[Pkg-octave-commit] [SCM] Debian packaging for octave branch, master, updated. 3.2.2-2-47-g47b3dd9

Thomas Weber tweber at debian.org
Thu Nov 10 23:02:05 UTC 2011


The following commit has been merged in the master branch:
commit 110307776a5bff587ed4bf3ce07aa3779c2a0739
Author: Thomas Weber <tweber at debian.org>
Date:   Thu Nov 10 23:55:16 2011 +0100

    Imported Upstream version 3.2.4

diff --git a/BUGS b/BUGS
new file mode 100644
index 0000000..d4ce4b0
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,308 @@
+This file documents known bugs in Octave and describes where and how to
+report any bugs that you may find.
+
+   Copyright (C) 1996, 1997, 2007 John W. Eaton.  You may copy,
+distribute, and modify it freely as long as you preserve this copyright
+notice and permission notice.
+
+1 Known Causes of Trouble with Octave
+*************************************
+
+   This section describes known problems that affect users of Octave.
+Most of these are not Octave bugs per se--if they were, we would fix
+them.  But the result for a user may be like the result of a bug.
+
+   Some of these problems are due to bugs in other software, some are
+missing features that are too much work to add, and some are places
+where people's opinions differ as to what is best.
+
+1.1 Actual Bugs We Haven't Fixed Yet
+====================================
+
+   * Output that comes directly from Fortran functions is not sent
+     through the pager and may appear out of sequence with other output
+     that is sent through the pager.  One way to avoid this is to force
+     pending output to be flushed before calling a function that will
+     produce output from within Fortran functions.  To do this, use the
+     command
+
+          fflush (stdout)
+
+     Another possible workaround is to use the command
+
+          page_screen_output (false);
+
+     to turn the pager off.
+
+   A list of ideas for future enhancements is distributed with Octave.
+See the file `PROJECTS' in the top level directory in the source
+distribution.
+
+1.2 Reporting Bugs
+==================
+
+Your bug reports play an essential role in making Octave reliable.
+
+   When you encounter a problem, the first thing to do is to see if it
+is already known.  *Note Trouble::.  If it isn't known, then you should
+report the problem.
+
+   Reporting a bug may help you by bringing a solution to your problem,
+or it may not.  In any case, the principal function of a bug report is
+to help the entire community by making the next version of Octave work
+better.  Bug reports are your contribution to the maintenance of Octave.
+
+   In order for a bug report to serve its purpose, you must include the
+information that makes it possible to fix the bug.
+
+   If you have Octave working at all, the easiest way to prepare a
+complete bug report is to use the Octave function `bug_report'.  When
+you execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+ -- Function File:  bug_report ()
+     Have Octave create a bug report template file, invoke your favorite
+     editor, and submit the report to the bug-octave mailing list when
+     you are finished editing.
+
+1.3 Have You Found a Bug?
+=========================
+
+If you are not sure whether you have found a bug, here are some
+guidelines:
+
+   * If Octave gets a fatal signal, for any input whatever, that is a
+     bug.  Reliable interpreters never crash.
+
+   * If Octave produces incorrect results, for any input whatever, that
+     is a bug.
+
+   * Some output may appear to be incorrect when it is in fact due to a
+     program whose behavior is undefined, which happened by chance to
+     give the desired results on another system.  For example, the
+     range operator may produce different results because of
+     differences in the way floating point arithmetic is handled on
+     various systems.
+
+   * If Octave produces an error message for valid input, that is a bug.
+
+   * If Octave does not produce an error message for invalid input,
+     that is a bug.  However, you should note that your idea of
+     "invalid input" might be my idea of "an extension" or "support for
+     traditional practice".
+
+   * If you are an experienced user of programs like Octave, your
+     suggestions for improvement are welcome in any case.
+
+1.4 Where to Report Bugs
+========================
+
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function `bug_report'.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+   If for some reason you cannot use Octave's `bug_report' function,
+send bug reports for Octave to <bug at octave.org>.
+
+   *Do not send bug reports to `help-octave'*.  Most users of Octave do
+not want to receive bug reports.  Those that do have asked to be on the
+mailing list.
+
+1.5 How to Report Bugs
+======================
+
+Send bug reports for Octave to one of the addresses listed in *note Bug
+Lists::.
+
+   The fundamental principle of reporting bugs usefully is this:
+*report all the facts*.  If you are not sure whether to state a fact or
+leave it out, state it!
+
+   Often people omit facts because they think they know what causes the
+problem and they conclude that some details don't matter.  Thus, you
+might assume that the name of the variable you use in an example does
+not matter.  Well, probably it doesn't, but one cannot be sure.
+Perhaps the bug is a stray memory reference which happens to fetch from
+the location where that name is stored in memory; perhaps, if the name
+were different, the contents of that location would fool the
+interpreter into doing the right thing despite the bug.  Play it safe
+and give a specific, complete example.
+
+   Keep in mind that the purpose of a bug report is to enable someone to
+fix the bug if it is not known.  Always write your bug reports on the
+assumption that the bug is not known.
+
+   Sometimes people give a few sketchy facts and ask, "Does this ring a
+bell?"  This cannot help us fix a bug.  It is better to send a complete
+bug report to begin with.
+
+   Try to make your bug report self-contained.  If we have to ask you
+for more information, it is best if you include all the previous
+information in your response, as well as the information that was
+missing.
+
+   To enable someone to investigate the bug, you should include all
+these things:
+
+   * The version of Octave.  You can get this by noting the version
+     number that is printed when Octave starts, or running it with the
+     `-v' option.
+
+   * A complete input file that will reproduce the bug.
+
+     A single statement may not be enough of an example--the bug might
+     depend on other details that are missing from the single statement
+     where the error finally occurs.
+
+   * The command arguments you gave Octave to execute that example and
+     observe the bug.  To guarantee you won't omit something important,
+     list all the options.
+
+     If we were to try to guess the arguments, we would probably guess
+     wrong and then we would not encounter the bug.
+
+   * The type of machine you are using, and the operating system name
+     and version number.
+
+   * The command-line arguments you gave to the `configure' command when
+     you installed the interpreter.
+
+   * A complete list of any modifications you have made to the
+     interpreter source.
+
+     Be precise about these changes--show a context diff for them.
+
+   * Details of any other deviations from the standard procedure for
+     installing Octave.
+
+   * A description of what behavior you observe that you believe is
+     incorrect.  For example, "The interpreter gets a fatal signal,"
+     or, "The output produced at line 208 is incorrect."
+
+     Of course, if the bug is that the interpreter gets a fatal signal,
+     then one can't miss it.  But if the bug is incorrect output, we
+     might not notice unless it is glaringly wrong.
+
+     Even if the problem you experience is a fatal signal, you should
+     still say so explicitly.  Suppose something strange is going on,
+     such as, your copy of the interpreter is out of synch, or you have
+     encountered a bug in the C library on your system.  Your copy
+     might crash and the copy here would not.  If you said to expect a
+     crash, then when the interpreter here fails to crash, we would
+     know that the bug was not happening.  If you don't say to expect a
+     crash, then we would not know whether the bug was happening.  We
+     would not be able to draw any conclusion from our observations.
+
+     Often the observed symptom is incorrect output when your program
+     is run.  Unfortunately, this is not enough information unless the
+     program is short and simple.  It is very helpful if you can
+     include an explanation of the expected output, and why the actual
+     output is incorrect.
+
+   * If you wish to suggest changes to the Octave source, send them as
+     context diffs.  If you even discuss something in the Octave source,
+     refer to it by context, not by line number, because the line
+     numbers in the development sources probably won't match those in
+     your sources.
+
+   Here are some things that are not necessary:
+
+   * A description of the envelope of the bug.
+
+     Often people who encounter a bug spend a lot of time investigating
+     which changes to the input file will make the bug go away and
+     which changes will not affect it.  Such information is usually not
+     necessary to enable us to fix bugs in Octave, but if you can find
+     a simpler example to report _instead_ of the original one, that is
+     a convenience.  Errors in the output will be easier to spot,
+     running under the debugger will take less time, etc.  Most Octave
+     bugs involve just one function, so the most straightforward way to
+     simplify an example is to delete all the function definitions
+     except the one in which the bug occurs.
+
+     However, simplification is not vital; if you don't want to do
+     this, report the bug anyway and send the entire test case you used.
+
+   * A patch for the bug.  Patches can be helpful, but if you find a
+     bug, you should report it, even if you cannot send a fix for the
+     problem.
+
+1.6 Sending Patches for Octave
+==============================
+
+If you would like to write bug fixes or improvements for Octave, that is
+very helpful.  When you send your changes, please follow these
+guidelines to avoid causing extra work for us in studying the patches.
+
+   If you don't follow these guidelines, your information might still be
+useful, but using it will take extra work.  Maintaining Octave is a lot
+of work in the best of circumstances, and we can't keep up unless you do
+your best to help.
+
+   * Send an explanation with your changes of what problem they fix or
+     what improvement they bring about.  For a bug fix, just include a
+     copy of the bug report, and explain why the change fixes the bug.
+
+   * Always include a proper bug report for the problem you think you
+     have fixed.  We need to convince ourselves that the change is
+     right before installing it.  Even if it is right, we might have
+     trouble judging it if we don't have a way to reproduce the problem.
+
+   * Include all the comments that are appropriate to help people
+     reading the source in the future understand why this change was
+     needed.
+
+   * Don't mix together changes made for different reasons.  Send them
+     _individually_.
+
+     If you make two changes for separate reasons, then we might not
+     want to install them both.  We might want to install just one.
+
+   * Use `diff -c' to make your diffs.  Diffs without context are hard
+     for us to install reliably.  More than that, they make it hard for
+     us to study the diffs to decide whether we want to install them.
+     Unidiff format is better than contextless diffs, but not as easy
+     to read as `-c' format.
+
+     If you have GNU diff, use `diff -cp', which shows the name of the
+     function that each change occurs in.
+
+   * Write the change log entries for your changes.
+
+     Read the `ChangeLog' file to see what sorts of information to put
+     in, and to learn the style that we use.  The purpose of the change
+     log is to show people where to find what was changed.  So you need
+     to be specific about what functions you changed; in large
+     functions, it's often helpful to indicate where within the
+     function the change was made.
+
+     On the other hand, once you have shown people where to find the
+     change, you need not explain its purpose.  Thus, if you add a new
+     function, all you need to say about it is that it is new.  If you
+     feel that the purpose needs explaining, it probably does--but the
+     explanation will be much more useful if you put it in comments in
+     the code.
+
+     If you would like your name to appear in the header line for who
+     made the change, send us the header line.
+
+1.7 How To Get Help with Octave
+===============================
+
+The mailing list <help at octave.org> exists for the discussion of matters
+related to using and installing Octave.  If would like to join the
+discussion, please send a short note to <help*-request*@octave.org>.
+
+   *Please do not* send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+   If you think you have found a bug in the installation procedure,
+however, you should send a complete bug report for the problem to
+<bug at octave.org>.  *Note Bug Reporting::, for information that will
+help you to submit a useful report.
+
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ 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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+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:
+
+    <program>  Copyright (C) <year>  <name of author>
+    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
+<http://www.gnu.org/licenses/>.
+
+  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
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..47cf13a
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,5332 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+2010-01-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* octMakefile.in: Add acx_pthread.m4 to CONF_DISTFILES.
+
+2009-08-04  John W. Eaton  <jwe at octave.org>
+
+	* acx_pthread.m4: New file.
+	* configure.in: Include it and invoke ACX_PTHREAD macro.  Print
+	ptrhead flags and libraries in summary output.
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+2009-08-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* acx_blas_f77_func.m4: Fix typo.
+
+2009-08-18  John W. Eaton  <jwe at octave.org>
+
+	* acx_blas_f77_func.m4 (ACX_BLAS_F77_FUNC): Save and restore LIBS.
+
+2009-07-16  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (MAGICK_LIBS): Don't pass --ldflags to $(MAGICK_CONFIG).
+
+2009-07-09  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Don't use system strftime on MinGW systems.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* examples/@polynomial/subsref.m: Handle ':' correctly.
+	* examples/@polynomial/subsasgn.m: Ditto.
+
+2009-05-22 Benjamin Lindner <lindnerb at users.sourceforge.net>
+
+	* mkoctfile.cc.in: mask MSVC specific linker flags for mex output
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-06-02  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* examples/@polynomial: Fix end method for zero based indexing.
+
+2009-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* examples/@polynomial/subsref.m: Allow chained subscripts,
+	fix behavior according to docs.
+	* examples/@polynomial/subsasgn.m: Allow chained subscripts,
+	fix behavior according to docs.
+
+2009-06-02  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* examples/@polynomial: Remove tabs from all functions so
+	documentation looks right.  Fix a bunch of methods
+	that didn't work.  Add a method referred to in the docs
+	that didn't exist.
+
+2009-05-26  John W. Eaton  <jwe at octave.org>
+
+	* src/dirfns.cc (Fpathsep): Allow path separator to be set.
+
+2009-03-17  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+        * configure.in: fix typo with regards to termios.h
+
+2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* examples/@FIRfilter/Makefile.in: New file.
+	* examples/Makefile.in: Include it.
+	* configure.in: Ditto.
+
+2009-05-24  Benjamin Lindner <lindnerb at users.sourceforge.net>
+
+	* configure.in: (SCRIPTS_EXE_SUFFIX) Define to ".exe" for 
+	mingw32 compilation (similar to msvc)
+
+2009-05-24  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* examples/@FIRfilter: added FIRfilter class example.
+
+2009-05-22  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+        * src/sysdep.cc: Removed CYGWIN_init 
+
+2009-05-21  Marco Atzeri  <marco_atzeri at yahoo.it>
+        * configure.in: Correct my mistake in cygwin SHLBINPRE SHLBIN
+
+2008-05-21  Michael Goffioul <michael.goffioul at gmail.com>
+
+	* aclocal.m4 (AC_CHECK_QHULL_OK): Do not use -lm under
+	Windows systems.
+	* configure.in: Add -luser32 to LIBS under Windows.
+
+	* configure.in (SCRIPTS_EXE_SUFFIX): New substituted
+	variable. Define to ".exe" for MSVC compilation.
+	* octMakefile.in (SCRIPTS_EXE_SUFFIX): New variable.
+	(DISTFILES): Add mkoctfile.cc.in, octave-config.cc.in and
+	octave-bug.cc.in.
+	(SHELL_SCRIPTS): Use SCRIPTS_EXE_SUFFIX.
+	(mkoctfile.cc, mkoctfile$(EXEEXT)): New build rules.
+	(octave-config.cc, octave-config$(EXEEXT)): Likewise.
+	(octave-bug.cc, octave-bug$(EXEEXT)): Likewise.
+	(install, install-strip, uninstall): Use SCRIPTS_EXE_SUFFIX.
+	(maintainer-clean, distclean): Remove mkoctfile.[cc|o|exe],
+	octave-config.[cc|o|exe] and octave-bug.[cc|o|exe].
+	(clean): Remove mkoctfile$(EXEEXT), octave-config$(EXEEXT),
+	octave-bug$(EXEEXT) and the corresponding object files.
+
+2009-05-07  Rik <rdrider0-list at yahoo.com>
+
+	* README.mirrors: Remove invalid mirror sites which no longer exist.
+
+2009-05-07  John W. Eaton  <jwe at octave.org>
+
+	* configure.in, mkoctfile.in, mkoctfile.cc.in, octave-bug.in,
+	octave-bug.cc.in: Eliminate last remnants of f2c goop.
+
+2009-05-07  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+	* configure.in, Makeconf.in: (SHLPRE): Rename from SHLLIBPRE.
+
+2009-05-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* configure.in: Include the whole 3.x g++ series as problematic.
+	* Makefile: Don't mention that g++-3.x might work.
+
+2009-05-04  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Put -lftgl ahead of $FT2_LIBS, and $FT2_LIBS ahead
+	of $OPENGL_LIBS.
+
+2009-05-04  Peter O'Gorman  <pogma at thewrittenword.com>
+
+	* aclocal.m4 (OCTAVE_HAVE_C99_VSNPRINTF): New macro.
+	* configure.in: Use it.
+
+	* configure.in (rs6000-ibm-aix* | powerpc-ibm-aix*): Set
+	library_path_var to LIBPATH.
+	(hppa*-hp-hpux*): Set library_path_var to SHLIB_PATH.
+	(ia64*-hp-hpux*): New case for shared library variables.
+
+	* configure.in: Provide decls for exp2, round, and tgamma if they
+	are missing.
+
+2009-04-11  David Bateman  <dbateman at free.fr>
+
+	* NEWS: Add new graphics functions.
+
+2009-04-05  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Use AC_USE_SYSTEM_EXTENSIONS instead of
+	AC_GNU_SOURCE, AC_AIX, AC_MINIX, and AC_ISC_POSIX.
+	Require Autoconf 2.60.
+
+	* configure.in: Add -Wformat to extra warning flags.  Add
+	-Wconversion to strict warning flags.
+
+2009-04-02  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-script-install): Use $(INSTALL_DATA) instead of
+	mv to install PKG_ADD file.
+
+2009-04-02  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+	* Makeconf.in (do-subst-script-vals): Use SHLLIBPRE instead of
+	LIBPRE for names for shared libraries.
+
+2009-03-28  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+	* configure.in: For cygwin, set LIBPRE=lib and clear CPICFLAG,
+	CXXPICFLAG, and FPICFLAG.
+
+2009-03-27  Jaroslav Hajek <highegg at gmail.com>
+
+	* aclocal.m4 (OCTAVE_CMATH_FUNC): Add missing AC_LANG_POP.
+	* configure.in: Enclose string in quotes.
+
+2009-03-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* NEWS: More updates.
+
+2009-03-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* aclocal.m4 (OCTAVE_CMATH_FUNC): New macro.
+	* configure.in: Use it.
+
+2009-03-09  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Use doc-cache instead of DOC for doc cache file.
+	* configure.in: Likewise.
+
+	* configure.in (--enable-extra-warning-flags): New option to
+	control extra compiler warning flags.
+	(--enable-strict-warning-flags): Rename from --enable-picky-flags.
+	(GXX_STRICT_FLAGS): Remove -Wenum-clash from the list.
+
+2009-03-08  Søren Hauberg  <hauberg at gmail.com>
+
+	* NEWS: Mention 'histc'.
+
+2009-03-07  John W. Eaton  <jwe at octave.org>
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (doc_cache_file): New default variable
+	* Makeconf.in (@doc_cache_file, do-subst-default-vals): Substitute it.
+
+2009-02-24  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in (DOCFILE): New variable.  Pass --doc-cache-file
+	option to Octave.
+
+	* configure.in: Copy Makefile to build directory if not building
+	in srcdir.
+
+2009-02-24  Thorsten Meyer  <thorsten at hexe>
+
+	* configure.in: AC_SUBST ac_config_files.
+	* Makeconf.in (config_opts): Define CONFIG_SUBDIRS variable.
+	* Makefile: Add make target for configuration files.
+	* octMakefile.in: Add make targets for configuration files,
+	config.status and configure.
+
+	* Makefile.in: Rename to Makefile.
+	* configure.in: Remove Makefile from list of autogenerated
+	configuration files.
+	* octMakefile.in: Remove references to Makefile.in, add Makefile
+	to list of CONF_DISTFILES.
+	* octMakefile.in (maintainer-clean distclean): Don't delete Makefile.
+
+2009-02-17  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* configure.in: Check for mkstemps on MinGW platform
+	(HAVE_MKSTEMPS): Define if mkstsmps is avilable in libiberty.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* NEWS: Mention cummin and cummax
+
+2009-02-17  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_GPERF): Don't run gperf.
+
+	* Makeconf.in (do-subst-config-vals): Substitute CARBON_LIBS,
+	X11_INCFLAGS, and X11_LIBS.
+
+2009-02-17  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* Makeconf.in: Substitute CARBON_LIBS.
+	* configure.in: Use CARBON_LIBS instead of LIBS for framework Carbon.
+
+	* configure.in: Fix test for X11 if "--without-x" is given.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* NEWS: Yet more updates.
+
+2009-02-16  John W. Eaton  <jwe at octave.org>
+
+	* NEWS: Mention command-style parsing changes.  More updates.
+
+2009-02-13  John W. Eaton  <jwe at octave.org>
+
+	* NEWS: Update for release.
+
+2009-02-11 Thomas Treichl <Thomas.Treichl at gmx.net>
+
+	* aclocal.m4 (OCTAVE_GLUTESSCALLBACK_THREEDOTS): New macro.
+	(OCTAVE_OPENGL): Use it in OpenGL check.
+
+2009-02-11 Ben Abbott <bpabbott at mac.com>
+
+	* configure.in: Include FTGLTextureFont.h when FTGL_UPPER_CASE is
+	not defined.
+
+2009-02-11  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (octetcdir): New default value.
+	* Makeconf.in (octetcdir): New variable.
+	(do-subst-default-vals): Substitute octetcdir.
+	* octMakefile.in (install, uninstall): Use $(octetcdir) for NEWS.
+	(DIRS_TO_MAKE): Add $(octetcdir) to the list.
+
+2009-02-10  Rafael Laboissiere  <rafael at debian.org>
+
+	* examples/Makefile.in: Run some clean targets on sub-directory
+	@polynomial.
+
+2009-02-09  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (dist): Create subdirs of examples, not scripts.
+
+	* examples/@polynomial/Makefile.in (do-mkpkgadd):
+	Provide special definition for this directory.
+
+	* examples/Makefile.in (EXAMPLE_SOURCES): Delete unused variable.
+	(SUBDIRS, DISTSUBDIRS): Don't reset to empty.
+
+2009-02-08  John W. Eaton  <jwe at octave.org>
+
+	* install-octave.in: Delete.
+	* configure.in: Delete AC_CONFIG_COMMANDS macro that was used to
+	make install-octave executable.
+
+2009-02-07  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (all): Display $(prefix) in summary message.
+
+2009-02-05  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_HDF5_HAS_REQUIRED_API): New macro.
+	* configure.in: Use it in HDF5 check.
+
+2009-02-04  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* configure.in: Use separate cases for *-*-mingw* and *-*-cygwin*
+	to set variables related to creating shared libraries.
+
+2009-02-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* aclocal.m4 (AC_CHECK_QHULL_OK): New macro, based on suggestion by
+	Petr Mikulik <mikulik at physics.muni.cz>.
+	* configure.in: Call it.
+
+2009-02-01  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* autogen.sh: Remove printing of cvs motd.
+
+2009-01-30  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+	* configure.in (SHLLIBPRE, SHLBINPRE): Fix definitions for Cygwin.
+	(SHLEXT, SHLLIB, SHLBIN, SONAME_FLAGS): Fix definitions for Cygwin
+	and MinGW.
+
+2009-01-30  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* configure.in: Add -lgdi32 to LIBS on *-*-msdosmsvc* and
+	*-*-mingw* systems.
+
+2009-01-29  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* aclocal.m4 (OCTAVE_HAVE_FRAMEWORK): Add support for 
+	--with-framework-<name> and replace "$ac_safe" by "$1".
+	* configure.in: Change "have_carbon" with 
+	"have_framework_carbon".
+
+2009-01-28  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check to see that pcre library has pcre_compile
+	function.
+
+ 	* configure.in (SHLLIBPRE, SHLBINPRE): New variables.  AC_SUBST them.
+ 	(*-*-cygwin*): Set LIBPRE and SHLBINPRE to cyg and SHLLIBPRE to lib.
+	Use SHLLIBPRE and SHLLIB in definition of SONAME_FLAGS.
+	(*-*-msdosmsvc): Make SHLBINPRE and SHLLIBPRE empty.
+ 	Adjust definition of SONAME_FLAGS for SHLLIBPRE.
+
+	* Makeconf.in (SHLLIBPRE, SHLBINPRE): Substitute new variables here.
+	From Marco Atzeri <marco_atzeri at yahoo.it>.
+
+2009-01-27  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* configure.in: Add of -lregex to REGEX_LIBS.
+
+2009-01-26  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* aclocal.m4 (OCTAVE_HAVE_FRAMEWORK): New macro.
+	* configure.in: Use it.
+
+2009-01-22  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AH_BOTTOM): Define OCTAVE_USE_OS_X_API if
+	__APPLE__ and __MACH__ are defined.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* configure.in: Fix qrupdate warning message.
+
+2009-01-21  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in: Substitute X11_INCFLAGS and X11_LIBS.
+	* configure.in: Use AC_PATH_X to check for X11 header files and
+	libraries.
+
+	* THANKS, Announce: Remove obsolete files.
+	* octMakefile.in (DISTFILES): Remove THANKS from the list.
+
+2009-01-20  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for fstat.
+
+2008-12-23  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Add configuration test for ARPACK. 
+	* Makeconf.in (ARPACK_LIBS): Add variable with location of ARPACK
+	library.
+	* NEWS: Document that eigs and svds were moved to Octaave.
+
+2008-10-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* configure.in: Remove the OCTAVE_LOCAL_BUFFER stuff (moved to
+	liboctave).
+
+2008-12-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* NEWS: Document more new features.
+
+2008-12-03  John W. Eaton  <jwe at octave.org>
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2008-11-18  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.cc.in, octave-bug.cc.in: Style fixes.
+
+2008-11-13  Ben Abbott <bpabbott at mac.com>
+
+	* src/graphics.h.in: Add props screensize & screenpixelsperinch.
+
+2008-11-08  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * Makeconf.in: export PERL variable for use in scripts/mkdoc
+        
+2008-10-30  David Bateman  <dbateman at free.fr>
+
+	* NEWS: Minor update to document improved indexing code.
+
+2008-10-23  Jason Riedy  <jason at acm.org>
+
+	* configure.in: Take care to use FT2_CFLAGS when checking
+	for FTGL headers.
+
+2008-10-22  David Bateman  <dbateman at free.fr>
+
+	* examples/@polynomial: Move examples/polynomial here.
+	* examples/@polynomial/Makefile.in: Update for new location.
+	* examples/Makefile.in: Ditto.
+	* configure.in: Change locate of examples/@polynomial makefile
+	in AC_CONFIG_FILES.
+	
+2008-10-16  David Bateman  <dbateman at free.fr>
+
+	* NEWS: Minor update.
+
+2008-10-15  David Bateman  <dbateman at free.fr>
+
+	* examples/polynomial/display.m, examples/polynomial/double.m,
+	examples/polynomial/end.m, examples/polynomial/get.m,
+	examples/polynomial/mtimes.m, examples/polynomial/plot.m,
+	examples/polynomial/polynomial.m,
+	examples/polynomial/polynomial_superiorto.m,
+	examples/polynomial/polyval.m, examples/polynomial/set.m,
+	examples/polynomial/subsasgn.m, examples/polynomial/subsref.m:
+	New example files for a sample OOP class.
+	* examples/polynomial/Makefile.in: Add a makefile for this new
+	directory
+	* examples/Makefile.in: Reference the new subdirectory here.
+	* configure.in: Add the new makefile to AC_CONFIG_FILES.
+	
+2008-10-01  Jaroslav Hajek <highegg at gmail.com>
+
+	* configure.in: Check for sizeof (long double) and randl.
+
+2008-09-30  Jaroslav Hajek <highegg at gmail.com>
+
+	* aclocal.m4 (OCTAVE_FAST_INT_OPS): New macro.
+	* configure.in: Call OCTAVE_FAST_INT_OPS
+
+2008-09-08  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.cc.in, octave-bug.cc.in, octave-config.cc.in: Style fixes.
+
+2008-09-08  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* mkoctfile.cc.in, octave-bug.cc.in, octave-config.cc.in: New files.
+
+2008-08-28  David Bateman  <dbateman at free.fr>
+
+	* NEWS: Update for some of the graphics changes
+	
+2008-08-11  Jaroslav Hajek <highegg at gmail.com>
+
+	* acx_blas_f77_func.m4, acx_lapack.m4: Update macros from
+	<http://autoconf-archive.cryp.to/>.
+
+2008-08-07  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_STRING_NPOS): Delete.
+	* configure.in (OCTAVE_STRING_NPOS): Delete use.
+
+2008-08-04  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-subst-script-vals): Also substitute SED.
+	* run-octave.in: Use sed to append : to path elements
+	instead of using the find expression "-exec echo '{}':".
+	Substitute SED here.
+
+	* aclocal.m4: Fail if no usable version of sed is found.
+
+	* Makefile.in (header-msg): Mention GNU Make requirement.
+	Update GCC version info.
+
+2008-07-31  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (DISTFILES): Add "missing" to the list.
+
+2008-07-30  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (CXX_ABI, OCTAVE_CXX_PREPENDS_UNDERSCORE,
+	OCTAVE_PROG_NM): Delete macros.
+	* configure.in: Delete uses.
+
+2008-07-29  Tatsuro MATSUOKA  <tmacchant at yahoo.co.jp>
+
+	* aclocal.m4 (OCTAVE_OPENGL): Handle MinGW the same as MSVC.
+
+2008-07-29  David Bateman  <dbateman at free.fr>
+
+	* NEWS.3: Copy from NEWS.
+	* NEWS: Initial update in preparation for a 3.2 release.
+
+2008-07-21  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: If FTGL.h is found, then also include
+	FTGLTextureFont.h in test code.
+
+2008-07-21  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* configure.in: Remove GRAPHICS_OPENGL variable.
+
+2008-07-21  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_OPENGL): Fix shell syntax problems.
+	Handle HAVE_GL_GL_H and HAVE_OPENGL_GL_H in link test.
+
+	* configure.in: Don't define and substitute FLTK_BACKEND_SRC or
+	GL_RENDER_SRC.
+	(HAVE_FLTK): AC_DEFINE if FLTK is available.
+	(HAVE_OPENGL): AC_DEFINE if OpenGL is available.
+
+2008-07-21  Jaroslav Hajek <highegg at gmail.com>
+
+	* configure.in: Extend FTGL test to test for both ftgl.h and FTGL.h.
+	Use HAVE_FTGL_UPPERCASE to indicate the latter (version <= 2.1.2).
+
+2008-07-19 Rafael Laboissiere <rafael at debia8n.org>
+
+	* octMakefile.in (CONF_DISTFILES): Include acx_blas_f77_func.m4 in
+	the list.
+
+2008-07-18 Carlo de Falco <carlo.defalco at gmail.com>
+
+	* aclocal.m4: Search for gl.h and glu.h in OpenGL/ as well as in GL/.
+
+2008-07-18  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Fix FTGL test to handle either FTGL/ftgl.h or ftgl.h.
+	(warn_freetype, warn_ftgl, warn_fltk_config, warn_fltk_opengl):
+	New variables.  Use these instead of overloading warn_graphics.
+
+2008-07-17  David Bateman  <dbateman at free.fr>
+
+	* configure.in (HAVE_MAGICK): New define for presence of
+	GraphicsMagick.
+
+2008-07-16  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* configure.in: Add check for pthread.h.
+
+2008-07-14  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (MAGICK_CONFIG): Substitute here.
+	(MAGICK_INCFLAGS, MAGICK_LIBS): Define using GraphicsMagick++
+	config script.
+	(do-subst-config-vals): Include MAGICK_LIBS and MAGICK_INCFLAGS in
+	list of substitutions.
+	* configure.in: Check for GraphicsMagick++ config script.
+
+2008-07-10  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (DIRS_TO_MAKE): Delete $(localfcnfilepath) and
+	$(localoctfilepath) from the list.  Include $(datadir)
+	$(localfcnfiledir) $(localapifcnfiledir) $(localverfcnfiledir)
+	$(localoctfiledir) $(localapioctfiledir) $(localveroctfiledir)
+	$(imagedir) and $(localapiarchlibdir) in the list.
+
+	* configure.in: Look for FTGL/ftgl.h instead of FTGL/FTGL.h.  Also
+	look for ftgl.h.
+
+2008-07-10  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* configure.in: new substituted variables GL_RENDER_SRC and
+	FLTK_BACKEND_SRC.
+
+2008-06-20  Michael Goffioul <michael.goffioul at gmail.com>
+
+	* Makeconf.in: Add GRAPHICS_CFLAGS substitution.
+	* configure.in: Add checks for hypotf and _hypotf.
+
+2008-06-12  Jaroslav Hajek <highegg at gmail.com>
+
+	* configure.in: Move LIBS and CXXFLAGS restoration into
+	the proper block.
+
+2008-06-05  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Add FT2_CFLAGS to XTRA_CXXFLAGS, not CXXFLAGS.
+	Don't add FT2_LIBS to LIBS.
+	Don't generate src/graphics/Makefile, src/graphics/Makerules,
+	src/graphics/opengl/Makefile, or src/graphics/fltk_backend/Makefile.
+
+	* Makeconf.in (FT2_LIBS, GRAPHICS_LIBS): Substitute here.
+
+2008-06-04  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* configure.in: Use AC_TRY_LINK in FTGL test.
+	Include FT_CFLAGS in CXXFLAGS.
+
+	* aclocal.m4 (OCTAVE_OPENGL): Note FIXME for apple.
+
+	* configure.in: Check for FTGL library.
+
+	* configure.in: Remove check for Fl/glu.h header.
+
+	* aclocal.m4 (AC_CHECK_FT2): New macro to check for freetype2.
+
+	* configure.in: Check for FLTK and corresponding compiler flags.
+
+2008-06-04  Michael Goffioul <michael.goffioul at gmail.com>
+
+	* configure.in: Double-quote warn_graphics variable.
+
+	* aclocal.m4 (OCTAVE_OPENGL): New function to detect OpenGL
+	headers and libraries.
+	* configure.in (OCTAVE_OPENGL): Use it.
+	(OCTGRAPHICS_DLL_DEFS): New define to build
+	graphics-related DLL.
+	(AC_CONFIG_FILES): Generate additional files for graphics
+	related libraries.
+	* Makeconf.in (OPENGL_LIBS): New variable.
+
+	* .hgignore: Also ignore build-.*, configure, and autom4te.cache.
+
+2008-05-22  Jaroslav Hajek <highegg at gmail.com>
+
+	* mk-opts.pl (emit_print_function, emit_set_function,
+	emit_show_function): Support float type.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* configure.in (AC_CHECK_FUNCS): Add expm1, lgammaf, lgammaf_r,
+	log1pf and tgammaf. Also check for libfftw3f.
+
+2008-04-09  Rafael Laboissiere  <rafael at debian.org>
+
+	* example/octave.desktop.in: Drop the Encoding key, which is
+	deprecated by the FreeDesktop standard.
+
+2008-04-04  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-check-m-sources): New macro.
+
+2008-04-03  Tatsuro MATSUOKA  <tmacchant at yahoo.co.jp>
+
+	* README.Cygwin: Update.
+
+2008-04-02  Jaroslav Hajek <highegg at gmail.com>
+
+	* acx_blas_f77_func.m4: New file.
+	* configure.in: Call ACX_BLAS_WITH_F77_FUNC instead of ACX_BLAS.
+	Supply a warning for incompatible Fortran/BLAS configuration.
+
+2008-03-25  Jaroslav Hajek <highegg at gmail.com>
+
+	* configure.in: Check for expm1 and log1p functions.
+
+2008-03-25  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for trunc.
+
+2008-03-21  David Bateman  <dbateman at free.fr>
+
+	* configure.in (HAVE_AMD): Complete test for presence of amd.
+
+2008-03-18  David Bateman  <dbateman at free.fr>
+
+	* configure.in (AC_CHECK_FUNCS): Also check lgamma_r.
+
+2008-03-11  David Bateman  <dbateman at free.fr>
+
+	* run-octave.in: Fix typo.
+
+2008-02-21  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (install install-strip): Ignore errors
+	installing octave.desktop file.
+
+2008-02-15  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (*-*-freebsd*, *-*-openbsd*): Don't set SH_LD.
+
+2008-02-14  John W. Eaton  <jwe at octave.org>
+
+	* examples/fortdemo.cc: Don't check f77_exception_encountered.
+
+2008-02-06  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (octave.desktop):
+	Use mv instead of move-if-change.
+
+2008-02-05  John W. Eaton  <jwe at octave.org>
+
+	* dlfcn/Makefile.in: Unconditionally include $(MAKEDEPS).
+	Mark $(MAKEDEPS) as .PHONY targets if omit_deps is true.
+
+2008-01-12  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4: Call AC_SUBST instead of AC_DEFINE_UNQOTED for
+	GNUPLOT_BINARY.
+	* aclocal.m4, configure.in: Use GNUPLOT instead of GNUPLOT_BINARY
+	as variable name.
+	* Makeconf.in (GNUPLOT): Substitute.
+	(do-subst-config-vals): Substitute GNUPLOT.
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+2007-12-13  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (octave-bug, octave-config, mkoctfile):
+	Also depend on $(top_srcdir)/src/version.h.
+
+2007-12-10  John W. Eaton  <jwe at octave.org>
+
+	* acx_blas.m4: Use -lsunperf, not -xlic_lib=sunperf.
+	From Jim Langston <Jim.Langston at Sun.COM>.
+
+2007-12-06  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (*-*-darwin*): Only set CPICFLAG, CXXPICFLAG, and
+	FPICFLAG to "" on powerpc systems.
+
+2007-12-04  John W. Eaton  <jwe at octave.org>
+
+	* octave-bug.in (LIBDLFCN): Delete variable and all uses.
+	* Makeconf.in (LIBDLFCN, DLFCN_INCFLAGS): Likewise.
+	* configure.in (DLFCN_DIR, LIBDLFCN, DLFCN_INCFLAGS): Likewise.
+	Don't generate dlfcn/Makefile.
+	* octMakefile.in (DISTSUBDIRS): Delete dlfcn from the list.
+	(SUBDIRS): Don't substitute DLFCN_DIR here.
+
+2007-12-03  Moritz Borgmann  <octave at moriborg.de>
+
+	* Makeconf.in, aclocal.m4, configure.in: Check for find program,
+	preferably gfind (on non-GNU systems).  Need a sane find for
+	run-octave script.
+	* run-octave.in: Use FIND and AWK as determined by configure.
+
+2007-12-03  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: If available, include <sys/types.h> in test for
+	sigset_t and sig_atomic_t.
+
+2007-11-30  Moritz Borgmann  <octave at moriborg.de>
+
+	* configure.in: Also check for sunmath.h.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* PROJECTS: condest now implemented.
+
+	* NEWS: Document the TeX interpreter mode and its limitations with
+	gnuplot 4.0.
+
+	* NEWS: Document the use of "colormap gmap40" to workaround some
+	gnuplot 4.0 colormap issues.
+
+2007-11-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Don't create Makefrag.bsd.
+
+2007-11-14  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* configure.in: Rework pcre.h tests to work with autoconf 2.59,
+	and avoid explicit pcre/pcre.h check by using pcre-config.
+
+2007-11-13  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* octave-bug.in: Try mailx, then Mail, then /usr/ucb/mail, then
+	/bin/mail.
+ 
+2007-11-13  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Only define HAVE_PCRE_H if <pcre.h> has the
+	definitions we need.  Likewise for <pcre/pcre.h>.
+
+2007-11-10  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Delete AC_SUBST_FILE(f77_rules_frag).
+
+2007-11-07  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Also check for pcre/pcre.h.
+
+2007-11-01  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Delete BLAS library calling convention
+	compatibility check.
+
+2007-10-31  John W. Eaton  <jwe at octave.org>
+
+	* README.binary-dist: Delete.
+
+	* README.MachTen: Delete.
+	* octMakefile.in (DISTFILES): Remove it from the list.
+
+2007-10-30  David Bateman  <dbateman at free.fr>
+
+	* examples/addtwomatrices.cc, examples/celldemo.cc,
+	examples/firstmexdemo.c, examples/fortdemo.cc, examples/fortsub.f,
+	examples/funcdemo.cc, examples/globaldemo.cc,
+	examples/helloworld.cc, examples/mycell.c, examples/myfeval.c,
+	examples/myfunc.c, examples/mypow2.c, examples/mysparse.c,
+	examples/mystring.c, examples/mystruct.c, examples/paramdemo.cc,
+	examples/stringdemo.cc, examples/structdemo.cc,
+	examples/unwinddemo.cc: Doc fixes for small book format.
+
+2007-10-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Makeconf.in: Remove UNSETCOMSPEC trick.
+
+2007-10-25  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AH_BOTTOM): Define OCTAVE_EMPTY_CPP_ARG here.
+
+2007-10-24  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (maintainer-clean distclean): No need to delete
+	Makefrag.f77 and Makerules.f77.
+	* Makeconf.in: Include rules for making .o files from .f files
+	instead of substituting @f77_rules_frag at .  
+	* configure.in): Delete handling of --with-f2c and --with-f77
+	options.  No need to call OCTAVE_CHECK_EXCLUSIVE_WITH_OPTIONS.
+	Delete all special cases for f2c.
+	* aclocal.m4 (OCTAVE_CHECK_EXCLUSIVE_WITH_OPTIONS): Delete macro.
+
+	* FLEX.patch: Delete obsolete file.
+	* octMakefile.in (DISTFILES): Remove it from the list.
+
+	* acx_blas.m4: Use "-Wl,-framework -Wl,vecLib" instead of
+	just "-framework vecLib" in test for Mac OS X test.
+
+	* configure.in, aclocal.m4: Avoid AC_TRY_EVAL.
+
+	* aclocal.m4 (OCTAVE_STRPTIME_BROKEN): New macro.
+	* configure.in: Use it.
+
+2007-10-23  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: When checking for -lf2c, set F2CLIBS instad of
+	FLIBS, then set FLIBS to $F2CLIBS just before printing the summary.
+	Check for BLAS library calling convention compatibility.
+
+2007-10-17  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Delete checks for METIS.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* mk-opts.pl (parse_input): Allow comment lines beginning with #.
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+	* COPYING: Update to GPLv3.
+
+        * run-octave.in: List args explicitly in exec command.
+
+2007-10-11  John W. Eaton  <jwe at octave.org>
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2007-10-10  Kim Hansen  <kimhanse at gmail.com>
+
+        * run-octave.in: Use $args.  Eliminate "if [ -n "$args" ]" conditional.
+
+2007-10-09  John W. Eaton  <jwe at octave.org>
+
+	* gdbinit.in: Delete.
+	* octMakefile.in (DISTFILES): Remove it from the list.
+	(.gdbinit): Delete rule.
+	(maintainer-clean, distclean): No need to delete .gdbinit.
+
+2007-10-09  Kim Hansen  <kimhanse at gmail.com>
+
+        * run-octave.in: Use gdb with --args, not .gdbinit.
+
+2007-10-08  John W. Eaton  <jwe at octave.org>
+
+	* emacs/octave-hlp.el, emacs/octave-inf.el, emacs/octave-mod.el:
+	Sync with GNU Emacs versions.
+	* emacs/octave-mod.el: Delete last two args from calls to
+	define-abbrev.
+
+2007-10-06  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for lgamma and tgamma.
+
+2007-10-04  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (UGLY_DEFS): Delete special case for darwin.
+
+2007-10-03  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_SED): Also check for \(X\|Y\) style
+	regular expression alternation.
+
+2007-10-01  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_CHECK_STRPTIME): Delete.
+	* configure.in: Don't use OCTAVE_CHECK_STRPTIME, simply check for
+	strptime.
+
+2007-09-18  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* aclocal.m4 (OCTAVE_CHECK_STRPTIME): New macro.
+	* configure.in: Use it.
+
+2007-09-06  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Avoid broken strptime function on Cygwin systems.
+
+2007-09-01  David Bateman  <dbateman at free.fr>
+
+	* configure.in: AC_SUBST and check the variable TEXINFO_QHULL.
+	* Makeconf.in: Use it.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Extra Qhull bits.
+
+2007-08-24  Kim Hansen  <kimhanse at gmail.com>
+
+	* run-octave.in: Use `command` instead of $(command) to accomodate
+	brain-dead shells.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+        * configure.in: Probe for the use of Qhull.
+        * aclocal.m4 (AC_CHECK_QHULL_VERSION): Macro to check whether
+        Qhull needs a version number.
+        * Makeconf.in: Add QHULL_LIBS.
+
+2007-08-23  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_SED): Don't clobber value from environment.
+	From: Christian Cornelssen <ccorn at cs.tu-berlin.de>.
+
+2007-08-23  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* aclocal.m4 (OCTAVE_PROG_GNUPLOT): Drop check for multiple plot
+	windows.
+
+2007-08-10  Søren Hauberg  <hauberg at gmail.com>
+
+	* ROADMAP: Update for current sources.
+
+2007-07-26  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Also look for glpk/glpk.h.
+
+2007-07-25  David Bateman  <dbateman at free.fr>
+
+	* octMakefile.in, dlfcn/Makefile.in, emacs/Makefile.in,
+	examples/Makefile.in, test/Makefile.in: Adjust DISTFILES to allow 
+	out of tree "make dist" to work.	
+	
+2007-07-24  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in (*-*-msdosmsvc): Only add -g to DL_LDFLAGS and
+	SH_LDFLAGS if either CFLAGS or CXXFLAGS contains -g.
+
+2007-07-24  Rafael Laboissiere  <rafael at debian.org>
+
+	* Makeconf.in (RUNTEST): Delete variable substitution.
+	(do-subst-config-vals): Don't substitute %OCTAVE_CONF_RUNTEST%.
+
+2007-07-20  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* mkoctfile.in: Fix typo.
+
+2007-06-25  John W. Eaton  <jwe at octave.org>
+
+	* mk-opts.pl (emit_print_function): Make generated function print
+	to ostream (passed as arg) instead of local buffer.  Don't call
+	print_usage in generated function.
+	(emit_options_function): Fix call to print_${class_name} in
+	generated to pass octave_stdout as arg.
+
+2007-06-18  John W. Eaton  <jwe at octave.org>
+
+	* emacs/octave-inf.el (inferior-octave-prompt): Match "octave.bin"
+	and "octave.exe" in addition to "octave".
+
+2007-06-15  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Use simple string concatenation instead of
+	sprintf in AWK program.
+
+2007-06-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in: Set NO_OCT_FILE_STRIP=true for msdosmsvc.
+
+	* aclocal.m4 (OCTAVE_HDF5_DLL): Include return statements in
+	function body used for test.
+
+	* configure.in: Check for CXSparse with C++.
+
+	* Makeconf.in (do-subst-config-vals): Also substitute ${libdir} as
+	OCTAVE_CONF_LIBDIR.
+	* mkoctfile.in: Set DEFAULT_LIBDIR and substitute OCTAVE_HOME.
+	Define LIBDIR.  Use LIBDIR to set DEFAULT_LFLAGS.
+
+2007-06-12  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* configure.in: For mingw, add -lws2_32 -lkernel32 to LIBS and set
+	_USE_MATH_DEFINES same as for msvc.
+
+2007-06-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in: Check for utime.h and sys/utime.h headers.
+	Check for utime, _chmod, _utime, and _utime32 functions.
+
+2007-06-03  David Bateman  <dbateman at free.fr>
+
+	* configure.in (AC_CONFIG_FILES): Add src/mxarray.h
+	* examples/mycell.c, examples/mypow2.c, examples/mysparse.c,
+	examples/mystring.c, examples/mystruct.c: Use mwSize and mwIndex,
+	rather than int for indexing to conform to new mex API.
+	
+2007-06-01  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (*-*-darwin*): Fix quoting and construction of
+	MKOCTFILE_DL_LDFLAGS.
+	* mkoctfile.in (DEFAULT_BINDIR, EXEEXT): New substitutions.
+	* Makeconf.in (MKOCTFILE_DL_LDFLAGS): Delete.
+	(do-subst-config-vals): Do configure substitution of
+	MKOCTFILE_DL_LDFLAGS directly here instead of using intermediate
+	variable.  Quote this sed substitution with ' instead of ".
+
+2007-05-29  Steven Mestdagh  <steven.mestdagh at esat.kuleuven.be>
+
+	* configure.in: Delete spurious "break" in fftw3 check.
+	Use separate case for SH_LD and SH_LDFLAGS on openbsd.
+
+2007-05-22  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-script-uninstall): Also remove directory.
+
+2007-05-22  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* NEWS.2, README.MSVC, WWW/NEWS-2.html: Fix typos.
+
+2007-05-16  David Bateman  <dbateman at free.fr>
+
+	* PROJECTS: Update.
+
+2007-04-27  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (SOURCES): Add all example files to the list.
+
+	* octave-config.in: Don't set PREFIX to OCTAVE_HOME if OCTAVE_HOME
+	is empty.
+
+2007-04-27  David Bateman  <dbateman at free.fr>
+
+	* examples/mycell.c, examples/mypow2.c, examples/mystring.c,
+	examples/myprop.c: New example mex files.
+
+2007-04-26  Alex Zvoleff  <azvoleff at sbcglobal.net>
+
+	* configure.in: Don't report ARPACK libraries in summary.
+
+2007-04-25  David Bateman  <dbateman at free.fr>
+
+	* Makeconf.in (do-subst-texinfo-vals): Also substitute abs_top_srcdir.
+
+	* examples/myfunc.c, exampples/paramdemo.cc: New files
+	* examples/mystruct.c, examples/mysparse.c, fortdemo.cc: Fix a few
+	formatting issues when included in texinfo files.
+
+2007-04-25  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-subst-texinfo-vals): Also substitute top_srcdir.
+
+	* examples/addtwomatrices.cc, examples/celldemo.cc,
+	examples/fortdemo.cc, examples/funcdemo.cc,
+	examples/globaldemo.cc, examples/helloworld.cc,
+	examples/stringdemo.cc, examples/structdemo.cc,
+	examples/unwinddemo.cc, examples/fortsub.f,
+	examples/firstmexdemo.c: New files.
+	* examples/Makefile.in (SOURCES): Add them to the list.
+
+2007-04-20  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Don't check for ARPACK.
+
+2007-03-29  Rafael Laboissiere  <rafael at debian.org>
+
+ 	* emacs/octave-mod.el: Drop LOADPATH, INFO_FILE, and
+ 	INFO_PROGRAM from octave-variables.
+
+	* examples/info-emacs-octave-help, examples/info-emacs-info:
+	Use gnuclient, not gnudoit.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (dist, conf-dist): Use ln, not $(LN_S).
+	* emacs/Makefile.in (dist): Likewise.
+	* examples/Makefile.in (dist): Likewise.
+	* dlfcn/Makefile.in (conf-dist): Likewise.
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2007-03-23  John W. Eaton  <jwe at octave.org>
+
+	* examples/make_int.cc (octave_integer::clone): Return type is
+	pointer to octave_base_value, not octave_value.
+	(Fdoit): Rep is reference to octave_base_value, not octave_value.
+
+2007-03-21  Paul Kienzle <pkienzle at users.sf.net>
+
+	* octMakefile.in (all): Print message after successful build.
+
+2007-03-05  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (GLPK_PRE_4_14): Rename from GLPK_PRE_4_15.
+
+2007-02-27  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-script-uninstall): Remove PKG_ADD.
+	* examples/Makefile.in (uninstall): Don't remove files listed in
+	$(SCRIPTS) from $(srcdir).
+	Remove www.octave.org-octave.desktop, not octave.desktop.
+
+	* run-octave.in (run-octave.in): Use --no-initial-path.
+	Rename to qargs to args.  Use $args not "$args" when invoking Octave.
+	Try harder to get quoting right when passing args to Octave.
+
+2007-02-26  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (DISTDIRS): Eliminate variable.
+
+2007-02-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* octMakefile.in, dlfcn/Makefile.in, emacs/Makefile.in:
+	Use $(LN_S) instead of ln or ln -s.
+
+	* octMakefile.in (dist): Use -9 instead of --best with gzip/bzip2.
+
+2007-02-21  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Also warn about missing functionality for
+	--without-glpk or --without-curl options.  Print curl library
+	warning in summary.
+
+2007-02-20  Rafael Laboissiere  <rafael at debian.org>
+
+	* configure.in: Check for versions of GLPK prior to 4.15 and set
+	the GLPK_PRE_4_15 macro accordingly.
+
+2007-02-16  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in: Use OCTAVE_PREFIX, not OCTAVE_CONF_PREFIX, in sed
+	substitutions.
+	* octave-conf.in: Define DATAROOTDIR, not DATADIR, from
+	OCTAVE_DATAROOTDIR.
+	From Michael Goffioul <michael.goffioul at swing.be>.
+
+2007-02-15  John W. Eaton  <jwe at octave.org>
+
+	* octave-config.in (DATAROOTDIR): Include in list of vars.
+	Substitute OCTAVE_HOME.
+
+	* Makeconf.in (MKOCTFILE_INCFLAGS, MKOCTFILE_LFLAGS): Delete vars.
+	(do-subst-config-vals): Don't substitute them.
+	Also substitute OCTAVE_CONF_INCLUDEDIR, OCTAVE_CONF_OCTINCLUDEDIR,
+	OCTAVE_CONF_OCTLIBDIR, and OCTAVE_CONF_PREFIX here.
+	* mkoctfile.in (OCTAVE_CONF_OCTINCLUDEDIR, OCTAVE_CONF_INCLUDEDIR,
+	OCTAVE_CONF_OCTLIBDIR): Substitute values and perform OCTAVE_HOME
+	substitution here.
+	(DEFAULT_INCFLAGS, DEFAULT_LFLAGS): New variables.  Use them to
+	set default values for INCFLAGS and LFLAGS.
+
+2007-02-09  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in: Handle .a files.
+
+2007-02-08  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (all): Depend on dist-info-files.
+	(dist): Delete dist-info-files dependency.
+
+	* configure.in: Rewrite if !( X ) ... fi as if X; true; else ... fi.
+	Also check for _glp_lpx_simplex.
+
+2007-02-07  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-script-install): Use $(FCN_FILES) for list of
+	files instead of $(FCN_FILES_NO_DIR).  Use basename to get
+	filename with no directory part.
+
+2007-02-07  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* aclocal.m4 (OCTAVE_HDF5_DLL): New macro.
+	* configure.in: Use it.
+
+2007-02-05  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for realpath function.
+
+	* demo.m: Delete obsolete file.
+
+2007-01-29  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in (*-*-msdosmsvc): Set NO_OCT_FILE_STRIP to true.
+
+2007-01-24  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (install): Install NEWS file.
+	(uninstall): Remove it.
+
+2007-01-08  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Replace sparsesuite with suitesparse to match
+	upstream name.
+
+2006-12-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* acx_blas.m4, acx_lapack.m4: Handle f2c calling convention.
+
+2006-12-05  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Don't check for strptime on *-apple-darwin* systems.
+
+2006-11-28  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in: Construct default output file from basename of
+	input file name.
+
+2006-11-28  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Check for sparse header files in the sparsesuite
+	sub-directory. In the cholmod tests, include the camd libraries, as
+	this might be a dependency for cholmod.
+
+2006-11-15  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Don't forget LD_PRELOAD if there are args.
+
+2006-11-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: If warning message is printed, print additional
+	final note about missing libraries.
+
+2006-11-13  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Substitute liboctinterp, liboctave, and libcruft.
+	Use them to set LD_PRELOAD.
+	* Makeconf.in (do-subst-script-vals): Also substitute
+	liboctinterp, liboctave, and libcruft.
+
+2006-11-13  Rafael Laboissiere  <rafael at debian.org>
+
+	* mkoctfile.in: Add -Wl,... options to ldflags, not pass_on_flags.
+
+2006-11-11  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (octave.desktop):
+	Use $(simple-move-if-change-rule) here.
+
+	* Makeconf.in (simple-move-if-change-rule,
+	(builddir-move-if-change-rule): New macros.
+
+2006-11-11  Søren Hauberg  <hauberg at gmail.com>
+
+	* examples/Makefile.in (uninstall): Add missing semicolon.
+
+2006-11-09  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (uninstall): New target.
+
+2006-11-09  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in (OCTAVE_LOCAL_BUFFER): Don't access first element
+	if size is 0.
+
+2006-11-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in (CRUFT_DLL_DEFS, OCTAVE_DLL_DEFS, OCTINTERP_DLL_DEFS):
+	Also rename in AC_SUBST calls.
+	* Makeconf.in (ALL_CFLAGS): Use DLL_CDEFS instead of XTRA_CDEFS.
+	(ALL_CXXFLAGS): Use DLL_CDEFS instead of XTRA_CXXDEFS.
+
+2006-11-03  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (CRUFT_DLL_DEFS): Rename from XTRA_CRUFT_DEFS.
+	(OCTAVE_DLL_DEFS): Rename from XTRA_OCTAVE_DEFS.
+	(OCTINTERP_DLL_DEFS): Rename from XTRA_OCTINTERP_DEFS.
+	(XTRA_CRUFT_LINK_FLAGS): Rename from XTRA_CRUFT_LINK_DEPS.
+
+2006-11-02  John W. Eaton  <jwe at octave.org>
+
+	* README.Cygwin: Rename from README.Windows.
+	* README.MSVC: New file.
+	* README.Windows: Point to the README.Cygwin and README.MSVC files.
+
+2006-11-01  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for PCRE macros we use.  Warn if regex
+	library is not found.  Print hdf5, zlib, umfpack, colamd, ccolamd,
+	cholmod, and cxsparse warnings when we detect the problems.
+
+	* run-octave.in: Handle quoted args properly in exec call?
+
+2006-10-29  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Handle spaces in directory names.
+
+2006-10-28  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in (AH_BOTTOM): If using MSVC, define __WIN32__ before
+	other #ifdefs that use it.
+
+2006-10-27  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AH_BOTTOM): Move DLL defs to
+	libcruft/misc/oct-dlldefs.h and include it here.
+
+	* aclocal.m4 (OCTAVE_PROG_TEXI2PDF): Require OCTAVE_PROG_TEXI2DVI.
+	If texi2pdf is not found but texi2dvi is available, set TEXI2PDF
+	to "$TEXI2DVI --pdf".
+	(OCTAVE_PROG_GHOSTSCRIPT): Also check for gswin32 on Windows systems.
+
+	* Makeconf.in (UNSETCOMSPEC): Define if COMSPEC is defined.
+	From Michael Goffioul <michael.goffioul at swing.be>.
+
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (OCTAVE_EXPORT, OCTAVE_IMPORT): New macros
+	(CRUFT_API, OCTAVE_API, OCTINTERP_API): Define using OCTAVE_EXPORT
+	and OCTAVE_IMPORT.
+
+2006-10-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in (*-*-msdosmsvc): Set library_path_var.
+	Check for _WIN32_WINNT >= 0x0403.  Define _USE_MATH_DEFINES if it
+	is needed.
+	(XTRA_CRUFT_LINK_DEPS): New variable.  Substitute it.
+
+	* aclocal.m4 (OCTAVE_MKDIR_TAKES_ONE_ARG): Perform check with C++
+	compiler.
+
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_PAGER): Also check for more.com for
+	*-*-mingw* and *-*-msdosmsvc systems.
+
+	* configure.in (F77_TOLOWER, F77_APPEND_UNDERSCORE,
+	F77_APPEND_EXTRA_UNDERSCORE): New variables.  Substitute them.
+	* Makeconf.in (F77_TOLOWER, F77_APPEND_UNDERSCORE,
+	F77_APPEND_EXTRA_UNDERSCORE): Substitute here.
+	(do-subst-f77-mangling): New macro.
+
+	* emacs/octave-inf.el (inferior-octave-has-built-in-variables):
+	New defvar.
+	(inferior-octave-resync-dirs): Check to see whether Octave has
+	built-in variables and set inferior-octave-has-built-in-variables.
+	Check inferior-octave-has-built-in-variables to decide whether to
+	send commands that set built-in variables or call functions to
+	change Octave's behavior.
+	Send "disp (pwd ())" to Octave instead of just "pwd".
+	(inferior-octave-startup): Send "more off" to Octave instead of
+	"page_screen_output = 0".
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (RETSIGTYPE_IS_VOID): Define if
+	"$ac_cv_type_signal" = "void".
+
+	* configure.in (*-*-msdosmsvc): Don't check for strftime.
+
+	* configure.in (INCLUDE_DEPS): Set and substitute.
+	(DEPEND_FLAGS, DEPEND_EXTRA_SED_PATTERN): Rearrange way these are set.
+
+	* Makeconf.in (INCLUDE_DEPS): Substitute here, and use to set default
+	value for omit_deps.
+
+2006-10-25  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makeconf.in (ALL_CFLAGS): Include $(XTRA_CDEFS) in the list.
+	(ALL_CXXFLAGS): Include $(XTRA_CXXDEFS) in the list.
+
+	* configure.in (XTRA_CRUFT_DEFS, XTRA_OCTAVE_DEFS,
+	XTRA_OCTINTERP_DEFS): Define and substitute.
+	(AH_BOTTOM) [_MSC_VER]: include definitions for CRUFT_API,
+	OCTAVE_API, and OCTINTERP_API.
+
+	* configure.in (*-*-msdosmsvc): Add "-EHs -MD" to CXXFLAGS.
+	Add "-MD" to CFLAGS.  Add "-MD" to CONFLIB_ARG when checking for
+	libf2c.
+
+	* configure.in (*-*-msdosmsvc): Generate replacement unistd.h.
+	* octMakefile.in (maintainer-clean, distclean): Also remove unistd.h.
+
+	* configure.in (*-*-msdosmsvc): Default sepchar is ';'.
+	Define default LIBS (link against kernel32 and ws2_32).
+	Force having LoadLibrary API.
+
+	* configure.in (AH_BOTTOM) [_MSC_VER]: Define __WIN32__.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in (OCTAVE_VERSION): No need to quote replacement here.
+
+2006-10-24  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Only modify .gdbinit if -g option is given.
+	Use $(/bin/pwd) instead of $(pwd).
+
+2006-10-23  John W. Eaton  <jwe at octave.org>
+
+	* emacs/Makefile.in (SOURCES, DISTFILES, install, install-strip,
+	uninstall): Handle otags name change.
+	* emacs/octave-tags, emacs/octave-tags.1: Rename from otags.
+
+2006-10-17  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for _isnan, _finite, and _copysign.
+
+2006-10-17  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* aclocal.m4 (OCTAVE_CXX_PREPENDS_UNDERSCORE, OCTAVE_CXX_ABI): Use
+	$ac_objext instead of assuming .o.
+	(OCTAVE_PROG_GNUPLOT): Handle *-*-msdos the same as *-*-cygwin*
+	and *-*-mingw32*.
+
+2006-10-17  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for curl_easy_escap instead of
+	curl_global_init.
+
+2006-10-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* configure.in [_MSC_VER]: Disable some warnings.
+	(*-*-msdos): New case for shared libraries.
+	(LIBPRE): New variable.
+	* Makeconf.in: Substitute it.
+
+2006-10-12  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AH_BOTTOM): Don't unconditionally #define
+	OCTAVE_HAVE_POSIX_FILESYSTEM followed by a conditional #undef
+	OCTAVE_HAVE_POSIX_FILESYSTEM since autoconf is commenting out the
+	#undef.
+
+2006-10-09  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (CURL_LIBS, do-subst-config-vals):
+	Substitute CURL_LIBS.
+
+	* configure.in: Check for libcurl.
+
+2006-10-04  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (library_path_var): Substitute value from configure.
+	(do-subst-script-vals): Add library_path_var to the list.
+	* run-octave.in: Substitute value here.
+
+2006-10-03  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Warn if PCRE library is not found.
+
+	* configure.in: Include CAMD_LIBS, AMD_LIBS, and REGEX_LIBS in the
+	summary.
+
+2006-10-03  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Check for libcamd.
+	* Makeconf.in (CAMD_LIBS): New variable.
+
+2006-09-27  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in [--mex]: Include -I. in incflags.
+	From Søren Hauberg <hauberg at gmail.com>.
+
+2006-09-26  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_CONFIG_FILES):
+	Remove doc/interpreter/images/Makefile from the list.
+
+2006-09-16  John W. Eaton  <jwe at octave.org>
+
+	* octave-bug.in: Delete LIBPLPLOT variables.
+
+2006-09-15  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for locale.h and setlocale.
+
+2006-09-13  Christopher Hulbert  <cchgroupmail at gmail.com>
+
+	* run-octave.in (LD_LIBRARY_PATH): Also append LD_LIBRARY_PATH
+	from environment.
+
+2006-08-25  Alexander Barth  <abarth at marine.usf.edu>
+
+	* mkoctfile.in: Accept .f90 and .F90 as Fortran files.
+	Pass $incflags and $defs to Fortran compiler.
+
+2006-08-18  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-subst-texinfo-vals): Don't substitute
+	%CANONICAL_HOST_TYPE%.
+
+2006-08-17  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_GHOSTSCRIPT, OCTAVE_PROG_MAKEINFO,
+	OCTAVE_PROG_TEXI2DVI, OCTAVE_PROG_TEXI2PDF): New macros.
+	* configure.in: Use them.  Maybe print warnings in summary.
+
+2006-07-27  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (localapiarchlibdir): Substitute it here.
+	(do-subst-default-vals): Include it in the sed command here.
+	* configure.in (localapiarchlibdir): New variable.
+	* octave-config.in: Don't quote %VAR% values.
+	(LOCALAPIARCHLIBDIR): New variable.
+
+2006-07-27  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* octave-config.in (OCTAVE_FCNFILEPATH, OCTAVE_IMAGEPATH,
+	OCTAVE_LOCALFCNFILEPATH, OCTAVE_LOCALOCTFILEPATH): Delete variables.
+
+2006-07-26  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in (Options): Accept -g.
+
+	* configure.in: Check for exp2 and log2.
+
+2006-07-25  David Bateman  <dbateman at free.fr>
+
+	* mysparse.c: New file.
+
+2006-06-27  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (maintainer-clean distclean): Remove
+	$(SHELL_SCRIPTS) instead of naming files individually.
+	Also remove .gdbinit.
+
+2006-06-21  John W. Eaton  <jwe at octave.org>
+
+	* examples/myfeval.c, examples/myfevalf.f, examples/myhello.c,
+	examples/myset.c, examples/mystruct.c: New files.
+
+	* mkoctfile.in: New option, --mex.
+
+2006-06-13  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (--enable-64): Include "(EXPERIMENTAL)" in help text.
+	Also set warn_64_bit if no suitable type for octave_idx_type is found.
+	If --enable-64 is specified, print warning in summary message.
+
+2006-06-12  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_CXX_BROKEN_REINTERPRET_CAST): New macro.
+	* configure.in: Use it.
+	* AH_BOTTOM: Conditionally define FCN_PTR_CAST here.
+
+2006-06-08  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-subst-default-vals): Also substitute
+	OCTAVE_DATAROOTDIR.
+
+2006-06-06  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (datarootdir): New variable.
+
+	* acx_lapack.m4 (acx_lapack_ok): 
+	Use AC_LINK_IFELSE+AC_LANG_PROGRAM instead of AC_TRY_LINK
+
+	* aclocal.m4: Use AC_RUN_IFELSE+AC_LANG_SOURCE instead of AC_TRY_RUN.
+
+	* acx_blas.m4, acx_lapack.m4, configure.in, aclocal.m4:
+	Use AS_HELP_STRING instead of AC_HELP_STRING.
+
+	* configure.in: Outside of other macros, use AC_MSG_NOTICE instad
+	of AC_MSG_RESULT.  Check for sys_siglist using method from
+	autoconf manual.
+
+	* configure.in, Makeconf.in: octMakefile.in: Delete plplot cruft.
+
+	* configure.in, aclocal.m4:
+	Use AC_LINK_IFELSE+AC_LANG_PROGRAM instead of AC_TRY_LINK
+	Use AC_COMPILE_IFELSE+AC_LANG_PROGRAM instead of AC_TRY_COMPILE.
+	Use AS_HELP_STRING consistently with AC_ARG_WITH and AC_ARG_ENABLE.
+
+2006-05-23  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for inttypes.h and stdint.h.
+
+2006-05-19  John W. Eaton  <jwe at octave.org>
+
+	* mk-opts.pl (emit_print_function, emit_options_function):
+	Generate print_usage calls with no args.
+
+2006-05-11  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (localfcnfilepath, localoctfilepath, fcnfilepath,
+	imagepath): Delete variables.
+	* Makeconf.in (localfcnfilepath, localoctfilepath, fcnfilepath,
+	imagepath): Likewise.
+	(do-subst-default-vals): Don't substitute them.
+
+	* run-octave.in: Pass --image-path to octave.
+	Use find to recursively add directories to loadpath.
+	Fixup set args command in .gdbinit here.
+
+2006-05-09  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (abs_top_srcdir): Substitute value here.
+
+2006-05-05  David Bateman  <dbateman at free.fr>
+
+	    * Makeconf.in (do-subst-scripts-vals): Also replace 
+	    abs_top_srcdir.
+	    * run-octave.in: Define top_srcdir as an absolute path.
+
+2006-05-04  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (SHELL_SCRIPTS): Include run-octave in the list.
+
+2006-05-02  John W. Eaton  <jwe at octave.org>
+
+	* NEWS: New contents for 3.0.
+	* NEWS.2: Move contents of NEWS here.
+
+2006-04-29  John W. Eaton  <jwe at octave.org>
+
+	* run-octave.in: Execute $builddir/src/octave, not src/octave.
+
+2006-04-26  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* configure.in: Fix apiversion vs. api_version typo.
+
+2006-04-25  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (TARGETS): Include run-octave and .gdbinit in the list.
+	* Makeconf.in (subst-script-vals): New macro.
+	* octMakefile.in (run-octave, .gdbinit): New rules.
+	(DISTFILES): Include run-octave.in and gdbinit.in in the list.
+
+2006-04-17  John W. Eaton  <jwe at octave.org>
+
+	* mk-opts.pl (emit_print_function): Emit code that uses
+	std::ostringstream directly.
+
+2006-04-13  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (CONST_CAST, DYNAMIC_CAST, REINTERPRET_CAST,
+	STATIC_CAST): Delete.
+
+2006-04-12  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: If using g++, also add -Wold-style-cast to CXXFLAGS.
+
+2006-03-28  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Don't check for MPI libraries.
+
+2006-03-27  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Downcase ac_cv_header_mach_o_dyld_h.
+	From Martin Costabel <costabel at wanadoo.fr>.
+
+2006-03-22  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in: (TEXINFO_COLAMD, TEXINFO_CHOLMOD, TEXINFO_UMFPACK):
+	Substitute here.
+	(do-subst-texinfo-vals): New macro definition.
+
+	* configure.in: Don't substitute OCTAVE_VERSION, OCTAVE_HOSTTYPE,
+	or OCTAVE_HOME.
+	(AC_CONFIG_FILES): Remove doc/conf.texi from the list.
+
+2006-03-21  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Only print warnings for missing functionality in
+	summary message.
+
+2006-03-14  John W. Eaton  <jwe at octave.org>
+
+	* mk-opts.pl (emit_print_function): Buffer extra message here and
+	pass to print_usage.
+
+2006-03-09  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-subst-default-vals): Also substitute OCTAVE_RELEASE.
+
+2006-03-08  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Update the test for CXSPARSE for new upstream release.
+	(OCTAVE_VERSION, OCTAVE_HOSTTYPE, OCTAVE_HOME,TEXINFO_UMFPACK, 
+	TEXINFO_COLAMD, TEXINFO_CHOLMOD): New variables for texinfo 
+	documentation.
+	(AC_CONFIG_FILES): Add doc/interpreter/images/Makefile and
+	doc/conf.texi.
+	
+2006-03-02  Kurt Hornik  <Kurt.Hornik at wu-wien.ac.at>
+
+	* emacs/octave-mod.el (octave-indent-for-comment): Make the code
+	match the comments.
+
+2006-03-02  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (ALL_SUBDIRS): Delete.
+	(SUBDIRS): Include src here.
+	(SHELL_SCRIPTS): New variable.
+	(all): Depend on $(SHELL_SCRIPTS) and $(SUBDIRS) with libcruft and
+	liboctave filtered out.
+	(src): Depend on liboctave.
+	(liboctave): Depend on libcruft.
+
+2006-02-09  David Bateman  <dbateman at free.fr>
+
+        * configure.in: Fix for probe of colamd, cccolamd and metis. New test
+        for the presence of cxsparse.
+        Makeconf.in: Include CXSPARSE_LIBS.
+
+2006-01-19  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Use $WITH_PCRE instead of $HAVE_PCRE in shell test.
+
+2006-01-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for mach-o/dyld.h, not Mach-O/dyld.h.
+	From Martin Costabel <costabel at wanadoo.fr>.
+
+2006-01-13  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-mkpkgadd): New macro.
+
+2005-12-14  David Bateman  <dbateman at free.fr>
+
+	* Makeconf.in: Remove OCTAVE_PROG_RUNTEST.
+	* alocal.m4: Remove OCTAVE_PROG_RUNTEST.
+
+	* Makeconf.in: New tests of regex and pcre.
+
+2005-12-13  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (install install-strip): Fix typo.
+	From William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>.
+
+2005-12-05  Kurt Hornik  <Kurt.Hornik at wu-wien.ac.at>
+
+	* emacs/octave-inf.el (inferior-octave-startup):
+	Force a non-empty string for secondary prompt PS2.
+
+2005-12-02  John W. Eaton  <jwe at octave.org>
+
+	* emacs/octave-mod.el (octave-electric-space): Don't indent
+	comments or strings if octave-auto-indent is nil.
+
+2005-11-30  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (install install-strip): Install images and
+	desktop file.
+
+2005-11-29  Rafael Laboissiere  <rafael at debian.org>
+
+	* emacs/octave-mod.el: Ensure that key bindings for 
+	octave-mark-defun and backward-kill-word work in both XEmacs and
+	GNU Emacs.
+
+2005-11-28  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for uname.
+
+2005-11-21  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (DISTFILES): Don't include octave.desktop here.
+	(distclean): Remove octave.desktop here.
+	(maintainer-clean): Not here.
+
+2005-11-01  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (distclean, maintainer-clean):
+	Also remove octave.desktop.
+	From Quentin Spencer <qspencer at ieee.org>.
+
+2005-11-01  Quentin Spencer  <qspencer at ieee.org>
+
+	* octMakefile.in (CONF_DISTFILES): Delete acx_include_dirs.m4 from
+	the list.
+
+2005-10-28  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_ARG_WITH(cholmod, ...)): Fix typo.
+	From Quentin Spencer <qspencer at ieee.org> and
+	Andy Adler <adler at site.uOttawa.ca>.
+
+2005-10-26  John W. Eaton  <jwe at octave.org>
+
+	* configure.in, aclocal.m4: Don't quote "yes".
+
+	* configure.in: Print warning messages for umfpack, colamd,
+	ccolamd, and cholmod as we are searching.  Avoid multiple
+	definitions of message strings.
+
+	* aclocal.m4 (OCTAVE_UMFPACK_SEPERATE_SPLIT):
+	Use new method of finding umfpack.h.
+	* configure.in: Use AC_CHECK_HEADERS instead of
+	ACX_CHECK_HEADER_IN_DIRS.
+	(AC_CONFIG_FILES): Delete liboctave/oct-sparse.h from the list.
+
+	* acx_include_dirs.m4: Delete.
+
+2005-10-26  Arno J. Klaassen  <arno at heho.snv.jussieu.fr>
+
+	* configure.in [*-*-freebsd*] (SH_LDFLAGS): Properly quote.
+	(RLD_FLAG): Set.
+
+2005-10-23  David Bateman  <dbateman at free.fr>
+
+	* configure.in (OCTAVE_UMFPACK_SEPERATE_SPLIT): Check for metis 
+	separately.
+	* PROJECTS: Remove completed sparse matrix tasks.
+
+2005-10-17  Paul Kienzle <pkienzle at users.sf.net>
+
+	* octave.test/system/system.exp: rmdir no longer prints a
+	message if the directory does not exist.
+
+	* octave.test/system/mk-rm-dir-1.m: mkdir/rmdir return 1
+	on success and 0 on failure.
+
+2005-10-17  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (F77_FFLOAT_STORE_FLAG):
+	Check for -ffloat-store option for Fortran compiler and set
+	F77_FLOAT_STORE_FLAG if it works.
+	* Makeconf.in: Substitute it here.
+	(do-subst-config-vals): Substitute OCTAVE_CONF_F77_FLOAT_STORE_FLAG.
+
+2005-10-14  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_PYTHON): New macro.
+	* configure.in: Use it.
+	* Makeconf.in (PYTHON): Substitute it.
+
+2005-10-05  David Bateman  <dbateman at free.fr>
+
+	 mkoctfile.in: allow -idirafter argument.
+
+2005-09-23  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (install install-strip):
+	Conditionally install octave.desktop.
+	(IMAGE_FILES, IMAGE_FILES_NO_DIR): New macros.
+	(DISTFILES): Include IMAGE_FILES in list.
+	(install install-strip): Install image file.
+
+	* aclocal.m4 (OCTAVE_PROG_DESKTOP_FILE_INSTALL): New macro
+	* configure.in: Use it.
+	* Makeconf.in: Substitute DESKTOP_FILE_INSTALL.
+
+	* octave.desktop.in: New file.  From Søren Hauberg <hauberg at gmail.com>.
+	* examples/Makefile.in (SOURCES): Add it to the list.
+	(octave.desktop): New target.
+	(all): Depend on octave.desktop.
+
+2005-09-22  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_PERL): New macro.
+	* configure.in: Use it.
+	* Makeconf.in (PERL): Substitute it.
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2005-09-19  David Bateman  <dbateman at free.fr>
+
+	* octMakefile.in (LN_S): Change to DESTDIR before LN_S to avoid
+	lack of symlinks under mingw.
+
+2005-09-15  John W. Eaton  <jwe at octave.org>
+
+	* oct-sparse.h.in: Move to liboctave.
+	* octMakefile.in (CONF_DISTFILES): Delete it from the list.
+	(maintainer-clean, distclean, install, install-strip, uninstall):
+	Omit rules for oct-sparse.h.
+	* configure.in: Substitute liboctave/oct-sparse.h, not oct-sparse.h.
+
+2005-09-15  David Bateman  <dbateman at free.fr>
+
+	* acx_include_dirs.m4 (AC_CHECK_HEADER_IN_DIRS): Define new macro.
+	* oct-sparse.h.in: New AC_CONFIG_FILE.
+	* configure.in: (AC_CHECK_HEADER_IN_DIRS): Use macro.
+	(AMD_LIBS, COLAMD_LIBS, CCOLAMD_LIBS, CHOLMOD_LIBS): Probe for
+	these sparse library in addition to UMFPACK.
+	(UMFPACK_INCLUDE, AMD_INCLUDE, COLAMD_INCLUDE, CCOLAMD_INCLUDE):
+	AC_SUBST into oct-sparse.h.
+	(LIBGLOB): Probe for external glob/fnmatch, define LIBGLOB.
+	(sepchar): Define path seperation character in system dependent 
+	manner. Use it with OCTAVE_SET_DEFAULT.
+	(SEPCHAR, SEPCHAR_STR): Dpend on sepchar.
+	(DL_LDFLAGS): Define for cygwin and mingw.
+	(-lwsock32): Add to LIBS.
+	(loadlibrary_api): Set for mingw/cygwin and autoconf test appears
+	broken.
+	* Makeconf.in: Don't use ";" as sed seperation to avoid confusion
+	with sepchar.
+	(LIBGLOB, AMD_LIBS, COLAMD_LIBS, CCOLAMD_LIBS, CHOLMOD_LIBS, 
+	sepchar): Substitute.
+	* octMakefile.in: (CONF_DISTFILES): Add acx_include_dirs.m4 and
+	oct-sparse.h.in
+	(oct-sparse.h): Include in install and clean directives
+
+2005-08-31  Pascal A. Dupuis  <Pascal.Dupuis at esat.kuleuven.be>
+
+	* emacs/octave-inf.el (inferior-octave-startup): Call
+	inferior-octave-resync-dirs here.
+
+2005-07-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (SH_LDFLAGS): Add -Wl,--enable-auto-image-base for
+	Cygwin and MinGW.
+
+2005-06-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AH_BOTTOM): Also define GCC_ATTR_DEPRECATED.
+
+2005-06-02  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (do-subst-default-vals): Substitute
+	${localstartupfiledir}, not ${localstartupfile} (which is undefined).
+
+2005-05-16  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Change UMFPACK_LONG_IDX to IDX_TYPE_LONG.
+
+2005-05-04  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_CHECK_LIB($zlib_lib, ...)): Check for
+	gzclearerr instead of deflate.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_ARG_WITH(umfpack)): List -lumfpack ahead of -lamd.
+	From Dmitri A. Sergatskov <dasergatskov at gmail.com>.
+
+2005-04-29  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Add UMFPACK_LONG_IDX
+
+2005-04-21  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_CONFIG_FILES): Remove install-octave from the list.
+	(AH_BOTTOM): Define SIZEOF_OCTAVE_IDX_TYPE.
+
+2005-04-14  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in: Only perform link step if we have some object files.
+	If only -v or --version is supplied, print version info and exit.
+
+2005-04-08  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (maintainer-clean distclean):
+	Remove install-octave from the list of files to remove.
+	(install-octave.in): Delete file.
+	(DISTFILES): Remove it from the list.
+
+	* Initial merge of 64-bit changes from Clinton Chee:
+
+	2005-04-07  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (--enable-64): Make default disabled.
+
+	2005-04-06  John W. Eaton  <jwe at octave.org>
+
+	* mk-opts.pl (emit_show_function, emit_set_functions,
+	emit_print_function): Also accept "octave_idx_type" and
+	"Array<octave_idx_type>".
+
+	2005-04-01  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (USE_64_BIT_IDX_T): Substitute value.
+	(do-subst-config-vals): Add to list of substitutions.
+
+	* configure.in (AC_CONFIG_FILES): Perform substitutions on
+	liboctave/oct-types.h too.
+	Handle --enable-64.
+
+2005-04-06  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Split the HDF5 and zlib detection code, so that zlib 
+	can be used for compressed load/save in the absence of HDF5.
+
+	* Makeconf.in: Define UMFPACK_LIBS.
+
+	* Configure.in: Slightly alter the UMFPACK detection code so that it 
+	correctly detects cblas bindings or not.
+
+2005-03-22  John W. Eaton  <jwe at octave.org>
+
+	* Makeconf.in (GLPK_LIBS): Substitute value.
+	(do-subst-config-vals): Add to list of substitutions.
+
+	* configure.in: Check for glpk.
+
+	* emacs/octave-mod.el (octave-abbrev-table): Omit fifth and sixth
+	arguments from define-abbrev for compatibility with some older
+	versions of Emacs.
+
+2005-03-21  John W. Eaton  <jwe at octave.org>
+
+	* octave-bug.in: Try harder to find default pager (use code
+	similar to that used for finding default editor).
+
+2005-03-17  Shan G. Smith  <shan at cybertrails.com>
+
+	* configure.in: Move check for -lumfpack to after check for blas.
+
+2005-03-17  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: If first check for -lumfpack fails try again with
+	-lcblas as an additional library.
+
+	* configure.in: Change defaults to enable shared libraries and
+	dynamic linking and disable static libraries.
+
+2005-03-15  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (DISTFILES): Remove texi2dvi from the list.
+
+	* emacs/octave-inf.el, emacs/octave-mod.el, emacs/octave-hlp.el:
+	Import changes from Emacs.
+
+2005-03-14  Rafael Laboissiere  <rafael at debian.org>
+
+	* emacs/octave-mod.el (octave-end-keywords): Omit "end" from the list.
+	(octave-reserved-words): Include "end" here.
+	(octve-block-match-alist): Don't include "end" here.
+
+2005-03-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for umfpack/umfpack.h instead of just umfpack.h.
+
+2004-06-22  David Bateman  <dbateman at free.org>
+
+	* configure.in: Check for UMFPACK library and header files.
+
+2005-03-14  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Also print a warning if HDF5 library is not found.
+
+2005-03-10  John W. Eaton  <jwe at octave.org>
+
+	* mkoctfile.in: Accept -R DIR.
+
+2005-03-09  John W. Eaton  <jwe at octave.org>
+
+	* examples/Makefile.in (bin-dist): Delete target.
+	(BINDISTFILES): Delete variable.
+	* emacs/Makefile.in: Likewise.
+
+	* octMakefile.in (VERSION, ARCH, binary-dist): Delete targets.
+	(XBINDISTFILES, BINDISTFILES, BINDISTSUBDIRS): Delete variables.
+
+2005-03-04  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (GXX_PICKY_FLAGS): Don't include
+	-Wmissing-prototypes or -Wstrict-prototypes.
+
+2005-03-02  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_CC_FLAG, OCTAVE_CXX_FLAG, OCTAVE_F77_FLAG):
+	Use AC_LINK_IFELSE instead of AC_TRY_LINK.
+
+	* configure.in (OCTAVE_LOCAL_BUFFER): Use < T > instead of <T>.
+	From Clinton Chee <chee at parallel.hpc.unsw.edu.au>.
+
+2005-03-01  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_CONFIG_FILES): Remove libcruft/odessa/Makefile
+	from the list.
+
+2005-03-01  Todd Neal  <tolchz at gmail.com>
+
+	* examples/make_int.cc: DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA now
+	takes three arguments.
+
+	* octMakefile.in (SUBDIRS, CLEANSUBDIRS):
+	Remove @GLOB_DIR@ from the list.
+
+2005-02-28  John W. Eaton  <jwe at octave.org>
+
+	* octMakefile.in (DISTDIRS): Remove glob from the list.
+	(dist): No need to clean up in glob subdirectory.
+	* glob: Delete directory.
+	* Makeconf.in (GLOB_INCFLAGS, LIBGLOB): Delete.
+	(do-subst-config-vals): Don't substitute them.
+	(INCFLAGS): Remove $(GLOB_INCFLAGS) from the list.
+	* configure.in: Don't test for glob or fnmatch.
+
+2005-02-22  Shan G. Smith  <shan at cybertrails.com>
+
+	* mkoctfile.in: If not linking, then use output file name
+	specified with -o.
+
+2005-02-21  John W. Eaton  <jwe at octave.org>
+
+	* texi2dvi: Delete our private version.
+
+	* Makeconf.in (MAKEINFO): Define.
+	(TEXI2DVI): Define as texi2dvi, not $(top_srcdir)/texi2dvi.
+
+2005-02-09  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for canonicalize_file_name and resolvepath.
+
+2005-02-02  John W. Eaton  <jwe at octave.org>
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2005-01-18  John W. Eaton  <jwe at octave.org>
+
+	* octave-bug.in: Try harder to find default editor (stolen from
+	bashbug).
+
+2004-12-17  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Use AC_GNU_SOURCE.
+
+2004-12-17  Orion Poplawski  <orion at cora.nwra.com>
+
+	* configure.in: Also check for signbit decl.
+
+2004-12-03  John W. Eaton  <jwe at octave.org>
+
+	* aclocal.m4 (OCTAVE_PROG_GPERF): Check with -L C++, not -L ANSI_C.
+	* Makefile.in (header-msg): Change recommended gperf version to
+	3.0.1 or more recent.
+
+2004-11-12  John W. Eaton  <jwe at octave.org>
+
+	* Back off on -ffloat-store until we decide whether it is really
+	necessary.
+
+2004-11-11  John W. Eaton  <jwe at octave.org>
+
+	* (OCTAVE_PROG_GNUPLOT): Don't set GNUPLOT_BINARY before calling
+	AC_CHECK_PROGS(GNUPLOT_BINARY, ...).
+
+	* configure.in: Use it to see if the C, C++, and Fortran compilers
+	accept -ffloat-store.
+	* aclocal.m4 (OCTAVE_F77_FLAG): New macro.
+
+2004-09-08  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (GXX_PICKY_FLAGS): Remove -fno-nonnull-objects.
+	(GCC_PICKY_FLAGS): Remove -Wnested-externs -Wid-clash-31.
+	From Quentin Spencer <qspencer at ieee.org>.
+
+	* configure.in (GCC_PICKY_FLAGS): Remove -Winline.
+
+2004-09-07  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Check for round.
+
+2004-06-22  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Use -Wl,-Bsymbolic for MKOCTFILE_DL_LDFLAGS on
+	GNU/Linux systems but not for SH_LDFLAGS.
+    
+2004-04-22  John W. Eaton  <jwe at octave.org>
+
+	* configure.in: Add -Wl,-Bsymbolic to SH_LDFLAGS for GNU/Linux
+	systems.  From Fredrik Lingvall <Fredrik.Lingvall at signal.uu.se>.
+
+	* mkoctfile.in: Allow -Wx,option style options to be passed to the
+	compiler.  From Al Niessner <Al.Niessner at jpl.nasa.gov>.
+
+2004-04-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Delete code for --with-ieee754.
+	Use OCTAVE_IEEE754_DATA_FORMAT.
+
+	* aclocal.m4 (OCTAVE_IEEE754_DATA_FORMAT): New macro, based on
+	configure.in code for HAVE_IEEE754_COMPLIANCE.
+
+2004-04-06  David Bateman  <dbateman at free.fr>
+
+  	* configure.in : add the option --with-ieee754 and use it to define
+	HAVE_IEEE754_COMPLIANCE
+
+2004-04-02  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Warn about g++ 2.9x versions.
+
+2004-04-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (dist): Also make bz2 file and compute md5
+	checksums of both gz and bz2 files.
+
+2004-03-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: No longer accept --with-g77 (it is still possible
+	to use --with-f77=g77).
+
+2004-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for -mieee instead of -mieee-with-inexact.
+
+2004-02-20  Per Persson  <persquare at mac.com>
+
+	* mkoctfile.in (LINK_DEPS): Include $LDFLAGS in the list.
+
+2004-02-18  Per Persson  <persquare at mac.com>
+
+	* configure.in (*-*-darwin*): Define SONAME_FLAGS.
+
+2004-02-16  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Test for the presence of FFTW 3.x and use it in
+	preference to FFTW 2.x.  Define HAVE_FFTW3
+
+2004-02-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in (LINK_DEPS): Include $LIBS and $RLD_FLAG.
+	Use $OCTAVE_LIBS instead of listing libs individually.
+
+2004-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Delete INCLUDE_LINK_DEPS.  Fix help text.
+	Always define LINK_DEPS.
+	(LINK_DEPS): Also include FLIBS in the list.
+
+	* Makeconf.in (INCLUDE_LINK_DEPS): Don't substitute.
+	(do-subst-config-vals): Delete INCLUDE_LINK_DEPS.
+	* configure.in (INCLUDE_LINK_DEPS): Delete.
+
+	* mkoctfile (SH_LD, SH_LDFLAGS): Delete.
+	(DL_LD, DL_LDFLAGS): New variables.  Use them instead of SH_LD and
+	SH_LDFLAGS for creating .oct files.
+	Fix help text.
+
+	* configure.in (MKOCTFILE_SH_LDFLAGS): Delete.
+	(MKOCTFILE_DL_LDFLAGS): New variable, default to DL_LDFLAGS.
+
+	* Makeconf.in (do-subst-config-vals): Add DL_LD, DL_LDFLAGS, and
+	MKOCTFILE_DL_LDFLAGS to the list of substitutions.
+	Delete MKOCTFILE_SH_LDFLAGS.
+
+2004-02-14  Per Persson  <persquare at mac.com>
+
+	* configure.in (DL_LD, DL_LDFLAGS): New variables, default to
+	SH_LD and SH_LDFLAGS, respectively.
+	Define independently for SH_LD and SH_LDFLAGS for *-*-darwin* targets.
+	* Makeconf.in (DL_LD, DL_LDFLAGS): Substitute them here.
+
+2004-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (header-msg): Required bison version now 1.31 or later.
+
+2004-01-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el: If line-end-position is not defined,
+	provide it as an alias for point-at-eol.
+
+2004-01-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el: If line-beginning-position is not defined,
+	provide it as an alias for point-at-bol.
+
+2004-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM):
+	Define OCTAVE_LOCAL_BUFFER using vector<T> instead of auto_ptr.
+	Suggested by Paul Thomas <Paul.Thomas at jet.efda.org>
+
+2004-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (maintainer-clean, distclean):
+	Remove Makefile and autom4te.cache.
+
+2004-01-14  David Bateman  <dbateman at free.fr>
+
+	* configure.in: Test for the presence of the function 
+	H5Gget_num_objs	in HDF5 library, and define HAVE_H5GGET_NUM_OBJS.
+ 	
+2004-01-06  Per Persson  <persquare at mac.com>
+
+	* aclocal.m4 (OCTAVE_CXX_PREPENDS_UNDERSCORE): Recognize
+	*-*-darwin*, not *-*-darwin6*.
+
+2003-12-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* INSTALL: Update to newer version from autoconf.
+
+2003-11-26  Cyril Humbert  <Cyril.Humbert at univ-mlv.fr>
+
+	* octave-config.in (--m-site-dir): Echo $LOCALVERFCNFILEDIR, not
+	$OCTAVE_LOCALVERFCNFILEDIR.
+	(--oct-site-dir): Echo $LOCALVEROCTFILEDIR, not
+	$OCTAVE_LOCALVEROCTFILEDIR.
+
+2003-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Also maybe add -W to WARN_CFLAGS and WARN_CXXFLAGS.
+
+2003-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (SHLLIB_VER): Fix typo.
+
+	* Makeconf.in (WARN_CFLAGS, WARN_CXXFLAGS): Substitute them.
+	(ALL_CFLAGS, BUG_CFLAGS): Add $(WARN_CFLAGS).
+	(ALL_CXXFLAGS, BUG_CXXFLAGS): Add $(WARN_CXXFLAGS).
+	(UGLY_ALL_CXXFLAGS): Delete.
+
+	* configure.in: Add -Wall and -Wshadow to WARN_CFLAGS and
+	WARN_CXXFLAGS instead of CFLAGS and CXXFLAGS.
+
+2003-11-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: If we need alloca, then also include it in LIBGLOB.
+
+2003-11-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Preserve CFLAGS and CXXFLAGS before doing anything.
+	Maybe add -Wshadow to CFLAGS and CXXFLAGS.
+
+2003-10-24  Stefan Monnier  <monnier at iro.umontreal.ca>
+
+	* emacs/octave-mod.el (octave-comment-start): Simplify.
+	(octave-point): Remove.
+	(octave-in-comment-p, octave-in-string-p)
+	(octave-not-in-string-or-comment-p, calculate-octave-indent)
+	(octave-blink-matching-block-open, octave-auto-fill):
+	Use line-(beginning|end)-position instead.
+
+2003-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-inf.el (inferior-octave-prompt): Don't bother
+	matching "octave.bin".
+
+2003-10-29  Lute Kamstra  <lute at gnu.org>
+
+	* emacs/octave-inf.el (inferior-octave-prompt): Recognize
+	version number in prompt.
+
+2003-10-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-mode-syntax-table): Allow % to be a
+	comment character.
+
+2003-10-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (AWK): Substitute and export it.
+	* configure.in: Also check for AWK.
+
+2003-10-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_PREREQ): Require 2.57.
+
+2003-09-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): Don't define HEAVYWEIGHT_INDEXING here.
+
+2003-07-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-variables): Delete
+	propagate_empty_matrices from the list.
+
+	* ck-oct-fcns.m: Delete.
+
+2003-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Warn if --enable-dl but not --enable-shared.
+
+2003-07-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-variables): Delete
+	default_return_value and define_all_return_values from the list.
+	Add warn_undefined_return_values to the list.
+
+2003-07-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-variables):
+	Add warn_empty_list_elements and warn_resize_on_range_error to the
+	list.
+	Delete empty_list_elements_ok and resize_on_range_error from the
+	list.
+
+2003-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-variables): Add warn_neg_dim_as_zero
+	to the list.
+	Delete treat_neg_dim_as_zero from the list.
+
+2003-07-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-variables): Include
+	DEFAULT_EXEC_PATH, DEFAULT_LOAD_PATH, crash_dumps_octave_core,
+	sighup_dumps_octave_core, sigterm_dumps_octave_core,
+	warn_imag_to_real, warn_num_to_str, warn_str_to_num, and
+	warn_fortran_indexing in the list.
+	Delete ok_to_lose_imaginary_part, implicit_num_to_str_ok,
+	implicit_str_to_num_ok, prefer_column_vectors,
+	prefer_zero_one_indexing, and do_fortran_indexing from the list.
+
+2003-07-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-default-vals): Substitute OCTAVE_API_VERSION.
+	* octave-config.in: Handle new variable OCTAVE_API_VERSION.
+
+	* octMakefile.in (DIRS_TO_MAKE): Delete undefined vars
+	$(localfcnfilepathdirs) and $(localoctfilepathdirs) from the list.
+
+	* octave-config.in: Handle new variables OCTAVE_LOCALAPIFCNFILEDIR
+	and OCTAVE_LOCALAPIOCTFILEDIR
+
+	* configure.in (localapifcnfiledir): New variable.
+	(localfcnfilepath): Add it to the list.
+	(localapioctfiledir): New variable.
+	(localoctfilepath): Add it to the list.
+	* Makeconf.in (do-subst-default-vals): Substitute new varibles.
+
+	* Makeconf.in (getapiversion, apiversion): New macros.
+
+	* octMakefile.in (DIRS_TO_MAKE): Include $(localverarchlibdir) in
+	the list.
+
+2003-07-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in: Set and substitute values for startupfiledir and
+	localstartupfiledir.
+
+	* octave-config.in: Allow other configuration defaults to be
+	accessed using --variable VAR option.
+
+2003-07-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (distclean): remove install-octave here.
+
+2003-06-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: If user doesn't specify --enable-rpath, then
+	default is to enable it.
+
+2003-06-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (GNUPLOT_HAS_FRAMES): Eliminate variable.
+
+	* emacs/octave-mod.el (octave-variables): Eliminate
+	gnuplot_has_multiplot.
+
+2003-05-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: In check for f_open in libf2c, only use
+	-L. -lconflib if we have created libconflib.a.
+
+2003-05-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_GPERF): Provide struct decl so -t option
+	succeeds with gperf 3.0.
+
+	* Makeconf.in (NO_OCT_FILE_STRIP): Use -C arg for make.
+
+	* octMakefile.in (DIRS_TO_MAKE): Use $(shell ...) instead of `...`.
+
+2003-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in, octMakefile.in, emacs/Makefile.in,
+	examples/Makefile.in: Handle DESTDIR.
+
+2003-05-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (sbindir): New variable substitution.
+
+2003-04-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't define WITH_KPATHSEARCH.
+
+2003-04-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Look for wsock32 library on MinGW systems.
+
+2003-04-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (OCTAVE_LOCAL_BUFFER): Always allocate temporary
+	buffer using new.
+
+2003-04-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in octMakefile.in: Delete kpathsea targets.
+
+	* kpathsea: Delete all files and directory.
+
+	* configure.in: Don't run configure in kpathsea subdirectory.
+
+	* README.kpathsea: New file.
+	* octMakefile.in (DISTFILES): Include it in the list.
+
+	* Makeconf.in (do-subst-config-vals): Don't substitute it.
+
+	* configure.in: Also check for basename.
+	Don't substitute LIBKPATHSEA.
+
+2003-04-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): Don't assume that __WIN32__ will be
+	defined when __CYGWIN__ is defined.
+
+2003-03-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Only complain for g++ earlier than 2.95.
+	Try harder to get version number only.
+
+2003-03-05  Paul Kienzle <pkienzle at users.sf.net>
+
+	* aclocal.m4 (OCTAVE_DYNAMIC_AUTO_ARRAYS): New macro.
+	* configure.in: Use it.
+	(AH_BOTTOM): Check HAVE_DYNAMIC_AUTO_ARRAYS instead of __GNUG__.
+
+2003-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Undo previous change.
+	* Makeconf.in: Likewise.
+
+2003-03-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (KPATHSEA_INCFLAGS): New variable.
+	* Makeconf.in (KPATHSEA_INCFLAGS): Substitute it.
+	(do-subst-config-vals): Add it to the list.
+	(INCFLAGS): Add $(KPATHSEA_INCFLAGS).
+
+2003-02-23  Paul Kienzle <pkienzle at users.sf.net>
+
+	* aclocal.m4 (OCTAVE_PLACEMENT_DELETE): New macro.
+	* configure.in: Use it.
+	(AH_BOTTOM): Don't define HAVE_PLACEMENT_DELETE here.
+
+2003-02-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Allow RLD_FLAG to be set using --enable-rpath arg.
+
+	* configure.in: Fix default RLD_FLAG value for *-sgi-*.  From 
+	Paul Kienzle <pkienzle at users.sf.net>.
+
+	* configure.in: Check for long long int and unsigned long long int.
+
+	* configure.in (AH_BOTTOM): Define HAVE_PLACEMENT_DELETE for gcc
+	3.2 and later.
+
+	* configure.in: Check for copysign and signbit.
+
+2003-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/Makefile.in (DISTFILES): Add otags.1 to the list.
+
+2003-02-18  Dirk Eddelbuettel <edd at debian.org>
+
+	* emacs/otags.1: New file.
+
+2003-02-18  David Bateman <dbateman at free.fr>
+
+	* configure.in: Eliminate linpack
+
+2003-02-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for mkstemp too.
+
+2003-02-13  Arno Klaassen  <arno at scito.com>
+
+        * configure.in: Fix SH_LD and SH_LDFLAGS for -*-*-freebsd*.
+
+2003-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Use '$(CXX)', '$(AR)', not "$CXX" and "$AR" when
+	setting variables for building shared libraries.
+
+2003-02-13  Paul Kienzle <pkienzle at users.sf.net>
+
+	* examples/make_int.cc: Support for ISO standard compilers.
+
+2003-01-22  Richard Stallman <rms at gnu.org>
+
+	* emacs/octave-mod.el (octave-mode-map): Avoid binding keys that
+	are reserved for users.
+
+2003-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in: Fix typo in previous change.
+
+2003-01-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (MKOCTFILE_INCFLAGS): Skip -I$(includedir) if
+	$(includedir) is /usr/include.
+
+2003-01-16  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* Makeconf.in (SED): Export to subshells.
+
+2003-01-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't bother with compiler flags for
+	explicit/no-implicit template instantiation.
+
+2003-01-11  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in, Makeconf.in: Allow setting of BUILD_LDFLAGS.
+
+2003-01-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* autogen.sh: Use --force for autoconf and autoheader.
+
+2003-01-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (CONF_DISTFILES): Include acx_blas.m4 and
+	acx_lapack.m4.
+
+	* configure.in (BUILD_CC, BUILD_CFLAGS, BUILD_CXX,
+	BUILD_CXXFLAGS): Kluge for Sun C/C++.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Default value of BUILD_CXX is $CXX, not g++.
+	(AH_BOTTOM): Define __USE_STD_IOSTREAM if using Compaq C++ compiler.
+	For compiler/linker options, use -Wl,OPT instead of -Xlinker OPT.
+	Check for -ieee option for the C and C++ compilers on alpha systems.
+
+2003-01-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Fail on all gcc 1.x and 2.x versions.
+
+2002-12-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (OCTAVE_LOCAL_BUFFER): New macro.
+
+2002-12-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Include $LIBOCTINTERP in the stand alone link command.
+	Define LIBOCTAVE, LIBOCTINTERP, LIBCRUFT, LIBREADLINE using -lLIB.
+
+2002-12-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-script-install, do-script-uninstall):
+	New macros, used in Makefiles in scripts subdirectory.
+	(do-script-install): Use new scripts/mkpkgadd script to construct
+	PKG_ADD files.
+
+2002-12-03  Nix  <nix at esperi.demon.co.uk>
+
+	* configure.in: Use AC_CHECK_DECL in conjunction with
+        AC_DECL_SYS_SIGLIST to ensure signal.h is searched.
+
+2002-12-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Dont't set SONAME_FLAGS for alpha alpha*-dec-osf*
+	systems.
+
+2002-11-29  Paul Kienzle <pkienzle at users.sf.net>
+
+	* mkoctfile.in: Include "$incflags $def" in commands to generate
+	dependecies.
+
+2002-11-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (do-subst-config-vals): Substitute OCTAVE_BINDIR.
+
+	* configure.in (MKOCTFILE_SH_LDFLAGS): New variable.
+	* Makeconf.in (do-subst-config-vals): Substitute
+	OCTAVE_CONF version of this variable.
+
+	* mkoctfile.in: Set SH_LDFLAGS from MKOCTFILE_SH_LDFLAGS, not
+	SH_LDFLAGS.
+	(VERSION): Substitute value of OCTAVE_CONF_VERSION.
+
+	* configure.in (NO_OCT_FILE_STRIP): New variable.
+	* Makeconf.in (do-subst-config-vals): Substitute it.
+	* mkoctfile.in (no_oct_file_strip_on_this_platform): New variable.
+
+2002-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (OCTAVE_CXX_PRAGMA_INTERFACE_IMPLEMENTATION):
+	Delete use.
+
+	* aclocal.m4 (OCTAVE_LANG_PROG_NO_CONFDEFS): Delete.
+	(OCTAVE_CXX_PRAGMA_INTERFACE_IMPLEMENTATION): Delete.
+
+2002-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for dlopen last, to avoid broken
+	compatibility libraries.
+	Default value for SHLLIB is '$(SHLEXT)', not $SHLEXT.
+
+2002-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (USE_EXCEPTIONS_FOR_INTERRUPTS): No need to define.
+
+2002-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for sigsetjmp and siglongjmp.
+	(AH_BOTTOM): If both are found, define OCTAVE_HAVE_SIG_JUMP.
+	Also check for sig_atomic_t, typedef it if not available.
+
+2002-11-10  Per Persson  <persquare at mac.com>
+
+	* configure.in: Detect dyld API for dynamic linking on OS X.
+
+2002-11-09  Per Persson  <persquare at mac.com>
+
+	* configure.in: Use $(TOPDIR)/src/octave, not $(bindir)/octave for
+	-bundle-loader argument.	
+
+	* aclocal.m4 (OCTAVE_CXX_PREPENDS_UNDERSCORE): Force result for OS X.
+
+2002-11-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Set FPICFLAG, Also set CXXPICFLAG, CPICFLAG,
+	FPICFLAG, and INCLUDE_LINK_DEPS for OS X.
+
+	* acx_blas.m4 (LIBS): Also check for Apple vecLib framework.
+
+2002-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): Define USE_EXCEPTIONS_FOR_INTERRUPTS.
+
+2002-11-04  Joseph P. Skudlarek  <jskud at jskud.com>
+
+	* emacs/otags: handle declarations without arguments and/or return
+	values.
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (SHLEXT_VER, SHLLIB_VER, SHLBIN_VER): Use
+	$(version), not $(VERSION).
+
+2002-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (HAVE_DLOPEN_API, HAVE_SHL_LOAD_API,
+	HAVE_LOADLIBRARY_API): Delete.
+	(do-subst-config-vals): Don't substitute them here.
+
+2002-10-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (ENABLE_DYNAMIC_LINKING): Rename from
+	WITH_DYNAMIC_LINKING.
+	* Makeconf.in: Likewise.
+	* examples/hello.cc: Likewise.  Improve comments.
+
+	* configure.in: Revive --enable-dl to set default value for
+	WITH_DYNAMIC_LINKING.
+
+	* configure.in: Also set SHLEXT_VER, SHLLIB_VER, SHLBIN_VER.
+	* Makeconf.in: Substitute them here.
+	Also substitute SHLLINKEXT.
+
+2002-10-25  Per Persson  <persquare at mac.com>
+
+	* aclocal.m4 (OCTAVE_CXX_PRAGMA_INTERFACE_IMPLEMENTATION): Fix
+	first test to properly fail on OS X.  Fix typo in final test to
+	set result.
+
+2002-10-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-opts.pl (emit_opt_class_header): Make set_options another
+	name for copy.
+
+2002-10-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Don't substitute
+	OCTAVE_CONF_OCTAVE_LITE.
+	(OCTAVE_LITE): Delete.
+
+	* Makeconf.in: Use HAVE_DLOPEN_API, HAVE_LOADLIBRARY_API, and
+	HAVE_SHL_LOAD_API instead of WITH_DL and WITH_SHL.
+
+	* configure.in: Rewrite the way we handle dynamic linking.
+	If dynamic linking is used always do what was previously only
+	enabled by --enable-lite-kernel.
+
+2002-10-17  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in: Define WITH_DYNAMIC_LINKING based on --enable-shared.
+	Add -lwsock32 to LIBS for MinGW.
+
+2002-10-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_LANG_PROG_NO_CONFDEFS): New macro.
+	(OCTAVE_CXX_PRAGMA_INTERFACE_IMPLEMENTATION): Use it along with
+	AC_LINK_IFELSE instead of AC_TRY_LINK.
+	Require both programs to compile for success.
+
+2002-10-16  Paul Kienzle <pkienzle at users.sf.net>
+
+	* aclocal.m4: Both Cygwin and MinGW don't prepend underscores.
+	* configure.in: MinGW builds shared libraries the same as Cygwin.
+	MinGW must link to winsock explicitly.
+	* install-octave.in: MinGW and Cygwin both need OCTAVE_HOME.
+
+2002-10-15  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in (library_path_var): New variable.
+
+2002-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (SH_LDFLAGS): Additional options for Cygwin:
+	-Wl,--export-all-symbols -Wl,--enable-auto-import.
+
+	* Makeconf.in (TERMLIBS): Substitute here.
+
+	* configure.in: Define OCTAVE_USE_WINDOWS_API if 
+	defined (__WIN32__) && ! defined (__CYGWIN__), not if
+	defined (__WIN32__) || ! defined (__CYGWIN__).
+	Also call AC_SUBST for TERMLIBS.
+
+2002-10-14  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in: Use correct SHLEXT and PICFLAG for Cygwin.
+	* configure.in: Cygwin must link against -loctave.dll, etc.
+
+	* configure.in: Define INCLUDE_LINK_DEPS because Cygwin needs DLLs
+	to be linked against their dependencies.
+	* Makeconf.in: Ditto.
+
+	* configure.in: Define SHLLIB and SHLBIN because Cygwin doesn't
+	link against shared libs but instead against -lxxx.dll.  LIB and
+	BIN are the link and load forms respectively of the library.
+	* Makeconf.in: Ditto, and define the corresponding XXX_VER.
+
+	* configure.in: Remove LIBOCT_READLINE and LIBOCT_PATHSEARCH
+	because they are merged into LIBOCTAVE to avoid circular
+	dependencies.
+	* Makeconf.in: Ditto.
+	* mkoctfile.in: Ditto.
+
+	* aclocal.m4 (OCTAVE_ENABLE_READLINE): Define LIBREADLINE because
+	Cygwin requires liboctave to be linked against -lreadline so
+	including it in LIBS isn't sufficient.
+	* mkoctfile.in: Substitute and use LIBREADLINE here.
+
+	* aclocal.m4 (OCTAVE_CXX_PREPENDS_UNDERSCORE): Force no for cygwin.
+
+2002-10-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): Maybe define OCTAVE_USE_WINDOWS_API
+	and OCTAVE_HAVE_WINDOWS_FILESYSTEM.
+
+2002-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_GNUPLOT): AC_DEFINE GNUPLOT_BINARY
+	Default value on Windows systems is pgnuplot.
+	If not cross compiling and no gnuplot program is found, set
+	default to gnuplot.  Set defaults for multiplot and frames.  Check
+	for pgnpuplot, pipe-gnuplot, and gnuplot on Windows systems.
+
+	* configure.in (BUILD_EXEEXT): New variable.
+	* Makeconf.in (BUILD_EXEEXT): Substitute it here.
+
+	* aclocal.m4 (OCTAVE_CXX_PRAGMA_INTERFACE_IMPLEMENTATION):
+	Add second test for OS X.
+
+2002-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXX_PRAGMA_INTERFACE_IMPLEMENTATION): New macro.
+	* configure.in: Use it.
+
+	* configure.in (BUILD_CC, BUILD_CFLAGS, BUILD_CXX, BUILD_CXXFLAGS): 
+	Set default values if cross compiling.
+
+	* aclocal.m4 (OCTAVE_PROG_NM): Do the right thing for cross compiling.
+	(OCTAVE_CXX_PREPENDS_UNDERSCORE): Require OCTAVE_PROG_NM.
+	(OCTAVE_CXX_ABI): Likewise.
+
+	* Makeconf.in (BUILD_CC, BUILD_CFLAGS, BUILD_CXX, BUILD_CXXFLAGS):
+	New variables for cross compiling.
+
+2002-10-07  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in: Check for raise.
+
+2002-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_SED): New macro, adapted from autoconf
+	patches mailing list archive, written by Robert Boehne
+	<rboehne at ricardo-us.com>.
+	* configure.in: Use it.
+	* Makeconf.in: Substitute SED, use $(SED), not sed.
+	(do-subst-conffig-vals): Substitute it here too.
+	* mkoctfile.in: And here.  Use $SED, not sed.
+	* octave-bug.in: Likewise.
+	* install-octave.in: Likewise.
+
+2002-09-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't define mkdir here.
+
+2002-09-25  Mumit Khan  <khan at nanotech.wisc.edu>
+ 
+ 	* aclocal.m4 (OCTAVE_MKDIR_TAKES_ONE_ARG): New macro to determine if
+ 	host mkdir accepts only one arg instead of the usual two.
+ 	* configure.in: Use. Check for direct.h.
+ 	(mkdir): Define.
+ 
+2002-09-26  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in: Check for conio.h.
+	Check for _kbhit.
+
+2002-09-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): Don't define
+	USE_PRAGMA_INTERFACE_IMPLEMENTATION.
+
+2002-09-26  Paul Kienzle <pkienzle at users.sf.net>
+
+	* configure.in: Fix syntax errors in !HAVE_XXX_T.
+	Don't require terminal control for build.
+
+2002-09-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Fix typedefs used in AH_BOTTOM.
+
+2002-09-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): If using g++, define
+	USE_PRAGMA_INTERFACE_IMPLEMENTATION.
+
+2002-08-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for sstream.
+
+2002-08-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (%.d : %.cc): Add $*.df to LHS of dependency list.
+
+2002-08-15  Paul Kienzle <pkienzle at users.sf.net>
+
+	* mk-opts.pl: Add support for INCLUDE = "...".
+
+2002-08-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-opts.pl: Handle Array<int> too.
+
+2002-08-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-opts.pl (emit_options_function): Emit newline at EOF.
+
+2002-08-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in: Use $@-t instead of $@.tmp or $@.t.
+
+2002-07-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-opts.pl: New file.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+2002-07-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_CONFIG_FILES): Add libcruft/dasrt/Makefile to
+	the list.
+
+2002-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_CONFIG_FILES): Add libcruft/odessa/Makefile to
+	the list.
+
+2002-05-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Maybe add -fno-coalesce-templates to XTRA_CXXFLAGS
+	on darwin systems.
+	(SH_LDFLAGS): Set this on darwin systems.
+	(UGLY_DEFS): Cope with broken sed or shell quoting on darwin systems.
+
+2002-05-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXX_ISO_COMPLIANT_LIBRARY): Omit cwctype.
+
+2002-05-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_AIX): Move before AC_MINIX and AC_ISC_POSIX.
+	(AH_BOTTOM): Move contents of acconfig.h here.
+	* acconfig.h: Delete.
+	* octMakefile.in (CONF_DISTFILES): Delete acconfig.h from the list.
+
+2002-04-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_CONFIG_FILES): Add libcruft/daspk/Makefile to
+	the list.
+
+2002-04-24  Kurt Hornik <hornik at ci.tuwien.ac.at>
+
+	* aclocal.m4 (OCTAVE_CC_FLAG, OCTAVE_CXX_FLAG): Also handle flags
+	that contain : and =.
+
+2002-04-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.guess, config.sub: Update from FSF sources.
+
+2002-04-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Declare F2C and F2CFLAGS with AC_ARG_VAR.
+	Delete AC_SUBST calls for F77, FFLAGS, FLIBS, F2C, F2CFLAGS (no
+	need to do this explicitly now).
+
+2002-04-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in: Set and substitute EXEEXT, not EXE.
+
+	* configure.in (EXE): Delete check and substitution.
+	* install-octave.in: Use EXEEXT instead of EXE.
+
+	* configure.in: Use AC_CHECK_MEMBERS, not OCTAVE_STRUCT_GR_PASSWD.
+	Use AC_CHECK_TYPES, not AC_CHECK_TYPE or OCTAVE_CHECK_TYPE.
+	* aclocal.m4 (OCTAVE_STRUCT_GR_PASSWD, OCTAVE_CHECK_TYPE): Delete.
+	* acconfig.h (dev_t, ino_t, nlink_t, sigset_t): Typedef if not found.
+
+2002-04-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4: Replace AC_LANG_SAVE, AC_LANG_C, AC_LANG_CPLUSPLUS,
+	and AC_LANG_RESTORE with AC_LANG_PUSH and AC_LANG_POP.
+	Use AS_MESSAGE_LOG_FD instead of AC_FD_CC.
+	* configure.in: Delete second arg in AC_CHECK_SIZEOF calls.
+
+2002-04-03  Steven G. Johnson <stevenj at alum.mit.edu>
+
+	* configure.in: Correct usage of AC_ARG_WITH for --with-fftw.
+
+	* configure.in: Update for autoconf 2.5x.
+	Minor syntax changes to new recommended syntaxes and macros.
+	Apply changes from autoupdate plus eliminate some warning
+	messages, deprecated uses of changequote, etc.
+	Use autoheader templates to generate config.h.in.
+	Replace most of Octave's Fortran support macros with those in the
+	new autoconf.
+	Eliminate most uses of internal (undocumented) autoconf cache vars.
+	Replace BLAS/LAPACK detection new macros ACX_BLAS/ACX_LAPACK from
+	the autoconf macro repository.
+	* acx_blas.m4, acx_lapack.m4: New files.
+	* acconfig.h: Delete lines that can be automatically generated
+	from new info in configure.in and aclocal.m4.
+	If it is not already defined, define F77_FUNC for use with f2c.
+	* aclocal.m4 (OCTAVE_PROG_G77, OCTAVE_FLIBS, OCTAVE_F77_MAIN_FLAG,
+	OCTAVE_F77_UPPERCASE_NAMES, OCTAVE_F77_APPEND_UNDERSCORE,
+	OCTAVE_F2C_F77_COMPAT): Delete definitions.
+	Use autoheader templates to generate config.h.in.
+	* Makeconf.in, mkoctfile.in (FORTRAN_MAIN_FLAG): Delete all uses.
+
+2001-11-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave-bug.in (BLAS_LIBS, FFTW_LIBS, LD_CXX): Substitute and
+	print values.
+	* mkoctfile.in: Accept --compile as an alias for -c.
+	New option, --link-stand-alone.
+	New option, --no-pathsearch.
+	New option, --no-readline.
+	Substitute RLD_FLAG, FLIBS, LIBKPATHSEA, LIBOCTINTERP,
+	LIBOCTAVE, LIBOCT_READLINE, LIBOCT_PATHSEARCH, LIBCRUFT,
+	BLAS_LIBS, FFTW_LIBS, and LIBS.
+	* Makeconf.in (MKOCTFILE_LFLAGS): New variable.
+	(do-subst-config-vals): Substitute FFTW_LIBS, LD_CXX,
+	LIBOCT_PATHSEARCH, LIBOCT_READLINE, MKOCTFILE_LFLAGS.
+
+2001-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (LIBOCT_READLINE, LIBOCT_PATHSEARCH): New variables.
+	* Makeconf.in: Substitute them here.
+
+2001-11-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (dist): Omit long-gone info subdir.
+	Fix find command for removing Makefile in kpathsea and glob subdirs.
+
+2001-08-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Substitute F2C and F2CFLAGS. Make it possible to
+	use f2c and a C compile to compiling Fortran source files.  Print
+	warnings and error message on stderr, not stdout.  Issue warnings
+	if it is not possible to comiple Fortran, C, or C++ files.
+
+	* configure.in (%.c : %.f): Don't use cat in F2C rule.
+
+2001-07-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Substitute DEPEND_FLAGS and
+	DEPEND_EXTRA_SED_PATTERN.
+	* mkoctfile.in: Handle --depend.
+
+2001-07-25  Rafael Laboissiere  <rafael at laboissiere.net>
+
+       * octave-config.in: New file.
+       * Makeconf.in (do-subst-default-vals): Substitute OCTAVE_VERSION.
+       * Makefile.in (TARGETS): Add octave-config to list.
+       * octMakefile.in (DISTFILES): Add octave-config.in to list.
+       (BINDISTFILES): Add octave-config to list.
+       (all): Add octave-config dependency.
+       (octave-config): New rule.
+       (install): Install octave-config.
+       (uninstall): Delete octave-config from bindir.
+       (maintainer-clean): Delete octave-config.
+       (binary-dist): Add octave-config dependency.
+
+2001-06-29  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXX_ABI): Use "sun_v5" instead of "sun".
+
+	* aclocal.m4 (OCTAVE_CXX_ABI): New macro.
+	(OCTAVE_CXX_PREPENDS_UNDERSCORE): Add missing return value.
+	* configure.in: Use.
+	* acconfig.h (CXX_ABI): New macro.
+
+2001-05-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Quote the call to AC_CHECK_FUNC inside the
+	AC_CHECK_LIB macro when checking for lapack.  For autoconf 2.50
+
+	* aclocal.m4: Changes for autoconf 2.50:
+	Convert dnl comments inside AC_DEFUN to ###.
+	(OCTAVE_FLIBS): Use [] quoting instead of changequote.
+
+2001-05-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in: Remove remaining references to readline.
+	(CONF_DISTFILES): Add autogen.sh to the list.
+
+2001-05-02  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* configure.in: Support for --with-fftw.
+	(FFT_DIR, FFTW_LIBS): New substitutions.
+	* Makeconf.in (FFTW_LIBS): New variable.
+	* acconfig.h (HAVE_FFTW): New macro.
+
+2001-04-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_ENABLE_READLINE): Require readline unless
+	--disable-readline is specified.
+
+	* configure.in: Don't define TERMLIBS.  Do add terminal lib(s) to LIBS.
+	* octave-bug.in: Delete references to TERMLIBS.
+	* Makeconf.in: Likewise.
+
+	* Makeconf.in (LIBREADLINE): Delete substitution.
+	(do-subst-config-vals): Likewise.
+	* octMakefile.in (SUBDIRS): Delete @READLINE_DIR@ from the list.
+	* configure.in (AC_CONFIG_SUBDIRS): Delete $READLINE_DIR from the list.
+
+	* configure.in (VOID_SIGHANDLER): Don't check or substitute here.
+
+2001-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (install, install-strip): Don't use mk-includedir-link
+
+	* Makeconf.in (mk-includedir-link, mk-libdir-link): Delete definitions.
+
+2001-04-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (mk-libdir-link): Undo previous change
+
+2001-04-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Only check for libz if checking for HDF5 libraries.
+	Allow user to specify HDF5 library name on command line, same as
+	for BLAS libraries.  Include BLAS and HDF5 libs in summary output.
+
+2001-04-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (CONF_DISTFILES): Remove config.h.bot from the list.
+
+2001-04-19  David Livings <david.livings at asa.co.uk>
+
+	* Makeconf.in (mk-libdir-link): Omit check for $(octlibdir)/octave
+	existing as a directory.
+
+2001-02-28  Albert Chin-A-Young  <china at thewrittenword.com>
+
+	* configure.in: Check for getpwnam in libsun only after checking
+	default libraries first.  Check for gethostname in libsocket only
+	after checking default libraries first.	
+
+2001-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Allow for using f2c when setting functions to look
+	for in the BLAS and Lapack libraries.
+	From Kurt Hornik <Kurt.Hornik at ci.tuwien.ac.at>.
+
+2001-02-10  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* test/octave.test/string/dec2hex-1.m: Don't assume hex format
+	produces lower case letters.
+
+2001-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* acconfig.h: Merge contents of config.h.bot.
+	* config.h.bot: Delete.
+
+	* autogen.sh: Allow running of autoconf or autoheader to be skipped.
+
+2001-02-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* readline: Update to new version (4.2-beta1).
+
+2001-02-05  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* configure.in (TEMPLATE_AR, TEMPLATE_ARFLAGS): New variables.
+	* Makeconf.in (TEMPLATE_AR, TEMPLATE_ARFLAGS): Likewise.
+	
+	* configure.in (XTRA_CXXFLAGS): Use -fno-implicit templates for
+	pre-gcc3 compilers. Remove -fno-rtti and -fno-exceptions.
+	(DEPEND_FLAGS, DEPEND_EXTRA_SED_PATTERN): New macros.
+	(BLAS_LIBS): Fix test for sunperf library on Sun Solaris.
+	(CPICFLAG, CXXPICFLAG, FPICFLAG, SH_LDFLAGS, RLD_FLAG): Add Sun
+	compiler support.
+	* Makefile.in (DEPEND_FLAGS, DEPEND_EXTRA_SED_PATTERN): New
+	variables.
+	(%.d : %.cc): Use.
+	(%.d : %.c): Likewise.
+	* acconfig.h (CXX_ISO_COMPLIANT_LIBRARY): Add #undef.
+
+2001-01-31  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* Makeconf.in (%.d : %.cc): Strip the directory portion of the
+	target.
+	(%.d : %.c): Likewise.
+
+	* aclocal.m4 (OCTAVE_CXX_ISO_COMPLIANT_LIBRARY): New macro.
+	* configure.in: Use it.
+
+2001-01-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Substitute
+	OCTAVE_CONF_CANONICAL_HOST_TYPE here too.
+	* octave-bug.in: Substitute OCTAVE_CONF_CANONICAL_HOST_TYPE, not
+	OCTAVE_CANONICAL_HOST_TYPE.
+
+2000-12-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4: Give gperf a keyword, to avoid complaints from newer
+	versions.
+
+2000-11-27  Marcus.Brinkmann  <Marcus.Brinkmann at ruhr-uni-bochum.de>
+
+	* configure.in: Handle *-*-gnu* the same as *-*-linux* for shared
+	library creation.
+
+2000-11-03  Andy Adler  <en254 at freenet.carleton.ca>
+
+	* mkoctfile.in: Handle -c to mean compile only.
+
+2000-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Handle --print.
+
+2000-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_GPERF): Check that gperf supports flags
+	we use.
+
+	* missing: New file, modified from the missing script provided by
+	automake (never create files, just exit with failure status).
+	* aclocal.m4 (OCTAVE_PROG_BISON, OCTAVE_PROG_FLEX, OCTAVE_PROG_GPERF): 
+	Use $(top_srcdir)/missing as replacement script.
+
+	* aclocal.m4 (OCTAVE_PROG_FLEX, OCTAVE_PROG_BISON): New macros.
+	* configure.in: Use them.
+
+2000-10-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* autogen.sh: Don't run configure.
+
+	* configure.in (SPECIAL_MATH_LIB): Delete code related to this var.
+	* Makeconf.in: Ditto.
+	(BLAS_LIBS, LIBS): Substitute here.
+	(do-subst-config-vals): Put BLAS_LIBS in oct-conf.h.
+
+2000-07-20  Joao Cardoso  <jcardoso at inescn.pt>
+
+	* configure.in: (LD_CXX): Define and substitute.
+	For sco3.2v5 systems, set SONAME_FLAGS and RLD_FLAG.
+	* Makeconf.in (LD_CXX): Allow substitution.
+
+2000-07-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DISTSUBDIRS): Define in terms of $(ALL_SUBDIRS).
+
+2000-07-17  Joao Cardoso  <jcardoso at inescn.pt>
+
+	* configure.in (LIBGLOB): Set to be the two object files in the
+	glob directory instead of libglob.a.
+
+2000-07-05  Steven G. Johnson  <stevenj at gil-galad.mit.edu>
+
+	* Use BLAS_LIBS to save the names of BLAS libraries instead of
+	adding them to LIBS, then substitute BLAS_LIBS.
+
+2000-06-30  Steven G. Johnson  <stevenj at gil-galad.mit.edu>
+
+	* configure.in: Support for --with-fastblas (ATLAS).
+
+2000-06-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for long long data type.
+
+2000-06-29  Steven G. Johnson  <stevenj at gil-galad.mit.edu>
+
+	* acconfig.h (HAVE_HDF5): Add undef.
+	* configure.in: Handle --with-hdf5.
+
+2000-06-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave-bug.in: Substitute correct values for config_opts,
+	MACHINE, and CXXFLAGS.
+
+2000-06-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (GPERF): Allow substitution.
+
+2000-06-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_GPERF): New macro.
+	* configure.in: Use it.  Print warning at end if gperf is missing.
+
+2000-04-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Try moving output file first.  But comment these
+	lines and let people who have trouble enable them.
+
+2000-04-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Remove output file before linking.
+
+	* octMakefile.in (DIRS_TO_MAKE): Create $(octincludedir)/octave.
+	(install install-strip): Install config.h in $(octincludedir)/octave,
+	not $(octincludedir).
+
+2000-03-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DIRS_TO_MAKE): Double up on $ in awk command to
+	get them past Make.
+
+2000-03-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (SUBDIRS): Omit src.
+	(ALL_SUBDIRS): New variable.  Include src here.
+	(all): Depend on src instead of $(SUBDIRS).
+	(src): New target.  Depend on $(SUBDIRS).
+
+	* Makefile.in (.NOTPARALLEL): New target, for GNU Make 3.79.
+	* octMakefile.in (.NOTPARALLEL): Likewise.
+
+2000-03-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for vsnprintf.
+
+2000-03-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (liboctave.$(SHLEXT)): Delete target before rebuilding.
+
+2000-03-21  Ben Sapp <bsapp at nua.lampf.lanl.gov>:
+
+	* Makeconf.in (%.o : %.c): Pass -o to compile command.
+	(%.o : %.cc): Ditto.
+	* configure.in (%.o : %.f): Ditto.
+
+2000-03-08  Stephen Eglen  <stephen at gnu.org>
+
+	* emacs/octave-mod.el (octave-font-lock-keywords): To font-lock
+	the builtin operators, use `font-lock-builtin-face' for Emacs
+	and `font-lock-preprocessor-face' for XEmacs.
+
+2000-03-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: For building shared libaries, handle
+	i386-pc-solaris2* the same as sparc-sun-solaris2*.
+
+2000-02-29  Ben Sapp <bsapp at nua.lampf.lanl.gov>
+
+	* examples/make_int.cc (make_int): Handle new operator names.
+
+2000-02-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (maintainer-clean distclean): Don't delete Makefile.
+	(dist): Delete stamp-auto.
+
+2000-02-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (octincludedir): Delete trailing /octave here.
+	* Makeconf.in (mk-includedir-link): Append it here.
+	(MKOCTFILE_INCFLAGS): Use both -I$(octincludedir) and
+	-I$(octincludedir)/octave.
+
+	* configure.in (localveroctfiledir, localverarchlibdir,
+	localverfcnfiledir): New variables.
+	(localfcnfilepath): Prepend localverfcnfiledir.
+	(localoctfilepath): Prepend localveroctfiledir.
+	* Makeconf.in: Substitute them here.
+
+	* Makeconf.in (do-subst-default-vals): Substitute
+	OCTAVE_LOCALVERARCHLIBDIR, OCTAVE_LOCALVERFCNFILEDIR,
+	OCTAVE_LOCALVEROCTFILEDIR.
+
+2000-02-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.guess: Update to latest from subversions.gnu.org.
+	* config.sub: Likewise.  Recognize sv1-cray as a basic_machine.
+
+	* Makeconf.in (MKOCTFILE_INCFLAGS): New macro.
+	(do-subst-conf-vals): Substitute it.
+	* mkoctfile.in: Set INCFLAGS from OCTAVE_CONF_MKOCTFILE_INCFLAGS.
+
+	* mkoctfile.in: Fix names in substititions.
+	* octave-bug.in: Likewise.
+
+2000-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-default-vals, do-subst-config-vals):
+	Substitute more complete set of values.
+
+2000-02-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (octave_cv_string_npos): Add std:: qualifier.
+
+2000-01-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-begin-keywords): Add "do".
+	(octave-end-keywords): Add "until".
+	(octave-abbrev-table): Add "u" as abbrev for "until ()"
+	(octave-block-match-alist): Add do-until.
+
+2000-01-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't look for the sunmath library.
+	Don't check for infinity or quiet_nan.
+
+	* emacs/octave-mod.el (octave-mode-syntax-table):
+	Undo previous change, but add a comment explaining why.
+
+	* install-octave.in: Exit on any error instead of continuing.
+	Install Octave binary last.
+
+2000-01-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-mode-syntax-table):
+	Make `%' a comment start character too.
+
+2000-01-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for strptime and localtime_r.
+
+1999-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (XTRA_CXXFLAGS, XTRA_CFLAGS): Use -mminimal-toc on
+	AIX systems.
+
+1999-10-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/README: New file.
+	* emacs/Makefile.in (DISTFILES, BINDISTFILES): Add it to the lists.
+
+	* emacs/Makefile.in: Don't distribute .elc files.
+
+1999-10-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for select and poll.  Also check for poll.h
+	and sys/poll.h.
+
+1999-10-19  Geoff Jacobsen <geoffj at casquet.inet.net.nz>
+
+	* autogen.sh: New file.
+
+1999-10-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in: Use `$(MAKE) -C dir' instead of `cd dir; $(MAKE)'.
+
+Mon Sep 20 11:02:29 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-inf.el, emacs/octave-mod.el: Update to match FSF
+	sources plus code that will make it work if Emacs doesn't have the
+	customize code.
+
+Tue Sep 14 07:57:06 1999  Kurt Hornik <hornik at ci.tuwien.ac.at>
+
+	* emacs/octave-inf.el (inferior-octave-startup): Always pass "-i"
+	and "--no-line-editing" to Octave subprocess.
+ 	(inferior-octave-startup-args): Default to nil.
+
+Mon Sep  6 10:50:10 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-inf.el (inferior-octave-startup-args):
+	Add --no-line-editing to the list.
+
+Fri Jul  9 09:15:24 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Try to handle IEEE FP flags for g77 on Alphas.
+
+Thu Jul  8 19:56:37 1999  Stephen Eglen  <stephen at gnu.org>
+
+	* emacs/octave-inf.el (inferior-octave-directory-tracker):
+	Change regexp so that it doesn't match commands beginning with `cd'.
+
+Wed Jun 23 13:20:11 1999  Mumit Khan  <khan at xraylith.wisc.edu>
+
+	* configure.in (HAVE_TERMIOS_H): Avoid autoheader lossage.
+
+Sun Jun 20 23:05:18 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for sys/ioctl.h.
+
+Mon May 10 09:06:47 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_G77): Also match "FSF-g77", for egcs.
+
+Thu Apr  8 19:20:09 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* examples/hello.cc (Fhello): octave_value::print now requires a
+	stream arg.
+
+Wed Feb  3 01:02:37 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Use AC_OUTPUT_COMMANDS to chmod install-octave so
+	that the command will also executed in config.status.
+
+Thu Jan 28 21:05:32 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Do substitution on
+	CANONICAL_HOST_TYPE, not TARGET_HOST_TYPE.
+	(do-subst-default-vals): Likewise.
+
+Wed Jan 20 12:56:02 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't put -O in FFLAGS for powerpc-apple-machten*.
+
+Wed Dec  9 14:02:45 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (RDYNAMIC_FLAG): Substitute RDYNAMIC_FLAG here.
+	* configure.in: Check for G++ compiler flag -rdynamic if setting
+	up to support dynamic linking, and substitute RDYNAMIC_FLAG if
+	-rdynamic is accepted.
+	* aclocal.m4 (OCTAVE_CC_FLAG, OCTAVE_CXX_FLAG): Clarify usage comment.
+
+Mon Dec  7 19:49:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for -lm just after compiler tests.
+	Remove -lm from other macro calls.  Don't check for -lm on NeXT
+	systems.  Eric Norum <eric at skatter.usask.ca> says /lib/libsys_s.a
+	has all the routines that are traditionally in libc.a and libm.a
+	on *NIX systems.  NeXT also supplies a libm.a, but it seems to be
+	horribly buggy.
+
+Sat Dec  5 10:48:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Correctly handle -?.
+
+Fri Dec  4 18:05:51 1998  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* emacs/octave-mod.el (octave-abbrev-start): Use the correct name
+	of the abbrev table, and provide support for XEmacs.
+	(octave-xemacs-p): New variable.
+
+Tue Nov 24 23:31:50 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for strftime too.
+	Avoid checking for termios.h on NeXT systems.
+
+Thu Nov 19 16:07:57 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXX_PREPENDS_UNDERSCORE): New macro.
+	* configure.in: Use it.
+	* acconfig.h: Add #undef for it.
+
+Thu Nov 12 10:42:25 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/otags: New script from Mario Storti
+	<mstorti at minerva.unl.edu.ar>.
+	* emacs/Makefile.in: Add it to the list of files to distribute and
+	install.
+
+Wed Nov 11 17:26:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Add libcruft/amos/Makefile.
+	Delete libcruft/specfun/Makefile.
+
+Mon Nov  9 08:53:03 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (LIBGLOB): Add a place for substitution to occur.
+	(GLOB_INCFLAGS): Define as @GLOB_INCFLAGS@, not @DLFCN_INCFLAGS at .
+	(do-subst-config-vals): Don't forget LIBGLOB.
+	* octave-bug.in (LIBGLOB): Substitute here too, and add it to the
+	list of configuration items to print.
+
+Mon Nov  2 20:33:16 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Define __NO_MATH_INLINES.
+	* acconfig.h: Add #undef for it.
+
+	* configure.in (AC_OUTPUT): Escape newlinew in macro call with \.
+
+	* install-octave.in (SHLEXT): Substitute.
+	(SHLEXT_VER): Define.
+	Use them for installing shared libraries.
+	Use subshells to avoid having to cd back to $distdir.
+	(distdir): Delete variable.
+
+Fri Oct  2 14:23:59 1998  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* octave-inf.el (inferior-octave-prompt):  Also match prompts of
+	the form `octave.bin:1>' which come from using precopiled binary
+	versions.
+
+Thu Sep 24 13:51:03 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Add libcruft/ordered-qz to the list.
+	Delete libcruft/balgen and libcruft/eispack from the list.
+
+Mon Aug 31 12:07:02 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.sub: Accept armv4 everywhere arm is allowed.
+
+Tue Aug 18 17:02:25 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Allow -DDEF on command line.
+
+Thu Jun 18 20:24:40 1998  Roman Hodek <Roman.Hodek at informatik.uni-erlangen.de>
+
+	* configure.in (RLD_FLAG): Set correctly for Linux on all
+	architectures.  From 
+
+Thu May 28 10:17:45 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: When checking for glob stuff, make sure that the
+	systsem header file has all the definitions that we need.  If not,
+	set up to use our replacement library.
+
+Mon May 18 11:33:45 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Fix typos in case statement.
+
+Fri May 15 00:34:54 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Make sure install-octave is executable.
+
+	* install-octave.in (oct_files): Don't cd to src.
+	(have_find): Delete variable (assume all systems have find).
+
+Thu May 14 10:29:30 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_SET_DEFAULT): Allow values to come from the
+	environment.
+
+	* Makefile.in (binary-dist): Don't set LDFLAGS to -static.
+	Run configure with --enable-shared and --enable-lite-kernel.
+
+	* octMakefile.in (DISTFILES): Include README.MachTen in the list.
+	(XBINDISTFILES): Include README.MachTen in the list.
+	Delete README.NLP from the list
+	* README.MachTen: New file.
+
+	* configure.in: Add -mno-fp-in-toc on ibm-aix4 systems.
+	From Philippe.Defert at cern.ch <Philippe.Defert at cern.ch>.
+
+Tue May  5 14:43:36 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_PROG_G77): Compile trivial program instead of
+	just running ${f77-f77} -v on nothing.
+	Convert all uses of $F77 to ${F77-f77}.
+
+Mon May  4 12:08:36 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-mode): Make comment-multi-line local
+	and set to nil.
+
+Tue Apr 28 14:28:14 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Really do skip -lkernel32.
+
+Thu Apr 23 23:26:19 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* kpathsea: Update to version 3.2.
+
+Mon Apr 20 21:58:39 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (dlfcn.h): Add check.
+
+Sat Apr 18 20:15:37 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (USE_GNU_INFO): Delete everything related to this.
+	* acconfig.h (USE_GNU_INFO): Delete undef.
+
+Tue Apr 14 15:33:20 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* install-octave.in: Improve error messages if version number or
+	host architecture can't be found.
+
+	* install-octave.in: Don't install info reader.
+
+Fri Mar 27 02:54:59 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_F2C_F77_COMPAT): Use a Fortran subroutine
+	instead of a function.
+
+Tue Mar 10 17:28:20 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (RLD_FLAG): Use $(octlibdir), not $(libdir).
+
+Mon Mar  2 00:02:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* install-octave.in: Explicitly set permissions on ls-R files.
+
+	* configure.in: Don't disable GNU Info on cygwin32 systems.
+
+	* install-octave.in: New file.
+	* configure.in: Create install-octave.
+	* octMakefile.in (distclean, maintainer-clean): Delete install-octave.
+	(DISTFILES): Distribute install-octave.in, not install-octave.
+
+Sun Mar  1 23:15:04 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Fix typo in test for glob and fnmatch headers.
+
+Fri Feb 27 15:43:14 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Fix support for dlopen on SCO systems.
+
+Mon Feb 23 13:06:11 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (ieee_fp_flag): Use -mieee-with-inexact on Alphas.
+	Use octave_cv_f77_is_g77, not just f77_is_g77.
+
+Fri Feb 20 00:38:31 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in, Makeconf.in: Try to set things up to use the
+	system glob and fnmatch headers and functions if they exist.
+	Better handling of include and lib flags.
+
+Thu Feb 19 01:21:19 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't check for gamma or lgamma
+	* acconfig.h: Delete undef for HAVE_GAMMA and HAVE_LGAMMA.
+
+Wed Feb 18 15:05:54 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't check for vfork.
+
+Wed Feb 11 19:41:22 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (mk-libdir-link): Don't create link if a directory
+	named $(libdir)/octave already exists.
+
+Mon Feb  9 14:47:42 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (INSTALL_SUBDIRS): Delete @INFO_DIR at .
+
+Thu Feb  5 03:04:09 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for vfork.
+
+	* config.h.bot (X_CAST): New macro.
+
+Wed Feb  4 01:42:50 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): If ld_run_path is not absolute, kill it.
+
+Tue Feb  3 00:24:01 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-vals): Substitute $(libexecdir) too.
+
+Mon Feb  2 22:42:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Define octlibdir.
+	* Makeconf.in: Substitute value.
+	(do-subst-config-vals): Set LIBDIR to $(octlibdir).
+	(do-subst-default-vals): Substitute OCTLIBDIR too.
+
+Sat Jan 31 19:29:56 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* acconfig.h: Add #undefs for HAVE_GAMMA and HAVE_LGAMMA to avoid
+	bug in autoconf, but #if 0 them out to avoid warning messages
+	about redefining them.
+
+Mon Jan 26 13:26:09 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Substitute XTRA_CFLAGS and
+	XTRA_CXXFLAGS.
+	* mkoctfile.in: Substitute XTRA_CFLAGS and XTRA_CXXFLAGS, not
+	GCC_IEEE_FP_FLAG, HOST_CXXFLAGS, and NO_IMPLICIT_TEMPLATES.
+	(ALL_CFLAGS): Use XTRA_CFLAGS, not GCC_IEEE_FP_FLAG here.
+	(ALL_CXXFLAGS): Use XTRA_CXXFLAGS, not GCC_IEEE_FP_FLAG,
+	HOST_CXXFLAGS, and NO_IMPLICIT_TEMPLATES here.
+
+Sun Jan 25 01:59:47 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: (GXX_PICKY_FLAGS): Add -Weffc++.
+	Use OCTAVE_CC_FLAG and OCTAVE_CXX_FLAG to add -Wall and for adding
+	picky flags in AC_ARG_ENABLE(picky-flags ...) macro.
+
+	* aclocal.m4 (OCTAVE_F2C_F77_COMPAT): Require OCTAVE_PROG_G77.
+	Handle cross compiling with g77.
+	(OCTAVE_REINSTALL_SIGHANDLERS): Provide defaults for cross compiling.
+
+	* aclocal.m4 (OCTAVE_PROG_AR, OCTAVE_PROG_G77, OCTAVE_PROG_PAGER,
+	OCTAVE_PROG_GNUPLOT, OCTAVE_PROG_RUNTEST, OCTAVE_F77_MAIN_FLAG):
+	New macros.
+	* configure.in: Use them in place of in-line code.
+	
+Sat Jan 24 00:33:14 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_HOST_TYPE): Don't set target_host_type.
+	* configure.in: Use canonical_host_type in place of target_host_type.
+
+Fri Jan 23 02:47:57 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Also check for -fno-rtti.
+
+Thu Jan 15 23:12:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.guess, config.sub: Update to new version from the FSF.
+	* configure.in: Match alpha*-... instead of just alpha-... to cope
+	with new strings like alphaev56-dec-osf4.0b returned from
+	config.guess.
+
+	* aclocal.m4 (OCTAVE_CC_FLAG, OCTAVE_CXX_FLAG): New macros.
+	* configure.in: Use them to find out if the C and C++ compilers
+	support -mieee-fp, -mieee, -fno-implicit-templates, and
+	-fno-exceptions instead of relying on version information.  Add
+	found flags to XTRA_CFLAGS and XTRA_CXXFLAGS instead of using
+	GCC_IEEE_FP_FLAG and NO_IMPLICIT_TEMPLATES.
+	Delete unused variable HOST_CXXFLAGS.
+	* Makeconf.in: Use XTRA_CFLAGS and XTRA_CXXFLAGS instead of
+	GCC_IEEE_FP_FLAG and NO_IMPLICIT_TEMPLATES.
+	Delete unused variable HOST_CXXFLAGS.
+
+Thu Dec 11 09:43:56 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot: Define CONST_CAST and STATIC_CAST too.
+
+	* configure.in (SH_LD): Set default to $CXX, not $CC.
+
+Mon Dec  1 00:49:56 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Add libcruft/slatec-err/Makefile.
+
+Sun Nov 30 18:19:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for gamma and lgamma too.
+
+Fri Nov 28 23:21:17 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Include libcruft/specfun/Makefile.
+
+Fri Nov 28 13:32:26 1997  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* octave-inf.el (inferior-octave-directory-tracker):  Anchor
+	regexp match to beginning of command string.
+
+Wed Nov 26 00:38:31 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (SPECIAL_MATH_LIB): If libdxml exists on DU
+	systems, define SPECIAL_MATH_LIB.
+	* Makeconf.in (SPECIAL_MATH_LIB): Substitute it.
+
+Wed Nov 19 01:54:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXX_NEW_FRIEND_TEMPLATE_DECL): Don't forget
+	to call AC_LANG_RESTORE.
+
+	* configure.in (CXX_VERSION): Require 2.7.2 or later.
+
+Wed Nov 19 01:38:58 1997  Mumit Khan  <khan at dhaka.xraylith.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXX_NEW_FRIEND_TEMPLATE_DECL): New macro
+	check for new friend template declaration syntax (guiding
+	declarations in DWP).
+	* configure.in: Use it.
+	* config.h.in: Add undef for CXX_NEW_FRIEND_TEMPLATE_DECL.
+
+	* configure.in (CC_VERSION, CXX_VERISON): Check for egcs snapshots.
+
+Mon Oct 20 01:31:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Reprint important warning messages at the end of
+	the run.
+
+Fri Oct 17 04:43:27 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Include the following change from RMS for octave-mode.el:
+
+	1997-04-22  Richard Stallman  <rms at psilocin.gnu.ai.mit.edu>
+
+	* octave-mod.el (inferior-octave-output-list): Declare here
+        to avoid compiler warnings.
+        (inferior-octave-output-string): Likewise.
+        (inferior-octave-receive-in-progress): Likewise.
+
+Tue Oct 14 10:48:28 1997  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* emacs/octave-mod.el (octave-block-match-alist):  Move
+	`otherwise' to right after `case' to have octave-close-block()
+	correctly close a `switch' block by `endswitch'.
+
+Thu Oct  2 01:37:15 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Ignore -lc and -lgcc.
+	From "Ram'on Garc'ia Fern'andez" <ramon at juguete.quim.ucm.es>
+
+	* mkoctfile.in: Handle -IDIR option.
+
+Thu Sep 25 11:47:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Really add link options to link command.
+	Also handle -LDIR options.
+
+Fri Sep 19 09:35:59 1997  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* octave-inf.el (inferior-octave-startup-args):  Set to '("-i") to
+	force interactive behavior.
+
+Wed Sep 10 15:31:03 1997  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* emacs/octave-mod.el (octave-auto-indent):  New variable.
+	(octave-electric-semi, octave-electric-space):  Use it.
+
+	* emacs/octave-mod.el (octave-maybe-insert-continuation-string):  New
+	function.
+	(octave-auto-fill):  No longer calls do-auto-fill.  Should now
+	avoid breaking lines after comment starts or before code line
+	continuation expressions.
+	(octave-fill-paragraph):  Move forward a line if octave-auto-fill
+	gave up.
+
+	* emacs/octave-mod.el (octave-before-magic-comment-p):  New function.
+	(octave-comment-indent):  Handle magic comments correctly.
+	(calculate-octave-indent):  Handle magic comments correctly.
+
+	* emacs/octave-inf.el (inferior-octave-prompt):  Include the `debug'
+	prompt issued by the Octave `keyboard' command.
+
+	* emacs/octave-mod.el (octave-abbrev-table):  Added abbrevs for switch,
+	case, otherwise, and endswitch.
+	(octave-begin-keywords):  Added switch.
+	(octave-else-keywords):  Added case and otherwise.
+	(octave-end-keywords):  Added endswitch.
+	(octave-block-match-alist):  Added an entry for switch syntax.
+	(calculate-octave-indent):  Added support for switch syntax.
+	(octave-block-end-offset):  New function.
+	(octave-comment-indent):  Fix a typo.
+
+	* emacs/octave-hlp.el:  Provide octave-hlp.
+
+	* emacs/octave-inf.el:  Provide octave-inf.
+
+Sun Sep  7 23:16:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in Don't use OCTAVE_SET_DEFAULT to set values for
+	bindir, datadir, exec_prefix, includedir, infodir, libdir,
+	libexecdir, mandir.
+	Don't use AC_PREFIX_DEFAULT, since we don't want to override the
+	default setting anyway.
+
+Tue Aug 26 13:30:36 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave-bug.in: CC bug report to user if $USER or $LOGNAME is set.
+
+Mon Aug 25 11:06:54 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave-bug.in: Avoid clobbering existing dead bug report files
+	by numbering them.
+
+Wed Aug 13 20:34:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-before-magic-comment-p): New function.
+	(calculate-octave-indent, octave-comment-indent): Use it.
+
+Sun Aug  3 15:33:18 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* info: Delete subdirectory.
+	* Makefile.in (TARGETS, help): Delete info.
+	* octMakefile.in (DISTSUBDIRS, BINDISTSUBDIRS): Delete info
+	(binary-dist): Don't strip info/info.
+	* install-octave: Don't install info.
+	* configure.in: Don't run configure in info subdirectory.
+
+Fri Jul 25 14:05:15 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Avoid adding -lcrt0.o to FLIBS.
+
+Thu Jul 17 13:31:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Only accept an ld_run_path that is
+	absolute.
+
+Wed Jul  9 19:27:38 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Also check for getwd.
+
+Tue Jul  8 17:47:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Avoid grabbing an argument starting
+	with a - as an option for another argument.
+
+Wed Jul  2 21:34:15 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-auto-indent): New variable.
+	(octave-electric-semi, octave-electric-space): Use it.
+
+Thu Jun 26 22:16:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Only set GCC_IEEE_FP_FLAG to -mieee-fp on Intel
+	systems if it seems to work.
+
+Mon Jun 23 09:16:56 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (BOUNDS_CHECKING): Fix comment, allow bounds
+	checking to be enabled.
+
+Fri Jun 20 14:26:17 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Define SH_LD, SH_LDFLAGS, and RLD_FLAG for
+	sparc-sun-sunos4*.
+
+	* mkoctfile.in: Handle --strip.
+
+Sun Jun 15 16:24:03 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DISTSUBDIRS): Delete readline.
+	(BINDISTSUBDIRS): Delete readline and kpathsea.
+	(DISTDIRS): Add readline.
+
+Wed Jun 11 16:28:36 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Allow more options, support for C and Fortran
+	source, existing object files, etc.  Based on patch from Guido
+	Dietz <guido at aia009.aia.RWTH-Aachen.De>.
+
+Fri Jun  6 15:20:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Use eval to invoke compilation and linking
+	commands.
+
+	* octMakefile.in (dist, binary-dist): Don't worry about npsol or qpsol.
+	* configure.in: Don't create libcruft/fsqp/Makefile,
+	libcruft/npsol/Makefile, or libcruft/qpsol/Makefile.
+
+	* octMakefile.in (DISTFILES): Don't distribute MAKEINFO.PATCH.
+
+	* octMakefile.in (DISTFILES): Don't distribute README.NLP.
+	* configure.in: Delete checks for FSQP, NPSOL, and QPSOL.
+	* acconfig.h: Delete undefs for FSQP, NPSOL, and QPSOL.
+
+	* readline: Update to new version (2.1).
+
+Thu Jun  5 01:38:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (SONAME_FLAGS): Define for some systems.
+	* Makeconf.in: Substitute value here.
+
+	* Makeconf.in (STATIC_LIBS): New variable.
+	* configure.in: Handle --enable-static.
+
+	* Makeconf.in (LIBEXT, SHLEXT_VER): New macros.
+	(octlibdir, mk-libdir-link): Delete.
+
+Wed Jun  4 00:07:29 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (mk-includedir-link, mk-libdir-link): Make them work.
+
+	* configure.in (OCTAVE_PROGRAM_INVOCATION_NAME): Delete check.
+	* aclocal.m4 (OCTAVE_PROGRAM_INVOCATION_NAME): Delete macro.
+
+Mon Jun  2 13:56:26 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Move checks for RANLIB, AR, and ARFLAGS before
+	checks for libf2c.
+
+Fri May 30 14:59:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Fix typo in check for $with_f77.
+
+Thu May 22 16:48:34 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Remove duplicate entry for emacs/Makefile.
+
+	* octMakefile.in (INSTALL_SUBDIRS): New macro.
+	(install): Use it.
+
+	* kpathsea: Update to new version (3.0).
+
+	* readline: Update to new version (2.1-beta2).
+
+Wed May 21 16:33:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (install, install-strip): Append version
+	information to octave-bug and mkoctfile.
+	(install, install-strip): Remove octave-bug and mkoctfile first.
+	Ensure link is made in include directory.
+
+	* configure.in (octlibdir): New variable.
+	* Makeconf.in: Substitute it here.	
+	(do-subst-config-vals): Add -I${octincludedir} to INCFLAGS.
+	Add -L${octlibdir} to LIBFLAGS.
+
+	* Makeconf.in (mk-includedir-link, mk-libdir-link): New macros.
+
+Mon May  5 00:58:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Make --enable-readline work again.
+	* Makeconf.in: Ditto.
+
+Tue Apr  8 12:38:18 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in: Do substitute SH_LD and SH_LDFLAGS.  Don't
+	substitute or use LIBFLAGS, RLD_FLAG, OCTAVE_LIBS, FLIBS, LEXLIB,
+	TERMLIBS, LIBS, LDFLAGS, LIBPLPLOT, or LIBDLFCN.  Use $SH_LD and
+	$SH_LDFLAGS, not $CXX -shared.
+
+	* Makeconf.in (do-subst-config-vals): Also substitute SH_LD and
+	SH_LDFLAGS.
+
+Fri Mar 28 16:53:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't add -fpe1 to FFLAGS on Alpha OSF/1 systems
+	unless we are also using a version of gcc that appears to support
+	IEEE floating point.
+
+	* aclocal.m4 (OCTAVE_FLIBS): Require OCTAVE_HOST_TYPE.
+	Skip -lkernel32 on cygwin32 systems.
+
+Wed Mar 26 17:04:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* COPYING: Update to latest version that includes correct address
+	for the FSF.
+
+Tue Mar 25 21:46:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CXXLIBS): Delete macro definition.
+	* configure.in, mkoctfile.in, Makeconf.in, octave-bug.in:
+	Delete use of OCTAVE_CXXIBS.
+
+Thu Mar 13 11:44:46 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Move extra checks for Fortran compiler above
+	checks for dynamic linking and shared library stuff.
+	Handle --with-f77.  Check for Fortran compiler compatibility, even
+	if using g77.  Handle --enable-picky-flags.
+
+	* configure.in: Don't set special PIC options on SGI systems,
+	since PIC is apparently the default.
+
+	* aclocal.m4 (OCTAVE_CHECK_EXCLUSIVE_WITH_OPTIONS,
+	OCTAVE_HOST_TYPE, OCTAVE_SET_DEFAULT): New macros.
+	* configure.in: Use them.
+
+	* octMakefile.in (distclean): Don't remove configure, config.h.in,
+	BUGS, or INSTALL.OCTAVE.
+
+Wed Mar 12 16:56:56 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-strip): Don't try to set INSTALL_PROGRAM here.
+
+	* emacs/Makefile.in (install-strip): New target.
+	* dlfcn/Makefile.in: Ditto.
+	* examples/Makefile.in: Ditto.
+
+Sun Mar  9 03:44:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot (STATIC_CAST): Delete definition.
+
+Thu Mar  6 03:26:41 1997  Kurt Hornik <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* emacs/octave-hlp.el: Provide octave-hlp.
+	* emacs/octave-inf.el: Provide octave-inf.
+
+	* examples/info-emacs-octave-help: Require octave-hlp instead of
+	loading it.
+
+Tue Mar  4 12:19:24 1997  Kurt Hornik <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* emacs/octave-mod.el: Properly indent switch statement.
+
+Mon Mar  3 15:44:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dlfcn/Makefile.in (DISTFILES): Add ftp-site.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Improve checks for gettimeofday.
+
+	* Version 2.0.5 released.
+
+Sat Mar  1 01:34:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (dist): Also delete CVS junk
+
+	* config.h.bot: Unconditionally define WITH_KPATHSEARCH.
+
+Fri Feb 28 01:56:52 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-end-keywords): Add endswitch.
+	(octave-end-keywords): Add otherwise and case.
+	(octave-else-keywords): Add switch.
+	(octave-abbrev-table): Add abbrevs for all of them.
+
+	* configure.in (f77_rules_frag): Set default value to /dev/null
+	and redfine as needed.
+	(bsd_gcc_kluge_targets_frag): Likewise.
+
+Wed Feb 26 12:17:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (maintainer-clean): Delete some more stuff.
+
+Fri Feb 21 20:38:25 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Remove extra -L from
+	RLD_FLAG substitution.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+	* configure.in (SH_LDFLAGS): Add -fPIC for HP-UX.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (SH_LDFLAGS): Fix typo in last change.
+	(RLD_FLAG): Don't forget to put -shared in SH_LDFLAGS for alpha
+	systems.
+
+	* Version 2.0.3 released.
+
+Tue Feb 18 00:33:36 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (binary-dist): Strip src/octave and info/info.
+
+	* examples/oregonator.m, examples/oregonator.cc: New files.
+	* examples/Makefile.in (SOURCES): Add them to the list.
+
+Fri Feb 14 14:07:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* install-octave: Don't fail if LIBRARIES file is missing.
+	Don't try to install .oct files if there aren't any.
+
+	* octMakefile.in (bin-dist-type): Delete target.
+	(binary-dist): Don't depend on bin-dist-type.
+	Don't delete config.status or config.h here.
+	(BINDISTFILES): Include config.status and config.h here.
+	(dist): Don't delete Makefile here.
+	(binary-dist): Avoid empty chmod command.
+
+	* Makefile.in (config-check): New target.
+	(all): Depend on config-check.
+	(static-binary-distribution, dynamic-binary-distribution): Delete.
+	(binary-distribution): If in source directory, run configure and
+	make with appropriate args.
+
+	* octMakefile.in (maintainer-clean, distclean): Don't delete Makefile.
+	(CONF_DISTFILES): Distribute Makefile too.
+
+Thu Feb 13 16:25:09 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (SH_LD, SH_LDFLAGS): New variables.
+	* Makeconf.in: Substitute them.
+
+	* configure.in (SH_LIBS, SH_FLIBS, SH_TERMLIBS): Delete.
+
+	* Makeconf.in (SH_LIBS, SH_FLIBS, SH_TERMLIBS): Delete.
+
+	* octave-bug.in: Reinstate RLD_FLAG.
+	* mkoctfile.in: Likewise.
+	* Makeconf.in: Likewise.
+
+	* configure.in: Reinstate RLD_FLAG, but make it optional.
+
+Tue Feb  4 14:10:35 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (binary-dist): Use find and xargs instead of
+	requiring chmod to support X.
+
+Mon Feb  3 23:51:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* examples/info-emacs-octave-help: Update from Kurt Hornik.
+
+Fri Jan 31 20:41:15 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dlfcn/Makefile.in (all): Make libdlfcn.a, not dlfcn.a.
+
+Wed Jan 29 00:18:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in: Use -M instead of -MM to generate dependencies.
+	Don't strip $(srcdir) from output.
+
+	* examples/Makefile.in (install): Install info-emacs-info and
+	info-emacs-octave-help in $(archlibdir).
+
+	* configure.in (INSTALL_SCRIPT): Substitute this in Makefiles.
+	* octMakefile.in (INSTALL_SCRIPT): New macro.
+	(install): Use it.
+	* Makefile.in (install-strip): New target.
+
+Tue Jan 28 09:48:32 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Don't look for values-X*.o.  This is
+	apparently added automatically now by gcc.  Don't put space
+	between -L and directory name.
+
+	* Makefile.in (help): New target.
+	(header-msg): extract from all.
+	(all, help): Depend on header-msg.
+
+	* aclocal.m4 (ld_run_path): Fix typo in last fix.
+
+Mon Jan 27 00:10:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+	* configure.in: Add check for usleep().
+	(bsd_gcc_kluge_targets_frag): New fragment.
+
+	* Makefile.in: Delete `internal' targets.
+	(static-binary-dist, dynamic-binary-dist): Special cases.
+
+	* octMakefile.in (static-binary-dist, dynamic-binary-dist):
+	New targets.
+	(binary-dist, bin-dist): Delete.
+
+Sun Jan 26 19:39:51 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/Makefile.in: New file.
+	* configure.in: create emacs/Makefile.
+	* octMakefile.in: Move/add emacs dir to the appropriate lists.
+
+Sat Jan 25 22:27:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_CHECK_TYPE): New macro, stolen from bash.
+	* configure.in: Use it.
+	* acconfig.h: Add #undef for sigset_t.
+
+	* configure.in (RLD_FLAG): Delete.
+	* mkoctfile.in (RLD_FLAG): Delete.
+	* octave-bug.in (RLD_FLAG): Delete.
+	* Makeconf.in (RLD_FLAG): Delete.
+
+	* Makefile.in (bin-dist): New target.
+
+	* install-octave: Rename from doinstall.sh.  Update for 2.x.
+
+Wed Jan 22 11:14:07 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (ld_run_path): Anchor search at beginning of line to
+	avoid GNU sed bug on HP-UX systems.  Use just one sed command.
+
+	* emacs/octave-hlp.el, emacs/octave-inf.el, emacs/octave-mod.el:
+	New files from Kurt Hornik.
+	* emacs/octave.el: Delete.
+
+Mon Jan 20 11:16:21 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkoctfile.in (ALL_CXXFLAGS): Delete reference to -lg++.
+
+	* configure.in (RLD_FLAG): For sparc-sun-sunos4*, remove space
+	between -L and $(libdir).
+	(FPICFLAG): If using g77, set it to -fPIC.
+
+Sun Jan 19 15:57:20 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in, configure.in: Delete FUGLY.
+
+Wed Jan  8 23:12:02 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (DEFAULT_PAGER): On cygwin32 systems, also look for
+	more.com.
+
+Tue Jan  7 00:16:35 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Thu Dec 19 16:18:59 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Only add -Xlinker args if compiler is
+	gcc.
+
+Sat Dec 14 09:46:50 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* README.Linux: New file.
+	* octMakefile.in: Distribute it.
+
+Fri Dec 13 22:37:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (TERMLIBS): Look for termcap and terminfo after
+	ncurses and curses.
+
+Thu Dec 12 02:27:08 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (ALL_LDFLAGS): Add CPICFLAG here since gcc needs it
+	on some systems.
+
+	* configure.in (FPICFLAGS): Set to -fPIC if using g77 on HP/UX.
+
+	* Makefile.in, octMakefile.in: Delete all doc-dist, local-dist,
+	and split-dist targets.  Likewise for all other Makefiles in the
+	subdirectories.
+
+	* README.Windows: Renamed from README.WINDOWS.
+
+Tue Dec 10 01:33:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+	* octMakefile.in (binary-dist): Print message instead of making a
+	binary distribution.
+
+Mon Dec  9 11:28:27 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* README.WINDOWS: New file.
+	* octMakefile.in: Distribute it.
+
+	* configure.in: Substitute EXE.  On cygwin32 systems, set it to .exe.
+	* Makeconf.in (EXE): Add definition.
+
+	* configure.in: On cygwin32 systems, set default to disable GNU info.
+
+	* aclocal.m4 (OCTAVE_STRING_NPOS): New macro.
+	* configure.in: Call it.
+
+	* acconfig.h: Add undef for NPOS.
+	* config.h.bot: Remove kluge for deciding whether to define NPOS.
+
+Thu Dec  5 11:05:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.sub: Update to current version from FSF.
+
+	* Makeconf.in (ALL_LDFLAGS): Add $(FORTRAN_MAIN_FLAG).
+	* configure.in (FORTRAN_MAIN_FLAG): Substitute it.
+
+	* octave-bug.in: Prompt for abort, edit, list, or send.
+	Get subject from message in case it has been edited.
+
+	* configure.in: When looking for libf2c, provide definitions for
+	MAIN_ and MAIN__.
+
+Tue Dec  3 11:35:35 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.guess: Delete second copy of script in file.
+
+Sun Nov 24 21:40:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Set GCC_IEEE_FP_FLAG to -mieee-fp on all x86
+	systems, not just those running Linux.
+
+Fri Nov 22 15:10:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave.el: Update from Kurt Hornik to with fixes for
+	fill-paragraph.
+
+Wed Nov 20 00:33:03 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.93.
+
+	* aclocal.m4 (OCTAVE_STRUCT_GR_PASSWD): New macro.
+	* configure.in: Use it.
+	* acconfig.h (HAVE_GR_PASSWD): Add undef.
+
+Tue Nov 19 23:10:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (INCFLAGS): Add libcruft/misc directory.
+
+Thu Nov 14 00:07:31 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave.el (octave-text-functions): Change set and show to
+	gset and gshow.
+
+	* Makeconf.in (TEXI2DVI): Define to be our own private version.
+
+	* texi2dvi: New file.
+	* octMakefile.in (DISTFILES): Add it to the list.
+
+	* configure.in: Don't substitute values in src/mk-oct-links.in.
+
+	* emacs/octave.el: Update to version 0.8.6, from Kurt Hornik.
+
+	* configure.in (RLD_FLAG): Surround case pattern in changequote.
+
+	* Version 1.92.
+
+Wed Nov 13 11:04:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't set or substitute LIBINFO.
+	(infofile): Set and substitute a default value.
+
+	* Makeconf.in (do-subst-default-values): Substitute it here.
+
+	* configure.in: If running on an SCO system, define SCO, and force
+	HAVE_ISINF and HAVE_ISNAN to be defined.
+	Also check for ieeefp.h and nan.h.
+	* acconfig.h (HAVE_ISINF, HAVE_ISNAN, SCO): Add undefs.
+
+Tue Nov 12 21:50:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MAKEINFO.PATCH: Update to use patch relative to texinfo-3.9.
+
+	* INFO.PATCH: New file.
+	* octMakefile.in (DISTFILES): Add it.
+
+	* info: Update to current release from texinfo-3.9.
+
+Mon Nov 11 23:56:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot: Only check value of __GNUC__ and __GNUC_MINOR__ if
+	__GNUC__ is defined.
+
+Fri Nov  8 11:15:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (version): Look in $(TOPDIR)/src then
+	$(srcdir)/$(TOPDIR)/src for version.h.
+
+	* configure.in (TERMLIBS): Print warning message if no term
+	library is found.
+	(CXXLIB_LIST, CXXLIB_PATH, FLIB_LIST, FLIB_PATH): Delete.
+	* Makeconf.in (CXXLIB_LIST, CXXLIB_PATH, FLIB_LIST, FLIB_PATH):
+	Delete.
+	(do-subst-default-vals): Delete CXXLIB_LIST, CXXLIB_PATH,
+	FLIB_LIST, and FLIB_PATH from the list.
+
+Thu Nov  7 12:43:36 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (bin-dist-tar): Delete references to octtopnm.
+
+	* configure.in (RLD_FLAG): Define if x86-linux.
+
+	* Version 1.91.
+
+Wed Nov  6 16:26:39 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Add checks for group stuff.
+
+Tue Nov  5 12:32:30 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Add checks for geteuid, getuid.
+
+	* configure.in: Comment out code to handle --enable-readline since
+	it doesn't work yet.
+
+	* aclocal.m4 (OCTAVE_SIGNAL_CHECK, OCTAVE_REINSTALL_SIGHANDLERS):
+	New checks stolen from bash 2.0 config.
+	* configure.in: Use them.
+
+	* acconfig.h: Add #undefs for HAVE_BSD_SIGNALS, HAVE_POSIX_SIGNALS,
+	HAVE_USG_SIGHOLD, and MUST_REINSTALL_SIGHANDLERS.
+
+Mon Nov  4 11:31:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for gethostname in libsocket.  Apparently
+	needed for some SCO systems.
+
+	* emacs/octave.el: Update to version 0.8.5 from Kurt Hornik.
+
+Fri Nov  1 01:33:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (octave-bug, mkoctfile): After substituting
+	values, chmod a+rx.
+
+Thu Oct 31 13:50:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DISTFILES): Add NEWS.[0-9].
+	* NEWS.1: Old news.
+	* NEWS: Just keep news since last major release.
+
+Wed Oct 30 01:04:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* configure.in: Default is now no internal bounds checking.
+
+	* Makefile.in (all): Fix message to say 2.7.2, not 2.7.0.
+
+	* config.h.bot (GCC_ATTR_NORETURN): Rename from NORETURN.
+	(GCC_ATTR_UNUSED): Rename from GCC_ATTRIBUTE_UNUSED.
+	(NPOS): Define if using gcc 2.8.x or later.
+
+	* octMakefile.in (DIRS_TO_MAKE): Add localarchlibdir to list.
+
+	* configure.in (localarchlibdir): New variable.
+	* Makeconf.in (localarchlibdir): Substitute it.
+	(do-subst-default-vals): Likewise.
+
+Sun Oct 27 14:03:36 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (do-subst-config-vals): Split into two sed commands
+	to try to avoid fixed limits in some seds and/or systems.
+
+Fri Oct 25 01:13:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot: Add definition for GCC_ATTRIBUTE_UNUSED.
+
+	* configure.in: Define RUSAGE_TIMES_ONLY if cygwin32.
+	* acconfig.h: Add undef.
+
+Thu Oct 24 21:17:53 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.guess: Update to version that understands what to do for
+	cygwin32 systems.
+
+Fri Oct 18 12:23:57 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't comment out substitutions for plplot stuff.
+
+Wed Oct 16 12:01:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* examples/Makefile.in (install): New target.
+
+Tue Oct 15 14:40:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Comment out plplot stuff.
+	In commands to get gxx_version and gcc_version, use simpler sed
+	command to avoid confusing brain-dead vendor-supplied seds.
+	
+Mon Oct 14 11:09:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (maintainer-clean distclean): Remove mkoctfile too.
+	(kpathsea.info): New target.
+	(dist-info-files): New target.
+	(links-for-dist, links-for-bin-dist, local-dist-tar):
+	Depend on dist-info-files instead of individual files.
+
+Sat Oct 12 00:17:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* examples/Makefile.in (clean, mostlyclean): New targets.
+
+	* octMakefile.in (CLEANSUBDIRS): New macro.
+	Use it for clean targets.
+
+	* config.h.bot (STATIC_CAST, DYNAMIC_CAST, REINTERPRET_CAST):
+	New macros.
+
+Wed Sep 25 12:24:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't look in /usr/ucb/include to find getrusage
+	on Solaris systems since that just seems to cause trouble.
+	* Makeconf.in (UCB_INCFLAGS): Delete.
+
+Fri Aug 30 09:07:23 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (TERMLIBS): Add check for ncurses.
+
+Tue Aug 20 21:40:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Always set FPICFLAG, CPICFLAG, CXXPICFLAG, SHLEXT,
+	RLD_FLAG, DLFCN_DIR, even if SHARED_LIBS is false.
+
+Thu Aug 15 14:39:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (gxx_version, gcc_version): Strip out cygnus- from
+	the version number.
+
+Tue Jul 30 12:55:43 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Also check for -bI:FILE arg to ld,
+	for AIX systems.
+
+Thu Jul 25 03:09:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: On AIX systems, add "-ll -lld" to LIBDLFCN.
+
+Fri Jul 19 13:02:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: If using g77 on alpha, don't add -fpe1 to FFLAGS.
+
+Mon Jul 15 14:26:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.sub: Update to new version from FSF (gcc sources).
+
+Thu Jun 13 16:38:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Look for g77 before other fortran compilers.
+
+Thu Jun  6 00:05:47 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Add check for multiple plot windows in gnuplot.
+	* acconfig.h: Add #undef for GNUPLOT_HAS_FRAMES.
+
+Wed May 22 15:05:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (UCB_INCFLAGS): Another kluge to try to find
+	getrusage on Solaris systems.
+	* Makeconf.in Substitute it.
+
+	* configure.in (SH_LIBS, SH_FLIBS, SH_TERMLIBS): Define.
+	* Makeconf.in: Substitute.
+
+Wed May 22 02:42:32 1996  Kurt Hornik <Kurt.Hornik at tuwien.ac.at>
+
+	* emacs/octave.el (octave-indent-new-line): Protect
+	octave-indent-line with save-excursion.
+	(octave-calc-indent-this-line): Attempt to handle end tokens that
+	are not on separate lines.
+	(octave-electric-semi): Make `;' self-insert if inside comment.
+	(octave-previous-line): Don't try to go back past the beginning of
+	the buffer.
+
+Tue May 21 23:11:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (F77): Also check for f90.
+
+Mon May 20 12:22:54 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave.el (octave-indent-new-line): Make it do what the
+	docstring says it does.
+
+	* octave-bug.in: Fix previous change so it also matches things
+	like 1.90, not just 1.1.90.
+
+Fri May 17 09:58:49 1996  Kurt Hornik <Kurt.Hornik at tuwien.ac.at>
+
+	* emacs/octave.el (octave-electric-semi): Also call octave-indent-line
+	to indent the current line after inserting a semicolon.
+
+Fri May 17 02:53:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DIRS_TO_MAKE): Add octincludedir.
+	(all): Add mkoctfile.
+
+	* configure.in: Don't set values for exec_prefix, bindir, datadir,
+	libdir, libexecdir, includedir, mandir, or infodir, so that they
+	can be set from the configure command line.
+
+	* configure.in, Makeconf.in: Handle mandir, man1dir and man1ext.
+	Change topincludedir to includedir.  Use octincludedir as the
+	subdirectory of includedir where we really install include files.
+
+	* octave-bug.in (BUGADDR): Also set to octave-maintainers if this
+	looks like a pretest version number.
+
+	* Makeconf.in (do-subst-config-vals): Use $< instead of
+	referencing $(srcdir) directly.
+	(do-subst-default-vals): Likewise.
+
+	* octMakefile.in (octave-bug): Depend on octave-bug.in
+	(mkoctfile): Likewise, depend on mkoctfile.in.
+
+Thu May 16 11:49:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DISTFILES): Add mkoctfile.in.
+	(install): Install mkoctfile too.
+
+	* aclocal.m4 (OCTAVE_F2C_F77_COMPAT): Fix typo in last change
+
+Mon May 13 04:02:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (UGLY_DEFS): Quote " with more \'s.
+
+	* Makeconf.in (do-subst-config-vals): Quote substitutions here.
+	* octave-bug.in, mkoctfile: Not here.
+
+	* octMakefile.in (octave-bug, mkoctfile): Depend on Makeconf,
+	octMakefile.
+
+	* Makeconf.in (do-subst-default-vals): New definition, from
+	src/Makefile.in.
+
+	* Makeconf.in (do-subst-config-vals): Define here.
+	* octMakefile.in: Not here.
+
+	* octave-bug.in: Handle more configuration stuff.
+
+	* configure.in (config_opts): Set from ac_configure_args and subst.
+	* Makeconf.in: Handle config_opts.
+	* octMakefile.in (do-subst-config-vals): Substitute them.
+
+Sun May 12 03:37:55 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (TERMLIBS): Substitute here.
+
+	* configure.in (topincludedir): New variable.
+	* Makeconf.in (libexecdir): Substitute it.
+
+	* octMakefile.in (do-subst-config-vals): Define new command.
+	(octave-bug): Use it.
+	(mkoctfile): New target.
+
+	* Makefile.in (TARGETS): Add mkoctfile.
+
+	* examples: New subdirectory.
+	* octMakefile.in: Add it to the appropriate lists.
+	* configure.in: Create examples/Makefile.
+
+	* octMakefile.in (DIRS_TO_MAKE): Add $(libdir) here.
+	(install): Use INSTALL_PROGRAM to install octave-bug script.
+	Also install config.h.
+
+	* aclocal.m4 (OCTAVE_F2C_F77_COMPAT): Provide a definition for
+	MAIN__ on Linux systems.
+
+Tue Apr 30 05:44:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Handle --enable-bounds-check.
+	* acconfig.h: Add undef for BOUNDS_CHECKING
+
+Mon Apr 29 01:42:38 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_FUNC_SETVBUF_REVERSED): Delete.  Octave doesn't
+	need this check (it was for info, which has its own configure now).
+
+Sun Apr 28 05:41:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (DEFAULT_PAGER): Don't append -e to less here.
+
+Sat Apr 27 22:23:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for pid_t and sys/types.h.
+
+Tue Apr 23 17:44:18 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for fcntl.h, not sys/fcntl.h.
+	Add checks for various system calls.
+
+Sun Apr  7 16:42:54 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for strdup.
+
+	* Makefile.in (TARGETS): Add dlfcn.
+	* octMakefile.in (DISTSUBDIRS): Add dlfcn.
+	(SUBDIRS): Add @DLFCN_DIR at .
+	* configure.in: On AIX systems: set DLFCN_DIR=dlfcn when doing
+	shared libraries, bypass checks for dlopen, etc., set and
+	substitute LIBDLFCN and DLFCN_INCFLAGS.  Create dlfcn/Makefile.
+
+Sat Apr  6 21:45:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (%.d : %.cc, %.d : %.c): Add dependency for pic/%.o.
+
+Fri Mar 29 13:38:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (maintainer-clean distclean): Delete mk-oct-links.
+
+Wed Mar 27 09:05:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_FLIBS): Fix typo in message.
+
+Tue Mar 26 02:41:16 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (UGLY_DEFS): Undo previous change.
+	When checking for various libraries, don't check for main(), but
+	instead look for functions that are actually supposed to be in
+	those libraries.
+	Require autoconf 2.9.
+	If using solaris2, don't add /usr/ucblib/libucb.a to LIBS until
+	near the very end, then check for for getrusage and times just
+	after that.
+
+	* Makeconf.in (UGLY_DEFS): Ditto.
+
+	* octave-bug.in: Don't send empty bug reports.
+
+Sat Mar 23 04:55:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (DISTDIRS): Omit plplot for now.
+	* Makefile.in (TARGETS): Likewise.
+
+Fri Mar 22 06:15:44 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Add checks for sys/times.h and times().
+	(GCC_IEEE_FP_FLAG): Define this if using gcc 2.8.x or later on
+	Alpha/OSF systems.
+
+Wed Mar 20 02:04:08 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (octave.info): cd to doc/interpreter, not doc.
+
+Sun Mar  3 10:01:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot: Define HEAVYWEIGHT_INDEXING here.
+
+	* Makefile.in (TARGETS): Remove dld.
+	* octMakefile.in (DISTSUBDIRS): Ditto.
+	* configure.in: Don't create dld/Makefile.
+	Do create doc/fac/Makefile, doc/interpreter/Makefile,
+	doc/liboctave/Makefile, and doc/refcard/Makefile.
+
+Thu Feb 29 08:55:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (%.o : %.c): Use pattern rule instead of suffix rule.
+	(%.o : %.cc): Likewise.
+	(pic/%.o : %.c, pic/%.o : %.cc): Use separate rules instead of
+	expecting one rule to generate two output files.
+	* configure.in (f77_rules_frag): Use separate rules here too.
+
+Mon Feb 26 03:34:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: If --disable-dl or --disable-shl, don't check for
+	dynamic linking functions.
+	(includedir): Append version.
+
+Wed Feb 14 12:20:57 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (snapshot-version): Don't quote version number.
+
+	* aclocal.m4 (OCTAVE_FLIBS): Avoid setting FLIBS=" ".
+
+Sat Feb 10 12:59:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* glob/Makefile.in (install): New target.
+
+Fri Feb  9 14:00:53 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Fix help text for --enable-shared option.
+
+Thu Feb  8 10:17:55 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (CONF_DISTFILES): New variable.
+	(DISTFILES): Use it instead of listing things twice.
+	(CONF_DISTSUBDIRS): New variable.
+	(conf-dist): New target.
+
+	* Makefile.in (TARGETS): Add conf-dist.
+
+	* configure.in (CXX_VERSION, CC_VERSION): Substitute them.
+	* octMakefile.in (octave-bug): Substitute them here too.
+	* octave-bug.in: Put them in the configuration message.
+
+Sat Feb  3 08:53:56 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: RLD_FLAG should be empty by default, but give it a
+	value for alpha-dec-osf* systems.	
+
+Fri Feb  2 23:03:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in: Actually do add substitutions for FPICFLAG,
+	CPICFLAG, and CXXPICFLAG.
+
+Thu Feb  1 14:58:16 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (%.c : %.f): Fix typo.
+
+Wed Jan 24 14:47:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Also configure in glob subdirectory.
+	Make pattern rule say how to make .o from .f, not .f from .o.  Duh.
+
+	* octMakefile.in: Add glob stuff to the appropriate lists.
+	* Makeconf.in: Likewise.
+
+	* aclocal.m4: Add test for program_invocation_name.
+	* configure.in: Use it here.
+
+	* acconfig.h: Add #undef here.
+
+Mon Jan 22 17:32:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Add checks for mode_t, off_t, size_t, uid_t,
+	dev_t, ino_t, and nlink_t typedefs.
+	* acconfig.h: Add undefs for dev_t, ino_t, and nlink_t.
+
+Sat Jan 20 21:05:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: For Fortran rules, use pattern rules instead of
+	suffix rules.
+
+Fri Jan 19 12:38:23 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: When checking for libf2c.a, add -lm and an extra lib.
+
+Wed Jan 10 16:36:43 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.i: Add missing colon in .o.f pattern for f2c rules.
+
+Mon Jan  8 23:18:39 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_PROG_LN_S): New check.
+	* Makeconf.in (LN_S): Substitute it.
+
+	* configure.in (libexecdir): New variable.
+	(archlibdir, octfiledir, localoctfiledir): Use it instead of libdir.
+	(datadir): Default to $(prefix)/share instead of $(prefix)/lib.
+
+	* Makeconf.in (libexecdir): Substitute it.
+
+	* configure.in (localoctfiledir): Use $(libdir), not $(datadir).
+
+Sun Jan  7 18:40:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* aclocal.m4 (OCTAVE_SMART_PUTENV): New macro, extracted from
+	the kpathsearch library.
+	* configure.in: Call it.
+
+Fri Dec 29 22:07:52 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makeconf.in (subdir-for-command): New definition for
+	SUBDIR_FOR_COMMAND using GNU Make `foreach' instead of shell `for'
+	command.
+	* libcruft/Makefile.in, scripts/Makefile.in, octMakefile.in:
+	Invoke new definition with `@'.
+
+Wed Dec 27 14:27:48 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (SUBDIRS): Delete DLD_DIR.
+	(distclean): Delete Makerules.f77.
+
+	* Makeconf.in (WITH_DLD): Delete variable.
+
+	* configure.in: Delete support for dynamic linking with dld.
+
+	* configure.in, Makeconf.in: Use consistent names for WITH_DL,
+	WITH_SHL, OCTAVE_LITE, and SHARED_LIBS
+	
+	* config.h.bot: Undo previous change.
+	* acconfig.h: Add #undef for WITH_DYNAMIC_LINKING.
+	* Makeconf.in: Substitute it here too.
+	* configure.in: Set it here.
+
+Tue Dec 26 00:12:14 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_CONFIG_SUBDIRS): Delete libcruft.
+	(AC_OUTPUT): List libcruft files here.
+
+	* configure.in, Makeconf.in: Handle Fortran compilation rules
+	using an included fragment in Makeconf.
+
+Mon Dec 25 22:14:21 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (CPICFLAG, CXXPICFLAG, FPICFLAG): New variables.
+	* Makeconf.in: Substitute them.
+
+	* configure.in: Handle --enable-shared option.
+	Handle Fortran source files differently.
+	* Makeconf.in (SHARED_LIBS): Substitute shared_libs.
+	(SHLEXT, RLD_FLAG, fortran_rules_flag): Substitute these too.
+	(.c.o, .cc.o): Handle creating position independent code for
+	shared libraries.
+
+Sun Dec 24 00:29:12 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot: Maybe define WITH_DYNAMIC_LINKING.
+
+	* Makeconf.in (WITH_DL, WITH_SHL): Substitute values.
+	* acconfig.h: Add undefs for WITH_DL and WITH_SHL.
+	* configure.in: Handle --enable-dl and --enable-shl.
+	Check for -ldl and dlopen, dlsym, dlclose, and dlerror.
+	Check for -ldld and shl_load, shl_findsym.
+	(have_fortran_compiler): Quit if no suitable Fortran compiler is
+	found.
+
+Fri Nov  3 03:33:42 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* emacs/octave-mode.el: Rename from octave.el.
+
+Wed Oct 11 19:22:12 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (GNUPLOT_BINARY): When checking for multiplot,
+	issue a `set term unknown' command first.
+
+Wed Oct  4 01:42:35 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.guess: Add entry for PowerPC Macs running Machten.
+
+	* octMakefile.in (dist-z): Remove old .gz file before creating new one.
+
+Mon Oct  2 19:17:22 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check to see if it looks like gnuplot supports
+	multiplot.
+	* acconfig.h: Add undef for GNUPLOT_HAS_MULTIPLOT.
+
+	* acconfig.h: #undefs for HAVE_FINITE, HAVE_ISNAN, HAVE_ISINF,
+	HAVE_TERMIOS_H, HAVE_TERMIO_H, and HAVE_SGTTY_H removed.  This
+	file should only have things that autoheader can't figure out.
+
+Sun Oct  1 17:08:37 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (clean-tar): Also omit directories called OLD and
+	files beginning with =.
+
+Fri Sep 29 01:04:31 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ROADMAP: New file.
+	* (DISTFILES): Include it.
+
+	* emacs: New subdirectory for Emacs-related stuff.
+	* octMakefile.in (DISTDIRS, BINDISTSUBDIRS): Include emacs.
+	(DISTFILES, BINDISTFILES): Don't include octave-mode.el.
+
+Tue Sep 26 03:56:39 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't add -Wno-unused to CFLAGS or CXXFLAGS.
+	* config.h.bot: Remove definition of UNUSED.
+
+	* config.sub: Replace with current version from FSF.
+	* config.guess: Likewise.
+
+Thu Sep 21 20:29:00 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AR, ARFLAGS): Set defaults for these, but also
+	allow them to come from the environment.
+	* Makeconf.in (AR, ARFLAGS): New variables to substitute.
+
+Wed Sep 20 00:51:24 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octMakefile.in (maintainer-clean): Also remove Makeconf,
+	config.cache, config.h, and config.log.
+
+Tue Sep 19 17:20:32 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.h [HAVE_SIGACTION && HAVE_SIGPROCMASK &&
+	HAVE_SIGPENDING && HAVE_SIGSUSPEND]: #define HAVE_POSIX_SIGNALS.
+
+	* configure.in: Check for sigaction(), sigprocmask(),
+	sigpending(), and sigsuspend() functions.
+	Don't do anything special about checking for termios.h, termio.h,
+	and sgtty.h.
+
+Mon Sep 18 22:39:33 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* config.h.bot [__GNUC__]: Define NORETURN.
+
+Fri Sep 15 05:12:29 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_C_BIGENDIAN): Remove test.
+
+Thu Sep 14 02:07:51 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (LIBPLPLOT): Disable plplot by default for now.
+	Check for mkdir, rmdir, rename, and umask.
+
+	* All Makefile.in files: Convert from realclean to
+	maintainer-clean, for GNU coding standards.
+
+	* configure.in: Call AC_FUNC_CLOSEDIR_VOID.
+
+Wed Sep 13 03:25:37 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Do check for IEEE functions on the Alpha.
+
+Mon Sep 11 19:08:47 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Call AC_STRUCT_ST_BLKSIZE, AC_STRUCT_ST_BLOCKS,
+	and AC_STRUCT_ST_RDEV.
+
+Tue Sep  5 02:02:35 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Check for sys/param.h and sys/stat.h
+	Use AC_HEADER_TIME, not AC_TIME_WITH_SYS_TIME.
+	Use AC_HEADER_SYS_WAIT.
+
+Thu Aug 24 15:35:44 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Don't set or call AC_SUBST for CXXFLAGS or CFLAGS,
+	and don't call AC_SUBST for LDFLAGS -- autoconf takes care of this.
+	If adding -Wall, add -Wno-unused too.
+
+Tue Aug 22 01:37:02 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (all): Update message.
+
+	* config.h.bot: New file.
+	* octMakefile.in (DISTFILES): Add it to the list.
+
+	* acconfig.h (USE_PLPLOT): Add #undef.
+
+Mon Aug 21 19:33:33 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (NO_DEP_TARGETS): New variable, for targets that can
+	be made without updating dependency files.
+
+Sun Jun 25 18:27:49 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (FFLAGS): Add -fpe1 on alpha-dec-osf1 systems.
+
+Thu May  4 22:26:34 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: export CC, CXX, and F77 before calling
+	AC_CONFIG_SUBDIRS.
+
+Mon May  1 14:17:07 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: Handle --with-plplot.
+	(AC_CONFIG_SUBDIRS): Add plplot directory if --with-plplot.
+	* plplot: New subdirectory.
+	* Makefile.in (plplot): New target.
+	* octMakefile.in (SUBDIRS): Add @PLPLOT_DIR at .
+	(DISTDIRS): Add plplot.
+
+	* acconfig.h: Add #undef for GETTIMEOFDAY_NO_TZ.
+
+	* configure.in: Improve check for gettimeofday.
+
+Mon May  1 12:50:03 1995  John Eaton  (jwe at bullwinkle.che.utexas.edu)
+
+	* acconfig.h (OCTAVE_LITE): Fix comment.
+
+Tue Apr 11 20:31:52 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (INFO_DIR, READLINE_DIR): New variables.
+	If $USE_GNU_INFO, AC_DEFINE it, don't AC_SUBST it.
+	Likewise, for USE_READLINE.
+
+	* octMakefile.in (SUBDIRS): Substitute INFO_DIR and READLINE_DIR.
+
+	* aclocal.m4 (OCTAVE_F77_UPPERCASE_NAMES): New macro.
+	(OCTAVE_F77_APPEND_UNDERSCORES): Require it.
+	* configure.in: Use it.
+	(info_subdir): If $USE_GNU_INFO, then run configure in info
+	subdirectory too.
+	Don't check for sys/ttold.h or sys/ptem.h.
+
+Mon Apr 10 00:17:57 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (UGLY_DEFS): Delete commands to create this.
+	* Makeconf.in (UGLY_DEFS): Delete substitution.
+	* Makeconf.in (UGLY_ALL_CFLAGS): Delete definition.
+
+	* configure.in: Add scripts and libcruft to CONFIG_SUBDIRS.
+	Don't edit scripts or libcruft Makefiles here.
+	Reorganize checking for the Fortran compiler.
+
+	* octMakefile.in (DISTFILES): Delete f2c-compat.sh flibs.sh
+	cxxlibs.sh from list.  Add aclocal.m4.
+	* configure.in: Use new macros defined in aclocal.m4.  Don't use
+	external shell scripts.  Cache values.
+
+	* aclocal.m4: New file.
+
+Sun Apr  9 12:47:27 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: Print status message before exiting.
+	Cache CXXLIBS and FLIBS.
+
+	* acconfig.h: Delete #undefs for floating point format.
+	* octMakefile.in (DISTFILES): Delete float-type.c from list.
+	* configure.in: Don't try to determine floating point format at
+	configuration time.
+
+Mon Apr  3 21:46:10 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: Create scripts/time/Makefile too.
+
+	* configure.in (gxx_version): Handle new gcc version message.
+	(gcc_version): Likewise.
+
+Wed Mar 29 22:59:42 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (AC_STRFTIME): Delete check.
+	(AC_STRUCT_TIMEZONE): New check.
+
+Wed Mar 22 08:31:21 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makeconf.in (ALL_FFLAGS, FUGLY): New variables.
+
+	* configure.in: Use AC_ARG_ENABLE and AC_ARG_WITH consistently.
+	Handle --with-g77.  Substitute new variable FUGLY.  If F77 is g77,
+	set it to -fugly.  Substitute command for making .o from .f.
+
+Tue Mar 21 14:24:32 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* cxxlibs.sh: Extract -R options like -L options.
+	* configure.in (FLIB_PATH, FLIB_LIST): Extract -R options along
+	with -L options.
+
+Tue Mar 21 14:20:55 1995  Paul Eggert  <eggert at twinsun.com>
+
+	* configure.in (CXX): Export; cxxlibs.sh needs this.
+	(FLIB_LIST, CXXLIB_LIST): Extract -R options along with -L options.
+
+	* flibs.sh: Treat `-L foo' like `-Lfoo'.  Extract -R options
+	like -L options.
+
+Tue Mar 21 08:08:06 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* flibs.sh: Search for values-X*.o, not values-*.o.
+
+Fri Mar 10 10:32:27 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makeconf.in (SUBDIR_FOR_COMMAND): New command definition.
+	* octMakefile.in: Use it.
+
+	* octMakefile.in (install, uninstall, tags, TAGS, clean,
+	mostlyclean, distclean, realclean): Combine actions.
+
+Tue Feb 28 21:24:35 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (FC): Set to $F77 and substitute it.
+	* Makeconf.in (FC): Add substitution line.
+
+Sun Feb 26 00:20:19 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* dointsall.sh: Create ls-R database.
+
+	* configure.in: Configure kpathsea using AC_CONFIG_SUBDIRS().
+	Remove check for SMART_PUTENV.
+	Remove kpathsea/c-auto.h from AC_CONFIG_HEADER().
+
+	* make: New directory, for kpathsea configuration.
+	* octMakefile.in (DISTDIRS): Add it
+
+	* kpathsea: Update with 2.6 distribution.
+
+	* Makefile.in (TARGETS): New variable.  Combine all identical targets.
+
+	* configure.in (LIBINFO, LIBREADLINE): New variables to substitute.
+
+Sat Feb 25 18:47:11 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* acconfig.h (USE_READLINE): Add #undef.
+	* configure.in: Add support for --enable-readline.
+
+	* acconfig.h (USE_GNU_INFO): Add #undef.
+	* configure.in: Add support for --enable-info.
+
+	* acconfig.h (RUN_IN_PLACE): Delete #undef.
+
+See ChangeLog.1 for earlier changes.
diff --git a/ChangeLog.1 b/ChangeLog.1
new file mode 100644
index 0000000..bcdfd75
--- /dev/null
+++ b/ChangeLog.1
@@ -0,0 +1,10392 @@
+Thu Feb 23 09:32:01 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Version 1.1.1 released.
+
+	* src/idx-vector.cc (idx_vector (const Range&)): Always initialize
+	data to 0.
+	(idx_vector (const Matrix&, int, const char *, int)): Likewise.
+	(idx_vector (const idx_vector&): Likewise, do it first.
+	* src/idx-vector.h (~idx_vector): Simply delete data.
+
+	* octMakefile.in: Combine libcruft, liboctave,dld, info, readline,
+	kpathsea, src, scripts, and doc targets into just one.
+	(all): Depend on $(SUBDIRS).
+	* libcruft/Makefile.in (make-objects): Change to $(SUBDIRS)
+	target that doesn't use a loop.
+	(all): Depend on $(SUBDIRS).
+
+Wed Feb 22 07:27:18 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Don't leave @LIBDLD@ on a line by itself.
+
+	* src/tc-rep-idx.cc (fortran_style_matrix_index): Handle zero-one
+	indexing as a separate case.
+	(fortran_style_matrix_index): Check for out-of-bounds index.
+
+	* src/idx-vector.cc (init_state): Don't forget len, num_zeros, and
+	the one_zero flag for vectors of all zero elements.
+	(convert_one_zero_to_idx): Set data to zero after deleting it.
+
+	* src/data.cc (check_dimensions):
+	Handle case of treat_neg_dim_as_zero = "warn".
+
+Tue Feb 21 08:18:19 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-misc.cc (initialize_undefined_elements): Don't declare
+	arg const.
+
+	* src/sysdepl.cc (octave_getcwd): Declare arg as char *, not
+	const char *.
+
+	* src/input.cc (match_sans_spaces): Initialize ep from copy of
+	arg, not arg itself.
+
+	* octMakefile.in (snapshot-version): Look for OCTAVE_VERSION,
+	not just VERSION.  Don't end #define with a semicolon.
+
+Mon Feb 20 15:57:17 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/image/Makefile.in (clean): Delete octtopnm.o and octtopnm.
+
+Fri Feb 17 08:12:09 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/variables.cc (maybe_add_default_load_path): New function,
+	extracted from default_path(), which no longer needs it.
+	* src/user-prefs.cc (sv_loadpath): Call it here.
+
+Wed Feb 15 15:13:22 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/octave.cc (verbose_usage): Format help message more like
+	the help messages of other GNU programs.
+
+	* src/variables.cc (install_builtin_variables): New builtin
+	variable, suppress_verbose_help_message.
+	* src/user-prefs.cc (user_prefs): New field,
+	suppress_verbose_help_message.
+	* src/user-prefs.cc (suppress_verbose_help_message): New function.
+	* src/help.cc (additional_help_message): Check
+	user_pref.suppress_verbose_help_message before printing message.
+
+Tue Feb 14 15:36:01 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/sysdep.cc (octave_chdir): New function.
+	* src/dirfns.cc (change_to_directory): Use it.
+
+	* src/sysdep.cc (octave_getcwd): New function.
+	* src/dirfns.cc (get_working_directory, Fpwd): Use it.
+	* src/input.cc (decode_prompt_string): Likewise.
+
+	* src/version.h (VERSION): New #define.
+	(version_string): Use it.
+	(OCTAVE_COPYRIGHT): New #define.
+	(OCTAVE_NAME_AND_VERSION): New #define.
+	(OCTAVE_NAME_VERSION_AND_COPYRIGHT): New #define.
+	(OCTAVE_STARTUP_MESSAGE): New #define.
+	* src/octave.cc (main): Use new macros from version.h
+	(print_version_and_exit): Likewise.
+	(verbose_usage): Likewise.
+	(Fwarranty): Likewise.
+
+	* Makeconf.in (version): Make work with new version.h.
+	* octMakefile.in (snapshot-version): Likewise.
+
+	* src/variables.cc (default_path): Use SEPCHAR instead of literal ':'.
+	* src/utils.cc (pathstring_to_vector): Likewise.
+	* src/octave.cc (initialize_globals): Likewise, use SEPCHAR_STR to
+	construct format string instead of using literal `:'.
+
+	* configure.in: Call AC_DEFINE for SEPCHAR and SEPCHAR_STR.
+	* acconfig.h: Add #undefs for SEPCHAR and SEPCHAR_STR.
+
+	* src/dynamic-ld.cc: Don't include dld.h unless WITH_DLD.
+
+	* src/octave.cc (parse_and_execute): Close file.
+
+Mon Feb 13 19:39:12 1995  John Eaton  (jwe at bullwinkle.che.utexas.edu)
+
+	* scripts/general/linspace.m: Delete.
+	* src/data.cc (Flinspace): New function.
+	* liboctave/dRowVector.cc (linspace): New function.
+	* liboctave/CRowVector.cc (linspace): New function.
+
+Sun Feb 12 21:23:54 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/load-save.cc (read_mat_binary_data): Only convert to string
+	if the number of rows is 1.
+
+	* scripts/image/saveimage.m: Force ASCII save.
+
+Thu Feb  9 08:46:09 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/elfun/sec.m: Returned variable is `w', not `y'.
+	* scripts/elfun/sech.m: Likewise.
+
+Wed Feb  8 10:51:33 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/f-find.cc (find_nonzero_elem_idx): Increment i, j indices by
+	1 before stashing them.
+
+Fri Feb  3 15:44:03 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-misc.cc
+	(tree_parameter_list::initialize_undefined_elements): New function. 
+	* src/tree-expr.cc (tree_function::eval): Use it to define return
+	values.
+	(tree_simple_assignment_expression:eval): Complain if RHS is undefined.
+	(tree_multi_assignment_expression:eval): Complain if any of the
+	RHS values are undefined. 
+	* src/user-prefs.h (init_user_prefs): New structure element,
+	define_all_return_values.
+	* src/user-prefs.cc (define_all_return_values): New function.
+	* src/variables.cc (install_builtin_variables): Add DEFVARs for
+	default_return_value and define_all_return_values.
+	(builtin_any_variable): New function.
+
+Wed Feb  1 08:02:28 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/parse.y (parse_error): Call yyerror() here.
+	(input): Not here.	
+
+	* src/lex.l (handle_string): Call have_continuation and
+	have_ellipsis_continuation with 0 arg, to disallow comments after
+	continuation characters inside strings.
+	(have_continuation): New arg, trailing_comments_ok with default
+	value of 1.  If !trailing_comments_ok, don't allow comments to
+	follow continuation token.
+	(have_ellipsis_continuation): New arg, trailing_comments_ok, with
+	default value of 1.  Pass it along to have_continuation.
+
+	* src/parse.y (yyerror): Call parse_error with first arg == "%s",
+	since msg might contain format specifiers.
+
+	* src/tree-expr.cc (tree_index_expression::eval (int)): Detect
+	undefined elements in argument list and print error message.
+	(tree_index_expression::eval (int, int, const Octave_object&)):
+	Likewise.
+
+	* configure.in: Only set CFLAGS, CXXFLAGS, LDFLAGS, FFLAGS, and
+	F2CFLAGS if they are not already set in the environment.
+
+	* doinstall.sh: Add -print to find commands.
+
+Tue Jan 31 13:26:53 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l (<MATRIX>{S}*\,{S}*): Eat any trailing continuation
+	here.  Use value returned from eat_continuation to decide whether
+	to insert a row separator.
+	(<MATRIX>{S}+): Likewise.
+	(<MATRIX>{SNLCMT}*\n{SNLCMT}*): Eat any trailing whitespace here.
+
+	* lex.l (ATE_SPACE_OR_TAB, ATE_NEWLINE): New macros.
+	(eat_whitespace): Use them to set return value.
+
+Mon Jan 30 14:02:24 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/user-prefs.cc (set_output_precision): Don't pass NaN to NINT.
+	(set_output_max_field_width): Likewise.
+	(set_save_precision): Likewise.
+	* src/file-io.cc (return_valid_file): Likewise.
+	(fgets_internal): Likewise.
+	(fseek_internal): Likewise.
+	(process_printf_format): Likewise.
+	(fread_internal): Likewise.
+	* src/f-colloc.cc (Fcolloc): Likewise.
+	* src/f-fft.cc (Ffft): Likewise.
+	* src/f-fft2.cc (Ffft2): Likewise.
+	* src/f-ifft.cc (Fifft): Likewise.
+	* src/f-ifft2.cc (Fifft2): Likewise.
+	* src/f-npsol.cc (do_npsol_option): Likewise.
+	* src/f-qpsol.cc (do_qpsol_option): Likewise.
+	* src/f-rand.cc (Frand): Likewise.
+	* src/pr-output.cc (all_elements_are_ints): Likewise.
+	* src/tree-plot.cc (subplot_using::eval): Likewise.
+	(subplot_style::print): Likewise.
+	* src/sysdep.cc (Fpause): Likewise.
+	* src/tc-rep.cc (TC_REP::valid_as_scalar_index): Likewise.
+	(TC_REP::valid_as_zero_index): Likewise.
+	(TC_REP::convert_to_str): Likewise.
+	* src/tc-rep-idx.cc (TC_REP::do_scalar_index): Likewise.
+	(TC_REP::fortran_style_matrix_index): Likewise.
+	* src/tc-rep-ass.cc (TC_REP::fortran_style_matrix_assignment):
+	Likewise.
+
+Sat Jan 28 13:09:44 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/general/tril.m: Allow the k == nc for k > 0 and
+	-k == nr for k < 0.  Make faster by eliminating nested loops.
+	* scripts/general/triu.m: Likewise.
+
+Fri Jan 27 08:32:10 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* libcruft/lapack: Update with files from LAPACK 2.0.
+
+	* src/lex.l (\[{S}*): Don't call fixup_column_count() here.
+	Don't use TOK_RETURN here, since we call eat_whitespace().
+	(eat_whitespace): Decrement current_input_column when calling
+	yyunput().
+	(<MATRIX>{SNLCMT}*\n{SNLCMT}): Always call fixup_column_count().
+
+	* src/parse.y (rows): Don't accept repeated semicolons.
+	(matrix_row): Likewise, for commas.
+
+	* src/Makefile.in (LIBOBJS): Delete.
+
+	* liboctave/f77-uscore.h: Don't use C++ style comments.
+
+	* octMakefile.in (DISTDIRS): Don't include bsd-math.
+	* src/Makefile.in (VPATH): Don't include bsd-math directory.
+	(SOURCES): Include acosh.c, asinh.c, atanh.c, erf.c erfc.c, and
+	lgamma.c.
+	* configure.in: Create libcruft/slatec-fn/Makefile.
+	Use AC_CHECK_FUNCS to look for acosh, asinh, atanh.
+	Don't do anything special if they are missing.
+	* src/acosh.c, src/asinh.c, src/atanh.c, src/erf.c, src/erfc.c,
+	src/lgamma.c: New files.
+	* acconfig.h: Delete #undefs for ACOSH_MISSING, ASINH_MISSING,
+	and ATANH_MISSING.
+	* libcruft/Makefile.in (CRUFT_DIRS): Add slatec-fn.
+	* libcruft/slatec-fn: New directory.
+
+	* configure.in: Don't try to use IEEE floating point on m68k HP
+	systems.
+	
+Thu Jan 26 12:57:05 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l (maybe_unput_comma):  New function, extracted from
+	handle_identifier().  Correctly handle the dot in things like
+	`a.b' inside matrix lists.
+	(handle_identifier): Use it.  Don't allow things like [a .1] or
+	[a.b .1] to fool us.
+
+Wed Jan 25 08:04:16 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/Makefile.in (realclean): Don't depend on distclean.  Do
+	delete Makefile here.
+
+	* flibs.sh: Also check for /*values-*.o, for Sun Fortran 2.x.
+	* configure.in (FLIB_LIST, CXXLIB_LIST, FLIB_PATH, CXXLIB_PATH):
+	Delete any .o files found here.
+	When checking for -lm, also append -lc on Linux systems.
+
+	* mkinstalldirs: Create directories with mode 0755, to avoid
+	problems because the installers umask is too restrictive.
+
+	* octave-bug.in: Don't use rmail, it crashes on Ultrix systems if
+	the message file isn't just right.  Use nested if statements
+	instead of ||, for Ultrix /bin/sh.  Avoid Ultrix awk crash.
+
+	* scripts/linear-algebra/trace.m: Handle row and column vectors as
+	a special case.
+	* scripts/linear-algebra/null.m: Likewise.
+	* scripts/linear-algebra/orth.m: Likewise.
+
+Tue Jan 24 08:11:51 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octave-bug.in: Add F2C, F2CFLAGS, FLIBS, and LDFLAGS to report.
+	* Makefile.in (octave-bug): Substitute them.
+
+Mon Jan 23 20:42:55 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-misc.cc (tree_if_clause::is_else_clause): New function.
+	(tree_if_command_list::print_code): Use it to decide whether to
+	print "else" or "elseif" here.
+	(tree_if_clause::print_code): Don't print "else" here.
+
+	* scripts/image/colormap.m: Fix logic for initializing default
+	colormap and handling subsequent calls with no arguments.
+
+	* src/lex.h (TOK_PUSH_AND_RETURN): Correct last change.
+
+Sun Jan 22 18:02:37 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l (handle_identifier): Handle incrementing
+	current_input_column here.
+	({IDENT}{S}*): Not here.
+
+	* src/lex.h (TOK_PUSH_AND_RETURN): New macro.
+	* src/lex.l: Use it.
+
+	* src/parse.y (yyerror): If printing input line, always print `^'
+	error marker too.
+
+	* src/parse.y (command [BREAK]): Allow break to occur in function
+	bodies too.
+	* src/tree-expr.cc (tree_function::eval): Also check to see if
+	function exited because of a break statement.
+
+Fri Jan 20 10:48:18 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* config.guess: Replace with current version from FSF.
+	* config.sub: Likewise.
+
+	* src/tempname.c: Include statdefs.h.
+
+	* src/tree-expr.cc (eval): Improve error messages.
+
+Thu Jan 19 08:33:50 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l (handle_string): Properly handle pending escapes.
+	Call error() for unterminated string constants.
+	* src/parse.y (input): For parse errors, call yyerror().
+
+	* test/config/unix-octave.exp (octave_start): Correctly set OSPATH
+	from $OCTAVE_SCRIPT_PATH, not to the string OCTAVE_SCRIPT_PATH.
+
+	* test/Makefile.in (OCTAVE_SCRIPT_PATH): Delete surrounding quotes
+	in definition.
+
+	* doc/texinfo.tex: Move to version 2.140.
+
+	* src/f-rand.cc (Frand): Use different method for generating
+	initial seed so that it varies more each time Octave starts.
+
+	* src/file-io.cc (feof_internal): Use args(0), not args(1).
+
+	* src/Makefile.in (SOURCES): Use tempnam.c, not tmpnam.c.
+	* src/tempnam.c: New file, from the GNU C library.
+
+Wed Jan 18 08:10:31 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/user-prefs.h (user_prefs): New field, read_only_constants.
+	* src/user-prefs.cc (read_only_constants): New function.
+	* src/variables.cc (install_builtin_variables): Add DEFVAR for
+	read_only_constants, but leave it #if 0'd out since we're not
+	really ready for it yet..
+	* src/symtab.cc (symbol_record::read_only_error): Check
+	user_prefs.read_only_constants to see if it is ok to redefine
+	constants that are marked as read-only.
+
+	* src/user-prefs.h (user_prefs): New field, ps4.
+	* src/user-prefs.cc (sv_ps4): New function.
+	* src/variables.cc (install_builtin_variables): Add DEFVAR for PS4.
+	* src/input.cc (do_input_echo): New function.  Use PS4 variable as
+	prefix of echoed input.  Send echoed input through the pager.
+
+	* flibs.sh: Ignore -lang* options.
+
+	* src/load-save.cc (Fsave): Send `save - ...' output through the
+	pager.
+
+	* doc/Makefile.in: Create and distribute refcards of various sizes.
+	Delete rules for making refcard.tex from refcard.tex.in.
+	Don't make or distribute refcard-local.
+	* doc/refcard.tex: Handle setting paper size with \refcardsize.
+	* doc/refcard-a4.tex, doc/refcard-legal.tex, doc/refcard-letter.tex:
+	New files.
+
+Mon Jan 16 13:19:29 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tc-rep-ass.cc (TC_REP::do_scalar_assignment): Handle
+	assignments like a(0) = [].
+	* src/tc-inlines.h (valid_zero_index): New function.
+	* src/tc-rep.cc (valid_as_zero_index): New function.
+	* src/tree-const.h (valid_as_zero_index): New function.
+
+	* src/parse.y (func_def2): Check user_prefs before warning about
+	function name and function file name conflict.
+	* src/user-prefs.h (user_prefs): New field, warn_function_name_clash.
+	* src/user-prefs.cc (warn_function_name_clash): New function.
+	* src/variables.cc (install_builtin_variables): Add DEFVAR for
+	warn_function_name_clash.
+
+	* scripts/image/octtopnm.c: Include stdlib.h instead of malloc.h.
+
+Sun Jan 15 15:08:04 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* readline/rldefs.h: Use new #defines for directory headers now
+	that we are using autoconf 2.
+
+	* scripts/special-matrix/hankel.m: Use .', instead of '.
+
+	* src/input.cc (match_sans_spaces): Use strcmp, not strncmp.
+
+	* src/tc-rep-ass.cc (TC_REP::fortran_style_matrix_assignment):
+	For scalar index, don't do assignment if RHS and LHS are both empty.
+
+	* src/data.cc (Fsize): Handle optional second arg.
+
+	* src/tree-expr.cc (tree_function::eval (int)): Correctly set
+	nargin and nargout to zero when evaluating function.
+
+	* src/lex.l (handle_string): Correct handling of string escapes.
+
+Thu Jan 12 15:25:34 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Version 1.1.0 released.
+
+	* octMakefile.in (bin-dist-tar): Ignore errors on strip commands.
+
+	* src/tree-expr.cc (tree_builtin::eval (int)): Set nargout to 0
+	when calling function.
+
+	* doc/Makefile.in (FORMATTED): Add refcard.dvi and refcard.ps so
+	that they are distributed along with the other docs.
+	* octMakefile.in (clean-doc-dist-tar): Delete target.
+	(doc-dist): Depend on doc-dist-tar, not	clean-doc-dist-tar. 
+
+Tue Jan 10 14:29:43 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/help.cc (print_usage): Print warning if symbol isn't found.
+
+	* src/utils.cc (Fundo_string_escapes): Fix typo in call to
+	print_usage().
+
+	* src/octave.cc (Fsystem): Correctly compute exit code.
+
+	* scripts/miscellaneous/etime.m: Complain if args are not the
+	right length, not if they are.  Reverse sense of test for years.
+	Duh.
+
+	* src/f-find.cc (find_to_fortran_idx): For the case of one output
+	argument, return a row vector if the original argument to find was
+	a row vector.
+
+Mon Jan  9 12:57:27 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l (grab_help_text): Always overwrite help_buf.
+	({CCHAR}): Don't call grab_help_text() if there is already
+	something in help_buf.
+
+Sat Jan  7 12:28:35 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (HOST_CXXFLAGS): New variable to substitute.
+	* Makeconf.in (ALL_CXXFLAGS, UGLY_ALL_CXXFLAGS, BUG_CXXFLAGS):
+	Add $(HOST_CXXFLAGS).
+
+Fri Jan  6 13:07:09 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/special-matrix/toeplitz.m: Use .' instead of '.
+
+Tue Jan  3 18:14:33 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* test: Rewrite many tests to not run Octave interactively.  This
+	makes the log files much more readable.
+
+	* octMakefile.in (clean-tar): Delete octave-test/npsol directory,
+	not just test/octave.test/npsol.exp.  Likewise, add a command for
+	deleting qpsol tests.
+
+Mon Jan  2 20:02:10 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/octave.cc (main): Return 0 if error_state is not set.
+
+	* src/error.cc (error_1): New function.
+	(error): Use it.
+	(parse_error): New function.
+	* src/parse.y: Never call error and yyerror; just use yyerror.
+	(yyerror): Improve logic.  Use new parse_error() function so that
+	error_state is always set for a parse error.  Don't use
+	ostream::form().
+	(ABORT_PARSE): Don't call reset parser here.
+	(colon_expr): Don't call yyerror here.  An error message is
+	printed by tree_colon_expression::chain() if it fails.
+
+Mon Dec 26 20:11:01 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-expr.cc (eval): Only call multi-arg form of eval for
+	object_to_eval if necessary.
+
+Fri Dec 23 00:08:08 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l: Don't increment promptflag anywhere.
+	(eat_continuation): New function.
+	(eat_whitespace): Handle embedded continuations.  Return nonzero
+	if whitespace consumed.
+	(handle_close_brace): Don't pass yytext.  Do pass flag indicating
+	whether whitespace follows brace.
+	(handle_identifier): Check for next token being `=' here.  Pass
+	flag indicating whether whitespace follows identifier.
+	(<MATRIX>{SNLCMT}*;{SNLCMT}*): Call eat_whitespace() here.
+	({IDENT}{S}*): Call eat_continuation() here.
+	(do_comma_insert_check): And here, but put a space back if
+	whitespace is gobbled.
+	(have_continuation, have_ellipsis_continuation): Decrement
+	promptflag here.
+
+Wed Dec 21 09:56:49 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-plot.cc (Fclearplot): Send "set nolabel" too.
+
+Mon Dec 19 17:50:15 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-plot.h, src/tree-plot.cc (subplot): Rename using to
+	using_clause to avoid new C++ keyword.  Rename title and style to
+	match.
+
+Fri Dec 16 00:09:01 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: Don't check for fpsetmask.
+	* src/sysdep.cc (sysdep_init): Don't check HAVE_FPSETMASK
+
+Thu Dec 15 00:28:52 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/variables.cc (install_builtin_variables) [default_save_format]: 
+	Fix doc string.
+
+	* configure.in: Rework DEFAULT_DOT_O_FROM_DOT_F and
+	DEFAULT_DOT_C_FROM_DOT_F to avoid embedded newlines.
+	* Makeconf.in: Likewise.
+
+	* src/pager.cc (flush_output_to_pager): Close stream before
+	resetting signal handler.
+
+	* src/help.cc (Fhelp): Call fcn_file_in_path here.  Delete it too.
+	Print file name before help message.
+	* src/variables.cc (get_help_from_file): Don't call
+	fcn_file_in_path here.
+	(gobble_leading_white_space): Correctly grab only first set of
+	comments.
+	
+Wed Dec 14 11:42:13 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/parse.y (pager_buf): Don't make it a fixed-size array.
+	* src/variables.cc (get_help_from_file): New function.
+	(gobble_leading_white_space): Return first block of comments for
+	later use as help string.
+	(looks_like_octave_copyright): New function.
+	(parse_fcn_file): Stash help from gobble_leading_white_space in
+	global help_buf.
+	* src/lex.l (grab_help_text): Don't overwrite help found by
+	gobble_leading_white_space.
+	(reset_parser): Delete help_buf.
+	* src/help.cc (Fhelp): Only try to get help from symbol records
+	that are defined.  If all else fails, try get_help_from_file.
+
+	* src/pager.cc (flush_output_to_pager): Re-initialize pager_buf
+	immediately after extracting message.  Delete message immediately
+	after sending it to the output stream.  Ignore interrupts while
+	running pager.
+
+	* octMakefile.in (clean-tar): Delete npsol.exp and any .m files
+	that are in the test/octave.test directory.
+	(install): Use $(INSTALL), not just install.
+
+	* src/lex.l (reset_parser): Don't reset input column or line
+	number if reading from a script file or a function file.
+	(is_keyword): Don't set line number to 1 if reading function file
+	or script file.
+	* src/variables.cc (gobble_leading_whitespace): Count lines.
+	* src/octave.cc (main): If reading file, set reading_script_file
+	and curr_fcn_file_name before calling get_input_from_file().
+
+	* src/tc-rep.cc (TC_REP::matrix_value): If implicit_str_to_num_ok,
+	convert empty string to empty matrix.
+
+Tue Dec 13 20:25:34 1994  Frederick (Rick) A Niles <niles at axp745.gsfc.nasa.gov>
+
+	* liboctave/dbleQR.cc, liboctave/dbleQRP.cc, liboctave/CmplxQR.cc,
+	liboctave/CmplxQRP.cc: Get economy-sized dimensions correct.
+
+	* libcruft/misc/i1mach.f, libcruft/misc/gen-d1mach.c,
+	libcruft/ranlib/ignuin.f: Prevent warnings about variable may be
+	used before defined.
+
+Tue Dec 13 11:07:34 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/variables.cc: Change commas_in_literal_matrix to
+	whitespace_in_literal_matrix.
+	* src/user-prefs.h (user_preferences): Likewise.
+	* src/user-prefs.cc (init_user_prefs): Likewise.
+	(whitespace_in_literal_matrix): Likewise, rename function.
+	* src/lex.l: Likewise.
+	(nesting_level): Rename from in_brace_or_paren.
+	(<MATRIX>{SNLCMT}*\n{SNLCMT}*): Make separate case from
+	<MATRIX>{SNLCMT}*;{SNLCMT}.  Check nesting level to decide whether
+	to convert newline to semicolon.
+	({NL}, {CCHAR}): Check nesting level to decide whether to eat
+	or return newline. 
+	("("): Decrement promptflag.
+	(")"): Increment promptflag.
+
+Mon Dec 12 00:02:51 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/Makefile.in, scripts/*/Makefile.in (install): Don't
+	depend on all.
+
+	* octMakefile.in: Put doc dir last.
+	* doc/Makefile.in (dir): New file.
+	(DISTFILES): Distribute dir.
+	(install): Install dir if it does not already exist in $(infodir).
+	Otherwise, print message.
+
+	* src/lex.l: Handle {IDENT}{S}*/= with yyinput() instead of
+	trailing context.
+	(handle_close_brace): New function.
+	(handle_number): New function.
+	(have_continuation, handle_ellipsis_continuation, handle_string):
+	New functions for handling strings and continuation lines in
+	string constants.
+	(eat_whitespace): New function eliminates need for NEW_MATRIX
+	start state.
+
+Sun Dec 11 15:53:03 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l: Eliminate special case for eating whitespace when
+	start state is <TEXT_FCN>.
+	Merge three cases for handling `]' for <MATRIX> start state.
+
+Fri Dec  9 12:21:35 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l: Handle `\' as a continuation character too.
+	Allow comments and blanks to follow continuation characters.
+	Improve handling of comments in matrices.  Create a few more
+	definitions for patterns.  Restructure source.
+
+	* configure.in: Check for bcopy too.
+
+	* configure.in (gxx_version): Don't use -fno-implicit-templates on
+	AIX systems with g++ 2.6.x.
+
+	* octave-bug.in: Check for CC: lines too.  Use case-insensitive
+	match for To: and Cc: lines.  Actually send file that has header
+	separator stripped.  Print list of CC: addresses too.
+
+	* src/input.cc (get_user_input): If user enters empty string,
+	return empty matrix or empty string.
+
+	* src/help.cc (Fhelp, Ftype, Fwhich): Don't allow lookup_by_name
+	to execute script files.
+
+Thu Dec  8 23:20:02 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tc-rep.cc (print): Don't check `print', which is not a
+	variable in this context.
+
+Wed Dec  7 10:52:59 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/configure.in: Check for fpsetmask.
+	* src/sysdep.cc (sysdep_init): Check HAVE_FPSETMASK.  Only call it
+	if either __386BSD__ or __FreeBSD__ is defined.
+	Don't check __386BSD__ as a condition for including
+	floatingpoint.h.
+
+Mon Dec  5 12:29:07 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/utils.cc: Update directory header macro names for autoconf 2.
+	* src/dirfns.cc: Likewise.
+
+Sun Dec  4 22:00:40 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octMakefile.in (DISTFILES): Don't distribute GCC.PATCH, since it
+	is not needed with gcc 2.6.3.
+
+	* configure.in: Really do disable IEEE floating point functions on
+	the Alpha.
+
+Wed Nov 30 11:42:44 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* doc/FAQ.texi: New file.
+	* doc/Makefile.in: Create info, dvi, and ps files and distribute
+	them.
+
+	* Makefile.in (all): Expand initial message.
+
+Sat Nov 26 21:47:05 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/octave.cc (Fcomputer): Always append ios::ends to ostrstream
+	before returning.
+
+Mon Nov 21 09:41:34 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l: When start state is TEXT_FCN, gobble blanks with
+	pattern that matches only blanks before other patterns that can
+	also match just blanks.  Always check whether in_brace_or_paren
+	stack is empty before trying to use it.
+
+	* src/parse.y (make_multi_val_ret): Call constructor for
+	tree_simple_assignment_expression with correct number of args.
+
+	* scripts/plot/shg.m: New function.
+
+	* src/f-qpsol.cc (Fqpsol): Correct for changes in meaning of
+	nargin and the way args is loaded.
+	* src/f-npsol.cc (Fnpsol): Likewise.
+
+	* scripts/polynomial/roots.m: Return empty matrix for scalar or
+	empty matrix args.
+
+	* src/tree-plot.cc (gnuplot_terminal_type): New static variable.
+	(Fset): If this is a set term command, set gnuplot_terminal_type.
+	(open_plot_stream): Use gnuplot_terminal_type if it is set.
+
+	* src/idx-vector.cc (idx_vector::init): Don't check max value of
+	index vector against dimension here.  We may need to resize.
+	* src/tc-rep-idx.cc (do_scalar_index): Do check idx-vector max
+	value here.
+
+	* src/lex.l (is_plot_keyword): Don't set past_plot_range here.
+	Don't accept abbreviations for clear.
+	(handle_identifier): Don't call is_plot_keyword unless plotting.
+	Set past_plot_range here, before checking for plot option keywords.
+
+Fri Nov 18 17:25:59 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/data.cc (Fis_struct): New function.
+
+Thu Nov 17 18:13:56 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octMakefile.in (DISTFILES): Distribute GCC.PATCH.  Don't
+	distribute LIBG++.PATCH.
+
+	* src/tree-plot.cc (Fclearplot): Turn off grid and reset
+	plot_line_count to zero.
+
+	* configure.in: Check for sys/resource.h.
+	Create scripts/strings/Makefile too.
+
+	* src/timefns.cc: Surround inclusion of sys/resource.h in extern "C".
+	Only include sys/resource.h if both HAVE_SYS_RESOURCE_H and
+	HAVE_GETRUSAGE are defined.
+
+Wed Nov 16 09:26:10 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/plot/plot_opt.m: New function.
+	* scripts/plot/semilogx.m, scripts/plot/semilogx.m,
+	scripts/plot/loglog.m, scripts/plot/plot.m: Handle additional
+	args and format strings.
+	* scripts/plot/polar.m: Handle format arg.
+	* scripts/plot/polar_int_1.m, scripts/plot/polar_int_2.m: Extract
+	from polar_int.m.
+	* scripts/plot/plot_int_1.m, scripts/plot/plot_int_2.m: Extract
+	from plot_int.m.
+	* scripts/plot/plot_2_s_s.m, scripts/plot/plot_2_v_v.m,
+	scripts/plot/plot_2_m_m.m, scripts/plot/plot_2_v_m.m,
+	scripts/plot/plot_2_m_v.m: Handle format arg.
+
+	* scripts/strings/strcmp.m: Move here.
+	* scripts/general/strcmp.m: From here.
+
+	* src/xdiv.cc (result_ok): Issue warning instead of error if warn
+	is nonzero.
+
+Tue Nov 15 15:54:19 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-plot.cc (Fcloseplot): Clear title and labels too.
+
+	* src/help.cc (keywords): Add entries for all_va_args,
+	unwind_protect, unwind_protect_cleanup, and end_unwind_protect.
+
+	* liboctave/Makefile.in: Use -include for dependency files.
+	* src/Makefile.in: Likewise.
+
+Mon Nov 14 10:28:23 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-misc.cc (convert_to_const_vector): Resize vector before
+	returning.
+
+	* src/lex.l (plot_style_token): Also allow "steps", "boxes", and
+	"boxerrorbars".
+
+	* src/parse.y (UNWIND): Rename from UNWIND_PROTECT.
+	(CLEANUP): Rename from UNWIND_PROTECT_CLEANUP.
+	(command): Allow optsep after UNWIND and CLEANUP tokens.
+	* src/lex.l (is_keyword): Use new token names
+
+	* src/tree-const.h (tree_constant::all_va_args): New enum.
+	(tree_constant (tree_constant::all_va_args t)): New constructor.
+	(is_all_va_args): New function.
+	(is_empty, is_zero_by_zero, make_numeric_or_magic,
+	make_numeric_or_range_or_magic): Handle	all_va_args type.
+	* src/tc-rep.h (constant_type::all_va_args): New enum element.
+	(is_all_va_args): New function.
+	* src/tc-rep.cc (TC_REP::tree_constant_rep (TC_REP::constant_type),
+	TC_REP::print_code): Handle all_va_args.
+	* src/tree-misc.cc (tree_argument_list::convert_to_const_vector):
+	Handle all_va_args.
+	* src/tree-expr.cc (tree_index_expression::eval): After call to 
+	tree_argument_list::convert_to_const_vector (), check error_state.
+	(tree_simple_assignment_expression::eval): Likewise.
+	(tree_function::octave_all_va_args): New function.
+	* src/parse.y (ALL_VA_ARGS): New token.
+	(arg_list): Handle ALL_VA_ARGS.
+	* src/lex.l (is_keyword): Handle all_va_args.
+
+	* src/tree-expr.cc (tree_identifier::bump_value): Check read-only
+	status of sym before altering value.
+	(tree_prefix_expression::eval): Check error_state after call to
+	tree_identifier::bump_value ().
+
+	* src/variables.cc (bind_nargin_and_nargout): Don't make nargin
+	and nargout read only.
+
+	* scripts/strings: New subdirectory for string functions.
+	* scripts/Makefile.in (SUBDIRS): Add strings.
+	* scripts/strings/strcat.m: New function.
+
+Fri Nov 11 14:17:31 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/load-save.cc (extract_keyword): Allow trailing blanks on the
+	input line. 
+
+Thu Nov 10 09:53:35 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/general/reshape.m, scripts/image/ind2gray.m,
+	scripts/image/ind2gray.m, scripts/image/ind2rgb.m,
+	scripts/image/rgb2ind.m: unwind_protect do_fortran_indexing.
+	* scripts/general/strcmp.m: unwind_protect implicit_str_to_num_ok.
+	* scripts/miscellaneous/menu.m: unwind_protect page_screen_output.
+
+	* src/parse.y (UNWIND_PROTECT, UNWIND_PROTECT_CLEANUP): New tokens.
+	(command): Handle unwind-protect.
+	* src/lex.l (is_keyword): Handle unwind_protect,
+	unwind_protect_cleanup, and end_unwind_protect.
+	* src/tree-cmd.cc (tree_unwind_protect_command): New class, to
+	handle unwind-protect.
+
+	* src/token.h (end_tok_type): New field, end_unwind_protect.
+
+	* src/error.cc (verror): Flush pending output to pager here.
+	(error): Not here.
+
+	* src/tc-rep.cc (force_numeric): Don't jump to top level on error.
+	* src/tc-rep.cc, src/tc-rep-ass.cc, src/tc-rep-idx.cc: Check
+	error_state after calls to make_numeric* functions.
+
+	* src/f-lpsolve.cc: Define Flp_solve and Flp_solve_options, not
+	Flpsolve or Flpsolve_options.
+
+	* src/utils.cc (Ffile_in_path): Define Ffile_in_path, not
+	Ffile_in_pat.
+
+	* src/f-inv.cc: Add DEFUN for inverse.
+
+Wed Nov  9 09:30:15 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/load-save.cc (read_mat_file_header): Check for mopt < 0 too.
+	Don't fail if reading mopt fails.
+	(save_mat_binary_data): Handle range data as a special case.
+	(get_default_save_format): Also accept `mat-binary' and
+	`mat_binary'.
+	(Fsave): Add ios::trunc to flags for opening output file.
+
+	* src/parse.y (func_def2): Stash function name before stashing
+	file name.
+
+	* src/utils.cc (fcn_file_in_path): Don't append `.m' if the name
+	already ends in `.m'.
+	(oct_file_in_path): Likewise, for `.oct'.
+
+	* src/error.cc (usage): Set error state to -1, so we get traceback
+	information after a call to usage.
+
+	* src/tree-expr.cc (stash_fcn_file_name): Store full name of the
+	file.
+
+	* scripts/*/*.m: Change messages to say `invalid' instead of
+	`illegal', since no laws are being broken by using these functions
+	incorrectly.
+
+	* src/timefns.cc (Fcputime): New function.
+	* configure.in: Check for getrusage.
+
+	* src/scripts/miscellaneous/tic.m: New function.
+	* src/scripts/miscellaneous/toc.m: New function.
+	* src/scripts/miscellaneous/etime.m: New function.
+	* src/scripts/miscellaneous/is_leap_year.m: New function.
+
+	* src/error.cc (Fwarning, Fusage): New functions.
+	* scripts/*/*.m: Use them instead of printing warning and usage
+	messages directly with disp, printf, or fprintf.
+
+	* src/file-io.cc (close_files): Check Pix before using.
+	(file_count): Delete unnecessary variable.  Instead, use
+	DLList::length to get the number of files in the list.
+
+	* src/sighandlers.cc (install_signal_handlers): Explicitly ignore
+	SIGPOLL and SIGIO.
+
+Tue Nov  8 15:26:50 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/general/logspace.m: Lose fractional part of third arg.
+	Don't round, for compatibility with Matlab.
+	* scripts/general/linspace.m: Likewise.
+
+	* liboctave/CMatrix.cc (row_min, row_max, row_min_loc, row_max_loc):
+	Handle case of row containing only real elements.
+	(column_min, column_max, column_min_loc, column_max_loc):
+	Likewise, for columnwise operations.
+	* src/f-minmax.cc (two-complex-arg min, max): Handle case of both
+	columns containing only real elements.
+
+	* src/variables.cc (Fclear): Pass 0 to symbol_table::list() for
+	pats and npats.
+
+Mon Nov  7 20:22:36 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* liboctave/dColVector.cc (operator +=): Don't return reference to
+	temporary.
+	(operator -=): Likewise.
+	* liboctave/CMatrix.cc (operator +=, operator -=): Likewise.
+
+Sun Nov  6 23:15:24 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octMakefile.in (DISTSUBDIRS): Don't use $(SUBDIRS) here.
+
+	* src/load-save.cc (Fsave): Open output file with mode ==
+	ios::out, not ios::in.
+
+Sat Nov  5 18:18:11 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (HAVE_SYS_SIGLIST): Check for sys_siglist variable,
+	even if it isn't declared in a system header.
+	* acconfig.h (HAVE_SYS_SIGLIST): Add #undef.
+	* src/sighandlers.cc (sys_siglist): Define our own if
+	HAVE_SYS_SIGLIST is not defined, not if SYS_SIGLIST_DECLARED is
+	not defined.
+
+	* src/tree-plot.cc (Fclearplot): New function.
+	(clg): Alias for clearplot.
+
+	* src/parse.y (CLEAR): New token.
+	(statement): Handle PLOT CLEAR as a special case.
+	* src/lex.l (is_plot_keyword): Handle CLEAR here too.
+
+Fri Nov  4 08:44:57 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* All: Remove remaining #pragma interface/implementation statements.
+
+	* src/tree-plot.cc (subplot): Move actual code here from .h file.
+
+	* src/tree-expr.cc (tree_expression): Declare destructor virtual.
+	Delete unnecessary destructors.
+
+	* src/SLStack.h, src/SLStack.cc (operator =): Return reference to
+	SLStack, not void.
+
+	* src/f-qzval.cc (Fqzval): Rename from Fqzvalue.  Change Help
+	and usage messages too.
+
+	* scripts/plot/plot_int.m: Really figure out if there are any
+	imaginary parts.
+
+	* scripts/control/are.m: Fix typo.
+
+Thu Nov  3 18:44:11 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/load-save.cc (save_ascii_data): Handle new arg,
+	strip_nan_and_inf.  Change callers.
+	(strip_infnan): New functions.
+	(save_three_d): Strip inf and nan values here too.
+
+	* src/tree-plot.h (subplot_using): New data have_values and val.
+	* src/tree-plot.cc (subplot_using::eval, subplot_using::values):
+	New functions.
+	(subplot_style::errorbars): New function.
+	(subplot::extract_plot_data, subplot::handle_plot_data): New functions.
+	(subplot::print): Improve handling of data.
+
+Wed Nov  2 08:11:08 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/file-io.cc (do_scanf): If reading from stdin, flush stdout
+	first.
+
+	* configure.in: Leave some comments in the configure file.
+	Improve checking for termios.h, termio.h, and sgtty.h.
+
+	* src/variables.cc (install_builtin_variables): DEFVAR realmax and
+	realmin here.
+	* src/sysdep.cc: Instead of DEFUNing them here.
+
+	* src/variables.cc (do_who): Accept globbing patterns as args.
+	(maybe_list): Handle them here.
+
+	* src/symtab.cc (matches_patterns): New function.
+	(symbol_table::list, symbol_table::long_list): Accept list of
+	patterns, and use matches_patterns to see if the given string is a
+	match.  Change all callers.
+
+	* src/load-save.cc (read_binary_data): Don't fail if reading
+	name_len fails.
+	(do_load): Quit quietly if nothing is left to read.  Clean up doc
+	and name in all cases.
+
+Tue Nov  1 16:34:20 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/lex.l (")"): Set cant_be_identifier to 1 here too.
+
+	* src/tree-plot.cc: Use abbreviations for gnpulot plot, splot,
+	replot, with, using, and title commands.
+
+Mon Oct 31 14:26:12 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/variables.cc (Fclear): Look in global symbol table for
+	user-defined function names.
+
+	* src/load-save.cc (do_load): New function.
+	(Fload): Use it to avoid assigning streams.
+	(write_binary_header): New function.
+	(save_vars): New function.
+	(Fsave): Use it to avoid assigning streams.
+
+	* libcruft/linpack/zgesl.f (zgesl): Comment out unused varialbes
+	and statement functions.
+
+	* src/sysdep.cc (Fisieee): New function.
+	(Frealmax, Frealmin): Ditto.
+
+	* scripts/miscellaneous/version.m: New file.
+
+Fri Oct 28 14:52:08 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octMakefile.in (distclean): Also delete config.cache and
+	config.log.
+
+	* Makeconf.in (CPPFLAGS): Allow substitution.
+
+	* configure.in: Use AC_PREFIX_DEFAULT.
+
+	* configure.in: Use AC_CANONICAL_HOST instead of doing this
+	ourselves.
+
+	* install-sh: Rename from install.sh.
+	* octMakefile.in (DISTFILES): Distribute install-sh, not install.sh.
+
+Mon Oct 24 10:04:27 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octave-bug.in: Print message if bug report appears to have been
+	mailed successfully.  Otherwise, exit with error status.
+
+Fri Oct 21 14:05:10 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tc-rep-ass.cc (TC_REP::do_vector_assign (rhs, idx-vector)):
+	Handle all four cases of row/colum mixing.  Report an error if the
+	RHS is a matrix.
+
+	* src/tc-rep-idx.cc (TC_REP::do_index): Don't barf on indexing an
+	empty matrix with colon(s).
+	(TC_REP::do_scalar_index): Create index vector with  z_len = 1.
+	(TC_REP::do_matrix_index (Range, tree_constant)): Correctly handle
+	case of colon as second arg.
+
+	* octave-bug.in: Put mail commands in subshells so error message
+	really do go away.
+
+Thu Oct 20 11:05:36 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* octave-bug.in: If passing $SUBJECT on the command line to a
+	mailer, quote it.  Don't assume /bin/mail takes any args other
+	than a recipient address.  Do the right thing if the To: line
+	changes.
+
+	* src/tc-rep.cc (TC_REP::rows, TC_REP::columns): Return -1 for
+	anything that doesn't really have rows or columns.
+
+	* src/tc-rep-idx.cc (fortran_style_matrix_index): Check max and
+	min index values.
+
+	* Makefile.in (FORCE): New phony target.  Used instead of .PHONY
+	to be portable.
+
+	* octave-bug.in: Try harder to mail the message.
+
+	* src/dynamic-ld.cc: Undefine true, false, and boolean after
+	including kpathse/pathsearch.h.
+
+	* src/sysdep.cc: Include <float.h>.
+
+Wed Oct 19 10:28:49 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in (CXXLIB_LIST, FLIB_LIST, CXXLIB_PATH, FLIB_PATH):
+	Be careful not to match -l or -L in the middle of a word.
+
+	* src/f-minmax.cc: Correctly handle mixed scalar/matrix args.
+
+	* octMakefile.in: Rename from Makefile.in.
+	* Makefile.in: New file.  For `all' target, print message and
+	execute make again using octMakefile.  For other targets, just
+	execute make again using octMakefile.
+
+	* configure.in: Check for sys_siglist.
+	* src/sighandlers.h [! HAVE_SYS_SIGLIST]: Provide an external
+	declaration.
+	* src/sighandlers.cc (generic_sig_handler): New function, replaces
+	most individual signal handler functions.
+	(sigint_handler, sigpipe_handler): Restore signal handler before
+	doing anything else.
+	[! HAVE_SYS_SIGLIST] (sys_siglist): Provide our own definition.
+
+	* config.guess: Update from FSF sources.
+
+Tue Oct 18 23:36:24 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* flibs.sh: Don't pass -Y P,path.  Instead, turn it into a series
+	of -L dir args.
+
+	* configure.in: Update for autoconf 2.0.
+	Delete support for --enable-run-in-place (it is too hard to make
+	this work reliably...).
+
+Mon Oct 17 11:40:49 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/user-prefs.cc (init_user_prefs): Declare to return void,
+	not int.
+
+	* configure.in: Change quote characters around tr command.  Some
+	systems actually do need the []'s for ranges...
+
+Sun Oct 16 12:22:14 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tempname.c, src/tmpnam.c: New files.
+	* src/Makefile.in (SOURCES): Add them.
+	* src/dirfns.cc: Delete functions extracted from glibc.
+
+	* configure.in (localfcnfiledir, localoctfiledir, imagedir):
+	New variables.  Use them to define localfcnfilepath,
+	localoctfilepath, and imagepath.
+	* Makeconf.in: Substitute them here.
+
+	* src/utils.cc (get_fcn_file_names) [WITH_DLD]: Also match .oct
+	files.
+
+	* dld/find_exec.c (dld_find_executable): Don't be fooled by
+	directories or other special files in PATH.
+	(ABSOLUTE_FILENAME_P): Also return true if the name includes a
+	`/'.  This isn't necessarily an absolute path, but we will turn it
+	into one later.
+	* src/dynamic-ld.cc (octave_dld_init): Call make_absolute() on
+	value returned from dld_find_executable().
+
+Sat Oct 15 08:35:13 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* flibs.sh: Undo previous change.  Only substitute spaces for
+	commas if it looks like we have output from xlf.  Handle -Y and
+	LD_RUN_PATH using gcc's -Xlinker option.
+
+	* Makefile.in (snapshot-version): Use move-if-change for version.h.
+
+Fri Oct 14 09:18:08 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/image/Makefile.in (SOURCES): Don't forget octtopnm.c.
+
+	* Makefile.in (BINDISTFILES): Distribute octave-bug too.
+
+	* configure.in (imagepath): Install at same level as fcnfiledir,
+	not below it.
+
+	* doinstall.sh: Correctly extract version numbers that are not all
+	digits.  Also install images too.  Also install octaverc.  Ask
+	octave for the target host type.  Also create site/m and
+	site/oct directories.  Also install octave-bug.
+
+	* scripts/image/Makefile.in (DISTFILES): Distribute demo image
+	files too.
+
+	* doinstall.sh: Update for new directory organization.
+
+	* src/variables.cc (subst_octave_home): Make it work for multiple
+	substitutions.
+
+	* flibs.sh: Handle -Y P,path:of:lib:dirs output from f77 on Solaris.
+
+	* src/strfns.cc (Ftoascii): New file, new function.
+	(Fisstr, Fsetstr): Move here, fromd ata.cc.
+
+	* src/Makefile.in (SOURCES): Include it.
+
+Thu Oct 13 11:58:03 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/signal/filter.m: Postpad `b' before reshaping.
+
+	* mkinstalldirs: New file.
+	* Makefile.in: Distribute it, don't make mkpath.
+	* All Makefile.in files: Use it instead of mkpath.
+
+	* src/utils.cc (Foctave_tmp_file): New function.
+
+	* src/utils.cc (undo_string_escape): Move here from tc-rep.cc,
+	rename from undo_string_escapes, and make extern.
+	(undo_string_escapes): New function, for undoing a whole string.
+	(Fundo_string_escapes): New function.
+
+	* scripts/miscellaneous/dump_prefs.m,
+	scripts/miscellaneous/dump_1_pref.m: New functions.
+	* scripts/miscellaneous/bug_report.m: Record user preferences in a
+	file and pass the name of the file to octave-bug.  Use
+	octave_tmp_file to generate tmp file name.
+	* octave-bug.in: Accept a final file-name arg as a file that
+	contains a list of user-preferences.
+
+Wed Oct 12 09:09:37 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: Redefine archlibdir and octfiledir so that oct
+	and exec directories are at the same level as the m directory.
+	Redefine localoctfilepath so that site/oct is a the same level as
+	site/m.
+
+	* Makeconf.in (F77): Substitute it.
+	(BUG_CFLAGS, BUG_CXXFLAGS): New vars.
+	* configure.in:
+	* scripts/bug_report.m: New file.
+	* octave-bug.in: New file.
+	* Makefile.in (DISTFILES): Distribute octave-bug.in.
+	(dirs_to_make): Add $bindir.
+	(all): Add octave-bug.
+	(octave-bug): New target.
+	(install): Install it.
+	* src/defaults.h.in: Add defines for bindir.
+	* src/Makefile.in (defaults.h): Substitute it.
+	* src/variables.cc (octave_bin_dir): New function.
+	* src/octave.cc (initialize_globals): Also add $bindir to path.
+
+	* configure.in: Check for gettimeofday. Add AC_TIME_WITH_SYS_TIME.
+	* src/systime.h: New file.
+	* src/timefns.h: Use gettimeofday if available.
+	* src/Makefile.in (INCLUDES): Add systime.h.
+
+Mon Oct 10 14:34:56 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/octave.cc (verbose_flag): New global variable.
+	(long_opts): Add "verbose".
+	(usage_string): Update.
+	(main): Set verbose_flag if given --verbose.
+	(execute_startup_files): Don't print messages about reading
+	startup files if verbose_flag is not set.
+
+	* src/tree-expr.cc (apply_mapper_fcn): Handle scalars as a special
+	case, but then just try to convert other arg types to a matrix.
+
+	* src/f-det.cc (Fdet): Check if arg is complex type, but not
+	necessarily a complex matrix.
+	* src/f-schur.cc (Fschur): Likewise, and also for real types.
+	* src/f-lu.cc (Flu): Likewise.
+	* src/f-minmax.cc (Fmin, Fmax): Likewise.
+
+Sun Oct  9 21:04:17 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tc-rep-ass.cc (TC_REP::assign): If LHS is undefined, don't
+	try to force it to be a numeric type.
+
+Fri Oct  7 09:05:10 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: Define LD_STATIC_FLAG for Alpha OSF/1 1.3 systems.
+
+	* src/tc-rep-idx.cc (TC_REP::do_index): Only work for numeric
+	types, but don't panic if conversion doesn't work.
+	* src/tc-rep-ass.cc (TC_REP::assign): Likewise.
+
+	* src/tc-rep.cc (TC_REP::gripe_wrong_type_arg): New function.
+
+	* src/gripes.cc (gripe_wrong_type_arg): Define here.
+	* src/tree-const.cc: Not here.
+
+Wed Oct  5 16:24:38 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/file-io.cc (do_scanf): Don't panic if string is NULL.
+
+	* src/gripes.cc (gripe_unrecognized_float_fmt): New function.
+	(gripe_2_or_3_dim_plot): Ditto.
+	(gripe_unrecognized_data_fmt): Ditto.
+	(gripe_data_conversion): Ditto.  Use it in load-save.cc data
+	conversion routines that aren't implemented yet.
+
+	* src/load-save.cc (do_double_format_conversion): Don't panic on
+	unrecognized floating point formats.
+	(do_float_format_conversion): Likewise.
+	(write_doubles): Don't panic if data format is unrecognized.
+	(do_save): Likewise
+	(install_loaded_variable): Don't panic for unknown symbol types.
+	(read_binary_data): Also check error_state after calls to read_doubles.
+
+	* src/symtab.cc (symbol_table::rename): Don't panic if symbol
+	can't be renamed.
+	* src/parse.y (return_list): Abort parse if renaming results in an
+	error.
+
+	* src/tree-misc.cc (tree_if_command::eval): Don't panic if all
+	(all (cond)) is not a scalar.
+
+	* src/tree-expr.cc (tree_unary_expression::print_code): Don't
+	panic if expression type is unknown.
+
+	* src/tree-plot.cc (tree_plot_command::eval): Don't panic if plot
+	is not 2 or 3 dimensional.
+	(tree_plot_command::print_code, subplot::print, save_in_tmp_file):
+	Likewise.
+
+	* src/variables.cc (alias_builtin): Panic with better message.
+	(subst_octave_home): Don't panic if OCTAVE_HOME doesn't contain
+	OCTAVE_PREFIX.
+
+	* src/tc-inlines.h (REP_RHS_MATRIX): Use panic_impossible()
+	instead of abort().
+	(REP_ELEM_ASSIGN, CRMATRIX): Likewise.
+
+	* src/data.cc (Fdiag, make_diag): Do work here.
+	* src/tc-rep.cc (TC_REP::diag, make_diag): Not here.
+	* src/tc-rep.h (TC_REP::diag): Delete.
+	* src/tree-const.h (tree_constant::diag): Delete.
+
+Tue Oct  4 08:35:37 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/f-fft.cc (Ffft): Correctly set n_points for row vectors if
+	nargin == 1.
+	* src/f-ifft.cc (Fifft): Likewise.
+
+	* src/load-save.cc (Fsave): Declare file and stream static.
+
+Mon Oct  3 10:40:50 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tree-expr.cc (octave_va_arg): Correct arg count and index to
+	match recent change to arg passing/nargin.
+	(define_param_list): Always set num_named_args = param_list->length ().
+
+	* readline/Makefile.in (install): Don't install libreadline.a by
+	default.
+	(uninstall): Now no need to delete it.
+
+	* configure.in (localfcnfilepath, localoctfilepath): Change to 
+	match organization of system fcn and oct files, and enable
+	recursive searching in both.  Enable recursive searching in
+	$(octfiledir).
+	(includedir): Change to $(prefix)/include/octave.
+
+Sun Oct  2 10:14:18 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: For now, disable IEEE floating point functions on
+	the Alpha.  This is braindead, but at least prevents divide by
+	zero crashes...
+
+	* src/file-io.cc (fseek_internal): Use values for origin that
+	match what we use to define SEEK_SET, SEEK_CUR, and SEEK_END in
+	variables.cc.
+
+	* dld: Merge various changes for Linux from dld 3.2.4 that is
+	being distributed with jacal.
+
+	* src/file-io.cc (fwrite_internal): Correct indexing of args.
+
+	* src/tree-expr.cc (apply_mapper_fcn): New function.
+	(tree_builtin::eval): Use it instead of tree_constant::mapper().
+	* src/tree-const.h (tree_constant::mapper): Delete.
+	* src/tc-rep.cc, src/tc-rep.h (TC_REP::mapper): Delete.
+
+	* src/data.cc (Fcumprod, Fcumsum, Fprod, Fsum, Fsumsq): Do work here.
+	* src/tc-rep.cc (TC_REP::cumprod, TC_REP::cumsum, TC_REP::prod,
+	TC_REP::sum, TC_REP::sumsq): Not here.  Delete. 
+	* src/tc-rep.h (TC_REP::cumprod, TC_REP::cumsum, TC_REP::prod,
+	TC_REP::sum, TC_REP::sumsq): Delete
+	* src/tree-const.h (tree_constant::cumprod, tree_constant::cumsum,
+	tree_constant::prod, tree_constant::sum, tree_constant::sumsq):
+	Delete.
+
+	* tree-const.h: Don't check gcc minor version number.
+	* tc-rep.h: Likewise.
+
+	* src/file-io.h (class file_info): Declare here.
+	* src/file-io.cc: Not here.
+
+	* configure.in (LIBOCTDLD, LIBDLD): Remove ../ prefix.
+	* Makefile.in (distclean, realclean): Don't remove *.a.
+	* src/Makefile.in (OCTAVE_LIBS): Correct directory spec for libs.
+	Build, install, and clean liboctdld.a, not ../liboctdld.a.
+	* dld/Makefile.in: Build, install, and clean libdld.a, not ../libdld.a.
+	* info/Makefile.in: Likewise, for libinfo.a.
+	* kpathsea/Makefile.in: Likewise, for libkpathsea.a.
+	* libcruft/Makefile.in: Likewise, for libcruft.a.
+	* liboctave/Makefile.in: Likewise, for liboctave.a.
+	* readline/Makefile.in: Likewise, for libreadline.a.
+
+	* configure.in (gxx_version): Require 2.6.x or later.  Don't
+	define EXTERNAL_TEMPLATES.  Do define NO_IMPLICIT_TEMPLATES.
+	* liboctave/Array-C.cc, liboctave/Array-d.cc, src/Array-tc.cc,
+	src/DLList-fi.cc src/SLStack-tok.cc, src/SLStack-ue.cc,
+	src/SLStack-tm.cc, src/SLStack-pc.cc, src/SLStack-i.cc,
+	src/SLList-tc.cc, src/SLStack-sym.cc, src/SLStack-ui.cc,
+	src/SLList-misc.cc, src/SLList-expr.cc, src/SLList-plot.cc,
+	src/Map-tc.cc: New files.  Instantiate templates here.
+	* libocave/Array.cc, src/Map.cc, src/Stack.cc, src/SLStack.cc:
+	Not here.  Remove #pragma implementation hack.
+	* liboctave/Array.h, src/Stack.h, src/Map.h, src/SLStack.h: Remove
+	#pragma interface hack.
+	* Makeconf.in: Substitute NO_IMPLICIT_TEMPLATES, not
+	EXTERNAL_TEMPLATES.
+	(ALL_CXX_FLAGS, UGLY_ALL_CXX_FLAGS): Use $(NO_IMPLICIT_TEMPLATES),
+	not $(EXTERNAL_TEMPLATES).
+	* acconfig.h: Remove USE_EXTERNAL_TEMPLATES #undef.
+	* src/Makefile.in (XALL_CXX_FLAGS): Delete -fno-implicit-templates.
+	(TI_SRC, TI_OBJ): New variables.
+	(libtinst.a): New target.
+	* liboctave/Makefile.in (TI_SRC): New variable.
+	(SOURCES): Add it to list.
+
+Fri Sep 30 09:52:15 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/Makefile.in: Automatically generate more lists.
+	Use := in more places.
+	* src/Array-C.cc src/Array-d.cc src/Array-tc.cc src/Map-tc.cc
+	src/Stack-i.cc src/SLStack-pc.cc src/SLStack-sym.cc
+	src/SLStack-tok.cc src/SLStack-tm.cc src/SLStack-ue.cc:
+	New template instantiation files.
+	* configure.in: If using gcc 2.6.x or later, use
+	-fno-implicit-templates instead of -fexternal-templates.
+
+	* src/tc-inlines.h: Rename from tc-inlines.cc.
+
+	* src/parse.y (looking_at_indirect_ref): New global flag, for
+	parser feedback.
+	(tree_indirect_ref_type): New token type.
+	(TEXT_ID): New token.
+	(indirect_ref): New non-terminal.
+	(make_index_expression): New function.
+	(variable): Use it to build variable from indirect_ref, not just
+	identifier.
+
+	* src/lex.l (handle_identifier): Handle identifiers differently if
+	looking at an indirect reference.  Add `.' to list of other ops.
+
+	* src/tree-expr.cc (tree_identifier::do_lookup): Handle new
+	exec_script arg.
+	(tree_identifier::assign): New functions for assignment to a
+	strucutre element.
+	(print_constant): New function.
+	(tree_identifier::eval, tree_indirect_ref::eval): Use it.
+	(
+	
+	* src/tree-expr.h (tree_indirect_ref): New class for handling
+	structure references.
+	(tree_expression::is_indirect_ref): New virtual function.
+	(tree_fvc::lookup_map_element): New virtual function.
+	(tree_index_expression, tree_simple_assignment_expression):
+	Add new constructors for handling indirect references.
+
+	* src/oct-map.h: New file, for class managing Octave's
+	structure/map type.
+
+	* src/tree-misc.cc (tree_global::eval): Don't allow individual
+	structure elements to be tagged global.
+
+	* src/tc-rep.h (tree_constant_rep): Add new field, a_map, and a
+	new type_tag, map_constant.
+	* src/tree-const.cc (tree_constant::is_map): New function.
+	* src/tree-const.cc (tree_constant::map_value,
+	tree_constant::assign_map_element, tree_constant::make_unique,
+	tree_constant::lookup_map_element,
+	tree_constant::make_unique_map_element): New functions.
+
+	* src/Map.h (CHNode::CHNode): Copy key.
+	(CHNode::~CHNode): Delete it.
+	(CHMap::contents): Don't declare return value const.
+
+	* src/tc-inlines.cc: Move some macros here from tc-rep.cc so they
+	can appear in one place and be shared by tc-rep-idx.cc,
+	tc-rep-ass.cc, and tc-pre.cc.
+
+	* src/tc-rep-idx.cc, src/tc-rep-ass.cc: New files, extracted from
+	tc-rep.cc to make compilation of tc-rep stuff faster and require
+	less memory.
+
+	* src/variables.cc (Fwhos): Correctly insert "-long" into arg list
+	for Fwho.
+
+Mon Sep 26 12:59:55 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* test/Makefile.in (OCTAVE_SCRIPT_PATH): Append `//' for recursive
+	searching.
+
+Fri Sep 23 07:53:13 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/plot/bar.m: Don't return values if nargout == 0.
+	* scripts/plot/hist.m: Likewise.
+	* scripts/plot/stairs.m: Likewise.
+
+	* src/tree-plot.cc (Fishold): New function.
+	(plot_line_count, parametric_plot, clear_before_plotting):
+	Declare static.
+
+	* src/f-fft.cc (Ffft): Handle row vector as a special case.
+	* src/f-ifft.cc (Fifft): Ditto.
+
+Thu Sep 22 13:20:53 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/help.cc (print_symbol_type): New function, extracted from Fwhich.
+	(Fwhich): Use it.
+	(Fhelp): Use it to print type info before help message.
+
+	* src/dynamic-ld.cc: Hide all DLD-specific functions behind
+	#ifdef WITH_DLD.
+
+	* scripts/startup: New directory.
+	* scripts/startup/Makefile.in: New file.
+	* scripts/startup/octaverc: New file.  Don't overwrite existing
+	file when nstalling.
+	* configure.in: Generate Makefile in scripts/startup.
+	* scripts/Makefile.in (SUBDIRS): Add startup.
+	* src/defaults.h.in (OCTAVE_STARTUPFILEDIR): New macro.
+	* src/variables.cc (get_site_defaults): Look for octaverc in
+	OCTAVE_STARTUPFILEDIR.
+
+	* configure.in (fcnfiledir): Make it end in `//'.
+
+	* src/error.cc (Ferror): Correct indexing error.
+
+	* src/Map.h, src/Map.cc: New files implementing associative arrays.
+	* src/Makefile.in: Include them in the list of files to distribute
+	and compile.
+
+Wed Sep 21 09:50:19 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (DISTSUBDIRS): Add dld to the list.
+
+	* scripts/plot/hist.m: New function file.
+
+	* src/tc-rep.cc (TC_REP::do_matrix_index (tree_constant,
+	tree_constant): For case of scalar as first arg, move call to
+	index check to the TC_REP::do_matrix_index (int, tree_constant)
+	function.
+	(TC_REP::do_matrix_index (int, tree_constant): Be compatible with
+	Matlab for indexing of the form row_vector (0, :).
+	(TC_REP::do_matrix_index (tree_constant, int): Likewise, for
+	indexing of the form col_vector (:, 0).
+	(TC_REP::do_matrix_assignment): Similar changes for assignment.
+
+Tue Sep 20 17:48:39 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/parse.y (return_list, return_list1): New nonterminals.
+	Rename from func_def1a.  Handle variable number of return values.
+	* src/tree-expr.h (tree_function::vr_list): New field.
+	* src/tree-expr.cc (delete_vr_list): New function.
+	(tree_function::octave_vr_val, tree_function::takes_var_return):
+	New functions, for variable return lists.
+	(tree_function::define_ret_list, tree_function::eval): Handle vr_list.
+	(Fvr_val): New function.
+	* src/tree-misc.h (tree_va_return_list): New list class.
+	* src/tree-misc.cc (tree_parameter_list::convert_to_const_vector):
+	Take pointer to tree_va_return_list as arg, and append the values
+	found there.
+
+	* src/arith-ops.cc (mx_stupid_bool_op): Correctly handle empty
+	matrices for == and != ops.
+
+	* src/variables.cc (Fis_global): Check args(0), not args(1).
+	(Fexist): Likewise.
+	(install_builtin_mapper): Set nargin_max to 1, not 2.
+
+	* src/dynamic-ld.cc (octave_dld_init): Make raw program name
+	absolute before calling dld_find_executable.
+
+	* src/octave.cc (initialize_error_handlers): New function.
+	(main): Call init_user_prefs and initialize_error_handlers.
+	Rearrange order of calls to initialization functions.
+
+	* src/user-prefs.cc (init_user_prefs): New function.
+
+	* src/data.cc (map): Correct condition for assert ().  Correct
+	handling of empty args.
+
+	* src/f-lsode.cc src/f-dassl.cc src/f-quad.cc src/f-npsol.cc
+	src/f-fsolve.cc: Pass correct number of args to
+	takes_correct_nargs ().
+	* src/variables.cc (takes_correct_nargs): Use %s, not %c in format
+	string.
+
+	* src/f-ifft2.cc src/f-expm.cc src/f-det.cc src/f-svd.cc
+	src/f-syl.cc src/f-schur.cc src/f-qzval.cc src/f-qr.cc
+	src/f-pinv.cc src/f-lu.cc src/f-log.cc src/f-inv.cc src/f-hess.cc
+	src/f-eig.cc src/f-chol.cc src/f-balance.cc src/f-lsode.cc
+	src/f-dassl.cc src/f-quad.cc src/f-npsol.cc src/f-fsolve.cc:
+	Correctly handle return value from empty_arg ().
+	* src/utils.cc (empty_arg): Clarify usage, correct return value if
+	arg is empty but no message is printed.
+
+	* src/Makefile.in (dist): Delete builtins.cc too.
+
+	* configure.in (DYNAMIC_LD_OBJ): Delete.
+	* src/Makefile.in (OBJECTS): Don't substitute DYNAMIC_LD_OBJ.
+	Always include dynamic-ld.o.
+
+	* configure.in: Generate Makefile in scripts/elfun and
+	scripts/specfun.
+
+	* Makeconf.in (version): Use `:=' and `$(shell )', not just `='
+	and backticks, so we only extract the version number once.
+
+Mon Sep 19 09:04:30 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/tc-rep.h (represent_strings_with_doubles): New field in
+	tree_constant_rep class.
+
+	* tree-misc.cc (tree_argument_list::convert_to_const_vector):
+	Don't allocate extra arg for function name.
+	* sysdep.cc, pr-output.cc, input.cc, file-io.cc, error.cc,
+	tc-rep.cc, tree-expr.cc, f-svd.cc, f-sort.cc, f-schur.cc,
+	f-rand.cc, f-qzval.cc, f-quad.cc, f-qr.cc, f-qpsol.cc, f-pinv.cc,
+	f-npsol.cc, f-minmax.cc, f-lu.cc, f-lsode.cc, f-log.cc, f-inv.cc,
+	f-ifft2.cc, f-ifft.cc, f-hess.cc, f-givens.cc, f-fsolve.cc,
+	f-fft2.cc, f-fft.cc, f-expm.cc, f-eig.cc, f-det.cc, f-dassl.cc,
+	f-colloc.cc, f-chol.cc, f-balance.cc, f-syl.cc, variables.cc,
+	tree-misc.cc, data.cc, octave.cc, utils.cc, defun-int.h:
+	Change meaning and usage of nargin and args.length() to cope with
+	above change.  This makes nargin mean the same thing in built-in
+	functions as it does in M-files.
+
+Sat Sep 17 09:29:08 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* scripts/general/nargchk.m: New function.
+
+Fri Sep 16 08:48:13 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makeconf.in (FLIB_LIST, FLIB_PATH, CXXLIBS, CXXLIB_LIST,
+	CXXLIB_PATH): Set these.
+
+	* cxxlibs.sh: New file.
+	* configure.in: Use it to determine extra C++ libraries to link
+	to.  Use sed magic to extract list of libraries and directories
+	from FLIBS and CXXLIBS.
+	* Makefile.in: (DISTFILES): Include cxxlibs.sh.
+
+	* configure.in: Change AC_VERBOSE messages to match
+	autoconf-generated messages.
+
+	* src/dynamic-ld.cc (dld_octave_resolve_reference): Search library
+	path for list of files to link.
+
+	* src/utils.cc (pathstring_to_vector): Un-#if 0 it.
+
+	* Makefile.in: Install liboctdld.a if not linking to it.
+	(defaults.h): Substitute FLIB_LIST, FLIB_PATH, CXXLIB_LIST,
+	CXXLIB_PATH.
+
+Thu Sep 15 09:31:29 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makeconf.in (LD_STATIC_FLAG): Actually substitute LD_STATIC_FLAG.
+	(ALL_LDFLAGS): Include it here.
+
+	* configure.in: Check for signgam declaration in math.h
+	* acconfig.h: Add #undef for SIGNGAM_DECLARED.
+	* src/mappers.h: Provide our own declaration of signgam if
+	HAVE_LGAMMA but not SIGNGAM_DECLARED.
+
+Wed Sep 14 11:28:09 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/dynamic-ld.cc (mangled_octave_builtin_name,
+	mangle_octave_oct_file_name, load_octave_builtin,
+	load_octave_oct_file, init_dynamic_linker): New functions.
+	[WITH_DLD] (octave_dld_init, dld_octave_resolve_reference,
+	dld_octave_builtin, dld_octave_oct_file): New functions to handle
+	details of dynamic linking using dld.
+
+	* src/variables.cc (load_fcn_from_file) [WITH_DLD]: Handle looking
+	for .oct file to link at run time.
+
+	* src/tree-expr.cc (tree_builtin::tree_builtin): Always init my_name.
+	(tree_builtin::eval): If no definition, try to load one using
+	load_octave_builtin().
+
+	* src/octave.cc (main): Initialize dynamic linking here.
+
+	* src/defun-int.h (DEFINE_FUN_STRUCT, DEFINE_FUN_STRUCT_FUN):
+	New macros.
+	* src/defun-dld.h (DEFUN_DLD_BUILTIN): Rename from DEFUN_DLD and
+	handle case of WITH_DLD && OCTAVE_LITE && MAKE_BUITLINS.
+	(DEFUN_DLD): Use this for external user-supplied functions that
+	are intended to be dynamically linked.
+
+	* configure.in: Handle --enable-lite-kernel.  Call AC_SUBST for
+	use_dld and lite_kernel.  Define LIBOCTDLD unless doing dynamic
+	linking and small kernel requested.
+	* acconfig.h: Add #undefs for OCTAVE_LITE and SMART_PUTENV.
+	* Makeconf.in: Define WITH_DLD from @use_dld@ and OCTAVE_LITE from
+	@lite_kernel at .
+
+	* src/octave.cc (Fsystem): Rename from shell_cmd.
+	(Fshell_cmd): Define as alias to Fsystem.
+
+Mon Sep 12 20:19:20 1994  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* src/mappers.cc: Include error.h and math.h.
+
+Sat Sep 10 11:49:11 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makefile.in: Clean up rules for making distributions.
+	(DISTDIRS): Distribute kpathsea
+
+Fri Sep  9 08:46:03 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/dMatrix.cc (pseudo_inverse): New function.
+	* liboctave/CMatrix.cc (pseudo_inverse): New function.
+	* src/f-pinv.cc: New file, for pinv().
+	* src/Makefile.in (DLD_SRC): Add f-pinv.cc.
+	(DLD_OBJ): Add f-pinv.o.
+	* scripts/linear-algebra/pinv.m: Delete.
+
+	* configure.in: Define and substitute $imagepath.
+	* src/Makefile.in: Substitute OCTAVE_IMAGEPATH.
+	* src/defaults.h.in: Add OCTAVE_IMAGEPATH.
+	* src/variables.cc (install_builtin_variables): Define IMAGEPATH.
+	* src/user-prefs.cc (image_path): New function.
+	* Makeconf.in (imagepath): substitute it.
+
+	* src/octave.cc (initialize_globals): Ensure that $archlibdir is
+	in the user's PATH.
+
+	* utils.cc (search_path_for_file, Ffile_in_path): New functions.
+
+	* configure.in: Append `//' to $fcnfiledir, for recursive
+	searching.
+	(AC_OUTPUT): Edit makefiles in script subdirectories too.
+
+	* scripts: Regroup function files in the following directories,
+	each with its own Makefile.in:
+
+           image           plot        signal          control
+	   linear-algebra  polynomial  special-matrix  general
+           miscellaneous   set         statistics
+
+	* src/help.cc (simple_help): Use kpathsea functions to find files
+	in path.
+	* src/utils.cc (get_fcn_file_names): Likewise.
+	(pathstring_to_vector): #if 0 out.
+
+Thu Sep  8 16:59:42 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/Makefile.in (OCTAVE_LIBS): Include ../libkpathsea.a.
+	* configure.in: Include configure stuff for kpathsea here too.
+	* Makefile.in (kpathsea): New target.
+	* src/utils.cc (file_in_path): Use kpathsea function instead of
+	doing our own searching.
+	* kpathsea/Makefile.in (lib): Define as ../libkpathsea.a, not just
+	kpathsea.a.
+
+Wed Sep  7 09:39:20 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/user-prefs.cc (check_str_pref): Fix comment.
+
+	* src/utils.cc (empty_arg): Check flag == 0, not is_empty > 0.
+
+	* src/f-fft2.cc (Ffft2): New file and function.
+	* src/f-ifft2.cc (Fifft2): Likewise.
+	* src/fft2.m, src/ifft2.m: Delete.
+
+	* src/f-fft.cc (Ffft): Handle second arg.  Depending on value of
+	propagate_empty_matrices, return empty matrix for empty arg.
+	* src/f-ifft.cc (Fifft): Likewise.
+
+	* liboctave/CMatrix.cc (fourier2d, ifourier2d): New functions.
+	* liboctave/dMatrix.cc (fourier2d, ifourier2d): New functions.
+
+	* src/tree-misc.cc (eval (int, int)): New function.
+	* src/octave.cc (eval_string, Feval): Handle multiple output args.
+
+	* src/error.cc (suppress_octave_error_messages): New global.
+	(error): Check it to see if messages should be printed.
+	* src/octave/cc (Feval): Set it if `catch' arg is supplied.
+
+	* src/octave.cc (Feval): Handle second `catch' arg.
+
+	* src/load-save.cc (read_mat_file_header): Init swap to zero.
+
+	* doc/octave.1: New simple man page.
+	* doc/Makefile.in: Distribute and install it.
+
+	* src/variables.cc (Fclear): Handle -x option for exclusive clear.
+
+Tue Sep  6 16:00:34 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/load-save.cc (save_mat_binary_data): New function.
+	(do_save): Handle LS_MAT_BINARY.
+	(Fsave): Handle -mat-binary.
+	(Changes from G. Beyerle <gbeyerle at AWI-Potsdam.DE>.)
+
+	* src/variables.cc (subs_octave_home, octave_arch_lib_dir):
+	New functions.
+	(octave_home, octave_info_dir, octave_lib_dir, default_path):
+	Fix for new directory organization.
+
+	* src/tree-expr.h (tree_multi_val_ret): New class to serve as a
+	base for objects that can produce more than one value when
+	evaluated.
+	(tree_fvc, tree_index_expression, tree_multi_assignment_expression):
+	Use it as a base. 
+
+	* src/parse.y (make_multi_val_re): New function.
+	(expression): Use it to construct multiple value assignments.
+
+	* configure.in, Makefile.in, Makeconf.in, src/defaults.h.in:
+	Revamp directory structure used for installed versions of Octave.
+
+	* src/f-schur.cc (Fschur): Correct argument count in error message.
+
+	* src/octave.cc (Fcomputer): New function.
+	* scripts/computer.in: Delete.
+	* scripts/Makefile.in: Don't edit or distribute computer.in.
+
+Thu Sep  1 09:02:06 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/variables.cc (install_builtin_variables): New builtin
+	variable, OCTAVE_VERSION.
+
+Tue Aug 30 17:18:14 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-expr.cc: Include string.h
+	(tree_matrix::eval): Fix handling of strings to work as in 1.0.
+
+Mon Aug 29 14:55:14 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/lex.l: Handle ".+" and ".-" too.
+
+	* src/dirfns.cc (dir_acess, exists, gen_tempname, tempnam): New
+	functions from glibc.
+	* src/utils.cc (octave_tmp_file_name): Use tempnam.
+	(choose_temp_base_try): Delete.
+	* configure.in: Check for tempnam.
+
+	* src/load-save.cc (Fsave): Only write floating point format if
+	doing binary save.
+
+	* liboctave/Array.cc (operator =): Check to see if assignment is
+	to same object.
+
+Sun Aug 28 23:32:59 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/CollocWt.cc (CollocWt::init): Call delete [] on vectors.
+	* liboctave/NPSOL.cc (NPSOL::minimize): Eliminate some memory leaks.
+	* liboctave/QPSOL.cc (QPSOL::minimize): Likewise.
+	* liboctave/NLEqn.cc (NLEqn::solve): Likewise.
+
+Thu Aug 25 09:27:04 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* info/session.c (info_get_input_char): Don't exit immediately if
+	we see EOF on the input stream.
+
+	* scripts/kurtosis.m, scripts/skewness.m: Update from KH.
+
+Wed Aug 24 00:19:49 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* dld/Makefile.in, scripts/Makefile.in, doc/Makefile.in,
+	readline/Makefile.in, info/Makefile.in, libcruft/Makefile.in,
+	liboctave/Makefile.in, src/Makefile.in (INSTALL, INSTALL_PROGRAM,
+	INSTALL_DATA): Define here.
+	* Makeconf.in: Not here.
+
+	* src/tree-plot.cc (send_to_plot_stream): Handle
+	user_pref.automatic_replot.
+	* src/variables.cc (install_builtin_variables):
+	Add DEFVAR for automatic_replot.
+	* src/user-prefs.cc (automatic_replot): New function.
+	* src/user-prefs.h (user_preferences): Add automatic_replot to the
+	list.
+
+	* src/data.cc (Fatan2): Make work for mixed scalar and Matrix args.
+	(map): New functions for two arg mappers (like atan2).
+
+	* src/f-fsqp.cc: Don't surround everything in FSQP_MISSING, so
+	that trying to use fsqp will result in a message about fsqp not
+	being freely redistributable.
+	* src/f-npsol.cc: Likewise, for NPSOL_MISSING.
+	* src/f-qpsol.cc: Likewise, for QPSOL_MISSING.
+
+Tue Aug 23 12:56:47 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-expr.cc (tree_identifier::eval): Don't call delete for
+	ans_id.  The destructor for tree_simple_assignment_expression does
+	this now.
+
+	* src/Makefile.in (%.def : %.cc): Use sed, not awk.
+	(realclean, distclean, local-dist, dist): Delete .d and .def files.
+
+	* liboctave/Array.h (DiagArray::Proxy): Make compilation
+	conditional on gcc version, not just _AIX.
+
+	* src/utils.cc (octave_tmp_file_name, choose_temp_base_try): New
+	functions, stolen from GCC.  If HAVE_MKTEMP is not defined, just
+	call tmpnam; otherwise, try harder to please.
+	* src/tree-plot.cc (save_in_tmp_file): Use it, instead of calling
+	tmpnam() directly.
+	* src/file-io.cc (do_scanf): Likewise.
+	* src/octave-hist.cc (mk_tmp_hist_file): Likewise.
+	* configure.in: Check for mktemp.
+
+	* src/tree-const.h (is_matrix_type, is_scalar_type): Make private.
+	* src/tc-rep.h (is_matrix_type, is_scalar_type): Likewise.
+
+	* src/tc-rep.h (force_numeric, make_numeric,
+	make_numeric_or_magic, make_numeric_or_range_or_magic): Make
+	private.
+	(make_numeric_or_range): #if 0 out.
+
+	* src/utils.cc (empty_arg): Correctly set return value.
+
+	* src/arith-ops.cc: Don't include setjmp.h.
+	* src/utils.cc: Surround setjmp.h with extern "C".
+	* src/octave.cc: Likewise.
+
+	* src/sighandlers.cc (octave_new_handler): New function.
+	(install_signal_handlers): Call it.
+
+	* src/f-qzval.cc (Fqzvalue): Don't call make_numeric for args.
+	Check error state after attempting to extract values.  Simplify
+	where possible.
+	* src/f-colloc.cc (Fcolloc): Likewise.
+	* src/f-rand.cc (Frand): Likewise.
+	* src/f-sort.cc (Fsort): Likewise.
+	* src/f-find.cc (Ffind): Likewise.
+	* src/f-minmax.cc (Fmin, Fmax): Likewise.
+	* src/f-fft.cc (Ffft): Likewise.
+	* src/f-ifft.cc (Fifft): Likewise.
+	* src/f-svd.cc (Fsvd): Likewise.
+	* src/f-inv.cc (Finv): Likewise.
+	* src/f-det.cc (Fdet): Likewise.
+	* src/f-eig.cc (Feig): Likewise.
+	* src/f-lu.cc (Flu): Likewise.
+	* src/f-hess.cc (Fhess): Likewise.
+	* src/f-qr.cc (Fqr): Likewise.
+	* src/f-givens.cc (Fgivens): Likewise.
+	* src/f-syl.cc (Fsyl): Likewise.
+	* src/f-log.cc (Flog): Likewise.
+	* src/f-expm.cc (Fexpm): Likewise.
+	* src/f-balance.cc (Fbalance): Likewise.
+	* src/f-schur.cc (Fschur): Likewise.
+	* src/f-chol.cc (Fchol): Likewise.
+	* src/f-npsol.cc (Fnpsol, npsol_options): Likewise.
+	* src/f-fsolve.cc (Ffsolve, fsolve_options): Likewise.
+	* src/f-dassl.cc (Fdassl, dassl_options): Likewise.
+	* src/f-lsode.cc (Flsode, lsode_options): Likewise.
+	* src/f-quad.cc (Fquad, quad_options): Likewise.
+	* src/tree-expr.cc (tree_matrix::eval): Likewise, while building
+	matrix.
+	(tree_colon_expression::eval): Likewise, for elements of range.
+	* src/variables.cc (is_valid_function, Fis_global, Fexist):
+	Likewise.
+	* src/sysdep.cc (Fgetenv, Fpause): Likewise.
+	* src/octave.cc (eval_string, Fshell_cmd): Likewise.
+	* src/input.cc (get_user_input): Likewise.
+	* src/file-io.cc (return_valid_file, fopen_file_for_user,
+	fgets_internal, fseek_internal, process_printf_format, do_printf,
+	do_scanf, fread_internal, fwrite_internal, feof_internal):
+	Likewise.
+
+	* src/tc-rep.cc (TC_REP::string_value): Call error() and return 0
+	instead of crashing if not string_constant.
+
+	* src/file-io.cc (fopen_file_for_user): Take string as first arg,
+	not tree_constant.  Change callers.
+	(fgets_internal, fseek_internal): Correct check for int arg.
+	(process_scanf_format): Use isspace instead of checking directly
+	(and incorrectly) for white space characters.
+
+	* src/tree-expr.cc (tree_matrix::eval, tree_unary_expression::eval,
+	tree_binary_expression::eval, tree_colon_expression::eval,
+	tree_simple_assignment_expression::eval ): Eliminate uneccesary
+	conversions to and from Octave_object/tree_constant.
+
+Mon Aug 22 18:35:05 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/data.cc (Fatan2): New function.
+
+	* src/data.cc (get_dimensions): Don't call make_numeric for args.
+	Check error state after attempting to extract values.
+
+Fri Aug 19 08:28:24 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-misc.h (tree_parameter_list::tree_parameter_list)):
+	Initialize marked_for_varargs to zero.
+
+	* src/load-save.cc: Add float variants of the conversion routines.
+	(LS_DO_READ): Add swap parameter and only swap bytes if it is true.
+	(read_doubles): Pass swap to LS_DO_READ.  Handle float data.
+	(LS_DO_WRITE): Copy data to tmp buffer to avoid destroying data.
+	(do_double_format_conversion): Rename from do_float_format_conversion.
+	(do_float_format_conversion): New function to handle conversion
+	for float data.
+	(read_mat_binary_data): Use read_doules for all cases.  Handle
+	float data.
+	(too_large_for_float): New function.
+	(save_binary_data): Save data format for scalars and ranges too.
+	(read_binary_data): Read data format for scalars and ranges too.
+	(do_save, save_vars): New arg, save_as_floats.
+	(Fsave): New option, -float-binary.
+
+	* src/utils.cc (empty_arg): New function.
+	* src/f-balance.cc (Fbalance): Use it to simplify handling of
+	empty arguments.
+	* src/f-chol.cc (Fchol): Likewise.
+	* src/f-det.cc (Fdet): Likewise.
+	* src/f-eig.cc (Feig): Likewise.
+	* src/f-expm.cc (Fexpm): Likewise.
+	* src/f-fft.cc (Ffft): Likewise.
+	* src/f-hess.cc (Fhess): Likewise.
+	* src/f-ifft.cc (Fifft): Likewise.
+	* src/f-inv.cc (Finv): Likewise.
+	* src/f-log.cc (Flogm, Fsqrtm): Likewise.
+	* src/f-lu.cc (Flu): Likewise.
+	* src/f-qr.cc (Fqr): Likewise.
+	* src/f-schur.cc (Fschur): Likewise.
+	* src/f-svd.cc (Fsvd): Likewise.
+
+	* src/tc-rep.cc (tupe_as_string): Move here.
+	* src/tree-const.cc: From here.
+
+	* src/gripes.cc (gripe_invalid_conversion): New function.
+
+Thu Aug 18 21:02:19 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/(print_empty_matrix): New function.
+	* src/pr-output.cc (octave_print_internal): Use it to print empty
+	matrices.
+	* src/tc-rep.cc (TC_REP::print_code, TC_REP::print): Rely on
+	octave_print_internal() to handle printing empty matrices.
+
+	* src/pr-output.cc (octave_print_internal (all variants)):
+	New arg, pr_as_read_syntax.  If nonzero, print the value in a form
+	that Octave can parse.	Declare os as ostream&, not ostrstream&.
+	* src/tc-rep.cc (TC_REP::print_code): Handle all types, not just
+	real and imaginary constants.
+	* src/help.cc (Ftype): Also print values of variables.
+
+Wed Aug 17 08:46:44 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/octave.cc (Fshell_cmd): Return output if nargout > 0 or
+	nargin > 2, otherwise, just send output to the pager.
+
+	* src/mappers.cc (xerf, xerfc, xgamma, xlgamma): New functions.
+	Put preprocessor conditionals here.
+	(install_mapper_functions): Not here.
+
+Tue Aug 16 09:55:25 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Check for erf, erfc, and lgamma.
+	* src/mappers.cc (erf, erfc, lgamma): New mappers.
+	* src/mappers.h (Mapper_fcn): Add new field `name'.
+	* src/variables.cc (install_builtin_mapper): Save the name.
+	* src/tc-rep.cc (TC_REP::mapper): Don't crash if a mapper function
+	is missing.
+
+	* src/tc-rep-1.cc (warn_invalid_conversion): New function.
+	* src/gripes.cc (gripe_invalid_conversion): New function.
+
+	* src/parse.y (list1, parse_error): New non-terminals.
+	(list): Use them.
+	* src/lex.l: Return LEXICAL_ERROR instead of calling
+	jump_to_top_level.
+
+	* liboctave/Range.cc (matrix_value): New function.
+	* src/tc-rep.cc (TC_REP::matrix_value): Use it.
+
+	* src/tree-const.h (to_matrix, to_vector, to_scalar): Delete
+	unecessary functions.
+	* src/tc-rep.cc (TC_REP::to_matrix, TC_REP::to_vector,
+	TC_REP::to_scalar): Likewise.  Change all callers to use
+	matrix_value, vector_value, and scalar_value instead. 
+
+	* src/tree-const.cc (TC_REP::matrix_value): If at all possible,
+	produce a matrix from the current constant.  Otherwise, print an
+	error message.  Don't abort or jump to the top level.
+	(TC_REP::scalar_value, TC_REP::complex_scalar_value,
+	TC_REP::vector_value, TC_REP::complex_vector_value,
+	TC_REP::complex_matrix_value): Likewise, for appropriate types.
+
+	* src/utils.cc (empty_arg): New function.
+	* src/f-svd.cc (Fsvd): Use it.	Don't call make_numeric; rely on
+	value functions to do conversion.
+
+	* src/load-save.cc (Fload): Handle -list and -verbose.
+
+Mon Aug 15 09:32:57 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-rep.cc (TC_REP): New define, so we don't have to write
+	tree_constant::tree_constant_rep:: everywhere.
+	* src/tree-const.h (class tree_constant): Nest tree_constant_rep
+	class inside tree_constant class by including tc-rep.h here.
+	* src/tc-rep.h: Don't include any other files, delete forward
+	class declarations.
+
+	* src/tc-rep.h (constant_type): Make private.
+
+	* src/parse.y (arg_list): Use tree_constant::magic_colon in
+	constructor call, not tree_constant_rep::magic_colon.
+	* src/tree-const.h (tree_constant::tree_constant
+	(tree_constant::magic_colon)): Convert arg from
+	tree_constant_rep::constant_type.
+
+	* src/f-svd.cc (Fsvd): Simplify.
+
+	* src/tree-expr.cc (any_arg_is_magic_colon): Don't use values from
+	tree_constant_rep::constant_type enum.
+	(tree_matrix::eval): Likewise.
+	* src/tree-misc.cc (tree_parameter_list::define_from_arg_vector,
+	tree_if_clause::eval):	Likewise.
+	* src/tree-cmd.cc (tree_while_command::eval,
+	tree_for_command::eval): Likewise.
+	* src/symtab.cc (symbol_record_info::symbol_record_info): Likewise.
+	* src/f-colloc.cc (Fcolloc): Likewise.
+	* src/f-npsol.cc (npsol_objective_function): Likewise.
+	* src/f-chol.cc (Fchol): Likewise.
+	* src/f-det.cc (Fdet): Likewise.
+	* src/f-eig.cc (Feig): Likewise.
+	* src/f-expm.cc (Fexpm): Likewise.
+	* src/f-fft.cc (Ffft): Likewise.
+	* src/f-find.cc (Ffind): Likewise.
+	* src/f-hess.cc (Fhess): Likewise.
+	* src/f-ifft.cc (Fifft): Likewise.
+	* src/f-inv.cc (Finv): Likewise.
+	* src/f-log.cc (Flog): Likewise.
+	* src/f-lu.cc (Flu): Likewise.
+	* src/f-minmax.cc (Fmin, Fmax): Likewise.
+	* src/f-qr.cc (Fqr): Likewise.
+	* src/f-rand.cc (rand): Likewise.
+	* src/f-schur.cc (schur): Likewise.
+	* src/f-sort.cc (Fsort): Likewise.
+	* src/f-svd.cc (Fsvd): Likewise.
+
+	* src/f-lu.cc (Flu): Handle case of nargout == 0 the same as
+	nargout == 1.
+
+	* src/tree-const.h (force_numeric): Don't return type info.
+	* src/tc-rep.cc (tree_matrix::eval): Ditto.
+	* src/tree-expr.cc (tree_matrix::eval): Don't use return value
+	from tree_constant::force_numeric().
+
+	* src/tree-const.h (is_magic_colon): New function.
+	* src/tc-rep.h (is_magic_colon): New function.
+
+	* src/load-save.cc (ascii_save_type): New function.
+	(save_binary_data, save_ascii_data, save_three_d): Don't use
+	values from tree_constant_rep::constant_type enum. Fail if write
+	is unsuccessful.  Fail but don't panic if type is unrecognized.
+	(save_vars): Check error state after call to do_save().
+
+	* src/tc-rep.cc (isstr): Delete, since we have is_string.
+	* src/tree-const.h (isstr): Ditto.
+	* src/data.cc (Fisstr): Use is_string(), not isstr().
+
+Sun Aug 14 16:12:10 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/load-save.cc (save_type): Add LS_U_INT, LS_CHAR and LS_FLOAT.
+	(get_save_type): Handle them.
+	(read_doubles, write_doubles): Likewise.
+
+	* src/load-save.cc (get_floating_point_format): New function.
+	(read_mat_binary_data, read_binary_file_header): Use it.
+
+	* src/lex.l: Combine {D}+\.{D}*{EXPON}?{Im} and {D}+{EXPON}?{Im}
+	patterns into the single pattern {D}+\.?{D}*{EXPON}?{Im}
+	Likewise, combine {D}+\.{D}*{EXPON}? and {D}+{EXPON}? into the
+	single pattern {D}+\.?{D}*{EXPON}?
+	({D}+/\.[\*/\\^']): New pattern to force expressions like `1./m'
+	to be parsed the same as `1 ./ m'.
+
+	* src/tree-expr.cc (do_lookup): Correctly set script_file_executed.
+
+	* src/octave.cc (long_opts): Add --silent as an alias for --quiet,
+	and --ignore-init-file as an alias for --norc.
+
+	* src/octave.cc (verbose_usage): Exit successfully to conform to
+	the GNU coding standards.
+
+Sat Aug 13 11:06:23 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/dirfns.cc (chdir): New alias for cd.
+
+	* src/lex.l (")"): Set convert_spaces_to_comma.
+
+	* src/*.cc: Use tree_constant::is_string(), not
+	tree_constant::is_string_type().
+
+	* src/f-balance.cc (Fbalance): Use is_string() rather than
+	checking const_type() against tree_constant_rep::string_constant.
+
+	* src/tc-rep.h (tree_constant_rep::is_string_type): Delete.
+	* src/tree-const.h (tree_constant::is_string_type): Delete.
+
+	* src/Makefile.in (%.def : %.cc): Complain if generated file is
+	empty.
+
+	* configure.in (gcc_version): Set LDFLAGS to -g, not "-g -O".
+
+	* src/lex.l (looks_like_bin_op): Also return true for things like
+	[ 1+ 2 ].
+
+	* src/data.cc (Feye, Fones): With no args, return 1.0.
+	(Fzeros): With no args, return 0.0.
+
+	* src/Makefile.in (XALL_CXXFLAGS): ALL_CXXFLAGS without
+	-fextternal-templates.
+	(%.def : %.cc): Use it instead of ALL_CXXFLAGS.
+
+	* configure.in: Don't use -O for compiling float-type.c.
+
+	* libcruft/misc/Makefile.in (XCC): Use patsubst to delete any -O#
+	flags, not just -O.
+
+Fri Aug 12 18:20:35 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	Changes for binary load/save, and reading .mat files:
+
+	* src/variables.cc (is_globally_visible): Declare extern, not
+	static.
+
+	* src/user-prefs.cc (sv_default_save_format): New function.
+	* src/user-prefs.h (default_save_format): New field in
+	user_preferences struct.
+	src/variables.cc (install_builtin_variables): Add DEFVAR for
+	default_save_format.
+
+	* src/tc-rep.h (tree_constant_rep::is_unknown,
+	tree_constant_rep::is_scalar, tree_constant_rep::is_matrix,
+	tree_constant_rep::is_complex_scalar,
+	tree_constant_rep::is_complex_matrix,
+	tree_constant_rep::is_string, tree_constant_rep::is_range):
+	New functions.
+
+	* src/tree-const.h (tree_constant::is_unknown,
+	tree_constant::is_scalar, tree_constant::is_matrix,
+	tree_constant::is_complex_scalar, tree_constant::is_complex_matrix,
+	tree_constant::is_string, tree_constant::is_range):
+	New functions.
+
+	* src/tc-rep.cc (tree_constant_rep::save,
+	tree_constant_rep::save_three_d): Move to load-save.cc and convert
+	to nonmember functions.
+
+	* src/tree-const.h (tree_constant::save,
+	tree_constant::save_three_d): Delete functions.
+
+	* src/tree-plot.cc (save_in_tmp_file): Call nonmember functions
+	save_ascii_file and save_three_d instead of tree_constant class
+	member functions.
+
+	* src/symtab.cc (symbol_table::glob): New function.
+	(symbol_table::save, symbol_record::save, symbol_def::save):
+	Delete unneeded functions.
+
+	* src/load-save.cc: New file, for load/save related functions
+	extracted from src/variables.cc and src/tc-rep.cc.
+
+	* src/error.cc (verror): Don't print name if it is null.
+
+Tue Aug  9 14:31:43 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/file-io.cc (process_printf_format): Use
+	tree_constant::is_scalar_type() and is_string_type() functions
+	instead of comparing directly with elements of the
+	tree_constant_rep::constant_type enum.
+	* src/variables.cc (builtin_real_scalar_variable): Likewise.
+	(install_loaded_variable): Likewise.
+
+	* src/tree-plot.cc (open_plot_stream): New function.
+	(send_to_plot_stream): Use it.  Do our own check for replot with
+	nothing to plot.
+	(tree_plot_command::eval): Open plot stream before doing anything.
+
+	* src/data.cc (check_dimensions): When changing negative
+	dimensions to zero, handle nr and nc separately.
+
+Mon Aug  8 20:18:17 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* variables.cc (is_valid_fcn): Use lookup_by_name() instead of
+	looking in the global symbol table directly.
+
+	* variables.cc (load_variable): Move code here.
+	* src/tc-rep.cc (tree_constant_rep::load): From here.
+	* src/tree-const.h (tree_constant::load): Delete.
+
+	* src/tree-plot.cc: Derive classes from tree_print_code and
+	implement print_code() member functions.
+
+	* src/tree-plot.cc (subplot_list::print): New function.
+	(tree_plot_command::print): Use it, and don't crash if plot_list
+	is null.
+
+	* scripts/axis.m: New function file.
+
+Sun Aug  7 17:06:16 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Check for size of short, int, and long.
+
+	* float-type.c: New file.
+	* configure.in: Use it to determine the native floating point
+	format.
+	* Makefile.in: Add it to the list of files to distribute.
+	* acconfig.h (IEEE_BIG_ENDIAN, IEEE_LITTLE_ENDIAN, VAX_D_FLOAT,
+	VAX_G_FLOAT): Add #undefs.
+
+Sat Aug  6 18:23:47 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* config.guess: Update with new copy from gcc 2.6.0.
+
+	* src/*.cc, src/*.h, src/*.l, src/*.y: Eliminate need for tree.h.
+	* src/Makefile.in (INCLUDES): Delete it from the list.
+
+	* src/token.cc (token::token (double)): Handle saving original
+	text of constants for later use by print_code() functions.
+	(token::~token): Delete original text.
+	(token::text_rep): New function.
+	* src/lex.l: Save original text for NUM and IMAG_NUM tokens.
+	* src/parse.y: Likewise.
+
+	* src/parse.y (yyerror): Use the pager.
+
+	* src/tree-base.h (tree_print_code): New base class for trees and
+	lists of trees.
+	(tree): Derive from tree_print_code.
+	* src/tree-base.cc: New file, for tree_print_code functions, and
+	for initializing tree_print_code static members.
+	* src/tree-const.cc, src/tc-rep.cc, src/tree-plot.cc,
+	src/tree-expr.cc, src/tree-cmd.cc (all tree classes):
+	Provide print_code() member function. 
+	* src/tree-misc.cc: Also derive list classes from tree-base.h and
+	provide print_code() member functions.
+
+	* src/help.cc (Ftype, Fwhich): New functions.
+
+	* src/octave-hist (do_history): Send history output through the
+	pager.
+
+	* src/variables.cc (do_who, Fwhos): New functions.
+
+	* src/tree-expr.h (tree_expression::in_parens): Declare here.
+	(tree_simple_assignment_expression::in_parens): Not here.
+	* src/parse.y (maybe_warn_assign_as_truth_value): Eliminate cast.
+
+	* src/variables.cc (load_fcn_from_file, lookup, lookup_by_name):
+	New functions, extracted from tree_identifier class.
+	(gobble_leading_whitespace, is_function_file, parse_fcn_file):
+	Move here from tree-expr.cc.
+	* src/help.cc (Fhelp): Use lookup_by_name so that looking up
+	symbols is handled in a consistent way.
+
+	* tree-expr.cc (tree_unary_expression::oper,
+	tree_binary_expression::oper, tree_prefix_expression::oper,
+	tree_postfix_expression::oper): New functions.
+
+	* tc-rep.cc (valid_scalar_indices): Define here.
+	* tc-inlines.cc: Not here.
+
+	* src/tree-const.h (tree_constant::stash_original_text): New
+	function.
+	* src/tc-rep.cc (tree_constant_rep::stash_original_text): Ditto.
+	(undo_string_escapes): Ditto.
+
+	* src/tc-rep (tree_constant_rep::do_matrix_index): Don't just
+	return *this.
+	* src/tree-const.h (tree_constant::tree_constant (tree_constant_re&)):
+	Delete.
+
+	* src/pager.cc (open_diary_file, close_diary_file,
+	maybe_write_to_diary_file, Fdiary): New functions.
+	(flush_output_to_pager): Call maybe_write_to_diary_file before
+	sending output to the screen.
+	* src/input.cc (octave_gets): Call maybe_write_to_diary file to
+	save the prompt and the user input.
+	* src/error.cc (verror): Use C++ streams, not C I/O functions.
+	Call maybe_write_to_diary file to save error messges too.
+	* src/octave.cc (clean_up_and_exit): Close diary file here.
+
+	* src/octave.cc (main): Initialize pager first.
+
+	* src/input.cc (get_user_input): Return empty matrix for no input.
+
+	* src/tree-plot.cc: Include readline/tilde.h instead of declaring
+	tilde_expand() directly.
+	* src/utils.cc: Likewise.
+
+	* src/tree-plot.cc (tree_plot_command::print_code): New function.
+	* src/tree-const.h (tree_constant::print_code): Likewise.
+
+	* src/tree-expr.h (tree_simple_assignment_expression::ans_ass):
+	New data member to flag assignments to ans.
+	* src/tree-expr.cc (tree_identifier::eval): Set it when
+	constructing assignments to ans.
+	* src/parse.y (maybe_convert_to_ans_assign): Likewise.
+
+	* src/tree-expr.h (tree_simple_assignment_expression::preserve):
+	New data member to allow preserving left hand side args that
+	shouldn't be deleted in some cases (ugh).
+	* src/tree-expr.cc (tree_multi_assignment_expression::eval):
+	Create assignment with preserve flag set.
+
+Wed Aug  3 14:27:25 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	Yet another massive reorganization of sources, once again
+	hopefully for the better.  A fair amount of work is not detailed
+	here, but these are the major points.  The grammar file and the
+	derivation of the tree classes are somewhat cleaner now.
+
+	* src/parse.y: Cope with changes to derivation scheme.
+
+	* src/tree-misc.cc: New file.
+	(tree_statement, tree_global): New classes.
+	(tree_global_init_list): New class, derived from SLList for the
+	list of expressions in a global command.
+	* src/tree-cmd.cc (tree_global_command): Use tree_global_init_list.
+
+	* src/tree-misc.cc (tree_argument_list): Move here from
+	tree-expr.cc, and derive from SLList instead of tree.
+	(tree_parameter_list): Likewise.
+	(tree_return_list): Likewise.
+
+	* src/tree-cmd.cc (tree_command_list): Delete class.
+	* src/tree-misc.cc (tree_statement_list): New class for keeping a
+	list of commands or expressions to evaluate.  Derive from SLList,
+	not tree.
+
+	* src/tree-plot.cc (subplot_list, plot_limits, plot_range,
+	subplot_using, subplot_style): Rename from tree_*, and
+	don't derive from tree class.
+
+	* src/tree-plot.cc: Eliminate eval member function for classes not
+	derived from tree class.
+
+	* src/tree-plot.cc, src/tree-cmd.cc: For classes derived from
+	tree-command, the eval() member function is now void eval (void).
+
+	* src/tree-base.h (tree::tree): New constructor, to initialize the
+	line and column info.  For all classes that are derived from the
+	tree class, use it instead of manipulating the data directly.
+	(line_num, column_num): Make private.
+
+	* src/tree-expr.cc (tree_simple_assignment_expression::preserve):
+	New data member, set in constructors and used by the destructor
+	when the left-hand side of the expression should not be deleted
+	(as for some temporary assignments not constructed in the parser).
+
+	* src/tree-expr.h (tree_expression::type) Rename and move here from
+	tree-base.h.  Change all uses.
+	(tree_matrix::dir): Likewise.  Change all uses.
+
+	* src/utils.cc (make_argv): Stash function name in argv[0].
+
+	* src/octave.cc (global_command): Declare as tree_statement_list,
+	not tree.
+
+	* src/parse.y (make_binary_op, make_unary_op, make_prefix_op,
+	make_postfix_op): New functions.
+
+	* src/parse.y (GLOBAL): Make it a tok_val type.
+	* src/lex.l (is_keyword): Give GLOBAL a value.
+
+Mon Aug  1 22:37:22 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/lex.l (grab_help_text): Unput the last character read.
+
+Sun Jul 31 21:17:07 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/pr-output.cc (set_format (double, int&)): Avoid calling
+	log10 for Inf and NaN.
+
+Fri Jul 29 16:08:32 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/octave.cc (reading_startup_message_printed): New flag.
+	(parse_and_execute): New arg, verbose.  If true, print name of
+	file as it is read.
+	(execute_startup_files): Don't print message if
+	inhibit_startup_message is true.
+	(main): Move startup message before reading init files.
+
+Thu Jul 28 00:25:42 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Makefile.in (MATRIX_INC): Delete CmplxColVec.h from list.
+
+	* src/symtab.cc (symbol_table::rename): New function.
+	* src/parse.y (func_def2): Use it instead of tree_identifier::rename.
+	* src/tree-expr.cc (tree_identifier::rename): Delete unused function.
+
+	* src/tree-expr.cc (tree_identifier::load_fcn_from_file): New function.
+	(tree_identifier::do_lookup): Use it instead of parse_fcn_file.
+	* src/variables.cc (is_valid_function): Ditto.
+	* src/help.cc (Fhelp): Ditto.
+
+	* src/utils.cc (oct_file_in_path): New function.
+
+Wed Jul 27 08:59:32 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-expr.cc (tree_identifier::parse_fcn_file): Combine
+	three functions into one.
+
+	* src/utils.cc: Delete uneeded declaration of ioctl().
+	* src/sysdep.cc: Likewise.
+
+	* install.sh: New file, from autoconf distribution.
+	* Makefile.in (DISTFILES): Distribute it.
+
+Tue Jul 26 16:08:58 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/Makefile.in (DISTDIRS): New variable, for directories
+	below scripts to distribute.
+	(dist): Handle distributing whole directories named by $(DISTDIRS).
+	(local-dist): Ditto.
+
+Mon Jul 25 12:57:09 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/CmplxQRP.cc: Provide declaration for zungqr.
+	* liboctave/dbleQRP.cc: Provide declaration for dorgqr.
+
+	* src/Makefile.in (dist): Also remove y.output and defaults.h.
+	(local-dist): Ditto.
+	(realclean): Ditto.
+
+	* src/oct-obj.h (Octave_object::Octave_object (int)): Make
+	private, to avoid problems with different meanings of
+	Octave_object (int) and Octave_object (double) constructors.
+
+	* scripts/amr-image: New files for image processing from Tony
+	Richardson.  These are not in the default octave LOADPATH yet.
+	See the README file in the amr-image directory for more info on
+	how to use them.
+
+	* src/octave.cc (Fshell_cmd): Restore accidentally deleted
+	function.
+
+	* scripts/conv-amr.m, scripts/deconv-amr.m, scripts/roots-amr.m,
+	scripts/poly-amr.m, scripts/roots-tuwien.m, scripts/conv-tuwien.m,
+	scripts/deconv-tuwien.m, scripts/poly-tuwien.m:
+	New files.
+	FIXME -- For each of these functions, either one of the
+	versions will need to be selected, or they will need to be merged
+	before the next release.
+
+	* scripts/null.m, scripts/orth.m, scripts/fft2.m, scripts/ifft2.m,
+	scripts/filter.m, scripts/compan.m, scripts/polyderiv.m,
+	scripts/polyinteg.m, scripts/polyreduce.m, scripts/polyval.m,
+	scripts/polyvalm.m, scripts/postpad.m, scripts/prepad.m,
+	scripts/residue.m, scripts/sinc.m, scripts/freqz.m,
+	scripts/complement.m, scripts/intersection.m,
+	scripts/create_set.m, scripts/union.m:
+	New files.
+
+	* scripts/hilb.m: Eliminate inner loop, for speed.  From
+	romolo at URSAMAJOR.ENG.UNIPR.IT (Romolo Manfredini).
+
+Sun Jul 24 22:08:48 1994  Castor Fu (castor at drizzle.stanford.edu)
+
+	* libcruft/ranlib/genf.f (genf): Use 1.2E-38 instead of 1.0E-38
+	when checking to see if generated numbers will cause overflow.
+	This helps DEC's f77 compiler on the Alpha, which refuses to
+	generate denormalized constants.
+	* libcruft/ranlib/gennf.f (gennf): Likewise.
+
+Fri Jul 22 10:27:00 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/Makefile.in (DEF_FILES): Depend on defun header files too.
+
+Thu Jul 21 14:40:30 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/NLFunc.h (nonlinear_fcn): Declare as pointer to
+	function taking const ColumnVector arg.
+	(jacobian_fcn): Ditto.
+
+	* src/defun-int.h (DEFINE_ARGV): Declare and define save_argc and
+	save_argv for functions that mess with argc and argv directly.
+	(DELETE_ARGV): Use save_argc and save_argv instead of argc and argv.
+
+	* src/f-lsode.cc (ODE_OPTIONS): Add const qualifier for string elts.
+	(print_lsode_option_list): Declare keyword as const char *.
+	* src/f-npsol.cc, src/f-qpsol.cc, src/f-dassl.cc, src/f-quad.cc:
+	Likewise, for corresponding structs and functions.
+
+	* liboctave/dbleSVD.h (SVD::type): New enum, for choosing type of
+	factorization.
+	* liboctave/CmplxSVD.cc (SVD::SVD): Add new optional arg for type.
+	(init): Handle case of type == SVD::economy.
+	* liboctave/dbleSVD.cc: Likewise.
+
+	QR changes from R. Bruce Tenison (btenison at eng.auburn.edu) adapted
+	for new way of defining builtin functions:
+
+	* doc/linalg.texi:  Changed QR description to include QRP
+	factorization
+
+	* src/f-qr.cc (Fqr): Handle permuted and economy QR
+	factorizations.  Handle case of 1 output arg.
+
+	* liboctave/Makefile.in (MATRIX_INC, MATRIX_SRC): Add new QRP files.
+
+	* liboctave/dbleQRP.h, liboctave/dbleQRP.cc, liboctave/CmplxQRP.h,
+	liboctave/CmplxQRP.h: New files, for QR with pivoting.
+
+	* liboctave/dbleQR.h (QR::type): New enum, for choosing type of
+	factorization.
+	* liboctave/CmplxQR.cc (QR): Add new optional arg for type.
+	Handle case of type == SVD::economy and SVD::raw.
+	* liboctave/dbleQR.cc (QR): Likewise.
+
+	* libcruft/lapack/dgeqpf.f: New file.
+	* libcruft/lapack/zgeqpf.f: Ditto.
+
+Wed Jul 20 13:12:55 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/*.cc, liboctave/*.h: Various cleanups to remove use of
+	NULL.  Only mention default argument values in function
+	declarations, not in their definitions (required for gcc 2.6.x).
+
+	* configure.in: If configuring for alpha-dec-osf, check for sgtty
+	first. If not found, go ahead and check for Posix terminal driver.
+
+Tue Jul 19 09:25:45 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/mx-defs.h (FILE): Don't declare as struct FILE just to
+	avoid including stdio.h.
+	* liboctave/dMatrix.cc: Do include stdio.h here.
+
+	* liboctave matrix classes: Declare operator>> correctly, and
+	return istream object.  Get friend stuff right.
+
+	* liboctave/DAE.cc (DAE::integrate): To see if the user provided a
+	Jacobian function, call DAEFunc::jacobian_function ().
+
+	* liboctave/DAE.cc (user_fun, user_jac): Qualify with class name.
+	* liboctave/ODE.cc (user_fun, user_jac): Ditto.
+
+	* liboctave/DAFunc.h (DAEJac): Declare inside class.
+	(DAERHSFunc, DAEJacFunc): Define types inside class.
+	* liboctave/ODEFunc.h (ODERHSFunc, ODEJacFunc) Likewise.
+
+	Massive reorganization of sources, hopefully for the better.
+	A fair amount of work is not detailed here, but these are the
+	major points...
+
+	* src/symtab.h (symbol_def::TYPE) Add new elements for recording
+	whether a symbol is a text function or mapper function.
+	* src/symtab.cc (symbol_def::is_text_function,
+	symbol_record::is_text_function, symbol_def::is_mapper_function,
+	symbol_record::is_mapper_function): New functions.
+	Modify existing is_* functions to cope with these changes.
+	(symbol_def::symbol_def (tree_builtin*, unsigned)): New 2nd arg.
+	(symbol_def::symbol_def (tree_function*, unsigned)): Ditto
+	(symbol_def::define (tree_builtin*, unsigned)): Ditto.
+	(symbol_def::define (tree_function*, unsigned)): Ditto.
+	* src/variables.cc (is_text_function_name): Use the new symbol
+	table functions, since we can no longer tell by looking in a
+	simple list.
+
+	* tree-expr.cc (class tree_builtin): Text functions are no longer
+	handled as a special case here.
+
+	* src/sysdep.cc (octave_ieee_init): Special case Alpha for
+	initializing Inf and NaN.
+
+	* src/tc-rep.cc: Use const in more places.
+
+	* src/data.cc src/timefns.cc, src/dirfns.cc, src/dirfns.h: New
+	files.
+
+	* src/*.cc, src/*.y, src/*.l, src/*.h: Various cleanups to remove
+	use of NULL.  Only mention default argument values in function
+	declarations, not in their definitions (required for gcc 2.6.x).
+
+	* src/g-builtins.cc, src/g-builtins.h, src/t-builtins.cc
+	src/t-builtins.h: Removed.  Functions moved to various other
+	files, where they more logically belong.
+	* src/utils.cc:  Likewise, various functions moved to other files,
+	where they more logically belong.
+	* src/mappers.cc (install_mapper_functions): Declare all mapper
+	functions here with the new DEFUN_MAPPER() macro.
+	* src/variables.cc (install_builtin_variables): Declare all
+	builtin variables here, with the new DEFVAR() macro.
+
+	* src/f-*.h: Deleted.
+	* src/f-*.cc: Delete #ifdef WITH_DLD code and use DEFUN_DLD()
+	instead to declare builtin functions that will be dynamically
+	loaded.  Give all functions a uniform return type and argument
+	list.
+
+	* src/mkdefs, src/mkbuiltins: New scripts.
+	* src/Makefile.in: Use them to generate builtins.cc automatically
+	from source files that use DEFUN.
+
+	* src/defun.h, src/defun-dld.h, src/defun-int.h: New files, to
+	define DEFUN() and DEFVAR() macros to make it possible to define
+	functions together with their help strings in one place.  The code
+	to install functions in the symbol table is now generated by
+	mkbuiltins.
+
+	* configure.in (LIBOCTDLD): New variable to define.
+	Only call AC_VERBOSE() for DYNAMIC_LD_OBJ, DLD_DIR, LIBDLD,
+	LIBOCTDLD, and LD_STATIC_FLAG if they are set.
+	* move-if-change: Move here, from src/move-if-change.
+	* Makeconf.in (%.d: %.cc): Echo simple message instead of the
+	commands actually executed.
+	(%.d: %.c): Likewise.
+
+	* src/unwind-prot.h: Include stddef.h, for size_t.
+
+Tue Jul 12 12:51:25 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/f-eval.cc, src/f-fill.cc, src/f-find.cc, src/f-input.cc,
+	src/f-minmax.cc, src/f-log.cc, src/f-sort.cc, src/f-eval.h,
+	src/f-fill.h, src/f-find.h, src/f-input.h, src/f-log.h,
+	src/f-minmax.h, src/f-sort.h: New files, for functions extracted
+	from tree-const.cc.
+	* src/Makefile.in: Add them to the list of INCLUDES, SOURCES, and
+	OBJECTS.
+
+	* src/f-*.cc: Clean up things a bit by letting the compiler
+	generate the tree_constant constructor calls.
+
+	* src/unwind-prot.h: Include stddef.h, for size_t.
+
+	* src/oct-obj.h (Octave_object (int, const tree_constant&)):
+	New constructor form.
+	* src/tree-const.cc (find_nonzero_elem_idx): Rewrite to handle 2
+	and 3 return values.
+
+	* src/g-builtins.cc (builtin_find): Check nargout too.
+	* src/builtins.cc (general_functions): Fix help message for find.
+
+Mon Jul 11 13:36:15 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-rep.cc	(tree_constant_rep::convert_to_row_or_column_vector):
+	If already have a row or column vector, return without doing
+	anything.
+
+Sat Jul  9 01:02:51 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/oct-obj.h (Octave_object): Make it a class, not just a
+	typedef.
+
+	* src/tree-expr.h (tree_function::curr_va_arg_number): Rename from
+	curr_arg_number.
+	(tree_function::varargs_ok): Delete unused member variable.
+	* src/tree-expr.cc (tree_function::octave_va_arg): Increment
+	cur_va_arg_number before indexing args_passed.
+	(tree_function::octave_va_start): Set curr_va_arg_number to
+	num_args_passed, not num_args_passed + 1.
+	(tree_function::takes_varargs): Call param_list::takes_varargs,
+	don't just return varargs_ok.
+	(tree_function::define_param_list): If param_list is not NULL, set
+	num_named_args and curr_va_arg_number even if function doesn't
+	take varargs.
+
+	* src/tree-expr.cc (tree_identifier::eval (int)): Only pass empty
+	arg list if evaluating a constant.
+	(tree_function::eval (int)): Always pass least one arg.
+
+	* Makeconf.in (TMP_IF_1): Add `-I../src'.
+	(TMP_IF_2): Add `-I$(TOPDIR)/src' and `-I$(top_srcdir)/src'.
+
+	* src/t-builtins.h, src/variables.h, src/file-io.h, src/f-syl.h,
+	src/f-svd.h, src/f-schur.h, src/f-rand.h, src/f-qzval.h,
+	src/f-quad.h, src/f-qpsol.h, src/f-npsol.h, src/f-lsode.h,
+	src/f-lpsolve.h, src/f-hess.h, src/f-givens.h, src/f-fsqp.h,
+	src/f-fsolve.h, src/f-eig.h, src/f-dassl.h, src/f-colloc.h,
+	src/f-balance.h, src/dynamic-ld.h, src/builtins.cc,
+	src/tree-const.cc, src/file-io.cc, src/f-syl.cc, src/f-svd.cc,
+	src/f-schur.cc, src/f-rand.cc, src/f-qzval.cc, src/f-qr.cc,
+	src/f-qpsol.cc, src/f-lu.cc, src/f-lpsolve.cc, src/f-inv.cc,
+	src/f-ifft.cc, src/f-hess.cc, src/f-givens.cc, src/f-fsqp.cc,
+	src/f-fft.cc, src/f-expm.cc, src/f-eig.cc, src/f-det.cc,
+	src/f-colloc.cc, src/f-chol.cc, src/f-balance.cc,
+	src/dynamic-ld.cc, src/f-dassl.cc, src/f-fsolve.cc,
+	src/f-lsode.cc, src/f-npsol.cc, src/f-quad.cc, src/tree-expr.h,
+	src/tc-rep.cc, src/tc-inlines.cc, src/tc-rep.h, src/tree-const.h,
+	src/g-builtins.cc, src/g-builtins.h, src/tree-expr.cc,
+	src/variables.cc: Delete nargin in favor of using args.length().
+
+	* configure.in: Check for struct exception in math.h.
+	* src/sysdep.cc (matherr): New function.
+
+Fri Jul  8 15:31:53 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-rep.cc: Include arith-ops.h.
+	(tree_constant_rep::do_scalar_index): Use `invalid', not `illegal'
+	in messages.
+
+	* src/oct-obj.h: Protect contents from multiple inclusion.
+
+	* src/tree-const.h, src/tree-expr.h: Don't include Array.h.
+
+	* src/parse.y (param_list): Allow ELLIPSIS by itself.
+	* src/tree-expr.cc (tree_identifier::mark_varargs_only,
+	tree_identifier::vararg_only): New functions.
+	(tree_function::eval): Only call define_from_arg_vector if
+	param_list is non-null and not marked as varargs_only.
+
+	* src/f-balance.h, src/f-chol.h, src/f-colloc.h, src/f-dassl.h,
+	src/f-eig.h, src/f-fsolve.h, src/f-fsqp.h, src/f-givens.h,
+	src/f-hess.h, src/f-lpsolve.h, src/f-lsode.h, src/f-lu.h,
+	src/f-npsol.h, src/f-qpsol.h, src/f-qr.h, src/f-quad.h,
+	src/f-qzval.h, src/f-rand.h, src/f-schur.h, src/f-svd.h,
+	src/f-syl.h: Include oct-obj.h, not tree-const.h to get
+	declaration of Octave_object.
+
+	* src/f-givens.cc (givens): Handle case of nargout == 0.
+	Use `invalid', not `illegal' in messages.
+	* src/f-balance.cc (balance): Likewise.
+
+	* src/f-balance.cc (balance): Print warning about two output
+	arguments for complex-valued case too.
+
+	* src/tc-rep.cc: Include arith-ops.h.
+
+Thu Jul  7 20:54:12 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/parse.y (identifier): Add missing semicolon.
+	(param_list): Ditto.
+
+	* src/f-svd.cc (svd): Handle nargout == 0 the same as nargout == 1.
+	* src/f-schur.cc (schur): Likewise.
+	* src/f-hess.cc (hess): Likewise.
+	* src/f-eig.cc (eig): Likewise.
+	* src/f-syl.cc (syl): Likewise.
+	* src/f-qzval.cc (qzvalue): Likewise.
+	* src/f-npsol.cc (npsol): Likewise.
+	* src/f-qpsol.cc (qpsol): Likewise.
+	* src/f-givens.cc (givens): Likewise.
+	* src/f-fsolve.cc (fsolve): Likewise.
+	* src/f-balance.cc (balance): Likewise.
+	* src/file-io.cc (process_scanf_format): Likewise.
+	* src/g-builtins.cc (builtin_balance, builtin_chol, builtin_dassl,
+	builtin_eig, builtin_fsolve, builtin_fsqp, builtin_lsode,
+	builtin_max, builtin_min, builtin_npsol, builtin_qpsol,
+	builtin_quad, builtin_rand, builtin_size, builtin_sort,
+	builtin_svd, builtin_schur, builtin_syl, builtin_givens,
+	builtin_hess): Likewise.
+	* src/tree-const.cc (vector_of_empties, column_max, column_min):
+	Likewise.
+
+	* src/variables.h, src/symtab.h: Include builtins.h for typedefs.
+
+	* src/tree-expr.cc(tree_multi_assignment_expression::eval): Rework
+	handling of undefined values returned from functions.
+
+	* src/tree-expr.cc (tree_identifier::is_defined): New function.
+	(tree_parameter_list::is_defined): New function.
+	(tree_parameter_list::convert_to_const_vector): Use it to avoid
+	evaluating undefined objects.
+
+	* src/f-balance.cc, src/f-eig.h, src/f-hess.cc, src/f-lu.h,
+	src/f-rand.cc, src/f-balance.h, src/f-expm.cc, src/f-hess.h,
+	src/f-npsol.cc, src/f-rand.h, src/f-chol.cc, src/f-expm.h,
+	src/f-ifft.cc, src/f-npsol.h, src/f-schur.cc, src/f-chol.h,
+	src/f-fft.cc, src/f-ifft.h, src/f-qpsol.cc, src/f-schur.h,
+	src/f-colloc.cc, src/f-fft.h, src/f-inv.cc, src/f-qpsol.h,
+	src/f-svd.cc, src/f-colloc.h, src/f-fsolve.cc, src/f-inv.h,
+	src/f-qr.cc, src/f-svd.h, src/f-dassl.cc, src/f-fsolve.h,
+	src/f-lpsolve.cc, src/f-qr.h, src/f-syl.cc, src/f-dassl.h,
+	src/f-fsqp.cc, src/f-lpsolve.h, src/f-quad.cc, src/f-syl.h,
+	src/f-det.cc, src/f-fsqp.h, src/f-lsode.cc, src/f-quad.h,
+	src/f-det.h, src/f-givens.cc, src/f-lsode.h, src/f-qzval.cc,
+	src/f-eig.cc, src/f-givens.h, src/f-lu.cc, src/f-qzval.h,
+	src/dynamic-ld.cc, src/dynamic-ld.h, src/file-io.cc,
+	src/file-io.h, src/t-biultins.cc, src/t-builtins.h,
+	src/tree-expr.cc, src/tree-expr.h, src/tree-const.cc,
+	src/tree-const.h, src/tc-inlines.cc, src/tc-rep.cc, src/tc-rep.h,
+	src/g-builtins.cc, src/g-builtins.h:
+	Cope with inital round of Octave_object changes.
+
+	* src/oct-obj.h: New file for Octave_object typedef.
+	* src/dynamic-ld.h, src/file-io.h, src/tree-const.h,
+	src/tree-expr.h: Include it.
+	* src/Makefile.in (INCLUDES): Add it to the list.
+
+Wed Jul  6 09:28:28 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* libocsrc/tree-const.h: 
+
+	* src/parse.y (maybe_convert_to_ans_assign,
+	maybe_warn_assign_as_truth_value): Pass tree_expression*, not tree*.
+	(ans_expression, expression, simple_expr, simple_expr1, title):
+	Declare as tree_expression_type, not tree_type.
+	(opt_list): Add missing semicolon.
+
+	* src/tc-rep.h, src/tc-rep.cc: New files, extracted from
+	tree-const.h and tree-const.cc, for the tree_constant_rep class.
+	Leave most friend functions behind, in tree-const.h.
+	Don't declare do_binary_op or do_unary_op as friends.
+
+	* src/lex.l: Include tree-plot.h and tree-const.h.
+
+	* src/variables.cc (takes_correct_nargs): Pass tree_fvc* not tree*.
+	* src/variables.cc (is_valid_function): Return tree_fvc* not tree*.
+	Change all callers.
+
+	* src/symtab.h, symtab.cc: Change declaration of symbol definition to
+	be tree_fvc* instead of tree*.  Change all callers.
+
+	* src/f-dassl.cc (dassl_fcn): Declare as tree_fvc*, not tree*.
+	* src/f-quad.cc (quad_fcn): Likewise.
+	* src/f-lsode.cc (lsode_fcn): Likewise.
+	* src/f-fsolve.cc (fsolve_fcn): Likewise.
+	* src/f-npsol.cc (npsol_fcn, npsol_constraints): Likewise.
+
+	* src/tree-plot.cc: All operations are now on tree_expression types,
+	not tree types.
+
+	* src/tree-expr.h (tree_matrix): Derive from tree_expression, not tree.
+
+	* src/tree-expr.h (tree_builtin, tree_function, tree_identifier):
+	Derive from tree_fvc, not tree.	
+	* src/tree-const.h (class tree_constant): Likewise.
+
+	* src/tree-expr.h (is_identifier, is_index_expression,
+	is_assignment_expression, is_prefix_expression,
+	mark_for_possible_ans_assign, eval (with args)): Declare in
+	tree_expression class, not tree class.
+
+	* src/tree-expr.h (tree_fvc): New class, derived from
+	tree_expression, to provide a connection between functions,
+	variables, and constants.
+	(is_constant, assign, name, bump_value, max_expected_args,
+	fcn_file_name, time_parsed, is_system_fcn_file, save): Declare
+	in tree_fvc class, not in tree class.
+
+	* src/tree.h: Simply include tree-expr.h and tree-cmd.h.
+	* src/tree-expr.h, tree-expr.cc: New files, extracted from tree.h
+	and tree.cc for classes derived from tree_expression, plus some
+	helper classes.
+	* src/tree-cmd.h, tree-cmd.cc: Likewise, for classes derived from
+	tree_command.
+
+	* src/tree.cc (eval (int, int)): Merge with eval (int,
+	tree_constant*, int, int) by rearranging order of args and using
+	default arg values.  Change all callers.	
+
+Tue Jul  5 14:33:33 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/Makefile.in (refcard.dvi): Run TeX on $(srcdir)/refcard.tex,
+	not just refcard.tex.
+	(refcard-local.tex): Likewise, for the local version.
+
+	* src/tree-const.cc (tree_constant_rep::do_index): Check for empty
+	matrix here.
+	(tree_constant_rep::do_vector_index) Not here.
+
+Thu Jun 30 09:41:03 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/g-builtins.cc (builtin_shell_command): Only take one
+	argument and return [status, output].
+	* src/procstream.cc (procstreambase::close): Return process exit
+	status.
+
+	* src/tree.cc (tree_builtin::eval (int)): Handle new style of
+	calling text functions.
+	(tree_builtin::eval (int, int): Likewise.
+	(tree_builtin::eval (tree_constant*, int, int, int): Likewise.
+	(tree_identifier::eval (tree_constant*, int, int, int)): Don't
+	count the output arguments that we create automatically (ans) when
+	figuring nargout.
+	(tree_identifier::eval (int)): Likewise.
+
+	* src/tree-const.cc: Delete text-style eval() functions.
+	* src/tree.cc: Ditto.
+
+	* src/tree-const.h: Change typedef of Text_fcn to return a pointer
+	to a tree_constant, and to include the number of output arguments
+	in the parameter list.
+	* src/t-builtins.h: Change declarations of all builtin text-style
+	functions to match.
+	* src/t-builtins.cc: Change definitions too.
+
+	* src/parse.y (word_list): Build an argument_list, not a word_list.
+	(word_list_command): Create an index_expression, not a
+	word_list_command.
+	* src/tree.cc (tree_word_list): Delete unneeded class.
+	(tree_word_list_command): Likewise.
+
+	* src/tc-extras.cc (get_dimensions): For one-arg version, expect
+	2-element vector or scalar specifying dimensions.  Don't simply
+	use the dimensions of a matrix arg.
+
+Wed Jun 29 09:52:15 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/f-det.cc (determinant): Return 0 if matrix is singular to
+	machine precision.
+
+	* liboctave/dMatrix.cc (Matrix::inverse): Declare rcond as
+	volatile to prevent optimization of the expression
+	`rcond + 1.0 == 1.0'.
+	(Matrix::determinant): Ditto.
+	(Matrix::solve): Ditto.
+	* liboctave/CMatrix.cc (ComplexMatrix::inverse): Ditto.
+	(ComplexMatrix::determinant): Ditto.
+	(ComplexMatrix::solve): Ditto.
+
+Tue Jun 28 10:53:31 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/utils.cc (default_info_file): Add directory separator when
+	appending "octave.info".
+
+	* src/tree-plot.cc (plot_line_count): Make global.
+	* src/utils.cc (send_to_plot_stream): If the plot stream is not
+	open, set plot_line_count to zero.
+	(close_plot_stream): Likewise, set it to zero when closing the
+	stream.
+
+	* src/parse.y (plot_command): Allow replot without args.
+
+	* src/tree-plot.cc (clear_before_plotting): New global variable.
+	(tree_plot_command::eval): Use it to handle hold on/off.
+	* src/t-builtins.cc (builtin_hold): New function.
+	* src/builtins.cc (text_functions): Add it to the list.
+
+Fri Jun 24 11:08:36 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/token.h (plot_tok_type): Add new field, replot.
+	* src/lex.l (is_keyword): Handle replot here.
+	* src/parse.y (plot_command): And here.
+	* src/g-builtins.cc (builtin_replot): Not here.
+	* src/builtins.cc (general_functions): Or here.
+
+Tue Jun 21 10:47:08 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/g-builtins.cc (builtin_kbhit): New function.
+	* src/builtins.cc (general_functions): Add it to the list.
+
+	* src/tree-const.cc (tree_constant_rep::rows (void)): For strings
+	and ranges, only return 1 if the string or range is not empty.
+
+Thu Jun  9 20:42:06 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (tree_builtin::eval (int)): Delete ancient code that
+	eval()'d the return value.
+	(tree_builtin::eval (int, int)): Likewise.
+	(tree_builtin::eval (int, char**, int)): Likewise.
+	(tree_builtin::eval (tree_constant*, int, int, int)): Likewise.
+	(tree_function::eval (tree_constant*, int, int, int)): Likewise.
+	(tree_colon_expression::eval (int)): Likewise.
+	(tree_unary_expression::eval (int)): Likewise.
+	(tree_binary_expression::eval (int)): Likewise.
+
+Mon Jun  6 03:48:32 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/file-io.cc (fread_internal): Make it work.
+	(fwrite_internal): Likewise.
+	(num_items_remaining): Renamed from get_whats_left().  Don't pass
+	nr/nc as last arg, simply return the number of items of size that
+	are left to read.
+	(get_size_conv): Delete unnecessary function.
+	* liboctave/dMatrix.cc (Matrix::read): Make it work.
+	(Matrix::write): Likewise.
+	* liboctave/dMatrix.h (conversion): Delete unecessary enum.
+
+	* src/sysdep.cc: Include <math.h>.
+	(octave_ieee_init): Cast return value of infinity() and
+	quiet_nan() to double.
+
+Sun Jun  5 14:35:32 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makeconf.in (getversion): Get everything between the double
+	quotes, not just numbers and periods.
+
+	* src/tree-const.cc (tree_constant_rep::do_scalar_assignment): Correct
+	typo in last change.
+
+	* src/parse.y: Include tree-plot.h and tree-const.h.
+
+	* src/Makefile.in (SOURCES): Delete tc-assign.cc and tc-index.cc
+	(INCLUDES): Add tree-plot.h.
+
+	* src/tree-plot.h: New file.  Declare plotting classes here.
+	* src/tree.h: Not here.
+
+	* src/tc-index.cc, tc-assign.cc: Delete unnecessary files.
+
+	* src/tc-extras.cc: Include EIG.h
+
+	* src/tree-const.cc (tree_constant_rep::tree_constant_rep (RowVector&,
+	int)): Provide default value for int arg.
+	(tree_constant_rep::tree_constant_rep (ColumnwVector&, int)): Ditto
+	(tree_constant_rep::tree_constant_rep (ComplexRowVector&, int)): Ditto
+	(tree_constant_rep::tree_constant_rep (ComplexColumnwVector&, int)):
+	Ditto.
+	(tree_constant_rep::tree_constant_rep (RowVector&)): Delete, now
+	handled by corresponding two arg constructor.
+	(tree_constant_rep::tree_constant_rep (ColumnwVector&)): Likewise.
+	(tree_constant_rep::tree_constant_rep (ComplexRowVector&)): Likewise.
+	(tree_constant_rep::tree_constant_rep (ComplexColumnwVector&)):
+	Likewise.
+
+	* src/tree-const.cc: Add pragma implementation.  Merge in contents of
+	tc-index.cc and tc-assign.cc so that the pragma interface/pragma
+	implementation hack will do some good.
+	* src/tree-const.h: Include mx-base.h, not Matrix.h.  Add pragma
+	interface.  Delete unnecessary constructor declarations.
+
+	* src/unwind-prot.h, src/unwind-prot.cc (unwind_elem_tag): Rename
+	from _tag.
+	(unwind_elem_fptr): Rename from _fptr.
+	(unwind_elem_ptr): Rename from _ptr.
+
+	* NLConst.cc (NLConst::NLConst): Pass vector args by reference.
+
+	* src/procstream.h, src/procstream.cc, src/idx-vector.h,
+	src/idx-vector.cc, src/token.h, src/token.cc, src/unwind-prot.h,
+	src/unwind-prot.cc, src/symtab.h, src/symtab.cc, src/tree.h,
+	src/tree.cc, liboctave/Range.h, liboctave/Range.cc,
+	liboctave/QLD.h, liboctave/QLD.cc, liboctave/ODE.h,
+	liboctave/ODE.cc, liboctave/Quad.h, liboctave/Quad.cc,
+	liboctave/Objective.h, liboctave/Objective.cc, liboctave/NPSOL.h,
+	liboctave/NPSOl.cc, liboctave/NLFunc.h, liboctave/NLFunc.cc,
+	liboctave/Bounds.h, liboctave/Bounds.cc, liboctave/QP.h,
+	liboctave/QP.cc, liboctave/NLConst.cc, liboctave/LinConst.cc,
+	liboctave/LPsolve.cc, liboctave/LP.cc, liboctave/FSQP.cc,
+	liboctave/FEGrid.cc, liboctave/QPSOL.cc, liboctave/CollocWt.cc,
+	liboctave/DAEFunc.cc, liboctave/DAEFunc.h, liboctave/DAE.cc,
+	liboctave/NLEqn.cc, liboctave/ODEFunc.cc, liboctave/QPSOL.h,
+	liboctave/ODEFunc.h, liboctave/NLP.h, liboctave/NLEqn.h,
+	liboctave/NLConst.h, liboctave/LinConst.h, liboctave/LPsolve.h,
+	liboctave/LP.h, liboctave/FSQP.h, liboctave/FEGrid.h,
+	liboctave/DAE.h, liboctave/CollocWt.h:
+	Add pragma interface/implementation.
+
+	* src/f-svd.cc, src/f-schur.cc, src/f-qr.cc, src/f-lu.cc,
+	src/f-hess.cc, src/f-det.cc, src/f-chol.cc, src/f-qzval.cc,
+	src/f-inv.cc, src/f-ifft.cc, src/f-givens.cc, src/f-fft.cc, 
+	src/f-balance.cc, src/f-expm.cc, src/f-fsqp.cc, src/f-syl.cc,
+	src/xdiv.cc, src/xpow.cc, src/idx-vector.cc, src/pr-output.cc,
+	src/unwind-prot.cc, src/file-io.cc, liboctave/Bounds.h,
+	liboctave/CollocWt.h, liboctave/DAE.h, liboctave/EIG.h,
+	liboctave/FEGrid.h, liboctave/LP.h, liboctave/LPsolve.cc,
+	liboctave/LinConst.h, liboctave/NLEqn.cc, liboctave/NLEqn.h,
+	liboctave/NLP.h, liboctave/NPSOL.cc, liboctave/NPSOL.h,
+	liboctave/ODE.h, liboctave/Objective.h, liboctave/QLD.cc,
+	liboctave/QP.h, liboctave/QPSOL.h, liboctave/Quad.h:
+	Instead of including Matrix.h, only include the individual
+	matrix/vector/etc. header files that are needed.
+
+	* liboctave/QLD.cc, liboctave/ODE.cc, liboctave/NLFunc.cc,
+	liboctave/DAEFunc.cc, liboctave/DAE.cc, liboctave/NLEqn.cc,
+	liboctave/ODEFunc.cc:
+	Use 0, not NULL.
+
+	* liboctave/mx-inlines.cc: Include Complex.h.
+
+	* liboctave/mx-kludge.h: Don't enclose contents in extern "C++".
+
+	* liboctave/Matrix.h: Simply include mx-base.h and mx-ext.h.
+
+	* liboctave/mx-base.h: New file, includes all basic matrix/vector
+	header files.
+	* liboctave/mx-ext.h: New file, includes all extra matrix/vector
+	related header files.
+	* liboctave/mx-defs.h: New file, for matrix/vector related
+	defines.  Also provides forward declarations for all matrix/vector
+	classes.
+
+	* liboctave/Makefile.in: Cope with new files.
+
+	* liboctave/CmplxAEPBAL.cc, liboctave/CmplxDET.h,
+	liboctave/CmplxQR.cc, liboctave/CmplxSVD.h, liboctave/dbleDET.cc,
+	liboctave/dbleHESS.h, liboctave/dbleSCHUR.cc,
+	liboctave/CmplxAEPBAL.h, liboctave/CmplxHESS.cc,
+	liboctave/CmplxQR.h, liboctave/dbleAEPBAL.cc, liboctave/dbleDET.h,
+	liboctave/dbleLU.cc, liboctave/dbleSCHUR.h,
+	liboctave/CmplxCHOL.cc, liboctave/CmplxHESS.h,
+	liboctave/CmplxSCHUR.cc, liboctave/dbleAEPBAL.h,
+	liboctave/dbleGEPBAL.cc, liboctave/dbleLU.h, liboctave/dbleSVD.cc,
+	liboctave/CmplxCHOL.h, liboctave/CmplxLU.cc,
+	liboctave/CmplxSCHUR.h, liboctave/dbleCHOL.cc
+	liboctave/dbleGEPBAL.h, liboctave/dbleQR.cc, liboctave/dbleSVD.h,
+	liboctave/CmplxDET.cc, liboctave/CmplxLU.h, liboctave/CmplxSVD.cc,
+	liboctave/dbleCHOL.h, liboctave/dbleHESS.cc, liboctave/dbleQR.h,
+	liboctave/EIG.h, liboctave/EIG.cc:
+	New files, extracted from Matrix-ext.cc, in an attempt to allow
+	effective use of pragma interface/implementation and make
+	generated code somewhat smaller.
+	* liboctave/dColVector.cc liboctave/CColVector.cc: Likewise, from
+	ColVector.{cc,h}.
+	* liboctave/dRowVector.cc liboctave/CRowVector.cc: Likewise, from
+	RowVector.{cc,h}.
+	* liboctave/dMatrix.cc liboctave/CMatrix.cc: Likewise, from
+	Matrix.{cc,h}.
+	* liboctave/dDiagMatrix.cc liboctave/CDiagMatrix.cc: Likewise,
+	from DiagMatrix.{cc,h}.
+
+Fri Jun  3 15:32:53 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Array.h: Include assert.h.
+	(DiagArray<T>::operator T ()): [! _AIX] Only call get() if i is
+	also equal to j.
+
+	* scripts/rem.m: Allow mixing of scalar/matrix args, but complain
+	if both args are matrices and the dimensions don't agree.
+
+	* src/lex.l (grab_help_text): Correct previous change.
+
+Thu Jun  2 12:08:18 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.h (conversion): New enum, for binary read/write
+	functions.
+	* Matrix.cc (read, write) New functions.
+	* file-io.cc (feof_internal, ferror_internal, fread_internal,
+	fwrite_internal, get_size_conv, get_whats_left): New functions.
+	* g-builtins.cc (builtin_feof, builtin_ferror, builtin_fread,
+	builtin_fwrite): New functions.
+	* builtins.cc (general_functions): Add them to the list.
+
+	* configure.in: Check for infinity() and quiet_nan().
+	* sysdep.h (octave_Inf, octave_NaN): New global variables.
+	* sysdep.cc (octave_ieee_init): New function.  Initialize
+	octave_Inf and octave_NaN.
+	(sysdep_init): Call it.
+	* builtins.cc (initialize_builtins): Don't compute Inf and NaN
+	values here.
+	
+Tue May 31 20:06:27 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/variables.cc (identifier_exists): Only return 1 for
+	variables if they are also defined.
+
+Sun May 29 20:40:55 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/lex.l: Don't declare beginning_of_function as static.
+	(COMMENT): Delete unnecessary exclusive start state.
+	(\#, \%): Handle comments directly.  Try to be smart about not
+	returning a newline character when reading a matrix list.
+	(grab_help_text): Don't put a newline back on the input stream.
+	* src/parse.y (list1): Set beginning_of_function to zero here.
+
+Wed May 25 03:34:17 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/error.cc (error): If error_state is -2, don't do anything.
+	If the format string ends in a new line character, strip it, print
+	the error message, and set the error state to -2.
+	* src/tree.cc (tree_function::traceback_error): Don't set the
+	error_state if it is already negative.
+
+	* src/tree-const.cc (convert_to_row_or_column_vector): New function.
+	* src/idx-vector.cc (idx_vector::shorten): New function.
+	* src/tc-assign.cc (fortran_style_matrix_assignment
+	(tree_constant&, tree_constant&)): Handle deleting elements by
+	assignment of `[]'.  Use convert_to_row_or_column_vector to handle
+	conversion to a vector in the case of deleting some elements from
+	a matrix.  Use idx_vector::shorten() to remove unnecessary index
+	vector elements.
+	(do_scalar_assignment (tree_constant&, tree_constant*, int)):
+	Handle assignment of empty matrix.
+	If converting complex to real, delete old complex value.
+	(delete_rows (idx_vector&)): If deleting all rows of a column
+	vector, convert to empty matrix.
+	(delete_rows (Range&)): Ditto.
+	(delete_columns (idx_vector&)): If deleting all columns of a row
+	vector, convert to empty matrix.
+	(delete_columns (Range&)): Ditto.
+
+	* src/tc-extras.cc (column_max (tree_constant*, int, int)):
+	Use MAX, not MIN when trying to find the biggest scalar.
+	Likewise, find the complex scalar with the largest, not the
+	smallest absolute value.
+
+	* src/tc-assign.cc (do_matrix_assignment (tree_constant&,
+	tree_constant_rep::constant_type, tree_constant&): For case of
+	j_arg == matrix constant, don't negate return value of
+	indexed_assign_conforms().
+
+	* src/user-prefs.cc (commas_in_literal_matrix): New function.
+	Put functions in alphabetical order.
+	* src/user-prefs.h (commas_in_literal_matrix): New structure element.
+	Alphabetize structure elements and lists of functions.
+	* src/builtins.cc (string_variables): Add commas_in_literal_matrix
+	to the list.
+	* src/lex.l (<MATRIX>{SN}*\]{S}*): Pay attention to the value of
+	usre_pref.commas_in_literal_matrix when deciding whether to insert
+	a comma after seeing a ']' character.
+	(handle_identifier): Likewise.
+	(<MATRIX>{S}+): If commas are required, just eat the spaces.
+
+Tue May 24 19:49:51 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-assign.cc (tree_constant_rep::do_matrix_assignment
+	  (tree_constant&, tree_constant*, int)): Handle empty arguments
+	for two index values.
+	(tree_constant_rep::do_matrix_assignment
+	  (tree_constant&, tree_constant&)):
+	Likewise, for single index values.
+
+Mon May 23 01:43:23 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makefile.in (snapshot, snapshot-version): New targets.
+
+	* configure.in: Handle --enable-run-in-place (was easier than
+	doing the work to parse --run-in-place like Emacs uses).
+
+	* acconfig.h: Add #undef for RUN_IN_PLACE.
+
+	* Makeconf.in (OCTAVE_HOME): New macro.
+	* src/Makefile.in (defaults.h): Use it instead of ${prefix}.
+
+	* Makeconf.in (OCTAVE_INFO_DIR, OCTAVE_LIB_DIR): New macros.
+	* src/Makefile.in (defaults.h): Substitute them too.
+
+	* src/defaults.h.in (OCTAVE_INFO_DIR): New macro, used if
+	RUN_IN_PLACE is defined.
+	(OCTAVE_LIB_DIR): Likewise.
+
+	* src/utils.cc (octave_home): Handle RUN_IN_PLACE
+	(octave_info_dir): Ditto.
+	(octave_lib_dir): Ditto.
+
+	* src/tree-const.cc (tree_constant_rep::diag (void)): For empty
+	matrix, return empty matrix.
+	(tree_constant_rep::diag (tree_constant &)): Likewise, regardless
+	of value of arg.
+
+	* scripts/int2str.m: Format as integer, not float.
+	Don't add trailing new line character.
+
+Sun May 22 22:13:01 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/plot_int.m: When looking for imaginary arguments, check
+	if any element has an imaginary component, not if all elements
+	have imaginary components.
+
+Thu May 19 19:46:23 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/parse.y (EXPR_AND_AND, EXPR_OR_OR): New tokens, for
+	short-circuit logical AND and OR operators.
+	(simple_expression): Handle new tokens.
+	* src/lex.l (&&) [SHORT_CIRCUIT_LOGICALS]: Return EXPR_AND_AND.
+	(||) [SHORT_CIRCUIT_LOGICALS]: Return EXPR_OR_OR.
+	* src/tree.cc (tree_binary_expression::eval): Handle short-circuit
+	boolean operators.
+	(tree_binary_expression::eval_error): Print different messages for
+	or_or/or and and_and/and.
+	* src/tree-base.h (tree_expression_type): Add new structure
+	elements and_and and or_or.
+	* src/tree-const.cc (tree_constant_rep::is_true): New function.
+
+Tue May 17 17:04:00 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/idx-vector.cc (idx_vector::sort_uniq ()): New function.
+	* src/tc-assign.cc (tree_constant_rep::delete_rows ()): Use it.
+	(tree_constant_rep::delete_columns ()): Likewise.
+
+Mon May 16 13:31:33 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/linspace.m: Replace for loop with range operation.
+	* scripts/logspace.m: Replace for loop with element by element
+	exponentiation.
+
+Sun May  8 00:49:38 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/lqe.m: Correct comment.
+	Transpose k before returning. 
+
+Fri May  6 00:47:24 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (quit_loop_now): New function.
+	(tree_while_command::eval): Use it.
+	(tree_for_command::eval): Ditto.
+
+	* src/tree.cc (tree_for_command::do_for_loop_once): New function.
+	(tree_for_command::eval): Use it.
+
+Mon May  2 19:45:39 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (tree_for_command::eval): Handle returning,
+	breaking, and continuing for case of scalar expression in loop
+	control statement.
+
+Wed Apr 20 00:38:26 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/lex.l (\[{S}*): Don't return ',' for this	match when
+	convert_spaces_to_comma is true, since that can never be the right
+	thing to do.
+
+	* All Makefile.in files: Set top_srcdir here.
+	* Makeconf.in: Not here.
+
+	* Makeconf.in: Use top_srcdir instead of root_srcdir
+
+	* configure.in: Update for autoconf-1.8.  Use AC_VERBOSE for
+	verbose messages.  Use AC_WARN and AC_ERROR instead of echo for
+	warning and error messages.  Organize feature tests a bit better.
+	Use new autoconf macros to check for C++ compiler.  Add copyright
+	notice.  Recognize --enable-dld instead of --with-dld since that
+	seems to be more in line with the intent of the --enable/--with
+	options for configure scripts.  Use new autoconf macros
+	AC_REVISION and AC_PREREQ.  Don't add -Wall to CFLAGS and CXXFLAGS
+	until after all feature tests are done.  Etc.
+
+Fri Apr 15 01:56:20 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* acconfig.h: Add #undefs for HAVE_FINITE, HAVE_ISINF, and
+	HAVE_ISNAN.
+	* configure.in: Check for floatingpoint.h.
+	* src/sysdep.cc (sysdep_init): Disable trapping on common
+	exceptions for 386BSD systems that have floatingpoint.h.
+
+	* src/utils.cc: Don't declare ioctl() with prototype.
+
+Sat Apr  9 17:48:07 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-assign.cc (tree_constant_rep::fortran_style_matrix_assignment
+	  (tree_constant&, tree_constant&)):
+	Handle case of M (X) = scalar, where X is a zero-one vector with
+	only one nonzero element.
+
+	* src/tc-assign.cc (tree_constant_rep::do_vector_assign
+	  (tree_constant&, Range&):
+	Handle case of right hand side being a scalar.
+	(tree_constant_rep::do_vector_assign (tree_constant&, idx_vector&):
+	Ditto.
+
+	* src/tc-assign.cc (tree_constant_rep::do_matrix_assignment
+	  (int,tree_constant_rep::constant_type)):
+	Allow assignment of complex scalar too. 
+	(tree_constant_rep::do_matrix_assignment
+	  (tree_constant_rep::constant_type, int)):
+	Ditto.
+
+	* src/tree-const.h (REP_RHS_MATRIX): Initialize nr and nc.
+	Abort if rhs is not a real or complex matrix.
+
+Wed Apr  6 13:59:37 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Range.cc (Range::nelem_internal): Use an integer, not
+	a double, for the number of intervals.	Avoid possible problems
+	with extended precision registers on some systems (e.g. x86/Linux).
+
+Mon Mar 28 17:23:18 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/utils.cc (raw_mode): For OCRNL, ONOCR, and ONLRET, check to
+	see if they are defined before using them instead of checking to
+	see if NeXT is defined.
+
+	* info/terminal.c (terminal_prep_terminal): Check to see if OCRNL
+	is defined before using it instead of checking to see if NeXT is
+	defined.
+
+Thu Mar 24 03:21:01 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (tree_parameter_list::define_from_arg_vector):
+	New function.
+	(tree_parameter_list::convert_to_const_vector): Ditto.
+	(tree_function::eval): Use them instead of trying to do this
+	in-line.
+
+	* src/symtab.h (symbol_record::global_link_context): New stack for
+	saving linked_to_global flag.
+	* src/symtab.cc (symbol_record::push_context): Save
+	linked_to_global too.
+	(symbol_record::pop_context): And restore it.
+
+Wed Mar 23 16:18:19 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/refcard.tex.in: New file.
+	* doc/Makefile.in: Create refcard.* and refcard-local.* from
+	refcard.tex.in.
+
+Tue Mar 22 15:23:55 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.sh: exec $OCTAVE_HOME/bin/octave.bin, not just
+	octave.bin.
+
+Thu Mar 17 01:06:10 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/arith-ops.cc (do_binary_op (ComplexMatrix&, Matrix& b)):
+	Correctly handle element by element left division.
+
+	* src/g-builtins.cc (builtin_error): Return without calling error
+	(and setting error_state) if the message is empty.
+
+	* src/help.cc (operators): Correct help message for `.^'.
+
+	* src/tc-index.cc (tree_contant_rep::fortran_style_matrix_index):
+	Preserve vector orientation when indexing with a zero-one vector.
+
+	* src/tc-index.cc (tree_constant_rep::do_scalar_index): Handle
+	indexing a scalar with `0'.
+
+	* src/tc-index.cc (tree_constant_rep::do_scalar_index): Handle the
+	index `:' the same as the index `1'.
+
+Tue Mar 15 17:22:00 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Array.cc: Fix typo in comments about compiler flags.
+
+Wed Mar  9 15:08:21 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 1.0.1.
+
+	* src/*.h: Use the macro octave_FOO_h instead of _FOO_h to protect
+	against multiple inclusion.
+	* liboctave/*.h: Likewise.
+
+	* liboctave/*.h: Surround contents of files in extern "C++" { }.
+
+Tue Mar  8 18:06:54 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-index.cc (tree_constant_rep::do_vector_index (const
+	tree_constant&) const): Don't crash if matrix is empty.
+
+	* scripts/norm.m: Return empty matrix for empty argument.
+
+Mon Mar  7 23:34:44 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doinstall.sh: chmod new directories to 755.
+
+Sat Mar  5 13:15:10 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* bsd-math/log1p.c: Declare finite as returning int, not double.
+	* bsd-math/finite.c (finite): Add return type.
+
+Thu Mar  3 14:42:00 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/DiagMatrix.cc (operator *): Provide definitions for
+	DiagMatrix * DiagMatrix, ComplexDiagMatrix * ComplexDiagMatrix, 
+	ComplexDiagMatrix * DiagMatrix, and DiagMatrix * ComplexDiagMatrix.
+
+	* liboctave/ColVector.cc (operator >>): Provide definitions for
+	real and complex column vectors.
+
+	* liboctave/RowVector.cc (operator >>): Provide definitions for
+	real and complex row vectors.
+
+Wed Mar  2 18:00:47 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Array.h (DiagArray::Proxy::operator & ()): Provide
+	function body.
+
+Tue Mar  1 13:18:35 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-const.cc (tree_constant::load (istream&)): Don't skip
+	past first type keyword if not global.
+	(tree_constant::load (istream&, tree_constant_rep::constant_type)): 
+	Allocate storage for reading complex scalar.
+
+Sun Feb 20 14:17:47 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/menu.m: Don't fail on input that is empty or not a
+	scalar.
+
+	* Makefile.in (DISTFILES): Distribute ChangeLog.[0-9].
+
+	* src/lex.l (reset_parser): Don't resynch line number to command
+	history number if reading a script file.
+
+Thu Feb 17 01:36:19 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 1.0 released.
+
+	* src/file-io.cc (fopen_file_for_user): Improve error message.
+	(fopen_internal): Likewise.
+
+Wed Feb 16 02:21:05 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Try harder to find finite, isnan, and isinf.
+	Use m4 `dnl' comments, not shell `#' comments.
+
+	* src/file-io.cc (file_io_get_file): New function.
+	(fgets_internal): Use it instead of trying to do this in line.
+	(frewind_internal, fseek_internal, ftell_internal, do_printf,
+	do_scanf): Likewise.
+	* (do_scanf): Allow file name as string for fscanf.
+	* (procss_scanf_format): Delete unused argument `args'.  Delete
+	unused local variable `arg_type'.  Don't complain if we can't
+	store the result of a requested conversion.  Only return
+	successfully if a conversion actually occurs, even if we are not
+	storing the value.
+
+Sun Feb 13 13:32:03 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.83 released.
+
+	* Array.h (DiagArray): Move inline definitions of get() and set()
+	before use by other inline functions.
+
+Sat Feb 12 14:15:45 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Check for g77 last.  Even if it is ever actually
+	released, it probably won't be stable for quite a while.
+
+	* MAKEINFO.PATCH: New file.
+	* Makefile.in (DISTFILES): Distribute it.
+
+	* liboctave/Matrix.cc (operator + (Complex, const Matrix&)):
+	Make it work.
+	(operator - (Complex, const Matrix&)): Ditto.
+	(operator * (Complex, const Matrix&)): Ditto.
+	(operator / (Complex, const Matrix&)): Ditto.
+
+Fri Feb 11 00:03:39 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Check for strerror too.
+
+	* configure.in: When saving CFLAGS as XCFLAGS and then restoring
+	the value, quote the RHS.
+
+	* src/g-builtins.cc (builtin_clc): Do the dirty work to clear the
+	screen here instead of using rl_clear_screen to avoid printing
+	prompt unnecessarily.
+
+Thu Feb 10 00:26:32 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/utils.cc: Add all the cruft that the autoconf manual
+	suggests for including dirent.h.
+
+	* info/terminal.c (terminal_prep_terminal): [HAVE_TERMIOS_H &&
+	NeXT]: Don't use OCRNL, as someone says NeXT's termios.h doesn't
+	have it.
+
+	* configure.in (GCC_IEEE_FP_FLAG): Correct check for ix86 Linux.
+	Don't try to check for CC == gcc.
+	Add GCC_IEEE_FP_FLAG to CFLAGS while checking for IEEE FP
+	functions finite, isnan, and isinf.
+
+	* readline/rldefs.h: Make definition of HAVE_POSIX_SIGNALS
+	conditional on definition of _POSIX_VERSION, not HAVE_TERMIOS_H.
+
+Wed Feb  9 02:41:32 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (tree_function::octave_va_start): Rename from
+	va_start to avoid conflict with va_start macro.
+	(tree_function::octave_var_arg): Likewise, rename from va_arg.
+	* src/g-builtins.cc (builtin_va_arg): Call octave_va_arg for the
+	current function instead of va_arg.
+	(builtin_va_start): Likewise, for octave_va_start.
+
+	* Version 0.82.1.
+
+	* doc/Makefile.in (clean): Also remove octave.in, octave.rd,
+	octave.ins, and octave.rds.
+
+	* src/t-builtins.cc (load_variable): Make it work for all
+	combinations of loading global or local variables when the
+	variable to be loaded is already a global variable, local
+	variable, a function, or even undefined.
+
+Tue Feb  8 00:33:09 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.82 released.
+
+	* liboctave/mx-kludge.cc (operator + (KL_MAT_TYPE, KL_MAT_TYPE)):
+	For an empty matrix with one nonzero dimension, be sure to return
+	a result of the same size.
+	(operator - (KL_MAT_TYPE, KL_MAT_TYPE)): Ditto.
+	(product (KL_MAT_TYPE, KL_MAT_TYPE)): Ditto.
+	(quotient (KL_MAT_TYPE, KL_MAT_TYPE)): Ditto.
+
+Mon Feb  7 01:30:19 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Array.h, liboctave/array.cc (DiagArray): Back off on
+	indexing via Proxy class changes for AIX systems to avoid gcc (or
+	possibly AIX assembler?) bug.
+
+	* src/tree-const.cc (tree_constant_rep::maybe_resize (int,
+	force_orient)): Don't abort for a max index of zero.
+
+	* liboctave/Matrix.h (class RowVector, friend double operator *
+	(const RowVector&, const ColumnVector&)): Add missing const in
+	declaration.
+
+	* liboctave/Matrix.cc (Matrix::fill (val, r1, c1, r2, c2)): Set nc
+	to cols(), not rows().
+	(ComplexMatrix::fill (double val, r1, c1, r2, c2)): Likewise.
+	(ComplexMatrix::fill (Complex val, r1, c1, r2, c2)): Likewise.
+
+	* All source files: To match the documenation, refer to function
+	files, not M-files.  Rename functions and variables that refer to
+	_m_file_,  mfile, or mf to refer to _fcn_file, ffile, or ff.
+
+Sun Feb  6 19:08:26 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/parse.y (yyerror): Don't crash if a parse error happens and
+	the current input line is NULL.
+
+Sat Feb  5 18:53:04 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/file-io.cc (initialize_file_io): Don't use variable names
+	that start with `_'.
+	* src/file-io.cc (class file_info): Likewise.
+
+Fri Feb  4 01:15:59 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/builtins.cc (general_functions): In usage message for fopen,
+	use `Valid' instead of `Legal'.
+
+	* src/file-io.cc (do_printf): Use `invalid' instead of `illegal'
+	in error message.
+	(do_scanf): Likewise.
+
+	* src/mappers.cc (atanh): Use correct formula.
+
+Thu Feb  3 22:08:40 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/refcard.tex: New file.
+	* doc/Makefile.in (all): Make refcard.ps.
+	(DISTFILES): Distribute refcard.tex, refcard.dvi, and refcard.ps.
+
+	* src/tree-const.cc (any_element_is_negative): Delete function.
+	(any_element_less_than): New function.
+	(any_element_greater_than): Ditto.
+	(tree_constant_rep::mapper): Use struct elements lower_limit,
+	upper_limit, and can_return_complex_for_real_arg to properly
+	handle functions like acos, asin, atanh, and acosh.
+
+	* src/builins.h (struct Mapper_fcn): Rename neg_arg_complex to 
+	can_return_complex_for_real_arg.  New elements, lower_limit and
+	upper_limit.
+	(struct builtin mappers functions): Rename neg_arg_complex to 
+	can_return_complex_for_real_arg.  New elements, lower_limit and
+	upper_limit.  Delete elements nargin_max and nargout_max.
+	* src/variables.cc (install_builtin_mapper_function): Handle new
+	struct elements can_return_complex_for_real_arg, lower_limit, and
+	upper_limit.  Don't use nargin_max and nargout_max -- they are
+	the same for all mapper functions.
+
+Wed Feb  2 05:06:56 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Matrix.h: Don't include values.h.
+	* liboctave/Matrix-ext.cc: Include float.h
+	(DET::value_will_overflow): Use DBL_MAX, not MAXDOUBLE.
+	(ComplexDET::value_will_overflow): Likewise.
+	(DET::value_will_underflow): Use DBL_MIN, not MINDOUBLE.
+	(ComplexDET::value_will_underflow): Likewise.
+	* src/tree.cc: Include limits.h, not values.h.
+	(tree_builtin::max_expected_args): Use INT_MAX, not MAXINT.
+
+	* configure.in: If compiling on an ix86, set GCC_IEEE_FP_FLAG to
+	-mieee-fp.  We should no longer require the modified crt0 code on
+	Linux systems in order to get IEEE functions.
+	* Makeconf.in (GCC_IEEE_FP_FLAG): Substitute value.
+	(ALL_CFLAGS, UGLY_ALL_CFLAGS, ALL_CXX_FLAGS, UGLY_ALL_CXX_FLAGS,
+	ALL_LDFLAGS): Use it.
+
+Tue Feb  1 22:30:46 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/builtins.cc (install_builtins): Make SEEK_SET, SEEK_CUR, and
+	SEEK_END constants.
+
+	* src/tree-plot.cc (tree_subplot_using::print): Only check column
+	number against max if max is greater than 0.
+
+Mon Jan 31 15:59:31 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/strcmp.m: Correctly handle empty strings.
+
+	* src/parse.y (input): Recognize lone simple_list and simple_list
+	followed by error and '\n'.
+
+Fri Jan 28 00:20:30 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.81 released.
+
+	* src/octave.cc (clean_up_and_exit): Call cleanup_tmp_files() here
+	too.
+
+	* configure.in: Check for atexit and on_exit.
+	* src/octave.cc: Use HAVE_ATEXIT and HAVE_ON_EXIT (instead of
+	just checking to see if sun is defined) to decide whether to
+	define atexit as on_exit.
+	(main): Don't try to call atexit if it's missing and we don't have
+	on_exit either.
+
+Thu Jan 27 22:16:48 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Check for gethostname and sys/utsname.h.
+	* utils.cc (gethostname): Steal replacement from bash.  Provide
+	definition if it looks like it's missing and we have
+	sys/utsname.h.
+
+	* liboctave/Array.h (DiagArray): Define non-const indexing
+	functions here.
+	* liboctave/Array.cc (DiagArray): Not here.
+
+	* liboctave/Array.h (DiagArray::Proxy): New class to handle
+	non-const reference indexing.  Allows different action if indexing
+	on left side of assignment operator.
+
+	* src/octave.cc (main): Call initialize_pager(),
+	initialize_readline(), and install_signal_handlers() before trying
+	to read startup files.
+
+	* src/octave.cc (input_from_startup_file): New global flag.
+	(execute_startup_files): Set it to 1 before reading startup files.
+	* src/parse.y (func_def_2): If input_from_startup_file, don't try
+	to compare file name and function name.
+
+Wed Jan 26 14:39:27 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* readline/rldefs.h: Make better use of autoconf defines.
+
+Tue Jan 25 17:19:19 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Matrix.cc (ComplexMatrix (DiagMatrix)): Make sure off
+	diagonal elements are zero.
+	(ComplexMatrix (ComplexDiagMatrix): Likewise.
+	(Matrix (DiagMatrix): Likewise.
+
+Fri Jan 21 17:43:11 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* flibs.sh: Recognize libraries that match `/*.a'.
+
+Thu Jan 20 18:12:01 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.80.1.
+
+Wed Jan 19 14:48:27 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* libcruft/odepack/stode.f: Don't try to `RETURN 0'.  This causes
+	lsode to fail, at least with Sun's f77.
+
+	* src/tree-const.cc (tree_constant_rep::load): Delete string
+	returned from extract_keyword.
+	* src/t-builtins.cc (builtin_load): Likewise.
+	* src/variables.cc (extract_keyword): Return new storage, not
+	static buffer.
+
+	* src/t-builtins.cc (builtin_save): If saving a named list of
+	variables, use is_globally_visible to decide whether to mark
+	variables in the current symbol table as global.
+
+Tue Jan 18 11:57:03 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.80 released.
+
+	* doc/Makefile.in (install): Delete commands for installing
+	liboctave.info instead of trying to comment them out.
+
+	* liboctave/Array.cc: Allow users to compile with
+	-fexternal-stemplates and USE_EXTERNAL_TEMPLATES defined to
+	generate their own .o files with new types.
+
+	* Makeconf.in (includedir): Install include files in
+	$prefix/include/octave by default.
+
+	* liboctave/Makefile.in (TEMPLATE_SRC): New macro.
+	(install): Install files listed in $(TEMPLATE_SRC) too.
+
+	* info/search.h: Conditionally declare stricmp and strnicmp.
+	* info/search.c: Conditionally define stricmp and strnicmp.
+	* config.h.in: Add undefs for HAVE_STRICMP and HAVE_STRNICMP.
+
+	* configure.in: Check for stricmp and strnicmp too.
+
+	* doc/Makefile.in: For now, don't format or try to install the
+	liboctave manual. 
+	Don't distribute formatted copies of liboctave manual.
+
+Mon Jan 17 01:10:54 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/Makefile.in (clean): Remove all index files.
+
+	* src/Makefile.in (defaults.h): Depend on Makefile too.
+	* doc/Makefile.in (conf.texi): New rule for making conf.texi from
+	conf.texi.in.
+
+	* doc/conf.texi.in: New file.
+	* doc/octave.texi: Include conf.texi to get VERSION, OCTAVE_HOME,
+	and other variables that need to be set depending on the
+	configuration.
+
+	* Makefile.in (DISTFILES): Don't distribute PLOTTING.  Current
+	plotting info is in the Texinfo docs.
+
+Sat Jan 15 15:43:34 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* config.sub: New file, from libg++-2.5.2.
+	* Makefile.in: Distribute config.sub.
+	* configure.in: Use config.sub to validate system types.  If it
+	fails, continue with target_host_type and canonical_host_type set
+	to unknown.  Leave target_host_type set to any alias given as the
+	TARGET argument to configure.
+
+	* readline/rldefs.h: If ultrix and HAVE_SGTTY_H, avoid Posix
+	terminal driver.
+	* configure.in: If configuring for ultrix, check for sgtty first.
+	If not found, go ahead and check for Posix terminal driver.
+
+	* configure.in: Don't try to do anything special for readline on
+	NeXT systems.
+	
+	* Makeconf.in: Define rules for making .d files here.
+	liboctave/Makefile.in: Not here.
+	src/Makefile.in: Or here.
+
+	* liboctave/Matrix.h (all Matrix/Vector operator = functions):
+	Simply call the base class operator =, then return *this.
+	(class ColumnVector): Declare RowVector a friend class, so it can
+	access the private constructor for the transpose operator.
+	(class RowVector): Likewise, for ColumnVector.
+	(class ComplexColumnVector): Likewise, for CommplexRowVector.
+	(class ComplexRowVector): Likewise, for ComplexColumnVector.
+	Numerous formatting cleanups.
+
+Thu Jan 13 13:17:47 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.79.90.
+
+	* builtins.cc: Include missing-math.h.
+
+	* src/missing-math.h: Provide declarations for acosh, asinh,
+	atanh, and gamma whether they are actually missing or not, because
+	they are not part of the standard math.h, and the g++/libg++
+	installation no longer provides declarations for them.
+
+	* src/sighandlers.h (RETSIGTYPE): Define here.
+	(BADSIG): Likewise.
+	(sig_handler): Likewise.
+
+	* src/g-builtins.cc: Include sighandlers.h
+	Don't define RETSIGTYPE, BADSIG, or sig_handler here.
+	* src/octave.cc: Or here.
+
+Wed Jan 12 16:12:27 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/g-builtins.cc: Don't check nargin/nargout in *_options
+	functions.
+
+	* src/f-qpsol.cc, src/f-quad.cc, src/f-lsode.cc, src/f-fsolve.cc,
+	src/f-dassl.cc, liboctave/QPSOL.cc, liboctave/Quad.cc,
+	liboctave/ODE.cc, liboctave/NLEqn.cc, liboctave/DAE.cc:
+	Similar changes for these classes/functions as the following
+	changes for src/f-npsol.cc and liboctave/NPSOL.cc:
+
+	* src/f-npsol.cc (npsol_opts): New static variable to hold Octave's
+	current idea of npsol options.
+	(npsol): Call nlp.copy (npsol_opts) after creating NPSOL object.
+	(npsol_option_table): New static list of options for npsol.
+	(print_npsol_option_list): New function.
+	(do_npsol_option): New function.
+	(npsol_options): Make it work.
+
+	* liboctave/NPSOL.cc (NPSOL_options): New class.
+	* (NPSOL): Also derive from NPSOL_options.
+	* (minimize): Call pass_options_to_npsol before calling npsol.
+	* (NPSOL::option): No longer works.  Print error message instead.
+	* (NPSOL::set_default_options): Now a member of NPSOL_options class.
+
+	* src/utils.cc: If missing, declare strcasecmp, strncasecmp.
+	* (almost_match): Add new argument to do case-insensitive matches.
+	* (keyword_almost_match): New function to match a string against a
+	list of keywords.
+
+	* liboctave/NLP.h (NLP): Add destructor and copy constructor.
+
+	* configure.in: Check for strcasecmp and strncasecmp.
+	* config.h.in: Add #undefs for HAVE_STRCASECMP and STRNCASECMP.
+	* src/strcasecmp.c, src/strncase.c: New files, from glibc.
+	* src/Makefile.in (SOURCES, OBJECTS): List them.
+
+	* src/builtins.cc (general_functions): Improve usage message for
+	the *_options functions.
+	(print_usage): New arg, just_usage with default value of 0.
+	If nonzero, don't print info about where to find additional help.
+
+	* src/Makefile.in (INCLUDES): Add error.h.
+	(SOURCES): Add error.h.
+
+	* src/tree.cc (tree_identifier::parse_m_file): call reset_parser
+	before calling yyparse ().
+	* src/tc-extras.cc (eval_string): Likewise.
+	Don't save previous symbol table.  That is handled by the
+	unwind protect.
+
+	* src/lex.l (reset_parser): Don't unconditionally call yyreset.
+	Add a couple of comments.
+	(yywrap): Always return 1, not 0.
+	(yy_flex_alloc, yy_flex_realloc, yy_flex_free): #if 0 out.
+
+	* src/utils.cc (raw_mode): Only complain about stdin not being a
+	tty if we are really interactive.
+
+	* src/octave.cc (main): End startup message with endl to ensure
+	flushing before other output.
+	* Turn of readline's blink_matching_paren feature if not
+	interactive, or if reading from a file specified on the command
+	line.
+
+	* src/octave.cc (main): Set the symbol table context just before
+	calling reset_parser in the main loop.
+	* src/lex.l (reset_parser): Not here.
+
+	* src/input.cc (octave_gets): Declare static.
+	(octave_read): Also handle echoing input if not using readline.
+
+	* Makefile.in (DISTFILES): Add SENDING-PATCHES to the list.
+
+Mon Jan 10 14:30:13 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/corrcoef.m, scripts/fortran_vec.m, scripts/kurtosis.m,
+	scripts/ols.m, scripts/skewness.m, scripts/cov.m, scripts/gls.m,
+	scripts/mahalanobis.m, scripts/pinv.m: New script files from Kurt
+	Hornik (hornik at neuro.tuwien.ac.at) and the Department of
+	Probability Theory and Statistics TU Wien, Austria. 
+
+Sun Jan  9 01:11:05 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/g-builtins.cc (builtin_fsqp_options): If FSQP_MISSING is
+	defined, don't call fsqp_options; just print usage message.
+	(builtin_npsol_options): Likewise, for npsol_options.
+	(builtin_qpsol_options): Likewise, for qpsol_options.
+	* src/builtins.cc (general_functions): Provide different usage
+	message for fsqp_options depending on whether FSQP_MISSING is
+	defined.  Likewise for npsol_options and qpsol_options.
+
+Sat Jan  8 16:45:57 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* libcruft/misc/dostop.c: Include config.h.
+
+	* src/variables.cc (extract_keyword): Use ostrstream instead of
+	fixed length buffer.  For keywords with string values, return
+	value in static buffer.
+	* src/t-builtins.cc (builtin_load): Handle new argument list for
+	extract_keyword.  Handle possiblity of load_variable setting
+	error_state.
+	* src/tree-const.cc (tree_constant_rep::load): Handle new argument
+	list for extract_keyword.
+
+Fri Jan  7 13:20:47 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/f-eig.cc (builtin_eig_2): Rename from builtin_eig.
+	* src/f-fsolve.cc (builtin_fsolve_2): Rename from builtin_fsolve.
+	* src/f-inv.cc (builtin_inv_2): Rename from builtin_inv.
+
+Thu Jan  6 12:29:41 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-base.h (tree::save): Add optional argument `precision'.
+	* src/tree-const.cc (tree_constant::save): Ditto.
+	(tree_constant_rep::save): Ditto.
+	* src/symtab.cc (symbol_def::save): Ditto.
+	(symbol_record::save): Ditto.
+	(symbol_table::save): Ditto.
+
+	* src/t-builtins.cc (builtin_save): Pass user_pref.save_precision
+	to symbol table save functions.
+	* src/builtns.cc (string_variables): Add save precision to thelist.
+	(install_builtins): Initialize it.
+	* src/user-prefs.cc (set_save_precision): New function.
+	* src/user-prefs.h (user_pref.save_precision): New data element.
+
+	* liboctave/Matrix-ext.cc: Provide correct prototypes for dgeesx
+	and zgeesx.
+	* (SCHUR::init): Don't declare a dummy_select function pointer,
+	just pass `(void *) 0' instead, since the dummy argument is never
+	supposed to be used anyway.
+
+	* src/input.cc (initialize_readline): Cast command_completer to
+	CPPFunction, not Function, now that readline has more than one
+	function typedef.
+	* Add extern declaration for free_undo_list ().
+
+	* Replace readline source from GDB with readline source from bash.
+	This allows paren matching.
+
+Wed Jan  5 01:20:26 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Also check for sys/select.h.
+
+	* liboctave/RowVector.cc (ComplexRowVector::operator *): Complete
+	function body.  Put code in-line rather than making a call to the
+	BLAS routine zdotu to avoid having to cope with the various ways
+	that Fortran compilers might translate this.
+
+	* src/input.cc (operate_and_get_next): New function, from bash.
+	(initialize_readline): Bind operate_and_get_next to C-O here.
+
+	* src/input.cc (command_completer, command_generator):
+	Declare static here.
+	* srs/input.h (command_completer, command_generator):
+	Not extern here.
+
+	* g-builtins.cc (builtin_warranty): Change copyright info.
+	* octave.cc (verbose_usage): Likewise.
+	(main): Likewise.
+
+Mon Jan  3 15:49:41 1994  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/fnmatch.c, src/fnmatch.h: New files for pattern matching
+	from the GNU C library.
+	* src/Makefile.in: Add them to the appropriate lists.
+	* src/t-builtins.cc (builtin_save): Use fnmatch to do pattern
+	matching instead of using regular expressions.
+	(builtin_clear): Likewise.
+	(glob_pattern_p): New function.
+	(builtin_save): Print error message and return if only given one
+	argument that contains globbing characters.
+
+	* src/symtab.cc (symbol_record::save): Don't attempt to save
+	undefined variables.
+
+Wed Dec 29 02:55:08 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/rank.m: Also need to compute SVD when nargin == 2.
+	Correct usage message.
+
+Wed Dec 15 01:44:18 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/f-lpsolve.cc, src/f-fsqp.cc, src/f-npsol.cc, src/f-qpsol.cc,
+	src/f-lsode.cc, src/f-dassl.cc, src/f-fsolve.cc, src/f-quad.cc:
+	New stub options functions, XXX_options, and XXX_options_2 (for
+	future dld use), where XXX is lpsolve, fsqp, npsol, etc.
+	* src/f-lpsolve.h, src/f-fsqp.h, src/f-npsol.h, src/f-qpsol.h,
+	src/f-lsode.h, src/f-dassl.h, src/f-fsolve.h, src/f-quad.h:
+	Declare XXX_options functions.
+	* src/builtins.cc (builtin_general_functions): Add new XXX_options
+	functions to the list of builtin functions.
+	* src/g-builtins.cc: Define builtin_XXX_options functions.
+	* src/g-builtins.h: Declare them.
+
+	* scripts/tzero.m: Add missing comma in fprintf call.
+
+Tue Dec 14 00:24:35 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* libcruft/quadpack/*.f: Modify to handle user-requested
+	termination from inside the user-supplied function.
+	* src/f-quad.cc (quad_user_function): Set quad_integration_error
+	if an error is encountered in the user-supplied function.
+	* liboctave/Quad.h (quad_integration_error): New global variable.
+	* liboctave/Quad.cc (user_function): Handle
+	quad_integration_error, and error flag for modified Quadpack
+	functions.
+
+	* src/tree.cc (tree_simple_assignment_expression::eval): Check
+	error status after calling convert_to_const_vector () on the
+	argument list.
+	(tree_index_expression::eval): Ditto.
+
+	* src/tree.cc (tree_argument_list::convert_to_const_vector):
+	If an error is encountered while evaluating an element of the
+	list, print an error message including the element number.
+
+	* liboctave/ODE.cc (integration_error): New private data member.
+	(ODE constructors): Initialize it to zero.
+	(ODE::integrate (double)): Reset it to zero before each
+	integration step.
+	(lsode_f): Treat empty vector returned from user-supplied function
+	as an error.
+	* src/f-lsode.cc (lsode_user_function): Return empty vector if
+	error is encountered in user-supplied function.  Don't jump to top
+	level on error.
+
+	* libcruft/odepack/lsode.f (lsode): Return with istate = -13 on
+	error from user supplied subroutine.
+	* libcruft/odepack/lsode.f (lsode): Handle extra argument returned
+	from user-supplied function.
+	* libcruft/odepack/stode.f (stode): Likewise.
+	* libcruft/odepack/prepj.f (prepj): Likewise.
+
+Wed Dec  8 01:30:57 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/DAE.cc (integration_error): New private data member.
+	(DAE constructors): Initialize it to zero.
+	(DAE::integrate (double)): Reset it to zero before each
+	integration step.
+	(dassl_f): Treat empty vector returned from user-supplied function
+	as an error.
+	* src/f-dassl.cc (dassl_user_function): Return empty vector if
+	error is encountered in user-supplied function.  Don't jump to top
+	level on error.
+
+	* liboctave/NPSOL.cc (npsol_objective_error): New global variable.
+	(npsol_objfun): Set to zero before calling user-supplied function.
+	Check after calling user-supplied function.
+	Set mode to -1 on error.
+	(npsol_confun): Set mode to -1 on error.
+	(npsol declaration): Declare args for user-supplied functions.
+	* src/f-npsol.cc (npsol_objective_function): If an error is
+	encountered in the calculation of the objective function, set
+	npsol_objective_error to 1.
+	(npsol_constraint_function): Treat empty vector returned from
+	user-supplied function as an error.
+
+	* liboctave/Array.cc (*::checkelem): Correct bounds checking.  On
+	error, return uninitialized value of type T.  This avoids placing
+	an extra requirement on the class that can be used as an array
+	element.
+	(*::operator ()): Likewise.
+
+Mon Dec  6 07:24:49 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/NLEqn.cc (hybrd1 declaration): Declare args for
+	user-supplied fuction.
+	(hybrj1): Likewise.
+	(hybrd1_fcn): Treat return of empty vector from user supplied
+	function as an error by setting iflag to -1.
+	(hybrj1_fcn): Likewise.
+	(solve): Handle case of info < 0 returned from hybrd1.
+
+	* src/f-fsolve.cc (fsolve_user_function): Don't jump to top level
+	on error in user-supplied function.  Treat empty vector returned
+	from user-supplied function as error.
+	(hybrd_info_to_fsolve_info): Translate -1 (failure in evaluation
+	of user-supplied function) to -2.
+	* scripts/perror.m (fsolve case): Handle -2.
+
+	* info/error.c (program_name): Initialize to info, not NULL.
+
+	* info/session.c (initialize_info_session): Don't exit if term is
+	too dumb or too small to use info.  Return int status instead.
+	* info/info.h (TERM_TOO_SMALL): New macro.
+
+	* src/t-buitlins.cc (try_info): Check return value from
+	initialize_info_session ().
+
+	* liboctave/Array.cc (DiagArray<T>::DiagArray (int n, const T& val)):
+	Set number of rows and columns to n, not 0.
+
+Sat Dec  4 14:01:41 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/lex.h (YY_INPUT): Undefine if defined, then always define
+	the way we want.
+	(YY_FATAL_ERROR): Likewise.
+
+	* src/lex.l (yywrap): Declare static.
+	(yy_flex_alloc): New function, so we don't have to link with
+	libfl.a when using flex 2.4.x.
+	(yy_flex_realloc): Ditto.
+	(yy_flex_free): Ditto.
+
+Thu Dec  2 19:23:43 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/*.m: Add copying notice to script files.
+
+	* src/input.cc (command_generator): Return copy of matching string.
+
+	* src/input.cc (command_generator): Correctly delete array of
+	character strings.
+	* src/symtab.cc (symbol_table::save): Likewise.
+	* src/utils.cc (pathstring_to_vector): Likewise.
+
+	* src/utils.cc (get_m_file_names): When reallocating vector of
+	strings, delete original vector of pointers, but not the strings
+	they point to.
+
+Tue Nov 30 12:36:41 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/RowVector.cc, liboctave/ColVector.cc,
+	liboctave/DiagMatrix.cc, liboctave/Matrix.cc,
+	liboctave/Matrix-ext.cc: Massive rewrite to cope with new
+	derivation scheme.
+
+	* liboctave/Matrix.h: Include Array.h, and derive Matrix,
+	ComplexMatrix, etc. from Array<double>.  Derive Complex
+	versions from Array<Complex>.  Delete declarations of functions
+	now inherited from the Array classes.
+	* Include mx-kludge.h with appropriate #defines in each class that
+	needs it.
+	* liboctave/Matrix.cc: Include mx-kludge.cc with appropriate
+	#defines in each class that needs it.
+
+	* liboctave/Makefile.in (INCLUDES): Add Array.h, MArray.h, and
+	mx-kludge.h.
+	(SOURCES): Add Array.cc.
+	(EXTRAS): Add MArray.cc and mx-kludge.cc.
+
+	* liboctave/mx-kludge.h, liboctave/mx-kludge.cc: New files to
+	implement the MArray functionality with macros until g++ can
+	handle the MArray stuff.
+
+	* liboctave/MArray.h, liboctave/MArray.cc: New files for generic
+	arrays with simple math functions for like-types.  This won't
+	quite work with g++ yet, so it's not used anywhere.
+
+	* liboctave/Array.h, liboctave/Array.cc: New files for generic
+	arrays.
+
+	* liboctave/mx-inlines.cc: Add const for const arguments.
+
+	* src/file-io.cc (file_info): Rename class from File_info.
+	(file_info::operator =): Fix memory leak by deleting old name
+	and mode before saving new.  Don't do copy if source and
+	destination are the same.
+
+	* src/tree.cc (tree_matrix::eval): Plug memory leak.
+
+	* src/tree.cc (tree_builtin::tree_builtin): Check to see that nm,
+	not my_name, is non-NULL before saving it.
+
+	* src/tree.cc (tree_identifier::eval, tree_gobal_command::eval):
+	After performing the assignment, delete the identifier created
+	for temporary asssignment since the destrucotr for
+	tree_simple_assignment_expression doesn't do it for us.
+
+	* src/tree.cc (tree_function::stash_m_file_name): Delete file_name
+	before saving it.
+	(tree_function::stash_function_name): Likewise, for fcn_name.
+
+	* src/lex.l, src/lex.h: Make quote_is_transpose globally visible.
+	* src/parse.y (param_list): Use it, and recognize empty parameter
+	lists here.
+
+	* src/parse.y (simple_expr1): Recognize empty matrices here.
+	(matrix): Not here.
+
+	* src/arith-ops.cc (do_binary_op): The matrix product and quotient
+	functions aren't class member functions now.
+
+	* src/tc-index.cc, src/tc-assign.cc, src/symtab.cc,
+	src/tree-plot.cc, src/idx-vector.cc, src/tree-const.cc:
+	Call ::error, not just error, since g++ now complains about not
+	being able to find a non-hidden member function by that name.
+
+	* src/tree-const.cc: Call ::real and ::imag, not just real and imag,
+	since g++ now complains about not being able to find non-hidden
+	member functions by those names.
+
+	* src/tree-const.cc (tree_constant_rep::force_numeric): Handle case
+	of zero-length strings.
+
+	* src/tree-const.cc (tree_constant_rep::convert_to_str): Null
+	terminate strings created from scalars.
+
+	* src/tc-index.cc (tree_constant_rep::fortran_style_matrix_index): Use
+	data(), not fortran_vec().
+	* src/idx-vector.cc (idx_vector::idx_vector): Likewise.
+
+	* src/SLStack.cc: Move function definitions here.
+	* src/SLStack.h: From here.  Include SLStack.cc if not using
+	external templates.
+
+	* src/unwind-prot.h: Move class declaration here.
+	* src/unwind-prot.cc: From here.
+
+	* src/xdiv.h, src/xpow.h, src/variables.h, src/utils.h,
+	src/user-prefs.h, src/t-builtins.h, src/sighandlers.h,
+	src/pr-output.h, src/pager.h, src/octave-hist.h, src/mappers.h,
+	src/input.h, src/help.h, src/gripes.h, src/g-builtins.h,
+	src/f-syl.h, src/f-svd.h, src/f-schur.h, src/f-rand.h,
+	src/f-qzval.h, src/f-quad.h, src/f-qr.h, src/f-qpsol.h,
+	src/f-npsol.h, src/f-lu.h, src/f-lsode.h, src/f-lpsolve.h,
+	src/f-inv.h, src/f-ifft.h, src/f-hess.h, src/f-givens.h,
+	src/f-fsqp.h, src/f-fsolve.h, src/f-fft.h, src/f-expm.h,
+	src/f-eig.h, src/f-det.h, src/f-dassl.h, src/f-colloc.h,
+	src/f-chol.h, src/f-balance.h, src/error.h, src/dynamic-ld.h,
+	src/builtins.h, src/arith-ops.h, src/tree-const.h, src/tree.h,
+	src/token.h, src/symtab.h, src/procstream.h, src/idx-vector.h,
+	src/file-io.h, src/tree-base.h, src/unwind-prot.h, src/Stack.h,
+	liboctave/LinConst.h, liboctave/FEGrid.h, liboctave/NLEqn.h,
+	liboctave/NLConst.h, liboctave/LPsolve.h, liboctave/LP.h,
+	liboctave/FSQP.h, liboctave/DAEFunc.h, liboctave/DAE.h,
+	liboctave/CollocWt.h, liboctave/Bounds.h, liboctave/Objective.h,
+	liboctave/ODEFunc.h, liboctave/NLFunc.h, liboctave/Range.h,
+	liboctave/Quad.h, liboctave/QP.h, liboctave/QPSOL.h,
+	liboctave/QLD.h, liboctave/NPSOL.h, liboctave/NLP.h,
+	liboctave/f77-uscore.h, liboctave/lo-error.h,
+	liboctave/Matrix.h:
+	Don't use #pragma interface.
+
+	* src/tc-index.cc, src/tc-assign.cc, src/symtab.cc,
+	src/procstream.cc, src/gripes.cc, src/f-syl.cc, src/f-svd.cc,
+	src/f-schur.cc, src/f-rand.cc, src/f-quad.cc, src/f-qr.cc,
+	src/f-qpsol.cc, src/f-npsol.cc, src/f-lu.cc, src/f-lsode.cc,
+	src/f-lpsolve.cc, src/f-inv.cc, src/f-ifft.cc, src/f-hess.cc,
+	src/f-givens.cc, src/f-fsqp.cc, src/f-fsolve.cc, src/f-fft.cc,
+	src/f-eig.cc, src/f-det.cc, src/f-dassl.cc, src/f-colloc.cc,
+	src/f-chol.cc, src/f-balance.cc, src/t-builtins.cc,
+	src/octave-hist.cc, src/input.cc, src/g-builtins.cc,
+	src/xdiv.cc, src/xpow.cc, src/user-prefs.cc, src/unwind-prot.cc,
+	src/tree-plot.cc, src/token.cc, src/tc-extras.cc, src/sysdep.cc,
+	src/sighandlers.cc, src/pr-output.cc, src/pager.cc,
+	src/mappers.cc, src/idx-vector.cc, src/help.cc, src/f-qzval.cc,
+	src/f-expm.cc, src/error.cc, src/dynamic-ld.cc, src/builtins.cc,
+	src/arith-ops.cc, src/variables.cc, src/utils.cc,
+	src/tree-const.cc, src/file-io.cc, src/tree.cc,
+	liboctave/sun-utils.cc, liboctave/mx-inlines.cc,
+	liboctave/RowVector.cc, liboctave/ColVector.cc,
+	liboctave/DiagMatrix.cc, liboctave/Matrix.cc,
+	liboctave/Matrix-ext.cc, liboctave/Quad.cc, liboctave/ODE.cc,
+	liboctave/LPsolve.cc, liboctave/FSQP.cc, liboctave/DAE.cc,
+	liboctave/DAEFunc.cc, liboctave/QP.cc, liboctave/Objective.cc,
+	liboctave/ODEFunc.cc, liboctave/NLFunc.cc, liboctave/NLConst.cc,
+	liboctave/LP.cc, liboctave/lo-error.cc, liboctave/Range.cc,
+	liboctave/QPSOL.cc, liboctave/NPSOL.cc, liboctave/NLEqn.cc,
+	liboctave/Matrix.cc, liboctave/Matrix-ext.cc,
+	liboctave/LinConst.cc, liboctave/FEGrid.cc,
+	liboctave/DiagMatrix.cc, liboctave/CollocWt.cc,
+	liboctave/ColVector.cc, liboctave/Bounds.cc:
+	Don't use #pragma implementation.
+
+	* src/lex.l, src/parse.y, src/procstream.cc, src/gripes.cc,
+	src/f-syl.cc, src/f-svd.cc, src/f-schur.cc, src/f-rand.cc,
+	src/f-quad.cc, src/f-qr.cc, src/f-qpsol.cc, src/f-npsol.cc,
+	src/f-lu.cc, src/f-lsode.cc, src/f-lpsolve.cc, src/f-inv.cc,
+	src/f-ifft.cc, src/f-hess.cc, src/f-givens.cc, src/f-fsqp.cc,
+	src/f-fsolve.cc, src/f-fft.cc, src/f-eig.cc, src/f-det.cc,
+	src/f-dassl.cc, src/f-colloc.cc, src/f-chol.cc,
+	src/f-balance.cc, src/t-builtins.cc, src/octave-hist.cc,
+	src/input.cc, src/g-builtins.cc, src/xdiv.cc, src/xpow.cc,
+	src/user-prefs.cc, src/unwind-prot.cc, src/tree-plot.cc,
+	src/token.cc, src/tc-extras.cc, src/sysdep.cc,
+	src/sighandlers.cc, src/pr-output.cc, src/pager.cc,
+	src/mappers.cc, src/idx-vector.cc, src/help.cc, src/f-qzval.cc,
+	src/f-expm.cc, src/error.cc, src/dynamic-ld.cc, src/builtins.cc,
+	src/arith-ops.cc, src/variables.cc, src/utils.cc,
+	src/tree-const.cc, src/file-io.cc, src/tree.cc: If HAVE_CONFIG_H
+	is defined, include config.h.
+
+	* config.h.in, acconfig.h: New files
+	* Makefile.in (DISTFILES): Add them to the list.
+
+	* Makeconf.in (root_srcdir): Define.
+	(INCFLAGS): Clean up.
+	(UGLY_ALL_CFLAGS): New macro.
+	(UGLY_ALL_CXXFLAGS): Likewise.
+	(UGLY_ALL_LDFLAGS): Likewise.
+
+	* configure.in: Convert to generate config.h.
+	Substitute root_srcdir in Makefiles.
+	Use AC_DEFINE(foo, 1) instead of DEFS="$DEFS -Dfoo=1".
+	If using g++ 2.5 or later, define USE_EXTERNAL_TEMPLATES.
+	Use UGLY_DEFS for what would have been substited in DEFS, for
+	those cases when we need DEFS instead of config.h.
+
+Tue Nov 16 04:59:19 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/f-expm.cc, src/f-givens.cc, src/f-qzval.cc, src/f-syl.cc:
+	Include f77-uscore.h here.
+
+	* liboctave/ColVector.cc, liboctave/Matrix.cc,
+	liboctave/Matrix-ext.cc, liboctave/RowVector.cc: Move declarations
+	for Fortran functions here.
+	* liboctave/Matrix.h: From here. Don't include f77-uscore.h here.
+
+Mon Nov 15 04:03:34 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-extras.cc (min): For two-arg versions, use error(), not
+	FAIL.
+	(max): Likewise.
+	* src/idx-vector.cc (checkelem): Likewise.
+
+	* liboctave/Matrix.h, liboctave/Matrix.cc, liboctave/RowVector.cc,
+	liboctave/ColVector.cc, liboctave/DiagMatrix.cc,
+	liboctave/Matrix-ext.cc, liboctave/Bounds.cc, liboctave/DAE.cc,
+	liboctave/CollocWt.cc, liboctave/FEGrid.cc, liboctave/LinConst.cc,
+	liboctave/ODE.cc, liboctave/NLEqn.cc: Don't abort or exit on
+	errors.  Instead print some message by calling the function
+	pointed to by current_liboctave_error_handler and then return.
+
+	* liboctave/lo-error.cc: New file, for liboctave error handling
+	stuff.
+
+Sun Nov 14 23:28:12 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/utils.cc (default_path): Handle OCTAVE_PATH from the
+	environment like TeX handles TEXINPUTS.  If the path starts with
+	`:', prepend the standard path.  If it ends with `:' append the
+	standard path.  If it begins and ends with `:', do both (which is
+	useless, but the luser asked for it...).
+	(octave_lib_dir): Plug memory leak.
+
+Sat Nov 13 02:41:24 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/symtab.h (symbol_record::context): New data member, to allow
+	recursive functions to work.
+	* src/symtab.cc (symbol_record::push_context): New function
+	(symbol_record::pop_context): Ditto.
+	(symbol_table::pop_context): Ditto.
+	(symbol_table::push_context): Ditto.
+
+	* src/tree.cc (tree_function::eval): If call_depth is > 1, push
+	symbol table context and add unwind protect to pop it on exit or
+	error.
+	(pop_symbol_table_context): New function for unwind protect.
+
+	* configure.in: Use AC_HAVE_HEADERS(unistd.h) instead of
+	AC_UNISTD_H.
+
+	* src/lex.l, src/f-quad.cc, src/f-rand.cc, src/f-lpsolve.cc,
+	src/f-fsqp.cc, src/f-fsolve.cc, src/f-det.cc, src/f-dassl.cc,
+	src/f-colloc.cc, src/utils.cc, src/variables.cc, src/tree.cc,
+	src/tree-const.cc, src/tc-extras.cc, src/sysdep.cc, src/symtab.cc,
+	src/octave-hist.cc, src/pr-output.cc, src/input.cc,
+	src/g-builtins.cc, src/f-det.cc, src/f-inv.cc, src/file-io.cc:
+	Convert most calls to message() to calls to warning() or error()
+	instead.
+
+	* src/f-npsol.cc (npsol): Don't try to create the linear
+	constraint object before checking array sizes.
+
+Fri Nov 12 04:36:12 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tc-inlines.cc (is_one_zero): New function.
+	* src/tc-assign.cc: Everywhere we check for is_zero_one, also
+	check for is_one_zero.  Some people write ranges that go in
+	decreasing order...
+	* src/tc-index.cc: Likewise.
+
+	* src/tc-inlines (index_check (Range&, int&, char*)): Eliminate
+	second arg -- there is no need to return the max value of the
+	range.  Correctly compute and check the minimum value.
+	* src/tc-index.cc: Change all callers, and check the max value
+	there.
+	* src/tc-assign.cc: Likewise.
+
+	* src/tc-assign.cc (do_vector_assign): Handle assignment of empty
+	matrix for int, idx_vector, and Range cases.
+	(do_matrix_assign): Likewise, for cases when one of the indices is
+	a colon and the other is an int, idx_vector, or Range.
+
+	* liboctave/Range.h (Range): Rename private data members rng_foo
+	instead of just _foo.
+	* liboctave/Range.cc: Change names where used.
+
+	* liboctave/Range.cc (max): Return correct value even when the
+	elements in the range don't line up exactly with the limit.
+	(min): Likewise.
+	(sort): New function.
+
+	* src/tc-assign.cc (delete_row (int)): New function.
+	(delete_rows (idx_vector&)): Ditto.
+	(delete_rows (Range&)): Ditto.
+	(delete_column (int)): New function.
+	(delete_columns (idx_vector&)): Ditto.
+	(delete_columns (Range&)): Ditto.
+
+	* src/tree-const.h (is_empty): Don't try checking rows and columns
+	if type is magic_colon or unknown.  Return false instead.
+	(is_zero_by_zero): New function.
+
+	* src/idx-vector.cc (sort): New function.
+	(intcmp): New static function, for sorting.
+
+Thu Nov 11 02:31:13 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/menu.m: Update to use new va_start() and va_arg()
+	functions.
+
+	* src/g-builtins.cc (builtin_va_arg): Rename from
+	builtin_get_next_arg.
+	(builtin_va_start): New function.
+	* src/builtins.cc (builtin_general_functions): Fix up list.
+
+	* src/tree.cc (tree_function::va_arg): Rename from get_next_arg.
+	(tree_function::va_start): New function.
+
+	* src/tree.h (tree_function::num_named_args): New data member.
+	* src/tree.cc (tree_function::define_param_list): Set it.
+	(tree_function::eval): Unwind-protect it.
+
+Wed Nov 10 03:37:44 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (tree_identifier::assign): Also check to make sure
+	that the symbol record is defined since symbol_record::is_variable
+	may return true even if the record is undefined.
+	* src/variables.cc (link_to_global_variable): Don't try to copy a
+	NULL_TREE_CONST.
+
+	* src/tree-const.cc (tree_constant_rep::matrix_value): If the
+	current value is a scalar, return 1x1 matrix.
+	* src/tc-assign.cc (tree_constant_rep::check_vector_assign):
+	Handle case of zero size LHS.
+	Clean up formatting of some error messages.
+
+	* src/lex.l ({EL}): Recognize ... when not at end of line.
+	* src/octave.cc (curr_function): New global variable.
+	* src/g-buitlins.cc (builtin_get_next_arg): New function.
+	* src/builtins.cc (builtin_general_functions): Add it to the list.
+	* src/parse.y (param_list1): Handle ... at end of parameter list.
+	Abort parse on error.
+	(ELLIPSIS): New token, for variable argument lists.
+	* src/tree.h (tree_function): Add varargs_ok, args_passed,
+	num_args_passed, and curr_arg_number data members to handle
+	variable argument lists.
+	(tree_parameter_list::marked_for_varargs): New data member.
+	* src/tree.cc (tree_function::takes_varargs): New function.
+	(tree_function::get_next_arg): New function.
+	(tree_parameter_list::mark_varargs): New function.
+	(tree_parameter_list::takes_varargs): New function.
+	(tree_function::eval): Set curr_function, args_passed, and
+	num_args_passed for use by get_next_arg.
+
+Mon Nov  8 14:22:34 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.79 released.
+
+	* src/builtins.cc (builtin_text_functions):  Correct usage message
+	for who.
+
+	* scripts/dgram.m: New function, from R. Bruce Tenison
+	(btenison at eng.auburn.edu).
+	* scripts/dlqe.m: Ditto.
+	* scripts/dlqr.m: Ditto.
+	* scripts/c2d.m: Ditto.
+
+	* src/tree.cc (tree_identifier::name): Make it const.
+	(tree_builtin::name): Ditto.
+	(tree_parameter_list::name): Ditto.
+	(tree_word_list::name): Ditto.
+
+	* src/symtab.cc (symbol_table::save): Delete list of names after
+	saving.
+
+	* src/symtab.h (symbol_table): Move #defines outside of class
+	declaration.
+
+Sun Nov  7 07:03:12 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makeconf.in (CXX): Don't set from C++.  Do set from @CXX@, which
+	is determined by configure.  Don't set C++FLAGS.
+
+	* src/tree.cc: (tree_function::eval (int, int)): Simply call
+	eval (tree_constant *, int, int, int) with nargin = 1 and args =
+	NULL_TREE_CONST instead of duplicating most of that function in place.
+
+	* src/parse.y (func_def2): Reset id_name after renaming identifier.
+	Clear id_name from top level symbol table before defining identifier.
+
+Sat Nov  6 04:38:57 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: When checking for g++, set CXX, not GXX.
+
+	Merge min changes from Bruce Tenison (btenison at eng.auburn.edu) and
+	make the corresponding changes for max.
+
+        * src/tc-extras.cc (min (ComplexMatrix&, ComplexMatrix&)): New
+	function.
+	(max (ComplexMatrix&, ComplexMatrix&)): Ditto.
+	(column_min): Handle complex args and two return values.
+	(column_max): Likewise.
+
+        * liboctave/Matrix.cc (row_min_loc): New function.
+	(row_max_loc): New function.
+	(column_min_loc): Ditto.
+	(column_max_loc): Ditto.
+
+Fri Nov  5 03:12:55 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.78.
+
+	* src/octave.h (clean_up_and_exit): Change form of declaration for
+	GCC 2.5.x and beyond.
+
+	* src/tree.cc (tree_identifier::eval): Correctly handle printing
+	of identifier tags and conversion to assignment to `ans'.
+	* src/parse.y (maybe_convert_to_ans_assign): Simplify.
+	For identifiers, defer decision about making an ans assignment
+	until evaluation time since identifiers can be undefined at parse
+	time, and we can't tell what to do until we know what the def is.
+	* src/tree.cc (tree_identifier::mark_for_possible_ans_assgin): New
+	function.
+	* src/tree.cc (tree_index_expression::mark_for_possible_ans_assign):
+	New function.
+	* src/tree.h (tree_identifier): Add new private data,
+	maybe_do_ans_assign.
+
+	* src/t-builtins.cc (builtin_who): Major overhaul.  Support long
+	listings.
+	(print_symbol_info_line): New function.
+	(print_long_listing): Ditto.
+	(maybe_list): Ditto.
+
+	* src/user-prefs.cc (sv_editor): New function for builtin variable
+	EDITOR.
+	* src/octave-hist.cc (do_edit_history): Use user_pref.editor, not
+	just the EDITOR environment variable.
+
+	* src/user-prefs.cc (ignore_function_time_stamp): New function for
+	new builtin variable ignore_function_time_stamp.
+	* src/variables.cc (symbol_out_of_date): Use value of new
+	user_pref.ignore_function_time_stamp to decide whether to check to
+	see if a file has changed.
+	* src/tree.h (tree_function): Add new private data, system_m_file.
+
+	* src/builtins.cc (string_variables): Add EDITOR and
+	ignore_function_time_stamp EDITOR to the list.
+	(bultin_general_functions): Add is_global to the list.
+
+	* src/t-builtins.cc (builtin_clear): Make it work with new
+	variable scoping rules.
+	(builtin_document): Likewise, using new document_symbol()
+	function.
+	(builtin_save): Likewise.  Allow regular expression arguments.
+	Don't save builtin variables that are read-only.
+
+	* src/utils.cc (octave_home): Don't declare static.
+	(octave_lib_dir): Likewise.
+	(octave_info_dir): Likewise.
+	(default_editor): New function.
+
+	* src/tree.cc (tree_builtin::def): Delete function.
+	(tree_identifier::def): Likewise.
+	(tree_identifier::symrec): Likewise.
+
+	* src/tree.h (tree_builtin): Store name of function, not pointer
+	to symbol record.
+
+	* src/user-prefs.cc (warn_assign_as_truth_value): Lookup
+	"warn_assign_as_truth_value", not "user_pref.warn...".
+
+	* src/tree-base.h (def): Delete unused virtual function.
+	(is_prefix_expression): New virtual function.
+	(mark_for_possible_ans_assign): Likewise.
+	(is_system_m_file): Likewise.
+	(stash_m_file_name): No longer needs to be virtual.
+	(stash_m_file_time): Likewise.
+
+	* src/octave.cc (octave_Complex_error_handler): Define, to keep
+	errors in the Complex class from aborting Octave.  This is only a
+	temporary fix, I hope.
+	(main): Install it.
+	(initialize_globals): Get default editor.
+	(main): Call initialize_symbol_tables to do that instead of
+	creating them directly in main.
+
+	* src/variables.cc (document_symbol): New function.
+	(initialize_symbol_tables): Likewise.
+	(install_builtin_mapper_function): Likewise.
+	(install_builtin_text_function): Likewise.
+	(install_builtin_general_function): Likewise.
+	(install_builtin_variable): Likewise.
+	(install_builtin_variable_as_function): Likewise.
+	(bind_nargin_and_nargout): Likewise.
+	(bind_builtin_variable): Likewise.
+	(link_to_global_variable): Likewise.
+	(link_to_builtin_variable): Likewise.
+	(link_to_builtin_or_function): Likewise.
+	(force_link_to_function): Likewise.
+	(is_globally_visible): Likewise.
+	(is_builtin_variable): Likewise.
+
+	* src/tree.cc (print_as_scalar): Avoid trying to print row vectors
+	on one line.
+
+	* src/builtins.cc (install_buitlins): Simplify installation of
+	builtin functions using new install_builtin_*_function functions.
+	Ditto for using bind_builtin_variable for installing variables.
+
+	* src/tree.h (tree_global_command): New class.
+	* src/tree.cc (tree_global_command::*): Implement new class to
+	make global command executable.
+	* src/parse.y (global_decl): Make global an executable statement.
+
+	* src/parse.y (func_def2): Rework to match new way of handling
+	global variables and function names in the symbol table.
+	Mark functions as `system' or not.
+	Don't use id_to_define.
+	If m-file and function names disagree, rename function to match
+	m-file name.
+	* src/tree.cc (tree_identifier::rename): New function.
+	* src/parse.cc, src/parse.h (id_to_define): Delete unused global
+	variable.
+
+	* src/varables.cc (builtin_string_variable): Fix to match new
+	rules for global and builtin variables.
+	(builtin_real_scalar_variable): Likewise.
+
+	* src/tree.cc (tree_identifier::assign): Make it work with new
+	rules for global variables.
+	(tree_identifier::parse_m_file): Likewise.
+	(tree_identifier::do_lookup): Likewise.
+
+	* src/tree.cc (mark_as_system_m_file): New function.
+	(is_system_m_file): Ditto.
+
+	* src/tree.cc (clear_symbol_table): New function, to be used in an
+	unwined_protect element for clearing function symbol tables on
+	exit or error.
+
+	* src/tree.cc (tree_function::eval): Simplify using
+	bind_nargin_and_nargout.
+	Clear symbol table on exit or error with unwind_protect.
+
+	* src/tree.cc (tree_prefix_expression::is_prefix_expression): New
+	function.
+
+	* src/g-builtins.cc (builtin_is_global): New function.
+
+	* src/lex.l (lookup_identifier): Now that global variable binding
+	has been fixed, only look for symbols in the current symbol table.
+	Really.  I mean it this time.
+
+	* src/symtab.cc: Complete overhaul, to make global variables work
+	a bit more reasonably.
+
+Mon Nov  1 15:03:39 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/Matrix.h (DiagMatrix::rows): Return nr, not len.
+	(ComplexDiagMatrix::rows): Ditto.
+	* src/Matrix.h (DiagMatrix::cols): Return nc, not len.
+	(ComplexDiagMatrix::cols): Ditto.
+	(DiagMatrix::columns): Ditto.
+	(ComplexDiagMatrix::columns): Ditto.
+
+	* liboctave/DiagMatrix.cc (DiagMatrix::row): Make it work for
+	square case.
+	(DiagMatrix::column): Likewise.
+	(ComplexDiagMatrix::row): Likewise.
+	(ComplexDiagMatrix::column): Likewise.
+
+	* liboctave/DiagMatrix.cc (DiagMatrix::operator <<): Print spaces
+	between elements.
+	(ComplexDiagMatrix::operator <<): Likewise.
+
+Fri Oct 29 15:32:12 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.77.1.
+
+	* src/symtab.cc (symbol_record::alias): Don't copy formal_param or
+	forced_global attribute.
+
+	* src/symtabl.cc (symbol_table::bind_globals): Don't bind to
+	global symbol unless it has forced_global attribute set.
+
+	* src/tree.cc (print_as_scalar): New function.
+	(tree_identifier::eval): Use it.
+	(tree_simple_assignment_expression::eval): Likewise.
+	(tree_multi_assignment_expression::eval): Likewise.
+
+	* src/lex.l (is_keyword): Give better error message for attempts
+	to define nested functions.
+
+	* src/parse.y (global_decl): Return a command_list to execute
+	(this makes assignments in global declarations executable).
+
+	* src/tree.cc (tree_for_command): Handle line and column info in
+	constructors and for error messages.
+	(tree_while_command): Ditto.
+	(tree_if_command): Ditto.
+	(tree_break_command): Ditto.
+	(tree_continue_command): Ditto.
+	(tree_return_command): Ditto.
+	(*::eval_error): Only print messages if error_state > 0.
+	(various): Only need to check that error_state is non-zero before
+	calling eval_error().
+
+	* src/parse.y: Handle line and column information for FOR WHILE IF
+	ELSEIF ELSE BREAK CONTINUE and FUNC_RET tokens.
+	* src/lex.l: Likewise.
+
+	* src/octave.cc (parse_and_execute): Reset parser before starting
+	new parse.
+
+	* src/tree-plot.cc (various): Check error_state in many more
+	places, and issue more meaningful error messages.
+
+	* src/tree-const.cc (maybe_resize): Don't call
+	jump_to_top_level() on errors.
+	(tree_constant_rep (Range)): Likewise.
+
+	* src/g-builtins.cc (builtin_error): Use error(), not
+	print_if_string() to print error messages.
+	* src/tree-const.cc (print_if_string): Delete unused function.
+
+	* src/tc-assign.cc (various): Check error_state after calls to
+	maybe_resize().
+
+	* src/tc-index.cc (various): Always check the state of idx_vectors
+	after trying to create them.
+	* src/tc-assign.cc (various): Likewise.
+
+	* src/idx-vector.cc: Use 0, not NULL.
+	Don't include stdlib.h.
+	(initialized): New data member, set nonzero if the idx_vector has
+	been properly initialized.
+	Never call jump_to_top_level () if initialization fails.
+	Add operator void *(), so we can test the state of an idx_vector
+	with `if (vector)'.
+
+	* src/pager.cc: Explicitly initialize pager_buf to NULL.
+
+	* src/tree-base.h: Move includes ahead of other definitions.
+
+	* liboctave/NLEqn.cc (NLEqn::NLEqn (const Vector&, const NLFunc)):
+	Initialize n from xvec, not x.
+
+Mon Oct 25 18:01:12 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/user-prefs.cc (sv_info_file): New function.
+	* src/user-prefs.h (user_pref): Add info_file to the list.
+	* src/t-builtins.cc (try_info): Use it instead of
+	DEFAULT_INFO_FILE.
+
+	* src/utils.cc (default_info_file): New function.
+	(octave_info_dir): Likewise.
+
+	* src/defaults.h.in (DEFAULT_INFO_FILE): Delete unnecessary
+	definition since we figure out what it should be in utils.cc now.
+	* src/Makefile.in (defaults.h): Don't substitute DEFAULT_INFO_FILE.
+	* src/Makeconf.in (DEFAULT_INFO_FILE): Delete definition.
+
+	* src/octave.cc (info_file): New global variable.
+	(initialize_globals): Call default_info_file () to initialize it.
+	(--info-file): New command line option.
+
+	* src/builtins.cc (string_variables): Add INFO_FILE to the list.
+	(install_builtins): Define it.
+
+	* info/filesys.c (compress_suffixes): Choose gunzip for .gz files.
+
+Sat Oct 23 17:46:09 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.77 released.
+
+	* src/Makefile.in (INCFLAGS): Don't include info or dld
+	directories.
+	* dynamic-ld.cc: Include dld/dld.h, not just dld.h.
+	* t-buitlins.cc: Include info/info.h, info/dribble.h, and
+	info/terminal.h, not just info.h, dribble.h, and terminal.h.
+
+	* src/t-builtins.cc (builtin_help): New option, -i, for invoking
+	info browser.  If -i is not given, just do what we used to do, but
+	point to help -i as a way to get additional information.
+
+	* builtins.cc (print_usage): New function.
+
+	* g-builtins.cc (all builtins): Call print_usage to get usage message.
+	* t-builtins.cc (all builtins): Likewise.
+
+Fri Oct 22 15:56:16 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Cholesky changes from R. Bruce Tenison (btenison at eng.auburn.edu):
+
+	* src/f-chol.cc, src/f-chol.h: New files for the Cholesky
+	Factorization.
+	* src/Makefile.in (SOURCES, OBJECTS, DLD_OBJECTS): Add to lists.
+	* src/g-builtins.cc (builtin_chol): New function.
+	* src/g-builtins.h: Declare it.
+
+	* liboctave/Matrix-ext.cc (CHOL, ComplexCHOL): New classes.
+
+	* libcruft/lapack: dpotrf.f, zpotrf.f, dpotf2.f, zpotf2.f: New
+	files.
+
+	* libcruft/blas: dsyrk.f, zherk.f: New files.
+
+Fri Oct 22 14:04:16 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/g-builtins.cc (builtin_schur): Fourth arg for DLD_BUILTIN is
+	schur, not hess.
+
+	* scripts/dare.m: Correct usage of fprintf.
+
+	* src/utils.cc (raw_mode): Only complain about stdin not a tty if
+	interactive or forced interactive.
+
+Thu Oct 21 17:00:57 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/builtins.cc (install_builtins): Try harder to make
+	initialization of NaN work.  Make note about possible fixes if it
+	still doesn't work.
+
+	* src/utils.cc (raw_mode): [HAVE_TERMIOS_H] and [HAVE_TERMIO_H]
+	Don't set TAB3 since it doesn't seem necessary and some systems
+	don't have it by this name.
+	[HAVE_SGTTY_H] To be consistent, don't set XTABS here either.
+
+	* src/error.c (error): Call flush_output_to_pager before printing
+	error message.
+	(panic): Likewise, before aborting.
+
+	* src/symtab.cc (symbol_record::undefine): Delete unused function.
+	(symbol_table::undefine): Likewise.
+
+	* src/symtab.cc (clear): Never delete symbol records from the
+	table.  Only delete the definitions.  This makes clear and
+	undefine equivalent, so we don't need them
+	* src/tree.cc (tree_function::eval): Call symbol_table::clear, not
+	symbol_table::undefine.
+
+	* src/t-builtins.cc (builtin_clear): Only clear global symbols if
+	we are at the top level.
+	* src/parse.y (CLEAR): Delete token.
+	(word_list_command): Remove code to handle CLEAR as special case.
+	(expect): Only 19 now.
+	* src/lex.l (handle_identifier): Remove special code for clear.
+	It's ok to use it in a function body now.
+
+	* src/t-builtins.cc: Include extern "C" declarations for Info stuff.
+	(builtin_help): If given an argument, try to get help directly
+	from info file first.  If that fails, do as before.
+	(help_syms_list): New function:
+	(simple_help): New function.
+	(try_info): New function.
+	(help_from_list): New function.
+
+	* src/defaults.h.in (DEFAULT_INFO_FILE): Define new macro.
+	* Makeconf.in: Set value of DEFAULT_INFO_FILE.
+	* Makeconf.in (INSTALL_PROGRAM): Add definition.
+	* Makefile.in (SUBDIRS): Add info directory.
+	(info): New target.
+	* configure.in: Add autoconf macros to handle info configuration.
+
+	* info/Makefile.in: Major changes to make it work with Octave's
+	Makeconf file, etc.  The default action is now to build a
+	libinfo.a file.
+
+	* info/error.c: New file.  Move error functions here from info.c.
+
+	* info/signals.c (clear_info_signal_handler): New function, useful
+	if info is used directly in another program.
+
+	* info/termdep.h: Handle termios too.
+	* info/terminal.c (terminal_prep_terminal): Handle termios.
+	* (terminal_unprep_terminal): Likewise
+
+	* info/session.c (initialize_info_session): Add arg to make
+	clearing the screen conditional.  Useful if we want to call
+	index_entry_exists() first before displaying anything.
+	Change all callers.
+
+	* info/session.c (finish_info_session): New function.
+
+	* info/session.c (dispatch_error): Change message to include info
+	about how to get help and how to quit.
+
+	* info/info.c (index_search_p): New flag.
+	(--index-search): New option, like apropos, but search the indices
+	and display the first node found.
+
+	* info/indices.c (do_info_index_search): New function, modified
+	from info_index_search to allow searching the index for a string
+	without prompting for it.
+	(info_index_search): Just call do_info_index_search.
+	(index_entry_exists): New function, to allow us to find out if
+	there is an index entry for a given string without actually
+	displaying anything.
+
+	* info: New directory, containing source for GNU info browser.
+
+Tue Oct 19 00:14:33 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/octave-hist.cc (input_from_tmp_history_file): New global flag.
+	(do_edit_history): Protect and set it.
+	(do_run_history): Likewise.
+	* src/parse.y (func_def2): Use it to see that input is coming from
+	a temporary file.  This means that we shouldn't exit when we're
+	done reading it, and we should treat it just as if the input were
+	coming from the keyboard.
+
+	* variables.cc (force_global): Force aliasing so it will happen
+	even if the symbol record is undefined.
+
+	* src/lex.l (lookup_identifier): Simplify
+
+	* src/lex.l (reset_parser): Reset error_state here.
+	* src/octave.cc (main): Not here.
+
+Mon Oct 18 14:27:02 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-const.cc: Delete constructor for tree_constant from
+	String.
+
+	* In src: tree.h, mappers.h, unwind-prot.h, parse.h, file-io.h,
+	arith-ops.h, tree-base.h, tree-const.h, g-builtins.h,
+	idx-vector.h, builtins.h, dynamic-ld.h, xdiv.h, xpow.h,
+	pr-output.h, input.h, symtab.h, utils.h: Avoid including files
+	unnecessarily.
+
+	* In src: tc-inlines.cc, mappers.cc, variables.cc, arith-ops.cc,
+	tree.cc, tree-const.cc, g-builtins.cc, file-io.cc, idx-vector.cc,
+	tc-assign.cc, tc-index.cc, builtins.cc, dynamic-ld.cc, xdiv.cc,
+	xpow.cc, pr-output.cc, tc-extras.cc, input.cc, symtab.cc,
+	utils.cc: Sprinkle liberally with const.
+
+	* In src: f-syl.cc, f-svd.cc, f-schur.cc, f-rand.cc, f-qzval.cc,
+	f-quad.cc, f-qr.cc, f-qpsol.cc, f-npsol.cc, f-lu.cc,
+	f-lsode.cc, f-lpsolve.cc, f-inv.cc, f-ifft.cc, f-hess.cc,
+	f-givens.cc, f-fsqp.cc, f-fsolve.cc, f-fft.cc, f-expm.cc,
+	f-eig.cc, f-det.cc, f-dassl.cc, f-colloc.cc, f-balance.cc:
+	Add const qualifier to tree-constant arg.
+
+Sat Oct 16 12:22:24 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-const.h, src/tree-const.cc: Add const qualifier to
+	constructor arguments passed by reference.
+	Pass Complex arguments by const reference instead of by value.
+
+	* liboctave/Matrix.h, liboctave/Matrix.cc, liboctave/ColVector.cc,
+	liboctave/RowVector.cc liboctave/DiagMatrix.cc: Pass Complex
+	arguments by const reference instead of by value.
+
+Wed Oct 13 14:13:29 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/utils.cc (decode_prompt_string): ctime returns time_t, which
+	might not be a long.
+
+	* src/variables.cc (identifier_exists):	Only return non-zero if
+	the name has a definition.
+
+	* src/f-npsol.cc (npsol): Call error(), not message(), to print
+	error messages.
+	(linear_constraints_ok): Likewise.
+	(nonlinear_constraints_ok): Likewise.
+
+	* src/f-qpsol.cc (qpsol): Don't try to create the linear
+	constraint object before checking array sizes.  Wouldn't exception
+	handling be nice?
+	Call error(), not message(), to print error messages.
+	Check to ensure that the bounds on linear constraints are
+	vectors.
+
+	* src/lex.l (lookup_identifier): Don't bind global variables
+	immediately in loops or conditionals, even at the top level.
+
+Sun Oct 10 8:48:00 1993  John Eaton  (jwe at schoch.che.utexas.edu)
+
+	* README.doc: New file.
+	* Makefile.in (doc-dist): New target.
+	* doc/Makefile.in (FORMATTED): New macro.
+	(doc-dist): New target.
+
+	* src/tree.cc (tree_identifier::eval): Don't print anything if an
+	error is encountered.
+	(tree_simple_assignment_expression::eval): Likewise.
+
+	* src/tc-assign.cc (do_matrix_assignment): Handle resizing
+	correctly when indices are (:,range), (:,matrix), (range,:), or
+	(matrix,:) and the lhs is empty or undefined.
+
+Tue Oct  5 04:02:37 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.76 released.
+
+	* src/octave.cc (main):	Print usage message if we are given more
+	than one extra argument on the command line.
+	Delay printing startup message until just before setting the toplevel
+	jump context.
+
+	* src/lex.h (DO_COMMA_INSERT_CHECK): Delete unused macro.
+
+	* src/lex.l (handle_identifier): New function.
+	({IDENT}/{S}*=, {IDENT}{S}*): Use it instead of duplicating code.
+	(do_comma_insert_check): Use yyunput instad of returning original
+	character count.
+	Call directly instead of using DO_COMMA_INSERT_CHECK macro.
+
+Mon Oct  4 08:06:10 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.75.4.
+
+	* src/tree-const.cc (tree_constant_rep::eval ()): Avoid calling
+	rows() and columns() for things like magic_colon.
+
+Sun Oct  3 19:39:33 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	Changes to add line and column info to run-time error messages:
+
+	* src/tree.cc (tree_identifier, tree_prefix_expression,
+	tree_postfix_expression, tree_simple_assignment_expression,
+	tree_multi_assignment_expression, tree_colon_expression,
+	tree_index_expression): Modify constructors to allow line and
+	column information to be stored.
+	(abort_on_undefined): Delete (now) unnecessary static variable.
+	(all eval() functions): If error_state, return immediately.
+	(tree_matrix::eval ()): Call error and return tree_constant()
+	instead of jumping to top level on error.
+	(tree_identifier::parse_m_file ()): When starting to read an
+	M-file, initialize current_input_column to 1, not 0.
+	(tree_identifier::eval_undefined_error ()): Improve error message
+	with line and column info if it is available.  Don't abort to top
+	level on errors.
+	(tree_function::traceback_error ()): New function.
+	(tree_function::eval ()): Don't jump to top level on errors.
+	Call traceback_error if there is an error evaluating the command
+	list.
+
+	* src/tree.cc (tree_prefix_expression::eval_error ()): New function.
+	(tree_postfix_expression::eval_error ()): Ditto.
+	(tree_unary_expression::eval_error ()): Ditto.
+	(tree_binary_expression::eval_error ()): Ditto.
+	(tree_simple_assignment_expression::eval_error ()): Ditto.
+	(tree_multi_assignment_expression::eval_error ()): Ditto.
+	(tree_colon_expression::eval_error ()): Ditto.
+	(tree_index_expression::eval_error ()): Ditto.
+
+	* src/tree.cc (tree_function::stash_function_name ()): New function.
+	* src/parse.y (FCN): Use it.
+
+	* src/lex.l: Return line and column info for many (but not all)
+	tokens.
+
+	* src/parse.y: Handle token values with the token class defined in
+	token.cc.
+	(check_end ()): New function.
+	(end_error ()): Improve error messages by including line and
+	column info.
+
+	* src/arith-ops.cc (lots of functions): Don't jump to top level on
+	errors.
+	* src/tree.cc (tree_unary_expression::eval ()),
+	tree_binary_expression::eval ()): Handle error condition here.
+
+	* src/gripes.cc (gripe_nonconformant): Add additional form of this
+	function to allow message to include dimensions.  Change most
+	callers to use new form
+
+	* src/octave.cc: Initialize column counter to 1, not 0.
+	(main): Reset error_state before evaluating each top level
+	command.
+
+	* src/tree-plot.cc (tree_plot_command::eval ()): If error_state,
+	return immediately.
+
+	* src/tree-const.cc (do_binary_op ()): Return tree_constant() instead
+	of jumping to top level on errors.
+	(do_unary_op): Likewise.
+	(tree_constant_rep::eval ()): If error_state, return immediately.
+	Convert 1x1 matrices to scalars.
+
+	* src/tc-assign.cc (tree_constant_rep::do_scalar_assignment ()):
+	Don't jump to top level on error.
+	If there is an error while attempting to convert an undefined
+	variable to a matrix, don't suddenly create an empty matrix.
+	(tree_constant_rep::fortran_style_matrix_assignment ()): Check
+	return value of range_max_check() and don't jumpt to top level on
+	errors.
+	(tree_constant_rep::vector_assignment ()): Check return value of
+	index_check and don't jump to top level on errors.
+	(tree_constant_rep::check_vector_assign ()): Don't jump to top
+	level on errors.
+	(tree_constant_rep::do_matrix_assignment ()): Check return value
+	of index_check and don't jump to top level on errors.
+
+	* src/tc-extras.cc (get_dimensions ()): Call error (sets error state)
+	but don't jump to top level on errors.
+	(fill_matrix): Return tree_constant() on error.
+	(identity_matrix): Likewise.
+
+	* src/error.cc (error_state): New global variable, initialize to zero.
+	(error): Set it to one.
+
+	* src/tc-index.cc (tree_constant_rep::valid_as_scalar_index ()):
+	Don't declare unused variable retval.
+	(tree_constant_rep::do_scalar_index ()): Return tree_constant()
+	instead of jumping to top level on error.
+	(tree_constant_rep::fortran_style_matrix_index): Don't jump to top
+	level on indexing or range errors.
+	(tree_constant_rep::do_vector_index ()): Likewise.
+	(tree_constant_rep::do_matrix_index ()): Likewise.
+
+	* src/tc-inlines (range_max_check): Return -1 instead of jumping
+	to top level on error.
+	(index_check): Likewise.
+
+	* src/utils.cc (check_dimensions): Call error, not warning, and
+	don't jump to top level.
+
+	* src/tree-base.h (line_num, column_num): New data members for all
+	tree classes.
+	(line (), column ()): New virtual functions to access line and
+	column info.
+
+	* src/lex.l (enum end_tok_type, enum plot_tok_type): Delete
+	declarations (now in token.h).
+
+	* src/lex.h (YY_INPUT, YY_FATAL_ERROR, DO_COMMA_INSERT_CHECK,
+	TOK_RETURN, BIN_OP_RETURN): Move macro definition here, from
+	lex.l.  Rename RETURN TOK_RETURN.
+
+	* src/token.cc, token.h: New files that define a class for tokens
+	that includes line and column information.
+
+Wed Sep 29 11:15:12 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/octave.cc: Use GNU getopt to handle option parsing.
+	* src/getopt.h src/getopt.c src/getopt1.c: New files for GNU
+	getopt.
+	* src/Makefile.in: Add them to the appropriate lists.
+
+	* src/utils.cc (raw_mode): Use the termios.h terminal driver
+	interface if it is available.
+	* configure.in: Check for termios.h
+
+	* src/tree-plot.cc (tree_subplot_list::print (int, ostrstream&)):
+	If the data to be plotted is a string but it doesn't name a file,
+	try sending it to gnuplot directly.
+
+Tue Sep 28 16:06:42 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/QPSOL.cc (QPSOL::minimize (double&, int&, Vector&)):
+	Correct dimensions of work arrays, based on QPSOL source.
+	Pass ncon, which is max (1, nclin), not n, as the row dimension of
+	clin.
+
+	* src/f-npsol.cc (linear_constraints_ok): Improve warning for the
+	case of constraints with zero dimensions.
+	(nonlinear_constraints_ok): Likewise.
+
+Mon Sep 27 01:20:50 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.75.3.
+
+	* Makefile.in (dist): Make file permissions for distribution rw.
+	(binary-dist): Ditto.
+	(local-dist): Ditto.
+
+Sat Sep 25 15:29:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/pr-output.cc: Include stdio.h, for sprintf.
+
+	* src/input.cc (octave_gets): Set octave_gets_line to NULL after
+	freeing it.
+
+	* Version 0.75.2.
+
+	* liboctave/Matrix.cc (Matrix::operator * (const ColumnVector&):
+	Correct dimension of return value.
+	(ComplexMatrix::operator * (const ComplexColumnVector&)): Ditto.
+
+Tue Sep 21 20:42:10 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree.cc (tree_identifier::assign (tree_constant&)):
+	Correctly handle case of hiding a function with a variable when
+	the variable has not been flagged as global.
+	tree_identifier::assign (tree_constant&, tree_constant*, int)):
+	Likewise.
+
+	* src/variables.cc (force_global): When a variable is moved to the
+	global symbol table, mark it as global.
+
+	* src/symtab.cc (symbol_record::symbol_record ()): Initialize
+	forced_global.
+	(symbol_record::clear_visible ()): Reset forced_global to zero.
+	(symbol_record::clear_all ()): Ditto.
+	(symbol_record::mark_as_forced_global ()): New function.
+	(symbol_record::is_forced_global ()): New function.
+	(symbol_record::alias ()): Also copy forced_global attribute.
+
+	* src/symtab.h (symbol_record::forced_global): New private data
+	member, used to record when a variable has been explicitly
+	declared global.
+
+	* src/lex.l (lookup_identifier): Look in current scope first.
+
+Mon Sep 20 03:15:52 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/parse.y, src/tree.cc, src/tree.h: Allow `for' command to
+	assign to an index expression, not just an identifier.
+
+	* src/t-builtins.cc (builtin_clear (int, char **)): Don't delete
+	g_names twice.
+
+	* src/symtab.cc	(symbol_table::list (int&)): Make sure count is
+	initialized to zero.
+	(symbol_table::var_list (int&)): Ditto.
+	(symbol_table::fcn_list (int&)): Ditto.
+
+Sat Sep 18 04:06:42 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/lex.l, src/parse.y, src/parse.h: Use new global variable
+	past_plot_range to make gplot and gsplot smarter about
+	distinguishing plot ranges and literal matrices.
+
+Fri Sep 17 01:06:30 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.75.1 released.
+
+	* src/f-qzval.cc: Include <float.h> for DBL_EPSILON.
+
+	* src/symtab.cc (symbol_record::save (ostream&, int)): Don't print
+	a warning for ans being undefined.  Call warning to print the
+	message, and change the text to make it clearer.
+	(symbol_table::save (ostream&, int)): Don't crash if there aren't
+	any symbols to save.
+
+Thu Sep 16 00:21:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/t-builtins.cc (builtin_help): When trying harder to find
+	help for M-files, only insert the symbol into the global symbol
+	table if there really is an M-file of the given name in the path.
+
+Wed Sep 15 02:08:27 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.75.
+
+	* src/Makefile.in (INCLUDES): Distribute defaults.h
+	(%.d: %.cc): Don't fail if we can't determine dependencies.
+	(DISTFILES): Include move-if-change.
+
+Tue Sep 14 21:23:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/perror.m: Use err, not info for fsolve section.
+
+Mon Sep 13 19:29:26 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/utils.cc (get_m_file_names): Call closedir(), not free(), to
+	dispose of directory structure.
+
+Sun Sep 12 19:07:36 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-const.cc (tree_constant_rep::double_value): Rearrange
+	to avoid warning about reaching end of non-void function.
+	(tree_constant_rep::matrix_value): Ditto.
+
+	* src/error.cc (panic): Declare volatile.
+	* src/utils.cc (jump_to_top_level): Declare as `void volatile',
+	not `volatile void'.
+
+	* src/tree-const.cc (tree_constant_rep::complex_matrix_value):
+	Make it work even if the internal representation is really a real
+	or complex scalar or a real matrix.
+	(tree_constant_rep::complex_scalar_value): Make it work even if
+	the internal representation is really a real scalar.
+
+	* src/f-syl.cc (syl): Delete ComplexMatrixLoad().
+	Use complex_matrix_value(), not ComplexMatrixLoad().
+
+	* src/tree-const.cc (vector_of_empties): Renamed from empty_tree,
+	moved from f-syl.cc.
+
+	* src/f-syl.cc (syl): Call vector_of_empties() instead of empty_tree().
+	* src/f-qzval.cc (qzvalue): Ditto.
+
+	* src/tree-const.h (tree_constant::is_empty): New inline function.
+
+	* src/f-syl.cc (syl): Call is_empty instead of empty_arg.
+	* src/f-qzval.cc (qzvalue): Ditto.
+	* src/f-expm.cc (matrix_exp): Ditto.
+
+Thu Sep  9 22:40:16 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/Matrix.cc (Matrix::transpose): Make it work for empty
+	matrices.
+	(ComplexMatrix::transpose): Ditto.
+
+Mon Sep  6 04:56:50 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/tree-plot.cc (tree_subplot_list::print): 	If the plot data
+	is a string and it names a file, plot the data in the file.
+
+	* src/octave.cc (execute_startup_files): Try harder to avoid
+	executing $HOME/.octaverc twice.
+
+	* liboctave/DAE.cc (DAE::integrate (Vector&, Matrix&, Vector&)):
+	Add missing parameter in call to integrate() if no critical points
+	are specified.
+
+Sat Sep  4 16:18:49 1993  John W. Eaton  (jwe at ward.che.utexas.edu)
+
+	* src/octave.cc (execute_startup_files): Don't execute
+	$HOME/.octaverc twice.
+
+Mon Aug 30 11:25:12 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/t-builtins.cc (builtin_clear): Handle regular expressions.
+
+Fri Aug 27 07:25:32 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/RowVector.cc:
+	(RowVector::operator * (const ColumnVector& a) const): Fix brain-o.
+
+Wed Aug 18 00:29:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* list_primes.m: New M-file.
+
+	* src/tc-index.cc (do_scalar_index): Handle two vector args of all
+	ones.
+
+Tue Aug 17 06:26:04 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/file-io.cc (process_printf_format): Use NINT for * modifier
+	argument.
+
+Mon Aug 16 19:30:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/mappers.cc: (arg (double)): Return pi for negative real values.
+
+Sun Aug 15 05:08:48 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/octave-hist.cc (mk_tmp_hist_file): New function, extracted
+	from do_edit_history.
+	(do_edit_history): Simplify using mk_tmp_hist_file.
+	(do_run_history): New function.
+	(edit_history_repl_hist): New function.
+
+	* src/t-builtins.cc (builtin_run_history): New function.
+
+	* src/builtins.cc (text_functions): Add run_history to the list.
+
+Fri Aug 13 16:04:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tzero.m: New M-file.
+	* abcdchk.m: New M-file.
+	* is_symmetric.m: Use tol and norm (A) to decide if A' is close
+	enough to A to be considered the same.
+
+Wed Aug 11 15:50:59 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.74.1.
+
+	Merge in expm changes from A. S. Hodel <scotte at eng.auburn.edu>:
+
+	* f-expm.{h,cc}: New files.
+	* src/Makefile.in: Include them in the usual places.
+	* src/g-builtins.cc (builtin_expm): The new matrix_exp returns a
+	tree_constant by value.
+	Include f-expm.h
+	* src/tc-extras.cc (matrix_exp): Delete function.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	Merge in qzval changes from A. S. Hodel <scotte at eng.auburn.edu>:
+
+	* f-qzval.{h,cc}: New files.
+	* src/Makefile.in: Include them in the usual places.
+	* src/g-builtins.cc (builtin_qzval): New function.
+	Include f-qzval.h
+	* src/g-builtins.h: Declare builtin_qzval.
+	* src/builtins.cc (general_functions): Add qzval to the list.
+
+	* libcruft/eispack: New directory.
+	* libcruft/Makefile.in (SUBDIRS): Include it.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Add libcruft/balgen/Makefile and
+	libcruft/eispack/Makefile to the list of files to frob.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	Merge in syl changes from A. S. Hodel <scotte at eng.auburn.edu>:
+
+	* lyap.m: New M-file.
+
+	* f-syl.{h,cc}: New files.
+	* src/Makefile.in: Include them in the usual places.
+	* src/g-builtins.cc (builtin_syl): New function.
+	Include f-syl.h
+	* src/g-builtins.h: Declare builtin_syl.
+	* src/builtins.cc (general_functions): Add syl to the list.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/g-builtins.cc (builtin_balance): Fix typo in doc string.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	Merge in givens changes from A. S. Hodel <scotte at eng.auburn.edu>:
+
+	* f-givens.{h,cc}: New files.
+	* src/Makefile.in: Include them in the usual places.
+	* src/g-builtins.cc (builtin_givens): New function.
+	Include f-givens.h
+	* src/g-builtins.h: Declare builtin_givens.
+	* src/builtins.cc (general_functions): Add givens to the list.
+
+	* src/Makefile.in: (defaults.h) Quote substitutions.
+	Use %foo%, not @foo@ to mark substitution.
+	* src/defaults.h.in: Use %foo%, no @foo@ to do mark things to
+	substitute.
+
+	* qzhess.m: New M-file.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	Merge in balance changes from A. S. Hodel <scotte at eng.auburn.edu>:
+
+	* are, is_controllable.m, is_observable.m, is_square.m,
+	is_symmetric.m:  New M-files.
+
+	* Matrix.h (AEPBALANCE): New class.
+	(ComplexAEPBALANCE): New class.
+	(GEPBALANCE): New class.
+	* Matrix-ext.cc: Add init functions for balancing classes.
+
+	* src/f-balance.{h,cc}: New files.
+	* src/Makefile.in: Include them in the usual places.
+	* src/g-builtins.cc (builtin_balance): New function.
+	Include f-givens.h
+	* src/g-builtins.h: Declare builtin_balance.
+	* src/builtins.cc (general_functions): Add balance to the list.
+
+	* libcruft/balgen: New directory.
+	* libcruft/Makefile.in (SUBDIRS): Include it.
+
+Tue Aug 10 20:06:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Use AC_HAVE_LIBRARY to check for -lm.
+
+	* src/Makefile.in (defaults.h): Quote substitutions.
+
+Mon Aug  9 13:30:07 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* README.NLP: New file.
+	* Makefile.in (DISTFILES): Distribute it.
+
+Sun Aug  8 19:05:48 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/move-if-change: New file.
+	* src/Makefile.in (DISTFILES): Distribute it.
+	(defaults.h): New rule.
+	(utils.o): Delete rule, since extra defines are no longer needed.
+	(INCLUDES): Distribute defaults.h.in.
+	* src/utils.cc: Include defaults.h to get DEFAULT_PAGER and
+	OCTAVE_HOME instead of depending on having them defined by the
+	compile command.
+
+	* configure.in (DEFAULT_PAGER): Use AC_PROGRAMS_CHECK.
+	If we find less, add `-e' flag, so users won't have to type q to
+	quit paging.
+
+Sat Aug  7 13:34:06 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* f-*.cc: Renamed from tc-*.cc.  (Use f- as the file prefix
+	because most of these functions are ultimately implemented in
+	Fortran, and, most importantly, it keeps them grouped together.)
+	* f-*.h: New files, for external declarations of visible functions
+	defined in f-*.cc.
+	* g-builtins.cc: Include them all.
+	* tree-const.h: Don't declare these functions as friends.
+	* Makefile.in: Cope with new names.
+
+	* octave.cc (parse_and_execute (char *, int)): Don't declare static.
+	* octave.h: Declare it extern here.
+	* octave-hist.cc (do_edit_history): Use it here.
+
+	* octave-hist.cc (do_edit_history): New function.
+	* t-builtins.cc (builtin_edit_history): Use it.
+
+	* t-builtins.cc, t-builtins.h, builtins.cc: Rename edit to
+	edit_history.
+
+	* octave-hist.cc (do_history): Print line numbers by default.
+	Allow quieter output with -q option.
+
+	* g-builtins.cc (builtin_hess): Use DLD_BUILTIN macro to call hess.
+	* g-builtins.cc (builtin_schur): Likewise
+
+	* tc-hess.cc (builtin_hess_2): Call hess with corrrect args.
+	* tc-schur.cc (builtin_schur_2): Likewise, for schur dude :-).
+
+	* tc-fsqp.cc (builtin_fsqp_2): Fix typo.
+
+Thu Aug  5 23:14:01 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* input.cc (octave_read): Ensure that the last character in the
+	buffer is a new line.
+
+Wed Aug  4 19:25:54 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* parse.y (func_def2): Also warn if we encounter a function
+	definition with the same name as the script file we are reading.
+
+	* tree.cc (tree_identifier::do_lookup): Always return NULL_TREE if
+	a script file was executed.
+
+Tue Aug  3 23:25:45 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* file-io.cc: Delete useless static keyword from File_info class
+	declaration.
+	* unwind-prot.cc: Likewise, for unwind_elem and saved_variable
+	classes.
+	* tc-rand.cc: Likewise, for enum rand_dist declaration.
+	* arith-ops.cc:  Likewise, for enum Matrix_bool_op declaration.
+	* tree.cc: Likewise, for struct const_matrix_list declaration.
+
+Fri Jul 23 01:40:38 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* sysdep.cc (malloc_handler): Add missing arg to call to message().
+
+Tue Jul 20 04:09:32 1993  John W. Eaton  (jwe at june.che.utexas.edu)
+
+	* Version 0.74 released.
+
+	* doinstall.sh (version): Run `./octave -v' to get the version
+	number instead of grabbing it from version.h.
+	* Fail if we can't get a version number.
+	* Install ./octave, not src/octave.
+
+	* Makefile.in (binary-dist): Don't depend on all.
+	* Link src/octave to ./octave.  (Now that there's no source in
+	binary distributions, why have a src directory?)
+
+	* file-io.cc (process_scanf_format): Rename local variable `i' to
+	`chars_from_fmt_str'.
+	* (process_printf_format): Likewise.
+
+	* sighandlers.cc (can_interrupt): New global variable.
+	* (sigint_handler): Use it to decide whether to jump to top level.
+	* octave.cc (main): Set it after calling setjmp.
+
+	* octave.cc (main): Declare saved_sigint_handler to be volatile.
+
+	* tree.cc, tree-plot.cc, t-builtins.cc, pager.cc, g-builtins.cc,
+	file-io.cc: Terminate strstream strings with ends instead of just
+	using '\0'.
+
+	* file-io.cc (process_scanf_format): Skip leading white space for
+	%s conversions.
+	* (fopen_file_for_user): Pass tree_constant arg by reference.
+	* (do_scanf): If doing fprintf, don't fail if first arg is a
+	string.
+
+Mon Jul 19 16:00:22 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* symtab.cc (pstrcmp): Declare to take char** args, not char*.
+
+Sun Jul 18 13:02:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* file-io.cc (return_valid_file): Pass arg by reference.
+
+	* file-io.cc (fclose_internal, fgets_internal, fseek_internal):
+	Eliminate unnecessary casts to double.
+
+	* file-io.cc (return_valid_file, fgets_internal, fopen_internal,
+	do_printf, do_scanf): Use is_string_type instead of doing the
+	comparison ourselves.
+	* g-builtins.cc (builtin_exist, builtin_getenv,
+	builtin_shell_command): Ditto.
+	* tc-colloc.cc (collocation_weights): Ditto.
+	* tc-extras.cc (eval_string, get_user_input): Ditto.
+	* tc-rand.cc (rand_internal): Ditto.
+	* tree-plot.cc (tree_subplot_list::print): Ditto.
+	* variables.cc (is_valid_function, octave_string_variable): Ditto.
+
+Thu Jul 15 02:29:03 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/Makefile.in (TEXINFO): Distribute texinfo.tex too.
+
+	* t-builtins.cc (load_variable): Warn if replacing local symbol
+	with global from file.
+	* Warn if variable is not marked as global in a file, but already
+	exists as a global symbol, then go ahead and load it as a global.
+
+Tue Jul 13 01:47:48 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (lookup_identifier): Never alias to global here.
+	* tree.cc (do_lookup): Don't alias formal parameters to global.
+	* variables.cc (force_global): Likewise.
+	* symtab.cc (symbol_table::bind_globals): Likewise.
+
+	* symtab.h (symbol_record::formal_param): New field.
+	* symtab.cc (symbol_record::mark_as_global_parameter): New function.
+	* (symbol_record::is_formal_parameter): Ditto.
+	* tree.cc (tree_identifier::mark_as_formal_parameter): Ditto.
+	* (tree_parameter_list::mark_as_formal_parameters): Ditto.
+	* parse.y (param_list): Use it to tag formal parameters.
+	* (func_def1): Ditto.
+
+	* arith-ops.cc (DIVIDE_BY_ZERO_ERROR): On IEEE machines, allow
+	divide by zero errors to be suppressed.
+	* user-prefs.h (warn_divide_by_zero): New user preference.
+	* user-prefs.cc (warn_divide_by_zero): New function.
+	* builtins.cc (builtin_string_variables): Install it with default
+	value of true.
+
+	* tree.cc (tree_multi_assignemnt_expression): Use tree_return_list
+	instead of tree_param_list.
+	* (tree_multi_assignment_expression:eval): Make it work.
+
+	* tree.cc (tree_return_list): New class.  Allow index expressions
+	and identifiers in return lists.
+	* (tree_matrix::to_return_list): Rename from to_param_list.
+	* parse.y (expression): Use it.
+
+	* parse.y: Increment and decrement maybe_screwed_again instead of
+	just setting it to zero or one.
+
+Mon Jul 12 03:23:40 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-assign.cc (tree_constant_rep::do_matrix_assignment): Handle
+	case of lhs being of unknown type.
+
+	* lex.l (check_for_garbage_after_fcn_def): Also ignore trailing
+	commas and semicolons.
+
+Sun Jul 11 00:08:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.73.1 released.
+
+	* symtab.cc (symbol_record::alias): Also copy pointer to sv_fcn.
+
+Sat Jul 10 14:34:00 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_function::eval (int, char **, int): New function.
+
+	* symtab.cc (symbol_table::bind_globals): New function.
+	* tree.cc (tree_function::eval): Use it to associate local symbols
+	with global data.
+
+	* symtab.cc (alias): Add optional parameter `force'.
+
+	* Version 0.73 released.
+
+	* pr-output.cc: Use D_NINT instead of NINT in some cases to avoid
+	overflow problems on systems that don't have IEEE Inf.
+	* mappers.cc (round): Likewise.  Also avoids conversion of Inf to
+	INT_MAX on systems that do have IEEE Inf.
+
+	* builtins.h: Remove definition of NINT.
+	* tree.h: Likewise.
+	* tree-const.h: Likewise.
+
+	* utils.cc (NINT): Move function here and improve handling of
+	extreme values.
+	* (D_NINT): New function.
+
+	* scripts/isempty.m: Don't require the number of rows and columns
+	to both be zero.
+
+Thu Jul  8 16:25:50 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.72.2.
+
+	* configure.in: Do a better job of grabbing the last argument as
+	the target_host_type and avoiding setting it to things like
+	--prefix=/foo/bar
+
+	* tree-const.cc (tree_constant_rep::save): Add default case for
+	mark_as_global switch to avoid warnings from gcc.
+
+	* variables.cc (force_global): Cope with symbol table changes.
+	* tree.cc: (tree_identifier::do_lookup): Likewise.
+	* lex.l (lookup_identifier): Likewise.
+	* builtins.cc (install_builtins): Likewise.
+
+	* symtab.cc, symtab.h: Massive internal rewrite.
+
+Wed Jul  7 02:18:01 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-assign.cc (tree_constant_rep::do_scalar_assignment): If rhs
+	is a scalar type, also handle case of lhs being of unknown type.
+	* Be sure to set the new type of the lhs.
+
+	* tree-base.h: Don't include symtab.h.
+	* tree-const.h: Ditto.
+
+Tue Jul  6 22:47:28 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* parse.y (func_def2): Remove the function name from the top-level
+	symbol table if defining on command line (an M-file would never be
+	parsed if there was already an entry with the same name in the top
+	level symbol table).
+
+	* parse.y (word_list_command): Allow clear without any arguments.
+	* tree.cc (word_list_command::eval): Handle word list commands
+	with no arguments.
+
+Mon Jul  5 14:43:30 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.72.1.
+
+	* help.cc (operators): Document the double quote character.
+
+	* lex.l (getting_help): Delete unused variable.
+	* (HELP_FCN): New exclusive start state.
+	* ({IDENT}{S}*): Set start state to HELP_FCN instead of setting
+	getting_help.
+	* ({IDENT}/{S}*=): Likewise.
+
+	* symtab.cc (symbol_table::load): Delete unused function.
+
+	* tree-const.cc (tree_constant::load): Return flag telling whether
+	the constant is global.
+	* t-builtins.cc (builtin_load): Handle global variables.
+	* (builtin_save): Likewise.
+
+	* symtab.cc (symbol_record::save): Don't save builtin variables
+	(variables marked as eternal are assumed to be builtin).
+
+	* symtab.cc (symbol_record::mark_from_global): New function.
+	* (symbol_def::undefine): Add optional argument to prevent
+	deleting symbol's definition.
+	* (symbol_table::undefine): If this variable has been marked as
+	defined from a global, call symbol_def::undefine with arg = 1.
+	* tree.cc (tree_identifier::do_lookup): If a local symbol is
+	defined from a global, mark it as such.
+
+	* symtab.cc (symbol_record::define (symbol_record*)): Delete
+	unused function.
+
+	* tree.cc (tree_identifier::do_lookup (int&)): Use operator=
+	instead of symbol_record::define().
+	* variables.cc (force_global (char*)): Likewise.
+
+Sun Jul  4 01:27:44 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* symtab.cc (symbol_record): Define copy constructor and operator=.
+
+	* builtins.cc (install_builtins): Make `i' and `j' read-only
+	functions.
+
+	* symtab.cc (symbol_record::define): Respect read-only status of
+	variables and functions.
+
+Sat Jul  3 19:11:31 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* user-prefs.h (print_empty_dimensions): New user preference variable.
+	* user-prefs.cc (print_empty_dimensions): New function.
+	* builtins.cc (print_empty_dimesions): Make default value true.
+	* tree-const.cc (tree_constant_rep::eval): Use value here.
+
+	* cond.m: Handle empty matrices.
+	* tc-det.m (determinant): Likewise.
+	* tc-inv.m (inverse): Likewise.
+
+	* tc-hess.cc (hess): Use gripe_square_matrix_required instead of
+	calling error.
+	* tc-schur.cc (schur): Likewise.
+
+	* builtins.cc (propagate_empty_matrices): Change default value to
+	true.
+
+	* tree-const.cc (tree_constant_rep::eval): If a matrix has zero
+	rows or columns, also print the dimension along with the `[]'
+	symbol.
+
+	* tree-const.cc (do_binary_op): If ok to propagate empty matrices,
+	go ahead and do the binary operation so that the result will have
+	consistent dimensions.
+	* (do_unary_op): Likewyse.
+
+	* tc-extras.cc (get_dimensions): Don't force both nr and nc to
+	zero if one is.
+	* Matrix.cc, DiagMatrix.cc, ColVector.cc, RowVector.cc: Handle
+	matrices with zero dimensions in a more consistent fashion.
+
+Thu Jul  1 00:27:01 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* perror.m: New M-file.
+
+	* LP.h, LP.cc: New interface for linear programmming.
+	* LPsolve.h LPsolve.cc: New files to implement linear programming
+	using lp_solve.
+
+	* NPSOL.cc (minimize): Also return the vector of Lagrange
+	multipliers.
+	* tc-npsol.cc (npsol): Optionally return them.
+
+	* QPSOL.cc (minimize): Also return the vector of Lagrange
+	multipliers.
+	* tc-qpsol.cc (qpsol): Optionally return them.
+
+	* tc-qpsol.cc (qpsol): Make it work.
+
+Wed Jun 30 02:19:00 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_lpsolve): New function.
+	* (builtin_qpsol): Ditto.
+	* builtins.cc (general_functions): Add them to the list.
+
+	* tc-lpsolve.cc: New file.
+	* tc-qpsol.cc: Ditto.
+	* src/Makefile.in: Add them to the list of SOURCES and DLD_OBJECTS.
+
+Tue Jun 29 15:02:07 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/DAE.cc (integrate): If stop_time_set is false, reset
+	default value for info[3].
+	* liboctave/ODE.cc (integrate): Likewise, reset default values of
+	iopt and itask.
+
+	From Thorsten Ohl <ohl at physics.harvard.edu>:
+	* config.guess: Add check for NeXT.
+	* configure.in: Add check for NeXT so that readline is configured
+	properly (really need to improve readline's configuration scheme).
+	* sysdep.cc (malloc_handler): New function for handling malloc
+	errors on NeXT systems.
+
+	* octave.cc (main): Call sysdep_init before anything else.
+
+	* sysdep.cc: New file for system dependent things.
+
+	* octave.cc (initialize_globals): Only pass argv[0] since that's
+	the only thing that's used.
+
+Sat Jun 26 13:00:50 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_builtin::eval (int, char**, int)): Don't panic if
+	called for something other than a text_fcn.
+
+	* t-builtins.cc (builtin_cd): Rewrite to fix bogus memory
+	problems.
+
+Fri Jun 25 15:23:03 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-builtins.cc (builtin_cd): Don't delete value returned by
+	get_working_directory.
+	* g-builtins.cc (builtin_pwd): Likewise, and simplify.
+
+	* utils.cc (make_absolute): Always create a new copy to return.
+	* utils.cc (change_to_directory): Don't delete pointer returned
+	from get_working_directory().
+	* (file_in_path): Likewise.
+
+Thu Jun 24 16:48:38 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l ({IDENT}{S}*): Always insert a comma if the next token
+	doesn't look like some sort of operator, not just if
+	convert_spaces_to_comma is also true (it may have been turned off
+	by BIN_OP_RETURN).
+
+	* tree-const.h (matrix_ptr): Delete function.
+	* tc-extras.cc (frobit): Delete function.
+	* (get_dimensions): New function.
+	* (identity_matrix): Completely rewrite.
+	* (fill_matrix): Likewise.
+
+Wed Jun 23 13:50:16 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix-ext.cc (SCHUR::init): Also allow ord flag to be lowercase.
+	* (ComplexSCHUR::init): Ditto.
+	* tc-schur.cc (schur): Likewise.
+
+	* Matrix-ext.cc (SCHUR::init): Declare sort as char, not char*,
+	and pass its address to Lapack.
+	* (ComplexSCHUR::init): Ditto.
+
+	* Matrix-ext.cc (SCHUR::select_dig): Make static, and move ahead
+	of first reference in file.
+	* (SCHUR::select_ana): Likewise.
+	* (ComplexSCHUR::select_complex_dig): Likewise.
+	* (ComplexSCHUR::select_complex_ana): Likewise.
+
+	* builtins.cc (install_builtins): Add `J' as an alias for `I'.
+
+	* builtins.cc (install_builtins): Always create a new
+	tree_constant for each variable, since the symbol table doesn't
+	know how to share them.
+
+	* tc-schur.cc (schur): Use warning and error functions instead of
+	writing directly to cerr.
+	* tc-hess.cc (hess): Ditto.
+
+	* src/Makefile.in (DLD_OBJECTS): Include tc-schur.o and tc-hess.o.
+	* (SOURCES): Add tc-schur.cc tc-hess.cc.
+
+	* Merge Schur and Hessenberg changes:
+
+	Fri Mar 19 11:01:19 1993  R. Bruce Tenison (btenison at eng.auburn.edu)
+
+	* src/builtins.cc: Changed schur definition to include one more
+	input.  Also changed the help line description
+	* src/g-builtins.cc: Changed builtin_schur to accept two inputs
+	Also changed the information to explain ordered schur operation.
+	* src/tc-schur.cc Added extensions to the SCHUR and ComplexSCHUR
+	calls to pass extra paramater.  Also added check for proper param.
+	* liboctave/Matrix.h: Modified declarations dgeesx and zgeesx to
+	accept address of select function.  Modified class structures for
+	SCHUR and ComplexSCHUR to accept extra ordered schur param.
+	* liboctave/Matrix-ext.cc: Added extensions for the extra ordered
+	schur paramater.
+
+	Wed Mar 17 15:23:14 1993  R. Bruce Tenison (btenison at eng.auburn.edu)
+
+	* liboctave/Matrix-ext.cc (HESS and ComplexHESS): Added the
+	Hessenburg decomposition routines.
+	* liboctave/Matrix.h Added fortran lapack functions definitions
+	used in the Hessenburg procedure.
+	* src/g-builtins.cc (builtin_hess): Hessenburg Decomposition routine
+	added
+	* src/g-builtins.h (builtin_hess): Added extern definition.
+	* liboctave/Matrix.h Added classed HESS and ComplexHESS
+	* src/tree_const.h added defs for hess.
+	* src/tc-hess.cc (hess): New file for hess function.
+
+	Tue Mar 16 10:46:32 1993  R. Bruce Tenison (btenison at eng.auburn.edu)
+
+	* src/g-builtins.cc (builtin_schur): Schur Decomposition routine
+	added.
+	* src/g-builtins.h (builtin_schur): Added extern definition.
+	* liboctave/Matrix.h Added Classes SCHUR and Complex SCHUR, and
+	added defs for zgeesx and dgeesx (lapack schur decomp)
+	* liboctave/Matrix-ext.cc (SCHUR and Complex SCHUR): Ditto.
+	* src/tree-const.h added defs for schur.
+	* src/tc-schur.cc (schur): New file for schur function.
+
+Tue Jun 22 20:18:52 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (check_for_garbage_after_fcn_def): New function
+	* parse.y (fcn_end_or_eof): If reading from an M-file, use it to
+	print warning about trailing garbage after the end of a function
+	has been found.
+
+Mon Jun 21 20:21:01 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-assign.cc (tree_constant_rep::assign): Handle case of
+	assignment to unknown constant too.
+	* (tree_constant_rep::do_scalar_assignment): Don't fail for
+	unknown_constant type.
+	* (tree_constant_rep::do_matrix_assignment): Likewise.
+
+	* tree-const.cc (rows): Return 0 for unknown_constant type.
+	* (columns): Likewise.
+
+	* tree.cc (tree_identifier::assign): Defer defining symbol until
+	assignment is successful.
+	* When creating a new dummy tree_constant to assign a value to,
+	leave it an unknown_constant type.
+
+	* tc-assign.cc (do_scalar_assignment): If the right hand side
+	isn't a scalar, maybe try to resize instead.
+	* (do_matrix_assignment): For A(:,int) and A(int,:) cases, also
+	resize if left hand side is a scalar.
+
+	* norm.m: Allow "fro" to work for scalars and vectors too.
+
+Sun Jun 20 01:17:03 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* NLConst.cc: New file.  Move inline function definitions here
+	from NLConst.h.
+
+	* Objective.cc: New file.  Move inline function definitions here
+	from Objective.h
+
+	* tree.cc (tree_word_list_command::eval): Call strsave for argv[0]
+	too, and delete argv before returning.
+	* (tree_builtin::eval): Likewise, for text functions with no
+	arguments.
+
+Sat Jun 19 01:37:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (parse_and_execute): Delete calls to delete_buffer
+	and switch_to_buffer, since that is taken care of by unwinding the
+	frame.
+
+Fri Jun 18 00:08:36 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_matrix::eval): Delete useless direct = ptr->direct
+	and ptr = ptr->next statements from size-determining loop.
+
+	* parse.y (opt_list): New rule.  Replace all occurrences of list
+	with opt_list.
+
+	* tree.cc: (tree_index_expression::eval (int, int)): Don't
+	complain if the index expression has an empty argument list.
+
+	* octave.cc (initialize_globals): Check return value of
+	getenv ("HOME") against NULL, not the global variable
+	home_directory that we are trying to initialize.
+
+	* tree.cc (tree_function::eval): Quick return if command list
+	is empty.
+	* parse.y (func_def3): Allow empty function bodies.
+
+Thu Jun 17 02:08:02 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_while_command): Add constructor for case of
+	expression only.
+	* parse.y (statement): Allow empty command list for while commands.
+
+	* parse.y (list): Allow empty commands in more places.  This ups
+	the shift/reduce error count by 6, to 19.
+
+	* octave.cc (execute_startup_files): Don't delete sd.
+
+	* octave.cc (initialize_globals): Make copies of all strings.
+	* Store more humorous messages if things fail.
+
+Tue Jun 15 11:03:39 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-extras.cc (get_user_input): Finish incomplete change to get
+	input using readline.
+
+	* tc-extras.cc (match_sans_spaces): New function.
+	* (get_user_input): Use it when checking to see if the user
+	entered a `quit' command.
+
+	* liboctave/Makefile.in: Don't distribute Makedeps.in or include
+	Makedeps since we generate dependencies automatically now.
+	* configure.in: Don't create liboctave/Makedeps.
+
+Sun Jun 13 18:31:17 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/xdiv.cc (xdiv): Solve least-squares problem if system of
+	equations is not square, or if it is singular.
+	* (xleftdiv): Likewise.
+
+	* liboctave/Matrix.h (Matrix::lssolve): New functions for
+	least-squares solutions of linear systems.
+	* (ComplexMatrix::lssove): Ditto.
+
+Sat Jun 12 19:07:07 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* libcruft/misc/xstopx.f (xstopx): Call dostop, not do_stop.
+	* libcruft/misc/dostop.c: Rename from do_stop.c
+	* (dostop): Likewise.
+
+	* src/mappers.cc (xisnan (double)): Define even for systems that
+	don't have xisnan by always returning false.
+	* (xisnan (const Complex&)): Likewise.
+
+Fri Jun 11 19:54:58 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/Makefile.in (install): Try harder to install info files.
+
+	* libcruft/Makefile.in (install): Run ranlib on installed library.
+	* liboctave/Makefile.in (install): Ditto.
+	* readline/Makefile.in (install): Ditto.
+
+Thu Jun 10 00:15:41 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.72 released.
+
+	* libcruft/*/*.f: Don't call xstopx with '' since some Fortran
+	compilers object to zero-length strings.
+	* libcruft/misc/xstopx.f (xstopx): Don't print empty strings or
+	single blanks.
+	* libcruft/misc/gen-d1mach.c (main): Likewise, for generated code.
+
+	* test/Makefile.in (check): Set the Tcl variable OCTAVE_PATH.
+	* test/config/unix-octave.exp: Pass OCTAVE_PATH to OCTAVE using
+	the new -p flag.
+
+	* builtins.cc (install_builtins): Use load_path instead of calling
+	default_path().
+
+	* octave.cc (load_path): New global variable.
+	* (initialize_globals): Initialize it here by calling default_path().
+	* (main): Call initialize_globals() before getting command line
+	arguments.
+	* Accept new argument, -p PATH.
+
+	* octave.cc (clean_up_and_exit): Don't print a message when Octave
+	exits.
+
+	* doinstall.sh: Install M-files in $(libsubdir), not $(libdir).
+	* Use mkpath to create directories.
+	* Extract version from version.h.
+
+	* Makeconf.in (version): Compute version just once.
+
+	* (libsubdir): New directory that includes version number, for
+	installing M-files in (old versions of Octave may not be able to
+	understand new M-files).
+
+	* src/Makefile.in, libcruft/Makefile.in, liboctave/Makefile.in,
+	doc/Makefile.in, readline/Makefile.in, scripts/Makefile.in
+	(install): Use mkpath to create directories.
+	* scripts/Makefile.in (install): Install M-files in $(libsubdir),
+	not $(libdir).
+
+	* mkpath.c: New file, from Emacs-19.
+	* Makefile.in (mkpath): New rule.
+	* (all): Depend on mkpath
+	* (binary-dist): Distribute it.
+
+	* config.guess: Update from bothner at cygnus.com.
+
+	* lex.l (<STRING>{QSTR}*[\n\']): Set start state to 0 or MATRIX,
+	depending on value of braceflag.
+	* (<DQSTRING>{DQSTR}*[\n\"]): Ditto.
+
+	* tree.cc (tree_matrix::eval): Make sure that strings are nul
+	terminated.
+
+Tue Jun  8 16:08:10 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (clean_up_and_exit): Print `bye-bye' here.
+	* g-builtins.cc (builtin_quit): Not here.
+
+	* pager.cc (terminal_columns): If screenwidth <= 0, return a
+	default value of 80 columns.
+	* (terminal_rows): Likewise for screenheight and a default of 24
+	rows.
+
+	* octave.cc (parse_and_execute): Don't fiddle with interactive
+	states since that screws paging output.
+	* tree.cc (parse_m_file): Likewise.
+
+	* parse.y (input): For `simple_list error END_OF_INPUT' and
+	`error END_OF_INPUT' use ABORT_PARSE.
+	* Always accept `simple_list END_OF_INPUT'.
+	* Always abort for `END_OF_INPUT'.
+
+Mon Jun  8 13:55:41 1993  John C. Campbell  (jcc at schoch.che.utexas.edu)
+
+	* file-io.h (fopen_file_for_user): New function declaration.
+
+	* file-io.cc (fopen_file_for_user): New function.
+	* (fgets_internal): If file doesn't exist open it for user,
+	also return (double) -1 on EOF
+	* (fseek_internal), (ftell_internal), (frewind_internal),
+	(do_printf): Ditto.
+	* (fopen_internal): Remove warn_on_not_open flag, limit warns.
+
+Mon Jun  7 00:28:13 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* file-io.cc (do_scanf): Use `type' wherever possible instead of
+	hardcoding name in messages.
+	* (do_printf): Ditto.
+
+	* file-io.cc (fflush_internal): If flushing stdout, flush output
+	to the pager instead of calling fflush on a stream.
+	* (do_printf): Make fprintf (stdout, ...) exactly the same as
+	printf (...).
+	* (do_scanf): Make fscanf (stdin, ...) exactly the same as
+	scanf (...).
+
+	* tc-extras.cc (get_user_input): Flush output to pager before
+	prompting for input.
+
+	* libcruft/Makefile.in (DISTFILES): Distribute STOP.patch to show
+	the changes made to the Fortran sources.
+
+	* libcruft/*/*.f: Replace STOP statements with calls to xstopx, so
+	that Fortran programs won't just quit on us.
+
+	* libcruft/misc/xstopx.f: New file.
+	* libcruft/misc/do_stop.c: New file.
+	* libcruft/misc/Makefile.in (SPECIAL): Add do_stop.c to the list.
+	* (SPECIAL_DEPEND): Likewise, for do_stop.o.
+	* libcruft/Makefile.in (CRUFT_OBJ): Ditto.
+
+	* lex.l (")"): Don't pop the top of the in_brace_or_paren stack if
+	it's empty.
+
+Sun Jun  6 00:41:28 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* liboctave/CollocWt.cc (init): Always compute Gaussian quadrature
+	weights instead of trying to compute Radau or Lobatto weights if
+	the endpoints are included.
+	* Really do compute roots and derivative weights corresponding to
+	Legendre polynomials if alpha and beta are zero, even if the
+	endpoints are included.
+
+Sat Jun  5 22:19:55 1993  John C. Campbell  (jcc at schoch.che.utexas.edu)
+
+	* builtins.cc (builtin_general_functions): Correct max arg counts
+	for fscanf, scanf, and sscanf.
+
+	* g-builtins.cc (builtin_fscanf): Correct argument checks.
+	* (builtin_sscanf): Likewise.
+
+	* file-io.cc (fopen_internal): Don't warn for opening new file.
+
+	* file-io.cc (process_printf_format): Handle * for field width and
+	precision.
+	* Pass array of arguments and nargin instead of just one arg.
+	* (do_printf): Call process_printf_format() with new args.
+
+	* file-io.cc (process_scanf_format): New function to handle scanf
+	dirty work.
+	* (do_scanf): New function.
+
+Sat Jun  5 14:09:41 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (YY_FATAL_ERROR): Redefine here to keep from exiting on
+	fatal scanner errors.
+
+Fri Jun  4 16:35:25 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_multi_assignment_expression::eval (int)): Check to
+	see if result is NULL before trying to use it.
+
+	* tc-extras.cc (get_user_input): Call gnu_readline() to get input.
+
+Thu Jun  3 00:30:28 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/*.m: Convert single-quoted strings to use double quotes
+	since the manual says they are better.
+
+	* Version 0.71.10.
+
+	* doc/Makefile.in (DISTFILES): Distribute octave.info*.
+
+	* Makefile.in (.fname): Delete target and move actions back to the
+	individual dist targets because this always needs to be done.
+	* (binary-dist): Strip src/octave.
+
+	* doinstall.sh: New file, for binary distributions.
+
+Wed Jun  2 15:11:54 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makefile.in (binary-dist): New target, just like dist, except
+	also distribute libcruft.a, liboctave.a, libreadline.a and
+	src/octave.
+
+	* Makefile.in (.fname): New target.
+	* (links-for-dist): New target.
+	* (local-dist): Depend on .fname.
+	* (dist): Depend on .fname and use links-for-dist.
+
+	* octave.cc: Move code to print startup message to just after
+	option processing so that any messages from startup files will
+	appear after the normal startup message.
+
+	* utils.cc (get_site_defaults): New function.
+	* (OCTAVE_HOME): Provide default definition.
+
+	* (SITE_DEFAULTS): Delete definition.
+	* octave.cc (execute_startup_files): Use get_site_defaults instead.
+
+	* src/Makefile.in (utils.o): Define OCTAVE_HOME to be $(prefix)
+	here.
+
+	* Makeconf.in: Don't define SITE_DEFAULTS or OCTAVE_M_FILE_DIR.
+
+	* lex.l (do_string_escapes): Recognize `\"'.
+
+Tue Jun  1 01:28:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.71.9.
+
+	* parse.y (maybe_convert_to_ans_assign): Greatly simplify.
+
+	* file-io.cc (File_info): Convert from struct to proper class.
+	* (valid_mode): New function.
+
+	* parse.y, parse.h, lex.l, tree-extras.cc (convert_to_ans_assign):
+	Delete unused variable.
+
+	* builtins.cc (SEEK_CUR): Set to 1 to match (normal) system values.
+	* (SEEK_END): Likewise, set to 2.
+
+	* statdefs.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* octave-hist.cc: Include it.
+	* variables.cc (identifier_exists): Likewise.
+	* utils.cc (is_newer): Likewise.
+
+	* builtins.cc (SEEK_SET): New builtin varible.
+	* (SEEK_CUR): Ditto.
+	* (SEEK_END): Ditto.
+	* (stdin): Ditto.
+	* (stdout): Ditto.
+	* (stderr): Ditto.
+
+	* lex.l (strip_trailing_whitespace): New function.
+	* ({IDENT}{S}*): Use it.
+	* (<TEXT_FCN>[^ \t\n\;\,]*): Fix to grab trailing spaces.
+	Use strip_trailing_whitespce() to delete it before returning.
+
+Mon May 31 21:00:00 1993  John C. Campbell  (jcc at june.che.utexas.edu)
+
+	* file-io.cc, file-io.h: New files to implement C-style file
+	handling and I/O functions.
+	* (do_printf): Move here from tc-extras.cc.
+	* (process_printf_format): Likewise.  Also renamed from
+	process_format.
+
+Mon May 31 00:52:55 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* (tree_function::eval): Now that we can restore values, enable
+	code to give error for attempts to call functions recursively.
+
+	* octave.cc (parse_and_execute): Use unwind-protect functions to
+	save and restore state.
+	* tree.cc (parse_m_file): Likewise.
+	* (tree_function::eval): Likewise.
+	* tc-extras (eval_string): Likewise.
+
+	* unwind-prot.cc (saved_variable): New class to hold values of and
+	pointers to variables we want to restore.
+	* (restore_saved_variable): New function.
+
+	* unwind-prot.cc (unwind_protect_int_internal): New function.
+	* (unwind_protect_ptr_internal): Ditto.
+	* (unwind_protect_var_internal): Ditto.
+
+	* unwind-prot.h (unwind_prot_int): New macro.
+	* unwind-prot.h (unwind_prot_ptr): Ditto.
+	* unwind-prot.h (unwind_prot_var): Ditto.
+
+	* variables.cc (symbol_out_of_date ()): Move here from tree.cc.
+	* (is_valid_function): Fix logic for finding a function
+	definition, including checking to see if the current symbol
+	definition is out of date.
+
+	* tree-const.h (is_numeric_or_range_type): New function.
+	* tree-const.h (is_string_type): New function.
+	* tree.cc (tree_matrix::eval): Use !is_string_type() instead of
+	is_numeric_type() to decide that we've seen something other than
+	a string.
+
+	* parse.y (maybe_warn_assign_as_truth_value ()): New function.
+	* user-prefs.h (warn_assign_as_truth_value): New preference.
+	* user-prefs.cc (warn_assign_as_truth_value ()): New function.
+	* builtins.cc (string_variables): Add it to the list.
+
+	* tree.h (tree_simple_assignment_expression): Rename class from
+	tree_assignment_expression.
+	* (tree_assignment_expression): New class, derived from
+	tree_expression.
+	* (tree_simple_assignment_expression): Derive from new
+	tree_assignment_expression class, not tree_expression class.
+	* (tree_multi_assignment_expression): Ditto.
+
+Sun May 30 22:40:58 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/Makefile.in (%.d: %.cc): First remove target file, then
+	redirect into tmp file, and finally move tmp file to target file
+	only if creating tmp file was successful.
+	* liboctave/Makefile.in (%.d: %.cc): Ditto.
+
+Sat May 29 18:18:16 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_constant *tree_multi_assignment_expression
+	::eval (int print, int nargout)): New function.
+	* (tree_constant tree_multi_assignment_expression::eval (int print)):
+	Use it to do the real work.
+
+	* tree.cc (tree_matrix::to_param_list ()): Also allow index
+	expressions as long as the argument list is missing.
+
+	* parse.y (ans_expression): Now that assignments are just
+	expressions, don't convert expressions to assignemnts to `ans' if
+	they already are assignments.
+	* maybe_convert_to_ans_assign (tree *expr): New function to do the
+	real work.
+
+	* tree.cc (tree_multi_assignment_expression::
+	is_assignement_expression ()): Return 1.
+
+	* tree-base.h (tree::is_index_expression ()): New virtual
+	function, returns 0.
+	* tree.cc (tree_index_expression::is_index_expression ()): Return 1.
+
+	* tree.cc (tree_assignment): Construct from tree_index_expression
+	and a tree.
+	* (tree_index_expression::ident ()): New function.
+	* (tree_index_expression::arg_list ()): New function.
+
+	* parse.y (variable): New rule, returns tree_index_expression.
+
+	* parse.y: Rewrite assignment rules so that they are simply
+	expressions, not special cases.
+	* Rearrange fact and expression rules into expression (assignement
+	or simple expression), simple_expr (binary and postfix expressions
+	or secondary simple expression), and simple_expr1 (constants and
+	prefix expressions) rules.
+	* Delete fact rules.
+
+	* parse.y: Make EXPR_EQ and EXPR_NE have the same precedence as
+	the other relational operators.
+
+Fri May 28 10:14:01 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* unix-octave.exp: Delete use of OCTAVEFLAGS.
+
+	* test/config: New directory.
+	* test/config/Makefile.in: New file.
+	* test/config/unix-octave.exp: Rename from test/octave-init.exp.
+	* test/Makefile.in (SOURCES): Delete octave-init.exp from list.
+	* configure.in: Add test/config/Makefile to the list of Makefiles
+	to build.
+
+	* utils.cc (send_to_plot_stream): Plot lines by default.
+
+Thu May 27 08:03:31 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (\]): Don't pop the top of the in_brace_or_paren stack if
+	it's empty.
+
+	* tree.cc (tree_matrix::eval): Make it work for single element
+	strings as well.
+
+	* Version 0.71.8.
+
+	* lex.l (next_token_is_postfix_unary_op): New function.
+	* (<MATRIX>{SN}*\]{S}*): Use it as well, to decide whether to
+	insert a comma.
+	* (<MATRIX>{S}+): Likewise.
+	* ({IDENT}{S}*): Likewise.
+
+Wed May 26 15:37:27 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* pr-otput.cc (pr_any_float): Use form() now that iostream
+	formatting bug has been fixed (libg++-2.3.1).
+
+Mon May 24 15:36:22 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (any_arg_is_magic_colon): New function.
+	* (tree_builtin::eval) Use it to avoid calling builtin functions
+	with `:' arguments.
+
+Sun May 23 14:07:19 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_fprintf): Correct usage message.
+
+Fri May 21 10:35:40 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.71.7.
+
+	* octave.cc (main): Always reset_parser() before every call to
+	yyparse(), not just on a longjmp return.
+
+	* doc/Makefile.in (install): For now, don't try to install
+	anything.
+
+	* lex.l (<MATRIX>{S}+): Call next_token_is_bin_op() instead of
+	making the check in line.
+	* (<MATRIX>{SN}*\]{S}*): Likewise.
+	* (<MATRIX>{S}+): Likewise.
+
+	* lex.l (looks_like_bin_op): New function.
+	* (next_char_is_space): Ditto.
+	* (next_token_is_bin_op): Ditto.
+
+	* lex.l ({IDENT}{S}*): If we're in a brace context and the next
+	character is an open paren, set convert_spaces_to_comma to 0.
+	* tree-const.cc (convert_to_str): New function.
+	* g-builtins.cc (builtin_setstr): New function.
+	* builtins.cc (builtin_general_functions): Add it to the list.
+
+Thu May 20 17:56:15 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* doc/Makefile.in (SOURCES): Define to be all .texi files.
+	* (octave.info): Depend on $(SOURCES).
+	* (octave.dvi): New target.
+	* Don't distribute the man page.
+
+	* lex.l (<MATRIX>{S}+): If the next character is a plus or minus
+	followed by a space or tab, don't insert a comma.  This makes
+	input like [1 + 1] == 2 and input like [1 +1] == [1 1].
+	* (<MATRIX>{SN}*\]{S}*): Likewise.
+
+	* lex.l (<MATRIX>{S}+): Use in_brace_or_paren and
+	convert_spaces_to_comma to decide whether to convert spaces to a
+	comma.
+
+	* lex.l ({IDENT}{S}*): If we're in a brace context and the next
+	character is an open paren, set convert_spaces_to_comma to 0.
+
+	* lex.l (<MATRIX>{SN}*\]{S}*): Even if we're still inside some braces,
+	don't always push a comma onto the input.
+
+	* lex.l (<MATRIX>{SN}*\]): Also grab trailing spaces.
+	* ({IDENT}): Ditto.
+
+	* lex.l (in_brace_or_paren): New stack to keep track of whether
+	the closest enclosing scope is a pair of braces or parens.  When
+	we see a `[' or a `(', push a flag on the stack.  When we see a
+	`]' or a `)', pop the top of the stack.
+
+	* lex.l (convert_spaces_to_comma): New flag to control lexer behavior.
+	* (RETURN): Reset it to 1.
+	* (most other returns): Reset it to 1.
+
+	* lex.l (BIN_OP_RETURN): New macro.  Set convert_spaces_to_comma to 0.
+	* (most binary operators): Use it instead of RETURN.
+
+	* lex.l (match_any): New function.
+
+Wed May 19 12:51:54 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Range.cc (nelem_internal): Don't allow ranges with more than
+	INT_MAX elements.  Return -1 to indicate failure.
+	* tree-const.cc (tree_constant_rep::tree_constant_rep (double,
+	double, double)): Check nelem() to see if the range is valid.
+
+	* pr-output.cc (all_elements_are_ints (Range&)): We only need to
+	check the base and the increment, not the limit too.
+
+	* Range.cc (nelem_internal): Move function definition here from
+	Range.h and do a better job of determining the number of elements
+	in the range.
+
+Tue May 18 09:06:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.71.6.
+
+	* tc-extras.cc (find_nonzero_elem_idx): Declare inner loop
+	iteration variables that are used inside later nested loops
+	in the outer enclosing scope to make this work for old and new
+	language definitions (see the ARM, chapter 19: "ANSI/ISO
+	Resolutions", 6.4/6.5: "The statement or statements immediately
+	controlled by the condition in a selection-statement, or an
+	iteration-statement introduce an implicit local scope".
+	* xpow.cc (elem_xpow (Matrix&, Matrix&)): Likewise.
+
+	* tree.cc (tree_identifier::parse_m_file (char*, int)): Set
+	reading_script_file before calling parse_m_file and restore it
+	afterward.
+
+Mon May 17 20:04:54 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.h (prog_name): Declare extern.
+	* (raw_prog_name): Ditto.
+
+	* f2c-compat.sh (ctest.c): Also write a dummy MAIN_ since gcc 2.4
+	doesn't seem to create an executable now if there are unresolved
+	externals, and the linker wants to see it on Suns.
+
+Thu May 13 01:06:18 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makefile.in (DISTFILES): Include Makeconf.in.
+
+	* configure.in: Set defaults for CFLAGS, CXXFLAGS, LDFLAGS, and
+	FFLAGS.
+	* Don't substitute CDEBUG, COPTIMIZE, FOPTIMIZE, or CXXOPTIMIZE.
+	* Use AC_PROGRAMS_CHECK instead of our own code for checking for a
+	Fortran compiler.
+	* Add Makeconf to the list of files to create.
+
+	* src/Makefile.in (octave): Use ALL_LDFLAGS instead of LDFLAGS.
+
+	* Makeconf.in (ALL_CFLAGS, ALL_CXXFLAGS, ALL_LDFLAGS): New macros.
+	* Allow the user to set CFLAGS, CXXFLAGS, and FFLAGS without
+	screwing things up.
+	* (CDEBUG, COPTIMIZE, FOPTIMIZE, CXXOPTIMIZE): Delete.
+	* Provide rules for making .o from .cc or .c files that use
+	ALL_CXXFLAGS and ALL_CFLAGS.
+
+	* src/Makefile.in: Generate dependencies automatically using the
+	method described in the GNU make manual.
+	* liboctave/Makefile.in: Likewise.
+
+	* All Makefile.in files: Set TOPDIR and include $(TOPDIR)/Makeconf.
+	* Makeconf.in: New file, for most configuration options.
+
+	* tc-rand.cc (rand_internal): Return an empty matrix for rand (0).
+
+Wed May 12 01:32:36 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (clean_up_and_exit): Call close_plot_stream before
+	quitting.
+
+	* Version 0.71.4.
+
+	* pr-output.cc (octave_print_internal (ostrstream&, Matrix&)):
+	Handle wrapping columns neatly, respecting value of split_long_rows.
+	* (octave_print_internal (ostrstream&, ComplexMatrix&)): Ditto.
+	* (octave_print_internal (ostrstream&, Range&)): Ditto.
+
+	* user-prefs.cc (split_long_rows): New preference variable and
+	function.
+	* builtins.cc (builtin_string_variables): Add to list with default
+	value == true.
+
+Tue May 11 02:20:43 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* pr-output.cc (pr_max_internal): Don't count Inf or NaN when
+	looking for max value.
+	* (pr_min_internal): Likewise, for min values.
+
+	* pr-output.cc (pr_any_float): Merge pr_float and pr_imag_float.
+
+	* pr-output.cc (any_element_is_inf_or_nan (Matrix&)): New function.
+	* (any_element_is_inf_or_nan (ComplexMatrix&)): New function.
+	* (all set_format functions (except Range)): Consider Inf and NaN
+	when computing field width (we'll either print "Inf" (possibly
+	with a sign) or "NaN").
+
+	* pr-output.cc (pr_float): Handle Inf and NaN.
+	* (pr_imag_float): Ditto.
+
+	* pr-output.cc (set_format_style): Make format short set precision
+	to 3 and max field width to 8.
+
+	* pr-output.cc (pr_float): Don't print a sign for -0.0.
+	* (pr_imag_float): Ditto.
+
+	* pr-output.cc (all set_format functions): Return the actual field
+	width computed or 0 if free format.  For complex, return both real
+	and imaginary field widths.
+	* Include pager.h for terminal_rows() and terminal_columns().
+
+	* pr-output.cc (pr_complex): If imaginary part is -0.0, print a
+	minus sign but convert the value to 0.0 before printing.
+
+	* octave.cc (parse_and_execute (FILE *, int)): Don't use readline
+	to read commands from files.
+	* (parse_and_execute (char *, int)): Set reading_script_file
+	before calling get_input_from_file.
+
+	* Version 0.71.3.
+
+	* src/Makefile.in (deps): New target.
+	* Update dependencies using the output from running `make deps'.
+
+	* pr-output.cc (set_output_prec_and_fw): New function.
+	* (set_format_style): Use it.
+	* (set_format functions): Use user_pref variables for precision
+	and field width.
+
+	* variables.cc (octave_real_scalar_variable): New function.
+	* buitlins.cc (builtin_string_varaibles): Add output_precision and
+	max_field_width to the list (really need a separate list for
+	numeric values...).
+	* user-prefs.cc (set_output_max_field_width): New function to be
+	called when output_max_field_width changes.
+	* (output_precision): Likewise, for output_precision.
+
+	* sighandlers.cc (pipe_handler_error_count): New global variable.
+	* (sigpipe_handler): Use it to keep from printing more than one
+	broken pipe message between prompts.
+	* (input.cc): Reset pipe_handler_error_count before printing the
+	prompt.
+
+Mon May 10 13:06:52 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* sighandlers.cc (sigpipe_handler): Issue warning and return
+	instead of aborting.
+
+	* user-prefs.cc (all sv_* functions): Don't delete previous value
+	of a preference string if the new value is bogus.
+
+	* user-prefs.cc (all sv_* functions and all functions that handle
+	user preferences): Return 0 for success, -1 for failure.
+	* symbtab.cc (symbol_record::define): Check return value of sv_fcn
+	and restore previous value on failure.
+	* symtab.h (sv_Function typedef): Change to return int, not void.
+	* builtins.h (sv_Function typedef): Ditto.
+
+Sun May  9 18:25:00 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* user-prefs.cc (all sv_* functions): Issue a warning if the user
+	gives us something that's not a string.
+
+Sat May  8 23:40:59 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* ColVector.cc (ColumnVector::min): Upper loop limit is len, not 0.
+	* (ComplexColumnVector::min): Ditto.
+	* RowVector.cc (RowVector::min): Ditto.
+	* (ComplexRowVector::min): Ditto.
+
+Fri May  7 18:41:29 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* pr-output.cc (set_format_style): New function, extracted from
+	builtin_format().
+	* t-builtins.cc (builtin_format): Call set_format_style to do real
+	work.
+
+	* pr-output.cc: New file for special formatted printing funcions.
+	* tree-const.cc (tree_constant_rep::eval): Use new functions.
+
+	* user-prefs.cc (sv_pager_binary): New function.
+	* user-prefs.h (user_preferences) Add new field, pager_binary.
+	* builtins.cc (builtin_string_variables): Add PAGER to the list.
+	* utils.cc (default_pager): New function.
+	* Makefile.in: Define DEFAULT_PAGER for utils.cc, not pager.cc.
+	* pager.cc (get_pager): Delete function.
+	* Use user_pref.pager_binary instead of calling get_pager().
+
+Thu May  6 11:05:06 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* pager.cc (pager_buf): Declare as static pointer to ostrstream.
+	* (initialze_pager): Delete old pager_buf and create new one for
+	each batch of output.  This is needed because once str() is called
+	for pager buf, it will no longer grow.
+
+	* pager.cc (maybe_page_output): Take care of deleting buffer after
+	str() is called.
+	* (flush_output_to_pager): Likewise.
+	* t-builtins.cc (builtin_ls): Likewise.
+	* (builtin_set): Likewise.
+	* (builtin_show): Likewise.
+	* tc-extras.cc (process_format): Likewise.
+	* (process_format): Likewise.
+	* tree-plot.cc (tree_plot_command::eval): Likewise.
+
+Wed May  5 10:45:39 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_shell_command): Buffer characters with an
+	ostrstream and call maybe_page_output instead of writing directly
+	to cout.
+	* (builtin_warranty): Likewise.
+	* tc-extras (do_printf): Likewise.
+	* tree.cc (tree_identifier::eval): Likewise.
+	* (tree_assignment_expression::eval): Likewise.
+	* (tree_multi_assignment_expression::eval): Likewise.
+	* tree-const.cc (tree_constant_rep::eval): Likewise.
+	* t-builtins.cc (builtin_help): Likewise.
+	* (builtin_ls): Likewise.
+	* (builtin_who): Likewise.
+
+	* user-prefs.h user-prefs.cc (page_screen_output): New preference.
+	* builtins.cc (string_variables): Add to list with default value
+	of true.
+
+	* input.cc (octave_gets): If interactive, call flush_to_pager()
+	before prompting.
+
+	* utils.cc (terminal_rows): Move to pager.cc
+	* (terminal_columns): Likewise.
+	* (get_pager): Likewise.
+
+	* pager.h, pager.cc: New file to handle pager stuff.
+	* src/Makefile.in: Fix things to distribute and compile them.
+
+	* libcruft/Makefile.in (CRUFT_OBJ): Strip $(srcdir)/ and convert
+	from .f to .o in two steps since some versions of GNU make strip
+	the leading ./ from the output of $(wildcard), causing my pattern
+	match to fail if compiling in the source tree.
+
+Tue May  4 09:13:52 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* symtab.cc (symbol_record::define (symbol_record *)): Delete old
+	name before saving new name.
+	* (symbol_record::document): Likewise, for var.help and fcn.help.
+
+	* parse.y (ABORT_PARSE): Renamed from DO_ABORT.
+
+Mon May  3 01:00:04 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc: Define destructors for every class in tree.h.  It
+	appears that it should always be ok to delete everything in a
+	command tree once we're done executing it.  Function definitions
+	are still ok because the parser doesn't set global_command to the
+	tree_function we've built (that's saved somewhere in the symbol
+	table and shouldn't be deleted until we clear or redefine the
+	function).
+
+	* utils.cc (pathstring_to_vector): Do memory management here so
+	callers don't have to.
+	* (default_path): Likewise.
+
+	* utils.cc (make_absolute): Return current_path (not a copy) since
+	it is static.
+	* (get_working_directory): Return the_current_working_directory
+	(not a copy) since it is global.
+
+	* utils.cc (cleanup_tmp_files): Delete filename when done.
+
+	* parse.y: Replace output to cerr with calls to error() or warning().
+	* DO_ABORT: New macro.  Use it instead of YYERROR for errors that
+	we detect, and call yyerror since bison doesn't.
+	* (param_list1): Detect invalid parameter lists.
+	* (yyerror): Don't print pointer if it is past the end of the line.
+
+Sun May  2 13:03:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-extras.cc (process_format): Use ostrstream instead of a
+	fixed-size character string to buffer the format.
+
+	* utils.cc (terminal_rows): Get info from readline variable
+	instead of hardcoded constants.
+	* (terminal_columns): Likewise.
+
+	* utils.cc (maybe_page_output): New function.
+	* t-builtins.cc (builtin_help): Use it.
+	* (builtin_who): Ditto.
+	* Don't include procstream.h anymore since we no longer need it.
+
+	* utils.cc (jump_to_top_level): Call run_all_unwind_protects ()
+	before jumping back to the top level.
+
+Sat May  1 20:59:12 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* unwind-prot.cc unwind-prot.h: New files to implement memory
+	cleanup stuff.
+	* src/Makefile.in: Distribute them.
+
+	* Version 0.71.2.
+
+	* computer.m: Delete file.
+	* scripts/Makefile.in (computer.m): Add $(srcdir)/ prefix to
+	computer.in.
+
+Fri Apr 30 17:03:04 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.h (<CLASS>::row (int i)): New function for extracting a
+	row of a matrix where CLASS is one of Matrix, DiagMatrix,
+	ComplexMatrix, or ComplexDiagMatrix.
+	* (<CLASS>:: column (int i)): Likewise for columns.
+	* (<CLASS>::row (char *s)): Likewise, but selection is done with a
+	character string.  Currently we accept anything beginning with `F'
+	or `f' to mean the first row and anything beginning with `l' or
+	`L' to mean the last row.
+
+Wed Apr 28 14:23:49 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* scripts/computer.in: New template file for computer.m.
+	* scripts/Makefile.in (computer.m): Generate a custom computer.m
+	file using $target_host_type.
+	* (clean): Delete computer.m.
+
+	* configure.in: If last argument is not empty, use its value as
+	the TARGET.
+	* If we aren't given a TARGET, use config.guess to find one.
+	* Substitute target_host_type.
+
+	* config.guess: New file, taken from gdb distribution.
+	* Makefile.in: Distribute it.
+
+	* tree-const.cc (force_numeric): New parameter, force_str_conv to
+	allow us to ignore user preference on string to numeric
+	conversion.
+	* (make_numeric): Likewise.
+
+	* tree.cc (tree_matrix::eval): Allow range constants in matrix
+	lists by simply converting them to matrices.
+	* Ditto for string constants.
+
+Tue Apr 27 17:21:12 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* utils.cc (smells_like_X11): Delete unneeded function.
+	* builtins.cc (install_builtins): Don't initialize
+	graphics_terminal since it's no longer needed.
+
+	* utils.cc (pathstring_to_vector): Call tilde_expand on each
+	element of the path.
+
+	* mappers.cc: Include float.h for DBL_MAX.
+
+Wed Apr 21 19:31:12 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* mappers.cc (xisnan (Complex&)): Rename from isnan.
+	* builtins.cc (mapper_functions): Use xisnan instead of isnan.
+	* (install_builtins): Special case for linux for geenerating
+	infinity and NaN.
+
+Mon Apr 19 14:10:55 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.71.1 released.
+
+	* symtab.cc (char **sorted_list (int& count)) New function.
+	* (char **sorted_var_list (int& count)): Ditto.
+	* (char **sorted_fcn_list (int& count)): Ditto.
+	* t-builtins.cc (builtin_who): Check symbol count too.
+
+	* utils.cc (send_to_plot_stream): Check is_open(), not just the
+	state of the stream.
+	* (close_plot_stream): Likewise.
+
+	* procstream.cc, procstream.h: Rewrite, taking a hint from the GNU
+	fstream class.
+
+Sun Apr 18 17:40:54 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-builtins.cc (builtin_help): Don't call list_in_columns if
+	there isn't anything to list.
+
+Fri Apr 16 20:57:15 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Makefile.in (DISTDIRS): List dld here.
+	* (DISTSUBDIRS): Not here.
+
+Thu Apr 15 12:17:08 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.71 released.
+
+	* scripts/*.m: Improve help messages for most files.
+
+	* libcruft/Makefile.in: Make libcruft.a here.
+	* libcruft/Makerules.in: Not here.
+
+	* PLOTTING: New file.
+	* Makefile.in: Add it to the list of files we distribute.
+
+	* g-builtins.cc (builtin_shell_command): New function.
+	* builtins.cc (general_functions): Add it to the list.
+
+	* procstream.h, procstream.cc (iprocstream): New class.
+
+	* lex.l (<MATRIX>{SN}*\]): Maybe insert a comma after reading a `]'.
+
+	* t-builtins.cc (builtin_load): Do tilde expansion for the file name.
+	* (builtin_save): Ditto.
+
+Wed Apr 14 10:40:44 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_function::eval): Until we have a proper call frame
+	unwinding scheme, comment out previous change.
+
+	* tree.cc (tree_matrix::eval): Brain Transplant.
+	* (tree_matrix::length): New function.
+
+	* tree-base.h (matrix_dir): Delete md_none, md_left, and md_up.
+	The only valid values are md_unknown, md_right, and md_down.
+
+Tue Apr 13 20:07:25 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.h (tree_function::call_depth): New member variable.
+	* tree.cc (tree_function::eval): Check it to make recursive
+	function calls fail (waiting for proper symbol table handling).
+
+	* utils.cc (pathstring_to_vector): Don't prepend `.' here.  We do
+	that already in default_path() if the user hasn't given us a
+	loadpath.
+
+	* t-builtins.cc (builtin_help): Get help for M-files even if they
+	haven't been compiled yet.
+	* List M-files we find in the loadpath.
+
+	* utils.cc (get_m_file_names): Split into two functions, add
+	parameter to specify whether .m suffix is deleted.
+
+	* lex.l (grab_help_text): New function.
+	* (beginning_of_function): New global variable.
+	* (%|#): Call grab_help_text() if at beginning of a function.
+	* tree.cc (tree_identifier::document): New function.
+	* parse.y (func_def2): Use it.
+	* (help_buf): New global buffer for help text.
+
+Mon Apr 12 00:31:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* utils.cc (get_m_file_names): New function.
+	* variables.cc (make_name_list): Use it.
+
+	* t-builtins.cc (list_in_columns): Put output on an strstream
+	instead of in a String.
+	* (builtin_help): Use an strstream instead of a String for buffering.
+	* (builtin_who): Likewise.
+
+	* g-builtins.cc (builtin_keyboard): New function.
+	* builtins.cc (general_functions): Add to list.
+
+	* tc-extras.cc (get_user_input): If the user enters `exit',
+	`quit', or `return', return instead of eval'ing the string.
+	* Don't abort on empty input.
+	* Add additional argument to handle debugging via new `keyboard'
+	function.  If doing debugging, keep reading until we see `exit',
+	`quit', or `return'.
+
+	* menu.m: New M-file.
+
+	* New top level plotting functions:
+
+	    plot.m    semilogx.m  semilogy.m  loglog.m   polar.m
+	    title.m   xlabel.m    ylabel.m    grid.m     bar.m
+            stairs.m  mesh.m      meshdom.m   contour.m
+
+	* New internal plotting functions:
+
+	    plot_int.m    plot_2_s_s.m  plot_2_v_v.m  plot_2_v_m.m
+	    plot_2_m_v.m  plot_2_m_m.m  polar_int.m
+
+	* New utility functions:
+
+	    is_scalar.m  is_vector.m  is_matrix.m
+
+Sun Apr 11 11:10:29 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-buitlins.cc (builtin_ls): New function.
+	* builtins.cc (text_functions): Add it to the list under the names
+	`ls' and `dir'.
+
+Sat Apr 10 15:13:05 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* procstream.cc (oprocstream::close): Set badbit for stream after
+	it is closed.
+
+	* utils.cc (close_plot_stream): New function.
+	* g-buitlins.cc (closeplot): New builtin function.
+	* builtins.cc (general_functions): Add to list.
+
+	* lex.l (cant_be_identifier): New cruft to properly handle the
+	plot command's `using', `title', and `with' keywords.
+
+Fri Apr  9 09:38:25 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Warn if it looks like gnuplot isn't installed.
+
+	* utils.cc (send_to_plot_stream): Check the user's preference for
+	the gnuplot binary.
+
+	* user-prefs.cc (sv_graphics_terminal): Delete function.
+	* user-prefs.h (graphics_terminal): Delete variable.
+
+	* tree-plot.cc (tree_subplot_using::print): Add argument to allow
+	checking of columns given in using command and use it.
+	* (tree_plot_command::eval): Change caller.
+
+	* parse.y (title): Allow plot title to be any expression.
+	* tree-plot.cc (subplot_list): Likewise.
+
+	* tree-plot.cc (tree_plot_command::eval): Don't let lusers try to
+	make 2D parametric plots, since that seems to crash gnuplot.
+
+	* tree.cc (tree_identifier::parse_m_file): Don't try to stash
+	m-file name or time parsed if we were actually executing a script
+	file.
+
+	* sombrero.m: New M-file to demonstrate 3D plotting.
+
+	* parse.y (plot_options): Allow them to be specified in any order.
+
+	* g-builtins.cc (builtin_purge_tmp_files): New function.
+	* builtins.cc (general_functions): Add to list.
+
+	* g-builtins.cc, g-builtins.h (builtin_plot): Delete.
+	* builtins.cc (general_functions): Delete entry for builtin_plot.
+
+	* t-builtins.cc (builtin_set): Check to see if the user is setting
+	up parametric plotting.
+	* tree-plot.cc (parametric_plot): New global variable.
+	* tree_const.cc (save_three_d): New function.
+	* tree-plot.cc (tree_subplot_list::print): Handle 3D plots.
+
+	* Makefile.in: Delete everything having to do with distributing or
+	making gnuplot.
+	* configure.in: Likewise.
+
+Thu Apr  8 10:02:52 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* utils.cc (send_to_plot_stream): New function.  Move declaration
+	of plot_stream to utils.cc and make static.
+
+	* t-builtins.cc (builtin_set): New function.
+	* (builtin_show): Ditto.
+
+	* lex.l: Handle set command.
+	* (doing_set): Yet another global variable to control behavior of
+	the lexer.
+
+	* tree-plot.cc (tree_subplot_using::print): Print warning if scanf
+	format string is given.
+
+	* parse.y (ranges1): Allow lower and upper bounds to be optional.
+	* tree-plot.cc (tree_plot_range::print): Make it work.
+
+	* tree-plot.cc: New file, extracted from tree.cc.
+
+	* sighandlers.cc (install_signals): New function.
+	* (*_handler): New set of functions to handle signals that would
+	otherwise cause us to abort.
+	* (my_friendly_exit): Call exit from most signal_handlers to clean
+	up tmp files, etc.
+
+	* lex.l (do_string_escapes): Correctly handle '' quotes.
+	* Warn about unrecognized escape sequences but convert them to the
+	escaped character anyway.
+	* (EXPON): New definition.  Use it and ? qualifier to shorten the
+	expressions for matching numbers.
+	* (ECHAR): New definition.  Use it to correctly match
+	backslash-escaped characters in strings.
+	* Definitions: Surround multi-character definitions in ()'s to
+	avoid potential problems with things like {DEF}*.
+	* (QQ): Rename from DQ.
+	* (DQSTR): New definition for strings in double quotes.
+	* (DQSTRING): New start state.  Recognizing a naked " puts us here.
+	* ("\n"): Turn off quote_is_transpose at the beginning of each line.
+	* Use error functions instead of writing messages directly.
+	* Don't include iostream.h -- we don't need it now.
+	* Do include error.h.
+
+Wed Apr  7 13:12:17 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* sighandlers.h, sighandlers.cc: New files for signal handling
+	functions.
+	* Makefile.in: Include them in the usual places.
+	* octave.cc (interrupt_handler): Move to sighandlers.cc and rename
+	to sigint_handler.
+
+	* utils.cc (mark_for_deletion): New function.
+	* octave.cc (cleanup_tmp_files): New function.
+	* octave.cc (main): Register cleanup_tmp_files with atexit
+	(on_exit for sun).
+
+	* Stack.h: Template based stack class converted from libg++
+	genclass files.
+	* SLStack.h: Likewise.
+	* (SLStack::pop): Avoid apparent bug in SLList::remove_front.
+
+Tue Apr  6 10:01:52 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (almost_match): New function.
+	* (plot_style_token): New function.
+
+	* t-buitlins.cc: Include procstream.h instead of procbuf.h.
+	* (builtin_help): Simplyfy opening of process output stream.
+	* (builtin_who): Likewise.
+
+Mon Apr  5 13:48:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-extras.cc (tree_constant_to_scalar): Move to tree-const.cc
+	and make it a member function called to_scalar.
+	* (tree_constant_to_vector): Likewise.
+	* (tree_constant_to_matrix): Likewise.
+
+	* procstream.h, procstream.cc: New files/classes that implement
+	an ostream to a process.  Built on top of procbuf from libg++.
+	* src/Makefile.in: Add them to the lists of files/objects.
+
+Sat Apr  3 23:11:56 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Lots of clean-up changes to parse.y, tree.cc, tree.h, and
+	tree-base.h.  Use more specific types than just <tree *> for
+	nonterminals.  This allows us to have fewer virtual functions in
+	the base class.  Safer.  Cleaner.  Should have always been this
+	way...
+
+Fri Apr  2 10:04:32 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* parse.y, lex.l: Fix grammar to accept plot command very similar
+	to the gnuplot plot command.
+
+Wed Mar 31 13:11:56 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (eval_undefined_error): Until we can figure out how to
+	clear names without causing problems later on, just remove the
+	symbol name.
+
+	* tree.h (tree_plot_command): New class.
+	* (tree_plot_limits): Ditto.
+	* (tree_plot_range): Ditto.
+	* (tree_subplot_list): Ditto.
+	* (tree_subplot_using): Ditto.
+	* (tree_subplot_style): Ditto.
+
+	* tree-base.h (command_type): Add plot_command to list.
+
+Mon Mar 29 09:53:50 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* find_exec.c (ABSOLUTE_FILENAME_P): Also return true if the
+	given filename begins with `.'.
+
+	* DAE.cc, DAE.h, DAEFunc.h, tc-dassl.cc: Make sure all calls to
+	dassl and the user-supplied functions have consistent argument
+	lists.
+
+	* octave.cc (raw_program_name): New global variable to hold the
+	unprocessed argv[0].  This is to help dld find the absolute path
+	to the executing program.
+	* (initialize_globals): Pass in argc and argv from main.
+	Initialize raw_prog_name.
+
+	* builtins.cc (general_functions): Correct help message for dassl.
+	* g-builtins.cc (dassl_usage): Likewise.
+
+	* src/Makefile.in: Lots of changes to make things work with or
+	without dld.
+	* Makefile.in: Likewise.
+	* configure.in: Likewise.
+
+	* dld: New directory, containing our copy of the dld sources.
+
+	* dynamic-ld.cc, dynamic-ld.h: New files to implement dynamic
+	loading functions.
+	* src/Makefile.in: Add them to the distribution, compile them if
+	doing dynamic loading.
+
+Sun Mar 28 11:03:15 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: When looking for Fortran compilers, check for fc
+	last to avoid confusion with some vendor's /bin/sh fc builtin.
+	* Handle new argument --with-dld.
+
+	* g-builtins.cc (builtin_warranty): Add 1993 to list of copyright
+	dates.
+
+Sat Mar 27 17:58:23 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-extras.cc: Rename from tree-extras.cc.
+	* tc-colloc.cc, tc-dassl.cc, tc-det.cc tc-eig.cc, tc-fft.cc,
+	tc-fsolve.cc, tc-fsqp.cc, tc-ifft.cc, tc-inv.cc, tc-lsode.cc,
+	tc-lu.cc, tc-npsol.cc, tc-qr.cc, tc-quad.cc, tc-rand.cc,
+	tc-svd.cc: Split individual functions from tree-extras.cc.
+
+	* g-builtins.cc (npsol_usage): Improve message.
+	* (dassl_usage): Likewise.
+	* (builtin_lsode): Likewise.
+	* (builtin_fsolve): Likewise.
+	* (builtin_quad): Likewise.
+	* builtins.cc (general_functions): Improve corresponding messages.
+
+	* libcruft/fftpack: New directory for fftpack functions.
+	* libcrutf/fftpack/*.f: Add implicit double precision (a-h,o-z) at
+	the top of every subroutine.
+
+	* tree-extras.cc (fft): Allow propagation of empty matrices.
+	* (ifft): Ditto.
+
+	* Matrix.cc (Matrix::fourier): New function.
+	* (Matrix::ifourier): Ditto.
+	* mx-inlines (make_complex): New function.
+	* tree-extras.cc (fft): Use Matrix::fourier instead of doing real
+	to complex conversion here and calling ComplexMatrix::fourier.
+	* (ifft): Likewise, for ifourier.
+
+Sat Mar 27 17:56:59 1993  Fook Fah Yap (ffy at eng.cam.ac.uk)
+
+	* Matrix.cc (ComplexMatrix::fourier): New function for fft.
+	* (ComplexMatrix::ifourier): New function for inverse fft.
+
+	* builtins.cc (general_functions): Add fft and ifft to the list of
+	builtin functions.
+
+	* g-builtins.cc (fft): New function.
+	* (ifft): Ditto.
+
+	* tree-extras.cc (fft): New function.
+	* (ifft): Ditto.
+
+Sat Mar 27 13:53:39 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (usage_string): New file scope constant.
+	* (getopt_option_string): Ditto.
+
+	* error.cc: Declare all arguments const since we don't change them.
+
+	* utils.cc (print_str_or_null): Delete unused function.
+	* utils.h: Delete declaration.
+
+	* tc-assign.cc, tc-index.cc, tc-inlines.cc, tree.cc,
+	tree-const.cc: More error message cleanups.
+
+	* tree-const.cc (print_if_string): Don't write to cerr
+	unconditionally.
+
+Fri Mar 26 22:00:18 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (min): Avoid function calls as arguments for MIN.
+	* (column_min): Ditto.
+	* (max): Likewise, for MAX.
+	* (column_max): Ditto.
+
+	* tree-const.h (NINT): Make it an inline function instead of a
+	macro.
+
+	* tree-extras.cc (fill_matrix (tree_constant&, double, char*)):
+	Convert to scalar type for complex values too.
+
+	* error.h (panic_impossible): New macro to be used in place of
+	assert (0) calls.
+	* All .cc files: Replace calls to assert (0) and abort () with
+	panic_impossible ().
+
+	* Many .cc files:: Replace many instances of `cerr << ...' with
+	calls to gripe() functions.
+
+	* gripes.h, gripes.cc: New functions for reporting common errors.
+	* Makefile.in: Include them in the usual places.
+
+Thu Mar 25 18:42:49 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Many .cc files:: Replace many instances of `cerr << ...' with
+	calls to error() functions.
+
+	* error.h, error.cc: New functions for reporting errors in a
+	consistent way.
+	* Makefile.in: Include them in the usual places.
+
+Wed Mar 17 17:29:44 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* symtab.cc (symbol_table::save): New functions.
+	* t-buitlins.cc (builtin_save): Use new functions for saving
+	symbols.  Handle case of saving all variables.
+
+	* g-builtins.cc (builtin_pause): If one argument is given, pause
+	for that many seconds before continuing.  Otherwise, wait for user
+	input.
+
+	* symtab.cc (clear): Actually delete undefined symbol_records and
+	remove their names from the list.
+
+	* lex.l (lookup_identifier): New function.  Avoid putting global
+	names in the local symbol table.
+	* ({IDENT}): Use it
+	* ({IDENT}/{S}*=): Ditto.
+
+	* tc-index.cc (do_scalar_index (tree_constant*, int)): Make
+	indexing like a([1,1,1,1]) work for scalars.  GAG.
+
+Tue Mar 16 20:08:23 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-buitlins.cc (builtin_cd): Call tilde_expand (from readline) on
+	the argument.
+
+	* lex.l (discard_until): Delete unused function.
+	* When reading numbers, abort if scanf fails to read a number that
+	we think it should.
+	* (IDENT): New macro to match identifiers.
+	* ([_a-zA-Z][_a-zA-Z0-9]*): Use the / operator for trailing
+	context and split into two cases instead of trying to do the
+	lookahead ourselves.
+
+        * lex.l (do_comma_insert_check): Return the value yyleng had
+        before yyinput() is called.
+        * (DO_COMMA_INSERT_CHECK): New macro.  This avoids the use of
+        unput() in do_comma_insert_check() since there seems to be a bug
+        in flex when calling unput() for '\n'.
+
+	Note that this change is necessary if we want to use yyless()
+	since we cant call yyless() from outside of yylex(), because
+	Flex's yyless() is a macro that uses some variables local to
+	yylex().
+
+Mon Mar 15 11:03:43 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_matrix::eval): Undo part of previous change to
+	make a = [1,2;3,4]; [a,a;a,a] work again.
+
+	* parse.y (input): Don't abort for simple_list followed by EOF.
+
+Sun Mar 14 14:38:56 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* RowVector.cc (RowVector::operator << ()): Insert a space between
+	each element.
+	* (ComplexRowVector::operator << ()): Ditto.
+
+	* g-buitlins.cc (plot): Don't declare plot_prog or plot_term as
+	static, and don't delete them.
+
+	* Matrix.h (all checkelem functions): Don't check for range errors
+	if NO_RANGE_CHECK is defined.
+
+Sat Mar 13 10:18:51 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.cc (ComplexMatrix::prod): Make it work.
+
+Thu Mar 11 00:08:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.h (ellum): Delete function.
+	* Declare and define new const elem, checkelem, and operator()
+	functions.
+
+	* ColVector.cc, DiagMatrix.cc, RowVector.cc, Matrix.cc, ODE.cc,
+	LinConst.cc, FEGrid.cc, DAE.cc, Bounds.cc, FEGrid.h:
+	Change all callers.
+	* tree-const.cc, tree-extras.cc, xdiv.cc, xpow.cc: Ditto.
+
+	* tree.cc (tree_matrix::eval): Improve row and column mismatch
+	checking -- [[1,2];[3,4]] works now, and [1,2;3,4,[5,6]] is
+	rejected.
+	* Reformat error messages to include `error:' prefix.
+
+Wed Mar 10 14:02:09 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (do_comma_insert): New global variable.
+	* (reset_parser): Reset it.
+	* lex.l (do_comma_insert_check): New function.  Call it wherever a
+	token can be directly followed by '['.
+	* (\[{S}*): Check the value of do_comma_insert.
+
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Only look for names in the
+	current symbol table.
+
+	* parse.y (word_list_cmd): Special case to disallow use of clear
+	inside a fuction body.
+
+	* parse.y (CLEAR): New %token.
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Return it if token is "clear".
+
+	* t-builtins.cc (builtin_clear): Allow global symbols to be
+	cleared.
+
+	* symtab.cc (symbol_table::undefine): Clarify comment.
+	* (symbol_table::clear): Don't actually remove names from the
+	table, just force them to be undefined.
+
+	* tree.h (tree_function): Delete unused data member `id'.
+	* tree.cc (tree_function constructors): Don't initialize id.
+
+Mon Mar  8 15:50:28 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.70 released.
+
+	* src/Makefile.in: Update dependencies.
+
+	* tree.h: Include stdio.h, for FILE.
+
+	* gnuplot-build: For now, always define -DNOGAMMA.
+	* configure.in: Don't check for gamma().
+
+	* libcruft/Makerules.in: Don't use lib.a(obj.o) style dependencies
+	because it's too slow for large archives.
+	* liboctave/Makefile.in: Ditto.
+
+Sun Mar  7 16:33:39 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (parse_and_execute): Save and restore current column
+	number.  Set input line and column number to zero.
+	* tree.cc (parse_m_file): Likewise.
+
+	* tree.cc (tree_identifier::parse_m_file (FILE*, int*)): New
+	function.  If a parse error occurs, ensure that the symbol is
+	cleared from the global symbol table.
+	* (tree_identifier::parse_m_file (char*, int): Use it.
+
+	* tree.cc (tree_identifier::do_lookup): New function.
+	* (tree_identifier::eval): Use it.
+
+	* utils.cc (decode_prompt_string): Really do use value of PWD.
+
+	* user_prefs.cc (sv_loadpath, sv_ps1, sv_ps2, sv_pwd,
+	sv_gnuplot_binary, sv_graphics_terminal): New functions.
+	* (sv_graphics_terminal): Warn if terminal isn't valid, but set it
+	anyway (it's too late to do anything by the time the function is
+	called).
+	* In functions that use these variables:  Use the value from the
+	user_pref structure instead of doing a symbol table lookup.
+
+	* builtins.cc (builtin_string_variables): Add functions to call
+	for LOADPATH, PS1, PS2, PWD, gnuplot_binary, and graphics_terminal.
+
+	* builtins.cc (PS2): New builtin_string_variables.  Set default
+	value to "> ".
+	* input.cc (octave_gets): Use it instead of no prompt for
+	continued input.
+
+	* parse.y (yyerror): Use line, column, file name, and text of
+	current input line to print better parse error messages.
+
+	* lex.l (NEW_MATRIX): New exclusive start state.  Need this to be
+	able to match \[{SN}* _and_ get secondary prompting right.
+
+	* input.cc (octave_read): Keep track of current input line.
+	* tree.cc (parse_m_file): Save and restore current line number.
+
+	* lex.l (all patterns): Keep track of current input column.
+	* (fixup_column_count): New function to deal with patterns that
+	match more than one line.
+
+	* input.h, input.cc (current_input_line): Global pointer to
+	the text of the current input line.
+
+	* parse.y, parse.h (input_line_number, current_input_column): New
+	global variables.
+
+	* Almost all source files: Finish (for now, at least) the
+	reorganization we started for global variables.
+
+Wed Mar  3 14:49:59 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tc-assign.cc, tc-index.cc, tc-inlines.cc: New files, split out
+	from tree-const.cc.
+
+	* Almost all source files: reorganize so that all global data is
+	declared in some include file or another.  It probably wouldn't
+	hurt to do some more reorganizing to try to eliminate the amount
+	of global information...
+
+Tue Mar  2 20:49:35 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* variables.h, variables.cc: New files for handling things that
+	need symbol table information.  Lots of files changed to include
+	variables.h, which now includes the extern declarations for the
+	symbol tables.  The declarations of the symbol tables are now in
+	variables.cc, but they are still initialized in octave.cc.
+
+Mon Mar  1 11:35:03 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* builtins.h (builtin_string_variables): New field, sv_function,
+	holds a pointer to the function to call when a variable changes.
+	* builtins.cc (string_variables): Initialize sv_function field.
+	* (install_builtins): While installing builtin string variables,
+	stash sv_function and, if it isn't NULL, call it to initialize
+	global variable user_pref.
+
+	* symtab.h (symbol_record): New field, sv_fcn, holds a pointer to
+	the function to call when a variable changes.
+	* symtab.cc (symbol_record::define): Call sv_fcn if it isn't NULL.
+	* symtab.cc (symbol_record::set_sv_function): New function.
+
+	* utils.cc, parse.y, tree.cc, tree-extras.cc, tree-const.cc,
+	idx-vector.cc, builtins.cc, symtab.cc: Instead of calling
+	functions like do_fortran_indexing(), get the user's preference
+	from the global struct user_pref.
+
+	* utils.h, utils.cc: Delete all functions like do_fortran_indexing()
+	that lookup user variables to find integer values.
+	* user-prefs.h, user-prefs.cc: Move them here, but instead of
+	returning values, set elements of the new global struct user_pref.
+
+	* user-prefs.h, user-prefs.cc: New files for handling global
+	variables for user preferences.
+	* Makefile.in: Add them to the SOURCES and INCLUDES macros.
+
+	* bsd-math/{acosh,asinh,atanh,log1p}.c: Declare all external
+	functions used in each file since they might not be in math.h.
+	* bsd-math/{scalb,copysign,logb,finite,drem,sqrt}.c: New files
+	from BSD's support.c.  Only using scalb, copysign, logb, and
+	finite for now.
+
+	* configure.in: Move tests for f77 closer to the top.
+	* Allow configuration to proceed even if we can't find a Fortran
+	compiler or f2c.
+	* Use `here' documents instead of multiple echos for multi-line
+	messages.
+	* Imrpoved checking for missing math functions.
+
+Sun Feb 28 17:45:53 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* test/Makefile.in (check): Try to avoid errors from cp.
+
+	* mappers.cc (xfinite): Put test for HAVE_FINITE first.
+
+	* libcruft/Makerules.in (LIBCRUFT_DEPEND): Use `=' in assignment
+	instead of `:='.
+
+	* liboctave/Makefile.in: Make an explicit list of sources instead
+	of using $(wildcard).
+
+Thu Feb 25 20:18:12 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* bsd-math/copysign.c: New file.  HP's don't have this?
+	* configure.in (LIBOBJS): Also check for copysign, log1p, and
+	log__L.  For each missing user-level function, add -DFOO_MISSING=1
+	to DEFS.
+	* src/missing-math.h: For each function we declare, check the
+	corresponding XXX_MISSING macro.  Add declarations for copysign
+	and log1p.
+
+Wed Feb 24 20:39:32 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (<MATRIX>{SN}*\]/{S}*==): Change scanning pattern to
+	<MATRIX>{SN}*\]{S}*/== in order to keep flex from generating any
+	backtracking code.
+	* (<MATRIX>{SN}*\]/{S}*=): Likewise.
+
+Tue Feb 23 02:45:00 1993  John W. Eaton  (jwe at ward.che.utexas.edu)
+
+	* Version 0.69 released.
+
+	* mappers.cc [_AIX && __GNUG__] : Provide a definition for
+	finite(), since whatever version we get from the system when using
+	g++ doesn't work (note that it does seem to work with gcc, xlc,
+	and xlC).
+
+	* bugs.texi: Note that the math.h file from libg++ declares
+	finite() incorrectly for some systems.
+
+Mon Feb 22 02:04:16 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Look for runtest, but only believe that it exists
+	if we can also find expect.
+	* test/Makefile.in (check): Run tests in build directory, not
+	source directory.
+
+	* tree.cc (reading_script_file): New global variable.
+	* (parse_m_file): Use it, and properly save and restore state so
+	that nested script files will work.
+
+	* octave.cc (parse_and_execute): Properly save and restore state
+	so that nested script files will work.
+	* Don't close input file here.
+
+	* input.cc (get_input_from (FILE*)): Don't declare mf_instream
+	static.  Set mf_instream if reading and M-file or a script file.
+
+	* parse.y: Minor changes to accomodate new lexer.
+
+	* lex.l: Major overhaul in an attempt to do better string
+	handling.  Looks much simpler and even seems to work.
+	* (do_string_escapes): New function.
+
+Sat Feb 20 00:40:32 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_npsol): If npsol is missing, return empty
+	matrices for x and phi, and -1 for inform.
+
+	* num2str.m: Use %g, not %f.
+
+	* tree.cc (parse_m_file): Save and restor curr_sym_tab, because
+	yyparse may mess with it if it encounters a function definition.
+	* tree-extras.cc (eval_string): Ditto
+	* octave.cc (parse_and_execute): Ditto
+
+	* Makefile.in (DISTDIRS): Add bsd-math to list.
+
+	* src/Makefile.in (LIBOBJS): New macro, value set by configure.
+	(vpath): Add @srcdir@/../bsd-math for LIBOBJS.
+	(octave): Add $(LIBOBJS) to deps.
+	* gnuplot-build/Makefile.in: Likewise, for notgnuplot.
+
+	* configure.in: Use AC_REPLACE_FUNCS to Check for acosh, asinh,
+	atanh, and gamma.
+
+	* bsd-math: New directory for functions from the BSD math library
+	to use as replacements for missing functions.
+
+	* parse.y (semi_comma, comma_semi): New rules.
+	(simple_list, simple_list1): Use them to allow empty statements.
+	(list, list1): Likewise.  This allows empty commands as long as
+	the empty command doesn't contain any newlines.
+
+	* parse.y (simple_assign): New rule, allows things like a = b = c.
+	(multi_assign): Extracted from assignment.
+	(assignment): Split into simple_assign and multi_assign.
+	(expression): Allow '(' simple_assign ')' to be an expression.
+
+	* tree-extras.cc (eval_string): Return result of last expression
+	evaluated, to make things like `eval ('1+1;')*2' work.
+
+Fri Feb 19 19:45:21 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_pwd): Use getcwd, which is defined in
+	unistd.h, instead of getwd, which seems to be a BSDISM.
+	* utils.cc (decode_prompt_string): Ditto.
+	* (get_working_directory): Ditto.
+
+	* arith_ops.cc (DIVIDE_BY_ZERO_ERROR):  Don't rely on
+	HAVE_IEEE_MATH, use HAVE_ISINF, HAVE_FINITE, and HAVE_ISNAN
+	instead.
+	* configure.in: Don't define HAVE_IEEE_MATH.
+
+	* tree-extras.cc: Include stdio.h for FILE.
+
+Thu Feb 18 10:17:38 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (gobble_leading_white_space): New function.
+	* (is_function_file): New function.
+
+	* (parse_m_file): Handle case of .m file being just a file of
+	commands to execute.
+	* Add optional argument to specify whether to execute a script
+	file.
+	* Return whether a script file was executed.
+	* (tree.cc, tree-extras.cc): Change callers.
+
+	* octave.cc (parse_and_execute): new functions.
+	* (execute_startup_files): Use them.
+
+	* lex.l (<COMMENT>\n): Don't gobble new line.
+
+	* num2str.m: Don't print '\n'.
+
+Wed Feb 17 21:59:55 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* mappers.cc: Simplify and correct finite, isinf, isnan functions.
+	* test/octave/t7.oct: New test for finite, isinf, and isnan
+	functions.
+
+	* configure.in: Define HAVE_IEEE_MATH if isnan and either finite
+	or isinf is available.
+
+	* builtins.cc (mapper_functions): Check HAVE_ISNAN instead of
+	HAVE_IEEE_MATH to determine whether or not to define isnan().
+
+	* mappers.cc: Don't check for HAVE_IEEE_MATH.  Just check for
+	individual functions directly.
+
+	* g-builtins.cc (npsol_usage): Correct usage message.
+
+	* g-builtins.cc: Don't include unistd.h unless HAVE_UNISTD_H is
+	defined.
+	* t-builtins.cc: Ditto.
+	* utils.cc: Ditto.
+
+Tue Feb 16 00:35:44 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.68 released.
+
+	* tree.cc (parse_m_file): Set reading_m_file before calling
+	get_input_from_file.
+	* Don't mess with current_infile.
+
+	* input.cc (get_input_from_file): Set mf_instream if we are
+	reading an M-file.  Otherwise, set rl_instream, (even if we aren't
+	really using readline -- this is just the `normal' input stream).
+	* Don't use current_infile.
+	* (octave_read): If not interactive, check reading_m_file to
+	determine where to look for input.
+
+	* octave.cc (main): Don't use readline if we aren't interactive.
+
+	* libcruft/misc/Makefile.in (local-dist): Make sure we don't
+	distribute a bogus d1mach.f.
+	(dist): Ditto.
+
+	* tree-extras.cc (convert_to_ans_assign): New global variable.
+	(eval_string): Conditionally turn off assignment to `ans', for
+	get_user_input ().
+	* parse.y (ans_expression): Use it.
+	* lex.l (reset_parser): Reset it.
+
+	* g-builtins.cc (builtin_input): New function.
+	* builtins.cc (general_fucntions): Add it to the list.
+	* tree-extras.cc (get_user_input): Do most of the real work.
+
+Mon Feb 15 01:14:40 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-builtins.cc (load_variable): New function.
+	(builtin_load): Use it.
+
+	* Makefile.in (SUBDIRS): Add the test directory.
+	(check): Don't depend on all.
+
+Sat Feb 13 05:17:53 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (determinant, lu, matrix_exp, matrix_log,
+	matrix_sqrt): Handle empty matrix argument.
+
+	* Matrix.h: Add constructors of the form Matrix (double a) and
+	ColumnVector (double a) to make it even easier to form single
+	element vectors.
+
+Fri Feb 12 03:27:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (main): Add -v option that will print the version
+	string and quit with a successful exit status.
+
+Thu Feb 11 00:46:34 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (eig): If given an empty argument, return enough
+	empty matrices to fill all possible LHS variables.
+	(qr): Likewise.
+	(svd): Likewise.
+
+	* tree-const.cc (fortran_style_matrix_assignment): Do the right
+	thing if LHS is an empty matrix.
+
+	* tree-extras.cc (qr): Handle empty matrix argument.
+
+	* Matrix-ext.cc (QR): Make it work (really!).
+	(ComplexQR): Ditto.
+
+Wed Feb 10 00:56:31 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* xdiv.cc (xdiv (ComplexMatrix& a, ComplexMatrix& b)): Do
+	btmp.solve (atmp), like the other three xdiv's.  Argh!
+
+	* tree-extras.cc (eval_string): New function.  Mostly works but
+	could be very fragile.  We desperately need some sort of
+	`unwind-protect' scheme to avoid disaster when octave is
+	interrupted.
+
+	* g-builtins.cc (builtin_eval): Instead of just aborting, call
+	eval_string if given one argument.
+
+	* input.cc (octave_read): If get_input_from_eval_string is
+	nonzero, stuff current_eval_string into buf for flex to read.
+
+	* tree-extras.cc (char *current_eval_string): New global variable
+	for eval().
+	* (int get_input_from_eval_string): Ditto.
+
+	* Update copyright notices to include 1993 (now that it's
+	February...).
+
+Tue Feb  9 14:35:08 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.67 released.
+
+	* tree-extras.cc, tree-const.cc: Check the value of the variable
+	`propagate_empty_matrices' to decide what to do about empty
+	matrices in binary and unary operations and some function calls.
+
+	* builtins.cc (builtin_string_variables): New global variable
+	`propagate_empty_matrices' with initial value `warn'.
+	* utils.cc (propagate_empty_matrices): New function.
+
+Mon Feb  8 19:46:51 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-const.cc: Finish changes required to make zero-one indexing
+	work for indexing and assignment.
+
+Sat Feb  6 15:54:10 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* builtins.cc (builtin_string_variables): New global variable
+	`prefer_zero_one_indexing' with initial value `false'.
+	* utils.c (prefer_zero_one_indexing): New function.
+
+Fri Feb  5 13:03:14 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* idx-vector.h, idx-vector.cc: Major overhaul to help with
+	zero-one style indexing.
+	* tree-const.cc (matrix_to_index_vector): Delete functions.
+	* (functions that use idx_vectors): Update for new idx-vector
+	stuff.
+
+	* arith-ops.cc: Don't declare matrix_to_fortran_indices.
+
+	* tree-const.cc (matrix_to_index_vector): Add new argument,
+	allow_neg_one, with default value of false.
+	* (matrix_to_fortran_indices): Add new argument, allow_zero, with
+	default value of false.
+
+	* g-builtins.cc (builtin_find): New function.
+	* builtins.cc (general_fucntions): Add it to the list.
+	* tree-extras.cc (find_nonzero_elem_idx (tree_constant)): Do
+	most of the real work.
+	* tree-extras.cc (find_nonzero_elem_idx (const Matrix&): Do the rest.
+	* (find_nonzero_elem_idx (const ComplexMatrix&): Ditto, for complex.
+
+Wed Feb  3 00:54:01 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in (DEFAULT_DOT_O_FROM_DOT_F): If using f2c, quote
+	with single quotes instead of double quotes to avoid problems on
+	systems (like the NeXT) that strip \'s from double quoted strings.
+
+	* utils.c (empty_list_elements_ok): New function.
+	* tree.cc (matrix_list::eval): Use it.
+	* builtins.cc (builtin_string_variables): New global variable
+	`empty_list_elements_ok' with initial value `warn'.
+
+	* utils.cc (check_str_pref): New function.
+	* (resize_on_range_error, prefer_column_vectors,
+	warn_comma_in_global_decl, do_fortran_indexing,
+	implicit_str_to_num_ok, treat_neg_dim_as_zero,
+	ok_to_lose_imaginary_part, return_last_computed_value,
+	silent_functions, print_answer_id_name): Use it instead of
+	needlessly duplicating code.
+
+Tue Feb  2 16:58:02 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l ("'"): If it looks like we're defining a matrix, don't set
+	the start condition to be MAYBE_QSTRING.  GAK.  There has to be a
+	better way...
+
+	* lex.l: Increment and decrement promptflag instead of just
+	setting its value.  This should help get prompting right for
+	things like if [1,2;3,4] NL ...
+	* input.cc (octave_gets): In order to issue a prompt, Require
+	propmtflag to be greater than zero, not just nonzero.
+
+	* tree.cc (tree_if_command): Allow matrices as the expression to
+	test.  Unlike Matlab, a complex value is false only if both the
+	real and imaginary parts are 0.
+	* tree.cc (tree_while_command): Ditto.
+
+	* tree.cc (tree_for_command): Allow matrices and complex values
+	in the expression.  For matrices, assign each column in turn to
+	the dummy variable.
+
+	* Matrix-ext.cc (qr): Make it work.  The LAPACK book gags me again!
+
+	* xdiv.cc: When computing right division with complex matrices,
+	use hermitian() instead of transpose().
+
+	* lex.l: Return IMAG_NUM for a numeric constant followed by
+	[iIjJ], but don't allow spaces between the numeric constant and
+	the letter (it causes problems inside `[]' where spaces matter...
+
+Mon Feb  1 17:15:19 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree_extras.cc (rand_internal): Make the random number generator
+	give us a different sequence every time we start octave unless we
+	specifically set the seed.
+
+Thu Jan 28 00:10:24 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.66 released.
+
+	* configure.in: Define PLOTLIB in addition to adding -DUNIXPLOT to
+	DEFS if we find -lplot, and call AC_SUBST for PLOTLIB.
+
+	* QP.cc: Define constructors here.
+	* QP.h: Not here.
+
+	* QP.cc (All constructors that are given H): Force H to be
+	symmetric.
+	* (make_h_symmetric): New function.
+
+Wed Jan 27 01:35:53 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* arith-ops.cc (do_unary_op): Do the right thing for complex
+	logical not operator.
+	* Matrix.cc (ComplexMatrix::operator ! (void)): Return Matrix
+	instead of ComplexMatrix.
+	* mx-inlines.cc (not (Complex *d, int len)): For each element of
+	d, return (d[i] == 0.0), not (d[i] != 0.0), and return it as a
+	pointer to double, not Complex.
+
+	* configure.in: Check for libcruft/qpsol/qpsol.f.
+	* Create Makefile in libcruft/qpsol.
+
+	* libcruft/qpsol: New directory.  Copy QPSOL sources here.
+	* libcruft/qpsol/Makefile.in: New file.
+	* libcruft/qpsol/README.MISSING: New file.
+	* libcuft/Makefile.in: Include qpsol in list of directories to
+	make.
+
+	* QPSOL.h, QPSOL.cc: New file for solving QPs with Gill and
+	Murray's QPSOL.
+
+	* QLD.h, QLD.cc: Delete all minimize functions except
+	Vector minimize (double&, int&).
+
+	* QP.h: Declare minimize functions virtual.
+	* (Vector minimize (double&, int&): Declare as a pure virtual
+	function.
+
+	* QP.cc: New file to implement generic minimize functions.
+
+Tue Jan 26 00:27:13 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l: Recognize numbers of the form .{digits}E{digits} and
+	.{digits}E[+-]{digits}
+
+	* lex.l: Recognize .\ as ELEFTDIV.
+	* parse.y: Handle ELEFTDIV.
+	* tree.cc (tree_binary_expression::eval): Handle el_leftdiv.
+
+	* arith-ops.cc (do_binary_op): Handle element by element left
+	division.  Fix some errors in element by element right division.
+
+	* tree-base.h (enum expression_type): Add el_leftdiv.
+
+	* Version 0.65 released.
+
+	* tree-const.cc (tree_constant_rep::eval (tree_constant *args, int
+	nargin, int nargout, int print)): Fix another brain-o in making
+	recursive call.s
+
+	* src/Makefile.in: Complete changes for CXX instead of C++ make
+	variables.
+
+	* tree-const.cc: For assignment and indexing functions, treat
+	complex scalars and matrices in the same branch of the switch as
+	real scalars and matrices -- the double_value() and matrix_value()
+	functions take care of checking to see if it's ok to lose the
+	imaginary part.
+
+	* tree-const.h (tree_constant_rep::is_numeric_type): New function.
+	* tree-const.h (tree_constant::make_numeric functions): Use it.
+
+	* tree-const.h (tree_constant::make_numeric functions): Return
+	*this for complex constants too.
+
+Mon Jan 25 18:31:06 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (Matrix min (Matrix&, Matrix&)): Loop over nc and
+	nr, not nr and nr.
+	* (Matrix max (Matrix&, Matrix&)): Ditto.
+
+	* tree-const.cc (tree_constant_rep::mapper): Fix brain-o in making
+	recursive call.
+
+Sun Jan 24 20:05:39 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: If using f2c, explicitly check for -lf2c.  If it's
+	not found, look for -lF77 and -lI77.  If a suitable combination
+	isn't found, print a warning.
+
+	* src/Makefile.in liboctave/Makefile.in: GNU Make 3.63 uses CXX
+	and CXXFLAGS instead of C++ and C++FLAGS.  Fix things so that 3.63
+	will work without sacrificing compatibility with earlier versions.
+
+	* tree-const.cc (tree_constant_rep::diag (tree_constant&)): Fix
+	brain-o in forcing argument to be numeric.
+
+Fri Jan 22 15:03:42 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (interrupt_handler): Declare to take int argument.
+
+	* NPSOL.cc (npsol_objfun): Delete leftover debugging message.
+
+Thu Jan 21 14:28:24 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Check version of gcc and issue a warning if it
+	looks like 1.something.
+	* Check for g++.  Issue a warning if it is missing or if it is
+	there but it looks like verion 1.something.
+
+	* flibs.sh, f2c-compat.sh: Change file permission to 755 to avoid
+	problems if the uid of the installer is different from the uid of
+	the owner of the files.
+
+Wed Jan 20 04:18:49 1993  John W. Eaton  (jwe at june.che.utexas.edu)
+
+	* libcruft/Makerules.in (@DOT_O_DOT_F_C[1234]@): Patterns deleted.
+	* configure.in: Do multiple line sed substitutions the right way.
+
+Tue Jan 19 14:50:50 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Use new AC_WITH to accept --with-f2c instead of
+	--use-f2c.
+	* Use new AC_HAVE_LIBRARY to find -lplot.
+
+	* flibs.sh: Actually avoid including duplicate -lflags.
+	* Use test, not `['.
+
+Sun Jan 17 16:57:02 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.h: Declare operator+ and operator- functions for vectors.
+	* RowVector.cc: Define half of them.
+	* ColVector.cc: Define the other half.
+
+Fri Jan 15 03:00:46 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/Makefile.in (install): Include version number in name of
+	installed binary and make a link to $(bindir)/octave.
+
+	* Version 0.64 released.
+
+	* t-builtins.cc (builtin_clear): Don't allow the user to clear
+	global symbols by name.  If he tries, issue a warning.
+
+	* tree.cc (tree_identifier::eval_undefined_error):  Don't clear
+	undefined symbols from the global or local (function) symbol
+	tables.
+
+Thu Jan 14 02:10:20 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_function::eval): Save old and set current symbol
+	table context, so eval_undefined_error() doesn't wipe out top
+	level symbols.
+
+	* Version 0.63 released.
+
+Wed Jan 13 13:16:56 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Nearly every .h and .cc file: Add interface and implementation
+	#pragmas for G++ in hopes of making smaller objects with -g.
+
+	* tree-const: Properly handle assignments like A(:) = RHS when
+	do_fortran_indexing is true.
+
+	* g-builtins.cc (builtin_eig): Correct usage message.
+
+	* tree-const.cc (tree_constant_rep (ComplexDiagMatrix&)): Create
+	and initialize a new complex_scalar.  Don't just try to copy the
+	value...
+
+	* Matrix.h: Declare new fill functions for diagonal matrices.
+	* DiagMatrix.cc: Define them.
+
+	* Matrix.h: Declare map functions for row and column vectors.
+	* RowVector.cc: Define them.
+	* ColumnVector.cc: Likewise.
+
+	* CollocWt.h: Declare data protected instead of private.
+	* CollocWt.cc (CollocWt::CollocWt (const CollocWt&)): Fix brain-o.
+
+	* lex.l: Return IMAG_NUM for a numeric constant followed by
+	[ \t]*[iIjJ].
+
+	* parse.y (IMAG_NUM): New token.
+	* (fact): Recogize IMAG_NUM and convert its value to a complex
+	constant.
+
+	* Version 0.62 released.
+
+	* Makefile.in (local-dist): Include -local in tar.Z filename.
+	* (split-local-dist): New target.
+	* (dist): Don't depend on newversion.
+	* (local-dist): Ditto.
+
+	* tree-extras.cc (npsol): If the first argument isn't a vector,
+	print an error message and return.
+
+	* tree.cc (tree_matrix::eval): Always set prev_row_total and
+	prev_column_total when starting out.
+
+	* octave.cc (main): Don't try to detect signal handler failures,
+	but do call signal() to set up the interrupt handler.
+
+Tue Jan 12 19:59:33 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (npsol): Fix brain-o in checking length of bounds
+	vectors.
+
+Mon Jan 11 20:32:24 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (set_rand_seed): New function.
+	(force_to_fit_range): New function.
+	(current_seed): Really return current seed.
+	(rand_internal): Allow the user to actually set the seed for the
+	random number generator.
+
+Sun Jan 10 16:46:06 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.61 released.
+
+	* builtins.h, builtins.cc: Rename from builtin-fcns.h,
+	builtin-fcns.cc (too long for Linux/SysV).
+
+	* mappers.cc (xisinf): For non-IEEE machines, consider DBL_MAX to
+	be infinite.
+
+Fri Jan  8 09:15:57 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* gnuplot-build/Makefile.in (x11targets): Don't worry about
+	checking HAVE_X11_X_H.
+
+	* configure.in: Check for gamma and lgamma for gnuplot.
+
+	* gnuplot-build/Makefile.in (Makefile.X11): Only move Makefile to
+	../Makefile.X11 if xmkmf succeeds.
+
+	* gnuplot-build/Makefile.in (x11targets): Check to see that XMKMF
+	is set *and* that Makefile.X11 exists.
+	* If making notgnuplot_x11 with Makefile.X11 fails, try again with
+	Makefile.
+
+	* gnuplot-build/Makefile.in: Use @PLOTLIB@ in definintion of LIBS.
+	* Don't define UNIXPLOT in TERMFLAGS.
+	* Don't define LN_S; it isn't used anywhere, and configure doesn't
+	give it a value.
+
+	* configure.in: Check for closepl().  If found, define UNIXPLOT,
+	and substitute -lplot for @PLOTLIB at .
+
+	* arith-ops.cc (DIVIDE_BY_ZERO_ERROR): New macro.  On systems that
+	have IEEE math, give a warning but also go ahead and divide by
+	zero.  On systems that don't have IEEE math, just give an error
+	message and return an undefined tree_constant (it would probably
+	be possible to handle this so that it works the same everywhere,
+	but I'm not sure it's worth the effort...).
+
+	* builtin-fcns.cc (install_builtins): On systems that don't have
+	IEEE_MATH, define Inf to be MAX_DBL, but don't define NaN at all.
+
+	* configure.in: Check for finite, isnan, and isinf.
+	* Set HAVE_IEEE_MATH if we find finite and isnan.
+
+	* builtin-fcns.cc (install_builtins): Use HAVE_IEEE_MATH instead
+	of IEEE_MATH.
+	* mappers.cc: Check HAVE_IEEE_MATH and HAVE_ISINF macros rather
+	than checking system type.
+
+	* graph3d.c (hidden_line_plot): Declare dy and y as double, not
+	float, since VERYLARGE can be DBL_MAX.
+
+	* lsoda.f, lsodar.f, lsodes.f, lsodi.f, lsoibt.f, stoda.f,
+	stodi.f, zrotg.f, sdot.f: Remove unused files.
+
+	* texas_lotto.m: Renamed from win_texas_lotto.m to keep the
+	filename less than 14 characters.
+
+Thu Jan  7 15:45:29 1993  John W. Eaton  (jwe at june.che.utexas.edu)
+
+	* utils.cc: Declare ioctl extern "C".
+
+	* tree.cc: Include stdio.h to be sure FILE is defined (apparently
+	not required by older versions of GNU iostream library).
+	* t-builtins.cc: Likewise.
+	* g-builtins.cc: Likewise, but for tmpnam.
+
+	* tree-const.h (rand_internal): Rename from rand to avoid
+	conflict with standard library rand (a macro in Linux).
+	* tree-extras.cc (rand_internal): Fix function definition.
+	* g-builtins.cc (builtin_rand): Call rand_internal instead of rand.
+
+	* octave.cc (main): Don't try to detect signal handler failures.
+	What's the proper way to do this if RETSIGTYPE is void?
+
+Tue Jan  5 08:14:29 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_matrix::eval): When adding a matrix down or to the
+	right, column or row dimension mismatches are always errors.
+
+Mon Jan  4 04:58:55 1993  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.60 released.
+
+	* xdiv.h, xdiv.cc: New files for Octave-specific matrix division
+	stuff.
+	* src/Makefile.in (INCLUDES, SOURCES, OBJECTS): Add xdiv stuff.
+
+	* arith-ops.cc: Include xdiv.h.
+
+Sun Jan  3 12:24:04 1993  John W. Eaton  (jwe at ward.che.utexas.edu)
+
+	* gnuplot-build/Imakefile.in (notgnuplot_x11): In the compile
+	command, put source file before	libraries.
+
+	* libcruft/misc/Makefile.in: Don't use -O to compile gen-dimach.c.
+
+Thu Dec 31 00:45:50 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (matrix_sqrt): Don't create D until it is really
+	needed.
+	* (matrix_log): Ditto.
+	* (matrix_exp): Ditto.
+	[this should really be just one function instead of three...]
+
+	* g-builtins.cc (builtin_sqrtm): New function.
+	* builtin-fcns.cc (general_fucntions): Add it to the list.
+	* tree-extras.cc (matrix_sqrt): Do the real work.
+
+	* Makefile.in: Distribute INSTALL.OCTAVE and configure.in.
+	* (INSTALL.info): Make ../INSTALL.OCTAVE, not ../INSTALL.
+
+	* doc/Makefile.in: Make ../INSTALL.OCTAVE, not ../INSTALL.
+
+	* INSTALL.OCTAVE: Rename from INSTALL.
+	Refer to INSTALL for more info.
+
+	* INSTALL: Copy from autoconf distribution.
+	Refer to INSTALL.OCTAVE for more info.
+
+	* octave.cc (main): Remove leading blank line from startup message.
+	* Don't print it everytime the user types C-c...
+
+	* xpow.cc: Finish off remaining cases.
+
+	* tree-extras.cc (process_format): New function.
+	(do_printf): Use it.
+
+Wed Dec 30 00:43:14 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.56.
+
+	* g-builtins.cc (builtin_logm): New function.
+	* builtin-fcns.cc (general_fucntions): Add it to the list.
+	* tree-extras.cc (matrix_log): Do the real work.
+
+	* g-builtins.cc (builtin_expm): New function.
+	* builtin-fcns.cc (general_fucntions): Add it to the list.
+	* tree-extras.cc (matrix_exp): Do the real work.
+
+	* Matrix-ext.cc (LU): Construct LU decomp. here, not in Matrix class.
+	(ComplexLU): Likewise.
+	* Matrix.cc (lu): Deleted.  Use LU constructor instead.
+	Change all uses in octave sources.
+
+	* Matrix-ext.cc (EIG): Construct EIG object here, not in Matrix class.
+	* Matrix.cc (eig): Deleted.  Use EIG constructor instead.
+	Change all uses in octave sources.
+
+	* Matrix-ext.cc (SVD): Construct SVD here, not in Matrix class.
+	(ComplexSVD): Likewise.
+	* Matrix.cc (svd): Deleted.  Use SVD constructor instead.
+	Change all uses in octave sources.
+
+	* Makefile.in: Update for new Matrix file organization.
+	Don't compile mx-inlines separately -- it's included where needed.
+	* Matrix.h: Declare Fortran routines we call here, not in Matrix.cc.
+	Don't declare every class to be a friend of every other class.
+	* mx-inlines.cc: New file, included by all Matrix-related .cc files.
+	* Matrix.cc: Split into several files.
+	* ColVector.cc: New file, from Matrix.cc
+	* RowVector.cc: Ditto.
+	* DiagMatrix.cc: Ditto.
+	* Matrix-ext.cc: Ditto.
+
+	* tree-extras.cc (svd): Take advantage of new constructors and
+	diag functions.
+
+	* Matrix.cc (DiagMatrix::diag) New function.
+	(ComplexDiagMatrix::diag) Ditto.
+
+	* tree-extras.cc (eig): Take advantage of new constructors.
+
+	* tree-const.cc (tree_constant (DiagMatrix)): New constructor.
+	(tree_constant (ComplexDiagMatrix)): Ditto.
+
+	* Matrix.cc (Matrix (const DiagMatrix)): New constructor.
+	(ComplexMatrix (const DiagMatrix)): Ditto.
+	(ComplexMatrix (const ComplexDiagMatrix)): Ditto.
+
+Tue Dec 29 01:14:49 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (main): Print message at startup by default.
+	Don't print it until just before main loop.
+	* New -q option (inhibit_startup_message) turns it off.
+	* New -f option (read_init_files) inhibits reading of startup files.
+	* Delete -v option.
+	* (verbose_usage): Reflect changes in arguments, document -d.
+
+	* win_texas_lotto.m: Sort picks before returning.
+
+	* tree-extras.cc (eig): Return [v,d], not [l,v], where d is a
+	diagonal matrix made from l.
+
+	* builtin-fcns.cc (mapper_functions): Fix last element of
+	initialization list to have correct number of elements.
+
+	* Version 0.55.
+
+	* Quad.h: Move all inline functions to Quad.cc to avoid apparent
+	g++ bug on the RS/6000.
+
+	* configure.in: If we find flex, don't define LEXLIB.
+
+	* COPYING.LIB: Deleted -- we're not actually distributing anything
+	under these terms.
+	* Makefile.in: Don't distribute COPYING.LIB.
+
+Mon Dec 28 00:46:21 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* xpow.h, xpow.cc: New files for safer pow() interface for octave.
+	* src/Makefile.in (INCLUDES, SOURCES, OBJECTS): Add xpow stuff.
+
+	* arith-ops.cc: Include xpow.h.
+	* Don't declare toplevel jmp_buf.
+
+	* t-builtins.cc (builtin_save): Make file and stream static to
+	avoid dumping core on return (is this a bug in libg++ or g++?).
+	* (builtin_load): Ditto.
+
+	* symtab.cc (load): Make it work again.  Yikes!  This hasn't
+	worked since the big symbol table overhaul...
+
+	* tree-const.cc (tree_constant_rep::save): Handle complex scalars
+	and matrices.
+
+	* (symbol_def::undefine): Delete previous symbol definition before
+	defining.  This should be ok now, after the parse_m_file fix of
+	27 Dec.
+
+	* getting_help: New global flag.
+	* ([_a-zA-Z][_a-zA-Z0-9]*): Set it if looking at "help".
+	* (reset_parser): Clear it.
+	* lex.l (STRING): Use it to determine what to do with ' ; and , .
+
+	* lex.l (QSTRING): Handle the following (C-style) backslash escape
+	sequences correctly(?).
+
+	  \a  bell	   \r  carriage return
+	  \b  backspace    \t  horizontal tab
+	  \f  formfeed     \v  vertical tab
+	  \n  newline	   \\  backslash
+
+	* median.m: New M-file.
+
+	* g-builtins.cc (builtin_sort): New function.
+	* builtin-fcns.cc (general_fucntions): Add it to the list.
+	* tree-extras.cc (sort): Do most of the real work.
+	* tree-extras.cc (mx_sort): Do the rest.
+
+Sun Dec 27 17:40:24 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-builtins.cc (builtin_casesen): New function.
+	* builtin-fcns.cc (text_functions): Add it to the list.
+
+	* strcmp.m: Temporarily allow string to numeric conversions.
+	Maybe strcmp() should be built in to the interpreter?
+
+	* norm.m: New M-file.
+
+	* builtin-fcns.cc (install_builtins): Treat i and j as functions,
+	not variables.
+	* Install inf as an alias for Inf.
+	* Install nan as an alias for NaN.
+
+	* tree.cc (tree_identifier::parse_m_file (char*)): Force new
+	global symbol to be a function, not a variable.
+
+Tue Dec 22 14:15:57 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_function::eval): Check with silent_functions()
+	and return_last_value_computed() to determine proper behavoir.
+
+	* builtin-fcns.cc (silent_functions): New builtin variable.
+	* (return_last_value_computed) Ditto.
+
+	* utils.cc (silent_functions): New function.
+	* (return_last_value_computed) Ditto.
+	[This scheme for determining preferences needs to be reworked...]
+
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Only force yytext[len] to be the
+	end of the identifier if we gobbled some whitespace.
+	* Always unput the last character read.
+
+	* tree.cc (tree_function::eval) Always turn on printing for
+	commands inside functions.
+
+Sat Dec 19 14:03:49 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.54.
+
+Fri Dec 18 16:02:59 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* (symbol_def::undefine): Undo previous change.  Someone is
+	calling this function when they shouldn't be...
+
+	* tree.cc (parse_m_file): If the script file is successfully
+	parsed, Ensure that the new symbol is defined in the global
+	symbol table.
+
+	* lex.l: Handle continuation lines with the pattern
+	{EL}{S}*\n { promptflag = 0; }  // Line continuation.
+
+Thu Dec 17 01:47:14 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* symtab.cc (symbol_def::define): Delete previous symbol
+	definition before defining.
+	(symbol_def::undefine): Ditto, but new definition is always NULL.
+
+	* readline/Makefile.in:  Don't compile emacs_keymap.c and
+	vi_keymap.c since they are included by keymaps.c.
+
+	* configure.in: If RETSIGTYPE isn't int, then define
+	VOID_SIGHANDLER="-DVOID_SIGHANDLER=1".
+	Substitute VOID_SIGHANDLER.
+
+	* readline/Makefile.in (CFLAGS): Add -DVOID_SIGHANDLER if
+	appropriate.
+
+	* tilde.c: Declare xmalloc, not malloc.
+
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Only call unput if we've
+	actually read something.
+
+	* Version 0.53.
+
+Wed Dec 16 01:35:48 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Look in the global symbol table
+	for names, but ignore functions.
+
+	* tree.cc (tree_identifier::eval): Use symbol_out_of_date() to
+	simplify logic for re-parsing M-files.
+	Always look in global symbol table for functions in case the
+	definition has changed (shouldn't the local symbols be undefined
+	anyway??).
+
+	* tree.cc (symbol_out_of_date): New function.
+
+	* symtab.cc (symbol_table::undefine): Actually do something.
+	* (symbol_table::remove_name): Ditto.
+	* (symbol_table::clear): And so on.
+
+	* Matrix.cc (ComplexMatrix::svd): Use complex conjugate transpose,
+	not simple transpose, for V.
+
+	* Version  0.52.
+
+	* gnuplot-build/Imakefile (notgnuplot_x11): In the compile
+	command, put source file before	libraries.
+
+	* parse.y (assignment): If trying to warn against assignment to a
+	function, check is_function() instead of !is_variable().
+
+	* src/Makefile.in: Distribute input.h.
+
+Tue Dec 15 10:48:22 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (main): Call initialize_readline to set up completion
+	functions.
+
+	* input.cc (make_name_list, command_generator, command_completer,
+	initialize_readline): New functions.
+
+	* input.h: New file.
+	* lex.l: Include it instead of input.cc.
+	* src/Makefile.in: Create input.o rather than including it
+	directly in lex.l.
+
+	* builtin-fcns.cc: do_fortran_indexing is now initially false.
+	prefer_column_vectors is now initially true.
+
+	* builtin-fcns.cc (install_builtins): Install i and j
+	 (== sqrt(-1)) as permanent global variables.
+
+	* g-builtins.cc (MAXPATHLEN) Provide default definition here.
+	* t-builtins.cc: Not here.
+
+	* g-builtins.cc (quitting_gracefully, interactive,
+	clean_up_and_exit, verbatim_pwd, getwd) Declare here.
+	* t-builtins.cc: Not here.
+
+	* g-builtins.cc: Also include readline.h and history.h.
+
+	* g-builtins.cc: Include version.h and sys/param.h here.
+	* t-builtins.cc: Not here.
+
+	* g-builtins.cc: Move builtin_clc, builtin_clock, builtin_date,
+	builtin_pause, builtin_quit, builtin_warranty here from
+	t-builtins.cc.
+
+	* builtin-fcns.cc (general_functions): Move builtin_clc,
+	builtin_clock, builtin_date, builtin_pause, builtin_quit,
+	builtin_warranty here from text_functions to limit the number of
+	reserved words.
+
+	* scripts/*.m: Check for correct number of input arguments before
+	proceeding.
+
+	* configure.in (DEFAULT_PAGER): Look for less, more, page, and pg.
+
+	* t-buitlins.cc (builtin_help): If no arguments are given, list
+	all the known operators, keywords, functions, and variables.
+
+	* t-builtins.cc (builtin_help) Pass the output through PAGER using
+	a libg++ procbuf.
+	(builtin_who): Ditto.
+
+	* utils.cc (get_pager): New function.
+
+	* help.h, help.cc: New files to manage lists of help info for
+	keywords and operators.
+
+	* symtab.cc (symbol_record): Implement the Matlab-style semantics
+	of functions using two symbol_def objects.
+	* (symbol_table): Store identifier names in a hash table instead
+	of a linear list.
+	* symtab.cc (symbol_def): New class.
+
+Sat Dec 12 00:00:00 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* parse.y (yyerror): Change error text to be more accurate.
+
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Only look in the current symbol
+	table for names.  Function names and other global symbols are now
+	resolved at execution time.
+
+	* symtab.cc (sorted_var_list): New function.
+	* (sorted_fcn_list): Ditto.
+	* (var_list): Ditto.
+	* (fcn_list): Ditto.
+	These should probably not all be separate functions...
+
+	* t-functions.cc (builtin_who): Call sorted_var_list for each
+	symbol table to print variable names only.
+	* Accept -fcn, -fcns, or -functions to also list function names.
+	* Make -all list function names, but under a separate heading from
+	other symbols.
+
+	* builtin-fcns.cc (is_text_function_name): New function.
+	* lex.l ([_a-zA-Z][_a-zA-Z0-9]*): Use is_text_function_name to
+	find if a name is a text function name instead of relying on the
+	symbol tables.
+
+	* lex.l (is_keyword): New function.
+	([_a-zA-Z][_a-zA-Z0-9]*): Use is_keyword instead of having a
+	special lex pattern for each keyword.
+
+Thu Dec 10 12:25:12 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-builtins.cc: Declare top_level_sym_tab extern.
+
+	* Version 0.51.
+
+Wed Dec  9 02:00:38 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (all user_functions): If the return value from a
+	user's function is bogus, print an error message and abort to the
+	top level.
+
+	* tree-const.cc (all do_matrix_index functions): Major overhaul to
+	simplify and apply range checking before doing the indexing.
+
+	* tree-const.cc (fortran_row, fortran_column, valid_scalar_indices,
+	matrix_to_fortran_indices): Move here from arith-ops.cc and
+	declare as `static inline'.  Delete declarations from arith-ops.h.
+
+	* arith-ops.cc (gripe_nonconformant_assignment): Delete function.
+
+	* tree-const.h (TREE_TO_MAT_IDX): Delete macro.
+	* tree-const.cc (tree_to_mat_idx): Make it an inline function.
+
+	* tree-const.cc (all do_matrix_assignment functions): Major
+	overhaul to simplify resizing and range checking.
+
+	* tree-const.cc (): Move here from arith-ops.cc.
+	Jump to top level on errors.
+	Return max value.
+	(indexed_assign_conforms) New function.
+	(index_check (int)): New function.
+	(index_check (Range)): New function.
+
+Tue Dec  8 21:07:23 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-const.cc (tree_constant_rep::tree_constant_rep (Range):
+	Don't create range constants that have less than 2 elements.
+
+	* utils.cc (jump_to_top_level): New function.
+	* All: Replace calls to longjmp with calls to jump_to_top_level().
+	Don't include <setjmp.h>, except in octave.cc, and utils.cc.
+
+Mon Dec  7 01:57:30 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in: Create Imakefile in gnuplot-build directory.
+	Look for xmkmf, then X11/X.h.
+	* gnuplot-build/Makefile.in: Try harder to get notgnuplot_x11 to
+	build correctly.
+	* gnuplot-build/Imakefile.in: New file, for building
+	notgnuplot_x11 if xmkmf is available.
+
+	* Version 0.50.
+
+	* gnuplot-build/Makefile.in (SUBDIRS): Add docs.
+
+	* tree-const.h (make_numeric_or_range_or_magic): New function.
+	* tree-const.cc (do_matrix_index): Use it instead of make_numeric
+	so that we actually take advantage of all the special cases we
+	have for range types as matrix indices.
+
+	* tree-const.cc (tree_constant_rep::do_matrix_index (int, Matrix)):
+	Fix typo.
+
+	* DAE.cc (integrate): If returning a matrix of values, don't mix
+	time with the states.
+	* ODE.cc (integrate): Likewise.
+
+Sun Dec  6 16:58:41 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (dassl): New function.
+	* g-builtins.cc (builtin_dassl): Make it work.
+	* doc/octave.1: Document it.
+
+	* DAEFunc.h, DAEFunc.cc, DAE.h, DAE.cc: New files.
+
+	* tree-extras.cc (lsode): Clean up.  Use available functions
+	instead of doing everything in line.
+
+	* tree.cc (tree_multi_assignment_expression::eval): Don't define
+	constants that are of unknown type.
+	Try to be smarter about padding after last value.
+
+	* tree-extras.cc (lu): Don't bother trying to return the LU
+	factorization in a single matrix since this isn't really useful
+	and isn't compatible with Matlab anyway (they use Linpack, we use
+	Lapack).
+
+	* tree.cc (tree_identifier::assign (rhs, args, nargs)): Only try
+	to do assignment if rhs is defined.
+
+Sat Dec  5 18:23:55 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (qr): New function.
+	* g-builtins.cc (builtin_qr): New function.
+	* builtins.cc: Add builtin_qr to list of builtin functions.
+	* doc/octave.1: Document it.
+
+	* Matrix.cc (Matrix::lu): Use dgesv from Lapack instead of dgefa
+	since it returns L and U, not some factors that need decoding.
+	(ComplexMatrix:lu): Likewise.
+
+Fri Dec  4 01:51:05 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* configure.in (INCDIRS): Don't include /usr/local/include.
+	(LIBDIRS): Don't include /usr/local/lib.
+
+	* tree-extras.cc (lu): New function.
+	* g-builtins.cc (builtin_lu): New function.
+	* builtins.cc: Add builtin_lu to list of builtin functions.
+	* doc/octave.1: Document it.
+
+	* Matrix.cc (Matrix:lu, ComplexMatrix:lu): New functions.
+	* Matrix.h, Matrix.cc (LU, ComplexLU): New classes.
+
+	* tree-extras.cc (do_quad): New function.
+	* g-builtins.cc (builtin_quad): New function.
+	* builtins.cc: Add builtin_quad to list of builtin functions.
+	* doc/octave.1: Document it.
+
+	* doc/Makefile.in (install): Edit the manpage to substitute
+	correct values in the FILES section.
+	(dist) Depend on octave.info.
+	(local-dist): Ditto.
+
+	* Quad.h, Quad.cc: New files to implement quadrature.
+
+	* NPSOL.cc (npsol_objfun): If compiling with GCC on a Sun, assign
+	to objf via assign_double().
+
+	* sun-utils.h, sun-utils.cc: New files.
+	* sun-utils.cc: Move declaration and definition of MAIN_ here from
+	utils.cc.
+	(access_double): New function, from GCC manual.
+	(assign_double): New function, after access_double.
+
+Thu Dec  3 03:16:03 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* NEWS: New file.
+	* Makefile.in: Distribute it.
+
+	* scripts/*.m: Change to use new end feature.
+
+	* lex.l: Recognize `endif', `endfor', `endfunction', `endif', and
+	`endwhile', in addtion to `end'.
+	* parse.y: Check for command/end mismatches.
+	(end_error): New function.
+	* doc/octave.1: Document it.
+
+Wed Dec  2 11:57:18 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* libcruft/villad: New directory.  Move and split villad.f here
+	from libcruft/misc.
+	* configure.in: Create Makefile in libcruft/villad.
+	* libcruft/Makefile.in: Add libcruft/villad to list of dirs to make.
+
+	* All Makefile.in (uninstall): New target.
+	(distclean): Likewise.
+	(check): Ditto.
+	* Try to make clean targets conform with GNU coding standards.
+
+	* utils.cc (smells_like_X11): New function.
+	* builtin-fcns.cc (install_builtins): Don't set graphics terminal
+	to x11 unless it looks like we're running X11.
+
+	* win_texas_lotto.m: New M-file.
+	* octave.1: Document it.
+
+	* arith-ops.h: New file.
+	* src/Makefile.in: Build arith-ops.o, distribute arith-ops.cc,
+	arith-ops.h.  Maybe this will at least speed up recompiles.
+
+	* THANKS: New file
+	* Makefile.in: Distribute it.
+
+	* configure.in: Create Makefile in gnuplot-build/docs.
+	* gnuplot-build/docs/Makefile.in: New file.
+	* Create and install notgnuplot.gih.
+
+Tue Dec  1 00:15:48 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_identifier::eval (int)): Only pad after if printing.
+	(tree_multi_assignment_expression::eval (int)): Ditto.
+	(tree_assignment_expression::eval (int)): Ditto.
+
+	* hankel.m: Use disp to print message.
+	* toeplitz.m: Ditto.
+
+	* lex.l (<MATRIX>{SN}*\]/{S}*=): Check maybe_screwed_again to
+	decide whether to return SCREW_TWO or ']'.
+
+	* doc/Makefile.in (install): Really install the manpage.
+
+	* Version 0.49.
+
+	* Matrix.cc (ComplexMatrix::operator !): New function.
+	* arith-ops.cc (do_unar_op): Use it.
+
+	* tree-extras.cc (inverse, svd, eig): Don't try to operate on
+	empty matrices.
+
+	* Matrix.h, Matrix.cc: (EIG): New class.
+	(Matrix::eig): New functions.
+	(ComplexMatrix::eig): Ditto.
+	* tree-extras (eig): Use them.
+	* g-builtins.cc (builtin_eig): New function.
+	* builtin-fcns.cc (general_functions): Add eig to list.
+	* dococtave.1: Document it.
+
+	* Matrix.h, Matrix.cc: (ComplexDET): New class.
+	* tree-extras (determinant): Use it.
+
+Mon Nov 30 04:02:29 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.h, Matrix.cc (ComplexSVD): New class.
+	* tree-extras (svd): Use it.
+
+	* Matrix.cc (svd): Use lapack instead of linpack to compute SVD.
+
+	* libcruft/Makefile.in: Replace eispack with lapack in
+	subdirectory list.
+	* libcruft/eispack: Delete directory.
+	* libcruft/lapack/Makefile.in: New file.
+	* configure.in: Create Makefile in libcruft/lapack, not
+	libcruft/eispack.
+
+	* libcruft/lapack: New directory.
+	* Copy files for SVD and Eigenvalue computation here.
+
+	* lex.l (<MATRIX>{SN}*\]/{S}*=): Only return SCREW_TWO if not
+	defining a function.
+
+	* arith-ops.cc (do_binary_op (double, double)): For pow operator,
+	don't create complex value if exponent is really an int.
+
+	* configure.in: Check for f77 last.
+	* Print warnings if bison or lex is not found.
+	* Reformat fatal no f2c/f77 error message.
+
+	* flib.sh: Make it work even if xlf is called f77.
+
+Sun Nov 29 01:55:41 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc: Include f77-uscore.h.
+	* Use F77_FCN macro when declaring or calling Fortran functions.
+
+	* configure.in: After checking to see that it's not garbage, add
+	the output of f2c-compat.sh to DEFS.
+
+	* f2c-compat.sh: Figure out whether or not we need to append an
+	underscore to Fortran function names.
+
+	* flibs.sh: Handle xlf -v output as special case.
+
+	* octave.cc: Only define BADSIG if it isn't already defined.
+	* g-builtins.cc: Ditto.
+
+	* configure.in: Don't create man/Makefile.
+	* man: Directory deleted.
+	* doc/Makefile.in: Distribute and install octave.1.
+	* doc/octave.1: Renamed from man/octave.1.
+
+Sat Nov 28 15:54:39 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* man/Makefile.in (install): Install manpage.
+	* octave.1: rename from octave.man
+	* octave.1: Document builtin variables and command line editing
+	(stolen from bash man page).
+
+	* tree-const.cc (eval (int print)): Convert complex values to real
+	if imaginary part is zero.
+
+	* octave.cc (log_usage): Deleted.
+	(main): Don't call log_usage.
+
+	* g-builtins.cc (builtin_sqrt): Delete.
+	(builtin_log): Ditto.
+	(builtin_log10): Ditto.
+
+	* tree-const.h, tree-const.cc (sqrt_internal): Delete.
+	(log_internal): Ditto.
+	(log10_internal): Ditto.
+
+	* tree-const.cc (mapper): Handle neg_arg_complex.
+
+	* builtin-fcns.h (Mapper_fcn): New field neg_arg_complex.
+	* builtin-fcns.cc: (mapper_functions[]): Initialize it for list of
+	mapper functions.
+	* builtin-fcns.cc: (mapper_functions[]): Move log, log10, and sqrt
+	back here from general_functions[].
+
+Fri Nov 27 17:05:21 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (tree_constant_to_vector): Handle complex scalars
+	and matrices.
+
+Wed Nov 25 17:32:42 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* man/octave.man: New file, very incomplete.
+	* man/Makefile.in: Include octave.man in list of files to
+	distribute.
+
+	* g-buitlins.cc (builtin_rand): Handle nargin == 1.
+	* tree-extras.cc (rand): Likewise.
+
+	* rem.m: New M-file.  Implemented as M-file because it's much
+	simpler!
+
+	* configure.in (DEFAULT_DOT_C_FROM_DOT_F): Escape % characters in
+	rule to avoid problems with autoconf, which uses % for sed command
+	delimeters.
+	(DEFAULT_DOT_O_FROM_DOT_F): Ditto.
+
+Tue Nov 24 00:21:34 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (fill_matrix): Don't try to create matrices with
+	negative dimensions.
+	(frobit): Likewise.
+
+	* utils.cc (check_dimensions): New function.
+
+	* utils.cc (treat_neg_dim_as_zero): New function.
+	* builtin-fcns.cc (treat_neg_dim_as_zero): New builtin variable,
+	default value is false.
+
+	* tree-const.h (tree_constant::bump_value): Like, assign, check
+	reference count and possibly make a new copy before changing
+	anything.
+
+	* tree-base.h (is_builtin): New virtual function.
+	* tree.cc (tree_builtin::is_builtin): New function.
+
+	* parse.y (ans_expression): Also check to see if the lone
+	expression is a builtin text-style function invoked without any
+	arguments.
+
+	* octave.cc, t-builtins.cc: Print copyright and other normal
+	(non-error) message on cout instead of cerr.
+
+	* t-builtins.cc (builtin_warranty): Don't return message in
+	retval.
+	(builtin_history): Likewise.
+	(builtin_help): Also.
+	(builtin_who): Ditto.
+
+	* Version 0.48.
+
+	* tree-extras.cc: Fix most functions to handle complex arguments.
+	Still need to finish SVD and DET (waiting for these functions in
+	the Matrix class).
+
+	* tree.cc (tree_multi_assignment::eval): Optionally print names
+	for result variables.
+
+	* tree-const.h (tree_constant::eval (int print, int nargout)):
+	New function.  Simply ignore nargout.
+	* tree.cc (tree_matrix::eval (int print, int nargout)): Ditto.
+
+	* tree.cc (tree_parameter_list::name): New function.
+
+	* lex.l (<NEWMAT>): Delete rules, start condition because they are
+	unecessary.
+
+	* lex.l (<MATRIX>{SN}*\]): Split into three rules.  Use trailing
+	context instead of home-brew lookahead.
+
+Mon Nov 23 00:51:51 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* utils.cc (ok_to_lose_imaginary_part): New function.
+	* builtin-fcns.cc (ok_to_lose_imaginary_part): New builtin
+	variable, default value is warn.
+
+	* tree-const.h (double_value): Maybe return real part if invoked
+	for complex tree_constant.
+	* tree-const.h (matrix_value): Ditto.
+
+	* Version 0.47.  This one wasn't tested, but there have been a lot
+	of significant changes and I wanted a backup.
+
+	* tree-const.cc (sqrt_internal): New function.  Sqrt isn't
+	implemented as a mapper function since negative real arguments
+	give complex results.
+	(log_internal): Ditto.
+	(log10_internal): Ditto.
+	* builtin-fcns.cc: Move sqrt, log, and log10 from mapper struct
+	initializer to general function struct initializer.
+
+	* rot90.m: New M-file.  Still needs rem() to be complete.
+
+	* tree-const.cc (mapper): Handle mapper functions for complex
+	variables.
+
+	* mappers.h, mappers.cc: New file for mapper functions.
+
+	* builtin-fcns.h, builtin-fcns.cc: Rename from builtins.h
+	builtins.cc.
+
+	* flipud.m: Don't do indexing on lhs.
+	* fliplr.m: Likewise.
+
+Sun Nov 22 17:09:36 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* arith-ops.cc (do_binary_op (double, double)): Handle a^b for
+	a < 0.
+
+	* builtins.cc: Make sqrt a general builtin function instead of a
+	mapper function.
+	* g-builtins.cc (builtin_sqrt): New function.
+	* tree-const.cc (sqrt_internal): New function.
+
+Sat Nov 21 16:41:02 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-const.h, tree-const.cc:  Complete most changes required to
+	handle complex types.  There are lots of details, most will be
+	omitted here.
+
+	* tree-const.h (is_real_type) New function.
+	(is_complex_type): Ditto.
+	(is_scalar_type): Ditto.
+	(is_matrix_type): Ditto.
+
+	* tree-const.h (REP_RHS_MATRIX, REP_ELEM_ASSIGN, CRMATRIX,
+	ASSIGN_CRMATRIX_TO, CRMATRIX_ASSIGN_REP_ELEM,
+	CRMATRIX_ASSIGN_ELEM): New macro for dealing with real and complex
+	matrices in the same tree_constant_rep function.
+
+	* tree-const.cc: Include arith-ops.cc.
+
+	* arith-op.cc: New file for functions that implement unary and
+	binary operations for the tree_constat classes.
+	* Mark all operations that aren't implemented yet with a
+	FIXME comment.  There are about 35-40 things left to fix
+	in this file.
+
+Thu Nov 19 00:25:16 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.46.
+	[ This one wasn't tested, but there have been a lot of significant
+	changes and I wanted a backup. ]
+
+	* tree-const.cc (tree_constant_rep::do_unary_op): Handle Complex.
+	(do_unary_op (Complex&, tree::expression_type)): New function.
+	(do_unary_op (ComplexMatrix&, tree_expression_type): Ditto.
+
+	* tree-const.cc (tree_constant_rep::assign): Handle Complex
+	(still needs updated support functions in order to work).
+
+	* tree.cc (tree_matrix::eval): Handle Complex.
+	(tree_identifier::eval): Ditto.
+	(tree_for_command::eval): Ditto.
+
+Wed Nov 18 23:33:13 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree_const.cc (tree_constant_rep::rows): Handle Complex.
+	(tree_constant_rep::columns): Ditto.
+	(tree_constant_rep::all): Ditto.
+	(tree_constant_rep::any): Ditto.
+	(tree_constant_rep::cumprod): Ditto.
+	(tree_constant_rep::cumsum): Ditto.
+	(tree_constant_rep::prod): Ditto.
+	(tree_constant_rep::sum): Ditto.
+	(tree_constant_rep::sumsq): Ditto.
+
+	* tree_const.h, tree_const.cc (tree_constant::complex_value): New
+	function.
+	(tree_constant_rep::complex_value): Ditto
+	(tree_constant::complex_matrix_value): New
+	(tree_constant_rep::complex_matrix_value): New
+
+	* tree_const.cc (tree_constant_rep::~tree_constant_rep): Handle
+	complex scalars and matrices.
+	(tree_constant_rep::force_numeric): Ditto.
+	(tree_constant_rep::make_numeric): Ditto.
+	(tree_constant_rep::eval): Ditto.
+	(tree_constant_rep::bump_value): Ditto.  C++, for C == a
+	complex value is C = C + 1.  Should I even do this?  Hmmm.
+
+	* tree-const.h, tree-const.cc: Begin adding support for Compelex.
+	* Add complex_scalar and complex_matrix to value union.
+	* Add complex_scalar_constant and complex_matrix_constant to type
+	tag enum.
+	* New constructors.
+
+	* Matrix.h, Matrix.cc: Major changes to add Complex support.
+
+Tue Nov 17 14:40:45 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Matrix.cc (RowVector::operator (const Matrix&)): New function.
+
+	* Matrix.cc (ColumnVector::transpose): New function.
+	Eliminate friend function that served the same purpose.
+	(RowVector::transpose): Ditto.
+
+Mon Nov 16 09:57:33 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (QSTRING): Fix to allow '' inside a string to represent a
+	single quote.  Makes computer.m a little funnier.
+
+Fri Nov 13 18:46:39 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.45.
+
+	* computer.m: New M-file.
+	* tril.m: Ditto.
+	* triu.m: Ditto.
+
+	* doc (*.texi): Can now produce BUGS, INSTALL, and octave.info
+	files without generating errors, though the organization is
+	probably till very wrong.
+
+	* Makefile.in (newversion): Add magic to handle major versions
+	other than 0, and major/minor versions of any length.
+
+Thu Nov 12 01:37:45 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.h, tree-const.h, builtins.cc, g-builtins.cc,
+	tree-extras.cc: Conditionally compile code for NPSOL and FSQP
+	based on FSQP_MISSING and NPSOL_MISSING.
+	* g-builtins.cc (builtin_npsol): If NPSOL is missing, always call
+	npsol_usage() to print out message indicating why NPSOL doesn't
+	work.
+	* g-builtins.cc (builtin_fsqp): Likewise for FSQP.
+
+	* configure.in: Check for srcdir/libcruft/npsol/npsol.f and
+	srcdir/libcruft/fsqp/fsqp.f.  If missing, define NPSOL_MISSING or
+	FSQP_MISSING and add them to DEFS.
+
+	* libcruft/npsol/README.MISSING: New file.
+	* libcruft/fsqp/README.MISSING: Ditto.
+
+	* libcruft/npsol/Makefile.in (dist): Don't distribute sources
+	because of license restriction.  Do distribute Makefile.in and
+	README.MISSING.
+	* libcruft/fsqp/Makefile.in (dist): Ditto.
+
+	* All Makefile.in files (local-dist): New target, usually the same
+	as dist.
+
+	* parse.y (ans_expression): Check to see that the RHS isn't just
+	an identifier.
+	* tree.cc (tree_identifier::eval (int)): Maybe print id name.
+	* tree.cc (tree_assignment::eval (int)): Ditto.
+	* buitlins.cc (print_answer_id_name): New builtin variable.
+	* utils.cc (print_answer_id_name): New function.
+
+Tue Nov 10 10:58:36 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (log_usage): Surround with #if 0/#endif.
+
+Mon Nov  9 13:42:54 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* symtab.cc (load): Only issue error mesasge if attempt to find
+	_first_ name keyword fails.
+
+	* tree-const.cc (make_numeric_or_magic): New function.  Like
+	make_numeric except also pass magic_colons.
+	* tree-const.cc (all do_matrix_index functions): Matrix ndices can
+	be naked colons, so use make_numeric_or_magic on index arguments
+	instead of make_numeric.
+
+	* liboctave/Makefie.in (install): Install .h files in $(includedir).
+	(includedir): New macro, default value $(prefix)/include.
+
+	* tree.cc (tree_function::eval (int print)): Force arguments to be
+	undefined.
+
+	* tree-const.h (tree_constant::assign (rhs, args, nargs)): Check
+	reference count before assigning.
+	* tree.cc (tree_identifier::assign (rhs, args, nargs)): Don't eval
+	lhs before doing assignment.
+
+	* tree.cc (parse_m_file): Gobble leading white space, including
+	comments.
+
+Fri Nov  6 16:52:59 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.44.
+
+	* g-builtins.cc (builtin_getenv): New function.
+
+	* isempty.m: New M-file.
+
+	* g-builtins.cc (builtin_exist): New function.
+	* utils.cc (identifier_exists): Handle the dirty details.
+
+	* utils.cc (warn_comma_in_global_decl): New function.
+	* builtins.cc (warn_comma_in_global_decl): New builtin variable.
+	Initial value is true.
+	* parse.y (global_decl): Handle global declarations here,
+	including optional initialization.
+	* t-builtins.cc (builtin_global): Deleted.
+
+Thu Nov  5 23:59:39 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_feval): New function.
+	* tree-extras.cc (feval): Handle the dirty details.
+
+	* g-builtins.cc (builtin_rand): New function.
+	* tree-extras.cc (rand): Handle the dirty details.
+
+Wed Nov  4 14:54:17 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* num2str.m: New M-file.
+	* int2str.m: Ditto.
+
+	* g-builtins.cc (builtin_disp): New function.
+
+	* g-builtins.cc (builtin_fprintf, builtin_printf,
+	builtin_sprintf):  New functions.
+	* tree-extras.cc (do_printf): New function to handle the gory
+	details.
+
+	* g-builtins.cc (builtin_flops): Implement here because we may
+	actually want to count operations at some point.
+
+Tue Nov  3 17:06:40 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-const.cc (do_binary_op): Detect and give error message for
+	optations on empty matrices.
+	(do_unary_op): Likewise.
+
+	* parse.y (matrix): Convert `[]' and `[;]' to empty matrices
+	instead of (tree_matrix *) NULL.
+
+Mon Nov  2 11:23:40 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* src/Makefile.in: Update dependencies.
+	* liboctave/Makefile.in: Ditto.
+
+	* tree-const.cc (force_numeric): Consult matlab_strings()
+	before doing string to number conversion.
+	* builtins.cc (matlab_strings): New builtin variable.
+	* utils.cc (matlab_strings): New function.
+
+	* tree-extras.cc (linear_constraints_ok): New function.
+	(linear_constraints_ok): Ditto.
+	(npsol): Use them to avoid creating inconsistent sets of
+	constraints and crashing.  It would really be nice to have
+	exception handling.
+
+	* symtab.cc (load): Issue error mesasges if attempt to find
+	name keyword fails.
+
+	* Version 0.43.
+
+	* tree-extras.cc (npsol): Use new minimize (phi, inform).
+	Handle nargout == 3.
+
+	* g-builtins.cc (builtin_npsol): Allow nargout == 3.
+
+	* NPSOL.cc (set_default_options): New function.
+	(all constructors): Use it.
+	(operator =): Use it and print warning message (setting default
+	options doesn't represent a true copy and it would be somewhat
+	difficult to fix this...).
+
+	* npchkd.f (npchkd): Only write message if msglvl > 0.
+
+Sun Nov  1 00:58:16 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* gnuplot-build/Makefile.in (LIBDIRS): Set correctly.
+	(notgnuplot): Use it.
+
+	* libcruft/misc/gen-d1mach.c: Generate d1mach.f at build time
+	instead of depending on the installer to get it right.
+	* libcruft/Makefile.in (gen-d1mach): New target.
+
+	* libcruft/Makerules.in (SPECIAL): New macro.
+	(DISTFILES): Include it.
+
+	* libcruft/Makerules.in (SPECIAL_DEPEND): Ditto.
+	(../../libcruft.a): Use it.
+
+Mon Oct 26 02:25:11 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (is_valid_function): Try harder to find M-files
+	that may not have been parsed yet.
+
+	* symtab.cc (define (symbol_record*)): New function.  Make it
+	simple to copy all fields of a symbol_record if we already have
+	one.
+	* utils.cc (force_global): Use it.
+
+	* utils.cc (valid_identifier): Allow underscores in names.
+
+	* tree-extras.cc (npsol): Force column vector to be returned.
+	(fsolve): Ditto.
+
+	* Version 0.42.
+
+	* tree-extras.cc (fsolve): New function for solving nonlinear
+	algebraic equations.  This needs much more work if it is to
+	provide all the functionality of Matlab's fsolve.
+
+	* tree-extras.cc (fsolve_user_function): New function.
+
+	* libcruft/minpack: Import needed functions.
+
+	* tree-extras.cc: (npsol (tree_constant*, int, int): Completely
+	rewrite to handle all of the follwing:
+
+	  1. npsol (x, phi)
+	  2. npsol (x, phi, lb, ub)
+	  3. npsol (x, phi, lb, ub, llb, c, lub)
+	  4. npsol (x, phi, lb, ub, llb, c, lub, nllb, g, nlub)
+	  5. npsol (x, phi, lb, ub,              nllb, g, nlub)
+	  6. npsol (x, phi,         llb, c, lub, nllb, g, nlub)
+	  7. npsol (x, phi,         llb, c, lub)
+	  8. npsol (x, phi,                      nllb, g, nlub)
+
+	* tree-extras.cc (npsol_constraint_function): New function.
+
+	* tree-extras.cc (tree_constant_to_vector): New function.
+	(tree_constant_to_matrix): Ditto.
+	(takes_correct_nargs): Ditto.
+
+Fri Oct 23 10:19:51 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (is_valid_function): New function.
+	(npsol): Use it.
+
+	* utils.cc (s_plural): New function.
+	(es_plural): Ditto.
+
+	* tree-extras.cc (npsol): Improve checks for valid objective
+	function.
+
+	* tree.cc (tree_function::max_expected_args): New function.
+
+Thu Oct 22 18:42:07 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_lsode): Quick check of arguments, then
+	call lsode (tree_constant *, int, int).
+	* Move rest of code for implementing builtin_lsode to
+	tree-extras.cc.
+
+	* g-builtins.cc (builtin_npsol: Quick check of arguments, then
+	call npsol (tree_constant *, int, int).
+	* Move rest of code for implementing builtin_npsol to
+	tree-extras.cc.
+
+	* tree-const.cc: Simplify functions that require numeric arguments
+	by always calling make_numeric for them instead of doing it
+	conditionally.
+	* tree.cc: Ditto.
+	* tree-extras.cc: Ditto.
+
+	* tree-const.h (tree_constant::make_numeric): Return *this if
+	already a numeric type.
+
+	* NLP.cc: In constructors, don't try to assign NULL to bounds
+	objects.
+
+	* tree-const.cc (tree_constant_rep::valid_as_scalar_index (void)):
+	New function.
+	* tree-const.cc (valid_scalar_indices (tree_constant*, int):
+	New function.
+	* tree-const.cc (tree_constant_rep::do_scalar_index): Simplify by
+	using functions to determine if arguments are valid as indices.
+	(tree_constant_rep::do_scalar_assignment): Likewise.
+
+Wed Oct 21 14:11:58 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-extras.cc (determinant): Make it work again.
+
+	* tree.cc (tree_identifier::eval (tree_constant*, int, int, int):
+	Simplify logic.  Only have one ans->eval() call.
+
+	* tree-const.cc (tree_constant_rep::eval (tree_constant*, int,
+	int, int): Properly handle indexing of range constants.
+
+	* tree-const.cc (stupid_fortran_style_matrix_index): Preserve row
+	or column orientation for vectors.
+
+	* toeplitz.m: New M-file.
+	* invhilb.m: Ditto.
+	* hankel.m: Ditto.
+
+	* tree-extras.cc (max): Handle two arg case.
+	tree-extras.cc (max): Likewise.
+	(min (Matrix&, Matrix&): New function.
+	(max (Matrix&, Matrix&): Ditto.
+
+Tue Oct 20 15:13:57 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.41.
+
+Mon Oct 19 16:46:35 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* rows.m: New M-file.
+	* g-builtins.cc (builtin_rows): Delete function.
+	* g-builtins.h (builtin_rows): Delete declaration.
+	* builtins.cc (general_functions): Delete from initialization list.
+
+	* columns.m: New M-file.
+	* g-builtins.cc (builtin_columns): Delete function.
+	* g-builtins.h (builtin_columns): Delete declaration.
+	* builtins.cc (general_functions): Delete from initialization list.
+
+	* length.m: New M-file.
+	* g-builtins.cc (builtin_length): Delete function.
+	* g-builtins.h (builtin_length): Delete declaration.
+	* builtins.cc (general_functions): Delete from initialization list.
+
+	* g-builtins.cc (builtin_size): If two values are expected to be
+	returned, put nr and nc in separate registers.
+
+Sun Oct 18 13:37:17 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree-base.h: Extract base tree class declarations from tree.h.
+	* tree-const.cc, tree-const.h: Extract tree_constant class from
+	from tree.cc, tree.h.
+	Change all uses of tree.h to use either or both of tree-base.h and
+	tree-const.h.
+
+	* Matrix.cc (solve): Replaces LinEqn class.
+	tree.cc (do_binary_op) Use it.
+
+	* g-builtins.cc (builtin_max): New function.
+	tree.cc (tree_constant::max): New friend.
+
+	* g-builtins.cc (builtin_min): New function.
+	tree.cc (tree_constant::min): New friend.
+
+	* cond.m: New M-file.
+
+	* rank.m: New M-file.
+
+	* g-builtins.cc (builtin_svd): New function.
+	tree.cc (tree_constant::svd): New friend function.
+
+	* g-builtins.cc (builtin_svd): New function.
+	tree.cc (tree_constant::svd): New friend function.
+
+	* t-builtins.cc (builtin_format): New function.  Implement some of
+	the Matlab options (sort of).
+
+	* Major changes to liboctave source.  A new Matrix.cc/Matrix.h
+	completely replaces the old Matrix/Vec/AVec code.  All other
+	classes that use Matrix/Vector objects have been updated (or
+	deleted, if they are no longer needed).  All callers changed in
+	octave sources.
+
+Sun Oct 11 21:22:16 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_function::eval): Don't define more function
+	parameters than are expected.  If fewer arguments than expected
+	are actually supplied, force them to be undefined.
+
+	* parse.y (fact): Give warning and abort for identifiers followed
+	by '['.  This should catch most improper uses of [] instead of ()
+	for indexing operators.
+
+	* tree.cc (do_binary_op (Matrix&, Matrix&, tree::expression_type):
+	Handle element by element exponentiation.
+
+Tue Sep 22 10:09:06 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.40.
+
+Mon Sep 21 13:09:06 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l: Accept ** and .** as well as ^ and .^ as exponentiation
+	operators.
+
+Fri Sep 18 15:19:51 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.h tree.cc utils.cc g-builtins.cc: Elimitate need for
+	overloaded operator-> in the tree_constant class.  Also eliminate
+	uses of ->string, ->scalar, etc.  Instead, always call
+	.string_value(), .double_value(), etc.
+
+	* builtins.cc (install_builtins): Reserve `ans' as an
+	uninitialized global variable (should it really be global?).
+
+	* parse.y (ans_expression): Handle default assignemnt to builtin
+	variable ans.
+	(command): Use it.
+
+Tue Sep 15 14:06:12 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.39.
+
+	* tree.cc (tree_identifier::bump_value): Don't try to increment
+	undefined symbols or values.
+	(tree_prefix_expression::eval): Don't call bump_value if id is a
+	NULL_TREE.
+	(tree_prefix_expression::eval): Likewise.
+
+	* g-builtins.cc (lsode_builtin): Handle extra arguments.
+	liboctave/ODE.cc (integ): Add template for handling bad returns
+	from lsode.
+
+	* tree.cc (class tree_return_command): Implementation is just like
+	break and continue.  Something seems wrong about this...
+	lex.l (return): Recognize return statement.
+	parse.y (statement): Handle function returns.
+	tree.cc (various eval functions): Check to see if we are returning
+	from a function.
+
+	* tree.cc (tree_for_command::eval): Set abort_on_undefined when
+	evaluating the loop body.
+	(tree_while_command::eval): Ditto.
+
+	* tree.cc (class tree_idenfier): Improve searching/parsing M-files
+	when handling undefined names.
+	tree.cc (tree_identifier::parse_m_file (char*)): New function.
+	(tree_identifier::parse_m_file (void)): Use it.
+
+	* utils.cc (force_global): New function.
+	* symtab.cc (symbol_table::remove_name(char *)): New function.
+
+	* tree.h, tree.cc (class tree_constant): Split into two classes,
+	tree_constant (handle) and tree_constant_rep (body) to enable use
+	of `smart pointers' and reference counted memory management.
+	(Lots of things are different with this change.)
+
+Sat Aug 22 11:58:27 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.38.
+
+	* lex.l (COMMA_KLUDGE): Delete production, all uses.  This doesn't
+	seem to be necessary anymore, and the mystery output lines
+	disappear without it.
+
+	* builtins.cc (make_eternal (char *)): New function.
+	(install_builtins): Make LOADPATH, eps, pi, Inf, and NaN eternal.
+
+	* New M-files: mean.m, std.m, hadamard.m, vander.m, hilb.m,
+	linspace.m, logspace.m.
+
+	* tree.cc (tree_function::eval): Don't check number of arguments
+	supplied against total number possible (previously thought to be
+	`expected') so that user-defined functions can have variable
+	numbers of arguments.
+
+	* tree.cc (tree_identifier::eval_undefined_error): New function.
+	(tree_identifier::eval): Use it.
+
+	* octave.cc (abort_on_undefined): New global symbol to control
+	whether we should jump to top level after an undefined symbol has
+	been encountered.
+	tree.cc (tree_function::eval) Set it before evaluating function
+	body, restore to previous value after successful completion.
+	tree.cc (tree_identifier::eval_undefined_error): Use it
+
+Fri Aug 20 09:31:14 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc:  New mapper functions:
+	isnan: Uses xisnan, which calls IEEE function isnan.
+	isinf: Uses xisinf which calls IEEE functions finite and isnan,
+	or isinf if available.
+	finite: Uses xfinite, which calls IEEE function finite.
+	abs: Uses fabs.
+
+	* g-builtins.cc	(sumsq): New function.
+	(diag): New function.
+
+	* tree.cc (tree_constant::sumsq): New function
+	(tree_constant::diag): New function
+
+	* Matrix.cc (sumsq): New function.
+	(diag): Ditto.
+
+Thu Aug 20 00:36:44 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_error): New function.
+
+	* gnuplot-build/Makefile.in (dist): Actually create `term'
+	subdirectory.
+
+	* Lots of changes to tree.cc tree_assignment_expression::eval and
+	tree_index_expression::eval to make matrix indexing work like
+	Matlab.
+	(do_fortran_indexing): New user-level variable to control this
+	behavior.  If this variable is false, things like
+
+	  a([1,2;3,4], [1,2;3,4]) = b
+
+	become syntax errors.  Otherwise, Matlab braindamage prevails.
+
+Tue Aug 18 13:15:46 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.37.
+
+	* tree.cc (do_matrix_assignment): Conditionally allow single
+	indices for Matrix assignments.
+	(do_matrix_index): Ditto.
+
+	* utils.cc (do_fortran_indexing): New function.
+	utils.h: Declare it.
+	builtins.cc (install_builtins): Default value for new
+	do_fortran_indexing variable.
+
+	* builtins.cc (install_builtins): Bind eps to the value
+	DBL_EPSILON from float.h.  Make it read only (will this cause
+	trouble)?
+	* Bind Inf to 1/0 (will only work for IEEE machines.
+	* Bind NaN to 0/0 (will only work for IEEE machines.
+	* Add round, fix, floor, ceil, and sign to builtin mapper functions.
+	(round): New function.
+	(fix): Ditto.
+	(signum): Ditto.
+	* Add clc (clear screen function).
+	* Add home (clear screen function).  To be just like Matlab, this
+	wouldn't clear the screen.
+
+	* New M-files: fliplr.m, flipud.m, trace.m, reshape.m.
+
+	* utils.cc (bind_variable): Revise bind_string_variable so that it
+	takes a tree_constant as an argument.
+	(bind_protected_variable): Likewise for the function
+	bind_protected_string_variable.
+	(bind_string_variable): Delete.
+	(bind_protected_string_variable): Ditto.
+	utils.h: Fix declarations.
+	builtins.cc t-builtins.cc: Fix callers.
+
+	* builtins.cc (install_builtins): Bind LOADPATH here.
+	octave.cc (initialize_globals): Not here.
+
+	* Makefile.in (SOURCES): Add new scripts directory.
+	(scripts): New target.
+	libcruft/Makefile.in (install): Don't depend on all.
+
+	* utils.cc (m_file_in_path): Get path from LOADPATH variable.
+	tree.cc (tree_identifier::parse_m_file): Modify caller.
+
+	* src/Makefile.in (OCTAVE_M_FILE_DIR): New variable.
+	(utils.o): Use it.
+	utils.cc (default_path): Use it.
+
+	* utils.cc (pathstring_to_vector): New function.
+	(default_path): Return colon separated path instead of vector of
+	paths.
+	* octave.cc (initialize_globals): Use pathstring_to_vector here.
+	Bind output of default_path to LOADPATH variable.
+	Eliminate octave_path global variable.
+
+	* tree.cc (isstr): New function.
+	(all): Ditto.
+	(any): Ditto.
+	(cumprod): Ditto.
+	(cumsum): Ditto.
+	(prod): Ditto.
+	(sum): Ditto.
+
+	* g-builtins.cc (builtin_isstr): New function.
+	(builtin_all): Ditto.
+	(builtin_any): Ditto.
+	(builtin_cumprod): Ditto.
+	(builtin_cumsum): Ditto.
+	(builtin_prod): Ditto.
+	(builtin_sum): Ditto.
+
+	* Matrix.cc (all): New function.
+	(any): Ditto.
+	(cumprod): Ditto.
+	(cumsum): Ditto.
+	(prod): Ditto.
+	(sum): Ditto.
+
+	* scripts: New directory.
+	scripts/strcmp.m: New file (first M-file function in distribution!).
+	scripts/Makefile.in: New file.
+	configure.in: Include scripts/Makefile in list of files to create.
+
+Sat Aug 15 18:32:24 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.36.
+
+Fri Aug 14 08:44:10 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (id_to_define): New global variable.
+	(curr_m_file_name): Ditto.
+	(current_infile): Ditto.
+
+	* tree.h tree.cc (tree_identifier::parse_m_file): New function.
+	(tree_identifier::eval): Handle M-files.
+
+	* tree.h (stash_m_file_name): New virtual function.
+	(stash_m_file_time): Ditto.
+	(time_parsed): Ditto.
+	(m_file_name): Ditto.
+
+	* tree.h tree.cc (tree_function::stash_m_file_name) New function.
+	(tree_function::stash_m_file_time): Ditto.
+	(tree_function::time_parsed): Ditto.
+	(tree_function::m_file_name): Ditto.
+
+	* lex.l (reading_m_file): New global variable.
+	(delete_buffer): New function.
+	(yywrap): New function.  Always return 0 (is this a smart thing to
+	do?).
+
+	* parse.y (func_def2): Handle input from m-files (sort of).
+
+	* octave.cc (octave_path): New global variable.
+	(using_readline): Ditto.
+	(no_line_editing): Ditto.
+
+	* octave.cc (main): Initialize current_command_number before
+	calling setjmp.
+	* Increment it in main command loop, not in parse.y.
+
+	* utils.h utils.cc (default_path): New function.
+	(m_file_in_path): Ditto.
+	(is_newer): Ditto.
+
+	* octave.cc (main): Execute commands here.
+	* parse.y (input): Not here.
+
+	* octave.cc (tree *global_command): New global variable that
+	points to the current command to be executed.
+
+Thu Aug 13 07:08:11 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* parse.y: Make word_list_cmd a fact, not a command, so that
+	things like `y = who -all' can work.  You can't do that in Matlab.
+
+	* t-builtins.cc (builtin_who): Print symbols in columns, sorted.
+	(list_in_columns) New function, mostly stolen from GNU ls.
+
+	* symtab.h symtab.cc (char **list (void)) New function.
+	(char **sorted_list (void) New function.
+
+	* tree.cc (various eval functions): Handle printing results of
+	text and general functions here.  Straighten out other printing
+	stuff, maybe...
+
+	* t-builtins.h t-builtins.cc: Make text functions return
+	tree_constant* instead of int, delete print flag argument.
+
+	* g-builtins.h g-builtins.cc: Delete print flag argument.
+
+	* Version 0.35.
+
+Wed Aug 12 15:12:23 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_builtin::eval): Call mapper function with
+	print = 0 to avoid getting two answers.
+	(specific do_matrix_assignment functions): Handle resizing
+	correctly for `:' indices.
+	(tree_colon_expression::eval): Don't crash if the evaluation of
+	an operand yields a NULL_TREE_CONST.
+
+Mon Aug 10 07:31:37 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_identifier::define):  Return NULL_TREE_CONST if
+	symbol_record::define fails.
+	(tree_identifier::assign): Likewise.
+
+	* symtab.h (symbol_lifetime): New attribute for symbol_records.
+	Can be either temporary or eternal.
+	(symbol_class): Delete eternal attribute.
+	* builtins.cc (install_builtins): Mark all builtins as eternal.
+
+	* Version 0.34.
+
+	* tree.h: Delete ttype, enum list of tree types.
+
+	* g-builtins.h g-builtins.cc (builtin_colloc): New function.
+
+	* liboctave (various): Add missing return values, etc. so that
+	liboctave compiles cleanly.
+
+	* tree.h tree.cc (tree_multi_assignment): New class to implement
+	assignments to more than one variable.  Does it work?  Maybe...
+
+	* tree.h (tree_constant **eval (int, int)): New virtual function.
+	(is_identifier): Another one.
+
+	* symtab.h (eternal): New class for symbol_records.
+	* symtab.h symtab.cc (make_eternal): New function.
+	* builtins.cc (install_builtins): Make builtin variables eternal.
+
+	* tree.cc (list_to_vector): Surround by `#if 0/#endif' to avoid
+	compilation warning.
+
+Sun Aug  9 03:18:38 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* t-builtins.h t-builtins.cc (builtin_cd): New function adapted
+	from bash for changing the current working directory.
+	(builtin_pwd): New function adapted from bash for printing the
+	current working directory.
+
+	* utils.h utils.cc: New functions from bash for changing and
+	printing the current working directory:
+
+            pathname_backup        make_absolute
+            get_working_directory  change_to_directory
+
+	* utils.h utils.cc (bind_string_variable): New function.
+	(bind_protected_string_variable): Likewise.
+
+	* octave.cc (initialze_globals): New function.
+
+	* utils.h utils.cc: New functions from bash, mostly for fancy
+	prompting:
+
+	    polite_directory_format  absolute_pathname
+	    absolute_program         base_pathname
+	    read_octal               sub_append_string
+	    decode_prompt_string
+
+Thu Aug  6 02:39:31 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* octave.cc (initialize_history): Fix up to
+	(octave_hist_file) New global variable.
+	(octave_hist_size) Ditto.
+	(history_lines_this_session) Ditto.
+	(history_lines_in_file) Ditto.
+
+	* input.cc (octave_gets): Keep track of number of lines read
+	during the current session.
+
+	* utils.cc (default_history_file): New function.  Look for
+	OCTAVE_HISTFILE environment variable and use its value if
+	possible.
+	(default_history_size): New function.  Look for OCTAVE_HISTSIZE
+	environment variable and use its value if possible.
+
+	* t-builtins.cc (builtin_history): Steal from bash and modify to
+	work with octave.
+
+	* g-builtins.cc (builtin_det): New function.
+
+	* tree.h tree.cc (determinant): New function
+
+	* g-builtins.cc: Rewrite functions that use fill_matrix, inverse,
+	and identity_matrix to use new versions implemented as friends of
+	tree_constant.  This is being done in an attempt to get rid of all
+	calls to tree_constant::const_type() outside of tree.cc.
+
+	* tree.cc (tree_constant): Implement new functions for filling
+	and inverting tree constants as matrices, and for creating an
+	identity matrix from a tree_constant.
+
+	* g-builtins.cc (builtin_inv): New function.
+	builtins.cc: Allow builtin_inv to be called as either inv(A) or
+	inverse(A).
+
+	* tree.cc (do_binary_op (Matrix, Matrix)): Better handling of
+	solution of linear equations for square coefficient matrices.
+
+	* LinEqn.cc (solve): Don't exit on singular matrices.  Implement
+	new variations of these functions that will allow status checking.
+
+	* src/Makefile.in: Define GNUPLOT_BINARY and SITE_DEFAULTS.
+	Specific rules for octave.o and builtins.o to avoid defining
+	GNUPLOT_BINARY and SITE_DEFAULTS for all .cc targets.
+
+	* builtins.cc: Use macro GNUPLOT_BINARY.
+
+	* octave.cc (execute_startup_files): Use macro SITE_DEFAULTS.
+	Execute commands from SITE_DEFAULTS file.
+
+	* t-buitlins.cc (builtin_pause): Make it work.
+
+	* configure.in: Check for termio.h and/or sgtty.h.
+
+	* octave.cc (clean_up): Reset terminal state to cooked mode.
+	(main) Likewise, after return from SIGINT signal handler.
+
+	* utils.h utils.cc (raw_mode): New function (mostly stolen from
+	less(1)) toggle input processing for stdin to raw/cooked modes.
+	(kbhit): New function to read one character from cin in raw mode
+	without echoing it.
+
+	* builtins.cc: Fix expected number of arguments in lists of
+	builtins.
+
+	* tree.h tree.cc (max_args_expected (void)): New virtual function.
+	(tree_builtins::) Provide a definition of it.
+
+	* lex.l (identifier): Before gobbling up text function arguments,
+	check to see that we expect some.
+
+	* symtab.h symtab.cc (max_args_expected): Return max args expected
+	by a symbol (currently only valid for tree_builtins).
+
+Wed Aug  5 05:03:59 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* utils.h utils.cc (resize_on_range_error): Decide what to return
+	based on value of global variable of same name.
+	(prefer_column_vectors): Likewise.
+
+	* Version 0.33.
+
+	* parse.y (func_def2): Call define (tree *, symbol_type), not
+	define (tree *), so that the symbol type is set for user-defined
+	functions.
+	(assignment): Catch assignments to functions here.
+
+	* tree.h tree.cc (tree_identifier::define (tree *, symbol_type):
+	New function (be careful out there...).
+
+	* symtab.h (symbol_type): Add new `user_function' enum value.
+
+	* tree.cc (do_matrix_assignment): Call prefer_column_vectors().
+
+	* tree.h tree.cc (do_matrix_assignment (...)): New functions to
+	implement assignment to indexed matrices.
+	(do_scalar_assignment (...)): New function to implement assignment
+	to an indexed scalar.
+
+	* utils.h utils.cc (resize_on_range_error): New function.  Should
+	eventually decide what to return based on value of global variable
+	of same name.
+	(prefer_column_vectors): New function.
+
+Tue Aug  4 05:37:47 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_constant::save): New function.
+	(tree_constant::load): New function.
+
+	* symtab.cc (symbol_record::save): New function.
+	(symbol_table::load): New function.
+
+	* t-builtins.cc (builtin_load): Start implementation.  Yikes, this
+	is probably going to need a lot of work to be very robust...
+
+	* t-builtins.cc (builtin_save): Implement by asking the
+	symbol_record to save itself.  Maybe this should really be done by
+	asking the symbol table to save a symbol...
+
+	* utils.cc (extract_keyword): New function.
+	(valid_identifier): New function.
+
+Fri Jul 31 04:16:24 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* parse.y (func_def3): Extra error cases for empty function
+	bodies.
+	(func_def1, func_def1a, func_def1b): Slighly straighten out some
+	truly twisted logic, eliminate func_def1a, rename func_def1b to
+	func_def1a, and make statementss like function [x,y] = foo() end
+	work properly (I think).
+	(func_def*): Put function name in global symbol table, not top
+	level symbold table.  This makes them accessible from other
+	functions, eh?
+
+	* t-builtins.cc (builtin_who): Accept -all, -local, -global, and
+	-top flags.
+
+Thu Jul 30 00:39:40 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* lex.l (current_buffer): New function to return current flex
+	input buffer.  Will need this to be able to switch file contexts.
+
+	* Version 0.32.
+
+	* lex.l (create_buffer, switch_to_buffer): New functions to handle
+	input from various streams.  This should be enough to allow us to
+	implement Matlab-like M-files.
+	octave.cc (main, execute_startup_files): Use them.
+
+	* octave.cc (execute_startup_files): Execute commands from
+	$HOME/.octaverc and ./.octaverc.
+
+	* g-builtins.cc (builtin_plot): Delete temporary files.
+	Ignore SIGINT while gnuplot is executing.
+
+Wed Jul 29 20:16:25 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (all_args_defined): New function to check a
+	tree_constant** vector to see if all elements are non-null.
+	(tree_index_expression::eval (int)): Use it, and abort the
+	evaluation if test fails.
+
+	* terminals.h, terminals.cc: New files for doing things with
+	gnuplot graphics terminal names.
+	src/Makefile.in: Handle new files.
+
+Tue Jul 28 00:25:24 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* g-builtins.cc (builtin_plot): Make it work, at least halfway.
+
+	* g-builtins.cc (builtin_save): New function.
+
+	* gnuplot-build/Makefile.in: Add -DREADLINE and remove readline.o
+	from list of objects to actually enable the GNU command line
+	editing.
+
+	* configure.in: Use AC_PROG_CHECK macro to search for f2c and f77.
+	Check for several common Un*x Fortran compilers.
+	Add extra messages.
+
+	* g-builtins.cc g-builtins.h: New files for builtin general
+	functions extracted from builtins.cc.
+
+	* t-builtins.cc t-builtins.h: New files for builtin text functions
+	extracted from builtins.cc.
+
+	* Makefile.in (split-dist): New target.
+
+	* Version 0.31.
+
+Mon Jul 27 22:01:58 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_constant::do_matrix_index (tree_constant **, int):
+	Allow single argument to work for matrices that are really row or
+	column vectors.
+
+	* lex.l: Accept `<>' in addition to `!=' and `~=' as `not equal'
+	comparison operators.
+
+	* libcruft/Makerules: Allow for compiling the Fortran routines
+	with the native Fortran compiler instead of translating to C.
+
+	* f2c-compat.sh, flibs.sh: New scripts which try to determine
+	whether it will be possible for us to use the system's Fortran
+	compiler directly, and if so, what libraries to add to the loader
+	command.  These scripts are known to work on SPARCstations running
+	SunOS and DECstations running Ultrix.  Not tested elsewhere...
+	* configure.in: Use them.
+	* Makefile.in: Distribute them.
+
+Wed Jul 22 00:04:48 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* builtins.cc: Begin implementation of NLP solver using NPSOL.
+
+Tue Jul 21 13:44:13 1992  John W. Eaton  (jwe at june.che.utexas.edu)
+
+	* octave.cc: If printing version information, also print pointer
+	to warranty info.
+
+	* builtins.cc: Implement the Matlab functions ones, zeros, eye,
+	clock, date, size, length, and global.
+	Implement warranty builtin.
+	(builtin_clear): Fix to work with global variables.
+
+	* symtab.cc (clear): Fix to work properly with global variables.
+
+Mon Jul 20 11:58:23 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc (tree_constant::do_matrix_index (tree_constant**, int)):
+	Make string indices work.
+	(tree_constant::force_numeric): Don't special case
+	single-character strings (this uncovers a flaw in the design of
+	the constructor for the magic colon operator...).
+
+Fri Jul 17 16:33:00 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.30.
+
+	* tree.cc: Delete undefined identifiers when trying to eval them.
+
+	* builtins.cc: Add beginnings of builtin who and clear functions.
+
+	* symtab.cc symtab.h (clear): New function.
+
+	* tree.cc, tree.h, parse.y: Implement matrix indexing with colon
+	expressions, implement the magic colon operator for column and row
+	selection.
+
+	* tree.cc tree.h: Completely rework colon expressions.
+
+Thu Jul 16 09:27:48 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* gnuplot-dist: Rename from gnuplot-3.2 so we're not tied to a
+	version number.
+
+Tue Jul 14 11:22:35 1992  John W. Eaton  (jwe at ward.che.utexas.edu)
+
+	* tree.cc builtins.cc: Make argc/nargs/nargin work like C:
+	the argument count is the number of command line arguments plus
+	the function name.  This goes for `argument lists' for matrices as
+	well as functions.  It seems a bit awkward but at it's consistent,
+	and it's like C.  Hmm.  Maybe this is a bad choice...
+
+	* utils.cc utils.h: New files for utility functions.
+
+Mon Jul 13 00:29:50 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.29.
+
+	* tree.cc tree_constant::tree_constant (matrix): Automatically
+	convert 1x1 matrices to scalars.
+
+	* parse.y lex.l: Fix up a bunch of stupid stuff and reduce the
+	number of shift/reduce conflicts to 16 (all but one because of the
+	optional separator garbage).
+
+	* parse.y lex.l: Allow for assignments to lists of identifiers to
+	be partially parsed.  This will still require some error checking
+	in tree.cc to ensure that the list is made up of identifiers only,
+	since that's not enforced by the grammar (I don't see a way to do
+	it, do you?)
+
+Sun Jul 12 11:24:33 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* tree.cc tree.h parse.y lex.l: Implement logical AND (symbol &),
+	OR (symbol |), and not (symbol ~).  Also provide the C-style
+	operators &&, ||, and !).
+
+	* Matrix.cc Matrix.h: Provide stupid element-wise logical
+	operators for matrices.
+
+	* Version 0.28.
+
+	* parse.y lex.l tree.cc tree.h: Implement C-style prefix and
+	postfix increment and decrement operators (symbols ++ and --
+	respectively).
+
+	* parse.y lex.l tree.cc tree.h: Implement break and continue.
+
+	* tree.cc tree.h: Assignment to matrix elements roughed out.
+
+	* gnuplot/tree.cc: Solution of linear equations via the lift
+	division operator partially implemented.  Singular coefficient
+	matrices aren't handled very well yet...
+
+	* gnuplot-build/Makefile.in: Make this work to build gnuplot for
+	generic X11/unix environments.
+	* Remove -Wall from CFLAGS to avoid loads of warnings.
+	* Use GNU readline instead of the one that comes with gnuplot.
+
+	* gnuplot-build/*.diff: Various patches for various things.
+
+Sat Jul 11 10:14:12 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.26
+
+	* src/Makefile.in: Distribute lex.cc, parse.cc, y.tab.h.
+	* src/Makefile.in (dist): Depend on lex.cc and parse.cc.
+
+	* gnuplot-build: New directory for patching and building gnuplot.
+	This is apparenty required because the gnuplot license won't allow
+	distrubution of modified versions, but will allow patches to be
+	distributed.
+	* gnuplot-build/Makefile.in: New file.
+
+	* gnuplot-3.2: New directory.
+
+	* readline: New directory from the bash-1.12 distribution, plus
+	tilde.c from bash's lib/glob directory and xmalloc.c from bash's
+	lib/malloc directory.
+	* readline/Makefile.in, readline/doc/Makefile.in,
+	readline/examples/Makefile.in: New files.
+
+	* All Makefie.in files: Allow make to work from any directory, not
+	just the top level one.
+
+Fri Jul 10 22:20:56 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* SERVICE: Remove, since it seems too specific to GNU products.
+
+Thu Jul  9 07:48:33 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.20.
+
+	* Solution of ODEs with LSODE partially implemented.  It's
+	possible to solve some simple equations.
+
+	* tree.cc tree.h (tree_constant): Add string constants and make
+	them work more or less like string constants in Matlab (implicit
+	conversion to ASCII numbers -- gag.  This isn't complete, and it
+	it assumes that ASCII is the character set for the host
+	machine/compiler...).
+
+Tue Jul  7 07:28:35 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.19.
+
+	* User defined function definitions and calls to them mostly work.
+	Still need to implement multiple return values correctly.
+
+Mon Jul  6 04:23:37 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.18.
+
+	* lex.l parse.y tree.cc tree.h: Begin implementation of
+	user-defined functions.
+
+Sun Jul  5 19:27:08 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.17.
+
+	* lex.l: Replace SAVE_STRING macro with a function.
+
+	* builtins.cc (builtin_document): New builtin function.
+	(builtin_help): Make it work.
+
+	* lex.l: More rules for gathering text.  These are still not quite
+	as they should be, but they will work in most cases.  I think the
+	flex generated scanner is either going to have to be reworked or
+	replaced with a handemade version at some point (probably soon)...
+
+	* tree.cc tree.h: Add tree_word_list and tree_word_list_command
+	classes for text functions.
+
+Fri Jul  3 05:13:15 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.16.
+
+	* builtins.h builtins.cc: New files for builtin functions.
+	Implement a few simple builtin functions.
+
+	* tree.cc tree.h: Add tree_builtin type for builtin functions.
+
+	* tree.cc tree.h: eval (args...) New virtual function.
+
+Thu Jul  2 01:27:38 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.15.
+
+	* symtab.h, symtab.cc: Allow variables and functions to be tagged
+	as read-only or read-write.
+
+Wed Jul  1 15:54:36 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* input.cc and octave.cc: allow input to come from a file.
+
+	* lex.l: to accept `#' as a comment character (allows one to
+	use the `#!/bin/octave' style script hack).
+
+	* doc: New directory containing skeleton stuff
+	* SERVICE: New file from GCC.
+	* BUGS: New file, now produced from doc/bugs.texi.
+	* INSTALL: New file, now produced from doc/install.texi.
+
+Sat Jun 27 15:52:37 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.14.
+
+	* Fixed parser to eliminate reduce/reduce conflicts.
+
+	* Fixed parser to recognize assignment to multiple identifiers
+	(e.g., [E,V] = eig (A); ).
+
+	* Quickie implementation of indexed array evaluation.  Works for
+	scalar indices, but not range/array indices.
+
+Fri Jun 26 04:23:12 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.12.
+
+	* Hooks added for indexed array evaluation and assignment.
+	* Colon expression implementation improved.
+	* Implementation of for command eval() improved.
+
+Thu Jun 25 00:28:12 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.11.
+
+	* Colon expressions added.
+	* For command added, but the implementation needs work.
+
+Wed Jun 24 15:09:36 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.10.
+
+	* Cheesy signal handler added to catch interrupts.
+
+	* Matrix input works, even for nested matrices.  Some error
+	checking is done while the matrix is evaluated to ensure that
+	the number of rows and columns match up.
+
+Mon Jun 22 00:21:49 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.9.
+
+	* Command line matrix input partially implemented.  It's not yet
+	possible to enter nested matrices, but it is possible to enter
+	simple matrices (e.g. [1,2;a,b+c], where a, b, and c are scalars.
+
+	* Version 0.8.
+
+	* If commands added.
+
+	* Version 0.7.
+
+	* Command chains added.
+	* Boolean operations added, tested for scalars.
+	* While loop added, tested for simple commands.
+
+Fri Jun 19 05:50:44 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.6.
+
+	At this early stage, while a lot of changes are being made very
+	quickly, ChangeLog entries will probably just list features added.
+
+	* Variable assignment works for scalars.
+	* Simple scalar expressions work.
+
+Thu Jun 18 06:44:24 1992  John W. Eaton  (jwe at schoch.che.utexas.edu)
+
+	* Version 0.5.
+
+	* src/version.h: For all the pre-alpha distributions, count
+	versions as 0.1, etc. instead of 0.01.
+
+	* Makefile: (dist) Automatically update version_string in
+	src/version.h.
+
+	* symtab.h, symbtab.cc: New files for symbol tables.
+
+	* tree.h, tree.cc: New files for parse trees.
+
+	* Lots of work unrecorded here.  Octave is now self-contained, the
+	tree routines are being redesigned, etc.
+
+Fri Mar 20 17:03:16 1992  John W. Eaton  (jwe at andy.che.utexas.edu)
+
+	* Version 0.02.  Octave understands some simple matrix
+	expressions, but it is not yet possible for matrix elements to
+	be constructed from expressions.
+
+Thu Mar 19 06:13:39 1992  John W. Eaton  (jwe at andy.che.utexas.edu)
+
+	* Version 0.01.  Octave understands simple scalar expressions.
+	Hey, Hey!  It is not yet self contained -- I'm still linking to
+	the old libraries in /usr/local/c++-classes, and this isn't likely
+	to change for a while.  (Other things are much more important than
+	making the distribution work on other machines.  Sorry...)
+
+Fri Feb 21 05:06:38 1992  John W. Eaton  (jwe at andy.che.utexas.edu)
+
+	* Version 0.00.  This includes the basic directory structure,
+	makefiles, and a lot of the old Fortran source, including a way to
+	make a libcruft.a.  Octave compiles and accepts input (with
+	history and editing) but doesn't do much else.
+
+Wed Feb 19 06:20:44 1992  John W. Eaton  (jwe at andy.che.utexas.edu)
+
+	* ChangeLog: New file.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..448c663
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,236 @@
+This file is the generic INSTALL document distributed with autoconf.
+It is intended as a basic guide for all autoconf-generated configure
+scripts.  See the file INSTALL.OCTAVE for information specific to
+installing Octave.
+
+========================================================================
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/INSTALL.OCTAVE b/INSTALL.OCTAVE
new file mode 100644
index 0000000..c65f69b
--- /dev/null
+++ b/INSTALL.OCTAVE
@@ -0,0 +1,403 @@
+This file documents the installation of Octave.
+
+   Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation.
+
+   *Note:* This file is automatically generated from
+`doc/interpreter/install.txi' in the Octave sources.  To update the
+documentation make changes to the .txi source file rather than this
+derived file.
+
+1 Installing Octave
+*******************
+
+   Here is the procedure for installing Octave from scratch on a Unix
+system.
+
+   * Run the shell script `configure'.  This will determine the features
+     your system has (or doesn't have) and create a file named
+     `Makefile' from each of the files named `Makefile.in'.
+
+     Here is a summary of the configure options that are most
+     frequently used when building Octave:
+
+    `--prefix=PREFIX'
+          Install Octave in subdirectories below PREFIX.  The default
+          value of PREFIX is `/usr/local'.
+
+    `--srcdir=DIR'
+          Look for Octave sources in the directory DIR.
+
+    `--enable-bounds-check'
+          Enable bounds checking for indexing operators in the internal
+          array classes.  This option is primarily used for debugging
+          Octave.  Building Octave with this option has a negative
+          impact on performance and is not recommended for general use.
+
+    `--enable-64'
+          This is an *experimental* option to enable Octave to use
+          64-bit integers for array dimensions and indexing on 64-bit
+          platforms.  You probably don't want to use this option unless
+          you know what you are doing.
+
+          If you use `--enable-64', you must ensure that your Fortran
+          compiler generates code with 8 byte signed `INTEGER' values,
+          and that your BLAS and LAPACK libraries are compiled to use 8
+          byte signed integers for array dimensions and indexing.
+
+    `--enable-shared'
+          Create shared libraries (this is the default).  If you are
+          planning to use the dynamic loading features, you will
+          probably want to use this option.  It will make your `.oct'
+          files much smaller and on some systems it may be necessary to
+          build shared libraries in order to use dynamically linked
+          functions.
+
+          You may also want to build a shared version of `libstdc++',
+          if your system doesn't already have one.
+
+    `--enable-dl'
+          Use `dlopen' and friends to make Octave capable of dynamically
+          linking externally compiled functions (this is the default if
+          `--enable-shared' is specified).  This option only works on
+          systems that actually have these functions.  If you plan on
+          using this feature, you should probably also use
+          `--enable-shared' to reduce the size of your `.oct' files.
+
+    `--without-blas'
+          Compile and use the generic BLAS and LAPACK versions included
+          with Octave.  By default, configure first looks for BLAS and
+          LAPACK matrix libraries on your system, including optimized
+          BLAS implementations such as the free ATLAS 3.0, as well as
+          vendor-tuned libraries.  (The use of an optimized BLAS will
+          generally result in several-times faster matrix operations.)
+          Only use this option if your system has BLAS/LAPACK libraries
+          that cause problems for some reason.  You can also use
+          `--with-blas=lib' to specify a particular BLAS library  that
+          configure doesn't check for automatically.
+
+    `--without-ccolamd'
+          Don't use CCOLAMD, disable some sparse matrix functionality.
+
+    `--without-colamd'
+          Don't use COLAMD, disable some sparse matrix functionality.
+
+    `--without-curl'
+          Don't use the cURL, disable the `urlread' and `urlwrite'
+          functions.
+
+    `--without-cxsparse'
+          Don't use CXSPARSE, disable some sparse matrix functionality.
+
+    `--without-umfpack'
+          Don't use UMFPACK, disable some sparse matrix functionality.
+
+    `--without-fftw'
+          Use the included FFTPACK library instead of the FFTW library.
+
+    `--without-glpk'
+          Don't use the GLPK library for linear programming.
+
+    `--without-hdf5'
+          Don't use the HDF5 library for reading and writing HDF5 files.
+
+    `--without-zlib'
+          Don't use the zlib library, disable data file compression and
+          support for recent MAT file formats.
+
+    `--without-lapack'
+          Compile and use the generic BLAS and LAPACK versions included
+          with Octave.  By default, configure first looks for BLAS and
+          LAPACK matrix libraries on your system, including optimized
+          BLAS implementations such as the free ATLAS 3.0, as well as
+          vendor-tuned libraries.  (The use of an optimized BLAS will
+          generally result in several-times faster matrix operations.)
+          Only use this option if your system has BLAS/LAPACK libraries
+          that cause problems for some reason.  You can also use
+          `--with-blas=lib' to specify a particular BLAS library  that
+          configure doesn't check for automatically.
+
+    `--without-framework-carbon'
+          Don't use framework Carbon headers, libraries and specific
+          source code for compilation even if the configure test
+          succeeds (the default value is `--with-framework-carbon').
+          This is a platform specific configure option for Mac systems.
+
+    `--without-framework-opengl'
+          Don't use framework OpenGL headers, libraries and specific
+          source code for compilation even if the configure test
+          succeeds.  If this option is given then OpenGL headers and
+          libraries in standard system locations are tested (the
+          default value is `--with-framework-opengl').  This is a
+          platform specific configure option for Mac systems.
+
+    `--help'
+          Print a summary of the options recognized by the configure
+          script.
+
+     See the file `INSTALL' for more general information about the
+     command line options used by configure.  That file also contains
+     instructions for compiling in a directory other than where the
+     source is located.
+
+   * Run make.
+
+     You will need a recent version of GNU Make.  Modifying Octave's
+     makefiles to work with other make programs is probably not worth
+     your time.  We recommend you get and compile GNU Make instead.
+
+     For plotting, you will need to have gnuplot installed on your
+     system.  Gnuplot is a command-driven interactive function plotting
+     program.  Gnuplot is copyrighted, but freely distributable.  The
+     `gnu' in gnuplot is a coincidence--it is not related to the GNU
+     project or the FSF in any but the most peripheral sense.
+
+     To compile Octave, you will need a recent version of GNU Make.
+     You will also need a recent version of `g++' or other ANSI C++
+     compiler.  You will also need a Fortran 77 compiler or `f2c'.  If
+     you use `f2c', you will need a script like `fort77' that works
+     like a normal Fortran compiler by combining `f2c' with your C
+     compiler in a single script.
+
+     If you plan to modify the parser you will also need GNU `bison' and
+     `flex'.  If you modify the documentation, you will need GNU
+     Texinfo, along with the patch for the `makeinfo' program that is
+     distributed with Octave.
+
+     GNU Make, `gcc', and `libstdc++', `gnuplot', `bison', `flex', and
+     Texinfo are all available from many anonymous ftp archives.  The
+     primary site is `ftp.gnu.org', but it is often very busy.  A list
+     of sites that mirror the software on `ftp.gnu.org' is available by
+     anonymous ftp from `ftp://ftp.gnu.org/pub/gnu/GNUinfo/FTP'.
+
+     You will need about 1 gigabyte of disk storage to work with when
+     building Octave from source (considerably less if you don't
+     compile with debugging symbols).  To do that, use the command
+
+          make CFLAGS=-O CXXFLAGS=-O LDFLAGS=
+
+     instead of just `make'.
+
+   * If you encounter errors while compiling Octave, first check the
+     list of known problems below to see if there is a workaround or
+     solution for your problem.  If not, see the file BUGS for
+     information about how to report bugs.
+
+   * Once you have successfully compiled Octave, run `make install'.
+
+     This will install a copy of Octave, its libraries, and its
+     documentation in the destination directory.  As distributed,
+     Octave is installed in the following directories.  In the table
+     below, PREFIX defaults to `/usr/local', VERSION stands for the
+     current version number of the interpreter, and ARCH is the type of
+     computer on which Octave is installed (for example,
+     `i586-unknown-gnu').
+
+    `PREFIX/bin'
+          Octave and other binaries that people will want to run
+          directly.
+
+    `PREFIX/lib'
+          Libraries like libcruft.a and liboctave.a.
+
+    `PREFIX/share'
+          Architecture-independent data files.
+
+    `PREFIX/include/octave'
+          Include files distributed with Octave.
+
+    `PREFIX/man/man1'
+          Unix-style man pages describing Octave.
+
+    `PREFIX/info'
+          Info files describing Octave.
+
+    `PREFIX/share/octave/VERSION/m'
+          Function files distributed with Octave.  This includes the
+          Octave version, so that multiple versions of Octave may be
+          installed at the same time.
+
+    `PREFIX/lib/octave/VERSION/exec/ARCH'
+          Executables to be run by Octave rather than the user.
+
+    `PREFIX/lib/octave/VERSION/oct/ARCH'
+          Object files that will be dynamically loaded.
+
+    `PREFIX/share/octave/VERSION/imagelib'
+          Image files that are distributed with Octave.
+
+1.1 Installation Problems
+=========================
+
+This section contains a list of problems (and some apparent problems
+that don't really mean anything is wrong) that may show up during
+installation of Octave.
+
+   * On some SCO systems, `info' fails to compile if `HAVE_TERMIOS_H'
+     is defined in `config.h'.  Simply removing the definition from
+     `info/config.h' should allow it to compile.
+
+   * If `configure' finds `dlopen', `dlsym', `dlclose', and `dlerror',
+     but not the header file `dlfcn.h', you need to find the source for
+     the header file and install it in the directory `usr/include'.
+     This is reportedly a problem with Slackware 3.1.  For Linux/GNU
+     systems, the source for `dlfcn.h' is in the `ldso' package.
+
+   * Building `.oct' files doesn't work.
+
+     You should probably have a shared version of `libstdc++'.  A patch
+     is needed to build shared versions of version 2.7.2 of `libstdc++'
+     on the HP-PA architecture.  You can find the patch at
+     `ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix'.
+
+   * On some alpha systems there may be a problem with the `libdxml'
+     library, resulting in floating point errors and/or segmentation
+     faults in the linear algebra routines called by Octave.  If you
+     encounter such problems, then you should modify the configure
+     script so that `SPECIAL_MATH_LIB' is not set to `-ldxml'.
+
+   * On FreeBSD systems Octave may hang while initializing some internal
+     constants.  The fix appears to be to use
+
+          options      GPL_MATH_EMULATE
+
+     rather than
+
+          options      MATH_EMULATE
+
+     in the kernel configuration files (typically found in the directory
+     `/sys/i386/conf'.  After making this change, you'll need to rebuild
+     the kernel, install it, and reboot.
+
+   * If you encounter errors like
+
+          passing `void (*)()' as argument 2 of
+            `octave_set_signal_handler(int, void (*)(int))'
+
+     or
+
+          warning: ANSI C++ prohibits conversion from `(int)'
+                   to `(...)'
+
+     while compiling `sighandlers.cc', you may need to edit some files
+     in the `gcc' include subdirectory to add proper prototypes for
+     functions there.  For example, Ultrix 4.2 needs proper
+     declarations for the `signal' function and the `SIG_IGN' macro in
+     the file `signal.h'.
+
+     On some systems the `SIG_IGN' macro is defined to be something like
+     this:
+
+          #define  SIG_IGN  (void (*)())1
+
+     when it should really be something like:
+
+          #define  SIG_IGN  (void (*)(int))1
+
+     to match the prototype declaration for the `signal' function.  This
+     change should also be made for the `SIG_DFL' and `SIG_ERR'
+     symbols.  It may be necessary to change the definitions in
+     `sys/signal.h' as well.
+
+     The `gcc' `fixincludes' and `fixproto' scripts should probably fix
+     these problems when `gcc' installs its modified set of header
+     files, but I don't think that's been done yet.
+
+     *You should not change the files in `/usr/include'*.  You can find
+     the `gcc' include directory tree by running the command
+
+          gcc -print-libgcc-file-name
+
+     The directory of `gcc' include files normally begins in the same
+     directory that contains the file `libgcc.a'.
+
+   * Some of the Fortran subroutines may fail to compile with older
+     versions of the Sun Fortran compiler.  If you get errors like
+
+          zgemm.f:
+          	zgemm:
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 245: warning: unexpected parent of complex
+            expression subtree
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 304: warning: unexpected parent of complex
+            expression subtree
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 327: warning: unexpected parent of complex
+            expression subtree
+          pcc_binval: missing IR_CONV in complex op
+          make[2]: *** [zgemm.o] Error 1
+
+     when compiling the Fortran subroutines in the `libcruft'
+     subdirectory, you should either upgrade your compiler or try
+     compiling with optimization turned off.
+
+   * On NeXT systems, if you get errors like this:
+
+          /usr/tmp/cc007458.s:unknown:Undefined local
+                symbol LBB7656
+          /usr/tmp/cc007458.s:unknown:Undefined local
+                symbol LBE7656
+
+     when compiling `Array.cc' and `Matrix.cc', try recompiling these
+     files without `-g'.
+
+   * Some people have reported that calls to shell_cmd and the pager do
+     not work on SunOS systems.  This is apparently due to having
+     `G_HAVE_SYS_WAIT' defined to be 0 instead of 1 when compiling
+     `libg++'.
+
+   * On NeXT systems, linking to `libsys_s.a' may fail to resolve the
+     following functions
+
+          _tcgetattr
+          _tcsetattr
+          _tcflow
+
+     which are part of `libposix.a'.  Unfortunately, linking Octave with
+     `-posix' results in the following undefined symbols.
+
+          .destructors_used
+          .constructors_used
+          _objc_msgSend
+          _NXGetDefaultValue
+          _NXRegisterDefaults
+          .objc_class_name_NXStringTable
+          .objc_class_name_NXBundle
+
+     One kluge around this problem is to extract `termios.o' from
+     `libposix.a', put it in Octave's `src' directory, and add it to
+     the list of files to link together in the makefile.  Suggestions
+     for better ways to solve this problem are welcome!
+
+   * If Octave crashes immediately with a floating point exception, it
+     is likely that it is failing to initialize the IEEE floating point
+     values for infinity and NaN.
+
+     If your system actually does support IEEE arithmetic, you should
+     be able to fix this problem by modifying the function
+     `octave_ieee_init' in the file `lo-ieee.cc' to correctly
+     initialize Octave's internal infinity and NaN variables.
+
+     If your system does not support IEEE arithmetic but Octave's
+     configure script incorrectly determined that it does, you can work
+     around the problem by editing the file `config.h' to not define
+     `HAVE_ISINF', `HAVE_FINITE', and `HAVE_ISNAN'.
+
+     In any case, please report this as a bug since it might be
+     possible to modify Octave's configuration script to automatically
+     determine the proper thing to do.
+
+   * If Octave is unable to find a header file because it is installed
+     in a location that is not normally searched by the compiler, you
+     can add the directory to the include search path by specifying
+     (for example) `CPPFLAGS=-I/some/nonstandard/directory' as an
+     argument to `configure'.  Other variables that can be specified
+     this way are `CFLAGS', `CXXFLAGS', `FFLAGS', and `LDFLAGS'.
+     Passing them as options to the configure script also records them
+     in the `config.status' file.  By default, `CPPFLAGS' and `LDFLAGS'
+     are empty, `CFLAGS' and `CXXFLAGS' are set to `"-g -O"' and
+     `FFLAGS' is set to `"-O"'.
+
+
diff --git a/Makeconf.in b/Makeconf.in
new file mode 100644
index 0000000..0df8b96
--- /dev/null
+++ b/Makeconf.in
@@ -0,0 +1,693 @@
+# @configure_input@
+#
+# Common configuration rules for all of octave's Makefiles.
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+#               2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+ 
+SHELL = /bin/sh
+
+AWK = @AWK@
+export AWK
+
+SED = @SED@
+export SED
+
+FIND = @FIND@
+export FIND
+
+PERL = @PERL@
+export PERL
+
+PYTHON = @PYTHON@
+
+GNUPLOT = @GNUPLOT@
+
+DESKTOP_FILE_INSTALL = @DESKTOP_FILE_INSTALL@
+
+# A shell command to extract the version number from version.h.
+getversion = $(SED) -e '/OCTAVE_VERSION/!d' -e 's/.*"\(.*\)".*$$/\1/' -e q
+
+# A shell command to extract the API version number from version.h.
+getapiversion = $(SED) -e '/OCTAVE_API_VERSION/!d' -e 's/.*"\(.*\)".*$$/\1/' -e q
+
+# Look for version.h to get version information.
+xfiles := $(TOPDIR)/src/version.h $(srcdir)/$(TOPDIR)/src/version.h
+version_file := $(firstword $(foreach file, $(xfiles), $(wildcard $(file))))
+version := $(shell $(getversion) $(version_file))
+api_version := $(shell $(getapiversion) $(version_file))
+
+#### Start of system configuration section. ####
+
+EXEEXT = @EXEEXT@
+
+BUILD_EXEEXT = @BUILD_EXEEXT@
+
+LEX = @LEX@
+LFLAGS = @LFLAGS@
+LEXLIB = @LEXLIB@
+
+YACC = @YACC@
+YFLAGS = -dv
+
+GPERF = @GPERF@
+
+AR = @AR@
+ARFLAGS = @ARFLAGS@ 
+
+TEMPLATE_AR = @TEMPLATE_AR@
+TEMPLATE_ARFLAGS = @TEMPLATE_ARFLAGS@
+
+RANLIB = @RANLIB@
+
+LN_S = @LN_S@
+
+MAKEINFO = @MAKEINFO@
+TEXI2DVI = @TEXI2DVI@
+TEXI2PDF = @TEXI2PDF@
+
+GHOSTSCRIPT = @GHOSTSCRIPT@
+
+DEFAULT_PAGER = @DEFAULT_PAGER@
+
+ENABLE_DYNAMIC_LINKING = @ENABLE_DYNAMIC_LINKING@
+
+STATIC_LIBS = @STATIC_LIBS@
+
+SHARED_LIBS = @SHARED_LIBS@
+SHLEXT = @SHLEXT@
+SHLEXT_VER = @SHLEXT_VER@
+SHLLIB = @SHLLIB@
+SHLLIB_VER = @SHLLIB_VER@
+SHLBIN = @SHLBIN@
+SHLBIN_VER = @SHLBIN_VER@
+SHLLINKEXT=
+
+LIBEXT = a
+LIBPRE = @LIBPRE@
+SHLPRE = @SHLPRE@
+SHLLIBPRE = @SHLLIBPRE@
+SHLBINPRE = @SHLBINPRE@
+
+# Fortran compiler flags.
+
+FC = @FC@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FPICFLAG = @FPICFLAG@
+ALL_FFLAGS = $(FFLAGS)
+F77_FLOAT_STORE_FLAG = @F77_FLOAT_STORE_FLAG@
+
+F77_TOLOWER=@F77_TOLOWER@
+F77_APPEND_UNDERSCORE=@F77_TOLOWER@
+F77_APPEND_EXTRA_UNDERSCORE=@F77_TOLOWER@
+
+# cc and associated flags.
+
+# Clean up INCFLAGS a bit if we are not compiling in a separate
+# directory.
+ifeq ($(srcdir),.)
+  TMP_IF_1 = -I.
+else
+  TMP_IF_1 = -I. -I$(srcdir)
+endif
+ifeq ($(TOPDIR),$(top_srcdir))
+  TMP_IF_2 = \
+    -I$(TOPDIR) \
+    -I$(TOPDIR)/liboctave \
+    -I$(TOPDIR)/src \
+    -I$(TOPDIR)/libcruft/misc
+else
+  TMP_IF_2 = \
+    -I$(TOPDIR) \
+    -I$(TOPDIR)/liboctave \
+    -I$(TOPDIR)/src \
+    -I$(TOPDIR)/libcruft/misc \
+    -I$(top_srcdir) \
+    -I$(top_srcdir)/liboctave \
+    -I$(top_srcdir)/src \
+    -I$(top_srcdir)/libcruft/misc
+endif
+INCFLAGS = $(TMP_IF_1) $(TMP_IF_2)
+
+X11_INCFLAGS = @X11_INCFLAGS@
+X11_LIBS = @X11_LIBS@
+
+CARBON_LIBS = @CARBON_LIBS@
+
+MAGICK_CONFIG = @MAGICK_CONFIG@
+MAGICK_INCFLAGS = $(shell $(MAGICK_CONFIG) --cppflags)
+MAGICK_LIBS = $(shell $(MAGICK_CONFIG) --libs)
+
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+
+LIBFLAGS = -L$(TOPDIR)
+
+DEFS = @DEFS@
+
+UGLY_DEFS = @UGLY_DEFS@
+
+CC = @CC@
+CC_VERSION = @CC_VERSION@
+CFLAGS = @CFLAGS@
+CPICFLAG = @CPICFLAG@
+XTRA_CFLAGS = @XTRA_CFLAGS@
+WARN_CFLAGS = @WARN_CFLAGS@
+ALL_CFLAGS = $(INCFLAGS) $(DLL_CDEFS) $(DEFS) $(XTRA_CFLAGS) $(WARN_CFLAGS) $(CFLAGS) $(PTHREAD_CFLAGS)
+BUG_CFLAGS = $(DEFS) $(XTRA_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
+
+BUILD_CC = @BUILD_CC@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+
+DEPEND_FLAGS = @DEPEND_FLAGS@
+DEPEND_EXTRA_SED_PATTERN = @DEPEND_EXTRA_SED_PATTERN@
+INCLUDE_DEPS = @INCLUDE_DEPS@
+ifeq ($(INCLUDE_DEPS),false)
+  omit_deps = true;
+endif
+
+GRAPHICS_CFLAGS = @GRAPHICS_CFLAGS@
+
+CXX = @CXX@
+CXX_VERSION = @CXX_VERSION@
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+CXXPICFLAG = @CXXPICFLAG@
+XTRA_CXXFLAGS = @XTRA_CXXFLAGS@
+WARN_CXXFLAGS = @WARN_CXXFLAGS@
+ALL_CXXFLAGS = \
+  $(INCFLAGS) $(DLL_CXXDEFS) $(DEFS) $(XTRA_CXXFLAGS) $(WARN_CXXFLAGS) $(CXXFLAGS) $(PTHREAD_CFLAGS)
+BUG_CXXFLAGS = $(DEFS) $(XTRA_CXXFLAGS) $(WARN_CXXFLAGS) $(CXXFLAGS)
+
+BUILD_CXX = @BUILD_CXX@
+BUILD_CXXFLAGS = @BUILD_CXXFLAGS@
+
+CPPFLAGS = @CPPFLAGS@
+
+LD_CXX = @LD_CXX@
+LDFLAGS = @LDFLAGS@
+LD_STATIC_FLAG = @LD_STATIC_FLAG@
+ALL_LDFLAGS = $(LIBFLAGS) $(LD_STATIC_FLAG) $(CPICFLAG) $(LDFLAGS)
+
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+
+SH_LD = @SH_LD@
+SH_LDFLAGS = @SH_LDFLAGS@
+
+DL_LD = @DL_LD@
+DL_LDFLAGS = @DL_LDFLAGS@
+
+SONAME_FLAGS = @SONAME_FLAGS@
+
+RDYNAMIC_FLAG = @RDYNAMIC_FLAG@
+
+RLD_FLAG = @RLD_FLAG@
+
+FLIBS = @FLIBS@
+
+LIBGLOB = @LIBGLOB@
+LIBOCTINTERP = @LIBOCTINTERP@
+LIBOCTAVE = @LIBOCTAVE@
+LIBCRUFT = @LIBCRUFT@
+LIBREADLINE = @LIBREADLINE@
+TERMLIBS = @TERMLIBS@
+
+FT2_LIBS = @FT2_LIBS@
+GRAPHICS_LIBS = @GRAPHICS_LIBS@
+QHULL_LIBS = @QHULL_LIBS@
+REGEX_LIBS = @REGEX_LIBS@
+BLAS_LIBS = @BLAS_LIBS@
+FFTW_LIBS = @FFTW_LIBS@
+GLPK_LIBS = @GLPK_LIBS@
+CURL_LIBS = @CURL_LIBS@
+AMD_LIBS = @AMD_LIBS@
+CAMD_LIBS = @CAMD_LIBS@
+UMFPACK_LIBS = @UMFPACK_LIBS@
+COLAMD_LIBS = @COLAMD_LIBS@
+CCOLAMD_LIBS = @CCOLAMD_LIBS@
+CHOLMOD_LIBS = @CHOLMOD_LIBS@
+CXSPARSE_LIBS = @CXSPARSE_LIBS@
+OPENGL_LIBS = @OPENGL_LIBS@
+QRUPDATE_LIBS = @QRUPDATE_LIBS@
+ARPACK_LIBS = @ARPACK_LIBS@
+LIBS = @LIBS@
+
+USE_64_BIT_IDX_T = @USE_64_BIT_IDX_T@
+
+TEXINFO_COLAMD = @TEXINFO_COLAMD@
+TEXINFO_CHOLMOD = @TEXINFO_CHOLMOD@
+TEXINFO_UMFPACK = @TEXINFO_UMFPACK@
+TEXINFO_QHULL = @TEXINFO_QHULL@
+
+# The arguments passed to configure.
+config_opts = @config_opts@
+
+CONFIG_SUBDIRS = @subdirs@
+
+# ==================== Where To Install Things ====================
+
+# The default location for installation.  Everything is placed in
+# subdirectories of this directory.  The default values for many of
+# the variables below are expressed in terms of this one, so you may
+# not need to change them.  This defaults to /usr/local.
+prefix = @prefix@
+
+# Like `prefix', but used for architecture-specific files.
+exec_prefix = @exec_prefix@
+
+# Where to install Octave and other binaries that people will want to
+# run directly.
+bindir = @bindir@
+
+# Normally the directory for installing executables that system
+# administrators run.  This is the same as libexecdir on Cygwin systems.
+sbindir = @sbindir@
+
+# The root of the directory tree for read-only
+# architecture-independent data files.
+datarootdir = @datarootdir@
+
+# Where to install architecture-independent data files.  ${fcnfiledir}
+# and ${localfcnfiledir} are subdirectories of this.
+datadir = @datadir@
+
+libdir = @libdir@
+
+# Where to install and expect extra files like NEWS and doc-cache.
+octetcdir = @octetcdir@
+
+# Where to install and expect libraries like libcruft.a, liboctave.a,
+# and other architecture-dependent data.
+octlibdir = @octlibdir@
+
+# Where to install and expect executable programs to be run by Octave
+# rather than directly by users.
+libexecdir = @libexecdir@
+
+# The prefix for Octave's include file directory.  The default is
+# ${prefix}/include
+includedir = @includedir@
+
+# Where to install Octave's man pages, and what extension they should
+# have.  The default is ${prefix}/man/man1
+mandir = @mandir@
+man1dir = @man1dir@
+man1ext = @man1ext@
+
+# The full path to the default doc cache file.
+doc_cache_file = @doc_cache_file@
+
+# Where to install and expect the info files describing Octave..
+infodir = @infodir@
+
+# The full path to the default info file.
+infofile = @infofile@
+
+# ==================== Octave-specific directories ====================
+
+# These variables hold the values specific to Octave.  They are
+# based on the values of the standard Make variables above.
+
+# What is the path separation character
+sepchar = @sepchar@
+
+# Where to install Octave's include files (they will actually be
+# installed in a subdirectory called octave).  The default is
+# ${includedir}/octave-${version}
+octincludedir = @octincludedir@
+
+# Where to install the function file distributed with
+# Octave.  This includes the Octave version, so that the
+# function files for different versions of Octave will install
+# themselves in separate directories.
+fcnfiledir = @fcnfiledir@
+
+# Directories Octave should search for function files specific
+# to this site (i.e. customizations), before consulting
+# ${fcnfiledir}.  This should be a colon-separated list of
+# directories.
+localfcnfiledir = @localfcnfiledir@
+localapifcnfiledir = @localapifcnfiledir@
+localverfcnfiledir = @localverfcnfiledir@
+
+# Where to put executables to be run by Octave rather than
+# the user.  This path usually includes the Octave version
+# and configuration name, so that multiple configurations
+# for multiple versions of Octave may be installed at once.
+archlibdir = @archlibdir@
+
+# Where to put executables to be run by Octave rather than by the
+# user that are specific to this site.
+localarchlibdir = @localarchlibdir@
+localapiarchlibdir = @localapiarchlibdir@
+localverarchlibdir = @localverarchlibdir@
+
+# Where to put object files that will by dynamically loaded.
+# This path usually includes the Octave version and configuration
+# name, so that multiple configurations for multiple versions of
+# Octave may be installed at once. 
+octfiledir = @octfiledir@
+
+# Directories Octave should search for object files that will be
+# dynamically loaded and that are specific to this site
+# (i.e. customizations), before consulting ${octfiledir}.  This should
+# be a colon-separated list of directories.
+localoctfiledir = @localoctfiledir@
+localapioctfiledir = @localapioctfiledir@
+localveroctfiledir = @localveroctfiledir@
+
+# Where Octave will search to find image files.
+imagedir = @imagedir@
+
+# The type of computer we are running on.
+canonical_host_type = @canonical_host_type@
+
+# Where Octave will look for startup files
+startupfiledir = ${fcnfiledir}/startup
+localstartupfiledir = ${localfcnfiledir}/startup
+
+# LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, PATH, ...
+library_path_var = @library_path_var@
+
+NO_OCT_FILE_STRIP = @NO_OCT_FILE_STRIP@
+
+# The following pattern rules and the substitution functions require
+# GNU make.  If you don't have it, get it!
+
+# How to make .o files:
+
+%.o : %.f
+	$(FC) -c $(ALL_FFLAGS) -o $@ $<
+
+%.o : %.c
+	$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $< -o $@
+
+%.o : %.cc
+	$(CXX) -c $(CPPFLAGS) $(ALL_CXXFLAGS) $< -o $@
+
+pic/%.o : %.f
+	$(FC) -c $(FPICFLAG) $(ALL_FFLAGS) $< -o $@
+
+pic/%.o : %.c
+	$(CC) -c $(CPPFLAGS) $(CPICFLAG) $(ALL_CFLAGS) $< -o $@
+
+pic/%.o : %.cc
+	$(CXX) -c $(CPPFLAGS) $(CXXPICFLAG) $(ALL_CXXFLAGS) $< -o $@
+
+# Here is a rule for generating dependencies for .cc files:
+
+%.d : %.cc
+	@echo making $@ from $<
+	@rm -f $@
+	@$(CXX) $(DEPEND_FLAGS) $(CPPFLAGS) $(ALL_CXXFLAGS) $< | \
+	  $(SED) \
+              $(DEPEND_EXTRA_SED_PATTERN) \
+	      -e 's,^[^:]*/\(.*\.o\):,\1:,' \
+	      -e 's,$*\.o,pic/& & $*.df $@,g' > $@-t
+	@mv $@-t $@
+
+# And one for .c files.too:
+
+%.d : %.c
+	@echo making $@ from $<
+	@rm -f $@
+	@$(CC) $(DEPEND_FLAGS) $(CPPFLAGS) $(ALL_CFLAGS) $< | \
+	  $(SED) \
+              $(DEPEND_EXTRA_SED_PATTERN) \
+	      -e 's,^[^:]*/\(.*\.o\):,\1:,' \
+	      -e 's,$*\.o,pic/& & $@,g' > $@-t
+	@mv $@-t $@
+
+define do-subdir-for-command
+echo making $@ in $d; $(MAKE) -C $d $@;
+endef
+
+define subdir-for-command
+$(foreach d, $(SUBDIRS), $(do-subdir-for-command))
+endef
+
+define simple-move-if-change-rule
+if [ -s $@-t ]; then \
+  $(top_srcdir)/move-if-change $@-t $@; \
+else \
+  echo "$@-t is empty!" 1>&2; \
+  rm -f $@-t; \
+  exit 1; \
+fi
+endef
+
+define builddir-move-if-change-rule
+if [ -s $(@F)-t ]; then \
+  $(top_srcdir)/move-if-change $(@F)-t $(@F); \
+else \
+  echo "$(@F)-t is empty!" 1>&2; \
+  rm -f $(@F)-t; \
+  exit 1; \
+fi
+endef
+
+# Yes, the second sed command near the end is needed, to avoid limits
+# in command lengths for some versions of sed.  UGLY_DEFS is often
+# quite large, so it makes sense to split this command there.
+
+define do-subst-config-vals
+echo "making $@ from $<"
+$(SED) < $< \
+  -e "s|%NO_OCT_FILE_STRIP%|${NO_OCT_FILE_STRIP}|" \
+  -e "s|%OCTAVE_BINDIR%|\"${bindir}\"|" \
+  -e "s|%OCTAVE_CONF_ALL_CFLAGS%|\"${ALL_CFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_ALL_CXXFLAGS%|\"${ALL_CXXFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_ALL_FFLAGS%|\"${ALL_FFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_ALL_LDFLAGS%|\"${ALL_LDFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_AR%|\"${AR}\"|" \
+  -e "s|%OCTAVE_CONF_ARFLAGS%|\"${ARFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_BLAS_LIBS%|\"${BLAS_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_CANONICAL_HOST_TYPE%|\"${canonical_host_type}\"|" \
+  -e "s|%OCTAVE_CONF_CARBON_LIBS%|\"${CARBON_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_CC%|\"${CC}\"|" \
+  -e "s|%OCTAVE_CONF_CC_VERSION%|\"${CC_VERSION}\"|" \
+  -e "s|%OCTAVE_CONF_CFLAGS%|\"${CFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_CPICFLAG%|\"${CPICFLAG}\"|" \
+  -e "s|%OCTAVE_CONF_CPPFLAGS%|\"${CPPFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_CURL_LIBS%|\"${CURL_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_CXX%|\"${CXX}\"|" \
+  -e "s|%OCTAVE_CONF_CXXCPP%|\"${CXXCPP}\"|" \
+  -e "s|%OCTAVE_CONF_CXXFLAGS%|\"${CXXFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_CXXPICFLAG%|\"${CXXPICFLAG}\"|" \
+  -e "s|%OCTAVE_CONF_CXX_VERSION%|\"${CXX_VERSION}\"|" \
+  -e "s|%OCTAVE_CONF_DEFAULT_PAGER%|\"${DEFAULT_PAGER}\"|" \
+  -e "s|%OCTAVE_CONF_DEPEND_FLAGS%|\"${DEPEND_FLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%|\"${DEPEND_EXTRA_SED_PATTERN}\"|" \
+  -e "s|%OCTAVE_CONF_DL_LD%|\"${DL_LD}\"|" \
+  -e "s|%OCTAVE_CONF_DL_LDFLAGS%|\"${DL_LDFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_EXEEXT%|\"${EXEEXT}\"|" \
+  -e "s|%OCTAVE_CONF_F77%|\"${F77}\"|" \
+  -e "s|%OCTAVE_CONF_F77_FLOAT_STORE_FLAG%|\"${F77_FLOAT_STORE_FLAG}\"|" \
+  -e "s|%OCTAVE_CONF_FC%|\"${FC}\"|" \
+  -e "s|%OCTAVE_CONF_FFLAGS%|\"${FFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_FFTW_LIBS%|\"${FFTW_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_FLIBS%|\"${FLIBS}\"|" \
+  -e "s|%OCTAVE_CONF_FPICFLAG%|\"${FPICFLAG}\"|" \
+  -e "s|%OCTAVE_CONF_GLPK_LIBS%|\"${GLPK_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_GNUPLOT%|\"${GNUPLOT}\"|" \
+  -e "s|%OCTAVE_CONF_INCFLAGS%|\"${INCFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_INCLUDEDIR%|\"${includedir}\"|" \
+  -e "s|%OCTAVE_CONF_LD_CXX%|\"${LD_CXX}\"|" \
+  -e "s|%OCTAVE_CONF_LDFLAGS%|\"${LDFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_LD_STATIC_FLAG%|\"${LD_STATIC_FLAG}\"|" \
+  -e "s|%OCTAVE_CONF_LEX%|\"${LEX}\"|" \
+  -e "s|%OCTAVE_CONF_LEXLIB%|\"${LEXLIB}\"|" \
+  -e "s|%OCTAVE_CONF_LFLAGS%|\"${LFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_LIBCRUFT%|\"${LIBCRUFT}\"|" \
+  -e "s|%OCTAVE_CONF_LIBDIR%|\"${libdir}\"|" \
+  -e "s|%OCTAVE_CONF_LIBEXT%|\"${LIBEXT}\"|" \
+  -e "s|%OCTAVE_CONF_LIBFLAGS%|\"${LIBFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_LIBGLOB%|\"${LIBGLOB}\"|" \
+  -e "s|%OCTAVE_CONF_LIBOCTAVE%|\"${LIBOCTAVE}\"|" \
+  -e "s|%OCTAVE_CONF_LIBOCTINTERP%|\"${LIBOCTINTERP}\"|" \
+  -e "s|%OCTAVE_CONF_LIBREADLINE%|\"${LIBREADLINE}\"|" \
+  -e "s|%OCTAVE_CONF_LIBS%|\"${LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_LN_S%|\"${LN_S}\"|" \
+  -e "s|%OCTAVE_CONF_MAGICK_INCFLAGS%|\"${MAGICK_INCFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_MAGICK_LIBS%|\"${MAGICK_LIBS}\"|" \
+  -e 's|%OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%|\"@MKOCTFILE_DL_LDFLAGS@\"|' \
+  -e "s|%OCTAVE_CONF_OCTINCLUDEDIR%|\"${octincludedir}\"|" \
+  -e "s|%OCTAVE_CONF_OCTLIBDIR%|\"${octlibdir}\"|" \
+  -e "s|%OCTAVE_CONF_PREFIX%|\"${prefix}\"|" \
+  -e "s|%OCTAVE_CONF_RANLIB%|\"${RANLIB}\"|" \
+  -e "s|%OCTAVE_CONF_RDYNAMIC_FLAG%|\"${RDYNAMIC_FLAG}\"|" \
+  -e "s|%OCTAVE_CONF_RLD_FLAG%|\"${RLD_FLAG}\"|" \
+  -e "s|%OCTAVE_CONF_SED%|\"${SED}\"|" \
+  -e "s|%OCTAVE_CONF_SHARED_LIBS%|\"${SHARED_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_SHLEXT%|\"${SHLEXT}\"|" \
+  -e "s|%OCTAVE_CONF_SHLLINKEXT%|\"${SHLLINKEXT}\"|" \
+  -e "s|%OCTAVE_CONF_SHLEXT_VER%|\"${SHLEXT_VER}\"|" \
+  -e "s|%OCTAVE_CONF_SH_LD%|\"${SH_LD}\"|" \
+  -e "s|%OCTAVE_CONF_SH_LDFLAGS%|\"${SH_LDFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_SONAME_FLAGS%|\"${SONAME_FLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_STATIC_LIBS%|\"${STATIC_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_UGLY_DEFS%|\"${UGLY_DEFS}\"|" \
+  -e "s|%OCTAVE_CONF_USE_64_BIT_IDX_T%|\"${USE_64_BIT_IDX_T}\"|" \
+  -e "s|%OCTAVE_CONF_VERSION%|\"${version}\"|" \
+  -e "s|%OCTAVE_CONF_ENABLE_DYNAMIC_LINKING%|\"${ENABLE_DYNAMIC_LINKING}\"|" \
+  -e "s|%OCTAVE_CONF_X11_INCFLAGS%|\"${X11_INCFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_X11_LIBS%|\"${X11_LIBS}\"|" \
+  -e "s|%OCTAVE_CONF_XTRA_CFLAGS%|\"${XTRA_CFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_XTRA_CXXFLAGS%|\"${XTRA_CXXFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_YACC%|\"${YACC}\"|" \
+  -e "s|%OCTAVE_CONF_YFLAGS%|\"${YFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_config_opts%|\"${config_opts}\"|" | \
+  $(SED)  -e "s|%OCTAVE_CONF_DEFS%|\"${UGLY_DEFS}\"|" > $@-t
+$(simple-move-if-change-rule)
+endef
+
+define do-subst-default-vals
+echo "making $@ from $<"
+$(SED) < $< > $@-t \
+  -e "s|%OCTAVE_ARCHLIBDIR%|\"${archlibdir}\"|" \
+  -e "s|%OCTAVE_BINDIR%|\"${bindir}\"|" \
+  -e "s|%OCTAVE_CANONICAL_HOST_TYPE%|\"${canonical_host_type}\"|" \
+  -e "s|%OCTAVE_DATADIR%|\"${datadir}\"|" \
+  -e "s|%OCTAVE_DATAROOTDIR%|\"${datarootdir}\"|" \
+  -e "s|%OCTAVE_DEFAULT_PAGER%|\"${DEFAULT_PAGER}\"|" \
+  -e "s|%OCTAVE_DOC_CACHE_FILE%|\"${doc_cache_file}\"|" \
+  -e "s|%OCTAVE_EXEC_PREFIX%|\"${exec_prefix}\"|" \
+  -e "s|%OCTAVE_FCNFILEDIR%|\"${fcnfiledir}\"|" \
+  -e "s|%OCTAVE_IMAGEDIR%|\"${imagedir}\"|" \
+  -e "s|%OCTAVE_INCLUDEDIR%|\"${includedir}\"|" \
+  -e "s|%OCTAVE_INFODIR%|\"${infodir}\"|" \
+  -e "s|%OCTAVE_INFOFILE%|\"${infofile}\"|" \
+  -e "s|%OCTAVE_LIBDIR%|\"${libdir}\"|" \
+  -e "s|%OCTAVE_LIBEXECDIR%|\"${libexecdir}\"|" \
+  -e "s|%OCTAVE_LOCALAPIFCNFILEDIR%|\"${localapifcnfiledir}\"|" \
+  -e "s|%OCTAVE_LOCALAPIOCTFILEDIR%|\"${localapioctfiledir}\"|" \
+  -e "s|%OCTAVE_LOCALARCHLIBDIR%|\"${localarchlibdir}\"|" \
+  -e "s|%OCTAVE_LOCALFCNFILEDIR%|\"${localfcnfiledir}\"|" \
+  -e "s|%OCTAVE_LOCALOCTFILEDIR%|\"${localoctfiledir}\"|" \
+  -e "s|%OCTAVE_LOCALSTARTUPFILEDIR%|\"${localstartupfiledir}\"|" \
+  -e "s|%OCTAVE_LOCALAPIARCHLIBDIR%|\"${localapiarchlibdir}\"|" \
+  -e "s|%OCTAVE_LOCALVERARCHLIBDIR%|\"${localverarchlibdir}\"|" \
+  -e "s|%OCTAVE_LOCALVERFCNFILEDIR%|\"${localverfcnfiledir}\"|" \
+  -e "s|%OCTAVE_LOCALVEROCTFILEDIR%|\"${localveroctfiledir}\"|" \
+  -e "s|%OCTAVE_MAN1DIR%|\"${man1dir}\"|" \
+  -e "s|%OCTAVE_MAN1EXT%|\"${man1ext}\"|" \
+  -e "s|%OCTAVE_MANDIR%|\"${mandir}\"|" \
+  -e "s|%OCTAVE_OCTFILEDIR%|\"${octfiledir}\"|" \
+  -e "s|%OCTAVE_OCTETCDIR%|\"${octetcdir}\"|" \
+  -e "s|%OCTAVE_OCTINCLUDEDIR%|\"${octincludedir}\"|" \
+  -e "s|%OCTAVE_OCTLIBDIR%|\"${octlibdir}\"|" \
+  -e "s|%OCTAVE_STARTUPFILEDIR%|\"${startupfiledir}\"|" \
+  -e "s|%OCTAVE_PREFIX%|\"${prefix}\"|" \
+  -e "s|%OCTAVE_API_VERSION%|\"${api_version}\"|" \
+  -e "s|%OCTAVE_RELEASE%|\"${OCTAVE_RELEASE}\"|" \
+  -e "s|%OCTAVE_VERSION%|\"${version}\"|"
+$(simple-move-if-change-rule)
+endef
+
+define do-subst-texinfo-vals
+echo "making $@ from $<"
+$(SED) < $< \
+  -e "s|%abs_top_srcdir%|${abs_top_srcdir}|" \
+  -e "s|%top_srcdir%|${top_srcdir}|" \
+  -e "s|%OCTAVE_HOME%|${prefix}|" \
+  -e "s|%OCTAVE_VERSION%|${version}|" \
+  -e "s|%TEXINFO_COLAMD%|${TEXINFO_COLAMD}|" \
+  -e "s|%TEXINFO_CHOLMOD%|${TEXINFO_CHOLMOD}|" \
+  -e "s|%TEXINFO_UMFPACK%|${TEXINFO_UMFPACK}|" \
+  -e "s|%TEXINFO_QHULL%|${TEXINFO_QHULL}|" | \
+  $(SED) -e "s|%OCTAVE_CONF_DEFS%|\"${UGLY_DEFS}\"|" > $@-t
+$(simple-move-if-change-rule)
+endef
+
+define do-subst-script-vals
+echo "making $@ from $<"
+$(SED) < $< \
+  -e "s|%AWK%|${AWK}|g" \
+  -e "s|%FIND%|${FIND}|g" \
+  -e "s|%SED%|${SED}|g" \
+  -e "s|%library_path_var%|${library_path_var}|g" \
+  -e "s|%liboctinterp%|${SHLPRE}octinterp.${SHLEXT}|g" \
+  -e "s|%liboctave%|${SHLPRE}octave.${SHLEXT}|g" \
+  -e "s|%libcruft%|${SHLPRE}cruft.${SHLEXT}|g" \
+  -e "s|%srcdir%|${srcdir}|" \
+  -e "s|%top_srcdir%|${top_srcdir}|" \
+  -e "s|%abs_top_srcdir%|${abs_top_srcdir}|" \
+  -e "s|%builddir%|$(shell pwd)|" > $@-t
+$(simple-move-if-change-rule)
+endef
+
+define do-subst-f77-mangling
+echo "making $@ from $<"
+$(SED) < $< \
+  -e "s|%F77_TOLOWER%|${F77_TOLOWER}|g" \
+  -e "s|%F77_APPEND_UNDERSCORE%|${F77_APPEND_UNDERSCORE}|" \
+  -e "s|%F77_APPEND_EXTRA_UNDERSCORE%|${F77_APPEND_EXTRA_UNDERSCORE}|" > $@-t
+$(simple-move-if-change-rule)
+endef
+
+define do-mkpkgadd
+$(top_srcdir)/mkpkgadd $(srcdir) > PKG_ADD.t
+if [ -n "`cat PKG_ADD.t`" ]; then \
+  mv PKG_ADD.t PKG_ADD ; \
+else \
+  rm -f PKG_ADD.t ; \
+fi
+endef
+
+define do-script-install
+$(top_srcdir)/mkinstalldirs \
+  $(addprefix $(DESTDIR), $(fcnfiledir)/$(script_sub_dir))
+for f in $(FCN_FILES); do \
+  fbase=`basename $$f`; \
+  rm -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/$$fbase; \
+  $(INSTALL_DATA) $$f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/$$fbase; \
+done
+$(top_srcdir)/mkpkgadd $(DESTDIR)$(fcnfiledir)/$(script_sub_dir) > $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/PKG_ADD.t
+if [ -n "`cat $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/PKG_ADD.t`" ]; then \
+  $(INSTALL_DATA) $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/PKG_ADD.t $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/PKG_ADD ; \
+else \
+  rm -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/PKG_ADD.t ; \
+fi
+endef
+
+define do-script-uninstall
+for f in $(FCN_FILES_NO_DIR); \
+  do rm -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/$$f; \
+done
+rm -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/PKG_ADD
+-rmdir $(addprefix $(DESTDIR), $(fcnfiledir)/$(script_sub_dir))
+endef
+
+define do-check-m-sources
+for f in $(notdir $(wildcard $(srcdir)/*.m)); do \
+  found=false; \
+  for m in $(SOURCES); do \
+    if [ "$$f" = "$$m" ]; then \
+      found=true; \
+      break; \
+    fi; \
+  done; \
+  if $$found; then \
+    true; \
+  else \
+    echo "$(script_sub_dir)/$$f: not listed in SOURCES"; \
+  fi; \
+done
+endef
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b1292eb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,129 @@
+# Makefile for octave's src directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2003, 2004,
+#               2005, 2006, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TARGETS = octave-bug octave-config mkoctfile libcruft liboctave \
+	dlfcn readline src scripts doc check octave.info \
+	INSTALL.OCTAVE BUGS install install-strip uninstall \
+	tags TAGS dist conf-dist snapshot snapshot-version \
+	.gdbinit run-octave
+
+NO_DEP_TARGETS = clean mostlyclean distclean maintainer-clean
+
+all: header-msg config-check
+	$(MAKE) -f octMakefile all
+
+configfiles: FORCE
+	$(MAKE) -f octMakefile configfiles
+
+$(TARGETS): FORCE
+	$(MAKE) -f octMakefile $@
+
+$(NO_DEP_TARGETS): FORCE
+	$(MAKE) -f octMakefile omit_deps=true $@
+
+# Maybe this message will prevent people from asking why the
+# Makefiles don't work for them.  Maybe not.
+
+header-msg: FORCE
+	@echo ""
+	@echo "***********************************************************"
+	@echo "*"
+	@echo "*  To compile Octave, you will need a recent versions of"
+	@echo "*  the following software:"
+	@echo "*"
+	@echo "*    GNU Make (a recent version)"
+	@echo "*"
+	@echo "*    g++ (preferably a recent 4.x version)"
+	@echo "*"
+	@echo "*    flex (2.5.4 or a more recent version) -- required if"
+	@echo "*    you need to recreate lex.cc from lex.l"
+	@echo "*"
+	@echo "*    bison (1.31 or a more recent version) -- required if"
+	@echo "*    you need to recreate parse.cc from parse.y"
+	@echo "*"
+	@echo "*    gperf (3.0.1 or a more recent version) -- required if"
+	@echo "*    you need to recreate oct-gperf.h from octave.gperf"
+	@echo "*"
+	@echo "*  Now would be a good time to read INSTALL.OCTAVE if"
+	@echo "*  you have not done so already."
+	@echo "*"
+	@echo "***********************************************************"
+	@echo ""
+
+help: header-msg
+	@echo ""
+	@echo "For more information, please read the files INSTALL,"
+	@echo "INSTALL.OCTAVE, and any other system-specific README"
+	@echo "files that apply (e.g., README.Linux)."
+	@echo ""
+	@echo "The following targets are available:"
+	@echo ""
+	@echo "  all                  build everything"
+	@echo "  check                run self tests"
+	@echo "  install              install files"
+	@echo "  install-strip        same as install but strip binaries"
+	@echo "  uninstall            delete installed files"
+	@echo ""
+	@echo "  dist                 create a source distribution"
+	@echo "  conf-dist            create a config files distribution"
+	@echo ""
+	@echo "  clean                remove files created by make all"
+	@echo "  mostlyclean          remove most files created by make all"
+	@echo "  distclean            remove all files not in distribution"
+	@echo "  maintainer-clean     clean up everything"
+	@echo ""
+	@echo "  octave-bug           create octave-bug script"
+	@echo "  octave-config        create octave-config script"
+	@echo "  mkoctfile            create mkoctfile script"
+	@echo "  INSTALL.OCTAVE       create INSTALL.OCTAVE doc file"
+	@echo "  BUGS                 create BUGS doc file"
+	@echo "  tags                 create tags files"
+	@echo "  TAGS                 create TAGS files"
+	@echo ""
+	@echo "  dlfcn                make all in subdirectory dlfcn"
+	@echo "  doc                  make all in subdirectory doc"
+	@echo "  libcruft             make all in subdirectory libcruft"
+	@echo "  liboctave            make all in subdirectory liboctave"
+	@echo "  scripts              make all in subdirectory scripts"
+	@echo "  src                  make all in subdirectory src"
+	@echo ""
+	@echo "  configfiles          update the configuration files"
+	@echo ""
+	@echo "  help                 print this message"
+	@echo ""
+
+config-check:
+	@if test -f octMakefile; then \
+	  true; \
+	else \
+	  echo ""; \
+	  echo "*** You must run configure before running make."; \
+	  echo "***"; \
+	  echo "*** Please read the INSTALL and INSTALL.OCTAVE files"; \
+	  echo "*** for more information about how to configure and"; \
+	  echo "*** compile Octave."; \
+	  echo ""; \
+	  exit 1; \
+	fi
+
+FORCE:
+
+.NOTPARALLEL:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..7141bf5
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,396 @@
+Summary of important user-visible changes for version 3.2:
+---------------------------------------------------------
+
+ ** Compatibility with Matlab graphics has been improved.
+
+    The hggroup object and associated listener callback functions have
+    been added allowing the inclusion of group objects.  Data sources
+    have been added to these group objects such that
+
+           x = 0:0.1:10;
+           y = sin (x);
+           plot (x, y, "ydatasource", "y");
+           for i = 1 : 100
+             pause(0.1)
+             y = sin (x + 0.1 * i);
+             refreshdata();
+           endfor
+
+    works as expected.  This capability has be used to introduce
+    stem-series, bar-series, etc., objects for better Matlab
+    compatibility.
+
+ ** New graphics functions:
+
+      addlistener         ezcontour   gcbo         refresh  
+      addproperty         ezcontourf  ginput       refreshdata
+      allchild            ezmesh      gtext        specular
+      available_backends  ezmeshc     intwarning   surfl
+      backend             ezplot      ishghandle   trisurf
+      cla                 ezplot3     isocolors    waitforbuttonpress
+      clabel              ezpolar     isonormals  
+      comet               ezsurf      isosurface  
+      dellistener         findall     linkprop   
+      diffuse             gcbf        plotmatrix
+
+ ** New experimental OpenGL/FLTK based plotting system.
+
+    An experimental plotting system based on OpenGL and the FLTK
+    toolkit is now part of Octave.  This backend is disabled by
+    default.  You can switch to using it with the command
+
+        backend ("fltk")
+
+    for all future figures or for a particular figure with the command
+
+        backend (h, "fltk")
+
+    where "h" is a valid figure handle.  Please note that this backend
+    does not yet support text objects.  Obviously, this is a necessary
+    feature before it can be considered usable.  We are looking for
+    volunteers to help implement this missing feature.
+
+ ** Functions providing direct access to gnuplot have been removed.
+
+    The functions __gnuplot_plot__, __gnuplot_set__, __gnuplot_raw__,
+     __gnuplot_show__, __gnuplot_replot__, __gnuplot_splot__,
+     __gnuplot_save_data__ and __gnuplot_send_inline_data__ have been
+     removed from Octave.  These function were incompatible with the
+     high level graphics handle code.
+
+ ** The Control, Finance and Quaternion functions have been removed.
+
+    These functions are now available as separate packages from
+
+      http://octave.sourceforge.net/packages.html
+
+    and can be reinstalled using the Octave package manager (see
+    the pkg function).
+
+ ** Specific sparse matrix functions removed.
+
+    The following functions, which handled only sparse matrices have
+    been removed.  Instead of calling these functions directly, you
+    should use the corresponding function without the "sp" prefix.
+
+      spatan2     spcumsum  spkron   spprod
+      spchol      spdet     splchol  spqr
+      spchol2inv  spdiag    splu     spsum
+      spcholinv   spfind    spmax    spsumsqk
+      spcumprod   spinv     spmin
+
+ ** Improvements to the debugger.
+
+    The interactive debugging features have been improved.  Stopping
+    on statements with dbstop should work correctly now.  Stepping
+    into and over functions, and stepping one statement at a time
+    (with dbstep) now works.  Moving up and down the call stack with
+    dbup and dbdown now works.  The dbstack function is now available
+    to print the current function call stack.  The new dbquit function
+    is available to exit the debugging mode.
+
+ ** Improved traceback error messages.
+
+    Traceback error messages are much more concise and easier to
+    understand.  They now display information about the function call
+    stack instead of the stack of all statements that were active at
+    the point of the error.
+
+ ** Object Oriented Programming.
+
+    Octave now includes OOP features and the user can create their own
+    class objects and overloaded functions and operators.  For
+    example, all methods of a class called "myclass" will be found in
+    a directory "@myclass" on the users path.  The class specific
+    versions of functions and operators take precedence over the
+    generic versions of these functions.
+
+    New functions related to OOP include
+
+      class  inferiorto  isobject  loadobj  methods  superiorto
+
+    See the Octave manual for more details.
+
+ ** Parsing of Command-style Functions.
+
+    Octave now parses command-style functions without needing to first
+    declare them with "mark_as_command".  The rules for recognizing a
+    command-style function calls are
+
+      * A command must appear as the first word in a statement,
+        followed by a space.
+
+      * The first character after the space must not be '=' or '('
+
+      * The next token after the space must not look like a binary
+        operator.
+
+    These rules should be mostly compatible with the way Matlab parses
+    command-style function calls and allow users to define commands in
+    .m files without having to mark them as commands.
+
+    Note that previous versions of Octave allowed expressions like
+
+      x = load -text foo.dat
+
+    but an expression like this will now generate a parse error.  In
+    order to assign the value returned by a function to a variable,
+    you must use the normal function call syntax:
+
+      x = load ("-text", "foo.dat");
+
+ ** Block comments.
+
+    Commented code can be between matching "#{" and "#}" or "%{" and
+    "%}" markers, even if the commented code spans several line.  This
+    allows blocks code to be commented, without needing to comment
+    each line.  For example,
+
+    function [s, t] = func (x, y)
+      s = 2 * x;
+    #{
+      s *= y;
+      t = y + x;
+    #}
+    endfunction
+
+    the lines "s *= y;" and "t = y + x" will not be executed.
+
+ ** Special treatment in the parser of expressions like "a' * b".
+
+    In these cases the transpose is no longer explicitly formed and
+    BLAS libraries are called with the transpose flagged,
+    significantly improving performance for these kinds of
+    operations.
+
+ ** Single Precision data type.
+
+    Octave now includes a single precision data type.  Single
+    precision variables can be created with the "single" command, or
+    from functions like ones, eye, etc.  For example,
+
+      single (1)
+      ones (2, 2, "single")
+      zeros (2, 2, "single")
+      eye (2, 2, "single")
+      Inf (2, 2, "single")
+      NaN (2, 2, "single")
+      NA (2, 2, "single")
+
+    all create single precision variables.  For compatibility with
+    Matlab, mixed double/single precision operators and functions
+    return single precision types.
+
+    As a consequence of this addition to Octave the internal
+    representation of the double precision NA value has changed, and
+    so users that make use of data generated by Octave with R or
+    visa-versa are warned that compatibility might not be assured.
+
+ ** Improved array indexing.
+
+    The underlying code used for indexing of arrays has been
+    completely rewritten and indexing is now significantly faster.
+
+ ** Improved memory management.
+
+    Octave will now attempt to share data in some cases where previously
+    a copy would be made, such as certain array slicing operations or
+    conversions between cells, structs and cs-lists.  This usually reduces
+    both time and memory consumption.
+    Also, Octave will now attempt to detect and optimize usage of a vector 
+    as a stack, when elements are being repeatedly inserted at/removed from 
+    the end of the vector.
+
+ ** Improved performance for reduction operations.
+
+    The performance of the sum, prod, sumsq, cumsum, cumprod, any, all,
+    max and min functions has been significantly improved.
+
+ ** Sorting and searching.
+    
+    The performance of sort has been improved, especially when sorting
+    indices are requested. An efficient built-in issorted implementation
+    was added. sortrows now uses a more efficient algorithm, especially
+    in the homegeneous case. lookup is now a built-in function performing
+    a binary search, optimized for long runs of close elements. Lookup
+    also works with cell arrays of strings.
+
+ ** Range arithmetics
+
+    For some operations on ranges, Octave will attempt to keep the result as a
+    range.  These include negation, adding a scalar, subtracting a scalar, and
+    multiplying by a scalar. Ranges with zero increment are allowed and can be
+    constructed using the built-in function `ones'.
+
+ ** Various performance improvements.
+
+    Performance of a number of other built-in operations and functions was
+    improved, including:
+
+    * logical operations
+    * comparison operators
+    * element-wise power
+    * accumarray
+    * cellfun
+    * isnan
+    * isinf
+    * isfinite
+    * nchoosek
+    * repmat
+    * strcmp
+
+ ** 64-bit integer arithmetic.
+
+    Arithmetic with 64-bit integers (int64 and uint64 types) is fully
+    supported, with saturation semantics like the other integer types.
+    Performance of most integer arithmetic operations has been
+    improved by using integer arithmetic directly.  Previously, Octave
+    performed integer math with saturation semantics by converting the
+    operands to double precision, performing the operation, and then
+    converting the result back to an integer value, truncating if
+    necessary.
+
+ ** Diagonal and permutation matrices.
+
+    The interpreter can now treat diagonal and permutation matrices as
+    special objects that store only the non-zero elements, rather than
+    general full matrices.  Therefore, it is now possible to construct
+    and use these matrices in linear algebra without suffering a
+    performance penalty due to storing large numbers of zero elements.
+
+ ** Improvements to fsolve.
+
+    The fsolve function now accepts an option structure argument (see
+    also the optimset function).  The INFO values returned from fsolve
+    have changed to be compatible with Matlab's fsolve function.
+    Additionally, fsolve is now able to solve overdetermined systems,
+    complex-differentiable complex systems, systems with a sparse
+    jacobian and can work in single precision if given single precision
+    inputs.  It can also be called recursively.
+
+ ** Improvements to the norm function.
+
+    The norm function is now able to compute row or column norms of a
+    matrix in a single call, as well as general matrix p-norms.
+
+ ** New functions for computing some eigenvalues or singular values.
+
+    The eigs and svds functions have been included in Octave.  These
+    functions require the ARPACK library (now distributed under a
+    GPL-compatible license).
+
+ ** New QR and Cholesky factorization updating functions.
+
+      choldelete  cholshift   qrdelete  qrshift
+      cholinsert  cholupdate  qrinsert  qrupdate
+
+ ** New quadrature functions.
+
+      dblquad  quadgk  quadv  triplequad
+
+ ** New functions for reading and writing images.
+
+    The imwrite and imread functions have been included in Octave.
+    These functions require the GraphicsMagick library.  The new
+    function imfinfo provides information about an image file (size,
+    type, colors, etc.)
+
+ ** The input_event_hook function has been replaced by the pair of
+    functions add_input_event_hook and remove_input_event_hook so that
+    more than one hook function may be installed at a time.
+
+ ** Other miscellaneous new functions.
+
+      addtodate          hypot                       reallog
+      bicgstab           idivide                     realpow
+      cellslices         info                        realsqrt
+      cgs                interp1q                    rectint
+      command_line_path  isdebugmode                 regexptranslate
+      contrast           isfloat                     restoredefaultpath
+      convn              isstrprop                   roundb
+      cummin             log1p                       rundemos
+      cummax             lsqnonneg                   runlength
+      datetick           matlabroot                  saveobj
+      display            namelengthmax               spaugment
+      expm1              nargoutchk                  strchr
+      filemarker         pathdef                     strvcat
+      fstat              perl                        subspace
+      full               prctile                     symvar
+      fzero              quantile                    treelayout
+      genvarname         re_read_readline_init_file  validatestring
+      histc
+
+ ** Changes to strcat.
+
+    The strcat function is now compatible with Matlab's strcat
+    function, which removes trailing whitespace when concatenating
+    character strings.  For example
+
+      strcat ('foo ', 'bar')
+      ==> 'foobar'
+
+    The new function cstrcat provides the previous behavior of
+    Octave's strcat.
+
+ ** Improvements to the help functions.
+
+    The help system has been mostly re-implemented in .m files to make
+    it easier to modify.  Performance of the lookfor function has been
+    greatly improved by caching the help text from all functions that
+    are distributed with Octave.  The pkg function has been modified
+    to generate cache files for external packages when they are
+    installed.
+
+ ** Deprecated functions.
+
+    The following functions were deprecated in Octave 3.0 and will be
+    removed in Octave 3.4 (or whatever version is the second major
+    release after 3.0):
+                                           
+      beta_cdf         geometric_pdf        pascal_pdf      
+      beta_inv         geometric_rnd        pascal_rnd      
+      beta_pdf         hypergeometric_cdf   poisson_cdf     
+      beta_rnd         hypergeometric_inv   poisson_inv     
+      binomial_cdf     hypergeometric_pdf   poisson_pdf     
+      binomial_inv     hypergeometric_rnd   poisson_rnd     
+      binomial_pdf     intersection         polyinteg       
+      binomial_rnd     is_bool              setstr          
+      chisquare_cdf    is_complex           struct_contains 
+      chisquare_inv    is_list              struct_elements 
+      chisquare_pdf    is_matrix            t_cdf           
+      chisquare_rnd    is_scalar            t_inv           
+      clearplot        is_square            t_pdf           
+      clg              is_stream            t_rnd           
+      com2str          is_struct            uniform_cdf     
+      exponential_cdf  is_symmetric         uniform_inv     
+      exponential_inv  is_vector            uniform_pdf     
+      exponential_pdf  isstr                uniform_rnd     
+      exponential_rnd  lognormal_cdf        weibcdf         
+      f_cdf            lognormal_inv        weibinv         
+      f_inv            lognormal_pdf        weibpdf         
+      f_pdf            lognormal_rnd        weibrnd         
+      f_rnd            meshdom              weibull_cdf     
+      gamma_cdf        normal_cdf           weibull_inv     
+      gamma_inv        normal_inv           weibull_pdf     
+      gamma_pdf        normal_pdf           weibull_rnd     
+      gamma_rnd        normal_rnd           wiener_rnd      
+      geometric_cdf    pascal_cdf
+      geometric_inv    pascal_inv
+
+    The following functions are now deprecated in Octave 3.2 and will
+    be removed in Octave 3.6 (or whatever version is the second major
+    release after 3.2):
+
+      create_set          spcholinv  spmax
+      dmult               spcumprod  spmin
+      iscommand           spcumsum   spprod
+      israwcommand        spdet      spqr
+      lchol               spdiag     spsum
+      loadimage           spfind     spsumsq
+      mark_as_command     spinv      str2mat
+      mark_as_rawcommand  spkron     unmark_command
+      spatan2             splchol    unmark_rawcommand
+      spchol              split
+      spchol2inv          splu
+
+See NEWS.3 for old news.
diff --git a/NEWS.1 b/NEWS.1
new file mode 100644
index 0000000..eb1f9f9
--- /dev/null
+++ b/NEWS.1
@@ -0,0 +1,1602 @@
+Summary of changes for version 1.1.1:
+------------------------------------
+
+  * New built-in variables, default_return_value and
+    define_all_return_values.
+
+    If define_all_return_values is set to "false", Octave does not do
+    anything special for return values that are left undefined, and
+    you will get an error message if you try to use them.  For
+    example, if the function
+
+      function [x, y] = f ()
+        y = 1;
+      endfunction
+
+    is called as
+
+      octave:13> [a, b] = f ()
+
+    Octave will print an error message for the attempt to assign an
+    undefined value to `a'.
+
+    This is incompatible with Matlab, which will define the return
+    variable `x' to be the empty matrix.  To get the Matlab-like
+    behavior, you can set the variable define_all_return_values to
+    "true" (the default is "false") and default_return_value to `[]'
+    (the default).  Then, any return values that remain undefined when
+    the function returns will be initialized to `[]'.
+
+    If the function is called without explicitly asking for an output,
+    it will succeed.  This behavior is compatible and unchanged from
+    previous versions of Octave.
+
+  * New built-in variable suppress_verbose_help_message.  If set to
+    "true", Octave will not add additional help information to the end
+    of the output from the help command and usage messages for
+    built-in commands.  The default value is "false".
+
+  * New built-in variable PS4 is used as the prefix of echoed input
+    (enabled with the --echo-input (-x) option).
+
+  * The function size() now accepts an optional second argument.
+
+  * Output from `save - ...' now goes through the pager.
+
+  * The break statement may also be used to exit a function, for
+    compatibility with Matlab.
+
+  * The directory tree for installing Octave is now closer to
+    conforming with the current GNU standards.
+
+  * More bug fixes.
+
+Summary of changes for version 1.1.0:
+------------------------------------
+
+  * Octave now requires g++ 2.6.3 or later.  This change is necessary
+    to make template instantiations cleaner, and to avoid having to
+    have special cases in the code for earlier versions of gcc.
+
+  * A new data structure type has been added.  The implementation uses
+    an associative array with indices limited to strings, but the
+    syntax is more like C-style structures.  here are some examples of
+    using it.
+
+    Elements of structures can be of any type, including structures:
+
+      octave:1> x.a = 1;
+      octave:2> x.b = [1, 2; 3, 4];
+      octave:3> x.c = "string";
+      octave:4> x
+      x =
+
+      <structure: a b c>
+
+      octave:5> x.a
+      x.a = 1
+      octave:6> x.b
+      x.b =
+
+        1  2
+        3  4
+
+      octave:7> x.c
+      x.c = string
+      octave:8> x.b.d = 3
+      x.b.d = 3
+      octave:9> x.b
+      x.b =
+
+      <structure: d>
+
+      octave:10> x.b.d
+      x.b.d = 3
+
+    Functions can return structures:
+
+      octave:1> a = rand (3) + rand (3) * I;
+      octave:2> function y = f (x)
+      > y.re = real (x);
+      > y.im = imag (x);
+      > endfunction
+      octave:3> f (a)
+      ans =
+
+      <structure: im re>
+
+      octave:4> ans.im
+      ans.im =
+
+        0.093411  0.229690  0.627585
+        0.415128  0.221706  0.850341
+        0.894990  0.343265  0.384018
+
+      octave:5> ans.re
+      ans.re =
+
+        0.56234  0.14797  0.26416
+        0.72120  0.62691  0.20910
+        0.89211  0.25175  0.21081
+
+    Return lists can include structure elements:
+
+      octave:1> [x.u, x.s, x.v] = svd ([1, 2; 3, 4])
+      x.u =
+
+        -0.40455  -0.91451
+        -0.91451   0.40455
+
+      x.s =
+
+        5.46499  0.00000
+        0.00000  0.36597
+
+      x.v =
+
+        -0.57605   0.81742
+        -0.81742  -0.57605
+
+      octave:8> x
+      x =
+
+      <structure: s u v>
+
+    This feature should be considered experimental, but it seems to
+    work ok.  Suggestions for ways to improve it are welcome.
+
+  * Octave now supports a limited form of exception handling modelled
+    after the unwind-protect form of Lisp:
+
+      unwind_protect
+        BODY
+      unwind_protect_cleanup
+        CLEANUP
+      end_unwind_protect
+
+    Where BODY and CLEANUP are both optional and may contain any
+    Octave expressions or commands.  The statements in CLEANUP are
+    guaranteed to be executed regardless of how control exits BODY.
+
+    This is useful to protect temporary changes to global variables
+    from possible errors.  For example, the following code will always
+    restore the original value of the built-in variable
+    do_fortran_indexing even if an error occurs while performing the
+    indexing operation.
+
+      save_do_fortran_indexing = do_fortran_indexing;
+      unwind_protect
+        do_fortran_indexing = "true";
+        elt = a (idx)
+      unwind_protect_cleanup
+        do_fortran_indexing = save_do_fortran_indexing;
+      end_unwind_protect
+
+    Without unwind_protect, the value of do_fortran_indexing would not
+    be restored if an error occurs while performing the indexing
+    operation because evaluation would stop at the point of the error
+    and the statement to restore the value would not be executed.
+
+  * Recursive directory searching has been implemented using Karl
+    Berry's kpathsea library.  Directories below path elements that
+    end in // are searched recursively for .m files.
+
+  * Octave now waits for additional input when a pair of parentheses
+    is `open' instead of giving an error.  This allows one to write
+    statements like this
+
+      if (big_long_variable_name == other_long_variable_name
+          || not_so_short_variable_name > 4
+          && y > x)
+        some (code, here);
+
+    without having to clutter up the if statement with continuation
+    characters.
+
+  * Continuation lines are now allowed in string constants and are
+    handled correctly inside matrix constants.
+
+  * Both `...{whitespace}\n' and `\{whitespace}\n' can be used to
+    introduce continuation lines, where {whitespace} may include
+    spaces, tabs and comemnts.
+
+  * The script directory has been split up by topic.
+
+  * Dynamic linking mostly works with dld.  The following limitations
+    are known problems:
+
+    -- Clearing dynamically linked functions doesn't work.
+
+    -- Dynamic linking only works with dld, which has not been ported
+       to very many systems yet.
+
+    -- Configuring with --enable-lite-kernel seems to mostly work to
+       make nonessential built-in functions dynamically loaded, but
+       there also seem to be some problems.  For example, fsolve seems
+       to always return info == 3.  This is difficult to debug since
+       gdb won't seem to allow breakpoints to be set inside
+       dynamically loaded functions.
+
+    -- Octave uses a lot of memory if the dynamically linked functions
+       are compiled with -g.  This appears to be a limitation with
+       dld, and can be avoided by not using -g to compile functions
+       that will be linked dynamically.
+
+  * fft2 and ifft2 are now built-in functions.
+
+  * The `&&' and `||' logical operators are now evaluated in a
+    short-circuit fashion and work differently than the element by
+    element operators `&' and `|'.  See the Octave manual for more
+    details.
+
+  * Expressions like 1./m are now parsed as 1 ./ m, not 1. / m.
+
+  * The replot command now takes the same arguments as gplot or
+    gsplot (except ranges, which cannot be respecified with replot
+    (yet)) so you can add additional lines to existing plots.
+
+  * The hold command has been implemented.
+
+  * New function `clearplot' clears the plot window.  The name `clg'
+    is aliased to `clearplot' for compatibility with Matlab.
+
+  * The commands `gplot clear' and `gsplot clear' are equivalent to
+    `clearplot'.  (Previously, `gplot clear' would evaluate `clear' as
+    an ordinary expression and clear all the visible variables.)
+
+  * The Matlab-style plotting commands have been improved.  They now
+    accept line-style arguments, multiple x-y pairs, and other plot
+    option flags.  For example,
+ 
+      plot (x, y, "@12", x, y2, x, y3, "4", x, y4, "+")
+
+    results in a plot with
+
+      y  plotted with points of type 2 ("+") and color 1 (red).
+      y2 plotted with lines.
+      y3 plotted with lines of color 4.
+      y4 plotted with points which are "+"s.
+
+    the help message for `plot' and `plot_opt' provide full
+    descriptions of the options.
+
+  * NaN is now dropped from plot data, and Inf is converted to a
+    very large value before calling gnuplot.
+
+  * Improved load and save commands:
+
+    -- The save and load commands can now read and write a new binary
+       file format.  Conversion to and from IEEE big and little endian
+       formats is handled automatically.  Conversion for other formats
+       has not yet been implemented.
+
+    -- The load command can now read Matlab .mat files, though it is
+       not yet able to read sparse matrices or handle conversion for
+       all data formats.
+
+    -- The save command can write Matlab .mat files.
+
+    -- The load command automatically determines the save format
+       (binary, ascii, or Matlab binary).
+
+    -- The default format for the save command is taken from the
+       built-in variable `default_save_format'.
+
+    -- The save and load commands now both accept a list of globbing
+       patterns so you can easily load a list of variables from a
+       file.
+
+    -- The load command now accepts the option -list, for listing the
+       variable names without actually loading the data.  With
+       -verbose, it prints a long listing.
+
+    -- The load command now accepts the option -float-binary, for
+       saving floating point data in binary files in single precision.
+
+  * who and whos now accept a list of globbing patterns so you can
+    limit the lists of variables and functions to those that match a
+    given set of patterns.
+
+  * New functions for manipulating polynomials
+      
+      compan     -- companion matrix corresponding to polynomial coefficients
+      conv       -- convolve two vectors
+      deconv     -- deconvolve two vectors
+      roots      -- find the roots of a polynomial
+      poly       -- characteristic polynomial of a matrix
+      polyderiv  -- differentiate a polynomial
+      polyinteg  -- integrate a polynomial
+      polyreduce -- reduce a polynomial to minimum number of terms
+      polyval    -- evaluate a polynomial at a point
+      polyvalm   -- evaluate a polynomial in the matrix sense
+      residue    -- partial fraction expansion corresponding to the ratio
+                    of two polynomials
+
+  * New functions for manipulating sets
+
+      create_set   -- create a set of unique values
+      complement   -- find the complement of two sets
+      intersection -- find the intersection of two sets
+      union        -- find the union of two sets
+
+  * New elementary functions:
+
+      acot   acoth   acsc   acsch
+      asec   asech   cot    coth
+      csc    csch    log2   sec
+      sech
+
+  * New special functions:
+
+      beta   -- beta function
+      betai  -- incomplete beta function
+      gammai -- incomplete gamma function
+
+  * New image processing functions:
+
+      colormap  -- set and return current colormap
+      gray      -- set a gray colormap
+      gray2ind  -- image format conversion
+      image     -- display an image
+      imagesc   -- scale and display an image
+      imshow    -- display images
+      ind2gray  -- image format conversion
+      ind2rgb   -- image format conversion
+      loadimage -- load an image from a file
+      ntsc2rgb  -- image format conversion
+      ocean     -- set a color colormap
+      rgb2ind   -- image format conversion
+      rgb2ntsc  -- image format conversion
+      saveimage -- save an image to a file
+
+  * New time and date funcitons:
+
+      tic          -- set wall-clock timer
+      toc          -- get elapsed wall-clock time, since timer last set
+      etime        -- another way to get elapsed wall-clock time
+      cputime      -- get CPU time used since Octave started
+      is_leap_year -- is the given year a leap year?
+
+  * Other new functions:
+
+      bug_report -- submit a bug report to the bug-octave mailing list
+
+      toascii -- convert a string to a matrix of ASCII character codes
+
+      octave_tmp_file -- generate a unique temporary file name
+
+      undo_string_escapes -- replace special characters in a string by
+                             their backslash forms
+
+      is_struct -- determine whether something is a structure data type
+
+      feof   -- check EOF condition for a specified file
+      ferror -- check error state for a specified file
+      fread  -- read binary data from a file
+      fwrite -- write binary data to a file
+
+      file_in_path -- check to see if named file exists in given path
+
+      kbhit  -- get a single character from the terminal
+
+      axis   -- change plot ranges
+      hist   -- plot histograms
+
+      diary  -- save commands and output to a file
+
+      type   -- show the definition of a function
+      which  -- print the type of an identifier or the location of a
+                function file
+
+      isieee  -- Returns 1 if host uses IEEE floating point
+      realmax -- Returns largest floating point number
+      realmin -- Returns smallest floating point number
+
+      gcd     -- greatest common divisor
+      lcm     -- least common multiple
+
+      null    -- orthonormal basis of the null space of a matrix
+      orth    -- orthonormal basis of the range space of a matrix
+
+      fft2    -- two-dimensional fast fourier transform
+      ifft2   -- two-dimensional inverse fast fourier transform
+      filter  -- digital filter
+      fftfilt -- filter using fft
+      fftconv -- convolve to vectors using fft
+      sinc    -- returns sin(pi*x)/(pi*x)
+      freqz   -- compute the frequency response of a filter
+
+  * The meaning of nargin (== args.length ()) in built-in functions
+    has been changed to match the meaning of nargin in user-defined
+    functions.
+
+  * Variable return lists.  Octave now has a real mechanism for
+    handling functions that return an unspecified number of values,
+    so it is no longer necessary to place an upper bound on the number
+    of outputs that a function can produce.
+
+    Here is an example of a function that uses the new syntax to
+    produce n values:
+
+      function [...] = foo (n)
+        for i = 1:n
+          vr_val (i * x);
+        endfor
+      endfunction
+
+  * New keyword, all_va_args, that allows the entire list of va_args
+    to be passed to another function.  For example, given the functions
+
+      function f (...)
+        while (nargin--)
+          disp (va_arg ())
+        endwhile
+      endfunction
+      function g (...)
+        f ("begin", all_va_args, "end")
+      endfunction
+
+    the statement
+
+      g (1, 2, 3)
+
+    prints
+
+      begin
+      1
+      2
+      3
+      end
+
+    all_va_args may be used more than once, but can only be used
+    within functions that take a variable number of arguments.
+
+  * If given a second argument, svd now returns an economy-sized
+    decomposition, eliminating the unecessary rows or columns of U or
+    V.
+
+  * The max and min functions correctly handle complex matrices in
+    which some columns contain real values only.
+
+  * The find function now handles 2 and 3 output arguments.
+
+  * The qr function now allows computation of QR with pivoting.
+
+  * hilb() is much faster for large matrices.
+
+  * computer() is now a built-in function.
+
+  * pinv() is now a built-in function.
+
+  * The output from the history command now goes through the pager.
+
+  * If a function is called without assigning the result, nargout is
+    now correctly set to 0.
+
+  * It is now possible to write functions that only set some return
+    values.  For example, calling the function
+
+      function [x, y, z] = f () x = 1; z = 2; endfunction
+
+    as
+
+      [a, b, c] = f ()
+
+    produces:
+
+      a = 1
+
+      b = [](0x0)
+
+      c = 2
+
+  * The shell_cmd function has been renamed to system (the name
+    shell_cmd remains for compatibility).  It now returns [output, status].
+
+  * New built-in variable `OCTAVE_VERSION'.  Also a new function,
+    version, for compatibility with Matlab.
+
+  * New built-in variable `automatic_replot'.  If it is "true", Octave
+    will automatically send a replot command to gnuplot each time the
+    plot changes.  Since this is fairly inefficient, the default value
+    is "false".
+
+  * New built-in variable `whitespace_in_literal_matrix' allows some
+    control over how Octave decides to convert spaces to commas in
+    matrix expressions like `[m (1)]'.
+
+    If the value of `whitespace_in_literal_matrix' is "ignore", Octave
+    will never insert a comma or a semicolon in a literal matrix list.
+    For example, the expression `[1 2]' will result in an error
+    instead of being treated the same as `[1, 2]', and the expression
+
+      [ 1, 2,
+        3, 4 ]
+
+    will result in the vector [1 2 3 4] instead of a matrix.
+
+    If the value of `whitespace_in_literal_matrix' is "traditional",
+    Octave will convert spaces to a comma between identifiers and `('.
+    For example, given the matrix
+
+      m = [3 2]
+
+    the expression
+
+      [m (1)]
+
+    will be parsed as
+
+      [m, (1)]
+
+    and will result in
+
+      [3 2 1]
+
+    and the expression
+
+      [ 1, 2,
+        3, 4 ]
+
+    will result in a matrix because the newline character is converted
+    to a semicolon (row separator) even though there is a comma at the
+    end of the first line (trailing commas or semicolons are ignored).
+    This is apparently how Matlab behaves.
+
+    Any other value for `whitespace_in_literal_matrix' results in
+    behavior that is the same as traditional, except that Octave does
+    not convert spaces to a comma between identifiers and `('.
+    For example, the expression
+
+      [m (1)]
+
+    will produce 3.  This is the way Octave has always behaved.
+
+  * Line numbers in error messages for functions defined in files and
+    for script files now correspond to the file line number, not the
+    number of lines after the function keyword appeared.
+
+  * Octave now extracts help from script files.  The comments must
+    come before any other statements in the file.
+
+  * In function files, the first block of comments in the file will
+    now be interpreted as the help text if it doesn't look like the
+    Octave copyright notice.  Otherwise, Octave extracts the first set
+    of comments after the function keyword.
+
+  * The function clock is more accurate on systems that have the
+    gettimeofday() function.
+
+  * The standard output stream is now automatically flushed before
+    reading from stdin with any of the *scanf() functions.
+
+  * Expanded reference card.
+
+  * The Octave distribution now includes a frequently asked questions
+    file, with answers.  Better answers and more questions (with
+    answers!) are welcome.
+
+  * New option --verbose.  If Octave is invoked with --verbose and not
+    --silent, a message is printed if an octaverc file is read while
+    Octave is starting.
+
+  * An improved configure script generated by Autoconf 2.0.
+
+  * Lots of bug fixes.
+
+Summary of changes for version 1.0:
+----------------------------------
+
+  * C-style I/O functions now handle files referenced by name or by
+    number more consistently.
+
+Summary of changes for version 0.83:
+-----------------------------------
+
+  * Loading global symbols should work now.
+
+  * Clearing the screen doesn't reprint the prompt unnecessarily.
+
+  * The operations <complex scalar> OP <real matrix> for OP == +, -,
+    *, or ./ no longer crash Octave.
+
+  * More portability and configuration fixes.
+
+Summary of changes for version 0.82:
+-----------------------------------
+
+  * Octave now comes with a reference card.
+
+  * The manual has been improved, but more work remains to be done.
+
+  * The atanh function now works for complex arguments.
+
+  * The asin, acos, acosh, and atanh functions now work properly when
+    given real-valued arguments that produce complex results.
+
+  * SEEK_SET, SEEK_CUR, and SEEK_END are now constants.
+
+  * The `using' qualifier now works with gplot and gsplot when the
+    data to plot is coming directly from a file.
+
+  * The strcmp function now works correctly for empty strings.
+
+  * Eliminated bogus parse error for M-files that don't end with `end'
+    or `endfunction'.
+
+  * For empty matrices with one nonzero dimension, the +, -, .*, and
+    ./ operators now correctly preserve the dimension.
+
+  * Octave no longer crashes if you type ^D at the beginning of a line
+    in the middle of defining a loop or if statement.
+
+  * On AIX systems, Back off on indexing DiagArray via Proxy class to
+    avoid gcc (or possibly AIX assembler?) bug. 
+
+  * Various other bug and portability fixes.
+
+Summary of changes for version 0.81:
+-----------------------------------
+
+  * Octave no longer dumps core if you try to define a function in
+    your .octaverc file.
+
+  * Fixed bug in Array class that resulted in bogus off-diagonal
+    elements when computing eigenvalue and singular value
+    decompositions.
+
+  * Fixed bug that prevented lsode from working on the SPARCstation,
+    at least with some versions of Sun's f77.  This bug was introduced
+    in 0.80, when I changed LSODE to allow the user to abort the
+    integration from within the RHS function.
+
+  * Fixed bug that prevented global attribute of variables from being
+    saved with save(), and another that prevented load() from working
+    at all.
+
+Summary of changes for version 0.80:
+-----------------------------------
+
+  * I have started working on a manual for the C++ classes.  At this
+    point, it is little more than a list of function names.  If you
+    would like to volunteer to help work on this, please contact
+    maintainers at octave.org.
+
+  * The patterns accepted by the save and clear commands now work like
+    file name globbing patterns instead of regular expressions.  I
+    apologize for any inconvenience this change may cause, but file
+    name globbing seems like a more reasonable style of pattern
+    matching for this purpose.
+
+  * It is now possible to specify tolerances and other optional inputs
+    for dassl, fsolve, lsode, npsol, qpsol, and quad.  For each of
+    these functions, there is a corresponding function X_options,
+    which takes a keyword and value arguments.  If invoked without any
+    arguments, the X_options functions print a list of possible
+    keywords and current values.  For example,
+
+      npsol_options ()
+
+    prints a list of possible options with values, and
+
+      npsol_options ("major print level", 10)
+
+    sets the major print level to 10.
+
+    The keyword match is not case sensitive, and the keywords may be
+    abbreviated to the shortest unique match.  For example,
+
+      npsol_options ("ma p", 10)
+
+    is equivalent to the statement shown above.
+
+  * The new built-in variable save_precision can be used to set the
+    number of digits preserved by the ASCII save command.
+
+  * Assignment of [] now works in most cases to allow you to delete
+    rows or columns of matrices and vectors.  For example, given a
+    4x5 matrix A, the assignment
+
+      A (3, :) = []
+
+    deletes the third row of A, and the assignment
+
+      A (:, 1:2:5) = []
+
+    deletes the first, third, and fifth columns.
+
+  * Variable argument lists.  Octave now has a real mechanism for
+    handling functions that take an unspecified number of arguments,
+    so it is no longer necessary to place an upper bound on the number
+    of optional arguments that a function can accept.
+
+    Here is an example of a function that uses the new syntax to print
+    a header followed by an unspecified number of values:
+
+      function foo (heading, ...)
+        disp (heading);
+        va_start ();
+        while (--nargin)
+          disp (va_arg ());
+        endwhile
+      endfunction
+
+    Note that the argument list must contain at least one named
+    argument (this restriction may eventually be removed), and the
+    ellipsis must appear as the last element of the argument list.
+
+    Calling va_start() positions an internal pointer to the first
+    unnamed argument and allows you to cycle through the arguments
+    more than once.  It is not necessary to call va_start() if you
+    do not plan to cycle through the arguments more than once.
+
+  * Recursive functions should work now.
+
+  * The environment variable OCTAVE_PATH is now handled in the same
+    way as TeX handles TEXINPUTS.  If the path starts with `:', the
+    standard path is prepended to the value obtained from the
+    environment.  If it ends with `:' the standard path is appended to
+    the value obtained from the environment.
+
+  * New functions, from Kurt Hornik (hornik at neuro.tuwien.ac.at) and
+    the Department of Probability Theory and Statistics TU Wien,
+    Austria:
+
+     corrcoef    -- corrcoef (X, Y) is the correlation between the i-th
+                    variable in X and the j-th variable in Y
+                    corrcoef (X) is corrcoef (X, X)
+     cov         -- cov (X, Y) is the covariance between the i-th
+                    variable in X and the j-th variable in Y
+                    cov (X) is cov (X, X)
+     gls         -- generalized least squares estimation
+     kurtosis    -- kurtosis(x) = N^(-1) std(x)^(-4) SUM_i (x(i)-mean(x))^4 - 3
+                    If x is a matrix, return the row vector containing
+                    the kurtosis of each column
+     mahalanobis -- returns Mahalanobis' D-square distance between the
+                    multivariate samples X and Y, which must have the
+                    same number of components (columns), but may have
+                    a different number of observations (rows)
+     ols         -- ordinary least squares estimation
+     pinv        -- returns the pseudoinverse of X; singular values
+                    less than tol are ignored
+     skewness    -- skewness (x) = N^(-1) std(x)^(-3) SUM_i (x(i)-mean(x))^3
+                    if x is a matrix, return the row vector containing
+                    the skewness of each column
+
+  * Errors in user-supplied functions called from dassl, fsolve,
+    lsode, npsol, and quad are handled more gracefully.
+
+  * Programming errors in the use of the C++ classes within Octave
+    should no longer cause Octave to abort.  Instead, Octave's error
+    handler function is called and execution continues as best as is
+    possible.  This should result in eventually returning control to
+    the top-level Octave prompt.  (It would be nice to have a real
+    exception handling mechanism...)
+
+  * A number of memory leaks have been eliminated.  Thanks to
+    Fong Kin Fui <fui at ee.nus.sg> for reporting them.
+
+  * The C++ matrix classes are now derived from a generic
+    template-based array class.
+
+  * The readline function operate-and-get-next (from bash) is now
+    available and bound to C-O by default.
+
+  * Octave now uses the version of readline currently distributed with
+    bash-1.13.  On some systems, interactive invocations of Octave
+    will now blink the cursor to show matching parens.
+
+  * By default, include files are now installed in
+    $prefix/include/octave instead of $prefix/include.
+
+  * Octave now uses a config.h file instead of putting all defines on
+    the compiler command line.
+
+Summary of changes for version 0.79:
+-----------------------------------
+
+  * New control systems functions:
+
+     dgram -- Returns the discrete controllability and observability gramian.
+     dlqr  -- Discrete linear quadratic regulator design.
+     dlqe  -- Discrete linear quadratic estimator (Kalman Filter) design.
+     c2d   -- Convert continuous system description to discrete time
+              description assuming zero-order hold and given sample time.
+
+  * The max (min) functions can now return the index of the max (min)
+    value as a second return value.
+
+Summary of changes for version 0.78:
+-----------------------------------
+
+  * Octave's handling of global variables has been completely
+    rewritten.  To access global variables inside a function, you must
+    now declare them to be global within the function body.  Likewise,
+    if you do not declare a variable as global at the command line,
+    you will not have access to it within a function, even if it is
+    declared global there.  For example, given the function
+
+      function f ()
+        global x = 1;
+        y = 2;
+      endfunction
+
+    the global variable `x' is not visible at the top level until the
+    command
+
+      octave:13> global x
+
+    has been evaluated, and the variable `y' remains local to the
+    function f() even if it is declared global at the top level.
+
+    Clearing a global variable at the top level will remove its global
+    scope and leave it undefined.  For example,
+
+      octave:1> function f ()   # Define a function that accesses
+      >  global x;              #   the global variable `x'.
+      >  x
+      > endfunction
+      octave:2> global x = 1    # Give the variable `x' a value.
+      octave:3> f ()            # Evaluating the function accesses the
+      x = 1                     #   global `x'.
+      octave:4> clear x         # Remove `x' from global scope, clear value.
+      octave:5> x = 2           # Define new local `x' at the top level
+      x = 2
+      octave:6> f               # The global `x' is no longer defined.
+      error: `x' undefined near line 1 column 25
+      error: evaluating expression near line 1, column 25
+      error: called from `f'
+      octave:7> x               # But the local one is.
+      x = 2
+
+  * The new function, `is_global (string)' returns 1 if the variable
+    named by string is globally visible.  Otherwise, returns 0.
+
+  * The implementation of `who' has changed.  It now accepts the
+    following options:
+
+      -b -builtins   -- display info for built-in variables and functions
+      -f -functions  -- display info for currently compiled functions
+      -v -variables  -- display info for user variables
+      -l -long       -- display long info
+
+    The long output looks like this:
+
+      octave:5> who -l
+
+      *** currently compiled functions:
+
+      prot  type               rows   cols  name
+      ====  ====               ====   ====  ====
+       wd   user function         -      -  f
+
+      *** local user variables:
+
+      prot  type               rows   cols  name
+      ====  ====               ====   ====  ====
+       wd   real scalar           1      1  y
+
+      *** globally visible user variables:
+
+      prot  type               rows   cols  name
+      ====  ====               ====   ====  ====
+       wd   complex matrix       13     13  x
+
+    where the first character of the `protection' field is `w' if the
+    symbol can be redefined, and `-' if it has read-only access.  The
+    second character may be `d' if the symbol can be deleted, or `-'
+    if the symbol cannot be cleared.
+
+  * The new built-in variable ignore_function_time_stamp can be used
+    to prevent Octave from calling stat() each time it looks up
+    functions defined in M-files.  If set to "system", Octave will not
+    automatically recompile M-files in subdirectories of
+    $OCTAVE_HOME/lib/VERSION if they have changed since they were last
+    compiled, but will recompile other M-files in the LOADPATH if they
+    change.  If set to "all", Octave will not recompile any M-files
+    unless their definitions are removed with clear.  For any other
+    value of ignore_function_time_stamp, Octave will always check to
+    see if functions defined in M-files need to recompiled.  The
+    default value of ignore_function_time_stamp is "system".
+
+  * The new built-in variable EDITOR can be used to specify the editor
+    for the edit_history command.  It is set to the value of the
+    environment variable EDITOR, or `vi' if EDITOR is not set, or is
+    empty.
+
+  * There is a new built-in variable, INFO_FILE, which is used as the
+    location of the info file.  Its initial value is
+    $OCTAVE_HOME/info/octave.info, so `help -i' should now work
+    provided that OCTAVE_HOME is set correctly, even if Octave is
+    installed in a directory different from that specified at compile
+    time.
+
+  * There is a new command line option, --info-file FILE, that may be
+    used to set Octave's idea of the location of the info file.  It
+    will override any value of OCTAVE_INFO_FILE found in the
+    environment, but not any INFO_FILE="filename" commands found in
+    the system or user startup files. 
+
+  * Octave's Info reader will now recognize gzipped files that have
+    names ending in `.gz'.
+
+  * The save command now accepts regular expressions as arguments.
+    Note that these patterns are regular expressions, and do not work
+    like filename globbing.  For example, given the variables `a',
+    `aa', and `a1', the command `save a*' saves `a' and `aa' but not
+    `a1'.  To match all variables beginning with `a', you must use an
+    expression like `a.*' (match all sequences beginning with `a'
+    followed by zero or more characters).
+
+  * Line and column information is included in more error messages.
+
+Summary of changes for version 0.77:
+-----------------------------------
+
+  * Improved help.  The command `help -i topic' now uses the GNU Info
+    browser to display help for the given topic directly from the
+    Texinfo documenation.
+
+  * New function: chol -- Cholesky factorization.
+
+Summary of changes for version 0.76:
+-----------------------------------
+
+  * Better run-time error messages.  Many now include line and column
+    information indicating where the error occurred.  Octave will also
+    print a traceback for errors occurring inside functions. If you
+    find error messages that could use improvement, or errors that
+    Octave fails to catch, please send a bug report to
+    bug at octave.org.
+
+  * If gplot (or gsplot) is given a string to plot, and the string
+    does not name a file, Octave will pass the string along to gnuplot
+    directly.  This allows commands like
+
+      gplot "sin (x)" w l, data w p
+
+    to work (assuming that data is a variable containing a matrix of
+    values).
+
+  * Long options (--help, --version, etc.) are supported.
+
+Summary of changes for version 0.75:
+-----------------------------------
+
+  * The documentation is much more complete, but still could use a lot
+    of work.
+
+  * The history function now prints line numbers by default.  The
+    command `history -q' will  omit them.
+
+  * The clear function now accepts regular expressions.
+
+  * If gplot (or gsplot) is given a string to plot, and the string
+    names a file, Octave attempts to plot the contents of the file.
+
+  * New functions:
+
+    history:
+
+      run_history  -- run commands from the history list.
+      edit_history -- edit commands from the history list with your
+                      favorite editor.
+
+    linear algebra:
+
+      balance         -- Balancing for algebraic and generalized
+                         eigenvalue problems.
+      givens          -- Givens rotation.
+      is_square       -- Check to see if a matrix is square.
+      qzhess          -- QZ decomposition of the matrix pencil (a - lambda b).
+      qzval           -- Generalized eigenvalues for real matrices.
+      syl             -- Sylvester equation solver.
+
+    control systems:
+
+      is_symmetric    -- Check to see if a matrix is symmetric.
+      abcddim         -- Check dimensions of linear dynamic system [A,B,C,D].
+      is_controllable -- Check to see if [A,B,C,D] is controllable.
+      is_observable   -- Check to see if [A,B,C,D] is observable.
+      are             -- Solve algebraic Ricatti equation.
+      dare            -- Solve discrete-time algebraic Ricatti equation.
+      lqe             -- Kalman filter design for continuous linear system.
+      lqr             -- Linear Quadratic Regulator design.
+      lyap            -- Solve Lyapunov equation.
+      dlyap           -- Solve discrete Lyapunov equation.
+      tzero           -- Compute the transmission zeros of [A,B,C,D].
+
+Summary of changes for version 0.74:
+-----------------------------------
+
+  * Formal parameters to functions are now always considered to be
+    local variables, so things like
+
+      global x = 0
+      global y = 0
+      function y = f (x) x = 1; y = x; end
+      f (x)
+
+    result in the function returning 1, with the global values of x
+    and y unchanged.
+
+  * Multiple assignment expressions are now allowed to take indices,
+    so things like
+
+      octave:13> [a([1,2],[3,4]), b([5,6],[7,8])] = lu ([1,2;3,4])
+
+    will work correctly.
+
+Summary of changes for version 0.73:
+-----------------------------------
+
+  * Saving and loading global variables works correctly now.
+
+  * The save command no longer saves built-in variables.
+
+  * Global variables are more reliable.
+
+  * Matrices may now have one or both dimensions zero, so that
+    operations on empty matrices are now handled more consistently.
+
+    By default, dimensions of the empty matrix are now printed along
+    with the empty matrix symbol, `[]'.  For example:
+
+      octave:13> zeros (3, 0)
+      ans = 
+
+      [](3x0)
+
+    The new variable `print_empty_dimensions' controls this behavior.
+    
+    See also Carl de Boor, An Empty Exercise, SIGNUM, Volume 25,
+    pages 2--6, 1990, or C. N. Nett and W. M. Haddad, A
+    System-Theoretic Appropriate Realization of the Empty Matrix
+    Concept, IEEE Transactions on Automatic Control, Volume 38,
+    Number 5, May 1993.
+
+  * The right and left division operators `/' and `\' will now find a
+    minimum norm solution if the system is not square, or if the
+    coefficient matrix is singular.
+
+  * New functions:
+
+      hess   -- Hessenberg decomposition
+      schur  -- Ordered Schur factorization
+      perror -- print error messages corresponding to error codes
+                returned from the functions fsolve, npsol, and qpsol
+                (with others to possibly be added later).
+
+  * Octave now prints a warning if it finds anything other than
+    whitespace or comments after the final `end' or `endfunction'
+    statement.
+
+  * The bodies of functions, and the for, while, and if commands are
+    now allowed to be empty.
+
+  * Support for Gill and Murray's QPSOL has been added.  Like NPSOL,
+    QPSOL is not freely redistributable either, so you must obtain
+    your own copy to be able to use this feature.  More information
+    about where to find QPSOL and NPSOL are in the file README.NLP.
+
+Summary of changes for version 0.72:
+-----------------------------------
+
+  * For numeric output, columns are now lined up on the decimal point.
+    (This requires libg++-2.3.1 or later to work correctly).
+
+  * If octave is running interactively and the output intended for the
+    screen is longer than one page and a pager is available, it is
+    sent to the pager through a pipe.  You may specify the program to
+    use as the pager by setting the variable PAGER.  PAGER may also
+    specify a command pipeline.
+
+  * Spaces are not always significant inside square brackets now, so
+    commands like
+
+      [ linspace (1, 2) ]
+
+    will work.  However, some possible sources of confusion remain
+    because Octave tries (possibly too hard) to determine exactly what
+    operation is intended from the context surrounding an operator.
+    For example:
+
+    -- In the command 
+
+         [ 1 - 1 ]
+
+       the `-' is treated as a binary operator and the result is the
+       scalar 0, but in the command
+
+         [ 1 -1 ]
+
+       the `-' is treated as a unary operator and the result is the
+       vector [ 1 -1 ].
+
+    -- In the command
+
+         a = 1; [ 1 a' ]
+
+       the single quote character `'' is treated as a transpose operator
+       and the result is the vector [ 1 1 ], but in the command
+
+         a = 1; [ 1 a ' ]
+
+       an error message indicating an unterminated string constant is
+       printed.
+
+  * Assignments are just expressions now, so they are valid anywhere
+    other expressions are.  This means that things like
+
+      if (a = n < m) ... endif
+
+    are valid.  This is parsed as:  compare `n < m', assign the result
+    to the variable `a', and use it as the test expression in the if
+    statement.
+
+    To help avoid errors where `=' has been used but `==' was
+    intended, Octave issues a warning suggesting parenthesis around
+    assignments used as truth values.  You can suppress this warning
+    by adding parenthesis, or by setting the value of the new built-in
+    variable `warn_assign_as_truth_value' to 'false' (the default
+    value is 'true').
+
+    This is also true for multiple assignments, so expressions like
+
+      [a, b, c] = [u, s, v] = expression
+
+    are now possible.  If the expression is a function, nargout is set
+    to the number of arguments for the right-most assignment.  The
+    other assignments need not contain the same number of elements.
+    Extra left hand side variables in an assignment become undefined.
+
+  * The default line style for plots is now `lines' instead of
+    `points'.  To change it, use the `set data style STYLE' command.
+
+  * New file handling and I/O functions:
+
+      fopen    -- open a file for reading or writing
+      fclose   -- close a file
+      fflush   -- flush output to a file
+      fgets    -- read characters from a file
+      frewind  -- set file position to the beginning of a file
+      fseek    -- set file position
+      ftell    -- tell file position
+      freport  -- print a report for all open files
+      fscanf   -- read from a file
+      sscanf   -- read from a string
+      scanf    -- read from the standard input
+
+  * New built-in variables for file and I/O functions:
+
+      stdin    -- file number corresponding to the standard input stream.
+      stdout   -- file number corresponding to the standard output stream.
+      stderr   -- file number corresponding to the standard error stream.
+
+    The following may be used as the final (optional) argument for
+    fseek: 
+
+      SEEK_SET -- set position relative to the beginning of the file.
+      SEEK_CUR -- set position relative to the current position.
+      SEEK_END -- set position relative to the end of the file.
+
+  * New function: setstr -- convert vectors or scalars to strings
+    (doesn't work for matrices yet).
+
+  * If possible, computer now prints the system type instead of
+    always printing `Hi Dave, I'm a HAL-9000'.
+
+  * Octave now properly saves and restores its internal state
+    correctly in more places.  Interrupting Octave while it is
+    executing a script file no longer causes it to exit.
+
+  * Octave now does tilde expansion on each element of the LOADPATH.
+
+  * A number of memory leaks have been plugged.
+
+  * Dependencies for C++ source files are now generated automatically
+    by g++.
+
+  * There is a new command line option, -p PATH, that may be used to
+    set Octave's loadpath from the command line.  It will override any
+    value of OCTAVE_PATH found in the environment, but not any
+    LOADPATH="path" commands found in the system or user startup files.
+
+  * It is now possible to override Octave's default idea of the
+    location of the system-wide startup file (usually stored in
+    $(prefix)/lib/octave/octaverc) using the environment variable
+    OCTAVE_HOME.  If OCTAVE_HOME has a value, Octave will look for
+    octaverc and its M-files in the directory $OCTAVE_HOME/lib/octave.
+
+    This allows people who are using binary distributions (as is
+    common with systems like Linux) to install the real octave binary
+    in any directory (using a name like octave.bin) and then install
+    a simple script like this
+
+      #!/bin/sh
+      OCTAVE_HOME=/foo/bar/baz
+      export OCTAVE_HOME
+      exec octave.bin
+
+    to be invoked as octave.
+
+
+Summary of changes for version 0.71:
+-----------------------------------
+
+  * Much improved plotting facility.  With this release, Octave does
+    not require a specially modified version of gnuplot, so gnuplot
+    sources are no longer distributed with Octave.  For a more
+    detailed description of the new plotting features, see the file
+    PLOTTING.
+
+  * New plotting commands:
+
+      plot            -- 2D plots
+      semilogx        -- 2D semilog plot with logscale on the x axis
+      semilogy        -- 2D semilog plot with logscale on the y axis
+      loglog          -- 2D log-log plot
+      mesh            -- 3D mesh plot
+      meshdom         -- create matrices for 3D plotting from two vectors
+      contour         -- contour plots of 3D data
+      bar             -- create bar graphs
+      stairs          -- create stairstep plots
+      polar           -- 2D plots from theta-R data
+      grid            -- turn plot grid lines on or off
+      xlabel, ylabel  -- place labels on the x and y axes of 2D plots
+      sombrero        -- demonstrate 3D plotting
+      gplot           -- 2D plot command with gnuplot-like syntax
+      gsplot          -- 3D plot command with gnuplot-like syntax
+      set             -- set plot options with gnuplot syntax
+      show            -- show plot options with gnuplot syntax
+      closeplot       -- close stream to gnuplot process
+      purge_tmp_files -- delete temporary files created by plot command
+
+  * Other new commands:
+
+      ls, dir         -- print a directory listing
+      shell_cmd       -- execute shell commands
+      keyboard        -- get input from keyboard, useful for debugging
+      menu            -- display a menu of options and ask for input
+      fft             -- fast fourier transform
+      ifft            -- inverse fast fourier transform
+
+  * Strings may be enclosed in either single or double quote
+    characters.  Double quote characters are not special within single
+    quote strings, and single quotes are not special within double
+    quote strings.
+
+  * Command name completion now works for M-file names too.
+
+  * Better help and usage messages for many functions.
+
+  * Help is now available for functions defined in M-files.  The first
+    block of comments is taken as the text of the help message.
+
+  * Numerous changes in preparation to support dynamic loading of
+    object files with dld.
+
+  * Bug fixes to make solving DAEs with dassl actually work.
+
+  * The command `save file' now saves all variables in the named file.
+
+  * If do_fortran_indexing is 'true', indexing a scalar with
+    [1,1,1,...] (n times) replicates its value n times.  The
+    orientation of the resulting vector depends on the value of
+    prefer_column_vectors.
+
+  * Things like [[1,2][3,4]] no longer cause core dumps, and invalid
+    input like [1,2;3,4,[5,6]] now produces a diagnositic message.
+
+  * The cd, save, and load commands now do tilde expansion.
+
+  * It's now possible to clear global variables and functions by name.
+
+  * Use of clear inside functions is now a parse error.
+
+Summary of changes for version 0.70:
+-----------------------------------
+
+  * Better parse error diagnostics.  For interactive input, you get
+    messages like
+
+      octave:1> a = 3 + * 4;
+
+      parse error:
+
+          a = 3 + * 4;
+                  ^
+
+    and for script files, the message includes the file name and input
+    line number:
+
+      octave:1> foo
+
+      parse error near line 4 of file foo.m:
+
+          a = 3 + * 4;
+                  ^
+
+  * New built-in variable PS2 which is used as the secondary prompt.
+    The default value is '> '.
+
+  * New file, octave-mode.el, for editing Octave code with GNU Emacs.
+    This is a modified version of Matthew R. Wette's matlab-mode.el.
+
+  * Better support for missing math functions.
+
+  * User preferences are now cached in a global struct so we don't
+    have to do a symbol table lookup each time we need to know what
+    they are.  This should mean slightly improved performance for
+    evaluating expressions.
+
+Summary of changes for version 0.69:
+-----------------------------------
+
+  * Multiple assignments are now possible, so statements like
+
+      a = b = c = 3;
+      a = b = c = [1,2;3,4];
+
+    or
+
+      c = (a = (b = 2) * 3 + 4) * 5
+
+    are legal, as are things that have even more bizarre effects, like
+
+      a(4:6,4:6) = b(2:3,2:3) = [1,2;3,4];
+
+    (try it).
+
+  * Improved parsing of strings (but they still don't work as matrix
+    elements).
+
+  * An M-file may now either define a function or be a list of
+    commands to execute.
+
+  * Better detection and conditional compilation of IEEE functions
+    isinf, finite, and isnan.
+
+  * Replacements for acosh, asinh, atanh, and gamma from the BSD math
+    library for those systems that don't have them.
+
+Summary of changes for version 0.68:
+-----------------------------------
+
+  * New functions:
+
+      eval  -- evaluate a string as a sequence of Octave commands. 
+      input -- print a prompt and get user input.
+
+Summary of changes for version 0.67:
+-----------------------------------
+
+  * New functions:
+
+      find -- return the indices of nonzero elements.
+
+  * Zero-one style indexing now works.  For example,
+
+      a = [1,2,3,4];
+      b = a([1,0,0,1])
+
+    sets b to the first and fourth elememnts of a.
+
+    Zero-one style indexing also works for indexing the left hand side
+    of an assignment.  For example,
+
+      a = rand (1,2;3,4);
+      a([0,1],:) = [-1,-2]
+
+    sets the second row of a to [-1 -2]
+
+    The behavior for the ambiguous case
+
+      a = [1,2,3,4];
+      b = a([1,1,1,1]);
+
+    is controlled by the new global variable `prefer_zero_one_indexing'.
+    If this variable is equal to 'true', b will be set to [1 2 3 4].
+    If it is false, b will be set to [1 1 1 1].  The default value is
+    'false'.
+
+  * Using the new global variable `propagate_empty_matrices', it is
+    possible to have unary andy binary operations on empty matrices
+    return an empty matrix.  The default value of this variable is
+    'warn', so that empty matrices are propagated but you get a
+    warning.  Some functions, like eig and svd have also been changed
+    to handle this.
+
+  * Empty matrices can be used in conditionals, but they always
+    evaluate to `false'.  With propagate_empty_matrices = 'true', both
+    of the following expressions print 0: 
+
+      if  [], 1, else 0, end
+      if ~[], 1, else 0, end
+
+  * Octave no longer converts input like `3.2 i' or `3 I' to complex
+    constants directly because that causes problems inside square
+    brackets, where spaces are important.  This abbreviated notation
+    *does* work if there isn't a space between the number and the i,
+    I, j, or J.
+
+Summary of changes for version 0.66:
+-----------------------------------
+
+  * Logical unary not operator (~ or !) now works for complex.
+
+  * Left division works.
+
+  * Right and left element by element division should work correctly
+    now.
+
+  * Numbers like .3e+2 are no longer errors.
+
+  * Indexing a matrix with a complex value doesn't cause a core dump.
+
+  * The min and max functions should work correctly for two arguments.
+
+  * Improved (I hope!) configuration checks.
+
+  * Octave is now installed as octave-M.N, where M and N are version
+    numbers, and octave is a link to that file.  This makes it
+    possible to have more than one version of the interpreter installed.
+
+Summary of changes for version 0.63:
+-----------------------------------
+
+  * The reshape function works again.
+
+  * Octave now converts input like `3.2i' or `3 I' or `2.3e5 j' to be 
+    complex constants directly, rather than requiring an expression
+    like `3.3 * i' to be evaluated.
+
+Summary of changes for version 0.61:
+-----------------------------------
+
+  * Octave has been successfully compiled using gcc 2.3.3 and libg++ 2.3.
+    on a 486 system running Linux.
+
+  * The win_texas_lotto function is now called texas_lotto (it's a
+    script file, and win_texas_lotto.m is too long for some Linux and
+    System V systems).
+
+Summary of changes for version 0.57:
+------------------------------------
+
+  * The C-like formatted print functions printf, fprintf, and sprintf
+    finally work. 
+
+Summary of changes for version 0.56:
+------------------------------------
+
+  * By default, octave prints a short disclaimer when it starts.
+    (You can suppress it by invoking octave with -q).
+
+  * You can keep octave from reading your ~/.octaverc and .octaverc
+    files by invoking it with -f.
+
+  * When returning two values, eig now returns [v, d] instead of
+    [lambda, v], where d is a diagonal matrix made from lambda.
+
+  * The win_texas_lotto function now produces a sorted list.
+
+  * New functions:
+
+      expm -- matrix exponential.
+      logm -- matrix logarithm.
+
+Summary of changes for version 0.55:
+------------------------------------
+
+  * The following (C-style) backslash escape sequences work in quoted
+    strings (useful(?) with printf()):
+
+      \a  bell         \r  carriage return
+      \b  backspace    \t  horizontal tab
+      \f  formfeed     \v  vertical tab
+      \n  newline      \\  backslash
+
+  * Use of `...' at the end of a line will allow a statement to
+    continue over more than one line.
+
+  * The names `inf' and `nan' are now aliases for `Inf' and `NaN',
+    respectively.
+
+  * New functions:
+
+      casesen -- print a warning if the luser tries to turn off case
+                 sensitivity.
+      median  -- find median value.
+      norm    -- compute the norm of a matrix.
+      sort    -- sort columns.
+
+  * New variable, `silent_functions'.  If silent_functions == 'true',
+    the results of expressions are not printed even if they are not
+    followed by a semicolon.  The disp() and printf() functions still
+    result in output.  The default value for this variable is 'false'.
+
+  * New variable `return_last_value_computed'.  If it is 'true',
+    functions defined in script files return the last value computed
+    if a return value has not been explicitly declared.  The default
+    value for this variable is 'false'.
+
+Summary of changes for version 0.52:
+------------------------------------
+
+  * Name completion works for function and variable names currently in
+    the symbol tables.  Coming soon: completion for names of functions
+    defined in script files but not yet compiled. 
+
+  * The initial value of do_fortran_indexing is now false, and the
+    initial value of prefer_column_vectors is now true.  Swap the
+    values of these variables if you want behavior that is more like
+    Matlab.
+
+  * All script files check the number of input arguments before doing
+    much real work.
+
+  * The identifiers `i' and `j' are now also names for sqrt(-1).
+    These symbols may be used for other purposes, but their original
+    definition will reappear if they are cleared.
+
+  * The symbol tables are now implemented with hash tables for faster
+    searching. 
+
+  * A small amount of help is now available for most built-in
+    operators, keywords and functions.  Coming soon: help for script
+    files.
+
+  * Without any arguments, the help command now lists all known
+    built-in operators, keywords and functions.
+
+  * Generic parse errors are now signalled by `Eh, what's up doc?',
+    which is closer to what Bugs actually says.
+
+  * The who command now only prints variable names by default.
+    Use the -fcn (or -fcns, or -functions) switch to print the names of
+    built-in or currently compiled functions.
+
+Summary of changes for version 0.51:
+------------------------------------
+
+  * Major overhaul of array indexing.
+
+  * The colloc function actually works now.
+
+Summary of changes for version 0.50:
+------------------------------------
+
+  * The lsode and dassl functions now return the states only,
+    instead of the time and the states, so you must keep track of
+    the corresponding times (this is easy though, because you have
+    to specify a vector of desired output times anyway).
+
+  * Solution of NLPs with NPSOL now works on the SPARC.
+
+  * New keywords `endif', `endfor', `endfunction', `endif', and
+    `endwhile', which allow for better diagnostics.  The `end' keyword
+    is still recognized.  All script files have been changed to use
+    these new keywords in place of `end'.
+
+  * It is now possible to uninstall Octave by doing a `make uninstall'
+    in the top level directory.
+
+  * The Makefiles are much closer to conforming with GNU coding standards.
+
+  * New functions:
+
+      win_texas_lotto  -- produce six unique random numbers between 1 and 50.
+      quad             -- numerical integration.
+      lu               -- LU factorization
+      qr               -- QR factorization
+      dassl            -- Solution of DAEs using DASSL.
+
+  * New files:
+
+      THANKS -- A list of people and organazations who have supported
+                the development of Octave.
+
+      NEWS   -- This file, listing recent changes.
+
+  * Help is now available at the gnuplot prompt.
diff --git a/NEWS.2 b/NEWS.2
new file mode 100644
index 0000000..4d760f8
--- /dev/null
+++ b/NEWS.2
@@ -0,0 +1,1036 @@
+Summary of changes for version 2.1.x:
+------------------------------------
+
+  * Given a matrix, X, and a boolean index, idx, of the same shape as
+    X, X(idx) and X(idx) = RHS now work no matter what the value of
+    do_fortran_indexing is.
+
+  * If you are using GNU Emacs 19.34 or earlier, you will need to add
+    the following code to your ~/.emacs file in order to use Emacs
+    Octave mode:
+
+      ;; Set up the custom library.
+      ;; taken from http://www.dina.kvl.dk/~abraham/custom/
+      (eval-and-compile
+	(condition-case ()
+	    (require 'custom)
+	  (error nil))
+	(if (and (featurep 'custom) (fboundp 'custom-declare-variable))
+	    nil ;; We've got what we needed
+	  ;; We have the old custom-library, hack around it!
+	  (defmacro defgroup (&rest args)
+	    nil)
+	  (defmacro defcustom (var value doc &rest args) 
+	    (` (defvar (, var) (, value) (, doc))))))
+
+  * When `format +' is in effect, Octave uses the following symbols to
+    provide more information about the values in a matrix:
+
+      +      postive real
+      -      negative real
+      i      pure imaginary
+      c      complex
+      blank  zero
+
+  * The ++ and -- operators now work for indexed matrices, and the
+    following operators now work:
+
+      +=, -=, *=, /=, \=, <<=, >>=, .*=, ./=, .\=, &=, |=
+
+    These operators are currently implemented using a relatively
+    inefficient brute-force method but hey, they work.
+
+  * The built-in variable argv is now a list of strings instead of a
+    string vector.
+
+  * The value of LOADPATH set by the environment variable
+    OCTAVE_PATH, the -p or --path command line options, or on the
+    command line is no longer modified to include the default path.
+    Instead it is left as specified.  Its default value is now ":",
+    which tells Octave to search the default path, and the new
+    built-in variable DEFAULT_LOADPATH contains the default list of
+    directories to search.  
+
+  * The function file_in_path no longer does any special processing of
+    its PATH argument.  To search LOADPATH for files, it is now
+    generally better to use the new function file_in_loadpath.
+
+  * If fread is given a skip parameter, the skip is performed after
+    the read instead of before (for compatibility with Matlab).
+
+  * The new built-in variable `crash_dumps_octave_core' controls
+    whether Octave writes user variables to the file `octave-core'
+    when it crashes or is killed by a signal.  The default value is 1
+    (0 if you use --traditional).
+
+  * If LOADPATH contains a doubled colon, the default path is inserted
+    in its place.  This is similar to the substitution that also takes
+    place for leading or trailing colons in the LOADPATH.
+
+  * Loops of the form `for i = STRING ... endfor' are now allowed.
+
+  * It is now possible to set the iteration limit for lsode using
+    lsode_options ("step limit", N).
+
+  * New functions:
+
+      is_complex  -- tell whether a variable is complex
+      rehash      -- re-initialize the cache of directories in LOADPATH
+      graw        -- send a string to the gnuplot subprocess
+
+  * New functions from Kurt Hornik's Octave-ci package:
+
+    In finance (new directory):
+
+      fv    -- future value of an investment
+      fvl   -- future value of an initial lump sum investment
+      irr   -- internal rate of return of an investment
+      nper  -- number of payments needed for amortizing a loan
+      npv   -- net present value of a series of payments
+      pmt   -- amount of periodic payment needed to amortize a loan
+      pv    -- present value of an investment
+      pvl   -- present value of an investment that pays off at the end
+      rate  -- rate of return of an investment
+      vol   -- volatility of financial time series data
+
+    In linear-algebra:
+
+      dmult -- rescale the rows of a matrix
+
+    In signal:
+
+      arch_fit       -- fit an ARCH regression model
+      arch_rnd       -- simulate an ARCH process
+      arch_test      -- test for conditional heteroscedascity
+      arma_rnd       -- simulate an ARMA process
+      autocor        -- compute autocorrelations
+      autocov        -- compute autocovariances
+      autoreg_matrix -- design matrix for autoregressions
+      bartlett       -- coefficients of the Bartlett (triangular) window
+      blackman       -- coefficients of the Blackman window
+      diffpara       -- estimate the fractional differencing parameter
+      durbinlevinson -- perform one step of the Durbin-Levinson algorithm
+      fractdiff      -- compute fractional differences
+      hamming        -- coefficients of the Hamming window
+      hanning        -- coefficients of the Hanning window
+      hurst          -- estimate the Hurst parameter
+      periodogram    -- compute the periodogram
+      rectangle_lw   -- rectangular lag window
+      rectangle_sw   -- rectangular spectral window
+      sinetone       -- compute a sine tone
+      sinewave       -- compute a sine wave
+      spectral_adf   -- spectral density estimation
+      spectral_xdf   -- spectral density estimation
+      spencer        -- apply Spencer's 15-point MA filter
+      stft           -- short-term Fourier transform
+      synthesis      -- recover a signal from its short-term Fourier transform
+      triangle_lw    -- triangular lag window
+      triangle_sw    -- triangular spectral window
+      yulewalker     -- fit AR model by Yule-Walker method
+
+    In statistics/base (new directory):
+
+      center     -- center by subtracting means
+      cloglog    -- complementary log-log function
+      cor        -- compute correlations
+      cov        -- compute covariances
+      cut        -- cut data into intervals
+      iqr        -- interquartile range
+      kendall    -- kendall's rank correlation tau
+      logit      -- logit transformation
+      mean       -- compute arithmetic, geometric, and harmonic mean
+      meansq     -- compute mean square
+      moment     -- compute moments
+      ppplot     -- perform a PP-plot (probability plot)
+      probit     -- probit transformation
+      qqplot     -- perform a QQ-plot (quantile plot)
+      range      -- compute range
+      ranks      -- compute ranks
+      run_count  -- count upward runs
+      spearman   -- spearman's rank correlation rho
+      statistics -- compute basic statistics
+      studentize -- subtract mean and divide by standard deviation
+      table      -- cross tabulation
+      values     -- extract unique elements
+      var        -- compute variance
+
+    In statistics/distributions (new directory):
+
+      beta_cdf           -- CDF of the Beta distribution
+      beta_inv           -- Quantile function of the Beta distribution
+      beta_pdf           -- PDF of the Beta distribution
+      beta_rnd           -- Random deviates from the Beta distribution
+
+      binomial_cdf       -- CDF of the binomial distribution
+      binomial_inv       -- Quantile function of the binomial distribution
+      binomial_pdf       -- PDF of the binomial distribution
+      binomial_rnd       -- Random deviates from the binomial distribution
+
+      cauchy_cdf         -- CDF of the Cauchy distribution
+      cauchy_inv         -- Quantile function of the Cauchy distribution
+      cauchy_pdf         -- PDF of the Cauchy distribution
+      cauchy_rnd         -- Random deviates from the Cauchy distribution
+
+      chisquare_cdf      -- CDF of the chi-square distribution
+      chisquare_inv      -- Quantile function of the chi-square distribution
+      chisquare_pdf      -- PDF of the chi-sqaure distribution
+      chisquare_rnd      -- Random deviates from the chi-square distribution
+
+      discrete_cdf       -- CDF of a discrete distribution
+      discrete_inv       -- Quantile function of a discrete distribution
+      discrete_pdf       -- PDF of a discrete distribution
+      discrete_rnd       -- Random deviates from a discrete distribution
+
+      empirical_cdf      -- CDF of the empirical distribution
+      empirical_inv      -- Quantile function of the empirical distribution
+      empirical_pdf      -- PDF of the empirical distribution
+      empirical_rnd      -- Bootstrap samples from the empirical distribution
+
+      exponential_cdf    -- CDF of the exponential distribution
+      exponential_inv    -- Quantile function of the exponential distribution
+      exponential_pdf    -- PDF of the exponential distribution
+      exponential_rnd    -- Random deviates from the exponential distribution
+
+      f_cdf              -- CDF of the F distribution
+      f_inv              -- Quantile function of the F distribution
+      f_pdf              -- PDF of the F distribution
+      f_rnd              -- Random deviates from the F distribution
+
+      gamma_cdf          -- CDF of the Gamma distribution
+      gamma_inv          -- Quantile function of the Gamma distribution
+      gamma_pdf          -- PDF of the Gamma distribution
+      gamma_rnd          -- Random deviates from the Gamma distribution
+
+      geometric_cdf      -- CDF of the geometric distribution
+      geometric_inv      -- Quantile function of the geometric distribution
+      geometric_pdf      -- PDF of the geometric distribution
+      geometric_rnd      -- Random deviates from the geometric distribution
+
+      hypergeometric_cdf -- CDF of the hypergeometric distribution
+      hypergeometric_inv -- Random deviates from hypergeometric distribution
+      hypergeometric_pdf -- PDF of the hypergeometric distribution
+      hypergeometric_rnd -- Random deviates from hypergeometric distribution
+
+      kolmogorov_smirnov_cdf -- CDF of the Kolmogorov-Smirnov distribution
+
+      laplace_cdf        -- CDF of the Laplace distribution
+      laplace_inv        -- Quantile function of the Laplace distribution
+      laplace_pdf        -- PDF of the Laplace distribution
+      laplace_rnd        -- Random deviates from the Laplace distribution
+
+      logistic_cdf       -- CDF of the logistic distribution
+      logistic_inv       -- Quantile function of the logistic distribution
+      logistic_pdf       -- PDF of the logistic distribution
+      logistic_rnd       -- Random deviates from the logistic distribution
+
+      lognormal_cdf      -- CDF of the log normal distribution
+      lognormal_inv      -- Quantile function of the log normal distribution
+      lognormal_pdf      -- PDF of the log normal distribution
+      lognormal_rnd      -- Random deviates from the log normal distribution
+
+      normal_cdf         -- CDF of the normal distribution
+      normal_inv         -- Quantile function of the normal distribution
+      normal_pdf         -- PDF of the normal distribution
+      normal_rnd         -- Random deviates from the normal distribution
+
+      pascal_cdf         -- CDF of the Pascal (negative binomial) distribution
+      pascal_inv         -- Quantile function of the Pascal distribution
+      pascal_pdf         -- PDF of the Pascal (negative binomial) distribution
+      pascal_rnd         -- Random deviates from the Pascal distribution
+
+      poisson_cdf        -- CDF of the Poisson distribution
+      poisson_inv        -- Quantile function of the Poisson distribution
+      poisson_pdf        -- PDF of the Poisson distribution
+      poisson_rnd        -- Random deviates from the Poisson distribution
+
+      stdnormal_cdf      -- CDF of the standard normal distribution
+      stdnormal_inv      -- Quantile function of standard normal distribution
+      stdnormal_pdf      -- PDF of the standard normal distribution
+      stdnormal_rnd      -- Random deviates from standard normal distribution
+
+      t_cdf              -- CDF of the t distribution
+      t_inv              -- Quantile function of the t distribution
+      t_pdf              -- PDF of the t distribution
+      t_rnd              -- Random deviates from the t distribution
+
+      uniform_cdf        -- CDF of the uniform distribution
+      uniform_inv        -- Quantile function of the uniform distribution
+      uniform_pdf        -- PDF of the uniform distribution
+      uniform_rnd        -- Random deviates from the uniform distribution
+
+      weibull_cdf        -- CDF of the Weibull distribution
+      weibull_inv        -- Quantile function of the Weibull distribution
+      weibull_pdf        -- PDF of the Weibull distribution
+      weibull_rnd        -- Random deviates from the Weibull distribution
+
+      wiener_rnd         -- Simulate a Wiener process
+
+    In statistics/models (new directory):
+
+      logistic_regression             -- ordinal logistic regression
+      logistic_regression_derivatives -- derivates of log-likelihood
+                                         in logistic regression
+      logistic_regression_likelihood  -- likelihood in logistic regression
+
+    In statistics/tests (new directory):
+
+      anova                       -- one-way analysis of variance
+      bartlett_test               -- bartlett test for homogeneity of variances
+      chisquare_test_homogeneity  -- chi-square test for homogeneity
+      chisquare_test_independence -- chi-square test for independence
+      cor_test                    -- test for zero correlation
+      f_test_regression           -- test linear hypotheses in linear
+                                     regression model
+      hotelling_test              -- test for mean of a multivariate normal
+      hotelling_test_2            -- compare means of two multivariate normals
+      kolmogorov_smirnov_test     -- one-sample Kolmogorov-Smirnov test
+      kolmogorov_smirnov_test_2   -- two-sample Kolmogorov-Smirnov test
+      kruskal_wallis_test         -- kruskal-Wallis test
+      manova                      -- one-way multivariate analysis of variance
+      mcnemar_test                -- mcnemar's test for symmetry
+      prop_test_2                 -- compare two proportions
+      run_test                    -- run test for independence
+      sign_test                   -- sign test
+      t_test                      -- student's one-sample t test 
+      t_test_2                    -- student's two-sample t test
+      t_test_regression           -- test one linear hypothesis in linear
+                                     regression model
+      u_test                      -- mann-Whitney U-test
+      var_test                    -- f test to compare two variances
+      welch_test                  -- welch two-sample t test
+      wilcoxon_test               -- wilcoxon signed-rank test
+      z_test                      -- test for mean of a normal sample with
+                                     known variance
+      z_test_2                    -- compare means of two normal samples with
+                                     known variances
+
+  * The save command now accepts the option -append to save the
+    variables at the end of the file, leaving the existing contents.
+
+  * New command-line option --no-history (also available using the
+    single character option -H) inhibits saving command history.
+
+  * The mkoctfile script now accepts -DDEF options and passes them on
+    to the C and C++ compilers.
+
+  * Running `make check' should work now before you run `make install', 
+    even if you build a copy of Octave that depends on shared versions
+    of the Octave libraries.
+
+  * For matrices, x(:) now works and returns a column vector no matter
+    what the value of do_fortran_indexing is.
+
+  * New keywords __FILE__ and __LINE__ expand to the name of the file
+    that is being read and the current input line number, respectively.
+
+  * Octave's expression parser is more general and consistent.  It is
+    now possible to access structure elements and index arbitrary
+    values.  For example, expressions like
+
+      my_home_dir = getpwuid (getuid ()) . dir;
+
+    and
+
+      svd (x) (1:5)
+
+    now work.
+
+  * New built-in variable `print_rhs_assign_val' controls what is
+    printed when an assignment expression is evaluated.  If it is
+    zero, the value of the variable on the left hand side (after the
+    assignment) is printed.  If it is nonzero, the value of the right
+    hand side (i.e., the result of the expression) is printed.  The
+    default value of is zero, so the behavior is the same as in
+    previous versions of Octave.
+
+  * tmpnam now takes two optional arguments, DIR, and PREFIX.  For
+    example, tmpnam ("/foo", "bar-") returns a file name like
+    "/foo/bar-10773baa".  If DIR is omitted or empty, the value of the
+    environment variable TMPDIR, or /tmp is used.  If PREFIX is 
+    omitted, "oct-" is used.
+
+  * The built-in variable `PWD' has been removed.  If you need to get
+    the value of the current working directory, use the pwd() function
+    instead.
+
+  * New operators.  Octave's parser now recognizes the following
+    operators:  << >> += -= *= /= .+= .-= .*= ./= &= |= <<= >>=.  So
+    far, there are only a few operations defined that actually use
+    them (this should change before 2.1 is released).
+
+  * New built-in data types:
+
+    logical:
+
+      A true value is represented by 1, and false value by 0.
+      Comparison operations like <, <=, ==, >, >=, and != now return
+      logical values.  Indexing operations that use zero-one style
+      indexing must now use logical values.  You can use the new
+      function logical() to convert a numeric value to a logical
+      value.  This avoids the need for the built-in variable
+      `prefer_zero_one_indexing', so it has been removed.  Logical
+      values are automatically converted to numeric values where
+      appropriate.
+
+    file:
+
+      A file object represents an open Octave stream object.  The
+      fopen function now returns a file object instead of an integer.
+      File objects can be converted to integers automatically, and the
+      other functions that work with file ids still work with
+      integers, so this change should be backward compatible.
+
+      The binary left-shift operator `<<' has been defined to work as
+      in C++ for file objects and built-in types.  For example,
+
+        my_stream = fopen ("foo", "w");
+        my_stream << "x = " << pi << " marks the spot\n";
+
+      writes `x = 3.1416 marks the spot' in the file foo.
+
+      The built-in variables stdin, stdout, and stderr are now also
+      file objects instead of integers.
+
+    list:
+
+      A list is an array of Octave objects.  It can be indexed using
+      the normal indexing operator.  For example,
+
+        x = list ([1,2;3,4], 1, "foo");
+        stdout << x(2) << "\n"
+        1
+        stdout << x;
+        (
+         [1] =
+        
+           1  2
+           3  4
+        
+          [2] = 1
+          [3] = foo
+        )
+
+      There is currently no special syntax for creating lists; you
+      must use the list function.
+
+  * Commas in global statements are no longer special.  They are now
+    treated as command separators.  This removes a conflict in the
+    grammar and is consistent with the way Matlab behaves.  The
+    variable `warn_comma_in_global_decl' has been eliminated.
+
+  * It is now possible to declare static variables that retain their
+    values across function calls.  For example,
+
+      function ncall = f () static n = 0; ncall = ++n; endfunction
+
+    defines a function that returns the number of times that it has
+    been called.
+
+  * Within user-defined functions, the new automatic variable `argn'
+    contains the names of the arguments that were passed to the
+    function.  For example,
+
+      function f (...)
+        for i = 1:nargin
+          stdout << "argn(" << i << ") = `" << deblank (argn(i,:)) \
+                 << "' and its value is " << va_arg () << "\n";
+        endfor
+      endfunction
+      f (1+2, "foo", sin (pi/2))
+
+    prints
+
+      argn(1) = `1 + 2' and its value is 3
+      argn(2) = `"foo"' and its value is foo
+      argn(3) = `sin (pi)' and its value is 1
+
+    on the standard output stream.  If nargin is zero, argn is not defined.
+  * Functions like quad, fsolve, and lsode can take either a function
+    name or a simple function body as a string.  For example,
+
+      quad ("sqrt (x)", 0, 1)
+
+    is equivalent to
+
+      function y = f (x) y = sqrt (x); endfunction
+      quad ("f", 0, 1)
+
+  * If the argument to eig() is symmetric, Octave uses the specialized
+    Lapack subroutine for symmetric matrices for a significant
+    increase in performance.
+
+  * If the argument to lsode that names the user-supplied function is
+    a 2-element string array, the second element is taken as the name
+    of the Jacobian function.  The named function should have the
+    following form:
+
+      JAC = f (X, T)
+
+    where JAC is the Jacobian matrix of partial derivatives of the
+    right-hand-side functions that define the set of differential
+    equations with respect to the state vector X.
+
+  * Global variables are now initialized to the empty matrix, for
+    compatibility with Matlab.
+
+  * Explicit initialization of global variables only happens once.
+    For example, after the following statements are evaluated, g still
+    has the value 1.
+
+      global g = 1
+      global g = 2
+
+    This is useful for initializing global variables that are used to
+    maintain state information that is shared among several functions.
+
+  * Structure elements completion on the command line actually works
+    now.
+
+  * The new built-in variable `fixed_point_format' controls whether
+    Octave uses a scaled fixed-point format for displaying matrices.
+    The default value is 0 unless you use --traditional.
+
+  * The function sumsq now computes sum (x .* conj (x)) for complex values.
+
+  * The new built-in variable max_recursion_depth allows you to
+    prevent Octave from attempting infinite recursion.  The default
+    value is 256.
+
+  * Octave now uses kpathsea 3.2.
+
+  * New configure option, --enable-readline.
+
+  * New configure option, --enable-static.
+
+Summary of changes for version 2.0.7:
+------------------------------------
+
+  This is a bug-fixing release.  There are no new user-visible features.
+
+Summary of changes for version 2.0.6:
+------------------------------------
+
+  This is primarily a bug-fixing release.  There are only a few new
+  user-visible features.
+
+  * The new built-in variable default_eval_print_flag controls whether
+    Octave prints the results of commands executed by eval() that do
+    not end with semicolons.  The default is 1.
+
+  * The new built-in constant OCTAVE_HOME specifies the top-level
+    directory where Octave is installed.
+
+  * Octave no longer includes functions to work with NPSOL or QPSOL,
+    because they are not free software.
+
+  * The new built-in variable called kluge_procbuf_delay specifies the
+    number of microseconds to delay in the parent process after
+    forking.  By default on gnu-win32 systems, it's set to 500000 (1/2
+    second).  On other systems, the default value is 0.  Delaying for
+    a short time in the parent after forking seems to avoid problems
+    in which communicating with subprocesses via pipes would sometimes
+    cause Octave to hang.  I doubt that the delay is really the right
+    solution.  If anyone has a better idea, I'd love to hear it.
+
+Summary of changes for version 2.0.5:
+------------------------------------
+
+  * A `switch' statement is now available.  See the Statements chapter
+    in the manual for details.
+
+  * Commands like ls, save, and cd may now also be used as formal
+    parameters for functions.
+
+  * More tests.
+
+Summary of changes for version 2.0.4:
+------------------------------------
+
+  * It is now possible to use commands like ls, save, and cd as simple
+    variable names.  They still cannot be used as formal parameters
+    for functions, or as the names of structure variables.  Failed
+    assignments leave them undefined (you can recover the orginal
+    function definition using clear).
+
+  * Is is now possible to invoke commands like ls, save, and cd as
+    normal functions (for example, load ("foo", "x", "y", "z")).
+
+Summary of changes for version 2.0.3:
+------------------------------------
+
+  * The manual has been completely revised and now corresponds much
+    more closely to the features of the current version.
+
+  * The return value for assignment expressions is now the RHS since
+    that is more consistent with the way other programming languages
+    work.  However, Octave still prints the entire LHS value so that
+
+      x = zeros (1, 2);
+      x(2) = 1
+
+    still prints
+
+      x =
+
+        0  1
+
+    but an assignment like
+
+      z = x(2) = 1
+
+    sets z to 1 (not [ 0, 1 ] as in previous versions of Octave).
+
+  * It is now much easier to make binary distributions.  See the
+    Binary Distributions section of the manual for more details.
+
+Summary of changes for version 2.0.2:
+------------------------------------
+
+  * Octave now stops executing commands from a script file if an error
+    is encountered.
+
+  * The return, and break commands now cause Octave to quit executing
+    commands from script files.  When used in invalid contexts, the
+    break, continue, and return commands are now simply ignored
+    instead of producing parse errors.
+
+  * size ("") is now [0, 0].
+
+  * New functions:
+
+      sleep   -- pause execution for a specified number of seconds
+      usleep  -- pause execution for a specified number of microseconds
+
+Summary of changes for version 2.0:
+----------------------------------
+
+  * The set and show commands for setting and displaying gnuplot
+    parameters have been replaced by gset and gshow.  This change will
+    probably break lots of things, but it is necessary to allow for
+    compatibility with the Matlab graphics and GUI commands in a
+    future version of Octave.  (For now, the old set and show commands
+    do work, but they print an annoying warning message to try to get
+    people to switch to using gset.)
+
+  * Octave has been mostly ported to Windows NT and Windows 95 using
+    the beta 17 release of the Cygnus GNU-WIN32 tools.  Not everything
+    works, but it is usable.  See the file README.WINDOWS for more
+    information.
+
+  * Dynamic linking works on more systems using dlopen() and friends
+    (most modern Unix systems) or shl_load() and friends (HP/UX
+    systems).  A simple example is provided in examples/hello.cc.
+    For this feature to work, you must configure Octave with
+    --enable-shared.  You may also need to have a shared-library
+    version of libg++ and libstdc++.
+
+  * New data types can be added to Octave by writing a C++ class.  On
+    systems that support dynamic linking, new data types can be added
+    to an already running Octave binary.  A simple example appears in
+    the file examples/make_int.cc.  Other examples are the standard
+    Octave data types defined in the files src/ov*.{h,cc} and
+    src/op-*.cc.
+
+  * The configure option --enable-bounds-check turns on bounds
+    checking on element references for Octave's internal array and
+    matrix classes.  It's enabled by default.  To disable this
+    feature, configure Octave with --disable-bounds-check.
+
+  * The C-style I/O functions (fopen, fprintf, etc.) have been
+    rewritten to be more compatible with Matlab.  The fputs function
+    has also been added.  Usage of the *printf functions that was
+    allowed in previous versions of Octave should still work.
+    However, there is no way to make the new versions of the *scanf
+    functions compatible with Matlab *and* previous versions of
+    Octave.  An optional argument to the *scanf functions is now
+    available to make them behave in a way that is compatible with
+    previous versions of Octave.
+
+  * Octave can now read files that contain columns of numbers only,
+    with no header information.  The name of the loaded variable is
+    constructed from the file name.  Each line in the file must have
+    the same number of elements.
+
+  * The interface to the pager has changed.  The new built-in variable
+    `page_output_immediately' controls when Octave sends output to the
+    pager.  If it is nonzero, Octave sends output to the pager as soon
+    as it is available.  Otherwise, Octave buffers its output and
+    waits until just before the prompt is printed to flush it to the
+    pager.
+
+  * Expressions of the form
+
+      A(i,j) = x
+
+    where X is a scalar and the indices i and j define a matrix of
+    elements now work as you would expect rather than giving an error.
+    I am told that this is how Matlab 5.0 will behave when it is
+    released.
+
+  * Indexing of character strings now works.
+
+  * The echo command has been implemented.
+
+  * The document command is now a regular function.
+
+  * New method for handling errors:
+
+      try
+        BODY
+      catch
+        CLEANUP
+      end_try_catch
+
+    Where BODY and CLEANUP are both optional and may contain any
+    Octave expressions or commands.  The statements in CLEANUP are
+    only executed if an error occurs in BODY.
+
+    No warnings or error messages are printed while BODY is
+    executing.  If an error does occur during the execution of BODY,
+    CLEANUP can access the text of the message that would have been
+    printed in the builtin constant __error_text__.  This is the same
+    as eval (TRY, CATCH) (which may now also use __error_text__) but
+    it is more efficient since the commands do not need to be parsed
+    each time the TRY and CATCH statements are evaluated.
+
+  * Octave no longer parses the help command by grabbing everything
+    after the keyword `help' until a newline character is read.  To
+    get help for `;' or `,', now, you need to use the command
+    `help semicolon' or `help comma'.
+
+  * Octave's parser now does some simple constant folding.  This means
+    that expressions like 3*i are now evaluated only once, when a
+    function is compiled, and the right hand side of expressions like
+    a = [1,2;3,4] are treated as true matrix constants rather than
+    lists of elements which must be evaluated each time they are
+    needed.
+
+  * Built-in variables that can take values of "true" and "false" can
+    now also be set to any nonzero scalar value to indicate "true",
+    and 0 to indicate "false".
+
+  * New built-in variables `history_file', `history_size', and
+    `saving_history'.
+
+  * New built-in variable `string_fill_char' specifies the character
+    to fill with when creating arrays of strings.
+
+  * If the new built-in variable `gnuplot_has_frames' is nonzero,
+    Octave assumes that your copy of gnuplot includes support for
+    multiple plot windows when using X11.
+
+    If the new built-in variable `gnuplot_has_multiplot' is nonzero,
+    Octave assumes that your copy of gnuplot has the multiplot support
+    that is included in recent 3.6beta releases.
+
+    The initial values of these variables are determined by configure,
+    but can be changed in your startup script or at the command line
+    in case configure got it wrong, or if you upgrade your gnuplot
+    installation.
+
+  * The new plot function `figure' allows multiple plot windows when
+    using newer versions of gnuplot with X11.
+
+  * Octave now notices when the plotter has exited unexpectedly.
+
+  * New built-in variable `warn_missing_semicolon'.  If nonzero, Octave
+    will warn when statements in function definitions don't end in
+    semicolons.  The default value is 0.
+
+  * Octave now attempts to continue after floating point exceptions
+    or out-of-memory errors.
+
+  * If Octave crashes, it now attempts to save all user-defined
+    variables in a file named `octave-core' in the current directory
+    before exiting.
+
+  * It is now possible to get the values of individual option settings
+    for the dassl, fsolve, lsode, npsol, qpsol, and quad functions
+    using commands like
+
+      dassl_reltol = dassl_options ("relative tolerance");
+
+  * The svd() function no longer computes the left and right singular
+    matrices unnecessarily.  This can significantly improve
+    performance for large matrices if you are just looking for the  
+    singular values.
+
+  * The filter() function is now a built-in function.
+
+  * New function randn() returns a pseudo-random number from a normal
+    distribution.  The rand() and randn() functions have separate
+    seeds and generators.
+
+  * Octave's command-line arguments are now available in the built-in
+    variable `argv'.  The program name is also available in the
+    variables `program_invocation_name' and `program_name'.  If
+    executing a script from the command line (e.g., octave foo.m) or
+    using the `#! /bin/octave' hack, the program name is set to the
+    name of the script.
+
+  * New built-in variable `completion_append_char' used as the
+    character to append to successful command-line completion
+    attempts.  The default is " " (a single space).
+
+  * Octave now uses a modified copy of the readline library from
+    version 1.14.5 of GNU bash.
+
+  * In prompt strings, `\H' expands to the whole host name.
+
+  * New built-in variable `beep_on_error'.  If nonzero, Octave will try
+    to ring your terminal's bell before printing an error message.
+    The default value is 0.
+
+  * For functions defined from files, the type command now prints the
+    text of the file.  You can still get the text reconstructed from
+    the parse tree by using the new option -t (-transformed).
+
+  * New command-line argument --traditional sets the following
+    preference variables for compatibility with Matlab:
+
+      PS1                           = ">> "
+      PS2                           = ""
+      beep_on_error                 = 1
+      default_save_format           = "mat-binary"
+      define_all_return_values      = 1
+      do_fortran_indexing           = 1
+      empty_list_elements_ok        = 1
+      implicit_str_to_num_ok        = 1
+      ok_to_lose_imaginary_part     = 1
+      page_screen_output            = 0
+      prefer_column_vectors         = 0
+      prefer_zero_one_indexing      = 1
+      print_empty_dimensions        = 0
+      treat_neg_dim_as_zero         = 1
+      warn_function_name_clash      = 0
+      whitespace_in_literal_matrix  = "traditional"
+
+  * New functions:
+
+      readdir  -- returns names of files in directory as array of strings
+      mkdir    -- create a directory
+      rmdir    -- remove a directory
+      rename   -- rename a file
+      unlink   -- delete a file
+      umask    -- set permission mask for file creation
+      stat     -- get information about a file
+      lstat    -- get information about a symbolic link
+      glob     -- perform filename globbing
+      fnmatch  -- match strings with filename globbing patterns
+      more     -- turn the pager on or off
+      gammaln  -- alias for lgamma
+
+  * New audio functions from Andreas Weingessel
+    <Andreas.Weingessel at ci.tuwien.ac.at>.
+
+      lin2mu     -- linear to mu-law encoding
+      loadaudio  -- load an audio file to a vector
+      mu2lin     -- mu-law to linear encoding
+      playaudio  -- play an audio file
+      record     -- record sound and store in vector
+      saveaudio  -- save a vector as an audio file
+      setaudio   -- executes mixer shell command
+
+  * New plotting functions from Vinayak Dutt.  Ones dealing with
+    multiple plots on one page require features from gnuplot 3.6beta
+    (or later).
+
+      bottom_title  -- put title at the bottom of the plot
+      mplot         -- multiplot version of plot
+      multiplot     -- switch multiple-plot mode on or off
+      oneplot       -- return to one plot per page
+      plot_border   -- put a border around plots
+      subplot       -- position multiple plots on a single page
+      subwindow     -- set subwindow position for next plot
+      top_title     -- put title at the top of the plot
+      zlabel        -- put a label on the z-axis
+
+  * New string functions
+
+      bin2dec  -- convert a string of ones and zeros to an integer
+      blanks   -- create a string of blanks
+      deblank  -- delete trailing blanks
+      dec2bin  -- convert an integer to a string of ones and zeros
+      dec2hex  -- convert an integer to a hexadecimal string
+      findstr  -- locate occurrences of one string in another
+      hex2dec  -- convert a hexadecimal string to an integer
+      index    -- return position of first occurrence a string in another
+      rindex   -- return position of last occurrence a string in another
+      split    -- divide one string into pieces separated by another
+      str2mat  -- create a string matrix from a list of strings
+      strrep   -- replace substrings in a string
+      substr   -- extract a substring
+
+    The following functions return a matrix of ones and zeros.
+    Elements that are nonzero indicate that the condition was true for
+    the corresponding character in the string array.
+
+      isalnum   -- letter or a digit
+      isalpha   -- letter
+      isascii   -- ascii
+      iscntrl   -- control character
+      isdigit   -- digit
+      isgraph   -- printable (but not space character)
+      islower   -- lower case
+      isprint   -- printable (including space character)
+      ispunct   -- punctuation
+      isspace   -- whitespace
+      isupper   -- upper case
+      isxdigit  -- hexadecimal digit
+
+    These functions return new strings.
+
+      tolower  -- convert to lower case
+      toupper  -- convert to upper case
+
+  * New function, fgetl.  Both fgetl and fgets accept an optional
+    second argument that specifies a maximum number of characters to
+    read, and the function fgets is now compatible with Matlab.
+
+  * Printing in hexadecimal format now works (format hex).  It is also
+    possible to print the internal bit representation of a value
+    (format bit).  Note that these formats are only implemented for
+    numeric values.
+
+  * Additional structure features:
+
+    -- Name completion now works for structures.
+
+    -- Values and names of structure elements are now printed by
+       default.  The new built-in variable `struct_levels_to_print'
+       controls the depth of nested structures to print.  The default
+       value is 2.
+
+    -- New functions:
+
+       struct_contains (S, NAME) -- returns 1 if S is a structure with
+                                    element NAME; otherwise returns 0.
+
+       struct_elements (S)       -- returns the names of all elements
+                                    of structure S in an array of strings. 
+
+  * New io/subprocess functions:
+
+      fputs    -- write a string to a file with no formatting
+      popen2   -- start a subprocess with 2-way communication
+      mkfifo   -- create a FIFO special file
+      popen    -- open a pipe to a subprocess
+      pclose   -- close a pipe from a subprocess
+      waitpid  -- check the status of or wait for subprocesses
+
+  * New time functions:
+
+      asctime    -- format time structure according to local format
+      ctime      -- equivalent to `asctime (localtime (TMSTRUCT))'
+      gmtime     -- return time structure corresponding to UTC
+      localtime  -- return time structure corresponding to local time zone
+      strftime   -- print given time structure using specified format
+      time       -- return current time
+
+    The `clock' and `date' functions are now implemented in M-files
+    using these basic functions.
+
+  * Access to additional Unix system calls:
+
+      dup2     -- duplicate a file descriptor
+      exec     -- replace current process with a new process
+      fcntl    -- control open file descriptors
+      fork     -- create a copy of the current process
+      getpgrp  -- return the process group id of the current process
+      getpid   -- return the process id of the current process
+      getppid  -- return the process id of the parent process
+      getuid   -- return the real user id of the current process
+      getgid   -- return the real group id of the current process
+      geteuid  -- return the effective user id of the current process
+      getegid  -- return the effective group id of the current process
+      pipe     -- create an interprocess channel
+
+  * Other new functions:
+
+      commutation_matrix  -- compute special matrix form
+      duplication_matrix  -- compute special matrix form
+      common_size.m       -- bring arguments to a common size
+      completion_matches  -- perform command completion on string
+      tilde_expand        -- perform tilde expansion on string
+
+      meshgrid  -- compatible with Matlab's meshgrid function
+      tmpnam    -- replaces octave_tmp_file_name
+      atexit    -- register functions to be called when Octave exits
+      putenv    -- define an environment variable
+      bincoeff  -- compute binomial coefficients
+      nextpow2  -- compute the next power of 2 greater than a number
+      detrend   -- remove a best fit polynomial from data
+      erfinv    -- inverse error function
+      shift     -- perform a circular shift on the elements of a matrix
+      pow2      -- compute 2 .^ x
+      log2      -- compute base 2 logarithms
+      diff      -- compute differences of matrix elements
+      vech      -- stack columns of a matrix below the diagonal
+      vec       -- stack columns of a matrix to form a vector
+      xor       -- compute exclusive or
+
+  * Functions for getting info from the password database on Unix systems:
+
+      getpwent  -- read entry from password-file stream, opening if necessary
+      getpwuid  -- search for password entry with matching user ID
+      getpwnam  -- search for password entry with matching username
+      setpwent  -- rewind the password-file stream
+      endpwent  -- close the password-file stream
+
+  * Functions for getting info from the group database on Unix systems:
+
+      getgrent  -- read entry from group-file stream, opening if necessary
+      getgrgid  -- search for group entry with matching group ID
+      getgrnam  -- search for group entry with matching group name
+      setgrent  -- rewind the pgroup-file stream
+      endgrent  -- close the group-file stream
+
+  * The New function octave_config_info returns a structure containing
+    information about how Octave was configured and compiled.
+
+  * New function getrusage returns a structure containing system
+    resource usage statistics.  The `cputime' function is now defined
+    in an M-file using getrusage.
+
+  * The info reader is now a separate binary that runs as a
+    subprocess.  You still need the info reader distributed with
+    Octave though, because there are some new command-line arguments
+    that are not yet available in the public release of Info.
+
+  * There is a new built-in variable, INFO_PROGRAM, which is used as
+    the name of the info program to run.  Its initial value is
+    $OCTAVE_HOME/lib/octave/VERSION/exec/ARCH/info, but that value can
+    be overridden by the environment variable OCTAVE_INFO_PROGRAM, or
+    the command line argument --info-program NAME, or by setting the
+    value of INFO_PROGRAM in a startup script.
+
+  * There is a new built-in variable, EXEC_PATH, which is used as
+    the list of directories to search when executing subprograms.  Its
+    initial value is taken from the environment variable
+    OCTAVE_EXEC_PATH (if it exists) or PATH, but that value can be
+    overridden by the command line argument --exec-path PATH, or
+    by setting the value of EXEC_PATH in a startup script.  If the
+    EXEC_PATH begins (ends) with a colon, the directories
+    $OCTAVE_HOME/lib/octave/VERSION/exec/ARCH and $OCTAVE_HOME/bin are
+    prepended (appended) to EXEC_PATH (if you don't specify a value
+    for EXEC_PATH explicitly, these special directories are prepended
+    to your PATH).
+
+  * If it is present, Octave will now use an `ls-R' database file to
+    speed up recursive path searching.  Octave looks for a file called
+    ls-R in the directory specified by the environment variable
+    OCTAVE_DB_DIR.  If that is not set but the environment variable
+    OCTAVE_HOME is set, Octave looks in $OCTAVE_HOME/lib/octave.
+    Otherwise, Octave looks in the directory $datadir/octave (normally
+    /usr/local/lib/octave).
+
+  * New examples directory.
+
+  * There is a new script, mkoctfile, that can be used to create .oct
+    files suitable for dynamic linking.
+
+  * Many more bug fixes.
+
+  * ChangeLogs are now kept in each subdirectory.
+
+See NEWS.1 for old news.
diff --git a/NEWS.3 b/NEWS.3
new file mode 100644
index 0000000..f74f3f4
--- /dev/null
+++ b/NEWS.3
@@ -0,0 +1,200 @@
+Summary of important user-visible changes for version 3.0:
+---------------------------------------------------------
+
+ ** Compatibility with Matlab graphics is much better now.  We now
+    have some graphics features that work like Matlab's Handle
+    Graphics (tm):
+
+    + You can make a subplot and then use the print function to
+      generate a file with the plot.
+
+    + RGB line colors are supported if you use gnuplot 4.2.  Octave
+      can still use gnuplot 4.0, but there is no way to set arbitrary
+      line colors with it when using the Matlab-style plot functions.
+      There never was any way to do this reliably with older versions
+      of gnuplot (whether run from Octave or not) since it only
+      provided a limited set to choose from, and they were terminal
+      dependent, so choosing color 1 with the X11 terminal would be
+      different from color 1 with the PostScript terminal.  Valid RGB
+      colors for gnuplot 4.0 are the eight possible combinations of 0
+      and 1 for the R, G and B values. Invalid values are all mapped
+      to the same color.
+
+      This also affects patch objects used in the bar, countour, meshc
+      and surfc functions, where the bars and contours will be
+      monochrome. A workaround for this is to type "colormap gmap40"
+      that loads a colormap that in many cases will be adequate for
+      simple bar and contour plots.
+
+    + You can control the width of lines using (for example):
+
+	line (x, y, "linewidth", 4, "color", [1, 0, 0.5]);
+
+      (this also shows the color feature).
+
+    + With gnuplot 4.2, image data is plotted with gnuplot and may be
+      combined with other 2-d plot data.
+
+    + Lines for contour plots are generated with an Octave function, so
+      contour plots are now 2-d plots instead of special 3-d plots, and
+      this allows you to plot additional 2-d data on top of a contour
+      plot.
+
+    + With the gnuplot "extended" terminals the TeX interpreter is
+    emulated. However, this means that the TeX interpreter is only
+    supported on the postscript terminals with gnuplot 4.0. Under
+    gnuplot 4.2 the terminals aqua, dumb, png, jpeg, gif, pm, windows,
+    wxt, svg and x11 are supported as well.
+
+    + The following plot commands are now considered obsolete and will
+      be removed from a future version of Octave:
+
+	__gnuplot_set__
+	__gnuplot_show__
+	__gnuplot_plot__
+	__gnuplot_splot__
+	__gnuplot_replot__
+
+      Additionally, these functions no longer have any effect on plots
+      created with the Matlab-style plot commands (plot, line, mesh,
+      semilogx, etc.).
+
+    + Plot property values are not extensively checked.  Specifying
+      invalid property values may produce unpredictible results.
+
+    + Octave now sends data over the same pipe that is used to send
+      commands to gnuplot.  While this avoids the problem of
+      cluttering /tmp with data files, it is no longer possible to use
+      the mouse to zoom in on plots.  This is a limitation of gnuplot,
+      which is unable to zoom when the data it plots is not stored in
+      a file.  Some work has been done to fix this problem in newer
+      versions of gnuplot (> 4.2.2).  See for example, this thread
+
+        http://www.nabble.com/zooming-of-inline-data-tf4357017.html#a12416496
+
+      on the gnuplot development list.
+
+
+ ** The way Octave handles search paths has changed.  Instead of
+    setting the built-in variable LOADPATH, you must use addpath,
+    rmpath, or path to manipulate the function search path.  These
+    functions will maintain "." at the head of the path, for
+    compatibility with Matlab.
+
+    Leading, trailing or doubled colons are no longer special.
+    Now, all elements of the search path are explicitly included in
+    the path when Octave starts.  To display the path, use the path
+    function.
+
+    Path elements that end in // are no longer searched recursively.
+    Instead, you may use addpath and the genpath function to add an
+    entire directory tree to the path.  For example,
+
+      addpath (genpath ("~/octave"));
+
+    will add ~/octave and all directories below it to the head of the
+    path.
+
+
+ ** Previous versions of Octave had a number of built-in variables to
+    control warnings (for example, warn_divide_by_zero).  These
+    variables have been replaced by warning identifiers that are used
+    with the warning function to control the state of warnings.
+
+    For example, instead of writing
+
+      warn_divide_by_zero = false;
+
+    to disable divide-by-zero warnings, you should write
+
+      warning ("off", "Octave:divide-by-zero");
+
+    You may use the same technique in your own code to control
+    warnings.  For example, you can use
+
+      warning ("My-package:phase-of-the-moon",
+               "the phase of the moon could cause trouble today");
+
+    to allow users to control this warning using the
+    "My-package:phase-of-the-moon" warning identifier.
+
+    You may also enable or disable all warnings, or turn them into
+    errors:
+
+      warning ("on", "all");
+      warning ("off", "all");
+      warning ("error", "Octave:divide-by-zero");
+      warning ("error", "all");
+
+    You can query the state of current warnings using
+
+      warning ("query", ID)
+      warning ("query")
+
+    (only those warning IDs which have been explicitly set are
+    returned).
+
+    A partial list and description of warning identifiers is available
+    using
+
+      help warning_ids
+
+
+ ** All built-in variables have been converted to functions.  This
+    change simplifies the interpreter and allows a consistent
+    interface to internal variables for user-defined packages and the
+    core functions distributed with Octave.  In most cases, code that
+    simply accesses internal variables does not need to change.  Code
+    that sets internal variables will change.  For example, instead of
+    writing
+
+      PS1 = ">> ";
+
+    you will need to write
+
+      PS1 (">> ");
+
+    If you need write code that will run in both old and new versions
+    of Octave, you can use something like
+
+      if (exist ("OCTAVE_VERSION") == 5)
+        ## New:
+        PS1 (">> ");
+      else
+        ## Old:
+        PS1 = ">> ";
+      endif
+
+
+ ** For compatibility with Matlab, the output order of Octave's
+    "system" function has changed from
+
+      [output, status] = system (cmd);
+
+    to
+
+      [status, output] = system (cmd);
+
+
+ ** For compatibility with Matlab, the output of Octave's fsolve
+    function has been changed from
+
+      [x, info, msg] = fsolve (...);
+
+    to
+
+      [x, fval, info] = fsolve (...);
+
+
+ ** For compatibility with Matlab, normcdf, norminv, normpdf, and
+    normrnd have been modified to compute distributions using the
+    standard deviation instead of the variance.
+
+
+ ** For compatibility with Matlab, gamcdf, gaminv, gampdf, gamrnd,
+    expcdf, expinv, exppdf and exprnd have been modified to compute 
+    the distributions using the standard scale factor rather than
+    one over the scale factor.
+
+
+See NEWS.2 for old news.
diff --git a/PROJECTS b/PROJECTS
new file mode 100644
index 0000000..3a6d7e8
--- /dev/null
+++ b/PROJECTS
@@ -0,0 +1,463 @@
+<html>
+<pre>
+Octave PROJECTS                                          -*- text -*-
+===============
+
+Look in the Octave source archive on Savannah for a possibly more
+current copy.  Also, if you start working steadily on a project,
+please let maintainers at octave.org know.  We might have information
+that could help you.  You should also read the Contributing Guidelines
+chapter in the Octave manual.
+
+This list is not exclusive -- there are many other things that might
+be good projects, but it might instead be something we already have.
+Also, some of the following items may not actually be considered good
+ideas now.  So please check with maintainers at octave.org before you
+start working on some large project.
+
+
+---------
+Numerical:
+---------
+
+  * Improve logm, and sqrtm.
+
+  * Improve complex mapper functions.  See W. Kahan, ``Branch Cuts for
+    Complex Elementary Functions, or Much Ado About Nothing's Sign
+    Bit'' (in The State of the Art in Numerical Analysis, eds. Iserles
+    and Powell, Clarendon Press, Oxford, 1987) for explicit
+    trigonometric formulae.
+
+  * Make functions like gamma() return the right IEEE Inf or NaN
+    values for extreme args or other undefined cases.
+
+  * Improve sqp.
+
+  * Fix CollocWt to handle Laguerre polynomials.  Make it easy to
+    extend it to other polynomial types.
+
+  * Add optional arguments to colloc so that it's not restricted to
+    Legendre polynomials.
+
+  * Fix eig to also be able to solve the generalized eigenvalue
+    problem, and to solve for eigenvalues and eigenvectors without
+    performing a balancing step first.
+
+  * Move rand, eye, xpow, xdiv, etc., functions to the matrix classes.
+
+  * Use octave_allocator for memory management in Array classes once
+    g++ supports static member templates.
+
+  * Improve design of ODE, DAE, classes.
+
+  * Make QR more memory efficient for large matrices when not all the
+    columns of Q are required (apparently this is not handled by the
+    lapack code yet).
+
+---------------
+Sparse Matrices:
+---------------
+
+  * Improve QR factorization functions, using idea based on CSPARSE
+    cs_dmsol.m 
+
+  * Implement fourth argument to the sprand and sprandn, and addition
+    arguments to sprandsym that the leading brand implements.
+
+  * Sparse logical indexing in idx_vector class so that something like
+    "a=sprandn(1e6,1e6,1e-6); a(a<1) = 0" won't cause a memory overflow.
+
+  * Make spalloc (r, c, n) actually create an empty sparse with n
+    non-zero elements?  This allows something like
+
+    sm = spalloc (r, c, n)
+    for j=1:c
+      for i=1:r
+        tmp = foo (i,j);
+        if (tmp != 0.)
+          sm (i,j) = tmp;
+        endif
+      endfor
+    endfor
+
+    actually make sense.  Otherwise the above will cause massive amounts
+    of memory reallocation.
+
+    The fact is that this doesn't make sense in any case as the assign
+    function makes another copy of the sparse matrix.  So although spalloc
+    might easily be made to have the correct behavior, the first assign
+    will cause the matrix to be resized!  There seems to be no simple
+    way to treat this but a complete rewrite of the sparse assignment
+    functions...
+
+  * Other missing Functions
+      - symmmd      Superseded by symamd
+      - colmmd      Superseded by colamd
+      - cholinc
+      - bicg        Can this be taken from octave-forge?
+      - cgs
+      - gmres
+      - lsqr
+      - minres
+      - qmr
+      - symmlq 
+
+-------
+Strings:
+-------
+
+  * Improve performance of string functions, particularly for
+    searching and replacing.
+
+  * Make find work for strings.
+
+  * Consider making octave_print_internal() print some sort of text
+    representation for unprintable characters instead of sending them
+    directly to the terminal.  (But don't do this for fprintf!)
+
+  * Consider changing the default value of `string_fill_char' from SPC
+    to NUL.
+
+----------------
+Other Data Types:
+----------------
+
+  * Template functions for mixed-type ops.
+
+  * Convert other functions for use with the floating point type
+    including quad, dasrt, daspk, etc.
+
+------------
+Input/Output:
+------------
+
+  * Make fread and fwrite work for complex data.  Iostreams based
+    versions of these functions would also be nice, and if you are
+    working on them, it would be good to support other size
+    specifications (integer*2, etc.).
+
+  * Move some pr-output stuff to liboctave.
+
+  * Make the cutoff point for changing to packed storage a
+    user-preference variable with default value 8192.
+
+  * Complain if there is not enough disk space available (I think
+    there is simply not enough error checking in the code that handles
+    writing data).
+
+  * Make it possible to tie arbitrary input and output streams
+    together, similar to the way iostreams can be tied together.
+
+-----------
+Interpreter:
+-----------
+
+  * Allow customization of the debug prompt.
+
+  * Fix the parser so that
+
+      if (expr) 'this is a string' end
+
+    is parsed as IF expr STRING END.
+
+  * Clean up functions in input.cc that handle user input (there
+    currently seems to be some unnecessary duplication of code and it
+    seems overly complex).
+
+  * Consider allowing an arbitrary property list to be attached to any
+    variable.  This could be a more general way to handle the help
+    string that can currently be added with `document'.
+
+  * Allow more command line options to be accessible as built-in
+    variables (--echo-commands, etc.).
+
+  * Make the interpreter run faster.
+
+  * Allow arbitrary lower bounds for array indexing.
+
+  * Improve performance of recursive function calls.
+
+  * Improve the way ignore_function_time_stamp works to allow
+    selecting by individual directories or functions.
+
+  * Add a command-line option to tell Octave to just do syntax
+    checking and not execute statements.
+
+  * Clean up symtab and variable stuff.
+
+  * Input stream class for parser files -- must manage buffers for
+    flex and context for global variable settings.
+
+  * make parser do more semantic checking, continue after errors when
+    compiling functions, etc.
+
+  * Make LEXICAL_ERROR have a value that is the error message for
+    parse_error() to print?
+
+  * Add a run-time alias mechanism that would allow things like
+
+      alias fun function_with_a_very_long_name 
+
+    so that `function_with_a_very_long_name' could be invoked as
+    `fun'.
+
+  * Allow local changes to variables to be written more compactly than
+    is currently possible with unwind_protect.  For example,
+
+      function f ()
+	local prefer_column_vectors = something;
+	...
+      endfunction
+
+    would be equivalent to
+
+      function f ()
+        save_prefer_column_vectors = prefer_column_vectors;
+	unwind_protect
+	  prefer_column_vectors = something;
+	  ...
+	unwind_protect_cleanup
+	  prefer_column_vectors = save_prefer_column_vectors;
+	end_unwind_protect
+      endfunction
+
+  * Fix all function files to check for bogus inputs (wrong number or
+    types of input arguments, wrong number of output arguments).
+
+  * Handle options for built-in functions more consistently.
+
+  * Too much time is spent allocating and freeing memory.  What can be
+    done to improve performance?
+
+  * Error output from Fortran code is ugly.  Something should be done to
+    make it look better.
+
+  * It would be nice if output from the Fortran routines could be
+    passed through the pager.
+
+  * Attempt to recognize common subexpressions in the parser.
+
+  * Consider making it possible to specify an empty matrix with a
+    syntax like [](e1, e2).  Of course at least one of the expressions
+    must be zero...
+
+  * Is Matrix::fortran_vec() really necessary?
+
+  * Rewrite whos and the symbol_record_info class.  Write a built-in
+    function that gives all the basic information, then write who and
+    whos as M-files.
+
+  * On systems that support matherr(), make it possible for users to
+    enable the printing of warning messages.
+
+  * Make it possible to mark variables and functions as read-only.
+
+  * Make it possible to write a function that gets a reference to a
+    matrix in memory and change one or more elements without
+    generating a second copy of the data.
+
+  * Use nanosleep instead of usleep if it is available?  Apparently
+    nanosleep is to be preferred over usleep on Solaris systems.
+
+--------
+Graphics:
+--------
+
+  * Correctly handle case where DISPLAY is unset.  Provide
+  --no-window-system or --nodisplay (?) option.  Provide
+  --display=DISPLAY option?  How will this work with gnuplot (i.e.,
+  how do we know whether gnuplot requires an X display to display
+  graphics)?
+
+-------
+History:
+-------
+
+  * Add an option to allow saving input from script files in the
+    history list.
+
+  * The history command should accept two numeric arguments to
+    indicate a range of history entries to display, save or read.
+
+  * Avoid writing the history file if the history list has not
+    changed.
+
+  * Avoid permission errors if the history file cannot be opened for
+    writing.
+
+  * Fix history problems -- core dump if multiple processes are
+    writing to the same history file?
+
+------------------------------
+Configuration and Installation:
+------------------------------
+
+  * Split config.h into a part for Octave-specific configuration
+  things (this part can be installed) and the generic HAVE_X type of
+  configure information that should not be installed.
+
+  * Makefile changes:
+      -- eliminate for loops
+      -- define shell commands or eliminate them
+      -- consolidate targets
+
+  * Make it possible to configure so that installed binaries and
+    shared libraries are stripped.
+
+  * Create a docs-only distribution?
+
+------------------------------
+Documentation and On-Line Help:
+------------------------------
+
+  * Document new features.
+
+  * Improve the Texinfo Documentation for the interpreter.  It would
+    be useful to have lots more examples, to not have so many forward
+    references, and to not have very many simple lists of functions.
+
+  * The docs should mention something about efficiency and that using
+    array operations is almost always a good idea for speed.
+
+  * Texinfo documentation for the C++ classes.
+
+  * Make index entries more consistent to improve behavior of `help -i'.
+
+  * Make `help -i' try to find a whole word match first.
+
+  * Clean up help stuff.
+
+  * Demo files.
+
+-----
+Tests:
+-----
+
+  * Improved set of tests:
+
+      -- Tests for various functions.  Would be nice to have a test file
+	 corresponding to every function.
+
+      -- Tests for element by element operators:
+	   +  -  .*  ./  .\  .^  |  &  <  <=  ==  >=  >  !=  ! 
+
+      -- Tests for boolean operators:  &&  ||
+
+      -- Tests for other operators:  *  /  \  '  .'
+
+      -- Tests from bug reports.
+
+      -- Tests for indexed assignment.  Need to consider the following:
+	   o fortran-style indexing
+	   o zero-one indexing
+	   o assignment of empty matrix as well as values
+	   o resizing
+
+  * Tests for all internal functions.
+
+-----------
+Programming:
+-----------
+
+  * C++ namespace for Octave library functions.
+
+  * Better error messages for missing operators?
+
+  * Eliminate duplicate enums in pt-exp.cc, pt-const.cc, and ov.cc.
+
+  * Handle octave_print_internal() stuff at the liboctave level.  Then
+    the octave_value classes could just call on the print() methods
+    for the underlying classes.
+
+  * As much as possible, eliminate explicit checks for the types of
+    octave_value objects so that user-defined types will automatically
+    do the right thing in more cases.
+
+  * Only include config.h in files that actually need it, instead of
+    including it in every .cc file.  Unfortunately, this might not be
+    so easy to figure out.
+
+  * GNU coding standards:
+
+    -- Add a `Makefile' target to the Makefiles.
+    -- Comments on #else and #endif preprocessor commands.
+    -- Change error message format to match standards everywhere.
+
+  * Eliminate more global variables.
+
+  * Move procstream to liboctave.
+
+  * Use references and classes in more places.
+
+  * Share more code among the various *_options functions.
+
+-------------
+Miscellaneous:
+-------------
+
+  * Implement some functions for interprocess communication:  bind,
+    accept, connect, gethostbyname, etc.
+
+  * The installation process should also install octave.el.  This
+    needs to detect the appropriate Emacs binary to use to
+    byte-compile the .el file.  Following GNU Emacs philosophy,
+    installation would be into $(prefix)/share/emacs/site-lisp by
+    default, but it should be selectable.
+
+  * The ability to transparently handle very large files:
+
+    Juhana K Kouhia <kouhia at nic.funet.fi> wrote:
+
+      If I have a one-dimensional signal data with the size 400
+      Mbytes, then what are my choices to operate with it:
+
+       * I have to split the data
+       * Octave has a virtual memory on its own and I don't have to
+         worry about the splitting.
+
+      If I split the data, then my easily programmed processing
+      programs will become hard to program.
+
+      If possible, I would like to have the virtual memory system in
+      Octave i.e., the all big files, the user see as one big array or
+      such.  There could be several user selectable models to do the
+      virtual memory depending on what kind of data the user have (1d,
+      2d) and in what order they are processed (stream or random
+      access).
+
+    Perhaps this can be done entirely with a library of M-files.
+
+  * An interface to gdb.
+
+    Michael Smolsky <fnsiguc at weizmann.weizmann.ac.il> wrote:
+
+      I was thinking about a tool, which could be very useful for me
+      in my numerical simulation work.  It is an interconnection
+      between gdb and octave.  We are often managing very large arrays
+      of data in our fortran or c codes, which might be studied with
+      the help of octave at the algorithm development stages.  Assume
+      you're coding, say, wave equation.  And want to debug the
+      code.  It would be great to pick some array from the memory of
+      the code you're developing, fft it and see the image as a
+      log-log plot of the spectral density.  I'm facing similar
+      problems now.  To avoid high c-development cost, I develop in
+      matlab/octave, and then rewrite into c.  It might be so much
+      easier, if I could off-load a c array right from the debugger
+      into octave, study it, and, perhaps, change some [many] values
+      with a convenient matlab/octave syntax, similar to
+      a(:,50:250)=zeros(100,200), and then store it back into the
+      memory of my c code.
+
+  * Add a definition to lgrind so that it supports Octave.
+    (See http://www.tex.ac.uk/tex-archive/support/lgrind/ for more
+    information about lgrind.)
+
+------
+Always:
+------
+
+  * Squash bugs.
+
+				--30--
+</pre>
+</html>
diff --git a/README b/README
new file mode 100644
index 0000000..99df222
--- /dev/null
+++ b/README
@@ -0,0 +1,76 @@
+GNU Octave -- a high-level language for numerical computations.
+
+Copyright (C) 1996, 1997, 1998, 2002, 2007, 2009 John W. Eaton
+
+Overview
+--------
+
+GNU Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient command line interface for
+solving linear and nonlinear problems numerically.
+
+GNU Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the file
+COPYING for more details.
+
+Availability
+------------
+
+The latest released version of Octave is always available via
+anonymous ftp from ftp.gnu.org and its many mirror sites around the
+world.  You may also find links to binary distributions at
+http://www.octave.org/download.html.  The current development sources
+may be found on Savannah (http://savannah.gnu.org).
+
+Installation and Bugs
+---------------------
+
+Octave requires approximately 1.5GB of disk storage to unpack and
+compile from source (significantly less if you don't compile with
+debugging symbols).  Once installed, Octave requires approximately
+450MB of disk space (again, considerably less if you don't build
+shared libraries or the binaries and libraries do not include
+debugging symbols).
+
+To compile Octave, you will need a recent version of GNU Make.  You
+will also need a recent version of g++ or another ANSI C++ compiler.
+You will also need a Fortran 77 compiler or f2c.  If you use f2c, you
+will need a script like fort77 that works like a normal Fortran
+compiler by combining f2c with your C compiler in a single script.
+
+YOU MUST HAVE GNU MAKE TO COMPILE OCTAVE.  Octave's Makefiles use
+features of GNU Make that are not present in other versions of make.
+GNU Make is very portable and easy to install.
+
+See the notes in the files INSTALL and INSTALL.OCTAVE for more
+specific installation instructions, including directions for
+installing Octave from a binary distribution.
+
+The file BUGS explains the recommended procedure for reporting bugs.
+
+Documentation
+-------------
+
+Octave's manual has been revised for version 3.0, but it is lagging a
+bit behind the development of the software.  In particular, there is
+currently no complete documentation of the C++ class libraries.  If
+you notice omissions or inconsistencies, please report them as bugs
+to bug at octave.org.  Specific suggestions for ways to improve Octave
+and its documentation are always welcome.  Reports with patches are
+even more welcome.
+
+Additional Information
+----------------------
+
+Up to date information about Octave is available on the WWW at the
+URL http://www.octave.org, including archives of the help, bug, and
+maintainers mailing lists.
+
+
+Last updated: Sat, 07 Mar 2009 11:18:14 EST
diff --git a/README.Cygwin b/README.Cygwin
new file mode 100644
index 0000000..2fa509a
--- /dev/null
+++ b/README.Cygwin
@@ -0,0 +1,59 @@
+Starting with version 3.0.1, Octave is once again part of the normal
+net distribution of Cygwin, available from http://www.cygwin.com.  
+The latest previous version available was 2.1.73
+
+It is possible to build Octave on Windows systems with Cygwin,
+but with standard gcc-3.4.4-3 compiler there are some performance
+problems related to the way C++ exception handling is implemented.
+This is a known problem with a long history so it is suggested to use
+version gcc-4.3.2-1 or later.
+
+Binary version 3.0.2-2 is built with gcc-4.3.2-1
+ 
+Current cygwin octvave maintainer : 
+	Marco Atzeri
+	http://matzeri.altervista.org
+
+An obsolete version of Octave (2.1.73) is part of the normal net
+distribution of Cygwin, available from http://www.cygwin.com.  Check
+the package list in Cygwin's setup.exe installer if you would like to
+try using it.  However, 2.1.73 is unsupported and we STRONGLY
+recommended that you use a more recent version of Octave.
+
+It should be possible to build Octave on Windows systems with Cygwin,
+but at the time of this writing, there are some performance problems
+related to the way C++ exception handling is implemented with the
+default Cygwin compiler.  This is a known problem with a long history.
+If you would like to see this problem corrected, please search the
+Cygwin mailing lists for threads related to "sjlj exception handling"
+(or similar).
+
+There is also an "unofficial" Octave distribution for Cygwin:
+
+ 1. http://www.geocities.jp/tmacchant
+
+    The binaries here are built using gcc-3.4.4-3 configured with
+    --disable-sjlj-exceptions.  Performance is improved by using DWARF
+    exception handling instead of setjump/longjump exception
+    handling.  However, to build dynamically loaded .oct files that
+    will work with this version of Octave, you must use the same
+    specially configured version of GCC that was used to build Octave
+    itself and not the version of GCC that is distributed with
+    Cygwin.
+
+    This binary is maintained by Tatsuro Matsuroka.
+
+
+John W. Eaton
+jwe at octave.org
+
+Tatsuro MATSUOKA 
+tmacchant at yahoo.co.jp
+Department of Molecular Design and Engineering, 
+Gradudate School of Engineering, Nagoya University.
+
+Marco Atzeri
+marco_atzeri at yahoo.it
+Italy
+
+Wed, 17 Sep 2008 14:16:03 EDT
diff --git a/README.Linux b/README.Linux
new file mode 100644
index 0000000..f605feb
--- /dev/null
+++ b/README.Linux
@@ -0,0 +1,10 @@
+There are binary packages for Debian, Fedora, and other GNU/Linux
+distributions.
+
+Octave should build cleanly from source on most GNU/Linux systems.
+
+
+John W. Eaton
+jwe at octave.org
+
+Last updated: Wed, 31 Oct 2007 16:22:26 EDT
diff --git a/README.MSVC b/README.MSVC
new file mode 100644
index 0000000..958eda2
--- /dev/null
+++ b/README.MSVC
@@ -0,0 +1,290 @@
+Compiling Octave with MSVC
+
+Starting with Octave 2.9.9, Octave source tree contains support for
+MSVC (Microsoft C/C++ compiler).  This file explains how to
+successfully compile Octave under such a system.
+
+
+1. Requirements
+===============
+
+Depending whether you are compiling Octave from a release package or
+from CVS source tree, various additional tools are required.
+
+1.1 Shell
+---------
+
+The compilation process requires a working UNIX-like shell under
+Windows.  Such shell is provided either by Cygwin or MSYS (MinGW).
+The choice of the actual shell will have an impact on the rest of the
+procedure.  Altough both shell can be used, the procedure has been
+mainly tested under the MSYS shell.
+
+1.1.1 Cygwin shell
+
+The use of the Cygwin shell has the advantage of installation
+simplicity, as all required packages can be easily installed through
+the setup program.  However it presents some annoying compile-time
+problems.  The Cygwin shell can be installed via the setup program
+http://www.cygwin.com/setup.exe.  You should at least select the
+following packages
+
+  bash  grep  sed  make
+
+If you are building the CVS sources of Octave, you will also need
+
+  gawk  bison  flex  autoconf  tetex  texinfo  ghostscript
+
+When building from CVS, you need also gperf.  However, the version
+available under Cygwin is too old, so you should grab a more recent
+one.  You can either build gperf from the sources found at
+ftp://ftp.gnu.org or use the package from the GunWin32 project
+(http://gnuwin32.sourceforge.net).  Either way, get the gperf package,
+install it and make sure the executable is in your PATH under the
+Cygwin shell.
+
+1.1.2 MSYS shell
+
+The use of the MSYS shell requires more manual installation, but
+currently results in fewer compile-time problem.  Download and install
+the following packages from the MinGW download page
+(http://www.mingw.org):
+
+  MSYS-1.0.10.exe
+  msysDTK-1.0.1.exe
+
+If you are building the CVS sources of Octave, you will also need
+
+  msys-autoconf-2.59.tar.bz2
+
+from the MinGW site.
+
+  NOTE: the autoconf version included in msysDTK is too old (2.56).
+        Grab the newer one and simply uncompress it in the root
+        directory of the MSYS installation directory.
+
+If you are building from CVS, you will need the following
+additional tools that are not part of the MSYS packages
+
+  bison  flex  gperf
+
+You can find these packages as part of the GnuWin32 project
+(http://gnuwin32.sourceforge.net) or you can build them from sources
+found at ftp://ftp.gnu.org.  Download and install these packages and
+make sure the executables are in your PATH under the MSYS shell.
+
+Building the documentation from CVS also requires additional tools,
+mainly TeX, texinfo and ghostscript.  MiKTeX (http://www.miktex.org)
+provides a user-friendly TeX implementation under Windows, with an
+easy-to-use installer.  Download and install MiKTeX if you're building
+from CVS, and make sure the executables (located in
+<MiKTeX_install>\Main\miktex\bin) are in your PATH under the MSYS shell.
+
+MiKTeX also provides texinfo.  However, the msysDTK package provides
+an out-dated version that cannot be used to build Octave
+documentation.  So you should make sure that you're using the MiKTeX
+implementation, by either playing with your PATH variable or renaming
+the makeinfo.exe, texi2dvi and texi2pdf files located in the directory
+<MSYS_install>\bin.
+
+Ghostscript is available from http://www.cs.wisc.edu/~ghost/.
+Download and install the package gsxxxw32.exe, where xxx stands for
+the actual release or ghostscript (as of writing this documentation,
+version is 8.54; hence the package is named gs854w32.exe).  Again,
+make sure the gswin32.exe executable is in your PATH under the MSYS
+shell.
+
+1.2 Gnuplot
+-----------
+
+Octave relies on gnuplot for plotting.  It is not necessary to install
+gnuplot just to build the Octave executable, but it is needed to
+create some figures for the documentation if you are building the CVS
+sources of Octave.
+
+A Windows version of Gnuplot can be found at http://www.gnuplot.info.
+Download and install it, and make sure the pgnuplot.exe executable is
+in your PATH under the shell.
+
+1.3 MSVC compiler
+-----------------
+
+You'll need a recent MSVC compiler.  This compiler is available for
+free (as in beer) from Microsoft MSDN web site.  Octave has been
+successfully compiled using version 8 of the compiler (AKA Visual
+Studio 2005).  To start a command prompt with the correct compilation
+environment, use the corresponding menu entry in your start menu.
+
+If you're using the free version of Visual Studio (Express edition),
+you'll need to install the Platform SDK package, also available from
+MSDN.  In that case, you'll also need to run the "SetEnv.cmd" script
+found in the SDK installation directory for the required additional
+setup.
+
+1.4 Unix-to-MSVC compilation scripts
+------------------------------------
+
+These scripts provide a UNIX-like compilation interface, based on the
+Microsoft compilation tools.  The package is available from the Octave
+web site.  Download and install the package, and make sure the scripts
+are in your PATH under the shell.
+
+As those scripts calls the Microsoft compilation tools, those tools
+should also be in your PATH.  I've found that the easiest way to get a
+correct environment is to start the shell from the command prompt that
+is already configured for MSVC.
+
+Hence the following steps:
+
+  * start command prompt from Visual Studio menu entry
+
+  * run "SetEnv.cmd" if required
+
+  * additional setup (like adding Gnuplot, GnuWin32 bin
+    directory... to the PATH)
+
+  * start the shell:
+
+    - MSYS:    start <MSYS_install>\bin\rxvt.exe -e /bin/sh --login -i
+    - Cygwin:  start <Cygwin_install>\cygwin.bat
+
+1.5 Glob library
+----------------
+
+Octave also requires a filename globbing library.  This library is
+typically part of the C library on UNIX systems, but is not part of
+the Windows or MSVC run-time libraries.  You can find a glob package
+on the Octave website.  This package provides the missing features and
+is intended to be compiled in a fully setup shell with the
+Unix-to-MSVC compilation scripts:
+
+  * download and decompress the sources
+  * run "./configure.vc" (you can edit it to change the installation dir)
+  * run "make"
+  * run "make install"
+
+Then you'll have to tell MSVC where to find the headers and library
+files by adjusting the INCLUDE and LIB environment variables.  This
+can be done before starting the shell, in the "additional setup" step
+(see above).
+
+1.6 Readline library
+--------------------
+
+While not mandatory to compile Octave, the readline library is very
+useful to make Octave really usable.  A patched version of the
+readline library can be found in the Octave website.  This patched
+version is intended to be compiled from the shell using the
+Unix-to-MSVC compilation scripts:
+
+ * download and decompress the sources (and apply the patch, if required)
+ * follow the instructions in the file README.msvc
+
+As for the glob library, adapt the INCLUDE and LIB environment
+variables.  Note that as Octave will be linked to the readline DLL,
+you should also add the path of readline.dll to your PATH variable.
+
+1.7 F2C
+-------
+
+As there exist no free MSVC-like fortran compiler, the compilation
+process makes use of the f2c utility and the libf2c library.  Those
+components can be downloaded from http://www.netlib.org/f2c/msdos/ and
+http://www.netlib.org/f2c/libf2c.zip.
+
+To compile libf2c, use makefile.vc and NMAKE.EXE.  To be usable within
+Octave, the following modifications needs to be done:
+  1) edit makefile.vc and add "-MD" as compilation flag (to
+     the CFLAGS variable).
+  2) edit fio.h and comment the declaration of isatty (around line 112).
+     This means replacing the line:
+
+		extern int isatty(int);
+
+     with
+
+		/* extern int isatty(int); */
+
+After compilation, install f2c.h and vcf2c.lib at locations where they
+can be found by the MSVC tools (adjust the INCLUDE and LIB variables).
+Note that you must rename vcf2c.lib into f2c.lib so that Octave's
+configure script will find it.
+
+
+2. Compilation
+==============
+
+Copy the following lines into a shell script and execute it (note that
+you can use whatever you want as installation directory):
+
+--- BEGIN (cut me)
+#!/bin/sh
+if ! grep "__declspec(noreturn dllimport)" configure 2>&1 > /dev/null; then
+  echo "Pre-processing configure script..."
+  sed -e "s/'extern \"C\" void exit (int);'/'extern \"C\" __declspec(noreturn dllimport) void exit (int);' 'extern \"C\" void exit (int);'/g" configure \
+    > configure.tmp
+  mv configure.tmp configure
+fi
+
+CC=cc-msvc CXX=cc-msvc NM="dumpbin -symbols" AR=ar-msvc RANLIB=ranlib-msvc \
+  ./configure --build=i686-pc-msdosmsvc --prefix=/usr/local/octave-vc8-debug --with-f2c
+--- END (cut me)
+
+Then run the usual:
+
+  make
+  make install
+
+2.1 MSYS
+--------
+
+When building from the MSYS shell and CVS, everything should run fine
+until building the doc.  At some point, TeX might ask you for the
+location of the file conf.texi.  If this happens, simply type
+"../conf.texi" and the process should continue.
+
+2.2 Cygwin
+----------
+
+Building from the Cygwin shell and CVS produces more compile-time
+errors when generating the documentation.  Here are some fixes that
+should work around most problems:
+
+  * edit "run-octave" and add the 2 lines right after the definition of
+    LOADPATH and IMAGEPATH:
+
+      LOADPATH=`cygpath -d -p $LOADPATH`
+      IMAGEPATH=`cygpath -d $IMAGEPATH`
+
+  * if texi2dvi fails with the error "Fatal error: I'm stymied", defines TEX
+    variable to "tex" as in: "TEX=tex make"
+
+  * if pdftex fails in doc/refcard with the same error as above, edit
+  the Makefile and replace "pdftex" calls with "pdfetex"
+
+
+3. Installation
+===============
+
+The compiled Octave is relocatable.  This means that whatever
+installation dir you chose at configure time, you can move the whole
+installation directory to another location without any problem.  Octave
+should still run OK.
+
+
+4. Notes
+========
+
+This procedure has been successfully tested under Windows XP with
+Visual Studio 2005 Express edition, Platform SDK for Windows Server
+2003 R2, patched readline version 5.2, APFL ghostscript 8.54, Gnuplot
+4.0, MSYS-1.0.10, msysDTK-1.0.1, MiKTeX-2.4.  Depending on your
+configuration, it may or may not work for you.
+
+
+Please send questions, comments or suggestions to
+
+Michael Goffioul
+michael dot goffioul at swing dot be
+
+Thu Nov  2 11:30:50 2006
diff --git a/README.Windows b/README.Windows
new file mode 100644
index 0000000..0f2365a
--- /dev/null
+++ b/README.Windows
@@ -0,0 +1,11 @@
+See the file README.Cygwin for information about installing the binary
+package of Octave for Cygwin.
+
+See the file README.MSVC for instructions for compiling Octave with
+the MSVC compiler.
+
+
+John W. Eaton
+jwe at octave.org
+
+Last updated: Wed, 31 Oct 2007 16:34:12 EDT
diff --git a/README.kpathsea b/README.kpathsea
new file mode 100644
index 0000000..46f17ad
--- /dev/null
+++ b/README.kpathsea
@@ -0,0 +1,171 @@
+The code in the files
+
+  liboctave/kpse.cc
+  liboctave/kpse-xfns.h
+  liboctave/kpse-xfns.c
+
+was adapted from the kpathsearch library.  We don't use kpathsearch
+directly now because it has too many TeX-specific things that are not
+necessary for Octave, and it also does not implement all the special
+kinds of file searches that Octave needs (mainly for compatibility
+with Matlab).
+
+Original authors of the kpathsearch library
+-------------------------------------------
+
+Karl Berry wrote all files not otherwise marked, with help from Kathryn
+Hargreaves on some of the original versions.
+
+Thomas Esser originated most of the MakeTeX... scripts.
+
+The brace expansion code in expand.c was written by Brian Fox and Chet
+Ramey for Bash, the GNU shell.
+
+The implementation of the link trick in pathsearch.c is taken from GNU
+find, implemented by David MacKenzie from Matthew Farwell's suggestion.
+
+Debugging
+---------
+
+  Kpathsea provides a number of runtime debugging options, detailed
+below by their names and corresponding numeric values.  When the files
+you expect aren't being found, the thing to do is enable these options
+and examine the output.
+
+  You can set these with some runtime argument (e.g., `-d') to the
+program; in that case, you should use the numeric values described in
+the program's documentation (which, for Dvipsk and Xdvik, are different
+than those below).  It's best to give the `-d' (or whatever) option
+first, for maximal output.  Dvipsk and Xdvik have additional
+program-specific debugging options as well.
+
+  You can also set the environment variable `KPATHSEA_DEBUG'; in this
+case, you should use the numbers below.  If you run the program under a
+debugger and set the variable `kpathsea_debug', also use the numbers
+below.
+
+  In any case, by far the simplest value to use is `-1', which will
+turn on all debugging output.  This is usually better than guessing
+which particular values will yield the output you need.
+
+  Debugging output always goes to standard error, so you can redirect it
+easily.  For example, in Bourne-compatible shells:
+     dvips -d -1 ... 2>/tmp/debug
+
+  It is sometimes helpful to run the standalone Kpsewhich utility
+(*note Invoking kpsewhich::.), instead of the original program.
+
+  In any case, you can *not* use the *names* below; you must always use
+somebody's numbers.  (Sorry.)  To set more than one option, just sum
+the corresponding numbers.
+
+`KPSE_DEBUG_STAT (1)'
+     Report `stat'(2) calls.  This is useful for verifying that your
+     directory structure is not forcing Kpathsea to do many additional
+     file tests (*note Slow path searching::., and *note Subdirectory
+     expansion::.).  If you are using an up-to-date `ls-R' database
+     (*note Filename database::.), this should produce no output unless
+     a nonexistent file that must exist is searched for.
+
+`KPSE_DEBUG_HASH (2)'
+     Report lookups in all hash tables: `ls-R' and `aliases' (*note
+     Filename database::.); font aliases (*note Fontmap::.); and config
+     file values (*note Config files::.).  Useful when expected values
+     are not being found, e.g.., file searches are looking at the disk
+     instead of using `ls-R'.
+
+`KPSE_DEBUG_FOPEN (4)'
+     Report file openings and closings.  Especially useful when your
+     system's file table is full, for seeing which files have been
+     opened but never closed.  In case you want to set breakpoints in a
+     debugger: this works by redefining `fopen' (`fclose') to be
+     `kpse_fopen_trace' (`kpse_fclose_trace').
+
+`KPSE_DEBUG_PATHS (8)'
+     Report general path information for each file type Kpathsea is
+     asked to search.  This is useful when you are trying to track down
+     how a particular path got defined--from `texmf.cnf', `config.ps',
+     an environment variable, the compile-time default, etc.  This is
+     the contents of the `kpse_format_info_type' structure defined in
+     `tex-file.h'.
+
+`KPSE_DEBUG_EXPAND (16)'
+     Report the directory list corresponding to each path element
+     Kpathsea searches.  This is only relevant when Kpathsea searches
+     the disk, since `ls-R' searches don't look through directory lists
+     in this way.
+
+`KPSE_DEBUG_SEARCH (32)'
+     Report on each file search: the name of the file searched for, the
+     path searched in, whether or not the file must exist (when drivers
+     search for `cmr10.vf', it need not exist), and whether or not we
+     are collecting all occurrences of the file in the path (as with,
+     e.g., `texmf.cnf' and `texfonts.map'), or just the first (as with
+     most lookups).  This can help you correlate what Kpathsea is doing
+     with what is in your input file.
+
+`KPSE_DEBUG_VARS (64)'
+     Report the value of each variable Kpathsea looks up.  This is
+     useful for verifying that variables do indeed obtain their correct
+     values.
+
+`GSFTOPK_DEBUG (128)'
+     Activates debugging printout specific to `gsftopk' program.
+
+`MAKETEX_DEBUG (512)'
+     If you use the optional `mktex' programs instead of the
+     traditional shell scripts, this will report the name of the site
+     file (`mktex.cnf' by default) which is read, directories created by
+     `mktexdir', the full path of the `ls-R' database built by
+     `mktexlsr', font map searches, `MT_FEATURES' in effect, parameters
+     from `mktexnam', filenames added by `mktexupd', and some
+     subsidiary commands run by the programs.
+
+`MAKETEX_FINE_DEBUG (1024)'
+     When the optional `mktex' programs are used, this will print
+     additional debugging info from functions internal to these
+     programs.
+
+  Debugging output from Kpathsea is always written to standard error,
+and begins with the string `kdebug:'.  (Except for hash table buckets,
+which just start with the number, but you can only get that output
+running under a debugger.  See comments at the `hash_summary_only'
+variable in `kpathsea/db.c'.)
+
+Logging
+-------
+
+  Kpathsea can record the time and filename found for each successful
+search.  This may be useful in finding good candidates for deletion when
+your filesystem is full, or in discovering usage patterns at your site.
+
+  To do this, define the environment or config file variable
+`TEXMFLOG'.  The value is the name of the file to append the
+information to.  The file is created if it doesn't exist, and appended
+to if it does.
+
+  Each successful search turns into one line in the log file: two words
+separated by a space.  The first word is the time of the search, as the
+integer number of seconds since "the epoch", i.e., UTC midnight 1
+January 1970 (more precisely, the result of the `time' system call).
+The second word is the filename.
+
+  For example, after `setenv TEXMFLOG /tmp/log', running Dvips on
+`story.dvi' appends the following lines:
+
+     774455887 /usr/local/share/texmf/dvips/config.ps
+     774455887 /usr/local/share/texmf/dvips/psfonts.map
+     774455888 /usr/local/share/texmf/dvips/texc.pro
+     774455888 /usr/local/share/texmf/fonts/pk/ljfour/public/cm/cmbx10.600pk
+     774455889 /usr/local/share/texmf/fonts/pk/ljfour/public/cm/cmsl10.600pk
+     774455889 /usr/local/share/texmf/fonts/pk/ljfour/public/cm/cmr10.600pk
+     774455889 /usr/local/share/texmf/dvips/texc.pro
+
+Only filenames that are absolute are recorded, to preserve some
+semblance of privacy.
+
+
+John W. Eaton
+jwe at octave.org
+
+Last updated: Wed, 31 Oct 2007 16:33:13 EDT
diff --git a/ROADMAP b/ROADMAP
new file mode 100644
index 0000000..5132b45
--- /dev/null
+++ b/ROADMAP
@@ -0,0 +1,73 @@
+Here is an attempt at a simple explanation of the directory layout for
+Octave's source files.
+
+  dlfcn         -- dlopen, dlsym, dlerror, and dlclose for AIX
+
+  doc           -- Texinfo documentation for Octave
+
+  emacs         -- Emacs lisp stuff
+
+  examples      -- some example files
+
+  libcruft      -- various numerical libraries (mostly Fortran)
+    amos           * bessel functions
+    blas           * basic linear algebra subroutines
+    blas-xtra      * wrappers for blas functions used in Octave
+    daspk          * large scale differential algebraic equation solver
+    dasrt          * differential algebraic equation solver with root finding
+    dassl          * differential-algebraic system solver
+    fftpack        * subroutines for fast fourier transforms
+    lapack         * linear algebra package
+    lapack-xtra    * wrappers for lapack functions used in Octave
+    minpack        * nonlinear equation solver
+    misc           * miscellaneous utilities
+    odepack        * odinary differential equation solver
+    ordered-qz     * code for ordering eigenvalues for QZ factorization
+    quadpack       * subroutines for numerical integration
+    ranlib         * random number generators
+    slatec-err     * slatec error handling library
+    slatec-fn      * various special function subroutines
+    villad         * subroutines for orthogonal collocation weights
+
+  liboctave     -- the C++ interfaces to the numerical libraries and
+                   various OS facilities
+
+  scripts       -- functions written in the Octave language
+    audio          * play and record sound files (system dependent)
+    control        * control theory
+    deprecated     * older deprecated functions
+    elfun          * elementary mathematical functions
+    finance        * financial functions
+    general        * utility functions
+    image          * image processing
+    io             * input/output functions
+    linear-algebra * linear algebra stuff
+    miscellaneous  * stuff that doesn't fit anywhere else
+    optimization   * optimizers
+    path           * functions for path handling
+    pkg            * the package manager
+    plot           * plotting
+    polynomial     * polynomial manipulation
+    quaternion     * quaternions
+    set            * set manipulation
+    signal         * signal processing
+    sparse         * sparse matrix support
+    specfun        * special mathematical functions
+    special-matrix * functions for generating special types of matrices
+    startup        * initialization functions
+    statistics     * statistical stuff
+    strings        * character string manipulation
+    testfun        * unit testing
+    time           * time and date functions
+
+  src           -- the interpreter itself
+
+  test          -- tests for the interpreter
+    config         * configuration files for DejaGnu
+    octave.test    * subdirectories containing actual tests are here
+
+
+John W. Eaton
+jwe at octave.org
+
+Last updated: Wed, 31 Oct 2007 16:44:04 EDT
diff --git a/SENDING-PATCHES b/SENDING-PATCHES
new file mode 100644
index 0000000..7f9f374
--- /dev/null
+++ b/SENDING-PATCHES
@@ -0,0 +1,26 @@
+[This was originally from Richard Stallman who was writing about
+ Emacs.  --jwe]
+
+A reminder for those sending patches for Octave:
+
+  * Always make the diffs with context.  Preferably use diff -c.  It
+    is unreliable to install a diff without context, and therefore we
+    probably will not take the risk of trying; instead we will
+    probably ask you to send a context diff.  You might as well send
+    that in your first message.
+
+  * Always send change log entries with your patches.  Itemize the
+    entries so that they list each of the functions and variables
+    changed.  Look at the ChangeLog files and follow our conventions
+    regarding what information to include and what style to use.
+
+  * If the patch is to fix a bug, send a detailed bug report for the
+    bug.  Make this just as detailed as if you did not have any fix
+    for it.  This information is vital for convincing the maintainer
+    that your fix is necessary and should be installed.  Also, if your
+    fix would cause some other sort of problem, the bug report may
+    enable the maintainer to find some other correct fix.
+
+Everyone, please read the Bugs chapter in the Octave manual to see
+other guidelines on how to write a bug report that makes it possible
+to fix a bug.
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..df5758b
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1466 @@
+dnl aclocal.m4 -- extra macros for configuring Octave
+dnl
+dnl Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+dnl               2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+dnl 
+dnl This file is part of Octave.
+dnl 
+dnl Octave is free software; you can redistribute it and/or modify it
+dnl under the terms of the GNU General Public License as published by the
+dnl Free Software Foundation; either version 3 of the License, or (at
+dnl your option) any later version.
+dnl 
+dnl Octave is distributed in the hope that it will be useful, but WITHOUT
+dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+dnl FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+dnl for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with Octave; see the file COPYING.  If not, see
+dnl <http://www.gnu.org/licenses/>.
+dnl
+dnl ----------------------------------------------------------------------
+dnl
+dnl Figure out the hardware-vendor-os info.
+dnl
+dnl OCTAVE_HOST_TYPE
+AC_DEFUN(OCTAVE_HOST_TYPE,
+[AC_CANONICAL_HOST
+if test -z "$host"; then
+  host=unknown
+fi
+canonical_host_type=$host
+if test "$host" = unknown; then
+  AC_MSG_WARN([configuring Octave for unknown system type
+])
+fi
+AC_SUBST(canonical_host_type)])
+dnl
+dnl Set default value for a variable and substitute it.
+dnl
+dnl OCTAVE_SET_DEFAULT
+AC_DEFUN(OCTAVE_SET_DEFAULT,
+[ifelse($#, 2, [: ${$1=$2}
+])dnl
+AC_MSG_RESULT([defining $1 to be $$1])
+AC_SUBST($1)])
+dnl
+dnl Check for ar.
+dnl
+AC_DEFUN(OCTAVE_PROG_AR,
+[if test -z "$AR"; then
+  AR=ar
+fi
+AC_SUBST(AR)
+
+if test -z "$ARFLAGS"; then
+  ARFLAGS="rc"
+fi
+AC_SUBST(ARFLAGS)
+])
+dnl
+dnl See if the compiler supports placement delete
+dnl
+AC_DEFUN(OCTAVE_PLACEMENT_DELETE,
+[AC_CACHE_CHECK([whether <new> defines placement delete operator],
+octave_cv_placement_delete,
+[AC_LANG_PUSH(C++)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <new>]],
+[[operator delete((void *)0, (void *)0);]])],
+octave_cv_placement_delete=yes, octave_cv_placement_delete=no)])
+if test $octave_cv_placement_delete = yes; then
+AC_DEFINE(HAVE_PLACEMENT_DELETE,1,[Define if C++ supports operator delete(void *, void *)])
+fi
+AC_LANG_POP(C++)
+])
+dnl
+dnl See if the compiler dynamic auto arrays
+dnl
+AC_DEFUN(OCTAVE_DYNAMIC_AUTO_ARRAYS,
+[AC_CACHE_CHECK([whether C++ supports dynamic auto arrays],
+octave_cv_dynamic_auto_arrays,
+[AC_LANG_PUSH(C++)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],
+[[void test(char *); int length(); char x[length()]; test(x);]])],
+octave_cv_dynamic_auto_arrays=yes, octave_cv_dynamic_auto_arrays=no)])
+if test $octave_cv_dynamic_auto_arrays = yes; then
+AC_DEFINE(HAVE_DYNAMIC_AUTO_ARRAYS,1,[Define if C++ supports dynamic auto arrays])
+fi
+AC_LANG_POP(C++)
+])
+dnl
+dnl Check for broken strptime
+dnl
+AC_DEFUN(OCTAVE_STRPTIME_BROKEN,
+[AC_CACHE_CHECK([whether strptime is broken],
+octave_cv_strptime_broken,
+[AC_LANG_PUSH(C)
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#define _XOPEN_SOURCE
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#if defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#endif
+#include <stdio.h>
+#include <time.h>
+]], [[
+struct tm t;
+char *q = strptime ("09/13", "%m/%d/%y", &t);
+return q ? 1 : 0;
+]])], [octave_cv_strptime_broken=no], [octave_cv_strptime_broken=yes])])
+if test $octave_cv_strptime_broken = yes; then
+AC_DEFINE(OCTAVE_HAVE_BROKEN_STRPTIME, 1, [Define if strptime is broken on your system])
+fi
+AC_LANG_POP(C)
+])
+dnl
+dnl The following test is from Karl Berry's Kpathseach library.  I'm
+dnl including it here in case we someday want to make the use of
+dnl kpathsea optional.
+dnl
+dnl Some BSD putenv's, e.g., FreeBSD, do malloc/free's on the environment.
+dnl This test program is due to Mike Hibler <mike at cs.utah.edu>.
+dnl We don't actually need to run this if we don't have putenv, but it
+dnl doesn't hurt.
+AC_DEFUN(OCTAVE_SMART_PUTENV,
+[AC_MSG_CHECKING(whether putenv uses malloc)
+AC_CACHE_VAL(octave_cv_func_putenv_malloc,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#define VAR	"YOW_VAR"
+#define STRING1 "GabbaGabbaHey"
+#define STRING2 "Yow!!"		/* should be shorter than STRING1 */
+extern char *getenv (); /* in case char* and int don't mix gracefully */
+main ()
+{
+  char *str1, *rstr1, *str2, *rstr2;
+  str1 = getenv (VAR);
+  if (str1)
+    exit (1);
+  str1 = malloc (strlen (VAR) + 1 + strlen (STRING1) + 1);
+  if (str1 == 0)
+    exit (2);
+  strcpy (str1, VAR);
+  strcat (str1, "=");
+  strcat (str1, STRING1);
+  if (putenv (str1) < 0)
+    exit (3);
+  rstr1 = getenv (VAR);
+  if (rstr1 == 0)
+    exit (4);
+  rstr1 -= strlen (VAR) + 1;
+  if (strncmp (rstr1, VAR, strlen (VAR)))
+    exit (5);
+  str2 = malloc (strlen (VAR) + 1 + strlen (STRING2) + 1);
+  if (str2 == 0 || str1 == str2)
+    exit (6);
+  strcpy (str2, VAR);
+  strcat (str2, "=");
+  strcat (str2, STRING2);
+  if (putenv (str2) < 0)
+    exit (7);
+  rstr2 = getenv (VAR);
+  if (rstr2 == 0)
+    exit (8);
+  rstr2 -= strlen (VAR) + 1;
+#if 0
+  printf ("rstr1=0x%x, rstr2=0x%x\n", rstr1, rstr2);
+  /*
+   * If string from first call was reused for the second call,
+   * you had better not do a free on the first string!
+   */
+  if (rstr1 == rstr2)
+          printf ("#define SMART_PUTENV\n");
+  else
+          printf ("#undef SMART_PUTENV\n");
+#endif
+  exit (rstr1 == rstr2 ? 0 : 1);
+}]])], octave_cv_func_putenv_malloc=yes, octave_cv_func_putenv_malloc=no,
+    octave_cv_func_putenv_malloc=no)])dnl
+AC_MSG_RESULT($octave_cv_func_putenv_malloc)
+if test $octave_cv_func_putenv_malloc = yes; then
+  AC_DEFINE(SMART_PUTENV,1,[To quiet autoheader.])
+fi])
+dnl
+dnl These two checks for signal functions were originally part of the
+dnl aclocal.m4 file distributed with bash 2.0.
+dnl
+dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7)
+AC_DEFUN(OCTAVE_SIGNAL_CHECK,
+[AC_REQUIRE([AC_TYPE_SIGNAL])
+AC_MSG_CHECKING(for type of signal functions)
+AC_CACHE_VAL(octave_cv_signal_vintage,
+[
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]],
+    [[sigset_t ss;
+      struct sigaction sa;
+      sigemptyset (&ss);
+      sigsuspend (&ss);
+      sigaction (SIGINT, &sa, (struct sigaction *) 0);
+      sigprocmask (SIG_BLOCK, &ss, (sigset_t *) 0);]])],
+    [octave_cv_signal_vintage=posix],
+    [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]],
+       [[int mask = sigmask (SIGINT);
+	 sigsetmask (mask);
+         sigblock (mask);
+         sigpause (mask);]])],
+       [octave_cv_signal_vintage=4.2bsd],
+       [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>
+          RETSIGTYPE foo() { }]],
+          [[int mask = sigmask (SIGINT);
+	    sigset (SIGINT, foo);
+            sigrelse (SIGINT);
+	    sighold (SIGINT);
+            sigpause (SIGINT);]])],
+          [octave_cv_signal_vintage=svr3],
+          [octave_cv_signal_vintage=v7])])])])
+AC_MSG_RESULT($octave_cv_signal_vintage)
+if test "$octave_cv_signal_vintage" = posix; then
+AC_DEFINE(HAVE_POSIX_SIGNALS, 1, [Define if you have POSIX style signals.])
+elif test "$octave_cv_signal_vintage" = "4.2bsd"; then
+AC_DEFINE(HAVE_BSD_SIGNALS, 1, [Define if you have BSD style signals.])
+elif test "$octave_cv_signal_vintage" = svr3; then
+AC_DEFINE(HAVE_USG_SIGHOLD, 1, [Define if you have System V Release 3 signals.])
+fi
+])
+dnl
+AC_DEFUN(OCTAVE_REINSTALL_SIGHANDLERS,
+[AC_REQUIRE([AC_TYPE_SIGNAL])
+AC_REQUIRE([OCTAVE_SIGNAL_CHECK])
+AC_MSG_CHECKING([if signal handlers must be reinstalled when invoked])
+AC_CACHE_VAL(octave_cv_must_reinstall_sighandlers,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <signal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+typedef RETSIGTYPE sigfunc();
+int nsigint;
+#ifdef HAVE_POSIX_SIGNALS
+sigfunc *
+set_signal_handler(sig, handler)
+     int sig;
+     sigfunc *handler;
+{
+  struct sigaction act, oact;
+  act.sa_handler = handler;
+  act.sa_flags = 0;
+  sigemptyset (&act.sa_mask);
+  sigemptyset (&oact.sa_mask);
+  sigaction (sig, &act, &oact);
+  return (oact.sa_handler);
+}
+#else
+#define set_signal_handler(s, h) signal(s, h)
+#endif
+RETSIGTYPE
+sigint(s)
+    int s;
+{
+  nsigint++;
+}
+main()
+{
+  nsigint = 0;
+  set_signal_handler(SIGINT, sigint);
+  kill((int)getpid(), SIGINT);
+  kill((int)getpid(), SIGINT);
+  exit(nsigint != 2);
+}
+]])],
+  octave_cv_must_reinstall_sighandlers=no,
+  octave_cv_must_reinstall_sighandlers=yes,
+if test "$octave_cv_signal_vintage" = svr3; then
+  octave_cv_must_reinstall_sighandlers=yes
+else
+  octave_cv_must_reinstall_sighandlers=no
+fi)])
+if test "$cross_compiling" = yes; then
+  AC_MSG_RESULT([$octave_cv_must_reinstall_sighandlers assumed for cross compilation])
+else
+  AC_MSG_RESULT($octave_cv_must_reinstall_sighandlers)
+fi
+if test "$octave_cv_must_reinstall_sighandlers" = yes; then
+  AC_DEFINE(MUST_REINSTALL_SIGHANDLERS,1,[Define if signal handlers must be reinstalled after they are called.])
+fi
+])
+dnl
+dnl Check to see if C++ compiler needs the new friend template declaration 
+dnl syntax. 
+dnl
+dnl OCTAVE_CXX_NEW_FRIEND_TEMPLATE_DECL
+AC_DEFUN(OCTAVE_CXX_NEW_FRIEND_TEMPLATE_DECL, [
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_MSG_CHECKING([for C++ support for new friend template declaration])
+  AC_CACHE_VAL(octave_cv_cxx_new_friend_template_decl, [
+    AC_LANG_PUSH(C++)
+    rm -f conftest.h
+    cat > conftest.h <<EOB
+       struct A {
+	 friend int operator== (const A&, const A&);
+	 A (int) { }
+       };
+
+       template <class T> int
+       operator== (const T&, const T&)
+       {
+	 return 0;
+       }
+EOB
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "conftest.h"]],
+      [[A a (1);
+        return a == A(1);]])],
+      [octave_cv_cxx_new_friend_template_decl=no],
+      [octave_cv_cxx_new_friend_template_decl=yes])
+    AC_LANG_POP(C++)
+  ])
+  AC_MSG_RESULT($octave_cv_cxx_new_friend_template_decl)
+  if test $octave_cv_cxx_new_friend_template_decl = yes; then
+    AC_DEFINE(CXX_NEW_FRIEND_TEMPLATE_DECL,1,[Define if your compiler supports `<>' stuff for template friends.])
+  fi
+])
+dnl
+dnl Check to see if C compiler handles FLAG command line option.  If
+dnl two arguments are specified, execute the second arg as shell
+dnl commands.  Otherwise, add FLAG to CFLAGS if the compiler accepts
+dnl the flag.
+dnl
+dnl OCTAVE_CC_FLAG
+AC_DEFUN(OCTAVE_CC_FLAG, [
+  ac_safe=`echo "$1" | sed 'y%./+-:=%__p___%'`
+  AC_MSG_CHECKING(whether ${CC-cc} accepts $1)
+  AC_CACHE_VAL(octave_cv_cc_flag_$ac_safe, [
+    AC_LANG_PUSH(C)
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $1"
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+      eval "octave_cv_cc_flag_$ac_safe=yes",
+      eval "octave_cv_cc_flag_$ac_safe=no")
+    CFLAGS="$XCFLAGS"
+    AC_LANG_POP(C)
+  ])
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    AC_MSG_RESULT(yes)
+    ifelse([$2], , [
+      CFLAGS="$CFLAGS $1"
+      AC_MSG_RESULT([adding $1 to CFLAGS])], [$2])
+  else
+    AC_MSG_RESULT(no)
+    ifelse([$3], , , [$3])
+  fi
+])
+dnl
+dnl Check to see if C++ compiler handles FLAG command line option.  If
+dnl two arguments are specified, execute the second arg as shell
+dnl commands.  Otherwise, add FLAG to CXXFLAGS if the compiler accepts
+dnl the flag.
+dnl
+dnl OCTAVE_CXX_FLAG
+AC_DEFUN(OCTAVE_CXX_FLAG, [
+  ac_safe=`echo "$1" | sed 'y%./+-:=%__p___%'`
+  AC_MSG_CHECKING(whether ${CXX-g++} accepts $1)
+  AC_CACHE_VAL(octave_cv_cxx_flag_$ac_safe, [
+    AC_LANG_PUSH(C++)
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS $1"
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+      eval "octave_cv_cxx_flag_$ac_safe=yes",
+      eval "octave_cv_cxx_flag_$ac_safe=no")
+    CXXFLAGS="$XCXXFLAGS"
+    AC_LANG_POP(C++)
+  ])
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    AC_MSG_RESULT(yes)
+    ifelse([$2], , [
+      CXXFLAGS="$CXXFLAGS $1"
+      AC_MSG_RESULT([adding $1 to CXXFLAGS])], [$2])
+  else
+    AC_MSG_RESULT(no)
+    ifelse([$3], , , [$3])
+  fi
+])
+dnl
+dnl Check to see if Fortran compiler handles FLAG command line option.  If
+dnl two arguments are specified, execute the second arg as shell
+dnl commands.  Otherwise, add FLAG to FFLAGS if the compiler accepts
+dnl the flag.
+dnl
+dnl OCTAVE_F77_FLAG
+AC_DEFUN(OCTAVE_F77_FLAG, [
+  ac_safe=`echo "$1" | sed 'y%./+-:=%__p___%'`
+  AC_MSG_CHECKING(whether ${F77-g77} accepts $1)
+  AC_CACHE_VAL(octave_cv_f77_flag_$ac_safe, [
+    AC_LANG_PUSH(Fortran 77)
+    XFFLAGS="$FFLAGS"
+    FFLAGS="$FFLAGS $1"
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+      eval "octave_cv_f77_flag_$ac_safe=yes",
+      eval "octave_cv_f77_flag_$ac_safe=no")
+    FFLAGS="$XFFLAGS"
+    AC_LANG_POP(Fortran 77)
+  ])
+  if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then
+    AC_MSG_RESULT(yes)
+    ifelse([$2], , [
+      FFLAGS="$FFLAGS $1"
+      AC_MSG_RESULT([adding $1 to FFLAGS])], [$2])
+  else
+    AC_MSG_RESULT(no)
+    ifelse([$3], , , [$3])
+  fi
+])
+dnl
+dnl Check for flex
+dnl
+AC_DEFUN(OCTAVE_PROG_FLEX, [
+### For now, don't define LEXLIB to be -lfl -- we don't use anything in
+### it, and it might not be installed.
+###
+### Also make sure that we generate an interactive scanner if we are
+### using flex.
+  AC_PROG_LEX
+  case "$LEX" in
+    flex*)
+      LFLAGS="-t -I"
+      AC_MSG_RESULT([defining LFLAGS to be $LFLAGS])
+      LEXLIB=
+    ;;
+    *)
+      LEX='$(top_srcdir)/missing flex'
+      warn_flex="I didn't find flex, but it's only a problem if you need to reconstruct lex.cc"
+      AC_MSG_WARN($warn_flex)
+    ;;
+  esac
+  AC_SUBST(LFLAGS)
+])
+dnl
+dnl Check for bison
+dnl
+AC_DEFUN(OCTAVE_PROG_BISON, [
+  AC_PROG_YACC
+  case "$YACC" in
+    bison*)
+    ;;
+    *)
+      YACC='$(top_srcdir)/missing bison'
+      warn_bison="I didn't find bison, but it's only a problem if you need to reconstruct parse.cc"
+      AC_MSG_WARN($warn_bison)
+    ;;
+  esac
+])
+dnl
+dnl What pager should we use?
+dnl
+AC_DEFUN(OCTAVE_PROG_PAGER,
+[if test "$cross_compiling" = yes; then
+  DEFAULT_PAGER=less
+  AC_MSG_RESULT(assuming $DEFAULT_PAGER exists on $canonical_host_type host)
+  AC_SUBST(DEFAULT_PAGER)
+else
+  octave_possible_pagers="less more page pg"
+  case "$canonical_host_type" in
+    *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc)
+      octave_possible_pagers="$octave_possible_pagers more.com"
+    ;;
+  esac
+
+  AC_CHECK_PROGS(DEFAULT_PAGER, $octave_possible_pagers, [])
+  if test -z "$DEFAULT_PAGER"; then
+    warn_less="I couldn't find \`less', \`more', \`page', or \`pg'"
+    AC_MSG_WARN($warn_less)
+  fi
+fi
+])
+dnl
+dnl Does gnuplot exist?
+dnl
+AC_DEFUN(OCTAVE_PROG_GNUPLOT, [
+case "$canonical_host_type" in
+  *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc)
+    gp_names="pgnuplot pipe-gnuplot gnuplot"
+    gp_default=pgnuplot
+  ;;
+  *)
+    gp_names=gnuplot
+    gp_default=gnuplot
+  ;;
+esac
+if test "$cross_compiling" = yes; then
+  GNUPLOT="$gp_default"
+  AC_MSG_RESULT(assuming $GNUPLOT exists on $canonical_host_type host)
+else
+  AC_CHECK_PROGS(GNUPLOT, $gp_names)
+  if test -z "$GNUPLOT"; then
+    warn_gnuplot=yes
+
+    GNUPLOT="$gp_default"
+
+    ## If you change this text, be sure to also copy it to the set of
+    ## warnings at the end of the script
+
+    AC_MSG_WARN([I didn't find gnuplot.  It isn't necessary to have gnuplot])
+    AC_MSG_WARN([installed, but you won't be able to use any of Octave's])
+    AC_MSG_WARN([plotting commands without it.])
+    AC_MSG_WARN([])
+    AC_MSG_WARN([If gnuplot is installed but it isn't in your path, you can])
+    AC_MSG_WARN([tell Octave where to find it by typing the command])
+    AC_MSG_WARN([])
+    AC_MSG_WARN([gnuplot_binary = "/full/path/to/gnuplot/binary"])
+    AC_MSG_WARN([])
+    AC_MSG_WARN([at the Octave prompt.])
+    AC_MSG_WARN([])
+    AC_MSG_WARN([Setting default value to $GNUPLOT])
+  fi
+fi
+AC_SUBST(GNUPLOT)
+])
+dnl
+dnl Is gperf installed?
+dnl
+dnl OCTAVE_PROG_GPERF
+AC_DEFUN(OCTAVE_PROG_GPERF, [
+  AC_CHECK_PROG(GPERF, gperf, gperf, [])
+  if test -z "$GPERF"; then
+    GPERF='$(top_srcdir)/missing gperf'
+    warn_gperf="I didn't find gperf, but it's only a problem if you need to reconstruct oct-gperf.h"
+    AC_MSG_WARN($warn_gperf)
+  fi
+  AC_SUBST(GPERF)
+])
+dnl
+dnl Is ghostscript installed?
+dnl
+dnl OCTAVE_PROG_GHOSTSCRIPT
+AC_DEFUN(OCTAVE_PROG_GHOSTSCRIPT, [
+  case "$canonical_host_type" in
+    *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc)
+      gs_names="gs gswin32"
+    ;;
+    *)
+      gs_names=gs
+    ;;
+  esac
+  AC_CHECK_PROGS(GHOSTSCRIPT, $gs_names)
+  if test -z "$GHOSTSCRIPT"; then
+    GHOSTSCRIPT='$(top_srcdir)/missing gs'
+    warn_ghostscript="I didn't find ghostscript, but it's only a problem if you need to reconstruct figures for the manual"
+    AC_MSG_WARN($warn_ghostscript)
+  fi
+  AC_SUBST(GHOSTSCRIPT)
+])
+dnl
+dnl Is makeinfo installed?
+dnl
+dnl OCTAVE_PROG_MAKEINFO
+AC_DEFUN(OCTAVE_PROG_MAKEINFO, [
+  AC_CHECK_PROG(MAKEINFO, makeinfo, makeinfo, [])
+  if test -z "$MAKEINFO"; then
+    MAKEINFO='$(top_srcdir)/missing makeinfo'
+    warn_makeinfo="I didn't find makeinfo, but it's only a problem if you need to reconstruct the Info version of the manual"
+    AC_MSG_WARN($warn_makeinfo)
+  fi
+  AC_SUBST(MAKEINFO)
+])
+dnl
+dnl Is texi2dvi installed?
+dnl
+dnl OCTAVE_PROG_TEXI2DVI
+AC_DEFUN(OCTAVE_PROG_TEXI2DVI, [
+  AC_CHECK_PROG(TEXI2DVI, texi2dvi, texi2dvi, [])
+  if test -z "$TEXI2DVI"; then
+    TEXI2DVI='$(top_srcdir)/missing texi2dvi'
+    warn_texi2dvi="I didn't find texi2dvi, but it's only a problem if you need to reconstruct the DVI version of the manual"
+    AC_MSG_WARN($warn_texi2dvi)
+  fi
+  AC_SUBST(TEXI2DVI)
+])
+dnl
+dnl Is texi2pdf installed?
+dnl
+dnl OCTAVE_PROG_TEXI2PDF
+AC_DEFUN(OCTAVE_PROG_TEXI2PDF, [
+  AC_REQUIRE([OCTAVE_PROG_TEXI2DVI])
+  AC_CHECK_PROG(TEXI2PDF, texi2pdf, texi2pdf, [])
+  if test -z "$TEXI2PDF"; then
+    missing=true;
+    if test -n "$TEXI2DVI"; then
+      TEXI2PDF="$TEXI2DVI --pdf"
+      missing=false;
+    fi
+  else
+    missing=false;
+  fi
+  if $missing; then
+    TEXI2PDF='$(top_srcdir)/missing texi2pdf'
+    warn_texi2pdf="I didn't find texi2pdf, but it's only a problem if you need to reconstruct the PDF version of the manual"
+    AC_MSG_WARN($warn_texi2pdf)
+  fi
+  AC_SUBST(TEXI2PDF)
+])
+dnl
+dnl See if the C++ library is ISO compliant.
+dnl FIXME: This is obviously very simplistic, and trivially fooled.
+dnl
+dnl OCTAVE_CXX_ISO_COMPLIANT_LIBRARY
+AC_DEFUN(OCTAVE_CXX_ISO_COMPLIANT_LIBRARY, [
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_MSG_CHECKING([if C++ library is ISO compliant])
+  AC_CACHE_VAL(octave_cv_cxx_iso_compliant_library, [
+    AC_LANG_PUSH(C++)
+    rm -f conftest.h
+### Omitting cwctype for now, since it is broken with gcc-3.0.x and
+### possibly other versions...
+    for inc in algorithm bitset cassert cctype cerrno cfloat ciso646 \
+	climits clocale cmath complex csetjmp csignal cstdarg cstddef \
+	cstdio cstdlib cstring ctime cwchar deque exception \
+	fstream functional iomanip ios iosfwd iostream istream iterator \
+	limits list locale map memory new numeric ostream queue set \
+	sstream stack stdexcept streambuf string strstream typeinfo \
+	utility valarray vector; do
+      echo "#include <$inc>" >> conftest.h
+    done
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "conftest.h"]],
+      [[std::bitset<50> flags;
+        flags.set();
+        int digits = std::numeric_limits<unsigned long>::digits;
+        digits = 0;]])],
+      [octave_cv_cxx_iso_compliant_library=yes],
+      [octave_cv_cxx_iso_compliant_library=no])
+    AC_LANG_POP(C++)
+  ])
+  AC_MSG_RESULT($octave_cv_cxx_iso_compliant_library)
+  if test $octave_cv_cxx_iso_compliant_library = yes; then
+    AC_DEFINE(CXX_ISO_COMPLIANT_LIBRARY, 1, [Define if your C++ runtime library is ISO compliant.])
+  fi
+])
+dnl
+dnl Allow the user disable support for command line editing using GNU
+dnl readline.
+dnl
+dnl OCTAVE_ENABLE_READLINE
+AC_DEFUN(OCTAVE_ENABLE_READLINE, [
+  USE_READLINE=true
+  LIBREADLINE=
+  AC_ARG_ENABLE(readline,
+    [  --enable-readline       use readline library (default is yes)],
+    [if test "$enableval" = no; then
+       USE_READLINE=false
+       warn_readline="command editing and history features require GNU Readline"
+     fi])
+  if $USE_READLINE; then
+    AC_CHECK_LIB(readline, rl_set_keyboard_input_timeout, [
+      LIBREADLINE="-lreadline"
+      LIBS="$LIBREADLINE $LIBS"
+      AC_DEFINE(USE_READLINE, 1, [Define to use the readline library.])
+    ], [
+      AC_MSG_WARN([I need GNU Readline 4.2 or later])
+      AC_MSG_ERROR([this is fatal unless you specify --disable-readline])
+    ])
+  fi
+  AC_SUBST(LIBREADLINE)
+])
+dnl
+dnl Check to see if C++ reintrepret cast works for function pointers.
+dnl
+dnl OCTAVE_CXX_BROKEN_REINTERPRET_CAST
+dnl
+AC_DEFUN(OCTAVE_CXX_BROKEN_REINTERPRET_CAST, [
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_LANG_PUSH(C++)
+  AC_CACHE_CHECK([for broken C++ reinterpret_cast],
+    octave_cv_cxx_broken_reinterpret_cast, [
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <cmath>]], [[
+      typedef double (*fptr) (double);
+      fptr psin = sin;
+      void *vptr = reinterpret_cast<void *> (psin);
+      psin = reinterpret_cast<fptr> (vptr);]])],
+      octave_cv_cxx_broken_reinterpret_cast=no,
+      octave_cv_cxx_broken_reinterpret_cast=yes)])
+  if test $octave_cv_cxx_broken_reinterpret_cast = yes ; then
+    AC_DEFINE(CXX_BROKEN_REINTERPRET_CAST, 1, [Define if C++ reinterpret_cast fails for function pointers.])
+fi
+  AC_LANG_POP(C++)])
+dnl
+dnl Determine if mkdir accepts only one argument instead dnl of the usual 2.
+dnl
+AC_DEFUN(OCTAVE_MKDIR_TAKES_ONE_ARG, [
+AC_LANG_PUSH(C++)
+AC_CACHE_CHECK([if mkdir takes one argument], octave_cv_mkdir_takes_one_arg,
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif]], [[mkdir ("foo", 0);]])],
+        octave_cv_mkdir_takes_one_arg=no, octave_cv_mkdir_takes_one_arg=yes)])
+AC_LANG_POP(C++)
+if test $octave_cv_mkdir_takes_one_arg = yes ; then
+  AC_DEFINE(MKDIR_TAKES_ONE_ARG, 1, [Define if host mkdir takes a single argument.])
+fi
+])
+dnl
+dnl Find find.
+dnl
+# Prefer GNU find if found.
+AN_MAKEVAR([FIND],  [OCTAVE_PROG_FIND])
+AN_PROGRAM([gfind], [OCTAVE_PROG_FIND])
+AN_PROGRAM([find],  [OCTAVE_PROG_FIND])
+AC_DEFUN([OCTAVE_PROG_FIND],
+[AC_CHECK_PROGS(FIND, gfind find, )])
+dnl
+dnl Find sed.
+dnl
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible and that supports "\(X\|Y\)"
+# style regular expression alternation.  Prefer GNU sed if found.
+AC_DEFUN([OCTAVE_PROG_SED],
+[AC_MSG_CHECKING([for a usable sed])
+if test -z "$SED"; then
+  AC_CACHE_VAL(ac_cv_path_sed, [
+  # Loop through the user's path and test for sed and gsed.
+  # Then use that list of sed's as ones to test for truncation.
+  _AS_PATH_WALK([$PATH],
+    [for ac_prog in sed gsed; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if AS_EXECUTABLE_P(["$as_dir/$ac_prog$ac_exec_ext"]); then
+	  _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext"
+	fi
+      done
+    done
+    ])
+    AS_TMPDIR(sed)
+    _max=0
+    _count=0
+    # Add /usr/xpg4/bin/sed as it is typically found on Solaris
+    # along with /bin/sed that truncates output.
+    for _sed in $_sed_list /usr/xpg4/bin/sed; do
+      test ! -f ${_sed} && break
+      cat /dev/null > "$tmp/sed.in"
+      _count=0
+      echo $ECHO_N "0123456789$ECHO_C" >"$tmp/sed.in"
+      # Check for GNU sed and select it if it is found.
+      if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then
+	octave_cv_path_sed=${_sed}
+	break;
+      fi
+      # Reject if RE alternation is not handled.
+      if test "`echo 'this and that' | ${_sed} -n 's/\(this\|that\).*$/\1/p'`" != "this"; then
+        continue;
+      fi
+      while true; do
+	cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp"
+	mv "$tmp/sed.tmp" "$tmp/sed.in"
+	cp "$tmp/sed.in" "$tmp/sed.nl"
+	echo >>"$tmp/sed.nl"
+	${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break
+	cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break
+	# 10000 chars as input seems more than enough
+	test $_count -gt 10 && break
+	_count=`expr $_count + 1`
+	if test $_count -gt $_max; then
+	  _max=$_count
+	  octave_cv_path_sed=$_sed
+	fi
+      done
+    done
+    rm -rf "$tmp"
+  ])
+  SED=$octave_cv_path_sed
+  if test -z "$SED"; then
+    AC_MSG_ERROR([no usable version of sed found])
+  fi
+fi
+AC_SUBST(SED)
+AC_MSG_RESULT([$SED])
+])
+dnl
+dnl Find Perl.
+dnl
+dnl OCTAVE_PROG_PERL
+AC_DEFUN(OCTAVE_PROG_PERL,
+[AC_CHECK_PROG(PERL, perl, perl, [])
+  AC_SUBST(PERL)
+])
+dnl
+dnl Find Python.
+dnl
+dnl OCTAVE_PROG_PYTHON
+AC_DEFUN(OCTAVE_PROG_PYTHON,
+[AC_CHECK_PROG(PYTHON, python, python, [])
+  AC_SUBST(PYTHON)
+])
+dnl
+dnl Find desktop-file-install.
+dnl
+dnl OCTAVE_PROG_DESKTOP_FILE_INSTALL
+AC_DEFUN(OCTAVE_PROG_DESKTOP_FILE_INSTALL,
+[AC_CHECK_PROG(DESKTOP_FILE_INSTALL, desktop-file-install, desktop-file-install, [])
+  AC_SUBST(DESKTOP_FILE_INSTALL)
+])
+dnl
+dnl Check for IEEE 754 data format.
+dnl
+AC_DEFUN([OCTAVE_IEEE754_DATA_FORMAT],
+[AC_MSG_CHECKING([for IEEE 754 data format])
+AC_CACHE_VAL(octave_cv_ieee754_data_format,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+int
+main (void) 
+{
+  typedef union { unsigned char c[8]; double d; } ieeebytes;
+   
+  ieeebytes l = {0x1c, 0xbc, 0x6e, 0xf2, 0x54, 0x8b, 0x11, 0x43};
+  ieeebytes b = {0x43, 0x11, 0x8b, 0x54, 0xf2, 0x6e, 0xbc, 0x1c};
+
+  return l.d != 1234567891234567.0 && b.d != 1234567891234567.0;
+}]])],
+  octave_cv_ieee754_data_format=yes,
+  octave_cv_ieee754_data_format=no,
+  octave_cv_ieee754_data_format=no)])
+if test "$cross_compiling" = yes; then
+  AC_MSG_RESULT([$octave_cv_ieee754_data_format assumed for cross compilation])
+else
+  AC_MSG_RESULT($octave_cv_ieee754_data_format)
+fi
+if test "$octave_cv_ieee754_data_format" = yes; then
+  AC_DEFINE(HAVE_IEEE754_DATA_FORMAT, 1, [Define if your system uses IEEE 754 data format.])
+fi
+])
+dnl
+dnl Check for UMFPACK seperately split complex matrix and RHS. Note
+dnl that as umfpack.h can be in three different places, rather than
+dnl include it, just declare the functions needed.
+dnl
+dnl Assumes that the check for umfpack has already been performed.
+dnl
+AC_DEFUN([OCTAVE_UMFPACK_SEPERATE_SPLIT],
+[AC_MSG_CHECKING([for UMFPACK seperate complex matrix and rhs split])
+AC_CACHE_VAL(octave_cv_umfpack_seperate_split,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdlib.h>
+#if defined (HAVE_UFSPARSE_UMFPACK_h)
+#include <ufsparse/umfpack.h>
+#elif defined (HAVE_UMFPACK_UMFPACK_H)
+#include <umfpack/umfpack.h>
+#elif defined (HAVE_UMFPACK_H)
+#include <umfpack.h>
+#endif
+int n = 5;
+int Ap[] = {0, 2, 5, 9, 10, 12};
+int Ai[]  = {0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4};
+double Ax[] = {2., 0., 3., 0., 3., 0., -1., 0., 4., 0., 4., 0., 
+	      -3., 0., 1., 0., 2., 0., 2., 0., 6., 0., 1., 0.};
+double br[] = {8., 45., -3., 3., 19.};
+double bi[] = {0., 0., 0., 0., 0.};
+int main (void)
+{
+  double *null = (double *) NULL ;
+  double *x = (double *)malloc (2 * n * sizeof(double));
+  int i ;
+  void *Symbolic, *Numeric ;
+  (void) umfpack_zi_symbolic (n, n, Ap, Ai, Ax, null, &Symbolic, null, null) ;
+  (void) umfpack_zi_numeric (Ap, Ai, Ax, null, Symbolic, &Numeric, null, null) ;
+  umfpack_zi_free_symbolic (&Symbolic) ;
+  (void) umfpack_zi_solve (0, Ap, Ai, Ax, null, x, null, br, bi, 
+		Numeric, null, null) ;
+  umfpack_zi_free_numeric (&Numeric) ;
+  for (i = 0; i < n; i++, x+=2) 
+    if (fabs(*x - i - 1.) > 1.e-13)
+      return (1);
+  return (0) ;
+}
+]])],
+  octave_cv_umfpack_seperate_split=yes,
+  octave_cv_umfpack_seperate_split=no,
+  octave_cv_umfpack_seperate_split=no)])
+if test "$cross_compiling" = yes; then
+  AC_MSG_RESULT([$octave_cv_umfpack_seperate_split assumed for cross compilation])
+else
+  AC_MSG_RESULT($octave_cv_umfpack_seperate_split)
+fi
+if test "$octave_cv_umfpack_seperate_split" = yes; then
+  AC_DEFINE(UMFPACK_SEPARATE_SPLIT, 1, [Define if the UMFPACK Complex solver allow matrix and RHS to be split independently])
+fi
+])
+dnl
+dnl Check whether using HDF5 DLL under Windows. This is done by
+dnl testing for a data symbol in the HDF5 library, which would
+dnl requires the definition of _HDF5USEDL_ under MSVC compiler.
+dnl
+AC_DEFUN([OCTAVE_HDF5_DLL], [
+  AC_CACHE_CHECK([if _HDF5USEDLL_ needs to be defined],octave_cv_hdf5_dll, [
+    AC_TRY_LINK([#include <hdf5.h>], [hid_t x = H5T_NATIVE_DOUBLE; return x],
+      octave_cv_hdf5_dll=no, [
+      CFLAGS_old=$CFLAGS
+      CFLAGS="$CFLAGS -DWIN32 -D_HDF5USEDLL_"
+      AC_TRY_LINK([#include <hdf5.h>], [hid_t x = H5T_NATIVE_DOUBLE; return x],
+        octave_cv_hdf5_dll=yes,
+	octave_cv_hdf5_dll=no)
+      CFLAGS=$CFLAGS_old])])
+  if test "$octave_cv_hdf5_dll" = yes; then
+    AC_DEFINE(_HDF5USEDLL_, 1, [Define if using HDF5 dll (Win32)])
+  fi])
+dnl
+dnl Check whether HDF5 library has version 1.6 API functions.
+dnl
+AC_DEFUN([OCTAVE_HDF5_HAS_REQUIRED_API], [
+  AC_CACHE_CHECK([whether HDF5 library has required API],
+    octave_cv_hdf5_has_required_api, [
+    AC_TRY_LINK([
+#define H5_USE_16_API 1
+#include <hdf5.h>
+], [
+  H5Eset_auto (0, 0);], [
+      octave_cv_hdf5_has_required_api=yes], [
+      octave_cv_hdf5_has_required_api=no])])
+  if test "$octave_cv_hdf5_has_required_api" = "no"; then
+    WITH_HDF5=false
+    warn_hdf5="HDF5 library does not provide the version 1.6 API.  Octave will not be able to save or load HDF5 data files."
+    AC_MSG_WARN($warn_hdf5)
+  fi
+])
+dnl
+dnl Check for the QHull version.
+dnl
+AC_DEFUN(AC_CHECK_QHULL_VERSION,
+[AC_MSG_CHECKING([for qh_qhull in -lqhull with qh_version])
+AC_CACHE_VAL(octave_cv_lib_qhull_version,  [
+cat > conftest.c <<EOF
+#include <stdio.h>
+char *qh_version = "version";
+char qh_qhull();
+int
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  qh_qhull();
+  return 0;
+}
+EOF
+
+octave_qhull_try="${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS conftest.c -o conftest -lqhull $LIBS"
+if (eval "$octave_qhull_try") 2>&AS_MESSAGE_LOG_FD && test -s conftest ; then
+    octave_cv_lib_qhull_version=yes
+else
+    octave_cv_lib_qhull_version=no
+fi
+rm -f conftest.c conftest.o conftest
+])dnl
+if test "$octave_cv_lib_qhull_version" = "yes"; then
+  AC_MSG_RESULT(yes)
+  ifelse([$1], , , [$1])
+else
+  AC_MSG_RESULT(no)
+  ifelse([$2], , , [$2])
+fi
+])
+dnl
+dnl Check whether QHull works (does not crash)
+dnl
+AC_DEFUN(AC_CHECK_QHULL_OK,
+[AC_MSG_CHECKING([whether the qhull library works])
+AC_CACHE_VAL(octave_cv_lib_qhull_ok,
+[
+  save_LIBS="$LIBS"
+  LIBS="$LIBS -lqhull"
+  case $host in
+    *-mingw*|*-msdosmsvc*) ;;
+    *) LIBS="$LIBS -lm" ;;
+  esac
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <qhull/qhull.h>
+
+#ifdef NEED_QHULL_VERSION
+char *qh_version = "version";
+#endif
+int main()
+{
+  int dim = 2, n = 4;
+  coordT points[8] = { -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5 };
+  boolT ismalloc = 0;
+
+  return qh_new_qhull (dim, n, points, ismalloc, "qhull ", 0, stderr); 
+}
+]])],
+  [octave_cv_lib_qhull_ok=yes],
+  [octave_cv_lib_qhull_ok=no],
+  [octave_cv_lib_qhull_ok=yes])
+  LIBS="$save_LIBS"
+])
+if test "$octave_cv_lib_qhull_ok" = "yes"; then
+  AC_MSG_RESULT(yes)
+  ifelse([$1], , , [$1])
+else
+  AC_MSG_RESULT(no)
+  ifelse([$2], , , [$2])
+fi
+])
+dnl
+dnl Check for OpenGL. If found, define OPENGL_LIBS
+dnl
+AC_DEFUN([OCTAVE_OPENGL], [
+OPENGL_LIBS=
+
+### On MacOSX systems the OpenGL framework can be used
+OCTAVE_HAVE_FRAMEWORK(OpenGL, [
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h> ], [GLint par; glGetIntegerv (GL_VIEWPORT, &par);],
+  [have_framework_opengl="yes"], [have_framework_opengl="no"])
+
+if test $have_framework_opengl = "yes"; then
+  AC_DEFINE(HAVE_FRAMEWORK_OPENGL, 1, [Define if framework OPENGL is available.])
+  OPENGL_LIBS="-Wl,-framework -Wl,OpenGL"
+  AC_MSG_NOTICE([adding -Wl,-framework -Wl,OpenGL to OPENGL_LIBS])
+  OCTAVE_GLUTESSCALLBACK_THREEDOTS
+else
+  case $canonical_host_type in
+    *-*-mingw32* | *-*-msdosmsvc)
+      AC_CHECK_HEADERS(windows.h)
+    ;;
+  esac
+  have_opengl_incs=no
+  AC_CHECK_HEADERS([GL/gl.h OpenGL/gl.h], [
+    AC_CHECK_HEADERS([GL/glu.h OpenGL/glu.h], [
+      have_opengl_incs=yes; break], [], [
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+    ])
+    break
+    ], [], [
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+    ])
+
+  if test "$have_opengl_incs" = "yes"; then
+    case $canonical_host_type in
+      *-*-mingw32* | *-*-msdosmsvc)
+        save_LIBS="$LIBS"
+        LIBS="$LIBS -lopengl32"
+        AC_MSG_CHECKING([for glEnable in -lopengl32])
+        AC_TRY_LINK([
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if defined (HAVE_GL_GL_H)
+#include <GL/gl.h>
+#elif defined (HAVE_OPENGL_GL_H)
+#include <OpenGL/gl.h>
+#endif
+], [glEnable(GL_SMOOTH);], OPENGL_LIBS="-lopengl32 -lglu32")
+        LIBS="$save_LIBS"
+        if test "x$OPENGL_LIBS" != "x"; then
+          AC_MSG_RESULT(yes)
+        else
+          AC_MSG_RESULT(no)
+        fi
+        ;;
+      *)
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -L/usr/X11R6/lib"
+        AC_CHECK_LIB(GL, glEnable, OPENGL_LIBS="-L/usr/X11R6/lib -lGL -lGLU")
+        LDFLAGS="$save_LDFLAGS"
+        ;;
+    esac
+  fi
+fi
+AC_SUBST(OPENGL_LIBS)
+])
+dnl
+dnl See if function gluTessCallback is called with "(...)"
+dnl
+dnl OCTAVE_GLUTESSCALLBACK_THREEDOTS
+AC_DEFUN(OCTAVE_GLUTESSCALLBACK_THREEDOTS,
+[AC_CACHE_CHECK([whether gluTessCallback is called with "(...)"],
+octave_cv_glutesscallback_threedots,
+[AC_LANG_PUSH(C++)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_GL_GLU_H
+#include <GL/glu.h>
+#elif defined HAVE_OPENGL_GLU_H || defined HAVE_FRAMEWORK_OPENGL
+#include <OpenGL/glu.h>
+#endif]],
+[[GLvoid (*func)(...); gluTessCallback(0, 0, func);]])],
+octave_cv_glutesscallback_threedots="yes", octave_cv_glutesscallback_threedots="no")])
+AC_LANG_POP(C++)
+if test $octave_cv_glutesscallback_threedots = "yes"; then
+  AC_DEFINE(HAVE_GLUTESSCALLBACK_THREEDOTS, 1, 
+    [Define if gluTessCallback is called with (...)])
+fi
+])
+dnl
+dnl Configure paths for FreeType2
+dnl Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+dnl
+dnl Copyright 2001, 2003 by
+dnl David Turner, Robert Wilhelm, and Werner Lemberg.
+dnl
+dnl This file is part of the FreeType project, and may only be used, modified,
+dnl and distributed under the terms of the FreeType project license,
+dnl LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+dnl indicate that you have read the license and understand and accept it
+dnl fully.
+dnl
+dnl As a special exception to the FreeType project license, this file may be
+dnl distributed as part of a program that contains a configuration script
+dnl generated by Autoconf, under the same distribution terms as the rest of
+dnl that program.
+dnl
+dnl serial 2
+dnl
+dnl AC_CHECK_FT2([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for FreeType 2, and define FT2_CFLAGS and FT2_LIBS.
+dnl MINIMUM-VERSION is what libtool reports; the default is `7.0.1' (this is
+dnl FreeType 2.0.4).
+dnl
+AC_DEFUN([AC_CHECK_FT2],
+  [dnl Get the cflags and libraries from the freetype-config script
+   dnl
+   AC_ARG_WITH([ft-prefix],
+     dnl don't quote AS_HELP_STRING!
+     AS_HELP_STRING([--with-ft-prefix=PREFIX],
+                    [Prefix where FreeType is installed (optional)]),
+     [ft_config_prefix="$withval"],
+     [ft_config_prefix=""])
+  
+   AC_ARG_WITH([ft-exec-prefix],
+     dnl don't quote AS_HELP_STRING!
+     AS_HELP_STRING([--with-ft-exec-prefix=PREFIX],
+                    [Exec prefix where FreeType is installed (optional)]),
+     [ft_config_exec_prefix="$withval"],
+     [ft_config_exec_prefix=""])
+
+   AC_ARG_ENABLE([freetypetest],
+     dnl don't quote AS_HELP_STRING!
+     AS_HELP_STRING([--disable-freetypetest],
+                    [Do not try to compile and run a test FreeType program]),
+     [],
+     [enable_fttest=yes])
+
+   if test x$ft_config_exec_prefix != x ; then
+     ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix"
+     if test x${FT2_CONFIG+set} != xset ; then
+       FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config
+     fi
+   fi
+
+   if test x$ft_config_prefix != x ; then
+     ft_config_args="$ft_config_args --prefix=$ft_config_prefix"
+     if test x${FT2_CONFIG+set} != xset ; then
+       FT2_CONFIG=$ft_config_prefix/bin/freetype-config
+     fi
+   fi
+
+   AC_PATH_PROG([FT2_CONFIG], [freetype-config], [no])
+
+   min_ft_version=m4_if([$1], [], [7.0.1], [$1])
+   AC_MSG_CHECKING([for FreeType -- version >= $min_ft_version])
+   no_ft=""
+   if test "$FT2_CONFIG" = "no" ; then
+     no_ft=yes
+   else
+     FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags`
+     FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs`
+     ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+     ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+     ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+     ft_min_major_version=`echo $min_ft_version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+     ft_min_minor_version=`echo $min_ft_version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+     ft_min_micro_version=`echo $min_ft_version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+     if test x$enable_fttest = xyes ; then
+       ft_config_is_lt=""
+       if test $ft_config_major_version -lt $ft_min_major_version ; then
+         ft_config_is_lt=yes
+       else
+         if test $ft_config_major_version -eq $ft_min_major_version ; then
+           if test $ft_config_minor_version -lt $ft_min_minor_version ; then
+             ft_config_is_lt=yes
+           else
+            if test $ft_config_minor_version -eq $ft_min_minor_version ; then
+               if test $ft_config_micro_version -lt $ft_min_micro_version ; then
+                 ft_config_is_lt=yes
+               fi
+             fi
+           fi
+         fi
+       fi
+       if test x$ft_config_is_lt = xyes ; then
+         no_ft=yes
+       else
+         ac_save_CFLAGS="$CFLAGS"
+         ac_save_LIBS="$LIBS"
+         CFLAGS="$CFLAGS $FT2_CFLAGS"
+         LIBS="$FT2_LIBS $LIBS"
+
+         dnl
+         dnl Sanity checks for the results of freetype-config to some extent.
+         dnl
+         AC_RUN_IFELSE([
+             AC_LANG_SOURCE([[
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main()
+{
+  FT_Library library;
+  FT_Error  error;
+
+  error = FT_Init_FreeType(&library);
+
+  if (error)
+    return 1;
+  else
+  {
+    FT_Done_FreeType(library);
+    return 0;
+  }
+}
+
+             ]])
+           ],
+           [],
+           [no_ft=yes],
+           [echo $ECHO_N "cross compiling; assuming OK... $ECHO_C"])
+
+         CFLAGS="$ac_save_CFLAGS"
+         LIBS="$ac_save_LIBS"
+       fi             dnl test $ft_config_version -lt $ft_min_version
+     fi               dnl test x$enable_fttest = xyes
+   fi                 dnl test "$FT2_CONFIG" = "no"
+
+   if test x$no_ft = x ; then
+     AC_MSG_RESULT([yes])
+     m4_if([$2], [], [:], [$2])
+   else
+     AC_MSG_RESULT([no])
+     if test "$FT2_CONFIG" = "no" ; then
+       AC_MSG_WARN([
+
+  The freetype-config script installed by FreeType 2 could not be found.
+  If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in
+  your path, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+       ])
+     else
+       if test x$ft_config_is_lt = xyes ; then
+         AC_MSG_WARN([
+
+  Your installed version of the FreeType 2 library is too old.
+  If you have different versions of FreeType 2, make sure that
+  correct values for --with-ft-prefix or --with-ft-exec-prefix
+  are used, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+         ])
+       else
+         AC_MSG_WARN([
+
+  The FreeType test program failed to run.  If your system uses
+  shared libraries and they are installed outside the normal
+  system library path, make sure the variable LD_LIBRARY_PATH
+  (or whatever is appropiate for your system) is correctly set.
+         ])
+       fi
+     fi
+
+     FT2_CFLAGS=""
+     FT2_LIBS=""
+     m4_if([$3], [], [:], [$3])
+   fi
+
+   AC_SUBST([FT2_CFLAGS])
+   AC_SUBST([FT2_LIBS])])
+dnl end of freetype2.m4
+
+dnl Check whether a math mapper function is available in <cmath>.
+dnl Will define HAVE_CMATH_FUNC if there is a double variant and
+dnl HAVE_CMATH_FUNCF if there is a float variant.
+dnl Currently capable of checking for functions with single 
+dnl argument and returning bool/int/real.
+AC_DEFUN([OCTAVE_CMATH_FUNC],[
+AC_MSG_CHECKING([for std::$1 in <cmath>])
+AC_LANG_PUSH(C++)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <cmath>
+void take_func (bool (*func) (double x));
+void take_func (int (*func) (double x));
+void take_func (double (*func) (double x));
+]],
+[[
+take_func(std::$1);
+]])],
+[AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_CMATH_[]AS_TR_CPP($1),1,[Define if <cmath> provides $1])],
+[AC_MSG_RESULT([no])])
+AC_MSG_CHECKING([for std::$1 (float variant) in <cmath>])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <cmath>
+void take_func (bool (*func) (float x));
+void take_func (int (*func) (float x));
+void take_func (float (*func) (float x));
+]],
+[[
+take_func(std::$1);
+]])],
+[AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_CMATH_[]AS_TR_CPP($1)F,1,[Define if <cmath> provides float variant of $1])],
+[AC_MSG_RESULT([no])])
+AC_LANG_POP(C++)
+])
+
+dnl Check whether fast signed integer arithmetics using bit tricks
+dnl can be used in oct-inttypes.h. Defines HAVE_FAST_INT_OPS if
+dnl the following conditions hold:
+dnl 1. Signed numbers are represented by twos complement
+dnl    (see <http://en.wikipedia.org/wiki/Two%27s_complement>)
+dnl 2. static_cast to unsigned int counterpart works like interpreting
+dnl    the signed bit pattern as unsigned (and is thus zero-cost).
+dnl 3. Signed addition and subtraction yield the same bit results as unsigned.
+dnl    (We use casts to prevent optimization interference, so there is no
+dnl     need for things like -ftrapv).
+dnl 4. Bit operations on signed integers work like on unsigned integers,
+dnl    except for the shifts. Shifts are arithmetic.
+dnl
+AC_DEFUN([OCTAVE_FAST_INT_OPS],[
+AC_MSG_CHECKING([whether fast integer arithmetics is usable])
+AC_LANG_PUSH(C++)
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <limits>
+template<class UT, class ST>
+static bool 
+do_test (UT, ST)
+{
+  volatile ST s = std::numeric_limits<ST>::min () / 3;
+  volatile UT u = static_cast<UT> (s);
+  if (*(reinterpret_cast<volatile ST *> (&u)) != s) return true;
+  
+  u = 0; u = ~u;
+  if (*(reinterpret_cast<volatile ST *> (&u)) != -1) return true;
+  
+  ST sx, sy;
+  sx = std::numeric_limits<ST>::max () / 2 + 1;
+  sy = std::numeric_limits<ST>::max () / 2 + 2;
+  if (static_cast<ST> (static_cast<UT> (sx) + static_cast<UT> (sy))
+      != std::numeric_limits<ST>::min () + 1) return true;
+  if (static_cast<ST> (static_cast<UT> (sx) - static_cast<UT> (sy))
+      != -1) return true;
+  
+  if ((sx & sy) != (static_cast<UT> (sx) & static_cast<UT> (sy)))
+    return true;
+  if ((sx | sy) != (static_cast<UT> (sx) | static_cast<UT> (sy)))
+    return true;
+  if ((sx ^ sy) != (static_cast<UT> (sx) ^ static_cast<UT> (sy)))
+    return true;
+  if ((-1 >> 1) != -1) return true;
+  return false;
+}
+
+#define DO_TEST(T) \
+if (do_test (static_cast<unsigned T> (0), static_cast<signed T> (0))) \
+  return sizeof (T);
+]],[[
+  DO_TEST(char)
+  DO_TEST(short)
+  DO_TEST(int)
+  DO_TEST(long)
+#if (defined(HAVE_LONG_LONG_INT) && defined(HAVE_UNSIGNED_LONG_LONG_INT))
+  DO_TEST(long long)
+#endif
+]])],
+[AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_FAST_INT_OPS,1,[Define if signed integers use two's complement])],
+[AC_MSG_RESULT([no])])
+AC_LANG_POP(C++)])
+dnl
+dnl Check to see if the compiler and the linker can handle the flags
+dnl "-framework $1" for the given prologue $2 and the given body $3 of
+dnl a source file.  Arguments 2 and 3 optionally can also be empty.
+dnl Add options (lower case letters $1) "--with-framework-$1" and
+dnl "--without-framework-$1". If this test is successful then perform
+dnl $4, otherwise do $5.
+dnl
+dnl OCTAVE_HAVE_FRAMEWORK
+AC_DEFUN(OCTAVE_HAVE_FRAMEWORK, [
+  AC_MSG_CHECKING(whether ${LD-ld} accepts -framework $1)
+  AC_CACHE_VAL(octave_cv_framework_$1, [
+    XLDFLAGS="$LDFLAGS"
+    LDFLAGS="$LDFLAGS -framework $1"
+    AC_LANG_PUSH(C++)
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([$2], [$3])],
+      eval "octave_cv_framework_$1=yes",
+      eval "octave_cv_framework_$1=no")
+    AC_LANG_POP(C++)
+    LDFLAGS="$XLDFLAGS"
+  ])
+  if test "$octave_cv_framework_$1" = "yes"; then
+    AC_MSG_RESULT(yes)
+    AC_ARG_WITH(framework-m4_tolower($1),
+      [AS_HELP_STRING([--without-framework-m4_tolower($1)], 
+        [don't use framework $1])],
+         with_have_framework=$withval, with_have_framework="yes")
+    if test "$with_have_framework" = "yes"; then
+      [$4]
+    else
+      AC_MSG_NOTICE([framework rejected by --without-framework-m4_tolower($1)])
+      [$5]
+    fi
+  else
+    AC_MSG_RESULT(no)
+    [$5]
+  fi
+])
+dnl
+dnl Do we have a working c99 vsnprintf function?
+dnl
+dnl OCTAVE_HAVE_C99_VSNPRINTF
+AC_DEFUN(OCTAVE_HAVE_C99_VSNPRINTF, [
+  AC_CACHE_CHECK([for c99 vsnprintf], [oct_cv_c99_vsnprintf],
+    [AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+int
+doit(char * s, ...)
+{
+  char buffer[32];
+  va_list args;
+  int r;
+
+  va_start(args, s);
+  r = vsnprintf(buffer, 5, s, args);
+  va_end(args);
+
+  if (r != 7)
+    exit(1);
+
+  exit(0);
+}
+  ]],[
+doit("1234567");])],
+  [oct_cv_c99_vsnprintf=yes],
+  [oct_cv_c99_vsnprintf=no],
+  [oct_cv_c99_vsnprintf="guessing no"])])
+
+case $oct_cv_c99_vsnprintf in
+yes)
+    AC_DEFINE([HAVE_C99_VSNPRINTF], [1], [Define if you have a c99 vsnprintf])
+  ;;
+esac
+])
diff --git a/acx_blas.m4 b/acx_blas.m4
new file mode 100644
index 0000000..e80c7e8
--- /dev/null
+++ b/acx_blas.m4
@@ -0,0 +1,169 @@
+dnl @synopsis ACX_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl This macro looks for a library that implements the BLAS
+dnl linear-algebra interface (see http://www.netlib.org/blas/).
+dnl On success, it sets the BLAS_LIBS output variable to
+dnl hold the requisite library linkages.
+dnl
+dnl To link with BLAS, you should link with:
+dnl
+dnl 	$BLAS_LIBS $LIBS $FLIBS
+dnl
+dnl in that order.  FLIBS is the output variable of the
+dnl AC_F77_LIBRARY_LDFLAGS macro (called if necessary by ACX_BLAS),
+dnl and is sometimes necessary in order to link with F77 libraries.
+dnl Users will also need to use AC_F77_DUMMY_MAIN (see the autoconf
+dnl manual), for the same reason.
+dnl
+dnl Many libraries are searched for, from ATLAS to CXML to ESSL.
+dnl The user may also use --with-blas=<lib> in order to use some
+dnl specific BLAS library <lib>.  In order to link successfully,
+dnl however, be aware that you will probably need to use the same
+dnl Fortran compiler (which can be set via the F77 env. var.) as
+dnl was used to compile the BLAS library.
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a BLAS
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands
+dnl to run it if it is not found.  If ACTION-IF-FOUND is not specified,
+dnl the default action will define HAVE_BLAS.
+dnl
+dnl This macro requires autoconf 2.50 or later.
+dnl
+dnl @version $Id: acx_blas.m4,v 1.2 2001/12/13 01:03:06 simons Exp $
+dnl @author Steven G. Johnson <stevenj at alum.mit.edu>
+dnl
+AC_DEFUN([ACX_BLAS], [
+AC_PREREQ(2.50)
+AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])
+acx_blas_ok=no
+
+AC_ARG_WITH(blas,
+	[AS_HELP_STRING([--with-blas=<lib>], [use BLAS library <lib>])])
+case $with_blas in
+	yes | "") ;;
+	no) acx_blas_ok=disable ;;
+	-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;;
+	*) BLAS_LIBS="-l$with_blas" ;;
+esac
+
+# Get fortran linker names of BLAS functions to check for.
+if $have_fortran_compiler; then 
+  AC_F77_FUNC(sgemm)
+  AC_F77_FUNC(dgemm)
+elif $have_f2c; then
+  sgemm=sgemm_
+  dgemm=dgemm_
+fi
+
+acx_blas_save_LIBS="$LIBS"
+LIBS="$LIBS $FLIBS"
+
+# First, check BLAS_LIBS environment variable
+if test $acx_blas_ok = no; then
+if test "x$BLAS_LIBS" != x; then
+	save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
+	AC_MSG_CHECKING([for $sgemm in $BLAS_LIBS])
+	AC_LINK_IFELSE([AC_LANG_CALL([], [$sgemm])],
+		       [acx_blas_ok=yes], [BLAS_LIBS=""])
+	AC_MSG_RESULT($acx_blas_ok)
+	LIBS="$save_LIBS"
+fi
+fi
+
+# BLAS linked to by default?  (happens on some supercomputers)
+if test $acx_blas_ok = no; then
+	save_LIBS="$LIBS"; LIBS="$LIBS"
+	AC_CHECK_FUNC($sgemm, [acx_blas_ok=yes])
+	LIBS="$save_LIBS"
+fi
+
+# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(atlas, ATL_xerbla,
+		[AC_CHECK_LIB(f77blas, $sgemm,
+		[AC_CHECK_LIB(cblas, cblas_dgemm,
+			[acx_blas_ok=yes
+			 BLAS_LIBS="-lcblas -lf77blas -latlas"],
+			[], [-lf77blas -latlas])],
+			[], [-latlas])])
+fi
+
+# BLAS in Apple vecLib framework? (Mac OS X)
+if test $acx_blas_ok = no; then
+	vlib_flags="-Wl,-framework -Wl,vecLib"
+	save_LIBS="$LIBS"; LIBS="$vlib_flags $LIBS"
+	AC_MSG_CHECKING([for $sgemm in $vlib_flags])
+	AC_LINK_IFELSE([AC_LANG_CALL([], [$sgemm])],
+                       [acx_blas_ok=yes; BLAS_LIBS="$vlib_flags"],
+		       [BLAS_LIBS=""])
+	AC_MSG_RESULT($acx_blas_ok)
+	LIBS="$save_LIBS"
+fi
+
+# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(blas, $sgemm,
+		[AC_CHECK_LIB(dgemm, $dgemm,
+		[AC_CHECK_LIB(sgemm, $sgemm,
+			[acx_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"],
+			[], [-lblas])],
+			[], [-lblas])])
+fi
+
+# BLAS in Alpha CXML library?
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(cxml, $sgemm, [acx_blas_ok=yes;BLAS_LIBS="-lcxml"])
+fi
+
+# BLAS in Alpha DXML library? (now called CXML, see above)
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(dxml, $sgemm, [acx_blas_ok=yes;BLAS_LIBS="-ldxml"])
+fi
+
+# BLAS in Sun Performance library?
+if test $acx_blas_ok = no; then
+	if test "x$GCC" != xyes; then # only works with Sun CC
+		AC_CHECK_LIB(sunmath, acosp,
+			[AC_CHECK_LIB(sunperf, $sgemm,
+        			[BLAS_LIBS="-lsunperf -lsunmath"
+                                 acx_blas_ok=yes],[],[-lsunmath])])
+	fi
+fi
+
+# BLAS in SCSL library?  (SGI/Cray Scientific Library)
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(scs, $sgemm, [acx_blas_ok=yes; BLAS_LIBS="-lscs"])
+fi
+
+# BLAS in SGIMATH library?
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(complib.sgimath, $sgemm,
+		     [acx_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"])
+fi
+
+# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(blas, $sgemm,
+		[AC_CHECK_LIB(essl, $sgemm,
+			[acx_blas_ok=yes; BLAS_LIBS="-lessl -lblas"],
+			[], [-lblas $FLIBS])])
+fi
+
+# Generic BLAS library?
+if test $acx_blas_ok = no; then
+	AC_CHECK_LIB(blas, $sgemm, [acx_blas_ok=yes; BLAS_LIBS="-lblas"])
+fi
+
+AC_SUBST(BLAS_LIBS)
+
+LIBS="$acx_blas_save_LIBS"
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_blas_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_BLAS,1,[Define if you have a BLAS library.]),[$1])
+        :
+else
+        acx_blas_ok=no
+        $2
+fi
+])dnl ACX_BLAS
diff --git a/acx_blas_f77_func.m4 b/acx_blas_f77_func.m4
new file mode 100644
index 0000000..4e74db9
--- /dev/null
+++ b/acx_blas_f77_func.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+#           http://autoconf-archive.cryp.to/acx_blas_f77_func.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_BLAS_F77_FUNC([ACTION-IF-PASS[, ACTION-IF-FAIL[, ACTION-IF-CROSS-COMPILING]])
+#   ACX_BLAS_WITH_F77_FUNC([ACTION-IF-FOUND-AND-PASS[, ACTION-IF-NOT-FOUND-OR-FAIL]])
+#
+# DESCRIPTION
+#
+#   These macros are intended as a supplement to the ACX_BLAS macro, to
+#   verify that BLAS functions are properly callable from Fortran. This is
+#   necessary, for example, if you want to build the LAPACK library on top
+#   of the BLAS.
+#
+#   ACX_BLAS_F77_FUNC uses the defined BLAS_LIBS and Fortran environment to
+#   check for compatibility, and takes a specific action in case of success,
+#   resp. failure, resp. cross-compilation.
+#
+#   ACX_BLAS_WITH_F77_FUNC is a drop-in replacement wrapper for ACX_BLAS
+#   that calls ACX_BLAS_F77_FUNC after detecting a BLAS library and rejects
+#   it on failure (i.e. pretends that no library was found).
+#
+# LAST MODIFICATION
+#
+#   2008-06-18
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Jaroslav Hajek <highegg at gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([ACX_BLAS_F77_FUNC], [
+AC_PREREQ(2.50)
+AC_REQUIRE([ACX_BLAS])
+
+# F77 call-compatibility checks
+if test "$cross_compiling" = yes ; then
+	ifelse($3, ,$1,$3)
+elif test x"$acx_blas_ok" = xyes; then
+	save_acx_blas_f77_func_LIBS="$LIBS"
+	LIBS="$BLAS_LIBS $LIBS"
+	AC_LANG_PUSH(Fortran 77)
+# LSAME check (LOGICAL return values)
+	AC_MSG_CHECKING([whether LSAME is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
+      logical lsame,w
+      external lsame
+      character c1,c2
+      c1 = 'A'
+      c2 = 'B'
+      w = lsame(c1,c2)
+      if (w) stop 1
+      w = lsame(c1,c1)
+      if (.not. w) stop 1
+      ]]),[acx_blas_lsame_fcall_ok=yes],
+	[acx_blas_lsame_fcall_ok=no])
+	AC_MSG_RESULT([$acx_blas_lsame_fcall_ok])
+# ISAMAX check (INTEGER return values)
+	AC_MSG_CHECKING([whether ISAMAX is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
+      integer isamax,i
+      external isamax
+      real a(2)
+      a(1) = 1e0
+      a(2) = -2e0
+      i = isamax(2,a,1)
+      if (i.ne.2) stop 1
+      ]]),[acx_blas_isamax_fcall_ok=yes],
+	[acx_blas_isamax_fcall_ok=no])
+	AC_MSG_RESULT([$acx_blas_isamax_fcall_ok])
+# SDOT check (REAL return values)
+	AC_MSG_CHECKING([whether SDOT is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
+      real sdot,a(1),b(1),w
+      external sdot
+      a(1) = 1e0
+      b(1) = 2e0
+      w = sdot(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+      ]]),[acx_blas_sdot_fcall_ok=yes],
+	[acx_blas_sdot_fcall_ok=no])
+	AC_MSG_RESULT([$acx_blas_sdot_fcall_ok])
+# DDOT check (DOUBLE return values)
+	AC_MSG_CHECKING([whether DDOT is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
+      double precision ddot,a(1),b(1),w
+      external ddot
+      a(1) = 1d0
+      b(1) = 2d0
+      w = ddot(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+      ]]),[acx_blas_ddot_fcall_ok=yes],
+	[acx_blas_ddot_fcall_ok=no])
+	AC_MSG_RESULT([$acx_blas_ddot_fcall_ok])
+# CDOTU check (COMPLEX return values)
+	AC_MSG_CHECKING([whether CDOTU is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
+      complex cdotu,a(1),b(1),w
+      external cdotu
+      a(1) = cmplx(1e0,1e0)
+      b(1) = cmplx(1e0,2e0)
+      w = cdotu(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+      ]]),[acx_blas_cdotu_fcall_ok=yes],
+	[acx_blas_cdotu_fcall_ok=no])
+	AC_MSG_RESULT([$acx_blas_cdotu_fcall_ok])
+# ZDOTU check (DOUBLE COMPLEX return values)
+	AC_MSG_CHECKING([whether ZDOTU is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
+      double complex zdotu,a(1),b(1),w
+      external zdotu
+      a(1) = dcmplx(1d0,1d0)
+      b(1) = dcmplx(1d0,2d0)
+      w = zdotu(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+      ]]),[acx_blas_zdotu_fcall_ok=yes],
+	[acx_blas_zdotu_fcall_ok=no])
+	AC_MSG_RESULT([$acx_blas_zdotu_fcall_ok])
+
+	AC_LANG_POP(Fortran 77)
+
+# if any of the tests failed, reject the BLAS library
+	if test $acx_blas_lsame_fcall_ok = yes \
+		-a $acx_blas_sdot_fcall_ok = yes \
+		-a $acx_blas_ddot_fcall_ok = yes \
+		-a $acx_blas_cdotu_fcall_ok = yes \
+		-a $acx_blas_zdotu_fcall_ok = yes ; then
+		acx_blas_f77_func_ok=yes;
+		$1
+	else
+		acx_blas_f77_func_ok=no;
+		$2
+	fi
+	LIBS="$save_acx_blas_f77_func_LIBS"
+fi
+
+])dnl ACX_BLAS_F77_FUNC
+
+AC_DEFUN([ACX_BLAS_WITH_F77_FUNC], [
+AC_PREREQ(2.50)
+ACX_BLAS([# disable special action], [])
+if test x$acx_blas_ok = xyes ; then
+	ACX_BLAS_F77_FUNC(
+	[ifelse([$1],,AC_DEFINE(HAVE_BLAS,1,[Define if you have a BLAS library.]),[$1])],
+	[acx_blas_ok=no; BLAS_LIBS=])
+fi
+if test x$acx_blas_ok = xno ; then
+	$2
+fi
+])dnl ACX_BLAS_WITH_F77_FUNC
diff --git a/acx_lapack.m4 b/acx_lapack.m4
new file mode 100644
index 0000000..d03751a
--- /dev/null
+++ b/acx_lapack.m4
@@ -0,0 +1,132 @@
+# ===========================================================================
+#               http://autoconf-archive.cryp.to/acx_lapack.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_LAPACK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the LAPACK linear-algebra
+#   interface (see http://www.netlib.org/lapack/). On success, it sets the
+#   LAPACK_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with LAPACK, you should link with:
+#
+#       $LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. BLAS_LIBS is the output variable of the ACX_BLAS macro,
+#   called automatically. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by ACX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   The user may also use --with-lapack=<lib> in order to use some specific
+#   LAPACK library <lib>. In order to link successfully, however, be aware
+#   that you will probably need to use the same Fortran compiler (which can
+#   be set via the F77 env. var.) as was used to compile the LAPACK and BLAS
+#   libraries.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a LAPACK library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_LAPACK.
+#
+# LAST MODIFICATION
+#
+#   2008-06-29
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([ACX_LAPACK], [
+AC_REQUIRE([ACX_BLAS])
+acx_lapack_ok=no
+
+AC_ARG_WITH(lapack,
+        [AC_HELP_STRING([--with-lapack=<lib>], [use LAPACK library <lib>])])
+case $with_lapack in
+        yes | "") ;;
+        no) acx_lapack_ok=disable ;;
+        -* | */* | *.a | *.so | *.so.* | *.o) LAPACK_LIBS="$with_lapack" ;;
+        *) LAPACK_LIBS="-l$with_lapack" ;;
+esac
+
+# Get fortran linker name of LAPACK function to check for.
+AC_F77_FUNC(cheev)
+
+# We cannot use LAPACK if BLAS is not found
+if test "x$acx_blas_ok" != xyes; then
+        acx_lapack_ok=noblas
+        LAPACK_LIBS=""
+fi
+
+# First, check LAPACK_LIBS environment variable
+if test "x$LAPACK_LIBS" != x; then
+        save_LIBS="$LIBS"; LIBS="$LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS"
+        AC_MSG_CHECKING([for $cheev in $LAPACK_LIBS])
+        AC_TRY_LINK_FUNC($cheev, [acx_lapack_ok=yes], [LAPACK_LIBS=""])
+        AC_MSG_RESULT($acx_lapack_ok)
+        LIBS="$save_LIBS"
+        if test $acx_lapack_ok = no; then
+                LAPACK_LIBS=""
+        fi
+fi
+
+# LAPACK linked to by default?  (is sometimes included in BLAS lib)
+if test $acx_lapack_ok = no; then
+        save_LIBS="$LIBS"; LIBS="$LIBS $BLAS_LIBS $FLIBS"
+        AC_CHECK_FUNC($cheev, [acx_lapack_ok=yes])
+        LIBS="$save_LIBS"
+fi
+
+# Generic LAPACK library?
+for lapack in lapack lapack_rs6k; do
+        if test $acx_lapack_ok = no; then
+                save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
+                AC_CHECK_LIB($lapack, $cheev,
+                    [acx_lapack_ok=yes; LAPACK_LIBS="-l$lapack"], [], [$FLIBS])
+                LIBS="$save_LIBS"
+        fi
+done
+
+AC_SUBST(LAPACK_LIBS)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_lapack_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_LAPACK,1,[Define if you have LAPACK library.]),[$1])
+        :
+else
+        acx_lapack_ok=no
+        $2
+fi
+])dnl ACX_LAPACK
diff --git a/acx_pthread.m4 b/acx_pthread.m4
new file mode 100644
index 0000000..798d6d1
--- /dev/null
+++ b/acx_pthread.m4
@@ -0,0 +1,271 @@
+# ===========================================================================
+#           http://www.nongnu.org/autoconf-archive/acx_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#          LIBS="$PTHREAD_LIBS $LIBS"
+#          CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#          CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_MSG_CHECKING([for joinable pthread attribute])
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+	done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+	fi
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..e5742c8
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,41 @@
+#! /bin/sh
+# autogen.sh
+# Run this to generate all the initial makefiles, etc.
+
+# copied from the accelerated glx project
+
+echo "calling autoconf and autoheader..."
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+	echo
+        echo "You must have autoconf installed to build Octave."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+        exit 1
+}
+
+(autoheader --version) < /dev/null > /dev/null 2>&1 || {
+	echo
+        echo "You must have autoheader installed to build Octave."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+        exit 1
+}
+
+for i in `find . -name configure.in -print`; do (
+    dir=`dirname $i`
+    cd $dir
+    pwd
+    if [ -f skip-autoconf ]; then
+      echo "skipping autoconf in $dir"
+    else
+      autoconf --force
+    fi
+    if [ -f skip-autoheader ]; then
+      echo "skipping autoheader in $dir"
+    else
+      autoheader --force
+    fi
+); done
+
+echo done
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..7b24a87
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1542 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
+
+timestamp='2008-11-15'
+
+# This file is free software; you can 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if echo '\n#ifdef __amd64\nIS_64BIT_ARCH\n#endif' | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:[3456]*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    EM64T | authenticamd | genuineintel)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..64c1c0c
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,1260 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to use internal bounds checking. */
+#undef BOUNDS_CHECKING
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#undef CLOSEDIR_VOID
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define if C++ reinterpret_cast fails for function pointers. */
+#undef CXX_BROKEN_REINTERPRET_CAST
+
+/* Define if your C++ runtime library is ISO compliant. */
+#undef CXX_ISO_COMPLIANT_LIBRARY
+
+/* Define if your compiler supports `<>' stuff for template friends. */
+#undef CXX_NEW_FRIEND_TEMPLATE_DECL
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define if using dynamic linking */
+#undef ENABLE_DYNAMIC_LINKING
+
+/* Define if your math.h declares struct exception for matherr(). */
+#undef EXCEPTION_IN_MATH
+
+/* Define to dummy `main' function (if any) required to link to the Fortran
+   libraries. */
+#undef F77_DUMMY_MAIN
+
+/* Define to a macro mangling the given C identifier (in lower and upper
+   case), which must not contain underscores, for linking with Fortran. */
+#undef F77_FUNC
+
+/* As F77_FUNC, but for C identifiers containing underscores. */
+#undef F77_FUNC_
+
+/* Define if F77 and FC dummy `main' functions are identical. */
+#undef FC_DUMMY_MAIN_EQ_F77
+
+/* Define if your system has a single-arg prototype for gettimeofday. */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* Define if GLPK version is less than 4.14. */
+#undef GLPK_PRE_4_14
+
+/* Define to 1 if you have the `acosh' function. */
+#undef HAVE_ACOSH
+
+/* Define to 1 if you have the `acoshf' function. */
+#undef HAVE_ACOSHF
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define if the AMD library is used. */
+#undef HAVE_AMD
+
+/* Define to 1 if you have the <amd/amd.h> header file. */
+#undef HAVE_AMD_AMD_H
+
+/* Define to 1 if you have the <amd.h> header file. */
+#undef HAVE_AMD_H
+
+/* Define if the ARPACK library is used. */
+#undef HAVE_ARPACK
+
+/* Define to 1 if you have the `asinh' function. */
+#undef HAVE_ASINH
+
+/* Define to 1 if you have the `asinhf' function. */
+#undef HAVE_ASINHF
+
+/* Define to 1 if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define to 1 if you have the `atanh' function. */
+#undef HAVE_ATANH
+
+/* Define to 1 if you have the `atanhf' function. */
+#undef HAVE_ATANHF
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you have the `basename' function. */
+#undef HAVE_BASENAME
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define if you have a BLAS library. */
+#undef HAVE_BLAS
+
+/* Define if you have BSD style signals. */
+#undef HAVE_BSD_SIGNALS
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define if you have a c99 vsnprintf */
+#undef HAVE_C99_VSNPRINTF
+
+/* Define to 1 if you have the `canonicalize_file_name' function. */
+#undef HAVE_CANONICALIZE_FILE_NAME
+
+/* Define if the CCOLAMD library is used. */
+#undef HAVE_CCOLAMD
+
+/* Define to 1 if you have the <ccolamd/ccolamd.h> header file. */
+#undef HAVE_CCOLAMD_CCOLAMD_H
+
+/* Define to 1 if you have the <ccolamd.h> header file. */
+#undef HAVE_CCOLAMD_H
+
+/* Define to 1 if you have the `chmod' function. */
+#undef HAVE_CHMOD
+
+/* Define if the CHOLMOD library is used. */
+#undef HAVE_CHOLMOD
+
+/* Define to 1 if you have the <cholmod/cholmod.h> header file. */
+#undef HAVE_CHOLMOD_CHOLMOD_H
+
+/* Define to 1 if you have the <cholmod.h> header file. */
+#undef HAVE_CHOLMOD_H
+
+/* Define if <cmath> provides isfinite */
+#undef HAVE_CMATH_ISFINITE
+
+/* Define if <cmath> provides float variant of isfinite */
+#undef HAVE_CMATH_ISFINITEF
+
+/* Define if <cmath> provides isinf */
+#undef HAVE_CMATH_ISINF
+
+/* Define if <cmath> provides float variant of isinf */
+#undef HAVE_CMATH_ISINFF
+
+/* Define if <cmath> provides isnan */
+#undef HAVE_CMATH_ISNAN
+
+/* Define if <cmath> provides float variant of isnan */
+#undef HAVE_CMATH_ISNANF
+
+/* Define if the COLAMD library is used. */
+#undef HAVE_COLAMD
+
+/* Define to 1 if you have the <colamd/colamd.h> header file. */
+#undef HAVE_COLAMD_COLAMD_H
+
+/* Define to 1 if you have the <colamd.h> header file. */
+#undef HAVE_COLAMD_H
+
+/* Define to 1 if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define to 1 if you have the `copysign' function. */
+#undef HAVE_COPYSIGN
+
+/* Define to 1 if you have the <cs.h> header file. */
+#undef HAVE_CS_H
+
+/* Define if CURL is available. */
+#undef HAVE_CURL
+
+/* Define to 1 if you have the <curl/curl.h> header file. */
+#undef HAVE_CURL_CURL_H
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if the CXSparse library is used. */
+#undef HAVE_CXSPARSE
+
+/* Define to 1 if you have the <cxsparse/cs.h> header file. */
+#undef HAVE_CXSPARSE_CS_H
+
+/* Define to 1 if you have the declaration of `exp2', and to 0 if you don't.
+   */
+#undef HAVE_DECL_EXP2
+
+/* Define to 1 if you have the declaration of `round', and to 0 if you don't.
+   */
+#undef HAVE_DECL_ROUND
+
+/* Define to 1 if you have the declaration of `signbit', and to 0 if you
+   don't. */
+#undef HAVE_DECL_SIGNBIT
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+   don't. */
+#undef HAVE_DECL_SYS_SIGLIST
+
+/* Define to 1 if you have the declaration of `tgamma', and to 0 if you don't.
+   */
+#undef HAVE_DECL_TGAMMA
+
+/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
+   */
+#undef HAVE_DECL_TZNAME
+
+/* Define to 1 if the system has the type `dev_t'. */
+#undef HAVE_DEV_T
+
+/* Define to 1 if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the `dlclose' function. */
+#undef HAVE_DLCLOSE
+
+/* Define to 1 if you have the `dlerror' function. */
+#undef HAVE_DLERROR
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define if your system has dlopen, dlsym, dlerror, and dlclose for dynamic
+   linking */
+#undef HAVE_DLOPEN_API
+
+/* Define to 1 if you have the `dlsym' function. */
+#undef HAVE_DLSYM
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define if your system has dyld for dynamic linking */
+#undef HAVE_DYLD_API
+
+/* Define if C++ supports dynamic auto arrays */
+#undef HAVE_DYNAMIC_AUTO_ARRAYS
+
+/* Define to 1 if you have the `endgrent' function. */
+#undef HAVE_ENDGRENT
+
+/* Define to 1 if you have the `endpwent' function. */
+#undef HAVE_ENDPWENT
+
+/* Define to 1 if you have the `erf' function. */
+#undef HAVE_ERF
+
+/* Define to 1 if you have the `erfc' function. */
+#undef HAVE_ERFC
+
+/* Define to 1 if you have the `erfcf' function. */
+#undef HAVE_ERFCF
+
+/* Define to 1 if you have the `erff' function. */
+#undef HAVE_ERFF
+
+/* Define to 1 if you have the `execvp' function. */
+#undef HAVE_EXECVP
+
+/* Define to 1 if you have the `exp2' function. */
+#undef HAVE_EXP2
+
+/* Define to 1 if you have the `exp2f' function. */
+#undef HAVE_EXP2F
+
+/* Define to 1 if you have the `expm1' function. */
+#undef HAVE_EXPM1
+
+/* Define to 1 if you have the `expm1f' function. */
+#undef HAVE_EXPM1F
+
+/* Define if signed integers use two's complement */
+#undef HAVE_FAST_INT_OPS
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if the FFTW3 library is used. */
+#undef HAVE_FFTW3
+
+/* Define to 1 if you have the `finite' function. */
+#undef HAVE_FINITE
+
+/* Define to 1 if you have the <floatingpoint.h> header file. */
+#undef HAVE_FLOATINGPOINT_H
+
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* Define if FLTK is available */
+#undef HAVE_FLTK
+
+/* Define to 1 if you have the `fnmatch' function. */
+#undef HAVE_FNMATCH
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define if framework CARBON is available. */
+#undef HAVE_FRAMEWORK_CARBON
+
+/* Define if framework OPENGL is available. */
+#undef HAVE_FRAMEWORK_OPENGL
+
+/* Define to 1 if you have the `fstat' function. */
+#undef HAVE_FSTAT
+
+/* Define to 1 if FTGL is present */
+#undef HAVE_FTGL
+
+/* Define to 1 if you have the <FTGL/FTGL.h> header file. */
+#undef HAVE_FTGL_FTGL_H
+
+/* Define to 1 if you have the <FTGL.h> header file. */
+#undef HAVE_FTGL_H
+
+/* Define to 1 if you have FTGL.h or FTGL/FTGL.h */
+#undef HAVE_FTGL_UPPERCASE
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getegid' function. */
+#undef HAVE_GETEGID
+
+/* Define to 1 if you have the `geteuid' function. */
+#undef HAVE_GETEUID
+
+/* Define to 1 if you have the `getgid' function. */
+#undef HAVE_GETGID
+
+/* Define to 1 if you have the `getgrent' function. */
+#undef HAVE_GETGRENT
+
+/* Define to 1 if you have the `getgrgid' function. */
+#undef HAVE_GETGRGID
+
+/* Define to 1 if you have the `getgrnam' function. */
+#undef HAVE_GETGRNAM
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the `getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the `getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the `getppid' function. */
+#undef HAVE_GETPPID
+
+/* Define to 1 if you have the `getpwent' function. */
+#undef HAVE_GETPWENT
+
+/* Define to 1 if you have the `getpwnam' function. */
+#undef HAVE_GETPWNAM
+
+/* Define to 1 if you have the `getpwuid' function. */
+#undef HAVE_GETPWUID
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `getuid' function. */
+#undef HAVE_GETUID
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the `glob' function. */
+#undef HAVE_GLOB
+
+/* Define to 1 if you have the <glob.h> header file. */
+#undef HAVE_GLOB_H
+
+/* Define if GLPK is available. */
+#undef HAVE_GLPK
+
+/* Define to 1 if you have the <glpk/glpk.h> header file. */
+#undef HAVE_GLPK_GLPK_H
+
+/* Define to 1 if you have the <glpk.h> header file. */
+#undef HAVE_GLPK_H
+
+/* Define if gluTessCallback is called with (...) */
+#undef HAVE_GLUTESSCALLBACK_THREEDOTS
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+#undef HAVE_GL_GLU_H
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+#undef HAVE_GL_GL_H
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if HDF5 has H5Gget_num_objs. */
+#undef HAVE_H5GGET_NUM_OBJS
+
+/* Define if HDF5 is available. */
+#undef HAVE_HDF5
+
+/* Define to 1 if you have the <hdf5.h> header file. */
+#undef HAVE_HDF5_H
+
+/* Define to 1 if you have the `hypotf' function. */
+#undef HAVE_HYPOTF
+
+/* Define if your system uses IEEE 754 data format. */
+#undef HAVE_IEEE754_DATA_FORMAT
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#undef HAVE_IEEEFP_H
+
+/* Define to 1 if the system has the type `ino_t'. */
+#undef HAVE_INO_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `isinf' function. */
+#undef HAVE_ISINF
+
+/* Define to 1 if you have the `isnan' function. */
+#undef HAVE_ISNAN
+
+/* Define to 1 if you have the `kill' function. */
+#undef HAVE_KILL
+
+/* Define if you have LAPACK library. */
+#undef HAVE_LAPACK
+
+/* Define to 1 if you have the `lgamma' function. */
+#undef HAVE_LGAMMA
+
+/* Define to 1 if you have the `lgammaf' function. */
+#undef HAVE_LGAMMAF
+
+/* Define to 1 if you have the `lgammaf_r' function. */
+#undef HAVE_LGAMMAF_R
+
+/* Define to 1 if you have the `lgamma_r' function. */
+#undef HAVE_LGAMMA_R
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the `sun' library (-lsun). */
+#undef HAVE_LIBSUN
+
+/* Define to 1 if you have the `wsock32' library (-lwsock32). */
+#undef HAVE_LIBWSOCK32
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the `link' function. */
+#undef HAVE_LINK
+
+/* Define to 1 if you have the `LoadLibrary' function. */
+#undef HAVE_LOADLIBRARY
+
+/* Define if your system has LoadLibrary for dynamic linking */
+#undef HAVE_LOADLIBRARY_API
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define to 1 if you have the `log1p' function. */
+#undef HAVE_LOG1P
+
+/* Define to 1 if you have the `log1pf' function. */
+#undef HAVE_LOG1PF
+
+/* Define to 1 if you have the `log2' function. */
+#undef HAVE_LOG2
+
+/* Define to 1 if you have the `log2f' function. */
+#undef HAVE_LOG2F
+
+/* Define to 1 if the system has the type `long long int'. */
+#undef HAVE_LONG_LONG_INT
+
+/* Define to 1 if you have the `lstat' function. */
+#undef HAVE_LSTAT
+
+/* Define if GraphicsMagick++ is available. */
+#undef HAVE_MAGICK
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have the `mkfifo' function. */
+#undef HAVE_MKFIFO
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define if mkstemps is available in libiberty. */
+#undef HAVE_MKSTEMPS
+
+/* Define to 1 if you have the <nan.h> header file. */
+#undef HAVE_NAN_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if the system has the type `nlink_t'. */
+#undef HAVE_NLINK_T
+
+/* Define to 1 if you have the `on_exit' function. */
+#undef HAVE_ON_EXIT
+
+/* Define if OpenGL is available */
+#undef HAVE_OPENGL
+
+/* Define to 1 if you have the <OpenGL/glu.h> header file. */
+#undef HAVE_OPENGL_GLU_H
+
+/* Define to 1 if you have the <OpenGL/gl.h> header file. */
+#undef HAVE_OPENGL_GL_H
+
+/* Define if PCRE library is available. */
+#undef HAVE_PCRE
+
+/* Define to 1 if you have the `pcre_compile' function. */
+#undef HAVE_PCRE_COMPILE
+
+/* Define to 1 if you have the `pipe' function. */
+#undef HAVE_PIPE
+
+/* Define if C++ supports operator delete(void *, void *) */
+#undef HAVE_PLACEMENT_DELETE
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define if you have POSIX style signals. */
+#undef HAVE_POSIX_SIGNALS
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if the QHull library is used. */
+#undef HAVE_QHULL
+
+/* Define if the qrupdate library is used. */
+#undef HAVE_QRUPDATE
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define if regex library is available. */
+#undef HAVE_REGEX
+
+/* Define to 1 if you have the `regexec' function. */
+#undef HAVE_REGEXEC
+
+/* Define to 1 if you have the `rename' function. */
+#undef HAVE_RENAME
+
+/* Define to 1 if you have the `resolvepath' function. */
+#undef HAVE_RESOLVEPATH
+
+/* Define to 1 if you have the `rindex' function. */
+#undef HAVE_RINDEX
+
+/* Define to 1 if you have the `rmdir' function. */
+#undef HAVE_RMDIR
+
+/* Define to 1 if you have the `round' function. */
+#undef HAVE_ROUND
+
+/* Define to 1 if you have the `roundl' function. */
+#undef HAVE_ROUNDL
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setgrent' function. */
+#undef HAVE_SETGRENT
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the `setpwent' function. */
+#undef HAVE_SETPWENT
+
+/* Define to 1 if you have the `setvbuf' function. */
+#undef HAVE_SETVBUF
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define to 1 if you have the `shl_findsym' function. */
+#undef HAVE_SHL_FINDSYM
+
+/* Define to 1 if you have the `shl_load' function. */
+#undef HAVE_SHL_LOAD
+
+/* Define if your system has shl_load and shl_findsym for dynamic linking */
+#undef HAVE_SHL_LOAD_API
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the `siglongjmp' function. */
+#undef HAVE_SIGLONGJMP
+
+/* Define to 1 if you have the `signbit' function. */
+#undef HAVE_SIGNBIT
+
+/* Define to 1 if you have the `sigpending' function. */
+#undef HAVE_SIGPENDING
+
+/* Define to 1 if you have the `sigprocmask' function. */
+#undef HAVE_SIGPROCMASK
+
+/* Define to 1 if the system has the type `sigset_t'. */
+#undef HAVE_SIGSET_T
+
+/* Define to 1 if you have the `sigsuspend' function. */
+#undef HAVE_SIGSUSPEND
+
+/* Define to 1 if the system has the type `sig_atomic_t'. */
+#undef HAVE_SIG_ATOMIC_T
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the <sstream> header file. */
+#undef HAVE_SSTREAM
+
+/* Define to 1 if you have the `stat' function. */
+#undef HAVE_STAT
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the `stricmp' function. */
+#undef HAVE_STRICMP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strnicmp' function. */
+#undef HAVE_STRNICMP
+
+/* Define to 1 if you have the `strptime' function. */
+#undef HAVE_STRPTIME
+
+/* Define to 1 if you have the `strsignal' function. */
+#undef HAVE_STRSIGNAL
+
+/* Define to 1 if `struct group' is a member of `gr_passwd'. */
+#undef HAVE_STRUCT_GROUP_GR_PASSWD
+
+/* Define to 1 if `struct stat' is a member of `st_blksize'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if `struct stat' is a member of `st_blocks'. */
+#undef HAVE_STRUCT_STAT_ST_BLOCKS
+
+/* Define to 1 if `struct stat' is a member of `st_rdev'. */
+#undef HAVE_STRUCT_STAT_ST_RDEV
+
+/* Define to 1 if `struct tm' is a member of `tm_zone'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if you have the <suitesparse/amd.h> header file. */
+#undef HAVE_SUITESPARSE_AMD_H
+
+/* Define to 1 if you have the <suitesparse/ccolamd.h> header file. */
+#undef HAVE_SUITESPARSE_CCOLAMD_H
+
+/* Define to 1 if you have the <suitesparse/cholmod.h> header file. */
+#undef HAVE_SUITESPARSE_CHOLMOD_H
+
+/* Define to 1 if you have the <suitesparse/colamd.h> header file. */
+#undef HAVE_SUITESPARSE_COLAMD_H
+
+/* Define to 1 if you have the <suitesparse/cs.h> header file. */
+#undef HAVE_SUITESPARSE_CS_H
+
+/* Define to 1 if you have the <suitesparse/umfpack.h> header file. */
+#undef HAVE_SUITESPARSE_UMFPACK_H
+
+/* Define to 1 if you have the <sunmath.h> header file. */
+#undef HAVE_SUNMATH_H
+
+/* Define to 1 if you have the `symlink' function. */
+#undef HAVE_SYMLINK
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#undef HAVE_SYS_POLL_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+#undef HAVE_SYS_UTIME_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `tempnam' function. */
+#undef HAVE_TEMPNAM
+
+/* Define to 1 if you have the <termcap.h> header file. */
+#undef HAVE_TERMCAP_H
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define to 1 if you have the `tgamma' function. */
+#undef HAVE_TGAMMA
+
+/* Define to 1 if you have the `tgammaf' function. */
+#undef HAVE_TGAMMAF
+
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
+
+/* Define if struct timeval is defined. */
+#undef HAVE_TIMEVAL
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+   `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the `trunc' function. */
+#undef HAVE_TRUNC
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+   `tzname'. */
+#undef HAVE_TZNAME
+
+/* Define to 1 if you have the <ufsparse/amd.h> header file. */
+#undef HAVE_UFSPARSE_AMD_H
+
+/* Define to 1 if you have the <ufsparse/ccolamd.h> header file. */
+#undef HAVE_UFSPARSE_CCOLAMD_H
+
+/* Define to 1 if you have the <ufsparse/cholmod.h> header file. */
+#undef HAVE_UFSPARSE_CHOLMOD_H
+
+/* Define to 1 if you have the <ufsparse/colamd.h> header file. */
+#undef HAVE_UFSPARSE_COLAMD_H
+
+/* Define to 1 if you have the <ufsparse/cs.h> header file. */
+#undef HAVE_UFSPARSE_CS_H
+
+/* Define to 1 if you have the <ufsparse/umfpack.h> header file. */
+#undef HAVE_UFSPARSE_UMFPACK_H
+
+/* Define to 1 if you have the `umask' function. */
+#undef HAVE_UMASK
+
+/* Define if the UMFPACK library is used. */
+#undef HAVE_UMFPACK
+
+/* Define to 1 if you have the <umfpack.h> header file. */
+#undef HAVE_UMFPACK_H
+
+/* Define to 1 if you have the <umfpack/umfpack.h> header file. */
+#undef HAVE_UMFPACK_UMFPACK_H
+
+/* Define to 1 if you have the `uname' function. */
+#undef HAVE_UNAME
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `unlink' function. */
+#undef HAVE_UNLINK
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#undef HAVE_UNSIGNED_LONG_LONG_INT
+
+/* Define if you have System V Release 3 signals. */
+#undef HAVE_USG_SIGHOLD
+
+/* Define to 1 if you have the `usleep' function. */
+#undef HAVE_USLEEP
+
+/* Define to 1 if you have the `utime' function. */
+#undef HAVE_UTIME
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
+
+/* Define to 1 if you have the `vfprintf' function. */
+#undef HAVE_VFPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `vsprintf' function. */
+#undef HAVE_VSPRINTF
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Define to 1 if you have the `x_utime' function. */
+#undef HAVE_X_UTIME
+
+/* Define if you have X11 */
+#undef HAVE_X_WINDOWS
+
+/* Define if ZLIB is available. */
+#undef HAVE_ZLIB
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to 1 if you have the `_chmod' function. */
+#undef HAVE__CHMOD
+
+/* Define to 1 if you have the `_copysign' function. */
+#undef HAVE__COPYSIGN
+
+/* Define to 1 if you have the `_finite' function. */
+#undef HAVE__FINITE
+
+/* Define to 1 if you have the `_hypotf' function. */
+#undef HAVE__HYPOTF
+
+/* Define to 1 if you have the `_isnan' function. */
+#undef HAVE__ISNAN
+
+/* Define to 1 if you have the `_kbhit' function. */
+#undef HAVE__KBHIT
+
+/* Define to 1 if you have the `_snprintf' function. */
+#undef HAVE__SNPRINTF
+
+/* Define to 1 if you have the `_utime32' function. */
+#undef HAVE__UTIME32
+
+/* Define to 1 if octave index type is long */
+#undef IDX_TYPE_LONG
+
+/* Define if host mkdir takes a single argument. */
+#undef MKDIR_TAKES_ONE_ARG
+
+/* Define if signal handlers must be reinstalled after they are called. */
+#undef MUST_REINSTALL_SIGHANDLERS
+
+/* Define if the QHull library needs a wh_version variable defined. */
+#undef NEED_QHULL_VERSION
+
+/* Define if strptime is broken on your system */
+#undef OCTAVE_HAVE_BROKEN_STRPTIME
+
+/* Define if this is Octave. */
+#undef OCTAVE_SOURCE
+
+/* 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 necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define if this if RETSIGTYPE is defined to be void. Needed because
+   preprocessor comparisons to void fail on some systems. */
+#undef RETSIGTYPE_IS_VOID
+
+/* Define if your struct rusage only has time information. */
+#undef RUSAGE_TIMES_ONLY
+
+/* Define if using an SCO system. */
+#undef SCO
+
+/* Define this to be the path separator for your system, as a character
+   constant. */
+#undef SEPCHAR
+
+/* Define this to the path separator, as a string. */
+#undef SEPCHAR_STR
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* To quiet autoheader. */
+#undef SMART_PUTENV
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define if the UMFPACK Complex solver allow matrix and RHS to be split
+   independently */
+#undef UMFPACK_SEPARATE_SPLIT
+
+/* Define if using 64-bit integers for array dimensions and indexing */
+#undef USE_64_BIT_IDX_T
+
+/* Define to use the readline library. */
+#undef USE_READLINE
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#undef YYTEXT_POINTER
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+#if HAVE_EXP2 && ! HAVE_DECL_EXP2
+double exp2 (double );
+#endif
+#if HAVE_ROUND && ! HAVE_DECL_ROUND
+double round (double);
+#endif
+#if HAVE_TGAMMA && ! HAVE_DECL_TGAMMA
+double tgamma (double);
+#endif
+#if defined (__cplusplus)
+}
+#endif
+
+
+/* Define if using HDF5 dll (Win32) */
+#undef _HDF5USEDLL_
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define if your system needs it to define math constants like M_LN2 */
+#undef _USE_MATH_DEFINES
+
+/* Define to 0x0403 to access InitializeCriticalSectionAndSpinCount */
+#undef _WIN32_WINNT
+
+/* Define if your version of GNU libc has buggy inline assembly code for math
+   functions like exp. */
+#undef __NO_MATH_INLINES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+
+#if defined (__GNUC__)
+#define GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__))
+#define GCC_ATTR_UNUSED __attribute__ ((__unused__))
+#else
+#define GCC_ATTR_DEPRECATED
+#define GCC_ATTR_NORETURN
+#define GCC_ATTR_UNUSED
+#endif
+
+#define X_CAST(T, E) (T) (E)
+
+#if defined (CXX_BROKEN_REINTERPRET_CAST)
+#define FCN_PTR_CAST(T, E) (T) (E)
+#else
+#define FCN_PTR_CAST(T, E) reinterpret_cast<T> (E)
+#endif
+
+#if !defined(HAVE_DEV_T)
+typedef short dev_t;
+#endif
+
+#if !defined(HAVE_INO_T)
+typedef unsigned long ino_t;
+#endif
+
+#if !defined(HAVE_NLINK_T)
+typedef short nlink_t;
+#endif
+
+#if !defined(HAVE_SIGSET_T)
+typedef int sigset_t;
+#endif
+
+#if !defined(HAVE_SIG_ATOMIC_T)
+typedef int sig_atomic_t;
+#endif
+
+#if defined (_MSC_VER)
+#define __WIN32__
+#define WIN32
+/* missing parameters in macros */
+#pragma warning (disable: 4003)
+/* missing implementations in template instantiation */
+#pragma warning (disable: 4996)
+/* deprecated function names (FIXME?) */
+#pragma warning (disable: 4661)
+#endif
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#define OCTAVE_HAVE_WINDOWS_FILESYSTEM 1
+#elif defined (__CYGWIN__)
+#define OCTAVE_HAVE_WINDOWS_FILESYSTEM 1
+#define OCTAVE_HAVE_POSIX_FILESYSTEM 1
+#else
+#define OCTAVE_HAVE_POSIX_FILESYSTEM 1
+#endif
+
+/* Define if we expect to have <windows.h>, Sleep, etc. */
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#define OCTAVE_USE_WINDOWS_API 1
+#endif
+
+#if defined (__APPLE__) && defined (__MACH__)
+#define OCTAVE_USE_OS_X_API 1
+#endif
+
+/* sigsetjmp is a macro, not a function. */
+#if defined (sigsetjmp) && defined (HAVE_SIGLONGJMP)
+#define OCTAVE_HAVE_SIG_JUMP
+#endif
+
+#if defined (__DECCXX)
+#define __USE_STD_IOSTREAM
+#endif
+
+#if defined (_UNICOS)
+#define F77_USES_CRAY_CALLING_CONVENTION
+#endif
+
+#if 0
+#define F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION
+#endif
+
+#ifdef USE_64_BIT_IDX_T
+#define SIZEOF_OCTAVE_IDX_TYPE 8
+#else
+#define SIZEOF_OCTAVE_IDX_TYPE SIZEOF_INT
+#endif
+
+// To be able to use long doubles for 64-bit mixed arithmetics, we need them at
+// least 80 bits wide and we need roundl declared in math.h.
+// FIXME -- maybe substitute this by a more precise check in the future.
+#if (SIZEOF_LONG_DOUBLE >= 10) && defined (HAVE_ROUNDL)
+#define OCTAVE_INT_USE_LONG_DOUBLE
+#endif
+
+#define OCTAVE_EMPTY_CPP_ARG
+
+#include "oct-dlldefs.h"
+#include "oct-types.h"
+
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..b5994f7
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1685 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
+
+timestamp='2009-03-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..ccc1f7f
--- /dev/null
+++ b/configure
@@ -0,0 +1,21288 @@
+#! /bin/sh
+# From configure.in Revision: 1.603 .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="src/octave.cc"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+enable_option_checking=no
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+ac_config_files
+subdirs
+WARN_CXXFLAGS
+WARN_CFLAGS
+UGLY_DEFS
+TEXI2PDF
+TEXI2DVI
+MAKEINFO
+GHOSTSCRIPT
+GPERF
+DEFAULT_PAGER
+GNUPLOT
+DESKTOP_FILE_INSTALL
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LN_S
+YFLAGS
+YACC
+LFLAGS
+LEXLIB
+LEX_OUTPUT_ROOT
+LEX
+PYTHON
+PERL
+SED
+FIND
+AWK
+LIBREADLINE
+TERMLIBS
+LIBCRUFT
+LIBOCTAVE
+LIBOCTINTERP
+ENABLE_DYNAMIC_LINKING
+RDYNAMIC_FLAG
+LD_CXX
+LIBGLOB
+ALLOCA
+SCRIPTS_EXE_SUFFIX
+library_path_var
+OCTGRAPHICS_DLL_DEFS
+OCTINTERP_DLL_DEFS
+OCTAVE_DLL_DEFS
+CRUFT_DLL_DEFS
+TEMPLATE_ARFLAGS
+TEMPLATE_AR
+RLD_FLAG
+NO_OCT_FILE_STRIP
+SONAME_FLAGS
+MKOCTFILE_DL_LDFLAGS
+DL_LDFLAGS
+DL_LD
+SH_LDFLAGS
+SH_LD
+SHLBINPRE
+SHLLIBPRE
+SHLPRE
+LIBPRE
+SHLLINKEXT
+SHLBIN_VER
+SHLLIB_VER
+SHLEXT_VER
+SHLBIN
+SHLLIB
+SHLEXT
+CXXPICFLAG
+CPICFLAG
+FPICFLAG
+SHARED_LIBS
+STATIC_LIBS
+ARPACK_LIBS
+CXSPARSE_LIBS
+TEXINFO_CHOLMOD
+CHOLMOD_LIBS
+CCOLAMD_LIBS
+TEXINFO_COLAMD
+COLAMD_LIBS
+TEXINFO_UMFPACK
+UMFPACK_LIBS
+CAMD_LIBS
+AMD_LIBS
+QRUPDATE_LIBS
+LAPACK_DIR
+BLAS_DIR
+LAPACK_LIBS
+BLAS_LIBS
+F77_FLOAT_STORE_FLAG
+FC
+XTRA_CRUFT_SH_LDFLAGS
+F77_APPEND_EXTRA_UNDERSCORE
+F77_APPEND_UNDERSCORE
+F77_TOLOWER
+FLIBS
+ac_ct_F77
+FFLAGS
+F77
+RANLIB
+ARFLAGS
+AR
+GRAPHICS_LIBS
+GRAPHICS_CFLAGS
+FLTK_CONFIG
+FT2_LIBS
+FT2_CFLAGS
+FT2_CONFIG
+OPENGL_LIBS
+MAGICK_CONFIG
+CURL_LIBS
+GLPK_LIBS
+FFTW_LIBS
+FFT_DIR
+REGEX_LIBS
+WITH_PCRE_CONFIG
+TEXINFO_QHULL
+QHULL_LIBS
+BUILD_EXEEXT
+BUILD_LDFLAGS
+BUILD_CXXFLAGS
+BUILD_CXX
+BUILD_CFLAGS
+BUILD_CC
+LD_STATIC_FLAG
+XTRA_CXXFLAGS
+XTRA_CFLAGS
+CARBON_LIBS
+X11_LIBS
+X11_INCFLAGS
+XMKMF
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+acx_pthread_config
+DEPEND_EXTRA_SED_PATTERN
+DEPEND_FLAGS
+INCLUDE_DEPS
+CC_VERSION
+CXX_VERSION
+CXXCPP
+ac_ct_CXX
+CXXFLAGS
+CXX
+USE_64_BIT_IDX_T
+OCTAVE_IDX_TYPE
+config_opts
+imagedir
+localveroctfiledir
+localapioctfiledir
+localoctfiledir
+octfiledir
+localverarchlibdir
+localapiarchlibdir
+localarchlibdir
+archlibdir
+octlibdir
+octetcdir
+localverfcnfiledir
+localapifcnfiledir
+localfcnfiledir
+fcnfiledir
+octincludedir
+infofile
+doc_cache_file
+man1ext
+man1dir
+sepchar
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+canonical_host_type
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_sepchar
+enable_bounds_check
+enable_64
+with_x
+with_framework_carbon
+with_zlib
+with_hdf5
+with_fftw
+with_glpk
+with_curl
+with_framework_opengl
+with_ft_prefix
+with_ft_exec_prefix
+enable_freetypetest
+with_fltk_prefix
+with_fltk_exec_prefix
+with_blas
+with_lapack
+with_qrupdate
+with_amd
+with_umfpack
+with_colamd
+with_ccolamd
+with_cholmod
+with_cxsparse
+with_arpack
+enable_static
+enable_shared
+enable_dl
+enable_rpath
+enable_readline
+enable_extra_warning_flags
+enable_strict_warning_flags
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+XMKMF
+BUILD_CC
+BUILD_CFLAGS
+BUILD_CXX
+BUILD_CXXFLAGS
+BUILD_LDFLAGS
+BUILD_EXEEXT
+F77
+FFLAGS
+YACC
+YFLAGS'
+ac_subdirs_all='scripts'
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+X features:
+  --x-includes=DIR    X include files are in DIR
+  --x-libraries=DIR   X library files are in DIR
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-bounds-check   bounds checking for indexing in internal array
+                          classes (default is no)
+  --enable-64             (EXPERIMENTAL) use 64-bit integers for array
+                          dimensions and indexing
+       --disable-freetypetest  Do not try to compile and run a test FreeType
+                          program
+  --enable-static         create static libraries
+  --enable-shared         create shared libraries (not all systems)
+  --enable-dl             create shared libraries (not all systems)
+  --enable-rpath          override the default link options for rpath; e.g.,
+                          --enable-rpath='-rpath $(octlibdir)'
+  --enable-readline       use readline library (default is yes)
+  --enable-extra-warning-flags
+                          add -Wall, -W, -Wshadow, and -Wold-style-cast
+                          options to CFLAGS and CXXFLAGS (on by default, but
+                          only if the compiler appears to accept them)
+  --enable-strict-warning-flags
+                          add extra strict warning options to CFLAGS and
+                          CXXFLAGS (off by default)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-sepchar=<char>   use <char> as the path separation character
+  --with-x                use the X Window System
+  --without-framework-carbon
+                          don't use framework Carbon
+  --without-zlib          don't use zlib
+  --without-hdf5          don't use HDF5
+  --without-fftw          use included fftpack instead of installed fftw
+  --without-glpk          don't use GLPK
+  --without-curl          don't use CURL
+  --without-framework-opengl
+                          don't use framework OpenGL
+       --with-ft-prefix=PREFIX Prefix where FreeType is installed (optional)
+       --with-ft-exec-prefix=PREFIX
+                          Exec prefix where FreeType is installed (optional)
+  --with-fltk-prefix=PFX   Prefix where FLTK is installed (optional)
+  --with-fltk-exec-prefix=PFX Exec prefix where FLTK is installed (optional)
+  --with-blas=<lib>       use BLAS library <lib>
+  --with-lapack=<lib>     use LAPACK library <lib>
+  --without-qrupdate      don't use qrupdate, disable QR & Cholesky updating
+                          functions
+  --without-amd           don't use AMD, disable some sparse functionality
+  --without-umfpack       don't use UMFPACK, disable some sparse functionality
+  --without-colamd        don't use COLAMD, disable some sparse functionality
+  --without-ccolamd       don't use CCOLAMD, disable some sparse functionality
+  --without-cholmod       don't use CHOLMOD, disable some sparse functionality
+  --without-cxsparse      don't use CXSparse, disable some sparse
+                          functionality
+  --without-arpack        don't use ARPACK, disable some sparse functionality
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  XMKMF       Path to xmkmf, Makefile generator for X Window System
+  BUILD_CC    build system C compiler (used if cross compiling)
+  BUILD_CFLAGS
+              build system C compiler flags (used if cross compiling)
+  BUILD_CXX   build system C++ compiler (used if cross compiling)
+  BUILD_CXXFLAGS
+              build system C++ compiler flags (used if cross compiling)
+  BUILD_LDFLAGS
+              build system C++ compiler link flags (used if cross compiling)
+  BUILD_EXEEXT
+              build system executable extension (used if cross compiling)
+  F77         Fortran 77 compiler command
+  FFLAGS      Fortran 77 compiler flags
+  YACC        The `Yet Another C Compiler' implementation to use. Defaults to
+              the first program found out of: `bison -y', `byacc', `yacc'.
+  YFLAGS      The list of arguments that will be passed by default to $YACC.
+              This script will default YFLAGS to the empty string to avoid a
+              default value of `-d' given by some make applications.
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_f77_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_f77_try_compile
+
+# ac_fn_f77_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_f77_try_link
+
+# ac_fn_f77_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_f77_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_f77_try_run
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_run
+
+# ac_fn_cxx_check_decl LINENO SYMBOL VAR
+# --------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_cxx_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+#ifndef $2
+  (void) $2;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_cxx_check_decl
+
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_cxx_check_func
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+#ifndef $2
+  (void) $2;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_member
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+if test -z "$host"; then
+  host=unknown
+fi
+canonical_host_type=$host
+if test "$host" = unknown; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: configuring Octave for unknown system type
+" >&5
+$as_echo "$as_me: WARNING: configuring Octave for unknown system type
+" >&2;}
+fi
+
+
+
+$as_echo "#define OCTAVE_SOURCE 1" >>confdefs.h
+
+
+### Produce unistd.h for MSVC target, this simplifies changes in
+### Octave source tree and avoid problems with lex-generated code.
+case "$canonical_host_type" in
+  *-*-msdosmsvc)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Generating replacement for <unistd.h> for MSVC" >&5
+$as_echo "$as_me: Generating replacement for <unistd.h> for MSVC" >&6;}
+    cat << \EOF > unistd.h
+/* File generated by configure script. */
+#include <direct.h>
+#include <io.h>
+#include <process.h>
+EOF
+    CPPFLAGS="-I. $CPPFLAGS"
+    ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+  if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#	  define __EXTENSIONS__ 1
+	  $ac_includes_default
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_safe_to_define___extensions__=yes
+else
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+### Path separator.
+sepchar=:
+
+# Check whether --with-sepchar was given.
+if test "${with_sepchar+set}" = set; then :
+  withval=$with_sepchar;
+fi
+
+case $with_sepchar in
+  yes | "")
+    case "$canonical_host_type" in
+      *-*-mingw* | *-*-msdosmsvc)
+	sepchar=';'
+        ;;
+      esac
+    ;;
+  no)
+    as_fn_error "You are required to define a path separation character" "$LINENO" 5
+    ;;
+  *)
+    sepchar=$with_sepchar
+    ;;
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define SEPCHAR '$sepchar'
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SEPCHAR_STR "$sepchar"
+_ACEOF
+
+
+### some defaults
+
+: ${man1dir='$(mandir)/man1'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining man1dir to be $man1dir" >&5
+$as_echo "defining man1dir to be $man1dir" >&6; }
+
+: ${man1ext='.1'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining man1ext to be $man1ext" >&5
+$as_echo "defining man1ext to be $man1ext" >&6; }
+
+: ${doc_cache_file='$(octetcdir)/doc-cache'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining doc_cache_file to be $doc_cache_file" >&5
+$as_echo "defining doc_cache_file to be $doc_cache_file" >&6; }
+
+: ${infofile='$(infodir)/octave.info'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining infofile to be $infofile" >&5
+$as_echo "defining infofile to be $infofile" >&6; }
+
+: ${octincludedir='$(includedir)/octave-$(version)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining octincludedir to be $octincludedir" >&5
+$as_echo "defining octincludedir to be $octincludedir" >&6; }
+
+: ${fcnfiledir='$(datadir)/octave/$(version)/m'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining fcnfiledir to be $fcnfiledir" >&5
+$as_echo "defining fcnfiledir to be $fcnfiledir" >&6; }
+
+: ${localfcnfiledir='$(datadir)/octave/site/m'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localfcnfiledir to be $localfcnfiledir" >&5
+$as_echo "defining localfcnfiledir to be $localfcnfiledir" >&6; }
+
+: ${localapifcnfiledir='$(datadir)/octave/site/$(api_version)/m'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localapifcnfiledir to be $localapifcnfiledir" >&5
+$as_echo "defining localapifcnfiledir to be $localapifcnfiledir" >&6; }
+
+: ${localverfcnfiledir='$(datadir)/octave/$(version)/site/m'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localverfcnfiledir to be $localverfcnfiledir" >&5
+$as_echo "defining localverfcnfiledir to be $localverfcnfiledir" >&6; }
+
+: ${octetcdir='$(datadir)/octave/$(version)/etc'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining octetcdir to be $octetcdir" >&5
+$as_echo "defining octetcdir to be $octetcdir" >&6; }
+
+: ${octlibdir='$(libdir)/octave-$(version)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining octlibdir to be $octlibdir" >&5
+$as_echo "defining octlibdir to be $octlibdir" >&6; }
+
+: ${archlibdir='$(libexecdir)/octave/$(version)/exec/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining archlibdir to be $archlibdir" >&5
+$as_echo "defining archlibdir to be $archlibdir" >&6; }
+
+: ${localarchlibdir='$(libexecdir)/octave/site/exec/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localarchlibdir to be $localarchlibdir" >&5
+$as_echo "defining localarchlibdir to be $localarchlibdir" >&6; }
+
+: ${localapiarchlibdir='$(libexecdir)/octave/$(api_version)/site/exec/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localapiarchlibdir to be $localapiarchlibdir" >&5
+$as_echo "defining localapiarchlibdir to be $localapiarchlibdir" >&6; }
+
+: ${localverarchlibdir='$(libexecdir)/octave/$(version)/site/exec/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localverarchlibdir to be $localverarchlibdir" >&5
+$as_echo "defining localverarchlibdir to be $localverarchlibdir" >&6; }
+
+: ${octfiledir='$(libexecdir)/octave/$(version)/oct/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining octfiledir to be $octfiledir" >&5
+$as_echo "defining octfiledir to be $octfiledir" >&6; }
+
+: ${localoctfiledir='$(libexecdir)/octave/site/oct/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localoctfiledir to be $localoctfiledir" >&5
+$as_echo "defining localoctfiledir to be $localoctfiledir" >&6; }
+
+: ${localapioctfiledir='$(libexecdir)/octave/site/oct/$(api_version)/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localapioctfiledir to be $localapioctfiledir" >&5
+$as_echo "defining localapioctfiledir to be $localapioctfiledir" >&6; }
+
+: ${localveroctfiledir='$(libexecdir)/octave/$(version)/site/oct/$(canonical_host_type)'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining localveroctfiledir to be $localveroctfiledir" >&5
+$as_echo "defining localveroctfiledir to be $localveroctfiledir" >&6; }
+
+: ${imagedir='$(datadir)/octave/$(version)/imagelib'}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defining imagedir to be $imagedir" >&5
+$as_echo "defining imagedir to be $imagedir" >&6; }
+
+
+### Make configure args available for other uses.
+
+config_opts=$ac_configure_args
+
+
+### Make it possible to have Octave's array and matrix classes do bounds
+### checking on element references.  This slows some operations down a
+### bit, so it is turned off by default.
+
+BOUNDS_CHECKING=false
+# Check whether --enable-bounds-check was given.
+if test "${enable_bounds_check+set}" = set; then :
+  enableval=$enable_bounds_check; if test "$enableval" = yes; then BOUNDS_CHECKING=true; fi
+fi
+
+if $BOUNDS_CHECKING; then
+
+$as_echo "#define BOUNDS_CHECKING 1" >>confdefs.h
+
+fi
+
+### If possible, use a 64-bit integer type for array dimensions and indexing.
+
+USE_64_BIT_IDX_T=false
+OCTAVE_IDX_TYPE=int
+# Check whether --enable-64 was given.
+if test "${enable_64+set}" = set; then :
+  enableval=$enable_64; if test "$enableval" = yes; then USE_64_BIT_IDX_T=true; fi
+fi
+
+if $USE_64_BIT_IDX_T; then
+  # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
+$as_echo_n "checking size of void *... " >&6; }
+if test "${ac_cv_sizeof_void_p+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_void_p" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (void *)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_void_p=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
+$as_echo "$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
+  # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if test "${ac_cv_sizeof_int+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+  # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+  if test $ac_cv_sizeof_void_p -eq 8; then
+    if test $ac_cv_sizeof_int -eq 8; then
+      OCTAVE_IDX_TYPE=int
+    elif test $ac_cv_sizeof_long -eq 8; then
+      OCTAVE_IDX_TYPE=long
+
+$as_echo "#define IDX_TYPE_LONG 1" >>confdefs.h
+
+    else
+      warn_64_bit="no suitable type found for octave_idx_type so disabling 64-bit features"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_64_bit" >&5
+$as_echo "$as_me: WARNING: $warn_64_bit" >&2;}
+      USE_64_BIT_IDX_T=false
+    fi
+  else
+    warn_64_bit="pointers are not 64-bits wide so disabling 64-bit features"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_64_bit" >&5
+$as_echo "$as_me: WARNING: $warn_64_bit" >&2;}
+    USE_64_BIT_IDX_T=false
+  fi
+fi
+
+if $USE_64_BIT_IDX_T; then
+
+$as_echo "#define USE_64_BIT_IDX_T 1" >>confdefs.h
+
+fi
+
+
+### It seems that there are some broken inline assembly functions in
+### the GNU libc.  Since I'm not sure how to test whether we are using
+### GNU libc, just disable them for all platforms.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining __NO_MATH_INLINES avoids buggy GNU libc exp function" >&5
+$as_echo "$as_me: defining __NO_MATH_INLINES avoids buggy GNU libc exp function" >&6;}
+
+$as_echo "#define __NO_MATH_INLINES 1" >>confdefs.h
+
+
+### See which C++ compiler to use (we expect to find g++).
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+### Do special things for g++.
+
+gxx_version=`$CXX -v 2>&1 | grep "^.*g.. version" | \
+  sed -e 's/^.*g.. version *//' -e 's/cygnus-//' -e 's/egcs-//' -e 's/ .*//'`
+
+case "$gxx_version" in
+  1.* | 2.[0123456789].* | 3.[01234].*)
+    as_fn_error "g++ version $gxx_version will probably fail to compile Octave
+" "$LINENO" 5
+  ;;
+esac
+
+CXX_VERSION=
+if test -n "$gxx_version"; then
+  CXX_VERSION="$gxx_version"
+fi
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ support for new friend template declaration" >&5
+$as_echo_n "checking for C++ support for new friend template declaration... " >&6; }
+  if test "${octave_cv_cxx_new_friend_template_decl+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    rm -f conftest.h
+    cat > conftest.h <<EOB
+       struct A {
+	 friend int operator== (const A&, const A&);
+	 A (int) { }
+       };
+
+       template <class T> int
+       operator== (const T&, const T&)
+       {
+	 return 0;
+       }
+EOB
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include "conftest.h"
+int
+main ()
+{
+A a (1);
+        return a == A(1);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  octave_cv_cxx_new_friend_template_decl=no
+else
+  octave_cv_cxx_new_friend_template_decl=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_cxx_new_friend_template_decl" >&5
+$as_echo "$octave_cv_cxx_new_friend_template_decl" >&6; }
+  if test $octave_cv_cxx_new_friend_template_decl = yes; then
+
+$as_echo "#define CXX_NEW_FRIEND_TEMPLATE_DECL 1" >>confdefs.h
+
+  fi
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C++ library is ISO compliant" >&5
+$as_echo_n "checking if C++ library is ISO compliant... " >&6; }
+  if test "${octave_cv_cxx_iso_compliant_library+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    rm -f conftest.h
+### Omitting cwctype for now, since it is broken with gcc-3.0.x and
+### possibly other versions...
+    for inc in algorithm bitset cassert cctype cerrno cfloat ciso646 \
+	climits clocale cmath complex csetjmp csignal cstdarg cstddef \
+	cstdio cstdlib cstring ctime cwchar deque exception \
+	fstream functional iomanip ios iosfwd iostream istream iterator \
+	limits list locale map memory new numeric ostream queue set \
+	sstream stack stdexcept streambuf string strstream typeinfo \
+	utility valarray vector; do
+      echo "#include <$inc>" >> conftest.h
+    done
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include "conftest.h"
+int
+main ()
+{
+std::bitset<50> flags;
+        flags.set();
+        int digits = std::numeric_limits<unsigned long>::digits;
+        digits = 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  octave_cv_cxx_iso_compliant_library=yes
+else
+  octave_cv_cxx_iso_compliant_library=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_cxx_iso_compliant_library" >&5
+$as_echo "$octave_cv_cxx_iso_compliant_library" >&6; }
+  if test $octave_cv_cxx_iso_compliant_library = yes; then
+
+$as_echo "#define CXX_ISO_COMPLIANT_LIBRARY 1" >>confdefs.h
+
+  fi
+
+
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken C++ reinterpret_cast" >&5
+$as_echo_n "checking for broken C++ reinterpret_cast... " >&6; }
+if test "${octave_cv_cxx_broken_reinterpret_cast+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <cmath>
+int
+main ()
+{
+
+      typedef double (*fptr) (double);
+      fptr psin = sin;
+      void *vptr = reinterpret_cast<void *> (psin);
+      psin = reinterpret_cast<fptr> (vptr);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  octave_cv_cxx_broken_reinterpret_cast=no
+else
+  octave_cv_cxx_broken_reinterpret_cast=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_cxx_broken_reinterpret_cast" >&5
+$as_echo "$octave_cv_cxx_broken_reinterpret_cast" >&6; }
+  if test $octave_cv_cxx_broken_reinterpret_cast = yes ; then
+
+$as_echo "#define CXX_BROKEN_REINTERPRET_CAST 1" >>confdefs.h
+
+fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+### See which C compiler to use (we expect to find gcc).
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
+$as_echo_n "checking whether $CC needs -traditional... " >&6; }
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5
+$as_echo "$ac_cv_prog_gcc_traditional" >&6; }
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+
+### Do special things for gcc.
+
+gcc_version=`$CC -v 2>&1 | grep "^.*gcc version" | \
+  sed -e 's/^.*g.. version *//' -e 's/cygnus-//' -e 's/egcs-//'`
+case "$gcc_version" in
+  2.*)
+    if test -z "$LDFLAGS"; then
+      LDFLAGS="-g"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: defining LDFLAGS to be $LDFLAGS" >&5
+$as_echo "$as_me: defining LDFLAGS to be $LDFLAGS" >&6;}
+    fi
+  ;;
+  1.*)
+    warn_gcc_version="gcc version $gcc_version is likely to cause problems"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_gcc_version" >&5
+$as_echo "$as_me: WARNING: $warn_gcc_version" >&2;}
+  ;;
+esac
+
+CC_VERSION=
+if test -n "$gcc_version"; then
+  CC_VERSION="$gcc_version"
+fi
+
+
+### The flag to create dependency varies depending on the compier.
+
+# Assume GCC.
+INCLUDE_DEPS=true
+DEPEND_FLAGS="-M"
+DEPEND_EXTRA_SED_PATTERN=""
+if test "$GCC" = yes; then
+  true
+else
+  case "$canonical_host_type" in
+    sparc-sun-solaris2* | i386-pc-solaris2*)
+      DEPEND_FLAGS="-xM1"
+      DEPEND_EXTRA_SED_PATTERN="-e '/\/opt\/SUNWspro/d'"
+    ;;
+    *-*-msdosmsvc)
+    ;;
+    *)
+      INCLUDE_DEPS=false
+    ;;
+  esac
+fi
+
+
+
+
+# ===========================================================================
+#           http://www.nongnu.org/autoconf-archive/acx_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#          LIBS="$PTHREAD_LIBS $LIBS"
+#          CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#          CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		# Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_acx_pthread_config+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$acx_pthread_config"; then
+  ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_acx_pthread_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+fi
+fi
+acx_pthread_config=$ac_cv_prog_acx_pthread_config
+if test -n "$acx_pthread_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5
+$as_echo "$acx_pthread_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr=$attr; return attr;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	done
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          for ac_prog in xlc_r cc_r
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PTHREAD_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}"
+
+        else
+          PTHREAD_CC=$CC
+	fi
+else
+        PTHREAD_CC="$CC"
+fi
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+        :
+else
+        acx_pthread_ok=no
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
+$as_echo_n "checking for X... " >&6; }
+
+
+# Check whether --with-x was given.
+if test "${with_x+set}" = set; then :
+  withval=$with_x;
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  case $x_includes,$x_libraries in #(
+    *\'*) as_fn_error "cannot use X directory names containing '" "$LINENO" 5;; #(
+    *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=no ac_x_libraries=no
+rm -f -r conftest.dir
+if mkdir conftest.dir; then
+  cd conftest.dir
+  cat >Imakefile <<'_ACEOF'
+incroot:
+	@echo incroot='${INCROOT}'
+usrlibdir:
+	@echo usrlibdir='${USRLIBDIR}'
+libdir:
+	@echo libdir='${LIBDIR}'
+_ACEOF
+  if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    for ac_var in incroot usrlibdir libdir; do
+      eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
+    done
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl dylib la dll; do
+      if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" &&
+	 test -f "$ac_im_libdir/libX11.$ac_extension"; then
+	ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case $ac_im_incroot in
+	/usr/include) ac_x_includes= ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+    esac
+    case $ac_im_usrlibdir in
+	/usr/lib | /usr/lib64 | /lib | /lib64) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+    esac
+  fi
+  cd ..
+  rm -f -r conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R7/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R7
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R7/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R7
+/usr/local/include/X11R6
+/usr/local/include/X11R5
+/usr/local/include/X11R4
+
+/usr/X386/include
+/usr/x386/include
+/usr/XFree86/include/X11
+
+/usr/include
+/usr/local/include
+/usr/unsupported/include
+/usr/athena/include
+/usr/local/x11r5/include
+/usr/lpp/Xamples/include
+
+/usr/openwin/include
+/usr/openwin/share/include'
+
+if test "$ac_x_includes" = no; then
+  # Guess where to find include files, by looking for Xlib.h.
+  # First, try using that file with no special directory specified.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  for ac_dir in $ac_x_header_dirs; do
+  if test -r "$ac_dir/X11/Xlib.h"; then
+    ac_x_includes=$ac_dir
+    break
+  fi
+done
+fi
+rm -f conftest.err conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+  # Check for the libraries.
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS=$LIBS
+  LIBS="-lX11 $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize ()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  LIBS=$ac_save_LIBS
+for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+  # Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl dylib la dll; do
+    if test -r "$ac_dir/libX11.$ac_extension"; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+case $ac_x_includes,$ac_x_libraries in #(
+  no,* | *,no | *\'*)
+    # Didn't find X, or a directory has "'" in its name.
+    ac_cv_have_x="have_x=no";; #(
+  *)
+    # Record where we found X for the cache.
+    ac_cv_have_x="have_x=yes\
+	ac_x_includes='$ac_x_includes'\
+	ac_x_libraries='$ac_x_libraries'"
+esac
+fi
+;; #(
+    *) have_x=yes;;
+  esac
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
+$as_echo "$have_x" >&6; }
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes\
+	ac_x_includes='$x_includes'\
+	ac_x_libraries='$x_libraries'"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
+$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
+fi
+
+if test "$have_x"; then
+
+$as_echo "#define HAVE_X_WINDOWS 1" >>confdefs.h
+
+
+  if test "$x_includes" != "NONE"; then
+    X11_INCFLAGS="$x_includes"
+  fi
+
+
+  if test -z $x_libraries; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XrmInitialize in -lX11" >&5
+$as_echo_n "checking for XrmInitialize in -lX11... " >&6; }
+if test "${ac_cv_lib_X11_XrmInitialize+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lX11  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XrmInitialize ();
+int
+main ()
+{
+return XrmInitialize ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_X11_XrmInitialize=yes
+else
+  ac_cv_lib_X11_XrmInitialize=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XrmInitialize" >&5
+$as_echo "$ac_cv_lib_X11_XrmInitialize" >&6; }
+if test "x$ac_cv_lib_X11_XrmInitialize" = x""yes; then :
+  X11_LIBS=-lX11
+else
+  X11_LIBS=
+fi
+
+  elif test $x_libraries != "NONE"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XrmInitialize in -lX11" >&5
+$as_echo_n "checking for XrmInitialize in -lX11... " >&6; }
+if test "${ac_cv_lib_X11_XrmInitialize+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lX11 "-L$x_libraries" $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XrmInitialize ();
+int
+main ()
+{
+return XrmInitialize ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_X11_XrmInitialize=yes
+else
+  ac_cv_lib_X11_XrmInitialize=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XrmInitialize" >&5
+$as_echo "$ac_cv_lib_X11_XrmInitialize" >&6; }
+if test "x$ac_cv_lib_X11_XrmInitialize" = x""yes; then :
+  X11_LIBS="-L$x_libraries -lX11"
+else
+  X11_LIBS=
+fi
+
+  fi
+
+fi
+
+### On MacOSX system the Carbon framework is used to determine ScreenSize
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${LD-ld} accepts -framework Carbon" >&5
+$as_echo_n "checking whether ${LD-ld} accepts -framework Carbon... " >&6; }
+  if test "${octave_cv_framework_Carbon+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    XLDFLAGS="$LDFLAGS"
+    LDFLAGS="$LDFLAGS -framework Carbon"
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <Carbon/Carbon.h>
+int
+main ()
+{
+CGMainDisplayID ()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_framework_Carbon=yes"
+else
+  eval "octave_cv_framework_Carbon=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    LDFLAGS="$XLDFLAGS"
+
+fi
+
+  if test "$octave_cv_framework_Carbon" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+# Check whether --with-framework-carbon was given.
+if test "${with_framework_carbon+set}" = set; then :
+  withval=$with_framework_carbon; with_have_framework=$withval
+else
+  with_have_framework="yes"
+fi
+
+    if test "$with_have_framework" = "yes"; then
+      have_framework_carbon="yes"
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: framework rejected by --without-framework-carbon" >&5
+$as_echo "$as_me: framework rejected by --without-framework-carbon" >&6;}
+      have_framework_carbon="no"
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    have_framework_carbon="no"
+  fi
+
+if test $have_framework_carbon = "yes"; then
+
+$as_echo "#define HAVE_FRAMEWORK_CARBON 1" >>confdefs.h
+
+  CARBON_LIBS="-Wl,-framework -Wl,Carbon"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: adding -Wl,-framework -Wl,Carbon to CARBON_LIBS" >&5
+$as_echo "$as_me: adding -Wl,-framework -Wl,Carbon to CARBON_LIBS" >&6;}
+
+fi
+
+### On Intel systems with gcc, we may need to compile with -mieee-fp
+### and -ffloat-store to get full support for IEEE floating point.
+###
+### On Alpha/OSF systems, we need -mieee.
+
+ieee_fp_flag=
+case "$canonical_host_type" in
+  ## Keep this pattern first, so that it is preferred over the
+  ## following pattern for x86.
+  *-*-msdosmsvc)
+    CXXFLAGS="$CXXFLAGS -EHs -MD"
+    CFLAGS="$CFLAGS -MD"
+  ;;
+  i[3456789]86-*-*)
+    if test "$GCC" = yes; then
+
+  ac_safe=`echo "-mieee-fp" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -mieee-fp" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -mieee-fp... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mieee-fp"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+        ieee_fp_flag=-mieee-fp
+        XTRA_CFLAGS="$XTRA_CFLAGS -mieee-fp"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: adding -mieee-fp to XTRA_CFLAGS" >&5
+$as_echo "$as_me: adding -mieee-fp to XTRA_CFLAGS" >&6;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+###      OCTAVE_CC_FLAG(-ffloat-store, [
+###        float_store_flag=-ffloat-store
+###        XTRA_CFLAGS="$XTRA_CFLAGS -ffloat-store"
+###        AC_MSG_RESULT([adding -ffloat-store to XTRA_CFLAGS])])
+    fi
+    if test "$GXX" = yes; then
+
+  ac_safe=`echo "-mieee-fp" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -mieee-fp" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -mieee-fp... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -mieee-fp"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+	ieee_fp_flag=-mieee-fp
+	XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mieee-fp"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: adding -mieee-fp to XTRA_CXXFLAGS" >&5
+$as_echo "$as_me: adding -mieee-fp to XTRA_CXXFLAGS" >&6;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+###      OCTAVE_CXX_FLAG(-ffloat-store, [
+###        float_store_flag=-ffloat-store
+###        XTRA_CXXFLAGS="$XTRA_CXXFLAGS -ffloat-store"
+###        AC_MSG_RESULT([adding -ffloat-store to XTRA_CXXFLAGS])])
+    fi
+  ;;
+  alpha*-*-*)
+    if test "$GCC" = yes; then
+
+  ac_safe=`echo "-mieee" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -mieee" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -mieee... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mieee"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+	ieee_fp_flag=-mieee
+	XTRA_CFLAGS="$XTRA_CFLAGS -mieee"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: adding -mieee to XTRA_CFLAGS" >&5
+$as_echo "$as_me: adding -mieee to XTRA_CFLAGS" >&6;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+    else
+
+  ac_safe=`echo "-ieee" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -ieee" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -ieee... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -ieee"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+	ieee_fp_flag=-ieee
+	XTRA_CFLAGS="$XTRA_CFLAGS -ieee"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: adding -ieee to XTRA_CFLAGS" >&5
+$as_echo "$as_me: adding -ieee to XTRA_CFLAGS" >&6;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+    fi
+    if test "$GXX" = yes; then
+
+  ac_safe=`echo "-mieee" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -mieee" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -mieee... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -mieee"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+	ieee_fp_flag=-mieee
+	XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mieee"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: adding -mieee to XTRA_CXXFLAGS" >&5
+$as_echo "$as_me: adding -mieee to XTRA_CXXFLAGS" >&6;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+    else
+
+  ac_safe=`echo "-ieee" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -ieee" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -ieee... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -ieee"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+	ieee_fp_flag=-ieee
+	XTRA_CXXFLAGS="$XTRA_CXXFLAGS -ieee"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: adding -ieee to XTRA_CXXFLAGS" >&5
+$as_echo "$as_me: adding -ieee to XTRA_CXXFLAGS" >&6;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+    fi
+  ;;
+  *ibm-aix4*)
+
+  ac_safe=`echo "-mminimal-toc" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -mminimal-toc" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -mminimal-toc... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mminimal-toc"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      XTRA_CFLAGS="$XTRA_CFLAGS -mminimal-toc"
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+
+  ac_safe=`echo "-mminimal-toc" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -mminimal-toc" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -mminimal-toc... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -mminimal-toc"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mminimal-toc"
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+  ;;
+esac
+
+
+
+
+### Use -static if compiling on Alpha OSF/1 1.3 systems.
+
+case "$canonical_host_type" in
+  alpha*-dec-osf1.3)
+    LD_STATIC_FLAG=-static
+  ;;
+esac
+if test -n "$LD_STATIC_FLAG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: defining LD_STATIC_FLAG to be $LD_STATIC_FLAG" >&5
+$as_echo "$as_me: defining LD_STATIC_FLAG to be $LD_STATIC_FLAG" >&6;}
+fi
+
+
+### Defaults for cross compiling.  BUILD_CC and BUILD_CXX are
+### the compilers that we use for building tools on the build system.
+### For now, we assume that the only cross compiling we can do is
+### with gcc on a Unixy system, but the dedicated hacker can override these.
+
+if test "$cross_compiling" = yes; then
+  BUILD_CC="gcc"
+  BUILD_CFLAGS="-O2 -g"
+  BUILD_CXX="g++"
+  BUILD_CXXFLAGS="-O2 -g"
+  BUILD_LDFLAGS=""
+  BUILD_EXEEXT=""
+else
+  BUILD_CC='$(CC)'
+  BUILD_CFLAGS='$(CFLAGS)'
+  BUILD_CXX='$(CXX)'
+  BUILD_CXXFLAGS='$(CXXFLAGS)'
+  BUILD_LDFLAGS='$(LDFLAGS)'
+  case "$canonical_host_type" in
+    sparc-sun-solaris2*)
+      if test "$GCC" != yes; then
+        ## The Sun C++ compiler never seems to complete compiling
+	## gendoc.cc unless we reduce the optimization level...
+	BUILD_CXXFLAGS="-g -O1"
+      fi
+    ;;
+  esac
+  BUILD_EXEEXT='$(EXEEXT)'
+fi
+
+
+
+
+
+
+
+
+
+### Look for math library.  If found, this will add -lm to LIBS.
+
+case "$canonical_host_type" in
+  *-*-nextstep*)
+  ;;
+  *-*-linux*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5
+$as_echo_n "checking for sin in -lm... " >&6; }
+if test "${ac_cv_lib_m_sin+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm -lc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sin ();
+int
+main ()
+{
+return sin ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_sin=yes
+else
+  ac_cv_lib_m_sin=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5
+$as_echo "$ac_cv_lib_m_sin" >&6; }
+if test "x$ac_cv_lib_m_sin" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+  ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5
+$as_echo_n "checking for sin in -lm... " >&6; }
+if test "${ac_cv_lib_m_sin+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sin ();
+int
+main ()
+{
+return sin ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_sin=yes
+else
+  ac_cv_lib_m_sin=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5
+$as_echo "$ac_cv_lib_m_sin" >&6; }
+if test "x$ac_cv_lib_m_sin" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+  ;;
+esac
+
+### Check for the QHull library
+
+ac_fn_c_check_header_mongrel "$LINENO" "qhull/qhull_a.h" "ac_cv_header_qhull_qhull_a_h" "$ac_includes_default"
+if test "x$ac_cv_header_qhull_qhull_a_h" = x""yes; then :
+  have_qhull=yes
+else
+  have_qhull=no
+fi
+
+
+if test "$have_qhull" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for qh_qhull in -lqhull" >&5
+$as_echo_n "checking for qh_qhull in -lqhull... " >&6; }
+if test "${ac_cv_lib_qhull_qh_qhull+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lqhull  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char qh_qhull ();
+int
+main ()
+{
+return qh_qhull ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_qhull_qh_qhull=yes
+else
+  ac_cv_lib_qhull_qh_qhull=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qhull_qh_qhull" >&5
+$as_echo "$ac_cv_lib_qhull_qh_qhull" >&6; }
+if test "x$ac_cv_lib_qhull_qh_qhull" = x""yes; then :
+  have_qhull=yes
+else
+  have_qhull=no
+fi
+
+  if test "$have_qhull" != yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for qh_qhull in -lqhull with qh_version" >&5
+$as_echo_n "checking for qh_qhull in -lqhull with qh_version... " >&6; }
+if test "${octave_cv_lib_qhull_version+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat > conftest.c <<EOF
+#include <stdio.h>
+char *qh_version = "version";
+char qh_qhull();
+int
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  qh_qhull();
+  return 0;
+}
+EOF
+
+octave_qhull_try="${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS conftest.c -o conftest -lqhull $LIBS"
+if (eval "$octave_qhull_try") 2>&5 && test -s conftest ; then
+    octave_cv_lib_qhull_version=yes
+else
+    octave_cv_lib_qhull_version=no
+fi
+rm -f conftest.c conftest.o conftest
+
+fi
+if test "$octave_cv_lib_qhull_version" = "yes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  have_qhull=yes
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  have_qhull=no
+fi
+
+
+$as_echo "#define NEED_QHULL_VERSION 1" >>confdefs.h
+
+  fi
+  if test "$have_qhull" = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the qhull library works" >&5
+$as_echo_n "checking whether the qhull library works... " >&6; }
+if test "${octave_cv_lib_qhull_ok+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  save_LIBS="$LIBS"
+  LIBS="$LIBS -lqhull"
+  case $host in
+    *-mingw*|*-msdosmsvc*) ;;
+    *) LIBS="$LIBS -lm" ;;
+  esac
+if test "$cross_compiling" = yes; then :
+  octave_cv_lib_qhull_ok=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <qhull/qhull.h>
+
+#ifdef NEED_QHULL_VERSION
+char *qh_version = "version";
+#endif
+int main()
+{
+  int dim = 2, n = 4;
+  coordT points[8] = { -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5 };
+  boolT ismalloc = 0;
+
+  return qh_new_qhull (dim, n, points, ismalloc, "qhull ", 0, stderr);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  octave_cv_lib_qhull_ok=yes
+else
+  octave_cv_lib_qhull_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+  LIBS="$save_LIBS"
+
+fi
+
+if test "$octave_cv_lib_qhull_ok" = "yes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  have_qhull=yes
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  have_qhull=bad
+fi
+
+  fi
+fi
+if test "$have_qhull" = yes; then
+
+$as_echo "#define HAVE_QHULL 1" >>confdefs.h
+
+  QHULL_LIBS="-lqhull"
+  TEXINFO_QHULL="@set HAVE_QHULL"
+else
+  if test "$have_qhull" = bad; then
+    warn_qhull="Qhull library found, but seems not to work properly --- This will result in loss of functionality of some geometry functions. Please try recompiling the library with -fno-strict-aliasing."
+  else
+    warn_qhull="Qhull library not found --- This will result in loss of functionality of some geometry functions."
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_qhull" >&5
+$as_echo "$as_me: WARNING: $warn_qhull" >&2;}
+fi
+
+
+
+### Check for pcre/regex library.
+
+## check for pcre-config, and if so, set CPPFLAGS appropriately
+# Extract the first word of "pcre-config", so it can be a program name with args.
+set dummy pcre-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_WITH_PCRE_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$WITH_PCRE_CONFIG"; then
+  ac_cv_prog_WITH_PCRE_CONFIG="$WITH_PCRE_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_WITH_PCRE_CONFIG="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_WITH_PCRE_CONFIG" && ac_cv_prog_WITH_PCRE_CONFIG="no"
+fi
+fi
+WITH_PCRE_CONFIG=$ac_cv_prog_WITH_PCRE_CONFIG
+if test -n "$WITH_PCRE_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WITH_PCRE_CONFIG" >&5
+$as_echo "$WITH_PCRE_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test $WITH_PCRE_CONFIG = yes ; then
+  CPPFLAGS="$CPPFLAGS $(pcre-config --cflags)"
+fi
+
+## NB: no need to do separate check for pcre.h header -- checking macros is good enough
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pcre.h defines the macros we need" >&5
+$as_echo_n "checking whether pcre.h defines the macros we need... " >&6; }
+if test "${ac_cv_pcre_h_macros_present+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <pcre.h>
+#if defined (PCRE_INFO_NAMECOUNT) \
+  && defined (PCRE_INFO_NAMEENTRYSIZE) \
+  && defined (PCRE_INFO_NAMETABLE)
+PCRE_HAS_MACROS_WE_NEED
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "PCRE_HAS_MACROS_WE_NEED" >/dev/null 2>&1; then :
+  ac_cv_pcre_h_macros_present=yes
+else
+  ac_cv_pcre_h_macros_present=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pcre_h_macros_present" >&5
+$as_echo "$ac_cv_pcre_h_macros_present" >&6; }
+WITH_PCRE="$ac_cv_pcre_h_macros_present"
+
+REGEX_LIBS=
+
+using_pcre=no
+using_regex=no
+
+if test "$WITH_PCRE" = yes; then
+  if test "$WITH_PCRE_CONFIG" = yes; then
+    REGEX_LIBS=$(pcre-config --libs)
+  else
+    REGEX_LIBS=-lpcre
+  fi
+  save_LIBS="$LIBS"
+  LIBS="$REGEX_LIBS $LIBS"
+  for ac_func in pcre_compile
+do :
+  ac_fn_c_check_func "$LINENO" "pcre_compile" "ac_cv_func_pcre_compile"
+if test "x$ac_cv_func_pcre_compile" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PCRE_COMPILE 1
+_ACEOF
+ using_pcre=yes
+
+$as_echo "#define HAVE_PCRE 1" >>confdefs.h
+
+else
+
+      REGEX_LIBS=
+      warn_pcre="PCRE library not found.  This will result in some loss of functionality for the regular expression matching functions."
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_pcre" >&5
+$as_echo "$as_me: WARNING: $warn_pcre" >&2;}
+fi
+done
+
+  LIBS="$save_LIBS"
+else
+  warn_pcre="PCRE library not found.  This will result in some loss of functionality for the regular expression matching functions."
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_pcre" >&5
+$as_echo "$as_me: WARNING: $warn_pcre" >&2;}
+fi
+
+for ac_func in regexec
+do :
+  ac_fn_c_check_func "$LINENO" "regexec" "ac_cv_func_regexec"
+if test "x$ac_cv_func_regexec" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_REGEXEC 1
+_ACEOF
+ using_regex=yes
+else
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for regexec in -lregex" >&5
+$as_echo_n "checking for regexec in -lregex... " >&6; }
+if test "${ac_cv_lib_regex_regexec+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lregex  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char regexec ();
+int
+main ()
+{
+return regexec ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_regex_regexec=yes
+else
+  ac_cv_lib_regex_regexec=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_regex_regexec" >&5
+$as_echo "$ac_cv_lib_regex_regexec" >&6; }
+if test "x$ac_cv_lib_regex_regexec" = x""yes; then :
+  using_regex=yes
+    REGEX_LIBS="-lregex $REGEX_LIBS"
+else
+
+      warn_regex="regular expression functions not found.  The regular expression matching functions will be disabled."
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_regex" >&5
+$as_echo "$as_me: WARNING: $warn_regex" >&2;}
+fi
+
+fi
+done
+
+
+if test "$using_regex" = yes; then
+
+$as_echo "#define HAVE_REGEX 1" >>confdefs.h
+
+fi
+
+
+
+### Check for ZLIB library.
+
+WITH_ZLIB=true
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+  withval=$with_zlib; with_zlib=$withval
+else
+  with_zlib=yes
+fi
+
+
+zlib_lib=
+if test "$with_zlib" = yes; then
+  zlib_lib="z"
+elif test "$with_zlib" != no; then
+  zlib_lib="$with_zlib"
+fi
+
+ZLIB_LIBS=
+WITH_ZLIB=false
+if test -n "$zlib_lib"; then
+  as_ac_Lib=`$as_echo "ac_cv_lib_$zlib_lib''_gzclearerr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzclearerr in -l$zlib_lib" >&5
+$as_echo_n "checking for gzclearerr in -l$zlib_lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$zlib_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gzclearerr ();
+int
+main ()
+{
+return gzclearerr ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+
+      for ac_header in zlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ZLIB_H 1
+_ACEOF
+
+	WITH_ZLIB=true
+        ZLIB_LIBS="-l$zlib_lib"
+        LIBS="$ZLIB_LIBS $LIBS"
+
+$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
+
+fi
+
+done
+
+fi
+
+fi
+
+if $WITH_ZLIB; then
+  ### Check for HDF5 library.
+
+  WITH_HDF5=true
+
+# Check whether --with-hdf5 was given.
+if test "${with_hdf5+set}" = set; then :
+  withval=$with_hdf5; with_hdf5=$withval
+else
+  with_hdf5=yes
+fi
+
+
+  hdf5_lib=
+  if test "$with_hdf5" = yes; then
+    hdf5_lib="hdf5"
+  elif test "$with_hdf5" != no; then
+    hdf5_lib="$with_hdf5"
+  fi
+
+  HDF5_LIBS=
+  WITH_HDF5=false
+  if test -n "$hdf5_lib"; then
+    as_ac_Lib=`$as_echo "ac_cv_lib_$hdf5_lib''_H5Pcreate" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for H5Pcreate in -l$hdf5_lib" >&5
+$as_echo_n "checking for H5Pcreate in -l$hdf5_lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$hdf5_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char H5Pcreate ();
+int
+main ()
+{
+return H5Pcreate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+
+      for ac_header in hdf5.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "hdf5.h" "ac_cv_header_hdf5_h" "$ac_includes_default"
+if test "x$ac_cv_header_hdf5_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_HDF5_H 1
+_ACEOF
+
+        WITH_HDF5=true
+        HDF5_LIBS="-l$hdf5_lib"
+        LIBS="$HDF5_LIBS $LIBS"
+	as_ac_Lib=`$as_echo "ac_cv_lib_$hdf5_lib''_H5Gget_num_objs" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for H5Gget_num_objs in -l$hdf5_lib" >&5
+$as_echo_n "checking for H5Gget_num_objs in -l$hdf5_lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$hdf5_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char H5Gget_num_objs ();
+int
+main ()
+{
+return H5Gget_num_objs ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether HDF5 library has required API" >&5
+$as_echo_n "checking whether HDF5 library has required API... " >&6; }
+if test "${octave_cv_hdf5_has_required_api+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define H5_USE_16_API 1
+#include <hdf5.h>
+
+int
+main ()
+{
+
+  H5Eset_auto (0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+      octave_cv_hdf5_has_required_api=yes
+else
+
+      octave_cv_hdf5_has_required_api=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_hdf5_has_required_api" >&5
+$as_echo "$octave_cv_hdf5_has_required_api" >&6; }
+  if test "$octave_cv_hdf5_has_required_api" = "no"; then
+    WITH_HDF5=false
+    warn_hdf5="HDF5 library does not provide the version 1.6 API.  Octave will not be able to save or load HDF5 data files."
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_hdf5" >&5
+$as_echo "$as_me: WARNING: $warn_hdf5" >&2;}
+  fi
+
+          if test $WITH_HDF5; then
+
+$as_echo "#define HAVE_HDF5 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_H5GGET_NUM_OBJS 1" >>confdefs.h
+
+	  fi
+fi
+
+fi
+
+done
+
+fi
+
+  fi
+
+  if $WITH_HDF5; then
+    case "$canonical_host_type" in
+      *-*-msdosmsvc)
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _HDF5USEDLL_ needs to be defined" >&5
+$as_echo_n "checking if _HDF5USEDLL_ needs to be defined... " >&6; }
+if test "${octave_cv_hdf5_dll+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <hdf5.h>
+int
+main ()
+{
+hid_t x = H5T_NATIVE_DOUBLE; return x
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  octave_cv_hdf5_dll=no
+else
+
+      CFLAGS_old=$CFLAGS
+      CFLAGS="$CFLAGS -DWIN32 -D_HDF5USEDLL_"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <hdf5.h>
+int
+main ()
+{
+hid_t x = H5T_NATIVE_DOUBLE; return x
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  octave_cv_hdf5_dll=yes
+else
+  octave_cv_hdf5_dll=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+      CFLAGS=$CFLAGS_old
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_hdf5_dll" >&5
+$as_echo "$octave_cv_hdf5_dll" >&6; }
+  if test "$octave_cv_hdf5_dll" = yes; then
+
+$as_echo "#define _HDF5USEDLL_ 1" >>confdefs.h
+
+  fi
+        ;;
+    esac
+    true
+  fi
+else
+  warn_zlib="ZLIB library not found.  Octave will not be able to save or load compressed data files or HDF5 files."
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_zlib" >&5
+$as_echo "$as_me: WARNING: $warn_zlib" >&2;}
+fi
+
+
+# Checks for FFTW header and library.
+
+# subdirectories of libcruft to build if they aren't found on the system:
+FFT_DIR="fftpack"
+
+
+# Installed fftw library, if any.
+FFTW_LIBS=''
+
+
+
+# Check whether --with-fftw was given.
+if test "${with_fftw+set}" = set; then :
+  withval=$with_fftw; with_fftw=$withval
+else
+  with_fftw=yes
+fi
+
+
+if test "$with_fftw" = yes; then
+  have_fftw3_header=no
+  with_fftw3=no
+  ac_fn_c_check_header_mongrel "$LINENO" "fftw3.h" "ac_cv_header_fftw3_h" "$ac_includes_default"
+if test "x$ac_cv_header_fftw3_h" = x""yes; then :
+  have_fftw3_header=yes
+fi
+
+
+  if test "$have_fftw3_header" = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw_plan_dft_1d in -lfftw3" >&5
+$as_echo_n "checking for fftw_plan_dft_1d in -lfftw3... " >&6; }
+if test "${ac_cv_lib_fftw3_fftw_plan_dft_1d+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fftw_plan_dft_1d ();
+int
+main ()
+{
+return fftw_plan_dft_1d ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_fftw3_fftw_plan_dft_1d=yes
+else
+  ac_cv_lib_fftw3_fftw_plan_dft_1d=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3_fftw_plan_dft_1d" >&5
+$as_echo "$ac_cv_lib_fftw3_fftw_plan_dft_1d" >&6; }
+if test "x$ac_cv_lib_fftw3_fftw_plan_dft_1d" = x""yes; then :
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftwf_plan_dft_1d in -lfftw3f" >&5
+$as_echo_n "checking for fftwf_plan_dft_1d in -lfftw3f... " >&6; }
+if test "${ac_cv_lib_fftw3f_fftwf_plan_dft_1d+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3f  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fftwf_plan_dft_1d ();
+int
+main ()
+{
+return fftwf_plan_dft_1d ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_fftw3f_fftwf_plan_dft_1d=yes
+else
+  ac_cv_lib_fftw3f_fftwf_plan_dft_1d=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3f_fftwf_plan_dft_1d" >&5
+$as_echo "$ac_cv_lib_fftw3f_fftwf_plan_dft_1d" >&6; }
+if test "x$ac_cv_lib_fftw3f_fftwf_plan_dft_1d" = x""yes; then :
+  FFTW_LIBS="-lfftw3 -lfftw3f"; with_fftw3=yes
+fi
+
+fi
+
+  fi
+fi
+
+if test "$with_fftw" = yes && test "$with_fftw3" = yes; then
+  FFT_DIR=''
+
+$as_echo "#define HAVE_FFTW3 1" >>confdefs.h
+
+else
+  warn_fftw="FFTW library not found.  Octave will use the (slower) FFTPACK library instead."
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $warn_fftw" >&5
+$as_echo "$warn_fftw" >&6; }
+fi
+
+# Checks for GLPK header and library.
+
+
+# Check whether --with-glpk was given.
+if test "${with_glpk+set}" = set; then :
+  withval=$with_glpk; with_glpk=$withval
+else
+  with_glpk=yes
+fi
+
+
+glpk_lib=
+if test "$with_glpk" = yes; then
+  glpk_lib="glpk"
+elif test "$with_glpk" != no; then
+  glpk_lib="$with_glpk"
+fi
+
+GLPK_LIBS=
+if test -n "$glpk_lib"; then
+  for ac_header in glpk/glpk.h glpk.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    as_ac_Lib=`$as_echo "ac_cv_lib_$glpk_lib''_glp_lpx_simplex" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glp_lpx_simplex in -l$glpk_lib" >&5
+$as_echo_n "checking for glp_lpx_simplex in -l$glpk_lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$glpk_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char glp_lpx_simplex ();
+int
+main ()
+{
+return glp_lpx_simplex ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+
+      GLPK_LIBS="-l$glpk_lib"
+
+$as_echo "#define GLPK_PRE_4_14 1" >>confdefs.h
+
+else
+
+        as_ac_Lib=`$as_echo "ac_cv_lib_$glpk_lib''__glp_lpx_simplex" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _glp_lpx_simplex in -l$glpk_lib" >&5
+$as_echo_n "checking for _glp_lpx_simplex in -l$glpk_lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$glpk_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _glp_lpx_simplex ();
+int
+main ()
+{
+return _glp_lpx_simplex ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+
+          GLPK_LIBS="-l$glpk_lib"
+fi
+
+fi
+
+
+    if test -n "$GLPK_LIBS"; then
+
+$as_echo "#define HAVE_GLPK 1" >>confdefs.h
+
+    fi
+    break
+fi
+
+done
+
+fi
+
+if test -z "$GLPK_LIBS"; then
+  warn_glpk="GLPK library not found.  The glpk function for solving linear programs will be disabled."
+fi
+
+# Checks for CURL header and library.
+
+
+# Check whether --with-curl was given.
+if test "${with_curl+set}" = set; then :
+  withval=$with_curl; with_curl=$withval
+else
+  with_curl=yes
+fi
+
+
+curl_lib=
+if test "$with_curl" = yes; then
+  curl_lib="curl"
+elif test "$with_curl" != no; then
+  curl_lib="$with_curl"
+else
+  curl_missing=yes
+fi
+
+CURL_LIBS=
+if test -n "$curl_lib"; then
+  as_ac_Lib=`$as_echo "ac_cv_lib_$curl_lib''_curl_easy_escape" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl_easy_escape in -l$curl_lib" >&5
+$as_echo_n "checking for curl_easy_escape in -l$curl_lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$curl_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char curl_easy_escape ();
+int
+main ()
+{
+return curl_easy_escape ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+
+    for ac_header in curl/curl.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default"
+if test "x$ac_cv_header_curl_curl_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CURL_CURL_H 1
+_ACEOF
+
+      CURL_LIBS="-l$curl_lib"
+
+$as_echo "#define HAVE_CURL 1" >>confdefs.h
+
+else
+
+      curl_missing=yes
+fi
+
+done
+
+fi
+
+fi
+
+if test "$curl_missing" = yes; then
+  warn_curl="cURL library not found.  The urlread and urlwrite functions will be disabled."
+fi
+
+# GraphicsMagick++
+
+warn_magick=
+for ac_prog in GraphicsMagick++-config GraphicsMagick-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_MAGICK_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MAGICK_CONFIG"; then
+  ac_cv_prog_MAGICK_CONFIG="$MAGICK_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MAGICK_CONFIG="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MAGICK_CONFIG=$ac_cv_prog_MAGICK_CONFIG
+if test -n "$MAGICK_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGICK_CONFIG" >&5
+$as_echo "$MAGICK_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$MAGICK_CONFIG" && break
+done
+
+if test -z "$MAGICK_CONFIG"; then
+  warn_magick="GraphicsMagick++ config script not found.  Assuming GraphicsMagic++ library and header files are missing, so imread will not be fully functional"
+else
+
+$as_echo "#define HAVE_MAGICK 1" >>confdefs.h
+
+fi
+
+# ---------------------------------------------------------------------
+
+## libraries needed for graphics
+
+warn_freetype=""
+warn_ftgl=""
+
+
+OPENGL_LIBS=
+
+### On MacOSX systems the OpenGL framework can be used
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${LD-ld} accepts -framework OpenGL" >&5
+$as_echo_n "checking whether ${LD-ld} accepts -framework OpenGL... " >&6; }
+  if test "${octave_cv_framework_OpenGL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    XLDFLAGS="$LDFLAGS"
+    LDFLAGS="$LDFLAGS -framework OpenGL"
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+int
+main ()
+{
+GLint par; glGetIntegerv (GL_VIEWPORT, &par);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_framework_OpenGL=yes"
+else
+  eval "octave_cv_framework_OpenGL=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    LDFLAGS="$XLDFLAGS"
+
+fi
+
+  if test "$octave_cv_framework_OpenGL" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+# Check whether --with-framework-opengl was given.
+if test "${with_framework_opengl+set}" = set; then :
+  withval=$with_framework_opengl; with_have_framework=$withval
+else
+  with_have_framework="yes"
+fi
+
+    if test "$with_have_framework" = "yes"; then
+      have_framework_opengl="yes"
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: framework rejected by --without-framework-opengl" >&5
+$as_echo "$as_me: framework rejected by --without-framework-opengl" >&6;}
+      have_framework_opengl="no"
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    have_framework_opengl="no"
+  fi
+
+
+if test $have_framework_opengl = "yes"; then
+
+$as_echo "#define HAVE_FRAMEWORK_OPENGL 1" >>confdefs.h
+
+  OPENGL_LIBS="-Wl,-framework -Wl,OpenGL"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: adding -Wl,-framework -Wl,OpenGL to OPENGL_LIBS" >&5
+$as_echo "$as_me: adding -Wl,-framework -Wl,OpenGL to OPENGL_LIBS" >&6;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gluTessCallback is called with \"(...)\"" >&5
+$as_echo_n "checking whether gluTessCallback is called with \"(...)\"... " >&6; }
+if test "${octave_cv_glutesscallback_threedots+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef HAVE_GL_GLU_H
+#include <GL/glu.h>
+#elif defined HAVE_OPENGL_GLU_H || defined HAVE_FRAMEWORK_OPENGL
+#include <OpenGL/glu.h>
+#endif
+int
+main ()
+{
+GLvoid (*func)(...); gluTessCallback(0, 0, func);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  octave_cv_glutesscallback_threedots="yes"
+else
+  octave_cv_glutesscallback_threedots="no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_glutesscallback_threedots" >&5
+$as_echo "$octave_cv_glutesscallback_threedots" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $octave_cv_glutesscallback_threedots = "yes"; then
+
+$as_echo "#define HAVE_GLUTESSCALLBACK_THREEDOTS 1" >>confdefs.h
+
+fi
+
+else
+  case $canonical_host_type in
+    *-*-mingw32* | *-*-msdosmsvc)
+      for ac_header in windows.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+
+fi
+
+done
+
+    ;;
+  esac
+  have_opengl_incs=no
+  for ac_header in GL/gl.h OpenGL/gl.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    for ac_header in GL/glu.h OpenGL/glu.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+      have_opengl_incs=yes; break
+fi
+
+done
+
+    break
+
+fi
+
+done
+
+
+  if test "$have_opengl_incs" = "yes"; then
+    case $canonical_host_type in
+      *-*-mingw32* | *-*-msdosmsvc)
+        save_LIBS="$LIBS"
+        LIBS="$LIBS -lopengl32"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glEnable in -lopengl32" >&5
+$as_echo_n "checking for glEnable in -lopengl32... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if defined (HAVE_GL_GL_H)
+#include <GL/gl.h>
+#elif defined (HAVE_OPENGL_GL_H)
+#include <OpenGL/gl.h>
+#endif
+
+int
+main ()
+{
+glEnable(GL_SMOOTH);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  OPENGL_LIBS="-lopengl32 -lglu32"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LIBS="$save_LIBS"
+        if test "x$OPENGL_LIBS" != "x"; then
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+        else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+        fi
+        ;;
+      *)
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -L/usr/X11R6/lib"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glEnable in -lGL" >&5
+$as_echo_n "checking for glEnable in -lGL... " >&6; }
+if test "${ac_cv_lib_GL_glEnable+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lGL  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char glEnable ();
+int
+main ()
+{
+return glEnable ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_GL_glEnable=yes
+else
+  ac_cv_lib_GL_glEnable=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glEnable" >&5
+$as_echo "$ac_cv_lib_GL_glEnable" >&6; }
+if test "x$ac_cv_lib_GL_glEnable" = x""yes; then :
+  OPENGL_LIBS="-L/usr/X11R6/lib -lGL -lGLU"
+fi
+
+        LDFLAGS="$save_LDFLAGS"
+        ;;
+    esac
+  fi
+fi
+
+
+if test -n "$OPENGL_LIBS"; then
+
+$as_echo "#define HAVE_OPENGL 1" >>confdefs.h
+
+
+## ftgl (needs freetype 2)
+
+# Check whether --with-ft-prefix was given.
+if test "${with_ft_prefix+set}" = set; then :
+  withval=$with_ft_prefix; ft_config_prefix="$withval"
+else
+  ft_config_prefix=""
+fi
+
+
+
+# Check whether --with-ft-exec-prefix was given.
+if test "${with_ft_exec_prefix+set}" = set; then :
+  withval=$with_ft_exec_prefix; ft_config_exec_prefix="$withval"
+else
+  ft_config_exec_prefix=""
+fi
+
+
+   # Check whether --enable-freetypetest was given.
+if test "${enable_freetypetest+set}" = set; then :
+  enableval=$enable_freetypetest;
+else
+  enable_fttest=yes
+fi
+
+
+   if test x$ft_config_exec_prefix != x ; then
+     ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix"
+     if test x${FT2_CONFIG+set} != xset ; then
+       FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config
+     fi
+   fi
+
+   if test x$ft_config_prefix != x ; then
+     ft_config_args="$ft_config_args --prefix=$ft_config_prefix"
+     if test x${FT2_CONFIG+set} != xset ; then
+       FT2_CONFIG=$ft_config_prefix/bin/freetype-config
+     fi
+   fi
+
+   # Extract the first word of "freetype-config", so it can be a program name with args.
+set dummy freetype-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_FT2_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $FT2_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_FT2_CONFIG="$FT2_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_FT2_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_FT2_CONFIG" && ac_cv_path_FT2_CONFIG="no"
+  ;;
+esac
+fi
+FT2_CONFIG=$ac_cv_path_FT2_CONFIG
+if test -n "$FT2_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FT2_CONFIG" >&5
+$as_echo "$FT2_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+   min_ft_version=9.0.3
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeType -- version >= $min_ft_version" >&5
+$as_echo_n "checking for FreeType -- version >= $min_ft_version... " >&6; }
+   no_ft=""
+   if test "$FT2_CONFIG" = "no" ; then
+     no_ft=yes
+   else
+     FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags`
+     FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs`
+     ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+     ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
+     ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+     ft_min_major_version=`echo $min_ft_version | \
+       sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+     ft_min_minor_version=`echo $min_ft_version | \
+       sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
+     ft_min_micro_version=`echo $min_ft_version | \
+       sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+     if test x$enable_fttest = xyes ; then
+       ft_config_is_lt=""
+       if test $ft_config_major_version -lt $ft_min_major_version ; then
+         ft_config_is_lt=yes
+       else
+         if test $ft_config_major_version -eq $ft_min_major_version ; then
+           if test $ft_config_minor_version -lt $ft_min_minor_version ; then
+             ft_config_is_lt=yes
+           else
+            if test $ft_config_minor_version -eq $ft_min_minor_version ; then
+               if test $ft_config_micro_version -lt $ft_min_micro_version ; then
+                 ft_config_is_lt=yes
+               fi
+             fi
+           fi
+         fi
+       fi
+       if test x$ft_config_is_lt = xyes ; then
+         no_ft=yes
+       else
+         ac_save_CFLAGS="$CFLAGS"
+         ac_save_LIBS="$LIBS"
+         CFLAGS="$CFLAGS $FT2_CFLAGS"
+         LIBS="$FT2_LIBS $LIBS"
+
+                                    if test "$cross_compiling" = yes; then :
+  echo $ECHO_N "cross compiling; assuming OK... $ECHO_C"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main()
+{
+  FT_Library library;
+  FT_Error  error;
+
+  error = FT_Init_FreeType(&library);
+
+  if (error)
+    return 1;
+  else
+  {
+    FT_Done_FreeType(library);
+    return 0;
+  }
+}
+
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  no_ft=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+         CFLAGS="$ac_save_CFLAGS"
+         LIBS="$ac_save_LIBS"
+       fi                  fi                  fi
+   if test x$no_ft = x ; then
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+     :
+   else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+     if test "$FT2_CONFIG" = "no" ; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+
+  The freetype-config script installed by FreeType 2 could not be found.
+  If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in
+  your path, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+       " >&5
+$as_echo "$as_me: WARNING:
+
+  The freetype-config script installed by FreeType 2 could not be found.
+  If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in
+  your path, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+       " >&2;}
+     else
+       if test x$ft_config_is_lt = xyes ; then
+         { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+
+  Your installed version of the FreeType 2 library is too old.
+  If you have different versions of FreeType 2, make sure that
+  correct values for --with-ft-prefix or --with-ft-exec-prefix
+  are used, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+         " >&5
+$as_echo "$as_me: WARNING:
+
+  Your installed version of the FreeType 2 library is too old.
+  If you have different versions of FreeType 2, make sure that
+  correct values for --with-ft-prefix or --with-ft-exec-prefix
+  are used, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+         " >&2;}
+       else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+
+  The FreeType test program failed to run.  If your system uses
+  shared libraries and they are installed outside the normal
+  system library path, make sure the variable LD_LIBRARY_PATH
+  (or whatever is appropiate for your system) is correctly set.
+         " >&5
+$as_echo "$as_me: WARNING:
+
+  The FreeType test program failed to run.  If your system uses
+  shared libraries and they are installed outside the normal
+  system library path, make sure the variable LD_LIBRARY_PATH
+  (or whatever is appropiate for your system) is correctly set.
+         " >&2;}
+       fi
+     fi
+
+     FT2_CFLAGS=""
+     FT2_LIBS=""
+     warn_freetype="FreeType library not found. Native renderer will not have on-screen text"
+   fi
+
+
+
+  if test -z "$warn_freetype"; then
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+      save_LIBS="$LIBS"
+      save_CXXFLAGS="$CXXFLAGS"
+      save_CPPFLAGS="$CPPFLAGS"
+      LIBS="$LIBS $FT2_LIBS $OPENGL_LIBS"
+      CXXFLAGS="$CXXFLAGS $FT2_CFLAGS"
+      CPPFLAGS="$CPPFLAGS $FT2_CFLAGS"
+      has_ftgl_h=yes
+
+for ac_header in FTGL/ftgl.h ftgl.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+else
+
+	for ac_header in FTGL/FTGL.h FTGL.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+
+$as_echo "#define HAVE_FTGL_UPPERCASE 1" >>confdefs.h
+
+	  break
+
+else
+  has_ftgl_h=no
+fi
+
+done
+
+fi
+
+done
+
+      if test "$has_ftgl_h" = yes; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FTGLTextureFont in -lftgl" >&5
+$as_echo_n "checking for FTGLTextureFont in -lftgl... " >&6; }
+	LIBS="$save_LIBS -lftgl $FT2_LIBS $OPENGL_LIBS"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef HAVE_FTGL_FTGL_H
+#ifdef HAVE_FTGL_UPPERCASE
+#include <FTGL/FTGL.h>
+#else
+#include <FTGL/ftgl.h>
+#endif
+#include <FTGL/FTGLTextureFont.h>
+#elif HAVE_FTGL_H
+#ifdef HAVE_FTGL_UPPERCASE
+#include <FTGL.h>
+#else
+#include <ftgl.h>
+#endif
+#include <FTGLTextureFont.h>
+#endif
+int
+main ()
+{
+
+FTGLTextureFont font("");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+          OPENGL_LIBS="-lftgl $FT2_LIBS $OPENGL_LIBS"
+	  LIBS="$save_LIBS"
+	  CPPFLAGS="$save_CPPFLAGS"
+
+$as_echo "#define HAVE_FTGL 1" >>confdefs.h
+
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	  XTRA_CXXFLAGS="$XTRA_CXXFLAGS $FT2_CFLAGS"
+else
+
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+          warn_ftgl="FTGL library not found. Native renderer will not have on-screen text"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LIBS="$save_LIBS"
+	CXXFLAGS="$save_CXXFLAGS"
+	CPPFLAGS="$save_CPPFLAGS"
+      else
+        warn_ftgl="FTGL headers not found. Native renderer will not have on-screen text"
+      fi
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  fi
+fi
+
+GRAPHICS_LIBS=
+GRAPHICS_CFLAGS=
+
+## fltk (www.fltk.org)
+
+# Check whether --with-fltk-prefix was given.
+if test "${with_fltk_prefix+set}" = set; then :
+  withval=$with_fltk_prefix; fltk_prefix="$withval"
+else
+  fltk_prefix=""
+fi
+
+
+# Check whether --with-fltk-exec-prefix was given.
+if test "${with_fltk_exec_prefix+set}" = set; then :
+  withval=$with_fltk_exec_prefix; fltk_exec_prefix="$withval"
+else
+  fltk_exec_prefix=""
+fi
+
+
+if test -n "$fltk_exec_prefix"; then
+  fltk_args="$fltk_args --exec-prefix=$fltk_exec_prefix"
+  if test "x${FLTK_CONFIG+set}" != xset ; then
+    FLTK_CONFIG="$fltk_exec_prefix/bin/fltk-config"
+  fi
+fi
+
+if test -n "$fltk_prefix"; then
+  fltk_args="$fltk_args --prefix=$fltk_prefix"
+  if test x${FLTK_CONFIG+set} != xset ; then
+    FLTK_CONFIG="$fltk_prefix/bin/fltk-config"
+  fi
+fi
+
+# Extract the first word of "fltk-config", so it can be a program name with args.
+set dummy fltk-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_FLTK_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $FLTK_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_FLTK_CONFIG="$FLTK_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_FLTK_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_FLTK_CONFIG" && ac_cv_path_FLTK_CONFIG="no"
+  ;;
+esac
+fi
+FLTK_CONFIG=$ac_cv_path_FLTK_CONFIG
+if test -n "$FLTK_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLTK_CONFIG" >&5
+$as_echo "$FLTK_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+warn_fltk_config=""
+warn_fltk_opengl=""
+
+if test "$FLTK_CONFIG" = "no" ; then
+  warn_fltk_config="FLTK config script not found.  Native graphics will be disabled."
+else
+  FLTK_CFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --cflags`"
+  FLTK_LDFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags`"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL support in FLTK" >&5
+$as_echo_n "checking for OpenGL support in FLTK... " >&6; }
+  cat > conftest.cc <<EOF
+  #include <FL/gl.h>
+  int nothing=0;
+EOF
+  $CXX $CXXFLAGS $FLTK_CFLAGS -c conftest.cc || \
+    warn_fltk_opengl="FLTK does not have OpenGL support.  Native graphics will be disabled."
+
+  if test -z "$warn_fltk_opengl"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FLTK 1" >>confdefs.h
+
+    GRAPHICS_CFLAGS="$FLTK_CFLAGS"
+    GRAPHICS_LIBS="$FLTK_LDFLAGS"
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IEEE 754 data format" >&5
+$as_echo_n "checking for IEEE 754 data format... " >&6; }
+if test "${octave_cv_ieee754_data_format+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  octave_cv_ieee754_data_format=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+  typedef union { unsigned char c[8]; double d; } ieeebytes;
+
+  ieeebytes l = {0x1c, 0xbc, 0x6e, 0xf2, 0x54, 0x8b, 0x11, 0x43};
+  ieeebytes b = {0x43, 0x11, 0x8b, 0x54, 0xf2, 0x6e, 0xbc, 0x1c};
+
+  return l.d != 1234567891234567.0 && b.d != 1234567891234567.0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  octave_cv_ieee754_data_format=yes
+else
+  octave_cv_ieee754_data_format=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+if test "$cross_compiling" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_ieee754_data_format assumed for cross compilation" >&5
+$as_echo "$octave_cv_ieee754_data_format assumed for cross compilation" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_ieee754_data_format" >&5
+$as_echo "$octave_cv_ieee754_data_format" >&6; }
+fi
+if test "$octave_cv_ieee754_data_format" = yes; then
+
+$as_echo "#define HAVE_IEEE754_DATA_FORMAT 1" >>confdefs.h
+
+fi
+
+
+# ----------------------------------------------------------------------
+
+if test -z "$AR"; then
+  AR=ar
+fi
+
+
+if test -z "$ARFLAGS"; then
+  ARFLAGS="rc"
+fi
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+## Default FFLAGS is -O.
+if test "x$FFLAGS" = x; then
+  FFLAGS="-O"
+fi
+
+## the F77 variable, if set, overrides AC_PROG_F77 automatically
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5
+$as_echo "$F77" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_F77="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5
+$as_echo "$ac_ct_F77" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_F77" && break
+done
+
+  if test "x$ac_ct_F77" = x; then
+    F77=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    F77=$ac_ct_F77
+  fi
+fi
+
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; }
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5
+$as_echo "$ac_cv_f77_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5
+$as_echo_n "checking whether $F77 accepts -g... " >&6; }
+if test "${ac_cv_prog_f77_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  FFLAGS=-g
+cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_cv_prog_f77_g=yes
+else
+  ac_cv_prog_f77_g=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5
+$as_echo "$ac_cv_prog_f77_g" >&6; }
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+if test $ac_compiler_gnu = yes; then
+  G77=yes
+else
+  G77=
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get verbose linking output from $F77" >&5
+$as_echo_n "checking how to get verbose linking output from $F77... " >&6; }
+if test "${ac_cv_prog_f77_v+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_cv_prog_f77_v=
+# Try some options frequently used verbose output
+for ac_verb in -v -verbose --verbose -V -\#\#\#; do
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+
+# Compile and link our simple test program by passing a flag (argument
+# 1 to this macro) to the Fortran compiler in order to get
+# "verbose" output that we can then parse for the Fortran linker
+# flags.
+ac_save_FFLAGS=$FFLAGS
+FFLAGS="$FFLAGS $ac_verb"
+eval "set x $ac_link"
+shift
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_f77_v_output=`eval $ac_link 5>&1 2>&1 |
+  grep -v 'Driving:' | grep -v "^[_$as_cr_Letters][_$as_cr_alnum]*="`
+$as_echo "$ac_f77_v_output" >&5
+FFLAGS=$ac_save_FFLAGS
+
+rm -rf conftest*
+
+# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
+# /foo, /bar, and /baz are search directories for the Fortran linker.
+# Here, we change these into -L/foo -L/bar -L/baz (and put it first):
+ac_f77_v_output="`echo $ac_f77_v_output |
+	grep 'LPATH is:' |
+	sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output"
+
+# FIXME: we keep getting bitten by quoted arguments; a more general fix
+#        that detects unbalanced quotes in FLIBS should be implemented
+#        and (ugh) tested at some point.
+case $ac_f77_v_output in
+  # If we are using xlf then replace all the commas with spaces.
+  *xlfentry*)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/,/ /g'` ;;
+
+  # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
+  # $LIBS confuse us, and the libraries appear later in the output anyway).
+  *mGLOB_options_string*)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;;
+
+  # Portland Group compiler has singly- or doubly-quoted -cmdline argument
+  # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4.
+  # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
+  *-cmdline\ * | *-ignore\ * | *-def\ *)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed "\
+	s/-cmdline  *'[^']*'/ /g; s/-cmdline  *\"[^\"]*\"/ /g
+	s/-ignore  *'[^']*'/ /g; s/-ignore  *\"[^\"]*\"/ /g
+	s/-def  *'[^']*'/ /g; s/-def  *\"[^\"]*\"/ /g"` ;;
+
+  # If we are using Cray Fortran then delete quotes.
+  *cft90*)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"//g'` ;;
+esac
+
+
+  # look for -l* and *.a constructs in the output
+  for ac_arg in $ac_f77_v_output; do
+     case $ac_arg in
+	[\\/]*.a | ?:[\\/]*.a | -[lLRu]*)
+	  ac_cv_prog_f77_v=$ac_verb
+	  break 2 ;;
+     esac
+  done
+done
+if test -z "$ac_cv_prog_f77_v"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine how to obtain linking information from $F77" >&5
+$as_echo "$as_me: WARNING: cannot determine how to obtain linking information from $F77" >&2;}
+fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compilation failed" >&5
+$as_echo "$as_me: WARNING: compilation failed" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_v" >&5
+$as_echo "$ac_cv_prog_f77_v" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 libraries of $F77" >&5
+$as_echo_n "checking for Fortran 77 libraries of $F77... " >&6; }
+if test "${ac_cv_f77_libs+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$FLIBS" != "x"; then
+  ac_cv_f77_libs="$FLIBS" # Let the user override the test.
+else
+
+cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+
+# Compile and link our simple test program by passing a flag (argument
+# 1 to this macro) to the Fortran compiler in order to get
+# "verbose" output that we can then parse for the Fortran linker
+# flags.
+ac_save_FFLAGS=$FFLAGS
+FFLAGS="$FFLAGS $ac_cv_prog_f77_v"
+eval "set x $ac_link"
+shift
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_f77_v_output=`eval $ac_link 5>&1 2>&1 |
+  grep -v 'Driving:' | grep -v "^[_$as_cr_Letters][_$as_cr_alnum]*="`
+$as_echo "$ac_f77_v_output" >&5
+FFLAGS=$ac_save_FFLAGS
+
+rm -rf conftest*
+
+# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
+# /foo, /bar, and /baz are search directories for the Fortran linker.
+# Here, we change these into -L/foo -L/bar -L/baz (and put it first):
+ac_f77_v_output="`echo $ac_f77_v_output |
+	grep 'LPATH is:' |
+	sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output"
+
+# FIXME: we keep getting bitten by quoted arguments; a more general fix
+#        that detects unbalanced quotes in FLIBS should be implemented
+#        and (ugh) tested at some point.
+case $ac_f77_v_output in
+  # If we are using xlf then replace all the commas with spaces.
+  *xlfentry*)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/,/ /g'` ;;
+
+  # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
+  # $LIBS confuse us, and the libraries appear later in the output anyway).
+  *mGLOB_options_string*)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;;
+
+  # Portland Group compiler has singly- or doubly-quoted -cmdline argument
+  # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4.
+  # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
+  *-cmdline\ * | *-ignore\ * | *-def\ *)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed "\
+	s/-cmdline  *'[^']*'/ /g; s/-cmdline  *\"[^\"]*\"/ /g
+	s/-ignore  *'[^']*'/ /g; s/-ignore  *\"[^\"]*\"/ /g
+	s/-def  *'[^']*'/ /g; s/-def  *\"[^\"]*\"/ /g"` ;;
+
+  # If we are using Cray Fortran then delete quotes.
+  *cft90*)
+    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"//g'` ;;
+esac
+
+
+
+ac_cv_f77_libs=
+
+# Save positional arguments (if any)
+ac_save_positional="$@"
+
+set X $ac_f77_v_output
+while test $# != 1; do
+  shift
+  ac_arg=$1
+  case $ac_arg in
+	[\\/]*.a | ?:[\\/]*.a)
+	    ac_exists=false
+  for ac_i in $ac_cv_f77_libs; do
+    if test x"$ac_arg" = x"$ac_i"; then
+      ac_exists=true
+      break
+    fi
+  done
+
+  if test x"$ac_exists" = xtrue; then :
+
+else
+  ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+fi
+	  ;;
+	-bI:*)
+	    ac_exists=false
+  for ac_i in $ac_cv_f77_libs; do
+    if test x"$ac_arg" = x"$ac_i"; then
+      ac_exists=true
+      break
+    fi
+  done
+
+  if test x"$ac_exists" = xtrue; then :
+
+else
+  if test "$ac_compiler_gnu" = yes; then
+  for ac_link_opt in $ac_arg; do
+    ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt"
+  done
+else
+  ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+fi
+fi
+	  ;;
+	  # Ignore these flags.
+	-lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -little \
+	  |-LANG:=* | -LIST:* | -LNO:*)
+	  ;;
+	-lkernel32)
+	  test x"$CYGWIN" != xyes && ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+	  ;;
+	-[LRuYz])
+	  # These flags, when seen by themselves, take an argument.
+	  # We remove the space between option and argument and re-iterate
+	  # unless we find an empty arg or a new option (starting with -)
+	  case $2 in
+	     "" | -*);;
+	     *)
+		ac_arg="$ac_arg$2"
+		shift; shift
+		set X $ac_arg "$@"
+		;;
+	  esac
+	  ;;
+	-YP,*)
+	  for ac_j in `$as_echo "$ac_arg" | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do
+	      ac_exists=false
+  for ac_i in $ac_cv_f77_libs; do
+    if test x"$ac_j" = x"$ac_i"; then
+      ac_exists=true
+      break
+    fi
+  done
+
+  if test x"$ac_exists" = xtrue; then :
+
+else
+  ac_arg="$ac_arg $ac_j"
+			       ac_cv_f77_libs="$ac_cv_f77_libs $ac_j"
+fi
+	  done
+	  ;;
+	-[lLR]*)
+	    ac_exists=false
+  for ac_i in $ac_cv_f77_libs; do
+    if test x"$ac_arg" = x"$ac_i"; then
+      ac_exists=true
+      break
+    fi
+  done
+
+  if test x"$ac_exists" = xtrue; then :
+
+else
+  ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+fi
+	  ;;
+	-zallextract*| -zdefaultextract)
+	  ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+	  ;;
+	  # Ignore everything else.
+  esac
+done
+# restore positional arguments
+set X $ac_save_positional; shift
+
+# We only consider "LD_RUN_PATH" on Solaris systems.  If this is seen,
+# then we insist that the "run path" must be an absolute path (i.e. it
+# must begin with a "/").
+case `(uname -sr) 2>/dev/null` in
+   "SunOS 5"*)
+      ac_ld_run_path=`$as_echo "$ac_f77_v_output" |
+			sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'`
+      test "x$ac_ld_run_path" != x &&
+	if test "$ac_compiler_gnu" = yes; then
+  for ac_link_opt in $ac_ld_run_path; do
+    ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt"
+  done
+else
+  ac_cv_f77_libs="$ac_cv_f77_libs $ac_ld_run_path"
+fi
+      ;;
+esac
+fi # test "x$[]_AC_LANG_PREFIX[]LIBS" = "x"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_libs" >&5
+$as_echo "$ac_cv_f77_libs" >&6; }
+FLIBS="$ac_cv_f77_libs"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dummy main to link with Fortran 77 libraries" >&5
+$as_echo_n "checking for dummy main to link with Fortran 77 libraries... " >&6; }
+if test "${ac_cv_f77_dummy_main+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_f77_dm_save_LIBS=$LIBS
+ LIBS="$LIBS $FLIBS"
+ ac_fortran_dm_var=F77_DUMMY_MAIN
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ # First, try linking without a dummy main:
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_fortran_dummy_main=none
+else
+  ac_cv_fortran_dummy_main=unknown
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+ if test $ac_cv_fortran_dummy_main = unknown; then
+   for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define $ac_fortran_dm_var $ac_func
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_fortran_dummy_main=$ac_func; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+   done
+ fi
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+ ac_cv_f77_dummy_main=$ac_cv_fortran_dummy_main
+ rm -rf conftest*
+ LIBS=$ac_f77_dm_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_dummy_main" >&5
+$as_echo "$ac_cv_f77_dummy_main" >&6; }
+F77_DUMMY_MAIN=$ac_cv_f77_dummy_main
+if test "$F77_DUMMY_MAIN" != unknown; then :
+  if test $F77_DUMMY_MAIN != none; then
+
+cat >>confdefs.h <<_ACEOF
+#define F77_DUMMY_MAIN $F77_DUMMY_MAIN
+_ACEOF
+
+  if test "x$ac_cv_fc_dummy_main" = "x$ac_cv_f77_dummy_main"; then
+
+$as_echo "#define FC_DUMMY_MAIN_EQ_F77 1" >>confdefs.h
+
+  fi
+fi
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "linking to Fortran libraries from C fails
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 name-mangling scheme" >&5
+$as_echo_n "checking for Fortran 77 name-mangling scheme... " >&6; }
+if test "${ac_cv_f77_mangling+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      subroutine foobar()
+      return
+      end
+      subroutine foo_bar()
+      return
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  mv conftest.$ac_objext cfortran_test.$ac_objext
+
+  ac_save_LIBS=$LIBS
+  LIBS="cfortran_test.$ac_objext $LIBS $FLIBS"
+
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+  ac_success=no
+  for ac_foobar in foobar FOOBAR; do
+    for ac_underscore in "" "_"; do
+      ac_func="$ac_foobar$ac_underscore"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_success=yes; break 2
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    done
+  done
+  ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+  if test "$ac_success" = "yes"; then
+     case $ac_foobar in
+	foobar)
+	   ac_case=lower
+	   ac_foo_bar=foo_bar
+	   ;;
+	FOOBAR)
+	   ac_case=upper
+	   ac_foo_bar=FOO_BAR
+	   ;;
+     esac
+
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+     ac_success_extra=no
+     for ac_extra in "" "_"; do
+	ac_func="$ac_foo_bar$ac_underscore$ac_extra"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_success_extra=yes; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     done
+     ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+     if test "$ac_success_extra" = "yes"; then
+	ac_cv_f77_mangling="$ac_case case"
+	if test -z "$ac_underscore"; then
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, no underscore"
+	else
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, underscore"
+	fi
+	if test -z "$ac_extra"; then
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, no extra underscore"
+	else
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, extra underscore"
+	fi
+      else
+	ac_cv_f77_mangling="unknown"
+      fi
+  else
+     ac_cv_f77_mangling="unknown"
+  fi
+
+  LIBS=$ac_save_LIBS
+  rm -rf conftest*
+  rm -f cfortran_test*
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compile a simple Fortran program
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_mangling" >&5
+$as_echo "$ac_cv_f77_mangling" >&6; }
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+case $ac_cv_f77_mangling in
+  "lower case, no underscore, no extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) name" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) name" >>confdefs.h
+ ;;
+  "lower case, no underscore, extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) name" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) name ## _" >>confdefs.h
+ ;;
+  "lower case, underscore, no extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) name ## _" >>confdefs.h
+ ;;
+  "lower case, underscore, extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) name ## __" >>confdefs.h
+ ;;
+  "upper case, no underscore, no extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) NAME" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME" >>confdefs.h
+ ;;
+  "upper case, no underscore, extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) NAME" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME ## _" >>confdefs.h
+ ;;
+  "upper case, underscore, no extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) NAME ## _" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME ## _" >>confdefs.h
+ ;;
+  "upper case, underscore, extra underscore")
+	  $as_echo "#define F77_FUNC(name,NAME) NAME ## _" >>confdefs.h
+
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME ## __" >>confdefs.h
+ ;;
+  *)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unknown Fortran name-mangling scheme" >&5
+$as_echo "$as_me: WARNING: unknown Fortran name-mangling scheme" >&2;}
+	  ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+F77_TOLOWER=true
+F77_APPEND_UNDERSCORE=true
+F77_APPEND_EXTRA_UNDERSCORE=true
+
+case "$ac_cv_f77_mangling" in
+  "upper case") F77_TOLOWER=false ;;
+esac
+case "$ac_cv_f77_mangling" in
+  "no underscore") F77_APPEND_UNDERSCORE=false ;;
+esac
+case "$ac_cv_f77_mangling" in
+  "no extra underscore") F77_APPEND_EXTRA_UNDERSCORE=false ;;
+esac
+
+case "$canonical_host_type" in
+  i[3456789]86-*-*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+
+  ac_safe=`echo "-mieee-fp" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${F77-g77} accepts -mieee-fp" >&5
+$as_echo_n "checking whether ${F77-g77} accepts -mieee-fp... " >&6; }
+  if { as_var=octave_cv_f77_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+    XFFLAGS="$FFLAGS"
+    FFLAGS="$FFLAGS -mieee-fp"
+    cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  eval "octave_cv_f77_flag_$ac_safe=yes"
+else
+  eval "octave_cv_f77_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    FFLAGS="$XFFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      FFLAGS="$FFLAGS -mieee-fp"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -mieee-fp to FFLAGS" >&5
+$as_echo "adding -mieee-fp to FFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+###      OCTAVE_F77_FLAG(-ffloat-store)
+    fi
+  ;;
+  alpha*-*-*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+
+  ac_safe=`echo "-mieee" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${F77-g77} accepts -mieee" >&5
+$as_echo_n "checking whether ${F77-g77} accepts -mieee... " >&6; }
+  if { as_var=octave_cv_f77_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+    XFFLAGS="$FFLAGS"
+    FFLAGS="$FFLAGS -mieee"
+    cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  eval "octave_cv_f77_flag_$ac_safe=yes"
+else
+  eval "octave_cv_f77_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    FFLAGS="$XFFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      FFLAGS="$FFLAGS -mieee"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -mieee to FFLAGS" >&5
+$as_echo "adding -mieee to FFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+    else
+
+  ac_safe=`echo "-ieee" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${F77-g77} accepts -ieee" >&5
+$as_echo_n "checking whether ${F77-g77} accepts -ieee... " >&6; }
+  if { as_var=octave_cv_f77_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+    XFFLAGS="$FFLAGS"
+    FFLAGS="$FFLAGS -ieee"
+    cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  eval "octave_cv_f77_flag_$ac_safe=yes"
+else
+  eval "octave_cv_f77_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    FFLAGS="$XFFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      FFLAGS="$FFLAGS -ieee"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -ieee to FFLAGS" >&5
+$as_echo "adding -ieee to FFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-fpe1" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${F77-g77} accepts -fpe1" >&5
+$as_echo_n "checking whether ${F77-g77} accepts -fpe1... " >&6; }
+  if { as_var=octave_cv_f77_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+    XFFLAGS="$FFLAGS"
+    FFLAGS="$FFLAGS -fpe1"
+    cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  eval "octave_cv_f77_flag_$ac_safe=yes"
+else
+  eval "octave_cv_f77_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    FFLAGS="$XFFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      FFLAGS="$FFLAGS -fpe1"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -fpe1 to FFLAGS" >&5
+$as_echo "adding -fpe1 to FFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+    fi
+  ;;
+  powerpc-apple-machten*)
+    FFLAGS=
+  ;;
+esac
+
+if test -n "$FFLAGS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: defining FFLAGS to be $FFLAGS" >&5
+$as_echo "$as_me: defining FFLAGS to be $FFLAGS" >&6;}
+fi
+
+
+
+
+
+if test -z "$F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: in order to build octave, you must have a compatible" >&5
+$as_echo "$as_me: WARNING: in order to build octave, you must have a compatible" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Fortran compiler or wrapper script for f2c that functions" >&5
+$as_echo "$as_me: WARNING: Fortran compiler or wrapper script for f2c that functions" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: as a Fortran compiler installed and in your path." >&5
+$as_echo "$as_me: WARNING: as a Fortran compiler installed and in your path." >&2;}
+  as_fn_error "See the file INSTALL for more information." "$LINENO" 5
+fi
+
+XTRA_CRUFT_SH_LDFLAGS=
+case "$canonical_host_type" in
+  *-*-msdosmsvc)
+    FLIBS="$FLIBS -lkernel32"
+    XTRA_CRUFT_SH_LDFLAGS="-Wl,-def:cruft.def"
+  ;;
+esac
+
+
+FC=$F77
+
+
+
+  ac_safe=`echo "-ffloat-store" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${F77-g77} accepts -ffloat-store" >&5
+$as_echo_n "checking whether ${F77-g77} accepts -ffloat-store... " >&6; }
+  if { as_var=octave_cv_f77_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+    XFFLAGS="$FFLAGS"
+    FFLAGS="$FFLAGS -ffloat-store"
+    cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  eval "octave_cv_f77_flag_$ac_safe=yes"
+else
+  eval "octave_cv_f77_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    FFLAGS="$XFFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: setting F77_FLOAT_STORE_FLAG to -ffloat-store" >&5
+$as_echo "setting F77_FLOAT_STORE_FLAG to -ffloat-store" >&6; }
+F77_FLOAT_STORE_FLAG=-ffloat-store
+
+
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+### Checks for BLAS and LAPACK libraries:
+# (Build subdirectories of libcruft if they aren't found on the system.)
+
+# ===========================================================================
+#           http://autoconf-archive.cryp.to/acx_blas_f77_func.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_BLAS_F77_FUNC([ACTION-IF-PASS[, ACTION-IF-FAIL[, ACTION-IF-CROSS-COMPILING]])
+#   ACX_BLAS_WITH_F77_FUNC([ACTION-IF-FOUND-AND-PASS[, ACTION-IF-NOT-FOUND-OR-FAIL]])
+#
+# DESCRIPTION
+#
+#   These macros are intended as a supplement to the ACX_BLAS macro, to
+#   verify that BLAS functions are properly callable from Fortran. This is
+#   necessary, for example, if you want to build the LAPACK library on top
+#   of the BLAS.
+#
+#   ACX_BLAS_F77_FUNC uses the defined BLAS_LIBS and Fortran environment to
+#   check for compatibility, and takes a specific action in case of success,
+#   resp. failure, resp. cross-compilation.
+#
+#   ACX_BLAS_WITH_F77_FUNC is a drop-in replacement wrapper for ACX_BLAS
+#   that calls ACX_BLAS_F77_FUNC after detecting a BLAS library and rejects
+#   it on failure (i.e. pretends that no library was found).
+#
+# LAST MODIFICATION
+#
+#   2008-06-18
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Jaroslav Hajek <highegg at gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+
+
+# ===========================================================================
+#               http://autoconf-archive.cryp.to/acx_lapack.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_LAPACK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the LAPACK linear-algebra
+#   interface (see http://www.netlib.org/lapack/). On success, it sets the
+#   LAPACK_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with LAPACK, you should link with:
+#
+#       $LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. BLAS_LIBS is the output variable of the ACX_BLAS macro,
+#   called automatically. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by ACX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   The user may also use --with-lapack=<lib> in order to use some specific
+#   LAPACK library <lib>. In order to link successfully, however, be aware
+#   that you will probably need to use the same Fortran compiler (which can
+#   be set via the F77 env. var.) as was used to compile the LAPACK and BLAS
+#   libraries.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a LAPACK library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_LAPACK.
+#
+# LAST MODIFICATION
+#
+#   2008-06-29
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+
+
+
+
+
+
+acx_blas_ok=no
+
+
+# Check whether --with-blas was given.
+if test "${with_blas+set}" = set; then :
+  withval=$with_blas;
+fi
+
+case $with_blas in
+	yes | "") ;;
+	no) acx_blas_ok=disable ;;
+	-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;;
+	*) BLAS_LIBS="-l$with_blas" ;;
+esac
+
+# Get fortran linker names of BLAS functions to check for.
+if $have_fortran_compiler; then
+  ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+case $ac_cv_f77_mangling in
+  upper*) ac_val="SGEMM" ;;
+  lower*) ac_val="sgemm" ;;
+  *)      ac_val="unknown" ;;
+esac
+case $ac_cv_f77_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+
+sgemm="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+case $ac_cv_f77_mangling in
+  upper*) ac_val="DGEMM" ;;
+  lower*) ac_val="dgemm" ;;
+  *)      ac_val="unknown" ;;
+esac
+case $ac_cv_f77_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+
+dgemm="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+elif $have_f2c; then
+  sgemm=sgemm_
+  dgemm=dgemm_
+fi
+
+acx_blas_save_LIBS="$LIBS"
+LIBS="$LIBS $FLIBS"
+
+# First, check BLAS_LIBS environment variable
+if test $acx_blas_ok = no; then
+if test "x$BLAS_LIBS" != x; then
+	save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in $BLAS_LIBS" >&5
+$as_echo_n "checking for $sgemm in $BLAS_LIBS... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_blas_ok=yes
+else
+  BLAS_LIBS=""
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_ok" >&5
+$as_echo "$acx_blas_ok" >&6; }
+	LIBS="$save_LIBS"
+fi
+fi
+
+# BLAS linked to by default?  (happens on some supercomputers)
+if test $acx_blas_ok = no; then
+	save_LIBS="$LIBS"; LIBS="$LIBS"
+	as_ac_var=`$as_echo "ac_cv_func_$sgemm" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$sgemm" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes
+fi
+
+	LIBS="$save_LIBS"
+fi
+
+# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
+if test $acx_blas_ok = no; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ATL_xerbla in -latlas" >&5
+$as_echo_n "checking for ATL_xerbla in -latlas... " >&6; }
+if test "${ac_cv_lib_atlas_ATL_xerbla+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-latlas  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ATL_xerbla ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return ATL_xerbla ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_atlas_ATL_xerbla=yes
+else
+  ac_cv_lib_atlas_ATL_xerbla=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_atlas_ATL_xerbla" >&5
+$as_echo "$ac_cv_lib_atlas_ATL_xerbla" >&6; }
+if test "x$ac_cv_lib_atlas_ATL_xerbla" = x""yes; then :
+  as_ac_Lib=`$as_echo "ac_cv_lib_f77blas_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lf77blas" >&5
+$as_echo_n "checking for $sgemm in -lf77blas... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lf77blas -latlas $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cblas_dgemm in -lcblas" >&5
+$as_echo_n "checking for cblas_dgemm in -lcblas... " >&6; }
+if test "${ac_cv_lib_cblas_cblas_dgemm+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcblas -lf77blas -latlas $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cblas_dgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return cblas_dgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_cblas_cblas_dgemm=yes
+else
+  ac_cv_lib_cblas_cblas_dgemm=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cblas_cblas_dgemm" >&5
+$as_echo "$ac_cv_lib_cblas_cblas_dgemm" >&6; }
+if test "x$ac_cv_lib_cblas_cblas_dgemm" = x""yes; then :
+  acx_blas_ok=yes
+			 BLAS_LIBS="-lcblas -lf77blas -latlas"
+fi
+
+fi
+
+fi
+
+fi
+
+# BLAS in Apple vecLib framework? (Mac OS X)
+if test $acx_blas_ok = no; then
+	vlib_flags="-Wl,-framework -Wl,vecLib"
+	save_LIBS="$LIBS"; LIBS="$vlib_flags $LIBS"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in $vlib_flags" >&5
+$as_echo_n "checking for $sgemm in $vlib_flags... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_blas_ok=yes; BLAS_LIBS="$vlib_flags"
+else
+  BLAS_LIBS=""
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_ok" >&5
+$as_echo "$acx_blas_ok" >&6; }
+	LIBS="$save_LIBS"
+fi
+
+# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_blas_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lblas" >&5
+$as_echo_n "checking for $sgemm in -lblas... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lblas  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  as_ac_Lib=`$as_echo "ac_cv_lib_dgemm_$dgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dgemm in -ldgemm" >&5
+$as_echo_n "checking for $dgemm in -ldgemm... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldgemm -lblas $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $dgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $dgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  as_ac_Lib=`$as_echo "ac_cv_lib_sgemm_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lsgemm" >&5
+$as_echo_n "checking for $sgemm in -lsgemm... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsgemm -lblas $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"
+fi
+
+fi
+
+fi
+
+fi
+
+# BLAS in Alpha CXML library?
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_cxml_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lcxml" >&5
+$as_echo_n "checking for $sgemm in -lcxml... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcxml  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes;BLAS_LIBS="-lcxml"
+fi
+
+fi
+
+# BLAS in Alpha DXML library? (now called CXML, see above)
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_dxml_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -ldxml" >&5
+$as_echo_n "checking for $sgemm in -ldxml... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldxml  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes;BLAS_LIBS="-ldxml"
+fi
+
+fi
+
+# BLAS in Sun Performance library?
+if test $acx_blas_ok = no; then
+	if test "x$GCC" != xyes; then # only works with Sun CC
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosp in -lsunmath" >&5
+$as_echo_n "checking for acosp in -lsunmath... " >&6; }
+if test "${ac_cv_lib_sunmath_acosp+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsunmath  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acosp ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return acosp ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_sunmath_acosp=yes
+else
+  ac_cv_lib_sunmath_acosp=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunmath_acosp" >&5
+$as_echo "$ac_cv_lib_sunmath_acosp" >&6; }
+if test "x$ac_cv_lib_sunmath_acosp" = x""yes; then :
+  as_ac_Lib=`$as_echo "ac_cv_lib_sunperf_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lsunperf" >&5
+$as_echo_n "checking for $sgemm in -lsunperf... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsunperf -lsunmath $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  BLAS_LIBS="-lsunperf -lsunmath"
+                                 acx_blas_ok=yes
+fi
+
+fi
+
+	fi
+fi
+
+# BLAS in SCSL library?  (SGI/Cray Scientific Library)
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_scs_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lscs" >&5
+$as_echo_n "checking for $sgemm in -lscs... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lscs  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes; BLAS_LIBS="-lscs"
+fi
+
+fi
+
+# BLAS in SGIMATH library?
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_complib.sgimath_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lcomplib.sgimath" >&5
+$as_echo_n "checking for $sgemm in -lcomplib.sgimath... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcomplib.sgimath  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"
+fi
+
+fi
+
+# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_blas_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lblas" >&5
+$as_echo_n "checking for $sgemm in -lblas... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lblas  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  as_ac_Lib=`$as_echo "ac_cv_lib_essl_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lessl" >&5
+$as_echo_n "checking for $sgemm in -lessl... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lessl -lblas $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes; BLAS_LIBS="-lessl -lblas"
+fi
+
+fi
+
+fi
+
+# Generic BLAS library?
+if test $acx_blas_ok = no; then
+	as_ac_Lib=`$as_echo "ac_cv_lib_blas_$sgemm" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sgemm in -lblas" >&5
+$as_echo_n "checking for $sgemm in -lblas... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lblas  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sgemm ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sgemm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_blas_ok=yes; BLAS_LIBS="-lblas"
+fi
+
+fi
+
+
+
+LIBS="$acx_blas_save_LIBS"
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_blas_ok" = xyes; then
+        # disable special action
+        :
+else
+        acx_blas_ok=no
+
+fi
+
+if test x$acx_blas_ok = xyes ; then
+
+
+
+
+# F77 call-compatibility checks
+if test "$cross_compiling" = yes ; then
+
+$as_echo "#define HAVE_BLAS 1" >>confdefs.h
+
+elif test x"$acx_blas_ok" = xyes; then
+	save_acx_blas_f77_func_LIBS="$LIBS"
+	LIBS="$BLAS_LIBS $LIBS"
+	ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+# LSAME check (LOGICAL return values)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether LSAME is called correctly from Fortran" >&5
+$as_echo_n "checking whether LSAME is called correctly from Fortran... " >&6; }
+	if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      logical lsame,w
+      external lsame
+      character c1,c2
+      c1 = 'A'
+      c2 = 'B'
+      w = lsame(c1,c2)
+      if (w) stop 1
+      w = lsame(c1,c1)
+      if (.not. w) stop 1
+
+      end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+  acx_blas_lsame_fcall_ok=yes
+else
+  acx_blas_lsame_fcall_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_lsame_fcall_ok" >&5
+$as_echo "$acx_blas_lsame_fcall_ok" >&6; }
+# ISAMAX check (INTEGER return values)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ISAMAX is called correctly from Fortran" >&5
+$as_echo_n "checking whether ISAMAX is called correctly from Fortran... " >&6; }
+	if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      integer isamax,i
+      external isamax
+      real a(2)
+      a(1) = 1e0
+      a(2) = -2e0
+      i = isamax(2,a,1)
+      if (i.ne.2) stop 1
+
+      end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+  acx_blas_isamax_fcall_ok=yes
+else
+  acx_blas_isamax_fcall_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_isamax_fcall_ok" >&5
+$as_echo "$acx_blas_isamax_fcall_ok" >&6; }
+# SDOT check (REAL return values)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SDOT is called correctly from Fortran" >&5
+$as_echo_n "checking whether SDOT is called correctly from Fortran... " >&6; }
+	if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      real sdot,a(1),b(1),w
+      external sdot
+      a(1) = 1e0
+      b(1) = 2e0
+      w = sdot(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+
+      end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+  acx_blas_sdot_fcall_ok=yes
+else
+  acx_blas_sdot_fcall_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_sdot_fcall_ok" >&5
+$as_echo "$acx_blas_sdot_fcall_ok" >&6; }
+# DDOT check (DOUBLE return values)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether DDOT is called correctly from Fortran" >&5
+$as_echo_n "checking whether DDOT is called correctly from Fortran... " >&6; }
+	if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      double precision ddot,a(1),b(1),w
+      external ddot
+      a(1) = 1d0
+      b(1) = 2d0
+      w = ddot(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+
+      end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+  acx_blas_ddot_fcall_ok=yes
+else
+  acx_blas_ddot_fcall_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_ddot_fcall_ok" >&5
+$as_echo "$acx_blas_ddot_fcall_ok" >&6; }
+# CDOTU check (COMPLEX return values)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CDOTU is called correctly from Fortran" >&5
+$as_echo_n "checking whether CDOTU is called correctly from Fortran... " >&6; }
+	if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      complex cdotu,a(1),b(1),w
+      external cdotu
+      a(1) = cmplx(1e0,1e0)
+      b(1) = cmplx(1e0,2e0)
+      w = cdotu(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+
+      end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+  acx_blas_cdotu_fcall_ok=yes
+else
+  acx_blas_cdotu_fcall_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_cdotu_fcall_ok" >&5
+$as_echo "$acx_blas_cdotu_fcall_ok" >&6; }
+# ZDOTU check (DOUBLE COMPLEX return values)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ZDOTU is called correctly from Fortran" >&5
+$as_echo_n "checking whether ZDOTU is called correctly from Fortran... " >&6; }
+	if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      double complex zdotu,a(1),b(1),w
+      external zdotu
+      a(1) = dcmplx(1d0,1d0)
+      b(1) = dcmplx(1d0,2d0)
+      w = zdotu(1,a,1,b,1)
+      if (w .ne. a(1)*b(1)) stop 1
+
+      end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+  acx_blas_zdotu_fcall_ok=yes
+else
+  acx_blas_zdotu_fcall_ok=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_blas_zdotu_fcall_ok" >&5
+$as_echo "$acx_blas_zdotu_fcall_ok" >&6; }
+
+	ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# if any of the tests failed, reject the BLAS library
+	if test $acx_blas_lsame_fcall_ok = yes \
+		-a $acx_blas_sdot_fcall_ok = yes \
+		-a $acx_blas_ddot_fcall_ok = yes \
+		-a $acx_blas_cdotu_fcall_ok = yes \
+		-a $acx_blas_zdotu_fcall_ok = yes ; then
+		acx_blas_f77_func_ok=yes;
+
+$as_echo "#define HAVE_BLAS 1" >>confdefs.h
+
+	else
+		acx_blas_f77_func_ok=no;
+		acx_blas_ok=no; BLAS_LIBS=
+	fi
+	LIBS="$save_acx_blas_f77_func_LIBS"
+fi
+
+
+fi
+if test x$acx_blas_ok = xno ; then
+	BLAS_DIR="blas"
+fi
+
+
+
+acx_lapack_ok=no
+
+
+# Check whether --with-lapack was given.
+if test "${with_lapack+set}" = set; then :
+  withval=$with_lapack;
+fi
+
+case $with_lapack in
+        yes | "") ;;
+        no) acx_lapack_ok=disable ;;
+        -* | */* | *.a | *.so | *.so.* | *.o) LAPACK_LIBS="$with_lapack" ;;
+        *) LAPACK_LIBS="-l$with_lapack" ;;
+esac
+
+# Get fortran linker name of LAPACK function to check for.
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+case $ac_cv_f77_mangling in
+  upper*) ac_val="CHEEV" ;;
+  lower*) ac_val="cheev" ;;
+  *)      ac_val="unknown" ;;
+esac
+case $ac_cv_f77_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+
+cheev="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# We cannot use LAPACK if BLAS is not found
+if test "x$acx_blas_ok" != xyes; then
+        acx_lapack_ok=noblas
+        LAPACK_LIBS=""
+fi
+
+# First, check LAPACK_LIBS environment variable
+if test "x$LAPACK_LIBS" != x; then
+        save_LIBS="$LIBS"; LIBS="$LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $cheev in $LAPACK_LIBS" >&5
+$as_echo_n "checking for $cheev in $LAPACK_LIBS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $cheev ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $cheev ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_lapack_ok=yes
+else
+  LAPACK_LIBS=""
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_lapack_ok" >&5
+$as_echo "$acx_lapack_ok" >&6; }
+        LIBS="$save_LIBS"
+        if test $acx_lapack_ok = no; then
+                LAPACK_LIBS=""
+        fi
+fi
+
+# LAPACK linked to by default?  (is sometimes included in BLAS lib)
+if test $acx_lapack_ok = no; then
+        save_LIBS="$LIBS"; LIBS="$LIBS $BLAS_LIBS $FLIBS"
+        as_ac_var=`$as_echo "ac_cv_func_$cheev" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$cheev" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  acx_lapack_ok=yes
+fi
+
+        LIBS="$save_LIBS"
+fi
+
+# Generic LAPACK library?
+for lapack in lapack lapack_rs6k; do
+        if test $acx_lapack_ok = no; then
+                save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
+                as_ac_Lib=`$as_echo "ac_cv_lib_$lapack''_$cheev" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $cheev in -l$lapack" >&5
+$as_echo_n "checking for $cheev in -l$lapack... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$lapack $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $cheev ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $cheev ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  acx_lapack_ok=yes; LAPACK_LIBS="-l$lapack"
+fi
+
+                LIBS="$save_LIBS"
+        fi
+done
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_lapack_ok" = xyes; then
+        BLAS_LIBS="$LAPACK_LIBS $BLAS_LIBS"
+        :
+else
+        acx_lapack_ok=no
+        LAPACK_DIR="lapack"
+fi
+
+
+
+
+if test "x$acx_blas_f77_func_ok" = "xno"; then
+  warn_blas_f77_incompatible="A BLAS library was detected but found incompatible with your Fortran 77 compiler.  The reference BLAS implementation will be used. To improve performance, consider using a different Fortran compiler or a switch like -ff2c to make your Fortran compiler use a calling convention compatible with the way your BLAS library was compiled, or use a different BLAS library."
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_blas_f77_incompatible" >&5
+$as_echo "$as_me: WARNING: $warn_blas_f77_incompatible" >&2;}
+fi
+
+QRUPDATE_LIBS=
+
+
+# Check for the qrupdate library
+
+# Check whether --with-qrupdate was given.
+if test "${with_qrupdate+set}" = set; then :
+  withval=$with_qrupdate; with_qrupdate=$withval
+else
+  with_qrupdate=yes
+fi
+
+
+warn_qrupdate="qrupdate not found. The QR & Cholesky updating functions will be slow."
+if test "$with_qrupdate" = yes; then
+  with_qrupdate=no
+  if $have_fortran_compiler; then
+    ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+case $ac_cv_f77_mangling in
+  upper*) ac_val="SQR1UP" ;;
+  lower*) ac_val="sqr1up" ;;
+  *)      ac_val="unknown" ;;
+esac
+case $ac_cv_f77_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+
+sqr1up="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  elif $have_f2c; then
+    sqr1up=sqr1up_
+  fi
+  as_ac_Lib=`$as_echo "ac_cv_lib_qrupdate_$sqr1up" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $sqr1up in -lqrupdate" >&5
+$as_echo_n "checking for $sqr1up in -lqrupdate... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lqrupdate $BLAS_LIBS $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $sqr1up ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return $sqr1up ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  QRUPDATE_LIBS="-lqrupdate"; with_qrupdate=yes
+fi
+
+  if test "$with_qrupdate" = yes; then
+
+$as_echo "#define HAVE_QRUPDATE 1" >>confdefs.h
+
+    warn_qrupdate=
+  fi
+fi
+if test -n "$warn_qrupdate"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_qrupdate" >&5
+$as_echo "$as_me: WARNING: $warn_qrupdate" >&2;}
+fi
+
+# Check for AMD library
+AMD_LIBS=
+
+
+
+# Check whether --with-amd was given.
+if test "${with_amd+set}" = set; then :
+  withval=$with_amd; with_amd=$withval
+else
+  with_amd=yes
+fi
+
+
+warn_amd="AMD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_amd" = yes; then
+  with_amd=no
+  for ac_header in suitesparse/amd.h ufsparse/amd.h amd/amd.h amd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for amd_postorder in -lamd" >&5
+$as_echo_n "checking for amd_postorder in -lamd... " >&6; }
+if test "${ac_cv_lib_amd_amd_postorder+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lamd  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char amd_postorder ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return amd_postorder ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_amd_amd_postorder=yes
+else
+  ac_cv_lib_amd_amd_postorder=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_amd_amd_postorder" >&5
+$as_echo "$ac_cv_lib_amd_amd_postorder" >&6; }
+if test "x$ac_cv_lib_amd_amd_postorder" = x""yes; then :
+  AMD_LIBS="-lamd"; with_amd=yes
+fi
+
+    if test "$with_amd" = yes; then
+
+$as_echo "#define HAVE_AMD 1" >>confdefs.h
+
+      warn_amd=
+    fi
+    break
+fi
+
+done
+
+fi
+if test -n "$warn_amd"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_amd" >&5
+$as_echo "$as_me: WARNING: $warn_amd" >&2;}
+fi
+
+# Check for CAMD library
+CAMD_LIBS=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for camd_postorder in -lcamd" >&5
+$as_echo_n "checking for camd_postorder in -lcamd... " >&6; }
+if test "${ac_cv_lib_camd_camd_postorder+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcamd  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char camd_postorder ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return camd_postorder ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_camd_camd_postorder=yes
+else
+  ac_cv_lib_camd_camd_postorder=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_camd_camd_postorder" >&5
+$as_echo "$ac_cv_lib_camd_camd_postorder" >&6; }
+if test "x$ac_cv_lib_camd_camd_postorder" = x""yes; then :
+  CAMD_LIBS="-lcamd"; with_camd=yes
+else
+  with_camd=no
+fi
+
+
+# Check for UMFPACK library.
+
+UMFPACK_LIBS=
+
+
+
+# Check whether --with-umfpack was given.
+if test "${with_umfpack+set}" = set; then :
+  withval=$with_umfpack; with_umfpack=$withval
+else
+  with_umfpack=yes
+fi
+
+
+warn_umfpack="UMFPACK not found.  This will result in some lack of functionality for sparse matrices."
+if test "$with_umfpack" = yes && test "$with_amd" = yes; then
+  with_umfpack=no
+  for ac_header in suitesparse/umfpack.h ufsparse/umfpack.h umfpack/umfpack.h umfpack.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for umfpack_zi_get_determinant in -lumfpack" >&5
+$as_echo_n "checking for umfpack_zi_get_determinant in -lumfpack... " >&6; }
+if test "${ac_cv_lib_umfpack_umfpack_zi_get_determinant+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lumfpack $AMD_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char umfpack_zi_get_determinant ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return umfpack_zi_get_determinant ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_umfpack_umfpack_zi_get_determinant=yes
+else
+  ac_cv_lib_umfpack_umfpack_zi_get_determinant=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_umfpack_umfpack_zi_get_determinant" >&5
+$as_echo "$ac_cv_lib_umfpack_umfpack_zi_get_determinant" >&6; }
+if test "x$ac_cv_lib_umfpack_umfpack_zi_get_determinant" = x""yes; then :
+
+      UMFPACK_LIBS="-lumfpack"; with_umfpack=yes
+else
+
+        ## Invalidate the cache.
+	$as_unset ac_cv_lib_umfpack_umfpack_zi_get_determinant
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for umfpack_zi_get_determinant in -lumfpack" >&5
+$as_echo_n "checking for umfpack_zi_get_determinant in -lumfpack... " >&6; }
+if test "${ac_cv_lib_umfpack_umfpack_zi_get_determinant+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lumfpack $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char umfpack_zi_get_determinant ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return umfpack_zi_get_determinant ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_umfpack_umfpack_zi_get_determinant=yes
+else
+  ac_cv_lib_umfpack_umfpack_zi_get_determinant=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_umfpack_umfpack_zi_get_determinant" >&5
+$as_echo "$ac_cv_lib_umfpack_umfpack_zi_get_determinant" >&6; }
+if test "x$ac_cv_lib_umfpack_umfpack_zi_get_determinant" = x""yes; then :
+
+          UMFPACK_LIBS="-lumfpack"; with_umfpack=yes
+else
+
+
+	  ## Invalidate the cache.
+	  $as_unset ac_cv_lib_umfpack_umfpack_zi_get_determinant
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for umfpack_zi_get_determinant in -lumfpack" >&5
+$as_echo_n "checking for umfpack_zi_get_determinant in -lumfpack... " >&6; }
+if test "${ac_cv_lib_umfpack_umfpack_zi_get_determinant+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lumfpack $AMD_LIBS -lcblas $BLAS_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char umfpack_zi_get_determinant ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return umfpack_zi_get_determinant ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_umfpack_umfpack_zi_get_determinant=yes
+else
+  ac_cv_lib_umfpack_umfpack_zi_get_determinant=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_umfpack_umfpack_zi_get_determinant" >&5
+$as_echo "$ac_cv_lib_umfpack_umfpack_zi_get_determinant" >&6; }
+if test "x$ac_cv_lib_umfpack_umfpack_zi_get_determinant" = x""yes; then :
+
+            UMFPACK_LIBS="-lumfpack -lcblas"; with_umfpack=yes
+fi
+
+fi
+
+fi
+
+
+    if test "$with_umfpack" = yes; then
+
+$as_echo "#define HAVE_UMFPACK 1" >>confdefs.h
+
+      OLD_LIBS=$LIBS
+      LIBS="$LIBS $UMFPACK_LIBS $AMD_LIBS $BLAS_LIBS $FLIBS"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for UMFPACK seperate complex matrix and rhs split" >&5
+$as_echo_n "checking for UMFPACK seperate complex matrix and rhs split... " >&6; }
+if test "${octave_cv_umfpack_seperate_split+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  octave_cv_umfpack_seperate_split=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#if defined (HAVE_UFSPARSE_UMFPACK_h)
+#include <ufsparse/umfpack.h>
+#elif defined (HAVE_UMFPACK_UMFPACK_H)
+#include <umfpack/umfpack.h>
+#elif defined (HAVE_UMFPACK_H)
+#include <umfpack.h>
+#endif
+int n = 5;
+int Ap[] = {0, 2, 5, 9, 10, 12};
+int Ai[]  = {0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4};
+double Ax[] = {2., 0., 3., 0., 3., 0., -1., 0., 4., 0., 4., 0.,
+	      -3., 0., 1., 0., 2., 0., 2., 0., 6., 0., 1., 0.};
+double br[] = {8., 45., -3., 3., 19.};
+double bi[] = {0., 0., 0., 0., 0.};
+int main (void)
+{
+  double *null = (double *) NULL ;
+  double *x = (double *)malloc (2 * n * sizeof(double));
+  int i ;
+  void *Symbolic, *Numeric ;
+  (void) umfpack_zi_symbolic (n, n, Ap, Ai, Ax, null, &Symbolic, null, null) ;
+  (void) umfpack_zi_numeric (Ap, Ai, Ax, null, Symbolic, &Numeric, null, null) ;
+  umfpack_zi_free_symbolic (&Symbolic) ;
+  (void) umfpack_zi_solve (0, Ap, Ai, Ax, null, x, null, br, bi,
+		Numeric, null, null) ;
+  umfpack_zi_free_numeric (&Numeric) ;
+  for (i = 0; i < n; i++, x+=2)
+    if (fabs(*x - i - 1.) > 1.e-13)
+      return (1);
+  return (0) ;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  octave_cv_umfpack_seperate_split=yes
+else
+  octave_cv_umfpack_seperate_split=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+if test "$cross_compiling" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_umfpack_seperate_split assumed for cross compilation" >&5
+$as_echo "$octave_cv_umfpack_seperate_split assumed for cross compilation" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_umfpack_seperate_split" >&5
+$as_echo "$octave_cv_umfpack_seperate_split" >&6; }
+fi
+if test "$octave_cv_umfpack_seperate_split" = yes; then
+
+$as_echo "#define UMFPACK_SEPARATE_SPLIT 1" >>confdefs.h
+
+fi
+
+      LIBS=$OLD_LIBS
+      TEXINFO_UMFPACK="@set HAVE_UMFPACK"
+      warn_umfpack=
+    fi
+    break
+fi
+
+done
+
+fi
+if test -n "$warn_umfpack"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_umfpack" >&5
+$as_echo "$as_me: WARNING: $warn_umfpack" >&2;}
+fi
+
+
+
+COLAMD_LIBS=
+
+
+
+# Check whether --with-colamd was given.
+if test "${with_colamd+set}" = set; then :
+  withval=$with_colamd; with_colamd=$withval
+else
+  with_colamd=yes
+fi
+
+
+warn_colamd="COLAMD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_colamd" = yes; then
+  with_colamd=no
+  for ac_header in suitesparse/colamd.h ufsparse/colamd.h colamd/colamd.h colamd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for colamd in -lcolamd" >&5
+$as_echo_n "checking for colamd in -lcolamd... " >&6; }
+if test "${ac_cv_lib_colamd_colamd+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcolamd  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char colamd ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return colamd ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_colamd_colamd=yes
+else
+  ac_cv_lib_colamd_colamd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_colamd_colamd" >&5
+$as_echo "$ac_cv_lib_colamd_colamd" >&6; }
+if test "x$ac_cv_lib_colamd_colamd" = x""yes; then :
+  COLAMD_LIBS="-lcolamd"; with_colamd=yes
+fi
+
+    if test "$with_colamd" = yes; then
+
+$as_echo "#define HAVE_COLAMD 1" >>confdefs.h
+
+      TEXINFO_COLAMD="@set HAVE_COLAMD"
+      warn_colamd=
+    fi
+    break
+fi
+
+done
+
+fi
+if test -n "$warn_colamd"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_colamd" >&5
+$as_echo "$as_me: WARNING: $warn_colamd" >&2;}
+fi
+
+
+
+CCOLAMD_LIBS=
+
+
+
+# Check whether --with-ccolamd was given.
+if test "${with_ccolamd+set}" = set; then :
+  withval=$with_ccolamd; with_ccolamd=$withval
+else
+  with_ccolamd=yes
+fi
+
+
+warn_ccolamd="CCOLAMD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_ccolamd" = yes; then
+  with_ccolamd=no
+  for ac_header in suitesparse/ccolamd.h ufsparse/ccolamd.h ccolamd/ccolamd.h ccolamd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ccolamd in -lccolamd" >&5
+$as_echo_n "checking for ccolamd in -lccolamd... " >&6; }
+if test "${ac_cv_lib_ccolamd_ccolamd+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lccolamd  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ccolamd ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return ccolamd ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ccolamd_ccolamd=yes
+else
+  ac_cv_lib_ccolamd_ccolamd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ccolamd_ccolamd" >&5
+$as_echo "$ac_cv_lib_ccolamd_ccolamd" >&6; }
+if test "x$ac_cv_lib_ccolamd_ccolamd" = x""yes; then :
+  CCOLAMD_LIBS="-lccolamd"; with_ccolamd=yes
+fi
+
+    if test "$with_ccolamd" = yes; then
+
+$as_echo "#define HAVE_CCOLAMD 1" >>confdefs.h
+
+      warn_ccolamd=
+    fi
+    break
+fi
+
+done
+
+fi
+if test -n "$warn_ccolamd"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_ccolamd" >&5
+$as_echo "$as_me: WARNING: $warn_ccolamd" >&2;}
+fi
+
+CHOLMOD_LIBS=
+
+
+
+# Check whether --with-cholmod was given.
+if test "${with_cholmod+set}" = set; then :
+  withval=$with_cholmod; with_cholmod=$withval
+else
+  with_cholmod=yes
+fi
+
+
+warn_cholmod="CHOLMOD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_cholmod" = yes && test "$with_colamd" = yes &&
+	test "$with_ccolamd" = yes && test "$with_amd" = yes; then
+  with_cholmod=no
+  for ac_header in suitesparse/cholmod.h ufsparse/cholmod.h cholmod/cholmod.h cholmod.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cholmod_start in -lcholmod" >&5
+$as_echo_n "checking for cholmod_start in -lcholmod... " >&6; }
+if test "${ac_cv_lib_cholmod_cholmod_start+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcholmod $CAMD_LIBS $AMD_LIBS $COLAMD_LIBS $CCOLAMD_LIBS $BLAS_LIBS $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cholmod_start ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return cholmod_start ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_cholmod_cholmod_start=yes
+else
+  ac_cv_lib_cholmod_cholmod_start=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cholmod_cholmod_start" >&5
+$as_echo "$ac_cv_lib_cholmod_cholmod_start" >&6; }
+if test "x$ac_cv_lib_cholmod_cholmod_start" = x""yes; then :
+  CHOLMOD_LIBS="-lcholmod";
+      with_cholmod=yes
+else
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cholmod_start in -lcholmod" >&5
+$as_echo_n "checking for cholmod_start in -lcholmod... " >&6; }
+if test "${ac_cv_lib_cholmod_cholmod_start+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcholmod $CAMD_LIBS $AMD_LIBS $COLAMD_LIBS $CCOLAMD_LIBS $BLAS_LIBS $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cholmod_start ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return cholmod_start ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_cholmod_cholmod_start=yes
+else
+  ac_cv_lib_cholmod_cholmod_start=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cholmod_cholmod_start" >&5
+$as_echo "$ac_cv_lib_cholmod_cholmod_start" >&6; }
+if test "x$ac_cv_lib_cholmod_cholmod_start" = x""yes; then :
+  CHOLMOD_LIBS="-lcholmod -cblas";
+	with_cholmod=yes
+fi
+
+fi
+
+
+    if test "$with_cholmod" = yes; then
+
+$as_echo "#define HAVE_CHOLMOD 1" >>confdefs.h
+
+      TEXINFO_CHOLMOD="@set HAVE_CHOLMOD"
+      warn_cholmod=
+    fi
+    break
+fi
+
+done
+
+fi
+if test -n "$warn_cholmod"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_cholmod" >&5
+$as_echo "$as_me: WARNING: $warn_cholmod" >&2;}
+fi
+
+
+
+CXSPARSE_LIBS=
+
+
+
+# Check whether --with-cxsparse was given.
+if test "${with_cxsparse+set}" = set; then :
+  withval=$with_cxsparse; with_cxsparse=$withval
+else
+  with_cxsparse=yes
+fi
+
+
+warn_cxsparse="CXSparse not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_cxsparse" = yes; then
+  with_cxsparse=no
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  for ac_header in suitesparse/cs.h ufsparse/cs.h cxsparse/cs.h cs.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cs_di_sqr in -lcxsparse" >&5
+$as_echo_n "checking for cs_di_sqr in -lcxsparse... " >&6; }
+if test "${ac_cv_lib_cxsparse_cs_di_sqr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcxsparse  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cs_di_sqr ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return cs_di_sqr ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_cxsparse_cs_di_sqr=yes
+else
+  ac_cv_lib_cxsparse_cs_di_sqr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cxsparse_cs_di_sqr" >&5
+$as_echo "$ac_cv_lib_cxsparse_cs_di_sqr" >&6; }
+if test "x$ac_cv_lib_cxsparse_cs_di_sqr" = x""yes; then :
+  CXSPARSE_LIBS="-lcxsparse"; with_cxsparse=yes
+fi
+
+    if test "$with_cxsparse" = yes; then
+
+$as_echo "#define HAVE_CXSPARSE 1" >>confdefs.h
+
+      warn_cxsparse=
+    fi
+    break
+fi
+
+done
+
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+if test -n "$warn_cxsparse"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_cxsparse" >&5
+$as_echo "$as_me: WARNING: $warn_cxsparse" >&2;}
+fi
+
+ARPACK_LIBS=
+
+
+
+# Check whether --with-arpack was given.
+if test "${with_arpack+set}" = set; then :
+  withval=$with_arpack; with_arpack=$withval
+else
+  with_arpack=yes
+fi
+
+
+warn_arpack="arpack not found. This will result in a lack of the eigs function."
+if test "$with_arpack" = yes; then
+  with_arpack=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for F77_FUNC(dseupd,DSEUPD) in -larpack" >&5
+$as_echo_n "checking for F77_FUNC(dseupd,DSEUPD) in -larpack... " >&6; }
+if test "${ac_cv_lib_arpack_F77_FUNC_dseupd_DSEUPD_+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-larpack $LAPACK_LIBS $FLIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char F77_FUNC(dseupd,DSEUPD) ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return F77_FUNC(dseupd,DSEUPD) ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_arpack_F77_FUNC_dseupd_DSEUPD_=yes
+else
+  ac_cv_lib_arpack_F77_FUNC_dseupd_DSEUPD_=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_arpack_F77_FUNC_dseupd_DSEUPD_" >&5
+$as_echo "$ac_cv_lib_arpack_F77_FUNC_dseupd_DSEUPD_" >&6; }
+if test "x$ac_cv_lib_arpack_F77_FUNC_dseupd_DSEUPD_" = x""yes; then :
+  ARPACK_LIBS="-larpack"; with_arpack=yes
+fi
+
+  if test "$with_arpack" = yes; then
+
+$as_echo "#define HAVE_ARPACK 1" >>confdefs.h
+
+    warn_arpack=
+  fi
+fi
+if test -n "$warn_arpack"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_arpack" >&5
+$as_echo "$as_me: WARNING: $warn_arpack" >&2;}
+fi
+
+### Handle shared library options.
+
+### Enable creation of static libraries.
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; if test "$enableval" = no; then STATIC_LIBS=false;
+   else STATIC_LIBS=true; fi
+else
+  STATIC_LIBS=false
+fi
+
+
+
+### Enable creation of shared libraries.  Currently only works with
+### gcc on some systems.
+
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; if test "$enableval" = no; then SHARED_LIBS=false;
+   else SHARED_LIBS=true; fi
+else
+  SHARED_LIBS=true
+fi
+
+
+
+### Enable dynamic linking.  --enable-shared implies this, so
+### --enable-dl is only need if you are only building static libraries
+### and want to try dynamic linking too (works on some systems, for
+### example, OS X and Windows).
+
+# Check whether --enable-dl was given.
+if test "${enable_dl+set}" = set; then :
+  enableval=$enable_dl; if test "$enableval" = no; then ENABLE_DYNAMIC_LINKING=false;
+   else ENABLE_DYNAMIC_LINKING=true; fi
+else
+  ENABLE_DYNAMIC_LINKING=true
+fi
+
+
+if $STATIC_LIBS || $SHARED_LIBS; then
+  true
+else
+  as_fn_error "You can't disable building static AND shared libraries!" "$LINENO" 5
+fi
+
+# Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+  enableval=$enable_rpath;  if test "$enableval" = no; then use_rpath=false;
+    else
+      use_rpath=true
+      if test "$enableval" = yes; then true;
+      else enable_rpath_arg="$enableval"; fi
+    fi
+else
+  use_rpath=true
+fi
+
+
+CPICFLAG=-fPIC
+CXXPICFLAG=-fPIC
+FPICFLAG=-fPIC
+SHLEXT=so
+SHLLIB='$(SHLEXT)'
+SHLBIN=
+SHLEXT_VER='$(SHLEXT).$(version)'
+SHLLIB_VER='$(SHLLIB).$(version)'
+SHLBIN_VER='$(SHLBIN).$(version)'
+SHLLINKEXT=
+LIBPRE=lib
+SHLPRE=lib
+SHLLIBPRE=lib
+SHLBINPRE=lib
+SH_LD='$(CXX)'
+SH_LDFLAGS=-shared
+DL_LD='$(SH_LD)'
+DL_LDFLAGS='$(SH_LDFLAGS)'
+MKOCTFILE_DL_LDFLAGS='$(DL_LDFLAGS)'
+SONAME_FLAGS=
+RLD_FLAG=
+NO_OCT_FILE_STRIP=false
+TEMPLATE_AR='$(AR)'
+TEMPLATE_ARFLAGS="$ARFLAGS"
+CRUFT_DLL_DEFS=
+OCTAVE_DLL_DEFS=
+OCTINTERP_DLL_DEFS=
+OCTGRAPHICS_DLL_DEFS=
+library_path_var=LD_LIBRARY_PATH
+SCRIPTS_EXE_SUFFIX=
+case "$canonical_host_type" in
+  *-*-386bsd* | *-*-netbsd*)
+    SH_LD=ld
+    SH_LDFLAGS=-Bshareable
+  ;;
+  *-*-openbsd*)
+    SH_LDFLAGS='-shared -fPIC'
+  ;;
+  *-*-freebsd*)
+    SH_LDFLAGS="-shared -Wl,-x"
+    RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)'
+  ;;
+  alpha*-dec-osf*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    SH_LDFLAGS="-shared -Wl,-expect_unresolved -Wl,'*'"
+    RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)'
+  ;;
+  *-*-darwin*)
+    DL_LDFLAGS='-bundle -bundle_loader $(TOPDIR)/src/octave $(LDFLAGS)'
+    MKOCTFILE_DL_LDFLAGS='-bundle -bundle_loader $$BINDIR/octave-$$OCTAVE_VERSION$$EXEEXT'
+    SH_LDFLAGS='-dynamiclib -single_module $(LDFLAGS)'
+    case "$canonical_host_type" in
+      powerpc-*)
+        CXXPICFLAG=
+        CPICFLAG=
+        FPICFLAG=
+      ;;
+    esac
+    SHLEXT=dylib
+    SHLLIB='$(SHLEXT)'
+    SHLEXT_VER='$(version).$(SHLEXT)'
+    SHLLIB_VER='$(version).$(SHLLIB)'
+    NO_OCT_FILE_STRIP=true
+    SONAME_FLAGS='-install_name $(octlibdir)/$@'
+    library_path_var=DYLD_LIBRARY_PATH
+  ;;
+  *-*-cygwin*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    LIBPRE=lib
+    SHLPRE=cyg
+    SHLBINPRE=cyg
+    SHLEXT=dll
+    SHLLIB=dll.a
+    SHLBIN=dll
+    DL_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc"
+    SH_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-auto-image-base"
+    SONAME_FLAGS='-Wl,--out-implib=$(patsubst $(SHLPRE)%,$(LIBPRE)%,$@).a'
+  ;;
+  *-*-mingw*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    SHLEXT=dll
+    SHLLIB=dll.a
+    SHLBIN=dll
+    DL_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc"
+    SH_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-auto-image-base"
+    SONAME_FLAGS='-Wl,--out-implib=$@.a'
+    library_path_var=PATH
+    SCRIPTS_EXE_SUFFIX='$(EXEEXT)'
+  ;;
+
+  *-*-msdosmsvc)
+    DL_LDFLAGS="-shared"
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    SHLEXT=dll
+    SHLLIB=lib
+    SHLBIN=dll
+    LIBPRE=
+    SHLPRE=
+    SHLLIBPRE=
+    SHLBINPRE=
+    SH_LDFLAGS="-shared"
+      if test -n "`echo $CFLAGS | grep -e '-g'`" -o -n "`echo $CXXFLAGS | grep -e '-g'`"; then
+      DL_LDFLAGS="$DL_LDFLAGS -g"
+      SH_LDFLAGS="$SH_LDFLAGS -g"
+    fi
+    NO_OCT_FILE_STRIP=true
+    library_path_var=PATH
+    NO_OCT_FILE_STRIP=true
+    ## Extra compilation flags.
+    CRUFT_DLL_DEFS="-DCRUFT_DLL"
+    OCTAVE_DLL_DEFS="-DOCTAVE_DLL"
+    OCTINTERP_DLL_DEFS="-DOCTINTERP_DLL"
+    OCTGRAPHICS_DLL_DEFS="-DOCTGRAPHICS_DLL"
+    SCRIPTS_EXE_SUFFIX='$(EXEEXT)'
+  ;;
+  *-*-linux* | *-*-gnu*)
+    MKOCTFILE_DL_LDFLAGS="-shared -Wl,-Bsymbolic"
+    SONAME_FLAGS='-Wl,-soname -Wl,$@'
+    RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)'
+  ;;
+  i[3456]86-*-sco3.2v5*)
+    SONAME_FLAGS='-Wl,-h -Wl,$@'
+    RLD_FLAG=
+    SH_LDFLAGS=-G
+  ;;
+  rs6000-ibm-aix* | powerpc-ibm-aix*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    library_path_var=LIBPATH
+  ;;
+  hppa*-hp-hpux*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=+Z
+    fi
+    SHLEXT=sl
+    SH_LDFLAGS="-shared -fPIC"
+    RLD_FLAG='-Wl,+b -Wl,$(octlibdir)'
+    library_path_var=SHLIB_PATH
+  ;;
+  ia64*-hp-hpux*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=+Z
+    fi
+    SH_LDFLAGS="-shared -fPIC"
+    RLD_FLAG='-Wl,+b -Wl,$(octlibdir)'
+  ;;
+  *-sgi-*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    RLD_FLAG='-rpath $(octlibdir)'
+  ;;
+  sparc-sun-sunos4*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=-PIC
+    fi
+    SH_LD=ld
+    SH_LDFLAGS="-assert nodefinitions"
+    RLD_FLAG='-L$(octlibdir)'
+  ;;
+  sparc-sun-solaris2* | i386-pc-solaris2*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=-KPIC
+    fi
+    if test "$GCC" = yes; then
+      CPICFLAG=-fPIC
+    else
+      CPICFLAG=-KPIC
+    fi
+    if test "$GXX" = yes; then
+      CXXPICFLAG=-fPIC
+      SH_LDFLAGS=-shared
+    else
+      CXXPICFLAG=-KPIC
+      SH_LDFLAGS=-G
+    fi
+    RLD_FLAG='-R $(octlibdir)'
+    ## Template closures in archive libraries need a different mechanism.
+    if test "$GXX" = yes; then
+      true
+    else
+      TEMPLATE_AR='$(CXX)'
+      TEMPLATE_ARFLAGS="-xar -o"
+    fi
+  ;;
+esac
+
+if $use_rpath; then
+  if test -n "$enable_rpath_arg"; then
+    RLD_FLAG="$enable_rpath_arg"
+  fi
+else
+  RLD_FLAG=""
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining FPICFLAG to be $FPICFLAG" >&5
+$as_echo "$as_me: defining FPICFLAG to be $FPICFLAG" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining CPICFLAG to be $CPICFLAG" >&5
+$as_echo "$as_me: defining CPICFLAG to be $CPICFLAG" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining CXXPICFLAG to be $CXXPICFLAG" >&5
+$as_echo "$as_me: defining CXXPICFLAG to be $CXXPICFLAG" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLEXT to be $SHLEXT" >&5
+$as_echo "$as_me: defining SHLEXT to be $SHLEXT" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLLIB to be $SHLLIB" >&5
+$as_echo "$as_me: defining SHLLIB to be $SHLLIB" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLBIN to be $SHLBIN" >&5
+$as_echo "$as_me: defining SHLBIN to be $SHLBIN" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLEXT_VER to be $SHLEXT_VER" >&5
+$as_echo "$as_me: defining SHLEXT_VER to be $SHLEXT_VER" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLLIB_VER to be $SHLLIB_VER" >&5
+$as_echo "$as_me: defining SHLLIB_VER to be $SHLLIB_VER" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLBIN_VER to be $SHLBIN_VER" >&5
+$as_echo "$as_me: defining SHLBIN_VER to be $SHLBIN_VER" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLLINKEXT to be $SHLLINKEXT" >&5
+$as_echo "$as_me: defining SHLLINKEXT to be $SHLLINKEXT" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining LIBPRE to be $LIBPRE" >&5
+$as_echo "$as_me: defining LIBPRE to be $LIBPRE" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLPRE to be $SHLPRE" >&5
+$as_echo "$as_me: defining SHLPRE to be $SHLPRE" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLLIBPRE to be $SHLLIBPRE" >&5
+$as_echo "$as_me: defining SHLLIBPRE to be $SHLLIBPRE" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SHLBINPRE to be $SHLBINPRE" >&5
+$as_echo "$as_me: defining SHLBINPRE to be $SHLBINPRE" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SH_LD to be $SH_LD" >&5
+$as_echo "$as_me: defining SH_LD to be $SH_LD" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SH_LDFLAGS to be $SH_LDFLAGS" >&5
+$as_echo "$as_me: defining SH_LDFLAGS to be $SH_LDFLAGS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining DL_LD to be $DL_LD" >&5
+$as_echo "$as_me: defining DL_LD to be $DL_LD" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining DL_LDFLAGS to be $DL_LDFLAGS" >&5
+$as_echo "$as_me: defining DL_LDFLAGS to be $DL_LDFLAGS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining MKOCTFILE_DL_LDFLAGS to be $MKOCTFILE_DL_LDFLAGS" >&5
+$as_echo "$as_me: defining MKOCTFILE_DL_LDFLAGS to be $MKOCTFILE_DL_LDFLAGS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining SONAME_FLAGS to be $SONAME_FLAGS" >&5
+$as_echo "$as_me: defining SONAME_FLAGS to be $SONAME_FLAGS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining NO_OCT_FILE_STRIP to be $NO_OCT_FILE_STRIP" >&5
+$as_echo "$as_me: defining NO_OCT_FILE_STRIP to be $NO_OCT_FILE_STRIP" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining RLD_FLAG to be $RLD_FLAG" >&5
+$as_echo "$as_me: defining RLD_FLAG to be $RLD_FLAG" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining TEMPLATE_AR to be $TEMPLATE_AR" >&5
+$as_echo "$as_me: defining TEMPLATE_AR to be $TEMPLATE_AR" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining TEMPLATE_ARFLAGS to be $TEMPLATE_ARFLAGS" >&5
+$as_echo "$as_me: defining TEMPLATE_ARFLAGS to be $TEMPLATE_ARFLAGS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining CRUFT_DLL_DEFS to be $CRUFT_DLL_DEFS" >&5
+$as_echo "$as_me: defining CRUFT_DLL_DEFS to be $CRUFT_DLL_DEFS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining OCTAVE_DLL_DEFS to be $OCTAVE_DLL_DEFS" >&5
+$as_echo "$as_me: defining OCTAVE_DLL_DEFS to be $OCTAVE_DLL_DEFS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining OCTINTERP_DLL_DEFS to be $OCTINTERP_DLL_DEFS" >&5
+$as_echo "$as_me: defining OCTINTERP_DLL_DEFS to be $OCTINTERP_DLL_DEFS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining OCTGRAPHICS_DLL_DEFS to be $OCTGRAPHICS_DLL_DEFS" >&5
+$as_echo "$as_me: defining OCTGRAPHICS_DLL_DEFS to be $OCTGRAPHICS_DLL_DEFS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining library_path_var to be $library_path_var" >&5
+$as_echo "$as_me: defining library_path_var to be $library_path_var" >&6;}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### special checks for odd OS specific things.
+###
+### I am told that on some SCO systems, the only place to find some
+### functions like gethostname and gettimeofday is in libsocket.
+
+for ac_func in gethostname
+do :
+  ac_fn_c_check_func "$LINENO" "gethostname" "ac_cv_func_gethostname"
+if test "x$ac_cv_func_gethostname" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETHOSTNAME 1
+_ACEOF
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostname in -lsocket" >&5
+$as_echo_n "checking for gethostname in -lsocket... " >&6; }
+if test "${ac_cv_lib_socket_gethostname+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostname ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return gethostname ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_gethostname=yes
+else
+  ac_cv_lib_socket_gethostname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_gethostname" >&5
+$as_echo "$ac_cv_lib_socket_gethostname" >&6; }
+if test "x$ac_cv_lib_socket_gethostname" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
+_ACEOF
+
+  LIBS="-lsocket $LIBS"
+
+fi
+
+fi
+done
+
+for ac_func in getpwnam
+do :
+  ac_fn_c_check_func "$LINENO" "getpwnam" "ac_cv_func_getpwnam"
+if test "x$ac_cv_func_getpwnam" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPWNAM 1
+_ACEOF
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam in -lsun" >&5
+$as_echo_n "checking for getpwnam in -lsun... " >&6; }
+if test "${ac_cv_lib_sun_getpwnam+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsun  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpwnam ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return getpwnam ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_sun_getpwnam=yes
+else
+  ac_cv_lib_sun_getpwnam=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sun_getpwnam" >&5
+$as_echo "$ac_cv_lib_sun_getpwnam" >&6; }
+if test "x$ac_cv_lib_sun_getpwnam" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSUN 1
+_ACEOF
+
+  LIBS="-lsun $LIBS"
+
+fi
+
+fi
+done
+
+
+case "$canonical_host_type" in
+  *-*-cygwin*)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostname in -lwsock32" >&5
+$as_echo_n "checking for gethostname in -lwsock32... " >&6; }
+if test "${ac_cv_lib_wsock32_gethostname+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwsock32  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostname ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return gethostname ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_wsock32_gethostname=yes
+else
+  ac_cv_lib_wsock32_gethostname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wsock32_gethostname" >&5
+$as_echo "$ac_cv_lib_wsock32_gethostname" >&6; }
+if test "x$ac_cv_lib_wsock32_gethostname" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBWSOCK32 1
+_ACEOF
+
+  LIBS="-lwsock32 $LIBS"
+
+fi
+
+   LIBS="$LIBS -lwsock32"
+  ;;
+  *-*-msdosmsvc* | *-*-mingw*)
+  LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32"
+  ;;
+esac
+
+### Type stuff.
+
+ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
+if test "x$ac_cv_type_mode_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
+if test "x$ac_cv_type_off_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if test "${ac_cv_type_uid_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uid_t" >/dev/null 2>&1; then :
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" >>confdefs.h
+
+
+$as_echo "#define gid_t int" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "dev_t" "ac_cv_type_dev_t" "$ac_includes_default"
+if test "x$ac_cv_type_dev_t" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DEV_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "ino_t" "ac_cv_type_ino_t" "$ac_includes_default"
+if test "x$ac_cv_type_ino_t" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INO_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "nlink_t" "ac_cv_type_nlink_t" "$ac_includes_default"
+if test "x$ac_cv_type_nlink_t" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NLINK_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "nlink_t" "ac_cv_type_nlink_t" "$ac_includes_default"
+if test "x$ac_cv_type_nlink_t" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NLINK_T 1
+_ACEOF
+
+
+fi
+
+ac_fn_c_check_type "$LINENO" "long long int" "ac_cv_type_long_long_int" "$ac_includes_default"
+if test "x$ac_cv_type_long_long_int" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_LONG_INT 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "unsigned long long int" "ac_cv_type_unsigned_long_long_int" "$ac_includes_default"
+if test "x$ac_cv_type_unsigned_long_long_int" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UNSIGNED_LONG_LONG_INT 1
+_ACEOF
+
+
+fi
+
+ac_fn_c_check_type "$LINENO" "sigset_t" "ac_cv_type_sigset_t" "
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#include <signal.h>
+"
+if test "x$ac_cv_type_sigset_t" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGSET_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "sig_atomic_t" "ac_cv_type_sig_atomic_t" "
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#include <signal.h>
+"
+if test "x$ac_cv_type_sig_atomic_t" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIG_ATOMIC_T 1
+_ACEOF
+
+
+fi
+
+
+### How big are ints and how are they oriented?  These could probably
+### be eliminated in favor of run-time checks.
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if test "${ac_cv_sizeof_short+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_short" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (short)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_short=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if test "${ac_cv_sizeof_int+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+
+### Does the C compiler handle alloca() and const correctly?
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if test "${ac_cv_working_alloca_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <alloca.h>
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+			  if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_working_alloca_h=yes
+else
+  ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if test "${ac_cv_func_alloca_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+char *p = (char *) alloca (1);
+				    if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_func_alloca_works=yes
+else
+  ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if test "${ac_cv_os_cray+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then :
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if test "${ac_cv_c_stack_direction+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_c_stack_direction=0
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  return find_stack_direction () < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_stack_direction=1
+else
+  ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if test "${ac_cv_c_const+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset cs;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+
+### See if we should use placement delete.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether <new> defines placement delete operator" >&5
+$as_echo_n "checking whether <new> defines placement delete operator... " >&6; }
+if test "${octave_cv_placement_delete+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <new>
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+operator delete((void *)0, (void *)0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  octave_cv_placement_delete=yes
+else
+  octave_cv_placement_delete=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_placement_delete" >&5
+$as_echo "$octave_cv_placement_delete" >&6; }
+if test $octave_cv_placement_delete = yes; then
+
+$as_echo "#define HAVE_PLACEMENT_DELETE 1" >>confdefs.h
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+### See if we can auto allocate variable sized arrays.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ supports dynamic auto arrays" >&5
+$as_echo_n "checking whether C++ supports dynamic auto arrays... " >&6; }
+if test "${octave_cv_dynamic_auto_arrays+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+void test(char *); int length(); char x[length()]; test(x);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  octave_cv_dynamic_auto_arrays=yes
+else
+  octave_cv_dynamic_auto_arrays=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_dynamic_auto_arrays" >&5
+$as_echo "$octave_cv_dynamic_auto_arrays" >&6; }
+if test $octave_cv_dynamic_auto_arrays = yes; then
+
+$as_echo "#define HAVE_DYNAMIC_AUTO_ARRAYS 1" >>confdefs.h
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+### See if we can use fast integer arithmetics
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fast integer arithmetics is usable" >&5
+$as_echo_n "checking whether fast integer arithmetics is usable... " >&6; }
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <limits>
+template<class UT, class ST>
+static bool
+do_test (UT, ST)
+{
+  volatile ST s = std::numeric_limits<ST>::min () / 3;
+  volatile UT u = static_cast<UT> (s);
+  if (*(reinterpret_cast<volatile ST *> (&u)) != s) return true;
+
+  u = 0; u = ~u;
+  if (*(reinterpret_cast<volatile ST *> (&u)) != -1) return true;
+
+  ST sx, sy;
+  sx = std::numeric_limits<ST>::max () / 2 + 1;
+  sy = std::numeric_limits<ST>::max () / 2 + 2;
+  if (static_cast<ST> (static_cast<UT> (sx) + static_cast<UT> (sy))
+      != std::numeric_limits<ST>::min () + 1) return true;
+  if (static_cast<ST> (static_cast<UT> (sx) - static_cast<UT> (sy))
+      != -1) return true;
+
+  if ((sx & sy) != (static_cast<UT> (sx) & static_cast<UT> (sy)))
+    return true;
+  if ((sx | sy) != (static_cast<UT> (sx) | static_cast<UT> (sy)))
+    return true;
+  if ((sx ^ sy) != (static_cast<UT> (sx) ^ static_cast<UT> (sy)))
+    return true;
+  if ((-1 >> 1) != -1) return true;
+  return false;
+}
+
+#define DO_TEST(T) \
+if (do_test (static_cast<unsigned T> (0), static_cast<signed T> (0))) \
+  return sizeof (T);
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  DO_TEST(char)
+  DO_TEST(short)
+  DO_TEST(int)
+  DO_TEST(long)
+#if (defined(HAVE_LONG_LONG_INT) && defined(HAVE_UNSIGNED_LONG_LONG_INT))
+  DO_TEST(long long)
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FAST_INT_OPS 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+### Check for long double type (for 64-bit integers)
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5
+$as_echo_n "checking size of long double... " >&6; }
+if test "${ac_cv_sizeof_long_double+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_double" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long double)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long_double=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5
+$as_echo "$ac_cv_sizeof_long_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+_ACEOF
+
+
+
+### Checks for header files.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_ac_Header=yes"
+else
+  eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if test "${ac_cv_header_time+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_sys_wait_h=yes
+else
+  ac_cv_header_sys_wait_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+
+### C headers
+
+for ac_header in assert.h curses.h direct.h dlfcn.h fcntl.h float.h \
+  floatingpoint.h grp.h ieeefp.h inttypes.h limits.h locale.h memory.h nan.h \
+  ncurses.h poll.h pthread.h pwd.h stdint.h stdlib.h string.h sunmath.h sys/ioctl.h \
+  sys/param.h sys/poll.h sys/resource.h sys/select.h sys/stat.h \
+  sys/time.h sys/times.h sys/types.h sys/utsname.h sys/utime.h termcap.h \
+  unistd.h utime.h varargs.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+### C++ headers
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+for ac_header in sstream
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "sstream" "ac_cv_header_sstream" "$ac_includes_default"
+if test "x$ac_cv_header_sstream" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SSTREAM 1
+_ACEOF
+
+fi
+
+done
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+have_termios_h=no
+for ac_header in termios.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_termios_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TERMIOS_H 1
+_ACEOF
+ have_termios_h=yes
+fi
+
+done
+
+for ac_header in termio.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "termio.h" "ac_cv_header_termio_h" "$ac_includes_default"
+if test "x$ac_cv_header_termio_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TERMIO_H 1
+_ACEOF
+ have_termio_h=yes
+else
+  have_termio_h=no
+fi
+
+done
+
+for ac_header in sgtty.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sgtty.h" "ac_cv_header_sgtty_h" "$ac_includes_default"
+if test "x$ac_cv_header_sgtty_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SGTTY_H 1
+_ACEOF
+ have_sgtty_h=yes
+else
+  have_sgtty_h=no
+fi
+
+done
+
+for ac_header in glob.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "glob.h" "ac_cv_header_glob_h" "$ac_includes_default"
+if test "x$ac_cv_header_glob_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GLOB_H 1
+_ACEOF
+ have_glob_h=yes
+else
+  have_glob_h=no
+fi
+
+done
+
+for ac_header in fnmatch.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fnmatch.h" "ac_cv_header_fnmatch_h" "$ac_includes_default"
+if test "x$ac_cv_header_fnmatch_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FNMATCH_H 1
+_ACEOF
+ have_fnmatch_h=yes
+else
+  have_fnmatch_h=no
+fi
+
+done
+
+for ac_header in conio.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "conio.h" "ac_cv_header_conio_h" "$ac_includes_default"
+if test "x$ac_cv_header_conio_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CONIO_H 1
+_ACEOF
+ have_conio_h=yes
+else
+  have_conio_h=no
+fi
+
+done
+
+
+### I'm told that termios.h is broken on NeXT systems.
+
+case "$canonical_host_type" in
+  *-*-nextstep*)
+    if test "$have_termios_h" = yes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring termios.h on NeXT systems." >&5
+$as_echo "$as_me: WARNING: Ignoring termios.h on NeXT systems." >&2;}
+      have_termios_h=no
+    fi
+  ;;
+esac
+
+if test "$have_termios_h" = yes \
+    || test "$have_termio_h" = yes \
+    || test "$have_sgtty_h" = yes; then
+  true
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I couldn't find termios.h, termio.h, or sgtty.h!" >&5
+$as_echo "$as_me: WARNING: I couldn't find termios.h, termio.h, or sgtty.h!" >&2;}
+fi
+
+LIBGLOB=
+
+if test "$have_fnmatch_h" = yes && test "$have_glob_h" = yes; then
+  for ac_func in fnmatch
+do :
+  ac_fn_c_check_func "$LINENO" "fnmatch" "ac_cv_func_fnmatch"
+if test "x$ac_cv_func_fnmatch" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FNMATCH 1
+_ACEOF
+ have_fnmatch=yes
+else
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fnmatch in -lglob" >&5
+$as_echo_n "checking for fnmatch in -lglob... " >&6; }
+if test "${ac_cv_lib_glob_fnmatch+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lglob  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fnmatch ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return fnmatch ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_glob_fnmatch=yes
+else
+  ac_cv_lib_glob_fnmatch=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glob_fnmatch" >&5
+$as_echo "$ac_cv_lib_glob_fnmatch" >&6; }
+if test "x$ac_cv_lib_glob_fnmatch" = x""yes; then :
+  have_fnmatch=yes; LIBGLOB=-lglob
+else
+  have_fnmatch=no
+fi
+
+fi
+done
+
+  for ac_func in glob
+do :
+  ac_fn_c_check_func "$LINENO" "glob" "ac_cv_func_glob"
+if test "x$ac_cv_func_glob" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GLOB 1
+_ACEOF
+ have_glob=yes
+else
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glob in -lglob" >&5
+$as_echo_n "checking for glob in -lglob... " >&6; }
+if test "${ac_cv_lib_glob_glob+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lglob  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char glob ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return glob ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_glob_glob=yes
+else
+  ac_cv_lib_glob_glob=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glob_glob" >&5
+$as_echo "$ac_cv_lib_glob_glob" >&6; }
+if test "x$ac_cv_lib_glob_glob" = x""yes; then :
+  have_glob=yes; LIBGLOB=-lglob
+else
+  have_glob=no
+fi
+
+fi
+done
+
+
+  if test "$have_fnmatch" != yes || test "$have_glob" != yes; then
+    as_fn_error "You are required to have fnmatch and glob" "$LINENO" 5
+  fi
+else
+  as_fn_error "You are required to have fnmatch.h and glob.h" "$LINENO" 5
+fi
+
+### Checks for functions and variables.
+
+for ac_func in atexit basename bcopy bzero canonicalize_file_name \
+  chmod dup2 endgrent endpwent execvp expm1 expm1f fcntl fork fstat getcwd \
+  getegid geteuid getgid getgrent getgrgid getgrnam getpgrp getpid \
+  getppid getpwent getpwuid gettimeofday getuid getwd _kbhit kill \
+  lgamma lgammaf lgamma_r lgammaf_r link localtime_r log1p log1pf lstat \
+  memmove mkdir mkfifo mkstemp on_exit pipe poll putenv raise readlink \
+  realpath rename resolvepath rindex rmdir roundl select setgrent setlocale \
+  setpwent setvbuf sigaction siglongjmp sigpending sigprocmask sigsuspend \
+  snprintf stat strcasecmp strdup strerror stricmp strncasecmp \
+  strnicmp strptime strsignal symlink tempnam tgammaf trunc umask \
+  uname unlink usleep utime vfprintf vsprintf vsnprintf waitpid \
+  _chmod _snprintf x_utime _utime32
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ac_fn_cxx_check_decl "$LINENO" "exp2" "ac_cv_have_decl_exp2" "#include <cmath>
+"
+if test "x$ac_cv_have_decl_exp2" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_EXP2 $ac_have_decl
+_ACEOF
+ac_fn_cxx_check_decl "$LINENO" "round" "ac_cv_have_decl_round" "#include <cmath>
+"
+if test "x$ac_cv_have_decl_round" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ROUND $ac_have_decl
+_ACEOF
+ac_fn_cxx_check_decl "$LINENO" "tgamma" "ac_cv_have_decl_tgamma" "#include <cmath>
+"
+if test "x$ac_cv_have_decl_tgamma" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_TGAMMA $ac_have_decl
+_ACEOF
+
+for ac_func in exp2 round tgamma
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+case "$canonical_host_type" in
+  *-*-mingw*)
+    ## MinGW does not provide a mkstemp function.  However, it provides
+    ## the mkstemps function in libiberty.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mkstemps in libiberty" >&5
+$as_echo_n "checking for mkstemps in libiberty... " >&6; }
+    save_LIBS="$LIBS"
+    LIBS="-liberty $LIBS"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      int mkstemps (char *pattern, int suffix_len);
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+mkstemps ("XXXXXX", 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+     HAVE_MKSTEMPS=yes
+
+$as_echo "#define HAVE_MKSTEMPS 1" >>confdefs.h
+
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+     HAVE_MKSTEMPS=no
+     LIBS="$save_LIBS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+   ;;
+esac
+
+case "$canonical_host_type" in
+  *-*-msdosmsvc | *-*-mingw*)
+    ## The %T and %e format specifiers for strftime are not implemented
+    ## so use our version.  We could use an actual configure test
+    ## for this.
+  ;;
+  *)
+    for ac_func in strftime
+do :
+  ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
+if test "x$ac_cv_func_strftime" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+fi
+done
+
+  ;;
+esac
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for c99 vsnprintf" >&5
+$as_echo_n "checking for c99 vsnprintf... " >&6; }
+if test "${oct_cv_c99_vsnprintf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  oct_cv_c99_vsnprintf="guessing no"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+int
+doit(char * s, ...)
+{
+  char buffer[32];
+  va_list args;
+  int r;
+
+  va_start(args, s);
+  r = vsnprintf(buffer, 5, s, args);
+  va_end(args);
+
+  if (r != 7)
+    exit(1);
+
+  exit(0);
+}
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+doit("1234567");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  oct_cv_c99_vsnprintf=yes
+else
+  oct_cv_c99_vsnprintf=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $oct_cv_c99_vsnprintf" >&5
+$as_echo "$oct_cv_c99_vsnprintf" >&6; }
+
+case $oct_cv_c99_vsnprintf in
+yes)
+
+$as_echo "#define HAVE_C99_VSNPRINTF 1" >>confdefs.h
+
+  ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strptime is broken" >&5
+$as_echo_n "checking whether strptime is broken... " >&6; }
+if test "${octave_cv_strptime_broken+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define _XOPEN_SOURCE
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#if defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#endif
+#include <stdio.h>
+#include <time.h>
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+struct tm t;
+char *q = strptime ("09/13", "%m/%d/%y", &t);
+return q ? 1 : 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  octave_cv_strptime_broken=no
+else
+  octave_cv_strptime_broken=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_strptime_broken" >&5
+$as_echo "$octave_cv_strptime_broken" >&6; }
+if test $octave_cv_strptime_broken = yes; then
+
+$as_echo "#define OCTAVE_HAVE_BROKEN_STRPTIME 1" >>confdefs.h
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether putenv uses malloc" >&5
+$as_echo_n "checking whether putenv uses malloc... " >&6; }
+if test "${octave_cv_func_putenv_malloc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  octave_cv_func_putenv_malloc=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define VAR	"YOW_VAR"
+#define STRING1 "GabbaGabbaHey"
+#define STRING2 "Yow!!"		/* should be shorter than STRING1 */
+extern char *getenv (); /* in case char* and int don't mix gracefully */
+main ()
+{
+  char *str1, *rstr1, *str2, *rstr2;
+  str1 = getenv (VAR);
+  if (str1)
+    exit (1);
+  str1 = malloc (strlen (VAR) + 1 + strlen (STRING1) + 1);
+  if (str1 == 0)
+    exit (2);
+  strcpy (str1, VAR);
+  strcat (str1, "=");
+  strcat (str1, STRING1);
+  if (putenv (str1) < 0)
+    exit (3);
+  rstr1 = getenv (VAR);
+  if (rstr1 == 0)
+    exit (4);
+  rstr1 -= strlen (VAR) + 1;
+  if (strncmp (rstr1, VAR, strlen (VAR)))
+    exit (5);
+  str2 = malloc (strlen (VAR) + 1 + strlen (STRING2) + 1);
+  if (str2 == 0 || str1 == str2)
+    exit (6);
+  strcpy (str2, VAR);
+  strcat (str2, "=");
+  strcat (str2, STRING2);
+  if (putenv (str2) < 0)
+    exit (7);
+  rstr2 = getenv (VAR);
+  if (rstr2 == 0)
+    exit (8);
+  rstr2 -= strlen (VAR) + 1;
+#if 0
+  printf ("rstr1=0x%x, rstr2=0x%x\n", rstr1, rstr2);
+  /*
+   * If string from first call was reused for the second call,
+   * you had better not do a free on the first string!
+   */
+  if (rstr1 == rstr2)
+          printf ("#define SMART_PUTENV\n");
+  else
+          printf ("#undef SMART_PUTENV\n");
+#endif
+  exit (rstr1 == rstr2 ? 0 : 1);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  octave_cv_func_putenv_malloc=yes
+else
+  octave_cv_func_putenv_malloc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_func_putenv_malloc" >&5
+$as_echo "$octave_cv_func_putenv_malloc" >&6; }
+if test $octave_cv_func_putenv_malloc = yes; then
+
+$as_echo "#define SMART_PUTENV 1" >>confdefs.h
+
+fi
+
+case "$canonical_host_type" in
+  *-*-msdosmsvc | *-*-mingw*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required _WIN32_WINNT" >&5
+$as_echo_n "checking for required _WIN32_WINNT... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <windows.h>
+#if _WIN32_WINNT < 0x0403
+#error "Wrong version"
+#endif
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+else
+
+
+$as_echo "#define _WIN32_WINNT 0x0403" >>confdefs.h
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 0x0403" >&5
+$as_echo "0x0403" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _USE_MATH_DEFINES needs to be defined" >&5
+$as_echo_n "checking whether _USE_MATH_DEFINES needs to be defined... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <math.h>
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+int x = M_LN2;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+
+
+$as_echo "#define _USE_MATH_DEFINES 1" >>confdefs.h
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ;;
+esac
+
+### Dynamic linking is now enabled only if we are building shared
+### libs and some API for dynamic linking is detected.
+
+LD_CXX='$(CXX)'
+RDYNAMIC_FLAG=
+DL_API_MSG=""
+dlopen_api=false
+shl_load_api=false
+loadlibrary_api=false
+dyld_api=false
+
+if $SHARED_LIBS || $ENABLE_DYNAMIC_LINKING; then
+
+  ## Check for dyld first since OS X can have a non-standard libdl
+
+  ac_fn_c_check_header_mongrel "$LINENO" "mach-o/dyld.h" "ac_cv_header_mach_o_dyld_h" "$ac_includes_default"
+if test "x$ac_cv_header_mach_o_dyld_h" = x""yes; then :
+
+fi
+
+
+  if test "$ac_cv_header_mach_o_dyld_h" = yes; then
+    dyld_api=true
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDLD 1
+_ACEOF
+
+  LIBS="-ldld $LIBS"
+
+fi
+
+    for ac_func in shl_load shl_findsym
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+    if test "$ac_cv_func_shl_load" = yes \
+      && test "$ac_cv_func_shl_findsym" = yes; then
+      shl_load_api=true
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LoadLibrary in -lwsock32" >&5
+$as_echo_n "checking for LoadLibrary in -lwsock32... " >&6; }
+if test "${ac_cv_lib_wsock32_LoadLibrary+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwsock32  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char LoadLibrary ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return LoadLibrary ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_wsock32_LoadLibrary=yes
+else
+  ac_cv_lib_wsock32_LoadLibrary=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wsock32_LoadLibrary" >&5
+$as_echo "$ac_cv_lib_wsock32_LoadLibrary" >&6; }
+if test "x$ac_cv_lib_wsock32_LoadLibrary" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBWSOCK32 1
+_ACEOF
+
+  LIBS="-lwsock32 $LIBS"
+
+fi
+
+      for ac_func in LoadLibrary
+do :
+  ac_fn_c_check_func "$LINENO" "LoadLibrary" "ac_cv_func_LoadLibrary"
+if test "x$ac_cv_func_LoadLibrary" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LOADLIBRARY 1
+_ACEOF
+
+fi
+done
+
+      if test "$ac_cv_func_loadlibrary" = yes; then
+        loadlibrary_api=true
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+  LIBS="-ldl $LIBS"
+
+fi
+
+        for ac_func in dlopen dlsym dlerror dlclose
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+        if test "$ac_cv_func_dlclose" = yes \
+          && test "$ac_cv_func_dlerror" = yes \
+          && test "$ac_cv_func_dlopen" = yes \
+          && test "$ac_cv_func_dlsym" = yes; then
+          dlopen_api=true
+        else
+	  case "$canonical_host_type" in
+	    i[3456]86-*-sco3.2v5*)
+	      LD_CXX='LD_RUN_PATH=$LD_RUN_PATH:$(octlibdir) $(CXX)'
+	      dlopen_api=true
+	    ;;
+	  esac
+	fi
+      fi
+    fi
+  fi
+
+  ## autoconf test for LoadLibrary appears broken. Bypass for cygwin/mingw
+  if $dlopen_api || $shl_load_api || $loadlibrary_api || $dyld_api; then
+    true
+  else
+    case "$canonical_host_type" in
+      *-*-cygwin* | *-*-mingw* | *-*-msdosmsvc)
+       loadlibrary_api=true;
+      ;;
+    esac
+  fi
+
+  if $dlopen_api; then
+    DL_API_MSG="(dlopen)"
+
+$as_echo "#define HAVE_DLOPEN_API 1" >>confdefs.h
+
+
+  ac_safe=`echo "-rdynamic" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -rdynamic" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -rdynamic... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -rdynamic"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    RDYNAMIC_FLAG=-rdynamic
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+  elif $shl_load_api; then
+    DL_API_MSG="(shl_load)"
+
+$as_echo "#define HAVE_SHL_LOAD_API 1" >>confdefs.h
+
+  elif $loadlibrary_api; then
+    DL_API_MSG="(LoadLibrary)"
+
+$as_echo "#define HAVE_LOADLIBRARY_API 1" >>confdefs.h
+
+  elif $dyld_api; then
+    DL_API_MSG="(dyld)"
+
+$as_echo "#define HAVE_DYLD_API 1" >>confdefs.h
+
+  fi
+
+  if $dlopen_api || $shl_load_api || $loadlibrary_api || $dyld_api; then
+    ENABLE_DYNAMIC_LINKING=true
+
+$as_echo "#define ENABLE_DYNAMIC_LINKING 1" >>confdefs.h
+
+  fi
+fi
+
+if $SHARED_LIBS; then
+   LIBOCTINTERP=-loctinterp$SHLLINKEXT
+   LIBOCTAVE=-loctave$SHLLINKEXT
+   LIBCRUFT=-lcruft$SHLLINKEXT
+else
+  LIBOCTINTERP='$(TOPDIR)/src/liboctinterp.$(LIBEXT)'
+  LIBOCTAVE='$(TOPDIR)/liboctave/liboctave.$(LIBEXT)'
+  LIBCRUFT='$(TOPDIR)/libcruft/libcruft.$(LIBEXT)'
+fi
+
+
+
+
+
+
+
+
+### There is more than one possible prototype for gettimeofday.  See
+### which one (if any) appears in sys/time.h.  These tests are from
+### Emacs 19.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timeval" >&5
+$as_echo_n "checking for struct timeval... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+static struct timeval x; x.tv_sec = x.tv_usec;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+   HAVE_TIMEVAL=yes
+
+$as_echo "#define HAVE_TIMEVAL 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+   HAVE_TIMEVAL=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test "x$HAVE_TIMEVAL" = xyes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gettimeofday can't accept two arguments" >&5
+$as_echo_n "checking whether gettimeofday can't accept two arguments... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+struct timeval time;
+  struct timezone dummy;
+  gettimeofday (&time, &dummy);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define GETTIMEOFDAY_NO_TZ 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::isnan in <cmath>" >&5
+$as_echo_n "checking for std::isnan in <cmath>... " >&6; }
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <cmath>
+void take_func (bool (*func) (double x));
+void take_func (int (*func) (double x));
+void take_func (double (*func) (double x));
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+take_func(std::isnan);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CMATH_ISNAN 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::isnan (float variant) in <cmath>" >&5
+$as_echo_n "checking for std::isnan (float variant) in <cmath>... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <cmath>
+void take_func (bool (*func) (float x));
+void take_func (int (*func) (float x));
+void take_func (float (*func) (float x));
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+take_func(std::isnan);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CMATH_ISNANF 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::isinf in <cmath>" >&5
+$as_echo_n "checking for std::isinf in <cmath>... " >&6; }
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <cmath>
+void take_func (bool (*func) (double x));
+void take_func (int (*func) (double x));
+void take_func (double (*func) (double x));
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+take_func(std::isinf);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CMATH_ISINF 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::isinf (float variant) in <cmath>" >&5
+$as_echo_n "checking for std::isinf (float variant) in <cmath>... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <cmath>
+void take_func (bool (*func) (float x));
+void take_func (int (*func) (float x));
+void take_func (float (*func) (float x));
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+take_func(std::isinf);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CMATH_ISINFF 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::isfinite in <cmath>" >&5
+$as_echo_n "checking for std::isfinite in <cmath>... " >&6; }
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <cmath>
+void take_func (bool (*func) (double x));
+void take_func (int (*func) (double x));
+void take_func (double (*func) (double x));
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+take_func(std::isfinite);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CMATH_ISFINITE 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::isfinite (float variant) in <cmath>" >&5
+$as_echo_n "checking for std::isfinite (float variant) in <cmath>... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <cmath>
+void take_func (bool (*func) (float x));
+void take_func (int (*func) (float x));
+void take_func (float (*func) (float x));
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+take_func(std::isfinite);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CMATH_ISFINITEF 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+### I am told that Inf and NaN don't work on m68k HP sytems, and that
+### on SCO systems, isnan and isinf don't work, but they can be
+### replaced by something that does.
+
+case "$canonical_host_type" in
+  m68k-hp-hpux*)
+  ;;
+  *-*-sco*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: defining SCO to be 1" >&5
+$as_echo "$as_me: defining SCO to be 1" >&6;}
+
+$as_echo "#define SCO 1" >>confdefs.h
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: forcing HAVE_ISINF for SCO" >&5
+$as_echo "$as_me: forcing HAVE_ISINF for SCO" >&6;}
+
+$as_echo "#define HAVE_ISINF 1" >>confdefs.h
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: forcing HAVE_ISNAN for SCO" >&5
+$as_echo "$as_me: forcing HAVE_ISNAN for SCO" >&6;}
+
+$as_echo "#define HAVE_ISNAN 1" >>confdefs.h
+
+  ;;
+  *)
+    for ac_func in finite isnan isinf copysign signbit
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+    for ac_func in _finite _isnan _copysign
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+    ac_fn_c_check_decl "$LINENO" "signbit" "ac_cv_have_decl_signbit" "#include <math.h>
+"
+if test "x$ac_cv_have_decl_signbit" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SIGNBIT $ac_have_decl
+_ACEOF
+
+  ;;
+esac
+
+### Check for nonstandard but common math functions that we need.
+
+for ac_func in acosh acoshf asinh asinhf atanh atanhf erf erff erfc erfcf exp2f log2 log2f
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in hypotf _hypotf
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+### Checks for OS specific cruft.
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blksize" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blocks" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLOCKS 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_rdev" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_RDEV 1
+_ACEOF
+
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if test "${ac_cv_struct_tm+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+struct tm tm;
+				     int *p = &tm.tm_sec;
+				     return !p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_struct_tm=time.h
+else
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+$as_echo "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+
+"
+if test "x$ac_cv_member_struct_tm_tm_zone" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TM_TM_ZONE 1
+_ACEOF
+
+
+fi
+
+if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
+
+$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h
+
+else
+  ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h>
+"
+if test "x$ac_cv_have_decl_tzname" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_TZNAME $ac_have_decl
+_ACEOF
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5
+$as_echo_n "checking for tzname... " >&6; }
+if test "${ac_cv_var_tzname+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <time.h>
+#if !HAVE_DECL_TZNAME
+extern char *tzname[];
+#endif
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return tzname[0][0];
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_var_tzname=yes
+else
+  ac_cv_var_tzname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5
+$as_echo "$ac_cv_var_tzname" >&6; }
+  if test $ac_cv_var_tzname = yes; then
+
+$as_echo "#define HAVE_TZNAME 1" >>confdefs.h
+
+  fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5
+$as_echo_n "checking whether closedir returns void... " >&6; }
+if test "${ac_cv_func_closedir_void+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_closedir_void=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header_dirent>
+#ifndef __cplusplus
+int closedir ();
+#endif
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return closedir (opendir (".")) != 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_closedir_void=no
+else
+  ac_cv_func_closedir_void=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_closedir_void" >&5
+$as_echo "$ac_cv_func_closedir_void" >&6; }
+if test $ac_cv_func_closedir_void = yes; then
+
+$as_echo "#define CLOSEDIR_VOID 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_member "$LINENO" "struct group" "gr_passwd" "ac_cv_member_struct_group_gr_passwd" "$ac_includes_default"
+if test "x$ac_cv_member_struct_group_gr_passwd" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_GROUP_GR_PASSWD 1
+_ACEOF
+
+
+fi
+
+
+# mkdir takes a single argument on some systems.
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mkdir takes one argument" >&5
+$as_echo_n "checking if mkdir takes one argument... " >&6; }
+if test "${octave_cv_mkdir_takes_one_arg+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+mkdir ("foo", 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  octave_cv_mkdir_takes_one_arg=no
+else
+  octave_cv_mkdir_takes_one_arg=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_mkdir_takes_one_arg" >&5
+$as_echo "$octave_cv_mkdir_takes_one_arg" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $octave_cv_mkdir_takes_one_arg = yes ; then
+
+$as_echo "#define MKDIR_TAKES_ONE_ARG 1" >>confdefs.h
+
+fi
+
+
+octave_found_termlib=no
+for termlib in ncurses curses termcap terminfo termlib; do
+  as_ac_Lib=`$as_echo "ac_cv_lib_${termlib}''_tputs" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tputs in -l${termlib}" >&5
+$as_echo_n "checking for tputs in -l${termlib}... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l${termlib}  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tputs ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return tputs ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  TERMLIBS="${TERMLIBS} -l${termlib}"
+fi
+
+  case "${TERMLIBS}" in
+    *-l${termlib}*)
+      LIBS="$TERMLIBS $LIBS"
+
+      octave_found_termlib=yes
+      break
+    ;;
+  esac
+done
+
+if test "$octave_found_termlib" = no; then
+  warn_termlibs="I couldn't find -ltermcap, -lterminfo, -lncurses, -lcurses, o\
+r -ltermlib!"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_termlibs" >&5
+$as_echo "$as_me: WARNING: $warn_termlibs" >&2;}
+fi
+
+
+  USE_READLINE=true
+  LIBREADLINE=
+  # Check whether --enable-readline was given.
+if test "${enable_readline+set}" = set; then :
+  enableval=$enable_readline; if test "$enableval" = no; then
+       USE_READLINE=false
+       warn_readline="command editing and history features require GNU Readline"
+     fi
+fi
+
+  if $USE_READLINE; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_set_keyboard_input_timeout in -lreadline" >&5
+$as_echo_n "checking for rl_set_keyboard_input_timeout in -lreadline... " >&6; }
+if test "${ac_cv_lib_readline_rl_set_keyboard_input_timeout+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rl_set_keyboard_input_timeout ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return rl_set_keyboard_input_timeout ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_readline_rl_set_keyboard_input_timeout=yes
+else
+  ac_cv_lib_readline_rl_set_keyboard_input_timeout=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_set_keyboard_input_timeout" >&5
+$as_echo "$ac_cv_lib_readline_rl_set_keyboard_input_timeout" >&6; }
+if test "x$ac_cv_lib_readline_rl_set_keyboard_input_timeout" = x""yes; then :
+
+      LIBREADLINE="-lreadline"
+      LIBS="$LIBREADLINE $LIBS"
+
+$as_echo "#define USE_READLINE 1" >>confdefs.h
+
+
+else
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I need GNU Readline 4.2 or later" >&5
+$as_echo "$as_me: WARNING: I need GNU Readline 4.2 or later" >&2;}
+      as_fn_error "this is fatal unless you specify --disable-readline" "$LINENO" 5
+
+fi
+
+  fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct exception in math.h" >&5
+$as_echo_n "checking for struct exception in math.h... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <math.h>
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+struct exception *x; x->type; x->name;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define EXCEPTION_IN_MATH 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+### Signal stuff.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if test "${ac_cv_type_signal+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_type_signal=int
+else
+  ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h>
+/* NetBSD declares sys_siglist in unistd.h.  */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+"
+if test "x$ac_cv_have_decl_sys_siglist" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_SIGLIST $ac_have_decl
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for type of signal functions" >&5
+$as_echo_n "checking for type of signal functions... " >&6; }
+if test "${octave_cv_signal_vintage+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <signal.h>
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+sigset_t ss;
+      struct sigaction sa;
+      sigemptyset (&ss);
+      sigsuspend (&ss);
+      sigaction (SIGINT, &sa, (struct sigaction *) 0);
+      sigprocmask (SIG_BLOCK, &ss, (sigset_t *) 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  octave_cv_signal_vintage=posix
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <signal.h>
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+int mask = sigmask (SIGINT);
+	 sigsetmask (mask);
+         sigblock (mask);
+         sigpause (mask);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  octave_cv_signal_vintage=4.2bsd
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <signal.h>
+          RETSIGTYPE foo() { }
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+int mask = sigmask (SIGINT);
+	    sigset (SIGINT, foo);
+            sigrelse (SIGINT);
+	    sighold (SIGINT);
+            sigpause (SIGINT);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  octave_cv_signal_vintage=svr3
+else
+  octave_cv_signal_vintage=v7
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_signal_vintage" >&5
+$as_echo "$octave_cv_signal_vintage" >&6; }
+if test "$octave_cv_signal_vintage" = posix; then
+
+$as_echo "#define HAVE_POSIX_SIGNALS 1" >>confdefs.h
+
+elif test "$octave_cv_signal_vintage" = "4.2bsd"; then
+
+$as_echo "#define HAVE_BSD_SIGNALS 1" >>confdefs.h
+
+elif test "$octave_cv_signal_vintage" = svr3; then
+
+$as_echo "#define HAVE_USG_SIGHOLD 1" >>confdefs.h
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if signal handlers must be reinstalled when invoked" >&5
+$as_echo_n "checking if signal handlers must be reinstalled when invoked... " >&6; }
+if test "${octave_cv_must_reinstall_sighandlers+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  if test "$octave_cv_signal_vintage" = svr3; then
+  octave_cv_must_reinstall_sighandlers=yes
+else
+  octave_cv_must_reinstall_sighandlers=no
+fi
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <signal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+typedef RETSIGTYPE sigfunc();
+int nsigint;
+#ifdef HAVE_POSIX_SIGNALS
+sigfunc *
+set_signal_handler(sig, handler)
+     int sig;
+     sigfunc *handler;
+{
+  struct sigaction act, oact;
+  act.sa_handler = handler;
+  act.sa_flags = 0;
+  sigemptyset (&act.sa_mask);
+  sigemptyset (&oact.sa_mask);
+  sigaction (sig, &act, &oact);
+  return (oact.sa_handler);
+}
+#else
+#define set_signal_handler(s, h) signal(s, h)
+#endif
+RETSIGTYPE
+sigint(s)
+    int s;
+{
+  nsigint++;
+}
+main()
+{
+  nsigint = 0;
+  set_signal_handler(SIGINT, sigint);
+  kill((int)getpid(), SIGINT);
+  kill((int)getpid(), SIGINT);
+  exit(nsigint != 2);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  octave_cv_must_reinstall_sighandlers=no
+else
+  octave_cv_must_reinstall_sighandlers=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+if test "$cross_compiling" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_must_reinstall_sighandlers assumed for cross compilation" >&5
+$as_echo "$octave_cv_must_reinstall_sighandlers assumed for cross compilation" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $octave_cv_must_reinstall_sighandlers" >&5
+$as_echo "$octave_cv_must_reinstall_sighandlers" >&6; }
+fi
+if test "$octave_cv_must_reinstall_sighandlers" = yes; then
+
+$as_echo "#define MUST_REINSTALL_SIGHANDLERS 1" >>confdefs.h
+
+fi
+
+if test "$ac_cv_type_signal" = "void"; then
+
+$as_echo "#define RETSIGTYPE_IS_VOID 1" >>confdefs.h
+
+fi
+
+### A system dependent kluge or two.
+
+for ac_func in getrusage times
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+case "$canonical_host_type" in
+  *-*-cygwin*)
+
+$as_echo "#define RUSAGE_TIMES_ONLY 1" >>confdefs.h
+
+  ;;
+esac
+
+### Checks for other programs used for building, testing, installing,
+### and running Octave.
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+for ac_prog in gfind find
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_FIND+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$FIND"; then
+  ac_cv_prog_FIND="$FIND" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_FIND="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+FIND=$ac_cv_prog_FIND
+if test -n "$FIND"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FIND" >&5
+$as_echo "$FIND" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$FIND" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a usable sed" >&5
+$as_echo_n "checking for a usable sed... " >&6; }
+if test -z "$SED"; then
+  if test "${ac_cv_path_sed+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  # Loop through the user's path and test for sed and gsed.
+  # Then use that list of sed's as ones to test for truncation.
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext"
+	fi
+      done
+    done
+
+  done
+IFS=$as_save_IFS
+
+    # Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+  tmp=`(umask 077 && mktemp -d "$TMPDIR/sedXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=$TMPDIR/sed$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in $TMPDIR" "$LINENO" 5
+    _max=0
+    _count=0
+    # Add /usr/xpg4/bin/sed as it is typically found on Solaris
+    # along with /bin/sed that truncates output.
+    for _sed in $_sed_list /usr/xpg4/bin/sed; do
+      test ! -f ${_sed} && break
+      cat /dev/null > "$tmp/sed.in"
+      _count=0
+      echo $ECHO_N "0123456789$ECHO_C" >"$tmp/sed.in"
+      # Check for GNU sed and select it if it is found.
+      if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then
+	octave_cv_path_sed=${_sed}
+	break;
+      fi
+      # Reject if RE alternation is not handled.
+      if test "`echo 'this and that' | ${_sed} -n 's/\(this\|that\).*$/\1/p'`" != "this"; then
+        continue;
+      fi
+      while true; do
+	cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp"
+	mv "$tmp/sed.tmp" "$tmp/sed.in"
+	cp "$tmp/sed.in" "$tmp/sed.nl"
+	echo >>"$tmp/sed.nl"
+	${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break
+	cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break
+	# 10000 chars as input seems more than enough
+	test $_count -gt 10 && break
+	_count=`expr $_count + 1`
+	if test $_count -gt $_max; then
+	  _max=$_count
+	  octave_cv_path_sed=$_sed
+	fi
+      done
+    done
+    rm -rf "$tmp"
+
+fi
+
+  SED=$octave_cv_path_sed
+  if test -z "$SED"; then
+    as_fn_error "no usable version of sed found" "$LINENO" 5
+  fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5
+$as_echo "$SED" >&6; }
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_PERL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PERL"; then
+  ac_cv_prog_PERL="$PERL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PERL="perl"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PERL=$ac_cv_prog_PERL
+if test -n "$PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+$as_echo "$PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+# Extract the first word of "python", so it can be a program name with args.
+set dummy python; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_PYTHON+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PYTHON"; then
+  ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PYTHON="python"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYTHON=$ac_cv_prog_PYTHON
+if test -n "$PYTHON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+for ac_prog in flex lex
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LEX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LEX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5
+$as_echo "$LEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test "x$LEX" != "x:"; then
+  cat >conftest.l <<_ACEOF
+%%
+a { ECHO; }
+b { REJECT; }
+c { yymore (); }
+d { yyless (1); }
+e { yyless (input () != 0); }
+f { unput (yytext[0]); }
+. { BEGIN INITIAL; }
+%%
+#ifdef YYTEXT_POINTER
+extern char *yytext;
+#endif
+int
+main (void)
+{
+  return ! yylex () + ! yywrap ();
+}
+_ACEOF
+{ { ac_try="$LEX conftest.l"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$LEX conftest.l") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5
+$as_echo_n "checking lex output file root... " >&6; }
+if test "${ac_cv_prog_lex_root+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+if test -f lex.yy.c; then
+  ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+  ac_cv_prog_lex_root=lexyy
+else
+  as_fn_error "cannot find output from $LEX; giving up" "$LINENO" 5
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5
+$as_echo "$ac_cv_prog_lex_root" >&6; }
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+if test -z "${LEXLIB+set}"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5
+$as_echo_n "checking lex library... " >&6; }
+if test "${ac_cv_lib_lex+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_save_LIBS=$LIBS
+    ac_cv_lib_lex='none needed'
+    for ac_lib in '' -lfl -ll; do
+      LIBS="$ac_lib $ac_save_LIBS"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_lex=$ac_lib
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+      test "$ac_cv_lib_lex" != 'none needed' && break
+    done
+    LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5
+$as_echo "$ac_cv_lib_lex" >&6; }
+  test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5
+$as_echo_n "checking whether yytext is a pointer... " >&6; }
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent.  Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+ac_save_LIBS=$LIBS
+LIBS="$LEXLIB $ac_save_LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define YYTEXT_POINTER 1
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_prog_lex_yytext_pointer=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5
+$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; }
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h
+
+fi
+rm -f conftest.l $LEX_OUTPUT_ROOT.c
+
+fi
+
+### For now, don't define LEXLIB to be -lfl -- we don't use anything in
+### it, and it might not be installed.
+###
+### Also make sure that we generate an interactive scanner if we are
+### using flex.
+
+  case "$LEX" in
+    flex*)
+      LFLAGS="-t -I"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: defining LFLAGS to be $LFLAGS" >&5
+$as_echo "defining LFLAGS to be $LFLAGS" >&6; }
+      LEXLIB=
+    ;;
+    *)
+      LEX='$(top_srcdir)/missing flex'
+      warn_flex="I didn't find flex, but it's only a problem if you need to reconstruct lex.cc"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_flex" >&5
+$as_echo "$as_me: WARNING: $warn_flex" >&2;}
+    ;;
+  esac
+
+
+
+  for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_YACC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_YACC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+  case "$YACC" in
+    bison*)
+    ;;
+    *)
+      YACC='$(top_srcdir)/missing bison'
+      warn_bison="I didn't find bison, but it's only a problem if you need to reconstruct parse.cc"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_bison" >&5
+$as_echo "$as_me: WARNING: $warn_bison" >&2;}
+    ;;
+  esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+INSTALL_SCRIPT='${INSTALL}'
+
+
+# Extract the first word of "desktop-file-install", so it can be a program name with args.
+set dummy desktop-file-install; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DESKTOP_FILE_INSTALL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DESKTOP_FILE_INSTALL"; then
+  ac_cv_prog_DESKTOP_FILE_INSTALL="$DESKTOP_FILE_INSTALL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DESKTOP_FILE_INSTALL="desktop-file-install"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DESKTOP_FILE_INSTALL=$ac_cv_prog_DESKTOP_FILE_INSTALL
+if test -n "$DESKTOP_FILE_INSTALL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DESKTOP_FILE_INSTALL" >&5
+$as_echo "$DESKTOP_FILE_INSTALL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+
+case "$canonical_host_type" in
+  *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc)
+    gp_names="pgnuplot pipe-gnuplot gnuplot"
+    gp_default=pgnuplot
+  ;;
+  *)
+    gp_names=gnuplot
+    gp_default=gnuplot
+  ;;
+esac
+if test "$cross_compiling" = yes; then
+  GNUPLOT="$gp_default"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming $GNUPLOT exists on $canonical_host_type host" >&5
+$as_echo "assuming $GNUPLOT exists on $canonical_host_type host" >&6; }
+else
+  for ac_prog in $gp_names
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_GNUPLOT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$GNUPLOT"; then
+  ac_cv_prog_GNUPLOT="$GNUPLOT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_GNUPLOT="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+GNUPLOT=$ac_cv_prog_GNUPLOT
+if test -n "$GNUPLOT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNUPLOT" >&5
+$as_echo "$GNUPLOT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$GNUPLOT" && break
+done
+
+  if test -z "$GNUPLOT"; then
+    warn_gnuplot=yes
+
+    GNUPLOT="$gp_default"
+
+    ## If you change this text, be sure to also copy it to the set of
+    ## warnings at the end of the script
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I didn't find gnuplot.  It isn't necessary to have gnuplot" >&5
+$as_echo "$as_me: WARNING: I didn't find gnuplot.  It isn't necessary to have gnuplot" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: installed, but you won't be able to use any of Octave's" >&5
+$as_echo "$as_me: WARNING: installed, but you won't be able to use any of Octave's" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: plotting commands without it." >&5
+$as_echo "$as_me: WARNING: plotting commands without it." >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: If gnuplot is installed but it isn't in your path, you can" >&5
+$as_echo "$as_me: WARNING: If gnuplot is installed but it isn't in your path, you can" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: tell Octave where to find it by typing the command" >&5
+$as_echo "$as_me: WARNING: tell Octave where to find it by typing the command" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gnuplot_binary = \"/full/path/to/gnuplot/binary\"" >&5
+$as_echo "$as_me: WARNING: gnuplot_binary = \"/full/path/to/gnuplot/binary\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: at the Octave prompt." >&5
+$as_echo "$as_me: WARNING: at the Octave prompt." >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Setting default value to $GNUPLOT" >&5
+$as_echo "$as_me: WARNING: Setting default value to $GNUPLOT" >&2;}
+  fi
+fi
+
+
+if test "$cross_compiling" = yes; then
+  DEFAULT_PAGER=less
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming $DEFAULT_PAGER exists on $canonical_host_type host" >&5
+$as_echo "assuming $DEFAULT_PAGER exists on $canonical_host_type host" >&6; }
+
+else
+  octave_possible_pagers="less more page pg"
+  case "$canonical_host_type" in
+    *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc)
+      octave_possible_pagers="$octave_possible_pagers more.com"
+    ;;
+  esac
+
+  for ac_prog in $octave_possible_pagers
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DEFAULT_PAGER+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DEFAULT_PAGER"; then
+  ac_cv_prog_DEFAULT_PAGER="$DEFAULT_PAGER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DEFAULT_PAGER="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DEFAULT_PAGER=$ac_cv_prog_DEFAULT_PAGER
+if test -n "$DEFAULT_PAGER"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_PAGER" >&5
+$as_echo "$DEFAULT_PAGER" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$DEFAULT_PAGER" && break
+done
+
+  if test -z "$DEFAULT_PAGER"; then
+    warn_less="I couldn't find \`less', \`more', \`page', or \`pg'"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_less" >&5
+$as_echo "$as_me: WARNING: $warn_less" >&2;}
+  fi
+fi
+
+
+  # Extract the first word of "gperf", so it can be a program name with args.
+set dummy gperf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_GPERF+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$GPERF"; then
+  ac_cv_prog_GPERF="$GPERF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_GPERF="gperf"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+GPERF=$ac_cv_prog_GPERF
+if test -n "$GPERF"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPERF" >&5
+$as_echo "$GPERF" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  if test -z "$GPERF"; then
+    GPERF='$(top_srcdir)/missing gperf'
+    warn_gperf="I didn't find gperf, but it's only a problem if you need to reconstruct oct-gperf.h"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_gperf" >&5
+$as_echo "$as_me: WARNING: $warn_gperf" >&2;}
+  fi
+
+
+
+
+  case "$canonical_host_type" in
+    *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc)
+      gs_names="gs gswin32"
+    ;;
+    *)
+      gs_names=gs
+    ;;
+  esac
+  for ac_prog in $gs_names
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_GHOSTSCRIPT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$GHOSTSCRIPT"; then
+  ac_cv_prog_GHOSTSCRIPT="$GHOSTSCRIPT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_GHOSTSCRIPT="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+GHOSTSCRIPT=$ac_cv_prog_GHOSTSCRIPT
+if test -n "$GHOSTSCRIPT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GHOSTSCRIPT" >&5
+$as_echo "$GHOSTSCRIPT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$GHOSTSCRIPT" && break
+done
+
+  if test -z "$GHOSTSCRIPT"; then
+    GHOSTSCRIPT='$(top_srcdir)/missing gs'
+    warn_ghostscript="I didn't find ghostscript, but it's only a problem if you need to reconstruct figures for the manual"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_ghostscript" >&5
+$as_echo "$as_me: WARNING: $warn_ghostscript" >&2;}
+  fi
+
+
+
+  # Extract the first word of "makeinfo", so it can be a program name with args.
+set dummy makeinfo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_MAKEINFO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MAKEINFO"; then
+  ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MAKEINFO="makeinfo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MAKEINFO=$ac_cv_prog_MAKEINFO
+if test -n "$MAKEINFO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5
+$as_echo "$MAKEINFO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  if test -z "$MAKEINFO"; then
+    MAKEINFO='$(top_srcdir)/missing makeinfo'
+    warn_makeinfo="I didn't find makeinfo, but it's only a problem if you need to reconstruct the Info version of the manual"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_makeinfo" >&5
+$as_echo "$as_me: WARNING: $warn_makeinfo" >&2;}
+  fi
+
+
+
+  # Extract the first word of "texi2dvi", so it can be a program name with args.
+set dummy texi2dvi; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_TEXI2DVI+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$TEXI2DVI"; then
+  ac_cv_prog_TEXI2DVI="$TEXI2DVI" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_TEXI2DVI="texi2dvi"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+TEXI2DVI=$ac_cv_prog_TEXI2DVI
+if test -n "$TEXI2DVI"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2DVI" >&5
+$as_echo "$TEXI2DVI" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  if test -z "$TEXI2DVI"; then
+    TEXI2DVI='$(top_srcdir)/missing texi2dvi'
+    warn_texi2dvi="I didn't find texi2dvi, but it's only a problem if you need to reconstruct the DVI version of the manual"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_texi2dvi" >&5
+$as_echo "$as_me: WARNING: $warn_texi2dvi" >&2;}
+  fi
+
+
+
+
+  # Extract the first word of "texi2pdf", so it can be a program name with args.
+set dummy texi2pdf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_TEXI2PDF+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$TEXI2PDF"; then
+  ac_cv_prog_TEXI2PDF="$TEXI2PDF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_TEXI2PDF="texi2pdf"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+TEXI2PDF=$ac_cv_prog_TEXI2PDF
+if test -n "$TEXI2PDF"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2PDF" >&5
+$as_echo "$TEXI2PDF" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  if test -z "$TEXI2PDF"; then
+    missing=true;
+    if test -n "$TEXI2DVI"; then
+      TEXI2PDF="$TEXI2DVI --pdf"
+      missing=false;
+    fi
+  else
+    missing=false;
+  fi
+  if $missing; then
+    TEXI2PDF='$(top_srcdir)/missing texi2pdf'
+    warn_texi2pdf="I didn't find texi2pdf, but it's only a problem if you need to reconstruct the PDF version of the manual"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_texi2pdf" >&5
+$as_echo "$as_me: WARNING: $warn_texi2pdf" >&2;}
+  fi
+
+
+
+### Even though we include config.h, we need to have the preprocessor
+### defines available in a variable for the octave-bug script.  Use
+### UGLY_DEFS for that.
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+### We have to insert extra levels of backslash quoting here so that
+### the right thing ends up in oct-conf.h.
+UGLY_DEFS=`echo $DEFS | $SED 's,\\",\\\\\\\\\\\\\\\\\\",g'`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: defining UGLY_DEFS to be $UGLY_DEFS" >&5
+$as_echo "$as_me: defining UGLY_DEFS to be $UGLY_DEFS" >&6;}
+
+
+### Maybe add -Wall, -W, and -Wshadow to compiler flags now that we're
+### done feature testing.
+
+try_extra_warning_flags=true
+# Check whether --enable-extra-warning-flags was given.
+if test "${enable_extra_warning_flags+set}" = set; then :
+  enableval=$enable_extra_warning_flags; if test "$enableval" = no; then
+     try_extra_warning_flags=false
+   fi
+fi
+
+
+if $try_extra_warning_flags; then
+
+  ac_safe=`echo "-Wall" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -Wall" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -Wall... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -Wall"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CFLAGS="$WARN_CFLAGS -Wall";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wall to WARN_CFLAGS" >&5
+$as_echo "adding -Wall to WARN_CFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-W" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -W" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -W... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -W"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CFLAGS="$WARN_CFLAGS -W";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -W to WARN_CFLAGS" >&5
+$as_echo "adding -W to WARN_CFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-Wshadow" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -Wshadow" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -Wshadow... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -Wshadow"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CFLAGS="$WARN_CFLAGS -Wshadow";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wshadow to WARN_CFLAGS" >&5
+$as_echo "adding -Wshadow to WARN_CFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-Wformat" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -Wformat" >&5
+$as_echo_n "checking whether ${CC-cc} accepts -Wformat... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -Wformat"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CFLAGS="$WARN_CFLAGS -Wformat";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wformat to WARN_CFLAGS" >&5
+$as_echo "adding -Wformat to WARN_CFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+
+  ac_safe=`echo "-Wall" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -Wall" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -Wall... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wall";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wall to WARN_CXXFLAGS" >&5
+$as_echo "adding -Wall to WARN_CXXFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-W" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -W" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -W... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -W"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -W";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -W to WARN_CXXFLAGS" >&5
+$as_echo "adding -W to WARN_CXXFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-Wshadow" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -Wshadow" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -Wshadow... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -Wshadow"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wshadow";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wshadow to WARN_CXXFLAGS" >&5
+$as_echo "adding -Wshadow to WARN_CXXFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-Wold-style-cast" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -Wold-style-cast" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -Wold-style-cast... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -Wold-style-cast"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wold-style-cast";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wold-style-cast to WARN_CXXFLAGS" >&5
+$as_echo "adding -Wold-style-cast to WARN_CXXFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+
+  ac_safe=`echo "-Wformat" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -Wformat" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts -Wformat... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS -Wformat"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat";
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding -Wformat to WARN_CXXFLAGS" >&5
+$as_echo "adding -Wformat to WARN_CXXFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+fi
+
+GCC_STRICT_FLAGS="-Wcast-align -Wcast-qual -Wconversion -Wmissing-prototypes \
+  -Wpointer-arith -Wstrict-prototypes -Wwrite-strings"
+
+GXX_STRICT_FLAGS="-Wcast-align -Wcast-qual -Wconversion -Wpointer-arith \
+  -Wwrite-strings -Weffc++"
+
+try_strict_warning_flags=false
+
+# Check whether --enable-strict-warning-flags was given.
+if test "${enable_strict_warning_flags+set}" = set; then :
+  enableval=$enable_strict_warning_flags; if test "$enableval" = yes; then
+     try_strict_warning_flags=true
+   fi
+fi
+
+
+if $try_strict_warning_flags; then
+  for flag in $GCC_STRICT_FLAGS; do
+
+  ac_safe=`echo "$flag" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts $flag" >&5
+$as_echo_n "checking whether ${CC-cc} accepts $flag... " >&6; }
+  if { as_var=octave_cv_cc_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    XCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $flag"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "octave_cv_cc_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cc_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$XCFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      WARN_CFLAGS="$WARN_CFLAGS $flag";
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding $flag to WARN_CFLAGS" >&5
+$as_echo "adding $flag to WARN_CFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+  done
+  for flag in $GXX_STRICT_FLAGS; do
+
+  ac_safe=`echo "$flag" | sed 'y%./+-:=%__p___%'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts $flag" >&5
+$as_echo_n "checking whether ${CXX-g++} accepts $flag... " >&6; }
+  if { as_var=octave_cv_cxx_flag_$ac_safe; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    XCXXFLAGS="$CXXFLAGS"
+    CXXFLAGS="$CXXFLAGS $flag"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "octave_cv_cxx_flag_$ac_safe=yes"
+else
+  eval "octave_cv_cxx_flag_$ac_safe=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CXXFLAGS="$XCXXFLAGS"
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+  if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      WARN_CXXFLAGS="$WARN_CXXFLAGS $flag";
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding $flag to WARN_CXXFLAGS" >&5
+$as_echo "adding $flag to WARN_CXXFLAGS" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  fi
+
+  done
+fi
+
+
+
+
+### Run configure in subdirectories.
+
+export CC
+export CXX
+export F77
+
+
+
+subdirs="$subdirs scripts"
+
+
+### Some things to add to the bottom of config.h.
+
+
+
+### Do the substitutions in all the Makefiles.
+
+ac_config_commands="$ac_config_commands Makefile"
+
+
+
+
+ac_config_files="$ac_config_files octMakefile Makeconf test/Makefile doc/Makefile doc/faq/Makefile doc/interpreter/Makefile doc/liboctave/Makefile doc/refcard/Makefile emacs/Makefile examples/Makefile examples/@polynomial/Makefile examples/@FIRfilter/Makefile liboctave/Makefile liboctave/oct-types.h src/Makefile src/mxarray.h libcruft/Makefile libcruft/Makerules libcruft/amos/Makefile libcruft/blas/Makefile libcruft/daspk/Makefile libcruft/dasrt/Makefile libcruft/dassl/Makefile libcruft/fftpack/Makefile libcruft/lapack/Makefile libcruft/misc/Makefile libcruft/odepack/Makefile libcruft/ordered-qz/Makefile libcruft/quadpack/Makefile libcruft/ranlib/Makefile libcruft/slatec-fn/Makefile libcruft/slatec-err/Makefile libcruft/villad/Makefile libcruft/blas-xtra/Makefile libcruft/lapack-xtra/Makefile"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.64,
+  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;;
+    "octMakefile") CONFIG_FILES="$CONFIG_FILES octMakefile" ;;
+    "Makeconf") CONFIG_FILES="$CONFIG_FILES Makeconf" ;;
+    "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
+    "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+    "doc/faq/Makefile") CONFIG_FILES="$CONFIG_FILES doc/faq/Makefile" ;;
+    "doc/interpreter/Makefile") CONFIG_FILES="$CONFIG_FILES doc/interpreter/Makefile" ;;
+    "doc/liboctave/Makefile") CONFIG_FILES="$CONFIG_FILES doc/liboctave/Makefile" ;;
+    "doc/refcard/Makefile") CONFIG_FILES="$CONFIG_FILES doc/refcard/Makefile" ;;
+    "emacs/Makefile") CONFIG_FILES="$CONFIG_FILES emacs/Makefile" ;;
+    "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+    "examples/@polynomial/Makefile") CONFIG_FILES="$CONFIG_FILES examples/@polynomial/Makefile" ;;
+    "examples/@FIRfilter/Makefile") CONFIG_FILES="$CONFIG_FILES examples/@FIRfilter/Makefile" ;;
+    "liboctave/Makefile") CONFIG_FILES="$CONFIG_FILES liboctave/Makefile" ;;
+    "liboctave/oct-types.h") CONFIG_FILES="$CONFIG_FILES liboctave/oct-types.h" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "src/mxarray.h") CONFIG_FILES="$CONFIG_FILES src/mxarray.h" ;;
+    "libcruft/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/Makefile" ;;
+    "libcruft/Makerules") CONFIG_FILES="$CONFIG_FILES libcruft/Makerules" ;;
+    "libcruft/amos/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/amos/Makefile" ;;
+    "libcruft/blas/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/blas/Makefile" ;;
+    "libcruft/daspk/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/daspk/Makefile" ;;
+    "libcruft/dasrt/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/dasrt/Makefile" ;;
+    "libcruft/dassl/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/dassl/Makefile" ;;
+    "libcruft/fftpack/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/fftpack/Makefile" ;;
+    "libcruft/lapack/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/lapack/Makefile" ;;
+    "libcruft/misc/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/misc/Makefile" ;;
+    "libcruft/odepack/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/odepack/Makefile" ;;
+    "libcruft/ordered-qz/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/ordered-qz/Makefile" ;;
+    "libcruft/quadpack/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/quadpack/Makefile" ;;
+    "libcruft/ranlib/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/ranlib/Makefile" ;;
+    "libcruft/slatec-fn/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/slatec-fn/Makefile" ;;
+    "libcruft/slatec-err/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/slatec-err/Makefile" ;;
+    "libcruft/villad/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/villad/Makefile" ;;
+    "libcruft/blas-xtra/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/blas-xtra/Makefile" ;;
+    "libcruft/lapack-xtra/Makefile") CONFIG_FILES="$CONFIG_FILES libcruft/lapack-xtra/Makefile" ;;
+
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_t"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+    } >"$tmp/config.h" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$tmp/config.h" "$ac_file" \
+	|| as_fn_error "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "Makefile":C) if test "$ac_srcdir" != "."; then
+  cp $srcdir/Makefile .
+fi ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit $?
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+  # so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  eval "set x $ac_configure_args"
+  shift
+  for ac_arg
+  do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    --disable-option-checking)
+      ;;
+    *)
+      case $ac_arg in
+      *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      esac
+      as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_arg="--prefix=$prefix"
+  case $ac_arg in
+  *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+  # Pass --silent
+  if test "$silent" = yes; then
+    ac_sub_configure_args="--silent $ac_sub_configure_args"
+  fi
+
+  # Always prepend --disable-option-checking to silence warnings, since
+  # different subdirs can have different --enable and --with options.
+  ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d "$srcdir/$ac_dir" || continue
+
+    ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
+    $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+    $as_echo "$ac_msg" >&6
+    as_dir="$ac_dir"; as_fn_mkdir_p
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+    cd "$ac_dir"
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      ac_sub_configure=$ac_srcdir/configure.gnu
+    elif test -f "$ac_srcdir/configure"; then
+      ac_sub_configure=$ac_srcdir/configure
+    elif test -f "$ac_srcdir/configure.in"; then
+      # This should be Cygnus configure.
+      ac_sub_configure=$ac_aux_dir/configure
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative name.
+	ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
+      esac
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
+	   --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
+	as_fn_error "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+    fi
+
+    cd "$ac_popdir"
+  done
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+### Print a summary so that important information isn't missed.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}:
+
+Octave is now configured for $canonical_host_type
+
+  Source directory:     $srcdir
+  Installation prefix:  $prefix
+  C compiler:           $CC $XTRA_CFLAGS $WARN_CFLAGS $CFLAGS
+  C++ compiler:         $CXX $XTRA_CXXFLAGS $WARN_CXXFLAGS $CXXFLAGS
+  Fortran compiler:     $F77 $FFLAGS
+  Fortran libraries:    $FLIBS
+  BLAS libraries:       $BLAS_LIBS
+  FFTW libraries:       $FFTW_LIBS
+  GLPK libraries:       $GLPK_LIBS
+  UMFPACK libraries:    $UMFPACK_LIBS
+  AMD libraries:        $AMD_LIBS
+  CAMD libraries:       $CAMD_LIBS
+  COLAMD libraries:     $COLAMD_LIBS
+  CCOLAMD libraries:    $CCOLAMD_LIBS
+  CHOLMOD libraries:    $CHOLMOD_LIBS
+  CXSPARSE libraries:   $CXSPARSE_LIBS
+  ARPACK libraries:     $ARPACK_LIBS
+  QRUPDATE libraries:	$QRUPDATE_LIBS
+  HDF5 libraries:       $HDF5_LIBS
+  CURL libraries:       $CURL_LIBS
+  REGEX libraries:      $REGEX_LIBS
+  QHULL libraries:	$QHULL_LIBS
+  OPENGL libraries:     $OPENGL_LIBS
+  FLTK backend libs:    $GRAPHICS_LIBS
+  X11 include flags:    $X11_INCFLAGS
+  X11 libraries:        $X11_LIBS
+  CARBON libraries:     $CARBON_LIBS
+  PTHREAD flags         $PTHREAD_CFLAGS
+  PTHREAD libraries     $PTHREAD_LIBS
+  LIBS:                 $LIBS
+  Default pager:        $DEFAULT_PAGER
+  gnuplot:              $GNUPLOT
+  Magick config:        $MAGICK_CONFIG
+
+  Do internal array bounds checking:  $BOUNDS_CHECKING
+  Build static libraries:             $STATIC_LIBS
+  Build shared libraries:             $SHARED_LIBS
+  Dynamic Linking:                    $ENABLE_DYNAMIC_LINKING $DL_API_MSG
+  Include support for GNU readline:   $USE_READLINE
+  64-bit array dims and indexing:     $USE_64_BIT_IDX_T
+" >&5
+$as_echo "$as_me:
+
+Octave is now configured for $canonical_host_type
+
+  Source directory:     $srcdir
+  Installation prefix:  $prefix
+  C compiler:           $CC $XTRA_CFLAGS $WARN_CFLAGS $CFLAGS
+  C++ compiler:         $CXX $XTRA_CXXFLAGS $WARN_CXXFLAGS $CXXFLAGS
+  Fortran compiler:     $F77 $FFLAGS
+  Fortran libraries:    $FLIBS
+  BLAS libraries:       $BLAS_LIBS
+  FFTW libraries:       $FFTW_LIBS
+  GLPK libraries:       $GLPK_LIBS
+  UMFPACK libraries:    $UMFPACK_LIBS
+  AMD libraries:        $AMD_LIBS
+  CAMD libraries:       $CAMD_LIBS
+  COLAMD libraries:     $COLAMD_LIBS
+  CCOLAMD libraries:    $CCOLAMD_LIBS
+  CHOLMOD libraries:    $CHOLMOD_LIBS
+  CXSPARSE libraries:   $CXSPARSE_LIBS
+  ARPACK libraries:     $ARPACK_LIBS
+  QRUPDATE libraries:	$QRUPDATE_LIBS
+  HDF5 libraries:       $HDF5_LIBS
+  CURL libraries:       $CURL_LIBS
+  REGEX libraries:      $REGEX_LIBS
+  QHULL libraries:	$QHULL_LIBS
+  OPENGL libraries:     $OPENGL_LIBS
+  FLTK backend libs:    $GRAPHICS_LIBS
+  X11 include flags:    $X11_INCFLAGS
+  X11 libraries:        $X11_LIBS
+  CARBON libraries:     $CARBON_LIBS
+  PTHREAD flags         $PTHREAD_CFLAGS
+  PTHREAD libraries     $PTHREAD_LIBS
+  LIBS:                 $LIBS
+  Default pager:        $DEFAULT_PAGER
+  gnuplot:              $GNUPLOT
+  Magick config:        $MAGICK_CONFIG
+
+  Do internal array bounds checking:  $BOUNDS_CHECKING
+  Build static libraries:             $STATIC_LIBS
+  Build shared libraries:             $SHARED_LIBS
+  Dynamic Linking:                    $ENABLE_DYNAMIC_LINKING $DL_API_MSG
+  Include support for GNU readline:   $USE_READLINE
+  64-bit array dims and indexing:     $USE_64_BIT_IDX_T
+" >&6;}
+
+warn_msg_printed=false
+
+if $ENABLE_DYNAMIC_LINKING; then
+  if $SHARED_LIBS; then
+    true
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You used --enable-dl but not --enable-shared." >&5
+$as_echo "$as_me: WARNING: You used --enable-dl but not --enable-shared." >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Are you sure that is what you want to do?" >&5
+$as_echo "$as_me: WARNING: Are you sure that is what you want to do?" >&2;}
+    warn_msg_printed=true
+  fi
+fi
+
+if test -n "$gxx_only"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $gxx_only" >&5
+$as_echo "$as_me: WARNING: $gxx_only" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gcc_version"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_gcc_version" >&5
+$as_echo "$as_me: WARNING: $warn_gcc_version" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gcc_only"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_gcc_only" >&5
+$as_echo "$as_me: WARNING: $warn_gcc_only" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_readline"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_readline" >&5
+$as_echo "$as_me: WARNING: $warn_readline" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_termlibs"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_termlibs" >&5
+$as_echo "$as_me: WARNING: $warn_termlibs" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gperf"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_gperf" >&5
+$as_echo "$as_me: WARNING: $warn_gperf" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_flex"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_flex" >&5
+$as_echo "$as_me: WARNING: $warn_flex" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_bison"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_bison" >&5
+$as_echo "$as_me: WARNING: $warn_bison" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_less"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_less" >&5
+$as_echo "$as_me: WARNING: $warn_less" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_blas_f77_incompatible"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_blas_f77_incompatible" >&5
+$as_echo "$as_me: WARNING: $warn_blas_f77_incompatible" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_umfpack"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_umfpack" >&5
+$as_echo "$as_me: WARNING: $warn_umfpack" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_qrupdate"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_qrupdate" >&5
+$as_echo "$as_me: WARNING: $warn_qrupdate" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_amd"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_amd" >&5
+$as_echo "$as_me: WARNING: $warn_amd" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_colamd"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_colamd" >&5
+$as_echo "$as_me: WARNING: $warn_colamd" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_ccolamd"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_ccolamd" >&5
+$as_echo "$as_me: WARNING: $warn_ccolamd" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_cholmod"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_cholmod" >&5
+$as_echo "$as_me: WARNING: $warn_cholmod" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_cxsparse"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_cxsparse" >&5
+$as_echo "$as_me: WARNING: $warn_cxsparse" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_arpack"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_arpack" >&5
+$as_echo "$as_me: WARNING: $warn_arpack" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_curl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_curl" >&5
+$as_echo "$as_me: WARNING: $warn_curl" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_fftw"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_fftw" >&5
+$as_echo "$as_me: WARNING: $warn_fftw" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_glpk"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_glpk" >&5
+$as_echo "$as_me: WARNING: $warn_glpk" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_magick"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_magick" >&5
+$as_echo "$as_me: WARNING: $warn_magick" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_hdf5"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_hdf5" >&5
+$as_echo "$as_me: WARNING: $warn_hdf5" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_regex"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_regex" >&5
+$as_echo "$as_me: WARNING: $warn_regex" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_pcre"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_pcre" >&5
+$as_echo "$as_me: WARNING: $warn_pcre" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_qhull"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_qhull" >&5
+$as_echo "$as_me: WARNING: $warn_qhull" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_zlib"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_zlib" >&5
+$as_echo "$as_me: WARNING: $warn_zlib" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_ghostscript"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_ghostscript" >&5
+$as_echo "$as_me: WARNING: $warn_ghostscript" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_makeinfo"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_makeinfo" >&5
+$as_echo "$as_me: WARNING: $warn_makeinfo" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_texi2dvi"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_texi2dvi" >&5
+$as_echo "$as_me: WARNING: $warn_texi2dvi" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_texi2pdf"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_texi2pdf" >&5
+$as_echo "$as_me: WARNING: $warn_texi2pdf" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_64_bit"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $warn_64_bit" >&5
+$as_echo "$as_me: WARNING: $warn_64_bit" >&2;}
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gnuplot"; then
+
+  ## If you change this text, be sure to also change the corresponding
+  ## set of warnings above.
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I didn't find gnuplot.  It isn't necessary to have gnuplot" >&5
+$as_echo "$as_me: WARNING: I didn't find gnuplot.  It isn't necessary to have gnuplot" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: installed, but you won't be able to use any of Octave's" >&5
+$as_echo "$as_me: WARNING: installed, but you won't be able to use any of Octave's" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: plotting commands without it." >&5
+$as_echo "$as_me: WARNING: plotting commands without it." >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: If gnuplot is installed but it isn't in your path, you can" >&5
+$as_echo "$as_me: WARNING: If gnuplot is installed but it isn't in your path, you can" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: tell Octave where to find it by typing the command" >&5
+$as_echo "$as_me: WARNING: tell Octave where to find it by typing the command" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gnuplot_binary = \"/full/path/to/gnuplot/binary\"" >&5
+$as_echo "$as_me: WARNING: gnuplot_binary = \"/full/path/to/gnuplot/binary\"" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: at the Octave prompt." >&5
+$as_echo "$as_me: WARNING: at the Octave prompt." >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  warn_msg_printed=true
+fi
+
+if $USE_64_BIT_IDX_T; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You used the EXPERIMENTAL --enable-64 option." >&5
+$as_echo "$as_me: WARNING: You used the EXPERIMENTAL --enable-64 option." >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Are you sure that is what you want to do?" >&5
+$as_echo "$as_me: WARNING: Are you sure that is what you want to do?" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must ensure that the Fortran compiler generates" >&5
+$as_echo "$as_me: WARNING: You must ensure that the Fortran compiler generates" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: code with 8 byte signed INTEGER values, and that your" >&5
+$as_echo "$as_me: WARNING: code with 8 byte signed INTEGER values, and that your" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: BLAS and LAPACK libraries are compiled to use 8 byte" >&5
+$as_echo "$as_me: WARNING: BLAS and LAPACK libraries are compiled to use 8 byte" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: signed integers for array indexing." >&5
+$as_echo "$as_me: WARNING: signed integers for array indexing." >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  warn_msg_printed=true
+fi
+
+native_graphics=true
+if test -n "$warn_freetype"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$warn_freetype\"" >&5
+$as_echo "$as_me: WARNING: \"$warn_freetype\"" >&2;}
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_ftgl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$warn_ftgl\"" >&5
+$as_echo "$as_me: WARNING: \"$warn_ftgl\"" >&2;}
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_fltk_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$warn_fltk_config\"" >&5
+$as_echo "$as_me: WARNING: \"$warn_fltk_config\"" >&2;}
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_fltk_opengl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$warn_fltk_opengl\"" >&5
+$as_echo "$as_me: WARNING: \"$warn_fltk_opengl\"" >&2;}
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if $native_graphics; then
+  true;
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I didn't find the necessary libraries to compile native" >&5
+$as_echo "$as_me: WARNING: I didn't find the necessary libraries to compile native" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: graphics. It isn't necessary to have native graphics" >&5
+$as_echo "$as_me: WARNING: graphics. It isn't necessary to have native graphics" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: but you will have to use gnuplot or you won't be able" >&5
+$as_echo "$as_me: WARNING: but you will have to use gnuplot or you won't be able" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: to use any of Octave's plotting commands" >&5
+$as_echo "$as_me: WARNING: to use any of Octave's plotting commands" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: " >&5
+$as_echo "$as_me: WARNING: " >&2;}
+  warn_msg_printed=true
+fi
+
+if $warn_msg_printed; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}:
+
+NOTE: libraries may be skipped if a library is not found OR
+      if the library on your system is missing required features.
+" >&5
+$as_echo "$as_me:
+
+NOTE: libraries may be skipped if a library is not found OR
+      if the library on your system is missing required features.
+" >&6;}
+fi
+
+### End of configure.
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..5f32656
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,2482 @@
+dnl configure.in
+dnl
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+dnl               2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+dnl               2009 John W. Eaton
+### 
+### This file is part of Octave.
+### 
+### Octave is free software; you can redistribute it and/or modify it
+### under the terms of the GNU General Public License as published by the
+### Free Software Foundation; either version 3 of the License, or (at
+### your option) any later version.
+### 
+### Octave is distributed in the hope that it will be useful, but WITHOUT
+### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+### FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+### for more details.
+### 
+### You should have received a copy of the GNU General Public License
+### along with Octave; see the file COPYING.  If not, see
+### <http://www.gnu.org/licenses/>.
+
+### Preserve CFLAGS and CXXFLAGS from the environment before doing
+### anything else because we don't know which macros might call
+### AC_PROG_CC or AC_PROG_CXX.
+
+EXTERN_CFLAGS="$CFLAGS"
+EXTERN_CXXFLAGS="$CXXFLAGS"
+
+AC_INIT
+AC_REVISION($Revision: 1.603 $)
+AC_PREREQ(2.60)
+AC_CONFIG_SRCDIR([src/octave.cc])
+AC_CONFIG_HEADER(config.h)
+
+OCTAVE_HOST_TYPE
+
+AC_DEFINE(OCTAVE_SOURCE, 1, [Define if this is Octave.])
+  
+dnl FIXME -- we should probably only generate this file if it is missing.
+### Produce unistd.h for MSVC target, this simplifies changes in
+### Octave source tree and avoid problems with lex-generated code.
+case "$canonical_host_type" in
+  *-*-msdosmsvc)
+    AC_MSG_NOTICE([Generating replacement for <unistd.h> for MSVC])
+    cat << \EOF > unistd.h
+/* File generated by configure script. */
+#include <direct.h>
+#include <io.h>
+#include <process.h>
+EOF
+    CPPFLAGS="-I. $CPPFLAGS"
+    ;;
+esac
+
+AC_USE_SYSTEM_EXTENSIONS
+
+### Path separator.
+sepchar=:
+AC_ARG_WITH(sepchar,
+  [AS_HELP_STRING([--with-sepchar=<char>],
+     [use <char> as the path separation character])])
+case $with_sepchar in
+  yes | "")
+    case "$canonical_host_type" in
+      *-*-mingw* | *-*-msdosmsvc)
+	sepchar=';'
+        ;;
+      esac
+    ;;
+  no)
+    AC_MSG_ERROR([You are required to define a path separation character])
+    ;;
+  *)
+    sepchar=$with_sepchar
+    ;;
+esac
+AC_SUBST(sepchar)
+AC_DEFINE_UNQUOTED(SEPCHAR, ['$sepchar'], [Define this to be the path separator for your system, as a character constant.])
+AC_DEFINE_UNQUOTED(SEPCHAR_STR, ["$sepchar"], [Define this to the path separator, as a string.])
+
+### some defaults
+
+OCTAVE_SET_DEFAULT(man1dir, '$(mandir)/man1')
+OCTAVE_SET_DEFAULT(man1ext, '.1')
+OCTAVE_SET_DEFAULT(doc_cache_file, '$(octetcdir)/doc-cache')
+OCTAVE_SET_DEFAULT(infofile, '$(infodir)/octave.info')
+OCTAVE_SET_DEFAULT(octincludedir, '$(includedir)/octave-$(version)')
+OCTAVE_SET_DEFAULT(fcnfiledir, '$(datadir)/octave/$(version)/m')
+OCTAVE_SET_DEFAULT(localfcnfiledir, '$(datadir)/octave/site/m')
+OCTAVE_SET_DEFAULT(localapifcnfiledir,
+  '$(datadir)/octave/site/$(api_version)/m')
+OCTAVE_SET_DEFAULT(localverfcnfiledir, '$(datadir)/octave/$(version)/site/m')
+OCTAVE_SET_DEFAULT(octetcdir, '$(datadir)/octave/$(version)/etc')
+OCTAVE_SET_DEFAULT(octlibdir, '$(libdir)/octave-$(version)')
+OCTAVE_SET_DEFAULT(archlibdir,
+  '$(libexecdir)/octave/$(version)/exec/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(localarchlibdir,
+  '$(libexecdir)/octave/site/exec/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(localapiarchlibdir,
+  '$(libexecdir)/octave/$(api_version)/site/exec/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(localverarchlibdir,
+  '$(libexecdir)/octave/$(version)/site/exec/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(octfiledir,
+  '$(libexecdir)/octave/$(version)/oct/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(localoctfiledir,
+  '$(libexecdir)/octave/site/oct/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(localapioctfiledir,
+  '$(libexecdir)/octave/site/oct/$(api_version)/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(localveroctfiledir,
+  '$(libexecdir)/octave/$(version)/site/oct/$(canonical_host_type)')
+OCTAVE_SET_DEFAULT(imagedir, '$(datadir)/octave/$(version)/imagelib')
+
+### Make configure args available for other uses.
+
+config_opts=$ac_configure_args
+AC_SUBST(config_opts)
+
+### Make it possible to have Octave's array and matrix classes do bounds
+### checking on element references.  This slows some operations down a
+### bit, so it is turned off by default.
+
+BOUNDS_CHECKING=false
+AC_ARG_ENABLE(bounds-check,
+  [AS_HELP_STRING([--enable-bounds-check],
+     [bounds checking for indexing in internal array classes (default is no)])],
+  [if test "$enableval" = yes; then BOUNDS_CHECKING=true; fi], [])
+if $BOUNDS_CHECKING; then
+  AC_DEFINE(BOUNDS_CHECKING, 1, [Define to use internal bounds checking.])
+fi
+
+### If possible, use a 64-bit integer type for array dimensions and indexing.
+
+USE_64_BIT_IDX_T=false
+OCTAVE_IDX_TYPE=int
+AC_ARG_ENABLE(64,
+  [AS_HELP_STRING([--enable-64],
+     [(EXPERIMENTAL) use 64-bit integers for array dimensions and indexing])],
+  [if test "$enableval" = yes; then USE_64_BIT_IDX_T=true; fi], [])
+if $USE_64_BIT_IDX_T; then
+  AC_CHECK_SIZEOF(void *)
+  AC_CHECK_SIZEOF(int)
+  AC_CHECK_SIZEOF(long)
+  if test $ac_cv_sizeof_void_p -eq 8; then
+    if test $ac_cv_sizeof_int -eq 8; then
+      OCTAVE_IDX_TYPE=int
+    elif test $ac_cv_sizeof_long -eq 8; then
+      OCTAVE_IDX_TYPE=long
+      AC_DEFINE(IDX_TYPE_LONG, 1, [Define to 1 if octave index type is long])
+    else
+      warn_64_bit="no suitable type found for octave_idx_type so disabling 64-bit features"
+      AC_MSG_WARN($warn_64_bit)
+      USE_64_BIT_IDX_T=false
+    fi
+  else
+    warn_64_bit="pointers are not 64-bits wide so disabling 64-bit features"
+    AC_MSG_WARN($warn_64_bit)
+    USE_64_BIT_IDX_T=false
+  fi
+fi
+AC_SUBST(OCTAVE_IDX_TYPE)
+if $USE_64_BIT_IDX_T; then
+  AC_DEFINE(USE_64_BIT_IDX_T, 1, [Define if using 64-bit integers for array dimensions and indexing])
+fi
+AC_SUBST(USE_64_BIT_IDX_T)
+
+### It seems that there are some broken inline assembly functions in
+### the GNU libc.  Since I'm not sure how to test whether we are using
+### GNU libc, just disable them for all platforms.
+
+AC_MSG_NOTICE([defining __NO_MATH_INLINES avoids buggy GNU libc exp function])
+AC_DEFINE(__NO_MATH_INLINES, 1, [Define if your version of GNU libc has buggy inline assembly code for math functions like exp.])
+
+### See which C++ compiler to use (we expect to find g++).
+
+AC_PROG_CXX
+AC_PROG_CXXCPP
+
+### Do special things for g++.
+
+gxx_version=`$CXX -v 2>&1 | grep "^.*g.. version" | \
+  sed -e 's/^.*g.. version *//' -e 's/cygnus-//' -e 's/egcs-//' -e 's/ .*//'`
+
+case "$gxx_version" in
+  1.* | 2.[[0123456789]].* | 3.[[01234]].*)
+    AC_MSG_ERROR([g++ version $gxx_version will probably fail to compile Octave]
+)
+  ;;
+esac
+
+CXX_VERSION=
+if test -n "$gxx_version"; then
+  CXX_VERSION="$gxx_version"
+fi
+AC_SUBST(CXX_VERSION)
+
+OCTAVE_CXX_NEW_FRIEND_TEMPLATE_DECL
+OCTAVE_CXX_ISO_COMPLIANT_LIBRARY
+OCTAVE_CXX_BROKEN_REINTERPRET_CAST
+
+### See which C compiler to use (we expect to find gcc).
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_GCC_TRADITIONAL
+
+### Do special things for gcc.
+
+gcc_version=`$CC -v 2>&1 | grep "^.*gcc version" | \
+  sed -e 's/^.*g.. version *//' -e 's/cygnus-//' -e 's/egcs-//'`
+case "$gcc_version" in
+  2.*)
+    if test -z "$LDFLAGS"; then
+      LDFLAGS="-g"
+      AC_MSG_NOTICE([defining LDFLAGS to be $LDFLAGS])
+    fi
+  ;;
+  1.*)
+    warn_gcc_version="gcc version $gcc_version is likely to cause problems"
+    AC_MSG_WARN($warn_gcc_version)
+  ;;
+esac
+
+CC_VERSION=
+if test -n "$gcc_version"; then
+  CC_VERSION="$gcc_version"
+fi
+AC_SUBST(CC_VERSION)
+
+### The flag to create dependency varies depending on the compier.
+
+# Assume GCC.
+INCLUDE_DEPS=true
+DEPEND_FLAGS="-M"
+DEPEND_EXTRA_SED_PATTERN=""
+if test "$GCC" = yes; then
+  true
+else
+  case "$canonical_host_type" in
+    sparc-sun-solaris2* | i386-pc-solaris2*)
+      DEPEND_FLAGS="-xM1"
+      DEPEND_EXTRA_SED_PATTERN="-e '/\/opt\/SUNWspro/d'"
+    ;;
+    *-*-msdosmsvc)
+    ;;
+    *)
+      INCLUDE_DEPS=false
+    ;;
+  esac
+fi
+AC_SUBST(INCLUDE_DEPS)
+AC_SUBST(DEPEND_FLAGS)
+AC_SUBST(DEPEND_EXTRA_SED_PATTERN)
+
+sinclude(acx_pthread.m4)
+ACX_PTHREAD
+
+AC_PATH_X
+if test "$have_x"; then
+  AC_DEFINE(HAVE_X_WINDOWS, 1, [Define if you have X11])
+
+  if test "$x_includes" != "NONE"; then
+    X11_INCFLAGS="$x_includes"
+  fi
+  AC_SUBST(X11_INCFLAGS)
+
+  if test -z $x_libraries; then
+    AC_CHECK_LIB(X11, XrmInitialize, [X11_LIBS=-lX11], [X11_LIBS=])
+  elif test $x_libraries != "NONE"; then
+    AC_CHECK_LIB(X11, XrmInitialize, 
+      [X11_LIBS="-L$x_libraries -lX11"], [X11_LIBS=], "-L$x_libraries")
+  fi
+  AC_SUBST(X11_LIBS)
+fi
+
+### On MacOSX system the Carbon framework is used to determine ScreenSize
+OCTAVE_HAVE_FRAMEWORK(Carbon, [#include <Carbon/Carbon.h>], [CGMainDisplayID ()],
+  [have_framework_carbon="yes"], [have_framework_carbon="no"])
+if test $have_framework_carbon = "yes"; then
+  AC_DEFINE(HAVE_FRAMEWORK_CARBON, 1, [Define if framework CARBON is available.])
+  CARBON_LIBS="-Wl,-framework -Wl,Carbon"
+  AC_MSG_NOTICE([adding -Wl,-framework -Wl,Carbon to CARBON_LIBS])
+  AC_SUBST(CARBON_LIBS)
+fi
+
+### On Intel systems with gcc, we may need to compile with -mieee-fp
+### and -ffloat-store to get full support for IEEE floating point.
+###
+### On Alpha/OSF systems, we need -mieee.
+
+ieee_fp_flag=
+case "$canonical_host_type" in
+  ## Keep this pattern first, so that it is preferred over the
+  ## following pattern for x86.
+  *-*-msdosmsvc)
+    CXXFLAGS="$CXXFLAGS -EHs -MD"
+    CFLAGS="$CFLAGS -MD"
+  ;;
+  i[[3456789]]86-*-*)
+    if test "$GCC" = yes; then
+      OCTAVE_CC_FLAG(-mieee-fp, [
+        ieee_fp_flag=-mieee-fp
+        XTRA_CFLAGS="$XTRA_CFLAGS -mieee-fp"
+        AC_MSG_NOTICE([adding -mieee-fp to XTRA_CFLAGS])])
+
+###      OCTAVE_CC_FLAG(-ffloat-store, [
+###        float_store_flag=-ffloat-store
+###        XTRA_CFLAGS="$XTRA_CFLAGS -ffloat-store"
+###        AC_MSG_RESULT([adding -ffloat-store to XTRA_CFLAGS])])
+    fi
+    if test "$GXX" = yes; then
+      OCTAVE_CXX_FLAG(-mieee-fp, [
+	ieee_fp_flag=-mieee-fp
+	XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mieee-fp"
+	AC_MSG_NOTICE([adding -mieee-fp to XTRA_CXXFLAGS])])
+
+###      OCTAVE_CXX_FLAG(-ffloat-store, [
+###        float_store_flag=-ffloat-store
+###        XTRA_CXXFLAGS="$XTRA_CXXFLAGS -ffloat-store"
+###        AC_MSG_RESULT([adding -ffloat-store to XTRA_CXXFLAGS])])
+    fi
+  ;;
+  alpha*-*-*)
+    if test "$GCC" = yes; then
+      OCTAVE_CC_FLAG(-mieee, [
+	ieee_fp_flag=-mieee
+	XTRA_CFLAGS="$XTRA_CFLAGS -mieee"
+	AC_MSG_NOTICE([adding -mieee to XTRA_CFLAGS])])
+    else
+      OCTAVE_CC_FLAG(-ieee, [
+	ieee_fp_flag=-ieee
+	XTRA_CFLAGS="$XTRA_CFLAGS -ieee"
+	AC_MSG_NOTICE([adding -ieee to XTRA_CFLAGS])])
+    fi
+    if test "$GXX" = yes; then
+      OCTAVE_CXX_FLAG(-mieee, [
+	ieee_fp_flag=-mieee
+	XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mieee"
+	AC_MSG_NOTICE([adding -mieee to XTRA_CXXFLAGS])])
+    else
+      OCTAVE_CXX_FLAG(-ieee, [
+	ieee_fp_flag=-ieee
+	XTRA_CXXFLAGS="$XTRA_CXXFLAGS -ieee"
+	AC_MSG_NOTICE([adding -ieee to XTRA_CXXFLAGS])])
+    fi
+  ;;
+  *ibm-aix4*)
+    OCTAVE_CC_FLAG(-mminimal-toc, [
+      XTRA_CFLAGS="$XTRA_CFLAGS -mminimal-toc"])
+
+    OCTAVE_CXX_FLAG(-mminimal-toc, [
+      XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mminimal-toc"])
+  ;;
+esac
+
+AC_SUBST(XTRA_CFLAGS)
+AC_SUBST(XTRA_CXXFLAGS)
+
+### Use -static if compiling on Alpha OSF/1 1.3 systems.
+
+case "$canonical_host_type" in
+  alpha*-dec-osf1.3)
+    LD_STATIC_FLAG=-static
+  ;;
+esac
+if test -n "$LD_STATIC_FLAG"; then
+  AC_MSG_NOTICE([defining LD_STATIC_FLAG to be $LD_STATIC_FLAG])
+fi
+AC_SUBST(LD_STATIC_FLAG)
+
+### Defaults for cross compiling.  BUILD_CC and BUILD_CXX are
+### the compilers that we use for building tools on the build system.
+### For now, we assume that the only cross compiling we can do is
+### with gcc on a Unixy system, but the dedicated hacker can override these.
+
+if test "$cross_compiling" = yes; then
+  BUILD_CC="gcc"
+  BUILD_CFLAGS="-O2 -g"
+  BUILD_CXX="g++"
+  BUILD_CXXFLAGS="-O2 -g"
+  BUILD_LDFLAGS=""
+  BUILD_EXEEXT=""
+else
+  BUILD_CC='$(CC)'
+  BUILD_CFLAGS='$(CFLAGS)'
+  BUILD_CXX='$(CXX)'
+  BUILD_CXXFLAGS='$(CXXFLAGS)'
+  BUILD_LDFLAGS='$(LDFLAGS)'
+  case "$canonical_host_type" in
+    sparc-sun-solaris2*)
+      if test "$GCC" != yes; then
+        ## The Sun C++ compiler never seems to complete compiling
+	## gendoc.cc unless we reduce the optimization level...
+	BUILD_CXXFLAGS="-g -O1"
+      fi
+    ;;
+  esac
+  BUILD_EXEEXT='$(EXEEXT)'
+fi
+
+AC_ARG_VAR(BUILD_CC, [build system C compiler (used if cross compiling)])
+AC_ARG_VAR(BUILD_CFLAGS, [build system C compiler flags (used if cross compiling)])
+AC_ARG_VAR(BUILD_CXX, [build system C++ compiler (used if cross compiling)])
+AC_ARG_VAR(BUILD_CXXFLAGS, [build system C++ compiler flags (used if cross compiling)])
+AC_ARG_VAR(BUILD_LDFLAGS, [build system C++ compiler link flags (used if cross compiling)])
+AC_ARG_VAR(BUILD_EXEEXT, [build system executable extension (used if cross compiling)])
+
+dnl This is bogus.  We shouldn't have to explicitly add libc too!
+
+### Look for math library.  If found, this will add -lm to LIBS.
+
+case "$canonical_host_type" in
+  *-*-nextstep*)
+  ;;  
+  *-*-linux*)
+    AC_CHECK_LIB(m, sin, , , -lc)
+  ;;
+  *)
+    AC_CHECK_LIB(m, sin)
+  ;;
+esac
+
+### Check for the QHull library
+AC_SUBST(QHULL_LIBS)
+AC_CHECK_HEADER(qhull/qhull_a.h, have_qhull=yes, have_qhull=no)
+if test "$have_qhull" = yes; then
+  AC_CHECK_LIB(qhull, qh_qhull, have_qhull=yes, have_qhull=no)
+  if test "$have_qhull" != yes; then
+    AC_CHECK_QHULL_VERSION(have_qhull=yes, have_qhull=no)
+    AC_DEFINE(NEED_QHULL_VERSION, 1, [Define if the QHull library needs a wh_version variable defined.])
+  fi
+  if test "$have_qhull" = yes; then
+    AC_CHECK_QHULL_OK(have_qhull=yes, have_qhull=bad)
+  fi
+fi
+if test "$have_qhull" = yes; then
+  AC_DEFINE(HAVE_QHULL, 1, [Define if the QHull library is used.])
+  QHULL_LIBS="-lqhull"
+  TEXINFO_QHULL="@set HAVE_QHULL"
+else
+  if test "$have_qhull" = bad; then
+    warn_qhull="Qhull library found, but seems not to work properly --- This will result in loss of functionality of some geometry functions. Please try recompiling the library with -fno-strict-aliasing."
+  else
+    warn_qhull="Qhull library not found --- This will result in loss of functionality of some geometry functions."
+  fi
+  AC_MSG_WARN($warn_qhull)
+fi
+
+AC_SUBST(TEXINFO_QHULL)
+
+### Check for pcre/regex library.
+
+## check for pcre-config, and if so, set CPPFLAGS appropriately
+AC_CHECK_PROG(WITH_PCRE_CONFIG, pcre-config, yes, no)
+if test $WITH_PCRE_CONFIG = yes ; then
+  CPPFLAGS="$CPPFLAGS $(pcre-config --cflags)"
+fi
+
+## NB: no need to do separate check for pcre.h header -- checking macros is good enough
+AC_CACHE_CHECK([whether pcre.h defines the macros we need], [ac_cv_pcre_h_macros_present], [
+  AC_EGREP_CPP([PCRE_HAS_MACROS_WE_NEED], [
+#include <pcre.h>
+#if defined (PCRE_INFO_NAMECOUNT) \
+  && defined (PCRE_INFO_NAMEENTRYSIZE) \
+  && defined (PCRE_INFO_NAMETABLE)
+PCRE_HAS_MACROS_WE_NEED
+#endif], ac_cv_pcre_h_macros_present=yes, ac_cv_pcre_h_macros_present=no)])
+WITH_PCRE="$ac_cv_pcre_h_macros_present"
+
+REGEX_LIBS=
+
+using_pcre=no
+using_regex=no
+
+if test "$WITH_PCRE" = yes; then
+  if test "$WITH_PCRE_CONFIG" = yes; then
+    REGEX_LIBS=$(pcre-config --libs)
+  else
+    REGEX_LIBS=-lpcre
+  fi
+  save_LIBS="$LIBS"
+  LIBS="$REGEX_LIBS $LIBS"
+  AC_CHECK_FUNCS(pcre_compile, [using_pcre=yes
+    AC_DEFINE(HAVE_PCRE, 1, [Define if PCRE library is available.])], [
+      REGEX_LIBS=
+      warn_pcre="PCRE library not found.  This will result in some loss of functionality for the regular expression matching functions."
+      AC_MSG_WARN($warn_pcre)])
+  LIBS="$save_LIBS"
+else
+  warn_pcre="PCRE library not found.  This will result in some loss of functionality for the regular expression matching functions."
+  AC_MSG_WARN($warn_pcre)
+fi
+
+AC_CHECK_FUNCS(regexec, [using_regex=yes], [
+  AC_CHECK_LIB(regex, regexec, [using_regex=yes
+    REGEX_LIBS="-lregex $REGEX_LIBS"], [
+      warn_regex="regular expression functions not found.  The regular expression matching functions will be disabled."
+      AC_MSG_WARN($warn_regex)])])
+
+if test "$using_regex" = yes; then
+  AC_DEFINE(HAVE_REGEX, 1, [Define if regex library is available.])
+fi
+
+AC_SUBST(REGEX_LIBS)
+
+### Check for ZLIB library.
+
+WITH_ZLIB=true
+AC_ARG_WITH(zlib,
+  [AS_HELP_STRING([--without-zlib], [don't use zlib])],
+  with_zlib=$withval, with_zlib=yes)
+
+zlib_lib=
+if test "$with_zlib" = yes; then
+  zlib_lib="z"
+elif test "$with_zlib" != no; then
+  zlib_lib="$with_zlib"
+fi
+
+ZLIB_LIBS=
+WITH_ZLIB=false
+if test -n "$zlib_lib"; then
+  AC_CHECK_LIB($zlib_lib, gzclearerr, [
+      AC_CHECK_HEADERS(zlib.h, [
+	WITH_ZLIB=true
+        ZLIB_LIBS="-l$zlib_lib"
+        LIBS="$ZLIB_LIBS $LIBS"
+        AC_DEFINE(HAVE_ZLIB, 1, [Define if ZLIB is available.])])])
+fi
+
+if $WITH_ZLIB; then
+  ### Check for HDF5 library.
+
+  WITH_HDF5=true
+  AC_ARG_WITH(hdf5,
+    [AS_HELP_STRING([--without-hdf5], [don't use HDF5])],
+    with_hdf5=$withval, with_hdf5=yes)
+
+  hdf5_lib=
+  if test "$with_hdf5" = yes; then
+    hdf5_lib="hdf5"
+  elif test "$with_hdf5" != no; then
+    hdf5_lib="$with_hdf5"
+  fi
+
+  HDF5_LIBS=
+  WITH_HDF5=false
+  if test -n "$hdf5_lib"; then
+    AC_CHECK_LIB($hdf5_lib, H5Pcreate, [
+      AC_CHECK_HEADERS(hdf5.h, [
+        WITH_HDF5=true
+        HDF5_LIBS="-l$hdf5_lib"
+        LIBS="$HDF5_LIBS $LIBS"
+	AC_CHECK_LIB($hdf5_lib, H5Gget_num_objs, [
+          OCTAVE_HDF5_HAS_REQUIRED_API
+          if test $WITH_HDF5; then
+            AC_DEFINE(HAVE_HDF5, 1, [Define if HDF5 is available.])
+	    AC_DEFINE(HAVE_H5GGET_NUM_OBJS, 1, [Define if HDF5 has H5Gget_num_objs.])
+	  fi])])])
+  fi
+
+  if $WITH_HDF5; then
+    case "$canonical_host_type" in
+      *-*-msdosmsvc)
+        OCTAVE_HDF5_DLL
+        ;;
+    esac
+    true
+  fi
+else
+  warn_zlib="ZLIB library not found.  Octave will not be able to save or load compressed data files or HDF5 files."
+  AC_MSG_WARN($warn_zlib)
+fi
+
+
+# Checks for FFTW header and library.
+
+# subdirectories of libcruft to build if they aren't found on the system:
+FFT_DIR="fftpack"
+AC_SUBST(FFT_DIR)
+
+# Installed fftw library, if any.
+FFTW_LIBS=''
+AC_SUBST(FFTW_LIBS)
+
+AC_ARG_WITH(fftw, 
+  [AS_HELP_STRING([--without-fftw],
+     [use included fftpack instead of installed fftw])],
+  with_fftw=$withval, with_fftw=yes)
+
+if test "$with_fftw" = yes; then
+  have_fftw3_header=no
+  with_fftw3=no
+  AC_CHECK_HEADER(fftw3.h, [have_fftw3_header=yes])
+  if test "$have_fftw3_header" = yes; then
+    AC_CHECK_LIB(fftw3, fftw_plan_dft_1d, [
+      AC_CHECK_LIB(fftw3f, fftwf_plan_dft_1d, [FFTW_LIBS="-lfftw3 -lfftw3f"; with_fftw3=yes])])
+  fi
+fi
+
+if test "$with_fftw" = yes && test "$with_fftw3" = yes; then
+  FFT_DIR=''
+  AC_DEFINE(HAVE_FFTW3, 1, [Define if the FFTW3 library is used.])
+else
+  warn_fftw="FFTW library not found.  Octave will use the (slower) FFTPACK library instead."
+  AC_MSG_RESULT($warn_fftw)
+fi
+
+# Checks for GLPK header and library.
+
+AC_ARG_WITH(glpk,
+  [AS_HELP_STRING([--without-glpk], [don't use GLPK])],
+  with_glpk=$withval, with_glpk=yes)
+
+glpk_lib=
+if test "$with_glpk" = yes; then
+  glpk_lib="glpk"
+elif test "$with_glpk" != no; then
+  glpk_lib="$with_glpk"
+fi
+
+GLPK_LIBS=
+if test -n "$glpk_lib"; then
+  AC_CHECK_HEADERS([glpk/glpk.h glpk.h], [
+    AC_CHECK_LIB($glpk_lib, glp_lpx_simplex, [
+      GLPK_LIBS="-l$glpk_lib"
+      AC_DEFINE(GLPK_PRE_4_14, 1, [Define if GLPK version is less than 4.14.])], [
+        AC_CHECK_LIB($glpk_lib, _glp_lpx_simplex, [
+          GLPK_LIBS="-l$glpk_lib"], [])])
+
+    if test -n "$GLPK_LIBS"; then
+      AC_DEFINE(HAVE_GLPK, 1, [Define if GLPK is available.])
+    fi
+    break])
+fi
+AC_SUBST(GLPK_LIBS)
+if test -z "$GLPK_LIBS"; then
+  warn_glpk="GLPK library not found.  The glpk function for solving linear programs will be disabled."
+fi
+
+# Checks for CURL header and library.
+
+AC_ARG_WITH(curl,
+  [AS_HELP_STRING([--without-curl], [don't use CURL])],
+  with_curl=$withval, with_curl=yes)
+
+curl_lib=
+if test "$with_curl" = yes; then
+  curl_lib="curl"
+elif test "$with_curl" != no; then
+  curl_lib="$with_curl"
+else
+  curl_missing=yes
+fi
+
+CURL_LIBS=
+if test -n "$curl_lib"; then
+  AC_CHECK_LIB($curl_lib, curl_easy_escape, [
+    AC_CHECK_HEADERS(curl/curl.h, [
+      CURL_LIBS="-l$curl_lib"
+      AC_DEFINE(HAVE_CURL, 1, [Define if CURL is available.])], [
+      curl_missing=yes])])
+fi
+AC_SUBST(CURL_LIBS)
+if test "$curl_missing" = yes; then
+  warn_curl="cURL library not found.  The urlread and urlwrite functions will be disabled."
+fi
+
+# GraphicsMagick++
+
+warn_magick=
+AC_CHECK_PROGS(MAGICK_CONFIG, [GraphicsMagick++-config GraphicsMagick-config])
+if test -z "$MAGICK_CONFIG"; then
+  warn_magick="GraphicsMagick++ config script not found.  Assuming GraphicsMagic++ library and header files are missing, so imread will not be fully functional"
+else
+  AC_DEFINE(HAVE_MAGICK, 1, [Define if GraphicsMagick++ is available.])
+fi
+
+# ---------------------------------------------------------------------
+
+## libraries needed for graphics
+
+warn_freetype=""
+warn_ftgl=""
+
+OCTAVE_OPENGL
+if test -n "$OPENGL_LIBS"; then
+  AC_DEFINE(HAVE_OPENGL, 1, [Define if OpenGL is available])
+
+## ftgl (needs freetype 2)
+  AC_CHECK_FT2([9.0.3],[],
+    [warn_freetype="FreeType library not found. Native renderer will not have on-screen text"])
+  if test -z "$warn_freetype"; then
+    AC_LANG_PUSH(C++)
+      save_LIBS="$LIBS"
+      save_CXXFLAGS="$CXXFLAGS"
+      save_CPPFLAGS="$CPPFLAGS"
+      LIBS="$LIBS $FT2_LIBS $OPENGL_LIBS"
+      CXXFLAGS="$CXXFLAGS $FT2_CFLAGS"
+      CPPFLAGS="$CPPFLAGS $FT2_CFLAGS"
+      has_ftgl_h=yes
+      AC_CHECK_HEADERS([FTGL/ftgl.h ftgl.h], break, [
+	AC_CHECK_HEADERS([FTGL/FTGL.h FTGL.h], [
+          AC_DEFINE(HAVE_FTGL_UPPERCASE, 1, [Define to 1 if you have FTGL.h or FTGL/FTGL.h])
+	  break
+	  ], has_ftgl_h=no)])
+      if test "$has_ftgl_h" = yes; then
+	AC_MSG_CHECKING([for FTGLTextureFont in -lftgl])
+	LIBS="$save_LIBS -lftgl $FT2_LIBS $OPENGL_LIBS"
+        AC_TRY_LINK([
+#ifdef HAVE_FTGL_FTGL_H
+#ifdef HAVE_FTGL_UPPERCASE
+#include <FTGL/FTGL.h>
+#else
+#include <FTGL/ftgl.h>
+#endif
+#include <FTGL/FTGLTextureFont.h>
+#elif HAVE_FTGL_H
+#ifdef HAVE_FTGL_UPPERCASE
+#include <FTGL.h>
+#else
+#include <ftgl.h>
+#endif
+#include <FTGLTextureFont.h>
+#endif], [
+FTGLTextureFont font("");], [
+          OPENGL_LIBS="-lftgl $FT2_LIBS $OPENGL_LIBS"
+	  LIBS="$save_LIBS"
+	  CPPFLAGS="$save_CPPFLAGS"
+          AC_DEFINE(HAVE_FTGL, 1, [Define to 1 if FTGL is present])
+	  AC_MSG_RESULT(yes)
+	  XTRA_CXXFLAGS="$XTRA_CXXFLAGS $FT2_CFLAGS"], [
+	  AC_MSG_RESULT(no)
+          warn_ftgl="FTGL library not found. Native renderer will not have on-screen text"
+        ])
+	LIBS="$save_LIBS"
+	CXXFLAGS="$save_CXXFLAGS"
+	CPPFLAGS="$save_CPPFLAGS"
+      else
+        warn_ftgl="FTGL headers not found. Native renderer will not have on-screen text"
+      fi
+    AC_LANG_POP(C++)
+  fi
+fi
+
+GRAPHICS_LIBS=
+GRAPHICS_CFLAGS=
+
+## fltk (www.fltk.org)
+AC_ARG_WITH(fltk-prefix,
+        [  --with-fltk-prefix=PFX   Prefix where FLTK is installed (optional)],
+        fltk_prefix="$withval",
+        fltk_prefix="")
+AC_ARG_WITH(fltk-exec-prefix,
+        [  --with-fltk-exec-prefix=PFX Exec prefix where FLTK is installed (optional)],
+        fltk_exec_prefix="$withval", 
+        fltk_exec_prefix="")
+
+if test -n "$fltk_exec_prefix"; then
+  fltk_args="$fltk_args --exec-prefix=$fltk_exec_prefix"
+  if test "x${FLTK_CONFIG+set}" != xset ; then
+    FLTK_CONFIG="$fltk_exec_prefix/bin/fltk-config"
+  fi
+fi
+
+if test -n "$fltk_prefix"; then
+  fltk_args="$fltk_args --prefix=$fltk_prefix"
+  if test x${FLTK_CONFIG+set} != xset ; then
+    FLTK_CONFIG="$fltk_prefix/bin/fltk-config"
+  fi
+fi
+
+AC_PATH_PROG(FLTK_CONFIG, fltk-config, no)
+
+warn_fltk_config=""
+warn_fltk_opengl=""
+
+if test "$FLTK_CONFIG" = "no" ; then
+  warn_fltk_config="FLTK config script not found.  Native graphics will be disabled."
+else
+  FLTK_CFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --cflags`"
+  FLTK_LDFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags`"
+  
+  AC_MSG_CHECKING(for OpenGL support in FLTK)
+  cat > conftest.cc <<EOF
+  #include <FL/gl.h>
+  int nothing=0;
+EOF
+  $CXX $CXXFLAGS $FLTK_CFLAGS -c conftest.cc || \
+    warn_fltk_opengl="FLTK does not have OpenGL support.  Native graphics will be disabled."
+
+  if test -z "$warn_fltk_opengl"; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_FLTK, 1, [Define if FLTK is available])
+    GRAPHICS_CFLAGS="$FLTK_CFLAGS"
+    GRAPHICS_LIBS="$FLTK_LDFLAGS"
+  else
+    AC_MSG_RESULT(no)
+  fi
+fi
+
+AC_SUBST(GRAPHICS_CFLAGS)
+AC_SUBST(GRAPHICS_LIBS)
+
+OCTAVE_IEEE754_DATA_FORMAT
+
+# ----------------------------------------------------------------------
+
+OCTAVE_PROG_AR
+
+AC_PROG_RANLIB
+
+## Default FFLAGS is -O.
+if test "x$FFLAGS" = x; then
+  FFLAGS="-O"
+fi
+
+## the F77 variable, if set, overrides AC_PROG_F77 automatically
+AC_PROG_F77
+AC_F77_LIBRARY_LDFLAGS
+AC_F77_DUMMY_MAIN
+AC_F77_WRAPPERS
+
+F77_TOLOWER=true
+F77_APPEND_UNDERSCORE=true
+F77_APPEND_EXTRA_UNDERSCORE=true
+
+case "$ac_cv_f77_mangling" in
+  "upper case") F77_TOLOWER=false ;;
+esac
+case "$ac_cv_f77_mangling" in
+  "no underscore") F77_APPEND_UNDERSCORE=false ;;
+esac
+case "$ac_cv_f77_mangling" in
+  "no extra underscore") F77_APPEND_EXTRA_UNDERSCORE=false ;;
+esac
+
+case "$canonical_host_type" in
+  i[[3456789]]86-*-*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      OCTAVE_F77_FLAG(-mieee-fp)
+###      OCTAVE_F77_FLAG(-ffloat-store)
+    fi
+  ;;
+  alpha*-*-*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      OCTAVE_F77_FLAG(-mieee)
+    else
+      OCTAVE_F77_FLAG(-ieee)
+      OCTAVE_F77_FLAG(-fpe1)
+    fi
+  ;;
+  powerpc-apple-machten*)
+    FFLAGS=
+  ;;
+esac
+
+if test -n "$FFLAGS"; then
+  AC_MSG_NOTICE([defining FFLAGS to be $FFLAGS])
+fi
+
+AC_SUBST(F77_TOLOWER)
+AC_SUBST(F77_APPEND_UNDERSCORE)
+AC_SUBST(F77_APPEND_EXTRA_UNDERSCORE)
+
+if test -z "$F77"; then
+  AC_MSG_WARN([in order to build octave, you must have a compatible])
+  AC_MSG_WARN([Fortran compiler or wrapper script for f2c that functions])
+  AC_MSG_WARN([as a Fortran compiler installed and in your path.])
+  AC_MSG_ERROR([See the file INSTALL for more information.])
+fi
+
+XTRA_CRUFT_SH_LDFLAGS=
+case "$canonical_host_type" in
+  *-*-msdosmsvc)
+    FLIBS="$FLIBS -lkernel32"
+    XTRA_CRUFT_SH_LDFLAGS="-Wl,-def:cruft.def"
+  ;;
+esac
+AC_SUBST(XTRA_CRUFT_SH_LDFLAGS)
+
+FC=$F77
+AC_SUBST(FC)
+
+OCTAVE_F77_FLAG(-ffloat-store, [
+AC_MSG_RESULT([setting F77_FLOAT_STORE_FLAG to -ffloat-store])
+F77_FLOAT_STORE_FLAG=-ffloat-store
+AC_SUBST(F77_FLOAT_STORE_FLAG)
+])
+
+### Checks for BLAS and LAPACK libraries:
+# (Build subdirectories of libcruft if they aren't found on the system.)
+sinclude(acx_blas.m4)
+sinclude(acx_blas_f77_func.m4)
+sinclude(acx_lapack.m4)
+ACX_BLAS_WITH_F77_FUNC([], [BLAS_DIR="blas"])
+ACX_LAPACK([BLAS_LIBS="$LAPACK_LIBS $BLAS_LIBS"], [LAPACK_DIR="lapack"])
+AC_SUBST(BLAS_DIR)
+AC_SUBST(LAPACK_DIR)
+
+if test "x$acx_blas_f77_func_ok" = "xno"; then
+  warn_blas_f77_incompatible="A BLAS library was detected but found incompatible with your Fortran 77 compiler.  The reference BLAS implementation will be used. To improve performance, consider using a different Fortran compiler or a switch like -ff2c to make your Fortran compiler use a calling convention compatible with the way your BLAS library was compiled, or use a different BLAS library."
+  AC_MSG_WARN($warn_blas_f77_incompatible)
+fi
+
+QRUPDATE_LIBS=
+AC_SUBST(QRUPDATE_LIBS)
+
+# Check for the qrupdate library
+AC_ARG_WITH(qrupdate,
+  [AS_HELP_STRING([--without-qrupdate],
+     [don't use qrupdate, disable QR & Cholesky updating functions])],
+  with_qrupdate=$withval, with_qrupdate=yes)
+
+warn_qrupdate="qrupdate not found. The QR & Cholesky updating functions will be slow."
+if test "$with_qrupdate" = yes; then
+  with_qrupdate=no
+  if $have_fortran_compiler; then 
+    AC_F77_FUNC(sqr1up)
+  elif $have_f2c; then
+    sqr1up=sqr1up_
+  fi
+  AC_CHECK_LIB(qrupdate, $sqr1up, 
+    [QRUPDATE_LIBS="-lqrupdate"; with_qrupdate=yes], [], [$BLAS_LIBS $FLIBS])
+  if test "$with_qrupdate" = yes; then
+    AC_DEFINE(HAVE_QRUPDATE, 1, [Define if the qrupdate library is used.])
+    warn_qrupdate=
+  fi
+fi
+if test -n "$warn_qrupdate"; then
+  AC_MSG_WARN($warn_qrupdate)
+fi
+
+# Check for AMD library
+AMD_LIBS=
+AC_SUBST(AMD_LIBS)
+
+AC_ARG_WITH(amd,
+  [AS_HELP_STRING([--without-amd],
+     [don't use AMD, disable some sparse functionality])],
+  with_amd=$withval, with_amd=yes)
+
+warn_amd="AMD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_amd" = yes; then
+  with_amd=no
+  AC_CHECK_HEADERS([suitesparse/amd.h ufsparse/amd.h amd/amd.h amd.h], [
+    AC_CHECK_LIB(amd, amd_postorder, [AMD_LIBS="-lamd"; with_amd=yes])
+    if test "$with_amd" = yes; then
+      AC_DEFINE(HAVE_AMD, 1, [Define if the AMD library is used.])
+      warn_amd=
+    fi
+    break])
+fi 
+if test -n "$warn_amd"; then
+  AC_MSG_WARN($warn_amd)
+fi
+
+# Check for CAMD library
+CAMD_LIBS=
+AC_SUBST(CAMD_LIBS)
+AC_CHECK_LIB(camd, camd_postorder, [CAMD_LIBS="-lcamd"; with_camd=yes],[with_camd=no])
+
+# Check for UMFPACK library.
+
+UMFPACK_LIBS=
+AC_SUBST(UMFPACK_LIBS)
+
+AC_ARG_WITH(umfpack,
+  [AS_HELP_STRING([--without-umfpack],
+     [don't use UMFPACK, disable some sparse functionality])],
+  with_umfpack=$withval, with_umfpack=yes)
+
+warn_umfpack="UMFPACK not found.  This will result in some lack of functionality for sparse matrices."
+if test "$with_umfpack" = yes && test "$with_amd" = yes; then
+  with_umfpack=no
+  AC_CHECK_HEADERS([suitesparse/umfpack.h ufsparse/umfpack.h umfpack/umfpack.h umfpack.h], [
+    AC_CHECK_LIB(umfpack, umfpack_zi_get_determinant, [
+      UMFPACK_LIBS="-lumfpack"; with_umfpack=yes], [
+        ## Invalidate the cache.
+	$as_unset ac_cv_lib_umfpack_umfpack_zi_get_determinant
+	AC_CHECK_LIB(umfpack, umfpack_zi_get_determinant, [
+          UMFPACK_LIBS="-lumfpack"; with_umfpack=yes], [
+
+	  ## Invalidate the cache.
+	  $as_unset ac_cv_lib_umfpack_umfpack_zi_get_determinant
+	  AC_CHECK_LIB(umfpack, umfpack_zi_get_determinant, [
+            UMFPACK_LIBS="-lumfpack -lcblas"; with_umfpack=yes], [], $AMD_LIBS -lcblas $BLAS_LIBS)], $AMD_LIBS $BLAS_LIBS $FLIBS)], $AMD_LIBS)
+
+    if test "$with_umfpack" = yes; then
+      AC_DEFINE(HAVE_UMFPACK, 1, [Define if the UMFPACK library is used.])
+      OLD_LIBS=$LIBS
+      LIBS="$LIBS $UMFPACK_LIBS $AMD_LIBS $BLAS_LIBS $FLIBS"
+      OCTAVE_UMFPACK_SEPERATE_SPLIT
+      LIBS=$OLD_LIBS
+      TEXINFO_UMFPACK="@set HAVE_UMFPACK"
+      warn_umfpack=
+    fi
+    break])
+fi
+if test -n "$warn_umfpack"; then
+  AC_MSG_WARN($warn_umfpack)
+fi
+
+AC_SUBST(TEXINFO_UMFPACK)
+
+COLAMD_LIBS=
+AC_SUBST(COLAMD_LIBS)
+
+AC_ARG_WITH(colamd,
+  [AS_HELP_STRING([--without-colamd],
+     [don't use COLAMD, disable some sparse functionality])],
+  with_colamd=$withval, with_colamd=yes)
+
+warn_colamd="COLAMD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_colamd" = yes; then
+  with_colamd=no
+  AC_CHECK_HEADERS([suitesparse/colamd.h ufsparse/colamd.h colamd/colamd.h colamd.h], [
+    AC_CHECK_LIB(colamd, colamd, [COLAMD_LIBS="-lcolamd"; with_colamd=yes])
+    if test "$with_colamd" = yes; then
+      AC_DEFINE(HAVE_COLAMD, 1, [Define if the COLAMD library is used.])
+      TEXINFO_COLAMD="@set HAVE_COLAMD"
+      warn_colamd=
+    fi
+    break])
+fi 
+if test -n "$warn_colamd"; then
+  AC_MSG_WARN($warn_colamd)
+fi
+
+AC_SUBST(TEXINFO_COLAMD)
+
+CCOLAMD_LIBS=
+AC_SUBST(CCOLAMD_LIBS)
+
+AC_ARG_WITH(ccolamd,
+  [AS_HELP_STRING([--without-ccolamd],
+     [don't use CCOLAMD, disable some sparse functionality])],
+  with_ccolamd=$withval, with_ccolamd=yes)
+
+warn_ccolamd="CCOLAMD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_ccolamd" = yes; then
+  with_ccolamd=no
+  AC_CHECK_HEADERS([suitesparse/ccolamd.h ufsparse/ccolamd.h ccolamd/ccolamd.h ccolamd.h], [
+    AC_CHECK_LIB(ccolamd, ccolamd, [CCOLAMD_LIBS="-lccolamd"; with_ccolamd=yes])
+    if test "$with_ccolamd" = yes; then
+      AC_DEFINE(HAVE_CCOLAMD, 1, [Define if the CCOLAMD library is used.])
+      warn_ccolamd=
+    fi
+    break])
+fi 
+if test -n "$warn_ccolamd"; then
+  AC_MSG_WARN($warn_ccolamd)
+fi
+
+CHOLMOD_LIBS=
+AC_SUBST(CHOLMOD_LIBS)
+
+AC_ARG_WITH(cholmod,
+  [AS_HELP_STRING([--without-cholmod],
+     [don't use CHOLMOD, disable some sparse functionality])],
+  with_cholmod=$withval, with_cholmod=yes)
+
+warn_cholmod="CHOLMOD not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_cholmod" = yes && test "$with_colamd" = yes &&
+	test "$with_ccolamd" = yes && test "$with_amd" = yes; then
+  with_cholmod=no
+  AC_CHECK_HEADERS([suitesparse/cholmod.h ufsparse/cholmod.h cholmod/cholmod.h cholmod.h], [
+    AC_CHECK_LIB(cholmod, cholmod_start, [CHOLMOD_LIBS="-lcholmod"; 
+      with_cholmod=yes], [
+      AC_CHECK_LIB(cholmod, cholmod_start, [CHOLMOD_LIBS="-lcholmod -cblas"; 
+	with_cholmod=yes], [],
+	$CAMD_LIBS $AMD_LIBS $COLAMD_LIBS $CCOLAMD_LIBS $BLAS_LIBS $FLIBS)],
+      $CAMD_LIBS $AMD_LIBS $COLAMD_LIBS $CCOLAMD_LIBS $BLAS_LIBS $FLIBS)
+
+    if test "$with_cholmod" = yes; then
+      AC_DEFINE(HAVE_CHOLMOD, 1, [Define if the CHOLMOD library is used.])
+      TEXINFO_CHOLMOD="@set HAVE_CHOLMOD"
+      warn_cholmod=
+    fi
+    break])
+fi
+if test -n "$warn_cholmod"; then
+  AC_MSG_WARN($warn_cholmod)
+fi
+
+AC_SUBST(TEXINFO_CHOLMOD)
+
+CXSPARSE_LIBS=
+AC_SUBST(CXSPARSE_LIBS)
+
+AC_ARG_WITH(cxsparse,
+  [AS_HELP_STRING([--without-cxsparse],
+     [don't use CXSparse, disable some sparse functionality])],
+  with_cxsparse=$withval, with_cxsparse=yes)
+
+warn_cxsparse="CXSparse not found. This will result in some lack of functionality for sparse matrices."
+if test "$with_cxsparse" = yes; then
+  with_cxsparse=no
+  AC_LANG_PUSH(C++)
+  AC_CHECK_HEADERS([suitesparse/cs.h ufsparse/cs.h cxsparse/cs.h cs.h], [
+    AC_CHECK_LIB(cxsparse, cs_di_sqr, [CXSPARSE_LIBS="-lcxsparse"; with_cxsparse=yes])
+    if test "$with_cxsparse" = yes; then
+      AC_DEFINE(HAVE_CXSPARSE, 1, [Define if the CXSparse library is used.])
+      warn_cxsparse=
+    fi
+    break])
+  AC_LANG_POP(C++)
+fi
+if test -n "$warn_cxsparse"; then
+  AC_MSG_WARN($warn_cxsparse)
+fi
+
+ARPACK_LIBS=
+AC_SUBST(ARPACK_LIBS)
+
+AC_ARG_WITH(arpack,
+  [AS_HELP_STRING([--without-arpack],
+     [don't use ARPACK, disable some sparse functionality])],
+  with_arpack=$withval, with_arpack=yes)
+
+warn_arpack="arpack not found. This will result in a lack of the eigs function."
+if test "$with_arpack" = yes; then
+  with_arpack=no
+  AC_CHECK_LIB(arpack, F77_FUNC(dseupd,DSEUPD), [ARPACK_LIBS="-larpack"; with_arpack=yes], , $LAPACK_LIBS $FLIBS)
+  if test "$with_arpack" = yes; then
+    AC_DEFINE(HAVE_ARPACK, 1, [Define if the ARPACK library is used.])
+    warn_arpack=
+  fi
+fi
+if test -n "$warn_arpack"; then
+  AC_MSG_WARN($warn_arpack)
+fi
+
+### Handle shared library options.
+
+### Enable creation of static libraries.
+
+AC_ARG_ENABLE(static,
+  [AS_HELP_STRING([--enable-static], [create static libraries])],
+  [if test "$enableval" = no; then STATIC_LIBS=false;
+   else STATIC_LIBS=true; fi],
+  STATIC_LIBS=false)
+AC_SUBST(STATIC_LIBS)
+
+### Enable creation of shared libraries.  Currently only works with
+### gcc on some systems.
+
+AC_ARG_ENABLE(shared,
+  [AS_HELP_STRING([--enable-shared],
+     [create shared libraries (not all systems)])],
+  [if test "$enableval" = no; then SHARED_LIBS=false;
+   else SHARED_LIBS=true; fi],
+  SHARED_LIBS=true)
+AC_SUBST(SHARED_LIBS)
+
+### Enable dynamic linking.  --enable-shared implies this, so
+### --enable-dl is only need if you are only building static libraries
+### and want to try dynamic linking too (works on some systems, for
+### example, OS X and Windows).
+
+AC_ARG_ENABLE(dl,
+  [AS_HELP_STRING([--enable-dl],
+     [create shared libraries (not all systems)])],
+  [if test "$enableval" = no; then ENABLE_DYNAMIC_LINKING=false;
+   else ENABLE_DYNAMIC_LINKING=true; fi],
+  ENABLE_DYNAMIC_LINKING=true)
+
+if $STATIC_LIBS || $SHARED_LIBS; then
+  true
+else
+  AC_MSG_ERROR([You can't disable building static AND shared libraries!])
+fi
+
+AC_ARG_ENABLE(rpath,
+  [AS_HELP_STRING([--enable-rpath],
+     [override the default link options for rpath; e.g., --enable-rpath='-rpath $(octlibdir)'])],
+  [ if test "$enableval" = no; then use_rpath=false;
+    else
+      use_rpath=true
+      if test "$enableval" = yes; then true;
+      else enable_rpath_arg="$enableval"; fi
+    fi], [use_rpath=true])
+
+CPICFLAG=-fPIC
+CXXPICFLAG=-fPIC
+FPICFLAG=-fPIC
+SHLEXT=so
+SHLLIB='$(SHLEXT)'
+SHLBIN=
+SHLEXT_VER='$(SHLEXT).$(version)'
+SHLLIB_VER='$(SHLLIB).$(version)'
+SHLBIN_VER='$(SHLBIN).$(version)'
+SHLLINKEXT=
+LIBPRE=lib
+SHLPRE=lib
+SHLLIBPRE=lib
+SHLBINPRE=lib
+SH_LD='$(CXX)'
+SH_LDFLAGS=-shared
+DL_LD='$(SH_LD)'
+DL_LDFLAGS='$(SH_LDFLAGS)'
+MKOCTFILE_DL_LDFLAGS='$(DL_LDFLAGS)'
+SONAME_FLAGS=
+RLD_FLAG=
+NO_OCT_FILE_STRIP=false
+TEMPLATE_AR='$(AR)'
+TEMPLATE_ARFLAGS="$ARFLAGS"
+CRUFT_DLL_DEFS=
+OCTAVE_DLL_DEFS=
+OCTINTERP_DLL_DEFS=
+OCTGRAPHICS_DLL_DEFS=
+library_path_var=LD_LIBRARY_PATH
+SCRIPTS_EXE_SUFFIX=
+case "$canonical_host_type" in
+  *-*-386bsd* | *-*-netbsd*)
+    SH_LD=ld
+    SH_LDFLAGS=-Bshareable
+  ;;
+  *-*-openbsd*)
+    SH_LDFLAGS='-shared -fPIC'
+  ;;
+  *-*-freebsd*)
+    SH_LDFLAGS="-shared -Wl,-x"
+    RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)'
+  ;;
+  alpha*-dec-osf*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    SH_LDFLAGS="-shared -Wl,-expect_unresolved -Wl,'*'"
+    RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)'
+  ;;
+  *-*-darwin*)
+    DL_LDFLAGS='-bundle -bundle_loader $(TOPDIR)/src/octave $(LDFLAGS)'
+    MKOCTFILE_DL_LDFLAGS='-bundle -bundle_loader $$BINDIR/octave-$$OCTAVE_VERSION$$EXEEXT'
+    SH_LDFLAGS='-dynamiclib -single_module $(LDFLAGS)'
+    case "$canonical_host_type" in
+      powerpc-*)
+        CXXPICFLAG=
+        CPICFLAG=
+        FPICFLAG=
+      ;;
+    esac
+    SHLEXT=dylib 
+    SHLLIB='$(SHLEXT)'
+    SHLEXT_VER='$(version).$(SHLEXT)'
+    SHLLIB_VER='$(version).$(SHLLIB)'
+    NO_OCT_FILE_STRIP=true
+    SONAME_FLAGS='-install_name $(octlibdir)/$@'
+    library_path_var=DYLD_LIBRARY_PATH	
+  ;;
+  *-*-cygwin*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    LIBPRE=lib
+    SHLPRE=cyg
+    SHLBINPRE=cyg
+    SHLEXT=dll
+    SHLLIB=dll.a
+    SHLBIN=dll    
+    DL_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc"
+    SH_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-auto-image-base"
+    SONAME_FLAGS='-Wl,--out-implib=$(patsubst $(SHLPRE)%,$(LIBPRE)%,$@).a'
+  ;;
+  *-*-mingw*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    SHLEXT=dll
+    SHLLIB=dll.a
+    SHLBIN=dll
+    DL_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc"
+    SH_LDFLAGS="-shared -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--enable-auto-image-base"
+    SONAME_FLAGS='-Wl,--out-implib=$@.a'
+    library_path_var=PATH
+    SCRIPTS_EXE_SUFFIX='$(EXEEXT)'
+  ;;
+
+  *-*-msdosmsvc)
+    DL_LDFLAGS="-shared"
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    SHLEXT=dll
+    SHLLIB=lib
+    SHLBIN=dll
+    LIBPRE=
+    SHLPRE=
+    SHLLIBPRE=
+    SHLBINPRE=
+    SH_LDFLAGS="-shared"
+      if test -n "`echo $CFLAGS | grep -e '-g'`" -o -n "`echo $CXXFLAGS | grep -e '-g'`"; then
+      DL_LDFLAGS="$DL_LDFLAGS -g"
+      SH_LDFLAGS="$SH_LDFLAGS -g"
+    fi
+    NO_OCT_FILE_STRIP=true
+    library_path_var=PATH
+    NO_OCT_FILE_STRIP=true
+    ## Extra compilation flags.
+    CRUFT_DLL_DEFS="-DCRUFT_DLL"
+    OCTAVE_DLL_DEFS="-DOCTAVE_DLL"
+    OCTINTERP_DLL_DEFS="-DOCTINTERP_DLL"
+    OCTGRAPHICS_DLL_DEFS="-DOCTGRAPHICS_DLL"
+    SCRIPTS_EXE_SUFFIX='$(EXEEXT)'
+  ;;
+  *-*-linux* | *-*-gnu*)
+    MKOCTFILE_DL_LDFLAGS="-shared -Wl,-Bsymbolic"
+    SONAME_FLAGS='-Wl,-soname -Wl,$@'
+    RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)'
+  ;;
+  i[[3456]]86-*-sco3.2v5*)
+    SONAME_FLAGS='-Wl,-h -Wl,$@'
+    RLD_FLAG=
+    SH_LDFLAGS=-G
+  ;;
+  rs6000-ibm-aix* | powerpc-ibm-aix*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    library_path_var=LIBPATH
+  ;;
+  hppa*-hp-hpux*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=+Z
+    fi
+    SHLEXT=sl
+    SH_LDFLAGS="-shared -fPIC"
+    RLD_FLAG='-Wl,+b -Wl,$(octlibdir)'
+    library_path_var=SHLIB_PATH
+  ;;
+  ia64*-hp-hpux*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=+Z
+    fi
+    SH_LDFLAGS="-shared -fPIC"
+    RLD_FLAG='-Wl,+b -Wl,$(octlibdir)'
+  ;;
+  *-sgi-*)
+    CPICFLAG=
+    CXXPICFLAG=
+    FPICFLAG=
+    RLD_FLAG='-rpath $(octlibdir)'
+  ;;
+  sparc-sun-sunos4*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=-PIC
+    fi
+    SH_LD=ld
+    SH_LDFLAGS="-assert nodefinitions"
+    RLD_FLAG='-L$(octlibdir)'
+  ;;
+  sparc-sun-solaris2* | i386-pc-solaris2*)
+    if test "$ac_cv_f77_compiler_gnu" = yes; then
+      FPICFLAG=-fPIC
+    else
+      FPICFLAG=-KPIC
+    fi
+    if test "$GCC" = yes; then
+      CPICFLAG=-fPIC
+    else
+      CPICFLAG=-KPIC
+    fi
+    if test "$GXX" = yes; then
+      CXXPICFLAG=-fPIC
+      SH_LDFLAGS=-shared
+    else
+      CXXPICFLAG=-KPIC
+      SH_LDFLAGS=-G
+    fi
+    RLD_FLAG='-R $(octlibdir)'
+    ## Template closures in archive libraries need a different mechanism.
+    if test "$GXX" = yes; then
+      true
+    else
+      TEMPLATE_AR='$(CXX)'
+      TEMPLATE_ARFLAGS="-xar -o"
+    fi
+  ;;
+esac
+
+if $use_rpath; then
+  if test -n "$enable_rpath_arg"; then
+    RLD_FLAG="$enable_rpath_arg"
+  fi
+else
+  RLD_FLAG=""
+fi
+
+AC_MSG_NOTICE([defining FPICFLAG to be $FPICFLAG])
+AC_MSG_NOTICE([defining CPICFLAG to be $CPICFLAG])
+AC_MSG_NOTICE([defining CXXPICFLAG to be $CXXPICFLAG])
+AC_MSG_NOTICE([defining SHLEXT to be $SHLEXT])
+AC_MSG_NOTICE([defining SHLLIB to be $SHLLIB])
+AC_MSG_NOTICE([defining SHLBIN to be $SHLBIN])
+AC_MSG_NOTICE([defining SHLEXT_VER to be $SHLEXT_VER])
+AC_MSG_NOTICE([defining SHLLIB_VER to be $SHLLIB_VER])
+AC_MSG_NOTICE([defining SHLBIN_VER to be $SHLBIN_VER])
+AC_MSG_NOTICE([defining SHLLINKEXT to be $SHLLINKEXT])
+AC_MSG_NOTICE([defining LIBPRE to be $LIBPRE])
+AC_MSG_NOTICE([defining SHLPRE to be $SHLPRE])
+AC_MSG_NOTICE([defining SHLLIBPRE to be $SHLLIBPRE])
+AC_MSG_NOTICE([defining SHLBINPRE to be $SHLBINPRE])
+AC_MSG_NOTICE([defining SH_LD to be $SH_LD])
+AC_MSG_NOTICE([defining SH_LDFLAGS to be $SH_LDFLAGS])
+AC_MSG_NOTICE([defining DL_LD to be $DL_LD])
+AC_MSG_NOTICE([defining DL_LDFLAGS to be $DL_LDFLAGS])
+AC_MSG_NOTICE([defining MKOCTFILE_DL_LDFLAGS to be $MKOCTFILE_DL_LDFLAGS])
+AC_MSG_NOTICE([defining SONAME_FLAGS to be $SONAME_FLAGS])
+AC_MSG_NOTICE([defining NO_OCT_FILE_STRIP to be $NO_OCT_FILE_STRIP])
+AC_MSG_NOTICE([defining RLD_FLAG to be $RLD_FLAG])
+AC_MSG_NOTICE([defining TEMPLATE_AR to be $TEMPLATE_AR])
+AC_MSG_NOTICE([defining TEMPLATE_ARFLAGS to be $TEMPLATE_ARFLAGS])
+AC_MSG_NOTICE([defining CRUFT_DLL_DEFS to be $CRUFT_DLL_DEFS])
+AC_MSG_NOTICE([defining OCTAVE_DLL_DEFS to be $OCTAVE_DLL_DEFS])
+AC_MSG_NOTICE([defining OCTINTERP_DLL_DEFS to be $OCTINTERP_DLL_DEFS])
+AC_MSG_NOTICE([defining OCTGRAPHICS_DLL_DEFS to be $OCTGRAPHICS_DLL_DEFS])
+AC_MSG_NOTICE([defining library_path_var to be $library_path_var])
+AC_SUBST(FPICFLAG)
+AC_SUBST(CPICFLAG)
+AC_SUBST(CXXPICFLAG)
+AC_SUBST(SHLEXT)
+AC_SUBST(SHLLIB)
+AC_SUBST(SHLBIN)
+AC_SUBST(SHLEXT_VER)
+AC_SUBST(SHLLIB_VER)
+AC_SUBST(SHLBIN_VER)
+AC_SUBST(SHLLINKEXT)
+AC_SUBST(LIBPRE)
+AC_SUBST(SHLPRE)
+AC_SUBST(SHLLIBPRE)
+AC_SUBST(SHLBINPRE)
+AC_SUBST(SH_LD)
+AC_SUBST(SH_LDFLAGS)
+AC_SUBST(DL_LD)
+AC_SUBST(DL_LDFLAGS)
+AC_SUBST(MKOCTFILE_DL_LDFLAGS)
+AC_SUBST(SONAME_FLAGS)
+AC_SUBST(NO_OCT_FILE_STRIP)
+AC_SUBST(RLD_FLAG)
+AC_SUBST(TEMPLATE_AR)
+AC_SUBST(TEMPLATE_ARFLAGS)
+AC_SUBST(CRUFT_DLL_DEFS)
+AC_SUBST(OCTAVE_DLL_DEFS)
+AC_SUBST(OCTINTERP_DLL_DEFS)
+AC_SUBST(OCTGRAPHICS_DLL_DEFS)
+AC_SUBST(library_path_var)
+AC_SUBST(SCRIPTS_EXE_SUFFIX)
+
+### special checks for odd OS specific things.
+###
+### I am told that on some SCO systems, the only place to find some
+### functions like gethostname and gettimeofday is in libsocket.
+
+AC_CHECK_FUNCS(gethostname, [], [AC_CHECK_LIB(socket, gethostname)])
+AC_CHECK_FUNCS(getpwnam, [], [AC_CHECK_LIB(sun, getpwnam)])
+
+case "$canonical_host_type" in
+  *-*-cygwin*)
+   AC_CHECK_LIB(wsock32, gethostname)
+   LIBS="$LIBS -lwsock32"
+  ;;
+  *-*-msdosmsvc* | *-*-mingw*)
+  LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32"
+  ;;
+esac
+
+### Type stuff.
+
+AC_TYPE_MODE_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+AC_CHECK_TYPES([dev_t, ino_t, nlink_t, nlink_t])
+AC_CHECK_TYPES([long long int, unsigned long long int])
+AC_CHECK_TYPES([sigset_t, sig_atomic_t], , , [
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#include <signal.h>])
+
+### How big are ints and how are they oriented?  These could probably
+### be eliminated in favor of run-time checks.
+
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+
+### Does the C compiler handle alloca() and const correctly?
+
+AC_FUNC_ALLOCA
+AC_C_CONST
+
+### See if we should use placement delete.
+
+OCTAVE_PLACEMENT_DELETE
+
+### See if we can auto allocate variable sized arrays.
+
+OCTAVE_DYNAMIC_AUTO_ARRAYS
+
+### See if we can use fast integer arithmetics
+
+OCTAVE_FAST_INT_OPS
+
+### Check for long double type (for 64-bit integers)
+
+AC_CHECK_SIZEOF(long double)
+
+### Checks for header files.
+
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+AC_HEADER_TIME
+AC_HEADER_SYS_WAIT
+
+### C headers
+
+AC_CHECK_HEADERS(assert.h curses.h direct.h dlfcn.h fcntl.h float.h \
+  floatingpoint.h grp.h ieeefp.h inttypes.h limits.h locale.h memory.h nan.h \
+  ncurses.h poll.h pthread.h pwd.h stdint.h stdlib.h string.h sunmath.h sys/ioctl.h \
+  sys/param.h sys/poll.h sys/resource.h sys/select.h sys/stat.h \
+  sys/time.h sys/times.h sys/types.h sys/utsname.h sys/utime.h termcap.h \
+  unistd.h utime.h varargs.h)
+
+### C++ headers
+
+AC_LANG_PUSH(C++)
+AC_CHECK_HEADERS(sstream)
+AC_LANG_POP(C++)
+
+have_termios_h=no
+AC_CHECK_HEADERS(termios.h, have_termios_h=yes)
+AC_CHECK_HEADERS(termio.h, have_termio_h=yes, have_termio_h=no)
+AC_CHECK_HEADERS(sgtty.h, have_sgtty_h=yes, have_sgtty_h=no)
+AC_CHECK_HEADERS(glob.h, have_glob_h=yes, have_glob_h=no)
+AC_CHECK_HEADERS(fnmatch.h, have_fnmatch_h=yes, have_fnmatch_h=no)
+AC_CHECK_HEADERS(conio.h, have_conio_h=yes, have_conio_h=no)
+
+### I'm told that termios.h is broken on NeXT systems.
+
+case "$canonical_host_type" in
+  *-*-nextstep*)
+    if test "$have_termios_h" = yes; then
+      AC_MSG_WARN([Ignoring termios.h on NeXT systems.])
+      have_termios_h=no
+    fi
+  ;;
+esac
+
+if test "$have_termios_h" = yes \
+    || test "$have_termio_h" = yes \
+    || test "$have_sgtty_h" = yes; then
+  true
+else
+  AC_MSG_WARN([I couldn't find termios.h, termio.h, or sgtty.h!])
+fi
+
+LIBGLOB=
+AC_SUBST(LIBGLOB)
+if test "$have_fnmatch_h" = yes && test "$have_glob_h" = yes; then
+  AC_CHECK_FUNCS(fnmatch, have_fnmatch=yes, [
+    AC_CHECK_LIB(glob, fnmatch, [have_fnmatch=yes; LIBGLOB=-lglob],
+      have_fnmatch=no)])
+  AC_CHECK_FUNCS(glob, have_glob=yes, [
+    AC_CHECK_LIB(glob, glob, [have_glob=yes; LIBGLOB=-lglob],
+      have_glob=no)])
+
+  if test "$have_fnmatch" != yes || test "$have_glob" != yes; then
+    AC_MSG_ERROR([You are required to have fnmatch and glob])
+  fi
+else
+  AC_MSG_ERROR([You are required to have fnmatch.h and glob.h])
+fi
+
+### Checks for functions and variables.
+
+AC_CHECK_FUNCS(atexit basename bcopy bzero canonicalize_file_name \
+  chmod dup2 endgrent endpwent execvp expm1 expm1f fcntl fork fstat getcwd \
+  getegid geteuid getgid getgrent getgrgid getgrnam getpgrp getpid \
+  getppid getpwent getpwuid gettimeofday getuid getwd _kbhit kill \
+  lgamma lgammaf lgamma_r lgammaf_r link localtime_r log1p log1pf lstat \
+  memmove mkdir mkfifo mkstemp on_exit pipe poll putenv raise readlink \
+  realpath rename resolvepath rindex rmdir roundl select setgrent setlocale \
+  setpwent setvbuf sigaction siglongjmp sigpending sigprocmask sigsuspend \
+  snprintf stat strcasecmp strdup strerror stricmp strncasecmp \
+  strnicmp strptime strsignal symlink tempnam tgammaf trunc umask \
+  uname unlink usleep utime vfprintf vsprintf vsnprintf waitpid \
+  _chmod _snprintf x_utime _utime32)
+
+AC_LANG_PUSH(C++)
+AC_CHECK_DECLS([exp2, round, tgamma], [], [], [[#include <cmath>]])
+AC_CHECK_FUNCS([exp2 round tgamma])
+AH_VERBATIM([Z_FUNCS_AND_DECLS], [
+#if defined (__cplusplus)
+extern "C" {
+#endif
+#if HAVE_EXP2 && ! HAVE_DECL_EXP2
+double exp2 (double );
+#endif
+#if HAVE_ROUND && ! HAVE_DECL_ROUND
+double round (double);
+#endif
+#if HAVE_TGAMMA && ! HAVE_DECL_TGAMMA
+double tgamma (double);
+#endif
+#if defined (__cplusplus)
+}
+#endif
+])
+AC_LANG_POP(C++)
+
+case "$canonical_host_type" in
+  *-*-mingw*)
+    ## MinGW does not provide a mkstemp function.  However, it provides
+    ## the mkstemps function in libiberty.
+    AC_MSG_CHECKING(for mkstemps in libiberty)
+    save_LIBS="$LIBS"
+    LIBS="-liberty $LIBS"
+    AC_LINK_IFELSE([
+      AC_LANG_PROGRAM([[int mkstemps (char *pattern, int suffix_len);]], 
+       [[mkstemps ("XXXXXX", 0);]]
+    )],
+    [AC_MSG_RESULT(yes)
+     HAVE_MKSTEMPS=yes
+     AC_DEFINE(HAVE_MKSTEMPS, 1, [Define if mkstemps is available in libiberty.])
+    ],
+    [AC_MSG_RESULT(no)
+     HAVE_MKSTEMPS=no
+     LIBS="$save_LIBS"
+    ])
+   ;;
+esac
+
+case "$canonical_host_type" in
+  *-*-msdosmsvc | *-*-mingw*)
+    ## The %T and %e format specifiers for strftime are not implemented
+    ## so use our version.  We could use an actual configure test
+    ## for this.
+  ;;
+  *)
+    AC_CHECK_FUNCS(strftime)
+  ;;
+esac
+
+OCTAVE_HAVE_C99_VSNPRINTF
+OCTAVE_STRPTIME_BROKEN
+OCTAVE_SMART_PUTENV
+
+case "$canonical_host_type" in
+  *-*-msdosmsvc | *-*-mingw*)
+    AC_MSG_CHECKING([for required _WIN32_WINNT])
+    AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[
+#include <windows.h>
+#if _WIN32_WINNT < 0x0403
+#error "Wrong version"
+#endif]], []),
+      AC_MSG_RESULT([none]), [
+	AC_DEFINE(_WIN32_WINNT, 0x0403, [Define to 0x0403 to access InitializeCriticalSectionAndSpinCount])
+	AC_MSG_RESULT([0x0403])])
+    AC_MSG_CHECKING([whether _USE_MATH_DEFINES needs to be defined])
+    AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[#include <math.h>]],
+[[int x = M_LN2;]]),
+      AC_MSG_RESULT([no]), [
+	AC_DEFINE(_USE_MATH_DEFINES, 1, [Define if your system needs it to define math constants like M_LN2])
+	AC_MSG_RESULT([yes])])
+  ;;
+esac
+
+### Dynamic linking is now enabled only if we are building shared
+### libs and some API for dynamic linking is detected.
+
+LD_CXX='$(CXX)'
+RDYNAMIC_FLAG=
+DL_API_MSG=""
+dlopen_api=false
+shl_load_api=false
+loadlibrary_api=false
+dyld_api=false
+
+if $SHARED_LIBS || $ENABLE_DYNAMIC_LINKING; then
+
+  ## Check for dyld first since OS X can have a non-standard libdl	
+
+  AC_CHECK_HEADER(mach-o/dyld.h)  
+  if test "$ac_cv_header_mach_o_dyld_h" = yes; then
+    dyld_api=true
+  else 
+    AC_CHECK_LIB(dld, shl_load)
+    AC_CHECK_FUNCS(shl_load shl_findsym)
+    if test "$ac_cv_func_shl_load" = yes \
+      && test "$ac_cv_func_shl_findsym" = yes; then
+      shl_load_api=true
+    else
+      AC_CHECK_LIB(wsock32, LoadLibrary)
+      AC_CHECK_FUNCS(LoadLibrary)
+      if test "$ac_cv_func_loadlibrary" = yes; then
+        loadlibrary_api=true
+      else
+        AC_CHECK_LIB(dl, dlopen)
+        AC_CHECK_FUNCS(dlopen dlsym dlerror dlclose)
+        if test "$ac_cv_func_dlclose" = yes \
+          && test "$ac_cv_func_dlerror" = yes \
+          && test "$ac_cv_func_dlopen" = yes \
+          && test "$ac_cv_func_dlsym" = yes; then
+          dlopen_api=true
+        else
+	  case "$canonical_host_type" in
+	    i[[3456]]86-*-sco3.2v5*)
+	      LD_CXX='LD_RUN_PATH=$LD_RUN_PATH:$(octlibdir) $(CXX)'
+	      dlopen_api=true
+	    ;;
+	  esac
+	fi
+      fi
+    fi
+  fi
+
+  ## autoconf test for LoadLibrary appears broken. Bypass for cygwin/mingw 
+  if $dlopen_api || $shl_load_api || $loadlibrary_api || $dyld_api; then
+    true
+  else
+    case "$canonical_host_type" in
+      *-*-cygwin* | *-*-mingw* | *-*-msdosmsvc)
+       loadlibrary_api=true;
+      ;;
+    esac
+  fi
+
+  if $dlopen_api; then
+    DL_API_MSG="(dlopen)"
+    AC_DEFINE(HAVE_DLOPEN_API, 1, [Define if your system has dlopen, dlsym, dlerror, and dlclose for dynamic linking])
+    OCTAVE_CXX_FLAG(-rdynamic, [RDYNAMIC_FLAG=-rdynamic])
+  elif $shl_load_api; then
+    DL_API_MSG="(shl_load)"
+    AC_DEFINE(HAVE_SHL_LOAD_API, 1, [Define if your system has shl_load and shl_findsym for dynamic linking])
+  elif $loadlibrary_api; then
+    DL_API_MSG="(LoadLibrary)"
+    AC_DEFINE(HAVE_LOADLIBRARY_API, 1, [Define if your system has LoadLibrary for dynamic linking])
+  elif $dyld_api; then
+    DL_API_MSG="(dyld)"
+    AC_DEFINE(HAVE_DYLD_API, 1, [Define if your system has dyld for dynamic linking])
+  fi
+
+  if $dlopen_api || $shl_load_api || $loadlibrary_api || $dyld_api; then
+    ENABLE_DYNAMIC_LINKING=true
+    AC_DEFINE(ENABLE_DYNAMIC_LINKING, 1, [Define if using dynamic linking])
+  fi
+fi
+
+if $SHARED_LIBS; then
+   LIBOCTINTERP=-loctinterp$SHLLINKEXT
+   LIBOCTAVE=-loctave$SHLLINKEXT
+   LIBCRUFT=-lcruft$SHLLINKEXT
+else
+  LIBOCTINTERP='$(TOPDIR)/src/liboctinterp.$(LIBEXT)'
+  LIBOCTAVE='$(TOPDIR)/liboctave/liboctave.$(LIBEXT)'
+  LIBCRUFT='$(TOPDIR)/libcruft/libcruft.$(LIBEXT)'
+fi
+
+AC_SUBST(LD_CXX)
+AC_SUBST(RDYNAMIC_FLAG)
+AC_SUBST(ENABLE_DYNAMIC_LINKING)
+AC_SUBST(LIBOCTINTERP)
+AC_SUBST(LIBOCTAVE)
+AC_SUBST(LIBCRUFT)
+
+### There is more than one possible prototype for gettimeofday.  See
+### which one (if any) appears in sys/time.h.  These tests are from
+### Emacs 19.
+
+AC_MSG_CHECKING(for struct timeval)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif]], [[static struct timeval x; x.tv_sec = x.tv_usec;]])],
+  [AC_MSG_RESULT(yes)
+   HAVE_TIMEVAL=yes
+   AC_DEFINE(HAVE_TIMEVAL, 1, [Define if struct timeval is defined.])],
+  [AC_MSG_RESULT(no)
+   HAVE_TIMEVAL=no])
+
+if test "x$HAVE_TIMEVAL" = xyes; then
+AC_MSG_CHECKING(whether gettimeofday can't accept two arguments)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif]], [[struct timeval time;
+  struct timezone dummy;
+  gettimeofday (&time, &dummy);]])],
+  [AC_MSG_RESULT(no)],
+  [AC_MSG_RESULT(yes)
+   AC_DEFINE(GETTIMEOFDAY_NO_TZ, 1,
+     [Define if your system has a single-arg prototype for gettimeofday.])])
+fi
+
+dnl Maybe <cmath> defines the IEEE functions we need.
+
+OCTAVE_CMATH_FUNC(isnan)
+OCTAVE_CMATH_FUNC(isinf)
+OCTAVE_CMATH_FUNC(isfinite)
+
+dnl Would like to get rid of this cruft, and just have
+dnl
+dnl   AC_CHECK_FUNCS(finite isnan isinf)
+dnl
+dnl instead, but that used to fail on some systems...
+dnl
+dnl Also just using AC_CHECK_FUNCS doesn't seem to work to find isinf
+dnl and isnan on Linux systems, so we use AC_CHECK_FUNC, and if that
+dnl fails, we try again by including math.h and invoking the function
+dnl with an argument. 
+
+### I am told that Inf and NaN don't work on m68k HP sytems, and that
+### on SCO systems, isnan and isinf don't work, but they can be
+### replaced by something that does.
+
+case "$canonical_host_type" in
+  m68k-hp-hpux*)
+  ;;
+  *-*-sco*)
+    AC_MSG_NOTICE([defining SCO to be 1])
+    AC_DEFINE(SCO, 1, [Define if using an SCO system.])
+    AC_MSG_NOTICE([forcing HAVE_ISINF for SCO])
+    AC_DEFINE(HAVE_ISINF, 1, [Define if you have isinf().])
+    AC_MSG_NOTICE([forcing HAVE_ISNAN for SCO])
+    AC_DEFINE(HAVE_ISNAN, 1, [Define if you have isnan().])
+  ;;
+  *)
+    AC_CHECK_FUNCS(finite isnan isinf copysign signbit)
+    AC_CHECK_FUNCS(_finite _isnan _copysign)
+    AC_CHECK_DECLS(signbit, , , [#include <math.h>])
+  ;;
+esac
+
+### Check for nonstandard but common math functions that we need.
+
+AC_CHECK_FUNCS(acosh acoshf asinh asinhf atanh atanhf erf erff erfc erfcf exp2f log2 log2f)
+AC_CHECK_FUNCS(hypotf _hypotf)
+
+### Checks for OS specific cruft.
+
+AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_blocks, struct stat.st_rdev])
+
+AC_STRUCT_TM
+AC_STRUCT_TIMEZONE
+AC_FUNC_CLOSEDIR_VOID
+
+AC_CHECK_MEMBERS(struct group.gr_passwd)
+
+# mkdir takes a single argument on some systems.
+OCTAVE_MKDIR_TAKES_ONE_ARG
+
+octave_found_termlib=no
+for termlib in ncurses curses termcap terminfo termlib; do
+  AC_CHECK_LIB(${termlib}, tputs, [TERMLIBS="${TERMLIBS} -l${termlib}"])
+  case "${TERMLIBS}" in
+    *-l${termlib}*)
+      LIBS="$TERMLIBS $LIBS"
+      AC_SUBST(TERMLIBS)
+      octave_found_termlib=yes
+      break
+    ;;
+  esac
+done
+
+if test "$octave_found_termlib" = no; then
+  warn_termlibs="I couldn't find -ltermcap, -lterminfo, -lncurses, -lcurses, o\
+r -ltermlib!"
+  AC_MSG_WARN($warn_termlibs)
+fi
+
+OCTAVE_ENABLE_READLINE
+
+AC_MSG_CHECKING([for struct exception in math.h])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]],
+  [[struct exception *x; x->type; x->name;]])],
+  [AC_MSG_RESULT(yes)
+   AC_DEFINE(EXCEPTION_IN_MATH, 1,
+     [Define if your math.h declares struct exception for matherr().])],
+  [AC_MSG_RESULT(no)])
+
+### Signal stuff.
+
+AC_TYPE_SIGNAL
+AC_CHECK_DECLS([sys_siglist], [], [],
+[#include <signal.h>
+/* NetBSD declares sys_siglist in unistd.h.  */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+])
+OCTAVE_SIGNAL_CHECK
+OCTAVE_REINSTALL_SIGHANDLERS
+if test "$ac_cv_type_signal" = "void"; then
+  AC_DEFINE(RETSIGTYPE_IS_VOID, 1, [Define if this if RETSIGTYPE is defined to be void.  Needed because preprocessor comparisons to void fail on some systems.])
+fi
+
+### A system dependent kluge or two.
+
+AC_CHECK_FUNCS(getrusage times)
+case "$canonical_host_type" in
+  *-*-cygwin*)
+    AC_DEFINE(RUSAGE_TIMES_ONLY, 1, [Define if your struct rusage only has time information.])
+  ;;
+esac
+
+### Checks for other programs used for building, testing, installing,
+### and running Octave.
+
+AC_PROG_AWK
+OCTAVE_PROG_FIND
+OCTAVE_PROG_SED
+OCTAVE_PROG_PERL
+OCTAVE_PROG_PYTHON
+
+OCTAVE_PROG_FLEX
+OCTAVE_PROG_BISON
+
+AC_PROG_LN_S
+
+AC_PROG_INSTALL
+INSTALL_SCRIPT='${INSTALL}'
+AC_SUBST(INSTALL_SCRIPT)
+
+OCTAVE_PROG_DESKTOP_FILE_INSTALL
+
+OCTAVE_PROG_GNUPLOT
+OCTAVE_PROG_PAGER
+OCTAVE_PROG_GPERF
+
+OCTAVE_PROG_GHOSTSCRIPT
+OCTAVE_PROG_MAKEINFO
+OCTAVE_PROG_TEXI2DVI
+OCTAVE_PROG_TEXI2PDF
+
+### Even though we include config.h, we need to have the preprocessor
+### defines available in a variable for the octave-bug script.  Use
+### UGLY_DEFS for that.
+
+AC_OUTPUT_MAKE_DEFS
+
+### We have to insert extra levels of backslash quoting here so that
+### the right thing ends up in oct-conf.h.
+UGLY_DEFS=`echo $DEFS | $SED 's,\\",\\\\\\\\\\\\\\\\\\",g'`
+AC_MSG_NOTICE([defining UGLY_DEFS to be $UGLY_DEFS])
+AC_SUBST(UGLY_DEFS)
+
+### Maybe add -Wall, -W, and -Wshadow to compiler flags now that we're
+### done feature testing. 
+
+try_extra_warning_flags=true
+AC_ARG_ENABLE(extra-warning-flags,
+  [AS_HELP_STRING([--enable-extra-warning-flags],
+     [add -Wall, -W, -Wshadow, and -Wold-style-cast options to CFLAGS and CXXFLAGS  (on by default, but only if the compiler appears to accept them)])],
+  [if test "$enableval" = no; then
+     try_extra_warning_flags=false
+   fi], [])
+
+if $try_extra_warning_flags; then
+  OCTAVE_CC_FLAG(-Wall, [
+    WARN_CFLAGS="$WARN_CFLAGS -Wall";
+    AC_MSG_RESULT([adding -Wall to WARN_CFLAGS])])
+  OCTAVE_CC_FLAG(-W, [
+    WARN_CFLAGS="$WARN_CFLAGS -W";
+    AC_MSG_RESULT([adding -W to WARN_CFLAGS])])
+  OCTAVE_CC_FLAG(-Wshadow, [
+    WARN_CFLAGS="$WARN_CFLAGS -Wshadow";
+    AC_MSG_RESULT([adding -Wshadow to WARN_CFLAGS])])
+  OCTAVE_CC_FLAG(-Wformat, [
+    WARN_CFLAGS="$WARN_CFLAGS -Wformat";
+    AC_MSG_RESULT([adding -Wformat to WARN_CFLAGS])])
+
+  OCTAVE_CXX_FLAG(-Wall, [
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wall";
+    AC_MSG_RESULT([adding -Wall to WARN_CXXFLAGS])])
+  OCTAVE_CXX_FLAG(-W, [
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -W";
+    AC_MSG_RESULT([adding -W to WARN_CXXFLAGS])])
+  OCTAVE_CXX_FLAG(-Wshadow, [
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wshadow";
+    AC_MSG_RESULT([adding -Wshadow to WARN_CXXFLAGS])])
+  OCTAVE_CXX_FLAG(-Wold-style-cast, [
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wold-style-cast";
+    AC_MSG_RESULT([adding -Wold-style-cast to WARN_CXXFLAGS])])
+  OCTAVE_CXX_FLAG(-Wformat, [
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat";
+    AC_MSG_RESULT([adding -Wformat to WARN_CXXFLAGS])])
+fi
+
+GCC_STRICT_FLAGS="-Wcast-align -Wcast-qual -Wconversion -Wmissing-prototypes \
+  -Wpointer-arith -Wstrict-prototypes -Wwrite-strings"
+
+GXX_STRICT_FLAGS="-Wcast-align -Wcast-qual -Wconversion -Wpointer-arith \
+  -Wwrite-strings -Weffc++"
+
+try_strict_warning_flags=false
+
+AC_ARG_ENABLE(strict-warning-flags,
+  [AS_HELP_STRING([--enable-strict-warning-flags],
+     [add extra strict warning options to CFLAGS and CXXFLAGS (off by default)])],
+  [if test "$enableval" = yes; then
+     try_strict_warning_flags=true
+   fi], [])
+
+if $try_strict_warning_flags; then
+  for flag in $GCC_STRICT_FLAGS; do
+    OCTAVE_CC_FLAG($flag, [
+      WARN_CFLAGS="$WARN_CFLAGS $flag";
+      AC_MSG_RESULT([adding $flag to WARN_CFLAGS])])
+  done
+  for flag in $GXX_STRICT_FLAGS; do
+    OCTAVE_CXX_FLAG($flag, [
+      WARN_CXXFLAGS="$WARN_CXXFLAGS $flag";
+      AC_MSG_RESULT([adding $flag to WARN_CXXFLAGS])])
+  done
+fi
+
+AC_SUBST(WARN_CFLAGS)
+AC_SUBST(WARN_CXXFLAGS)
+
+### Run configure in subdirectories.
+
+export CC
+export CXX
+export F77
+
+AC_CONFIG_SUBDIRS(scripts)
+
+### Some things to add to the bottom of config.h.
+
+AH_BOTTOM([
+#if defined (__GNUC__)
+#define GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__))
+#define GCC_ATTR_UNUSED __attribute__ ((__unused__))
+#else
+#define GCC_ATTR_DEPRECATED
+#define GCC_ATTR_NORETURN
+#define GCC_ATTR_UNUSED
+#endif
+
+#define X_CAST(T, E) (T) (E)
+
+#if defined (CXX_BROKEN_REINTERPRET_CAST)
+#define FCN_PTR_CAST(T, E) (T) (E)
+#else
+#define FCN_PTR_CAST(T, E) reinterpret_cast<T> (E)
+#endif
+
+#if !defined(HAVE_DEV_T)
+typedef short dev_t;
+#endif
+
+#if !defined(HAVE_INO_T)
+typedef unsigned long ino_t;
+#endif
+
+#if !defined(HAVE_NLINK_T)
+typedef short nlink_t;
+#endif
+
+#if !defined(HAVE_SIGSET_T)
+typedef int sigset_t;
+#endif
+
+#if !defined(HAVE_SIG_ATOMIC_T)
+typedef int sig_atomic_t;
+#endif
+
+#if defined (_MSC_VER)
+#define __WIN32__
+#define WIN32
+/* missing parameters in macros */
+#pragma warning (disable: 4003)
+/* missing implementations in template instantiation */
+#pragma warning (disable: 4996)
+/* deprecated function names (FIXME?) */
+#pragma warning (disable: 4661)
+#endif
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#define OCTAVE_HAVE_WINDOWS_FILESYSTEM 1
+#elif defined (__CYGWIN__)
+#define OCTAVE_HAVE_WINDOWS_FILESYSTEM 1
+#define OCTAVE_HAVE_POSIX_FILESYSTEM 1
+#else
+#define OCTAVE_HAVE_POSIX_FILESYSTEM 1
+#endif
+
+/* Define if we expect to have <windows.h>, Sleep, etc. */
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#define OCTAVE_USE_WINDOWS_API 1
+#endif
+
+#if defined (__APPLE__) && defined (__MACH__)
+#define OCTAVE_USE_OS_X_API 1
+#endif
+
+/* sigsetjmp is a macro, not a function. */
+#if defined (sigsetjmp) && defined (HAVE_SIGLONGJMP)
+#define OCTAVE_HAVE_SIG_JUMP
+#endif
+
+#if defined (__DECCXX)
+#define __USE_STD_IOSTREAM
+#endif
+
+#if defined (_UNICOS)
+#define F77_USES_CRAY_CALLING_CONVENTION
+#endif
+
+#if 0
+#define F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION
+#endif
+
+#ifdef USE_64_BIT_IDX_T
+#define SIZEOF_OCTAVE_IDX_TYPE 8
+#else
+#define SIZEOF_OCTAVE_IDX_TYPE SIZEOF_INT
+#endif
+
+// To be able to use long doubles for 64-bit mixed arithmetics, we need them at
+// least 80 bits wide and we need roundl declared in math.h.
+// FIXME -- maybe substitute this by a more precise check in the future.
+#if (SIZEOF_LONG_DOUBLE >= 10) && defined (HAVE_ROUNDL)
+#define OCTAVE_INT_USE_LONG_DOUBLE
+#endif
+
+#define OCTAVE_EMPTY_CPP_ARG
+
+#include "oct-dlldefs.h"
+#include "oct-types.h"
+])
+
+### Do the substitutions in all the Makefiles.
+
+AC_CONFIG_COMMANDS([Makefile], [if test "$ac_srcdir" != "."; then
+  cp $srcdir/Makefile .
+fi])
+
+AC_SUBST(ac_config_files)
+
+AC_CONFIG_FILES([octMakefile Makeconf test/Makefile
+  doc/Makefile doc/faq/Makefile doc/interpreter/Makefile
+  doc/liboctave/Makefile doc/refcard/Makefile emacs/Makefile
+  examples/Makefile examples/@polynomial/Makefile 
+  examples/@FIRfilter/Makefile liboctave/Makefile
+  liboctave/oct-types.h src/Makefile src/mxarray.h libcruft/Makefile
+  libcruft/Makerules libcruft/amos/Makefile libcruft/blas/Makefile
+  libcruft/daspk/Makefile libcruft/dasrt/Makefile
+  libcruft/dassl/Makefile libcruft/fftpack/Makefile
+  libcruft/lapack/Makefile 
+  libcruft/misc/Makefile libcruft/odepack/Makefile
+  libcruft/ordered-qz/Makefile libcruft/quadpack/Makefile
+  libcruft/ranlib/Makefile libcruft/slatec-fn/Makefile
+  libcruft/slatec-err/Makefile libcruft/villad/Makefile
+  libcruft/blas-xtra/Makefile libcruft/lapack-xtra/Makefile])
+
+AC_OUTPUT
+
+### Print a summary so that important information isn't missed.
+
+AC_MSG_NOTICE([
+
+Octave is now configured for $canonical_host_type
+
+  Source directory:     $srcdir
+  Installation prefix:  $prefix
+  C compiler:           $CC $XTRA_CFLAGS $WARN_CFLAGS $CFLAGS
+  C++ compiler:         $CXX $XTRA_CXXFLAGS $WARN_CXXFLAGS $CXXFLAGS
+  Fortran compiler:     $F77 $FFLAGS
+  Fortran libraries:    $FLIBS
+  BLAS libraries:       $BLAS_LIBS
+  FFTW libraries:       $FFTW_LIBS
+  GLPK libraries:       $GLPK_LIBS
+  UMFPACK libraries:    $UMFPACK_LIBS
+  AMD libraries:        $AMD_LIBS
+  CAMD libraries:       $CAMD_LIBS
+  COLAMD libraries:     $COLAMD_LIBS
+  CCOLAMD libraries:    $CCOLAMD_LIBS
+  CHOLMOD libraries:    $CHOLMOD_LIBS
+  CXSPARSE libraries:   $CXSPARSE_LIBS
+  ARPACK libraries:     $ARPACK_LIBS
+  QRUPDATE libraries:	$QRUPDATE_LIBS
+  HDF5 libraries:       $HDF5_LIBS
+  CURL libraries:       $CURL_LIBS
+  REGEX libraries:      $REGEX_LIBS
+  QHULL libraries:	$QHULL_LIBS
+  OPENGL libraries:     $OPENGL_LIBS
+  FLTK backend libs:    $GRAPHICS_LIBS
+  X11 include flags:    $X11_INCFLAGS
+  X11 libraries:        $X11_LIBS
+  CARBON libraries:     $CARBON_LIBS
+  PTHREAD flags         $PTHREAD_CFLAGS
+  PTHREAD libraries     $PTHREAD_LIBS
+  LIBS:                 $LIBS
+  Default pager:        $DEFAULT_PAGER
+  gnuplot:              $GNUPLOT
+  Magick config:        $MAGICK_CONFIG
+
+  Do internal array bounds checking:  $BOUNDS_CHECKING
+  Build static libraries:             $STATIC_LIBS
+  Build shared libraries:             $SHARED_LIBS
+  Dynamic Linking:                    $ENABLE_DYNAMIC_LINKING $DL_API_MSG
+  Include support for GNU readline:   $USE_READLINE
+  64-bit array dims and indexing:     $USE_64_BIT_IDX_T
+])
+
+warn_msg_printed=false
+
+if $ENABLE_DYNAMIC_LINKING; then
+  if $SHARED_LIBS; then
+    true
+  else
+    AC_MSG_WARN([You used --enable-dl but not --enable-shared.])
+    AC_MSG_WARN([Are you sure that is what you want to do?])
+    warn_msg_printed=true
+  fi
+fi
+
+if test -n "$gxx_only"; then
+  AC_MSG_WARN($gxx_only)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gcc_version"; then
+  AC_MSG_WARN($warn_gcc_version)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gcc_only"; then
+  AC_MSG_WARN($warn_gcc_only)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_readline"; then
+  AC_MSG_WARN($warn_readline)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_termlibs"; then
+  AC_MSG_WARN($warn_termlibs)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gperf"; then
+  AC_MSG_WARN($warn_gperf)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_flex"; then
+  AC_MSG_WARN($warn_flex)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_bison"; then
+  AC_MSG_WARN($warn_bison)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_less"; then
+  AC_MSG_WARN($warn_less)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_blas_f77_incompatible"; then
+  AC_MSG_WARN($warn_blas_f77_incompatible)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_umfpack"; then
+  AC_MSG_WARN($warn_umfpack)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_qrupdate"; then
+  AC_MSG_WARN($warn_qrupdate)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_amd"; then
+  AC_MSG_WARN($warn_amd)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_colamd"; then
+  AC_MSG_WARN($warn_colamd)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_ccolamd"; then
+  AC_MSG_WARN($warn_ccolamd)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_cholmod"; then
+  AC_MSG_WARN($warn_cholmod)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_cxsparse"; then
+  AC_MSG_WARN($warn_cxsparse)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_arpack"; then
+  AC_MSG_WARN($warn_arpack)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_curl"; then
+  AC_MSG_WARN($warn_curl)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_fftw"; then
+  AC_MSG_WARN($warn_fftw)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_glpk"; then
+  AC_MSG_WARN($warn_glpk)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_magick"; then
+  AC_MSG_WARN($warn_magick)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_hdf5"; then
+  AC_MSG_WARN($warn_hdf5)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_regex"; then
+  AC_MSG_WARN($warn_regex)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_pcre"; then
+  AC_MSG_WARN($warn_pcre)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_qhull"; then
+  AC_MSG_WARN($warn_qhull)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_zlib"; then
+  AC_MSG_WARN($warn_zlib)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_ghostscript"; then
+  AC_MSG_WARN($warn_ghostscript)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_makeinfo"; then
+  AC_MSG_WARN($warn_makeinfo)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_texi2dvi"; then
+  AC_MSG_WARN($warn_texi2dvi)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_texi2pdf"; then
+  AC_MSG_WARN($warn_texi2pdf)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_64_bit"; then
+  AC_MSG_WARN($warn_64_bit)
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_gnuplot"; then
+
+  ## If you change this text, be sure to also change the corresponding
+  ## set of warnings above.
+
+  AC_MSG_WARN([])
+  AC_MSG_WARN([I didn't find gnuplot.  It isn't necessary to have gnuplot])
+  AC_MSG_WARN([installed, but you won't be able to use any of Octave's])
+  AC_MSG_WARN([plotting commands without it.])
+  AC_MSG_WARN([])
+  AC_MSG_WARN([If gnuplot is installed but it isn't in your path, you can])
+  AC_MSG_WARN([tell Octave where to find it by typing the command])
+  AC_MSG_WARN([])
+  AC_MSG_WARN([gnuplot_binary = "/full/path/to/gnuplot/binary"])
+  AC_MSG_WARN([])
+  AC_MSG_WARN([at the Octave prompt.])
+  AC_MSG_WARN([])
+  warn_msg_printed=true
+fi
+
+if $USE_64_BIT_IDX_T; then
+  AC_MSG_WARN([])
+  AC_MSG_WARN([You used the EXPERIMENTAL --enable-64 option.])
+  AC_MSG_WARN([Are you sure that is what you want to do?])
+  AC_MSG_WARN([])
+  AC_MSG_WARN([You must ensure that the Fortran compiler generates])
+  AC_MSG_WARN([code with 8 byte signed INTEGER values, and that your])
+  AC_MSG_WARN([BLAS and LAPACK libraries are compiled to use 8 byte])
+  AC_MSG_WARN([signed integers for array indexing.])
+  AC_MSG_WARN([])
+  warn_msg_printed=true
+fi
+
+native_graphics=true
+if test -n "$warn_freetype"; then
+  AC_MSG_WARN("$warn_freetype")
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_ftgl"; then
+  AC_MSG_WARN("$warn_ftgl")
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_fltk_config"; then
+  AC_MSG_WARN("$warn_fltk_config")
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if test -n "$warn_fltk_opengl"; then
+  AC_MSG_WARN("$warn_fltk_opengl")
+  native_graphics=false
+  warn_msg_printed=true
+fi
+
+if $native_graphics; then
+  true;
+else
+  AC_MSG_WARN([])
+  AC_MSG_WARN([I didn't find the necessary libraries to compile native])
+  AC_MSG_WARN([graphics. It isn't necessary to have native graphics])
+  AC_MSG_WARN([but you will have to use gnuplot or you won't be able])
+  AC_MSG_WARN([to use any of Octave's plotting commands])
+  AC_MSG_WARN([])
+  warn_msg_printed=true
+fi
+
+if $warn_msg_printed; then
+  AC_MSG_NOTICE([
+
+NOTE: libraries may be skipped if a library is not found OR
+      if the library on your system is missing required features.
+])
+fi
+
+### End of configure.
diff --git a/doc/ChangeLog b/doc/ChangeLog
new file mode 100644
index 0000000..1fdddf2
--- /dev/null
+++ b/doc/ChangeLog
@@ -0,0 +1,1928 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+2009-10-11  Rik <octave at nomad.inbox5.com>
+
+	* intepreter/Makefile.in: Fix broken command to create octave.dvi
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+2009-07-20  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/contributors.in: Add Aleksej Saushev.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-06-24  Rafael Laboissiere  <rafael at debian.org>
+
+	* Makefile.in (dist): Drop conf.texi as prerequisite.
+
+2009-06-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/tips.txi: Update.
+
+2009-06-07  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/plot.txi: Update some of Advanced Plotting documentation.
+	Updated functions delete, allchild, backend, clf, hold, and refreshdata.
+
+2009-06-07  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* interpreter/container.txi: Udate documentation of container types
+
+2009-06-03  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/plotimages.m: Correct errorbar plot for docs.  Make hist plot
+	reprodroducible for docs.
+	* interpreter/interpimages.m: Correct typo in legend of interpft plot for
+	docs 
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-06-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Makefile.in: Omit conf.texi in DISTFILES.
+
+2009-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/oop.txi: Update docs of polynomial class, mention
+	chained indexing.
+
+2009-05-27  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/errors.txi: fix 'print_usage' output.
+
+2009-05-27  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/bugs.txi: fix call to 'page_screen_output'.
+
+2009-05-25  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/Makefile.in: Add texmf.cnf to list of distributed files
+	(DIST_FILES) so that pdfs will build.
+
+2009-05-24  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* interpreter/oop.txi: Added inheritance documentatin
+
+2009-05-21  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/Makefile.in, texmf.cnf: Change texi2pdf call to include local
+	TeX configuration file which increases save_history variable.
+
+2009-05-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/tips.txi: Change recommendation to use @tex rather than
+	@iftex construction.
+
+2009-05-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/*.txi: Simplify TeXinfo files by eliminating redundant @iftex
+	followed by @tex construction.  Also, spellchecked all .txi and .texi files.
+
+2009-05-14  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.8 (Mathematical Consants)
+	of arith.txi.
+
+2009-05-01  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.7 (Coordinate
+	Transformations) of arith.txi.
+
+2009-05-01  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Simplify TeXinfo and eliminate use of
+	@iftex in arith.txi.
+
+2009-05-01  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.5 (Utility Functions)
+	of arith.txi.
+
+2009-04-30  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.4 (Sums and Products)
+	of arith.txi.
+
+2009-04-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/numbers.txi: Update info on ranges.
+	* interpreter/expr.txi: Update some info on indexing.
+
+2009-04-26  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.3 (Trigonometry) of
+	arith.txi.
+
+2009-04-24  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.2 (Complex Arithmetic)
+	of arith.txi.  Use Tex in more of the doc strings for pretty
+	printing in pdf format.
+
+2009-04-24  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/octave.pdf: Eliminate most overfull errors when
+	running texi2pdf for generating pdf documentation.  Use
+	@smallexample when necessary to reduce font for long lines.
+	Reword variables or phrases so that Tex can break them at a better
+	spot.
+
+2009-04-21  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/octave.pdf: Eliminate 'unbalanced parentheses in
+	@def...' error during texi2pdf.  Fixed four .m files incorrectly
+	using @deftypefn macro.
+
+2009-04-19  Ansgar Burchardt  <ansgar at 43-1.org>
+
+	* interpreter/numbers.txi: Fix small mistake in example.
+
+2009-04-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/arith.txi: Update section 17.1 (Utility Functions)
+	of arith.txi.  Split section into "Exponents and Logarithms" and
+	"Utility Functions" Use Tex in many more of the doc strings for
+	pretty printing in pdf format.
+
+2009-04-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/basics.txi: Update help text for sections 2.5, 2.6, 2.7
+	of basics.txi 
+
+2009-04-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/basics.txi: Update help text for sections 2.4 of
+	basics.txi.
+
+2009-04-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/basics.txi: Update help text for sections 2.2 
+	and 2.3 of basics.txi.
+
+2009-04-17  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/basics.txi: Update help strings for command line options.
+
+2009-04-11  David Bateman  <dbateman at free.fr>
+
+	* interpreter/contributors.in: Add Martin Helm.
+
+2009-04-06  John W. Eaton  <jwe at octave.org>
+
+	* texinfo.tex: Prefer PDF image files if generating PDF output.
+
+2009-03-27  Rik  <rdrider0-list at yahoo.com>
+
+	* interpreter/intro.txi: Add new sample section on elementary 
+	calculations.  Add new example of solving systems of equations
+
+2009-03-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/diagperm.txi: Mention mixing with sparse matrices.
+
+2009-03-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/munge-texi.cc (process_texi_input_file):
+	Copy leading comment with file name info to output.
+
+2009-03-09  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (DISTFILES): Use doc-cache instead of
+	DOC for doc cache file.
+
+2009-03-08  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/stats.txi (Basic Statistical Functions):
+	Add the 'histc' function.
+
+2009-03-07  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/basics.txi (Command Line Options):
+	Document --doc-cache-file command-line option.
+
+2009-03-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/diagperm.txi: Various improvements.
+
+2009-02-27  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/set.txi (Sets): Don't document create_set.
+
+2009-02-26  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/strings.txi (Manipulating Strings):
+	Document strsplit, not split.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (distclean): Remove tags and TAGS here
+	instead of in maintainer-clean target.
+	(maintainer-clean): Depend on distclean, not clean.  Remove DOC.
+	(DISTFILES): Add stmp-html to the list.
+
+	* Makefile.in: Remove conf.texi in maintainer-clean target but not
+	distclean target.
+
+2009-02-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/diagperm.txi: Remove redundant url references.
+
+2009-02-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/diagperm.txi: Use TeX alternatives in some
+	formulas, improve examples, delete superfluous defs.
+
+2009-02-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/diagperm.txi: New file.
+	* interpreter/octave.texi: Reference it.
+	* intepreter/Makefile.in: Include it.
+	* interpreter/matrix.txi: Move @DOCSTRING(diag) to diagperm.txi.
+
+2009-02-19  John W. Eaton  <jwe at octave.org>
+
+	* doc/interperter: Include @DOCSTRING commands for the following
+	functions: bicgstab, cgs, choldelete, cholinsert, cholshift,
+	clabel, comet, command_line_path, compass, contour3, ctranspose,
+	cylinder, dellistener, diffuse, edit, ellipsoid, fclear, feather,
+	fill, find_dir_in_path, finite, flag, info, is_absolute_filename,
+	is_rooted_relative_filename, isdebugmode, ishghandle, isnull,
+	issorted, make_absolute_filename, meshz, news,
+	octave_tmp_file_name, optimget, pareto, plotmatrix, plotyy,
+	qrshift, quiver3, re_read_readline_init_file, ribbon, rose,
+	rundemos, scatter, scatter3, slice, specular, sphere, spinmap,
+	stem3, strchr, strtrim, surfl, surfnorm, times, transpose,
+	treelayout, uminus, uplus, warranty, what, xlim, yes_or_no.
+
+2009-02-17  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* interpreter/install.txi: Add documentation for configure options
+	"--without-framework-carbon" and "--without-framework-opengl".
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/arith.txi: Add reference to "cummin" and "cummax".
+
+2009-02-11  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (uninstall): Use $(DESTDIR) here too.
+	Uninstall Info dir file.  Uninstall DOC file.
+	(install): Install DOC file.  Add $(DESTDIR)$(octetcdir) to the
+	list of directories to make.
+
+2009-02-10  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (DOC): New target.
+	(DISTFILES): Add DOC nad mk_doc_cache.m to the list.
+	* mk_doc_cache.m: New file.
+
+2009-02-01  S�ren Hauberg <hauberg at gmail.com>
+
+	* interpreter/nonlin.txi: Remove reference to 'fsolve_options'.
+
+2009-02-01  S�ren Hauberg <hauberg at gmail.com>
+
+	* interpreter/system.txi: Remove reference to 'eomdate'.
+
+2009-01-24  Thorsten Meyer  <thorsten at hexe>
+
+	* interpreter/container.txi (Data Structures): Update examples for
+	structure arrays.
+
+2009-01-22  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/io.txi (Terminal Output): Remove @DOCSTRING(ans).
+
+	* vr-idx.txi: Delete.
+	* interpreter/Makefile.in (SUB_SOURCE): Remove it from the list.
+
+2009-01-22  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/func.txi: Put varargin and varargout in concept index.
+	* interpreter/var.txi: Put ans in concept index.
+	* interpreter/octave.texi: Don't include vr-idx.texi.
+	
+        * interpreter/var.txi: Remove sections on built-in variables.
+
+2009-01-20  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/system.txi (Filesystem Utilities): @DOCSTRING for
+	fstat.  Delete @DOCSTRING for lstat.  Add anchor for doc-lstat.
+
+2009-01-18  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* interpreter/numbers.txi (Numeric Data Types): Trivial fixes.
+
+2009-01-14  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* interpreter/matrix.txi: Add anchor for doc-postpad.
+	
+2008-12-26  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* interpreter/strings.txi: Add space to ischar example.
+	
+2008-12-26  Francesco Potortì  <pot at gnu.org>
+
+	* interpreter/matrix.txi (Rearranging Matrices): Add reference
+	to resize function.
+
+	* interpreter/plot.txi (Plot Annotations): Add cross reference to
+	Text Properties.
+	(Two-Dimensional Plots): Update introduction to the axis function.
+
+       * interpreter/signal.txi (Signal Processing): Add explanation of
+       what wisdom is.
+
+2008-12-23  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Document the eigs and svds functions.
+
+2008-12-02  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * interpreter/container.txi, interpreter/strings.txi:
+        Remove reference to str2mat.m
+        
+2008-11-15  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * interpreter/strings.txi: Add text around docstrings, change
+        structure of the strings chapter.
+        
+2008-10-31  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in ($(TEXINFO)): Depend directly on
+	../../src/DOCSTRINGS and ../../scripts/DOCSTRINGS instead of phony
+	src-DOCSTRINGS and scripts-DOCSTRINGS targets.
+	(src-DOCSTRINGS, scripts-DOCSTRINGS): Delete.
+	(DOCSTRING_FILES): New variable.
+	($(SUB_TEXFINO)): Use it.  Display actual command.
+	($(DOCSTRING_FILES)): New target.
+	(%.spell : %.texi): Use -t suffix instead of .tmp.
+	(constributors.texi, $(SUB_TEXINFO)): Use mv, instead of
+	$(simple-move-if-change-rule).
+
+2008-10-30  David Bateman  <dbateman at free.fr>
+
+	* faq/Octave-FAQ.texi: Document improved indexing and add an faq for
+	the compatibility of mldivide/mrdivide for singualr, under- and 
+	over-determined matrices.
+	
+	* interpreter/plot.txi: Document contour groups.
+
+2008-10-29  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* interpreter/system.txi, interpreter/poly.txi,
+	interpreter/arith.txi, interpreter/poly.txi,
+	interpreter/optim.txi, interpreter/diffeq.txi,
+	interpreter/sparse.txi, interpreter/matrix.txi,
+	interpreter/plot.txi, interpreter/io.txi, interpreter/debug.txi,
+	interpreter/var.txi, interpreter/strings.txi:
+	Add missing @DOCSTRING commands.
+
+	* interpreter/munge-texi.cc (extract_docstring): Expand arguments
+	of @seealso{} into Texinfo references.
+          
+2008-10-22  David Bateman  <dbateman at free.fr>
+
+	* interprter/plot.txi: Add documentation for error bar series.
+
+	* interprter/plot.txi: Update documentation for line series, Add 
+	documetation for scatter groups, stem series and surface groups.
+
+	* texinfo.tex: Import new upstream version.
+	* interpreter/Makefile.in (EXAMPLE_FILES_NODIR): Update for new OOP
+	class example location.
+	* interpreter/oop.txi: Ditto.
+
+2008-10-15  David Bateman  <dbateman at free.fr>
+
+	* interpreter/oop.txi: New file.
+	* interpreter/Makefile.in (SUB_SOURCES): Add it here.
+	(POLYNOMIAL_FILES_NODIR): New varaible for polynomial example class
+	methods.
+	(EXAMPLE_FILES_NODIR): Add POLYNOMIAL_FILES_NODIR here.
+	* interpreter/octave.texi: Reference new OOP chapter here.
+	* interpreter/func.txi: Document private directories and function
+	precedence here.
+	
+2008-10-16  Thorsten Meyer  <thorsten.meyier at gmx.de>
+        * interpreter/contrib.txi: added recommendation of limited
+          line width in code examples
+          
+2008-10-03  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* interpreter/contrib.txi: added example for mercurial queues
+
+08-10-03  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * interpreter/contrib.txi: correction of the mercurial example
+        * interpreter/container.txi: minor correction of the text
+
+2008-09-25  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/image.txi: Update for imread and imwrite instead of
+	loadimge and saveimage.
+
+2008-09-24  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/image.txi: Document imfinfo.
+
+2008-09-23  Francesco Potorti`  <Potorti at isti.cnr.it>.
+
+	* interpreter/container.txi: Fix cross reference in struct docs.
+
+2008-09-23  Brian Gough  <bjg at network-theory.co.uk>
+
+	* interpreter/matrix.txi: Update docs for random number generators.
+
+2008-09-22  David Bateman  <dbateman at free.fr>
+
+	* faq/Octave-FAQ.texi: Update for Octave 3.1.51 and Matlab 2008a.
+
+2008-09-15  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Minor clarificiation
+
+2008-08-28  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/func.txi, interpreter/plot.txi: Doc fixes
+	suggested by Francesco Potorti` <Potorti at isti.cnr.it>.
+
+2008-08-28  David Bateman  <dbateman at free.fr>
+
+	* interpreter/plot.txi: Add description of data sources and line
+	series objects.
+
+2008-08-26  David Bateman  <dbateman at free.fr>
+
+	* interpreter/plot.txi: Document the group objects (bar, stem,
+	stair, quiver and area series), and cllback functions.
+
+2008-08-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* interpreter/contrib.txi: New file.
+	* interpreter/octave.texi: Include it here.
+	* interpreter/Makefile.in (SUB_SOURCE): Add contrib.txi to the list.
+
+2008-08-21  David Bateman  <dbateman at free.fr>
+
+	* interpreter/plot.txi: Document ezplot.
+	
+2008-08-19  David Bateman  <dbateman at free.fr>
+
+	* interpreter/numbers.txi: Document intwarning.
+
+2008-08-06  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/basics.txi, interpreter/errors.txi,
+	interpreter/expr.txi, interpreter/func.txi,
+	interpreter/numbers.txi: Update format of error messages in examples.
+
+2008-07-29  David Bateman  <dbateman at free.fr>
+
+	* interpreter/numbers.txi, interpreter/plot.txi,
+	interpreter/quad.txi: Miscellaneous documentation fixes.
+
+	* control.txi, finance.txi, quaternion.txi: Delete.
+	* octave.texi: Remove all references to the above.
+	* Makefile.in: ditto.
+
+2008-07-28  David Bateman  <dbateman at free.fr>
+
+	* interpreter/arith.txi: Document reallog, realpow and realsqrt.
+	* interpreter/dbug.txi: Document the means of setting a breakpoint
+	in a sub-function
+	* interpreter/func.txi: Document nargoutchk and symvar.
+	* interpreter/geometry.txi: Document rectint.
+	* interpreter/image.txi: Document contrast.
+	* interpreter/interp.txi: Document interp1q.
+	* interpreter/linalg.txi: Document planerot, rcond and subspace.
+	* interpreter/numbers.txi: Document data type demotion and single
+	precision data type.
+	* interpreter/plot.txi: Document ginput, gtext,
+	waitforbuttonpress, ezcontour, ezcontourf, ezpolar, ezplot3,
+	ezmesh, ezmeshc, ezsurf, ezsurfc, allchild, findobj and findall
+	functions.
+	* interpreter/quad.txi: Document quadv, quadgk, dblquad and
+	triplequad functions.
+	* interpreter/strings.txi: Document validstring, regexptranslate
+	and isstrprop functions.
+	* interpreter/system.txi: Document addtodate, filemarker and perl
+	functions.
+	* interpreter/var.txi: Document the genvarname and namelengthmax
+	functions.
+	* interpreter/octave.texi: Update table of contents for the above
+	changes.
+
+	* interpreter/plot.txi: Document contourf.
+
+	* interpreter/plot.txi: Clarify the description of OuterPosition
+	axes property.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* interpreter/debug.txi: Uodate documentation for multiline
+	input. Add documentation for dbcont, dbquit, dbstep, dbstqck, dbup
+	and dbdown functions.
+	* interpreter/octave.texi: Upodate index for debugging functions.
+
+2008-05-03  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/expr.txi, interpreter/tips.txi: Use ischar instead of
+	deprecated isstr.
+
+2008-04-02  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Document spaugment.
+
+2008-03-26  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/mkoctfile.1: Remove spurious whitespace before macros
+
+2008-03-25  David Bateman  <dbateman at free.fr>
+
+	* interpreter/strings.txi: Document hex2num, num2hex.
+	
+2008-03-21  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Document amd function.
+
+2008-03-19  Michael D. Godfrey  <godfrey at isl.stanford.edu>
+
+	* interpreter/plot.txi: Reorder symbol character table.
+
+2008-03-18  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/octave.1, interpreter/mkoctfile.1:
+	Escape "-" signs that mean the "minus" character.
+
+2008-03-12  David Bateman  <dbateman at free.fr>
+
+	* interpreter/io.txi: Document dlmread, dlmwrite, csvread and
+	csvwrite.
+
+2008-02-25  Ben Abbott  <bpabbott at mac.com>
+
+	* interpreter/geometryimages.m, interpreter/interpimages.m,
+	interpreter/plotimages.m, interpreter/sparseimages.m:
+	Use cstrcat instead of strcat.
+
+2008-02-22  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Remove refernces to spdiag, spcumprod,
+	spcumsum, spprod, spsum, spsumsq, spchol, spchol2inv, spcholinv,
+	spinv and splu.
+
+2008-02-20  David Bateman  <dbateman at free.fr>
+ 
+ 	* interpreter/sparse.txi: Remove references to spmin, spmax,
+ 	spatan2, spfind, spqr and spdet.
+ 	
+2008-02-19  Carlo de Falco  <kingcrimson at tiscali.it>
+
+	* interpreter/package.txi: Improve INDEX file documentation.
+
+2008-01-18  Ben Abbott  <bpabbott at mac.com>
+
+	* interpreter/intro.txi: Replaced reference to deprecated
+	function struct_elements with filenames.
+
+2008-02-08  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/octave.1: Dropped unknow LO macro
+	* interpreter/octave-bug.1: Likewise	
+
+2008-02-07  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Remove references to spkron.
+
+2008-02-06  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (stmp-html, HTML): New targets.
+	($(HTML_IMAGES_PNG)): Also depend on stmp-html.
+	Don't create HTML directory here.
+
+2007-12-28  John W. Eaton  <jwe at octave.org>
+
+	Merge changes from object branch:
+
+	2007-06-20  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/var.txi, interpreter/io.txi:
+	Eliminate print_answer_id_name.
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+2007-12-13  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (conf.texi): Also depend on $(top_srcdir)/src/version.h.
+
+2007-12-05  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/geometryimages.m (image_as_txt): New function.
+	Use it to generate "figures" for Info format.
+	* interpreter/interpimages.m: Likewise.
+	* interpreter/sparseimages.m: Likewise.
+
+2007-12-04  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/sparseimages.m, interpreter/plotimages.m,
+	interpreter/interpimages.m, interpreter/geometryimages.m:
+	Set default text font to "*" for png images.
+
+	* interpreter/Makefile.in (run-octave): Don't sleep.
+
+2007-12-04  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* interpreter/plotimages.m: Generate text plots.
+	* interpreter/sparseimages.m: Add initial blank line to text plots.
+
+	* interpreter/Makefile.in (IMAGES_TXT): Include $(INTERPIMAGES_TXT)
+	$(GEOMETRYIMAGES_TXT) and $(PLOTIMAGES_TXT) in the list.
+	(INTERPIMAGES_TXT, GEOMETRYIMAGES_TXT, PLOTIMAGES_TXT): New variables.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Document condest.
+	* interpreter/plot.txi: Document the new text properties and the
+	TeX interpreter mode of text objects.
+	* interpreter/plotimages.m: Add an example for the TeX
+	interpreter.
+	* interpreter/Makefile.in (PLOTIMAGES): Add the TeX example
+
+	* interpreter/plot.txi: Document caxis.
+	* interpreter/image.txi: Document gmap40.
+
+2007-11-12  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* interpreter/gpl.txi: Move index commands after sectioning commands.
+
+2007-11-09  David Bateman  <dbateman at free.fr>
+
+	* interpreter/plot.txi: Document the new hidden and area functions.
+
+2007-11-07  David Bateman  <dbateman at free.fr>
+
+	* interpreter/plot.txi: Document new functions.
+
+2007-10-30  David Bateman  <dbateman at free.fr>
+
+	* interpreter/dynamic.txi, interpreter/install.txi,
+	interpreter/stats.txi, interpreter/strings.txi,
+	interpreter/testfun.txi, interpreter/tips.txi:
+	Doc fixes for small book format.
+
+2007-10-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* interpreter/Makefile.in, faq/Makefile.in, liboctave/Makefile.in:
+	Use temporary renamed files instead of Don't use --output option
+	argument for texi2[dvi|pdf].  Use $(sepchar) for path element
+	separation when building TEXINPUTS.  Remove use of UNSETCOMSPEC trick.
+
+2007-10-22  Kim Hansen  <kimhanse at gmail.com>
+
+	* interpreter/munge-texi.cc: Include <cstdlib> and <cstring>.
+
+2007-10-19  David Bateman  <dbateman at free.fr>
+
+	* refcard/refcard.tex: Update for 3.0.
+
+2007-10-15  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/preface.txi, interpreter/basics.txi,
+	interpreter/strings.txi, interpreter/container.txi,
+	interpreter/var.txi, interpreter/expr.txi, interpreter/errors.txi,
+	interpreter/io.txi, interpreter/func.txi, interpreter/package.txi:
+	Make text fit on pages when using smallbook.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+2007-10-11  Brian Gough  <bjg at network-theory.co.uk>
+
+	* interpreter/dynamic.txi, interpreter/geometry.txi,
+	interpreter/package.txi, interpreter/sparse.txi,
+	interpreter/system.txi: Spelling fixes.
+
+2007-10-10  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* interpreter/arith.txi, interpreter/basics.txi,
+	interpreter/container.txi, interpreter/dynamic.txi,
+	interpreter/eval.txi, interpreter/expr.txi, interpreter/func.txi,
+	interpreter/geometry.txi, interpreter/intro.txi,
+	interpreter/numbers.txi, interpreter/plot.txi,
+	interpreter/poly.txi, interpreter/set.txi, interpreter/sparse.txi,
+	interpreter/stmt.txi, interpreter/strings.txi,
+	interpreter/testfun.txi, interpreter/tips.txi: Spelling fixes. 
+
+2007-10-06  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/octave.texi: Add David Bateman and S�ren Hauberg as
+	authors.
+
+2006-09-28  Henry Mollet  mollet at pacbell.net
+
+	* interpreter/func.txi: Correct results of a couple of examples.
+
+2007-09-14  John W. Eaton  <jwe at octave.org>
+
+	* faq/Makefile.in: Create single Octave-FAQ.html file instead of a
+	splitting files into HTML directory.
+
+2007-09-05  David Bateman  <dbateman at free.fr>
+
+        * interpreter/system.m: Document gzip.
+        * interpreter/container.txi: Document celldisp.
+        * interpreter/matrix.txi: Document bsxfun.
+        * interpreter/data.txi: Document typecast and swapbytes. 
+        * interpreter/container.txi: Document struct2cell.
+        * interpreter/stats.txi: Document mode.
+        * interpreter/eval.txi: Document run.
+
+2007-09-01  David Bateman  <dbateman at free.fr>
+
+	* interpreter/Makefile.in: Remove stray character from
+	INTERIMAGES_PNG target. 
+	* conf.texi.in: Substitute for the variable TEXINFO_QHULL
+	* interpreter/geometryimages.m: Check for the HAVE_QHULL build
+	flag before creating certain figures.
+	* interpreter/geometry.txi: Check whether TEXINFO_QHULL is set
+	before including certain figures.
+
+2007-08-31  S�ren Hauberg  <hauberg at gmail.com>
+
+        * interpreter/nonlin.txi: Extended the example.
+
+        * interpreter/poly.txi: Sectioning and documentation.
+        * interpreter/octave.texi: Adapt to changes in poly.txi.
+
+2007-08-30  David Bateman  <dbateman at free.fr>
+
+	* interpreter/geometryimages.m: Add inpolygon example
+	* interpreter/Makefile.in (GEOMETRYIMAGES): Add inpolygon example.
+	* interpret/geometry.txi: Document inpolygon.
+
+2007-08-27  David Bateman  <dbateman at free.fr>
+
+	* interpreter/struct.txi: Remove.
+	* interpreter/containers.txi: Combine with this chapter. Add
+	examples, and section on comma separated lists. Document the
+	difference between "c(1,:) = []" and c{1,:} = []" for a cell
+	arrays.
+	* interpreter/octave.texi: Document new indexing of containers
+	section.
+
+2007-08-25  David Bateman  <dbateman at free.fr>
+
+        * interpreter/geometry.txi: Add examples and explanatory text.
+        * interpreter/octave.texi: Update indexing of geometry functions.
+	* interpreter/geometryimage.m: New script to create images for
+	geometry chapter.
+	* interpreter/Makefile.in (SCRIPT_SORCES): add geometryimages.m
+	(GEOMETRYIMAGES*): New variables.
+	(IMAGES_EPS, IMAGES_PDF, IMAGES_PNG): Add the GEOMETRYIMAGES*.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+        * interpreter/geometry.txi: Document new functions.
+        * interpreter/octave.texi: Update indexing of geometry items.
+
+2007-07-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (run-octave): Don't set DISPLAY.
+
+2007-07-25  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in, faq/Makefile.in, interpreter/Makwfile.in, 
+	liboctave/Makefile.in, refcard/Makefile.in:  Adjust DISTFILES 
+	to allow out of tree "make dist" to work.
+
+2007-07-23  David Bateman  <dbateman at free.fr>
+
+	* interpreter/Makefile.in (SUB_SOURCE): remove bit.txi.
+	* interpreter/io.txi: Document rat and rats in new sub-section.
+	* interpreter/plot.txi: New section for test functions. Document
+	peaks and meshc.
+	* interpreter/octave.texi: Add test plotting section.
+	* interpreter/image.txi: Document the functions autumn, bone,
+	cool, copper, hot, hsv, jet, pink, prism, rainbow, spring, 
+	summer, white and winter.
+	
+2007-07-19  David Bateman  <dbateman at free.fr>
+
+	* interpreter/bit.xi: Remove.
+	* interpreter/numbers.txi: Move here, and add examples.
+	* interpreter/octave.texi: Remove "Bit manipulation" chapter and make
+	it a sub-section of the "Numeric Data Types" chapter.
+
+2007-07-06  David Bateman  <dbateman at free.fr>
+
+        * interpreter/arith.txi: Add accumarray.
+
+2007-06-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/stats.txi: Reorganize sections and add introductory text.
+
+	* interpreter/octave.texi: Update to reflect changes in stats.txi.
+
+2007-06-18  David Bateman  <dbateman at free.fr>
+
+	* interpreter/interpimages.m: Simpler images to demonstrate
+	the continuity of the second derivative of splines.
+	* interpreter/interp.txi: Also change figures here.
+	* interpreter/Makefile.in: and here.
+	
+2007-06-18  S�ren Hauberg  <hauberg at gmail.com>
+
+        * interpreter/optim.txi: Added some introductory text to each
+	section.
+
+        * interpreter/set.txi: Added some introductory text.
+        * interpreter/octave.texi: Updated to reflect changes in set.txi.
+
+2007-06-15  David Bateman  <dbateman at free.fr>
+
+	* faq/Octave-FAQ.texi: Document the gnuplot 4.2 bug using pipes.
+
+2007-06-15  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* interpreter/testfun.txi: Provide a clue to using xtest for assert.
+
+2007-06-14  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* interpreter/testfun.txi: Document xtest block
+
+2007-06-14  David Bateman  <dbateman at free.fr>
+
+	* interpreter/Makefile.in (SCRIPT_SORCES): add interimages.m
+	(INTERPIMAGES*): New variables. Add targets for them
+	(IMAGES_EPS, IMAGES_PDF, IMAGES_PNG): Add the INTERPIMAGES.
+	* interpreter/interpimages.m: New function
+	* interpreter/interp.txi: Add text about second derivation of
+	splines	and add figures.
+
+2007-06-12  David Bateman  <dbateman at free.fr>
+
+	* interpreter/numbers.txi: Document that 64-bit arithmetic is
+	not possible.
+
+2007-06-12  David Bateman  <dbateman at free.fr>
+
+	* interpreter/interp.txi: Split into two section and document
+	interp3 and the differences in the treatement of the dimensions
+	between interpn and interp3.
+	* hashing.txi: Remove.
+	* system.txi: Move it here as a subsection. Include explanation
+	and example.
+	* interpreter/octave.texi: Add sections for the Interpolation
+	chapter. Remove references to Hashing chapter and hashing.texi,
+	and subsections for hashing to system utilities chapter.
+
+
+2007-06-12  2007-06-10  S�ren Hauberg  <hauberg at gmail.com>
+
+        * interpreter/diffeq.txi: Note that x-dot is the derivative of x.
+
+2007-06-03  David Bateman  <dbatemna at free.fr>
+
+	* interpreter/dynamic.txi: Use "mwSize" and "mwIndex" rather than
+	"int" for indexing in mex-files and document them.
+	
+2007-05-30  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (TEXI2DVICOMMAND, TEXI2PDFCOMMAND):
+	New macros.
+	(octave-a4.pdf, octave-smallbook.pdf): New targets.
+	(FORMATTED, all): Include octave-a4.pdf in list of dependencies.
+	Delete octave.dvi and octave.ps from list.
+	(FORMATTED, all): Use $(PDF_TARGETS).
+	(maintainer-clean): Depend on clean.
+
+2007-05-30  G. D. McBain  <gdmcbain at freeshell.org>
+
+	* interpreter/expr.txi (Assignment Ops): Doc fix.
+
+2007-05-29  Steven Mestdagh  <steven.mestdagh at esat.kuleuven.be>
+
+	* interpreter/Makefile.in ($(HTML_IMAGES_PNG)): Use cp instead of
+	INSTALL_DATA to copy files to the HTML directory.
+
+2007-05-28  S�ren Hauberg  <hauberg at gmail.com>
+
+        * interpreter/errors.txi: Add new sections and some more detailed
+	descriptions on errors and warnings.
+        * interpreter/octave.texi, interpreter/stmt.txi,
+	interpreter/var.txi: Add references to the new sections in
+	errors.txi.
+
+2007-05-28  S�ren Hauberg  <hauberg at gmail.com>
+
+        * interpreter/io.txi: Rearrange some sections, and add
+        a few examples.
+
+2007-05-28  G. D. McBain  <geordie_mcbain at yahoo.com.au>
+
+	* interpreter/struct.txi: Doc fix.
+
+2007-05-23  John W. Eaton  <jwe at octave.org>
+
+	* liboctave/Makefile.in (TEXINFO_SOURCE): New variable.
+	(TEXINFO): Define using $(TEXINFO_SOURCE).
+	(DISTFILES): Include $(TEXINFO_SOURCE) in the list, not $(TEXINFO).
+
+2007-05-22  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (TEXINFO_SOURCE): New variable.
+	(TEXINFO): Define using $(TEXINFO_SOURCE).
+	(DISTFILES): Include $(TEXINFO_SOURCE) in the list, not $(TEXINFO).
+
+2007-05-22  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* faq/Octave-FAQ.texi, interpreter/basics.txi,
+	refcard/refcard.tex: Fix typos.
+
+2007-05-22  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (DISTFILES): Add mkcontrib.awk to the list.
+
+2007-05-21  David Bateman  <dbatemna at free.fr>
+
+	* interpreter/debug.txi, io.txi, octave.txi: Doc fixes.
+
+2007-05-21  S�ren Hauberg  <hauberg at gmail.com>
+
+        * interpreter/expr.txi: Describe +=, -=, *=, and /= operators.
+	Add new example.
+
+        * interpreter/eval.txi: Partition the chapter into sections.
+        Describe evalin and assignin functions using text from Paul
+	Kienzle.  Change "See See" to "See".  Use @ref instead of @xref to
+	avoid "See" to be written with a capital letter in the middle of a
+	sentence.
+
+        * interpreter/func.txi: New section describing load path.
+        Improve 'inline' and 'command' sections.
+
+        * interpreter/stmt.txi: Describe cell array cases for the switch
+	statement.  Minor layout changes.
+
+2007-05-19  David Bateman  <dbatemna at free.fr>
+
+	* interpreter/func.txi: Additional documentation for function
+	locking, dispatch and autoloading.
+
+2007-05-16  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/expr.txi: Improve docs.
+
+2007-05-14  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/basics.txi, interpreter/data.txi,
+	interpreter/intro.txi, interpreter/numbers.txi,
+	interpreter/octave.texi, interpreter/preface.txi: Doc fixes.
+
+2007-04-18  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/package.texi: Document "*" flag for loaded packages.
+
+	* interpreter.var.txi: Improve explanation of clear, exist, and who.
+
+	* interpreter/intro.txi: Change @unnumberedsubsec to @subsection.
+
+	* interpreter/container.txi: Doc fix.
+
+	* interpreter/strings.txi: Improve explanation for creating
+	comparing, and converting strings.
+	* interpreter/octave.texi: Update detailed menu.
+
+2007-05-09  David Bateman  <dbateman at free.fr>
+
+	* faq/Octave-FAQ.texi: Update compatibility section.
+
+2007-04-27  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (EXAMPLE_FILES_NODIR): Add mycell.c, myfeval.c,
+	myfunc.c, mypow2.c, mysparse.c, mystring.c, mystruct.c and
+	paramdemo.cc.
+	* interpreter.txi/dynamic.txi: Complete all but the section on
+	the mex- and oct-file APIs.
+
+2007-04-26  David Bateman  <dbateman at free.fr>
+
+	* interpreter/stmt.txi: Document for loops over matrices, arrays
+	and cell arrays.
+
+2007-04-25  David Bateman  <dbateman at free.fr>
+
+	* interpreter/dynamic.txi: Add additional copyrights. Add sections
+	of input parameter checking, documentation and testing of
+	oct-files. Adds a section on calling other functions from
+	mex-files, expands the basic information on mex-files, and add a
+	few new sections (to be completed) to the section about mex-files
+
+2007-04-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/dynamic.txi: Use abs_top_srcdir to find example files.
+
+2007-04-25  David Bateman  <dbateman at free.fr>
+
+	* conf.texi.in: Also set abs_top_srcdir with substitution.
+	* Makefile.in: Substitute abs_top_srcdir here.
+
+2007-04-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/dynamic.txi: Use @verbatiminclude for example code.
+
+	* interpreter/Makefile.in (EXAMPLE_FILES_NODIR, EXAMPLE_FILES):
+	New variables.
+	(octave.info, octave.dvi, octave.pdf, HTML/index.html):
+	Depend on $(EXAMPLE_FILES).
+
+	* conf.texi.in: Also set top_srcdir with substitution.
+
+	* interpreter/tips.txi: Update with new text and examples.
+	Move documentation section to the end.
+
+2007-04-24  David Bateman  <dbateman at free.fr>
+
+	* interpreter/octave.texi: Include dynamic.texi as appendix and
+	update menus.
+
+	* interpreter/plot.txi: Update menus.
+
+	* interpreter/strings.txi: @result -> @result{}.
+
+	* intrepreter/func.txi, intrepreter/sparse.txi:
+	Delete .oct file section and update menus.
+
+	* interpreter/addtwomatrices.cc, interpreter/celldemo.cc,
+	interpreter/fortdemo.cc, interpreter/funcdemo.cc,
+	interpreter/globaldemo.cc, interpreter/helloworld.cc,
+	interpreter/stringdemo.cc, interpreter/structdemo.cc,
+	interpreter/unwinddemo.cc, interpreter/fortsub.f,
+	interpreter/dynamic.txi: New files.
+
+	* Makefile.in (SUB_SOURCE): Include dynamic.txi in the list.
+
+2007-04-18  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/package.texi: New file.
+	* octave/texi: @include it, add it to the menus.
+
+2007-04-18  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/contributors.in: New file.
+	* interpreter/Makefile.in (contributors.texi): New target.
+	(clean): Also deleete contributors.texi
+	(TEXINFO): Include contributors.texi in the list.
+	(preface.texi): @include contributors.texi.
+
+2007-04-17  David Bateman  <dbateman at free.fr>
+
+	* interpreter/linalg.txi (Techniques used for Linear Algebra):
+	New node.
+	* interpreter/octave.texi: Include it in menu.
+	* interpreter/sparse.txi: Delete discusion of matrix_type.
+
+2007-04-16  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/stream.txi: Delete.
+	* interpreter/Makefile.in (SUB_SOURCE): Remove it from the list.
+
+2007-04-16  S�ren Hauberg  <hauberg at gmail.com>
+
+	* intrepreter/stmt.txi: Improve documentation of switch statement.
+
+	* interpreter/tips.txi: Update description of how copyright
+	statements are recognized.
+
+	* interpreter/octave.texi: Don't include stream.texi.
+	Remove menu entry for I/O streams.
+
+	* interpreter/image.txi: Update docs.
+
+2007-04-11  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/container.txi: Document indexing with ().
+
+2007-04-11  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/container.txi: Improve cell array documentation.
+
+2007-04-09  S�ren Hauberg  <hauberg at gmail.com>
+
+	* interpreter/func.txi: Document varargin, varargout, and default
+	argument values.
+
+2007-04-03  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/basics.txi: Clarified some limitations of the #!
+	script mechanism, in particular related to the parsing of the
+	arguments.
+
+2007-03-29  Rafael Laboissiere  <rafael at debian.org>
+
+	* faq/Octave-FAQ.texi, interpreter/basics.txi,
+	interpreter/emacs.txi, interpreter/func.tx, interpreter/var.txi:
+	Make it clear that the old built-in LOADPATH is an internal
+	variable, accessible through path ().
+	Drop references to DEFAULT_LOADPATH.
+	Chang references to the old built-in variables INFO_FILE and
+	INFO_PROGRAM to the respective fucntions info_file and
+	info_program.
+	* refcard/refcard.tex: Drop LOADPATH from list of built-in variables.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in, interpreter/Makefile.in, faq/Makefile.in,
+	liboctave/Makefile.in, refcard/Makefile.in (dist):
+	Use ln instead of $(LN_S).
+
+2007-03-21  G. D. McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* interpreter/sparse.txi: Delete repeated word.
+
+2007-03-20  G. D. McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* interpreter/sparse.txi: Clarify sparse matrix creation example.
+
+2007-03-14  G. D. McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* interpreter/sparse.txi: Fix typo.
+
+2007-02-26  From Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in, interpreter/Makefile.in, faq/Makefile.in,
+	liboctave/Makefile.in, refcard/Makefile.in:
+	Use $(LN_S) instead of ln or ln -s.
+
+2007-02-21  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Add functions sprank and normest to
+	documentation.
+
+2007-01-25  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/sparseimages.m: Don't call __gnuplot_x__ functions.
+
+2006-11-17  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/sparseimages.m: Fix call to __plt3__.
+
+2006-11-16  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/sparseimages.m (femimages): Use plot3.
+
+2006-11-11  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (%.texi : %.txi):
+	Use $(simple-move-if-change-rule) here.
+
+2006-10-29  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (run-octave): Call it here.
+	* interpreter/sparseimages.m (sparseimages): Don't call sleep here.
+
+2006-10-27  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (run-octave):
+	Unset DISPLAY while running Octave.
+	From Michael Goffioul <michael.goffioul at swing.be>.
+
+	* interpreter/Makefile.in (octave.dvi, octave.pdf):
+	Use $(UNSETCOMSPEC) in command.
+	* faq/Makefile.in (Octave-FAQ.dvi, Octave-FAQ.pdf): Likewise.
+	* liboctave/Makefile.in (liboctave.dvi, liboctave.pdf): Likewise.
+
+2006-10-09  Thomas Treichl <Thomas.Treichl at gmx.net>
+
+	* interpreter/sparseimages.m: Plot sombrero images if sparse
+	capabilities are missing.
+
+2006-10-04  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (HTML_IMAGES_PNG): New variable.
+	(HTML/index.html): Depend on $(HTML_IMAGES_PNG) instead of html-figs.
+	($(HTML_IMAGES_PNG): HTML/%.png : %.png): New pattern rule.
+	(html-dir): Delete target.
+
+2006-10-03  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/mkoctfile.1: Fix indentation for --mex description.
+
+2006-09-26  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in (stamp-images): Delete.
+	(octave.info): Depend on $(IMAGES_TXT), not stamp-images.
+	(octave.dvi): Depend on $(IMAGES_EPS), not stamp-images.
+	(octave.pdf): Depend on $(IMAGES_PDF), not stamp-images.
+	(html-figs): Depend on $(IMAGES_PNG), not stamp-images.
+	(SCRIPT_SOURCES, SPARSEIMAGES_1, SPARSEIMAGES_EPS,
+	SPARSEIMAGES_PDF, SPARSEIMAGES_PNG, SPARSE_IMAGES_TXT, IMAGES_EPS,
+	IMAGES_PDF, IMAGES_PNG, IMAGES_TXT, and IMAGES): New variables.
+	(SOURCES): Include $(SCRIPT_SOURCES) in the list.
+	(DISTFILES): Include $(IMAGES) in the list.
+	(maintainer-clean): Delete $(IMAGES) here.
+	(DISTSUBDIRS, SUBDIRS): Remove $(IMAGEDIR) from list.
+	(octave.dvi, octave.info, octave.pdf, HTML/index.html):
+	Don't include $(IMAGEDIR) in list of directories to search
+	* sparseimages.m: Move here from images/sparseimages.m.
+	* images/Makefile.in: Delete.
+	* images: Delete directory.
+
+2006-08-24  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/images/Makefile.in (SPARSEIMAGES_PDF): New macro.
+	Keep PDF images out of IMAGES list.
+
+2006-08-18  John W. Eaton  <jwe at octave.org>
+
+	* conf.texi.in: Eliminate TARGETHOSTTYPE variable.
+
+2006-08-17  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/images/Makefile.in (%.pdf : %eps):
+	Use $(GHOSTSCRIPT) instead of gs.
+
+2006-08-14  Dmitri A. Sergatskov  <dasergatskov at gmail.com>
+
+	* interpreter/images/sparseimages.m: Adapt to new automatic_replot
+	definition.
+	
+2006-06-27  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/Makefile.in: Elminate double-colon rules.
+
+2006-05-31  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/images/Makefile.in (run-octave):
+	Use $(TOPDIR)/run-octave script to execute Octave.
+	(OCTAVE_BINARY, OCTAVE_SCRIPT_PATH, OCTAVE_LD_LIBRARY_PATH,
+	XLD_LIBRARY_PATH, SET_LD_LIBRARY_PATH): Delete variables.
+
+2006-04-06  Keith Goodman  <kwgoodman at gmail.com>
+
+	* interpreter/mkoctfile.1: Doc string fix.
+
+2006-04-03  David Bateman  <dbateman at free.fr>
+
+	* interpreter/matrix.txi: Add rande, randp, randg and update
+          for different random generator behavior.
+
+2006-03-28  John W. Eaton  <jwe at octave.org>
+
+	* texinfo.tex: Update FSF address.
+
+2006-03-27  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/images/sparseimages.m: Fix missing endif.  Omit
+	unnecessary call to axis.
+
+2006-03-24  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/images/sparseimages.m:
+	Avoid some unnecessary calculations.
+
+2006-03-22  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/sparse.txi: Undo previous change.
+	Always use @image to include image files.
+	* interpreter/Makefile.in: Eliminate stamp files.
+	(clean, mostlyclean, distclean, maintainer-clean): Now
+	double-colon targets.
+	(stamp-images): New target.
+	(octave.info, octave.dvi, octave.pdf, HTML/index.html): Depend on it.
+	* interpreter/images/Makefile.in: Explicitly list images to be
+	created and their dependencies.
+	* interpreter/images/sparseimages.m (sparseimage): Delete dirc arg.
+	Sleep for 1 second before returning.
+	(txtimages): Also create gplot.txt and grid.txt.
+	(sparseimages): Don't redirect output here.
+	New arg, nm.  Only output a single figure at a time.
+	(bury_output): New function.  Use it before plotting commands and
+	after every print function.
+	* Makefile.in (conf.texi): New target.
+	(DISTFILES): Include conf.texi in the list.
+	(all, dist): Depend on conf.texi.
+	* conf.texi.in: Values come from Makeconf, not configure.
+
+2006-03-21  John W. Eaton  <jwe at octave.org>
+
+	* liboctave/Makefile.in (FORMATTED): Omit .html files here.
+	(DISTDIRS): New variable.
+	(dist): Handle $(DISTDIRS) here.
+
+	* faq/Makefile.in (FORMATTED): Omit .html files here.
+	(DISTDIRS): New variable.
+	(dist): Handle $(DISTDIRS) here.
+
+	* interpreter/Makefile.in (FORMATTED): Omit .html files here.
+	(DISTDIRS): New variable.
+	(dist): Handle $(DISTDIRS) here.
+
+	* interpreter/sparse.txi: Temporarily omit figures.
+	* interpreter/Makefile.in: Temporarily omit actions for making figures.
+	(DISTSUBDIRS): New macro.
+	(dist): Recurse into $(DISTSUBDIRS) here.
+
+	* interpreter/Makefile.in (real-pdf): Depend on stamp-eps
+	(stamp-pdf): Depend on real-pdf.  Touch stamp-pdf here.
+	(real-pdf): Not here.
+
+2006-03-16  David Bateman  <dbateman at free.fr>
+
+	* interpreter/images/sparseimages.m: set terminal type to dummy to
+	direct output to terminal rather than X11.
+	* interpreter/sparse.txi: Update docs for new QR solvers.
+	
+2006-03-09  David Bateman  <dbateman at free.fr>
+
+	* interpreter/Makefile.in: Change order of commands in HTML/index.html
+	target. Respawn make for stamp-pdf target so that $(wildcard *.eps) is
+	reinterpreted.
+	* interpreter/sparse.txi: Isolate conditionally built targets in
+	"@ifset ... @end ifset".
+
+2006-03-08  David Bateman  <dbateman at free.fr>
+
+	* conf.texi: Remove.
+	* conf.texi.in: New file, for autoconf'ed version of conf.texi.
+	* Makefile.in: replace conf.texi with conf.texi.in in DISTFILES
+	* interpreter/Makefile.in: build in subdir IMAGEDIR, add stamps for
+	image files. Copy png-files to HTML directory. Build pdf files from
+	eps files using epsffit, gs, grep, basename, head and awk.
+	* octave.texi: Update sparse sub-sections.
+	* sparse.txi: Updates for current state of sparse code.
+	* interpreter/images/Makefile.in: New file.
+	* interpreter/images/sparseimages.m: New file to build sparse images.
+
+2006-03-07  David Bateman  <dbateman at free.fr>
+
+	* liboctave/dae.texi, liboctave/factor.texi, liboctave/nleqn.texi,
+	liboctave/quad.texi, liboctave/matvec.texi, liboctave/nlfunc.texi,
+	liboctave/diffeq.texi, liboctave/array.texi, liboctave/range.texi,
+	liboctave/optim.texi: Fix some syntax problems for texinfo.tex 4.8.
+
+2006-03-06  Keith Goodman  <kwgoodman at gmail.com>
+
+	* interpreter/octave.texi (@seealso): Display args instead of
+	discarding them.
+
+2006-03-02  John W. Eaton  <jwe at octave.org>
+
+	* faq/Makefile.in (Octave-FAQ.ps): Depend on Octave-FAQ.dvi, not
+	$(TEXINFO).
+
+	* texinfo.tex: Update to 2004-11-25.16 version from Texinfo 4.8.
+
+2005-12-14  David Bateman  <dbateman at free.fr>
+
+	* interpreter/testfun.txi: New test/demo documentation.
+	* interpreter/strings.txi: Include regexp/regexi docstrings.
+	* interpreter/octave.texi: Include test/demo appendix.
+	* interpreter/Makefile.in (SUB_SOURCE): Include test.txi.
+
+2005-12-13  David Bateman <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Add new gplot, etreeplot and treeplot
+	functions.
+
+2005-11-01  John W. Eaton  <jwe at octave.org>
+
+	* liboctave/Makefile.in (maintainer-clean): Also remove liboctave.pdf
+	* faq/Makefile.in (maintainer-clean): Also remove Octave-FAQ.pdf.
+	From Quentin Spencer <qspencer at ieee.org>.
+
+2005-10-23  David Bateman  <dbateman at free.fr>
+
+	* sparse.txi: Updates for new ufsparse licensing, new functions and
+	various typos.
+
+2005-09-19  Rafael Laboissiere  <rafael at debian.org>
+
+	* interpreter/octave-config.1: Use bold instead of italics to
+	markup command name.
+
+2005-07-29  John W. Eaton  <jwe at octave.org>
+
+	* faq/Makefile.in (HTML/index.html): Pass --ifinfo to makeinfo.
+	* interpreter/Makefile.in (HTML/index.html): Likewise.
+	* liboctave/Makefile.in (HTML/index.html): Likewise.
+
+2005-07-28  John W. Eaton  <jwe at octave.org>
+
+	* faq/Makefile.in, interpreter/Makefile.in, liboctave/Makefile.in:
+	Use makeinfo instead of texi2html to generate HTML.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* interpreter/munge-texi.cc (skip_comments): New function.
+	(process_doc_file): Use it to skip comments at beginning of file.
+
+2005-04-29  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Add matrix_type, spkron, and document
+	changes in solve code.
+
+2005-03-14  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: Add luinc function.
+
+2005-03-09  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (bin-dist): Delete target.
+	(BINDISTSUBDIRS): Delete variable.
+
+	* refcard/Makefile.in (bin-dist): Delete target.
+	(BINDISTFILES): Delete variable.
+	* liboctave/Makefile.in: Likewise.
+	* interpreter/Makefile.in: Likewise.
+	* faq/Makefile.in: Likewise.
+
+2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	Sparse merge.
+
+	2005-01-07  David Bateman  <dbateman at free.fr>
+
+	* interpreter/sparse.txi: New file.
+	* interpreter/Makefile.in: Add it to the build.
+	* interpreter/octave.texi: Include it in the contents tables and the
+	top level document.
+
+2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	* liboctave/Makefile.in (all): Also depend on Octave-FAQ.pdf.
+	Use $(MAKEINFO) instead of makeinfo in rules.
+
+2005-02-25  Rafael Laboissiere  <rafael at debian.org>
+
+	* liboctave/Makefile.in (Octave-FAQ.pdf): New target and rule.
+	(FORMATTED): Add Octave-FAQ.pdf to the list.
+
+2005-02-21  John W. Eaton  <jwe at octave.org>
+
+	* liboctave/Makefile.in (liboctave.pdf): New target and rule.
+	(FORMATTED): Add liboctave.pdf to the list.
+	(all): Also depend on liboctave.pdf.
+	Use $(MAKEINFO) instead of makeinfo in rules.
+
+	* interpreter/Makefile.in (octave.pdf): New target and rule.
+	(FORMATTED): Add octave.pdf to the list.
+	(all): Also depend on octave.pdf.
+	Use $(MAKEINFO) instead of makeinfo in rules.
+
+2005-02-08  Quentin Spencer  <qspencer at ieee.org>
+
+	* interpreter/plot.txi: Emphasize compatible plotting functions
+	over gplot and friends.
+
+2004-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* liboctave/Makefile.in (FORMATTED): Use liboctave*.html instead
+	of liboctave_*.html.
+
+	* faq/Makefile.in (FORMATTED): Use Octave-FAQ*.html instead of
+	Octave-FAQ_*.html.
+
+2004-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* faq/Makefile.in (maintainer-clean): Remove Octave-FAQ*.html
+	instead of just Octave-FAQ_*.html.
+
+	* liboctave/Makefile.in (maintainer-clean): Remove liboctave*.html
+	instead of just liboctave_*.html.
+
+	* refcard/Makefile.in (maintainer-clean): Remove refcard-*.pdf.
+
+2003-12-09  Eric S. Raymond  <esr at thyrsus.com>
+
+	* interpreter/mkoctfile.1: Use .I instead of .f for markup of ".oct".
+
+2003-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/munge-texi.cc (process_texi_input_file):
+	Avoid -Wshadow warnings.
+
+2003-08-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* refcard/Makefile.in (refcard-a4.pdf, refcard-legal.pdf,
+	refcard-letter.pdf): New targets.
+	(FORMATTED): Add them to the list.
+	* refcard/refcard.tex: Optionally set pdf paper size parameters.
+
+2003-08-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (octave_toc.html): Add "-I ." to texinfo
+	command line args.
+
+2003-07-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* faq/Makefile.in (FORMATTED): Include all Octave-FAQ_*.html files
+	here, not just the toc.
+
+2003-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in, liboctave/Makefile.in: Handle DESTDIR.
+
+2003-02-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (MAN_BASE): Add octave-config.1 to the list.
+
+2003-02-19  Dirk Eddelbuettel <edd at debian.org>
+
+	* octave-config.1: New file.
+
+2003-01-11  Paul Kienzle <pkienzle at users.sf.net>
+
+	* interpreter/Makefile.in (munge-texi$(BUILD_EXEEXT)): Pass
+	$(BUILD_CXXFLAGS) and $(BUILD_LDFLAGS) to compiler.
+	(%.o : %.cc): Delete pattern rule.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/munge-texi.cc: Define __USE_STD_IOSTREAM if using
+	Compaq C++.
+
+2002-12-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (%.o : %.c): No longer need
+	-DNO_PRAGMA_INTERFACE_IMPLEMENTATION=1 compiler option.
+	(munge-texi#(BUILD_EXEEXT)): Likewise.
+	Don't link to Map-s.o.
+
+	* interpreter/Map-s.cc: Delete.
+	* interpreter/Makefile.in (DISTFILES): Delete it from the list.
+	(mostlyclean, clean): Don't delete Map-s.o.
+
+	* interpreter/munge-texi.cc: Require working STL.
+
+2002-11-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (maintainer-clean): Depend on
+	clean-texi, don't remove $(TEXINFO).
+
+2002-11-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/munge-texi.cc: Use STL map class by default, but
+	make it easy to revert back to libg++-based Map class if that
+	fails to work on some systems.
+
+2002-11-01  Dirk Eddelbuettel <edd at debian.org>
+
+	* interpreter/Makefile.in (MAN_BASE, MAN_SRC): New variables, use
+	as appropriate.
+
+2002-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+ 	* interpreter/mkoctfile.1: New file.
+	
+2002-10-25  Paul Kienzle <pkienzle at users.sf.net>
+
+	* interpreter/Makefile.in (octave_toc.html): Use -expandinfo and
+	-split_chapter instead of -expand info and -split chapter.
+	* liboctave/Makefile.in (liboctave_toc.html): Likewisel
+	* faq/Makefile.in (Octave-FAQ_toc.html): Likewise.
+
+2002-10-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (munge-texi$(BUILD_EXEEXT)): Always use
+	-DNO_PRAGMA_INTERFACE_IMPLEMENTATION for compiling and linking.
+
+2002-10-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (%.texi : %.txi):
+	Use $(top_srcdir)/move-if-change.
+
+2002-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in: Use $(BUILD_EXEEXT) as appropriate.
+
+2002-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (munge-texi, %.o : %.cc):
+	Use $(BUILD_CXX), not $(CXX).
+	(src-DOCSTRINGS, scripts-DOCSTRINGS): New targets.
+	($(TEXIFNO)): Depend on them.
+	(DOCSTRINGS): Delete variable.
+
+2002-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (%.spell): Use $(SED), not sed.
+	* liboctave/Makefile.in (%.spell): Likewise.
+	* faq/Makefile.in (%.spell): Likewise.
+
+2001-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (octave_toc.html): Use -expand info and
+	-split chapter, to be consistent.
+	* liboctave/Makefile.in (liboctave_toc.html): Likewise.
+	* faq/Makefile.in (Octave-FAQ_toc.html): Likewise.
+
+2001-11-14  Christoph Spiel <cspiel at hammersmith-consulting.com>
+
+	* faq/Makefile.in (Octave-FAQ_toc.html): Use -expandinfo and
+	-split_chapter, not -expand info and -split chapter.
+	* liboctave/Makefile.in (liboctave_toc.html): Likewise.
+
+2001-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (MAIN_TEXINFO): Look in $(srcdir).
+	(octave_toc.html): Use -expandinfo and -split_chapter, not
+	-expand info and -split chapter.
+
+2001-03-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* liboctave/Makefile.in (liboctave_toc.html): Use -expand info and
+	-split chapter instead of -expandinfo and -split_chapter options
+	for texi2html.
+	* faq/Makefile.in (Octave-FAQ_toc.html): Likewise.
+	* interpreter/Makefile.in (octave_toc.html): Likewise.
+
+2000-10-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* liboctave/Makefile.in (liboctave_toc.html): Add space after -I
+	in texi2html command.
+	* interpreter/Makefile.in (octave_toc.html): Ditto.
+
+2000-03-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/octave-bug.1: New file.
+	* interpreter/Makefile.in (install install-strip): Install it.
+	(DISTFILES, BINDISTFILES): Add it to the
+
+2000-02-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (clean): Also delete munge-texi,
+	munge-texi.o, and Map-s.o.
+
+2000-02-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/munge-texi.cc: Sprinkle with std:: qualifier.
+
+2000-01-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (clean-texi): Avoid removing octave.texi.
+
+2000-01-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in: Don't generate octave.texi from octave.txi.
+	* interpreter/octave.texi: Rename from octave.txi.
+
+	* interpreter/munge-texi.cc (process_texi_input_file): Undo
+	previous change, since % doesn't work as a comment character after
+	texinfo.tex is included.
+
+2000-01-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* texinfo.tex: Update to version from texinfo-4.0.
+
+	* interpreter/munge-texi.cc (process_texi_input_file): For Texinfo
+	doc strings, automatically insert an @anchor{doc-SYMBOL} command
+	just before the docstring for SYMBOL.
+
+1999-12-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/munge-texi.cc (process_texi_input_file): Begin
+	transformed files with `% DO NOT EDIT' instead of `@c DO NOT EDIT'
+	to prevent problems with TeX not knowing the definition of @c
+	before it is used.
+
+1999-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (%.texi : %.txi): Suppress command echo.
+
+1999-10-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (dist): Remove .texi files first, so
+	they will have timestamps newer than the $(DOCSTRINGS) files.
+	(%.texi : %.txi): Use mv instead of move-if-change.
+
+	* interpreter/Map-s.cc: New file.
+	* interpreter/munge-texi.cc: Use old libg++ Map class instead of
+	STL map, for the benefit of systems that have assemblers that
+	can't handle the long symbol names generated by g++ for
+	map<string,string>.
+
+1999-10-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/munge-texi.cc: Strip the "-*- texinfo -*-" marker
+	when including help text.
+
+	* interpreter/Makefile.in ($(TEXINFO)): Depend on $(DOCSTRINGS).
+	($(DOCSTRINGS)): New rule.
+
+	* Makefile.in (dist, bin-dist): Use `$(MAKE) -C dir' instead of
+	`cd dir; $(MAKE); cd ..'.
+	(../BUGS, ../INSTALL.OCTAVE, $(SUBDIRS)) Likewise.
+
+	* interpreter/*.txi: Rename from *.txi.
+	* interpreter/munge-texi.cc: New file.
+	* interpreter/Makefile.in: Use it to create .texi files from .txi
+	files and DOCSTRING files.
+
+Fri Jun 18 23:17:02 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (octave_toc.html): Add -expandinfo to
+	tex12html options.
+	* liboctave/Makefile.in (liboctave_toc.html): Likewise.
+	* faq/Makefile.in (Octave-FAQ_toc.html): Likewise.
+
+Fri Oct  9 00:27:33 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* faq/Makefile.in, interpreter/Makefile.in, liboctave/Makefile.in:
+	New rules for generating HTML files from Texinfo sources.
+
+Thu May 14 21:04:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (../../BUGS, ../../INSTALL): Add
+	--no-validate to makeinfo args.
+
+Wed Jul  2 16:41:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* refcard/Makefile.in: Remove .tex files from binary distributions.
+
+	* interpreter/Makefile.in: Add DVI and Postscript files to binary
+	distributions.
+
+Fri Apr 18 02:51:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* faq/Octave-FAQ.texi: Rename from faq/FAQ.texi.
+	* faq/Makefile.in: Fix names to match.
+
+Wed Mar 12 17:01:02 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-strip): New target.
+	* faq/Makefile.in: Ditto.
+	* interpreter/Makefile.in: Ditto.
+	* liboctave/Makefile.in: Ditto.
+	* refcard/Makefile.in: Ditto.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.5 released.
+
+Fri Feb 28 20:53:40 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* texinfo.tex: Update to latest version from Karl Berry, and apply
+	previous patch too.
+
+Thu Feb 27 03:34:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* texinfo.tex (\codeunder): Maybe make it work for @var{} inside
+	@code{}.
+
+Wed Feb 26 12:03:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* refcard/Makefile.in (mostlyclean clean): Delete log files.
+
+	* liboctave/Makefile.in (mostlyclean clean): Delete more stuff.
+
+	* faq/Makefile.in (mostlyclean clean): Delete some stuff.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+Wed Feb 19 10:30:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTFILES): Distribute conf.texi, not conf.texi.in.
+
+	* liboctave/Makefile.in: Don't make or distribute conf.texi.
+	(liboctave.info, liboctave.dvi): Depend on ../conf.texi, not conf.texi.
+
+	* interpreter/Makefile.in: Don't create or distribute conf.texi.
+	(octave.info, octave.dvi): Depend on ../conf.texi, not conf.texi.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.3 released.
+
+Wed Jan 29 11:49:25 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (../INSTALL.OCTAVE, ../BUGS): Declare these to be
+	.PHONY so that we will always check the interpreter makefile to
+	get the proper dependencies.
+
+Mon Jan 27 15:52:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+Sun Jan 26 22:07:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in: Make BUGS file directly from bugs.texi.
+	* interpreter/bugs.texi: Incorporate bugs1.texi directly.
+	* interpreter/bugs1.texi: Delete.
+
+	* interpreter/Makefile.in: Make INSTALL file directly from
+	install.texi.
+	* interpreter/install.texi: Incorporate install1.texi directly.
+	* interpreter/install1.texi: Delete.
+
+Sat Jan 25 22:32:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, interpreter/Makefile.in, liboctave/Makefile.in,
+	faq/Makefile.in, refcard/Makefile.in (bin-dist): New target.
+
+Tue Jan  7 00:17:24 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Tue Dec 10 01:43:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+Fri Dec  6 15:23:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.94.
+
+Wed Nov 20 01:00:50 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.93.
+
+Thu Nov 14 00:07:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* faq/Makefile.in (FAQ.dvi): Use $(TEXI2DVI), not just texi2dvi.
+	* interpreter/Makefile.in (octave.dvi): Likewise.
+	* liboctave/Makefile.in (liboctave.dvi): Likewise.
+
+	* Version 1.92.
+
+Thu Nov  7 12:43:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.91.
+
+	* texinfo.tex: Update to version from texinfo-3.9 distribution.
+
+Wed Oct 30 17:20:28 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* Makefile.in (DISTFILES): Add ChangeLog.
+
+Sat Oct 12 13:38:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (maintainer-clean): Don't depend on distclean.
+
+Sat Jun 15 23:01:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in (TEXINFO): Add audio.texi and emacs.texi.
+
+Fri May 17 03:02:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* interpreter/Makefile.in: Use man1dir instead of mandir, and
+	man1ext instead of manext.
+
+Sat Mar 23 05:01:17 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* liboctave/Makefile.in (TEXINFO): Don't list conf.texi and
+	gpl.texi here.
+
+	* liboctave/Makefile.in (dist targets): Fix ln command.
+	* refcard/Makefile.in (dist targets): Likewise.
+	* interpreter/Makefile.in (dist targets): Likewise.
+	* faq/Makefile.in (dist targets): Likewise.
+
+Fri Mar 22 23:57:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* liboctave/Makefile.in (DISTFILES): Add gpl.texi.
+	* interpreter/Makefile.in (DISTFILES): Add gpl.texi.
+	* Makefile.in (DISTFILES): Delete gpl.texi.
+
+Sun Mar  3 11:33:30 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Split docs into faq, interpreter, liboctave, and refcard
+	subdirectories.
+
+Wed Sep 20 00:47:45 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkinstalldirs: New file.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+	* Makefile.in (maintainer-clean): Delete .dvi, .ps, and .info
+	files here.
+	(clean): Not here.
+	(mostlyclean): Make this the same as clean.
+
+Tue Sep 19 03:18:35 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (../BUGS, ../INSTALL.OCTAVE): Specify output file to
+	makeinfo with --output option.
+
+Thu Sep 14 20:31:47 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Don't fail if makeinfo, tex, or dvips fail.
+
+See ChangeLog.1 in the top level directory for earlier changes.
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..75c2ccb
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,65 @@
+#
+# Makefile for octave's doc directory
+#
+# John W. Eaton
+# jwe at octave.org
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+abs_top_srcdir = @abs_top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES =
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in ChangeLog conf.texi.in texinfo.tex)
+
+SUBDIRS = faq interpreter liboctave refcard
+
+DISTSUBDIRS = $(SUBDIRS)
+
+all: conf.texi $(SUBDIRS)
+.PHONY: all
+
+conf.texi: conf.texi.in $(TOPDIR)/Makeconf
+	@$(do-subst-texinfo-vals)
+
+../BUGS ../INSTALL.OCTAVE:
+	$(MAKE) -C interpreter ../$@
+.PHONY: ../BUGS ../INSTALL.OCTAVE
+
+$(SUBDIRS):
+	$(MAKE) -C $@ all
+.PHONY: $(SUBDIRS)
+
+install install-strip uninstall clean mostlyclean distclean maintainer-clean::
+	@$(subdir-for-command)
+.PHONY: install install-strip uninstall
+.PHONY: clean mostlyclean distclean maintainer-clean
+
+tags TAGS:: $(SOURCES)
+	$(SUBDIR_FOR_COMMAND)
+
+tags::
+	ctags $(SOURCES)
+
+TAGS:: $(SOURCES)
+	etags $(SOURCES)
+
+distclean::
+	rm -f Makefile
+
+maintainer-clean::
+	rm -f tags TAGS Makefile
+
+dist:
+	ln $(DISTFILES) ../`cat ../.fname`/doc
+	for dir in $(DISTSUBDIRS); do mkdir ../`cat ../.fname`/doc/$$dir; $(MAKE) -C $$dir $@; done
+.PHONY: dist
diff --git a/doc/conf.texi.in b/doc/conf.texi.in
new file mode 100644
index 0000000..8e9d09b
--- /dev/null
+++ b/doc/conf.texi.in
@@ -0,0 +1,27 @@
+ at c Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at set OCTAVE_MANUAL
+ at set top_srcdir %top_srcdir%
+ at set abs_top_srcdir %abs_top_srcdir%
+ at set OCTAVEHOME %OCTAVE_HOME%
+ at set VERSION %OCTAVE_VERSION%
+%TEXINFO_COLAMD%
+%TEXINFO_CHOLMOD%
+%TEXINFO_UMFPACK%
+%TEXINFO_QHULL%
diff --git a/doc/faq/Makefile.in b/doc/faq/Makefile.in
new file mode 100644
index 0000000..925ab75
--- /dev/null
+++ b/doc/faq/Makefile.in
@@ -0,0 +1,100 @@
+# Makefile for octave's doc/faq directory
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
+#               2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES =
+
+TEXINFO := Octave-FAQ.texi
+
+FORMATTED := Octave-FAQ.info Octave-FAQ.dvi Octave-FAQ.ps Octave-FAQ.pdf
+
+DISTFILES := $(addprefix $(srcdir)/, Makefile.in $(TEXINFO) $(FORMATTED))
+
+SPELL := $(patsubst %.texi, %.spell, $(ALL_TEXINFO))
+
+%.spell : %.texi
+	rm -f $@
+	$(SED) -e 's/@@/ at /g' -e 's/@[a-zA-Z]*//g' $< | spell > $@.tmp
+	mv $@.tmp $@
+
+all: Octave-FAQ.info Octave-FAQ.dvi Octave-FAQ.ps Octave-FAQ.pdf Octave-FAQ.html
+.PHONY: all
+
+Octave-FAQ.info: $(TEXINFO)
+	-$(MAKEINFO) -I.. -I$(srcdir) -I$(srcdir)/.. $<
+
+Octave-FAQ.dvi: $(TEXINFO)
+	-TEXINPUTS="..:$(srcdir):$(srcdir)/..:$(TEXINPUTS):" \
+	  $(TEXI2DVI) $<
+
+Octave-FAQ.ps: Octave-FAQ.dvi
+	-dvips -o $@ $<
+
+Octave-FAQ.pdf: $(TEXINFO)
+	-TEXINPUTS="..:$(srcdir):$(srcdir)/..:$(TEXINPUTS):" \
+	  $(TEXI2PDF) $<
+
+Octave-FAQ.html: $(TEXINFO)
+	-$(MAKEINFO) --html --ifinfo --no-split --output=$@ -I.. -I$(srcdir) -I$(srcdir)/.. $<
+
+check install install-strip uninstall:
+.PHONY: check install install-strip uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+spell: $(SPELL)
+.PHONY: spell
+
+mostlyclean clean:
+	rm -f Octave-FAQ.cp Octave-FAQ.fn Octave-FAQ.ky Octave-FAQ.pg \
+	Octave-FAQ.tp Octave-FAQ.vr Octave-FAQ.cps Octave-FAQ.fns \
+	Octave-FAQ.kys Octave-FAQ.pgs Octave-FAQ.tps Octave-FAQ.vrs \
+	Octave-FAQ.aux	Octave-FAQ.log Octave-FAQ.toc
+.PHONY: mostlyclean clean
+
+distclean: clean
+	rm -f Makefile
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS Octave-FAQ.info Octave-FAQ.info-*
+	rm -f Octave-FAQ.dvi Octave-FAQ.ps Octave-FAQ.pdf
+	rm -f Octave-FAQ.html
+.PHONY: maintainer-clean
+
+dist: all
+	ln $(DISTFILES) ../../`cat ../../.fname`/doc/faq
+.PHONY: dist
diff --git a/doc/faq/Octave-FAQ.dvi b/doc/faq/Octave-FAQ.dvi
new file mode 100644
index 0000000..7f32596
Binary files /dev/null and b/doc/faq/Octave-FAQ.dvi differ
diff --git a/doc/faq/Octave-FAQ.info b/doc/faq/Octave-FAQ.info
new file mode 100644
index 0000000..20b5030
--- /dev/null
+++ b/doc/faq/Octave-FAQ.info
@@ -0,0 +1,1239 @@
+START-INFO-DIR-ENTRY
+This is Octave-FAQ.info, produced by makeinfo version 4.11 from Octave-FAQ.texi.
+
+* Octave-FAQ: (Octave-FAQ).  Frequently asked questions about Octave
+END-INFO-DIR-ENTRY
+
+
+File: Octave-FAQ.info,  Node: Top,  Next: What is Octave?,  Up: (dir)
+
+Frequently asked questions about Octave (with answers)
+******************************************************
+
+Preface
+*******
+
+   This is a list of frequently asked questions (FAQ) for Octave users.
+
+   We are always looking for new questions (_with_ answers), better
+answers, or both.  Please send suggestions to <bug at octave.org>.  If you
+have general questions about Octave, or need help for something that is
+not covered by the Octave manual or the FAQ, please use the
+<help at octave.org> mailing list.
+
+   This FAQ is intended to supplement, not replace, the Octave manual.
+Before posting a question to the <help at octave.org> mailing list, you
+should first check to see if the topic is covered in the manual.
+
+* Menu:
+
+* What is Octave?::
+* Licensing Issues::
+* How can I cite Octave?::
+* Series 3.0.N::
+* Octave Features::
+* Learning more about Octave::
+* Getting Octave::
+* Installation::
+* Common problems::
+* How do I ...?::
+* MATLAB compatibility::
+* Index::
+
+
+File: Octave-FAQ.info,  Node: What is Octave?,  Next: Licensing Issues,  Prev: Top,  Up: Top
+
+1 What is Octave?
+*****************
+
+Octave is a high-level interactive language, primarily intended for
+numerical computations that is mostly compatible with MATLAB.(1)
+
+   Octave can do arithmetic for real, complex or integer-valued scalars
+and matrices, solve sets of nonlinear algebraic equations, integrate
+functions over finite and infinite intervals, and integrate systems of
+ordinary differential and differential-algebraic equations.
+
+   Octave uses the GNU readline library to handle reading and editing
+input.  By default, the line editing commands are similar to the cursor
+movement commands used by GNU Emacs, and a vi-style line editing
+interface is also available.  At the end of each session, the command
+history is saved, so that commands entered during previous sessions are
+not lost.
+
+   The Octave distribution includes a 590+ page Texinfo manual.  Access
+to the complete text of the manual is available via the help command at
+the Octave prompt.
+
+* Menu:
+
+* Who develops Octave?::
+* Why GNU Octave?::
+* What version should I use?::
+* On what platforms does Octave run?::
+
+   ---------- Footnotes ----------
+
+   (1) MATLAB is a registered trademark of The MathWorks, Inc.
+
+
+File: Octave-FAQ.info,  Node: Who develops Octave?,  Next: Why GNU Octave?,  Up: What is Octave?
+
+1.1 Who develops Octave?
+========================
+
+Discussions about writing the software that would eventually become
+Octave started in about 1988 with James B. Rawlings and John W. Eaton at
+the University of Texas.  John W. Eaton was the original author of
+Octave, starting full-time development in February 1992.  He is still
+the primary maintainer.  The community of users/developers has in
+addition contributed some code and fuels the discussion on the mailing
+lists <help at octave.org> (user forum), <bug at octave.org> (bug reports),
+<maintainers at octave.org> (development issues), and
+<octave-dev at lists.sourceforge.net> (all things related to the Octave
+Forge repository of user-contributed functions).
+
+
+File: Octave-FAQ.info,  Node: Why GNU Octave?,  Next: What version should I use?,  Prev: Who develops Octave?,  Up: What is Octave?
+
+1.2 Why GNU Octave?
+===================
+
+The GNU Project was launched in 1984 to develop a complete Unix-like
+operating system which is free software: the GNU system.
+
+   GNU is a recursive acronym for "GNU's Not Unix"; it is pronounced
+guh-noo, approximately like canoe.
+
+   The Free Software Foundation (FSF) is the principal organizational
+sponsor of the GNU Project.
+
+   Octave became GNU Octave in 1997 (beginning with version 2.0.6).
+This meant agreeing to consider Octave a part of the GNU Project and
+support the efforts of the FSF.  However, Octave is not and has never
+been developed by the FSF.
+
+   For more information about the GNU project, see `www.gnu.org'.
+
+
+File: Octave-FAQ.info,  Node: What version should I use?,  Next: On what platforms does Octave run?,  Prev: Why GNU Octave?,  Up: What is Octave?
+
+1.3 What version should I use?
+==============================
+
+In general, you will find the latest version on
+`http://www.octave.org/download.html'.  It is recommended to use the
+"testing" version of octave for general use, and the "development"
+version if you want the latest features.
+
+   A list of user-visible changes since the last release is available in
+the file `NEWS'.  The file `ChangeLog' in the source distribution
+contains a more detailed record of changes made since the last release.
+
+
+File: Octave-FAQ.info,  Node: On what platforms does Octave run?,  Prev: What version should I use?,  Up: What is Octave?
+
+1.4 On what platforms does Octave run?
+======================================
+
+Octave runs on various Unices--at least Linux and Solaris, Mac OS X,
+Windows and anything you can compile it on.  Binary distributions exist
+at least for Debian, Suse, Fedora and RedHat Linuxes (Intel and AMD
+CPUs, at least), for Mac Os X and Windows' 98, 2000 and XP.
+
+   Two and three dimensional plotting is fully supported using gnuplot.
+
+   The underlying numerical solvers are currently standard Fortran ones
+like Lapack, Linpack, Odepack, the Blas, etc., packaged in a library of
+C++ classes.  If possible, the Fortran subroutines are compiled with
+the system's Fortran compiler, and called directly from the C++
+functions.  If that's not possible, you can still compile Octave if you
+have the free Fortran to C translator f2c.
+
+   Octave is also free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by the
+Free Software Foundation.
+
+
+File: Octave-FAQ.info,  Node: Licensing Issues,  Next: How can I cite Octave?,  Prev: What is Octave?,  Up: Top
+
+2 Licensing Issues
+******************
+
+* Menu:
+
+* If I write code using Octave do I have to release it under the GPL?: GPL
+* Since the MEX interface allows plugins to be distributed under terms that are incompatible with the GPL, does this mean that you are encouraging people to to write non-free software for Octave?: Licensing MEX Files
+* I wrote a program that links with Octave libraries and I don't want to release it under the terms of the GPL.  Will you change the license of the Octave libraries for me?: Requesting License Changes
+
+
+File: Octave-FAQ.info,  Node: GPL,  Next: Licensing MEX Files,  Up: Licensing Issues
+
+2.1 If I write code using Octave do I have to release it under the GPL?
+=======================================================================
+
+The answer depends on precisely how the code is written and how it
+works.
+
+   Code written entirely in the scripting language of Octave
+(interpreted code in .m files) may be released under the terms of
+whatever license you choose.
+
+   Code written using Octave's native plug-in interface (also known as
+a .oct file) necessarily links with Octave internals and is considered
+a derivative work of Octave and therefore must be released under terms
+that are compatible with the GPL.
+
+   Code written using Octave's implementation of the Matlab MEX
+interface may be released under the terms of whatever license you
+choose, provided that the following conditions are met:
+
+  1. The plugin should not use any bindings that are specific to
+     Octave.  In other words, the MEX file must use the MEX interface
+     only, and not also call on other Octave internals.  It should be
+     possible in principle to use the MEX file with other programs that
+     implement the MEX interface (e.g., Matlab).
+
+  2. The MEX file should not be distributed together with Octave in
+     such a way that they effectively create a single work.  For
+     example, you should not distribute the MEX file and Octave
+     together in a single package such that Octave automatically loads
+     and runs the MEX file when it starts up.  There are other possible
+     ways that you might effectively create a single work; this is just
+     one example.
+
+   A program that embeds the Octave interpreter (e.g., by calling the
+"octave_main" function), or that calls functions from Octave's
+libraries (e.g., liboctinterp, liboctave, or libcruft) is considered a
+derivative work of Octave and therefore must be released under terms
+that are compatible with the GPL.
+
+
+File: Octave-FAQ.info,  Node: Licensing MEX Files,  Next: Requesting License Changes,  Prev: GPL,  Up: Licensing Issues
+
+2.2 Since the MEX interface allows plugins to be distributed under terms that are incompatible with the GPL, does this mean that you are encouraging people to to write non-free software for Octave?
+=====================================================================================================================================================================================================
+
+No.  The original reason for implementing the MEX interface for Octave
+was to allow Octave to run free software that uses MEX files (the
+particular goal was to run SundialsTB in Octave).  The intent was to
+liberate that software from Matlab and increase the amount of free
+software available to Octave users, not to enable people to write
+proprietary code for Octave.  For the good of the community, we strongly
+encourage users of Octave to release the code they write for Octave
+under terms that are compatible with the GPL.
+
+
+File: Octave-FAQ.info,  Node: Requesting License Changes,  Prev: Licensing MEX Files,  Up: Licensing Issues
+
+2.3 I wrote a program that links with Octave libraries and I don't want to release it under the terms of the GPL.  Will you change the license of the Octave libraries for me?
+==============================================================================================================================================================================
+
+No.  Instead of asking us to change the licensing terms for Octave, we
+recommend that you release your program under terms that are compatible
+with the GPL so that the free software community can benefit from your
+work the same as you have benefitted from the work of all the people who
+have contributed to Octave.
+
+
+File: Octave-FAQ.info,  Node: How can I cite Octave?,  Next: Series 3.0.N,  Prev: Licensing Issues,  Up: Top
+
+3 How can I cite Octave?
+************************
+
+Pointing to `http://www.octave.org' is good, because that gives people
+a direct way to find out more.  If citation of a URL is not allowed by
+a publisher, or if you also want to point to a traditional reference,
+then you can cite the Octave manual:
+
+     @BOOK{eaton:2008,
+       author =     "John W. Eaton and David Bateman and Søren Hauberg",
+       title =      "GNU Octave Manual Version 3",
+       publisher =  "Network Theory Limited",
+       year =       "2008",
+       isbn =       "0-9546120-6-X"
+     }
+
+
+File: Octave-FAQ.info,  Node: Series 3.0.N,  Next: Octave Features,  Prev: How can I cite Octave?,  Up: Top
+
+4 What's new in version series 3.0.N and 3.1.N of Octave
+********************************************************
+
+The 3.0.N series has enough new features to justify a major version
+number change. The 3.0.N series brings
+
+   * integer types
+
+   * fixed point arithmetic
+
+   * sparse matrices
+
+   * Linear programming code based on GLPK
+
+   * 64-bit compilation support
+
+   * gzipped files and stream and consequently support of matlab v7
+     files
+
+   * better support for both msvc and mingw
+
+   * a fully compatible MEX interface
+
+   * many many other minor features and compatibility changes
+
+
+   Here are some features that have been around since 2.1.N
+
+   * NDarrays
+
+   * cells
+
+
+   The 3.1.N series is the current development release and will become a
+3.2.N release in the future. This series brings the new features
+
+   * OpenGL backend
+
+     An experimental OpenGL graphics backend to replace the gnuplot
+
+   * Object Orient Programming
+
+   * Block comments
+
+   * imwrite and imread
+
+     The functions are based on the GraphicsMagick library.
+
+   * Lazy transpose
+
+     Special treatment in the parser of things like "a' * b", where the
+     transpose is never explicitly formed but a flag is rather passed
+     to the underlying LAPACK code.
+
+   * Single precision type
+
+   * Improved array indexing The underlying code used for indexing of
+     arrays has been completely rewritten and so the indexing of arrays
+     is now significantly faster.
+
+
+File: Octave-FAQ.info,  Node: Octave Features,  Next: Learning more about Octave,  Prev: Series 3.0.N,  Up: Top
+
+5 What features are unique to Octave?
+*************************************
+
+* Menu:
+
+* Functions defined on the command-line::
+* Comments with #::
+* Strings delimitted by double quotes "::
+* Line continuation by backslash::
+* Informative block closing::
+* Coherent syntax::
+* Exclamation mark as not operator::
+* Increment and decrement operators::
+* Unwind-protect::
+* Built-in ODE and DAE solvers::
+
+   This section refers to Matlab R2008b and Octave 2.1.51.
+
+
+File: Octave-FAQ.info,  Node: Functions defined on the command-line,  Next: Comments with #,  Up: Octave Features
+
+5.1 Functions defined on the command-line
+=========================================
+
+Functions can be defined by entering code on the command line, a
+feature not supported by the other leading brand.  For example, you may
+type:
+
+     octave:1> function s = hello_string (to_who)
+     > ## Say hello
+     > if nargin<1, to_who = "World"; end
+     > s = ["Hello ",\
+     >      to_who];
+     > endfunction
+     octave:2> hello_string ("Moon")
+     ans = Hello Moon
+
+
+File: Octave-FAQ.info,  Node: Comments with #,  Next: Strings delimitted by double quotes ",  Prev: Functions defined on the command-line,  Up: Octave Features
+
+5.2 Comments with #
+===================
+
+The pound character, `#', may be used to start comments, in addition to
+`%'.  See the previous example.  The major advantage of this is that as
+`#' is also a comment character for unix script files, any file that
+starts with a string like `#! /usr/bin/octave -q' will be treated as an
+octave script and be executed by octave.
+
+
+File: Octave-FAQ.info,  Node: Strings delimitted by double quotes ",  Next: Line continuation by backslash,  Prev: Comments with #,  Up: Octave Features
+
+5.3 Strings delimitted by double quotes "
+=========================================
+
+The double quote, `"', may be used to delimit strings, in addition to
+the single quote `''.  See the previous example.  Also, double-quoted
+strings include backslash interpretation (like C++, C, and Perl) while
+single quoted are uninterpreted (like Matlab and Perl).
+
+
+File: Octave-FAQ.info,  Node: Line continuation by backslash,  Next: Informative block closing,  Prev: Strings delimitted by double quotes ",  Up: Octave Features
+
+5.4 Line continuation by backslash
+==================================
+
+Lines can be continued with a backslash, `\', in addition to three
+points `...'.  See the previous example.
+
+
+File: Octave-FAQ.info,  Node: Informative block closing,  Next: Coherent syntax,  Prev: Line continuation by backslash,  Up: Octave Features
+
+5.5 Informative block closing
+=============================
+
+You may close `function', `for', `while', `if', ... blocks with
+`endfunction', `endfor', `endwhile', ... keywords in addition to using
+`end'.  As with Matlab, the `end' (or `endfunction') keyword that marks
+the end of a function defined in a `.m' file is optional.
+
+
+File: Octave-FAQ.info,  Node: Coherent syntax,  Next: Exclamation mark as not operator,  Prev: Informative block closing,  Up: Octave Features
+
+5.6 Coherent syntax
+===================
+
+Indexing other things than variables is possible, as in:
+     octave:1> [3 1 4 1 5 9](3)
+     ans = 4
+     octave:2> cos([0 pi pi/4 7])(3)
+     ans = 0.70711
+
+
+File: Octave-FAQ.info,  Node: Exclamation mark as not operator,  Next: Increment and decrement operators,  Prev: Coherent syntax,  Up: Octave Features
+
+5.7 Exclamation mark as not operator
+====================================
+
+The exclamation mark '!' (aka "Bang!") is a negation operator, just
+like the tilde '~':
+
+     octave:1> if ! strcmp (program_name, "octave"),
+     >   "It's an error"
+     > else
+     >   "It works!"
+     > end
+     ans = It works!
+
+
+File: Octave-FAQ.info,  Node: Increment and decrement operators,  Next: Unwind-protect,  Prev: Exclamation mark as not operator,  Up: Octave Features
+
+5.8 Increment and decrement operators
+=====================================
+
+If you like the `++', `+=' etc operators, rejoice!  Octave includes the
+C-like increment and decrement operators `++' and `--' in both their
+prefix and postfix forms, in addition to `+=', `-=', `*=', `/=', `^=',
+`.*=', `./=', and `.^='.
+
+   For example, to pre-increment the variable X, you would write `++X'.
+This would add one to X and then return the new value of X as the
+result of the expression.  It is exactly the same as the expression `X
+= X + 1'.
+
+   To post-increment a variable X, you would write `x++'.  This adds
+one to the variable X, but returns the value that X had prior to
+incrementing it.  For example, if X is equal to 2, the result of the
+expression `x++' is 2, and the new value of X is 3.
+
+   For matrix and vector arguments, the increment and decrement
+operators work on each element of the operand.
+
+
+File: Octave-FAQ.info,  Node: Unwind-protect,  Next: Built-in ODE and DAE solvers,  Prev: Increment and decrement operators,  Up: Octave Features
+
+5.9 Unwind-protect
+==================
+
+Octave supports a limited form of exception handling modelled after the
+unwind-protect form of Lisp.  The general form of an `unwind_protect'
+block looks like this:
+
+     unwind_protect
+       BODY
+     unwind_protect_cleanup
+       CLEANUP
+     end_unwind_protect
+
+Where BODY and CLEANUP are both optional and may contain any Octave
+expressions or commands.  The statements in CLEANUP are guaranteed to
+be executed regardless of how control exits BODY.
+
+   The `unwind_protect' statement is often used to reliably restore the
+values of global variables that need to be temporarily changed.
+
+   Matlab can be made to do something similar with their `OnCleanUp'
+function that was introduced in 2008a.
+
+
+File: Octave-FAQ.info,  Node: Built-in ODE and DAE solvers,  Prev: Unwind-protect,  Up: Octave Features
+
+5.10 Built-in ODE and DAE solvers
+=================================
+
+Octave includes LSODE and DASSL for solving systems of stiff ordinary
+differential and differential-algebraic equations.  These functions are
+built in to the interpreter.
+
+
+File: Octave-FAQ.info,  Node: Learning more about Octave,  Next: Getting Octave,  Prev: Octave Features,  Up: Top
+
+6 What documentation exists for Octave?
+***************************************
+
+* Menu:
+
+* Documentation::
+* Getting additional help::
+* User community::
+* Bug reports::
+
+
+File: Octave-FAQ.info,  Node: Documentation,  Next: Getting additional help,  Up: Learning more about Octave
+
+6.1 What documentation exists for Octave?
+=========================================
+
+The Octave distribution includes a 590+ page manual that is also
+distributed under the terms of the GNU GPL.  It is available on the web
+at `http://www.octave.org/docs.html' and you will also find there
+instructions on how to order a paper version.
+
+   The complete text of the Octave manual is also available using the
+GNU Info system via the GNU Emacs, info, or xinfo programs, or by using
+the `help -i' command to start the GNU info browser directly from the
+Octave prompt.
+
+   If you have problems using this documentation, or find that some
+topic is not adequately explained, indexed, or cross-referenced, please
+send a bug report to <bug at octave.org>.
+
+
+File: Octave-FAQ.info,  Node: Getting additional help,  Next: User community,  Prev: Documentation,  Up: Learning more about Octave
+
+6.2 Getting additional help
+===========================
+
+If you can't find an answer to your question, the <help at octave.org>
+mailing list is available for questions related to using, installing,
+and porting Octave that are not adequately answered by the Octave
+manual or by this document.
+
+
+File: Octave-FAQ.info,  Node: User community,  Next: Bug reports,  Prev: Getting additional help,  Up: Learning more about Octave
+
+6.3 User community
+==================
+
+To subscribe to the list, go to `www.octave.org/archive.html' and
+follow the link to the subscription page for the list.
+
+   *Please do not* send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+   An archive of old postings to the help-octave mailing list is
+maintained on `http://www.octave.org/archive.html'.
+
+   You will also find some user advice and code spread over the web.
+Good starting points are the Octave Wiki `http://wiki.octave.org' and
+Octave-Forge `http://octave.sourceforge.net'
+
+
+File: Octave-FAQ.info,  Node: Bug reports,  Prev: User community,  Up: Learning more about Octave
+
+6.4 I think I have found a bug in Octave.
+=========================================
+
+"I think I have found a bug in Octave, but I'm not sure.  How do I know,
+and who should I tell?"
+
+   First, see the section on bugs and bug reports in the Octave manual.
+When you report a bug, make sure to describe the type of computer you
+are using, the version of the operating system it is running, and the
+version of Octave that you are using.  Also provide enough code so that
+the Octave maintainers can duplicate your bug.
+
+   If you have Octave working at all, the easiest way to do this is to
+use the Octave function `bug_report'.  When you execute this function,
+Octave will prompt you for a subject and then invoke the editor on a
+file that already contains all the configuration information.  When you
+exit the editor, Octave will mail the bug report for you (in a unix-like
+operating system).
+
+   If for some reason you cannot use Octave's `bug_report' function,
+mail your bug report to <bug at octave.org>.  Your message needs to
+include enough information to allow the maintainers of Octave to fix the
+bug.  Please read the section on bugs and bug reports in the Octave
+manual for a list of things that should be included in every bug report.
+
+
+File: Octave-FAQ.info,  Node: Getting Octave,  Next: Installation,  Prev: Learning more about Octave,  Up: Top
+
+7 Getting Octave
+****************
+
+* Menu:
+
+* Source code::
+* Pre-compiled binary packages::
+* Octave for other platforms::
+
+
+File: Octave-FAQ.info,  Node: Source code,  Next: Pre-compiled binary packages,  Up: Getting Octave
+
+7.1 Source code
+===============
+
+Source code is available on the Octave development site, where you are
+sure to get the latest version.
+
+   * `http://www.octave.org/download.html'
+
+   * `ftp://ftp.octave.org/pub/octave/'
+
+   Since Octave is distrubted under the terms of the GPL, you can get
+Octave from a friend who has a copy, by anonymous FTP, or by ordering a
+tape or CD-ROM from the Free Software Foundation (FSF).
+
+
+File: Octave-FAQ.info,  Node: Pre-compiled binary packages,  Next: Octave for other platforms,  Prev: Source code,  Up: Getting Octave
+
+7.2 Pre-compiled binary packages
+================================
+
+The Octave project does not distribute binary packages, but other
+projects do.  For an up-to-date listing of packagers, see:
+
+   * `http://www.octave.org/download.html'
+
+   * `http://wiki.octave.org/wiki.pl?CategoryInstall'
+
+   As of today, Octave binaries are available at least on Debian,
+RedHat, Suse and Fedora Linuxes, Mac OS X, Windows' 98, 2000 and XP.
+
+
+File: Octave-FAQ.info,  Node: Octave for other platforms,  Prev: Pre-compiled binary packages,  Up: Getting Octave
+
+7.3 How do I get a copy of Octave for (some other platform)?
+============================================================
+
+Octave currently runs on Unix-like systems, Mac OS X, and Windows.  It
+should be possible to make Octave work on other systems as well.  If
+you are interested in porting Octave to other systems, please contact
+<bug at octave.org>.
+
+
+File: Octave-FAQ.info,  Node: Installation,  Next: Common problems,  Prev: Getting Octave,  Up: Top
+
+8 Installation Issues and Problems
+**********************************
+
+Octave 3.2 require approximately 800MB of disk storage to unpack and
+compile from source (considerably less if you don't compile with
+debugging symbols).  Once installed, Octave requires approximately 200MB
+of disk space (again, considerably less if you don't compile with
+debugging symbols).
+
+* Menu:
+
+* What else do I need?::
+* Other C++ compilers?::
+
+
+File: Octave-FAQ.info,  Node: What else do I need?,  Next: Other C++ compilers?,  Up: Installation
+
+8.1 What else do I need?
+========================
+
+To compile Octave, you will need a recent version of GNU Make.  You
+will also need GCC 3.3 or later, although GCC 4.1 or later is
+recommended.
+
+   *You must have GNU Make to compile octave*.  Octave's Makefiles use
+features of GNU Make that are not present in other versions of make.
+GNU Make is very portable and easy to install.
+
+
+File: Octave-FAQ.info,  Node: Other C++ compilers?,  Prev: What else do I need?,  Up: Installation
+
+8.2 Can I compile Octave with another C++ compiler?
+===================================================
+
+Yes, but development is done primarily with GCC, so you may hit some
+incompatibilities.  Octave is intended to be portable to any standard
+conforming compiler.  If you have difficulties that you think are bugs,
+please report them to the <bug at octave.org> mailing list, or ask for
+help on the <help at octave.org> mailing list.
+
+
+File: Octave-FAQ.info,  Node: Common problems,  Next: How do I ...?,  Prev: Installation,  Up: Top
+
+9 Common problems
+*****************
+
+This list is probably far too short.  Feel free to suggest additional
+questions (preferably with answers!)
+
+   * Octave takes a long time to find symbols.
+
+     Octave uses the `genpath' function to recursively add directories
+     to the list of directories searched for function files.  Check the
+     list of directories with the `path' command. If the path list is
+     very long check your use of the `genpath' function.
+
+   * When plotting Octave occasionally gives me errors like `gnuplot> 9
+     0.735604 line 26317: invalid command'.
+
+     There is a known bug in gnuplot 4.2 that can cause an off by one
+     error while piping data to gnuplot. The relevant gnuplot bug
+     report can be found at
+     `http://sourceforge.net/tracker/index.php?func=detail&aid=1716556&group_id=2055&atid=102055'
+
+     If you have obtained your copy of Octave from a distribution
+     please file a bug report requesting that the fix reported in the
+     above bug report be included.
+
+   * I cannot install a package. Octave complains about a missing
+     `mkoctfile'.
+
+     Most distributions split Octave into several packages. The script
+     `mkoctfile' is then part of a separate package:
+        - Debian/Ubuntu
+
+          `aptitude install octave3.0-headers'
+
+        - Fedora
+
+          `yum install octave-devel'
+
+
+
+File: Octave-FAQ.info,  Node: How do I ...?,  Next: MATLAB compatibility,  Prev: Common problems,  Up: Top
+
+10 How do I ...?
+****************
+
+* Menu:
+
+* How do I set the number of displayed decimals?::
+
+
+File: Octave-FAQ.info,  Node: How do I set the number of displayed decimals?,  Up: How do I ...?
+
+10.1 How do I set the number of displayed decimals?
+===================================================
+
+     octave:1> format long
+     octave:2> pi
+     pi = 3.14159265358979
+     octave:3> format short
+     octave:4> pi
+     pi = 3.1416
+
+
+File: Octave-FAQ.info,  Node: MATLAB compatibility,  Next: Index,  Prev: How do I ...?,  Up: Top
+
+11 Porting programs from MATLAB to Octave
+*****************************************
+
+People often ask
+
+   "I wrote some code for MATLAB, and I want to get it running under
+Octave.  Is there anything I should watch out for?"
+
+   or alternatively
+
+   "I wrote some code in Octave, and want to share it with MATLAB
+users.  Is there anything I should watch out for?"
+
+   which is not quite the same thing.  There are still a number of
+differences between Octave and MATLAB, however in general differences
+between the two are considered as bugs.  Octave might consider that the
+bug is in MATLAB and do nothing about it, but generally functionality
+is almost identical.  If you find a difference between Octave behavior
+and MATLAB, then you should send a description of this difference (with
+code illustrating the difference, if possible) to <bug at octave.org>.
+
+   Furthermore, Octave adds a few syntactical extensions to Matlab that
+might cause some issues when exchanging files between Matlab and Octave
+users. As both Octave and MATLAB are under constant development the
+information in this section is subject to change at anytime.
+
+   You should also look at the page
+`http://octave.sourceforge.net/packages.html' and
+`http://octave.sourceforge.net/doc/' that has a function reference that
+is up to date. You can use this function reference to see the number of
+octave function that are available and their MATLAB compatibility.
+
+   The major differences between Octave 3.2.N and  MATLAB R2008a are:
+
+   * Nested Functions
+
+     Octave doesn't yet have nested functions. That is
+
+          function y = foo (x)
+            y = bar(x)
+            function y = bar (x)
+              y = ...;
+            end
+          end
+
+     There was discussion in Octave of having these even prior to
+     MATLAB, and the decision was made not to have these in Octave at
+     the time for compatibility.  The above written with sub-functions
+     functions would be
+
+          function y = foo (x)
+             y = bar(x)
+          end
+          function y = bar (x)
+             y = ...;
+          end
+
+     Now that MATLAB has recently introduced nested functions, Octave
+     will probably have them soon as well.  Until then nested functions
+     in Octave are treated as sub-functions with the same scoping rules
+     as sub-functions.
+
+     The authors of Octave consider the nested function scoping rules of
+     Matlab to be more problems than they are worth as they introduce
+     diffiult to find bugs as inadvertantly modifying a variable in a
+     nested function that is also used in the parent is particularly
+     easy.
+
+   * Differences in core syntax There a few core MATLAB syntaxes that
+     are not accepted by Octave, these being
+
+        * Some limitations on the use of function handles. The major
+          difference is related to nested function scoping rules (as
+          above) and their use with function handles.
+
+        * Some limitations of variable argument lists on the LHS of an
+          expression, though the most common types are accepted.
+
+        * MATLAB classdef object oriented programming is not yet
+          supportted, though work is underway and when development more
+          on to Octave 3.3 this will be included in teh development
+          tree.
+
+   * Differences in core functions A large number of the MATLAB core
+     functions (ie those that are in the core and not a toolbox) are
+     implemented, and certainly all of the commonly used ones. There
+     are a few functions that aren't implemented, for example `condest'
+     or to do with specific missing Octave functionality (gui, dll,
+     java, activex, dde, web, and serial functions). Some of the core
+     functions have limitations that aren't in the MATLAB version.  For
+     example the `sprandn' function can not force a particular
+     condition number for the matrix like MATLAB can.
+
+   * Just-In-Time compiler MATLAB includes a "Just-In-Time" compiler.
+     This compiler allows the acceleration of for-loops in MATLAB to
+     almost native performance with certain restrictions. The JIT must
+     know the return type of all functions called in the loops and so
+     you can't include user functions in the loop of JIT optimized
+     loops.  Octave doesn't have a JIT and so to some might seem slower
+     than MATLAB.  For this reason you must vectorize your code as much
+     as possible.  The MathWorks themselves have a good document
+     discussing vectorization at
+     `http://www.mathworks.com/support/tech-notes/1100/1109.html'.
+
+   * Compiler On a related point, there is no Octave compiler, and so
+     you can't convert your Octave code into a binary for additional
+     speed or distribution.  There is an example of how to do this at
+     `http://www.stud.tu-ilmenau.de/~rueckn/', but this is a very early
+     example code and would need lots of work to complete it.
+
+   * Graphic Handles Up to Octave 2.9.9 there was no support for
+     graphic handles in Octave itself.  In the 3.2.N versions of Octave
+     the support for graphics handles is converging towards full
+     compatibility. The `patch' function is currently limited to 2-D
+     patches, due to an underlying limitation in gnuplot.
+
+   * GUI There are no MATLAB compatible GUI functions.  There are a
+     number of bindings from Octave to Tcl/Tk, Vtk and zenity included
+     in the Octave Forge project (`http://octave.sourceforge.net') for
+     example that can be used for a GUI, but these are not MATLAB
+     compatible. Work on a matlab compatible GUI is in an alpha stage
+     in the JHandles package
+     (`http://octave.sourceforge.net/jhandles/index.html').  This might
+     be an issue if you intend to exchange Octave code with MATLAB
+     users.
+
+   * Simulink Octave itself includes no Simulink support. Typically the
+     simulink models lag research and are less flexible, so shouldn't
+     really be used in a research environment.  However, some MATLAB
+     users that try to use Octave complain about this lack.  There is a
+     similar package to simulink for the Octave and R projects
+     available at `http://www.scicraft.org/'
+
+   * Mex-Files Octave includes an API to the matlab MEX interface.
+     However, as MEX is an API to the internals of MATLAB and the
+     internals of Octave differ from MATLAB, there is necessarily a
+     manipulation of the data to convert from a MEX interface to the
+     Octave equivalent. This is notable for all complex matrices, where
+     MATLAB stores complex arrays as real and imaginary parts, whereas
+     Octave respects the C99/C++ standards of co-locating the real/imag
+     parts in memory.  Also due to the way MATLAB allows access to the
+     arrays passed through a pointer, the MEX interface might require
+     copies of arrays (even non complex ones).
+
+   * Block comments Block comments denoted by "%{" and "%}" markers are
+     supported by Octave with some limitations. The major limitation is
+     that block comments are not supported within [] or {}.
+
+   * Mat-File format There are some differences in the mat v5 file
+     format accepted by Octave. MATLAB recently introduced the "-V7.3"
+     save option which is an HDF5 format which is particularly useful
+     for 64-bit platforms where the standard matlab format can not
+     correctly save variables.. Octave accepts HDF5 files, but is not
+     yet compatible with the "-v7.3" versions produced by MATLAB.
+
+     Although Octave can load inline abd function handles saved by
+     MATLAB, it can not yet save them.
+
+     Finally, Some multi-byte unicode characters aren't yet treated in
+     mat-files.
+
+   * Profiler Octave doesn't have a profiler. Though there is a patch
+     for a flat profiler, that might become a real profiler sometime in
+     the future. see the thread
+
+     `http://www.cae.wisc.edu/pipermail/octave-maintainers/2007-January/001685.html'
+
+     for more details
+
+   * Toolboxes Octave is a community project and so the toolboxes that
+     exist are donated by those interested in them through the Octave
+     Forge website (`http://octave.sourceforge.net'). These might be
+     lacking in certain functionality relative to the MATLAB toolboxes,
+     and might not exactly duplicate the matlab functionality or
+     interface.
+
+   * Short-circuit & and | operators The `&' and `|' operators in
+     MATLAB short-circuit when included in an if statemant and not
+     otherwise.  In Octave only the `&&' and `||' short circuit.  Note
+     that this means that
+
+            if (a | b)
+              ...
+            end
+
+     and
+
+            t = a | b;
+            if t
+              ...
+            end
+
+     are different in MATLAB. This is really a MATLAB bug, but there is
+     too much code out there that relies on this behavior to change it.
+     Prefer the || and && operators in if statements if possible.
+
+     Note that the difference is also significant when either argument
+     is a function with side effects or if the first argument is a
+     scalar and the second argument is an empty matrix.  For example,
+     note the difference between
+
+            t = 1 | [];          ## results in [], so...
+            if (t) 1, end        ## in if ([]), this is false.
+
+     and
+
+            if (1 | []) 1, end   ## short circuits so condition is true.
+
+     Another case that is documented in the MATLAB manuals is that
+
+            t = [1, 1] | [1, 2, 3];          ## error
+            if ([1, 1] | [1, 2, 3]) 1, end   ## OK
+
+     Also MATLAB requires the operands of && and || to be scalar values
+     but Octave does not (it just applies the rule that for an operand
+     to be considered true, every element of the object must be nonzero
+     or logically true).
+
+     Finally, note the inconsistence of thinking of the condition of an
+     if statement as being equivalent to `all(X(:))' when X is a
+     matrix.  This is true for all cases EXCEPT empty matrices:
+
+            if ([0, 1]) == if (all ([0, 1]))   ==>  i.e., condition is false.
+            if ([1, 1]) == if (all ([1, 1]))   ==>  i.e., condition is true.
+
+     However,
+
+            if ([]) != if (all ([]))
+
+     because `samp ([]) == 1' (because, despite the name, it is really
+     returning true if none of the elements of the matrix are zero, and
+     since there are no elements, well, none of them are zero).  But,
+     somewhere along the line, someone decided that if `([])' should be
+     false.  Mathworks probably thought it just looks wrong to have
+     `[]' be true in this context even if you can use logical
+     gymnastics to convince yourself that "all" the elements of a
+     matrix that doesn't actually have any elements are nonzero. Octave
+     however duplicates this behavior for if statements containing
+     empty matrices.
+
+   * Solvers for singular, under- and over-determined matrices
+
+     Matlab's solvers as used by the operators mldivide (\) and
+     mrdivide (/), use a different approach than Octave's in the case
+     of singular, under-, or over-determined matrices. In the case of a
+     singular matrix, Matlab returns the result given by the LU
+     decomposition, even though the underlying solver has flagged the
+     result as erroneous. Octave has made the choice of falling back to
+     a minimum norm solution of matrices that have been flagged as
+     singular which arguably is a better result for these cases.
+
+     In the case of under- or over-determined matrices, Octave
+     continues to use a minimum norm solution, whereas Matlab uses an
+     approach that is equivalent to
+
+          function x = mldivide (A, b)
+            [Q, R, E] = qr(A);
+            x = [A \ b, E(:, 1:m) * (R(:, 1:m) \ (Q' * b))]
+          end
+
+     While this approach is certainly faster and uses less memory than
+     Octave's minimum norm approach, this approach seems to be inferior
+     in other ways.
+
+     A numerical question arises: how big can the null space component
+     become, relative to the minimum-norm solution? Can it be nicely
+     bounded, or can it be arbitrarily big? Consider this example:
+
+          m = 10;
+          n = 10000;
+          A = ones(m, n) + 1e-6 * randn(m,n);
+          b = ones(m, 1) + 1e-6 * randn(m,1);
+          norm(A \ b)
+
+     while Octave's minimum-norm values are around 3e-2, Matlab's
+     results are 50-times larger. For another issue, try this code:
+
+          m = 5;
+          n = 100;
+          j = floor(m * rand(1, n)) + 1;
+          b = ones(m, 1);
+          A = zeros(m, n);
+          A(sub2ind(size(A),j,1:n)) = 1;
+          x = A \ b;
+          [dummy,p] = sort(rand(1,n));
+          y = A(:,p)\b;
+          norm(x(p)-y)
+
+     It shows that unlike in Octave, mldivide in Matlab is not invariant
+     with respect to column permutations. If there are multiple columns
+     of the same norm, permuting columns of the matrix gets you
+     different result than permuting the solution vector. This will
+     surprise many users.
+
+     Since the mldivide (\) and mrdivide (/) operators are often part
+     of a more complex expression, where there is no room to react to
+     warnings or flags, it should prefer intelligence (robustness) to
+     speed, and so the Octave developers are firmly of the opinion that
+     Octave's approach for singular, under- and over-determined
+     matrices is a better choice that Matlab's
+
+   * Octave extensions The extensions in Octave over MATLAB syntax are
+     very useful, but might cause issues when sharing with MATLAB users.
+     A list of the major extensions that should be avoided to be
+     compatible with MATLAB are
+
+        * Comments in octave can be marked with `#'. This allows POSIX
+          systems to have the first line as `#! octave -q' and mark the
+          script itself executable. MATLAB doesn't have this feature
+          due to the absence of comments starting with `#'".
+
+        * Code blocks like if, for, while, etc can be terminated with
+          block specific terminations like "endif". MATLAB doesn't have
+          this and all blocks must be terminated with "end"
+
+        * Octave has a lisp like unwind_protect block that allows
+          blocks of code that terminate in an error to ensure that the
+          variables that are touched are restored. You can do something
+          similar with `try'/`catch' combined with `rethrow (lasterror
+          ())' in MATLAB, however rethrow and lasterror are only
+          available in Octave 2.9.10 and later.
+
+          Note that using `try'/`catch' combined with `rethrow
+          (lasterror ())' can not guarantee that global variables will
+          be correctly reset, as it won't catch user interrupts with
+          Ctrl-C. For example
+
+                 global a
+                 a = 1;
+                 try
+                   _a = a;
+                   a = 2
+                   while true
+                   end
+                 catch
+                   fprintf ('caught interrupt\n');
+                   a = _a;
+                   rethrow (lasterror());
+                 end
+
+          compared to
+
+                 global a
+                 a = 1;
+                 unwind_protect
+                   _a = a;
+                   a = 2
+                   while true
+                   end
+                 unwind_protect_cleanup
+                   fprintf ('caught interrupt\n');
+                   a = _a;
+                 end
+
+          Typing Ctrl-C in the first case returns the user directly to
+          the prompt, and the variable "a" is not reset to the saved
+          value. In the second case the variable "a" is reset
+          correctly.  Therefore MATLAB gives no save way of temporarily
+          changing global variables.
+
+        * Indexing can be applied to all objects in Octave and not just
+          variable. Therefore `sin(x)(1:10);' for example is perfectly
+          valid in Octave but not MATLAB. To do the same in MATLAB you
+          must do `y = sin(x); y = y([1:10]);'
+
+        * Octave has the operators "++", "-", "-=", "+=", "*=", etc.  As
+          MATLAB doesn't, if you are sharing code these should be
+          avoided.
+
+        * Character strings in Octave can be denoted with double or
+          single quotes. There is a subtle difference between the two
+          in that escaped characters like `\n' (newline), `\t' (tab),
+          etc are interpreted in double quoted strings but not single
+          quoted strings. This difference is important on Windows
+          platforms where the "\" character is used in path names, and
+          so single quoted strings should be used in paths. MATLAB
+          doesn't have double quoted strings and so they should be
+          avoided if the code will be transfered to a MATLAB user.
+
+
+
+File: Octave-FAQ.info,  Node: Index,  Prev: MATLAB compatibility,  Up: Top
+
+Appendix A Concept Index
+************************
+
+ [index ]
+* Menu:
+
+* Additional help:                       Getting additional help.
+                                                               (line  6)
+* Binaries:                              Pre-compiled binary packages.
+                                                               (line  6)
+* Bug in Octave, newly found:            Bug reports.          (line  6)
+* Compatibility with MATLAB:             MATLAB compatibility. (line  6)
+* DASSL:                                 Built-in ODE and DAE solvers.
+                                                               (line  6)
+* Decrement operators:                   Increment and decrement operators.
+                                                               (line  6)
+* DJGPP:                                 Octave for other platforms.
+                                                               (line  6)
+* EMX:                                   Octave for other platforms.
+                                                               (line  6)
+* FAQ for Octave, latest version:        Top.                  (line  9)
+* Flex:                                  What else do I need?. (line  6)
+* FSF [Free Software Foundation]:        Why GNU Octave?.      (line 22)
+* GNU [GNU's not unix]:                  Why GNU Octave?.      (line 22)
+* GNU Bison:                             What else do I need?. (line  6)
+* GNU g++:                               What else do I need?. (line  6)
+* GNU gcc:                               What else do I need?. (line  6)
+* GNU Make:                              What else do I need?. (line  6)
+* How do I ... ?:                        How do I ...?.        (line 10)
+* Increment operators:                   Increment and decrement operators.
+                                                               (line  6)
+* libg++:                                What else do I need?. (line  6)
+* LSODE:                                 Built-in ODE and DAE solvers.
+                                                               (line  6)
+* Mailing lists, bug-octave:             Bug reports.          (line 22)
+* Mailing lists, help-octave:            Getting additional help.
+                                                               (line  6)
+* Manual, for Octave:                    Bug reports.          (line  9)
+* MATLAB compatibility:                  MATLAB compatibility. (line  6)
+* MS-DOS support:                        Octave for other platforms.
+                                                               (line  6)
+* Octave bug report:                     Bug reports.          (line 22)
+* Octave, building:                      Installation.         (line  6)
+* Octave, documentation:                 Documentation.        (line  6)
+* Operators, decrement:                  Increment and decrement operators.
+                                                               (line  6)
+* Operators, increment:                  Increment and decrement operators.
+                                                               (line  6)
+* OS/2 support:                          Octave for other platforms.
+                                                               (line  6)
+* Pre-compiled binary packages:          Pre-compiled binary packages.
+                                                               (line  6)
+* Source code:                           Source code.          (line  6)
+* Tips and tricks:                       How do I ...?.        (line 10)
+* Unwind-protect:                        Unwind-protect.       (line  6)
+* VAX:                                   Octave for other platforms.
+                                                               (line  6)
+* VMS support:                           Octave for other platforms.
+                                                               (line  6)
+* Windows support:                       Octave for other platforms.
+                                                               (line  6)
+
+
+
+Tag Table:
+Node: Top192
+Node: What is Octave?1232
+Ref: What is Octave?-Footnote-12457
+Node: Who develops Octave?2521
+Node: Why GNU Octave?3327
+Node: What version should I use?4136
+Node: On what platforms does Octave run?4786
+Node: Licensing Issues5897
+Node: GPL6554
+Node: Licensing MEX Files8520
+Node: Requesting License Changes9567
+Node: How can I cite Octave?10345
+Node: Series 3.0.N11024
+Node: Octave Features12596
+Node: Functions defined on the command-line13174
+Node: Comments with #13755
+Node: Strings delimitted by double quotes "14286
+Node: Line continuation by backslash14795
+Node: Informative block closing15141
+Node: Coherent syntax15612
+Node: Exclamation mark as not operator15958
+Node: Increment and decrement operators16420
+Node: Unwind-protect17476
+Node: Built-in ODE and DAE solvers18365
+Node: Learning more about Octave18713
+Node: Documentation19002
+Node: Getting additional help19857
+Node: User community20282
+Node: Bug reports21010
+Node: Getting Octave22351
+Node: Source code22590
+Node: Pre-compiled binary packages23114
+Node: Octave for other platforms23680
+Node: Installation24150
+Node: What else do I need?24678
+Node: Other C++ compilers?25163
+Node: Common problems25694
+Node: How do I ...?27151
+Node: How do I set the number of displayed decimals?27357
+Node: MATLAB compatibility27698
+Node: Index44527
+
+End Tag Table
diff --git a/doc/faq/Octave-FAQ.pdf b/doc/faq/Octave-FAQ.pdf
new file mode 100644
index 0000000..9a8d36c
Binary files /dev/null and b/doc/faq/Octave-FAQ.pdf differ
diff --git a/doc/faq/Octave-FAQ.ps b/doc/faq/Octave-FAQ.ps
new file mode 100644
index 0000000..257f21e
--- /dev/null
+++ b/doc/faq/Octave-FAQ.ps
@@ -0,0 +1,4608 @@
+%!PS-Adobe-2.0
+%%Creator: dvips(k) 5.96 Copyright 2005 Radical Eye Software
+%%Title: Octave-FAQ.dvi
+%%CreationDate: Thu Dec 10 12:05:30 2009
+%%Pages: 20
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 612 792
+%%DocumentFonts: CMBX12 CMR10 CMTI10 CMTT10 CMCSC10 CMR7 CMR9 CMSY10
+%%+ CMTT12 CMSL10 CMSLTT10 CMB10 CMMI9 CMTT9 CMMI12 CMMI10
+%%DocumentPaperSizes: Letter
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips -o Octave-FAQ.ps Octave-FAQ.dvi
+%DVIPSParameters: dpi=600
+%DVIPSSource:  TeX output 2009.12.10:1205
+%%BeginProcSet: tex.pro 0 0
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S
+/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy
+setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask
+restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
+/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{A length product length le{A length product exch 0
+exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
+end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
+grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
+imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
+exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
+fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
+delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
+B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
+p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
+rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+%%BeginProcSet: texps.pro 0 0
+%!
+TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
+index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0
+ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{
+pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get
+div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type
+/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end
+definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
+sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
+mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
+exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
+forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
+end
+
+%%EndProcSet
+%%BeginFont: CMCSC10
+%!PS-AdobeFont-1.1: CMCSC10 1.0
+%%CreationDate: 1991 Aug 18 17:46:49
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMCSC10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMCSC10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 45 /hyphen put
+dup 77 /M put
+dup 97 /a put
+dup 98 /b put
+dup 108 /l put
+dup 116 /t put
+readonly def
+/FontBBox{14 -250 1077 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A30EB76029337
+900ECFB1390CA5C0C3A04528044F266BA17BE487C79B94FAC6D6484684C5BFEA
+87BCCC77D40AD11552035E95E3007126418ED49B68468B38A14E88E68A267B98
+076F1C9769A5AFBC285E5B158EAC9F926F1D6C0B8F1D57D9C31D25AE27123518
+9D2CD92E5689E0213089BD268DA5E47525CB8EABAA4B78A15AEA34705889AB3A
+FFB8953B5B3482E52BFA0940630ADF8C0AC2177D907324299EE980E850F203CD
+B627962F43D5A678C44243CDE97853BDC6AB45FD5C09AD274DAF89929F583CC9
+CCC24BDFC68B92111055ABA5F26D2DC67C70906F71C2957701D65AE746A60C30
+40E6CB24B97FCDAD0487AE38A201FBF0E41BABD2181981A71940F1E707F91E5D
+C8CA50CB16D8702D188E56D014D92F76CE0B52ABDB9110E32438D2BBF3E6A40B
+7B005F10BB437812CAC6ED2996F7606DC962C4FDE207FF322782C343DF44CEC5
+FF06A55C630C20E9AE1B0D1C5673753C43BA0767D65D1B451CC6380D8BB3C4DC
+81E8FD8AA79BE993218686F29D3CD925566DD587F541A0DA1B1CC3BCEA2E6C7D
+5E1016F6917A871F1BBAD96AF9E867735017119A381FCF33EB2D3E1E7093FD90
+CDB0CED4818CFD9E201A03430CEC713620BE0D3254158931FB657C6877C1B3D2
+24030F377820DA58F4B95CFE645109F3F1B80DB5FACFD7D05AE2909EEFCF95AD
+9CB286C8B6C075CA2267C101B736139863186C193E31085E7C9FD88EF8BBECE3
+933542C85309013325B4BBFE9A5B606780C8580ABDA2F5D0064EBFC23939B307
+08568C3B7F5F053BF367DEBA349FABB9F760C44D100BDEEFBB01F27BFC61FA63
+A4A06A8A6DE448B703FAC1C902F6D832654461543E185CF1B37142BFA33E1913
+633A92C7B380198B75E8CC28B64D333DBA92DCE2AEE418CEB99E48407FA04A04
+0E73207A062492DC13CBB63B0262CE6BA48B0F6600BCB36AA5010D9C1D2B18FE
+D86BEB753658CDE069183A21903D07F5B6C1CBF06A96E5E647FF9D08E353AE19
+32A8F4AABD60E58CC24169A507F24075A93FBC555488B4552522CD780C8D77BE
+8214C0E17D7AFE1744FAA434C28FA0B0D239A51F909F56F23F292EDF468A4B38
+053F0B2A4036A11C93A6CCCFC27B335805602957481D6FF2C826026D6E5733D3
+CBEE543BCE989C50506514327BF44DA7D742924651008B21ED81255864789383
+8FA7312B86999635E55E645DAB080801F9CEEAE8DF1284191FAB1150614A0947
+9C92FD1080A26ED1EB9B3871A5098CD7D53C759FA9478E3BEC5796E00A8659E6
+AAC6395D143EF6C887CECC2EBE66FD35A633CCA8EAB76CC9EE9AE7119B2DF590
+5DBE63A760918D9547EA570B432CD3D44C6C574D84C60712A6CB69CC40A1C636
+409D2B7D724607E9573C6B70ACC533ADF70124FFD8FB4356C9F2833572131541
+605B9323B6EBE286D062ACA0277C5B5CFC97E08CE15D74E58DC9011FFABF4CB5
+A6FB5612D555084B948AEA7809DFBBD5629BFC62185E093282BC656D87B553DD
+ECE4F064CFA5A44CD77AEE471BB7B8E59ED91DE8AE9F40164B5E237B247B6C65
+5ACBC0B8721FE6518D581600AAD1E4E58126C4BC373459B46C6ECEC22D6D5EAE
+0F3535E983E3124DAF50B9CECF0BC8D6126D45A3BF1FC9BFA6FAB8AA771AC46C
+7D56E989B4673E21E6F20D0EB64F66C8A6D7D183DC1DA81B0C20236DBA4FB69D
+B6580D74F12D2C401FCE829FF295F9E7FB456610C7C5AED14F2B5814AB1634ED
+5DFFC7AD733CD4C4A84486DA99EB95082A6A235A3DB65AAE2A2600576F732F26
+2D15E28AA1F1FB33E34B43987F7882138E562D373383255827EEC34BDDB4BFD1
+E7AD11DF2460D58D175590A55A959B9C76DD8EF9CE33F1373A1A2F173EE19670
+F07FC38BD0667A0FAEEE3CFEA6FEE9FCE9E37B543B0A93AE80004581C5DBEF65
+7E68D3D6E7F3CED72AC57528D0AF3975296AAC8FB8D7A9C4973E088055AE4443
+BB58E6B489ADF4056C825DA60A8D63BABB3664529E2BE790F351BBE216BF9B5D
+2F62C516DDDF58A17315A10A3F11A3653CF8AD35FA6461BEA263A93AF24DCBE9
+463DA4AFBD25EA3FDE3A24D8A4DBCF4E2A6C850D8625A57038E4EF4424193ECB
+D6E9E816FDEF2948DE89A559CBEDFD187515A9D363D4EC969782FF7B77
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMMI10
+%!PS-AdobeFont-1.1: CMMI10 1.100
+%%CreationDate: 1996 Jul 23 07:53:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 58 /period put
+readonly def
+/FontBBox{-32 -250 1048 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321
+990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E
+6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB
+DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721
+59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823
+D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF
+8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808
+6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9
+1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE
+03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909
+95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1
+74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2
+3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8
+47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19
+AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8
+42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8
+40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837
+B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53
+9560176676ABB71BBD0EE56B4CC492C0652750227CEC6CBEEE374709231B00CD
+0DE83AFDE295B314F6C8B1FFD32251C1925D96A64D739FF1DA4926460B28B3DE
+E949AA0BA3DDB16534FBA30C32092D5F712B5E8C8D5142F35AF2906E6C219D2C
+7FD9A368C193E0EB9C7E25FF03C546B6ED993F964CEDB1B8537C617170787F37
+88D6F2AD02384B01067FE3F98257BAB958BB3BCD1001090A4502DA0638080EC6
+DB784CC8AC37CDC01B29BC481D6A05ADC6188785262358C1BF1D694BBF31C1F1
+AF117C1ACED44AAC6EB4B9A2511A6762DDE8FCCBA5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMMI12
+%!PS-AdobeFont-1.1: CMMI12 1.100
+%%CreationDate: 1996 Jul 27 08:57:55
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 58 /period put
+readonly def
+/FontBBox{-30 -250 1026 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5
+5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC
+4391C9DF440285B8FC159D0E98D4258FC57892DCC57F7903449E07914FBE9E67
+3C15C2153C061EB541F66C11E7EE77D5D77C0B11E1AC55101DA976CCACAB6993
+EED1406FBB7FF30EAC9E90B90B2AF4EC7C273CA32F11A5C1426FF641B4A2FB2F
+4E68635C93DB835737567FAF8471CBC05078DCD4E40E25A2F4E5AF46C234CF59
+2A1CE8F39E1BA1B2A594355637E474167EAD4D97D51AF0A899B44387E1FD933A
+323AFDA6BA740534A510B4705C0A15647AFBF3E53A82BF320DD96753639BE49C
+2F79A1988863EF977B800C9DB5B42039C23EB86953713F730E03EA22FF7BB2C1
+D97D33FD77B1BDCC2A60B12CF7805CFC90C5B914C0F30A673DF9587F93E47CEA
+5932DD1930560C4F0D97547BCD805D6D854455B13A4D7382A22F562D7C55041F
+0FD294BDAA1834820F894265A667E5C97D95FF152531EF97258F56374502865D
+A1E7C0C5FB7C6FB7D3C43FEB3431095A59FBF6F61CEC6D6DEE09F4EB0FD70D77
+2A8B0A4984C6120293F6B947944BE23259F6EB64303D627353163B6505FC8A60
+00681F7A3968B6CBB49E0420A691258F5E7B07B417157803FCBE9B9FB1F80FD8
+CA0DA1186446DD565542BCCC7D339A1EB34C7F49246E8D72E987EB477C6DB757
+99AF86CEBCD7605C487A00CD2CD093098182DC57B20D78ECE0BECF3A0BF88EBA
+C866DB19F34BBBED6634AFC0F08D2AFB2A92578A6F8B4ADCD6594737FF6EED7D
+5B536DA9E3E2CADB40DB7C600EA4D100D33C3B92B1CF857E012C4EB370BA8295
+55B50047CC8911C98FE1A7BA6CDEA82D34476286E710776823690AD333DD3A49
+335002F4680DBE1C21174BF016B0DF799B01EB9D6988479A8334BBA2F8DC7146
+BC0DAE9DE3A6453B181808E68A89E0C02DAC6264D002B422EBC1CF14F65D9888
+15EE6D514D3457F7F3C6A3D17EE1DA076F73ECC392D349174DA9E4680F29CE10
+0157E42CA35F5DBFF56BFC3AA07E61A78DBE882C5AB388220C19750D3643E7C8
+23D6673027CE568A4ACCE1D12B1D9E5A43507F4AF9BC873237F65A6B95078DD2
+378007CF0F0DE7CCEF760E19D6D1D7B412EC5D4972
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT9
+%!PS-AdobeFont-1.1: CMTT9 1.0
+%%CreationDate: 1991 Aug 20 16:46:24
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT9) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT9 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 43 /plus put
+readonly def
+/FontBBox{-6 -233 542 698}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8232429ED8B7CF6A3D879A2D1E
+2931CE5F5D18C658602059F07BE66E6EFC9239D7AB2FB8A4CBD41675B8ECF279
+650C29E53B14AC0E392A664848C1844B1CECBB2D5CFB72D0916B675C9A9A1E35
+F12696A6F628473C604A95376468E06E295AD6F76CEB939D94113532050B9D5A
+D2F41A9EFB9424D986612313B89EFE9C8A71313340B248F6853B1EDBF02B7F9E
+F447220FE131D7D54CFB8AA1281DBAEA73E665BACB1F164552CC0CEDB63BD4B1
+4A9AE8AC6FA02242DBE8DA46B64B6BFC11762F0784F216FC8B9120D688D1705A
+438B14F5E5DEAF2A98408B3B64620DE3732A4DAE6D08D5D97E34C75DAE19EABD
+BA0796165C1151BCBFB1DF8D29A63A8300DBDB9E3323CB82D0337598B83F4F2B
+A97CF5196D4D1CEC1EDB8966E548C0D9C194C932319610FB43EA1B86322FE641
+AB48770FF13BD475A7267E142388563D1A400419C585B22A9886074687BEDF74
+D905BE8EE440BA2ABF28EAB673399B7F129B9729DD5564C681954621903B84BB
+CAF89AC5ADB2932472DF29ADA2BDBDB4D05F65F28F5F4C529613D61858E0074A
+082A852710A62A147C966F2B85B51B0BE85F11D2057C66FDD61F6C5755367980
+9F4DE680601D4DA41B46F8D2148450000413C27AA39B586B74B977B25F0FD3C0
+4BA1EBFAFDBEC531EA13DFBD6700E53818CE04D23886B8AE75DCC36BCD3189B1
+0D55FAE27D0D126E82AEF31D7B5DF27E58C30BB0867D6D7AC1DA9EFB8A2DF095
+B5B934A68EE122DA0A83B36C952431586B957990206194E89339048AA6EE4C53
+703763505ED57C494DD907D0EEA04F6B1D4C8F3BA778F4E7AA832AAB4D75F024
+61E91C6D25FD6823CB24FC863B44EAE226CBCD81DEE29413023C52E4C515F83A
+438044BADA9C0C761E5DD2D956BCBDD4840634177563DA23842B184A296634BE
+0A0AB6BBA520664C931B1C9E15FE06AC9301D2F91C450F19E49631A384DF168B
+BA74D9AEBBF7655FE72479CCEDC2603F30B37B52DFC0BAF909F7AAFC3BC10B5D
+796EE4F6FEDEE6E50E6E41FA6E1AD4AB2D74EE1312FBF54E0CA3483C68BD44ED
+08D0F2F46F272A28FFC147144E9591267FA724BBBA92E064A27BFCD740D93E5D
+19E80D877F088B4D85B0A683ECD47458B9BC6A7A00EB36F83955B17C55F980FB
+A8FA0DA2C20E25E8AB13861E574A8F7F57B949A3D97F1DE25509301DD18855C7
+4776FFBA1B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMMI9
+%!PS-AdobeFont-1.1: CMMI9 1.100
+%%CreationDate: 1996 Jul 23 07:53:55
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI9) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI9 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 58 /period put
+readonly def
+/FontBBox{-29 -250 1075 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D6F5CA5FED4F9AC9ADE41E04F9FC52E758C9F45A92BED935
+86F9CFDB57732045913A6422AD4206418610C81D882EE493DE9523CC1BFE1505
+DD1390B19BC1947A01B93BC668BE9B2A0E69A968554239B88C00AF9FBDF09CCD
+67D3B2094C11A04762FE8CC1E91D020A28B3C122D24BEAACF82313F4604F2FEF
+6E176D730A879BE45DD0D4996EF0247AEB1CA0AB08FF374D99F06D47B36F9554
+FAD9A2D3CE451B7791C3709D8A1DDDEFBD840C1B42AB824D5A0DFF0E0F15B0B7
+22AEEB877FF489581DA6FA8DA64944555101EB16F7AB0B717E148B7B98D8DBFD
+730C52937E226545CF8DC3E07C5BA30739BAFCD0F2B44275A6D503F582C0FB4F
+449963D0AD2FAFDE33BA3D77BCA9D1DF878DDAFCA2E22CC4BACD542B282164C7
+97C2BDE318AF9D501CA21F6E662E7AAB75A5F24D2C182E598D175D44E88AB19A
+E7CD59584F95B389183EE21B525BF52A3F23C0FE5383A5565A19361D716F508C
+AAB78411CA5A4D27552CC1C435760D5A89D535B71C593E755C616661363308DA
+A683F54ED0C23FB2C225A008392B0B719F66F11A946A090B7C00B662A3C69599
+B4ECB0CC70C85C4BBBF207E0026F6C7A19F2ACFB7A60804FC98A4BFFD7BFFF2B
+9529E6D9D4238002BBC255BC62959D6F3381FE06E0621B879D5FE5B541D45A1E
+759A6E7DC32B1D1632368D09A97039DF255B6492B1B2B7E2C1434E8306ECA7D3
+5A79B6D614B4979F10988BC76ED53A5F45315CD7DA216221F842FD0F3E050DD2
+BAC23C984D506D8F7D614BCB6B244F5F41321549BB0BD041FBF3053307168680
+3435E9C9445A59A7C666418C4F2512C32058B1CE1EA46C7839C6E372F6CC60AE
+2CF46DD2F130B532DE8ECD42D9204500E413799E298CF6426F28D23BB7216BEA
+1A618B3ECC61B44DDEF0BB22D640B47C09AC0DF378CE68FC9CD88BDAE9ED89CB
+431A5CF9C3E9528FEE7A9936C2B1CF7B38DD2B95773F0EA0051607BE1B0B3588
+A8B907A5EF011B4622C5093A7B107DD1EED6FEE9536DECF1CC96E65373D0F433
+30AE3C094654ABF4698C07F8C74E71D023DFD242EE83B1306786124DD8C6BFA7
+801E66CB944BE7EBCB3FE803EC97067AF7AFC8A4E9AC9D11
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMB10
+%!PS-AdobeFont-1.1: CMB10 1.0
+%%CreationDate: 1991 Aug 20 16:34:36
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMB10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMB10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 71 /G put
+dup 77 /M put
+dup 78 /N put
+dup 80 /P put
+dup 85 /U put
+dup 89 /Y put
+dup 97 /a put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+readonly def
+/FontBBox{-62 -250 1011 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8B731A88D7740B0DDAED1B3F82
+7DB9DFB4372D3935C286E39EE7AC9FB6A9B5CE4D2FAE1BC0E55AE02BFC464378
+77B9F65C23E3BAB41EFAE344DDC9AB1B3CCBC0618290D83DC756F9D5BEFECB18
+2DB0E39996C010F3024A5A3C69C8485664A4E3AA81348AE21A30280D0E3B6542
+A770F048F31907891EAB8B57DC70FF775574D6CD26B8AC9C3E64C3631325BF0A
+99AB413BDADAA3B51A3E168B03A856EC7D346A38BBB0A2700A23B2CA91120B9D
+2AA5BE5A359C60CD78F055253785CC9701F5D670ABE4967D74838C3B267C6563
+C9651AC41D8684AD5E913A5C9C547CA225A74782D1AC62020FC38E29C356950A
+00E8F2B0752CDBF81EE4ACD59BDEBBB9523AE4764B995855F3A401EB4B04EE56
+B10758196CB661448A3617B83CA88C41756EF131CFCE0C968B94B6C69AEC1E9F
+BF8B21837BC422D766B5089D81CF35A807394A026FE3160580695B1213968D90
+8ECD1611E719A871E15C6085A17906F77B5B2DFA6AE670976758E67F8A4FC362
+FC7299D85ECC3C0BBAD4649B9DAB4A2FB248D6481CF0CCF274634D37A5AA4DDC
+31F3138AAF10998FD66F3817B77060E71C6D8F17205F9C098D81D952E0FE3831
+2264C55D73215176470D8D75E7BE6E44514984B9D20208DB3ADD4767CAC09D41
+9C8DAB6EDF4FA1AA2CB285CA28E30972B3BFA4F8600DB92164865738B015A331
+EA9EFDD478132047DAC28DD4FFE419F94CF5FCDE732E53FD332ADBED32F76B2E
+69531BCE0D461BA3F41A528DB0CCEFF9663FEB3EC9CE0F760604F835699D7C08
+CADBF7AA3DCCE9E813D66BC62C6E452FA02FE7E5F4FAAA527B4567AA4FACE790
+87910AC2498C0999866614C90AF7DFD65A59B9183FD8AC5DB9AA81E8E9055D15
+9EE4095B305AB9DE2CD55BB4B397AC184E30FAAF0402644EE68ED4AE981EE274
+4ADA70B275CBEA65A669ED2441C8ECF15D7417BECD22C88A3115E7958CF97F7A
+2CEF95C2937F7670932B8184FA0C14117874EA9F0E40A26B88DACB9AA5824EC6
+9CD2D52E2EB200C434E8857877D3489D7125D15DC918BB4CE849291827ABD343
+06532C83CC290A1EC8A1AF9FC8169A3A6380EE15839D7EB9CC6BFA3B2419FEAE
+D292EB6F289DC6728899A9B90876AFF504703840123D4820E287313019E0D4C2
+F3524845C46FA4826500A350408291191F13A2DC4C875FDBD99500D16A24E370
+F36F509BED25AF5CAD97104404DD4D09EB655A1A2901CFD826B9207FF1F6A528
+A58B291F98128A4522E796B07D97138BED5FA2B6088A8750D1D3DCD301CBB682
+C89E4323FAF4347449B6211258B31D9A0AB780D48140483824C80F2DE7EEA129
+A159E1927D44E82ADAA783FE0778C4C659F13A71E0F6FF97C01CAF1878707A99
+D9D05AAFF4A9A47704A6E2A097E014BACC5629BDBFF429E3603DD20F534B70A1
+EC3FDAA55EFDF86A20A9D0DD276ECF75B9A1619C4D1C0CAF4078FEF8781A9DC0
+C711FFEA3F1044182DAF8986A237A095CEFDD1F14586C511482172E754AA6332
+8C8741CD450EEF1732F44B8628E14C6E446ECF9FC1B5A3CA9C8D0D3601D60C32
+B4FB0F400F408C984F7E7E41A9C05388E162947F870A960947D89CD3495DA677
+C4A49B0C09CC374B4CCCB4A7BEDFE58901D3EBDF9D6CB119D4040B1D4D4C491E
+E4FCEAC00CAEABC1C1D5FD7F0076700A70E3D83B43AC64D79CEBD95A9F5427AA
+2D0CE2E4651CFE05B1C21302BD02C95E06625EE6F45597EE2018A00F6D503866
+D7C7ACF2E824B34C03B6680BF61093B50A9EF9E8BDA384730D5A81885929C147
+F5B6525E344A10F9511AF12804D7626BB1A7CC72B8C69D8027AF435A07C010A0
+396EF3BA6F0DDA28A899074E5D96ED37BDFA5D985E89D16696AD30AF1D0120ED
+E40CC6C1AC5753E74C21FE71371D2773772B1119C893121324BBD77C179DD133
+C48A390932FBBEB9A8F08028D300901EF1A7872122B5B4ACD2B87E86B0F1BCBD
+9DAC2B8A9A6551376373B8719749DC1B91868947ABD946121D09CDA191A41031
+213EABBC301D00AC0FE7EF785E4845EF84B1BEE231DBD11A56928F6716AF3D13
+D2C1AC97C589DAB2FAEF601FD1998A4BD6F09725DA7284A165238FF1D7D8FC9B
+6BCC20FA2840C62E1E510518A107575713A4FA9D0365CF2EE988FFDA89249A12
+905E9B993514CEFF32FDB491D24E83DFB3DA6234938939A15BE44180D438E95B
+68DB67D4C9E0E6DAA677B4FA06881968E29A5A2F4A887D2F4664B791B32ADE21
+017D2B20C0D20313B06C065C7C2BC8AF658E9BBC8EED2A014D742A352F2603B3
+D4DFE96B931E3FA783076F467AFD73B3BCAF1808E5517F7BB355C1083A60863E
+037B50E319EAD1B50D0ABEAB9690AA9F36B411949172E4002FB98B930DCA88FF
+C1E3591FAC31B65627755FB06F1ECE83777761F6B599317948A795F632D02F29
+D120E1C6B0C7F2DE6FA6F7B966C1CAC9386930377C42637620AFF91D41A77FC3
+212C5CF548DB96F9E011DF3C65A3E9692F8C33CBECFDA181ACAF37DF2E75857C
+1DA5F2177A82B8AF1A3563C7D135DFBF8EEFCE1E58A6DD4DEE37008A59FF3289
+EE2C0BA99939E14F164319057DFB9B355F13B540FE59290AD3531BED898BD246
+039A1E5C34356BB731637543DDEB7FA8034AC66CDAB0FDB50C345C314156B33D
+E3DBE9E561F99DA53DA75C03A26F5A4F763F1A433F98AEF843E6AE6B6F6E7B65
+4C6FF45835CED5FFCE86CEB3258FBA9001CC82122D49355D94014336903C40B1
+E4922057C7D66F70A904775DE0D220AFF214A7D5ADB757702AA0F9425160BEDD
+8F23DCDC4A90EF09FAC406F44C4C69DDF8D4BEFD31DEA65AE26859B75DB6F0A2
+1319B671404FB6D7B53EA244999BEEBEC9428FB9B52AC6B2058DBE84C5320186
+243D0AB8E138FC81C9C48AD43BC88FD11FE4D74178B29EEDCDF8D9382D29788F
+17791EEDF0521C2E4F1C193FF558C370DB014B38640FD4EBC222C583E27E80C5
+E707FF06BDC7F2A0FF6E86BFB97D88E2041269F7158322787582A899195D1FCF
+AE545CAB2AB4F26654643844B7DA78086D3CC076F589FAFE0BCC62ED079325E1
+192850239115DD051E157D4AFAE5074CBB0F443CC91F46C37F505EFE971FD365
+1BBB04C1E58473E4CF913C327209A192F983C1DF4109F82D82578D5E91BCA999
+2DDFBB9EA64B4C8DE218CE130B0539202C0B304C84B6BE4B76046359A3B865FE
+9F3BBFA33A77FEFB192DC99A989B45786E3CCB313211138E42D00405356EE9A9
+97AC15BB55433714D4304CE87351E99DEDB3BA6F51A51954EA86D181D9EE75DD
+F8D7ED8B669A0A3BC7854249D00C84FF17C1860BF2516A5395BA8BBD76D45179
+D231B9841D4983DF7D04D7296AE194D1707F4244DD36151A9338A2416949E547
+9991E2AEA6EE5A3EFD5748E7715E5E57A751798EC78C16E5E48549CC0D2BE96A
+079AD409771E954E5700E5E43E6C98678BE5E0EDEB778A94FB65E2E2C6EF08A6
+CCE8EA18AE0F63ED63A0DD245AFD21DD8B7B5778CCB6BD6CC0985C85244DDD60
+B04FE8135374BAC8E799B21BF3A3E1E0494AE79133A7FE7FBA8D5D4C91F4ADEE
+C6ACBBD78D84F1D633DD8C34D9C615678EAF6EC645FBD88632B03DCA49E80327
+BAE821A6A071C61C1C28712FEBD4A7EA320A28D8F88195A4AE46641B67D38054
+127BC6E5325F6A626B8EC6F33FAD0F13C811660119CED9942163EF0DE49B8F84
+27925511A0E55DFAE7EDDA3C7146767CDFA15B62E2AC3F8133992DA47F0CBFD7
+F1FDA1341B880BCC0A11198A9C4A8696ACEEC2CE278B4D57BC35DCC463341498
+3DFD44290E3872857BD8F91FD78C3E0D42B6968B9EB400335A58906829D58AEA
+01CB16FBADFF68B2986DE8E2C26C691AAC0E120CCF058F30C44EE82FE323C252
+227EE7BFC59D445172A81A1A172F8DCA72CFA91732C59973C75843849E3496DC
+E624596E4FD7791DA51C9ECF5AA0F59AD7D47F0D1D4E5A044E56F91C95031618
+01B6D1951383CC0B166C1D03A78680E1747AA8878962A5DE05457BE1FEA7FEFA
+AADA99BD4E6160223F25A83893DAB448F344095FAACA74FE5FC3CCF0508AC7C5
+B5EFE00C2A5A0610910232624F7996C013F076D0DBAEFA5F3AEF78419C53B09A
+F403A810F2DFEE829825280B9E83A97E60D90DF5A4AE696007B492B16E5D8F1A
+7F61514E74EB2FA47916892B9B11664E7E2189A6BE193FB80E6B0C57BF406B7A
+F8A7F3CE7A342FDB94A0D9404320E40E7A6E43B7D4E895122308724E1F3C714A
+65AF4DF7C7CE6071297B5C57C6C4E88D35E8CB8528DD2C9A85C65B830D318020
+04352F025061EDEE5BED437CD4866CD9768A0089C652FBD44AA211CCC9C3BC6C
+B945353383A8C8BD2910134FEC7E03EB71CC1130C132406ACCEF7CF59A5C4662
+59187B6B70E95A96435B7FBC9261D7F0BFC6F8818AD934303AC6638E4228DE42
+1E896F7EB612DAC85897B009E6A51F087512DBD434EDC6A74224D3F654D8117B
+88F68522D464969FD803DE22400E3465E991BDB57092DD229212BF3B0A45C5F2
+31754F66BF38A4F793054C6459EB08C0882426081F475DFA06F846154A377DD9
+098356B0D873AC73064C7AC4AA5BEE4282F7BD42DE82D4E58EECC5B2AB62B5BC
+ED19EFF42375072843F823A4E0BBE2BFD5C5F9576B765AB74D47B984D3CC271F
+669381C886DC3064FFD636E6EA891A1C41902B011E5FA4618A081F67EEB14FBB
+EB89465CB3576E10453C986BE8A76660922A4E3F4E1AD1B92353F0A93FCF4203
+571B05A7071E4398DE46DD84D6C8AB0AA6C947B00753A9993B194EF79A9BC15F
+936C1F744C082A1727AF65A9D53BFED8EAC89348BB0FFE0C69AB53E8DC929DF0
+6A6E348F0E8113ACDAF8381DD242C4538628EA786613F85DCF0BBB8938698905
+B37B5245BFC0ED267AC5C88E2BFFB8EF5B0BE1BB4A9DF032369B7CE86EF40FC9
+11F719AEC0F25832CB6D420327C6EA50356F7415DF319A237B7E4B8A31D827C4
+64111BCA99C343CD1B603B87EFE23F4A0206ACE5F766093A06D100C91B6DA257
+A4A7612EE1F1E89B3EF865552A15740EFABBB0A8CC78E6BDCB6081D0BB5B7DAB
+716432EA180F18C9A986BB3B8776BBD1B5177C7CB132B0F03F97811417FFB8DB
+4888F13A0E4DA561E196A8CD09A943A7CDF5731FE381BC4085E1923CCDA12EDC
+BAE5D60E1E557105AB70696EE67938C432831CA85144850FEDDD16BFFE79BA03
+70F1BF0D505FCB79AE1169D1880B4897A89545E17BDF17BA29D7CF1F3E544551
+945EEB6E49A63313532966AE549D1033DC3AD906C2A4FCCC2975D2C0E812232D
+2871CCBCA3891A571C7659C61F327EEFEE45075947697176BA00D0DA04ED303F
+C43092809057535780E434CC5700555D5DBF088A3A62353DB9E51EFE5F011B27
+3474E09CA39268337AAB0D3501C872864453BCD3041236421A804132DA9DBBEC
+C8A36DE3D9CD728A711091EE56F9DED9E2D0569B24F61B121B93F3529D23C62C
+F341B58679ECDCC72C067D8E9969707B2883542B81C53A20CFB9A7D12C113A4D
+5BF3E2CCC9C5A599B6FA541E9D91FF817810793138942BE303047695695462BF
+7C1BA4A2AF2AAA5D30ACC22950AECEFF6A74E4151FFB4E7A12AC642AFAFE2BA1
+A0A2296CE5D85D79AFE7053A42C2DC80FC4B56643AEB9ADD2FF7332A0176FEB6
+D892FE672A8E1EA1F60121F4F06C53259507BD8339E470E54CC2D41CBE3A5578
+72F93147273327589A71F0156810A1F076EB1F9CCC09118F57EC0EE0BB9638D3
+F7D07D8824C6E1624198D214C15B2DB0CA675FB98343A220F276C51F6B961700
+96F71950202B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSLTT10
+%!PS-AdobeFont-1.1: CMSLTT10 1.0
+%%CreationDate: 1991 Aug 20 16:41:43
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSLTT10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -9.46 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMSLTT10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 108 /l put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 117 /u put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-20 -233 617 696}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0528A405DF15F03DB1C3DA8B850431F8
+0E5F73DAC973450D1ED0530313057E971FC7E7CA88E61DA6DB9A5CD61F0F76CB
+4DE9105D0627B8DDF51A655098229920CF429CDAFC3F7788C95E7AB30E84F840
+8CED52E98DB4CFF161D2E62B0D28CB8B0AC82E7A8D2C007953BAFB3056D66079
+8064956E257D31C13509FB81A250D9E875C77A4E91CC49E9FB3C0718B2F691D4
+B4A64F351F4DD68133DED7629B0D96E5124584A16FD2AC7A3EB244A934FF059F
+ED7297B0505F3C2994AD66A3CA5D2728B034DE94B64A8AFAF341601BD4DB5858
+C9950A8BB9C598B8960609F48116ABA8C007190AF0ED335EB5BF61BA6871FA5F
+EAB5A26AEB5C7C352EB80799CEB983F19EEFA801093F62086AADD0B80BB6580F
+2CF61B1390FA56DFA1A0B61C58DEF96BA767A8A37EA44730783C600706606C60
+4EE74EA99B7C0F8E2525C8847F3D31907C3C483EFA98F6C416B6B2C343DE6370
+52FAE423008D086A76A1FFB327CC7FD84B1C66B203A4F41582F4599A82F8362D
+38108452EACCC937FFC4F3ABBFE3628DF51367DA6BA3F6826FC6522D6AC5E8EA
+00BAD300FFB6DEDAB93237704202BACD030AA824B1E97C0AFE17FCE8C75F4FA0
+B8A74329A6CF1788C7EB34DA7307411E9AD7ED8D6582884456E06E033B4FFE7D
+CD4DD8B06AD01340CCCFBC382C18CA451E4C886B01D082FF8CC5793F4727C3DF
+B52B4F1A242F31D1EB79D1E39A1D4FD13D6C5E2A42AD4B4D1CC4EE7BA0E5F80F
+802E5AB57EA15F4DE44D82AC408AA86D4BF58EF967FBC6497BBC7F017C0598AE
+32CF865DFFF0FC7FF9E6DCE9B5F2F4C7491AC674F46E8E7660452CE0A77C1EE8
+00DE382ABED85350033F8ECB97398E4E0A75D4877A107F6A909D0C76D14F9A96
+8A6CFDE3FD9D79B6FD82693A9F354BD2ECF30C6D99F7AC522F8D6C93EA214F7B
+3D0ED77F042ACDE9414264C0698E86398562E2C640DEBBA0734AB4C3ACE3907D
+CC79E6B2C6C3C3F9B01526E8CD98237D4A9B403FF8CE3132222FA60C196A19BC
+A2393AE6935C0F8B67FC1D1A10C5C549C4FE46D774AD771B09A7E74AD31B8CB1
+9D4322C755BE5D1FE3F831627E32BA52B658285F494101213D9CECCC2A0689F5
+9D978ED69DEA3F8D049ABD577EE6BB29917C17A41568907A6459BBB9B0057630
+AB2AC9E27A6F18BB276FA21BD3FB7B6097DA8BD3565BA6AA128851AFBA3CE04C
+CC75ED23A8EF51BA7BE31B5CF2BB3CBC124524FF9986F02CCD828325ABE143F5
+87A4E5076604E6A0603FA82054EC169E8C62972A47A74ABD66C69475181A437C
+8889009D06370CB5AB5930B0889237D6EE7B7A4229494D80AC9DC87F14C21EFF
+51279BA22B1F625A61859D5AC4165C4895BE8F324541F4CDA102B4FCB6CDB6C8
+8FE67CF567EFA18BBF0B030D64174741F2731DB0D1F06C6886870039362610BD
+ABBAEEE38DE083D942D022CA97F7C3DFE1A43D75CBB57119A74282A25C6A1D2E
+054A9271CF2D42C78667A56D23507DE74C53D6F3942F39A38B341967BA2BC51A
+9F912462046894A9C9B94485D38B763BBBB402D178B8847D828700FCFE6DFDAE
+42636DFA3E99A42D667742AD39EC28B100236F9B1F483794C28FDAB0E9D68CA5
+D40D9B6FC99469B41B75BE0F9BF0917E330BD1CD03D14A954853316323CEF361
+69AA81ABCC59EB0B33297D75DF7D9C96CDFD0A45EAD8C0235CC040CD39ACC10F
+9E7377B5B1C0127C76FFC0C3CFFFE994F8C1F6C8C6760CBEC3FFC5CF3D912B70
+19D1960566283B4AFC933952778243AE3233D08A230F59E89830A60C367C147E
+6C155FF9CAF526CD45E1C20107344FD11131BE2F1F72C443D4C853490C2AB0CD
+4BA5B50FCF5F9A5D1232CAB829A9665B7D404F71A7BFB67CA9C2A94EBF6951F8
+A5DECCCE0DCE10701CD192402095908EBF0991A36B226D8193131079EFCD572C
+0609FC8F9A91AE790926EDAE904803B4C1CBA2804B9AF6E8793C512D5927781A
+0BB45EB6E9B1678B617AE01A85363C6997503A931D534B523824E60351EB1A83
+BBF935CB9C94DA3B637ECC291FFB2027BA82ABA9198E31266A830F8289DABFF4
+A82F25326717E6A20AEEE0AFE3249989BAEDB1525973A2DB6EDD7ED195F84D90
+70D1D8043A45237D9BA441ADDE49F4853C54EF4E13BDDC1BB4D795E410D5B786
+9096CA8FE3415A7056A6D40FE32F54DEE882E145C7E1EFC87118B25FB9616D98
+EFDD4241E8204F06B2A8F00D5CB5DB7630D3D1726A40910F8C1C40570333CE7E
+BA6C2468B8853EECB08AE39BE6E54C36723B0E00C89371395DF0C8B9846D42CF
+49B9014799415EE376D394D56B8AB9BB0E76CFEE7B81EA95ECBA5FB362B0E199
+3563EA4035E863E90FB0A0124E86A63EAA8B0127350CA12F3F0245062EB994D2
+E1489CA208394FDDC495D12924708F14398820F5DB8CFD0DFF4193B2A1E9EF84
+82E4DDCAD860CE7DE4F83BD6650AA54F9671E66B950D27CAD580AFECFBE7A62F
+303671896CB8625A1E4107DAA1E47DB7C863AE6A42614CCECAA59920B7AF8B62
+EB3C3929E4963C9EAD57DC02F2A1CC0EAB09BF4D1D358E4E2CB46DE4D7F28925
+8830FCA80B7BD0BC0A04F08DAA98406243A0C29BED4563FB20F18CD3959C9BEE
+6DD62A13C94188586CE088FBA58B0767C4A64D590756FD818090B77BF7081DCD
+9948A03E0E91E7764B6AA1D1383BC4C6FBB1C37A5DB23ADB6276DE097449B0AF
+90B607088676CCD618E3FA37CFED916A77D79C904C12E16E6DE40A21CC27B017
+26C2387B0DBFDCF34D098683C1667C12B7F10176DFC1F1A9A511518A9BA7FFD3
+FE8CBC24ED210FC6785AB0D32A5371186CBA97908246ACC1CC09F6DCB2729D64
+FE8E1B1958815FF853E2000E19FA6127EFFE2DB6706302589A15A31CB14CAD1C
+F07B7BB37C05DE46EF371BA3696C5DE408C35D14F554C1C90286E2A77DFE87CB
+CE88E44E194FFAAB9085E510A6D71C898E387D42F45D04BBBCC1E67479CEC58D
+6F8CA81C51860F590A00BA5128FD117DE0D67A9AF8E54824A094852338CD39DF
+8F6E0D6F143C222B71D2044281ED2B4132E7DCF13457E158FBCE407D4C671491
+75B3E888AF301B8A08C5005FE2F8D912426022D5AA5EF8E588D1AE4A69D47585
+981CBA8E87C26CBE3CFEB295CDB7A39CBBD3F77E0ABE754F14070674EDBAF6C4
+3D9AD02FF26141D47D702A6CD807338EB8B460E50B053168F97C936F28678A78
+8F433EB150349892AEB079D372B1005740E5E8BCD38D3D211AD8EF6FD15E11FD
+93B9DD26E79B34D677BB2F5D3E6817583094B87D7C4F5B2851283E7E151BBA6C
+45BA89B9F0573AA45892F72C0BFA569AF26F63C1D800D9771364099737E6BB30
+50B6432A727AB8B30041A8EDE77CED6A24BCA2C13C414879691ACBE067A6B3CE
+6C152859DCBDCBE9AD5453C7DF1392F65BB241C4F865D9255EFD429E46D05D21
+CFC2A0819693B3ACD1F0D5105B3D82E214B692460322ECC52DA077A3389F1897
+70FAEB8822AED9F5A95760A724C36099DBCE6FE1B5D2F4AD370EB74EED8B8708
+B2F22E6B86B8ED6DBD703426E00D49D38F7A479EA550C88ACCBDB05D501BED0C
+6BB489F19FAAD2BA031A38110E4BBE98458BD395A8F7B2254EE80F35B68C1936
+6AB5942216298E98AADECEF3EDFE3897AD8C9F01C61DFD466A5036A7BCE63237
+52A1A0A2B0FD066B0FFE477468DCC6BDA43FC0C0428B5C7E681218C75E4490A6
+EE3D2835578634355330075D785D8E47A2ED4D8AF0B489505D43466E85826000
+D8442CC7086A03320089CA04BEA393
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSL10
+%!PS-AdobeFont-1.1: CMSL10 1.0
+%%CreationDate: 1991 Aug 20 16:40:20
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSL10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -9.46 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSL10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 88 /X put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 108 /l put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 117 /u put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-62 -250 1123 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9429B9D40924DC059325D9D4CC0344F3F997A99E6CC0676735EBCD685AAC9142
+08DAFEC78BB41AFC2F1C219910BDF41D6279284EF600B69776CA15BC8A34347C
+30783C52AFA60FBE3E353E2AE354CF87B558776A22C776C7A0B5AB5CE1F941EF
+C2D9CAC37294BF407A671F10E4743BF842143F4F7DFEE643BA3BBD8BB9E3F24A
+BCCF7F0ADF8BA500620C81033EAE8C4EF2C1DEF13AC575F1B3BBB66F093D3B78
+5412B82B67FFA087AF57182B2230F9F2137180CA58A7D9B2C822FF04BE6CD01D
+43B2CA7058C7B953F6D9B5D6E91ECBAA5CDE1159B0E59C83DBAD96D6C8C8BAB1
+374EF652D10C0F3EE7104472C98DD3572AAF2D45A70BF7061447E21EE3C3BF23
+DF39C2D1B35B42CD5297BEBE6BC94F7C9DC6E61EC67E4F677256FED9064BD3E4
+B51A71B1D27CA4E5AA9E1D8080E6DAB5310711EEF87C40859FA935B19524AE83
+63B163FA8397BDFF443227FEDF7DB27DC35D89FB1C5E435DA0619A5C88AFC73B
+89A2DF5E767C5B536BC7167A840A0C32BD57A14DE69A7D0D819AC36FF32F908A
+5070F32983BB007437E3500799DF5E0AD3710A4C0000F0098D5BE99F2EB9C1C2
+C444FD9552D0DCA098A94B3BF176F511CEE13DB7EFFAED7C47B5ADCF8D4700F5
+7B6DF50EE617C00966B9A2828882804DB7477F4A8CF5345B7F3568B4F72BCE73
+2E2AA5BC4B4C70E21F3AD9AFC3B8605A00D67EF9ED1F4D13DDAA920D45B43CE0
+0941BF17CF05D2B777C11D4D844AB20C0693D1DDF00B27D9E1AA2D98A4A06CC6
+D342AD8F644F4787B66CA7D861E7CE13FCDA85C1B0C9F94009768EA89838EBA2
+7818F4085B44C90C23540C89A817389BEA6E134159F543A82F0E7641FB72713D
+96E332559B03C9C71D1F9127E5608AAAC3C87586FDDAF5AA9A578B8BA95E9F73
+F4E65CAC20A67FC0E68705FCC1AE28F0860F8532A232FC3C84EB343D6CD327A3
+53BC979CE50CB0250CCE7ADD39C7E6764CED52235021A2DE6495F480AB2DE133
+B5CB78E36C9689399C6E259568A182751CBA74CFAEF70AD9B475185297A16542
+45B66696CD832C5AA3622A2F7B81609ABC3ECC14E4B8C0EC79A6A42D86A82379
+9E4D33DE1F8CCD7FB9A0E423A28126780A65573F3F22C518E52960E0959CCDDA
+FD534FE61969FBCE502B4974C0B16CC67A5D875CBD95E1F4CB2712DEA5A939DC
+7B5E7EEB73ACA44ADB8BB05659D87823922E9F68196C70D82A1F3BB24412ACE8
+F568A31651B1D86FF7C22B364E2B3BD4731F6BE7CFE7E4D47726FE1826CDB706
+8BB2775F360F1E88110B600C842D21F617869DDE98A5DAAB5AEA5A1F68F69808
+064F7ADA31BF9E3BFBBF5F312C777CD5F95A0C79E5C7405DF5C3811083598EF3
+E6668D96FFB169E64105F5ED3AA7F0A94F44E595B3CC0474FB9ED29D89C83765
+EB4ED9951C0AF7B75C1929E9B6A6651AF90ACD9D84C8A987A0E80EE16EF8CE5C
+345857B6DD2C89889DE54B2F788B7AB9106E4A0C078EEB255B9C1648F3EA1157
+831C270E8D64D9559313323D3667F797F3D6366A8E0CE49EDA0432A92B1D8756
+0B6BDFCA356F47BE0B23E732C90A28F56E52B786FE888B985243E72B446E09E0
+061550F796A31B540BD683F4D5368798B54452659BCC07D46B9DAD64F2686D97
+E8A494D7B9DE383372FEE841BBA5848D90265EE04297F2D747953B840146B628
+83406160544ED2C53DFBB2D6F18137CB6B04C1AEBDDAE7614BA37336A950E900
+59529A1E7F5D8919D113444BFC5BF31308A8EB6292B3ADEB7ACCBA192A28C1B3
+8A252CCE7616FA41000331D828BF174DE660AA82B8B72A7BE7E76E2E57033B8D
+8A3A1B192D48BBFDE73D2734673ED7A183A7F7DF7DE57FAF251D96BF61977810
+4E6AD5823A038FFAEFDDC2CA71F4DFA209586F30D31B590A4D5A37960423C5B7
+3215AF43E99D43746A7025794AC352E44C40972A4EBFFAECA305F3334EDAFD4B
+87BDA272B6421CD7487DBFAD23DF0AC0EA8369747933FC290ECC1ACC502E7B02
+EB55CBEA69A40D29C7C65EBA27FD5B0D36FA02E3D0CF06B1EEEB421B49F05C38
+2F7CF86BB074ED5AF4679DC389598CDF45B140383260E3AC33353C06BD094358
+5507F371C3DBF5B963090559AAEFE04D7D7AFB45D52538FEA20029BA8ED88E3C
+AAB93381995345113222166A11551C8B6C470192BE6F38ED92CC7EAEB6A38D74
+DB674EF4604015BB755BE816B1A846D3B7A627E8AC760429C830FD2925144DA8
+61F8FBCB5E87D04279280D98FAE69B5DCC595105BE3D007420CC52CB99F9BF5F
+09D3EFD6D2DE4EE9879122E0C0AF89713B1B8E2AB87AEBD2C1E97178B1B36951
+5C4DA661B9C9078756E737EFD12AD17979C376FC006684CD9957E1DE331DB9CA
+A9FB27B6F942C1B3B14615A07FE49D22E6BFE3C5EB8A7736EAB04CD5D256A660
+BC3DC49FB9E3E7AEB663D63B4CCC853CB4555C48323AAEC9D443C8A4A9F0D66A
+ACCF737DEE7D5B1708FD63286BCAF5F11905548717498E0A6DA2A20E5ABCA822
+25CF8DB101B3903D636DC3D7F75A3AD125C6FD7DDFB52DE9CC34986080402183
+E7AEF748E196417A987ABC6870D08AB0C7CB1A2E31F3E821164C8235249FC73B
+772674D15985865C4542954FDB9C4A012DE4C916D3B38A2C9362EF96A98B753F
+CD50FD68CF8EF5F5234143A20524563AE9EFAF564BD1A8E6CF9C2014CC37926C
+23A916216D80E931712D2B92F8BCE85FA6420005CF617FDC533095D9511E95DA
+7F235C4CE8FABD6A7544BD1F5E0380648B780232861CCD84B6AB90E2C39A2E01
+C81D5C65401E0709453E3B86E9B4D9FD93439BC2DB74850EC8AFA4AEB64597FB
+4139ACC28FA35DA65650FD64DD8753605E0200BEB8B032524F59EEA85B9E8029
+ACC2D722F332CE5A12F1688E48C748BD05EE703F3828DB030CFC8736AF2DFF38
+79E3A87057968C68A1C7770D3CDC9A4847121B3295FC3E6828524A9FCD3BF6A4
+01486A3F28645DC029312197A5C1B23B95F7E780A120DD2E4F2E6BA58C1DC4CC
+4929F72507BC73792CB9298232F1E386279609969FFCBDABABAC92ABEE0FCF4A
+BA307F5D5C3BAF909AEB0011890BA925B05398737F1D7BBD3F3FB5D3531C7BEC
+CF71F2E96B2F67257FFAE58DBD5BA45EDDDEC14710620318D77DE9835A78847E
+FB27EEED7AE907A6D37A7DF8E04B4A48451A7C653C7DA3CD7D94AAC0F2015570
+C0F6BE6153E49357FFA37C369FDFE7156E17B2762C5178D929367685685C7A71
+D7C03C9AD84FECB44B7DA5AFD82F977167C43B5BA10176FB6E96150800EAEED9
+D0A50F442A8768FE6BC8D42764BAB63E0B6C1D054B9F5775871DA64C7F95482F
+00BEA7A4E0F5A691D776A30ABB8A11C87DEA528EDD6462E85D919216EC6ED852
+13742166E987535DB5155CE6FE7F917CACFD973FF0A115DDC353E8F9FFE217B7
+B8BE6CB5922DD634DA733F0613E66136B449CBF3418FF8EA84F2B98C0DD128B8
+491341E1974CBC54C60FE0D5547A40541F27B20E6B7B40F164A49DC675F4E211
+DCDC3DE60C0B44F70E96C215D6966743F1CFFBC194B7635E9EEBC8054A1F6F36
+2F160FF094F1DCE103AC7A74B31A78A17A5E42A88B751F5BFE5BDD2BB9F49814
+03613DCFACCBB396ACBE06355D2F2962DCF5FA88F2FC665835C7294A6FCDCF42
+458653CFCBB73ECC3A12FD6C7B8E1F6A10EFF59740A712763C5255ED1FC9CC29
+724726040970C2214F69A295BA570CDF2D3959D0CCADAA8A9DAABD0B994EABA7
+8238270FBAC5CB6E2FE57F4B4FACCB1371C4820EBEA2E4B4390CD24BB5B13BE4
+5BFC6EE9FE026F1FDAC5CF35C8F16EB59B0607E440559AE1FFF7D8401D4BF822
+D17DF916A43480BEEEFE0A89C2040DC0684497EB3CA1C50FF4C38BC75219DD47
+61047D237ECF30579D0B4A977438DEF9BD9E9C726DB7F64A3D61A2F5B1F39706
+0CCD3F36D4FF8DF3E62BDF5800ACCBEC8F3706B6EF1211C23917127CEC021B60
+D3D7801CEA0F9E9890A24A5AA36EB8AF9EEAF3922D351D67AEE32371454368BE
+7FEFF4F7C4373DFBD3584B25BBE088A6E5DABD02C7D23105C217A8F70CE498A0
+BC8AD13E72185CA78A568AD937DC06C6146B9B9A3BACB4D08D22F18A2B238795
+2B2FA36C94745F9240D40B495113AB1F3E2AFF5B65B09947A5123048843FF6EC
+655515201C3727ABD9DC6DA4ED1854CF222F0EA9D22BE55016DF2007D83476D6
+E408FC0938D21527C3C97608C8189BAF5CB9BC412EF84084C6F87F70E7F59E27
+5A25479D4E3AEB11DB6D31FE8984AB0B10FC7E6DE5513A8C5F4BFC6C701BDEC7
+93025B436C5C16BA7CC15F0EE94733FDC5DBC7642CC208532087DB80030ECB41
+B0EB640BA5E7EF421588CE990F5BF7C1A07B8DC878175B3ABE4E0BE0FA17F60A
+4615E255E9BFEEDFB36AE67392A583F928375B02C8FCA84D68872BE1D67D993B
+F215F5CA2E65DBFBA53BA6D00B53FF4CC6D4024D525C7B959BD306A29AA8AE62
+1F414C6FA546C91EF52BE12214
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT12
+%!PS-AdobeFont-1.1: CMTT12 1.0
+%%CreationDate: 1991 Aug 20 16:45:46
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 34 /quotedbl put
+dup 43 /plus put
+readonly def
+/FontBBox{-1 -234 524 695}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660FE13FF01BC20148F9C480BCD0E
+C81D5BFC66F04993DD73F0BE0AB13F53B1BA79FE5F618A4F672B16C06BE3251E
+3BCB599BFA0E6041FBD558475370D693A959259A2699BA6E97CF40435B8E8A4B
+426343E145DF14E59028D4E0941AB537E34024E6CDE0EA9AF8038A3260A0358D
+D5B1DB53582F0DAB7ADE29CF8DBA0992D5A94672DFF91573F38D9BFD1A57E161
+E52DA1B41433C82261E47F79997DF603935D2A187A95F7A25D148FB3C2B6AA32
+6B982C32C6B25867871ED7B38E150031A3DE568C8D3731A779EAAF09AC5CE6C5
+A129C4147E56882B8068DF37C97C761694F1316AF93E33FF7E0B2F1F252735CE
+0D9F7BCE136B06EE967ABE0C8DF24DCBBF99874702ED252B677F407CB39678CC
+85DDFC2F45C552BA967E4158165ED16FECC4E32AC4D3B3EB8046DCDD37C92FDF
+F1F3710BB8EF5CA358ABACA33C7E5ACAD6BF5DC58BDFC3CF09BA2A38291D45A4
+C15FF1916FE2EC47FDC80911EB9C61F5D355BEDFC9DB17588547763AC5F0B1CC
+12D2FFB32E0803D37E3281DA9CE36C5433655526ACFB3A301C56FAB09DF07B5D
+048B47687348DEB96F3F9C53CE56DDD312B93D3918CD92AF53FB9461864D11B8
+0138918D0B1270C54873C4012CDE6F886DB11BCEA04B023EBB43E0D0A06BE725
+741D08B9DB688731A6C9886C15A83C28DADCC81385EA239E045E8F3670CE03DB
+9EE77ED067036595C9F3B1854343BE3A12E486B6E5A2F8AC44FA5378D28DCCEE
+306B0E283AA444423F9A4FF38E2B56DCF67A39CEB2C643DAE86865517D5D0371
+CB8797208ADEC637330A3A57902C9A88EDB75A7C16FA9850075D9F19578EC666
+1353CC1FC512D59DFF847ACCD1660F9EBABC78EEED8A207056C14012F5717F9B
+C63E88A38FF8E4CBFAC51989DC79A30F08ED5BE05D12CF8D46D684FBDB0F0417
+820814570D08B21B4742BB1176394F05415394414A214806211B049CA4E75D19
+4439DE6836353A4FDF1B6CABA378B3E7A91ED41F21682C4A470A6C84C6DDEBB8
+13DF35F5773893B4D0D238792BB1EFD2226B8B5D72E5FE19E3FE3D41BA486F1C
+1E8B408DC150E294FA4EBF815D05074A2F56BE4A9ED26D959564AD84D6DFC4DD
+CCECBF57AD8CEFB4755954C7DDC4D983DCA47A2BC497741157DDA724394BC391
+507567A9566B5667A3DDC115D6BC443A3CE7A1B97D69AFF628B51D6CF76B943A
+36F7CDBB507D363D90BA858245354305F7D41AE38F864C0FBEE47DE27C44B168
+7E8550239D9D4883B4F4D5961284099B685F4B2EED66FB9B447D6780BD05A91E
+3C693009BACB4F06F302619F6667A98AE64A028900859C1285A098AC15348DBF
+B4FF701C9B644F326C79C1D734894404B08AA367825E1EDC694C9D553DC9BEDA
+E2844BC10E231E1AFAEFF1CAB449EDDCFF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSY10
+%!PS-AdobeFont-1.1: CMSY10 1.0
+%%CreationDate: 1991 Aug 15 07:20:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSY10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.035 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSY10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 0 /minus put
+dup 15 /bullet put
+readonly def
+/FontBBox{-29 -960 1116 775}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964
+7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4
+A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85
+E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A
+221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A
+27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF
+5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09
+0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730
+DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A
+71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09
+4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C
+515DB70A8D4F6146FE068DC1E5DE8BC57036431151EC603C8BCFE359BBD953AD
+5F3D9983B036D9202C8FCC4FA88AF960E1E49914EC809263862931DB14B61EEE
+6D37A389B488D0B64CFB7DA527AAED80494F79A073D895AA287BB47BD5246090
+A76CE91680C1F37E6597E5E218364221B1905B9A039AC299F630788E5BF4FB76
+0B085608F3775AFF14697B68F221B3ACCF1F1D22AC1B36CB0097C1D107687140
+7ADD3D30FD8024497E249E45A48D4963235ED0352CC111C1FAAE249EC9582BA2
+3953C6C05294F5BFA481FDEFE541223EEDDDC45BB0F787D9958700AD538C045F
+71EC9ADF07C3DA6F0CDB1BD600B7F4EEF95A88A5A611CBF47A59F8539AF2927E
+832CB63AC57101AD75A7E49EE625CFFC9DD948910ACAEE750C58D8B43A233916
+FB3E7945B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR9
+%!PS-AdobeFont-1.1: CMR9 1.0
+%%CreationDate: 1991 Aug 20 16:39:59
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR9) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR9 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 39 /quoteright put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 63 /question put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 74 /J put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 91 /bracketleft put
+dup 93 /bracketright put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-39 -250 1036 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FADB679CF58BAFDD3E51DFDD314B91A605515D729EE20C42505FD4E0835
+3C9D365B14C003BC6DD352F0228A8C161F172D2551CD1C67CD0B1B21DED53203
+046FAFF9B1129167921DD82C5964F9DDDFE0D2686875BD075FC81831A941F20E
+C5CD90040A092E559F6D1D3B0E9BB71733595AE0EA6093F986377A96060BF12A
+A1B525CD9FA741FE051DD54A32BECD55A868DD63119A4370F8322CCBEC889BC2
+A723CB4015FC4AA90AE873EA14DE13382CA9CF0D8DFB65F0ABEDFD9A64BB3F4D
+731E2E1C9A1789228FF44116230A70C339C9819676022AB31B5C9C589AE9094B
+09882051AD4637C1710D93E8DD117B4E7B478493B91EA6306FDB3FA6D738AAB1
+49FBB21A00AC2A999C21445DE3177F21D8B6AAB33869C882613EA6B5EC56476B
+5634181ECBF03BFEDB57F079EACE3B334F6F384BDF9D70AEBD592C8ECF21378B
+54A8B5DBF7CB9282E16AA517E14843909339B5E7C55B038BF3BB493F3B884A1C
+C25F9E8FB912CBE23199AD9D2C3E573727701BA301526C66C3617B9514D6F11F
+11930B1D97C17816C85B1BFD9B973A191B33CC3B391815AD14F1CBE935942AEC
+D4004E6BEF379066FD72209DC88D2E634E79BCC2B98C766CBD92C561F2703F8A
+109E6C6CEC7B866F2FC7ADF646BF492E520319F3B949AB5D84AE990B33344A40
+3971F58DFDF8D8D67FA0B8F2A0D884F8C09A5A721319B911DBA0A35903877343
+C37BC36C5EB32353272D1E6ED5FCA611BE319A7E1E842CB7576E78F1F8DC029B
+CFAEFB8D0F4A2BF62940D450A881B0A3D1941B2C869DE8B026BD53BB8CDEE954
+F9D77197A3E5872D5576D5263EAB90280D7B96F194043AEB4DFD59E92AA6B4E3
+864233C32D123171530C8AEC596FCE4ECDA141895D2EB6FD50C5049D18E05943
+56D1298B54E2D2E97A0DDCCFBD17F667BE8B8F8621960B8E4156D5C7F27246A5
+091A32667BA0B19883B9F9E5E16A90A6803A6A834651388482F971F1516A80B5
+4036CE7E22B0096D77D48EDC94716469F466FF9FB6F957892DB662742F7ED3A7
+E14A833D7019365315C51DFAEBE253227313729DF897A5C3C42348DB7A01C408
+654BDBACC924E85115CC7E47585156BE1C8508E22466AB5915BF6D072E79DDDF
+1BDD0103DDE65B120AFB9A513008BBD3B1BA800725F186968A8B6486665C991D
+CB747F80660274335A1A74AA59E8A51018219E9B1CF093DCB83D5C6E4C12358E
+9FD9AC34FB76418AA84B140991F8DEB124D5E847AE0457A59324163A306983F1
+2AA279C88E4635C4DAF7122AC7C10D71498728623994E0C5CA4D6E17C71D3CBD
+03D89DCDE74B60FDC1A70148EC16ECC67192473899A69378024898B4306FF5A2
+A5F0EFEE8EFC7B857A73BB6FB8389E477A17CAA6122C6FC1EFB58D48A70A0A8A
+79A170ADA95E1906051BE020EBF49ADFD5E13ACEF8E3F8054B9BAD26843EE792
+9B6F6631219B9D22B6F5E42EE276A384610A9ECB0083D8CBD05A7C5008558E41
+1037A412362FEABF244110B69D92E97F55A3BC4975613F61148D54F8458A03E8
+DCA742A03D63355BB2EB7E2C437E444761C6E66F64B77582067DFDF49CB116A2
+10353D72DA12CED4260BB0F7688DFA98C91A1C7D611A25D3916033CCCC654EA0
+39224693518E231D8C1F66B0B9DDB5186EC0CDF95B233BB2C8507E11DF7446E3
+930A5746591E3B060AE0DBFC2D23C77E7BBED8D4A9C67AB8BF06C1779546CB4E
+1395EB0CF7C9B95334F346B032185C861EC47BA0D8EC60FE178DADEC3A03F6A1
+B365CCDF23F0537D4D4ED45206AD731DEEDB95A53D693C9F13E837B19065E8CB
+7E99F7069984774A5352C8FEB259E488EB521A40AD1B6E140B8FE3ECA312D306
+770029EEEC3756A786AC685A6E0169FE31E89F4C4C778C3DFCBFD316F1AF278F
+F9BCE6D43482FE0AAAC669CB8B2E54264103B538D70C1F1CA128F63ACC4FC417
+9ACBB52EBCA5BECD2C1859ABAC96D48D99225F49E3A0C102EB56311A27A0C06F
+74F7D6C1E69A244E6E5D5C82E1BA8BF96F380288855861EAC3BF13C87B0700A5
+7C661E0548C496F5CBD946EF1E1DF0B9F25526E583A366586ECBABC16F007B8A
+F394EF094CEB2143D5B7204C336AC11B4F4BB9B189FC40FA0195DBBCAD76E83A
+40D825D91C46D1D1753351BFCDEE377386B20BB53F56B168EC15CFB1A2608F41
+586AA8445FCE206536BA07DD8A51A15D3E2FB0C5B10A13B4099B8D161BE9FCE3
+D5641D93EF80402D178014E25807D148064081BC0696B89F0D7925D29497F21C
+556AAEA2E841B9D9E9E83A0347C373426B87DD87573F9DED201F618E9CD3FFDA
+10F2F884361FED666BF6261A2310ECF223F388F00B4BCD12CDD5FC6A893D4820
+466A67FFC41DF1A4334F4101C2DBF7623DFFA7382F6697EC45A900D1D1222B1E
+780DA4EA7C44030682DE457A865B04457940BC8444D56A356452712DF02475BB
+E1BC388F60D9A3519A7037E62756135AC10063B05F23045E46859D782C240C6B
+2DFAB9055FF7F6C2A1F9B720479F66DF9CF085E14CB2CDC56AB58CBC19CBFFF9
+FE1FD5CF91B0B460A9891ADAB29FE8A59F90127A94475DF9DB629B825C81D257
+21C48D46024E1D002278D42303CF35F4A47CD9DAC19F6D29ED32AB6C9C7F366F
+42D7A433CD18C8C57B88E2B742F8764B95D96334A30C94CFD2C806402AD326AD
+F54EE110F60D9FFE36D8C4960E14555C02BB6F88654A6434AE3169C08CBF8077
+B1368600F8CF5609B42017666733AF88ED93CD50F224E9A441F535FCDE9E8B80
+5AC0E8643F1EBEE3816D8CFC089084C0572387D59A02870F95FCBD5D254BD4BC
+7D21DF6B5C81131116B425E934278851D4BA475BAEDBB7012217BCB05EB9CC8D
+CB5AD5098C655292B274790E77BC21C832B6D10ED00EB3B117AB501B8461E460
+5034F9095C127E1CEE233243A85C1728B6AE28B82A15CC45C2E770DFF3C0D6FE
+92CFB4DF4F3C5AB555E887C7C8529EDC701556A53B1D31CF683565E0DDACDE07
+CC1A8A5426B06A1FCF89B8D8494A663E77C20E94A2E0A49F73310C22548401E4
+A17DE647E096AE280B4AC9FDF1E8A48B8C1E3FF9F4E34571463603EF13F21438
+71C91FBDA9688413E6B482B366F1DA0CFEA5A7D885493EA25F5CE62F750D8232
+39249980377CBDAAE52B827733F0EB32940C8380C25C0925E1B3C6CB483A1F41
+01096BD4284C768D82800A7FCB77235B81ED726B6D6F527CDC97963590672E8E
+1E0CBA9A0B76AC0443A46ACD8221369F558C23D19A61E4354FEFD7C6A20E734D
+FA74279041E79665DBEDD57554568F91C464750B3CBA5959AD33CC118E1BBBF5
+A216C7D296C6FA64BDCFFAC46A6AFDF906F05263295912FD3EDD276A2376C18F
+F33BF1CC4691DE428431074EEFA2F69D1DF392373750FE10CA258EF9C203C849
+799958B23EA751EE67E6FFC633A1110E2CC633CEB7B4C4B795C2C66D2D7F67D3
+048F1CA75A27FB7B1D496D2E7AAA0B0C9E8933AA29A002086D86EF51D5378747
+543055409593F4034796B40345367C431A273DAB7A42F7565FAB4AA07A1FFABD
+DB43014201300F27582F2AF955EE908669BDC35F2E6EA793CD783118C97292BD
+660E5E6F619C8319B7D86F1E4A6B1E554B47E19E935B95D4F39376CC24CDBC78
+791FB464D5802CAF9D017754A8C343646890326176B2BFB5D958ABD0B7C1C9C4
+E1700C7628A071C3718302053493D4BB2AF39509F9F25F7EECB398420642E6E3
+D5971FAB6D72C8E2627E63C5BAC7F51610E7764D2627AB46C61F8A948A7BB531
+34DF0DAF9F1D7AF381A0EC489668A71C4D3F996AC034A5101978F02EEA50EC42
+BA14C6B8916AF6E80F98EC2FF81CC9CEEF959CF7D9CE6876D8CACC7BFFB45107
+1A20CC11DC9C6A55AB67503FD8C7BC48B9F0E0CCD1250A96B3FE91FBA3534083
+DF0065AB08B30A3FDEB7759FC62C6113D4B6E90D767320245D81F03E28D11A13
+A442DEB1C68ADB1D8FF744CDC0DB6C48D0A55E0891FC5D223EB562F84A28A4AB
+86E0DF7F768AB558D764C8574990E7F5F73ACCBA816D7135B7ED9B6FEF931403
+2F941330F0AE29F884A12ACEE4FD77EE83F42F0B5F0288148A95017F86F36218
+E5C6E1AA87B098F29A07FA384DEB3C8EE7C8863BCD66D79470F258CF23A8ACB3
+536EB0133E5F40942881607F6F75B91C08E44C996C8259C810DD1EABD5F070BC
+94D98AC8297A28E523D2384D025800881E515A023FBAFED55C54FB8A2AA3AEA3
+3537B265F59356426CBF82BF3DFABABC81F02C74D2FF8D01B697E7766E6E125C
+EBC8422E65B1ACF81C6A49BA93012AE736F1B040CDF336DAEC4DCD7333496E2E
+8B3A9461AFD36463B4CAC695FCA2076983564C65981C301C33BD4044E1847B99
+E6D1B4D1EAD8E54CAD78D5D41A493A46EE9B2561530520248AE6147CAB073BDA
+5F437A06ED4517DDD76C41D1AF370537949575DE8F1EBF30B56D1B5389020DBC
+B9D7A67A983E4EEECDF20C18446562BC7004165B3BD8EE0EAF770F9A5FC90929
+A581BEA03697DB983BF5132CB4550D2D3ED4D1765221F1B6FFC94A281632B8C3
+17FC9D70713467A7419E005ED0208A02C0B595473F8BAC35532631480417E0DD
+0DB239D7699BD9FCF80E0D227CC5787B45B6F06CB1545E990F5808EB44A95525
+DC3CB766A7BB554F29D665B4B38166491DA19ADA4865DDB8BBCB3B7D1B388719
+F191BD65A36D766C457EFE1DC1DB6BAFCFAB6FE189C2BED0F9D063A9B43D7658
+2D2FFB21BB846E8BD8310FDE8019E4785E4E1C469E1CC2D9A36ED5FD284C5A1D
+E6DD83D8BDCEFFCFDD06F96C0BA2E456C9D659D494766FD02A4BC5F0BDB17C05
+405EC59E2A574F801C5953532342412702FC5ADD2759A17DAB16FD2870C29AF5
+A549634E0A54DF18118F189A3BB759EDAE6FDDC963268BC268C860D6AC82E9FD
+4CFEC746049E435E14838BFDCA0BCF626028FCE9774EFED9788D0BCB939DE114
+2868A8334466E7986D8E144771C28DFB9A6ECEA5FA219481661A49547F283310
+5F357181C4DE4D2958B8B828DDE9496EEFAF76029553A51A358AB838BC3B108B
+61FDD750151F805FF3D50B4FD44EFBC26F27896DBE481E0EB2DD5C5050D4C265
+B5089687FE5200D8BE189BE643F24C734E9C3077E968E7FFE3EC0A77D904F501
+056F529253A61CB6E2CAD640E7E0A172B1BC1559123AF24B9C8B8AADDDBEC868
+3D1AA000AA261D07DD15B3A5FA64D48722AEEE8006FBCBF5BE3A50F63D07B218
+9D7A980E5D1B0E9DD5F421D392C47B5DB33DA2D3A7C73C3F895AC2E90DAD20F3
+3A35C8CCF83514FD2A6A3C7A4248F65E8E9B15F809E79F916C1EB70C1A49C5A2
+C306443CDB00D93471A9AA3F266C3EE9BF1D2F0E476B6AF66868F110F10CAE88
+3C7F3340D8D9C466ABB38DC052E9B6C5E21C6458160524855C745DA3920356AD
+B79742C37D0F1275D9A6C34049DA5191A8B8C2CC945E22431EDA91972E8D6F30
+5C142B3A92466AF4A1CF116A0C42A6146A4D9004646834CD3A025DDA614A4653
+7E9B32A02349081E24A4893566F8FF7AD5E672B6EA2ECE480F2834996B36759C
+AFB7E8227F6B7775448A851BEED077120489B02D6EE7BBC870942505109E44FE
+7EE7E2D19A2EF9AE7DB618B457B3A7A1F4D715168A518AAEBEE496E8927001E6
+E27C5BD83A71826B51A7F1EA982726B2C15ABAA4C8BED9EED7B407A947191987
+221C79F5D28F43518CA2DE3E93412CBD459304B0E9FDA853AEC91DCA548EAD1E
+238EEF20078E1459DBFFF89DF4E76F8098A74C961446AA884F71A07F8B7C92CC
+59073027167562609503B9A89012C0D9CE0CB5982BAAB06873BAE9B940C73668
+756146A88EF69261CC395100A526CD74D425DCC752112759BCFBA9F975851AEC
+BFDD7AB415D257563E1359241FD36711FA95013ED90407400F0B7B5C70276DD0
+ACAFCD46272E86449CA5AF5AC6464B3C2ABC7383BB9FDE97FE61C091B0FA5ECC
+F8E6F40A861A49D35687534619E5D9AC515912491477E3E77D7A1B2C10E4FF0B
+296F6512BD7710051FE8BC2F37516DD0A234AEE3260C88A519DFD6CB739E6433
+0CBA4611987B3946401A8E578B2A7F1C8E8005A6575B5A62E4C3255AD6B3F2AC
+70576A04D0CDA6B6B83771AF828700E6D6D86EA0E4FD9220E9FFC452E06B28C5
+FA78B1E5644306691DCD2B7613A565267566077C459D7DEC4DFF1977D98E2EB0
+49DEA8B009F39A1AF74CA39F443FC0A77076C4BDFA5174B954A6D556AC2C70DF
+478B7C51C3B757E04E68659C570D2B6412C102928D7ADA83231A2FF3274B1464
+E2CCD27D04D7266D9CA3D6406B2FCB7F25725E3BA06233F7515A3AD1316A1D54
+A0DD4E7C5E17F7D5B73044C0C76BF28357C5669D836B5675B8FB0ADE7F044F7C
+C80C5F0A96FDE6F4407D18E9B5993A0A44A26D2B3CB00989EE6485E885474E52
+892DC7466AA9538B3B9C09118526A796467BEADDC6F9436A7F788CE4FD8396AC
+1C1195ED1B10A5C5B2DB366132AE54D896356633C24DA06AE127E0394DDF2A81
+E933DF1073EF74D89B441EC842DAC44350E8BF7935EA1ABF5550AB6943AB4EAA
+0A2C0E71E47E4FFE0EE40F31BB2ECEF60BBE87D7CF2B355C9CD6304BA253BEC8
+BB110690AF2675D403052CFC6588E4CC2036EB6808B5F5A17131805C0A68DB05
+9804B7434A007D51884949A8B439A8B3E1CE03C7028ED43606104FEC1949648C
+912B6D17AAA24E5F1D65401FF4F9F99A12429D00CEE5AB919E503B82F4770C6F
+B59AB02F33DF5C2EDA8D30848D74CC13E0A88A4E6959537B4F83387AE15179E4
+A84C33F27F824BB43F92E4D5B7FF43C3B64ECE3960C712E072014CF798596E49
+BB1B0108B4F3BF3F520239257812C174D484841E29E125B01AF08B1EEC3BFC2C
+EF91063A16E0D8E300D43E66F01939335CC8317CBEBE27850C68A43AEC54485D
+08F0BEF6DB4A19297E753FD89051AACD898D1FEA8E806E79667CE6374DBB4A46
+A7B734C150028F313C03354DB772285C37706555C48FFD16128C794F1843265A
+1905E2FF100460BE357ACFA44A03C8D68A484FF7771143B5433A919A6BBA0005
+5E5DFA41FDB3D5D396CE0701BC9E602B935A0AE20DB2DDEB5D804B9B67BB9E1E
+BEF7A038FADD7C3C20EE90A5D5C9D7E4BC8A86023B53C4FDFDF06F42F5371847
+7744A0C39980CE35975D3E49D7781E528130E1CE3B5F1F05F965DEB03C28F8EC
+C2CD537D32CC585DB4C52482BDFFF1B8DFA96F8B1CD6575BBA3FC56DAECABE1F
+61F00DD5B66637572E454F8BCFC8F3A940676D3DC7774510AA1D2F015F35E826
+C9D7EBA5D52BE66E254F7622DE629CD537A3722EF9A3BAF2A0FC8F59956F6525
+01B3B8594F368EB2E063DCF99471B6DAAD6F1E9966A5E5B4FABBA58BE9116482
+4C00A7972C73943BD45A0B223DF1E2FBBE6FB198AE53960916A4F411C33879CE
+962B9B79DFE2A52DC2F999BD71326BA1CEFA6342C5A004840B11A7FD3B3029AD
+5A0F9029AE563866D38C870D744414272F78AC137A99BCB060C7FCC1F0B6144D
+B90735132DF09EDFEEEA522D4592ED44F2A91F31146E3E44313EC3BA844E0640
+5C654CAFDD5ED4FF8E72DAEC0E96C83C6D74DDC4CF1B1B528EEFFAEA36A7CDD3
+690888C6D9FCF0688AC59268F16DDB94890AD6838F93C7E39F83079D94189F3E
+695452E74A53C4237B2C346781A69793AEABC06455E8F2B17BE509C9F7D4B1C7
+4975F564272A6BE79E095863C2159E56BD3AE99D3AEBC3396BE422C27CDA9682
+BB4932270D93C351BCBE39679FB56A684CDF7F3F835E07DF067777F7D8A39235
+BF88803070EB62513AE0FA7F72C12786B3C62E72A96CBCD0B2F787360750772E
+946B6782ABEDF47B052AF7E6FE07DC42FE14C53403432C2DF860A03BF70CBBE3
+3D18463F0362E3A524DAF270325AE702F238CA303C54B7578F2C34CF73741C4A
+30FC98764A5E4D67BDAE85E243211D7A2DCF9296F804FC13E950C3C8D70D0D8D
+4EA193F567419745DBDB912E92DFC9E8FA52E172F9AFEE49C24E0B4FDF11898D
+A5BECD8D83B5F821D1C19DDB6D8684C1B8DD61C953CA8CCACDCF3872AA10F85B
+2FDCA4C7AC73E76B3A9707361534E519C2F98454650999A08F3358A03D0AE4EE
+D8ABDAD368C1922ACF9DA41B0F0147C6DBE152DA9A8EB3609E4A7A1B70BA8C6E
+4274A25DC873B71DD8A9F0D661C99E85D00F37D875ABBB68733BABA0A083AF2C
+0777BC4596A93867360F0A7A205E2797E7445BB0E00575085085968BB2B537A1
+C878D777F1C7AA50ABE1D898ABF410CAA3E1B1BD1F5614AED27A2ABF72612758
+93D05B880E01A1B89CA2DF54653EB264573AFF0F8673D6F1529F53B90E51072C
+DE024CC64854C49B3983DE4D8555EF86C0EACB937477AF842C7FEE037B251BD0
+B1AF6E1BC1756869DE8D4FB8F763DF3CAD80D5B698F7B290FD5E18B80F255EBC
+832C74A2832AE74FFF22F21A607AE77A66FC0B83D13BBCD20611DF4CBBD5B9DD
+F3D6906A9B51262A66EF51C58E62EE24D054A813E603E39B7A1088A6439211E2
+9ED9AD9731DE32D9CDB7EA33A613DE86EF893406E5E71BC6E6A8DD4540428460
+AC45201272B0873FA40259CF68DD716666E620518810BC86CC85E0DFF821CB67
+0022515263B17F99480D8E3D2B71394A57CB224DE6033EBBE38CDB7331BEC235
+64E0E39A8EAEB35176462ADBF63D828049C4208ED9C0AFEB933B07EAFCA29749
+5C6216322D93D9C4AF093B1DA327BB1BB22A1452424F0A3AA19C8A3F6998CBA1
+662F56B57AE11DBA106164E0C8A411E78C6740EDE2FFA7F2757490BD407CE761
+28413F7D0A47F0E8DD93F07637D1DEDE427C27F174BBFE290A502DF784313336
+DEC0BBFEE12BA188129BEEB206BDCA95E360E658CD4B5C0F63A55C77E728DB8C
+C063D9FC33580AD9652EDD1F4223968D92E9B7EB72008A804878B502CA848CCD
+DE690A4B2D6650348A9F526B87231A270661E4EAB9D5E3951024598E5DD46C39
+96D9237CF21FC21CFCF5FE6D706D92FF326E09CB7F44C46BB61C5B653CEFF975
+524AFFD4D1D878BD2F7F28CC1DCF83E98AA1561F8C013FAF2966A3AEEBB63C07
+A0E623295B4E147BAF9C987DA7B1BD4D12C79027802FA688666A87FDF0F5B04A
+B3C388EE6E1835B41CC345BDCA7627BE88F03D9B0D72D5AEEC5FD6749339A4EB
+1D872F41105C4DF5CD707358D03438A9D73BE3C0BA4A3D22F5831FAD8AD8B897
+BC9694A4B1601C32BA83FD20CD0F254CF833EDF52C6A89FA36ACD1E8FBF37379
+DA5066D20A45E8A72F1095BCE4DBA64335BA3D2C6B7CE9EBFC9479AB78A837F4
+E17C24F1F6D718CE09879A4F26673B51CF08A7A4A772FA1CF86C7DBE4BA9FD97
+75630ED3B9DE79CAD4D64D656054FB9FBFA15CA94B9A1508275C92F22BF0F002
+1AC86793290CBC42CBBD542E9E7EEF5A5C27EA8C61BA56EB67477AA26B9B7FDE
+B1E204FFD49549BC71012714F4ECCEBA2493CD8689543E3EBA011164C1089423
+A392322595F685E6BBD1E14F61136C44F8212066ECDFB40D7CC4BB1D9D35EB95
+A5F96B19C3B1714AC4A8F72E5E878ED8475BEB9409F930A9DA452A546CA5C956
+5063786BCC5EC34355C0D114868B69853720677D61C2F0B61357BE9847721455
+A01AFF6F5A9809D0DA43D613969B2E2140351B72D89DBCABA26E1BD0371EEABA
+B0551DA1A69B202B18356966AB2B0BAE96EC0A82124F0B92BCCC42C7EBF2A644
+ECDC9FB3793E6133AAA86CABDF215BEB53FCBBB38868E8823EB2F41ECD1D9006
+6A43B54A25C80CAB7066861F3CD5D45BF479CC93505C89C0C4F1D68231BD8051
+27FA24275A0C62F79631B8AD78F5CA610CC091D83A431E848B8337EFA5880B44
+A7A0129683002501DE9A5F4E20F0566CA193810E1FF52FB4984EC25F5FE82943
+B6C810E99677E409CBA8A63307980F350A90C638FCDD5C10783543AD93B12344
+9B4970FD099640329A20A6035CA4E6466DC3C2D1B5439AE4AB183AD0B10CC91B
+CFED58BA55E7B2AF8EE3D09BC627439F4AF82802036F31EE1F41BBC27172748B
+C9BB41C591BEEEDE35A2A77A682208A9C0365360A1ED3B8CB20A5AAE02D0C132
+D9DE883864ED41CDC06D14B8973484344D68C62E4C5AF8DBEEAE71CA7023291A
+80244622C751295115731D0309ED0B0D5294ABAB95AB9A834637EE3E68B81B0C
+2010018C69E92BC48D925F45F5099EDDE3CA8BFB8F0E792BCA29265655FBE6E6
+5BAE0311BF44206F3A23DA0601F7218AA7AACAB225D75C5C99312303436DACB6
+E1BF7EE224712B97B76E35F28499D63F83F27CE65EC956DB403B84D45604B757
+0B7377C5CB8E2CE3F7BA4222719439D7AE6D68E3DD6724FB737A0E5DAA495631
+5814C216931071C3DDA953ED34CFACD7B35981DB5353D5CAAAA93F29541DBFBC
+261C8245C298CDFFD1173A516A81CE0A30806DFE78483FFBBC5E9203E24FBED9
+69150EC2E07E96E72B8ECBD058FFB46C41ADBB3F3EC38B16559AD8B49A02AB22
+C935B424595B75283643B8A37CE29D3DE9FDC8B1AAC6BB969541687227792EF9
+A20530740DC867F1BB4C90051CED2DE826CD70D1253339DB3C3DC840F7F21186
+61EBC18B3246121E424AA04A9A63FFA331AA875FDC78981152BCD7913BC7741B
+838E52DA3ADFF66BDA143C6C6FB29168ED90A2BEC9DEC9A307826FA5166AB524
+5AE7BEA436988F6360CCBB5CF4CCF8BBA147D00133DDBD547D289BC99317E6D3
+CD8FE0BE3E4E533CCF97D95756F4DA3F7242500D792CE62A03342C88AF449E48
+D99A33E441DB998BE6B5DA7C9D774C94A876C9E7558CD539C75E79EF77E3E4BE
+12DC0530F61CCC5CEC6E1F06D9F262FEF3700834F5731F461070786835291C15
+589C4A565A9DC253A2212DA7C93B67A450B45619CFC7DCC9842ED0291C917EFF
+3F1590C61C541BE67F3E2C5D0E7D9A5893C2DFE92FDB402073A0A699D14F9F63
+054AFA274088083B95F096ACE27912C8B95D230A7B9E6E4135B14F601721C610
+0C900B64D37040AE5B23D81B5AC70EADE83190E395DA24E96C95505F1726E7A2
+3B2DA236C98B30C4A412E4E65E2708917EF44F1C170DC3CF412990F0C7B4BE94
+4D1ACFC5B5E5A1F4BDA98A06CAE6250666E97CCA32BFB710CD9C582E196B7878
+AD30AF538F973971D18BF8A7827DCE3264797E738AA58C91AEC0E6BE7581E3BC
+EECA2706AD887103AEF1BDA8A4B2FD8732A4995E0F03D947C140C52F60167D4B
+AA3B66FDA3C8BE1D28BD5C5A13A63D9D463A23225DCD2CA99D8094507E787FEC
+13F241945171865AC92B7E871CBF97A41311F58E04A03E60AEB128F91E2EF26D
+477EF947F6697E27CBD9A430BCB811325E8FD02352EC0B5B7D70FDFF275A0A14
+ECF0EFBA513606C749C3DE2AF7568EB01868755EF087E40C2409870C657FF6FB
+909461E7972FCA8FB5133DEE870B3889D406EE2C1F5669565DEA42C1F56C4DEE
+9DF9BFA2D4F43B3B00A4AFC10E50EC60526956CDE75AB78F951CB102ADAD454E
+3B1A3CF31648678972A48BCFFB2CB367D8E12CFCE5B222BC261597030DC0E4B3
+C67F9F8300F49E621DB4C731DB59EE0CC3EFAA0624355F53FD0F2ED42D7E1F74
+757533FF13A0DE2065E66FEC053EFDD10BC342BC08966C17EF8BFF644132ACA7
+BACA9D310C8612A4C041C0B3413B26E4AAC6F317915A9608B4282DC77C2D92D9
+3AA33B72017CC3A4651756D89DCA236934DA4D268CCD2C6F085F5572C2EC481D
+635367B4F25C01DEF9EDC2AA3F1FB11D1A7376BB38E2D62CB9FEB910ACF6D75B
+14BA4809818D0ED02A5BA55E527E64B3AAC40BAB2CB3B693073819254E2EDC8D
+3085BB54D6BC2A80942D0F1A5D84DA6FE6EE8A556E3F90D15C5EF4890388B295
+28CC219785D797C93D9B94E65957BED024FDD36E1E392D85CEE21DC4D1B2CC01
+D0B1FF24BBCA96FB24FA180FD7D6293046C2F56BCD0A0FF37697F2F42FA3EED1
+0B96451A5F4DB4695260AD5E83E1D2DD6334913FE3E02BBBA5CB276357FD7B8B
+F75986C13424FE98414E9F79E5AA9676274C50CF3B8FF65BC5F586B270ADA9C4
+6478746317D7BA5E44750D1648B2137AB4574D807F8E51F0408E42580ACEEF67
+6FB86D18D6EBAC709D2E387F663F90CE351F62272F984209A1185DB1FC60D3C0
+F2CB4E2F84415E962F9FA56D13E01ED475801AC2B720B46579549693446C660F
+4DA462760D33FAE77EF07843CFAE87EE45B6F0D79A61CADEE1DB72C56AD9854C
+B67912177D8AB920BE7996902206121F3F6A9A5D62388684ADA6D7D49486E427
+2CC91E30C00BB344193DD65AD929B93651189595F5A3368896F4BD559B78E8F4
+93D8F58C07D6A007F2F47EC38B10B9F0D4C948E08D18BD98461F7947C84D445A
+20F3CB6F0E30FCA78442B1BBB1B9AF4C64E526B49E41149FDEE41F333717ABE8
+52970F923FEEE910A2C795692B1C6378A6AB07BF55D198B100461A156ED1CC2D
+FE7642909F34CF257CE89156C727D908B68B283104F65A1B9954A6C1101412E7
+31048BAA1E38FCCFF7500CD1088B01BC06B20950FAA6470FE50B5B78B9B3931A
+11C1346A9E40691E6AC94CE54CF5327991E2A3300ED4C24A5E3E5D5307E02278
+8F3B2FCFB8C85BB3F24A3589AB70234758E9E6106BE6FB108B34FC3A95000740
+7F9378C9803D8E626BBF07076540559B4F0E4BF9109A1DF5E645768180213CD6
+23E79C857C2C35A11141DFEA108DF35ED0BCFBA135586567262C3C68B155B13A
+66FB131FCF47794C8D7ADECF340AB419F12916201AD05962600C8F261F66C7F2
+10E2A3A33AED14E4EB9589BF6BB590333184CC05FED807AAF9C5B41029A87858
+646F8CD415D635B8AA61213D25DA01A8C470860495DCFC1A6557D9C7AD9D0F08
+3E60E00039A8660E6FDF11AAF37DFD54E9109F65F4EAF4F0FD86568371B05479
+D2277BC2071771DD2AA3D351637CBD178969301C32990FD4C8BFD3C9FAC47481
+D0AC5D5ABF89662CDB31055F6AABFA695710F999C2981B4C9174B621F5835FCB
+28894E9B0EDD37836ED6A947993E34B2431CEDBCF6C695FC3A6174B266969F0B
+CE0F7C5732048CFCF17043527363BC524467EF7112A498C5C2812D3BA33552BF
+E8367A192BD41D711061A3E24B19F343DB8BFAA1185A793F3D01BB59389E1934
+B9BF7380C2788EDF64B55D88EDC18B4EB04E3A141DD036CB819B56A1C1747CFE
+44A800C291AC0FDF8B2D3566CFAE9D4BC19DAFDA1B5B7F9FF08317EC3139EF28
+2A22F5E63B5A6FA09AAF12CD831556CC8908FEE6E124DEA18FD5CCD8AFD4EF26
+638473E397524F0894B8B104C46FB51800F7C1F1727AAC74468904E17C5134CA
+99DC55A2DB9FFCE9814ADF65F896FF07BC03D54B4584ACFDCBCB938BAAB7697E
+EEF3547045468B5C351AEDDA1B678E9B168A347E27A96B862B0321D2145309BC
+AC3C58996AD95554D97827138A2C6DE9CB634C6A7B2E582BFE1BEC6523854D6D
+69595169A7797C49428A30C70DF5F210A688D77FDBD8C510E4EFEFEEF39C7973
+030D489BD6BFD52A96FD6D2FACAEBDC0C11BAACB9AA8C0C7D56004173E767EDB
+5A27E7D9673EBBCFD6AE6176D75716C1AFE99B8DC2FD1A72DA84FB7667924671
+BDE3462F6AB8B7A3D3BFC01A59A6A916583EA68359A325FF99A8C98A24DB8129
+2D87417CECB040877F5644C113FA2B7BCEEB58B6340E03EC1DEF83763CBFDC2C
+99AA74E804B8B189F7AAB7EC2674BA4CC13EA41BBEA9D5585A62CE3D14D204EA
+62C761B314205F0449167DDB844137C49D848A44AD46BB4BC7B74757E05B506B
+DD8469C6033D12E3C15A9C86786EF515F6BE1AE5A2C52316D8158A27D7B44171
+3A4BCB34CA6EA3FBE813CD7DD326DEDDA610DDBE065303944B260C52D496ED8E
+122F4776458B368CC08D439CBBC5AB75FE82F5E63C66F35E36727FDCBE91C1AE
+96B797E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR7
+%!PS-AdobeFont-1.1: CMR7 1.0
+%%CreationDate: 1991 Aug 20 16:39:21
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 49 /one put
+readonly def
+/FontBBox{-27 -250 1122 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF5B8CABB9FFC6CC3F1E9AE32F234EB60FE7D
+E34995B1ACFF52428EA20C8ED4FD73E3935CEBD40E0EAD70C0887A451E1B1AC8
+47AEDE4191CCDB8B61345FD070FD30C4F375D8418DDD454729A251B3F61DAE7C
+8882384282FDD6102AE8EEFEDE6447576AFA181F27A48216A9CAD730561469E4
+78B286F22328F2AE84EF183DE4119C402771A249AAC1FA5435690A28D1B47486
+1060C8000D3FE1BF45133CF847A24B4F8464A63CEA01EC84AA22FD005E74847E
+01426B6890951A7DD1F50A5F3285E1F958F11FC7F00EE26FEE7C63998EA1328B
+C9841C57C80946D2C2FC81346249A664ECFB08A2CE075036CEA7359FCA1E90C0
+F686C3BB27EEFA45D548F7BD074CE60E626A4F83C69FE93A5324133A78362F30
+8E8DCC80DD0C49E137CDC9AC08BAE39282E26A7A4D8C159B95F227BDA2A281AF
+A9DAEBF31F504380B20812A211CF9FEB112EC29A3FB3BD3E81809FC6293487A7
+455EB3B879D2B4BD46942BB1243896264722CB59146C3F65BD59B96A74B12BB2
+9A1354AF174932210C6E19FE584B1B14C00E746089CBB17E68845D7B3EA05105
+EEE461E3697FCF835CBE6D46C75523478E766832751CF6D96EC338BDAD57D53B
+52F5340FAC9FE0456AD13101824234B262AC0CABA43B62EBDA39795BAE6CFE97
+563A50AAE1F195888739F2676086A9811E5C9A4A7E0BF34F3E25568930ADF80F
+0BDDAC3B634AD4BA6A59720EA4749236CF0F79ABA4716C340F98517F6F06D9AB
+7ED8F46FC1868B5F3D3678DF71AA772CF1F7DD222C6BF19D8EF0CFB7A76FC6D1
+0AD323C176134907AB375F20CFCD667AB094E2C7CB2179C4283329C9E435E7A4
+1E042AD0BAA059B3F862236180B34D3FCED833472577BACD472A4DE3E3F6222F
+7A252B780C86447859579C68E52691E144F836C1C62F19A12EFB710343D33262
+1F7955FE5C37074CE5F9C7ABF1A241078519A4D7913A0AD861E0E357B50FB730
+E757C0D26390E6028FAC61EB0E9414716AC8406A6E35DC70A7C1AA524804FC8E
+985CC3604A2BE0A8235CC895B2B33CB7EE85FE4F2CD817BAC3D27ADD295D0A0E
+BC0E8D849952BCA7325DC261A785CD2305BC377AC61AC5E5B2CD3164CFF033CB
+5436B8000673A4D763ED26273130702447C75A774C7799FB8C3E54A2E34D1710
+CF7883A9B05285C7DF30F314455A4428A5369D92C0348D45BF4AEC5E16611D16
+1E5EF015900F4DF63A58DC233BEE88417B204DBD110AACD1DE3D750F9C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX12
+%!PS-AdobeFont-1.1: CMBX12 1.0
+%%CreationDate: 1991 Aug 20 16:34:54
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 35 /numbersign put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 63 /question put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 74 /J put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-53 -251 1139 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660F74BEE96790DE35AFA90CCF712
+B1805DA88AE375A04D99598EADFC625BDC1F9C315B6CF28C9BD427F32C745C99
+AEBE70DAAED49EA45AF94F081934AA47894A370D698ABABDA4215500B190AF26
+7FCFB7DDA2BC68605A4EF61ECCA3D61C684B47FFB5887A3BEDE0B4D30E8EBABF
+20980C23312618EB0EAF289B2924FF4A334B85D98FD68545FDADB47F991E7390
+B10EE86A46A5AF8866C010225024D5E5862D49DEB5D8ECCB95D94283C50A363D
+68A49071445610F03CE3600945118A6BC0B3AA4593104E727261C68C4A47F809
+D77E4CF27B3681F6B6F3AC498E45361BF9E01FAF5527F5E3CC790D3084674B3E
+26296F3E03321B5C555D2458578A89E72D3166A3C5D740B3ABB127CF420C316D
+F957873DA04CF0DB25A73574A4DE2E4F2D5D4E8E0B430654CF7F341A1BDB3E26
+77C194764EAD58C585F49EF10843FE020F9FDFD9008D660DE50B9BD7A2A87299
+BC319E66D781101BB956E30643A19B93C8967E1AE4719F300BFE5866F0D6DA5E
+C55E171A24D3B707EFA325D47F473764E99BC8B1108D815CF2ACADFA6C4663E8
+30855D673CE98AB78F5F829F7FA226AB57F07B3E7D4E7CE30ED3B7EB0D3035C5
+148DA8D9FA34483414FDA8E3DC9E6C479E3EEE9A11A0547FC9085FA4631AD19C
+E936E0598E3197207FA7BB6E55CFD5EF72AEC12D9A9675241C7B00AD58FAF645
+1297991B5D01701E82228D0313FC7C66B263BC79ACDDF9AAC48A3CBF42B96E38
+583E1D059953076D68148DC8B6C9527B3A74CE7DEF788A11531F44120BDF0F61
+0B2F3ED94EEBCDE4ACD23834C242AA4314B9EF98E4BE72DB76EBDD0A028CEA9D
+B4C38C1F2D24B8FDE686832FE96204552C820E45B6BAF0C3308742AE2CAE8F2D
+F32F67760F27DBD48AB574320BF361160FAA5DD6BC6F6B295869195C18D588CD
+698E9ACC618E399D8173F63376367EB398E855E4A1195B487B2E62B10860D248
+756381C783CABDBED0FC99FC6D5CA7920DE57AB0262492062B2A3B0F314E14F2
+71297A4A4171D253523F75A07C561564C0A0D59C96AEFB1ED57A236A5D0B00BA
+3175365D64C1AA98BDA0F152B6259763BAF2391568CC8EF9D1562C8083B7A002
+76CA3A327CD22C190BB35ECBD86B4AEA447DF6D40F967D38ACCB04D1BAEF96CD
+B15BAE67A84E7BE7566165576C1FBE1D0A32E6DFE46C63A20A997AECD19320CD
+2B02DB2FEB4BD2679834EBDABB1686211AE986EF3661CBE766152DD3BDDB550E
+7DD4AE767D060143996AFB23FFD272457ADECD7A10078C1162D5A2D62EB710FB
+44B140D7A607CAA51395FDF65549D44287F11152B28B21B482E168BF62D2D3A0
+4C946B9A1F2CE9B2A0C653773E992144B684E2D4C1092AD8022B6BA4A0E2A3AD
+ED250A09CF8DD499E2A9B2FB296BD4FC535DC0E1E8A5B41BB3976E955A4BDE9D
+04DDF750C6BA778E6B4DB200D59C83645171B05EDBBB867DDFA92B3321AE35C1
+8F8DD1D578AAD9322BC0B2F6DF08A3179F9AAFC27C1B73FA759D56CEB2086C3F
+04146E8219B47D50DC1205C3096486281C7BD3786CFC2B049B34723EC7B76C06
+5EEF39959CFE2BDACAF56381DC8416DD7BF9FE93B9A1874FA412AA90FFB828EA
+6A29E6D0FD4D4EADE00BC5C31F0C44B2624419D9AAD226A7C9024BA824622B52
+97CB8308C2238F4349A89677776AB904019FE70007B5E21BF95F2A06FD9AE294
+574CDC5C81D93193C0F5664C0CF61317A73325F0B1C59E7A324D2042595430EC
+B6BCB8B7DC2262B4B98187829A898625E5A6781C88714B16FCC60D0A5CB6AC9E
+B8AA501ADC27A029AA99C62CCF2748BB783B9AB3AE58A1547DD805083FFC4FF0
+04BA87B7FE7D8A449E6AE0B5025F90374A3E8BA6EF42758C6ECCB7B033E1EA08
+643A5276BD11C1B553A8FB4DAA0E88D5611AECBE09928DDAFE154F04D72693E0
+E4DCC5112017CF2FE53A145B64C9EDF4209D438F4D22187265F1F8DEDD81AD27
+5A269EC246966FEF7EF5DCC1F1672243F5B2ED47795164999A3B4ED4784ADAF0
+6374AE0E2EAF83F77856F6C449F46548F2CB15ED2A69191180F2B59C05EA6913
+3B880081C7A633E67A44C38D36E838C58C6756CA21AAF5EF3228C405540851D9
+6D000D9FE7B2282F78F6687829B80A219794548D019DE6BE8D54D750D7BD8DB0
+0ECAA1E7574D554A8D0C5F2C3796F69EF3FBC7D1B8ACE786EBB1F24E0763C26A
+3FE979E337D82016FA3AA86A25115C697CB907B95951DCEBBA225F055660FBA0
+F4AE0B3AFF9BA585FD827383B14EE699637F5D87C4E2A984B617F920EEEFB388
+74B3CD466D74CDDF82E9EC0B7C11EDD73709D4339D3F8F909F8FEE8C60B31A62
+09372D9A38B44E5870EF293182127E7BEB55BA3927B77EE55E71D934D61F0C46
+5F5E2E82264641321E13364573E75694360A816673CF8E522B38ABBA06C8CF80
+5650BC9563341B5BFB215731678EC644B864B4DE71066F1BAF00F84DEF792DEA
+3985D48F105528CA8EC5F8ADA287962A3A632E6B1F5965F52153008DD20D480B
+7AAD03D79F5BDB56C4B1AC3DEBCD1EE2C1AA00756EC69935074345ACF6F36B8E
+B43B4E99076F80F38DA73863C69DD5ED735F28327876211ACAC9D10F1B7BBB0C
+CFC68049892B0187EDC31FA5AF0E00695C276468BC57D91B510AAD78634C6A86
+FEB52140526CE9B9222C754CCA7B984607B93F249FEDBD90A2B03013581ADB34
+46BFA1DF5F2AB864E36BC5464E7DD22FB3EA06B53ECE872E1009E5CE9ADDFAB0
+C11F0A2F97122D1027D64A3CB37244810101B619F378F91AB41A054F888A34FD
+805642BA5F06B550D98FE126923FEA0C4AC31B525B7188178E4B32315D1ABF30
+1DF453FCC5A71E6ED6A3522479A5023F71A9CF99E7CD4A6D9D3C45FA80A96525
+3FBF2305BBBCEEA5FFABA83E68F94586F2DED351EAF23304AF6B0B6C116D609D
+03E820F33BBBA96AF7382823EF3CF06A9BE9183E545BDA966FCCEF9778D51488
+4BAD280D060FBD671491019F99DA72CACD7F531020226B6973161D3B4F48A253
+4BAD7BE992E48DE43C9D816A5C255B9C44D79DC8D54653DE771B5031796F0E78
+395C29033AB0276014DAADF645D7DAB3E7B20DDF44E92D9B395CA87A8445AD5E
+F092E37CB1E89B12C5DB3CB106E31C43899F4C28F1B37D7B0C318353BCF417D6
+62F8D198E1970A869D3EEB1AD6E3D228340EC8A0667DC3D30777254AD6B5E69E
+B3F69B12630CCDEDD11FD4BCD417A453BC0B5EF890289100354334A4F9D09F9D
+E917E848E0B0C62944A6F9B22AB05352FE66E579EA6F1EA064974C9B736253F5
+CFC3BAB92F60861EEC5E7B16210569D453F7F2D4AC9D6F94DA2CBA04E927DC61
+3F8ACBEA43191E5B0A1A71C9C8798D0DE7E5EB7EDA809671B5346E9E7065AFB8
+F4EE1AA649DE55A1AE8ADAA3AF6D86E21331F0175CF2F7120740A821C26DA12A
+675615BC903AA57DF9893E10DA8E02DEF0125CE1F82BC7C4B0337788BD8B4371
+6E0557AA8A47AE3F097FA85C9B1A165D8B16FB8429E8796AE390670BBBEF5924
+36AECBCD300C9E65435EDACF5AB05316FADFD3A4E749985748FBBD19F18784A8
+56A08DC2A8E331331354FB4E7DCD4EC16F5167424AE0BE20B302CAD9487BE529
+F64DD7871001AF5A36E95A51EE2A38AE698FF5A9ADDFFD1710247F2EB1CC70BF
+69B14395AC49C2B233844A8A9FDA1E0F2285B4B2E490A67CA7E2FFFFC30A2B9F
+7813A430A9106F258D3BE59AB1E0D22D39F5A4503B8CDF418D2D4F25B5544D92
+557EF9C3D5D8D88E40927E5FE1C121F5F86BFAD87C38EED25BEEA229DDA2E989
+3164D6C0AB3B7E513DFD93E8D4C67A1FA5C22BE730D035F0AFA9DF7E32A07180
+EC9D66B061C291FDA89DBF50F6796D9933C945B0D822E1079518850D54814EB0
+47E64AB6C92626548185F0A20153056C55764974A54CB7B798D3B571AFEE438F
+F73F4D398A72526E9E08C468172D8B0F73DA0F2F2E07F900E45966726822097F
+6991D5365CA7052D144CF9EC7506CD3A668B0C935D5F748135A70EF3D7FD900B
+B9C0C9D355A3066B77659B7E938F519DF3D11331283960D21F426B289B1425F3
+BEF5EA53DB9CEC31A376490473AB3E70EE1C80D3309BF09ECF910F4FFC766E1E
+8D335F8E0136ADF71DFA990700411469F44FA674A051DFC9DD69DBF015C4854B
+1EE881F086505AA7DF696440A43BE2E4DE73CDF5D7584C8B239F754CF57F3B3F
+070AF9F1400B378BD4AE5E894DD076624831666BD29D655F84689C96540A9700
+2E25539B8DC5916F57CE3F662D0B141CB0CBF93E5570C206BDEF2521C7E80EF6
+D143C7A031CC721C22B51AEA6A99898CECE81807148AEC9A9BB27F139307C17B
+C265EF674E1F5D0A314A3D82D0EE516635453A53520DFB87292AF8CD39ACB718
+C9EBBE32658B2E78A1FCB2BAB05CCCFDF50F1021F19519640EDD4879F3F1BFEA
+F96F049D6A29656CBAC7D73F5BCD48BE61E3126E566F662756839A28A12AA35F
+918F1BD42802CADFF08880C457A4204E8439B74E7699C2B52681D4BBC0464B66
+8ABAD126DFDF9620D3A3DC2579EDBEDBAD7EFB4B18D044B6C44C09426D926FC1
+44BF54B0A99AF9940BAA96EC9A4E67BD51DCC9B88AEE1F2E902B3B3E652C501E
+54620432DDA0AF375451A9A6F7530C942BF2A4655207EE098A9C73393CAFB3E5
+4A65B42629505B91EDF553B85E3AE18108D09A866785445788529F210F39ECF6
+0DD1B18C3A1F0C8A1BFA4688071E5B407D7792B91B4028AD8165520D11047939
+C66B13C9DC63913381EE39A398CA5A129C82C64514829EFF41AC90DE6178F9EB
+BEE827DF141CA272D82A452F8E28677B4305B9D867D2834D73AA489C9F441045
+C60EA1AB9383884B507A5F66AB80B5191DBBBF30C491D9B42F549F8F0E7600CB
+360EB965B0623E786BEE3D419B03FE1EA8F48A8C27CFEB3119B30CBCEEEB07D6
+DFC956AC5A5A9D0CC5BE5272A986FD066AA2DD2B00BCBC9144A8E49230E08BBF
+5768F53DC51A152C7F6B6BCB6837F31A7F754D7F34DAFB79FD77BBA8EBD2B678
+80ADA5ABB5E02C0CF7EA38AB4E1EAD51506033EC4E4D48A3B4D40317E984DB8F
+B626C52E124B09D39B3C69DACCF42148EC959196F7CFB8DFCD147B1958B2AC19
+12B91CA17278AEF94E11568907D5041777421C0D91D1793160A3AB16DC06D022
+55204058605EC82DB21B7315C9408434467E0467DF31A45CD7A9B3D2DEC289F6
+A6321CE7A2FCDA5C30B439A56B2E5E37061E6D52A8971B5935F9D0193866180B
+1854B994FDBCA6EDF3A8275AF27719F5E78150A444CF16EB647315D8D35D0E8C
+5B6315F9BD6E69500C6A30A117250AB978942532AA15E88B29588C588174C8BB
+353EA558D0A4A5A0B47B0724A2902E22A4DD2764825006E4A83BB06D7EF069BD
+74A16B305091C64DA901F956A067E1FBE2FB832BCDCEDAAB9E2224F9089AF249
+E58CE65662B099DFBF854A3EC7BD4B5B67D1EA11990E3A7312423A6BE88267C2
+AF854C50ED1A58EAD11810CD33BD188C1972557AB7C84938E546A827C7AB773D
+29E375FF9105B0AD5DC7802A7EA903003E972AEEE457E10795AA48538C523B8B
+7DA81D034BCA911964BE2F0217817A4287E2FFBEC1D24F14B577D53A3E046BF3
+6F00D1F7084DD9FB3792C1528766AA99D70C4CE02F4CE5C19CFD7D1CDF088321
+5AA5013F2E97A814150A20925980BF9F80E4B6D5371E41F27BA0A50B02857047
+730A4508F8E37A42F3C67E59EEDCFD620FC75945B3E3874AB08C7A7020881C76
+06071A118FB52CA8F5DD26B946C1BA8CF0F35083F57814FEA759E06065E4DDD2
+4845F23D93583651A248A0CC916955663FA7B978399EFB9CCE8927056A1F1931
+F08BA2650223A9C81840DF4E224136509D4CCD3C4272375180ED44E3D0FB1C6F
+1464833DA630B01A0E82A8E39CE34F2385F47675537D3956841BA6A47DD2BE94
+19DADCD194E4B8EED3ED3E4F7266E9760A881C3FE3ED344EE0A90734A467BCD8
+82FED18392EF253F7A3E27B448459185FDD9D31F908A4E75B355E6E2BC71862C
+3430E755BC3CCBACD2493088783801B0EAA0345D3A57B5A37603CC4B563F62FB
+7FC9B63292810836BF68829FF6C0DF8BE4C34ABD7CCF8BEB8EC2B61F7BE0E8D6
+45EF5E8B231ACD33C87CE831DF522B2A6D8CB21AA6BC69B270851C9E965351BE
+EE7C86C395104BE4AA853472ECD2E7F5FF3E0A1E86884C5CF980929ABC1E1E62
+CA0E7F2C49A63277B8191185D43429F2E3560B7B2A22AF788A1D73F22CFF5F22
+D2B842B2404A13E15D7E1563C8D154FA0FEC915C1BF1C65DFFA4A8967A3E3CEE
+DBFB885DDDBD62E58BEE4A67C86198BA4882D985C16C1DF43CC11A318AE36275
+12F4B462F6766FC40053FE1D3C1F765DDE1184778F05CA9034F2901495C72969
+C2674B77484217D8E3880C513F68A00EDABC89FE69BA3E72DD2766FB97E4BB06
+30E4836817F19ED580E3D5EBC35D87B8E92434323460D3EDAFB481FDB13E3957
+7464389886871CCFE1885AB1583424DC8BB79F7DF1BE04AD782905770D5C36A0
+FD63D1A999ACFDB3296ECD207D4A2A668F31B30A84C530F3B4B215FCF2E8A5A7
+CB6F501B271A6214F25A4EC98205F501BAAF4D8B3B1FF2244FDAF3671373D42E
+B0CA0FB264C58098B447AA2754E5B90D87ADECD2BED8A92EE9470C90FEC0153B
+C3F9CECA8ACCC466B02171FBF9698A74F8BD5F97D12CA8A23ED7E6B7AE464F59
+F1ACC6913B7DC4E635F57C5CF553F5BF6C995C76CCA485804CD71F5C94EF46F4
+FBD6AD7058E9B7557A8FF529789878AFFF6D773E83BAD1D1593A536EFE7E197E
+52C48F560DFA33648112A102DA3622BE79D614B5D5622B2DB629CCC62779DC24
+43A81C40CDA9750F4E65B3401B84DE80AEAC771BD267ECE4A8DFCE90E8775EB6
+1D10FF15B0C6DE35642F84DCEC66525246F1829B87F60BED7A65C76E6A43C98F
+49A0047B971A7A9D9BE3A677337ACAA4E6BAEB3207A1E4C46A27527F4EB486F8
+8F4BCBB0857006A993CE82CF0030F49FD582721A8EDB7ABA1DACCFA0D7D2873D
+F28B69E4E22F9C602F5715D446008241D3D0EE0A569734250124E91C861BD6B1
+DD363B8A050EE8B89BE03EF88F25036664ACB01FEF2B664CCC3FB77C4F49821B
+F6F05B4192E441CFD834CA05D42AD60C03C63A16D6F4B25AD054DB5BD3CE8456
+0B4E0E4B583C0A1B2011D74EE936D0A26729A4BA9309C27FD849654CA174C7F6
+BD682F2DDD1DACFFF1BB34E7FA24C0A772E1025870E28550AC942039C3EC6CFC
+39C2DFD16F9C74B84DB2ACBFC1E28EE5580D75B5A290ED1D924CE27CC0B056AE
+0D2E6EE7925B2736DE0B38A0CB9BB04902A769A572D74C6360B41CFD7B2BE357
+56219F61E3F74417B4CC501960CD6301966BEDE78DC5715078114F779716DFC2
+31D74BD3865B4B5944F1DD3859B7C0E75CC31D1BA3C52517ECFC656CE3A83B23
+FD53381E27A2A69AE43037341CAD9D0CFA618000FF531DDAA9B3AFF91C289463
+81F32D0ACD6AE20E219FA43A8E7245EE85559CA3A0F214EF89A864FED3D47B09
+6A00BDB23AB724E619266B2215FE501B10A5895594CB3B427269A2EF6CC7C121
+D2C4F856093F19425A1476B46143E99F2D42057D577927A7A20765216A267360
+A73C54D3FBBB0CC45AD5A58D3DF856991E5B8D7EFE61FB24FE0C951F0A10DB98
+15BB63F42F745CC33BAAC4E62C91FFBDD0C23C0BF5F8A4068B4417330C45BFD2
+7D9BC4F182B64F46CFE3F91269B2DFCB78EC787CEB3253870A301E8EAF4CD907
+0AB3F7045D2BE3406B646D1B656D97B8E207AF583C38979B9545FBFD953564CB
+ED40274EBAB9C2BFD389667D774F945935D815EBC7C86B56570FAE5CF797B541
+5D69E640F4CD3D9E43B88361FFEB4A37794C23B801DDF549C0538B1CF80195E2
+E981373F50864B4A9536C21AEF4E695994CC5514B8829421C4612DEB7809E078
+CC7FBEE79A99C200605F6A846CD894806138B527F6E309485DD41FED593B1687
+2D7C6F9F7BB823D809D36C7D9CB943E97C21C5125B72366825956D3CF3778C6B
+1A505B5A0665DF727E86FB465576CCB69EDB0B605EF1AE8D9E923F9EC940188C
+2F88D13223D95AB6FF2DFD8BE1FE31FB6FA1F04D5299595C26F9A1CC44404CEB
+1A46D6AAF64370711734272D9EA845D65B76606E2A3EFF55DEF9E418129BCFFB
+839FB4EB24E3E161E987B5A932FF4474806F8DF8DA667EA9BD256234DAC36C56
+509A9666DF820D2FB31F6EAE0E65F2FFC49B23AE22D7E2CB8FC918430363388C
+6685A16AC764E9B91884D3A06FC3E5803E8726901C043AF7822BDABF397FCB50
+8660D9625FD35221166979466B3D5E891EB055E5A254A8CBA91B72A76310C3EB
+C42BB831FCE95C0217C78971F98AA26E47D1EAD695A2C4486CD4B15EF78485A7
+A00BE3D97E293E8B529A3682BBAB30044A4ECCAF85D4A42841696E6FF3396394
+DD145B91985B78EC5E8B91CE9D17A39EC95AB3D79D84B30B7BF9096A938E55BE
+3D814C84108EB20A9248A98CA4CF657743D4751E83F052DB3243E34F80B4A7B8
+51387FA89F8F1E5A9B42A18BC79684DF300D212D97792DB9FBB2A21A8CD972FD
+4F54C0E85DACA648C80FAED8ECB7E244171B9DA980F4230C4D4CA34B25A3A19D
+FB800CCFC66001B6C74263B2FD7D4424C3522985F4406024056FDCC72D8F33BE
+F6971088DA8301CC253833AB6181388DF8EEB33DF22B363DDB53D9D224420C78
+EB090374BBDE516125F18023FF00FDC5C31840C05F1EEBC5658C6B5C0883D3B4
+227FC192FF0B0E872C6E7D583ECE0D52F8D41C5989539059CAE0661F36711BAC
+4CA1CBC7912C935919CCF060BDC406FC00418FB2150563C400FE409D204882A7
+FE66102F83CC13017491F73BED519625B2F05393C204310530E9EF937FDA6EED
+F1F48961D6CEAC9127DAB36C55FFE3715D2CB9EE35092031F4EF190196FD72C3
+B8865F799DCAF6C49469453AAFD957F16AB8598B69B4298E3002DA163F7B331E
+85F63C57B4283EA74EABEB8550529C5781BF07CAA9593A3AB65E91A4D7FEAF9E
+5D0ADCDF3E6F0C16921398B79B1B1CA2E3D7E75210511BEE4DD0351B137CFABC
+06CA3773676B5EA6FB57401817B68DC7C6EAB1F3754E19BFD1165CA94A96BD66
+53A079C1A1C3B62F7E5BEF649D89E51AE21E0B12BC7CD1EBD2B7336AD76AFAC3
+55B85A59DB3C239C28F53205513EB82E0BC80585BCF89071BAF9D7B7F58866C8
+1076D731B366DB273952CAC506941F728638F45962C91EEDD3CB1ECB0E342281
+40461A60412184DEFFAA75F79AE6FABF3487ED07D03FBFBD7F4B8C9CDDDBC5F0
+6BD357A8D276641716AC56CC3F13815CCE762F5354E6EE516234FDD152AE87C9
+61C8A3723E526D6957CF4286E72816DBE34A1A714DD0A1E556B4D570257B9E9D
+D27ECA24BCEB7DB3B5CB6E3DD7714E50B5896FF146CBCDE2E55D0A4CD7C63229
+9194A655452BBAA10D0B92636228CA4D1C7AE2FD1A3FDD18C760B3DAB4B2E030
+06A587D118FF75E052DD8E79F03E6EFE215AA6C0093FEE0934DC71FFCCDE88EE
+29950050FB10B1687F2E0DC028B1EB0ED4898B73318D623CFFA68B4A117792AD
+DC7E3AF038FDA45E0980EC1077B4DD69418DF51E037C8306E1D7829C00E8CE2B
+EFAC64CF4FD46D60EF53E7E6EDDE33F43D595C9294430913F1F49D5BAE038FED
+FFF77B8563D7C1612F29E22843BEA9B452580EDB42F4675F595DA909B9F32994
+1A260534DE00C916EE76EB1D9BDEBA2147449558834AF7BC10D8D64E9A99012E
+73EC6A8236D01DB8D06CDDF030D5685A85C541AD07E9ED9F1C9C187FE2183BE8
+657E5E7CF9F6D77DA8295E88F35757497E00A1D652DE147134FACD0F63E80997
+35F363E3B60EEF717E3C26F6C2D601FBCBCDE8D4E14FF648BBB4846D05BFABAD
+762D97B85CA2164A1E1E0BBA34FA1AA5D511DD9AB5D1A28CD2E9EC72636BEE36
+E9AB39BFEC36B7CF3D7CF43BC08D61DA0D99A752FFFF20F4849157EF5C7AA0F0
+71E103ED4946267D71D494E219242ACE96441F7D024B77E2487B38E1C636F77E
+016B1E38E7A9CD4BA580A7CB49A7FB4E74F928B72045D9A587EE6FC1772F1439
+AC598618D00228850E1F37D25E893AF973F4B127F08EE3F112925FD3FBDEE241
+9D1265D21B33B42F2CD91AB1DA7E9E55975A737F37B1C66174E4FAC89354CA76
+F9D2318158AE2D820A06F6D5AD73030A9F10D2850FC343236FCF3557D8C438F0
+FA81EFC53D69A3E64EB743E8996A1E4B0FA705C692495C66623E67DDBB7141DC
+509FB036B19764A0477C53EAD909CC0285975F4979786EED6D12C348EB1CF466
+E447883CCF03AF5371BB8E3306249EA527C0B30B4A66DE570F078428BA4C188C
+A0C2F324D68948854BDDE2AE87703EDBE51A1A9EB5CC61C9A9FA325D50363D7C
+346B86A99C6CB6C5803FED24ECCFE341F1C2FD2EDE606DE36BD2411F6EC2E830
+CEE8A457F0FE37D030E64828C9D55E4188F60F0502B4F10EAC4468CBC492A203
+DADD08EA1F3EE0F6008043D84CD2E0B20E6443461D678C80A561BEEAFC9F711C
+5CA249C20298DC2CCA609FCD74078106DB66C70AAE6C33106977803202FCDEBE
+1ADFD3CA22C48D74FDD762734F2499EEF03AA4044DE1BE15C9E058A6EDD5DE1E
+F6695A536C5A44813EF9C85BEDC0625E542E73269AD3D7E279DB6C5A2CD166B2
+5F3AAA007582E46956EC3CF624C28F323D0368DDAD14A67EE86B4D9E2D1DAADA
+A0B65E17BCDBDB28D689F463629E8B96132122CEB7B5FCD494B306361101073F
+986EF1C6D416BC42C1932866EC1854F204C039F2788AACA2FC2128BABDDBA401
+127A370095DE40063BE0BB76B16A19667A8E7E7CA6287030C861E34C45F7EDF6
+14EDDBBEBCF53D0987CA3F9F6C70A943714098798D7869A01634E4BC898BC9BB
+ED2BA79341F1AD5B07EE377D17A0C0620B3737279257A39BAAC5B0D62CAF1241
+020473D894EDD655800F73D1EBA4D31FF778C8FE28C5497C7A1F7ACB9CDEF599
+124170D34D0CA7857E9DD791510D9152D21E6D86195E4FD91B64C77E7D98F377
+FD1DFBBD75FC6A5AC2A5827874B174FABE8536F57563BEDE0CA9DC0F2B923D2F
+6DABCCE5551B6E2BB50E2D230CE6C0DED5500C5386ED1425B65332A1FA6FBDA9
+E66A01CAD24530E71CBC4B5ED10D63012C666E012F89F01411CDCEFF6AF7E9F6
+2D222ED18B2F9FA4763847805AC1338182369DECFEEC4B7BC4E495460A99DD34
+4F0E9FFC41735658B17E08780E519B5DBF88795FA1B17A4FA409A075089D4DA5
+E3747553BAAABF573CD718BD347F09703F301C5CC2FAC990AE29D275940AC326
+3B90E3BF9A41FE596B01C92575747F685FAAA6D1A8C1175FF05A8A44453276F4
+ECD8EF78AD673B92B7EC1E923F09450996807F623BB15E4E3253EF34FCDDBB65
+F9AED9854DCBE1F0C324908BA1FA95DBFCD734045A04EC25A8AB243780377D1C
+70F9D68B844A5EAE1FD168C0D015FEE4DC1D882D708B5350A29105B5AD5B972A
+1865D64FD5E92BBFF370AF055E64542E6654B7FC31FCE4B1CC764EDC2D557B36
+C5F3989CFE322EE3D4AE2638351926B6C7DA1B3E27571A9587D5CBE4CBED1543
+7D069E6DF32C9AA03D0B765E0A9575E0347EE556CEC542267DEB2082915DD03D
+137FAF7AC57E3BA267C2D6D6BB1BED18B76EB5584C18ADB10F923C31D2BA113B
+B5BCE33A4DAD2FB21F02CD333D36D4B82CA2E10B02199AAF1BCCF6F6003FDDA6
+FC55228A584A2EFE27C9E17ED946365E4C06ABBFB82E9AB396CBDED6AC89A338
+BA02DDDA228653F245001B05B8A4693EE2CCACDF69DB7731568B794E2A7400F0
+5D1C0C1DBA3087E796D7D20227FF31D1B3C65F5A013B8FDC3D3D649F2499A1B9
+9645E0D34B4F5B441A240AB2F09E15BEB6A237CD67B97EFDED5148FAE95070EB
+164A4D93B15270466343C046E00308E70163BE966F26CA149CA035BA1E8DAAFC
+06487D6BE18DEE2C4F54E66369C7A00BCCB02B84AE13AD4EF365C25C32DB3743
+BCABC4DE9C1F1457026DD90B3FFD49271DF3915A767B27553D66FE405B2B4A45
+E50690208BA5C774F8AD3F205BBCCC97DEAD8973E9A41AC8F1FB7D1A9E18D38E
+CE32472C08BB06D943D0147B8039DC147A26FDAFE28830062381BC5C5E31A54C
+5298C20FCBA6231425A5DAF43C339473F2428A1AB32BAD782FC62CCDE8E7F310
+FBEBB7DD53E0F980AFAD9776A3D40A9F01F1E79D407A0AC79989C1B176D2F757
+DA68285719A54C74F0608722DB71B32368232377BC538C0793234771F058F69A
+DFCCCEAC8BBD83C6C496034FD5300A903DF02088B7FEAAB76C7CCC676656A0B3
+05EE7239F93C33218C62863A6769297751B54DD84A95294FE2BCD9DFD6C79076
+167F3B21B7C72EF571B0ED99E2C27DCBF7714481105522336C82FA5BB22848C8
+755E1A03D2F9C3FEF18DC220270F502EC22D821B794D601889FEDDF18A716115
+4B728FACED91B66198786CC5D499B5734B7B69A97096515FB583253CFC0F1199
+F441B70CBAABA633376BAE8C9D7B9222D48546CB974A658543D47330B7D98379
+5D1B27E49AB389ABCEED1C4B0C6ECA9D44DB2CABECFC7C29EDA255CB2D6A10B5
+BC40C8D5E318F2028EC99B8854D9B5290680FBBE4F669AA87A56767D6C4FA3E6
+602F96B52DFAA4C389DF82BD566D5BF1536D5584A57FB77079AE1A606A9C46B9
+89F3108C737710EA4E65768E881CF2C3C558CA3721198A118006DACF7E57BF7E
+0621591E154CA1999123CEF212615C753BD45F473378423DDFB1EDB0BDA5745E
+F37E61040A52690ECC0FE485F6FA80B6B877472ACB108C5BE4218153380471CF
+8B1472A21D5A39D99F24B920BE9D993D17FF23EC97973EC6A9A5E94FB587E0CB
+BA71C2BAC80C9F469C9D2BAA10B594A57AB1B1CBBA91A0A855FD28F774AC5AE2
+9B3D5555615E146119EAB5205838E07F9F80193F4EEE89D3493A20D71602744E
+F29104C987C1F19BC6BBE0FE193458AC09B6A84FC880194E8A28EB4CFD430594
+548D5122E75E727E528FF59822681A5F148F24F3B959B2845A7C70441631F85B
+168A0C410C6A4A75D4E249BB76965C1C3CD3919EBE5FF3F02C2E76307D387EA2
+2373027CB9BF4BEE1BE32047E776BF81456AB67006E8A1B16FC3E59E69A0F074
+495884EC0E7D2F961F88E5EBF853FA51451BDB3F3EDC55CB8858A116684A7254
+333ECD1D64F66A60F9475DDD6D9F2DE4EA3F8CE4B09C88BE997CE3CC13596E69
+F834A3FFEFF935949C69C365E50F8B33D8A387C8B6544E2000388E3DA38ADE4A
+2C52C4E57773A930CE20B5EAC975DBAF6F7F85E93D7D575DCEFCE1371782BA16
+D2D56DDB217D359FED05A3F7E79721477C2C590A830A6BBA00BA9018436476B0
+613128CDDAF5CAC01FF5A6263BC3DE3D10FCFB29121F56C3181245875A7B3D38
+D5865422713D488A87BB8447DB27E89E1DEF4A8001A80E009F65000383272C63
+F327898A5F35C672CD27A97A8D108BEF43F52A767F6D96FE7D21ECFB420F8C52
+85C1E075A95749FDB5EB00D0BF1FFF7B6F1CD62785A0EDA6DB303E735DCDD9A4
+126170D32036787F5E4C94E185A961E6514BCF0358941741B22CA4EE4E34E0DF
+9681BC5467CB4ED189F201EF6C7A8EABFEB327ADE50C14AB484D874BABDEF442
+967FE7CC08237F2ED25D3893E319DAEE7EA80706252533FA198C172C4B0330AD
+8F10A79B17AF825C8893CAE2FDA02D329FBC9605952F5EACB2D9D330AB883349
+384D3F90EFB46B53DB1C038C6D77F31F3B4650DA576FBAB2BD412FFC85E58ECD
+4BB25F102EB36A2AB5B9CE1E5A2D913E246E0346EFFDDCE764B1DD0E0B1D8F08
+3984B6898F394B0A04C89DF5C426834AD8FD0655D1B0E8B37059B0DF2826B250
+B07B1107BBCB26FE581A1F5D31FD214EA4AA2D3547CC890AE8B13ACB0756D3CC
+59FF711C8A90503F4D94891710D28CE5FF5CFCAC21C05ECB436E8405C40E6308
+FF120275372FFEAAA70863B530B4D9597FD2C8ED610B0A25E7DD64C7B914505C
+AA91C2CD17724FDD9779659B0B643DBFC5598AEA3C33CCAB0756B74648CBE0F2
+FA889115D99BF21C56E3E4DF8995E508F91CAD7E584BC6D7E1626579C1B12C78
+AC9CD3052F31018E897C8E2B74184AA466B64154A1C9F730F298EFBAE33ED024
+EC7618E89A721E349ECC79A6967F8423F00FD44375724A389EA39D7DFCF83D32
+F9B5621D808EC6F54DF4EB3AF5B76E606719AF58BBA0D9BA09B6F8034B7E4D26
+089F022C0E31B6B5CE87E0F48D9C6134C5901F47489FBB96C312759DCF129952
+EC1F992E9D09E006847F2418B05DCC99E52A1840442311AE921572576EF7629C
+8B151893187A442C583AC5B992DE114D3F724F29BC1771B7594FC1CB0AB702A9
+516529FC200C4D88459069F14BA7CD235B57C37699B28BACAD70F61242E626EE
+4C6A652BBD3CC8B50D991512805F9C5E73626B3AA012C6513F95552233AF0C00
+9ED12F50B07BF44C9EF44B313A59928D2E76562E139EEF0CE7F3A55502C96883
+A01F8C78D2221C794DBBF74F49A0097A3D88184BB9C3979E3D52462D8D2D0302
+332372168E903BA6C660DDEAC9459602BD97371470B0BF8E86AE835D54652854
+478473246B14ABE78FE5B42E708A344CE739308136C0AFF80E7737C7838D7891
+63BE52F9EFC17741218E9B0B86AF7A69E8D194B8E91090B4CD0AC49FF3421EF1
+60C502212AF7562E7D7C8FE9FD118953B531CDF366646344C1EE4017B4E94358
+27D6F192B71018C1F1022214AC7F67423B11C7A4D81F35856AE1EFB4E639B1BA
+FD660DFF289792236CE8AD3EF68D7EFC13DCDA2519C4C604024FD0739D100CBD
+8A3D7415AD4EE6D6512CD0FDEE288C8E9F37E1E7813BEDE7BCA806F494B1D8E3
+EAC8F91BCEE12C80598993FA2649821BE086F79A58EDC1CC51F70F86F65524E5
+DD59E1F64FCC48BCC850F3D4BAAF052225CD1E5BDF76C4FEC9EA00D7F979D4EC
+84D01ECEE9E7AEF7424753B605A6D258B589686C18786575FF7F18BBF9388D8B
+069AF17B9DF4FC211352F9BC8F2EDCA7F537373B57AC0FAFE2E10C388130FEB6
+A6E673CC94DEDFD9FD22E8D486784344CCA0BB25E9973C57B5162359C6F831F3
+C50C18
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT10
+%!PS-AdobeFont-1.1: CMTT10 1.00B
+%%CreationDate: 1992 Apr 26 10:42:42
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 33 /exclam put
+dup 34 /quotedbl put
+dup 35 /numbersign put
+dup 37 /percent put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 63 /question put
+dup 64 /at put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 74 /J put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 91 /bracketleft put
+dup 92 /backslash put
+dup 93 /bracketright put
+dup 94 /asciicircum put
+dup 95 /underscore put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+dup 123 /braceleft put
+dup 124 /bar put
+dup 125 /braceright put
+dup 126 /asciitilde put
+readonly def
+/FontBBox{-4 -235 731 800}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8232429ED8B7CF6A3D879A2D19
+38DD5C4467F9DD8C5D1A2000B3A6BF2F25629BAEC199AE8BD4BA6ED9BBF7DABF
+D0E153BAB1C17900D4FCE209622ACD19E7C74C2807D0397357ED07AB460D5204
+EB3A45B7AC4D106B7303AD8348853032A745F417943F9B4FED652B835AA49727
+A8B4117AFF1D4BCE831EB510B6851796D0BE6982B76620CB3CE0C22CACDD4593
+F244C14EEC0E5A7C4AC42392F81C01BC4257FE12AF33F4BFEA9108FF11CF9714
+4DD6EC70A2C4C1E4F328A1EB25E43525FB1E16C07E28CC359DF61F426B7D41EA
+6A0C84DD63275395A503AAE908E1C82D389FD12A21E86999799E7F24A994472E
+A10EAE77096709BE0D11AAD24A30D96E15A51D720AFB3B10D2E0AC8DC1A1204B
+E8725E00D7E3A96F9978BC19377034D93D080C4391E579C34FF9FC2379CB119F
+1E5BBEA91AE20F343C6420BE1E2BD0636B04FCCC0BEE0DC2D56D66F06DB22438
+452822CBEAF03EE9EAA8398F276EC0D92A7FB978C17805DB2F4A7DFBA56FD6AF
+8670EB364F01DE8FCAFBAF657D68C3A03112915736CEABAA8BA5C0AC25288369
+5D49BD891FABEFE8699A0AE3ED85B48ACB22229E15623399C93DE7D935734ADA
+DA7A1462C111D44AD53EA35B57E5D0B5FC0B481820E43222DB8EFCD5D30E15F9
+BA304FA879392EE0BCC0E1A61E74B3A1FC3A3D170218D7244580C7AA0DC65D19
+741FA5FE6F8CBF60250ACC27454BBF0897CA4B909C83A56672958752ED4B5E79
+E18660764F155E86F09EFA9F7685F2F5027EC85A775287B30E2069DE4E4D5712
+E7D033481A53A2702BA7542C71062173039030CF28D8B9C63B5596A9B42B33E7
+D922944A38713383D3648A4AF160A3B0C8F3379BA4372BE2E7EA49AABA75AEEE
+C5DDE1D8BF68483C3D21271280ABB91D54CC819680322EAB72E1250A760BC8DC
+FF798F2ABFC4F3539392985C4CB324B00072295FC160818BB0355FDC4F12E39B
+984826450553E3D271F03D8DC2D12A92A4D32034FD16DA13B876D88C8C097384
+46D8D7E41CA1A8979F9B07EC3337E70CBBE3A377235B04C79BBBDB66CE1C1A41
+89DAB7CE91F2FC0CAF6DDAD09992D56F72299068192610EE3DE5DB7CF6366B4C
+D74F414484DCCDBA449BFAADA39D0F27574E604E31CB513B18E3821A33076151
+C2BCB6E957C77A0AECA48C587ABB5E8C7624D56B32F80BBCFDC874AAD6EA5119
+C9B06886F08CC7DE5400E0F52B07483FD4BAF26C1556CA27B259FF3DDF71131F
+DFC05D8B14C28F2073C460B5011B76D84F7917E919E50FEF563B5DEBC5CE6923
+ADB72392C98D03CD978D3FC207A52B91E267E7ED8BB4531E8BBAC113DA68765E
+E23FA502BC71CFB91E4FDCA39BDAEB7FEEC3588B1108CE4A1652B770375724A6
+508376586216289093485CDDBBE68956210B6FFF3953D097D66BA31D19CEF2A4
+35A33AE97547B81426E58F9FFECAB633C6433E86C32130665210F44F10F3A2F4
+EA31540D0BC08EA4DA2DDE3E8CAEBE52A3E8B037632B235D4ECE3CB797A5A939
+12C45C282783F675060040FFE2676A7ED903798EE3B86644EF30D3B461D4EC3A
+A1D2E95C02FF1531D93180F66A13E868C9E1FF1722FEF6C4F304921961D4A10A
+6AE943157B1B0E8871BEA71162E5246080618A96D5B23FFA8F420F2AC74BFB60
+BFA3BAC4AC3A320887D4090FA3EF7071D2E1DD5D70DB98A01B6D315271D10F2B
+3D9256D96FFE8D8BA0F4781B74490C63686397241640B08A08FBE7CC9B1FD0A8
+21CECF0F994CC97AB18411EC8745F5A6AF56010C22E73CFFCB45B82DB68E6552
+2E57A4C06B96C55031442EE1F53373C50E14657ED320D9ECD21ACB26D7535DEA
+D36F68D8479E0B28185EDC21207BFC130315E7341A85018CA22A251ED1BECD7B
+08A33D61A73E061B2B1B6B23FAFFE725F967F1713EB98446A9045AEAE23E725C
+ABF73E2B90F429D6EF62567ED4140AB5648EAACE7DDC8E61B456C36D377418D7
+4BBAD5754ADF5D3023EBF5E35886078B9553406EAD40A1328EF917A05730AF7B
+1D776901B4AEFC3444FD3FF04EFEC96FA9ABCBC841975993E6E829A1732D8E56
+CB51C433510AF8E81CD8693A9561AD2C3F9B9737C698FB07D42C089F720E36B2
+997B18E2BAD498424539316476532E3B730962F63C8BBCB9C6155FAEA379CB8B
+3A95089641FCAB3E3CCC1FE6A2BFA86A8E80668715BBCD87FD41463D2271C067
+0BC3563F0A9991AF367D47239E3A0D9B387A609E143312F849EEBF29FB05F4C7
+C9961CEBC8A59A432794851499E38B747BEF6763A9CE65F6578A00BB52B8360A
+C9E680E418EFD533714834004F6847E2711EAA91F7A7F7459B84E74B8C89A8B9
+F3DAD1710EC7EB1513E0ED1126AF7A8A85DD62D68A1A212587E091BBEBE77CC3
+9F507D6675FA68478938422F71376AB89445165DC953CB7C2FBD74E0E2540AAC
+5A9EFB1A07B4FA12233FDD04A2EBB453DB695AC9B568FF0E85FB92E6DA3EBDF6
+F2192E70FC1B4678090AFDB63D09D186B4ADECE093B9F2089C023F12FF57BB31
+1471C0EB88558E548A39FDEEB4232F60CBD9483FF33F8DB99EB33972739D0D5E
+B6219DFB2535CCBDBEDE0F1CE0FEE736A6B8C462A60C4EE8539ABD972D5B4BA9
+5FE95A60A9A57011A266D3B731B5C3BDB670E6A80CB86A819E1962B01C89CCC6
+EC65D58C736DCCA2DC07F797C919F044637114229D5B862A6F9F7B12AE11CAF2
+3265043AA9C1BF4C4752F0B4BFD01449F4D539AC6D0832F27D948634CAC3083B
+F790FC4A4A8E56CE439A4BD1C90353758504606FB157E981CC2F00AB8A4718ED
+83C5A8417BB1DAC624050E9B52A7CE2DA21A224500343E3F983027CD972C9D19
+F4C2616DE83D7E1E1D1F6B934CAD387E96011D61133D78768C024CC8F35101E0
+0820D053C558B3EB5B264C680CD025BEFADF200F198CEE7D7F13433A96731B45
+0BEE1770C04F88767CAE29C2FE8E8E78FB8FCD1393813A3D6D5AE15E5F3150BD
+5CB7C0E718F99BC82A807DB6917C776D0E1B4687234B3460B073B1D6A90E5F8F
+309DEF3E538C170F81F4A56ABAAA9D8CBB333C80DA63B33FED75530DA73D8481
+4A5710EDDA8FF12E0D8672C4D077FFF4E31A152394CB4E0264797A4821C72568
+4781EE748CBF90F6833C6D11A66B07A824613B1A9861BD54902D4D3D645A9EB9
+31BAEE50D1B9A73F4AA015C301EC11FF53B127A7D96B04FEF8CC7A863CE61A24
+EF5E5638F571857A52BA9AFCBD038D8963563039BEC5FCB3110211FD02566D94
+DF3FC9C2DAF3B231DF46F3A07BCF75CA118D9D59B535412237AC8B32222C7A66
+C622603920EA05FA178EBC79D5E72813DFF35D4AB1951251EA084C9959C5F6E7
+1B91C4F6DAF8A80E1558FCF0C5DA368E4DB89F72B379F6A4BC45D92E6A14DCEC
+519A1068FFEA10E8C84DCE615FB0F741F87D89DAF237BBD31B52EA0EEC9AC8EF
+4B98DAC49E20DDF8B849EB816A0F8F076DF01B5AA03EF01175F287521013E82B
+414857A6F7E1829537FDAA6468C0391CC30BBEC2D8E97ECCF4A3DAEADB087AE7
+DB57AB20E57BF2EC7B6DB5C309AF653EF228C2F29871D6B8F92AC96D0BEED738
+7F7F009947D85982F576C23879FC10AC52B5BCAE7291F48C97633FF8BE68D485
+EA8AF9853A88B358ECC1A2724B71A177BBEA95BBAAA1029063A27956325AFC07
+4D719894FEED33E67764887106598E3A0502D70E39624D3AAEE1D7694A4C9083
+37C37C3562DDF5CBB6288C8B5464F46A3EB07AAEA4148466A2428B4FC0EA3570
+BCAAFD26BABB091639FDFBC537D2CF28D69CC671F156D8E7C1B15EFDB17A3948
+348D7D4B7D306A7A48DE1923F67CD83EF5FCB3AE8DECDDDB7827B5B4A1B2D699
+0F5ADBD0DADC9C006DF4DD91B2AC165CF1DF199B0201E58E37D455AE61E7BAB3
+909E8A34AFB8CB041D969D314DE76990A48FDB897864EC5084AE8EDCE71E22CB
+E152BBB94003106AF073704E00E612EB4B0AB27D08B715BF094ACC7ECA9A059B
+1905387221A865BB3D6292016A79276B2FA57871836425A6CF21E3B56C925D40
+E4889BA24BD49F65824824E98EA5D31574B175D6925F0EB9745A466440B0C1FE
+92FB0E19278B39639251580907E775838FF9C56B62DFB4D64BEB1875C926BC11
+0AB8174CCFFD67FAFEAAC7A46901F72A8584459312AC8BC59A9A2FAEC7AC49E3
+D6A76C2603173608397702268D13C7B61DA1C9182E944983AA5BC989CB61D915
+E61EC3B5B6F727288CEEEDC9D8F704462E9727CA5CF5932A624EB06AFF84C1D8
+03CF2096B42DD9D18C459707067CFDA121D28D8D7F82B2E905B681AE4132CA8F
+D7551E01D44758B2C7AFE857E5C074326BE8122E1A6D61F67035B9826E634E56
+9D0B584AEE90E1D7D4535A28C2E3CAD8A178C6568E8A73A9CA72924FC4B91898
+98ACF3617BF6C90BF1C749FBD5A5AAD1808153CAE24CBB6179792A97DE66EA62
+5F2C2B10D18D827BE1237680FA3441A689E1833B1232CE2D1A893D70075487D7
+AC69D2804B5D4B5B3056FC1E8DC3986DB6A29A919F74D8F7DB4CA49E96C282AF
+3DF5B149ED5AAD7374AC4F3FEC2FFCAEF91C65DC3FEB8FA6BFB42DD9A65DB830
+F2660CA71BEA8872060728A32F6557AC61D9F11B40DC87B2A0681F345921DEE7
+907106CCBBE431581442978712ADDE28562B6CF48B93687EF300315D615274F8
+12AE7973AEF5637BC65FEDE93BAEB7D8DA4D1722CC948E79D6FB500A1116555C
+B61EEA652224C67AACCAEF671DB18C7FE23AB7BC1EAFF1C0BA29DB5BA5C2CA2F
+A44C2DC765030BF9698220C267271CA77C6F8B7016E42B95E3F6453E05DB72BB
+6D86774C88B2DB31151270D2323235251B383B660D265C2D4998AEA580605758
+E46C144851919847DC382002B8E293018E39B32A33E21E33333FF4EF16256163
+3E4C42CDA56C48C7FE4DA7A2B6CABFA6FB46F41CD29E60902024AE4912CAF9D3
+2A7C97B53983D4B012135C51898EEBEE389A1986D407B80B5DD71E9C6F8C51B2
+F900026DFC405702EBF979CB318A3BF97AB2DA347A6480778F700C2476383551
+A11D0D0AB355ACD8787EC13452674BDEF884E222485CE98DD1C76FA8175E8C10
+A38657950432F1E8832B671FA09CEF57F9EB4BB158F5D9C6E582E10CEA63F7D1
+F7DE82FF949311B6B0A29C39A1BCFFA039E63AB97A88F90D0B31E6F341CF0934
+4271C75BC9B362DDA1FA745462BE89F74FA2AC6791C9295DF406031CFDB44220
+9BC488FE52AF35F12CEFBC046F17B6D78535188CC4A7CAFDBD251346192CA09F
+6E28EC633C475757EFF24D5230317E8036F571BB4840765F1F0A81BC189E0B28
+2F270F0DC73643F794189878185EC1D0820E771189172A6F47B8716DE5CA64A3
+577EEEAD5FF2D3315AF1D1CD964AC96CA6857BE042410C457E3F47FCDDF3E55F
+1BAD545F8E25E40AE29D99E029A0E0C959278227A3D71C47F258977C4BC39BF2
+2096A66E6192DFB166E7BA682257F0AAB86DCD7B5AA7C8F348FAA031846CAA1A
+7424052499E6DDDBD28CD6C1DEC831CE0E4E65C66202E3D5FBAB06B23846C0B9
+69035E387275474D9260CFB80A51A1B6FB97426BE1E91C1DABC6905C596AF761
+4AB06D59FE77FFFD214E7BFEAF791D69E768FF16987E6B4B6CC745029DF32303
+B6702C60BD9C569AADDDDDFC972CC368C99AD581F5789B04B3FA050483B34B03
+206D78BD7C309B12B887DBB17AAF36BF42AB778BC8406C58BDE5636B5C26185A
+D25D6412379566E44584476016A046F9C9F3F8F540D0C456B5E7FF73CF4BCDAD
+1A6977B7355D2B5A5F991DCB82BA74D9953F2C1DC4D2FE038B0946CC61C5A887
+22295E18D466C0BD279A7DDEEDA2666AADAE29D9A5B4E557E7D7E0E15A5881D4
+242835539F9A8116D79C05D96DA578182A3A26AFD257839EF84A417F6814ABAD
+9C980FA246ADFE5F295B9B6F1071C16ED2BC1BAB95FBD5511E378E09ECB753BE
+0220590CC4E37A361F324AAD9F95958BDA8D3EF41415370306F863A149325F15
+86B8AEEE8AFDFA52A3142D160956B9E205C0F97634417EADE4BB1D0DCB2C87C1
+88C3F011E9B8F125EB954C7B78E058205011796E3DD1D6534CA0E3B00F0A2BAF
+E3D67C1DF19D3CE1BA920913CAC6AE6CDC90CAADD2572A43669EC39159682696
+A0415DE354E8B425805CB5A61CBEC017D8E2C2077F3F9E39BB829EDE2E742A81
+54A6CFA0BC1BD7D73505823AF44041E6DEEDC28429796A402DA101EEC9E71D37
+42992DA99AAEFC059A389A90B5E0A995DF8E3F14CBD85C0E7C03F1E5D55F583B
+B85790EFBFBFCECB93B2CB0F9DFD6F06C8AA252BB699B61BC38309C7A34170F6
+4871011CBA9095CA5EC150D2A215AC595DFB03500BA2F0B1D578A0BBCCF8957A
+CDF1D0DC1BC6536E94078088A253D728EAFC8AEED08F75E3449689CE0DE21B2B
+C57B4709B7BA5070DF51CEB7C30F564922561F4DD42B747BED2D5DD46780980A
+5D1CF9513B1F1DBF7480A7E9DA15768FC55D165619AC4FCBA01B540BC0BF3BED
+20043FB25239990EF3E8FD80F2B2D6E5B557D0904F211857E43018C4CFF154B8
+A5F85DA6AC400A2623158C20F07824A9F87A59223A1E8086476B45F5FA39BB58
+21773C4EF88034D748C3F1AF96257282CA8A4EF52DE225D4190CD0D73E33BD15
+69F2A1CF366658B416B2881C6983AFCF2E9B9EC2918EAF7F6E115AB87392627C
+A00D5C1C3434CB2702BCE26ECBBF49D1E8C9A463D207D2607A3B859D591F60DA
+EBE452953EC688847C87A4FFDAA9F3F4B00928BE5E42241F14BD195D2F253685
+0AB92AA2DCFF48396028E19AEE659D3BB14EABF205424D36AB6AEC0F32677EF0
+D016019D122754B4976102A276AA1C6BCF4692211AAA31A1F95DA557AEEB1E9F
+0780CB9449B91418586B70365AE30CA54900ED2E9E96B13C9C5ED2CF1ED12EF5
+F8A42324346785DBEB97F6CAC6B0075D31D5BEDE71685A841E2B2AF89590B9ED
+5A6361E6B993EC5112BED5F8CAD5123C023CE3773F6E20754C29B8188F5EA3DF
+0F270447764B692935769BE47A5357526109A3351C4E3C139BDC73DC60AC8F39
+7987036E139AA0D28351195779687EE688222B9982052D208CDDAB41425A6D31
+5DF4BF6FD8269C139320E9B449C1C7AEE220AB86240B93B9D971D6D0D8A606B7
+CB325D1315C3F544FE10A4FAC7FCBDEE6235E93792FD70DB9CCABEA3385C6E10
+D455DF2D180E297BB7751E15C436484F34D9BC0A476423029E3804EABE421EC4
+8E4234C3772C425F77247C7ADCB37947C024251C63576295ACA4F89C49D19445
+AF85E3ADB29B0140C7D149148D9AE618CC9E3D299A4EB64D8E2EED46A45A3DC8
+73CDE720FCDB72B4D31FD01DF6469582ABE456B354808985926E6FB9C3130228
+65D16B82ADAC33EEE45415D7E6BEF5F8D30DD31AB8A0BF1151F2911C70134BBA
+ECC569A7F18B4B9C522CE80379BC1A78DDA289E8D3AC439DAAA1795933B96B42
+608896CA1EC6452F5B64B1A2552182B8E2D9F1AECBFA261165623B9EE2229E4F
+C913121DA5CA2CAFC07E787D58CE15D75B89C0EAD734F968CB52DC4EAC3DDE6E
+0A3BA7875D4C2AD62E58ED3E425DE2DE6D3B592DE55E3B0CC80AD5D6C9FC2E19
+DF89E7A87AD1B94EF7B5B9FA62909FB8F90B800F3C9F294A2C262974F8F7AB8B
+96578909CE3ABA59268B0A1ABE276970093AA7C58A1649E1380A5F146748B671
+23998AA72C998E464BFFB3CBEAAEFFE45319C8C573CD4DCB08596801B4CE8BF8
+A7A93B3007EF27842B9A97396964019EB771B3EBB6C2262B7C5F3127265C047D
+B820659EDD5524359BF27F4F91B884E4D6D72DD98341BB6050341AA7607471F4
+954DA63AC607BAD152539B65CC15619972EF4F4D33A792643C70A92BDC4958BC
+8712AF4764C6899CDE26CE3718C7F4DD12A8EF406392D6FC7068AACCE2AF9680
+D8C86FDDAF19DF459AA8955D4C3D059A9931A870EF50CA8331211B9E3D213394
+6B4F95A3504066925CDF5F6AF0CDF0B98231075C4308294B2ED7627F42202DCE
+FF290F9F49E9F1F445A5EA022CF91350BA31DA4776053908D0EFCF30463AC0E5
+AA8ACE271AECFA8EF51A172D08C328D6B326B03D086BF91F22D3EAD4B98CBE6C
+4A1876C5A67952A33D6B1405E1C6EF2313EA4EB2AD2F08A55C6A8F04B418E13A
+3B2CEC3C9632E864777F762A2DD35A6664CD1A85F68DEBACCCB8987FD06D496F
+5EE925F5398D30648822AEECFCAF5A99E95971E84BBD7154277E31520BB792C3
+35A421E1856E8D7365FB6DED41E0D4D2C49E83F8F6B3A128A7E6BCB1F3216324
+F0AA0727122610F8120E8C1B834EA2454FADEA8608D007A03DB692F46A7689ED
+825BA3EEA409581D73140B0AE964A23C1A5396321B3CB8E2FE731AB23F69DDCF
+2FC7924CA7033165552787AAB4EDB0AAD11011E3CE8677FB5855C900B52669C6
+16F361F09C4BFD1D2F33499EAB5D3304EE8EFC6328DBCCC9E0FDBA2917985F03
+66E97ADDEBD7CB1DDBAB3DF9A49DCDA7E777688948FF28C5251D172F583A76E0
+EBAA9D7DD896F6DD6BED748413CD73FB62E8C9B503275B462EF64914997F56EA
+02D9B6075CEF2F9B24D44FAC84B077107DECA574328059F016FAF6692199CE91
+7F6214DA83F6D1EDF757F3B032D94CE15EDFE89A3CCE82207516FF44FB0BF681
+B6E00E1EBB2E517BEA4744D15A43BC380F6FE1B8EE27FB2C83818D768E633600
+D52EEEF61000BB400BFCED1D0FC997DA253AE035EB5DCBCABC30D8891A50CFDA
+99FD20EB3ED54EDE5DE7C8FDD5D4B65C3CBE467397B56F3E9504410325BF4913
+FB59AA1AD7C65BEEB3D25BD8DE65824A524EA27EB2409B4C2BB6166B08E34468
+FFBC5C7A8161F0F1973AE5B5977E887F19D0B87C1DB4367E4B42BF456ECDE536
+39443B7687E6B58BC8577F1651602764088D2A81445703DCD2AD6A2C7A8E91AE
+B95C1DCE9CC4561A5D5A4FB341DDB7C692DC2C20ADE596B6CF3000BD42310440
+6BAEBFD77845BC054F58B86A7061E382A14799C765C868D3E6555A93B2CA97A8
+76CE6EF7893C7B05626EB2F6A2502EB1F8EC002F4E9D7D28577AD06125050A6A
+14E1F3D838F4E870B7BED0E8B00F05E94CF7F59B06B23C02A7054F02A096F241
+71082B3BD67D172B7CEE10FF6EBD30CB9ADC959EC8CF7B846C34837E41CCA707
+DFF6DD0CF203B1DF20443743059BFBD63552598BAA6BC3CED8466EDDDE8D5725
+EC41CE8AF9E6446686CFB51FC27DBBCAB6CFE460CECDEF7F4AFC7A7D28276F9B
+E19FCEA81CE38E6785CAF64F1B59B0E64F6177D01AB5F8252E8650BF56337509
+C330F02ED4CDF5D53A501F4E81412A33712AAF3044DB6F8CCBBCB73BA7210471
+E59504DC24F5B12B60BB25EC8226AFA3FF0DED1257BC49D124674323B4CF1028
+FF372F591EA216F70B83F9BFA100BF67D6507D08F15404D8C1C57D78F916B530
+2135ED9C8BA1781E18D11EB741A8CBFA2F8B6E433ADD2914F185452F130C1322
+E3BA1C34AA72E5BD979421929D3DC910A9583C038DF9D3F5C6791FCF6D37B714
+47B4D4AD3BE562AEA7C233A096763FF5E5D87E238B104E7BA4AAEAC9569C4085
+93F56789FB5DDE2C5150FDD7097385C2D9CC39965B1601D16345F503B191270E
+2AAB08EA85160F7C3EE11828DDE4A6EE458356B5D9D01DB780FE3E1779915537
+9FE2E3ED7ABBCD4F78377309568EAE4604A01962DD4A37A474791DD87B99E2DE
+68A0527A9976B1B059C2C61812B04AC474E2ABC632DBB8DCA5C0819C865741DB
+D9B2B12CC1CE8BB67E43F2715ABA6C89C99A84F86003CECD1C8FD1276BCAE308
+CC55D0C31CA9CD029A4CCAC7127C14E30A1161CE3D4E86F64F1AF182A00987E2
+1066C037CD34007F31B6899EA07B3BD553A6E39DBC3D570E8D74079FFDCC3512
+CEC80D01334A588A410986B71CB3ADD3CF8ECC000ADE998B85AF3808F1C0D06E
+776C81C7E173263EF76F157D972D6EB2A2C36F0813886CBF3D46557AA7B6F13E
+741A2F0F2BF2AEDEBC8EE496D19AA1DC82668158DB1994EDFA5E57A1F1B81B4E
+61764D20BA19EDBF16D234CE0A14777F51FD8BD208D4F4CD8CCFC10954EDDF19
+86DD37FF668EBBA7769A270FF0A99CE85048889A5AFA09B8118EAC11B78F22E3
+262A2EE3108D5B9BEF8DD4F5104573F3DCAE837D20AA9FFB646FE04B984BA895
+78BB092933EB4E85985E58CE215C2D8643F5048F65A0751F9C7E052B72FC6556
+D3C50D835A2AD50B3CA9ABE0B654BAB617C8D3ADD698396BFA520035BA9279BA
+F4D38A2063083F5FAE33F60A67C83BB7B8763AEA9F8EAEA6696918668ED70D90
+88FB78C80C41EF9B9094B2C08C48754B1CD18F341770916144372C62E0AC5F70
+0B5D648990311915BCEF2049A32CD4C455E2043CC4911F6A3D668AAC9DB3E76F
+5087AFE281EFE975AC63010BA08B6CB9803A00A8BD7544FAF06DAE4D4C597A22
+59E493B29B14C5C9FB0129D25B014A7E40E401E79D7270BD7798F716E605598D
+1E3DDD4209EF1E56557E66F4E71D65840D5F7F9E3A98512F1BCEC701599A8E4D
+7CB8624B9E0CE6E63961166ABF9F84F709306498FF75DF3A9A442B2F4F60EBF1
+2C2EA729D0EBB657B79D669E1782DF4EFB731E062AA59F1011E146590AF34AFA
+DD27A8EA7208A68222B46F35CC08E6B762246588D072414EFE83541233C4263B
+E3FFE22E9B28B47C39063C22C6099862A434421DD266D744EAEF54A673706E58
+C6D82F80697AEAFB7B47B4B0E6435489B2576812E3B6D9DBA21E99728F5CBD83
+BED39B54D8461ED02A07D8D38788646808B1661664E3BCB689ABBE5AFBD73F78
+8EF3D0EC3785A7FD103AA62C8EAE5C4DFC629C8E1FD2B2B65F5515CD55A9C029
+ED25A6B08141A3F30AB6884622FFDBFC22CC56304E24A99850119140D7B13E1C
+E71354631C185430A2FADED956BCC21B66729A83636290C418ACB8D48BF79F4E
+21FC88CF9963488BBF8F08C1E6D19DFA328A1C2D0AF8528F5147F9EB1EA49CEE
+2DAF2F1C15C8CF734ECA8FFEF1A9A6DC53A2ABEC1342D8729846A474F1543E80
+FAAE46F935789CE56C27FC8C762459008DD1198B0ACAE84F8EFF8DE367C5AE78
+0E143D02A9BB4D3BFF25AC2744A4C8D448F9C94BE989E147B8DF529BF84A3833
+3DB8C5764F785EF3D1D8C1EA9F7DF1E38D916AADBF018B1C4282DECA057387D0
+6EE4BA41C5EBEFB721CDEA04E7BCC136DCD3A84FA464FB7503CAC6ADE6613C69
+6912DA348709039BBAC727CB4BAFECB841523AB5BD85A62305D129B83BA7093D
+E8138A8C15E00DFA2D4F0BE6A6DE99306D61A80727EA43C88F110B57B410397D
+0244B42E2D4BEA6625117342AC2CA776E5C1A466BB269D3059A145DB9ADBE730
+5AC91A2C4926808FCBEFE867237E27EE47A574B98094AF8764888C59D1EF5446
+595F1446E40D9074130CF545F2DE9DF923CFFB4917C23DC3D77B28904754B0FB
+8C021B1E461059236084CE7E206C419C9E07CDB59B044F7F8AA742E6695B7CD8
+CDE7DA67F52B51C1824E3EDB5FF78AA99A493501D2F8EC9B3F75E1A6EFDEA158
+017767694054328B798A49866ECB3D4E08A06E3664CF6EFC78F988C6EA283C55
+F222B9E7A86A3E80EED28D9E328E1D949B0910D06606906ED97876B374FA8821
+BE90FB2867839FF4A80910C1B0C807EDCACE1709575A747826C8E3BDDC94418F
+C85F8135B2B3ED17EADC9804FCF1ECA32D4B79EC5DC7E2EB1703D39E204C4FAF
+92273E26FA0DAF53AF0CE067ED27A90EE1AADFA082A8998C661C0D16425C911D
+B241AD1A8FFF59818A8F8E577DF777E1C4DF0AF2663B11A43EA674CC115C9C89
+0F3D9FF1505CFB2C75685E48BD5DA29BE3D9BD2355174B4A017AED23D13A7EAA
+FD05464E3BDDEA677D34FD3C9165CBC15BA951DC3F3509551C7384F6117A9FA7
+A21684D3B17BABD064D0B66C3A8A14B3FE01FE094174869F6C363B8578AAA31D
+1201F6F79387A334BE44A33BD591CD3FF30F1288E2C1AA408258D67FA4347900
+3700F0A6281C9A58976FF97DF4EE96EA16D8EBBEB860A6383DE06E6C11E1A371
+499D39AB917B811343ABD3CBD2E7A5C2FAC6D720DFF5918C2BBF72E0370D04E9
+39A67FB187EFA85D5C8ACF04B41A02F81374971076EB8EDFCF5DCA19C90A1C4A
+6F211134AA783813A1CB235FFDE8A9D1A9E9610E8441846F7ADAD3806018D391
+890EA4D4070DBCC6FD40FEF776607031E9D193F280F483F237CF9D70C78EA012
+7148FDD167C775333837CF050E91DC4C07F45D93BC35937B85A1425EB8AE9B10
+42299120D0F495EB245ED06F623068D5EF549B359CFA2D771A42D52D475982A2
+00130AE16BE2C4F1C291E0D61F5888F591B9BA03CDA8C12B3E3167975FD23409
+7AD9925FE79AE2358578291A599773FA9E03DE07B5C7678E8DD7869F461DCDF6
+4B11129BA01BDF8BB09BD7DC6C562FF5BDBCEF8362911E786C19767DDEAF9CE1
+06909FF38495BF1958AC640B14318A7A81EADF5BCDC0E375D4F56B2C822B783F
+FB7DB4D2C574683472AFA9776978BBD7C1D527FF8F137065D95E393C342296A2
+E8DAE79B22284496C1D1641987483B145A5B28CCCE29B28E112954822C49A4E6
+AD7E3F332F2FDB1C49B01CC744048DAA87DBCD331AE8141AA27ED85653733562
+A96AC4147AD72176A38BF0187F2F0F87A8648312973EE93417013CB5FB92BAE0
+538E9C9A66658D8C53E7EAC6E2B9726AA2E53E9969A04A3D995D0B037A7D7400
+1B7AED70FD7882048F83685B0FD886972F7099295F7C376589DC53E7A4CAC6A0
+F9610FEBE446AF268C9B2307D50C697AD002873B2474B1D8754E8D3A6F4EB68C
+C5A50C342EB34E650B65AF1560A86A8D13C7A294D4EA6F221606F1CBEB3130A8
+AC8023B11FB4CC2B891D4BE2817CE9EBE90BE53C6B9DDE56A1D0250F5A5F5F5A
+8AA1AE1CE34DFD16405D366AC4D2F2B26856A93866ECF56FCAD5564352D8D599
+8540E3B84C79E95DE31FE8145FB305A64D62DCA5CBC26F31F6BCCC9BAF15FC5D
+48902C387EFA22AB9EA363DAC984B2E0E85792A3B57D458539527AC7CCFC986C
+AD25EFDEA0EA11DEB6D03E7545F8419472C94F53D10E8F7DA56929C222D7A2ED
+C19D540B4351437748EBCE940D96FBF65508CE1FB9CC691B75859F86EE6CE762
+F569B3BDF68D14107C0FAD9EB17289F60EDB16077BBE7AA4A21A1B650DCC912B
+0A561AB119C111D6FE6A15E5AD92777E02E6A8CBD6B1B6CEBF1C42111CCDCF9E
+3F98A224A2085DE0E463C337DAB37ADE879883F6E3279D7FA28A045CF5BF004D
+450F8DCDEB66F9CAEBE317CFA0240567A85C8D0F68C534CD30C0640F1F224A3A
+CA4B7BEB6489430C56CF717E19F0D015AC73219FCE48428B914799D37F039183
+34DFD5FFB3ED7B20C2C52E6C67F56B2EB26285B64658EE798842623302849816
+D65B8A7EB3EC6CD43EF365FF32A460E11A8C85C665A6C264CC5760DCC4DAC1D8
+2EAF0B2D91D879B957D9BB333F7A8E203239F6772F33A5B9ECEB3B80DFF37AE4
+3D8B6677C8B93E235F1B8C1A962B31BA71D896D522554A098C48B697ABE47107
+C9F70A93371B7B2C4583882301CC49380F049CDEFF6D139DF7F407871891DC1B
+F33CA7F33351DB10E35ABE3D2F52BBFB4950DEC4747197E6A143D13ED7577475
+47DC30F6655348850A22751E2AEF2F0AF83753373840325C2764A2FD2BDA2D20
+610C9A544DE7CA151D94EE6B9E94A9BC21FA7A22D4BFB3E19535655E13C61F23
+12BC7E8343ABA63433F973E65564BD91D1EA604E1C749511235681291363E0E1
+1A3744889B880E921BB4F1461A53138B5913AA881FB213A5055812E970F2C9D0
+F45AEC8B7D10CB3FC10EF67E372026F85F0FCC74D234A6786FE691791D95785A
+D6D9149B1C12B4C54B1207657AF4C319BDCB896D8CA7E7FCFD957C9FD2E99E00
+621A20154534BFC3479B18526226F3E32C8B2468C61C4342E962A9CFB2DBA2D8
+6E254A83391FAECFF95FBDDF6CF52633CC4976B339B03044E45B48962CB0B8E4
+B1FB27B3D8E879DBEA6038131499830068703264369D3C0795BE4C75D3F1FBDE
+AD0B984A2450F4FE72773E93A3C4ECCC9543754421A2D7932763A971A59DE6C4
+15605C32F39167D53196688CA10A1B79EABF9970BDE0C65EB032862B6B712D32
+1141FC1852317F129ED2A294AFBE84F6600EEF1675517E0F1941BDB275D717D2
+95984D8185E98EB51352F88C51E27CE2DCE6E27CEE9E173835DE3048E049E271
+6722DA11F17496B4D7C9C841A3FEA1FA93C18FE9BA0D3E4745B23B1E57676799
+6216EE784AB6BADE26633D69E129A85BFCD412AD5C79BC09B3B6A53992CF8404
+F364CBEEA5BA2622AD77FF114D136534E88667E08C9C450555ACB48E00D79A7A
+3211FAB010FC97BF13B76F6EA93D5C3027C43803C945D324EA4C8046DC7BB412
+66830990F696FC6A259AA0BC7BD7DA7A823F465896D84A4C6010F952176ABE59
+EB11D1903554A5AA0DE05D565FDE5CAF8EDB4B2B91CB3FAA067B643DDD911D38
+B7C315B1FEED6C92D62314DA2949FEDA8E9EE5B876FEF967B08B73C6A572E9D3
+41291C56F67FE6496450D430BD2DEFD9EF170F55D217B9D56F5F8B4BBED8E169
+0DCA5E74811AECCC56B4D10DDB7FB6F767DFCCEA14C870C658E45555CD3FCC01
+72251877DD9591482052029AEF229D1BA56796DE0054669812E432B67133C7FC
+A90202FDA4BA088D328A74ED015A69D74462A70D42F323258E7A7074B8840291
+CFEA84BF9D04FEB8E4B26AB24AC2987758FB16B1ABEFBF80A3C4FC84E2EB3B06
+62063C6D7BB95F586FECBA5C37B569592292B3275CCF0F2CAAEB6E9816D59DB1
+D01B52C5E5161466F588F48C4C80FFE64DD37D25DA9DC7619B42EAE46D79F0A8
+F4F1407CF9A20E3FE512E8B1A3F6E4CE22061879D8C06C2A2D5B4B3DF64541B8
+76502D67BC97C8163803FA5A289F0D08C4A851D6DC7411D74D0018B006CF8874
+820FE0CDDB265D98A4A2572AFAC5F5E8E55EA4E12D0665BD913065C76BFE23C4
+FC2ADF554860A86D261343C61E565D490451A28FF8C1A87B2F29CA7170F50B24
+6AB64C1A92AF1492758F7D886164465F631CCB40DC5FE219BD5F2602738A53AE
+617D3D340068D6F321ADDAFA9878C34E694FAC50CAC482EC8DCD51E349D6A4A4
+95431E6B0CEF3713B077B8A3658B065D47FD0B5D4F373310439062EA7E9AECC2
+E45A81F689FCFF5DB5691C788B31A91AE8C0CE4AC156259F8BFEA5F33F8CE279
+2350EFB1019719918943AE73B3EB5E6269249BDDE6452DE586846431276FCAD2
+18AD3F997487AE49DCA5BDB0FE2E727DC6CC5E8CFC9F15F7C1786F756D0EAB8E
+55A86F1AB33C49B78896411A4D0BD12C6FA313BACC67CD439BF793F925F1E9B0
+7AE22A27A9D30C0AEF7861D7A582BFABC80BF09874A503C0131D5FC11D8D76CD
+A4498FDA32481119BE4A2EEAA32B761B01487FFD6E6C5D0E509E2D3EAD010547
+C4B3638E3D9758277D723E578E3D6C55767140B51625B15DCB777D4C4CCF1242
+0991F469B1E77702357D869F9F7795038DB847B75404FF926BDEA1EDC79161DB
+73E2536171A4353B3A9E2561E86BE6E550EABAB6F33FCA446F7E17C872C42CD3
+2F42F87AAB93967C7880725AC5D2C0850E7EF5B42B630C282B402B53A3B79ABB
+23F08A7DC6795D4CA8FE32FF2F9488957B760C76DB186C66ADBFAE35E5C70AD0
+99F782489D6E7F93C2B6C767A45CA027241F807E2AED0113C044FCDA46E26A35
+2790E581A790FE029FC6D31B6B7D433ED7C9F19283A6877971F366CB8668B39D
+9828FB01583130D6B902A84F95F5112BDBE942D2E22E24F5411823007C91262E
+4360175A1BD287644AD561F2329F00DD9A880D78A9EECB6671260B1013697784
+1BB657091BFDC33C23C4DA4B3C999B79F1508AD2E5D7CC42674876E6379E9EF3
+DB6644EF9938030A71C9112939F1F6FD64A0DEBCED031C47639B312E07BAC035
+FC0A1473FD603DCBD6B0A30D55B4A0B8C227BFA2161B8F5A4A67F85EF9C3C252
+8A952FF5E67F1C08025336286760DDFB27C26712BAEFE7315C5BC28CAF6C83CE
+C680BD16BD24A8002AF1D94FF2BC357E5939548C3992D8FA16AAAB91E958C7C8
+6CF72CECCB79A2C25C9A1F37C6FE483C6696DD04946BA3DD5E48C13F7C6A617B
+EE4DDA62CCDEE2E7E1C2C25C2634BAB2B0FCC880FD712F9185E0D1CAD17B72CC
+B4B98FE56B5F5D04D88F7E75D5B08A0C718084578EF795C95EF630DF4E46E835
+1E4E15B3DEE439D59657F41AA91AFB18283BDB32A2AF768B423607C7FAA136D0
+B59CDC3302D03D538919E62DB87F0CF91137640930582C2A719F3E5247537D96
+8A4B85B3D6E2B0C351684343F91B7BE2AC23B8C3EDA629BA0863508DE700224C
+B240785E2A0382DE3095C121A964AC0FD0D1914F4F407E4CA49E0D828638737F
+0EAA047B30772151CD5E8E854B301FF74F7889CD63E777464848092DEE68D201
+751B5C00C34FFE9D0DA1598C8C82AC303DA3F0A3F03DE5299867FF4F0DFD814B
+E2E8D9D73F3263BBDB71C2FC70B922FF76CF1FEC6E45BFB29FD78985DDB7210E
+D95D718B71350EFC458AEB3445B9EB275AC27F7CE1AA3959E908FEDAF925BBD6
+9AD9944498796827AC19723CB2F9505BAF9E9059D5DB33B48ED1AEC06CC59C90
+49405A1A616D76697B6D735E70BCBA2E21D41806C05E509C9CB3152176C582B7
+5DD287EEC612EF10595AE0A3E0885E93EBFD2FA36EF1C3D5E7569FCD04469BF9
+6A6B69B8A32910589FCD881FB8B160FB3A25EBA374A1CAFB753AD9E691762879
+60F955940D14D9ED9AD80A461DDB3311684EF8C67C225BB086A4D4E050055632
+0F5A8A7BEC1CB03A7289EC10D5D560B34FF9CAAD74464E5564DA857A38686799
+CBFAA21A2875B8FC2DB1527A4231051E27A6E1214A8E268E0921001F1B2E3624
+EF89B762B0974DF72B82D05E0270A468DA500A6A65FCB33679F39B58295B2946
+3C666F56E4766B91E98C4C2BCD5E4ADC3245302DFA42F467064CC14D9307721A
+9F019D0CD95743391CF061BC8503646D0218ABBB8444F1CD64CFF539F492D70F
+D52881E1DC23DC27A4352A05A21698E7E7360E4D693E3F915A52E12AAE5B9701
+01C37921836E23A7BE82CB2CBBC6D3ABC1080AE491FED1B83381FFFC481CA499
+7C3FA60297A370030BFA4C9355EA34EC0BBFD7FCDCD7ED12614AD25EF0EFCA58
+9DFE1A22208EA44008037E6F39E31CEC582E7A6AFC0F5D721B5665A867787BD3
+C93F0305035E9CF0401073BF3AD6C7BFB3C34FE851B31039E7FC010E69538BDE
+B729B3AD48A092803E8A1DFEDE47429E2D0624433464233B7924C64155258D7B
+6F52979D4DAFECDD3ECFDD99391D9DCA0E27BF42AE30C128BF9BA00E738AB0D8
+B63F5EB58109A1908ADA9505354AAD5DB4FFB6E66E2396D709EA9B469DAAD0BF
+CFF5FA6D9106D3832DB053A80546FA12096A56E3D417E6B71CE9B735DD423440
+1F35A7CD8D600C39D8C487308E233A09DB002D8CDD7685B2942C08CAA32E828A
+0CCC26A469FB0F9AF5A187AB362BFB221D7AB1C02FE76622E854734BE3A3F06A
+908A8DA413FF2964A54023C5A42F3FA5087CAA0CEAD9EA56C554E253B8406506
+E0439419BAE126FEF24B53EF3909675F0DCCA0CA0E5CA729562BE6C5911DA1E0
+6EB794D6C481CF832D3B9F2834D71524D4E07653927D574910AEEB7F5EECE7A1
+97F620E16AE7815387981AE655D39B3CE1065D821A67ACA7140DC822DBCD05F9
+B2F0B46F51023AB8BD4EB27F4689B1E19020458B43E2055D8C98F54BA4E9F98E
+8EF85AE7B4A331FA105D83B994A6FFF39B4DFD0E1AB42DCAFBC8E0A1005794FA
+C0FB96D7A0FB7776FD8118959828AE3A83F10DD22E1E06E6D4CDC7E30FAEBC0C
+4931E086F82691C6BC7F7D1847D0E03E970F9BBCD54D310DDF871F08C1769E5E
+C9DBC69B052EA74D7D00E913F507D2844D272C6808FA8F6382AD715AEEEE9697
+4307E98EAF995703B0D742860D4E3AC83D819BB41B2B28EF33917752D4F1041B
+F324D34711266D23EAFF29B94D82FF3AF2CC56B44BCED2DDDC4555F76A636925
+BBBC41D4EF2D86E64F1CDAE09A3C6356BA44F9261593B910FB6DE62A1E7C8B28
+CDD2B13826EB0C8FD517C2329B798A0AEF6E50A9EF9B1300C72763393C29607E
+5DDBBEDBCD3F476F8C06F0635AE76EA2350FD13CC6FB88C6A740AA15921BAD25
+A51F131EDD66B44FA75C006B53750F8048A7E182DAAE9646E7DD255AA0B07EE5
+9EF43252D90A1B0147089B3BA70795B66677AC47B450FFDAFCF7AB336CE7D21B
+A8D974FAF7C51782E58B4808B9552CC860C2458C31A89AB0C044BAB9E7E9C4AD
+633564BADECD43D726A5D50B85E7517DF9D178C826E6DFA6CA87FC24FB73322C
+D8C5B93858C70106EB22FA222192F9A40D4E5764FD0ACBE061AE6DE98466E075
+59FDF50230FE2CD9244B790C6AEE91DB06E920E841ED19CC4C7578A020F3B45C
+7033D4B8702FB7F5B33537D0D7FAD0FA83E4E6B6529473FE0FA6A400E60CE8EA
+8F33A7E3EC1F514416BCDBF691B601535F8FC9A1A23D87BD8AA57B77977F3E03
+318BBEA25A18A03565C10BF63D717E0A74E5F2EAE84B8F18DDF94568E2E11981
+F6EF4E9B8D3926DE626B52ACBF592019C8FD7ADD8A1795BB8E3C083184C1DCAA
+20DFB99DECAEA3061A2CB5295F2853EB847E92C151B10E7A81C0B259A99E8213
+EADEDF6EBBF0B6E111ECF74F02F3813CDCD54E17712D7894AD0577C4F83217FF
+1B3122CC2E604ECB83B1B5ABE8E459CE82AE12B0121F2864E88040A9D5AF43D3
+83B3267ED7B15EB98F9C598F5B8C8A1AB5D4E032422D6649A16D58611E4DED34
+AFDD1E6A6C1F550E475C4F4253718D0E1DACD6B70C810EDF014748994507466A
+5CDBD400EDC359A785A9631BCF52E1E4BA548B16E428AA72AB9CB0B563D64030
+7305EED369FF7E50A9895D3D6773CF060D3E5E96218FBD4236F421D1C53ECE3B
+4368EA6A0133EE3CDD14BFBE197C63BD40D63444896D9123B7D3ECA97EAB4057
+8A42C650F42F36AE5F070A597B22E08A000ED1033971409FB208D37D752E11BC
+0BCF4AC813841BEEB10B6B1B0C4AAD1B77F5BCC3C79F7034068EC515D4564FC7
+543F7147CA931FD616AA488588B018B749539403F6B85C54FB119AAC6FDB25F5
+B688F527835629ADDF033206250928BD9D6EAACC910DF2180E984E0D061E0476
+BD938B9EEA1BC998483B6085D31271EB2D3C4139077AE441A3B8BC71D8F1573A
+1246FD9337625B1FE7B21F2607EC6D645FA849CFD8A1324574E378830E9D73C7
+ED7CBEC9495F79B6F164F85B18F461C2EF884D1E5B88ECC8F5D6521B2226FD8B
+A6E6CAAC690F718411443D9FC809990194AD7EB403A60C249946AB325D308577
+FB44170C00DA1BB50AC81DD8832633ABC744FFD38A278D23628DCBBF27E49325
+E2C3B6DDAD2ADA47EB43D28E47B0FA599495C6B80421FAF6B78D616FB8D5B9B2
+020EFAC63258AF512CB096CB4392186E04FEFF1C6B079140C4ECCE189B5EE0BB
+A164DCF05ED513993DEA7D0C98E7BF1D096D6F2DD24062B115448DC5DB99A43C
+6C8BD7F0B0B6A4E74155A55C175D5B1F6487A6995D819193360093BA7D14759E
+C2C84C0AE206801D30B1458E790E03BC101393D25E970DEDAA0C46A86DFA3467
+8E108DEE0F5A6F310A007C46C21AF25FCAA518F3185C4E2D287A3563D6AB8CB6
+F2CDF16F6A181ABA846328F99B07304A4075A319677BA3951E20FEFED5B7FEBD
+F390D497F1B0812E82C8CF8A82213073A481B008E1BACEC8798F0CF70B1FB0AB
+5054E5F37A170FCB6AF8ABA57A9405373A5E4E6DA9B641103761E6181A973000
+076065C4ED09215E283F4790882339DDA0713BC6DA083F0E4B84583B41BF24FB
+60D13BE5781055CB0457F02C2CBD9423417E02A8A6FAB22E47F5FFBABF13A83F
+3780EA93870CDC27113981AE6270E2A6832E02EC944CC60A1F809782F2AEC673
+DF1008E1F68A4069A8EC74AEC41B16317ACC24D5DFC302A401082F8EBA5DF55E
+83DCEEC6612CBB036017F8266C27EDF97C6DBC878C0BE6FD1A5BC1104A99E6F9
+524D3E294FF96FAFF42B8DF375759A952EC7A3B0B1A948D436A48D0B96F7FE0C
+1C1C15A5746795EBBF68EEE86824F23005D4C04723C7D350D17CED07D3A43666
+713BE7A8F6CB4460BA3699B0C036D7938C8F8E15BE6B86503C8E6D42563EEF5D
+BB511948D04C331EE257C6FD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTI10
+%!PS-AdobeFont-1.1: CMTI10 1.00B
+%%CreationDate: 1992 Feb 19 19:56:16
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMTI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 104 /h put
+dup 105 /i put
+dup 116 /t put
+dup 119 /w put
+readonly def
+/FontBBox{-163 -250 1146 969}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E3948FFB0B4E70F212EC976D65099D84E0D37A7A771C3101D6AD26A0513378F
+21EC3643079EECE0C9AB54B4772E5DCA82D0D4ACC7F42FB493AA04A3BF4A1BD6
+06ECE186315DBE9CFDCB1A0303E8D3E83027CD3AFA8F0BD466A8E8CA0E7164CF
+55B332FAD43482748DD4A1CB3F40CB1F5E67192B8216A0D8FE30F9F05BF016F5
+B5CC130A4B0796EE065495422FBA55BEE9BFD99D04464D987AC4D237C208FA86
+0B112E55CE7B3782A34BC22E3DE31755D9AFF19E490C8E43B85E17ECE87FA8B9
+1485831624D24F37C39BF9972D74E6EC4784727AC00B9C4A3AD3DA1C22BD6961
+7E0ADAF55422F22ACA5E4DCD4DF9FCD187A566B7FB661D0530454D0DD6C6C50A
+7A3875C6CBF8EC7769F32A1F3F7FC1C072BADEC97794D4E90E0035282A170402
+356E5A9CD9ABD80AC4342A5283E458A7269252F4541CBB6452B39ED54D336D0B
+19928E9CD1AB26AD83EB209E2EC75011A2643813053B5DBB0246097C4821B5F2
+C92554E9140BE35B2DBFCD98809A8EC9FC910FDE9E0D86457C70ACB056EBF90F
+244DC0A5BBD455E15D6E3180311D52CF50B0BF7D0A7F64F3A1821E0AEDBC2E7B
+AEB549FE1D51088C153799C6E089B5D5D65E1C4E2D2B430CDF1FFA23CCB25D95
+5C43C8942435D0AAA3D9055FF808F2C3C887A3C469BBD98F026D0A59E26BA9F9
+C2144CFE49A9AD892D4D31764F0AE3A10644AE3966B0A790684B14D11FA49785
+EC5565D2B2E584CBFD85125F3FAC133338DE35361943DCE9AF05FCF2840CE512
+998D42CBEC52B57B79DD63F00985881E8463396ADA47189A94DDF951A78866F0
+B8A3D9197E39335277EF2294308DA70065D910943A34F7D5F2090FB4AA42ED70
+CBA469A9F64B95A6FBA4BC89DBC93765E3AE4723162DF3F9D6BDE77DD5870ADE
+C8900D6346957B84C3CE88A8F9A12D46B8FCA50DF4433B0B8AED6A63B3DA102B
+6DF94E62408E24154BAAC66B2B249C695BC0FA37A28699D9C0F3EE94AA32E3C5
+8F8D7F803B5D25014D43A353D719B14B247A87898A960DF68C0C0BAF70C83917
+6E9F7B3ACC64DBAEF3FDCD3A80C0AB907EE342E543D607556CBE5A9089B86D1D
+E768F27D74A613F3ABF883222A8596B542EBF54E9DCE327B5682AEE5F1A7A225
+BF26E2AEA0F352B9C950B47ADF650E1B2AE31E883EDD884EC90F94761C470EB1
+72F27B74049C2A13EC522271032939B656020D617F4E58DCA88D138F4C84979D
+5EE89221BFD28AE8117B6D0B27B85C3D231F0E4F778A94B3CD76B89BA43A7D67
+455C912EF1FD77E7D783E929017C9A3E84EECC325A7EF33325648ABCDA4E8FF3
+583710F87461345CFAF37FD04F5BA8120649446616C39520FC00B90DDE889A69
+AC68F7239B18D798ACAD2D120DD239E94DA568ED454646FC6C69AACE5F29B2DB
+F15066801DFDA08A95596A759FD97B542B87FA0E900C44CF8C083AB0C30D62C0
+FFD775EE51FFF804E1A7FF418167C78C6F7670A9DD874DA83393AFD4B59EA4A1
+B1FEF920692056E62DB0AFF082F204DA69574D6C88D66E5835615FC1D2B9A1B6
+AD0A9F69CCC328D1793580E042610B429B57DA484059ECE7F092218874C94353
+1680A18A4B6684BDB98F3B6374F0D4029E6A43D93800B218122859323DA6AFD7
+D8B4786B2AED55C2A44B7F6631B57134CB61C3FA4431CFC85262AC2BE703D140
+28425BE79D31FAC12C02615875039FE286FB15567582310605447EB96F8572B7
+F6C38DCB76C13BA9D78102EC362019EE4E93E59209A8241190882BD50690A462
+11CBE283C95D9AC939EA9E263908839C86F88F12DC1C52FDAC5A9646F030D4FB
+1FFB1B74462736F23B0D5F1CD19DE2ACE96DE633EEAEE963B5729E4CA2539145
+B0EBACD62637766427FC677F70FA6B7B17FA43AE5853241252095C1FE2744303
+ADF31251A021D16F538C78BDBB0FD8B12493FC5C31A8D7BDB89A4E31B0EA5CCB
+54FADA7CB40CD289F60A3521B8EFC893BFA9CE8FE901A482C133A6BD402454D1
+99B1E3C26EE821940CF2D29DF16E0CE3199E4E3424C04FF7C14CE71298F9E005
+E1AB3C143D34351AEE0240A1E88D948A2A4E9DADBE1D2A481BC0213E4A912DDD
+C9F64B164F212454E119E22327CEA1E91CDDC2B39B5BEB8C9A307A7E56731A35
+EA9D40FE11C8B801F6C360067CD3047EF7EB32DFF67AE6711BDD02D2EC6F4F9C
+F03D30CC7846E86972D765B5280DA3735C60451DE7E175F75E3CB9994388B3BF
+AB1A43D120DEB396BFC5197892F47E1F10B0BAB73EC8B31241A6FA5F5FCA8A11
+3ABBD2BF7461784BD905248CD44C5609563E2BD32DC72ED281B948709799C7E9
+3FD79DC6753E1CC699DFF4DE78286740041428E22B9E93BE3AB53228AC65234C
+9C54F145A3B9BBFF10F458C65CD94263CAD1E106683B3778976EA276BBCF08DE
+1D43D24202126E8BD82C7D120561287505AC3884A96D11338E9F23FD14C82500
+63D669A02B9D5EF5030DCF394AE96818FC75640666EDF63AA36B3DDCAF476831
+B18A9833EAD02A6CB257B05ED9305E914A2BC170329169171363B2CC2066F51C
+B97ED3D8DA9234558CDC2E6F45169AF4F495CA9BC7A6993E6155F992801A4586
+8370741EBD58151EB7A069DE880DD3AB69963F37B221FFA02F5724F342344600
+0881B71027939554AB3A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR10
+%!PS-AdobeFont-1.1: CMR10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:52
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 11 /ff put
+dup 12 /fi put
+dup 13 /fl put
+dup 14 /ffi put
+dup 33 /exclam put
+dup 34 /quotedblright put
+dup 35 /numbersign put
+dup 37 /percent put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 61 /equal put
+dup 63 /question put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 74 /J put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 89 /Y put
+dup 91 /bracketleft put
+dup 92 /quotedblleft put
+dup 93 /bracketright put
+dup 96 /quoteleft put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+dup 123 /endash put
+dup 124 /emdash put
+readonly def
+/FontBBox{-251 -250 1009 969}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C
+295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75
+409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C
+4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF
+2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E
+0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E
+B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008
+24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B
+43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF
+D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575
+5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC
+96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3
+7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC3BEFD8D9C400015B65
+0F2F536D035626B1FF0A69D732C7A1836D635C30C06BED4327737029E5BA5830
+B9E88A4024C3326AD2F34F47B54739B48825AD6699F7D117EA4C4AEC4440BF6D
+AA0099DEFD326235965C63647921828BF269ECC87A2B1C8CAD6C78B6E561B007
+97BE2BC7CA32B4534075F6491BE959D1F635463E71679E527F4F456F774B2AF8
+FEF3D8C63B2F8B99FE0F73BA44B3CF15A613471EA3C7A1CD783D3EB41F4ACEE5
+20759B6A4C4466E2D80EF7C7866BAD06E5DF0434D2C607FC82C9EBD4D8902EE4
+0A7617C3AEACCB7CCE00319D0677AA6DB7E0250B51908F966977BD8C8D07FDBD
+F4D058444E7D7D91788DEA997CBE0545902E67194B7BA3CD0BF454FCA60B9A20
+3E6BB526D2D5B5321EE18DD2A0B15E53BCB8E3E01067B30ED2DD2CB9B06D3122
+A737435305D42DE9C6B614926BFD44DF10D14402EBEDFF0B144B1C9BD22D7379
+5262FEEAFE31C8A721C2D46AA00C10681BA9970D09F1EA4FA1566B96E221864A
+45A24ADAEC63F61C9FD18376D39E0FDDE3FB4FBCDD6A7B66068A99D31CF54CD7
+DF2262DA91CCC72889CAA62B1D6F2155CC8E940A2C35D8CD3EC75326188E2D30
+1090F31AB50F30AC77D2C445BAF7323389406C44641B3A72C26BCDA442504D03
+6C22A3BA1A69E5F87EA400501A3B3231E46F96AC3A6C0E4A4F6F21E0B2BEEF53
+E016F34D7003351FD12436520926C632218410359AF9FF167750D3CE0DAC3B91
+B310C457402E05C316F400246C8C38B98CC8030F71104BC4FA0505B5EFA4F5C5
+9E4FA27C3E790D698690336254D7E34451E692AE23BF5FFBACBDF33E25359BD2
+B0E7A0686602568BC87422F32486CB50776C7EAAE7F1BF78B228CA3254510653
+3D6368A4985C5FF5A48AEF16E1AB71D7CE2C6649F2CF4B2879D4FA042239B504
+F988D2FBE87C3BC784E55B8EE36F1BB5EF14FD5836CA448E139EF8FE221E827D
+0608A6B90E08CBF44A30669AF4E20CD5C0C8051E5F86062204AF362DA690B74C
+B952C9F4799FB2535E47AC019175950A1F3A0D0937016148222B545B1E00A91B
+39D2121462F51F736802C523BCFBA894EC11C3353F9BCDF0892C00EB583A4D62
+247118996064991B816F9F490FA73861FA614FEC7FC23A5D45310527B6559781
+F1C805F0EC931D0C60E70FD5AC55F22E6379D369303F63A0E7069237118DA0A6
+5BB55FC6EA1797BC51C1D053401ACD4E9B5E724F4AEB149C38DB0E2BFEE811A9
+A94A7405422CDC911CDD97EC4976E27F766A9E3F84387C04C6367509157E4D91
+09A1F6DDB59AB9096FC43A6F9773ED9CE3DA6B56D10AEF99FD277F8666E72028
+807AEC6C26E5A142496CD41A80EC051E875DF9F547BEF060B969B197AF97608B
+F7A3740B3153621A680DAEAB0454706C65581255CA9B40078FA6D352737F0165
+D834359ABCFDF5C212F8AE9FD50BEE9683E7D5969D183C058E8BDA78F61B61AC
+98746B3A1750093A40C17EBD4AEF36BB2DFA1C9AC2A12834DE4623CCC76BF5A7
+92B2B2E368D1DF3471D83495B19154836569D2A30F9CB05C0EC499EA5D3184CD
+BAE8D2A2CF80C6359275B3894B4DAD7F92501BA9A6BD215256CF9F35C2BDD40A
+D1D949000633FF0B5FC7674BBED71294AD28FF25710E968E85C3FE71046BF0C1
+71EF48F8024C28959FBE6E896BD1AFE579764616672C724959FD66C8398ABB5D
+6C02C5619866453708E3FDCAC2754E9C333C1123A5F746DC5B2CA9D430263645
+A88C743EBEF8C82DA0236FB73D3DCDFF874A1A5928406838A81E40F34816EBEA
+0D7A89406A6F492E5E5E6C8C4D85A2B9A83B6A4304B05AB541041AE014C845B4
+283CE3F75DA22CB7CD78C67A1F067C79B209BDBA6705D80FBF08CD0FEB9D3293
+D9955BF6730BD59495A1F81B708292B509537089D8AC34A06DAE5E8BBB9B0A0D
+F09BA6723DEA964F06C0E1A6541656470E251F5AFC6677043DE7C6D85B60D3EB
+B8A4415DBFDE3F29D5FAA0B5CE4BE9559595265FA8BC24A172FBAF9B1AD0A4E1
+1CADABC2B71A43098146DBFDF7E126069259EB490CAAB07D5C9D91509467A406
+65E0505B23A1430CBCC2E5E244055C5B56FEEB94966664BE5FAC0E04A79F3B08
+5BC1F176E47DE7423E28A0CE9A6DF201D41218964C6F19219974EF442405AD85
+D9F1B07265CE8F273AFA073D7947C61D80622FCB3E11F65D1DD988383CA47A0F
+9359EA83AA14CECEF920E7CB4BC234EF65D10FE6AE6FA8FC2BFFBDD27CB3E38A
+0CFAAD18767AC15699BB371018D319C906311F339B43BEC20508008E87F82514
+796BF53820643D82BD07863F605321A34984FC534C6785E18E25C7A679FA8800
+2A48BB5FD5C73709EDBE0C1F44D50F5F44EACB2FBA0864630A622B82FAC9BEFD
+67EC2788898BB04B90D46C5D66514D32DC50EA7856BE6382C5C2A9D31C4E557B
+6894710EB42ACEF6CC2A5FDBBD902C0F705858ECF03DCF2E86803BFB023AF869
+1C0E5CC876EFCFB153A61B750D1CCF9A3B181ECC6089CC41897A1519A9804332
+E00577F56C74F2B24FF6568EB630030384DB1546ED1320AED3846BB1C7EA0885
+6BED1B2C999CE879FEBF373A3BF0840A747E133CB59135EE98E5015789975AB5
+AD653130C1E9A736A0D76DE583082C3A1DDA115A0D6B5497E47C25C154A68EBE
+79E4037DA6DFEA184D341ECEE3F8DFC060A6C440E63493E03715C0B1A730B7F5
+4663E05079BD40487D679271A395163C67CB563272F984C79945AA4FFBAEB0A3
+9C226A28EB1546BA06872700807C8E0644080A99A6E19EF70B821853BC90105F
+753306A59290EFD89CF4E4083D31FB4F5269F4FCE30D8579C18D287E16DAD1C1
+4FBFD19D8E126EA637CB57BA5553727E5D596FF53F3C7C8D1929B658736DB0A2
+7C2F5C8B1DA45F7677BB3B9941FA00652597BD2F1B3E5FE83545DC1826E2777D
+78674F3AF408AD5E4A033428509230EAD687D4B200870EA7C877A0B5E06D5FBF
+84F5A4F99080B80E742D6009E7ADA9A8D15A86CA008A74DF4F21204CE1CD02A4
+822D3CAA248E61383E76CFD1A6F9EF8E7DAD05E7266E1234388E70E88D2125F0
+4EFF25C1BDDDDA09719F9EDE96E9EE7351EA08EB38916C8415FEFDCA9746FE1E
+9801EC761BA4CB75BC958ACA6895EC4E29EB4AE4A8A24F41FB13DEB2578DB919
+3EF0FABD55DEB31C6D91D294A76C8EF7C6BC32BA995CF89C9E05B506D3930C1A
+8DD2893A479B40DA30EFB2675B445D4A135FAADA3A2DDB5D4905F756700F330E
+C7A614A9209E1A88EEECCE3637DB10A3088E0A3027472B0A1FB013C764ED97E4
+314E7DD846AA69CC2FFA8B15FBFC9E84D835EF2AF874065C1462C06FA70EA8C3
+B65664F33F7E6D1EFD7B8D2DDAAB9CAE17D9EA9C0B89A4ABA6598E7F27680752
+16B924AECF733026CB337DFEDAFDF9CBB48F96AFB48097DD76CCED10CFC353C5
+B0B1C0783D32DE11E591E94B898941E3BBF77E0E904285709D6575EC24132FAE
+8D34307EA87E41ACB89D51A173F80D99D504F66DB3A6D4582C19AF4B8FCDA813
+E77164A3FFB380A9F885A8DCA3FF7A54AE52A75531FC48FAE79D97084EA9AC44
+86AE85B5E72D6B849741A223DD361FF97EB767292EAF09571D46E821192187ED
+D76CD0244D1AFBD6C4D1E75C5AD39C3ED9CC7439F17C5AEE75F4C134FF5093DA
+63744E2383BDAD5E8AC835E228C05EC56B28B4DD8B9D7486DCF63F331E7429E7
+AD97CC6AD4020D1E3B63DF2D108BA654CEF955D689977C418ABA0023DD2D3208
+EACC856D4D02E092683ABFD4291F0D82D65E53831D62EE672A1504B847D149DE
+4D640CB48362B7E40E0C4F3189B8BBD0DF751D7FF3452B5ACE0FF3A7E8EE863E
+84ECA8A6E1949077580F57F65A30388B9A346F1117D1ADBDBC9E968F0818DC80
+130F4DD0BE6973AF825075A56869107083A39B710023F5BDAA9FBEB2B8FE29E6
+62FE5513960812255BE6A9262630347CF84F9EA6B359721C132061D13986B84E
+281E100C094E61D8E0243A7D9C2E2D8D63617849B57D84FD8A2C12A94EE12F9C
+48B0B7F668B3C52121F16714A9666CCFFA5E153AA9B5CED56BA8D73C31121A87
+271A118EE499A6DB2F0073263561A3B7FE2DD3C8D9ED17E9E628F2A9459D30F3
+15CCF81B5B9A561BC0E0AF7FD57BA8EB78FA7D576A70A86155A1A65B7E3F2D7E
+E7C0C5C1261E443D569132BA2D65DBDB022E17D4104F37C7BD3B8FBE7049555E
+6C70532AC97F9FDA7A1B65CD4A16100E069FC80F76053B4ABEDAC49D1368F3C9
+579CFAB25694A1BB60F60C50FD371A817206E0B3FA5B61056E181D43AD10C1D6
+24C1294FB6236A78DAA3FD8D097C6F8378A7DC0527D3DC78BC347F6C2F7FA8FE
+78D50921554331A22360DA1610FCD13C42A13AA76AA70CD4BAE69841F64582C4
+FA90EA1092E5F0FF1EDADE93187CF60CFF8F03C4FB4E3FACC02A67FAE5354980
+3C78208AE32FEE982065BD108EE9AADDEE14E23BD1EB46CE8976EC9058C1E789
+6CA12102DB21456CA3BABF4B37F286D1A16378AE27A35F84B1B41E9E98A94304
+411B846DBF3664487D2B329DE138395DEC4D077CDD316074E8AA028EA0F51991
+3570284806F2731A4A8F3A07CEBD51BC468E43E707D85539D9B134E792D7B5FF
+3F0113023D19AD861FCCDDE2BA6360350AEF5E4049C0AA3E97B59D1977C71A6E
+9E6EA1292EDAFD8BB296374A7F315C84EEA7346E0B2F9FE56092546B0B54B71F
+9B5A8144822E994B2C8039D384410C665D906B55CB3AEBF9DCA73A9DC2591615
+4A1367972F49F8E4A89A5338F1EC2D30362B48D0AAEC70886FABE2EA76087B26
+68D5B9127F99A50A708A6420C418A6649CD81D1232BCFC1CDCD9B85D92A09749
+E95C751AD73CA7C333E24041A8F5E9B2C4E6D5144876782367660556C6E520E6
+A8F6B67C27E070015CE391FE45E177383D95B09A58E9C5969335E04C2B928939
+D90F04C4DF42C434A2D1DEDF5268AE10A887001F262A7DD2B88F19DEB0E02E36
+C5FAE8C47894BA15937CF8F4F8A5E5584971280542DC076AAB7893506D43E373
+749A1FC22740B87C3BB3F3D864545A3C3ABF9BC1BB8F476D2B6018657DEF7318
+76BD4F6E1ED977F5952EE7E4E814966219F8E7B364CC1CAD04925404B12DA73B
+38BBB7DE8C884AD8DE1B6F43A7616D64ED34C638CDD9133DE3F646CE274D38D7
+1935A8BC89FD23880980280ED6A7FB3E615A107BABC5476F1D4A8D1C6B9A2916
+AD8F54F580E5A17BBBF426959C9CC30E64CD8FB8693667B20103C06454DFC54B
+CA17EB821066EC85EE6B7196E4CF408846410D1F8719ECCF10D69650B202702D
+CC655110E020B6CC08AA1DF6C28998455F7012201B19729FF6E3D9AE06879EFB
+8DDBCD950EC394A20036847C4784700A3B8A1A5A75EF64F632EFBFFB9E4A12D4
+860B1FCAD170893F5B946A35F0043C18374F65AA102000C02FD9F42B3F2A3979
+4A2E3BE6EA79D933F61150C79C17A8DB7B1F45A755D93CF736DA0FF951EEB4B5
+4D2E6433B4A276697FF9CFC13395C0322B3137D147D5D202041323DAB6E06311
+4ACBA55FE6185C3D9D3E3E751DF0C23C1E2E345F60FBB2E444B1634614629C00
+9A37914D59F478723BC2C1D3AC58AFE0DF9765526DAF381F1B2E1A55E7F9455B
+6F882B4A95902C3C9599C73A58081BA4B1E34439244EF99B0D3BB3E118842665
+602FB696BBCD429BB8776EA55D881E4E484585FF6E91F40F34EF131831DB6D4B
+909D30489E9CE31CB18DF75C090387C6624CBF071E3DA245625D0F20EA0401F2
+197F5E2C9CBEAF43926B46408DD589CEE28C23A29AD7562FF49A253920B6BB68
+E40A07B2886F1BB73733D556B2FFC8D96F90BF35C8E4E4E899E034D3B2CB6ED8
+F19872874B4CA8AF7DEC4BC76E05E85DA921B926A27E259F0775856306B5567A
+ED1DC9E3A1C4C698B91684A136D4F054A3DA473762BF518B96317D008789C76C
+35974CE7DB35C6D6CF85F9DF4A4BC5015AE23FD90AA0F184B0D4AFD251A7EF2A
+24AACCDB64F10B94DF51B192BF00CC2C064A5C2B358BDF5F63F0B6F0704FE01C
+C9E1CB60670D3606DD5A7E1D5CEF1375BD5179ADF6F7DE31BCEA1E282B83E171
+BF56772121B031469C0594CB0112CB21217AD9C1478C1948253F71CA14F19F34
+887C51203620198302D62A7BE61831091A59D5C75D072F81CE959D23064CCEF2
+123C6109414D423271CA4502ADC71206D2EBDE97C70EBF80881EFF3969379498
+5EE65BFDA09BA68BD6CAA01DC2FAF44D56A1401578CF2937352198EB90943208
+F4844D787DA13E44099CF4CA131F531E52E1E1649CA7FA44F5E9B7D9E04AA62B
+BDE0BABC0C08962568272A6D172C40DAF39858DD0B32C859AA6DC0005607903D
+D42606BD0DB53C96D953F4F8402BC0B35B5D7DBA5BFF2C723D49EB25A2EB1BA5
+953A0FDBD15F9AE23DC187C122B5E8D157FD00FF0C8B57132F1EF7E4B85E911D
+48CA25534C9B820F3A5DCBCFE693CB50B5C1EAD7758AFFAFBA852C9324F9D466
+3A666788F77D3683C3E8331DF1D0253330C85E9001A4054FDDA00E847DC77381
+90FD0AD1E8679F21735AE36E53A103586E9BA574CC07D95BBE5A99816AD03B02
+D5543DC1CDF3BDA26A55B41EABE7234520E71257973E55CB9C4224D26A7742D1
+B4A825EE1DCFB9AA7BFA02E18B09D51EFAE85BB52581F5287CFE0EDE78A69A5B
+BC5DC290937B0E5AD33FA73E9166607500086279A6EB791CD2DA1DAAE138C42A
+255D1A729AB9D2CCE1F6B632D3A8AF29DDD0F14B9A203E2F0EC6DB05E1B8E553
+B39ACF5E4F5F0F261490266A64A0570A9647827B95A1BF919AB220A23BF4C35B
+7B17A96FBB6F90B69BB8A041B93BE96DB5B76D716CC269EB5F7341DC8164737B
+208245EE6201F58F1FC68B59198DBD466F6755BB1DDB0693167CE232A3EBB5D8
+05DB42B769321138FF5458B84B3E6EA118CAAE426D6D45F6A2BA975844B9F709
+F4C8973FD8346CE519ED79525BB8CDAF69C74C036DCFADD05979BBF67DC42CB2
+82E8FE31C8A70146A9443B8710E9A47EB58069D68D24B38BC39CF7594B47C4D1
+B94976EC91E671B64A1072661C95056D455AEBD47FB6801A3F2E734FC1199D53
+B7A7F9479D5761C9FAD6D65A4282E30C022E782486CC0F80EC41DE930E4A6BBA
+EA3DF1A4D174B647E81BA0747759121BAD6E64202BB209EF3B0370C6ACF237FA
+920B717ED92AF133E6B0A589113AD1C84C65065EB1DAC271DE45DA0669A70AD0
+9B87FAF5925C65F2E0F83CF8FAEAED02D6317B43E3E1F09D43F4883952053521
+2DE7042F88463EA75AC93DBA8D07332866C2F4235FFA10868D076058F43F7072
+ABC0D7EE6B52E0D66E09B8ABFF14955A9F75C774F045049A8FDA1038267FA75D
+8BB765E9FE9DA3A13B20B2A015DECCA08382B5002F13B61E0401549FD5156C54
+38563629500310ACB94A360C7C29D01EE77BD646A27BA5927394F4FA2DB82DD1
+39A3B929412C48A3366FA088F55E9C396D5E748BCC659043001389C231AE4BAA
+4D1EC7263D3448F2148FE0AF195010D9D2430B9C3D3265371103EAA3D5948367
+95B16DE20400EF457730CB8A08B215BE46B895EEF0BF749B2454BC9F232A8AB5
+9F6DF063B9616E8E650D5D2E176FBF9B9F75C637CB10E1D0AE54223EFACE87AA
+3C1918E726ECD1DDD06260E140416877BDEE9CE0D3D27288E9FEC9ED170A5341
+8CB735E43BF16AD0847A3C4171BCFB532C08DF5C07D047D51A86D75638B625F7
+840F9DD7655E6E8F3A6D02D02FE903BC95A7A498CB81D4F8B55D6E6443188383
+B07CDD1B0710F8E3D7807D7CB8CD633449D7351D06AC5D847B6F45FBC339F585
+B3D099AAC9DA7C03536D75F7A7DC8C092327983C9C9E4D4EB5E5AAA827114F07
+0D0D78AAC8013DAACA697D4DB0AEE4D19F912CE892AE548C233A86651D09E423
+FC68CFB65F2097D6D5CE6BC3A83BF60FE72B52055F5F8B0E58EB5D61FC34EDBC
+5EB120953C28225F2C585166AC6CE6D6398D37FA4893259E0CD9775B9BFB0EAE
+94FEC64F7EFC695DEF269DF399C51D774ADF4A6358BE90EB144C3F3ADC24A482
+56C2A6B8D4720A3708BEF9201C6BB6CF7995ED46D07A4A6BE755C7B6D86C267A
+C75243BD06A2D8D4DBDC1B82A74562ECFD7FB85D5E8B9042ECD9018576531511
+5744B38ACCE37A8930A81B7CE6735BC2D69CCCD9AB4A9D763E45E8326E7E5CF5
+3DEAE61321C31802F58AC2BCC03246C090ECD87A50CC2CC431348ED0795D39AA
+48EF9F09894F0723C18E900E7BE9EF8FAF88BE6A00DABCC58A6CAA24BC23A77D
+462123BEAE7451FC96BABE4A71B951AF0D63D4AF74637380856E6E4D6EA77BBA
+0FBA42287A788BF2F73A7582A323E231B1E647D5CE6B0E85D0FAC97DEB89FC7A
+F914124C474D77741488C4332D1D1645962A122AB8646D086758ED5873CF1460
+B8C7186353E2AE4DE505827C27D04B0FD9833090E51E827E5F80DA71E87D54C9
+F31BDC10CB1AF752E3D58AE063635A17F067F88272537E38F867B06D269A4039
+743CCA93E51C9D1899282A0361A1D5088D8D5C3B37CE2D6773F2220B2059C208
+378E2A9424577ACD4CD54E6D3E487892E0A8A6A9F439CBD2E5F052118E55BFBD
+FC2C26FD7F5C5EC3C641001BD0592024A10CDD11794FA2F4F72ACBA1BA479D2B
+6EF0579A66C08849150363F6FB70AA123781458E5F44E088C26A057AFE543C16
+69132F71929648BF52B60955E446A0A0FFCFC660ED5EFE6AD21E2BC79D647691
+A4B520F144343B16A14EB9533531619CC1A8CDB8FA962F3417EE1FEF0FEF5BEA
+DB835DD2F7C4F656EF9B13A421ED6C006CA585EC73FC70418FF7B9EDF59D5E65
+743226277135CCFE612B99DCADBA9677AF4E0C71CB4037C9EE6067DE358E9A64
+43DACC84E8B4BC701E3ECE1AEB883AD7B3225404CC0214805920BC09744197AE
+DD6F9ECD8F488C0820A1BACFB1DEC20BFC5A3A83F8AC974346D876EBCA977F1F
+19EE959D6AF929C8CFFB49B1681C0464581603C599833853F6204F5770A8F10C
+F0B77A88357082FC033D85F31B3A41989A69784C368BA1BD9FD698D0C733ACB8
+73A8988B30446C6F27344F430A33FA7FF6E1F393EA5E55CC337DD07E222CF410
+25FF64FD656C1D651312686243D0B9395E868D906F9087E87C07BE20820B4833
+3F3C8E40B00C96BA87D70E776493FB5E623189AEDE0771F6227C3567425E1B39
+18F8526B730724E9DED28968429C3E4C9922D324FF5C11AC7F51D1627F68A9B4
+FD64285C1F12C9CF032F3D1CC46573567F8A9E9DAF754BE1180A03D9CB2CD335
+2A0AD42DE7ABBE379AAA48BCA7081B0CFB54B3D07095296D312CE97465CAEBC8
+7EE0C4E970BFCC6F684A6CCDE5D96D0AB2186EF7E6DB7065543DC76F6290CA7B
+E2F18B9BE17CC68CE0EE9B5C41486A6D273C2BB747D3C6EFE84663642FC99B32
+C8A1F61675C3F74CC13B81D2507152F8F86EE10A782B8B377F5FD9CBC5D6096B
+EE084A0A2CF8B64E0FE1283892D44CEA8C07D5699FF028C6AFD2CB85689F02AF
+EA534D07EB2669B97DBB524F877BAD513E7C761FA24C78F291FCFD8EA6128EFC
+20C3EF11FABDD8F0E695D4FCBB4DCB8D7FC38F1112D6C8F3716EF5E5A745A4DC
+B5B76C2A61AE5022CE7B2380FF6BE95CF5CF684EDE1F7E1E6EFCB6A9D8794E43
+9A436C7ED69A9A2313638CFF21C3A1035833F560E7C700E8A5CD602D4654FE39
+4C3DDF517C912017FEFB98AD4EB23D63FD72898D151A8BF29F78DB74B2870F25
+967B400087A386B70DD8AD85EF17B756799346A437EB18ECE0CA0383CA7E8DD0
+8E6B313673BD5B4F50719806F79A732D4553A135C082ABBC7DE8335B247E3F0D
+3D0CB1547C7033BFAC34848A46DAB4CB6F91BFCBCA2694DA3130CB50DFDBF57B
+E987B9E024124AB37ADDA79D9DA92A5B2A472D22360F98719CB8D94B2C2ADA17
+A93CDA4B8C12EBE0529BAEABA44EEA8B922C7977764713EF8A94939ED05DC761
+181BC30AFA25C85750B85FA9E9BA1C18AB2F33957DFC91A17035BE7EE2EECF4C
+51602249A0C69D913E69C972C2451F37FC338BD37970E4355B6A15168F7F2B59
+D43704178C8DB09635EBAA6E0557C37F391D8940BA055357E305ABAD0AE07DE1
+DCD281BAE650BCA2A6DBF28239AE94FDC0DCE1DDEAAC2BED703F7B5596373DFB
+5112BA07C2A418279DB7087C1A8AD45B29038E6CA312E2886365F8252E688F40
+472DB5FCA46220B85F8A72228B967B4A7EF87258BB4768BEA5BAC63164FDADAD
+8874753300AEC91FC26B05A20B0D825F1B009B94149096E7F094F9239AAB4C11
+3A38E9142245D71AFEE8A349FDAAAB1C548B59FE8462E511F8D18578F317E5E4
+69F266A88EF1030E001F82D2DCCD989F56340629E598732888BA97B1BC23E8E2
+3316B6638CFDE674462972F3F32FAD235622F531AC9C5D6024BEA095BA2B5B20
+103500160B65D6E779A55EA00EAC225A1DF2DE2250AD8DB8E55EDCEB82C4A1E7
+74866C63D9D2581DBB68D162E3109F94D7D03B47584D4994594B3551EA9756EE
+93A25715DBE3465E3E39534C7E15F900C6F92292E2D2CC5B9EE9832FA30CF468
+36C3CC0B193CBA37123772615A58C04679E5D6A82DEAAF112384B36D992E819F
+F5CE55C744326ED75DF8DB9F42B738A9769BEBF6175122C32F6D02C60B7F0E4B
+C4E33EB284F153BA62F38CBFBF0B55C445FC51C07596C9FD56DA9C2215A6A74D
+483397590911A40F2D9A036B4F4F224EB40C6789CC177748F7CED2C9AD736048
+422B5B56B5E8F986EDE0D897EC008A53FC6FE31548E7C174A423A8170362EB10
+9F394D47263FD3301D027BBB6BFD80AA775095FC05212E25E4CA254CA225F16F
+97D4284BA124BFB36D9FAB4836BB2DEC83CF7859977D93CCEAC4EA31C157BEAD
+6E704D3659ACFE88FB6E244B05B7DCF1715A8211DEA2609C5A87B50128549B0C
+4F36716ED8B286C37B529147D31888597016F92CE3E23E3D286E1B83BC4DC56A
+30061BE611673F7AFB067F30661333C7E20235B5B00FB9E2AC8AE78D8090E583
+757C53AE8F11D0C9185B871228A6948FF436B07559241F4E9879FBF20EE48C4D
+61A0D05D516DAC6FE76090AA32BB7D85F20B57AA1A7F03E88177C5071D45A2AE
+2DE56BF54D4080F7CA8DE2674964F55376035A45772ABA1CD04B92170C147500
+17D761A01014C4278078CE9DFFEA8F664E1AF14D55A9E6C35291DA6EF616E4AF
+292D8E806480BFEBABBB07B9CA48211D1CEF7356E0353619B774C7B4B9FCADA4
+B2381F981ADBE3FCDEC4514643959CE508C729F0017745920C4D0D961B18720A
+B5E4AD49E1BF18351073A497C2AFE30DB792F3D840B600F06BB85AAE536150BE
+B770665701C405300B57D3893E806598D6F79CA7AF844C8209B6AE55A2F13596
+7E51E1F43FEE69ECB7BBE95FE59D5A77AD4E10A9C20712C0645A98D92DE48F55
+EF2D8B450ED65B0060C8D0CB00B55A6EFA5866D4DFEA943CF79D510B12636003
+88248E878404BE11ADCBC55568A22254534918A90EB853BDCF2AE9FFE09B270E
+74CF7374CF0E02F24154AB883948EAE6E51109A991D344A1DD0AF2A88D6E88C1
+5C1275659E9E64009994C70A6ECA2B9FD67EA6DAFB5A462FD56679220E0FC19D
+E0FCF998433F9FD2AEB1D19CCA9052FF2E1DA517D30B06C0557AC46DC4545E42
+9ED317A1410590B8AC0A231C82220149F5166149F94EC4604B136A9CEF0175ED
+D562808278C55F7BBFEEDEB05EF0696BAC7CF24BEBD25BCD789AF34136156044
+0CBFF106A01BA8791EB96A9DE1FEC66A69E887CD84BB09B1068645F3D763912E
+D7B10BBFE515557936851665BBA83C8168F5071C4E4DC831BD623F026C7FEF1D
+CFF86B7B4F3166E97AA8603BD0153630E171894181A83D6855B9C922A61E21B1
+260852EEB799D6B02EF06495DD3EB17D5ACEDE4FC390A965734AFF1C86D0ABB4
+3AF895ED3BBCD4204FCC931BB1D1445056E5CDC15A35F68CFE57DCEF60B38039
+D2C3F333E88B37D043BE8555ED5D1EF3EC7ADE5DFA9CAD5A57EF1C24592E8791
+FA63382D86051BD15A75D61EEA62DFB2B6D58B42859CC0860A3B70F2600C3BCE
+8FEB13B8BC70FDF0FE509DEC5923AA700B9BEDD5E8DA95AFFA477B606C9F642B
+31B5A289D003FCAC762973430F68228259F0834216ABC90F2390DE575115958F
+EC8094EF76BDB0A8311873DB3A9EF93B84CBA538129779398AD5F07A2B161DE2
+EB245BDE209AE3B3746B8C4D522CD4F03AF3C3604E8A04CEC19B7704322B6625
+C5D1739E3B09B0C6314C1E4E376FBA32B92BA118EFB75A900D52A0EC748CC579
+64DA18C9A3EF2FB002DCAB6396B3DBF5446D61D2D19816F04653BBFF8DB0BDC6
+564A83DEF52E35972FE61644360BAE7C28725F33B77B5BABAD2C4AF38AE09C76
+0B8988862725B96B4F1E97832A04D15F9FEB31772A01DDD6A3C6853ADB37DFB9
+CF33C65E492D1B67964C290B315EC1ECA2D66CC114E30E93B6784FD03E007A9E
+A3708DB95057993F2A9D120FF2036AFC55E646B6E1A19173359C98E2F6F54C68
+0F2AB3F3CBD1A0EC9E4914619965C298A9BA82100F789455B74216315F986885
+E797FF113D5F58AE01A3111B8EDC5E60AFB493F26158FE272F99F58F5950A162
+54B674D8E18CDEC1A3C8DF1D222E40DB1AE267066012F35BBD9FF47C8F41E274
+00D9E04289B55DB29C62317ABDF641F5A80FFD44EA17A515BF686C8144ECB262
+C9A00754E328580741F62B129FB5404C7EA59BD53AC6B3B4FF3B7049B687711F
+F7252BDE999639A382260CDB5E3A493A58EDC76FACAFBBFB3FBB5AABF7B73EA8
+680E515E60C960002772683B6F5E0206F2B0B1A5C5CF6BE70A8B5991615D9037
+74BAE542A52AAF5B1814C9DA0D1A446721EFF16E407D50F14658A81F23F5678C
+1D9EBC8C135A05691587C6FCD3FB0FC5733AE707DBB47C02F4B35CA729F5E31E
+1CDA438CC60AAA23DB4ACBEE5756AE73B5C30646C79E217D1A3A464EB0E10339
+1ABD6979DC2B8DF32560730FCD36E48A697426B31C637A47D18FFC8371D3C4F4
+87C231053EB90540854B5AA70AB1265A7D923B2CF81BB46FBA29B2E04070A5C9
+C113A3CC4707988E8944362FD63BFD86D81FDA05112A76FEF22200C5CADD61C7
+675432106F183CE0F3DE8650F074597863E1C5052160B938EA5C58D18456EEB5
+AC6CB231E52111CA0DD8B6AB29F1A83C3B5051C5799BC80D1094C495D1D5920F
+73C82D52671B9AA1398616E1F0BECE376BE87FD614D0C562FA61A07298802C44
+2BBF69E2756B5E6933D7EBE74A2C9C6E0FE63CE9FD32D2F53E0B354E352B80C1
+05A6361DDAEE7435B15B8097519FDEBC444BC2A82BB73C43B7517BD52A38E0EB
+837DF785E6FA86597F278DBADD7CCC45114D15538FF3EEDB9A51AD73C8149378
+2B4355F574973897C4BACBF7AA523BE11E70E8E50842D9F5C61378715BD01031
+8F4DA1B843E3FC263EB1B0770BC73869CDE01FDD6447CD980F0B08F82E906AA9
+F0ACC1DE37766AB4BE723CB70B3AA8F20CF6A1C858E323F7A4C4066D758AF400
+FD7D2137625EFFEF9DA0B8DFA6CF7E9D255C1F2A6A6C9FF1993665DC94D7B66A
+1155C979BF2526BAD6797A7E0237B564F1A5E851208FBE6B4A24F3B7403BF643
+8AA05DB01013E1C92E2AACEFA6C83864DCDC80D464226CA3CF1C5109F74D832E
+463DD07C7EF291DC0B3F0AFF283EF0B0EC724289BFEFF1F2681FD73C359CCB05
+823D5C3EC711C057723168BF231C8CE1DC0BAC5700AD648C0B2EDF41E570C9A0
+8BB071FD6607317A0C26FCFAE913125A75C4E05856A4867D3869287869DBACED
+7C1B9C28A47E44CBCCAA4D1E29C2A0206F2BE7BD7633A7BC16B24CE711A77604
+9274EA197544EDA1CF60D7B4E79DB66CE55D741E7733DFC502C57A8624B4BCDD
+CB87AEF1F1AE850184D05F0B07F89AF5935C065B660B8D01073A8A21384CE117
+0C9B30F251239DC473CC1EB07645006BA28A3349D0FE9E6C784F7EA1AA048DCD
+D32D5A48740309C3968D6BEBF7EA01310BD20C7A09C98B66397807506726A94C
+2CFCAFB83515C2F50B9A8704E6CFF3C9E99AD89838079E72D1DEF1E149705440
+6EF3FE643B6ED8EF327137AE99701780B5B6E1F805F713A3EDCB9C5DFBB41AAE
+EAAC1631BBEEDBD60BE1A1B7D424455C0551D1949C46073FDBE4B5AED9191504
+BC19C97605A50587923008E98C20449F88BA0454FA1E0BD24017DDF87EBA90D7
+59A2CB4461AF750A5E0CCC86E82946CFAADF61F5AEF539365A64666D87464FA9
+0AA83E81C591471BEB33DC59193698C56C24805907CC7B6C5E0B98D49AB0C58B
+83ADA704F589DDF8B5671F15A22B28C795D005F5C456EC056FEBCBA7F3D2E4AF
+5A4CF815499A39451211F87412D5C31FD0AC16333E657D4F56A49FEFFB1E6219
+66F70B760FDD03120EE95D7295968FCB708428ED16C3BBC974B7386B5D293184
+202751B1F000469AB2F956B429984A443F47123A835279E67A4ABDBF5A6648FD
+3836316F8043C3714368EB10D5FC9EEDBAC56154A0D2CF4319F72A2844D5F79B
+4049AA331EE68626DE704B354559AE2607D73DD6AFF85D10E6F7B8A80D6F590A
+F14B4E00969DD3E1F2DD123C4C12DA2D87EF4EA9B7E4822E7AC9C466FA93469C
+705DCD793B8234597ADDC255A813010B1C357FE79FFFD61F71B1F5BBF283571A
+F10E4C475325321DB85D38B37DF214FCB6ABE68B3DABED7CCF738E084ED2A1BB
+58013DFD9F38592703C0FD5098710758EE7D03AC33A1C0F99E7CE6BEBC48CAEE
+F8EBBCF85A12CE3ABAE3F31DAC2D9A62EBC7140DED9B8ECD504AE9621736D5FF
+F2648BD92474505659A06F9633CFAE15B2AC6F8794892CB933E8FE5D784E9569
+4F4C5BF49764871C767394AE71A2693558F9AE51EE259DEA9B9B431D9A81687E
+8719464E84A8EE210F81AD7BC678796F42E9C265FC9394125E59EFA01D65F47D
+6C1028A58915A7CEE3C3F9404E224801DC3678F6A6EEFC9A9A7DD25B2EE6BB90
+884670A9D1FA0AA73B92FA8E697264432C7EEBAF740092EDDC9FAD1E924A55E7
+7E22C483ADD858C210C9A62EA0A66B4B010E674168D0F8BCD0E65D68358AA87F
+8E3CDB181DA3C5337B80AE04E8544EC7DA3097D8EC158594F73C06C45FD5C3FC
+7B0A3223EEF50A34DB19085C142691BC257E35DFC58F8E6ED9CCC8A0EA0E874B
+06E34C630CA69EA0475B0900DAE1D3D7AEFC8F256898B5335C43DB1782977863
+63F6B046EDF3E7EED285F2732B5841049329A60A21860867C7B98807D5054141
+9ABFCC76D1BAF26C4F86ACD2359FEA18E568764FCADBA74619180B4699461F31
+C455AC95658040BC4A9D08FDB314DB366B3E02A72F195E3D86D613AC2FE95D53
+36D0645B49DBD215FC757BB0CB0C0575F27BFB86CFFE3FE4844076D855AE7858
+5FF2BDE09D3EE55B85738FCFB63DFCBA28AAC3C755BBA838C5BF0578994266A0
+509EA91381B2B6D7DBD44A741D49F18BF984294F2E03DD250B8412BB9763F4AB
+F759A1DF65A4D85B74950807AB3E586BEA2C1B94C3FB064ADB42B44DCA4C4FDB
+0EB50FD99DAFCD0C527139FCBC6556160F96EC5966EE0D5DB77CD7FECD80C0C3
+AF00513B1CED91E1D0A123C70044EEAC1E493F8DE445CECBA5D82A29112AE756
+B761D0CD56543D4FCCF52FB322F8D751A2270071C2AD9BADBD4F9F2483B526DB
+41786125FE7EBD5CD16CBB140FAC70B7F66CD606A4FF3347B03E8B3461CCF732
+CC4276651078B49E24DE9A50F5C7C29EC86CA5B05AC5520B5E62D82EF6DB4740
+774DABA98ACC7B18F9DC5CFB813478E6ED7BC11F75597FCF327D25D645D3611B
+08CC73A2142D876136C7C7F1F4D7E419D62C3FA55E4E650D644293A177F0F5DE
+FCCA8B2EA0BB1C826CC04FA186C69543320D0CA226AB9BF1F463EDBF4541D894
+BD6070ED9BF8B1A00493DE0780545A9715585648A3F75FE5C0EC15F451665D8E
+A472367AAD73D4B80ACBF9AEE650A42CCA367784FF7FEBEC6BE001689FE82279
+CF23A42D25621C78DAFA72A5C63CADA4E5DADFB565ACC9FA9ECABC2BDCED927D
+93EDAD00461F46E7071494CA5A2EBD455069B477F39DB4F8B1DDB100C1976017
+483D7A7A23D827FA8AB91718C0F85A6A94EB507366580D6D569D3C81B167D399
+366B0F07D77AFE7DC3805888B9774D4B9F33077356B8DD20924FCE331D741339
+EFE0B224F9BA9D643C7A371D3C93686AF1D45A5285867A33ACB94A04B1B3445A
+5CEF6E928F851ACE627057C88C0361EDB7B970EAE4988C40F5416BB9514B16E4
+6F43E5483B37503F4CB095CE50A54B9F063BF37639EE485DC46AFE322D7D44E1
+843AB20EF0BBCB93055B7398099E6520DDF799DEE344DB7661EE79D5A94C471B
+8E83AD8242DFDDD666B8EADEDE132E3FCC247E6DB147F1C7B6FC32F1B94E910E
+2040C18065871DFC5773BDBDB93917A75D654CA065E6A3D3CFB22B263E0BF1E6
+40496D6AF3B4B365D40095DB46A33F5CEBC1A897A864BBBA09051EE958D33BA6
+C524A244FBE28F949CFC34F97917668EE6AA011E0F71EA1FE96A4A342695CFF0
+A801B86CCDA2F121C911C62531721F71A4CDDE5B67E6BF296A08CA6DB6B0CD63
+1378D449B24E5134A912EB80A0DB13B33C30999A2FDF054E51404D4BD6B90466
+56A30E51426CBD6A903B219C1A31C697BEE98757D5560AF360EDE13F2E29F543
+CA8814630C8D347A76FBB3753F2A6FA6F28E85842B2337257E04FCEAE8B38456
+5145720710DDD6D02ADBC70BCBAED5276569F42E29BC2658D0A32507F28188E5
+F1351294846AE40809C100A366C0024E19103333E8606125BC4C456EFD4E07BA
+925BB7594D29A017B0A09B06D4AC59B66D866CF26CA27458F6EC2BA572EB8D64
+70011AA667F4F8B9F73E6CA4A253CE08246F0224F052A0DE846FB4512C4D99AE
+FE04497E473996E14A58942FE5951C1384E357BB4C1E822432FBB54684B1B059
+98385164D52E76ECADB3C3F2CEB4ACB6A4905123535227C738DF2F947285559F
+48A99C1F2A89542ECBA0AA08F4902E16855148378425B9A9F559F9055E535D72
+7F6FC94A3C9B11C54C25E4E0ADA3E967230DA2EE5BE074DB6B459CD8FBD83C90
+29B25D75F114D36787E6ACED228B9D90F857BCC43828E10D4A2B62D237E0F67B
+E4C6D94FC46AF77143F8A9D40C29D1C390AA9CB1ECC9C4266CA6E36E051E8A96
+64A3ED986808A8F34E57401090E25CA4A844648715E06F624AF53D35E8777B19
+F2D772E3BD51FD1B7ACC31525A7F31ADAFD94389A71D7576BA0B3E28AD2C0011
+A3A174F6A910837C757E900A943C23EACEE40AFE65362F1A017D857509BD2B17
+BC3D89D493597D21C328C3CEEAD0D278B56B74E77679A1F4BAB0CC7FAB822294
+50EF060040680A815A04157CF3A88624B7B0B490B24EFBA5CB0DF2FA8251D0B6
+950DECDF1A01E09DAF3234C0B4D860F473D49CC675C1709E325E61F513D97B10
+4F902B550EB128AA1BB8A0044C124CA61969245F6DAC43EFC755DB4D00F08EAB
+B1F511BAB19F7F97139B0B099CC654E11E4808DCB034E9DA2C622E146FC05A8B
+5C2ECCB3D9D9C1C695E34665E8869245915A11992231F37F4460DBC14010DAFE
+4919A5767E6453674431D7A25734BB6087DE6B14223FA334CBEBEF71433065EA
+5DBA8A7DBA7A1E02AD5EA415822905931C76B8959AD82B8BDA3945EB735B7DE9
+DF98EBCC297C4E9ABE788E0FE75A5CBD619F9C6762A9303F73A226F86B39D138
+3A4126743E7D1676E82F2BED869B730074EA0A8F373ED53460E5CA118DC3A7B9
+2C6A22D12FA75ECE2289008F1374A040E66526DD1B4370546639F3BF7E30DD2D
+C6A02D5311289734F92DA1E5E6ACFC1FD57A64A16172FFEAB20EE4C1A283F2EA
+4B5D1E692B50613DAD9C9677137E7638C52CD1969F9D153F207D952A37BB4B27
+64BCC54DC9FABEAC2ED21BD716729128C4FC1BB218696329DDC9B9C1629B88B5
+768A5AFCD4A961C221F026C75975B99CAC631955BD515B89C23FB37098FD59CD
+CCD1CF98FC3BBAC40492735629889465F76DF0FB76A33EE835A311F3C7487949
+A00C2DB06B85D2022AA8ED039BD822E6A4D29E3DD53E46B4BBADD35FAD5D65D5
+6B000C3593C61BD1E2EBD076C16D2FB01753A07D4A38192478DDFF0A9DC214C9
+19DA628C39CB642BFE6C03FB53925ED587AF9FDCD9861D3E4E83DB75713D250F
+D905707396C118206005F199092674970C974041282D1F8A7535487E16F0467B
+D739AE26E2D9874ECACCF1C4D1EEE194B33CB646EAE7FEA5C2EC4E271F9B5A57
+0B3C183832188683B3A30CC9F5A4D12A6CA68F0205CCD32CBE0DA85998E7AF79
+30AF2D933A2A77AD64CA2A25C31CE434806B9417EC86C8190EFAB9554B608FF7
+B04A615DC6FB78147E000B84A5F109F1CF62D986954F1D4120A8356DF2F9D9D7
+30919F5DBE47C0843FF3114CAEFA9C569B7F5890AB1E5165F76CF1F3FA53A4C1
+CB0F286DD13438FDE1BEA397D323C04F44A145DEA2D01E55878C426BC0A58087
+D6505E555EE57AA91759E0DA6CF38698C9F0F08818802F41C4914CE92F15ACDE
+E98637E4358105938CC76258D64E74C9C8A1B9F5A11FD99A3259F978DDD8B3A0
+B1D3752AA227058E4C71E922F1B7F98860F4D4B4047812D8D57438D7080B6D36
+2F6703817E51FE12FE9C09622AC00BBCEECE83A66E0615647A33282242DF4A3F
+B6C65896B3A97E1FE53DD15E36450B8A0CA5A167F165A6031C6964C63F3A97AF
+8CB13F002F49EAF9CC3E6B3E949D82A928F9067D87378D809D44EAEB291C50F7
+4DD71BE5705751ED52D092864C586D8339465762636FB1BC4984BC4EEE9D1B73
+40B7CD1D446314E6B6876AFD799D5CF15414F406D5FFBFB161B2787D52BA6EC6
+EB045E89841C27ADBA513CD9E66D801D6558D38C7CF39BA611F12D721C9F3892
+53F54FBB72F0A37397607203E3D013796CE7AA904FC100E4D98D982188E35F98
+CA42E3FB5B6CAF4802E89F8C1490EAC4B4126737A88117589126C8271723B24A
+862645DE31498A014B2E200952DE96EE90015227FFAC7B51233A848080EE28BB
+DC772A2B370C0D1E4FAF709BECFE4C849D37576C30E68682CC6D4780EA706129
+AE83FDA278750EB88F7E532E182209EAFE5AE9511B475BB2BF8B4A927BE9940E
+BCBBB3A8F5C406D5D6A400CB1E411F0DA2C7C5E06554A63865F6FEC67514CFA2
+8F3E641618FF41780B8931C3F74DF560706D4083DCC3FF15CF317674A732815B
+1609248151E1F0F5FFA5BE875471C6DBBA24286DDECEFB18393D80B7D55B72BB
+1964B30901EFE3C56FC60E7A66B94996EF02A3566691B901F9E2A43FB802BA79
+991EBA9FBE8812CC2B1FAA1EDC6E5751409B4FDF1453276B9A9C353D79072033
+7541BB5985933C6F53C6F21CA29A5E0C51EFBDDC4F73EC23F8834386EC3D205E
+8C93E7460C054E3FFC65D22E2A23EEE804F7BF948F239B472DDB05F7C771EF10
+16CE412CDB0CC15945803A30C73A5A0569383B21FD39F8381D1730C1CDA1C3B0
+9D4AA2C78B44CA68E91CB796B3C11C857583BBB8DA115A58D2BAA86CFC90C5B3
+0B0077DB873191007515ECF130E3F893273DC1EE17B771E644758374D64FCF5F
+EDA79D50153CBD229632ED99FE0D58C28DC2BF68B0B508A2C2D285E7E652A7CD
+4328B5EBF67FD91DADEAE30C9F26A0BD144161CF41F2D47E8085C285DD6B171D
+137F5741EE3123A6D85436025FA41C8395A7B22F260972FD5C19291376489231
+AE57E4F16A50F24DF213D52AB738BEF14167D3D274209C681B170330ADDBD230
+0A32A50BF5ECDC51533E6BECA9FEAF7B45A71216B46FDDC96028922117455876
+67684185E5F2E14EEDFC6AB5A9D07C4CED852207E6F42DA2B970AAB0D4AC422E
+2B4DF09019DD94D4845BB1495EF02D73782F4DFEC1753977DDAF89827E7CCCF9
+98AE53464AC30512FC7816ACF0F1BEB693115D52D6351A61BBF9B0E8D246A3BF
+D18D269B565C69FFDD16D54FE71E0DD4C92C1BCB237B373F5235134E41CF0CF5
+CC736A7027353486DDCC40FE4E57CCF97A3CCBD1BDDD6E84B3035E48248F5FB7
+2592440636458AFD96B800ABCDC8F0051D950660C4215D8CC495CB9CE156578D
+5538131D58A08A70926FC5EEF78AA949DCE6DB4A4C699450C8EBED59530FF23E
+39C0C1678914BB5A0AA6CCF11B03A99432E312A015A4A31333B0BE73C67BE4B8
+CBADE9D60945C74A1107CACB5960065D184C703E9A1C17F8F4E04F9E567D6B74
+2248AC0733C23E6873FC85CF3A53E88AF599ED10273ED3A83D1D522B1020524C
+0C27B11ABD35609A9EE09F2BADEFD765814E09C782E9A6B36A40D81F9688E115
+77559C0DEBE26BFB922C29B66EA4CB27D6DD2DEC043FC1E9DBFCCAD44C59A384
+8297FED328D577A0FA04ACE7D9C193BA251C0E04AEC6155DFAE41717E2BC5D2B
+10B02D17215892E43F4890242B3642B8689019A107FE2A095D72D0BE69F698A6
+CB5A558A6EC8B5A9FDA647D4AE4B44F47BB4D9BC9712B9DB8BCB59939D5E2FEF
+CBD29C8DE79C5B2EE8FBE3B7EB365FC8D1BD9296B8BA79597A91C1BEF3AF81D3
+9A5F9B3B594305B1F5AA1A550B3F059B214FB1BF7722986C7437088856734D14
+0E3939A831F30B1A199B3F3E9F1BCFAF251045A2ED48E9792D74CFF5EC48707B
+13CF5A9C97BBE85DC3735E5AF81C4B57A8EEDFCEB6C1A43B2689FDBB995382B1
+C47908B06D6B829FADC04CDA394AB3FF6E8073B23503B5164259A80E65FD1097
+F5D2FD33B3448C0836F100AE390AD372233976776F295C44EAC321202620AB20
+883AE25EB88D43B33F1B8BF150DFB18C72E62F08EA623B9E8F9F2764D62F19A2
+51B7729DC20E03A4E78CD3AF38FE514542269ABBE0DE716ADDC5CAAAC0F7FC48
+EA589E90E0FE8CBFB8B5F61BDB55A97D946826629498353F4B52A81C50558C4B
+5D8DA6BA8412491E312E879DB14BAE092FFF0CEC2FC0C1C57E58F84E02E40E9E
+9FA42C2D9D03B16FF6EC4C7D9FD8FB452E6A1AD853E3919D6D60C4F7F90A2B58
+2BFAEF0F2C1A03F531C8EA8BA6D938682FF3F9952BA45661F0A8FBC31FC9BB50
+D29159B2083E232E75AE9A988AB9B88FBD0BCF51EAF9F2F3923FD27BE2E9375B
+328631E2CD4F5F4CD70C85D88F2DFC0E37ED32A5914BAFB650B9E6F82711CA44
+5DD06C963C316BC8387491737D5F56B2AD3EB8908736AF9C88D2A1198E2F025D
+FFB07FC6588C601E64E46BB4A3331B6E259DD50783A066870BC674F455ED9040
+404FF3D0203944DEAF5E531431B677D28A8882717F8B29D8EA4CAF0E102D2AED
+C9FD82860D4DC50A4218CDF16A1A1E36AB5005C060422C7F7818E97635DAFA13
+4462F6707B6EF3572D9EA2F4A0C96DFB90FADC599DD0F34AC2A0DC1484AA125D
+2EF0C8A52AED8C78F0F0338A2F61DE2CB5A07103AB15D64F9568A58DEBD2A28B
+C57ED6374FAB9950415EA47106C412261D49AB71FAB08C883E138FDED516CB04
+9EF1D1904E054C1B85E85751DE7E613EB1DB617727CA0917397F31D6E6341270
+F05EB52DA45202E87EBD684D1BFA47F1268B7816081F9F2952276F01243014C1
+5C4AD1B86EBBE3EC296BC5A9413F475FE5BFEA5F1633FDE6D8F678427B1000F3
+BE42D227374D4A8682629F80C10E37AEFC7E0263641649AAA793C16AAF286A11
+A2BE6DD0475A6037BDA22765DF55778B6A68D22E1EA0C4BE2B6A35D4F4B4D508
+1EDBFFF9E2558D9E0F4009065480EA8FA5FBCD91A4D8AA9131F6B9A9493ED31A
+F9C5D4EA07C528FF12B5DABAC8A37B6A1A48383FCEB193BED6E3DFD861E6FEAD
+5EF51DD6886BE65526725746A26EF762DB8653DC958D22738F59389C9FDAFB4F
+785107FD2ACCE87F23286207E930F5B0E3D832B043B6478B01ACC3BCE8EA590D
+951EF0CF581B28A592B8E3E00E316621547EF1ED4278A388926E263D4B3F6AC3
+1EB90CF0294E4BFDE585B7BAC8F723349C3E8F7A4D5E8A66EC5996959861DD9F
+E0326C6F0E685441F1F2AEB5A42B3C38C6347492F619FB671C543D12E84E95C4
+2F2C5E604B9211D91E420934AF52F070EB92016862962759CC24C6308A03A1D4
+DE856B851A0A01F3D794952B34B5D872D50A8692BD7F2568A45ED5D099615453
+28D2CA6118E430D395BE48BDF145EA32528591835B13A30D4D5621FC9BF95756
+0BD6612A622EE225F58096F7E448999D5921B1A4C087A48C815075C2639D96F5
+0B026DA5432293812B72503F727E39AFB400865E5F6FD09BC8617D81CD70C531
+63049CD97F577ADBB1A173CA4E4B0F9B5D806B51C4EB5A16CC5528CD865EFFA9
+28B9AE77A06598B60A2A91D75D605F1440394290EA0D7D932996FDEFD1BC7F92
+F0D5B4BEACC38782E16510F684AE4FD0EF9A44F3B81BD261065673EF46B29C49
+9B66A597BE886D1C42C978E3C7AC466EED99E6AFDAE7A37E5DB4EA9D2EF19640
+8B11CC0DD5BAB91E88E8E523E2AB3A8A0B01659FA7A188E19CF4A96F876F28A8
+9D6C64C07644009042B664B7E9FF96313063DE00DF66E5E57EA11A3ACBC6A158
+C359F596434BD9784C589279678DED0F3E8C56599BE553BB063197579AE1D65A
+2BAB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+TeXDict begin 40258431 52099146 1000 600 600 (Octave-FAQ.dvi)
+ at start /Fa 139[71 7[61 9[69 73 19[118 77[{}5 119.552
+/CMCSC10 rf /Fb 197[25 58[{}1 90.9091 /CMMI10 rf /Fc
+197[33 58[{}1 119.552 /CMMI12 rf /Fd 212[39 43[{}1 74.7198
+/CMTT9 rf /Fe 197[21 58[{}1 74.7198 /CMMI9 rf /Ff 139[85
+7[74 9[83 88 19[142 77[{}5 143.462 /CMCSC10 rf /Fg 137[48
+51 35 36 2[51 45 51 76 25 48 1[25 51 2[42 51 40 1[44
+7[69 3[70 4[62 1[71 86 5[71 71[{}22 90.9091 /CMB10 rf
+/Fh 134[48 48 2[48 4[48 48 48 1[48 6[48 48 48 48 48 97[{}12
+90.9091 /CMSLTT10 rf /Fi 134[48 48 2[51 4[51 45 51 1[25
+6[40 51 40 51 45 8[68 88[{}13 90.9091 /CMSL10 rf /Fj
+212[62 8[62 34[{}2 119.552 /CMTT12 rf /Fk 240[45 14[71{}2
+90.9091 /CMSY10 rf /Fl 134[41 41 55 41 43 30 30 30 1[43
+38 43 64 21 41 1[21 43 38 23 34 43 34 43 38 3[21 1[21
+2[58 79 58 58 55 43 2[52 60 58 70 48 1[39 28 58 60 50
+52 59 55 54 58 1[36 5[38 38 38 38 3[38 38 38 38 21 26
+21 4[21 39[{}59 74.7198 /CMR9 rf /Fm 139[44 7[38 9[43
+46 19[74 77[{}5 74.7198 /CMCSC10 rf /Fn 206[33 49[{}1
+58.1154 /CMR7 rf /Fo 139[54 7[47 9[53 56 19[90 31[34
+45[{}6 90.9091 /CMCSC10 rf /Fp 135[85 117 85 90 63 64
+66 85 90 81 90 134 45 2[45 90 81 49 74 90 72 90 78 9[167
+2[112 3[110 121 126 1[97 2[60 126 127 3[117 1[122 1[76
+5[81 81 81 81 81 81 81 81 81 81 1[45 6[45 39[{}46 143.462
+/CMBX12 rf /Fq 129[48 48 48 48 48 48 48 48 48 48 48 48
+48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48
+1[48 48 48 48 48 2[48 48 48 48 48 48 48 48 1[48 48 48
+48 48 48 48 48 48 1[48 48 48 48 48 48 48 48 48 48 48
+48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48
+48 48 48 48 1[48 48 48 33[{}88 90.9091 /CMTT10 rf /Fr
+136[60 2[30 10[28 46 104[{}4 90.9091 /CMTI10 rf /Fs 134[71
+71 97 71 75 52 53 55 71 75 67 75 112 37 71 1[37 75 67
+41 61 75 60 75 65 8[102 139 102 103 94 75 2[92 101 105
+128 81 1[69 50 105 106 85 88 103 97 96 102 1[64 5[67
+67 67 67 67 67 67 67 67 67 1[37 45 37 2[52 52 37 3[112
+22[75 12[{}64 119.552 /CMBX12 rf /Ft 131[91 45 40 48
+48 66 48 51 35 36 36 48 51 45 51 76 25 48 28 25 51 45
+28 40 51 40 51 45 25 2[25 45 25 1[68 68 93 68 68 66 51
+67 71 62 71 68 83 57 71 47 33 68 71 59 62 69 66 64 68
+1[43 1[71 1[25 25 45 45 45 45 45 45 45 45 45 45 45 25
+30 25 71 45 35 35 25 71 76 1[76 45 25 18[76 51 51 53
+11[{}89 90.9091 /CMR10 rf /Fu 137[102 1[75 14[88 1[86
+1[94 15[145 1[145 8[122 4[146 65[{}9 172.154 /CMBX12
+rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%BeginPaperSize: Letter
+<< /PageSize [612 792] >> setpagedevice
+%%EndPaperSize
+ end
+%%EndSetup
+%%Page: 1 1
+TeXDict begin 1 0 bop 150 1317 a Fu(Octa)-5 b(v)g(e)65
+b(F)-22 b(A)-5 b(Q)p 150 1417 3600 34 v 2116 1513 a Ft(F)d(requen)m
+(tly)31 b(ask)m(ed)g(questions)g(ab)s(out)f(Octa)m(v)m(e)3118
+1621 y(Septem)m(b)s(er)g(2008)150 5091 y Fs(John)45 b(W.)g(Eaton)h(and)
+f(Da)l(vid)g(Bateman)p 150 5141 3600 17 v eop end
+%%Page: 2 2
+TeXDict begin 2 1 bop eop end
+%%Page: 1 3
+TeXDict begin 1 2 bop 150 -116 a Ft(Chapter)30 b(1:)41
+b(What)31 b(is)f(Octa)m(v)m(e?)2428 b(1)275 299 y(This)29
+b(is)i(a)f(list)h(of)g(frequen)m(tly)f(ask)m(ed)h(questions)g(\(F)-10
+b(A)m(Q\))31 b(for)g(Octa)m(v)m(e)h(users.)275 445 y(W)-8
+b(e)27 b(are)g(alw)m(a)m(ys)i(lo)s(oking)e(for)g(new)f(questions)h(\()p
+Fr(with)34 b Ft(answ)m(ers\),)28 b(b)s(etter)f(answ)m(ers,)g(or)g(b)s
+(oth.)39 b(Please)150 554 y(send)30 b(suggestions)h(to)h
+Fq(bug at octave.org)p Ft(.)37 b(If)31 b(y)m(ou)g(ha)m(v)m(e)h(general)f
+(questions)g(ab)s(out)f(Octa)m(v)m(e,)k(or)c(need)150
+664 y(help)35 b(for)h(something)g(that)g(is)f(not)h(co)m(v)m(ered)h(b)m
+(y)f(the)g(Octa)m(v)m(e)h(man)m(ual)f(or)g(the)g(F)-10
+b(A)m(Q,)36 b(please)g(use)g(the)150 774 y Fq(help at octave.org)26
+b Ft(mailing)31 b(list.)275 919 y(This)e(F)-10 b(A)m(Q)32
+b(is)f(in)m(tended)f(to)i(supplemen)m(t,)e(not)h(replace,)h(the)f(Octa)
+m(v)m(e)i(man)m(ual.)42 b(Before)32 b(p)s(osting)f(a)150
+1029 y(question)j(to)g(the)f Fq(help at octave.org)c Ft(mailing)34
+b(list,)h(y)m(ou)f(should)e(\014rst)h(c)m(hec)m(k)i(to)f(see)g(if)f
+(the)h(topic)g(is)150 1139 y(co)m(v)m(ered)e(in)e(the)h(man)m(ual.)150
+1444 y Fp(1)80 b(What)54 b(is)f(Octa)l(v)l(e?)150 1712
+y Ft(Octa)m(v)m(e)33 b(is)e(a)h(high-lev)m(el)g(in)m(teractiv)m(e)i
+(language,)f(primarily)e(in)m(tended)g(for)g(n)m(umerical)g
+(computations)150 1822 y(that)g(is)f(mostly)h(compatible)h(with)e
+Fo(Ma)-6 b(tlab)p Ft(.)1781 1789 y Fn(1)275 1967 y Ft(Octa)m(v)m(e)31
+b(can)f(do)f(arithmetic)i(for)e(real,)i(complex)f(or)f(in)m(teger-v)-5
+b(alued)32 b(scalars)e(and)f(matrices,)i(solv)m(e)150
+2077 y(sets)36 b(of)g(nonlinear)f(algebraic)i(equations,)h(in)m
+(tegrate)g(functions)d(o)m(v)m(er)i(\014nite)e(and)g(in\014nite)h(in)m
+(terv)-5 b(als,)150 2187 y(and)30 b(in)m(tegrate)i(systems)f(of)f
+(ordinary)g(di\013eren)m(tial)i(and)d(di\013eren)m(tial-algebraic)34
+b(equations.)275 2332 y(Octa)m(v)m(e)f(uses)e(the)g(GNU)h(readline)g
+(library)f(to)h(handle)f(reading)g(and)g(editing)h(input.)43
+b(By)31 b(default,)150 2442 y(the)38 b(line)h(editing)g(commands)e(are)
+i(similar)f(to)h(the)g(cursor)e(mo)m(v)m(emen)m(t)j(commands)e(used)f
+(b)m(y)h(GNU)150 2552 y(Emacs,)29 b(and)f(a)h(vi-st)m(yle)h(line)f
+(editing)g(in)m(terface)h(is)f(also)g(a)m(v)-5 b(ailable.)42
+b(A)m(t)30 b(the)f(end)e(of)i(eac)m(h)h(session,)f(the)150
+2661 y(command)f(history)g(is)g(sa)m(v)m(ed,)i(so)f(that)f(commands)g
+(en)m(tered)h(during)e(previous)h(sessions)g(are)g(not)h(lost.)275
+2807 y(The)j(Octa)m(v)m(e)k(distribution)d(includes)g(a)g(590)p
+Fq(+)i Ft(page)f(T)-8 b(exinfo)33 b(man)m(ual.)50 b(Access)35
+b(to)f(the)f(complete)150 2917 y(text)e(of)g(the)f(man)m(ual)h(is)g(a)m
+(v)-5 b(ailable)32 b(via)f(the)g(help)f(command)g(at)h(the)g(Octa)m(v)m
+(e)h(prompt.)150 3166 y Fs(1.1)68 b(Who)45 b(dev)l(elops)h(Octa)l(v)l
+(e?)150 3326 y Ft(Discussions)41 b(ab)s(out)h(writing)f(the)g(soft)m(w)
+m(are)i(that)f(w)m(ould)f(ev)m(en)m(tually)i(b)s(ecome)f(Octa)m(v)m(e)h
+(started)f(in)150 3435 y(ab)s(out)32 b(1988)h(with)f(James)g(B.)g(Ra)m
+(wlings)h(and)e(John)g(W.)h(Eaton)g(at)h(the)f(Univ)m(ersit)m(y)h(of)f
+(T)-8 b(exas.)46 b(John)150 3545 y(W.)39 b(Eaton)g(w)m(as)g(the)f
+(original)i(author)e(of)g(Octa)m(v)m(e,)43 b(starting)c(full-time)g
+(dev)m(elopmen)m(t)h(in)e(F)-8 b(ebruary)150 3654 y(1992.)48
+b(He)32 b(is)h(still)g(the)f(primary)f(main)m(tainer.)47
+b(The)32 b(comm)m(unit)m(y)h(of)f(users/dev)m(elop)s(ers)g(has)g(in)g
+(addi-)150 3764 y(tion)g(con)m(tributed)f(some)h(co)s(de)f(and)f(fuels)
+h(the)h(discussion)e(on)h(the)g(mailing)h(lists)g Fq(help at octave.org)
+150 3874 y Ft(\(user)i(forum\),)h Fq(bug at octave.org)30
+b Ft(\(bug)k(rep)s(orts\),)h Fq(maintainers at octave.org)28
+b Ft(\(dev)m(elopmen)m(t)36 b(is-)150 3983 y(sues\),)42
+b(and)c Fq(octave-dev at lists.sourcefo)o(rge.)o(net)33
+b Ft(\(all)40 b(things)f(related)h(to)g(the)g(Octa)m(v)m(e)h(F)-8
+b(orge)150 4093 y(rep)s(ository)30 b(of)h(user-con)m(tributed)f
+(functions\).)150 4342 y Fs(1.2)68 b(Wh)l(y)45 b(GNU)g(Octa)l(v)l(e?)
+150 4502 y Ft(The)31 b(GNU)h(Pro)5 b(ject)32 b(w)m(as)g(launc)m(hed)f
+(in)g(1984)i(to)f(dev)m(elop)h(a)e(complete)i(Unix-lik)m(e)g(op)s
+(erating)f(system)150 4611 y(whic)m(h)e(is)h(free)f(soft)m(w)m(are:)42
+b(the)31 b(GNU)g(system.)275 4757 y(GNU)f(is)f(a)h(recursiv)m(e)g
+(acron)m(ym)g(for)f(\\GNU's)i(Not)f(Unix";)g(it)g(is)g(pronounced)e
+(guh-no)s(o,)h(appro)m(xi-)150 4867 y(mately)j(lik)m(e)f(cano)s(e.)275
+5013 y(The)25 b(F)-8 b(ree)27 b(Soft)m(w)m(are)h(F)-8
+b(oundation)27 b(\(FSF\))f(is)h(the)f(principal)g(organizational)j(sp)s
+(onsor)c(of)h(the)g(GNU)150 5122 y(Pro)5 b(ject.)p 150
+5241 1200 4 v 199 5308 a Fn(1)275 5340 y Fm(Ma)-5 b(tlab)26
+b Fl(is)g(a)g(registered)g(trademark)g(of)h(The)f(MathW)-6
+b(orks,)26 b(Inc.)p eop end
+%%Page: 2 4
+TeXDict begin 2 3 bop 150 -116 a Ft(Chapter)30 b(2:)41
+b(Licensing)31 b(Issues)2457 b(2)275 299 y(Octa)m(v)m(e)25
+b(b)s(ecame)e(GNU)g(Octa)m(v)m(e)i(in)e(1997)i(\(b)s(eginning)d(with)h
+(v)m(ersion)g(2.0.6\).)41 b(This)22 b(mean)m(t)h(agreeing)150
+408 y(to)28 b(consider)e(Octa)m(v)m(e)j(a)f(part)e(of)h(the)g(GNU)h
+(Pro)5 b(ject)28 b(and)e(supp)s(ort)f(the)i(e\013orts)g(of)g(the)g
+(FSF.)h(Ho)m(w)m(ev)m(er,)150 518 y(Octa)m(v)m(e)33 b(is)d(not)h(and)e
+(has)h(nev)m(er)h(b)s(een)f(dev)m(elop)s(ed)h(b)m(y)f(the)g(FSF.)275
+665 y(F)-8 b(or)31 b(more)f(information)h(ab)s(out)f(the)h(GNU)g(pro)5
+b(ject,)31 b(see)g Fq(www.gnu.org)p Ft(.)150 916 y Fs(1.3)68
+b(What)45 b(v)l(ersion)h(should)f(I)g(use?)150 1075 y
+Ft(In)27 b(general,)j(y)m(ou)e(will)h(\014nd)d(the)i(latest)i(v)m
+(ersion)f(on)f Fq(http://www.octave.org/)o(down)o(load)o(.ht)o(ml)p
+Ft(.)34 b(It)150 1185 y(is)21 b(recommended)f(to)i(use)e(the)h
+(\\testing")i(v)m(ersion)e(of)g(o)s(cta)m(v)m(e)i(for)d(general)i(use,)
+h(and)d(the)h(\\dev)m(elopmen)m(t")150 1294 y(v)m(ersion)31
+b(if)f(y)m(ou)h(w)m(an)m(t)g(the)g(latest)h(features.)275
+1441 y(A)38 b(list)g(of)g(user-visible)g(c)m(hanges)h(since)f(the)h
+(last)f(release)i(is)e(a)m(v)-5 b(ailable)40 b(in)e(the)g(\014le)g(`)p
+Fq(NEWS)p Ft('.)62 b(The)150 1551 y(\014le)28 b(`)p Fq(ChangeLog)p
+Ft(')f(in)h(the)g(source)g(distribution)g(con)m(tains)i(a)e(more)h
+(detailed)g(record)f(of)h(c)m(hanges)g(made)150 1660
+y(since)i(the)f(last)i(release.)150 1911 y Fs(1.4)68
+b(On)45 b(what)g(platforms)h(do)t(es)f(Octa)l(v)l(e)h(run?)150
+2071 y Ft(Octa)m(v)m(e)33 b(runs)c(on)i(v)-5 b(arious)31
+b(Unices|at)h(least)g(Lin)m(ux)e(and)h(Solaris,)g(Mac)h(OS)e(X,)h
+(Windo)m(ws)g(and)f(an)m(y-)150 2180 y(thing)36 b(y)m(ou)g(can)g
+(compile)h(it)f(on.)57 b(Binary)36 b(distributions)f(exist)i(at)g
+(least)g(for)e(Debian,)j(Suse,)f(F)-8 b(edora)150 2290
+y(and)37 b(RedHat)i(Lin)m(uxes)f(\(In)m(tel)h(and)e(AMD)i(CPUs,)h(at)e
+(least\),)k(for)c(Mac)h(Os)e(X)h(and)g(Windo)m(ws')g(98,)150
+2400 y(2000)32 b(and)e(XP)-8 b(.)275 2546 y(Tw)m(o)30
+b(and)g(three)g(dimensional)h(plotting)g(is)g(fully)f(supp)s(orted)e
+(using)i(gn)m(uplot.)275 2693 y(The)g(underlying)f(n)m(umerical)i(solv)
+m(ers)h(are)f(curren)m(tly)f(standard)g(F)-8 b(ortran)31
+b(ones)g(lik)m(e)h(Lapac)m(k,)g(Lin-)150 2803 y(pac)m(k,)e(Odepac)m(k,)
+g(the)g(Blas,)g(etc.,)h(pac)m(k)-5 b(aged)31 b(in)d(a)i(library)f(of)g
+(C)p Fq(++)f Ft(classes.)41 b(If)29 b(p)s(ossible,)g(the)g(F)-8
+b(ortran)150 2912 y(subroutines)31 b(are)h(compiled)h(with)f(the)g
+(system's)g(F)-8 b(ortran)33 b(compiler,)h(and)d(called)i(directly)g
+(from)f(the)150 3022 y(C)p Fq(++)40 b Ft(functions.)72
+b(If)41 b(that's)h(not)f(p)s(ossible,)i(y)m(ou)f(can)f(still)h(compile)
+g(Octa)m(v)m(e)h(if)e(y)m(ou)g(ha)m(v)m(e)i(the)e(free)150
+3132 y(F)-8 b(ortran)31 b(to)g(C)f(translator)h(f2c.)275
+3278 y(Octa)m(v)m(e)g(is)e(also)g(free)h(soft)m(w)m(are;)h(y)m(ou)e
+(can)g(redistribute)g(it)g(and/or)g(mo)s(dify)f(it)h(under)f(the)h
+(terms)g(of)150 3388 y(the)i(GNU)g(General)g(Public)f(License)h(as)f
+(published)f(b)m(y)h(the)h(F)-8 b(ree)31 b(Soft)m(w)m(are)h(F)-8
+b(oundation.)150 3695 y Fp(2)80 b(Licensing)52 b(Issues)150
+4059 y Fs(2.1)68 b(If)45 b(I)g(write)h(co)t(de)f(using)g(Octa)l(v)l(e)h
+(do)f(I)f(ha)l(v)l(e)i(to)g(release)g(it)389 4192 y(under)e(the)i(GPL?)
+150 4352 y Ft(The)30 b(answ)m(er)g(dep)s(ends)f(on)h(precisely)h(ho)m
+(w)f(the)h(co)s(de)f(is)h(written)f(and)g(ho)m(w)g(it)h(w)m(orks.)275
+4498 y(Co)s(de)h(written)h(en)m(tirely)h(in)e(the)h(scripting)g
+(language)h(of)f(Octa)m(v)m(e)i(\(in)m(terpreted)e(co)s(de)g(in)g(.m)g
+(\014les\))150 4608 y(ma)m(y)e(b)s(e)f(released)h(under)e(the)h(terms)h
+(of)f(whatev)m(er)h(license)h(y)m(ou)e(c)m(ho)s(ose.)275
+4755 y(Co)s(de)21 b(written)h(using)g(Octa)m(v)m(e's)i(nativ)m(e)f
+(plug-in)f(in)m(terface)h(\(also)h(kno)m(wn)d(as)h(a)h(.o)s(ct)g
+(\014le\))f(necessarily)150 4864 y(links)i(with)f(Octa)m(v)m(e)j(in)m
+(ternals)f(and)e(is)h(considered)g(a)g(deriv)-5 b(ativ)m(e)25
+b(w)m(ork)f(of)g(Octa)m(v)m(e)i(and)e(therefore)g(m)m(ust)150
+4974 y(b)s(e)30 b(released)h(under)e(terms)h(that)h(are)g(compatible)g
+(with)f(the)h(GPL.)275 5121 y(Co)s(de)j(written)h(using)f(Octa)m(v)m
+(e's)j(implemen)m(tation)g(of)e(the)g(Matlab)h(MEX)f(in)m(terface)h(ma)
+m(y)g(b)s(e)e(re-)150 5230 y(leased)22 b(under)e(the)h(terms)g(of)g
+(whatev)m(er)h(license)g(y)m(ou)g(c)m(ho)s(ose,)i(pro)m(vided)d(that)h
+(the)f(follo)m(wing)h(conditions)150 5340 y(are)31 b(met:)p
+eop end
+%%Page: 3 5
+TeXDict begin 3 4 bop 150 -116 a Ft(Chapter)30 b(3:)41
+b(Ho)m(w)31 b(can)g(I)f(cite)h(Octa)m(v)m(e?)2166 b(3)199
+299 y(1.)61 b(The)35 b(plugin)h(should)f(not)h(use)f(an)m(y)i(bindings)
+d(that)j(are)f(sp)s(eci\014c)g(to)g(Octa)m(v)m(e.)60
+b(In)35 b(other)h(w)m(ords,)330 408 y(the)42 b(MEX)h(\014le)f(m)m(ust)g
+(use)f(the)i(MEX)f(in)m(terface)i(only)-8 b(,)45 b(and)d(not)g(also)h
+(call)h(on)d(other)i(Octa)m(v)m(e)330 518 y(in)m(ternals.)51
+b(It)34 b(should)e(b)s(e)h(p)s(ossible)g(in)g(principle)g(to)i(use)e
+(the)h(MEX)g(\014le)f(with)h(other)f(programs)330 628
+y(that)e(implemen)m(t)g(the)g(MEX)f(in)m(terface)i(\(e.g.,)g(Matlab\).)
+199 787 y(2.)61 b(The)29 b(MEX)h(\014le)g(should)f(not)h(b)s(e)f
+(distributed)f(together)k(with)d(Octa)m(v)m(e)j(in)d(suc)m(h)h(a)g(w)m
+(a)m(y)g(that)h(they)330 897 y(e\013ectiv)m(ely)36 b(create)f(a)f
+(single)f(w)m(ork.)50 b(F)-8 b(or)34 b(example,)h(y)m(ou)e(should)g
+(not)g(distribute)g(the)g(MEX)h(\014le)330 1006 y(and)25
+b(Octa)m(v)m(e)k(together)e(in)f(a)g(single)h(pac)m(k)-5
+b(age)28 b(suc)m(h)d(that)i(Octa)m(v)m(e)h(automatically)h(loads)d(and)
+g(runs)330 1116 y(the)d(MEX)g(\014le)f(when)g(it)h(starts)g(up.)37
+b(There)22 b(are)h(other)f(p)s(ossible)g(w)m(a)m(ys)i(that)f(y)m(ou)g
+(migh)m(t)g(e\013ectiv)m(ely)330 1226 y(create)32 b(a)f(single)g(w)m
+(ork;)f(this)h(is)f(just)g(one)h(example.)275 1460 y(A)c(program)g
+(that)h(em)m(b)s(eds)f(the)g(Octa)m(v)m(e)j(in)m(terpreter)e(\(e.g.,)i
+(b)m(y)d(calling)i(the)e Fq(")p Ft(o)s(cta)m(v)m(e)p
+3242 1460 28 4 v 43 w(main)p Fq(")g Ft(func-)150 1570
+y(tion\),)f(or)d(that)h(calls)h(functions)e(from)g(Octa)m(v)m(e's)i
+(libraries)f(\(e.g.,)j(lib)s(o)s(ctin)m(terp,)e(lib)s(o)s(cta)m(v)m(e,)
+i(or)c(lib)s(cruft\))150 1679 y(is)31 b(considered)g(a)g(deriv)-5
+b(ativ)m(e)33 b(w)m(ork)e(of)g(Octa)m(v)m(e)j(and)c(therefore)i(m)m
+(ust)f(b)s(e)f(released)i(under)d(terms)i(that)150 1789
+y(are)g(compatible)g(with)f(the)h(GPL.)150 2075 y Fs(2.2)68
+b(Since)45 b(the)g(MEX)f(in)l(terface)j(allo)l(ws)f(plugins)f(to)h(b)t
+(e)e(distributed)389 2208 y(under)g(terms)i(that)f(are)h(incompatible)g
+(with)g(the)f(GPL,)f(do)t(es)389 2341 y(this)h(mean)h(that)f(y)l(ou)g
+(are)h(encouraging)f(p)t(eople)h(to)f(to)g(write)389
+2474 y(non-free)g(soft)l(w)l(are)i(for)e(Octa)l(v)l(e?)150
+2633 y Ft(No.)83 b(The)44 b(original)i(reason)e(for)g(implemen)m(ting)i
+(the)e(MEX)h(in)m(terface)h(for)e(Octa)m(v)m(e)j(w)m(as)d(to)h(allo)m
+(w)150 2743 y(Octa)m(v)m(e)29 b(to)f(run)d(free)i(soft)m(w)m(are)i
+(that)e(uses)g(MEX)g(\014les)g(\(the)h(particular)f(goal)i(w)m(as)e(to)
+h(run)d(SundialsTB)150 2852 y(in)k(Octa)m(v)m(e\).)43
+b(The)29 b(in)m(ten)m(t)i(w)m(as)f(to)g(lib)s(erate)g(that)h(soft)m(w)m
+(are)g(from)e(Matlab)h(and)f(increase)i(the)e(amoun)m(t)150
+2962 y(of)d(free)h(soft)m(w)m(are)h(a)m(v)-5 b(ailable)28
+b(to)f(Octa)m(v)m(e)i(users,)d(not)h(to)g(enable)g(p)s(eople)f(to)h
+(write)g(proprietary)f(co)s(de)g(for)150 3071 y(Octa)m(v)m(e.)51
+b(F)-8 b(or)34 b(the)f(go)s(o)s(d)g(of)h(the)f(comm)m(unit)m(y)-8
+b(,)35 b(w)m(e)f(strongly)g(encourage)g(users)e(of)h(Octa)m(v)m(e)j(to)
+e(release)150 3181 y(the)d(co)s(de)f(they)h(write)f(for)g(Octa)m(v)m(e)
+j(under)c(terms)h(that)h(are)g(compatible)g(with)g(the)f(GPL.)150
+3468 y Fs(2.3)68 b(I)45 b(wrote)h(a)f(program)g(that)h(links)f(with)h
+(Octa)l(v)l(e)g(libraries)g(and)389 3600 y(I)f(don't)g(w)l(an)l(t)h(to)
+f(release)i(it)f(under)e(the)h(terms)h(of)f(the)g(GPL.)389
+3733 y(Will)h(y)l(ou)f(c)l(hange)g(the)g(license)h(of)f(the)h(Octa)l(v)
+l(e)g(libraries)g(for)389 3866 y(me?)150 4025 y Ft(No.)69
+b(Instead)40 b(of)g(asking)g(us)f(to)i(c)m(hange)f(the)g(licensing)h
+(terms)f(for)f(Octa)m(v)m(e,)45 b(w)m(e)40 b(recommend)f(that)150
+4135 y(y)m(ou)34 b(release)g(y)m(our)g(program)f(under)f(terms)h(that)h
+(are)g(compatible)h(with)e(the)g(GPL)h(so)f(that)h(the)g(free)150
+4245 y(soft)m(w)m(are)f(comm)m(unit)m(y)f(can)g(b)s(ene\014t)e(from)h
+(y)m(our)g(w)m(ork)h(the)f(same)h(as)g(y)m(ou)f(ha)m(v)m(e)i(b)s
+(ene\014tted)e(from)g(the)150 4354 y(w)m(ork)f(of)h(all)g(the)g(p)s
+(eople)f(who)g(ha)m(v)m(e)i(con)m(tributed)e(to)h(Octa)m(v)m(e.)150
+4737 y Fp(3)80 b(Ho)l(w)53 b(can)h(I)g(cite)e(Octa)l(v)l(e?)150
+5121 y Ft(P)m(oin)m(ting)26 b(to)g Fq(http://www.octave.org)19
+b Ft(is)25 b(go)s(o)s(d,)h(b)s(ecause)f(that)h(giv)m(es)g(p)s(eople)f
+(a)g(direct)h(w)m(a)m(y)g(to)f(\014nd)150 5230 y(out)34
+b(more.)49 b(If)33 b(citation)i(of)f(a)g(URL)f(is)g(not)h(allo)m(w)m
+(ed)h(b)m(y)e(a)h(publisher,)e(or)i(if)f(y)m(ou)g(also)i(w)m(an)m(t)f
+(to)g(p)s(oin)m(t)150 5340 y(to)d(a)g(traditional)h(reference,)f(then)f
+(y)m(ou)g(can)h(cite)h(the)e(Octa)m(v)m(e)j(man)m(ual:)p
+eop end
+%%Page: 4 6
+TeXDict begin 4 5 bop 150 -116 a Ft(Chapter)30 b(4:)41
+b(What's)31 b(new)f(in)g(v)m(ersion)h(series)g(3.0.N)g(and)f(3.1.N)i
+(of)f(Octa)m(v)m(e)895 b(4)390 299 y Fq(@BOOK{eaton:2008,)485
+408 y(author)47 b(=)238 b("John)46 b(W.)h(Eaton)g(and)g(David)f
+(Bateman)g(and)h(Sren)f(Hauberg",)485 518 y(title)h(=)286
+b("GNU)47 b(Octave)f(Manual)g(Version)g(3",)485 628 y(publisher)g(=)95
+b("Network)45 b(Theory)i(Limited",)485 737 y(year)g(=)334
+b("2008",)485 847 y(isbn)47 b(=)334 b("0-9546120-6-X")390
+956 y(})150 1216 y Fp(4)80 b(What's)53 b(new)g(in)g(v)l(ersion)f
+(series)g(3.0.N)h(and)h(3.1.N)f(of)311 1374 y(Octa)l(v)l(e)150
+1630 y Ft(The)34 b(3.0.N)h(series)g(has)f(enough)g(new)f(features)i(to)
+g(justify)e(a)i(ma)5 b(jor)34 b(v)m(ersion)g(n)m(um)m(b)s(er)f(c)m
+(hange.)53 b(The)150 1740 y(3.0.N)32 b(series)f(brings)225
+1882 y Fk(\017)60 b Ft(in)m(teger)32 b(t)m(yp)s(es)225
+2020 y Fk(\017)60 b Ft(\014xed)30 b(p)s(oin)m(t)g(arithmetic)225
+2158 y Fk(\017)60 b Ft(sparse)30 b(matrices)225 2296
+y Fk(\017)60 b Ft(Linear)30 b(programming)g(co)s(de)h(based)f(on)g
+(GLPK)225 2434 y Fk(\017)60 b Ft(64-bit)32 b(compilation)g(supp)s(ort)
+225 2572 y Fk(\017)60 b Ft(gzipp)s(ed)30 b(\014les)g(and)g(stream)h
+(and)e(consequen)m(tly)j(supp)s(ort)c(of)j(matlab)g(v7)g(\014les)225
+2711 y Fk(\017)60 b Ft(b)s(etter)30 b(supp)s(ort)f(for)h(b)s(oth)g(msv)
+m(c)h(and)e(mingw)225 2849 y Fk(\017)60 b Ft(a)31 b(fully)f(compatible)
+h(MEX)g(in)m(terface)225 2987 y Fk(\017)60 b Ft(man)m(y)30
+b(man)m(y)h(other)g(minor)e(features)i(and)f(compatibilit)m(y)i(c)m
+(hanges)275 3157 y(Here)e(are)h(some)g(features)g(that)g(ha)m(v)m(e)g
+(b)s(een)f(around)f(since)i(2.1.N)225 3299 y Fk(\017)60
+b Ft(NDarra)m(ys)225 3438 y Fk(\017)g Ft(cells)275 3608
+y(The)34 b(3.1.N)i(series)f(is)g(the)f(curren)m(t)h(dev)m(elopmen)m(t)h
+(release)g(and)e(will)h(b)s(ecome)g(a)g(3.2.N)h(release)g(in)150
+3718 y(the)31 b(future.)39 b(This)30 b(series)h(brings)e(the)i(new)f
+(features)225 3859 y Fk(\017)60 b Ft(Op)s(enGL)29 b(bac)m(k)m(end)330
+3998 y(An)h(exp)s(erimen)m(tal)h(Op)s(enGL)e(graphics)i(bac)m(k)m(end)g
+(to)g(replace)g(the)g(gn)m(uplot)225 4136 y Fk(\017)60
+b Ft(Ob)5 b(ject)31 b(Orien)m(t)f(Programming)225 4274
+y Fk(\017)60 b Ft(Blo)s(c)m(k)32 b(commen)m(ts)225 4412
+y Fk(\017)60 b Ft(im)m(write)31 b(and)f(imread)330 4550
+y(The)g(functions)g(are)h(based)f(on)g(the)g(GraphicsMagic)m(k)j
+(library)-8 b(.)225 4689 y Fk(\017)60 b Ft(Lazy)31 b(transp)s(ose)330
+4827 y(Sp)s(ecial)37 b(treatmen)m(t)h(in)f(the)g(parser)f(of)h(things)g
+(lik)m(e)h Fq(")p Ft(a')f(*)g(b)p Fq(")p Ft(,)h(where)e(the)h(transp)s
+(ose)g(is)g(nev)m(er)330 4936 y(explicitly)32 b(formed)e(but)f(a)i
+(\015ag)g(is)f(rather)h(passed)e(to)j(the)e(underlying)f(LAP)-8
+b(A)m(CK)31 b(co)s(de.)225 5075 y Fk(\017)60 b Ft(Single)31
+b(precision)f(t)m(yp)s(e)225 5213 y Fk(\017)60 b Ft(Impro)m(v)m(ed)41
+b(arra)m(y)g(indexing)g(The)f(underlying)g(co)s(de)h(used)f(for)h
+(indexing)g(of)g(arra)m(ys)g(has)g(b)s(een)330 5322 y(completely)32
+b(rewritten)f(and)e(so)i(the)f(indexing)h(of)f(arra)m(ys)h(is)f(no)m(w)
+h(signi\014can)m(tly)g(faster.)p eop end
+%%Page: 5 7
+TeXDict begin 5 6 bop 150 -116 a Ft(Chapter)30 b(5:)41
+b(What)31 b(features)g(are)f(unique)g(to)h(Octa)m(v)m(e?)1619
+b(5)150 299 y Fp(5)80 b(What)54 b(features)f(are)g(unique)g(to)g(Octa)l
+(v)l(e?)150 563 y Ft(This)30 b(section)h(refers)f(to)h(Matlab)h(R2008b)
+f(and)f(Octa)m(v)m(e)j(2.1.51.)150 810 y Fs(5.1)68 b(F)-11
+b(unctions)44 b(de\014ned)h(on)f(the)i(command-line)150
+969 y Ft(F)-8 b(unctions)35 b(can)g(b)s(e)f(de\014ned)f(b)m(y)h(en)m
+(tering)i(co)s(de)f(on)f(the)h(command)f(line,)i(a)f(feature)g(not)g
+(supp)s(orted)150 1079 y(b)m(y)30 b(the)h(other)f(leading)i(brand.)39
+b(F)-8 b(or)31 b(example,)g(y)m(ou)g(ma)m(y)g(t)m(yp)s(e:)390
+1223 y Fq(octave:1>)45 b(function)h(s)h(=)h(hello_string)c(\(to_who\))
+390 1333 y(>)j(##)h(Say)f(hello)390 1442 y(>)g(if)h(nargin<1,)d(to_who)
+h(=)h("World";)f(end)390 1552 y(>)h(s)h(=)f(["Hello)f(",\\)390
+1661 y(>)286 b(to_who];)390 1771 y(>)47 b(endfunction)390
+1881 y(octave:2>)e(hello_string)g(\("Moon"\))390 1990
+y(ans)i(=)g(Hello)g(Moon)150 2237 y Fs(5.2)68 b(Commen)l(ts)46
+b(with)g(#)150 2397 y Ft(The)c(p)s(ound)f(c)m(haracter,)48
+b(`)p Fq(#)p Ft(',)e(ma)m(y)d(b)s(e)f(used)g(to)i(start)f(commen)m(ts,)
+k(in)42 b(addition)h(to)h(`)p Fq(\045)p Ft('.)78 b(See)43
+b(the)150 2506 y(previous)33 b(example.)50 b(The)32 b(ma)5
+b(jor)34 b(adv)-5 b(an)m(tage)35 b(of)e(this)g(is)g(that)h(as)g(`)p
+Fq(#)p Ft(')f(is)g(also)h(a)g(commen)m(t)g(c)m(haracter)150
+2616 y(for)d(unix)e(script)i(\014les,)g(an)m(y)g(\014le)g(that)g
+(starts)h(with)e(a)h(string)g(lik)m(e)h(`)p Fq(#!)e(/usr/bin/octave)c
+(-q)p Ft(')k(will)i(b)s(e)150 2726 y(treated)f(as)g(an)f(o)s(cta)m(v)m
+(e)j(script)d(and)g(b)s(e)g(executed)h(b)m(y)f(o)s(cta)m(v)m(e.)150
+2973 y Fs(5.3)68 b(Strings)45 b(delimitted)i(b)l(y)e(double)g(quotes)g
+Fj(")150 3132 y Ft(The)34 b(double)g(quote,)i(`)p Fq(")p
+Ft(',)f(ma)m(y)g(b)s(e)f(used)f(to)i(delimit)g(strings,)h(in)e
+(addition)g(to)h(the)g(single)g(quote)g(`)p Fq(')p Ft('.)150
+3242 y(See)24 b(the)g(previous)g(example.)39 b(Also,)26
+b(double-quoted)f(strings)e(include)h(bac)m(kslash)h(in)m(terpretation)
+g(\(lik)m(e)150 3351 y(C)p Fq(++)p Ft(,)30 b(C,)g(and)g(P)m(erl\))h
+(while)f(single)h(quoted)g(are)g(unin)m(terpreted)e(\(lik)m(e)j(Matlab)
+g(and)e(P)m(erl\).)150 3599 y Fs(5.4)68 b(Line)45 b(con)l(tin)l(uation)
+h(b)l(y)f(bac)l(kslash)150 3758 y Ft(Lines)39 b(can)h(b)s(e)f(con)m
+(tin)m(ued)h(with)g(a)g(bac)m(kslash,)i(`)p Fq(\\)p Ft(',)h(in)c
+(addition)h(to)g(three)g(p)s(oin)m(ts)f(`)p Fq(...)p
+Ft('.)68 b(See)40 b(the)150 3868 y(previous)30 b(example.)150
+4115 y Fs(5.5)68 b(Informativ)l(e)47 b(blo)t(c)l(k)e(closing)150
+4274 y Ft(Y)-8 b(ou)25 b(ma)m(y)g(close)h Fq(function)p
+Ft(,)e Fq(for)p Ft(,)h Fq(while)p Ft(,)g Fq(if)p Ft(,)31
+b(.)22 b(.)g(.)36 b(blo)s(c)m(ks)25 b(with)g Fq(endfunction)p
+Ft(,)e Fq(endfor)p Ft(,)h Fq(endwhile)p Ft(,)156 4384
+y(.)e(.)g(.)37 b(k)m(eyw)m(ords)26 b(in)f(addition)h(to)g(using)g
+Fq(end)p Ft(.)38 b(As)25 b(with)h(Matlab,)i(the)e Fq(end)f
+Ft(\(or)h Fq(endfunction)p Ft(\))c(k)m(eyw)m(ord)150
+4493 y(that)31 b(marks)f(the)g(end)g(of)h(a)g(function)f(de\014ned)f
+(in)h(a)h(`)p Fq(.m)p Ft(')f(\014le)g(is)h(optional.)150
+4741 y Fs(5.6)68 b(Coheren)l(t)46 b(syn)l(tax)150 4900
+y Ft(Indexing)30 b(other)g(things)h(than)f(v)-5 b(ariables)31
+b(is)f(p)s(ossible,)g(as)h(in:)390 5044 y Fq(octave:1>)45
+b([3)i(1)h(4)f(1)h(5)f(9]\(3\))390 5154 y(ans)g(=)g(4)390
+5264 y(octave:2>)e(cos\([0)h(pi)i(pi/4)e(7]\)\(3\))390
+5373 y(ans)h(=)g(0.70711)p eop end
+%%Page: 6 8
+TeXDict begin 6 7 bop 150 -116 a Ft(Chapter)30 b(5:)41
+b(What)31 b(features)g(are)f(unique)g(to)h(Octa)m(v)m(e?)1619
+b(6)150 299 y Fs(5.7)68 b(Exclamation)47 b(mark)e(as)g(not)g(op)t
+(erator)150 458 y Ft(The)30 b(exclamation)i(mark)f(')10
+b(!')41 b(\(ak)-5 b(a)31 b(\\Bang!"\))43 b(is)30 b(a)h(negation)h(op)s
+(erator,)f(just)f(lik)m(e)h(the)g(tilde)g(')p Fq(~)p
+Ft(':)390 610 y Fq(octave:1>)45 b(if)i(!)h(strcmp)e(\(program_name,)e
+("octave"\),)390 720 y(>)143 b("It's)46 b(an)h(error")390
+829 y(>)g(else)390 939 y(>)143 b("It)47 b(works!")390
+1049 y(>)g(end)390 1158 y(ans)g(=)g(It)h(works!)150 1417
+y Fs(5.8)68 b(Incremen)l(t)46 b(and)e(decremen)l(t)i(op)t(erators)150
+1576 y Ft(If)36 b(y)m(ou)h(lik)m(e)g(the)g(`)p Fq(++)p
+Ft(',)h(`)p Fq(+=)p Ft(')e(etc)i(op)s(erators,)g(rejoice!)60
+b(Octa)m(v)m(e)38 b(includes)e(the)h(C-lik)m(e)h(incremen)m(t)f(and)150
+1686 y(decremen)m(t)27 b(op)s(erators)f(`)p Fq(++)p Ft(')h(and)e(`)p
+Fq(--)p Ft(')h(in)g(b)s(oth)g(their)g(pre\014x)g(and)f(p)s(ost\014x)h
+(forms,)g(in)g(addition)h(to)g(`)p Fq(+=)p Ft(',)150
+1796 y(`)p Fq(-=)p Ft(',)k(`)p Fq(*=)p Ft(',)f(`)p Fq(/=)p
+Ft(',)h(`)p Fq(^=)p Ft(',)f(`)p Fq(.*=)p Ft(',)g(`)p
+Fq(./=)p Ft(',)h(and)e(`)p Fq(.^=)p Ft('.)275 1948 y(F)-8
+b(or)28 b(example,)h(to)g(pre-incremen)m(t)f(the)g(v)-5
+b(ariable)28 b Fi(x)p Ft(,)g(y)m(ou)g(w)m(ould)g(write)g
+Fq(++)p Fh(x)11 b Ft(.)38 b(This)27 b(w)m(ould)h(add)f(one)150
+2057 y(to)35 b Fi(x)41 b Ft(and)35 b(then)f(return)g(the)g(new)h(v)-5
+b(alue)35 b(of)g Fi(x)41 b Ft(as)35 b(the)g(result)f(of)h(the)g
+(expression.)54 b(It)34 b(is)h(exactly)i(the)150 2167
+y(same)31 b(as)f(the)h(expression)f Fh(x)41 b Fq(=)30
+b Fh(x)40 b Fq(+)30 b(1)p Ft(.)275 2319 y(T)-8 b(o)33
+b(p)s(ost-incremen)m(t)h(a)g(v)-5 b(ariable)34 b Fi(x)p
+Ft(,)h(y)m(ou)e(w)m(ould)h(write)f Fq(x++)p Ft(.)49 b(This)33
+b(adds)f(one)i(to)g(the)g(v)-5 b(ariable)34 b Fi(x)p
+Ft(,)150 2428 y(but)e(returns)f(the)h(v)-5 b(alue)33
+b(that)g Fi(x)39 b Ft(had)32 b(prior)f(to)i(incremen)m(ting)h(it.)47
+b(F)-8 b(or)33 b(example,)h(if)e Fi(x)39 b Ft(is)32 b(equal)h(to)g(2,)
+150 2538 y(the)e(result)f(of)g(the)h(expression)f Fq(x++)g
+Ft(is)g(2,)h(and)f(the)g(new)g(v)-5 b(alue)31 b(of)g
+Fi(x)36 b Ft(is)31 b(3.)275 2690 y(F)-8 b(or)29 b(matrix)g(and)f(v)m
+(ector)j(argumen)m(ts,)e(the)g(incremen)m(t)h(and)e(decremen)m(t)h(op)s
+(erators)g(w)m(ork)g(on)g(eac)m(h)150 2800 y(elemen)m(t)j(of)e(the)h
+(op)s(erand.)150 3058 y Fs(5.9)68 b(Un)l(wind-protect)150
+3218 y Ft(Octa)m(v)m(e)40 b(supp)s(orts)35 b(a)j(limited)g(form)f(of)h
+(exception)g(handling)f(mo)s(delled)h(after)g(the)f(un)m(wind-protect)
+150 3327 y(form)30 b(of)g(Lisp.)41 b(The)29 b(general)j(form)e(of)g(an)
+g Fq(unwind_protect)d Ft(blo)s(c)m(k)k(lo)s(oks)g(lik)m(e)g(this:)390
+3479 y Fq(unwind_protect)485 3589 y Fh(body)390 3699
+y Fq(unwind_protect_cleanup)485 3808 y Fh(cleanup)390
+3918 y Fq(end_unwind_protect)150 4070 y Ft(Where)39 b
+Fi(b)s(o)s(dy)46 b Ft(and)38 b Fi(clean)m(up)43 b Ft(are)c(b)s(oth)g
+(optional)h(and)f(ma)m(y)h(con)m(tain)g(an)m(y)g(Octa)m(v)m(e)h
+(expressions)e(or)150 4179 y(commands.)65 b(The)38 b(statemen)m(ts)j
+(in)d Fi(clean)m(up)k Ft(are)d(guaran)m(teed)h(to)f(b)s(e)f(executed)i
+(regardless)f(of)g(ho)m(w)150 4289 y(con)m(trol)32 b(exits)f
+Fi(b)s(o)s(dy)p Ft(.)275 4441 y(The)41 b Fq(unwind_protect)c
+Ft(statemen)m(t)44 b(is)d(often)h(used)f(to)i(reliably)f(restore)g(the)
+g(v)-5 b(alues)42 b(of)g(global)150 4551 y(v)-5 b(ariables)31
+b(that)g(need)f(to)h(b)s(e)f(temp)s(orarily)g(c)m(hanged.)275
+4703 y(Matlab)37 b(can)f(b)s(e)g(made)g(to)h(do)f(something)g(similar)h
+(with)e(their)i Fq(OnCleanUp)c Ft(function)j(that)h(w)m(as)150
+4812 y(in)m(tro)s(duced)30 b(in)g(2008a.)150 5071 y Fs(5.10)68
+b(Built-in)45 b(ODE)h(and)e(D)l(AE)h(solv)l(ers)150 5230
+y Ft(Octa)m(v)m(e)39 b(includes)d(LSODE)f(and)h(D)m(ASSL)g(for)g
+(solving)h(systems)g(of)f(sti\013)h(ordinary)f(di\013eren)m(tial)i(and)
+150 5340 y(di\013eren)m(tial-algebraic)c(equations.)41
+b(These)30 b(functions)g(are)h(built)f(in)g(to)h(the)g(in)m(terpreter.)
+p eop end
+%%Page: 7 9
+TeXDict begin 7 8 bop 150 -116 a Ft(Chapter)30 b(6:)41
+b(What)31 b(do)s(cumen)m(tation)g(exists)g(for)f(Octa)m(v)m(e?)1508
+b(7)150 299 y Fp(6)80 b(What)54 b(do)t(cumen)l(tation)d(exists)i(for)h
+(Octa)l(v)l(e?)150 687 y Fs(6.1)68 b(What)45 b(do)t(cumen)l(tation)h
+(exists)g(for)f(Octa)l(v)l(e?)150 847 y Ft(The)39 b(Octa)m(v)m(e)j
+(distribution)d(includes)g(a)h(590)p Fq(+)h Ft(page)f(man)m(ual)g(that)
+g(is)g(also)g(distributed)f(under)f(the)150 956 y(terms)29
+b(of)g(the)g(GNU)g(GPL.)g(It)g(is)g(a)m(v)-5 b(ailable)31
+b(on)e(the)g(w)m(eb)g(at)g Fq(http://www.octave.org/docs)o(.htm)o(l)150
+1066 y Ft(and)h(y)m(ou)g(will)h(also)h(\014nd)c(there)j(instructions)f
+(on)g(ho)m(w)h(to)g(order)f(a)h(pap)s(er)e(v)m(ersion.)275
+1216 y(The)d(complete)i(text)f(of)g(the)f(Octa)m(v)m(e)j(man)m(ual)e
+(is)f(also)i(a)m(v)-5 b(ailable)29 b(using)d(the)h(GNU)g(Info)f(system)
+g(via)150 1326 y(the)32 b(GNU)h(Emacs,)f(info,)h(or)e(xinfo)h
+(programs,)g(or)g(b)m(y)g(using)f(the)h(`)p Fq(help)e(-i)p
+Ft(')h(command)h(to)g(start)h(the)150 1435 y(GNU)e(info)f(bro)m(wser)g
+(directly)h(from)f(the)h(Octa)m(v)m(e)h(prompt.)275 1586
+y(If)24 b(y)m(ou)h(ha)m(v)m(e)h(problems)f(using)f(this)h(do)s(cumen)m
+(tation,)i(or)e(\014nd)e(that)j(some)f(topic)h(is)f(not)g(adequately)
+150 1696 y(explained,)31 b(indexed,)f(or)g(cross-referenced,)h(please)h
+(send)d(a)i(bug)f(rep)s(ort)f(to)j Fq(bug at octave.org)p
+Ft(.)150 1952 y Fs(6.2)68 b(Getting)46 b(additional)g(help)150
+2112 y Ft(If)38 b(y)m(ou)h(can't)g(\014nd)e(an)h(answ)m(er)g(to)h(y)m
+(our)g(question,)h(the)f Fq(help at octave.org)34 b Ft(mailing)39
+b(list)g(is)g(a)m(v)-5 b(ail-)150 2221 y(able)33 b(for)g(questions)f
+(related)i(to)g(using,)f(installing,)h(and)e(p)s(orting)h(Octa)m(v)m(e)
+h(that)g(are)f(not)g(adequately)150 2331 y(answ)m(ered)d(b)m(y)g(the)h
+(Octa)m(v)m(e)i(man)m(ual)d(or)h(b)m(y)f(this)g(do)s(cumen)m(t.)150
+2587 y Fs(6.3)68 b(User)46 b(comm)l(unit)l(y)150 2747
+y Ft(T)-8 b(o)35 b(subscrib)s(e)f(to)h(the)g(list,)i(go)f(to)f
+Fq(www.octave.org/archive.htm)o(l)29 b Ft(and)34 b(follo)m(w)i(the)f
+(link)g(to)h(the)150 2856 y(subscription)29 b(page)i(for)g(the)f(list.)
+275 3007 y Fg(Please)43 b(do)f(not)g Ft(send)g(requests)g(to)h(b)s(e)e
+(added)g(or)i(remo)m(v)m(ed)g(from)e(the)i(mailing)g(list,)j(or)c
+(other)150 3116 y(administrativ)m(e)32 b(trivia)f(to)g(the)g(list)g
+(itself.)275 3267 y(An)73 b(arc)m(hiv)m(e)i(of)f(old)g(p)s(ostings)g
+(to)g(the)g(help-o)s(cta)m(v)m(e)i(mailing)f(list)g(is)e(main)m(tained)
+i(on)150 3377 y Fq(http://www.octave.org/ar)o(chiv)o(e.ht)o(ml)p
+Ft(.)275 3527 y(Y)-8 b(ou)70 b(will)g(also)g(\014nd)e(some)i(user)f
+(advice)i(and)e(co)s(de)g(spread)g(o)m(v)m(er)i(the)f(w)m(eb.)158
+b(Go)s(o)s(d)150 3637 y(starting)77 b(p)s(oin)m(ts)g(are)g(the)g(Octa)m
+(v)m(e)i(Wiki)e Fq(http://wiki.octave.org)71 b Ft(and)76
+b(Octa)m(v)m(e-F)-8 b(orge)150 3746 y Fq(http://octave.sourceforg)o
+(e.ne)o(t)150 4003 y Fs(6.4)68 b(I)45 b(think)g(I)g(ha)l(v)l(e)h(found)
+e(a)h(bug)g(in)g(Octa)l(v)l(e.)150 4162 y Ft(\\I)32 b(think)f(I)h(ha)m
+(v)m(e)g(found)f(a)h(bug)f(in)g(Octa)m(v)m(e,)k(but)c(I'm)g(not)h
+(sure.)44 b(Ho)m(w)32 b(do)g(I)f(kno)m(w,)i(and)e(who)g(should)150
+4272 y(I)f(tell?")275 4422 y(First,)d(see)g(the)f(section)h(on)f(bugs)g
+(and)f(bug)h(rep)s(orts)f(in)h(the)g(Octa)m(v)m(e)i(man)m(ual.)40
+b(When)26 b(y)m(ou)g(rep)s(ort)g(a)150 4532 y(bug,)h(mak)m(e)h(sure)f
+(to)g(describ)s(e)g(the)g(t)m(yp)s(e)g(of)g(computer)g(y)m(ou)h(are)f
+(using,)g(the)h(v)m(ersion)f(of)g(the)g(op)s(erating)150
+4641 y(system)36 b(it)h(is)f(running,)f(and)h(the)g(v)m(ersion)g(of)g
+(Octa)m(v)m(e)i(that)f(y)m(ou)f(are)h(using.)57 b(Also)36
+b(pro)m(vide)g(enough)150 4751 y(co)s(de)31 b(so)f(that)h(the)g(Octa)m
+(v)m(e)h(main)m(tainers)f(can)g(duplicate)g(y)m(our)f(bug.)275
+4902 y(If)24 b(y)m(ou)h(ha)m(v)m(e)h(Octa)m(v)m(e)h(w)m(orking)e(at)g
+(all,)i(the)e(easiest)h(w)m(a)m(y)g(to)g(do)e(this)h(is)g(to)g(use)f
+(the)h(Octa)m(v)m(e)i(function)150 5011 y Fq(bug_report)p
+Ft(.)55 b(When)36 b(y)m(ou)g(execute)h(this)f(function,)i(Octa)m(v)m(e)
+g(will)e(prompt)f(y)m(ou)i(for)e(a)i(sub)5 b(ject)36
+b(and)150 5121 y(then)42 b(in)m(v)m(ok)m(e)h(the)f(editor)h(on)e(a)i
+(\014le)f(that)g(already)g(con)m(tains)h(all)g(the)f(con\014guration)g
+(information.)150 5230 y(When)29 b(y)m(ou)g(exit)g(the)g(editor,)h
+(Octa)m(v)m(e)h(will)e(mail)h(the)f(bug)f(rep)s(ort)g(for)h(y)m(ou)g
+(\(in)g(a)g(unix-lik)m(e)g(op)s(erating)150 5340 y(system\).)p
+eop end
+%%Page: 8 10
+TeXDict begin 8 9 bop 150 -116 a Ft(Chapter)30 b(8:)41
+b(Installation)32 b(Issues)d(and)h(Problems)1798 b(8)275
+299 y(If)31 b(for)h(some)g(reason)g(y)m(ou)g(cannot)h(use)e(Octa)m(v)m
+(e's)k Fq(bug_report)29 b Ft(function,)j(mail)g(y)m(our)g(bug)g(rep)s
+(ort)150 408 y(to)d Fq(bug at octave.org)p Ft(.)36 b(Y)-8
+b(our)28 b(message)i(needs)d(to)i(include)f(enough)g(information)h(to)g
+(allo)m(w)g(the)g(main-)150 518 y(tainers)36 b(of)g(Octa)m(v)m(e)i(to)f
+(\014x)e(the)i(bug.)56 b(Please)37 b(read)f(the)g(section)h(on)f(bugs)f
+(and)h(bug)f(rep)s(orts)g(in)h(the)150 628 y(Octa)m(v)m(e)d(man)m(ual)d
+(for)g(a)h(list)g(of)g(things)f(that)h(should)e(b)s(e)h(included)g(in)g
+(ev)m(ery)h(bug)f(rep)s(ort.)150 968 y Fp(7)80 b(Getting)52
+b(Octa)l(v)l(e)150 1402 y Fs(7.1)68 b(Source)45 b(co)t(de)150
+1561 y Ft(Source)24 b(co)s(de)h(is)g(a)m(v)-5 b(ailable)27
+b(on)d(the)h(Octa)m(v)m(e)h(dev)m(elopmen)m(t)g(site,)h(where)d(y)m(ou)
+h(are)g(sure)f(to)h(get)h(the)e(latest)150 1671 y(v)m(ersion.)225
+1835 y Fk(\017)60 b Fq(http://www.octave.org/do)o(wnlo)o(ad.h)o(tml)225
+1984 y Fk(\017)g Fq(ftp://ftp.octave.org/pub)o(/oct)o(ave/)275
+2187 y Ft(Since)41 b(Octa)m(v)m(e)j(is)e(distrubted)f(under)f(the)i
+(terms)g(of)g(the)g(GPL,)g(y)m(ou)g(can)g(get)h(Octa)m(v)m(e)h(from)e
+(a)150 2296 y(friend)36 b(who)g(has)g(a)h(cop)m(y)-8
+b(,)39 b(b)m(y)e(anon)m(ymous)f(FTP)-8 b(,)37 b(or)g(b)m(y)f(ordering)g
+(a)h(tap)s(e)g(or)f(CD-R)m(OM)i(from)e(the)150 2406 y(F)-8
+b(ree)31 b(Soft)m(w)m(are)h(F)-8 b(oundation)31 b(\(FSF\).)150
+2682 y Fs(7.2)68 b(Pre-compiled)46 b(binary)e(pac)l(k)-7
+b(ages)150 2841 y Ft(The)40 b(Octa)m(v)m(e)j(pro)5 b(ject)41
+b(do)s(es)g(not)g(distribute)f(binary)g(pac)m(k)-5 b(ages,)46
+b(but)40 b(other)h(pro)5 b(jects)41 b(do.)72 b(F)-8 b(or)41
+b(an)150 2951 y(up-to-date)31 b(listing)h(of)e(pac)m(k)-5
+b(agers,)32 b(see:)225 3115 y Fk(\017)60 b Fq(http://www.octave.org/do)
+o(wnlo)o(ad.h)o(tml)225 3264 y Fk(\017)g Fq(http://wiki.octave.org/w)o
+(iki.)o(pl?C)o(ate)o(gory)o(Inst)o(all)275 3467 y Ft(As)29
+b(of)h(to)s(da)m(y)-8 b(,)31 b(Octa)m(v)m(e)h(binaries)e(are)g(a)m(v)-5
+b(ailable)32 b(at)f(least)g(on)e(Debian,)i(RedHat,)g(Suse)e(and)g(F)-8
+b(edora)150 3576 y(Lin)m(uxes,)30 b(Mac)i(OS)d(X,)i(Windo)m(ws')g(98,)g
+(2000)h(and)e(XP)-8 b(.)150 3838 y Fs(7.3)68 b(Ho)l(w)46
+b(do)f(I)f(get)i(a)f(cop)l(y)g(of)g(Octa)l(v)l(e)i(for)e(\(some)h
+(other)389 3971 y(platform\)?)150 4130 y Ft(Octa)m(v)m(e)27
+b(curren)m(tly)d(runs)f(on)h(Unix-lik)m(e)i(systems,)g(Mac)f(OS)f(X,)g
+(and)g(Windo)m(ws.)39 b(It)24 b(should)g(b)s(e)f(p)s(ossible)150
+4240 y(to)34 b(mak)m(e)g(Octa)m(v)m(e)h(w)m(ork)e(on)f(other)i(systems)
+f(as)g(w)m(ell.)49 b(If)32 b(y)m(ou)i(are)f(in)m(terested)h(in)f(p)s
+(orting)f(Octa)m(v)m(e)j(to)150 4349 y(other)c(systems,)f(please)h(con)
+m(tact)i Fq(bug at octave.org)p Ft(.)150 4690 y Fp(8)80
+b(Installation)53 b(Issues)f(and)i(Problems)150 5011
+y Ft(Octa)m(v)m(e)27 b(3.2)e(require)g(appro)m(ximately)g(800MB)i(of)e
+(disk)f(storage)i(to)f(unpac)m(k)f(and)g(compile)i(from)e(source)150
+5121 y(\(considerably)38 b(less)f(if)h(y)m(ou)f(don't)h(compile)g(with)
+f(debugging)g(sym)m(b)s(ols\).)61 b(Once)38 b(installed,)i(Octa)m(v)m
+(e)150 5230 y(requires)31 b(appro)m(ximately)j(200MB)g(of)e(disk)f
+(space)i(\(again,)h(considerably)e(less)g(if)g(y)m(ou)g(don't)g
+(compile)150 5340 y(with)e(debugging)g(sym)m(b)s(ols\).)p
+eop end
+%%Page: 9 11
+TeXDict begin 9 10 bop 150 -116 a Ft(Chapter)30 b(9:)41
+b(Common)30 b(problems)2341 b(9)150 299 y Fs(8.1)68 b(What)45
+b(else)h(do)f(I)g(need?)150 458 y Ft(T)-8 b(o)32 b(compile)g(Octa)m(v)m
+(e,)h(y)m(ou)f(will)f(need)g(a)h(recen)m(t)g(v)m(ersion)g(of)f(GNU)h
+(Mak)m(e.)44 b(Y)-8 b(ou)32 b(will)f(also)h(need)f(GCC)150
+568 y(3.3)g(or)g(later,)g(although)g(GCC)f(4.1)i(or)e(later)h(is)g
+(recommended.)275 754 y Fg(Y)-8 b(ou)31 b(m)m(ust)h(ha)m(v)m(e)h(GNU)f
+(Mak)m(e)h(to)g(compile)g(o)s(cta)m(v)m(e)p Ft(.)47 b(Octa)m(v)m(e's)34
+b(Mak)m(e\014les)g(use)d(features)h(of)g(GNU)150 863
+y(Mak)m(e)f(that)f(are)f(not)h(presen)m(t)f(in)g(other)g(v)m(ersions)h
+(of)f(mak)m(e.)41 b(GNU)30 b(Mak)m(e)h(is)e(v)m(ery)h(p)s(ortable)f
+(and)f(easy)150 973 y(to)j(install.)150 1283 y Fs(8.2)68
+b(Can)45 b(I)g(compile)h(Octa)l(v)l(e)g(with)f(another)h(C)p
+Fj(++)e Fs(compiler?)150 1442 y Ft(Y)-8 b(es,)32 b(but)f(dev)m(elopmen)
+m(t)h(is)g(done)f(primarily)f(with)h(GCC,)g(so)h(y)m(ou)f(ma)m(y)h(hit)
+f(some)h(incompatibilities.)150 1552 y(Octa)m(v)m(e)j(is)e(in)m(tended)
+g(to)h(b)s(e)e(p)s(ortable)h(to)h(an)m(y)f(standard)g(conforming)g
+(compiler.)49 b(If)33 b(y)m(ou)g(ha)m(v)m(e)h(di\016-)150
+1661 y(culties)d(that)f(y)m(ou)h(think)e(are)i(bugs,)e(please)i(rep)s
+(ort)e(them)h(to)h(the)f Fq(bug at octave.org)c Ft(mailing)31
+b(list,)g(or)150 1771 y(ask)g(for)f(help)g(on)g(the)h
+Fq(help at octave.org)26 b Ft(mailing)31 b(list.)150 2156
+y Fp(9)80 b(Common)54 b(problems)150 2545 y Ft(This)25
+b(list)h(is)g(probably)f(far)h(to)s(o)g(short.)39 b(F)-8
+b(eel)28 b(free)e(to)g(suggest)h(additional)g(questions)f(\(preferably)
+f(with)150 2655 y(answ)m(ers!\))225 2841 y Fk(\017)60
+b Ft(Octa)m(v)m(e)33 b(tak)m(es)e(a)g(long)g(time)g(to)g(\014nd)e(sym)m
+(b)s(ols.)330 3001 y(Octa)m(v)m(e)e(uses)e(the)g Fq(genpath)e
+Ft(function)i(to)g(recursiv)m(ely)h(add)e(directories)i(to)g(the)f
+(list)h(of)f(directories)330 3110 y(searc)m(hed)j(for)f(function)g
+(\014les.)40 b(Chec)m(k)28 b(the)g(list)g(of)f(directories)i(with)e
+(the)h Fq(path)e Ft(command.)40 b(If)27 b(the)330 3220
+y(path)j(list)h(is)g(v)m(ery)f(long)h(c)m(hec)m(k)h(y)m(our)f(use)f(of)
+g(the)h Fq(genpath)d Ft(function.)225 3380 y Fk(\017)60
+b Ft(When)41 b(plotting)h(Octa)m(v)m(e)i(o)s(ccasionally)f(giv)m(es)g
+(me)e(errors)g(lik)m(e)i(`)p Fq(gnuplot>)28 b(9)i(0.735604)e(line)330
+3490 y(26317:)h(invalid)f(command)p Ft('.)330 3650 y(There)52
+b(is)h(a)g(kno)m(wn)f(bug)g(in)h(gn)m(uplot)g(4.2)h(that)f(can)g(cause)
+g(an)g(o\013)g(b)m(y)g(one)g(error)f(while)330 3760 y(piping)67
+b(data)h(to)g(gn)m(uplot.)152 b(The)67 b(relev)-5 b(an)m(t)69
+b(gn)m(uplot)e(bug)g(rep)s(ort)g(can)g(b)s(e)g(found)f(at)330
+3869 y Fq(http://sourceforge.net/t)o(rack)o(er/i)o(nde)o(x.ph)o(p?fu)o
+(nc=)o(deta)o(il&a)o(id=)o(1716)o(556&)o(gro)o(up_)330
+3979 y(id=2055&atid=102055)330 4139 y Ft(If)33 b(y)m(ou)h(ha)m(v)m(e)h
+(obtained)e(y)m(our)h(cop)m(y)g(of)g(Octa)m(v)m(e)h(from)e(a)h
+(distribution)f(please)h(\014le)g(a)g(bug)f(rep)s(ort)330
+4249 y(requesting)e(that)g(the)f(\014x)g(rep)s(orted)g(in)g(the)g(ab)s
+(o)m(v)m(e)i(bug)e(rep)s(ort)f(b)s(e)h(included.)225
+4409 y Fk(\017)60 b Ft(I)30 b(cannot)h(install)g(a)g(pac)m(k)-5
+b(age.)43 b(Octa)m(v)m(e)32 b(complains)f(ab)s(out)f(a)h(missing)f
+Fq(mkoctfile)p Ft(.)330 4569 y(Most)38 b(distributions)f(split)g(Octa)m
+(v)m(e)i(in)m(to)g(sev)m(eral)f(pac)m(k)-5 b(ages.)63
+b(The)37 b(script)g Fq(mkoctfile)e Ft(is)i(then)330 4679
+y(part)30 b(of)h(a)g(separate)g(pac)m(k)-5 b(age:)379
+4839 y Fk(\000)60 b Ft(Debian/Ubun)m(tu)510 4999 y Fq(aptitude)28
+b(install)h(octave3.0-headers)379 5160 y Fk(\000)60 b
+Ft(F)-8 b(edora)510 5320 y Fq(yum)29 b(install)g(octave-devel)p
+eop end
+%%Page: 10 12
+TeXDict begin 10 11 bop 150 -116 a Ft(Chapter)30 b(11:)41
+b(P)m(orting)32 b(programs)e(from)g Fo(Ma)-6 b(tlab)28
+b Ft(to)j(Octa)m(v)m(e)1294 b(10)150 299 y Fp(10)80 b(Ho)l(w)53
+b(do)g(I)h(...?)150 584 y Fs(10.1)68 b(Ho)l(w)46 b(do)f(I)g(set)g(the)g
+(n)l(um)l(b)t(er)g(of)g(displa)l(y)l(ed)h(decimals?)390
+744 y Fq(octave:1>)f(format)h(long)390 853 y(octave:2>)f(pi)390
+963 y(pi)i(=)h(3.14159265358979)390 1073 y(octave:3>)d(format)h(short)
+390 1182 y(octave:4>)f(pi)390 1292 y(pi)i(=)h(3.1416)150
+1559 y Fp(11)80 b(P)l(orting)52 b(programs)i(from)g Ff(Ma)-10
+b(tlab)53 b Fp(to)h(Octa)l(v)l(e)150 1754 y Ft(P)m(eople)32
+b(often)e(ask)275 1881 y(\\I)k(wrote)i(some)f(co)s(de)g(for)f
+Fo(Ma)-6 b(tlab)p Ft(,)35 b(and)f(I)g(w)m(an)m(t)i(to)f(get)h(it)f
+(running)e(under)g(Octa)m(v)m(e.)56 b(Is)35 b(there)150
+1990 y(an)m(ything)c(I)f(should)f(w)m(atc)m(h)j(out)f(for?")275
+2117 y(or)f(alternativ)m(ely)275 2244 y(\\I)22 b(wrote)g(some)g(co)s
+(de)g(in)g(Octa)m(v)m(e,)k(and)21 b(w)m(an)m(t)i(to)f(share)g(it)g
+(with)g Fo(Ma)-6 b(tlab)20 b Ft(users.)37 b(Is)21 b(there)i(an)m
+(ything)150 2353 y(I)30 b(should)g(w)m(atc)m(h)h(out)g(for?")275
+2480 y(whic)m(h)43 b(is)g(not)h(quite)g(the)g(same)f(thing.)81
+b(There)43 b(are)g(still)i(a)f(n)m(um)m(b)s(er)e(of)i(di\013erences)f
+(b)s(et)m(w)m(een)150 2590 y(Octa)m(v)m(e)h(and)e Fo(Ma)-6
+b(tlab)p Ft(,)44 b(ho)m(w)m(ev)m(er)f(in)f(general)i(di\013erences)e(b)
+s(et)m(w)m(een)h(the)f(t)m(w)m(o)i(are)f(considered)f(as)150
+2699 y(bugs.)71 b(Octa)m(v)m(e)42 b(migh)m(t)g(consider)e(that)i(the)e
+(bug)g(is)h(in)f Fo(Ma)-6 b(tlab)39 b Ft(and)h(do)h(nothing)f(ab)s(out)
+h(it,)j(but)150 2809 y(generally)29 b(functionalit)m(y)g(is)f(almost)h
+(iden)m(tical.)41 b(If)27 b(y)m(ou)h(\014nd)e(a)j(di\013erence)f(b)s
+(et)m(w)m(een)g(Octa)m(v)m(e)i(b)s(eha)m(vior)150 2919
+y(and)i Fo(Ma)-6 b(tlab)p Ft(,)32 b(then)g(y)m(ou)h(should)e(send)h(a)h
+(description)f(of)h(this)g(di\013erence)g(\(with)f(co)s(de)h
+(illustrating)150 3028 y(the)e(di\013erence,)g(if)f(p)s(ossible\))g(to)
+h Fq(bug at octave.org)p Ft(.)275 3155 y(F)-8 b(urthermore,)27
+b(Octa)m(v)m(e)h(adds)d(a)h(few)g(syn)m(tactical)i(extensions)f(to)g
+(Matlab)g(that)f(migh)m(t)h(cause)g(some)150 3264 y(issues)i(when)f
+(exc)m(hanging)i(\014les)f(b)s(et)m(w)m(een)h(Matlab)h(and)d(Octa)m(v)m
+(e)j(users.)40 b(As)29 b(b)s(oth)f(Octa)m(v)m(e)k(and)c
+Fo(Ma)-6 b(t-)150 3374 y(lab)28 b Ft(are)h(under)e(constan)m(t)i(dev)m
+(elopmen)m(t)h(the)f(information)g(in)f(this)h(section)g(is)g(sub)5
+b(ject)28 b(to)i(c)m(hange)f(at)150 3484 y(an)m(ytime.)275
+3610 y(Y)-8 b(ou)43 b(should)f(also)i(lo)s(ok)g(at)g(the)f(page)h
+Fq(http://octave.sourcefor)o(ge.n)o(et/p)o(ack)o(ages)o(.htm)o(l)150
+3720 y Ft(and)39 b Fq(http://octave.sourceforge.)o(net/)o(doc)o(/)34
+b Ft(that)41 b(has)f(a)g(function)g(reference)g(that)h(is)f(up)f(to)150
+3830 y(date.)64 b(Y)-8 b(ou)39 b(can)f(use)g(this)g(function)g
+(reference)g(to)h(see)g(the)f(n)m(um)m(b)s(er)e(of)j(o)s(cta)m(v)m(e)h
+(function)e(that)h(are)150 3939 y(a)m(v)-5 b(ailable)33
+b(and)d(their)g Fo(Ma)-6 b(tlab)29 b Ft(compatibilit)m(y)-8
+b(.)275 4066 y(The)29 b(ma)5 b(jor)31 b(di\013erences)f(b)s(et)m(w)m
+(een)h(Octa)m(v)m(e)i(3.2.N)f(and)e Fo(Ma)-6 b(tlab)29
+b Ft(R2008a)j(are:)225 4193 y Fk(\017)60 b Ft(Nested)31
+b(F)-8 b(unctions)330 4319 y(Octa)m(v)m(e)33 b(do)s(esn't)d(y)m(et)h
+(ha)m(v)m(e)h(nested)e(functions.)40 b(That)31 b(is)570
+4446 y Fq(function)46 b(y)h(=)g(foo)g(\(x\))665 4556
+y(y)h(=)f(bar\(x\))665 4665 y(function)f(y)h(=)h(bar)f(\(x\))761
+4775 y(y)g(=)h(...)o(;)665 4884 y(end)570 4994 y(end)330
+5121 y Ft(There)24 b(w)m(as)i(discussion)e(in)g(Octa)m(v)m(e)j(of)e(ha)
+m(ving)h(these)f(ev)m(en)h(prior)e(to)h Fo(Ma)-6 b(tlab)p
+Ft(,)25 b(and)f(the)h(decision)330 5230 y(w)m(as)i(made)g(not)g(to)g
+(ha)m(v)m(e)h(these)f(in)f(Octa)m(v)m(e)j(at)e(the)g(time)g(for)g
+(compatibilit)m(y)-8 b(.)42 b(The)26 b(ab)s(o)m(v)m(e)i(written)330
+5340 y(with)i(sub-functions)f(functions)h(w)m(ould)g(b)s(e)p
+eop end
+%%Page: 11 13
+TeXDict begin 11 12 bop 150 -116 a Ft(Chapter)30 b(11:)41
+b(P)m(orting)32 b(programs)e(from)g Fo(Ma)-6 b(tlab)28
+b Ft(to)j(Octa)m(v)m(e)1294 b(11)570 299 y Fq(function)46
+b(y)h(=)g(foo)g(\(x\))713 408 y(y)h(=)f(bar\(x\))570
+518 y(end)570 628 y(function)f(y)h(=)g(bar)g(\(x\))713
+737 y(y)h(=)f(...)o(;)570 847 y(end)330 978 y Ft(No)m(w)25
+b(that)h Fo(Ma)-6 b(tlab)23 b Ft(has)h(recen)m(tly)i(in)m(tro)s(duced)e
+(nested)h(functions,)g(Octa)m(v)m(e)i(will)e(probably)f(ha)m(v)m(e)330
+1088 y(them)31 b(so)s(on)g(as)h(w)m(ell.)45 b(Un)m(til)32
+b(then)f(nested)g(functions)g(in)g(Octa)m(v)m(e)j(are)d(treated)i(as)e
+(sub-functions)330 1198 y(with)f(the)h(same)f(scoping)h(rules)f(as)h
+(sub-functions.)330 1329 y(The)26 b(authors)h(of)g(Octa)m(v)m(e)i
+(consider)e(the)g(nested)g(function)g(scoping)g(rules)g(of)g(Matlab)h
+(to)f(b)s(e)g(more)330 1439 y(problems)33 b(than)g(they)h(are)g(w)m
+(orth)f(as)h(they)f(in)m(tro)s(duce)h(di\016ult)f(to)h(\014nd)e(bugs)h
+(as)g(inadv)m(ertan)m(tly)330 1548 y(mo)s(difying)28
+b(a)h(v)-5 b(ariable)30 b(in)e(a)h(nested)g(function)f(that)h(is)g
+(also)h(used)e(in)g(the)h(paren)m(t)g(is)f(particularly)330
+1658 y(easy)-8 b(.)225 1789 y Fk(\017)60 b Ft(Di\013erences)28
+b(in)e(core)i(syn)m(tax)f(There)f(a)h(few)g(core)g Fo(Ma)-6
+b(tlab)25 b Ft(syn)m(taxes)j(that)f(are)g(not)g(accepted)h(b)m(y)330
+1899 y(Octa)m(v)m(e,)33 b(these)e(b)s(eing)405 2030 y
+Fk(\017)60 b Ft(Some)34 b(limitations)i(on)f(the)f(use)g(of)h(function)
+f(handles.)52 b(The)34 b(ma)5 b(jor)34 b(di\013erence)h(is)f(related)
+510 2140 y(to)d(nested)f(function)h(scoping)f(rules)g(\(as)h(ab)s(o)m
+(v)m(e\))h(and)e(their)g(use)g(with)g(function)g(handles.)405
+2271 y Fk(\017)60 b Ft(Some)34 b(limitations)i(of)e(v)-5
+b(ariable)34 b(argumen)m(t)h(lists)f(on)g(the)g(LHS)f(of)i(an)e
+(expression,)i(though)510 2381 y(the)c(most)f(common)h(t)m(yp)s(es)f
+(are)h(accepted.)405 2513 y Fk(\017)60 b Fo(Ma)-6 b(tlab)24
+b Ft(classdef)h(ob)5 b(ject)26 b(orien)m(ted)g(programming)f(is)g(not)h
+(y)m(et)g(supp)s(ortted,)f(though)g(w)m(ork)510 2622
+y(is)j(underw)m(a)m(y)f(and)h(when)f(dev)m(elopmen)m(t)i(more)f(on)g
+(to)h(Octa)m(v)m(e)h(3.3)f(this)e(will)i(b)s(e)e(included)g(in)510
+2732 y(teh)k(dev)m(elopmen)m(t)g(tree.)225 2863 y Fk(\017)60
+b Ft(Di\013erences)36 b(in)e(core)h(functions)f(A)h(large)h(n)m(um)m(b)
+s(er)d(of)i(the)g Fo(Ma)-6 b(tlab)32 b Ft(core)k(functions)e(\(ie)h
+(those)330 2973 y(that)45 b(are)g(in)f(the)h(core)g(and)f(not)g(a)h(to)
+s(olb)s(o)m(x\))h(are)f(implemen)m(ted,)j(and)c(certainly)i(all)f(of)g
+(the)330 3082 y(commonly)31 b(used)f(ones.)41 b(There)31
+b(are)g(a)g(few)f(functions)g(that)h(aren't)g(implemen)m(ted,)h(for)e
+(example)330 3192 y Fq(condest)23 b Ft(or)i(to)h(do)f(with)g(sp)s
+(eci\014c)f(missing)h(Octa)m(v)m(e)j(functionalit)m(y)e(\(gui,)h(dll,)f
+(ja)m(v)-5 b(a,)28 b(activ)m(ex,)g(dde,)330 3302 y(w)m(eb,)34
+b(and)f(serial)h(functions\).)50 b(Some)33 b(of)h(the)g(core)g
+(functions)f(ha)m(v)m(e)h(limitations)h(that)f(aren't)g(in)330
+3411 y(the)40 b Fo(Ma)-6 b(tlab)38 b Ft(v)m(ersion.)69
+b(F)-8 b(or)41 b(example)f(the)g Fq(sprandn)e Ft(function)h(can)h(not)g
+(force)h(a)f(particular)330 3521 y(condition)31 b(n)m(um)m(b)s(er)e
+(for)h(the)h(matrix)f(lik)m(e)i Fo(Ma)-6 b(tlab)29 b
+Ft(can.)225 3652 y Fk(\017)60 b Ft(Just-In-Time)40 b(compiler)h
+Fo(Ma)-6 b(tlab)39 b Ft(includes)h(a)h Fq(")p Ft(Just-In-Time)p
+Fq(")f Ft(compiler.)72 b(This)39 b(compiler)330 3762
+y(allo)m(ws)68 b(the)f(acceleration)i(of)e(for-lo)s(ops)g(in)f
+Fo(Ma)-6 b(tlab)65 b Ft(to)i(almost)h(nativ)m(e)g(p)s(erformance)330
+3871 y(with)55 b(certain)h(restrictions.)116 b(The)55
+b(JIT)f(m)m(ust)h(kno)m(w)g(the)h(return)e(t)m(yp)s(e)h(of)g(all)h
+(functions)330 3981 y(called)g(in)f(the)g(lo)s(ops)g(and)f(so)h(y)m(ou)
+h(can't)f(include)g(user)f(functions)h(in)g(the)g(lo)s(op)g(of)g(JIT)
+330 4091 y(optimized)c(lo)s(ops.)99 b(Octa)m(v)m(e)53
+b(do)s(esn't)c(ha)m(v)m(e)j(a)e(JIT)f(and)g(so)i(to)f(some)h(migh)m(t)f
+(seem)h(slo)m(w)m(er)330 4200 y(than)42 b Fo(Ma)-6 b(tlab)p
+Ft(.)74 b(F)-8 b(or)42 b(this)g(reason)h(y)m(ou)f(m)m(ust)g(v)m
+(ectorize)i(y)m(our)e(co)s(de)h(as)f(m)m(uc)m(h)g(as)g(p)s(ossible.)330
+4310 y(The)64 b(MathW)-8 b(orks)66 b(themselv)m(es)g(ha)m(v)m(e)g(a)f
+(go)s(o)s(d)f(do)s(cumen)m(t)g(discussing)g(v)m(ectorization)k(at)330
+4419 y Fq(http://www.mathworks.com)o(/sup)o(port)o(/te)o(ch-n)o(otes)o
+(/11)o(00/1)o(109.)o(htm)o(l)p Ft(.)225 4551 y Fk(\017)60
+b Ft(Compiler)23 b(On)g(a)g(related)i(p)s(oin)m(t,)g(there)e(is)h(no)f
+(Octa)m(v)m(e)i(compiler,)h(and)d(so)g(y)m(ou)h(can't)g(con)m(v)m(ert)h
+(y)m(our)330 4661 y(Octa)m(v)m(e)39 b(co)s(de)d(in)m(to)i(a)f(binary)e
+(for)i(additional)g(sp)s(eed)f(or)g(distribution.)58
+b(There)36 b(is)h(an)f(example)330 4770 y(of)f(ho)m(w)g(to)h(do)f(this)
+g(at)g Fq(http://www.stud.tu-ilmena)o(u.de)o(/~r)o(ueck)o(n/)p
+Ft(,)30 b(but)k(this)h(is)g(a)h(v)m(ery)330 4880 y(early)31
+b(example)g(co)s(de)g(and)e(w)m(ould)i(need)f(lots)h(of)f(w)m(ork)h(to)
+g(complete)h(it.)225 5011 y Fk(\017)60 b Ft(Graphic)23
+b(Handles)g(Up)g(to)h(Octa)m(v)m(e)h(2.9.9)g(there)e(w)m(as)h(no)f
+(supp)s(ort)e(for)i(graphic)g(handles)g(in)g(Octa)m(v)m(e)330
+5121 y(itself.)55 b(In)34 b(the)h(3.2.N)h(v)m(ersions)f(of)g(Octa)m(v)m
+(e)i(the)e(supp)s(ort)f(for)g(graphics)h(handles)f(is)h(con)m(v)m
+(erging)330 5230 y(to)m(w)m(ards)27 b(full)g(compatibilit)m(y)-8
+b(.)42 b(The)26 b Fq(patch)f Ft(function)h(is)h(curren)m(tly)g(limited)
+g(to)g(2-D)h(patc)m(hes,)h(due)330 5340 y(to)i(an)f(underlying)g
+(limitation)i(in)e(gn)m(uplot.)p eop end
+%%Page: 12 14
+TeXDict begin 12 13 bop 150 -116 a Ft(Chapter)30 b(11:)41
+b(P)m(orting)32 b(programs)e(from)g Fo(Ma)-6 b(tlab)28
+b Ft(to)j(Octa)m(v)m(e)1294 b(12)225 299 y Fk(\017)60
+b Ft(GUI)35 b(There)g(are)g(no)g Fo(Ma)-6 b(tlab)34 b
+Ft(compatible)i(GUI)g(functions.)54 b(There)35 b(are)g(a)h(n)m(um)m(b)s
+(er)e(of)h(bind-)330 408 y(ings)43 b(from)g(Octa)m(v)m(e)i(to)e
+(Tcl/Tk,)k(Vtk)d(and)e(zenit)m(y)i(included)f(in)f(the)i(Octa)m(v)m(e)h
+(F)-8 b(orge)44 b(pro)5 b(ject)330 518 y(\()p Fq
+(http://octave.sourceforge.)o(net)o Ft(\))19 b(for)24
+b(example)h(that)g(can)f(b)s(e)g(used)f(for)h(a)h(GUI,)g(but)e(these)
+330 628 y(are)33 b(not)f Fo(Ma)-6 b(tlab)31 b Ft(compatible.)48
+b(W)-8 b(ork)33 b(on)f(a)h(matlab)g(compatible)h(GUI)e(is)h(in)f(an)g
+(alpha)g(stage)330 737 y(in)c(the)g(JHandles)g(pac)m(k)-5
+b(age)30 b(\()p Fq(http://octave.sourceforge.n)o(et/j)o(han)o(dles)o
+(/ind)o(ex.)o(html)o Ft(\).)330 847 y(This)g(migh)m(t)h(b)s(e)e(an)i
+(issue)f(if)g(y)m(ou)h(in)m(tend)f(to)h(exc)m(hange)h(Octa)m(v)m(e)h
+(co)s(de)d(with)g Fo(Ma)-6 b(tlab)29 b Ft(users.)225
+977 y Fk(\017)60 b Ft(Sim)m(ulink)37 b(Octa)m(v)m(e)k(itself)d
+(includes)g(no)g(Sim)m(ulink)f(supp)s(ort.)62 b(T)m(ypically)39
+b(the)f(sim)m(ulink)g(mo)s(dels)330 1087 y(lag)j(researc)m(h)g(and)f
+(are)g(less)h(\015exible,)i(so)d(shouldn't)f(really)i(b)s(e)f(used)f
+(in)h(a)h(researc)m(h)g(en)m(viron-)330 1197 y(men)m(t.)g(Ho)m(w)m(ev)m
+(er,)33 b(some)e Fo(Ma)-6 b(tlab)28 b Ft(users)i(that)h(try)f(to)h(use)
+f(Octa)m(v)m(e)j(complain)e(ab)s(out)f(this)g(lac)m(k.)330
+1306 y(There)44 b(is)h(a)g(similar)g(pac)m(k)-5 b(age)47
+b(to)e(sim)m(ulink)g(for)f(the)h(Octa)m(v)m(e)i(and)d(R)h(pro)5
+b(jects)45 b(a)m(v)-5 b(ailable)47 b(at)330 1416 y Fq
+(http://www.scicraft.org/)225 1546 y Fk(\017)60 b Ft(Mex-Files)32
+b(Octa)m(v)m(e)g(includes)e(an)g(API)g(to)g(the)h(matlab)f(MEX)h(in)m
+(terface.)42 b(Ho)m(w)m(ev)m(er,)32 b(as)f(MEX)f(is)330
+1656 y(an)j(API)g(to)h(the)g(in)m(ternals)g(of)f Fo(Ma)-6
+b(tlab)32 b Ft(and)g(the)i(in)m(ternals)g(of)f(Octa)m(v)m(e)i(di\013er)
+e(from)g Fo(Ma)-6 b(tlab)p Ft(,)330 1766 y(there)40 b(is)f(necessarily)
+i(a)f(manipulation)f(of)h(the)g(data)g(to)g(con)m(v)m(ert)h(from)e(a)h
+(MEX)g(in)m(terface)h(to)330 1875 y(the)29 b(Octa)m(v)m(e)j(equiv)-5
+b(alen)m(t.)42 b(This)28 b(is)h(notable)h(for)f(all)h(complex)g
+(matrices,)h(where)e Fo(Ma)-6 b(tlab)27 b Ft(stores)330
+1985 y(complex)42 b(arra)m(ys)g(as)f(real)h(and)f(imaginary)h(parts,)i
+(whereas)d(Octa)m(v)m(e)i(resp)s(ects)e(the)h(C99/C)p
+Fq(++)330 2094 y Ft(standards)27 b(of)h(co-lo)s(cating)j(the)e
+(real/imag)h(parts)e(in)g(memory)-8 b(.)40 b(Also)29
+b(due)e(to)i(the)f(w)m(a)m(y)i Fo(Ma)-6 b(tlab)330 2204
+y Ft(allo)m(ws)31 b(access)f(to)g(the)g(arra)m(ys)g(passed)f(through)f
+(a)i(p)s(oin)m(ter,)g(the)g(MEX)f(in)m(terface)i(migh)m(t)f(require)330
+2314 y(copies)h(of)g(arra)m(ys)f(\(ev)m(en)i(non)e(complex)h(ones\).)
+225 2444 y Fk(\017)60 b Ft(Blo)s(c)m(k)34 b(commen)m(ts)f(Blo)s(c)m(k)g
+(commen)m(ts)g(denoted)f(b)m(y)g Fq(")p Ft(\045)p Fq({")f
+Ft(and)h Fq(")p Ft(\045)p Fq(}")f Ft(mark)m(ers)h(are)h(supp)s(orted)
+330 2554 y(b)m(y)26 b(Octa)m(v)m(e)j(with)d(some)h(limitations.)41
+b(The)27 b(ma)5 b(jor)26 b(limitation)i(is)f(that)g(blo)s(c)m(k)g
+(commen)m(ts)h(are)f(not)330 2663 y(supp)s(orted)i(within)g([])i(or)g
+Fq({})p Ft(.)225 2794 y Fk(\017)60 b Ft(Mat-File)47 b(format)d(There)g
+(are)g(some)h(di\013erences)f(in)g(the)h(mat)f(v5)h(\014le)f(format)h
+(accepted)g(b)m(y)330 2904 y(Octa)m(v)m(e.)40 b Fo(Ma)-6
+b(tlab)21 b Ft(recen)m(tly)j(in)m(tro)s(duced)e(the)h
+Fq(")p Ft(-V7.3)p Fq(")g Ft(sa)m(v)m(e)h(option)f(whic)m(h)g(is)f(an)h
+(HDF5)h(format)330 3013 y(whic)m(h)j(is)h(particularly)g(useful)f(for)g
+(64-bit)i(platforms)f(where)f(the)h(standard)e(matlab)j(format)f(can)
+330 3123 y(not)d(correctly)h(sa)m(v)m(e)g(v)-5 b(ariables..)40
+b(Octa)m(v)m(e)27 b(accepts)f(HDF5)g(\014les,)g(but)f(is)f(not)h(y)m
+(et)h(compatible)g(with)330 3232 y(the)31 b Fq(")p Ft(-v7.3)p
+Fq(")g Ft(v)m(ersions)f(pro)s(duced)f(b)m(y)h Fo(Ma)-6
+b(tlab)p Ft(.)330 3363 y(Although)36 b(Octa)m(v)m(e)i(can)e(load)h
+(inline)f(ab)s(d)f(function)g(handles)g(sa)m(v)m(ed)i(b)m(y)f
+Fo(Ma)-6 b(tlab)p Ft(,)36 b(it)h(can)f(not)330 3473 y(y)m(et)c(sa)m(v)m
+(e)f(them.)330 3603 y(Finally)-8 b(,)32 b(Some)e(m)m(ulti-b)m(yte)i
+(unico)s(de)e(c)m(haracters)i(aren't)f(y)m(et)g(treated)h(in)e
+(mat-\014les.)225 3734 y Fk(\017)60 b Ft(Pro\014ler)28
+b(Octa)m(v)m(e)i(do)s(esn't)e(ha)m(v)m(e)h(a)g(pro\014ler.)39
+b(Though)27 b(there)i(is)f(a)h(patc)m(h)f(for)g(a)h(\015at)f
+(pro\014ler,)g(that)330 3843 y(migh)m(t)j(b)s(ecome)g(a)g(real)g
+(pro\014ler)e(sometime)j(in)e(the)g(future.)40 b(see)31
+b(the)g(thread)330 3974 y Fq(http://www.cae.wisc.edu/)o(pipe)o(rmai)o
+(l/o)o(ctav)o(e-ma)o(int)o(aine)o(rs/2)o(007)o(-Jan)o(uary)o(/00)o
+(1685)o(.htm)o(l)p 4011 3994 42 84 v 330 4105 a Ft(for)f(more)h
+(details)225 4235 y Fk(\017)60 b Ft(T)-8 b(o)s(olb)s(o)m(xes)77
+b(Octa)m(v)m(e)i(is)d(a)h(comm)m(unit)m(y)g(pro)5 b(ject)77
+b(and)f(so)g(the)h(to)s(olb)s(o)m(xes)g(that)g(exist)330
+4345 y(are)72 b(donated)g(b)m(y)f(those)i(in)m(terested)f(in)g(them)f
+(through)g(the)h(Octa)m(v)m(e)i(F)-8 b(orge)73 b(w)m(ebsite)330
+4454 y(\()p Fq(http://octave.sourceforge.)o(net)o Ft(\).)46
+b(These)34 b(migh)m(t)h(b)s(e)e(lac)m(king)j(in)e(certain)g
+(functionalit)m(y)330 4564 y(relativ)m(e)57 b(to)f(the)g
+Fo(Ma)-6 b(tlab)54 b Ft(to)s(olb)s(o)m(xes,)63 b(and)54
+b(migh)m(t)i(not)g(exactly)h(duplicate)f(the)f(matlab)330
+4674 y(functionalit)m(y)32 b(or)e(in)m(terface.)225 4804
+y Fk(\017)60 b Ft(Short-circuit)31 b(&)f(and)g Fq(|)g
+Ft(op)s(erators)g(The)g Fq(&)g Ft(and)g Fq(|)g Ft(op)s(erators)h(in)f
+Fo(Ma)-6 b(tlab)29 b Ft(short-circuit)i(when)330 4914
+y(included)37 b(in)h(an)g(if)g(stateman)m(t)h(and)f(not)g(otherwise.)64
+b(In)37 b(Octa)m(v)m(e)j(only)e(the)g Fq(&&)g Ft(and)f
+Fq(||)g Ft(short)330 5023 y(circuit.)k(Note)32 b(that)f(this)f(means)h
+(that)665 5154 y Fq(if)48 b(\(a)f(|)g(b\))761 5264 y(...)665
+5373 y(end)p eop end
+%%Page: 13 15
+TeXDict begin 13 14 bop 150 -116 a Ft(Chapter)30 b(11:)41
+b(P)m(orting)32 b(programs)e(from)g Fo(Ma)-6 b(tlab)28
+b Ft(to)j(Octa)m(v)m(e)1294 b(13)330 299 y(and)665 428
+y Fq(t)48 b(=)f(a)h(|)f(b;)665 537 y(if)h(t)761 647 y(...)665
+757 y(end)330 886 y Ft(are)27 b(di\013eren)m(t)h(in)f
+Fo(Ma)-6 b(tlab)p Ft(.)38 b(This)26 b(is)h(really)h(a)g
+Fo(Ma)-6 b(tlab)25 b Ft(bug,)j(but)e(there)h(is)g(to)s(o)h(m)m(uc)m(h)f
+(co)s(de)h(out)330 995 y(there)35 b(that)g(relies)h(on)f(this)f(b)s
+(eha)m(vior)h(to)h(c)m(hange)g(it.)54 b(Prefer)35 b(the)g
+Fq(||)f Ft(and)g(&&)g(op)s(erators)h(in)g(if)330 1105
+y(statemen)m(ts)d(if)e(p)s(ossible.)330 1234 y(Note)e(that)f(the)g
+(di\013erence)h(is)e(also)i(signi\014can)m(t)g(when)e(either)h(argumen)
+m(t)g(is)g(a)g(function)g(with)f(side)330 1343 y(e\013ects)j(or)e(if)h
+(the)f(\014rst)g(argumen)m(t)h(is)f(a)h(scalar)h(and)e(the)g(second)h
+(argumen)m(t)g(is)f(an)g(empt)m(y)h(matrix.)330 1453
+y(F)-8 b(or)31 b(example,)g(note)g(the)g(di\013erence)g(b)s(et)m(w)m
+(een)665 1582 y Fq(t)48 b(=)f(1)h(|)f([];)477 b(##)47
+b(results)f(in)h([],)g(so...)665 1691 y(if)h(\(t\))f(1,)g(end)381
+b(##)47 b(in)g(if)g(\([]\),)g(this)f(is)h(false.)330
+1820 y Ft(and)665 1949 y Fq(if)h(\(1)f(|)g([]\))g(1,)g(end)143
+b(##)47 b(short)f(circuits)g(so)h(condition)e(is)i(true.)330
+2078 y Ft(Another)30 b(case)i(that)f(is)f(do)s(cumen)m(ted)g(in)g(the)h
+Fo(Ma)-6 b(tlab)29 b Ft(man)m(uals)h(is)h(that)665 2207
+y Fq(t)48 b(=)f([1,)g(1])g(|)h([1,)f(2,)g(3];)476 b(##)48
+b(error)665 2317 y(if)g(\([1,)e(1])h(|)h([1,)f(2,)g(3]\))g(1,)g(end)142
+b(##)48 b(OK)330 2446 y Ft(Also)29 b Fo(Ma)-6 b(tlab)26
+b Ft(requires)h(the)h(op)s(erands)f(of)h(&&)f(and)g Fq(||)g
+Ft(to)i(b)s(e)e(scalar)i(v)-5 b(alues)28 b(but)f(Octa)m(v)m(e)j(do)s
+(es)330 2555 y(not)k(\(it)h(just)e(applies)h(the)g(rule)g(that)g(for)g
+(an)g(op)s(erand)e(to)j(b)s(e)e(considered)h(true,)h(ev)m(ery)f(elemen)
+m(t)330 2665 y(of)d(the)f(ob)5 b(ject)31 b(m)m(ust)g(b)s(e)e(nonzero)i
+(or)f(logically)j(true\).)330 2794 y(Finally)-8 b(,)32
+b(note)f(the)g(inconsistence)h(of)f(thinking)f(of)h(the)f(condition)h
+(of)g(an)g(if)f(statemen)m(t)j(as)d(b)s(eing)330 2903
+y(equiv)-5 b(alen)m(t)27 b(to)f Fq(all\(X\(:\)\))d Ft(when)h
+Fi(X)35 b Ft(is)25 b(a)h(matrix.)40 b(This)24 b(is)i(true)f(for)g(all)h
+(cases)h(EX)m(CEPT)e(empt)m(y)330 3013 y(matrices:)665
+3142 y Fq(if)48 b(\([0,)e(1]\))h(==)g(if)h(\(all)e(\([0,)h(1]\)\))142
+b(==>)95 b(i.e.,)46 b(condition)f(is)i(false.)665 3251
+y(if)h(\([1,)e(1]\))h(==)g(if)h(\(all)e(\([1,)h(1]\)\))142
+b(==>)95 b(i.e.,)46 b(condition)f(is)i(true.)330 3380
+y Ft(Ho)m(w)m(ev)m(er,)665 3509 y Fq(if)h(\([]\))e(!=)h(if)h(\(all)e
+(\([]\)\))330 3638 y Ft(b)s(ecause)23 b Fq(samp)29 b(\([]\))h(==)f(1)23
+b Ft(\(b)s(ecause,)i(despite)f(the)f(name,)i(it)f(is)f(really)h
+(returning)f(true)g(if)g(none)g(of)330 3748 y(the)j(elemen)m(ts)h(of)f
+(the)g(matrix)f(are)i(zero,)g(and)e(since)h(there)g(are)g(no)g(elemen)m
+(ts,)i(w)m(ell,)g(none)d(of)h(them)330 3857 y(are)g(zero\).)40
+b(But,)27 b(somewhere)f(along)g(the)g(line,)h(someone)f(decided)g(that)
+g(if)f Fq(\([]\))g Ft(should)f(b)s(e)h(false.)330 3967
+y(Math)m(w)m(orks)39 b(probably)f(though)m(t)h(it)g(just)f(lo)s(oks)g
+(wrong)g(to)i(ha)m(v)m(e)f Fq([])f Ft(b)s(e)g(true)g(in)g(this)g(con)m
+(text)330 4076 y(ev)m(en)29 b(if)g(y)m(ou)f(can)h(use)f(logical)j
+(gymnastics)e(to)g(con)m(vince)h(y)m(ourself)f(that)g
+Fq(")p Ft(all)p Fq(")g Ft(the)f(elemen)m(ts)i(of)f(a)330
+4186 y(matrix)24 b(that)h(do)s(esn't)e(actually)j(ha)m(v)m(e)f(an)m(y)f
+(elemen)m(ts)h(are)f(nonzero.)39 b(Octa)m(v)m(e)26 b(ho)m(w)m(ev)m(er)g
+(duplicates)330 4296 y(this)k(b)s(eha)m(vior)h(for)f(if)g(statemen)m
+(ts)i(con)m(taining)g(empt)m(y)f(matrices.)225 4425 y
+Fk(\017)60 b Ft(Solv)m(ers)31 b(for)f(singular,)g(under-)g(and)f(o)m(v)
+m(er-determined)j(matrices)330 4554 y(Matlab's)27 b(solv)m(ers)f(as)g
+(used)f(b)m(y)g(the)h(op)s(erators)g(mldivide)f(\()p
+Fq(\\)p Ft(\))h(and)f(mrdivide)f(\(/\),)k(use)e(a)f(di\013eren)m(t)330
+4663 y(approac)m(h)h(than)f(Octa)m(v)m(e's)i(in)e(the)g(case)i(of)e
+(singular,)i(under-,)e(or)g(o)m(v)m(er-determined)i(matrices.)40
+b(In)330 4773 y(the)25 b(case)g(of)g(a)f(singular)h(matrix,)h(Matlab)f
+(returns)f(the)g(result)g(giv)m(en)i(b)m(y)e(the)h(LU)f(decomp)s
+(osition,)330 4882 y(ev)m(en)h(though)e(the)h(underlying)f(solv)m(er)i
+(has)f(\015agged)h(the)f(result)g(as)g(erroneous.)38
+b(Octa)m(v)m(e)26 b(has)e(made)330 4992 y(the)d(c)m(hoice)i(of)e
+(falling)h(bac)m(k)g(to)g(a)f(minim)m(um)g(norm)f(solution)i(of)f
+(matrices)h(that)g(ha)m(v)m(e)g(b)s(een)e(\015agged)330
+5101 y(as)31 b(singular)f(whic)m(h)g(arguably)g(is)h(a)g(b)s(etter)f
+(result)g(for)g(these)h(cases.)330 5230 y(In)c(the)h(case)i(of)e
+(under-)e(or)i(o)m(v)m(er-determined)i(matrices,)g(Octa)m(v)m(e)g(con)m
+(tin)m(ues)f(to)g(use)e(a)i(minim)m(um)330 5340 y(norm)h(solution,)h
+(whereas)f(Matlab)i(uses)e(an)g(approac)m(h)h(that)f(is)h(equiv)-5
+b(alen)m(t)32 b(to)p eop end
+%%Page: 14 16
+TeXDict begin 14 15 bop 150 -116 a Ft(Chapter)30 b(11:)41
+b(P)m(orting)32 b(programs)e(from)g Fo(Ma)-6 b(tlab)28
+b Ft(to)j(Octa)m(v)m(e)1294 b(14)570 299 y Fq(function)46
+b(x)h(=)g(mldivide)f(\(A,)h(b\))665 408 y([Q,)g(R,)h(E])f(=)g(qr\(A\);)
+665 518 y(x)h(=)f([A)h(\\)f(b,)g(E\(:,)g(1:m\))f(*)i(\(R\(:,)e(1:m\))h
+(\\)g(\(Q')g(*)h(b\)\)])570 628 y(end)330 770 y Ft(While)33
+b(this)f(approac)m(h)h(is)f(certainly)i(faster)f(and)e(uses)h(less)h
+(memory)f(than)g(Octa)m(v)m(e's)j(minim)m(um)330 880
+y(norm)30 b(approac)m(h,)h(this)f(approac)m(h)g(seems)h(to)g(b)s(e)f
+(inferior)g(in)g(other)h(w)m(a)m(ys.)330 1022 y(A)k(n)m(umerical)h
+(question)f(arises:)51 b(ho)m(w)35 b(big)h(can)f(the)h(n)m(ull)f(space)
+g(comp)s(onen)m(t)h(b)s(ecome,)h(relativ)m(e)330 1132
+y(to)28 b(the)f(minim)m(um-norm)e(solution?)40 b(Can)26
+b(it)i(b)s(e)e(nicely)i(b)s(ounded,)d(or)i(can)g(it)h(b)s(e)e
+(arbitrarily)h(big?)330 1241 y(Consider)j(this)g(example:)570
+1384 y Fq(m)47 b(=)h(10;)570 1493 y(n)f(=)h(10000;)570
+1603 y(A)f(=)h(ones\(m,)e(n\))h(+)g(1e-6)g(*)g(randn\(m,n\);)570
+1713 y(b)g(=)h(ones\(m,)e(1\))h(+)g(1e-6)g(*)g(randn\(m,1\);)570
+1822 y(norm\(A)f(\\)i(b\))330 1965 y Ft(while)37 b(Octa)m(v)m(e's)j
+(minim)m(um-norm)c(v)-5 b(alues)38 b(are)g(around)e(3e-2,)41
+b(Matlab's)e(results)e(are)h(50-times)330 2074 y(larger.)j(F)-8
+b(or)32 b(another)e(issue,)h(try)f(this)g(co)s(de:)570
+2217 y Fq(m)47 b(=)h(5;)570 2326 y(n)f(=)h(100;)570 2436
+y(j)f(=)h(floor\(m)e(*)h(rand\(1,)f(n\)\))h(+)g(1;)570
+2545 y(b)g(=)h(ones\(m,)e(1\);)570 2655 y(A)h(=)h(zeros\(m,)d(n\);)570
+2765 y(A\(sub2ind\(size\(A\),j,1:n\))o(\))d(=)47 b(1;)570
+2874 y(x)g(=)h(A)f(\\)h(b;)570 2984 y([dummy,p])d(=)j
+(sort\(rand\(1,n\)\);)570 3093 y(y)f(=)h(A\(:,p\)\\b;)570
+3203 y(norm\(x\(p\)-y\))330 3345 y Ft(It)40 b(sho)m(ws)f(that)h(unlik)m
+(e)g(in)g(Octa)m(v)m(e,)k(mldivide)c(in)f(Matlab)i(is)e(not)h(in)m(v)-5
+b(arian)m(t)41 b(with)f(resp)s(ect)f(to)330 3455 y(column)k(p)s(erm)m
+(utations.)78 b(If)42 b(there)h(are)g(m)m(ultiple)h(columns)e(of)h(the)
+g(same)g(norm,)j(p)s(erm)m(uting)330 3565 y(columns)40
+b(of)g(the)h(matrix)f(gets)i(y)m(ou)e(di\013eren)m(t)h(result)f(than)g
+(p)s(erm)m(uting)g(the)g(solution)h(v)m(ector.)330 3674
+y(This)30 b(will)g(surprise)f(man)m(y)i(users.)330 3817
+y(Since)37 b(the)f(mldivide)h(\()p Fq(\\)p Ft(\))g(and)f(mrdivide)g
+(\(/\))h(op)s(erators)g(are)g(often)g(part)g(of)f(a)h(more)g(complex)
+330 3926 y(expression,)30 b(where)f(there)h(is)f(no)h(ro)s(om)f(to)h
+(react)h(to)f(w)m(arnings)f(or)h(\015ags,)g(it)g(should)f(prefer)f(in)m
+(tel-)330 4036 y(ligence)36 b(\(robustness\))e(to)h(sp)s(eed,)g(and)f
+(so)h(the)g(Octa)m(v)m(e)h(dev)m(elop)s(ers)f(are)g(\014rmly)f(of)g
+(the)h(opinion)330 4145 y(that)g(Octa)m(v)m(e's)i(approac)m(h)f(for)e
+(singular,)i(under-)e(and)g(o)m(v)m(er-determined)i(matrices)g(is)f(a)g
+(b)s(etter)330 4255 y(c)m(hoice)d(that)f(Matlab's)225
+4398 y Fk(\017)60 b Ft(Octa)m(v)m(e)33 b(extensions)e(The)f(extensions)
+h(in)f(Octa)m(v)m(e)j(o)m(v)m(er)f Fo(Ma)-6 b(tlab)29
+b Ft(syn)m(tax)i(are)g(v)m(ery)g(useful,)f(but)330 4507
+y(migh)m(t)36 b(cause)g(issues)f(when)f(sharing)h(with)g
+Fo(Ma)-6 b(tlab)33 b Ft(users.)55 b(A)35 b(list)h(of)g(the)f(ma)5
+b(jor)35 b(extensions)330 4617 y(that)c(should)e(b)s(e)h(a)m(v)m(oided)
+i(to)f(b)s(e)f(compatible)h(with)f Fo(Ma)-6 b(tlab)29
+b Ft(are)405 4759 y Fk(\017)60 b Ft(Commen)m(ts)30 b(in)f(o)s(cta)m(v)m
+(e)k(can)d(b)s(e)f(mark)m(ed)h(with)g(`)p Fq(#)p Ft('.)40
+b(This)29 b(allo)m(ws)i(POSIX)e(systems)h(to)h(ha)m(v)m(e)510
+4869 y(the)40 b(\014rst)f(line)h(as)g(`)p Fq(#!)30 b(octave)e(-q)p
+Ft(')40 b(and)f(mark)g(the)h(script)g(itself)g(executable.)71
+b Fo(Ma)-6 b(tlab)510 4978 y Ft(do)s(esn't)30 b(ha)m(v)m(e)i(this)e
+(feature)h(due)f(to)h(the)f(absence)h(of)g(commen)m(ts)g(starting)g
+(with)f(`)p Fq(#)p Ft(')p Fq(")p Ft(.)405 5121 y Fk(\017)60
+b Ft(Co)s(de)32 b(blo)s(c)m(ks)g(lik)m(e)h(if,)g(for,)g(while,)f(etc)i
+(can)e(b)s(e)f(terminated)i(with)f(blo)s(c)m(k)g(sp)s(eci\014c)g
+(termina-)510 5230 y(tions)i(lik)m(e)i Fq(")p Ft(endif)p
+Fq(")p Ft(.)50 b Fo(Ma)-6 b(tlab)33 b Ft(do)s(esn't)g(ha)m(v)m(e)j
+(this)d(and)h(all)h(blo)s(c)m(ks)f(m)m(ust)g(b)s(e)f(terminated)510
+5340 y(with)d Fq(")p Ft(end)p Fq(")p eop end
+%%Page: 15 17
+TeXDict begin 15 16 bop 150 -116 a Ft(Chapter)30 b(11:)41
+b(P)m(orting)32 b(programs)e(from)g Fo(Ma)-6 b(tlab)28
+b Ft(to)j(Octa)m(v)m(e)1294 b(15)405 299 y Fk(\017)60
+b Ft(Octa)m(v)m(e)31 b(has)e(a)g(lisp)g(lik)m(e)i(un)m(wind)p
+1679 299 28 4 v 38 w(protect)f(blo)s(c)m(k)g(that)f(allo)m(ws)i(blo)s
+(c)m(ks)e(of)g(co)s(de)h(that)f(termi-)510 408 y(nate)c(in)e(an)h
+(error)g(to)g(ensure)f(that)i(the)f(v)-5 b(ariables)25
+b(that)f(are)h(touc)m(hed)f(are)g(restored.)39 b(Y)-8
+b(ou)25 b(can)510 518 y(do)35 b(something)h(similar)g(with)g
+Fq(try)p Ft(/)p Fq(catch)d Ft(com)m(bined)j(with)f(`)p
+Fq(rethrow)29 b(\(lasterror)f(\(\)\))p Ft(')510 628 y(in)e
+Fo(Ma)-6 b(tlab)p Ft(,)27 b(ho)m(w)m(ev)m(er)h(rethro)m(w)e(and)h
+(lasterror)g(are)g(only)g(a)m(v)-5 b(ailable)29 b(in)e(Octa)m(v)m(e)i
+(2.9.10)g(and)510 737 y(later.)510 874 y(Note)47 b(that)f(using)f
+Fq(try)p Ft(/)p Fq(catch)e Ft(com)m(bined)j(with)f(`)p
+Fq(rethrow)29 b(\(lasterror)e(\(\)\))p Ft(')45 b(can)h(not)510
+984 y(guaran)m(tee)29 b(that)g(global)g(v)-5 b(ariables)28
+b(will)g(b)s(e)f(correctly)i(reset,)g(as)f(it)g(w)m(on't)h(catc)m(h)g
+(user)e(in)m(ter-)510 1093 y(rupts)i(with)h(Ctrl-C.)h(F)-8
+b(or)31 b(example)845 1230 y Fq(global)47 b(a)845 1340
+y(a)h(=)f(1;)845 1450 y(try)941 1559 y(_a)g(=)h(a;)941
+1669 y(a)f(=)h(2)941 1778 y(while)e(true)941 1888 y(end)845
+1998 y(catch)941 2107 y(fprintf)g(\('caught)f(interrupt\\n'\);)941
+2217 y(a)i(=)h(_a;)941 2326 y(rethrow)e(\(lasterror\(\)\);)845
+2436 y(end)510 2573 y Ft(compared)30 b(to)845 2710 y
+Fq(global)47 b(a)845 2819 y(a)h(=)f(1;)845 2929 y(unwind_protect)941
+3039 y(_a)g(=)h(a;)941 3148 y(a)f(=)h(2)941 3258 y(while)e(true)941
+3367 y(end)845 3477 y(unwind_protect_cleanup)941 3587
+y(fprintf)g(\('caught)f(interrupt\\n'\);)941 3696 y(a)i(=)h(_a;)845
+3806 y(end)510 3943 y Ft(T)m(yping)36 b(Ctrl-C)g(in)g(the)g(\014rst)f
+(case)j(returns)c(the)j(user)e(directly)i(to)g(the)f(prompt,)h(and)f
+(the)510 4052 y(v)-5 b(ariable)36 b Fq(")p Ft(a)p Fq(")f
+Ft(is)g(not)g(reset)g(to)h(the)f(sa)m(v)m(ed)h(v)-5 b(alue.)56
+b(In)34 b(the)h(second)g(case)h(the)f(v)-5 b(ariable)36
+b Fq(")p Ft(a)p Fq(")510 4162 y Ft(is)f(reset)g(correctly)-8
+b(.)56 b(Therefore)34 b Fo(Ma)-6 b(tlab)33 b Ft(giv)m(es)k(no)d(sa)m(v)
+m(e)j(w)m(a)m(y)e(of)g(temp)s(orarily)g(c)m(hanging)510
+4271 y(global)d(v)-5 b(ariables.)405 4408 y Fk(\017)60
+b Ft(Indexing)31 b(can)h(b)s(e)f(applied)h(to)g(all)h(ob)5
+b(jects)33 b(in)e(Octa)m(v)m(e)j(and)d(not)h(just)f(v)-5
+b(ariable.)46 b(Therefore)510 4518 y Fq(sin\(x\)\(1:10\);)28
+b Ft(for)k(example)h(is)f(p)s(erfectly)g(v)-5 b(alid)32
+b(in)g(Octa)m(v)m(e)i(but)d(not)i Fo(Ma)-6 b(tlab)p Ft(.)44
+b(T)-8 b(o)32 b(do)510 4628 y(the)f(same)f(in)g Fo(Ma)-6
+b(tlab)29 b Ft(y)m(ou)i(m)m(ust)f(do)g Fq(y)g(=)g(sin\(x\);)f(y)h(=)g
+(y\([1:10]\);)405 4765 y Fk(\017)60 b Ft(Octa)m(v)m(e)30
+b(has)e(the)g(op)s(erators)g Fq("++")p Ft(,)g Fq(")p
+Ft({)p Fq(")p Ft(,)g Fq(")p Ft(-=)p Fq(")p Ft(,)h Fq("+)p
+Ft(=)p Fq(")p Ft(,)e Fq(")p Ft(*=)p Fq(")p Ft(,)h(etc.)41
+b(As)28 b Fo(Ma)-6 b(tlab)27 b Ft(do)s(esn't,)510 4874
+y(if)j(y)m(ou)h(are)g(sharing)f(co)s(de)g(these)h(should)f(b)s(e)f(a)m
+(v)m(oided.)405 5011 y Fk(\017)60 b Ft(Character)28 b(strings)f(in)h
+(Octa)m(v)m(e)i(can)d(b)s(e)g(denoted)h(with)f(double)h(or)f(single)h
+(quotes.)41 b(There)27 b(is)510 5121 y(a)35 b(subtle)g(di\013erence)g
+(b)s(et)m(w)m(een)g(the)g(t)m(w)m(o)h(in)e(that)h(escap)s(ed)g(c)m
+(haracters)h(lik)m(e)g Fq(\\n)e Ft(\(newline\),)510 5230
+y Fq(\\t)24 b Ft(\(tab\),)j(etc)f(are)f(in)m(terpreted)g(in)f(double)g
+(quoted)h(strings)f(but)g(not)h(single)g(quoted)g(strings.)510
+5340 y(This)e(di\013erence)h(is)f(imp)s(ortan)m(t)h(on)f(Windo)m(ws)h
+(platforms)g(where)f(the)g Fq("\\")g Ft(c)m(haracter)i(is)f(used)p
+eop end
+%%Page: 16 18
+TeXDict begin 16 17 bop 150 -116 a Ft(App)s(endix)29
+b(A:)h(Concept)h(Index)2387 b(16)510 299 y(in)38 b(path)h(names,)h(and)
+e(so)h(single)g(quoted)g(strings)f(should)g(b)s(e)g(used)f(in)i(paths.)
+65 b Fo(Ma)-6 b(tlab)510 408 y Ft(do)s(esn't)30 b(ha)m(v)m(e)i(double)e
+(quoted)g(strings)g(and)g(so)h(they)f(should)g(b)s(e)f(a)m(v)m(oided)j
+(if)e(the)h(co)s(de)g(will)510 518 y(b)s(e)f(transfered)g(to)h(a)f
+Fo(Ma)-6 b(tlab)29 b Ft(user.)150 800 y Fp(App)t(endix)52
+b(A)81 b(Concept)52 b(Index)150 1140 y Fs(A)150 1261
+y Fl(Additional)26 b(help)12 b Fe(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)39 b Fl(7)150 1525 y Fs(B)150
+1647 y Fl(Binaries)18 b Fe(:)c(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)45 b Fl(8)150
+1737 y(Bug)26 b(in)g(Octa)n(v)n(e,)f(newly)h(found)8
+b Fe(:)13 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)35 b Fl(7)150 2001 y Fs(C)150 2123
+y Fl(Compatibilit)n(y)27 b(with)f Fm(Ma)-5 b(tlab)17
+b Fe(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)h(:)43 b Fl(10)150 2387 y Fs(D)150 2509 y Fl(D)n(ASSL)13
+b Fe(:)f(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)40 b Fl(6)150 2599 y(Decremen)n(t)25
+b(op)r(erators)9 b Fe(:)15 b(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)36
+b Fl(6)150 2689 y(DJGPP)23 b Fe(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)49
+b Fl(8)150 2936 y Fs(E)150 3058 y Fl(EMX)13 b Fe(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)40 b Fl(8)150 3305 y Fs(F)150 3427 y Fl(Flex)13
+b Fe(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)40 b Fl(9)150
+3517 y(FSF)26 b([F)-6 b(ree)26 b(Soft)n(w)n(are)g(F)-6
+b(oundation])10 b Fe(:)j(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)37 b Fl(2)150 3785 y Fs(G)150 3907 y
+Fl(GNU)25 b([GNU's)h(not)g(unix])19 b Fe(:)13 b(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+47 b Fl(2)150 3997 y(GNU)25 b(Bison)11 b Fe(:)j(:)g(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)38 b
+Fl(9)150 4087 y(GNU)25 b(g)p Fd(++)12 b Fe(:)i(:)f(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)39
+b Fl(9)150 4177 y(GNU)25 b(gcc)17 b Fe(:)d(:)f(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)44
+b Fl(9)150 4267 y(GNU)25 b(Mak)n(e)14 b Fe(:)g(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)41 b
+Fl(9)150 4514 y Fs(H)150 4636 y Fl(Ho)n(w)26 b(do)g(I)k(.)18
+b(.)h(.)36 b(?)15 b Fe(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)42 b Fl(10)150 4883 y Fs(I)150 5005 y Fl(Incremen)n(t)25
+b(op)r(erators)c Fe(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)47
+b Fl(6)2025 1140 y Fs(L)2025 1256 y Fl(libg)p Fd(++)20
+b Fe(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46 b Fl(9)2025 1343 y(LSODE)6
+b Fe(:)12 b(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)33 b Fl(6)2025 1575 y Fs(M)2025
+1691 y Fl(Mailing)27 b(lists,)g(bug-o)r(cta)n(v)n(e)16
+b Fe(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)43 b Fl(7)2025 1779 y(Mailing)27
+b(lists,)g(help-o)r(cta)n(v)n(e)7 b Fe(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)35
+b Fl(7)2025 1866 y(Man)n(ual,)26 b(for)h(Octa)n(v)n(e)17
+b Fe(:)c(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)45 b
+Fl(7)2025 1953 y Fm(Ma)-5 b(tlab)26 b Fl(compatibilit)n(y)13
+b Fe(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)39 b Fl(10)2025 2040
+y(MS-DOS)24 b(supp)r(ort)16 b Fe(:)c(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)43 b Fl(8)2025 2289 y Fs(O)2025 2405 y
+Fl(Octa)n(v)n(e)25 b(bug)g(rep)r(ort)17 b Fe(:)d(:)f(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)44 b Fl(7)2025 2493 y(Octa)n(v)n(e,)25
+b(building)14 b Fe(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)41 b Fl(8)2025 2580 y(Octa)n(v)n(e,)25 b(do)r(cumen)n(tation)c
+Fe(:)13 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)48 b Fl(7)2025 2667
+y(Op)r(erators,)26 b(decremen)n(t)13 b Fe(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)40 b Fl(6)2025 2754 y(Op)r(erators,)26 b(incremen)n(t)19
+b Fe(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)46 b Fl(6)2025
+2841 y(OS/2)26 b(supp)r(ort)8 b Fe(:)k(:)h(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)35 b Fl(8)2025 3095 y
+Fs(P)2025 3211 y Fl(Pre-compiled)26 b(binary)f(pac)n(k)l(ages)13
+b Fe(:)h(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)40 b Fl(8)2025 3460 y Fs(S)2025 3576 y Fl(Source)25
+b(co)r(de)f Fe(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)50 b Fl(8)2025 3809 y Fs(T)2025 3925
+y Fl(Tips)26 b(and)f(tric)n(ks)17 b Fe(:)d(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)43 b Fl(10)2025 4174 y Fs(U)2025
+4290 y Fl(Un)n(wind-protect)11 b Fe(:)h(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)38 b Fl(6)2025 4540 y Fs(V)2025
+4656 y Fl(V)-9 b(AX)20 b Fe(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)48
+b Fl(8)2025 4743 y(VMS)25 b(supp)r(ort)12 b Fe(:)h(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)39 b Fl(8)2025
+4992 y Fs(W)2025 5108 y Fl(Windo)n(ws)26 b(supp)r(ort)12
+b Fe(:)g(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)39
+b Fl(8)p eop end
+%%Page: -1 19
+TeXDict begin -1 18 bop 3725 -116 a Ft(i)150 299 y Fp(T)-13
+b(able)53 b(of)h(Con)l(ten)l(ts)150 641 y Fs(1)135 b(What)45
+b(is)g(Octa)l(v)l(e?)25 b Fc(:)20 b(:)g(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)h(:)f(:)h(:)69 b Fs(1)275 778 y Ft(1.1)92 b(Who)30
+b(dev)m(elops)h(Octa)m(v)m(e?)d Fb(:)15 b(:)g(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)55
+b Ft(1)275 888 y(1.2)92 b(Wh)m(y)30 b(GNU)h(Octa)m(v)m(e?)f
+Fb(:)15 b(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)58 b Ft(1)275
+997 y(1.3)92 b(What)31 b(v)m(ersion)f(should)g(I)g(use?)14
+b Fb(:)h(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)
+h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)44 b Ft(2)275 1107 y(1.4)92 b(On)29 b(what)h(platforms)h(do)
+s(es)f(Octa)m(v)m(e)i(run?)21 b Fb(:)14 b(:)h(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)51 b Ft(2)150 1349 y Fs(2)135 b(Licensing)45 b(Issues)20
+b Fc(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)64
+b Fs(2)275 1486 y Ft(2.1)92 b(If)29 b(I)g(write)g(co)s(de)h(using)f
+(Octa)m(v)m(e)j(do)d(I)g(ha)m(v)m(e)i(to)f(release)h(it)f(under)d(the)j
+(GPL?)480 1596 y Fb(:)16 b(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)54
+b Ft(2)275 1705 y(2.2)92 b(Since)30 b(the)h(MEX)f(in)m(terface)i(allo)m
+(ws)g(plugins)e(to)h(b)s(e)e(distributed)h(under)456
+1815 y(terms)h(that)g(are)f(incompatible)i(with)e(the)g(GPL,)h(do)s(es)
+f(this)g(mean)h(that)456 1924 y(y)m(ou)g(are)g(encouraging)g(p)s(eople)
+f(to)i(to)f(write)f(non-free)h(soft)m(w)m(are)g(for)456
+2034 y(Octa)m(v)m(e?)e Fb(:)15 b(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)57 b Ft(3)275
+2144 y(2.3)92 b(I)30 b(wrote)h(a)f(program)g(that)h(links)g(with)f
+(Octa)m(v)m(e)i(libraries)f(and)e(I)i(don't)456 2253
+y(w)m(an)m(t)h(to)f(release)g(it)g(under)e(the)i(terms)f(of)g(the)h
+(GPL.)g(Will)g(y)m(ou)g(c)m(hange)g(the)456 2363 y(license)h(of)e(the)h
+(Octa)m(v)m(e)h(libraries)f(for)f(me?)21 b Fb(:)15 b(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)g(:)h(:)f(:)51 b Ft(3)150 2605 y Fs(3)135 b(Ho)l(w)45
+b(can)g(I)g(cite)h(Octa)l(v)l(e?)11 b Fc(:)20 b(:)g(:)f(:)g(:)h(:)f(:)h
+(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+56 b Fs(3)150 2875 y(4)135 b(What's)43 b(new)g(in)g(v)l(ersion)h
+(series)g(3.0.N)g(and)f(3.1.N)h(of)419 3008 y(Octa)l(v)l(e)17
+b Fc(:)j(:)g(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)61 b Fs(4)150 3278 y(5)135
+b(What)45 b(features)h(are)f(unique)g(to)h(Octa)l(v)l(e?)26
+b Fc(:)20 b(:)g(:)f(:)g(:)h(:)f(:)h(:)f(:)71 b Fs(5)275
+3415 y Ft(5.1)92 b(F)-8 b(unctions)31 b(de\014ned)e(on)h(the)g
+(command-line)16 b Fb(:)g(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)46
+b Ft(5)275 3524 y(5.2)92 b(Commen)m(ts)30 b(with)g(#)e
+Fb(:)15 b(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)58 b Ft(5)275
+3634 y(5.3)92 b(Strings)29 b(delimitted)j(b)m(y)e(double)g(quotes)h
+Fq(")11 b Fb(:)k(:)g(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)41 b
+Ft(5)275 3743 y(5.4)92 b(Line)30 b(con)m(tin)m(uation)i(b)m(y)e(bac)m
+(kslash)23 b Fb(:)16 b(:)g(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)53 b Ft(5)275 3853 y(5.5)92 b(Informativ)m(e)31
+b(blo)s(c)m(k)g(closing)17 b Fb(:)g(:)e(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)47 b Ft(5)275
+3963 y(5.6)92 b(Coheren)m(t)30 b(syn)m(tax)8 b Fb(:)17
+b(:)e(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)
+f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)39 b
+Ft(5)275 4072 y(5.7)92 b(Exclamation)32 b(mark)e(as)g(not)h(op)s
+(erator)11 b Fb(:)16 b(:)g(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)42
+b Ft(6)275 4182 y(5.8)92 b(Incremen)m(t)30 b(and)g(decremen)m(t)h(op)s
+(erators)11 b Fb(:)k(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)41
+b Ft(6)275 4291 y(5.9)92 b(Un)m(wind-protect)24 b Fb(:)15
+b(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)54 b
+Ft(6)275 4401 y(5.10)92 b(Built-in)31 b(ODE)g(and)e(D)m(AE)j(solv)m
+(ers)16 b Fb(:)g(:)g(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)47
+b Ft(6)150 4643 y Fs(6)135 b(What)45 b(do)t(cumen)l(tation)h(exists)g
+(for)f(Octa)l(v)l(e?)24 b Fc(:)c(:)g(:)f(:)h(:)f(:)69
+b Fs(7)275 4780 y Ft(6.1)92 b(What)31 b(do)s(cumen)m(tation)g(exists)g
+(for)f(Octa)m(v)m(e?)f Fb(:)16 b(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)
+h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)57
+b Ft(7)275 4890 y(6.2)92 b(Getting)32 b(additional)f(help)11
+b Fb(:)k(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)g(:)h(:)41 b Ft(7)275 5000 y(6.3)92
+b(User)30 b(comm)m(unit)m(y)8 b Fb(:)17 b(:)e(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)
+h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)g(:)39 b Ft(7)275 5109 y(6.4)92 b(I)30
+b(think)g(I)g(ha)m(v)m(e)h(found)e(a)i(bug)f(in)g(Octa)m(v)m(e.)14
+b Fb(:)k(:)d(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)44 b Ft(7)p eop
+end
+%%Page: -2 20
+TeXDict begin -2 19 bop 3699 -116 a Ft(ii)150 83 y Fs(7)135
+b(Getting)46 b(Octa)l(v)l(e)12 b Fc(:)20 b(:)g(:)f(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)
+g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)57 b Fs(8)275 220 y Ft(7.1)92
+b(Source)30 b(co)s(de)18 b Fb(:)d(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)48 b Ft(8)275 330 y(7.2)92
+b(Pre-compiled)31 b(binary)e(pac)m(k)-5 b(ages)29 b Fb(:)15
+b(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)57
+b Ft(8)275 439 y(7.3)92 b(Ho)m(w)31 b(do)f(I)g(get)i(a)e(cop)m(y)h(of)g
+(Octa)m(v)m(e)i(for)d(\(some)h(other)f(platform\)?)11
+b Fb(:)16 b(:)f(:)h(:)f(:)h(:)f(:)41 b Ft(8)150 682 y
+Fs(8)135 b(Installation)47 b(Issues)e(and)g(Problems)29
+b Fc(:)19 b(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)73
+b Fs(8)275 819 y Ft(8.1)92 b(What)31 b(else)g(do)f(I)g(need?)15
+b Fb(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)
+h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)45 b Ft(9)275 928
+y(8.2)92 b(Can)30 b(I)g(compile)h(Octa)m(v)m(e)i(with)d(another)g(C++)g
+(compiler?)15 b Fb(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)45
+b Ft(9)150 1171 y Fs(9)135 b(Common)45 b(problems)11
+b Fc(:)20 b(:)g(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)56
+b Fs(9)150 1440 y(10)135 b(Ho)l(w)46 b(do)e(I)h(...?)10
+b Fc(:)21 b(:)e(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)
+55 b Fs(10)275 1577 y Ft(10.1)92 b(Ho)m(w)31 b(do)f(I)h(set)f(the)h(n)m
+(um)m(b)s(er)e(of)i(displa)m(y)m(ed)g(decimals?)22 b
+Fb(:)16 b(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)51
+b Ft(10)150 1820 y Fs(11)135 b(P)l(orting)46 b(programs)f(from)g
+Fa(Ma)-8 b(tlab)46 b Fs(to)g(Octa)l(v)l(e)446 1953 y
+Fc(:)20 b(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)72
+b Fs(10)150 2222 y(App)t(endix)44 b(A)160 b(Concept)45
+b(Index)24 b Fc(:)19 b(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f
+(:)g(:)h(:)f(:)h(:)f(:)h(:)68 b Fs(16)p eop end
+%%Trailer
+
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/doc/faq/Octave-FAQ.texi b/doc/faq/Octave-FAQ.texi
new file mode 100644
index 0000000..a80d6d1
--- /dev/null
+++ b/doc/faq/Octave-FAQ.texi
@@ -0,0 +1,1236 @@
+% Copyright (C) 1997, 1998, 1999, 2001, 2003, 2004, 2005, 2007, 2008, 2009
+%               John W. Eaton
+%
+% This file is part of Octave.
+%
+% Octave is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 3 of the License, or (at
+% your option) any later version.
+% 
+% Octave is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+% 
+% You should have received a copy of the GNU General Public License
+% along with Octave; see the file COPYING.  If not, see
+% <http://www.gnu.org/licenses/>.
+
+\input texinfo.tex      @c -*-texinfo-*-
+
+ at setfilename Octave-FAQ.info
+ at settitle Frequently asked questions about Octave (with answers)
+
+ at setchapternewpage off
+ at direntry
+* Octave-FAQ: (Octave-FAQ).  Frequently asked questions about Octave
+ at end direntry
+ at titlepage
+ at title Octave FAQ
+ at subtitle Frequently asked questions about Octave
+ at subtitle September 2008
+ at sp 1
+ at author John W. Eaton and David Bateman
+ at page
+ at end titlepage
+
+ at ifnottex
+ at node Top
+ at top
+ at unnumbered Preface
+ at cindex FAQ for Octave, latest version
+ at end ifnottex
+
+This is a list of frequently asked questions (FAQ) for Octave users.
+
+We are always looking for new questions (@emph{with} answers), better
+answers, or both.  Please send suggestions to @email{bug@@octave.org}.
+If you have general questions about Octave, or need help for something
+that is not covered by the Octave manual or the FAQ, please use the
+ at email{help@@octave.org} mailing list.
+
+This FAQ is intended to supplement, not replace, the Octave manual.
+Before posting a question to the @email{help@@octave.org} mailing list,
+you should first check to see if the topic is covered in the manual.
+
+ at menu
+* What is Octave?::  
+* Licensing Issues::
+* How can I cite Octave?::  
+* Series 3.0.N::  
+* Octave Features::  
+* Learning more about Octave:: 
+* Getting Octave::  
+* Installation::  
+* Common problems::             
+* How do I ...?::  
+* MATLAB compatibility:: 
+* Index::                       
+ at end menu
+
+ at node What is Octave?
+ at chapter What is Octave?
+
+Octave is a high-level interactive language, primarily intended for
+numerical computations that is mostly compatible with
+ at sc{Matlab}. at footnote{@sc{Matlab} is a registered trademark of The MathWorks,
+Inc.} 
+
+Octave can do arithmetic for real, complex or integer-valued scalars
+and matrices, solve sets of nonlinear algebraic equations, integrate
+functions over finite and infinite intervals, and integrate systems of
+ordinary differential and differential-algebraic equations.
+
+Octave uses the GNU readline library to handle reading and editing
+input.  By default, the line editing commands are similar to the
+cursor movement commands used by GNU Emacs, and a vi-style line
+editing interface is also available.  At the end of each session, the
+command history is saved, so that commands entered during previous
+sessions are not lost.
+
+The Octave distribution includes a 590+ page Texinfo manual.  Access
+to the complete text of the manual is available via the help command
+ at c really, the *complete* text?
+at the Octave prompt.
+
+ at menu
+* Who develops Octave?::  
+* Why GNU Octave?::  
+* What version should I use?::  
+* On what platforms does Octave run?::  
+ at end menu
+
+ at node Who develops Octave?
+ at section Who develops Octave?
+
+Discussions about writing the software that would eventually become
+Octave started in about 1988 with James B. Rawlings and John W. Eaton at
+the University of Texas.  John W. Eaton was the original author of
+Octave, starting full-time development in February 1992.  He is still
+the primary maintainer.  The community
+of users/developers has in addition contributed some code and fuels the
+discussion on the mailing lists @email{help@@octave.org} (user forum),
+ at email{bug@@octave.org} (bug reports), @email{maintainers@@octave.org}
+(development issues), and @email{octave-dev@@lists.sourceforge.net} (all
+things related to the Octave Forge repository of user-contributed
+functions).
+
+ at node Why GNU Octave?
+ at section Why GNU Octave?
+
+The GNU Project was launched in 1984 to develop a complete Unix-like
+operating system which is free software: the GNU system.
+
+GNU is a recursive acronym for ``GNU's Not Unix''; it is pronounced
+guh-noo, approximately like canoe.
+
+The Free Software Foundation (FSF) is the principal organizational
+sponsor of the GNU Project.
+
+Octave became GNU Octave in 1997 (beginning with version 2.0.6).  This
+meant agreeing to consider Octave a part of the GNU Project and support
+the efforts of the FSF.  However, Octave is not and has never been
+developed by the FSF.
+
+For more information about the GNU project, see @url{www.gnu.org}.
+
+ at cindex FSF [Free Software Foundation]
+ at cindex GNU [GNU's not unix]
+
+ at node What version should I use?
+ at section What version should I use?
+
+In general, you will find the latest version on 
+ at url{http://www.octave.org/download.html}.  It is
+recommended to use the ``testing'' version of octave for general use,
+and the ``development'' version if you want the latest features.
+
+A list of user-visible changes since the last release is available in
+the file @file{NEWS}.  The file @file{ChangeLog} in the source
+distribution contains a more detailed record of changes made since the
+last release.
+
+ at node On what platforms does Octave run?
+ at section On what platforms does Octave run?
+
+Octave runs on various Unices---at least Linux and Solaris, Mac OS X,
+Windows and anything you can compile it on.  Binary distributions exist
+at least for Debian, Suse, Fedora and RedHat Linuxes (Intel and AMD
+CPUs, at least), for Mac Os X and Windows' 98, 2000 and XP.
+
+Two and three dimensional plotting is fully supported using gnuplot.
+
+The underlying numerical solvers are currently standard Fortran ones
+like Lapack, Linpack, Odepack, the Blas, etc., packaged in a library
+of C++ classes.  If possible, the Fortran subroutines are compiled
+with the system's Fortran compiler, and called directly from the C++
+functions.  If that's not possible, you can still compile Octave if
+you have the free Fortran to C translator f2c.
+
+Octave is also free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation.
+
+ at node Licensing Issues
+ at chapter Licensing Issues
+
+ at menu
+* If I write code using Octave do I have to release it under the GPL?: GPL
+* Since the MEX interface allows plugins to be distributed under terms that are incompatible with the GPL, does this mean that you are encouraging people to to write non-free software for Octave?: Licensing MEX Files
+* I wrote a program that links with Octave libraries and I don't want to release it under the terms of the GPL.  Will you change the license of the Octave libraries for me?: Requesting License Changes
+ at end menu
+
+ at node GPL
+ at section If I write code using Octave do I have to release it under the GPL?
+
+The answer depends on precisely how the code is written and how it works.
+
+Code written entirely in the scripting language of Octave
+(interpreted code in .m files) may be released under the terms of
+whatever license you choose.
+
+Code written using Octave's native plug-in interface (also known
+as a .oct file) necessarily links with Octave internals and is
+considered a derivative work of Octave and therefore must be
+released under terms that are compatible with the GPL.
+
+Code written using Octave's implementation of the Matlab MEX
+interface may be released under the terms of whatever license you
+choose, provided that the following conditions are met:
+
+ at enumerate
+ at item
+The plugin should not use any bindings that are specific to Octave.  In
+other words, the MEX file must use the MEX interface only, and not also
+call on other Octave internals.  It should be possible in principle to
+use the MEX file with other programs that implement the MEX interface
+(e.g., Matlab).
+
+ at item
+The MEX file should not be distributed together with Octave in such a
+way that they effectively create a single work.  For example, you should
+not distribute the MEX file and Octave together in a single package such
+that Octave automatically loads and runs the MEX file when it starts up.
+There are other possible ways that you might effectively create a single
+work; this is just one example.
+ at end enumerate
+
+A program that embeds the Octave interpreter (e.g., by calling the
+"octave_main" function), or that calls functions from Octave's
+libraries (e.g., liboctinterp, liboctave, or libcruft) is
+considered a derivative work of Octave and therefore must be
+released under terms that are compatible with the GPL.
+
+ at node Licensing MEX Files
+ at section Since the MEX interface allows plugins to be distributed under terms that are incompatible with the GPL, does this mean that you are encouraging people to to write non-free software for Octave?
+
+No.  The original reason for implementing the MEX interface for Octave
+was to allow Octave to run free software that uses MEX files (the
+particular goal was to run SundialsTB in Octave).  The intent was to
+liberate that software from Matlab and increase the amount of free
+software available to Octave users, not to enable people to write
+proprietary code for Octave.  For the good of the community, we strongly
+encourage users of Octave to release the code they write for Octave
+under terms that are compatible with the GPL.
+
+ at node Requesting License Changes
+ at section I wrote a program that links with Octave libraries and I don't want to release it under the terms of the GPL.  Will you change the license of the Octave libraries for me?
+
+No.  Instead of asking us to change the licensing terms for Octave, we
+recommend that you release your program under terms that are compatible
+with the GPL so that the free software community can benefit from your
+work the same as you have benefitted from the work of all the people who
+have contributed to Octave.
+
+ at node How can I cite Octave?
+ at chapter How can I cite Octave?
+
+Pointing to @url{http://www.octave.org} is good, because that gives
+people a direct way to find out more.  If citation of a URL is not
+allowed by a publisher, or if you also want to point to a traditional
+reference, then you can cite the Octave manual:
+
+ at example
+ at group
+@@BOOK@{eaton:2008,
+  author =     "John W. Eaton and David Bateman and Søren Hauberg",
+  title =      "GNU Octave Manual Version 3",
+  publisher =  "Network Theory Limited",
+  year =       "2008",
+  isbn =       "0-9546120-6-X"
+@}
+ at end group
+ at end example
+
+ at node Series 3.0.N
+ at chapter What's new in version series 3.0.N and 3.1.N of Octave
+
+The 3.0.N series has enough new features to justify a major version
+number change. The 3.0.N series brings
+
+ at itemize @bullet
+
+ at item integer types
+
+ at item fixed point arithmetic
+
+ at item sparse matrices
+
+ at item Linear programming code based on GLPK
+
+ at item 64-bit compilation support
+
+ at item gzipped files and stream and consequently support of matlab v7 files
+
+ at item better support for both msvc and mingw
+
+ at item a fully compatible MEX interface
+
+ at item many many other minor features and compatibility changes
+
+ at end itemize
+
+Here are some features that have been around since 2.1.N
+
+ at itemize @bullet
+
+ at item NDarrays 
+
+ at item cells
+
+ at end itemize
+
+The 3.1.N series is the current development release and will become a
+3.2.N release in the future. This series brings the new features
+
+ at itemize
+ at item OpenGL backend
+
+An experimental OpenGL graphics backend to replace the gnuplot
+
+ at item Object Orient Programming
+
+ at item Block comments
+
+ at item imwrite and imread 
+
+The functions are based on the GraphicsMagick library.
+
+ at item Lazy transpose
+
+Special treatment in the parser of things like "a' * b", where the
+transpose is never explicitly formed but a flag is rather passed to the
+underlying LAPACK code.
+
+ at item Single precision type
+
+ at item Improved array indexing
+The underlying code used for indexing of arrays has been completely
+rewritten and so the indexing of arrays is now significantly faster.
+ at end itemize
+
+
+ at node Octave Features
+ at chapter What features are unique to Octave?
+
+ at menu
+* Functions defined on the command-line::
+* Comments with #::            
+* Strings delimitted by double quotes "::
+* Line continuation by backslash::
+* Informative block closing::
+* Coherent syntax::             
+* Exclamation mark as not operator::
+* Increment and decrement operators::  
+* Unwind-protect::              
+* Built-in ODE and DAE solvers::
+ at end menu
+
+This section refers to Matlab R2008b and Octave 2.1.51.
+
+ at node Functions defined on the command-line
+ at section Functions defined on the command-line
+
+Functions can be defined by entering code on the command line, a
+feature not supported by the other leading brand.  For example, you may
+type:
+
+ at example
+ at group
+octave:1> function s = hello_string (to_who)
+> ## Say hello 
+> if nargin<1, to_who = "World"; end
+> s = ["Hello ",\
+>      to_who];
+> endfunction
+octave:2> hello_string ("Moon")
+ans = Hello Moon
+ at end group
+ at end example
+
+ at node Comments with #           
+ at section Comments with #
+
+The pound character, @samp{#}, may be used to start comments, in addition
+to @samp{%}.  See the previous example.  The major advantage of this is
+that as @samp{#} is also a comment character for unix script files, any
+file that starts with a string like @samp{#! /usr/bin/octave -q} will be
+treated as an octave script and be executed by octave.
+
+ at node Strings delimitted by double quotes " 
+ at section Strings delimitted by double quotes " 
+The double quote, @samp{"}, may be used to delimit strings, in addition to
+the single quote @samp{'}.  See the previous example.  Also, double-quoted
+strings include backslash interpretation (like C++, C, and Perl) while
+single quoted are uninterpreted (like Matlab and Perl).
+ 
+ at node Line continuation by backslash 
+ at section Line continuation by backslash 
+
+Lines can be continued with a backslash, @samp{\}, in addition to three
+points @samp{@dots{}}.  See the previous example.
+
+ at node Informative block closing
+ at section Informative block closing
+
+You may close @code{function}, @code{for}, @code{while}, @code{if},
+ at dots{} blocks with @code{endfunction}, @code{endfor}, @code{endwhile},
+ at dots{} keywords in addition to using @code{end}.  As with Matlab, the
+ at code{end} (or @code{endfunction}) keyword that marks the end of a
+function defined in a @file{.m} file is optional.
+
+ at node Coherent syntax
+ at section Coherent syntax
+
+Indexing other things than variables is possible, as in:
+ at example
+ at group
+octave:1> [3 1 4 1 5 9](3)
+ans = 4
+octave:2> cos([0 pi pi/4 7])(3)
+ans = 0.70711
+ at end group
+ at end example
+
+ at node Exclamation mark as not operator
+ at section Exclamation mark as not operator
+
+The exclamation mark '!' (aka ``Bang!'') is a negation operator, just
+like the tilde '~':
+
+ at example
+ at group
+octave:1> if ! strcmp (program_name, "octave"),
+>   "It's an error"
+> else
+>   "It works!"
+> end
+ans = It works!
+ at end group
+ at end example
+
+ at node Increment and decrement operators
+ at section Increment and decrement operators
+
+ at cindex Increment operators
+ at cindex Decrement operators
+ at cindex Operators, increment
+ at cindex Operators, decrement
+
+If you like the @samp{++}, @samp{+=} etc operators, rejoice!
+Octave includes the C-like increment and decrement operators @samp{++}
+and @samp{--} in both their prefix and postfix forms, in addition to
+ at samp{+=}, @samp{-=}, @samp{*=}, @samp{/=}, @samp{^=}, @samp{.*=},
+ at samp{./=}, and @samp{.^=}.
+
+For example, to pre-increment the variable @var{x}, you would write
+ at code{++ at var{x}}.  This would add one to @var{x} and then return the new
+value of @var{x} as the result of the expression.  It is exactly the
+same as the expression @code{@var{x} = @var{x} + 1}.
+
+To post-increment a variable @var{x}, you would write @code{x++}.
+This adds one to the variable @var{x}, but returns the value that
+ at var{x} had prior to incrementing it.  For example, if @var{x} is equal
+to 2, the result of the expression @code{x++} is 2, and the new
+value of @var{x} is 3.
+
+For matrix and vector arguments, the increment and decrement operators
+work on each element of the operand.
+
+
+ at node Unwind-protect
+ at section Unwind-protect
+
+ at cindex Unwind-protect
+
+Octave supports a limited form of exception handling modelled after the
+unwind-protect form of Lisp.  The general form of an
+ at code{unwind_protect} block looks like this:
+
+ at example
+ at group
+unwind_protect
+  @var{body}
+unwind_protect_cleanup
+  @var{cleanup}
+end_unwind_protect
+ at end group
+ at end example
+
+ at noindent
+Where @var{body} and @var{cleanup} are both optional and may contain any
+Octave expressions or commands.  The statements in @var{cleanup} are 
+guaranteed to be executed regardless of how control exits @var{body}.
+
+The @code{unwind_protect} statement is often used to reliably restore
+the values of global variables that need to be temporarily changed.
+
+Matlab can be made to do something similar with their @code{OnCleanUp}
+function that was introduced in 2008a.
+
+ at node Built-in ODE and DAE solvers
+ at section Built-in ODE and DAE solvers
+
+ at cindex DASSL
+ at cindex LSODE
+
+Octave includes LSODE and DASSL for solving systems of stiff ordinary
+differential and differential-algebraic equations.  These functions are
+built in to the interpreter.
+
+ at node Learning more about Octave
+ at chapter What documentation exists for Octave?
+
+ at menu
+* Documentation::
+* Getting additional help::            
+* User community::
+* Bug reports::
+ at end menu
+
+
+ at node Documentation
+ at section What documentation exists for Octave?
+
+ at cindex Octave, documentation
+
+The Octave distribution includes a 590+ page manual that is also
+distributed under the terms of the GNU GPL.
+It is available on the web at
+ at url{http://www.octave.org/docs.html} and you will also
+find there instructions on how to order a paper version.
+
+The complete text of the Octave manual is also available using the GNU
+Info system via the GNU Emacs, info, or xinfo programs, or by using
+the @samp{help -i} command to start the GNU info browser directly from
+the Octave prompt.
+
+If you have problems using this documentation, or find that some topic
+is not adequately explained, indexed, or cross-referenced, please send
+a bug report to @email{bug@@octave.org}.
+
+
+ at node Getting additional help
+ at section Getting additional help
+
+ at cindex Additional help
+ at cindex Mailing lists, help-octave
+
+If you can't find an answer to your question, the
+ at email{help@@octave.org} mailing list is available for questions related
+to using, installing, and porting Octave that are not adequately
+answered by the Octave manual or by this document.
+
+ at node User community
+ at section User community
+
+To subscribe to the list, go to @url{www.octave.org/archive.html} and
+follow the link to the subscription page for the list.
+
+ at strong{Please do not} send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+An archive of old postings to the help-octave mailing list is maintained
+on @url{http://www.octave.org/archive.html}.
+
+You will also find some user advice and code spread over the web.  Good
+starting points are the Octave Wiki @url{http://wiki.octave.org} and
+Octave-Forge @url{http://octave.sourceforge.net}
+
+ at node Bug reports
+ at section I think I have found a bug in Octave.
+
+ at cindex Bug in Octave, newly found
+
+``I think I have found a bug in Octave, but I'm not sure.  How do I know,
+and who should I tell?''
+
+ at cindex Manual, for Octave
+
+First, see the section on bugs and bug reports in the Octave manual.
+When you report a bug, make sure to describe the type of computer you
+are using, the version of the operating system it is running, and the
+version of Octave that you are using.  Also provide enough code so that
+the Octave maintainers can duplicate your bug.
+
+If you have Octave working at all, the easiest way to do this is to use
+the Octave function @code{bug_report}.  When you execute this function,
+Octave will prompt you for a subject and then invoke the editor on a
+file that already contains all the configuration information.  When you
+exit the editor, Octave will mail the bug report for you (in a unix-like
+operating system).
+
+ at cindex Octave bug report
+ at cindex Mailing lists, bug-octave
+
+If for some reason you cannot use Octave's @code{bug_report} function,
+mail your bug report to @email{bug@@octave.org}.  Your message needs to
+include enough information to allow the maintainers of Octave to fix the
+bug.  Please read the section on bugs and bug reports in the Octave
+manual for a list of things that should be included in every bug report.
+
+
+ at node Getting Octave
+ at chapter Getting Octave
+
+ at menu
+* Source code::  
+* Pre-compiled binary packages::
+* Octave for other platforms::
+ at end menu
+
+ at node Source code
+ at section Source code
+ at cindex Source code
+
+Source code is available on the Octave development site, where you are
+sure to get the latest version.
+
+ at itemize @bullet
+ at item @url{http://www.octave.org/download.html}
+ at item @url{ftp://ftp.octave.org/pub/octave/}
+ at end itemize
+
+Since Octave is distrubted under the terms of the GPL, you can get
+Octave from a friend who has a copy, by anonymous FTP, or by ordering
+a tape or CD-ROM from the Free Software Foundation (FSF).
+
+ at node Pre-compiled binary packages
+ at section Pre-compiled binary packages
+ at cindex  Pre-compiled binary packages
+ at cindex  Binaries
+
+The Octave project does not distribute binary packages, but other
+projects do.  For an up-to-date listing of packagers, see:
+
+ at itemize @bullet
+ at item @url{http://www.octave.org/download.html}
+ at item @url{http://wiki.octave.org/wiki.pl?CategoryInstall}
+ at end itemize
+
+As of today, Octave binaries are available at least on Debian, RedHat,
+Suse and Fedora Linuxes, Mac OS X, Windows' 98, 2000 and XP.
+
+ at node Octave for other platforms
+ at section How do I get a copy of Octave for (some other platform)?
+
+ at cindex VMS support
+ at cindex VAX
+ at cindex MS-DOS support
+ at cindex Windows support
+ at cindex DJGPP
+ at cindex EMX
+ at cindex OS/2 support
+
+Octave currently runs on Unix-like systems, Mac OS X, and Windows.
+It should be possible to make Octave work on other systems as well.  
+If you are interested in porting Octave to other systems, please contact
+ at email{bug@@octave.org}.
+
+ at c @menu
+ at c * Octave for Unix::             
+ at c * Octave for other platforms::  
+ at c * latest versions::             
+ at c @end menu
+
+ at c @cindex Octave, ordering
+ at c @cindex Octave, getting a copy
+
+ at node Installation
+ at chapter Installation Issues and Problems
+
+ at cindex Octave, building 
+
+Octave 3.2 require approximately 800MB of disk storage to unpack
+and compile from source (considerably less if you don't compile with
+debugging symbols).  Once installed, Octave requires approximately 200MB
+of disk space (again, considerably less if you don't compile with
+debugging symbols).
+
+ at menu
+* What else do I need?::        
+* Other C++ compilers?::        
+ at end menu
+
+ at node What else do I need?
+ at section What else do I need?
+
+ at cindex GNU gcc
+ at cindex GNU g++
+ at cindex libg++
+ at cindex GNU Make
+ at cindex Flex
+ at cindex GNU Bison
+
+To compile Octave, you will need a recent version of GNU Make.  You
+will also need GCC 3.3 or later, although GCC 4.1 or later is 
+recommended.
+
+ at strong{You must have GNU Make to compile octave}.  Octave's Makefiles
+use features of GNU Make that are not present in other versions of make.
+GNU Make is very portable and easy to install.
+
+ at node Other C++ compilers?
+ at section Can I compile Octave with another C++ compiler?
+
+Yes, but development is done primarily with GCC, so you may hit some
+incompatibilities.  Octave is intended to be portable to any standard
+conforming compiler.  If you have difficulties that you think are bugs,
+please report them to the @email{bug@@octave.org} mailing list, or ask
+for help on the @email{help@@octave.org} mailing list.
+
+ at node Common problems
+ at chapter Common problems
+
+This list is probably far too short.  Feel free to suggest additional
+questions (preferably with answers!)
+
+ at itemize @bullet
+ at item
+Octave takes a long time to find symbols.
+
+Octave uses the @code{genpath} function to recursively add directories
+to the list of directories searched for function files.  Check the list
+of directories with the @code{path} command. If the path list is very
+long check your use of the @code{genpath} function.
+
+ at item
+When plotting Octave occasionally gives me errors like @samp{gnuplot> 9 0.735604
+line 26317: invalid command}.
+
+There is a known bug in gnuplot 4.2 that can cause an off by one error
+while piping data to gnuplot. The relevant gnuplot bug report can be
+found at @url{http://sourceforge.net/tracker/index.php?func=detail&aid=1716556&group_id=2055&atid=102055}
+
+If you have obtained your copy of Octave from a distribution please file
+a bug report requesting that the fix reported in the above bug report be
+included.
+
+ at item
+I cannot install a package. Octave complains about a missing @code{mkoctfile}.
+
+Most distributions split Octave into several packages. The script
+ at code{mkoctfile} is then part of a separate package:
+ at itemize @minus
+ at item
+Debian/Ubuntu
+
+ at code{aptitude install octave3.0-headers}
+
+ at item
+Fedora
+
+ at code{yum install octave-devel}
+
+ at end itemize
+ at end itemize
+
+ at node How do I ...?
+ at chapter  How do I ...?
+
+ at menu
+* How do I set the number of displayed decimals?::
+ at end menu
+
+ at cindex Tips and tricks
+ at cindex How do I @dots{} ?
+
+ at node How do I set the number of displayed decimals?
+ at section How do I set the number of displayed decimals?
+
+ at example
+ at group
+octave:1> format long
+octave:2> pi
+pi = 3.14159265358979
+octave:3> format short
+octave:4> pi
+pi = 3.1416
+ at end group
+ at end example
+
+ at node MATLAB compatibility
+ at chapter Porting programs from @sc{Matlab} to Octave
+
+ at cindex @sc{Matlab} compatibility
+ at cindex Compatibility with @sc{Matlab}
+
+People often ask
+
+``I wrote some code for @sc{Matlab}, and I want to get it running under
+Octave.  Is there anything I should watch out for?''
+
+or alternatively
+
+``I wrote some code in Octave, and want to share it with @sc{Matlab}
+users.  Is there anything I should watch out for?''
+
+which is not quite the same thing.  There are still a number of
+differences between Octave and @sc{Matlab}, however in general
+differences between the two are considered as bugs.  Octave might
+consider that the bug is in @sc{Matlab} and do nothing about it, but
+generally functionality is almost identical.  If you find a difference
+between Octave behavior and @sc{Matlab}, then you should send a
+description of this difference (with code illustrating the difference,
+if possible) to @email{bug@@octave.org}.
+
+Furthermore, Octave adds a few syntactical extensions to Matlab that
+might cause some issues when exchanging files between Matlab and Octave
+users. As both Octave and @sc{Matlab} are under constant development the
+information in this section is subject to change at anytime.
+
+You should also look at the page
+ at url{http://octave.sourceforge.net/packages.html} and
+ at url{http://octave.sourceforge.net/doc/} that has a function reference
+that is up to date. You can use this function reference to see the
+number of octave function that are available and their @sc{Matlab}
+compatibility.
+
+The major differences between Octave 3.2.N and  @sc{Matlab} R2008a are:
+
+ at itemize @bullet
+ at item Nested Functions
+
+Octave doesn't yet have nested functions. That is
+
+ at example
+ at group
+function y = foo (x)
+  y = bar(x)
+  function y = bar (x)
+    y = @dots{};
+  end
+end
+ at end group
+ at end example
+
+There was discussion in Octave of having these even prior to @sc{Matlab},
+and the decision was made not to have these in Octave at the time for
+compatibility.  The above written with sub-functions functions would be
+
+ at example
+ at group
+function y = foo (x)
+   y = bar(x)
+end
+function y = bar (x)
+   y = @dots{};
+end
+ at end group
+ at end example
+
+Now that @sc{Matlab} has recently introduced nested functions, Octave will
+probably have them soon as well.  Until then nested functions in Octave
+are treated as sub-functions with the same scoping rules as
+sub-functions.  
+
+The authors of Octave consider the nested function scoping rules of
+Matlab to be more problems than they are worth as they introduce
+diffiult to find bugs as inadvertantly modifying a variable in a
+nested function that is also used in the parent is particularly easy.
+
+ at item Differences in core syntax
+There a few core @sc{Matlab} syntaxes that are not accepted by Octave,
+these being
+
+ at itemize @bullet
+ at item
+Some limitations on the use of function handles. The major difference is
+related to nested function scoping rules (as above) and their use with
+function handles.
+
+ at item
+Some limitations of variable argument lists on the LHS of an expression,
+though the most common types are accepted.
+
+ at item
+ at sc{Matlab} classdef object oriented programming is not yet supportted,
+though work is underway and when development more on to Octave 3.3 this
+will be included in teh development tree.
+ at end itemize
+
+ at item Differences in core functions
+A large number of the @sc{Matlab} core functions (ie those that are in
+the core and not a toolbox) are implemented, and certainly all of the
+commonly used ones. There are a few functions that aren't implemented,
+for example @code{condest} or to do with specific missing Octave functionality
+(gui, dll, java, activex, dde, web, and serial functions). Some of the
+core functions have limitations that aren't in the @sc{Matlab}
+version.  For example the @code{sprandn} function can not force a
+particular condition number for the matrix like @sc{Matlab} can.
+
+ at item Just-In-Time compiler
+ at sc{Matlab} includes a "Just-In-Time" compiler. This compiler allows the
+acceleration of for-loops in @sc{Matlab} to almost native performance with
+certain restrictions. The JIT must know the return type of all functions
+called in the loops and so you can't include user functions in the loop
+of JIT optimized loops.  Octave doesn't have a JIT and so to some might
+seem slower than @sc{Matlab}.  For this reason you must vectorize your code as
+much as possible.  The MathWorks themselves have a good document
+discussing vectorization at
+ at url{http://www.mathworks.com/support/tech-notes/1100/1109.html}.
+
+ at item Compiler
+On a related point, there is no Octave compiler, and so you can't
+convert your Octave code into a binary for additional speed or
+distribution.  There is an example of how to do this at
+ at url{http://www.stud.tu-ilmenau.de/~rueckn/}, but this is a very early
+example code and would need lots of work to complete it.
+
+ at item Graphic Handles
+Up to Octave 2.9.9 there was no support for graphic handles in Octave
+itself.  In the 3.2.N versions of Octave the support for graphics
+handles is converging towards full compatibility. The @code{patch}
+function is currently limited to 2-D patches, due to an underlying
+limitation in gnuplot.
+
+ at item GUI 
+There are no @sc{Matlab} compatible GUI functions.  There are a number of
+bindings from Octave to Tcl/Tk, Vtk and zenity included in the
+Octave Forge project (@url{http://octave.sourceforge.net}) for example
+that can be used for a GUI, but these are not @sc{Matlab}
+compatible. Work on a matlab compatible GUI is in an alpha stage in the
+JHandles package (@url{http://octave.sourceforge.net/jhandles/index.html}).
+This might be an issue if you intend to exchange Octave code with 
+ at sc{Matlab} users.
+
+ at item Simulink
+Octave itself includes no Simulink support. Typically the simulink
+models lag research and are less flexible, so shouldn't really be used
+in a research environment.  However, some @sc{Matlab} users that try to
+use Octave complain about this lack.  There is a similar package to
+simulink for the Octave and R projects available at
+ at url{http://www.scicraft.org/}
+
+ at item Mex-Files
+Octave includes an API to the matlab MEX interface. However, as MEX is
+an API to the internals of @sc{Matlab} and the internals of Octave
+differ from @sc{Matlab}, there is necessarily a manipulation of the data
+to convert from a MEX interface to the Octave equivalent. This is
+notable for all complex matrices, where @sc{Matlab} stores complex
+arrays as real and imaginary parts, whereas Octave respects the C99/C++
+standards of co-locating the real/imag parts in memory.  Also due to the
+way @sc{Matlab} allows access to the arrays passed through a pointer,
+the MEX interface might require copies of arrays (even non complex
+ones).
+
+ at item Block comments
+Block comments denoted by "%@{" and "%@}" markers are supported by
+Octave with some limitations. The major limitation is that block
+comments are not supported within [] or @{@}.
+
+ at item Mat-File format
+There are some differences in the mat v5 file format accepted by
+Octave. @sc{Matlab} recently introduced the "-V7.3" save option which is
+an HDF5 format which is particularly useful for 64-bit platforms where
+the standard matlab format can not correctly save variables.. Octave
+accepts HDF5 files, but is not yet compatible with the "-v7.3" versions
+produced by @sc{Matlab}. 
+
+Although Octave can load inline abd function handles saved by
+ at sc{Matlab}, it can not yet save them.
+
+Finally, Some multi-byte unicode characters aren't yet treated in
+mat-files.
+
+ at item Profiler
+Octave doesn't have a profiler. Though there is a patch for a flat
+profiler, that might become a real profiler sometime in the future. see
+the thread
+
+ at url{http://www.cae.wisc.edu/pipermail/octave-maintainers/2007-January/001685.html}
+
+for more details
+
+ at item Toolboxes
+Octave is a community project and so the toolboxes that exist are
+donated by those interested in them through the Octave Forge website
+(@url{http://octave.sourceforge.net}). These might be lacking in certain
+functionality relative to the @sc{Matlab} toolboxes, and might not
+exactly duplicate the matlab functionality or interface.
+
+ at item Short-circuit & and | operators
+The @code{&} and @code{|} operators in @sc{Matlab} short-circuit when
+included in an if statemant and not otherwise.  In Octave only the
+ at code{&&} and @code{||} short circuit.  Note that this means that
+
+ at example
+ at group
+  if (a | b)
+    @dots{}
+  end
+ at end group
+ at end example
+
+and
+  
+ at example
+ at group
+  t = a | b;
+  if t
+    @dots{}
+  end
+ at end group
+ at end example
+
+ at noindent
+are different in @sc{Matlab}. This is really a @sc{Matlab} bug, but
+there is too much code out there that relies on this behavior to change
+it. Prefer the || and && operators in if statements if possible.
+
+Note that the difference is also significant when either argument is a
+function with side effects or if the first argument is a scalar and the
+second argument is an empty matrix.  For example, note the difference
+between
+
+ at example
+ at group
+  t = 1 | [];          ## results in [], so...
+  if (t) 1, end        ## in if ([]), this is false.
+ at end group
+ at end example
+
+and
+
+ at example
+  if (1 | []) 1, end   ## short circuits so condition is true.
+ at end example
+
+Another case that is documented in the @sc{Matlab} manuals is that
+
+ at example
+ at group
+  t = [1, 1] | [1, 2, 3];          ## error
+  if ([1, 1] | [1, 2, 3]) 1, end   ## OK
+ at end group
+ at end example
+
+Also @sc{Matlab} requires the operands of && and || to be scalar values but
+Octave does not (it just applies the rule that for an operand to be
+considered true, every element of the object must be nonzero or
+logically true).
+
+Finally, note the inconsistence of thinking of the condition of an if
+statement as being equivalent to @code{all(X(:))} when @var{X} is a
+matrix.  This is true for all cases EXCEPT empty matrices:
+
+ at example
+ at group
+  if ([0, 1]) == if (all ([0, 1]))   ==>  i.e., condition is false.
+  if ([1, 1]) == if (all ([1, 1]))   ==>  i.e., condition is true.
+ at end group
+ at end example
+
+However,
+
+ at example
+  if ([]) != if (all ([]))
+ at end example
+
+because @code{samp ([]) == 1} (because, despite the name, it is really
+returning true if none of the elements of the matrix are zero, and since
+there are no elements, well, none of them are zero).  But, somewhere
+along the line, someone decided that if @code{([])} should be false.
+Mathworks probably thought it just looks wrong to have @code{[]} be true
+in this context even if you can use logical gymnastics to convince
+yourself that "all" the elements of a matrix that doesn't actually have
+any elements are nonzero. Octave however duplicates this behavior for if
+statements containing empty matrices.
+
+ at item Solvers for singular, under- and over-determined matrices
+
+Matlab's solvers as used by the operators mldivide (\) and mrdivide (/),
+use a different approach than Octave's in the case of singular, under-, 
+or over-determined matrices. In the case of a singular matrix, Matlab
+returns the result given by the LU decomposition, even though the underlying
+solver has flagged the result as erroneous. Octave has made the choice
+of falling back to a minimum norm solution of matrices that have been
+flagged as singular which arguably is a better result for these cases.
+
+In the case of under- or over-determined matrices, Octave continues to
+use a minimum norm solution, whereas Matlab uses an approach that is
+equivalent to
+
+ at example
+ at group
+function x = mldivide (A, b)
+  [Q, R, E] = qr(A);
+  x = [A \ b, E(:, 1:m) * (R(:, 1:m) \ (Q' * b))]
+end
+ at end group
+ at end example
+
+ at noindent
+While this approach is certainly faster and uses less memory than
+Octave's minimum norm approach, this approach seems to be inferior in
+other ways.
+
+A numerical question arises: how big can the null space component become,
+relative to the minimum-norm solution? Can it be nicely bounded, or can it be
+arbitrarily big? Consider this example:
+
+ at example
+ at group
+m = 10; 
+n = 10000; 
+A = ones(m, n) + 1e-6 * randn(m,n); 
+b = ones(m, 1) + 1e-6 * randn(m,1); 
+norm(A \ b)
+ at end group
+ at end example
+
+ at noindent
+while Octave's minimum-norm values are around 3e-2, Matlab's results
+are 50-times larger. For another issue, try this code:
+
+ at example
+ at group
+m = 5; 
+n = 100; 
+j = floor(m * rand(1, n)) + 1; 
+b = ones(m, 1);
+A = zeros(m, n);
+A(sub2ind(size(A),j,1:n)) = 1;
+x = A \ b; 
+[dummy,p] = sort(rand(1,n)); 
+y = A(:,p)\b; 
+norm(x(p)-y)
+ at end group
+ at end example
+
+ at noindent
+It shows that unlike in Octave, mldivide in Matlab is not invariant
+with respect to column permutations. If there are multiple columns of
+the same norm, permuting columns of the matrix gets you different
+result than permuting the solution vector. This will surprise many
+users.
+
+Since the mldivide (\) and mrdivide (/) operators are often part of a more 
+complex expression, where there is no room to react to warnings or flags, it 
+should prefer intelligence (robustness) to speed, and so the Octave developers
+are firmly of the opinion that Octave's approach for singular, under- and
+over-determined matrices is a better choice that Matlab's
+
+ at item Octave extensions
+The extensions in Octave over @sc{Matlab} syntax are
+very useful, but might cause issues when sharing with @sc{Matlab} users.
+A list of the major extensions that should be avoided to be compatible
+with @sc{Matlab} are
+
+ at itemize @bullet
+ at item
+Comments in octave can be marked with @samp{#}. This allows POSIX
+systems to have the first line as @samp{#! octave -q} and mark the script
+itself executable. @sc{Matlab} doesn't have this feature due to the
+absence of comments starting with @samp{#}".
+
+ at item
+Code blocks like if, for, while, etc can be terminated with block
+specific terminations like "endif". @sc{Matlab} doesn't have this and
+all blocks must be terminated with "end"
+
+ at item
+Octave has a lisp like unwind_protect block that allows blocks of
+code that terminate in an error to ensure that the variables that
+are touched are restored. You can do something similar with
+ at code{try}/@code{catch} combined with @samp{rethrow (lasterror ())} in
+ at sc{Matlab}, however rethrow and lasterror are only available in Octave 2.9.10 and later.
+
+Note that using @code{try}/@code{catch} combined with @samp{rethrow
+(lasterror ())} can not guarantee that global variables will be
+correctly reset, as it won't catch user interrupts with Ctrl-C. For
+example
+
+ at example
+ at group
+  global a
+  a = 1;
+  try
+    _a = a;
+    a = 2
+    while true
+    end
+  catch
+    fprintf ('caught interrupt\n');
+    a = _a;
+    rethrow (lasterror());
+  end
+ at end group
+ at end example
+
+ at noindent
+compared to
+
+ at example
+ at group
+  global a
+  a = 1;
+  unwind_protect
+    _a = a;
+    a = 2
+    while true
+    end
+  unwind_protect_cleanup
+    fprintf ('caught interrupt\n');
+    a = _a;
+  end
+ at end group
+ at end example
+
+Typing Ctrl-C in the first case returns the user directly to the
+prompt, and the variable "a" is not reset to the saved value. In the
+second case the variable "a" is reset correctly.  Therefore @sc{Matlab}
+gives no save way of temporarily changing global variables.
+
+ at item
+Indexing can be applied to all objects in Octave and not just
+variable. Therefore @code{sin(x)(1:10);} for example is perfectly valid
+in Octave but not @sc{Matlab}. To do the same in @sc{Matlab} you must do
+ at code{y = sin(x); y = y([1:10]);}
+
+ at item
+Octave has the operators "++", "--", "-=", "+=", "*=", etc.  As
+ at sc{Matlab} doesn't, if you are sharing code these should be avoided.
+
+ at item
+Character strings in Octave can be denoted with double or single
+quotes. There is a subtle difference between the two in that escaped
+characters like @code{\n} (newline), @code{\t} (tab), etc are
+interpreted in double quoted strings but not single quoted strings. This
+difference is important on Windows platforms where the "\" character is
+used in path names, and so single quoted strings should be used in
+paths. @sc{Matlab} doesn't have double quoted strings and so they should
+be avoided if the code will be transfered to a @sc{Matlab} user.
+ at end itemize
+
+ at end itemize
+
+ at node Index
+ at appendix Concept Index
+
+ at printindex cp
+
+ at page
+ at contents
+ at bye
diff --git a/doc/interpreter/HTML/A-Sample-Command-Description.html b/doc/interpreter/HTML/A-Sample-Command-Description.html
new file mode 100644
index 0000000..1ff8749
--- /dev/null
+++ b/doc/interpreter/HTML/A-Sample-Command-Description.html
@@ -0,0 +1,54 @@
+<html lang="en">
+<head>
+<title>A Sample Command Description - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Format-of-Descriptions.html#Format-of-Descriptions" title="Format of Descriptions">
+<link rel="prev" href="A-Sample-Function-Description.html#A-Sample-Function-Description" title="A Sample Function Description">
+<link rel="next" href="A-Sample-Variable-Description.html#A-Sample-Variable-Description" title="A Sample Variable Description">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="A-Sample-Command-Description"></a>
+Next: <a rel="next" accesskey="n" href="A-Sample-Variable-Description.html#A-Sample-Variable-Description">A Sample Variable Description</a>,
+Previous: <a rel="previous" accesskey="p" href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a>,
+Up: <a rel="up" accesskey="u" href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">1.3.5.2 A Sample Command Description</h5>
+
+<p><a name="index-command-descriptions-22"></a>
+Command descriptions have a format similar to function descriptions,
+except that the word `Function' is replaced by `Command'.  Commands are
+functions that may be called without surrounding their arguments in
+parentheses.  For example, here is the description for Octave's
+<code>cd</code> command:
+
+<div class="defun">
+— Command: <b>cd</b><var> dir<a name="index-cd-23"></a></var><br>
+— Command: <b>chdir</b><var> dir<a name="index-chdir-24"></a></var><br>
+<blockquote><p>Change the current working directory to <var>dir</var>.  For example,
+<kbd>cd ~/octave</kbd> changes the current working directory to
+<samp><span class="file">~/octave</span></samp>.  If the directory does not exist, an error message is
+printed and the working directory is not changed. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/A-Sample-Function-Description.html b/doc/interpreter/HTML/A-Sample-Function-Description.html
new file mode 100644
index 0000000..42d6b41
--- /dev/null
+++ b/doc/interpreter/HTML/A-Sample-Function-Description.html
@@ -0,0 +1,91 @@
+<html lang="en">
+<head>
+<title>A Sample Function Description - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Format-of-Descriptions.html#Format-of-Descriptions" title="Format of Descriptions">
+<link rel="next" href="A-Sample-Command-Description.html#A-Sample-Command-Description" title="A Sample Command Description">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="A-Sample-Function-Description"></a>
+Next: <a rel="next" accesskey="n" href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a>,
+Up: <a rel="up" accesskey="u" href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">1.3.5.1 A Sample Function Description</h5>
+
+<p><a name="index-function-descriptions-16"></a>
+In a function description, the name of the function being described
+appears first.  It is followed on the same line by a list of parameters. 
+The names used for the parameters are also used in the body of the
+description.
+
+   <p>Here is a description of an imaginary function <code>foo</code>:
+
+<div class="defun">
+— Function:  <b>foo</b> (<var>x, y, <small class="dots">...</small></var>)<var><a name="index-foo-17"></a></var><br>
+<blockquote><p>The function <code>foo</code> subtracts <var>x</var> from <var>y</var>, then adds the
+remaining arguments to the result.  If <var>y</var> is not supplied, then the
+number 19 is used by default.
+
+     <pre class="example">          foo (1, [3, 5], 3, 9)
+                [ 14, 16 ]
+          foo (5)
+                14
+</pre>
+        <p>More generally,
+
+     <pre class="example">          foo (<var>w</var>, <var>x</var>, <var>y</var>, ...)
+          ==
+          <var>x</var> - <var>w</var> + <var>y</var> + ...
+</pre>
+        </blockquote></div>
+
+   <p>Any parameter whose name contains the name of a type (e.g.,
+<var>integer</var> or <var>matrix</var>) is expected to be of that
+type.  Parameters named <var>object</var> may be of any type.  Parameters
+with other sorts of names (e.g., <var>new_file</var>) are discussed
+specifically in the description of the function.  In some sections,
+features common to parameters of several functions are described at the
+beginning.
+
+   <p>Functions in Octave may be defined in several different ways.  The
+category name for functions may include another name that indicates the
+way that the function is defined.  These additional tags include
+
+     <dl>
+<dt>Function File<dd><a name="index-function-file-18"></a>The function described is defined using Octave commands stored in a text
+file.  See <a href="Function-Files.html#Function-Files">Function Files</a>.
+
+     <br><dt>Built-in Function<dd><a name="index-built_002din-function-19"></a>The function described is written in a language like C++, C, or Fortran,
+and is part of the compiled Octave binary.
+
+     <br><dt>Loadable Function<dd><a name="index-loadable-function-20"></a>The function described is written in a language like C++, C, or Fortran. 
+On systems that support dynamic linking of user-supplied functions, it
+may be automatically linked while Octave is running, but only if it is
+needed.  See <a href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>.
+
+     <br><dt>Mapping Function<dd><a name="index-mapping-function-21"></a>The function described works element-by-element for matrix and vector
+arguments. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/A-Sample-Variable-Description.html b/doc/interpreter/HTML/A-Sample-Variable-Description.html
new file mode 100644
index 0000000..65a0ad1
--- /dev/null
+++ b/doc/interpreter/HTML/A-Sample-Variable-Description.html
@@ -0,0 +1,74 @@
+<html lang="en">
+<head>
+<title>A Sample Variable Description - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Format-of-Descriptions.html#Format-of-Descriptions" title="Format of Descriptions">
+<link rel="prev" href="A-Sample-Command-Description.html#A-Sample-Command-Description" title="A Sample Command Description">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="A-Sample-Variable-Description"></a>
+Previous: <a rel="previous" accesskey="p" href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a>,
+Up: <a rel="up" accesskey="u" href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">1.3.5.3 A Sample Variable Description</h5>
+
+<p><a name="index-variable-descriptions-25"></a>
+A <dfn>variable</dfn> is a name that can hold a value.  Although any variable
+can be set by the user, <dfn>built-in variables</dfn> typically exist
+specifically so that users can change them to alter the way Octave
+behaves (built-in variables are also sometimes called <dfn>user
+options</dfn>).  Ordinary variables and built-in variables are described
+using a format like that for functions except that there are no
+arguments.
+
+   <p>Here is a description of the imaginary variable
+<code>do_what_i_mean_not_what_i_say</code>.
+
+<div class="defun">
+— Built-in Variable: <b>do_what_i_mean_not_what_i_say</b><var><a name="index-do_005fwhat_005fi_005fmean_005fnot_005fwhat_005fi_005fsay-26"></a></var><br>
+<blockquote><p>If the value of this variable is nonzero, Octave will do what you
+actually wanted, even if you have typed a completely different and
+meaningless list of commands. 
+</p></blockquote></div>
+
+   <p>Other variable descriptions have the same format, but `Built-in
+Variable' is replaced by `Variable', for ordinary variables, or
+`Constant' for symbolic constants whose values cannot be changed.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2005, 2006, -->
+<!-- 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Accessing-Global-Variables-in-Oct_002dFiles.html b/doc/interpreter/HTML/Accessing-Global-Variables-in-Oct_002dFiles.html
new file mode 100644
index 0000000..c599048
--- /dev/null
+++ b/doc/interpreter/HTML/Accessing-Global-Variables-in-Oct_002dFiles.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Accessing Global Variables in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles" title="Sparse Matrices in Oct-Files">
+<link rel="next" href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles" title="Calling Octave Functions from Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Accessing-Global-Variables-in-Oct-Files"></a>
+<a name="Accessing-Global-Variables-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles">Calling Octave Functions from Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.7 Accessing Global Variables in Oct-Files</h4>
+
+<p>Global variables allow variables in the global scope to be
+accessed.  Global variables can easily be accessed with oct-files using
+the support functions <code>get_global_value</code> and
+<code>set_global_value</code>.  <code>get_global_value</code> takes two arguments,
+the first is a string representing the variable name to obtain.  The
+second argument is a boolean argument specifying what to do in the case
+that no global variable of the desired name is found.  An example of the
+use of these two functions is
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     
+     DEFUN_DLD (globaldemo, args, , "Global demo.")
+     {
+       int nargin = args.length ();
+       octave_value retval;
+     
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           std::string s = args(0).string_value ();
+           if (! error_state)
+             {
+               octave_value tmp = get_global_value (s, true);
+               if (tmp.is_defined ())
+                 retval = tmp;
+               else
+                 retval = "Global variable not found";
+     
+               set_global_value ("a", 42.0);
+             }
+         }
+       return retval;
+     }
+</pre></pre>
+   <p>An example of its use is
+
+<pre class="example">     global a b
+     b = 10;
+     globaldemo ("b")
+      10
+     globaldemo ("c")
+      "Global variable not found"
+     num2str (a)
+      42
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Acknowledgements.html b/doc/interpreter/HTML/Acknowledgements.html
new file mode 100644
index 0000000..cca7b20
--- /dev/null
+++ b/doc/interpreter/HTML/Acknowledgements.html
@@ -0,0 +1,173 @@
+<html lang="en">
+<head>
+<title>Acknowledgements - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Preface.html#Preface" title="Preface">
+<link rel="next" href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave" title="How You Can Contribute to Octave">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Acknowledgements"></a>
+Next: <a rel="next" accesskey="n" href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a>,
+Up: <a rel="up" accesskey="u" href="Preface.html#Preface">Preface</a>
+<hr>
+</div>
+
+<h3 class="unnumberedsec">Acknowledgements</h3>
+
+<p><a name="index-acknowledgements-3"></a>
+Many people have already contributed to Octave's development.  The
+following people have helped code parts of Octave or aided in
+various other ways (listed alphabetically).
+
+   <p><table summary=""><tr align="left"><td valign="top" width="33%">Ben Abbott </td><td valign="top" width="33%">Andy Adler </td><td valign="top" width="33%">Joel Andersson
+<br></td></tr><tr align="left"><td valign="top" width="33%">Muthiah Annamalai </td><td valign="top" width="33%">Shai Ayal </td><td valign="top" width="33%">Roger Banks
+<br></td></tr><tr align="left"><td valign="top" width="33%">Ben Barrowes </td><td valign="top" width="33%">Alexander Barth </td><td valign="top" width="33%">David Bateman
+<br></td></tr><tr align="left"><td valign="top" width="33%">Heinz Bauschke </td><td valign="top" width="33%">Karl Berry </td><td valign="top" width="33%">David Billinghurst
+<br></td></tr><tr align="left"><td valign="top" width="33%">Don Bindner </td><td valign="top" width="33%">Jakub Bogusz </td><td valign="top" width="33%">Moritz Borgmann
+<br></td></tr><tr align="left"><td valign="top" width="33%">Richard Bovey </td><td valign="top" width="33%">Marcus Brinkmann </td><td valign="top" width="33%">Remy Bruno
+<br></td></tr><tr align="left"><td valign="top" width="33%">Marco Caliari </td><td valign="top" width="33%">Daniel Calvelo </td><td valign="top" width="33%">John C. Campbell
+<br></td></tr><tr align="left"><td valign="top" width="33%">Jean-Francois Cardoso </td><td valign="top" width="33%">Joao Cardoso </td><td valign="top" width="33%">Larrie Carr
+<br></td></tr><tr align="left"><td valign="top" width="33%">David Castelow </td><td valign="top" width="33%">Vincent Cautaerts </td><td valign="top" width="33%">Clinton Chee
+<br></td></tr><tr align="left"><td valign="top" width="33%">Albert Chin-A-Young </td><td valign="top" width="33%">Carsten Clark </td><td valign="top" width="33%">J. D. Cole
+<br></td></tr><tr align="left"><td valign="top" width="33%">Martin Costabel </td><td valign="top" width="33%">Michael Creel </td><td valign="top" width="33%">Jeff Cunningham
+<br></td></tr><tr align="left"><td valign="top" width="33%">Martin Dalecki </td><td valign="top" width="33%">Jorge Barros de Abreu </td><td valign="top" width="33%">Carlo de Falco
+<br></td></tr><tr align="left"><td valign="top" width="33%">Thomas D. Dean </td><td valign="top" width="33%">Philippe Defert </td><td valign="top" width="33%">Bill Denney
+<br></td></tr><tr align="left"><td valign="top" width="33%">David M. Doolin </td><td valign="top" width="33%">Pascal A. Dupuis </td><td valign="top" width="33%">John W. Eaton
+<br></td></tr><tr align="left"><td valign="top" width="33%">Dirk Eddelbuettel </td><td valign="top" width="33%">Paul Eggert </td><td valign="top" width="33%">Stephen Eglen
+<br></td></tr><tr align="left"><td valign="top" width="33%">Peter Ekberg </td><td valign="top" width="33%">Rolf Fabian </td><td valign="top" width="33%">Stephen Fegan
+<br></td></tr><tr align="left"><td valign="top" width="33%">Ramon Garcia Fernandez </td><td valign="top" width="33%">Torsten Finke </td><td valign="top" width="33%">Jose Daniel Munoz Frias
+<br></td></tr><tr align="left"><td valign="top" width="33%">Castor Fu </td><td valign="top" width="33%">Eduardo Gallestey </td><td valign="top" width="33%">Walter Gautschi
+<br></td></tr><tr align="left"><td valign="top" width="33%">Klaus Gebhardt </td><td valign="top" width="33%">Driss Ghaddab </td><td valign="top" width="33%">Nicolo Giorgetti
+<br></td></tr><tr align="left"><td valign="top" width="33%">Michael Goffioul </td><td valign="top" width="33%">Glenn Golden </td><td valign="top" width="33%">Tomislav Goles
+<br></td></tr><tr align="left"><td valign="top" width="33%">Keith Goodman </td><td valign="top" width="33%">Brian Gough </td><td valign="top" width="33%">Steffen Groot
+<br></td></tr><tr align="left"><td valign="top" width="33%">Etienne Grossmann </td><td valign="top" width="33%">Peter Gustafson </td><td valign="top" width="33%">Kai Habel
+<br></td></tr><tr align="left"><td valign="top" width="33%">William P. Y. Hadisoeseno </td><td valign="top" width="33%">Jaroslav Hajek </td><td valign="top" width="33%">Benjamin Hall
+<br></td></tr><tr align="left"><td valign="top" width="33%">Kim Hansen </td><td valign="top" width="33%">Soren Hauberg </td><td valign="top" width="33%">Dave Hawthorne
+<br></td></tr><tr align="left"><td valign="top" width="33%">Daniel Heiserer </td><td valign="top" width="33%">Martin Helm </td><td valign="top" width="33%">Stefan Hepp
+<br></td></tr><tr align="left"><td valign="top" width="33%">Yozo Hida </td><td valign="top" width="33%">Ryan Hinton </td><td valign="top" width="33%">Roman Hodek
+<br></td></tr><tr align="left"><td valign="top" width="33%">A. Scottedward Hodel </td><td valign="top" width="33%">Richard Allan Holcombe </td><td valign="top" width="33%">Tom Holroyd
+<br></td></tr><tr align="left"><td valign="top" width="33%">David Hoover </td><td valign="top" width="33%">Kurt Hornik </td><td valign="top" width="33%">Christopher Hulbert
+<br></td></tr><tr align="left"><td valign="top" width="33%">Cyril Humbert </td><td valign="top" width="33%">Teemu Ikonen </td><td valign="top" width="33%">Alan W. Irwin
+<br></td></tr><tr align="left"><td valign="top" width="33%">Geoff Jacobsen </td><td valign="top" width="33%">Mats Jansson </td><td valign="top" width="33%">Cai Jianming
+<br></td></tr><tr align="left"><td valign="top" width="33%">Steven G. Johnson </td><td valign="top" width="33%">Heikki Junes </td><td valign="top" width="33%">Atsushi Kajita
+<br></td></tr><tr align="left"><td valign="top" width="33%">Jarkko Kaleva </td><td valign="top" width="33%">Mohamed Kamoun </td><td valign="top" width="33%">Lute Kamstra
+<br></td></tr><tr align="left"><td valign="top" width="33%">Thomas Kasper </td><td valign="top" width="33%">Joel Keay </td><td valign="top" width="33%">Mumit Khan
+<br></td></tr><tr align="left"><td valign="top" width="33%">Paul Kienzle </td><td valign="top" width="33%">Aaron A. King </td><td valign="top" width="33%">Arno J. Klaassen
+<br></td></tr><tr align="left"><td valign="top" width="33%">Geoffrey Knauth </td><td valign="top" width="33%">Heine Kolltveit </td><td valign="top" width="33%">Ken Kouno
+<br></td></tr><tr align="left"><td valign="top" width="33%">Oyvind Kristiansen </td><td valign="top" width="33%">Piotr Krzyzanowski </td><td valign="top" width="33%">Volker Kuhlmann
+<br></td></tr><tr align="left"><td valign="top" width="33%">Tetsuro Kurita </td><td valign="top" width="33%">Miroslaw Kwasniak </td><td valign="top" width="33%">Rafael Laboissiere
+<br></td></tr><tr align="left"><td valign="top" width="33%">Kai Labusch </td><td valign="top" width="33%">Claude Lacoursiere </td><td valign="top" width="33%">Walter Landry
+<br></td></tr><tr align="left"><td valign="top" width="33%">Bill Lash </td><td valign="top" width="33%">Dirk Laurie </td><td valign="top" width="33%">Maurice LeBrun
+<br></td></tr><tr align="left"><td valign="top" width="33%">Friedrich Leisch </td><td valign="top" width="33%">Timo Lindfors </td><td valign="top" width="33%">Benjamin Lindner
+<br></td></tr><tr align="left"><td valign="top" width="33%">Ross Lippert </td><td valign="top" width="33%">David Livings </td><td valign="top" width="33%">Erik de Castro Lopo
+<br></td></tr><tr align="left"><td valign="top" width="33%">Massimo Lorenzin </td><td valign="top" width="33%">Emil Lucretiu </td><td valign="top" width="33%">Hoxide Ma
+<br></td></tr><tr align="left"><td valign="top" width="33%">James Macnicol </td><td valign="top" width="33%">Jens-Uwe Mager </td><td valign="top" width="33%">Ricardo Marranita
+<br></td></tr><tr align="left"><td valign="top" width="33%">Orestes Mas </td><td valign="top" width="33%">Makoto Matsumoto </td><td valign="top" width="33%">Tatsuro Matsuoka
+<br></td></tr><tr align="left"><td valign="top" width="33%">Laurent Mazet </td><td valign="top" width="33%">G. D. McBain </td><td valign="top" width="33%">Alexander Mamonov
+<br></td></tr><tr align="left"><td valign="top" width="33%">Christoph Mayer </td><td valign="top" width="33%">Thorsten Meyer </td><td valign="top" width="33%">Petr Mikulik
+<br></td></tr><tr align="left"><td valign="top" width="33%">Stefan Monnier </td><td valign="top" width="33%">Antoine Moreau </td><td valign="top" width="33%">Kai P. Mueller
+<br></td></tr><tr align="left"><td valign="top" width="33%">Victor Munoz </td><td valign="top" width="33%">Carmen Navarrete </td><td valign="top" width="33%">Todd Neal
+<br></td></tr><tr align="left"><td valign="top" width="33%">Al Niessner </td><td valign="top" width="33%">Rick Niles </td><td valign="top" width="33%">Takuji Nishimura
+<br></td></tr><tr align="left"><td valign="top" width="33%">Kai Noda </td><td valign="top" width="33%">Eric Norum </td><td valign="top" width="33%">Krzesimir Nowak
+<br></td></tr><tr align="left"><td valign="top" width="33%">Michael O'Brien </td><td valign="top" width="33%">Peter O'Gorman </td><td valign="top" width="33%">Thorsten Ohl
+<br></td></tr><tr align="left"><td valign="top" width="33%">Arno Onken </td><td valign="top" width="33%">Luis F. Ortiz </td><td valign="top" width="33%">Scott Pakin
+<br></td></tr><tr align="left"><td valign="top" width="33%">Gabriele Pannocchia </td><td valign="top" width="33%">Sylvain Pelissier </td><td valign="top" width="33%">Per Persson
+<br></td></tr><tr align="left"><td valign="top" width="33%">Primozz Peterlin </td><td valign="top" width="33%">Jim Peterson </td><td valign="top" width="33%">Danilo Piazzalunga
+<br></td></tr><tr align="left"><td valign="top" width="33%">Nicholas Piper </td><td valign="top" width="33%">Robert Platt </td><td valign="top" width="33%">Hans Ekkehard Plesser
+<br></td></tr><tr align="left"><td valign="top" width="33%">Tom Poage </td><td valign="top" width="33%">Orion Poplawski </td><td valign="top" width="33%">Ondrej Popp
+<br></td></tr><tr align="left"><td valign="top" width="33%">Jef Poskanzer </td><td valign="top" width="33%">Francesco Potorti </td><td valign="top" width="33%">James B. Rawlings
+<br></td></tr><tr align="left"><td valign="top" width="33%">Eric S. Raymond </td><td valign="top" width="33%">Balint Reczey </td><td valign="top" width="33%">Michael Reifenberger
+<br></td></tr><tr align="left"><td valign="top" width="33%">Jason Riedy </td><td valign="top" width="33%">Petter Risholm </td><td valign="top" width="33%">Matthew W. Roberts
+<br></td></tr><tr align="left"><td valign="top" width="33%">Andrew Ross </td><td valign="top" width="33%">Mark van Rossum </td><td valign="top" width="33%">Kevin Ruland
+<br></td></tr><tr align="left"><td valign="top" width="33%">Ryan Rusaw </td><td valign="top" width="33%">Olli Saarela </td><td valign="top" width="33%">Toni Saarela
+<br></td></tr><tr align="left"><td valign="top" width="33%">Juhani Saastamoinen </td><td valign="top" width="33%">Radek Salac </td><td valign="top" width="33%">Ben Sapp
+<br></td></tr><tr align="left"><td valign="top" width="33%">Aleksej Saushev </td><td valign="top" width="33%">Alois Schloegl </td><td valign="top" width="33%">Michel D. Schmid
+<br></td></tr><tr align="left"><td valign="top" width="33%">Julian Schnidder </td><td valign="top" width="33%">Nicol N. Schraudolph </td><td valign="top" width="33%">Sebastian Schubert
+<br></td></tr><tr align="left"><td valign="top" width="33%">Ludwig Schwardt </td><td valign="top" width="33%">Thomas L. Scofield </td><td valign="top" width="33%">Daniel J. Sebald
+<br></td></tr><tr align="left"><td valign="top" width="33%">Dmitri A. Sergatskov </td><td valign="top" width="33%">Baylis Shanks </td><td valign="top" width="33%">Joseph P. Skudlarek
+<br></td></tr><tr align="left"><td valign="top" width="33%">John Smith </td><td valign="top" width="33%">Julius Smith </td><td valign="top" width="33%">Shan G. Smith
+<br></td></tr><tr align="left"><td valign="top" width="33%">Joerg Specht </td><td valign="top" width="33%">Quentin H. Spencer </td><td valign="top" width="33%">Christoph Spiel
+<br></td></tr><tr align="left"><td valign="top" width="33%">Richard Stallman </td><td valign="top" width="33%">Russell Standish </td><td valign="top" width="33%">Doug Stewart
+<br></td></tr><tr align="left"><td valign="top" width="33%">Jonathan Stickel </td><td valign="top" width="33%">Thomas Stuart </td><td valign="top" width="33%">Ivan Sutoris
+<br></td></tr><tr align="left"><td valign="top" width="33%">John Swensen </td><td valign="top" width="33%">Ariel Tankus </td><td valign="top" width="33%">Georg Thimm
+<br></td></tr><tr align="left"><td valign="top" width="33%">Duncan Temple Lang </td><td valign="top" width="33%">Kris Thielemans </td><td valign="top" width="33%">Olaf Till
+<br></td></tr><tr align="left"><td valign="top" width="33%">Thomas Treichl </td><td valign="top" width="33%">Frederick Umminger </td><td valign="top" width="33%">Utkarsh Upadhyay
+<br></td></tr><tr align="left"><td valign="top" width="33%">Stefan van der Walt </td><td valign="top" width="33%">Peter Van Wieren </td><td valign="top" width="33%">James R. Van Zandt
+<br></td></tr><tr align="left"><td valign="top" width="33%">Gregory Vanuxem </td><td valign="top" width="33%">Ivana Varekova </td><td valign="top" width="33%">Thomas Walter
+<br></td></tr><tr align="left"><td valign="top" width="33%">Olaf Weber </td><td valign="top" width="33%">Thomas Weber </td><td valign="top" width="33%">Rik Wehbring
+<br></td></tr><tr align="left"><td valign="top" width="33%">Bob Weigel </td><td valign="top" width="33%">Andreas Weingessel </td><td valign="top" width="33%">Michael Weitzel
+<br></td></tr><tr align="left"><td valign="top" width="33%">Fook Fah Yap </td><td valign="top" width="33%">Michael Zeising </td><td valign="top" width="33%">Federico Zenith
+<br></td></tr><tr align="left"><td valign="top" width="33%">Alex Zvoleff
+   <br></td></tr></table>
+
+   <p>Special thanks to the following people and organizations for
+supporting the development of Octave:
+
+     <ul>
+<li>The United States Department of Energy, through grant number
+DE-FG02-04ER25635.
+
+     <li>Ashok Krishnamurthy, David Hudak, Juan Carlos Chaves, and Stanley
+C. Ahalt of the Ohio Supercomputer Center.
+
+     <li>The National Science Foundation, through grant numbers CTS-0105360,
+CTS-9708497, CTS-9311420, CTS-8957123, and CNS-0540147.
+
+     <li>The industrial members of the Texas-Wisconsin Modeling and Control
+Consortium (<a href="http://www.che.utexas.edu/twmcc">TWMCC</a>).
+
+     <li>The Paul A. Elfers Endowed Chair in Chemical Engineering at the
+University of Wisconsin-Madison.
+
+     <li>Digital Equipment Corporation, for an equipment grant as part of their
+External Research Program.
+
+     <li>Sun Microsystems, Inc., for an Academic Equipment grant.
+
+     <li>International Business Machines, Inc., for providing equipment as part
+of a grant to the University of Texas College of Engineering.
+
+     <li>Texaco Chemical Company, for providing funding to continue the
+development of this software.
+
+     <li>The University of Texas College of Engineering, for providing a
+Challenge for Excellence Research Supplement, and for providing an
+Academic Development Funds grant.
+
+     <li>The State of Texas, for providing funding through the Texas
+Advanced Technology Program under Grant No. 003658-078.
+
+     <li>Noel Bell, Senior Engineer, Texaco Chemical Company, Austin Texas.
+
+     <li>John A. Turner, Group Leader, Continuum Dynamics (CCS-2), Los Alamos
+National Laboratory, for registering the <a href="octave.org">octave.org</a> domain name.
+
+     <li>James B. Rawlings, Professor, University of Wisconsin-Madison,
+Department of Chemical and Biological Engineering.
+
+     <li>Richard Stallman, for writing GNU. 
+</ul>
+
+   <p>This project would not have been possible without the GNU software used
+in and to produce Octave.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Actual-Bugs.html b/doc/interpreter/HTML/Actual-Bugs.html
new file mode 100644
index 0000000..285264a
--- /dev/null
+++ b/doc/interpreter/HTML/Actual-Bugs.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Actual Bugs - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="next" href="Reporting-Bugs.html#Reporting-Bugs" title="Reporting Bugs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Actual-Bugs"></a>
+Next: <a rel="next" accesskey="n" href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.1 Actual Bugs We Haven't Fixed Yet</h3>
+
+     <ul>
+<li>Output that comes directly from Fortran functions is not sent through
+the pager and may appear out of sequence with other output that is sent
+through the pager.  One way to avoid this is to force pending output to
+be flushed before calling a function that will produce output from
+within Fortran functions.  To do this, use the command
+
+     <pre class="example">          fflush (stdout)
+</pre>
+     <p>Another possible workaround is to use the command
+
+     <pre class="example">          page_screen_output (false);
+</pre>
+     <p class="noindent">to turn the pager off. 
+</ul>
+
+   <p>A list of ideas for future enhancements is distributed with Octave.  See
+the file <samp><span class="file">PROJECTS</span></samp> in the top level directory in the source
+distribution.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Administrating-Packages.html b/doc/interpreter/HTML/Administrating-Packages.html
new file mode 100644
index 0000000..353b747
--- /dev/null
+++ b/doc/interpreter/HTML/Administrating-Packages.html
@@ -0,0 +1,68 @@
+<html lang="en">
+<head>
+<title>Administrating Packages - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Packages.html#Packages" title="Packages">
+<link rel="prev" href="Using-Packages.html#Using-Packages" title="Using Packages">
+<link rel="next" href="Creating-Packages.html#Creating-Packages" title="Creating Packages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Administrating-Packages"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Packages.html#Creating-Packages">Creating Packages</a>,
+Previous: <a rel="previous" accesskey="p" href="Using-Packages.html#Using-Packages">Using Packages</a>,
+Up: <a rel="up" accesskey="u" href="Packages.html#Packages">Packages</a>
+<hr>
+</div>
+
+<h3 class="section">35.3 Administrating Packages</h3>
+
+<p>On UNIX-like systems it is possible to make both per-user and
+system-wide installations of a package.  If the user performing the
+installation is <code>root</code> the packages will be installed in a
+system-wide directory that defaults to
+<samp><span class="file">OCTAVE_HOME/share/octave/packages/</span></samp>.  If the user is not
+<code>root</code> the default installation directory is
+<samp><span class="file">~/octave/</span></samp>.  Packages will be installed in a subdirectory of the
+installation directory that will be named after the package.  It is
+possible to change the installation directory by using the
+<code>pkg prefix</code> command
+
+<pre class="example">     pkg prefix new_installation_directory
+</pre>
+   <p class="noindent">The current installation directory can be retrieved by typing
+
+<pre class="example">     current_installation_directory = pkg prefix
+</pre>
+   <p>To function properly the package manager needs to keep some
+information about the installed packages.  For per-user packages this
+information is by default stored in the file <samp><span class="file">~/.octave_packages</span></samp>
+and for system-wide installations it is stored in
+<samp><span class="file">OCTAVE_HOME/share/octave/octave_packages</span></samp>.  The path to the
+per-user file can be changed with the <code>pkg local_list</code> command
+
+<pre class="example">     pkg local_list /path/to/new_file
+</pre>
+   <p class="noindent">For system-wide installations this can be changed in the same way
+using the <code>pkg global_list</code> command.  If these commands are
+called without a new path, the current path will be returned.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Advanced-Plotting.html b/doc/interpreter/HTML/Advanced-Plotting.html
new file mode 100644
index 0000000..78ce2d3
--- /dev/null
+++ b/doc/interpreter/HTML/Advanced-Plotting.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Advanced Plotting - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting.html#Plotting" title="Plotting">
+<link rel="prev" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Advanced-Plotting"></a>
+Previous: <a rel="previous" accesskey="p" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>,
+Up: <a rel="up" accesskey="u" href="Plotting.html#Plotting">Plotting</a>
+<hr>
+</div>
+
+<h3 class="section">15.2 Advanced Plotting</h3>
+
+<ul class="menu">
+<li><a accesskey="1" href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a>
+<li><a accesskey="2" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<li><a accesskey="3" href="Managing-Default-Properties.html#Managing-Default-Properties">Managing Default Properties</a>
+<li><a accesskey="4" href="Colors.html#Colors">Colors</a>
+<li><a accesskey="5" href="Line-Styles.html#Line-Styles">Line Styles</a>
+<li><a accesskey="6" href="Marker-Styles.html#Marker-Styles">Marker Styles</a>
+<li><a accesskey="7" href="Callbacks.html#Callbacks">Callbacks</a>
+<li><a accesskey="8" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<li><a accesskey="9" href="Graphics-backends.html#Graphics-backends">Graphics backends</a>
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Allocating-Local-Memory-in-Oct_002dFiles.html b/doc/interpreter/HTML/Allocating-Local-Memory-in-Oct_002dFiles.html
new file mode 100644
index 0000000..c18efa3
--- /dev/null
+++ b/doc/interpreter/HTML/Allocating-Local-Memory-in-Oct_002dFiles.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Allocating Local Memory in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles" title="Calling External Code from Oct-Files">
+<link rel="next" href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles" title="Input Parameter Checking in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Allocating-Local-Memory-in-Oct-Files"></a>
+<a name="Allocating-Local-Memory-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles">Input Parameter Checking in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles">Calling External Code from Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.10 Allocating Local Memory in Oct-Files</h4>
+
+<p>Allocating memory within an oct-file might seem easy as the C++
+new/delete operators can be used.  However, in that case care must be
+taken to avoid memory leaks.  The preferred manner in which to allocate
+memory for use locally is to use the <code>OCTAVE_LOCAL_BUFFER</code><!-- /@w --> macro. 
+An example of its use is
+
+<pre class="example">     OCTAVE_LOCAL_BUFFER (double, tmp, len)
+</pre>
+   <p>that returns a pointer <code>tmp</code> of type <code>double *</code> of length
+<code>len</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Anonymous-Functions.html b/doc/interpreter/HTML/Anonymous-Functions.html
new file mode 100644
index 0000000..acaa3b6
--- /dev/null
+++ b/doc/interpreter/HTML/Anonymous-Functions.html
@@ -0,0 +1,70 @@
+<html lang="en">
+<head>
+<title>Anonymous Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions" title="Function Handles Inline Functions and Anonymous Functions">
+<link rel="prev" href="Function-Handles.html#Function-Handles" title="Function Handles">
+<link rel="next" href="Inline-Functions.html#Inline-Functions" title="Inline Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Anonymous-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Inline-Functions.html#Inline-Functions">Inline Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Function-Handles.html#Function-Handles">Function Handles</a>,
+Up: <a rel="up" accesskey="u" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.9.2 Anonymous Functions</h4>
+
+<p>Anonymous functions are defined using the syntax
+
+<pre class="example">     @(<var>argument-list</var>) <var>expression</var>
+</pre>
+   <p class="noindent">Any variables that are not found in the argument list are inherited from
+the enclosing scope.  Anonymous functions are useful for creating simple
+unnamed functions from expressions or for wrapping calls to other
+functions to adapt them for use by functions like <code>quad</code>.  For
+example,
+
+<pre class="example">     f = @(x) x.^2;
+     quad (f, 0, 10)
+          333.33
+</pre>
+   <p class="noindent">creates a simple unnamed function from the expression <code>x.^2</code> and
+passes it to <code>quad</code>,
+
+<pre class="example">     quad (@(x) sin (x), 0, pi)
+          2
+</pre>
+   <p class="noindent">wraps another function, and
+
+<pre class="example">     a = 1;
+     b = 2;
+     quad (@(x) betainc (x, a, b), 0, 0.4)
+          0.13867
+</pre>
+   <p class="noindent">adapts a function with several parameters to the form required by
+<code>quad</code>.  In this example, the values of <var>a</var> and <var>b</var> that
+are passed to <code>betainc</code> are inherited from the current
+environment.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Applying-a-Function-to-an-Array.html b/doc/interpreter/HTML/Applying-a-Function-to-an-Array.html
new file mode 100644
index 0000000..3b4da22
--- /dev/null
+++ b/doc/interpreter/HTML/Applying-a-Function-to-an-Array.html
@@ -0,0 +1,157 @@
+<html lang="en">
+<head>
+<title>Applying a Function to an Array - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link rel="prev" href="Rearranging-Matrices.html#Rearranging-Matrices" title="Rearranging Matrices">
+<link rel="next" href="Special-Utility-Matrices.html#Special-Utility-Matrices" title="Special Utility Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Applying-a-Function-to-an-Array"></a>
+Next: <a rel="next" accesskey="n" href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a>,
+Previous: <a rel="previous" accesskey="p" href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>
+<hr>
+</div>
+
+<h3 class="section">16.3 Applying a Function to an Array</h3>
+
+<!-- ./general/arrayfun.m -->
+<p><a name="doc_002darrayfun"></a>
+
+<div class="defun">
+— Function File:  <b>arrayfun</b> (<var>func, a</var>)<var><a name="index-arrayfun-1306"></a></var><br>
+— Function File: <var>x</var> = <b>arrayfun</b> (<var>func, a</var>)<var><a name="index-arrayfun-1307"></a></var><br>
+— Function File: <var>x</var> = <b>arrayfun</b> (<var>func, a, b, <small class="dots">...</small></var>)<var><a name="index-arrayfun-1308"></a></var><br>
+— Function File: [<var>x</var>, <var>y</var>, <small class="dots">...</small>] = <b>arrayfun</b> (<var>func, a, <small class="dots">...</small></var>)<var><a name="index-arrayfun-1309"></a></var><br>
+— Function File:  <b>arrayfun</b> (<var><small class="dots">...</small>, "UniformOutput", val</var>)<var><a name="index-arrayfun-1310"></a></var><br>
+— Function File:  <b>arrayfun</b> (<var><small class="dots">...</small>, "ErrorHandler", errfunc</var>)<var><a name="index-arrayfun-1311"></a></var><br>
+<blockquote>
+        <p>Execute a function on each element of an array.  This is useful for
+functions that do not accept array arguments.  If the function does
+accept array arguments it is better to call the function directly.
+
+        <p>The first input argument <var>func</var> can be a string, a function
+handle, an inline function or an anonymous function.  The input
+argument <var>a</var> can be a logic array, a numeric array, a string
+array, a structure array or a cell array.  By a call of the function
+<samp><span class="command">arrayfun</span></samp> all elements of <var>a</var> are passed on to the named
+function <var>func</var> individually.
+
+        <p>The named function can also take more than two input arguments, with
+the input arguments given as third input argument <var>b</var>, fourth
+input argument <var>c</var>, <small class="dots">...</small>  If given more than one array input
+argument then all input arguments must have the same sizes, for
+example
+
+     <pre class="example">          arrayfun (@atan2, [1, 0], [0, 1])
+           ans = [1.5708   0.0000]
+</pre>
+        <p>If the parameter <var>val</var> after a further string input argument
+"UniformOutput" is set <code>true</code> (the default), then the named
+function <var>func</var> must return a single element which then will be
+concatenated into the return value and is of type matrix.  Otherwise,
+if that parameter is set to <code>false</code>, then the outputs are
+concatenated in a cell array.  For example
+
+     <pre class="example">          arrayfun (@(x,y) x:y, "abc", "def", "UniformOutput", false)
+           ans =
+          {
+            [1,1] = abcd
+            [1,2] = bcde
+            [1,3] = cdef
+          }
+</pre>
+        <p>If more than one output arguments are given then the named function
+must return the number of return values that also are expected, for
+example
+
+     <pre class="example">          [A, B, C] = arrayfun (@find, [10; 0], "UniformOutput", false)
+          
+          A =
+          {
+            [1,1] =  1
+            [2,1] = [](0x0)
+          }
+          B =
+          {
+            [1,1] =  1
+            [2,1] = [](0x0)
+          }
+          C =
+          {
+            [1,1] =  10
+            [2,1] = [](0x0)
+          }
+</pre>
+        <p>If the parameter <var>errfunc</var> after a further string input argument
+"ErrorHandler" is another string, a function handle, an inline
+function or an anonymous function, then <var>errfunc</var> defines a
+function to call in the case that <var>func</var> generates an error. 
+The definition of the function must be of the form
+
+     <pre class="example">          function [...] = errfunc (<var>s</var>, ...)
+</pre>
+        <p>where there is an additional input argument to <var>errfunc</var>
+relative to <var>func</var>, given by <var>s</var>.  This is a structure with
+the elements "identifier", "message" and "index", giving
+respectively the error identifier, the error message and the index of
+the array elements that caused the error.  The size of the output
+argument of <var>errfunc</var> must have the same size as the output
+argument of <var>func</var>, otherwise a real error is thrown.  For
+example
+
+     <pre class="example">          function y = ferr (s, x), y = "MyString"; endfunction
+          arrayfun (@str2num, [1234], \
+                    "UniformOutput", false, "ErrorHandler", @ferr)
+           ans =
+          {
+           [1,1] = MyString
+          }
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcellfun.html#doc_002dcellfun">cellfun</a>, <a href="doc_002dspfun.html#doc_002dspfun">spfun</a>, <a href="doc_002dstructfun.html#doc_002dstructfun">structfun</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/bsxfun.cc -->
+   <p><a name="doc_002dbsxfun"></a>
+
+<div class="defun">
+— Loadable Function:  <b>bsxfun</b> (<var>f, a, b</var>)<var><a name="index-bsxfun-1312"></a></var><br>
+<blockquote><p>Applies a binary function <var>f</var> element-wise to two matrix arguments
+<var>a</var> and <var>b</var>.  The function <var>f</var> must be capable of accepting
+two column vector arguments of equal length, or one column vector
+argument and a scalar.
+
+        <p>The dimensions of <var>a</var> and <var>b</var> must be equal or singleton.  The
+singleton dimensions of the matrices will be expanded to the same
+dimensionality as the other matrix.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002darrayfun.html#doc_002darrayfun">arrayfun</a>, <a href="doc_002dcellfun.html#doc_002dcellfun">cellfun</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Area-series.html b/doc/interpreter/HTML/Area-series.html
new file mode 100644
index 0000000..90123bd
--- /dev/null
+++ b/doc/interpreter/HTML/Area-series.html
@@ -0,0 +1,58 @@
+<html lang="en">
+<head>
+<title>Area series - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Data-sources-in-object-groups.html#Data-sources-in-object-groups" title="Data sources in object groups">
+<link rel="next" href="Bar-series.html#Bar-series" title="Bar series">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Area-series"></a>
+Next: <a rel="next" accesskey="n" href="Bar-series.html#Bar-series">Bar series</a>,
+Previous: <a rel="previous" accesskey="p" href="Data-sources-in-object-groups.html#Data-sources-in-object-groups">Data sources in object groups</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.2 Area series</h5>
+
+<p><a name="index-series-objects-1232"></a><a name="index-area-series-1233"></a>
+Area series objects are created by the <code>area</code> function.  Each of the
+<code>hggroup</code> elements contains a single patch object.  The properties
+of the area series are
+
+     <dl>
+<dt><code>basevalue</code><dd>The value where the base of the area plot is drawn.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the edge of the patch objects making up the
+areas.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>edgecolor</code><dt><code>facecolor</code><dd>The line and fill color of the patch objects making up the areas.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dd>The x and y coordinates of the original columns of the data passed to
+<code>area</code> prior to the cumulative summation used in the <code>area</code>
+function.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Arithmetic-Ops.html b/doc/interpreter/HTML/Arithmetic-Ops.html
new file mode 100644
index 0000000..742830a
--- /dev/null
+++ b/doc/interpreter/HTML/Arithmetic-Ops.html
@@ -0,0 +1,129 @@
+<html lang="en">
+<head>
+<title>Arithmetic Ops - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Calling-Functions.html#Calling-Functions" title="Calling Functions">
+<link rel="next" href="Comparison-Ops.html#Comparison-Ops" title="Comparison Ops">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Arithmetic-Ops"></a>
+Next: <a rel="next" accesskey="n" href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a>,
+Previous: <a rel="previous" accesskey="p" href="Calling-Functions.html#Calling-Functions">Calling Functions</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.3 Arithmetic Operators</h3>
+
+<p><a name="index-arithmetic-operators-457"></a><a name="index-operators_002c-arithmetic-458"></a><a name="index-addition-459"></a><a name="index-subtraction-460"></a><a name="index-multiplication-461"></a><a name="index-matrix-multiplication-462"></a><a name="index-division-463"></a><a name="index-quotient-464"></a><a name="index-negation-465"></a><a name="index-unary-minus-466"></a><a name="index-exponentiation-467"></a><a name="index-transpose-468"></a><a name="index-Hermitian-operator-469"></a><a name="index-transpose_002c-complex_002dconjugate-470"></a><a name="index-complex_002dconjugate-transpose-471"></a>
+The following arithmetic operators are available, and work on scalars
+and matrices.
+
+     <dl>
+<dt><var>x</var><code> + </code><var>y</var><dd><a name="index-g_t_002b-472"></a>Addition.  If both operands are matrices, the number of rows and columns
+must both agree.  If one operand is a scalar, its value is added to
+all the elements of the other operand.
+
+     <br><dt><var>x</var><code> .+ </code><var>y</var><dd><a name="index-g_t_002e_002b-473"></a>Element by element addition.  This operator is equivalent to <code>+</code>.
+
+     <br><dt><var>x</var><code> - </code><var>y</var><dd><a name="index-g_t_002d-474"></a>Subtraction.  If both operands are matrices, the number of rows and
+columns of both must agree.
+
+     <br><dt><var>x</var><code> .- </code><var>y</var><dd>Element by element subtraction.  This operator is equivalent to <code>-</code>.
+
+     <br><dt><var>x</var><code> * </code><var>y</var><dd><a name="index-g_t_002a-475"></a>Matrix multiplication.  The number of columns of <var>x</var> must agree
+with the number of rows of <var>y</var>.
+
+     <br><dt><var>x</var><code> .* </code><var>y</var><dd><a name="index-g_t_002e_002a-476"></a>Element by element multiplication.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+     <br><dt><var>x</var><code> / </code><var>y</var><dd><a name="index-g_t_002f-477"></a>Right division.  This is conceptually equivalent to the expression
+
+     <pre class="example">          (inverse (y') * x')'
+</pre>
+     <p class="noindent">but it is computed without forming the inverse of <var>y'</var>.
+
+     <p>If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+     <br><dt><var>x</var><code> ./ </code><var>y</var><dd><a name="index-g_t_002e_002f-478"></a>Element by element right division.
+
+     <br><dt><var>x</var><code> \ </code><var>y</var><dd><a name="index-g_t_005c-479"></a>Left division.  This is conceptually equivalent to the expression
+
+     <pre class="example">          inverse (x) * y
+</pre>
+     <p class="noindent">but it is computed without forming the inverse of <var>x</var>.
+
+     <p>If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+     <br><dt><var>x</var><code> .\ </code><var>y</var><dd><a name="index-g_t_002e_005c-480"></a>Element by element left division.  Each element of <var>y</var> is divided
+by each corresponding element of <var>x</var>.
+
+     <br><dt><var>x</var><code> ^ </code><var>y</var><dt><var>x</var><code> ** </code><var>y</var><dd><a name="index-g_t_002a_002a-481"></a><a name="index-g_t_005e-482"></a>Power operator.  If <var>x</var> and <var>y</var> are both scalars, this operator
+returns <var>x</var> raised to the power <var>y</var>.  If <var>x</var> is a scalar and
+<var>y</var> is a square matrix, the result is computed using an eigenvalue
+expansion.  If <var>x</var> is a square matrix, the result is computed by
+repeated multiplication if <var>y</var> is an integer, and by an eigenvalue
+expansion if <var>y</var> is not an integer.  An error results if both
+<var>x</var> and <var>y</var> are matrices.
+
+     <p>The implementation of this operator needs to be improved.
+
+     <br><dt><var>x</var><code> .^ </code><var>y</var><br><dt><var>x</var><code> .** </code><var>y</var><dd><a name="index-g_t_002e_002a_002a-483"></a><a name="index-g_t_002e_005e-484"></a>Element by element power operator.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+     <br><dt><code>-</code><var>x</var><dd><a name="index-g_t_002d-485"></a>Negation.
+
+     <br><dt><code>+</code><var>x</var><dd><a name="index-g_t_002b-486"></a>Unary plus.  This operator has no effect on the operand.
+
+     <br><dt><var>x</var><code>'</code><dd><a name="index-g_t_0027-487"></a>Complex conjugate transpose.  For real arguments, this operator is the
+same as the transpose operator.  For complex arguments, this operator is
+equivalent to the expression
+
+     <pre class="example">          conj (x.')
+</pre>
+     <br><dt><var>x</var><code>.'</code><dd><a name="index-g_t_002e_0027-488"></a>Transpose. 
+</dl>
+
+   <p>Note that because Octave's element by element operators begin with a
+‘<samp><span class="samp">.</span></samp>’, there is a possible ambiguity for statements like
+
+<pre class="example">     1./m
+</pre>
+   <p class="noindent">because the period could be interpreted either as part of the constant
+or as part of the operator.  To resolve this conflict, Octave treats the
+expression as if you had typed
+
+<pre class="example">     (1) ./ m
+</pre>
+   <p class="noindent">and not
+
+<pre class="example">     (1.) / m
+</pre>
+   <p class="noindent">Although this is inconsistent with the normal behavior of Octave's
+lexer, which usually prefers to break the input into tokens by
+preferring the longest possible match at any given point, it is more
+useful in this case.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Arithmetic.html b/doc/interpreter/HTML/Arithmetic.html
new file mode 100644
index 0000000..b1d1605
--- /dev/null
+++ b/doc/interpreter/HTML/Arithmetic.html
@@ -0,0 +1,57 @@
+<html lang="en">
+<head>
+<title>Arithmetic - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link rel="next" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Arithmetic"></a>
+Next: <a rel="next" accesskey="n" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">17 Arithmetic</h2>
+
+<p>Unless otherwise noted, all of the functions described in this chapter
+will work for real and complex scalar, vector, or matrix arguments.  Functions
+described as <dfn>mapping functions</dfn> apply the given operation individually to
+each element when given a matrix argument.  For example,
+
+<pre class="example">     sin ([1, 2; 3, 4])
+            0.84147   0.90930
+              0.14112  -0.75680
+</pre>
+   <ul class="menu">
+<li><a accesskey="1" href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a>
+<li><a accesskey="2" href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a>
+<li><a accesskey="3" href="Trigonometry.html#Trigonometry">Trigonometry</a>
+<li><a accesskey="4" href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a>
+<li><a accesskey="5" href="Utility-Functions.html#Utility-Functions">Utility Functions</a>
+<li><a accesskey="6" href="Special-Functions.html#Special-Functions">Special Functions</a>
+<li><a accesskey="7" href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a>
+<li><a accesskey="8" href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Array-and-Sparse-Differences.html b/doc/interpreter/HTML/Array-and-Sparse-Differences.html
new file mode 100644
index 0000000..28c6e43
--- /dev/null
+++ b/doc/interpreter/HTML/Array-and-Sparse-Differences.html
@@ -0,0 +1,97 @@
+<html lang="en">
+<head>
+<title>Array and Sparse Differences - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles" title="Sparse Matrices in Oct-Files">
+<link rel="next" href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles" title="Creating Sparse Matrices in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Array-and-Sparse-Differences"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles">Creating Sparse Matrices in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">A.1.6.1 The Differences between the Array and Sparse Classes</h5>
+
+<p>The number of elements in a sparse matrix is considered to be the number
+of non-zero elements rather than the product of the dimensions.  Therefore
+
+<pre class="example">     SparseMatrix sm;
+     ...
+     int nel = sm.nelem ();
+</pre>
+   <p>returns the number of non-zero elements.  If the user really requires the
+number of elements in the matrix, including the non-zero elements, they
+should use <code>numel</code> rather than <code>nelem</code>.  Note that for very
+large matrices, where the product of the two dimensions is larger than
+the representation of an unsigned int, then <code>numel</code> can overflow. 
+An example is <code>speye(1e6)</code> which will create a matrix with a million
+rows and columns, but only a million non-zero elements.  Therefore the
+number of rows by the number of columns in this case is more than two
+hundred times the maximum value that can be represented by an unsigned int. 
+The use of <code>numel</code> should therefore be avoided useless it is known
+it won't overflow.
+
+   <p>Extreme care must be take with the elem method and the "()" operator,
+which perform basically the same function.  The reason is that if a
+sparse object is non-const, then Octave will assume that a
+request for a zero element in a sparse matrix is in fact a request
+to create this element so it can be filled.  Therefore a piece of
+code like
+
+<pre class="example">     SparseMatrix sm;
+     ...
+     for (int j = 0; j < nc; j++)
+       for (int i = 0; i < nr; i++)
+         std::cerr << " (" << i << "," << j << "): " << sm(i,j)
+                   << std::endl;
+</pre>
+   <p>is a great way of turning the sparse matrix into a dense one, and a
+very slow way at that since it reallocates the sparse object at each
+zero element in the matrix.
+
+   <p>An easy way of preventing the above from happening is to create a temporary
+constant version of the sparse matrix.  Note that only the container for
+the sparse matrix will be copied, while the actual representation of the
+data will be shared between the two versions of the sparse matrix.  So this
+is not a costly operation.  For example, the above would become
+
+<pre class="example">     SparseMatrix sm;
+     ...
+     const SparseMatrix tmp (sm);
+     for (int j = 0; j < nc; j++)
+       for (int i = 0; i < nr; i++)
+         std::cerr << " (" << i << "," << j << "): " << tmp(i,j)
+                   << std::endl;
+</pre>
+   <p>Finally, as the sparse types aren't just represented as a contiguous
+block of memory, the <code>fortran_vec</code> method of the <code>Array<T></code>
+is not available.  It is however replaced by three separate methods
+<code>ridx</code>, <code>cidx</code> and <code>data</code>, that access the raw compressed
+column format that the Octave sparse matrices are stored in. 
+Additionally, these methods can be used in a manner similar to <code>elem</code>,
+to allow the matrix to be accessed or filled.  However, in that case it is
+up to the user to respect the sparse matrix compressed column format
+discussed previous.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Assignment-Ops.html b/doc/interpreter/HTML/Assignment-Ops.html
new file mode 100644
index 0000000..55c0008
--- /dev/null
+++ b/doc/interpreter/HTML/Assignment-Ops.html
@@ -0,0 +1,190 @@
+<html lang="en">
+<head>
+<title>Assignment Ops - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Boolean-Expressions.html#Boolean-Expressions" title="Boolean Expressions">
+<link rel="next" href="Increment-Ops.html#Increment-Ops" title="Increment Ops">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Assignment-Ops"></a>
+Next: <a rel="next" accesskey="n" href="Increment-Ops.html#Increment-Ops">Increment Ops</a>,
+Previous: <a rel="previous" accesskey="p" href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.6 Assignment Expressions</h3>
+
+<p><a name="index-assignment-expressions-526"></a><a name="index-assignment-operators-527"></a><a name="index-operators_002c-assignment-528"></a><a name="index-expressions_002c-assignment-529"></a>
+<a name="index-g_t_003d-530"></a>
+An <dfn>assignment</dfn> is an expression that stores a new value into a
+variable.  For example, the following expression assigns the value 1 to
+the variable <code>z</code>:
+
+<pre class="example">     z = 1
+</pre>
+   <p class="noindent">After this expression is executed, the variable <code>z</code> has the value 1. 
+Whatever old value <code>z</code> had before the assignment is forgotten. 
+The ‘<samp><span class="samp">=</span></samp>’ sign is called an <dfn>assignment operator</dfn>.
+
+   <p>Assignments can store string values also.  For example, the following
+expression would store the value <code>"this food is good"</code> in the
+variable <code>message</code>:
+
+<pre class="example">     thing = "food"
+     predicate = "good"
+     message = [ "this " , thing , " is " , predicate ]
+</pre>
+   <p class="noindent">(This also illustrates concatenation of strings.)
+
+   <p><a name="index-side-effect-531"></a>Most operators (addition, concatenation, and so on) have no effect
+except to compute a value.  If you ignore the value, you might as well
+not use the operator.  An assignment operator is different.  It does
+produce a value, but even if you ignore the value, the assignment still
+makes itself felt through the alteration of the variable.  We call this
+a <dfn>side effect</dfn>.
+
+   <p><a name="index-lvalue-532"></a>The left-hand operand of an assignment need not be a variable
+(see <a href="Variables.html#Variables">Variables</a>).  It can also be an element of a matrix
+(see <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a>) or a list of return values
+(see <a href="Calling-Functions.html#Calling-Functions">Calling Functions</a>).  These are all called <dfn>lvalues</dfn>, which
+means they can appear on the left-hand side of an assignment operator. 
+The right-hand operand may be any expression.  It produces the new value
+which the assignment stores in the specified variable, matrix element,
+or list of return values.
+
+   <p>It is important to note that variables do <em>not</em> have permanent types. 
+The type of a variable is simply the type of whatever value it happens
+to hold at the moment.  In the following program fragment, the variable
+<code>foo</code> has a numeric value at first, and a string value later on:
+
+<pre class="example">     octave:13> foo = 1
+     foo = 1
+     octave:13> foo = "bar"
+     foo = bar
+</pre>
+   <p class="noindent">When the second assignment gives <code>foo</code> a string value, the fact that
+it previously had a numeric value is forgotten.
+
+   <p>Assignment of a scalar to an indexed matrix sets all of the elements
+that are referenced by the indices to the scalar value.  For example, if
+<code>a</code> is a matrix with at least two columns,
+
+<pre class="example">     a(:, 2) = 5
+</pre>
+   <p class="noindent">sets all the elements in the second column of <code>a</code> to 5.
+
+   <p>Assigning an empty matrix ‘<samp><span class="samp">[]</span></samp>’ works in most cases to allow you to
+delete rows or columns of matrices and vectors.  See <a href="Empty-Matrices.html#Empty-Matrices">Empty Matrices</a>. 
+For example, given a 4 by 5 matrix <var>A</var>, the assignment
+
+<pre class="example">     A (3, :) = []
+</pre>
+   <p class="noindent">deletes the third row of <var>A</var>, and the assignment
+
+<pre class="example">     A (:, 1:2:5) = []
+</pre>
+   <p class="noindent">deletes the first, third, and fifth columns.
+
+   <p>An assignment is an expression, so it has a value.  Thus, <code>z = 1</code>
+as an expression has the value 1.  One consequence of this is that you
+can write multiple assignments together:
+
+<pre class="example">     x = y = z = 0
+</pre>
+   <p class="noindent">stores the value 0 in all three variables.  It does this because the
+value of <code>z = 0</code>, which is 0, is stored into <code>y</code>, and then
+the value of <code>y = z = 0</code>, which is 0, is stored into <code>x</code>.
+
+   <p>This is also true of assignments to lists of values, so the following is
+a valid expression
+
+<pre class="example">     [a, b, c] = [u, s, v] = svd (a)
+</pre>
+   <p class="noindent">that is exactly equivalent to
+
+<pre class="example">     [u, s, v] = svd (a)
+     a = u
+     b = s
+     c = v
+</pre>
+   <p>In expressions like this, the number of values in each part of the
+expression need not match.  For example, the expression
+
+<pre class="example">     [a, b] = [u, s, v] = svd (a)
+</pre>
+   <p class="noindent">is equivalent to
+
+<pre class="example">     [u, s, v] = svd (a)
+     a = u
+     b = s
+</pre>
+   <p class="noindent">The number of values on the left side of the expression can, however,
+not exceed the number of values on the right side.  For example, the
+following will produce an error.
+
+<pre class="example">     [a, b, c, d] = [u, s, v] = svd (a);
+     -| error: element number 4 undefined in return list
+</pre>
+   <p><a name="index-g_t_002b_003d-533"></a>A very common programming pattern is to increment an existing variable
+with a given value, like this
+
+<pre class="example">     a = a + 2;
+</pre>
+   <p class="noindent">This can be written in a clearer and more condensed form using the
+<code>+=</code> operator
+
+<pre class="example">     a += 2;
+</pre>
+   <p class="noindent"><a name="index-g_t_002d_003d-534"></a><a name="index-g_t_002a_003d-535"></a><a name="index-g_t_002f_003d-536"></a>Similar operators also exist for subtraction (<code>-=</code>),
+multiplication (<code>*=</code>), and division (<code>/=</code>).  An expression
+of the form
+
+<pre class="example">     <var>expr1</var> <var>op</var>= <var>expr2</var>
+</pre>
+   <p class="noindent">is evaluated as
+
+<pre class="example">     <var>expr1</var> = (<var>expr1</var>) <var>op</var> (<var>expr2</var>)
+</pre>
+   <p class="noindent">where <var>op</var> can be either <code>+</code>, <code>-</code>, <code>*</code>, or <code>/</code>. 
+So, the expression
+
+<pre class="example">     a *= b+1
+</pre>
+   <p class="noindent">is evaluated as
+
+<pre class="example">     a = a * (b+1)
+</pre>
+   <p class="noindent">and <em>not</em>
+
+<pre class="example">     a = a * b + 1
+</pre>
+   <p>You can use an assignment anywhere an expression is called for.  For
+example, it is valid to write <code>x != (y = 1)</code> to set <code>y</code> to 1
+and then test whether <code>x</code> equals 1.  But this style tends to make
+programs hard to read.  Except in a one-shot program, you should rewrite
+it to get rid of such nesting of assignments.  This is never very hard.
+
+   <p><a name="index-increment-operator-537"></a><a name="index-decrement-operator-538"></a><a name="index-operators_002c-increment-539"></a><a name="index-operators_002c-decrement-540"></a>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Audio-Processing.html b/doc/interpreter/HTML/Audio-Processing.html
new file mode 100644
index 0000000..e0d317c
--- /dev/null
+++ b/doc/interpreter/HTML/Audio-Processing.html
@@ -0,0 +1,242 @@
+<html lang="en">
+<head>
+<title>Audio Processing - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link rel="next" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Audio-Processing"></a>
+Next: <a rel="next" accesskey="n" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>,
+Previous: <a rel="previous" accesskey="p" href="Image-Processing.html#Image-Processing">Image Processing</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">32 Audio Processing</h2>
+
+<p>Octave provides a few functions for dealing with audio data.  An audio
+`sample' is a single output value from an A/D converter, i.e., a small
+integer number (usually 8 or 16 bits), and audio data is just a series
+of such samples.  It can be characterized by three parameters:  the
+sampling rate (measured in samples per second or Hz, e.g., 8000 or
+44100), the number of bits per sample (e.g., 8 or 16), and the number of
+channels (1 for mono, 2 for stereo, etc.).
+
+   <p>There are many different formats for representing such data.  Currently,
+only the two most popular, <em>linear encoding</em> and <em>mu-law
+encoding</em>, are supported by Octave.  There is an excellent FAQ on audio
+formats by Guido van Rossum <guido at cwi.nl> which can be found at any
+FAQ ftp site, in particular in the directory
+<samp><span class="file">/pub/usenet/news.answers/audio-fmts</span></samp> of the archive site
+<code>rtfm.mit.edu</code>.
+
+   <p>Octave simply treats audio data as vectors of samples (non-mono data are
+not supported yet).  It is assumed that audio files using linear
+encoding have one of the extensions <samp><span class="file">lin</span></samp> or <samp><span class="file">raw</span></samp>, and that
+files holding data in mu-law encoding end in <samp><span class="file">au</span></samp>, <samp><span class="file">mu</span></samp>, or
+<samp><span class="file">snd</span></samp>.
+
+<!-- ./audio/lin2mu.m -->
+   <p><a name="doc_002dlin2mu"></a>
+
+<div class="defun">
+— Function File:  <b>lin2mu</b> (<var>x, n</var>)<var><a name="index-lin2mu-2238"></a></var><br>
+<blockquote><p>Converts audio data from linear to mu-law.  Mu-law values use 8-bit
+unsigned integers.  Linear values use <var>n</var>-bit signed integers or
+floating point values in the range -1<=<var>x</var><=1 if <var>n</var> is 0. 
+If <var>n</var> is not specified it defaults to 0, 8 or 16 depending on
+the range values in <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmu2lin.html#doc_002dmu2lin">mu2lin</a>, <a href="doc_002dloadaudio.html#doc_002dloadaudio">loadaudio</a>, <a href="doc_002dsaveaudio.html#doc_002dsaveaudio">saveaudio</a>, <a href="doc_002dplayaudio.html#doc_002dplayaudio">playaudio</a>, <a href="doc_002dsetaudio.html#doc_002dsetaudio">setaudio</a>, <a href="doc_002drecord.html#doc_002drecord">record</a>. 
+</p></blockquote></div>
+
+<!-- ./audio/mu2lin.m -->
+   <p><a name="doc_002dmu2lin"></a>
+
+<div class="defun">
+— Function File:  <b>mu2lin</b> (<var>x, bps</var>)<var><a name="index-mu2lin-2239"></a></var><br>
+<blockquote><p>Converts audio data from linear to mu-law.  Mu-law values are 8-bit
+unsigned integers.  Linear values use <var>n</var>-bit signed integers
+or floating point values in the range -1<=y<=1 if <var>n</var> is 0.  If
+<var>n</var> is not specified it defaults to 8. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlin2mu.html#doc_002dlin2mu">lin2mu</a>, <a href="doc_002dloadaudio.html#doc_002dloadaudio">loadaudio</a>, <a href="doc_002dsaveaudio.html#doc_002dsaveaudio">saveaudio</a>, <a href="doc_002dplayaudio.html#doc_002dplayaudio">playaudio</a>, <a href="doc_002dsetaudio.html#doc_002dsetaudio">setaudio</a>, <a href="doc_002drecord.html#doc_002drecord">record</a>. 
+</p></blockquote></div>
+
+<!-- ./audio/loadaudio.m -->
+   <p><a name="doc_002dloadaudio"></a>
+
+<div class="defun">
+— Function File:  <b>loadaudio</b> (<var>name, ext, bps</var>)<var><a name="index-loadaudio-2240"></a></var><br>
+<blockquote><p>Loads audio data from the file <samp><var>name</var><span class="file">.</span><var>ext</var></samp> into the
+vector <var>x</var>.
+
+        <p>The extension <var>ext</var> determines how the data in the audio file is
+interpreted;  the extensions <samp><span class="file">lin</span></samp> (default) and <samp><span class="file">raw</span></samp>
+correspond to linear, the extensions <samp><span class="file">au</span></samp>, <samp><span class="file">mu</span></samp>, or <samp><span class="file">snd</span></samp>
+to mu-law encoding.
+
+        <p>The argument <var>bps</var> can be either 8 (default) or 16, and specifies
+the number of bits per sample used in the audio file. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlin2mu.html#doc_002dlin2mu">lin2mu</a>, <a href="doc_002dmu2lin.html#doc_002dmu2lin">mu2lin</a>, <a href="doc_002dsaveaudio.html#doc_002dsaveaudio">saveaudio</a>, <a href="doc_002dplayaudio.html#doc_002dplayaudio">playaudio</a>, <a href="doc_002dsetaudio.html#doc_002dsetaudio">setaudio</a>, <a href="doc_002drecord.html#doc_002drecord">record</a>. 
+</p></blockquote></div>
+
+<!-- ./audio/saveaudio.m -->
+   <p><a name="doc_002dsaveaudio"></a>
+
+<div class="defun">
+— Function File:  <b>saveaudio</b> (<var>name, x, ext, bps</var>)<var><a name="index-saveaudio-2241"></a></var><br>
+<blockquote><p>Saves a vector <var>x</var> of audio data to the file
+<samp><var>name</var><span class="file">.</span><var>ext</var></samp>.  The optional parameters <var>ext</var> and
+<var>bps</var> determine the encoding and the number of bits per sample used
+in the audio file (see <code>loadaudio</code>);  defaults are <samp><span class="file">lin</span></samp> and
+8, respectively. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlin2mu.html#doc_002dlin2mu">lin2mu</a>, <a href="doc_002dmu2lin.html#doc_002dmu2lin">mu2lin</a>, <a href="doc_002dloadaudio.html#doc_002dloadaudio">loadaudio</a>, <a href="doc_002dplayaudio.html#doc_002dplayaudio">playaudio</a>, <a href="doc_002dsetaudio.html#doc_002dsetaudio">setaudio</a>, <a href="doc_002drecord.html#doc_002drecord">record</a>. 
+</p></blockquote></div>
+
+   <p>The following functions for audio I/O require special A/D hardware and
+operating system support.  It is assumed that audio data in linear
+encoding can be played and recorded by reading from and writing to
+<samp><span class="file">/dev/dsp</span></samp>, and that similarly <samp><span class="file">/dev/audio</span></samp> is used for mu-law
+encoding.  These file names are system-dependent.  Improvements so that
+these functions will work without modification on a wide variety of
+hardware are welcome.
+
+<!-- ./audio/playaudio.m -->
+   <p><a name="doc_002dplayaudio"></a>
+
+<div class="defun">
+— Function File:  <b>playaudio</b> (<var>name, ext</var>)<var><a name="index-playaudio-2242"></a></var><br>
+— Function File:  <b>playaudio</b> (<var>x</var>)<var><a name="index-playaudio-2243"></a></var><br>
+<blockquote><p>Plays the audio file <samp><var>name</var><span class="file">.</span><var>ext</var></samp> or the audio data
+stored in the vector <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlin2mu.html#doc_002dlin2mu">lin2mu</a>, <a href="doc_002dmu2lin.html#doc_002dmu2lin">mu2lin</a>, <a href="doc_002dloadaudio.html#doc_002dloadaudio">loadaudio</a>, <a href="doc_002dsaveaudio.html#doc_002dsaveaudio">saveaudio</a>, <a href="doc_002dsetaudio.html#doc_002dsetaudio">setaudio</a>, <a href="doc_002drecord.html#doc_002drecord">record</a>. 
+</p></blockquote></div>
+
+<!-- ./audio/record.m -->
+   <p><a name="doc_002drecord"></a>
+
+<div class="defun">
+— Function File:  <b>record</b> (<var>sec, sampling_rate</var>)<var><a name="index-record-2244"></a></var><br>
+<blockquote><p>Records <var>sec</var> seconds of audio input into the vector <var>x</var>.  The
+default value for <var>sampling_rate</var> is 8000 samples per second, or
+8kHz.  The program waits until the user types <RET> and then
+immediately starts to record. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlin2mu.html#doc_002dlin2mu">lin2mu</a>, <a href="doc_002dmu2lin.html#doc_002dmu2lin">mu2lin</a>, <a href="doc_002dloadaudio.html#doc_002dloadaudio">loadaudio</a>, <a href="doc_002dsaveaudio.html#doc_002dsaveaudio">saveaudio</a>, <a href="doc_002dplayaudio.html#doc_002dplayaudio">playaudio</a>, <a href="doc_002dsetaudio.html#doc_002dsetaudio">setaudio</a>. 
+</p></blockquote></div>
+
+<!-- ./audio/setaudio.m -->
+   <p><a name="doc_002dsetaudio"></a>
+
+<div class="defun">
+— Function File:  <b>setaudio</b> ([<var>w_type </var>[<var>, value</var>]])<var><a name="index-setaudio-2245"></a></var><br>
+<blockquote><p>Execute the shell command ‘<samp><span class="samp">mixer [</span><var>w_type</var><span class="samp"> [, </span><var>value</var><span class="samp">]]</span></samp>’
+</p></blockquote></div>
+
+<!-- ./audio/wavread.m -->
+   <p><a name="doc_002dwavread"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>wavread</b> (<var>filename</var>)<var><a name="index-wavread-2246"></a></var><br>
+<blockquote><p>Load the RIFF/WAVE sound file <var>filename</var>, and return the samples
+in vector <var>y</var>.  If the file contains multichannel data, then
+<var>y</var> is a matrix with the channels represented as columns.
+
+   — Function File: [<var>y</var>, <var>Fs</var>, <var>bits</var>] = <b>wavread</b> (<var>filename</var>)<var><a name="index-wavread-2247"></a></var><br>
+<blockquote><p>Additionally return the sample rate (<var>fs</var>) in Hz and the number of bits
+per sample (<var>bits</var>).
+
+   — Function File: [<small class="dots">...</small>] = <b>wavread</b> (<var>filename, n</var>)<var><a name="index-wavread-2248"></a></var><br>
+<blockquote><p>Read only the first <var>n</var> samples from each channel.
+
+   — Function File: [<small class="dots">...</small>] = <b>wavread</b> (<var>filename,</var>[<var>n1 n2</var>])<var><a name="index-wavread-2249"></a></var><br>
+<blockquote><p>Read only samples <var>n1</var> through <var>n2</var> from each channel.
+
+   — Function File: [<var>samples</var>, <var>channels</var>] = <b>wavread</b> (<var>filename, "size"</var>)<var><a name="index-wavread-2250"></a></var><br>
+<blockquote><p>Return the number of samples (<var>n</var>) and channels (<var>ch</var>)
+instead of the audio data. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwavwrite.html#doc_002dwavwrite">wavwrite</a>. 
+</p></blockquote></div>
+
+<!-- ./audio/wavwrite.m -->
+   <p><a name="doc_002dwavwrite"></a>
+
+<div class="defun">
+— Function File:  <b>wavwrite</b> (<var>y, filename</var>)<var><a name="index-wavwrite-2251"></a></var><br>
+— Function File:  <b>wavwrite</b> (<var>y, fs, filename</var>)<var><a name="index-wavwrite-2252"></a></var><br>
+— Function File:  <b>wavwrite</b> (<var>y, fs, bits, filename</var>)<var><a name="index-wavwrite-2253"></a></var><br>
+<blockquote><p>Write <var>y</var> to the canonical RIFF/WAVE sound file <var>filename</var>
+with sample rate <var>fs</var> and bits per sample <var>bits</var>.  The
+default sample rate is 8000 Hz with 16-bits per sample.  Each column
+of the data represents a separate channel. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwavread.html#doc_002dwavread">wavread</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2008, 2009 David Bateman -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+<!-- FIXME -->
+<!-- For now can't include "@" character in the path name, and so name -->
+<!-- the example directory without the "@"!! -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Axes-Properties.html b/doc/interpreter/HTML/Axes-Properties.html
new file mode 100644
index 0000000..e9c20d0
--- /dev/null
+++ b/doc/interpreter/HTML/Axes-Properties.html
@@ -0,0 +1,122 @@
+<html lang="en">
+<head>
+<title>Axes Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Figure-Properties.html#Figure-Properties" title="Figure Properties">
+<link rel="next" href="Line-Properties.html#Line-Properties" title="Line Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Axes-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Line-Properties.html#Line-Properties">Line Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Figure-Properties.html#Figure-Properties">Figure Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.3 Axes Properties</h5>
+
+<p><a name="index-axes-properties-1191"></a>
+     <dl>
+<dt><code>position</code><dd>A vector specifying the position of the plot, excluding titles, axes and
+legend.  The four elements of the vector are the coordinates of the
+lower left corner and width and height of the plot, in units normalized
+to the width and height of the plot window.  For example, <code>[0.2,
+0.3, 0.4, 0.5]</code> sets the lower left corner of the axes at (0.2,
+0.3) and the width and height to be 0.4 and 0.5 respectively.  See also
+the <code>outerposition</code> property.
+
+     <br><dt><code>title</code><dd>Index of text object for the axes title.
+
+     <br><dt><code>box</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of the box around
+the axes.
+
+     <br><dt><code>key</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of the legend. 
+Note that this property is not compatible with <span class="sc">matlab</span> and may be
+removed in a future version of Octave.
+
+     <br><dt><code>keybox</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of a box around the
+legend.  Note that this property is not compatible with <span class="sc">matlab</span> and
+may be removed in a future version of Octave.
+
+     <br><dt><code>keypos</code><dd>An integer from 1 to 4 specifying the position of the legend.  1
+indicates upper right corner, 2 indicates upper left, 3 indicates lower
+left, and 4 indicates lower right.  Note that this property is not
+compatible with <span class="sc">matlab</span> and may be removed in a future version of
+Octave.
+
+     <br><dt><code>dataaspectratio</code><dd>A two-element vector specifying the relative height and width of the
+data displayed in the axes.  Setting <code>dataaspectratio</code> to ‘<samp><span class="samp">1,
+2]</span></samp>’ causes the length of one unit as displayed on the y-axis to be the
+same as the length of 2 units on the x-axis.  Setting
+<code>dataaspectratio</code> also forces the <code>dataaspectratiomode</code>
+property to be set to <code>"manual"</code>.
+
+     <br><dt><code>dataaspectratiomode</code><dd>Either <code>"manual"</code> or <code>"auto"</code>.
+
+     <br><dt><code>xlim</code><dt><code>ylim</code><dt><code>zlim</code><dt><code>clim</code><dd>Two-element vectors defining the limits for the x, y, and z axes and the
+Setting one of these properties also forces the corresponding mode
+property to be set to <code>"manual"</code>.
+
+     <br><dt><code>xlimmode</code><dt><code>ylimmode</code><dt><code>zlimmode</code><dt><code>climmode</code><dd>Either <code>"manual"</code> or <code>"auto"</code>.
+
+     <br><dt><code>xlabel</code><dt><code>ylabel</code><dt><code>zlabel</code><dd>Indices to text objects for the axes labels.
+
+     <br><dt><code>xgrid</code><dt><code>ygrid</code><dt><code>zgrid</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of grid lines.
+
+     <br><dt><code>xminorgrid</code><dt><code>yminorgrid</code><dt><code>zminorgrid</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of minor grid lines.
+
+     <br><dt><code>xtick</code><dt><code>ytick</code><dt><code>ztick</code><dd>Setting one of these properties also forces the corresponding mode
+property to be set to <code>"manual"</code>.
+
+     <br><dt><code>xtickmode</code><dt><code>ytickmode</code><dt><code>ztickmode</code><dd>Either <code>"manual"</code> or <code>"auto"</code>.
+
+     <br><dt><code>xticklabel</code><dt><code>yticklabel</code><dt><code>zticklabel</code><dd>Setting one of these properties also forces the corresponding mode
+property to be set to <code>"manual"</code>.
+
+     <br><dt><code>xticklabelmode</code><dt><code>yticklabelmode</code><dt><code>zticklabelmode</code><dd>Either <code>"manual"</code> or <code>"auto"</code>.
+
+     <br><dt><code>xscale</code><dt><code>yscale</code><dt><code>zscale</code><dd>Either <code>"linear"</code> or <code>"log"</code>.
+
+     <br><dt><code>xdir</code><dt><code>ydir</code><dt><code>zdir</code><dd>Either <code>"forward"</code> or <code>"reverse"</code>.
+
+     <br><dt><code>xaxislocation</code><dt><code>yaxislocation</code><dd>Either <code>"top"</code> or <code>"bottom"</code> for the x-axis and <code>"left"</code>
+or <code>"right"</code> for the y-axis.
+
+     <br><dt><code>view</code><dd>A three element vector specifying the view point for three-dimensional plots.
+
+     <br><dt><code>visible</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of the axes.
+
+     <br><dt><code>nextplot</code><dd>May be one of
+          <dl>
+<dt><code>"new"</code><br><dt><code>"add"</code><br><dt><code>"replace"</code><br><dt><code>"replacechildren"</code><dd></dl>
+
+     <br><dt><code>outerposition</code><dd>A vector specifying the position of the plot, including titles, axes and
+legend.  The four elements of the vector are the coordinates of the
+lower left corner and width and height of the plot, in units normalized
+to the width and height of the plot window.  For example, <code>[0.2,
+0.3, 0.4, 0.5]</code> sets the lower left corner of the axes at (0.2,
+0.3) and the width and height to be 0.4 and 0.5 respectively.  See also
+the <code>position</code> property. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Bar-series.html b/doc/interpreter/HTML/Bar-series.html
new file mode 100644
index 0000000..63cc107
--- /dev/null
+++ b/doc/interpreter/HTML/Bar-series.html
@@ -0,0 +1,76 @@
+<html lang="en">
+<head>
+<title>Bar series - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Area-series.html#Area-series" title="Area series">
+<link rel="next" href="Contour-groups.html#Contour-groups" title="Contour groups">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bar-series"></a>
+Next: <a rel="next" accesskey="n" href="Contour-groups.html#Contour-groups">Contour groups</a>,
+Previous: <a rel="previous" accesskey="p" href="Area-series.html#Area-series">Area series</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.3 Bar series</h5>
+
+<p><a name="index-series-objects-1234"></a><a name="index-bar-series-1235"></a>
+Bar series objects are created by the <code>bar</code> or <code>barh</code>
+functions.  Each <code>hggroup</code> element contains a single patch object. 
+The properties of the bar series are
+
+     <dl>
+<dt><code>showbaseline</code><dt><code>baseline</code><dt><code>basevalue</code><dd>The property <code>showbaseline</code> flags whether the baseline of the bar
+series is displayed (default is "on").  The handle of the graphics object
+representing the baseline is given by the <code>baseline</code> property and
+the y-value of the baseline by the <code>basevalue</code> property.
+
+     <p>Changes to any of these property are propagated to the other members of
+the bar series and to the baseline itself.  Equally changes in the
+properties of the base line itself are propagated to the members of the
+corresponding bar series.
+
+     <br><dt><code>barwidth</code><dt><code>barlayout</code><dt><code>horizontal</code><dd>The property <code>barwidth</code> is the width of the bar corresponding to
+the <var>width</var> variable passed to <code>bar</code> or <var>barh</var>.  Whether the
+bar series is "grouped" or "stacked" is determined by the
+<code>barlayout</code> property and whether the bars are horizontal or
+vertical by the <code>horizontal</code> property.
+
+     <p>Changes to any of these property are propagated to the other members of
+the bar series.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the edge of the patch objects making up the
+bars.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>edgecolor</code><dt><code>facecolor</code><dd>The line and fill color of the patch objects making up the bars.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dd>The nominal x positions of the bars.  Changes in this property and
+propagated to the other members of the bar series.
+
+     <br><dt><code>ydata</code><dd>The y value of the bars in the <code>hggroup</code>.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Basic-Input-and-Output.html b/doc/interpreter/HTML/Basic-Input-and-Output.html
new file mode 100644
index 0000000..f8e6aaa
--- /dev/null
+++ b/doc/interpreter/HTML/Basic-Input-and-Output.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Basic Input and Output - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Input-and-Output.html#Input-and-Output" title="Input and Output">
+<link rel="next" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basic-Input-and-Output"></a>
+Next: <a rel="next" accesskey="n" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>,
+Up: <a rel="up" accesskey="u" href="Input-and-Output.html#Input-and-Output">Input and Output</a>
+<hr>
+</div>
+
+<h3 class="section">14.1 Basic Input and Output</h3>
+
+<!-- We could use a two-line introduction here... -->
+<ul class="menu">
+<li><a accesskey="1" href="Terminal-Output.html#Terminal-Output">Terminal Output</a>
+<li><a accesskey="2" href="Terminal-Input.html#Terminal-Input">Terminal Input</a>
+<li><a accesskey="3" href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a>
+<li><a accesskey="4" href="Rational-Approximations.html#Rational-Approximations">Rational Approximations</a>
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Basic-Matrix-Functions.html b/doc/interpreter/HTML/Basic-Matrix-Functions.html
new file mode 100644
index 0000000..1f436fd
--- /dev/null
+++ b/doc/interpreter/HTML/Basic-Matrix-Functions.html
@@ -0,0 +1,414 @@
+<html lang="en">
+<head>
+<title>Basic Matrix Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link rel="prev" href="Techniques-used-for-Linear-Algebra.html#Techniques-used-for-Linear-Algebra" title="Techniques used for Linear Algebra">
+<link rel="next" href="Matrix-Factorizations.html#Matrix-Factorizations" title="Matrix Factorizations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basic-Matrix-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>,
+Previous: <a rel="previous" accesskey="p" href="Techniques-used-for-Linear-Algebra.html#Techniques-used-for-Linear-Algebra">Techniques used for Linear Algebra</a>,
+Up: <a rel="up" accesskey="u" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>
+<hr>
+</div>
+
+<h3 class="section">18.2 Basic Matrix Functions</h3>
+
+<!-- ./DLD-FUNCTIONS/balance.cc -->
+<p><a name="doc_002dbalance"></a>
+
+<div class="defun">
+— Loadable Function: <var>aa</var> = <b>balance</b> (<var>a, opt</var>)<var><a name="index-balance-1549"></a></var><br>
+— Loadable Function: [<var>dd</var>, <var>aa</var>] = <b>balance</b> (<var>a, opt</var>)<var><a name="index-balance-1550"></a></var><br>
+— Loadable Function: [<var>d</var>, <var>p</var>, <var>aa</var>] = <b>balance</b> (<var>a, opt</var>)<var><a name="index-balance-1551"></a></var><br>
+— Loadable Function: [<var>cc</var>, <var>dd</var>, <var>aa</var>, <var>bb</var>] = <b>balance</b> (<var>a, b, opt</var>)<var><a name="index-balance-1552"></a></var><br>
+<blockquote>
+        <p>Compute <code>aa = dd \ a * dd</code> in which <code>aa</code> is a matrix whose
+row and column norms are roughly equal in magnitude, and
+<code>dd</code> = <code>p * d</code>, in which <code>p</code> is a permutation
+matrix and <code>d</code> is a diagonal matrix of powers of two.  This allows
+the equilibration to be computed without roundoff.  Results of
+eigenvalue calculation are typically improved by balancing first.
+
+        <p>If two output values are requested, <code>balance</code> returns
+the diagonal <code>d</code> and the permutation <code>p</code> separately as vectors. 
+In this case, <code>dd = eye(n)(:,p) * diag (d)</code>, where <code>n</code> is the matrix
+size.
+
+        <p>If four output values are requested, compute <code>aa = cc*a*dd</code> and
+<code>bb = cc*b*dd)</code>, in which <code>aa</code> and <code>bb</code> have non-zero
+elements of approximately the same magnitude and <code>cc</code> and <code>dd</code>
+are permuted diagonal matrices as in <code>dd</code> for the algebraic
+eigenvalue problem.
+
+        <p>The eigenvalue balancing option <code>opt</code> may be one of:
+
+          <dl>
+<dt><code>"noperm"</code>, <code>"S"</code><dd>Scale only; do not permute.
+
+          <br><dt><code>"noscal"</code>, <code>"P"</code><dd>Permute only; do not scale. 
+</dl>
+
+        <p>Algebraic eigenvalue balancing uses standard <span class="sc">lapack</span> routines.
+
+        <p>Generalized eigenvalue problem balancing uses Ward's algorithm
+(SIAM Journal on Scientific and Statistical Computing, 1981). 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/cond.m -->
+   <p><a name="doc_002dcond"></a>
+
+<div class="defun">
+— Function File:  <b>cond</b> (<var>a,p</var>)<var><a name="index-cond-1553"></a></var><br>
+<blockquote><p>Compute the <var>p</var>-norm condition number of a matrix.  <code>cond (</code><var>a</var><code>)</code> is
+defined as <code>norm (</code><var>a</var><code>, </code><var>p</var><code>) * norm (inv (</code><var>a</var><code>), </code><var>p</var><code>)</code>. 
+By default <var>p</var><code>=2</code> is used which implies a (relatively slow)
+singular value decomposition.  Other possible selections are
+<var>p</var><code>= 1, Inf, inf, 'Inf', 'fro'</code> which are generally faster. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcondest.html#doc_002dcondest">condest</a>, <a href="doc_002drcond.html#doc_002drcond">rcond</a>, <a href="doc_002dnorm.html#doc_002dnorm">norm</a>, <a href="doc_002dsvd.html#doc_002dsvd">svd</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/det.cc -->
+   <p><a name="doc_002ddet"></a>
+
+<div class="defun">
+— Loadable Function: [<var>d</var>, <var>rcond</var>] = <b>det</b> (<var>a</var>)<var><a name="index-det-1554"></a></var><br>
+<blockquote><p>Compute the determinant of <var>a</var> using <span class="sc">lapack</span> for full and UMFPACK
+for sparse matrices.  Return an estimate of the reciprocal condition number
+if requested. 
+</p></blockquote></div>
+
+<!-- ./deprecated/dmult.m -->
+   <p><a name="doc_002ddmult"></a>
+
+<div class="defun">
+— Function File:  <b>dmult</b> (<var>a, b</var>)<var><a name="index-dmult-1555"></a></var><br>
+<blockquote><p>This function has been deprecated.  Use the direct syntax <code>diag(A)*B</code>
+which is more readable and now also more efficient. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/dot.m -->
+   <p><a name="doc_002ddot"></a>
+
+<div class="defun">
+— Function File:  <b>dot</b> (<var>x, y, dim</var>)<var><a name="index-dot-1556"></a></var><br>
+<blockquote><p>Computes the dot product of two vectors.  If <var>x</var> and <var>y</var>
+are matrices, calculate the dot-product along the first
+non-singleton dimension.  If the optional argument <var>dim</var> is
+given, calculate the dot-product along this dimension. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/eig.cc -->
+   <p><a name="doc_002deig"></a>
+
+<div class="defun">
+— Loadable Function: <var>lambda</var> = <b>eig</b> (<var>a</var>)<var><a name="index-eig-1557"></a></var><br>
+— Loadable Function: <var>lambda</var> = <b>eig</b> (<var>a, b</var>)<var><a name="index-eig-1558"></a></var><br>
+— Loadable Function: [<var>v</var>, <var>lambda</var>] = <b>eig</b> (<var>a</var>)<var><a name="index-eig-1559"></a></var><br>
+— Loadable Function: [<var>v</var>, <var>lambda</var>] = <b>eig</b> (<var>a, b</var>)<var><a name="index-eig-1560"></a></var><br>
+<blockquote><p>The eigenvalues (and eigenvectors) of a matrix are computed in a several
+step process which begins with a Hessenberg decomposition, followed by a
+Schur decomposition, from which the eigenvalues are apparent.  The
+eigenvectors, when desired, are computed by further manipulations of the
+Schur decomposition.
+
+        <p>The eigenvalues returned by <code>eig</code> are not ordered. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002deigs.html#doc_002deigs">eigs</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/givens.cc -->
+   <p><a name="doc_002dgivens"></a>
+
+<div class="defun">
+— Loadable Function: <var>g</var> = <b>givens</b> (<var>x, y</var>)<var><a name="index-givens-1561"></a></var><br>
+— Loadable Function: [<var>c</var>, <var>s</var>] = <b>givens</b> (<var>x, y</var>)<var><a name="index-givens-1562"></a></var><br>
+<blockquote><p>Return a 2 by 2 orthogonal matrix
+<var>g</var><code> = [</code><var>c</var> <var>s</var><code>; -</code><var>s</var><code>' </code><var>c</var><code>]</code> such that
+<var>g</var><code> [</code><var>x</var><code>; </code><var>y</var><code>] = [*; 0]</code> with <var>x</var> and <var>y</var> scalars.
+
+        <p>For example,
+
+     <pre class="example">          givens (1, 1)
+                  0.70711   0.70711
+                   -0.70711   0.70711
+</pre>
+        </blockquote></div>
+
+<!-- ./linear-algebra/planerot.m -->
+   <p><a name="doc_002dplanerot"></a>
+
+<div class="defun">
+— Function File: [<var>g</var>, <var>y</var>] = <b>planerot</b> (<var>x</var>)<var><a name="index-planerot-1563"></a></var><br>
+<blockquote><p>Given a two-element column vector, returns the
+2 by 2 orthogonal matrix
+<var>G</var> such that
+<var>y</var><code> = </code><var>g</var><code> * </code><var>x</var> and <var>y</var><code>(2) = 0</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgivens.html#doc_002dgivens">givens</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/inv.cc -->
+   <p><a name="doc_002dinv"></a>
+
+<div class="defun">
+— Loadable Function: [<var>x</var>, <var>rcond</var>] = <b>inv</b> (<var>a</var>)<var><a name="index-inv-1564"></a></var><br>
+— Loadable Function: [<var>x</var>, <var>rcond</var>] = <b>inverse</b> (<var>a</var>)<var><a name="index-inverse-1565"></a></var><br>
+<blockquote><p>Compute the inverse of the square matrix <var>a</var>.  Return an estimate
+of the reciprocal condition number if requested, otherwise warn of an
+ill-conditioned matrix if the reciprocal condition number is small.
+
+        <p>If called with a sparse matrix, then in general <var>x</var> will be a full
+matrix, and so if possible forming the inverse of a sparse matrix should
+be avoided.  It is significantly more accurate and faster to do
+<var>y</var><code> = </code><var>a</var><code> \ </code><var>b</var>, rather than
+<var>y</var><code> = inv (</code><var>a</var><code>) * </code><var>b</var>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/matrix_type.cc -->
+   <p><a name="doc_002dmatrix_005ftype"></a>
+
+<div class="defun">
+— Loadable Function: <var>type</var> = <b>matrix_type</b> (<var>a</var>)<var><a name="index-matrix_005ftype-1566"></a></var><br>
+— Loadable Function: <var>a</var> = <b>matrix_type</b> (<var>a, type</var>)<var><a name="index-matrix_005ftype-1567"></a></var><br>
+— Loadable Function: <var>a</var> = <b>matrix_type</b> (<var>a, 'upper', perm</var>)<var><a name="index-matrix_005ftype-1568"></a></var><br>
+— Loadable Function: <var>a</var> = <b>matrix_type</b> (<var>a, 'lower', perm</var>)<var><a name="index-matrix_005ftype-1569"></a></var><br>
+— Loadable Function: <var>a</var> = <b>matrix_type</b> (<var>a, 'banded', nl, nu</var>)<var><a name="index-matrix_005ftype-1570"></a></var><br>
+<blockquote><p>Identify the matrix type or mark a matrix as a particular type.  This allows rapid
+for solutions of linear equations involving <var>a</var> to be performed.  Called with a
+single argument, <code>matrix_type</code> returns the type of the matrix and caches it for
+future use.  Called with more than one argument, <code>matrix_type</code> allows the type
+of the matrix to be defined.
+
+        <p>The possible matrix types depend on whether the matrix is full or sparse, and can be
+one of the following
+
+          <dl>
+<dt>'unknown'<dd>Remove any previously cached matrix type, and mark type as unknown
+
+          <br><dt>'full'<dd>Mark the matrix as full.
+
+          <br><dt>'positive definite'<dd>Probable full positive definite matrix.
+
+          <br><dt>'diagonal'<dd>Diagonal Matrix.  (Sparse matrices only)
+
+          <br><dt>'permuted diagonal'<dd>Permuted Diagonal matrix.  The permutation does not need to be specifically
+indicated, as the structure of the matrix explicitly gives this.  (Sparse matrices
+only)
+
+          <br><dt>'upper'<dd>Upper triangular.  If the optional third argument <var>perm</var> is given, the matrix is
+assumed to be a permuted upper triangular with the permutations defined by the
+vector <var>perm</var>.
+
+          <br><dt>'lower'<dd>Lower triangular.  If the optional third argument <var>perm</var> is given, the matrix is
+assumed to be a permuted lower triangular with the permutations defined by the
+vector <var>perm</var>.
+
+          <br><dt>'banded'<dt>'banded positive definite'<dd>Banded matrix with the band size of <var>nl</var> below the diagonal and <var>nu</var> above
+it.  If <var>nl</var> and <var>nu</var> are 1, then the matrix is tridiagonal and treated
+with specialized code.  In addition the matrix can be marked as probably a
+positive definite (Sparse matrices only)
+
+          <br><dt>'singular'<dd>The matrix is assumed to be singular and will be treated with a minimum norm solution
+
+        </dl>
+
+        <p>Note that the matrix type will be discovered automatically on the first attempt to
+solve a linear equation involving <var>a</var>.  Therefore <code>matrix_type</code> is only
+useful to give Octave hints of the matrix type.  Incorrectly defining the
+matrix type will result in incorrect results from solutions of linear equations,
+and so it is entirely the responsibility of the user to correctly identify the
+matrix type.
+
+        <p>Also the test for positive definiteness is a low-cost test for a hermitian
+matrix with a real positive diagonal.  This does not guarantee that the matrix
+is positive definite, but only that it is a probable candidate.  When such a
+matrix is factorized, a Cholesky factorization is first attempted, and if
+that fails the matrix is then treated with an LU factorization.  Once the
+matrix has been factorized, <code>matrix_type</code> will return the correct
+classification of the matrix. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dnorm"></a>
+
+<div class="defun">
+— Built-in Function:  <b>norm</b> (<var>a, p, opt</var>)<var><a name="index-norm-1571"></a></var><br>
+<blockquote><p>Compute the p-norm of the matrix <var>a</var>.  If the second argument is
+missing, <code>p = 2</code> is assumed.
+
+        <p>If <var>a</var> is a matrix (or sparse matrix):
+
+          <dl>
+<dt><var>p</var> = <code>1</code><dd>1-norm, the largest column sum of the absolute values of <var>a</var>.
+
+          <br><dt><var>p</var> = <code>2</code><dd>Largest singular value of <var>a</var>.
+
+          <br><dt><var>p</var> = <code>Inf</code> or <code>"inf"</code><dd><a name="index-infinity-norm-1572"></a>Infinity norm, the largest row sum of the absolute values of <var>a</var>.
+
+          <br><dt><var>p</var> = <code>"fro"</code><dd><a name="index-Frobenius-norm-1573"></a>Frobenius norm of <var>a</var>, <code>sqrt (sum (diag (</code><var>a</var><code>' * </code><var>a</var><code>)))</code>.
+
+          <br><dt>other <var>p</var>, <var>p</var><code> > 1</code><dd><a name="index-general-p_002dnorm-1574"></a>maximum <code>norm (A*x, p)</code> such that <code>norm (x, p) == 1</code>
+</dl>
+
+        <p>If <var>a</var> is a vector or a scalar:
+
+          <dl>
+<dt><var>p</var> = <code>Inf</code> or <code>"inf"</code><dd><code>max (abs (</code><var>a</var><code>))</code>.
+
+          <br><dt><var>p</var> = <code>-Inf</code><dd><code>min (abs (</code><var>a</var><code>))</code>.
+
+          <br><dt><var>p</var> = <code>"fro"</code><dd>Frobenius norm of <var>a</var>, <code>sqrt (sumsq (abs (a)))</code>.
+
+          <br><dt><var>p</var> = 0<dd>Hamming norm - the number of nonzero elements.
+
+          <br><dt>other <var>p</var>, <var>p</var><code> > 1</code><dd>p-norm of <var>a</var>, <code>(sum (abs (</code><var>a</var><code>) .^ </code><var>p</var><code>)) ^ (1/</code><var>p</var><code>)</code>.
+
+          <br><dt>other <var>p</var> <var>p</var><code> < 1</code><dd>the p-pseudonorm defined as above. 
+</dl>
+
+        <p>If <code>"rows"</code> is given as <var>opt</var>, the norms of all rows of the matrix <var>a</var> are
+returned as a column vector.  Similarly, if <code>"columns"</code> or <code>"cols"</code> is passed
+column norms are computed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcond.html#doc_002dcond">cond</a>, <a href="doc_002dsvd.html#doc_002dsvd">svd</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/null.m -->
+   <p><a name="doc_002dnull"></a>
+
+<div class="defun">
+— Function File:  <b>null</b> (<var>a, tol</var>)<var><a name="index-null-1575"></a></var><br>
+<blockquote><p>Return an orthonormal basis of the null space of <var>a</var>.
+
+        <p>The dimension of the null space is taken as the number of singular
+values of <var>a</var> not greater than <var>tol</var>.  If the argument <var>tol</var>
+is missing, it is computed as
+
+     <pre class="example">          max (size (<var>a</var>)) * max (svd (<var>a</var>)) * eps
+</pre>
+        </blockquote></div>
+
+<!-- ./linear-algebra/orth.m -->
+   <p><a name="doc_002dorth"></a>
+
+<div class="defun">
+— Function File:  <b>orth</b> (<var>a, tol</var>)<var><a name="index-orth-1576"></a></var><br>
+<blockquote><p>Return an orthonormal basis of the range space of <var>a</var>.
+
+        <p>The dimension of the range space is taken as the number of singular
+values of <var>a</var> greater than <var>tol</var>.  If the argument <var>tol</var> is
+missing, it is computed as
+
+     <pre class="example">          max (size (<var>a</var>)) * max (svd (<var>a</var>)) * eps
+</pre>
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/pinv.cc -->
+   <p><a name="doc_002dpinv"></a>
+
+<div class="defun">
+— Loadable Function:  <b>pinv</b> (<var>x, tol</var>)<var><a name="index-pinv-1577"></a></var><br>
+<blockquote><p>Return the pseudoinverse of <var>x</var>.  Singular values less than
+<var>tol</var> are ignored.
+
+        <p>If the second argument is omitted, it is assumed that
+
+     <pre class="example">          tol = max (size (<var>x</var>)) * sigma_max (<var>x</var>) * eps,
+</pre>
+        <p class="noindent">where <code>sigma_max (</code><var>x</var><code>)</code> is the maximal singular value of <var>x</var>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/rank.m -->
+   <p><a name="doc_002drank"></a>
+
+<div class="defun">
+— Function File:  <b>rank</b> (<var>a, tol</var>)<var><a name="index-rank-1578"></a></var><br>
+<blockquote><p>Compute the rank of <var>a</var>, using the singular value decomposition. 
+The rank is taken to be the number of singular values of <var>a</var> that
+are greater than the specified tolerance <var>tol</var>.  If the second
+argument is omitted, it is taken to be
+
+     <pre class="example">          tol = max (size (<var>a</var>)) * sigma(1) * eps;
+</pre>
+        <p class="noindent">where <code>eps</code> is machine precision and <code>sigma(1)</code> is the largest
+singular value of <var>a</var>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/rcond.cc -->
+   <p><a name="doc_002drcond"></a>
+
+<div class="defun">
+— Loadable Function: <var>c</var> = <b>rcond</b> (<var>a</var>)<var><a name="index-rcond-1579"></a></var><br>
+<blockquote><p>Compute the 1-norm estimate of the reciprocal condition as returned
+by <span class="sc">lapack</span>.  If the matrix is well-conditioned then <var>c</var> will be near
+1 and if the matrix is poorly conditioned it will be close to zero.
+
+        <p>The matrix <var>a</var> must not be sparse.  If the matrix is sparse then
+<code>condest (</code><var>a</var><code>)</code> or <code>rcond (full (</code><var>a</var><code>))</code> should be used
+instead. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinv.html#doc_002dinv">inv</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/trace.m -->
+   <p><a name="doc_002dtrace"></a>
+
+<div class="defun">
+— Function File:  <b>trace</b> (<var>a</var>)<var><a name="index-trace-1580"></a></var><br>
+<blockquote><p>Compute the trace of <var>a</var>, <code>sum (diag (</code><var>a</var><code>))</code>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/rref.m -->
+   <p><a name="doc_002drref"></a>
+
+<div class="defun">
+— Function File: [<var>r</var>, <var>k</var>] = <b>rref</b> (<var>a, tol</var>)<var><a name="index-rref-1581"></a></var><br>
+<blockquote>
+        <p>Returns the reduced row echelon form of <var>a</var>.  <var>tol</var> defaults
+to <code>eps * max (size (</code><var>a</var><code>)) * norm (</code><var>a</var><code>, inf)</code>.
+
+        <p>Called with two return arguments, <var>k</var> returns the vector of
+"bound variables", which are those columns on which elimination
+has been performed.
+
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Basic-Statistical-Functions.html b/doc/interpreter/HTML/Basic-Statistical-Functions.html
new file mode 100644
index 0000000..1595889
--- /dev/null
+++ b/doc/interpreter/HTML/Basic-Statistical-Functions.html
@@ -0,0 +1,335 @@
+<html lang="en">
+<head>
+<title>Basic Statistical Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="prev" href="Descriptive-Statistics.html#Descriptive-Statistics" title="Descriptive Statistics">
+<link rel="next" href="Statistical-Plots.html#Statistical-Plots" title="Statistical Plots">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basic-Statistical-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Statistical-Plots.html#Statistical-Plots">Statistical Plots</a>,
+Previous: <a rel="previous" accesskey="p" href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.2 Basic Statistical Functions</h3>
+
+<p>Octave also supports various helpful statistical functions.
+
+<!-- ./statistics/base/mahalanobis.m -->
+   <p><a name="doc_002dmahalanobis"></a>
+
+<div class="defun">
+— Function File:  <b>mahalanobis</b> (<var>x, y</var>)<var><a name="index-mahalanobis-1840"></a></var><br>
+<blockquote><p>Return the Mahalanobis' D-square distance between the multivariate
+samples <var>x</var> and <var>y</var>, which must have the same number of
+components (columns), but may have a different number of observations
+(rows). 
+</p></blockquote></div>
+
+<!-- ./statistics/base/center.m -->
+   <p><a name="doc_002dcenter"></a>
+
+<div class="defun">
+— Function File:  <b>center</b> (<var>x</var>)<var><a name="index-center-1841"></a></var><br>
+— Function File:  <b>center</b> (<var>x, dim</var>)<var><a name="index-center-1842"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, subtract its mean. 
+If <var>x</var> is a matrix, do the above for each column. 
+If the optional argument <var>dim</var> is given, perform the above
+operation along this dimension
+</p></blockquote></div>
+
+<!-- ./statistics/base/studentize.m -->
+   <p><a name="doc_002dstudentize"></a>
+
+<div class="defun">
+— Function File:  <b>studentize</b> (<var>x, dim</var>)<var><a name="index-studentize-1843"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, subtract its mean and divide by its standard
+deviation.
+
+        <p>If <var>x</var> is a matrix, do the above along the first non-singleton
+dimension.  If the optional argument <var>dim</var> is given then operate
+along this dimension. 
+</p></blockquote></div>
+
+<!-- ./specfun/nchoosek.m -->
+   <p><a name="doc_002dnchoosek"></a>
+
+<div class="defun">
+— Function File: <var>c</var> = <b>nchoosek</b> (<var>n, k</var>)<var><a name="index-nchoosek-1844"></a></var><br>
+<blockquote>
+        <p>Compute the binomial coefficient or all combinations of <var>n</var>. 
+If <var>n</var> is a scalar then, calculate the binomial coefficient
+of <var>n</var> and <var>k</var>, defined as
+
+     <pre class="example">           /   \
+           | n |    n (n-1) (n-2) ... (n-k+1)       n!
+           |   |  = ------------------------- =  ---------
+           | k |               k!                k! (n-k)!
+           \   /
+</pre>
+        <p>If <var>n</var> is a vector generate all combinations of the elements
+of <var>n</var>, taken <var>k</var> at a time, one row per combination.  The
+resulting <var>c</var> has size <code>[nchoosek (length (</code><var>n</var><code>),
+</code><var>k</var><code>), </code><var>k</var><code>]</code>.
+
+        <p><code>nchoosek</code> works only for non-negative integer arguments; use
+<code>bincoeff</code> for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbincoeff.html#doc_002dbincoeff">bincoeff</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/histc.m -->
+   <p><a name="doc_002dhistc"></a>
+
+<div class="defun">
+— Function File: <var>n</var> = <b>histc</b> (<var>y, edges</var>)<var><a name="index-histc-1845"></a></var><br>
+— Function File: <var>n</var> = <b>histc</b> (<var>y, edges, dim</var>)<var><a name="index-histc-1846"></a></var><br>
+— Function File: [<var>n</var>, <var>idx</var>] = <b>histc</b> (<var><small class="dots">...</small></var>)<var><a name="index-histc-1847"></a></var><br>
+<blockquote><p>Produce histogram counts.
+
+        <p>When <var>y</var> is a vector, the function counts the number of elements of
+<var>y</var> that fall in the histogram bins defined by <var>edges</var>.  This must be
+a vector of monotonically non-decreasing values that define the edges of the
+histogram bins.  So, <var>n</var><code> (k)</code> contains the number of elements in
+<var>y</var> for which <var>edges</var><code> (k) <= </code><var>y</var><code> < </code><var>edges</var><code> (k+1)</code>. 
+The final element of <var>n</var> contains the number of elements of <var>y</var>
+that was equal to the last element of <var>edges</var>.
+
+        <p>When <var>y</var> is a N-dimensional array, the same operation as above is
+repeated along dimension <var>dim</var>.  If this argument is given, the operation
+is performed along the first non-singleton dimension.
+
+        <p>If a second output argument is requested an index matrix is also returned. 
+The <var>idx</var> matrix has same size as <var>y</var>.  Each element of <var>idx</var>
+contains the index of the histogram bin in which the corresponding element
+of <var>y</var> was counted.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhist.html#doc_002dhist">hist</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/perms.m -->
+   <p><a name="doc_002dperms"></a>
+
+<div class="defun">
+— Function File:  <b>perms</b> (<var>v</var>)<var><a name="index-perms-1848"></a></var><br>
+<blockquote>
+        <p>Generate all permutations of <var>v</var>, one row per permutation.  The
+result has size <code>factorial (</code><var>n</var><code>) * </code><var>n</var>, where <var>n</var>
+is the length of <var>v</var>.
+
+        <p>As an example, <code>perms([1, 2, 3])</code> returns the matrix
+     <pre class="example">            1   2   3
+            2   1   3
+            1   3   2
+            2   3   1
+            3   1   2
+            3   2   1
+</pre>
+        </blockquote></div>
+
+<!-- ./statistics/base/values.m -->
+   <p><a name="doc_002dvalues"></a>
+
+<div class="defun">
+— Function File:  <b>values</b> (<var>x</var>)<var><a name="index-values-1849"></a></var><br>
+<blockquote><p>Return the different values in a column vector, arranged in ascending
+order.
+
+        <p>As an example, <code>values([1, 2, 3, 1])</code> returns the vector
+<code>[1, 2, 3]</code>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/table.m -->
+   <p><a name="doc_002dtable"></a>
+
+<div class="defun">
+— Function File: [<var>t</var>, <var>l_x</var>] = <b>table</b> (<var>x</var>)<var><a name="index-table-1850"></a></var><br>
+— Function File: [<var>t</var>, <var>l_x</var>, <var>l_y</var>] = <b>table</b> (<var>x, y</var>)<var><a name="index-table-1851"></a></var><br>
+<blockquote><p>Create a contingency table <var>t</var> from data vectors.  The <var>l</var>
+vectors are the corresponding levels.
+
+        <p>Currently, only 1- and 2-dimensional tables are supported. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/spearman.m -->
+   <p><a name="doc_002dspearman"></a>
+
+<div class="defun">
+— Function File:  <b>spearman</b> (<var>x, y</var>)<var><a name="index-spearman-1852"></a></var><br>
+<blockquote><p>Compute Spearman's rank correlation coefficient <var>rho</var> for each of
+the variables specified by the input arguments.
+
+        <p>For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+        <p><code>spearman (</code><var>x</var><code>)</code> is equivalent to <code>spearman (</code><var>x</var><code>,
+</code><var>x</var><code>)</code>.
+
+        <p>For two data vectors <var>x</var> and <var>y</var>, Spearman's <var>rho</var> is the
+correlation of the ranks of <var>x</var> and <var>y</var>.
+
+        <p>If <var>x</var> and <var>y</var> are drawn from independent distributions,
+<var>rho</var> has zero mean and variance <code>1 / (n - 1)</code>, and is
+asymptotically normally distributed. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/run_count.m -->
+   <p><a name="doc_002drun_005fcount"></a>
+
+<div class="defun">
+— Function File:  <b>run_count</b> (<var>x, n</var>)<var><a name="index-run_005fcount-1853"></a></var><br>
+<blockquote><p>Count the upward runs along the first non-singleton dimension of
+<var>x</var> of length 1, 2, <small class="dots">...</small>, <var>n</var>-1 and greater than or equal
+to <var>n</var>.  If the optional argument <var>dim</var> is given operate
+along this dimension
+</p></blockquote></div>
+
+<!-- ./statistics/base/ranks.m -->
+   <p><a name="doc_002dranks"></a>
+
+<div class="defun">
+— Function File:  <b>ranks</b> (<var>x, dim</var>)<var><a name="index-ranks-1854"></a></var><br>
+<blockquote><p>Return the ranks of <var>x</var> along the first non-singleton dimension
+adjust for ties.  If the optional argument <var>dim</var> is
+given, operate along this dimension. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/range.m -->
+   <p><a name="doc_002drange"></a>
+
+<div class="defun">
+— Function File:  <b>range</b> (<var>x</var>)<var><a name="index-range-1855"></a></var><br>
+— Function File:  <b>range</b> (<var>x, dim</var>)<var><a name="index-range-1856"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, return the range, i.e., the difference
+between the maximum and the minimum, of the input data.
+
+        <p>If <var>x</var> is a matrix, do the above for each column of <var>x</var>.
+
+        <p>If the optional argument <var>dim</var> is supplied, work along dimension
+<var>dim</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/probit.m -->
+   <p><a name="doc_002dprobit"></a>
+
+<div class="defun">
+— Function File:  <b>probit</b> (<var>p</var>)<var><a name="index-probit-1857"></a></var><br>
+<blockquote><p>For each component of <var>p</var>, return the probit (the quantile of the
+standard normal distribution) of <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/logit.m -->
+   <p><a name="doc_002dlogit"></a>
+
+<div class="defun">
+— Function File:  <b>logit</b> (<var>p</var>)<var><a name="index-logit-1858"></a></var><br>
+<blockquote><p>For each component of <var>p</var>, return the logit of <var>p</var> defined as
+     <pre class="example">          logit(<var>p</var>) = log (<var>p</var> / (1-<var>p</var>))
+</pre>
+        </blockquote></div>
+
+<!-- ./statistics/base/cloglog.m -->
+   <p><a name="doc_002dcloglog"></a>
+
+<div class="defun">
+— Function File:  <b>cloglog</b> (<var>x</var>)<var><a name="index-cloglog-1859"></a></var><br>
+<blockquote><p>Return the complementary log-log function of <var>x</var>, defined as
+
+     <pre class="example">          cloglog(x) = - log (- log (<var>x</var>))
+</pre>
+        </blockquote></div>
+
+<!-- ./statistics/base/kendall.m -->
+   <p><a name="doc_002dkendall"></a>
+
+<div class="defun">
+— Function File:  <b>kendall</b> (<var>x, y</var>)<var><a name="index-kendall-1860"></a></var><br>
+<blockquote><p>Compute Kendall's <var>tau</var> for each of the variables specified by
+the input arguments.
+
+        <p>For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+        <p><code>kendall (</code><var>x</var><code>)</code> is equivalent to <code>kendall (</code><var>x</var><code>,
+</code><var>x</var><code>)</code>.
+
+        <p>For two data vectors <var>x</var>, <var>y</var> of common length <var>n</var>,
+Kendall's <var>tau</var> is the correlation of the signs of all rank
+differences of <var>x</var> and <var>y</var>;  i.e., if both <var>x</var> and
+<var>y</var> have distinct entries, then
+
+     <pre class="example">                   1
+          tau = -------   SUM sign (q(i) - q(j)) * sign (r(i) - r(j))
+                n (n-1)   i,j
+</pre>
+        <p class="noindent">in which the
+<var>q</var>(<var>i</var>) and <var>r</var>(<var>i</var>)
+ are the ranks of
+<var>x</var> and <var>y</var>, respectively.
+
+        <p>If <var>x</var> and <var>y</var> are drawn from independent distributions,
+Kendall's <var>tau</var> is asymptotically normal with mean 0 and variance
+<code>(2 * (2</code><var>n</var><code>+5)) / (9 * </code><var>n</var><code> * (</code><var>n</var><code>-1))</code>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/iqr.m -->
+   <p><a name="doc_002diqr"></a>
+
+<div class="defun">
+— Function File:  <b>iqr</b> (<var>x, dim</var>)<var><a name="index-iqr-1861"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, return the interquartile range, i.e., the
+difference between the upper and lower quartile, of the input data.
+
+        <p>If <var>x</var> is a matrix, do the above for first non-singleton
+dimension of <var>x</var>.  If the option <var>dim</var> argument is given,
+then operate along this dimension. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/cut.m -->
+   <p><a name="doc_002dcut"></a>
+
+<div class="defun">
+— Function File:  <b>cut</b> (<var>x, breaks</var>)<var><a name="index-cut-1862"></a></var><br>
+<blockquote><p>Create categorical data out of numerical or continuous data by
+cutting into intervals.
+
+        <p>If <var>breaks</var> is a scalar, the data is cut into that many
+equal-width intervals.  If <var>breaks</var> is a vector of break points,
+the category has <code>length (</code><var>breaks</var><code>) - 1</code> groups.
+
+        <p>The returned value is a vector of the same size as <var>x</var> telling
+which group each point in <var>x</var> belongs to.  Groups are labelled
+from 1 to the number of groups; points outside the range of
+<var>breaks</var> are labelled by <code>NaN</code>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Basic-Usage-and-Examples.html b/doc/interpreter/HTML/Basic-Usage-and-Examples.html
new file mode 100644
index 0000000..ae713b6
--- /dev/null
+++ b/doc/interpreter/HTML/Basic-Usage-and-Examples.html
@@ -0,0 +1,189 @@
+<html lang="en">
+<head>
+<title>Basic Usage and Examples - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Structures.html#Data-Structures" title="Data Structures">
+<link rel="next" href="Structure-Arrays.html#Structure-Arrays" title="Structure Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basic-Usage-and-Examples"></a>
+Next: <a rel="next" accesskey="n" href="Structure-Arrays.html#Structure-Arrays">Structure Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Data-Structures.html#Data-Structures">Data Structures</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.1.1 Basic Usage and Examples</h4>
+
+<p>Here are some examples of using data structures in Octave.
+
+   <p>Elements of structures can be of any value type.  For example, the three
+expressions
+
+<pre class="example">     x.a = 1;
+     x.b = [1, 2; 3, 4];
+     x.c = "string";
+</pre>
+   <p class="noindent">create a structure with three elements.  To print the value of the
+structure, you can type its name, just as for any other variable:
+
+<pre class="example">     x
+           x =
+             {
+               a = 1
+               b =
+     
+                 1  2
+                 3  4
+     
+               c = string
+             }
+</pre>
+   <p class="noindent">Note that Octave may print the elements in any order.
+
+   <p>Structures may be copied just like any other variable:
+
+<pre class="example">     y = x
+           y =
+             {
+               a = 1
+               b =
+     
+                 1  2
+                 3  4
+     
+               c = string
+             }
+</pre>
+   <p>Since structures are themselves values, structure elements may reference
+other structures.  The following statements change the value of the
+element <code>b</code> of the structure <code>x</code> to be a data structure
+containing the single element <code>d</code>, which has a value of 3.
+
+<pre class="example">     x.b.d = 3;
+     x.b
+           ans =
+             {
+               d = 3
+             }
+     
+     x
+           x =
+             {
+               a = 1
+               b =
+               {
+                 d = 3
+               }
+     
+               c = string
+             }
+</pre>
+   <p>Note that when Octave prints the value of a structure that contains
+other structures, only a few levels are displayed.  For example,
+
+<pre class="example">     a.b.c.d.e = 1;
+     a
+           a =
+             {
+               b =
+               {
+                 c =
+                 {
+                   1x1 struct array containing the fields:
+     
+                   d: 1x1 struct
+                 }
+               }
+             }
+</pre>
+   <p class="noindent">This prevents long and confusing output from large deeply nested
+structures. The number of levels to print for nested structures can be
+set with the function <code>struct_levels_to_print</code>:
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002dstruct_005flevels_005fto_005fprint"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>struct_levels_to_print</b> ()<var><a name="index-struct_005flevels_005fto_005fprint-371"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>struct_levels_to_print</b> (<var>new_val</var>)<var><a name="index-struct_005flevels_005fto_005fprint-372"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the number of
+structure levels to display. 
+</p></blockquote></div>
+
+   <p>Functions can return structures.  For example, the following function
+separates the real and complex parts of a matrix and stores them in two
+elements of the same structure variable.
+
+<pre class="example">     function y = f (x)
+       y.re = real (x);
+       y.im = imag (x);
+     endfunction
+</pre>
+   <p>When called with a complex-valued argument, <code>f</code> returns the data
+structure containing the real and imaginary parts of the original
+function argument.
+
+<pre class="example">     f (rand (2) + rand (2) * I)
+           ans =
+             {
+               im =
+     
+                 0.26475  0.14828
+                 0.18436  0.83669
+     
+               re =
+     
+                 0.040239  0.242160
+                 0.238081  0.402523
+     
+             }
+</pre>
+   <p>Function return lists can include structure elements, and they may be
+indexed like any other variable.  For example,
+
+<pre class="example">     [ x.u, x.s(2:3,2:3), x.v ] = svd ([1, 2; 3, 4]);
+     x
+           x =
+             {
+               u =
+     
+                 -0.40455  -0.91451
+                 -0.91451   0.40455
+     
+               s =
+     
+                  0.00000   0.00000   0.00000
+                  0.00000   5.46499   0.00000
+                  0.00000   0.00000   0.36597
+     
+               v =
+     
+                 -0.57605   0.81742
+                 -0.81742  -0.57605
+     
+             }
+</pre>
+   <p>It is also possible to cycle through all the elements of a structure in
+a loop, using a special form of the <code>for</code> statement
+(see <a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a>).
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Basic-Usage-of-Cell-Arrays.html b/doc/interpreter/HTML/Basic-Usage-of-Cell-Arrays.html
new file mode 100644
index 0000000..378358a
--- /dev/null
+++ b/doc/interpreter/HTML/Basic-Usage-of-Cell-Arrays.html
@@ -0,0 +1,120 @@
+<html lang="en">
+<head>
+<title>Basic Usage of Cell Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link rel="next" href="Creating-Cell-Arrays.html#Creating-Cell-Arrays" title="Creating Cell Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basic-Usage-of-Cell-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.2.1 Basic Usage of Cell Arrays</h4>
+
+<p>As an example, the following code creates a cell array containing a
+string and a 2-by-2 random matrix
+
+<pre class="example">     c = {"a string", rand(2, 2)};
+</pre>
+   <p class="noindent">To access the elements of a cell array, it can be indexed with the {
+and } operators.  Thus, the variable created in the previous example
+can be indexed like this:
+
+<pre class="example">     c{1}
+           ans = a string
+</pre>
+   <p class="noindent">As with numerical arrays several elements of a cell array can be
+extracted by indexing with a vector of indexes
+
+<pre class="example">     c{1:2}
+           ans =
+     
+               (,
+                 [1] = a string
+                 [2] =
+     
+                    0.593993   0.627732
+                    0.377037   0.033643
+     
+               ,)
+</pre>
+   <p>The indexing operators can also be used to insert or overwrite elements
+of a cell array.  The following code inserts the scalar 3 on the
+third place of the previously created cell array
+
+<pre class="example">     c{3} = 3
+           c =
+     
+              {
+                [1,1] = a string
+                [1,2] =
+     
+                   0.593993   0.627732
+                   0.377037   0.033643
+     
+                [1,3] =  3
+              }
+</pre>
+   <p>Details on indexing cell arrays are explained in <a href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>.
+
+   <p>In general nested cell arrays are displayed hierarchically as in the
+previous example.  In some circumstances it makes sense to reference
+them by their index, and this can be performed by the <code>celldisp</code>
+function.
+
+<!-- ./general/celldisp.m -->
+   <p><a name="doc_002dcelldisp"></a>
+
+<div class="defun">
+— Function File:  <b>celldisp</b> (<var>c, name</var>)<var><a name="index-celldisp-388"></a></var><br>
+<blockquote><p>Recursively display the contents of a cell array.  By default the values
+are displayed with the name of the variable <var>c</var>.  However, this name
+can be replaced with the variable <var>name</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddisp.html#doc_002ddisp">disp</a>. 
+</p></blockquote></div>
+
+   <p>To test if an object is a cell array, use the <code>iscell</code>
+function. For example:
+
+<pre class="example">     iscell(c)
+           ans = 1
+     
+     iscell(3)
+           ans = 0
+</pre>
+   <!-- ov-cell.cc -->
+   <p><a name="doc_002discell"></a>
+
+<div class="defun">
+— Built-in Function:  <b>iscell</b> (<var>x</var>)<var><a name="index-iscell-389"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a cell array object.  Otherwise, return
+false. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Basic-Usage.html b/doc/interpreter/HTML/Basic-Usage.html
new file mode 100644
index 0000000..a5fa082
--- /dev/null
+++ b/doc/interpreter/HTML/Basic-Usage.html
@@ -0,0 +1,60 @@
+<html lang="en">
+<head>
+<title>Basic Usage - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link rel="next" href="Matrix-Algebra.html#Matrix-Algebra" title="Matrix Algebra">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basic-Usage"></a>
+Next: <a rel="next" accesskey="n" href="Matrix-Algebra.html#Matrix-Algebra">Matrix Algebra</a>,
+Up: <a rel="up" accesskey="u" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">20.1 Creating and Manipulating Diagonal and Permutation Matrices</h3>
+
+<p>A diagonal matrix is defined as a matrix that has zero entries outside the main diagonal;
+that is,
+<code>D(i,j) == 0</code> if <code>i != j</code>. 
+Most often, square diagonal matrices are considered; however, the definition can equally
+be applied to nonsquare matrices, in which case we usually speak of a rectangular diagonal
+matrix.
+
+   <p>A permutation matrix is defined as a square matrix that has a single element equal to unity
+in each row and each column; all other elements are zero.  That is, there exists a
+permutation (vector)
+<code>p</code> such that <code>P(i,j) == 1</code> if <code>j == p(i)</code> and
+<code>P(i,j) == 0</code> otherwise.
+
+   <p>Octave provides special treatment of real and complex rectangular diagonal matrices,
+as well as permutation matrices.  They are stored as special objects, using efficient
+storage and algorithms, facilitating writing both readable and efficient matrix algebra
+expressions in the Octave language.
+
+<ul class="menu">
+<li><a accesskey="1" href="Creating-Diagonal-Matrices.html#Creating-Diagonal-Matrices">Creating Diagonal Matrices</a>
+<li><a accesskey="2" href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices">Creating Permutation Matrices</a>
+<li><a accesskey="3" href="Explicit-and-Implicit-Conversions.html#Explicit-and-Implicit-Conversions">Explicit and Implicit Conversions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Basics.html b/doc/interpreter/HTML/Basics.html
new file mode 100644
index 0000000..0a49f8f
--- /dev/null
+++ b/doc/interpreter/HTML/Basics.html
@@ -0,0 +1,62 @@
+<html lang="en">
+<head>
+<title>Basics - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices.html#Sparse-Matrices" title="Sparse Matrices">
+<link rel="next" href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra" title="Sparse Linear Algebra">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Basics"></a>
+Next: <a rel="next" accesskey="n" href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">21.1 The Creation and Manipulation of Sparse Matrices</h3>
+
+<p>The size of mathematical problems that can be treated at any particular
+time is generally limited by the available computing resources.  Both,
+the speed of the computer and its available memory place limitation on
+the problem size.
+
+   <p>There are many classes of mathematical problems which give rise to
+matrices, where a large number of the elements are zero.  In this case
+it makes sense to have a special matrix type to handle this class of
+problems where only the non-zero elements of the matrix are
+stored.  Not only does this reduce the amount of memory to store the
+matrix, but it also means that operations on this type of matrix can
+take advantage of the a-priori knowledge of the positions of the
+non-zero elements to accelerate their calculations.
+
+   <p>A matrix type that stores only the non-zero elements is generally called
+sparse.  It is the purpose of this document to discuss the basics of the
+storage and creation of sparse matrices and the fundamental operations
+on them.
+
+<ul class="menu">
+<li><a accesskey="1" href="Storage-of-Sparse-Matrices.html#Storage-of-Sparse-Matrices">Storage of Sparse Matrices</a>
+<li><a accesskey="2" href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a>
+<li><a accesskey="3" href="Information.html#Information">Information</a>
+<li><a accesskey="4" href="Operators-and-Functions.html#Operators-and-Functions">Operators and Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Binary-I_002fO.html b/doc/interpreter/HTML/Binary-I_002fO.html
new file mode 100644
index 0000000..e5ba7bb
--- /dev/null
+++ b/doc/interpreter/HTML/Binary-I_002fO.html
@@ -0,0 +1,200 @@
+<html lang="en">
+<head>
+<title>Binary I/O - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="String-Input-Conversions.html#String-Input-Conversions" title="String Input Conversions">
+<link rel="next" href="Temporary-Files.html#Temporary-Files" title="Temporary Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Binary-I%2fO"></a>
+<a name="Binary-I_002fO"></a>
+Next: <a rel="next" accesskey="n" href="Temporary-Files.html#Temporary-Files">Temporary Files</a>,
+Previous: <a rel="previous" accesskey="p" href="String-Input-Conversions.html#String-Input-Conversions">String Input Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.16 Binary I/O</h4>
+
+<p>Octave can read and write binary data using the functions <code>fread</code>
+and <code>fwrite</code>, which are patterned after the standard C functions
+with the same names.  They are able to automatically swap the byte order
+of integer data and convert among the supported floating point formats
+as the data are read.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfread"></a>
+
+<div class="defun">
+— Built-in Function: [<var>val</var>, <var>count</var>] = <b>fread</b> (<var>fid, size, precision, skip, arch</var>)<var><a name="index-fread-800"></a></var><br>
+<blockquote><p>Read binary data of type <var>precision</var> from the specified file ID
+<var>fid</var>.
+
+        <p>The optional argument <var>size</var> specifies the amount of data to read
+and may be one of
+
+          <dl>
+<dt><code>Inf</code><dd>Read as much as possible, returning a column vector.
+
+          <br><dt><var>nr</var><dd>Read up to <var>nr</var> elements, returning a column vector.
+
+          <br><dt><code>[</code><var>nr</var><code>, Inf]</code><dd>Read as much as possible, returning a matrix with <var>nr</var> rows.  If the
+number of elements read is not an exact multiple of <var>nr</var>, the last
+column is padded with zeros.
+
+          <br><dt><code>[</code><var>nr</var><code>, </code><var>nc</var><code>]</code><dd>Read up to <var>nr</var><code> * </code><var>nc</var> elements, returning a matrix with
+<var>nr</var> rows.  If the number of elements read is not an exact multiple
+of <var>nr</var>, the last column is padded with zeros. 
+</dl>
+
+     <p class="noindent">If <var>size</var> is omitted, a value of <code>Inf</code> is assumed.
+
+        <p>The optional argument <var>precision</var> is a string specifying the type of
+data to read and may be one of
+
+          <dl>
+<dt><code>"schar"</code><dt><code>"signed char"</code><dd>Signed character.
+
+          <br><dt><code>"uchar"</code><dt><code>"unsigned char"</code><dd>Unsigned character.
+
+          <br><dt><code>"int8"</code><dt><code>"integer*1"</code><dd>
+8-bit signed integer.
+
+          <br><dt><code>"int16"</code><dt><code>"integer*2"</code><dd>16-bit signed integer.
+
+          <br><dt><code>"int32"</code><dt><code>"integer*4"</code><dd>32-bit signed integer.
+
+          <br><dt><code>"int64"</code><dt><code>"integer*8"</code><dd>64-bit signed integer.
+
+          <br><dt><code>"uint8"</code><dd>8-bit unsigned integer.
+
+          <br><dt><code>"uint16"</code><dd>16-bit unsigned integer.
+
+          <br><dt><code>"uint32"</code><dd>32-bit unsigned integer.
+
+          <br><dt><code>"uint64"</code><dd>64-bit unsigned integer.
+
+          <br><dt><code>"single"</code><dt><code>"float32"</code><dt><code>"real*4"</code><dd>32-bit floating point number.
+
+          <br><dt><code>"double"</code><dt><code>"float64"</code><dt><code>"real*8"</code><dd>64-bit floating point number.
+
+          <br><dt><code>"char"</code><dt><code>"char*1"</code><dd>Single character.
+
+          <br><dt><code>"short"</code><dd>Short integer (size is platform dependent).
+
+          <br><dt><code>"int"</code><dd>Integer (size is platform dependent).
+
+          <br><dt><code>"long"</code><dd>Long integer (size is platform dependent).
+
+          <br><dt><code>"ushort"</code><dt><code>"unsigned short"</code><dd>Unsigned short integer (size is platform dependent).
+
+          <br><dt><code>"uint"</code><dt><code>"unsigned int"</code><dd>Unsigned integer (size is platform dependent).
+
+          <br><dt><code>"ulong"</code><dt><code>"unsigned long"</code><dd>Unsigned long integer (size is platform dependent).
+
+          <br><dt><code>"float"</code><dd>Single precision floating point number (size is platform dependent). 
+</dl>
+
+     <p class="noindent">The default precision is <code>"uchar"</code>.
+
+        <p>The <var>precision</var> argument may also specify an optional repeat
+count.  For example, ‘<samp><span class="samp">32*single</span></samp>’ causes <code>fread</code> to read
+a block of 32 single precision floating point numbers.  Reading in
+blocks is useful in combination with the <var>skip</var> argument.
+
+        <p>The <var>precision</var> argument may also specify a type conversion. 
+For example, ‘<samp><span class="samp">int16=>int32</span></samp>’ causes <code>fread</code> to read 16-bit
+integer values and return an array of 32-bit integer values.  By
+default, <code>fread</code> returns a double precision array.  The special
+form ‘<samp><span class="samp">*TYPE</span></samp>’ is shorthand for ‘<samp><span class="samp">TYPE=>TYPE</span></samp>’.
+
+        <p>The conversion and repeat counts may be combined.  For example, the
+specification ‘<samp><span class="samp">32*single=>single</span></samp>’ causes <code>fread</code> to read
+blocks of single precision floating point values and return an array
+of single precision values instead of the default array of double
+precision values.
+
+        <p>The optional argument <var>skip</var> specifies the number of bytes to skip
+after each element (or block of elements) is read.  If it is not
+specified, a value of 0 is assumed.  If the final block read is not
+complete, the final skip is omitted.  For example,
+
+     <pre class="example">          fread (f, 10, "3*single=>single", 8)
+</pre>
+        <p class="noindent">will omit the final 8-byte skip because the last read will not be
+a complete block of 3 values.
+
+        <p>The optional argument <var>arch</var> is a string specifying the data format
+for the file.  Valid values are
+
+          <dl>
+<dt><code>"native"</code><dd>The format of the current machine.
+
+          <br><dt><code>"ieee-be"</code><dd>IEEE big endian.
+
+          <br><dt><code>"ieee-le"</code><dd>IEEE little endian.
+
+          <br><dt><code>"vaxd"</code><dd>VAX D floating format.
+
+          <br><dt><code>"vaxg"</code><dd>VAX G floating format.
+
+          <br><dt><code>"cray"</code><dd>Cray floating format. 
+</dl>
+
+     <p class="noindent">Conversions are currently only supported for <code>"ieee-be"</code> and
+<code>"ieee-le"</code> formats.
+
+        <p>The data read from the file is returned in <var>val</var>, and the number of
+values read is returned in <code>count</code>
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfwrite.html#doc_002dfwrite">fwrite</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfwrite"></a>
+
+<div class="defun">
+— Built-in Function: <var>count</var> = <b>fwrite</b> (<var>fid, data, precision, skip, arch</var>)<var><a name="index-fwrite-801"></a></var><br>
+<blockquote><p>Write data in binary form of type <var>precision</var> to the specified file
+ID <var>fid</var>, returning the number of values successfully written to the
+file.
+
+        <p>The argument <var>data</var> is a matrix of values that are to be written to
+the file.  The values are extracted in column-major order.
+
+        <p>The remaining arguments <var>precision</var>, <var>skip</var>, and <var>arch</var> are
+optional, and are interpreted as described for <code>fread</code>.
+
+        <p>The behavior of <code>fwrite</code> is undefined if the values in <var>data</var>
+are too large to fit in the specified precision. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Bit-Manipulations.html b/doc/interpreter/HTML/Bit-Manipulations.html
new file mode 100644
index 0000000..1869dd2
--- /dev/null
+++ b/doc/interpreter/HTML/Bit-Manipulations.html
@@ -0,0 +1,229 @@
+<html lang="en">
+<head>
+<title>Bit Manipulations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Integer-Data-Types.html#Integer-Data-Types" title="Integer Data Types">
+<link rel="next" href="Logical-Values.html#Logical-Values" title="Logical Values">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bit-Manipulations"></a>
+Next: <a rel="next" accesskey="n" href="Logical-Values.html#Logical-Values">Logical Values</a>,
+Previous: <a rel="previous" accesskey="p" href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.5 Bit Manipulations</h3>
+
+<p>Octave provides a number of functions for the manipulation of numeric
+values on a bit by bit basis.  The basic functions to set and obtain the
+values of individual bits are <code>bitset</code> and <code>bitget</code>.
+
+<!-- ./general/bitset.m -->
+   <p><a name="doc_002dbitset"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>bitset</b> (<var>a, n</var>)<var><a name="index-bitset-250"></a></var><br>
+— Function File: <var>x</var> = <b>bitset</b> (<var>a, n, v</var>)<var><a name="index-bitset-251"></a></var><br>
+<blockquote><p>Set or reset bit(s) <var>n</var> of unsigned integers in <var>a</var>. 
+<var>v</var> = 0 resets and <var>v</var> = 1 sets the bits. 
+The lowest significant bit is: <var>n</var> = 1
+
+     <pre class="example">          dec2bin (bitset (10, 1))
+           1011
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitand.html#doc_002dbitand">bitand</a>, <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitxor.html#doc_002dbitxor">bitxor</a>, <a href="doc_002dbitget.html#doc_002dbitget">bitget</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitshift.html#doc_002dbitshift">bitshift</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+<!-- ./general/bitget.m -->
+   <p><a name="doc_002dbitget"></a>
+
+<div class="defun">
+— Function File: <var>X</var> = <b>bitget</b> (<var>a,n</var>)<var><a name="index-bitget-252"></a></var><br>
+<blockquote><p>Return the status of bit(s) <var>n</var> of unsigned integers in <var>a</var>
+the lowest significant bit is <var>n</var> = 1.
+
+     <pre class="example">          bitget (100, 8:-1:1)
+           0  1  1  0  0  1  0  0
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitand.html#doc_002dbitand">bitand</a>, <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitxor.html#doc_002dbitxor">bitxor</a>, <a href="doc_002dbitset.html#doc_002dbitset">bitset</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitshift.html#doc_002dbitshift">bitshift</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+   <p>The arguments to all of Octave's bitwise operations can be scalar or
+arrays, except for <code>bitcmp</code>, whose <var>k</var> argument must a
+scalar.  In the case where more than one argument is an array, then all
+arguments must have the same shape, and the bitwise operator is applied
+to each of the elements of the argument individually.  If at least one
+argument is a scalar and one an array, then the scalar argument is
+duplicated.  Therefore
+
+<pre class="example">     bitget (100, 8:-1:1)
+</pre>
+   <p>is the same as
+
+<pre class="example">     bitget (100 * ones (1, 8), 8:-1:1)
+</pre>
+   <p>It should be noted that all values passed to the bit manipulation
+functions of Octave are treated as integers.  Therefore, even though the
+example for <code>bitset</code> above passes the floating point value
+<code>10</code>, it is treated as the bits <code>[1, 0, 1, 0]</code> rather than the
+bits of the native floating point format representation of <code>10</code>.
+
+   <p>As the maximum value that can be represented by a number is important
+for bit manipulation, particularly when forming masks, Octave supplies
+the function <code>bitmax</code>.
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dbitmax"></a>
+
+<div class="defun">
+— Built-in Function:  <b>bitmax</b> ()<var><a name="index-bitmax-253"></a></var><br>
+<blockquote><p>Return the largest integer that can be represented as a floating point
+value.  On IEEE-754 compatible systems, <code>bitmax</code> is <code>2^53 - 1</code>. 
+</p></blockquote></div>
+
+   <p>This is the double precision version of the functions <code>intmax</code>,
+previously discussed.
+
+   <p>Octave also includes the basic bitwise 'and', 'or' and 'exclusive or'
+operators.
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dbitand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>bitand</b> (<var>x, y</var>)<var><a name="index-bitand-254"></a></var><br>
+<blockquote><p>Return the bitwise AND of non-negative integers. 
+<var>x</var>, <var>y</var> must be in the range [0,bitmax]
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitxor.html#doc_002dbitxor">bitxor</a>, <a href="doc_002dbitset.html#doc_002dbitset">bitset</a>, <a href="doc_002dbitget.html#doc_002dbitget">bitget</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitshift.html#doc_002dbitshift">bitshift</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dbitor"></a>
+
+<div class="defun">
+— Built-in Function:  <b>bitor</b> (<var>x, y</var>)<var><a name="index-bitor-255"></a></var><br>
+<blockquote><p>Return the bitwise OR of non-negative integers. 
+<var>x</var>, <var>y</var> must be in the range [0,bitmax]
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitxor.html#doc_002dbitxor">bitxor</a>, <a href="doc_002dbitset.html#doc_002dbitset">bitset</a>, <a href="doc_002dbitget.html#doc_002dbitget">bitget</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitshift.html#doc_002dbitshift">bitshift</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dbitxor"></a>
+
+<div class="defun">
+— Built-in Function:  <b>bitxor</b> (<var>x, y</var>)<var><a name="index-bitxor-256"></a></var><br>
+<blockquote><p>Return the bitwise XOR of non-negative integers. 
+<var>x</var>, <var>y</var> must be in the range [0,bitmax]
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitand.html#doc_002dbitand">bitand</a>, <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitset.html#doc_002dbitset">bitset</a>, <a href="doc_002dbitget.html#doc_002dbitget">bitget</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitshift.html#doc_002dbitshift">bitshift</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+   <p>The bitwise 'not' operator is a unary operator that performs a logical
+negation of each of the bits of the value.  For this to make sense, the
+mask against which the value is negated must be defined.  Octave's
+bitwise 'not' operator is <code>bitcmp</code>.
+
+<!-- ./general/bitcmp.m -->
+   <p><a name="doc_002dbitcmp"></a>
+
+<div class="defun">
+— Function File:  <b>bitcmp</b> (<var>a, k</var>)<var><a name="index-bitcmp-257"></a></var><br>
+<blockquote><p>Return the <var>k</var>-bit complement of integers in <var>a</var>.  If
+<var>k</var> is omitted <code>k = log2 (bitmax) + 1</code> is assumed.
+
+     <pre class="example">          bitcmp(7,4)
+           8
+          dec2bin(11)
+           1011
+          dec2bin(bitcmp(11, 6))
+           110100
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitand.html#doc_002dbitand">bitand</a>, <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitxor.html#doc_002dbitxor">bitxor</a>, <a href="doc_002dbitset.html#doc_002dbitset">bitset</a>, <a href="doc_002dbitget.html#doc_002dbitget">bitget</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitshift.html#doc_002dbitshift">bitshift</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+   <p>Octave also includes the ability to left-shift and right-shift values bitwise.
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dbitshift"></a>
+
+<div class="defun">
+— Built-in Function:  <b>bitshift</b> (<var>a, k</var>)<var><a name="index-bitshift-258"></a></var><br>
+— Built-in Function:  <b>bitshift</b> (<var>a, k, n</var>)<var><a name="index-bitshift-259"></a></var><br>
+<blockquote><p>Return a <var>k</var> bit shift of <var>n</var>-digit unsigned
+integers in <var>a</var>.  A positive <var>k</var> leads to a left shift. 
+A negative value to a right shift.  If <var>n</var> is omitted it defaults
+to log2(bitmax)+1. 
+<var>n</var> must be in the range [1,log2(bitmax)+1] usually [1,33]
+
+     <pre class="example">          bitshift (eye (3), 1)
+          <p>2 0 0
+          0 2 0
+          0 0 2
+          
+          bitshift (10, [-2, -1, 0, 1, 2])
+           2   5  10  20  40
+          <!-- FIXME - restore this example when third arg is allowed to be an array. -->
+          <!-- bitshift ([1, 10], 2, [3,4]) -->
+          <!-- @result{} 4  8 -->
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbitand.html#doc_002dbitand">bitand</a>, <a href="doc_002dbitor.html#doc_002dbitor">bitor</a>, <a href="doc_002dbitxor.html#doc_002dbitxor">bitxor</a>, <a href="doc_002dbitset.html#doc_002dbitset">bitset</a>, <a href="doc_002dbitget.html#doc_002dbitget">bitget</a>, <a href="doc_002dbitcmp.html#doc_002dbitcmp">bitcmp</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+   <p>Bits that are shifted out of either end of the value are lost.  Octave
+also uses arithmetic shifts, where the sign bit of the value is kept
+during a right shift.  For example
+
+<pre class="example">     bitshift (-10, -1)
+      -5
+     bitshift (int8 (-1), -1)
+      -1
+</pre>
+   <p>Note that <code>bitshift (int8 (-1), -1)</code> is <code>-1</code> since the bit
+representation of <code>-1</code> in the <code>int8</code> data type is <code>[1, 1,
+1, 1, 1, 1, 1, 1]</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Block-Comments.html b/doc/interpreter/HTML/Block-Comments.html
new file mode 100644
index 0000000..4f85b57
--- /dev/null
+++ b/doc/interpreter/HTML/Block-Comments.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Block Comments - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Comments.html#Comments" title="Comments">
+<link rel="prev" href="Single-Line-Comments.html#Single-Line-Comments" title="Single Line Comments">
+<link rel="next" href="Comments-and-the-Help-System.html#Comments-and-the-Help-System" title="Comments and the Help System">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Block-Comments"></a>
+Next: <a rel="next" accesskey="n" href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">Comments and the Help System</a>,
+Previous: <a rel="previous" accesskey="p" href="Single-Line-Comments.html#Single-Line-Comments">Single Line Comments</a>,
+Up: <a rel="up" accesskey="u" href="Comments.html#Comments">Comments</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.7.2 Block Comments</h4>
+
+<p><a name="index-block-comments-164"></a><a name="index-multi_002dline-comments-165"></a><a name="index-g_t_0040samp_007b_0023_0040_007b_007d-166"></a><a name="index-g_t_0040samp_007b_0025_0040_007b_007d-167"></a>
+Entire blocks of code can be commented by enclosing the code between
+matching ‘<samp><span class="samp">#{</span></samp>’ and ‘<samp><span class="samp">#}</span></samp>’ or ‘<samp><span class="samp">%{</span></samp>’ and ‘<samp><span class="samp">%}</span></samp>’ markers. 
+For example,
+<pre class="example">     function quick_countdown
+       # Count down for main rocket engines
+       disp(3);
+      #{
+       disp(2);
+       disp(1);
+      #}
+       disp("Blast Off!");  # Rocket leaves pad
+     endfunction
+</pre>
+   <p class="noindent">will produce a very quick countdown from '3' to 'Blast Off' as the
+lines "<code>disp(2);</code>" and "<code>disp(1);</code>" won't be executed.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Boolean-Expressions.html b/doc/interpreter/HTML/Boolean-Expressions.html
new file mode 100644
index 0000000..4499b6b
--- /dev/null
+++ b/doc/interpreter/HTML/Boolean-Expressions.html
@@ -0,0 +1,45 @@
+<html lang="en">
+<head>
+<title>Boolean Expressions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Comparison-Ops.html#Comparison-Ops" title="Comparison Ops">
+<link rel="next" href="Assignment-Ops.html#Assignment-Ops" title="Assignment Ops">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Boolean-Expressions"></a>
+Next: <a rel="next" accesskey="n" href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a>,
+Previous: <a rel="previous" accesskey="p" href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.5 Boolean Expressions</h3>
+
+<p><a name="index-expressions_002c-boolean-507"></a><a name="index-boolean-expressions-508"></a><a name="index-expressions_002c-logical-509"></a><a name="index-logical-expressions-510"></a><a name="index-operators_002c-boolean-511"></a><a name="index-boolean-operators-512"></a><a name="index-logical-operators-513"></a><a name="index-operators_002c-logical-514"></a><a name="index-and-operator-515"></a><a name="index-or-operator-516"></a><a name="index-not-operator-517"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a>
+<li><a accesskey="2" href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">Short-circuit Boolean Operators</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Breakpoints.html b/doc/interpreter/HTML/Breakpoints.html
new file mode 100644
index 0000000..5daf929
--- /dev/null
+++ b/doc/interpreter/HTML/Breakpoints.html
@@ -0,0 +1,171 @@
+<html lang="en">
+<head>
+<title>Breakpoints - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Debugging.html#Debugging" title="Debugging">
+<link rel="prev" href="Leaving-Debug-Mode.html#Leaving-Debug-Mode" title="Leaving Debug Mode">
+<link rel="next" href="Debug-Mode.html#Debug-Mode" title="Debug Mode">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Breakpoints"></a>
+Next: <a rel="next" accesskey="n" href="Debug-Mode.html#Debug-Mode">Debug Mode</a>,
+Previous: <a rel="previous" accesskey="p" href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">Leaving Debug Mode</a>,
+Up: <a rel="up" accesskey="u" href="Debugging.html#Debugging">Debugging</a>
+<hr>
+</div>
+
+<h3 class="section">13.3 Breakpoints</h3>
+
+<p>Breakpoints can be set in any Octave function, using the <code>dbstop</code>
+function.
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbstop"></a>
+
+<div class="defun">
+— Loadable Function: <var>rline</var> = <b>dbstop</b> (<var>func, line, <small class="dots">...</small></var>)<var><a name="index-dbstop-693"></a></var><br>
+<blockquote><p>Set a breakpoint in a function
+          <dl>
+<dt><code>func</code><dd>String representing the function name.  When already in debug
+mode this should be left out and only the line should be given. 
+<br><dt><code>line</code><dd>Line number you would like the breakpoint to be set on.  Multiple
+lines might be given as separate arguments or as a vector. 
+</dl>
+
+        <p>The rline returned is the real line that the breakpoint was set at. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbclear.html#doc_002ddbclear">dbclear</a>, <a href="doc_002ddbstatus.html#doc_002ddbstatus">dbstatus</a>, <a href="doc_002ddbstep.html#doc_002ddbstep">dbstep</a>. 
+</p></blockquote></div>
+
+<p class="noindent">Note that breakpoints cannot be set in built-in functions
+(e.g., <code>sin</code>, etc.) or dynamically loaded function (i.e., oct-files).  To
+set a breakpoint immediately on entering a function, the breakpoint
+should be set to line 1. The leading comment block will be ignored and
+the breakpoint will be set to the first executable statement in the
+function.  For example
+
+<pre class="example">     dbstop ("asind", 1)
+      27
+</pre>
+   <p class="noindent">Note that the return value of <code>27</code> means that the breakpoint was
+effectively set to line 27.  The status of breakpoints in a function can
+be queried with the <code>dbstatus</code> function.
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbstatus"></a>
+
+<div class="defun">
+— Loadable Function: lst = <b>dbstatus</b> (<var>func</var>)<var><a name="index-dbstatus-694"></a></var><br>
+<blockquote><p>Return a vector containing the lines on which a function has
+breakpoints set.
+          <dl>
+<dt><code>func</code><dd>String representing the function name.  When already in debug
+mode this should be left out. 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbclear.html#doc_002ddbclear">dbclear</a>, <a href="doc_002ddbwhere.html#doc_002ddbwhere">dbwhere</a>. 
+</p></blockquote></div>
+
+<p class="noindent">Taking the above as an example, <code>dbstatus ("asind")</code> should return
+27.  The breakpoints can then be cleared with the <code>dbclear</code> function
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbclear"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dbclear</b> (<var>func, line, <small class="dots">...</small></var>)<var><a name="index-dbclear-695"></a></var><br>
+<blockquote><p>Delete a breakpoint in a function
+          <dl>
+<dt><code>func</code><dd>String representing the function name.  When already in debug
+mode this should be left out and only the line should be given. 
+<br><dt><code>line</code><dd>Line number where you would like to remove the breakpoint.  Multiple
+lines might be given as separate arguments or as a vector. 
+</dl>
+        No checking is done to make sure that the line you requested is really
+a breakpoint.  If you get the wrong line nothing will happen. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbstop.html#doc_002ddbstop">dbstop</a>, <a href="doc_002ddbstatus.html#doc_002ddbstatus">dbstatus</a>, <a href="doc_002ddbwhere.html#doc_002ddbwhere">dbwhere</a>. 
+</p></blockquote></div>
+
+<p class="noindent">These functions can be used to clear all the breakpoints in a function.  For example,
+
+<pre class="example">     dbclear ("asind", dbstatus ("asind"));
+</pre>
+   <p>A breakpoint can be set in a subfunction.  For example if a file contains
+the functions
+
+<pre class="example">     function y = func1 (x)
+       y = func2 (x);
+     endfunction
+     function y = func2 (x)
+       y = x + 1;
+     endfunction
+</pre>
+   <p class="noindent">then a breakpoint can be set at the start of the subfunction directly
+with
+
+<pre class="example">     dbstop (["func1", filemarker(), "func2"])
+      5
+</pre>
+   <p>Note that <code>filemarker</code> returns a character that marks the
+subfunctions from the file containing them.
+
+   <p>Another simple way of setting a breakpoint in an Octave script is the
+use of the <code>keyboard</code> function.
+
+<!-- input.cc -->
+   <p><a name="doc_002dkeyboard"></a>
+
+<div class="defun">
+— Built-in Function:  <b>keyboard</b> ()<var><a name="index-keyboard-696"></a></var><br>
+— Built-in Function:  <b>keyboard</b> (<var>prompt</var>)<var><a name="index-keyboard-697"></a></var><br>
+<blockquote><p>This function is normally used for simple debugging.  When the
+<code>keyboard</code> function is executed, Octave prints a prompt and waits
+for user input.  The input strings are then evaluated and the results
+are printed.  This makes it possible to examine the values of variables
+within a function, and to assign new values if necessary.  To leave the
+prompt and return to normal execution type ‘<samp><span class="samp">return</span></samp>’ or ‘<samp><span class="samp">dbcont</span></samp>’. 
+The <code>keyboard</code> function does not return an exit status.
+
+        <p>If <code>keyboard</code> is invoked without arguments, a default prompt of
+‘<samp><span class="samp">debug> </span></samp>’ is used. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbcont.html#doc_002ddbcont">dbcont</a>, <a href="doc_002ddbquit.html#doc_002ddbquit">dbquit</a>. 
+</p></blockquote></div>
+
+<p class="noindent">The <code>keyboard</code> function is typically placed in a script at the
+point where the user desires that the execution is stopped.  It
+automatically sets the running script into the debug mode.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Bug-Criteria.html b/doc/interpreter/HTML/Bug-Criteria.html
new file mode 100644
index 0000000..1e448df
--- /dev/null
+++ b/doc/interpreter/HTML/Bug-Criteria.html
@@ -0,0 +1,67 @@
+<html lang="en">
+<head>
+<title>Bug Criteria - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="prev" href="Reporting-Bugs.html#Reporting-Bugs" title="Reporting Bugs">
+<link rel="next" href="Bug-Lists.html#Bug-Lists" title="Bug Lists">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bug-Criteria"></a>
+Next: <a rel="next" accesskey="n" href="Bug-Lists.html#Bug-Lists">Bug Lists</a>,
+Previous: <a rel="previous" accesskey="p" href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.3 Have You Found a Bug?</h3>
+
+<p><a name="index-bug-criteria-2521"></a>
+If you are not sure whether you have found a bug, here are some guidelines:
+
+     
+<a name="index-fatal-signal-2522"></a>
+<a name="index-core-dump-2523"></a>
+<ul><li>If Octave gets a fatal signal, for any input whatever, that is
+a bug.  Reliable interpreters never crash.
+
+     <p><a name="index-incorrect-output-2524"></a><a name="index-incorrect-results-2525"></a><a name="index-results_002c-incorrect-2526"></a><a name="index-answers_002c-incorrect-2527"></a><a name="index-erroneous-results-2528"></a><a name="index-wrong-answers-2529"></a><li>If Octave produces incorrect results, for any input whatever,
+that is a bug.
+
+     <p><a name="index-undefined-behavior-2530"></a><a name="index-undefined-function-value-2531"></a><li>Some output may appear to be incorrect when it is in fact due to a
+program whose behavior is undefined, which happened by chance to give
+the desired results on another system.  For example, the range operator
+may produce different results because of differences in the way floating
+point arithmetic is handled on various systems.
+
+     <p><a name="index-erroneous-messages-2532"></a><a name="index-incorrect-error-messages-2533"></a><a name="index-error-messages_002c-incorrect-2534"></a><li>If Octave produces an error message for valid input, that is a bug.
+
+     <p><a name="index-invalid-input-2535"></a><li>If Octave does not produce an error message for invalid input, that is
+a bug.  However, you should note that your idea of “invalid input”
+might be my idea of “an extension” or “support for traditional
+practice”.
+
+     <p><a name="index-improving-Octave-2536"></a><a name="index-suggestions-2537"></a><li>If you are an experienced user of programs like Octave, your suggestions
+for improvement are welcome in any case. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Bug-Lists.html b/doc/interpreter/HTML/Bug-Lists.html
new file mode 100644
index 0000000..b7c529d
--- /dev/null
+++ b/doc/interpreter/HTML/Bug-Lists.html
@@ -0,0 +1,54 @@
+<html lang="en">
+<head>
+<title>Bug Lists - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="prev" href="Bug-Criteria.html#Bug-Criteria" title="Bug Criteria">
+<link rel="next" href="Bug-Reporting.html#Bug-Reporting" title="Bug Reporting">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bug-Lists"></a>
+Next: <a rel="next" accesskey="n" href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a>,
+Previous: <a rel="previous" accesskey="p" href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.4 Where to Report Bugs</h3>
+
+<p><a name="index-bug-report-mailing-lists-2538"></a><a name="index-reporting-bugs-2539"></a><a name="index-bugs_002c-reporting-2540"></a>
+<a name="index-bug_005freport-2541"></a>
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function <code>bug_report</code>.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+   <p>If for some reason you cannot use Octave's <code>bug_report</code> function,
+send bug reports for Octave to <a href="mailto:bug at octave.org">bug at octave.org</a>.
+
+   <p><strong>Do not send bug reports to ‘</strong><samp><span class="samp">help-octave</span></samp><strong>’</strong>.  Most users of
+Octave do not want to receive bug reports.  Those that do have asked to
+be on the mailing list.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Bug-Reporting.html b/doc/interpreter/HTML/Bug-Reporting.html
new file mode 100644
index 0000000..27bbb5b
--- /dev/null
+++ b/doc/interpreter/HTML/Bug-Reporting.html
@@ -0,0 +1,155 @@
+<html lang="en">
+<head>
+<title>Bug Reporting - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="prev" href="Bug-Lists.html#Bug-Lists" title="Bug Lists">
+<link rel="next" href="Sending-Patches.html#Sending-Patches" title="Sending Patches">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bug-Reporting"></a>
+Next: <a rel="next" accesskey="n" href="Sending-Patches.html#Sending-Patches">Sending Patches</a>,
+Previous: <a rel="previous" accesskey="p" href="Bug-Lists.html#Bug-Lists">Bug Lists</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.5 How to Report Bugs</h3>
+
+<p><a name="index-bugs_002c-reporting-2542"></a>
+Send bug reports for Octave to one of the addresses listed in
+<a href="Bug-Lists.html#Bug-Lists">Bug Lists</a>.
+
+   <p>The fundamental principle of reporting bugs usefully is this:
+<strong>report all the facts</strong>.  If you are not sure whether to state a
+fact or leave it out, state it!
+
+   <p>Often people omit facts because they think they know what causes the
+problem and they conclude that some details don't matter.  Thus, you might
+assume that the name of the variable you use in an example does not matter. 
+Well, probably it doesn't, but one cannot be sure.  Perhaps the bug is a
+stray memory reference which happens to fetch from the location where that
+name is stored in memory; perhaps, if the name were different, the contents
+of that location would fool the interpreter into doing the right thing
+despite the bug.  Play it safe and give a specific, complete example.
+
+   <p>Keep in mind that the purpose of a bug report is to enable someone to
+fix the bug if it is not known.  Always write your bug reports on
+the assumption that the bug is not known.
+
+   <p>Sometimes people give a few sketchy facts and ask, “Does this ring a
+bell?”  This cannot help us fix a bug.  It is better to send a complete
+bug report to begin with.
+
+   <p>Try to make your bug report self-contained.  If we have to ask you for
+more information, it is best if you include all the previous information
+in your response, as well as the information that was missing.
+
+   <p>To enable someone to investigate the bug, you should include all these
+things:
+
+     <ul>
+<li>The version of Octave.  You can get this by noting the version number
+that is printed when Octave starts, or running it with the ‘<samp><span class="samp">-v</span></samp>’
+option.
+
+     <li>A complete input file that will reproduce the bug.
+
+     <p>A single statement may not be enough of an example—the bug might
+depend on other details that are missing from the single statement where
+the error finally occurs.
+
+     <li>The command arguments you gave Octave to execute that example
+and observe the bug.  To guarantee you won't omit something important,
+list all the options.
+
+     <p>If we were to try to guess the arguments, we would probably guess wrong
+and then we would not encounter the bug.
+
+     <li>The type of machine you are using, and the operating system name and
+version number.
+
+     <li>The command-line arguments you gave to the <code>configure</code> command when
+you installed the interpreter.
+
+     <li>A complete list of any modifications you have made to the interpreter
+source.
+
+     <p>Be precise about these changes—show a context diff for them.
+
+     <li>Details of any other deviations from the standard procedure for installing
+Octave.
+
+     <p><a name="index-incorrect-output-2543"></a><a name="index-incorrect-results-2544"></a><a name="index-results_002c-incorrect-2545"></a><a name="index-answers_002c-incorrect-2546"></a><a name="index-erroneous-results-2547"></a><a name="index-wrong-answers-2548"></a><li>A description of what behavior you observe that you believe is
+incorrect.  For example, "The interpreter gets a fatal signal," or, "The
+output produced at line 208 is incorrect."
+
+     <p>Of course, if the bug is that the interpreter gets a fatal signal, then
+one can't miss it.  But if the bug is incorrect output, we might not
+notice unless it is glaringly wrong.
+
+     <p>Even if the problem you experience is a fatal signal, you should still
+say so explicitly.  Suppose something strange is going on, such as, your
+copy of the interpreter is out of synch, or you have encountered a bug
+in the C library on your system.  Your copy might crash and the copy
+here would not.  If you said to expect a crash, then when the
+interpreter here fails to crash, we would know that the bug was not
+happening.  If you don't say to expect a crash, then we would not know
+whether the bug was happening.  We would not be able to draw any
+conclusion from our observations.
+
+     <p>Often the observed symptom is incorrect output when your program is run. 
+Unfortunately, this is not enough information unless the program is
+short and simple.  It is very helpful if you can include an explanation
+of the expected output, and why the actual output is incorrect.
+
+     <li>If you wish to suggest changes to the Octave source, send them as
+context diffs.  If you even discuss something in the Octave source,
+refer to it by context, not by line number, because the line numbers in
+the development sources probably won't match those in your sources. 
+</ul>
+
+   <p>Here are some things that are not necessary:
+
+     
+<a name="index-bugs_002c-investigating-2549"></a>
+<ul><li>A description of the envelope of the bug.
+
+     <p>Often people who encounter a bug spend a lot of time investigating which
+changes to the input file will make the bug go away and which changes
+will not affect it.  Such information is usually not necessary to enable
+us to fix bugs in Octave, but if you can find a simpler example to
+report <em>instead</em> of the original one, that is a convenience. 
+Errors in the output will be easier to spot, running under the debugger
+will take less time, etc.  Most Octave bugs involve just one function, so
+the most straightforward way to simplify an example is to delete all the
+function definitions except the one in which the bug occurs.
+
+     <p>However, simplification is not vital; if you don't want to do
+this, report the bug anyway and send the entire test case you
+used.
+
+     <li>A patch for the bug.  Patches can be helpful, but if you find a bug, you
+should report it, even if you cannot send a fix for the problem. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Built_002din-Data-Types.html b/doc/interpreter/HTML/Built_002din-Data-Types.html
new file mode 100644
index 0000000..a7be923
--- /dev/null
+++ b/doc/interpreter/HTML/Built_002din-Data-Types.html
@@ -0,0 +1,129 @@
+<html lang="en">
+<head>
+<title>Built-in Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Types.html#Data-Types" title="Data Types">
+<link rel="next" href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types" title="User-defined Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Built-in-Data-Types"></a>
+<a name="Built_002din-Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a>,
+Up: <a rel="up" accesskey="u" href="Data-Types.html#Data-Types">Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">3.1 Built-in Data Types</h3>
+
+<p><a name="index-data-types_002c-built_002din-173"></a><a name="index-built_002din-data-types-174"></a>
+The standard built-in data types are real and complex scalars and
+matrices, ranges, character strings, a data structure type, and cell
+arrays.  Additional built-in data types may be added in future versions. 
+If you need a specialized data type that is not currently provided as a
+built-in type, you are encouraged to write your own user-defined data
+type and contribute it for distribution in a future release of Octave.
+
+   <p>The data type of a variable can be determined and changed through the
+use of the following functions.
+
+<!-- ov-class.cc -->
+   <p><a name="doc_002dclass"></a>
+
+<div class="defun">
+— Built-in Function:  <b>class</b> (<var>expr</var>)<var><a name="index-class-175"></a></var><br>
+— Built-in Function:  <b>class</b> (<var>s, id</var>)<var><a name="index-class-176"></a></var><br>
+— Built-in Function:  <b>class</b> (<var>s, id, p, <small class="dots">...</small></var>)<var><a name="index-class-177"></a></var><br>
+<blockquote><p>Return the class of the expression <var>expr</var> or create a class with
+fields from structure <var>s</var> and name (string) <var>id</var>.  Additional
+arguments name a list of parent classes from which the new class is
+derived. 
+</p></blockquote></div>
+
+<!-- ./general/isa.m -->
+   <p><a name="doc_002disa"></a>
+
+<div class="defun">
+— Function File:  <b>isa</b> (<var>x, class</var>)<var><a name="index-isa-178"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a value from the class <var>class</var>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/cast.m -->
+   <p><a name="doc_002dcast"></a>
+
+<div class="defun">
+— Function File:  <b>cast</b> (<var>val, type</var>)<var><a name="index-cast-179"></a></var><br>
+<blockquote><p>Convert <var>val</var> to data type <var>type</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dint8.html#doc_002dint8">int8</a>, <a href="doc_002duint8.html#doc_002duint8">uint8</a>, <a href="doc_002dint16.html#doc_002dint16">int16</a>, <a href="doc_002duint16.html#doc_002duint16">uint16</a>, <a href="doc_002dint32.html#doc_002dint32">int32</a>, <a href="doc_002duint32.html#doc_002duint32">uint32</a>, <a href="doc_002dint64.html#doc_002dint64">int64</a>, <a href="doc_002duint64.html#doc_002duint64">uint64</a>, <a href="doc_002ddouble.html#doc_002ddouble">double</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/typecast.cc -->
+   <p><a name="doc_002dtypecast"></a>
+
+<div class="defun">
+— Loadable Function:  <b>typecast</b> (<var>x, type</var>)<var><a name="index-typecast-180"></a></var><br>
+<blockquote><p>Convert from one datatype to another without changing the underlying
+data.  The argument <var>type</var> defines the type of the return argument
+and must be one of 'uint8', 'uint16', 'uint32', 'uint64', 'int8', 'int16',
+'int32', 'int64', 'single' or 'double'.
+
+        <p>An example of the use of typecast on a little-endian machine is
+
+     <pre class="example">          <var>x</var> = uint16 ([1, 65535]);
+          typecast (<var>x</var>, 'uint8')
+           [   0,   1, 255, 255]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcast.html#doc_002dcast">cast</a>, <a href="doc_002dswapbytes.html#doc_002dswapbytes">swapbytes</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/swapbytes.m -->
+   <p><a name="doc_002dswapbytes"></a>
+
+<div class="defun">
+— Function File:  <b>swapbytes</b> (<var>x</var>)<var><a name="index-swapbytes-181"></a></var><br>
+<blockquote><p>Swaps the byte order on values, converting from little endian to big
+endian and vice versa.  For example
+
+     <pre class="example">          swapbytes (uint16 (1:4))
+           [   256   512   768  1024]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtypecast.html#doc_002dtypecast">typecast</a>, <a href="doc_002dcast.html#doc_002dcast">cast</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Numeric-Objects.html#Numeric-Objects">Numeric Objects</a>
+<li><a accesskey="2" href="Missing-Data.html#Missing-Data">Missing Data</a>
+<li><a accesskey="3" href="String-Objects.html#String-Objects">String Objects</a>
+<li><a accesskey="4" href="Data-Structure-Objects.html#Data-Structure-Objects">Data Structure Objects</a>
+<li><a accesskey="5" href="Cell-Array-Objects.html#Cell-Array-Objects">Cell Array Objects</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/C_002b_002b-Sources.html b/doc/interpreter/HTML/C_002b_002b-Sources.html
new file mode 100644
index 0000000..0b96697
--- /dev/null
+++ b/doc/interpreter/HTML/C_002b_002b-Sources.html
@@ -0,0 +1,102 @@
+<html lang="en">
+<head>
+<title>C++ Sources - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link rel="prev" href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029" title="Octave Sources (m-files)">
+<link rel="next" href="Other-Sources.html#Other-Sources" title="Other Sources">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="C++-Sources"></a>
+<a name="C_002b_002b-Sources"></a>
+Next: <a rel="next" accesskey="n" href="Other-Sources.html#Other-Sources">Other Sources</a>,
+Previous: <a rel="previous" accesskey="p" href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029">Octave Sources (m-files)</a>,
+Up: <a rel="up" accesskey="u" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>
+<hr>
+</div>
+
+<h3 class="section">D.4 C++ Sources</h3>
+
+<p>Don't use tabs.  Tabs cause trouble.  If you are used to them, set up your editor
+so that it converts tabs to spaces.  Format function headers like this:
+
+<pre class="example">     static bool
+     matches_patterns (const string_vector& patterns, int pat_idx,
+     		  int num_pat, const std::string& name)
+</pre>
+   <p class="noindent">The function name should start in column 1, and multi-line argument lists should
+be aligned on the first char after the open parenthesis.  You should put a space
+after the left open parenthesis and after commas, for both function definitions
+and function calls.
+
+   <p>Recommended indent is 2 spaces.  When indenting, indent the statement after
+control structures (like <code>if</code>, <code>while</code>, etc.). If there is a compound
+statement, indent <i>both</i> the curly braces and the body of the statement (so
+that the body gets indented by <i>two</i> indents).  Example:
+
+<pre class="example">     if (have_args)
+       {
+         idx.push_back (first_args);
+         have_args = false;
+       }
+     else
+       idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
+</pre>
+   <p class="noindent">If you have nested <code>if</code> statements, use extra braces for extra
+clarification.
+
+   <p>Split long expressions in such a way that a continuation line starts with an
+operator rather than identifier.  If the split occurs inside braces, continuation
+should be aligned with the first char after the innermost braces enclosing the
+split.  Example:
+
+<pre class="example">     SVD::type type = ((nargout == 0 || nargout == 1)
+                       ? SVD::sigma_only
+                       : (nargin == 2) ? SVD::economy : SVD::std);
+</pre>
+   <p class="noindent">Consider putting extra braces around a multiline expression to make it more
+readable, even if they are not necessary.  Also, do not hesitate to put extra
+braces anywhere if it improves clarity.
+
+   <p>Try declaring variables just before they're needed.  Use local variables of
+blocks - it helps optimization.  Don't write multi-line variable declaration
+with a single type specification and multiple variables.  If the variables don't
+fit on single line, repeat the type specification.  Example:
+
+<pre class="example">     octave_value retval;
+     
+     octave_idx_type nr = b.rows ();
+     octave_idx_type nc = b.cols ();
+     
+     double d1, d2;
+</pre>
+   <p>Use lowercase names if possible.  Uppercase is acceptable for variable names
+consisting of 1-2 letters.  Do not use mixed case names.
+
+   <p>Try to use Octave's types and classes if possible.  Otherwise, try to use C++
+standard library.  Use of STL containers and algorithms is encouraged.  Use
+templates wisely to reduce code duplication.  Avoid comma expressions, labels
+and gotos, and explicit typecasts.  If you need to typecast, use the modern C++
+casting operators.  In functions, try to reduce the number of <code>return</code>
+statements - use nested <code>if</code> statements if possible.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/C_002dStyle-I_002fO-Functions.html b/doc/interpreter/HTML/C_002dStyle-I_002fO-Functions.html
new file mode 100644
index 0000000..ab40dad
--- /dev/null
+++ b/doc/interpreter/HTML/C_002dStyle-I_002fO-Functions.html
@@ -0,0 +1,116 @@
+<html lang="en">
+<head>
+<title>C-Style I/O Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Input-and-Output.html#Input-and-Output" title="Input and Output">
+<link rel="prev" href="Basic-Input-and-Output.html#Basic-Input-and-Output" title="Basic Input and Output">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="C-Style-I%2fO-Functions"></a>
+<a name="C_002dStyle-I_002fO-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>,
+Up: <a rel="up" accesskey="u" href="Input-and-Output.html#Input-and-Output">Input and Output</a>
+<hr>
+</div>
+
+<h3 class="section">14.2 C-Style I/O Functions</h3>
+
+<p>Octave's C-style input and output functions provide most of the
+functionality of the C programming language's standard I/O library.  The
+argument lists for some of the input functions are slightly different,
+however, because Octave has no way of passing arguments by reference.
+
+   <p>In the following, <var>file</var> refers to a file name and <code>fid</code> refers
+to an integer file number, as returned by <code>fopen</code>.
+
+   <p>There are three files that are always available.  Although these files
+can be accessed using their corresponding numeric file ids, you should
+always use the symbolic names given in the table below, since it will
+make your programs easier to understand.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dstdin"></a>
+
+<div class="defun">
+— Built-in Function:  <b>stdin</b> ()<var><a name="index-stdin-770"></a></var><br>
+<blockquote><p>Return the numeric value corresponding to the standard input stream. 
+When Octave is used interactively, this is filtered through the command
+line editing functions. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstdout.html#doc_002dstdout">stdout</a>, <a href="doc_002dstderr.html#doc_002dstderr">stderr</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dstdout"></a>
+
+<div class="defun">
+— Built-in Function:  <b>stdout</b> ()<var><a name="index-stdout-771"></a></var><br>
+<blockquote><p>Return the numeric value corresponding to the standard output stream. 
+Data written to the standard output is normally filtered through the pager. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstdin.html#doc_002dstdin">stdin</a>, <a href="doc_002dstderr.html#doc_002dstderr">stderr</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dstderr"></a>
+
+<div class="defun">
+— Built-in Function:  <b>stderr</b> ()<var><a name="index-stderr-772"></a></var><br>
+<blockquote><p>Return the numeric value corresponding to the standard error stream. 
+Even if paging is turned on, the standard error is not sent to the
+pager.  It is useful for error messages and prompts. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstdin.html#doc_002dstdin">stdin</a>, <a href="doc_002dstdout.html#doc_002dstdout">stdout</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">Opening and Closing Files</a>
+<li><a accesskey="2" href="Simple-Output.html#Simple-Output">Simple Output</a>
+<li><a accesskey="3" href="Line_002dOriented-Input.html#Line_002dOriented-Input">Line-Oriented Input</a>
+<li><a accesskey="4" href="Formatted-Output.html#Formatted-Output">Formatted Output</a>
+<li><a accesskey="5" href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices">Output Conversion for Matrices</a>
+<li><a accesskey="6" href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a>
+<li><a accesskey="7" href="Table-of-Output-Conversions.html#Table-of-Output-Conversions">Table of Output Conversions</a>
+<li><a accesskey="8" href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>
+<li><a accesskey="9" href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>
+<li><a href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>
+<li><a href="Formatted-Input.html#Formatted-Input">Formatted Input</a>
+<li><a href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">Input Conversion Syntax</a>
+<li><a href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">Table of Input Conversions</a>
+<li><a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>
+<li><a href="String-Input-Conversions.html#String-Input-Conversions">String Input Conversions</a>
+<li><a href="Binary-I_002fO.html#Binary-I_002fO">Binary I/O</a>
+<li><a href="Temporary-Files.html#Temporary-Files">Temporary Files</a>
+<li><a href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a>
+<li><a href="File-Positioning.html#File-Positioning">File Positioning</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Call-Stack.html b/doc/interpreter/HTML/Call-Stack.html
new file mode 100644
index 0000000..edf8fdf
--- /dev/null
+++ b/doc/interpreter/HTML/Call-Stack.html
@@ -0,0 +1,92 @@
+<html lang="en">
+<head>
+<title>Call Stack - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Debugging.html#Debugging" title="Debugging">
+<link rel="prev" href="Debug-Mode.html#Debug-Mode" title="Debug Mode">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Call-Stack"></a>
+Previous: <a rel="previous" accesskey="p" href="Debug-Mode.html#Debug-Mode">Debug Mode</a>,
+Up: <a rel="up" accesskey="u" href="Debugging.html#Debugging">Debugging</a>
+<hr>
+</div>
+
+<h3 class="section">13.5 Call Stack</h3>
+
+<!-- debug.cc -->
+<p><a name="doc_002ddbstack"></a>
+
+<div class="defun">
+— Loadable Function: [<var>stack</var>, <var>idx</var>] <b>dbstack</b> (<var>n</var>)<var><a name="index-dbstack-704"></a></var><br>
+<blockquote><p>Print or return current stack information.  With optional argument
+<var>n</var>, omit the <var>n</var> innermost stack frames. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbclear.html#doc_002ddbclear">dbclear</a>, <a href="doc_002ddbstatus.html#doc_002ddbstatus">dbstatus</a>, <a href="doc_002ddbstop.html#doc_002ddbstop">dbstop</a>. 
+</p></blockquote></div>
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbup"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dbup</b> (<var>n</var>)<var><a name="index-dbup-705"></a></var><br>
+<blockquote><p>In debugging mode, move up the execution stack <var>n</var> frames. 
+If <var>n</var> is omitted, move up one frame. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbstack.html#doc_002ddbstack">dbstack</a>. 
+</p></blockquote></div>
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbdown"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dbdown</b> (<var>n</var>)<var><a name="index-dbdown-706"></a></var><br>
+<blockquote><p>In debugging mode, move down the execution stack <var>n</var> frames. 
+If <var>n</var> is omitted, move down one frame. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbstack.html#doc_002ddbstack">dbstack</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Call-by-Value.html b/doc/interpreter/HTML/Call-by-Value.html
new file mode 100644
index 0000000..fba8b5c
--- /dev/null
+++ b/doc/interpreter/HTML/Call-by-Value.html
@@ -0,0 +1,82 @@
+<html lang="en">
+<head>
+<title>Call by Value - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Calling-Functions.html#Calling-Functions" title="Calling Functions">
+<link rel="next" href="Recursion.html#Recursion" title="Recursion">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Call-by-Value"></a>
+Next: <a rel="next" accesskey="n" href="Recursion.html#Recursion">Recursion</a>,
+Up: <a rel="up" accesskey="u" href="Calling-Functions.html#Calling-Functions">Calling Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">8.2.1 Call by Value</h4>
+
+<p>In Octave, unlike Fortran, function arguments are passed by value, which
+means that each argument in a function call is evaluated and assigned to
+a temporary location in memory before being passed to the function. 
+There is currently no way to specify that a function parameter should be
+passed by reference instead of by value.  This means that it is
+impossible to directly alter the value of a function parameter in the
+calling function.  It can only change the local copy within the function
+body.  For example, the function
+
+<pre class="example">     function f (x, n)
+       while (n-- > 0)
+         disp (x);
+       endwhile
+     endfunction
+</pre>
+   <p class="noindent">displays the value of the first argument <var>n</var> times.  In this
+function, the variable <var>n</var> is used as a temporary variable without
+having to worry that its value might also change in the calling
+function.  Call by value is also useful because it is always possible to
+pass constants for any function parameter without first having to
+determine that the function will not attempt to modify the parameter.
+
+   <p>The caller may use a variable as the expression for the argument, but
+the called function does not know this: it only knows what value the
+argument had.  For example, given a function called as
+
+<pre class="example">     foo = "bar";
+     fcn (foo)
+</pre>
+   <p class="noindent">you should not think of the argument as being “the variable
+<code>foo</code>.”  Instead, think of the argument as the string value,
+<code>"bar"</code>.
+
+   <p>Even though Octave uses pass-by-value semantics for function arguments,
+values are not copied unnecessarily.  For example,
+
+<pre class="example">     x = rand (1000);
+     f (x);
+</pre>
+   <p class="noindent">does not actually force two 1000 by 1000 element matrices to exist
+<em>unless</em> the function <code>f</code> modifies the value of its
+argument.  Then Octave must create a copy to avoid changing the
+value outside the scope of the function <code>f</code>, or attempting (and
+probably failing!) to modify the value of a constant or the value of a
+temporary result.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Callbacks.html b/doc/interpreter/HTML/Callbacks.html
new file mode 100644
index 0000000..370056b
--- /dev/null
+++ b/doc/interpreter/HTML/Callbacks.html
@@ -0,0 +1,130 @@
+<html lang="en">
+<head>
+<title>Callbacks - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Marker-Styles.html#Marker-Styles" title="Marker Styles">
+<link rel="next" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Callbacks"></a>
+Next: <a rel="next" accesskey="n" href="Object-Groups.html#Object-Groups">Object Groups</a>,
+Previous: <a rel="previous" accesskey="p" href="Marker-Styles.html#Marker-Styles">Marker Styles</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.7 Callbacks</h4>
+
+<p><a name="index-callbacks-1216"></a>
+Callback functions can be associated with graphics objects and triggered
+after certain events occur.  The basic structure of all callback function
+is
+
+<pre class="example">     function mycallback (src, data)
+     ...
+     endfunction
+</pre>
+   <p>where <code>src</code> gives a handle to the source of the callback, and
+<code>code</code> gives some event specific data.  This can then be associated
+with an object either at the objects creation or later with the
+<code>set</code> function.  For example
+
+<pre class="example">     plot (x, "DeleteFcn", @(s, e) disp("Window Deleted"))
+</pre>
+   <p class="noindent">where at the moment that the plot is deleted, the message "Window
+Deleted" will be displayed.
+
+   <p>Additional user arguments can be passed to callback functions, and will
+be passed after the 2 default arguments.  For example
+
+<pre class="example">     plot (x, "DeleteFcn", {@mycallback, "1"})
+     ...
+     function mycallback (src, data, a1)
+       fprintf ("Closing plot %d\n", a1);
+     endfunction
+</pre>
+   <p>The basic callback functions that are available for all graphics objects
+are
+
+     <ul>
+<li>CreateFcn
+This is the callback that is called at the moment of the objects
+creation.  It is not called if the object is altered in any way, and so
+it only makes sense to define this callback in the function call that
+defines the object.  Callbacks that are added to <code>CreateFcn</code> later with
+the <code>set</code> function will never be executed.
+
+     <li>DeleteFcn
+This is the callback that is called at the moment an object is deleted.
+
+     <li>ButtonDownFcn
+This is the callback that is called if a mouse button is pressed while
+the pointer is over this object.  Note, that the gnuplot interface does
+not respect this callback. 
+</ul>
+
+   <p>The object and figure that the event occurred in that resulted in the
+callback being called can be found with the <code>gcbo</code> and <code>gcbf</code>
+functions.
+
+<!-- ./plot/gcbo.m -->
+   <p><a name="doc_002dgcbo"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>gcbo</b> ()<var><a name="index-gcbo-1217"></a></var><br>
+— Function File: [<var>h</var>, <var>fig</var>] = <b>gcbo</b> ()<var><a name="index-gcbo-1218"></a></var><br>
+<blockquote><p>Return a handle to the object whose callback is currently
+executing.  If no callback is executing, this function returns the
+empty matrix.  This handle is obtained from the root object property
+"CallbackObject".
+
+        <p>Additionally return the handle of the figure containing the
+object whose callback is currently executing.  If no callback is
+executing, the second output is also set to the empty matrix.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgcf.html#doc_002dgcf">gcf</a>, <a href="doc_002dgca.html#doc_002dgca">gca</a>, <a href="doc_002dgcbf.html#doc_002dgcbf">gcbf</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/gcbf.m -->
+   <p><a name="doc_002dgcbf"></a>
+
+<div class="defun">
+— Function File: <var>fig</var> = <b>gcbf</b> ()<var><a name="index-gcbf-1219"></a></var><br>
+<blockquote><p>Return a handle to the figure containing the object whose callback
+is currently executing.  If no callback is executing, this function
+returns the empty matrix.  The handle returned by this function is
+the same as the second output argument of gcbo.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgcf.html#doc_002dgcf">gcf</a>, <a href="doc_002dgca.html#doc_002dgca">gca</a>, <a href="doc_002dgcbo.html#doc_002dgcbo">gcbo</a>. 
+</p></blockquote></div>
+
+   <p>Callbacks can equally be added to properties with the <code>addlistener</code>
+function described below.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Calling-External-Code-from-Oct_002dFiles.html b/doc/interpreter/HTML/Calling-External-Code-from-Oct_002dFiles.html
new file mode 100644
index 0000000..749aa04
--- /dev/null
+++ b/doc/interpreter/HTML/Calling-External-Code-from-Oct_002dFiles.html
@@ -0,0 +1,156 @@
+<html lang="en">
+<head>
+<title>Calling External Code from Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles" title="Calling Octave Functions from Oct-Files">
+<link rel="next" href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles" title="Allocating Local Memory in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Calling-External-Code-from-Oct-Files"></a>
+<a name="Calling-External-Code-from-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles">Allocating Local Memory in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles">Calling Octave Functions from Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.9 Calling External Code from Oct-Files</h4>
+
+<p>Linking external C code to Octave is relatively simple, as the C
+functions can easily be called directly from C++.  One possible issue is
+the declarations of the external C functions might need to be explicitly
+defined as C functions to the compiler.  If the declarations of the
+external C functions are in the header <code>foo.h</code>, then the manner in
+which to ensure that the C++ compiler treats these declarations as C
+code is
+
+<pre class="example">     #ifdef __cplusplus
+     extern "C"
+     {
+     #endif
+     #include "foo.h"
+     #ifdef __cplusplus
+     }  /* end extern "C" */
+     #endif
+</pre>
+   <p>Calling Fortran code however can pose some difficulties.  This is due to
+differences in the manner in compilers treat the linking of Fortran code
+with C or C++ code.  Octave supplies a number of macros that allow
+consistent behavior across a number of compilers.
+
+   <p>The underlying Fortran code should use the <code>XSTOPX</code> function to
+replace the Fortran <code>STOP</code> function.  <code>XSTOPX</code> uses the Octave
+exception handler to treat failing cases in the fortran code
+explicitly.  Note that Octave supplies its own replacement <span class="sc">blas</span>
+<code>XERBLA</code> function, which uses <code>XSTOPX</code>.
+
+   <p>If the underlying code calls <code>XSTOPX</code>, then the <code>F77_XFCN</code><!-- /@w -->
+macro should be used to call the underlying fortran function.  The Fortran
+exception state can then be checked with the global variable
+<code>f77_exception_encountered</code>.  If <code>XSTOPX</code> will not be called,
+then the <code>F77_FCN</code><!-- /@w --> macro should be used instead to call the Fortran
+code.
+
+   <p>There is no harm in using <code>F77_XFCN</code><!-- /@w --> in all cases, except that for
+Fortran code that is short running and executes a large number of times,
+there is potentially an overhead in doing so.  However, if <code>F77_FCN</code><!-- /@w -->
+is used with code that calls <code>XSTOP</code>, Octave can generate a
+segmentation fault.
+
+   <p>An example of the inclusion of a Fortran function in an oct-file is
+given in the following example, where the C++ wrapper is
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     #include <octave/f77-fcn.h>
+     
+     extern "C" 
+     {
+       F77_RET_T 
+       F77_FUNC (fortsub, FORTSUB) 
+             (const int&, double*, F77_CHAR_ARG_DECL  
+              F77_CHAR_ARG_LEN_DECL);
+     }
+     
+     DEFUN_DLD (fortdemo , args , , "Fortran Demo.")
+     {
+       octave_value_list retval;  
+       int nargin = args.length();
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           NDArray a = args(0).array_value ();
+           if (! error_state)
+             {
+               double *av = a.fortran_vec ();
+               octave_idx_type na = a.nelem ();
+               OCTAVE_LOCAL_BUFFER (char, ctmp, 128);
+     
+               F77_XFCN (fortsub, FORTSUB, (na, av, ctmp 
+                         F77_CHAR_ARG_LEN (128)));
+     
+     	  retval(1) = std::string (ctmp);
+     	  retval(0) = a;
+             }
+         }
+       return retval;
+     }
+</pre></pre>
+   <p class="noindent">and the fortran function is
+
+<pre class="example"><pre class="verbatim">           subroutine fortsub (n, a, s)
+           implicit none
+           character*(*) s
+           real*8 a(*)
+           integer*4 i, n, ioerr
+           do i = 1, n
+             if (a(i) .eq. 0d0) then
+               call xstopx ('fortsub: divide by zero')
+             else
+               a(i) = 1d0 / a(i)
+             endif
+           enddo
+           write (unit = s, fmt = '(a,i3,a,a)', iostat = ioerr)
+          $       'There are ', n,
+          $       ' values in the input vector', char(0)
+           if (ioerr .ne. 0) then
+             call xstopx ('fortsub: error writing string')
+           endif
+           return
+           end
+     
+</pre></pre>
+   <p>This example demonstrates most of the features needed to link to an
+external Fortran function, including passing arrays and strings, as well
+as exception handling.  An example of the behavior of this function is
+
+<pre class="example">     [b, s] = fortdemo (1:3)
+     
+       b = 1.00000   0.50000   0.33333
+       s = There are   3 values in the input vector
+     [b, s] = fortdemo(0:3)
+     error: fortsub:divide by zero
+     error: exception encountered in Fortran subroutine fortsub_
+     error: fortdemo: error in fortran
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Calling-Functions.html b/doc/interpreter/HTML/Calling-Functions.html
new file mode 100644
index 0000000..ed627ff
--- /dev/null
+++ b/doc/interpreter/HTML/Calling-Functions.html
@@ -0,0 +1,93 @@
+<html lang="en">
+<head>
+<title>Calling Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Index-Expressions.html#Index-Expressions" title="Index Expressions">
+<link rel="next" href="Arithmetic-Ops.html#Arithmetic-Ops" title="Arithmetic Ops">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Calling-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a>,
+Previous: <a rel="previous" accesskey="p" href="Index-Expressions.html#Index-Expressions">Index Expressions</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.2 Calling Functions</h3>
+
+<p>A <dfn>function</dfn> is a name for a particular calculation.  Because it has
+a name, you can ask for it by name at any point in the program.  For
+example, the function <code>sqrt</code> computes the square root of a number.
+
+   <p>A fixed set of functions are <dfn>built-in</dfn>, which means they are
+available in every Octave program.  The <code>sqrt</code> function is one of
+these.  In addition, you can define your own functions. 
+See <a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>, for information about how to do this.
+
+   <p><a name="index-arguments-in-function-call-453"></a>The way to use a function is with a <dfn>function call</dfn> expression,
+which consists of the function name followed by a list of
+<dfn>arguments</dfn> in parentheses.  The arguments are expressions which give
+the raw materials for the calculation that the function will do.  When
+there is more than one argument, they are separated by commas.  If there
+are no arguments, you can omit the parentheses, but it is a good idea to
+include them anyway, to clearly indicate that a function call was
+intended.  Here are some examples:
+
+<pre class="example">     sqrt (x^2 + y^2)      # <span class="roman">One argument</span>
+     ones (n, m)           # <span class="roman">Two arguments</span>
+     rand ()               # <span class="roman">No arguments</span>
+</pre>
+   <p>Each function expects a particular number of arguments.  For example, the
+<code>sqrt</code> function must be called with a single argument, the number
+to take the square root of:
+
+<pre class="example">     sqrt (<var>argument</var>)
+</pre>
+   <p>Some of the built-in functions take a variable number of arguments,
+depending on the particular usage, and their behavior is different
+depending on the number of arguments supplied.
+
+   <p>Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it.  In this
+example, the value of <code>sqrt (</code><var>argument</var><code>)</code> is the square root of
+the argument.  A function can also have side effects, such as assigning
+the values of certain variables or doing input or output operations.
+
+   <p>Unlike most languages, functions in Octave may return multiple values. 
+For example, the following statement
+
+<pre class="example">     [u, s, v] = svd (a)
+</pre>
+   <p class="noindent">computes the singular value decomposition of the matrix <code>a</code> and
+assigns the three result matrices to <code>u</code>, <code>s</code>, and <code>v</code>.
+
+   <p>The left side of a multiple assignment expression is itself a list of
+expressions, and is allowed to be a list of variable names or index
+expressions.  See also <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a>, and <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a>.
+
+<ul class="menu">
+<li><a accesskey="1" href="Call-by-Value.html#Call-by-Value">Call by Value</a>
+<li><a accesskey="2" href="Recursion.html#Recursion">Recursion</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Calling-Octave-Functions-from-Oct_002dFiles.html b/doc/interpreter/HTML/Calling-Octave-Functions-from-Oct_002dFiles.html
new file mode 100644
index 0000000..0d3d970
--- /dev/null
+++ b/doc/interpreter/HTML/Calling-Octave-Functions-from-Oct_002dFiles.html
@@ -0,0 +1,127 @@
+<html lang="en">
+<head>
+<title>Calling Octave Functions from Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles" title="Accessing Global Variables in Oct-Files">
+<link rel="next" href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles" title="Calling External Code from Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Calling-Octave-Functions-from-Oct-Files"></a>
+<a name="Calling-Octave-Functions-from-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles">Calling External Code from Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles">Accessing Global Variables in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.8 Calling Octave Functions from Oct-Files</h4>
+
+<p>There is often a need to be able to call another octave function from
+within an oct-file, and there are many examples of such within octave
+itself.  For example the <code>quad</code> function is an oct-file that
+calculates the definite integral by quadrature over a user supplied
+function.
+
+   <p>There are also many ways in which a function might be passed.  It might
+be passed as one of
+
+     <ol type=1 start=1>
+<li>Function Handle
+<li>Anonymous Function Handle
+<li>Inline Function
+<li>String
+        </ol>
+
+   <p>The example below demonstrates an example that accepts all four means of
+passing a function to an oct-file.
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     #include <octave/parse.h>
+     
+     DEFUN_DLD (funcdemo, args, nargout, "Function Demo")
+     {
+       int nargin = args.length();
+       octave_value_list retval;
+     
+       if (nargin < 2)
+         print_usage ();
+       else
+         {
+           octave_value_list newargs;
+           for (octave_idx_type i = nargin - 1; i > 0; i--)
+             newargs (i - 1) = args(i);
+           if (args(0).is_function_handle ()
+               || args(0).is_inline_function ())
+             {
+               octave_function *fcn = args(0).function_value ();
+               if (! error_state)
+                 retval = feval (fcn, newargs, nargout);
+             }
+           else if (args(0).is_string ())
+             {
+               std::string fcn = args (0).string_value ();
+               if (! error_state)
+                 retval = feval (fcn, newargs, nargout);
+             }
+           else
+             error ("funcdemo: expected string,",
+     	       " inline or function handle");
+         }
+       return retval;
+     }
+</pre></pre>
+   <p>The first argument to this demonstration is the user supplied function
+and the following arguments are all passed to the user function.
+
+<pre class="example">     funcdemo (@sin,1)
+      0.84147
+     funcdemo (@(x) sin(x), 1)
+      0.84147
+     funcdemo (inline ("sin(x)"), 1)
+      0.84147
+     funcdemo ("sin",1)
+      0.84147
+     funcdemo (@atan2, 1, 1)
+      0.78540
+</pre>
+   <p>When the user function is passed as a string, the treatment of the
+function is different.  In some cases it is necessary to always have the
+user supplied function as an <code>octave_function</code> object.  In that
+case the string argument can be used to create a temporary function like
+
+<pre class="example">     std::octave fcn_name = unique_symbol_name ("__fcn__");
+     std::string fname = "function y = ";
+     fname.append (fcn_name);
+     fname.append ("(x) y = ");
+     fcn = extract_function (args(0), "funcdemo", fcn_name,
+                             fname, "; endfunction");
+     ...
+     if (fcn_name.length ())
+       clear_function (fcn_name);
+</pre>
+   <p>There are two important things to know in this case.  The number of input
+arguments to the user function is fixed, and in the above is a single
+argument, and secondly to avoid leaving the temporary function in the
+Octave symbol table it should be cleared after use.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Calling-Other-Functions-in-Mex_002dFiles.html b/doc/interpreter/HTML/Calling-Other-Functions-in-Mex_002dFiles.html
new file mode 100644
index 0000000..bb8eefb
--- /dev/null
+++ b/doc/interpreter/HTML/Calling-Other-Functions-in-Mex_002dFiles.html
@@ -0,0 +1,82 @@
+<html lang="en">
+<head>
+<title>Calling Other Functions in Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="prev" href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles" title="Sparse Matrices with Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Calling-Other-Functions-in-Mex-Files"></a>
+<a name="Calling-Other-Functions-in-Mex_002dFiles"></a>
+Previous: <a rel="previous" accesskey="p" href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles">Sparse Matrices with Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.7 Calling Other Functions in Mex-Files</h4>
+
+<p>It is also possible call other Octave functions from within a mex-file
+using <code>mexCallMATLAB</code>.  An example of the use of
+<code>mexCallMATLAB</code> can be see in the example below
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+     	     const mxArray* prhs[])
+     {
+       char *str;
+     
+       mexPrintf ("Hello, World!\n");
+     
+       mexPrintf ("I have %d inputs and %d outputs\n", nrhs,
+     	     nlhs);
+     
+       if (nrhs < 1 || ! mxIsString (prhs[0])) 
+         mexErrMsgTxt ("function name expected");
+     
+       str = mxArrayToString (prhs[0]);
+     
+       mexPrintf ("I'm going to call the function %s\n", str);
+     
+       mexCallMATLAB (nlhs, plhs, nrhs-1, prhs+1, str);
+     
+       mxFree (str);
+     }
+</pre></pre>
+   <p>If this code is in the file <samp><span class="file">myfeval.c</span></samp>, and is compiled to
+<samp><span class="file">myfeval.mex</span></samp>, then an example of its use is
+
+<pre class="example">     myfeval("sin", 1)
+     a = myfeval("sin", 1)
+      Hello, World!
+         I have 2 inputs and 1 outputs
+         I'm going to call the interpreter function sin
+         a =  0.84147
+</pre>
+   <p>Note that it is not possible to use function handles or inline functions
+within a mex-file.
+
+<!-- @node Application Programming Interface for Mex-Files -->
+<!-- @subsection Application Programming Interface for Mex-Files -->
+<!-- WRITE ME, refer to mex.h and mexproto.h -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Calling-a-Function-by-its-Name.html b/doc/interpreter/HTML/Calling-a-Function-by-its-Name.html
new file mode 100644
index 0000000..70aeb4d
--- /dev/null
+++ b/doc/interpreter/HTML/Calling-a-Function-by-its-Name.html
@@ -0,0 +1,120 @@
+<html lang="en">
+<head>
+<title>Calling a Function by its Name - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Evaluation.html#Evaluation" title="Evaluation">
+<link rel="next" href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context" title="Evaluation in a Different Context">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Calling-a-Function-by-its-Name"></a>
+Next: <a rel="next" accesskey="n" href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context">Evaluation in a Different Context</a>,
+Up: <a rel="up" accesskey="u" href="Evaluation.html#Evaluation">Evaluation</a>
+<hr>
+</div>
+
+<h3 class="section">9.1 Calling a Function by its Name</h3>
+
+<p>The <code>feval</code> function allows you to call a function from a string
+containing its name.  This is useful when writing a function that needs to
+call user-supplied functions.  The <code>feval</code> function takes the name
+of the function to call as its first argument, and the remaining
+arguments are given to the function.
+
+   <p>The following example is a simple-minded function using <code>feval</code>
+that finds the root of a user-supplied function of one variable using
+Newton's method.
+
+<pre class="example">     <a name="index-Fordyce_002c-A_002e-P_002e-547"></a><a name="index-newtroot-548"></a>function result = newtroot (fname, x)
+     
+     # usage: newtroot (fname, x)
+     #
+     #   fname : a string naming a function f(x).
+     #   x     : initial guess
+     
+       delta = tol = sqrt (eps);
+       maxit = 200;
+       fx = feval (fname, x);
+       for i = 1:maxit
+         if (abs (fx) < tol)
+           result = x;
+           return;
+         else
+           fx_new = feval (fname, x + delta);
+           deriv = (fx_new - fx) / delta;
+           x = x - fx / deriv;
+           fx = fx_new;
+         endif
+       endfor
+     
+       result = x;
+     
+     endfunction
+</pre>
+   <p>Note that this is only meant to be an example of calling user-supplied
+functions and should not be taken too seriously.  In addition to using a
+more robust algorithm, any serious code would check the number and type
+of all the arguments, ensure that the supplied function really was a
+function, etc.  See <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a>, for example,
+for a list of predicates for numeric objects, and see <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a>, for a description of the <code>exist</code> function.
+
+<!-- parse.cc -->
+   <p><a name="doc_002dfeval"></a>
+
+<div class="defun">
+— Built-in Function:  <b>feval</b> (<var>name, <small class="dots">...</small></var>)<var><a name="index-feval-549"></a></var><br>
+<blockquote><p>Evaluate the function named <var>name</var>.  Any arguments after the first
+are passed on to the named function.  For example,
+
+     <pre class="example">          feval ("acos", -1)
+                3.1416
+</pre>
+        <p class="noindent">calls the function <code>acos</code> with the argument ‘<samp><span class="samp">-1</span></samp>’.
+
+        <p>The function <code>feval</code> is necessary in order to be able to write
+functions that call user-supplied functions, because Octave does not
+have a way to declare a pointer to a function (like C) or to declare a
+special kind of variable that can be used to hold the name of a function
+(like <code>EXTERNAL</code> in Fortran).  Instead, you must refer to functions
+by name, and use <code>feval</code> to call them. 
+</p></blockquote></div>
+
+   <p>A similar function <code>run</code> exists for calling user script files, that
+are not necessarily on the user path
+
+<!-- ./miscellaneous/run.m -->
+   <p><a name="doc_002drun"></a>
+
+<div class="defun">
+— Function File:  <b>run</b> (<var>f</var>)<var><a name="index-run-550"></a></var><br>
+— Command:  <b>run</b><var> f<a name="index-run-551"></a></var><br>
+<blockquote><p>Run scripts in the current workspace that are not necessarily on the
+path.  If <var>f</var> is the script to run, including its path, then <code>run</code>
+change the directory to the directory where <var>f</var> is found.  <code>run</code>
+then executes the script, and returns to the original directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsystem.html#doc_002dsystem">system</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Catching-Errors.html b/doc/interpreter/HTML/Catching-Errors.html
new file mode 100644
index 0000000..a63dcf5
--- /dev/null
+++ b/doc/interpreter/HTML/Catching-Errors.html
@@ -0,0 +1,174 @@
+<html lang="en">
+<head>
+<title>Catching Errors - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Handling-Errors.html#Handling-Errors" title="Handling Errors">
+<link rel="prev" href="Raising-Errors.html#Raising-Errors" title="Raising Errors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Catching-Errors"></a>
+Previous: <a rel="previous" accesskey="p" href="Raising-Errors.html#Raising-Errors">Raising Errors</a>,
+Up: <a rel="up" accesskey="u" href="Handling-Errors.html#Handling-Errors">Handling Errors</a>
+<hr>
+</div>
+
+<h4 class="subsection">12.1.2 Catching Errors</h4>
+
+<p>When an error occurs, it can be detected and handled using the
+<code>try</code> statement as described in <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>. 
+As an example, the following piece of code counts the number of errors
+that occurs during a <code>for</code> loop.
+
+<pre class="example">     number_of_errors = 0;
+     for n = 1:100
+       try
+         ...
+       catch
+         number_of_errors++;
+       end_try_catch
+     endfor
+</pre>
+   <p>The above example treats all errors the same.  In many situations it
+can however be necessary to discriminate between errors, and take
+different actions depending on the error.  The <code>lasterror</code>
+function returns a structure containing information about the last
+error that occurred.  As an example, the code above could be changed
+to count the number of errors related to the ‘<samp><span class="samp">*</span></samp>’ operator.
+
+<pre class="example">     number_of_errors = 0;
+     for n = 1:100
+       try
+         ...
+       catch
+         msg = lasterror.message;
+         if (strfind (msg, "operator *"))
+           number_of_errors++;
+         endif
+       end_try_catch
+     endfor
+</pre>
+   <!-- error.cc -->
+   <p><a name="doc_002dlasterror"></a>
+
+<div class="defun">
+— Built-in Function: <var>err</var> = <b>lasterror</b> (<var>err</var>)<var><a name="index-lasterror-670"></a></var><br>
+— Built-in Function:  <b>lasterror</b> (<var>'reset'</var>)<var><a name="index-lasterror-671"></a></var><br>
+<blockquote><p>Returns or sets the last error message.  Called without any arguments
+returns a structure containing the last error message, as well as other
+information related to this error.  The elements of this structure are:
+
+          <dl>
+<dt>'message'<dd>The text of the last error message
+<br><dt>'identifier'<dd>The message identifier of this error message
+<br><dt>'stack'<dd>A structure containing information on where the message occurred.  This might
+be an empty structure if this in the case where this information cannot
+be obtained.  The fields of this structure are:
+
+               <dl>
+<dt>'file'<dd>The name of the file where the error occurred
+<br><dt>'name'<dd>The name of function in which the error occurred
+<br><dt>'line'<dd>The line number at which the error occurred
+<br><dt>'column'<dd>An optional field with the column number at which the error occurred
+</dl>
+          </dl>
+
+        <p>The <var>err</var> structure may also be passed to <code>lasterror</code> to set the
+information about the last error.  The only constraint on <var>err</var> in that
+case is that it is a scalar structure.  Any fields of <var>err</var> that match
+the above are set to the value passed in <var>err</var>, while other fields are
+set to their default values.
+
+        <p>If <code>lasterror</code> is called with the argument 'reset', all values take
+their default values. 
+</p></blockquote></div>
+
+<!-- error.cc -->
+   <p><a name="doc_002dlasterr"></a>
+
+<div class="defun">
+— Built-in Function: [<var>msg</var>, <var>msgid</var>] = <b>lasterr</b> (<var>msg, msgid</var>)<var><a name="index-lasterr-672"></a></var><br>
+<blockquote><p>Without any arguments, return the last error message.  With one
+argument, set the last error message to <var>msg</var>.  With two arguments,
+also set the last message identifier. 
+</p></blockquote></div>
+
+   <p>When an error has been handled it is possible to raise it again.  This
+can be useful when an error needs to be detected, but the program should
+still abort.  This is possible using the <code>rethrow</code> function.  The
+previous example can now be changed to count the number of errors
+related to the ‘<samp><span class="samp">*</span></samp>’ operator, but still abort if another kind of
+error occurs.
+
+<pre class="example">     number_of_errors = 0;
+     for n = 1:100
+       try
+         ...
+       catch
+         msg = lasterror.message;
+         if (strfind (msg, "operator *"))
+           number_of_errors++;
+         else
+           rethrow (lasterror);
+         endif
+       end_try_catch
+     endfor
+</pre>
+   <!-- error.cc -->
+   <p><a name="doc_002drethrow"></a>
+
+<div class="defun">
+— Built-in Function:  <b>rethrow</b> (<var>err</var>)<var><a name="index-rethrow-673"></a></var><br>
+<blockquote><p>Reissues a previous error as defined by <var>err</var>.  <var>err</var> is a structure
+that must contain at least the 'message' and 'identifier' fields.  <var>err</var>
+can also contain a field 'stack' that gives information on the assumed
+location of the error.  Typically <var>err</var> is returned from
+<code>lasterror</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlasterror.html#doc_002dlasterror">lasterror</a>, <a href="doc_002dlasterr.html#doc_002dlasterr">lasterr</a>, <a href="doc_002derror.html#doc_002derror">error</a>. 
+</p></blockquote></div>
+
+<!-- FIXME: I have no idea what the rest of the functions are used for... -->
+<!-- utils.cc -->
+   <p><a name="doc_002derrno"></a>
+
+<div class="defun">
+— Built-in Function: <var>err</var> = <b>errno</b> ()<var><a name="index-errno-674"></a></var><br>
+— Built-in Function: <var>err</var> = <b>errno</b> (<var>val</var>)<var><a name="index-errno-675"></a></var><br>
+— Built-in Function: <var>err</var> = <b>errno</b> (<var>name</var>)<var><a name="index-errno-676"></a></var><br>
+<blockquote><p>Return the current value of the system-dependent variable errno,
+set its value to <var>val</var> and return the previous value, or return
+the named error code given <var>name</var> as a character string, or -1
+if <var>name</var> is not found. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002derrno_005flist"></a>
+
+<div class="defun">
+— Built-in Function:  <b>errno_list</b> ()<var><a name="index-errno_005flist-677"></a></var><br>
+<blockquote><p>Return a structure containing the system-dependent errno values. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Cell-Array-Objects.html b/doc/interpreter/HTML/Cell-Array-Objects.html
new file mode 100644
index 0000000..fe18eca
--- /dev/null
+++ b/doc/interpreter/HTML/Cell-Array-Objects.html
@@ -0,0 +1,42 @@
+<html lang="en">
+<head>
+<title>Cell Array Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Built_002din-Data-Types.html#Built_002din-Data-Types" title="Built-in Data Types">
+<link rel="prev" href="Data-Structure-Objects.html#Data-Structure-Objects" title="Data Structure Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Cell-Array-Objects"></a>
+Previous: <a rel="previous" accesskey="p" href="Data-Structure-Objects.html#Data-Structure-Objects">Data Structure Objects</a>,
+Up: <a rel="up" accesskey="u" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<hr>
+</div>
+
+<h4 class="subsection">3.1.5 Cell Array Objects</h4>
+
+<p><a name="index-cell-arrays-197"></a>
+A Cell Array in Octave is general array that can hold any number of
+different data types.
+
+   <p>See <a href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>, for more information.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Cell-Arrays-in-Oct_002dFiles.html b/doc/interpreter/HTML/Cell-Arrays-in-Oct_002dFiles.html
new file mode 100644
index 0000000..c6b3e31
--- /dev/null
+++ b/doc/interpreter/HTML/Cell-Arrays-in-Oct_002dFiles.html
@@ -0,0 +1,80 @@
+<html lang="en">
+<head>
+<title>Cell Arrays in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles" title="Character Strings in Oct-Files">
+<link rel="next" href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles" title="Structures in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Cell-Arrays-in-Oct-Files"></a>
+<a name="Cell-Arrays-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles">Structures in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles">Character Strings in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.4 Cell Arrays in Oct-Files</h4>
+
+<p>Octave's cell type is equally accessible within oct-files.  A cell
+array is just an array of <code>octave_value</code>s, and so each element of the cell
+array can then be treated just like any other <code>octave_value</code>.  A simple
+example is
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     #include <octave/Cell.h>
+     
+     DEFUN_DLD (celldemo, args, , "Cell Demo") 
+     {
+       octave_value_list retval;
+       int nargin = args.length ();
+     
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           Cell c = args (0).cell_value ();
+           if (! error_state)
+             for (octave_idx_type i = 0; i < c.nelem (); i++)
+               retval(i) = c.elem (i);
+         }
+     
+       return retval;
+     }
+</pre>
+</pre>
+   <p>Note that cell arrays are used less often in standard oct-files and so
+the <samp><span class="file">Cell.h</span></samp> header file must be explicitly included.  The rest of this
+example extracts the <code>octave_value</code>s one by one from the cell array and
+returns be as individual return arguments.  For example consider
+
+<pre class="example">     [b1, b2, b3] = celldemo ({1, [1, 2], "test"})
+     
+     b1 =  1
+     b2 =
+     
+        1   2
+     
+     b3 = test
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Cell-Arrays-of-Strings.html b/doc/interpreter/HTML/Cell-Arrays-of-Strings.html
new file mode 100644
index 0000000..b4f52bf
--- /dev/null
+++ b/doc/interpreter/HTML/Cell-Arrays-of-Strings.html
@@ -0,0 +1,118 @@
+<html lang="en">
+<head>
+<title>Cell Arrays of Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link rel="prev" href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays" title="Indexing Cell Arrays">
+<link rel="next" href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays" title="Processing Data in Cell Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Cell-Arrays-of-Strings"></a>
+Next: <a rel="next" accesskey="n" href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a>,
+Previous: <a rel="previous" accesskey="p" href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.2.4 Cell Arrays of Strings</h4>
+
+<p>One common use of cell arrays is to store multiple strings in the same
+variable.  It is also possible to store multiple strings in a
+character matrix by letting each row be a string.  This, however,
+introduces the problem that all strings must be of equal length. 
+Therefore, it is recommended to use cell arrays to store multiple
+strings.  For cases, where the character matrix representation is required
+for an operation, there are several functions that convert a cell
+array of strings to a character array and back.  <code>char</code> and
+<code>strvcat</code> convert cell arrays to a character array
+(see <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a>), while the function <code>cellstr</code>
+converts a character array to a cell array of strings:
+
+<pre class="example">     a = ["hello"; "world"];
+     c = cellstr (a)
+           c =
+              {
+                [1,1] = hello
+                [2,1] = world
+              }
+</pre>
+   <!-- ov-cell.cc -->
+   <p><a name="doc_002dcellstr"></a>
+
+<div class="defun">
+— Built-in Function:  <b>cellstr</b> (<var>string</var>)<var><a name="index-cellstr-397"></a></var><br>
+<blockquote><p>Create a new cell array object from the elements of the string
+array <var>string</var>. 
+</p></blockquote></div>
+
+   <p>One further advantage of using cell arrays to store multiple strings is
+that most functions for string manipulations included with Octave
+support this representation.  As an example, it is possible to compare
+one string with many others using the <code>strcmp</code> function.  If one of
+the arguments to this function is a string and the other is a cell array
+of strings, each element of the cell array will be compared to the string
+argument:
+
+<pre class="example">     c = {"hello", "world"};
+     strcmp ("hello", c)
+           ans =
+             1   0
+</pre>
+   <p class="noindent">The following string functions support cell arrays of strings:
+<code>char</code>, <code>strvcat</code>, <code>strcat</code> (see <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a>), <code>strcmp</code>, <code>strncmp</code>, <code>strcmpi</code>,
+<code>strncmpi</code> (see <a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a>), <code>str2double</code>,
+<code>deblank</code>, <code>strtrim</code>, <code>strtrunc</code>, <code>strfind</code>,
+<code>strmatch</code>, , <code>regexp</code>, <code>regexpi</code> (see <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a>) and <code>str2double</code> (see <a href="String-Conversions.html#String-Conversions">String Conversions</a>).
+
+   <p>The function <code>iscellstr</code> can be used to test if an object is a
+cell array of strings.
+
+<!-- ov-cell.cc -->
+   <p><a name="doc_002discellstr"></a>
+
+<div class="defun">
+— Built-in Function:  <b>iscellstr</b> (<var>cell</var>)<var><a name="index-iscellstr-398"></a></var><br>
+<blockquote><p>Return true if every element of the cell array <var>cell</var> is a
+character string
+</p></blockquote></div>
+
+<!-- ./general/cellidx.m -->
+   <p><a name="doc_002dcellidx"></a>
+
+<div class="defun">
+— Function File: [<var>idxvec</var>, <var>errmsg</var>] = <b>cellidx</b> (<var>listvar, strlist</var>)<var><a name="index-cellidx-399"></a></var><br>
+<blockquote><p>Return indices of string entries in <var>listvar</var> that match strings
+in <var>strlist</var>.
+
+        <p>Both <var>listvar</var> and <var>strlist</var> may be passed as strings or
+string matrices.  If they are passed as string matrices, each entry
+is processed by <code>deblank</code> prior to searching for the entries.
+
+        <p>The first output is the vector of indices in <var>listvar</var>.
+
+        <p>If <var>strlist</var> contains a string not in <var>listvar</var>, then
+an error message is returned in <var>errmsg</var>.  If only one output
+argument is requested, then <var>cellidx</var> prints <var>errmsg</var> to the
+screen and exits with an error. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Cell-Arrays-with-Mex_002dFiles.html b/doc/interpreter/HTML/Cell-Arrays-with-Mex_002dFiles.html
new file mode 100644
index 0000000..f98cb6c
--- /dev/null
+++ b/doc/interpreter/HTML/Cell-Arrays-with-Mex_002dFiles.html
@@ -0,0 +1,88 @@
+<html lang="en">
+<head>
+<title>Cell Arrays with Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="prev" href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles" title="Character Strings in Mex-Files">
+<link rel="next" href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles" title="Structures with Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Cell-Arrays-with-Mex-Files"></a>
+<a name="Cell-Arrays-with-Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles">Structures with Mex-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles">Character Strings in Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.4 Cell Arrays with Mex-Files</h4>
+
+<p>We can perform exactly the same operations in Cell arrays in mex-files
+as we can in oct-files.  An example that reduplicates the functional of
+the <samp><span class="file">celldemo.cc</span></samp> oct-file in a mex-file is given by
+<samp><span class="file">mycell.c</span></samp> as below
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+     	     const mxArray* prhs[])
+     {
+       mwSize n;
+       mwIndex i;
+     
+       if (nrhs != 1 || ! mxIsCell (prhs[0]))
+         mexErrMsgTxt ("expects cell");
+     
+       n = mxGetNumberOfElements (prhs[0]);
+       n = (n > nlhs ? nlhs : n);
+       
+       for (i = 0; i < n; i++)
+         plhs[i] = mxDuplicateArray (mxGetCell (prhs[0], i));
+     }
+</pre>
+</pre>
+   <p class="noindent">which as can be seen below has exactly the same behavior as the oct-file
+version.
+
+<pre class="example">     [b1, b2, b3] = mycell ({1, [1, 2], "test"})
+     
+     b1 =  1
+     b2 =
+     
+        1   2
+     
+     b3 = test
+</pre>
+   <p>Note in the example the use of the <code>mxDuplicateArray</code> function.  This
+is needed as the <code>mxArray</code> pointer returned by <code>mxGetCell</code>
+might be deallocated.  The inverse function to <code>mxGetCell</code> is
+<code>mcSetCell</code> and is defined as
+
+<pre class="example">     void mxSetCell (mxArray *ptr, int idx, mxArray *val);
+</pre>
+   <p>Finally, to create a cell array or matrix, the appropriate functions are
+
+<pre class="example">     mxArray *mxCreateCellArray (int ndims, const int *dims);
+     mxArray *mxCreateCellMatrix (int m, int n);
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Cell-Arrays.html b/doc/interpreter/HTML/Cell-Arrays.html
new file mode 100644
index 0000000..1bd4f9c
--- /dev/null
+++ b/doc/interpreter/HTML/Cell-Arrays.html
@@ -0,0 +1,53 @@
+<html lang="en">
+<head>
+<title>Cell Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Containers.html#Data-Containers" title="Data Containers">
+<link rel="prev" href="Data-Structures.html#Data-Structures" title="Data Structures">
+<link rel="next" href="Comma-Separated-Lists.html#Comma-Separated-Lists" title="Comma Separated Lists">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Cell-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>,
+Previous: <a rel="previous" accesskey="p" href="Data-Structures.html#Data-Structures">Data Structures</a>,
+Up: <a rel="up" accesskey="u" href="Data-Containers.html#Data-Containers">Data Containers</a>
+<hr>
+</div>
+
+<h3 class="section">6.2 Cell Arrays</h3>
+
+<p><a name="index-cell-arrays-387"></a>
+It can be both necessary and convenient to store several variables of
+different size or type in one variable.  A cell array is a container
+class able to do just that.  In general cell arrays work just like
+N-dimensional arrays with the exception of the use of ‘<samp><span class="samp">{</span></samp>’
+and ‘<samp><span class="samp">}</span></samp>’ as allocation and indexing operators.
+
+<ul class="menu">
+<li><a accesskey="1" href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a>
+<li><a accesskey="2" href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a>
+<li><a accesskey="3" href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>
+<li><a accesskey="4" href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a>
+<li><a accesskey="5" href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Character-Arrays.html b/doc/interpreter/HTML/Character-Arrays.html
new file mode 100644
index 0000000..73f6c35
--- /dev/null
+++ b/doc/interpreter/HTML/Character-Arrays.html
@@ -0,0 +1,106 @@
+<html lang="en">
+<head>
+<title>Character Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="prev" href="Escape-Sequences-in-string-constants.html#Escape-Sequences-in-string-constants" title="Escape Sequences in string constants">
+<link rel="next" href="Creating-Strings.html#Creating-Strings" title="Creating Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Character-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Strings.html#Creating-Strings">Creating Strings</a>,
+Previous: <a rel="previous" accesskey="p" href="Escape-Sequences-in-string-constants.html#Escape-Sequences-in-string-constants">Escape Sequences in string constants</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.2 Character Arrays</h3>
+
+<p>The string representation used by Octave is an array of characters, so
+internally the string "dddddddddd" is actually a row vector of length 10
+containing the value 100 in all places (100 is the ASCII code of "d").  This
+lends itself to the obvious generalization to character matrices.  Using a
+matrix of characters, it is possible to represent a collection of same-length
+strings in one variable.  The convention used in Octave is that each row in a
+character matrix is a separate string, but letting each column represent a
+string is equally possible.
+
+   <p>The easiest way to create a character matrix is to put several strings
+together into a matrix.
+
+<pre class="example">     collection = [ "String #1"; "String #2" ];
+</pre>
+   <p class="noindent">This creates a 2-by-9 character matrix.
+
+   <p>The function <code>ischar</code> can be used to test if an object is a character
+matrix.
+
+<!-- strfns.cc -->
+   <p><a name="doc_002dischar"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ischar</b> (<var>a</var>)<var><a name="index-ischar-284"></a></var><br>
+<blockquote><p>Return 1 if <var>a</var> is a character array.  Otherwise, return 0. 
+</p></blockquote></div>
+
+   <p>To test if an object is a string (i.e., a character vector and not a character
+matrix) you can use the <code>ischar</code> function in combination with the
+<code>isvector</code> function as in the following example:
+
+<pre class="example">     ischar(collection)
+           ans = 1
+     
+     ischar(collection) && isvector(collection)
+           ans = 0
+     
+     ischar("my string") && isvector("my string")
+           ans = 1
+</pre>
+   <p>One relevant question is, what happens when a character matrix is
+created from strings of different length.  The answer is that Octave
+puts blank characters at the end of strings shorter than the longest
+string.  It is possible to use a different character than the
+blank character using the <code>string_fill_char</code> function.
+
+<!-- pt-mat.cc -->
+   <p><a name="doc_002dstring_005ffill_005fchar"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>string_fill_char</b> ()<var><a name="index-string_005ffill_005fchar-285"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>string_fill_char</b> (<var>new_val</var>)<var><a name="index-string_005ffill_005fchar-286"></a></var><br>
+<blockquote><p>Query or set the internal variable used to pad all rows of a character
+matrix to the same length.  It must be a single character.  The default
+value is <code>" "</code> (a single space).  For example,
+
+     <pre class="example">          string_fill_char ("X");
+          [ "these"; "are"; "strings" ]
+                "theseXX"
+                  "areXXXX"
+                  "strings"
+</pre>
+        </blockquote></div>
+
+   <p>This shows a problem with character matrices.  It simply isn't possible to
+represent strings of different lengths.  The solution is to use a cell array of
+strings, which is described in <a href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Character-Class-Functions.html b/doc/interpreter/HTML/Character-Class-Functions.html
new file mode 100644
index 0000000..089e91f
--- /dev/null
+++ b/doc/interpreter/HTML/Character-Class-Functions.html
@@ -0,0 +1,222 @@
+<html lang="en">
+<head>
+<title>Character Class Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="prev" href="String-Conversions.html#String-Conversions" title="String Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Character-Class-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="String-Conversions.html#String-Conversions">String Conversions</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.7 Character Class Functions</h3>
+
+<p>Octave also provides the following character class test functions
+patterned after the functions in the standard C library.  They all
+operate on string arrays and return matrices of zeros and ones. 
+Elements that are nonzero indicate that the condition was true for the
+corresponding character in the string array.  For example,
+
+<pre class="example">     isalpha ("!Q at WERT^Y&")
+           [ 0, 1, 0, 1, 1, 1, 1, 0, 1, 0 ]
+</pre>
+   <!-- mappers.cc -->
+   <p><a name="doc_002disalnum"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isalnum</b> (<var>s</var>)<var><a name="index-isalnum-353"></a></var><br>
+<blockquote><p>Return 1 for characters that are letters or digits (<code>isalpha
+(</code><var>s</var><code>)</code> or <code>isdigit (</code><var>s</var><code>)</code> is true). 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disalpha"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isalpha</b> (<var>s</var>)<var><a name="index-isalpha-354"></a></var><br>
+— Mapping Function:  <b>isletter</b> (<var>s</var>)<var><a name="index-isletter-355"></a></var><br>
+<blockquote><p>Return true for characters that are letters (<code>isupper (</code><var>s</var><code>)</code>
+or <code>islower (</code><var>s</var><code>)</code> is true). 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disascii"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isascii</b> (<var>s</var>)<var><a name="index-isascii-356"></a></var><br>
+<blockquote><p>Return 1 for characters that are ASCII (in the range 0 to 127 decimal). 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002discntrl"></a>
+
+<div class="defun">
+— Mapping Function:  <b>iscntrl</b> (<var>s</var>)<var><a name="index-iscntrl-357"></a></var><br>
+<blockquote><p>Return 1 for control characters. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disdigit"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isdigit</b> (<var>s</var>)<var><a name="index-isdigit-358"></a></var><br>
+<blockquote><p>Return 1 for characters that are decimal digits. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disgraph"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isgraph</b> (<var>s</var>)<var><a name="index-isgraph-359"></a></var><br>
+<blockquote><p>Return 1 for printable characters (but not the space character). 
+</p></blockquote></div>
+
+<!-- ./strings/isletter.m -->
+   <p><a name="doc_002disletter"></a>
+
+<div class="defun">
+— Function File:  <b>isletter</b> (<var>s</var>)<var><a name="index-isletter-360"></a></var><br>
+<blockquote><p>Returns true if <var>s</var> is a letter, false otherwise. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disalpha.html#doc_002disalpha">isalpha</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dislower"></a>
+
+<div class="defun">
+— Mapping Function:  <b>islower</b> (<var>s</var>)<var><a name="index-islower-361"></a></var><br>
+<blockquote><p>Return 1 for characters that are lower case letters. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disprint"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isprint</b> (<var>s</var>)<var><a name="index-isprint-362"></a></var><br>
+<blockquote><p>Return 1 for printable characters (including the space character). 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dispunct"></a>
+
+<div class="defun">
+— Mapping Function:  <b>ispunct</b> (<var>s</var>)<var><a name="index-ispunct-363"></a></var><br>
+<blockquote><p>Return 1 for punctuation characters. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disspace"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isspace</b> (<var>s</var>)<var><a name="index-isspace-364"></a></var><br>
+<blockquote><p>Return 1 for whitespace characters (space, formfeed, newline,
+carriage return, tab, and vertical tab). 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disupper"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isupper</b> (<var>s</var>)<var><a name="index-isupper-365"></a></var><br>
+<blockquote><p>Return 1 for upper case letters. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disxdigit"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isxdigit</b> (<var>s</var>)<var><a name="index-isxdigit-366"></a></var><br>
+<blockquote><p>Return 1 for characters that are hexadecimal digits. 
+</p></blockquote></div>
+
+<!-- ./strings/isstrprop.m -->
+   <p><a name="doc_002disstrprop"></a>
+
+<div class="defun">
+— Function File:  <b>isstrprop</b> (<var>str, pred</var>)<var><a name="index-isstrprop-367"></a></var><br>
+<blockquote><p>Test character string properties.  For example,
+
+     <pre class="example">          isstrprop ("abc123", "alpha")
+           [1, 1, 1, 0, 0, 0]
+</pre>
+        <p>If <var>str</var> is a cell array, <code>isstrpop</code> is applied recursively
+to each element of the cell array.
+
+        <p>Numeric arrays are converted to character strings.
+
+        <p>The second argument <var>pred</var> may be one of
+
+          <dl>
+<dt><code>"alpha"</code><dd>True for characters that are alphabetic
+
+          <br><dt><code>"alnum"</code><dt><code>"alphanum"</code><dd>True for characters that are alphabetic or digits.
+
+          <br><dt><code>"ascii"</code><dd>True for characters that are in the range of ASCII encoding.
+
+          <br><dt><code>"cntrl"</code><dd>True for control characters.
+
+          <br><dt><code>"digit"</code><dd>True for decimal digits.
+
+          <br><dt><code>"graph"</code><dt><code>"graphic"</code><dd>True for printing characters except space.
+
+          <br><dt><code>"lower"</code><dd>True for lower-case letters.
+
+          <br><dt><code>"print"</code><dd>True for printing characters including space.
+
+          <br><dt><code>"punct"</code><dd>True for printing characters except space or letter or digit.
+
+          <br><dt><code>"space"</code><dt><code>"wspace"</code><dd>True for whitespace characters (space, formfeed, newline, carriage
+return, tab, vertical tab).
+
+          <br><dt><code>"upper"</code><dd>True for upper-case letters.
+
+          <br><dt><code>"xdigit"</code><dd>True for hexadecimal digits. 
+</dl>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disalnum.html#doc_002disalnum">isalnum</a>, <a href="doc_002disalpha.html#doc_002disalpha">isalpha</a>, <a href="doc_002disascii.html#doc_002disascii">isascii</a>, <a href="doc_002discntrl.html#doc_002discntrl">iscntrl</a>, <a href="doc_002disdigit.html#doc_002disdigit">isdigit</a>, <a href="doc_002disgraph.html#doc_002disgraph">isgraph</a>, <a href="doc_002dislower.html#doc_002dislower">islower</a>, <a href="doc_002disprint.html#doc_002disprint">isprint</a>, <a href="doc_002dispunct.html#doc_002dispunct">ispunct</a>, <a href="doc_002disspace.html#doc_002disspace">isspace</a>, <a href="doc_002disupper.html#doc_002disupper">isupper</a>, <a href="doc_002disxdigit.html#doc_002disxdigit">isxdigit</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Character-Strings-in-Mex_002dFiles.html b/doc/interpreter/HTML/Character-Strings-in-Mex_002dFiles.html
new file mode 100644
index 0000000..b9c5ce3
--- /dev/null
+++ b/doc/interpreter/HTML/Character-Strings-in-Mex_002dFiles.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Character Strings in Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="prev" href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles" title="Working with Matrices and Arrays in Mex-Files">
+<link rel="next" href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles" title="Cell Arrays with Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Character-Strings-in-Mex-Files"></a>
+<a name="Character-Strings-in-Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles">Cell Arrays with Mex-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles">Working with Matrices and Arrays in Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.3 Character Strings in Mex-Files</h4>
+
+<p>As mex-files do not make the distinction between single and double
+quoted strings within Octave, there is perhaps less complexity in the
+use of strings and character matrices in mex-files.  An example of their
+use, that parallels the demo in <samp><span class="file">stringdemo.cc</span></samp>, is given in the
+file <samp><span class="file">mystring.c</span></samp>, as seen below.
+
+<pre class="example"><pre class="verbatim">     #include <string.h>
+     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+     	     const mxArray *prhs[])
+     {
+       mwIndex i, j;
+       mwSize m, n;
+       mxChar *pi, *po;
+     
+       if (nrhs != 1 || ! mxIsChar (prhs[0]) || 
+           mxGetNumberOfDimensions (prhs[0]) > 2)
+         mexErrMsgTxt ("expecting char matrix");
+     
+       m = mxGetM (prhs[0]);
+       n = mxGetN (prhs[0]);
+       pi = mxGetChars (prhs[0]);
+       plhs[0] = mxCreateNumericMatrix (m, n, mxCHAR_CLASS, 
+     				   mxREAL);
+       po = mxGetChars (plhs[0]);
+     
+       for (j = 0; j < n; j++)
+         for (i = 0; i < m; i++)
+           po [j*m + m - 1 - i] = pi [j*m + i];
+     }
+</pre></pre>
+   <p class="noindent">An example of its expected output is
+
+<pre class="example">     mystring(["First String"; "Second String"])
+      s1 = Second String
+             First String
+</pre>
+   <p>Other functions in the mex interface for handling character strings are
+<code>mxCreateString</code>, <code>mxArrayToString</code>, and
+<code>mxCreateCharMatrixFromStrings</code>.  In a mex-file, a character string
+is considered to be a vector rather than a matrix.  This is perhaps an
+arbitrary distinction as the data in the mxArray for the matrix is
+consecutive in any case.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Character-Strings-in-Oct_002dFiles.html b/doc/interpreter/HTML/Character-Strings-in-Oct_002dFiles.html
new file mode 100644
index 0000000..65adda9
--- /dev/null
+++ b/doc/interpreter/HTML/Character-Strings-in-Oct_002dFiles.html
@@ -0,0 +1,115 @@
+<html lang="en">
+<head>
+<title>Character Strings in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles" title="Matrices and Arrays in Oct-Files">
+<link rel="next" href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles" title="Cell Arrays in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Character-Strings-in-Oct-Files"></a>
+<a name="Character-Strings-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles">Cell Arrays in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.3 Character Strings in Oct-Files</h4>
+
+<p>In Octave a character string is just a special <code>Array</code> class. 
+Consider the example
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     
+     DEFUN_DLD (stringdemo, args, , "String Demo")
+     {
+       int nargin = args.length();
+       octave_value_list retval; 
+     
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           charMatrix ch = args(0).char_matrix_value ();
+     
+           if (! error_state)
+             {
+               if (args(0).is_sq_string ())
+                 retval(1) = octave_value (ch, true);
+               else
+                 retval(1) = octave_value (ch, true, '\'');
+     
+               octave_idx_type nr = ch.rows();
+               for (octave_idx_type i = 0; i < nr / 2; i++)
+                 {
+                   std::string tmp = ch.row_as_string (i);
+                   ch.insert (ch.row_as_string(nr-i-1).c_str(), 
+     			 i, 0);
+                   ch.insert (tmp.c_str(), nr-i-1, 0);
+                 }
+               retval(0) = octave_value (ch, true);
+             }
+         }
+       return retval;
+     }
+</pre></pre>
+   <p>An example of the use of this function is
+
+<pre class="example">     s0 = ["First String"; "Second String"];
+     [s1,s2] = stringdemo (s0)
+      s1 = Second String
+             First String
+     
+      s2 = First String
+             Second String
+     
+     typeinfo (s2)
+      sq_string
+     typeinfo (s1)
+      string
+</pre>
+   <p>One additional complication of strings in Octave is the difference
+between single quoted and double quoted strings.  To find out if an
+<code>octave_value</code> contains a single or double quoted string an example is
+
+<pre class="example">         if (args(0).is_sq_string ())
+           octave_stdout <<
+             "First argument is a singularly quoted string\n";
+         else if (args(0).is_dq_string ())
+           octave_stdout <<
+             "First argument is a doubly quoted string\n";
+</pre>
+   <p>Note however, that both types of strings are represented by the
+<code>charNDArray</code> type, and so when assigning to an
+<code>octave_value</code>, the type of string should be specified.  For example
+
+<pre class="example">     octave_value_list retval;
+     charNDArray c;
+     ...
+     // Create single quoted string
+     retval(1) = octave_value (ch, true, '\'');
+     
+     // Create a double quoted string
+     retval(0) = octave_value (ch, true);
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Coding-Tips.html b/doc/interpreter/HTML/Coding-Tips.html
new file mode 100644
index 0000000..a814bcb
--- /dev/null
+++ b/doc/interpreter/HTML/Coding-Tips.html
@@ -0,0 +1,162 @@
+<html lang="en">
+<head>
+<title>Coding Tips - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link rel="prev" href="Style-Tips.html#Style-Tips" title="Style Tips">
+<link rel="next" href="Comment-Tips.html#Comment-Tips" title="Comment Tips">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Coding-Tips"></a>
+Next: <a rel="next" accesskey="n" href="Comment-Tips.html#Comment-Tips">Comment Tips</a>,
+Previous: <a rel="previous" accesskey="p" href="Style-Tips.html#Style-Tips">Style Tips</a>,
+Up: <a rel="up" accesskey="u" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
+<hr>
+</div>
+
+<h3 class="section">C.2 Tips for Making Code Run Faster.</h3>
+
+<p><a name="index-execution-speed-2508"></a><a name="index-speedups-2509"></a>
+Here are some ways of improving the execution speed of Octave programs.
+
+     <ul>
+<li>Vectorize loops. For instance, rather than
+     <pre class="example">          for i = 1:n-1
+            a(i) = b(i+1) - b(i);
+          endfor
+</pre>
+     <p>write
+
+     <pre class="example">          a = b(2:n) - b(1:n-1);
+</pre>
+     <p>This is especially important for loops with "cheap" bodies. Often it suffices to vectorize
+just the innermost loop to get acceptable performance. A general rule of thumb is that the
+"order" of the vectorized body should be greater or equal to the "order" of the enclosing loop.
+
+     <li>Use built-in and library functions if possible. Built-in and compiled functions are very fast. 
+Even with a m-file library function, chances are good that it is already optimized, or will be
+optimized more in a future release.
+
+     <li>Avoid computing costly intermediate results multiple times. Octave currently
+does not eliminate common subexpressions.
+
+     <li>Be aware of lazy copies (copy-on-write). When a copy of an object
+is created, the data is not immediately copied, but rather shared. The actual
+copying is postponed until the copied data needs to be modified. For example:
+
+     <pre class="example">          a = zeros (1000); # create a 1000x1000 matrix
+          b = a; # no copying done here
+          b(1) = 1; # copying done here
+</pre>
+     <p>Lazy copying applies to whole Octave objects such as matrices, cells, struct,
+and also individual cell or struct elements (not array elements).
+
+     <p>Additionally, index expressions also use lazy copying when Octave can determine
+that the indexed portion is contiguous in memory. For example:
+
+     <pre class="example">          a = zeros (1000); # create a 1000x1000 matrix
+          b = a(:,10:100); # no copying done here
+          b = a(10:100,:); # copying done here
+</pre>
+     <p>This applies to arrays (matrices), cell arrays, and structs indexed using (). 
+Index expressions generating cs-lists can also benefit of shallow copying
+in some cases. In particular, when <var>a</var> is a struct array, expressions like
+<code>{a.x}, {a(:,2).x}</code> will use lazy copying, so that data can be shared
+between a struct array and a cell array.
+
+     <p>Most indexing expressions do not live longer than their `parent' objects. 
+In rare cases, however, a lazily copied slice outlasts its parent, in which
+case it becomes orphaned, still occupying unnecessarily more memory than needed. 
+To provide a remedy working in most real cases,
+Octave checks for orphaned lazy slices at certain situations, when a value
+is stored into a "permanent" location, such as a named variable or cell or
+struct element, and possibly economizes them. For example
+
+     <pre class="example">          a = zeros (1000); # create a 1000x1000 matrix
+          b = a(:,10:100); # lazy slice
+          a = []; # the original a array is still allocated
+          c{1} = b; # b is reallocated at this point
+</pre>
+     <li>Avoid deep recursion. Function calls to m-file functions carry a relatively significant overhead,
+so rewriting a recursion as a loop often helps. Also, note that the maximum level of recursion is
+limited.
+
+     <li>Avoid resizing matrices unnecessarily. When building a single result
+matrix from a series of calculations, set the size of the result matrix
+first, then insert values into it.  Write
+
+     <pre class="example">          result = zeros (big_n, big_m)
+          for i = over:and_over
+            r1 = ...
+            r2 = ...
+            result (r1, r2) = new_value ();
+          endfor
+</pre>
+     <p class="noindent">instead of
+
+     <pre class="example">          result = [];
+          for i = ever:and_ever
+            result = [ result, new_value() ];
+          endfor
+</pre>
+     <p>Sometimes the number of items can't be computed in advance, and stack-like operations
+are needed. When elements are being repeatedly inserted at/removed from the end of an
+array, Octave detects it as stack usage and attempts to use a smarter memory management
+strategy preallocating the array in bigger chunks. Likewise works for cell and
+struct arrays.
+
+     <pre class="example">          a = [];
+          while (condition)
+            ...
+            a(end+1) = value; # "push" operation
+            ...
+            a(end) = []; # "pop" operation
+            ...
+          endwhile
+</pre>
+     <li>Use <code>cellfun</code> intelligently. The <code>cellfun</code> function is a useful tool
+for avoiding loops. See <a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a>. 
+<code>cellfun</code> is often use with anonymous function handles; however, calling
+an anonymous function involves an overhead quite comparable to the overhead
+of an m-file function. Passing a handle to a built-in function is faster,
+because the interpreter is not involved in the internal loop. For example:
+
+     <pre class="example">          a = {...}
+          v = cellfun (@(x) det(x), a); # compute determinants
+          v = cellfun (@det, a); # faster
+</pre>
+     <li>Avoid calling <code>eval</code> or <code>feval</code> excessively, because
+they require Octave to parse input or look up the name of a function in
+the symbol table.
+
+     <p>If you are using <code>eval</code> as an exception handling mechanism and not
+because you need to execute some arbitrary text, use the <code>try</code>
+statement instead.  See <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>.
+
+     <li>If you are calling lots of functions but none of them will need to
+change during your run, set the variable
+<code>ignore_function_time_stamp</code> to <code>"all"</code> so that Octave doesn't
+waste a lot of time checking to see if you have updated your function
+files. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Color-Conversion.html b/doc/interpreter/HTML/Color-Conversion.html
new file mode 100644
index 0000000..c28779a
--- /dev/null
+++ b/doc/interpreter/HTML/Color-Conversion.html
@@ -0,0 +1,113 @@
+<html lang="en">
+<head>
+<title>Color Conversion - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link rel="prev" href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images" title="Plotting on top of Images">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Color-Conversion"></a>
+Previous: <a rel="previous" accesskey="p" href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images">Plotting on top of Images</a>,
+Up: <a rel="up" accesskey="u" href="Image-Processing.html#Image-Processing">Image Processing</a>
+<hr>
+</div>
+
+<h3 class="section">31.5 Color Conversion</h3>
+
+<p>Octave supports conversion from the RGB color system to NTSC and HSV
+and vice versa.
+
+<!-- ./image/rgb2hsv.m -->
+   <p><a name="doc_002drgb2hsv"></a>
+
+<div class="defun">
+— Function File: <var>hsv_map</var> = <b>rgb2hsv</b> (<var>rgb_map</var>)<var><a name="index-rgb2hsv-2234"></a></var><br>
+<blockquote><p>Transform a colormap or image from the rgb space to the hsv space.
+
+        <p>A color n the RGB space consists of the red, green and blue intensities.
+
+        <p>In the HSV space each color is represented by their hue, saturation
+and value (brightness).  Value gives the amount of light in the color. 
+Hue describes the dominant wavelength. 
+Saturation is the amount of Hue mixed into the color. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhsv2rgb.html#doc_002dhsv2rgb">hsv2rgb</a>. 
+</p></blockquote></div>
+
+<!-- ./image/hsv2rgb.m -->
+   <p><a name="doc_002dhsv2rgb"></a>
+
+<div class="defun">
+— Function File: <var>rgb_map</var> = <b>hsv2rgb</b> (<var>hsv_map</var>)<var><a name="index-hsv2rgb-2235"></a></var><br>
+<blockquote><p>Transform a colormap or image from the hsv space to the rgb space. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drgb2hsv.html#doc_002drgb2hsv">rgb2hsv</a>. 
+</p></blockquote></div>
+
+<!-- ./image/rgb2ntsc.m -->
+   <p><a name="doc_002drgb2ntsc"></a>
+
+<div class="defun">
+— Function File:  <b>rgb2ntsc</b> (<var>rgb</var>)<var><a name="index-rgb2ntsc-2236"></a></var><br>
+<blockquote><p>Transform a colormap or image from RGB to NTSC. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dntsc2rgb.html#doc_002dntsc2rgb">ntsc2rgb</a>. 
+</p></blockquote></div>
+
+<!-- ./image/ntsc2rgb.m -->
+   <p><a name="doc_002dntsc2rgb"></a>
+
+<div class="defun">
+— Function File:  <b>ntsc2rgb</b> (<var>yiq</var>)<var><a name="index-ntsc2rgb-2237"></a></var><br>
+<blockquote><p>Transform a colormap or image from NTSC to RGB. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drgb2ntsc.html#doc_002drgb2ntsc">rgb2ntsc</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2005, 2007, 2009 Kurt Hornik -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+<!-- Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/05/14 -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Colors.html b/doc/interpreter/HTML/Colors.html
new file mode 100644
index 0000000..daba7c5
--- /dev/null
+++ b/doc/interpreter/HTML/Colors.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Colors - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Managing-Default-Properties.html#Managing-Default-Properties" title="Managing Default Properties">
+<link rel="next" href="Line-Styles.html#Line-Styles" title="Line Styles">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Colors"></a>
+Next: <a rel="next" accesskey="n" href="Line-Styles.html#Line-Styles">Line Styles</a>,
+Previous: <a rel="previous" accesskey="p" href="Managing-Default-Properties.html#Managing-Default-Properties">Managing Default Properties</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.4 Colors</h4>
+
+<p><a name="index-graphics-colors-1210"></a><a name="index-colors_002c-graphics-1211"></a>
+Colors may be specified as RGB triplets with values ranging from zero to
+one, or by name.  Recognized color names include <code>"blue"</code>,
+<code>"black"</code>, <code>"cyan"</code>, <code>"green"</code>, <code>"magenta"</code>,
+<code>"red"</code>, <code>"white"</code>, and <code>"yellow"</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comma-Separated-Lists-Generated-from-Cell-Arrays.html b/doc/interpreter/HTML/Comma-Separated-Lists-Generated-from-Cell-Arrays.html
new file mode 100644
index 0000000..b46ecd9
--- /dev/null
+++ b/doc/interpreter/HTML/Comma-Separated-Lists-Generated-from-Cell-Arrays.html
@@ -0,0 +1,92 @@
+<html lang="en">
+<head>
+<title>Comma Separated Lists Generated from Cell Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Comma-Separated-Lists.html#Comma-Separated-Lists" title="Comma Separated Lists">
+<link rel="next" href="Comma-Separated-Lists-Generated-from-Structure-Arrays.html#Comma-Separated-Lists-Generated-from-Structure-Arrays" title="Comma Separated Lists Generated from Structure Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comma-Separated-Lists-Generated-from-Cell-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Comma-Separated-Lists-Generated-from-Structure-Arrays.html#Comma-Separated-Lists-Generated-from-Structure-Arrays">Comma Separated Lists Generated from Structure Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.3.1 Comma Separated Lists Generated from Cell Arrays</h4>
+
+<p>As has been mentioned above (see <a href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>), elements
+of a cell array can be extracted into a comma separated list with the
+<code>{</code> and <code>}</code> operators. By surrounding this list with
+<code>[</code> and <code>]</code>, it can be concatenated into an array. For example:
+
+<pre class="example">     a = {1, [2, 3], 4, 5, 6};
+     b = [a{1:4}]
+           b =
+              1   2   3   4
+</pre>
+   <p>Similarly, it is possible to create a new cell array containing cell
+elements selected with <code>{}</code>.  By surrounding the list with
+‘<samp><span class="samp">{</span></samp>’ and ‘<samp><span class="samp">}</span></samp>’ a new cell array will be created, as the
+following example illustrates:
+
+<pre class="example">     a = {1, rand(2, 2), "three"};
+     b = { a{ [1, 3] } }
+           b =
+              {
+                [1,1] =  1
+                [1,2] = three
+              }
+</pre>
+   <p>Furthermore, cell elements (accessed by <code>{}</code>) can be passed
+directly to a function.  The list of elements from the cell array will
+be passed as an argument list to a given function as if it is called
+with the elements as individual arguments.  The two calls to
+<code>printf</code> in the following example are identical but the latter is
+simpler and can handle cell arrays of an arbitrary size:
+
+<pre class="example">     c = {"GNU", "Octave", "is", "Free", "Software"};
+     printf ("%s ", c{1}, c{2}, c{3}, c{4}, c{5});
+          -| GNU Octave is Free Software
+     printf ("%s ", c{:});
+          -| GNU Octave is Free Software
+</pre>
+   <p>If used on the left-hand side of an assignment, a comma separated list
+generated with <code>{}</code> can be assigned to.  An example is
+
+<pre class="example">     in{1} = [10, 20, 30, 40, 50, 60, 70, 80, 90];
+     in{2} = inf;
+     in{3} = "last";
+     in{4} = "first";
+     out = cell (4, 1);
+     [out{1:3}] = find (in{1 : 3});
+     [out{4:6}] = find (in{[1, 2, 4]})
+           out =
+             {
+               [1,1] = 1
+               [2,1] = 9
+               [3,1] = 90
+               [4,1] = 1
+               [3,1] = 1
+               [4,1] = 10
+             }
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comma-Separated-Lists-Generated-from-Structure-Arrays.html b/doc/interpreter/HTML/Comma-Separated-Lists-Generated-from-Structure-Arrays.html
new file mode 100644
index 0000000..59649f4
--- /dev/null
+++ b/doc/interpreter/HTML/Comma-Separated-Lists-Generated-from-Structure-Arrays.html
@@ -0,0 +1,62 @@
+<html lang="en">
+<head>
+<title>Comma Separated Lists Generated from Structure Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Comma-Separated-Lists.html#Comma-Separated-Lists" title="Comma Separated Lists">
+<link rel="prev" href="Comma-Separated-Lists-Generated-from-Cell-Arrays.html#Comma-Separated-Lists-Generated-from-Cell-Arrays" title="Comma Separated Lists Generated from Cell Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comma-Separated-Lists-Generated-from-Structure-Arrays"></a>
+Previous: <a rel="previous" accesskey="p" href="Comma-Separated-Lists-Generated-from-Cell-Arrays.html#Comma-Separated-Lists-Generated-from-Cell-Arrays">Comma Separated Lists Generated from Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.3.2 Comma Separated Lists Generated from Structure Arrays</h4>
+
+<p>Structure arrays can equally be used to create comma separated
+lists.  This is done by addressing one of the fields of a structure
+array.  For example
+
+<pre class="example">     x = ceil (randn (10, 1));
+     in = struct ("call1", {x, 3, "last"},
+                  "call2", {x, inf, "first"});
+     out = struct ("call1", cell (2, 1), "call2", cell (2, 1));
+     [out.call1] = find (in.call1);
+     [out.call2] = find (in.call2);
+</pre>
+   <!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, -->
+<!-- 2006, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comma-Separated-Lists.html b/doc/interpreter/HTML/Comma-Separated-Lists.html
new file mode 100644
index 0000000..b136914
--- /dev/null
+++ b/doc/interpreter/HTML/Comma-Separated-Lists.html
@@ -0,0 +1,82 @@
+<html lang="en">
+<head>
+<title>Comma Separated Lists - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Containers.html#Data-Containers" title="Data Containers">
+<link rel="prev" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comma-Separated-Lists"></a>
+Previous: <a rel="previous" accesskey="p" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Data-Containers.html#Data-Containers">Data Containers</a>
+<hr>
+</div>
+
+<h3 class="section">6.3 Comma Separated Lists</h3>
+
+<p><a name="index-comma-separated-lists-410"></a><a name="index-cs_002dlists-411"></a>
+Comma separated lists <a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a> are the basic argument type
+to all Octave functions - both for input and return arguments.  In the
+example
+
+<pre class="example">     max (<var>a</var>, <var>b</var>)
+</pre>
+   <p class="noindent">‘<samp><var>a</var><span class="samp">, </span><var>b</var></samp>’ is a comma separated list.  Comma separated lists
+can appear on both the right and left hand side of an assignment.  For
+example
+
+<pre class="example">     x = [1 0 1 0 0 1 1; 0 0 0 0 0 0 7];
+     [<var>i</var>, <var>j</var>] = find (<var>x</var>, 2, "last");
+</pre>
+   <p class="noindent">Here, ‘<samp><var>x</var><span class="samp">, 2, "last"</span></samp>’ is a comma separated list constituting
+the input arguments of <code>find</code>.  <code>find</code> returns a comma
+separated list of output arguments which is assigned element by
+element to the comma separated list ‘<samp><var>i</var><span class="samp">, </span><var>j</var></samp>’.
+
+   <p>Another example of where comma separated lists are used is in the
+creation of a new array with <code>[]</code> (see <a href="Matrices.html#Matrices">Matrices</a>) or the
+creation of a cell array with <code>{}</code> (see <a href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a>). In the expressions
+
+<pre class="example">     a = [1, 2, 3, 4];
+     c = {4, 5, 6, 7};
+</pre>
+   <p class="noindent">both ‘<samp><span class="samp">1, 2, 3, 4</span></samp>’ and ‘<samp><span class="samp">4, 5, 6, 7</span></samp>’ are comma separated lists.
+
+   <p>Comma separated lists cannot be directly manipulated by the
+user.  However, both structure arrays and cell arrays can be converted
+into comma separated lists, and thus used in place of explicitly
+written comma separated lists.  This feature is useful in many ways,
+as will be shown in the following subsections.
+
+<ul class="menu">
+<li><a accesskey="1" href="Comma-Separated-Lists-Generated-from-Cell-Arrays.html#Comma-Separated-Lists-Generated-from-Cell-Arrays">Comma Separated Lists Generated from Cell Arrays</a>
+<li><a accesskey="2" href="Comma-Separated-Lists-Generated-from-Structure-Arrays.html#Comma-Separated-Lists-Generated-from-Structure-Arrays">Comma Separated Lists Generated from Structure Arrays</a>
+</ul>
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> Comma-separated lists are also sometimes
+informally referred to as <dfn>cs-lists</dfn>.</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Command-Line-Editing.html b/doc/interpreter/HTML/Command-Line-Editing.html
new file mode 100644
index 0000000..e7687c1
--- /dev/null
+++ b/doc/interpreter/HTML/Command-Line-Editing.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Command Line Editing - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="prev" href="Getting-Help.html#Getting-Help" title="Getting Help">
+<link rel="next" href="Errors.html#Errors" title="Errors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Command-Line-Editing"></a>
+Next: <a rel="next" accesskey="n" href="Errors.html#Errors">Errors</a>,
+Previous: <a rel="previous" accesskey="p" href="Getting-Help.html#Getting-Help">Getting Help</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.4 Command Line Editing</h3>
+
+<p><a name="index-command_002dline-editing-104"></a><a name="index-editing-the-command-line-105"></a>
+Octave uses the GNU Readline library to provide an extensive set of
+command-line editing and history features.  Only the most common
+features are described in this manual.  In addition, all of the editing
+functions can be bound to different key strokes at the user's discretion. 
+This manual assumes no changes from the default Emacs bindings.  See the GNU
+Readline Library manual for more information on customizing Readline and
+for a complete feature list.
+
+   <p>To insert printing characters (letters, digits, symbols, etc.), simply
+type the character.  Octave will insert the character at the cursor and
+advance the cursor forward.
+
+   <p>Many of the command-line editing functions operate using control
+characters.  For example, the character <kbd>Control-a</kbd> moves the cursor
+to the beginning of the line.  To type <kbd>C-a</kbd>, hold down <CTRL>
+and then press <a>.  In the following sections, control characters
+such as <kbd>Control-a</kbd> are written as <kbd>C-a</kbd>.
+
+   <p>Another set of command-line editing functions use Meta characters.  To
+type <kbd>M-u</kbd>, hold down the <META> key and press <u>.  Depending
+on the keyboard, the <META> key may be labeled <ALT> or
+even <WINDOWS>.  If your terminal does not have a <META> key, you
+can still type Meta characters using two-character sequences starting
+with <kbd>ESC</kbd>.  Thus, to enter <kbd>M-u</kbd>, you would type
+<ESC> <u>.  The <kbd>ESC</kbd> character sequences are also allowed on
+terminals with real Meta keys.  In the following sections, Meta
+characters such as <kbd>Meta-u</kbd> are written as <kbd>M-u</kbd>.
+
+<ul class="menu">
+<li><a accesskey="1" href="Cursor-Motion.html#Cursor-Motion">Cursor Motion</a>
+<li><a accesskey="2" href="Killing-and-Yanking.html#Killing-and-Yanking">Killing and Yanking</a>
+<li><a accesskey="3" href="Commands-For-Text.html#Commands-For-Text">Commands For Text</a>
+<li><a accesskey="4" href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a>
+<li><a accesskey="5" href="Commands-For-History.html#Commands-For-History">Commands For History</a>
+<li><a accesskey="6" href="Customizing-readline.html#Customizing-readline">Customizing readline</a>
+<li><a accesskey="7" href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a>
+<li><a accesskey="8" href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Command-Line-Options.html b/doc/interpreter/HTML/Command-Line-Options.html
new file mode 100644
index 0000000..3b00ee3
--- /dev/null
+++ b/doc/interpreter/HTML/Command-Line-Options.html
@@ -0,0 +1,210 @@
+<html lang="en">
+<head>
+<title>Command Line Options - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line" title="Invoking Octave from the Command Line">
+<link rel="next" href="Startup-Files.html#Startup-Files" title="Startup Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Command-Line-Options"></a>
+Next: <a rel="next" accesskey="n" href="Startup-Files.html#Startup-Files">Startup Files</a>,
+Up: <a rel="up" accesskey="u" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">Invoking Octave from the Command Line</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.1.1 Command Line Options</h4>
+
+<p><a name="index-Octave-command-options-27"></a><a name="index-command-options-28"></a><a name="index-options_002c-Octave-command-29"></a>
+Here is a complete list of the command line options that Octave
+accepts.
+
+     <dl>
+<dt><code>--debug</code><dt><code>-d</code><dd><a name="index-g_t_0040code_007b_002d_002ddebug_007d-30"></a><a name="index-g_t_0040code_007b_002dd_007d-31"></a>Enter parser debugging mode.  Using this option will cause Octave's
+parser to print a lot of information about the commands it reads, and is
+probably only useful if you are actually trying to debug the parser.
+
+     <br><dt><code>--doc-cache-file </code><var>filename</var><dd><a name="index-g_t_0040code_007b_002d_002ddoc_002dcache_002dfile-_0040var_007bfilename_007d_007d-32"></a>Specify the name of the doc cache file to use.  The value of <var>filename</var>
+specified on the command line will override any value of
+<code>OCTAVE_DOC_CACHE_FILE</code><!-- /@w --> found in the environment, but not any commands
+in the system or user startup files that use the <code>doc_cache_file</code>
+function.
+
+     <br><dt><code>--echo-commands</code><dt><code>-x</code><dd><a name="index-g_t_0040code_007b_002d_002decho_002dcommands_007d-33"></a><a name="index-g_t_0040code_007b_002dx_007d-34"></a>Echo commands as they are executed.
+
+     <br><dt><code>--eval </code><var>code</var><dd>Evaluate <var>code</var> and exit when finished unless <code>--persist</code> is also
+specified.
+
+     <br><dt><code>--exec-path </code><var>path</var><dd><a name="index-g_t_0040code_007b_002d_002dexec_002dpath-_0040var_007bpath_007d_007d-35"></a>Specify the path to search for programs to run.  The value of <var>path</var>
+specified on the command line will override any value of
+<code>OCTAVE_EXEC_PATH</code><!-- /@w --> found in the environment, but not any commands
+in the system or user startup files that set the built-in variable
+<code>EXEC_PATH</code><!-- /@w -->.
+
+     <br><dt><code>--help</code><dt><code>-h</code><dt><code>-?</code><dd><a name="index-g_t_0040code_007b_002d_002dhelp_007d-36"></a><a name="index-g_t_0040code_007b_002dh_007d-37"></a><a name="index-g_t_0040code_007b_002d_003f_007d-38"></a>Print short help message and exit.
+
+     <br><dt><code>--image-path </code><var>path</var><dd><a name="index-g_t_0040code_007b_002d_002dimage_002dpath-_0040var_007bpath_007d_007d-39"></a>Add path to the head of the search path for images.  The value of
+<var>path</var> specified on the command line will override any value of
+<code>OCTAVE_IMAGE_PATH</code><!-- /@w --> found in the environment, but not any commands
+in the system or user startup files that set the built-in variable
+<code>IMAGE_PATH</code><!-- /@w -->.
+
+     <br><dt><code>--info-file </code><var>filename</var><dd><a name="index-g_t_0040code_007b_002d_002dinfo_002dfile-_0040var_007bfilename_007d_007d-40"></a>Specify the name of the info file to use.  The value of <var>filename</var>
+specified on the command line will override any value of
+<code>OCTAVE_INFO_FILE</code><!-- /@w --> found in the environment, but not any commands
+in the system or user startup files that use the <code>info_file</code>
+function.
+
+     <br><dt><code>--info-program </code><var>program</var><dd><a name="index-g_t_0040code_007b_002d_002dinfo_002dprogram-_0040var_007bprogram_007d_007d-41"></a>Specify the name of the info program to use.  The value of <var>program</var>
+specified on the command line will override any value of
+<code>OCTAVE_INFO_PROGRAM</code><!-- /@w --> found in the environment, but not any
+commands in the system or user startup files that use the
+<code>info_program</code> function.
+
+     <br><dt><code>--interactive</code><dt><code>-i</code><dd><a name="index-g_t_0040code_007b_002d_002dinteractive_007d-42"></a><a name="index-g_t_0040code_007b_002di_007d-43"></a>Force interactive behavior.  This can be useful for running Octave via a
+remote shell command or inside an Emacs shell buffer.  For another way
+to run Octave within Emacs, see <a href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>.
+
+     <br><dt><code>--line-editing</code><dd><a name="index-g_t_0040code_007b_002d_002dline_002dediting_007d-44"></a>Force readline use for command-line editing.
+
+     <br><dt><code>--no-history</code><dt><code>-H</code><dd><a name="index-g_t_0040code_007b_002d_002dno_002dhistory_007d-45"></a><a name="index-g_t_0040code_007b_002dH_007d-46"></a>Disable recording of command-line history.
+
+     <br><dt><code>--no-init-file</code><dd><a name="index-g_t_0040code_007b_002d_002dno_002dinit_002dfile_007d-47"></a>Don't read the initialization files <samp><span class="file">~/.octaverc</span></samp> and <samp><span class="file">.octaverc</span></samp>.
+
+     <br><dt><code>--no-init-path</code><dd><a name="index-g_t_0040code_007b_002d_002dno_002dinit_002dpath_007d-48"></a>Don't initialize the search path for function files to include default
+locations.
+
+     <br><dt><code>--no-line-editing</code><dd><a name="index-g_t_0040code_007b_002d_002dno_002dline_002dediting_007d-49"></a>Disable command-line editing.
+
+     <br><dt><code>--no-site-file</code><dd><a name="index-g_t_0040code_007b_002d_002dno_002dsite_002dfile_007d-50"></a>Don't read the site-wide <samp><span class="file">octaverc</span></samp> initialization files.
+
+     <br><dt><code>--norc</code><dt><code>-f</code><dd><a name="index-g_t_0040code_007b_002d_002dnorc_007d-51"></a><a name="index-g_t_0040code_007b_002df_007d-52"></a>Don't read any of the system or user initialization files at startup. 
+This is equivalent to using both of the options <code>--no-init-file</code>
+and <code>--no-site-file</code>.
+
+     <br><dt><code>--path </code><var>path</var><dt><code>-p </code><var>path</var><dd><a name="index-g_t_0040code_007b_002d_002dpath-_0040var_007bpath_007d_007d-53"></a><a name="index-g_t_0040code_007b_002dp-_0040var_007bpath_007d_007d-54"></a>Add path to the head of the search path for function files.  The
+value of <var>path</var> specified on the command line will override any value
+of <code>OCTAVE_PATH</code><!-- /@w --> found in the environment, but not any commands in the
+system or user startup files that set the internal load path through one
+of the path functions.
+
+     <br><dt><code>--persist</code><dd><a name="index-g_t_0040code_007b_002d_002dpersist_007d-55"></a>Go to interactive mode after <code>--eval</code> or reading from a file
+named on the command line.
+
+     <br><dt><code>--silent</code><dt><code>--quiet</code><dt><code>-q</code><dd><a name="index-g_t_0040code_007b_002d_002dsilent_007d-56"></a><a name="index-g_t_0040code_007b_002d_002dquiet_007d-57"></a><a name="index-g_t_0040code_007b_002dq_007d-58"></a>Don't print the usual greeting and version message at startup.
+
+     <br><dt><code>--traditional</code><dt><code>--braindead</code><dd><a name="index-g_t_0040code_007b_002d_002dtraditional_007d-59"></a><a name="index-g_t_0040code_007b_002d_002dbraindead_007d-60"></a>For compatibility with <span class="sc">matlab</span>, set initial values for
+user preferences to the following values
+
+     <pre class="example">          PS1                     = ">> "
+          PS2                     = ""
+          beep_on_error           = true
+          confirm_recursive_rmdir = false
+          crash_dumps_octave_core = false
+          default_save_options    = "-mat-binary"
+          fixed_point_format      = true
+          history_timestamp_format_string
+                                  = "%%-- %D %I:%M %p --%%"
+          page_screen_output      = false
+          print_empty_dimensions  = false
+</pre>
+     <p class="noindent">and disable the following warnings
+     <pre class="example">          Octave:fopen-file-in-path
+          Octave:function-name-clash
+          Octave:load-file-in-path
+</pre>
+     <br><dt><code>--verbose</code><dt><code>-V</code><dd><a name="index-g_t_0040code_007b_002d_002dverbose_007d-61"></a><a name="index-g_t_0040code_007b_002dV_007d-62"></a>Turn on verbose output.
+
+     <br><dt><code>--version</code><dt><code>-v</code><dd><a name="index-g_t_0040code_007b_002d_002dversion_007d-63"></a><a name="index-g_t_0040code_007b_002dv_007d-64"></a>Print the program version number and exit.
+
+     <br><dt><var>file</var><dd>Execute commands from <var>file</var>.  Exit when done unless
+<code>--persist</code> is also specified. 
+</dl>
+
+   <p>Octave also includes several functions which return information
+about the command line, including the number of arguments and all of the
+options.
+
+<!-- octave.cc -->
+   <p><a name="doc_002dargv"></a>
+
+<div class="defun">
+— Built-in Function:  <b>argv</b> ()<var><a name="index-argv-65"></a></var><br>
+<blockquote><p>Return the command line arguments passed to Octave.  For example,
+if you invoked Octave using the command
+
+     <pre class="example">          octave --no-line-editing --silent
+</pre>
+        <p class="noindent"><code>argv</code> would return a cell array of strings with the elements
+<code>--no-line-editing</code> and <code>--silent</code>.
+
+        <p>If you write an executable Octave script, <code>argv</code> will return the
+list of arguments passed to the script.  See <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a>,
+for an example of how to create an executable Octave script. 
+</p></blockquote></div>
+
+<!-- octave.cc -->
+   <p><a name="doc_002dprogram_005fname"></a>
+
+<div class="defun">
+— Built-in Function:  <b>program_name</b> ()<var><a name="index-program_005fname-66"></a></var><br>
+<blockquote><p>Return the last component of the value returned by
+<code>program_invocation_name</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprogram_005finvocation_005fname.html#doc_002dprogram_005finvocation_005fname">program_invocation_name</a>. 
+</p></blockquote></div>
+
+<!-- octave.cc -->
+   <p><a name="doc_002dprogram_005finvocation_005fname"></a>
+
+<div class="defun">
+— Built-in Function: program_invocation_name <b>(</b>)<var><a name="index-g_t_0028-67"></a></var><br>
+<blockquote><p>Return the name that was typed at the shell prompt to run Octave.
+
+        <p>If executing a script from the command line (e.g., <code>octave foo.m</code>)
+or using an executable Octave script, the program name is set to the
+name of the script.  See <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a>, for an example of
+how to create an executable Octave script. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprogram_005fname.html#doc_002dprogram_005fname">program_name</a>. 
+</p></blockquote></div>
+
+   <p>Here is an example of using these functions to reproduce the command
+line which invoked Octave.
+
+<pre class="example">     printf ("%s", program_name ());
+     arg_list = argv ();
+     for i = 1:nargin
+       printf (" %s", arg_list{i});
+     endfor
+     printf ("\n");
+</pre>
+   <p class="noindent">See <a href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>, for an explanation of how to retrieve objects
+from cell arrays, and <a href="Defining-Functions.html#Defining-Functions">Defining Functions</a>, for information about the
+variable <code>nargin</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Commands-For-Completion.html b/doc/interpreter/HTML/Commands-For-Completion.html
new file mode 100644
index 0000000..ed322fa
--- /dev/null
+++ b/doc/interpreter/HTML/Commands-For-Completion.html
@@ -0,0 +1,73 @@
+<html lang="en">
+<head>
+<title>Commands For Completion - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Commands-For-Text.html#Commands-For-Text" title="Commands For Text">
+<link rel="next" href="Commands-For-History.html#Commands-For-History" title="Commands For History">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Commands-For-Completion"></a>
+Next: <a rel="next" accesskey="n" href="Commands-For-History.html#Commands-For-History">Commands For History</a>,
+Previous: <a rel="previous" accesskey="p" href="Commands-For-Text.html#Commands-For-Text">Commands For Text</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.4 Letting Readline Type For You</h4>
+
+<p><a name="index-command-completion-109"></a>
+The following commands allow Octave to complete command and variable
+names for you.
+
+     <dl>
+<dt><kbd><TAB></kbd><dd>Attempt to do completion on the text before the cursor.  Octave can
+complete the names of commands and variables.
+
+     <br><dt><kbd>M-?</kbd><dd>List the possible completions of the text before the cursor. 
+</dl>
+
+<!-- input.cc -->
+   <p><a name="doc_002dcompletion_005fappend_005fchar"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>completion_append_char</b> ()<var><a name="index-completion_005fappend_005fchar-110"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>completion_append_char</b> (<var>new_val</var>)<var><a name="index-completion_005fappend_005fchar-111"></a></var><br>
+<blockquote><p>Query or set the internal character variable that is appended to
+successful command-line completion attempts.  The default
+value is <code>" "</code> (a single space). 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002dcompletion_005fmatches"></a>
+
+<div class="defun">
+— Built-in Function:  <b>completion_matches</b> (<var>hint</var>)<var><a name="index-completion_005fmatches-112"></a></var><br>
+<blockquote><p>Generate possible completions given <var>hint</var>.
+
+        <p>This function is provided for the benefit of programs like Emacs which
+might be controlling Octave and handling user input.  The current
+command number is not incremented when this function is called.  This is
+a feature, not a bug. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Commands-For-History.html b/doc/interpreter/HTML/Commands-For-History.html
new file mode 100644
index 0000000..da84bd9
--- /dev/null
+++ b/doc/interpreter/HTML/Commands-For-History.html
@@ -0,0 +1,242 @@
+<html lang="en">
+<head>
+<title>Commands For History - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Commands-For-Completion.html#Commands-For-Completion" title="Commands For Completion">
+<link rel="next" href="Customizing-readline.html#Customizing-readline" title="Customizing readline">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Commands-For-History"></a>
+Next: <a rel="next" accesskey="n" href="Customizing-readline.html#Customizing-readline">Customizing readline</a>,
+Previous: <a rel="previous" accesskey="p" href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.5 Commands For Manipulating The History</h4>
+
+<p><a name="index-command-history-113"></a><a name="index-input-history-114"></a><a name="index-history-of-commands-115"></a>
+Octave normally keeps track of the commands you type so that you can
+recall previous commands to edit or execute them again.  When you exit
+Octave, the most recent commands you have typed, up to the number
+specified by the variable <code>history_size</code>, are saved in a file. 
+When Octave starts, it loads an initial list of commands from the file
+named by the variable <code>history_file</code>.
+
+   <p>Here are the commands for simple browsing and searching the history
+list.
+
+     <dl>
+<dt><kbd><LFD></kbd><dt><kbd><RET></kbd><dd>Accept the current line regardless of where the cursor is.  If the line is
+non-empty, add it to the history list.  If the line was a history
+line, then restore the history line to its original state.
+
+     <br><dt><kbd>C-p</kbd><dd>Move `up' through the history list.
+
+     <br><dt><kbd>C-n</kbd><dd>Move `down' through the history list.
+
+     <br><dt><kbd>M-<</kbd><dd>Move to the first line in the history.
+
+     <br><dt><kbd>M-></kbd><dd>Move to the end of the input history, i.e., the line you are entering!
+
+     <br><dt><kbd>C-r</kbd><dd>Search backward starting at the current line and moving `up' through
+the history as necessary.  This is an incremental search.
+
+     <br><dt><kbd>C-s</kbd><dd>Search forward starting at the current line and moving `down' through
+the history as necessary. 
+</dl>
+
+   <p>On most terminals, you can also use the up and down arrow keys in place
+of <kbd>C-p</kbd> and <kbd>C-n</kbd> to move through the history list.
+
+   <p>In addition to the keyboard commands for moving through the history
+list, Octave provides three functions for viewing, editing, and
+re-running chunks of commands from the history list.
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002dhistory"></a>
+
+<div class="defun">
+— Command: <b>history</b><var> options<a name="index-history-116"></a></var><br>
+<blockquote><p>If invoked with no arguments, <code>history</code> displays a list of commands
+that you have executed.  Valid options are:
+
+          <dl>
+<dt><code>-w </code><var>file</var><dd>Write the current history to the file <var>file</var>.  If the name is
+omitted, use the default history file (normally <samp><span class="file">~/.octave_hist</span></samp>).
+
+          <br><dt><code>-r </code><var>file</var><dd>Read the file <var>file</var>, replacing the current history list with its
+contents.  If the name is omitted, use the default history file
+(normally <samp><span class="file">~/.octave_hist</span></samp>).
+
+          <br><dt><var>n</var><dd>Display only the most recent <var>n</var> lines of history.
+
+          <br><dt><code>-q</code><dd>Don't number the displayed lines of history.  This is useful for cutting
+and pasting commands using the X Window System. 
+</dl>
+
+        <p>For example, to display the five most recent commands that you have
+typed without displaying line numbers, use the command
+<kbd>history -q 5</kbd>. 
+</p></blockquote></div>
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002dedit_005fhistory"></a>
+
+<div class="defun">
+— Command: <b>edit_history</b> [<var>first</var>] [<var>last</var>]<var><a name="index-edit_005fhistory-117"></a></var><br>
+<blockquote><p>If invoked with no arguments, <code>edit_history</code> allows you to edit the
+history list using the editor named by the variable <code>EDITOR</code><!-- /@w -->.  The
+commands to be edited are first copied to a temporary file.  When you
+exit the editor, Octave executes the commands that remain in the file. 
+It is often more convenient to use <code>edit_history</code> to define functions
+rather than attempting to enter them directly on the command line. 
+By default, the block of commands is executed as soon as you exit the
+editor.  To avoid executing any commands, simply delete all the lines
+from the buffer before exiting the editor.
+
+        <p>The <code>edit_history</code> command takes two optional arguments specifying
+the history numbers of first and last commands to edit.  For example,
+the command
+
+     <pre class="example">          edit_history 13
+</pre>
+        <p class="noindent">extracts all the commands from the 13th through the last in the history
+list.  The command
+
+     <pre class="example">          edit_history 13 169
+</pre>
+        <p class="noindent">only extracts commands 13 through 169.  Specifying a larger number for
+the first command than the last command reverses the list of commands
+before placing them in the buffer to be edited.  If both arguments are
+omitted, the previous command in the history list is used. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drun_005fhistory.html#doc_002drun_005fhistory">run_history</a>. 
+</p></blockquote></div>
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002drun_005fhistory"></a>
+
+<div class="defun">
+— Command: <b>run_history</b> [<var>first</var>] [<var>last</var>]<var><a name="index-run_005fhistory-118"></a></var><br>
+<blockquote><p>Similar to <code>edit_history</code>, except that the editor is not invoked,
+and the commands are simply executed as they appear in the history list. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dedit_005fhistory.html#doc_002dedit_005fhistory">edit_history</a>. 
+</p></blockquote></div>
+
+<p class="noindent">Octave also allows you customize the details of when, where, and how history
+is saved.
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002dsaving_005fhistory"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>saving_history</b> ()<var><a name="index-saving_005fhistory-119"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>saving_history</b> (<var>new_val</var>)<var><a name="index-saving_005fhistory-120"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether commands entered
+on the command line are saved in the history file. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhistory_005ffile.html#doc_002dhistory_005ffile">history_file</a>, <a href="doc_002dhistory_005fsize.html#doc_002dhistory_005fsize">history_size</a>, <a href="doc_002dhistory_005ftimestamp_005fformat_005fstring.html#doc_002dhistory_005ftimestamp_005fformat_005fstring">history_timestamp_format_string</a>. 
+</p></blockquote></div>
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002dhistory_005ffile"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>history_file</b> ()<var><a name="index-history_005ffile-121"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>history_file</b> (<var>new_val</var>)<var><a name="index-history_005ffile-122"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the name of the
+file used to store command history.  The default value is
+<samp><span class="file">~/.octave_hist</span></samp>, but may be overridden by the environment
+variable <code>OCTAVE_HISTFILE</code><!-- /@w -->. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhistory_005fsize.html#doc_002dhistory_005fsize">history_size</a>, <a href="doc_002dsaving_005fhistory.html#doc_002dsaving_005fhistory">saving_history</a>, <a href="doc_002dhistory_005ftimestamp_005fformat_005fstring.html#doc_002dhistory_005ftimestamp_005fformat_005fstring">history_timestamp_format_string</a>. 
+</p></blockquote></div>
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002dhistory_005fsize"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>history_size</b> ()<var><a name="index-history_005fsize-123"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>history_size</b> (<var>new_val</var>)<var><a name="index-history_005fsize-124"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies how many entries
+to store in the history file.  The default value is <code>1024</code>,
+but may be overridden by the environment variable <code>OCTAVE_HISTSIZE</code><!-- /@w -->. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhistory_005ffile.html#doc_002dhistory_005ffile">history_file</a>, <a href="doc_002dhistory_005ftimestamp_005fformat_005fstring.html#doc_002dhistory_005ftimestamp_005fformat_005fstring">history_timestamp_format_string</a>, <a href="doc_002dsaving_005fhistory.html#doc_002dsaving_005fhistory">saving_history</a>. 
+</p></blockquote></div>
+
+<!-- oct-hist.cc -->
+   <p><a name="doc_002dhistory_005ftimestamp_005fformat_005fstring"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>history_timestamp_format_string</b> ()<var><a name="index-history_005ftimestamp_005fformat_005fstring-125"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>history_timestamp_format_string</b> (<var>new_val</var>)<var><a name="index-history_005ftimestamp_005fformat_005fstring-126"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the format string
+for the comment line that is written to the history file when Octave
+exits.  The format string is passed to <code>strftime</code>.  The default
+value is
+
+     <pre class="example">          "# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER at HOST>"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dhistory_005ffile.html#doc_002dhistory_005ffile">history_file</a>, <a href="doc_002dhistory_005fsize.html#doc_002dhistory_005fsize">history_size</a>, <a href="doc_002dsaving_005fhistory.html#doc_002dsaving_005fhistory">saving_history</a>. 
+</p></blockquote></div>
+
+<!-- defaults.cc -->
+   <p><a name="doc_002dEDITOR"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>EDITOR</b> ()<var><a name="index-EDITOR-127"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>EDITOR</b> (<var>new_val</var>)<var><a name="index-EDITOR-128"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the editor to
+use with the <code>edit_history</code> command.  The default value is taken from
+the environment variable <code>EDITOR</code><!-- /@w --> when Octave starts.  If the
+environment variable is not initialized, <code>EDITOR</code><!-- /@w --> will be set to
+<code>"emacs"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dedit_005fhistory.html#doc_002dedit_005fhistory">edit_history</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Commands-For-Text.html b/doc/interpreter/HTML/Commands-For-Text.html
new file mode 100644
index 0000000..dfa3d54
--- /dev/null
+++ b/doc/interpreter/HTML/Commands-For-Text.html
@@ -0,0 +1,66 @@
+<html lang="en">
+<head>
+<title>Commands For Text - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Killing-and-Yanking.html#Killing-and-Yanking" title="Killing and Yanking">
+<link rel="next" href="Commands-For-Completion.html#Commands-For-Completion" title="Commands For Completion">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Commands-For-Text"></a>
+Next: <a rel="next" accesskey="n" href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a>,
+Previous: <a rel="previous" accesskey="p" href="Killing-and-Yanking.html#Killing-and-Yanking">Killing and Yanking</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.3 Commands For Changing Text</h4>
+
+<p>The following commands can be used for entering characters that would
+otherwise have a special meaning (e.g., <TAB>, <kbd>C-q</kbd>, etc.), or
+for quickly correcting typing mistakes.
+
+     <dl>
+<dt><kbd>C-q</kbd><dt><kbd>C-v</kbd><dd>Add the next character that you type to the line verbatim.  This is
+how to insert things like <kbd>C-q</kbd> for example.
+
+     <br><dt><kbd>M-<TAB></kbd><dd>Insert a tab character.
+
+     <br><dt><kbd>C-t</kbd><dd>Drag the character before the cursor forward over the character at the
+cursor, also moving the cursor forward.  If the cursor is at the end of
+the line, then transpose the two characters before it.
+
+     <br><dt><kbd>M-t</kbd><dd>Drag the word behind the cursor past the word in front of the cursor
+moving the cursor over that word as well.
+
+     <br><dt><kbd>M-u</kbd><dd>Uppercase the characters following the cursor to the end of the current
+(or following) word, moving the cursor to the end of the word.
+
+     <br><dt><kbd>M-l</kbd><dd>Lowercase the characters following the cursor to the end of the current
+(or following) word, moving the cursor to the end of the word.
+
+     <br><dt><kbd>M-c</kbd><dd>Uppercase the character following the cursor (or the beginning of the
+next word if the cursor is between words), moving the cursor to the end
+of the word. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Commands.html b/doc/interpreter/HTML/Commands.html
new file mode 100644
index 0000000..87d5433
--- /dev/null
+++ b/doc/interpreter/HTML/Commands.html
@@ -0,0 +1,125 @@
+<html lang="en">
+<head>
+<title>Commands - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions" title="Function Handles Inline Functions and Anonymous Functions">
+<link rel="next" href="Organization-of-Functions.html#Organization-of-Functions" title="Organization of Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Commands"></a>
+Next: <a rel="next" accesskey="n" href="Organization-of-Functions.html#Organization-of-Functions">Organization of Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.10 Commands</h3>
+
+<p>Commands are a special class of functions that only accept string
+input arguments.  A command can be called as an ordinary function, but
+it can also be called without the parentheses like the following example
+shows
+
+<pre class="example">     my_command hello world
+</pre>
+   <p class="noindent">which is the same as
+
+<pre class="example">     my_command("hello", "world")
+</pre>
+   <p>The general form of a command call is
+
+<pre class="example">     <var>name</var> <var>arg1</var> <var>arg2</var> ...
+</pre>
+   <p class="noindent">which translates directly to
+
+<pre class="example">     <var>name</var> ("<var>arg1</var>", "<var>arg2</var>", ...)
+</pre>
+   <p>A function can be used as a command if it accepts string input arguments. 
+To do this, the function must be marked as a command, which can be done
+with the <code>mark_as_command</code> command like this
+
+<pre class="example">     mark_as_command name
+</pre>
+   <p class="noindent">where <code>name</code> is the function to be marked as a command.
+
+   <p>One difficulty of commands occurs when one of the string input arguments
+are stored in a variable.  Since Octave can't tell the difference between
+a variable name, and an ordinary string, it is not possible to pass a
+variable as input to a command.  In such a situation a command must be
+called as a function.
+
+<!-- ./deprecated/mark_as_command.m -->
+   <p><a name="doc_002dmark_005fas_005fcommand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>mark_as_command</b> (<var>name</var>)<var><a name="index-mark_005fas_005fcommand-656"></a></var><br>
+<blockquote><p>This function is obsolete and will be removed from a future
+version of Octave. 
+</p></blockquote></div>
+
+<!-- ./deprecated/unmark_command.m -->
+   <p><a name="doc_002dunmark_005fcommand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>unmark_command</b> (<var>name</var>)<var><a name="index-unmark_005fcommand-657"></a></var><br>
+<blockquote><p>This function is obsolete and will be removed from a future
+version of Octave. 
+</p></blockquote></div>
+
+<!-- ./deprecated/iscommand.m -->
+   <p><a name="doc_002discommand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>iscommand</b> (<var>name</var>)<var><a name="index-iscommand-658"></a></var><br>
+<blockquote><p>This function is obsolete and will be removed from a future
+version of Octave. 
+</p></blockquote></div>
+
+<!-- ./deprecated/mark_as_rawcommand.m -->
+   <p><a name="doc_002dmark_005fas_005frawcommand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>mark_as_rawcommand</b> (<var>name</var>)<var><a name="index-mark_005fas_005frawcommand-659"></a></var><br>
+<blockquote><p>This function is obsolete and will be removed from a future
+version of Octave. 
+</p></blockquote></div>
+
+<!-- ./deprecated/unmark_rawcommand.m -->
+   <p><a name="doc_002dunmark_005frawcommand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>unmark_rawcommand</b> (<var>name</var>)<var><a name="index-unmark_005frawcommand-660"></a></var><br>
+<blockquote><p>This function is obsolete and will be removed from a future
+version of Octave. 
+</p></blockquote></div>
+
+<!-- ./deprecated/israwcommand.m -->
+   <p><a name="doc_002disrawcommand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>israwcommand</b> (<var>name</var>)<var><a name="index-israwcommand-661"></a></var><br>
+<blockquote><p>This function is obsolete and will be removed from a future
+version of Octave. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comment-Tips.html b/doc/interpreter/HTML/Comment-Tips.html
new file mode 100644
index 0000000..388aee5
--- /dev/null
+++ b/doc/interpreter/HTML/Comment-Tips.html
@@ -0,0 +1,59 @@
+<html lang="en">
+<head>
+<title>Comment Tips - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link rel="prev" href="Coding-Tips.html#Coding-Tips" title="Coding Tips">
+<link rel="next" href="Function-Headers.html#Function-Headers" title="Function Headers">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comment-Tips"></a>
+Next: <a rel="next" accesskey="n" href="Function-Headers.html#Function-Headers">Function Headers</a>,
+Previous: <a rel="previous" accesskey="p" href="Coding-Tips.html#Coding-Tips">Coding Tips</a>,
+Up: <a rel="up" accesskey="u" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
+<hr>
+</div>
+
+<h3 class="section">C.3 Tips on Writing Comments</h3>
+
+<p>Here are the conventions to follow when writing comments.
+
+     <dl>
+<dt>‘<samp><span class="samp">#</span></samp>’<dd>Comments that start with a single sharp-sign, ‘<samp><span class="samp">#</span></samp>’, should all be
+aligned to the same column on the right of the source code.  Such
+comments usually explain how the code on the same line does its job.  In
+the Emacs mode for Octave, the <kbd>M-;</kbd> (<code>indent-for-comment</code>)
+command automatically inserts such a ‘<samp><span class="samp">#</span></samp>’ in the right place, or
+aligns such a comment if it is already present.
+
+     <br><dt>‘<samp><span class="samp">##</span></samp>’<dd>Comments that start with a double sharp-sign, ‘<samp><span class="samp">##</span></samp>’, should be aligned to
+the same level of indentation as the code.  Such comments usually
+describe the purpose of the following lines or the state of the program
+at that point. 
+</dl>
+
+<p class="noindent">The indentation commands of the Octave mode in Emacs, such as <kbd>M-;</kbd>
+(<code>indent-for-comment</code>) and <kbd>TAB</kbd> (<code>octave-indent-line</code>)
+automatically indent comments according to these conventions,
+depending on the number of semicolons.  See <a href="../emacs/Comments.html#Comments">Manipulating Comments</a>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comments-and-the-Help-System.html b/doc/interpreter/HTML/Comments-and-the-Help-System.html
new file mode 100644
index 0000000..0c8cfad
--- /dev/null
+++ b/doc/interpreter/HTML/Comments-and-the-Help-System.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Comments and the Help System - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Comments.html#Comments" title="Comments">
+<link rel="prev" href="Block-Comments.html#Block-Comments" title="Block Comments">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comments-and-the-Help-System"></a>
+Previous: <a rel="previous" accesskey="p" href="Block-Comments.html#Block-Comments">Block Comments</a>,
+Up: <a rel="up" accesskey="u" href="Comments.html#Comments">Comments</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.7.3 Comments and the Help System</h4>
+
+<p><a name="index-documenting-functions-168"></a><a name="index-documenting-user-scripts-169"></a><a name="index-help_002c-user_002ddefined-functions-170"></a>
+The <code>help</code> command (see <a href="Getting-Help.html#Getting-Help">Getting Help</a>) is able to find the first
+block of comments in a function and return those as a documentation
+string.  This means that the same commands used to get help
+on built-in functions are available for properly formatted user-defined
+functions.  For example, after defining the function <code>f</code> below,
+<pre class="example">     function xdot = f (x, t)
+     
+     # usage: f (x, t)
+     #
+     # This function defines the right-hand
+     # side functions for a set of nonlinear
+     # differential equations.
+     
+       r = 0.25;
+       ...
+     endfunction
+</pre>
+   <p>the command <kbd>help f</kbd> produces the output
+
+<pre class="example">      usage: f (x, t)
+     
+      This function defines the right-hand
+      side functions for a set of nonlinear
+      differential equations.
+</pre>
+   <p>Although it is possible to put comment lines into keyboard-composed,
+throw-away Octave programs, it usually isn't very useful because the
+purpose of a comment is to help you or another person understand the
+program at a later time.
+
+   <p>The <code>help</code> parser currently only recognizes single line comments
+(see <a href="Single-Line-Comments.html#Single-Line-Comments">Single Line Comments</a>) and not block comments for the initial
+help text.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comments.html b/doc/interpreter/HTML/Comments.html
new file mode 100644
index 0000000..68d8968
--- /dev/null
+++ b/doc/interpreter/HTML/Comments.html
@@ -0,0 +1,49 @@
+<html lang="en">
+<head>
+<title>Comments - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="prev" href="Executable-Octave-Programs.html#Executable-Octave-Programs" title="Executable Octave Programs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comments"></a>
+Previous: <a rel="previous" accesskey="p" href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.7 Comments in Octave Programs</h3>
+
+<p><a name="index-comments-159"></a><a name="index-use-of-comments-160"></a><a name="index-documenting-Octave-programs-161"></a>
+A <dfn>comment</dfn> is some text that is included in a program for the sake
+of human readers, and which is NOT an executable part of the program. 
+Comments can explain what the program does, and how it works.  Nearly all
+programming languages have provisions for comments, because programs are
+typically hard to understand without them.
+
+<ul class="menu">
+<li><a accesskey="1" href="Single-Line-Comments.html#Single-Line-Comments">Single Line Comments</a>
+<li><a accesskey="2" href="Block-Comments.html#Block-Comments">Block Comments</a>
+<li><a accesskey="3" href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">Comments and the Help System</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comparing-Strings.html b/doc/interpreter/HTML/Comparing-Strings.html
new file mode 100644
index 0000000..b7cdb54
--- /dev/null
+++ b/doc/interpreter/HTML/Comparing-Strings.html
@@ -0,0 +1,182 @@
+<html lang="en">
+<head>
+<title>Comparing Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="prev" href="Creating-Strings.html#Creating-Strings" title="Creating Strings">
+<link rel="next" href="Manipulating-Strings.html#Manipulating-Strings" title="Manipulating Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comparing-Strings"></a>
+Next: <a rel="next" accesskey="n" href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a>,
+Previous: <a rel="previous" accesskey="p" href="Creating-Strings.html#Creating-Strings">Creating Strings</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.4 Comparing Strings</h3>
+
+<p>Since a string is a character array, comparisons between strings work
+element by element as the following example shows:
+
+<pre class="example">     GNU = "GNU's Not UNIX";
+     spaces = (GNU == " ")
+           spaces =
+            0   0   0   0   0   1   0   0   0   1   0   0   0   0
+</pre>
+   <p class="noindent">To determine if two strings are identical it is necessary to use the
+<code>strcmp</code> function.  It compares complete strings and is case
+sensitive.  <code>strncmp</code> compares only the first <code>N</code> characters (with
+<code>N</code> given as a parameter).  <code>strcmpi</code> and <code>strncmpi</code> are the
+corresponding functions for case-insensitive comparison.
+
+<!-- strfns.cc -->
+   <p><a name="doc_002dstrcmp"></a>
+
+<div class="defun">
+— Built-in Function:  <b>strcmp</b> (<var>s1, s2</var>)<var><a name="index-strcmp-304"></a></var><br>
+<blockquote><p>Return 1 if the character strings <var>s1</var> and <var>s2</var> are the same,
+and 0 otherwise.
+
+        <p>If either <var>s1</var> or <var>s2</var> is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+        <p><strong>Caution:</strong> For compatibility with <span class="sc">matlab</span>, Octave's strcmp
+function returns 1 if the character strings are equal, and 0 otherwise. 
+This is just the opposite of the corresponding C library function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>, <a href="doc_002dstrncmp.html#doc_002dstrncmp">strncmp</a>, <a href="doc_002dstrncmpi.html#doc_002dstrncmpi">strncmpi</a>. 
+</p></blockquote></div>
+
+<!-- strfns.cc -->
+   <p><a name="doc_002dstrncmp"></a>
+
+<div class="defun">
+— Built-in Function:  <b>strncmp</b> (<var>s1, s2, n</var>)<var><a name="index-strncmp-305"></a></var><br>
+<blockquote><p>Return 1 if the first <var>n</var> characters of strings <var>s1</var> and <var>s2</var> are the same,
+and 0 otherwise.
+
+     <pre class="example">          strncmp ("abce", "abcd", 3)
+                1
+</pre>
+        <p>If either <var>s1</var> or <var>s2</var> is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+     <pre class="example">          strncmp ("abce", {"abcd", "bca", "abc"}, 3)
+                [1, 0, 1]
+</pre>
+        <p><strong>Caution:</strong> For compatibility with <span class="sc">matlab</span>, Octave's strncmp
+function returns 1 if the character strings are equal, and 0 otherwise. 
+This is just the opposite of the corresponding C library function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrncmpi.html#doc_002dstrncmpi">strncmpi</a>, <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strcmpi.m -->
+   <p><a name="doc_002dstrcmpi"></a>
+
+<div class="defun">
+— Function File:  <b>strcmpi</b> (<var>s1, s2</var>)<var><a name="index-strcmpi-306"></a></var><br>
+<blockquote><p>Ignoring case, return 1 if the character strings (or character
+arrays) <var>s1</var> and <var>s2</var> are the same, and 0 otherwise.
+
+        <p>If either <var>s1</var> or <var>s2</var> is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+        <p><strong>Caution:</strong> For compatibility with <span class="sc">matlab</span>, Octave's strcmpi
+function returns 1 if the character strings are equal, and 0 otherwise. 
+This is just the opposite of the corresponding C library function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrncmp.html#doc_002dstrncmp">strncmp</a>, <a href="doc_002dstrncmpi.html#doc_002dstrncmpi">strncmpi</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strncmpi.m -->
+   <p><a name="doc_002dstrncmpi"></a>
+
+<div class="defun">
+— Function File:  <b>strncmpi</b> (<var>s1, s2, n</var>)<var><a name="index-strncmpi-307"></a></var><br>
+<blockquote><p>Ignoring case, return 1 if the first <var>n</var> characters of character
+strings (or character arrays) <var>s1</var> and <var>s2</var> are the same, and
+0 otherwise.
+
+        <p>If either <var>s1</var> or <var>s2</var> is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+        <p><strong>Caution:</strong> For compatibility with <span class="sc">matlab</span>, Octave's strncmpi
+function returns 1 if the character strings are equal, and 0 otherwise. 
+This is just the opposite of the corresponding C library function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>, <a href="doc_002dstrncmp.html#doc_002dstrncmp">strncmp</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/validatestring.m -->
+   <p><a name="doc_002dvalidatestring"></a>
+
+<div class="defun">
+— Function File: <var>validstr</var> = <b>validatestring</b> (<var>str, strarray</var>)<var><a name="index-validatestring-308"></a></var><br>
+— Function File: <var>validstr</var> = <b>validatestring</b> (<var>str, strarray, funcname</var>)<var><a name="index-validatestring-309"></a></var><br>
+— Function File: <var>validstr</var> = <b>validatestring</b> (<var>str, strarray, funcname, varname</var>)<var><a name="index-validatestring-310"></a></var><br>
+— Function File: <var>validstr</var> = <b>validatestring</b> (<var><small class="dots">...</small>, position</var>)<var><a name="index-validatestring-311"></a></var><br>
+<blockquote><p>Verify that <var>str</var> is a string or substring of an element of
+<var>strarray</var>.
+
+        <p><var>str</var> is a character string to be tested, and <var>strarray</var> is a
+cellstr of valid values.  <var>validstr</var> will be the validated form
+of <var>str</var> where validation is defined as <var>str</var> being a member
+or substring of <var>validstr</var>.  If <var>str</var> is a substring of
+<var>validstr</var> and there are multiple matches, the shortest match
+will be returned if all matches are substrings of each other, and an
+error will be raised if the matches are not substrings of each other.
+
+        <p>All comparisons are case insensitive. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Comparison-Ops.html b/doc/interpreter/HTML/Comparison-Ops.html
new file mode 100644
index 0000000..94a8164
--- /dev/null
+++ b/doc/interpreter/HTML/Comparison-Ops.html
@@ -0,0 +1,100 @@
+<html lang="en">
+<head>
+<title>Comparison Ops - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Arithmetic-Ops.html#Arithmetic-Ops" title="Arithmetic Ops">
+<link rel="next" href="Boolean-Expressions.html#Boolean-Expressions" title="Boolean Expressions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Comparison-Ops"></a>
+Next: <a rel="next" accesskey="n" href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a>,
+Previous: <a rel="previous" accesskey="p" href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.4 Comparison Operators</h3>
+
+<p><a name="index-comparison-expressions-489"></a><a name="index-expressions_002c-comparison-490"></a><a name="index-relational-operators-491"></a><a name="index-operators_002c-relational-492"></a><a name="index-less-than-operator-493"></a><a name="index-greater-than-operator-494"></a><a name="index-equality-operator-495"></a><a name="index-tests-for-equality-496"></a><a name="index-equality_002c-tests-for-497"></a>
+<dfn>Comparison operators</dfn> compare numeric values for relationships
+such as equality.  They are written using
+<em>relational operators</em>.
+
+   <p>All of Octave's comparison operators return a value of 1 if the
+comparison is true, or 0 if it is false.  For matrix values, they all
+work on an element-by-element basis.  For example,
+
+<pre class="example">     [1, 2; 3, 4] == [1, 3; 2, 4]
+            1  0
+              0  1
+</pre>
+   <p>If one operand is a scalar and the other is a matrix, the scalar is
+compared to each element of the matrix in turn, and the result is the
+same size as the matrix.
+
+     <dl>
+<dt><var>x</var><code> < </code><var>y</var><dd><a name="index-g_t_003c-498"></a>True if <var>x</var> is less than <var>y</var>.
+
+     <br><dt><var>x</var><code> <= </code><var>y</var><dd><a name="index-g_t_003c_003d-499"></a>True if <var>x</var> is less than or equal to <var>y</var>.
+
+     <br><dt><var>x</var><code> == </code><var>y</var><dd><a name="index-g_t_003d_003d-500"></a>True if <var>x</var> is equal to <var>y</var>.
+
+     <br><dt><var>x</var><code> >= </code><var>y</var><dd><a name="index-g_t_003e_003d-501"></a>True if <var>x</var> is greater than or equal to <var>y</var>.
+
+     <br><dt><var>x</var><code> > </code><var>y</var><dd><a name="index-g_t_003e-502"></a>True if <var>x</var> is greater than <var>y</var>.
+
+     <br><dt><var>x</var><code> != </code><var>y</var><dt><var>x</var><code> ~= </code><var>y</var><dd><a name="index-g_t_0021_003d-503"></a><a name="index-g_t_007e_003d-504"></a>True if <var>x</var> is not equal to <var>y</var>. 
+</dl>
+
+   <p>String comparisons may also be performed with the <code>strcmp</code>
+function, not with the comparison operators listed above. 
+See <a href="Strings.html#Strings">Strings</a>.
+
+<!-- ./general/isequal.m -->
+   <p><a name="doc_002disequal"></a>
+
+<div class="defun">
+— Function File:  <b>isequal</b> (<var>x1, x2, <small class="dots">...</small></var>)<var><a name="index-isequal-505"></a></var><br>
+<blockquote><p>Return true if all of <var>x1</var>, <var>x2</var>, <small class="dots">...</small> are equal. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disequalwithequalnans.html#doc_002disequalwithequalnans">isequalwithequalnans</a>. 
+</p></blockquote></div>
+
+<!-- ./general/isequalwithequalnans.m -->
+   <p><a name="doc_002disequalwithequalnans"></a>
+
+<div class="defun">
+— Function File:  <b>isequalwithequalnans</b> (<var>x1, x2, <small class="dots">...</small></var>)<var><a name="index-isequalwithequalnans-506"></a></var><br>
+<blockquote><p>Assuming NaN == NaN, return true if all of <var>x1</var>, <var>x2</var>, <small class="dots">...</small>
+are equal. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disequal.html#doc_002disequal">isequal</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Complex-Arithmetic.html b/doc/interpreter/HTML/Complex-Arithmetic.html
new file mode 100644
index 0000000..ee39c22
--- /dev/null
+++ b/doc/interpreter/HTML/Complex-Arithmetic.html
@@ -0,0 +1,143 @@
+<html lang="en">
+<head>
+<title>Complex Arithmetic - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Exponents-and-Logarithms.html#Exponents-and-Logarithms" title="Exponents and Logarithms">
+<link rel="next" href="Trigonometry.html#Trigonometry" title="Trigonometry">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Complex-Arithmetic"></a>
+Next: <a rel="next" accesskey="n" href="Trigonometry.html#Trigonometry">Trigonometry</a>,
+Previous: <a rel="previous" accesskey="p" href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.2 Complex Arithmetic</h3>
+
+<p>In the descriptions of the following functions,
+<var>z</var> is the complex number <var>x</var> + <var>i</var><var>y</var>, where <var>i</var> is
+defined as <code>sqrt (-1)</code>.
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dabs"></a>
+
+<div class="defun">
+— Mapping Function:  <b>abs</b> (<var>z</var>)<var><a name="index-abs-1376"></a></var><br>
+<blockquote><p>Compute the magnitude of <var>z</var>, defined as
+|<var>z</var>| = <code>sqrt (x^2 + y^2)</code>.
+
+        <p>For example,
+
+     <pre class="example">          abs (3 + 4i)
+                5
+</pre>
+        </blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002darg"></a>
+
+<div class="defun">
+— Mapping Function:  <b>arg</b> (<var>z</var>)<var><a name="index-arg-1377"></a></var><br>
+— Mapping Function:  <b>angle</b> (<var>z</var>)<var><a name="index-angle-1378"></a></var><br>
+<blockquote><p>Compute the argument of <var>z</var>, defined as,
+<var>theta</var> = <code>atan2 (</code><var>y</var><code>, </code><var>x</var><code>)</code>,
+in radians.
+
+        <p>For example,
+
+     <pre class="example">          arg (3 + 4i)
+                0.92730
+</pre>
+        </blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dconj"></a>
+
+<div class="defun">
+— Mapping Function:  <b>conj</b> (<var>z</var>)<var><a name="index-conj-1379"></a></var><br>
+<blockquote><p>Return the complex conjugate of <var>z</var>, defined as
+<code>conj (</code><var>z</var><code>)</code> = <var>x</var> - <var>i</var><var>y</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dreal.html#doc_002dreal">real</a>, <a href="doc_002dimag.html#doc_002dimag">imag</a>. 
+</p></blockquote></div>
+
+<!-- ./general/cplxpair.m -->
+   <p><a name="doc_002dcplxpair"></a>
+
+<div class="defun">
+— Function File:  <b>cplxpair</b> (<var>z</var>)<var><a name="index-cplxpair-1380"></a></var><br>
+— Function File:  <b>cplxpair</b> (<var>z, tol</var>)<var><a name="index-cplxpair-1381"></a></var><br>
+— Function File:  <b>cplxpair</b> (<var>z, tol, dim</var>)<var><a name="index-cplxpair-1382"></a></var><br>
+<blockquote><p>Sort the numbers <var>z</var> into complex conjugate pairs ordered by
+increasing real part.  Place the negative imaginary complex number
+first within each pair.  Place all the real numbers (those with
+<code>abs (imag (</code><var>z</var><code>) / </code><var>z</var><code>) < </code><var>tol</var><code>)</code>) after the
+complex pairs.
+
+        <p>If <var>tol</var> is unspecified the default value is 100*<code>eps</code>.
+
+        <p>By default the complex pairs are sorted along the first non-singleton
+dimension of <var>z</var>.  If <var>dim</var> is specified, then the complex
+pairs are sorted along this dimension.
+
+        <p>Signal an error if some complex numbers could not be paired.  Signal an
+error if all complex numbers are not exact conjugates (to within
+<var>tol</var>).  Note that there is no defined order for pairs with identical
+real parts but differing imaginary parts.
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">          cplxpair (exp(2i*pi*[0:4]'/5)) == exp(2i*pi*[3; 2; 4; 1; 0]/5)
+</pre>
+        </blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dimag"></a>
+
+<div class="defun">
+— Mapping Function:  <b>imag</b> (<var>z</var>)<var><a name="index-imag-1383"></a></var><br>
+<blockquote><p>Return the imaginary part of <var>z</var> as a real number. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dreal.html#doc_002dreal">real</a>, <a href="doc_002dconj.html#doc_002dconj">conj</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dreal"></a>
+
+<div class="defun">
+— Mapping Function:  <b>real</b> (<var>z</var>)<var><a name="index-real-1384"></a></var><br>
+<blockquote><p>Return the real part of <var>z</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimag.html#doc_002dimag">imag</a>, <a href="doc_002dconj.html#doc_002dconj">conj</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Concatenating-Strings.html b/doc/interpreter/HTML/Concatenating-Strings.html
new file mode 100644
index 0000000..4fcdcca
--- /dev/null
+++ b/doc/interpreter/HTML/Concatenating-Strings.html
@@ -0,0 +1,248 @@
+<html lang="en">
+<head>
+<title>Concatenating Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Creating-Strings.html#Creating-Strings" title="Creating Strings">
+<link rel="next" href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings" title="Conversion of Numerical Data to Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Concatenating-Strings"></a>
+Next: <a rel="next" accesskey="n" href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">Conversion of Numerical Data to Strings</a>,
+Up: <a rel="up" accesskey="u" href="Creating-Strings.html#Creating-Strings">Creating Strings</a>
+<hr>
+</div>
+
+<h4 class="subsection">5.3.1 Concatenating Strings</h4>
+
+<p>It has been shown above that strings can be concatenated using matrix notation
+(see <a href="Strings.html#Strings">Strings</a>, <a href="Character-Arrays.html#Character-Arrays">Character Arrays</a>).  Apart from that, there are several
+functions to concatenate string objects: <code>char</code>,
+<code>strvcat</code>, <code>strcat</code> and <code>cstrcat</code>.  In addition, the general
+purpose concatenation functions can be used: see <a href="doc_002dcat.html#doc_002dcat">cat</a>,
+<a href="doc_002dhorzcat.html#doc_002dhorzcat">horzcat</a> and <a href="doc_002dvertcat.html#doc_002dvertcat">vertcat</a>.
+
+     <ul>
+<li>All string concatenation functions except <code>cstrcat</code>
+convert numerical input into character data by taking the corresponding ASCII
+character for each element, as in the following example:
+
+     <pre class="example">          char([98, 97, 110, 97, 110, 97])
+                ans =
+                 banana
+</pre>
+     <li><code>char</code> and <code>strvcat</code>
+concatenate vertically, while <code>strcat</code> and <code>cstrcat</code> concatenate
+horizontally.  For example:
+
+     <pre class="example">          char("an apple", "two pears")
+                ans =
+                 an apple
+                 two pears
+          
+          strcat("oc", "tave", " is", " good", " for you")
+                ans =
+                 octave is good for you
+</pre>
+     <li><code>char</code> generates an empty row in the output
+for each empty string in the input.  <code>strvcat</code>, on the other hand,
+eliminates empty strings.
+
+     <pre class="example">          char("orange", "green", "", "red")
+                ans =
+                 orange
+                 green
+          
+                 red
+          
+          strvcat("orange", "green", "", "red")
+                ans =
+                 orange
+                 green
+                 red
+</pre>
+     <li>All string concatenation functions except <code>cstrcat</code> also accept cell
+array data (see <a href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>).  <code>char</code> and
+<code>strvcat</code> convert cell arrays into character arrays, while <code>strcat</code>
+concatenates within the cells of the cell arrays:
+
+     <pre class="example">          char({"red", "green", "", "blue"})
+                ans =
+                 red
+                 green
+          
+                 blue
+          
+          strcat({"abc"; "ghi"}, {"def"; "jkl"})
+                ans =
+                 {
+                   [1,1] = abcdef
+                   [2,1] = ghijkl
+                 }
+</pre>
+     <li><code>strcat</code> removes trailing white space in the arguments (except
+within cell arrays), while <code>cstrcat</code> leaves white space untouched.  Both
+kinds of behavior can be useful as can be seen in the examples:
+
+     <pre class="example">          strcat(["dir1";"directory2"], ["/";"/"], ["file1";"file2"])
+                ans =
+                 dir1/file1
+                 directory2/file2
+          
+          cstrcat(["thirteen apples"; "a banana"], [" 5$";" 1$"])
+                ans =
+                 thirteen apples 5$
+                 a banana        1$
+</pre>
+     <p>Note that in the above example for <code>cstrcat</code>, the white space originates
+from the internal representation of the strings in a string array
+(see <a href="Character-Arrays.html#Character-Arrays">Character Arrays</a>). 
+</ul>
+
+<!-- strfns.cc -->
+   <p><a name="doc_002dchar"></a>
+
+<div class="defun">
+— Built-in Function:  <b>char</b> (<var>x</var>)<var><a name="index-char-288"></a></var><br>
+— Built-in Function:  <b>char</b> (<var>x, <small class="dots">...</small></var>)<var><a name="index-char-289"></a></var><br>
+— Built-in Function:  <b>char</b> (<var>s1, s2, <small class="dots">...</small></var>)<var><a name="index-char-290"></a></var><br>
+— Built-in Function:  <b>char</b> (<var>cell_array</var>)<var><a name="index-char-291"></a></var><br>
+<blockquote><p>Create a string array from one or more numeric matrices, character
+matrices, or cell arrays.  Arguments are concatenated vertically. 
+The returned values are padded with blanks as needed to make each row
+of the string array have the same length.  Empty input strings are
+significant and will concatenated in the output.
+
+        <p>For numerical input, each element is converted
+to the corresponding ASCII character.  A range error results if an input
+is outside the ASCII range (0-255).
+
+        <p>For cell arrays, each element is concatenated separately.  Cell arrays converted through
+<code>char</code> can mostly be converted back with <code>cellstr</code>. 
+For example,
+
+     <pre class="example">          char ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
+                ["abc    "
+                   "       "
+                   "98     "
+                   "99     "
+                   "d      "
+                   "str1   "
+                   "half   "]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrvcat.html#doc_002dstrvcat">strvcat</a>, <a href="doc_002dcellstr.html#doc_002dcellstr">cellstr</a>. 
+</p></blockquote></div>
+
+<!-- strfns.cc -->
+   <p><a name="doc_002dstrvcat"></a>
+
+<div class="defun">
+— Built-in Function:  <b>strvcat</b> (<var>x</var>)<var><a name="index-strvcat-292"></a></var><br>
+— Built-in Function:  <b>strvcat</b> (<var>x, <small class="dots">...</small></var>)<var><a name="index-strvcat-293"></a></var><br>
+— Built-in Function:  <b>strvcat</b> (<var>s1, s2, <small class="dots">...</small></var>)<var><a name="index-strvcat-294"></a></var><br>
+— Built-in Function:  <b>strvcat</b> (<var>cell_array</var>)<var><a name="index-strvcat-295"></a></var><br>
+<blockquote><p>Create a character array from one or more numeric matrices, character
+matrices, or cell arrays.  Arguments are concatenated vertically. 
+The returned values are padded with blanks as needed to make each row
+of the string array have the same length.  Unlike <code>char</code>, empty
+strings are removed and will not appear in the output.
+
+        <p>For numerical input, each element is converted
+to the corresponding ASCII character.  A range error results if an input
+is outside the ASCII range (0-255).
+
+        <p>For cell arrays, each element is concatenated separately.  Cell arrays converted through
+<code>strvcat</code> can mostly be converted back with <code>cellstr</code>. 
+For example,
+
+     <pre class="example">          strvcat ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
+                ["abc    "
+                   "98     "
+                   "99     "
+                   "d      "
+                   "str1   "
+                   "half   "]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchar.html#doc_002dchar">char</a>, <a href="doc_002dstrcat.html#doc_002dstrcat">strcat</a>, <a href="doc_002dcstrcat.html#doc_002dcstrcat">cstrcat</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strcat.m -->
+   <p><a name="doc_002dstrcat"></a>
+
+<div class="defun">
+— Function File:  <b>strcat</b> (<var>s1, s2, <small class="dots">...</small></var>)<var><a name="index-strcat-296"></a></var><br>
+<blockquote><p>Return a string containing all the arguments concatenated
+horizontally.  If the arguments are cells strings,  <code>strcat</code>
+returns a cell string with the individual cells concatenated. 
+For numerical input, each element is converted to the
+corresponding ASCII character.  Trailing white space is eliminated. 
+For example,
+
+     <pre class="example">          s = [ "ab"; "cde" ];
+          strcat (s, s, s)
+                ans =
+                  "ab ab ab "
+                  "cdecdecde"
+</pre>
+        <pre class="example">          s = { "ab"; "cde" };
+          strcat (s, s, s)
+                ans =
+                  {
+                    [1,1] = ababab
+                    [2,1] = cdecdecde
+                  }
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcstrcat.html#doc_002dcstrcat">cstrcat</a>, <a href="doc_002dchar.html#doc_002dchar">char</a>, <a href="doc_002dstrvcat.html#doc_002dstrvcat">strvcat</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/cstrcat.m -->
+   <p><a name="doc_002dcstrcat"></a>
+
+<div class="defun">
+— Function File:  <b>cstrcat</b> (<var>s1, s2, <small class="dots">...</small></var>)<var><a name="index-cstrcat-297"></a></var><br>
+<blockquote><p>Return a string containing all the arguments concatenated
+horizontally.  Trailing white space is preserved.  For example,
+
+     <pre class="example">          cstrcat ("ab   ", "cd")
+                "ab   cd"
+</pre>
+        <pre class="example">          s = [ "ab"; "cde" ];
+          cstrcat (s, s, s)
+                ans =
+                  "ab ab ab "
+                  "cdecdecde"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrcat.html#doc_002dstrcat">strcat</a>, <a href="doc_002dchar.html#doc_002dchar">char</a>, <a href="doc_002dstrvcat.html#doc_002dstrvcat">strvcat</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Concept-Index.html b/doc/interpreter/HTML/Concept-Index.html
new file mode 100644
index 0000000..0135896
--- /dev/null
+++ b/doc/interpreter/HTML/Concept-Index.html
@@ -0,0 +1,456 @@
+<html lang="en">
+<head>
+<title>Concept Index - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Copying.html#Copying" title="Copying">
+<link rel="next" href="Function-Index.html#Function-Index" title="Function Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Concept-Index"></a>
+Next: <a rel="next" accesskey="n" href="Function-Index.html#Function-Index">Function Index</a>,
+Previous: <a rel="previous" accesskey="p" href="Copying.html#Copying">Copying</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Concept Index</h2>
+
+<ul class="index-cp" compact>
+<li><a href="Single-Line-Comments.html#index-g_t_0040samp_007b_0023_007d-162">‘<samp><span class="samp">#</span></samp>’</a>: <a href="Single-Line-Comments.html#Single-Line-Comments">Single Line Comments</a></li>
+<li><a href="Executable-Octave-Programs.html#index-g_t_0040samp_007b_0023_0021_007d-158">‘<samp><span class="samp">#!</span></samp>’</a>: <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a></li>
+<li><a href="Block-Comments.html#index-g_t_0040samp_007b_0023_0040_007b_007d-166">‘<samp><span class="samp">#{</span></samp>’</a>: <a href="Block-Comments.html#Block-Comments">Block Comments</a></li>
+<li><a href="Single-Line-Comments.html#index-g_t_0040samp_007b_0025_007d-163">‘<samp><span class="samp">%</span></samp>’</a>: <a href="Single-Line-Comments.html#Single-Line-Comments">Single Line Comments</a></li>
+<li><a href="Block-Comments.html#index-g_t_0040samp_007b_0025_0040_007b_007d-167">‘<samp><span class="samp">%{</span></samp>’</a>: <a href="Block-Comments.html#Block-Comments">Block Comments</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dbraindead_007d-60"><code>--braindead</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002ddebug_007d-30"><code>--debug</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002ddoc_002dcache_002dfile-_0040var_007bfilename_007d_007d-32"><code>--doc-cache-file </code><var>filename</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002decho_002dcommands_007d-33"><code>--echo-commands</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dexec_002dpath-_0040var_007bpath_007d_007d-35"><code>--exec-path </code><var>path</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dhelp_007d-36"><code>--help</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dimage_002dpath-_0040var_007bpath_007d_007d-39"><code>--image-path </code><var>path</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dinfo_002dfile-_0040var_007bfilename_007d_007d-40"><code>--info-file </code><var>filename</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dinfo_002dprogram-_0040var_007bprogram_007d_007d-41"><code>--info-program </code><var>program</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dinteractive_007d-42"><code>--interactive</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dline_002dediting_007d-44"><code>--line-editing</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dno_002dhistory_007d-45"><code>--no-history</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dno_002dinit_002dfile_007d-47"><code>--no-init-file</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dno_002dinit_002dpath_007d-48"><code>--no-init-path</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dno_002dline_002dediting_007d-49"><code>--no-line-editing</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dno_002dsite_002dfile_007d-50"><code>--no-site-file</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dnorc_007d-51"><code>--norc</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dpath-_0040var_007bpath_007d_007d-53"><code>--path </code><var>path</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dpersist_007d-55"><code>--persist</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dquiet_007d-57"><code>--quiet</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dsilent_007d-56"><code>--silent</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dtraditional_007d-59"><code>--traditional</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dverbose_007d-61"><code>--verbose</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_002dversion_007d-63"><code>--version</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002d_003f_007d-38"><code>-?</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dd_007d-31"><code>-d</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002df_007d-52"><code>-f</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dH_007d-46"><code>-H</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dh_007d-37"><code>-h</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002di_007d-43"><code>-i</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dp-_0040var_007bpath_007d_007d-54"><code>-p </code><var>path</var></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dq_007d-58"><code>-q</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dv_007d-64"><code>-v</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dV_007d-62"><code>-V</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0040code_007b_002dx_007d-34"><code>-x</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#index-g_t_0040code_007b_002e_002e_002e_007d-continuation-marker-582"><code>...</code> continuation marker</a>: <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a></li>
+<li><a href="Startup-Files.html#index-g_t_0040code_007b_002eoctaverc_007d-76"><code>.octaverc</code></a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#index-g_t_0040code_007b_005c_007d-continuation-marker-583"><code>\</code> continuation marker</a>: <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a></li>
+<li><a href="Acknowledgements.html#index-acknowledgements-3">acknowledgements</a>: <a href="Acknowledgements.html#Acknowledgements">Acknowledgements</a></li>
+<li><a href="Arithmetic-Ops.html#index-addition-459">addition</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Boolean-Expressions.html#index-and-operator-515">and operator</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#index-anonymous-functions-645">anonymous functions</a>: <a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a></li>
+<li><a href="Variables.html#index-g_t_0040code_007bans_007d-417"><code>ans</code></a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Bug-Reporting.html#index-answers_002c-incorrect-2546">answers, incorrect</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Criteria.html#index-answers_002c-incorrect-2527">answers, incorrect</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Area-series.html#index-area-series-1233">area series</a>: <a href="Area-series.html#Area-series">Area series</a></li>
+<li><a href="Calling-Functions.html#index-arguments-in-function-call-453">arguments in function call</a>: <a href="Calling-Functions.html#Calling-Functions">Calling Functions</a></li>
+<li><a href="Arithmetic-Ops.html#index-arithmetic-operators-457">arithmetic operators</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Assignment-Ops.html#index-assignment-expressions-526">assignment expressions</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Assignment-Ops.html#index-assignment-operators-527">assignment operators</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Graphics-Objects.html#index-axes-graphics-object-1114">axes graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Axes-Properties.html#index-axes-properties-1191">axes properties</a>: <a href="Axes-Properties.html#Axes-Properties">Axes Properties</a></li>
+<li><a href="Graphics-backends.html#index-backends_002c-graphics-1253">backends, graphics</a>: <a href="Graphics-backends.html#Graphics-backends">Graphics backends</a></li>
+<li><a href="Bar-series.html#index-bar-series-1235">bar series</a>: <a href="Bar-series.html#Bar-series">Bar series</a></li>
+<li><a href="Executable-Octave-Programs.html#index-batch-processing-155">batch processing</a>: <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a></li>
+<li><a href="Block-Comments.html#index-block-comments-164">block comments</a>: <a href="Block-Comments.html#Block-Comments">Block Comments</a></li>
+<li><a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#index-body-of-a-loop-567">body of a loop</a>: <a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a></li>
+<li><a href="Boolean-Expressions.html#index-boolean-expressions-508">boolean expressions</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Boolean-Expressions.html#index-boolean-operators-512">boolean operators</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bbreak_007d-statement-573"><code>break</code> statement</a>: <a href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#The-_003ccode_003ebreak_003c_002fcode_003e-Statement">The <code>break</code> Statement</a></li>
+<li><a href="Bug-Criteria.html#index-bug-criteria-2521">bug criteria</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Bug-Lists.html#index-bug-report-mailing-lists-2538">bug report mailing lists</a>: <a href="Bug-Lists.html#Bug-Lists">Bug Lists</a></li>
+<li><a href="Reporting-Bugs.html#index-bugs-2517">bugs</a>: <a href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a></li>
+<li><a href="Bug-Reporting.html#index-bugs_002c-investigating-2549">bugs, investigating</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Trouble.html#index-bugs_002c-known-2513">bugs, known</a>: <a href="Trouble.html#Trouble">Trouble</a></li>
+<li><a href="Bug-Reporting.html#index-bugs_002c-reporting-2542">bugs, reporting</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Lists.html#index-bugs_002c-reporting-2540">bugs, reporting</a>: <a href="Bug-Lists.html#Bug-Lists">Bug Lists</a></li>
+<li><a href="Built_002din-Data-Types.html#index-built_002din-data-types-174">built-in data types</a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="A-Sample-Function-Description.html#index-built_002din-function-19">built-in function</a>: <a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a></li>
+<li><a href="Callbacks.html#index-callbacks-1216">callbacks</a>: <a href="Callbacks.html#Callbacks">Callbacks</a></li>
+<li><a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bcase_007d-statement-561"><code>case</code> statement</a>: <a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a></li>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bcatch_007d-579"><code>catch</code></a>: <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a></li>
+<li><a href="Cell-Arrays.html#index-cell-arrays-387">cell arrays</a>: <a href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a></li>
+<li><a href="Cell-Array-Objects.html#index-cell-arrays-197">cell arrays</a>: <a href="Cell-Array-Objects.html#Cell-Array-Objects">Cell Array Objects</a></li>
+<li><a href="Strings.html#index-character-strings-280">character strings</a>: <a href="Strings.html#Strings">Strings</a></li>
+<li><a href="String-Objects.html#index-character-strings-192">character strings</a>: <a href="String-Objects.html#String-Objects">String Objects</a></li>
+<li><a href="Matrix-Factorizations.html#index-Cholesky-factorization-1587">Cholesky factorization</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Cursor-Motion.html#index-clearing-the-screen-106">clearing the screen</a>: <a href="Cursor-Motion.html#Cursor-Motion">Cursor Motion</a></li>
+<li><a href="Contributing-Guidelines.html#index-coding-standards-2511">coding standards</a>: <a href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a></li>
+<li><a href="Tips-and-Standards.html#index-coding-standards-2507">coding standards</a>: <a href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a></li>
+<li><a href="Colors.html#index-colors_002c-graphics-1211">colors, graphics</a>: <a href="Colors.html#Colors">Colors</a></li>
+<li><a href="Comma-Separated-Lists.html#index-comma-separated-lists-410">comma separated lists</a>: <a href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-command-and-output-logs-143">command and output logs</a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Commands-For-Completion.html#index-command-completion-109">command completion</a>: <a href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a></li>
+<li><a href="A-Sample-Command-Description.html#index-command-descriptions-22">command descriptions</a>: <a href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-command-echoing-146">command echoing</a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Commands-For-History.html#index-command-history-113">command history</a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Command-Line-Options.html#index-command-options-28">command options</a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Command-Line-Editing.html#index-command_002dline-editing-104">command-line editing</a>: <a href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a></li>
+<li><a href="Comments.html#index-comments-159">comments</a>: <a href="Comments.html#Comments">Comments</a></li>
+<li><a href="Comparison-Ops.html#index-comparison-expressions-489">comparison expressions</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-complex_002dconjugate-transpose-471">complex-conjugate transpose</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Data-Containers.html#index-containers-368">containers</a>: <a href="Data-Containers.html#Data-Containers">Data Containers</a></li>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#index-continuation-lines-581">continuation lines</a>: <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a></li>
+<li><a href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bcontinue_007d-statement-574"><code>continue</code> statement</a>: <a href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#The-_003ccode_003econtinue_003c_002fcode_003e-Statement">The <code>continue</code> Statement</a></li>
+<li><a href="Contour-groups.html#index-contour-series-1237">contour series</a>: <a href="Contour-groups.html#Contour-groups">Contour groups</a></li>
+<li><a href="How-You-Can-Contribute-to-Octave.html#index-contributing-to-Octave-4">contributing to Octave</a>: <a href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a></li>
+<li><a href="Preface.html#index-contributors-1">contributors</a>: <a href="Preface.html#Preface">Preface</a></li>
+<li><a href="Formatted-Output.html#index-conversion-specifications-_0028_0040code_007bprintf_007d_0029-784">conversion specifications (<code>printf</code>)</a>: <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a></li>
+<li><a href="Formatted-Input.html#index-conversion-specifications-_0028_0040code_007bscanf_007d_0029-795">conversion specifications (<code>scanf</code>)</a>: <a href="Formatted-Input.html#Formatted-Input">Formatted Input</a></li>
+<li><a href="Copying.html#index-copyright-2561">copyright</a>: <a href="Copying.html#Copying">Copying</a></li>
+<li><a href="Bug-Criteria.html#index-core-dump-2523">core dump</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Comma-Separated-Lists.html#index-cs_002dlists-411">cs-lists</a>: <a href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a></li>
+<li><a href="Customizing-readline.html#index-customizing-_0040code_007breadline_007d-130">customizing <code>readline</code></a>: <a href="Customizing-readline.html#Customizing-readline">Customizing readline</a></li>
+<li><a href="Customizing-the-Prompt.html#index-customizing-the-prompt-135">customizing the prompt</a>: <a href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a></li>
+<li><a href="Differential-Equations.html#index-DAE-1785">DAE</a>: <a href="Differential-Equations.html#Differential-Equations">Differential Equations</a></li>
+<li><a href="Data-sources-in-object-groups.html#index-data-sources-in-object-groups-1228">data sources in object groups</a>: <a href="Data-sources-in-object-groups.html#Data-sources-in-object-groups">Data sources in object groups</a></li>
+<li><a href="Data-Structures.html#index-data-structures-370">data structures</a>: <a href="Data-Structures.html#Data-Structures">Data Structures</a></li>
+<li><a href="Data-Structure-Objects.html#index-data-structures-196">data structures</a>: <a href="Data-Structure-Objects.html#Data-Structure-Objects">Data Structure Objects</a></li>
+<li><a href="Data-Types.html#index-data-types-171">data types</a>: <a href="Data-Types.html#Data-Types">Data Types</a></li>
+<li><a href="Built_002din-Data-Types.html#index-data-types_002c-built_002din-173">data types, built-in</a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="User_002ddefined-Data-Types.html#index-data-types_002c-user_002ddefined-199">data types, user-defined</a>: <a href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a></li>
+<li><a href="Assignment-Ops.html#index-decrement-operator-538">decrement operator</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Default-Arguments.html#index-default-arguments-611">default arguments</a>: <a href="Default-Arguments.html#Default-Arguments">Default Arguments</a></li>
+<li><a href="Managing-Default-Properties.html#index-default-graphics-properties-1208">default graphics properties</a>: <a href="Managing-Default-Properties.html#Managing-Default-Properties">Managing Default Properties</a></li>
+<li><a href="Functions-and-Scripts.html#index-defining-functions-584">defining functions</a>: <a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a></li>
+<li><a href="Format-of-Descriptions.html#index-description-format-15">description format</a>: <a href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-diary-of-commands-and-output-142">diary of commands and output</a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Differential-Equations.html#index-Differential-Equations-1783">Differential Equations</a>: <a href="Differential-Equations.html#Differential-Equations">Differential Equations</a></li>
+<li><a href="Sending-Patches.html#index-diffs_002c-submitting-2551">diffs, submitting</a>: <a href="Sending-Patches.html#Sending-Patches">Sending Patches</a></li>
+<li><a href="Distribution.html#index-distribution-of-Octave-6">distribution of Octave</a>: <a href="Distribution.html#Distribution">Distribution</a></li>
+<li><a href="Arithmetic-Ops.html#index-division-463">division</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bdo_002duntil_007d-statement-568"><code>do-until</code> statement</a>: <a href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement">The <code>do-until</code> Statement</a></li>
+<li><a href="Fonts.html#index-documentation-fonts-10">documentation fonts</a>: <a href="Fonts.html#Fonts">Fonts</a></li>
+<li><a href="Evaluation-Notation.html#index-documentation-notation-12">documentation notation</a>: <a href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a></li>
+<li><a href="Comments-and-the-Help-System.html#index-documenting-functions-168">documenting functions</a>: <a href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">Comments and the Help System</a></li>
+<li><a href="Comments.html#index-documenting-Octave-programs-161">documenting Octave programs</a>: <a href="Comments.html#Comments">Comments</a></li>
+<li><a href="Comments-and-the-Help-System.html#index-documenting-user-scripts-169">documenting user scripts</a>: <a href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">Comments and the Help System</a></li>
+<li><a href="Mathematical-Considerations.html#index-Dulmage_002dMendelsohn-decomposition-1703">Dulmage-Mendelsohn decomposition</a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Dynamically-Linked-Functions.html#index-dynamic_002dlinking-2468">dynamic-linking</a>: <a href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-echoing-executing-commands-145">echoing executing commands</a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Command-Line-Editing.html#index-editing-the-command-line-105">editing the command line</a>: <a href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a></li>
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#index-element_002dby_002delement-evaluation-518">element-by-element evaluation</a>: <a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a></li>
+<li><a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#index-g_t_0040code_007belse_007d-statement-557"><code>else</code> statement</a>: <a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a></li>
+<li><a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#index-g_t_0040code_007belseif_007d-statement-558"><code>elseif</code> statement</a>: <a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a></li>
+<li><a href="Using-Octave-Mode.html#index-Emacs-TAGS-files-2558">Emacs TAGS files</a>: <a href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a></li>
+<li><a href="Statements.html#index-g_t_0040code_007bend_007d-statement-555"><code>end</code> statement</a>: <a href="Statements.html#Statements">Statements</a></li>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bend_005ftry_005fcatch_007d-580"><code>end_try_catch</code></a>: <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a></li>
+<li><a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bend_005funwind_005fprotect_007d-577"><code>end_unwind_protect</code></a>: <a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a></li>
+<li><a href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bendfor_007d-statement-570"><code>endfor</code> statement</a>: <a href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a></li>
+<li><a href="Defining-Functions.html#index-g_t_0040code_007bendfunction_007d-statement-589"><code>endfunction</code> statement</a>: <a href="Defining-Functions.html#Defining-Functions">Defining Functions</a></li>
+<li><a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bendif_007d-statement-559"><code>endif</code> statement</a>: <a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a></li>
+<li><a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bendswitch_007d-statement-563"><code>endswitch</code> statement</a>: <a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a></li>
+<li><a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bendwhile_007d-statement-565"><code>endwhile</code> statement</a>: <a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a></li>
+<li><a href="Comparison-Ops.html#index-equality-operator-495">equality operator</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Comparison-Ops.html#index-equality_002c-tests-for-497">equality, tests for</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Nonlinear-Equations.html#index-equations_002c-nonlinear-1632">equations, nonlinear</a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Bug-Criteria.html#index-erroneous-messages-2532">erroneous messages</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Bug-Reporting.html#index-erroneous-results-2547">erroneous results</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Criteria.html#index-erroneous-results-2528">erroneous results</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Error-bar-series.html#index-error-bar-series-1239">error bar series</a>: <a href="Error-bar-series.html#Error-bar-series">Error bar series</a></li>
+<li><a href="Error-Messages.html#index-error-message-notation-14">error message notation</a>: <a href="Error-Messages.html#Error-Messages">Error Messages</a></li>
+<li><a href="Errors.html#index-error-messages-151">error messages</a>: <a href="Errors.html#Errors">Errors</a></li>
+<li><a href="Bug-Criteria.html#index-error-messages_002c-incorrect-2534">error messages, incorrect</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Escape-Sequences-in-string-constants.html#index-escape-sequence-notation-283">escape sequence notation</a>: <a href="Escape-Sequences-in-string-constants.html#Escape-Sequences-in-string-constants">Escape Sequences in string constants</a></li>
+<li><a href="Evaluation-Notation.html#index-evaluation-notation-11">evaluation notation</a>: <a href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a></li>
+<li><a href="Executable-Octave-Programs.html#index-executable-scripts-153">executable scripts</a>: <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a></li>
+<li><a href="Coding-Tips.html#index-execution-speed-2508">execution speed</a>: <a href="Coding-Tips.html#Coding-Tips">Coding Tips</a></li>
+<li><a href="Quitting-Octave.html#index-exiting-octave-77">exiting octave</a>: <a href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a></li>
+<li><a href="Running-Octave.html#index-exiting-octave-8">exiting octave</a>: <a href="Running-Octave.html#Running-Octave">Running Octave</a></li>
+<li><a href="Arithmetic-Ops.html#index-exponentiation-467">exponentiation</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Ranges.html#index-expression_002c-range-232">expression, range</a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Expressions.html#index-expressions-447">expressions</a>: <a href="Expressions.html#Expressions">Expressions</a></li>
+<li><a href="Assignment-Ops.html#index-expressions_002c-assignment-529">expressions, assignment</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Boolean-Expressions.html#index-expressions_002c-boolean-507">expressions, boolean</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Comparison-Ops.html#index-expressions_002c-comparison-490">expressions, comparison</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Boolean-Expressions.html#index-expressions_002c-logical-509">expressions, logical</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Recursion.html#index-factorial-function-454">factorial function</a>: <a href="Recursion.html#Recursion">Recursion</a></li>
+<li><a href="Bug-Criteria.html#index-fatal-signal-2522">fatal signal</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Graphics-Objects.html#index-figure-graphics-object-1112">figure graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Figure-Properties.html#index-figure-properties-1190">figure properties</a>: <a href="Figure-Properties.html#Figure-Properties">Figure Properties</a></li>
+<li><a href="Output-Conversion-Syntax.html#index-flag-character-_0028_0040code_007bprintf_007d_0029-785">flag character (<code>printf</code>)</a>: <a href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a></li>
+<li><a href="Input-Conversion-Syntax.html#index-flag-character-_0028_0040code_007bscanf_007d_0029-797">flag character (<code>scanf</code>)</a>: <a href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">Input Conversion Syntax</a></li>
+<li><a href="Variables.html#index-flying-high-and-fast-416">flying high and fast</a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bfor_007d-statement-569"><code>for</code> statement</a>: <a href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a></li>
+<li><a href="Calling-a-Function-by-its-Name.html#index-Fordyce_002c-A_002e-P_002e-547">Fordyce, A. P.</a>: <a href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-Frobenius-norm-1573">Frobenius norm</a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="A-Sample-Function-Description.html#index-function-descriptions-16">function descriptions</a>: <a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a></li>
+<li><a href="Function-Files.html#index-function-file-612">function file</a>: <a href="Function-Files.html#Function-Files">Function Files</a></li>
+<li><a href="A-Sample-Function-Description.html#index-function-file-18">function file</a>: <a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a></li>
+<li><a href="Defining-Functions.html#index-g_t_0040code_007bfunction_007d-statement-588"><code>function</code> statement</a>: <a href="Defining-Functions.html#Defining-Functions">Defining Functions</a></li>
+<li><a href="Functions-and-Scripts.html#index-functions_002c-user_002ddefined-586">functions, user-defined</a>: <a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a></li>
+<li><a href="How-You-Can-Contribute-to-Octave.html#index-funding-Octave-development-5">funding Octave development</a>: <a href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-general-p_002dnorm-1574">general p-norm</a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Variables.html#index-getting-a-good-job-415">getting a good job</a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Global-Variables.html#index-g_t_0040code_007bglobal_007d-statement-424"><code>global</code> statement</a>: <a href="Global-Variables.html#Global-Variables">Global Variables</a></li>
+<li><a href="Global-Variables.html#index-global-variables-423">global variables</a>: <a href="Global-Variables.html#Global-Variables">Global Variables</a></li>
+<li><a href="Interaction-with-gnuplot.html#index-gnuplot-interaction-1257">gnuplot interaction</a>: <a href="Interaction-with-gnuplot.html#Interaction-with-gnuplot">Interaction with gnuplot</a></li>
+<li><a href="Plotting.html#index-graphics-816">graphics</a>: <a href="Plotting.html#Plotting">Plotting</a></li>
+<li><a href="Graphics-backends.html#index-graphics-backends-1252">graphics backends</a>: <a href="Graphics-backends.html#Graphics-backends">Graphics backends</a></li>
+<li><a href="Colors.html#index-graphics-colors-1210">graphics colors</a>: <a href="Colors.html#Colors">Colors</a></li>
+<li><a href="Line-Styles.html#index-graphics-line-styles-1213">graphics line styles</a>: <a href="Line-Styles.html#Line-Styles">Line Styles</a></li>
+<li><a href="Marker-Styles.html#index-graphics-marker-styles-1214">graphics marker styles</a>: <a href="Marker-Styles.html#Marker-Styles">Marker Styles</a></li>
+<li><a href="Graphics-Object-Properties.html#index-graphics-object-properties-1189">graphics object properties</a>: <a href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-axes-1115">graphics object, axes</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-figure-1113">graphics object, figure</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-image-1121">graphics object, image</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-line-1117">graphics object, line</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-patch-1123">graphics object, patch</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-root-figure-1111">graphics object, root figure</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-surface-1125">graphics object, surface</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-graphics-object_002c-text-1119">graphics object, text</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Managing-Default-Properties.html#index-graphics-properties_002c-default-1209">graphics properties, default</a>: <a href="Managing-Default-Properties.html#Managing-Default-Properties">Managing Default Properties</a></li>
+<li><a href="Comparison-Ops.html#index-greater-than-operator-494">greater than operator</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Surface-group.html#index-group-objects-1250">group objects</a>: <a href="Surface-group.html#Surface-group">Surface group</a></li>
+<li><a href="Stair-group.html#index-group-objects-1246">group objects</a>: <a href="Stair-group.html#Stair-group">Stair group</a></li>
+<li><a href="Scatter-group.html#index-group-objects-1244">group objects</a>: <a href="Scatter-group.html#Scatter-group">Scatter group</a></li>
+<li><a href="Quiver-group.html#index-group-objects-1242">group objects</a>: <a href="Quiver-group.html#Quiver-group">Quiver group</a></li>
+<li><a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#index-handle_002c-function-handles-643">handle, function handles</a>: <a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a></li>
+<li><a href="Function-Headers.html#index-header-comments-2510">header comments</a>: <a href="Function-Headers.html#Function-Headers">Function Headers</a></li>
+<li><a href="Getting-Help.html#index-help_002c-on_002dline-84">help, on-line</a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Comments-and-the-Help-System.html#index-help_002c-user_002ddefined-functions-170">help, user-defined functions</a>: <a href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">Comments and the Help System</a></li>
+<li><a href="Service.html#index-help_002c-where-to-find-2555">help, where to find</a>: <a href="Service.html#Service">Service</a></li>
+<li><a href="Arithmetic-Ops.html#index-Hermitian-operator-469">Hermitian operator</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Matrix-Factorizations.html#index-Hessenberg-decomposition-1596">Hessenberg decomposition</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Preface.html#index-history-2">history</a>: <a href="Preface.html#Preface">Preface</a></li>
+<li><a href="Commands-For-History.html#index-history-of-commands-115">history of commands</a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bif_007d-statement-556"><code>if</code> statement</a>: <a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a></li>
+<li><a href="Graphics-Objects.html#index-image-graphics-object-1120">image graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Image-Properties.html#index-image-properties-1194">image properties</a>: <a href="Image-Properties.html#Image-Properties">Image Properties</a></li>
+<li><a href="Sending-Patches.html#index-improving-Octave-2550">improving Octave</a>: <a href="Sending-Patches.html#Sending-Patches">Sending Patches</a></li>
+<li><a href="Bug-Criteria.html#index-improving-Octave-2536">improving Octave</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Bug-Criteria.html#index-incorrect-error-messages-2533">incorrect error messages</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Bug-Reporting.html#index-incorrect-output-2543">incorrect output</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Criteria.html#index-incorrect-output-2524">incorrect output</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Bug-Reporting.html#index-incorrect-results-2544">incorrect results</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Criteria.html#index-incorrect-results-2525">incorrect results</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Assignment-Ops.html#index-increment-operator-537">increment operator</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-infinity-norm-1572">infinity norm</a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Startup-Files.html#index-initialization-68">initialization</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#index-inline_002c-inline-functions-644">inline, inline functions</a>: <a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a></li>
+<li><a href="Table-of-Input-Conversions.html#index-input-conversions_002c-for-_0040code_007bscanf_007d-799">input conversions, for <code>scanf</code></a>: <a href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">Table of Input Conversions</a></li>
+<li><a href="Commands-For-History.html#index-input-history-114">input history</a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Trouble.html#index-installation-trouble-2514">installation trouble</a>: <a href="Trouble.html#Trouble">Trouble</a></li>
+<li><a href="Installation.html#index-installing-Octave-2556">installing Octave</a>: <a href="Installation.html#Installation">Installation</a></li>
+<li><a href="Introduction.html#index-introduction-7">introduction</a>: <a href="Introduction.html#Introduction">Introduction</a></li>
+<li><a href="Bug-Criteria.html#index-invalid-input-2535">invalid input</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Variables.html#index-job-hunting-414">job hunting</a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Trouble.html#index-known-causes-of-trouble-2515">known causes of trouble</a>: <a href="Trouble.html#Trouble">Trouble</a></li>
+<li><a href="Comparison-Ops.html#index-less-than-operator-493">less than operator</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Graphics-Objects.html#index-line-graphics-object-1116">line graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Line-Properties.html#index-line-properties-1192">line properties</a>: <a href="Line-Properties.html#Line-Properties">Line Properties</a></li>
+<li><a href="Line-series.html#index-line-series-1241">line series</a>: <a href="Line-series.html#Line-series">Line series</a></li>
+<li><a href="Line-Styles.html#index-line-styles_002c-graphics-1212">line styles, graphics</a>: <a href="Line-Styles.html#Line-Styles">Line Styles</a></li>
+<li><a href="A-Sample-Function-Description.html#index-loadable-function-20">loadable function</a>: <a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a></li>
+<li><a href="Simple-File-I_002fO.html#index-loading-data-728">loading data</a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-logging-commands-and-output-144">logging commands and output</a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Boolean-Expressions.html#index-logical-expressions-510">logical expressions</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Boolean-Expressions.html#index-logical-operators-513">logical operators</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#index-loop-566">loop</a>: <a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a></li>
+<li><a href="Looping-Over-Structure-Elements.html#index-looping-over-structure-elements-572">looping over structure elements</a>: <a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a></li>
+<li><a href="Optimization.html#index-LP-1798">LP</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Iterative-Techniques.html#index-LU-decomposition-1759">LU decomposition</a>: <a href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a></li>
+<li><a href="Matrix-Factorizations.html#index-LU-decomposition-1603">LU decomposition</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Assignment-Ops.html#index-lvalue-532">lvalue</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="A-Sample-Function-Description.html#index-mapping-function-21">mapping function</a>: <a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a></li>
+<li><a href="Marker-Styles.html#index-marker-styles_002c-graphics-1215">marker styles, graphics</a>: <a href="Marker-Styles.html#Marker-Styles">Marker Styles</a></li>
+<li><a href="Formatted-Input.html#index-matching-failure_002c-in-_0040code_007bscanf_007d-796">matching failure, in <code>scanf</code></a>: <a href="Formatted-Input.html#Formatted-Input">Formatted Input</a></li>
+<li><a href="Matrices.html#index-matrices-216">matrices</a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Arithmetic-Ops.html#index-matrix-multiplication-462">matrix multiplication</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Input-Conversion-Syntax.html#index-maximum-field-width-_0028_0040code_007bscanf_007d_0029-798">maximum field width (<code>scanf</code>)</a>: <a href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">Input Conversion Syntax</a></li>
+<li><a href="Errors.html#index-messages_002c-error-152">messages, error</a>: <a href="Errors.html#Errors">Errors</a></li>
+<li><a href="Mex_002dFiles.html#index-mex-2481">mex</a>: <a href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a></li>
+<li><a href="Mex_002dFiles.html#index-mex_002dfiles-2480">mex-files</a>: <a href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a></li>
+<li><a href="Output-Conversion-Syntax.html#index-minimum-field-width-_0028_0040code_007bprintf_007d_0029-786">minimum field width (<code>printf</code>)</a>: <a href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a></li>
+<li><a href="Missing-Data.html#index-missing-data-184">missing data</a>: <a href="Missing-Data.html#Missing-Data">Missing Data</a></li>
+<li><a href="Oct_002dFiles.html#index-mkoctfile-2470">mkoctfile</a>: <a href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a></li>
+<li><a href="Block-Comments.html#index-multi_002dline-comments-165">multi-line comments</a>: <a href="Block-Comments.html#Block-Comments">Block Comments</a></li>
+<li><a href="Arithmetic-Ops.html#index-multiplication-461">multiplication</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-negation-465">negation</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Optimization.html#index-NLP-1800">NLP</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Nonlinear-Equations.html#index-nonlinear-equations-1631">nonlinear equations</a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Optimization.html#index-nonlinear-programming-1796">nonlinear programming</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Boolean-Expressions.html#index-not-operator-517">not operator</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Numeric-Data-Types.html#index-numeric-constant-211">numeric constant</a>: <a href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a></li>
+<li><a href="Numeric-Objects.html#index-numeric-constant-182">numeric constant</a>: <a href="Numeric-Objects.html#Numeric-Objects">Numeric Objects</a></li>
+<li><a href="Numeric-Data-Types.html#index-numeric-value-212">numeric value</a>: <a href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a></li>
+<li><a href="Numeric-Objects.html#index-numeric-value-183">numeric value</a>: <a href="Numeric-Objects.html#Numeric-Objects">Numeric Objects</a></li>
+<li><a href="Object-Groups.html#index-object-groups-1220">object groups</a>: <a href="Object-Groups.html#Object-Groups">Object Groups</a></li>
+<li><a href="Oct_002dFiles.html#index-oct-2471">oct</a>: <a href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a></li>
+<li><a href="Oct_002dFiles.html#index-oct_002dfiles-2469">oct-files</a>: <a href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a></li>
+<li><a href="Command-Line-Options.html#index-Octave-command-options-27">Octave command options</a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Contributing-Guidelines.html#index-Octave-development-2512">Octave development</a>: <a href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a></li>
+<li><a href="Using-Octave-Mode.html#index-g_t_0040code_007boctave_002dtags_007d-2559"><code>octave-tags</code></a>: <a href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a></li>
+<li><a href="Differential-Equations.html#index-ODE-1784">ODE</a>: <a href="Differential-Equations.html#Differential-Equations">Differential Equations</a></li>
+<li><a href="Getting-Help.html#index-on_002dline-help-83">on-line help</a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Operator-Precedence.html#index-operator-precedence-545">operator precedence</a>: <a href="Operator-Precedence.html#Operator-Precedence">Operator Precedence</a></li>
+<li><a href="Arithmetic-Ops.html#index-operators_002c-arithmetic-458">operators, arithmetic</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Assignment-Ops.html#index-operators_002c-assignment-528">operators, assignment</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Boolean-Expressions.html#index-operators_002c-boolean-511">operators, boolean</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Assignment-Ops.html#index-operators_002c-decrement-540">operators, decrement</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Assignment-Ops.html#index-operators_002c-increment-539">operators, increment</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Boolean-Expressions.html#index-operators_002c-logical-514">operators, logical</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Comparison-Ops.html#index-operators_002c-relational-492">operators, relational</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Optimization.html#index-optimization-1797">optimization</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Command-Line-Options.html#index-options_002c-Octave-command-29">options, Octave command</a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Boolean-Expressions.html#index-or-operator-516">or operator</a>: <a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-oregonator-1788">oregonator</a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#index-g_t_0040code_007botherwise_007d-statement-562"><code>otherwise</code> statement</a>: <a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a></li>
+<li><a href="Table-of-Output-Conversions.html#index-output-conversions_002c-for-_0040code_007bprintf_007d-788">output conversions, for <code>printf</code></a>: <a href="Table-of-Output-Conversions.html#Table-of-Output-Conversions">Table of Output Conversions</a></li>
+<li><a href="Graphics-Objects.html#index-patch-graphics-object-1122">patch graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Patch-Properties.html#index-patch-properties-1195">patch properties</a>: <a href="Patch-Properties.html#Patch-Properties">Patch Properties</a></li>
+<li><a href="Sending-Patches.html#index-patches_002c-submitting-2552">patches, submitting</a>: <a href="Sending-Patches.html#Sending-Patches">Sending Patches</a></li>
+<li><a href="Persistent-Variables.html#index-g_t_0040code_007bpersistent_007d-statement-428"><code>persistent</code> statement</a>: <a href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a></li>
+<li><a href="Persistent-Variables.html#index-persistent-variables-427">persistent variables</a>: <a href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a></li>
+<li><a href="Startup-Files.html#index-personal-startup-file-73">personal startup file</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Plotting.html#index-plotting-815">plotting</a>: <a href="Plotting.html#Plotting">Plotting</a></li>
+<li><a href="Output-Conversion-Syntax.html#index-precision-_0028_0040code_007bprintf_007d_0029-787">precision (<code>printf</code>)</a>: <a href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a></li>
+<li><a href="Printing-Notation.html#index-printing-notation-13">printing notation</a>: <a href="Printing-Notation.html#Printing-Notation">Printing Notation</a></li>
+<li><a href="Executable-Octave-Programs.html#index-program_002c-self-contained-157">program, self contained</a>: <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a></li>
+<li><a href="Startup-Files.html#index-project-startup-file-75">project startup file</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Customizing-the-Prompt.html#index-prompt-customization-134">prompt customization</a>: <a href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a></li>
+<li><a href="Optimization.html#index-QP-1799">QP</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Matrix-Factorizations.html#index-QR-factorization-1606">QR factorization</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Optimization.html#index-quadratic-programming-1795">quadratic programming</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Quitting-Octave.html#index-quitting-octave-78">quitting octave</a>: <a href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a></li>
+<li><a href="Running-Octave.html#index-quitting-octave-9">quitting octave</a>: <a href="Running-Octave.html#Running-Octave">Running Octave</a></li>
+<li><a href="Quiver-group.html#index-quiver-group-1243">quiver group</a>: <a href="Quiver-group.html#Quiver-group">Quiver group</a></li>
+<li><a href="Arithmetic-Ops.html#index-quotient-464">quotient</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Ranges.html#index-range-expressions-231">range expressions</a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Customizing-readline.html#index-g_t_0040code_007breadline_007d-customization-131"><code>readline</code> customization</a>: <a href="Customizing-readline.html#Customizing-readline">Customizing readline</a></li>
+<li><a href="Comparison-Ops.html#index-relational-operators-491">relational operators</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Bug-Lists.html#index-reporting-bugs-2539">reporting bugs</a>: <a href="Bug-Lists.html#Bug-Lists">Bug Lists</a></li>
+<li><a href="Reporting-Bugs.html#index-reporting-bugs-2518">reporting bugs</a>: <a href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a></li>
+<li><a href="Bug-Reporting.html#index-results_002c-incorrect-2545">results, incorrect</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Criteria.html#index-results_002c-incorrect-2526">results, incorrect</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Graphics-Objects.html#index-root-figure-graphics-object-1110">root figure graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Simple-File-I_002fO.html#index-saving-data-727">saving data</a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Scatter-group.html#index-scatter-group-1245">scatter group</a>: <a href="Scatter-group.html#Scatter-group">Scatter group</a></li>
+<li><a href="Matrix-Factorizations.html#index-Schur-decomposition-1615">Schur decomposition</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Functions-and-Scripts.html#index-script-files-587">script files</a>: <a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a></li>
+<li><a href="Executable-Octave-Programs.html#index-scripts-154">scripts</a>: <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a></li>
+<li><a href="Executable-Octave-Programs.html#index-self-contained-programs-156">self contained programs</a>: <a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a></li>
+<li><a href="Stem-Series.html#index-series-objects-1248">series objects</a>: <a href="Stem-Series.html#Stem-Series">Stem Series</a></li>
+<li><a href="Line-series.html#index-series-objects-1240">series objects</a>: <a href="Line-series.html#Line-series">Line series</a></li>
+<li><a href="Error-bar-series.html#index-series-objects-1238">series objects</a>: <a href="Error-bar-series.html#Error-bar-series">Error bar series</a></li>
+<li><a href="Contour-groups.html#index-series-objects-1236">series objects</a>: <a href="Contour-groups.html#Contour-groups">Contour groups</a></li>
+<li><a href="Bar-series.html#index-series-objects-1234">series objects</a>: <a href="Bar-series.html#Bar-series">Bar series</a></li>
+<li><a href="Area-series.html#index-series-objects-1232">series objects</a>: <a href="Area-series.html#Area-series">Area series</a></li>
+<li><a href="Short_002dcircuit-Boolean-Operators.html#index-short_002dcircuit-evaluation-523">short-circuit evaluation</a>: <a href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">Short-circuit Boolean Operators</a></li>
+<li><a href="Assignment-Ops.html#index-side-effect-531">side effect</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Matrix-Factorizations.html#index-singular-value-decomposition-1619">singular value decomposition</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Startup-Files.html#index-site-startup-file-71">site startup file</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Coding-Tips.html#index-speedups-2509">speedups</a>: <a href="Coding-Tips.html#Coding-Tips">Coding Tips</a></li>
+<li><a href="Stair-group.html#index-stair-group-1247">stair group</a>: <a href="Stair-group.html#Stair-group">Stair group</a></li>
+<li><a href="Tips-and-Standards.html#index-standards-of-coding-style-2506">standards of coding style</a>: <a href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a></li>
+<li><a href="Startup-Files.html#index-startup-69">startup</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Startup-Files.html#index-startup-files-70">startup files</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Statements.html#index-statements-554">statements</a>: <a href="Statements.html#Statements">Statements</a></li>
+<li><a href="Stem-Series.html#index-stem-series-1249">stem series</a>: <a href="Stem-Series.html#Stem-Series">Stem Series</a></li>
+<li><a href="Strings.html#index-strings-279">strings</a>: <a href="Strings.html#Strings">Strings</a></li>
+<li><a href="String-Objects.html#index-strings-191">strings</a>: <a href="String-Objects.html#String-Objects">String Objects</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-Structural-Rank-1724">Structural Rank</a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Looping-Over-Structure-Elements.html#index-structure-elements_002c-looping-over-571">structure elements, looping over</a>: <a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a></li>
+<li><a href="Data-Structures.html#index-structures-369">structures</a>: <a href="Data-Structures.html#Data-Structures">Data Structures</a></li>
+<li><a href="Data-Structure-Objects.html#index-structures-195">structures</a>: <a href="Data-Structure-Objects.html#Data-Structure-Objects">Data Structure Objects</a></li>
+<li><a href="Sending-Patches.html#index-submitting-diffs-2553">submitting diffs</a>: <a href="Sending-Patches.html#Sending-Patches">Sending Patches</a></li>
+<li><a href="Sending-Patches.html#index-submitting-patches-2554">submitting patches</a>: <a href="Sending-Patches.html#Sending-Patches">Sending Patches</a></li>
+<li><a href="Arithmetic-Ops.html#index-subtraction-460">subtraction</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Bug-Criteria.html#index-suggestions-2537">suggestions</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Graphics-Objects.html#index-surface-graphics-object-1124">surface graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Surface-group.html#index-surface-group-1251">surface group</a>: <a href="Surface-group.html#Surface-group">Surface group</a></li>
+<li><a href="Surface-Properties.html#index-surface-properties-1196">surface properties</a>: <a href="Surface-Properties.html#Surface-Properties">Surface Properties</a></li>
+<li><a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bswitch_007d-statement-560"><code>switch</code> statement</a>: <a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a></li>
+<li><a href="Using-Octave-Mode.html#index-TAGS-2557">TAGS</a>: <a href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a></li>
+<li><a href="Test-and-Demo-Functions.html#index-test-functions-2484">test functions</a>: <a href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a></li>
+<li><a href="Comparison-Ops.html#index-tests-for-equality-496">tests for equality</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Graphics-Objects.html#index-text-graphics-object-1118">text graphics object</a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Text-Properties.html#index-text-properties-1193">text properties</a>: <a href="Text-Properties.html#Text-Properties">Text Properties</a></li>
+<li><a href="Tips-and-Standards.html#index-tips-2505">tips</a>: <a href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a></li>
+<li><a href="Arithmetic-Ops.html#index-transpose-468">transpose</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-transpose_002c-complex_002dconjugate-470">transpose, complex-conjugate</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Trouble.html#index-troubleshooting-2516">troubleshooting</a>: <a href="Trouble.html#Trouble">Trouble</a></li>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#index-g_t_0040code_007btry_007d-statement-578"><code>try</code> statement</a>: <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a></li>
+<li><a href="Arithmetic-Ops.html#index-unary-minus-466">unary minus</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Bug-Criteria.html#index-undefined-behavior-2530">undefined behavior</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Bug-Criteria.html#index-undefined-function-value-2531">undefined function value</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bunwind_005fprotect_007d-statement-575"><code>unwind_protect</code> statement</a>: <a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a></li>
+<li><a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bunwind_005fprotect_005fcleanup_007d-576"><code>unwind_protect_cleanup</code></a>: <a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a></li>
+<li><a href="Comments.html#index-use-of-comments-160">use of comments</a>: <a href="Comments.html#Comments">Comments</a></li>
+<li><a href="User_002ddefined-Data-Types.html#index-user_002ddefined-data-types-198">user-defined data types</a>: <a href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a></li>
+<li><a href="Functions-and-Scripts.html#index-user_002ddefined-functions-585">user-defined functions</a>: <a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a></li>
+<li><a href="Variables.html#index-user_002ddefined-variables-413">user-defined variables</a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Variable_002dlength-Argument-Lists.html#index-g_t_0040code_007bvarargin_007d-604"><code>varargin</code></a>: <a href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a></li>
+<li><a href="Variable_002dlength-Return-Lists.html#index-g_t_0040code_007bvarargout_007d-607"><code>varargout</code></a>: <a href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a></li>
+<li><a href="A-Sample-Variable-Description.html#index-variable-descriptions-25">variable descriptions</a>: <a href="A-Sample-Variable-Description.html#A-Sample-Variable-Description">A Sample Variable Description</a></li>
+<li><a href="Variable_002dlength-Argument-Lists.html#index-variable_002dlength-argument-lists-603">variable-length argument lists</a>: <a href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a></li>
+<li><a href="Variable_002dlength-Return-Lists.html#index-variable_002dlength-return-lists-606">variable-length return lists</a>: <a href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a></li>
+<li><a href="Global-Variables.html#index-variables_002c-global-425">variables, global</a>: <a href="Global-Variables.html#Global-Variables">Global Variables</a></li>
+<li><a href="Persistent-Variables.html#index-variables_002c-persistent-429">variables, persistent</a>: <a href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a></li>
+<li><a href="Variables.html#index-variables_002c-user_002ddefined-412">variables, user-defined</a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Startup-Files.html#index-version-startup-file-72">version startup file</a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+<li><a href="Copying.html#index-warranty-2560">warranty</a>: <a href="Copying.html#Copying">Copying</a></li>
+<li><a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#index-g_t_0040code_007bwhile_007d-statement-564"><code>while</code> statement</a>: <a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a></li>
+<li><a href="Bug-Reporting.html#index-wrong-answers-2548">wrong answers</a>: <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a></li>
+<li><a href="Bug-Criteria.html#index-wrong-answers-2529">wrong answers</a>: <a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a></li>
+<li><a href="Customizing-readline.html#index-g_t_0040file_007b_007e_002f_002einputrc_007d-129"><samp><span class="file">~/.inputrc</span></samp></a>: <a href="Customizing-readline.html#Customizing-readline">Customizing readline</a></li>
+<li><a href="Startup-Files.html#index-g_t_0040code_007b_007e_002f_002eoctaverc_007d-74"><code>~/.octaverc</code></a>: <a href="Startup-Files.html#Startup-Files">Startup Files</a></li>
+   </ul><!-- @include vr-idx.texi -->
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+</body></html>
+
diff --git a/doc/interpreter/HTML/Continuation-Lines.html b/doc/interpreter/HTML/Continuation-Lines.html
new file mode 100644
index 0000000..b4a1dd6
--- /dev/null
+++ b/doc/interpreter/HTML/Continuation-Lines.html
@@ -0,0 +1,89 @@
+<html lang="en">
+<head>
+<title>Continuation Lines - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007btry_007d-Statement.html#The-_0040code_007btry_007d-Statement" title="The @code{try} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Continuation-Lines"></a>
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.10 Continuation Lines</h3>
+
+<p>In the Octave language, most statements end with a newline character and
+you must tell Octave to ignore the newline character in order to
+continue a statement from one line to the next.  Lines that end with the
+characters <code>...</code> or <code>\</code> are joined with the following line
+before they are divided into tokens by Octave's parser.  For example,
+the lines
+
+<pre class="example">     x = long_variable_name ...
+         + longer_variable_name \
+         - 42
+</pre>
+   <p class="noindent">form a single statement.  The backslash character on the second line
+above is interpreted as a continuation character, <em>not</em> as a division
+operator.
+
+   <p>For continuation lines that do not occur inside string constants,
+whitespace and comments may appear between the continuation marker and
+the newline character.  For example, the statement
+
+<pre class="example">     x = long_variable_name ...     # comment one
+         + longer_variable_name \   # comment two
+         - 42                       # last comment
+</pre>
+   <p class="noindent">is equivalent to the one shown above.  Inside string constants, the
+continuation marker must appear at the end of the line just before the
+newline character.
+
+   <p>Input that occurs inside parentheses can be continued to the next line
+without having to use a continuation marker.  For example, it is
+possible to write statements like
+
+<pre class="example">     if (fine_dining_destination == on_a_boat
+         || fine_dining_destination == on_a_train)
+       seuss (i, will, not, eat, them, sam, i, am, i,
+              will, not, eat, green, eggs, and, ham);
+     endif
+</pre>
+   <p class="noindent">without having to add to the clutter with continuation markers.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Contour-groups.html b/doc/interpreter/HTML/Contour-groups.html
new file mode 100644
index 0000000..ab3309a
--- /dev/null
+++ b/doc/interpreter/HTML/Contour-groups.html
@@ -0,0 +1,87 @@
+<html lang="en">
+<head>
+<title>Contour groups - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Bar-series.html#Bar-series" title="Bar series">
+<link rel="next" href="Error-bar-series.html#Error-bar-series" title="Error bar series">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Contour-groups"></a>
+Next: <a rel="next" accesskey="n" href="Error-bar-series.html#Error-bar-series">Error bar series</a>,
+Previous: <a rel="previous" accesskey="p" href="Bar-series.html#Bar-series">Bar series</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.4 Contour groups</h5>
+
+<p><a name="index-series-objects-1236"></a><a name="index-contour-series-1237"></a>
+Contour group objects are created by the <code>contour</code>, <code>contourf</code>
+and <code>contour3</code> functions.  The are equally one of the handles returned
+by the <code>surfc</code> and <code>meshc</code> functions.  The properties of the contour
+group are
+
+     <dl>
+<dt><code>contourmatrix</code><dd>A read only property that contains the data return by <code>contourc</code> used to
+create the contours of the plot.
+
+     <br><dt><code>fill</code><dd>A radio property that can have the values "on" or "off" that flags whether the
+contours to plot are to be filled.
+
+     <br><dt><code>zlevelmode</code><dt><code>zlevel</code><dd>The radio property <code>zlevelmode</code> can have the values "none", "auto" or
+"manual".  When its value is "none" there is no z component to the plotted
+contours.  When its value is "auto" the z value of the plotted contours is
+at the same value as the contour itself.  If the value is "manual", then the
+z value at which to plot the contour is determined by the <code>zlevel</code>
+property.
+
+     <br><dt><code>levellistmode</code><dt><code>levellist</code><dt><code>levelstepmode</code><dt><code>levelstep</code><dd>If <code>levellistmode</code> is "manual", then the levels at which to plot the
+contours is determined by <code>levellist</code>.  If <code>levellistmode</code> is
+set to "auto", then the distance between contours is determined by
+<code>levelstep</code>.  If both <code>levellistmode</code> and <code>levelstepmode</code>
+are set to "auto", then there are assumed to be 10 equal spaced contours.
+
+     <br><dt><code>textlistmode</code><dt><code>textlist</code><dt><code>textstepmode</code><dt><code>textstep</code><dd>If <code>textlistmode</code> is "manual", then the labelled contours
+is determined by <code>textlist</code>.  If <code>textlistmode</code> is set to
+"auto", then the distance between labelled contours is determined by
+<code>textstep</code>.  If both <code>textlistmode</code> and <code>textstepmode</code>
+are set to "auto", then there are assumed to be 10 equal spaced
+labelled contours.
+
+     <br><dt><code>showtext</code><dd>Flag whether the contour labels are shown or not.
+
+     <br><dt><code>labelspacing</code><dd>The distance between labels on a single contour in points.
+
+     <br><dt><code>linewidth</code><br><dt><code>linestyle</code><br><dt><code>linecolor</code><dd>The properties of the contour lines.  The properties <code>linewidth</code> and
+<code>linestyle</code> are similar to the corresponding properties for lines.  The
+property <code>linecolor</code> is a color property (see <a href="Colors.html#Colors">Colors</a>), that can also
+have the values of "none" or "auto".  If <code>linecolor</code> is "none", then no
+contour line is drawn.  If <code>linecolor</code> is "auto" then the line color is
+determined by the colormap.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>The original x, y, and z data of the contour lines.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>zdatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Contributing-Guidelines.html b/doc/interpreter/HTML/Contributing-Guidelines.html
new file mode 100644
index 0000000..31116e9
--- /dev/null
+++ b/doc/interpreter/HTML/Contributing-Guidelines.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Contributing Guidelines - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link rel="next" href="Trouble.html#Trouble" title="Trouble">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Contributing-Guidelines"></a>
+Next: <a rel="next" accesskey="n" href="Trouble.html#Trouble">Trouble</a>,
+Previous: <a rel="previous" accesskey="p" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix D Contributing Guidelines</h2>
+
+<p><a name="index-coding-standards-2511"></a><a name="index-Octave-development-2512"></a>
+This chapter is dedicated to those who wish to contribute code to Octave.
+
+<ul class="menu">
+<li><a accesskey="1" href="How-to-Contribute.html#How-to-Contribute">How to Contribute</a>
+<li><a accesskey="2" href="General-Guidelines.html#General-Guidelines">General Guidelines</a>
+<li><a accesskey="3" href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029">Octave Sources (m-files)</a>
+<li><a accesskey="4" href="C_002b_002b-Sources.html#C_002b_002b-Sources">C++ Sources</a>
+<li><a accesskey="5" href="Other-Sources.html#Other-Sources">Other Sources</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Controlling-Subprocesses.html b/doc/interpreter/HTML/Controlling-Subprocesses.html
new file mode 100644
index 0000000..f649237
--- /dev/null
+++ b/doc/interpreter/HTML/Controlling-Subprocesses.html
@@ -0,0 +1,595 @@
+<html lang="en">
+<head>
+<title>Controlling Subprocesses - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Networking-Utilities.html#Networking-Utilities" title="Networking Utilities">
+<link rel="next" href="Process-ID-Information.html#Process-ID-Information" title="Process ID Information">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Controlling-Subprocesses"></a>
+Next: <a rel="next" accesskey="n" href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a>,
+Previous: <a rel="previous" accesskey="p" href="Networking-Utilities.html#Networking-Utilities">Networking Utilities</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.5 Controlling Subprocesses</h3>
+
+<p>Octave includes some high-level commands like <code>system</code> and
+<code>popen</code> for starting subprocesses.  If you want to run another
+program to perform some task and then look at its output, you will
+probably want to use these functions.
+
+   <p>Octave also provides several very low-level Unix-like functions which
+can also be used for starting subprocesses, but you should probably only
+use them if you can't find any way to do what you need with the
+higher-level functions.
+
+<!-- toplev.cc -->
+   <p><a name="doc_002dsystem"></a>
+
+<div class="defun">
+— Built-in Function:  <b>system</b> (<var>string, return_output, type</var>)<var><a name="index-system-2371"></a></var><br>
+<blockquote><p>Execute a shell command specified by <var>string</var>.  The second
+argument is optional.  If <var>type</var> is <code>"async"</code>, the process
+is started in the background and the process id of the child process
+is returned immediately.  Otherwise, the process is started, and
+Octave waits until it exits.  If the <var>type</var> argument is omitted, a
+value of <code>"sync"</code> is assumed.
+
+        <p>If two input arguments are given (the actual value of
+<var>return_output</var> is irrelevant) and the subprocess is started
+synchronously, or if <var>system</var> is called with one input argument and
+one or more output arguments, the output from the command is returned. 
+Otherwise, if the subprocess is executed synchronously, its output is
+sent to the standard output.  To send the output of a command executed
+with <var>system</var> through the pager, use a command like
+
+     <pre class="example">          disp (system (cmd, 1));
+</pre>
+        <p class="noindent">or
+
+     <pre class="example">          printf ("%s\n", system (cmd, 1));
+</pre>
+        <p>The <code>system</code> function can return two values.  The first is the
+exit status of the command and the second is any output from the
+command that was written to the standard output stream.  For example,
+
+     <pre class="example">          [status, output] = system ("echo foo; exit 2");
+</pre>
+        <p class="noindent">will set the variable <code>output</code> to the string ‘<samp><span class="samp">foo</span></samp>’, and the
+variable <code>status</code> to the integer ‘<samp><span class="samp">2</span></samp>’. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/unix.m -->
+   <p><a name="doc_002dunix"></a>
+
+<div class="defun">
+— Function File: [<var>status</var>, <var>text</var>] <b>unix</b> (<var>command</var>)<var><a name="index-unix-2372"></a></var><br>
+— Function File: [<var>status</var>, <var>text</var>] <b>unix</b> (<var>command, "-echo"</var>)<var><a name="index-unix-2373"></a></var><br>
+<blockquote><p>Execute a system command if running under a Unix-like operating
+system, otherwise do nothing.  Return the exit status of the program
+in <var>status</var> and any output sent to the standard output in
+<var>text</var>.  If the optional second argument <code>"-echo"</code> is given,
+then also send the output from the command to the standard output. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disunix.html#doc_002disunix">isunix</a>, <a href="doc_002dispc.html#doc_002dispc">ispc</a>, <a href="doc_002dsystem.html#doc_002dsystem">system</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/dos.m -->
+   <p><a name="doc_002ddos"></a>
+
+<div class="defun">
+— Function File: [<var>status</var>, <var>text</var>] = <b>dos</b> (<var>command</var>)<var><a name="index-dos-2374"></a></var><br>
+— Function File: [<var>status</var>, <var>text</var>] = <b>dos</b> (<var>command, "-echo"</var>)<var><a name="index-dos-2375"></a></var><br>
+<blockquote><p>Execute a system command if running under a Windows-like operating
+system, otherwise do nothing.  Return the exit status of the program
+in <var>status</var> and any output sent to the standard output in
+<var>text</var>.  If the optional second argument <code>"-echo"</code> is given,
+then also send the output from the command to the standard output. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunix.html#doc_002dunix">unix</a>, <a href="doc_002disunix.html#doc_002disunix">isunix</a>, <a href="doc_002dispc.html#doc_002dispc">ispc</a>, <a href="doc_002dsystem.html#doc_002dsystem">system</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/perl.m -->
+   <p><a name="doc_002dperl"></a>
+
+<div class="defun">
+— Function File: [<var>output</var>, <var>status</var>] = <b>perl</b> (<var>scriptfile</var>)<var><a name="index-perl-2376"></a></var><br>
+— Function File: [<var>output</var>, <var>status</var>] = <b>perl</b> (<var>scriptfile, argument1, argument2, <small class="dots">...</small></var>)<var><a name="index-perl-2377"></a></var><br>
+<blockquote><p>Invoke perl script <var>scriptfile</var> with possibly a list of
+command line arguments. 
+Returns output in <var>output</var> and status
+in <var>status</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsystem.html#doc_002dsystem">system</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dpopen"></a>
+
+<div class="defun">
+— Built-in Function: <var>fid</var> = <b>popen</b> (<var>command, mode</var>)<var><a name="index-popen-2378"></a></var><br>
+<blockquote><p>Start a process and create a pipe.  The name of the command to run is
+given by <var>command</var>.  The file identifier corresponding to the input
+or output stream of the process is returned in <var>fid</var>.  The argument
+<var>mode</var> may be
+
+          <dl>
+<dt><code>"r"</code><dd>The pipe will be connected to the standard output of the process, and
+open for reading.
+
+          <br><dt><code>"w"</code><dd>The pipe will be connected to the standard input of the process, and
+open for writing. 
+</dl>
+
+        <p>For example,
+
+     <pre class="example">          fid = popen ("ls -ltr / | tail -3", "r");
+          while (ischar (s = fgets (fid)))
+            fputs (stdout, s);
+          endwhile
+               -| drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc
+               -| drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib
+               -| drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp
+</pre>
+        </blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dpclose"></a>
+
+<div class="defun">
+— Built-in Function:  <b>pclose</b> (<var>fid</var>)<var><a name="index-pclose-2379"></a></var><br>
+<blockquote><p>Close a file identifier that was opened by <code>popen</code>.  You may also
+use <code>fclose</code> for the same purpose. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dpopen2"></a>
+
+<div class="defun">
+— Built-in Function: [<var>in</var>, <var>out</var>, <var>pid</var>] = <b>popen2</b> (<var>command, args</var>)<var><a name="index-popen2-2380"></a></var><br>
+<blockquote><p>Start a subprocess with two-way communication.  The name of the process
+is given by <var>command</var>, and <var>args</var> is an array of strings
+containing options for the command.  The file identifiers for the input
+and output streams of the subprocess are returned in <var>in</var> and
+<var>out</var>.  If execution of the command is successful, <var>pid</var>
+contains the process ID of the subprocess.  Otherwise, <var>pid</var> is
+−1.
+
+        <p>For example,
+
+     <pre class="example">          [in, out, pid] = popen2 ("sort", "-r");
+          fputs (in, "these\nare\nsome\nstrings\n");
+          fclose (in);
+          EAGAIN = errno ("EAGAIN");
+          done = false;
+          do
+            s = fgets (out);
+            if (ischar (s))
+              fputs (stdout, s);
+            elseif (errno () == EAGAIN)
+              sleep (0.1);
+              fclear (out);
+            else
+              done = true;
+            endif
+          until (done)
+          fclose (out);
+          waitpid (pid);
+               -| these
+               -| strings
+               -| some
+               -| are
+</pre>
+        <p>Note that <code>popen2</code>, unlike <code>popen</code>, will not "reap" the
+child process.  If you don't use <code>waitpid</code> to check the child's
+exit status, it will linger until Octave exits. 
+</p></blockquote></div>
+
+<!-- defaults.cc -->
+   <p><a name="doc_002dEXEC_005fPATH"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>EXEC_PATH</b> ()<var><a name="index-EXEC_005fPATH-2381"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>EXEC_PATH</b> (<var>new_val</var>)<var><a name="index-EXEC_005fPATH-2382"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies a colon separated
+list of directories to search when executing external programs. 
+Its initial value is taken from the environment variable
+<code>OCTAVE_EXEC_PATH</code><!-- /@w --> (if it exists) or <code>PATH</code>, but that
+value can be overridden by the command line argument
+<code>--exec-path PATH</code>.  At startup, an additional set of
+directories (including the shell PATH) is appended to the path
+specified in the environment or on the command line.  If you use
+the <code>EXEC_PATH</code><!-- /@w --> function to modify the path, you should take
+care to preserve these additional directories. 
+</p></blockquote></div>
+
+   <p>In most cases, the following functions simply decode their arguments and
+make the corresponding Unix system calls.  For a complete example of how
+they can be used, look at the definition of the function <code>popen2</code>.
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dfork"></a>
+
+<div class="defun">
+— Built-in Function: [<var>pid</var>, <var>msg</var>] = <b>fork</b> ()<var><a name="index-fork-2383"></a></var><br>
+<blockquote><p>Create a copy of the current process.
+
+        <p>Fork can return one of the following values:
+
+          <dl>
+<dt>> 0<dd>You are in the parent process.  The value returned from <code>fork</code> is
+the process id of the child process.  You should probably arrange to
+wait for any child processes to exit.
+
+          <br><dt>0<dd>You are in the child process.  You can call <code>exec</code> to start another
+process.  If that fails, you should probably call <code>exit</code>.
+
+          <br><dt>< 0<dd>The call to <code>fork</code> failed for some reason.  You must take evasive
+action.  A system dependent error message will be waiting in <var>msg</var>. 
+</dl>
+        </p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dexec"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>exec</b> (<var>file, args</var>)<var><a name="index-exec-2384"></a></var><br>
+<blockquote><p>Replace current process with a new process.  Calling <code>exec</code> without
+first calling <code>fork</code> will terminate your current Octave process and
+replace it with the program named by <var>file</var>.  For example,
+
+     <pre class="example">          exec ("ls" "-l")
+</pre>
+        <p class="noindent">will run <code>ls</code> and return you to your shell prompt.
+
+        <p>If successful, <code>exec</code> does not return.  If <code>exec</code> does return,
+<var>err</var> will be nonzero, and <var>msg</var> will contain a system-dependent
+error message. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dpipe"></a>
+
+<div class="defun">
+— Built-in Function: [<var>read_fd</var>, <var>write_fd</var>, <var>err</var>, <var>msg</var>] = <b>pipe</b> ()<var><a name="index-pipe-2385"></a></var><br>
+<blockquote><p>Create a pipe and return the reading and writing ends of the pipe
+into <var>read_fd</var> and <var>write_fd</var> respectively.
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002ddup2"></a>
+
+<div class="defun">
+— Built-in Function: [<var>fid</var>, <var>msg</var>] = <b>dup2</b> (<var>old, new</var>)<var><a name="index-dup2-2386"></a></var><br>
+<blockquote><p>Duplicate a file descriptor.
+
+        <p>If successful, <var>fid</var> is greater than zero and contains the new file
+ID.  Otherwise, <var>fid</var> is negative and <var>msg</var> contains a
+system-dependent error message. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dwaitpid"></a>
+
+<div class="defun">
+— Built-in Function: [<var>pid</var>, <var>status</var>, <var>msg</var>] = <b>waitpid</b> (<var>pid, options</var>)<var><a name="index-waitpid-2387"></a></var><br>
+<blockquote><p>Wait for process <var>pid</var> to terminate.  The <var>pid</var> argument can be:
+
+          <dl>
+<dt>−1<dd>Wait for any child process.
+
+          <br><dt>0<dd>Wait for any child process whose process group ID is equal to that of
+the Octave interpreter process.
+
+          <br><dt>> 0<dd>Wait for termination of the child process with ID <var>pid</var>. 
+</dl>
+
+        <p>The <var>options</var> argument can be a bitwise OR of zero or more of
+the following constants:
+
+          <dl>
+<dt><code>0</code><dd>Wait until signal is received or a child process exits (this is the
+default if the <var>options</var> argument is missing).
+
+          <br><dt><code>WNOHANG</code><dd>Do not hang if status is not immediately available.
+
+          <br><dt><code>WUNTRACED</code><dd>Report the status of any child processes that are stopped, and whose
+status has not yet been reported since they stopped.
+
+          <br><dt><code>WCONTINUE</code><dd>Return if a stopped child has been resumed by delivery of <code>SIGCONT</code>. 
+This value may not be meaningful on all systems. 
+</dl>
+
+        <p>If the returned value of <var>pid</var> is greater than 0, it is the process
+ID of the child process that exited.  If an error occurs, <var>pid</var> will
+be less than zero and <var>msg</var> will contain a system-dependent error
+message.  The value of <var>status</var> contains additional system-dependent
+information about the subprocess that exited. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dWCONTINUE.html#doc_002dWCONTINUE">WCONTINUE</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWNOHANG.html#doc_002dWNOHANG">WNOHANG</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWUNTRACED.html#doc_002dWUNTRACED">WUNTRACED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWCONTINUE"></a>
+
+<div class="defun">
+— Built-in Function: WCONINTUE <b>(</b>)<var><a name="index-g_t_0028-2388"></a></var><br>
+<blockquote><p>Return the numerical value of the option argument that may be
+passed to <code>waitpid</code> to indicate that it should also return
+if a stopped child has been resumed by delivery of a <code>SIGCONT</code>
+signal. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWNOHANG.html#doc_002dWNOHANG">WNOHANG</a>, <a href="doc_002dWUNTRACED.html#doc_002dWUNTRACED">WUNTRACED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWCOREDUMP"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WCOREDUMP</b> (<var>status</var>)<var><a name="index-WCOREDUMP-2389"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return true if the
+child produced a core dump.  This function should only be employed if
+<code>WIFSIGNALED</code> returned true.  The macro used to implement this
+function is not specified in POSIX.1-2001 and is not available on some
+Unix implementations (e.g., AIX, SunOS). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWEXITSTATUS"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WEXITSTATUS</b> (<var>status</var>)<var><a name="index-WEXITSTATUS-2390"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return the exit
+status of the child.  This function should only be employed if
+<code>WIFEXITED</code> returned true. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWIFCONTINUED"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WIFCONTINUED</b> (<var>status</var>)<var><a name="index-WIFCONTINUED-2391"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return true if the
+child process was resumed by delivery of <code>SIGCONT</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWIFSIGNALED"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WIFSIGNALED</b> (<var>status</var>)<var><a name="index-WIFSIGNALED-2392"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return true if the
+child process was terminated by a signal. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWIFSTOPPED"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WIFSTOPPED</b> (<var>status</var>)<var><a name="index-WIFSTOPPED-2393"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return true if the
+child process was stopped by delivery of a signal; this is only
+possible if the call was done using <code>WUNTRACED</code> or when the child
+is being traced (see ptrace(2)). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWIFEXITED"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WIFEXITED</b> (<var>status</var>)<var><a name="index-WIFEXITED-2394"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return true if the
+child terminated normally. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWNOHANG"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WNOHANG</b> ()<var><a name="index-WNOHANG-2395"></a></var><br>
+<blockquote><p>Return the numerical value of the option argument that may be
+passed to <code>waitpid</code> to indicate that it should return its
+status immediately instead of waiting for a process to exit. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWUNTRACED.html#doc_002dWUNTRACED">WUNTRACED</a>, <a href="doc_002dWCONTINUE.html#doc_002dWCONTINUE">WCONTINUE</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWSTOPSIG"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WSTOPSIG</b> (<var>status</var>)<var><a name="index-WSTOPSIG-2396"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return the number of
+the signal which caused the child to stop.  This function should only
+be employed if <code>WIFSTOPPED</code> returned true. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWTERMSIG.html#doc_002dWTERMSIG">WTERMSIG</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWTERMSIG"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WTERMSIG</b> (<var>status</var>)<var><a name="index-WTERMSIG-2397"></a></var><br>
+<blockquote><p>Given <var>status</var> from a call to <code>waitpid</code>, return the number of
+the signal that caused the child process to terminate.  This function
+should only be employed if <code>WIFSIGNALED</code> returned true. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWIFEXITED.html#doc_002dWIFEXITED">WIFEXITED</a>, <a href="doc_002dWEXITSTATUS.html#doc_002dWEXITSTATUS">WEXITSTATUS</a>, <a href="doc_002dWIFSIGNALED.html#doc_002dWIFSIGNALED">WIFSIGNALED</a>, <a href="doc_002dWCOREDUMP.html#doc_002dWCOREDUMP">WCOREDUMP</a>, <a href="doc_002dWIFSTOPPED.html#doc_002dWIFSTOPPED">WIFSTOPPED</a>, <a href="doc_002dWSTOPSIG.html#doc_002dWSTOPSIG">WSTOPSIG</a>, <a href="doc_002dWIFCONTINUED.html#doc_002dWIFCONTINUED">WIFCONTINUED</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dWUNTRACED"></a>
+
+<div class="defun">
+— Built-in Function:  <b>WUNTRACED</b> ()<var><a name="index-WUNTRACED-2398"></a></var><br>
+<blockquote><p>Return the numerical value of the option argument that may be
+passed to <code>waitpid</code> to indicate that it should also return
+if the child process has stopped but is not traced via the
+<code>ptrace</code> system call
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwaitpid.html#doc_002dwaitpid">waitpid</a>, <a href="doc_002dWNOHANG.html#doc_002dWNOHANG">WNOHANG</a>, <a href="doc_002dWCONTINUE.html#doc_002dWCONTINUE">WCONTINUE</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dfcntl"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>fcntl</b> (<var>fid, request, arg</var>)<var><a name="index-fcntl-2399"></a></var><br>
+<blockquote><p>Change the properties of the open file <var>fid</var>.  The following values
+may be passed as <var>request</var>:
+
+          <dl>
+<dt><code>F_DUPFD</code><a name="index-F_005fDUPFD-2400"></a><dd>Return a duplicate file descriptor.
+
+          <br><dt><code>F_GETFD</code><a name="index-F_005fGETFD-2401"></a><dd>Return the file descriptor flags for <var>fid</var>.
+
+          <br><dt><code>F_SETFD</code><a name="index-F_005fSETFD-2402"></a><dd>Set the file descriptor flags for <var>fid</var>.
+
+          <br><dt><code>F_GETFL</code><a name="index-F_005fGETFL-2403"></a><dd>Return the file status flags for <var>fid</var>.  The following codes may be
+returned (some of the flags may be undefined on some systems).
+
+               <dl>
+<dt><code>O_RDONLY</code><a name="index-O_005fRDONLY-2404"></a><dd>Open for reading only.
+
+               <br><dt><code>O_WRONLY</code><a name="index-O_005fWRONLY-2405"></a><dd>Open for writing only.
+
+               <br><dt><code>O_RDWR</code><a name="index-O_005fRDWR-2406"></a><dd>Open for reading and writing.
+
+               <br><dt><code>O_APPEND</code><a name="index-O_005fAPPEND-2407"></a><dd>Append on each write.
+
+               <br><dt><code>O_CREAT</code><a name="index-O_005fCREAT-2408"></a><dd>Create the file if it does not exist.
+
+               <br><dt><code>O_NONBLOCK</code><a name="index-O_005fNONBLOCK-2409"></a><dd>Nonblocking mode.
+
+               <br><dt><code>O_SYNC</code><a name="index-O_005fSYNC-2410"></a><dd>Wait for writes to complete.
+
+               <br><dt><code>O_ASYNC</code><a name="index-O_005fASYNC-2411"></a><dd>Asynchronous I/O. 
+</dl>
+
+          <br><dt><code>F_SETFL</code><a name="index-F_005fSETFL-2412"></a><dd>Set the file status flags for <var>fid</var> to the value specified by
+<var>arg</var>.  The only flags that can be changed are <code>O_APPEND</code><!-- /@w --> and
+<code>O_NONBLOCK</code><!-- /@w -->. 
+</dl>
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dkill"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>kill</b> (<var>pid, sig</var>)<var><a name="index-kill-2413"></a></var><br>
+<blockquote><p>Send signal <var>sig</var> to process <var>pid</var>.
+
+        <p>If <var>pid</var> is positive, then signal <var>sig</var> is sent to <var>pid</var>.
+
+        <p>If <var>pid</var> is 0, then signal <var>sig</var> is sent to every process
+in the process group of the current process.
+
+        <p>If <var>pid</var> is -1, then signal <var>sig</var> is sent to every process
+except process 1.
+
+        <p>If <var>pid</var> is less than -1, then signal <var>sig</var> is sent to every
+process in the process group <var>-pid</var>.
+
+        <p>If <var>sig</var> is 0, then no signal is sent, but error checking is still
+performed.
+
+        <p>Return 0 if successful, otherwise return -1. 
+</p></blockquote></div>
+
+<!-- sighandlers.cc -->
+   <p><a name="doc_002dSIG"></a>
+
+<div class="defun">
+— Built-in Function:  <b>SIG</b> ()<var><a name="index-SIG-2414"></a></var><br>
+<blockquote><p>Return a structure containing Unix signal names and their defined values. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Conventions.html b/doc/interpreter/HTML/Conventions.html
new file mode 100644
index 0000000..9d90131
--- /dev/null
+++ b/doc/interpreter/HTML/Conventions.html
@@ -0,0 +1,47 @@
+<html lang="en">
+<head>
+<title>Conventions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Introduction.html#Introduction" title="Introduction">
+<link rel="prev" href="Simple-Examples.html#Simple-Examples" title="Simple Examples">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Conventions"></a>
+Previous: <a rel="previous" accesskey="p" href="Simple-Examples.html#Simple-Examples">Simple Examples</a>,
+Up: <a rel="up" accesskey="u" href="Introduction.html#Introduction">Introduction</a>
+<hr>
+</div>
+
+<h3 class="section">1.3 Conventions</h3>
+
+<p>This section explains the notational conventions that are used in this
+manual.  You may want to skip this section and refer back to it later.
+
+<ul class="menu">
+<li><a accesskey="1" href="Fonts.html#Fonts">Fonts</a>
+<li><a accesskey="2" href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a>
+<li><a accesskey="3" href="Printing-Notation.html#Printing-Notation">Printing Notation</a>
+<li><a accesskey="4" href="Error-Messages.html#Error-Messages">Error Messages</a>
+<li><a accesskey="5" href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Conversion-of-Numerical-Data-to-Strings.html b/doc/interpreter/HTML/Conversion-of-Numerical-Data-to-Strings.html
new file mode 100644
index 0000000..60cf35e
--- /dev/null
+++ b/doc/interpreter/HTML/Conversion-of-Numerical-Data-to-Strings.html
@@ -0,0 +1,157 @@
+<html lang="en">
+<head>
+<title>Conversion of Numerical Data to Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Creating-Strings.html#Creating-Strings" title="Creating Strings">
+<link rel="prev" href="Concatenating-Strings.html#Concatenating-Strings" title="Concatenating Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Conversion-of-Numerical-Data-to-Strings"></a>
+Previous: <a rel="previous" accesskey="p" href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a>,
+Up: <a rel="up" accesskey="u" href="Creating-Strings.html#Creating-Strings">Creating Strings</a>
+<hr>
+</div>
+
+<h4 class="subsection">5.3.2 Conversion of Numerical Data to Strings</h4>
+
+<p>Apart from the string concatenation functions (see <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a>)
+which cast numerical data to the corresponding ASCII characters, there are
+several functions that format numerical data as strings.  <code>mat2str</code> and
+<code>num2str</code> convert real or complex matrices, while <code>int2str</code> converts
+integer matrices.  <code>int2str</code> takes the real part of complex values and
+round fractional values to integer.  A more flexible way to format numerical
+data as strings is the <code>sprintf</code> function (see <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>,
+<a href="doc_002dsprintf.html#doc_002dsprintf">doc-sprintf</a>).
+
+<!-- ./strings/mat2str.m -->
+   <p><a name="doc_002dmat2str"></a>
+
+<div class="defun">
+— Function File: <var>s</var> = <b>mat2str</b> (<var>x, n</var>)<var><a name="index-mat2str-298"></a></var><br>
+— Function File: <var>s</var> = <b>mat2str</b> (<var><small class="dots">...</small>, 'class'</var>)<var><a name="index-mat2str-299"></a></var><br>
+<blockquote>
+        <p>Format real/complex numerical matrices as strings.  This function
+returns values that are suitable for the use of the <code>eval</code>
+function.
+
+        <p>The precision of the values is given by <var>n</var>.  If <var>n</var> is a
+scalar then both real and imaginary parts of the matrix are printed
+to the same precision.  Otherwise <var>n</var><code> (1)</code> defines the
+precision of the real part and <var>n</var><code> (2)</code> defines the
+precision of the imaginary part.  The default for <var>n</var> is 17.
+
+        <p>If the argument 'class' is given, then the class of <var>x</var> is
+included in the string in such a way that the eval will result in the
+construction of a matrix of the same class.
+
+     <pre class="example">          mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
+                "[-0.3333+0.14i;0.3333-0.14i]"
+          
+          mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
+                "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]"
+          
+          mat2str (int16([1 -1]), 'class')
+                "int16([1,-1])"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsprintf.html#doc_002dsprintf">sprintf</a>, <a href="doc_002dnum2str.html#doc_002dnum2str">num2str</a>, <a href="doc_002dint2str.html#doc_002dint2str">int2str</a>. 
+</p></blockquote></div>
+
+<!-- ./general/num2str.m -->
+   <p><a name="doc_002dnum2str"></a>
+
+<div class="defun">
+— Function File:  <b>num2str</b> (<var>x</var>)<var><a name="index-num2str-300"></a></var><br>
+— Function File:  <b>num2str</b> (<var>x, precision</var>)<var><a name="index-num2str-301"></a></var><br>
+— Function File:  <b>num2str</b> (<var>x, format</var>)<var><a name="index-num2str-302"></a></var><br>
+<blockquote><p>Convert a number (or array) to a string (or a character array).  The
+optional second argument may either give the number of significant
+digits (<var>precision</var>) to be used in the output or a format
+template string (<var>format</var>) as in <code>sprintf</code> (see <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>).  <code>num2str</code> can also handle complex numbers.  For
+example:
+
+     <pre class="example">          num2str (123.456)
+                "123.46"
+          
+          num2str (123.456, 4)
+                "123.5"
+          
+          s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
+                s =
+                  1.0  1.3
+                  3.0  3.6
+          whos s
+               
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     s           2x8                         16  char
+          
+          num2str (1.234 + 27.3i)
+                "1.234+27.3i"
+</pre>
+        <p>The <code>num2str</code> function is not very flexible.  For better control
+over the results, use <code>sprintf</code> (see <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>). 
+Note that for complex <var>x</var>, the format string may only contain one
+output conversion specification and nothing else.  Otherwise, you
+will get unpredictable results. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsprintf.html#doc_002dsprintf">sprintf</a>, <a href="doc_002dint2str.html#doc_002dint2str">int2str</a>, <a href="doc_002dmat2str.html#doc_002dmat2str">mat2str</a>. 
+</p></blockquote></div>
+
+<!-- ./general/int2str.m -->
+   <p><a name="doc_002dint2str"></a>
+
+<div class="defun">
+— Function File:  <b>int2str</b> (<var>n</var>)<var><a name="index-int2str-303"></a></var><br>
+<blockquote><p>Convert an integer (or array of integers) to a string (or a character
+array).
+
+     <pre class="example">          
+          int2str (123)
+                "123"
+          
+          s = int2str ([1, 2, 3; 4, 5, 6])
+                s =
+                  1  2  3
+                  4  5  6
+          
+          whos s
+                s =
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     s           2x7                         14  char
+</pre>
+        <p>This function is not very flexible.  For better control over the
+results, use <code>sprintf</code> (see <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsprintf.html#doc_002dsprintf">sprintf</a>, <a href="doc_002dnum2str.html#doc_002dnum2str">num2str</a>, <a href="doc_002dmat2str.html#doc_002dmat2str">mat2str</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Convex-Hull.html b/doc/interpreter/HTML/Convex-Hull.html
new file mode 100644
index 0000000..a3c64af
--- /dev/null
+++ b/doc/interpreter/HTML/Convex-Hull.html
@@ -0,0 +1,93 @@
+<html lang="en">
+<head>
+<title>Convex Hull - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Geometry.html#Geometry" title="Geometry">
+<link rel="prev" href="Voronoi-Diagrams.html#Voronoi-Diagrams" title="Voronoi Diagrams">
+<link rel="next" href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data" title="Interpolation on Scattered Data">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Convex-Hull"></a>
+Next: <a rel="next" accesskey="n" href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a>,
+Previous: <a rel="previous" accesskey="p" href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a>,
+Up: <a rel="up" accesskey="u" href="Geometry.html#Geometry">Geometry</a>
+<hr>
+</div>
+
+<h3 class="section">29.3 Convex Hull</h3>
+
+<p>The convex hull of a set of points is the minimum convex envelope
+containing all of the points.  Octave has the functions <code>convhull</code>
+and <code>convhulln</code> to calculate the convex hull of 2-dimensional and
+N-dimensional sets of points.
+
+<!-- ./geometry/convhull.m -->
+   <p><a name="doc_002dconvhull"></a>
+
+<div class="defun">
+— Function File: <var>H</var> = <b>convhull</b> (<var>x, y</var>)<var><a name="index-convhull-2113"></a></var><br>
+— Function File: <var>H</var> = <b>convhull</b> (<var>x, y, opt</var>)<var><a name="index-convhull-2114"></a></var><br>
+<blockquote><p>Returns the index vector to the points of the enclosing convex hull.  The
+data points are defined by the x and y vectors.
+
+        <p>A third optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>, <a href="doc_002dconvhulln.html#doc_002dconvhulln">convhulln</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/convhulln.cc -->
+   <p><a name="doc_002dconvhulln"></a>
+
+<div class="defun">
+— Loadable Function: <var>h</var> = <b>convhulln</b> (<var>p</var>)<var><a name="index-convhulln-2115"></a></var><br>
+— Loadable Function: <var>h</var> = <b>convhulln</b> (<var>p, opt</var>)<var><a name="index-convhulln-2116"></a></var><br>
+— Loadable Function: [<var>h</var>, <var>v</var>] = <b>convhulln</b> (<var><small class="dots">...</small></var>)<var><a name="index-convhulln-2117"></a></var><br>
+<blockquote><p>Return an index vector to the points of the enclosing convex hull. 
+The input matrix of size [n, dim] contains n points of dimension dim.
+
+        <p>If a second optional argument is given, it must be a string or cell array
+of strings containing options for the underlying qhull command.  (See
+the Qhull documentation for the available options.)  The default options
+are "s Qci Tcv". 
+If the second output <var>V</var> is requested the volume of the convex hull is
+calculated.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dconvhull.html#doc_002dconvhull">convhull</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+   <p>An example of the use of <code>convhull</code> is
+
+<pre class="example">     x = -3:0.05:3;
+     y = abs (sin (x));
+     k = convhull (x, y);
+     plot (x(k), y(k), "r-", x, y, "b+");
+     axis ([-3.05, 3.05, -0.05, 1.05]);
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Coordinate-Transformations.html b/doc/interpreter/HTML/Coordinate-Transformations.html
new file mode 100644
index 0000000..4a9ca15
--- /dev/null
+++ b/doc/interpreter/HTML/Coordinate-Transformations.html
@@ -0,0 +1,106 @@
+<html lang="en">
+<head>
+<title>Coordinate Transformations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Special-Functions.html#Special-Functions" title="Special Functions">
+<link rel="next" href="Mathematical-Constants.html#Mathematical-Constants" title="Mathematical Constants">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Coordinate-Transformations"></a>
+Next: <a rel="next" accesskey="n" href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a>,
+Previous: <a rel="previous" accesskey="p" href="Special-Functions.html#Special-Functions">Special Functions</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.7 Coordinate Transformations</h3>
+
+<!-- ./general/cart2pol.m -->
+<p><a name="doc_002dcart2pol"></a>
+
+<div class="defun">
+— Function File: [<var>theta</var>, <var>r</var>] = <b>cart2pol</b> (<var>x, y</var>)<var><a name="index-cart2pol-1503"></a></var><br>
+— Function File: [<var>theta</var>, <var>r</var>, <var>z</var>] = <b>cart2pol</b> (<var>x, y, z</var>)<var><a name="index-cart2pol-1504"></a></var><br>
+<blockquote><p>Transform Cartesian to polar or cylindrical coordinates. 
+<var>x</var>, <var>y</var> (and <var>z</var>) must be the same shape, or scalar. 
+<var>theta</var> describes the angle relative to the positive x-axis. 
+<var>r</var> is the distance to the z-axis (0, 0, z). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpol2cart.html#doc_002dpol2cart">pol2cart</a>, <a href="doc_002dcart2sph.html#doc_002dcart2sph">cart2sph</a>, <a href="doc_002dsph2cart.html#doc_002dsph2cart">sph2cart</a>. 
+</p></blockquote></div>
+
+<!-- ./general/pol2cart.m -->
+   <p><a name="doc_002dpol2cart"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>y</var>] = <b>pol2cart</b> (<var>theta, r</var>)<var><a name="index-pol2cart-1505"></a></var><br>
+— Function File: [<var>x</var>, <var>y</var>, <var>z</var>] = <b>pol2cart</b> (<var>theta, r, z</var>)<var><a name="index-pol2cart-1506"></a></var><br>
+<blockquote><p>Transform polar or cylindrical to Cartesian coordinates. 
+<var>theta</var>, <var>r</var> (and <var>z</var>) must be the same shape, or scalar. 
+<var>theta</var> describes the angle relative to the positive x-axis. 
+<var>r</var> is the distance to the z-axis (0, 0, z). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcart2pol.html#doc_002dcart2pol">cart2pol</a>, <a href="doc_002dcart2sph.html#doc_002dcart2sph">cart2sph</a>, <a href="doc_002dsph2cart.html#doc_002dsph2cart">sph2cart</a>. 
+</p></blockquote></div>
+
+<!-- ./general/cart2sph.m -->
+   <p><a name="doc_002dcart2sph"></a>
+
+<div class="defun">
+— Function File: [<var>theta</var>, <var>phi</var>, <var>r</var>] = <b>cart2sph</b> (<var>x, y, z</var>)<var><a name="index-cart2sph-1507"></a></var><br>
+<blockquote><p>Transform Cartesian to spherical coordinates. 
+<var>x</var>, <var>y</var> and <var>z</var> must be the same shape, or scalar. 
+<var>theta</var> describes the angle relative to the positive x-axis. 
+<var>phi</var> is the angle relative to the xy-plane. 
+<var>r</var> is the distance to the origin (0, 0, 0). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpol2cart.html#doc_002dpol2cart">pol2cart</a>, <a href="doc_002dcart2pol.html#doc_002dcart2pol">cart2pol</a>, <a href="doc_002dsph2cart.html#doc_002dsph2cart">sph2cart</a>. 
+</p></blockquote></div>
+
+<!-- ./general/sph2cart.m -->
+   <p><a name="doc_002dsph2cart"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>y</var>, <var>z</var>] = <b>sph2cart</b> (<var>theta, phi, r</var>)<var><a name="index-sph2cart-1508"></a></var><br>
+<blockquote><p>Transform spherical to Cartesian coordinates. 
+<var>x</var>, <var>y</var> and <var>z</var> must be the same shape, or scalar. 
+<var>theta</var> describes the angle relative to the positive x-axis. 
+<var>phi</var> is the angle relative to the xy-plane. 
+<var>r</var> is the distance to the origin (0, 0, 0). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpol2cart.html#doc_002dpol2cart">pol2cart</a>, <a href="doc_002dcart2pol.html#doc_002dcart2pol">cart2pol</a>, <a href="doc_002dcart2sph.html#doc_002dcart2sph">cart2sph</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Copying.html b/doc/interpreter/HTML/Copying.html
new file mode 100644
index 0000000..71d68b2
--- /dev/null
+++ b/doc/interpreter/HTML/Copying.html
@@ -0,0 +1,747 @@
+<html lang="en">
+<head>
+<title>Copying - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Emacs-Octave-Support.html#Emacs-Octave-Support" title="Emacs Octave Support">
+<link rel="next" href="Concept-Index.html#Concept-Index" title="Concept Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Copying"></a>
+Next: <a rel="next" accesskey="n" href="Concept-Index.html#Concept-Index">Concept Index</a>,
+Previous: <a rel="previous" accesskey="p" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix H GNU GENERAL PUBLIC LICENSE</h2>
+
+<p><a name="index-warranty-2560"></a><a name="index-copyright-2561"></a>
+<div align="center">Version 3, 29 June 2007</div>
+
+<pre class="display">     Copyright © 2007 Free Software Foundation, Inc. <a href="http://fsf.org/">http://fsf.org/</a>
+     
+     Everyone is permitted to copy and distribute verbatim copies of this
+     license document, but changing it is not allowed.
+</pre>
+<h3 class="heading">Preamble</h3>
+
+<p>The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>The precise terms and conditions for copying, distribution and
+modification follow.
+
+<h3 class="heading">TERMS AND CONDITIONS</h3>
+
+     <ol type=1 start=0>
+<li>Definitions.
+
+     <p>“This License” refers to version 3 of the GNU General Public License.
+
+     <p>“Copyright” also means copyright-like laws that apply to other kinds
+of works, such as semiconductor masks.
+
+     <p>“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.
+
+     <p>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.
+
+     <p>A “covered work” means either the unmodified Program or a work based
+on the Program.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Source Code.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>The Corresponding Source need not include anything that users can
+regenerate automatically from other parts of the Corresponding Source.
+
+     <p>The Corresponding Source for a work in source code form is that same
+work.
+
+     <li>Basic Permissions.
+
+     <p>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.
+
+     <p>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.
+
+     <p>Conveying under any other circumstances is permitted solely under the
+conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+     <li>Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Conveying Verbatim Copies.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Conveying Modified Source Versions.
+
+     <p>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:
+
+          <ol type=a start=1>
+<li>The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+          <li>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”.
+
+          <li>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.
+
+          <li>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.
+          </ol>
+
+     <p>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.
+
+     <li>Conveying Non-Source Forms.
+
+     <p>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:
+
+          <ol type=a start=1>
+<li>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.
+
+          <li>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.
+
+          <li>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.
+
+          <li>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.
+
+          <li>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.
+
+          </ol>
+
+     <p>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.
+
+     <p>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.
+
+     <p>“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.
+
+     <p>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).
+
+     <p>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.
+
+     <p>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.
+
+     <li>Additional Terms.
+
+     <p>“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.
+
+     <p>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.
+
+     <p>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:
+
+          <ol type=a start=1>
+<li>Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+          <li>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
+
+          <li>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
+
+          <li>Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+          <li>Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+          <li>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.
+          </ol>
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Termination.
+
+     <p>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).
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Acceptance Not Required for Having Copies.
+
+     <p>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.
+
+     <li>Automatic Licensing of Downstream Recipients.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Patents.
+
+     <p>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”.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>No Surrender of Others' Freedom.
+
+     <p>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.
+
+     <li>Use with the GNU Affero General Public License.
+
+     <p>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.
+
+     <li>Revised Versions of this License.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Disclaimer of Warranty.
+
+     <p>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.
+
+     <li>Limitation of Liability.
+
+     <p>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.
+
+     <li>Interpretation of Sections 15 and 16.
+
+     <p>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.
+
+     </ol>
+
+<h3 class="heading">END OF TERMS AND CONDITIONS</h3>
+
+<h3 class="heading">How to Apply These Terms to Your New Programs</h3>
+
+<p>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.
+
+   <p>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.
+
+<pre class="smallexample">     <var>one line to give the program's name and a brief idea of what it does.</var>
+     Copyright (C) <var>year</var> <var>name of author</var>
+     
+     This program is free software: you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation, either version 3 of the License, or (at
+     your option) any later version.
+     
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+     
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
+</pre>
+   <p>Also add information on how to contact you by electronic and paper mail.
+
+   <p>If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+<pre class="smallexample">     <var>program</var> Copyright (C) <var>year</var> <var>name of author</var>
+     This program comes with ABSOLUTELY NO WARRANTY; for details type ‘<samp><span class="samp">show w</span></samp>’.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type ‘<samp><span class="samp">show c</span></samp>’ for details.
+</pre>
+   <p>The hypothetical commands ‘<samp><span class="samp">show w</span></samp>’ and ‘<samp><span class="samp">show c</span></samp>’ 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”.
+
+   <p>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
+<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
+
+   <p>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 <a href="http://www.gnu.org/philosophy/why-not-lgpl.html">http://www.gnu.org/philosophy/why-not-lgpl.html</a>.
+
+<!--  -->
+<!-- Indices start here. -->
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Cell-Arrays.html b/doc/interpreter/HTML/Creating-Cell-Arrays.html
new file mode 100644
index 0000000..565b027
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Cell-Arrays.html
@@ -0,0 +1,155 @@
+<html lang="en">
+<head>
+<title>Creating Cell Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link rel="prev" href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays" title="Basic Usage of Cell Arrays">
+<link rel="next" href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays" title="Indexing Cell Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Cell-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>,
+Previous: <a rel="previous" accesskey="p" href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.2.2 Creating Cell Array</h4>
+
+<p>The introductory example (see <a href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a>) showed
+how to create a cell array containing currently available variables. 
+In many situations, however, it is useful to create a cell array and
+then fill it with data.
+
+   <p>The <code>cell</code> function returns a cell array of a given size, containing
+empty matrices.  This function is similar to the <code>zeros</code>
+function for creating new numerical arrays.  The following example creates
+a 2-by-2 cell array containing empty matrices
+
+<pre class="example">     c = cell(2,2)
+           c =
+     
+              {
+                [1,1] = [](0x0)
+                [2,1] = [](0x0)
+                [1,2] = [](0x0)
+                [2,2] = [](0x0)
+              }
+</pre>
+   <p>Just like numerical arrays, cell arrays can be multidimensional.  The
+<code>cell</code> function accepts any number of positive integers to describe
+the size of the returned cell array.  It is also possible to set the size
+of the cell array through a vector of positive integers.  In the
+following example two cell arrays of equal size are created, and the size
+of the first one is displayed
+
+<pre class="example">     c1 = cell(3, 4, 5);
+     c2 = cell( [3, 4, 5] );
+     size(c1)
+           ans =
+              3   4   5
+</pre>
+   <p class="noindent">As can be seen, the <a href="doc_002dsize.html#doc_002dsize"><code>size</code></a> function also works
+for cell arrays.  As do other functions describing the size of an
+object, such as <a href="doc_002dlength.html#doc_002dlength"><code>length</code></a>, <a href="doc_002dnumel.html#doc_002dnumel"><code>numel</code></a>, <a href="doc_002drows.html#doc_002drows"><code>rows</code></a>, and <a href="doc_002dcolumns.html#doc_002dcolumns"><code>columns</code></a>.
+
+<!-- ov-cell.cc -->
+   <p><a name="doc_002dcell"></a>
+
+<div class="defun">
+— Built-in Function:  <b>cell</b> (<var>x</var>)<var><a name="index-cell-390"></a></var><br>
+— Built-in Function:  <b>cell</b> (<var>n, m</var>)<var><a name="index-cell-391"></a></var><br>
+<blockquote><p>Create a new cell array object.  If invoked with a single scalar
+argument, <code>cell</code> returns a square cell array with the dimension
+specified.  If you supply two scalar arguments, <code>cell</code> takes
+them to be the number of rows and columns.  If given a vector with two
+elements, <code>cell</code> uses the values of the elements as the number of
+rows and columns, respectively. 
+</p></blockquote></div>
+
+   <p>As an alternative to creating empty cell arrays, and then filling them, it
+is possible to convert numerical arrays into cell arrays using the
+<code>num2cell</code> and <code>mat2cell</code> functions.
+
+<!-- ./DLD-FUNCTIONS/cellfun.cc -->
+   <p><a name="doc_002dnum2cell"></a>
+
+<div class="defun">
+— Loadable Function: <var>c</var> = <b>num2cell</b> (<var>m</var>)<var><a name="index-num2cell-392"></a></var><br>
+— Loadable Function: <var>c</var> = <b>num2cell</b> (<var>m, dim</var>)<var><a name="index-num2cell-393"></a></var><br>
+<blockquote><p>Convert the matrix <var>m</var> to a cell array.  If <var>dim</var> is defined, the
+value <var>c</var> is of dimension 1 in this dimension and the elements of
+<var>m</var> are placed in slices in <var>c</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmat2cell.html#doc_002dmat2cell">mat2cell</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/cellfun.cc -->
+   <p><a name="doc_002dmat2cell"></a>
+
+<div class="defun">
+— Loadable Function: <var>b</var> = <b>mat2cell</b> (<var>a, m, n</var>)<var><a name="index-mat2cell-394"></a></var><br>
+— Loadable Function: <var>b</var> = <b>mat2cell</b> (<var>a, d1, d2, <small class="dots">...</small></var>)<var><a name="index-mat2cell-395"></a></var><br>
+— Loadable Function: <var>b</var> = <b>mat2cell</b> (<var>a, r</var>)<var><a name="index-mat2cell-396"></a></var><br>
+<blockquote><p>Convert the matrix <var>a</var> to a cell array.  If <var>a</var> is 2-D, then
+it is required that <code>sum (</code><var>m</var><code>) == size (</code><var>a</var><code>, 1)</code> and
+<code>sum (</code><var>n</var><code>) == size (</code><var>a</var><code>, 2)</code>.  Similarly, if <var>a</var> is
+a multi-dimensional and the number of dimensional arguments is equal
+to the dimensions of <var>a</var>, then it is required that <code>sum (</code><var>di</var><code>)
+== size (</code><var>a</var><code>, i)</code>.
+
+        <p>Given a single dimensional argument <var>r</var>, the other dimensional
+arguments are assumed to equal <code>size (</code><var>a</var><code>,</code><var>i</var><code>)</code>.
+
+        <p>An example of the use of mat2cell is
+
+     <pre class="example">          mat2cell (reshape(1:16,4,4),[3,1],[3,1])
+           {
+            [1,1] =
+          
+               1   5   9
+               2   6  10
+               3   7  11
+          
+            [2,1] =
+          
+               4   8  12
+          
+            [1,2] =
+          
+              13
+              14
+              15
+          
+            [2,2] = 16
+          }
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnum2cell.html#doc_002dnum2cell">num2cell</a>, <a href="doc_002dcell2mat.html#doc_002dcell2mat">cell2mat</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Diagonal-Matrices.html b/doc/interpreter/HTML/Creating-Diagonal-Matrices.html
new file mode 100644
index 0000000..aed914b
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Diagonal-Matrices.html
@@ -0,0 +1,69 @@
+<html lang="en">
+<head>
+<title>Creating Diagonal Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Usage.html#Basic-Usage" title="Basic Usage">
+<link rel="next" href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices" title="Creating Permutation Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Diagonal-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices">Creating Permutation Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Usage.html#Basic-Usage">Basic Usage</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.1.1 Creating Diagonal Matrices</h4>
+
+<p>The most common and easiest way to create a diagonal matrix is using the built-in
+function <dfn>diag</dfn>.  The expression <code>diag (v)</code>, with <var>v</var> a vector,
+will create a square diagonal matrix with elements on the main diagonal given
+by the elements of <var>v</var>, and size equal to the length of <var>v</var>. 
+<code>diag (v, m, n)</code> can be used to construct a rectangular diagonal matrix. 
+The result of these expressions will be a special diagonal matrix object, rather
+than a general matrix object.
+
+   <p>Diagonal matrix with unit elements can be created using <dfn>eye</dfn>. 
+Some other built-in functions can also return diagonal matrices.  Examples include
+<dfn>balance</dfn> or <dfn>inv</dfn>.
+
+   <p>Example:
+<pre class="example">       diag (1:4)
+     
+     Diagonal Matrix
+     
+        1   0   0   0
+        0   2   0   0
+        0   0   3   0
+        0   0   0   4
+     
+       diag(1:3,5,3)
+     
+     
+     Diagonal Matrix
+     
+        1   0   0
+        0   2   0
+        0   0   3
+        0   0   0
+        0   0   0
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Packages.html b/doc/interpreter/HTML/Creating-Packages.html
new file mode 100644
index 0000000..976bb78
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Packages.html
@@ -0,0 +1,123 @@
+<html lang="en">
+<head>
+<title>Creating Packages - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Packages.html#Packages" title="Packages">
+<link rel="prev" href="Administrating-Packages.html#Administrating-Packages" title="Administrating Packages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Packages"></a>
+Previous: <a rel="previous" accesskey="p" href="Administrating-Packages.html#Administrating-Packages">Administrating Packages</a>,
+Up: <a rel="up" accesskey="u" href="Packages.html#Packages">Packages</a>
+<hr>
+</div>
+
+<h3 class="section">35.4 Creating Packages</h3>
+
+<p>Internally a package is simply a gzipped tar file that contains a
+top level directory of any given name.  This directory will in the
+following be referred to as <code>package</code> and may contain the
+following files
+
+<p class="noindent">
+     <dl>
+<dt><code>package/DESCRIPTION</code><dd>This is a required file containing information about the package. 
+See <a href="The-DESCRIPTION-File.html#The-DESCRIPTION-File">The DESCRIPTION File</a>, for details on this file.
+
+     <br><dt><code>package/COPYING</code><dd>This is a required file containing the license of the package.  No
+restrictions is made on the license in general.  If however the
+package contains dynamically linked functions the license must be
+compatible with the GNU General Public License.
+
+     <br><dt><code>package/INDEX</code><dd>This is an optional file describing the functions provided by the
+package.  If this file is not given then one with be created
+automatically from the functions in the package and the
+<code>Categories</code> keyword in the <code>DESCRIPTION</code> file. 
+See <a href="The-INDEX-file.html#The-INDEX-file">The INDEX file</a>, for details on this file.
+
+     <p><a name="doc_002dPKG_005fADD"></a><br><dt><code>package/PKG_ADD</code><dd>An optional file that includes commands that are run when the package
+is added to the users path.  Note that <code>PKG_ADD</code><!-- /@w --> directives in the
+source code of the package will also be added to this file by the
+Octave package manager.  Note that symbolic links are to be avoided in
+packages, as symbolic links do not exist on some file systems, and so
+a typical use for this file is the replacement of the symbolic link
+
+     <pre class="example">          ln -s foo.oct bar.oct
+</pre>
+     <p class="noindent">with an autoload directive like
+
+     <pre class="example">          autoload ('bar', which ('foo'));
+</pre>
+     <p class="noindent">See <a href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives">PKG_ADD and PKG_DEL directives</a>, for details on <code>PKG_ADD</code><!-- /@w -->
+directives.
+
+     <br><dt><code>package/PKG_DEL</code><dd>An optional file that includes commands that are run when the package
+is removed from the users path.  Note that <code>PKG_DEL</code><!-- /@w --> directives in
+the source code of the package will also be added to this file by the
+Octave package manager. 
+See <a href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives">PKG_ADD and PKG_DEL directives</a>, for details on <code>PKG_DEL</code><!-- /@w -->
+directives.
+
+     <br><dt><code>package/pre_install.m</code><dd>This is an optional script that is run prior to the installation of a
+package.
+
+     <br><dt><code>package/post_install.m</code><dd>This is an optional script that is run after the installation of a
+package.
+
+     <br><dt><code>package/on_uninstall.m</code><dd>This is an optional script that is run prior to the removal of a
+package. 
+</dl>
+
+   <p>Besides the above mentioned files, a package can also contain on or
+more of the following directories
+
+<p class="noindent">
+     <dl>
+<dt><code>package/inst</code><dd>An optional directory containing any files that are directly installed
+by the package.  Typically this will include any <code>m</code>-files.
+
+     <br><dt><code>package/src</code><dd>An optional directory containing code that must be built prior to the
+packages installation.  The Octave package manager will execute
+<samp><span class="file">./configure</span></samp> in this directory if this script exists, and will
+then call <code>make</code> if a file <samp><span class="file">Makefile</span></samp> exists in this
+directory.  <code>make install</code> will however not be called.  If a file
+called <code>FILES</code> exists all files listed there will be copied to the
+<code>inst</code> directory, so they also will be installed.  If the
+<code>FILES</code> file doesn't exist, <samp><span class="file">src/*.m</span></samp> and <samp><span class="file">src/*.oct</span></samp>
+will be copied to the <code>inst</code> directory.
+
+     <br><dt><code>package/doc</code><dd>An optional directory containing documentation for the package.  The
+files in this directory will be directly installed in a sub-directory
+of the installed package for future reference.
+
+     <br><dt><code>package/bin</code><dd>An optional directory containing files that will be added to the
+Octave <code>EXEC_PATH</code><!-- /@w --> when the package is loaded.  This might contain
+external scripts, etc., called by functions within the package. 
+</dl>
+
+<ul class="menu">
+<li><a accesskey="1" href="The-DESCRIPTION-File.html#The-DESCRIPTION-File">The DESCRIPTION File</a>
+<li><a accesskey="2" href="The-INDEX-file.html#The-INDEX-file">The INDEX file</a>
+<li><a accesskey="3" href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives">PKG_ADD and PKG_DEL directives</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Permutation-Matrices.html b/doc/interpreter/HTML/Creating-Permutation-Matrices.html
new file mode 100644
index 0000000..36376bf
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Permutation-Matrices.html
@@ -0,0 +1,95 @@
+<html lang="en">
+<head>
+<title>Creating Permutation Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Usage.html#Basic-Usage" title="Basic Usage">
+<link rel="prev" href="Creating-Diagonal-Matrices.html#Creating-Diagonal-Matrices" title="Creating Diagonal Matrices">
+<link rel="next" href="Explicit-and-Implicit-Conversions.html#Explicit-and-Implicit-Conversions" title="Explicit and Implicit Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Permutation-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Explicit-and-Implicit-Conversions.html#Explicit-and-Implicit-Conversions">Explicit and Implicit Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Creating-Diagonal-Matrices.html#Creating-Diagonal-Matrices">Creating Diagonal Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Usage.html#Basic-Usage">Basic Usage</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.1.2 Creating Permutation Matrices</h4>
+
+<p>For creating permutation matrices, Octave does not introduce a new function, but
+rather overrides an existing syntax: permutation matrices can be conveniently
+created by indexing an identity matrix by permutation vectors. 
+That is, if <var>q</var> is a permutation vector of length <var>n</var>, the expression
+<pre class="example">       P = eye (n) (:, q);
+</pre>
+   <p>will create a permutation matrix - a special matrix object.
+<pre class="example">     eye (n) (q, :)
+</pre>
+   <p>will also work (and create a row permutation matrix), as well as
+<pre class="example">     eye (n) (q1, q2).
+</pre>
+   <p>For example:
+<pre class="example">       eye (4) ([1,3,2,4],:)
+     
+     Permutation Matrix
+     
+        1   0   0   0
+        0   0   1   0
+        0   1   0   0
+        0   0   0   1
+     
+       eye (4) (:,[1,3,2,4])
+     
+     Permutation Matrix
+     
+        1   0   0   0
+        0   0   1   0
+        0   1   0   0
+        0   0   0   1
+</pre>
+   <p>Mathematically, an identity matrix is both diagonal and permutation matrix. 
+In Octave, <code>eye (n)</code> returns a diagonal matrix, because a matrix
+can only have one class.  You can convert this diagonal matrix to a permutation
+matrix by indexing it by an identity permutation, as shown below. 
+This is a special property of the identity matrix; indexing other diagonal
+matrices generally produces a full matrix.
+
+<pre class="example">       eye (3)
+     
+     Diagonal Matrix
+     
+        1   0   0
+        0   1   0
+        0   0   1
+     
+       eye(3)(1:3,:)
+     
+     Permutation Matrix
+     
+        1   0   0
+        0   1   0
+        0   0   1
+</pre>
+   <p>Some other built-in functions can also return permutation matrices.  Examples include
+<dfn>inv</dfn> or <dfn>lu</dfn>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Sparse-Matrices-in-Oct_002dFiles.html b/doc/interpreter/HTML/Creating-Sparse-Matrices-in-Oct_002dFiles.html
new file mode 100644
index 0000000..ffb1826
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Sparse-Matrices-in-Oct_002dFiles.html
@@ -0,0 +1,210 @@
+<html lang="en">
+<head>
+<title>Creating Sparse Matrices in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles" title="Sparse Matrices in Oct-Files">
+<link rel="prev" href="Array-and-Sparse-Differences.html#Array-and-Sparse-Differences" title="Array and Sparse Differences">
+<link rel="next" href="Using-Sparse-Matrices-in-Oct_002dFiles.html#Using-Sparse-Matrices-in-Oct_002dFiles" title="Using Sparse Matrices in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Sparse-Matrices-in-Oct-Files"></a>
+<a name="Creating-Sparse-Matrices-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Using-Sparse-Matrices-in-Oct_002dFiles.html#Using-Sparse-Matrices-in-Oct_002dFiles">Using Sparse Matrices in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Array-and-Sparse-Differences.html#Array-and-Sparse-Differences">Array and Sparse Differences</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">A.1.6.2 Creating Sparse Matrices in Oct-Files</h5>
+
+<p>You have several alternatives for creating a sparse matrix. 
+You can first create the data as three vectors representing the
+row and column indexes and the data, and from those create the matrix. 
+Or alternatively, you can create a sparse matrix with the appropriate
+amount of space and then fill in the values.  Both techniques have their
+advantages and disadvantages.
+
+   <p>Here is an example of how to create a small sparse matrix with the first
+technique
+
+<pre class="example">     int nz = 4, nr = 3, nc = 4;
+     
+     ColumnVector ridx (nz);
+     ColumnVector cidx (nz);
+     ColumnVector data (nz);
+     
+     ridx(0) = 0; ridx(1) = 0; ridx(2) = 1; ridx(3) = 2;
+     cidx(0) = 0; cidx(1) = 1; cidx(2) = 3; cidx(3) = 3;
+     data(0) = 1; data(1) = 2; data(2) = 3; data(3) = 4;
+     
+     SparseMatrix sm (data, ridx, cidx, nr, nc);
+</pre>
+   <p class="noindent">which creates the matrix given in section
+<a href="Storage-of-Sparse-Matrices.html#Storage-of-Sparse-Matrices">Storage of Sparse Matrices</a>.  Note that the compressed matrix
+format is not used at the time of the creation of the matrix itself,
+however it is used internally.
+
+   <p>As previously mentioned, the values of the sparse matrix are stored
+in increasing column-major ordering.  Although the data passed by the
+user does not need to respect this requirement, the pre-sorting the
+data significantly speeds up the creation of the sparse matrix.
+
+   <p>The disadvantage of this technique of creating a sparse matrix is
+that there is a brief time where two copies of the data exists.  Therefore
+for extremely memory constrained problems this might not be the right
+technique to create the sparse matrix.
+
+   <p>The alternative is to first create the sparse matrix with the desired
+number of non-zero elements and then later fill those elements in.  The
+easiest way to do this is
+
+<pre class="example">     int nz = 4, nr = 3, nc = 4;
+     SparseMatrix sm (nr, nc, nz);
+     sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+</pre>
+   <p>That creates the same matrix as previously.  Again, although it is not
+strictly necessary, it is significantly faster if the sparse matrix is
+created in this manner that the elements are added in column-major
+ordering.  The reason for this is that if the elements are inserted
+at the end of the current list of known elements then no element
+in the matrix needs to be moved to allow the new element to be
+inserted.  Only the column indexes need to be updated.
+
+   <p>There are a few further points to note about this technique of creating
+a sparse matrix.  Firstly, it is possible to create a sparse matrix
+with fewer elements than are actually inserted in the matrix.  Therefore
+
+<pre class="example">     int nz = 4, nr = 3, nc = 4;
+     SparseMatrix sm (nr, nc, 0);
+     sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+</pre>
+   <p class="noindent">is perfectly valid.  However it is a very bad idea.  The reason is that
+as each new element is added to the sparse matrix the space allocated
+to it is increased by reallocating the memory.  This is an expensive
+operation, that will significantly slow this means of creating a sparse
+matrix.  Furthermore, it is possible to create a sparse matrix with
+too much storage, so having <var>nz</var> above equaling 6 is also valid. 
+The disadvantage is that the matrix occupies more memory than strictly
+needed.
+
+   <p>It is not always easy to know the number of non-zero elements prior
+to filling a matrix.  For this reason the additional storage for the
+sparse matrix can be removed after its creation with the
+<dfn>maybe_compress</dfn> function.  Furthermore, the maybe_compress can
+deallocate the unused storage, but it can equally remove zero elements
+from the matrix.  The removal of zero elements from the matrix is
+controlled by setting the argument of the <dfn>maybe_compress</dfn> function
+to be ‘<samp><span class="samp">true</span></samp>’.  However, the cost of removing the zeros is high because it
+implies resorting the elements.  Therefore, if possible it is better
+is the user doesn't add the zeros in the first place.  An example of
+the use of <dfn>maybe_compress</dfn> is
+
+<pre class="example">       int nz = 6, nr = 3, nc = 4;
+     
+       SparseMatrix sm1 (nr, nc, nz);
+       sm1(0,0) = 1; sm1(0,1) = 2; sm1(1,3) = 3; sm1(2,3) = 4;
+       sm1.maybe_compress ();  // No zero elements were added
+     
+       SparseMatrix sm2 (nr, nc, nz);
+       sm2(0,0) = 1; sm2(0,1) = 2; sm(0,2) = 0; sm(1,2) = 0;
+       sm1(1,3) = 3; sm1(2,3) = 4;
+       sm2.maybe_compress (true);  // Zero elements were added
+</pre>
+   <p>The use of the <dfn>maybe_compress</dfn> function should be avoided if
+possible, as it will slow the creation of the matrices.
+
+   <p>A third means of creating a sparse matrix is to work directly with
+the data in compressed row format.  An example of this technique might
+be
+
+<!-- Note the @verbatim environment is a relatively new addition to texinfo. -->
+<!-- Therefore use the @example environment and replace @, with @@, -->
+<!-- { with @{, etc -->
+<pre class="example">     octave_value arg;
+     ...
+     int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+     SparseMatrix sm (nr, nc, nz);
+     Matrix m = arg.matrix_value ();
+     
+     int ii = 0;
+     sm.cidx (0) = 0;
+     for (int j = 1; j < nc; j++)
+       {
+         for (int i = 0; i < nr; i++)
+           {
+             double tmp = foo (m(i,j));
+             if (tmp != 0.)
+               {
+                 sm.data(ii) = tmp;
+                 sm.ridx(ii) = i;
+                 ii++;
+               }
+           }
+         sm.cidx(j+1) = ii;
+      }
+     sm.maybe_compress ();  // If don't know a-priori
+                            // the final no of nz.
+</pre>
+   <p class="noindent">which is probably the most efficient means of creating the sparse matrix.
+
+   <p>Finally, it might sometimes arise that the amount of storage initially
+created is insufficient to completely store the sparse matrix.  Therefore,
+the method <code>change_capacity</code> exists to reallocate the sparse memory. 
+The above example would then be modified as
+
+<pre class="example">     octave_value arg;
+     ...
+     int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+     SparseMatrix sm (nr, nc, nz);
+     Matrix m = arg.matrix_value ();
+     
+     int ii = 0;
+     sm.cidx (0) = 0;
+     for (int j = 1; j < nc; j++)
+       {
+         for (int i = 0; i < nr; i++)
+           {
+             double tmp = foo (m(i,j));
+             if (tmp != 0.)
+               {
+                 if (ii == nz)
+                   {
+                     nz += 2;   // Add 2 more elements
+                     sm.change_capacity (nz);
+                   }
+                 sm.data(ii) = tmp;
+                 sm.ridx(ii) = i;
+                 ii++;
+               }
+           }
+         sm.cidx(j+1) = ii;
+      }
+     sm.maybe_mutate ();  // If don't know a-priori
+                          // the final no of nz.
+</pre>
+   <p>Note that both increasing and decreasing the number of non-zero elements in
+a sparse matrix is expensive, as it involves memory reallocation.  Also as
+parts of the matrix, though not its entirety, exist as the old and new copy
+at the same time, additional memory is needed.  Therefore if possible this
+should be avoided.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Sparse-Matrices.html b/doc/interpreter/HTML/Creating-Sparse-Matrices.html
new file mode 100644
index 0000000..e1fa296
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Sparse-Matrices.html
@@ -0,0 +1,393 @@
+<html lang="en">
+<head>
+<title>Creating Sparse Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basics.html#Basics" title="Basics">
+<link rel="prev" href="Storage-of-Sparse-Matrices.html#Storage-of-Sparse-Matrices" title="Storage of Sparse Matrices">
+<link rel="next" href="Information.html#Information" title="Information">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Sparse-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Information.html#Information">Information</a>,
+Previous: <a rel="previous" accesskey="p" href="Storage-of-Sparse-Matrices.html#Storage-of-Sparse-Matrices">Storage of Sparse Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Basics.html#Basics">Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">21.1.2 Creating Sparse Matrices</h4>
+
+<p>There are several means to create sparse matrix.
+
+     <dl>
+<dt>Returned from a function<dd>There are many functions that directly return sparse matrices.  These include
+<dfn>speye</dfn>, <dfn>sprand</dfn>, <dfn>diag</dfn>, etc. 
+<br><dt>Constructed from matrices or vectors<dd>The function <dfn>sparse</dfn> allows a sparse matrix to be constructed from
+three vectors representing the row, column and data.  Alternatively, the
+function <dfn>spconvert</dfn> uses a three column matrix format to allow easy
+importation of data from elsewhere. 
+<br><dt>Created and then filled<dd>The function <dfn>sparse</dfn> or <dfn>spalloc</dfn> can be used to create an empty
+matrix that is then filled by the user
+<br><dt>From a user binary program<dd>The user can directly create the sparse matrix within an oct-file. 
+</dl>
+
+   <p>There are several basic functions to return specific sparse
+matrices.  For example the sparse identity matrix, is a matrix that is
+often needed.  It therefore has its own function to create it as
+<code>speye (</code><var>n</var><code>)</code> or <code>speye (</code><var>r</var><code>, </code><var>c</var><code>)</code>, which
+creates an <var>n</var>-by-<var>n</var> or <var>r</var>-by-<var>c</var> sparse identity
+matrix.
+
+   <p>Another typical sparse matrix that is often needed is a random distribution
+of random elements.  The functions <dfn>sprand</dfn> and <dfn>sprandn</dfn> perform
+this for uniform and normal random distributions of elements.  They have exactly
+the same calling convention, where <code>sprand (</code><var>r</var><code>, </code><var>c</var><code>, </code><var>d</var><code>)</code>,
+creates an <var>r</var>-by-<var>c</var> sparse matrix with a density of filled
+elements of <var>d</var>.
+
+   <p>Other functions of interest that directly create sparse matrices, are
+<dfn>diag</dfn> or its generalization <dfn>spdiags</dfn>, that can take the
+definition of the diagonals of the matrix and create the sparse matrix
+that corresponds to this.  For example
+
+<pre class="example">     s = diag (sparse(randn(1,n)), -1);
+</pre>
+   <p>creates a sparse (<var>n</var>+1)-by-(<var>n</var>+1) sparse matrix with a single
+diagonal defined.
+
+<!-- ./sparse/spdiags.m -->
+   <p><a name="doc_002dspdiags"></a>
+
+<div class="defun">
+— Function File: [<var>b</var>, <var>c</var>] = <b>spdiags</b> (<var>a</var>)<var><a name="index-spdiags-1636"></a></var><br>
+— Function File: <var>b</var> = <b>spdiags</b> (<var>a, c</var>)<var><a name="index-spdiags-1637"></a></var><br>
+— Function File: <var>b</var> = <b>spdiags</b> (<var>v, c, a</var>)<var><a name="index-spdiags-1638"></a></var><br>
+— Function File: <var>b</var> = <b>spdiags</b> (<var>v, c, m, n</var>)<var><a name="index-spdiags-1639"></a></var><br>
+<blockquote><p>A generalization of the function <code>diag</code>.  Called with a single
+input argument, the non-zero diagonals <var>c</var> of <var>A</var> are extracted. 
+With two arguments the diagonals to extract are given by the vector
+<var>c</var>.
+
+        <p>The other two forms of <code>spdiags</code> modify the input matrix by
+replacing the diagonals.  They use the columns of <var>v</var> to replace
+the columns represented by the vector <var>c</var>.  If the sparse matrix
+<var>a</var> is defined then the diagonals of this matrix are replaced. 
+Otherwise a matrix of <var>m</var> by <var>n</var> is created with the
+diagonals given by <var>v</var>.
+
+        <p>Negative values of <var>c</var> represent diagonals below the main
+diagonal, and positive values of <var>c</var> diagonals above the main
+diagonal.
+
+        <p>For example
+
+     <pre class="example">          spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
+              5 10  0  0
+                1  6 11  0
+                0  2  7 12
+                0  0  3  8
+                0  0  0  4
+</pre>
+        </blockquote></div>
+
+<!-- ./sparse/speye.m -->
+   <p><a name="doc_002dspeye"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>speye</b> (<var>m</var>)<var><a name="index-speye-1640"></a></var><br>
+— Function File: <var>y</var> = <b>speye</b> (<var>m, n</var>)<var><a name="index-speye-1641"></a></var><br>
+— Function File: <var>y</var> = <b>speye</b> (<var>sz</var>)<var><a name="index-speye-1642"></a></var><br>
+<blockquote><p>Returns a sparse identity matrix.  This is significantly more
+efficient than <code>sparse (eye (</code><var>m</var><code>))</code> as the full matrix
+is not constructed.
+
+        <p>Called with a single argument a square matrix of size <var>m</var> by
+<var>m</var> is created.  Otherwise a matrix of <var>m</var> by <var>n</var> is
+created.  If called with a single vector argument, this argument
+is taken to be the size of the matrix to create. 
+</p></blockquote></div>
+
+<!-- ./sparse/spfun.m -->
+   <p><a name="doc_002dspfun"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>spfun</b> (<var>f,x</var>)<var><a name="index-spfun-1643"></a></var><br>
+<blockquote><p>Compute <code>f(</code><var>x</var><code>)</code> for the non-zero values of <var>x</var>. 
+This results in a sparse matrix with the same structure as
+<var>x</var>.  The function <var>f</var> can be passed as a string, a
+function handle or an inline function. 
+</p></blockquote></div>
+
+<!-- ./deprecated/spmax.m -->
+   <p><a name="doc_002dspmax"></a>
+
+<div class="defun">
+— Mapping Function:  <b>spmax</b> (<var>x, y, dim</var>)<var><a name="index-spmax-1644"></a></var><br>
+— Mapping Function: [<var>w</var>, <var>iw</var>] = <b>spmax</b> (<var>x</var>)<var><a name="index-spmax-1645"></a></var><br>
+<blockquote><p>This function has been deprecated.  Use <code>max</code> instead. 
+</p></blockquote></div>
+
+<!-- ./deprecated/spmin.m -->
+   <p><a name="doc_002dspmin"></a>
+
+<div class="defun">
+— Mapping Function:  <b>spmin</b> (<var>x, y, dim</var>)<var><a name="index-spmin-1646"></a></var><br>
+— Mapping Function: [<var>w</var>, <var>iw</var>] = <b>spmin</b> (<var>x</var>)<var><a name="index-spmin-1647"></a></var><br>
+<blockquote><p>This function has been deprecated.  Use <code>min</code> instead. 
+</p></blockquote></div>
+
+<!-- ./sparse/spones.m -->
+   <p><a name="doc_002dspones"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>spones</b> (<var>x</var>)<var><a name="index-spones-1648"></a></var><br>
+<blockquote><p>Replace the non-zero entries of <var>x</var> with ones.  This creates a
+sparse matrix with the same structure as <var>x</var>. 
+</p></blockquote></div>
+
+<!-- ./sparse/sprand.m -->
+   <p><a name="doc_002dsprand"></a>
+
+<div class="defun">
+— Function File:  <b>sprand</b> (<var>m, n, d</var>)<var><a name="index-sprand-1649"></a></var><br>
+— Function File:  <b>sprand</b> (<var>s</var>)<var><a name="index-sprand-1650"></a></var><br>
+<blockquote><p>Generate a random sparse matrix.  The size of the matrix will be
+<var>m</var> by <var>n</var>, with a density of values given by <var>d</var>. 
+<var>d</var> should be between 0 and 1. Values will be uniformly
+distributed between 0 and 1.
+
+        <p>Note: sometimes the actual density may be a bit smaller than <var>d</var>. 
+This is unlikely to happen for large really sparse matrices.
+
+        <p>If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix <var>S</var> is non-zero. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsprandn.html#doc_002dsprandn">sprandn</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/sprandn.m -->
+   <p><a name="doc_002dsprandn"></a>
+
+<div class="defun">
+— Function File:  <b>sprandn</b> (<var>m, n, d</var>)<var><a name="index-sprandn-1651"></a></var><br>
+— Function File:  <b>sprandn</b> (<var>s</var>)<var><a name="index-sprandn-1652"></a></var><br>
+<blockquote><p>Generate a random sparse matrix.  The size of the matrix will be
+<var>m</var> by <var>n</var>, with a density of values given by <var>d</var>. 
+<var>d</var> should be between 0 and 1. Values will be normally
+distributed with mean of zero and variance 1.
+
+        <p>Note: sometimes the actual density may be a bit smaller than <var>d</var>. 
+This is unlikely to happen for large really sparse matrices.
+
+        <p>If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix <var>S</var> is non-zero. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsprand.html#doc_002dsprand">sprand</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/sprandsym.m -->
+   <p><a name="doc_002dsprandsym"></a>
+
+<div class="defun">
+— Function File:  <b>sprandsym</b> (<var>n, d</var>)<var><a name="index-sprandsym-1653"></a></var><br>
+— Function File:  <b>sprandsym</b> (<var>s</var>)<var><a name="index-sprandsym-1654"></a></var><br>
+<blockquote><p>Generate a symmetric random sparse matrix.  The size of the matrix will be
+<var>n</var> by <var>n</var>, with a density of values given by <var>d</var>. 
+<var>d</var> should be between 0 and 1. Values will be normally
+distributed with mean of zero and variance 1.
+
+        <p>Note: sometimes the actual density may be a bit smaller than <var>d</var>. 
+This is unlikely to happen for large really sparse matrices.
+
+        <p>If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix <var>S</var> is non-zero in its lower
+triangular part. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsprand.html#doc_002dsprand">sprand</a>, <a href="doc_002dsprandn.html#doc_002dsprandn">sprandn</a>. 
+</p></blockquote></div>
+
+   <p>The recommended way for the user to create a sparse matrix, is to create
+two vectors containing the row and column index of the data and a third
+vector of the same size containing the data to be stored.  For example
+
+<pre class="example">       ri = ci = d = [];
+       for j = 1:c
+         ri = [ri; randperm(r)(1:n)'];
+         ci = [ci; j*ones(n,1)];
+         d = [d; rand(n,1)];
+       endfor
+       s = sparse (ri, ci, d, r, c);
+</pre>
+   <p>creates an <var>r</var>-by-<var>c</var> sparse matrix with a random distribution
+of <var>n</var> (<<var>r</var>) elements per column.  The elements of the vectors
+do not need to be sorted in any particular order as Octave will sort
+them prior to storing the data.  However, pre-sorting the data will
+make the creation of the sparse matrix faster.
+
+   <p>The function <dfn>spconvert</dfn> takes a three or four column real matrix. 
+The first two columns represent the row and column index respectively and
+the third and four columns, the real and imaginary parts of the sparse
+matrix.  The matrix can contain zero elements and the elements can be
+sorted in any order.  Adding zero elements is a convenient way to define
+the size of the sparse matrix.  For example
+
+<pre class="example">     s = spconvert ([1 2 3 4; 1 3 4 4; 1 2 3 0]')
+      Compressed Column Sparse (rows=4, cols=4, nnz=3)
+           (1 , 1) -> 1
+           (2 , 3) -> 2
+           (3 , 4) -> 3
+</pre>
+   <p>An example of creating and filling a matrix might be
+
+<pre class="example">     k = 5;
+     nz = r * k;
+     s = spalloc (r, c, nz)
+     for j = 1:c
+       idx = randperm (r);
+       s (:, j) = [zeros(r - k, 1); ...
+             rand(k, 1)] (idx);
+     endfor
+</pre>
+   <p>It should be noted, that due to the way that the Octave
+assignment functions are written that the assignment will reallocate
+the memory used by the sparse matrix at each iteration of the above loop. 
+Therefore the <dfn>spalloc</dfn> function ignores the <var>nz</var> argument and
+does not preassign the memory for the matrix.  Therefore, it is vitally
+important that code using to above structure should be vectorized
+as much as possible to minimize the number of assignments and reduce the
+number of memory allocations.
+
+<!-- data.cc -->
+   <p><a name="doc_002dfull"></a>
+
+<div class="defun">
+— Loadable Function: <var>FM</var> = <b>full</b> (<var>SM</var>)<var><a name="index-full-1655"></a></var><br>
+<blockquote><p> returns a full storage matrix from a sparse, diagonal, permutation matrix or a range. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/spalloc.m -->
+   <p><a name="doc_002dspalloc"></a>
+
+<div class="defun">
+— Function File: <var>s</var> = <b>spalloc</b> (<var>r, c, nz</var>)<var><a name="index-spalloc-1656"></a></var><br>
+<blockquote><p>Returns an empty sparse matrix of size <var>r</var>-by-<var>c</var>.  As Octave
+resizes sparse matrices at the first opportunity, so that no additional
+space is needed, the argument <var>nz</var> is ignored.  This function is
+provided only for compatibility reasons.
+
+        <p>It should be noted that this means that code like
+
+     <pre class="example">          k = 5;
+          nz = r * k;
+          s = spalloc (r, c, nz)
+          for j = 1:c
+            idx = randperm (r);
+            s (:, j) = [zeros(r - k, 1); rand(k, 1)] (idx);
+          endfor
+</pre>
+        <p>will reallocate memory at each step.  It is therefore vitally important
+that code like this is vectorized as much as possible. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>, <a href="doc_002dnzmax.html#doc_002dnzmax">nzmax</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/sparse.cc -->
+   <p><a name="doc_002dsparse"></a>
+
+<div class="defun">
+— Loadable Function: <var>s</var> = <b>sparse</b> (<var>a</var>)<var><a name="index-sparse-1657"></a></var><br>
+— Loadable Function: <var>s</var> = <b>sparse</b> (<var>i, j, sv, m, n, nzmax</var>)<var><a name="index-sparse-1658"></a></var><br>
+— Loadable Function: <var>s</var> = <b>sparse</b> (<var>i, j, sv</var>)<var><a name="index-sparse-1659"></a></var><br>
+— Loadable Function: <var>s</var> = <b>sparse</b> (<var>i, j, s, m, n, "unique"</var>)<var><a name="index-sparse-1660"></a></var><br>
+— Loadable Function: <var>s</var> = <b>sparse</b> (<var>m, n</var>)<var><a name="index-sparse-1661"></a></var><br>
+<blockquote><p>Create a sparse matrix from the full matrix or row, column, value triplets. 
+If <var>a</var> is a full matrix, convert it to a sparse matrix representation,
+removing all zero values in the process.
+
+        <p>Given the integer index vectors <var>i</var> and <var>j</var>, a 1-by-<code>nnz</code> vector
+of real of complex values <var>sv</var>, overall dimensions <var>m</var> and <var>n</var>
+of the sparse matrix.  The argument <code>nzmax</code> is ignored but accepted for
+compatibility with <span class="sc">matlab</span>.  If <var>m</var> or <var>n</var> are not specified their
+values are derived from the maximum index in the vectors <var>i</var> and <var>j</var>
+as given by <var>m</var><code> = max (</code><var>i</var><code>)</code>, <var>n</var><code> = max (</code><var>j</var><code>)</code>.
+
+        <p><strong>Note</strong>: if multiple values are specified with the same
+<var>i</var>, <var>j</var> indices, the corresponding values in <var>s</var> will
+be added.
+
+        <p>The following are all equivalent:
+
+     <pre class="example">          s = sparse (i, j, s, m, n)
+          s = sparse (i, j, s, m, n, "summation")
+          s = sparse (i, j, s, m, n, "sum")
+</pre>
+        <p>Given the option "unique". if more than two values are specified for the
+same <var>i</var>, <var>j</var> indices, the last specified value will be used.
+
+        <p><code>sparse(</code><var>m</var><code>, </code><var>n</var><code>)</code> is equivalent to
+<code>sparse ([], [], [], </code><var>m</var><code>, </code><var>n</var><code>, 0)</code>
+
+        <p>If any of <var>sv</var>, <var>i</var> or <var>j</var> are scalars, they are expanded
+to have a common size. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfull.html#doc_002dfull">full</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/spconvert.m -->
+   <p><a name="doc_002dspconvert"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>spconvert</b> (<var>m</var>)<var><a name="index-spconvert-1662"></a></var><br>
+<blockquote><p>This function converts for a simple sparse matrix format easily
+produced by other programs into Octave's internal sparse format.  The
+input <var>x</var> is either a 3 or 4 column real matrix, containing
+the row, column, real and imaginary parts of the elements of the
+sparse matrix.  An element with a zero real and imaginary part can
+be used to force a particular matrix size. 
+</p></blockquote></div>
+
+   <p>The above problem of memory reallocation can be avoided in
+oct-files.  However, the construction of a sparse matrix from an oct-file
+is more complex than can be discussed here, and
+you are referred to chapter <a href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>, to have
+a full description of the techniques involved.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Strings.html b/doc/interpreter/HTML/Creating-Strings.html
new file mode 100644
index 0000000..40aced6
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Strings.html
@@ -0,0 +1,69 @@
+<html lang="en">
+<head>
+<title>Creating Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="prev" href="Character-Arrays.html#Character-Arrays" title="Character Arrays">
+<link rel="next" href="Comparing-Strings.html#Comparing-Strings" title="Comparing Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Strings"></a>
+Next: <a rel="next" accesskey="n" href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a>,
+Previous: <a rel="previous" accesskey="p" href="Character-Arrays.html#Character-Arrays">Character Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.3 Creating Strings</h3>
+
+<p>The easiest way to create a string is, as illustrated in the introduction,
+to enclose a text in double-quotes or single-quotes.  It is however
+possible to create a string without actually writing a text.  The
+function <code>blanks</code> creates a string of a given length consisting
+only of blank characters (ASCII code 32).
+
+<!-- ./strings/blanks.m -->
+   <p><a name="doc_002dblanks"></a>
+
+<div class="defun">
+— Function File:  <b>blanks</b> (<var>n</var>)<var><a name="index-blanks-287"></a></var><br>
+<blockquote><p>Return a string of <var>n</var> blanks, for example:
+
+     <pre class="example">          blanks(10);
+          whos ans;
+               
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     ans         1x10                        10  char
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drepmat.html#doc_002drepmat">repmat</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a>
+<li><a accesskey="2" href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">Conversion of Numerical Data to Strings</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-Structures.html b/doc/interpreter/HTML/Creating-Structures.html
new file mode 100644
index 0000000..1cba44b
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-Structures.html
@@ -0,0 +1,117 @@
+<html lang="en">
+<head>
+<title>Creating Structures - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Structures.html#Data-Structures" title="Data Structures">
+<link rel="prev" href="Structure-Arrays.html#Structure-Arrays" title="Structure Arrays">
+<link rel="next" href="Manipulating-Structures.html#Manipulating-Structures" title="Manipulating Structures">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-Structures"></a>
+Next: <a rel="next" accesskey="n" href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a>,
+Previous: <a rel="previous" accesskey="p" href="Structure-Arrays.html#Structure-Arrays">Structure Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Data-Structures.html#Data-Structures">Data Structures</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.1.3 Creating Structures</h4>
+
+<p>As well as indexing a structure with ".", Octave can create a structure
+with the <code>struct</code> command.  <code>struct</code> takes pairs of arguments,
+where the first argument in the pair is the fieldname to include in the
+structure and the second is a scalar or cell array, representing the
+values to include in the structure or structure array.  For example
+
+<pre class="example">     struct ("field1", 1, "field2", 2)
+      ans =
+           {
+             field1 =  1
+             field2 =  2
+           }
+</pre>
+   <p>If the values passed to <code>struct</code> are a mix of scalar and cell
+arrays, then the scalar arguments are expanded to create a
+structure array with a consistent dimension.  For example
+
+<pre class="example">     s = struct ("field1", {1, "one"}, "field2", {2, "two"},
+             "field3", 3);
+     s.field1
+          
+             ans =  1
+             ans = one
+     
+     s.field2
+          
+             ans =  2
+             ans = two
+     
+     s.field3
+          
+             ans =  3
+             ans =  3
+</pre>
+   <p>If you want to create a struct which contains a cell array as an
+individual field, you have to put it into another cell array like in
+the following example:
+
+<pre class="example">     struct ("field1", {{1, "one"}}, "field2", 2)
+           ans =
+             {
+               field1 =
+     
+             {
+               [1,1] =  1
+               [1,2] = one
+             }
+     
+               field2 =  2
+             }
+</pre>
+   <!-- ov-struct.cc -->
+   <p><a name="doc_002dstruct"></a>
+
+<div class="defun">
+— Built-in Function:  <b>struct</b> (<var>"field", value, "field", value, <small class="dots">...</small></var>)<var><a name="index-struct-373"></a></var><br>
+<blockquote>
+        <p>Create a structure and initialize its value.
+
+        <p>If the values are cell arrays, create a structure array and initialize
+its values.  The dimensions of each cell array of values must match. 
+Singleton cells and non-cell values are repeated so that they fill
+the entire array.  If the cells are empty, create an empty structure
+array with the specified field names.
+
+        <p>If the argument is an object, return the underlying struct. 
+</p></blockquote></div>
+
+   <p>The function <code>isstruct</code> can be used to test if an object is a
+structure or a structure array.
+
+<!-- ov-struct.cc -->
+   <p><a name="doc_002disstruct"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isstruct</b> (<var>expr</var>)<var><a name="index-isstruct-374"></a></var><br>
+<blockquote><p>Return 1 if the value of the expression <var>expr</var> is a structure. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Creating-a-Class.html b/doc/interpreter/HTML/Creating-a-Class.html
new file mode 100644
index 0000000..b7b8840
--- /dev/null
+++ b/doc/interpreter/HTML/Creating-a-Class.html
@@ -0,0 +1,167 @@
+<html lang="en">
+<head>
+<title>Creating a Class - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link rel="next" href="Manipulating-Classes.html#Manipulating-Classes" title="Manipulating Classes">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Creating-a-Class"></a>
+Next: <a rel="next" accesskey="n" href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a>,
+Up: <a rel="up" accesskey="u" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>
+<hr>
+</div>
+
+<h3 class="section">33.1 Creating a Class</h3>
+
+<p>We use in the following text a polynomial class to demonstrate the use
+of object oriented programming within Octave.  This class was chosen as
+it is simple, and so doesn't distract unnecessarily from the
+discussion of the programming features of Octave.  However, even still
+a small understand of the polynomial class itself is necessary to
+fully grasp the techniques described.
+
+   <p>The polynomial class is used to represent polynomials of the form
+
+<pre class="example">     a0 + a1 * x + a2 * x^2 + ... + an * x^n
+</pre>
+   <p class="noindent">where
+a0, a1, etc. are real scalars. 
+Thus the polynomial can be represented by a vector
+
+<pre class="example">     a = [a0, a1, a2, ..., an];
+</pre>
+   <p>We therefore now have sufficient information about the requirements of
+the class constructor for our polynomial class to write it.  All object
+oriented classes in Octave, must be contained with a directory taking
+the name of the class, prepended with the @ symbol.  For example, with
+our polynomial class, we would place the methods defining the class in
+the @polynomial directory.
+
+   <p>The constructor of the class, must have the name of the class itself
+and so in our example the constructor with have the name
+<samp><span class="file">@polynomial/polynomial.m</span></samp>.  Also ideally when the constructor is
+called with no arguments to should return a value object.  So for example
+our polynomial might look like
+
+<pre class="example"><pre class="verbatim">     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} polynomial ()
+     ## @deftypefnx {Function File} {} polynomial (@var{a})
+     ## Creates a polynomial object representing the polynomial
+     ##
+     ## @example
+     ## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+     ## @end example
+     ##
+     ## from a vector of coefficients [a0 a1 a2 ... an].
+     ## @end deftypefn
+     
+     function p = polynomial (a)
+       if (nargin == 0)
+         p.poly = [0];
+         p = class (p, "polynomial");
+       elseif (nargin == 1)
+         if (strcmp (class (a), "polynomial"))
+           p = a;
+         elseif (isvector (a) && isreal (a))
+           p.poly = a(:).';
+           p = class (p, "polynomial");
+         else
+           error ("polynomial: expecting real vector");
+         endif
+       else
+         print_usage ();
+       endif
+     endfunction
+</pre>
+</pre>
+   <p>Note that the return value of the constructor must be the output of
+the <code>class</code> function called with the first argument being a
+structure and the second argument being the class name.  An example of
+the call to this constructor function is then
+
+<pre class="example">     p = polynomial ([1, 0, 1]);
+</pre>
+   <p>Note that methods of a class can be documented.  The help for the
+constructor itself can be obtained with the constructor name, that is
+for the polynomial constructor <code>help polynomial</code> will return the
+help string.  Also the help can be obtained by restricting the search
+for the help to a particular class, for example <code>help
+ at polynomial/polynomial</code>.  This second method is the only means of
+getting help for the overloaded methods and functions of the class.
+
+   <p>The same is true for other Octave functions that take a function name
+as an argument.  For example <code>type @polynomial/display</code> will
+print the code of the display method of the polynomial class to the
+screen, and <code>dbstop @polynomial/display</code> will set a breakpoint
+at the first executable line of the display method of the polynomial
+class.
+
+   <p>To check where a variable is a user class, the <code>isobject</code> and
+<code>isa</code> functions can be used. for example
+
+<pre class="example">     p = polynomial ([1, 0, 1]);
+     isobject (p)
+      1
+     isa (p, "polynomial")
+      1
+</pre>
+   <!-- ov-class.cc -->
+   <p><a name="doc_002disobject"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isobject</b> (<var>x</var>)<var><a name="index-isobject-2254"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a class object. 
+</p></blockquote></div>
+
+<p class="noindent">The available methods of a class can be displayed with the
+<code>methods</code> function.
+
+<!-- ov-class.cc -->
+   <p><a name="doc_002dmethods"></a>
+
+<div class="defun">
+— Built-in Function:  <b>methods</b> (<var>x</var>)<var><a name="index-methods-2255"></a></var><br>
+— Built-in Function:  <b>methods</b> (<var>"classname"</var>)<var><a name="index-methods-2256"></a></var><br>
+<blockquote><p>Return a cell array containing the names of the methods for the
+object <var>x</var> or the named class. 
+</p></blockquote></div>
+
+<p class="noindent">To inquire whether a particular method is available to a user class, the
+<code>ismethod</code> function can be used.
+
+<!-- ov-class.cc -->
+   <p><a name="doc_002dismethod"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ismethod</b> (<var>x, method</var>)<var><a name="index-ismethod-2257"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a class object and the string <var>method</var>
+is a method of this class. 
+</p></blockquote></div>
+
+<p class="noindent">For example
+
+<pre class="example">     p = polynomial ([1, 0, 1]);
+     ismethod (p, "roots")
+      1
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Current-Working-Directory.html b/doc/interpreter/HTML/Current-Working-Directory.html
new file mode 100644
index 0000000..f6b5651
--- /dev/null
+++ b/doc/interpreter/HTML/Current-Working-Directory.html
@@ -0,0 +1,143 @@
+<html lang="en">
+<head>
+<title>Current Working Directory - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Environment-Variables.html#Environment-Variables" title="Environment Variables">
+<link rel="next" href="Password-Database-Functions.html#Password-Database-Functions" title="Password Database Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Current-Working-Directory"></a>
+Next: <a rel="next" accesskey="n" href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Environment-Variables.html#Environment-Variables">Environment Variables</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.8 Current Working Directory</h3>
+
+<!-- dirfns.cc -->
+<p><a name="doc_002dcd"></a>
+
+<div class="defun">
+— Command: <b>cd</b><var> dir<a name="index-cd-2425"></a></var><br>
+— Command: <b>chdir</b><var> dir<a name="index-chdir-2426"></a></var><br>
+<blockquote><p>Change the current working directory to <var>dir</var>.  If <var>dir</var> is
+omitted, the current directory is changed to the user's home
+directory.  For example,
+
+     <pre class="example">          cd ~/octave
+</pre>
+        <p class="noindent">Changes the current working directory to <samp><span class="file">~/octave</span></samp>.  If the
+directory does not exist, an error message is printed and the working
+directory is not changed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmkdir.html#doc_002dmkdir">mkdir</a>, <a href="doc_002drmdir.html#doc_002drmdir">rmdir</a>, <a href="doc_002ddir.html#doc_002ddir">dir</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/ls.m -->
+   <p><a name="doc_002dls"></a>
+
+<div class="defun">
+— Command: <b>ls</b><var> options<a name="index-ls-2427"></a></var><br>
+<blockquote><p>List directory contents.  For example,
+
+     <pre class="example">          ls -l
+               -| total 12
+               -| -rw-r--r--   1 jwe  users  4488 Aug 19 04:02 foo.m
+               -| -rw-r--r--   1 jwe  users  1315 Aug 17 23:14 bar.m
+</pre>
+        <p>The <code>dir</code> and <code>ls</code> commands are implemented by calling your
+system's directory listing command, so the available options may vary
+from system to system. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddir.html#doc_002ddir">dir</a>, <a href="doc_002dstat.html#doc_002dstat">stat</a>, <a href="doc_002dreaddir.html#doc_002dreaddir">readdir</a>, <a href="doc_002dglob.html#doc_002dglob">glob</a>, <a href="doc_002dfilesep.html#doc_002dfilesep">filesep</a>, <a href="doc_002dls_005fcommand.html#doc_002dls_005fcommand">ls_command</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/ls_command.m -->
+   <p><a name="doc_002dls_005fcommand"></a>
+
+<div class="defun">
+— Function File: [<var>old_cmd</var> = <b>ls_command</b> (<var>cmd</var>)<var><a name="index-ls_005fcommand-2428"></a></var><br>
+<blockquote><p>Set or return the shell command used by Octave's <code>ls</code> command. 
+The value of <var>cmd</var> must be a character string. 
+With no arguments, simply return the previous value. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dls.html#doc_002dls">ls</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/dir.m -->
+   <p><a name="doc_002ddir"></a>
+
+<div class="defun">
+— Function File:  <b>dir</b> (<var>directory</var>)<var><a name="index-dir-2429"></a></var><br>
+— Function File: [<var>list</var>] = <b>dir</b> (<var>directory</var>)<var><a name="index-dir-2430"></a></var><br>
+<blockquote><p>Display file listing for directory <var>directory</var>.  If a return
+value is requested, return a structure array with the fields
+
+     <pre class="example">          name
+          bytes
+          date
+          isdir
+          statinfo
+</pre>
+        <p class="noindent">in which <code>statinfo</code> is the structure returned from <code>stat</code>.
+
+        <p>If <var>directory</var> is not a directory, return information about the
+named <var>filename</var>.  <var>directory</var> may be a list of directories
+specified either by name or with wildcard characters (like * and ?) 
+which will be expanded with glob.
+
+        <p>Note that for symbolic links, <code>dir</code> returns information about
+the file that a symbolic link points to instead of the link itself. 
+However, if the link points to a nonexistent file, <code>dir</code> returns
+information about the link. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dls.html#doc_002dls">ls</a>, <a href="doc_002dstat.html#doc_002dstat">stat</a>, <a href="doc_002dlstat.html#doc_002dlstat">lstat</a>, <a href="doc_002dreaddir.html#doc_002dreaddir">readdir</a>, <a href="doc_002dglob.html#doc_002dglob">glob</a>, <a href="doc_002dfilesep.html#doc_002dfilesep">filesep</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dpwd"></a>
+
+<div class="defun">
+— Built-in Function:  <b>pwd</b> ()<var><a name="index-pwd-2431"></a></var><br>
+<blockquote><p>Return the current working directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddir.html#doc_002ddir">dir</a>, <a href="doc_002dls.html#doc_002dls">ls</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Cursor-Motion.html b/doc/interpreter/HTML/Cursor-Motion.html
new file mode 100644
index 0000000..10b3645
--- /dev/null
+++ b/doc/interpreter/HTML/Cursor-Motion.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Cursor Motion - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="next" href="Killing-and-Yanking.html#Killing-and-Yanking" title="Killing and Yanking">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Cursor-Motion"></a>
+Next: <a rel="next" accesskey="n" href="Killing-and-Yanking.html#Killing-and-Yanking">Killing and Yanking</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.1 Cursor Motion</h4>
+
+<p>The following commands allow you to position the cursor.
+
+     <dl>
+<dt><kbd>C-b</kbd><dd>Move back one character.
+
+     <br><dt><kbd>C-f</kbd><dd>Move forward one character.
+
+     <br><dt><kbd><DEL></kbd><dd>Delete the character to the left of the cursor.
+
+     <br><dt><kbd>C-d</kbd><dd>Delete the character underneath the cursor.
+
+     <br><dt><kbd>M-f</kbd><dd>Move forward a word.
+
+     <br><dt><kbd>M-b</kbd><dd>Move backward a word.
+
+     <br><dt><kbd>C-a</kbd><dd>Move to the start of the line.
+
+     <br><dt><kbd>C-e</kbd><dd>Move to the end of the line.
+
+     <br><dt><kbd>C-l</kbd><dd>Clear the screen, reprinting the current line at the top.
+
+     <br><dt><kbd>C-_</kbd><dt><kbd>C-/</kbd><dd>Undo the last action.  You can undo all the way back to an empty line.
+
+     <br><dt><kbd>M-r</kbd><dd>Undo all changes made to this line.  This is like typing the `undo'
+command enough times to get back to the beginning. 
+</dl>
+
+   <p>The above table describes the most basic possible keystrokes that you need
+in order to do editing of the input line.  On most terminals, you can
+also use the left and right arrow keys in place of <kbd>C-f</kbd> and <kbd>C-b</kbd>
+to move forward and backward.
+
+   <p>Notice how <kbd>C-f</kbd> moves forward a character, while <kbd>M-f</kbd> moves
+forward a word.  It is a loose convention that control keystrokes
+operate on characters while meta keystrokes operate on words.
+
+   <p><a name="index-clearing-the-screen-106"></a>
+The function <code>clc</code> will allow you to clear the screen from within
+Octave programs.
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dclc"></a>
+
+<div class="defun">
+— Built-in Function:  <b>clc</b> ()<var><a name="index-clc-107"></a></var><br>
+— Built-in Function:  <b>home</b> ()<var><a name="index-home-108"></a></var><br>
+<blockquote><p>Clear the terminal screen and move the cursor to the upper left corner. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Customizing-readline.html b/doc/interpreter/HTML/Customizing-readline.html
new file mode 100644
index 0000000..1c9ee04
--- /dev/null
+++ b/doc/interpreter/HTML/Customizing-readline.html
@@ -0,0 +1,71 @@
+<html lang="en">
+<head>
+<title>Customizing readline - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Commands-For-History.html#Commands-For-History" title="Commands For History">
+<link rel="next" href="Customizing-the-Prompt.html#Customizing-the-Prompt" title="Customizing the Prompt">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Customizing-readline"></a>
+Next: <a rel="next" accesskey="n" href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a>,
+Previous: <a rel="previous" accesskey="p" href="Commands-For-History.html#Commands-For-History">Commands For History</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.6 Customizing <code>readline</code></h4>
+
+<p><a name="index-g_t_0040file_007b_007e_002f_002einputrc_007d-129"></a><a name="index-customizing-_0040code_007breadline_007d-130"></a><a name="index-g_t_0040code_007breadline_007d-customization-131"></a>
+Octave uses the GNU Readline library for command-line editing and
+history features.  Readline is very flexible and can be modified through
+a configuration file of commands (See the GNU Readline library for the
+exact command syntax).  The default configuration file is normally
+<samp><span class="file">~/.inputrc</span></samp>.
+
+   <p>Octave provides two commands for initializing Readline and thereby changing
+the command line behavior.
+
+<!-- input.cc -->
+   <p><a name="doc_002dread_005freadline_005finit_005ffile"></a>
+
+<div class="defun">
+— Built-in Function:  <b>read_readline_init_file</b> (<var>file</var>)<var><a name="index-read_005freadline_005finit_005ffile-132"></a></var><br>
+<blockquote><p>Read the readline library initialization file <var>file</var>.  If
+<var>file</var> is omitted, read the default initialization file (normally
+<samp><span class="file">~/.inputrc</span></samp>).
+
+        <p>See <a href="../readline/Readline-Init-File.html#Readline-Init-File">Readline Init File</a>,
+for details. 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002dre_005fread_005freadline_005finit_005ffile"></a>
+
+<div class="defun">
+— Built-in Function:  <b>re_read_readline_init_file</b> ()<var><a name="index-re_005fread_005freadline_005finit_005ffile-133"></a></var><br>
+<blockquote><p>Re-read the last readline library initialization file that was read. 
+See <a href="../readline/Readline-Init-File.html#Readline-Init-File">Readline Init File</a>,
+for details. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Customizing-the-Prompt.html b/doc/interpreter/HTML/Customizing-the-Prompt.html
new file mode 100644
index 0000000..9836d2b
--- /dev/null
+++ b/doc/interpreter/HTML/Customizing-the-Prompt.html
@@ -0,0 +1,138 @@
+<html lang="en">
+<head>
+<title>Customizing the Prompt - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Customizing-readline.html#Customizing-readline" title="Customizing readline">
+<link rel="next" href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands" title="Diary and Echo Commands">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Customizing-the-Prompt"></a>
+Next: <a rel="next" accesskey="n" href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a>,
+Previous: <a rel="previous" accesskey="p" href="Customizing-readline.html#Customizing-readline">Customizing readline</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.7 Customizing the Prompt</h4>
+
+<p><a name="index-prompt-customization-134"></a><a name="index-customizing-the-prompt-135"></a>
+The following variables are available for customizing the appearance of
+the command-line prompts.  Octave allows the prompt to be customized by
+inserting a number of backslash-escaped special characters that are
+decoded as follows:
+
+     <dl>
+<dt>‘<samp><span class="samp">\t</span></samp>’<dd>The time.
+
+     <br><dt>‘<samp><span class="samp">\d</span></samp>’<dd>The date.
+
+     <br><dt>‘<samp><span class="samp">\n</span></samp>’<dd>Begins a new line by printing the equivalent of a carriage return
+followed by a line feed.
+
+     <br><dt>‘<samp><span class="samp">\s</span></samp>’<dd>The name of the program (usually just ‘<samp><span class="samp">octave</span></samp>’).
+
+     <br><dt>‘<samp><span class="samp">\w</span></samp>’<dd>The current working directory.
+
+     <br><dt>‘<samp><span class="samp">\W</span></samp>’<dd>The basename of the current working directory.
+
+     <br><dt>‘<samp><span class="samp">\u</span></samp>’<dd>The username of the current user.
+
+     <br><dt>‘<samp><span class="samp">\h</span></samp>’<dd>The hostname, up to the first `.'.
+
+     <br><dt>‘<samp><span class="samp">\H</span></samp>’<dd>The hostname.
+
+     <br><dt>‘<samp><span class="samp">\#</span></samp>’<dd>The command number of this command, counting from when Octave starts.
+
+     <br><dt>‘<samp><span class="samp">\!</span></samp>’<dd>The history number of this command.  This differs from ‘<samp><span class="samp">\#</span></samp>’ by the
+number of commands in the history list when Octave starts.
+
+     <br><dt>‘<samp><span class="samp">\$</span></samp>’<dd>If the effective UID is 0, a ‘<samp><span class="samp">#</span></samp>’, otherwise a ‘<samp><span class="samp">$</span></samp>’.
+
+     <br><dt>‘<samp><span class="samp">\nnn</span></samp>’<dd>The character whose character code in octal is <var>nnn</var>.
+
+     <br><dt>‘<samp><span class="samp">\\</span></samp>’<dd>A backslash. 
+</dl>
+
+<!-- input.cc -->
+   <p><a name="doc_002dPS1"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>PS1</b> ()<var><a name="index-PS1-136"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>PS1</b> (<var>new_val</var>)<var><a name="index-PS1-137"></a></var><br>
+<blockquote><p>Query or set the primary prompt string.  When executing interactively,
+Octave displays the primary prompt when it is ready to read a command.
+
+        <p>The default value of the primary prompt string is <code>"\s:\#> "</code>. 
+To change it, use a command like
+
+     <pre class="example">          octave:13> PS1 ("\\u@\\H> ")
+</pre>
+        <p class="noindent">which will result in the prompt ‘<samp><span class="samp">boris at kremvax> </span></samp>’ for the user
+‘<samp><span class="samp">boris</span></samp>’ logged in on the host ‘<samp><span class="samp">kremvax.kgb.su</span></samp>’.  Note that two
+backslashes are required to enter a backslash into a double-quoted
+character string. 
+See <a href="Strings.html#Strings">Strings</a>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dPS2.html#doc_002dPS2">PS2</a>, <a href="doc_002dPS4.html#doc_002dPS4">PS4</a>. 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002dPS2"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>PS2</b> ()<var><a name="index-PS2-138"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>PS2</b> (<var>new_val</var>)<var><a name="index-PS2-139"></a></var><br>
+<blockquote><p>Query or set the secondary prompt string.  The secondary prompt is
+printed when Octave is expecting additional input to complete a
+command.  For example, if you are typing a <code>for</code> loop that spans several
+lines, Octave will print the secondary prompt at the beginning of
+each line after the first.  The default value of the secondary prompt
+string is <code>"> "</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dPS1.html#doc_002dPS1">PS1</a>, <a href="doc_002dPS4.html#doc_002dPS4">PS4</a>. 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002dPS4"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>PS4</b> ()<var><a name="index-PS4-140"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>PS4</b> (<var>new_val</var>)<var><a name="index-PS4-141"></a></var><br>
+<blockquote><p>Query or set the character string used to prefix output produced
+when echoing commands is enabled. 
+The default value is <code>"+ "</code>. 
+See <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a>, for a description of echoing commands. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002decho.html#doc_002decho">echo</a>, <a href="doc_002decho_005fexecuting_005fcommands.html#doc_002decho_005fexecuting_005fcommands">echo_executing_commands</a>, <a href="doc_002dPS1.html#doc_002dPS1">PS1</a>, <a href="doc_002dPS2.html#doc_002dPS2">PS2</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Data-Containers.html b/doc/interpreter/HTML/Data-Containers.html
new file mode 100644
index 0000000..bece8b0
--- /dev/null
+++ b/doc/interpreter/HTML/Data-Containers.html
@@ -0,0 +1,51 @@
+<html lang="en">
+<head>
+<title>Data Containers - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Strings.html#Strings" title="Strings">
+<link rel="next" href="Variables.html#Variables" title="Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Data-Containers"></a>
+Next: <a rel="next" accesskey="n" href="Variables.html#Variables">Variables</a>,
+Previous: <a rel="previous" accesskey="p" href="Strings.html#Strings">Strings</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">6 Data Containers</h2>
+
+<p><a name="index-containers-368"></a>
+Octave includes support for two different mechanisms to contain
+arbitrary data types in the same variable.  Structures, which are C-like,
+and are indexed with named fields, and cell arrays, where each element
+of the array can have a different data type and or shape. Multiple
+input arguments and return values of functions are organized as
+another data container, the comma separated list.
+
+<ul class="menu">
+<li><a accesskey="1" href="Data-Structures.html#Data-Structures">Data Structures</a>
+<li><a accesskey="2" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<li><a accesskey="3" href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Data-Structure-Objects.html b/doc/interpreter/HTML/Data-Structure-Objects.html
new file mode 100644
index 0000000..f3f732a
--- /dev/null
+++ b/doc/interpreter/HTML/Data-Structure-Objects.html
@@ -0,0 +1,46 @@
+<html lang="en">
+<head>
+<title>Data Structure Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Built_002din-Data-Types.html#Built_002din-Data-Types" title="Built-in Data Types">
+<link rel="prev" href="String-Objects.html#String-Objects" title="String Objects">
+<link rel="next" href="Cell-Array-Objects.html#Cell-Array-Objects" title="Cell Array Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Data-Structure-Objects"></a>
+Next: <a rel="next" accesskey="n" href="Cell-Array-Objects.html#Cell-Array-Objects">Cell Array Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="String-Objects.html#String-Objects">String Objects</a>,
+Up: <a rel="up" accesskey="u" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<hr>
+</div>
+
+<h4 class="subsection">3.1.4 Data Structure Objects</h4>
+
+<p><a name="index-structures-195"></a><a name="index-data-structures-196"></a>
+Octave's data structure type can help you to organize related objects of
+different types.  The current implementation uses an associative array
+with indices limited to strings, but the syntax is more like C-style
+structures.
+
+   <p>See <a href="Data-Structures.html#Data-Structures">Data Structures</a>, for more information.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Data-Structures.html b/doc/interpreter/HTML/Data-Structures.html
new file mode 100644
index 0000000..83336b3
--- /dev/null
+++ b/doc/interpreter/HTML/Data-Structures.html
@@ -0,0 +1,49 @@
+<html lang="en">
+<head>
+<title>Data Structures - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Containers.html#Data-Containers" title="Data Containers">
+<link rel="next" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Data-Structures"></a>
+Next: <a rel="next" accesskey="n" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Data-Containers.html#Data-Containers">Data Containers</a>
+<hr>
+</div>
+
+<h3 class="section">6.1 Data Structures</h3>
+
+<p><a name="index-structures-369"></a><a name="index-data-structures-370"></a>
+Octave includes support for organizing data in structures.  The current
+implementation uses an associative array with indices limited to
+strings, but the syntax is more like C-style structures.
+
+<ul class="menu">
+<li><a accesskey="1" href="Basic-Usage-and-Examples.html#Basic-Usage-and-Examples">Basic Usage and Examples</a>
+<li><a accesskey="2" href="Structure-Arrays.html#Structure-Arrays">Structure Arrays</a>
+<li><a accesskey="3" href="Creating-Structures.html#Creating-Structures">Creating Structures</a>
+<li><a accesskey="4" href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a>
+<li><a accesskey="5" href="Processing-Data-in-Structures.html#Processing-Data-in-Structures">Processing Data in Structures</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Data-Types.html b/doc/interpreter/HTML/Data-Types.html
new file mode 100644
index 0000000..8feb6eb
--- /dev/null
+++ b/doc/interpreter/HTML/Data-Types.html
@@ -0,0 +1,66 @@
+<html lang="en">
+<head>
+<title>Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="next" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>,
+Previous: <a rel="previous" accesskey="p" href="Getting-Started.html#Getting-Started">Getting Started</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">3 Data Types</h2>
+
+<p><a name="index-data-types-171"></a>
+All versions of Octave include a number of built-in data types,
+including real and complex scalars and matrices, character strings,
+a data structure type, and an array that can contain all data types.
+
+   <p>It is also possible to define new specialized data types by writing a
+small amount of C++ code.  On some systems, new data types can be loaded
+dynamically while Octave is running, so it is not necessary to recompile
+all of Octave just to add a new type.  See <a href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>, for more information about Octave's dynamic linking
+capabilities.  <a href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a> describes what you must do
+to define a new data type for Octave.
+
+<!-- ov-typeinfo.cc -->
+   <p><a name="doc_002dtypeinfo"></a>
+
+<div class="defun">
+— Built-in Function:  <b>typeinfo</b> (<var>expr</var>)<var><a name="index-typeinfo-172"></a></var><br>
+<blockquote>
+        <p>Return the type of the expression <var>expr</var>, as a string.  If
+<var>expr</var> is omitted, return an array of strings containing all the
+currently installed data types. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<li><a accesskey="2" href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a>
+<li><a accesskey="3" href="Object-Sizes.html#Object-Sizes">Object Sizes</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Data-sources-in-object-groups.html b/doc/interpreter/HTML/Data-sources-in-object-groups.html
new file mode 100644
index 0000000..94cf37a
--- /dev/null
+++ b/doc/interpreter/HTML/Data-sources-in-object-groups.html
@@ -0,0 +1,77 @@
+<html lang="en">
+<head>
+<title>Data sources in object groups - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="next" href="Area-series.html#Area-series" title="Area series">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Data-sources-in-object-groups"></a>
+Next: <a rel="next" accesskey="n" href="Area-series.html#Area-series">Area series</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.1 Data sources in object groups</h5>
+
+<p><a name="index-data-sources-in-object-groups-1228"></a>
+All of the group objects contain data source parameters.  There are
+string parameters that contain an expression that is evaluated to update
+the relevant data property of the group when the <code>refreshdata</code>
+function is called.
+
+<!-- ./plot/refreshdata.m -->
+   <p><a name="doc_002drefreshdata"></a>
+
+<div class="defun">
+— Function File:  <b>refreshdata</b> ()<var><a name="index-refreshdata-1229"></a></var><br>
+— Function File:  <b>refreshdata</b> (<var>h</var>)<var><a name="index-refreshdata-1230"></a></var><br>
+— Function File:  <b>refreshdata</b> (<var>h, workspace</var>)<var><a name="index-refreshdata-1231"></a></var><br>
+<blockquote><p>Evaluate any ‘<samp><span class="samp">datasource</span></samp>’ properties of the current figure and update
+the plot if the corresponding data has changed.  If called with one or more
+arguments <var>h</var> is a scalar or array of figure handles to refresh.  The
+optional second argument <var>workspace</var> can take the following values.
+
+          <dl>
+<dt><code>"base"</code><dd>Evaluate the datasource properties in the base workspace.  (default). 
+<br><dt><code>"caller"</code><dd>Evaluate the datasource properties in the workspace of the function
+that called <code>refreshdata</code>. 
+</dl>
+
+        <p>An example of the use of <code>refreshdata</code> is:
+
+     <pre class="example">          x = 0:0.1:10;
+          y = sin (x);
+          plot (x, y, "ydatasource", "y");
+          for i = 1 : 100
+            pause(0.1)
+            y = sin (x + 0.1 * i);
+            refreshdata();
+          endfor
+</pre>
+        </blockquote></div>
+
+   <p><a name="doc_002dlinkdata"></a><!-- add the description of the linkdata function here when it is written -->
+<!-- remove the explicit anchor when you add the corresponding @DOCSTRING -->
+<!-- command -->
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Debug-Mode.html b/doc/interpreter/HTML/Debug-Mode.html
new file mode 100644
index 0000000..9e6bde0
--- /dev/null
+++ b/doc/interpreter/HTML/Debug-Mode.html
@@ -0,0 +1,109 @@
+<html lang="en">
+<head>
+<title>Debug Mode - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Debugging.html#Debugging" title="Debugging">
+<link rel="prev" href="Breakpoints.html#Breakpoints" title="Breakpoints">
+<link rel="next" href="Call-Stack.html#Call-Stack" title="Call Stack">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Debug-Mode"></a>
+Next: <a rel="next" accesskey="n" href="Call-Stack.html#Call-Stack">Call Stack</a>,
+Previous: <a rel="previous" accesskey="p" href="Breakpoints.html#Breakpoints">Breakpoints</a>,
+Up: <a rel="up" accesskey="u" href="Debugging.html#Debugging">Debugging</a>
+<hr>
+</div>
+
+<h3 class="section">13.4 Debug Mode</h3>
+
+<p>There are two additional support functions that allow the user to
+interrogate where in the execution of a script Octave entered the debug
+mode and to print the code in the script surrounding the point where
+Octave entered debug mode.
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbwhere"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dbwhere</b> ()<var><a name="index-dbwhere-698"></a></var><br>
+<blockquote><p>Show where we are in the code
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbclear.html#doc_002ddbclear">dbclear</a>, <a href="doc_002ddbstatus.html#doc_002ddbstatus">dbstatus</a>, <a href="doc_002ddbstop.html#doc_002ddbstop">dbstop</a>. 
+</p></blockquote></div>
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbtype"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dbtype</b> ()<var><a name="index-dbtype-699"></a></var><br>
+<blockquote><p>List script file with line numbers. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbclear.html#doc_002ddbclear">dbclear</a>, <a href="doc_002ddbstatus.html#doc_002ddbstatus">dbstatus</a>, <a href="doc_002ddbstop.html#doc_002ddbstop">dbstop</a>. 
+</p></blockquote></div>
+
+   <p>You may also use <code>isdebugmode</code> to determine whether the debugger is
+currently active.
+
+<!-- debug.cc -->
+   <p><a name="doc_002disdebugmode"></a>
+
+<div class="defun">
+— Command:  <b>isdebugmode</b> ()<var><a name="index-isdebugmode-700"></a></var><br>
+<blockquote><p>Return true if debug mode is on, otherwise false. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbstack.html#doc_002ddbstack">dbstack</a>, <a href="doc_002ddbclear.html#doc_002ddbclear">dbclear</a>, <a href="doc_002ddbstop.html#doc_002ddbstop">dbstop</a>, <a href="doc_002ddbstatus.html#doc_002ddbstatus">dbstatus</a>. 
+</p></blockquote></div>
+
+   <p>Debug mode also allows single line stepping through a function using
+the commands <code>dbstep</code>.
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbstep"></a>
+
+<div class="defun">
+— Command:  <b>dbstep</b><var> n<a name="index-dbstep-701"></a></var><br>
+— Command:  <b>dbstep</b><var> in<a name="index-dbstep-702"></a></var><br>
+— Command:  <b>dbstep</b><var> out<a name="index-dbstep-703"></a></var><br>
+<blockquote><p>In debugging mode, execute the next <var>n</var> lines of code.  If <var>n</var> is
+omitted execute the next line of code.  If the next line of code is itself
+defined in terms of an m-file remain in the existing function.
+
+        <p>Using <code>dbstep in</code> will cause execution of the next line to step into
+any m-files defined on the next line.  Using <code>dbstep out</code> with cause
+execution to continue until the current function returns. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbcont.html#doc_002ddbcont">dbcont</a>, <a href="doc_002ddbquit.html#doc_002ddbquit">dbquit</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Debugging.html b/doc/interpreter/HTML/Debugging.html
new file mode 100644
index 0000000..0ebac1f
--- /dev/null
+++ b/doc/interpreter/HTML/Debugging.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Debugging - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Errors-and-Warnings.html#Errors-and-Warnings" title="Errors and Warnings">
+<link rel="next" href="Input-and-Output.html#Input-and-Output" title="Input and Output">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Debugging"></a>
+Next: <a rel="next" accesskey="n" href="Input-and-Output.html#Input-and-Output">Input and Output</a>,
+Previous: <a rel="previous" accesskey="p" href="Errors-and-Warnings.html#Errors-and-Warnings">Errors and Warnings</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">13 Debugging</h2>
+
+<p>Octave includes a built-in debugger to aid in the development of
+scripts.  This can be used to interrupt the execution of an Octave script
+at a certain point, or when certain conditions are met.  Once execution
+has stopped, and debug mode is entered, the symbol table at the point
+where execution has stopped can be examined and modified to check for
+errors.
+
+   <p>The normal command-line editing and history functions are available in
+debug mode.
+
+<ul class="menu">
+<li><a accesskey="1" href="Entering-Debug-Mode.html#Entering-Debug-Mode">Entering Debug Mode</a>
+<li><a accesskey="2" href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">Leaving Debug Mode</a>
+<li><a accesskey="3" href="Breakpoints.html#Breakpoints">Breakpoints</a>
+<li><a accesskey="4" href="Debug-Mode.html#Debug-Mode">Debug Mode</a>
+<li><a accesskey="5" href="Call-Stack.html#Call-Stack">Call Stack</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Default-Arguments.html b/doc/interpreter/HTML/Default-Arguments.html
new file mode 100644
index 0000000..ba522cd
--- /dev/null
+++ b/doc/interpreter/HTML/Default-Arguments.html
@@ -0,0 +1,71 @@
+<html lang="en">
+<head>
+<title>Default Arguments - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Returning-From-a-Function.html#Returning-From-a-Function" title="Returning From a Function">
+<link rel="next" href="Function-Files.html#Function-Files" title="Function Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Default-Arguments"></a>
+Next: <a rel="next" accesskey="n" href="Function-Files.html#Function-Files">Function Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Returning-From-a-Function.html#Returning-From-a-Function">Returning From a Function</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.6 Default Arguments</h3>
+
+<p><a name="index-default-arguments-611"></a>
+Since Octave supports variable number of input arguments, it is very useful
+to assign default values to some input arguments.  When an input argument
+is declared in the argument list it is possible to assign a default
+value to the argument like this
+
+<pre class="example">     function <var>name</var> (<var>arg1</var> = <var>val1</var>, ...)
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">If no value is assigned to <var>arg1</var> by the user, it will have the
+value <var>val1</var>.
+
+   <p>As an example, the following function implements a variant of the classic
+“Hello, World” program.
+<pre class="example">     function hello (who = "World")
+       printf ("Hello, %s!\n", who);
+     endfunction
+</pre>
+   <p class="noindent">When called without an input argument the function prints the following
+<pre class="example">     hello ();
+          -| Hello, World!
+</pre>
+   <p class="noindent">and when it's called with an input argument it prints the following
+<pre class="example">     hello ("Beautiful World of Free Software");
+          -| Hello, Beautiful World of Free Software!
+</pre>
+   <p>Sometimes it is useful to explicitly tell Octave to use the default value
+of an input argument.  This can be done writing a ‘<samp><span class="samp">:</span></samp>’ as the value
+of the input argument when calling the function.
+<pre class="example">     hello (:);
+          -| Hello, World!
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Defining-Functions.html b/doc/interpreter/HTML/Defining-Functions.html
new file mode 100644
index 0000000..f507004
--- /dev/null
+++ b/doc/interpreter/HTML/Defining-Functions.html
@@ -0,0 +1,215 @@
+<html lang="en">
+<head>
+<title>Defining Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="next" href="Multiple-Return-Values.html#Multiple-Return-Values" title="Multiple Return Values">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Defining-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.1 Defining Functions</h3>
+
+<p><a name="index-g_t_0040code_007bfunction_007d-statement-588"></a><a name="index-g_t_0040code_007bendfunction_007d-statement-589"></a>
+In its simplest form, the definition of a function named <var>name</var>
+looks like this:
+
+<pre class="example">     function <var>name</var>
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">A valid function name is like a valid variable name: a sequence of
+letters, digits and underscores, not starting with a digit.  Functions
+share the same pool of names as variables.
+
+   <p>The function <var>body</var> consists of Octave statements.  It is the
+most important part of the definition, because it says what the function
+should actually <em>do</em>.
+
+   <p>For example, here is a function that, when executed, will ring the bell
+on your terminal (assuming that it is possible to do so):
+
+<pre class="example">     function wakeup
+       printf ("\a");
+     endfunction
+</pre>
+   <p>The <code>printf</code> statement (see <a href="Input-and-Output.html#Input-and-Output">Input and Output</a>) simply tells
+Octave to print the string <code>"\a"</code>.  The special character ‘<samp><span class="samp">\a</span></samp>’
+stands for the alert character (ASCII 7).  See <a href="Strings.html#Strings">Strings</a>.
+
+   <p>Once this function is defined, you can ask Octave to evaluate it by
+typing the name of the function.
+
+   <p>Normally, you will want to pass some information to the functions you
+define.  The syntax for passing parameters to a function in Octave is
+
+<pre class="example">     function <var>name</var> (<var>arg-list</var>)
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">where <var>arg-list</var> is a comma-separated list of the function's
+arguments.  When the function is called, the argument names are used to
+hold the argument values given in the call.  The list of arguments may
+be empty, in which case this form is equivalent to the one shown above.
+
+   <p>To print a message along with ringing the bell, you might modify the
+<code>wakeup</code> to look like this:
+
+<pre class="example">     function wakeup (message)
+       printf ("\a%s\n", message);
+     endfunction
+</pre>
+   <p>Calling this function using a statement like this
+
+<pre class="example">     wakeup ("Rise and shine!");
+</pre>
+   <p class="noindent">will cause Octave to ring your terminal's bell and print the message
+‘<samp><span class="samp">Rise and shine!</span></samp>’, followed by a newline character (the ‘<samp><span class="samp">\n</span></samp>’
+in the first argument to the <code>printf</code> statement).
+
+   <p>In most cases, you will also want to get some information back from the
+functions you define.  Here is the syntax for writing a function that
+returns a single value:
+
+<pre class="example">     function <var>ret-var</var> = <var>name</var> (<var>arg-list</var>)
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">The symbol <var>ret-var</var> is the name of the variable that will hold the
+value to be returned by the function.  This variable must be defined
+before the end of the function body in order for the function to return
+a value.
+
+   <p>Variables used in the body of a function are local to the
+function.  Variables named in <var>arg-list</var> and <var>ret-var</var> are also
+local to the function.  See <a href="Global-Variables.html#Global-Variables">Global Variables</a>, for information about
+how to access global variables inside a function.
+
+   <p>For example, here is a function that computes the average of the
+elements of a vector:
+
+<pre class="example">     function retval = avg (v)
+       retval = sum (v) / length (v);
+     endfunction
+</pre>
+   <p>If we had written <code>avg</code> like this instead,
+
+<pre class="example">     function retval = avg (v)
+       if (isvector (v))
+         retval = sum (v) / length (v);
+       endif
+     endfunction
+</pre>
+   <p class="noindent">and then called the function with a matrix instead of a vector as the
+argument, Octave would have printed an error message like this:
+
+<pre class="example">     error: value on right hand side of assignment is undefined
+</pre>
+   <p class="noindent">because the body of the <code>if</code> statement was never executed, and
+<code>retval</code> was never defined.  To prevent obscure errors like this,
+it is a good idea to always make sure that the return variables will
+always have values, and to produce meaningful error messages when
+problems are encountered.  For example, <code>avg</code> could have been
+written like this:
+
+<pre class="example">     function retval = avg (v)
+       retval = 0;
+       if (isvector (v))
+         retval = sum (v) / length (v);
+       else
+         error ("avg: expecting vector argument");
+       endif
+     endfunction
+</pre>
+   <p>There is still one additional problem with this function.  What if it is
+called without an argument?  Without additional error checking, Octave
+will probably print an error message that won't really help you track
+down the source of the error.  To allow you to catch errors like this,
+Octave provides each function with an automatic variable called
+<code>nargin</code>.  Each time a function is called, <code>nargin</code> is
+automatically initialized to the number of arguments that have actually
+been passed to the function.  For example, we might rewrite the
+<code>avg</code> function like this:
+
+<pre class="example">     function retval = avg (v)
+       retval = 0;
+       if (nargin != 1)
+         usage ("avg (vector)");
+       endif
+       if (isvector (v))
+         retval = sum (v) / length (v);
+       else
+         error ("avg: expecting vector argument");
+       endif
+     endfunction
+</pre>
+   <p>Although Octave does not automatically report an error if you call a
+function with more arguments than expected, doing so probably indicates
+that something is wrong.  Octave also does not automatically report an
+error if a function is called with too few arguments, but any attempt to
+use a variable that has not been given a value will result in an error. 
+To avoid such problems and to provide useful messages, we check for both
+possibilities and issue our own error message.
+
+<!-- ov-usr-fcn.cc -->
+   <p><a name="doc_002dnargin"></a>
+
+<div class="defun">
+— Built-in Function:  <b>nargin</b> ()<var><a name="index-nargin-590"></a></var><br>
+— Built-in Function:  <b>nargin</b> (<var>fcn_name</var>)<var><a name="index-nargin-591"></a></var><br>
+<blockquote><p>Within a function, return the number of arguments passed to the function. 
+At the top level, return the number of command line arguments passed to
+Octave.  If called with the optional argument <var>fcn_name</var>, return the
+maximum number of arguments the named function can accept, or -1 if the
+function accepts a variable number of arguments. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnargout.html#doc_002dnargout">nargout</a>, <a href="doc_002dvarargin.html#doc_002dvarargin">varargin</a>, <a href="doc_002dvarargout.html#doc_002dvarargout">varargout</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/inputname.m -->
+   <p><a name="doc_002dinputname"></a>
+
+<div class="defun">
+— Function File:  <b>inputname</b> (<var>n</var>)<var><a name="index-inputname-592"></a></var><br>
+<blockquote><p>Return the text defining <var>n</var>-th input to the function. 
+</p></blockquote></div>
+
+<!-- pt-eval.cc -->
+   <p><a name="doc_002dsilent_005ffunctions"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>silent_functions</b> ()<var><a name="index-silent_005ffunctions-593"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>silent_functions</b> (<var>new_val</var>)<var><a name="index-silent_005ffunctions-594"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether internal
+output from a function is suppressed.  If this option is disabled,
+Octave will display the results produced by evaluating expressions
+within a function body that are not terminated with a semicolon. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Delaunay-Triangulation.html b/doc/interpreter/HTML/Delaunay-Triangulation.html
new file mode 100644
index 0000000..68d65dc
--- /dev/null
+++ b/doc/interpreter/HTML/Delaunay-Triangulation.html
@@ -0,0 +1,153 @@
+<html lang="en">
+<head>
+<title>Delaunay Triangulation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Geometry.html#Geometry" title="Geometry">
+<link rel="next" href="Voronoi-Diagrams.html#Voronoi-Diagrams" title="Voronoi Diagrams">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Delaunay-Triangulation"></a>
+Next: <a rel="next" accesskey="n" href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a>,
+Up: <a rel="up" accesskey="u" href="Geometry.html#Geometry">Geometry</a>
+<hr>
+</div>
+
+<h3 class="section">29.1 Delaunay Triangulation</h3>
+
+<p>The Delaunay triangulation is constructed from a set of
+circum-circles.  These circum-circles are chosen so that there are at
+least three of the points in the set to triangulation on the
+circumference of the circum-circle.  None of the points in the set of
+points falls within any of the circum-circles.
+
+   <p>In general there are only three points on the circumference of any
+circum-circle.  However, in some cases, and in particular for the
+case of a regular grid, 4 or more points can be on a single
+circum-circle.  In this case the Delaunay triangulation is not unique.
+
+<!-- ./geometry/delaunay.m -->
+   <p><a name="doc_002ddelaunay"></a>
+
+<div class="defun">
+— Function File: <var>tri</var> = <b>delaunay</b> (<var>x, y</var>)<var><a name="index-delaunay-2084"></a></var><br>
+— Function File: <var>tri</var> = <b>delaunay</b> (<var>x, y, opt</var>)<var><a name="index-delaunay-2085"></a></var><br>
+<blockquote><p>The return matrix of size [n, 3] contains a set triangles which are
+described by the indices to the data point x and y vector. 
+The triangulation satisfies the Delaunay circum-circle criterion. 
+No other data point is in the circum-circle of the defining triangle.
+
+        <p>A third optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+
+     <pre class="example">          x = rand (1, 10);
+          y = rand (size (x));
+          T = delaunay (x, y);
+          X = [x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1))];
+          Y = [y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1))];
+          axis ([0,1,0,1]);
+          plot (X, Y, "b", x, y, "r*");
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dvoronoi.html#doc_002dvoronoi">voronoi</a>, <a href="doc_002ddelaunay3.html#doc_002ddelaunay3">delaunay3</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+   <p>The 3- and N-dimensional extension of the Delaunay triangulation are
+given by <code>delaunay3</code> and <code>delaunayn</code> respectively. 
+<code>delaunay3</code> returns a set of tetrahedra that satisfy the
+Delaunay circum-circle criteria.  Similarly, <code>delaunayn</code> returns the
+N-dimensional simplex satisfying the Delaunay circum-circle criteria. 
+The N-dimensional extension of a triangulation is called a tessellation.
+
+<!-- ./geometry/delaunay3.m -->
+   <p><a name="doc_002ddelaunay3"></a>
+
+<div class="defun">
+— Function File: <var>T</var> = <b>delaunay3</b> (<var>x, y, z</var>)<var><a name="index-delaunay3-2086"></a></var><br>
+— Function File: <var>T</var> = <b>delaunay3</b> (<var>x, y, z, opt</var>)<var><a name="index-delaunay3-2087"></a></var><br>
+<blockquote><p>A matrix of size [n, 4] is returned.  Each row contains a
+set of tetrahedron which are
+described by the indices to the data point vectors (x,y,z).
+
+        <p>A fourth optional argument, which must be a string or cell array of strings,
+contains extra options passed to the underlying qhull command.  See the
+documentation for the Qhull library for details. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/delaunayn.m -->
+   <p><a name="doc_002ddelaunayn"></a>
+
+<div class="defun">
+— Function File: <var>T</var> = <b>delaunayn</b> (<var>P</var>)<var><a name="index-delaunayn-2088"></a></var><br>
+— Function File: <var>T</var> = <b>delaunayn</b> (<var>P, opt</var>)<var><a name="index-delaunayn-2089"></a></var><br>
+<blockquote><p>Form the Delaunay triangulation for a set of points. 
+The Delaunay triangulation is a tessellation of the convex hull of the
+points such that no n-sphere defined by the n-triangles contains
+any other points from the set. 
+The input matrix <var>P</var> of size <code>[n, dim]</code> contains <var>n</var>
+points in a space of dimension dim.  The return matrix <var>T</var> has the
+size <code>[m, dim+1]</code>.  It contains for each row a set of indices to
+the points, which describes a simplex of dimension dim.  For example,
+a 2d simplex is a triangle and 3d simplex is a tetrahedron.
+
+        <p>Extra options for the underlying Qhull command can be specified by the
+second argument.  This argument is a cell array of strings.  The default
+options depend on the dimension of the input:
+
+          <ul>
+<li>2D and 3D: <var>opt</var> = <code>{"Qt", "Qbb", "Qc"}</code>
+<li>4D and higher: <var>opt</var> = <code>{"Qt", "Qbb", "Qc", "Qz"}</code>
+</ul>
+
+        <p>If <var>opt</var> is [], then the default arguments are used.  If <var>opt</var>
+is <code>{"<!-- /@w -->"}</code>, then none of the default arguments are used by Qhull. 
+See the Qhull documentation for the available options.
+
+        <p>All options can also be specified as single string, for example
+<code>"Qt Qbb Qc Qz"</code>.
+
+        </blockquote></div>
+
+   <p>An example of a Delaunay triangulation of a set of points is
+
+<pre class="example">     rand ("state", 2);
+     x = rand (10, 1);
+     y = rand (10, 1);
+     T = delaunay (x, y);
+     X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
+     Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+     axis ([0, 1, 0, 1]);
+     plot(X, Y, "b", x, y, "r*");
+</pre>
+   <ul class="menu">
+<li><a accesskey="1" href="Plotting-the-Triangulation.html#Plotting-the-Triangulation">Plotting the Triangulation</a>
+<li><a accesskey="2" href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Demonstration-Functions.html b/doc/interpreter/HTML/Demonstration-Functions.html
new file mode 100644
index 0000000..f87f770
--- /dev/null
+++ b/doc/interpreter/HTML/Demonstration-Functions.html
@@ -0,0 +1,246 @@
+<html lang="en">
+<head>
+<title>Demonstration Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions" title="Test and Demo Functions">
+<link rel="prev" href="Test-Functions.html#Test-Functions" title="Test Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Demonstration-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Test-Functions.html#Test-Functions">Test Functions</a>,
+Up: <a rel="up" accesskey="u" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a>
+<hr>
+</div>
+
+<h3 class="section">B.2 Demonstration Functions</h3>
+
+<!-- ./testfun/demo.m -->
+<p><a name="doc_002ddemo"></a>
+
+<div class="defun">
+— Function File:  <b>demo</b> (<var>'name',n</var>)<var><a name="index-demo-2499"></a></var><br>
+<blockquote>
+        <p>Runs any examples associated with the function '<var>name</var>'. 
+Examples are stored in the script file, or in a file with the same
+name but no extension somewhere on your path.  To keep them separate
+from the usual script code, all lines are prefixed by <code>%!</code>.  Each
+example is introduced by the keyword 'demo' flush left to the prefix,
+with no intervening spaces.  The remainder of the example can contain
+arbitrary Octave code.  For example:
+
+     <pre class="example">             %!demo
+             %! t=0:0.01:2*pi; x = sin(t);
+             %! plot(t,x)
+             %! %-------------------------------------------------
+             %! % the figure window shows one cycle of a sine wave
+</pre>
+        <p>Note that the code is displayed before it is executed, so a simple
+comment at the end suffices.  It is generally not necessary to use
+disp or printf within the demo.
+
+        <p>Demos are run in a function environment with no access to external
+variables.  This means that all demos in your function must use
+separate initialization code.  Alternatively, you can combine your
+demos into one huge demo, with the code:
+
+     <pre class="example">             %! input("Press <enter> to continue: ","s");
+</pre>
+        <p>between the sections, but this is discouraged.  Other techniques
+include using multiple plots by saying figure between each, or
+using subplot to put multiple plots in the same window.
+
+        <p>Also, since demo evaluates inside a function context, you cannot
+define new functions inside a demo.  Instead you will have to
+use <code>eval(example('function',n))</code> to see them.  Because eval only
+evaluates one line, or one statement if the statement crosses
+multiple lines, you must wrap your demo in "if 1 <demo stuff> endif"
+with the 'if' on the same line as 'demo'.  For example,
+
+     <pre class="example">            %!demo if 1
+            %!  function y=f(x)
+            %!    y=x;
+            %!  endfunction
+            %!  f(3)
+            %! endif
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtest.html#doc_002dtest">test</a>, <a href="doc_002dexample.html#doc_002dexample">example</a>. 
+</p></blockquote></div>
+
+<!-- ./testfun/rundemos.m -->
+   <p><a name="doc_002drundemos"></a>
+
+<div class="defun">
+— Function File:  <b>rundemos</b> (<var>directory</var>)<var><a name="index-rundemos-2500"></a></var><br>
+        </div>
+
+<!-- ./testfun/example.m -->
+   <p><a name="doc_002dexample"></a>
+
+<div class="defun">
+— Function File:  <b>example</b> (<var>'name',n</var>)<var><a name="index-example-2501"></a></var><br>
+— Function File: [<var>x</var>, <var>idx</var>] = <b>example</b> (<var>'name',n</var>)<var><a name="index-example-2502"></a></var><br>
+<blockquote>
+        <p>Display the code for example <var>n</var> associated with the function
+'<var>name</var>', but do not run it.  If <var>n</var> is not given, all examples
+are displayed.
+
+        <p>Called with output arguments, the examples are returned in the form of
+a string <var>x</var>, with <var>idx</var> indicating the ending position of the
+various examples.
+
+        <p>See <code>demo</code> for a complete explanation. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddemo.html#doc_002ddemo">demo</a>, <a href="doc_002dtest.html#doc_002dtest">test</a>. 
+</p></blockquote></div>
+
+<!-- ./testfun/speed.m -->
+   <p><a name="doc_002dspeed"></a>
+
+<div class="defun">
+— Function File:  <b>speed</b> (<var>f, init, max_n, f2, tol</var>)<var><a name="index-speed-2503"></a></var><br>
+— Function File: [<var>order</var>, <var>n</var>, <var>T_f</var>, <var>T_f2</var>] = <b>speed</b> (<var><small class="dots">...</small></var>)<var><a name="index-speed-2504"></a></var><br>
+<blockquote>
+        <p>Determine the execution time of an expression for various <var>n</var>. 
+The <var>n</var> are log-spaced from 1 to <var>max_n</var>.  For each <var>n</var>,
+an initialization expression is computed to create whatever data
+are needed for the test.  If a second expression is given, the
+execution times of the two expressions will be compared.  Called
+without output arguments the results are presented graphically.
+
+          <dl>
+<dt><var>f</var><dd>The expression to evaluate.
+
+          <br><dt><var>max_n</var><dd>The maximum test length to run.  Default value is 100.  Alternatively,
+use <code>[min_n,max_n]</code> or for complete control, <code>[n1,n2,...,nk]</code>.
+
+          <br><dt><var>init</var><dd>Initialization expression for function argument values.  Use <var>k</var>
+for the test number and <var>n</var> for the size of the test.  This should
+compute values for all variables listed in args.  Note that init will
+be evaluated first for k = 0, so things which are constant throughout
+the test can be computed then.  The default value is <var>x</var><code> =
+randn (</code><var>n</var><code>, 1);</code>.
+
+          <br><dt><var>f2</var><dd>An alternative expression to evaluate, so the speed of the two
+can be compared.  Default is <code>[]</code>.
+
+          <br><dt><var>tol</var><dd>If <var>tol</var> is <code>Inf</code>, then no comparison will be made between the
+results of expression <var>f</var> and expression <var>f2</var>.  Otherwise,
+expression <var>f</var> should produce a value <var>v</var> and expression <var>f2</var>
+should produce a value <var>v2</var>, and these shall be compared using
+<code>assert(</code><var>v</var><code>,</code><var>v2</var><code>,</code><var>tol</var><code>)</code>.  If <var>tol</var> is positive,
+the tolerance is assumed to be absolute.  If <var>tol</var> is negative,
+the tolerance is assumed to be relative.  The default is <code>eps</code>.
+
+          <br><dt><var>order</var><dd>The time complexity of the expression <code>O(a n^p)</code>.  This
+is a structure with fields <code>a</code> and <code>p</code>.
+
+          <br><dt><var>n</var><dd>The values <var>n</var> for which the expression was calculated and
+the execution time was greater than zero.
+
+          <br><dt><var>T_f</var><dd>The nonzero execution times recorded for the expression <var>f</var> in seconds.
+
+          <br><dt><var>T_f2</var><dd>The nonzero execution times recorded for the expression <var>f2</var> in seconds. 
+If it is needed, the mean time ratio is just <code>mean(T_f./T_f2)</code>.
+
+        </dl>
+
+        <p>The slope of the execution time graph shows the approximate
+power of the asymptotic running time <code>O(n^p)</code>.  This
+power is plotted for the region over which it is approximated
+(the latter half of the graph).  The estimated power is not
+very accurate, but should be sufficient to determine the
+general order of your algorithm.  It should indicate if for
+example your implementation is unexpectedly <code>O(n^2)</code>
+rather than <code>O(n)</code> because it extends a vector each
+time through the loop rather than preallocating one which is
+big enough.  For example, in the current version of Octave,
+the following is not the expected <code>O(n)</code>:
+
+     <pre class="example">          speed ("for i = 1:n, y{i} = x(i); end", "", [1000,10000])
+</pre>
+        <p>but it is if you preallocate the cell array <code>y</code>:
+
+     <pre class="example">          speed ("for i = 1:n, y{i} = x(i); end", ...
+                 "x = rand (n, 1); y = cell (size (x));", [1000, 10000])
+</pre>
+        <p>An attempt is made to approximate the cost of the individual
+operations, but it is wildly inaccurate.  You can improve the
+stability somewhat by doing more work for each <code>n</code>.  For
+example:
+
+     <pre class="example">          speed ("airy(x)", "x = rand (n, 10)", [10000, 100000])
+</pre>
+        <p>When comparing a new and original expression, the line on the
+speedup ratio graph should be larger than 1 if the new expression
+is faster.  Better algorithms have a shallow slope.  Generally,
+vectorizing an algorithm will not change the slope of the execution
+time graph, but it will shift it relative to the original.  For
+example:
+
+     <pre class="example">          speed ("v = sum (x)", "", [10000, 100000], ...
+                 "v = 0; for i = 1:length (x), v += x(i); end")
+</pre>
+        <p>A more complex example, if you had an original version of <code>xcorr</code>
+using for loops and another version using an FFT, you could compare the
+run speed for various lags as follows, or for a fixed lag with varying
+vector lengths as follows:
+
+     <pre class="example">          speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100,
+                 "v2 = xcorr_orig (x, n)", -100*eps)
+          speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100,
+                 "v2 = xcorr_orig (x, n)", -100*eps)
+</pre>
+        <p>Assuming one of the two versions is in <var>xcorr_orig</var>, this
+would compare their speed and their output values.  Note that the
+FFT version is not exact, so we specify an acceptable tolerance on
+the comparison <code>100*eps</code>, and the errors should be computed
+relatively, as <code>abs((</code><var>x</var><code> - </code><var>y</var><code>)./</code><var>y</var><code>)</code> rather than
+absolutely as <code>abs(</code><var>x</var><code> - </code><var>y</var><code>)</code>.
+
+        <p>Type <code>example('speed')</code> to see some real examples.  Note for
+obscure reasons, you can't run examples 1 and 2 directly using
+<code>demo('speed')</code>.  Instead use, <code>eval(example('speed',1))</code>
+and <code>eval(example('speed',2))</code>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2002, 2004, 2005, 2007, 2008, -->
+<!-- 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Derivatives-and-Integrals.html b/doc/interpreter/HTML/Derivatives-and-Integrals.html
new file mode 100644
index 0000000..5a130b6
--- /dev/null
+++ b/doc/interpreter/HTML/Derivatives-and-Integrals.html
@@ -0,0 +1,108 @@
+<html lang="en">
+<head>
+<title>Derivatives and Integrals - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="prev" href="Products-of-Polynomials.html#Products-of-Polynomials" title="Products of Polynomials">
+<link rel="next" href="Polynomial-Interpolation.html#Polynomial-Interpolation" title="Polynomial Interpolation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Derivatives-and-Integrals"></a>
+Next: <a rel="next" accesskey="n" href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a>,
+Previous: <a rel="previous" accesskey="p" href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a>,
+Up: <a rel="up" accesskey="u" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<hr>
+</div>
+
+<h3 class="section">27.4 Derivatives and Integrals</h3>
+
+<p>Octave comes with functions for computing the derivative and the integral
+of a polynomial.  The functions <code>polyderiv</code> and <code>polyint</code>
+both return new polynomials describing the result.  As an example we'll
+compute the definite integral of p(x) = x^2 + 1 from 0 to 3.
+
+<pre class="example">     c = [1, 0, 1];
+     integral = polyint(c);
+     area = polyval(integral, 3) - polyval(integral, 0)
+      12
+</pre>
+   <!-- ./polynomial/polyderiv.m -->
+   <p><a name="doc_002dpolyderiv"></a>
+
+<div class="defun">
+— Function File:  <b>polyderiv</b> (<var>c</var>)<var><a name="index-polyderiv-2040"></a></var><br>
+— Function File: [<var>q</var>] = <b>polyderiv</b> (<var>b, a</var>)<var><a name="index-polyderiv-2041"></a></var><br>
+— Function File: [<var>q</var>, <var>r</var>] = <b>polyderiv</b> (<var>b, a</var>)<var><a name="index-polyderiv-2042"></a></var><br>
+<blockquote><p>Return the coefficients of the derivative of the polynomial whose
+coefficients are given by vector <var>c</var>.  If a pair of polynomials
+is given <var>b</var> and <var>a</var>, the derivative of the product is
+returned in <var>q</var>, or the quotient numerator in <var>q</var> and the
+quotient denominator in <var>r</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>, <a href="doc_002dpolyreduce.html#doc_002dpolyreduce">polyreduce</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolygcd.html#doc_002dpolygcd">polygcd</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/polyder.m -->
+   <p><a name="doc_002dpolyder"></a>
+
+<div class="defun">
+— Function File:  <b>polyder</b> (<var>c</var>)<var><a name="index-polyder-2043"></a></var><br>
+— Function File: [<var>q</var>] = <b>polyder</b> (<var>b, a</var>)<var><a name="index-polyder-2044"></a></var><br>
+— Function File: [<var>q</var>, <var>r</var>] = <b>polyder</b> (<var>b, a</var>)<var><a name="index-polyder-2045"></a></var><br>
+<blockquote><p>See polyderiv. 
+</p></blockquote></div>
+
+<!-- ./deprecated/polyinteg.m -->
+   <p><a name="doc_002dpolyinteg"></a>
+
+<div class="defun">
+— Function File:  <b>polyinteg</b> (<var>c</var>)<var><a name="index-polyinteg-2046"></a></var><br>
+<blockquote><p>Return the coefficients of the integral of the polynomial whose
+coefficients are represented by the vector <var>c</var>.
+
+        <p>The constant of integration is set to zero. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolyint.html#doc_002dpolyint">polyint</a>, <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyreduce.html#doc_002dpolyreduce">polyreduce</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/polyint.m -->
+   <p><a name="doc_002dpolyint"></a>
+
+<div class="defun">
+— Function File:  <b>polyint</b> (<var>c, k</var>)<var><a name="index-polyint-2047"></a></var><br>
+<blockquote><p>Return the coefficients of the integral of the polynomial whose
+coefficients are represented by the vector <var>c</var>.  The variable
+<var>k</var> is the constant of integration, which by default is set to zero. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyreduce.html#doc_002dpolyreduce">polyreduce</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Descriptive-Statistics.html b/doc/interpreter/HTML/Descriptive-Statistics.html
new file mode 100644
index 0000000..8ada860
--- /dev/null
+++ b/doc/interpreter/HTML/Descriptive-Statistics.html
@@ -0,0 +1,379 @@
+<html lang="en">
+<head>
+<title>Descriptive Statistics - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="next" href="Basic-Statistical-Functions.html#Basic-Statistical-Functions" title="Basic Statistical Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Descriptive-Statistics"></a>
+Next: <a rel="next" accesskey="n" href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.1 Descriptive Statistics</h3>
+
+<p>Octave can compute various statistics such as the moments of a data set.
+
+<!-- ./statistics/base/mean.m -->
+   <p><a name="doc_002dmean"></a>
+
+<div class="defun">
+— Function File:  <b>mean</b> (<var>x, dim, opt</var>)<var><a name="index-mean-1819"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, compute the mean of the elements of <var>x</var>
+
+     <pre class="example">          mean (x) = SUM_i x(i) / N
+</pre>
+        <p>If <var>x</var> is a matrix, compute the mean for each column and return them
+in a row vector.
+
+        <p>With the optional argument <var>opt</var>, the kind of mean computed can be
+selected.  The following options are recognized:
+
+          <dl>
+<dt><code>"a"</code><dd>Compute the (ordinary) arithmetic mean.  This is the default.
+
+          <br><dt><code>"g"</code><dd>Compute the geometric mean.
+
+          <br><dt><code>"h"</code><dd>Compute the harmonic mean. 
+</dl>
+
+        <p>If the optional argument <var>dim</var> is supplied, work along dimension
+<var>dim</var>.
+
+        <p>Both <var>dim</var> and <var>opt</var> are optional.  If both are supplied,
+either may appear first. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/median.m -->
+   <p><a name="doc_002dmedian"></a>
+
+<div class="defun">
+— Function File:  <b>median</b> (<var>x, dim</var>)<var><a name="index-median-1820"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, compute the median value of the elements of
+<var>x</var>.  If the elements of <var>x</var> are sorted, the median is defined
+as
+
+     <pre class="example">                      x(ceil(N/2)),             N odd
+          median(x) =
+                      (x(N/2) + x((N/2)+1))/2,  N even
+</pre>
+        <p>If <var>x</var> is a matrix, compute the median value for each
+column and return them in a row vector.  If the optional <var>dim</var>
+argument is given, operate along this dimension. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstd.html#doc_002dstd">std</a>, <a href="doc_002dmean.html#doc_002dmean">mean</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/quantile.m -->
+   <p><a name="doc_002dquantile"></a>
+
+<div class="defun">
+— Function File: <var>q</var> = <b>quantile</b> (<var>x, p</var>)<var><a name="index-quantile-1821"></a></var><br>
+— Function File: <var>q</var> = <b>quantile</b> (<var>x, p, dim</var>)<var><a name="index-quantile-1822"></a></var><br>
+— Function File: <var>q</var> = <b>quantile</b> (<var>x, p, dim, method</var>)<var><a name="index-quantile-1823"></a></var><br>
+<blockquote><p>For a sample, <var>x</var>, calculate the quantiles, <var>q</var>, corresponding to
+the cumulative probability values in <var>p</var>.  All non-numeric values (NaNs) of
+<var>x</var> are ignored.
+
+        <p>If <var>x</var> is a matrix, compute the quantiles for each column and
+return them in a matrix, such that the i-th row of <var>q</var> contains
+the <var>p</var>(i)th quantiles of each column of <var>x</var>.
+
+        <p>The optional argument <var>dim</var> determines the dimension along which
+the percentiles are calculated.  If <var>dim</var> is omitted, and <var>x</var> is
+a vector or matrix, it defaults to 1 (column wise quantiles).  In the
+instance that <var>x</var> is a N-d array, <var>dim</var> defaults to the first
+dimension whose size greater than unity.
+
+        <p>The methods available to calculate sample quantiles are the nine methods
+used by R (http://www.r-project.org/).  The default value is METHOD = 5.
+
+        <p>Discontinuous sample quantile methods 1, 2, and 3
+
+          <ol type=1 start=1>
+<li>Method 1: Inverse of empirical distribution function. 
+<li>Method 2: Similar to method 1 but with averaging at discontinuities. 
+<li>Method 3: SAS definition: nearest even order statistic.
+             </ol>
+
+        <p>Continuous sample quantile methods 4 through 9, where p(k) is the linear
+interpolation function respecting each methods' representative cdf.
+
+          <ol type=1 start=4>
+<li>Method 4: p(k) = k / n. That is, linear interpolation of the empirical cdf. 
+<li>Method 5: p(k) = (k - 0.5) / n. That is a piecewise linear function where
+the knots are the values midway through the steps of the empirical cdf. 
+<li>Method 6: p(k) = k / (n + 1). 
+<li>Method 7: p(k) = (k - 1) / (n - 1). 
+<li>Method 8: p(k) = (k - 1/3) / (n + 1/3).  The resulting quantile estimates
+are approximately median-unbiased regardless of the distribution of <var>x</var>. 
+<li>Method 9: p(k) = (k - 3/8) / (n + 1/4).  The resulting quantile estimates
+are approximately unbiased for the expected order statistics if <var>x</var> is
+normally distributed.
+             </ol>
+
+        <p>Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R
+(versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS
+use method 6.  <span class="sc">matlab</span> uses method 5.
+
+        <p>References:
+
+          <ul>
+<li>Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New
+S Language.  Wadsworth & Brooks/Cole.
+
+          <li>Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in
+statistical packages, American Statistician, 50, 361–365.
+
+          <li>R: A Language and Environment for Statistical Computing;
+<a href="http://cran.r-project.org/doc/manuals/fullrefman.pdf">http://cran.r-project.org/doc/manuals/fullrefman.pdf</a>. 
+</ul>
+        </p></blockquote></div>
+
+<!-- ./statistics/base/prctile.m -->
+   <p><a name="doc_002dprctile"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>prctile</b> (<var>x, p</var>)<var><a name="index-prctile-1824"></a></var><br>
+— Function File: <var>q</var> = <b>prctile</b> (<var>x, p, dim</var>)<var><a name="index-prctile-1825"></a></var><br>
+<blockquote><p>For a sample <var>x</var>, compute the quantiles, <var>y</var>, corresponding
+to the cumulative probability values, P, in percent.  All non-numeric
+values (NaNs) of X are ignored.
+
+        <p>If <var>x</var> is a matrix, compute the percentiles for each column and
+return them in a matrix, such that the i-th row of <var>y</var> contains the
+<var>p</var>(i)th percentiles of each column of <var>x</var>.
+
+        <p>The optional argument <var>dim</var> determines the dimension along which
+the percentiles are calculated.  If <var>dim</var> is omitted, and <var>x</var> is
+a vector or matrix, it defaults to 1 (column wise quantiles).  In the
+instance that <var>x</var> is a N-d array, <var>dim</var> defaults to the first
+dimension whose size greater than unity.
+
+        </blockquote></div>
+
+<!-- ./statistics/base/meansq.m -->
+   <p><a name="doc_002dmeansq"></a>
+
+<div class="defun">
+— Function File:  <b>meansq</b> (<var>x</var>)<var><a name="index-meansq-1826"></a></var><br>
+— Function File:  <b>meansq</b> (<var>x, dim</var>)<var><a name="index-meansq-1827"></a></var><br>
+<blockquote><p>For vector arguments, return the mean square of the values. 
+For matrix arguments, return a row vector containing the mean square
+of each column.  With the optional <var>dim</var> argument, returns the
+mean squared of the values along this dimension. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/std.m -->
+   <p><a name="doc_002dstd"></a>
+
+<div class="defun">
+— Function File:  <b>std</b> (<var>x</var>)<var><a name="index-std-1828"></a></var><br>
+— Function File:  <b>std</b> (<var>x, opt</var>)<var><a name="index-std-1829"></a></var><br>
+— Function File:  <b>std</b> (<var>x, opt, dim</var>)<var><a name="index-std-1830"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, compute the standard deviation of the elements
+of <var>x</var>.
+
+     <pre class="example">          std (x) = sqrt (sumsq (x - mean (x)) / (n - 1))
+</pre>
+        <p>If <var>x</var> is a matrix, compute the standard deviation for
+each column and return them in a row vector.
+
+        <p>The argument <var>opt</var> determines the type of normalization to use.  Valid values
+are
+
+          <dl>
+<dt>0:<dd>  normalizes with N-1, provides the square root of best unbiased estimator of
+  the variance [default]
+<br><dt>1:<dd>  normalizes with N, this provides the square root of the second moment around
+  the mean
+</dl>
+
+        <p>The third argument <var>dim</var> determines the dimension along which the standard
+deviation is calculated. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmean.html#doc_002dmean">mean</a>, <a href="doc_002dmedian.html#doc_002dmedian">median</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/var.m -->
+   <p><a name="doc_002dvar"></a>
+
+<div class="defun">
+— Function File:  <b>var</b> (<var>x</var>)<var><a name="index-var-1831"></a></var><br>
+<blockquote><p>For vector arguments, return the (real) variance of the values. 
+For matrix arguments, return a row vector containing the variance for
+each column.
+
+        <p>The argument <var>opt</var> determines the type of normalization to use. 
+Valid values are
+
+          <dl>
+<dt>0:<dd>Normalizes with N-1, provides the best unbiased estimator of the
+variance [default]. 
+<br><dt>1:<dd>Normalizes with N, this provides the second moment around the mean. 
+</dl>
+
+        <p>The third argument <var>dim</var> determines the dimension along which the
+variance is calculated. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/mode.m -->
+   <p><a name="doc_002dmode"></a>
+
+<div class="defun">
+— Function File: [<var>m</var>, <var>f</var>, <var>c</var>] = <b>mode</b> (<var>x, dim</var>)<var><a name="index-mode-1832"></a></var><br>
+<blockquote><p>Count the most frequently appearing value.  <code>mode</code> counts the
+frequency along the first non-singleton dimension and if two or more
+values have the same frequency returns the smallest of the two in
+<var>m</var>.  The dimension along which to count can be specified by the
+<var>dim</var> parameter.
+
+        <p>The variable <var>f</var> counts the frequency of each of the most frequently
+occurring elements.  The cell array <var>c</var> contains all of the elements
+with the maximum frequency . 
+</p></blockquote></div>
+
+<!-- ./statistics/base/cov.m -->
+   <p><a name="doc_002dcov"></a>
+
+<div class="defun">
+— Function File:  <b>cov</b> (<var>x, y</var>)<var><a name="index-cov-1833"></a></var><br>
+<blockquote><p>Compute covariance.
+
+        <p>If each row of <var>x</var> and <var>y</var> is an observation and each column is
+a variable, the (<var>i</var>, <var>j</var>)-th entry of
+<code>cov (</code><var>x</var><code>, </code><var>y</var><code>)</code> is the covariance between the <var>i</var>-th
+variable in <var>x</var> and the <var>j</var>-th variable in <var>y</var>. 
+If called with one argument, compute <code>cov (</code><var>x</var><code>, </code><var>x</var><code>)</code>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/cor.m -->
+   <p><a name="doc_002dcor"></a>
+
+<div class="defun">
+— Function File:  <b>cor</b> (<var>x, y</var>)<var><a name="index-cor-1834"></a></var><br>
+<blockquote><p>Compute correlation.
+
+        <p>The (<var>i</var>, <var>j</var>)-th entry of <code>cor (</code><var>x</var><code>, </code><var>y</var><code>)</code> is
+the correlation between the <var>i</var>-th variable in <var>x</var> and the
+<var>j</var>-th variable in <var>y</var>.
+
+     <pre class="example">          corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+</pre>
+        <p>For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+        <p><code>cor (</code><var>x</var><code>)</code> is equivalent to <code>cor (</code><var>x</var><code>, </code><var>x</var><code>)</code>.
+
+        <p>Note that the <code>corrcoef</code> function does the same as <code>cor</code>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/corrcoef.m -->
+   <p><a name="doc_002dcorrcoef"></a>
+
+<div class="defun">
+— Function File:  <b>corrcoef</b> (<var>x, y</var>)<var><a name="index-corrcoef-1835"></a></var><br>
+<blockquote><p>Compute correlation.
+
+        <p>If each row of <var>x</var> and <var>y</var> is an observation and each column is
+a variable, the (<var>i</var>, <var>j</var>)-th entry of
+<code>corrcoef (</code><var>x</var><code>, </code><var>y</var><code>)</code> is the correlation between the
+<var>i</var>-th variable in <var>x</var> and the <var>j</var>-th variable in <var>y</var>.
+
+     <pre class="example">          corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+</pre>
+        <p>If called with one argument, compute <code>corrcoef (</code><var>x</var><code>, </code><var>x</var><code>)</code>. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/kurtosis.m -->
+   <p><a name="doc_002dkurtosis"></a>
+
+<div class="defun">
+— Function File:  <b>kurtosis</b> (<var>x, dim</var>)<var><a name="index-kurtosis-1836"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector of length N, return the kurtosis
+
+     <pre class="example">          kurtosis (x) = N^(-1) std(x)^(-4) sum ((x - mean(x)).^4) - 3
+</pre>
+        <p class="noindent">of <var>x</var>.  If <var>x</var> is a matrix, return the kurtosis over the
+first non-singleton dimension.  The optional argument <var>dim</var>
+can be given to force the kurtosis to be given over that
+dimension. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/skewness.m -->
+   <p><a name="doc_002dskewness"></a>
+
+<div class="defun">
+— Function File:  <b>skewness</b> (<var>x, dim</var>)<var><a name="index-skewness-1837"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector of length n, return the skewness
+
+     <pre class="example">          skewness (x) = N^(-1) std(x)^(-3) sum ((x - mean(x)).^3)
+</pre>
+        <p class="noindent">of <var>x</var>.  If <var>x</var> is a matrix, return the skewness along the
+first non-singleton dimension of the matrix.  If the optional
+<var>dim</var> argument is given, operate along this dimension. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/statistics.m -->
+   <p><a name="doc_002dstatistics"></a>
+
+<div class="defun">
+— Function File:  <b>statistics</b> (<var>x</var>)<var><a name="index-statistics-1838"></a></var><br>
+<blockquote><p>If <var>x</var> is a matrix, return a matrix with the minimum, first
+quartile, median, third quartile, maximum, mean, standard deviation,
+skewness and kurtosis of the columns of <var>x</var> as its columns.
+
+        <p>If <var>x</var> is a vector, calculate the statistics along the
+non-singleton dimension. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/moment.m -->
+   <p><a name="doc_002dmoment"></a>
+
+<div class="defun">
+— Function File:  <b>moment</b> (<var>x, p, opt, dim</var>)<var><a name="index-moment-1839"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, compute the <var>p</var>-th moment of <var>x</var>.
+
+        <p>If <var>x</var> is a matrix, return the row vector containing the
+<var>p</var>-th moment of each column.
+
+        <p>With the optional string opt, the kind of moment to be computed can
+be specified.  If opt contains <code>"c"</code> or <code>"a"</code>, central
+and/or absolute moments are returned.  For example,
+
+     <pre class="example">          moment (x, 3, "ac")
+</pre>
+        <p class="noindent">computes the third central absolute moment of <var>x</var>.
+
+        <p>If the optional argument <var>dim</var> is supplied, work along dimension
+<var>dim</var>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Diagonal-Matrix-Functions.html b/doc/interpreter/HTML/Diagonal-Matrix-Functions.html
new file mode 100644
index 0000000..6edd55a
--- /dev/null
+++ b/doc/interpreter/HTML/Diagonal-Matrix-Functions.html
@@ -0,0 +1,47 @@
+<html lang="en">
+<head>
+<title>Diagonal Matrix Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Support.html#Function-Support" title="Function Support">
+<link rel="next" href="Permutation-Matrix-Functions.html#Permutation-Matrix-Functions" title="Permutation Matrix Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Diagonal-Matrix-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Permutation-Matrix-Functions.html#Permutation-Matrix-Functions">Permutation Matrix Functions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Support.html#Function-Support">Function Support</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.3.1 Diagonal Matrix Functions</h4>
+
+<p><dfn>inv</dfn> and <dfn>pinv</dfn> can be applied to a diagonal matrix, yielding again
+a diagonal matrix.  <dfn>det</dfn> will use an efficient straightforward calculation
+when given a diagonal matrix, as well as <dfn>cond</dfn>. 
+The following mapper functions can be applied to a diagonal matrix
+without converting it to a full one:
+<dfn>abs</dfn>, <dfn>real</dfn>, <dfn>imag</dfn>, <dfn>conj</dfn>, <dfn>sqrt</dfn>. 
+A diagonal matrix can also be returned from the <dfn>balance</dfn>
+and <dfn>svd</dfn> functions. 
+The <dfn>sparse</dfn> function will convert a diagonal matrix efficiently to a
+sparse matrix.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Diagonal-and-Permutation-Matrices.html b/doc/interpreter/HTML/Diagonal-and-Permutation-Matrices.html
new file mode 100644
index 0000000..752437d
--- /dev/null
+++ b/doc/interpreter/HTML/Diagonal-and-Permutation-Matrices.html
@@ -0,0 +1,45 @@
+<html lang="en">
+<head>
+<title>Diagonal and Permutation Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Nonlinear-Equations.html#Nonlinear-Equations" title="Nonlinear Equations">
+<link rel="next" href="Sparse-Matrices.html#Sparse-Matrices" title="Sparse Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Diagonal-and-Permutation-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>,
+Previous: <a rel="previous" accesskey="p" href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">20 Diagonal and Permutation Matrices</h2>
+
+<ul class="menu">
+<li><a accesskey="1" href="Basic-Usage.html#Basic-Usage">Basic Usage</a>:           Creation and Manipulation of Diagonal and Permutation Matrices
+<li><a accesskey="2" href="Matrix-Algebra.html#Matrix-Algebra">Matrix Algebra</a>:        Linear Algebra with Diagonal and Permutation Matrices
+<li><a accesskey="3" href="Function-Support.html#Function-Support">Function Support</a>:      Functions That Are Aware of These Matrices
+<li><a accesskey="4" href="Example-Codes.html#Example-Codes">Example Codes</a>:         Some Examples of Usage
+<li><a accesskey="5" href="Zeros-Treatment.html#Zeros-Treatment">Zeros Treatment</a>:       The Differences in Treatment of Zero Elements
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Diary-and-Echo-Commands.html b/doc/interpreter/HTML/Diary-and-Echo-Commands.html
new file mode 100644
index 0000000..a795b4f
--- /dev/null
+++ b/doc/interpreter/HTML/Diary-and-Echo-Commands.html
@@ -0,0 +1,112 @@
+<html lang="en">
+<head>
+<title>Diary and Echo Commands - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Customizing-the-Prompt.html#Customizing-the-Prompt" title="Customizing the Prompt">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Diary-and-Echo-Commands"></a>
+Previous: <a rel="previous" accesskey="p" href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.8 Diary and Echo Commands</h4>
+
+<p><a name="index-diary-of-commands-and-output-142"></a><a name="index-command-and-output-logs-143"></a><a name="index-logging-commands-and-output-144"></a><a name="index-echoing-executing-commands-145"></a><a name="index-command-echoing-146"></a>
+Octave's diary feature allows you to keep a log of all or part of an
+interactive session by recording the input you type and the output that
+Octave produces in a separate file.
+
+<!-- pager.cc -->
+   <p><a name="doc_002ddiary"></a>
+
+<div class="defun">
+— Command: <b>diary</b><var> options<a name="index-diary-147"></a></var><br>
+<blockquote><p>Record a list of all commands <em>and</em> the output they produce, mixed
+together just as you see them on your terminal.  Valid options are:
+
+          <dl>
+<dt><code>on</code><dd>Start recording your session in a file called <samp><span class="file">diary</span></samp> in your
+current working directory.
+
+          <br><dt><code>off</code><dd>Stop recording your session in the diary file.
+
+          <br><dt><var>file</var><dd>Record your session in the file named <var>file</var>. 
+</dl>
+
+        <p>With no arguments, <code>diary</code> toggles the current diary state. 
+</p></blockquote></div>
+
+   <p>Sometimes it is useful to see the commands in a function or script as
+they are being evaluated.  This can be especially helpful for debugging
+some kinds of problems.
+
+<!-- input.cc -->
+   <p><a name="doc_002decho"></a>
+
+<div class="defun">
+— Command: <b>echo</b><var> options<a name="index-echo-148"></a></var><br>
+<blockquote><p>Control whether commands are displayed as they are executed.  Valid
+options are:
+
+          <dl>
+<dt><code>on</code><dd>Enable echoing of commands as they are executed in script files.
+
+          <br><dt><code>off</code><dd>Disable echoing of commands as they are executed in script files.
+
+          <br><dt><code>on all</code><dd>Enable echoing of commands as they are executed in script files and
+functions.
+
+          <br><dt><code>off all</code><dd>Disable echoing of commands as they are executed in script files and
+functions. 
+</dl>
+
+     <p class="noindent">With no arguments, <code>echo</code> toggles the current echo state. 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002decho_005fexecuting_005fcommands"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>echo_executing_commands</b> ()<var><a name="index-echo_005fexecuting_005fcommands-149"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>echo_executing_commands</b> (<var>new_val</var>)<var><a name="index-echo_005fexecuting_005fcommands-150"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls the echo state. 
+It may be the sum of the following values:
+
+          <dl>
+<dt>1<dd>Echo commands read from script files.
+
+          <br><dt>2<dd>Echo commands from functions.
+
+          <br><dt>4<dd>Echo commands read from command line. 
+</dl>
+
+        <p>More than one state can be active at once.  For example, a value of 3 is
+equivalent to the command <kbd>echo on all</kbd>.
+
+        <p>The value of <code>echo_executing_commands</code> may be set by the <kbd>echo</kbd>
+command or the command line option <code>--echo-commands</code>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Differential-Equations.html b/doc/interpreter/HTML/Differential-Equations.html
new file mode 100644
index 0000000..1642bfb
--- /dev/null
+++ b/doc/interpreter/HTML/Differential-Equations.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Differential Equations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Numerical-Integration.html#Numerical-Integration" title="Numerical Integration">
+<link rel="next" href="Optimization.html#Optimization" title="Optimization">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Differential-Equations"></a>
+Next: <a rel="next" accesskey="n" href="Optimization.html#Optimization">Optimization</a>,
+Previous: <a rel="previous" accesskey="p" href="Numerical-Integration.html#Numerical-Integration">Numerical Integration</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">23 Differential Equations</h2>
+
+<p>Octave has built-in functions for solving ordinary differential equations,
+and differential-algebraic equations. 
+All solvers are based on reliable ODE routines written in Fortran.
+
+<ul class="menu">
+<li><a accesskey="1" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a>
+<li><a accesskey="2" href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a>
+</ul>
+
+   <p><a name="index-Differential-Equations-1783"></a><a name="index-ODE-1784"></a><a name="index-DAE-1785"></a>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Differential_002dAlgebraic-Equations.html b/doc/interpreter/HTML/Differential_002dAlgebraic-Equations.html
new file mode 100644
index 0000000..f7d918d
--- /dev/null
+++ b/doc/interpreter/HTML/Differential_002dAlgebraic-Equations.html
@@ -0,0 +1,527 @@
+<html lang="en">
+<head>
+<title>Differential-Algebraic Equations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Differential-Equations.html#Differential-Equations" title="Differential Equations">
+<link rel="prev" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations" title="Ordinary Differential Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Differential-Algebraic-Equations"></a>
+<a name="Differential_002dAlgebraic-Equations"></a>
+Previous: <a rel="previous" accesskey="p" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a>,
+Up: <a rel="up" accesskey="u" href="Differential-Equations.html#Differential-Equations">Differential Equations</a>
+<hr>
+</div>
+
+<h3 class="section">23.2 Differential-Algebraic Equations</h3>
+
+<p>The function <code>daspk</code> can be used to solve DAEs of the form
+
+<pre class="example">     0 = f (x-dot, x, t),    x(t=0) = x_0, x-dot(t=0) = x-dot_0
+</pre>
+   <p class="noindent">where
+x-dot
+is the derivative of x.  The equation is solved using Petzold's
+DAE solver <span class="sc">Daspk</span>.
+
+<!-- ./DLD-FUNCTIONS/daspk.cc -->
+   <p><a name="doc_002ddaspk"></a>
+
+<div class="defun">
+— Loadable Function: [<var>x</var>, <var>xdot</var>, <var>istate</var>, <var>msg</var>] = <b>daspk</b> (<var>fcn, x_0, xdot_0, t, t_crit</var>)<var><a name="index-daspk-1789"></a></var><br>
+<blockquote><p>Solve the set of differential-algebraic equations
+
+     <pre class="example">          0 = f (x, xdot, t)
+</pre>
+        <p>with
+
+     <pre class="example">          x(t_0) = x_0, xdot(t_0) = xdot_0
+</pre>
+        <p>The solution is returned in the matrices <var>x</var> and <var>xdot</var>,
+with each row in the result matrices corresponding to one of the
+elements in the vector <var>t</var>.  The first element of <var>t</var>
+should be t_0 and correspond to the initial state of the
+system <var>x_0</var> and its derivative <var>xdot_0</var>, so that the first
+row of the output <var>x</var> is <var>x_0</var> and the first row
+of the output <var>xdot</var> is <var>xdot_0</var>.
+
+        <p>The first argument, <var>fcn</var>, is a string, inline, or function handle
+that names the function f to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+     <pre class="example">          <var>res</var> = f (<var>x</var>, <var>xdot</var>, <var>t</var>)
+</pre>
+        <p class="noindent">in which <var>x</var>, <var>xdot</var>, and <var>res</var> are vectors, and <var>t</var> is a
+scalar.
+
+        <p>If <var>fcn</var> is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function f described above, and the second element names a
+function to compute the modified Jacobian
+
+     <pre class="example">                df       df
+          jac = -- + c ------
+                dx     d xdot
+</pre>
+        <p>The modified Jacobian function must have the form
+
+     <pre class="example">          
+          <var>jac</var> = j (<var>x</var>, <var>xdot</var>, <var>t</var>, <var>c</var>)
+</pre>
+        <p>The second and third arguments to <code>daspk</code> specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+        <p>The set of initial states and derivatives are not strictly required to
+be consistent.  If they are not consistent, you must use the
+<code>daspk_options</code> function to provide additional information so
+that <code>daspk</code> can compute a consistent starting point.
+
+        <p>The fifth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+        <p>After a successful computation, the value of <var>istate</var> will be
+greater than zero (consistent with the Fortran version of <span class="sc">Daspk</span>).
+
+        <p>If the computation is not successful, the value of <var>istate</var> will be
+less than zero and <var>msg</var> will contain additional information.
+
+        <p>You can use the function <code>daspk_options</code> to set optional
+parameters for <code>daspk</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddassl.html#doc_002ddassl">dassl</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/daspk.cc -->
+   <p><a name="doc_002ddaspk_005foptions"></a>
+
+<div class="defun">
+— Loadable Function:  <b>daspk_options</b> (<var>opt, val</var>)<var><a name="index-daspk_005foptions-1790"></a></var><br>
+<blockquote><p>When called with two arguments, this function
+allows you set options parameters for the function <code>daspk</code>. 
+Given one argument, <code>daspk_options</code> returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+        <p>Options include
+
+          <dl>
+<dt><code>"absolute tolerance"</code><dd>Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length. 
+<br><dt><code>"relative tolerance"</code><dd>Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+          <p>The local error test applied at each integration step is
+
+          <pre class="example">                 abs (local error in x(i))
+                      <= rtol(i) * abs (Y(i)) + atol(i)
+</pre>
+          <br><dt><code>"compute consistent initial condition"</code><dd>Denoting the differential variables in the state vector by ‘<samp><span class="samp">Y_d</span></samp>’
+and the algebraic variables by ‘<samp><span class="samp">Y_a</span></samp>’, <code>ddaspk</code> can solve
+one of two initialization problems:
+
+               <ol type=1 start=1>
+<li>Given Y_d, calculate Y_a and Y'_d
+<li>Given Y', calculate Y.
+               </ol>
+
+          <p>In either case, initial values for the given components are input, and
+initial guesses for the unknown components must also be provided as
+input.  Set this option to 1 to solve the first problem, or 2 to solve
+the second (the default is 0, so you must provide a set of
+initial conditions that are consistent).
+
+          <p>If this option is set to a nonzero value, you must also set the
+<code>"algebraic variables"</code> option to declare which variables in the
+problem are algebraic. 
+<br><dt><code>"use initial condition heuristics"</code><dd>Set to a nonzero value to use the initial condition heuristics options
+described below. 
+<br><dt><code>"initial condition heuristics"</code><dd>A vector of the following parameters that can be used to control the
+initial condition calculation.
+
+               <dl>
+<dt><code>MXNIT</code><dd>Maximum number of Newton iterations (default is 5). 
+<br><dt><code>MXNJ</code><dd>Maximum number of Jacobian evaluations (default is 6). 
+<br><dt><code>MXNH</code><dd>Maximum number of values of the artificial stepsize parameter to be
+tried if the <code>"compute consistent initial condition"</code> option has
+been set to 1 (default is 5).
+
+               <p>Note that the maximum total number of Newton iterations allowed is
+<code>MXNIT*MXNJ*MXNH</code> if the <code>"compute consistent initial
+condition"</code> option has been set to 1 and <code>MXNIT*MXNJ</code> if it is
+set to 2. 
+<br><dt><code>LSOFF</code><dd>Set to a nonzero value to disable the linesearch algorithm (default is
+0). 
+<br><dt><code>STPTOL</code><dd>Minimum scaled step in linesearch algorithm (default is eps^(2/3)). 
+<br><dt><code>EPINIT</code><dd>Swing factor in the Newton iteration convergence test.  The test is
+applied to the residual vector, premultiplied by the approximate
+Jacobian.  For convergence, the weighted RMS norm of this vector
+(scaled by the error weights) must be less than <code>EPINIT*EPCON</code>,
+where <code>EPCON</code> = 0.33 is the analogous test constant used in the
+time steps.  The default is <code>EPINIT</code> = 0.01. 
+</dl>
+          <br><dt><code>"print initial condition info"</code><dd>Set this option to a nonzero value to display detailed information
+about the initial condition calculation (default is 0). 
+<br><dt><code>"exclude algebraic variables from error test"</code><dd>Set to a nonzero value to exclude algebraic variables from the error
+test.  You must also set the <code>"algebraic variables"</code> option to
+declare which variables in the problem are algebraic (default is 0). 
+<br><dt><code>"algebraic variables"</code><dd>A vector of the same length as the state vector.  A nonzero element
+indicates that the corresponding element of the state vector is an
+algebraic variable (i.e., its derivative does not appear explicitly
+in the equation set.
+
+          <p>This option is required by the
+<code>compute consistent initial condition"</code> and
+<code>"exclude algebraic variables from error test"</code> options. 
+<br><dt><code>"enforce inequality constraints"</code><dd>Set to one of the following values to enforce the inequality
+constraints specified by the <code>"inequality constraint types"</code>
+option (default is 0).
+
+               <ol type=1 start=1>
+<li>To have constraint checking only in the initial condition calculation. 
+<li>To enforce constraint checking during the integration. 
+<li>To enforce both options 1 and 2.
+               </ol>
+<br><dt><code>"inequality constraint types"</code><dd>A vector of the same length as the state specifying the type of
+inequality constraint.  Each element of the vector corresponds to an
+element of the state and should be assigned one of the following
+codes
+
+               <dl>
+<dt>-2<dd>Less than zero. 
+<br><dt>-1<dd>Less than or equal to zero. 
+<br><dt>0<dd>Not constrained. 
+<br><dt>1<dd>Greater than or equal to zero. 
+<br><dt>2<dd>Greater than zero. 
+</dl>
+
+          <p>This option only has an effect if the
+<code>"enforce inequality constraints"</code> option is nonzero. 
+<br><dt><code>"initial step size"</code><dd>Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize (default is computed
+automatically). 
+<br><dt><code>"maximum order"</code><dd>Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive (default is 5). 
+<br><dt><code>"maximum step size"</code><dd>Setting the maximum stepsize will avoid passing over very large
+regions (default is not specified). 
+</dl>
+        </p></blockquote></div>
+
+   <p>Octave also includes <span class="sc">Dassl</span>, an earlier version of <var>Daspk</var>,
+and <var>dasrt</var>, which can be used to solve DAEs with constraints
+(stopping conditions).
+
+<!-- ./DLD-FUNCTIONS/dassl.cc -->
+   <p><a name="doc_002ddassl"></a>
+
+<div class="defun">
+— Loadable Function: [<var>x</var>, <var>xdot</var>, <var>istate</var>, <var>msg</var>] = <b>dassl</b> (<var>fcn, x_0, xdot_0, t, t_crit</var>)<var><a name="index-dassl-1791"></a></var><br>
+<blockquote><p>Solve the set of differential-algebraic equations
+
+     <pre class="example">          0 = f (x, xdot, t)
+</pre>
+        <p class="noindent">with
+
+     <pre class="example">          x(t_0) = x_0, xdot(t_0) = xdot_0
+</pre>
+        <p>The solution is returned in the matrices <var>x</var> and <var>xdot</var>,
+with each row in the result matrices corresponding to one of the
+elements in the vector <var>t</var>.  The first element of <var>t</var>
+should be t_0 and correspond to the initial state of the
+system <var>x_0</var> and its derivative <var>xdot_0</var>, so that the first
+row of the output <var>x</var> is <var>x_0</var> and the first row
+of the output <var>xdot</var> is <var>xdot_0</var>.
+
+        <p>The first argument, <var>fcn</var>, is a string, inline, or function handle
+that names the function f to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+     <pre class="example">          <var>res</var> = f (<var>x</var>, <var>xdot</var>, <var>t</var>)
+</pre>
+        <p class="noindent">in which <var>x</var>, <var>xdot</var>, and <var>res</var> are vectors, and <var>t</var> is a
+scalar.
+
+        <p>If <var>fcn</var> is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function f described above, and the second element names a
+function to compute the modified Jacobian
+
+     <pre class="example">                df       df
+          jac = -- + c ------
+                dx     d xdot
+</pre>
+        <p>The modified Jacobian function must have the form
+
+     <pre class="example">          
+          <var>jac</var> = j (<var>x</var>, <var>xdot</var>, <var>t</var>, <var>c</var>)
+</pre>
+        <p>The second and third arguments to <code>dassl</code> specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+        <p>The set of initial states and derivatives are not strictly required to
+be consistent.  In practice, however, <span class="sc">Dassl</span> is not very good at
+determining a consistent set for you, so it is best if you ensure that
+the initial values result in the function evaluating to zero.
+
+        <p>The fifth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+        <p>After a successful computation, the value of <var>istate</var> will be
+greater than zero (consistent with the Fortran version of <span class="sc">Dassl</span>).
+
+        <p>If the computation is not successful, the value of <var>istate</var> will be
+less than zero and <var>msg</var> will contain additional information.
+
+        <p>You can use the function <code>dassl_options</code> to set optional
+parameters for <code>dassl</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddaspk.html#doc_002ddaspk">daspk</a>, <a href="doc_002ddasrt.html#doc_002ddasrt">dasrt</a>, <a href="doc_002dlsode.html#doc_002dlsode">lsode</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dassl.cc -->
+   <p><a name="doc_002ddassl_005foptions"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dassl_options</b> (<var>opt, val</var>)<var><a name="index-dassl_005foptions-1792"></a></var><br>
+<blockquote><p>When called with two arguments, this function
+allows you set options parameters for the function <code>dassl</code>. 
+Given one argument, <code>dassl_options</code> returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+        <p>Options include
+
+          <dl>
+<dt><code>"absolute tolerance"</code><dd>Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length. 
+<br><dt><code>"relative tolerance"</code><dd>Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+          <p>The local error test applied at each integration step is
+
+          <pre class="example">                 abs (local error in x(i))
+                      <= rtol(i) * abs (Y(i)) + atol(i)
+</pre>
+          <br><dt><code>"compute consistent initial condition"</code><dd>If nonzero, <code>dassl</code> will attempt to compute a consistent set of initial
+conditions.  This is generally not reliable, so it is best to provide
+a consistent set and leave this option set to zero. 
+<br><dt><code>"enforce nonnegativity constraints"</code><dd>If you know that the solutions to your equations will always be
+nonnegative, it may help to set this parameter to a nonzero
+value.  However, it is probably best to try leaving this option set to
+zero first, and only setting it to a nonzero value if that doesn't
+work very well. 
+<br><dt><code>"initial step size"</code><dd>Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize. 
+<br><dt><code>"maximum order"</code><dd>Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive. 
+<br><dt><code>"maximum step size"</code><dd>Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified). 
+<br><dt><code>"step limit"</code><dd>Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code. 
+</dl>
+        </p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dasrt.cc -->
+   <p><a name="doc_002ddasrt"></a>
+
+<div class="defun">
+— Loadable Function: [<var>x</var>, <var>xdot</var>, <var>t_out</var>, <var>istat</var>, <var>msg</var>] = <b>dasrt</b> (<var>fcn </var>[<var>, g</var>]<var>, x_0, xdot_0, t </var>[<var>, t_crit</var>])<var><a name="index-dasrt-1793"></a></var><br>
+<blockquote><p>Solve the set of differential-algebraic equations
+
+     <pre class="example">          0 = f (x, xdot, t)
+</pre>
+        <p>with
+
+     <pre class="example">          x(t_0) = x_0, xdot(t_0) = xdot_0
+</pre>
+        <p>with functional stopping criteria (root solving).
+
+        <p>The solution is returned in the matrices <var>x</var> and <var>xdot</var>,
+with each row in the result matrices corresponding to one of the
+elements in the vector <var>t_out</var>.  The first element of <var>t</var>
+should be t_0 and correspond to the initial state of the
+system <var>x_0</var> and its derivative <var>xdot_0</var>, so that the first
+row of the output <var>x</var> is <var>x_0</var> and the first row
+of the output <var>xdot</var> is <var>xdot_0</var>.
+
+        <p>The vector <var>t</var> provides an upper limit on the length of the
+integration.  If the stopping condition is met, the vector
+<var>t_out</var> will be shorter than <var>t</var>, and the final element of
+<var>t_out</var> will be the point at which the stopping condition was met,
+and may not correspond to any element of the vector <var>t</var>.
+
+        <p>The first argument, <var>fcn</var>, is a string, inline, or function handle
+that names the function f to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+     <pre class="example">          <var>res</var> = f (<var>x</var>, <var>xdot</var>, <var>t</var>)
+</pre>
+        <p class="noindent">in which <var>x</var>, <var>xdot</var>, and <var>res</var> are vectors, and <var>t</var> is a
+scalar.
+
+        <p>If <var>fcn</var> is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function f described above, and the second element names a
+function to compute the modified Jacobian
+
+     <pre class="example">                df       df
+          jac = -- + c ------
+                dx     d xdot
+</pre>
+        <p>The modified Jacobian function must have the form
+
+     <pre class="example">          
+          <var>jac</var> = j (<var>x</var>, <var>xdot</var>, <var>t</var>, <var>c</var>)
+</pre>
+        <p>The optional second argument names a function that defines the
+constraint functions whose roots are desired during the integration. 
+This function must have the form
+
+     <pre class="example">          <var>g_out</var> = g (<var>x</var>, <var>t</var>)
+</pre>
+        <p>and return a vector of the constraint function values. 
+If the value of any of the constraint functions changes sign, <span class="sc">Dasrt</span>
+will attempt to stop the integration at the point of the sign change.
+
+        <p>If the name of the constraint function is omitted, <code>dasrt</code> solves
+the same problem as <code>daspk</code> or <code>dassl</code>.
+
+        <p>Note that because of numerical errors in the constraint functions
+due to roundoff and integration error, <span class="sc">Dasrt</span> may return false
+roots, or return the same root at two or more nearly equal values of
+<var>T</var>.  If such false roots are suspected, the user should consider
+smaller error tolerances or higher precision in the evaluation of the
+constraint functions.
+
+        <p>If a root of some constraint function defines the end of the problem,
+the input to <span class="sc">Dasrt</span> should nevertheless allow integration to a
+point slightly past that root, so that <span class="sc">Dasrt</span> can locate the root
+by interpolation.
+
+        <p>The third and fourth arguments to <code>dasrt</code> specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+        <p>The set of initial states and derivatives are not strictly required to
+be consistent.  In practice, however, <span class="sc">Dassl</span> is not very good at
+determining a consistent set for you, so it is best if you ensure that
+the initial values result in the function evaluating to zero.
+
+        <p>The sixth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+        <p>After a successful computation, the value of <var>istate</var> will be
+greater than zero (consistent with the Fortran version of <span class="sc">Dassl</span>).
+
+        <p>If the computation is not successful, the value of <var>istate</var> will be
+less than zero and <var>msg</var> will contain additional information.
+
+        <p>You can use the function <code>dasrt_options</code> to set optional
+parameters for <code>dasrt</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddaspk.html#doc_002ddaspk">daspk</a>, <a href="doc_002ddasrt.html#doc_002ddasrt">dasrt</a>, <a href="doc_002dlsode.html#doc_002dlsode">lsode</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dasrt.cc -->
+   <p><a name="doc_002ddasrt_005foptions"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dasrt_options</b> (<var>opt, val</var>)<var><a name="index-dasrt_005foptions-1794"></a></var><br>
+<blockquote><p>When called with two arguments, this function
+allows you set options parameters for the function <code>dasrt</code>. 
+Given one argument, <code>dasrt_options</code> returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+        <p>Options include
+
+          <dl>
+<dt><code>"absolute tolerance"</code><dd>Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length. 
+<br><dt><code>"relative tolerance"</code><dd>Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+          <p>The local error test applied at each integration step is
+          <pre class="example">                 abs (local error in x(i)) <= ...
+                     rtol(i) * abs (Y(i)) + atol(i)
+</pre>
+          <br><dt><code>"initial step size"</code><dd>Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize. 
+<br><dt><code>"maximum order"</code><dd>Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive. 
+<br><dt><code>"maximum step size"</code><dd>Setting the maximum stepsize will avoid passing over very large
+regions. 
+<br><dt><code>"step limit"</code><dd>Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code. 
+</dl>
+        </p></blockquote></div>
+
+   <p>See K. E. Brenan, et al., <cite>Numerical Solution of Initial-Value
+Problems in Differential-Algebraic Equations</cite>, North-Holland (1989) for
+more information about the implementation of <span class="sc">Dassl</span>.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Displaying-Images.html b/doc/interpreter/HTML/Displaying-Images.html
new file mode 100644
index 0000000..520555c
--- /dev/null
+++ b/doc/interpreter/HTML/Displaying-Images.html
@@ -0,0 +1,182 @@
+<html lang="en">
+<head>
+<title>Displaying Images - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link rel="prev" href="Loading-and-Saving-Images.html#Loading-and-Saving-Images" title="Loading and Saving Images">
+<link rel="next" href="Representing-Images.html#Representing-Images" title="Representing Images">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Displaying-Images"></a>
+Next: <a rel="next" accesskey="n" href="Representing-Images.html#Representing-Images">Representing Images</a>,
+Previous: <a rel="previous" accesskey="p" href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a>,
+Up: <a rel="up" accesskey="u" href="Image-Processing.html#Image-Processing">Image Processing</a>
+<hr>
+</div>
+
+<h3 class="section">31.2 Displaying Images</h3>
+
+<p>A natural part of image processing is visualization of an image. 
+The most basic function for this is the <code>imshow</code> function that
+shows the image given in the first input argument.  This function uses
+an external program to show the image.  If gnuplot 4.2 or later is
+available it will be used to display the image, otherwise the
+<code>display</code>, <code>xv</code>, or <code>xloadimage</code> program is used.  The
+actual program can be selected with the <code>image_viewer</code> function.
+
+<!-- ./image/imshow.m -->
+   <p><a name="doc_002dimshow"></a>
+
+<div class="defun">
+— Function File:  <b>imshow</b> (<var>im</var>)<var><a name="index-imshow-2189"></a></var><br>
+— Function File:  <b>imshow</b> (<var>im, limits</var>)<var><a name="index-imshow-2190"></a></var><br>
+— Function File:  <b>imshow</b> (<var>im, map</var>)<var><a name="index-imshow-2191"></a></var><br>
+— Function File:  <b>imshow</b> (<var>rgb, <small class="dots">...</small></var>)<var><a name="index-imshow-2192"></a></var><br>
+— Function File:  <b>imshow</b> (<var>filename</var>)<var><a name="index-imshow-2193"></a></var><br>
+— Function File:  <b>imshow</b> (<var><small class="dots">...</small>, string_param1, value1, <small class="dots">...</small></var>)<var><a name="index-imshow-2194"></a></var><br>
+<blockquote><p>Display the image <var>im</var>, where <var>im</var> can be a 2-dimensional
+(gray-scale image) or a 3-dimensional (RGB image) matrix.
+
+        <p>If <var>limits</var> is a 2-element vector <code>[</code><var>low</var><code>, </code><var>high</var><code>]</code>,
+the image is shown using a display range between <var>low</var> and
+<var>high</var>.  If an empty matrix is passed for <var>limits</var>, the
+display range is computed as the range between the minimal and the
+maximal value in the image.
+
+        <p>If <var>map</var> is a valid color map, the image will be shown as an indexed
+image using the supplied color map.
+
+        <p>If a file name is given instead of an image, the file will be read and
+shown.
+
+        <p>If given, the parameter <var>string_param1</var> has value
+<var>value1</var>.  <var>string_param1</var> can be any of the following:
+          <dl>
+<dt>‘<samp><span class="samp">"displayrange"</span></samp>’<dd><var>value1</var> is the display range as described above. 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimage.html#doc_002dimage">image</a>, <a href="doc_002dimagesc.html#doc_002dimagesc">imagesc</a>, <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>, <a href="doc_002dgray2ind.html#doc_002dgray2ind">gray2ind</a>, <a href="doc_002drgb2ind.html#doc_002drgb2ind">rgb2ind</a>. 
+</p></blockquote></div>
+
+<!-- ./image/image.m -->
+   <p><a name="doc_002dimage"></a>
+
+<div class="defun">
+— Function File:  <b>image</b> (<var>img</var>)<var><a name="index-image-2195"></a></var><br>
+— Function File:  <b>image</b> (<var>x, y, img</var>)<var><a name="index-image-2196"></a></var><br>
+<blockquote><p>Display a matrix as a color image.  The elements of <var>x</var> are indices
+into the current colormap, and the colormap will be scaled so that the
+extremes of <var>x</var> are mapped to the extremes of the colormap.
+
+        <p>It first tries to use <code>gnuplot</code>, then <code>display</code> from
+<code>ImageMagick</code>, then <code>xv</code>, and then <code>xloadimage</code>. 
+The actual program used can be changed using the <code>image_viewer</code>
+function.
+
+        <p>The axis values corresponding to the matrix elements are specified in
+<var>x</var> and <var>y</var>.  If you're not using gnuplot 4.2 or later, these
+variables are ignored. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimshow.html#doc_002dimshow">imshow</a>, <a href="doc_002dimagesc.html#doc_002dimagesc">imagesc</a>, <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>, <a href="doc_002dimage_005fviewer.html#doc_002dimage_005fviewer">image_viewer</a>. 
+</p></blockquote></div>
+
+<!-- ./image/imagesc.m -->
+   <p><a name="doc_002dimagesc"></a>
+
+<div class="defun">
+— Function File:  <b>imagesc</b> (<var>a</var>)<var><a name="index-imagesc-2197"></a></var><br>
+— Function File:  <b>imagesc</b> (<var>x, y, a</var>)<var><a name="index-imagesc-2198"></a></var><br>
+— Function File:  <b>imagesc</b> (<var><small class="dots">...</small>, limits</var>)<var><a name="index-imagesc-2199"></a></var><br>
+— Function File:  <b>imagesc</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-imagesc-2200"></a></var><br>
+— Function File: <var>h</var> = <b>imagesc</b> (<var><small class="dots">...</small></var>)<var><a name="index-imagesc-2201"></a></var><br>
+<blockquote><p>Display a scaled version of the matrix <var>a</var> as a color image.  The
+colormap is scaled so that the entries of the matrix occupy the entire
+colormap.  If <var>limits</var> = [<var>lo</var>, <var>hi</var>] are given, then that
+range is set to the 'clim' of the current axes.
+
+        <p>The axis values corresponding to the matrix elements are specified in
+<var>x</var> and <var>y</var>, either as pairs giving the minimum and maximum
+values for the respective axes, or as values for each row and column
+of the matrix <var>a</var>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimage.html#doc_002dimage">image</a>, <a href="doc_002dimshow.html#doc_002dimshow">imshow</a>, <a href="doc_002dcaxis.html#doc_002dcaxis">caxis</a>. 
+</p></blockquote></div>
+
+<!-- ./image/image_viewer.m -->
+   <p><a name="doc_002dimage_005fviewer"></a>
+
+<div class="defun">
+— Function File: [<var>fcn</var>, <var>default_zoom</var>] = <b>image_viewer</b> (<var>fcn, default_zoom</var>)<var><a name="index-image_005fviewer-2202"></a></var><br>
+<blockquote><p>Change the program or function used for viewing images and return the
+previous values.
+
+        <p>When the <code>image</code> or <code>imshow</code> function is called it will
+launch an external program to display the image.  The default behavior
+is to use gnuplot if the installed version supports image viewing,
+and otherwise try the programs <code>display</code>, <code>xv</code>, and
+<code>xloadimage</code>.  Using this function it is possible to change that
+behavior.
+
+        <p>When called with one input argument images will be displayed by saving
+the image to a file and the system command <var>command</var> will be called
+to view the image.  The <var>command</var> must be a string containing
+<code>%s</code> and possibly <code>%f</code>.  The <code>%s</code> will be replaced by
+the filename of the image, and the <code>%f</code> will (if present) be
+replaced by the zoom factor given to the <code>image</code> function. 
+For example,
+     <pre class="example">          image_viewer ("eog %s");
+</pre>
+        <p>changes the image viewer to the <code>eog</code> program.
+
+        <p>With two input arguments, images will be displayed by calling
+the function <var>function_handle</var>.  For example,
+     <pre class="example">          image_viewer (data, @my_image_viewer);
+</pre>
+        <p>sets the image viewer function to <code>my_image_viewer</code>.  The image
+viewer function is called with
+     <pre class="example">          my_image_viewer (<var>x</var>, <var>y</var>, <var>im</var>, <var>zoom</var>, <var>data</var>)
+</pre>
+        <p>where <var>x</var> and <var>y</var> are the axis of the image, <var>im</var> is the image
+variable, and <var>data</var> is extra user-supplied data to be passed to
+the viewer function.
+
+        <p>With three input arguments it is possible to change the zooming. 
+Some programs (like <code>xloadimage</code>) require the zoom factor to be
+between 0 and 100, and not 0 and 1 like Octave assumes.  This is
+solved by setting the third argument to 100.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimage.html#doc_002dimage">image</a>, <a href="doc_002dimshow.html#doc_002dimshow">imshow</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Distribution.html b/doc/interpreter/HTML/Distribution.html
new file mode 100644
index 0000000..3acd21d
--- /dev/null
+++ b/doc/interpreter/HTML/Distribution.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>Distribution - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Preface.html#Preface" title="Preface">
+<link rel="prev" href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave" title="How You Can Contribute to Octave">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Distribution"></a>
+Previous: <a rel="previous" accesskey="p" href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a>,
+Up: <a rel="up" accesskey="u" href="Preface.html#Preface">Preface</a>
+<hr>
+</div>
+
+<h3 class="unnumberedsec">Distribution</h3>
+
+<p><a name="index-distribution-of-Octave-6"></a>
+Octave is <dfn>free</dfn> software.  This means that everyone is free to
+use it and free to redistribute it on certain conditions.  Octave
+is not, however, in the public domain.  It is copyrighted and there are
+restrictions on its distribution, but the restrictions are designed to
+ensure that others will have the same freedom to use and redistribute
+Octave that you have.  The precise conditions can be found in the
+GNU General Public License that comes with Octave and that also appears
+in <a href="Copying.html#Copying">Copying</a>.
+
+   <p>Octave is available on CD-ROM, with various collections of other free
+software, from the Free Software Foundation.  Ordering a copy of
+Octave from the Free Software Foundation helps to fund the development
+of more free software.  For more information, write to
+
+   <blockquote>
+Free Software Foundation<br>
+51 Franklin Street, Fifth Floor<br>
+Boston, MA 02110-1301–1307<br>
+USA
+</blockquote>
+
+   <p>Octave can also be downloaded from <a href="http://www.octave.org">http://www.octave.org</a>, where
+additional information is available.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Distributions.html b/doc/interpreter/HTML/Distributions.html
new file mode 100644
index 0000000..3ac535c
--- /dev/null
+++ b/doc/interpreter/HTML/Distributions.html
@@ -0,0 +1,847 @@
+<html lang="en">
+<head>
+<title>Distributions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="prev" href="Models.html#Models" title="Models">
+<link rel="next" href="Random-Number-Generation.html#Random-Number-Generation" title="Random Number Generation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Distributions"></a>
+Next: <a rel="next" accesskey="n" href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a>,
+Previous: <a rel="previous" accesskey="p" href="Models.html#Models">Models</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.6 Distributions</h3>
+
+<p>Octave has functions for computing the Probability Density Function
+(PDF), the Cumulative Distribution function (CDF), and the quantile
+(the inverse of the CDF) of a large number of distributions.
+
+   <p>The following table summarizes the supported distributions (in
+alphabetical order).
+
+<!-- Do the table explicitly in TeX if possible to get a better layout. -->
+   <p><table summary=""><tr align="left"><td valign="top" width="31%"><strong>Distribution</strong>
+  </td><td valign="top" width="23%"><strong>PDF</strong>
+  </td><td valign="top" width="23%"><strong>CDF</strong>
+  </td><td valign="top" width="23%"><strong>Quantile</strong>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Beta Distribution
+  </td><td valign="top" width="23%"><code>betapdf</code>
+  </td><td valign="top" width="23%"><code>betacdf</code>
+  </td><td valign="top" width="23%"><code>betainv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Binomial Distribution
+  </td><td valign="top" width="23%"><code>binopdf</code>
+  </td><td valign="top" width="23%"><code>binocdf</code>
+  </td><td valign="top" width="23%"><code>binoinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Cauchy Distribution
+  </td><td valign="top" width="23%"><code>cauchy_pdf</code>
+  </td><td valign="top" width="23%"><code>cauchy_cdf</code>
+  </td><td valign="top" width="23%"><code>cauchy_inv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Chi-Square Distribution
+  </td><td valign="top" width="23%"><code>chi2pdf</code>
+  </td><td valign="top" width="23%"><code>chi2cdf</code>
+  </td><td valign="top" width="23%"><code>chi2inv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Univariate Discrete Distribution
+  </td><td valign="top" width="23%"><code>discrete_pdf</code>
+  </td><td valign="top" width="23%"><code>discrete_cdf</code>
+  </td><td valign="top" width="23%"><code>discrete_inv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Empirical Distribution
+  </td><td valign="top" width="23%"><code>empirical_pdf</code>
+  </td><td valign="top" width="23%"><code>empirical_cdf</code>
+  </td><td valign="top" width="23%"><code>empirical_inv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Exponential Distribution
+  </td><td valign="top" width="23%"><code>exppdf</code>
+  </td><td valign="top" width="23%"><code>expcdf</code>
+  </td><td valign="top" width="23%"><code>expinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">F Distribution
+  </td><td valign="top" width="23%"><code>fpdf</code>
+  </td><td valign="top" width="23%"><code>fcdf</code>
+  </td><td valign="top" width="23%"><code>finv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Gamma Distribution
+  </td><td valign="top" width="23%"><code>gampdf</code>
+  </td><td valign="top" width="23%"><code>gamcdf</code>
+  </td><td valign="top" width="23%"><code>gaminv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Geometric Distribution
+  </td><td valign="top" width="23%"><code>geopdf</code>
+  </td><td valign="top" width="23%"><code>geocdf</code>
+  </td><td valign="top" width="23%"><code>geoinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Hypergeometric Distribution
+  </td><td valign="top" width="23%"><code>hygepdf</code>
+  </td><td valign="top" width="23%"><code>hygecdf</code>
+  </td><td valign="top" width="23%"><code>hygeinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Kolmogorov Smirnov Distribution
+  </td><td valign="top" width="23%"><em>Not Available</em>
+  </td><td valign="top" width="23%"><code>kolmogorov_smirnov_cdf</code>
+  </td><td valign="top" width="23%"><em>Not Available</em>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Laplace Distribution
+  </td><td valign="top" width="23%"><code>laplace_pdf</code>
+  </td><td valign="top" width="23%"><code>laplace_cdf</code>
+  </td><td valign="top" width="23%"><code>laplace_inv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Logistic Distribution
+  </td><td valign="top" width="23%"><code>logistic_pdf</code>
+  </td><td valign="top" width="23%"><code>logistic_cdf</code>
+  </td><td valign="top" width="23%"><code>logistic_inv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Log-Normal Distribution
+  </td><td valign="top" width="23%"><code>lognpdf</code>
+  </td><td valign="top" width="23%"><code>logncdf</code>
+  </td><td valign="top" width="23%"><code>logninv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Pascal Distribution
+  </td><td valign="top" width="23%"><code>nbinpdf</code>
+  </td><td valign="top" width="23%"><code>nbincdf</code>
+  </td><td valign="top" width="23%"><code>nbininv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Univariate Normal Distribution
+  </td><td valign="top" width="23%"><code>normpdf</code>
+  </td><td valign="top" width="23%"><code>normcdf</code>
+  </td><td valign="top" width="23%"><code>norminv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Poisson Distribution
+  </td><td valign="top" width="23%"><code>poisspdf</code>
+  </td><td valign="top" width="23%"><code>poisscdf</code>
+  </td><td valign="top" width="23%"><code>poissinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">t (Student) Distribution
+  </td><td valign="top" width="23%"><code>tpdf</code>
+  </td><td valign="top" width="23%"><code>tcdf</code>
+  </td><td valign="top" width="23%"><code>tinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Univariate Discrete Distribution
+  </td><td valign="top" width="23%"><code>unidpdf</code>
+  </td><td valign="top" width="23%"><code>unidcdf</code>
+  </td><td valign="top" width="23%"><code>unidinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Uniform Distribution
+  </td><td valign="top" width="23%"><code>unifpdf</code>
+  </td><td valign="top" width="23%"><code>unifcdf</code>
+  </td><td valign="top" width="23%"><code>unifinv</code>
+<br></td></tr><tr align="left"><td valign="top" width="31%">Weibull Distribution
+  </td><td valign="top" width="23%"><code>wblpdf</code>
+  </td><td valign="top" width="23%"><code>wblcdf</code>
+  </td><td valign="top" width="23%"><code>wblinv</code>
+   <br></td></tr></table>
+
+<!-- ./statistics/distributions/betacdf.m -->
+   <p><a name="doc_002dbetacdf"></a>
+
+<div class="defun">
+— Function File:  <b>betacdf</b> (<var>x, a, b</var>)<var><a name="index-betacdf-1891"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, returns the CDF at <var>x</var> of the beta
+distribution with parameters <var>a</var> and <var>b</var>, i.e.,
+PROB (beta (<var>a</var>, <var>b</var>) <= <var>x</var>). 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/betainv.m -->
+   <p><a name="doc_002dbetainv"></a>
+
+<div class="defun">
+— Function File:  <b>betainv</b> (<var>x, a, b</var>)<var><a name="index-betainv-1892"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the Beta distribution with parameters <var>a</var>
+and <var>b</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/betapdf.m -->
+   <p><a name="doc_002dbetapdf"></a>
+
+<div class="defun">
+— Function File:  <b>betapdf</b> (<var>x, a, b</var>)<var><a name="index-betapdf-1893"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, returns the PDF at <var>x</var> of the beta
+distribution with parameters <var>a</var> and <var>b</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/binocdf.m -->
+   <p><a name="doc_002dbinocdf"></a>
+
+<div class="defun">
+— Function File:  <b>binocdf</b> (<var>x, n, p</var>)<var><a name="index-binocdf-1894"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the CDF at <var>x</var> of the
+binomial distribution with parameters <var>n</var> and <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/binoinv.m -->
+   <p><a name="doc_002dbinoinv"></a>
+
+<div class="defun">
+— Function File:  <b>binoinv</b> (<var>x, n, p</var>)<var><a name="index-binoinv-1895"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile at <var>x</var> of the
+binomial distribution with parameters <var>n</var> and <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/binopdf.m -->
+   <p><a name="doc_002dbinopdf"></a>
+
+<div class="defun">
+— Function File:  <b>binopdf</b> (<var>x, n, p</var>)<var><a name="index-binopdf-1896"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the binomial distribution with parameters <var>n</var>
+and <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/cauchy_cdf.m -->
+   <p><a name="doc_002dcauchy_005fcdf"></a>
+
+<div class="defun">
+— Function File:  <b>cauchy_cdf</b> (<var>x, lambda, sigma</var>)<var><a name="index-cauchy_005fcdf-1897"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the Cauchy distribution with location
+parameter <var>lambda</var> and scale parameter <var>sigma</var>.  Default
+values are <var>lambda</var> = 0, <var>sigma</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/cauchy_inv.m -->
+   <p><a name="doc_002dcauchy_005finv"></a>
+
+<div class="defun">
+— Function File:  <b>cauchy_inv</b> (<var>x, lambda, sigma</var>)<var><a name="index-cauchy_005finv-1898"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the Cauchy distribution with location parameter
+<var>lambda</var> and scale parameter <var>sigma</var>.  Default values are
+<var>lambda</var> = 0, <var>sigma</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/cauchy_pdf.m -->
+   <p><a name="doc_002dcauchy_005fpdf"></a>
+
+<div class="defun">
+— Function File:  <b>cauchy_pdf</b> (<var>x, lambda, sigma</var>)<var><a name="index-cauchy_005fpdf-1899"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the Cauchy distribution with location parameter
+<var>lambda</var> and scale parameter <var>sigma</var> > 0.  Default values are
+<var>lambda</var> = 0, <var>sigma</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/chi2cdf.m -->
+   <p><a name="doc_002dchi2cdf"></a>
+
+<div class="defun">
+— Function File:  <b>chi2cdf</b> (<var>x, n</var>)<var><a name="index-chi2cdf-1900"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the chisquare distribution with <var>n</var>
+degrees of freedom. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/chi2inv.m -->
+   <p><a name="doc_002dchi2inv"></a>
+
+<div class="defun">
+— Function File:  <b>chi2inv</b> (<var>x, n</var>)<var><a name="index-chi2inv-1901"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the chisquare distribution with <var>n</var> degrees of
+freedom. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/chi2pdf.m -->
+   <p><a name="doc_002dchi2pdf"></a>
+
+<div class="defun">
+— Function File:  <b>chisquare_pdf</b> (<var>x, n</var>)<var><a name="index-chisquare_005fpdf-1902"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the chisquare distribution with <var>n</var> degrees
+of freedom. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/discrete_cdf.m -->
+   <p><a name="doc_002ddiscrete_005fcdf"></a>
+
+<div class="defun">
+— Function File:  <b>discrete_cdf</b> (<var>x, v, p</var>)<var><a name="index-discrete_005fcdf-1903"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of a univariate discrete distribution which
+assumes the values in <var>v</var> with probabilities <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/discrete_inv.m -->
+   <p><a name="doc_002ddiscrete_005finv"></a>
+
+<div class="defun">
+— Function File:  <b>discrete_inv</b> (<var>x, v, p</var>)<var><a name="index-discrete_005finv-1904"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the univariate distribution which assumes the
+values in <var>v</var> with probabilities <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/discrete_pdf.m -->
+   <p><a name="doc_002ddiscrete_005fpdf"></a>
+
+<div class="defun">
+— Function File:  <b>discrete_pdf</b> (<var>x, v, p</var>)<var><a name="index-discrete_005fpdf-1905"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of a univariate discrete distribution which assumes
+the values in <var>v</var> with probabilities <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/empirical_cdf.m -->
+   <p><a name="doc_002dempirical_005fcdf"></a>
+
+<div class="defun">
+— Function File:  <b>empirical_cdf</b> (<var>x, data</var>)<var><a name="index-empirical_005fcdf-1906"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the empirical distribution obtained from
+the univariate sample <var>data</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/empirical_inv.m -->
+   <p><a name="doc_002dempirical_005finv"></a>
+
+<div class="defun">
+— Function File:  <b>empirical_inv</b> (<var>x, data</var>)<var><a name="index-empirical_005finv-1907"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the empirical distribution obtained from the
+univariate sample <var>data</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/empirical_pdf.m -->
+   <p><a name="doc_002dempirical_005fpdf"></a>
+
+<div class="defun">
+— Function File:  <b>empirical_pdf</b> (<var>x, data</var>)<var><a name="index-empirical_005fpdf-1908"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the empirical distribution obtained from the
+univariate sample <var>data</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/expcdf.m -->
+   <p><a name="doc_002dexpcdf"></a>
+
+<div class="defun">
+— Function File:  <b>expcdf</b> (<var>x, lambda</var>)<var><a name="index-expcdf-1909"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the exponential distribution with
+mean <var>lambda</var>.
+
+        <p>The arguments can be of common size or scalar. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/expinv.m -->
+   <p><a name="doc_002dexpinv"></a>
+
+<div class="defun">
+— Function File:  <b>expinv</b> (<var>x, lambda</var>)<var><a name="index-expinv-1910"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the exponential distribution with mean
+<var>lambda</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/exppdf.m -->
+   <p><a name="doc_002dexppdf"></a>
+
+<div class="defun">
+— Function File:  <b>exppdf</b> (<var>x, lambda</var>)<var><a name="index-exppdf-1911"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) of the exponential distribution with mean <var>lambda</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/fcdf.m -->
+   <p><a name="doc_002dfcdf"></a>
+
+<div class="defun">
+— Function File:  <b>fcdf</b> (<var>x, m, n</var>)<var><a name="index-fcdf-1912"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the CDF at <var>x</var> of the F
+distribution with <var>m</var> and <var>n</var> degrees of freedom, i.e.,
+PROB (F (<var>m</var>, <var>n</var>) <= <var>x</var>). 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/finv.m -->
+   <p><a name="doc_002dfinv"></a>
+
+<div class="defun">
+— Function File:  <b>finv</b> (<var>x, m, n</var>)<var><a name="index-finv-1913"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the F distribution with parameters <var>m</var> and
+<var>n</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/fpdf.m -->
+   <p><a name="doc_002dfpdf"></a>
+
+<div class="defun">
+— Function File:  <b>fpdf</b> (<var>x, m, n</var>)<var><a name="index-fpdf-1914"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the F distribution with <var>m</var> and <var>n</var>
+degrees of freedom. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/gamcdf.m -->
+   <p><a name="doc_002dgamcdf"></a>
+
+<div class="defun">
+— Function File:  <b>gamcdf</b> (<var>x, a, b</var>)<var><a name="index-gamcdf-1915"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the Gamma distribution with parameters
+<var>a</var> and <var>b</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>, <a href="doc_002dgammaln.html#doc_002dgammaln">gammaln</a>, <a href="doc_002dgammainc.html#doc_002dgammainc">gammainc</a>, <a href="doc_002dgampdf.html#doc_002dgampdf">gampdf</a>, <a href="doc_002dgaminv.html#doc_002dgaminv">gaminv</a>, <a href="doc_002dgamrnd.html#doc_002dgamrnd">gamrnd</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/gaminv.m -->
+   <p><a name="doc_002dgaminv"></a>
+
+<div class="defun">
+— Function File:  <b>gaminv</b> (<var>x, a, b</var>)<var><a name="index-gaminv-1916"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the Gamma distribution with parameters <var>a</var>
+and <var>b</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>, <a href="doc_002dgammaln.html#doc_002dgammaln">gammaln</a>, <a href="doc_002dgammainc.html#doc_002dgammainc">gammainc</a>, <a href="doc_002dgampdf.html#doc_002dgampdf">gampdf</a>, <a href="doc_002dgamcdf.html#doc_002dgamcdf">gamcdf</a>, <a href="doc_002dgamrnd.html#doc_002dgamrnd">gamrnd</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/gampdf.m -->
+   <p><a name="doc_002dgampdf"></a>
+
+<div class="defun">
+— Function File:  <b>gampdf</b> (<var>x, a, b</var>)<var><a name="index-gampdf-1917"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, return the probability density function
+(PDF) at <var>x</var> of the Gamma distribution with parameters <var>a</var>
+and <var>b</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>, <a href="doc_002dgammaln.html#doc_002dgammaln">gammaln</a>, <a href="doc_002dgammainc.html#doc_002dgammainc">gammainc</a>, <a href="doc_002dgamcdf.html#doc_002dgamcdf">gamcdf</a>, <a href="doc_002dgaminv.html#doc_002dgaminv">gaminv</a>, <a href="doc_002dgamrnd.html#doc_002dgamrnd">gamrnd</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/geocdf.m -->
+   <p><a name="doc_002dgeocdf"></a>
+
+<div class="defun">
+— Function File:  <b>geocdf</b> (<var>x, p</var>)<var><a name="index-geocdf-1918"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the CDF at <var>x</var> of the
+geometric distribution with parameter <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/geoinv.m -->
+   <p><a name="doc_002dgeoinv"></a>
+
+<div class="defun">
+— Function File:  <b>geoinv</b> (<var>x, p</var>)<var><a name="index-geoinv-1919"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile at <var>x</var> of the
+geometric distribution with parameter <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/geopdf.m -->
+   <p><a name="doc_002dgeopdf"></a>
+
+<div class="defun">
+— Function File:  <b>geopdf</b> (<var>x, p</var>)<var><a name="index-geopdf-1920"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the geometric distribution with parameter <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/hygecdf.m -->
+   <p><a name="doc_002dhygecdf"></a>
+
+<div class="defun">
+— Function File:  <b>hygecdf</b> (<var>x, t, m, n</var>)<var><a name="index-hygecdf-1921"></a></var><br>
+<blockquote><p>Compute the cumulative distribution function (CDF) at <var>x</var> of the
+hypergeometric distribution with parameters <var>t</var>, <var>m</var>, and
+<var>n</var>.  This is the probability of obtaining not more than <var>x</var>
+marked items when randomly drawing a sample of size <var>n</var> without
+replacement from a population of total size <var>t</var> containing
+<var>m</var> marked items.
+
+        <p>The parameters <var>t</var>, <var>m</var>, and <var>n</var> must positive integers
+with <var>m</var> and <var>n</var> not greater than <var>t</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/hygeinv.m -->
+   <p><a name="doc_002dhygeinv"></a>
+
+<div class="defun">
+— Function File:  <b>hygeinv</b> (<var>x, t, m, n</var>)<var><a name="index-hygeinv-1922"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile at <var>x</var> of the
+hypergeometric distribution with parameters <var>t</var>, <var>m</var>, and
+<var>n</var>.
+
+        <p>The parameters <var>t</var>, <var>m</var>, and <var>n</var> must positive integers
+with <var>m</var> and <var>n</var> not greater than <var>t</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/hygepdf.m -->
+   <p><a name="doc_002dhygepdf"></a>
+
+<div class="defun">
+— Function File:  <b>hygepdf</b> (<var>x, t, m, n</var>)<var><a name="index-hygepdf-1923"></a></var><br>
+<blockquote><p>Compute the probability density function (PDF) at <var>x</var> of the
+hypergeometric distribution with parameters <var>t</var>, <var>m</var>, and
+<var>n</var>.  This is the probability of obtaining <var>x</var> marked items
+when randomly drawing a sample of size <var>n</var> without replacement
+from a population of total size <var>t</var> containing <var>m</var> marked items.
+
+        <p>The arguments must be of common size or scalar. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/kolmogorov_smirnov_cdf.m -->
+   <p><a name="doc_002dkolmogorov_005fsmirnov_005fcdf"></a>
+
+<div class="defun">
+— Function File:  <b>kolmogorov_smirnov_cdf</b> (<var>x, tol</var>)<var><a name="index-kolmogorov_005fsmirnov_005fcdf-1924"></a></var><br>
+<blockquote><p>Return the CDF at <var>x</var> of the Kolmogorov-Smirnov distribution,
+     <pre class="example">                   Inf
+          Q(x) =   SUM    (-1)^k exp(-2 k^2 x^2)
+                 k = -Inf
+</pre>
+        <p class="noindent">for <var>x</var> > 0.
+
+        <p>The optional parameter <var>tol</var> specifies the precision up to which
+the series should be evaluated;  the default is <var>tol</var> = <code>eps</code>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/laplace_cdf.m -->
+   <p><a name="doc_002dlaplace_005fcdf"></a>
+
+<div class="defun">
+— Function File:  <b>laplace_cdf</b> (<var>x</var>)<var><a name="index-laplace_005fcdf-1925"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the Laplace distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/laplace_inv.m -->
+   <p><a name="doc_002dlaplace_005finv"></a>
+
+<div class="defun">
+— Function File:  <b>laplace_inv</b> (<var>x</var>)<var><a name="index-laplace_005finv-1926"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the Laplace distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/laplace_pdf.m -->
+   <p><a name="doc_002dlaplace_005fpdf"></a>
+
+<div class="defun">
+— Function File:  <b>laplace_pdf</b> (<var>x</var>)<var><a name="index-laplace_005fpdf-1927"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the Laplace distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/logistic_cdf.m -->
+   <p><a name="doc_002dlogistic_005fcdf"></a>
+
+<div class="defun">
+— Function File:  <b>logistic_cdf</b> (<var>x</var>)<var><a name="index-logistic_005fcdf-1928"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the CDF at <var>x</var> of the
+logistic distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/logistic_inv.m -->
+   <p><a name="doc_002dlogistic_005finv"></a>
+
+<div class="defun">
+— Function File:  <b>logistic_inv</b> (<var>x</var>)<var><a name="index-logistic_005finv-1929"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the logistic distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/logistic_pdf.m -->
+   <p><a name="doc_002dlogistic_005fpdf"></a>
+
+<div class="defun">
+— Function File:  <b>logistic_pdf</b> (<var>x</var>)<var><a name="index-logistic_005fpdf-1930"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the PDF at <var>x</var> of the
+logistic distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/logncdf.m -->
+   <p><a name="doc_002dlogncdf"></a>
+
+<div class="defun">
+— Function File:  <b>logncdf</b> (<var>x, mu, sigma</var>)<var><a name="index-logncdf-1931"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the lognormal distribution with
+parameters <var>mu</var> and <var>sigma</var>.  If a random variable follows this
+distribution, its logarithm is normally distributed with mean
+<var>mu</var> and standard deviation <var>sigma</var>.
+
+        <p>Default values are <var>mu</var> = 1, <var>sigma</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/logninv.m -->
+   <p><a name="doc_002dlogninv"></a>
+
+<div class="defun">
+— Function File:  <b>logninv</b> (<var>x, mu, sigma</var>)<var><a name="index-logninv-1932"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the lognormal distribution with parameters <var>mu</var>
+and <var>sigma</var>.  If a random variable follows this distribution, its
+logarithm is normally distributed with mean <code>log (</code><var>mu</var><code>)</code> and
+variance <var>sigma</var>.
+
+        <p>Default values are <var>mu</var> = 1, <var>sigma</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/lognpdf.m -->
+   <p><a name="doc_002dlognpdf"></a>
+
+<div class="defun">
+— Function File:  <b>lognpdf</b> (<var>x, mu, sigma</var>)<var><a name="index-lognpdf-1933"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the lognormal distribution with parameters
+<var>mu</var> and <var>sigma</var>.  If a random variable follows this distribution,
+its logarithm is normally distributed with mean <var>mu</var>
+and standard deviation <var>sigma</var>.
+
+        <p>Default values are <var>mu</var> = 1, <var>sigma</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/nbincdf.m -->
+   <p><a name="doc_002dnbincdf"></a>
+
+<div class="defun">
+— Function File:  <b>nbincdf</b> (<var>x, n, p</var>)<var><a name="index-nbincdf-1934"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the CDF at x of the Pascal
+(negative binomial) distribution with parameters <var>n</var> and <var>p</var>.
+
+        <p>The number of failures in a Bernoulli experiment with success
+probability <var>p</var> before the <var>n</var>-th success follows this
+distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/nbininv.m -->
+   <p><a name="doc_002dnbininv"></a>
+
+<div class="defun">
+— Function File:  <b>nbininv</b> (<var>x, n, p</var>)<var><a name="index-nbininv-1935"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile at <var>x</var> of the
+Pascal (negative binomial) distribution with parameters <var>n</var> and
+<var>p</var>.
+
+        <p>The number of failures in a Bernoulli experiment with success
+probability <var>p</var> before the <var>n</var>-th success follows this
+distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/nbinpdf.m -->
+   <p><a name="doc_002dnbinpdf"></a>
+
+<div class="defun">
+— Function File:  <b>nbinpdf</b> (<var>x, n, p</var>)<var><a name="index-nbinpdf-1936"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the Pascal (negative binomial) distribution with
+parameters <var>n</var> and <var>p</var>.
+
+        <p>The number of failures in a Bernoulli experiment with success
+probability <var>p</var> before the <var>n</var>-th success follows this
+distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/normcdf.m -->
+   <p><a name="doc_002dnormcdf"></a>
+
+<div class="defun">
+— Function File:  <b>normcdf</b> (<var>x, m, s</var>)<var><a name="index-normcdf-1937"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the normal distribution with mean
+<var>m</var> and standard deviation <var>s</var>.
+
+        <p>Default values are <var>m</var> = 0, <var>s</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/norminv.m -->
+   <p><a name="doc_002dnorminv"></a>
+
+<div class="defun">
+— Function File:  <b>norminv</b> (<var>x, m, s</var>)<var><a name="index-norminv-1938"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the normal distribution with mean <var>m</var> and
+standard deviation <var>s</var>.
+
+        <p>Default values are <var>m</var> = 0, <var>s</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/normpdf.m -->
+   <p><a name="doc_002dnormpdf"></a>
+
+<div class="defun">
+— Function File:  <b>normpdf</b> (<var>x, m, s</var>)<var><a name="index-normpdf-1939"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the normal distribution with mean <var>m</var> and
+standard deviation <var>s</var>.
+
+        <p>Default values are <var>m</var> = 0, <var>s</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/poisscdf.m -->
+   <p><a name="doc_002dpoisscdf"></a>
+
+<div class="defun">
+— Function File:  <b>poisscdf</b> (<var>x, lambda</var>)<var><a name="index-poisscdf-1940"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the Poisson distribution with parameter
+lambda. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/poissinv.m -->
+   <p><a name="doc_002dpoissinv"></a>
+
+<div class="defun">
+— Function File:  <b>poissinv</b> (<var>x, lambda</var>)<var><a name="index-poissinv-1941"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the Poisson distribution with parameter
+<var>lambda</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/poisspdf.m -->
+   <p><a name="doc_002dpoisspdf"></a>
+
+<div class="defun">
+— Function File:  <b>poisspdf</b> (<var>x, lambda</var>)<var><a name="index-poisspdf-1942"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the poisson distribution with parameter <var>lambda</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/tcdf.m -->
+   <p><a name="doc_002dtcdf"></a>
+
+<div class="defun">
+— Function File:  <b>tcdf</b> (<var>x, n</var>)<var><a name="index-tcdf-1943"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of the t (Student) distribution with
+<var>n</var> degrees of freedom, i.e., PROB (t(<var>n</var>) <= <var>x</var>). 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/tinv.m -->
+   <p><a name="doc_002dtinv"></a>
+
+<div class="defun">
+— Function File:  <b>tinv</b> (<var>x, n</var>)<var><a name="index-tinv-1944"></a></var><br>
+<blockquote><p>For each probability value <var>x</var>, compute the inverse of the
+cumulative distribution function (CDF) of the t (Student)
+distribution with degrees of freedom <var>n</var>.  This function is
+analogous to looking in a table for the t-value of a single-tailed
+distribution. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/tpdf.m -->
+   <p><a name="doc_002dtpdf"></a>
+
+<div class="defun">
+— Function File:  <b>tpdf</b> (<var>x, n</var>)<var><a name="index-tpdf-1945"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of the <var>t</var> (Student) distribution with <var>n</var>
+degrees of freedom. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unidcdf.m -->
+   <p><a name="doc_002dunidcdf"></a>
+
+<div class="defun">
+— Function File:  <b>unidcdf</b> (<var>x, v</var>)<var><a name="index-unidcdf-1946"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the cumulative distribution
+function (CDF) at <var>x</var> of a univariate discrete distribution which
+assumes the values in <var>v</var> with equal probability. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unidinv.m -->
+   <p><a name="doc_002dunidinv"></a>
+
+<div class="defun">
+— Function File:  <b>unidinv</b> (<var>x, v</var>)<var><a name="index-unidinv-1947"></a></var><br>
+<blockquote><p>For each component of <var>x</var>, compute the quantile (the inverse of
+the CDF) at <var>x</var> of the univariate discrete distribution which assumes the
+values in <var>v</var> with equal probability
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unidpdf.m -->
+   <p><a name="doc_002dunidpdf"></a>
+
+<div class="defun">
+— Function File:  <b>unidpdf</b> (<var>x, v</var>)<var><a name="index-unidpdf-1948"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the probability density function
+(PDF) at <var>x</var> of a univariate discrete distribution which assumes
+the values in <var>v</var> with equal probability. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unifcdf.m -->
+   <p><a name="doc_002dunifcdf"></a>
+
+<div class="defun">
+— Function File:  <b>unifcdf</b> (<var>x, a, b</var>)<var><a name="index-unifcdf-1949"></a></var><br>
+<blockquote><p>Return the CDF at <var>x</var> of the uniform distribution on [<var>a</var>,
+<var>b</var>], i.e., PROB (uniform (<var>a</var>, <var>b</var>) <= x).
+
+        <p>Default values are <var>a</var> = 0, <var>b</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unifinv.m -->
+   <p><a name="doc_002dunifinv"></a>
+
+<div class="defun">
+— Function File:  <b>unifinv</b> (<var>x, a, b</var>)<var><a name="index-unifinv-1950"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the quantile (the inverse of the
+CDF) at <var>x</var> of the uniform distribution on [<var>a</var>, <var>b</var>].
+
+        <p>Default values are <var>a</var> = 0, <var>b</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unifpdf.m -->
+   <p><a name="doc_002dunifpdf"></a>
+
+<div class="defun">
+— Function File:  <b>unifpdf</b> (<var>x, a, b</var>)<var><a name="index-unifpdf-1951"></a></var><br>
+<blockquote><p>For each element of <var>x</var>, compute the PDF at <var>x</var> of the uniform
+distribution on [<var>a</var>, <var>b</var>].
+
+        <p>Default values are <var>a</var> = 0, <var>b</var> = 1. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/wblcdf.m -->
+   <p><a name="doc_002dwblcdf"></a>
+
+<div class="defun">
+— Function File:  <b>wblcdf</b> (<var>x, scale, shape</var>)<var><a name="index-wblcdf-1952"></a></var><br>
+<blockquote><p>Compute the cumulative distribution function (CDF) at <var>x</var> of the
+Weibull distribution with shape parameter <var>scale</var> and scale
+parameter <var>shape</var>, which is
+
+     <pre class="example">          1 - exp(-(x/shape)^scale)
+</pre>
+        <p>for <var>x</var> >= 0. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/wblinv.m -->
+   <p><a name="doc_002dwblinv"></a>
+
+<div class="defun">
+— Function File:  <b>wblinv</b> (<var>x, scale, shape</var>)<var><a name="index-wblinv-1953"></a></var><br>
+<blockquote><p>Compute the quantile (the inverse of the CDF) at <var>x</var> of the
+Weibull distribution with shape parameter <var>scale</var> and scale
+parameter <var>shape</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/wblpdf.m -->
+   <p><a name="doc_002dwblpdf"></a>
+
+<div class="defun">
+— Function File:  <b>wblpdf</b> (<var>x, scale, shape</var>)<var><a name="index-wblpdf-1954"></a></var><br>
+<blockquote><p>Compute the probability density function (PDF) at <var>x</var> of the
+Weibull distribution with shape parameter <var>scale</var> and scale
+parameter <var>shape</var> which is given by
+
+     <pre class="example">             scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+</pre>
+        <p class="noindent">for <var>x</var> > 0. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Documentation-Tips.html b/doc/interpreter/HTML/Documentation-Tips.html
new file mode 100644
index 0000000..1205d9b
--- /dev/null
+++ b/doc/interpreter/HTML/Documentation-Tips.html
@@ -0,0 +1,271 @@
+<html lang="en">
+<head>
+<title>Documentation Tips - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link rel="prev" href="Function-Headers.html#Function-Headers" title="Function Headers">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Documentation-Tips"></a>
+Previous: <a rel="previous" accesskey="p" href="Function-Headers.html#Function-Headers">Function Headers</a>,
+Up: <a rel="up" accesskey="u" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
+<hr>
+</div>
+
+<h3 class="section">C.5 Tips for Documentation Strings</h3>
+
+<p>As noted above, documentation is typically in a commented header block
+on an Octave function following the copyright statement.  The help string
+shown above is an unformatted string and will be displayed as is by
+Octave.  Here are some tips for the writing of documentation strings.
+
+     <ul>
+<li>Every command, function, or variable intended for users to know about
+should have a documentation string.
+
+     <li>An internal variable or subroutine of an Octave program might as well have
+a documentation string.
+
+     <li>The first line of the documentation string should consist of one or two
+complete sentences that stand on their own as a summary.
+
+     <p>The documentation string can have additional lines that expand on the
+details of how to use the function or variable.  The additional lines
+should also be made up of complete sentences.
+
+     <li>For consistency, phrase the verb in the first sentence of a
+documentation string as an infinitive with “to” omitted.  For
+instance, use “Return the frob of A and B.” in preference to “Returns
+the frob of A and B.”  Usually it looks good to do likewise for the
+rest of the first paragraph.  Subsequent paragraphs usually look better
+if they have proper subjects.
+
+     <li>Write documentation strings in the active voice, not the passive, and in
+the present tense, not the future.  For instance, use “Return a list
+containing A and B.” instead of “A list containing A and B will be
+returned.”
+
+     <li>Avoid using the word “cause” (or its equivalents) unnecessarily. 
+Instead of, “Cause Octave to display text in boldface,” write just
+“Display text in boldface.”
+
+     <li>Do not start or end a documentation string with whitespace.
+
+     <li>Format the documentation string so that it fits in an Emacs window on an
+80-column screen.  It is a good idea for most lines to be no wider than
+60 characters.
+
+     <p>However, rather than simply filling the entire documentation string, you
+can make it much more readable by choosing line breaks with care. 
+Use blank lines between topics if the documentation string is long.
+
+     <li><strong>Do not</strong> indent subsequent lines of a documentation string so
+that the text is lined up in the source code with the text of the first
+line.  This looks nice in the source code, but looks bizarre when users
+view the documentation.  Remember that the indentation before the
+starting double-quote is not part of the string!
+
+     <li>The documentation string for a variable that is a yes-or-no flag should
+start with words such as “Nonzero means<small class="dots">...</small>”, to make it clear that
+all nonzero values are equivalent and indicate explicitly what zero and
+nonzero mean.
+
+     <li>When a function's documentation string mentions the value of an argument
+of the function, use the argument name in capital letters as if it were
+a name for that value.  Thus, the documentation string of the operator
+<code>/</code> refers to its second argument as ‘<samp><span class="samp">DIVISOR</span></samp>’, because the
+actual argument name is <code>divisor</code>.
+
+     <p>Also use all caps for meta-syntactic variables, such as when you show
+the decomposition of a list or vector into subunits, some of which may
+vary. 
+</ul>
+
+   <p>Octave also allows extensive formatting of the help string of functions
+using Texinfo.  The effect on the online documentation is relatively
+small, but makes the help string of functions conform to the help of
+Octave's own functions.  However, the effect on the appearance of printed
+or online documentation will be greatly improved.
+
+   <p>The fundamental building block of Texinfo documentation strings is the
+Texinfo-macro <code>@deftypefn</code>, which takes three arguments: The class
+the function is in, its output arguments, and the function's
+signature.  Typical classes for functions include <code>Function File</code>
+for standard Octave functions, and <code>Loadable Function</code> for
+dynamically linked functions.  A skeletal Texinfo documentation string
+therefore looks like this
+
+<pre class="example">     -*- texinfo -*-
+     @deftypefn{Function File} {@var{ret} =} fn (...)
+     @cindex index term
+     Help text in Texinfo format.  Code samples should be marked
+     like @code{sample of code} and variables should be marked
+     as @var{variable}.
+     @seealso{fn2}
+     @end deftypefn
+</pre>
+   <p>This help string must be commented in user functions, or in the help
+string of the <code>DEFUN_DLD</code><!-- /@w --> macro for dynamically loadable
+functions.  The important aspects of the documentation string are
+
+     <dl>
+<dt>-*- texinfo -*-<dd>This string signals Octave that the following text is in Texinfo format,
+and should be the first part of any help string in Texinfo format. 
+<br><dt>@deftypefn{class} <small class="dots">...</small> @end deftypefn<dd>The entire help string should be enclosed within the block defined by
+deftypefn. 
+<br><dt>@cindex index term<dd>This generates an index entry, and can be useful when the function is
+included as part of a larger piece of documentation.  It is ignored
+within Octave's help viewer.  Only one index term may appear per line
+but multiple @cindex lines are valid if the function should be
+filed under different terms. 
+<br><dt>@var{variable}<dd>All variables should be marked with this macro.  The markup of variables
+is then changed appropriately for display. 
+<br><dt>@code{sample of code}<dd>All samples of code should be marked with this macro for the same
+reasons as the @var macro. 
+<br><dt>@seealso{function2}<dd>This is a comma separated list of function names that allows cross
+referencing from one function documentation string to another. 
+</dl>
+
+   <p>Texinfo format has been designed to generate output for online viewing
+with text terminals as well as generating high-quality printed output. 
+To these ends, Texinfo has commands which control the diversion of parts
+of the document into a particular output processor.  Three formats are
+of importance: info, html and TeX.  These are selected with
+
+<pre class="example">     @ifinfo
+     Text area for info only
+     @end ifinfo
+</pre>
+   <pre class="example">     @ifhtml
+     Text area for HTML only
+     @end ifhtml
+</pre>
+   <pre class="example">     @tex
+     Text area for TeX only
+     @end tex
+</pre>
+   <p>Note that often TeX output can be used in html documents and so often
+the <code>@ifhtml</code> blocks are unnecessary.  If no specific output
+processor is chosen, by default, the text goes into all output
+processors.  It is usual to have the above blocks in pairs to allow the
+same information to be conveyed in all output formats, but with a
+different markup.  Currently, most Octave documentation only makes a
+distinction between TeX and all other formats.  Therefore, the
+following construct is seen repeatedly.
+
+<pre class="example">     @tex
+     text for TeX only
+     @end tex
+     @ifnottex
+     text for info, HTML, plaintext
+     @end ifnottex
+</pre>
+   <p>Another important feature of Texinfo that is often used in Octave help
+strings is the <code>@example</code> environment.  An example of its use is
+
+<pre class="example">     @example
+     @group
+     @code{2 * 2}
+     @result{} 4
+     @end group
+     @end example
+</pre>
+   <p>which produces
+
+<pre class="example">     <code>2 * 2</code>
+      4
+</pre>
+   <p>The <code>@group</code> block prevents the example from being split across a
+page boundary, while the <code>@result{}</code> macro produces a right
+arrow signifying the result of a command.  If your example is larger than
+20 lines it is better NOT to use grouping so that a reasonable page boundary
+can be calculated.
+
+   <p>In many cases a function has multiple ways in which it can be called,
+and the <code>@deftypefnx</code> macro can be used to give alternatives.  For
+example
+
+<pre class="example">     -*- texinfo -*-
+     @deftypefn{Function File} {@var{a} =} fn (@var{x}, ...)
+     @deftypefnx{Function File} {@var{a} =} fn (@var{y}, ...)
+     Help text in Texinfo format.
+     @end deftypefn
+</pre>
+   <p>Many complete examples of Texinfo documentation can be taken from the
+help strings for the Octave functions themselves.  A relatively complete
+example of which is the <code>nchoosek</code> function.  The Texinfo
+documentation string for <code>nchoosek</code> is
+
+<pre class="example">     -*- texinfo -*-
+     @deftypefn {Function File} {} nchoosek (@var{n}, @var{k})
+     
+     Compute the binomial coefficient or all combinations of
+     @var{n}.  If @var{n} is a scalar then, calculate the
+     binomial coefficient of @var{n} and @var{k}, defined as
+     
+     @tex
+     $$
+      {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+     $$
+     @end tex
+     @ifnottex
+     
+     @example
+     @group
+      /   \
+      | n |    n (n-1) (n-2) ... (n-k+1)
+      |   |  = -------------------------
+      | k |               k!
+      \   /
+     @end group
+     @end example
+     @end ifnottex
+     
+     If @var{n} is a vector, this generates all combinations
+     of the elements of @var{n}, taken @var{k} at a time,
+     one row per combination.  The resulting @var{c} has size
+     @code{[nchoosek (length (@var{n}), at var{k}), @var{k}]}.
+     
+     @code{nchoosek} works only for non-negative integer arguments; use
+     @code{bincoeff} for non-integer scalar arguments and for using vector
+     arguments to compute many coefficients at once.
+     
+     @seealso{bincoeff}
+     @end deftypefn
+</pre>
+   <p>which demonstrates most of the concepts discussed above.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2008, 2009 Jaroslav Hajek -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Documentation-and-Test-of-Oct_002dFiles.html b/doc/interpreter/HTML/Documentation-and-Test-of-Oct_002dFiles.html
new file mode 100644
index 0000000..8c85d2c
--- /dev/null
+++ b/doc/interpreter/HTML/Documentation-and-Test-of-Oct_002dFiles.html
@@ -0,0 +1,87 @@
+<html lang="en">
+<head>
+<title>Documentation and Test of Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles" title="Exception and Error Handling in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Documentation-and-Test-of-Oct-Files"></a>
+<a name="Documentation-and-Test-of-Oct_002dFiles"></a>
+Previous: <a rel="previous" accesskey="p" href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles">Exception and Error Handling in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.13 Documentation and Test of Oct-Files</h4>
+
+<p>The documentation of an oct-file is the fourth string parameter of the
+<code>DEFUN_DLD</code><!-- /@w --> macro.  This string can be formatted in the same manner
+as the help strings for user functions (<a href="Documentation-Tips.html#Documentation-Tips">Documentation Tips</a>),
+however there are some issue that are particular to the formatting of
+help strings within oct-files.
+
+   <p>The major issue is that the help string will typically be longer than a
+single line of text, and so the formatting of long help strings need to
+be taken into account.  There are several manners in which to treat this
+issue, but the most common is illustrated in the following example
+
+<pre class="example">     DEFUN_DLD (do_what_i_want, args, nargout,
+       "-*- texinfo -*-\n\
+     @deftypefn {Function File} {} do_what_i_say (@var{n})\n\
+     A function that does what the user actually wants rather\n\
+     than what they requested.\n\
+     @end deftypefn")
+     {
+     ...
+     }
+</pre>
+   <p class="noindent">where, as can be seen, end line of text within the help string is
+terminated by <code>\n\</code> which is an embedded new-line in the string
+together with a C++ string continuation character.  Note that the final
+<code>\</code> must be the last character on the line.
+
+   <p>Octave also includes the ability to embed the test and demonstration
+code for a function within the code itself (<a href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a>). 
+This can be used from within oct-files (or in fact any file) with
+certain provisos.  Firstly, the test and demo functions of Octave look
+for a <code>%!</code> as the first characters on a new-line to identify test
+and demonstration code.  This is equally a requirement for
+oct-files.  Furthermore the test and demonstration code must be included
+in a comment block of the compiled code to avoid it being interpreted by
+the compiler.  Finally, the Octave test and demonstration code must have
+access to the source code of the oct-file and not just the compiled code
+as the tests are stripped from the compiled code.  An example in an
+oct-file might be
+
+<pre class="example">     /*
+     
+     %!error (sin())
+     %!error (sin(1,1))
+     %!assert (sin([1,2]),[sin(1),sin(2)])
+     
+     */
+</pre>
+   <!-- @node Application Programming Interface for Oct-Files -->
+<!-- @subsection Application Programming Interface for Oct-Files -->
+<!-- WRITE ME, using Coda section 1.3 as a starting point. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Dynamically-Linked-Functions.html b/doc/interpreter/HTML/Dynamically-Linked-Functions.html
new file mode 100644
index 0000000..53d637e
--- /dev/null
+++ b/doc/interpreter/HTML/Dynamically-Linked-Functions.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Dynamically Linked Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Packages.html#Packages" title="Packages">
+<link rel="next" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions" title="Test and Demo Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Dynamically-Linked-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Packages.html#Packages">Packages</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix A Dynamically Linked Functions</h2>
+
+<p><a name="index-dynamic_002dlinking-2468"></a>
+Octave has the possibility of including compiled code as dynamically
+linked extensions and then using these extensions as if they were part
+of Octave itself.  Octave can call C++ code
+through its native oct-file interface or C code through its mex
+interface.  It can also indirectly call functions written in any other
+language through a simple wrapper.  The reasons to write code in a
+compiled language might be either to link to an existing piece of code
+and allow it to be used within Octave, or to allow improved performance
+for key pieces of code.
+
+   <p>Before going further, you should first determine if you really need to
+use dynamically linked functions at all.  Before proceeding with writing
+any dynamically linked function to improve performance you should
+address ask yourself
+
+     <ul>
+<li>Can I get the same functionality using the Octave scripting language only? 
+<li>Is it thoroughly optimized Octave code?  Vectorization of Octave code,
+doesn't just make it concise, it generally significantly improves its
+performance.  Above all, if loops must be used, make sure that the
+allocation of space for variables takes place outside the loops using an
+assignment to a matrix of the right size, or zeros. 
+<li>Does it make as much use as possible of existing built-in library
+routines?  These are highly optimized and many do not carry the overhead
+of being interpreted. 
+<li>Does writing a dynamically linked function represent useful investment
+of your time, relative to staying in Octave? 
+</ul>
+
+   <p>Also, as oct- and mex-files are dynamically linked to Octave, they
+introduce the possibility of Octave crashing due to errors in
+the user code.  For example a segmentation violation in the user's code
+will cause Octave to abort.
+
+<ul class="menu">
+<li><a accesskey="1" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<li><a accesskey="2" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<li><a accesskey="3" href="Standalone-Programs.html#Standalone-Programs">Standalone Programs</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/EOF-and-Errors.html b/doc/interpreter/HTML/EOF-and-Errors.html
new file mode 100644
index 0000000..d19e5cb
--- /dev/null
+++ b/doc/interpreter/HTML/EOF-and-Errors.html
@@ -0,0 +1,110 @@
+<html lang="en">
+<head>
+<title>EOF and Errors - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Temporary-Files.html#Temporary-Files" title="Temporary Files">
+<link rel="next" href="File-Positioning.html#File-Positioning" title="File Positioning">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="EOF-and-Errors"></a>
+Next: <a rel="next" accesskey="n" href="File-Positioning.html#File-Positioning">File Positioning</a>,
+Previous: <a rel="previous" accesskey="p" href="Temporary-Files.html#Temporary-Files">Temporary Files</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.18 End of File and Errors</h4>
+
+<p>Once a file has been opened its status can be acquired.  As an example
+the <code>feof</code> functions determines if the end of the file has been
+reached.  This can be very useful when reading small parts of a file
+at a time.  The following example shows how to read one line at a time
+from a file until the end has been reached.
+
+<pre class="example">     filename = "myfile.txt";
+     fid = fopen (filename, "r");
+     while (! feof (fid) )
+       text_line = fgetl (fid);
+     endwhile
+     fclose (fid);
+</pre>
+   <p class="noindent">Note that in some situations it is more efficient to read the entire
+contents of a file and then process it, than it is to read it line by
+line.  This has the potential advantage of removing the loop in the
+above code.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfeof"></a>
+
+<div class="defun">
+— Built-in Function:  <b>feof</b> (<var>fid</var>)<var><a name="index-feof-805"></a></var><br>
+<blockquote><p>Return 1 if an end-of-file condition has been encountered for a given
+file and 0 otherwise.  Note that it will only return 1 if the end of the
+file has already been encountered, not if the next read operation will
+result in an end-of-file condition. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dferror"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ferror</b> (<var>fid</var>)<var><a name="index-ferror-806"></a></var><br>
+<blockquote><p>Return 1 if an error condition has been encountered for a given file
+and 0 otherwise.  Note that it will only return 1 if an error has
+already been encountered, not if the next operation will result in an
+error condition. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfclear"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fclear</b> (<var>fid</var>)<var><a name="index-fclear-807"></a></var><br>
+<blockquote><p>Clear the stream state for the specified file. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfreport"></a>
+
+<div class="defun">
+— Built-in Function:  <b>freport</b> ()<var><a name="index-freport-808"></a></var><br>
+<blockquote><p>Print a list of which files have been opened, and whether they are open
+for reading, writing, or both.  For example,
+
+     <pre class="example">          freport ()
+          
+               -|  number  mode  name
+               -|
+               -|       0     r  stdin
+               -|       1     w  stdout
+               -|       2     w  stderr
+               -|       3     r  myfile
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Element_002dby_002delement-Boolean-Operators.html b/doc/interpreter/HTML/Element_002dby_002delement-Boolean-Operators.html
new file mode 100644
index 0000000..0807c95
--- /dev/null
+++ b/doc/interpreter/HTML/Element_002dby_002delement-Boolean-Operators.html
@@ -0,0 +1,95 @@
+<html lang="en">
+<head>
+<title>Element-by-element Boolean Operators - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Boolean-Expressions.html#Boolean-Expressions" title="Boolean Expressions">
+<link rel="next" href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators" title="Short-circuit Boolean Operators">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Element-by-element-Boolean-Operators"></a>
+<a name="Element_002dby_002delement-Boolean-Operators"></a>
+Next: <a rel="next" accesskey="n" href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">Short-circuit Boolean Operators</a>,
+Up: <a rel="up" accesskey="u" href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a>
+<hr>
+</div>
+
+<h4 class="subsection">8.5.1 Element-by-element Boolean Operators</h4>
+
+<p><a name="index-element_002dby_002delement-evaluation-518"></a>
+An <dfn>element-by-element boolean expression</dfn> is a combination of
+comparison expressions using the boolean
+operators “or” (‘<samp><span class="samp">|</span></samp>’), “and” (‘<samp><span class="samp">&</span></samp>’), and “not” (‘<samp><span class="samp">!</span></samp>’),
+along with parentheses to control nesting.  The truth of the boolean
+expression is computed by combining the truth values of the
+corresponding elements of the component expressions.  A value is
+considered to be false if it is zero, and true otherwise.
+
+   <p>Element-by-element boolean expressions can be used wherever comparison
+expressions can be used.  They can be used in <code>if</code> and <code>while</code>
+statements.  However, a matrix value used as the condition in an
+<code>if</code> or <code>while</code> statement is only true if <em>all</em> of its
+elements are nonzero.
+
+   <p>Like comparison operations, each element of an element-by-element
+boolean expression also has a numeric value (1 if true, 0 if false) that
+comes into play if the result of the boolean expression is stored in a
+variable, or used in arithmetic.
+
+   <p>Here are descriptions of the three element-by-element boolean operators.
+
+     <dl>
+<dt><var>boolean1</var><code> & </code><var>boolean2</var><dd><a name="index-g_t_0026-519"></a>Elements of the result are true if both corresponding elements of
+<var>boolean1</var> and <var>boolean2</var> are true.
+
+     <br><dt><var>boolean1</var><code> | </code><var>boolean2</var><dd><a name="index-g_t_007c-520"></a>Elements of the result are true if either of the corresponding elements
+of <var>boolean1</var> or <var>boolean2</var> is true.
+
+     <br><dt><code>! </code><var>boolean</var><dt><code>~ </code><var>boolean</var><dd><a name="index-g_t_007e-521"></a><a name="index-g_t_0021-522"></a>Each element of the result is true if the corresponding element of
+<var>boolean</var> is false. 
+</dl>
+
+   <p>For matrix operands, these operators work on an element-by-element
+basis.  For example, the expression
+
+<pre class="example">     [1, 0; 0, 1] & [1, 0; 2, 3]
+</pre>
+   <p class="noindent">returns a two by two identity matrix.
+
+   <p>For the binary operators, the dimensions of the operands must conform if
+both are matrices.  If one of the operands is a scalar and the other a
+matrix, the operator is applied to the scalar and each element of the
+matrix.
+
+   <p>For the binary element-by-element boolean operators, both subexpressions
+<var>boolean1</var> and <var>boolean2</var> are evaluated before computing the
+result.  This can make a difference when the expressions have side
+effects.  For example, in the expression
+
+<pre class="example">     a & b++
+</pre>
+   <p class="noindent">the value of the variable <var>b</var> is incremented even if the variable
+<var>a</var> is zero.
+
+   <p>This behavior is necessary for the boolean operators to work as
+described for matrix-valued operands.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Emacs-Octave-Support.html b/doc/interpreter/HTML/Emacs-Octave-Support.html
new file mode 100644
index 0000000..499de4f
--- /dev/null
+++ b/doc/interpreter/HTML/Emacs-Octave-Support.html
@@ -0,0 +1,65 @@
+<html lang="en">
+<head>
+<title>Emacs Octave Support - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Installation.html#Installation" title="Installation">
+<link rel="next" href="Copying.html#Copying" title="Copying">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Emacs-Octave-Support"></a>
+Next: <a rel="next" accesskey="n" href="Copying.html#Copying">Copying</a>,
+Previous: <a rel="previous" accesskey="p" href="Installation.html#Installation">Installation</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix G Emacs Octave Support</h2>
+
+<p>The development of Octave code can greatly be facilitated using Emacs
+with Octave mode, a major mode for editing Octave files which can e.g. 
+automatically indent the code, do some of the typing (with Abbrev mode)
+and show keywords, comments, strings, etc. in different faces (with
+Font-lock mode on devices that support it).
+
+   <p>It is also possible to run Octave from within Emacs, either by directly
+entering commands at the prompt in a buffer in Inferior Octave mode, or
+by interacting with Octave from within a file with Octave code.  This is
+useful in particular for debugging Octave code.
+
+   <p>Finally, you can convince Octave to use the Emacs info reader for
+<kbd>help -i</kbd>.
+
+   <p>All functionality is provided by the Emacs Lisp package EOS (for “Emacs
+Octave Support”).  This chapter describes how to set up and use this
+package.
+
+   <p>Please contact <Kurt.Hornik at wu-wien.ac.at> if you have any questions
+or suggestions on using EOS.
+
+<ul class="menu">
+<li><a accesskey="1" href="Installing-EOS.html#Installing-EOS">Installing EOS</a>
+<li><a accesskey="2" href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a>
+<li><a accesskey="3" href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs">Running Octave From Within Emacs</a>
+<li><a accesskey="4" href="Using-the-Emacs-Info-Reader-for-Octave.html#Using-the-Emacs-Info-Reader-for-Octave">Using the Emacs Info Reader for Octave</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Empty-Matrices.html b/doc/interpreter/HTML/Empty-Matrices.html
new file mode 100644
index 0000000..7cc5ced
--- /dev/null
+++ b/doc/interpreter/HTML/Empty-Matrices.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Empty Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrices.html#Matrices" title="Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Empty-Matrices"></a>
+Up: <a rel="up" accesskey="u" href="Matrices.html#Matrices">Matrices</a>
+<hr>
+</div>
+
+<h4 class="subsection">4.1.1 Empty Matrices</h4>
+
+<p>A matrix may have one or both dimensions zero, and operations on empty
+matrices are handled as described by Carl de Boor in <cite>An Empty
+Exercise</cite>, SIGNUM, Volume 25, pages 2-6, 1990 and C. N. Nett and W. M. 
+Haddad, in <cite>A System-Theoretic Appropriate Realization of the Empty
+Matrix Concept</cite>, IEEE Transactions on Automatic Control, Volume 38,
+Number 5, May 1993. 
+Briefly, given a scalar <var>s</var>, an <var>m</var> by
+<var>n</var> matrix <code>M(mxn)</code>, and an <var>m</var> by <var>n</var> empty matrix
+<code>[](mxn)</code> (with either one or both dimensions equal to zero), the
+following are true:
+
+<pre class="example">     s * [](mxn) = [](mxn) * s = [](mxn)
+     
+         [](mxn) + [](mxn) = [](mxn)
+     
+         [](0xm) *  M(mxn) = [](0xn)
+     
+          M(mxn) * [](nx0) = [](mx0)
+     
+         [](mx0) * [](0xn) =  0(mxn)
+</pre>
+   <p>By default, dimensions of the empty matrix are printed along with the
+empty matrix symbol, ‘<samp><span class="samp">[]</span></samp>’.  The built-in variable
+<code>print_empty_dimensions</code> controls this behavior.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002dprint_005fempty_005fdimensions"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>print_empty_dimensions</b> ()<var><a name="index-print_005fempty_005fdimensions-229"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>print_empty_dimensions</b> (<var>new_val</var>)<var><a name="index-print_005fempty_005fdimensions-230"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether the
+dimensions of empty matrices are printed along with the empty matrix
+symbol, ‘<samp><span class="samp">[]</span></samp>’.  For example, the expression
+
+     <pre class="example">          zeros (3, 0)
+</pre>
+        <p class="noindent">will print
+
+     <pre class="example">          ans = [](3x0)
+</pre>
+        </blockquote></div>
+
+   <p>Empty matrices may also be used in assignment statements as a convenient
+way to delete rows or columns of matrices. 
+See <a href="Assignment-Ops.html#Assignment-Ops">Assignment Expressions</a>.
+
+   <p>When Octave parses a matrix expression, it examines the elements of the
+list to determine whether they are all constants.  If they are, it
+replaces the list with a single matrix constant.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Enabling-and-Disabling-Warnings.html b/doc/interpreter/HTML/Enabling-and-Disabling-Warnings.html
new file mode 100644
index 0000000..edf60fa
--- /dev/null
+++ b/doc/interpreter/HTML/Enabling-and-Disabling-Warnings.html
@@ -0,0 +1,241 @@
+<html lang="en">
+<head>
+<title>Enabling and Disabling Warnings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Handling-Warnings.html#Handling-Warnings" title="Handling Warnings">
+<link rel="prev" href="Issuing-Warnings.html#Issuing-Warnings" title="Issuing Warnings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Enabling-and-Disabling-Warnings"></a>
+Previous: <a rel="previous" accesskey="p" href="Issuing-Warnings.html#Issuing-Warnings">Issuing Warnings</a>,
+Up: <a rel="up" accesskey="u" href="Handling-Warnings.html#Handling-Warnings">Handling Warnings</a>
+<hr>
+</div>
+
+<h4 class="subsection">12.2.2 Enabling and Disabling Warnings</h4>
+
+<p>The <code>warning</code> function also allows you to control which warnings
+are actually printed to the screen.  If the <code>warning</code> function
+is called with a string argument that is either <code>"on"</code> or <code>"off"</code>
+all warnings will be enabled or disabled.
+
+   <p>It is also possible to enable and disable individual warnings through
+their string identifications.  The following code will issue a warning
+
+<pre class="example">     warning ("non-negative-variable",
+              "'a' must be non-negative.  Setting 'a' to zero.");
+</pre>
+   <p class="noindent">while the following won't issue a warning
+
+<pre class="example">     warning ("off", "non-negative-variable");
+     warning ("non-negative-variable",
+              "'a' must be non-negative.  Setting 'a' to zero.");
+</pre>
+   <p>The functions distributed with Octave can issue one of the following
+warnings.
+
+<!-- ./miscellaneous/warning_ids.m -->
+   <p><a name="doc_002dwarning_005fids"></a>
+     <dl>
+<dt><code>Octave:array-to-scalar</code><dd>If the <code>Octave:array-to-scalar</code> warning is enabled, Octave will
+warn when an implicit conversion from an array to a scalar value is
+attempted.  By default, the <code>Octave:array-to-scalar</code> warning is
+disabled.
+
+     <br><dt><code>Octave:array-to-vector</code><dd>If the <code>Octave:array-to-vector</code> warning is enabled, Octave will
+warn when an implicit conversion from an array to a vector value is
+attempted.  By default, the <code>Octave:array-to-vector</code> warning is
+disabled.
+
+     <br><dt><code>Octave:assign-as-truth-value</code><dd>If the <code>Octave:assign-as-truth-value</code> warning is
+enabled, a warning is issued for statements like
+
+     <pre class="example">          if (s = t)
+            ...
+</pre>
+     <p class="noindent">since such statements are not common, and it is likely that the intent
+was to write
+
+     <pre class="example">          if (s == t)
+            ...
+</pre>
+     <p class="noindent">instead.
+
+     <p>There are times when it is useful to write code that contains
+assignments within the condition of a <code>while</code> or <code>if</code>
+statement.  For example, statements like
+
+     <pre class="example">          while (c = getc())
+            ...
+</pre>
+     <p class="noindent">are common in C programming.
+
+     <p>It is possible to avoid all warnings about such statements by
+disabling the <code>Octave:assign-as-truth-value</code> warning,
+but that may also let real errors like
+
+     <pre class="example">          if (x = 1)  # intended to test (x == 1)!
+            ...
+</pre>
+     <p class="noindent">slip by.
+
+     <p>In such cases, it is possible suppress errors for specific statements by
+writing them with an extra set of parentheses.  For example, writing the
+previous example as
+
+     <pre class="example">          while ((c = getc()))
+            ...
+</pre>
+     <p class="noindent">will prevent the warning from being printed for this statement, while
+allowing Octave to warn about other assignments used in conditional
+contexts.
+
+     <p>By default, the <code>Octave:assign-as-truth-value</code> warning is enabled.
+
+     <br><dt><code>Octave:associativity-change</code><dd>If the <code>Octave:associativity-change</code> warning is
+enabled, Octave will warn about possible changes in the meaning of
+some code due to changes in associativity for some operators. 
+Associativity changes have typically been made for <span class="sc">matlab</span>
+compatibility.  By default, the <code>Octave:associativity-change</code>
+warning is enabled.
+
+     <br><dt><code>Octave:divide-by-zero</code><dd>If the <code>Octave:divide-by-zero</code> warning is enabled, a
+warning is issued when Octave encounters a division by zero.  By
+default, the <code>Octave:divide-by-zero</code> warning is enabled.
+
+     <br><dt><code>Octave:empty-list-elements</code><dd>If the <code>Octave:empty-list-elements</code> warning is enabled, a
+warning is issued when an empty matrix is found in a matrix list. 
+For example,
+
+     <pre class="example">          a = [1, [], 3, [], 5]
+</pre>
+     <p class="noindent">By default, the <code>Octave:empty-list-elements</code> warning is enabled.
+
+     <br><dt><code>Octave:fortran-indexing</code><dd>If the <code>Octave:fortran-indexing</code> warning is enabled, a warning is
+printed for expressions which select elements of a two-dimensional matrix
+using a single index.  By default, the <code>Octave:fortran-indexing</code>
+warning is disabled.
+
+     <br><dt><code>Octave:function-name-clash</code><dd>If the <code>Octave:function-name-clash</code> warning is enabled, a
+warning is issued when Octave finds that the name of a function
+defined in a function file differs from the name of the file.  (If
+the names disagree, the name declared inside the file is ignored.) 
+By default, the <code>Octave:function-name-clash</code> warning is enabled.
+
+     <br><dt><code>Octave:future-time-stamp</code><dd>If the <code>Octave:future-time-stamp</code> warning is enabled, Octave
+will print a warning if it finds a function file with a time stamp
+that is in the future.  By default, the
+<code>Octave:future-time-stamp</code> warning is enabled.
+
+     <br><dt><code>Octave:imag-to-real</code><dd>If the <code>Octave:imag-to-real</code> warning is enabled, a warning is
+printed for implicit conversions of complex numbers to real numbers. 
+By default, the <code>Octave:imag-to-real</code> warning is disabled.
+
+     <br><dt><code>Octave:matlab-incompatible</code><dd>Print warnings for Octave language features that may cause
+compatibility problems with <span class="sc">matlab</span>.
+
+     <br><dt><code>Octave:missing-semicolon</code><dd>If the <code>Octave:missing-semicolon</code> warning is enabled, Octave
+will warn when statements in function definitions don't end in
+semicolons.  By default the <code>Octave:missing-semicolon</code> warning
+is disabled.
+
+     <br><dt><code>Octave:neg-dim-as-zero</code><dd>If the <code>Octave:neg-dim-as-zero</code> warning is enabled, print a warning
+for expressions like
+
+     <pre class="example">          eye (-1)
+</pre>
+     <p class="noindent">By default, the <code>Octave:neg-dim-as-zero</code> warning is disabled.
+
+     <br><dt><code>Octave:num-to-str</code><dd>If the <code>Octave:num-to-str</code> warning is enable, a warning is
+printed for implicit conversions of numbers to their ASCII character
+equivalents when strings are constructed using a mixture of strings and
+numbers in matrix notation.  For example,
+
+     <pre class="example">          [ "f", 111, 111 ]
+                "foo"
+</pre>
+     <p>elicits a warning if the <code>Octave:num-to-str</code> warning is
+enabled.  By default, the <code>Octave:num-to-str</code> warning is enabled.
+
+     <br><dt><code>Octave:precedence-change</code><dd>If the <code>Octave:precedence-change</code> warning is enabled, Octave
+will warn about possible changes in the meaning of some code due to
+changes in precedence for some operators.  Precedence changes have
+typically been made for <span class="sc">matlab</span> compatibility.  By default, the
+<code>Octave:precedence-change</code> warning is enabled.
+
+     <br><dt><code>Octave:reload-forces-clear</code><dd>If several functions have been loaded from the same file, Octave must
+clear all the functions before any one of them can be reloaded.  If
+the <code>Octave:reload-forces-clear</code> warning is enabled, Octave will
+warn you when this happens, and print a list of the additional
+functions that it is forced to clear.  By default, the
+<code>Octave:reload-forces-clear</code> warning is enabled.
+
+     <br><dt><code>Octave:resize-on-range-error</code><dd>If the <code>Octave:resize-on-range-error</code> warning is enabled, print a
+warning when a matrix is resized by an indexed assignment with
+indices outside the current bounds.  By default, the
+<code>Octave:resize-on-range-error</code> warning is disabled.
+
+     <br><dt><code>Octave:separator-insert</code><dd>Print warning if commas or semicolons might be inserted
+automatically in literal matrices.
+
+     <br><dt><code>Octave:single-quote-string</code><dd>Print warning if a single quote character is used to introduce a
+string constant.
+
+     <br><dt><code>Octave:str-to-num</code><dd>If the <code>Octave:str-to-num</code> warning is enabled, a warning is printed
+for implicit conversions of strings to their numeric ASCII equivalents. 
+For example,
+     <pre class="example">          "abc" + 0
+                97 98 99
+</pre>
+     <p>elicits a warning if the <code>Octave:str-to-num</code> warning is enabled. 
+By default, the <code>Octave:str-to-num</code> warning is disabled.
+
+     <br><dt><code>Octave:string-concat</code><dd>If the <code>Octave:string-concat</code> warning is enabled, print a
+warning when concatenating a mixture of double and single quoted strings. 
+By default, the <code>Octave:string-concat</code> warning is disabled.
+
+     <br><dt><code>Octave:undefined-return-values</code><dd>If the <code>Octave:undefined-return-values</code> warning is disabled,
+print a warning if a function does not define all the values in
+the return list which are expected.  By default, the
+<code>Octave:undefined-return-values</code> warning is enabled.
+
+     <br><dt><code>Octave:variable-switch-label</code><dd>If the <code>Octave:variable-switch-label</code> warning is enabled, Octave
+will print a warning if a switch label is not a constant or constant
+expression.  By default, the <code>Octave:variable-switch-label</code>
+warning is disabled. 
+</dl>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Entering-Debug-Mode.html b/doc/interpreter/HTML/Entering-Debug-Mode.html
new file mode 100644
index 0000000..e6e3a9a
--- /dev/null
+++ b/doc/interpreter/HTML/Entering-Debug-Mode.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Entering Debug Mode - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Debugging.html#Debugging" title="Debugging">
+<link rel="next" href="Leaving-Debug-Mode.html#Leaving-Debug-Mode" title="Leaving Debug Mode">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Entering-Debug-Mode"></a>
+Next: <a rel="next" accesskey="n" href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">Leaving Debug Mode</a>,
+Up: <a rel="up" accesskey="u" href="Debugging.html#Debugging">Debugging</a>
+<hr>
+</div>
+
+<h3 class="section">13.1 Entering Debug Mode</h3>
+
+<p>There are two basic means of interrupting the execution of an Octave
+script.  These are breakpoints see <a href="Breakpoints.html#Breakpoints">Breakpoints</a>, discussed in the next
+section and interruption based on some condition.
+
+   <p>Octave supports three means to stop execution based on the values set in
+the functions <code>debug_on_interrupt</code>, <code>debug_on_warning</code> and
+<code>debug_on_error</code>.
+
+<!-- sighandlers.cc -->
+   <p><a name="doc_002ddebug_005fon_005finterrupt"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>debug_on_interrupt</b> ()<var><a name="index-debug_005fon_005finterrupt-685"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>debug_on_interrupt</b> (<var>new_val</var>)<var><a name="index-debug_005fon_005finterrupt-686"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave will try
+to enter debugging mode when it receives an interrupt signal (typically
+generated with <kbd>C-c</kbd>).  If a second interrupt signal is received
+before reaching the debugging mode, a normal interrupt will occur. 
+</p></blockquote></div>
+
+<!-- error.cc -->
+   <p><a name="doc_002ddebug_005fon_005fwarning"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>debug_on_warning</b> ()<var><a name="index-debug_005fon_005fwarning-687"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>debug_on_warning</b> (<var>new_val</var>)<var><a name="index-debug_005fon_005fwarning-688"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave will try
+to enter the debugger when a warning is encountered. 
+</p></blockquote></div>
+
+<!-- error.cc -->
+   <p><a name="doc_002ddebug_005fon_005ferror"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>debug_on_error</b> ()<var><a name="index-debug_005fon_005ferror-689"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>debug_on_error</b> (<var>new_val</var>)<var><a name="index-debug_005fon_005ferror-690"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave will try
+to enter the debugger when an error is encountered.  This will also
+inhibit printing of the normal traceback message (you will only see
+the top-level error message). 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Environment-Variables.html b/doc/interpreter/HTML/Environment-Variables.html
new file mode 100644
index 0000000..05a2e02
--- /dev/null
+++ b/doc/interpreter/HTML/Environment-Variables.html
@@ -0,0 +1,59 @@
+<html lang="en">
+<head>
+<title>Environment Variables - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Process-ID-Information.html#Process-ID-Information" title="Process ID Information">
+<link rel="next" href="Current-Working-Directory.html#Current-Working-Directory" title="Current Working Directory">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Environment-Variables"></a>
+Next: <a rel="next" accesskey="n" href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a>,
+Previous: <a rel="previous" accesskey="p" href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.7 Environment Variables</h3>
+
+<!-- sysdep.cc -->
+<p><a name="doc_002dgetenv"></a>
+
+<div class="defun">
+— Built-in Function:  <b>getenv</b> (<var>var</var>)<var><a name="index-getenv-2422"></a></var><br>
+<blockquote><p>Return the value of the environment variable <var>var</var>.  For example,
+
+     <pre class="example">          getenv ("PATH")
+</pre>
+        <p class="noindent">returns a string containing the value of your path. 
+</p></blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dputenv"></a>
+
+<div class="defun">
+— Built-in Function:  <b>putenv</b> (<var>var, value</var>)<var><a name="index-putenv-2423"></a></var><br>
+— Built-in Function:  <b>setenv</b> (<var>var, value</var>)<var><a name="index-setenv-2424"></a></var><br>
+<blockquote><p>Set the value of the environment variable <var>var</var> to <var>value</var>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Error-Messages.html b/doc/interpreter/HTML/Error-Messages.html
new file mode 100644
index 0000000..8c05aae
--- /dev/null
+++ b/doc/interpreter/HTML/Error-Messages.html
@@ -0,0 +1,46 @@
+<html lang="en">
+<head>
+<title>Error Messages - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Conventions.html#Conventions" title="Conventions">
+<link rel="prev" href="Printing-Notation.html#Printing-Notation" title="Printing Notation">
+<link rel="next" href="Format-of-Descriptions.html#Format-of-Descriptions" title="Format of Descriptions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Error-Messages"></a>
+Next: <a rel="next" accesskey="n" href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a>,
+Previous: <a rel="previous" accesskey="p" href="Printing-Notation.html#Printing-Notation">Printing Notation</a>,
+Up: <a rel="up" accesskey="u" href="Conventions.html#Conventions">Conventions</a>
+<hr>
+</div>
+
+<h4 class="subsection">1.3.4 Error Messages</h4>
+
+<p><a name="index-error-message-notation-14"></a>
+Some examples signal errors.  This normally displays an error message
+on your terminal.  Error messages are shown on a line beginning with
+<code>error:</code>.
+
+<pre class="example">     fieldnames ([1, 2; 3, 4])
+     error: fieldnames: wrong type argument `matrix'
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Error-bar-series.html b/doc/interpreter/HTML/Error-bar-series.html
new file mode 100644
index 0000000..003e192
--- /dev/null
+++ b/doc/interpreter/HTML/Error-bar-series.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Error bar series - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Contour-groups.html#Contour-groups" title="Contour groups">
+<link rel="next" href="Line-series.html#Line-series" title="Line series">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Error-bar-series"></a>
+Next: <a rel="next" accesskey="n" href="Line-series.html#Line-series">Line series</a>,
+Previous: <a rel="previous" accesskey="p" href="Contour-groups.html#Contour-groups">Contour groups</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.5 Error bar series</h5>
+
+<p><a name="index-series-objects-1238"></a><a name="index-error-bar-series-1239"></a>
+Error bar series are created by the <code>errorbar</code> function.  Each
+<code>hggroup</code> element contains two line objects representing the data and
+the errorbars separately.  The properties of the error bar series are
+
+     <dl>
+<dt><code>color</code><dd>The RGB color or color name of the line objects of the error bars.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the line objects of the error bars.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>The line and fill color of the markers on the error bars.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>ldata</code><dt><code>udata</code><dt><code>xldata</code><dt><code>xudata</code><dd>The original x, y, l, u, xl, xu data of the error bars.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>ldatasource</code><dt><code>udatasource</code><dt><code>xldatasource</code><dt><code>xudatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Errors-and-Warnings.html b/doc/interpreter/HTML/Errors-and-Warnings.html
new file mode 100644
index 0000000..9b5f760
--- /dev/null
+++ b/doc/interpreter/HTML/Errors-and-Warnings.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Errors and Warnings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="next" href="Debugging.html#Debugging" title="Debugging">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Errors-and-Warnings"></a>
+Next: <a rel="next" accesskey="n" href="Debugging.html#Debugging">Debugging</a>,
+Previous: <a rel="previous" accesskey="p" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">12 Errors and Warnings</h2>
+
+<p>Octave includes several functions for printing error and warning
+messages.  When you write functions that need to take special action
+when they encounter abnormal conditions, you should print the error
+messages using the functions described in this chapter.
+
+   <p>Since many of Octave's functions use these functions, it is also useful
+to understand them, so that errors and warnings can be handled.
+
+<ul class="menu">
+<li><a accesskey="1" href="Handling-Errors.html#Handling-Errors">Handling Errors</a>
+<li><a accesskey="2" href="Handling-Warnings.html#Handling-Warnings">Handling Warnings</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Errors.html b/doc/interpreter/HTML/Errors.html
new file mode 100644
index 0000000..110f28e
--- /dev/null
+++ b/doc/interpreter/HTML/Errors.html
@@ -0,0 +1,100 @@
+<html lang="en">
+<head>
+<title>Errors - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="prev" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="next" href="Executable-Octave-Programs.html#Executable-Octave-Programs" title="Executable Octave Programs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Errors"></a>
+Next: <a rel="next" accesskey="n" href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a>,
+Previous: <a rel="previous" accesskey="p" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.5 How Octave Reports Errors</h3>
+
+<p><a name="index-error-messages-151"></a><a name="index-messages_002c-error-152"></a>
+Octave reports two kinds of errors for invalid programs.
+
+   <p>A <dfn>parse error</dfn> occurs if Octave cannot understand something you
+have typed.  For example, if you misspell a keyword,
+
+<pre class="example">     octave:13> function y = f (x) y = x***2; endfunction
+</pre>
+   <p class="noindent">Octave will respond immediately with a message like this:
+
+<pre class="example">     parse error:
+     
+       syntax error
+     
+     >>> function y = f (x) y = x***2; endfunction
+                                   ^
+</pre>
+   <p class="noindent">For most parse errors, Octave uses a caret (‘<samp><span class="samp">^</span></samp>’) to mark the point
+on the line where it was unable to make sense of your input.  In this
+case, Octave generated an error message because the keyword for
+exponentiation (<code>**</code>) was misspelled.  It marked the error at the
+third ‘<samp><span class="samp">*</span></samp>’ because the code leading up to this was correct but the final
+‘<samp><span class="samp">*</span></samp>’ was not understood.
+
+   <p>Another class of error message occurs at evaluation time.  These
+errors are called <dfn>run-time errors</dfn>, or sometimes
+<dfn>evaluation errors</dfn>, because they occur when your program is being
+<dfn>run</dfn>, or <dfn>evaluated</dfn>.  For example, if after correcting the
+mistake in the previous function definition, you type
+
+<pre class="example">     octave:13> f ()
+</pre>
+   <p class="noindent">Octave will respond with
+
+<pre class="example">     error: `x' undefined near line 1 column 24
+     error: called from:
+     error:   f at line 1, column 22
+</pre>
+   <p class="noindent">This error message has several parts, and gives quite a bit of
+information to help you locate the source of the error.  The messages
+are generated from the point of the innermost error, and provide a
+traceback of enclosing expressions and function calls.
+
+   <p>In the example above, the first line indicates that a variable named
+‘<samp><span class="samp">x</span></samp>’ was found to be undefined near line 1 and column 24 of some
+function or expression.  For errors occurring within functions, lines
+are counted from the beginning of the file containing the function
+definition.  For errors occurring outside of an enclosing function,
+the line number indicates the input line number, which is usually displayed
+in the primary prompt string.
+
+   <p>The second and third lines of the error message indicate that the error
+occurred within the function <code>f</code>.  If the function <code>f</code> had been
+called from within another function, for example, <code>g</code>, the list of
+errors would have ended with one more line:
+
+<pre class="example">     error:   g at line 1, column 17
+</pre>
+   <p>These lists of function calls make it fairly easy to trace the
+path your program took before the error occurred, and to correct the
+error before trying again.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Escape-Sequences-in-string-constants.html b/doc/interpreter/HTML/Escape-Sequences-in-string-constants.html
new file mode 100644
index 0000000..81ba7e0
--- /dev/null
+++ b/doc/interpreter/HTML/Escape-Sequences-in-string-constants.html
@@ -0,0 +1,96 @@
+<html lang="en">
+<head>
+<title>Escape Sequences in string constants - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="next" href="Character-Arrays.html#Character-Arrays" title="Character Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Escape-Sequences-in-string-constants"></a>
+Next: <a rel="next" accesskey="n" href="Character-Arrays.html#Character-Arrays">Character Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.1 Escape Sequences in string constants</h3>
+
+<p><a name="index-escape-sequence-notation-283"></a>In double-quoted strings, the backslash character is used to introduce
+<dfn>escape sequences</dfn> that represent other characters.  For example,
+‘<samp><span class="samp">\n</span></samp>’ embeds a newline character in a double-quoted string and
+‘<samp><span class="samp">\"</span></samp>’ embeds a double quote character.  In single-quoted strings, backslash
+is not a special character.  Here is an example showing the difference:
+
+<pre class="example">     toascii ("\n")
+          10
+     toascii ('\n')
+          [ 92 110 ]
+</pre>
+   <p>Here is a table of all the escape sequences used in Octave (within
+double quoted strings).  They are the same as those used in the C
+programming language.
+
+     <dl>
+<dt><code>\\</code><dd>Represents a literal backslash, ‘<samp><span class="samp">\</span></samp>’.
+
+     <br><dt><code>\"</code><dd>Represents a literal double-quote character, ‘<samp><span class="samp">"</span></samp>’.
+
+     <br><dt><code>\'</code><dd>Represents a literal single-quote character, ‘<samp><span class="samp">'</span></samp>’.
+
+     <br><dt><code>\0</code><dd>Represents the “nul” character, control-@, ASCII code 0.
+
+     <br><dt><code>\a</code><dd>Represents the “alert” character, control-g, ASCII code 7.
+
+     <br><dt><code>\b</code><dd>Represents a backspace, control-h, ASCII code 8.
+
+     <br><dt><code>\f</code><dd>Represents a formfeed, control-l, ASCII code 12.
+
+     <br><dt><code>\n</code><dd>Represents a newline, control-j, ASCII code 10.
+
+     <br><dt><code>\r</code><dd>Represents a carriage return, control-m, ASCII code 13.
+
+     <br><dt><code>\t</code><dd>Represents a horizontal tab, control-i, ASCII code 9.
+
+     <br><dt><code>\v</code><dd>Represents a vertical tab, control-k, ASCII code 11.
+
+     <!-- We don't do octal or hex this way yet. -->
+     <!-- @item \@var{nnn} -->
+     <!-- Represents the octal value @var{nnn}, where @var{nnn} are one to three -->
+     <!-- digits between 0 and 7.  For example, the code for the ASCII ESC -->
+     <!-- (escape) character is @samp{\033}. at refill -->
+     <!-- @item \x at var{hh}@dots{} -->
+     <!-- Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal -->
+     <!-- digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or -->
+     <!-- @samp{a} through @samp{f}).  Like the same construct in @sc{ansi} C, -->
+     <!-- the escape -->
+     <!-- sequence continues until the first non-hexadecimal digit is seen.  However, -->
+     <!-- using more than two hexadecimal digits produces undefined results.  (The -->
+     <!-- @samp{\x} escape sequence is not allowed in @sc{posix} @code{awk}.)@refill -->
+   </dl>
+
+   <p>In a single-quoted string there is only one escape sequence: you may insert a
+single quote character using two single quote characters in succession.  For
+example,
+
+<pre class="example">     'I can''t escape'
+          I can't escape
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Evaluating-Polynomials.html b/doc/interpreter/HTML/Evaluating-Polynomials.html
new file mode 100644
index 0000000..58f2207
--- /dev/null
+++ b/doc/interpreter/HTML/Evaluating-Polynomials.html
@@ -0,0 +1,97 @@
+<html lang="en">
+<head>
+<title>Evaluating Polynomials - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="next" href="Finding-Roots.html#Finding-Roots" title="Finding Roots">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Evaluating-Polynomials"></a>
+Next: <a rel="next" accesskey="n" href="Finding-Roots.html#Finding-Roots">Finding Roots</a>,
+Up: <a rel="up" accesskey="u" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<hr>
+</div>
+
+<h3 class="section">27.1 Evaluating Polynomials</h3>
+
+<p>The value of a polynomial represented by the vector <var>c</var> can be evaluated
+at the point <var>x</var> very easily, as the following example shows:
+
+<pre class="example">     N = length(c)-1;
+     val = dot( x.^(N:-1:0), c );
+</pre>
+   <p class="noindent">While the above example shows how easy it is to compute the value of a
+polynomial, it isn't the most stable algorithm.  With larger polynomials
+you should use more elegant algorithms, such as Horner's Method, which
+is exactly what the Octave function <code>polyval</code> does.
+
+   <p>In the case where <var>x</var> is a square matrix, the polynomial given by
+<var>c</var> is still well-defined.  As when <var>x</var> is a scalar the obvious
+implementation is easily expressed in Octave, but also in this case
+more elegant algorithms perform better.  The <code>polyvalm</code> function
+provides such an algorithm.
+
+<!-- ./polynomial/polyval.m -->
+   <p><a name="doc_002dpolyval"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>polyval</b> (<var>p, x</var>)<var><a name="index-polyval-2021"></a></var><br>
+— Function File: <var>y</var> = <b>polyval</b> (<var>p, x, </var>[]<var>, mu</var>)<var><a name="index-polyval-2022"></a></var><br>
+<blockquote><p>Evaluate the polynomial at of the specified values for <var>x</var>.  When <var>mu</var>
+is present evaluate the polynomial for (<var>x</var>-<var>mu</var>(1))/<var>mu</var>(2). 
+If <var>x</var> is a vector or matrix, the polynomial is evaluated for each of
+the elements of <var>x</var>.
+
+   — Function File: [<var>y</var>, <var>dy</var>] = <b>polyval</b> (<var>p, x, s</var>)<var><a name="index-polyval-2023"></a></var><br>
+— Function File: [<var>y</var>, <var>dy</var>] = <b>polyval</b> (<var>p, x, s, mu</var>)<var><a name="index-polyval-2024"></a></var><br>
+<blockquote><p>In addition to evaluating the polynomial, the second output
+represents the prediction interval, <var>y</var> +/- <var>dy</var>, which
+contains at least 50% of the future predictions.  To calculate the
+prediction interval, the structured variable <var>s</var>, originating
+form `polyfit', must be present. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolyfit.html#doc_002dpolyfit">polyfit</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>, <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/polyvalm.m -->
+   <p><a name="doc_002dpolyvalm"></a>
+
+<div class="defun">
+— Function File:  <b>polyvalm</b> (<var>c, x</var>)<var><a name="index-polyvalm-2025"></a></var><br>
+<blockquote><p>Evaluate a polynomial in the matrix sense.
+
+        <p><code>polyvalm (</code><var>c</var><code>, </code><var>x</var><code>)</code> will evaluate the polynomial in the
+matrix sense, i.e., matrix multiplication is used instead of element by
+element multiplication as is used in polyval.
+
+        <p>The argument <var>x</var> must be a square matrix. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Evaluation-Notation.html b/doc/interpreter/HTML/Evaluation-Notation.html
new file mode 100644
index 0000000..f7f2f30
--- /dev/null
+++ b/doc/interpreter/HTML/Evaluation-Notation.html
@@ -0,0 +1,72 @@
+<html lang="en">
+<head>
+<title>Evaluation Notation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Conventions.html#Conventions" title="Conventions">
+<link rel="prev" href="Fonts.html#Fonts" title="Fonts">
+<link rel="next" href="Printing-Notation.html#Printing-Notation" title="Printing Notation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Evaluation-Notation"></a>
+Next: <a rel="next" accesskey="n" href="Printing-Notation.html#Printing-Notation">Printing Notation</a>,
+Previous: <a rel="previous" accesskey="p" href="Fonts.html#Fonts">Fonts</a>,
+Up: <a rel="up" accesskey="u" href="Conventions.html#Conventions">Conventions</a>
+<hr>
+</div>
+
+<h4 class="subsection">1.3.2 Evaluation Notation</h4>
+
+<p><a name="index-evaluation-notation-11"></a><a name="index-documentation-notation-12"></a>
+In the examples in this manual, results from expressions that you
+evaluate are indicated with ‘<samp></samp>’.  For example,
+
+<pre class="example">     sqrt (2)
+           1.4142
+</pre>
+   <p class="noindent">You can read this as “<code>sqrt (2)</code> evaluates to 1.4142”.
+
+   <p>In some cases, matrix values that are returned by expressions are
+displayed like this
+
+<pre class="example">     [1, 2; 3, 4] == [1, 3; 2, 4]
+           [ 1, 0; 0, 1 ]
+</pre>
+   <p class="noindent">and in other cases, they are displayed like this
+
+<pre class="example">     eye (3)
+            1  0  0
+              0  1  0
+              0  0  1
+</pre>
+   <p class="noindent">in order to clearly show the structure of the result.
+
+   <p>Sometimes to help describe one expression, another expression is
+shown that produces identical results.  The exact equivalence of
+expressions is indicated with ‘<samp><span class="samp">==</span></samp>’.  For example,
+
+<pre class="example">     rot90 ([1, 2; 3, 4], -1)
+     ==
+     rot90 ([1, 2; 3, 4], 3)
+     ==
+     rot90 ([1, 2; 3, 4], 7)
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Evaluation-in-a-Different-Context.html b/doc/interpreter/HTML/Evaluation-in-a-Different-Context.html
new file mode 100644
index 0000000..1578411
--- /dev/null
+++ b/doc/interpreter/HTML/Evaluation-in-a-Different-Context.html
@@ -0,0 +1,136 @@
+<html lang="en">
+<head>
+<title>Evaluation in a Different Context - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Evaluation.html#Evaluation" title="Evaluation">
+<link rel="prev" href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name" title="Calling a Function by its Name">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Evaluation-in-a-Different-Context"></a>
+Previous: <a rel="previous" accesskey="p" href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a>,
+Up: <a rel="up" accesskey="u" href="Evaluation.html#Evaluation">Evaluation</a>
+<hr>
+</div>
+
+<h3 class="section">9.2 Evaluation in a Different Context</h3>
+
+<p>Before you evaluate an expression you need to substitute
+the values of the variables used in the expression.  These
+are stored in the symbol table.  Whenever the interpreter
+starts a new function it saves the current symbol table
+and creates a new one, initializing it with the list of
+function parameters and a couple of predefined variables
+such as <code>nargin</code>.  Expressions inside the function use the
+new symbol table.
+
+   <p>Sometimes you want to write a function so that when you
+call it, it modifies variables in your own context.  This
+allows you to use a pass-by-name style of function,
+which is similar to using a pointer in programming languages such
+as C.
+
+   <p>Consider how you might write <code>save</code> and <code>load</code> as
+m-files.  For example,
+
+<pre class="example">     function create_data
+       x = linspace (0, 10, 10);
+       y = sin (x);
+       save mydata x y
+     endfunction
+</pre>
+   <p>With <code>evalin</code>, you could write <code>save</code> as follows:
+
+<pre class="example">     function save (file, name1, name2)
+       f = open_save_file (file);
+       save_var(f, name1, evalin ("caller", name1));
+       save_var(f, name2, evalin ("caller", name2));
+     endfunction
+</pre>
+   <p class="noindent">Here, ‘<samp><span class="samp">caller</span></samp>’ is the <code>create_data</code> function and <code>name1</code>
+is the string <code>"x"</code>, which evaluates simply as the value of <code>x</code>.
+
+   <p>You later want to load the values back from <code>mydata</code>
+in a different context:
+
+<pre class="example">     function process_data
+       load mydata
+       ... do work ...
+     endfunction
+</pre>
+   <p class="noindent">With <code>assignin</code>, you could write <code>load</code> as follows:
+
+<pre class="example">     function load (file)
+       f = open_load_file (file);
+       [name, val] = load_var (f);
+       assignin ("caller", name, val);
+       [name, val] = load_var (f);
+       assignin ("caller", name, val);
+     endfunction
+</pre>
+   <p class="noindent">Here, ‘<samp><span class="samp">caller</span></samp>’ is the <code>process_data</code> function.
+
+   <p>You can set and use variables at the command prompt
+using the context ‘<samp><span class="samp">base</span></samp>’ rather than ‘<samp><span class="samp">caller</span></samp>’.
+
+   <p>These functions are rarely used in practice.  One
+example is the <code>fail (‘</code><samp><span class="samp">code</span></samp><code>’, ‘</code><samp><span class="samp">pattern</span></samp><code>’)</code> function
+which evaluates ‘<samp><span class="samp">code</span></samp>’ in the caller's context and
+checks that the error message it produces matches
+the given pattern.  Other examples such as <code>save</code> and <code>load</code>
+are written in C++ where all Octave variables
+are in the ‘<samp><span class="samp">caller</span></samp>’ context and <code>evalin</code> is not needed.
+
+<!-- parse.cc -->
+   <p><a name="doc_002devalin"></a>
+
+<div class="defun">
+— Built-in Function:  <b>evalin</b> (<var>context, try, catch</var>)<var><a name="index-evalin-552"></a></var><br>
+<blockquote><p>Like <code>eval</code>, except that the expressions are evaluated in the
+context <var>context</var>, which may be either <code>"caller"</code> or
+<code>"base"</code>. 
+</p></blockquote></div>
+
+<!-- parse.cc -->
+   <p><a name="doc_002dassignin"></a>
+
+<div class="defun">
+— Built-in Function:  <b>assignin</b> (<var>context, varname, value</var>)<var><a name="index-assignin-553"></a></var><br>
+<blockquote><p>Assign <var>value</var> to <var>varname</var> in context <var>context</var>, which
+may be either <code>"base"</code> or <code>"caller"</code>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2007, 2008, 2009 -->
+<!-- John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Evaluation.html b/doc/interpreter/HTML/Evaluation.html
new file mode 100644
index 0000000..908c06e
--- /dev/null
+++ b/doc/interpreter/HTML/Evaluation.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>Evaluation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Expressions.html#Expressions" title="Expressions">
+<link rel="next" href="Statements.html#Statements" title="Statements">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Evaluation"></a>
+Next: <a rel="next" accesskey="n" href="Statements.html#Statements">Statements</a>,
+Previous: <a rel="previous" accesskey="p" href="Expressions.html#Expressions">Expressions</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">9 Evaluation</h2>
+
+<p>Normally, you evaluate expressions simply by typing them at the Octave
+prompt, or by asking Octave to interpret commands that you have saved in
+a file.
+
+   <p>Sometimes, you may find it necessary to evaluate an expression that has
+been computed and stored in a string, which is exactly what the
+<code>eval</code> function lets you do.
+
+<!-- parse.cc -->
+   <p><a name="doc_002deval"></a>
+
+<div class="defun">
+— Built-in Function:  <b>eval</b> (<var>try, catch</var>)<var><a name="index-eval-546"></a></var><br>
+<blockquote><p>Parse the string <var>try</var> and evaluate it as if it were an Octave
+program.  If that fails, evaluate the optional string <var>catch</var>. 
+The string <var>try</var> is evaluated in the current context,
+so any results remain available after <code>eval</code> returns.
+
+        <p>The following example makes the variable <var>a</var> with the approximate
+value 3.1416 available.
+
+     <pre class="example">          eval("a = acos(-1);");
+</pre>
+        <p>If an error occurs during the evaluation of <var>try</var> the <var>catch</var>
+string is evaluated, as the following example shows:
+
+     <pre class="example">          eval ('error ("This is a bad example");',
+                'printf ("This error occurred:\n%s\n", lasterr ());');
+               -| This error occurred:
+                  This is a bad example
+</pre>
+        </blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a>
+<li><a accesskey="2" href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context">Evaluation in a Different Context</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Example-Codes.html b/doc/interpreter/HTML/Example-Codes.html
new file mode 100644
index 0000000..afc0b03
--- /dev/null
+++ b/doc/interpreter/HTML/Example-Codes.html
@@ -0,0 +1,66 @@
+<html lang="en">
+<head>
+<title>Example Codes - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link rel="prev" href="Function-Support.html#Function-Support" title="Function Support">
+<link rel="next" href="Zeros-Treatment.html#Zeros-Treatment" title="Zeros Treatment">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Example-Codes"></a>
+Next: <a rel="next" accesskey="n" href="Zeros-Treatment.html#Zeros-Treatment">Zeros Treatment</a>,
+Previous: <a rel="previous" accesskey="p" href="Function-Support.html#Function-Support">Function Support</a>,
+Up: <a rel="up" accesskey="u" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">20.4 Some Examples of Usage</h3>
+
+<p>The following can be used to solve a linear system <code>A*x = b</code>
+using the pivoted LU factorization:
+<pre class="example">       [L, U, P] = lu (A); ## now L*U = P*A
+       x = U \ L \ P*b;
+</pre>
+   <p class="noindent">This is how you normalize columns of a matrix <var>X</var> to unit norm:
+<pre class="example">       s = norm (X, "columns");
+       X = diag (s) \ X;
+</pre>
+   <p class="noindent">The following expression is a way to efficiently calculate the sign of a
+permutation, given by a permutation vector <var>p</var>.  It will also work
+in earlier versions of Octave, but slowly.
+<pre class="example">       det (eye (length (p))(p, :))
+</pre>
+   <p class="noindent">Finally, here's how you solve a linear system <code>A*x = b</code>
+with Tikhonov regularization (ridge regression) using SVD (a skeleton only):
+<pre class="example">       m = rows (A); n = columns (A);
+       [U, S, V] = svd (A);
+       ## determine the regularization factor alpha
+       ## alpha = ...
+       ## transform to orthogonal basis
+       b = U'*b;
+       ## Use the standard formula, replacing A with S.
+       ## S is diagonal, so the following will be very fast and accurate.
+       x = (S'*S + alpha^2 * eye (n)) \ (S' * b);
+       ## transform to solution basis
+       x = V*x;
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Exception-and-Error-Handling-in-Oct_002dFiles.html b/doc/interpreter/HTML/Exception-and-Error-Handling-in-Oct_002dFiles.html
new file mode 100644
index 0000000..a5300f6
--- /dev/null
+++ b/doc/interpreter/HTML/Exception-and-Error-Handling-in-Oct_002dFiles.html
@@ -0,0 +1,126 @@
+<html lang="en">
+<head>
+<title>Exception and Error Handling in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles" title="Input Parameter Checking in Oct-Files">
+<link rel="next" href="Documentation-and-Test-of-Oct_002dFiles.html#Documentation-and-Test-of-Oct_002dFiles" title="Documentation and Test of Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Exception-and-Error-Handling-in-Oct-Files"></a>
+<a name="Exception-and-Error-Handling-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Documentation-and-Test-of-Oct_002dFiles.html#Documentation-and-Test-of-Oct_002dFiles">Documentation and Test of Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles">Input Parameter Checking in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.12 Exception and Error Handling in Oct-Files</h4>
+
+<p>Another important feature of Octave is its ability to react to the user
+typing <kbd>Control-C</kbd> even during calculations.  This ability is based on the
+C++ exception handler, where memory allocated by the C++ new/delete
+methods are automatically released when the exception is treated.  When
+writing an oct-file, to allow Octave to treat the user typing <kbd>Control-C</kbd>,
+the <code>OCTAVE_QUIT</code><!-- /@w --> macro is supplied.  For example
+
+<pre class="example">     for (octave_idx_type i = 0; i < a.nelem (); i++)
+       {
+         OCTAVE_QUIT;
+         b.elem(i) = 2. * a.elem(i);
+       }
+</pre>
+   <p>The presence of the <code>OCTAVE_QUIT</code><!-- /@w --> macro in the inner loop allows Octave to
+treat the user request with the <kbd>Control-C</kbd>.  Without this macro, the user
+must either wait for the function to return before the interrupt is
+processed, or press <kbd>Control-C</kbd> three times to force Octave to exit.
+
+   <p>The <code>OCTAVE_QUIT</code><!-- /@w --> macro does impose a very small speed penalty, and so for
+loops that are known to be small it might not make sense to include
+<code>OCTAVE_QUIT</code><!-- /@w -->.
+
+   <p>When creating an oct-file that uses an external libraries, the function
+might spend a significant portion of its time in the external
+library.  It is not generally possible to use the <code>OCTAVE_QUIT</code><!-- /@w --> macro in
+this case.  The alternative in this case is
+
+<pre class="example">     BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+     ...  some code that calls a "foreign" function ...
+     END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+</pre>
+   <p>The disadvantage of this is that if the foreign code allocates any
+memory internally, then this memory might be lost during an interrupt,
+without being deallocated.  Therefore, ideally Octave itself should
+allocate any memory that is needed by the foreign code, with either the
+fortran_vec method or the <code>OCTAVE_LOCAL_BUFFER</code><!-- /@w --> macro.
+
+   <p>The Octave unwind_protect mechanism (<a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a>)
+can also be used in oct-files.  In conjunction with the exception
+handling of Octave, it is important to enforce that certain code is run
+to allow variables, etc. to be restored even if an exception occurs.  An
+example of the use of this mechanism is
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     #include <octave/unwind-prot.h>
+     
+     void
+     err_hand (const char *fmt, ...)
+     {
+       // Do nothing!!
+     }
+     
+     DEFUN_DLD (unwinddemo, args, nargout, "Unwind Demo")
+     {
+       int nargin = args.length();
+       octave_value retval;
+       if (nargin < 2)
+         print_usage ();
+       else
+         {
+           NDArray a = args(0).array_value ();
+           NDArray b = args(1).array_value ();
+     
+           if (! error_state)
+             {
+               unwind_protect::begin_frame ("Funwinddemo");
+               unwind_protect_ptr 
+     	    (current_liboctave_warning_handler);
+               set_liboctave_warning_handler(err_hand);
+               retval = octave_value (quotient (a, b));
+               unwind_protect::run_frame ("Funwinddemo");
+             }
+         }
+       return retval;
+     }
+</pre></pre>
+   <p>As can be seen in the example
+
+<pre class="example">     unwinddemo (1, 0)
+      Inf
+     1 / 0
+      warning: division by zero
+        Inf
+</pre>
+   <p>The division by zero (and in fact all warnings) is disabled in the
+<code>unwinddemo</code> function.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Executable-Octave-Programs.html b/doc/interpreter/HTML/Executable-Octave-Programs.html
new file mode 100644
index 0000000..942d42f
--- /dev/null
+++ b/doc/interpreter/HTML/Executable-Octave-Programs.html
@@ -0,0 +1,123 @@
+<html lang="en">
+<head>
+<title>Executable Octave Programs - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="prev" href="Errors.html#Errors" title="Errors">
+<link rel="next" href="Comments.html#Comments" title="Comments">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Executable-Octave-Programs"></a>
+Next: <a rel="next" accesskey="n" href="Comments.html#Comments">Comments</a>,
+Previous: <a rel="previous" accesskey="p" href="Errors.html#Errors">Errors</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.6 Executable Octave Programs</h3>
+
+<p><a name="index-executable-scripts-153"></a><a name="index-scripts-154"></a><a name="index-batch-processing-155"></a><a name="index-self-contained-programs-156"></a><a name="index-program_002c-self-contained-157"></a><a name="index-g_t_0040samp_007b_0023_0021_007d-158"></a>
+Once you have learned Octave, you may want to write self-contained
+Octave scripts, using the ‘<samp><span class="samp">#!</span></samp>’ script mechanism.  You can do this
+on GNU systems and on many Unix systems <a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>.
+
+   <p>Self-contained Octave scripts are useful when you want to write a
+program which users can invoke without knowing that the program is
+written in the Octave language.  Octave scripts are also used for batch
+processing of data files.  Once an algorithm has been developed and tested
+in the interactive portion of Octave, it can be committed to an executable
+script and used again and again on new data files.
+
+   <p>As a trivial example of an executable Octave script, you might create a
+text file named <samp><span class="file">hello</span></samp>, containing the following lines:
+
+<pre class="example">     #! <var>octave-interpreter-name</var> -qf
+     # a sample Octave program
+     printf ("Hello, world!\n");
+</pre>
+   <p class="noindent">(where <var>octave-interpreter-name</var> should be replaced with the full
+path and name of your Octave binary).  Note that this will only work if
+‘<samp><span class="samp">#!</span></samp>’ appears at the very beginning of the file.  After making the
+file executable (with the <code>chmod</code> command on Unix systems), you can
+simply type:
+
+<pre class="example">     hello
+</pre>
+   <p class="noindent">at the shell, and the system will arrange to run Octave as if you had
+typed:
+
+<pre class="example">     octave hello
+</pre>
+   <p>The line beginning with ‘<samp><span class="samp">#!</span></samp>’ lists the full path and filename of an
+interpreter to be run, and an optional initial command line argument to
+pass to that interpreter.  The operating system then runs the
+interpreter with the given argument and the full argument list of the
+executed program.  The first argument in the list is the full file name
+of the Octave executable.  The rest of the argument list will either be
+options to Octave, or data files, or both.  The ‘<samp><span class="samp">-qf</span></samp>’ options are
+usually specified in stand-alone Octave programs to prevent them from
+printing the normal startup message, and to keep them from behaving
+differently depending on the contents of a particular user's
+<samp><span class="file">~/.octaverc</span></samp> file.  See <a href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">Invoking Octave from the Command Line</a>.
+
+   <p>Note that some operating systems may place a limit on the number of
+characters that are recognized after ‘<samp><span class="samp">#!</span></samp>’.  Also, the arguments
+appearing in a ‘<samp><span class="samp">#!</span></samp>’ line are parsed differently by various
+shells/systems.  The majority of them group all the arguments together in one
+string and pass it to the interpreter as a single argument.  In this case, the
+following script:
+
+<pre class="example">     #! <var>octave-interpreter-name</var> -q -f # comment
+</pre>
+   <p class="noindent">is equivalent to typing at the command line:
+
+<pre class="example">     octave "-q -f # comment"
+</pre>
+   <p class="noindent">which will produce an error message.  Unfortunately, it is
+not possible for Octave to determine whether it has been called from the
+command line or from a ‘<samp><span class="samp">#!</span></samp>’ script, so some care is needed when using the
+‘<samp><span class="samp">#!</span></samp>’ mechanism.
+
+   <p>Note that when Octave is started from an executable script, the built-in
+function <code>argv</code> returns a cell array containing the command line
+arguments passed to the executable Octave script, not the arguments
+passed to the Octave interpreter on the ‘<samp><span class="samp">#!</span></samp>’ line of the script. 
+For example, the following program will reproduce the command line that
+was used to execute the script, not ‘<samp><span class="samp">-qf</span></samp>’.
+
+<pre class="example">     #! /bin/octave -qf
+     printf ("%s", program_name ());
+     arg_list = argv ();
+     for i = 1:nargin
+       printf (" %s", arg_list{i});
+     endfor
+     printf ("\n");
+</pre>
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> The ‘<samp><span class="samp">#!</span></samp>’
+mechanism works on Unix systems derived from Berkeley Unix, System V
+Release 4, and some System V Release 3 systems.</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Explicit-and-Implicit-Conversions.html b/doc/interpreter/HTML/Explicit-and-Implicit-Conversions.html
new file mode 100644
index 0000000..c459b40
--- /dev/null
+++ b/doc/interpreter/HTML/Explicit-and-Implicit-Conversions.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Explicit and Implicit Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Usage.html#Basic-Usage" title="Basic Usage">
+<link rel="prev" href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices" title="Creating Permutation Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Explicit-and-Implicit-Conversions"></a>
+Previous: <a rel="previous" accesskey="p" href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices">Creating Permutation Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Usage.html#Basic-Usage">Basic Usage</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.1.3 Explicit and Implicit Conversions</h4>
+
+<p>The diagonal and permutation matrices are special objects in their own right.  A number
+of operations and built-in functions are defined for these matrices to use special,
+more efficient code than would be used for a full matrix in the same place.  Examples
+are given in further sections.
+
+   <p>To facilitate smooth mixing with full matrices, backward compatibility, and
+compatibility with <span class="sc">matlab</span>, the diagonal and permutation matrices should allow
+any operation that works on full matrices, and will either treat it specially,
+or implicitly convert themselves to full matrices.
+
+   <p>Instances include matrix indexing, except for extracting a single element or
+a leading submatrix, indexed assignment, or applying most mapper functions,
+such as <dfn>exp</dfn>.
+
+   <p>An explicit conversion to a full matrix can be requested using the built-in
+function <dfn>full</dfn>.  It should also be noted that the diagonal and permutation
+matrix objects will cache the result of the conversion after it is first
+requested (explicitly or implicitly), so that subsequent conversions will
+be very cheap.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Exponents-and-Logarithms.html b/doc/interpreter/HTML/Exponents-and-Logarithms.html
new file mode 100644
index 0000000..d6cf250
--- /dev/null
+++ b/doc/interpreter/HTML/Exponents-and-Logarithms.html
@@ -0,0 +1,240 @@
+<html lang="en">
+<head>
+<title>Exponents and Logarithms - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="next" href="Complex-Arithmetic.html#Complex-Arithmetic" title="Complex Arithmetic">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Exponents-and-Logarithms"></a>
+Next: <a rel="next" accesskey="n" href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.1 Exponents and Logarithms</h3>
+
+<!-- mappers.cc -->
+<p><a name="doc_002dexp"></a>
+
+<div class="defun">
+— Mapping Function:  <b>exp</b> (<var>x</var>)<var><a name="index-exp-1361"></a></var><br>
+<blockquote><p>Compute
+<code>e^x</code>
+for each element of <var>x</var>.  To compute the matrix
+exponential, see <a href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlog.html#doc_002dlog">log</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dexpm1"></a>
+
+<div class="defun">
+— Mapping Function:  <b>expm1</b> (<var>x</var>)<var><a name="index-expm1-1362"></a></var><br>
+<blockquote><p>Compute
+<code>exp (</code><var>x</var><code>) - 1</code>
+accurately in the neighborhood of zero. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dexp.html#doc_002dexp">exp</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dlog"></a>
+
+<div class="defun">
+— Mapping Function:  <b>log</b> (<var>x</var>)<var><a name="index-log-1363"></a></var><br>
+<blockquote><p>Compute the natural logarithm,
+<code>ln (</code><var>x</var><code>)</code>,
+for each element of <var>x</var>.  To compute the
+matrix logarithm, see <a href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dexp.html#doc_002dexp">exp</a>, <a href="doc_002dlog1p.html#doc_002dlog1p">log1p</a>, <a href="doc_002dlog2.html#doc_002dlog2">log2</a>, <a href="doc_002dlog10.html#doc_002dlog10">log10</a>, <a href="doc_002dlogspace.html#doc_002dlogspace">logspace</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dlog1p"></a>
+
+<div class="defun">
+— Mapping Function:  <b>log1p</b> (<var>x</var>)<var><a name="index-log1p-1364"></a></var><br>
+<blockquote><p>Compute
+<code>log (1 + </code><var>x</var><code>)</code>
+accurately in the neighborhood of zero. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlog.html#doc_002dlog">log</a>, <a href="doc_002dexp.html#doc_002dexp">exp</a>, <a href="doc_002dexpm1.html#doc_002dexpm1">expm1</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dlog10"></a>
+
+<div class="defun">
+— Mapping Function:  <b>log10</b> (<var>x</var>)<var><a name="index-log10-1365"></a></var><br>
+<blockquote><p>Compute the base-10 logarithm of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlog.html#doc_002dlog">log</a>, <a href="doc_002dlog2.html#doc_002dlog2">log2</a>, <a href="doc_002dlogspace.html#doc_002dlogspace">logspace</a>, <a href="doc_002dexp.html#doc_002dexp">exp</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dlog2"></a>
+
+<div class="defun">
+— Mapping Function:  <b>log2</b> (<var>x</var>)<var><a name="index-log2-1366"></a></var><br>
+— Mapping Function: [<var>f</var>, <var>e</var>] = <b>log2</b> (<var>x</var>)<var><a name="index-log2-1367"></a></var><br>
+<blockquote><p>Compute the base-2 logarithm of each element of <var>x</var>.
+
+        <p>If called with two output arguments, split <var>x</var> into
+binary mantissa and exponent so that
+<code>1/2 <= abs(f) < 1</code>
+and <var>e</var> is an integer.  If
+<code>x = 0</code>, <code>f = e = 0</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpow2.html#doc_002dpow2">pow2</a>, <a href="doc_002dlog.html#doc_002dlog">log</a>, <a href="doc_002dlog10.html#doc_002dlog10">log10</a>, <a href="doc_002dexp.html#doc_002dexp">exp</a>. 
+</p></blockquote></div>
+
+<!-- ./general/nextpow2.m -->
+   <p><a name="doc_002dnextpow2"></a>
+
+<div class="defun">
+— Function File:  <b>nextpow2</b> (<var>x</var>)<var><a name="index-nextpow2-1368"></a></var><br>
+<blockquote><p>If <var>x</var> is a scalar, return the first integer <var>n</var> such that
+2^n >= abs (x).
+
+        <p>If <var>x</var> is a vector, return <code>nextpow2 (length (</code><var>x</var><code>))</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpow2.html#doc_002dpow2">pow2</a>, <a href="doc_002dlog2.html#doc_002dlog2">log2</a>. 
+</p></blockquote></div>
+
+<!-- ./general/nthroot.m -->
+   <p><a name="doc_002dnthroot"></a>
+
+<div class="defun">
+— Function File:  <b>nthroot</b> (<var>x, n</var>)<var><a name="index-nthroot-1369"></a></var><br>
+<blockquote>
+        <p>Compute the n-th root of <var>x</var>, returning real results for real
+components of <var>x</var>.  For example
+
+     <pre class="example">          nthroot (-1, 3)
+           -1
+          (-1) ^ (1 / 3)
+           0.50000 - 0.86603i
+</pre>
+        </blockquote></div>
+
+<!-- ./specfun/pow2.m -->
+   <p><a name="doc_002dpow2"></a>
+
+<div class="defun">
+— Mapping Function:  <b>pow2</b> (<var>x</var>)<var><a name="index-pow2-1370"></a></var><br>
+— Mapping Function:  <b>pow2</b> (<var>f, e</var>)<var><a name="index-pow2-1371"></a></var><br>
+<blockquote><p>With one argument, computes
+2 .^ x
+for each element of <var>x</var>.
+
+        <p>With two arguments, returns
+f .* (2 .^ e). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlog2.html#doc_002dlog2">log2</a>, <a href="doc_002dnextpow2.html#doc_002dnextpow2">nextpow2</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/reallog.m -->
+   <p><a name="doc_002dreallog"></a>
+
+<div class="defun">
+— Function File:  <b>reallog</b> (<var>x</var>)<var><a name="index-reallog-1372"></a></var><br>
+<blockquote><p>Return the real-valued natural logarithm of each element of <var>x</var>.  Report
+an error if any element results in a complex return value. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlog.html#doc_002dlog">log</a>, <a href="doc_002drealpow.html#doc_002drealpow">realpow</a>, <a href="doc_002drealsqrt.html#doc_002drealsqrt">realsqrt</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/realpow.m -->
+   <p><a name="doc_002drealpow"></a>
+
+<div class="defun">
+— Function File:  <b>realpow</b> (<var>x, y</var>)<var><a name="index-realpow-1373"></a></var><br>
+<blockquote><p>Compute the real-valued, element-by-element power operator.  This is
+equivalent to <var>x</var><code> .^ </code><var>y</var><!-- /@w -->, except that <code>realpow</code>
+reports an error if any return value is complex. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dreallog.html#doc_002dreallog">reallog</a>, <a href="doc_002drealsqrt.html#doc_002drealsqrt">realsqrt</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/realsqrt.m -->
+   <p><a name="doc_002drealsqrt"></a>
+
+<div class="defun">
+— Function File:  <b>realsqrt</b> (<var>x</var>)<var><a name="index-realsqrt-1374"></a></var><br>
+<blockquote><p>Return the real-valued square root of each element of <var>x</var>.  Report an
+error if any element results in a complex return value. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsqrt.html#doc_002dsqrt">sqrt</a>, <a href="doc_002drealpow.html#doc_002drealpow">realpow</a>, <a href="doc_002dreallog.html#doc_002dreallog">reallog</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dsqrt"></a>
+
+<div class="defun">
+— Mapping Function:  <b>sqrt</b> (<var>x</var>)<var><a name="index-sqrt-1375"></a></var><br>
+<blockquote><p>Compute the square root of each element of <var>x</var>.  If <var>x</var> is negative,
+a complex result is returned.  To compute the matrix square root, see
+<a href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drealsqrt.html#doc_002drealsqrt">realsqrt</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Expressions-Involving-Diagonal-Matrices.html b/doc/interpreter/HTML/Expressions-Involving-Diagonal-Matrices.html
new file mode 100644
index 0000000..6fef89b
--- /dev/null
+++ b/doc/interpreter/HTML/Expressions-Involving-Diagonal-Matrices.html
@@ -0,0 +1,105 @@
+<html lang="en">
+<head>
+<title>Expressions Involving Diagonal Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Algebra.html#Matrix-Algebra" title="Matrix Algebra">
+<link rel="next" href="Expressions-Involving-Permutation-Matrices.html#Expressions-Involving-Permutation-Matrices" title="Expressions Involving Permutation Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Expressions-Involving-Diagonal-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Expressions-Involving-Permutation-Matrices.html#Expressions-Involving-Permutation-Matrices">Expressions Involving Permutation Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Algebra.html#Matrix-Algebra">Matrix Algebra</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.2.1 Expressions Involving Diagonal Matrices</h4>
+
+<p>Assume <var>D</var> is a diagonal matrix.  If <var>M</var> is a full matrix,
+then <code>D*M</code> will scale the rows of <var>M</var>.  That means,
+if <code>S = D*M</code>, then for each pair of indices
+i,j it holds
+<pre class="example">     S(i,j) = D(i,i) * M(i,j).
+</pre>
+   <p>Similarly, <code>M*D</code> will do a column scaling.
+
+   <p>The matrix <var>D</var> may also be rectangular, m-by-n where <code>m != n</code>. 
+If <code>m < n</code>, then the expression <code>D*M</code> is equivalent to
+<pre class="example">     D(:,1:m) * M(1:m,:),
+</pre>
+   <p>i.e., trailing <code>n-m</code> rows of <var>M</var> are ignored.  If <code>m > n</code>,
+then <code>D*M</code> is equivalent to
+<pre class="example">     [D(1:n,n) * M; zeros(m-n, columns (M))],
+</pre>
+   <p>i.e., null rows are appended to the result. 
+The situation for right-multiplication <code>M*D</code> is analogous.
+
+   <p>The expressions <code>D \ M</code> and <code>M / D</code> perform inverse scaling. 
+They are equivalent to solving a diagonal (or rectangular diagonal)
+in a least-squares minimum-norm sense.  In exact arithmetics, this is
+equivalent to multiplying by a pseudoinverse.  The pseudoinverse of
+a rectangular diagonal matrix is again a rectangular diagonal matrix
+with swapped dimensions, where each nonzero diagonal element is replaced
+by its reciprocal. 
+The matrix division algorithms do, in fact, use division rather than
+multiplication by reciprocals for better numerical accuracy; otherwise, they
+honor the above definition.  Note that a diagonal matrix is never truncated due
+to ill-conditioning; otherwise, it would not be much useful for scaling.  This
+is typically consistent with linear algebra needs.  A full matrix that only
+happens to be diagonal (an is thus not a special object) is of course treated
+normally.
+
+   <p>Multiplication and division by diagonal matrices works efficiently also when
+combined with sparse matrices, i.e., <code>D*S</code>, where <var>D</var> is a diagonal
+matrix and <var>S</var> is a sparse matrix scales the rows of the sparse matrix and
+returns a sparse matrix.  The expressions <code>S*D</code>, <code>D\S</code>, <code>S/D</code> work
+analogically.
+
+   <p>If <var>D1</var> and <var>D2</var> are both diagonal matrices, then the expressions
+<pre class="example">     D1 + D2
+     D1 - D2
+     D1 * D2
+     D1 / D2
+     D1 \ D2
+</pre>
+   <p>again produce diagonal matrices, provided that normal
+dimension matching rules are obeyed.  The relations used are same as described above.
+
+   <p>Also, a diagonal matrix <var>D</var> can be multiplied or divided by a scalar, or raised
+to a scalar power if it is square, producing diagonal matrix result in all cases.
+
+   <p>A diagonal matrix can also be transposed or conjugate-transposed, giving the expected
+result.  Extracting a leading submatrix of a diagonal matrix, i.e., <code>D(1:m,1:n)</code>,
+will produce a diagonal matrix, other indexing expressions will implicitly convert to
+full matrix.
+
+   <p>Adding a diagonal matrix to a full matrix only operates on the diagonal elements.  Thus,
+<pre class="example">     A = A + eps * eye (n)
+</pre>
+   <p>is an efficient method of augmenting the diagonal of a matrix.  Subtraction works
+analogically.
+
+   <p>When involved in expressions with other element-by-element operators, <code>.*</code>,
+<code>./</code>, <code>.\</code> or <code>.^</code>, an implicit conversion to full matrix will
+take place.  This is not always strictly necessary but chosen to facilitate
+better consistency with <span class="sc">matlab</span>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Expressions-Involving-Permutation-Matrices.html b/doc/interpreter/HTML/Expressions-Involving-Permutation-Matrices.html
new file mode 100644
index 0000000..3ba4d03
--- /dev/null
+++ b/doc/interpreter/HTML/Expressions-Involving-Permutation-Matrices.html
@@ -0,0 +1,73 @@
+<html lang="en">
+<head>
+<title>Expressions Involving Permutation Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Algebra.html#Matrix-Algebra" title="Matrix Algebra">
+<link rel="prev" href="Expressions-Involving-Diagonal-Matrices.html#Expressions-Involving-Diagonal-Matrices" title="Expressions Involving Diagonal Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Expressions-Involving-Permutation-Matrices"></a>
+Previous: <a rel="previous" accesskey="p" href="Expressions-Involving-Diagonal-Matrices.html#Expressions-Involving-Diagonal-Matrices">Expressions Involving Diagonal Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Algebra.html#Matrix-Algebra">Matrix Algebra</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.2.2 Expressions Involving Permutation Matrices</h4>
+
+<p>If <var>P</var> is a permutation matrix and <var>M</var> a matrix, the expression
+<code>P*M</code> will permute the rows of <var>M</var>.  Similarly, <code>M*P</code> will
+yield a column permutation. 
+Matrix division <code>P\M</code> and <code>M/P</code> can be used to do inverse permutation.
+
+   <p>The previously described syntax for creating permutation matrices can actually
+help an user to understand the connection between a permutation matrix and
+a permuting vector.  Namely, the following holds, where <code>I = eye (n)</code>
+is an identity matrix:
+<pre class="example">       I(p,:) * M = (I*M) (p,:) = M(p,:)
+</pre>
+   <p>Similarly,
+<pre class="example">       M * I(:,p) = (M*I) (:,p) = M(:,p)
+</pre>
+   <p>The expressions <code>I(p,:)</code> and <code>I(:,p)</code> are permutation matrices.
+
+   <p>A permutation matrix can be transposed (or conjugate-transposed, which is the
+same, because a permutation matrix is never complex), inverting the
+permutation, or equivalently, turning a row-permutation matrix into a
+column-permutation one.  For permutation matrices, transpose is equivalent to
+inversion, thus <code>P\M</code> is equivalent to <code>P'*M</code>.  Transpose of a
+permutation matrix (or inverse) is a constant-time operation, flipping only a
+flag internally, and thus the choice between the two above equivalent
+expressions for inverse permuting is completely up to the user's taste.
+
+   <p>Multiplication and division by permutation matrices works efficiently also when
+combined with sparse matrices, i.e., <code>P*S</code>, where <var>P</var> is a permutation
+matrix and <var>S</var> is a sparse matrix permutes the rows of the sparse matrix and
+returns a sparse matrix.  The expressions <code>S*P</code>, <code>P\S</code>, <code>S/P</code> work
+analogically.
+
+   <p>Two permutation matrices can be multiplied or divided (if their sizes match), performing
+a composition of permutations.  Also a permutation matrix can be indexed by a permutation
+vector (or two vectors), giving again a permutation matrix. 
+Any other operations do not generally yield a permutation matrix and will thus
+trigger the implicit conversion.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Expressions.html b/doc/interpreter/HTML/Expressions.html
new file mode 100644
index 0000000..725ade7
--- /dev/null
+++ b/doc/interpreter/HTML/Expressions.html
@@ -0,0 +1,60 @@
+<html lang="en">
+<head>
+<title>Expressions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Variables.html#Variables" title="Variables">
+<link rel="next" href="Evaluation.html#Evaluation" title="Evaluation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Expressions"></a>
+Next: <a rel="next" accesskey="n" href="Evaluation.html#Evaluation">Evaluation</a>,
+Previous: <a rel="previous" accesskey="p" href="Variables.html#Variables">Variables</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">8 Expressions</h2>
+
+<p><a name="index-expressions-447"></a>
+Expressions are the basic building block of statements in Octave.  An
+expression evaluates to a value, which you can print, test, store in a
+variable, pass to a function, or assign a new value to a variable with
+an assignment operator.
+
+   <p>An expression can serve as a statement on its own.  Most other kinds of
+statements contain one or more expressions which specify data to be
+operated on.  As in other languages, expressions in Octave include
+variables, array references, constants, and function calls, as well as
+combinations of these with various operators.
+
+<ul class="menu">
+<li><a accesskey="1" href="Index-Expressions.html#Index-Expressions">Index Expressions</a>
+<li><a accesskey="2" href="Calling-Functions.html#Calling-Functions">Calling Functions</a>
+<li><a accesskey="3" href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a>
+<li><a accesskey="4" href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a>
+<li><a accesskey="5" href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a>
+<li><a accesskey="6" href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a>
+<li><a accesskey="7" href="Increment-Ops.html#Increment-Ops">Increment Ops</a>
+<li><a accesskey="8" href="Operator-Precedence.html#Operator-Precedence">Operator Precedence</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Famous-Matrices.html b/doc/interpreter/HTML/Famous-Matrices.html
new file mode 100644
index 0000000..5c2ff04
--- /dev/null
+++ b/doc/interpreter/HTML/Famous-Matrices.html
@@ -0,0 +1,278 @@
+<html lang="en">
+<head>
+<title>Famous Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link rel="prev" href="Special-Utility-Matrices.html#Special-Utility-Matrices" title="Special Utility Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Famous-Matrices"></a>
+Previous: <a rel="previous" accesskey="p" href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>
+<hr>
+</div>
+
+<h3 class="section">16.5 Famous Matrices</h3>
+
+<p>The following functions return famous matrix forms.
+
+<!-- ./special-matrix/hadamard.m -->
+   <p><a name="doc_002dhadamard"></a>
+
+<div class="defun">
+— Function File:  <b>hadamard</b> (<var>n</var>)<var><a name="index-hadamard-1350"></a></var><br>
+<blockquote><p>Construct a Hadamard matrix <var>Hn</var> of size <var>n</var>-by-<var>n</var>.  The
+size <var>n</var> must be of the form <code>2 ^ </code><var>k</var><code> * </code><var>p</var> in which
+<var>p</var> is one of 1, 12, 20 or 28.  The returned matrix is normalized,
+meaning <code>Hn(:,1) == 1</code> and <code>H(1,:) == 1</code>.
+
+        <p>Some of the properties of Hadamard matrices are:
+
+          <ul>
+<li><code>kron (</code><var>Hm</var><code>, </code><var>Hn</var><code>)</code> is a Hadamard matrix of size
+<var>m</var>-by-<var>n</var>. 
+<li><code>Hn * Hn' == </code><var>n</var><code> * eye (</code><var>n</var><code>)</code>. 
+<li>The rows of <var>Hn</var> are orthogonal. 
+<li><code>det (</code><var>A</var><code>) <= abs(det (</code><var>Hn</var><code>))</code> for all <var>A</var> with
+<code>abs (</code><var>A</var><code> (</code><var>i</var><code>, </code><var>j</var><code>)) <= 1</code>. 
+<li>Multiply any row or column by -1 and still have a Hadamard matrix. 
+</ul>
+
+        </blockquote></div>
+
+<!-- ./special-matrix/hankel.m -->
+   <p><a name="doc_002dhankel"></a>
+
+<div class="defun">
+— Function File:  <b>hankel</b> (<var>c, r</var>)<var><a name="index-hankel-1351"></a></var><br>
+<blockquote><p>Return the Hankel matrix constructed given the first column <var>c</var>, and
+(optionally) the last row <var>r</var>.  If the last element of <var>c</var> is
+not the same as the first element of <var>r</var>, the last element of
+<var>c</var> is used.  If the second argument is omitted, it is assumed to
+be a vector of zeros with the same size as <var>c</var>.
+
+        <p>A Hankel matrix formed from an m-vector <var>c</var>, and an n-vector
+<var>r</var>, has the elements
+
+     <pre class="example">          H(i,j) = c(i+j-1),  i+j-1 <= m;
+          H(i,j) = r(i+j-m),  otherwise
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/hilb.m -->
+   <p><a name="doc_002dhilb"></a>
+
+<div class="defun">
+— Function File:  <b>hilb</b> (<var>n</var>)<var><a name="index-hilb-1352"></a></var><br>
+<blockquote><p>Return the Hilbert matrix of order <var>n</var>.  The
+i, j
+element of a Hilbert matrix is defined as
+
+     <pre class="example">          H (i, j) = 1 / (i + j - 1)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/invhilb.m -->
+   <p><a name="doc_002dinvhilb"></a>
+
+<div class="defun">
+— Function File:  <b>invhilb</b> (<var>n</var>)<var><a name="index-invhilb-1353"></a></var><br>
+<blockquote><p>Return the inverse of a Hilbert matrix of order <var>n</var>.  This can be
+computed exactly using
+     <pre class="example">          
+                      (i+j)         /n+i-1\  /n+j-1\   /i+j-2\ 2
+           A(i,j) = -1      (i+j-1)(       )(       ) (       )
+                                    \ n-j /  \ n-i /   \ i-2 /
+          
+                  = p(i) p(j) / (i+j-1)
+</pre>
+        <p>where
+     <pre class="example">                       k  /k+n-1\   /n\
+              p(k) = -1  (       ) (   )
+                          \ k-1 /   \k/
+</pre>
+        <p>The validity of this formula can easily be checked by expanding
+the binomial coefficients in both formulas as factorials.  It can
+be derived more directly via the theory of Cauchy matrices:
+see J. W. Demmel, Applied Numerical Linear Algebra, page 92.
+
+        <p>Compare this with the numerical calculation of <code>inverse (hilb (n))</code>,
+which suffers from the ill-conditioning of the Hilbert matrix, and the
+finite precision of your computer's floating point arithmetic. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/magic.m -->
+   <p><a name="doc_002dmagic"></a>
+
+<div class="defun">
+— Function File:  <b>magic</b> (<var>n</var>)<var><a name="index-magic-1354"></a></var><br>
+<blockquote>
+        <p>Create an <var>n</var>-by-<var>n</var> magic square.  Note that <code>magic
+(</code><var>2</var><code>)</code> is undefined since there is no 2-by-2 magic square.
+
+        </blockquote></div>
+
+<!-- ./special-matrix/pascal.m -->
+   <p><a name="doc_002dpascal"></a>
+
+<div class="defun">
+— Function File:  <b>pascal</b> (<var>n, t</var>)<var><a name="index-pascal-1355"></a></var><br>
+<blockquote>
+        <p>Return the Pascal matrix of order <var>n</var> if <var>t</var><code> = 0</code>. 
+<var>t</var> defaults to 0. Return lower triangular Cholesky factor of
+the Pascal matrix if <var>t</var><code> = 1</code>.  This matrix is its own
+inverse, that is <code>pascal (</code><var>n</var><code>, 1) ^ 2 == eye (</code><var>n</var><code>)</code>. 
+If <var>t</var><code> = -1</code>, return its absolute value.  This is the
+standard pascal triangle as a lower-triangular matrix. 
+If <var>t</var><code> = 2</code>, return a transposed and permuted version of
+<code>pascal (</code><var>n</var><code>, 1)</code>, which is the cube-root of the identity
+matrix.  That is <code>pascal (</code><var>n</var><code>, 2) ^ 3 == eye (</code><var>n</var><code>)</code>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>, <a href="doc_002dhadamard.html#doc_002dhadamard">hadamard</a>, <a href="doc_002dwilkinson.html#doc_002dwilkinson">wilkinson</a>, <a href="doc_002dcompan.html#doc_002dcompan">compan</a>, <a href="doc_002drosser.html#doc_002drosser">rosser</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/rosser.m -->
+   <p><a name="doc_002drosser"></a>
+
+<div class="defun">
+— Function File:  <b>rosser</b> ()<var><a name="index-rosser-1356"></a></var><br>
+<blockquote>
+        <p>Returns the Rosser matrix.  This is a difficult test case used to test
+eigenvalue algorithms.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>, <a href="doc_002dhadamard.html#doc_002dhadamard">hadamard</a>, <a href="doc_002dwilkinson.html#doc_002dwilkinson">wilkinson</a>, <a href="doc_002dcompan.html#doc_002dcompan">compan</a>, <a href="doc_002dpascal.html#doc_002dpascal">pascal</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/sylvester_matrix.m -->
+   <p><a name="doc_002dsylvester_005fmatrix"></a>
+
+<div class="defun">
+— Function File:  <b>sylvester_matrix</b> (<var>k</var>)<var><a name="index-sylvester_005fmatrix-1357"></a></var><br>
+<blockquote><p>Return the Sylvester matrix of order
+n = 2^k. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/toeplitz.m -->
+   <p><a name="doc_002dtoeplitz"></a>
+
+<div class="defun">
+— Function File:  <b>toeplitz</b> (<var>c, r</var>)<var><a name="index-toeplitz-1358"></a></var><br>
+<blockquote><p>Return the Toeplitz matrix constructed given the first column <var>c</var>,
+and (optionally) the first row <var>r</var>.  If the first element of <var>c</var>
+is not the same as the first element of <var>r</var>, the first element of
+<var>c</var> is used.  If the second argument is omitted, the first row is
+taken to be the same as the first column.
+
+        <p>A square Toeplitz matrix has the form:
+
+     <pre class="example">          c(0)  r(1)   r(2)  ...  r(n)
+          c(1)  c(0)   r(1)  ... r(n-1)
+          c(2)  c(1)   c(0)  ... r(n-2)
+           .     ,      ,   .      .
+           .     ,      ,     .    .
+           .     ,      ,       .  .
+          c(n) c(n-1) c(n-2) ...  c(0)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/vander.m -->
+   <p><a name="doc_002dvander"></a>
+
+<div class="defun">
+— Function File:  <b>vander</b> (<var>c, n</var>)<var><a name="index-vander-1359"></a></var><br>
+<blockquote><p>Return the Vandermonde matrix whose next to last column is <var>c</var>. 
+If <var>n</var> is specified, it determines the number of columns;
+otherwise, <var>n</var> is taken to be equal to the length of <var>c</var>.
+
+        <p>A Vandermonde matrix has the form:
+
+     <pre class="example">          c(1)^(n-1) ... c(1)^2  c(1)  1
+          c(2)^(n-1) ... c(2)^2  c(2)  1
+              .     .      .      .    .
+              .       .    .      .    .
+              .         .  .      .    .
+          c(n)^(n-1) ... c(n)^2  c(n)  1
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>. 
+</p></blockquote></div>
+
+<!-- ./special-matrix/wilkinson.m -->
+   <p><a name="doc_002dwilkinson"></a>
+
+<div class="defun">
+— Function File:  <b>wilkinson</b> (<var>n</var>)<var><a name="index-wilkinson-1360"></a></var><br>
+<blockquote>
+        <p>Return the Wilkinson matrix of order <var>n</var>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhankel.html#doc_002dhankel">hankel</a>, <a href="doc_002dvander.html#doc_002dvander">vander</a>, <a href="doc_002dsylvester_005fmatrix.html#doc_002dsylvester_005fmatrix">sylvester_matrix</a>, <a href="doc_002dhilb.html#doc_002dhilb">hilb</a>, <a href="doc_002dinvhilb.html#doc_002dinvhilb">invhilb</a>, <a href="doc_002dtoeplitz.html#doc_002dtoeplitz">toeplitz</a>, <a href="doc_002dhadamard.html#doc_002dhadamard">hadamard</a>, <a href="doc_002drosser.html#doc_002drosser">rosser</a>, <a href="doc_002dcompan.html#doc_002dcompan">compan</a>, <a href="doc_002dpascal.html#doc_002dpascal">pascal</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2007, 2008, -->
+<!-- 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Figure-Properties.html b/doc/interpreter/HTML/Figure-Properties.html
new file mode 100644
index 0000000..2c95fad
--- /dev/null
+++ b/doc/interpreter/HTML/Figure-Properties.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Figure Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Root-Figure-Properties.html#Root-Figure-Properties" title="Root Figure Properties">
+<link rel="next" href="Axes-Properties.html#Axes-Properties" title="Axes Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Figure-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Axes-Properties.html#Axes-Properties">Axes Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Root-Figure-Properties.html#Root-Figure-Properties">Root Figure Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.2 Figure Properties</h5>
+
+<p><a name="index-figure-properties-1190"></a>
+     <dl>
+<dt><code>nextplot</code><dd>May be one of
+          <dl>
+<dt><code>"new"</code><br><dt><code>"add"</code><br><dt><code>"replace"</code><br><dt><code>"replacechildren"</code><dd></dl>
+
+     <br><dt><code>closerequestfcn</code><dd>Handle of function to call when a figure is closed.
+
+     <br><dt><code>currentaxes</code><dd>Index to graphics object of current axes.
+
+     <br><dt><code>colormap</code><dd>An N-by-3 matrix containing the color map for the current axes.
+
+     <br><dt><code>visible</code><dd>Either <code>"on"</code> or <code>"off"</code> to toggle display of the figure.
+
+     <br><dt><code>paperorientation</code><dd>Indicates the orientation for printing.  Either <code>"landscape"</code> or
+<code>"portrait"</code>. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/File-Archiving-Utilities.html b/doc/interpreter/HTML/File-Archiving-Utilities.html
new file mode 100644
index 0000000..f50bfa8
--- /dev/null
+++ b/doc/interpreter/HTML/File-Archiving-Utilities.html
@@ -0,0 +1,199 @@
+<html lang="en">
+<head>
+<title>File Archiving Utilities - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Filesystem-Utilities.html#Filesystem-Utilities" title="Filesystem Utilities">
+<link rel="next" href="Networking-Utilities.html#Networking-Utilities" title="Networking Utilities">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="File-Archiving-Utilities"></a>
+Next: <a rel="next" accesskey="n" href="Networking-Utilities.html#Networking-Utilities">Networking Utilities</a>,
+Previous: <a rel="previous" accesskey="p" href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.3 File Archiving Utilities</h3>
+
+<!-- ./miscellaneous/bunzip2.m -->
+<p><a name="doc_002dbunzip2"></a>
+
+<div class="defun">
+— Function File:  <b>bunzip2</b> (<var>bzfile, dir</var>)<var><a name="index-bunzip2-2349"></a></var><br>
+<blockquote><p>Unpack the bzip2 archive <var>bzfile</var> to the directory <var>dir</var>.  If
+<var>dir</var> is not specified, it defaults to the current directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunpack.html#doc_002dunpack">unpack</a>, <a href="doc_002dbzip2.html#doc_002dbzip2">bzip2</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>, <a href="doc_002duntar.html#doc_002duntar">untar</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dunzip.html#doc_002dunzip">unzip</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/gzip.m -->
+   <p><a name="doc_002dgzip"></a>
+
+<div class="defun">
+— Function File: <var>entries</var> = <b>gzip</b> (<var>files</var>)<var><a name="index-gzip-2350"></a></var><br>
+— Function File: <var>entries</var> = <b>gzip</b> (<var>files, outdir</var>)<var><a name="index-gzip-2351"></a></var><br>
+<blockquote><p>Compress the list of files and/or directories specified in <var>files</var>. 
+Each file is compressed separately and a new file with a '.gz' extension
+is created.  The original files are not touched.  Existing compressed
+files are silently overwritten.  If <var>outdir</var> is defined the compressed
+versions of the files are placed in this directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dbzip2.html#doc_002dbzip2">bzip2</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/gunzip.m -->
+   <p><a name="doc_002dgunzip"></a>
+
+<div class="defun">
+— Function File:  <b>gunzip</b> (<var>gzfile, dir</var>)<var><a name="index-gunzip-2352"></a></var><br>
+<blockquote><p>Unpack the gzip archive <var>gzfile</var> to the directory <var>dir</var>.  If
+<var>dir</var> is not specified, it defaults to the current directory.  If
+the <var>gzfile</var> is a directory, all files in the directory will be
+recursively gunzipped. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunpack.html#doc_002dunpack">unpack</a>, <a href="doc_002dbunzip2.html#doc_002dbunzip2">bunzip2</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>, <a href="doc_002duntar.html#doc_002duntar">untar</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dunzip.html#doc_002dunzip">unzip</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/tar.m -->
+   <p><a name="doc_002dtar"></a>
+
+<div class="defun">
+— Function File: <var>entries</var> = <b>tar</b> (<var>tarfile, files, root</var>)<var><a name="index-tar-2353"></a></var><br>
+<blockquote><p>Pack <var>files</var> <var>files</var> into the TAR archive <var>tarfile</var>.  The
+list of files must be a string or a cell array of strings.
+
+        <p>The optional argument <var>root</var> changes the relative path of <var>files</var>
+from the current directory.
+
+        <p>If an output argument is requested the entries in the archive are
+returned in a cell array. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002duntar.html#doc_002duntar">untar</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dunzip.html#doc_002dunzip">unzip</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/untar.m -->
+   <p><a name="doc_002duntar"></a>
+
+<div class="defun">
+— Function File:  <b>untar</b> (<var>tarfile, dir</var>)<var><a name="index-untar-2354"></a></var><br>
+<blockquote><p>Unpack the TAR archive <var>tarfile</var> to the directory <var>dir</var>. 
+If <var>dir</var> is not specified, it defaults to the current directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunpack.html#doc_002dunpack">unpack</a>, <a href="doc_002dbunzip2.html#doc_002dbunzip2">bunzip2</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dunzip.html#doc_002dunzip">unzip</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/zip.m -->
+   <p><a name="doc_002dzip"></a>
+
+<div class="defun">
+— Function File: <var>entries</var> = <b>zip</b> (<var>zipfile, files</var>)<var><a name="index-zip-2355"></a></var><br>
+— Function File: <var>entries</var> = <b>zip</b> (<var>zipfile, files, rootdir</var>)<var><a name="index-zip-2356"></a></var><br>
+<blockquote><p>Compress the list of files and/or directories specified in <var>files</var>
+into the archive <var>zipfiles</var> in the same directory.  If <var>rootdir</var>
+is defined the <var>files</var> is located relative to <var>rootdir</var> rather
+than the current directory
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunzip.html#doc_002dunzip">unzip</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/unzip.m -->
+   <p><a name="doc_002dunzip"></a>
+
+<div class="defun">
+— Function File:  <b>unzip</b> (<var>zipfile, dir</var>)<var><a name="index-unzip-2357"></a></var><br>
+<blockquote><p>Unpack the ZIP archive <var>zipfile</var> to the directory <var>dir</var>. 
+If <var>dir</var> is not specified, it defaults to the current directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunpack.html#doc_002dunpack">unpack</a>, <a href="doc_002dbunzip2.html#doc_002dbunzip2">bunzip2</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>, <a href="doc_002duntar.html#doc_002duntar">untar</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/pack.m -->
+   <p><a name="doc_002dpack"></a>
+
+<div class="defun">
+— Function File:  <b>pack</b> ()<var><a name="index-pack-2358"></a></var><br>
+<blockquote><p>This function is provided for compatibility with <span class="sc">matlab</span>, but it
+doesn't actually do anything. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/unpack.m -->
+   <p><a name="doc_002dunpack"></a>
+
+<div class="defun">
+— Function File: <var>files</var> = <b>unpack</b> (<var>file, dir</var>)<var><a name="index-unpack-2359"></a></var><br>
+— Function File: <var>files</var> = <b>unpack</b> (<var>file, dir, filetype</var>)<var><a name="index-unpack-2360"></a></var><br>
+<blockquote><p>Unpack the archive <var>file</var> based on its extension to the directory
+<var>dir</var>.  If <var>file</var> is a cellstr, then all files will be
+handled individually.  If <var>dir</var> is not specified, it defaults to
+the current directory.  It returns a list of <var>files</var>
+unpacked.  If a directory is in the file list, then the
+<var>filetype</var> to unpack must also be specified.
+
+        <p>The <var>files</var> includes the entire path to the output files. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbunzip2.html#doc_002dbunzip2">bunzip2</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>, <a href="doc_002duntar.html#doc_002duntar">untar</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dgunzip.html#doc_002dgunzip">gunzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dunzip.html#doc_002dunzip">unzip</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/bzip2.m -->
+   <p><a name="doc_002dbzip2"></a>
+
+<div class="defun">
+— Function File: <var>entries</var> = <b>bzip2</b> (<var>files</var>)<var><a name="index-bzip2-2361"></a></var><br>
+— Function File: <var>entries</var> = <b>bzip2</b> (<var>files, outdir</var>)<var><a name="index-bzip2-2362"></a></var><br>
+<blockquote><p>Compress the list of files specified in <var>files</var>. 
+Each file is compressed separately and a new file with a '.bz2' extension
+is created.  The original files are not touched.  Existing compressed files
+are silently overwritten.If <var>outdir</var> is defined the compressed versions
+of the files are placed in this directory. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbunzip2.html#doc_002dbunzip2">bunzip2</a>, <a href="doc_002dgzip.html#doc_002dgzip">gzip</a>, <a href="doc_002dzip.html#doc_002dzip">zip</a>, <a href="doc_002dtar.html#doc_002dtar">tar</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/File-Positioning.html b/doc/interpreter/HTML/File-Positioning.html
new file mode 100644
index 0000000..b2910ab
--- /dev/null
+++ b/doc/interpreter/HTML/File-Positioning.html
@@ -0,0 +1,127 @@
+<html lang="en">
+<head>
+<title>File Positioning - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="EOF-and-Errors.html#EOF-and-Errors" title="EOF and Errors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="File-Positioning"></a>
+Previous: <a rel="previous" accesskey="p" href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.19 File Positioning</h4>
+
+<p>Three functions are available for setting and determining the position of
+the file pointer for a given file.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dftell"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ftell</b> (<var>fid</var>)<var><a name="index-ftell-809"></a></var><br>
+<blockquote><p>Return the position of the file pointer as the number of characters
+from the beginning of the file <var>fid</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfseek.html#doc_002dfseek">fseek</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfseek"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fseek</b> (<var>fid, offset, origin</var>)<var><a name="index-fseek-810"></a></var><br>
+<blockquote><p>Set the file pointer to any location within the file <var>fid</var>.
+
+        <p>The pointer is positioned <var>offset</var> characters from the <var>origin</var>,
+which may be one of the predefined variables <code>SEEK_CUR</code><!-- /@w --> (current
+position), <code>SEEK_SET</code><!-- /@w --> (beginning), or <code>SEEK_END</code><!-- /@w --> (end of
+file) or strings "cof", "bof" or "eof".  If <var>origin</var> is omitted,
+<code>SEEK_SET</code><!-- /@w --> is assumed.  The offset must be zero, or a value returned
+by <code>ftell</code> (in which case <var>origin</var> must be <code>SEEK_SET</code><!-- /@w -->).
+
+        <p>Return 0 on success and -1 on error. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dftell.html#doc_002dftell">ftell</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dSEEK_005fSET"></a>
+
+<div class="defun">
+— Built-in Function:  <b>SEEK_SET</b> ()<var><a name="index-SEEK_005fSET-811"></a></var><br>
+— Built-in Function:  <b>SEEK_CUR</b> ()<var><a name="index-SEEK_005fCUR-812"></a></var><br>
+— Built-in Function:  <b>SEEK_END</b> ()<var><a name="index-SEEK_005fEND-813"></a></var><br>
+<blockquote><p>Return the value required to request that <code>fseek</code> perform
+one of the following actions:
+          <dl>
+<dt><code>SEEK_SET</code><dd>Position file relative to the beginning.
+
+          <br><dt><code>SEEK_CUR</code><dd>Position file relative to the current position.
+
+          <br><dt><code>SEEK_END</code><dd>Position file relative to the end. 
+</dl>
+        </p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfrewind"></a>
+
+<div class="defun">
+— Built-in Function:  <b>frewind</b> (<var>fid</var>)<var><a name="index-frewind-814"></a></var><br>
+<blockquote><p>Move the file pointer to the beginning of the file <var>fid</var>, returning
+0 for success, and -1 if an error was encountered.  It is equivalent to
+<code>fseek (</code><var>fid</var><code>, 0, SEEK_SET)</code>. 
+</p></blockquote></div>
+
+   <p>The following example stores the current file position in the variable
+<code>marker</code>, moves the pointer to the beginning of the file, reads
+four characters, and then returns to the original position.
+
+<pre class="example">     marker = ftell (myfile);
+     frewind (myfile);
+     fourch = fgets (myfile, 4);
+     fseek (myfile, marker, SEEK_SET);
+</pre>
+   <!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, -->
+<!-- 2006, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Filesystem-Utilities.html b/doc/interpreter/HTML/Filesystem-Utilities.html
new file mode 100644
index 0000000..c51935b
--- /dev/null
+++ b/doc/interpreter/HTML/Filesystem-Utilities.html
@@ -0,0 +1,597 @@
+<html lang="en">
+<head>
+<title>Filesystem Utilities - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Timing-Utilities.html#Timing-Utilities" title="Timing Utilities">
+<link rel="next" href="File-Archiving-Utilities.html#File-Archiving-Utilities" title="File Archiving Utilities">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Filesystem-Utilities"></a>
+Next: <a rel="next" accesskey="n" href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a>,
+Previous: <a rel="previous" accesskey="p" href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.2 Filesystem Utilities</h3>
+
+<p>Octave includes the following functions for renaming and deleting files,
+creating, deleting, and reading directories, and for getting information
+about the status of files.
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002drename"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>rename</b> (<var>old, new</var>)<var><a name="index-rename-2311"></a></var><br>
+<blockquote><p>Change the name of file <var>old</var> to <var>new</var>.
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dls.html#doc_002dls">ls</a>, <a href="doc_002ddir.html#doc_002ddir">dir</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dlink"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>link</b> (<var>old, new</var>)<var><a name="index-link-2312"></a></var><br>
+<blockquote><p>Create a new link (also known as a hard link) to an existing file.
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsymlink.html#doc_002dsymlink">symlink</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dsymlink"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>symlink</b> (<var>old, new</var>)<var><a name="index-symlink-2313"></a></var><br>
+<blockquote><p>Create a symbolic link <var>new</var> which contains the string <var>old</var>.
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlink.html#doc_002dlink">link</a>, <a href="doc_002dreadlink.html#doc_002dreadlink">readlink</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dreadlink"></a>
+
+<div class="defun">
+— Built-in Function: [<var>result</var>, <var>err</var>, <var>msg</var>] = <b>readlink</b> (<var>symlink</var>)<var><a name="index-readlink-2314"></a></var><br>
+<blockquote><p>Read the value of the symbolic link <var>symlink</var>.
+
+        <p>If successful, <var>result</var> contains the contents of the symbolic link
+<var>symlink</var>, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlink.html#doc_002dlink">link</a>, <a href="doc_002dsymlink.html#doc_002dsymlink">symlink</a>. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dunlink"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>unlink</b> (<var>file</var>)<var><a name="index-unlink-2315"></a></var><br>
+<blockquote><p>Delete the file named <var>file</var>.
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dreaddir"></a>
+
+<div class="defun">
+— Built-in Function: [<var>files</var>, <var>err</var>, <var>msg</var>] = <b>readdir</b> (<var>dir</var>)<var><a name="index-readdir-2316"></a></var><br>
+<blockquote><p>Return names of the files in the directory <var>dir</var> as a cell array of
+strings.  If an error occurs, return an empty cell array in <var>files</var>.
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddir.html#doc_002ddir">dir</a>, <a href="doc_002dglob.html#doc_002dglob">glob</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dmkdir"></a>
+
+<div class="defun">
+— Built-in Function: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>mkdir</b> (<var>dir</var>)<var><a name="index-mkdir-2317"></a></var><br>
+— Built-in Function: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>mkdir</b> (<var>parent, dir</var>)<var><a name="index-mkdir-2318"></a></var><br>
+<blockquote><p>Create a directory named <var>dir</var> in the directory <var>parent</var>.
+
+        <p>If successful, <var>status</var> is 1, with <var>msg</var> and <var>msgid</var> empty
+character strings.  Otherwise, <var>status</var> is 0, <var>msg</var> contains a
+system-dependent error message, and <var>msgid</var> contains a unique
+message identifier. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drmdir.html#doc_002drmdir">rmdir</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002drmdir"></a>
+
+<div class="defun">
+— Built-in Function: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>rmdir</b> (<var>dir</var>)<var><a name="index-rmdir-2319"></a></var><br>
+— Built-in Function: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>rmdir</b> (<var>dir, </var><code>"s"</code>)<var><a name="index-rmdir-2320"></a></var><br>
+<blockquote><p>Remove the directory named <var>dir</var>.
+
+        <p>If successful, <var>status</var> is 1, with <var>msg</var> and <var>msgid</var> empty
+character strings.  Otherwise, <var>status</var> is 0, <var>msg</var> contains a
+system-dependent error message, and <var>msgid</var> contains a unique
+message identifier.
+
+        <p>If the optional second parameter is supplied with value <code>"s"</code>,
+recursively remove all subdirectories as well. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmkdir.html#doc_002dmkdir">mkdir</a>, <a href="doc_002dconfirm_005frecursive_005frmdir.html#doc_002dconfirm_005frecursive_005frmdir">confirm_recursive_rmdir</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dconfirm_005frecursive_005frmdir"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>confirm_recursive_rmdir</b> ()<var><a name="index-confirm_005frecursive_005frmdir-2321"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>confirm_recursive_rmdir</b> (<var>new_val</var>)<var><a name="index-confirm_005frecursive_005frmdir-2322"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave
+will ask for confirmation before recursively removing a directory tree. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dmkfifo"></a>
+
+<div class="defun">
+— Built-in Function: [<var>err</var>, <var>msg</var>] = <b>mkfifo</b> (<var>name, mode</var>)<var><a name="index-mkfifo-2323"></a></var><br>
+<blockquote><p>Create a <var>fifo</var> special file named <var>name</var> with file mode <var>mode</var>
+
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dumask"></a>
+
+<div class="defun">
+— Built-in Function:  <b>umask</b> (<var>mask</var>)<var><a name="index-umask-2324"></a></var><br>
+<blockquote><p>Set the permission mask for file creation.  The parameter <var>mask</var>
+is an integer, interpreted as an octal number.  If successful,
+returns the previous value of the mask (as an integer to be
+interpreted as an octal number); otherwise an error message is printed. 
+</p></blockquote></div>
+
+   <p><a name="doc_002dlstat"></a><!-- syscalls.cc -->
+<a name="doc_002dstat"></a>
+
+<div class="defun">
+— Built-in Function: [<var>info</var>, <var>err</var>, <var>msg</var>] = <b>stat</b> (<var>file</var>)<var><a name="index-stat-2325"></a></var><br>
+— Built-in Function: [<var>info</var>, <var>err</var>, <var>msg</var>] = <b>lstat</b> (<var>file</var>)<var><a name="index-lstat-2326"></a></var><br>
+<blockquote><p>Return a structure <var>s</var> containing the following information about
+<var>file</var>.
+
+          <dl>
+<dt><code>dev</code><dd>ID of device containing a directory entry for this file.
+
+          <br><dt><code>ino</code><dd>File number of the file.
+
+          <br><dt><code>mode</code><dd>File mode, as an integer.  Use the functions <code>S_ISREG</code><!-- /@w -->,
+<code>S_ISDIR</code><!-- /@w -->, <code>S_ISCHR</code><!-- /@w -->, <code>S_ISBLK</code><!-- /@w -->, <code>S_ISFIFO</code><!-- /@w -->,
+<code>S_ISLNK</code><!-- /@w -->, or <code>S_ISSOCK</code><!-- /@w --> to extract information from this
+value.
+
+          <br><dt><code>modestr</code><dd>File mode, as a string of ten letters or dashes as would be returned by
+<kbd>ls -l</kbd>.
+
+          <br><dt><code>nlink</code><dd>Number of links.
+
+          <br><dt><code>uid</code><dd>User ID of file's owner.
+
+          <br><dt><code>gid</code><dd>Group ID of file's group.
+
+          <br><dt><code>rdev</code><dd>ID of device for block or character special files.
+
+          <br><dt><code>size</code><dd>Size in bytes.
+
+          <br><dt><code>atime</code><dd>Time of last access in the same form as time values returned from
+<code>time</code>.  See <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a>.
+
+          <br><dt><code>mtime</code><dd>Time of last modification in the same form as time values returned from
+<code>time</code>.  See <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a>.
+
+          <br><dt><code>ctime</code><dd>Time of last file status change in the same form as time values
+returned from <code>time</code>.  See <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a>.
+
+          <br><dt><code>blksize</code><dd>Size of blocks in the file.
+
+          <br><dt><code>blocks</code><dd>Number of blocks allocated for file. 
+</dl>
+
+        <p>If the call is successful <var>err</var> is 0 and <var>msg</var> is an empty
+string.  If the file does not exist, or some other error occurs, <var>s</var>
+is an empty matrix, <var>err</var> is −1, and <var>msg</var> contains the
+corresponding system error message.
+
+        <p>If <var>file</var> is a symbolic link, <code>stat</code> will return information
+about the actual file that is referenced by the link.  Use <code>lstat</code>
+if you want information about the symbolic link itself.
+
+        <p>For example,
+
+     <pre class="example">          [s, err, msg] = stat ("/vmlinuz")
+                 s =
+                  {
+                    atime = 855399756
+                    rdev = 0
+                    ctime = 847219094
+                    uid = 0
+                    size = 389218
+                    blksize = 4096
+                    mtime = 847219094
+                    gid = 6
+                    nlink = 1
+                    blocks = 768
+                    mode = -rw-r--r--
+                    modestr = -rw-r--r--
+                    ino = 9316
+                    dev = 2049
+                  }
+                err = 0
+                msg =
+</pre>
+        </blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dfstat"></a>
+
+<div class="defun">
+— Built-in Function: [<var>info</var>, <var>err</var>, <var>msg</var>] = <b>fstat</b> (<var>fid</var>)<var><a name="index-fstat-2327"></a></var><br>
+<blockquote><p>Return information about the open file <var>fid</var>.  See <code>stat</code>
+for a description of the contents of <var>info</var>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/fileattrib.m -->
+   <p><a name="doc_002dfileattrib"></a>
+
+<div class="defun">
+— Function File: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>fileattrib</b> (<var>file</var>)<var><a name="index-fileattrib-2328"></a></var><br>
+<blockquote><p>Return information about <var>file</var>.
+
+        <p>If successful, <var>status</var> is 1, with <var>result</var> containing a
+structure with the following fields:
+
+          <dl>
+<dt><code>Name</code><dd>Full name of <var>file</var>. 
+<br><dt><code>archive</code><dd>True if <var>file</var> is an archive (Windows). 
+<br><dt><code>system</code><dd>True if <var>file</var> is a system file (Windows). 
+<br><dt><code>hidden</code><dd>True if <var>file</var> is a hidden file (Windows). 
+<br><dt><code>directory</code><dd>True if <var>file</var> is a directory. 
+<br><dt><code>UserRead</code><dt><code>GroupRead</code><dt><code>OtherRead</code><dd>True if the user (group; other users) has read permission for
+<var>file</var>. 
+<br><dt><code>UserWrite</code><dt><code>GroupWrite</code><dt><code>OtherWrite</code><dd>True if the user (group; other users) has write permission for
+<var>file</var>. 
+<br><dt><code>UserExecute</code><dt><code>GroupExecute</code><dt><code>OtherExecute</code><dd>True if the user (group; other users) has execute permission for
+<var>file</var>. 
+</dl>
+        If an attribute does not apply (i.e., archive on a Unix system) then
+the field is set to NaN.
+
+        <p>With no input arguments, return information about the current
+directory.
+
+        <p>If <var>file</var> contains globbing characters, return information about
+all the matching files. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dglob.html#doc_002dglob">glob</a>. 
+</p></blockquote></div>
+
+<!-- ./general/isdir.m -->
+   <p><a name="doc_002disdir"></a>
+
+<div class="defun">
+— Function File:  <b>isdir</b> (<var>f</var>)<var><a name="index-isdir-2329"></a></var><br>
+<blockquote><p>Return true if <var>f</var> is a directory. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dglob"></a>
+
+<div class="defun">
+— Built-in Function:  <b>glob</b> (<var>pattern</var>)<var><a name="index-glob-2330"></a></var><br>
+<blockquote><p>Given an array of strings (as a char array or a cell array) in
+<var>pattern</var>, return a cell array of file names that match any of
+them, or an empty cell array if no patterns match.  Tilde expansion
+is performed on each of the patterns before looking for matching file
+names.  For example,
+
+     <pre class="example">          glob ("/vm*")
+                "/vmlinuz"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddir.html#doc_002ddir">dir</a>, <a href="doc_002dls.html#doc_002dls">ls</a>, <a href="doc_002dstat.html#doc_002dstat">stat</a>, <a href="doc_002dreaddir.html#doc_002dreaddir">readdir</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dfnmatch"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fnmatch</b> (<var>pattern, string</var>)<var><a name="index-fnmatch-2331"></a></var><br>
+<blockquote><p>Return 1 or zero for each element of <var>string</var> that matches any of
+the elements of the string array <var>pattern</var>, using the rules of
+filename pattern matching.  For example,
+
+     <pre class="example">          fnmatch ("a*b", {"ab"; "axyzb"; "xyzab"})
+                [ 1; 1; 0 ]
+</pre>
+        </blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dfile_005fin_005fpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>file_in_path</b> (<var>path, file</var>)<var><a name="index-file_005fin_005fpath-2332"></a></var><br>
+— Built-in Function:  <b>file_in_path</b> (<var>path, file, "all"</var>)<var><a name="index-file_005fin_005fpath-2333"></a></var><br>
+<blockquote><p>Return the absolute name of <var>file</var> if it can be found in
+<var>path</var>.  The value of <var>path</var> should be a colon-separated list of
+directories in the format described for <code>path</code>.  If no file
+is found, return an empty matrix.  For example,
+
+     <pre class="example">          file_in_path (EXEC_PATH, "sh")
+                "/bin/sh"
+</pre>
+        <p>If the second argument is a cell array of strings, search each
+directory of the path for element of the cell array and return
+the first that matches.
+
+        <p>If the third optional argument <code>"all"</code> is supplied, return
+a cell array containing the list of all files that have the same
+name in the path.  If no files are found, return an empty cell array. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfile_005fin_005floadpath.html#doc_002dfile_005fin_005floadpath">file_in_loadpath</a>. 
+</p></blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dtilde_005fexpand"></a>
+
+<div class="defun">
+— Built-in Function:  <b>tilde_expand</b> (<var>string</var>)<var><a name="index-tilde_005fexpand-2334"></a></var><br>
+<blockquote><p>Performs tilde expansion on <var>string</var>.  If <var>string</var> begins with a
+tilde character, (‘<samp><span class="samp">~</span></samp>’), all of the characters preceding the first
+slash (or all characters, if there is no slash) are treated as a
+possible user name, and the tilde and the following characters up to the
+slash are replaced by the home directory of the named user.  If the
+tilde is followed immediately by a slash, the tilde is replaced by the
+home directory of the user running Octave.  For example,
+
+     <pre class="example">          tilde_expand ("~joeuser/bin")
+                "/home/joeuser/bin"
+          tilde_expand ("~/bin")
+                "/home/jwe/bin"
+</pre>
+        </blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dcanonicalize_005ffile_005fname"></a>
+
+<div class="defun">
+— Built-in Function: [<var>cname</var>, <var>status</var>, <var>msg</var>] <b>canonicalize_file_name</b> (<var>name</var>)<var><a name="index-canonicalize_005ffile_005fname-2335"></a></var><br>
+<blockquote><p>Return the canonical name of file <var>name</var>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/movefile.m -->
+   <p><a name="doc_002dmovefile"></a>
+
+<div class="defun">
+— Function File: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>movefile</b> (<var>f1, f2</var>)<var><a name="index-movefile-2336"></a></var><br>
+<blockquote><p>Move the file <var>f1</var> to the new name <var>f2</var>.  The name <var>f1</var>
+may contain globbing patterns.  If <var>f1</var> expands to multiple file
+names, <var>f2</var> must be a directory.
+
+        <p>If successful, <var>status</var> is 1, with <var>msg</var> and <var>msgid</var> empty\n\
+character strings.  Otherwise, <var>status</var> is 0, <var>msg</var> contains a\n\
+system-dependent error message, and <var>msgid</var> contains a unique\n\
+message identifier.\n\
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dglob.html#doc_002dglob">glob</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/copyfile.m -->
+   <p><a name="doc_002dcopyfile"></a>
+
+<div class="defun">
+— Function File: [<var>status</var>, <var>msg</var>, <var>msgid</var>] = <b>copyfile</b> (<var>f1, f2, force</var>)<var><a name="index-copyfile-2337"></a></var><br>
+<blockquote><p>Copy the file <var>f1</var> to the new name <var>f2</var>.  The name <var>f1</var>
+may contain globbing patterns.  If <var>f1</var> expands to multiple file
+names, <var>f2</var> must be a directory.  If <var>force</var> is given and equals
+the string "f" the copy operation will be forced.
+
+        <p>If successful, <var>status</var> is 1, with <var>msg</var> and <var>msgid</var> empty\n\
+character strings.  Otherwise, <var>status</var> is 0, <var>msg</var> contains a\n\
+system-dependent error message, and <var>msgid</var> contains a unique\n\
+message identifier.\n\
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dglob.html#doc_002dglob">glob</a>, <a href="doc_002dmovefile.html#doc_002dmovefile">movefile</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/fileparts.m -->
+   <p><a name="doc_002dfileparts"></a>
+
+<div class="defun">
+— Function File: [<var>dir</var>, <var>name</var>, <var>ext</var>, <var>ver</var>] = <b>fileparts</b> (<var>filename</var>)<var><a name="index-fileparts-2338"></a></var><br>
+<blockquote><p>Return the directory, name, extension, and version components of
+<var>filename</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfullfile.html#doc_002dfullfile">fullfile</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dfilesep"></a>
+
+<div class="defun">
+— Built-in Function:  <b>filesep</b> ()<var><a name="index-filesep-2339"></a></var><br>
+— Built-in Function:  <b>filesep</b> (<var>'all'</var>)<var><a name="index-filesep-2340"></a></var><br>
+<blockquote><p>Return the system-dependent character used to separate directory names.
+
+        <p>If 'all' is given, the function return all valid file separators in
+the form of a string.  The list of file separators is system-dependent. 
+It is / (forward slash) under UNIX or Mac OS X, / and \ (forward and
+backward slashes) under Windows. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>, <a href="doc_002ddir.html#doc_002ddir">dir</a>, <a href="doc_002dls.html#doc_002dls">ls</a>. 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002dfilemarker"></a>
+
+<div class="defun">
+— Built-in Function:  <b>filemarker</b> ()<var><a name="index-filemarker-2341"></a></var><br>
+<blockquote><p>Returns or sets the character used to separate filename from the
+the subfunction names contained within the file.  This can be used in
+a generic manner to interact with subfunctions.  For example
+
+     <pre class="example">          help (["myfunc", filemarker, "mysubfunc"])
+</pre>
+        <p class="noindent">returns the help string associated with the sub-function <code>mysubfunc</code>
+of the function <code>myfunc</code>.  Another use of <code>filemarker</code> is when
+debugging it allows easier placement of breakpoints within sub-functions. 
+For example
+
+     <pre class="example">          dbstop (["myfunc", filemarker, "mysubfunc"])
+</pre>
+        <p class="noindent">will set a breakpoint at the first line of the subfunction <code>mysubfunc</code>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/fullfile.m -->
+   <p><a name="doc_002dfullfile"></a>
+
+<div class="defun">
+— Function File: <var>filename</var> = <b>fullfile</b> (<var>dir1, dir2, <small class="dots">...</small>, file</var>)<var><a name="index-fullfile-2342"></a></var><br>
+<blockquote><p>Return a complete filename constructed from the given components. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfileparts.html#doc_002dfileparts">fileparts</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/tempdir.m -->
+   <p><a name="doc_002dtempdir"></a>
+
+<div class="defun">
+— Function File: <var>dir</var> = <b>tempdir</b> ()<var><a name="index-tempdir-2343"></a></var><br>
+<blockquote><p>Return the name of the system's directory for temporary files. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/tempname.m -->
+   <p><a name="doc_002dtempname"></a>
+
+<div class="defun">
+— Function File: filename = <b>tempname</b> ()<var><a name="index-tempname-2344"></a></var><br>
+<blockquote><p>This function is an alias for <code>tmpnam</code>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dP_005ftmpdir"></a>
+
+<div class="defun">
+— Built-in Function:  <b>P_tmpdir</b> ()<var><a name="index-P_005ftmpdir-2345"></a></var><br>
+<blockquote><p>Return the default name of the directory for temporary files on
+this system.  The name of this directory is system dependent. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dis_005fabsolute_005ffilename"></a>
+
+<div class="defun">
+— Built-in Function:  <b>is_absolute_filename</b> (<var>file</var>)<var><a name="index-is_005fabsolute_005ffilename-2346"></a></var><br>
+<blockquote><p>Return true if <var>file</var> is an absolute filename. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dis_005frooted_005frelative_005ffilename"></a>
+
+<div class="defun">
+— Built-in Function:  <b>is_rooted_relative_filename</b> (<var>file</var>)<var><a name="index-is_005frooted_005frelative_005ffilename-2347"></a></var><br>
+<blockquote><p>Return true if <var>file</var> is a rooted-relative filename. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dmake_005fabsolute_005ffilename"></a>
+
+<div class="defun">
+— Built-in Function:  <b>make_absolute_filename</b> (<var>file</var>)<var><a name="index-make_005fabsolute_005ffilename-2348"></a></var><br>
+<blockquote><p>Return the full name of <var>file</var>, relative to the current directory. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Finding-Elements-and-Checking-Conditions.html b/doc/interpreter/HTML/Finding-Elements-and-Checking-Conditions.html
new file mode 100644
index 0000000..899a2b4
--- /dev/null
+++ b/doc/interpreter/HTML/Finding-Elements-and-Checking-Conditions.html
@@ -0,0 +1,248 @@
+<html lang="en">
+<head>
+<title>Finding Elements and Checking Conditions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link rel="next" href="Rearranging-Matrices.html#Rearranging-Matrices" title="Rearranging Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Finding-Elements-and-Checking-Conditions"></a>
+Next: <a rel="next" accesskey="n" href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>
+<hr>
+</div>
+
+<h3 class="section">16.1 Finding Elements and Checking Conditions</h3>
+
+<p>The functions <code>any</code> and <code>all</code> are useful for determining
+whether any or all of the elements of a matrix satisfy some condition. 
+The <code>find</code> function is also useful in determining which elements of
+a matrix meet a specified condition.
+
+<!-- data.cc -->
+   <p><a name="doc_002dany"></a>
+
+<div class="defun">
+— Built-in Function:  <b>any</b> (<var>x, dim</var>)<var><a name="index-any-1260"></a></var><br>
+<blockquote><p>For a vector argument, return 1 if any element of the vector is
+nonzero.
+
+        <p>For a matrix argument, return a row vector of ones and
+zeros with each element indicating whether any of the elements of the
+corresponding column of the matrix are nonzero.  For example,
+
+     <pre class="example">          any (eye (2, 4))
+                [ 1, 1, 0, 0 ]
+</pre>
+        <p>If the optional argument <var>dim</var> is supplied, work along dimension
+<var>dim</var>.  For example,
+
+     <pre class="example">          any (eye (2, 4), 2)
+                [ 1; 1 ]
+</pre>
+        </blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dall"></a>
+
+<div class="defun">
+— Built-in Function:  <b>all</b> (<var>x, dim</var>)<var><a name="index-all-1261"></a></var><br>
+<blockquote><p>The function <code>all</code> behaves like the function <code>any</code>, except
+that it returns true only if all the elements of a vector, or all the
+elements along dimension <var>dim</var> of a matrix, are nonzero. 
+</p></blockquote></div>
+
+   <p>Since the comparison operators (see <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a>) return matrices
+of ones and zeros, it is easy to test a matrix for many things, not just
+whether the elements are nonzero.  For example,
+
+<pre class="example">     all (all (rand (5) < 0.9))
+           0
+</pre>
+   <p class="noindent">tests a random 5 by 5 matrix to see if all of its elements are less
+than 0.9.
+
+   <p>Note that in conditional contexts (like the test clause of <code>if</code> and
+<code>while</code> statements) Octave treats the test as if you had typed
+<code>all (all (condition))</code>.
+
+<!-- ./miscellaneous/xor.m -->
+   <p><a name="doc_002dxor"></a>
+
+<div class="defun">
+— Mapping Function:  <b>xor</b> (<var>x, y</var>)<var><a name="index-xor-1262"></a></var><br>
+<blockquote><p>Return the `exclusive or' of the entries of <var>x</var> and <var>y</var>. 
+For boolean expressions <var>x</var> and <var>y</var>,
+<code>xor (</code><var>x</var><code>, </code><var>y</var><code>)</code> is true if and only if <var>x</var> or <var>y</var>
+is true, but not if both <var>x</var> and <var>y</var> are true. 
+</p></blockquote></div>
+
+<!-- ./general/is_duplicate_entry.m -->
+   <p><a name="doc_002dis_005fduplicate_005fentry"></a>
+
+<div class="defun">
+— Function File:  <b>is_duplicate_entry</b> (<var>x</var>)<var><a name="index-is_005fduplicate_005fentry-1263"></a></var><br>
+<blockquote><p>Return non-zero if any entries in <var>x</var> are duplicates of one
+another. 
+</p></blockquote></div>
+
+<!-- ./general/diff.m -->
+   <p><a name="doc_002ddiff"></a>
+
+<div class="defun">
+— Function File:  <b>diff</b> (<var>x, k, dim</var>)<var><a name="index-diff-1264"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector of length <var>n</var>, <code>diff (</code><var>x</var><code>)</code> is the
+vector of first differences
+<var>x</var>(2) - <var>x</var>(1), <small class="dots">...</small>, <var>x</var>(n) - <var>x</var>(n-1).
+
+        <p>If <var>x</var> is a matrix, <code>diff (</code><var>x</var><code>)</code> is the matrix of column
+differences along the first non-singleton dimension.
+
+        <p>The second argument is optional.  If supplied, <code>diff (</code><var>x</var><code>,
+</code><var>k</var><code>)</code>, where <var>k</var> is a non-negative integer, returns the
+<var>k</var>-th differences.  It is possible that <var>k</var> is larger than
+then first non-singleton dimension of the matrix.  In this case,
+<code>diff</code> continues to take the differences along the next
+non-singleton dimension.
+
+        <p>The dimension along which to take the difference can be explicitly
+stated with the optional variable <var>dim</var>.  In this case the
+<var>k</var>-th order differences are calculated along this dimension. 
+In the case where <var>k</var> exceeds <code>size (</code><var>x</var><code>, </code><var>dim</var><code>)</code>
+then an empty matrix is returned. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disinf"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isinf</b> (<var>x</var>)<var><a name="index-isinf-1265"></a></var><br>
+<blockquote><p>Return 1 for elements of <var>x</var> that are infinite and zero
+otherwise.  For example,
+
+     <pre class="example">          isinf ([13, Inf, NA, NaN])
+                [ 0, 1, 0, 0 ]
+</pre>
+        </blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disnan"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isnan</b> (<var>x</var>)<var><a name="index-isnan-1266"></a></var><br>
+<blockquote><p>Return 1 for elements of <var>x</var> that are NaN values and zero
+otherwise.  NA values are also considered NaN values.  For example,
+
+     <pre class="example">          isnan ([13, Inf, NA, NaN])
+                [ 0, 0, 1, 1 ]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disna.html#doc_002disna">isna</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dfinite"></a>
+
+<div class="defun">
+— Mapping Function:  <b>finite</b> (<var>x</var>)<var><a name="index-finite-1267"></a></var><br>
+<blockquote><p>Return 1 for elements of <var>x</var> that are finite values and zero
+otherwise.  For example,
+
+     <pre class="example">          finite ([13, Inf, NA, NaN])
+                [ 1, 0, 0, 0 ]
+</pre>
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/find.cc -->
+   <p><a name="doc_002dfind"></a>
+
+<div class="defun">
+— Loadable Function:  <b>find</b> (<var>x</var>)<var><a name="index-find-1268"></a></var><br>
+— Loadable Function:  <b>find</b> (<var>x, n</var>)<var><a name="index-find-1269"></a></var><br>
+— Loadable Function:  <b>find</b> (<var>x, n, direction</var>)<var><a name="index-find-1270"></a></var><br>
+<blockquote><p>Return a vector of indices of nonzero elements of a matrix, as a row if
+<var>x</var> is a row or as a column otherwise.  To obtain a single index for
+each matrix element, Octave pretends that the columns of a matrix form one
+long vector (like Fortran arrays are stored).  For example,
+
+     <pre class="example">          find (eye (2))
+                [ 1; 4 ]
+</pre>
+        <p>If two outputs are requested, <code>find</code> returns the row and column
+indices of nonzero elements of a matrix.  For example,
+
+     <pre class="example">          [i, j] = find (2 * eye (2))
+                i = [ 1; 2 ]
+                j = [ 1; 2 ]
+</pre>
+        <p>If three outputs are requested, <code>find</code> also returns a vector
+containing the nonzero values.  For example,
+
+     <pre class="example">          [i, j, v] = find (3 * eye (2))
+                i = [ 1; 2 ]
+                j = [ 1; 2 ]
+                v = [ 3; 3 ]
+</pre>
+        <p>If two inputs are given, <var>n</var> indicates the maximum number of
+elements to find from the beginning of the matrix or vector.
+
+        <p>If three inputs are given, <var>direction</var> should be one of "first" or
+"last", requesting only the first or last <var>n</var> indices, respectively. 
+However, the indices are always returned in ascending order.
+
+        <p>Note that this function is particularly useful for sparse matrices, as
+it extracts the non-zero elements as vectors, which can then be used to
+create the original matrix.  For example,
+
+     <pre class="example">          sz = size(a);
+          [i, j, v] = find (a);
+          b = sparse(i, j, v, sz(1), sz(2));
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>. 
+</p></blockquote></div>
+
+<!-- ./general/common_size.m -->
+   <p><a name="doc_002dcommon_005fsize"></a>
+
+<div class="defun">
+— Function File: [<var>err</var>, <var>y1</var>, <small class="dots">...</small>] = <b>common_size</b> (<var>x1, <small class="dots">...</small></var>)<var><a name="index-common_005fsize-1271"></a></var><br>
+<blockquote><p>Determine if all input arguments are either scalar or of common
+size.  If so, <var>err</var> is zero, and <var>yi</var> is a matrix of the
+common size with all entries equal to <var>xi</var> if this is a scalar or
+<var>xi</var> otherwise.  If the inputs cannot be brought to a common size,
+errorcode is 1, and <var>yi</var> is <var>xi</var>.  For example,
+
+     <pre class="example">          [errorcode, a, b] = common_size ([1 2; 3 4], 5)
+                errorcode = 0
+                a = [ 1, 2; 3, 4 ]
+                b = [ 5, 5; 5, 5 ]
+</pre>
+        <p class="noindent">This is useful for implementing functions where arguments can either
+be scalars or of common size. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Finding-Roots.html b/doc/interpreter/HTML/Finding-Roots.html
new file mode 100644
index 0000000..0897aef
--- /dev/null
+++ b/doc/interpreter/HTML/Finding-Roots.html
@@ -0,0 +1,135 @@
+<html lang="en">
+<head>
+<title>Finding Roots - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="prev" href="Evaluating-Polynomials.html#Evaluating-Polynomials" title="Evaluating Polynomials">
+<link rel="next" href="Products-of-Polynomials.html#Products-of-Polynomials" title="Products of Polynomials">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Finding-Roots"></a>
+Next: <a rel="next" accesskey="n" href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a>,
+Previous: <a rel="previous" accesskey="p" href="Evaluating-Polynomials.html#Evaluating-Polynomials">Evaluating Polynomials</a>,
+Up: <a rel="up" accesskey="u" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<hr>
+</div>
+
+<h3 class="section">27.2 Finding Roots</h3>
+
+<p>Octave can find the roots of a given polynomial.  This is done by computing
+the companion matrix of the polynomial (see the <code>compan</code> function
+for a definition), and then finding its eigenvalues.
+
+<!-- ./polynomial/roots.m -->
+   <p><a name="doc_002droots"></a>
+
+<div class="defun">
+— Function File:  <b>roots</b> (<var>v</var>)<var><a name="index-roots-2026"></a></var><br>
+<blockquote>
+        <p>For a vector <var>v</var> with N components, return
+the roots of the polynomial
+
+     <pre class="example">          v(1) * z^(N-1) + ... + v(N-1) * z + v(N)
+</pre>
+        <p>As an example, the following code finds the roots of the quadratic
+polynomial
+     <pre class="example">          p(x) = x^2 - 5.
+</pre>
+        <pre class="example">          c = [1, 0, -5];
+          roots(c)
+            2.2361
+           -2.2361
+</pre>
+        <p>Note that the true result is
++/- sqrt(5)
+which is roughly
++/- 2.2361. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcompan.html#doc_002dcompan">compan</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/compan.m -->
+   <p><a name="doc_002dcompan"></a>
+
+<div class="defun">
+— Function File:  <b>compan</b> (<var>c</var>)<var><a name="index-compan-2027"></a></var><br>
+<blockquote><p>Compute the companion matrix corresponding to polynomial coefficient
+vector <var>c</var>.
+
+        <p>The companion matrix is
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">               _                                                        _
+              |  -c(2)/c(1)   -c(3)/c(1)  ...  -c(N)/c(1)  -c(N+1)/c(1)  |
+              |       1            0      ...       0             0      |
+              |       0            1      ...       0             0      |
+          A = |       .            .   .            .             .      |
+              |       .            .       .        .             .      |
+              |       .            .           .    .             .      |
+              |_      0            0      ...       1             0     _|
+</pre>
+        <p>The eigenvalues of the companion matrix are equal to the roots of the
+polynomial. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/mpoles.m -->
+   <p><a name="doc_002dmpoles"></a>
+
+<div class="defun">
+— Function File: [<var>multp</var>, <var>indx</var>] = <b>mpoles</b> (<var>p</var>)<var><a name="index-mpoles-2028"></a></var><br>
+— Function File: [<var>multp</var>, <var>indx</var>] = <b>mpoles</b> (<var>p, tol</var>)<var><a name="index-mpoles-2029"></a></var><br>
+— Function File: [<var>multp</var>, <var>indx</var>] = <b>mpoles</b> (<var>p, tol, reorder</var>)<var><a name="index-mpoles-2030"></a></var><br>
+<blockquote><p>Identify unique poles in <var>p</var> and associates their multiplicity,
+ordering them from largest to smallest.
+
+        <p>If the relative difference of the poles is less than <var>tol</var>, then
+they are considered to be multiples.  The default value for <var>tol</var>
+is 0.001.
+
+        <p>If the optional parameter <var>reorder</var> is zero, poles are not sorted.
+
+        <p>The value <var>multp</var> is a vector specifying the multiplicity of the
+poles.  <var>multp</var>(:) refers to multiplicity of <var>p</var>(<var>indx</var>(:)).
+
+        <p>For example,
+
+     <pre class="example">          p = [2 3 1 1 2];
+          [m, n] = mpoles(p);
+             m = [1; 1; 2; 1; 2]
+             n = [2; 5; 1; 4; 3]
+             p(n) = [3, 2, 2, 1, 1]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Floating_002dPoint-Conversions.html b/doc/interpreter/HTML/Floating_002dPoint-Conversions.html
new file mode 100644
index 0000000..75bb64d
--- /dev/null
+++ b/doc/interpreter/HTML/Floating_002dPoint-Conversions.html
@@ -0,0 +1,99 @@
+<html lang="en">
+<head>
+<title>Floating-Point Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Integer-Conversions.html#Integer-Conversions" title="Integer Conversions">
+<link rel="next" href="Other-Output-Conversions.html#Other-Output-Conversions" title="Other Output Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Floating-Point-Conversions"></a>
+<a name="Floating_002dPoint-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.9 Floating-Point Conversions</h4>
+
+<p>This section discusses the conversion specifications for floating-point
+numbers: the ‘<samp><span class="samp">%f</span></samp>’, ‘<samp><span class="samp">%e</span></samp>’, ‘<samp><span class="samp">%E</span></samp>’, ‘<samp><span class="samp">%g</span></samp>’, and ‘<samp><span class="samp">%G</span></samp>’
+conversions.
+
+   <p>The ‘<samp><span class="samp">%f</span></samp>’ conversion prints its argument in fixed-point notation,
+producing output of the form
+[<code>-</code>]<var>ddd</var><code>.</code><var>ddd</var><!-- /@w -->,
+where the number of digits following the decimal point is controlled
+by the precision you specify.
+
+   <p>The ‘<samp><span class="samp">%e</span></samp>’ conversion prints its argument in exponential notation,
+producing output of the form
+[<code>-</code>]<var>d</var><code>.</code><var>ddd</var><code>e</code>[<code>+</code>|<code>-</code>]<var>dd</var><!-- /@w -->. 
+Again, the number of digits following the decimal point is controlled by
+the precision.  The exponent always contains at least two digits.  The
+‘<samp><span class="samp">%E</span></samp>’ conversion is similar but the exponent is marked with the letter
+‘<samp><span class="samp">E</span></samp>’ instead of ‘<samp><span class="samp">e</span></samp>’.
+
+   <p>The ‘<samp><span class="samp">%g</span></samp>’ and ‘<samp><span class="samp">%G</span></samp>’ conversions print the argument in the style
+of ‘<samp><span class="samp">%e</span></samp>’ or ‘<samp><span class="samp">%E</span></samp>’ (respectively) if the exponent would be less
+than -4 or greater than or equal to the precision; otherwise they use the
+‘<samp><span class="samp">%f</span></samp>’ style.  Trailing zeros are removed from the fractional portion
+of the result and a decimal-point character appears only if it is
+followed by a digit.
+
+   <p>The following flags can be used to modify the behavior:
+
+<!-- Not @samp so we can have ` ' as an item. -->
+     <dl>
+<dt>‘<samp><span class="samp">-</span></samp>’<dd>Left-justify the result in the field.  Normally the result is
+right-justified.
+
+     <br><dt>‘<samp><span class="samp">+</span></samp>’<dd>Always include a plus or minus sign in the result.
+
+     <br><dt>‘<samp> </samp>’<dd>If the result doesn't start with a plus or minus sign, prefix it with a
+space instead.  Since the ‘<samp><span class="samp">+</span></samp>’ flag ensures that the result includes
+a sign, this flag is ignored if you supply both of them.
+
+     <br><dt>‘<samp><span class="samp">#</span></samp>’<dd>Specifies that the result should always include a decimal point, even
+if no digits follow it.  For the ‘<samp><span class="samp">%g</span></samp>’ and ‘<samp><span class="samp">%G</span></samp>’ conversions,
+this also forces trailing zeros after the decimal point to be left
+in place where they would otherwise be removed.
+
+     <br><dt>‘<samp><span class="samp">0</span></samp>’<dd>Pad the field with zeros instead of spaces; the zeros are placed
+after any sign.  This flag is ignored if the ‘<samp><span class="samp">-</span></samp>’ flag is also
+specified. 
+</dl>
+
+   <p>The precision specifies how many digits follow the decimal-point
+character for the ‘<samp><span class="samp">%f</span></samp>’, ‘<samp><span class="samp">%e</span></samp>’, and ‘<samp><span class="samp">%E</span></samp>’ conversions.  For
+these conversions, the default precision is <code>6</code>.  If the precision
+is explicitly <code>0</code>, this suppresses the decimal point character
+entirely.  For the ‘<samp><span class="samp">%g</span></samp>’ and ‘<samp><span class="samp">%G</span></samp>’ conversions, the precision
+specifies how many significant digits to print.  Significant digits are
+the first digit before the decimal point, and all the digits after it. 
+If the precision is <code>0</code> or not specified for ‘<samp><span class="samp">%g</span></samp>’ or
+‘<samp><span class="samp">%G</span></samp>’, it is treated like a value of <code>1</code>.  If the value being
+printed cannot be expressed precisely in the specified number of digits,
+the value is rounded to the nearest number that fits.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Fonts.html b/doc/interpreter/HTML/Fonts.html
new file mode 100644
index 0000000..6f24c83
--- /dev/null
+++ b/doc/interpreter/HTML/Fonts.html
@@ -0,0 +1,45 @@
+<html lang="en">
+<head>
+<title>Fonts - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Conventions.html#Conventions" title="Conventions">
+<link rel="next" href="Evaluation-Notation.html#Evaluation-Notation" title="Evaluation Notation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Fonts"></a>
+Next: <a rel="next" accesskey="n" href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a>,
+Up: <a rel="up" accesskey="u" href="Conventions.html#Conventions">Conventions</a>
+<hr>
+</div>
+
+<h4 class="subsection">1.3.1 Fonts</h4>
+
+<p><a name="index-documentation-fonts-10"></a>
+Examples of Octave code appear in this font or form: <code>svd (a)</code>. 
+Names that represent variables or function arguments appear
+in this font or form: <var>first-number</var>.  Commands that you type at the
+shell prompt appear in this font or form: ‘<samp><span class="samp">octave --no-init-file</span></samp>’. 
+Commands that you type at the Octave prompt sometimes appear in this font
+or form: <kbd>foo --bar --baz</kbd>.  Specific keys on your keyboard appear
+in this font or form: <ANY>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Format-of-Descriptions.html b/doc/interpreter/HTML/Format-of-Descriptions.html
new file mode 100644
index 0000000..79f0cc3
--- /dev/null
+++ b/doc/interpreter/HTML/Format-of-Descriptions.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Format of Descriptions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Conventions.html#Conventions" title="Conventions">
+<link rel="prev" href="Error-Messages.html#Error-Messages" title="Error Messages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Format-of-Descriptions"></a>
+Previous: <a rel="previous" accesskey="p" href="Error-Messages.html#Error-Messages">Error Messages</a>,
+Up: <a rel="up" accesskey="u" href="Conventions.html#Conventions">Conventions</a>
+<hr>
+</div>
+
+<h4 class="subsection">1.3.5 Format of Descriptions</h4>
+
+<p><a name="index-description-format-15"></a>
+Functions, commands, and variables are described in this manual in a
+uniform format.  The first line of a description contains the name of
+the item followed by its arguments, if any. 
+The category—function, variable, or whatever—appears at the
+beginning of the line. 
+The description follows on succeeding lines, sometimes with examples.
+
+<ul class="menu">
+<li><a accesskey="1" href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a>
+<li><a accesskey="2" href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a>
+<li><a accesskey="3" href="A-Sample-Variable-Description.html#A-Sample-Variable-Description">A Sample Variable Description</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Formatted-Input.html b/doc/interpreter/HTML/Formatted-Input.html
new file mode 100644
index 0000000..d1ba1b8
--- /dev/null
+++ b/doc/interpreter/HTML/Formatted-Input.html
@@ -0,0 +1,144 @@
+<html lang="en">
+<head>
+<title>Formatted Input - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Other-Output-Conversions.html#Other-Output-Conversions" title="Other Output Conversions">
+<link rel="next" href="Input-Conversion-Syntax.html#Input-Conversion-Syntax" title="Input Conversion Syntax">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Formatted-Input"></a>
+Next: <a rel="next" accesskey="n" href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">Input Conversion Syntax</a>,
+Previous: <a rel="previous" accesskey="p" href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.11 Formatted Input</h4>
+
+<p>Octave provides the <code>scanf</code>, <code>fscanf</code>, and <code>sscanf</code>
+functions to read formatted input.  There are two forms of each of these
+functions.  One can be used to extract vectors of data from a file, and
+the other is more `C-like'.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfscanf"></a>
+
+<div class="defun">
+— Built-in Function: [<var>val</var>, <var>count</var>] = <b>fscanf</b> (<var>fid, template, size</var>)<var><a name="index-fscanf-789"></a></var><br>
+— Built-in Function: [<var>v1</var>, <var>v2</var>, <small class="dots">...</small>, <var>count</var>] = <b>fscanf</b> (<var>fid, template, "C"</var>)<var><a name="index-fscanf-790"></a></var><br>
+<blockquote><p>In the first form, read from <var>fid</var> according to <var>template</var>,
+returning the result in the matrix <var>val</var>.
+
+        <p>The optional argument <var>size</var> specifies the amount of data to read
+and may be one of
+
+          <dl>
+<dt><code>Inf</code><dd>Read as much as possible, returning a column vector.
+
+          <br><dt><var>nr</var><dd>Read up to <var>nr</var> elements, returning a column vector.
+
+          <br><dt><code>[</code><var>nr</var><code>, Inf]</code><dd>Read as much as possible, returning a matrix with <var>nr</var> rows.  If the
+number of elements read is not an exact multiple of <var>nr</var>, the last
+column is padded with zeros.
+
+          <br><dt><code>[</code><var>nr</var><code>, </code><var>nc</var><code>]</code><dd>Read up to <var>nr</var><code> * </code><var>nc</var> elements, returning a matrix with
+<var>nr</var> rows.  If the number of elements read is not an exact multiple
+of <var>nr</var>, the last column is padded with zeros. 
+</dl>
+
+     <p class="noindent">If <var>size</var> is omitted, a value of <code>Inf</code> is assumed.
+
+        <p>A string is returned if <var>template</var> specifies only character
+conversions.
+
+        <p>The number of items successfully read is returned in <var>count</var>.
+
+        <p>In the second form, read from <var>fid</var> according to <var>template</var>,
+with each conversion specifier in <var>template</var> corresponding to a
+single scalar return value.  This form is more `C-like', and also
+compatible with previous versions of Octave.  The number of successful
+conversions is returned in <var>count</var>
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dscanf.html#doc_002dscanf">scanf</a>, <a href="doc_002dsscanf.html#doc_002dsscanf">sscanf</a>, <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfprintf.html#doc_002dfprintf">fprintf</a>, <a href="doc_002dfgets.html#doc_002dfgets">fgets</a>, <a href="doc_002dfputs.html#doc_002dfputs">fputs</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dscanf"></a>
+
+<div class="defun">
+— Built-in Function: [<var>val</var>, <var>count</var>] = <b>scanf</b> (<var>template, size</var>)<var><a name="index-scanf-791"></a></var><br>
+— Built-in Function: [<var>v1</var>, <var>v2</var>, <small class="dots">...</small>, <var>count</var>]] = <b>scanf</b> (<var>template, "C"</var>)<var><a name="index-scanf-792"></a></var><br>
+<blockquote><p>This is equivalent to calling <code>fscanf</code> with <var>fid</var> = <code>stdin</code>.
+
+        <p>It is currently not useful to call <code>scanf</code> in interactive
+programs. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>, <a href="doc_002dsscanf.html#doc_002dsscanf">sscanf</a>, <a href="doc_002dprintf.html#doc_002dprintf">printf</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dsscanf"></a>
+
+<div class="defun">
+— Built-in Function: [<var>val</var>, <var>count</var>] = <b>sscanf</b> (<var>string, template, size</var>)<var><a name="index-sscanf-793"></a></var><br>
+— Built-in Function: [<var>v1</var>, <var>v2</var>, <small class="dots">...</small>, <var>count</var>] = <b>sscanf</b> (<var>string, template, "C"</var>)<var><a name="index-sscanf-794"></a></var><br>
+<blockquote><p>This is like <code>fscanf</code>, except that the characters are taken from the
+string <var>string</var> instead of from a stream.  Reaching the end of the
+string is treated as an end-of-file condition. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>, <a href="doc_002dscanf.html#doc_002dscanf">scanf</a>, <a href="doc_002dsprintf.html#doc_002dsprintf">sprintf</a>. 
+</p></blockquote></div>
+
+   <p>Calls to <code>scanf</code> are superficially similar to calls to
+<code>printf</code> in that arbitrary arguments are read under the control of
+a template string.  While the syntax of the conversion specifications in
+the template is very similar to that for <code>printf</code>, the
+interpretation of the template is oriented more towards free-format
+input and simple pattern matching, rather than fixed-field formatting. 
+For example, most <code>scanf</code> conversions skip over any amount of
+“white space” (including spaces, tabs, and newlines) in the input
+file, and there is no concept of precision for the numeric input
+conversions as there is for the corresponding output conversions. 
+Ordinarily, non-whitespace characters in the template are expected to
+match characters in the input stream exactly. 
+<a name="index-conversion-specifications-_0028_0040code_007bscanf_007d_0029-795"></a>
+When a <dfn>matching failure</dfn> occurs, <code>scanf</code> returns immediately,
+leaving the first non-matching character as the next character to be
+read from the stream, and <code>scanf</code> returns all the items that were
+successfully converted. 
+<a name="index-matching-failure_002c-in-_0040code_007bscanf_007d-796"></a>
+The formatted input functions are not used as frequently as the
+formatted output functions.  Partly, this is because it takes some care
+to use them properly.  Another reason is that it is difficult to recover
+from a matching error.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Formatted-Output.html b/doc/interpreter/HTML/Formatted-Output.html
new file mode 100644
index 0000000..39b32eb
--- /dev/null
+++ b/doc/interpreter/HTML/Formatted-Output.html
@@ -0,0 +1,139 @@
+<html lang="en">
+<head>
+<title>Formatted Output - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Line_002dOriented-Input.html#Line_002dOriented-Input" title="Line-Oriented Input">
+<link rel="next" href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices" title="Output Conversion for Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Formatted-Output"></a>
+Next: <a rel="next" accesskey="n" href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices">Output Conversion for Matrices</a>,
+Previous: <a rel="previous" accesskey="p" href="Line_002dOriented-Input.html#Line_002dOriented-Input">Line-Oriented Input</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.4 Formatted Output</h4>
+
+<p>This section describes how to call <code>printf</code> and related functions.
+
+   <p>The following functions are available for formatted output.  They are
+modelled after the C language functions of the same name, but they
+interpret the format template differently in order to improve the
+performance of printing vector and matrix values.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dprintf"></a>
+
+<div class="defun">
+— Built-in Function:  <b>printf</b> (<var>template, <small class="dots">...</small></var>)<var><a name="index-printf-781"></a></var><br>
+<blockquote><p>Print optional arguments under the control of the template string
+<var>template</var> to the stream <code>stdout</code> and return the number of
+characters printed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfprintf.html#doc_002dfprintf">fprintf</a>, <a href="doc_002dsprintf.html#doc_002dsprintf">sprintf</a>, <a href="doc_002dscanf.html#doc_002dscanf">scanf</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfprintf"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fprintf</b> (<var>fid, template, <small class="dots">...</small></var>)<var><a name="index-fprintf-782"></a></var><br>
+<blockquote><p>This function is just like <code>printf</code>, except that the output is
+written to the stream <var>fid</var> instead of <code>stdout</code>. 
+If <var>fid</var> is omitted, the output is written to <code>stdout</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprintf.html#doc_002dprintf">printf</a>, <a href="doc_002dsprintf.html#doc_002dsprintf">sprintf</a>, <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dsprintf"></a>
+
+<div class="defun">
+— Built-in Function:  <b>sprintf</b> (<var>template, <small class="dots">...</small></var>)<var><a name="index-sprintf-783"></a></var><br>
+<blockquote><p>This is like <code>printf</code>, except that the output is returned as a
+string.  Unlike the C library function, which requires you to provide a
+suitably sized string as an argument, Octave's <code>sprintf</code> function
+returns the string, automatically sized to hold all of the items
+converted. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprintf.html#doc_002dprintf">printf</a>, <a href="doc_002dfprintf.html#doc_002dfprintf">fprintf</a>, <a href="doc_002dsscanf.html#doc_002dsscanf">sscanf</a>. 
+</p></blockquote></div>
+
+   <p>The <code>printf</code> function can be used to print any number of arguments. 
+The template string argument you supply in a call provides
+information not only about the number of additional arguments, but also
+about their types and what style should be used for printing them.
+
+   <p>Ordinary characters in the template string are simply written to the
+output stream as-is, while <dfn>conversion specifications</dfn> introduced by
+a ‘<samp><span class="samp">%</span></samp>’ character in the template cause subsequent arguments to be
+formatted and written to the output stream.  For example,
+<a name="index-conversion-specifications-_0028_0040code_007bprintf_007d_0029-784"></a>
+<pre class="example">     pct = 37;
+     filename = "foo.txt";
+     printf ("Processed %d%% of `%s'.\nPlease be patient.\n",
+             pct, filename);
+</pre>
+   <p class="noindent">produces output like
+
+<pre class="example">     Processed 37% of `foo.txt'.
+     Please be patient.
+</pre>
+   <p>This example shows the use of the ‘<samp><span class="samp">%d</span></samp>’ conversion to specify that a
+scalar argument should be printed in decimal notation, the ‘<samp><span class="samp">%s</span></samp>’
+conversion to specify printing of a string argument, and the ‘<samp><span class="samp">%%</span></samp>’
+conversion to print a literal ‘<samp><span class="samp">%</span></samp>’ character.
+
+   <p>There are also conversions for printing an integer argument as an
+unsigned value in octal, decimal, or hexadecimal radix (‘<samp><span class="samp">%o</span></samp>’,
+‘<samp><span class="samp">%u</span></samp>’, or ‘<samp><span class="samp">%x</span></samp>’, respectively); or as a character value
+(‘<samp><span class="samp">%c</span></samp>’).
+
+   <p>Floating-point numbers can be printed in normal, fixed-point notation
+using the ‘<samp><span class="samp">%f</span></samp>’ conversion or in exponential notation using the
+‘<samp><span class="samp">%e</span></samp>’ conversion.  The ‘<samp><span class="samp">%g</span></samp>’ conversion uses either ‘<samp><span class="samp">%e</span></samp>’
+or ‘<samp><span class="samp">%f</span></samp>’ format, depending on what is more appropriate for the
+magnitude of the particular number.
+
+   <p>You can control formatting more precisely by writing <dfn>modifiers</dfn>
+between the ‘<samp><span class="samp">%</span></samp>’ and the character that indicates which conversion
+to apply.  These slightly alter the ordinary behavior of the conversion. 
+For example, most conversion specifications permit you to specify a
+minimum field width and a flag indicating whether you want the result
+left- or right-justified within the field.
+
+   <p>The specific flags and modifiers that are permitted and their
+interpretation vary depending on the particular conversion.  They're all
+described in more detail in the following sections.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Files.html b/doc/interpreter/HTML/Function-Files.html
new file mode 100644
index 0000000..cf2e9d9
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Files.html
@@ -0,0 +1,236 @@
+<html lang="en">
+<head>
+<title>Function Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Default-Arguments.html#Default-Arguments" title="Default Arguments">
+<link rel="next" href="Script-Files.html#Script-Files" title="Script Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Files"></a>
+Next: <a rel="next" accesskey="n" href="Script-Files.html#Script-Files">Script Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Default-Arguments.html#Default-Arguments">Default Arguments</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.7 Function Files</h3>
+
+<p><a name="index-function-file-612"></a>
+Except for simple one-shot programs, it is not practical to have to
+define all the functions you need each time you need them.  Instead, you
+will normally want to save them in a file so that you can easily edit
+them, and save them for use at a later time.
+
+   <p>Octave does not require you to load function definitions from files
+before using them.  You simply need to put the function definitions in a
+place where Octave can find them.
+
+   <p>When Octave encounters an identifier that is undefined, it first looks
+for variables or functions that are already compiled and currently
+listed in its symbol table.  If it fails to find a definition there, it
+searches a list of directories (the <dfn>path</dfn>) for files ending in
+<samp><span class="file">.m</span></samp> that have the same base name as the undefined
+identifier.<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>  Once Octave finds a file with a name that matches,
+the contents of the file are read.  If it defines a <em>single</em>
+function, it is compiled and executed.  See <a href="Script-Files.html#Script-Files">Script Files</a>, for more
+information about how you can define more than one function in a single
+file.
+
+   <p>When Octave defines a function from a function file, it saves the full
+name of the file it read and the time stamp on the file.  If the time
+stamp on the file changes, Octave may reload the file.  When Octave is
+running interactively, time stamp checking normally happens at most once
+each time Octave prints the prompt.  Searching for new function
+definitions also occurs if the current working directory changes.
+
+   <p>Checking the time stamp allows you to edit the definition of a function
+while Octave is running, and automatically use the new function
+definition without having to restart your Octave session.
+
+   <p>To avoid degrading performance unnecessarily by checking the time stamps
+on functions that are not likely to change, Octave assumes that function
+files in the directory tree
+<samp><var>octave-home</var><span class="file">/share/octave/</span><var>version</var><span class="file">/m</span></samp>
+will not change, so it doesn't have to check their time stamps every time the
+functions defined in those files are used.  This is normally a very good
+assumption and provides a significant improvement in performance for the
+function files that are distributed with Octave.
+
+   <p>If you know that your own function files will not change while you are
+running Octave, you can improve performance by calling
+<code>ignore_function_time_stamp ("all")</code>, so that Octave will
+ignore the time stamps for all function files.  Passing
+<code>"system"</code> to this function resets the default behavior.
+
+<!-- FIXME - note about time stamps on files in NFS environments? -->
+<!-- ./miscellaneous/edit.m -->
+   <p><a name="doc_002dedit"></a>
+
+<div class="defun">
+— Command: edit <var>name</var><var><a name="index-g_t_0040var_007bname_007d-613"></a></var><br>
+— Command: edit <var>field</var><var> value<a name="index-g_t_0040var_007bfield_007d-614"></a></var><br>
+— Command: <var>value</var> = <b>edit</b><var> get field<a name="index-edit-615"></a></var><br>
+<blockquote><p>Edit the named function, or change editor settings.
+
+        <p>If <code>edit</code> is called with the name of a file or function as
+its argument it will be opened in a text editor.
+
+          <ul>
+<li>If the function <var>name</var> is available in a file on your path and
+that file is modifiable, then it will be edited in place.  If it
+is a system function, then it will first be copied to the directory
+<code>HOME</code> (see further down) and then edited. 
+If no file is found, then the m-file
+variant, ending with ".m", will be considered.  If still no file
+is found, then variants with a leading "@" and then with both a
+leading "@" and trailing ".m" will be considered.
+
+          <li>If <var>name</var> is the name of a function defined in the interpreter but
+not in an m-file, then an m-file will be created in <code>HOME</code>
+to contain that function along with its current definition.
+
+          <li>If <code>name.cc</code> is specified, then it will search for <code>name.cc</code>
+in the path and try to modify it, otherwise it will create a new
+<samp><span class="file">.cc</span></samp> file in <code>HOME</code>.  If <var>name</var> happens to be an
+m-file or interpreter defined function, then the text of that
+function will be inserted into the .cc file as a comment.
+
+          <li>If <var>name.ext</var> is on your path then it will be edited, otherwise
+the editor will be started with <samp><span class="file">HOME/name.ext</span></samp> as the
+filename.  If <samp><span class="file">name.ext</span></samp> is not modifiable, it will be copied to
+<code>HOME</code> before editing.
+
+          <p><strong>WARNING!</strong> You may need to clear name before the new definition
+is available.  If you are editing a .cc file, you will need
+to mkoctfile <samp><span class="file">name.cc</span></samp> before the definition will be available. 
+</ul>
+
+        <p>If <code>edit</code> is called with <var>field</var> and <var>value</var> variables,
+the value of the control field <var>field</var> will be <var>value</var>. 
+If an output argument is requested and the first argument is <code>get</code>
+then <code>edit</code> will return the value of the control field <var>field</var>. 
+If the control field does not exist, edit will return a structure
+containing all fields and values.  Thus, <code>edit get all</code> returns
+a complete control structure. 
+The following control fields are used:
+
+          <dl>
+<dt>‘<samp><span class="samp">editor</span></samp>’<dd>This is the editor to use to modify the functions.  By default it uses
+Octave's <code>EDITOR</code> built-in function, which comes from
+<code>getenv("EDITOR")</code> and defaults to <code>emacs</code>.  Use <code>%s</code>
+In place of the function name.  For example,
+               <dl>
+<dt>‘<samp><span class="samp">[EDITOR, " %s"]</span></samp>’<dd>Use the editor which Octave uses for <code>bug_report</code>. 
+<br><dt>‘<samp><span class="samp">"xedit %s &"</span></samp>’<dd>pop up simple X11 editor in a separate window
+<br><dt>‘<samp><span class="samp">"gnudoit -q \"(find-file \\\"%s\\\")\""</span></samp>’<dd>Send it to current Emacs; must have <code>(gnuserv-start)</code> in <samp><span class="file">.emacs</span></samp>. 
+</dl>
+
+          <p>See also field 'mode', which controls how the editor is run by Octave.
+
+          <p>On Cygwin, you will need to convert the Cygwin path to a Windows
+path if you are using a native Windows editor.  For example
+<!-- Set example in small font to prevent overfull line -->
+          <pre class="smallexample">               '"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+</pre>
+          <br><dt>‘<samp><span class="samp">home</span></samp>’<dd>This is the location of user local m-files.  Be be sure it is in your
+path.  The default is <samp><span class="file">~/octave</span></samp>.
+
+          <br><dt>‘<samp><span class="samp">author</span></samp>’<dd>This is the name to put after the "## Author:" field of new functions. 
+By default it guesses from the <code>gecos</code> field of password database.
+
+          <br><dt>‘<samp><span class="samp">email</span></samp>’<dd>This is the e-mail address to list after the name in the author field. 
+By default it guesses <code><$LOGNAME@$HOSTNAME></code>, and if <code>$HOSTNAME</code>
+is not defined it uses <code>uname -n</code>.  You probably want to override this. 
+Be sure to use <code><user at host></code> as your format.
+
+          <br><dt>‘<samp><span class="samp">license</span></samp>’<dd>
+               <dl>
+<dt>‘<samp><span class="samp">gpl</span></samp>’<dd>GNU General Public License (default). 
+<br><dt>‘<samp><span class="samp">bsd</span></samp>’<dd>BSD-style license without advertising clause. 
+<br><dt>‘<samp><span class="samp">pd</span></samp>’<dd>Public domain. 
+<br><dt>‘<samp><span class="samp">"text"</span></samp>’<dd>Your own default copyright and license. 
+</dl>
+
+          <p>Unless you specify ‘<samp><span class="samp">pd</span></samp>’, edit will prepend the copyright statement
+with "Copyright (C) yyyy Function Author".
+
+          <br><dt>‘<samp><span class="samp">mode</span></samp>’<dd>This value determines whether the editor should be started in async mode
+(editor is started in the background and Octave continues) or sync mode
+(Octave waits until the editor exits).  Set it to "async" to start the editor
+in async mode.  The default is "sync" (see also "system").
+
+          <br><dt>‘<samp><span class="samp">editinplace</span></samp>’<dd>Determines whether files should be edited in place, without regard to
+whether they are modifiable or not.  The default is <code>false</code>. 
+</dl>
+        </p></blockquote></div>
+
+<!-- parse.cc -->
+   <p><a name="doc_002dmfilename"></a>
+
+<div class="defun">
+— Built-in Function:  <b>mfilename</b> ()<var><a name="index-mfilename-616"></a></var><br>
+— Built-in Function:  <b>mfilename</b> (<code>"fullpath"</code>)<var><a name="index-mfilename-617"></a></var><br>
+— Built-in Function:  <b>mfilename</b> (<code>"fullpathext"</code>)<var><a name="index-mfilename-618"></a></var><br>
+<blockquote><p>Return the name of the currently executing file.  At the top-level,
+return the empty string.  Given the argument <code>"fullpath"</code>,
+include the directory part of the file name, but not the extension. 
+Given the argument <code>"fullpathext"</code>, include the directory part
+of the file name and the extension. 
+</p></blockquote></div>
+
+<!-- symtab.cc -->
+   <p><a name="doc_002dignore_005ffunction_005ftime_005fstamp"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>ignore_function_time_stamp</b> ()<var><a name="index-ignore_005ffunction_005ftime_005fstamp-619"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>ignore_function_time_stamp</b> (<var>new_val</var>)<var><a name="index-ignore_005ffunction_005ftime_005fstamp-620"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave checks
+the time stamp on files each time it looks up functions defined in
+function files.  If the internal variable is set to <code>"system"</code>,
+Octave will not automatically recompile function files in subdirectories of
+<samp><var>octave-home</var><span class="file">/lib/</span><var>version</var></samp> if they have changed since
+they were last compiled, but will recompile other function files in the
+search path if they change.  If set to <code>"all"</code>, Octave will not
+recompile any function files unless their definitions are removed with
+<code>clear</code>.  If set to "none", Octave will always check time stamps
+on files to determine whether functions defined in function files
+need to recompiled. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a>
+<li><a accesskey="2" href="Subfunctions.html#Subfunctions">Subfunctions</a>
+<li><a accesskey="3" href="Private-Functions.html#Private-Functions">Private Functions</a>
+<li><a accesskey="4" href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a>
+<li><a accesskey="5" href="Function-Locking.html#Function-Locking">Function Locking</a>
+<li><a accesskey="6" href="Function-Precedence.html#Function-Precedence">Function Precedence</a>
+</ul>
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> The ‘<samp><span class="samp">.m</span></samp>’ suffix was chosen for compatibility
+with <span class="sc">matlab</span>.</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Handles-Inline-Functions-and-Anonymous-Functions.html b/doc/interpreter/HTML/Function-Handles-Inline-Functions-and-Anonymous-Functions.html
new file mode 100644
index 0000000..74b6557
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Handles-Inline-Functions-and-Anonymous-Functions.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Function Handles Inline Functions and Anonymous Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Script-Files.html#Script-Files" title="Script Files">
+<link rel="next" href="Commands.html#Commands" title="Commands">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Handles-Inline-Functions-and-Anonymous-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Commands.html#Commands">Commands</a>,
+Previous: <a rel="previous" accesskey="p" href="Script-Files.html#Script-Files">Script Files</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.9 Function Handles, Inline Functions, and Anonymous Functions</h3>
+
+<p><a name="index-handle_002c-function-handles-643"></a><a name="index-inline_002c-inline-functions-644"></a><a name="index-anonymous-functions-645"></a>
+It can be very convenient store a function in a variable so that it
+can be passed to a different function.  For example, a function that
+performs numerical minimization needs access to the function that
+should be minimized.
+
+<ul class="menu">
+<li><a accesskey="1" href="Function-Handles.html#Function-Handles">Function Handles</a>
+<li><a accesskey="2" href="Anonymous-Functions.html#Anonymous-Functions">Anonymous Functions</a>
+<li><a accesskey="3" href="Inline-Functions.html#Inline-Functions">Inline Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Handles.html b/doc/interpreter/HTML/Function-Handles.html
new file mode 100644
index 0000000..4f27307
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Handles.html
@@ -0,0 +1,93 @@
+<html lang="en">
+<head>
+<title>Function Handles - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions" title="Function Handles Inline Functions and Anonymous Functions">
+<link rel="next" href="Anonymous-Functions.html#Anonymous-Functions" title="Anonymous Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Handles"></a>
+Next: <a rel="next" accesskey="n" href="Anonymous-Functions.html#Anonymous-Functions">Anonymous Functions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.9.1 Function Handles</h4>
+
+<p>A function handle is a pointer to another function and is defined with
+the syntax
+
+<pre class="example">     @<var>function-name</var>
+</pre>
+   <p class="noindent">For example
+
+<pre class="example">     f = @sin;
+</pre>
+   <p class="noindent">Creates a function handle called <code>f</code> that refers to the
+function <code>sin</code>.
+
+   <p>Function handles are used to call other functions indirectly, or to pass
+a function as an argument to another function like <code>quad</code> or
+<code>fsolve</code>.  For example
+
+<pre class="example">     f = @sin;
+     quad (f, 0, pi)
+          2
+</pre>
+   <p>You may use <code>feval</code> to call a function using function handle, or
+simply write the name of the function handle followed by an argument
+list.  If there are no arguments, you must use an empty argument list
+‘<samp><span class="samp">()</span></samp>’.  For example
+
+<pre class="example">     f = @sin;
+     feval (f, pi/4)
+          0.70711
+     f (pi/4)
+          0.70711
+</pre>
+   <!-- ov-fcn-handle.cc -->
+   <p><a name="doc_002dfunctions"></a>
+
+<div class="defun">
+— Built-in Function:  <b>functions</b> (<var>fcn_handle</var>)<var><a name="index-functions-646"></a></var><br>
+<blockquote><p>Return a struct containing information about the function handle
+<var>fcn_handle</var>. 
+</p></blockquote></div>
+
+<!-- ov-fcn-handle.cc -->
+   <p><a name="doc_002dfunc2str"></a>
+
+<div class="defun">
+— Built-in Function:  <b>func2str</b> (<var>fcn_handle</var>)<var><a name="index-func2str-647"></a></var><br>
+<blockquote><p>Return a string containing the name of the function referenced by
+the function handle <var>fcn_handle</var>. 
+</p></blockquote></div>
+
+<!-- ov-fcn-handle.cc -->
+   <p><a name="doc_002dstr2func"></a>
+
+<div class="defun">
+— Built-in Function:  <b>str2func</b> (<var>fcn_name</var>)<var><a name="index-str2func-648"></a></var><br>
+<blockquote><p>Return a function handle constructed from the string <var>fcn_name</var>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Headers.html b/doc/interpreter/HTML/Function-Headers.html
new file mode 100644
index 0000000..9631e69
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Headers.html
@@ -0,0 +1,142 @@
+<html lang="en">
+<head>
+<title>Function Headers - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link rel="prev" href="Comment-Tips.html#Comment-Tips" title="Comment Tips">
+<link rel="next" href="Documentation-Tips.html#Documentation-Tips" title="Documentation Tips">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Headers"></a>
+Next: <a rel="next" accesskey="n" href="Documentation-Tips.html#Documentation-Tips">Documentation Tips</a>,
+Previous: <a rel="previous" accesskey="p" href="Comment-Tips.html#Comment-Tips">Comment Tips</a>,
+Up: <a rel="up" accesskey="u" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
+<hr>
+</div>
+
+<h3 class="section">C.4 Conventional Headers for Octave Functions</h3>
+
+<p><a name="index-header-comments-2510"></a>
+Octave has conventions for using special comments in function files
+to give information such as who wrote them.  This section explains these
+conventions.
+
+   <p>The top of the file should contain a copyright notice, followed by a
+block of comments that can be used as the help text for the function. 
+Here is an example:
+
+<pre class="example">     ## Copyright (C) 1996, 1997, 2007 John W. Eaton
+     ##
+     ## This file is part of Octave.
+     ##
+     ## Octave is free software; you can redistribute it and/or
+     ## modify it under the terms of the GNU General Public
+     ## License as published by the Free Software Foundation;
+     ## either version 3 of the License, or (at your option) any
+     ## later version.
+     ##
+     ## Octave is distributed in the hope that it will be useful,
+     ## but WITHOUT ANY WARRANTY; without even the implied
+     ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     ## PURPOSE.  See the GNU General Public License for more
+     ## details.
+     ##
+     ## You should have received a copy of the GNU General Public
+     ## License along with Octave; see the file COPYING.  If not,
+     ## see <http://www.gnu.org/licenses/>.
+     
+     ## usage: [IN, OUT, PID] = popen2 (COMMAND, ARGS)
+     ##
+     ## Start a subprocess with two-way communication.  COMMAND
+     ## specifies the name of the command to start.  ARGS is an
+     ## array of strings containing options for COMMAND.  IN and
+     ## OUT are the file ids of the input and streams for the
+     ## subprocess, and PID is the process id of the subprocess,
+     ## or -1 if COMMAND could not be executed.
+     ##
+     ## Example:
+     ##
+     ##  [in, out, pid] = popen2 ("sort", "-nr");
+     ##  fputs (in, "these\nare\nsome\nstrings\n");
+     ##  fclose (in);
+     ##  while (ischar (s = fgets (out)))
+     ##    fputs (stdout, s);
+     ##  endwhile
+     ##  fclose (out);
+</pre>
+   <p>Octave uses the first block of comments in a function file that do not
+appear to be a copyright notice as the help text for the file.  For
+Octave to recognize the first comment block as a copyright notice, it
+must start with the word `Copyright' after stripping the leading
+comment characters.
+
+   <p>After the copyright notice and help text come several <dfn>header
+comment</dfn> lines, each beginning with ‘<samp><span class="samp">## </span><var>header-name</var><span class="samp">:</span></samp>’.  For
+example,
+
+<pre class="example">     ## Author: jwe
+     ## Keywords: subprocesses input-output
+     ## Maintainer: jwe
+</pre>
+   <p>Here is a table of the conventional possibilities for <var>header-name</var>:
+
+     <dl>
+<dt>‘<samp><span class="samp">Author</span></samp>’<dd>This line states the name and net address of at least the principal
+author of the library.
+
+     <pre class="example">          ## Author: John W. Eaton <jwe at octave.org>
+</pre>
+     <br><dt>‘<samp><span class="samp">Maintainer</span></samp>’<dd>This line should contain a single name/address as in the Author line, or
+an address only, or the string ‘<samp><span class="samp">jwe</span></samp>’.  If there is no maintainer
+line, the person(s) in the Author field are presumed to be the
+maintainers.  The example above is mildly bogus because the maintainer
+line is redundant.
+
+     <p>The idea behind the ‘<samp><span class="samp">Author</span></samp>’ and ‘<samp><span class="samp">Maintainer</span></samp>’ lines is to make
+possible a function to “send mail to the maintainer” without
+having to mine the name out by hand.
+
+     <p>Be sure to surround the network address with ‘<samp><span class="samp"><...></span></samp>’ if
+you include the person's full name as well as the network address.
+
+     <br><dt>‘<samp><span class="samp">Created</span></samp>’<dd>This optional line gives the original creation date of the
+file.  For historical interest only.
+
+     <br><dt>‘<samp><span class="samp">Version</span></samp>’<dd>If you wish to record version numbers for the individual Octave program,
+put them in this line.
+
+     <br><dt>‘<samp><span class="samp">Adapted-By</span></samp>’<dd>In this header line, place the name of the person who adapted the
+library for installation (to make it fit the style conventions, for
+example).
+
+     <br><dt>‘<samp><span class="samp">Keywords</span></samp>’<dd>This line lists keywords.  Eventually, it will be used by an apropos
+command to allow people will find your package when they're looking for
+things by topic area.  To separate the keywords, you can use spaces,
+commas, or both. 
+</dl>
+
+   <p>Just about every Octave function ought to have the ‘<samp><span class="samp">Author</span></samp>’ and
+‘<samp><span class="samp">Keywords</span></samp>’ header comment lines.  Use the others if they are
+appropriate.  You can also put in header lines with other header
+names—they have no standard meanings, so they can't do any harm.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Index.html b/doc/interpreter/HTML/Function-Index.html
new file mode 100644
index 0000000..41e7b9e
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Index.html
@@ -0,0 +1,1299 @@
+<html lang="en">
+<head>
+<title>Function Index - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Concept-Index.html#Concept-Index" title="Concept Index">
+<link rel="next" href="Operator-Index.html#Operator-Index" title="Operator Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Index"></a>
+Next: <a rel="next" accesskey="n" href="Operator-Index.html#Operator-Index">Operator Index</a>,
+Previous: <a rel="previous" accesskey="p" href="Concept-Index.html#Concept-Index">Concept Index</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Function Index</h2>
+
+
+
+<ul class="index-fn" compact>
+<li><a href="Controlling-Subprocesses.html#index-g_t_0028-2388"><code>(</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Command-Line-Options.html#index-g_t_0028-67"><code>(</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Getting-Help.html#index-g_t_002dall-88"><code>-all</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-g_t_003d-1727"><code>=</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Nonlinear-Equations.html#index-g_t_003d-1634"><code>=</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Complex-Arithmetic.html#index-abs-1376"><code>abs</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Sums-and-Products.html#index-accumarray-1434"><code>accumarray</code></a>: <a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a></li>
+<li><a href="Trigonometry.html#index-acos-1392"><code>acos</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acosd-1417"><code>acosd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acosh-1404"><code>acosh</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acot-1396"><code>acot</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acotd-1421"><code>acotd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acoth-1408"><code>acoth</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acsc-1395"><code>acsc</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acscd-1420"><code>acscd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-acsch-1407"><code>acsch</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Object-Groups.html#index-addlistener-1225"><code>addlistener</code></a>: <a href="Object-Groups.html#Object-Groups">Object Groups</a></li>
+<li><a href="Manipulating-the-load-path.html#index-addpath-621"><code>addpath</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Object-Groups.html#index-addproperty-1224"><code>addproperty</code></a>: <a href="Object-Groups.html#Object-Groups">Object Groups</a></li>
+<li><a href="Timing-Utilities.html#index-addtodate-2299"><code>addtodate</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Special-Functions.html#index-airy-1482"><code>airy</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-all-1261"><code>all</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Graphics-Objects.html#index-allchild-1135"><code>allchild</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Mathematical-Considerations.html#index-amd-1686"><code>amd</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Graphics-Objects.html#index-ancestor-1133"><code>ancestor</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Complex-Arithmetic.html#index-angle-1378"><code>angle</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Tests.html#index-anova-1865"><code>anova</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-any-1260"><code>any</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Signal-Processing.html#index-arch_005ffit-2148"><code>arch_fit</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-arch_005frnd-2149"><code>arch_rnd</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-arch_005ftest-2150"><code>arch_test</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-area-935"><code>area</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Complex-Arithmetic.html#index-arg-1377"><code>arg</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Inline-Functions.html#index-argnames-652"><code>argnames</code></a>: <a href="Inline-Functions.html#Inline-Functions">Inline Functions</a></li>
+<li><a href="Command-Line-Options.html#index-argv-65"><code>argv</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Signal-Processing.html#index-arma_005frnd-2151"><code>arma_rnd</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Applying-a-Function-to-an-Array.html#index-arrayfun-1306"><code>arrayfun</code></a>: <a href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">Applying a Function to an Array</a></li>
+<li><a href="Timing-Utilities.html#index-asctime-2274"><code>asctime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Trigonometry.html#index-asec-1394"><code>asec</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-asecd-1419"><code>asecd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-asech-1406"><code>asech</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-asin-1391"><code>asin</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-asind-1416"><code>asind</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-asinh-1403"><code>asinh</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Test-Functions.html#index-assert-2492"><code>assert</code></a>: <a href="Test-Functions.html#Test-Functions">Test Functions</a></li>
+<li><a href="Evaluation-in-a-Different-Context.html#index-assignin-553"><code>assignin</code></a>: <a href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context">Evaluation in a Different Context</a></li>
+<li><a href="Trigonometry.html#index-atan-1393"><code>atan</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-atan2-1409"><code>atan2</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-atand-1418"><code>atand</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-atanh-1405"><code>atanh</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Quitting-Octave.html#index-atexit-81"><code>atexit</code></a>: <a href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a></li>
+<li><a href="Signal-Processing.html#index-autocor-2152"><code>autocor</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-autocov-2153"><code>autocov</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Overloading-and-Autoloading.html#index-autoload-638"><code>autoload</code></a>: <a href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a></li>
+<li><a href="Signal-Processing.html#index-autoreg_005fmatrix-2154"><code>autoreg_matrix</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Representing-Images.html#index-autumn-2214"><code>autumn</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Graphics-backends.html#index-available_005fbackends-1256"><code>available_backends</code></a>: <a href="Graphics-backends.html#Graphics-backends">Graphics backends</a></li>
+<li><a href="Graphics-Objects.html#index-axes-1136"><code>axes</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-axis-945"><code>axis</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Graphics-backends.html#index-backend-1254"><code>backend</code></a>: <a href="Graphics-backends.html#Graphics-backends">Graphics backends</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-balance-1549"><code>balance</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-bar-830"><code>bar</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-barh-836"><code>barh</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Signal-Processing.html#index-bartlett-2155"><code>bartlett</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Tests.html#index-bartlett_005ftest-1866"><code>bartlett_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="String-Conversions.html#index-base2dec-340"><code>base2dec</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Raising-Errors.html#index-beep-667"><code>beep</code></a>: <a href="Raising-Errors.html#Raising-Errors">Raising Errors</a></li>
+<li><a href="Raising-Errors.html#index-beep_005fon_005ferror-668"><code>beep_on_error</code></a>: <a href="Raising-Errors.html#Raising-Errors">Raising Errors</a></li>
+<li><a href="Special-Functions.html#index-besselh-1487"><code>besselh</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-besseli-1485"><code>besseli</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-besselj-1483"><code>besselj</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-besselk-1486"><code>besselk</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-bessely-1484"><code>bessely</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-beta-1488"><code>beta</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Distributions.html#index-betacdf-1891"><code>betacdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Special-Functions.html#index-betainc-1489"><code>betainc</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Distributions.html#index-betainv-1892"><code>betainv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Special-Functions.html#index-betaln-1490"><code>betaln</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Distributions.html#index-betapdf-1893"><code>betapdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-betarnd-1955"><code>betarnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Specialized-Solvers.html#index-bicgstab-1627"><code>bicgstab</code></a>: <a href="Specialized-Solvers.html#Specialized-Solvers">Specialized Solvers</a></li>
+<li><a href="Multi_002ddimensional-Interpolation.html#index-bicubic-2083"><code>bicubic</code></a>: <a href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a></li>
+<li><a href="String-Conversions.html#index-bin2dec-335"><code>bin2dec</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Special-Functions.html#index-bincoeff-1491"><code>bincoeff</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Distributions.html#index-binocdf-1894"><code>binocdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-binoinv-1895"><code>binoinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-binopdf-1896"><code>binopdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-binornd-1957"><code>binornd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Bit-Manipulations.html#index-bitand-254"><code>bitand</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitcmp-257"><code>bitcmp</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitget-252"><code>bitget</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitmax-253"><code>bitmax</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitor-255"><code>bitor</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitset-250"><code>bitset</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitshift-258"><code>bitshift</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Bit-Manipulations.html#index-bitxor-256"><code>bitxor</code></a>: <a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a></li>
+<li><a href="Signal-Processing.html#index-blackman-2156"><code>blackman</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Creating-Strings.html#index-blanks-287"><code>blanks</code></a>: <a href="Creating-Strings.html#Creating-Strings">Creating Strings</a></li>
+<li><a href="Rearranging-Matrices.html#index-blkdiag-1305"><code>blkdiag</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Representing-Images.html#index-bone-2215"><code>bone</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Plot-Annotations.html#index-box-1083"><code>box</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Representing-Images.html#index-brighten-2211"><code>brighten</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Applying-a-Function-to-an-Array.html#index-bsxfun-1312"><code>bsxfun</code></a>: <a href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">Applying a Function to an Array</a></li>
+<li><a href="Bug-Lists.html#index-bug_005freport-2541"><code>bug_report</code></a>: <a href="Bug-Lists.html#Bug-Lists">Bug Lists</a></li>
+<li><a href="Reporting-Bugs.html#index-bug_005freport-2519"><code>bug_report</code></a>: <a href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a></li>
+<li><a href="Overloading-and-Autoloading.html#index-builtin-637"><code>builtin</code></a>: <a href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a></li>
+<li><a href="File-Archiving-Utilities.html#index-bunzip2-2349"><code>bunzip2</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-byte_005fsize-2476"><code>byte_size</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="File-Archiving-Utilities.html#index-bzip2-2361"><code>bzip2</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Status-of-Variables.html#index-C-433"><code>C</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Timing-Utilities.html#index-calendar-2300"><code>calendar</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-canonicalize_005ffile_005fname-2335"><code>canonicalize_file_name</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Coordinate-Transformations.html#index-cart2pol-1503"><code>cart2pol</code></a>: <a href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a></li>
+<li><a href="Coordinate-Transformations.html#index-cart2sph-1507"><code>cart2sph</code></a>: <a href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a></li>
+<li><a href="Built_002din-Data-Types.html#index-cast-179"><code>cast</code></a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="Rearranging-Matrices.html#index-cat-1277"><code>cat</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Distributions.html#index-cauchy_005fcdf-1897"><code>cauchy_cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-cauchy_005finv-1898"><code>cauchy_inv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-cauchy_005fpdf-1899"><code>cauchy_pdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-cauchy_005frnd-1959"><code>cauchy_rnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-caxis-946"><code>caxis</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Mathematical-Considerations.html#index-ccolamd-1688"><code>ccolamd</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Current-Working-Directory.html#index-cd-2425"><code>cd</code></a>: <a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a></li>
+<li><a href="A-Sample-Command-Description.html#index-cd-23"><code>cd</code></a>: <a href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a></li>
+<li><a href="Utility-Functions.html#index-ceil-1436"><code>ceil</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Creating-Cell-Arrays.html#index-cell-390"><code>cell</code></a>: <a href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a></li>
+<li><a href="Processing-Data-in-Cell-Arrays.html#index-cell2mat-408"><code>cell2mat</code></a>: <a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a></li>
+<li><a href="Processing-Data-in-Cell-Arrays.html#index-cell2struct-409"><code>cell2struct</code></a>: <a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a></li>
+<li><a href="Basic-Usage-of-Cell-Arrays.html#index-celldisp-388"><code>celldisp</code></a>: <a href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a></li>
+<li><a href="Processing-Data-in-Cell-Arrays.html#index-cellfun-400"><code>cellfun</code></a>: <a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a></li>
+<li><a href="Cell-Arrays-of-Strings.html#index-cellidx-399"><code>cellidx</code></a>: <a href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a></li>
+<li><a href="Cell-Arrays-of-Strings.html#index-cellstr-397"><code>cellstr</code></a>: <a href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-center-1841"><code>center</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Specialized-Solvers.html#index-cgs-1629"><code>cgs</code></a>: <a href="Specialized-Solvers.html#Specialized-Solvers">Specialized Solvers</a></li>
+<li><a href="Concatenating-Strings.html#index-char-288"><code>char</code></a>: <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a></li>
+<li><a href="Current-Working-Directory.html#index-chdir-2426"><code>chdir</code></a>: <a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a></li>
+<li><a href="A-Sample-Command-Description.html#index-chdir-24"><code>chdir</code></a>: <a href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a></li>
+<li><a href="Distributions.html#index-chi2cdf-1900"><code>chi2cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-chi2inv-1901"><code>chi2inv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-chi2rnd-1961"><code>chi2rnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Distributions.html#index-chisquare_005fpdf-1902"><code>chisquare_pdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Tests.html#index-chisquare_005ftest_005fhomogeneity-1867"><code>chisquare_test_homogeneity</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Tests.html#index-chisquare_005ftest_005findependence-1868"><code>chisquare_test_independence</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Matrix-Factorizations.html#index-chol-1582"><code>chol</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-chol2inv-1589"><code>chol2inv</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-choldelete-1592"><code>choldelete</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-cholinsert-1591"><code>cholinsert</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-cholinv-1588"><code>cholinv</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-cholshift-1593"><code>cholshift</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-cholupdate-1590"><code>cholupdate</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Rearranging-Matrices.html#index-circshift-1287"><code>circshift</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Graphics-Objects.html#index-cla-1177"><code>cla</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Plot-Annotations.html#index-clabel-1076"><code>clabel</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Built_002din-Data-Types.html#index-class-175"><code>class</code></a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="Cursor-Motion.html#index-clc-107"><code>clc</code></a>: <a href="Cursor-Motion.html#Cursor-Motion">Cursor Motion</a></li>
+<li><a href="Status-of-Variables.html#index-clear-441"><code>clear</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Graphics-Objects.html#index-clf-1173"><code>clf</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Timing-Utilities.html#index-clock-2277"><code>clock</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-cloglog-1859"><code>cloglog</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Graphics-Objects.html#index-close-1184"><code>close</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-closereq-1188"><code>closereq</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Mathematical-Considerations.html#index-colamd-1692"><code>colamd</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Orthogonal-Collocation.html#index-colloc-1780"><code>colloc</code></a>: <a href="Orthogonal-Collocation.html#Orthogonal-Collocation">Orthogonal Collocation</a></li>
+<li><a href="Indexing-Objects.html#index-colon-2264"><code>colon</code></a>: <a href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a></li>
+<li><a href="Plot-Annotations.html#index-colorbar-1088"><code>colorbar</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Representing-Images.html#index-colormap-2209"><code>colormap</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Mathematical-Considerations.html#index-colperm-1696"><code>colperm</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Object-Sizes.html#index-columns-201"><code>columns</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-comet-941"><code>comet</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Installing-and-Removing-Packages.html#index-g_t_0040var_007bcommand_007d-2466"><var>command</var></a>: <a href="Installing-and-Removing-Packages.html#Installing-and-Removing-Packages">Installing and Removing Packages</a></li>
+<li><a href="Manipulating-the-load-path.html#index-command_005fline_005fpath-634"><code>command_line_path</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-common_005fsize-1271"><code>common_size</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Special-Functions.html#index-commutation_005fmatrix-1492"><code>commutation_matrix</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Finding-Roots.html#index-compan-2027"><code>compan</code></a>: <a href="Finding-Roots.html#Finding-Roots">Finding Roots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-compass-923"><code>compass</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Set-Operations.html#index-complement-2014"><code>complement</code></a>: <a href="Set-Operations.html#Set-Operations">Set Operations</a></li>
+<li><a href="Commands-For-Completion.html#index-completion_005fappend_005fchar-110"><code>completion_append_char</code></a>: <a href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a></li>
+<li><a href="Commands-For-Completion.html#index-completion_005fmatches-112"><code>completion_matches</code></a>: <a href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a></li>
+<li><a href="Numeric-Data-Types.html#index-complex-214"><code>complex</code></a>: <a href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a></li>
+<li><a href="System-Information.html#index-computer-2442"><code>computer</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-cond-1553"><code>cond</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-condest-1712"><code>condest</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Filesystem-Utilities.html#index-confirm_005frecursive_005frmdir-2321"><code>confirm_recursive_rmdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Complex-Arithmetic.html#index-conj-1379"><code>conj</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-contour-876"><code>contour</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-contour3-892"><code>contour3</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-contourc-891"><code>contourc</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-contourf-883"><code>contourf</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Representing-Images.html#index-contrast-2231"><code>contrast</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Products-of-Polynomials.html#index-conv-2031"><code>conv</code></a>: <a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a></li>
+<li><a href="Products-of-Polynomials.html#index-conv2-2034"><code>conv2</code></a>: <a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a></li>
+<li><a href="Convex-Hull.html#index-convhull-2113"><code>convhull</code></a>: <a href="Convex-Hull.html#Convex-Hull">Convex Hull</a></li>
+<li><a href="Convex-Hull.html#index-convhulln-2115"><code>convhulln</code></a>: <a href="Convex-Hull.html#Convex-Hull">Convex Hull</a></li>
+<li><a href="Products-of-Polynomials.html#index-convn-2032"><code>convn</code></a>: <a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a></li>
+<li><a href="Representing-Images.html#index-cool-2216"><code>cool</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Representing-Images.html#index-copper-2217"><code>copper</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Filesystem-Utilities.html#index-copyfile-2337"><code>copyfile</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Descriptive-Statistics.html#index-cor-1834"><code>cor</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Tests.html#index-cor_005ftest-1869"><code>cor_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Descriptive-Statistics.html#index-corrcoef-1835"><code>corrcoef</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Trigonometry.html#index-cos-1386"><code>cos</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-cosd-1411"><code>cosd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-cosh-1398"><code>cosh</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-cot-1390"><code>cot</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-cotd-1415"><code>cotd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-coth-1402"><code>coth</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Descriptive-Statistics.html#index-cov-1833"><code>cov</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Complex-Arithmetic.html#index-cplxpair-1380"><code>cplxpair</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Timing-Utilities.html#index-cputime-2280"><code>cputime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#index-crash_005fdumps_005foctave_005fcore-755"><code>crash_dumps_octave_core</code></a>: <a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a></li>
+<li><a href="Utility-Functions.html#index-cross-1437"><code>cross</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Trigonometry.html#index-csc-1389"><code>csc</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-cscd-1414"><code>cscd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-csch-1401"><code>csch</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Concatenating-Strings.html#index-cstrcat-297"><code>cstrcat</code></a>: <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a></li>
+<li><a href="Simple-File-I_002fO.html#index-csvread-754"><code>csvread</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Simple-File-I_002fO.html#index-csvwrite-753"><code>csvwrite</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Mathematical-Considerations.html#index-csymamd-1697"><code>csymamd</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Timing-Utilities.html#index-ctime-2270"><code>ctime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Utility-Functions.html#index-cummax-1470"><code>cummax</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Utility-Functions.html#index-cummin-1473"><code>cummin</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Sums-and-Products.html#index-cumprod-1430"><code>cumprod</code></a>: <a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a></li>
+<li><a href="Sums-and-Products.html#index-cumsum-1427"><code>cumsum</code></a>: <a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a></li>
+<li><a href="Functions-of-One-Variable.html#index-cumtrapz-1777"><code>cumtrapz</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-cut-1862"><code>cut</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Three_002ddimensional-Geometric-Shapes.html#index-cylinder-1050"><code>cylinder</code></a>: <a href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">Three-dimensional Geometric Shapes</a></li>
+<li><a href="Differential_002dAlgebraic-Equations.html#index-daspk-1789"><code>daspk</code></a>: <a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a></li>
+<li><a href="Differential_002dAlgebraic-Equations.html#index-daspk_005foptions-1790"><code>daspk_options</code></a>: <a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a></li>
+<li><a href="Differential_002dAlgebraic-Equations.html#index-dasrt-1793"><code>dasrt</code></a>: <a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a></li>
+<li><a href="Differential_002dAlgebraic-Equations.html#index-dasrt_005foptions-1794"><code>dasrt_options</code></a>: <a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a></li>
+<li><a href="Differential_002dAlgebraic-Equations.html#index-dassl-1791"><code>dassl</code></a>: <a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a></li>
+<li><a href="Differential_002dAlgebraic-Equations.html#index-dassl_005foptions-1792"><code>dassl_options</code></a>: <a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a></li>
+<li><a href="Timing-Utilities.html#index-date-2278"><code>date</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Timing-Utilities.html#index-datenum-2287"><code>datenum</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Timing-Utilities.html#index-datestr-2293"><code>datestr</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Timing-Utilities.html#index-datetick-2306"><code>datetick</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Timing-Utilities.html#index-datevec-2294"><code>datevec</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Breakpoints.html#index-dbclear-695"><code>dbclear</code></a>: <a href="Breakpoints.html#Breakpoints">Breakpoints</a></li>
+<li><a href="Leaving-Debug-Mode.html#index-dbcont-691"><code>dbcont</code></a>: <a href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">Leaving Debug Mode</a></li>
+<li><a href="Call-Stack.html#index-dbdown-706"><code>dbdown</code></a>: <a href="Call-Stack.html#Call-Stack">Call Stack</a></li>
+<li><a href="Functions-of-Multiple-Variables.html#index-dblquad-1781"><code>dblquad</code></a>: <a href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">Functions of Multiple Variables</a></li>
+<li><a href="Leaving-Debug-Mode.html#index-dbquit-692"><code>dbquit</code></a>: <a href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">Leaving Debug Mode</a></li>
+<li><a href="Call-Stack.html#index-dbstack-704"><code>dbstack</code></a>: <a href="Call-Stack.html#Call-Stack">Call Stack</a></li>
+<li><a href="Breakpoints.html#index-dbstatus-694"><code>dbstatus</code></a>: <a href="Breakpoints.html#Breakpoints">Breakpoints</a></li>
+<li><a href="Debug-Mode.html#index-dbstep-701"><code>dbstep</code></a>: <a href="Debug-Mode.html#Debug-Mode">Debug Mode</a></li>
+<li><a href="Breakpoints.html#index-dbstop-693"><code>dbstop</code></a>: <a href="Breakpoints.html#Breakpoints">Breakpoints</a></li>
+<li><a href="Debug-Mode.html#index-dbtype-699"><code>dbtype</code></a>: <a href="Debug-Mode.html#Debug-Mode">Debug Mode</a></li>
+<li><a href="Call-Stack.html#index-dbup-705"><code>dbup</code></a>: <a href="Call-Stack.html#Call-Stack">Call Stack</a></li>
+<li><a href="Debug-Mode.html#index-dbwhere-698"><code>dbwhere</code></a>: <a href="Debug-Mode.html#Debug-Mode">Debug Mode</a></li>
+<li><a href="Variable_002dlength-Return-Lists.html#index-deal-608"><code>deal</code></a>: <a href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a></li>
+<li><a href="Manipulating-Strings.html#index-deblank-312"><code>deblank</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Entering-Debug-Mode.html#index-debug_005fon_005ferror-689"><code>debug_on_error</code></a>: <a href="Entering-Debug-Mode.html#Entering-Debug-Mode">Entering Debug Mode</a></li>
+<li><a href="Entering-Debug-Mode.html#index-debug_005fon_005finterrupt-685"><code>debug_on_interrupt</code></a>: <a href="Entering-Debug-Mode.html#Entering-Debug-Mode">Entering Debug Mode</a></li>
+<li><a href="Entering-Debug-Mode.html#index-debug_005fon_005fwarning-687"><code>debug_on_warning</code></a>: <a href="Entering-Debug-Mode.html#Entering-Debug-Mode">Entering Debug Mode</a></li>
+<li><a href="String-Conversions.html#index-dec2base-339"><code>dec2base</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="String-Conversions.html#index-dec2bin-336"><code>dec2bin</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="String-Conversions.html#index-dec2hex-337"><code>dec2hex</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Products-of-Polynomials.html#index-deconv-2033"><code>deconv</code></a>: <a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a></li>
+<li><a href="Simple-File-I_002fO.html#index-default_005fsave_005foptions-737"><code>default_save_options</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Utility-Functions.html#index-del2-1439"><code>del2</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Delaunay-Triangulation.html#index-delaunay-2084"><code>delaunay</code></a>: <a href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a></li>
+<li><a href="Delaunay-Triangulation.html#index-delaunay3-2086"><code>delaunay3</code></a>: <a href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a></li>
+<li><a href="Delaunay-Triangulation.html#index-delaunayn-2088"><code>delaunayn</code></a>: <a href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a></li>
+<li><a href="Graphics-Objects.html#index-delete-1182"><code>delete</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Object-Groups.html#index-dellistener-1226"><code>dellistener</code></a>: <a href="Object-Groups.html#Object-Groups">Object Groups</a></li>
+<li><a href="Demonstration-Functions.html#index-demo-2499"><code>demo</code></a>: <a href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-det-1554"><code>det</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Signal-Processing.html#index-detrend-2122"><code>detrend</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Rearranging-Matrices.html#index-diag-1304"><code>diag</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-diary-147"><code>diary</code></a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-diff-1264"><code>diff</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Signal-Processing.html#index-diffpara-2157"><code>diffpara</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-diffuse-994"><code>diffuse</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-dims-2477"><code>dims</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="Current-Working-Directory.html#index-dir-2429"><code>dir</code></a>: <a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a></li>
+<li><a href="Distributions.html#index-discrete_005fcdf-1903"><code>discrete_cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-discrete_005finv-1904"><code>discrete_inv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-discrete_005fpdf-1905"><code>discrete_pdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-discrete_005frnd-1963"><code>discrete_rnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Terminal-Output.html#index-disp-707"><code>disp</code></a>: <a href="Terminal-Output.html#Terminal-Output">Terminal Output</a></li>
+<li><a href="Overloading-and-Autoloading.html#index-dispatch-636"><code>dispatch</code></a>: <a href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a></li>
+<li><a href="Manipulating-Classes.html#index-display-2258"><code>display</code></a>: <a href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a></li>
+<li><a href="Simple-File-I_002fO.html#index-dlmread-749"><code>dlmread</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Simple-File-I_002fO.html#index-dlmwrite-745"><code>dlmwrite</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Mathematical-Considerations.html#index-dmperm-1701"><code>dmperm</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-dmult-1555"><code>dmult</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="String-Conversions.html#index-do_005fstring_005fescapes-351"><code>do_string_escapes</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Getting-Help.html#index-doc_005fcache_005ffile-100"><code>doc_cache_file</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Controlling-Subprocesses.html#index-dos-2374"><code>dos</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-dot-1556"><code>dot</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Numeric-Data-Types.html#index-double-213"><code>double</code></a>: <a href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a></li>
+<li><a href="Graphics-Objects.html#index-drawnow-1163"><code>drawnow</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Identifying-points-in-Triangulation.html#index-dsearch-2097"><code>dsearch</code></a>: <a href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a></li>
+<li><a href="Identifying-points-in-Triangulation.html#index-dsearchn-2099"><code>dsearchn</code></a>: <a href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a></li>
+<li><a href="Controlling-Subprocesses.html#index-dup2-2386"><code>dup2</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Special-Functions.html#index-duplication_005fmatrix-1493"><code>duplication_matrix</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Signal-Processing.html#index-durbinlevinson-2158"><code>durbinlevinson</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Mathematical-Constants.html#index-e-1509"><code>e</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-echo-148"><code>echo</code></a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Diary-and-Echo-Commands.html#index-echo_005fexecuting_005fcommands-149"><code>echo_executing_commands</code></a>: <a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a></li>
+<li><a href="Function-Files.html#index-edit-615"><code>edit</code></a>: <a href="Function-Files.html#Function-Files">Function Files</a></li>
+<li><a href="Commands-For-History.html#index-edit_005fhistory-117"><code>edit_history</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Commands-For-History.html#index-EDITOR-127"><code>EDITOR</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-eig-1557"><code>eig</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-elem-2474"><code>elem</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="Three_002ddimensional-Geometric-Shapes.html#index-ellipsoid-1057"><code>ellipsoid</code></a>: <a href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">Three-dimensional Geometric Shapes</a></li>
+<li><a href="Distributions.html#index-empirical_005fcdf-1906"><code>empirical_cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-empirical_005finv-1907"><code>empirical_inv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-empirical_005fpdf-1908"><code>empirical_pdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-empirical_005frnd-1966"><code>empirical_rnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Group-Database-Functions.html#index-endgrent-2441"><code>endgrent</code></a>: <a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a></li>
+<li><a href="Password-Database-Functions.html#index-endpwent-2436"><code>endpwent</code></a>: <a href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a></li>
+<li><a href="Timing-Utilities.html#index-eomday-2305"><code>eomday</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Mathematical-Constants.html#index-eps-1534"><code>eps</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Special-Functions.html#index-erf-1494"><code>erf</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-erfc-1495"><code>erfc</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-erfinv-1496"><code>erfinv</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Catching-Errors.html#index-errno-674"><code>errno</code></a>: <a href="Catching-Errors.html#Catching-Errors">Catching Errors</a></li>
+<li><a href="Catching-Errors.html#index-errno_005flist-677"><code>errno_list</code></a>: <a href="Catching-Errors.html#Catching-Errors">Catching Errors</a></li>
+<li><a href="Raising-Errors.html#index-error-662"><code>error</code></a>: <a href="Raising-Errors.html#Raising-Errors">Raising Errors</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-errorbar-899"><code>errorbar</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Timing-Utilities.html#index-etime-2279"><code>etime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Information.html#index-etree-1672"><code>etree</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Information.html#index-etreeplot-1675"><code>etreeplot</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Evaluation.html#index-eval-546"><code>eval</code></a>: <a href="Evaluation.html#Evaluation">Evaluation</a></li>
+<li><a href="Evaluation-in-a-Different-Context.html#index-evalin-552"><code>evalin</code></a>: <a href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context">Evaluation in a Different Context</a></li>
+<li><a href="Demonstration-Functions.html#index-example-2501"><code>example</code></a>: <a href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a></li>
+<li><a href="Controlling-Subprocesses.html#index-exec-2384"><code>exec</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-EXEC_005fPATH-2381"><code>EXEC_PATH</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Status-of-Variables.html#index-exist-440"><code>exist</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Quitting-Octave.html#index-exit-79"><code>exit</code></a>: <a href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-exp-1361"><code>exp</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Distributions.html#index-expcdf-1909"><code>expcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-expinv-1910"><code>expinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Functions-of-a-Matrix.html#index-expm-1622"><code>expm</code></a>: <a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-expm1-1362"><code>expm1</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Distributions.html#index-exppdf-1911"><code>exppdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-exprnd-1969"><code>exprnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Special-Utility-Matrices.html#index-eye-1313"><code>eye</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Two_002ddimensional-Function-Plotting.html#index-ezcontour-963"><code>ezcontour</code></a>: <a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a></li>
+<li><a href="Two_002ddimensional-Function-Plotting.html#index-ezcontourf-968"><code>ezcontourf</code></a>: <a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a></li>
+<li><a href="Three_002ddimensional-Function-Plotting.html#index-ezmesh-1022"><code>ezmesh</code></a>: <a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a></li>
+<li><a href="Three_002ddimensional-Function-Plotting.html#index-ezmeshc-1029"><code>ezmeshc</code></a>: <a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a></li>
+<li><a href="Two_002ddimensional-Function-Plotting.html#index-ezplot-957"><code>ezplot</code></a>: <a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a></li>
+<li><a href="Three_002ddimensional-Function-Plotting.html#index-ezplot3-1017"><code>ezplot3</code></a>: <a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a></li>
+<li><a href="Two_002ddimensional-Function-Plotting.html#index-ezpolar-973"><code>ezpolar</code></a>: <a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a></li>
+<li><a href="Three_002ddimensional-Function-Plotting.html#index-ezsurf-1036"><code>ezsurf</code></a>: <a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a></li>
+<li><a href="Three_002ddimensional-Function-Plotting.html#index-ezsurfc-1043"><code>ezsurfc</code></a>: <a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a></li>
+<li><a href="Tests.html#index-f_005ftest_005fregression-1870"><code>f_test_regression</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Utility-Functions.html#index-factor-1442"><code>factor</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Utility-Functions.html#index-factorial-1444"><code>factorial</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Test-Functions.html#index-fail-2497"><code>fail</code></a>: <a href="Test-Functions.html#Test-Functions">Test Functions</a></li>
+<li><a href="Logical-Values.html#index-false-264"><code>false</code></a>: <a href="Logical-Values.html#Logical-Values">Logical Values</a></li>
+<li><a href="Distributions.html#index-fcdf-1912"><code>fcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="EOF-and-Errors.html#index-fclear-807"><code>fclear</code></a>: <a href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a></li>
+<li><a href="Opening-and-Closing-Files.html#index-fclose-776"><code>fclose</code></a>: <a href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">Opening and Closing Files</a></li>
+<li><a href="Controlling-Subprocesses.html#index-fcntl-2399"><code>fcntl</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Simple-File-I_002fO.html#index-fdisp-744"><code>fdisp</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-feather-928"><code>feather</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="EOF-and-Errors.html#index-feof-805"><code>feof</code></a>: <a href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a></li>
+<li><a href="EOF-and-Errors.html#index-ferror-806"><code>ferror</code></a>: <a href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a></li>
+<li><a href="Calling-a-Function-by-its-Name.html#index-feval-549"><code>feval</code></a>: <a href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a></li>
+<li><a href="Paging-Screen-Output.html#index-fflush-721"><code>fflush</code></a>: <a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a></li>
+<li><a href="Signal-Processing.html#index-fft-2123"><code>fft</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-fft2-2129"><code>fft2</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-fftconv-2133"><code>fftconv</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-fftfilt-2134"><code>fftfilt</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-fftn-2131"><code>fftn</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-fftshift-2159"><code>fftshift</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-fftw-2124"><code>fftw</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Line_002dOriented-Input.html#index-fgetl-779"><code>fgetl</code></a>: <a href="Line_002dOriented-Input.html#Line_002dOriented-Input">Line-Oriented Input</a></li>
+<li><a href="Line_002dOriented-Input.html#index-fgets-780"><code>fgets</code></a>: <a href="Line_002dOriented-Input.html#Line_002dOriented-Input">Line-Oriented Input</a></li>
+<li><a href="Function-Files.html#index-g_t_0040var_007bfield_007d-614"><var>field</var></a>: <a href="Function-Files.html#Function-Files">Function Files</a></li>
+<li><a href="Manipulating-Structures.html#index-fieldnames-378"><code>fieldnames</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Multiple-Plot-Windows.html#index-figure-1092"><code>figure</code></a>: <a href="Multiple-Plot-Windows.html#Multiple-Plot-Windows">Multiple Plot Windows</a></li>
+<li><a href="Manipulating-the-load-path.html#index-file_005fin_005floadpath-631"><code>file_in_loadpath</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Filesystem-Utilities.html#index-file_005fin_005fpath-2332"><code>file_in_path</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-fileattrib-2328"><code>fileattrib</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-filemarker-2341"><code>filemarker</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-fileparts-2338"><code>fileparts</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-filesep-2339"><code>filesep</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Graphics-Objects.html#index-fill-1151"><code>fill</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Signal-Processing.html#index-filter-2135"><code>filter</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-filter2-2139"><code>filter2</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-find-1268"><code>find</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Manipulating-the-load-path.html#index-find_005fdir_005fin_005fpath-635"><code>find_dir_in_path</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Searching-Properties.html#index-findall-1204"><code>findall</code></a>: <a href="Searching-Properties.html#Searching-Properties">Searching Properties</a></li>
+<li><a href="Searching-Properties.html#index-findobj-1197"><code>findobj</code></a>: <a href="Searching-Properties.html#Searching-Properties">Searching Properties</a></li>
+<li><a href="Manipulating-Strings.html#index-findstr-315"><code>findstr</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-finite-1267"><code>finite</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Distributions.html#index-finv-1913"><code>finv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Utility-Functions.html#index-fix-1445"><code>fix</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Matrices.html#index-fixed_005fpoint_005fformat-227"><code>fixed_point_format</code></a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Representing-Images.html#index-flag-2218"><code>flag</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Rearranging-Matrices.html#index-flipdim-1274"><code>flipdim</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-fliplr-1272"><code>fliplr</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-flipud-1273"><code>flipud</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Utility-Functions.html#index-floor-1446"><code>floor</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Utility-Functions.html#index-fmod-1447"><code>fmod</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Filesystem-Utilities.html#index-fnmatch-2331"><code>fnmatch</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="A-Sample-Function-Description.html#index-foo-17"><code>foo</code></a>: <a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a></li>
+<li><a href="Opening-and-Closing-Files.html#index-fopen-773"><code>fopen</code></a>: <a href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">Opening and Closing Files</a></li>
+<li><a href="Controlling-Subprocesses.html#index-fork-2383"><code>fork</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Terminal-Output.html#index-format-708"><code>format</code></a>: <a href="Terminal-Output.html#Terminal-Output">Terminal Output</a></li>
+<li><a href="Inline-Functions.html#index-formula-653"><code>formula</code></a>: <a href="Inline-Functions.html#Inline-Functions">Inline Functions</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-fortran_005fvec-2479"><code>fortran_vec</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="Distributions.html#index-fpdf-1914"><code>fpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Two_002ddimensional-Function-Plotting.html#index-fplot-953"><code>fplot</code></a>: <a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a></li>
+<li><a href="Formatted-Output.html#index-fprintf-782"><code>fprintf</code></a>: <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a></li>
+<li><a href="Simple-Output.html#index-fputs-777"><code>fputs</code></a>: <a href="Simple-Output.html#Simple-Output">Simple Output</a></li>
+<li><a href="Signal-Processing.html#index-fractdiff-2163"><code>fractdiff</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Binary-I_002fO.html#index-fread-800"><code>fread</code></a>: <a href="Binary-I_002fO.html#Binary-I_002fO">Binary I/O</a></li>
+<li><a href="EOF-and-Errors.html#index-freport-808"><code>freport</code></a>: <a href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a></li>
+<li><a href="Signal-Processing.html#index-freqz-2141"><code>freqz</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-freqz_005fplot-2145"><code>freqz_plot</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="File-Positioning.html#index-frewind-814"><code>frewind</code></a>: <a href="File-Positioning.html#File-Positioning">File Positioning</a></li>
+<li><a href="Random-Number-Generation.html#index-frnd-1971"><code>frnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Formatted-Input.html#index-fscanf-789"><code>fscanf</code></a>: <a href="Formatted-Input.html#Formatted-Input">Formatted Input</a></li>
+<li><a href="File-Positioning.html#index-fseek-810"><code>fseek</code></a>: <a href="File-Positioning.html#File-Positioning">File Positioning</a></li>
+<li><a href="Nonlinear-Equations.html#index-fsolve-1633"><code>fsolve</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Filesystem-Utilities.html#index-fstat-2327"><code>fstat</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="File-Positioning.html#index-ftell-809"><code>ftell</code></a>: <a href="File-Positioning.html#File-Positioning">File Positioning</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-full-1655"><code>full</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Filesystem-Utilities.html#index-fullfile-2342"><code>fullfile</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Function-Handles.html#index-func2str-647"><code>func2str</code></a>: <a href="Function-Handles.html#Function-Handles">Function Handles</a></li>
+<li><a href="Getting-Help.html#index-g_t_0040var_007bfunction_005fname_007d-86"><var>function_name</var></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Function-Handles.html#index-functions-646"><code>functions</code></a>: <a href="Function-Handles.html#Function-Handles">Function Handles</a></li>
+<li><a href="Binary-I_002fO.html#index-fwrite-801"><code>fwrite</code></a>: <a href="Binary-I_002fO.html#Binary-I_002fO">Binary I/O</a></li>
+<li><a href="Nonlinear-Equations.html#index-fzero-1635"><code>fzero</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Distributions.html#index-gamcdf-1915"><code>gamcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-gaminv-1916"><code>gaminv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Special-Functions.html#index-gamma-1497"><code>gamma</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-gammainc-1498"><code>gammainc</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Special-Functions.html#index-gammaln-1502"><code>gammaln</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Distributions.html#index-gampdf-1917"><code>gampdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-gamrnd-1973"><code>gamrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Graphics-Objects.html#index-gca-1130"><code>gca</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Callbacks.html#index-gcbf-1219"><code>gcbf</code></a>: <a href="Callbacks.html#Callbacks">Callbacks</a></li>
+<li><a href="Callbacks.html#index-gcbo-1217"><code>gcbo</code></a>: <a href="Callbacks.html#Callbacks">Callbacks</a></li>
+<li><a href="Utility-Functions.html#index-gcd-1448"><code>gcd</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Graphics-Objects.html#index-gcf-1129"><code>gcf</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Manipulating-the-load-path.html#index-genpath-623"><code>genpath</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Variables.html#index-genvarname-420"><code>genvarname</code></a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Distributions.html#index-geocdf-1918"><code>geocdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-geoinv-1919"><code>geoinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-geopdf-1920"><code>geopdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-geornd-1975"><code>geornd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Graphics-Objects.html#index-get-1131"><code>get</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Process-ID-Information.html#index-getegid-2420"><code>getegid</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Environment-Variables.html#index-getenv-2422"><code>getenv</code></a>: <a href="Environment-Variables.html#Environment-Variables">Environment Variables</a></li>
+<li><a href="Process-ID-Information.html#index-geteuid-2418"><code>geteuid</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Manipulating-Structures.html#index-getfield-380"><code>getfield</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Process-ID-Information.html#index-getgid-2421"><code>getgid</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Group-Database-Functions.html#index-getgrent-2437"><code>getgrent</code></a>: <a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a></li>
+<li><a href="Group-Database-Functions.html#index-getgrgid-2438"><code>getgrgid</code></a>: <a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a></li>
+<li><a href="Group-Database-Functions.html#index-getgrnam-2439"><code>getgrnam</code></a>: <a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a></li>
+<li><a href="Process-ID-Information.html#index-getpgrp-2415"><code>getpgrp</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Process-ID-Information.html#index-getpid-2416"><code>getpid</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Process-ID-Information.html#index-getppid-2417"><code>getppid</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Password-Database-Functions.html#index-getpwent-2432"><code>getpwent</code></a>: <a href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a></li>
+<li><a href="Password-Database-Functions.html#index-getpwnam-2434"><code>getpwnam</code></a>: <a href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a></li>
+<li><a href="Password-Database-Functions.html#index-getpwuid-2433"><code>getpwuid</code></a>: <a href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a></li>
+<li><a href="System-Information.html#index-getrusage-2462"><code>getrusage</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Process-ID-Information.html#index-getuid-2419"><code>getuid</code></a>: <a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a></li>
+<li><a href="Interacting-with-plots.html#index-ginput-1099"><code>ginput</code></a>: <a href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-givens-1561"><code>givens</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Filesystem-Utilities.html#index-glob-2330"><code>glob</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Linear-Programming.html#index-glpk-1801"><code>glpk</code></a>: <a href="Linear-Programming.html#Linear-Programming">Linear Programming</a></li>
+<li><a href="Linear-Least-Squares.html#index-gls-1805"><code>gls</code></a>: <a href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a></li>
+<li><a href="Representing-Images.html#index-gmap40-2232"><code>gmap40</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Timing-Utilities.html#index-gmtime-2271"><code>gmtime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Interaction-with-gnuplot.html#index-gnuplot_005fbinary-1258"><code>gnuplot_binary</code></a>: <a href="Interaction-with-gnuplot.html#Interaction-with-gnuplot">Interaction with gnuplot</a></li>
+<li><a href="Information.html#index-gplot-1677"><code>gplot</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Utility-Functions.html#index-gradient-1451"><code>gradient</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Representing-Images.html#index-gray-2219"><code>gray</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Representing-Images.html#index-gray2ind-2203"><code>gray2ind</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Plot-Annotations.html#index-grid-1085"><code>grid</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Interpolation-on-Scattered-Data.html#index-griddata-2118"><code>griddata</code></a>: <a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a></li>
+<li><a href="Interpolation-on-Scattered-Data.html#index-griddata3-2120"><code>griddata3</code></a>: <a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a></li>
+<li><a href="Interpolation-on-Scattered-Data.html#index-griddatan-2121"><code>griddatan</code></a>: <a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a></li>
+<li><a href="Interacting-with-plots.html#index-gtext-1101"><code>gtext</code></a>: <a href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a></li>
+<li><a href="File-Archiving-Utilities.html#index-gunzip-2352"><code>gunzip</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="File-Archiving-Utilities.html#index-gzip-2350"><code>gzip</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Famous-Matrices.html#index-hadamard-1350"><code>hadamard</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Signal-Processing.html#index-hamming-2164"><code>hamming</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Famous-Matrices.html#index-hankel-1351"><code>hankel</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Signal-Processing.html#index-hanning-2165"><code>hanning</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Matrix-Factorizations.html#index-hess-1594"><code>hess</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="String-Conversions.html#index-hex2dec-338"><code>hex2dec</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="String-Conversions.html#index-hex2num-342"><code>hex2num</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Object-Groups.html#index-hggroup-1221"><code>hggroup</code></a>: <a href="Object-Groups.html#Object-Groups">Object Groups</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-hidden-981"><code>hidden</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Famous-Matrices.html#index-hilb-1352"><code>hilb</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-hist-842"><code>hist</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-histc-1845"><code>histc</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Commands-For-History.html#index-history-116"><code>history</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Commands-For-History.html#index-history_005ffile-121"><code>history_file</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Commands-For-History.html#index-history_005fsize-123"><code>history_size</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Commands-For-History.html#index-history_005ftimestamp_005fformat_005fstring-125"><code>history_timestamp_format_string</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Graphics-Objects.html#index-hold-1169"><code>hold</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Cursor-Motion.html#index-home-108"><code>home</code></a>: <a href="Cursor-Motion.html#Cursor-Motion">Cursor Motion</a></li>
+<li><a href="Rearranging-Matrices.html#index-horzcat-1278"><code>horzcat</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Representing-Images.html#index-hot-2220"><code>hot</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Tests.html#index-hotelling_005ftest-1871"><code>hotelling_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Tests.html#index-hotelling_005ftest_005f2-1872"><code>hotelling_test_2</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Matrix-Factorizations.html#index-housh-1620"><code>housh</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Representing-Images.html#index-hsv-2221"><code>hsv</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Color-Conversion.html#index-hsv2rgb-2235"><code>hsv2rgb</code></a>: <a href="Color-Conversion.html#Color-Conversion">Color Conversion</a></li>
+<li><a href="Signal-Processing.html#index-hurst-2166"><code>hurst</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Distributions.html#index-hygecdf-1921"><code>hygecdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-hygeinv-1922"><code>hygeinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-hygepdf-1923"><code>hygepdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-hygernd-1977"><code>hygernd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Utility-Functions.html#index-hypot-1458"><code>hypot</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Mathematical-Constants.html#index-I-1519"><code>I</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Integer-Arithmetic.html#index-idivide-249"><code>idivide</code></a>: <a href="Integer-Arithmetic.html#Integer-Arithmetic">Integer Arithmetic</a></li>
+<li><a href="Signal-Processing.html#index-ifft-2128"><code>ifft</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-ifftn-2132"><code>ifftn</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-ifftshift-2161"><code>ifftshift</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Function-Files.html#index-ignore_005ffunction_005ftime_005fstamp-619"><code>ignore_function_time_stamp</code></a>: <a href="Function-Files.html#Function-Files">Function Files</a></li>
+<li><a href="Complex-Arithmetic.html#index-imag-1383"><code>imag</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Displaying-Images.html#index-image-2195"><code>image</code></a>: <a href="Displaying-Images.html#Displaying-Images">Displaying Images</a></li>
+<li><a href="Loading-and-Saving-Images.html#index-IMAGE_005fPATH-2185"><code>IMAGE_PATH</code></a>: <a href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a></li>
+<li><a href="Displaying-Images.html#index-image_005fviewer-2202"><code>image_viewer</code></a>: <a href="Displaying-Images.html#Displaying-Images">Displaying Images</a></li>
+<li><a href="Displaying-Images.html#index-imagesc-2197"><code>imagesc</code></a>: <a href="Displaying-Images.html#Displaying-Images">Displaying Images</a></li>
+<li><a href="Loading-and-Saving-Images.html#index-imfinfo-2187"><code>imfinfo</code></a>: <a href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a></li>
+<li><a href="Loading-and-Saving-Images.html#index-imread-2182"><code>imread</code></a>: <a href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a></li>
+<li><a href="Displaying-Images.html#index-imshow-2189"><code>imshow</code></a>: <a href="Displaying-Images.html#Displaying-Images">Displaying Images</a></li>
+<li><a href="Loading-and-Saving-Images.html#index-imwrite-2183"><code>imwrite</code></a>: <a href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a></li>
+<li><a href="Representing-Images.html#index-ind2gray-2204"><code>ind2gray</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Representing-Images.html#index-ind2rgb-2207"><code>ind2rgb</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Index-Expressions.html#index-ind2sub-452"><code>ind2sub</code></a>: <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a></li>
+<li><a href="Manipulating-Strings.html#index-index-319"><code>index</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Mathematical-Constants.html#index-Inf-1524"><code>Inf</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Precedence-of-Objects.html#index-inferiorto-2267"><code>inferiorto</code></a>: <a href="Precedence-of-Objects.html#Precedence-of-Objects">Precedence of Objects</a></li>
+<li><a href="Getting-Help.html#index-info-92"><code>info</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Getting-Help.html#index-info_005ffile-94"><code>info_file</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Getting-Help.html#index-info_005fprogram-96"><code>info_program</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Inline-Functions.html#index-inline-649"><code>inline</code></a>: <a href="Inline-Functions.html#Inline-Functions">Inline Functions</a></li>
+<li><a href="Voronoi-Diagrams.html#index-inpolygon-2112"><code>inpolygon</code></a>: <a href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a></li>
+<li><a href="Terminal-Input.html#index-input-722"><code>input</code></a>: <a href="Terminal-Input.html#Terminal-Input">Terminal Input</a></li>
+<li><a href="Defining-Functions.html#index-inputname-592"><code>inputname</code></a>: <a href="Defining-Functions.html#Defining-Functions">Defining Functions</a></li>
+<li><a href="Integer-Data-Types.html#index-int16-238"><code>int16</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Conversion-of-Numerical-Data-to-Strings.html#index-int2str-303"><code>int2str</code></a>: <a href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">Conversion of Numerical Data to Strings</a></li>
+<li><a href="Integer-Data-Types.html#index-int32-240"><code>int32</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-int64-242"><code>int64</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-int8-236"><code>int8</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="One_002ddimensional-Interpolation.html#index-interp1-2056"><code>interp1</code></a>: <a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a></li>
+<li><a href="One_002ddimensional-Interpolation.html#index-interp1q-2060"><code>interp1q</code></a>: <a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a></li>
+<li><a href="Multi_002ddimensional-Interpolation.html#index-interp2-2066"><code>interp2</code></a>: <a href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a></li>
+<li><a href="Multi_002ddimensional-Interpolation.html#index-interp3-2071"><code>interp3</code></a>: <a href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a></li>
+<li><a href="One_002ddimensional-Interpolation.html#index-interpft-2061"><code>interpft</code></a>: <a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a></li>
+<li><a href="Multi_002ddimensional-Interpolation.html#index-interpn-2077"><code>interpn</code></a>: <a href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a></li>
+<li><a href="Set-Operations.html#index-intersect-2012"><code>intersect</code></a>: <a href="Set-Operations.html#Set-Operations">Set Operations</a></li>
+<li><a href="Integer-Data-Types.html#index-intmax-244"><code>intmax</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-intmin-245"><code>intmin</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-intwarning-246"><code>intwarning</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-inv-1564"><code>inv</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-inverse-1565"><code>inverse</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Famous-Matrices.html#index-invhilb-1353"><code>invhilb</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-ipermute-1281"><code>ipermute</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-iqr-1861"><code>iqr</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Filesystem-Utilities.html#index-is_005fabsolute_005ffilename-2346"><code>is_absolute_filename</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-is_005fduplicate_005fentry-1263"><code>is_duplicate_entry</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Timing-Utilities.html#index-is_005fleap_005fyear-2281"><code>is_leap_year</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-is_005frooted_005frelative_005ffilename-2347"><code>is_rooted_relative_filename</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Built_002din-Data-Types.html#index-isa-178"><code>isa</code></a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="Character-Class-Functions.html#index-isalnum-353"><code>isalnum</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Character-Class-Functions.html#index-isalpha-354"><code>isalpha</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Character-Class-Functions.html#index-isascii-356"><code>isascii</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Basic-Usage-of-Cell-Arrays.html#index-iscell-389"><code>iscell</code></a>: <a href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a></li>
+<li><a href="Cell-Arrays-of-Strings.html#index-iscellstr-398"><code>iscellstr</code></a>: <a href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a></li>
+<li><a href="Character-Arrays.html#index-ischar-284"><code>ischar</code></a>: <a href="Character-Arrays.html#Character-Arrays">Character Arrays</a></li>
+<li><a href="Character-Class-Functions.html#index-iscntrl-357"><code>iscntrl</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Commands.html#index-iscommand-658"><code>iscommand</code></a>: <a href="Commands.html#Commands">Commands</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-iscomplex-270"><code>iscomplex</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Debug-Mode.html#index-isdebugmode-700"><code>isdebugmode</code></a>: <a href="Debug-Mode.html#Debug-Mode">Debug Mode</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isdefinite-276"><code>isdefinite</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Character-Class-Functions.html#index-isdigit-358"><code>isdigit</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Filesystem-Utilities.html#index-isdir-2329"><code>isdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Object-Sizes.html#index-isempty-206"><code>isempty</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Comparison-Ops.html#index-isequal-505"><code>isequal</code></a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Comparison-Ops.html#index-isequalwithequalnans-506"><code>isequalwithequalnans</code></a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Manipulating-Structures.html#index-isfield-379"><code>isfield</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Graphics-Objects.html#index-isfigure-1128"><code>isfigure</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isfloat-269"><code>isfloat</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Global-Variables.html#index-isglobal-426"><code>isglobal</code></a>: <a href="Global-Variables.html#Global-Variables">Global Variables</a></li>
+<li><a href="Character-Class-Functions.html#index-isgraph-359"><code>isgraph</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Graphics-Objects.html#index-ishandle-1126"><code>ishandle</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-ishghandle-1127"><code>ishghandle</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Graphics-Objects.html#index-ishold-1172"><code>ishold</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="System-Information.html#index-isieee-2447"><code>isieee</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-isinf-1265"><code>isinf</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Integer-Data-Types.html#index-isinteger-235"><code>isinteger</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Character-Class-Functions.html#index-isletter-355"><code>isletter</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-islogical-277"><code>islogical</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Character-Class-Functions.html#index-islower-361"><code>islower</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="System-Information.html#index-ismac-2446"><code>ismac</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-ismatrix-271"><code>ismatrix</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Set-Operations.html#index-ismember-2006"><code>ismember</code></a>: <a href="Set-Operations.html#Set-Operations">Set Operations</a></li>
+<li><a href="Creating-a-Class.html#index-ismethod-2257"><code>ismethod</code></a>: <a href="Creating-a-Class.html#Creating-a-Class">Creating a Class</a></li>
+<li><a href="Missing-Data.html#index-isna-190"><code>isna</code></a>: <a href="Missing-Data.html#Missing-Data">Missing Data</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-isnan-1266"><code>isnan</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Object-Sizes.html#index-isnull-207"><code>isnull</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isnumeric-267"><code>isnumeric</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Creating-a-Class.html#index-isobject-2254"><code>isobject</code></a>: <a href="Creating-a-Class.html#Creating-a-Class">Creating a Class</a></li>
+<li><a href="System-Information.html#index-ispc-2444"><code>ispc</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isprime-278"><code>isprime</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Character-Class-Functions.html#index-isprint-362"><code>isprint</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Character-Class-Functions.html#index-ispunct-363"><code>ispunct</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Commands.html#index-israwcommand-661"><code>israwcommand</code></a>: <a href="Commands.html#Commands">Commands</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isreal-268"><code>isreal</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isscalar-273"><code>isscalar</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Rearranging-Matrices.html#index-issorted-1297"><code>issorted</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Character-Class-Functions.html#index-isspace-364"><code>isspace</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Information.html#index-issparse-1663"><code>issparse</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-issquare-274"><code>issquare</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Character-Class-Functions.html#index-isstrprop-367"><code>isstrprop</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Creating-Structures.html#index-isstruct-374"><code>isstruct</code></a>: <a href="Creating-Structures.html#Creating-Structures">Creating Structures</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-issymmetric-275"><code>issymmetric</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="System-Information.html#index-isunix-2445"><code>isunix</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Character-Class-Functions.html#index-isupper-365"><code>isupper</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Variables.html#index-isvarname-419"><code>isvarname</code></a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Predicates-for-Numeric-Objects.html#index-isvector-272"><code>isvector</code></a>: <a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a></li>
+<li><a href="Character-Class-Functions.html#index-isxdigit-366"><code>isxdigit</code></a>: <a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a></li>
+<li><a href="Representing-Images.html#index-jet-2222"><code>jet</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Terminal-Input.html#index-kbhit-726"><code>kbhit</code></a>: <a href="Terminal-Input.html#Terminal-Input">Terminal Input</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-kendall-1860"><code>kendall</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Breakpoints.html#index-keyboard-696"><code>keyboard</code></a>: <a href="Breakpoints.html#Breakpoints">Breakpoints</a></li>
+<li><a href="Controlling-Subprocesses.html#index-kill-2413"><code>kill</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Distributions.html#index-kolmogorov_005fsmirnov_005fcdf-1924"><code>kolmogorov_smirnov_cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Tests.html#index-kolmogorov_005fsmirnov_005ftest-1873"><code>kolmogorov_smirnov_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Tests.html#index-kolmogorov_005fsmirnov_005ftest_005f2-1874"><code>kolmogorov_smirnov_test_2</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Functions-of-a-Matrix.html#index-kron-1625"><code>kron</code></a>: <a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a></li>
+<li><a href="Tests.html#index-kruskal_005fwallis_005ftest-1875"><code>kruskal_wallis_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Matrix-Factorizations.html#index-krylov-1621"><code>krylov</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Descriptive-Statistics.html#index-kurtosis-1836"><code>kurtosis</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Distributions.html#index-laplace_005fcdf-1925"><code>laplace_cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-laplace_005finv-1926"><code>laplace_inv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-laplace_005fpdf-1927"><code>laplace_pdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-laplace_005frnd-1980"><code>laplace_rnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Catching-Errors.html#index-lasterr-672"><code>lasterr</code></a>: <a href="Catching-Errors.html#Catching-Errors">Catching Errors</a></li>
+<li><a href="Catching-Errors.html#index-lasterror-670"><code>lasterror</code></a>: <a href="Catching-Errors.html#Catching-Errors">Catching Errors</a></li>
+<li><a href="Issuing-Warnings.html#index-lastwarn-684"><code>lastwarn</code></a>: <a href="Issuing-Warnings.html#Issuing-Warnings">Issuing Warnings</a></li>
+<li><a href="Utility-Functions.html#index-lcm-1459"><code>lcm</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Plot-Annotations.html#index-legend-1061"><code>legend</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Special-Functions.html#index-legendre-1499"><code>legendre</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="Object-Sizes.html#index-length-204"><code>length</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Special-Functions.html#index-lgamma-1501"><code>lgamma</code></a>: <a href="Special-Functions.html#Special-Functions">Special Functions</a></li>
+<li><a href="System-Information.html#index-license-2450"><code>license</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Audio-Processing.html#index-lin2mu-2238"><code>lin2mu</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Graphics-Objects.html#index-line-1139"><code>line</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Filesystem-Utilities.html#index-link-2312"><code>link</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Object-Groups.html#index-linkprop-1227"><code>linkprop</code></a>: <a href="Object-Groups.html#Object-Groups">Object Groups</a></li>
+<li><a href="Special-Utility-Matrices.html#index-linspace-1348"><code>linspace</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Utility-Functions.html#index-list_005fprimes-1461"><code>list_primes</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Simple-File-I_002fO.html#index-load-733"><code>load</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Audio-Processing.html#index-loadaudio-2240"><code>loadaudio</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Manipulating-Classes.html#index-loadobj-2260"><code>loadobj</code></a>: <a href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a></li>
+<li><a href="Timing-Utilities.html#index-localtime-2272"><code>localtime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-log-1363"><code>log</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-log10-1365"><code>log10</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-log1p-1364"><code>log1p</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-log2-1366"><code>log2</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Logical-Values.html#index-logical-260"><code>logical</code></a>: <a href="Logical-Values.html#Logical-Values">Logical Values</a></li>
+<li><a href="Distributions.html#index-logistic_005fcdf-1928"><code>logistic_cdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-logistic_005finv-1929"><code>logistic_inv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-logistic_005fpdf-1930"><code>logistic_pdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Models.html#index-logistic_005fregression-1890"><code>logistic_regression</code></a>: <a href="Models.html#Models">Models</a></li>
+<li><a href="Random-Number-Generation.html#index-logistic_005frnd-1982"><code>logistic_rnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-logit-1858"><code>logit</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-loglog-829"><code>loglog</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-loglogerr-902"><code>loglogerr</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Functions-of-a-Matrix.html#index-logm-1623"><code>logm</code></a>: <a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a></li>
+<li><a href="Distributions.html#index-logncdf-1931"><code>logncdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-logninv-1932"><code>logninv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-lognpdf-1933"><code>lognpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-lognrnd-1984"><code>lognrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Special-Utility-Matrices.html#index-logspace-1349"><code>logspace</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Getting-Help.html#index-lookfor-89"><code>lookfor</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="One_002ddimensional-Interpolation.html#index-lookup-2065"><code>lookup</code></a>: <a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a></li>
+<li><a href="String-Conversions.html#index-lower-348"><code>lower</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Current-Working-Directory.html#index-ls-2427"><code>ls</code></a>: <a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a></li>
+<li><a href="Current-Working-Directory.html#index-ls_005fcommand-2428"><code>ls_command</code></a>: <a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-lsode-1786"><code>lsode</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-lsode_005foptions-1787"><code>lsode_options</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Linear-Least-Squares.html#index-lsqnonneg-1806"><code>lsqnonneg</code></a>: <a href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a></li>
+<li><a href="Filesystem-Utilities.html#index-lstat-2326"><code>lstat</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Matrix-Factorizations.html#index-lu-1597"><code>lu</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Iterative-Techniques.html#index-luinc-1756"><code>luinc</code></a>: <a href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a></li>
+<li><a href="Famous-Matrices.html#index-magic-1354"><code>magic</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-mahalanobis-1840"><code>mahalanobis</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Filesystem-Utilities.html#index-make_005fabsolute_005ffilename-2348"><code>make_absolute_filename</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Getting-Help.html#index-makeinfo_005fprogram-98"><code>makeinfo_program</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Tests.html#index-manova-1876"><code>manova</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Commands.html#index-mark_005fas_005fcommand-656"><code>mark_as_command</code></a>: <a href="Commands.html#Commands">Commands</a></li>
+<li><a href="Commands.html#index-mark_005fas_005frawcommand-659"><code>mark_as_rawcommand</code></a>: <a href="Commands.html#Commands">Commands</a></li>
+<li><a href="Creating-Cell-Arrays.html#index-mat2cell-394"><code>mat2cell</code></a>: <a href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a></li>
+<li><a href="Conversion-of-Numerical-Data-to-Strings.html#index-mat2str-298"><code>mat2str</code></a>: <a href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">Conversion of Numerical Data to Strings</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-matrix_005ftype-1566"><code>matrix_type</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Utility-Functions.html#index-max-1462"><code>max</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Recursion.html#index-max_005frecursion_005fdepth-455"><code>max_recursion_depth</code></a>: <a href="Recursion.html#Recursion">Recursion</a></li>
+<li><a href="Tests.html#index-mcnemar_005ftest-1877"><code>mcnemar_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Hashing-Functions.html#index-md5sum-2463"><code>md5sum</code></a>: <a href="Hashing-Functions.html#Hashing-Functions">Hashing Functions</a></li>
+<li><a href="Descriptive-Statistics.html#index-mean-1819"><code>mean</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Descriptive-Statistics.html#index-meansq-1826"><code>meansq</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Descriptive-Statistics.html#index-median-1820"><code>median</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Terminal-Input.html#index-menu-724"><code>menu</code></a>: <a href="Terminal-Input.html#Terminal-Input">Terminal Input</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-mesh-978"><code>mesh</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-meshc-979"><code>meshc</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-meshgrid-997"><code>meshgrid</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-meshz-980"><code>meshz</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Creating-a-Class.html#index-methods-2255"><code>methods</code></a>: <a href="Creating-a-Class.html#Creating-a-Class">Creating a Class</a></li>
+<li><a href="Getting-Started-with-Mex_002dFiles.html#index-mex-2482"><code>mex</code></a>: <a href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles">Getting Started with Mex-Files</a></li>
+<li><a href="Getting-Started-with-Mex_002dFiles.html#index-mexext-2483"><code>mexext</code></a>: <a href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles">Getting Started with Mex-Files</a></li>
+<li><a href="Function-Files.html#index-mfilename-616"><code>mfilename</code></a>: <a href="Function-Files.html#Function-Files">Function Files</a></li>
+<li><a href="Utility-Functions.html#index-min-1466"><code>min</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Function-Locking.html#index-mislocked-641"><code>mislocked</code></a>: <a href="Function-Locking.html#Function-Locking">Function Locking</a></li>
+<li><a href="Filesystem-Utilities.html#index-mkdir-2317"><code>mkdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-mkfifo-2323"><code>mkfifo</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Getting-Started-with-Oct_002dFiles.html#index-mkoctfile-2472"><code>mkoctfile</code></a>: <a href="Getting-Started-with-Oct_002dFiles.html#Getting-Started-with-Oct_002dFiles">Getting Started with Oct-Files</a></li>
+<li><a href="Polynomial-Interpolation.html#index-mkpp-2050"><code>mkpp</code></a>: <a href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a></li>
+<li><a href="Temporary-Files.html#index-mkstemp-802"><code>mkstemp</code></a>: <a href="Temporary-Files.html#Temporary-Files">Temporary Files</a></li>
+<li><a href="Timing-Utilities.html#index-mktime-2273"><code>mktime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Function-Locking.html#index-mlock-639"><code>mlock</code></a>: <a href="Function-Locking.html#Function-Locking">Function Locking</a></li>
+<li><a href="Utility-Functions.html#index-mod-1476"><code>mod</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Descriptive-Statistics.html#index-mode-1832"><code>mode</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Descriptive-Statistics.html#index-moment-1839"><code>moment</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Paging-Screen-Output.html#index-more-710"><code>more</code></a>: <a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a></li>
+<li><a href="Filesystem-Utilities.html#index-movefile-2336"><code>movefile</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Finding-Roots.html#index-mpoles-2028"><code>mpoles</code></a>: <a href="Finding-Roots.html#Finding-Roots">Finding Roots</a></li>
+<li><a href="Audio-Processing.html#index-mu2lin-2239"><code>mu2lin</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Function-Locking.html#index-munlock-640"><code>munlock</code></a>: <a href="Function-Locking.html#Function-Locking">Function Locking</a></li>
+<li><a href="Missing-Data.html#index-NA-185"><code>NA</code></a>: <a href="Missing-Data.html#Missing-Data">Missing Data</a></li>
+<li><a href="Function-Files.html#index-g_t_0040var_007bname_007d-613"><var>name</var></a>: <a href="Function-Files.html#Function-Files">Function Files</a></li>
+<li><a href="Getting-Help.html#index-g_t_0040var_007bname_007d-85"><var>name</var></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Variables.html#index-namelengthmax-422"><code>namelengthmax</code></a>: <a href="Variables.html#Variables">Variables</a></li>
+<li><a href="Mathematical-Constants.html#index-NaN-1529"><code>NaN</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Multiple-Return-Values.html#index-nargchk-597"><code>nargchk</code></a>: <a href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a></li>
+<li><a href="Defining-Functions.html#index-nargin-590"><code>nargin</code></a>: <a href="Defining-Functions.html#Defining-Functions">Defining Functions</a></li>
+<li><a href="Multiple-Return-Values.html#index-nargout-595"><code>nargout</code></a>: <a href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a></li>
+<li><a href="Multiple-Return-Values.html#index-nargoutchk-600"><code>nargoutchk</code></a>: <a href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a></li>
+<li><a href="Simple-File-I_002fO.html#index-native_005ffloat_005fformat-743"><code>native_float_format</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Distributions.html#index-nbincdf-1934"><code>nbincdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-nbininv-1935"><code>nbininv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-nbinpdf-1936"><code>nbinpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-nbinrnd-1986"><code>nbinrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-nchoosek-1844"><code>nchoosek</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-ndgrid-1000"><code>ndgrid</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Object-Sizes.html#index-ndims-200"><code>ndims</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-nelem-2475"><code>nelem</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="Graphics-Objects.html#index-newplot-1168"><code>newplot</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Getting-Help.html#index-news-91"><code>news</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Calling-a-Function-by-its-Name.html#index-newtroot-548"><code>newtroot</code></a>: <a href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-nextpow2-1368"><code>nextpow2</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Information.html#index-nnz-1664"><code>nnz</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Information.html#index-nonzeros-1665"><code>nonzeros</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-norm-1571"><code>norm</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Distributions.html#index-normcdf-1937"><code>normcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-normest-1709"><code>normest</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Distributions.html#index-norminv-1938"><code>norminv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-normpdf-1939"><code>normpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-normrnd-1988"><code>normrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Timing-Utilities.html#index-now-2269"><code>now</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-nthroot-1369"><code>nthroot</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Color-Conversion.html#index-ntsc2rgb-2237"><code>ntsc2rgb</code></a>: <a href="Color-Conversion.html#Color-Conversion">Color Conversion</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-null-1575"><code>null</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Creating-Cell-Arrays.html#index-num2cell-392"><code>num2cell</code></a>: <a href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a></li>
+<li><a href="String-Conversions.html#index-num2hex-341"><code>num2hex</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Conversion-of-Numerical-Data-to-Strings.html#index-num2str-300"><code>num2str</code></a>: <a href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">Conversion of Numerical Data to Strings</a></li>
+<li><a href="Object-Sizes.html#index-numel-203"><code>numel</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Information.html#index-nzmax-1666"><code>nzmax</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Representing-Images.html#index-ocean-2223"><code>ocean</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="System-Information.html#index-octave_005fconfig_005finfo-2461"><code>octave_config_info</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#index-octave_005fcore_005ffile_005flimit-763"><code>octave_core_file_limit</code></a>: <a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a></li>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#index-octave_005fcore_005ffile_005fname-765"><code>octave_core_file_name</code></a>: <a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a></li>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#index-octave_005fcore_005ffile_005foptions-761"><code>octave_core_file_options</code></a>: <a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a></li>
+<li><a href="System-Information.html#index-OCTAVE_005fHOME-2448"><code>OCTAVE_HOME</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="System-Information.html#index-OCTAVE_005fVERSION-2449"><code>OCTAVE_VERSION</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Linear-Least-Squares.html#index-ols-1804"><code>ols</code></a>: <a href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-onenormest-1710"><code>onenormest</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Special-Utility-Matrices.html#index-ones-1316"><code>ones</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-operator-_0028_0029-2473"><code>operator ()</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="Linear-Least-Squares.html#index-optimget-1817"><code>optimget</code></a>: <a href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a></li>
+<li><a href="Linear-Least-Squares.html#index-optimset-1813"><code>optimset</code></a>: <a href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a></li>
+<li><a href="Status-of-Variables.html#index-options-442"><code>options</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Manipulating-Structures.html#index-orderfields-377"><code>orderfields</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Printing-Plots.html#index-orient-1098"><code>orient</code></a>: <a href="Printing-Plots.html#Printing-Plots">Printing Plots</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-orth-1576"><code>orth</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Matrices.html#index-output_005fmax_005ffield_005fwidth-221"><code>output_max_field_width</code></a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Matrices.html#index-output_005fprecision-223"><code>output_precision</code></a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Filesystem-Utilities.html#index-P_005ftmpdir-2345"><code>P_tmpdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="File-Archiving-Utilities.html#index-pack-2358"><code>pack</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Paging-Screen-Output.html#index-page_005foutput_005fimmediately-719"><code>page_output_immediately</code></a>: <a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a></li>
+<li><a href="Paging-Screen-Output.html#index-page_005fscreen_005foutput-717"><code>page_screen_output</code></a>: <a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a></li>
+<li><a href="Paging-Screen-Output.html#index-PAGER-713"><code>PAGER</code></a>: <a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a></li>
+<li><a href="Paging-Screen-Output.html#index-PAGER_005fFLAGS-715"><code>PAGER_FLAGS</code></a>: <a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-pareto-868"><code>pareto</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Variable_002dlength-Argument-Lists.html#index-parseparams-605"><code>parseparams</code></a>: <a href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a></li>
+<li><a href="Famous-Matrices.html#index-pascal-1355"><code>pascal</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Graphics-Objects.html#index-patch-1143"><code>patch</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Manipulating-the-load-path.html#index-path-626"><code>path</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Manipulating-the-load-path.html#index-pathdef-627"><code>pathdef</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Manipulating-the-load-path.html#index-pathsep-628"><code>pathsep</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Timing-Utilities.html#index-pause-2284"><code>pause</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Iterative-Techniques.html#index-pcg-1752"><code>pcg</code></a>: <a href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a></li>
+<li><a href="Signal-Processing.html#index-pchip-2167"><code>pchip</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Controlling-Subprocesses.html#index-pclose-2379"><code>pclose</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-pcolor-933"><code>pcolor</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Iterative-Techniques.html#index-pcr-1754"><code>pcr</code></a>: <a href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a></li>
+<li><a href="Test-Plotting-Functions.html#index-peaks-1105"><code>peaks</code></a>: <a href="Test-Plotting-Functions.html#Test-Plotting-Functions">Test Plotting Functions</a></li>
+<li><a href="Signal-Processing.html#index-periodogram-2169"><code>periodogram</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Controlling-Subprocesses.html#index-perl-2376"><code>perl</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-perms-1848"><code>perms</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Rearranging-Matrices.html#index-permute-1280"><code>permute</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Mathematical-Constants.html#index-pi-1514"><code>pi</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-pie-904"><code>pie</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Representing-Images.html#index-pink-2224"><code>pink</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-pinv-1577"><code>pinv</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Controlling-Subprocesses.html#index-pipe-2385"><code>pipe</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Packages.html#index-pkg-2465"><code>pkg</code></a>: <a href="Packages.html#Packages">Packages</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-planerot-1563"><code>planerot</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Audio-Processing.html#index-playaudio-2242"><code>playaudio</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-plot-817"><code>plot</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-plot3-1002"><code>plot3</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-plotmatrix-863"><code>plotmatrix</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-plotyy-822"><code>plotyy</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Distributions.html#index-poisscdf-1940"><code>poisscdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-poissinv-1941"><code>poissinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-poisspdf-1942"><code>poisspdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-poissrnd-1990"><code>poissrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Coordinate-Transformations.html#index-pol2cart-1505"><code>pol2cart</code></a>: <a href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-polar-903"><code>polar</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Miscellaneous-Functions.html#index-poly-2053"><code>poly</code></a>: <a href="Miscellaneous-Functions.html#Miscellaneous-Functions">Miscellaneous Functions</a></li>
+<li><a href="Voronoi-Diagrams.html#index-polyarea-2109"><code>polyarea</code></a>: <a href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a></li>
+<li><a href="Derivatives-and-Integrals.html#index-polyder-2043"><code>polyder</code></a>: <a href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a></li>
+<li><a href="Derivatives-and-Integrals.html#index-polyderiv-2040"><code>polyderiv</code></a>: <a href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a></li>
+<li><a href="Polynomial-Interpolation.html#index-polyfit-2048"><code>polyfit</code></a>: <a href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a></li>
+<li><a href="Products-of-Polynomials.html#index-polygcd-2036"><code>polygcd</code></a>: <a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a></li>
+<li><a href="Derivatives-and-Integrals.html#index-polyint-2047"><code>polyint</code></a>: <a href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a></li>
+<li><a href="Derivatives-and-Integrals.html#index-polyinteg-2046"><code>polyinteg</code></a>: <a href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a></li>
+<li><a href="Miscellaneous-Functions.html#index-polyout-2054"><code>polyout</code></a>: <a href="Miscellaneous-Functions.html#Miscellaneous-Functions">Miscellaneous Functions</a></li>
+<li><a href="Miscellaneous-Functions.html#index-polyreduce-2055"><code>polyreduce</code></a>: <a href="Miscellaneous-Functions.html#Miscellaneous-Functions">Miscellaneous Functions</a></li>
+<li><a href="Evaluating-Polynomials.html#index-polyval-2021"><code>polyval</code></a>: <a href="Evaluating-Polynomials.html#Evaluating-Polynomials">Evaluating Polynomials</a></li>
+<li><a href="Evaluating-Polynomials.html#index-polyvalm-2025"><code>polyvalm</code></a>: <a href="Evaluating-Polynomials.html#Evaluating-Polynomials">Evaluating Polynomials</a></li>
+<li><a href="Controlling-Subprocesses.html#index-popen-2378"><code>popen</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-popen2-2380"><code>popen2</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-pow2-1370"><code>pow2</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Statistical-Plots.html#index-ppplot-1864"><code>ppplot</code></a>: <a href="Statistical-Plots.html#Statistical-Plots">Statistical Plots</a></li>
+<li><a href="Polynomial-Interpolation.html#index-ppval-2049"><code>ppval</code></a>: <a href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a></li>
+<li><a href="Descriptive-Statistics.html#index-prctile-1824"><code>prctile</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Rearranging-Matrices.html#index-prepad-1302"><code>prepad</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Utility-Functions.html#index-primes-1477"><code>primes</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Printing-Plots.html#index-print-1094"><code>print</code></a>: <a href="Printing-Plots.html#Printing-Plots">Printing Plots</a></li>
+<li><a href="Empty-Matrices.html#index-print_005fempty_005fdimensions-229"><code>print_empty_dimensions</code></a>: <a href="Empty-Matrices.html#Empty-Matrices">Empty Matrices</a></li>
+<li><a href="Raising-Errors.html#index-print_005fusage-664"><code>print_usage</code></a>: <a href="Raising-Errors.html#Raising-Errors">Raising Errors</a></li>
+<li><a href="Formatted-Output.html#index-printf-781"><code>printf</code></a>: <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a></li>
+<li><a href="Representing-Images.html#index-prism-2225"><code>prism</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-probit-1857"><code>probit</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Sums-and-Products.html#index-prod-1425"><code>prod</code></a>: <a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a></li>
+<li><a href="Command-Line-Options.html#index-program_005fname-66"><code>program_name</code></a>: <a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a></li>
+<li><a href="Tests.html#index-prop_005ftest_005f2-1878"><code>prop_test_2</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Customizing-the-Prompt.html#index-PS1-136"><code>PS1</code></a>: <a href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a></li>
+<li><a href="Customizing-the-Prompt.html#index-PS2-138"><code>PS2</code></a>: <a href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a></li>
+<li><a href="Customizing-the-Prompt.html#index-PS4-140"><code>PS4</code></a>: <a href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a></li>
+<li><a href="Environment-Variables.html#index-putenv-2423"><code>putenv</code></a>: <a href="Environment-Variables.html#Environment-Variables">Environment Variables</a></li>
+<li><a href="Simple-Output.html#index-puts-778"><code>puts</code></a>: <a href="Simple-Output.html#Simple-Output">Simple Output</a></li>
+<li><a href="Current-Working-Directory.html#index-pwd-2431"><code>pwd</code></a>: <a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a></li>
+<li><a href="Quadratic-Programming.html#index-qp-1802"><code>qp</code></a>: <a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a></li>
+<li><a href="Statistical-Plots.html#index-qqplot-1863"><code>qqplot</code></a>: <a href="Statistical-Plots.html#Statistical-Plots">Statistical Plots</a></li>
+<li><a href="Matrix-Factorizations.html#index-qr-1604"><code>qr</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-qrdelete-1609"><code>qrdelete</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-qrinsert-1608"><code>qrinsert</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-qrshift-1610"><code>qrshift</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-qrupdate-1607"><code>qrupdate</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Functions-of-One-Variable.html#index-quad-1760"><code>quad</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Functions-of-One-Variable.html#index-quad_005foptions-1761"><code>quad_options</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Functions-of-One-Variable.html#index-quadgk-1766"><code>quadgk</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Functions-of-One-Variable.html#index-quadl-1762"><code>quadl</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Functions-of-One-Variable.html#index-quadv-1769"><code>quadv</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Descriptive-Statistics.html#index-quantile-1821"><code>quantile</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Quitting-Octave.html#index-quit-80"><code>quit</code></a>: <a href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-quiver-909"><code>quiver</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-quiver3-916"><code>quiver3</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Matrix-Factorizations.html#index-qz-1611"><code>qz</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-qzhess-1612"><code>qzhess</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Representing-Images.html#index-rainbow-2226"><code>rainbow</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Special-Utility-Matrices.html#index-rand-1327"><code>rand</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Special-Utility-Matrices.html#index-rande-1335"><code>rande</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Special-Utility-Matrices.html#index-randg-1343"><code>randg</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Special-Utility-Matrices.html#index-randn-1331"><code>randn</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Special-Utility-Matrices.html#index-randp-1339"><code>randp</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Special-Utility-Matrices.html#index-randperm-1347"><code>randperm</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-range-1855"><code>range</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-rank-1578"><code>rank</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-ranks-1854"><code>ranks</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Rational-Approximations.html#index-rat-767"><code>rat</code></a>: <a href="Rational-Approximations.html#Rational-Approximations">Rational Approximations</a></li>
+<li><a href="Rational-Approximations.html#index-rats-769"><code>rats</code></a>: <a href="Rational-Approximations.html#Rational-Approximations">Rational Approximations</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-rcond-1579"><code>rcond</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Customizing-readline.html#index-re_005fread_005freadline_005finit_005ffile-133"><code>re_read_readline_init_file</code></a>: <a href="Customizing-readline.html#Customizing-readline">Customizing readline</a></li>
+<li><a href="Customizing-readline.html#index-read_005freadline_005finit_005ffile-132"><code>read_readline_init_file</code></a>: <a href="Customizing-readline.html#Customizing-readline">Customizing readline</a></li>
+<li><a href="Filesystem-Utilities.html#index-readdir-2316"><code>readdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-readlink-2314"><code>readlink</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Complex-Arithmetic.html#index-real-1384"><code>real</code></a>: <a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-reallog-1372"><code>reallog</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Mathematical-Constants.html#index-realmax-1539"><code>realmax</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Mathematical-Constants.html#index-realmin-1544"><code>realmin</code></a>: <a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-realpow-1373"><code>realpow</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-realsqrt-1374"><code>realsqrt</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Audio-Processing.html#index-record-2244"><code>record</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Signal-Processing.html#index-rectangle_005flw-2170"><code>rectangle_lw</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-rectangle_005fsw-2171"><code>rectangle_sw</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Voronoi-Diagrams.html#index-rectint-2111"><code>rectint</code></a>: <a href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a></li>
+<li><a href="Graphics-Objects.html#index-refresh-1166"><code>refresh</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Data-sources-in-object-groups.html#index-refreshdata-1229"><code>refreshdata</code></a>: <a href="Data-sources-in-object-groups.html#Data-sources-in-object-groups">Data sources in object groups</a></li>
+<li><a href="Manipulating-Strings.html#index-regexp-329"><code>regexp</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-regexpi-331"><code>regexpi</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-regexprep-333"><code>regexprep</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-regexptranslate-334"><code>regexptranslate</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-the-load-path.html#index-rehash-630"><code>rehash</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Utility-Functions.html#index-rem-1478"><code>rem</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Filesystem-Utilities.html#index-rename-2311"><code>rename</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Special-Utility-Matrices.html#index-repmat-1324"><code>repmat</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-reshape-1282"><code>reshape</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Products-of-Polynomials.html#index-residue-2037"><code>residue</code></a>: <a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a></li>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#index-resize-2478"><code>resize</code></a>: <a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a></li>
+<li><a href="Rearranging-Matrices.html#index-resize-1284"><code>resize</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Manipulating-the-load-path.html#index-restoredefaultpath-633"><code>restoredefaultpath</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Catching-Errors.html#index-rethrow-673"><code>rethrow</code></a>: <a href="Catching-Errors.html#Catching-Errors">Catching Errors</a></li>
+<li><a href="Returning-From-a-Function.html#index-return-610"><code>return</code></a>: <a href="Returning-From-a-Function.html#Returning-From-a-Function">Returning From a Function</a></li>
+<li><a href="Color-Conversion.html#index-rgb2hsv-2234"><code>rgb2hsv</code></a>: <a href="Color-Conversion.html#Color-Conversion">Color Conversion</a></li>
+<li><a href="Representing-Images.html#index-rgb2ind-2205"><code>rgb2ind</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Color-Conversion.html#index-rgb2ntsc-2236"><code>rgb2ntsc</code></a>: <a href="Color-Conversion.html#Color-Conversion">Color Conversion</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-ribbon-1012"><code>ribbon</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Manipulating-Strings.html#index-rindex-321"><code>rindex</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Filesystem-Utilities.html#index-rmdir-2319"><code>rmdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Manipulating-Structures.html#index-rmfield-375"><code>rmfield</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Manipulating-the-load-path.html#index-rmpath-624"><code>rmpath</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Finding-Roots.html#index-roots-2026"><code>roots</code></a>: <a href="Finding-Roots.html#Finding-Roots">Finding Roots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-rose-872"><code>rose</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Famous-Matrices.html#index-rosser-1356"><code>rosser</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-rot90-1275"><code>rot90</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-rotdim-1276"><code>rotdim</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Utility-Functions.html#index-round-1479"><code>round</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Utility-Functions.html#index-roundb-1480"><code>roundb</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Object-Sizes.html#index-rows-202"><code>rows</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-rref-1581"><code>rref</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Calling-a-Function-by-its-Name.html#index-run-550"><code>run</code></a>: <a href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-run_005fcount-1853"><code>run_count</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Commands-For-History.html#index-run_005fhistory-118"><code>run_history</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Tests.html#index-run_005ftest-1879"><code>run_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Demonstration-Functions.html#index-rundemos-2500"><code>rundemos</code></a>: <a href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a></li>
+<li><a href="Simple-File-I_002fO.html#index-S-736"><code>S</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Status-of-Variables.html#index-S-437"><code>S</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Simple-File-I_002fO.html#index-save-729"><code>save</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Simple-File-I_002fO.html#index-save_005fheader_005fformat_005fstring-741"><code>save_header_format_string</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Simple-File-I_002fO.html#index-save_005fprecision-739"><code>save_precision</code></a>: <a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a></li>
+<li><a href="Audio-Processing.html#index-saveaudio-2241"><code>saveaudio</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Manipulating-Classes.html#index-saveobj-2259"><code>saveobj</code></a>: <a href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a></li>
+<li><a href="Manipulating-the-load-path.html#index-savepath-625"><code>savepath</code></a>: <a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a></li>
+<li><a href="Commands-For-History.html#index-saving_005fhistory-119"><code>saving_history</code></a>: <a href="Commands-For-History.html#Commands-For-History">Commands For History</a></li>
+<li><a href="Formatted-Input.html#index-scanf-791"><code>scanf</code></a>: <a href="Formatted-Input.html#Formatted-Input">Formatted Input</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-scatter-851"><code>scatter</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-scatter3-857"><code>scatter3</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Matrix-Factorizations.html#index-schur-1613"><code>schur</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Trigonometry.html#index-sec-1388"><code>sec</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-secd-1413"><code>secd</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-sech-1400"><code>sech</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="File-Positioning.html#index-SEEK_005fCUR-812"><code>SEEK_CUR</code></a>: <a href="File-Positioning.html#File-Positioning">File Positioning</a></li>
+<li><a href="File-Positioning.html#index-SEEK_005fEND-813"><code>SEEK_END</code></a>: <a href="File-Positioning.html#File-Positioning">File Positioning</a></li>
+<li><a href="File-Positioning.html#index-SEEK_005fSET-811"><code>SEEK_SET</code></a>: <a href="File-Positioning.html#File-Positioning">File Positioning</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-semilogx-827"><code>semilogx</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-semilogxerr-900"><code>semilogxerr</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-semilogy-828"><code>semilogy</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-semilogyerr-901"><code>semilogyerr</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Graphics-Objects.html#index-set-1132"><code>set</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Audio-Processing.html#index-setaudio-2245"><code>setaudio</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Set-Operations.html#index-setdiff-2015"><code>setdiff</code></a>: <a href="Set-Operations.html#Set-Operations">Set Operations</a></li>
+<li><a href="Environment-Variables.html#index-setenv-2424"><code>setenv</code></a>: <a href="Environment-Variables.html#Environment-Variables">Environment Variables</a></li>
+<li><a href="Manipulating-Structures.html#index-setfield-376"><code>setfield</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Group-Database-Functions.html#index-setgrent-2440"><code>setgrent</code></a>: <a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a></li>
+<li><a href="Password-Database-Functions.html#index-setpwent-2435"><code>setpwent</code></a>: <a href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a></li>
+<li><a href="Set-Operations.html#index-setxor-2018"><code>setxor</code></a>: <a href="Set-Operations.html#Set-Operations">Set Operations</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-shading-1015"><code>shading</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Graphics-Objects.html#index-shg-1181"><code>shg</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Rearranging-Matrices.html#index-shift-1290"><code>shift</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-shiftdim-1288"><code>shiftdim</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Controlling-Subprocesses.html#index-SIG-2414"><code>SIG</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#index-sighup_005fdumps_005foctave_005fcore-757"><code>sighup_dumps_octave_core</code></a>: <a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a></li>
+<li><a href="Utility-Functions.html#index-sign-1481"><code>sign</code></a>: <a href="Utility-Functions.html#Utility-Functions">Utility Functions</a></li>
+<li><a href="Tests.html#index-sign_005ftest-1880"><code>sign_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#index-sigterm_005fdumps_005foctave_005fcore-759"><code>sigterm_dumps_octave_core</code></a>: <a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a></li>
+<li><a href="Defining-Functions.html#index-silent_005ffunctions-593"><code>silent_functions</code></a>: <a href="Defining-Functions.html#Defining-Functions">Defining Functions</a></li>
+<li><a href="Trigonometry.html#index-sin-1385"><code>sin</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Signal-Processing.html#index-sinc-2146"><code>sinc</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Trigonometry.html#index-sind-1410"><code>sind</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Signal-Processing.html#index-sinetone-2172"><code>sinetone</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-sinewave-2173"><code>sinewave</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Single-Precision-Data-Types.html#index-single-234"><code>single</code></a>: <a href="Single-Precision-Data-Types.html#Single-Precision-Data-Types">Single Precision Data Types</a></li>
+<li><a href="Trigonometry.html#index-sinh-1397"><code>sinh</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Object-Sizes.html#index-size-205"><code>size</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Object-Sizes.html#index-size_005fequal-209"><code>size_equal</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Object-Sizes.html#index-sizeof-208"><code>sizeof</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Descriptive-Statistics.html#index-skewness-1837"><code>skewness</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Timing-Utilities.html#index-sleep-2285"><code>sleep</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-slice-1006"><code>slice</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Test-Plotting-Functions.html#index-sombrero-1104"><code>sombrero</code></a>: <a href="Test-Plotting-Functions.html#Test-Plotting-Functions">Test Plotting Functions</a></li>
+<li><a href="Rearranging-Matrices.html#index-sort-1292"><code>sort</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-sortrows-1296"><code>sortrows</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Script-Files.html#index-source-642"><code>source</code></a>: <a href="Script-Files.html#Script-Files">Script Files</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spalloc-1656"><code>spalloc</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-sparse-1657"><code>sparse</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Return-Types-of-Operators-and-Functions.html#index-sparse_005fauto_005fmutate-1684"><code>sparse_auto_mutate</code></a>: <a href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions">Return Types of Operators and Functions</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-spaugment-1726"><code>spaugment</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spconvert-1662"><code>spconvert</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spdiags-1636"><code>spdiags</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-spearman-1852"><code>spearman</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Signal-Processing.html#index-spectral_005fadf-2174"><code>spectral_adf</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-spectral_005fxdf-2175"><code>spectral_xdf</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-specular-995"><code>specular</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Demonstration-Functions.html#index-speed-2503"><code>speed</code></a>: <a href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a></li>
+<li><a href="Signal-Processing.html#index-spencer-2176"><code>spencer</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-speye-1640"><code>speye</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spfun-1643"><code>spfun</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Coordinate-Transformations.html#index-sph2cart-1508"><code>sph2cart</code></a>: <a href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a></li>
+<li><a href="Three_002ddimensional-Geometric-Shapes.html#index-sphere-1055"><code>sphere</code></a>: <a href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">Three-dimensional Geometric Shapes</a></li>
+<li><a href="Representing-Images.html#index-spinmap-2233"><code>spinmap</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="One_002ddimensional-Interpolation.html#index-spline-2063"><code>spline</code></a>: <a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a></li>
+<li><a href="Matrices.html#index-split_005flong_005frows-225"><code>split_long_rows</code></a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spmax-1644"><code>spmax</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spmin-1646"><code>spmin</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-spones-1648"><code>spones</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-spparms-1715"><code>spparms</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-sprand-1649"><code>sprand</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-sprandn-1651"><code>sprandn</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Creating-Sparse-Matrices.html#index-sprandsym-1653"><code>sprandsym</code></a>: <a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-sprank-1723"><code>sprank</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Representing-Images.html#index-spring-2227"><code>spring</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Formatted-Output.html#index-sprintf-783"><code>sprintf</code></a>: <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a></li>
+<li><a href="Information.html#index-spstats-1667"><code>spstats</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Information.html#index-spy-1669"><code>spy</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Nonlinear-Programming.html#index-sqp-1803"><code>sqp</code></a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Exponents-and-Logarithms.html#index-sqrt-1375"><code>sqrt</code></a>: <a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a></li>
+<li><a href="Functions-of-a-Matrix.html#index-sqrtm-1624"><code>sqrtm</code></a>: <a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a></li>
+<li><a href="Object-Sizes.html#index-squeeze-210"><code>squeeze</code></a>: <a href="Object-Sizes.html#Object-Sizes">Object Sizes</a></li>
+<li><a href="Formatted-Input.html#index-sscanf-793"><code>sscanf</code></a>: <a href="Formatted-Input.html#Formatted-Input">Formatted Input</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-stairs-843"><code>stairs</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Filesystem-Utilities.html#index-stat-2325"><code>stat</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Descriptive-Statistics.html#index-statistics-1838"><code>statistics</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Descriptive-Statistics.html#index-std-1828"><code>std</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="C_002dStyle-I_002fO-Functions.html#index-stderr-772"><code>stderr</code></a>: <a href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a></li>
+<li><a href="C_002dStyle-I_002fO-Functions.html#index-stdin-770"><code>stdin</code></a>: <a href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a></li>
+<li><a href="C_002dStyle-I_002fO-Functions.html#index-stdout-771"><code>stdout</code></a>: <a href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-stem-848"><code>stem</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-stem3-850"><code>stem3</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Signal-Processing.html#index-stft-2177"><code>stft</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Getting-Help.html#index-g_t_0040var_007bstr_007d-87"><var>str</var></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="String-Conversions.html#index-str2double-343"><code>str2double</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Function-Handles.html#index-str2func-648"><code>str2func</code></a>: <a href="Function-Handles.html#Function-Handles">Function Handles</a></li>
+<li><a href="String-Conversions.html#index-str2num-345"><code>str2num</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Concatenating-Strings.html#index-strcat-296"><code>strcat</code></a>: <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-strchr-316"><code>strchr</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Comparing-Strings.html#index-strcmp-304"><code>strcmp</code></a>: <a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a></li>
+<li><a href="Comparing-Strings.html#index-strcmpi-306"><code>strcmpi</code></a>: <a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-strfind-322"><code>strfind</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Timing-Utilities.html#index-strftime-2275"><code>strftime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Character-Arrays.html#index-string_005ffill_005fchar-285"><code>string_fill_char</code></a>: <a href="Character-Arrays.html#Character-Arrays">Character Arrays</a></li>
+<li><a href="String-Conversions.html#index-strjust-344"><code>strjust</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Manipulating-Strings.html#index-strmatch-324"><code>strmatch</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Comparing-Strings.html#index-strncmp-305"><code>strncmp</code></a>: <a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a></li>
+<li><a href="Comparing-Strings.html#index-strncmpi-307"><code>strncmpi</code></a>: <a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a></li>
+<li><a href="Timing-Utilities.html#index-strptime-2276"><code>strptime</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Manipulating-Strings.html#index-strrep-327"><code>strrep</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-strsplit-326"><code>strsplit</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-strtok-325"><code>strtok</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-strtrim-313"><code>strtrim</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Strings.html#index-strtrunc-314"><code>strtrunc</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Creating-Structures.html#index-struct-373"><code>struct</code></a>: <a href="Creating-Structures.html#Creating-Structures">Creating Structures</a></li>
+<li><a href="Processing-Data-in-Structures.html#index-struct2cell-386"><code>struct2cell</code></a>: <a href="Processing-Data-in-Structures.html#Processing-Data-in-Structures">Processing Data in Structures</a></li>
+<li><a href="Basic-Usage-and-Examples.html#index-struct_005flevels_005fto_005fprint-371"><code>struct_levels_to_print</code></a>: <a href="Basic-Usage-and-Examples.html#Basic-Usage-and-Examples">Basic Usage and Examples</a></li>
+<li><a href="Processing-Data-in-Structures.html#index-structfun-382"><code>structfun</code></a>: <a href="Processing-Data-in-Structures.html#Processing-Data-in-Structures">Processing Data in Structures</a></li>
+<li><a href="Concatenating-Strings.html#index-strvcat-292"><code>strvcat</code></a>: <a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-studentize-1843"><code>studentize</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Index-Expressions.html#index-sub2ind-450"><code>sub2ind</code></a>: <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a></li>
+<li><a href="Multiple-Plots-on-One-Page.html#index-subplot-1090"><code>subplot</code></a>: <a href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page">Multiple Plots on One Page</a></li>
+<li><a href="Indexing-Objects.html#index-subsasgn-2262"><code>subsasgn</code></a>: <a href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a></li>
+<li><a href="Indexing-Objects.html#index-subsindex-2263"><code>subsindex</code></a>: <a href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a></li>
+<li><a href="Matrix-Factorizations.html#index-subspace-1616"><code>subspace</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Indexing-Objects.html#index-subsref-2261"><code>subsref</code></a>: <a href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a></li>
+<li><a href="Manipulating-Strings.html#index-substr-328"><code>substr</code></a>: <a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a></li>
+<li><a href="Manipulating-Structures.html#index-substruct-381"><code>substruct</code></a>: <a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a></li>
+<li><a href="Sums-and-Products.html#index-sum-1422"><code>sum</code></a>: <a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a></li>
+<li><a href="Representing-Images.html#index-summer-2228"><code>summer</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Sums-and-Products.html#index-sumsq-1432"><code>sumsq</code></a>: <a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a></li>
+<li><a href="Precedence-of-Objects.html#index-superiorto-2266"><code>superiorto</code></a>: <a href="Precedence-of-Objects.html#Precedence-of-Objects">Precedence of Objects</a></li>
+<li><a href="Getting-Help.html#index-suppress_005fverbose_005fhelp_005fmessage-102"><code>suppress_verbose_help_message</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-surf-983"><code>surf</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Graphics-Objects.html#index-surface-1156"><code>surface</code></a>: <a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-surfc-984"><code>surfc</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-surfl-985"><code>surfl</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-surfnorm-990"><code>surfnorm</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Matrix-Factorizations.html#index-svd-1617"><code>svd</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-svds-1747"><code>svds</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Built_002din-Data-Types.html#index-swapbytes-181"><code>swapbytes</code></a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="Functions-of-a-Matrix.html#index-syl-1626"><code>syl</code></a>: <a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a></li>
+<li><a href="Famous-Matrices.html#index-sylvester_005fmatrix-1357"><code>sylvester_matrix</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Mathematical-Considerations.html#index-symamd-1704"><code>symamd</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Sparse-Linear-Algebra.html#index-symbfact-1725"><code>symbfact</code></a>: <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a></li>
+<li><a href="Filesystem-Utilities.html#index-symlink-2313"><code>symlink</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Mathematical-Considerations.html#index-symrcm-1708"><code>symrcm</code></a>: <a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a></li>
+<li><a href="Inline-Functions.html#index-symvar-655"><code>symvar</code></a>: <a href="Inline-Functions.html#Inline-Functions">Inline Functions</a></li>
+<li><a href="Signal-Processing.html#index-synthesis-2178"><code>synthesis</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Controlling-Subprocesses.html#index-system-2371"><code>system</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Tests.html#index-t_005ftest-1881"><code>t_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Tests.html#index-t_005ftest_005f2-1882"><code>t_test_2</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Tests.html#index-t_005ftest_005fregression-1883"><code>t_test_regression</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-table-1850"><code>table</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Trigonometry.html#index-tan-1387"><code>tan</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-tand-1412"><code>tand</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="Trigonometry.html#index-tanh-1399"><code>tanh</code></a>: <a href="Trigonometry.html#Trigonometry">Trigonometry</a></li>
+<li><a href="File-Archiving-Utilities.html#index-tar-2353"><code>tar</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Distributions.html#index-tcdf-1943"><code>tcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Filesystem-Utilities.html#index-tempdir-2343"><code>tempdir</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-tempname-2344"><code>tempname</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Test-Functions.html#index-test-2485"><code>test</code></a>: <a href="Test-Functions.html#Test-Functions">Test Functions</a></li>
+<li><a href="Plot-Annotations.html#index-text-1068"><code>text</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Timing-Utilities.html#index-tic-2282"><code>tic</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Filesystem-Utilities.html#index-tilde_005fexpand-2334"><code>tilde_expand</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Timing-Utilities.html#index-time-2268"><code>time</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Distributions.html#index-tinv-1944"><code>tinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Plot-Annotations.html#index-title-1059"><code>title</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Temporary-Files.html#index-tmpfile-803"><code>tmpfile</code></a>: <a href="Temporary-Files.html#Temporary-Files">Temporary Files</a></li>
+<li><a href="Temporary-Files.html#index-tmpnam-804"><code>tmpnam</code></a>: <a href="Temporary-Files.html#Temporary-Files">Temporary Files</a></li>
+<li><a href="String-Conversions.html#index-toascii-346"><code>toascii</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Timing-Utilities.html#index-toc-2283"><code>toc</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Famous-Matrices.html#index-toeplitz-1358"><code>toeplitz</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="String-Conversions.html#index-tolower-347"><code>tolower</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="String-Conversions.html#index-toupper-349"><code>toupper</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Distributions.html#index-tpdf-1945"><code>tpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Basic-Matrix-Functions.html#index-trace-1580"><code>trace</code></a>: <a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a></li>
+<li><a href="Functions-of-One-Variable.html#index-trapz-1774"><code>trapz</code></a>: <a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a></li>
+<li><a href="Information.html#index-treelayout-1682"><code>treelayout</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Information.html#index-treeplot-1680"><code>treeplot</code></a>: <a href="Information.html#Information">Information</a></li>
+<li><a href="Signal-Processing.html#index-triangle_005flw-2179"><code>triangle_lw</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Signal-Processing.html#index-triangle_005fsw-2180"><code>triangle_sw</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Rearranging-Matrices.html#index-tril-1298"><code>tril</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Plotting-the-Triangulation.html#index-trimesh-2093"><code>trimesh</code></a>: <a href="Plotting-the-Triangulation.html#Plotting-the-Triangulation">Plotting the Triangulation</a></li>
+<li><a href="Functions-of-Multiple-Variables.html#index-triplequad-1782"><code>triplequad</code></a>: <a href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">Functions of Multiple Variables</a></li>
+<li><a href="Plotting-the-Triangulation.html#index-triplot-2090"><code>triplot</code></a>: <a href="Plotting-the-Triangulation.html#Plotting-the-Triangulation">Plotting the Triangulation</a></li>
+<li><a href="Rearranging-Matrices.html#index-triu-1299"><code>triu</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Random-Number-Generation.html#index-trnd-1991"><code>trnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Logical-Values.html#index-true-261"><code>true</code></a>: <a href="Logical-Values.html#Logical-Values">Logical Values</a></li>
+<li><a href="Identifying-points-in-Triangulation.html#index-tsearch-2095"><code>tsearch</code></a>: <a href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a></li>
+<li><a href="Identifying-points-in-Triangulation.html#index-tsearchn-2096"><code>tsearchn</code></a>: <a href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a></li>
+<li><a href="Built_002din-Data-Types.html#index-typecast-180"><code>typecast</code></a>: <a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a></li>
+<li><a href="Data-Types.html#index-typeinfo-172"><code>typeinfo</code></a>: <a href="Data-Types.html#Data-Types">Data Types</a></li>
+<li><a href="Tests.html#index-u_005ftest-1884"><code>u_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Integer-Data-Types.html#index-uint16-239"><code>uint16</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-uint32-241"><code>uint32</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-uint64-243"><code>uint64</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Integer-Data-Types.html#index-uint8-237"><code>uint8</code></a>: <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a></li>
+<li><a href="Filesystem-Utilities.html#index-umask-2324"><code>umask</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="System-Information.html#index-uname-2443"><code>uname</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="String-Conversions.html#index-undo_005fstring_005fescapes-352"><code>undo_string_escapes</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Distributions.html#index-unidcdf-1946"><code>unidcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-unidinv-1947"><code>unidinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-unidpdf-1948"><code>unidpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-unidrnd-1993"><code>unidrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Distributions.html#index-unifcdf-1949"><code>unifcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-unifinv-1950"><code>unifinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-unifpdf-1951"><code>unifpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-unifrnd-1996"><code>unifrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Set-Operations.html#index-union-2009"><code>union</code></a>: <a href="Set-Operations.html#Set-Operations">Set Operations</a></li>
+<li><a href="Sets.html#index-unique-2001"><code>unique</code></a>: <a href="Sets.html#Sets">Sets</a></li>
+<li><a href="Controlling-Subprocesses.html#index-unix-2372"><code>unix</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Filesystem-Utilities.html#index-unlink-2315"><code>unlink</code></a>: <a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a></li>
+<li><a href="Commands.html#index-unmark_005fcommand-657"><code>unmark_command</code></a>: <a href="Commands.html#Commands">Commands</a></li>
+<li><a href="Commands.html#index-unmark_005frawcommand-660"><code>unmark_rawcommand</code></a>: <a href="Commands.html#Commands">Commands</a></li>
+<li><a href="Polynomial-Interpolation.html#index-unmkpp-2052"><code>unmkpp</code></a>: <a href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a></li>
+<li><a href="File-Archiving-Utilities.html#index-unpack-2359"><code>unpack</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="File-Archiving-Utilities.html#index-untar-2354"><code>untar</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Signal-Processing.html#index-unwrap-2147"><code>unwrap</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="File-Archiving-Utilities.html#index-unzip-2357"><code>unzip</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="String-Conversions.html#index-upper-350"><code>upper</code></a>: <a href="String-Conversions.html#String-Conversions">String Conversions</a></li>
+<li><a href="Networking-Utilities.html#index-urlread-2363"><code>urlread</code></a>: <a href="Networking-Utilities.html#Networking-Utilities">Networking Utilities</a></li>
+<li><a href="Networking-Utilities.html#index-urlwrite-2367"><code>urlwrite</code></a>: <a href="Networking-Utilities.html#Networking-Utilities">Networking Utilities</a></li>
+<li><a href="Raising-Errors.html#index-usage-666"><code>usage</code></a>: <a href="Raising-Errors.html#Raising-Errors">Raising Errors</a></li>
+<li><a href="Timing-Utilities.html#index-usleep-2286"><code>usleep</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Comparing-Strings.html#index-validatestring-308"><code>validatestring</code></a>: <a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a></li>
+<li><a href="Basic-Statistical-Functions.html#index-values-1849"><code>values</code></a>: <a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a></li>
+<li><a href="Famous-Matrices.html#index-vander-1359"><code>vander</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Descriptive-Statistics.html#index-var-1831"><code>var</code></a>: <a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a></li>
+<li><a href="Tests.html#index-var_005ftest-1885"><code>var_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Rearranging-Matrices.html#index-vec-1300"><code>vec</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Rearranging-Matrices.html#index-vech-1301"><code>vech</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Inline-Functions.html#index-vectorize-654"><code>vectorize</code></a>: <a href="Inline-Functions.html#Inline-Functions">Inline Functions</a></li>
+<li><a href="System-Information.html#index-ver-2457"><code>ver</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="System-Information.html#index-version-2456"><code>version</code></a>: <a href="System-Information.html#System-Information">System Information</a></li>
+<li><a href="Rearranging-Matrices.html#index-vertcat-1279"><code>vertcat</code></a>: <a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a></li>
+<li><a href="Three_002dDimensional-Plotting.html#index-view-1003"><code>view</code></a>: <a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a></li>
+<li><a href="Voronoi-Diagrams.html#index-voronoi-2103"><code>voronoi</code></a>: <a href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a></li>
+<li><a href="Voronoi-Diagrams.html#index-voronoin-2107"><code>voronoin</code></a>: <a href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a></li>
+<li><a href="Interacting-with-plots.html#index-waitforbuttonpress-1100"><code>waitforbuttonpress</code></a>: <a href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a></li>
+<li><a href="Controlling-Subprocesses.html#index-waitpid-2387"><code>waitpid</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Issuing-Warnings.html#index-warning-678"><code>warning</code></a>: <a href="Issuing-Warnings.html#Issuing-Warnings">Issuing Warnings</a></li>
+<li><a href="Getting-Help.html#index-warranty-93"><code>warranty</code></a>: <a href="Getting-Help.html#Getting-Help">Getting Help</a></li>
+<li><a href="Audio-Processing.html#index-wavread-2246"><code>wavread</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Audio-Processing.html#index-wavwrite-2251"><code>wavwrite</code></a>: <a href="Audio-Processing.html#Audio-Processing">Audio Processing</a></li>
+<li><a href="Distributions.html#index-wblcdf-1952"><code>wblcdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-wblinv-1953"><code>wblinv</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Distributions.html#index-wblpdf-1954"><code>wblpdf</code></a>: <a href="Distributions.html#Distributions">Distributions</a></li>
+<li><a href="Random-Number-Generation.html#index-wblrnd-1998"><code>wblrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WCOREDUMP-2389"><code>WCOREDUMP</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Timing-Utilities.html#index-weekday-2304"><code>weekday</code></a>: <a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a></li>
+<li><a href="Tests.html#index-welch_005ftest-1886"><code>welch_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WEXITSTATUS-2390"><code>WEXITSTATUS</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Status-of-Variables.html#index-what-444"><code>what</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Status-of-Variables.html#index-which-443"><code>which</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Representing-Images.html#index-white-2229"><code>white</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Status-of-Variables.html#index-who-430"><code>who</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Status-of-Variables.html#index-whos-434"><code>whos</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Status-of-Variables.html#index-whos_005fline_005fformat-438"><code>whos_line_format</code></a>: <a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a></li>
+<li><a href="Random-Number-Generation.html#index-wienrnd-2000"><code>wienrnd</code></a>: <a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WIFCONTINUED-2391"><code>WIFCONTINUED</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WIFEXITED-2394"><code>WIFEXITED</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WIFSIGNALED-2392"><code>WIFSIGNALED</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WIFSTOPPED-2393"><code>WIFSTOPPED</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Tests.html#index-wilcoxon_005ftest-1887"><code>wilcoxon_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Famous-Matrices.html#index-wilkinson-1360"><code>wilkinson</code></a>: <a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a></li>
+<li><a href="Representing-Images.html#index-winter-2230"><code>winter</code></a>: <a href="Representing-Images.html#Representing-Images">Representing Images</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WNOHANG-2395"><code>WNOHANG</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WSTOPSIG-2396"><code>WSTOPSIG</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WTERMSIG-2397"><code>WTERMSIG</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Controlling-Subprocesses.html#index-WUNTRACED-2398"><code>WUNTRACED</code></a>: <a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a></li>
+<li><a href="Plot-Annotations.html#index-xlabel-1072"><code>xlabel</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Two_002dDimensional-Plots.html#index-xlim-948"><code>xlim</code></a>: <a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a></li>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#index-xor-1262"><code>xor</code></a>: <a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a></li>
+<li><a href="Terminal-Input.html#index-yes_005for_005fno-725"><code>yes_or_no</code></a>: <a href="Terminal-Input.html#Terminal-Input">Terminal Input</a></li>
+<li><a href="Plot-Annotations.html#index-ylabel-1073"><code>ylabel</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+<li><a href="Signal-Processing.html#index-yulewalker-2181"><code>yulewalker</code></a>: <a href="Signal-Processing.html#Signal-Processing">Signal Processing</a></li>
+<li><a href="Tests.html#index-z_005ftest-1888"><code>z_test</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Tests.html#index-z_005ftest_005f2-1889"><code>z_test_2</code></a>: <a href="Tests.html#Tests">Tests</a></li>
+<li><a href="Special-Utility-Matrices.html#index-zeros-1320"><code>zeros</code></a>: <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a></li>
+<li><a href="File-Archiving-Utilities.html#index-zip-2355"><code>zip</code></a>: <a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a></li>
+<li><a href="Plot-Annotations.html#index-zlabel-1074"><code>zlabel</code></a>: <a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a></li>
+   </ul><!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+</body></html>
+
diff --git a/doc/interpreter/HTML/Function-Locking.html b/doc/interpreter/HTML/Function-Locking.html
new file mode 100644
index 0000000..2c69c56
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Locking.html
@@ -0,0 +1,133 @@
+<html lang="en">
+<head>
+<title>Function Locking - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="prev" href="Overloading-and-Autoloading.html#Overloading-and-Autoloading" title="Overloading and Autoloading">
+<link rel="next" href="Function-Precedence.html#Function-Precedence" title="Function Precedence">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Locking"></a>
+Next: <a rel="next" accesskey="n" href="Function-Precedence.html#Function-Precedence">Function Precedence</a>,
+Previous: <a rel="previous" accesskey="p" href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a>,
+Up: <a rel="up" accesskey="u" href="Function-Files.html#Function-Files">Function Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.7.5 Function Locking</h4>
+
+<p>It is sometime desirable to lock a function into memory with the
+<code>mlock</code> function.  This is typically used for dynamically linked
+functions in Oct-files or mex-files that contain some initialization,
+and it is desirable that calling <code>clear</code> does not remove this
+initialization.
+
+   <p>As an example,
+
+<pre class="example">     mlock ("my_function");
+</pre>
+   <p class="noindent">prevents <code>my_function</code> from being removed from memory, even if
+<code>clear</code> is called.  It is possible to determine if a function is
+locked into memory with the <code>mislocked</code>, and to unlock a function
+with <code>munlock</code>, which the following illustrates.
+
+<pre class="example">     mlock ("my_function");
+     mislocked ("my_function")
+      ans = 1
+     munlock ("my_function");
+     mislocked ("my_function")
+      ans = 0
+</pre>
+   <p>A common use of <code>mlock</code> is to prevent persistent variables from
+being removed from memory, as the following example shows:
+
+<pre class="example">     function count_calls()
+       persistent calls = 0;
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+     mlock ("count_calls");
+     
+     count_calls ();
+     -| 'count_calls' has been called 1 times
+     
+     clear count_calls
+     count_calls ();
+     -| 'count_calls' has been called 2 times
+</pre>
+   <p class="noindent">It is, however, often inconvenient to lock a function from the prompt,
+so it is also possible to lock a function from within its body.  This
+is simply done by calling <code>mlock</code> from within the function.
+
+<pre class="example">     function count_calls ()
+       mlock ();
+       persistent calls = 0;
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+</pre>
+   <p><code>mlock</code> might equally be used to prevent changes to a function from having
+effect in Octave, though a similar effect can be had with the
+<code>ignore_function_time_stamp</code> function.
+
+<!-- variables.cc -->
+   <p><a name="doc_002dmlock"></a>
+
+<div class="defun">
+— Built-in Function:  <b>mlock</b> ()<var><a name="index-mlock-639"></a></var><br>
+<blockquote><p>Lock the current function into memory so that it can't be cleared. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmunlock.html#doc_002dmunlock">munlock</a>, <a href="doc_002dmislocked.html#doc_002dmislocked">mislocked</a>, <a href="doc_002dpersistent.html#doc_002dpersistent">persistent</a>. 
+</p></blockquote></div>
+
+<!-- variables.cc -->
+   <p><a name="doc_002dmunlock"></a>
+
+<div class="defun">
+— Built-in Function:  <b>munlock</b> (<var>fcn</var>)<var><a name="index-munlock-640"></a></var><br>
+<blockquote><p>Unlock the named function.  If no function is named
+then unlock the current function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmlock.html#doc_002dmlock">mlock</a>, <a href="doc_002dmislocked.html#doc_002dmislocked">mislocked</a>, <a href="doc_002dpersistent.html#doc_002dpersistent">persistent</a>. 
+</p></blockquote></div>
+
+<!-- variables.cc -->
+   <p><a name="doc_002dmislocked"></a>
+
+<div class="defun">
+— Built-in Function:  <b>mislocked</b> (<var>fcn</var>)<var><a name="index-mislocked-641"></a></var><br>
+<blockquote><p>Return true if the named function is locked.  If no function is named
+then return true if the current function is locked. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmlock.html#doc_002dmlock">mlock</a>, <a href="doc_002dmunlock.html#doc_002dmunlock">munlock</a>, <a href="doc_002dpersistent.html#doc_002dpersistent">persistent</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Overloading.html b/doc/interpreter/HTML/Function-Overloading.html
new file mode 100644
index 0000000..cb7cc89
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Overloading.html
@@ -0,0 +1,79 @@
+<html lang="en">
+<head>
+<title>Function Overloading - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Overloading-Objects.html#Overloading-Objects" title="Overloading Objects">
+<link rel="next" href="Operator-Overloading.html#Operator-Overloading" title="Operator Overloading">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Overloading"></a>
+Next: <a rel="next" accesskey="n" href="Operator-Overloading.html#Operator-Overloading">Operator Overloading</a>,
+Up: <a rel="up" accesskey="u" href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>
+<hr>
+</div>
+
+<h4 class="subsection">33.4.1 Function Overloading</h4>
+
+<p>Any Octave function can be overloaded, and allows a object specific
+version of this function to be called as needed.  A pertinent example
+for our polynomial class might be to overload the <code>polyval</code> function
+like
+
+<pre class="example"><pre class="verbatim">     function [y, dy] = polyval (p, varargin)
+       if (nargout == 2)
+         [y, dy] = polyval (fliplr(p.poly), varargin{:});
+       else
+         y = polyval (fliplr(p.poly), varargin{:});
+       endif
+     endfunction
+</pre>
+</pre>
+   <p>This function just hands off the work to the normal Octave <code>polyval</code>
+function.  Another interesting example for an overloaded function for our
+polynomial class is the <code>plot</code> function.
+
+<pre class="example"><pre class="verbatim">     function h = plot(p, varargin)
+       n = 128;
+       rmax = max (abs (roots (p.poly)));
+       x = [0 : (n - 1)] / (n - 1) * 2.2 * rmax - 1.1 * rmax;
+       if (nargout > 0)
+         h = plot(x, p(x), varargin{:});
+       else
+         plot(x, p(x), varargin{:});
+       endif
+     endfunction</pre>
+</pre>
+   <p class="noindent">which allows polynomials to be plotted in the domain near the region
+of the roots of the polynomial.
+
+   <p>Functions that are of particular interest to be overloaded are the class
+conversion functions such as <code>double</code>.  Overloading these functions
+allows the <code>cast</code> function to work with the user class and can aid
+in the use of methods of other classes with the user class.  An example
+<code>double</code> function for our polynomial class might look like.
+
+<pre class="example"><pre class="verbatim">     function b = double (a)
+       b = a.poly;
+     endfunction
+</pre>
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Precedence.html b/doc/interpreter/HTML/Function-Precedence.html
new file mode 100644
index 0000000..69d1f41
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Precedence.html
@@ -0,0 +1,76 @@
+<html lang="en">
+<head>
+<title>Function Precedence - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="prev" href="Function-Locking.html#Function-Locking" title="Function Locking">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Precedence"></a>
+Previous: <a rel="previous" accesskey="p" href="Function-Locking.html#Function-Locking">Function Locking</a>,
+Up: <a rel="up" accesskey="u" href="Function-Files.html#Function-Files">Function Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.7.6 Function Precedence</h4>
+
+<p>Given the numerous different ways that Octave can define a function, it
+is possible and even likely that multiple versions of a function, might be
+defined within a particular scope.  The precedence of which function will be
+used within a particular scope is given by
+
+     <ol type=1 start=1>
+<li>Subfunction
+A subfunction with the required function name in the given scope.
+
+     <li>Private function
+A function defined within a private directory of the directory
+which contains the current function.
+
+     <li>Class constructor
+A function that constuctors a user class as defined in chapter
+<a href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>.
+
+     <li>Class method
+An overloaded function of a class as in chapter
+<a href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>.
+
+     <li>Legacy Dispatch
+An overloaded function as defined by See <a href="doc_002ddispatch.html#doc_002ddispatch">doc-dispatch</a>.
+
+     <li>Command-line Function
+A function that has been defined on the command-line.
+
+     <li>Autoload function
+A function that is marked as autoloaded with See <a href="doc_002dautoload.html#doc_002dautoload">doc-autoload</a>.
+
+     <li>A Function on the Path
+A function that can be found on the users load-path.  There can also be
+Oct-file, mex-file or m-file versions of this function and the precedence
+between these versions are in that order.
+
+     <li>Built-in function
+A function that is builtin to Octave itself such as <code>numel</code>,
+<code>size</code>, etc.
+        </ol>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Function-Support.html b/doc/interpreter/HTML/Function-Support.html
new file mode 100644
index 0000000..b6e2664
--- /dev/null
+++ b/doc/interpreter/HTML/Function-Support.html
@@ -0,0 +1,49 @@
+<html lang="en">
+<head>
+<title>Function Support - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link rel="prev" href="Matrix-Algebra.html#Matrix-Algebra" title="Matrix Algebra">
+<link rel="next" href="Example-Codes.html#Example-Codes" title="Example Codes">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Support"></a>
+Next: <a rel="next" accesskey="n" href="Example-Codes.html#Example-Codes">Example Codes</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrix-Algebra.html#Matrix-Algebra">Matrix Algebra</a>,
+Up: <a rel="up" accesskey="u" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">20.3 Functions That Are Aware of These Matrices</h3>
+
+<p>This section lists the built-in functions that are aware of diagonal and
+permutation matrices on input, or can return them as output.  Passed to other
+functions, these matrices will in general trigger an implicit conversion. 
+(Of course, user-defined dynamically linked functions may also work with
+diagonal or permutation matrices).
+
+<ul class="menu">
+<li><a accesskey="1" href="Diagonal-Matrix-Functions.html#Diagonal-Matrix-Functions">Diagonal Matrix Functions</a>
+<li><a accesskey="2" href="Permutation-Matrix-Functions.html#Permutation-Matrix-Functions">Permutation Matrix Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Functions-and-Scripts.html b/doc/interpreter/HTML/Functions-and-Scripts.html
new file mode 100644
index 0000000..6841a16
--- /dev/null
+++ b/doc/interpreter/HTML/Functions-and-Scripts.html
@@ -0,0 +1,57 @@
+<html lang="en">
+<head>
+<title>Functions and Scripts - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Statements.html#Statements" title="Statements">
+<link rel="next" href="Errors-and-Warnings.html#Errors-and-Warnings" title="Errors and Warnings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Functions-and-Scripts"></a>
+Next: <a rel="next" accesskey="n" href="Errors-and-Warnings.html#Errors-and-Warnings">Errors and Warnings</a>,
+Previous: <a rel="previous" accesskey="p" href="Statements.html#Statements">Statements</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">11 Functions and Scripts</h2>
+
+<p><a name="index-defining-functions-584"></a><a name="index-user_002ddefined-functions-585"></a><a name="index-functions_002c-user_002ddefined-586"></a><a name="index-script-files-587"></a>
+Complicated Octave programs can often be simplified by defining
+functions.  Functions can be defined directly on the command line during
+interactive Octave sessions, or in external files, and can be called just
+like built-in functions.
+
+<ul class="menu">
+<li><a accesskey="1" href="Defining-Functions.html#Defining-Functions">Defining Functions</a>
+<li><a accesskey="2" href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a>
+<li><a accesskey="3" href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a>
+<li><a accesskey="4" href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a>
+<li><a accesskey="5" href="Returning-From-a-Function.html#Returning-From-a-Function">Returning From a Function</a>
+<li><a accesskey="6" href="Default-Arguments.html#Default-Arguments">Default Arguments</a>
+<li><a accesskey="7" href="Function-Files.html#Function-Files">Function Files</a>
+<li><a accesskey="8" href="Script-Files.html#Script-Files">Script Files</a>
+<li><a accesskey="9" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>
+<li><a href="Commands.html#Commands">Commands</a>
+<li><a href="Organization-of-Functions.html#Organization-of-Functions">Organization of Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Functions-of-Multiple-Variables.html b/doc/interpreter/HTML/Functions-of-Multiple-Variables.html
new file mode 100644
index 0000000..1ec302d
--- /dev/null
+++ b/doc/interpreter/HTML/Functions-of-Multiple-Variables.html
@@ -0,0 +1,157 @@
+<html lang="en">
+<head>
+<title>Functions of Multiple Variables - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numerical-Integration.html#Numerical-Integration" title="Numerical Integration">
+<link rel="prev" href="Functions-of-One-Variable.html#Functions-of-One-Variable" title="Functions of One Variable">
+<link rel="next" href="Orthogonal-Collocation.html#Orthogonal-Collocation" title="Orthogonal Collocation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Functions-of-Multiple-Variables"></a>
+Next: <a rel="next" accesskey="n" href="Orthogonal-Collocation.html#Orthogonal-Collocation">Orthogonal Collocation</a>,
+Previous: <a rel="previous" accesskey="p" href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a>,
+Up: <a rel="up" accesskey="u" href="Numerical-Integration.html#Numerical-Integration">Numerical Integration</a>
+<hr>
+</div>
+
+<h3 class="section">22.3 Functions of Multiple Variables</h3>
+
+<p>Octave does not have built-in functions for computing the integral of
+functions of multiple variables directly.  It is however possible to
+compute the integral of a function of multiple variables using the
+functions for one-dimensional integrals.
+
+   <p>To illustrate how the integration can be performed, we will integrate
+the function
+<pre class="example">     f(x, y) = sin(pi*x*y)*sqrt(x*y)
+</pre>
+   <p>for x and y between 0 and 1.
+
+   <p>The first approach creates a function that integrates f with
+respect to x, and then integrates that function with respect to
+y.  Since <code>quad</code> is written in Fortran it cannot be called
+recursively.  This means that <code>quad</code> cannot integrate a function
+that calls <code>quad</code>, and hence cannot be used to perform the double
+integration.  It is however possible with <code>quadl</code>, which is what
+the following code does.
+
+<pre class="example">     function I = g(y)
+       I = ones(1, length(y));
+       for i = 1:length(y)
+         f = @(x) sin(pi.*x.*y(i)).*sqrt(x.*y(i));
+         I(i) = quadl(f, 0, 1);
+       endfor
+     endfunction
+     
+     I = quadl("g", 0, 1)
+            0.30022
+</pre>
+   <p>The above process can be simplified with the <code>dblquad</code> and
+<code>triplequad</code> functions for integrals over two and three
+variables.  For example
+
+<pre class="example">     I =  dblquad (@(x, y) sin(pi.*x.*y).*sqrt(x.*y), 0, 1, 0, 1)
+            0.30022
+</pre>
+   <!-- ./general/dblquad.m -->
+   <p><a name="doc_002ddblquad"></a>
+
+<div class="defun">
+— Function File:  <b>dblquad</b> (<var>f, xa, xb, ya, yb, tol, quadf, <small class="dots">...</small></var>)<var><a name="index-dblquad-1781"></a></var><br>
+<blockquote><p>Numerically evaluate a double integral.  The function over with to
+integrate is defined by <var>f</var>, and the interval for the
+integration is defined by <code>[</code><var>xa</var><code>, </code><var>xb</var><code>, </code><var>ya</var><code>,
+</code><var>yb</var><code>]</code>.  The function <var>f</var> must accept a vector <var>x</var> and a
+scalar <var>y</var>, and return a vector of the same length as <var>x</var>.
+
+        <p>If defined, <var>tol</var> defines the absolute tolerance to which to
+which to integrate each sub-integral.
+
+        <p>Additional arguments, are passed directly to <var>f</var>.  To use the default
+value for <var>tol</var> one may pass an empty matrix. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtriplequad.html#doc_002dtriplequad">triplequad</a>, <a href="doc_002dquad.html#doc_002dquad">quad</a>, <a href="doc_002dquadv.html#doc_002dquadv">quadv</a>, <a href="doc_002dquadl.html#doc_002dquadl">quadl</a>, <a href="doc_002dquadgk.html#doc_002dquadgk">quadgk</a>, <a href="doc_002dtrapz.html#doc_002dtrapz">trapz</a>. 
+</p></blockquote></div>
+
+<!-- ./general/triplequad.m -->
+   <p><a name="doc_002dtriplequad"></a>
+
+<div class="defun">
+— Function File:  <b>triplequad</b> (<var>f, xa, xb, ya, yb, za, zb, tol, quadf, <small class="dots">...</small></var>)<var><a name="index-triplequad-1782"></a></var><br>
+<blockquote><p>Numerically evaluate a triple integral.  The function over which to
+integrate is defined by <var>f</var>, and the interval for the
+integration is defined by <code>[</code><var>xa</var><code>, </code><var>xb</var><code>, </code><var>ya</var><code>,
+</code><var>yb</var><code>, </code><var>za</var><code>, </code><var>zb</var><code>]</code>.  The function <var>f</var> must accept a
+vector <var>x</var> and a scalar <var>y</var>, and return a vector of the same
+length as <var>x</var>.
+
+        <p>If defined, <var>tol</var> defines the absolute tolerance to which to
+which to integrate each sub-integral.
+
+        <p>Additional arguments, are passed directly to <var>f</var>.  To use the default
+value for <var>tol</var> one may pass an empty matrix. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddblquad.html#doc_002ddblquad">dblquad</a>, <a href="doc_002dquad.html#doc_002dquad">quad</a>, <a href="doc_002dquadv.html#doc_002dquadv">quadv</a>, <a href="doc_002dquadl.html#doc_002dquadl">quadl</a>, <a href="doc_002dquadgk.html#doc_002dquadgk">quadgk</a>, <a href="doc_002dtrapz.html#doc_002dtrapz">trapz</a>. 
+</p></blockquote></div>
+
+   <p>The above mentioned approach works but is fairly slow, and that problem
+increases exponentially with the dimensionality the problem.  Another
+possible solution is to use Orthogonal Collocation as described in the
+previous section.  The integral of a function f(x,y) for
+x and y between 0 and 1 can be approximated using n
+points by
+the sum over <code>i=1:n</code> and <code>j=1:n</code> of <code>q(i)*q(j)*f(r(i),r(j))</code>,
+where q and r is as returned by <code>colloc(n)</code>.  The
+generalization to more than two variables is straight forward.  The
+following code computes the studied integral using n=7 points.
+
+<pre class="example">     f = @(x,y) sin(pi*x*y').*sqrt(x*y');
+     n = 7;
+     [t, A, B, q] = colloc(n);
+     I = q'*f(t,t)*q;
+            0.30022
+</pre>
+   <p class="noindent">It should be noted that the number of points determines the quality
+of the approximation.  If the integration needs to be performed between
+a and b instead of 0 and 1, a change of variables is needed.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Functions-of-One-Variable.html b/doc/interpreter/HTML/Functions-of-One-Variable.html
new file mode 100644
index 0000000..9696cb5
--- /dev/null
+++ b/doc/interpreter/HTML/Functions-of-One-Variable.html
@@ -0,0 +1,348 @@
+<html lang="en">
+<head>
+<title>Functions of One Variable - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numerical-Integration.html#Numerical-Integration" title="Numerical Integration">
+<link rel="next" href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables" title="Functions of Multiple Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Functions-of-One-Variable"></a>
+Next: <a rel="next" accesskey="n" href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">Functions of Multiple Variables</a>,
+Up: <a rel="up" accesskey="u" href="Numerical-Integration.html#Numerical-Integration">Numerical Integration</a>
+<hr>
+</div>
+
+<h3 class="section">22.1 Functions of One Variable</h3>
+
+<p>Octave supports three different algorithms for computing the integral
+of a function f over the interval from a to b. 
+These are
+
+     <dl>
+<dt><code>quad</code><dd>Numerical integration based on Gaussian quadrature.
+
+     <br><dt><code>quadl</code><dd>Numerical integration using an adaptive Lobatto rule.
+
+     <br><dt><code>quadgk</code><dd>Numerical integration using an adaptive Gauss-Konrod rule.
+
+     <br><dt><code>quadv</code><dd>Numerical integration using an adaptive vectorized Simpson's rule.
+
+     <br><dt><code>trapz</code><dd>Numerical integration using the trapezoidal method. 
+</dl>
+
+<p class="noindent">Besides these functions Octave also allows you to perform cumulative
+numerical integration using the trapezoidal method through the
+<code>cumtrapz</code> function.
+
+<!-- ./DLD-FUNCTIONS/quad.cc -->
+   <p><a name="doc_002dquad"></a>
+
+<div class="defun">
+— Loadable Function: [<var>v</var>, <var>ier</var>, <var>nfun</var>, <var>err</var>] = <b>quad</b> (<var>f, a, b, tol, sing</var>)<var><a name="index-quad-1760"></a></var><br>
+<blockquote><p>Integrate a nonlinear function of one variable using Quadpack. 
+The first argument is the name of the function, the function handle or
+the inline function to call to compute the value of the integrand.  It
+must have the form
+
+     <pre class="example">          y = f (x)
+</pre>
+        <p class="noindent">where <var>y</var> and <var>x</var> are scalars.
+
+        <p>The second and third arguments are limits of integration.  Either or
+both may be infinite.
+
+        <p>The optional argument <var>tol</var> is a vector that specifies the desired
+accuracy of the result.  The first element of the vector is the desired
+absolute tolerance, and the second element is the desired relative
+tolerance.  To choose a relative test only, set the absolute
+tolerance to zero.  To choose an absolute test only, set the relative
+tolerance to zero.
+
+        <p>The optional argument <var>sing</var> is a vector of values at which the
+integrand is known to be singular.
+
+        <p>The result of the integration is returned in <var>v</var> and <var>ier</var>
+contains an integer error code (0 indicates a successful integration). 
+The value of <var>nfun</var> indicates how many function evaluations were
+required, and <var>err</var> contains an estimate of the error in the
+solution.
+
+        <p>You can use the function <code>quad_options</code> to set optional
+parameters for <code>quad</code>.
+
+        <p>It should be noted that since <code>quad</code> is written in Fortran it
+cannot be called recursively. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/quad.cc -->
+   <p><a name="doc_002dquad_005foptions"></a>
+
+<div class="defun">
+— Loadable Function:  <b>quad_options</b> (<var>opt, val</var>)<var><a name="index-quad_005foptions-1761"></a></var><br>
+<blockquote><p>When called with two arguments, this function
+allows you set options parameters for the function <code>quad</code>. 
+Given one argument, <code>quad_options</code> returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+        <p>Options include
+
+          <dl>
+<dt><code>"absolute tolerance"</code><dd>Absolute tolerance; may be zero for pure relative error test. 
+<br><dt><code>"relative tolerance"</code><dd>Nonnegative relative tolerance.  If the absolute tolerance is zero,
+the relative tolerance must be greater than or equal to
+<code>max (50*eps, 0.5e-28)</code>. 
+<br><dt><code>"single precision absolute tolerance"</code><dd>Absolute tolerance for single precision; may be zero for pure relative
+error test. 
+<br><dt><code>"single precision relative tolerance"</code><dd>Nonnegative relative tolerance for single precision.  If the absolute
+tolerance is zero, the relative tolerance must be greater than or equal to
+<code>max (50*eps, 0.5e-28)</code>. 
+</dl>
+        </p></blockquote></div>
+
+   <p>Here is an example of using <code>quad</code> to integrate the function
+
+<pre class="example">       <var>f</var>(<var>x</var>) = <var>x</var> * sin (1/<var>x</var>) * sqrt (abs (1 - <var>x</var>))
+</pre>
+   <p class="noindent">from <var>x</var> = 0 to <var>x</var> = 3.
+
+   <p>This is a fairly difficult integration (plot the function over the range
+of integration to see why).
+
+   <p>The first step is to define the function:
+
+<pre class="example">     function y = f (x)
+       y = x .* sin (1 ./ x) .* sqrt (abs (1 - x));
+     endfunction
+</pre>
+   <p>Note the use of the `dot' forms of the operators.  This is not necessary
+for the call to <code>quad</code>, but it makes it much easier to generate a
+set of points for plotting (because it makes it possible to call the
+function with a vector argument to produce a vector result).
+
+   <p>Then we simply call quad:
+
+<pre class="example">     [v, ier, nfun, err] = quad ("f", 0, 3)
+           1.9819
+           1
+           5061
+           1.1522e-07
+</pre>
+   <p>Although <code>quad</code> returns a nonzero value for <var>ier</var>, the result
+is reasonably accurate (to see why, examine what happens to the result
+if you move the lower bound to 0.1, then 0.01, then 0.001, etc.).
+
+<!-- ./general/quadl.m -->
+   <p><a name="doc_002dquadl"></a>
+
+<div class="defun">
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b</var>)<var><a name="index-quadl-1762"></a></var><br>
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b, tol</var>)<var><a name="index-quadl-1763"></a></var><br>
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b, tol, trace</var>)<var><a name="index-quadl-1764"></a></var><br>
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b, tol, trace, p1, p2, <small class="dots">...</small></var>)<var><a name="index-quadl-1765"></a></var><br>
+<blockquote>
+        <p>Numerically evaluate integral using adaptive Lobatto rule. 
+<code>quadl (</code><var>f</var><code>, </code><var>a</var><code>, </code><var>b</var><code>)</code> approximates the integral of
+<var>f</var><code>(</code><var>x</var><code>)</code> to machine precision.  <var>f</var> is either a
+function handle, inline function or string containing the name of
+the function to evaluate.  The function <var>f</var> must return a vector
+of output values if given a vector of input values.
+
+        <p>If defined, <var>tol</var> defines the relative tolerance to which to
+which to integrate <var>f</var><code>(</code><var>x</var><code>)</code>.  While if <var>trace</var> is
+defined, displays the left end point of the current interval, the
+interval length, and the partial integral.
+
+        <p>Additional arguments <var>p1</var>, etc., are passed directly to <var>f</var>. 
+To use default values for <var>tol</var> and <var>trace</var>, one may pass
+empty matrices.
+
+        <p>Reference: W. Gander and W. Gautschi, 'Adaptive Quadrature -
+Revisited', BIT Vol. 40, No. 1, March 2000, pp. 84–101. 
+<a href="http://www.inf.ethz.ch/personal/gander/">http://www.inf.ethz.ch/personal/gander/</a>
+
+        </blockquote></div>
+
+<!-- ./general/quadgk.m -->
+   <p><a name="doc_002dquadgk"></a>
+
+<div class="defun">
+— Function File:  <b>quadgk</b> (<var>f, a, b, abstol, trace</var>)<var><a name="index-quadgk-1766"></a></var><br>
+— Function File:  <b>quadgk</b> (<var>f, a, b, prop, val, <small class="dots">...</small></var>)<var><a name="index-quadgk-1767"></a></var><br>
+— Function File: [<var>q</var>, <var>err</var>] = <b>quadgk</b> (<var><small class="dots">...</small></var>)<var><a name="index-quadgk-1768"></a></var><br>
+<blockquote><p>Numerically evaluate integral using adaptive Gauss-Konrod quadrature. 
+The formulation is based on a proposal by L.F. Shampine,
+<cite>"Vectorized adaptive quadrature in </cite><span class="sc">matlab</span><cite>", Journal of
+Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2,
+Feb 2008</cite> where all function evaluations at an iteration are
+calculated with a single call to <var>f</var>.  Therefore the function
+<var>f</var> must be of the form <var>f</var><code> (</code><var>x</var><code>)</code> and accept
+vector values of <var>x</var> and return a vector of the same length
+representing the function evaluations at the given values of <var>x</var>. 
+The function <var>f</var> can be defined in terms of a function handle,
+inline function or string.
+
+        <p>The bounds of the quadrature <code>[</code><var>a</var><code>, </code><var>b</var><code>]</code> can be finite
+or infinite and contain weak end singularities.  Variable
+transformation will be used to treat infinite intervals and weaken
+the singularities.  For example
+
+     <pre class="example">          quadgk(@(x) 1 ./ (sqrt (x) .* (x + 1)), 0, Inf)
+</pre>
+        <p class="noindent">Note that the formulation of the integrand uses the
+element-by-element operator <code>./</code> and all user functions to
+<code>quadgk</code> should do the same.
+
+        <p>The absolute tolerance can be passed as a fourth argument in a manner
+compatible with <code>quadv</code>.  Equally the user can request that
+information on the convergence can be printed is the fifth argument
+is logically true.
+
+        <p>Alternatively, certain properties of <code>quadgk</code> can be passed as
+pairs <var>prop</var><code>, </code><var>val</var>.  Valid properties are
+
+          <dl>
+<dt><code>AbsTol</code><dd>Defines the absolute error tolerance for the quadrature.  The default
+absolute tolerance is 1e-10.
+
+          <br><dt><code>RelTol</code><dd>Defines the relative error tolerance for the quadrature.  The default
+relative tolerance is 1e-5.
+
+          <br><dt><code>MaxIntervalCount</code><dd><code>quadgk</code> initially subdivides the interval on which to perform
+the quadrature into 10 intervals.  Sub-intervals that have an
+unacceptable error are sub-divided and re-evaluated.  If the number of
+sub-intervals exceeds at any point 650 sub-intervals then a poor
+convergence is signaled and the current estimate of the integral is
+returned.  The property 'MaxIntervalCount' can be used to alter the
+number of sub-intervals that can exist before exiting.
+
+          <br><dt><code>WayPoints</code><dd>If there exists discontinuities in the first derivative of the
+function to integrate, then these can be flagged with the
+<code>"WayPoints"</code> property.  This forces the ends of a sub-interval
+to fall on the breakpoints of the function and can result in
+significantly improved estimation of the error in the integral, faster
+computation or both.  For example,
+
+          <pre class="example">               quadgk (@(x) abs (1 - x .^ 2), 0, 2, 'Waypoints', 1)
+</pre>
+          <p class="noindent">signals the breakpoint in the integrand at <var>x</var><code> = 1</code>.
+
+          <br><dt><code>Trace</code><dd>If logically true, then <code>quadgk</code> prints information on the
+convergence of the quadrature at each iteration. 
+</dl>
+
+        <p>If any of <var>a</var>, <var>b</var> or <var>waypoints</var> is complex, then the
+quadrature is treated as a contour integral along a piecewise
+continuous path defined by the above.  In this case the integral is
+assumed to have no edge singularities.  For example
+
+     <pre class="example">          quadgk (@(z) log (z), 1+1i, 1+1i, "WayPoints",
+                  [1-1i, -1,-1i, -1+1i])
+</pre>
+        <p class="noindent">integrates <code>log (z)</code> along the square defined by <code>[1+1i,
+ 1-1i, -1-1i, -1+1i]</code>
+
+        <p>If two output arguments are requested, then <var>err</var> returns the
+approximate bounds on the error in the integral <code>abs (</code><var>q</var><code> -
+</code><var>i</var><code>)</code>, where <var>i</var> is the exact value of the integral.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtriplequad.html#doc_002dtriplequad">triplequad</a>, <a href="doc_002ddblquad.html#doc_002ddblquad">dblquad</a>, <a href="doc_002dquad.html#doc_002dquad">quad</a>, <a href="doc_002dquadl.html#doc_002dquadl">quadl</a>, <a href="doc_002dquadv.html#doc_002dquadv">quadv</a>, <a href="doc_002dtrapz.html#doc_002dtrapz">trapz</a>. 
+</p></blockquote></div>
+
+<!-- ./general/quadv.m -->
+   <p><a name="doc_002dquadv"></a>
+
+<div class="defun">
+— Function File: <var>q</var> = <b>quadv</b> (<var>f, a, b</var>)<var><a name="index-quadv-1769"></a></var><br>
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b, tol</var>)<var><a name="index-quadl-1770"></a></var><br>
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b, tol, trace</var>)<var><a name="index-quadl-1771"></a></var><br>
+— Function File: <var>q</var> = <b>quadl</b> (<var>f, a, b, tol, trace, p1, p2, <small class="dots">...</small></var>)<var><a name="index-quadl-1772"></a></var><br>
+— Function File: [<var>q</var>, <var>fcnt</var>] = <b>quadl</b> (<var><small class="dots">...</small></var>)<var><a name="index-quadl-1773"></a></var><br>
+<blockquote>
+        <p>Numerically evaluate integral using adaptive Simpson's rule. 
+<code>quadv (</code><var>f</var><code>, </code><var>a</var><code>, </code><var>b</var><code>)</code> approximates the integral of
+<var>f</var><code>(</code><var>x</var><code>)</code> to the default absolute tolerance of <code>1e-6</code>. 
+<var>f</var> is either a function handle, inline function or string
+containing the name of the function to evaluate.  The function <var>f</var>
+must accept a string, and can return a vector representing the
+approximation to <var>n</var> different sub-functions.
+
+        <p>If defined, <var>tol</var> defines the absolute tolerance to which to
+which to integrate each sub-interval of <var>f</var><code>(</code><var>x</var><code>)</code>. 
+While if <var>trace</var> is defined, displays the left end point of the
+current interval, the interval length, and the partial integral.
+
+        <p>Additional arguments <var>p1</var>, etc., are passed directly to <var>f</var>. 
+To use default values for <var>tol</var> and <var>trace</var>, one may pass
+empty matrices. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtriplequad.html#doc_002dtriplequad">triplequad</a>, <a href="doc_002ddblquad.html#doc_002ddblquad">dblquad</a>, <a href="doc_002dquad.html#doc_002dquad">quad</a>, <a href="doc_002dquadl.html#doc_002dquadl">quadl</a>, <a href="doc_002dquadgk.html#doc_002dquadgk">quadgk</a>, <a href="doc_002dtrapz.html#doc_002dtrapz">trapz</a>. 
+</p></blockquote></div>
+
+<!-- ./general/trapz.m -->
+   <p><a name="doc_002dtrapz"></a>
+
+<div class="defun">
+— Function File: <var>z</var> = <b>trapz</b> (<var>y</var>)<var><a name="index-trapz-1774"></a></var><br>
+— Function File: <var>z</var> = <b>trapz</b> (<var>x, y</var>)<var><a name="index-trapz-1775"></a></var><br>
+— Function File: <var>z</var> = <b>trapz</b> (<var><small class="dots">...</small>, dim</var>)<var><a name="index-trapz-1776"></a></var><br>
+<blockquote>
+        <p>Numerical integration using trapezoidal method.  <code>trapz
+(</code><var>y</var><code>)</code> computes the integral of the <var>y</var> along the first
+non-singleton dimension.  If the argument <var>x</var> is omitted a
+equally spaced vector is assumed.  <code>trapz (</code><var>x</var><code>, </code><var>y</var><code>)</code>
+evaluates the integral with respect to <var>x</var>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcumtrapz.html#doc_002dcumtrapz">cumtrapz</a>. 
+</p></blockquote></div>
+
+<!-- ./general/cumtrapz.m -->
+   <p><a name="doc_002dcumtrapz"></a>
+
+<div class="defun">
+— Function File: <var>z</var> = <b>cumtrapz</b> (<var>y</var>)<var><a name="index-cumtrapz-1777"></a></var><br>
+— Function File: <var>z</var> = <b>cumtrapz</b> (<var>x, y</var>)<var><a name="index-cumtrapz-1778"></a></var><br>
+— Function File: <var>z</var> = <b>cumtrapz</b> (<var><small class="dots">...</small>, dim</var>)<var><a name="index-cumtrapz-1779"></a></var><br>
+<blockquote>
+        <p>Cumulative numerical integration using trapezoidal method. 
+<code>cumtrapz (</code><var>y</var><code>)</code> computes the cumulative integral of the
+<var>y</var> along the first non-singleton dimension.  If the argument
+<var>x</var> is omitted a equally spaced vector is assumed.  <code>cumtrapz
+(</code><var>x</var><code>, </code><var>y</var><code>)</code> evaluates the cumulative integral with respect
+to <var>x</var>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtrapz.html#doc_002dtrapz">trapz</a>, <a href="doc_002dcumsum.html#doc_002dcumsum">cumsum</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Functions-of-a-Matrix.html b/doc/interpreter/HTML/Functions-of-a-Matrix.html
new file mode 100644
index 0000000..56d01fa
--- /dev/null
+++ b/doc/interpreter/HTML/Functions-of-a-Matrix.html
@@ -0,0 +1,132 @@
+<html lang="en">
+<head>
+<title>Functions of a Matrix - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link rel="prev" href="Matrix-Factorizations.html#Matrix-Factorizations" title="Matrix Factorizations">
+<link rel="next" href="Specialized-Solvers.html#Specialized-Solvers" title="Specialized Solvers">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Functions-of-a-Matrix"></a>
+Next: <a rel="next" accesskey="n" href="Specialized-Solvers.html#Specialized-Solvers">Specialized Solvers</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>,
+Up: <a rel="up" accesskey="u" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>
+<hr>
+</div>
+
+<h3 class="section">18.4 Functions of a Matrix</h3>
+
+<!-- ./linear-algebra/expm.m -->
+<p><a name="doc_002dexpm"></a>
+
+<div class="defun">
+— Function File:  <b>expm</b> (<var>a</var>)<var><a name="index-expm-1622"></a></var><br>
+<blockquote><p>Return the exponential of a matrix, defined as the infinite Taylor
+series
+
+     <pre class="example">          expm(a) = I + a + a^2/2! + a^3/3! + ...
+</pre>
+        <p>The Taylor series is <em>not</em> the way to compute the matrix
+exponential; see Moler and Van Loan, <cite>Nineteen Dubious Ways to
+Compute the Exponential of a Matrix</cite>, SIAM Review, 1978.  This routine
+uses Ward's diagonal
+Pade'
+approximation method with three step preconditioning (SIAM Journal on
+Numerical Analysis, 1977).  Diagonal
+Pade'
+ approximations are rational polynomials of matrices
+
+     <pre class="example">               -1
+          D (a)   N (a)
+</pre>
+        <p>whose Taylor series matches the first
+<code>2q+1</code>
+terms of the Taylor series above; direct evaluation of the Taylor series
+(with the same preconditioning steps) may be desirable in lieu of the
+Pade'
+approximation when
+<code>Dq(a)</code>
+is ill-conditioned. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/logm.m -->
+   <p><a name="doc_002dlogm"></a>
+
+<div class="defun">
+— Function File:  <b>logm</b> (<var>a</var>)<var><a name="index-logm-1623"></a></var><br>
+<blockquote><p>Compute the matrix logarithm of the square matrix <var>a</var>.  Note that
+this is currently implemented in terms of an eigenvalue expansion and
+needs to be improved to be more robust. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/sqrtm.cc -->
+   <p><a name="doc_002dsqrtm"></a>
+
+<div class="defun">
+— Loadable Function: [<var>result</var>, <var>error_estimate</var>] = <b>sqrtm</b> (<var>a</var>)<var><a name="index-sqrtm-1624"></a></var><br>
+<blockquote><p>Compute the matrix square root of the square matrix <var>a</var>.
+
+        <p>Ref: Nicholas J. Higham.  A new sqrtm for <span class="sc">matlab</span>.  Numerical Analysis
+Report No. 336, Manchester Centre for Computational Mathematics,
+Manchester, England, January 1999. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dexpm.html#doc_002dexpm">expm</a>, <a href="doc_002dlogm.html#doc_002dlogm">logm</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/kron.cc -->
+   <p><a name="doc_002dkron"></a>
+
+<div class="defun">
+— Loadable Function:  <b>kron</b> (<var>a, b</var>)<var><a name="index-kron-1625"></a></var><br>
+<blockquote><p>Form the kronecker product of two matrices, defined block by block as
+
+     <pre class="example">          x = [a(i, j) b]
+</pre>
+        <p>For example,
+
+     <pre class="example">          kron (1:4, ones (3, 1))
+                  1  2  3  4
+                    1  2  3  4
+                    1  2  3  4
+</pre>
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/syl.cc -->
+   <p><a name="doc_002dsyl"></a>
+
+<div class="defun">
+— Loadable Function: <var>x</var> = <b>syl</b> (<var>a, b, c</var>)<var><a name="index-syl-1626"></a></var><br>
+<blockquote><p>Solve the Sylvester equation
+
+     <pre class="example">          A X + X B + C = 0
+</pre>
+        <p>using standard <span class="sc">lapack</span> subroutines.  For example,
+
+     <pre class="example">          syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
+                [ -0.50000, -0.66667; -0.66667, -0.50000 ]
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/General-Guidelines.html b/doc/interpreter/HTML/General-Guidelines.html
new file mode 100644
index 0000000..b0ce03f
--- /dev/null
+++ b/doc/interpreter/HTML/General-Guidelines.html
@@ -0,0 +1,84 @@
+<html lang="en">
+<head>
+<title>General Guidelines - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link rel="prev" href="How-to-Contribute.html#How-to-Contribute" title="How to Contribute">
+<link rel="next" href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029" title="Octave Sources (m-files)">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="General-Guidelines"></a>
+Next: <a rel="next" accesskey="n" href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029">Octave Sources (m-files)</a>,
+Previous: <a rel="previous" accesskey="p" href="How-to-Contribute.html#How-to-Contribute">How to Contribute</a>,
+Up: <a rel="up" accesskey="u" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>
+<hr>
+</div>
+
+<h3 class="section">D.2 General Guidelines</h3>
+
+<p>All Octave's sources are distributed under the General Public License (GPL). 
+Currently, Octave uses GPL version 3.  For details about this license, see
+<a href="http://www.gnu.org/licenses/gpl.html">http://www.gnu.org/licenses/gpl.html</a>.  Therefore, whenever you create a
+new source file, it should have the following comment header (use appropriate
+year, name and comment marks):
+
+<pre class="example">     ## Copyright (C) 1996, 1997, 2007 John W. Eaton <jwe at octave.org>
+     ##
+     ## This file is part of Octave.
+     ##
+     ## Octave is free software; you can redistribute it and/or
+     ## modify it under the terms of the GNU General Public
+     ## License as published by the Free Software Foundation;
+     ## either version 3 of the License, or (at your option) any
+     ## later version.
+     ##
+     ## Octave is distributed in the hope that it will be useful,
+     ## but WITHOUT ANY WARRANTY; without even the implied
+     ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     ## PURPOSE.  See the GNU General Public License for more
+     ## details.
+     ##
+     ## You should have received a copy of the GNU General Public
+     ## License along with Octave; see the file COPYING.  If not,
+     ## see <http://www.gnu.org/licenses/>.
+</pre>
+   <p>Always include ChangeLog entries in changesets.  After making your source
+changes, record and briefly describe the changes in the nearest ChangeLog file
+upwards in the directory tree.  Use the previous entries as a template.  Your
+entry should contain your name and email, and the path to the modified source
+file relative to the parent directory of the ChangeLog file.  If there are more
+functions in the file, you should also include the name of the modified function
+(in parentheses after file path).  Example:
+
+<pre class="example">     2008-04-02  David Bateman  <dbateman at free.fr>
+     
+             * graphics.cc (void gnuplot_backend::close_figure (const
+             octave_value&) const): Allow for an input and output stream.
+</pre>
+   <p class="noindent">The ChangeLog entries should describe what is changed, not why.  Any
+explanation of why a change is needed should appear as comments in the
+code, particularly if there is something that might not be obvious to
+someone reading it later.
+
+   <p>The preferred comment mark for places that may need further attention is FIXME.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Geometry.html b/doc/interpreter/HTML/Geometry.html
new file mode 100644
index 0000000..dfbc39c
--- /dev/null
+++ b/doc/interpreter/HTML/Geometry.html
@@ -0,0 +1,58 @@
+<html lang="en">
+<head>
+<title>Geometry - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Interpolation.html#Interpolation" title="Interpolation">
+<link rel="next" href="Signal-Processing.html#Signal-Processing" title="Signal Processing">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Geometry"></a>
+Next: <a rel="next" accesskey="n" href="Signal-Processing.html#Signal-Processing">Signal Processing</a>,
+Previous: <a rel="previous" accesskey="p" href="Interpolation.html#Interpolation">Interpolation</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">29 Geometry</h2>
+
+<p>Much of the geometry code in Octave is based on the Qhull
+library<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>. 
+Some of the documentation for Qhull, particularly for the options that
+can be passed to <code>delaunay</code>, <code>voronoi</code> and <code>convhull</code>,
+etc., is relevant to Octave users.
+
+<ul class="menu">
+<li><a accesskey="1" href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a>
+<li><a accesskey="2" href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a>
+<li><a accesskey="3" href="Convex-Hull.html#Convex-Hull">Convex Hull</a>
+<li><a accesskey="4" href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a>
+</ul>
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T.,
+"The Quickhull algorithm for convex hulls," ACM Trans. on Mathematical
+Software, 22(4):469–483, Dec 1996, <a href="http://www.qhull.org">http://www.qhull.org</a></p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Getting-Help.html b/doc/interpreter/HTML/Getting-Help.html
new file mode 100644
index 0000000..2c2f8bc
--- /dev/null
+++ b/doc/interpreter/HTML/Getting-Help.html
@@ -0,0 +1,245 @@
+<html lang="en">
+<head>
+<title>Getting Help - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="prev" href="Quitting-Octave.html#Quitting-Octave" title="Quitting Octave">
+<link rel="next" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Getting-Help"></a>
+Next: <a rel="next" accesskey="n" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>,
+Previous: <a rel="previous" accesskey="p" href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.3 Commands for Getting Help</h3>
+
+<p><a name="index-on_002dline-help-83"></a><a name="index-help_002c-on_002dline-84"></a>
+The entire text of this manual is available from the Octave prompt
+via the command <kbd>doc</kbd>.  In addition, the documentation for
+individual user-written functions and variables is also available via
+the <kbd>help</kbd> command.  This section describes the commands used for
+reading the manual and the documentation strings for user-supplied
+functions and variables.  See <a href="Function-Files.html#Function-Files">Function Files</a>, for more information
+about how to document the functions you write.
+
+<!-- ./help/help.m -->
+   <p><a name="doc_002dhelp"></a>
+
+<div class="defun">
+— Command: help <var>name</var><var><a name="index-g_t_0040var_007bname_007d-85"></a></var><br>
+<blockquote><p>Display the help text for <var>name</var>. 
+If invoked without any arguments, <code>help</code> prints a list
+of all the available operators and functions.
+
+        <p>For example, the command <kbd>help help</kbd> prints a short message
+describing the <code>help</code> command.
+
+        <p>The help command can give you information about operators, but not the
+comma and semicolons that are used as command separators.  To get help
+for those, you must type <kbd>help comma</kbd> or <kbd>help semicolon</kbd>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddoc.html#doc_002ddoc">doc</a>, <a href="doc_002dlookfor.html#doc_002dlookfor">lookfor</a>, <a href="doc_002dwhich.html#doc_002dwhich">which</a>. 
+</p></blockquote></div>
+
+<!-- ./help/doc.m -->
+   <p><a name="doc_002ddoc"></a>
+
+<div class="defun">
+— Command: doc <var>function_name</var><var><a name="index-g_t_0040var_007bfunction_005fname_007d-86"></a></var><br>
+<blockquote><p>Display documentation for the function <var>function_name</var>
+directly from an on-line version of
+the printed manual, using the GNU Info browser.  If invoked without
+any arguments, the manual is shown from the beginning.
+
+        <p>For example, the command <kbd>doc rand</kbd> starts the GNU Info browser
+at the <code>rand</code> node in the on-line version of the manual.
+
+        <p>Once the GNU Info browser is running, help for using it is available
+using the command <kbd>C-h</kbd>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhelp.html#doc_002dhelp">help</a>. 
+</p></blockquote></div>
+
+<!-- ./help/lookfor.m -->
+   <p><a name="doc_002dlookfor"></a>
+
+<div class="defun">
+— Command: lookfor <var>str</var><var><a name="index-g_t_0040var_007bstr_007d-87"></a></var><br>
+— Command: lookfor <b>-all</b><var> str<a name="index-g_t_002dall-88"></a></var><br>
+— Function: [<var>func</var>, <var>helpstring</var>] = <b>lookfor</b> (<var>str</var>)<var><a name="index-lookfor-89"></a></var><br>
+— Function: [<var>func</var>, <var>helpstring</var>] = <b>lookfor</b> (<var>'-all', str</var>)<var><a name="index-lookfor-90"></a></var><br>
+<blockquote><p>Search for the string <var>str</var> in all functions found in the current
+function search path.  By default, <code>lookfor</code> searches for <var>str</var>
+in the first sentence of the help string of each function found.  The entire
+help text of each function can be searched if the '-all' argument is
+supplied.  All searches are case insensitive.
+
+        <p>Called with no output arguments, <code>lookfor</code> prints the list of
+matching functions to the terminal.  Otherwise, the output arguments
+<var>func</var> and <var>helpstring</var> define the matching functions and the
+first sentence of each of their help strings.
+
+        <p>The ability of <code>lookfor</code> to correctly identify the first
+sentence of the help text is dependent on the format of the
+function's help.  All Octave core functions are correctly
+formatted, but the same can not be guaranteed for external packages and
+user-supplied functions.  Therefore, the use of the '-all' argument may
+be necessary to find related functions that are not a part of Octave. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhelp.html#doc_002dhelp">help</a>, <a href="doc_002ddoc.html#doc_002ddoc">doc</a>, <a href="doc_002dwhich.html#doc_002dwhich">which</a>. 
+</p></blockquote></div>
+
+   <p>To see what is new in the current release of Octave, use the <code>news</code>
+function.
+
+<!-- ./miscellaneous/news.m -->
+   <p><a name="doc_002dnews"></a>
+
+<div class="defun">
+— Function File:  <b>news</b> ()<var><a name="index-news-91"></a></var><br>
+<blockquote><p>Display the current NEWS file for Octave. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/info.m -->
+   <p><a name="doc_002dinfo"></a>
+
+<div class="defun">
+— Function File:  <b>info</b> ()<var><a name="index-info-92"></a></var><br>
+<blockquote><p>Display contact information for the GNU Octave community. 
+</p></blockquote></div>
+
+<!-- toplev.cc -->
+   <p><a name="doc_002dwarranty"></a>
+
+<div class="defun">
+— Built-in Function:  <b>warranty</b> ()<var><a name="index-warranty-93"></a></var><br>
+<blockquote><p>Describe the conditions for copying and distributing Octave. 
+</p></blockquote></div>
+
+   <p>The following functions can be used to change which programs are used
+for displaying the documentation, and where the documentation can be
+found.
+
+<!-- help.cc -->
+   <p><a name="doc_002dinfo_005ffile"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>info_file</b> ()<var><a name="index-info_005ffile-94"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>info_file</b> (<var>new_val</var>)<var><a name="index-info_005ffile-95"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the name of the
+Octave info file.  The default value is
+<samp><var>octave-home</var><span class="file">/info/octave.info</span></samp>, in
+which <var>octave-home</var> is the root directory of the Octave installation. 
+The default value may be overridden by the environment variable
+<code>OCTAVE_INFO_FILE</code><!-- /@w -->, or the command line argument
+‘<samp><span class="samp">--info-file NAME</span></samp>’. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinfo_005fprogram.html#doc_002dinfo_005fprogram">info_program</a>, <a href="doc_002ddoc.html#doc_002ddoc">doc</a>, <a href="doc_002dhelp.html#doc_002dhelp">help</a>, <a href="doc_002dmakeinfo_005fprogram.html#doc_002dmakeinfo_005fprogram">makeinfo_program</a>. 
+</p></blockquote></div>
+
+<!-- help.cc -->
+   <p><a name="doc_002dinfo_005fprogram"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>info_program</b> ()<var><a name="index-info_005fprogram-96"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>info_program</b> (<var>new_val</var>)<var><a name="index-info_005fprogram-97"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the name of the
+info program to run.  The default value is
+<samp><var>octave-home</var><span class="file">/libexec/octave/</span><var>version</var><span class="file">/exec/</span><var>arch</var><span class="file">/info</span></samp>
+in which <var>octave-home</var> is the root directory of the Octave installation,
+<var>version</var> is the Octave version number, and <var>arch</var>
+is the system type (for example, <code>i686-pc-linux-gnu</code>).  The
+default value may be overridden by the environment variable
+<code>OCTAVE_INFO_PROGRAM</code><!-- /@w -->, or the command line argument
+‘<samp><span class="samp">--info-program NAME</span></samp>’. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinfo_005ffile.html#doc_002dinfo_005ffile">info_file</a>, <a href="doc_002ddoc.html#doc_002ddoc">doc</a>, <a href="doc_002dhelp.html#doc_002dhelp">help</a>, <a href="doc_002dmakeinfo_005fprogram.html#doc_002dmakeinfo_005fprogram">makeinfo_program</a>. 
+</p></blockquote></div>
+
+<!-- help.cc -->
+   <p><a name="doc_002dmakeinfo_005fprogram"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>makeinfo_program</b> ()<var><a name="index-makeinfo_005fprogram-98"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>makeinfo_program</b> (<var>new_val</var>)<var><a name="index-makeinfo_005fprogram-99"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the name of the
+program that Octave runs to format help text containing
+Texinfo markup commands.  The default value is <code>makeinfo</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinfo_005ffile.html#doc_002dinfo_005ffile">info_file</a>, <a href="doc_002dinfo_005fprogram.html#doc_002dinfo_005fprogram">info_program</a>, <a href="doc_002ddoc.html#doc_002ddoc">doc</a>, <a href="doc_002dhelp.html#doc_002dhelp">help</a>. 
+</p></blockquote></div>
+
+<!-- help.cc -->
+   <p><a name="doc_002ddoc_005fcache_005ffile"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>doc_cache_file</b> ()<var><a name="index-doc_005fcache_005ffile-100"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>doc_cache_file</b> (<var>new_val</var>)<var><a name="index-doc_005fcache_005ffile-101"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the name of the
+Octave documentation cache file.  A cache file significantly improves
+the performance of the <code>lookfor</code> command.  The default value is
+<samp><var>octave-home</var><span class="file">/share/octave/</span><var>version</var><span class="file">/etc/doc-cache</span></samp>,
+in which <var>octave-home</var> is the root directory of the Octave installation,
+and <var>version</var> is the Octave version number. 
+The default value may be overridden by the environment variable
+<code>OCTAVE_DOC_CACHE_FILE</code><!-- /@w -->, or the command line argument
+‘<samp><span class="samp">--doc-cache-file NAME</span></samp>’. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlookfor.html#doc_002dlookfor">lookfor</a>, <a href="doc_002dinfo_005fprogram.html#doc_002dinfo_005fprogram">info_program</a>, <a href="doc_002ddoc.html#doc_002ddoc">doc</a>, <a href="doc_002dhelp.html#doc_002dhelp">help</a>, <a href="doc_002dmakeinfo_005fprogram.html#doc_002dmakeinfo_005fprogram">makeinfo_program</a>. 
+</p></blockquote></div>
+
+<!-- help.cc -->
+   <p><a name="doc_002dsuppress_005fverbose_005fhelp_005fmessage"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>suppress_verbose_help_message</b> ()<var><a name="index-suppress_005fverbose_005fhelp_005fmessage-102"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>suppress_verbose_help_message</b> (<var>new_val</var>)<var><a name="index-suppress_005fverbose_005fhelp_005fmessage-103"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave
+will add additional help information to the end of the output from
+the <code>help</code> command and usage messages for built-in commands. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Getting-Started-with-Mex_002dFiles.html b/doc/interpreter/HTML/Getting-Started-with-Mex_002dFiles.html
new file mode 100644
index 0000000..3e8e821
--- /dev/null
+++ b/doc/interpreter/HTML/Getting-Started-with-Mex_002dFiles.html
@@ -0,0 +1,154 @@
+<html lang="en">
+<head>
+<title>Getting Started with Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="next" href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles" title="Working with Matrices and Arrays in Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Getting-Started-with-Mex-Files"></a>
+<a name="Getting-Started-with-Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles">Working with Matrices and Arrays in Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.1 Getting Started with Mex-Files</h4>
+
+<p>The basic command to build a mex-file is either <code>mkoctfile --mex</code> or
+<code>mex</code>.  The first can either be used from within Octave or from the
+command line.  However, to avoid issues with the installation of other
+products, the use of the command <code>mex</code> is limited to within Octave.
+
+<!-- ./miscellaneous/mex.m -->
+   <p><a name="doc_002dmex"></a>
+
+<div class="defun">
+— Function File:  <b>mex</b> [<var>options</var>]<var> file <small class="dots">...</small><a name="index-mex-2482"></a></var><br>
+<blockquote><p>Compile source code written in C, C++, or Fortran, to a MEX file. 
+This is equivalent to <code>mkoctfile --mex [options] file</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmkoctfile.html#doc_002dmkoctfile">mkoctfile</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/mexext.m -->
+   <p><a name="doc_002dmexext"></a>
+
+<div class="defun">
+— Function File:  <b>mexext</b> ()<var><a name="index-mexext-2483"></a></var><br>
+<blockquote><p>Return the filename extension used for MEX files. 
+</p></blockquote></div>
+
+   <p>One important difference between the use of mex with other products and
+with Octave is that the header file "matrix.h" is implicitly included
+through the inclusion of "mex.h".  This is to avoid a conflict with the
+Octave file "Matrix.h" with operating systems and compilers that don't
+distinguish between filenames in upper and lower case
+
+   <p>Consider the short example
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+     	     const mxArray *prhs[])
+     {
+       mxArray *v = mxCreateDoubleMatrix (1, 1, mxREAL);
+       double *data = mxGetPr (v);
+       *data = 1.23456789;
+       plhs[0] = v;
+     }
+</pre>
+</pre>
+   <p>This simple example demonstrates the basics of writing a mex-file.  The
+entry point into the mex-file is defined by <code>mexFunction</code>.  Note
+that the function name is not explicitly included in the
+<code>mexFunction</code> and so there can only be a single <code>mexFunction</code>
+entry point per-file.  Also the name of the function is determined by the
+name of the mex-file itself.  Therefore if the above function is in the
+file <samp><span class="file">firstmexdemo.c</span></samp>, it can be compiled with
+
+<pre class="example">     mkoctfile --mex firstmexdemo.c
+</pre>
+   <p class="noindent">which creates a file <samp><span class="file">firstmexdemo.mex</span></samp>.  The function can then be run
+from Octave as
+
+<pre class="example">     firstmexdemo()
+      1.2346
+</pre>
+   <p>It should be noted that the mex-file contains no help string for the
+functions it contains.  To document mex-files, there should exist an
+m-file in the same directory as the mex-file itself.  Taking the above as
+an example, we would therefore have a file <samp><span class="file">firstmexdemo.m</span></samp> that might
+contain the text
+
+<pre class="example">     %FIRSTMEXDEMO Simple test of the functionality of a mex-file.
+</pre>
+   <p>In this case, the function that will be executed within Octave will be
+given by the mex-file, while the help string will come from the
+m-file.  This can also be useful to allow a sample implementation of the
+mex-file within the Octave language itself for testing purposes.
+
+   <p>Although we cannot have multiple entry points into a single mex-file,
+we can use the <code>mexFunctionName</code> function to determine what name
+the mex-file was called with.  This can be used to alter the behavior of
+the mex-file based on the function name.  For example if
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+     	     const mxArray *prhs[])
+     {
+       const char *nm;
+       nm = mexFunctionName ();
+       mexPrintf ("You called function: %s\n", nm);
+       if (strcmp (nm, "myfunc") == 0)
+         mexPrintf ("This is the principal function\n", nm);
+       return; 
+     }
+</pre>
+</pre>
+   <p class="noindent">is in file <samp><span class="file">myfunc.c</span></samp>, and it is compiled with
+
+<pre class="example">     mkoctfile --mex myfunc.c
+     ln -s myfunc.mex myfunc2.mex
+</pre>
+   <p>Then as can be seen by
+
+<pre class="example">     myfunc()
+      You called function: myfunc
+         This is the principal function
+     myfunc2()
+      You called function: myfunc2
+</pre>
+   <p class="noindent">the behavior of the mex-file can be altered depending on the functions
+name.
+
+   <p>Allow the user should only include <code>mex.h</code> in their code, Octave
+declares additional functions, typedefs, etc., available to the user to
+write mex-files in the headers <code>mexproto.h</code> and <code>mxarray.h</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Getting-Started-with-Oct_002dFiles.html b/doc/interpreter/HTML/Getting-Started-with-Oct_002dFiles.html
new file mode 100644
index 0000000..52c892a
--- /dev/null
+++ b/doc/interpreter/HTML/Getting-Started-with-Oct_002dFiles.html
@@ -0,0 +1,182 @@
+<html lang="en">
+<head>
+<title>Getting Started with Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="next" href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles" title="Matrices and Arrays in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Getting-Started-with-Oct-Files"></a>
+<a name="Getting-Started-with-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.1 Getting Started with Oct-Files</h4>
+
+<p>The basic command to build oct-files is <code>mkoctfile</code> and it can be
+call from within octave or from the command line.
+
+<!-- ./miscellaneous/mkoctfile.m -->
+   <p><a name="doc_002dmkoctfile"></a>
+
+<div class="defun">
+— Function File:  <b>mkoctfile</b> [<var>-options</var>]<var> file <small class="dots">...</small><a name="index-mkoctfile-2472"></a></var><br>
+<blockquote>
+        <p>The <code>mkoctfile</code> function compiles source code written in C,
+C++, or Fortran.  Depending on the options used with <code>mkoctfile</code>, the
+compiled code can be called within Octave or can be used as a stand-alone
+application.
+
+        <p><code>mkoctfile</code> can be called from the shell prompt or from the Octave
+prompt.
+
+        <p><code>mkoctfile</code> accepts the following options, all of which are optional
+except for the file name of the code you wish to compile:
+
+          <dl>
+<dt>‘<samp><span class="samp">-I DIR</span></samp>’<dd>Add the include directory DIR to compile commands.
+
+          <br><dt>‘<samp><span class="samp">-D DEF</span></samp>’<dd>Add the definition DEF to the compiler call.
+
+          <br><dt>‘<samp><span class="samp">-l LIB</span></samp>’<dd>Add the library LIB to the link command.
+
+          <br><dt>‘<samp><span class="samp">-L DIR</span></samp>’<dd>Add the library directory DIR to the link command.
+
+          <br><dt>‘<samp><span class="samp">-M</span></samp>’<dt>‘<samp><span class="samp">--depend</span></samp>’<dd>Generate dependency files (.d) for C and C++ source files.
+
+          <br><dt>‘<samp><span class="samp">-c</span></samp>’<dd>Compile but do not link.
+
+          <br><dt>‘<samp><span class="samp">-g</span></samp>’<dd>Enable debugging options for compilers.
+
+          <br><dt>‘<samp><span class="samp">-o FILE</span></samp>’<dt>‘<samp><span class="samp">--output FILE</span></samp>’<dd>Output file name.  Default extension is .oct
+(or .mex if –mex is specified) unless linking
+a stand-alone executable.
+
+          <br><dt>‘<samp><span class="samp">-p VAR</span></samp>’<dt>‘<samp><span class="samp">--print VAR</span></samp>’<dd>Print the configuration variable VAR.  Recognized variables are:
+
+          <pre class="example">                  ALL_CFLAGS                FFTW_LIBS
+                  ALL_CXXFLAGS              FLIBS
+                  ALL_FFLAGS                FPICFLAG
+                  ALL_LDFLAGS               INCFLAGS
+                  BLAS_LIBS                 LDFLAGS
+                  CC                        LD_CXX
+                  CFLAGS                    LD_STATIC_FLAG
+                  CPICFLAG                  LFLAGS
+                  CPPFLAGS                  LIBCRUFT
+                  CXX                       LIBOCTAVE
+                  CXXFLAGS                  LIBOCTINTERP
+                  CXXPICFLAG                LIBREADLINE
+                  DEPEND_EXTRA_SED_PATTERN  LIBS
+                  DEPEND_FLAGS              OCTAVE_LIBS
+                  DL_LD                     RDYNAMIC_FLAG
+                  DL_LDFLAGS                RLD_FLAG
+                  F2C                       SED
+                  F2CFLAGS                  XTRA_CFLAGS
+                  F77                       XTRA_CXXFLAGS
+                  FFLAGS
+</pre>
+          <br><dt>‘<samp><span class="samp">--link-stand-alone</span></samp>’<dd>Link a stand-alone executable file.
+
+          <br><dt>‘<samp><span class="samp">--mex</span></samp>’<dd>Assume we are creating a MEX file.  Set the default output extension
+to ".mex".
+
+          <br><dt>‘<samp><span class="samp">-s</span></samp>’<dt>‘<samp><span class="samp">--strip</span></samp>’<dd>Strip the output file.
+
+          <br><dt>‘<samp><span class="samp">-v</span></samp>’<dt>‘<samp><span class="samp">--verbose</span></samp>’<dd>Echo commands as they are executed.
+
+          <br><dt>‘<samp><span class="samp">file</span></samp>’<dd>The file to compile or link.  Recognized file types are
+
+          <pre class="example">                                 .c    C source
+                                 .cc   C++ source
+                                 .C    C++ source
+                                 .cpp  C++ source
+                                 .f    Fortran source
+                                 .F    Fortran source
+                                 .o    object file
+</pre>
+          </dl>
+        </p></blockquote></div>
+
+   <p>Consider the short example
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     
+     DEFUN_DLD (helloworld, args, nargout,
+       "Hello World Help String")
+     {
+       int nargin = args.length ();
+       octave_stdout << "Hello World has " << nargin 
+             << " input arguments and "
+             << nargout << " output arguments.\n";
+       return octave_value_list ();
+     }
+</pre>
+</pre>
+   <p>This example although short introduces the basics of writing a C++
+function that can be dynamically linked to Octave.  The easiest way to
+make available most of the definitions that might be necessary for an
+oct-file in Octave is to use the <code>#include <octave/oct.h></code>
+header.
+
+   <p>The macro that defines the entry point into the dynamically loaded
+function is <code>DEFUN_DLD</code><!-- /@w -->.  This macro takes four arguments, these being
+
+     <ol type=1 start=1>
+<li>The function name as it will be seen in Octave,
+<li>The list of arguments to the function of type <code>octave_value_list</code>,
+<li>The number of output arguments, which can and often is omitted if
+not used, and
+<li>The string that will be seen as the help text of the function.
+        </ol>
+
+   <p>The return type of functions defined with <code>DEFUN_DLD</code><!-- /@w --> is always
+<code>octave_value_list</code>.
+
+   <p>There are a couple of important considerations in the choice of function
+name.  Firstly, it must be a valid Octave function name and so must be a
+sequence of letters, digits and underscores, not starting with a
+digit.  Secondly, as Octave uses the function name to define the filename
+it attempts to find the function in, the function name in the <code>DEFUN_DLD</code><!-- /@w -->
+macro must match the filename of the oct-file.  Therefore, the above
+function should be in a file <samp><span class="file">helloworld.cc</span></samp>, and it should be
+compiled to an oct-file using the command
+
+<pre class="example">     mkoctfile helloworld.cc
+</pre>
+   <p>This will create a file called <samp><span class="file">helloworld.oct</span></samp>, that is the compiled
+version of the function.  It should be noted that it is perfectly
+acceptable to have more than one <code>DEFUN_DLD</code><!-- /@w --> function in a source
+file.  However, there must either be a symbolic link to the oct-file for
+each of the functions defined in the source code with the <code>DEFUN_DLD</code><!-- /@w -->
+macro or the autoload (<a href="Function-Files.html#Function-Files">Function Files</a>) function should be used.
+
+   <p>The rest of this function then shows how to find the number of input
+arguments, how to print through the octave pager, and return from the
+function.  After compiling this function as above, an example of its use
+is
+
+<pre class="example">     helloworld (1, 2, 3)
+     -| Hello World has 3 input arguments and 0 output arguments.
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Getting-Started.html b/doc/interpreter/HTML/Getting-Started.html
new file mode 100644
index 0000000..e8bc553
--- /dev/null
+++ b/doc/interpreter/HTML/Getting-Started.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Getting Started - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Introduction.html#Introduction" title="Introduction">
+<link rel="next" href="Data-Types.html#Data-Types" title="Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Getting-Started"></a>
+Next: <a rel="next" accesskey="n" href="Data-Types.html#Data-Types">Data Types</a>,
+Previous: <a rel="previous" accesskey="p" href="Introduction.html#Introduction">Introduction</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">2 Getting Started</h2>
+
+<p>This chapter explains some of Octave's basic features, including how to
+start an Octave session, get help at the command prompt, edit the
+command line, and write Octave programs that can be executed as commands
+from your shell.
+
+<ul class="menu">
+<li><a accesskey="1" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">Invoking Octave from the Command Line</a>
+<li><a accesskey="2" href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a>
+<li><a accesskey="3" href="Getting-Help.html#Getting-Help">Getting Help</a>
+<li><a accesskey="4" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<li><a accesskey="5" href="Errors.html#Errors">Errors</a>
+<li><a accesskey="6" href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a>
+<li><a accesskey="7" href="Comments.html#Comments">Comments</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Global-Variables.html b/doc/interpreter/HTML/Global-Variables.html
new file mode 100644
index 0000000..45a3db9
--- /dev/null
+++ b/doc/interpreter/HTML/Global-Variables.html
@@ -0,0 +1,110 @@
+<html lang="en">
+<head>
+<title>Global Variables - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Variables.html#Variables" title="Variables">
+<link rel="next" href="Persistent-Variables.html#Persistent-Variables" title="Persistent Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Global-Variables"></a>
+Next: <a rel="next" accesskey="n" href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a>,
+Up: <a rel="up" accesskey="u" href="Variables.html#Variables">Variables</a>
+<hr>
+</div>
+
+<h3 class="section">7.1 Global Variables</h3>
+
+<p><a name="index-global-variables-423"></a><a name="index-g_t_0040code_007bglobal_007d-statement-424"></a><a name="index-variables_002c-global-425"></a>
+A variable that has been declared <dfn>global</dfn> may be accessed from
+within a function body without having to pass it as a formal parameter.
+
+   <p>A variable may be declared global using a <code>global</code> declaration
+statement.  The following statements are all global declarations.
+
+<pre class="example">     global a
+     global a b
+     global c = 2
+     global d = 3 e f = 5
+</pre>
+   <p>A global variable may only be initialized once in a <code>global</code>
+statement.  For example, after executing the following code
+
+<pre class="example">     global gvar = 1
+     global gvar = 2
+</pre>
+   <p class="noindent">the value of the global variable <code>gvar</code> is 1, not 2.  Issuing a
+‘<samp><span class="samp">clear gvar</span></samp>’ command does not change the above behavior, but
+‘<samp><span class="samp">clear all</span></samp>’ does.
+
+   <p>It is necessary declare a variable as global within a function body in
+order to access it.  For example,
+
+<pre class="example">     global x
+     function f ()
+       x = 1;
+     endfunction
+     f ()
+</pre>
+   <p class="noindent">does <em>not</em> set the value of the global variable <code>x</code> to 1.  In
+order to change the value of the global variable <code>x</code>, you must also
+declare it to be global within the function body, like this
+
+<pre class="example">     function f ()
+       global x;
+       x = 1;
+     endfunction
+</pre>
+   <p>Passing a global variable in a function parameter list will
+make a local copy and not modify the global value.  For example, given
+the function
+
+<pre class="example">     function f (x)
+       x = 0
+     endfunction
+</pre>
+   <p class="noindent">and the definition of <code>x</code> as a global variable at the top level,
+
+<pre class="example">     global x = 13
+</pre>
+   <p class="noindent">the expression
+
+<pre class="example">     f (x)
+</pre>
+   <p class="noindent">will display the value of <code>x</code> from inside the function as 0,
+but the value of <code>x</code> at the top level remains unchanged, because
+the function works with a <em>copy</em> of its argument.
+
+<!-- variables.cc -->
+   <p><a name="doc_002disglobal"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isglobal</b> (<var>name</var>)<var><a name="index-isglobal-426"></a></var><br>
+<blockquote><p>Return 1 if <var>name</var> is globally visible.  Otherwise, return 0.  For
+example,
+
+     <pre class="example">          global x
+          isglobal ("x")
+                1
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Graphics-Object-Properties.html b/doc/interpreter/HTML/Graphics-Object-Properties.html
new file mode 100644
index 0000000..341e6b8
--- /dev/null
+++ b/doc/interpreter/HTML/Graphics-Object-Properties.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Graphics Object Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Graphics-Objects.html#Graphics-Objects" title="Graphics Objects">
+<link rel="next" href="Managing-Default-Properties.html#Managing-Default-Properties" title="Managing Default Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Graphics-Object-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Managing-Default-Properties.html#Managing-Default-Properties">Managing Default Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.2 Graphics Object Properties</h4>
+
+<p><a name="index-graphics-object-properties-1189"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Root-Figure-Properties.html#Root-Figure-Properties">Root Figure Properties</a>
+<li><a accesskey="2" href="Figure-Properties.html#Figure-Properties">Figure Properties</a>
+<li><a accesskey="3" href="Axes-Properties.html#Axes-Properties">Axes Properties</a>
+<li><a accesskey="4" href="Line-Properties.html#Line-Properties">Line Properties</a>
+<li><a accesskey="5" href="Text-Properties.html#Text-Properties">Text Properties</a>
+<li><a accesskey="6" href="Image-Properties.html#Image-Properties">Image Properties</a>
+<li><a accesskey="7" href="Patch-Properties.html#Patch-Properties">Patch Properties</a>
+<li><a accesskey="8" href="Surface-Properties.html#Surface-Properties">Surface Properties</a>
+<li><a accesskey="9" href="Searching-Properties.html#Searching-Properties">Searching Properties</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Graphics-Objects.html b/doc/interpreter/HTML/Graphics-Objects.html
new file mode 100644
index 0000000..c986b22
--- /dev/null
+++ b/doc/interpreter/HTML/Graphics-Objects.html
@@ -0,0 +1,550 @@
+<html lang="en">
+<head>
+<title>Graphics Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="next" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Graphics-Objects"></a>
+Next: <a rel="next" accesskey="n" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.1 Graphics Objects</h4>
+
+<p>Plots in Octave are constructed from the following <dfn>graphics
+objects</dfn>.  Each graphics object has a set of properties that define its
+appearance and may also contain links to other graphics objects. 
+Graphics objects are only referenced by a numeric index, or <dfn>handle</dfn>.
+
+     <dl>
+<dt>root figure<dd><a name="index-root-figure-graphics-object-1110"></a><a name="index-graphics-object_002c-root-figure-1111"></a>The parent of all figure objects.  The index for the root figure is
+defined to be 0.
+
+     <br><dt>figure<dd><a name="index-figure-graphics-object-1112"></a><a name="index-graphics-object_002c-figure-1113"></a>A figure window.
+
+     <br><dt>axes<dd><a name="index-axes-graphics-object-1114"></a><a name="index-graphics-object_002c-axes-1115"></a>A set of axes.  This object is a child of a figure object and may be a
+parent of line, text, image, patch, or surface objects.
+
+     <br><dt>line<dd><a name="index-line-graphics-object-1116"></a><a name="index-graphics-object_002c-line-1117"></a>A line in two or three dimensions.
+
+     <br><dt>text<dd><a name="index-text-graphics-object-1118"></a><a name="index-graphics-object_002c-text-1119"></a>Text annotations.
+
+     <br><dt>image<dd><a name="index-image-graphics-object-1120"></a><a name="index-graphics-object_002c-image-1121"></a>A bitmap image.
+
+     <br><dt>patch<dd><a name="index-patch-graphics-object-1122"></a><a name="index-graphics-object_002c-patch-1123"></a>A filled polygon, currently limited to two dimensions.
+
+     <br><dt>surface<dd><a name="index-surface-graphics-object-1124"></a><a name="index-graphics-object_002c-surface-1125"></a>A three-dimensional surface. 
+</dl>
+
+   <p>To determine whether a variable is a graphics object index or a figure
+index, use the functions <code>ishandle</code> and <code>isfigure</code>.
+
+<!-- graphics.cc -->
+   <p><a name="doc_002dishandle"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ishandle</b> (<var>h</var>)<var><a name="index-ishandle-1126"></a></var><br>
+<blockquote><p>Return true if <var>h</var> is a graphics handle and false otherwise. 
+</p></blockquote></div>
+
+<!-- ./plot/ishghandle.m -->
+   <p><a name="doc_002dishghandle"></a>
+
+<div class="defun">
+— Function File:  <b>ishghandle</b> (<var>h</var>)<var><a name="index-ishghandle-1127"></a></var><br>
+<blockquote><p>Return true if <var>h</var> is a graphics handle and false otherwise. 
+</p></blockquote></div>
+
+<!-- ./plot/isfigure.m -->
+   <p><a name="doc_002disfigure"></a>
+
+<div class="defun">
+— Function File:  <b>isfigure</b> (<var>h</var>)<var><a name="index-isfigure-1128"></a></var><br>
+<blockquote><p>Return true if <var>h</var> is a graphics handle that contains a figure
+object and false otherwise. 
+</p></blockquote></div>
+
+   <p>The function <code>gcf</code> returns an index to the current figure object,
+or creates one if none exists.  Similarly, <code>gca</code> returns the
+current axes object, or creates one (and its parent figure object) if
+none exists.
+
+<!-- ./plot/gcf.m -->
+   <p><a name="doc_002dgcf"></a>
+
+<div class="defun">
+— Function File:  <b>gcf</b> ()<var><a name="index-gcf-1129"></a></var><br>
+<blockquote><p>Return the current figure handle.  If a figure does not exist, create
+one and return its handle.  The handle may then be used to examine or
+set properties of the figure.  For example,
+
+     <pre class="example">          fplot (@sin, [-10, 10]);
+          fig = gcf ();
+          set (fig, "visible", "off");
+</pre>
+        <p class="noindent">plots a sine wave, finds the handle of the current figure, and then
+makes that figure invisible.  Setting the visible property of the
+figure to <code>"on"</code> will cause it to be displayed again. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dset.html#doc_002dset">set</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/gca.m -->
+   <p><a name="doc_002dgca"></a>
+
+<div class="defun">
+— Function File:  <b>gca</b> ()<var><a name="index-gca-1130"></a></var><br>
+<blockquote><p>Return a handle to the current axis object.  If no axis object
+exists, create one and return its handle.  The handle may then be
+used to examine or set properties of the axes.  For example,
+
+     <pre class="example">          ax = gca ();
+          set (ax, "position", [0.5, 0.5, 0.5, 0.5]);
+</pre>
+        <p class="noindent">creates an empty axes object, then changes its location and size in
+the figure window. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dset.html#doc_002dset">set</a>. 
+</p></blockquote></div>
+
+   <p>The <code>get</code> and <code>set</code> functions may be used to examine and set
+properties for graphics objects.  For example,
+
+<pre class="example">     get (0)
+          ans =
+            {
+              type = root
+              currentfigure = [](0x0)
+              children = [](0x0)
+              visible = on
+     			...
+            }
+</pre>
+   <p class="noindent">returns a structure containing all the properties of the root figure. 
+As with all functions in Octave, the structure is returned by value, so
+modifying it will not modify the internal root figure plot object.  To
+do that, you must use the <code>set</code> function.  Also, note that in this
+case, the <code>currentfigure</code> property is empty, which indicates that
+there is no current figure window.
+
+   <p>The <code>get</code> function may also be used to find the value of a single
+property.  For example,
+
+<pre class="example">     get (gca (), "xlim")
+          [ 0 1 ]
+</pre>
+   <p class="noindent">returns the range of the x-axis for the current axes object in the
+current figure.
+
+   <p>To set graphics object properties, use the set function.  For example,
+
+<pre class="example">     set (gca (), "xlim", [-10, 10]);
+</pre>
+   <p class="noindent">sets the range of the x-axis for the current axes object in the current
+figure to ‘<samp><span class="samp">[-10, 10]</span></samp>’.  Additionally, calling set with a graphics
+object index as the only argument returns a structure containing the
+default values for all the properties for the given object type.  For
+example,
+
+<pre class="example">     set (gca ())
+</pre>
+   <p class="noindent">returns a structure containing the default property values for axes
+objects.
+
+<!-- graphics.cc -->
+   <p><a name="doc_002dget"></a>
+
+<div class="defun">
+— Built-in Function:  <b>get</b> (<var>h, p</var>)<var><a name="index-get-1131"></a></var><br>
+<blockquote><p>Return the named property <var>p</var> from the graphics handle <var>h</var>. 
+If <var>p</var> is omitted, return the complete property list for <var>h</var>. 
+If <var>h</var> is a vector, return a cell array including the property
+values or lists respectively. 
+</p></blockquote></div>
+
+<!-- graphics.cc -->
+   <p><a name="doc_002dset"></a>
+
+<div class="defun">
+— Built-in Function:  <b>set</b> (<var>h, p, v, <small class="dots">...</small></var>)<var><a name="index-set-1132"></a></var><br>
+<blockquote><p>Set the named property value or vector <var>p</var> to the value <var>v</var>
+for the graphics handle <var>h</var>. 
+</p></blockquote></div>
+
+<!-- ./plot/ancestor.m -->
+   <p><a name="doc_002dancestor"></a>
+
+<div class="defun">
+— Function File: <var>parent</var> = <b>ancestor</b> (<var>h, type</var>)<var><a name="index-ancestor-1133"></a></var><br>
+— Function File: <var>parent</var> = <b>ancestor</b> (<var>h, type, 'toplevel'</var>)<var><a name="index-ancestor-1134"></a></var><br>
+<blockquote><p>Return the first ancestor of handle object <var>h</var> whose type matches
+<var>type</var>, where <var>type</var> is a character string.  If <var>type</var> is a
+cell array of strings, return the first parent whose type matches
+any of the given type strings.
+
+        <p>If the handle object <var>h</var> is of type <var>type</var>, return <var>h</var>.
+
+        <p>If <code>"toplevel"</code> is given as a 3rd argument, return the highest
+parent in the object hierarchy that matches the condition, instead
+of the first (nearest) one. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dset.html#doc_002dset">set</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/allchild.m -->
+   <p><a name="doc_002dallchild"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>allchild</b> (<var>handles</var>)<var><a name="index-allchild-1135"></a></var><br>
+<blockquote><p>Find all children, including hidden children, of a graphics object.
+
+        <p>This function is similar to <code>get (h, "children")</code>, but also
+returns includes hidden objects.  If <var>handles</var> is a scalar,
+<var>h</var> will be a vector.  Otherwise, <var>h</var> will be a cell matrix
+of the same size as <var>handles</var> and each cell will contain a
+vector of handles. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dset.html#doc_002dset">set</a>, <a href="doc_002dfindall.html#doc_002dfindall">findall</a>, <a href="doc_002dfindobj.html#doc_002dfindobj">findobj</a>. 
+</p></blockquote></div>
+
+   <p>You can create axes, line, and patch objects directly using the
+<code>axes</code>, <code>line</code>, and <code>patch</code> functions.  These objects
+become children of the current axes object.
+
+<!-- ./plot/axes.m -->
+   <p><a name="doc_002daxes"></a>
+
+<div class="defun">
+— Function File:  <b>axes</b> ()<var><a name="index-axes-1136"></a></var><br>
+— Function File:  <b>axes</b> (<var>property, value, <small class="dots">...</small></var>)<var><a name="index-axes-1137"></a></var><br>
+— Function File:  <b>axes</b> (<var>h</var>)<var><a name="index-axes-1138"></a></var><br>
+<blockquote><p>Create an axes object and return a handle to it. 
+</p></blockquote></div>
+
+<!-- ./plot/line.m -->
+   <p><a name="doc_002dline"></a>
+
+<div class="defun">
+— Function File:  <b>line</b> ()<var><a name="index-line-1139"></a></var><br>
+— Function File:  <b>line</b> (<var>x, y</var>)<var><a name="index-line-1140"></a></var><br>
+— Function File:  <b>line</b> (<var>x, y, z</var>)<var><a name="index-line-1141"></a></var><br>
+— Function File:  <b>line</b> (<var>x, y, z, property, value, <small class="dots">...</small></var>)<var><a name="index-line-1142"></a></var><br>
+<blockquote><p>Create line object from <var>x</var> and <var>y</var> and insert in current
+axes object.  Return a handle (or vector of handles) to the line
+objects created.
+
+        <p>Multiple property-value pairs may be specified for the line, but they
+must appear in pairs. 
+</p></blockquote></div>
+
+<!-- ./plot/patch.m -->
+   <p><a name="doc_002dpatch"></a>
+
+<div class="defun">
+— Function File:  <b>patch</b> ()<var><a name="index-patch-1143"></a></var><br>
+— Function File:  <b>patch</b> (<var>x, y, c</var>)<var><a name="index-patch-1144"></a></var><br>
+— Function File:  <b>patch</b> (<var>x, y, z, c</var>)<var><a name="index-patch-1145"></a></var><br>
+— Function File:  <b>patch</b> (<var>fv</var>)<var><a name="index-patch-1146"></a></var><br>
+— Function File:  <b>patch</b> (<var>'Faces', f, 'Vertices', v, <small class="dots">...</small></var>)<var><a name="index-patch-1147"></a></var><br>
+— Function File:  <b>patch</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-patch-1148"></a></var><br>
+— Function File:  <b>patch</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-patch-1149"></a></var><br>
+— Function File: <var>h</var> = <b>patch</b> (<var><small class="dots">...</small></var>)<var><a name="index-patch-1150"></a></var><br>
+<blockquote><p>Create patch object from <var>x</var> and <var>y</var> with color <var>c</var> and
+insert in the current axes object.  Return handle to patch object.
+
+        <p>For a uniform colored patch, <var>c</var> can be given as an RGB vector,
+scalar value referring to the current colormap, or string value (for
+example, "r" or "red").
+
+        <p>If passed a structure <var>fv</var> contain the fields "vertices", "faces"
+and optionally "facevertexcdata", create the patch based on these
+properties. 
+</p></blockquote></div>
+
+<!-- ./plot/fill.m -->
+   <p><a name="doc_002dfill"></a>
+
+<div class="defun">
+— Function File:  <b>fill</b> (<var>x, y, c</var>)<var><a name="index-fill-1151"></a></var><br>
+— Function File:  <b>fill</b> (<var>x1, y1, c1, x2, y2, c2</var>)<var><a name="index-fill-1152"></a></var><br>
+— Function File:  <b>fill</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-fill-1153"></a></var><br>
+— Function File:  <b>fill</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-fill-1154"></a></var><br>
+— Function File: <var>h</var> = <b>fill</b> (<var><small class="dots">...</small></var>)<var><a name="index-fill-1155"></a></var><br>
+<blockquote><p>Create one or more filled patch objects, returning a patch object for each. 
+</p></blockquote></div>
+
+<!-- ./plot/surface.m -->
+   <p><a name="doc_002dsurface"></a>
+
+<div class="defun">
+— Function File:  <b>surface</b> (<var>x, y, z, c</var>)<var><a name="index-surface-1156"></a></var><br>
+— Function File:  <b>surface</b> (<var>x, y, z</var>)<var><a name="index-surface-1157"></a></var><br>
+— Function File:  <b>surface</b> (<var>z, c</var>)<var><a name="index-surface-1158"></a></var><br>
+— Function File:  <b>surface</b> (<var>z</var>)<var><a name="index-surface-1159"></a></var><br>
+— Function File:  <b>surface</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-surface-1160"></a></var><br>
+— Function File:  <b>surface</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-surface-1161"></a></var><br>
+— Function File: <var>h</var> = <b>surface</b> (<var><small class="dots">...</small></var>)<var><a name="index-surface-1162"></a></var><br>
+<blockquote><p>Plot a surface graphic object given matrices <var>x</var>, and <var>y</var> from
+<code>meshgrid</code> and a matrix <var>z</var> corresponding to the <var>x</var> and
+<var>y</var> coordinates of the surface.  If <var>x</var> and <var>y</var> are vectors,
+then a typical vertex is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus,
+columns of <var>z</var> correspond to different <var>x</var> values and rows of
+<var>z</var> correspond to different <var>y</var> values.  If <var>x</var> and <var>y</var>
+are missing, they are constructed from size of the matrix <var>z</var>.
+
+        <p>Any additional properties passed are assigned to the surface. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsurf.html#doc_002dsurf">surf</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>, <a href="doc_002dline.html#doc_002dline">line</a>. 
+</p></blockquote></div>
+
+   <p>By default, Octave refreshes the plot window when a prompt is printed,
+or when waiting for input.  To force an update at other times, call the
+<code>drawnow</code> function.
+
+<!-- graphics.cc -->
+   <p><a name="doc_002ddrawnow"></a>
+
+<div class="defun">
+— Built-in Function:  <b>drawnow</b> ()<var><a name="index-drawnow-1163"></a></var><br>
+— Built-in Function:  <b>drawnow</b> (<var>"expose"</var>)<var><a name="index-drawnow-1164"></a></var><br>
+— Built-in Function:  <b>drawnow</b> (<var>term, file, mono, debug_file</var>)<var><a name="index-drawnow-1165"></a></var><br>
+<blockquote><p>Update figure windows and their children.  The event queue is flushed and
+any callbacks generated are executed.  With the optional argument
+<code>"expose"</code>, only graphic objects are updated and no other events or
+callbacks are processed. 
+The third calling form of <code>drawnow</code> is for debugging and is
+undocumented. 
+</p></blockquote></div>
+
+   <p>Only figures that are modified will be updated.  The <code>refresh</code>
+function can also be used to force an update of the current figure, even if
+it is not modified.
+
+<!-- ./plot/refresh.m -->
+   <p><a name="doc_002drefresh"></a>
+
+<div class="defun">
+— Function File:  <b>refresh</b> ()<var><a name="index-refresh-1166"></a></var><br>
+— Function File:  <b>refresh</b> (<var>h</var>)<var><a name="index-refresh-1167"></a></var><br>
+<blockquote><p>Refresh a figure, forcing it to be redrawn.  Called without an
+argument the current figure is redrawn, otherwise the figure pointed
+to by <var>h</var> is redrawn. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddrawnow.html#doc_002ddrawnow">drawnow</a>. 
+</p></blockquote></div>
+
+   <p>Normally, high-level plot functions like <code>plot</code> or <code>mesh</code> call
+<code>newplot</code> to initialize the state of the current axes so that the
+next plot is drawn in a blank window with default property settings.  To
+have two plots superimposed over one another, use the <code>hold</code>
+function.  For example,
+
+<pre class="example">     hold on;
+     x = -10:0.1:10;
+     plot (x, sin (x));
+     plot (x, cos (x));
+     hold off;
+</pre>
+   <p class="noindent">displays sine and cosine waves on the same axes.  If the hold state is
+off, consecutive plotting commands like this will only display the last
+plot.
+
+<!-- ./plot/newplot.m -->
+   <p><a name="doc_002dnewplot"></a>
+
+<div class="defun">
+— Function File:  <b>newplot</b> ()<var><a name="index-newplot-1168"></a></var><br>
+<blockquote><p>Prepare graphics engine to produce a new plot.  This function should
+be called at the beginning of all high-level plotting functions. 
+</p></blockquote></div>
+
+<!-- ./plot/hold.m -->
+   <p><a name="doc_002dhold"></a>
+
+<div class="defun">
+— Function File:  <b>hold</b><var><a name="index-hold-1169"></a></var><br>
+— Function File:  <b>hold</b><var> state<a name="index-hold-1170"></a></var><br>
+— Function File:  <b>hold</b> (<var>hax, <small class="dots">...</small></var>)<var><a name="index-hold-1171"></a></var><br>
+<blockquote><p>Toggle or set the 'hold' state of the plotting engine which determines
+whether new graphic objects are added to the plot or replace the existing
+objects.
+
+          <dl>
+<dt><code>hold on</code><dd>Retain plot data and settings so that subsequent plot commands are displayed
+on a single graph.
+
+          <br><dt><code>hold off</code><dd>Clear plot and restore default graphics settings before each new plot
+command.  (default).
+
+          <br><dt><code>hold</code><dd>Toggle the current 'hold' state. 
+</dl>
+
+        <p>When given the additional argument <var>hax</var>, the hold state is modified
+only for the given axis handle.
+
+        <p>To query the current 'hold' state use the <code>ishold</code> function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dishold.html#doc_002dishold">ishold</a>, <a href="doc_002dcla.html#doc_002dcla">cla</a>, <a href="doc_002dnewplot.html#doc_002dnewplot">newplot</a>, <a href="doc_002dclf.html#doc_002dclf">clf</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ishold.m -->
+   <p><a name="doc_002dishold"></a>
+
+<div class="defun">
+— Function File:  <b>ishold</b><var><a name="index-ishold-1172"></a></var><br>
+<blockquote><p>Return true if the next line will be added to the current plot, or
+false if the plot device will be cleared before drawing the next line. 
+</p></blockquote></div>
+
+   <p>To clear the current figure, call the <code>clf</code> function.  To clear the
+current axis, call the <code>cla</code> function.  To bring the current figure
+to the top of the window stack, call the <code>shg</code> function.  To delete
+a graphics object, call <code>delete</code> on its index.  To close the
+figure window, call the <code>close</code> function.
+
+<!-- ./plot/clf.m -->
+   <p><a name="doc_002dclf"></a>
+
+<div class="defun">
+— Function File:  <b>clf</b> ()<var><a name="index-clf-1173"></a></var><br>
+— Function File:  <b>clf</b> (<var>"reset"</var>)<var><a name="index-clf-1174"></a></var><br>
+— Function File:  <b>clf</b> (<var>hfig</var>)<var><a name="index-clf-1175"></a></var><br>
+— Function File:  <b>clf</b> (<var>hfig, "reset"</var>)<var><a name="index-clf-1176"></a></var><br>
+<blockquote><p>Clear the current figure window.  <code>clf</code> operates by deleting child
+graphics objects with visible handles (<code>HandleVisibility</code> = on). 
+If <var>hfig</var> is specified operate on it instead of the current figure. 
+If the optional argument <code>"reset"</code> is specified, all objects including
+those with hidden handles are deleted. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcla.html#doc_002dcla">cla</a>, <a href="doc_002dclose.html#doc_002dclose">close</a>, <a href="doc_002ddelete.html#doc_002ddelete">delete</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/cla.m -->
+   <p><a name="doc_002dcla"></a>
+
+<div class="defun">
+— Function File:  <b>cla</b> ()<var><a name="index-cla-1177"></a></var><br>
+— Function File:  <b>cla</b> (<var>"reset"</var>)<var><a name="index-cla-1178"></a></var><br>
+— Function File:  <b>cla</b> (<var>hax</var>)<var><a name="index-cla-1179"></a></var><br>
+— Function File:  <b>cla</b> (<var>hax, "reset"</var>)<var><a name="index-cla-1180"></a></var><br>
+<blockquote><p>Delete the children of the current axes with visible handles. 
+If <var>hax</var> is specified and is an axes object handle, operate on it
+instead of the current axes.  If the optional argument <code>"reset"</code>
+is specified, also delete the children with hidden handles. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclf.html#doc_002dclf">clf</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/shg.m -->
+   <p><a name="doc_002dshg"></a>
+
+<div class="defun">
+— Function File:  <b>shg</b><var><a name="index-shg-1181"></a></var><br>
+<blockquote><p>Show the graph window.  Currently, this is the same as executing
+<code>drawnow</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddrawnow.html#doc_002ddrawnow">drawnow</a>, <a href="doc_002dfigure.html#doc_002dfigure">figure</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/delete.m -->
+   <p><a name="doc_002ddelete"></a>
+
+<div class="defun">
+— Function File:  <b>delete</b> (<var>file</var>)<var><a name="index-delete-1182"></a></var><br>
+— Function File:  <b>delete</b> (<var>handle</var>)<var><a name="index-delete-1183"></a></var><br>
+<blockquote><p>Delete the named file or graphics handle.
+
+        <p>Deleting graphics objects is the proper way to remove
+features from a plot without clearing the entire figure. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclf.html#doc_002dclf">clf</a>, <a href="doc_002dcla.html#doc_002dcla">cla</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/close.m -->
+   <p><a name="doc_002dclose"></a>
+
+<div class="defun">
+— Command:  <b>close</b><var><a name="index-close-1184"></a></var><br>
+— Command:  <b>close</b> (<var>n</var>)<var><a name="index-close-1185"></a></var><br>
+— Command:  <b>close</b><var> all<a name="index-close-1186"></a></var><br>
+— Command:  <b>close</b><var> all hidden<a name="index-close-1187"></a></var><br>
+<blockquote><p>Close figure window(s) by calling the function specified by the
+<code>"closerequestfcn"</code> property for each figure.  By default, the
+function <code>closereq</code> is used. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclosereq.html#doc_002dclosereq">closereq</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/closereq.m -->
+   <p><a name="doc_002dclosereq"></a>
+
+<div class="defun">
+— Function File:  <b>closereq</b> ()<var><a name="index-closereq-1188"></a></var><br>
+<blockquote><p>Close the current figure and delete all graphics objects associated
+with it. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclose.html#doc_002dclose">close</a>, <a href="doc_002ddelete.html#doc_002ddelete">delete</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Graphics-backends.html b/doc/interpreter/HTML/Graphics-backends.html
new file mode 100644
index 0000000..acc63ec
--- /dev/null
+++ b/doc/interpreter/HTML/Graphics-backends.html
@@ -0,0 +1,68 @@
+<html lang="en">
+<head>
+<title>Graphics backends - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Graphics-backends"></a>
+Previous: <a rel="previous" accesskey="p" href="Object-Groups.html#Object-Groups">Object Groups</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.9 Graphics backends</h4>
+
+<p><a name="index-graphics-backends-1252"></a><a name="index-backends_002c-graphics-1253"></a>
+<!-- ./plot/backend.m -->
+<a name="doc_002dbackend"></a>
+
+<div class="defun">
+— Function File:  <b>backend</b> (<var>name</var>)<var><a name="index-backend-1254"></a></var><br>
+— Function File:  <b>backend</b> (<var>hlist, name</var>)<var><a name="index-backend-1255"></a></var><br>
+<blockquote><p>Change the default graphics backend to <var>name</var>.  If the backend is
+not already loaded, it is first initialized (initialization is done
+through the execution of <code>__init_</code><var>name</var><code>__</code>).
+
+        <p>When called with a list of figure handles, <var>hlist</var>, the backend is
+changed only for the listed figures. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002davailable_005fbackends.html#doc_002davailable_005fbackends">available_backends</a>. 
+</p></blockquote></div>
+
+<!-- graphics.cc -->
+   <p><a name="doc_002davailable_005fbackends"></a>
+
+<div class="defun">
+— Built-in Function:  <b>available_backends</b> ()<var><a name="index-available_005fbackends-1256"></a></var><br>
+<blockquote><p>Return a cell array of registered graphics backends. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Interaction-with-gnuplot.html#Interaction-with-gnuplot">Interaction with gnuplot</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Group-Database-Functions.html b/doc/interpreter/HTML/Group-Database-Functions.html
new file mode 100644
index 0000000..fa5558f
--- /dev/null
+++ b/doc/interpreter/HTML/Group-Database-Functions.html
@@ -0,0 +1,99 @@
+<html lang="en">
+<head>
+<title>Group Database Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Password-Database-Functions.html#Password-Database-Functions" title="Password Database Functions">
+<link rel="next" href="System-Information.html#System-Information" title="System Information">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Group-Database-Functions"></a>
+Next: <a rel="next" accesskey="n" href="System-Information.html#System-Information">System Information</a>,
+Previous: <a rel="previous" accesskey="p" href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.10 Group Database Functions</h3>
+
+<p>Octave's group database functions return information in a structure
+with the following fields.
+
+     <dl>
+<dt><code>name</code><dd>The user name.
+
+     <br><dt><code>passwd</code><dd>The encrypted password, if available.
+
+     <br><dt><code>gid</code><dd>The numeric group id.
+
+     <br><dt><code>mem</code><dd>The members of the group. 
+</dl>
+
+   <p>In the descriptions of the following functions, this data structure is
+referred to as a <var>grp_struct</var>.
+
+<!-- ./DLD-FUNCTIONS/getgrent.cc -->
+   <p><a name="doc_002dgetgrent"></a>
+
+<div class="defun">
+— Loadable Function: <var>grp_struct</var> = <b>getgrent</b> ()<var><a name="index-getgrent-2437"></a></var><br>
+<blockquote><p>Return an entry from the group database, opening it if necessary. 
+Once the end of the data has been reached, <code>getgrent</code> returns 0. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getgrent.cc -->
+   <p><a name="doc_002dgetgrgid"></a>
+
+<div class="defun">
+— Loadable Function: <var>grp_struct</var> = <b>getgrgid</b> (<var>gid</var>)<var>.<a name="index-getgrgid-2438"></a></var><br>
+<blockquote><p>Return the first entry from the group database with the group ID
+<var>gid</var>.  If the group ID does not exist in the database,
+<code>getgrgid</code> returns 0. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getgrent.cc -->
+   <p><a name="doc_002dgetgrnam"></a>
+
+<div class="defun">
+— Loadable Function: <var>grp_struct</var> = <b>getgrnam</b> (<var>name</var>)<var><a name="index-getgrnam-2439"></a></var><br>
+<blockquote><p>Return the first entry from the group database with the group name
+<var>name</var>.  If the group name does not exist in the database,
+<code>getgrnam</code> returns 0. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getgrent.cc -->
+   <p><a name="doc_002dsetgrent"></a>
+
+<div class="defun">
+— Loadable Function:  <b>setgrent</b> ()<var><a name="index-setgrent-2440"></a></var><br>
+<blockquote><p>Return the internal pointer to the beginning of the group database. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getgrent.cc -->
+   <p><a name="doc_002dendgrent"></a>
+
+<div class="defun">
+— Loadable Function:  <b>endgrent</b> ()<var><a name="index-endgrent-2441"></a></var><br>
+<blockquote><p>Close the group database. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Handling-Errors.html b/doc/interpreter/HTML/Handling-Errors.html
new file mode 100644
index 0000000..1fe80e6
--- /dev/null
+++ b/doc/interpreter/HTML/Handling-Errors.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Handling Errors - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Errors-and-Warnings.html#Errors-and-Warnings" title="Errors and Warnings">
+<link rel="next" href="Handling-Warnings.html#Handling-Warnings" title="Handling Warnings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Handling-Errors"></a>
+Next: <a rel="next" accesskey="n" href="Handling-Warnings.html#Handling-Warnings">Handling Warnings</a>,
+Up: <a rel="up" accesskey="u" href="Errors-and-Warnings.html#Errors-and-Warnings">Errors and Warnings</a>
+<hr>
+</div>
+
+<h3 class="section">12.1 Handling Errors</h3>
+
+<p>An error is something that occurs when a program is in a state where
+it doesn't make sense to continue.  An example is when a function is
+called with too few input arguments.  In this situation the function
+should abort with an error message informing the user of the lacking
+input arguments.
+
+   <p>Since an error can occur during the evaluation of a program, it is
+very convenient to be able to detect that an error occurred, so that
+the error can be fixed.  This is possible with the <code>try</code> statement
+described in <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>.
+
+<ul class="menu">
+<li><a accesskey="1" href="Raising-Errors.html#Raising-Errors">Raising Errors</a>
+<li><a accesskey="2" href="Catching-Errors.html#Catching-Errors">Catching Errors</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Handling-Warnings.html b/doc/interpreter/HTML/Handling-Warnings.html
new file mode 100644
index 0000000..28a6f27
--- /dev/null
+++ b/doc/interpreter/HTML/Handling-Warnings.html
@@ -0,0 +1,51 @@
+<html lang="en">
+<head>
+<title>Handling Warnings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Errors-and-Warnings.html#Errors-and-Warnings" title="Errors and Warnings">
+<link rel="prev" href="Handling-Errors.html#Handling-Errors" title="Handling Errors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Handling-Warnings"></a>
+Previous: <a rel="previous" accesskey="p" href="Handling-Errors.html#Handling-Errors">Handling Errors</a>,
+Up: <a rel="up" accesskey="u" href="Errors-and-Warnings.html#Errors-and-Warnings">Errors and Warnings</a>
+<hr>
+</div>
+
+<h3 class="section">12.2 Handling Warnings</h3>
+
+<p>Like an error, a warning is issued when something unexpected happens. 
+Unlike an error, a warning doesn't abort the currently running program. 
+A simple example of a warning is when a number is divided by zero.  In
+this case Octave will issue a warning and assign the value <code>Inf</code>
+to the result.
+
+<pre class="example">     a = 1/0
+          -| warning: division by zero
+           a = Inf
+</pre>
+   <ul class="menu">
+<li><a accesskey="1" href="Issuing-Warnings.html#Issuing-Warnings">Issuing Warnings</a>
+<li><a accesskey="2" href="Enabling-and-Disabling-Warnings.html#Enabling-and-Disabling-Warnings">Enabling and Disabling Warnings</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Hashing-Functions.html b/doc/interpreter/HTML/Hashing-Functions.html
new file mode 100644
index 0000000..4f17c6a
--- /dev/null
+++ b/doc/interpreter/HTML/Hashing-Functions.html
@@ -0,0 +1,83 @@
+<html lang="en">
+<head>
+<title>Hashing Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="System-Information.html#System-Information" title="System Information">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Hashing-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="System-Information.html#System-Information">System Information</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.12 Hashing Functions</h3>
+
+<p>It is often necessary to find if two strings or files are
+identical.  This might be done by comparing them character by character
+and looking for differences.  However, this can be slow, and so comparing
+a hash of the string or file can be a rapid way of finding if the files
+differ.
+
+   <p>Another use of the hashing function is to check for file integrity.  The
+user can check the hash of the file against a known value and find if
+the file they have is the same as the one that the original hash was
+produced with.
+
+   <p>Octave supplies the <code>md5sum</code> function to perform MD5 hashes on
+strings and files.  An example of the use of <code>md5sum</code> function might
+be
+
+<pre class="example">     if exist (file, "file")
+       hash = md5sum (file);
+     else
+       # Treat the variable "file" as a string
+       hash = md5sum (file, true);
+     endif
+</pre>
+   <!-- ./DLD-FUNCTIONS/md5sum.cc -->
+   <p><a name="doc_002dmd5sum"></a>
+
+<div class="defun">
+— Loadable Function:  <b>md5sum</b> (<var>file</var>)<var><a name="index-md5sum-2463"></a></var><br>
+— Loadable Function:  <b>md5sum</b> (<var>str, opt</var>)<var><a name="index-md5sum-2464"></a></var><br>
+<blockquote><p>Calculates the MD5 sum of the file <var>file</var>.  If the second parameter
+<var>opt</var> exists and is true, then calculate the MD5 sum of the
+string <var>str</var>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2007, 2008, 2009 S�ren Hauberg -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/How-You-Can-Contribute-to-Octave.html b/doc/interpreter/HTML/How-You-Can-Contribute-to-Octave.html
new file mode 100644
index 0000000..79b7ff4
--- /dev/null
+++ b/doc/interpreter/HTML/How-You-Can-Contribute-to-Octave.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>How You Can Contribute to Octave - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Preface.html#Preface" title="Preface">
+<link rel="prev" href="Acknowledgements.html#Acknowledgements" title="Acknowledgements">
+<link rel="next" href="Distribution.html#Distribution" title="Distribution">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="How-You-Can-Contribute-to-Octave"></a>
+Next: <a rel="next" accesskey="n" href="Distribution.html#Distribution">Distribution</a>,
+Previous: <a rel="previous" accesskey="p" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>,
+Up: <a rel="up" accesskey="u" href="Preface.html#Preface">Preface</a>
+<hr>
+</div>
+
+<h3 class="unnumberedsec">How You Can Contribute to Octave</h3>
+
+<p><a name="index-contributing-to-Octave-4"></a><a name="index-funding-Octave-development-5"></a>
+There are a number of ways that you can contribute to help make Octave a
+better system.  Perhaps the most important way to contribute is to write
+high-quality code for solving new problems, and to make your code freely
+available for others to use.  See <a href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>, for detailed
+information on contributing new code.
+
+   <p>If you find Octave useful, consider providing additional funding to
+continue its development.  Even a modest amount of additional funding
+could make a significant difference in the amount of time that is
+available for development and support.
+
+   <p>If you cannot provide funding or contribute code, you can still help
+make Octave better and more reliable by reporting any bugs you find and
+by offering suggestions for ways to improve Octave.  See <a href="Trouble.html#Trouble">Trouble</a>, for
+tips on how to write useful bug reports.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/How-to-Contribute.html b/doc/interpreter/HTML/How-to-Contribute.html
new file mode 100644
index 0000000..b8eb507
--- /dev/null
+++ b/doc/interpreter/HTML/How-to-Contribute.html
@@ -0,0 +1,97 @@
+<html lang="en">
+<head>
+<title>How to Contribute - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link rel="next" href="General-Guidelines.html#General-Guidelines" title="General Guidelines">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="How-to-Contribute"></a>
+Next: <a rel="next" accesskey="n" href="General-Guidelines.html#General-Guidelines">General Guidelines</a>,
+Up: <a rel="up" accesskey="u" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>
+<hr>
+</div>
+
+<h3 class="section">D.1 How to Contribute</h3>
+
+<p>The mailing list for Octave development discussion and sending contributions is
+<a href="mailto:maintainers at octave.org">maintainers at octave.org</a>.  This concerns the development of Octave core,
+i.e., code that goes to Octave directly.  You may consider developing and
+publishing a package instead; a great place for this is the allied Octave-Forge
+project (<a href="http://octave.sf.net">http://octave.sf.net</a>).  Note that the Octave project is
+inherently more conservative and follows narrower rules.
+
+   <p>The preferable form of contribution is creating a Mercurial changeset and
+sending it via e-mail to the octave-maintainers mailing list.  Mercurial is the
+source code management system currently used to develop Octave.  Other forms of
+contributions (e.g., simple diff patches) are also acceptable, but they slow
+down the review process.  If you want to make more contributions, you should
+really get familiar with Mercurial.  A good place to start is
+<a href="http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial">http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial</a>.  There you will
+also find help how to install Mercurial.
+
+   <p>A simple contribution sequence could look like this:
+<pre class="example">     hg clone http://www.octave.org/hg/octave
+                                  # make a local copy of the octave
+                                  # source repository
+     cd octave
+     # change some sources...
+     hg commit -m "make Octave the coolest software ever"
+                                  # commit the changeset into your
+                                  # local repository
+     hg export -o ../cool.diff tip
+                                  # export the changeset to a diff
+                                  # file
+     # send ../cool.diff via email
+</pre>
+   <p>You may want to get familiar with Mercurial queues to manage your changesets. 
+Here is a slightly less simple example using Mercurial queues, where you work
+on two unrelated changesets in parallel and update one of the changesets after
+discussion in the maintainers mailing list:
+<pre class="example">     hg qnew nasty_bug            # create a new patch
+     # change sources...
+     hg qref                      # save the changes into the patch
+     # change even more...
+     hg qref -m "solution to nasty bug!"
+                                  # save again with commit message
+     hg export -o ../nasty.diff tip
+                                  # export the patch
+     # send ../nasty.diff via email
+     hg qpop                      # undo the application of the patch
+                                  # and remove the changes from the
+                                  # source tree
+     hg qnew doc_improvements     # create an unrelated patch
+     # change doc sources...
+     hg qref -m "could not find myfav.m in the doc"
+                                  # save the changes into the patch
+     hg export -o ../doc.diff tip
+                                  # export the second patch
+     # send ../doc.diff tip via email
+     hg qpop
+     # discussion in the maintainers mailing list ...
+     hg qpush nasty_bug           # apply the patch again
+     # change sources yet again ...
+     hg qref
+     hg export -o ../nasty2.diff tip
+     # send ../nasty2.diff via email
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Identifying-points-in-Triangulation.html b/doc/interpreter/HTML/Identifying-points-in-Triangulation.html
new file mode 100644
index 0000000..c0c3831
--- /dev/null
+++ b/doc/interpreter/HTML/Identifying-points-in-Triangulation.html
@@ -0,0 +1,197 @@
+<html lang="en">
+<head>
+<title>Identifying points in Triangulation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Delaunay-Triangulation.html#Delaunay-Triangulation" title="Delaunay Triangulation">
+<link rel="prev" href="Plotting-the-Triangulation.html#Plotting-the-Triangulation" title="Plotting the Triangulation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Identifying-points-in-Triangulation"></a>
+Previous: <a rel="previous" accesskey="p" href="Plotting-the-Triangulation.html#Plotting-the-Triangulation">Plotting the Triangulation</a>,
+Up: <a rel="up" accesskey="u" href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a>
+<hr>
+</div>
+
+<h4 class="subsection">29.1.2 Identifying points in Triangulation</h4>
+
+<p>It is often necessary to identify whether a particular point in the
+N-dimensional space is within the Delaunay tessellation of a set of
+points in this N-dimensional space, and if so which N-simplex contains
+the point and which point in the tessellation is closest to the desired
+point.  The functions <code>tsearch</code> and <code>dsearch</code> perform this
+function in a triangulation, and <code>tsearchn</code> and <code>dsearchn</code> in
+an N-dimensional tessellation.
+
+   <p>To identify whether a particular point represented by a vector <var>p</var>
+falls within one of the simplices of an N-simplex, we can write the
+Cartesian coordinates of the point in a parametric form with respect to
+the N-simplex.  This parametric form is called the Barycentric
+Coordinates of the point.  If the points defining the N-simplex are given
+by <var>N</var><code> + 1</code> vectors <var>t</var>(<var>i</var>,:), then the Barycentric
+coordinates defining the point <var>p</var> are given by
+
+<pre class="example">     <var>p</var> = sum (<var>beta</var>(1:<var>N</var>+1) * <var>t</var>(1:<var>N</var>+1),:)
+</pre>
+   <p class="noindent">where there are <var>N</var><code> + 1</code> values <var>beta</var><code>(</code><var>i</var><code>)</code>
+that together as a vector represent the Barycentric coordinates of the
+point <var>p</var>.  To ensure a unique solution for the values of
+<var>beta</var><code>(</code><var>i</var><code>)</code> an additional criteria of
+
+<pre class="example">     sum (<var>beta</var>(1:<var>N</var>+1)) == 1
+</pre>
+   <p class="noindent">is imposed, and we can therefore write the above as
+
+<pre class="example">     <var>p</var> - <var>t</var>(end, :) = <var>beta</var>(1:end-1) * (<var>t</var>(1:end-1, :)
+           - ones(<var>N</var>, 1) * <var>t</var>(end, :)
+</pre>
+   <p class="noindent">Solving for <var>beta</var> we can then write
+
+<pre class="example">     <var>beta</var>(1:end-1) = (<var>p</var> - <var>t</var>(end, :)) / (<var>t</var>(1:end-1, :)
+           - ones(<var>N</var>, 1) * <var>t</var>(end, :))
+     <var>beta</var>(end) = sum(<var>beta</var>(1:end-1))
+</pre>
+   <p class="noindent">which gives the formula for the conversion of the Cartesian coordinates
+of the point <var>p</var> to the Barycentric coordinates <var>beta</var>.  An
+important property of the Barycentric coordinates is that for all points
+in the N-simplex
+
+<pre class="example">     0 <= <var>beta</var>(<var>i</var>) <= 1
+</pre>
+   <p class="noindent">Therefore, the test in <code>tsearch</code> and <code>tsearchn</code> essentially
+only needs to express each point in terms of the Barycentric coordinates
+of each of the simplices of the N-simplex and test the values of
+<var>beta</var>.  This is exactly the implementation used in
+<code>tsearchn</code>.  <code>tsearch</code> is optimized for 2-dimensions and the
+Barycentric coordinates are not explicitly formed.
+
+<!-- ./DLD-FUNCTIONS/tsearch.cc -->
+   <p><a name="doc_002dtsearch"></a>
+
+<div class="defun">
+— Loadable Function: <var>idx</var> = <b>tsearch</b> (<var>x, y, t, xi, yi</var>)<var><a name="index-tsearch-2095"></a></var><br>
+<blockquote><p>Searches for the enclosing Delaunay convex hull.  For <var>t</var><code> =
+delaunay (</code><var>x</var><code>, </code><var>y</var><code>)</code>, finds the index in <var>t</var> containing the
+points <code>(</code><var>xi</var><code>, </code><var>yi</var><code>)</code>.  For points outside the convex hull,
+<var>idx</var> is NaN. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/tsearchn.m -->
+   <p><a name="doc_002dtsearchn"></a>
+
+<div class="defun">
+— Function File: [<var>idx</var>, <var>p</var>] = <b>tsearchn</b> (<var>x, t, xi</var>)<var><a name="index-tsearchn-2096"></a></var><br>
+<blockquote><p>Searches for the enclosing Delaunay convex hull.  For <var>t</var><code> =
+delaunayn (</code><var>x</var><code>)</code>, finds the index in <var>t</var> containing the
+points <var>xi</var>.  For points outside the convex hull, <var>idx</var> is NaN. 
+If requested <code>tsearchn</code> also returns the Barycentric coordinates <var>p</var>
+of the enclosing triangles. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+   <p>An example of the use of <code>tsearch</code> can be seen with the simple
+triangulation
+
+<pre class="example">     <var>x</var> = [-1; -1; 1; 1];
+     <var>y</var> = [-1; 1; -1; 1];
+     <var>tri</var> = [1, 2, 3; 2, 3, 1];
+</pre>
+   <p class="noindent">consisting of two triangles defined by <var>tri</var>.  We can then identify
+which triangle a point falls in like
+
+<pre class="example">     tsearch (<var>x</var>, <var>y</var>, <var>tri</var>, -0.5, -0.5)
+      1
+     tsearch (<var>x</var>, <var>y</var>, <var>tri</var>, 0.5, 0.5)
+      2
+</pre>
+   <p class="noindent">and we can confirm that a point doesn't lie within one of the triangles like
+
+<pre class="example">     tsearch (<var>x</var>, <var>y</var>, <var>tri</var>, 2, 2)
+      NaN
+</pre>
+   <p>The <code>dsearch</code> and <code>dsearchn</code> find the closest point in a
+tessellation to the desired point.  The desired point does not
+necessarily have to be in the tessellation, and even if it the returned
+point of the tessellation does not have to be one of the vertexes of the
+N-simplex within which the desired point is found.
+
+<!-- ./geometry/dsearch.m -->
+   <p><a name="doc_002ddsearch"></a>
+
+<div class="defun">
+— Function File: <var>idx</var> = <b>dsearch</b> (<var>x, y, tri, xi, yi</var>)<var><a name="index-dsearch-2097"></a></var><br>
+— Function File: <var>idx</var> = <b>dsearch</b> (<var>x, y, tri, xi, yi, s</var>)<var><a name="index-dsearch-2098"></a></var><br>
+<blockquote><p>Returns the index <var>idx</var> or the closest point in <var>x</var><code>, </code><var>y</var>
+to the elements <code>[</code><var>xi</var><code>(:), </code><var>yi</var><code>(:)]</code>.  The variable <var>s</var> is
+accepted but ignored for compatibility. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddsearchn.html#doc_002ddsearchn">dsearchn</a>, <a href="doc_002dtsearch.html#doc_002dtsearch">tsearch</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/dsearchn.m -->
+   <p><a name="doc_002ddsearchn"></a>
+
+<div class="defun">
+— Function File: <var>idx</var> = <b>dsearchn</b> (<var>x, tri, xi</var>)<var><a name="index-dsearchn-2099"></a></var><br>
+— Function File: <var>idx</var> = <b>dsearchn</b> (<var>x, tri, xi, outval</var>)<var><a name="index-dsearchn-2100"></a></var><br>
+— Function File: <var>idx</var> = <b>dsearchn</b> (<var>x, xi</var>)<var><a name="index-dsearchn-2101"></a></var><br>
+— Function File: [<var>idx</var>, <var>d</var>] = <b>dsearchn</b> (<var><small class="dots">...</small></var>)<var><a name="index-dsearchn-2102"></a></var><br>
+<blockquote><p>Returns the index <var>idx</var> or the closest point in <var>x</var> to the elements
+<var>xi</var>.  If <var>outval</var> is supplied, then the values of <var>xi</var> that are
+not contained within one of the simplicies <var>tri</var> are set to
+<var>outval</var>.  Generally, <var>tri</var> is returned from <code>delaunayn
+(</code><var>x</var><code>)</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddsearch.html#doc_002ddsearch">dsearch</a>, <a href="doc_002dtsearch.html#doc_002dtsearch">tsearch</a>. 
+</p></blockquote></div>
+
+   <p>An example of the use of <code>dsearch</code>, using the above values of
+<var>x</var>, <var>y</var> and <var>tri</var> is
+
+<pre class="example">     dsearch (<var>x</var>, <var>y</var>, <var>tri</var>, -2, -2)
+      1
+</pre>
+   <p>If you wish the points that are outside the tessellation to be flagged,
+then <code>dsearchn</code> can be used as
+
+<pre class="example">     dsearchn ([<var>x</var>, <var>y</var>], <var>tri</var>, [-2, -2], NaN)
+      NaN
+     dsearchn ([<var>x</var>, <var>y</var>], <var>tri</var>, [-0.5, -0.5], NaN)
+      1
+</pre>
+   <p class="noindent">where the point outside the tessellation are then flagged with <code>NaN</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Image-Processing.html b/doc/interpreter/HTML/Image-Processing.html
new file mode 100644
index 0000000..1d2a1b2
--- /dev/null
+++ b/doc/interpreter/HTML/Image-Processing.html
@@ -0,0 +1,58 @@
+<html lang="en">
+<head>
+<title>Image Processing - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Signal-Processing.html#Signal-Processing" title="Signal Processing">
+<link rel="next" href="Audio-Processing.html#Audio-Processing" title="Audio Processing">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Image-Processing"></a>
+Next: <a rel="next" accesskey="n" href="Audio-Processing.html#Audio-Processing">Audio Processing</a>,
+Previous: <a rel="previous" accesskey="p" href="Signal-Processing.html#Signal-Processing">Signal Processing</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">31 Image Processing</h2>
+
+<p>Since an image basically is a matrix Octave is a very powerful
+environment for processing and analyzing images.  To illustrate
+how easy it is to do image processing in Octave, the following
+example will load an image, smooth it by a 5-by-5 averaging filter,
+and compute the gradient of the smoothed image.
+
+<pre class="example">     I = imread ("myimage.jpg");
+     S = conv2 (I, ones (5, 5) / 25, "same");
+     [Dx, Dy] = gradient (S);
+</pre>
+   <p class="noindent">In this example <code>S</code> contains the smoothed image, and <code>Dx</code>
+and <code>Dy</code> contains the partial spatial derivatives of the image.
+
+<ul class="menu">
+<li><a accesskey="1" href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a>
+<li><a accesskey="2" href="Displaying-Images.html#Displaying-Images">Displaying Images</a>
+<li><a accesskey="3" href="Representing-Images.html#Representing-Images">Representing Images</a>
+<li><a accesskey="4" href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images">Plotting on top of Images</a>
+<li><a accesskey="5" href="Color-Conversion.html#Color-Conversion">Color Conversion</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Image-Properties.html b/doc/interpreter/HTML/Image-Properties.html
new file mode 100644
index 0000000..0a929c8
--- /dev/null
+++ b/doc/interpreter/HTML/Image-Properties.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Image Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Text-Properties.html#Text-Properties" title="Text Properties">
+<link rel="next" href="Patch-Properties.html#Patch-Properties" title="Patch Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Image-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Patch-Properties.html#Patch-Properties">Patch Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Text-Properties.html#Text-Properties">Text Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.6 Image Properties</h5>
+
+<p><a name="index-image-properties-1194"></a>
+     <dl>
+<dt><code>cdata</code><dd>The data for the image.  Each pixel of the image corresponds to an
+element of <code>cdata</code>.  The value of an element of <code>cdata</code>
+specifies the row-index into the colormap of the axes object containing
+the image.  The color value found in the color map for the given index
+determines the color of the pixel.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dd>Two-element vectors specifying the range of the x- and y- coordinates for
+the image. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Increment-Ops.html b/doc/interpreter/HTML/Increment-Ops.html
new file mode 100644
index 0000000..91c2ab6
--- /dev/null
+++ b/doc/interpreter/HTML/Increment-Ops.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>Increment Ops - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Assignment-Ops.html#Assignment-Ops" title="Assignment Ops">
+<link rel="next" href="Operator-Precedence.html#Operator-Precedence" title="Operator Precedence">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Increment-Ops"></a>
+Next: <a rel="next" accesskey="n" href="Operator-Precedence.html#Operator-Precedence">Operator Precedence</a>,
+Previous: <a rel="previous" accesskey="p" href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.7 Increment Operators</h3>
+
+<p><em>Increment operators</em> increase or decrease the value of a variable
+by 1.  The operator to increment a variable is written as ‘<samp><span class="samp">++</span></samp>’.  It
+may be used to increment a variable either before or after taking its
+value.
+
+   <p>For example, to pre-increment the variable <var>x</var>, you would write
+<code>++</code><var>x</var>.  This would add one to <var>x</var> and then return the new
+value of <var>x</var> as the result of the expression.  It is exactly the
+same as the expression <var>x</var><code> = </code><var>x</var><code> + 1</code>.
+
+   <p>To post-increment a variable <var>x</var>, you would write <var>x</var><code>++</code>. 
+This adds one to the variable <var>x</var>, but returns the value that
+<var>x</var> had prior to incrementing it.  For example, if <var>x</var> is equal
+to 2, the result of the expression <var>x</var><code>++</code> is 2, and the new
+value of <var>x</var> is 3.
+
+   <p>For matrix and vector arguments, the increment and decrement operators
+work on each element of the operand.
+
+   <p>Here is a list of all the increment and decrement expressions.
+
+     <dl>
+<dt><code>++</code><var>x</var><dd><a name="index-g_t_002b_002b-541"></a>This expression increments the variable <var>x</var>.  The value of the
+expression is the <em>new</em> value of <var>x</var>.  It is equivalent to the
+expression <var>x</var><code> = </code><var>x</var><code> + 1</code>.
+
+     <br><dt><code>--</code><var>x</var><dd><a name="index-g_t_0040code_007b_002d_002d_007d-542"></a>This expression decrements the variable <var>x</var>.  The value of the
+expression is the <em>new</em> value of <var>x</var>.  It is equivalent to the
+expression <var>x</var><code> = </code><var>x</var><code> - 1</code>.
+
+     <br><dt><var>x</var><code>++</code><dd><a name="index-g_t_002b_002b-543"></a>This expression causes the variable <var>x</var> to be incremented.  The
+value of the expression is the <em>old</em> value of <var>x</var>.
+
+     <br><dt><var>x</var><code>--</code><dd><a name="index-g_t_0040code_007b_002d_002d_007d-544"></a>This expression causes the variable <var>x</var> to be decremented.  The
+value of the expression is the <em>old</em> value of <var>x</var>. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Index-Expressions.html b/doc/interpreter/HTML/Index-Expressions.html
new file mode 100644
index 0000000..be5891c
--- /dev/null
+++ b/doc/interpreter/HTML/Index-Expressions.html
@@ -0,0 +1,195 @@
+<html lang="en">
+<head>
+<title>Index Expressions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="next" href="Calling-Functions.html#Calling-Functions" title="Calling Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Index-Expressions"></a>
+Next: <a rel="next" accesskey="n" href="Calling-Functions.html#Calling-Functions">Calling Functions</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.1 Index Expressions</h3>
+
+<p><a name="index-g_t_0028-448"></a><a name="index-g_t_0029-449"></a>
+An <dfn>index expression</dfn> allows you to reference or extract selected
+elements of a matrix or vector.
+
+   <p>Indices may be scalars, vectors, ranges, or the special operator
+‘<samp><span class="samp">:</span></samp>’, which may be used to select entire rows or columns.
+
+   <p>Vectors are indexed using a single index expression.  Matrices may be
+indexed using one or two indices.  When using a single index
+expression, the elements of the matrix are taken in column-first order;
+the dimensions of the output match those of the index expression.  For
+example,
+<pre class="example">     a (2)       # a scalar
+     a (1:2)     # a row vector
+     a ([1; 2])  # a column vector
+</pre>
+   <p>As a special case, when a colon is used as a single index, the output
+is a column vector containing all the elements of the vector or matrix. 
+For example
+<pre class="example">     a (:)       # a column vector
+</pre>
+   <p>Given the matrix
+
+<pre class="example">     a = [1, 2; 3, 4]
+</pre>
+   <p class="noindent">all of the following expressions are equivalent
+
+<pre class="example">     a (1, [1, 2])
+     a (1, 1:2)
+     a (1, :)
+</pre>
+   <p class="noindent">and select the first row of the matrix.
+
+   <p>In general, an array with ‘<samp><span class="samp">n</span></samp>’ dimensions can be indexed using ‘<samp><span class="samp">m</span></samp>’
+indices.  If <code>n == m</code>, each index corresponds to its respective dimension. 
+The set of index tuples determining the result is formed by the Cartesian product
+of the index vectors (or ranges or scalars). 
+If <code>n < m</code>, then the array is padded by trailing singleton dimensions. 
+If <code>n > m</code>, the last <code>n-m+1</code> dimensions are folded into a single
+dimension with extent equal to product of extents of the original dimensions.
+
+<!-- FIXED - sections on variable prefer_zero_one_indexing were removed -->
+   <p>Indexing a scalar with a vector of ones can be used to create a
+vector the same size as the index vector, with each element equal to
+the value of the original scalar.  For example, the following statements
+
+<pre class="example">     a = 13;
+     a (ones (1, 4))
+</pre>
+   <p class="noindent">produce a vector whose four elements are all equal to 13.
+
+   <p>Similarly, indexing a scalar with two vectors of ones can be used to
+create a matrix.  For example the following statements
+
+<pre class="example">     a = 13;
+     a (ones (1, 2), ones (1, 3))
+</pre>
+   <p class="noindent">create a 2 by 3 matrix with all elements equal to 13.
+
+   <p>The last example could also be written as
+
+<pre class="example">     13 (ones (2, 3))
+</pre>
+   <p>It should be, noted that <code>ones (1, n)</code> (a row vector of ones) results in a
+range (with zero increment), and is therefore more efficient when used in index
+expression than other forms of <dfn>ones</dfn>.  In particular, when ‘<samp><span class="samp">r</span></samp>’ is a row
+vector, the expressions
+
+<pre class="example">       r(ones (1, n), :)
+</pre>
+   <pre class="example">       r(ones (n, 1), :)
+</pre>
+   <p>will produce identical results, but the first one will be significantly
+faster, at least for ‘<samp><span class="samp">r</span></samp>’ and ‘<samp><span class="samp">n</span></samp>’ large enough.  The reason is that
+in the first case the index is kept in a compressed form, which allows Octave
+to choose a more efficient algorithm to handle the expression.
+
+   <p>In general, for an user unaware of these subtleties, it is best to use
+the function <dfn>repmat</dfn> for spreading arrays into bigger ones.
+
+   <p>It is also possible to create a matrix with different values.  The
+following example creates a 10 dimensional row vector a containing
+the values
+a(i) = sqrt(i).
+
+<pre class="example">     for i = 1:10
+       a(i) = sqrt (i);
+     endfor
+</pre>
+   <p class="noindent">Note that it is quite inefficient to create a vector using a loop like
+the one shown in the example above.  In this particular case, it would
+have been much more efficient to use the expression
+
+<pre class="example">     a = sqrt (1:10);
+</pre>
+   <p class="noindent">thus avoiding the loop entirely.  In cases where a loop is still
+required, or a number of values must be combined to form a larger
+matrix, it is generally much faster to set the size of the matrix first,
+and then insert elements using indexing commands.  For example, given a
+matrix <code>a</code>,
+
+<pre class="example">     [nr, nc] = size (a);
+     x = zeros (nr, n * nc);
+     for i = 1:n
+       x(:,(i-1)*nc+1:i*nc) = a;
+     endfor
+</pre>
+   <p class="noindent">is considerably faster than
+
+<pre class="example">     x = a;
+     for i = 1:n-1
+       x = [x, a];
+     endfor
+</pre>
+   <p class="noindent">particularly for large matrices because Octave does not have to
+repeatedly resize the result.
+
+<!-- ./general/sub2ind.m -->
+   <p><a name="doc_002dsub2ind"></a>
+
+<div class="defun">
+— Function File: <var>ind</var> = <b>sub2ind</b> (<var>dims, i, j</var>)<var><a name="index-sub2ind-450"></a></var><br>
+— Function File: <var>ind</var> = <b>sub2ind</b> (<var>dims, s1, s2, <small class="dots">...</small>, sN</var>)<var><a name="index-sub2ind-451"></a></var><br>
+<blockquote><p>Convert subscripts into a linear index.
+
+        <p>The following example shows how to convert the two-dimensional
+index <code>(2,3)</code> of a 3-by-3 matrix to a linear index.  The matrix
+is linearly indexed moving from one column to next, filling up
+all rows in each column.
+
+     <pre class="example">          linear_index = sub2ind ([3, 3], 2, 3)
+           8
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dind2sub.html#doc_002dind2sub">ind2sub</a>. 
+</p></blockquote></div>
+
+<!-- ./general/ind2sub.m -->
+   <p><a name="doc_002dind2sub"></a>
+
+<div class="defun">
+— Function File: [<var>s1</var>, <var>s2</var>, <small class="dots">...</small>, <var>sN</var>] = <b>ind2sub</b> (<var>dims, ind</var>)<var><a name="index-ind2sub-452"></a></var><br>
+<blockquote><p>Convert a linear index into subscripts.
+
+        <p>The following example shows how to convert the linear index <code>8</code>
+in a 3-by-3 matrix into a subscript.  The matrix is linearly indexed
+moving from one column to next, filling up all rows in each column.
+     <pre class="example">          [r, c] = ind2sub ([3, 3], 8)
+           r =  2
+          c =  3
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsub2ind.html#doc_002dsub2ind">sub2ind</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Indexing-Cell-Arrays.html b/doc/interpreter/HTML/Indexing-Cell-Arrays.html
new file mode 100644
index 0000000..ab89fe8
--- /dev/null
+++ b/doc/interpreter/HTML/Indexing-Cell-Arrays.html
@@ -0,0 +1,141 @@
+<html lang="en">
+<head>
+<title>Indexing Cell Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link rel="prev" href="Creating-Cell-Arrays.html#Creating-Cell-Arrays" title="Creating Cell Arrays">
+<link rel="next" href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings" title="Cell Arrays of Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Indexing-Cell-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a>,
+Previous: <a rel="previous" accesskey="p" href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.2.3 Indexing Cell Arrays</h4>
+
+<p>As shown in see <a href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">Basic Usage of Cell Arrays</a> elements can be
+extracted from cell arrays using the ‘<samp><span class="samp">{</span></samp>’ and ‘<samp><span class="samp">}</span></samp>’
+operators.  If you want to extract or access subarrays which are still
+cell arrays, you need to use the ‘<samp><span class="samp">(</span></samp>’ and ‘<samp><span class="samp">)</span></samp>’ operators. The
+following example illustrates the difference:
+
+<pre class="example">     c = {"1", "2", "3"; "a", "b", "c"; "4", "5", "6"};
+     c{2,3}
+           ans = c
+     
+     c(2,3)
+           ans =
+             {
+               [1,1] = c
+             }
+</pre>
+   <p class="noindent">So with ‘<samp><span class="samp">{}</span></samp>’ you access elements of a cell
+array, while with ‘<samp><span class="samp">()</span></samp>’ you access a sub array of a cell
+array.
+
+   <p>Using the ‘<samp><span class="samp">(</span></samp>’ and ‘<samp><span class="samp">)</span></samp>’ operators, indexing works for cell
+arrays like for multidimensional arrays.  As an example, all the rows
+of the first and third column of a cell array can be set to <code>0</code>
+with the following command:
+
+<pre class="example">     c(:, [1, 3]) = {0}
+            =
+             {
+               [1,1] = 0
+               [2,1] = 0
+               [3,1] = 0
+               [1,2] = 2
+               [2,2] =  10
+               [3,2] =  20
+               [1,3] = 0
+               [2,3] = 0
+               [3,3] = 0
+             }
+</pre>
+   <p>Note, that the above can also be achieved like this:
+
+<pre class="example">     c(:, [1, 3]) = 0;
+</pre>
+   <p class="noindent">Here, the scalar ‘<samp><span class="samp">0</span></samp>’ is automatically promoted to
+cell array ‘<samp><span class="samp">{0}</span></samp>’ and then assigned to the subarray of <code>c</code>.
+
+   <p>To give another example for indexing cell arrays with ‘<samp><span class="samp">()</span></samp>’, you
+can exchange the first and the second row of a cell array as in the
+following command:
+
+<pre class="example">     c = {1, 2, 3; 4, 5, 6};
+     c([1, 2], :) = c([2, 1], :)
+           =
+             {
+               [1,1] =  4
+               [2,1] =  1
+               [1,2] =  5
+               [2,2] =  2
+               [1,3] =  6
+               [2,3] =  3
+             }
+</pre>
+   <p>Accessing multiple elements of a cell array with the ‘<samp><span class="samp">{</span></samp>’ and
+‘<samp><span class="samp">}</span></samp>’ operators will result in a comma-separated list of all the
+requested elements (see <a href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>). Using the
+‘<samp><span class="samp">{</span></samp>’ and ‘<samp><span class="samp">}</span></samp>’ operators the first two rows in the above
+example can be swapped back like this:
+
+<pre class="example">     [c{[1,2], :}] = deal(c{[2, 1], :})
+           =
+             {
+               [1,1] =  1
+               [2,1] =  4
+               [1,2] =  2
+               [2,2] =  5
+               [1,3] =  3
+               [2,3] =  6
+             }
+</pre>
+   <p>As for struct arrays and numerical arrays, the empty matrix ‘<samp><span class="samp">[]</span></samp>’
+can be used to delete elements from a cell array:
+
+<pre class="example">     x = {"1", "2"; "3", "4"};
+     x(1, :) = []
+           x =
+             {
+               [1,1] = 3
+               [1,2] = 4
+             }
+</pre>
+   <p>The following example shows how to just remove the contents of cell
+array elements but not delete the space for them:
+
+<pre class="example">     x = {"1", "2"; "3", "4"};
+     x{1, :} = []
+      x =
+           {
+             [1,1] = [](0x0)
+             [2,1] = 3
+             [1,2] = [](0x0)
+             [2,2] = 4
+           }
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Indexing-Objects.html b/doc/interpreter/HTML/Indexing-Objects.html
new file mode 100644
index 0000000..7e12673
--- /dev/null
+++ b/doc/interpreter/HTML/Indexing-Objects.html
@@ -0,0 +1,252 @@
+<html lang="en">
+<head>
+<title>Indexing Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link rel="prev" href="Manipulating-Classes.html#Manipulating-Classes" title="Manipulating Classes">
+<link rel="next" href="Overloading-Objects.html#Overloading-Objects" title="Overloading Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Indexing-Objects"></a>
+Next: <a rel="next" accesskey="n" href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a>,
+Up: <a rel="up" accesskey="u" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>
+<hr>
+</div>
+
+<h3 class="section">33.3 Indexing Objects</h3>
+
+<p>Objects can be indexed with parentheses, either like
+<var>a</var><code> (</code><var>idx</var><code>)</code> or like <var>a</var><code> {</code><var>idx</var><code>}</code>, or even
+like <var>a</var><code> (</code><var>idx</var><code>).</code><var>field</var>.  However, it is up to the user
+to decide what this indexing actually means.  In the case of our polynomial
+class <var>p</var><code> (</code><var>n</var><code>)</code> might mean either the coefficient of the
+<var>n</var>-th power of the polynomial, or it might be the evaluation of the
+polynomial at <var>n</var>.  The meaning of this subscripted referencing is
+determined by the <code>subsref</code> method.
+
+<!-- ov.cc -->
+   <p><a name="doc_002dsubsref"></a>
+
+<div class="defun">
+— Built-in Function:  <b>subsref</b> (<var>val, idx</var>)<var><a name="index-subsref-2261"></a></var><br>
+<blockquote><p>Perform the subscripted element selection operation according to
+the subscript specified by <var>idx</var>.
+
+        <p>The subscript <var>idx</var> is expected to be a structure array with
+fields ‘<samp><span class="samp">type</span></samp>’ and ‘<samp><span class="samp">subs</span></samp>’.  Valid values for ‘<samp><span class="samp">type</span></samp>’
+are ‘<samp><span class="samp">"()"</span></samp>’, ‘<samp><span class="samp">"{}"</span></samp>’, and ‘<samp><span class="samp">"."</span></samp>’. 
+The ‘<samp><span class="samp">subs</span></samp>’ field may be either ‘<samp><span class="samp">":"</span></samp>’ or a cell array
+of index values.
+
+        <p>The following example shows how to extract the two first columns of
+a matrix
+
+     <pre class="example">          val = magic(3)
+                val = [ 8   1   6
+                          3   5   7
+                          4   9   2 ]
+          idx.type = "()";
+          idx.subs = {":", 1:2};
+          subsref(val, idx)
+                [ 8   1
+                    3   5
+                    4   9 ]
+</pre>
+        <p class="noindent">Note that this is the same as writing <code>val(:,1:2)</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsubsasgn.html#doc_002dsubsasgn">subsasgn</a>, <a href="doc_002dsubstruct.html#doc_002dsubstruct">substruct</a>. 
+</p></blockquote></div>
+
+   <p>For example we might decide that indexing with "()" evaluates the
+polynomial and indexing with "{}" returns the <var>n</var>-th coefficient (of <var>n</var>-th power). 
+In this case the <code>subsref</code> method of our polynomial class might look like
+
+<pre class="example"><pre class="verbatim">     function b = subsref (a, s)
+       if (isempty (s))
+         error ("polynomial: missing index");
+       endif
+       switch (s(1).type)
+         case "()"
+           ind = s(1).subs;
+           if (numel (ind) != 1)
+             error ("polynomial: need exactly one index");
+           else
+             b = polyval (fliplr (a.poly), ind{1});
+           endif
+         case "{}"
+           ind = s(1).subs;
+           if (numel (ind) != 1)
+             error ("polynomial: need exactly one index");
+           else
+             if (isnumeric (ind{1}))
+               b = a.poly(ind{1}+1);
+             else
+               b = a.poly(ind{1});
+             endif
+           endif
+         case "."
+           fld = s.subs;
+           if (strcmp (fld, "poly"))
+             b = a.poly;
+           else
+             error ("@polynomial/subsref: invalid property \"%s\"", fld);
+           endif
+         otherwise
+           error ("invalid subscript type");
+       endswitch
+       if (numel (s) > 1)
+         b = subsref (b, s(2:end));
+       endif
+     endfunction
+</pre>
+</pre>
+   <p>The equivalent functionality for subscripted assignments uses the
+<code>subsasgn</code> method.
+
+<!-- ov.cc -->
+   <p><a name="doc_002dsubsasgn"></a>
+
+<div class="defun">
+— Built-in Function:  <b>subsasgn</b> (<var>val, idx, rhs</var>)<var><a name="index-subsasgn-2262"></a></var><br>
+<blockquote><p>Perform the subscripted assignment operation according to
+the subscript specified by <var>idx</var>.
+
+        <p>The subscript <var>idx</var> is expected to be a structure array with
+fields ‘<samp><span class="samp">type</span></samp>’ and ‘<samp><span class="samp">subs</span></samp>’.  Valid values for ‘<samp><span class="samp">type</span></samp>’
+are ‘<samp><span class="samp">"()"</span></samp>’, ‘<samp><span class="samp">"{}"</span></samp>’, and ‘<samp><span class="samp">"."</span></samp>’. 
+The ‘<samp><span class="samp">subs</span></samp>’ field may be either ‘<samp><span class="samp">":"</span></samp>’ or a cell array
+of index values.
+
+        <p>The following example shows how to set the two first columns of a
+3-by-3 matrix to zero.
+
+     <pre class="example">          val = magic(3);
+          idx.type = "()";
+          idx.subs = {":", 1:2};
+          subsasgn (val, idx, 0)
+                [ 0   0   6
+                    0   0   7
+                    0   0   2 ]
+</pre>
+        <p>Note that this is the same as writing <code>val(:,1:2) = 0</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsubsref.html#doc_002dsubsref">subsref</a>, <a href="doc_002dsubstruct.html#doc_002dsubstruct">substruct</a>. 
+</p></blockquote></div>
+
+   <p>Note that the <code>subsref</code> and <code>subsasgn</code> methods always receive the
+whole index chain, while they usually handle only the first element.  It is the
+responsibility of these methods to handle the rest of the chain (if needed),
+usually by forwarding it again to <code>subsref</code> or <code>subsasgn</code>.
+
+   <p>If you wish to use the <code>end</code> keyword in subscripted expressions
+of an object, then the user needs to define the <code>end</code> method for
+the class.
+
+   <p>For example the <code>end</code> method for our polynomial class might look like
+
+<pre class="example"><pre class="verbatim">     function r = end (obj, index_pos, num_indices)
+     
+       if (num_indices != 1)
+         error ("polynomial object may only have one index")
+       endif
+       
+       r = length (obj.poly) - 1;
+     
+     endfunction
+</pre>
+</pre>
+   <p class="noindent">which is a fairly generic <code>end</code> method that has a behavior similar to
+the <code>end</code> keyword for Octave Array classes.  It can then be used for
+example like
+
+<pre class="example">     p = polynomial([1,2,3,4]);
+     p(end-1)
+      3
+</pre>
+   <p>Objects can also be used as the index in a subscripted expression themselves
+and this is controlled with the <code>subsindex</code> function.
+
+<!-- ./general/subsindex.m -->
+   <p><a name="doc_002dsubsindex"></a>
+
+<div class="defun">
+— Function File: <var>idx</var> = <b>subsindex</b> (<var>a</var>)<var><a name="index-subsindex-2263"></a></var><br>
+<blockquote><p>Convert an object to an index vector.  When <var>a</var> is a class object
+defined with a class constructor, then <code>subsindex</code> is the
+overloading method that allows the conversion of this class object to
+a valid indexing vector.  It is important to note that
+<code>subsindex</code> must return a zero-based real integer vector of the
+class "double".  For example, if the class constructor
+
+     <pre class="example">          function b = myclass (a)
+           b = myclass (struct ("a", a), "myclass");
+          endfunction
+</pre>
+        <p class="noindent">then the <code>subsindex</code> function
+
+     <pre class="example">          function idx = subsindex (a)
+           idx = double (a.a) - 1.0;
+          endfunction
+</pre>
+        <p class="noindent">can then be used as follows
+
+     <pre class="example">          a = myclass (1:4);
+          b = 1:10;
+          b(a)
+           1  2  3  4
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclass.html#doc_002dclass">class</a>, <a href="doc_002dsubsref.html#doc_002dsubsref">subsref</a>, <a href="doc_002dsubsasgn.html#doc_002dsubsasgn">subsasgn</a>. 
+</p></blockquote></div>
+
+   <p>Finally, objects can equally be used like ranges, using the <code>colon</code>
+method
+
+<!-- ./general/colon.m -->
+   <p><a name="doc_002dcolon"></a>
+
+<div class="defun">
+— Function File: <var>r</var> = <b>colon</b> (<var>a, b</var>)<var><a name="index-colon-2264"></a></var><br>
+— Function File: <var>r</var> = <b>colon</b> (<var>a, b, c</var>)<var><a name="index-colon-2265"></a></var><br>
+<blockquote><p>Method of a class to construct a range with the <code>:</code> operator.  For
+example.
+
+     <pre class="example">          a = myclass (...)
+          b = myclass (...)
+          c = a : b
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclass.html#doc_002dclass">class</a>, <a href="doc_002dsubsref.html#doc_002dsubsref">subsref</a>, <a href="doc_002dsubsasgn.html#doc_002dsubsasgn">subsasgn</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Information.html b/doc/interpreter/HTML/Information.html
new file mode 100644
index 0000000..9cb1684
--- /dev/null
+++ b/doc/interpreter/HTML/Information.html
@@ -0,0 +1,296 @@
+<html lang="en">
+<head>
+<title>Information - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basics.html#Basics" title="Basics">
+<link rel="prev" href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices" title="Creating Sparse Matrices">
+<link rel="next" href="Operators-and-Functions.html#Operators-and-Functions" title="Operators and Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Information"></a>
+Next: <a rel="next" accesskey="n" href="Operators-and-Functions.html#Operators-and-Functions">Operators and Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Basics.html#Basics">Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">21.1.3 Finding out Information about Sparse Matrices</h4>
+
+<p>There are a number of functions that allow information concerning
+sparse matrices to be obtained.  The most basic of these is
+<dfn>issparse</dfn> that identifies whether a particular Octave object is
+in fact a sparse matrix.
+
+   <p>Another very basic function is <dfn>nnz</dfn> that returns the number of
+non-zero entries there are in a sparse matrix, while the function
+<dfn>nzmax</dfn> returns the amount of storage allocated to the sparse
+matrix.  Note that Octave tends to crop unused memory at the first
+opportunity for sparse objects.  There are some cases of user created
+sparse objects where the value returned by <dfn>nzmax</dfn> will not be
+the same as <dfn>nnz</dfn>, but in general they will give the same
+result.  The function <dfn>spstats</dfn> returns some basic statistics on
+the columns of a sparse matrix including the number of elements, the
+mean and the variance of each column.
+
+<!-- ./DLD-FUNCTIONS/sparse.cc -->
+   <p><a name="doc_002dissparse"></a>
+
+<div class="defun">
+— Loadable Function:  <b>issparse</b> (<var>expr</var>)<var><a name="index-issparse-1663"></a></var><br>
+<blockquote><p>Return 1 if the value of the expression <var>expr</var> is a sparse matrix. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dnnz"></a>
+
+<div class="defun">
+— Built-in Function: <var>scalar</var> = <b>nnz</b> (<var>a</var>)<var><a name="index-nnz-1664"></a></var><br>
+<blockquote><p>Returns the number of non zero elements in <var>a</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/nonzeros.m -->
+   <p><a name="doc_002dnonzeros"></a>
+
+<div class="defun">
+— Function File:  <b>nonzeros</b> (<var>s</var>)<var><a name="index-nonzeros-1665"></a></var><br>
+<blockquote><p>Returns a vector of the non-zero values of the sparse matrix <var>s</var>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dnzmax"></a>
+
+<div class="defun">
+— Built-in Function: <var>scalar</var> = <b>nzmax</b> (<var>SM</var>)<var><a name="index-nzmax-1666"></a></var><br>
+<blockquote><p>Return the amount of storage allocated to the sparse matrix <var>SM</var>. 
+Note that Octave tends to crop unused memory at the first opportunity
+for sparse objects.  There are some cases of user created sparse objects
+where the value returned by <dfn>nzmax</dfn> will not be the same as <dfn>nnz</dfn>,
+but in general they will give the same result. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>, <a href="doc_002dspalloc.html#doc_002dspalloc">spalloc</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/spstats.m -->
+   <p><a name="doc_002dspstats"></a>
+
+<div class="defun">
+— Function File: [<var>count</var>, <var>mean</var>, <var>var</var>] = <b>spstats</b> (<var>s</var>)<var><a name="index-spstats-1667"></a></var><br>
+— Function File: [<var>count</var>, <var>mean</var>, <var>var</var>] = <b>spstats</b> (<var>s, j</var>)<var><a name="index-spstats-1668"></a></var><br>
+<blockquote><p>Return the stats for the non-zero elements of the sparse matrix <var>s</var>. 
+<var>count</var> is the number of non-zeros in each column, <var>mean</var>
+is the mean of the non-zeros in each column, and <var>var</var> is the
+variance of the non-zeros in each column.
+
+        <p>Called with two input arguments, if <var>s</var> is the data and <var>j</var>
+is the bin number for the data, compute the stats for each bin.  In
+this case, bins can contain data values of zero, whereas with
+<code>spstats (</code><var>s</var><code>)</code> the zeros may disappear. 
+</p></blockquote></div>
+
+   <p>When solving linear equations involving sparse matrices Octave
+determines the means to solve the equation based on the type of the
+matrix as discussed in <a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a>.  Octave probes the
+matrix type when the div (/) or ldiv (\) operator is first used with
+the matrix and then caches the type.  However the <dfn>matrix_type</dfn>
+function can be used to determine the type of the sparse matrix prior
+to use of the div or ldiv operators.  For example
+
+<pre class="example">     a = tril (sprandn(1024, 1024, 0.02), -1) ...
+         + speye(1024);
+     matrix_type (a);
+     ans = Lower
+</pre>
+   <p>show that Octave correctly determines the matrix type for lower
+triangular matrices.  <dfn>matrix_type</dfn> can also be used to force
+the type of a matrix to be a particular type.  For example
+
+<pre class="example">     a = matrix_type (tril (sprandn (1024, ...
+        1024, 0.02), -1) + speye(1024), 'Lower');
+</pre>
+   <p>This allows the cost of determining the matrix type to be
+avoided.  However, incorrectly defining the matrix type will result in
+incorrect results from solutions of linear equations, and so it is
+entirely the responsibility of the user to correctly identify the
+matrix type
+
+   <p>There are several graphical means of finding out information about
+sparse matrices.  The first is the <dfn>spy</dfn> command, which displays
+the structure of the non-zero elements of the
+matrix.  See <a href="fig_003aspmatrix.html#fig_003aspmatrix">fig:spmatrix</a>, for an example of the use of
+<dfn>spy</dfn>.  More advanced graphical information can be obtained with the
+<dfn>treeplot</dfn>, <dfn>etreeplot</dfn> and <dfn>gplot</dfn> commands.
+
+   <div class="float">
+<a name="fig_003aspmatrix"></a><div align="center"><img src="spmatrix.png" alt="spmatrix.png"></div>
+   <p><strong class="float-caption">Figure 21.1: Structure of simple sparse matrix.</strong></p></div>
+
+   <p>One use of sparse matrices is in graph theory, where the
+interconnections between nodes are represented as an adjacency
+matrix.  That is, if the i-th node in a graph is connected to the j-th
+node.  Then the ij-th node (and in the case of undirected graphs the
+ji-th node) of the sparse adjacency matrix is non-zero.  If each node
+is then associated with a set of coordinates, then the <dfn>gplot</dfn>
+command can be used to graphically display the interconnections
+between nodes.
+
+   <p>As a trivial example of the use of <dfn>gplot</dfn>, consider the example
+
+<pre class="example">     A = sparse([2,6,1,3,2,4,3,5,4,6,1,5],
+         [1,1,2,2,3,3,4,4,5,5,6,6],1,6,6);
+     xy = [0,4,8,6,4,2;5,0,5,7,5,7]';
+     gplot(A,xy)
+</pre>
+   <p>which creates an adjacency matrix <code>A</code> where node 1 is connected
+to nodes 2 and 6, node 2 with nodes 1 and 3, etc.  The coordinates of
+the nodes are given in the n-by-2 matrix <code>xy</code>. 
+See <a href="fig_003agplot.html#fig_003agplot">fig:gplot</a>.
+
+   <div class="float">
+<a name="fig_003agplot"></a><div align="center"><img src="gplot.png" alt="gplot.png"></div>
+   <p><strong class="float-caption">Figure 21.2: Simple use of the <dfn>gplot</dfn> command.</strong></p></div>
+
+   <p>The dependencies between the nodes of a Cholesky factorization can be
+calculated in linear time without explicitly needing to calculate the
+Cholesky factorization by the <code>etree</code> command.  This command
+returns the elimination tree of the matrix and can be displayed
+graphically by the command <code>treeplot(etree(A))</code> if <code>A</code> is
+symmetric or <code>treeplot(etree(A+A'))</code> otherwise.
+
+<!-- ./sparse/spy.m -->
+   <p><a name="doc_002dspy"></a>
+
+<div class="defun">
+— Function File:  <b>spy</b> (<var>x</var>)<var><a name="index-spy-1669"></a></var><br>
+— Function File:  <b>spy</b> (<var><small class="dots">...</small>, markersize</var>)<var><a name="index-spy-1670"></a></var><br>
+— Function File:  <b>spy</b> (<var><small class="dots">...</small>, line_spec</var>)<var><a name="index-spy-1671"></a></var><br>
+<blockquote><p>Plot the sparsity pattern of the sparse matrix <var>x</var>.  If the argument
+<var>markersize</var> is given as an scalar value, it is used to determine the
+point size in the plot.  If the string <var>line_spec</var> is given it is
+passed to <code>plot</code> and determines the appearance of the plot. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/colamd.cc -->
+   <p><a name="doc_002detree"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>etree</b> (<var>s</var>)<var><a name="index-etree-1672"></a></var><br>
+— Loadable Function: <var>p</var> = <b>etree</b> (<var>s, typ</var>)<var><a name="index-etree-1673"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>q</var>] = <b>etree</b> (<var>s, typ</var>)<var><a name="index-etree-1674"></a></var><br>
+<blockquote>
+        <p>Returns the elimination tree for the matrix <var>s</var>.  By default <var>s</var>
+is assumed to be symmetric and the symmetric elimination tree is
+returned.  The argument <var>typ</var> controls whether a symmetric or
+column elimination tree is returned.  Valid values of <var>typ</var> are
+'sym' or 'col', for symmetric or column elimination tree respectively
+
+        <p>Called with a second argument, <dfn>etree</dfn> also returns the postorder
+permutations on the tree. 
+</p></blockquote></div>
+
+<!-- ./sparse/etreeplot.m -->
+   <p><a name="doc_002detreeplot"></a>
+
+<div class="defun">
+— Function File:  <b>etreeplot</b> (<var>tree</var>)<var><a name="index-etreeplot-1675"></a></var><br>
+— Function File:  <b>etreeplot</b> (<var>tree, node_style, edge_style</var>)<var><a name="index-etreeplot-1676"></a></var><br>
+<blockquote><p>Plot the elimination tree of the matrix <var>s</var> or
+<var>s</var><code>+</code><var>s</var><code>'</code>  if <var>s</var> in non-symmetric.  The optional
+parameters <var>line_style</var> and <var>edge_style</var> define the output
+style. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtreeplot.html#doc_002dtreeplot">treeplot</a>, <a href="doc_002dgplot.html#doc_002dgplot">gplot</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/gplot.m -->
+   <p><a name="doc_002dgplot"></a>
+
+<div class="defun">
+— Function File:  <b>gplot</b> (<var>a, xy</var>)<var><a name="index-gplot-1677"></a></var><br>
+— Function File:  <b>gplot</b> (<var>a, xy, line_style</var>)<var><a name="index-gplot-1678"></a></var><br>
+— Function File: [<var>x</var>, <var>y</var>] = <b>gplot</b> (<var>a, xy</var>)<var><a name="index-gplot-1679"></a></var><br>
+<blockquote><p>Plot a graph defined by <var>A</var> and <var>xy</var> in the graph theory
+sense.  <var>A</var> is the adjacency matrix of the array to be plotted
+and <var>xy</var> is an <var>n</var>-by-2 matrix containing the coordinates of
+the nodes of the graph.
+
+        <p>The optional parameter <var>line_style</var> defines the output style for
+the plot.  Called with no output arguments the graph is plotted
+directly.  Otherwise, return the coordinates of the plot in <var>x</var>
+and <var>y</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtreeplot.html#doc_002dtreeplot">treeplot</a>, <a href="doc_002detreeplot.html#doc_002detreeplot">etreeplot</a>, <a href="doc_002dspy.html#doc_002dspy">spy</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/treeplot.m -->
+   <p><a name="doc_002dtreeplot"></a>
+
+<div class="defun">
+— Function File:  <b>treeplot</b> (<var>tree</var>)<var><a name="index-treeplot-1680"></a></var><br>
+— Function File:  <b>treeplot</b> (<var>tree, line_style, edge_style</var>)<var><a name="index-treeplot-1681"></a></var><br>
+<blockquote><p>Produces a graph of tree or forest.  The first argument is vector of
+predecessors, optional parameters <var>line_style</var> and <var>edge_style</var>
+define the output style.  The complexity of the algorithm is O(n) in
+terms of is time and memory requirements. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002detreeplot.html#doc_002detreeplot">etreeplot</a>, <a href="doc_002dgplot.html#doc_002dgplot">gplot</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/treelayout.m -->
+   <p><a name="doc_002dtreelayout"></a>
+
+<div class="defun">
+— Function File:  <b>treelayout</b> (<var>Tree</var>)<var><a name="index-treelayout-1682"></a></var><br>
+— Function File:  <b>treelayout</b> (<var>Tree, permutation</var>)<var><a name="index-treelayout-1683"></a></var><br>
+<blockquote><p>treelayout lays out a tree or a forest.  The first argument <var>Tree</var> is a vector of
+predecessors, optional parameter <var>permutation</var> is an optional postorder permutation. 
+The complexity of the algorithm is O(n) in
+terms of time and memory requirements. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002detreeplot.html#doc_002detreeplot">etreeplot</a>, <a href="doc_002dgplot.html#doc_002dgplot">gplot</a>, <a href="doc_002dtreeplot.html#doc_002dtreeplot">treeplot</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Inheritance-and-Aggregation.html b/doc/interpreter/HTML/Inheritance-and-Aggregation.html
new file mode 100644
index 0000000..42e0a8c
--- /dev/null
+++ b/doc/interpreter/HTML/Inheritance-and-Aggregation.html
@@ -0,0 +1,255 @@
+<html lang="en">
+<head>
+<title>Inheritance and Aggregation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link rel="prev" href="Overloading-Objects.html#Overloading-Objects" title="Overloading Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Inheritance-and-Aggregation"></a>
+Previous: <a rel="previous" accesskey="p" href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>,
+Up: <a rel="up" accesskey="u" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>
+<hr>
+</div>
+
+<h3 class="section">33.5 Inheritance and Aggregation</h3>
+
+<p>Using classes to build new classes is supported by octave through the
+use of both inheritance and aggregation.
+
+   <p>Class inheritance is provided by octave using the <code>class</code>
+function in the class constructor.  As in the case of the polynomial
+class, the octave programmer will create a struct that contains the
+data fields required by the class, and then call the class function to
+indicate that an object is to be created from the struct.  Creating a
+child of an existing object is done by creating an object of the
+parent class and providing that object as the third argument of the
+class function.
+
+   <p>This is easily demonstrated by example.  Suppose the programmer needs
+an FIR filter, i.e. a filter with a numerator polynomial but a unity
+denominator polynomial.  In traditional octave programming, this would
+be performed as follows.
+
+<pre class="example">     octave:1> x = [some data vector];
+     octave:2> n = [some coefficient vector];
+     octave:3> y = filter (n, 1, x);
+</pre>
+   <p>The equivalent class could be implemented in a class directory
+ at FIRfilter that is on the octave path.  The constructor is a file
+FIRfilter.m in the class directory.
+
+<pre class="example"><pre class="verbatim">     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} FIRfilter ()
+     ## @deftypefnx {Function File} {} FIRfilter (@var{p})
+     ## Creates an FIR filter with polynomial @var{p} as
+     ## coefficient vector.
+     ##
+     ## @end deftypefn
+     
+     function f = FIRfilter (p)
+     
+       f.polynomial = [];
+       if (nargin == 0)
+         p = @polynomial ([1]);
+       elseif (nargin == 1)
+         if (!isa (p, "polynomial"))
+           error ("FIRfilter: expecting polynomial as input argument");
+         endif
+       else
+         print_usage ();
+       endif
+       f = class (f, "FIRfilter", p);
+     endfunction
+</pre>
+</pre>
+   <p>As before, the leading comments provide command-line documentation for
+the class constructor.  This constructor is very similar to the
+polynomial class constructor, except that we pass a polynomial object
+as the third argument to the class function, telling octave that the
+FIRfilter class will be derived from the polynomial class.  Our FIR
+filter does not have any data fields, but we must provide a struct to
+the <code>class</code> function.  The <code>class</code> function will add an
+element named polynomial to the object struct, so we simply add a
+dummy element named polynomial as the first line of the constructor. 
+This dummy element will be overwritten by the class function.
+
+   <p>Note further that all our examples provide for the case in which no
+arguments are supplied.  This is important since octave will call the
+constructor with no arguments when loading ojects from save files to
+determine the inheritance structure.
+
+   <p>A class may be a child of more than one class (see the documentation
+for the <code>class</code> function), and inheritance may be nested.  There
+is no limitation to the number of parents or the level of nesting
+other than memory or other physical issues.
+
+   <p>As before, we need a <code>display</code> method.  A simple example might be
+
+<pre class="example"><pre class="verbatim">     function display (f)
+     
+       display(f.polynomial);
+     
+     endfunction
+     
+</pre>
+</pre>
+   <p>Note that we have used the polynomial field of the struct to display
+the filter coefficients.
+
+   <p>Once we have the class constructor and display method, we may create
+an object by calling the class constructor.  We may also check the
+class type and examine the underlying structure.
+
+<pre class="example">     octave:1> f=FIRfilter(polynomial([1 1 1]/3))
+     f.polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+     octave:2> class(f)
+     ans = FIRfilter
+     octave:3> isa(f,"FIRfilter")
+     ans =  1
+     octave:4> isa(f,"polynomial")
+     ans =  1
+     octave:5> struct(f)
+     ans =
+     {
+     polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+     }
+</pre>
+   <p>We only need to define a method to actually process data with our
+filter and our class is usable.  It is also useful to provide a means
+of changing the data stored in the class.  Since the fields in the
+underlying struct are private by default, we could provide a mechanism
+to access the fields.  The <code>subsref</code> method may be used for both.
+
+<pre class="example"><pre class="verbatim">     function out = subsref (f, x)
+       switch x.type
+         case "()"
+           n = f.polynomial;
+           out = filter(n.poly, 1, x.subs{1});
+         case "."
+           fld = x.subs;
+           if (strcmp (fld, "polynomial"))
+             out = f.polynomial;
+           else
+             error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+           endif
+         otherwise
+           error ("@FIRfilter/subsref: invalid subscript type for FIR filter");
+       endswitch
+     endfunction
+</pre>
+</pre>
+   <p>The "()" case allows us to filter data using the polynomial provided
+to the constructor.
+
+<pre class="example">     octave:2> f=FIRfilter(polynomial([1 1 1]/3));
+     octave:3> x=ones(5,1);
+     octave:4> y=f(x)
+     y =
+     
+        0.33333
+        0.66667
+        1.00000
+        1.00000
+        1.00000
+</pre>
+   <p>The "." case allows us to view the contents of the polynomial field.
+
+<pre class="example">     octave:1> f=FIRfilter(polynomial([1 1 1]/3));
+     octave:2> f.polynomial
+     ans = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+</pre>
+   <p>In order to change the contents of the object, we need to define a
+<code>subsasgn</code> method.  For example, we may make the polynomial field
+publicly writeable.
+
+<pre class="example"><pre class="verbatim">     function out = subsasgn (f, index, val)
+       switch (index.type)
+         case "."
+           fld = index.subs;
+           if (strcmp (fld, "polynomial"))
+             out = f;
+             out.polynomial = val;
+           else
+             error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+           endif
+         otherwise
+           error ("FIRfilter/subsagn: Invalid index type")
+       endswitch
+     endfunction
+</pre>
+</pre>
+   <p>So that
+
+<pre class="example">     octave:6> f=FIRfilter();
+     octave:7> f.polynomial = polynomial([1 2 3]);
+     f.polynomial = 1 + 2 * X + 3 * X ^ 2
+</pre>
+   <p>Defining the FIRfilter class as a child of the polynomial class
+implies that and FIRfilter object may be used any place that a
+polynomial may be used.  This is not a normal use of a filter, so that
+aggregation may be a more sensible design approach.  In this case, the
+polynomial is simply a field in the class structure.  A class
+constructor for this case might be
+
+<pre class="example"><pre class="verbatim">     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} FIRfilter ()
+     ## @deftypefnx {Function File} {} FIRfilter (@var{p})
+     ## Creates an FIR filter with polynomial @var{p} as
+     ## coefficient vector.
+     ##
+     ## @end deftypefn
+     
+     function f = FIRfilter (p)
+     
+       if (nargin == 0)
+         f.polynomial = @polynomial ([1]);
+       elseif (nargin == 1)
+         if (isa (p, "polynomial"))
+           f.polynomial = p;
+         else
+           error ("FIRfilter: expecting polynomial as input argument");
+         endif
+       else
+         print_usage ();
+       endif
+       f = class (f, "FIRfilter");
+     endfunction
+</pre>
+</pre>
+   <p>For our example, the remaining class methods remain unchanged.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Inline-Functions.html b/doc/interpreter/HTML/Inline-Functions.html
new file mode 100644
index 0000000..d2df156
--- /dev/null
+++ b/doc/interpreter/HTML/Inline-Functions.html
@@ -0,0 +1,124 @@
+<html lang="en">
+<head>
+<title>Inline Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions" title="Function Handles Inline Functions and Anonymous Functions">
+<link rel="prev" href="Anonymous-Functions.html#Anonymous-Functions" title="Anonymous Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Inline-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Anonymous-Functions.html#Anonymous-Functions">Anonymous Functions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.9.3 Inline Functions</h4>
+
+<p>An inline function is created from a string containing the function
+body using the <code>inline</code> function.  The following code defines the
+function f(x) = x^2 + 2.
+
+<pre class="example">     f = inline("x^2 + 2");
+</pre>
+   <p class="noindent">After this it is possible to evaluate f at any x by
+writing <code>f(x)</code>.
+
+<!-- ov-fcn-inline.cc -->
+   <p><a name="doc_002dinline"></a>
+
+<div class="defun">
+— Built-in Function:  <b>inline</b> (<var>str</var>)<var><a name="index-inline-649"></a></var><br>
+— Built-in Function:  <b>inline</b> (<var>str, arg1, <small class="dots">...</small></var>)<var><a name="index-inline-650"></a></var><br>
+— Built-in Function:  <b>inline</b> (<var>str, n</var>)<var><a name="index-inline-651"></a></var><br>
+<blockquote><p>Create an inline function from the character string <var>str</var>. 
+If called with a single argument, the arguments of the generated
+function are extracted from the function itself.  The generated
+function arguments will then be in alphabetical order.  It should
+be noted that i, and j are ignored as arguments due to the
+ambiguity between their use as a variable or their use as an inbuilt
+constant.  All arguments followed by a parenthesis are considered
+to be functions.
+
+        <p>If the second and subsequent arguments are character strings,
+they are the names of the arguments of the function.
+
+        <p>If the second argument is an integer <var>n</var>, the arguments are
+<code>"x"</code>, <code>"P1"</code>, <small class="dots">...</small>, <code>"P</code><var>N</var><code>"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dargnames.html#doc_002dargnames">argnames</a>, <a href="doc_002dformula.html#doc_002dformula">formula</a>, <a href="doc_002dvectorize.html#doc_002dvectorize">vectorize</a>. 
+</p></blockquote></div>
+
+<!-- ov-fcn-inline.cc -->
+   <p><a name="doc_002dargnames"></a>
+
+<div class="defun">
+— Built-in Function:  <b>argnames</b> (<var>fun</var>)<var><a name="index-argnames-652"></a></var><br>
+<blockquote><p>Return a cell array of character strings containing the names of
+the arguments of the inline function <var>fun</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinline.html#doc_002dinline">inline</a>, <a href="doc_002dformula.html#doc_002dformula">formula</a>, <a href="doc_002dvectorize.html#doc_002dvectorize">vectorize</a>. 
+</p></blockquote></div>
+
+<!-- ov-fcn-inline.cc -->
+   <p><a name="doc_002dformula"></a>
+
+<div class="defun">
+— Built-in Function:  <b>formula</b> (<var>fun</var>)<var><a name="index-formula-653"></a></var><br>
+<blockquote><p>Return a character string representing the inline function <var>fun</var>. 
+Note that <code>char (</code><var>fun</var><code>)</code> is equivalent to
+<code>formula (</code><var>fun</var><code>)</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dargnames.html#doc_002dargnames">argnames</a>, <a href="doc_002dinline.html#doc_002dinline">inline</a>, <a href="doc_002dvectorize.html#doc_002dvectorize">vectorize</a>. 
+</p></blockquote></div>
+
+<!-- ov-fcn-inline.cc -->
+   <p><a name="doc_002dvectorize"></a>
+
+<div class="defun">
+— Built-in Function:  <b>vectorize</b> (<var>fun</var>)<var><a name="index-vectorize-654"></a></var><br>
+<blockquote><p>Create a vectorized version of the inline function <var>fun</var>
+by replacing all occurrences of <code>*</code>, <code>/</code>, etc., with
+<code>.*</code>, <code>./</code>, etc. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/symvar.m -->
+   <p><a name="doc_002dsymvar"></a>
+
+<div class="defun">
+— Function File:  <b>symvar</b> (<var>s</var>)<var><a name="index-symvar-655"></a></var><br>
+<blockquote><p>Identifies the argument names in the function defined by a string. 
+Common constant names such as <code>pi</code>, <code>NaN</code>, <code>Inf</code>,
+<code>eps</code>, <code>i</code> or <code>j</code> are ignored.  The arguments that are
+found are returned in a cell array of strings.  If no variables are
+found then the returned cell array is empty. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Input-Conversion-Syntax.html b/doc/interpreter/HTML/Input-Conversion-Syntax.html
new file mode 100644
index 0000000..97e3380
--- /dev/null
+++ b/doc/interpreter/HTML/Input-Conversion-Syntax.html
@@ -0,0 +1,89 @@
+<html lang="en">
+<head>
+<title>Input Conversion Syntax - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Formatted-Input.html#Formatted-Input" title="Formatted Input">
+<link rel="next" href="Table-of-Input-Conversions.html#Table-of-Input-Conversions" title="Table of Input Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Input-Conversion-Syntax"></a>
+Next: <a rel="next" accesskey="n" href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">Table of Input Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Formatted-Input.html#Formatted-Input">Formatted Input</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.12 Input Conversion Syntax</h4>
+
+<p>A <code>scanf</code> template string is a string that contains ordinary
+multibyte characters interspersed with conversion specifications that
+start with ‘<samp><span class="samp">%</span></samp>’.
+
+   <p>Any whitespace character in the template causes any number of whitespace
+characters in the input stream to be read and discarded.  The whitespace
+characters that are matched need not be exactly the same whitespace
+characters that appear in the template string.  For example, write
+‘<samp><span class="samp"> , </span></samp>’ in the template to recognize a comma with optional whitespace
+before and after.
+
+   <p>Other characters in the template string that are not part of conversion
+specifications must match characters in the input stream exactly; if
+this is not the case, a matching failure occurs.
+
+   <p>The conversion specifications in a <code>scanf</code> template string
+have the general form:
+
+<pre class="example">     % <var>flags</var> <var>width</var> <var>type</var> <var>conversion</var>
+</pre>
+   <p>In more detail, an input conversion specification consists of an initial
+‘<samp><span class="samp">%</span></samp>’ character followed in sequence by:
+
+     <ul>
+<li>An optional <dfn>flag character</dfn> ‘<samp><span class="samp">*</span></samp>’, which says to ignore the text
+read for this specification.  When <code>scanf</code> finds a conversion
+specification that uses this flag, it reads input as directed by the
+rest of the conversion specification, but it discards this input, does
+not return any value, and does not increment the count of
+successful assignments. 
+<a name="index-flag-character-_0028_0040code_007bscanf_007d_0029-797"></a>
+<li>An optional decimal integer that specifies the <dfn>maximum field
+width</dfn>.  Reading of characters from the input stream stops either when
+this maximum is reached or when a non-matching character is found,
+whichever happens first.  Most conversions discard initial whitespace
+characters, and these discarded characters don't count towards the
+maximum field width.  Conversions that do not discard initial whitespace
+are explicitly documented. 
+<a name="index-maximum-field-width-_0028_0040code_007bscanf_007d_0029-798"></a>
+<li>An optional type modifier character.  This character is ignored by
+Octave's <code>scanf</code> function, but is recognized to provide
+compatibility with the C language <code>scanf</code>.
+
+     <li>A character that specifies the conversion to be applied. 
+</ul>
+
+   <p>The exact options that are permitted and how they are interpreted vary
+between the different conversion specifiers.  See the descriptions of the
+individual conversions for information about the particular options that
+they allow.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Input-Parameter-Checking-in-Oct_002dFiles.html b/doc/interpreter/HTML/Input-Parameter-Checking-in-Oct_002dFiles.html
new file mode 100644
index 0000000..a3a60e6
--- /dev/null
+++ b/doc/interpreter/HTML/Input-Parameter-Checking-in-Oct_002dFiles.html
@@ -0,0 +1,101 @@
+<html lang="en">
+<head>
+<title>Input Parameter Checking in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles" title="Allocating Local Memory in Oct-Files">
+<link rel="next" href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles" title="Exception and Error Handling in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Input-Parameter-Checking-in-Oct-Files"></a>
+<a name="Input-Parameter-Checking-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles">Exception and Error Handling in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles">Allocating Local Memory in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.11 Input Parameter Checking in Oct-Files</h4>
+
+<p>As oct-files are compiled functions they have the possibility of causing
+Octave to abort abnormally.  It is therefore important that
+each and every function has the minimum of parameter
+checking needed to ensure that Octave behaves well.
+
+   <p>The minimum requirement, as previously discussed, is to check the number
+of input arguments before using them to avoid referencing a non existent
+argument.  However, it some case this might not be sufficient as the
+underlying code imposes further constraints.  For example an external
+function call might be undefined if the input arguments are not
+integers, or if one of the arguments is zero.  Therefore, oct-files often
+need additional input parameter checking.
+
+   <p>There are several functions within Octave that might be useful for the
+purposes of parameter checking.  These include the methods of the
+octave_value class like <code>is_real_matrix</code>, etc., but equally include
+more specialized functions.  Some of the more common ones are
+demonstrated in the following example
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     
+     DEFUN_DLD (paramdemo, args, nargout, 
+     	   "Parameter Check Demo.")
+     {
+       int nargin = args.length ();
+       octave_value retval;
+     
+       if (nargin != 1)
+         print_usage();
+       else if (nargout != 0)
+         error ("paramdemo: function has no output arguments");
+       else
+         {
+           NDArray m = args(0).array_value();
+           double min_val = -10.0;
+           double max_val = 10.0;
+           octave_stdout << "Properties of input array:\n";
+           if (m.any_element_is_negative ())
+             octave_stdout << "  includes negative values\n";
+           if (m.any_element_is_inf_or_nan())
+             octave_stdout << "  includes Inf or NaN values\n";
+           if (m.any_element_not_one_or_zero())
+             octave_stdout << 
+     	  "  includes other values than 1 and 0\n";
+           if (m.all_elements_are_int_or_inf_or_nan())
+             octave_stdout << 
+     	  "  includes only int, Inf or NaN values\n";
+           if (m.all_integers (min_val, max_val))
+             octave_stdout << 
+     	  "  includes only integers in [-10,10]\n";
+         }
+       return retval;
+     }
+</pre></pre>
+   <p class="noindent">and an example of its use is
+
+<pre class="example">     paramdemo ([1, 2, NaN, Inf])
+      Properties of input array:
+           includes Inf or NaN values
+           includes other values than 1 and 0
+           includes only int, Inf or NaN values
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Input-and-Output.html b/doc/interpreter/HTML/Input-and-Output.html
new file mode 100644
index 0000000..32f505f
--- /dev/null
+++ b/doc/interpreter/HTML/Input-and-Output.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Input and Output - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Debugging.html#Debugging" title="Debugging">
+<link rel="next" href="Plotting.html#Plotting" title="Plotting">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Input-and-Output"></a>
+Next: <a rel="next" accesskey="n" href="Plotting.html#Plotting">Plotting</a>,
+Previous: <a rel="previous" accesskey="p" href="Debugging.html#Debugging">Debugging</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">14 Input and Output</h2>
+
+<p>Octave supports several ways of reading and writing data to or from the
+prompt or a file.  The simplest functions for data Input and Output
+(I/O) are easy to use, but only provides limited control of how
+data is processed.  For more control, a set of functions modelled
+after the C standard library are also provided by Octave.
+
+<ul class="menu">
+<li><a accesskey="1" href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>
+<li><a accesskey="2" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Installation-Problems.html b/doc/interpreter/HTML/Installation-Problems.html
new file mode 100644
index 0000000..3a6fee6
--- /dev/null
+++ b/doc/interpreter/HTML/Installation-Problems.html
@@ -0,0 +1,225 @@
+<html lang="en">
+<head>
+<title>Installation Problems - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Installation.html#Installation" title="Installation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Installation-Problems"></a>
+Up: <a rel="up" accesskey="u" href="Installation.html#Installation">Installation</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">F.1 Installation Problems</h3>
+
+<p>This section contains a list of problems (and some apparent problems
+that don't really mean anything is wrong) that may show up during
+installation of Octave.
+
+     <ul>
+<li>On some SCO systems, <code>info</code> fails to compile if
+<code>HAVE_TERMIOS_H</code><!-- /@w --> is defined in <samp><span class="file">config.h</span></samp>.  Simply removing
+the definition from <samp><span class="file">info/config.h</span></samp> should allow it to compile.
+
+     <li>If <code>configure</code> finds <code>dlopen</code>, <code>dlsym</code>, <code>dlclose</code>,
+and <code>dlerror</code>, but not the header file <samp><span class="file">dlfcn.h</span></samp>, you need to
+find the source for the header file and install it in the directory
+<samp><span class="file">usr/include</span></samp>.  This is reportedly a problem with Slackware 3.1. 
+For Linux/GNU systems, the source for <samp><span class="file">dlfcn.h</span></samp> is in the
+<code>ldso</code> package.
+
+     <li>Building <samp><span class="file">.oct</span></samp> files doesn't work.
+
+     <p>You should probably have a shared version of <code>libstdc++</code>.  A patch
+is needed to build shared versions of version 2.7.2 of <code>libstdc++</code>
+on the HP-PA architecture.  You can find the patch at
+<a href="ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix">ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix</a>.
+
+     <li>On some alpha systems there may be a problem with the <code>libdxml</code>
+library, resulting in floating point errors and/or segmentation faults in
+the linear algebra routines called by Octave.  If you encounter such
+problems, then you should modify the configure script so that
+<code>SPECIAL_MATH_LIB</code><!-- /@w --> is not set to <code>-ldxml</code>.
+
+     <li>On FreeBSD systems Octave may hang while initializing some internal
+constants.  The fix appears to be to use
+
+     <pre class="example">          options      GPL_MATH_EMULATE
+</pre>
+     <p class="noindent">rather than
+
+     <pre class="example">          options      MATH_EMULATE
+</pre>
+     <p class="noindent">in the kernel configuration files (typically found in the directory
+<samp><span class="file">/sys/i386/conf</span></samp>.  After making this change, you'll need to rebuild
+the kernel, install it, and reboot.
+
+     <li>If you encounter errors like
+
+     <pre class="example">          passing `void (*)()' as argument 2 of
+            `octave_set_signal_handler(int, void (*)(int))'
+</pre>
+     <p class="noindent">or
+
+     <pre class="example">          warning: ANSI C++ prohibits conversion from `(int)'
+                   to `(...)'
+</pre>
+     <p class="noindent">while compiling <samp><span class="file">sighandlers.cc</span></samp>, you may need to edit some files
+in the <code>gcc</code> include subdirectory to add proper prototypes for functions
+there.  For example, Ultrix 4.2 needs proper declarations for the
+<code>signal</code> function and the <code>SIG_IGN</code><!-- /@w --> macro in the file
+<samp><span class="file">signal.h</span></samp>.
+
+     <p>On some systems the <code>SIG_IGN</code><!-- /@w --> macro is defined to be something like
+this:
+
+     <pre class="example">          #define  SIG_IGN  (void (*)())1
+</pre>
+     <p class="noindent">when it should really be something like:
+
+     <pre class="example">          #define  SIG_IGN  (void (*)(int))1
+</pre>
+     <p class="noindent">to match the prototype declaration for the <code>signal</code> function.  This
+change should also be made for the <code>SIG_DFL</code><!-- /@w --> and <code>SIG_ERR</code><!-- /@w -->
+symbols.  It may be necessary to change the definitions in
+<samp><span class="file">sys/signal.h</span></samp> as well.
+
+     <p>The <code>gcc</code> <code>fixincludes</code> and <code>fixproto</code> scripts should
+probably fix these problems when <code>gcc</code> installs its modified set of
+header files, but I don't think that's been done yet.
+
+     <p><strong>You should not change the files in </strong><samp><span class="file">/usr/include</span></samp>.  You
+can find the <code>gcc</code> include directory tree by running the command
+
+     <pre class="example">          gcc -print-libgcc-file-name
+</pre>
+     <p class="noindent">The directory of <code>gcc</code> include files normally begins in the same directory
+that contains the file <samp><span class="file">libgcc.a</span></samp>.
+
+     <li>Some of the Fortran subroutines may fail to compile with older versions
+of the Sun Fortran compiler.  If you get errors like
+
+     <pre class="example">          zgemm.f:
+          	zgemm:
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 245: warning: unexpected parent of complex
+            expression subtree
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 304: warning: unexpected parent of complex
+            expression subtree
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 327: warning: unexpected parent of complex
+            expression subtree
+          pcc_binval: missing IR_CONV in complex op
+          make[2]: *** [zgemm.o] Error 1
+</pre>
+     <p class="noindent">when compiling the Fortran subroutines in the <samp><span class="file">libcruft</span></samp>
+subdirectory, you should either upgrade your compiler or try compiling
+with optimization turned off.
+
+     <li>On NeXT systems, if you get errors like this:
+
+     <pre class="example">          /usr/tmp/cc007458.s:unknown:Undefined local
+                symbol LBB7656
+          /usr/tmp/cc007458.s:unknown:Undefined local
+                symbol LBE7656
+</pre>
+     <p class="noindent">when compiling <samp><span class="file">Array.cc</span></samp> and <samp><span class="file">Matrix.cc</span></samp>, try recompiling
+these files without <code>-g</code>.
+
+     <li>Some people have reported that calls to shell_cmd and the pager do not
+work on SunOS systems.  This is apparently due to having
+<code>G_HAVE_SYS_WAIT</code><!-- /@w --> defined to be 0 instead of 1 when compiling
+<code>libg++</code>.
+
+     <li>On NeXT systems, linking to <samp><span class="file">libsys_s.a</span></samp> may fail to resolve the
+following functions
+
+     <pre class="example">          _tcgetattr
+          _tcsetattr
+          _tcflow
+</pre>
+     <p class="noindent">which are part of <samp><span class="file">libposix.a</span></samp>.  Unfortunately, linking Octave with
+<code>-posix</code> results in the following undefined symbols.
+
+     <pre class="example">          .destructors_used
+          .constructors_used
+          _objc_msgSend
+          _NXGetDefaultValue
+          _NXRegisterDefaults
+          .objc_class_name_NXStringTable
+          .objc_class_name_NXBundle
+</pre>
+     <p>One kluge around this problem is to extract <samp><span class="file">termios.o</span></samp> from
+<samp><span class="file">libposix.a</span></samp>, put it in Octave's <samp><span class="file">src</span></samp> directory, and add it
+to the list of files to link together in the makefile.  Suggestions for
+better ways to solve this problem are welcome!
+
+     <li>If Octave crashes immediately with a floating point exception, it is
+likely that it is failing to initialize the IEEE floating point values
+for infinity and NaN.
+
+     <p>If your system actually does support IEEE arithmetic, you should be able
+to fix this problem by modifying the function <code>octave_ieee_init</code> in
+the file <samp><span class="file">lo-ieee.cc</span></samp> to correctly initialize Octave's internal
+infinity and NaN variables.
+
+     <p>If your system does not support IEEE arithmetic but Octave's configure
+script incorrectly determined that it does, you can work around the
+problem by editing the file <samp><span class="file">config.h</span></samp> to not define
+<code>HAVE_ISINF</code><!-- /@w -->, <code>HAVE_FINITE</code><!-- /@w -->, and <code>HAVE_ISNAN</code><!-- /@w -->.
+
+     <p>In any case, please report this as a bug since it might be possible to
+modify Octave's configuration script to automatically determine the
+proper thing to do.
+
+     <li>If Octave is unable to find a header file because it is installed in a
+location that is not normally searched by the compiler, you can add the
+directory to the include search path by specifying (for example)
+<code>CPPFLAGS=-I/some/nonstandard/directory</code> as an argument to
+<code>configure</code>.  Other variables that can be specified this way are
+<code>CFLAGS</code>, <code>CXXFLAGS</code>, <code>FFLAGS</code>, and <code>LDFLAGS</code>. 
+Passing them as options to the configure script also records them in the
+<samp><span class="file">config.status</span></samp> file.  By default, <code>CPPFLAGS</code> and
+<code>LDFLAGS</code> are empty, <code>CFLAGS</code> and <code>CXXFLAGS</code> are set to
+<code>"-g -O"</code> and <code>FFLAGS</code> is set to <code>"-O"</code>.
+
+   </ul>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2001, 2002, 2003, 2005, -->
+<!-- 2006, 2007, 2008, 2009 Kurt Hornik -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+<!-- Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/05/17. -->
+<!-- Last updated by KH on 1997/07/31. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Installation.html b/doc/interpreter/HTML/Installation.html
new file mode 100644
index 0000000..307f2c7
--- /dev/null
+++ b/doc/interpreter/HTML/Installation.html
@@ -0,0 +1,228 @@
+<html lang="en">
+<head>
+<title>Installation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Trouble.html#Trouble" title="Trouble">
+<link rel="next" href="Emacs-Octave-Support.html#Emacs-Octave-Support" title="Emacs Octave Support">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Installation"></a>
+Next: <a rel="next" accesskey="n" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>,
+Previous: <a rel="previous" accesskey="p" href="Trouble.html#Trouble">Trouble</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix F Installing Octave</h2>
+
+   <p><a name="index-installing-Octave-2556"></a>
+Here is the procedure for installing Octave from scratch on a Unix
+system.
+
+     <ul>
+<li>Run the shell script <samp><span class="file">configure</span></samp>.  This will determine the features
+your system has (or doesn't have) and create a file named
+<samp><span class="file">Makefile</span></samp> from each of the files named <samp><span class="file">Makefile.in</span></samp>.
+
+     <p>Here is a summary of the configure options that are most frequently used
+when building Octave:
+
+          <dl>
+<dt><code>--prefix=</code><var>prefix</var><dd>Install Octave in subdirectories below <var>prefix</var>.  The default value
+of <var>prefix</var> is <samp><span class="file">/usr/local</span></samp>.
+
+          <br><dt><code>--srcdir=</code><var>dir</var><dd>Look for Octave sources in the directory <var>dir</var>.
+
+          <br><dt><code>--enable-bounds-check</code><dd>Enable bounds checking for indexing operators in the internal array
+classes.  This option is primarily used for debugging Octave.  Building
+Octave with this option has a negative impact on performance and is not
+recommended for general use.
+
+          <br><dt><code>--enable-64</code><dd>This is an <strong>experimental</strong> option to enable Octave to use 64-bit
+integers for array dimensions and indexing on 64-bit platforms.  You
+probably don't want to use this option unless you know what you are
+doing.
+
+          <p>If you use <code>--enable-64</code>, you must ensure that your Fortran
+compiler generates code with 8 byte signed <code>INTEGER</code> values, and
+that your <span class="sc">blas</span> and <span class="sc">lapack</span> libraries are compiled to use 8 byte
+signed integers for array dimensions and indexing.
+
+          <br><dt><code>--enable-shared</code><dd>Create shared libraries (this is the default).  If you are planning to
+use the dynamic loading features, you will probably want to use this
+option.  It will make your <samp><span class="file">.oct</span></samp> files much smaller and on some
+systems it may be necessary to build shared libraries in order to use
+dynamically linked functions.
+
+          <p>You may also want to build a shared version of <code>libstdc++</code>, if your
+system doesn't already have one.
+
+          <br><dt><code>--enable-dl</code><dd>Use <code>dlopen</code> and friends to make Octave capable of dynamically
+linking externally compiled functions (this is the default if
+<code>--enable-shared</code> is specified).  This option only works on systems
+that actually have these functions.  If you plan on using this feature, you
+should probably also use <code>--enable-shared</code> to reduce the size of
+your <samp><span class="file">.oct</span></samp> files.
+
+          <br><dt><code>--without-blas</code><dd>Compile and use the generic <span class="sc">blas</span> and <span class="sc">lapack</span> versions included with
+Octave.  By default, configure first looks for <span class="sc">blas</span> and <span class="sc">lapack</span> matrix
+libraries on your system, including optimized <span class="sc">blas</span> implementations such
+as the free ATLAS 3.0, as well as vendor-tuned libraries.  (The use of
+an optimized <span class="sc">blas</span> will generally result in several-times faster matrix
+operations.)  Only use this option if your system has <span class="sc">blas</span>/<span class="sc">lapack</span>
+libraries that cause problems for some reason.  You can also use
+<code>--with-blas=lib</code> to specify a particular <span class="sc">blas</span> library
+ that configure doesn't check for automatically.
+
+          <br><dt><code>--without-ccolamd</code><dd>Don't use CCOLAMD, disable some sparse matrix functionality.
+
+          <br><dt><code>--without-colamd</code><dd>Don't use COLAMD, disable some sparse matrix functionality.
+
+          <br><dt><code>--without-curl</code><dd>Don't use the cURL, disable the <code>urlread</code> and <code>urlwrite</code>
+functions.
+
+          <br><dt><code>--without-cxsparse</code><dd>Don't use CXSPARSE, disable some sparse matrix functionality.
+
+          <br><dt><code>--without-umfpack</code><dd>Don't use UMFPACK, disable some sparse matrix functionality.
+
+          <br><dt><code>--without-fftw</code><dd>Use the included <span class="sc">fftpack</span> library instead of the <span class="sc">fftw</span> library.
+
+          <br><dt><code>--without-glpk</code><dd>Don't use the GLPK library for linear programming.
+
+          <br><dt><code>--without-hdf5</code><dd>Don't use the HDF5 library for reading and writing HDF5 files.
+
+          <br><dt><code>--without-zlib</code><dd>Don't use the zlib library, disable data file compression and support
+for recent MAT file formats.
+
+          <br><dt><code>--without-lapack</code><dd>Compile and use the generic <span class="sc">blas</span> and <span class="sc">lapack</span> versions included with
+Octave.  By default, configure first looks for <span class="sc">blas</span> and <span class="sc">lapack</span> matrix
+libraries on your system, including optimized <span class="sc">blas</span> implementations such
+as the free ATLAS 3.0, as well as vendor-tuned libraries.  (The use of
+an optimized <span class="sc">blas</span> will generally result in several-times faster matrix
+operations.)  Only use this option if your system has <span class="sc">blas</span>/<span class="sc">lapack</span>
+libraries that cause problems for some reason.  You can also use
+<code>--with-blas=lib</code> to specify a particular <span class="sc">blas</span> library
+ that configure doesn't check for automatically.
+
+          <br><dt><code>--without-framework-carbon</code><dd>Don't use framework Carbon headers, libraries and specific source code
+for compilation even if the configure test succeeds (the default value
+is <code>--with-framework-carbon</code>).  This is a platform specific configure
+option for Mac systems.
+
+          <br><dt><code>--without-framework-opengl</code><dd>Don't use framework OpenGL headers, libraries and specific source code
+for compilation even if the configure test succeeds.  If this option is
+given then OpenGL headers and libraries in standard system locations are
+tested (the default value is <code>--with-framework-opengl</code>).  This is a
+platform specific configure option for Mac systems.
+
+          <br><dt><code>--help</code><dd>Print a summary of the options recognized by the configure script. 
+</dl>
+
+     <p>See the file <samp><span class="file">INSTALL</span></samp> for more general information about the
+command line options used by configure.  That file also contains
+instructions for compiling in a directory other than where the source
+is located.
+
+     <li>Run make.
+
+     <p>You will need a recent version of GNU Make.  Modifying Octave's
+makefiles to work with other make programs is probably not worth
+your time.  We recommend you get and compile GNU Make instead.
+
+     <p>For plotting, you will need to have gnuplot installed on your system. 
+Gnuplot is a command-driven interactive function plotting program. 
+Gnuplot is copyrighted, but freely distributable.  The `gnu' in gnuplot
+is a coincidence—it is not related to the GNU project or the FSF in
+any but the most peripheral sense.
+
+     <p>To compile Octave, you will need a recent version of GNU Make.  You will
+also need a recent version of <code>g++</code> or other ANSI C++ compiler.  You
+will also need a Fortran 77 compiler or <code>f2c</code>.  If you use
+<code>f2c</code>, you will need a script like <code>fort77</code> that works like a
+normal Fortran compiler by combining <code>f2c</code> with your C compiler in
+a single script.
+
+     <p>If you plan to modify the parser you will also need GNU <code>bison</code> and
+<code>flex</code>.  If you modify the documentation, you will need GNU
+Texinfo, along with the patch for the <code>makeinfo</code> program that is
+distributed with Octave.
+
+     <p>GNU Make, <code>gcc</code>, and <code>libstdc++</code>, <code>gnuplot</code>,
+<code>bison</code>, <code>flex</code>, and Texinfo are all available from many
+anonymous ftp archives.  The primary site is <a href="ftp.gnu.org">ftp.gnu.org</a>, but it
+is often very busy.  A list of sites that mirror the software on
+<a href="ftp.gnu.org">ftp.gnu.org</a> is available by anonymous ftp from
+<a href="ftp://ftp.gnu.org/pub/gnu/GNUinfo/FTP">ftp://ftp.gnu.org/pub/gnu/GNUinfo/FTP</a>.
+
+     <p>You will need about 1 gigabyte of disk storage to work with when
+building Octave from source (considerably less if you don't compile with
+debugging symbols).  To do that, use the command
+
+     <pre class="example">          make CFLAGS=-O CXXFLAGS=-O LDFLAGS=
+</pre>
+     <p class="noindent">instead of just ‘<samp><span class="samp">make</span></samp>’.
+
+     <li>If you encounter errors while compiling Octave, first check the list of
+known problems below to see if there is a workaround or solution for
+your problem.  If not,
+see <a href="Trouble.html#Trouble">Trouble</a>,
+for information about how to report bugs.
+
+     <li>Once you have successfully compiled Octave, run ‘<samp><span class="samp">make install</span></samp>’.
+
+     <p>This will install a copy of Octave, its libraries, and its documentation
+in the destination directory.  As distributed, Octave is installed in
+the following directories.  In the table below, <var>prefix</var> defaults to
+<samp><span class="file">/usr/local</span></samp>, <var>version</var> stands for the current version number
+of the interpreter, and <var>arch</var> is the type of computer on which
+Octave is installed (for example, ‘<samp><span class="samp">i586-unknown-gnu</span></samp>’).
+
+          <dl>
+<dt><samp><var>prefix</var><span class="file">/bin</span></samp><dd>Octave and other binaries that people will want to run directly.
+
+          <br><dt><samp><var>prefix</var><span class="file">/lib</span></samp><dd>Libraries like libcruft.a and liboctave.a.
+
+          <br><dt><samp><var>prefix</var><span class="file">/share</span></samp><dd>Architecture-independent data files.
+
+          <br><dt><samp><var>prefix</var><span class="file">/include/octave</span></samp><dd>Include files distributed with Octave.
+
+          <br><dt><samp><var>prefix</var><span class="file">/man/man1</span></samp><dd>Unix-style man pages describing Octave.
+
+          <br><dt><samp><var>prefix</var><span class="file">/info</span></samp><dd>Info files describing Octave.
+
+          <br><dt><samp><var>prefix</var><span class="file">/share/octave/</span><var>version</var><span class="file">/m</span></samp><dd>Function files distributed with Octave.  This includes the Octave
+version, so that multiple versions of Octave may be installed at the
+same time.
+
+          <br><dt><samp><var>prefix</var><span class="file">/lib/octave/</span><var>version</var><span class="file">/exec/</span><var>arch</var></samp><dd>Executables to be run by Octave rather than the user.
+
+          <br><dt><samp><var>prefix</var><span class="file">/lib/octave/</span><var>version</var><span class="file">/oct/</span><var>arch</var></samp><dd>Object files that will be dynamically loaded.
+
+          <br><dt><samp><var>prefix</var><span class="file">/share/octave/</span><var>version</var><span class="file">/imagelib</span></samp><dd>Image files that are distributed with Octave. 
+</dl>
+     </ul>
+
+<ul class="menu">
+<li><a accesskey="1" href="Installation-Problems.html#Installation-Problems">Installation Problems</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Installing-EOS.html b/doc/interpreter/HTML/Installing-EOS.html
new file mode 100644
index 0000000..0cb2b9e
--- /dev/null
+++ b/doc/interpreter/HTML/Installing-EOS.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Installing EOS - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Emacs-Octave-Support.html#Emacs-Octave-Support" title="Emacs Octave Support">
+<link rel="next" href="Using-Octave-Mode.html#Using-Octave-Mode" title="Using Octave Mode">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Installing-EOS"></a>
+Next: <a rel="next" accesskey="n" href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a>,
+Up: <a rel="up" accesskey="u" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">G.1 Installing EOS</h3>
+
+<p>The Emacs package EOS consists of the three files <samp><span class="file">octave-mod.el</span></samp>,
+<samp><span class="file">octave-inf.el</span></samp>, and <samp><span class="file">octave-hlp.el</span></samp>.  These files, or better
+yet their byte-compiled versions, should be somewhere in your Emacs
+load-path.
+
+   <p>If you have GNU Emacs with a version number at least as high as 19.35,
+you are all set up, because EOS is respectively will be part of GNU
+Emacs as of version 19.35.
+
+   <p>Otherwise, copy the three files from the <samp><span class="file">emacs</span></samp> subdirectory of
+the Octave distribution to a place where Emacs can find them (this
+depends on how your Emacs was installed).  Byte-compile them for speed
+if you want.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Installing-and-Removing-Packages.html b/doc/interpreter/HTML/Installing-and-Removing-Packages.html
new file mode 100644
index 0000000..4c6a757
--- /dev/null
+++ b/doc/interpreter/HTML/Installing-and-Removing-Packages.html
@@ -0,0 +1,223 @@
+<html lang="en">
+<head>
+<title>Installing and Removing Packages - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Packages.html#Packages" title="Packages">
+<link rel="next" href="Using-Packages.html#Using-Packages" title="Using Packages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Installing-and-Removing-Packages"></a>
+Next: <a rel="next" accesskey="n" href="Using-Packages.html#Using-Packages">Using Packages</a>,
+Up: <a rel="up" accesskey="u" href="Packages.html#Packages">Packages</a>
+<hr>
+</div>
+
+<h3 class="section">35.1 Installing and Removing Packages</h3>
+
+<p>Assuming a package is available in the file <samp><span class="file">image-1.0.0.tar.gz</span></samp>
+it can be installed from the Octave prompt with the command
+
+<pre class="example">     pkg install image-1.0.0.tar.gz
+</pre>
+   <p class="noindent">If the package is installed successfully nothing will be printed on
+the prompt, but if an error occurred during installation it will be
+reported.  It is possible to install several packages at once by
+writing several package files after the <code>pkg install</code> command. 
+If a different version of the package is already installed it will
+be removed prior to installing the new package.  This makes it easy to
+upgrade and downgrade the version of a package, but makes it
+impossible to have several versions of the same package installed at
+once.
+
+   <p>To see which packages are installed type
+
+<pre class="example">     pkg list
+     -| Package Name  | Version | Installation directory
+     -| --------------+---------+-----------------------
+     -|        image *|   1.0.0 | /home/jwe/octave/image-1.0.0
+</pre>
+   <p class="noindent">In this case only version 1.0.0 of the <code>image</code> package is
+installed.  The '*' character next to the package name shows that the
+image package is loaded and ready for use.
+
+   <p>It is possible to remove a package from the system using the
+<code>pkg uninstall</code> command like this
+
+<pre class="example">     pkg uninstall image
+</pre>
+   <p class="noindent">If the package is removed successfully nothing will be printed in the
+prompt, but if an error occurred it will be reported.  It should be
+noted that the package file used for installation is not needed for
+removal, and that only the package name as reported by <code>pkg list</code>
+should be used when removing a package.  It is possible to remove
+several packages at once by writing several package names after the
+<code>pkg uninstall</code> command.
+
+   <p>To minimize the amount of code duplication between packages it is
+possible that one package depends on another one.  If a package
+depends on another, it will check if that package is installed
+during installation.  If it is not, an error will be reported and
+the package will not be installed.  This behavior can be disabled
+by passing the <code>-nodeps</code> flag to the <code>pkg install</code>
+command
+
+<pre class="example">     pkg install -nodeps my_package_with_dependencies.tar.gz
+</pre>
+   <p class="noindent">Since the installed package expects its dependencies to be installed
+it may not function correctly.  Because of this it is not recommended
+to disable dependency checking.
+
+<!-- ./pkg/pkg.m -->
+   <p><a name="doc_002dpkg"></a>
+
+<div class="defun">
+— Command: pkg <var>command</var><var> pkg_name<a name="index-g_t_0040var_007bcommand_007d-2466"></a></var><br>
+— Command: pkg <var>command</var><var> option pkg_name<a name="index-g_t_0040var_007bcommand_007d-2467"></a></var><br>
+<blockquote><p>This command interacts with the package manager.  Different actions will
+be taken depending on the value of <var>command</var>.
+
+          <dl>
+<dt>‘<samp><span class="samp">install</span></samp>’<dd>Install named packages.  For example,
+          <pre class="example">               pkg install image-1.0.0.tar.gz
+</pre>
+          <p class="noindent">installs the package found in the file <samp><span class="file">image-1.0.0.tar.gz</span></samp>.
+
+          <p>The <var>option</var> variable can contain options that affect the manner
+in which a package is installed.  These options can be one or more of
+
+               <dl>
+<dt><code>-nodeps</code><dd>The package manager will disable the dependency checking.  That way it
+is possible to install a package even if it depends on another package
+that's not installed on the system.  <strong>Use this option with care.</strong>
+
+               <br><dt><code>-noauto</code><dd>The package manager will not automatically load the installed package
+when starting Octave, even if the package requests that it is.
+
+               <br><dt><code>-auto</code><dd>The package manager will automatically load the installed package when
+starting Octave, even if the package requests that it isn't.
+
+               <br><dt><code>-local</code><dd>A local installation is forced, even if the user has system privileges.
+
+               <br><dt><code>-global</code><dd>A global installation is forced, even if the user doesn't normally have
+system privileges
+
+               <br><dt><code>-verbose</code><dd>The package manager will print the output of all of the commands that are
+performed. 
+</dl>
+
+          <br><dt>‘<samp><span class="samp">uninstall</span></samp>’<dd>Uninstall named packages.  For example,
+          <pre class="example">               pkg uninstall image
+</pre>
+          <p class="noindent">removes the <code>image</code> package from the system.  If another installed
+package depends on the <code>image</code> package an error will be issued. 
+The package can be uninstalled anyway by using the <code>-nodeps</code> option. 
+<br><dt>‘<samp><span class="samp">load</span></samp>’<dd>Add named packages to the path.  After loading a package it is
+possible to use the functions provided by the package.  For example,
+          <pre class="example">               pkg load image
+</pre>
+          <p class="noindent">adds the <code>image</code> package to the path.  It is possible to load all
+installed packages at once with the command
+          <pre class="example">               pkg load all
+</pre>
+          <br><dt>‘<samp><span class="samp">unload</span></samp>’<dd>Removes named packages from the path.  After unloading a package it is
+no longer possible to use the functions provided by the package. 
+This command behaves like the <code>load</code> command. 
+<br><dt>‘<samp><span class="samp">list</span></samp>’<dd>Show a list of the currently installed packages.  By requesting one or two
+output argument it is possible to get a list of the currently installed
+packages.  For example,
+          <pre class="example">               installed_packages = pkg list;
+</pre>
+          <p class="noindent">returns a cell array containing a structure for each installed package. 
+The command
+          <pre class="example">               [<var>user_packages</var>, <var>system_packages</var>] = pkg list
+</pre>
+          <p class="noindent">splits the list of installed packages into those who are installed by
+the current user, and those installed by the system administrator. 
+<br><dt>‘<samp><span class="samp">describe</span></samp>’<dd>Show a short description of the named installed packages, with the option
+'-verbose' also list functions provided by the package, e.g.:
+          <pre class="example">                pkg describe -verbose all
+</pre>
+          <p class="noindent">will describe all installed packages and the functions they provide. 
+If one output is requested a cell of structure containing the
+description and list of functions of each package is returned as
+output rather than printed on screen:
+          <pre class="example">                desc = pkg ("describe", "secs1d", "image")
+</pre>
+          <p class="noindent">If any of the requested packages is not installed, pkg returns an
+error, unless a second output is requested:
+          <pre class="example">                [ desc, flag] = pkg ("describe", "secs1d", "image")
+</pre>
+          <p class="noindent"><var>flag</var> will take one of the values "Not installed", "Loaded" or
+"Not loaded" for each of the named packages. 
+<br><dt>‘<samp><span class="samp">prefix</span></samp>’<dd>Set the installation prefix directory.  For example,
+          <pre class="example">               pkg prefix ~/my_octave_packages
+</pre>
+          <p class="noindent">sets the installation prefix to <samp><span class="file">~/my_octave_packages</span></samp>. 
+Packages will be installed in this directory.
+
+          <p>It is possible to get the current installation prefix by requesting an
+output argument.  For example,
+          <pre class="example">               p = pkg prefix
+</pre>
+          <p>The location in which to install the architecture dependent files can be
+independent specified with an addition argument.  For example
+
+          <pre class="example">               pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
+</pre>
+          <br><dt>‘<samp><span class="samp">local_list</span></samp>’<dd>Set the file in which to look for information on the locally
+installed packages.  Locally installed packages are those that are
+typically available only to the current user.  For example
+          <pre class="example">               pkg local_list ~/.octave_packages
+</pre>
+          <p>It is possible to get the current value of local_list with the following
+          <pre class="example">               pkg local_list
+</pre>
+          <br><dt>‘<samp><span class="samp">global_list</span></samp>’<dd>Set the file in which to look for, for information on the globally
+installed packages.  Globally installed packages are those that are
+typically available to all users.  For example
+          <pre class="example">               pkg global_list /usr/share/octave/octave_packages
+</pre>
+          <p>It is possible to get the current value of global_list with the following
+          <pre class="example">               pkg global_list
+</pre>
+          <br><dt>‘<samp><span class="samp">rebuild</span></samp>’<dd>Rebuilds the package database from the installed directories.  This can
+be used in cases where for some reason the package database is corrupted. 
+It can also take the <code>-auto</code> and <code>-noauto</code> options to allow the
+autoloading state of a package to be changed.  For example
+
+          <pre class="example">               pkg rebuild -noauto image
+</pre>
+          <p>will remove the autoloading status of the image package. 
+<br><dt>‘<samp><span class="samp">build</span></samp>’<dd>Builds a binary form of a package or packages.  The binary file produced
+will itself be an Octave package that can be installed normally with
+<code>pkg</code>.  The form of the command to build a binary package is
+
+          <pre class="example">               pkg build builddir image-1.0.0.tar.gz ...
+</pre>
+          <p class="noindent">where <code>builddir</code> is the name of a directory where the temporary
+installation will be produced and the binary packages will be found. 
+The options <code>-verbose</code> and <code>-nodeps</code> are respected, while
+the other options are ignored. 
+</dl>
+        </p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Integer-Arithmetic.html b/doc/interpreter/HTML/Integer-Arithmetic.html
new file mode 100644
index 0000000..34db4e2
--- /dev/null
+++ b/doc/interpreter/HTML/Integer-Arithmetic.html
@@ -0,0 +1,102 @@
+<html lang="en">
+<head>
+<title>Integer Arithmetic - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Integer-Data-Types.html#Integer-Data-Types" title="Integer Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Integer-Arithmetic"></a>
+Up: <a rel="up" accesskey="u" href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a>
+<hr>
+</div>
+
+<h4 class="subsection">4.4.1 Integer Arithmetic</h4>
+
+<p>While many numerical computations can't be carried out in integers,
+Octave does support basic operations like addition and multiplication
+on integers.  The operators <code>+</code>, <code>-</code>, <code>.*</code>, and <code>./</code>
+work on integers of the same type.  So, it is possible to add two 32 bit
+integers, but not to add a 32 bit integer and a 16 bit integer.
+
+   <p>The arithmetic operations on integers are performed by casting the
+integer values to double precision values, performing the operation, and
+then re-casting the values back to the original integer type.  As the
+double precision type of Octave is only capable of representing integers
+with up to 53 bits of precision, it is not possible to perform
+arithmetic with 64 bit integer types.
+
+   <p>When doing integer arithmetic one should consider the possibility of
+underflow and overflow.  This happens when the result of the computation
+can't be represented using the chosen integer type.  As an example it is
+not possible to represent the result of 10 - 20 when using
+unsigned integers.  Octave makes sure that the result of integer
+computations is the integer that is closest to the true result.  So, the
+result of 10 - 20 when using unsigned integers is zero.
+
+   <p>When doing integer division Octave will round the result to the nearest
+integer.  This is different from most programming languages, where the
+result is often floored to the nearest integer.  So, the result of
+<code>int32(5)./int32(8)</code> is <code>1</code>.
+
+<!-- ./general/idivide.m -->
+   <p><a name="doc_002didivide"></a>
+
+<div class="defun">
+— Function File:  <b>idivide</b> (<var>x, y, op</var>)<var><a name="index-idivide-249"></a></var><br>
+<blockquote><p>Integer division with different round rules.  The standard behavior of
+the an integer division such as <var>a</var><code> ./ </code><var>b</var> is to round
+the result to the nearest integer.  This is not always the desired
+behavior and <code>idivide</code> permits integer element-by-element
+division to be performed with different treatment for the fractional
+part of the division as determined by the <var>op</var> flag.  <var>op</var> is
+a string with one of the values:
+
+          <dl>
+<dt>"fix"<dd>Calculate <var>a</var><code> ./ </code><var>b</var> with the fractional part rounded
+towards zero. 
+<br><dt>"round"<dd>Calculate <var>a</var><code> ./ </code><var>b</var> with the fractional part rounded
+towards the nearest integer. 
+<br><dt>"floor"<dd>Calculate <var>a</var><code> ./ </code><var>b</var> with the fractional part rounded
+downwards. 
+<br><dt>"ceil"<dd>Calculate <var>a</var><code> ./ </code><var>b</var> with the fractional part rounded
+upwards. 
+</dl>
+
+     <p class="noindent">If <var>op</var> is not given it is assumed that it is <code>"fix"</code>. 
+An example demonstrating these rounding rules is
+
+     <pre class="example">          idivide (int8 ([-3, 3]), int8 (4), "fix")
+           int8 ([0, 0])
+          idivide (int8 ([-3, 3]), int8 (4), "round")
+           int8 ([-1, 1])
+          idivide (int8 ([-3, 3]), int8 (4), "ceil")
+           int8 ([0, 1])
+          idivide (int8 ([-3, 3]), int8 (4), "floor")
+           int8 ([-1, 0])
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dldivide.html#doc_002dldivide">ldivide</a>, <a href="doc_002drdivide.html#doc_002drdivide">rdivide</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Integer-Conversions.html b/doc/interpreter/HTML/Integer-Conversions.html
new file mode 100644
index 0000000..9519bd3
--- /dev/null
+++ b/doc/interpreter/HTML/Integer-Conversions.html
@@ -0,0 +1,80 @@
+<html lang="en">
+<head>
+<title>Integer Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Table-of-Output-Conversions.html#Table-of-Output-Conversions" title="Table of Output Conversions">
+<link rel="next" href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions" title="Floating-Point Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Integer-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Table-of-Output-Conversions.html#Table-of-Output-Conversions">Table of Output Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.8 Integer Conversions</h4>
+
+<p>This section describes the options for the ‘<samp><span class="samp">%d</span></samp>’, ‘<samp><span class="samp">%i</span></samp>’,
+‘<samp><span class="samp">%o</span></samp>’, ‘<samp><span class="samp">%u</span></samp>’, ‘<samp><span class="samp">%x</span></samp>’, and ‘<samp><span class="samp">%X</span></samp>’ conversion
+specifications.  These conversions print integers in various formats.
+
+   <p>The ‘<samp><span class="samp">%d</span></samp>’ and ‘<samp><span class="samp">%i</span></samp>’ conversion specifications both print an
+numeric argument as a signed decimal number; while ‘<samp><span class="samp">%o</span></samp>’,
+‘<samp><span class="samp">%u</span></samp>’, and ‘<samp><span class="samp">%x</span></samp>’ print the argument as an unsigned octal,
+decimal, or hexadecimal number (respectively).  The ‘<samp><span class="samp">%X</span></samp>’ conversion
+specification is just like ‘<samp><span class="samp">%x</span></samp>’ except that it uses the characters
+‘<samp><span class="samp">ABCDEF</span></samp>’ as digits instead of ‘<samp><span class="samp">abcdef</span></samp>’.
+
+   <p>The following flags are meaningful:
+
+     <dl>
+<dt>‘<samp><span class="samp">-</span></samp>’<dd>Left-justify the result in the field (instead of the normal
+right-justification).
+
+     <br><dt>‘<samp><span class="samp">+</span></samp>’<dd>For the signed ‘<samp><span class="samp">%d</span></samp>’ and ‘<samp><span class="samp">%i</span></samp>’ conversions, print a
+plus sign if the value is positive.
+
+     <br><dt>‘<samp> </samp>’<dd>For the signed ‘<samp><span class="samp">%d</span></samp>’ and ‘<samp><span class="samp">%i</span></samp>’ conversions, if the result
+doesn't start with a plus or minus sign, prefix it with a space
+character instead.  Since the ‘<samp><span class="samp">+</span></samp>’ flag ensures that the result
+includes a sign, this flag is ignored if you supply both of them.
+
+     <br><dt>‘<samp><span class="samp">#</span></samp>’<dd>For the ‘<samp><span class="samp">%o</span></samp>’ conversion, this forces the leading digit to be
+‘<samp><span class="samp">0</span></samp>’, as if by increasing the precision.  For ‘<samp><span class="samp">%x</span></samp>’ or
+‘<samp><span class="samp">%X</span></samp>’, this prefixes a leading ‘<samp><span class="samp">0x</span></samp>’ or ‘<samp><span class="samp">0X</span></samp>’ (respectively)
+to the result.  This doesn't do anything useful for the ‘<samp><span class="samp">%d</span></samp>’,
+‘<samp><span class="samp">%i</span></samp>’, or ‘<samp><span class="samp">%u</span></samp>’ conversions.
+
+     <br><dt>‘<samp><span class="samp">0</span></samp>’<dd>Pad the field with zeros instead of spaces.  The zeros are placed after
+any indication of sign or base.  This flag is ignored if the ‘<samp><span class="samp">-</span></samp>’
+flag is also specified, or if a precision is specified. 
+</dl>
+
+   <p>If a precision is supplied, it specifies the minimum number of digits to
+appear; leading zeros are produced if necessary.  If you don't specify a
+precision, the number is printed with as many digits as it needs.  If
+you convert a value of zero with an explicit precision of zero, then no
+characters at all are produced.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Integer-Data-Types.html b/doc/interpreter/HTML/Integer-Data-Types.html
new file mode 100644
index 0000000..657be92
--- /dev/null
+++ b/doc/interpreter/HTML/Integer-Data-Types.html
@@ -0,0 +1,245 @@
+<html lang="en">
+<head>
+<title>Integer Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Single-Precision-Data-Types.html#Single-Precision-Data-Types" title="Single Precision Data Types">
+<link rel="next" href="Bit-Manipulations.html#Bit-Manipulations" title="Bit Manipulations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Integer-Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a>,
+Previous: <a rel="previous" accesskey="p" href="Single-Precision-Data-Types.html#Single-Precision-Data-Types">Single Precision Data Types</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.4 Integer Data Types</h3>
+
+<p>Octave supports integer matrices as an alternative to using double
+precision.  It is possible to use both signed and unsigned integers
+represented by 8, 16, 32, or 64 bits.  It should be noted that most
+computations require floating point data, meaning that integers will
+often change type when involved in numeric computations.  For this
+reason integers are most often used to store data, and not for
+calculations.
+
+   <p>In general most integer matrices are created by casting
+existing matrices to integers.  The following example shows how to cast
+a matrix into 32 bit integers.
+
+<pre class="example">     float = rand (2, 2)
+           float = 0.37569   0.92982
+                     0.11962   0.50876
+     integer = int32 (float)
+           integer = 0  1
+                       0  1
+</pre>
+   <p class="noindent">As can be seen, floating point values are rounded to the nearest integer
+when converted.
+
+<!-- data.cc -->
+   <p><a name="doc_002disinteger"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isinteger</b> (<var>x</var>)<var><a name="index-isinteger-235"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is an integer object (int8, uint8, int16, etc.). 
+Note that <code>isinteger (14)</code> is false because numeric constants in
+Octave are double precision floating point values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disreal.html#doc_002disreal">isreal</a>, <a href="doc_002disnumeric.html#doc_002disnumeric">isnumeric</a>, <a href="doc_002dclass.html#doc_002dclass">class</a>, <a href="doc_002disa.html#doc_002disa">isa</a>. 
+</p></blockquote></div>
+
+<!-- ov-int8.cc -->
+   <p><a name="doc_002dint8"></a>
+
+<div class="defun">
+— Built-in Function:  <b>int8</b> (<var>x</var>)<var><a name="index-int8-236"></a></var><br>
+<blockquote><p>Convert <var>x</var> to 8-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-uint8.cc -->
+   <p><a name="doc_002duint8"></a>
+
+<div class="defun">
+— Built-in Function:  <b>uint8</b> (<var>x</var>)<var><a name="index-uint8-237"></a></var><br>
+<blockquote><p>Convert <var>x</var> to unsigned 8-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-int16.cc -->
+   <p><a name="doc_002dint16"></a>
+
+<div class="defun">
+— Built-in Function:  <b>int16</b> (<var>x</var>)<var><a name="index-int16-238"></a></var><br>
+<blockquote><p>Convert <var>x</var> to 16-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-uint16.cc -->
+   <p><a name="doc_002duint16"></a>
+
+<div class="defun">
+— Built-in Function:  <b>uint16</b> (<var>x</var>)<var><a name="index-uint16-239"></a></var><br>
+<blockquote><p>Convert <var>x</var> to unsigned 16-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-int32.cc -->
+   <p><a name="doc_002dint32"></a>
+
+<div class="defun">
+— Built-in Function:  <b>int32</b> (<var>x</var>)<var><a name="index-int32-240"></a></var><br>
+<blockquote><p>Convert <var>x</var> to 32-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-uint32.cc -->
+   <p><a name="doc_002duint32"></a>
+
+<div class="defun">
+— Built-in Function:  <b>uint32</b> (<var>x</var>)<var><a name="index-uint32-241"></a></var><br>
+<blockquote><p>Convert <var>x</var> to unsigned 32-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-int64.cc -->
+   <p><a name="doc_002dint64"></a>
+
+<div class="defun">
+— Built-in Function:  <b>int64</b> (<var>x</var>)<var><a name="index-int64-242"></a></var><br>
+<blockquote><p>Convert <var>x</var> to 64-bit integer type. 
+</p></blockquote></div>
+
+<!-- ov-uint64.cc -->
+   <p><a name="doc_002duint64"></a>
+
+<div class="defun">
+— Built-in Function:  <b>uint64</b> (<var>x</var>)<var><a name="index-uint64-243"></a></var><br>
+<blockquote><p>Convert <var>x</var> to unsigned 64-bit integer type. 
+</p></blockquote></div>
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dintmax"></a>
+
+<div class="defun">
+— Built-in Function:  <b>intmax</b> (<var>type</var>)<var><a name="index-intmax-244"></a></var><br>
+<blockquote><p>Return the largest integer that can be represented in an integer type. 
+The variable <var>type</var> can be
+
+          <dl>
+<dt><code>int8</code><dd>signed 8-bit integer. 
+<br><dt><code>int16</code><dd>signed 16-bit integer. 
+<br><dt><code>int32</code><dd>signed 32-bit integer. 
+<br><dt><code>int64</code><dd>signed 64-bit integer. 
+<br><dt><code>uint8</code><dd>unsigned 8-bit integer. 
+<br><dt><code>uint16</code><dd>unsigned 16-bit integer. 
+<br><dt><code>uint32</code><dd>unsigned 32-bit integer. 
+<br><dt><code>uint64</code><dd>unsigned 64-bit integer. 
+</dl>
+
+        <p>The default for <var>type</var> is <code>uint32</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dintmin.html#doc_002dintmin">intmin</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+<!-- bitfcns.cc -->
+   <p><a name="doc_002dintmin"></a>
+
+<div class="defun">
+— Built-in Function:  <b>intmin</b> (<var>type</var>)<var><a name="index-intmin-245"></a></var><br>
+<blockquote><p>Return the smallest integer that can be represented in an integer type. 
+The variable <var>type</var> can be
+
+          <dl>
+<dt><code>int8</code><dd>signed 8-bit integer. 
+<br><dt><code>int16</code><dd>signed 16-bit integer. 
+<br><dt><code>int32</code><dd>signed 32-bit integer. 
+<br><dt><code>int64</code><dd>signed 64-bit integer. 
+<br><dt><code>uint8</code><dd>unsigned 8-bit integer. 
+<br><dt><code>uint16</code><dd>unsigned 16-bit integer. 
+<br><dt><code>uint32</code><dd>unsigned 32-bit integer. 
+<br><dt><code>uint64</code><dd>unsigned 64-bit integer. 
+</dl>
+
+        <p>The default for <var>type</var> is <code>uint32</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dintmax.html#doc_002dintmax">intmax</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/intwarning.m -->
+   <p><a name="doc_002dintwarning"></a>
+
+<div class="defun">
+— Function File:  <b>intwarning</b> (<var>action</var>)<var><a name="index-intwarning-246"></a></var><br>
+— Function File:  <b>intwarning</b> (<var>s</var>)<var><a name="index-intwarning-247"></a></var><br>
+— Function File: <var>s</var> = <b>intwarning</b> (<var><small class="dots">...</small></var>)<var><a name="index-intwarning-248"></a></var><br>
+<blockquote><p>Control the state of the warning for integer conversions and math
+operations.
+
+          <dl>
+<dt>"query"<dd>The state of the Octave integer conversion and math warnings is
+queried.  If there is no output argument, then the state is printed. 
+Otherwise it is returned in a structure with the fields "identifier"
+and "state".
+
+          <!-- Set example in small font to prevent overfull line -->
+          <pre class="smallexample">               intwarning ("query")
+               The state of warning "Octave:int-convert-nan" is "off"
+               The state of warning "Octave:int-convert-non-int-val" is "off"
+               The state of warning "Octave:int-convert-overflow" is "off"
+               The state of warning "Octave:int-math-overflow" is "off"
+</pre>
+          <br><dt>"on"<dd>Turn integer conversion and math warnings "on".  If there is no output
+argument, then nothing is printed.  Otherwise the original state of
+the state of the integer conversion and math warnings is returned in
+a structure array.
+
+          <br><dt>"off"<dd>Turn integer conversion and math warnings "on".  If there is no output
+argument, then nothing is printed.  Otherwise the original state of
+the state of the integer conversion and math warnings is returned in
+a structure array. 
+</dl>
+
+        <p>The original state of the integer warnings can be restored by passing
+the structure array returned by <code>intwarning</code> to a later call to
+<code>intwarning</code>.  For example
+
+     <pre class="example">          s = intwarning ("off");
+          ...
+          intwarning (s);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwarning.html#doc_002dwarning">warning</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Integer-Arithmetic.html#Integer-Arithmetic">Integer Arithmetic</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Interacting-with-plots.html b/doc/interpreter/HTML/Interacting-with-plots.html
new file mode 100644
index 0000000..1d05a6e
--- /dev/null
+++ b/doc/interpreter/HTML/Interacting-with-plots.html
@@ -0,0 +1,86 @@
+<html lang="en">
+<head>
+<title>Interacting with plots - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Printing-Plots.html#Printing-Plots" title="Printing Plots">
+<link rel="next" href="Test-Plotting-Functions.html#Test-Plotting-Functions" title="Test Plotting Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Interacting-with-plots"></a>
+Next: <a rel="next" accesskey="n" href="Test-Plotting-Functions.html#Test-Plotting-Functions">Test Plotting Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Printing-Plots.html#Printing-Plots">Printing Plots</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.7 Interacting with plots</h4>
+
+<p>The user can select points on a plot with the <code>ginput</code> function or
+selection the position at which to place text on the plot with the
+<code>gtext</code> function using the mouse.
+
+<!-- ./plot/ginput.m -->
+   <p><a name="doc_002dginput"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>y</var>, <var>buttons</var>] = <b>ginput</b> (<var>n</var>)<var><a name="index-ginput-1099"></a></var><br>
+<blockquote><p>Return which mouse buttons were pressed and keys were hit on the current
+figure.  If <var>n</var> is defined, then wait for <var>n</var> mouse clicks
+before returning.  If <var>n</var> is not defined, then <code>ginput</code> will
+loop until the return key is pressed. 
+</p></blockquote></div>
+
+<!-- ./plot/waitforbuttonpress.m -->
+   <p><a name="doc_002dwaitforbuttonpress"></a>
+
+<div class="defun">
+— Function File: <var>b</var> = <b>waitforbuttonpress</b> ()<var><a name="index-waitforbuttonpress-1100"></a></var><br>
+<blockquote><p>Wait for button or mouse press.over a figure window.  The value of
+<var>b</var> returns 0 if a mouse button was pressed or 1 is a key was
+pressed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dginput.html#doc_002dginput">ginput</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/gtext.m -->
+   <p><a name="doc_002dgtext"></a>
+
+<div class="defun">
+— Function File:  <b>gtext</b> (<var>s</var>)<var><a name="index-gtext-1101"></a></var><br>
+— Function File:  <b>gtext</b> (<var>{s1; s2; <small class="dots">...</small>}</var>)<var><a name="index-gtext-1102"></a></var><br>
+— Function File:  <b>gtext</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-gtext-1103"></a></var><br>
+<blockquote><p>Place text on the current figure using the mouse.  The text is defined
+by the string <var>s</var>.  If <var>s</var> is a cell array, each element of the cell
+array is written to a separate line.  Additional arguments are passed to
+the underlying text object as properties. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dginput.html#doc_002dginput">ginput</a>, <a href="doc_002dtext.html#doc_002dtext">text</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Interaction-with-gnuplot.html b/doc/interpreter/HTML/Interaction-with-gnuplot.html
new file mode 100644
index 0000000..1970b6e
--- /dev/null
+++ b/doc/interpreter/HTML/Interaction-with-gnuplot.html
@@ -0,0 +1,59 @@
+<html lang="en">
+<head>
+<title>Interaction with gnuplot - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-backends.html#Graphics-backends" title="Graphics backends">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Interaction-with-gnuplot"></a>
+Up: <a rel="up" accesskey="u" href="Graphics-backends.html#Graphics-backends">Graphics backends</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.9.1 Interaction with <code>gnuplot</code></h5>
+
+<p><a name="index-gnuplot-interaction-1257"></a>
+<!-- ./plot/gnuplot_binary.m -->
+<a name="doc_002dgnuplot_005fbinary"></a>
+
+<div class="defun">
+— Loadable Function: <var>val</var> = <b>gnuplot_binary</b> ()<var><a name="index-gnuplot_005fbinary-1258"></a></var><br>
+— Loadable Function: <var>old_val</var> = <b>gnuplot_binary</b> (<var>new_val</var>)<var><a name="index-gnuplot_005fbinary-1259"></a></var><br>
+<blockquote><p>Query or set the name of the program invoked by the plot command. 
+The default value <code>\"gnuplot\"</code>.  See <a href="Installation.html#Installation">Installation</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Interpolation-on-Scattered-Data.html b/doc/interpreter/HTML/Interpolation-on-Scattered-Data.html
new file mode 100644
index 0000000..31ca4cd
--- /dev/null
+++ b/doc/interpreter/HTML/Interpolation-on-Scattered-Data.html
@@ -0,0 +1,132 @@
+<html lang="en">
+<head>
+<title>Interpolation on Scattered Data - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Geometry.html#Geometry" title="Geometry">
+<link rel="prev" href="Convex-Hull.html#Convex-Hull" title="Convex Hull">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Interpolation-on-Scattered-Data"></a>
+Previous: <a rel="previous" accesskey="p" href="Convex-Hull.html#Convex-Hull">Convex Hull</a>,
+Up: <a rel="up" accesskey="u" href="Geometry.html#Geometry">Geometry</a>
+<hr>
+</div>
+
+<h3 class="section">29.4 Interpolation on Scattered Data</h3>
+
+<p>An important use of the Delaunay tessellation is that it can be used to
+interpolate from scattered data to an arbitrary set of points.  To do
+this the N-simplex of the known set of points is calculated with
+<code>delaunay</code>, <code>delaunay3</code> or <code>delaunayn</code>.  Then the
+simplicies in to which the desired points are found are
+identified.  Finally the vertices of the simplicies are used to
+interpolate to the desired points.  The functions that perform this
+interpolation are <code>griddata</code>, <code>griddata3</code> and
+<code>griddatan</code>.
+
+<!-- ./geometry/griddata.m -->
+   <p><a name="doc_002dgriddata"></a>
+
+<div class="defun">
+— Function File: <var>zi</var> = <b>griddata</b> (<var>x, y, z, xi, yi, method</var>)<var><a name="index-griddata-2118"></a></var><br>
+— Function File: [<var>xi</var>, <var>yi</var>, <var>zi</var>] = <b>griddata</b> (<var>x, y, z, xi, yi, method</var>)<var><a name="index-griddata-2119"></a></var><br>
+<blockquote>
+        <p>Generate a regular mesh from irregular data using interpolation. 
+The function is defined by <var>z</var><code> = f (</code><var>x</var><code>, </code><var>y</var><code>)</code>. 
+The interpolation points are all <code>(</code><var>xi</var><code>, </code><var>yi</var><code>)</code>.  If
+<var>xi</var>, <var>yi</var> are vectors then they are made into a 2D mesh.
+
+        <p>The interpolation method can be <code>"nearest"</code>, <code>"cubic"</code> or
+<code>"linear"</code>.  If method is omitted it defaults to <code>"linear"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/griddata3.m -->
+   <p><a name="doc_002dgriddata3"></a>
+
+<div class="defun">
+— Function File: <var>vi</var> = <b>griddata3</b> (<var>x, y, z, v xi, yi, zi, method, options</var>)<var><a name="index-griddata3-2120"></a></var><br>
+<blockquote>
+        <p>Generate a regular mesh from irregular data using interpolation. 
+The function is defined by <var>y</var><code> = f (</code><var>x</var><code>,</code><var>y</var><code>,</code><var>z</var><code>)</code>. 
+The interpolation points are all <var>xi</var>.
+
+        <p>The interpolation method can be <code>"nearest"</code> or <code>"linear"</code>. 
+If method is omitted it defaults to <code>"linear"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgriddata.html#doc_002dgriddata">griddata</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/griddatan.m -->
+   <p><a name="doc_002dgriddatan"></a>
+
+<div class="defun">
+— Function File: <var>yi</var> = <b>griddatan</b> (<var>x, y, xi, method, options</var>)<var><a name="index-griddatan-2121"></a></var><br>
+<blockquote>
+        <p>Generate a regular mesh from irregular data using interpolation. 
+The function is defined by <var>y</var><code> = f (</code><var>x</var><code>)</code>. 
+The interpolation points are all <var>xi</var>.
+
+        <p>The interpolation method can be <code>"nearest"</code> or <code>"linear"</code>. 
+If method is omitted it defaults to <code>"linear"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgriddata.html#doc_002dgriddata">griddata</a>, <a href="doc_002ddelaunayn.html#doc_002ddelaunayn">delaunayn</a>. 
+</p></blockquote></div>
+
+   <p>An example of the use of the <code>griddata</code> function is
+
+<pre class="example">     rand("state",1);
+     x=2*rand(1000,1)-1;
+     y=2*rand(size(x))-1;
+     z=sin(2*(x.^2+y.^2));
+     [xx,yy]=meshgrid(linspace(-1,1,32));
+     griddata(x,y,z,xx,yy);
+</pre>
+   <p class="noindent">that interpolates from a random scattering of points, to a uniform
+grid.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2006, 2007, 2008, 2009 -->
+<!-- John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Interpolation.html b/doc/interpreter/HTML/Interpolation.html
new file mode 100644
index 0000000..4192188
--- /dev/null
+++ b/doc/interpreter/HTML/Interpolation.html
@@ -0,0 +1,42 @@
+<html lang="en">
+<head>
+<title>Interpolation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="next" href="Geometry.html#Geometry" title="Geometry">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Interpolation"></a>
+Next: <a rel="next" accesskey="n" href="Geometry.html#Geometry">Geometry</a>,
+Previous: <a rel="previous" accesskey="p" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">28 Interpolation</h2>
+
+<ul class="menu">
+<li><a accesskey="1" href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a>
+<li><a accesskey="2" href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a>
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Introduction.html b/doc/interpreter/HTML/Introduction.html
new file mode 100644
index 0000000..c46f9fb
--- /dev/null
+++ b/doc/interpreter/HTML/Introduction.html
@@ -0,0 +1,61 @@
+<html lang="en">
+<head>
+<title>Introduction - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Preface.html#Preface" title="Preface">
+<link rel="next" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Introduction"></a>
+Next: <a rel="next" accesskey="n" href="Getting-Started.html#Getting-Started">Getting Started</a>,
+Previous: <a rel="previous" accesskey="p" href="Preface.html#Preface">Preface</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">1 A Brief Introduction to Octave</h2>
+
+<p><a name="index-introduction-7"></a>
+GNU Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient interactive command line
+interface for solving linear and nonlinear problems numerically, and
+for performing other numerical experiments.  It may also be used as a
+batch-oriented language for data processing.
+
+   <p>GNU Octave is freely redistributable software.  You may redistribute
+it and/or modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation.  The GPL is included in
+this manual in <a href="Copying.html#Copying">Copying</a>.
+
+   <p>This manual provides comprehensive documentation on how to install,
+run, use, and extend GNU Octave.  Additional chapters describe how
+to report bugs and help contribute code.
+
+   <p>This document corresponds to Octave version 3.2.4.
+
+<ul class="menu">
+<li><a accesskey="1" href="Running-Octave.html#Running-Octave">Running Octave</a>
+<li><a accesskey="2" href="Simple-Examples.html#Simple-Examples">Simple Examples</a>
+<li><a accesskey="3" href="Conventions.html#Conventions">Conventions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Invoking-Octave-from-the-Command-Line.html b/doc/interpreter/HTML/Invoking-Octave-from-the-Command-Line.html
new file mode 100644
index 0000000..2c3e405
--- /dev/null
+++ b/doc/interpreter/HTML/Invoking-Octave-from-the-Command-Line.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Invoking Octave from the Command Line - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="next" href="Quitting-Octave.html#Quitting-Octave" title="Quitting Octave">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Invoking-Octave-from-the-Command-Line"></a>
+Next: <a rel="next" accesskey="n" href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.1 Invoking Octave from the Command Line</h3>
+
+<p>Normally, Octave is used interactively by running the program
+‘<samp><span class="samp">octave</span></samp>’ without any arguments.  Once started, Octave reads
+commands from the terminal until you tell it to exit.
+
+   <p>You can also specify the name of a file on the command line, and Octave
+will read and execute the commands from the named file and then exit
+when it is finished.
+
+   <p>You can further control how Octave starts by using the command-line
+options described in the next section, and Octave itself can remind you
+of the options available.  Type ‘<samp><span class="samp">octave --help</span></samp>’ to display all
+available options and briefly describe their use (‘<samp><span class="samp">octave -h</span></samp>’ is a
+shorter equivalent).
+
+<ul class="menu">
+<li><a accesskey="1" href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a>
+<li><a accesskey="2" href="Startup-Files.html#Startup-Files">Startup Files</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Issuing-Warnings.html b/doc/interpreter/HTML/Issuing-Warnings.html
new file mode 100644
index 0000000..f259112
--- /dev/null
+++ b/doc/interpreter/HTML/Issuing-Warnings.html
@@ -0,0 +1,104 @@
+<html lang="en">
+<head>
+<title>Issuing Warnings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Handling-Warnings.html#Handling-Warnings" title="Handling Warnings">
+<link rel="next" href="Enabling-and-Disabling-Warnings.html#Enabling-and-Disabling-Warnings" title="Enabling and Disabling Warnings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Issuing-Warnings"></a>
+Next: <a rel="next" accesskey="n" href="Enabling-and-Disabling-Warnings.html#Enabling-and-Disabling-Warnings">Enabling and Disabling Warnings</a>,
+Up: <a rel="up" accesskey="u" href="Handling-Warnings.html#Handling-Warnings">Handling Warnings</a>
+<hr>
+</div>
+
+<h4 class="subsection">12.2.1 Issuing Warnings</h4>
+
+<p>It is possible to issue warnings from any code using the <code>warning</code>
+function.  In its most simple form, the <code>warning</code> function takes a
+string describing the warning as its input argument.  As an example,
+the following code controls if the variable ‘<samp><span class="samp">a</span></samp>’ is non-negative,
+and if not issues a warning and sets ‘<samp><span class="samp">a</span></samp>’ to zero.
+
+<pre class="example">     a = -1;
+     if (a < 0)
+       warning ("'a' must be non-negative.  Setting 'a' to zero.");
+       a = 0;
+     endif
+          -| 'a' must be non-negative.  Setting 'a' to zero.
+</pre>
+   <p>Since warnings aren't fatal to a running program, it is not possible
+to catch a warning using the <code>try</code> statement or something similar. 
+It is however possible to access the last warning as a string using the
+<code>lastwarn</code> function.
+
+   <p>It is also possible to assign an identification string to a warning. 
+If a warning has such an ID the user can enable and disable this warning
+as will be described in the next section.  To assign an ID to a warning,
+simply call <code>warning</code> with two string arguments, where the first
+is the identification string, and the second is the actual warning.
+
+<!-- error.cc -->
+   <p><a name="doc_002dwarning"></a>
+
+<div class="defun">
+— Built-in Function:  <b>warning</b> (<var>template, <small class="dots">...</small></var>)<var><a name="index-warning-678"></a></var><br>
+— Built-in Function:  <b>warning</b> (<var>id, template, <small class="dots">...</small></var>)<var><a name="index-warning-679"></a></var><br>
+<blockquote><p>Format the optional arguments under the control of the template string
+<var>template</var> using the same rules as the <code>printf</code> family of
+functions (see <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>) and print the resulting message
+on the <code>stderr</code> stream.  The message is prefixed by the character
+string ‘<samp><span class="samp">warning: </span></samp>’. 
+You should use this function when you want to notify the user
+of an unusual condition, but only when it makes sense for your program
+to go on.
+
+        <p>The optional message identifier allows users to enable or disable
+warnings tagged by <var>id</var>.  The special identifier ‘<samp><span class="samp">"all"</span></samp>’ may
+be used to set the state of all warnings.
+
+   — Built-in Function:  <b>warning</b> (<var>"on", id</var>)<var><a name="index-warning-680"></a></var><br>
+— Built-in Function:  <b>warning</b> (<var>"off", id</var>)<var><a name="index-warning-681"></a></var><br>
+— Built-in Function:  <b>warning</b> (<var>"error", id</var>)<var><a name="index-warning-682"></a></var><br>
+— Built-in Function:  <b>warning</b> (<var>"query", id</var>)<var><a name="index-warning-683"></a></var><br>
+<blockquote><p>Set or query the state of a particular warning using the identifier
+<var>id</var>.  If the identifier is omitted, a value of ‘<samp><span class="samp">"all"</span></samp>’ is
+assumed.  If you set the state of a warning to ‘<samp><span class="samp">"error"</span></samp>’, the
+warning named by <var>id</var> is handled as if it were an error instead. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwarning_005fids.html#doc_002dwarning_005fids">warning_ids</a>. 
+</p></blockquote></div>
+
+<!-- error.cc -->
+   <p><a name="doc_002dlastwarn"></a>
+
+<div class="defun">
+— Built-in Function: [<var>msg</var>, <var>msgid</var>] = <b>lastwarn</b> (<var>msg, msgid</var>)<var><a name="index-lastwarn-684"></a></var><br>
+<blockquote><p>Without any arguments, return the last warning message.  With one
+argument, set the last warning message to <var>msg</var>.  With two arguments,
+also set the last message identifier. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Iterative-Techniques.html b/doc/interpreter/HTML/Iterative-Techniques.html
new file mode 100644
index 0000000..770b857
--- /dev/null
+++ b/doc/interpreter/HTML/Iterative-Techniques.html
@@ -0,0 +1,401 @@
+<html lang="en">
+<head>
+<title>Iterative Techniques - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices.html#Sparse-Matrices" title="Sparse Matrices">
+<link rel="prev" href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra" title="Sparse Linear Algebra">
+<link rel="next" href="Real-Life-Example.html#Real-Life-Example" title="Real Life Example">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Iterative-Techniques"></a>
+Next: <a rel="next" accesskey="n" href="Real-Life-Example.html#Real-Life-Example">Real Life Example</a>,
+Previous: <a rel="previous" accesskey="p" href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">21.3 Iterative Techniques applied to sparse matrices</h3>
+
+<p>The left division <code>\</code> and right division <code>/</code> operators,
+discussed in the previous section, use direct solvers to resolve a
+linear equation of the form <var>x</var><code> = </code><var>A</var><code> \ </code><var>b</var> or
+<var>x</var><code> = </code><var>b</var><code> / </code><var>A</var>.  Octave equally includes a number of
+functions to solve sparse linear equations using iterative techniques.
+
+<!-- ./sparse/pcg.m -->
+   <p><a name="doc_002dpcg"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>pcg</b> (<var>a, b, tol, maxit, m1, m2, x0, <small class="dots">...</small></var>)<var><a name="index-pcg-1752"></a></var><br>
+— Function File: [<var>x</var>, <var>flag</var>, <var>relres</var>, <var>iter</var>, <var>resvec</var>, <var>eigest</var>] = <b>pcg</b> (<var><small class="dots">...</small></var>)<var><a name="index-pcg-1753"></a></var><br>
+<blockquote>
+        <p>Solves the linear system of equations <var>a</var><code> * </code><var>x</var><code> =
+</code><var>b</var> by means of the Preconditioned Conjugate Gradient iterative
+method.  The input arguments are
+
+          <ul>
+<li><var>a</var> can be either a square (preferably sparse) matrix or a
+function handle, inline function or string containing the name
+of a function which computes <var>a</var><code> * </code><var>x</var>.  In principle
+<var>a</var> should be symmetric and positive definite; if <code>pcg</code>
+finds <var>a</var> to not be positive definite, you will get a warning
+message and the <var>flag</var> output parameter will be set.
+
+          <li><var>b</var> is the right hand side vector.
+
+          <li><var>tol</var> is the required relative tolerance for the residual error,
+<var>b</var><code> - </code><var>a</var><code> * </code><var>x</var>.  The iteration stops if <code>norm
+(</code><var>b</var><code> - </code><var>a</var><code> * </code><var>x</var><code>) <= </code><var>tol</var><code> * norm (</code><var>b</var><code> - </code><var>a</var><code> *
+</code><var>x0</var><code>)</code>.  If <var>tol</var> is empty or is omitted, the function sets
+<var>tol</var><code> = 1e-6</code> by default.
+
+          <li><var>maxit</var> is the maximum allowable number of iterations; if
+<code>[]</code> is supplied for <code>maxit</code>, or <code>pcg</code> has less
+arguments, a default value equal to 20 is used.
+
+          <li><var>m</var> = <var>m1</var> * <var>m2</var> is the (left) preconditioning matrix, so that the iteration is
+(theoretically) equivalent to solving by <code>pcg</code> <var>P</var><code> *
+</code><var>x</var><code> = </code><var>m</var><code> \ </code><var>b</var>, with <var>P</var><code> = </code><var>m</var><code> \ </code><var>a</var>. 
+Note that a proper choice of the preconditioner may dramatically
+improve the overall performance of the method.  Instead of matrices
+<var>m1</var> and <var>m2</var>, the user may pass two functions which return
+the results of applying the inverse of <var>m1</var> and <var>m2</var> to
+a vector (usually this is the preferred way of using the preconditioner). 
+If <code>[]</code> is supplied for <var>m1</var>, or <var>m1</var> is omitted, no
+preconditioning is applied.  If <var>m2</var> is omitted, <var>m</var> = <var>m1</var>
+will be used as preconditioner.
+
+          <li><var>x0</var> is the initial guess.  If <var>x0</var> is empty or omitted, the
+function sets <var>x0</var> to a zero vector by default. 
+</ul>
+
+        <p>The arguments which follow <var>x0</var> are treated as parameters, and
+passed in a proper way to any of the functions (<var>a</var> or <var>m</var>)
+which are passed to <code>pcg</code>.  See the examples below for further
+details.  The output arguments are
+
+          <ul>
+<li><var>x</var> is the computed approximation to the solution of
+<var>a</var><code> * </code><var>x</var><code> = </code><var>b</var>.
+
+          <li><var>flag</var> reports on the convergence.  <var>flag</var><code> = 0</code> means
+the solution converged and the tolerance criterion given by <var>tol</var>
+is satisfied.  <var>flag</var><code> = 1</code> means that the <var>maxit</var> limit
+for the iteration count was reached.  <var>flag</var><code> = 3</code> reports that
+the (preconditioned) matrix was found not positive definite.
+
+          <li><var>relres</var> is the ratio of the final residual to its initial value,
+measured in the Euclidean norm.
+
+          <li><var>iter</var> is the actual number of iterations performed.
+
+          <li><var>resvec</var> describes the convergence history of the method. 
+<var>resvec</var><code> (i,1)</code> is the Euclidean norm of the residual, and
+<var>resvec</var><code> (i,2)</code> is the preconditioned residual norm,
+after the (<var>i</var>-1)-th iteration, <var>i</var><code> =
+1, 2, ..., </code><var>iter</var><code>+1</code>.  The preconditioned residual norm
+is defined as
+<code>norm (</code><var>r</var><code>) ^ 2 = </code><var>r</var><code>' * (</code><var>m</var><code> \ </code><var>r</var><code>)</code> where
+<var>r</var><code> = </code><var>b</var><code> - </code><var>a</var><code> * </code><var>x</var>, see also the
+description of <var>m</var>.  If <var>eigest</var> is not required, only
+<var>resvec</var><code> (:,1)</code> is returned.
+
+          <li><var>eigest</var> returns the estimate for the smallest <var>eigest</var><code>
+(1)</code> and largest <var>eigest</var><code> (2)</code> eigenvalues of the
+preconditioned matrix <var>P</var><code> = </code><var>m</var><code> \ </code><var>a</var>.  In
+particular, if no preconditioning is used, the estimates for the
+extreme eigenvalues of <var>a</var> are returned.  <var>eigest</var><code> (1)</code>
+is an overestimate and <var>eigest</var><code> (2)</code> is an underestimate,
+so that <var>eigest</var><code> (2) / </code><var>eigest</var><code> (1)</code> is a lower bound
+for <code>cond (</code><var>P</var><code>, 2)</code>, which nevertheless in the limit should
+theoretically be equal to the actual value of the condition number. 
+The method which computes <var>eigest</var> works only for symmetric positive
+definite <var>a</var> and <var>m</var>, and the user is responsible for
+verifying this assumption. 
+</ul>
+
+        <p>Let us consider a trivial problem with a diagonal matrix (we exploit the
+sparsity of A)
+
+     <pre class="example">          	n = 10;
+          	a = diag (sparse (1:n));
+          	b = rand (n, 1);
+               [l, u, p, q] = luinc (a, 1.e-3);
+</pre>
+        <p><span class="sc">Example 1:</span> Simplest use of <code>pcg</code>
+
+     <pre class="example">            x = pcg(A,b)
+</pre>
+        <p><span class="sc">Example 2:</span> <code>pcg</code> with a function which computes
+<var>a</var><code> * </code><var>x</var>
+
+     <pre class="example">            function y = apply_a (x)
+              y = [1:N]'.*x;
+            endfunction
+          
+            x = pcg ("apply_a", b)
+</pre>
+        <p><span class="sc">Example 3:</span> <code>pcg</code> with a preconditioner: <var>l</var> * <var>u</var>
+
+     <pre class="example">          x = pcg (a, b, 1.e-6, 500, l*u);
+</pre>
+        <p><span class="sc">Example 4:</span> <code>pcg</code> with a preconditioner: <var>l</var> * <var>u</var>. 
+Faster than <span class="sc">Example 3</span> since lower and upper triangular matrices
+are easier to invert
+
+     <pre class="example">          x = pcg (a, b, 1.e-6, 500, l, u);
+</pre>
+        <p><span class="sc">Example 5:</span> Preconditioned iteration, with full diagnostics.  The
+preconditioner (quite strange, because even the original matrix
+<var>a</var> is trivial) is defined as a function
+
+     <pre class="example">            function y = apply_m (x)
+              k = floor (length (x) - 2);
+              y = x;
+              y(1:k) = x(1:k)./[1:k]';
+            endfunction
+          
+            [x, flag, relres, iter, resvec, eigest] = ...
+                               pcg (a, b, [], [], "apply_m");
+            semilogy (1:iter+1, resvec);
+</pre>
+        <p><span class="sc">Example 6:</span> Finally, a preconditioner which depends on a
+parameter <var>k</var>.
+
+     <pre class="example">            function y = apply_M (x, varargin)
+            K = varargin{1};
+            y = x;
+            y(1:K) = x(1:K)./[1:K]';
+            endfunction
+          
+            [x, flag, relres, iter, resvec, eigest] = ...
+                 pcg (A, b, [], [], "apply_m", [], [], 3)
+</pre>
+        <p><span class="sc">References</span>
+
+        <p>	[1] C.T.Kelley, 'Iterative methods for linear and nonlinear equations',
+	SIAM, 1995 (the base PCG algorithm)
+
+        <p>	[2] Y.Saad, 'Iterative methods for sparse linear systems', PWS 1996
+	(condition number estimate from PCG) Revised version of this book is
+	available online at http://www-users.cs.umn.edu/~saad/books.html
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>, <a href="doc_002dpcr.html#doc_002dpcr">pcr</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/pcr.m -->
+   <p><a name="doc_002dpcr"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>pcr</b> (<var>a, b, tol, maxit, m, x0, <small class="dots">...</small></var>)<var><a name="index-pcr-1754"></a></var><br>
+— Function File: [<var>x</var>, <var>flag</var>, <var>relres</var>, <var>iter</var>, <var>resvec</var>] = <b>pcr</b> (<var><small class="dots">...</small></var>)<var><a name="index-pcr-1755"></a></var><br>
+<blockquote>
+        <p>Solves the linear system of equations <var>a</var><code> * </code><var>x</var><code> =
+</code><var>b</var> by means of the Preconditioned Conjugate Residuals iterative
+method.  The input arguments are
+
+          <ul>
+<li><var>a</var> can be either a square (preferably sparse) matrix or a
+function handle, inline function or string containing the name
+of a function which computes <var>a</var><code> * </code><var>x</var>.  In principle
+<var>a</var> should be symmetric and non-singular; if <code>pcr</code>
+finds <var>a</var> to be numerically singular, you will get a warning
+message and the <var>flag</var> output parameter will be set.
+
+          <li><var>b</var> is the right hand side vector.
+
+          <li><var>tol</var> is the required relative tolerance for the residual error,
+<var>b</var><code> - </code><var>a</var><code> * </code><var>x</var>.  The iteration stops if <code>norm
+(</code><var>b</var><code> - </code><var>a</var><code> * </code><var>x</var><code>) <= </code><var>tol</var><code> * norm (</code><var>b</var><code> - </code><var>a</var><code> *
+</code><var>x0</var><code>)</code>.  If <var>tol</var> is empty or is omitted, the function sets
+<var>tol</var><code> = 1e-6</code> by default.
+
+          <li><var>maxit</var> is the maximum allowable number of iterations; if
+<code>[]</code> is supplied for <code>maxit</code>, or <code>pcr</code> has less
+arguments, a default value equal to 20 is used.
+
+          <li><var>m</var> is the (left) preconditioning matrix, so that the iteration is
+(theoretically) equivalent to solving by <code>pcr</code> <var>P</var><code> *
+</code><var>x</var><code> = </code><var>m</var><code> \ </code><var>b</var>, with <var>P</var><code> = </code><var>m</var><code> \ </code><var>a</var>. 
+Note that a proper choice of the preconditioner may dramatically
+improve the overall performance of the method.  Instead of matrix
+<var>m</var>, the user may pass a function which returns the results of
+applying the inverse of <var>m</var> to a vector (usually this is the
+preferred way of using the preconditioner).  If <code>[]</code> is supplied
+for <var>m</var>, or <var>m</var> is omitted, no preconditioning is applied.
+
+          <li><var>x0</var> is the initial guess.  If <var>x0</var> is empty or omitted, the
+function sets <var>x0</var> to a zero vector by default. 
+</ul>
+
+        <p>The arguments which follow <var>x0</var> are treated as parameters, and
+passed in a proper way to any of the functions (<var>a</var> or <var>m</var>)
+which are passed to <code>pcr</code>.  See the examples below for further
+details.  The output arguments are
+
+          <ul>
+<li><var>x</var> is the computed approximation to the solution of
+<var>a</var><code> * </code><var>x</var><code> = </code><var>b</var>.
+
+          <li><var>flag</var> reports on the convergence.  <var>flag</var><code> = 0</code> means
+the solution converged and the tolerance criterion given by <var>tol</var>
+is satisfied.  <var>flag</var><code> = 1</code> means that the <var>maxit</var> limit
+for the iteration count was reached.  <var>flag</var><code> = 3</code> reports t
+<code>pcr</code> breakdown, see [1] for details.
+
+          <li><var>relres</var> is the ratio of the final residual to its initial value,
+measured in the Euclidean norm.
+
+          <li><var>iter</var> is the actual number of iterations performed.
+
+          <li><var>resvec</var> describes the convergence history of the method,
+so that <var>resvec</var><code> (i)</code> contains the Euclidean norms of the
+residual after the (<var>i</var>-1)-th iteration, <var>i</var><code> =
+1,2, ..., </code><var>iter</var><code>+1</code>. 
+</ul>
+
+        <p>Let us consider a trivial problem with a diagonal matrix (we exploit the
+sparsity of A)
+
+     <pre class="example">          	n = 10;
+          	a = sparse (diag (1:n));
+          	b = rand (N, 1);
+</pre>
+        <p><span class="sc">Example 1:</span> Simplest use of <code>pcr</code>
+
+     <pre class="example">            x = pcr(A, b)
+</pre>
+        <p><span class="sc">Example 2:</span> <code>pcr</code> with a function which computes
+<var>a</var><code> * </code><var>x</var>.
+
+     <pre class="example">            function y = apply_a (x)
+              y = [1:10]'.*x;
+            endfunction
+          
+            x = pcr ("apply_a", b)
+</pre>
+        <p><span class="sc">Example 3:</span>  Preconditioned iteration, with full diagnostics.  The
+preconditioner (quite strange, because even the original matrix
+<var>a</var> is trivial) is defined as a function
+
+     <pre class="example">            function y = apply_m (x)
+              k = floor (length(x)-2);
+              y = x;
+              y(1:k) = x(1:k)./[1:k]';
+            endfunction
+          
+            [x, flag, relres, iter, resvec] = ...
+                               pcr (a, b, [], [], "apply_m")
+            semilogy([1:iter+1], resvec);
+</pre>
+        <p><span class="sc">Example 4:</span> Finally, a preconditioner which depends on a
+parameter <var>k</var>.
+
+     <pre class="example">            function y = apply_m (x, varargin)
+              k = varargin{1};
+              y = x; y(1:k) = x(1:k)./[1:k]';
+            endfunction
+          
+            [x, flag, relres, iter, resvec] = ...
+                               pcr (a, b, [], [], "apply_m"', [], 3)
+</pre>
+        <p><span class="sc">References</span>
+
+        <p>	[1] W. Hackbusch, "Iterative Solution of Large Sparse Systems of
+ 	Equations", section 9.5.4; Springer, 1994
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>, <a href="doc_002dpcg.html#doc_002dpcg">pcg</a>. 
+</p></blockquote></div>
+
+   <p>The speed with which an iterative solver converges to a solution can be
+accelerated with the use of a pre-conditioning matrix <var>M</var>.  In this
+case the linear equation <var>M</var><code>^-1 * </code><var>x</var><code> = </code><var>M</var><code>^-1 *
+</code><var>A</var><code> \ </code><var>b</var> is solved instead.  Typical pre-conditioning matrices
+are partial factorizations of the original matrix.
+
+<!-- ./DLD-FUNCTIONS/luinc.cc -->
+   <p><a name="doc_002dluinc"></a>
+
+<div class="defun">
+— Loadable Function: [<var>l</var>, <var>u</var>, <var>p</var>, <var>q</var>] = <b>luinc</b> (<var>a, '0'</var>)<var><a name="index-luinc-1756"></a></var><br>
+— Loadable Function: [<var>l</var>, <var>u</var>, <var>p</var>, <var>q</var>] = <b>luinc</b> (<var>a, droptol</var>)<var><a name="index-luinc-1757"></a></var><br>
+— Loadable Function: [<var>l</var>, <var>u</var>, <var>p</var>, <var>q</var>] = <b>luinc</b> (<var>a, opts</var>)<var><a name="index-luinc-1758"></a></var><br>
+<blockquote><p><a name="index-LU-decomposition-1759"></a>Produce the incomplete LU factorization of the sparse matrix <var>a</var>. 
+Two types of incomplete factorization are possible, and the type
+is determined by the second argument to <dfn>luinc</dfn>.
+
+        <p>Called with a second argument of '0', the zero-level incomplete
+LU factorization is produced.  This creates a factorization of <var>a</var>
+where the position of the non-zero arguments correspond to the same
+positions as in the matrix <var>a</var>.
+
+        <p>Alternatively, the fill-in of the incomplete LU factorization can
+be controlled through the variable <var>droptol</var> or the structure
+<var>opts</var>.  The UMFPACK multifrontal factorization code by Tim A. 
+Davis is used for the incomplete LU factorization, (availability
+<a href="http://www.cise.ufl.edu/research/sparse/umfpack/">http://www.cise.ufl.edu/research/sparse/umfpack/</a>)
+
+        <p><var>droptol</var> determines the values below which the values in the LU
+factorization are dropped and replaced by zero.  It must be a positive
+scalar, and any values in the factorization whose absolute value are
+less than this value are dropped, expect if leaving them increase the
+sparsity of the matrix.  Setting <var>droptol</var> to zero results in a
+complete LU factorization which is the default.
+
+        <p><var>opts</var> is a structure containing one or more of the fields
+
+          <dl>
+<dt><code>droptol</code><dd>The drop tolerance as above.  If <var>opts</var> only contains <code>droptol</code>
+then this is equivalent to using the variable <var>droptol</var>.
+
+          <br><dt><code>milu</code><dd>A logical variable flagging whether to use the modified incomplete LU
+factorization.  In the case that <code>milu</code> is true, the dropped values
+are subtracted from the diagonal of the matrix U of the factorization. 
+The default is <code>false</code>.
+
+          <br><dt><code>udiag</code><dd>A logical variable that flags whether zero elements on the diagonal of U
+should be replaced with <var>droptol</var> to attempt to avoid singular
+factors.  The default is <code>false</code>.
+
+          <br><dt><code>thresh</code><dd>Defines the pivot threshold in the interval [0,1].  Values outside that
+range are ignored. 
+</dl>
+
+        <p>All other fields in <var>opts</var> are ignored.  The outputs from <dfn>luinc</dfn>
+are the same as for <dfn>lu</dfn>.
+
+        <p>Given the string argument 'vector', <dfn>luinc</dfn> returns the values of <var>p</var>
+<var>q</var> as vector values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsparse.html#doc_002dsparse">sparse</a>, <a href="doc_002dlu.html#doc_002dlu">lu</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Killing-and-Yanking.html b/doc/interpreter/HTML/Killing-and-Yanking.html
new file mode 100644
index 0000000..4551059
--- /dev/null
+++ b/doc/interpreter/HTML/Killing-and-Yanking.html
@@ -0,0 +1,76 @@
+<html lang="en">
+<head>
+<title>Killing and Yanking - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Command-Line-Editing.html#Command-Line-Editing" title="Command Line Editing">
+<link rel="prev" href="Cursor-Motion.html#Cursor-Motion" title="Cursor Motion">
+<link rel="next" href="Commands-For-Text.html#Commands-For-Text" title="Commands For Text">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Killing-and-Yanking"></a>
+Next: <a rel="next" accesskey="n" href="Commands-For-Text.html#Commands-For-Text">Commands For Text</a>,
+Previous: <a rel="previous" accesskey="p" href="Cursor-Motion.html#Cursor-Motion">Cursor Motion</a>,
+Up: <a rel="up" accesskey="u" href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.4.2 Killing and Yanking</h4>
+
+<p><dfn>Killing</dfn> text means to delete the text from the line, but to save
+it away for later use, usually by <dfn>yanking</dfn> it back into the line. 
+If the description for a command says that it `kills' text, then you can
+be sure that you can get the text back in a different (or the same)
+place later.
+
+   <p>Here is the list of commands for killing text.
+
+     <dl>
+<dt><kbd>C-k</kbd><dd>Kill the text from the current cursor position to the end of the line.
+
+     <br><dt><kbd>M-d</kbd><dd>Kill from the cursor to the end of the current word, or if between
+words, to the end of the next word.
+
+     <br><dt><kbd>M-<DEL></kbd><dd>Kill from the cursor to the start of the previous word, or if between
+words, to the start of the previous word.
+
+     <br><dt><kbd>C-w</kbd><dd>Kill from the cursor to the previous whitespace.  This is different than
+<kbd>M-<DEL></kbd> because the word boundaries differ. 
+</dl>
+
+   <p>And, here is how to <dfn>yank</dfn> the text back into the line.  Yanking
+means to copy the most-recently-killed text from the kill buffer.
+
+     <dl>
+<dt><kbd>C-y</kbd><dd>Yank the most recently killed text back into the buffer at the cursor.
+
+     <br><dt><kbd>M-y</kbd><dd>Rotate the kill-ring, and yank the new top.  You can only do this if
+the prior command is <kbd>C-y</kbd> or <kbd>M-y</kbd>. 
+</dl>
+
+   <p>When you use a kill command, the text is saved in a <dfn>kill-ring</dfn>. 
+Any number of consecutive kills save all of the killed text together, so
+that when you yank it back, you get it in one clean sweep.  The kill
+ring is not line specific; the text that you killed on a previously
+typed line is available to be yanked back later, when you are typing
+another line.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Leaving-Debug-Mode.html b/doc/interpreter/HTML/Leaving-Debug-Mode.html
new file mode 100644
index 0000000..56684f7
--- /dev/null
+++ b/doc/interpreter/HTML/Leaving-Debug-Mode.html
@@ -0,0 +1,73 @@
+<html lang="en">
+<head>
+<title>Leaving Debug Mode - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Debugging.html#Debugging" title="Debugging">
+<link rel="prev" href="Entering-Debug-Mode.html#Entering-Debug-Mode" title="Entering Debug Mode">
+<link rel="next" href="Breakpoints.html#Breakpoints" title="Breakpoints">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Leaving-Debug-Mode"></a>
+Next: <a rel="next" accesskey="n" href="Breakpoints.html#Breakpoints">Breakpoints</a>,
+Previous: <a rel="previous" accesskey="p" href="Entering-Debug-Mode.html#Entering-Debug-Mode">Entering Debug Mode</a>,
+Up: <a rel="up" accesskey="u" href="Debugging.html#Debugging">Debugging</a>
+<hr>
+</div>
+
+<h3 class="section">13.2 Leavinging Debug Mode</h3>
+
+<p>To leave the debug mode, use either <code>dbcont</code>
+or <code>return</code>.
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbcont"></a>
+
+<div class="defun">
+— Command:  <b>dbcont</b> ()<var><a name="index-dbcont-691"></a></var><br>
+<blockquote><p>In debugging mode, quit debugging mode and continue execution. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbstep.html#doc_002ddbstep">dbstep</a>, <a href="doc_002ddbstep.html#doc_002ddbstep">dbstep</a>. 
+</p></blockquote></div>
+
+   <p>To quit debug mode and return directly to the prompt <code>dbquit</code>
+should be used instead
+
+<!-- debug.cc -->
+   <p><a name="doc_002ddbquit"></a>
+
+<div class="defun">
+— Command:  <b>dbquit</b> ()<var><a name="index-dbquit-692"></a></var><br>
+<blockquote><p>In debugging mode, quit debugging mode and return to the top level. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddbstep.html#doc_002ddbstep">dbstep</a>, <a href="doc_002ddbcont.html#doc_002ddbcont">dbcont</a>. 
+</p></blockquote></div>
+
+   <p>Finally, typing <code>exit</code> or <code>quit</code> at the debug prompt will
+result in Octave terminating normally.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Line-Properties.html b/doc/interpreter/HTML/Line-Properties.html
new file mode 100644
index 0000000..aacde78
--- /dev/null
+++ b/doc/interpreter/HTML/Line-Properties.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Line Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Axes-Properties.html#Axes-Properties" title="Axes Properties">
+<link rel="next" href="Text-Properties.html#Text-Properties" title="Text Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Line-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Text-Properties.html#Text-Properties">Text Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Axes-Properties.html#Axes-Properties">Axes Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.4 Line Properties</h5>
+
+<p><a name="index-line-properties-1192"></a>
+     <dl>
+<dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dt><code>ldata</code><dt><code>udata</code><dt><code>xldata</code><dt><code>xudata</code><dd>The data to be plotted.  The <code>ldata</code> and <code>udata</code> elements are
+for errorbars in the y direction, and the <code>xldata</code> and <code>xudata</code>
+elements are for errorbars in the x direction.
+
+     <br><dt><code>color</code><dd>The RGB color of the line, or a color name.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linestyle</code><dt><code>linewidth</code><dd>See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><br><dt><code>markeredgecolor</code><br><dt><code>markerfacecolor</code><br><dt><code>markersize</code><dd>See <a href="Marker-Styles.html#Marker-Styles">Marker Styles</a>.
+
+     <br><dt><code>keylabel</code><dd>The text of the legend entry corresponding to this line.  Note that this
+property is not compatible with <span class="sc">matlab</span> and may be removed in a
+future version of Octave. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Line-Styles.html b/doc/interpreter/HTML/Line-Styles.html
new file mode 100644
index 0000000..7cc9ae0
--- /dev/null
+++ b/doc/interpreter/HTML/Line-Styles.html
@@ -0,0 +1,54 @@
+<html lang="en">
+<head>
+<title>Line Styles - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Colors.html#Colors" title="Colors">
+<link rel="next" href="Marker-Styles.html#Marker-Styles" title="Marker Styles">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Line-Styles"></a>
+Next: <a rel="next" accesskey="n" href="Marker-Styles.html#Marker-Styles">Marker Styles</a>,
+Previous: <a rel="previous" accesskey="p" href="Colors.html#Colors">Colors</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.5 Line Styles</h4>
+
+<p><a name="index-line-styles_002c-graphics-1212"></a><a name="index-graphics-line-styles-1213"></a>
+Line styles are specified by the following properties:
+
+     <dl>
+<dt><code>linestyle</code><dd>May be one of
+          <dl>
+<dt><code>"-"</code><dd>Solid lines. 
+<br><dt><code>"--"</code><dd>Dashed lines. 
+<br><dt><code>":"</code><dd>Points. 
+<br><dt><code>"-."</code><dd>A dash-dot line. 
+</dl>
+
+     <br><dt><code>linewidth</code><dd>A number specifying the width of the line.  The default is 1.  A value
+of 2 is twice as wide as the default, etc. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Line-series.html b/doc/interpreter/HTML/Line-series.html
new file mode 100644
index 0000000..adf88a9
--- /dev/null
+++ b/doc/interpreter/HTML/Line-series.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Line series - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Error-bar-series.html#Error-bar-series" title="Error bar series">
+<link rel="next" href="Quiver-group.html#Quiver-group" title="Quiver group">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Line-series"></a>
+Next: <a rel="next" accesskey="n" href="Quiver-group.html#Quiver-group">Quiver group</a>,
+Previous: <a rel="previous" accesskey="p" href="Error-bar-series.html#Error-bar-series">Error bar series</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.6 Line series</h5>
+
+<p><a name="index-series-objects-1240"></a><a name="index-line-series-1241"></a>
+Line series objects are created by the <code>plot</code>  and <code>plot3</code>
+functions and are of the type <code>line</code>.  The properties of the
+line series with the ability to add data sources.
+
+     <dl>
+<dt><code>color</code><dd>The RGB color or color name of the line objects.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the line objects.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>The line and fill color of the markers.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>The original x, y and z data.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>zdatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Line_002dOriented-Input.html b/doc/interpreter/HTML/Line_002dOriented-Input.html
new file mode 100644
index 0000000..79f2736
--- /dev/null
+++ b/doc/interpreter/HTML/Line_002dOriented-Input.html
@@ -0,0 +1,91 @@
+<html lang="en">
+<head>
+<title>Line-Oriented Input - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Simple-Output.html#Simple-Output" title="Simple Output">
+<link rel="next" href="Formatted-Output.html#Formatted-Output" title="Formatted Output">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Line-Oriented-Input"></a>
+<a name="Line_002dOriented-Input"></a>
+Next: <a rel="next" accesskey="n" href="Formatted-Output.html#Formatted-Output">Formatted Output</a>,
+Previous: <a rel="previous" accesskey="p" href="Simple-Output.html#Simple-Output">Simple Output</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.3 Line-Oriented Input</h4>
+
+<p>To read from a file it must be opened for reading using <code>fopen</code>. 
+Then a line can be read from the file using <code>fgetl</code> as the following
+code illustrates
+
+<pre class="example">     fid = fopen ("free.txt");
+     txt = fgetl (fid)
+          -| Free Software is needed for Free Science
+     fclose (fid);
+</pre>
+   <p class="noindent">This of course assumes that the file ‘<samp><span class="samp">free.txt</span></samp>’ exists and contains
+the line ‘<samp><span class="samp">Free Software is needed for Free Science</span></samp>’.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfgetl"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fgetl</b> (<var>fid, len</var>)<var><a name="index-fgetl-779"></a></var><br>
+<blockquote><p>Read characters from a file, stopping after a newline, or EOF,
+or <var>len</var> characters have been read.  The characters read, excluding
+the possible trailing newline, are returned as a string.
+
+        <p>If <var>len</var> is omitted, <code>fgetl</code> reads until the next newline
+character.
+
+        <p>If there are no more characters to read, <code>fgetl</code> returns −1. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfgets"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fgets</b> (<var>fid, len</var>)<var><a name="index-fgets-780"></a></var><br>
+<blockquote><p>Read characters from a file, stopping after a newline, or EOF,
+or <var>len</var> characters have been read.  The characters read, including
+the possible trailing newline, are returned as a string.
+
+        <p>If <var>len</var> is omitted, <code>fgets</code> reads until the next newline
+character.
+
+        <p>If there are no more characters to read, <code>fgets</code> returns −1. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfputs.html#doc_002dfputs">fputs</a>, <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Linear-Algebra.html b/doc/interpreter/HTML/Linear-Algebra.html
new file mode 100644
index 0000000..03cf6c8
--- /dev/null
+++ b/doc/interpreter/HTML/Linear-Algebra.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Linear Algebra - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="next" href="Nonlinear-Equations.html#Nonlinear-Equations" title="Nonlinear Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Linear-Algebra"></a>
+Next: <a rel="next" accesskey="n" href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a>,
+Previous: <a rel="previous" accesskey="p" href="Arithmetic.html#Arithmetic">Arithmetic</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">18 Linear Algebra</h2>
+
+<p>This chapter documents the linear algebra functions of Octave. 
+Reference material for many of these functions may be found in
+Golub and Van Loan, <cite>Matrix Computations, 2nd Ed.</cite>, Johns Hopkins,
+1989, and in the <span class="sc">lapack</span><cite> Users' Guide</cite>, SIAM, 1992.
+
+<ul class="menu">
+<li><a accesskey="1" href="Techniques-used-for-Linear-Algebra.html#Techniques-used-for-Linear-Algebra">Techniques used for Linear Algebra</a>
+<li><a accesskey="2" href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a>
+<li><a accesskey="3" href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>
+<li><a accesskey="4" href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a>
+<li><a accesskey="5" href="Specialized-Solvers.html#Specialized-Solvers">Specialized Solvers</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Linear-Least-Squares.html b/doc/interpreter/HTML/Linear-Least-Squares.html
new file mode 100644
index 0000000..4663600
--- /dev/null
+++ b/doc/interpreter/HTML/Linear-Least-Squares.html
@@ -0,0 +1,192 @@
+<html lang="en">
+<head>
+<title>Linear Least Squares - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Nonlinear-Programming.html#Nonlinear-Programming" title="Nonlinear Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Linear-Least-Squares"></a>
+Previous: <a rel="previous" accesskey="p" href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">24.4 Linear Least Squares</h3>
+
+<p>Octave also supports linear least squares minimization.  That is,
+Octave can find the parameter b such that the model
+y = x*b
+fits data (x,y) as well as possible, assuming zero-mean
+Gaussian noise.  If the noise is assumed to be isotropic the problem
+can be solved using the ‘<samp><span class="samp">\</span></samp>’ or ‘<samp><span class="samp">/</span></samp>’ operators, or the <code>ols</code>
+function.  In the general case where the noise is assumed to be anisotropic
+the <code>gls</code> is needed.
+
+<!-- ./statistics/base/ols.m -->
+   <p><a name="doc_002dols"></a>
+
+<div class="defun">
+— Function File: [<var>beta</var>, <var>sigma</var>, <var>r</var>] = <b>ols</b> (<var>y, x</var>)<var><a name="index-ols-1804"></a></var><br>
+<blockquote><p>Ordinary least squares estimation for the multivariate model
+y = x b + e with
+mean (e) = 0 and cov (vec (e)) = kron (s, I). 
+ where
+y is a t by p matrix, x is a t by
+k matrix, b is a k by p matrix, and
+e is a t by p matrix.
+
+        <p>Each row of <var>y</var> and <var>x</var> is an observation and each column a
+variable.
+
+        <p>The return values <var>beta</var>, <var>sigma</var>, and <var>r</var> are defined as
+follows.
+
+          <dl>
+<dt><var>beta</var><dd>The OLS estimator for <var>b</var>, <var>beta</var><code> = pinv (</code><var>x</var><code>) *
+</code><var>y</var>, where <code>pinv (</code><var>x</var><code>)</code> denotes the pseudoinverse of
+<var>x</var>.
+
+          <br><dt><var>sigma</var><dd>The OLS estimator for the matrix <var>s</var>,
+
+          <pre class="example">               <var>sigma</var> = (<var>y</var>-<var>x</var>*<var>beta</var>)'
+                 * (<var>y</var>-<var>x</var>*<var>beta</var>)
+                 / (<var>t</var>-rank(<var>x</var>))
+</pre>
+          <br><dt><var>r</var><dd>The matrix of OLS residuals, <var>r</var><code> = </code><var>y</var><code> - </code><var>x</var><code> *
+</code><var>beta</var>. 
+</dl>
+        </p></blockquote></div>
+
+<!-- ./statistics/base/gls.m -->
+   <p><a name="doc_002dgls"></a>
+
+<div class="defun">
+— Function File: [<var>beta</var>, <var>v</var>, <var>r</var>] = <b>gls</b> (<var>y, x, o</var>)<var><a name="index-gls-1805"></a></var><br>
+<blockquote><p>Generalized least squares estimation for the multivariate model
+y = x b + e with mean (e) = 0 and
+cov (vec (e)) = (s^2) o,
+ where
+y is a t by p matrix, x is a t by
+k matrix, b is a k by p matrix, e
+is a t by p matrix, and o is a t p by
+t p matrix.
+
+     <p class="noindent">Each row of <var>y</var> and <var>x</var> is an observation and each column a
+variable.  The return values <var>beta</var>, <var>v</var>, and <var>r</var> are
+defined as follows.
+
+          <dl>
+<dt><var>beta</var><dd>The GLS estimator for b.
+
+          <br><dt><var>v</var><dd>The GLS estimator for s^2.
+
+          <br><dt><var>r</var><dd>The matrix of GLS residuals, r = y - x beta. 
+</dl>
+        </p></blockquote></div>
+
+<!-- ./optimization/lsqnonneg.m -->
+   <p><a name="doc_002dlsqnonneg"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>lsqnonneg</b> (<var>c, d</var>)<var><a name="index-lsqnonneg-1806"></a></var><br>
+— Function File: <var>x</var> = <b>lsqnonneg</b> (<var>c, d, x0</var>)<var><a name="index-lsqnonneg-1807"></a></var><br>
+— Function File: [<var>x</var>, <var>resnorm</var>] = <b>lsqnonneg</b> (<var><small class="dots">...</small></var>)<var><a name="index-lsqnonneg-1808"></a></var><br>
+— Function File: [<var>x</var>, <var>resnorm</var>, <var>residual</var>] = <b>lsqnonneg</b> (<var><small class="dots">...</small></var>)<var><a name="index-lsqnonneg-1809"></a></var><br>
+— Function File: [<var>x</var>, <var>resnorm</var>, <var>residual</var>, <var>exitflag</var>] = <b>lsqnonneg</b> (<var><small class="dots">...</small></var>)<var><a name="index-lsqnonneg-1810"></a></var><br>
+— Function File: [<var>x</var>, <var>resnorm</var>, <var>residual</var>, <var>exitflag</var>, <var>output</var>] = <b>lsqnonneg</b> (<var><small class="dots">...</small></var>)<var><a name="index-lsqnonneg-1811"></a></var><br>
+— Function File: [<var>x</var>, <var>resnorm</var>, <var>residual</var>, <var>exitflag</var>, <var>output</var>, <var>lambda</var>] = <b>lsqnonneg</b> (<var><small class="dots">...</small></var>)<var><a name="index-lsqnonneg-1812"></a></var><br>
+<blockquote><p>Minimize <code>norm (</code><var>c</var><code>*</code><var>x</var><code>-d)</code> subject to <var>x</var><code> >=
+0</code>.  <var>c</var> and <var>d</var> must be real.  <var>x0</var> is an optional
+initial guess for <var>x</var>.
+
+        <p>Outputs:
+          <ul>
+<li>resnorm
+
+          <p>The squared 2-norm of the residual: norm(<var>c</var>*<var>x</var>-<var>d</var>)^2
+<li>residual
+
+          <p>The residual: <var>d</var>-<var>c</var>*<var>x</var>
+<li>exitflag
+
+          <p>An indicator of convergence.  0 indicates that the iteration count
+was exceeded, and therefore convergence was not reached; >0 indicates
+that the algorithm converged.  (The algorithm is stable and will
+converge given enough iterations.) 
+<li>output
+
+          <p>A structure with two fields:
+               <ul>
+<li>"algorithm": The algorithm used ("nnls")
+<li>"iterations": The number of iterations taken. 
+</ul>
+          <li>lambda
+
+          <p>Not implemented. 
+</ul>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002doptimset.html#doc_002doptimset">optimset</a>. 
+</p></blockquote></div>
+
+<!-- ./optimization/optimset.m -->
+   <p><a name="doc_002doptimset"></a>
+
+<div class="defun">
+— Function File:  <b>optimset</b> ()<var><a name="index-optimset-1813"></a></var><br>
+— Function File:  <b>optimset</b> (<var>par, val, <small class="dots">...</small></var>)<var><a name="index-optimset-1814"></a></var><br>
+— Function File:  <b>optimset</b> (<var>old, par, val, <small class="dots">...</small></var>)<var><a name="index-optimset-1815"></a></var><br>
+— Function File:  <b>optimset</b> (<var>old, new</var>)<var><a name="index-optimset-1816"></a></var><br>
+<blockquote><p>Create options struct for optimization functions. 
+</p></blockquote></div>
+
+<!-- ./optimization/optimget.m -->
+   <p><a name="doc_002doptimget"></a>
+
+<div class="defun">
+— Function File:  <b>optimget</b> (<var>options, parname</var>)<var><a name="index-optimget-1817"></a></var><br>
+— Function File:  <b>optimget</b> (<var>options, parname, default</var>)<var><a name="index-optimget-1818"></a></var><br>
+<blockquote><p>Return a specific option from a structure created by
+<code>optimset</code>.  If <var>parname</var> is not a field of the <var>options</var>
+structure, return <var>default</var> if supplied, otherwise return an
+empty matrix. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006, -->
+<!-- 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Linear-Programming.html b/doc/interpreter/HTML/Linear-Programming.html
new file mode 100644
index 0000000..89a3591
--- /dev/null
+++ b/doc/interpreter/HTML/Linear-Programming.html
@@ -0,0 +1,315 @@
+<html lang="en">
+<head>
+<title>Linear Programming - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="next" href="Quadratic-Programming.html#Quadratic-Programming" title="Quadratic Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Linear-Programming"></a>
+Next: <a rel="next" accesskey="n" href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">24.1 Linear Programming</h3>
+
+<p>Octave can solve Linear Programming problems using the <code>glpk</code>
+function.  That is, Octave can solve
+
+<pre class="example">     min C'*x
+</pre>
+   <p>subject to the linear constraints
+A*x = b where x >= 0.
+
+<p class="noindent">The <code>glpk</code> function also supports variations of this problem.
+
+<!-- ./optimization/glpk.m -->
+   <p><a name="doc_002dglpk"></a>
+
+<div class="defun">
+— Function File: [<var>xopt</var>, <var>fmin</var>, <var>status</var>, <var>extra</var>] = <b>glpk</b> (<var>c, a, b, lb, ub, ctype, vartype, sense, param</var>)<var><a name="index-glpk-1801"></a></var><br>
+<blockquote><p>Solve a linear program using the GNU GLPK library.  Given three
+arguments, <code>glpk</code> solves the following standard LP:
+
+     <pre class="example">          min C'*x
+</pre>
+        <p>subject to
+
+     <pre class="example">          A*x  = b
+            x >= 0
+</pre>
+        <p>but may also solve problems of the form
+
+     <pre class="example">          [ min | max ] C'*x
+</pre>
+        <p>subject to
+
+     <pre class="example">          A*x [ "=" | "<=" | ">=" ] b
+            x >= LB
+            x <= UB
+</pre>
+        <p>Input arguments:
+
+          <dl>
+<dt><var>c</var><dd>A column array containing the objective function coefficients.
+
+          <br><dt><var>a</var><dd>A matrix containing the constraints coefficients.
+
+          <br><dt><var>b</var><dd>A column array containing the right-hand side value for each constraint
+in the constraint matrix.
+
+          <br><dt><var>lb</var><dd>An array containing the lower bound on each of the variables.  If
+<var>lb</var> is not supplied, the default lower bound for the variables is
+zero.
+
+          <br><dt><var>ub</var><dd>An array containing the upper bound on each of the variables.  If
+<var>ub</var> is not supplied, the default upper bound is assumed to be
+infinite.
+
+          <br><dt><var>ctype</var><dd>An array of characters containing the sense of each constraint in the
+constraint matrix.  Each element of the array may be one of the
+following values
+               <dl>
+<dt><code>"F"</code><dd>A free (unbounded) constraint (the constraint is ignored). 
+<br><dt><code>"U"</code><dd>An inequality constraint with an upper bound (<code>A(i,:)*x <= b(i)</code>). 
+<br><dt><code>"S"</code><dd>An equality constraint (<code>A(i,:)*x = b(i)</code>). 
+<br><dt><code>"L"</code><dd>An inequality with a lower bound (<code>A(i,:)*x >= b(i)</code>). 
+<br><dt><code>"D"</code><dd>An inequality constraint with both upper and lower bounds
+(<code>A(i,:)*x >= -b(i)</code> <em>and</em> (<code>A(i,:)*x <= b(i)</code>). 
+</dl>
+
+          <br><dt><var>vartype</var><dd>A column array containing the types of the variables.
+               <dl>
+<dt><code>"C"</code><dd>A continuous variable. 
+<br><dt><code>"I"</code><dd>An integer variable. 
+</dl>
+
+          <br><dt><var>sense</var><dd>If <var>sense</var> is 1, the problem is a minimization.  If <var>sense</var> is
+-1, the problem is a maximization.  The default value is 1.
+
+          <br><dt><var>param</var><dd>A structure containing the following parameters used to define the
+behavior of solver.  Missing elements in the structure take on default
+values, so you only need to set the elements that you wish to change
+from the default.
+
+          <p>Integer parameters:
+
+               <dl>
+<dt><code>msglev (LPX_K_MSGLEV, default: 1)</code><dd>Level of messages output by solver routines:
+                    <dl>
+<dt>0<dd>No output. 
+<br><dt>1<dd>Error messages only. 
+<br><dt>2<dd>Normal output . 
+<br><dt>3<dd>Full output (includes informational messages). 
+</dl>
+
+               <br><dt><code>scale (LPX_K_SCALE, default: 1)</code><dd>Scaling option:
+                    <dl>
+<dt>0<dd>No scaling. 
+<br><dt>1<dd>Equilibration scaling. 
+<br><dt>2<dd>Geometric mean scaling, then equilibration scaling. 
+</dl>
+
+               <br><dt><code>dual	 (LPX_K_DUAL, default: 0)</code><dd>Dual simplex option:
+                    <dl>
+<dt>0<dd>Do not use the dual simplex. 
+<br><dt>1<dd>If initial basic solution is dual feasible, use the dual simplex. 
+</dl>
+
+               <br><dt><code>price	 (LPX_K_PRICE, default: 1)</code><dd>Pricing option (for both primal and dual simplex):
+                    <dl>
+<dt>0<dd>Textbook pricing. 
+<br><dt>1<dd>Steepest edge pricing. 
+</dl>
+
+               <br><dt><code>round	 (LPX_K_ROUND, default: 0)</code><dd>Solution rounding option:
+                    <dl>
+<dt>0<dd>Report all primal and dual values "as is". 
+<br><dt>1<dd>Replace tiny primal and dual values by exact zero. 
+</dl>
+
+               <br><dt><code>itlim	 (LPX_K_ITLIM, default: -1)</code><dd>Simplex iterations limit.  If this value is positive, it is decreased by
+one each time when one simplex iteration has been performed, and
+reaching zero value signals the solver to stop the search.  Negative
+value means no iterations limit.
+
+               <br><dt><code>itcnt (LPX_K_OUTFRQ, default: 200)</code><dd>Output frequency, in iterations.  This parameter specifies how
+frequently the solver sends information about the solution to the
+standard output.
+
+               <br><dt><code>branch (LPX_K_BRANCH, default: 2)</code><dd>Branching heuristic option (for MIP only):
+                    <dl>
+<dt>0<dd>Branch on the first variable. 
+<br><dt>1<dd>Branch on the last variable. 
+<br><dt>2<dd>Branch using a heuristic by Driebeck and Tomlin. 
+</dl>
+
+               <br><dt><code>btrack (LPX_K_BTRACK, default: 2)</code><dd>Backtracking heuristic option (for MIP only):
+                    <dl>
+<dt>0<dd>Depth first search. 
+<br><dt>1<dd>Breadth first search. 
+<br><dt>2<dd>Backtrack using the best projection heuristic. 
+</dl>
+
+               <br><dt><code>presol (LPX_K_PRESOL, default: 1)</code><dd>If this flag is set, the routine lpx_simplex solves the problem using
+the built-in LP presolver.  Otherwise the LP presolver is not used.
+
+               <br><dt><code>lpsolver (default: 1)</code><dd>Select which solver to use.  If the problem is a MIP problem this flag
+will be ignored.
+                    <dl>
+<dt>1<dd>Revised simplex method. 
+<br><dt>2<dd>Interior point method. 
+</dl>
+               <br><dt><code>save (default: 0)</code><dd>If this parameter is nonzero, save a copy of the problem in
+CPLEX LP format to the file <samp><span class="file">"outpb.lp"</span></samp>.  There is currently no
+way to change the name of the output file. 
+</dl>
+
+          <p>Real parameters:
+
+               <dl>
+<dt><code>relax (LPX_K_RELAX, default: 0.07)</code><dd>Relaxation parameter used in the ratio test.  If it is zero, the textbook
+ratio test is used.  If it is non-zero (should be positive), Harris'
+two-pass ratio test is used.  In the latter case on the first pass of the
+ratio test basic variables (in the case of primal simplex) or reduced
+costs of non-basic variables (in the case of dual simplex) are allowed
+to slightly violate their bounds, but not more than
+<code>relax*tolbnd</code> or <code>relax*toldj (thus, relax is a
+percentage of tolbnd or toldj</code>.
+
+               <br><dt><code>tolbnd (LPX_K_TOLBND, default: 10e-7)</code><dd>Relative tolerance used to check if the current basic solution is primal
+feasible.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+               <br><dt><code>toldj (LPX_K_TOLDJ, default: 10e-7)</code><dd>Absolute tolerance used to check if the current basic solution is dual
+feasible.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+               <br><dt><code>tolpiv (LPX_K_TOLPIV, default: 10e-9)</code><dd>Relative tolerance used to choose eligible pivotal elements of the
+simplex table.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+               <br><dt><code>objll (LPX_K_OBJLL, default: -DBL_MAX)</code><dd>Lower limit of the objective function.  If on the phase II the objective
+function reaches this limit and continues decreasing, the solver stops
+the search.  This parameter is used in the dual simplex method only.
+
+               <br><dt><code>objul (LPX_K_OBJUL, default: +DBL_MAX)</code><dd>Upper limit of the objective function.  If on the phase II the objective
+function reaches this limit and continues increasing, the solver stops
+the search.  This parameter is used in the dual simplex only.
+
+               <br><dt><code>tmlim (LPX_K_TMLIM, default: -1.0)</code><dd>Searching time limit, in seconds.  If this value is positive, it is
+decreased each time when one simplex iteration has been performed by the
+amount of time spent for the iteration, and reaching zero value signals
+the solver to stop the search.  Negative value means no time limit.
+
+               <br><dt><code>outdly (LPX_K_OUTDLY, default: 0.0)</code><dd>Output delay, in seconds.  This parameter specifies how long the solver
+should delay sending information about the solution to the standard
+output.  Non-positive value means no delay.
+
+               <br><dt><code>tolint (LPX_K_TOLINT, default: 10e-5)</code><dd>Relative tolerance used to check if the current basic solution is integer
+feasible.  It is not recommended that you change this parameter unless
+you have a detailed understanding of its purpose.
+
+               <br><dt><code>tolobj (LPX_K_TOLOBJ, default: 10e-7)</code><dd>Relative tolerance used to check if the value of the objective function
+is not better than in the best known integer feasible solution.  It is
+not recommended that you change this parameter unless you have a
+detailed understanding of its purpose. 
+</dl>
+          </dl>
+
+        <p>Output values:
+
+          <dl>
+<dt><var>xopt</var><dd>The optimizer (the value of the decision variables at the optimum). 
+<br><dt><var>fopt</var><dd>The optimum value of the objective function. 
+<br><dt><var>status</var><dd>Status of the optimization.
+
+          <p>Simplex Method:
+               <dl>
+<dt>180 (<code>LPX_OPT</code>)<dd>Solution is optimal. 
+<br><dt>181 (<code>LPX_FEAS</code>)<dd>Solution is feasible. 
+<br><dt>182 (<code>LPX_INFEAS</code>)<dd>Solution is infeasible. 
+<br><dt>183 (<code>LPX_NOFEAS</code>)<dd>Problem has no feasible solution. 
+<br><dt>184 (<code>LPX_UNBND</code>)<dd>Problem has no unbounded solution. 
+<br><dt>185 (<code>LPX_UNDEF</code>)<dd>Solution status is undefined. 
+</dl>
+          Interior Point Method:
+               <dl>
+<dt>150 (<code>LPX_T_UNDEF</code>)<dd>The interior point method is undefined. 
+<br><dt>151 (<code>LPX_T_OPT</code>)<dd>The interior point method is optimal. 
+</dl>
+          Mixed Integer Method:
+               <dl>
+<dt>170 (<code>LPX_I_UNDEF</code>)<dd>The status is undefined. 
+<br><dt>171 (<code>LPX_I_OPT</code>)<dd>The solution is integer optimal. 
+<br><dt>172 (<code>LPX_I_FEAS</code>)<dd>Solution integer feasible but its optimality has not been proven
+<br><dt>173 (<code>LPX_I_NOFEAS</code>)<dd>No integer feasible solution. 
+</dl>
+          If an error occurs, <var>status</var> will contain one of the following
+codes:
+
+               <dl>
+<dt>204 (<code>LPX_E_FAULT</code>)<dd>Unable to start the search. 
+<br><dt>205 (<code>LPX_E_OBJLL</code>)<dd>Objective function lower limit reached. 
+<br><dt>206 (<code>LPX_E_OBJUL</code>)<dd>Objective function upper limit reached. 
+<br><dt>207 (<code>LPX_E_ITLIM</code>)<dd>Iterations limit exhausted. 
+<br><dt>208 (<code>LPX_E_TMLIM</code>)<dd>Time limit exhausted. 
+<br><dt>209 (<code>LPX_E_NOFEAS</code>)<dd>No feasible solution. 
+<br><dt>210 (<code>LPX_E_INSTAB</code>)<dd>Numerical instability. 
+<br><dt>211 (<code>LPX_E_SING</code>)<dd>Problems with basis matrix. 
+<br><dt>212 (<code>LPX_E_NOCONV</code>)<dd>No convergence (interior). 
+<br><dt>213 (<code>LPX_E_NOPFS</code>)<dd>No primal feasible solution (LP presolver). 
+<br><dt>214 (<code>LPX_E_NODFS</code>)<dd>No dual feasible solution (LP presolver). 
+</dl>
+          <br><dt><var>extra</var><dd>A data structure containing the following fields:
+               <dl>
+<dt><code>lambda</code><dd>Dual variables. 
+<br><dt><code>redcosts</code><dd>Reduced Costs. 
+<br><dt><code>time</code><dd>Time (in seconds) used for solving LP/MIP problem. 
+<br><dt><code>mem</code><dd>Memory (in bytes) used for solving LP/MIP problem (this is not
+available if the version of GLPK is 4.15 or later). 
+</dl>
+          </dl>
+
+        <p>Example:
+
+     <pre class="example">          c = [10, 6, 4]';
+          a = [ 1, 1, 1;
+               10, 4, 5;
+                2, 2, 6];
+          b = [100, 600, 300]';
+          lb = [0, 0, 0]';
+          ub = [];
+          ctype = "UUU";
+          vartype = "CCC";
+          s = -1;
+          
+          param.msglev = 1;
+          param.itlim = 100;
+          
+          [xmin, fmin, status, extra] = ...
+             glpk (c, a, b, lb, ub, ctype, vartype, s, param);
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Loading-and-Saving-Images.html b/doc/interpreter/HTML/Loading-and-Saving-Images.html
new file mode 100644
index 0000000..f11c781
--- /dev/null
+++ b/doc/interpreter/HTML/Loading-and-Saving-Images.html
@@ -0,0 +1,160 @@
+<html lang="en">
+<head>
+<title>Loading and Saving Images - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link rel="next" href="Displaying-Images.html#Displaying-Images" title="Displaying Images">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Loading-and-Saving-Images"></a>
+Next: <a rel="next" accesskey="n" href="Displaying-Images.html#Displaying-Images">Displaying Images</a>,
+Up: <a rel="up" accesskey="u" href="Image-Processing.html#Image-Processing">Image Processing</a>
+<hr>
+</div>
+
+<h3 class="section">31.1 Loading and Saving Images</h3>
+
+<p>The first step in most image processing tasks is to load an image
+into Octave.  This is done using the <code>imread</code> function, which uses the
+<code>GraphicsMagick</code> library for reading.  This means a vast number of image
+formats is supported.  The <code>imwrite</code> function is the corresponding function
+for writing images to the disk.
+
+   <p>In summary, most image processing code will follow the structure of this code
+
+<pre class="example">     I = imread ("my_input_image.img");
+     J = process_my_image (I);
+     imwrite ("my_output_image.img", J);
+</pre>
+   <!-- ./image/imread.m -->
+   <p><a name="doc_002dimread"></a>
+
+<div class="defun">
+— Function File: [<var>img</var>, <var>map</var>, <var>alpha</var>] = <b>imread</b> (<var>filename</var>)<var><a name="index-imread-2182"></a></var><br>
+<blockquote><p>Read images from various file formats.
+
+        <p>The size and numeric class of the output depends on the
+format of the image.  A color image is returned as an
+MxNx3 matrix.  Grey-level and black-and-white images are
+of size MxN. 
+The color depth of the image determines the numeric
+class of the output: "uint8" or "uint16" for grey
+and color, and "logical" for black and white.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimwrite.html#doc_002dimwrite">imwrite</a>, <a href="doc_002dimfinfo.html#doc_002dimfinfo">imfinfo</a>. 
+</p></blockquote></div>
+
+<!-- ./image/imwrite.m -->
+   <p><a name="doc_002dimwrite"></a>
+
+<div class="defun">
+— Function File:  <b>imwrite</b> (<var>img, filename, fmt, p1, v1, <small class="dots">...</small></var>)<var><a name="index-imwrite-2183"></a></var><br>
+— Function File:  <b>imwrite</b> (<var>img, map, filename, fmt, p1, v1, <small class="dots">...</small></var>)<var><a name="index-imwrite-2184"></a></var><br>
+<blockquote><p>Write images in various file formats.
+
+        <p>If <var>fmt</var> is missing, the file extension (if any) of
+<var>filename</var> is used to determine the format.
+
+        <p>The parameter-value pairs (<var>p1</var>, <var>v1</var>, <small class="dots">...</small>) are optional.  Currently
+the following options are supported for <tt>JPEG</tt> images
+
+          <dl>
+<dt>‘<samp><span class="samp">Quality</span></samp>’<dd>Sets the quality of the compression.  The corresponding value should be an
+integer between 0 and 100, with larger values meaning higher visual quality
+and less compression. 
+</dl>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimread.html#doc_002dimread">imread</a>, <a href="doc_002dimfinfo.html#doc_002dimfinfo">imfinfo</a>. 
+</p></blockquote></div>
+
+<!-- defaults.cc -->
+   <p><a name="doc_002dIMAGE_005fPATH"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>IMAGE_PATH</b> ()<var><a name="index-IMAGE_005fPATH-2185"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>IMAGE_PATH</b> (<var>new_val</var>)<var><a name="index-IMAGE_005fPATH-2186"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies a colon separated
+list of directories in which to search for image files. 
+</p></blockquote></div>
+
+   <p>It is possible to get information about an image file on disk, without actually
+reading it into Octave.  This is done using the <code>imfinfo</code> function which
+provides read access to many of the parameters stored in the header of the image
+file.
+
+<!-- ./image/imfinfo.m -->
+   <p><a name="doc_002dimfinfo"></a>
+
+<div class="defun">
+— Function File: <var>info</var> = <b>imfinfo</b> (<var>filename</var>)<var><a name="index-imfinfo-2187"></a></var><br>
+— Function File: <var>info</var> = <b>imfinfo</b> (<var>url</var>)<var><a name="index-imfinfo-2188"></a></var><br>
+<blockquote><p>Read image information from a file.
+
+        <p><code>imfinfo</code> returns a structure containing information about the image
+stored in the file <var>filename</var>.  The output structure contains the
+following fields.
+
+          <dl>
+<dt>‘<samp><span class="samp">Filename</span></samp>’<dd>The full name of the image file. 
+<br><dt>‘<samp><span class="samp">FileSize</span></samp>’<dd>Number of bytes of the image on disk
+<br><dt>‘<samp><span class="samp">FileModDate</span></samp>’<dd>Date of last modification to the file. 
+<br><dt>‘<samp><span class="samp">Height</span></samp>’<dd>Image height in pixels. 
+<br><dt>‘<samp><span class="samp">Width</span></samp>’<dd>Image Width in pixels. 
+<br><dt>‘<samp><span class="samp">BitDepth</span></samp>’<dd>Number of bits per channel per pixel. 
+<br><dt>‘<samp><span class="samp">Format</span></samp>’<dd>Image format (e.g., <code>"jpeg"</code>). 
+<br><dt>‘<samp><span class="samp">LongFormat</span></samp>’<dd>Long form image format description. 
+<br><dt>‘<samp><span class="samp">XResolution</span></samp>’<dd>X resolution of the image. 
+<br><dt>‘<samp><span class="samp">YResolution</span></samp>’<dd>Y resolution of the image. 
+<br><dt>‘<samp><span class="samp">TotalColors</span></samp>’<dd>Number of unique colors in the image. 
+<br><dt>‘<samp><span class="samp">TileName</span></samp>’<dd>Tile name. 
+<br><dt>‘<samp><span class="samp">AnimationDelay</span></samp>’<dd>Time in 1/100ths of a second (0 to 65535) which must expire before displaying
+the next image in an animated sequence. 
+<br><dt>‘<samp><span class="samp">AnimationIterations</span></samp>’<dd>Number of iterations to loop an animation (e.g., Netscape loop extension) for. 
+<br><dt>‘<samp><span class="samp">ByteOrder</span></samp>’<dd>Endian option for formats that support it.  Is either <code>"little-endian"</code>,
+<code>"big-endian"</code>, or <code>"undefined"</code>. 
+<br><dt>‘<samp><span class="samp">Gamma</span></samp>’<dd>Gamma level of the image.  The same color image displayed on two different
+workstations may look different due to differences in the display monitor. 
+<br><dt>‘<samp><span class="samp">Matte</span></samp>’<dd><code>true</code> if the image has transparency. 
+<br><dt>‘<samp><span class="samp">ModulusDepth</span></samp>’<dd>Image modulus depth (minimum number of bits required to support red/green/blue
+components without loss of accuracy). 
+<br><dt>‘<samp><span class="samp">Quality</span></samp>’<dd>JPEG/MIFF/PNG compression level. 
+<br><dt>‘<samp><span class="samp">QuantizeColors</span></samp>’<dd>Preferred number of colors in the image. 
+<br><dt>‘<samp><span class="samp">ResolutionUnits</span></samp>’<dd>Units of image resolution.  Is either <code>"pixels per inch"</code>,
+<code>"pixels per centimeter"</code>, or <code>"undefined"</code>. 
+<br><dt>‘<samp><span class="samp">ColorType</span></samp>’<dd>Image type.  Is either <code>"grayscale"</code>, <code>"indexed"</code>, <code>"truecolor"</code>,
+or <code>"undefined"</code>. 
+<br><dt>‘<samp><span class="samp">View</span></samp>’<dd>FlashPix viewing parameters. 
+</dl>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dimread.html#doc_002dimread">imread</a>, <a href="doc_002dimwrite.html#doc_002dimwrite">imwrite</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Logical-Values.html b/doc/interpreter/HTML/Logical-Values.html
new file mode 100644
index 0000000..bd28458
--- /dev/null
+++ b/doc/interpreter/HTML/Logical-Values.html
@@ -0,0 +1,106 @@
+<html lang="en">
+<head>
+<title>Logical Values - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Bit-Manipulations.html#Bit-Manipulations" title="Bit Manipulations">
+<link rel="next" href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types" title="Promotion and Demotion of Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Logical-Values"></a>
+Next: <a rel="next" accesskey="n" href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types">Promotion and Demotion of Data Types</a>,
+Previous: <a rel="previous" accesskey="p" href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.6 Logical Values</h3>
+
+<p>Octave has built-in support for logical values, i.e., variables that
+are either <code>true</code> or <code>false</code>.  When comparing two variables,
+the result will be a logical value whose value depends on whether or
+not the comparison is true.
+
+   <p>The basic logical operations are <code>&</code>, <code>|</code>, and <code>!</code>,
+which correspond to “Logical And”, “Logical Or”, and “Logical
+Negation”.  These operations all follow the usual rules of logic.
+
+   <p>It is also possible to use logical values as part of standard numerical
+calculations.  In this case <code>true</code> is converted to <code>1</code>, and
+<code>false</code> to 0, both represented using double precision floating
+point numbers.  So, the result of <code>true*22 - false/6</code> is <code>22</code>.
+
+   <p>Logical values can also be used to index matrices and cell arrays. 
+When indexing with a logical array the result will be a vector containing
+the values corresponding to <code>true</code> parts of the logical array. 
+The following example illustrates this.
+
+<pre class="example">     data = [ 1, 2; 3, 4 ];
+     idx = (data <= 2);
+     data(idx)
+           ans = [ 1; 2 ]
+</pre>
+   <p class="noindent">Instead of creating the <code>idx</code> array it is possible to replace
+<code>data(idx)</code> with <code>data( data <= 2 )</code> in the above code.
+
+   <p>Logical values can also be constructed by
+casting numeric objects to logical values, or by using the <code>true</code>
+or <code>false</code> functions.
+
+<!-- ./general/logical.m -->
+   <p><a name="doc_002dlogical"></a>
+
+<div class="defun">
+— Function File:  <b>logical</b> (<var>arg</var>)<var><a name="index-logical-260"></a></var><br>
+<blockquote><p>Convert <var>arg</var> to a logical value.  For example,
+
+     <pre class="example">          logical ([-1, 0, 1])
+</pre>
+        <p class="noindent">is equivalent to
+
+     <pre class="example">          [-1, 0, 1] != 0
+</pre>
+        </blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dtrue"></a>
+
+<div class="defun">
+— Built-in Function:  <b>true</b> (<var>x</var>)<var><a name="index-true-261"></a></var><br>
+— Built-in Function:  <b>true</b> (<var>n, m</var>)<var><a name="index-true-262"></a></var><br>
+— Built-in Function:  <b>true</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-true-263"></a></var><br>
+<blockquote><p>Return a matrix or N-dimensional array whose elements are all logical 1. 
+The arguments are handled the same as the arguments for <code>eye</code>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dfalse"></a>
+
+<div class="defun">
+— Built-in Function:  <b>false</b> (<var>x</var>)<var><a name="index-false-264"></a></var><br>
+— Built-in Function:  <b>false</b> (<var>n, m</var>)<var><a name="index-false-265"></a></var><br>
+— Built-in Function:  <b>false</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-false-266"></a></var><br>
+<blockquote><p>Return a matrix or N-dimensional array whose elements are all logical 0. 
+The arguments are handled the same as the arguments for <code>eye</code>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Looping-Over-Structure-Elements.html b/doc/interpreter/HTML/Looping-Over-Structure-Elements.html
new file mode 100644
index 0000000..3f9f10e
--- /dev/null
+++ b/doc/interpreter/HTML/Looping-Over-Structure-Elements.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>Looping Over Structure Elements - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="The-_0040code_007bfor_007d-Statement.html#The-_0040code_007bfor_007d-Statement" title="The @code{for} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Looping-Over-Structure-Elements"></a>
+Up: <a rel="up" accesskey="u" href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a>
+<hr>
+</div>
+
+<h4 class="subsection">10.5.1 Looping Over Structure Elements</h4>
+
+<p><a name="index-structure-elements_002c-looping-over-571"></a><a name="index-looping-over-structure-elements-572"></a>
+A special form of the <code>for</code> statement allows you to loop over all
+the elements of a structure:
+
+<pre class="example">     for [ <var>val</var>, <var>key</var> ] = <var>expression</var>
+       <var>body</var>
+     endfor
+</pre>
+   <p class="noindent">In this form of the <code>for</code> statement, the value of <var>expression</var>
+must be a structure.  If it is, <var>key</var> and <var>val</var> are set to the
+name of the element and the corresponding value in turn, until there are
+no more elements.  For example,
+
+<pre class="example">     x.a = 1
+     x.b = [1, 2; 3, 4]
+     x.c = "string"
+     for [val, key] = x
+       key
+       val
+     endfor
+     
+          -| key = a
+          -| val = 1
+          -| key = b
+          -| val =
+          -|
+          -|   1  2
+          -|   3  4
+          -|
+          -| key = c
+          -| val = string
+</pre>
+   <p>The elements are not accessed in any particular order.  If you need to
+cycle through the list in a particular way, you will have to use the
+function <code>fieldnames</code> and sort the list yourself.
+
+   <p>The <var>key</var> variable may also be omitted.  If it is, the brackets are
+also optional.  This is useful for cycling through the values of all the
+structure elements when the names of the elements do not need to be
+known.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Managing-Default-Properties.html b/doc/interpreter/HTML/Managing-Default-Properties.html
new file mode 100644
index 0000000..e18f2b4
--- /dev/null
+++ b/doc/interpreter/HTML/Managing-Default-Properties.html
@@ -0,0 +1,103 @@
+<html lang="en">
+<head>
+<title>Managing Default Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="next" href="Colors.html#Colors" title="Colors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Managing-Default-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Colors.html#Colors">Colors</a>,
+Previous: <a rel="previous" accesskey="p" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.3 Managing Default Properties</h4>
+
+<p><a name="index-default-graphics-properties-1208"></a><a name="index-graphics-properties_002c-default-1209"></a>
+Object properties have two classes of default values, <dfn>factory
+defaults</dfn> (the initial values) and <dfn>user-defined defaults</dfn>, which
+may override the factory defaults.
+
+   <p>Although default values may be set for any object, they are set in
+parent objects and apply to child objects.  For example,
+
+<pre class="example">     set (0, "defaultlinecolor", "green");
+</pre>
+   <p class="noindent">sets the default line color for all objects.  The rule for constructing
+the property name to set a default value is
+
+<pre class="example">     default + <var>object-type</var> + <var>property-name</var>
+</pre>
+   <p>This rule can lead to some strange looking names, for example
+<code>defaultlinelinewidth"</code> specifies the default <code>linewidth</code>
+property for <code>line</code> objects.
+
+   <p>The example above used the root figure object, 0, so the default
+property value will apply to all line objects.  However, default values
+are hierarchical, so defaults set in a figure objects override those
+set in the root figure object.  Likewise, defaults set in axes objects
+override those set in figure or root figure objects.  For example,
+
+<pre class="example">     subplot (2, 1, 1);
+     set (0, "defaultlinecolor", "red");
+     set (1, "defaultlinecolor", "green");
+     set (gca (), "defaultlinecolor", "blue");
+     line (1:10, rand (1, 10));
+     subplot (2, 1, 2);
+     line (1:10, rand (1, 10));
+     figure (2)
+     line (1:10, rand (1, 10));
+</pre>
+   <p class="noindent">produces two figures.  The line in first subplot window of the first
+figure is blue because it inherits its color from its parent axes
+object.  The line in the second subplot window of the first figure is
+green because it inherits its color from its parent figure object.  The
+line in the second figure window is red because it inherits its color
+from the global root figure parent object.
+
+   <p>To remove a user-defined default setting, set the default property to
+the value <code>"remove"</code>.  For example,
+
+<pre class="example">     set (gca (), "defaultlinecolor", "remove");
+</pre>
+   <p class="noindent">removes the user-defined default line color setting from the current axes
+object.
+
+   <p>Getting the <code>"default"</code> property of an object returns a list of
+user-defined defaults set for the object.  For example,
+
+<pre class="example">     get (gca (), "default");
+</pre>
+   <p class="noindent">returns a list of user-defined default values for the current axes
+object.
+
+   <p>Factory default values are stored in the root figure object.  The
+command
+
+<pre class="example">     get (0, "factory");
+</pre>
+   <p class="noindent">returns a list of factory defaults.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Manipulating-Classes.html b/doc/interpreter/HTML/Manipulating-Classes.html
new file mode 100644
index 0000000..5694a17
--- /dev/null
+++ b/doc/interpreter/HTML/Manipulating-Classes.html
@@ -0,0 +1,233 @@
+<html lang="en">
+<head>
+<title>Manipulating Classes - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link rel="prev" href="Creating-a-Class.html#Creating-a-Class" title="Creating a Class">
+<link rel="next" href="Indexing-Objects.html#Indexing-Objects" title="Indexing Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Manipulating-Classes"></a>
+Next: <a rel="next" accesskey="n" href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="Creating-a-Class.html#Creating-a-Class">Creating a Class</a>,
+Up: <a rel="up" accesskey="u" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>
+<hr>
+</div>
+
+<h3 class="section">33.2 Manipulating Classes</h3>
+
+<p>There are a number of basic classes methods that can be defined to allow
+the contents of the classes to be queried and set.  The most basic of
+these is the <code>display</code> method.  The <code>display</code> method is used
+by Octave when displaying a class on the screen, due to an expression
+that is not terminated with a semicolon.  If this method is not defined,
+then Octave will printed nothing when displaying the contents of a class.
+
+<!-- ./general/display.m -->
+   <p><a name="doc_002ddisplay"></a>
+
+<div class="defun">
+— Function File:  <b>display</b> (<var>a</var>)<var><a name="index-display-2258"></a></var><br>
+<blockquote><p>Display the contents of an object.  If <var>a</var> is an object of the
+class "myclass", then <code>display</code> is called in a case like
+
+     <pre class="example">          myclass (...)
+</pre>
+        <p class="noindent">where Octave is required to display the contents of a variable of the
+type "myclass".
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclass.html#doc_002dclass">class</a>, <a href="doc_002dsubsref.html#doc_002dsubsref">subsref</a>, <a href="doc_002dsubsasgn.html#doc_002dsubsasgn">subsasgn</a>. 
+</p></blockquote></div>
+
+<p class="noindent">An example of a display method for the polynomial class might be
+
+<pre class="example"><pre class="verbatim">     function display (p)
+       a = p.poly;
+       first = true;
+       fprintf("%s =", inputname(1));
+       for i = 1 : length (a);
+         if (a(i) != 0)
+           if (first)
+             first = false;
+           elseif (a(i) > 0)
+             fprintf (" +");
+           endif
+           if (a(i) < 0)
+             fprintf (" -");
+           endif
+           if (i == 1)
+             fprintf (" %g", abs (a(i)));
+           elseif (abs(a(i)) != 1)
+             fprintf (" %g *", abs (a(i)));
+           endif
+           if (i > 1)
+             fprintf (" X");
+           endif
+           if (i > 2)
+             fprintf (" ^ %d", i - 1);
+           endif
+         endif
+       endfor
+       if (first)
+         fprintf(" 0");
+       endif
+       fprintf("\n");
+     endfunction
+</pre>
+</pre>
+   <p class="noindent">Note that in the display method, it makes sense to start the method
+with the line <code>fprintf("%s =", inputname(1))</code> to be consistent
+with the rest of Octave and print the variable name to be displayed
+when displaying the class.
+
+   <p>To be consistent with the Octave graphic handle classes, a class
+should also define the <code>get</code> and <code>set</code> methods.  The
+<code>get</code> method should accept one or two arguments, and given one
+argument of the appropriate class it should return a structure with
+all of the properties of the class.  For example
+
+<pre class="example"><pre class="verbatim">     function s = get (p, f)
+       if (nargin == 1)
+         s.poly = p.poly;
+       elseif (nargin == 2)
+         if (ischar (f))
+           switch (f)
+             case "poly"
+               s = p.poly;
+             otherwise
+               error ("get: invalid property %s", f);
+           endswitch
+         else
+           error ("get: expecting the property to be a string");
+         endif
+       else
+         print_usage ();
+       endif
+     endfunction
+</pre>
+</pre>
+   <p class="noindent">Similarly, the <code>set</code> method should taken as its first argument an
+object to modify, and then take property/value pairs to be modified.
+
+<pre class="example"><pre class="verbatim">     function s = set (p, varargin)
+       s = p;
+       if (length (varargin) < 2 || rem (length (varargin), 2) != 0)
+         error ("set: expecting property/value pairs");
+       endif
+       while (length (varargin) > 1)
+         prop = varargin{1};
+         val = varargin{2};
+         varargin(1:2) = [];
+         if (ischar (prop) && strcmp (prop, "poly"))
+           if (isvector (val) && isreal (val))
+             s.poly = val(:).';
+           else
+             error ("set: expecting the value to be a real vector");
+           endif
+         else
+           error ("set: invalid property of polynomial class");
+         endif
+       endwhile
+     endfunction
+</pre>
+</pre>
+   <p class="noindent">Note that as Octave does not implement pass by reference, than the
+modified object is the return value of the <code>set</code> method and it
+must be called like
+
+<pre class="example">     p = set (p, "a", [1, 0, 0, 0, 1]);
+</pre>
+   <p class="noindent">Also the <code>set</code> method makes use of the <code>subsasgn</code> method of
+the class, and this method must be defined.  The <code>subsasgn</code> method
+is discussed in the next section.
+
+   <p>Finally, user classes can be considered as a special type of a
+structure, and so they can be saved to a file in the same manner as a
+structure.  For example
+
+<pre class="example">     p = polynomial ([1, 0, 1]);
+     save userclass.mat p
+     clear p
+     load userclass.mat
+</pre>
+   <p class="noindent">All of the file formats supported by <code>save</code> and <code>load</code> are
+supported.  In certain circumstances, a user class might either contain
+a field that it makes no sense to save or a field that needs to be
+initialized before it is saved.  This can be done with the
+<code>saveobj</code> method of the class
+
+<!-- ./general/saveobj.m -->
+   <p><a name="doc_002dsaveobj"></a>
+
+<div class="defun">
+— Function File: <var>b</var> = <b>saveobj</b> (<var>a</var>)<var><a name="index-saveobj-2259"></a></var><br>
+<blockquote><p>Method of a class to manipulate an object prior to saving it to a file. 
+The function <code>saveobj</code> is called when the object <var>a</var> is saved
+using the <code>save</code> function.  An example of the use of <code>saveobj</code>
+might be to remove fields of the object that don't make sense to be saved
+or it might be used to ensure that certain fields of the object are
+initialized before the object is saved.  For example
+
+     <pre class="example">          function b = saveobj (a)
+            b = a;
+            if (isempty (b.field))
+               b.field = initfield(b);
+            endif
+          endfunction
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dloadobj.html#doc_002dloadobj">loadobj</a>, <a href="doc_002dclass.html#doc_002dclass">class</a>. 
+</p></blockquote></div>
+
+<p class="noindent"><code>saveobj</code> is called just prior to saving the class to a
+file.  Likely, the <code>loadobj</code> method is called just after a class
+is loaded from a file, and can be used to ensure that any removed
+fields are reinserted into the user object.
+
+<!-- ./general/loadobj.m -->
+   <p><a name="doc_002dloadobj"></a>
+
+<div class="defun">
+— Function File: <var>b</var> = <b>loadobj</b> (<var>a</var>)<var><a name="index-loadobj-2260"></a></var><br>
+<blockquote><p>Method of a class to manipulate an object after loading it from a file. 
+The function <code>loadobj</code> is called when the object <var>a</var> is loaded
+using the <code>load</code> function.  An example of the use of <code>saveobj</code>
+might be to add fields to an object that don't make sense to be saved. 
+For example
+
+     <pre class="example">          function b = loadobj (a)
+            b = a;
+            b.addmissingfield = addfield (b);
+          endfunction
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsaveobj.html#doc_002dsaveobj">saveobj</a>, <a href="doc_002dclass.html#doc_002dclass">class</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Manipulating-Strings.html b/doc/interpreter/HTML/Manipulating-Strings.html
new file mode 100644
index 0000000..1dbfce4
--- /dev/null
+++ b/doc/interpreter/HTML/Manipulating-Strings.html
@@ -0,0 +1,508 @@
+<html lang="en">
+<head>
+<title>Manipulating Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="prev" href="Comparing-Strings.html#Comparing-Strings" title="Comparing Strings">
+<link rel="next" href="String-Conversions.html#String-Conversions" title="String Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Manipulating-Strings"></a>
+Next: <a rel="next" accesskey="n" href="String-Conversions.html#String-Conversions">String Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.5 Manipulating Strings</h3>
+
+<p>Octave supports a wide range of functions for manipulating strings. 
+Since a string is just a matrix, simple manipulations can be accomplished
+using standard operators.  The following example shows how to replace
+all blank characters with underscores.
+
+<pre class="example">     quote = ...
+       "First things first, but not necessarily in that order";
+     quote( quote == " " ) = "_"
+      quote =
+         First_things_first,_but_not_necessarily_in_that_order
+</pre>
+   <p>For more complex manipulations, such as searching, replacing, and
+general regular expressions, the following functions come with Octave.
+
+<!-- ./strings/deblank.m -->
+   <p><a name="doc_002ddeblank"></a>
+
+<div class="defun">
+— Function File:  <b>deblank</b> (<var>s</var>)<var><a name="index-deblank-312"></a></var><br>
+<blockquote><p>Remove trailing blanks and nulls from <var>s</var>.  If <var>s</var>
+is a matrix, <var>deblank</var> trims each row to the length of longest
+string.  If <var>s</var> is a cell array, operate recursively on each
+element of the cell array. 
+</p></blockquote></div>
+
+<!-- ./strings/strtrim.m -->
+   <p><a name="doc_002dstrtrim"></a>
+
+<div class="defun">
+— Function File:  <b>strtrim</b> (<var>s</var>)<var><a name="index-strtrim-313"></a></var><br>
+<blockquote><p>Remove leading and trailing blanks and nulls from <var>s</var>.  If
+<var>s</var> is a matrix, <var>strtrim</var> trims each row to the length of
+longest string.  If <var>s</var> is a cell array, operate recursively on
+each element of the cell array.  For example:
+
+     <pre class="example">          strtrim ("    abc  ")
+                "abc"
+          
+          strtrim ([" abc   "; "   def   "])
+                ["abc  "; "  def"]
+</pre>
+        </blockquote></div>
+
+<!-- ./strings/strtrunc.m -->
+   <p><a name="doc_002dstrtrunc"></a>
+
+<div class="defun">
+— Function File:  <b>strtrunc</b> (<var>s, n</var>)<var><a name="index-strtrunc-314"></a></var><br>
+<blockquote><p>Truncate the character string <var>s</var> to length <var>n</var>.  If <var>s</var>
+is a char matrix, then the number of columns is adjusted.
+
+        <p>If <var>s</var> is a cell array of strings, then the operation is performed
+on its members and the new cell array is returned. 
+</p></blockquote></div>
+
+<!-- ./strings/findstr.m -->
+   <p><a name="doc_002dfindstr"></a>
+
+<div class="defun">
+— Function File:  <b>findstr</b> (<var>s, t, overlap</var>)<var><a name="index-findstr-315"></a></var><br>
+<blockquote><p>Return the vector of all positions in the longer of the two strings
+<var>s</var> and <var>t</var> where an occurrence of the shorter of the two starts. 
+If the optional argument <var>overlap</var> is nonzero, the returned vector
+can include overlapping positions (this is the default).  For example,
+
+     <pre class="example">          findstr ("ababab", "a")
+                [1, 3, 5]
+          findstr ("abababa", "aba", 0)
+                [1, 5]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrfind.html#doc_002dstrfind">strfind</a>, <a href="doc_002dstrmatch.html#doc_002dstrmatch">strmatch</a>, <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrncmp.html#doc_002dstrncmp">strncmp</a>, <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>, <a href="doc_002dstrncmpi.html#doc_002dstrncmpi">strncmpi</a>, <a href="doc_002dfind.html#doc_002dfind">find</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strchr.m -->
+   <p><a name="doc_002dstrchr"></a>
+
+<div class="defun">
+— Function File: <var>idx</var> = <b>strchr</b> (<var>str, chars</var>)<var><a name="index-strchr-316"></a></var><br>
+— Function File: <var>idx</var> = <b>strchr</b> (<var>str, chars, n</var>)<var><a name="index-strchr-317"></a></var><br>
+— Function File: <var>idx</var> = <b>strchr</b> (<var>str, chars, n, direction</var>)<var><a name="index-strchr-318"></a></var><br>
+<blockquote><p>Search for the string <var>str</var> for occurrences of characters from the set <var>chars</var>. 
+The return value, as well as the <var>n</var> and <var>direction</var> arguments behave
+identically as in <code>find</code>.
+
+        <p>This will be faster than using regexp in most cases.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfind.html#doc_002dfind">find</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/index.m -->
+   <p><a name="doc_002dindex"></a>
+
+<div class="defun">
+— Function File:  <b>index</b> (<var>s, t</var>)<var><a name="index-index-319"></a></var><br>
+— Function File:  <b>index</b> (<var>s, t, direction</var>)<var><a name="index-index-320"></a></var><br>
+<blockquote><p>Return the position of the first occurrence of the string <var>t</var> in the
+string <var>s</var>, or 0 if no occurrence is found.  For example,
+
+     <pre class="example">          index ("Teststring", "t")
+                4
+</pre>
+        <p>If <var>direction</var> is ‘<samp><span class="samp">"first"</span></samp>’, return the first element found. 
+If <var>direction</var> is ‘<samp><span class="samp">"last"</span></samp>’, return the last element found. 
+The <code>rindex</code> function is equivalent to <code>index</code> with
+<var>direction</var> set to ‘<samp><span class="samp">"last"</span></samp>’.
+
+        <p><strong>Caution:</strong>  This function does not work for arrays of
+character strings. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfind.html#doc_002dfind">find</a>, <a href="doc_002drindex.html#doc_002drindex">rindex</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/rindex.m -->
+   <p><a name="doc_002drindex"></a>
+
+<div class="defun">
+— Function File:  <b>rindex</b> (<var>s, t</var>)<var><a name="index-rindex-321"></a></var><br>
+<blockquote><p>Return the position of the last occurrence of the character string
+<var>t</var> in the character string <var>s</var>, or 0 if no occurrence is
+found.  For example,
+
+     <pre class="example">          rindex ("Teststring", "t")
+                6
+</pre>
+        <p><strong>Caution:</strong>  This function does not work for arrays of
+character strings. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfind.html#doc_002dfind">find</a>, <a href="doc_002dindex.html#doc_002dindex">index</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strfind.m -->
+   <p><a name="doc_002dstrfind"></a>
+
+<div class="defun">
+— Function File: <var>idx</var> = <b>strfind</b> (<var>str, pattern</var>)<var><a name="index-strfind-322"></a></var><br>
+— Function File: <var>idx</var> = <b>strfind</b> (<var>cellstr, pattern</var>)<var><a name="index-strfind-323"></a></var><br>
+<blockquote><p>Search for <var>pattern</var> in the string <var>str</var> and return the
+starting index of every such occurrence in the vector <var>idx</var>. 
+If there is no such occurrence, or if <var>pattern</var> is longer
+than <var>str</var>, then <var>idx</var> is the empty array <code>[]</code>.
+
+        <p>If the cell array of strings <var>cellstr</var> is specified instead of the
+string <var>str</var>, then <var>idx</var> is a cell array of vectors, as specified
+above.  Examples:
+
+     <pre class="example">          strfind ("abababa", "aba")
+                [1, 3, 5]
+          
+          strfind ({"abababa", "bebebe", "ab"}, "aba")
+                ans =
+                  {
+                    [1,1] =
+          
+                       1   3   5
+          
+                    [1,2] = [](1x0)
+                    [1,3] = [](1x0)
+                  }
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfindstr.html#doc_002dfindstr">findstr</a>, <a href="doc_002dstrmatch.html#doc_002dstrmatch">strmatch</a>, <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrncmp.html#doc_002dstrncmp">strncmp</a>, <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>, <a href="doc_002dstrncmpi.html#doc_002dstrncmpi">strncmpi</a>, <a href="doc_002dfind.html#doc_002dfind">find</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strmatch.m -->
+   <p><a name="doc_002dstrmatch"></a>
+
+<div class="defun">
+— Function File:  <b>strmatch</b> (<var>s, a, "exact"</var>)<var><a name="index-strmatch-324"></a></var><br>
+<blockquote><p>Return indices of entries of <var>a</var> that match the string <var>s</var>. 
+The second argument <var>a</var> may be a string matrix or a cell array of
+strings.  If the third argument <code>"exact"</code> is not given, then
+<var>s</var> only needs to match <var>a</var> up to the length of <var>s</var>.  Nul
+characters match blanks.  Results are returned as a column vector. 
+For example:
+
+     <pre class="example">          strmatch ("apple", "apple juice")
+                1
+          
+          strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
+                [1; 2]
+          
+          strmatch ("apple", {"apple pie"; "apple juice"; "tomato"})
+                [1; 2]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrfind.html#doc_002dstrfind">strfind</a>, <a href="doc_002dfindstr.html#doc_002dfindstr">findstr</a>, <a href="doc_002dstrcmp.html#doc_002dstrcmp">strcmp</a>, <a href="doc_002dstrncmp.html#doc_002dstrncmp">strncmp</a>, <a href="doc_002dstrcmpi.html#doc_002dstrcmpi">strcmpi</a>, <a href="doc_002dstrncmpi.html#doc_002dstrncmpi">strncmpi</a>, <a href="doc_002dfind.html#doc_002dfind">find</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strtok.m -->
+   <p><a name="doc_002dstrtok"></a>
+
+<div class="defun">
+— Function File: [<var>tok</var>, <var>rem</var>] = <b>strtok</b> (<var>str, delim</var>)<var><a name="index-strtok-325"></a></var><br>
+<blockquote>
+        <p>Find all characters up to but not including the first character which
+is in the string delim.  If <var>rem</var> is requested, it contains the
+remainder of the string, starting at the first delimiter.  Leading
+delimiters are ignored.  If <var>delim</var> is not specified, space is
+assumed.  For example:
+
+     <pre class="example">          strtok ("this is the life")
+                "this"
+          
+          [tok, rem] = strtok ("14*27+31", "+-*/")
+               
+                  tok = 14
+                  rem = *27+31
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dindex.html#doc_002dindex">index</a>, <a href="doc_002dstrsplit.html#doc_002dstrsplit">strsplit</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strsplit.m -->
+   <p><a name="doc_002dstrsplit"></a>
+
+<div class="defun">
+— Function File: [<var>s</var>] = <b>strsplit</b> (<var>p, sep, strip_empty</var>)<var><a name="index-strsplit-326"></a></var><br>
+<blockquote><p>Split a single string using one or more delimiters and return a cell
+array of strings.  Consecutive delimiters and delimiters at
+boundaries result in empty strings, unless <var>strip_empty</var> is true. 
+The default value of <var>strip_empty</var> is false. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrtok.html#doc_002dstrtok">strtok</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strrep.m -->
+   <p><a name="doc_002dstrrep"></a>
+
+<div class="defun">
+— Function File:  <b>strrep</b> (<var>s, x, y</var>)<var><a name="index-strrep-327"></a></var><br>
+<blockquote><p>Replace all occurrences of the substring <var>x</var> of the string <var>s</var>
+with the string <var>y</var> and return the result.  For example,
+
+     <pre class="example">          strrep ("This is a test string", "is", "&%$")
+                "Th&%$ &%$ a test string"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dregexprep.html#doc_002dregexprep">regexprep</a>, <a href="doc_002dstrfind.html#doc_002dstrfind">strfind</a>, <a href="doc_002dfindstr.html#doc_002dfindstr">findstr</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/substr.m -->
+   <p><a name="doc_002dsubstr"></a>
+
+<div class="defun">
+— Function File:  <b>substr</b> (<var>s, offset, len</var>)<var><a name="index-substr-328"></a></var><br>
+<blockquote><p>Return the substring of <var>s</var> which starts at character number
+<var>offset</var> and is <var>len</var> characters long.
+
+        <p>If <var>offset</var> is negative, extraction starts that far from the end of
+the string.  If <var>len</var> is omitted, the substring extends to the end
+of S.
+
+        <p>For example,
+
+     <pre class="example">          substr ("This is a test string", 6, 9)
+                "is a test"
+</pre>
+        <p>This function is patterned after AWK.  You can get the same result by
+<var>s</var><code>(</code><var>offset</var><code> : (</code><var>offset</var><code> + </code><var>len</var><code> - 1))</code>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/regexp.cc -->
+   <p><a name="doc_002dregexp"></a>
+
+<div class="defun">
+— Loadable Function: [<var>s</var>, <var>e</var>, <var>te</var>, <var>m</var>, <var>t</var>, <var>nm</var>] = <b>regexp</b> (<var>str, pat</var>)<var><a name="index-regexp-329"></a></var><br>
+— Loadable Function: [<small class="dots">...</small>] = <b>regexp</b> (<var>str, pat, opts, <small class="dots">...</small></var>)<var><a name="index-regexp-330"></a></var><br>
+<blockquote>
+        <p>Regular expression string matching.  Matches <var>pat</var> in <var>str</var> and
+returns the position and matching substrings or empty values if there are
+none.
+
+        <p>The matched pattern <var>pat</var> can include any of the standard regex
+operators, including:
+
+          <dl>
+<dt><code>.</code><dd>Match any character
+<br><dt><code>* + ? {}</code><dd>Repetition operators, representing
+               <dl>
+<dt><code>*</code><dd>Match zero or more times
+<br><dt><code>+</code><dd>Match one or more times
+<br><dt><code>?</code><dd>Match zero or one times
+<br><dt><code>{}</code><dd>Match range operator, which is of the form <code>{</code><var>n</var><code>}</code> to match exactly
+<var>n</var> times, <code>{</code><var>m</var><code>,}</code> to match <var>m</var> or more times,
+<code>{</code><var>m</var><code>,</code><var>n</var><code>}</code> to match between <var>m</var> and <var>n</var> times. 
+</dl>
+          <br><dt><code>[...] [^...]</code><dd>List operators, where for example <code>[ab]c</code> matches <code>ac</code> and <code>bc</code>
+<br><dt><code>()</code><dd>Grouping operator
+<br><dt><code>|</code><dd>Alternation operator.  Match one of a choice of regular expressions.  The
+alternatives must be delimited by the grouping operator <code>()</code> above
+<br><dt><code>^ $</code><dd>Anchoring operator.  <code>^</code> matches the start of the string <var>str</var> and
+<code>$</code> the end
+</dl>
+
+        <p>In addition the following escaped characters have special meaning.  It should
+be noted that it is recommended to quote <var>pat</var> in single quotes rather
+than double quotes, to avoid the escape sequences being interpreted by Octave
+before being passed to <code>regexp</code>.
+
+          <dl>
+<dt><code>\b</code><dd>Match a word boundary
+<br><dt><code>\B</code><dd>Match within a word
+<br><dt><code>\w</code><dd>Matches any word character
+<br><dt><code>\W</code><dd>Matches any non word character
+<br><dt><code>\<</code><dd>Matches the beginning of a word
+<br><dt><code>\></code><dd>Matches the end of a word
+<br><dt><code>\s</code><dd>Matches any whitespace character
+<br><dt><code>\S</code><dd>Matches any non whitespace character
+<br><dt><code>\d</code><dd>Matches any digit
+<br><dt><code>\D</code><dd>Matches any non-digit
+</dl>
+
+        <p>The outputs of <code>regexp</code> by default are in the order as given below
+
+          <dl>
+<dt><var>s</var><dd>The start indices of each of the matching substrings
+
+          <br><dt><var>e</var><dd>The end indices of each matching substring
+
+          <br><dt><var>te</var><dd>The extents of each of the matched token surrounded by <code>(...)</code> in
+<var>pat</var>.
+
+          <br><dt><var>m</var><dd>A cell array of the text of each match.
+
+          <br><dt><var>t</var><dd>A cell array of the text of each token matched.
+
+          <br><dt><var>nm</var><dd>A structure containing the text of each matched named token, with the name
+being used as the fieldname.  A named token is denoted as
+<code>(?<name>...)</code>
+</dl>
+
+        <p>Particular output arguments or the order of the output arguments can be
+selected by additional <var>opts</var> arguments.  These are strings and the
+correspondence between the output arguments and the optional argument
+are
+
+        <p><table summary=""><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">'start'        </td><td valign="top" width="30%"><var>s</var>  </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">'end'          </td><td valign="top" width="30%"><var>e</var>  </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">'tokenExtents' </td><td valign="top" width="30%"><var>te</var> </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">'match'        </td><td valign="top" width="30%"><var>m</var>  </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">'tokens'       </td><td valign="top" width="30%"><var>t</var>  </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">'names'        </td><td valign="top" width="30%"><var>nm</var>  </td><td valign="top" width="20%">
+        <br></td></tr></table>
+
+        <p>A further optional argument is 'once', that limits the number of returned
+matches to the first match.  Additional arguments are
+
+          <dl>
+<dt>matchcase<dd>Make the matching case sensitive. 
+<br><dt>ignorecase<dd>Make the matching case insensitive. 
+<br><dt>stringanchors<dd>Match the anchor characters at the beginning and end of the string. 
+<br><dt>lineanchors<dd>Match the anchor characters at the beginning and end of the line. 
+<br><dt>dotall<dd>The character <code>.</code> matches the newline character. 
+<br><dt>dotexceptnewline<dd>The character <code>.</code> matches all but the newline character. 
+<br><dt>freespacing<dd>The pattern can include arbitrary whitespace and comments starting with
+<code>#</code>. 
+<br><dt>literalspacing<dd>The pattern is taken literally. 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dregexpi.html#doc_002dregexpi">regexpi</a>, <a href="doc_002dregexprep.html#doc_002dregexprep">regexprep</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/regexp.cc -->
+   <p><a name="doc_002dregexpi"></a>
+
+<div class="defun">
+— Loadable Function: [<var>s</var>, <var>e</var>, <var>te</var>, <var>m</var>, <var>t</var>, <var>nm</var>] = <b>regexpi</b> (<var>str, pat</var>)<var><a name="index-regexpi-331"></a></var><br>
+— Loadable Function: [<small class="dots">...</small>] = <b>regexpi</b> (<var>str, pat, opts, <small class="dots">...</small></var>)<var><a name="index-regexpi-332"></a></var><br>
+<blockquote>
+        <p>Case insensitive regular expression string matching.  Matches <var>pat</var> in
+<var>str</var> and returns the position and matching substrings or empty values
+if there are none.  See <a href="doc_002dregexp.html#doc_002dregexp">regexp</a>, for more details
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/regexp.cc -->
+   <p><a name="doc_002dregexprep"></a>
+
+<div class="defun">
+— Loadable Function: <var>string</var> = <b>regexprep</b> (<var>string, pat, repstr, options</var>)<var><a name="index-regexprep-333"></a></var><br>
+<blockquote><p>Replace matches of <var>pat</var> in  <var>string</var> with <var>repstr</var>.
+
+        <p>The replacement can contain <code>$i</code>, which substitutes
+for the ith set of parentheses in the match string.  E.g.,
+     <pre class="example">          
+             regexprep("Bill Dunn",'(\w+) (\w+)','$2, $1')
+</pre>
+        <p>returns "Dunn, Bill"
+
+        <p><var>options</var> may be zero or more of
+          <dl>
+<dt>‘<samp><span class="samp">once</span></samp>’<dd>Replace only the first occurrence of <var>pat</var> in the result.
+
+          <br><dt>‘<samp><span class="samp">warnings</span></samp>’<dd>This option is present for compatibility but is ignored.
+
+          <br><dt>‘<samp><span class="samp">ignorecase or matchcase</span></samp>’<dd>Ignore case for the pattern matching (see <code>regexpi</code>). 
+Alternatively, use (?i) or (?-i) in the pattern.
+
+          <br><dt>‘<samp><span class="samp">lineanchors and stringanchors</span></samp>’<dd>Whether characters ^ and $ match the beginning and ending of lines. 
+Alternatively, use (?m) or (?-m) in the pattern.
+
+          <br><dt>‘<samp><span class="samp">dotexceptnewline and dotall</span></samp>’<dd>Whether . matches newlines in the string. 
+Alternatively, use (?s) or (?-s) in the pattern.
+
+          <br><dt>‘<samp><span class="samp">freespacing or literalspacing</span></samp>’<dd>Whether whitespace and # comments can be used to make the regular expression more readable. 
+Alternatively, use (?x) or (?-x) in the pattern.
+
+        </dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dregexp.html#doc_002dregexp">regexp</a>, <a href="doc_002dregexpi.html#doc_002dregexpi">regexpi</a>, <a href="doc_002dstrrep.html#doc_002dstrrep">strrep</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/regexptranslate.m -->
+   <p><a name="doc_002dregexptranslate"></a>
+
+<div class="defun">
+— Function File:  <b>regexptranslate</b> (<var>op, s</var>)<var><a name="index-regexptranslate-334"></a></var><br>
+<blockquote><p>Translate a string for use in a regular expression.  This might
+include either wildcard replacement or special character escaping. 
+The behavior can be controlled by the <var>op</var> that can have the
+values
+
+          <dl>
+<dt>"wildcard"<dd>The wildcard characters <code>.</code>, <code>*</code> and <code>?</code> are replaced
+with wildcards that are appropriate for a regular expression. 
+For example:
+          <pre class="example">               regexptranslate ("wildcard", "*.m")
+                     ".*\.m"
+</pre>
+          <br><dt>"escape"<dd>The characters <code>$.?[]</code>, that have special meaning for regular
+expressions are escaped so that they are treated literally.  For example:
+          <pre class="example">               regexptranslate ("escape", "12.5")
+                     "12\.5"
+</pre>
+          </dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dregexp.html#doc_002dregexp">regexp</a>, <a href="doc_002dregexpi.html#doc_002dregexpi">regexpi</a>, <a href="doc_002dregexprep.html#doc_002dregexprep">regexprep</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Manipulating-Structures.html b/doc/interpreter/HTML/Manipulating-Structures.html
new file mode 100644
index 0000000..e0727c3
--- /dev/null
+++ b/doc/interpreter/HTML/Manipulating-Structures.html
@@ -0,0 +1,155 @@
+<html lang="en">
+<head>
+<title>Manipulating Structures - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Structures.html#Data-Structures" title="Data Structures">
+<link rel="prev" href="Creating-Structures.html#Creating-Structures" title="Creating Structures">
+<link rel="next" href="Processing-Data-in-Structures.html#Processing-Data-in-Structures" title="Processing Data in Structures">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Manipulating-Structures"></a>
+Next: <a rel="next" accesskey="n" href="Processing-Data-in-Structures.html#Processing-Data-in-Structures">Processing Data in Structures</a>,
+Previous: <a rel="previous" accesskey="p" href="Creating-Structures.html#Creating-Structures">Creating Structures</a>,
+Up: <a rel="up" accesskey="u" href="Data-Structures.html#Data-Structures">Data Structures</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.1.4 Manipulating Structures</h4>
+
+<p>Other functions that can manipulate the fields of a structure are given below.
+
+<!-- ov-struct.cc -->
+   <p><a name="doc_002drmfield"></a>
+
+<div class="defun">
+— Built-in Function:  <b>rmfield</b> (<var>s, f</var>)<var><a name="index-rmfield-375"></a></var><br>
+<blockquote><p>Remove field <var>f</var> from the structure <var>s</var>.  If <var>f</var> is a
+cell array of character strings or a character array, remove the
+named fields. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcellstr.html#doc_002dcellstr">cellstr</a>, <a href="doc_002discellstr.html#doc_002discellstr">iscellstr</a>, <a href="doc_002dsetfield.html#doc_002dsetfield">setfield</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/setfield.m -->
+   <p><a name="doc_002dsetfield"></a>
+
+<div class="defun">
+— Function File: [<var>k1</var>, <small class="dots">...</small>, <var>v1</var>] = <b>setfield</b> (<var>s, k1, v1, <small class="dots">...</small></var>)<var><a name="index-setfield-376"></a></var><br>
+<blockquote><p>Set field members in a structure.
+
+     <pre class="example">          oo(1,1).f0 = 1;
+          oo = setfield (oo, {1,2}, "fd", {3}, "b", 6);
+          oo(1,2).fd(3).b == 6
+           ans = 1
+</pre>
+        <p>Note that this function could be written
+
+     <pre class="example">          i1 = {1,2}; i2 = "fd"; i3 = {3}; i4 = "b";
+          oo(i1{:}).(i2)(i3{:}).(i4) == 6;
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgetfield.html#doc_002dgetfield">getfield</a>, <a href="doc_002drmfield.html#doc_002drmfield">rmfield</a>, <a href="doc_002disfield.html#doc_002disfield">isfield</a>, <a href="doc_002disstruct.html#doc_002disstruct">isstruct</a>, <a href="doc_002dfieldnames.html#doc_002dfieldnames">fieldnames</a>, <a href="doc_002dstruct.html#doc_002dstruct">struct</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/orderfields.m -->
+   <p><a name="doc_002dorderfields"></a>
+
+<div class="defun">
+— Function File: [<var>t</var>, <var>p</var>] = <b>orderfields</b> (<var>s1, s2</var>)<var><a name="index-orderfields-377"></a></var><br>
+<blockquote><p>Return a struct with fields arranged alphabetically or as specified
+by <var>s2</var> and a corresponding permutation vector.
+
+        <p>Given one struct, arrange field names in <var>s1</var> alphabetically.
+
+        <p>Given two structs, arrange field names in <var>s1</var> as they appear
+in <var>s2</var>.  The second argument may also specify the order in
+a permutation vector or a cell array of strings.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgetfield.html#doc_002dgetfield">getfield</a>, <a href="doc_002drmfield.html#doc_002drmfield">rmfield</a>, <a href="doc_002disfield.html#doc_002disfield">isfield</a>, <a href="doc_002disstruct.html#doc_002disstruct">isstruct</a>, <a href="doc_002dfieldnames.html#doc_002dfieldnames">fieldnames</a>, <a href="doc_002dstruct.html#doc_002dstruct">struct</a>. 
+</p></blockquote></div>
+
+<!-- ov-struct.cc -->
+   <p><a name="doc_002dfieldnames"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fieldnames</b> (<var>struct</var>)<var><a name="index-fieldnames-378"></a></var><br>
+<blockquote><p>Return a cell array of strings naming the elements of the structure
+<var>struct</var>.  It is an error to call <code>fieldnames</code> with an
+argument that is not a structure. 
+</p></blockquote></div>
+
+<!-- ov-struct.cc -->
+   <p><a name="doc_002disfield"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isfield</b> (<var>expr, name</var>)<var><a name="index-isfield-379"></a></var><br>
+<blockquote><p>Return true if the expression <var>expr</var> is a structure and it includes an
+element named <var>name</var>.  The first argument must be a structure and
+the second must be a string. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/getfield.m -->
+   <p><a name="doc_002dgetfield"></a>
+
+<div class="defun">
+— Function File: [<var>v1</var>, <small class="dots">...</small>] = <b>getfield</b> (<var>s, key, <small class="dots">...</small></var>)<var><a name="index-getfield-380"></a></var><br>
+<blockquote><p>Extract fields from a structure.  For example
+
+     <pre class="example">          ss(1,2).fd(3).b = 5;
+          getfield (ss, {1,2}, "fd", {3}, "b")
+           ans = 5
+</pre>
+        <p>Note that the function call in the previous example is equivalent to
+the expression
+
+     <pre class="example">          i1 = {1,2}; i2 = "fd"; i3 = {3}; i4= "b";
+          ss(i1{:}).(i2)(i3{:}).(i4)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsetfield.html#doc_002dsetfield">setfield</a>, <a href="doc_002drmfield.html#doc_002drmfield">rmfield</a>, <a href="doc_002disfield.html#doc_002disfield">isfield</a>, <a href="doc_002disstruct.html#doc_002disstruct">isstruct</a>, <a href="doc_002dfieldnames.html#doc_002dfieldnames">fieldnames</a>, <a href="doc_002dstruct.html#doc_002dstruct">struct</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/substruct.m -->
+   <p><a name="doc_002dsubstruct"></a>
+
+<div class="defun">
+— Function File:  <b>substruct</b> (<var>type, subs, <small class="dots">...</small></var>)<var><a name="index-substruct-381"></a></var><br>
+<blockquote><p>Create a subscript structure for use with <code>subsref</code> or
+<code>subsasgn</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsubsref.html#doc_002dsubsref">subsref</a>, <a href="doc_002dsubsasgn.html#doc_002dsubsasgn">subsasgn</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Manipulating-the-load-path.html b/doc/interpreter/HTML/Manipulating-the-load-path.html
new file mode 100644
index 0000000..41d81fa
--- /dev/null
+++ b/doc/interpreter/HTML/Manipulating-the-load-path.html
@@ -0,0 +1,238 @@
+<html lang="en">
+<head>
+<title>Manipulating the load path - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="next" href="Subfunctions.html#Subfunctions" title="Subfunctions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Manipulating-the-load-path"></a>
+Next: <a rel="next" accesskey="n" href="Subfunctions.html#Subfunctions">Subfunctions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Files.html#Function-Files">Function Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.7.1 Manipulating the load path</h4>
+
+<p>When a function is called, Octave searches a list of directories for
+a file that contains the function declaration.  This list of directories
+is known as the load path.  By default the load path contains
+a list of directories distributed with Octave plus the current
+working directory.  To see your current load path call the <code>path</code>
+function without any input or output arguments.
+
+   <p>It is possible to add or remove directories to or from the load path
+using <code>addpath</code> and <code>rmpath</code>.  As an example, the following
+code adds ‘<samp><span class="samp">~/Octave</span></samp>’ to the load path.
+
+<pre class="example">     addpath("~/Octave")
+</pre>
+   <p class="noindent">After this the directory ‘<samp><span class="samp">~/Octave</span></samp>’ will be searched for functions.
+
+<!-- load-path.cc -->
+   <p><a name="doc_002daddpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>addpath</b> (<var>dir1, <small class="dots">...</small></var>)<var><a name="index-addpath-621"></a></var><br>
+— Built-in Function:  <b>addpath</b> (<var>dir1, <small class="dots">...</small>, option</var>)<var><a name="index-addpath-622"></a></var><br>
+<blockquote><p>Add <var>dir1</var>, <small class="dots">...</small> to the current function search path.  If
+<var>option</var> is ‘<samp><span class="samp">"-begin"</span></samp>’ or 0 (the default), prepend the
+directory name to the current path.  If <var>option</var> is ‘<samp><span class="samp">"-end"</span></samp>’
+or 1, append the directory name to the current path. 
+Directories added to the path must exist. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpath.html#doc_002dpath">path</a>, <a href="doc_002drmpath.html#doc_002drmpath">rmpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dpathdef.html#doc_002dpathdef">pathdef</a>, <a href="doc_002dsavepath.html#doc_002dsavepath">savepath</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- load-path.cc -->
+   <p><a name="doc_002dgenpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>genpath</b> (<var>dir</var>)<var><a name="index-genpath-623"></a></var><br>
+<blockquote><p>Return a path constructed from <var>dir</var> and all its subdirectories. 
+</p></blockquote></div>
+
+<!-- load-path.cc -->
+   <p><a name="doc_002drmpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>rmpath</b> (<var>dir1, <small class="dots">...</small></var>)<var><a name="index-rmpath-624"></a></var><br>
+<blockquote><p>Remove <var>dir1</var>, <small class="dots">...</small> from the current function search path.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpath.html#doc_002dpath">path</a>, <a href="doc_002daddpath.html#doc_002daddpath">addpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dpathdef.html#doc_002dpathdef">pathdef</a>, <a href="doc_002dsavepath.html#doc_002dsavepath">savepath</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- ./path/savepath.m -->
+   <p><a name="doc_002dsavepath"></a>
+
+<div class="defun">
+— Function File:  <b>savepath</b> (<var>file</var>)<var><a name="index-savepath-625"></a></var><br>
+<blockquote><p>Save the portion of the current function search path, that is
+not set during Octave's initialization process, to <var>file</var>. 
+If <var>file</var> is omitted, <samp><span class="file">~/.octaverc</span></samp> is used.  If successful,
+<code>savepath</code> returns 0. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpath.html#doc_002dpath">path</a>, <a href="doc_002daddpath.html#doc_002daddpath">addpath</a>, <a href="doc_002drmpath.html#doc_002drmpath">rmpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dpathdef.html#doc_002dpathdef">pathdef</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- load-path.cc -->
+   <p><a name="doc_002dpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>path</b> (<var><small class="dots">...</small></var>)<var><a name="index-path-626"></a></var><br>
+<blockquote><p>Modify or display Octave's load path.
+
+        <p>If <var>nargin</var> and <var>nargout</var> are zero, display the elements of
+Octave's load path in an easy to read format.
+
+        <p>If <var>nargin</var> is zero and nargout is greater than zero, return the
+current load path.
+
+        <p>If <var>nargin</var> is greater than zero, concatenate the arguments,
+separating them with <code>pathsep()</code>.  Set the internal search path
+to the result and return it.
+
+        <p>No checks are made for duplicate elements. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002daddpath.html#doc_002daddpath">addpath</a>, <a href="doc_002drmpath.html#doc_002drmpath">rmpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dpathdef.html#doc_002dpathdef">pathdef</a>, <a href="doc_002dsavepath.html#doc_002dsavepath">savepath</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- ./path/pathdef.m -->
+   <p><a name="doc_002dpathdef"></a>
+
+<div class="defun">
+— Function File: <var>val</var> = <b>pathdef</b> ()<var><a name="index-pathdef-627"></a></var><br>
+<blockquote><p>Return the default path for Octave. 
+The path information is extracted from one of three sources. 
+In order of preference, those are;
+
+          <ol type=1 start=1>
+<li><samp><span class="file">~/.octaverc</span></samp>
+<li><samp><span class="file"><octave-home>/.../<version>/m/startup/octaverc</span></samp>
+<li>Octave's path prior to changes by any octaverc.
+             </ol>
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpath.html#doc_002dpath">path</a>, <a href="doc_002daddpath.html#doc_002daddpath">addpath</a>, <a href="doc_002drmpath.html#doc_002drmpath">rmpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dsavepath.html#doc_002dsavepath">savepath</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- dirfns.cc -->
+   <p><a name="doc_002dpathsep"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>pathsep</b> ()<var><a name="index-pathsep-628"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>pathsep</b> (<var>new_val</var>)<var><a name="index-pathsep-629"></a></var><br>
+<blockquote><p>Query or set the character used to separate directories in
+a path. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfilesep.html#doc_002dfilesep">filesep</a>, <a href="doc_002ddir.html#doc_002ddir">dir</a>, <a href="doc_002dls.html#doc_002dls">ls</a>. 
+</p></blockquote></div>
+
+<!-- load-path.cc -->
+   <p><a name="doc_002drehash"></a>
+
+<div class="defun">
+— Built-in Function:  <b>rehash</b> ()<var><a name="index-rehash-630"></a></var><br>
+<blockquote><p>Reinitialize Octave's load path directory cache. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dfile_005fin_005floadpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>file_in_loadpath</b> (<var>file</var>)<var><a name="index-file_005fin_005floadpath-631"></a></var><br>
+— Built-in Function:  <b>file_in_loadpath</b> (<var>file, "all"</var>)<var><a name="index-file_005fin_005floadpath-632"></a></var><br>
+<blockquote>
+        <p>Return the absolute name of <var>file</var> if it can be found in
+the list of directories specified by <code>path</code>. 
+If no file is found, return an empty matrix.
+
+        <p>If the first argument is a cell array of strings, search each
+directory of the loadpath for element of the cell array and return
+the first that matches.
+
+        <p>If the second optional argument <code>"all"</code> is supplied, return
+a cell array containing the list of all files that have the same
+name in the path.  If no files are found, return an empty cell array. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfile_005fin_005fpath.html#doc_002dfile_005fin_005fpath">file_in_path</a>, <a href="doc_002dpath.html#doc_002dpath">path</a>. 
+</p></blockquote></div>
+
+<!-- load-path.cc -->
+   <p><a name="doc_002drestoredefaultpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>restoredefaultpath</b> (<var><small class="dots">...</small></var>)<var><a name="index-restoredefaultpath-633"></a></var><br>
+<blockquote><p>Restore Octave's path to it's initial state at startup.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpath.html#doc_002dpath">path</a>, <a href="doc_002daddpath.html#doc_002daddpath">addpath</a>, <a href="doc_002drmpath.html#doc_002drmpath">rmpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dpathdef.html#doc_002dpathdef">pathdef</a>, <a href="doc_002dsavepath.html#doc_002dsavepath">savepath</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- load-path.cc -->
+   <p><a name="doc_002dcommand_005fline_005fpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>command_line_path</b> (<var><small class="dots">...</small></var>)<var><a name="index-command_005fline_005fpath-634"></a></var><br>
+<blockquote><p>Return the command line path variable.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpath.html#doc_002dpath">path</a>, <a href="doc_002daddpath.html#doc_002daddpath">addpath</a>, <a href="doc_002drmpath.html#doc_002drmpath">rmpath</a>, <a href="doc_002dgenpath.html#doc_002dgenpath">genpath</a>, <a href="doc_002dpathdef.html#doc_002dpathdef">pathdef</a>, <a href="doc_002dsavepath.html#doc_002dsavepath">savepath</a>, <a href="doc_002dpathsep.html#doc_002dpathsep">pathsep</a>. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dfind_005fdir_005fin_005fpath"></a>
+
+<div class="defun">
+— Built-in Function:  <b>find_dir_in_path</b> (<var>dir</var>)<var><a name="index-find_005fdir_005fin_005fpath-635"></a></var><br>
+<blockquote><p>Return the full name of the path element matching <var>dir</var>.  The
+match is performed at the end of each path element.  For example, if
+<var>dir</var> is <code>"foo/bar"</code>, it matches the path element
+<code>"/some/dir/foo/bar"</code>, but not <code>"/some/dir/foo/bar/baz"</code>
+or <code>"/some/dir/allfoo/bar"</code>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Marker-Styles.html b/doc/interpreter/HTML/Marker-Styles.html
new file mode 100644
index 0000000..3d78141
--- /dev/null
+++ b/doc/interpreter/HTML/Marker-Styles.html
@@ -0,0 +1,54 @@
+<html lang="en">
+<head>
+<title>Marker Styles - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Line-Styles.html#Line-Styles" title="Line Styles">
+<link rel="next" href="Callbacks.html#Callbacks" title="Callbacks">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Marker-Styles"></a>
+Next: <a rel="next" accesskey="n" href="Callbacks.html#Callbacks">Callbacks</a>,
+Previous: <a rel="previous" accesskey="p" href="Line-Styles.html#Line-Styles">Line Styles</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.6 Marker Styles</h4>
+
+<p><a name="index-graphics-marker-styles-1214"></a><a name="index-marker-styles_002c-graphics-1215"></a>
+Marker styles are specified by the following properties:
+     <dl>
+<dt><code>marker</code><dd>A character indicating a plot marker to be place at each data point, or
+<code>"none"</code>, meaning no markers should be displayed.
+
+     <dt><code>markeredgecolor</code><dd>The color of the edge around the marker, or <code>"auto"</code>, meaning that
+the edge color is the same as the face color.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <dt><code>markerfacecolor</code><dd>The color of the marker, or <code>"none"</code> to indicate that the marker
+should not be filled.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <dt><code>markersize</code><dd>A number specifying the size of the marker.  The default is 1.  A value
+of 2 is twice as large as the default, etc. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Mathematical-Considerations.html b/doc/interpreter/HTML/Mathematical-Considerations.html
new file mode 100644
index 0000000..fbdaed1
--- /dev/null
+++ b/doc/interpreter/HTML/Mathematical-Considerations.html
@@ -0,0 +1,555 @@
+<html lang="en">
+<head>
+<title>Mathematical Considerations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Operators-and-Functions.html#Operators-and-Functions" title="Operators and Functions">
+<link rel="prev" href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions" title="Return Types of Operators and Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Mathematical-Considerations"></a>
+Previous: <a rel="previous" accesskey="p" href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions">Return Types of Operators and Functions</a>,
+Up: <a rel="up" accesskey="u" href="Operators-and-Functions.html#Operators-and-Functions">Operators and Functions</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">21.1.4.3 Mathematical Considerations</h5>
+
+<p>The attempt has been made to make sparse matrices behave in exactly the
+same manner as there full counterparts.  However, there are certain differences
+and especially differences with other products sparse implementations.
+
+   <p>Firstly, the "./" and ".^" operators must be used with care.  Consider what
+the examples
+
+<pre class="example">       s = speye (4);
+       a1 = s .^ 2;
+       a2 = s .^ s;
+       a3 = s .^ -2;
+       a4 = s ./ 2;
+       a5 = 2 ./ s;
+       a6 = s ./ s;
+</pre>
+   <p>will give.  The first example of <var>s</var> raised to the power of 2 causes
+no problems.  However <var>s</var> raised element-wise to itself involves a
+large number of terms <code>0 .^ 0</code> which is 1. There <var>s</var><code> .^
+</code><var>s</var> is a full matrix.
+
+   <p>Likewise <var>s</var><code> .^ -2</code> involves terms like <code>0 .^ -2</code> which
+is infinity, and so <var>s</var><code> .^ -2</code> is equally a full matrix.
+
+   <p>For the "./" operator <var>s</var><code> ./ 2</code> has no problems, but
+<code>2 ./ </code><var>s</var> involves a large number of infinity terms as well
+and is equally a full matrix.  The case of <var>s</var><code> ./ </code><var>s</var>
+involves terms like <code>0 ./ 0</code> which is a <code>NaN</code> and so this
+is equally a full matrix with the zero elements of <var>s</var> filled with
+<code>NaN</code> values.
+
+   <p>The above behavior is consistent with full matrices, but is not
+consistent with sparse implementations in other products.
+
+   <p>A particular problem of sparse matrices comes about due to the fact that
+as the zeros are not stored, the sign-bit of these zeros is equally not
+stored.  In certain cases the sign-bit of zero is important.  For example
+
+<pre class="example">      a = 0 ./ [-1, 1; 1, -1];
+      b = 1 ./ a
+       -Inf            Inf
+          Inf           -Inf
+      c = 1 ./ sparse (a)
+        Inf            Inf
+          Inf            Inf
+</pre>
+   <p>To correct this behavior would mean that zero elements with a negative
+sign-bit would need to be stored in the matrix to ensure that their
+sign-bit was respected.  This is not done at this time, for reasons of
+efficiency, and so the user is warned that calculations where the sign-bit
+of zero is important must not be done using sparse matrices.
+
+   <p>In general any function or operator used on a sparse matrix will
+result in a sparse matrix with the same or a larger number of non-zero
+elements than the original matrix.  This is particularly true for the
+important case of sparse matrix factorizations.  The usual way to
+address this is to reorder the matrix, such that its factorization is
+sparser than the factorization of the original matrix.  That is the
+factorization of <code>L * U = P * S * Q</code> has sparser terms <code>L</code>
+and <code>U</code> than the equivalent factorization <code>L * U = S</code>.
+
+   <p>Several functions are available to reorder depending on the type of the
+matrix to be factorized.  If the matrix is symmetric positive-definite,
+then <dfn>symamd</dfn> or <dfn>csymamd</dfn> should be used.  Otherwise
+<dfn>amd</dfn>, <dfn>colamd</dfn> or <dfn>ccolamd</dfn> should be used.  For completeness
+the reordering functions <dfn>colperm</dfn> and <dfn>randperm</dfn> are
+also available.
+
+   <p>See <a href="fig_003asimplematrix.html#fig_003asimplematrix">fig:simplematrix</a>, for an example of the structure of a simple
+positive definite matrix.
+
+   <div class="float">
+<a name="fig_003asimplematrix"></a><div align="center"><img src="spmatrix.png" alt="spmatrix.png"></div>
+   <p><strong class="float-caption">Figure 21.3: Structure of simple sparse matrix.</strong></p></div>
+
+   <p>The standard Cholesky factorization of this matrix can be
+obtained by the same command that would be used for a full
+matrix.  This can be visualized with the command
+<code>r = chol(A); spy(r);</code>. 
+See <a href="fig_003asimplechol.html#fig_003asimplechol">fig:simplechol</a>. 
+The original matrix had
+598
+non-zero terms, while this Cholesky factorization has
+10200,
+with only half of the symmetric matrix being stored.  This
+is a significant level of fill in, and although not an issue
+for such a small test case, can represents a large overhead
+in working with other sparse matrices.
+
+   <p>The appropriate sparsity preserving permutation of the original
+matrix is given by <dfn>symamd</dfn> and the factorization using this
+reordering can be visualized using the command <code>q = symamd(A);
+r = chol(A(q,q)); spy(r)</code>.  This gives
+399
+non-zero terms which is a significant improvement.
+
+   <p>The Cholesky factorization itself can be used to determine the
+appropriate sparsity preserving reordering of the matrix during the
+factorization, In that case this might be obtained with three return
+arguments as r<code>[r, p, q] = chol(A); spy(r)</code>.
+
+   <div class="float">
+<a name="fig_003asimplechol"></a><div align="center"><img src="spchol.png" alt="spchol.png"></div>
+   <p><strong class="float-caption">Figure 21.4: Structure of the un-permuted Cholesky factorization of the above matrix.</strong></p></div>
+
+   <div class="float">
+<a name="fig_003asimplecholperm"></a><div align="center"><img src="spcholperm.png" alt="spcholperm.png"></div>
+   <p><strong class="float-caption">Figure 21.5: Structure of the permuted Cholesky factorization of the above matrix.</strong></p></div>
+
+   <p>In the case of an asymmetric matrix, the appropriate sparsity
+preserving permutation is <dfn>colamd</dfn> and the factorization using
+this reordering can be visualized using the command <code>q =
+colamd(A); [l, u, p] = lu(A(:,q)); spy(l+u)</code>.
+
+   <p>Finally, Octave implicitly reorders the matrix when using the div (/)
+and ldiv (\) operators, and so no the user does not need to explicitly
+reorder the matrix to maximize performance.
+
+<!-- ./DLD-FUNCTIONS/amd.cc -->
+   <p><a name="doc_002damd"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>amd</b> (<var>s</var>)<var><a name="index-amd-1686"></a></var><br>
+— Loadable Function: <var>p</var> = <b>amd</b> (<var>s, opts</var>)<var><a name="index-amd-1687"></a></var><br>
+<blockquote>
+        <p>Returns the approximate minimum degree permutation of a matrix.  This
+permutation such that the Cholesky factorization of <var>s</var><code> (</code><var>p</var><code>,
+</code><var>p</var><code>)</code> tends to be sparser than the Cholesky factorization of <var>s</var>
+itself.  <code>amd</code> is typically faster than <code>symamd</code> but serves a
+similar purpose.
+
+        <p>The optional parameter <var>opts</var> is a structure that controls the
+behavior of <code>amd</code>.  The fields of these structure are
+
+          <dl>
+<dt>opts.dense<dd>Determines what <code>amd</code> considers to be a dense row or column of the
+input matrix.  Rows or columns with more than <code>max(16, (dense *
+sqrt (</code><var>n</var><code>)</code> entries, where <var>n</var> is the order of the matrix <var>s</var>,
+are ignored by <code>amd</code> during the calculation of the permutation
+The value of dense must be a positive scalar and its default value is 10.0
+
+          <br><dt>opts.aggressive<dd>If this value is a non zero scalar, then <code>amd</code> performs aggressive
+absorption.  The default is not to perform aggressive absorption. 
+</dl>
+
+        <p>The author of the code itself is Timothy A. Davis (davis at cise.ufl.edu),
+University of Florida (see <a href="http://www.cise.ufl.edu/research/sparse/amd">http://www.cise.ufl.edu/research/sparse/amd</a>). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsymamd.html#doc_002dsymamd">symamd</a>, <a href="doc_002dcolamd.html#doc_002dcolamd">colamd</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/ccolamd.cc -->
+   <p><a name="doc_002dccolamd"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>ccolamd</b> (<var>s</var>)<var><a name="index-ccolamd-1688"></a></var><br>
+— Loadable Function: <var>p</var> = <b>ccolamd</b> (<var>s, knobs</var>)<var><a name="index-ccolamd-1689"></a></var><br>
+— Loadable Function: <var>p</var> = <b>ccolamd</b> (<var>s, knobs, cmember</var>)<var><a name="index-ccolamd-1690"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>stats</var>] = <b>ccolamd</b> (<var><small class="dots">...</small></var>)<var><a name="index-ccolamd-1691"></a></var><br>
+<blockquote>
+        <p>Constrained column approximate minimum degree permutation.  <var>p</var><code> =
+ccolamd (</code><var>s</var><code>)</code> returns the column approximate minimum degree permutation
+vector for the sparse matrix <var>s</var>.  For a non-symmetric matrix <var>s</var>,
+<var>s</var><code> (:, </code><var>p</var><code>)</code> tends to have sparser LU factors than <var>s</var>. 
+<code>chol (</code><var>s</var><code> (:, </code><var>p</var><code>)' * </code><var>s</var><code> (:, </code><var>p</var><code>))</code> also tends to be
+sparser than <code>chol (</code><var>s</var><code>' * </code><var>s</var><code>)</code>.  <var>p</var><code> = ccolamd
+(</code><var>s</var><code>, 1)</code> optimizes the ordering for <code>lu (</code><var>s</var><code> (:, </code><var>p</var><code>))</code>. 
+The ordering is followed by a column elimination tree post-ordering.
+
+        <p><var>knobs</var> is an optional one- to five-element input vector, with a default
+value of <code>[0 10 10 1 0]</code> if not present or empty.  Entries not present
+are set to their defaults.
+
+          <dl>
+<dt><var>knobs</var><code>(1)</code><dd>if nonzero, the ordering is optimized for <code>lu (S (:, p))</code>.  It will be a
+poor ordering for <code>chol (</code><var>s</var><code> (:, </code><var>p</var><code>)' * </code><var>s</var><code> (:,
+</code><var>p</var><code>))</code>.  This is the most important knob for ccolamd.
+
+          <br><dt><var>knob</var><code>(2)</code><dd>if <var>s</var> is m-by-n, rows with more than <code>max (16, </code><var>knobs</var><code> (2) *
+sqrt (n))</code> entries are ignored.
+
+          <br><dt><var>knob</var><code>(3)</code><dd>columns with more than <code>max (16, </code><var>knobs</var><code> (3) * sqrt (min (</code><var>m</var><code>,
+</code><var>n</var><code>)))</code> entries are ignored and ordered last in the output permutation
+(subject to the cmember constraints).
+
+          <br><dt><var>knob</var><code>(4)</code><dd>if nonzero, aggressive absorption is performed.
+
+          <br><dt><var>knob</var><code>(5)</code><dd>if nonzero, statistics and knobs are printed.
+
+        </dl>
+
+        <p><var>cmember</var> is an optional vector of length n.  It defines the constraints
+on the column ordering.  If <var>cmember</var><code> (j) = </code><var>c</var>, then column
+<var>j</var> is in constraint set <var>c</var> (<var>c</var> must be in the range 1 to
+<var>n</var>).  In the output permutation <var>p</var>, all columns in set 1 appear
+first, followed by all columns in set 2, and so on.  <var>cmember</var><code> =
+ones(1,n)</code> if not present or empty.  <code>ccolamd (</code><var>s</var><code>, [], 1 :
+</code><var>n</var><code>)</code> returns <code>1 : </code><var>n</var>
+
+        <p><var>p</var><code> = ccolamd (</code><var>s</var><code>)</code> is about the same as <var>p</var><code> =
+colamd (</code><var>s</var><code>)</code>.  <var>knobs</var> and its default values differ.  <code>colamd</code>
+always does aggressive absorption, and it finds an ordering suitable for
+both <code>lu (</code><var>s</var><code> (:, </code><var>p</var><code>))</code> and <code>chol (</code><var>S</var><code> (:, </code><var>p</var><code>)'
+* </code><var>s</var><code> (:, </code><var>p</var><code>))</code>; it cannot optimize its ordering for
+<code>lu (</code><var>s</var><code> (:, </code><var>p</var><code>))</code> to the extent that
+<code>ccolamd (</code><var>s</var><code>, 1)</code> can.
+
+        <p><var>stats</var> is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix <var>s</var>.  Ordering
+statistics are in <var>stats</var><code> (1 : 3)</code>.  <var>stats</var><code> (1)</code> and
+<var>stats</var><code> (2)</code> are the number of dense or empty rows and columns
+ignored by CCOLAMD and <var>stats</var><code> (3)</code> is the number of garbage
+collections performed on the internal data structure used by CCOLAMD
+(roughly of size <code>2.2 * nnz (</code><var>s</var><code>) + 4 * </code><var>m</var><code> + 7 * </code><var>n</var>
+integers).
+
+        <p><var>stats</var><code> (4 : 7)</code> provide information if CCOLAMD was able to
+continue.  The matrix is OK if <var>stats</var><code> (4)</code> is zero, or 1 if
+invalid.  <var>stats</var><code> (5)</code> is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists. 
+<var>stats</var><code> (6)</code> is the last seen duplicate or out-of-order row
+index in the column index given by <var>stats</var><code> (5)</code>, or zero if no
+such row index exists.  <var>stats</var><code> (7)</code> is the number of duplicate
+or out-of-order row indices.  <var>stats</var><code> (8 : 20)</code> is always zero in
+the current version of CCOLAMD (reserved for future use).
+
+        <p>The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),
+and a grant from Sandia National Lab.  See
+<a href="http://www.cise.ufl.edu/research/sparse">http://www.cise.ufl.edu/research/sparse</a> for ccolamd, csymamd, amd,
+colamd, symamd, and other related orderings. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolamd.html#doc_002dcolamd">colamd</a>, <a href="doc_002dcsymamd.html#doc_002dcsymamd">csymamd</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/colamd.cc -->
+   <p><a name="doc_002dcolamd"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>colamd</b> (<var>s</var>)<var><a name="index-colamd-1692"></a></var><br>
+— Loadable Function: <var>p</var> = <b>colamd</b> (<var>s, knobs</var>)<var><a name="index-colamd-1693"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>stats</var>] = <b>colamd</b> (<var>s</var>)<var><a name="index-colamd-1694"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>stats</var>] = <b>colamd</b> (<var>s, knobs</var>)<var><a name="index-colamd-1695"></a></var><br>
+<blockquote>
+        <p>Column approximate minimum degree permutation.  <var>p</var><code> = colamd
+(</code><var>s</var><code>)</code> returns the column approximate minimum degree permutation
+vector for the sparse matrix <var>s</var>.  For a non-symmetric matrix <var>s</var>,
+<var>s</var><code> (:,</code><var>p</var><code>)</code> tends to have sparser LU factors than <var>s</var>. 
+The Cholesky factorization of <var>s</var><code> (:,</code><var>p</var><code>)' * </code><var>s</var><code>
+(:,</code><var>p</var><code>)</code> also tends to be sparser than that of <var>s</var><code>' *
+</code><var>s</var>.
+
+        <p><var>knobs</var> is an optional one- to three-element input vector.  If <var>s</var> is
+m-by-n, then rows with more than <code>max(16,</code><var>knobs</var><code>(1)*sqrt(n))</code> entries
+are ignored.  Columns with more than <code>max(16,knobs(2)*sqrt(min(m,n)))</code>
+entries are removed prior to ordering, and ordered last in the output
+permutation <var>p</var>.  Only completely dense rows or columns are removed
+if <var>knobs</var><code> (1)</code> and <var>knobs</var><code> (2)</code> are < 0, respectively. 
+If <var>knobs</var><code> (3)</code> is nonzero, <var>stats</var> and <var>knobs</var> are
+printed.  The default is <var>knobs</var><code> = [10 10 0]</code>.  Note that
+<var>knobs</var> differs from earlier versions of colamd
+
+        <p><var>stats</var> is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix <var>s</var>.  Ordering
+statistics are in <var>stats</var><code> (1:3)</code>.  <var>stats</var><code> (1)</code> and
+<var>stats</var><code> (2)</code> are the number of dense or empty rows and columns
+ignored by COLAMD and <var>stats</var><code> (3)</code> is the number of garbage
+collections performed on the internal data structure used by COLAMD
+(roughly of size <code>2.2 * nnz(</code><var>s</var><code>) + 4 * </code><var>m</var><code> + 7 * </code><var>n</var>
+integers).
+
+        <p>Octave built-in functions are intended to generate valid sparse matrices,
+with no duplicate entries, with ascending row indices of the nonzeros
+in each column, with a non-negative number of entries in each column (!) 
+and so on.  If a matrix is invalid, then COLAMD may or may not be able
+to continue.  If there are duplicate entries (a row index appears two or
+more times in the same column) or if the row indices in a column are out
+of order, then COLAMD can correct these errors by ignoring the duplicate
+entries and sorting each column of its internal copy of the matrix
+<var>s</var> (the input matrix <var>s</var> is not repaired, however).  If a matrix
+is invalid in other ways then COLAMD cannot continue, an error message is
+printed, and no output arguments (<var>p</var> or <var>stats</var>) are returned. 
+COLAMD is thus a simple way to check a sparse matrix to see if it's
+valid.
+
+        <p><var>stats</var><code> (4:7)</code> provide information if COLAMD was able to
+continue.  The matrix is OK if <var>stats</var><code> (4)</code> is zero, or 1 if
+invalid.  <var>stats</var><code> (5)</code> is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists. 
+<var>stats</var><code> (6)</code> is the last seen duplicate or out-of-order row
+index in the column index given by <var>stats</var><code> (5)</code>, or zero if no
+such row index exists.  <var>stats</var><code> (7)</code> is the number of duplicate
+or out-of-order row indices.  <var>stats</var><code> (8:20)</code> is always zero in
+the current version of COLAMD (reserved for future use).
+
+        <p>The ordering is followed by a column elimination tree post-ordering.
+
+        <p>The authors of the code itself are Stefan I. Larimore and Timothy A. 
+Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+Ng, Oak Ridge National Laboratory.  (see
+<a href="http://www.cise.ufl.edu/research/sparse/colamd">http://www.cise.ufl.edu/research/sparse/colamd</a>)
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolperm.html#doc_002dcolperm">colperm</a>, <a href="doc_002dsymamd.html#doc_002dsymamd">symamd</a>. 
+</p></blockquote></div>
+
+<!-- ./sparse/colperm.m -->
+   <p><a name="doc_002dcolperm"></a>
+
+<div class="defun">
+— Function File: <var>p</var> = <b>colperm</b> (<var>s</var>)<var><a name="index-colperm-1696"></a></var><br>
+<blockquote><p>Returns the column permutations such that the columns of
+<var>s</var><code> (:, </code><var>p</var><code>)</code> are ordered in terms of increase number
+of non-zero elements.  If <var>s</var> is symmetric, then <var>p</var> is chosen
+such that <var>s</var><code> (</code><var>p</var><code>, </code><var>p</var><code>)</code> orders the rows and
+columns with increasing number of non zeros elements. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/ccolamd.cc -->
+   <p><a name="doc_002dcsymamd"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>csymamd</b> (<var>s</var>)<var><a name="index-csymamd-1697"></a></var><br>
+— Loadable Function: <var>p</var> = <b>csymamd</b> (<var>s, knobs</var>)<var><a name="index-csymamd-1698"></a></var><br>
+— Loadable Function: <var>p</var> = <b>csymamd</b> (<var>s, knobs, cmember</var>)<var><a name="index-csymamd-1699"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>stats</var>] = <b>csymamd</b> (<var><small class="dots">...</small></var>)<var><a name="index-csymamd-1700"></a></var><br>
+<blockquote>
+        <p>For a symmetric positive definite matrix <var>s</var>, returns the permutation
+vector <var>p</var> such that <var>s</var><code>(</code><var>p</var><code>,</code><var>p</var><code>)</code> tends to have a
+sparser Cholesky factor than <var>s</var>.  Sometimes <code>csymamd</code> works well
+for symmetric indefinite matrices too.  The matrix <var>s</var> is assumed to
+be symmetric; only the strictly lower triangular part is referenced. 
+<var>s</var> must be square.  The ordering is followed by an elimination tree
+post-ordering.
+
+        <p><var>knobs</var> is an optional one- to three-element input vector, with a
+default value of <code>[10 1 0]</code> if present or empty.  Entries not
+present are set to their defaults.
+
+          <dl>
+<dt><var>knobs</var><code>(1)</code><dd>If <var>s</var> is n-by-n, then rows and columns with more than
+<code>max(16,</code><var>knobs</var><code>(1)*sqrt(n))</code> entries are ignored, and ordered
+last in the output permutation (subject to the cmember constraints).
+
+          <br><dt><var>knobs</var><code>(2)</code><dd>If nonzero, aggressive absorption is performed.
+
+          <br><dt><var>knobs</var><code>(3)</code><dd>If nonzero, statistics and knobs are printed.
+
+        </dl>
+
+        <p><var>cmember</var> is an optional vector of length n. It defines the constraints
+on the ordering.  If <var>cmember</var><code>(j) = </code><var>s</var>, then row/column j is
+in constraint set <var>c</var> (<var>c</var> must be in the range 1 to n).  In the
+output permutation <var>p</var>, rows/columns in set 1 appear first, followed
+by all rows/columns in set 2, and so on.  <var>cmember</var><code> = ones(1,n)</code>
+if not present or empty.  <code>csymamd(</code><var>s</var><code>,[],1:n)</code> returns <code>1:n</code>.
+
+        <p><var>p</var><code> = csymamd(</code><var>s</var><code>)</code> is about the same as <var>p</var><code> =
+symamd(</code><var>s</var><code>)</code>.  <var>knobs</var> and its default values differ.
+
+        <p><var>stats</var><code> (4:7)</code> provide information if CCOLAMD was able to
+continue.  The matrix is OK if <var>stats</var><code> (4)</code> is zero, or 1 if
+invalid.  <var>stats</var><code> (5)</code> is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists. 
+<var>stats</var><code> (6)</code> is the last seen duplicate or out-of-order row
+index in the column index given by <var>stats</var><code> (5)</code>, or zero if no
+such row index exists.  <var>stats</var><code> (7)</code> is the number of duplicate
+or out-of-order row indices.  <var>stats</var><code> (8:20)</code> is always zero in
+the current version of CCOLAMD (reserved for future use).
+
+        <p>The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),
+and a grant from Sandia National Lab.  See
+<a href="http://www.cise.ufl.edu/research/sparse">http://www.cise.ufl.edu/research/sparse</a> for ccolamd, csymamd, amd,
+colamd, symamd, and other related orderings. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsymamd.html#doc_002dsymamd">symamd</a>, <a href="doc_002dccolamd.html#doc_002dccolamd">ccolamd</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dmperm.cc -->
+   <p><a name="doc_002ddmperm"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>dmperm</b> (<var>s</var>)<var><a name="index-dmperm-1701"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>q</var>, <var>r</var>, <var>s</var>] = <b>dmperm</b> (<var>s</var>)<var><a name="index-dmperm-1702"></a></var><br>
+<blockquote>
+        <p><a name="index-Dulmage_002dMendelsohn-decomposition-1703"></a>Perform a Dulmage-Mendelsohn permutation on the sparse matrix <var>s</var>. 
+With a single output argument <dfn>dmperm</dfn> performs the row permutations
+<var>p</var> such that <var>s</var><code> (</code><var>p</var><code>,:)</code> has no zero elements on the
+diagonal.
+
+        <p>Called with two or more output arguments, returns the row and column
+permutations, such that <var>s</var><code> (</code><var>p</var><code>, </code><var>q</var><code>)</code> is in block
+triangular form.  The values of <var>r</var> and <var>s</var> define the boundaries
+of the blocks.  If <var>s</var> is square then <var>r</var><code> == </code><var>s</var>.
+
+        <p>The method used is described in: A. Pothen & C.-J. Fan. Computing the block
+triangular form of a sparse matrix. ACM Trans. Math. Software,
+16(4):303-324, 1990. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolamd.html#doc_002dcolamd">colamd</a>, <a href="doc_002dccolamd.html#doc_002dccolamd">ccolamd</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/colamd.cc -->
+   <p><a name="doc_002dsymamd"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>symamd</b> (<var>s</var>)<var><a name="index-symamd-1704"></a></var><br>
+— Loadable Function: <var>p</var> = <b>symamd</b> (<var>s, knobs</var>)<var><a name="index-symamd-1705"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>stats</var>] = <b>symamd</b> (<var>s</var>)<var><a name="index-symamd-1706"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>stats</var>] = <b>symamd</b> (<var>s, knobs</var>)<var><a name="index-symamd-1707"></a></var><br>
+<blockquote>
+        <p>For a symmetric positive definite matrix <var>s</var>, returns the permutation
+vector p such that <var>s</var><code> (</code><var>p</var><code>, </code><var>p</var><code>)</code> tends to have a
+sparser Cholesky factor than <var>s</var>.  Sometimes SYMAMD works well for
+symmetric indefinite matrices too.  The matrix <var>s</var> is assumed to be
+symmetric; only the strictly lower triangular part is referenced.  <var>s</var>
+must be square.
+
+        <p><var>knobs</var> is an optional one- to two-element input vector.  If <var>s</var> is
+n-by-n, then rows and columns with more than
+<code>max(16,</code><var>knobs</var><code>(1)*sqrt(n))</code> entries are removed prior to ordering,
+and ordered last in the output permutation <var>p</var>.  No rows/columns are
+removed if <var>knobs</var><code>(1) < 0</code>.  If <var>knobs</var><code> (2)</code> is nonzero,
+<code>stats</code> and <var>knobs</var> are printed.  The default is <var>knobs</var><code>
+= [10 0]</code>.  Note that <var>knobs</var> differs from earlier versions of symamd.
+
+        <p><var>stats</var> is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix <var>s</var>.  Ordering
+statistics are in <var>stats</var><code> (1:3)</code>.  <var>stats</var><code> (1) =
+</code><var>stats</var><code> (2)</code> is the number of dense or empty rows and columns
+ignored by SYMAMD and <var>stats</var><code> (3)</code> is the number of garbage
+collections performed on the internal data structure used by SYMAMD
+(roughly of size <code>8.4 * nnz (tril (</code><var>s</var><code>, -1)) + 9 * </code><var>n</var>
+integers).
+
+        <p>Octave built-in functions are intended to generate valid sparse matrices,
+with no duplicate entries, with ascending row indices of the nonzeros
+in each column, with a non-negative number of entries in each column (!) 
+and so on.  If a matrix is invalid, then SYMAMD may or may not be able
+to continue.  If there are duplicate entries (a row index appears two or
+more times in the same column) or if the row indices in a column are out
+of order, then SYMAMD can correct these errors by ignoring the duplicate
+entries and sorting each column of its internal copy of the matrix S (the
+input matrix S is not repaired, however).  If a matrix is invalid in
+other ways then SYMAMD cannot continue, an error message is printed, and
+no output arguments (<var>p</var> or <var>stats</var>) are returned.  SYMAMD is
+thus a simple way to check a sparse matrix to see if it's valid.
+
+        <p><var>stats</var><code> (4:7)</code> provide information if SYMAMD was able to
+continue.  The matrix is OK if <var>stats</var><code> (4)</code> is zero, or 1
+if invalid.  <var>stats</var><code> (5)</code> is the rightmost column index that
+is unsorted or contains duplicate entries, or zero if no such column
+exists.  <var>stats</var><code> (6)</code> is the last seen duplicate or out-of-order
+row index in the column index given by <var>stats</var><code> (5)</code>, or zero
+if no such row index exists.  <var>stats</var><code> (7)</code> is the number of
+duplicate or out-of-order row indices.  <var>stats</var><code> (8:20)</code> is
+always zero in the current version of SYMAMD (reserved for future use).
+
+        <p>The ordering is followed by a column elimination tree post-ordering.
+
+        <p>The authors of the code itself are Stefan I. Larimore and Timothy A. 
+Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+Ng, Oak Ridge National Laboratory.  (see
+<a href="http://www.cise.ufl.edu/research/sparse/colamd">http://www.cise.ufl.edu/research/sparse/colamd</a>)
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolperm.html#doc_002dcolperm">colperm</a>, <a href="doc_002dcolamd.html#doc_002dcolamd">colamd</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/symrcm.cc -->
+   <p><a name="doc_002dsymrcm"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>symrcm</b> (<var>S</var>)<var><a name="index-symrcm-1708"></a></var><br>
+<blockquote><p>Symmetric reverse Cuthill-McKee permutation of <var>S</var>. 
+Return a permutation vector <var>p</var> such that
+<var>S</var><code> (</code><var>p</var><code>, </code><var>p</var><code>)</code> tends to have its diagonal elements
+closer to the diagonal than <var>S</var>.  This is a good preordering for LU
+or Cholesky factorization of matrices that come from 'long, skinny'
+problems.  It works for both symmetric and asymmetric <var>S</var>.
+
+        <p>The algorithm represents a heuristic approach to the NP-complete
+bandwidth minimization problem.  The implementation is based in the
+descriptions found in
+
+        <p>E. Cuthill, J. McKee: Reducing the Bandwidth of Sparse Symmetric
+Matrices. Proceedings of the 24th ACM National Conference, 157–172
+1969, Brandon Press, New Jersey.
+
+        <p>Alan George, Joseph W. H. Liu: Computer Solution of Large Sparse
+Positive Definite Systems, Prentice Hall Series in Computational
+Mathematics, ISBN 0-13-165274-5, 1981.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolperm.html#doc_002dcolperm">colperm</a>, <a href="doc_002dcolamd.html#doc_002dcolamd">colamd</a>, <a href="doc_002dsymamd.html#doc_002dsymamd">symamd</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Mathematical-Constants.html b/doc/interpreter/HTML/Mathematical-Constants.html
new file mode 100644
index 0000000..3040520
--- /dev/null
+++ b/doc/interpreter/HTML/Mathematical-Constants.html
@@ -0,0 +1,277 @@
+<html lang="en">
+<head>
+<title>Mathematical Constants - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Coordinate-Transformations.html#Coordinate-Transformations" title="Coordinate Transformations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Mathematical-Constants"></a>
+Previous: <a rel="previous" accesskey="p" href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.8 Mathematical Constants</h3>
+
+<!-- data.cc -->
+<p><a name="doc_002de"></a>
+
+<div class="defun">
+— Built-in Function:  <b>e</b><var><a name="index-e-1509"></a></var><br>
+— Built-in Function:  <b>e</b> (<var>n</var>)<var><a name="index-e-1510"></a></var><br>
+— Built-in Function:  <b>e</b> (<var>n, m</var>)<var><a name="index-e-1511"></a></var><br>
+— Built-in Function:  <b>e</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-e-1512"></a></var><br>
+— Built-in Function:  <b>e</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-e-1513"></a></var><br>
+<blockquote><p>Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the base of natural logarithms.  The constant
+‘<samp><span class="samp">e</span></samp>’ satisfies the equation <code>log</code> (e) = 1.
+
+        <p>When called with no arguments, return a scalar with the value e.  When
+called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dpi"></a>
+
+<div class="defun">
+— Built-in Function:  <b>pi</b><var><a name="index-pi-1514"></a></var><br>
+— Built-in Function:  <b>pi</b> (<var>n</var>)<var><a name="index-pi-1515"></a></var><br>
+— Built-in Function:  <b>pi</b> (<var>n, m</var>)<var><a name="index-pi-1516"></a></var><br>
+— Built-in Function:  <b>pi</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-pi-1517"></a></var><br>
+— Built-in Function:  <b>pi</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-pi-1518"></a></var><br>
+<blockquote><p>Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the ratio of the circumference of a circle to its
+diameter. 
+Internally, <code>pi</code> is computed as ‘<samp><span class="samp">4.0 * atan (1.0)</span></samp>’.
+
+        <p>When called with no arguments, return a scalar with the value of
+pi. 
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dI"></a>
+
+<div class="defun">
+— Built-in Function:  <b>I</b><var><a name="index-I-1519"></a></var><br>
+— Built-in Function:  <b>I</b> (<var>n</var>)<var><a name="index-I-1520"></a></var><br>
+— Built-in Function:  <b>I</b> (<var>n, m</var>)<var><a name="index-I-1521"></a></var><br>
+— Built-in Function:  <b>I</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-I-1522"></a></var><br>
+— Built-in Function:  <b>I</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-I-1523"></a></var><br>
+<blockquote><p>Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the pure imaginary unit, defined as
+<code>sqrt (-1)</code>. 
+ I, and its equivalents i, J, and j, are functions so any of the names may
+be reused for other purposes (such as i for a counter variable).
+
+        <p>When called with no arguments, return a scalar with the value i.  When
+called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dInf"></a>
+
+<div class="defun">
+— Built-in Function:  <b>Inf</b><var><a name="index-Inf-1524"></a></var><br>
+— Built-in Function:  <b>Inf</b> (<var>n</var>)<var><a name="index-Inf-1525"></a></var><br>
+— Built-in Function:  <b>Inf</b> (<var>n, m</var>)<var><a name="index-Inf-1526"></a></var><br>
+— Built-in Function:  <b>Inf</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-Inf-1527"></a></var><br>
+— Built-in Function:  <b>Inf</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-Inf-1528"></a></var><br>
+<blockquote><p>Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the IEEE representation for positive infinity.
+
+        <p>Infinity is produced when results are too large to be represented using the
+the IEEE floating point format for numbers.  Two common examples which
+produce infinity are division by zero and overflow.
+     <pre class="example">          [1/0 e^800]
+          
+          Inf   Inf
+</pre>
+        <p>When called with no arguments, return a scalar with the value ‘<samp><span class="samp">Inf</span></samp>’. 
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disinf.html#doc_002disinf">isinf</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dNaN"></a>
+
+<div class="defun">
+— Built-in Function:  <b>NaN</b><var><a name="index-NaN-1529"></a></var><br>
+— Built-in Function:  <b>NaN</b> (<var>n</var>)<var><a name="index-NaN-1530"></a></var><br>
+— Built-in Function:  <b>NaN</b> (<var>n, m</var>)<var><a name="index-NaN-1531"></a></var><br>
+— Built-in Function:  <b>NaN</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-NaN-1532"></a></var><br>
+— Built-in Function:  <b>NaN</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-NaN-1533"></a></var><br>
+<blockquote><p>Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the IEEE symbol NaN (Not a Number). 
+NaN is the result of operations which do not produce a well defined numerical
+result.  Common operations which produce a NaN are arithmetic with infinity
+(Inf - Inf), zero divided by zero (0/0),
+and any operation involving another NaN value (5 + NaN).
+
+        <p>Note that NaN always compares not equal to NaN (NaN != NaN).  This behavior
+is specified by the IEEE standard for floating point arithmetic.  To
+find NaN values, use the <code>isnan</code> function.
+
+        <p>When called with no arguments, return a scalar with the value ‘<samp><span class="samp">NaN</span></samp>’. 
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disnan.html#doc_002disnan">isnan</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002deps"></a>
+
+<div class="defun">
+— Built-in Function:  <b>eps</b><var><a name="index-eps-1534"></a></var><br>
+— Built-in Function:  <b>eps</b> (<var>x</var>)<var><a name="index-eps-1535"></a></var><br>
+— Built-in Function:  <b>eps</b> (<var>n, m</var>)<var><a name="index-eps-1536"></a></var><br>
+— Built-in Function:  <b>eps</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-eps-1537"></a></var><br>
+— Built-in Function:  <b>eps</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-eps-1538"></a></var><br>
+<blockquote><p>Return a scalar, matrix or N-dimensional array whose elements are all eps,
+the machine precision.  More precisely, <code>eps</code> is the relative spacing
+between any two adjacent numbers in the machine's floating point system. 
+This number is obviously system dependent.  On machines that support IEEE
+floating point arithmetic, <code>eps</code> is approximately
+2.2204e-16 for double precision and 1.1921e-07
+for single precision.
+
+        <p>When called with no arguments, return a scalar with the value
+<code>eps(1.0)</code>. 
+Given a single argument <var>x</var>, return the distance between <var>x</var> and
+the next largest value. 
+When called with more than one argument the first two arguments are taken as
+the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002drealmax"></a>
+
+<div class="defun">
+— Built-in Function:  <b>realmax</b><var><a name="index-realmax-1539"></a></var><br>
+— Built-in Function:  <b>realmax</b> (<var>n</var>)<var><a name="index-realmax-1540"></a></var><br>
+— Built-in Function:  <b>realmax</b> (<var>n, m</var>)<var><a name="index-realmax-1541"></a></var><br>
+— Built-in Function:  <b>realmax</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-realmax-1542"></a></var><br>
+— Built-in Function:  <b>realmax</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-realmax-1543"></a></var><br>
+<blockquote><p>Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the largest floating point number that is representable.  The actual
+value is system dependent.  On machines that support IEEE
+floating point arithmetic, <code>realmax</code> is approximately
+1.7977e+308 for double precision and 3.4028e+38
+for single precision.
+
+        <p>When called with no arguments, return a scalar with the value
+<code>realmax("double")</code>. 
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drealmin.html#doc_002drealmin">realmin</a>, <a href="doc_002dintmax.html#doc_002dintmax">intmax</a>, <a href="doc_002dbitmax.html#doc_002dbitmax">bitmax</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002drealmin"></a>
+
+<div class="defun">
+— Built-in Function:  <b>realmin</b><var><a name="index-realmin-1544"></a></var><br>
+— Built-in Function:  <b>realmin</b> (<var>n</var>)<var><a name="index-realmin-1545"></a></var><br>
+— Built-in Function:  <b>realmin</b> (<var>n, m</var>)<var><a name="index-realmin-1546"></a></var><br>
+— Built-in Function:  <b>realmin</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-realmin-1547"></a></var><br>
+— Built-in Function:  <b>realmin</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-realmin-1548"></a></var><br>
+<blockquote><p>Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the smallest normalized floating point number that is representable. 
+The actual value is system dependent.  On machines that support
+IEEE floating point arithmetic, <code>realmin</code> is approximately
+2.2251e-308 for double precision and 1.1755e-38
+for single precision.
+
+        <p>When called with no arguments, return a scalar with the value
+<code>realmin("double")</code>. 
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drealmax.html#doc_002drealmax">realmax</a>, <a href="doc_002dintmin.html#doc_002dintmin">intmin</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Matrices-and-Arrays-in-Oct_002dFiles.html b/doc/interpreter/HTML/Matrices-and-Arrays-in-Oct_002dFiles.html
new file mode 100644
index 0000000..ff958ef
--- /dev/null
+++ b/doc/interpreter/HTML/Matrices-and-Arrays-in-Oct_002dFiles.html
@@ -0,0 +1,209 @@
+<html lang="en">
+<head>
+<title>Matrices and Arrays in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Getting-Started-with-Oct_002dFiles.html#Getting-Started-with-Oct_002dFiles" title="Getting Started with Oct-Files">
+<link rel="next" href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles" title="Character Strings in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrices-and-Arrays-in-Oct-Files"></a>
+<a name="Matrices-and-Arrays-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles">Character Strings in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Getting-Started-with-Oct_002dFiles.html#Getting-Started-with-Oct_002dFiles">Getting Started with Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.2 Matrices and Arrays in Oct-Files</h4>
+
+<p>Octave supports a number of different array and matrix classes, the
+majority of which are based on the Array class.  The exception is the
+sparse matrix types discussed separately below.  There are three basic
+matrix types
+
+     <dl>
+<dt><code>Matrix</code><dd>A double precision matrix class defined in dMatrix.h,
+<br><dt><code>ComplexMatrix</code><dd>A complex matrix class defined in CMatrix.h, and
+<br><dt><code>BoolMatrix</code><dd>A boolean matrix class defined in boolMatrix.h. 
+</dl>
+
+   <p>These are the basic two-dimensional matrix types of octave.  In
+additional there are a number of multi-dimensional array types, these
+being
+
+     <dl>
+<dt><code>NDArray</code><dd>A double precision array class defined in <samp><span class="file">dNDArray.h</span></samp>
+<br><dt><code>ComplexNDarray</code><dd>A complex array class defined in <samp><span class="file">CNDArray.h</span></samp>
+<br><dt><code>boolNDArray</code><dd>A boolean array class defined in <samp><span class="file">boolNDArray.h</span></samp>
+<br><dt><code>int8NDArray</code><dt><code>int16NDArray</code><dt><code>int32NDArray</code><dt><code>int64NDArray</code><dd>8, 16, 32 and 64-bit signed array classes defined in
+<samp><span class="file">int8NDArray.h</span></samp>, <samp><span class="file">int16NDArray.h</span></samp>, etc. 
+<br><dt><code>uint8NDArray</code><dt><code>uint16NDArray</code><dt><code>uint32NDArray</code><dt><code>uint64NDArray</code><dd>8, 16, 32 and 64-bit unsigned array classes defined in
+<samp><span class="file">uint8NDArray.h</span></samp>, <samp><span class="file">uint16NDArray.h</span></samp>, etc. 
+</dl>
+
+   <p>There are several basic means of constructing matrices of
+multi-dimensional arrays.  Considering the <code>Matrix</code> type as an
+example
+
+     <ul>
+<li>We can create an empty matrix or array with the empty constructor.  For
+example
+
+     <pre class="example">          Matrix a;
+</pre>
+     <p>This can be used on all matrix and array types
+<li>Define the dimensions of the matrix or array with a dim_vector.  For
+example
+
+     <pre class="example">          dim_vector dv (2);
+          dv(0) = 2; dv(1) = 2;
+          Matrix a (dv);
+</pre>
+     <p>This can be used on all matrix and array types
+<li>Define the number of rows and columns in the matrix.  For example
+
+     <pre class="example">          Matrix a (2, 2)
+</pre>
+     <p>However, this constructor can only be used with the matrix types. 
+</ul>
+
+   <p>These types all share a number of basic methods and operators, a
+selection of which include
+
+<div class="defun">
+— Method: T& <b>operator ()</b> (<var>octave_idx_type</var>)<var><a name="index-operator-_0028_0029-2473"></a></var><br>
+— Method: T& <b>elem</b> (<var>octave_idx_type</var>)<var><a name="index-elem-2474"></a></var><br>
+<blockquote><p>The <code>()</code> operator or <code>elem</code> method allow the values of the
+matrix or array to be read or set.  These can take a single argument,
+which is of type <code>octave_idx_type</code>, that is the index into the matrix or
+array.  Additionally, the matrix type allows two argument versions of the
+<code>()</code> operator and elem method, giving the row and column index of the
+value to obtain or set. 
+</p></blockquote></div>
+
+   <p>Note that these functions do significant error checking and so in some
+circumstances the user might prefer to access the data of the array or
+matrix directly through the fortran_vec method discussed below.
+
+<div class="defun">
+— Method: octave_idx_type <b>nelem</b> (<var>void</var>)<var> const<a name="index-nelem-2475"></a></var><br>
+<blockquote><p>The total number of elements in the matrix or array. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method: size_t <b>byte_size</b> (<var>void</var>)<var> const<a name="index-byte_005fsize-2476"></a></var><br>
+<blockquote><p>The number of bytes used to store the matrix or array. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method: dim_vector <b>dims</b> (<var>void</var>)<var> const<a name="index-dims-2477"></a></var><br>
+<blockquote><p>The dimensions of the matrix or array in value of type dim_vector. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method: void <b>resize</b> (<var>const dim_vector&</var>)<var><a name="index-resize-2478"></a></var><br>
+<blockquote><p>A method taking either an argument of type <code>dim_vector</code>, or in the
+case of a matrix two arguments of type <code>octave_idx_type</code> defining
+the number of rows and columns in the matrix. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method: T* <b>fortran_vec</b> (<var>void</var>)<var><a name="index-fortran_005fvec-2479"></a></var><br>
+<blockquote><p>This method returns a pointer to the underlying data of the matrix or a
+array so that it can be manipulated directly, either within Octave or by
+an external library. 
+</p></blockquote></div>
+
+   <p>Operators such an <code>+</code>, <code>-</code>, or <code>*</code> can be used on the
+majority of the above types.  In addition there are a number of methods
+that are of interest only for matrices such as <code>transpose</code>,
+<code>hermitian</code>, <code>solve</code>, etc.
+
+   <p>The typical way to extract a matrix or array from the input arguments of
+<code>DEFUN_DLD</code><!-- /@w --> function is as follows
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     
+     DEFUN_DLD (addtwomatrices, args, , "Add A to B")
+     {
+       int nargin = args.length ();
+       if (nargin != 2)
+         print_usage ();
+       else
+         {
+           NDArray A = args(0).array_value ();
+           NDArray B = args(1).array_value ();
+           if (! error_state)
+             return octave_value (A + B);
+         }
+       return octave_value_list ();
+     }
+</pre>
+</pre>
+   <p>To avoid segmentation faults causing Octave to abort, this function
+explicitly checks that there are sufficient arguments available before
+accessing these arguments.  It then obtains two multi-dimensional arrays
+of type <code>NDArray</code> and adds these together.  Note that the array_value
+method is called without using the <code>is_matrix_type</code> type, and instead the
+error_state is checked before returning <code>A + B</code>.  The reason to
+prefer this is that the arguments might be a type that is not an
+<code>NDArray</code>, but it would make sense to convert it to one.  The
+<code>array_value</code> method allows this conversion to be performed
+transparently if possible, and sets <code>error_state</code> if it is not.
+
+   <p><code>A + B</code>, operating on two <code>NDArray</code>'s returns an
+<code>NDArray</code>, which is cast to an <code>octave_value</code> on the return
+from the function.  An example of the use of this demonstration function
+is
+
+<pre class="example">     addtwomatrices (ones (2, 2), ones (2, 2))
+             2  2
+               2  2
+</pre>
+   <p>A list of the basic <code>Matrix</code> and <code>Array</code> types, the methods to
+extract these from an <code>octave_value</code> and the associated header is
+listed below.
+
+   <p><table summary=""><tr align="left"><td valign="top" width="30%"><code>RowVector</code> </td><td valign="top" width="40%"><code>row_vector_value</code> </td><td valign="top" width="30%"><samp><span class="file">dRowVector.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>ComplexRowVector</code> </td><td valign="top" width="40%"><code>complex_row_vector_value</code> </td><td valign="top" width="30%"><samp><span class="file">CRowVector.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>ColumnVector</code> </td><td valign="top" width="40%"><code>column_vector_value</code> </td><td valign="top" width="30%"><samp><span class="file">dColVector.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>ComplexColumnVector</code> </td><td valign="top" width="40%"><code>complex_column_vector_value</code> </td><td valign="top" width="30%"><samp><span class="file">CColVector.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>Matrix</code> </td><td valign="top" width="40%"><code>matrix_value</code> </td><td valign="top" width="30%"><samp><span class="file">dMatrix.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>ComplexMatrix</code> </td><td valign="top" width="40%"><code>complex_matrix_value</code> </td><td valign="top" width="30%"><samp><span class="file">CMatrix.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>boolMatrix</code> </td><td valign="top" width="40%"><code>bool_matrix_value</code> </td><td valign="top" width="30%"><samp><span class="file">boolMatrix.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>charMatrix</code> </td><td valign="top" width="40%"><code>char_matrix_value</code> </td><td valign="top" width="30%"><samp><span class="file">chMatrix.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>NDArray</code> </td><td valign="top" width="40%"><code>array_value</code> </td><td valign="top" width="30%"><samp><span class="file">dNDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>ComplexNDArray</code> </td><td valign="top" width="40%"><code>complex_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">CNDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>boolNDArray</code> </td><td valign="top" width="40%"><code>bool_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">boolNDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>charNDArray</code> </td><td valign="top" width="40%"><code>char_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">charNDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>int8NDArray</code> </td><td valign="top" width="40%"><code>int8_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">int8NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>int16NDArray</code> </td><td valign="top" width="40%"><code>int16_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">int16NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>int32NDArray</code> </td><td valign="top" width="40%"><code>int32_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">int32NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>int64NDArray</code> </td><td valign="top" width="40%"><code>int64_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">int64NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>uint8NDArray</code> </td><td valign="top" width="40%"><code>uint8_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">uint8NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>uint16NDArray</code> </td><td valign="top" width="40%"><code>uint16_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">uint16NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>uint32NDArray</code> </td><td valign="top" width="40%"><code>uint32_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">uint32NDArray.h</span></samp>
+<br></td></tr><tr align="left"><td valign="top" width="30%"><code>uint64NDArray</code> </td><td valign="top" width="40%"><code>uint64_array_value</code> </td><td valign="top" width="30%"><samp><span class="file">uint64NDArray.h</span></samp>
+   <br></td></tr></table>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Matrices.html b/doc/interpreter/HTML/Matrices.html
new file mode 100644
index 0000000..b00db2a
--- /dev/null
+++ b/doc/interpreter/HTML/Matrices.html
@@ -0,0 +1,248 @@
+<html lang="en">
+<head>
+<title>Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="next" href="Ranges.html#Ranges" title="Ranges">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Ranges.html#Ranges">Ranges</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.1 Matrices</h3>
+
+<p><a name="index-matrices-216"></a>
+<a name="index-g_t_005b-217"></a><a name="index-g_t_005d-218"></a><a name="index-g_t_003b-219"></a><a name="index-g_t_002c-220"></a>
+It is easy to define a matrix of values in Octave.  The size of the
+matrix is determined automatically, so it is not necessary to explicitly
+state the dimensions.  The expression
+
+<pre class="example">     a = [1, 2; 3, 4]
+</pre>
+   <p class="noindent">results in the matrix
+
+<pre class="example">     
+             /      \
+             | 1  2 |
+       a  =  |      |
+             | 3  4 |
+             \      /
+</pre>
+   <p>Elements of a matrix may be arbitrary expressions, provided that the
+dimensions all make sense when combining the various pieces.  For
+example, given the above matrix, the expression
+
+<pre class="example">     [ a, a ]
+</pre>
+   <p class="noindent">produces the matrix
+
+<pre class="example">     ans =
+     
+       1  2  1  2
+       3  4  3  4
+</pre>
+   <p class="noindent">but the expression
+
+<pre class="example">     [ a, 1 ]
+</pre>
+   <p class="noindent">produces the error
+
+<pre class="example">     error: number of rows must match (1 != 2) near line 13, column 6
+</pre>
+   <p class="noindent">(assuming that this expression was entered as the first thing on line
+13, of course).
+
+   <p>Inside the square brackets that delimit a matrix expression, Octave
+looks at the surrounding context to determine whether spaces and newline
+characters should be converted into element and row separators, or
+simply ignored, so an expression like
+
+<pre class="example">     a = [ 1 2
+           3 4 ]
+</pre>
+   <p class="noindent">will work.  However, some possible sources of confusion remain.  For
+example, in the expression
+
+<pre class="example">     [ 1 - 1 ]
+</pre>
+   <p class="noindent">the ‘<samp><span class="samp">-</span></samp>’ is treated as a binary operator and the result is the
+scalar 0, but in the expression
+
+<pre class="example">     [ 1 -1 ]
+</pre>
+   <p class="noindent">the ‘<samp><span class="samp">-</span></samp>’ is treated as a unary operator and the result is the
+vector <code>[ 1, -1 ]</code>.  Similarly, the expression
+
+<pre class="example">     [ sin (pi) ]
+</pre>
+   <p class="noindent">will be parsed as
+
+<pre class="example">     [ sin, (pi) ]
+</pre>
+   <p class="noindent">and will result in an error since the <code>sin</code> function will be
+called with no arguments.  To get around this, you must omit the space
+between <code>sin</code> and the opening parenthesis, or enclose the
+expression in a set of parentheses:
+
+<pre class="example">     [ (sin (pi)) ]
+</pre>
+   <p>Whitespace surrounding the single quote character (‘<samp><span class="samp">'</span></samp>’, used as a
+transpose operator and for delimiting character strings) can also cause
+confusion.  Given <code>a = 1</code>, the expression
+
+<pre class="example">     [ 1 a' ]
+</pre>
+   <p class="noindent">results in the single quote character being treated as a
+transpose operator and the result is the vector <code>[ 1, 1 ]</code>, but the
+expression
+
+<pre class="example">     [ 1 a ' ]
+</pre>
+   <p class="noindent">produces the error message
+
+<pre class="example">     parse error:
+     
+       syntax error
+     
+     >>> [ 1 a ' ]
+                   ^
+</pre>
+   <p class="noindent">because not doing so would cause trouble when parsing the valid expression
+
+<pre class="example">     [ a 'foo' ]
+</pre>
+   <p>For clarity, it is probably best to always use commas and semicolons to
+separate matrix elements and rows.
+
+   <p>When you type a matrix or the name of a variable whose value is a
+matrix, Octave responds by printing the matrix in with neatly aligned
+rows and columns.  If the rows of the matrix are too large to fit on the
+screen, Octave splits the matrix and displays a header before each
+section to indicate which columns are being displayed.  You can use the
+following variables to control the format of the output.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002doutput_005fmax_005ffield_005fwidth"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>output_max_field_width</b> ()<var><a name="index-output_005fmax_005ffield_005fwidth-221"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>output_max_field_width</b> (<var>new_val</var>)<var><a name="index-output_005fmax_005ffield_005fwidth-222"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the maximum width
+of a numeric output field. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dformat.html#doc_002dformat">format</a>, <a href="doc_002doutput_005fprecision.html#doc_002doutput_005fprecision">output_precision</a>. 
+</p></blockquote></div>
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002doutput_005fprecision"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>output_precision</b> ()<var><a name="index-output_005fprecision-223"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>output_precision</b> (<var>new_val</var>)<var><a name="index-output_005fprecision-224"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the minimum number of
+significant figures to display for numeric output. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dformat.html#doc_002dformat">format</a>, <a href="doc_002doutput_005fmax_005ffield_005fwidth.html#doc_002doutput_005fmax_005ffield_005fwidth">output_max_field_width</a>. 
+</p></blockquote></div>
+
+   <p>It is possible to achieve a wide range of output styles by using
+different values of <code>output_precision</code> and
+<code>output_max_field_width</code>.  Reasonable combinations can be set using
+the <code>format</code> function.  See <a href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002dsplit_005flong_005frows"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>split_long_rows</b> ()<var><a name="index-split_005flong_005frows-225"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>split_long_rows</b> (<var>new_val</var>)<var><a name="index-split_005flong_005frows-226"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether rows of a matrix
+may be split when displayed to a terminal window.  If the rows are split,
+Octave will display the matrix in a series of smaller pieces, each of
+which can fit within the limits of your terminal width and each set of
+rows is labeled so that you can easily see which columns are currently
+being displayed.  For example:
+
+     <pre class="example">          octave:13> rand (2,10)
+          ans =
+          
+           Columns 1 through 6:
+          
+            0.75883  0.93290  0.40064  0.43818  0.94958  0.16467
+            0.75697  0.51942  0.40031  0.61784  0.92309  0.40201
+          
+           Columns 7 through 10:
+          
+            0.90174  0.11854  0.72313  0.73326
+            0.44672  0.94303  0.56564  0.82150
+</pre>
+        </blockquote></div>
+
+   <p>Octave automatically switches to scientific notation when values become
+very large or very small.  This guarantees that you will see several
+significant figures for every value in a matrix.  If you would prefer to
+see all values in a matrix printed in a fixed point format, you can set
+the built-in variable <code>fixed_point_format</code> to a nonzero value.  But
+doing so is not recommended, because it can produce output that can
+easily be misinterpreted.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002dfixed_005fpoint_005fformat"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>fixed_point_format</b> ()<var><a name="index-fixed_005fpoint_005fformat-227"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>fixed_point_format</b> (<var>new_val</var>)<var><a name="index-fixed_005fpoint_005fformat-228"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave will
+use a scaled format to print matrix values such that the largest
+element may be written with a single leading digit with the scaling
+factor is printed on the first line of output.  For example,
+
+     <pre class="example">          octave:1> logspace (1, 7, 5)'
+          ans =
+          
+            1.0e+07  *
+          
+            0.00000
+            0.00003
+            0.00100
+            0.03162
+            1.00000
+</pre>
+        <p class="noindent">Notice that first value appears to be zero when it is actually 1.  For
+this reason, you should be careful when setting
+<code>fixed_point_format</code> to a nonzero value. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Empty-Matrices.html#Empty-Matrices">Empty Matrices</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Matrix-Algebra.html b/doc/interpreter/HTML/Matrix-Algebra.html
new file mode 100644
index 0000000..13903c5
--- /dev/null
+++ b/doc/interpreter/HTML/Matrix-Algebra.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Matrix Algebra - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link rel="prev" href="Basic-Usage.html#Basic-Usage" title="Basic Usage">
+<link rel="next" href="Function-Support.html#Function-Support" title="Function Support">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrix-Algebra"></a>
+Next: <a rel="next" accesskey="n" href="Function-Support.html#Function-Support">Function Support</a>,
+Previous: <a rel="previous" accesskey="p" href="Basic-Usage.html#Basic-Usage">Basic Usage</a>,
+Up: <a rel="up" accesskey="u" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">20.2 Linear Algebra with Diagonal and Permutation Matrices</h3>
+
+<p>As has been already said, diagonal and permutation matrices make it
+possible to use efficient algorithms while preserving natural linear
+algebra syntax.  This section describes in detail the operations that
+are treated specially when performed on these special matrix objects.
+
+<ul class="menu">
+<li><a accesskey="1" href="Expressions-Involving-Diagonal-Matrices.html#Expressions-Involving-Diagonal-Matrices">Expressions Involving Diagonal Matrices</a>
+<li><a accesskey="2" href="Expressions-Involving-Permutation-Matrices.html#Expressions-Involving-Permutation-Matrices">Expressions Involving Permutation Matrices</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Matrix-Factorizations.html b/doc/interpreter/HTML/Matrix-Factorizations.html
new file mode 100644
index 0000000..45bad86
--- /dev/null
+++ b/doc/interpreter/HTML/Matrix-Factorizations.html
@@ -0,0 +1,760 @@
+<html lang="en">
+<head>
+<title>Matrix Factorizations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link rel="prev" href="Basic-Matrix-Functions.html#Basic-Matrix-Functions" title="Basic Matrix Functions">
+<link rel="next" href="Functions-of-a-Matrix.html#Functions-of-a-Matrix" title="Functions of a Matrix">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrix-Factorizations"></a>
+Next: <a rel="next" accesskey="n" href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a>,
+Previous: <a rel="previous" accesskey="p" href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a>,
+Up: <a rel="up" accesskey="u" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>
+<hr>
+</div>
+
+<h3 class="section">18.3 Matrix Factorizations</h3>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+<p><a name="doc_002dchol"></a>
+
+<div class="defun">
+— Loadable Function: <var>r</var> = <b>chol</b> (<var>a</var>)<var><a name="index-chol-1582"></a></var><br>
+— Loadable Function: [<var>r</var>, <var>p</var>] = <b>chol</b> (<var>a</var>)<var><a name="index-chol-1583"></a></var><br>
+— Loadable Function: [<var>r</var>, <var>p</var>, <var>q</var>] = <b>chol</b> (<var>s</var>)<var><a name="index-chol-1584"></a></var><br>
+— Loadable Function: [<var>r</var>, <var>p</var>, <var>q</var>] = <b>chol</b> (<var>s, 'vector'</var>)<var><a name="index-chol-1585"></a></var><br>
+— Loadable Function: [<var>l</var>, <small class="dots">...</small>] = <b>chol</b> (<var><small class="dots">...</small>, 'lower'</var>)<var><a name="index-chol-1586"></a></var><br>
+<blockquote><p><a name="index-Cholesky-factorization-1587"></a>Compute the Cholesky factor, <var>r</var>, of the symmetric positive definite
+matrix <var>a</var>, where
+
+     <pre class="example">          <var>r</var>' * <var>r</var> = <var>a</var>.
+</pre>
+        <p>Called with one output argument <code>chol</code> fails if <var>a</var> or <var>s</var> is
+not positive definite.  With two or more output arguments <var>p</var> flags
+whether the matrix was positive definite and <code>chol</code> does not fail.  A
+zero value indicated that the matrix was positive definite and the <var>r</var>
+gives the factorization, and <var>p</var> will have a positive value otherwise.
+
+        <p>If called with 3 outputs then a sparsity preserving row/column permutation
+is applied to <var>a</var> prior to the factorization.  That is <var>r</var>
+is the factorization of <var>a</var><code>(</code><var>q</var><code>,</code><var>q</var><code>)</code> such that
+
+     <pre class="example">          <var>r</var>' * <var>r</var> = <var>q</var>' * <var>a</var> * <var>q</var>.
+</pre>
+        <p>The sparsity preserving permutation is generally returned as a matrix. 
+However, given the flag 'vector', <var>q</var> will be returned as a vector
+such that
+
+     <pre class="example">          <var>r</var>' * <var>r</var> = a (<var>q</var>, <var>q</var>).
+</pre>
+        <p>Called with either a sparse or full matrix and using the 'lower' flag,
+<code>chol</code> returns the lower triangular factorization such that
+
+     <pre class="example">          <var>l</var> * <var>l</var>' = <var>a</var>.
+</pre>
+        <p>In general the lower triangular factorization is significantly faster for
+sparse matrices. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcholinv.html#doc_002dcholinv">cholinv</a>, <a href="doc_002dchol2inv.html#doc_002dchol2inv">chol2inv</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+   <p><a name="doc_002dcholinv"></a>
+
+<div class="defun">
+— Loadable Function:  <b>cholinv</b> (<var>a</var>)<var><a name="index-cholinv-1588"></a></var><br>
+<blockquote><p>Use the Cholesky factorization to compute the inverse of the
+symmetric positive definite matrix <var>a</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchol.html#doc_002dchol">chol</a>, <a href="doc_002dchol2inv.html#doc_002dchol2inv">chol2inv</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+   <p><a name="doc_002dchol2inv"></a>
+
+<div class="defun">
+— Loadable Function:  <b>chol2inv</b> (<var>u</var>)<var><a name="index-chol2inv-1589"></a></var><br>
+<blockquote><p>Invert a symmetric, positive definite square matrix from its Cholesky
+decomposition, <var>u</var>.  Note that <var>u</var> should be an upper-triangular
+matrix with positive diagonal elements.  <code>chol2inv (</code><var>u</var><code>)</code>
+provides <code>inv (</code><var>u</var><code>'*</code><var>u</var><code>)</code> but it is much faster than
+using <code>inv</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchol.html#doc_002dchol">chol</a>, <a href="doc_002dcholinv.html#doc_002dcholinv">cholinv</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+   <p><a name="doc_002dcholupdate"></a>
+
+<div class="defun">
+— Loadable Function: [<var>R1</var>, <var>info</var>] = <b>cholupdate</b> (<var>R, u, op</var>)<var><a name="index-cholupdate-1590"></a></var><br>
+<blockquote><p>Update or downdate a Cholesky factorization.  Given an upper triangular
+matrix <var>R</var> and a column vector <var>u</var>, attempt to determine another
+upper triangular matrix <var>R1</var> such that
+          <ul>
+<li><var>R1</var>'*<var>R1</var> = <var>R</var>'*<var>R</var> + <var>u</var>*<var>u</var>'
+if <var>op</var> is "+"
+<li><var>R1</var>'*<var>R1</var> = <var>R</var>'*<var>R</var> - <var>u</var>*<var>u</var>'
+if <var>op</var> is "-"
+</ul>
+
+        <p>If <var>op</var> is "-", <var>info</var> is set to
+          <ul>
+<li>0 if the downdate was successful,
+<li>1 if <var>R</var>'*<var>R</var> - <var>u</var>*<var>u</var>' is not positive definite,
+<li>2 if <var>R</var> is singular. 
+</ul>
+
+        <p>If <var>info</var> is not present, an error message is printed in cases 1 and 2. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchol.html#doc_002dchol">chol</a>, <a href="doc_002dqrupdate.html#doc_002dqrupdate">qrupdate</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+   <p><a name="doc_002dcholinsert"></a>
+
+<div class="defun">
+— Loadable Function: [<var>R1</var>, <var>info</var>] = <b>cholinsert</b> (<var>R, j, u</var>)<var><a name="index-cholinsert-1591"></a></var><br>
+<blockquote><p>Given a Cholesky factorization of a real symmetric or complex hermitian
+positive definite matrix <var>A</var> = <var>R</var>'*<var>R</var><!-- /@w -->, <var>R</var> upper triangular,
+return the Cholesky factorization of
+<var>A1</var>, where A1(p,p) = A<!-- /@w -->, A1(:,j) = A1(j,:)' = u<!-- /@w --> and
+p = [1:j-1,j+1:n+1]<!-- /@w -->.  u(j)<!-- /@w --> should be positive. 
+On return, <var>info</var> is set to
+          <ul>
+<li>0 if the insertion was successful,
+<li>1 if <var>A1</var> is not positive definite,
+<li>2 if <var>R</var> is singular. 
+</ul>
+
+        <p>If <var>info</var> is not present, an error message is printed in cases 1 and 2. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchol.html#doc_002dchol">chol</a>, <a href="doc_002dcholupdate.html#doc_002dcholupdate">cholupdate</a>, <a href="doc_002dcholdelete.html#doc_002dcholdelete">choldelete</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+   <p><a name="doc_002dcholdelete"></a>
+
+<div class="defun">
+— Loadable Function: <var>R1</var> = <b>choldelete</b> (<var>R, j</var>)<var><a name="index-choldelete-1592"></a></var><br>
+<blockquote><p>Given a Cholesky factorization of a real symmetric or complex hermitian
+positive definite matrix <var>A</var> = <var>R</var>'*<var>R</var><!-- /@w -->, <var>R</var> upper triangular,
+return the Cholesky factorization of A(p,p)<!-- /@w -->, where p = [1:j-1,j+1:n+1]<!-- /@w -->. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchol.html#doc_002dchol">chol</a>, <a href="doc_002dcholupdate.html#doc_002dcholupdate">cholupdate</a>, <a href="doc_002dcholinsert.html#doc_002dcholinsert">cholinsert</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/chol.cc -->
+   <p><a name="doc_002dcholshift"></a>
+
+<div class="defun">
+— Loadable Function: <var>R1</var> = <b>cholshift</b> (<var>R, i, j</var>)<var><a name="index-cholshift-1593"></a></var><br>
+<blockquote><p>Given a Cholesky factorization of a real symmetric or complex hermitian
+positive definite matrix <var>A</var> = <var>R</var>'*<var>R</var><!-- /@w -->, <var>R</var> upper triangular,
+return the Cholesky factorization of
+<var>A</var>(p,p)<!-- /@w -->, where p<!-- /@w --> is the permutation <br>
+<code>p = [1:i-1, shift(i:j, 1), j+1:n]</code> if <var>i</var> < <var>j</var><!-- /@w --> <br>
+ or <br>
+<code>p = [1:j-1, shift(j:i,-1), i+1:n]</code> if <var>j</var> < <var>i</var><!-- /@w -->.  <br>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchol.html#doc_002dchol">chol</a>, <a href="doc_002dcholinsert.html#doc_002dcholinsert">cholinsert</a>, <a href="doc_002dcholdelete.html#doc_002dcholdelete">choldelete</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/hess.cc -->
+   <p><a name="doc_002dhess"></a>
+
+<div class="defun">
+— Loadable Function: <var>h</var> = <b>hess</b> (<var>a</var>)<var><a name="index-hess-1594"></a></var><br>
+— Loadable Function: [<var>p</var>, <var>h</var>] = <b>hess</b> (<var>a</var>)<var><a name="index-hess-1595"></a></var><br>
+<blockquote><p><a name="index-Hessenberg-decomposition-1596"></a>Compute the Hessenberg decomposition of the matrix <var>a</var>.
+
+        <p>The Hessenberg decomposition is usually used as the first step in an
+eigenvalue computation, but has other applications as well (see Golub,
+Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).  The
+Hessenberg decomposition is
+<code>p * h * p' = a</code> where <code>p</code> is a square unitary matrix
+(<code>p' * p = I</code>, using complex-conjugate transposition) and <code>h</code>
+is upper Hessenberg (<code>i >= j+1 => h (i, j) = 0</code>). 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/lu.cc -->
+   <p><a name="doc_002dlu"></a>
+
+<div class="defun">
+— Loadable Function: [<var>l</var>, <var>u</var>, <var>p</var>] = <b>lu</b> (<var>a</var>)<var><a name="index-lu-1597"></a></var><br>
+— Loadable Function: [<var>l</var>, <var>u</var>, <var>p</var>, <var>q</var>] = <b>lu</b> (<var>s</var>)<var><a name="index-lu-1598"></a></var><br>
+— Loadable Function: [<var>l</var>, <var>u</var>, <var>p</var>, <var>q</var>, <var>r</var>] = <b>lu</b> (<var>s</var>)<var><a name="index-lu-1599"></a></var><br>
+— Loadable Function: [<small class="dots">...</small>] = <b>lu</b> (<var>s, thres</var>)<var><a name="index-lu-1600"></a></var><br>
+— Loadable Function: <var>y</var> = <b>lu</b> (<var><small class="dots">...</small></var>)<var><a name="index-lu-1601"></a></var><br>
+— Loadable Function: [<small class="dots">...</small>] = <b>lu</b> (<var><small class="dots">...</small>, 'vector'</var>)<var><a name="index-lu-1602"></a></var><br>
+<blockquote><p><a name="index-LU-decomposition-1603"></a>Compute the LU decomposition of <var>a</var>.  If <var>a</var> is full subroutines from
+<span class="sc">lapack</span> are used and if <var>a</var> is sparse then UMFPACK is used.  The
+result is returned in a permuted form, according to the optional return
+value <var>p</var>.  For example, given the matrix <code>a = [1, 2; 3, 4]</code>,
+
+     <pre class="example">          [l, u, p] = lu (a)
+</pre>
+        <p class="noindent">returns
+
+     <pre class="example">          l =
+          
+            1.00000  0.00000
+            0.33333  1.00000
+          
+          u =
+          
+            3.00000  4.00000
+            0.00000  0.66667
+          
+          p =
+          
+            0  1
+            1  0
+</pre>
+        <p>The matrix is not required to be square.
+
+        <p>Called with two or three output arguments and a spare input matrix,
+then <dfn>lu</dfn> does not attempt to perform sparsity preserving column
+permutations.  Called with a fourth output argument, the sparsity
+preserving column transformation <var>Q</var> is returned, such that
+<var>p</var><code> * </code><var>a</var><code> * </code><var>q</var><code> = </code><var>l</var><code> * </code><var>u</var>.
+
+        <p>Called with a fifth output argument and a sparse input matrix, then
+<dfn>lu</dfn> attempts to use a scaling factor <var>r</var> on the input matrix
+such that <var>p</var><code> * (</code><var>r</var><code> \ </code><var>a</var><code>) * </code><var>q</var><code> = </code><var>l</var><code> * </code><var>u</var>. 
+This typically leads to a sparser and more stable factorization.
+
+        <p>An additional input argument <var>thres</var>, that defines the pivoting
+threshold can be given.  <var>thres</var> can be a scalar, in which case
+it defines UMFPACK pivoting tolerance for both symmetric and unsymmetric
+cases.  If <var>thres</var> is a two element vector, then the first element
+defines the pivoting tolerance for the unsymmetric UMFPACK pivoting
+strategy and the second the symmetric strategy.  By default, the values
+defined by <code>spparms</code> are used and are by default <code>[0.1, 0.001]</code>.
+
+        <p>Given the string argument 'vector', <dfn>lu</dfn> returns the values of <var>p</var>
+<var>q</var> as vector values, such that for full matrix, <var>a</var><code>
+(</code><var>p</var><code>,:) = </code><var>l</var><code> * </code><var>u</var>, and <var>r</var><code>(</code><var>p</var><code>,:) * </code><var>a</var><code>
+(:, </code><var>q</var><code>) = </code><var>l</var><code> * </code><var>u</var>.
+
+        <p>With two output arguments, returns the permuted forms of the upper and
+lower triangular matrices, such that <var>a</var><code> = </code><var>l</var><code> * </code><var>u</var>. 
+With one output argument <var>y</var>, then the matrix returned by the <span class="sc">lapack</span>
+routines is returned.  If the input matrix is sparse then the matrix <var>l</var>
+is embedded into <var>u</var> to give a return value similar to the full case. 
+For both full and sparse matrices, <dfn>lu</dfn> looses the permutation
+information. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/qr.cc -->
+   <p><a name="doc_002dqr"></a>
+
+<div class="defun">
+— Loadable Function: [<var>q</var>, <var>r</var>, <var>p</var>] = <b>qr</b> (<var>a</var>)<var><a name="index-qr-1604"></a></var><br>
+— Loadable Function: [<var>q</var>, <var>r</var>, <var>p</var>] = <b>qr</b> (<var>a, '0'</var>)<var><a name="index-qr-1605"></a></var><br>
+<blockquote><p><a name="index-QR-factorization-1606"></a>Compute the QR factorization of <var>a</var>, using standard <span class="sc">lapack</span>
+subroutines.  For example, given the matrix <code>a = [1, 2; 3, 4]</code>,
+
+     <pre class="example">          [q, r] = qr (a)
+</pre>
+        <p class="noindent">returns
+
+     <pre class="example">          q =
+          
+            -0.31623  -0.94868
+            -0.94868   0.31623
+          
+          r =
+          
+            -3.16228  -4.42719
+             0.00000  -0.63246
+</pre>
+        <p>The <code>qr</code> factorization has applications in the solution of least
+squares problems
+
+     <pre class="example">          <code>min norm(A x - b)</code>
+</pre>
+        <p>for overdetermined systems of equations (i.e.,
+<code>a</code>
+ is a tall, thin matrix).  The QR factorization is
+<code>q * r = a</code> where <code>q</code> is an orthogonal matrix and <code>r</code> is
+upper triangular.
+
+        <p>If given a second argument of '0', <code>qr</code> returns an economy-sized
+QR factorization, omitting zero rows of <var>R</var> and the corresponding
+columns of <var>Q</var>.
+
+        <p>If the matrix <var>a</var> is full, the permuted QR factorization
+<code>[</code><var>q</var><code>, </code><var>r</var><code>, </code><var>p</var><code>] = qr (</code><var>a</var><code>)</code> forms the QR factorization
+such that the diagonal entries of <code>r</code> are decreasing in magnitude
+order.  For example,given the matrix <code>a = [1, 2; 3, 4]</code>,
+
+     <pre class="example">          [q, r, p] = qr(a)
+</pre>
+        <p class="noindent">returns
+
+     <pre class="example">          q =
+          
+            -0.44721  -0.89443
+            -0.89443   0.44721
+          
+          r =
+          
+            -4.47214  -3.13050
+             0.00000   0.44721
+          
+          p =
+          
+             0  1
+             1  0
+</pre>
+        <p>The permuted <code>qr</code> factorization <code>[q, r, p] = qr (a)</code>
+factorization allows the construction of an orthogonal basis of
+<code>span (a)</code>.
+
+        <p>If the matrix <var>a</var> is sparse, then compute the sparse QR factorization
+of <var>a</var>, using <span class="sc">CSparse</span>.  As the matrix <var>Q</var> is in general a full
+matrix, this function returns the <var>Q</var>-less factorization <var>r</var> of
+<var>a</var>, such that <var>r</var><code> = chol (</code><var>a</var><code>' * </code><var>a</var><code>)</code>.
+
+        <p>If the final argument is the scalar <code>0</code> and the number of rows is
+larger than the number of columns, then an economy factorization is
+returned.  That is <var>r</var> will have only <code>size (</code><var>a</var><code>,1)</code> rows.
+
+        <p>If an additional matrix <var>b</var> is supplied, then <code>qr</code> returns
+<var>c</var>, where <var>c</var><code> = </code><var>q</var><code>' * </code><var>b</var>.  This allows the
+least squares approximation of <var>a</var><code> \ </code><var>b</var> to be calculated
+as
+
+     <pre class="example">          [<var>c</var>,<var>r</var>] = spqr (<var>a</var>,<var>b</var>)
+          <var>x</var> = <var>r</var> \ <var>c</var>
+</pre>
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/qr.cc -->
+   <p><a name="doc_002dqrupdate"></a>
+
+<div class="defun">
+— Loadable Function: [<var>Q1</var>, <var>R1</var>] = <b>qrupdate</b> (<var>Q, R, u, v</var>)<var><a name="index-qrupdate-1607"></a></var><br>
+<blockquote><p>Given a QR factorization of a real or complex matrix
+<var>A</var> = <var>Q</var>*<var>R</var><!-- /@w -->, <var>Q</var> unitary and
+<var>R</var> upper trapezoidal, return the QR factorization
+of <var>A</var> + <var>u</var>*<var>v</var>'<!-- /@w -->, where <var>u</var> and <var>v</var> are
+column vectors (rank-1 update) or matrices with equal number of columns
+(rank-k update).  Notice that the latter case is done as a sequence of rank-1 updates;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+        <p>The QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dqr.html#doc_002dqr">qr</a>, <a href="doc_002dqrinsert.html#doc_002dqrinsert">qrinsert</a>, <a href="doc_002dqrdelete.html#doc_002dqrdelete">qrdelete</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/qr.cc -->
+   <p><a name="doc_002dqrinsert"></a>
+
+<div class="defun">
+— Loadable Function: [<var>Q1</var>, <var>R1</var>] = <b>qrinsert</b> (<var>Q, R, j, x, orient</var>)<var><a name="index-qrinsert-1608"></a></var><br>
+<blockquote><p>Given a QR factorization of a real or complex matrix
+<var>A</var> = <var>Q</var>*<var>R</var><!-- /@w -->, <var>Q</var> unitary and
+<var>R</var> upper trapezoidal, return the QR factorization of
+[A(:,1:j-1) x A(:,j:n)]<!-- /@w -->, where <var>u</var> is a column vector to be
+inserted into <var>A</var> (if <var>orient</var> is <code>"col"</code>), or the
+QR factorization of [A(1:j-1,:);x;A(:,j:n)]<!-- /@w -->, where <var>x</var>
+is a row vector to be inserted into <var>A</var> (if <var>orient</var> is
+<code>"row"</code>).
+
+        <p>The default value of <var>orient</var> is <code>"col"</code>. 
+If <var>orient</var> is <code>"col"</code>,
+<var>u</var> may be a matrix and <var>j</var> an index vector
+resulting in the QR factorization of a matrix <var>B</var> such that
+B(:,<var>j</var>)<!-- /@w --> gives <var>u</var> and B(:,<var>j</var>) = []<!-- /@w --> gives <var>A</var>. 
+Notice that the latter case is done as a sequence of k insertions;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+        <p>If <var>orient</var> is <code>"col"</code>,
+the QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+        <p>If <var>orient</var> is <code>"row"</code>, full factorization is needed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dqr.html#doc_002dqr">qr</a>, <a href="doc_002dqrupdate.html#doc_002dqrupdate">qrupdate</a>, <a href="doc_002dqrdelete.html#doc_002dqrdelete">qrdelete</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/qr.cc -->
+   <p><a name="doc_002dqrdelete"></a>
+
+<div class="defun">
+— Loadable Function: [<var>Q1</var>, <var>R1</var>] = <b>qrdelete</b> (<var>Q, R, j, orient</var>)<var><a name="index-qrdelete-1609"></a></var><br>
+<blockquote><p>Given a QR factorization of a real or complex matrix
+<var>A</var> = <var>Q</var>*<var>R</var><!-- /@w -->, <var>Q</var> unitary and
+<var>R</var> upper trapezoidal, return the QR factorization of
+[A(:,1:j-1) A(:,j+1:n)]<!-- /@w -->, i.e., <var>A</var> with one column deleted
+(if <var>orient</var> is "col"), or the QR factorization of
+[A(1:j-1,:);A(:,j+1:n)]<!-- /@w -->, i.e., <var>A</var> with one row deleted (if
+<var>orient</var> is "row").
+
+        <p>The default value of <var>orient</var> is "col".
+
+        <p>If <var>orient</var> is <code>"col"</code>,
+<var>j</var> may be an index vector
+resulting in the QR factorization of a matrix <var>B</var> such that
+A(:,<var>j</var>) = []<!-- /@w --> gives <var>B</var>. 
+Notice that the latter case is done as a sequence of k deletions;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+        <p>If <var>orient</var> is <code>"col"</code>,
+the QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+        <p>If <var>orient</var> is <code>"row"</code>, full factorization is needed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dqr.html#doc_002dqr">qr</a>, <a href="doc_002dqrinsert.html#doc_002dqrinsert">qrinsert</a>, <a href="doc_002dqrupdate.html#doc_002dqrupdate">qrupdate</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/qr.cc -->
+   <p><a name="doc_002dqrshift"></a>
+
+<div class="defun">
+— Loadable Function: [<var>Q1</var>, <var>R1</var>] = <b>qrshift</b> (<var>Q, R, i, j</var>)<var><a name="index-qrshift-1610"></a></var><br>
+<blockquote><p>Given a QR factorization of a real or complex matrix
+<var>A</var> = <var>Q</var>*<var>R</var><!-- /@w -->, <var>Q</var> unitary and
+<var>R</var> upper trapezoidal, return the QR factorization
+of <var>A</var>(:,p)<!-- /@w -->, where p<!-- /@w --> is the permutation <br>
+<code>p = [1:i-1, shift(i:j, 1), j+1:n]</code> if <var>i</var> < <var>j</var><!-- /@w --> <br>
+ or <br>
+<code>p = [1:j-1, shift(j:i,-1), i+1:n]</code> if <var>j</var> < <var>i</var><!-- /@w -->.  <br>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dqr.html#doc_002dqr">qr</a>, <a href="doc_002dqrinsert.html#doc_002dqrinsert">qrinsert</a>, <a href="doc_002dqrdelete.html#doc_002dqrdelete">qrdelete</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/qz.cc -->
+   <p><a name="doc_002dqz"></a>
+
+<div class="defun">
+— Loadable Function: <var>lambda</var> = <b>qz</b> (<var>a, b</var>)<var><a name="index-qz-1611"></a></var><br>
+<blockquote><p>Generalized eigenvalue problem A x = s B x,
+<var>QZ</var> decomposition.  There are three ways to call this function:
+          <ol type=1 start=1>
+<li><code>lambda = qz(A,B)</code>
+
+          <p>Computes the generalized eigenvalues
+<var>lambda</var>
+of (A - s B). 
+<li><code>[AA, BB, Q, Z, V, W, lambda] = qz (A, B)</code>
+
+          <p>Computes qz decomposition, generalized eigenvectors, and
+generalized eigenvalues of (A - sB)
+          <pre class="example">               
+                   A*V = B*V*diag(lambda)
+                   W'*A = diag(lambda)*W'*B
+                   AA = Q'*A*Z, BB = Q'*B*Z
+</pre>
+          <p>with <var>Q</var> and <var>Z</var> orthogonal (unitary)= <var>I</var>
+
+          <li><code>[AA,BB,Z{, lambda}] = qz(A,B,opt)</code>
+
+          <p>As in form [2], but allows ordering of generalized eigenpairs
+for (e.g.) solution of discrete time algebraic Riccati equations. 
+Form 3 is not available for complex matrices, and does not compute
+the generalized eigenvectors <var>V</var>, <var>W</var>, nor the orthogonal matrix <var>Q</var>.
+               <dl>
+<dt><var>opt</var><dd>for ordering eigenvalues of the GEP pencil.  The leading block
+of the revised pencil contains all eigenvalues that satisfy:
+                    <dl>
+<dt><code>"N"</code><dd>= unordered (default)
+
+                    <br><dt><code>"S"</code><dd>= small: leading block has all |lambda| <=1
+
+                    <br><dt><code>"B"</code><dd>= big: leading block has all |lambda| >= 1
+
+                    <br><dt><code>"-"</code><dd>= negative real part: leading block has all eigenvalues
+in the open left half-plane
+
+                    <br><dt><code>"+"</code><dd>= non-negative real part: leading block has all eigenvalues
+in the closed right half-plane
+</dl>
+               </dl>
+          </ol>
+
+        <p>Note: qz performs permutation balancing, but not scaling (see balance). 
+Order of output arguments was selected for compatibility with <span class="sc">matlab</span>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbalance.html#doc_002dbalance">balance</a>, <a href="doc_002deig.html#doc_002deig">eig</a>, <a href="doc_002dschur.html#doc_002dschur">schur</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/qzhess.m -->
+   <p><a name="doc_002dqzhess"></a>
+
+<div class="defun">
+— Function File: [<var>aa</var>, <var>bb</var>, <var>q</var>, <var>z</var>] = <b>qzhess</b> (<var>a, b</var>)<var><a name="index-qzhess-1612"></a></var><br>
+<blockquote><p>Compute the Hessenberg-triangular decomposition of the matrix pencil
+<code>(</code><var>a</var><code>, </code><var>b</var><code>)</code>, returning
+<var>aa</var><code> = </code><var>q</var><code> * </code><var>a</var><code> * </code><var>z</var>,
+<var>bb</var><code> = </code><var>q</var><code> * </code><var>b</var><code> * </code><var>z</var>, with <var>q</var> and <var>z</var>
+orthogonal.  For example,
+
+     <pre class="example">          [aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
+                aa = [ -3.02244, -4.41741;  0.92998,  0.69749 ]
+                bb = [ -8.60233, -9.99730;  0.00000, -0.23250 ]
+                 q = [ -0.58124, -0.81373; -0.81373,  0.58124 ]
+                 z = [ 1, 0; 0, 1 ]
+</pre>
+        <p>The Hessenberg-triangular decomposition is the first step in
+Moler and Stewart's QZ decomposition algorithm.
+
+        <p>Algorithm taken from Golub and Van Loan, <cite>Matrix Computations, 2nd
+edition</cite>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/schur.cc -->
+   <p><a name="doc_002dschur"></a>
+
+<div class="defun">
+— Loadable Function: <var>s</var> = <b>schur</b> (<var>a</var>)<var><a name="index-schur-1613"></a></var><br>
+— Loadable Function: [<var>u</var>, <var>s</var>] = <b>schur</b> (<var>a, opt</var>)<var><a name="index-schur-1614"></a></var><br>
+<blockquote><p><a name="index-Schur-decomposition-1615"></a>The Schur decomposition is used to compute eigenvalues of a
+square matrix, and has applications in the solution of algebraic
+Riccati equations in control (see <code>are</code> and <code>dare</code>). 
+<code>schur</code> always returns
+<code>s = u' * a * u</code>
+where
+<code>u</code>
+ is a unitary matrix
+(<code>u'* u</code> is identity)
+and
+<code>s</code>
+is upper triangular.  The eigenvalues of
+<code>a</code> (and <code>s</code>)
+are the diagonal elements of
+<code>s</code>. 
+If the matrix
+<code>a</code>
+is real, then the real Schur decomposition is computed, in which the
+matrix
+<code>u</code>
+is orthogonal and
+<code>s</code>
+is block upper triangular
+with blocks of size at most
+<code>2 x 2</code>
+along the diagonal.  The diagonal elements of
+<code>s</code>
+(or the eigenvalues of the
+<code>2 x 2</code>
+blocks, when
+appropriate) are the eigenvalues of
+<code>a</code>
+and
+<code>s</code>.
+
+        <p>The eigenvalues are optionally ordered along the diagonal according to
+the value of <code>opt</code>.  <code>opt = "a"</code> indicates that all
+eigenvalues with negative real parts should be moved to the leading
+block of
+<code>s</code>
+(used in <code>are</code>), <code>opt = "d"</code> indicates that all eigenvalues
+with magnitude less than one should be moved to the leading block of
+<code>s</code>
+(used in <code>dare</code>), and <code>opt = "u"</code>, the default, indicates that
+no ordering of eigenvalues should occur.  The leading
+<code>k</code>
+columns of
+<code>u</code>
+always span the
+<code>a</code>-invariant
+subspace corresponding to the
+<code>k</code>
+leading eigenvalues of
+<code>s</code>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/subspace.m -->
+   <p><a name="doc_002dsubspace"></a>
+
+<div class="defun">
+— Function File: <var>angle</var> = <b>subspace</b> (<var>a, B</var>)<var><a name="index-subspace-1616"></a></var><br>
+<blockquote><p>Determine the largest principal angle between two subspaces
+spanned by columns of matrices <var>a</var> and <var>b</var>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/svd.cc -->
+   <p><a name="doc_002dsvd"></a>
+
+<div class="defun">
+— Loadable Function: <var>s</var> = <b>svd</b> (<var>a</var>)<var><a name="index-svd-1617"></a></var><br>
+— Loadable Function: [<var>u</var>, <var>s</var>, <var>v</var>] = <b>svd</b> (<var>a</var>)<var><a name="index-svd-1618"></a></var><br>
+<blockquote><p><a name="index-singular-value-decomposition-1619"></a>Compute the singular value decomposition of <var>a</var>
+
+     <pre class="example">          A = U*S*V'
+</pre>
+        <p>The function <code>svd</code> normally returns the vector of singular values. 
+If asked for three return values, it computes
+U, S, and V. 
+For example,
+
+     <pre class="example">          svd (hilb (3))
+</pre>
+        <p class="noindent">returns
+
+     <pre class="example">          ans =
+          
+            1.4083189
+            0.1223271
+            0.0026873
+</pre>
+        <p class="noindent">and
+
+     <pre class="example">          [u, s, v] = svd (hilb (3))
+</pre>
+        <p class="noindent">returns
+
+     <pre class="example">          u =
+          
+            -0.82704   0.54745   0.12766
+            -0.45986  -0.52829  -0.71375
+            -0.32330  -0.64901   0.68867
+          
+          s =
+          
+            1.40832  0.00000  0.00000
+            0.00000  0.12233  0.00000
+            0.00000  0.00000  0.00269
+          
+          v =
+          
+            -0.82704   0.54745   0.12766
+            -0.45986  -0.52829  -0.71375
+            -0.32330  -0.64901   0.68867
+</pre>
+        <p>If given a second argument, <code>svd</code> returns an economy-sized
+decomposition, eliminating the unnecessary rows or columns of <var>u</var> or
+<var>v</var>. 
+</p></blockquote></div>
+
+<!-- FIXME - should there be a new section here? -->
+<!-- ./linear-algebra/housh.m -->
+   <p><a name="doc_002dhoush"></a>
+
+<div class="defun">
+— Function File: [<var>housv</var>, <var>beta</var>, <var>zer</var>] = <b>housh</b> (<var>x, j, z</var>)<var><a name="index-housh-1620"></a></var><br>
+<blockquote><p>Compute Householder reflection vector <var>housv</var> to reflect <var>x</var>
+to be the j-th column of identity, i.e.,
+
+     <pre class="example">          (I - beta*housv*housv')x =  norm(x)*e(j) if x(1) < 0,
+          (I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0
+</pre>
+        <p class="noindent">Inputs
+
+          <dl>
+<dt><var>x</var><dd>vector
+<br><dt><var>j</var><dd>index into vector
+<br><dt><var>z</var><dd>threshold for zero  (usually should be the number 0)
+</dl>
+
+     <p class="noindent">Outputs (see Golub and Van Loan):
+
+          <dl>
+<dt><var>beta</var><dd>If beta = 0, then no reflection need be applied (zer set to 0)
+<br><dt><var>housv</var><dd>householder vector
+</dl>
+        </p></blockquote></div>
+
+<!-- ./linear-algebra/krylov.m -->
+   <p><a name="doc_002dkrylov"></a>
+
+<div class="defun">
+— Function File: [<var>u</var>, <var>h</var>, <var>nu</var>] = <b>krylov</b> (<var>a, v, k, eps1, pflg</var>)<var><a name="index-krylov-1621"></a></var><br>
+<blockquote><p>Construct an orthogonal basis <var>u</var> of block Krylov subspace
+
+     <pre class="example">          [v a*v a^2*v ... a^(k+1)*v]
+</pre>
+        <p class="noindent">Using Householder reflections to guard against loss of orthogonality.
+
+        <p>If <var>v</var> is a vector, then <var>h</var> contains the Hessenberg matrix
+such that <code>a*u == u*h+rk*ek'</code>, in which <code>rk =
+a*u(:,k)-u*h(:,k)</code>, and <code>ek'</code> is the vector
+<code>[0, 0, ..., 1]</code> of length <code>k</code>.  Otherwise, <var>h</var> is
+meaningless.
+
+        <p>If <var>v</var> is a vector and <var>k</var> is greater than
+<code>length(A)-1</code>, then <var>h</var> contains the Hessenberg matrix such
+that <code>a*u == u*h</code>.
+
+        <p>The value of <var>nu</var> is the dimension of the span of the krylov
+subspace (based on <var>eps1</var>).
+
+        <p>If <var>b</var> is a vector and <var>k</var> is greater than <var>m-1</var>, then
+<var>h</var> contains the Hessenberg decomposition of <var>a</var>.
+
+        <p>The optional parameter <var>eps1</var> is the threshold for zero.  The
+default value is 1e-12.
+
+        <p>If the optional parameter <var>pflg</var> is nonzero, row pivoting is used
+to improve numerical behavior.  The default value is 0.
+
+        <p>Reference: Hodel and Misra, "Partial Pivoting in the Computation of
+Krylov Subspaces", to be submitted to Linear Algebra and its
+Applications
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Matrix-Manipulation.html b/doc/interpreter/HTML/Matrix-Manipulation.html
new file mode 100644
index 0000000..ffd81d4
--- /dev/null
+++ b/doc/interpreter/HTML/Matrix-Manipulation.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Matrix Manipulation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Plotting.html#Plotting" title="Plotting">
+<link rel="next" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrix-Manipulation"></a>
+Next: <a rel="next" accesskey="n" href="Arithmetic.html#Arithmetic">Arithmetic</a>,
+Previous: <a rel="previous" accesskey="p" href="Plotting.html#Plotting">Plotting</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">16 Matrix Manipulation</h2>
+
+<p>There are a number of functions available for checking to see if the
+elements of a matrix meet some condition, and for rearranging the
+elements of a matrix.  For example, Octave can easily tell you if all
+the elements of a matrix are finite, or are less than some specified
+value.  Octave can also rotate the elements, extract the upper- or
+lower-triangular parts, or sort the columns of a matrix.
+
+<ul class="menu">
+<li><a accesskey="1" href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a>
+<li><a accesskey="2" href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a>
+<li><a accesskey="3" href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">Applying a Function to an Array</a>
+<li><a accesskey="4" href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a>
+<li><a accesskey="5" href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Mex_002dFiles.html b/doc/interpreter/HTML/Mex_002dFiles.html
new file mode 100644
index 0000000..9c63db7
--- /dev/null
+++ b/doc/interpreter/HTML/Mex_002dFiles.html
@@ -0,0 +1,63 @@
+<html lang="en">
+<head>
+<title>Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions" title="Dynamically Linked Functions">
+<link rel="prev" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="next" href="Standalone-Programs.html#Standalone-Programs" title="Standalone Programs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Mex-Files"></a>
+<a name="Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Standalone-Programs.html#Standalone-Programs">Standalone Programs</a>,
+Previous: <a rel="previous" accesskey="p" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>
+<hr>
+</div>
+
+<h3 class="section">A.2 Mex-Files</h3>
+
+<p><a name="index-mex_002dfiles-2480"></a><a name="index-mex-2481"></a>
+Octave includes an interface to allow legacy mex-files to be compiled
+and used with Octave.  This interface can also be used to share code
+between Octave and non Octave users.  However, as mex-files expose the
+internal API of an alternative product to Octave, and the internal
+structure of Octave is different to this product, a mex-file can never
+have the same performance in Octave as the equivalent oct-file.  In
+particular to support the manner in which mex-files access the variables
+passed to mex functions, there are a significant number of additional
+copies of memory when calling or returning from a mex function.  For
+this reason, new code should be written using the oct-file interface
+discussed above if possible.
+
+<ul class="menu">
+<li><a accesskey="1" href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles">Getting Started with Mex-Files</a>
+<li><a accesskey="2" href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles">Working with Matrices and Arrays in Mex-Files</a>
+<li><a accesskey="3" href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles">Character Strings in Mex-Files</a>
+<li><a accesskey="4" href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles">Cell Arrays with Mex-Files</a>
+<li><a accesskey="5" href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles">Structures with Mex-Files</a>
+<li><a accesskey="6" href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles">Sparse Matrices with Mex-Files</a>
+<li><a accesskey="7" href="Calling-Other-Functions-in-Mex_002dFiles.html#Calling-Other-Functions-in-Mex_002dFiles">Calling Other Functions in Mex-Files</a>
+<!-- * Application Programming Interface for Mex-Files:: -->
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Miscellaneous-Functions.html b/doc/interpreter/HTML/Miscellaneous-Functions.html
new file mode 100644
index 0000000..cd2c3a5
--- /dev/null
+++ b/doc/interpreter/HTML/Miscellaneous-Functions.html
@@ -0,0 +1,112 @@
+<html lang="en">
+<head>
+<title>Miscellaneous Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="prev" href="Polynomial-Interpolation.html#Polynomial-Interpolation" title="Polynomial Interpolation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Miscellaneous-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a>,
+Up: <a rel="up" accesskey="u" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<hr>
+</div>
+
+<h3 class="section">27.6 Miscellaneous Functions</h3>
+
+<!-- ./polynomial/poly.m -->
+<p><a name="doc_002dpoly"></a>
+
+<div class="defun">
+— Function File:  <b>poly</b> (<var>a</var>)<var><a name="index-poly-2053"></a></var><br>
+<blockquote><p>If <var>a</var> is a square N-by-N matrix, <code>poly (</code><var>a</var><code>)</code>
+is the row vector of the coefficients of <code>det (z * eye (N) - a)</code>,
+the characteristic polynomial of <var>a</var>.  As an example we can use
+this to find the eigenvalues of <var>a</var> as the roots of <code>poly (</code><var>a</var><code>)</code>.
+     <pre class="example">          roots(poly(eye(3)))
+           1.00000 + 0.00000i
+           1.00000 - 0.00000i
+           1.00000 + 0.00000i
+</pre>
+        <p>In real-life examples you should, however, use the <code>eig</code> function
+for computing eigenvalues.
+
+        <p>If <var>x</var> is a vector, <code>poly (</code><var>x</var><code>)</code> is a vector of coefficients
+of the polynomial whose roots are the elements of <var>x</var>.  That is,
+of <var>c</var> is a polynomial, then the elements of
+<var>d</var><code> = roots (poly (</code><var>c</var><code>))</code> are contained in <var>c</var>. 
+The vectors <var>c</var> and <var>d</var> are, however, not equal due to sorting
+and numerical errors. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002deig.html#doc_002deig">eig</a>, <a href="doc_002droots.html#doc_002droots">roots</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/polyout.m -->
+   <p><a name="doc_002dpolyout"></a>
+
+<div class="defun">
+— Function File:  <b>polyout</b> (<var>c, x</var>)<var><a name="index-polyout-2054"></a></var><br>
+<blockquote><p>Write formatted polynomial
+     <pre class="example">             c(x) = c(1) * x^n + ... + c(n) x + c(n+1)
+</pre>
+        <p>and return it as a string or write it to the screen (if
+<var>nargout</var> is zero). 
+<var>x</var> defaults to the string <code>"s"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>, <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/polyreduce.m -->
+   <p><a name="doc_002dpolyreduce"></a>
+
+<div class="defun">
+— Function File:  <b>polyreduce</b> (<var>c</var>)<var><a name="index-polyreduce-2055"></a></var><br>
+<blockquote><p>Reduces a polynomial coefficient vector to a minimum number of terms by
+stripping off any leading zeros. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Missing-Data.html b/doc/interpreter/HTML/Missing-Data.html
new file mode 100644
index 0000000..b9555e4
--- /dev/null
+++ b/doc/interpreter/HTML/Missing-Data.html
@@ -0,0 +1,91 @@
+<html lang="en">
+<head>
+<title>Missing Data - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Built_002din-Data-Types.html#Built_002din-Data-Types" title="Built-in Data Types">
+<link rel="prev" href="Numeric-Objects.html#Numeric-Objects" title="Numeric Objects">
+<link rel="next" href="String-Objects.html#String-Objects" title="String Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Missing-Data"></a>
+Next: <a rel="next" accesskey="n" href="String-Objects.html#String-Objects">String Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="Numeric-Objects.html#Numeric-Objects">Numeric Objects</a>,
+Up: <a rel="up" accesskey="u" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<hr>
+</div>
+
+<h4 class="subsection">3.1.2 Missing Data</h4>
+
+<p><a name="index-missing-data-184"></a>
+It is possible to represent missing data explicitly in Octave using
+<code>NA</code> (short for “Not Available”).  Missing data can only be
+represented when data is represented as floating point numbers.  In this
+case missing data is represented as a special case of the representation
+of <code>NaN</code>.
+
+<!-- data.cc -->
+   <p><a name="doc_002dNA"></a>
+
+<div class="defun">
+— Built-in Function:  <b>NA</b><var><a name="index-NA-185"></a></var><br>
+— Built-in Function:  <b>NA</b> (<var>n</var>)<var><a name="index-NA-186"></a></var><br>
+— Built-in Function:  <b>NA</b> (<var>n, m</var>)<var><a name="index-NA-187"></a></var><br>
+— Built-in Function:  <b>NA</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-NA-188"></a></var><br>
+— Built-in Function:  <b>NA</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-NA-189"></a></var><br>
+<blockquote><p>Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the special constant used to designate missing values.
+
+        <p>Note that NA always compares not equal to NA (NA != NA). 
+To find NA values, use the <code>isna</code> function.
+
+        <p>When called with no arguments, return a scalar with the value ‘<samp><span class="samp">NA</span></samp>’. 
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions. 
+The optional argument <var>class</var> specifies the return type and may be
+either "double" or "single". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disna.html#doc_002disna">isna</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002disna"></a>
+
+<div class="defun">
+— Mapping Function:  <b>isna</b> (<var>x</var>)<var><a name="index-isna-190"></a></var><br>
+<blockquote><p>Return 1 for elements of <var>x</var> that are NA (missing) values and zero
+otherwise.  For example,
+
+     <pre class="example">          isna ([13, Inf, NA, NaN])
+                [ 0, 0, 1, 0 ]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disnan.html#doc_002disnan">isnan</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Models.html b/doc/interpreter/HTML/Models.html
new file mode 100644
index 0000000..ece8d22
--- /dev/null
+++ b/doc/interpreter/HTML/Models.html
@@ -0,0 +1,88 @@
+<html lang="en">
+<head>
+<title>Models - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="prev" href="Tests.html#Tests" title="Tests">
+<link rel="next" href="Distributions.html#Distributions" title="Distributions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Models"></a>
+Next: <a rel="next" accesskey="n" href="Distributions.html#Distributions">Distributions</a>,
+Previous: <a rel="previous" accesskey="p" href="Tests.html#Tests">Tests</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.5 Models</h3>
+
+<!-- ./statistics/models/logistic_regression.m -->
+<p><a name="doc_002dlogistic_005fregression"></a>
+
+<div class="defun">
+— Function File: [<var>theta</var>, <var>beta</var>, <var>dev</var>, <var>dl</var>, <var>d2l</var>, <var>p</var>] = <b>logistic_regression</b> (<var>y, x, print, theta, beta</var>)<var><a name="index-logistic_005fregression-1890"></a></var><br>
+<blockquote><p>Perform ordinal logistic regression.
+
+        <p>Suppose <var>y</var> takes values in <var>k</var> ordered categories, and let
+<code>gamma_i (</code><var>x</var><code>)</code> be the cumulative probability that <var>y</var>
+falls in one of the first <var>i</var> categories given the covariate
+<var>x</var>.  Then
+
+     <pre class="example">          [theta, beta] = logistic_regression (y, x)
+</pre>
+        <p class="noindent">fits the model
+
+     <pre class="example">          logit (gamma_i (x)) = theta_i - beta' * x,   i = 1 ... k-1
+</pre>
+        <p>The number of ordinal categories, <var>k</var>, is taken to be the number
+of distinct values of <code>round (</code><var>y</var><code>)</code>.  If <var>k</var> equals 2,
+<var>y</var> is binary and the model is ordinary logistic regression.  The
+matrix <var>x</var> is assumed to have full column rank.
+
+        <p>Given <var>y</var> only, <code>theta = logistic_regression (y)</code>
+fits the model with baseline logit odds only.
+
+        <p>The full form is
+
+     <pre class="example">          [theta, beta, dev, dl, d2l, gamma]
+             = logistic_regression (y, x, print, theta, beta)
+</pre>
+        <p class="noindent">in which all output arguments and all input arguments except <var>y</var>
+are optional.
+
+        <p>Setting <var>print</var> to 1 requests summary information about the fitted
+model to be displayed.  Setting <var>print</var> to 2 requests information
+about convergence at each iteration.  Other values request no
+information to be displayed.  The input arguments <var>theta</var> and
+<var>beta</var> give initial estimates for <var>theta</var> and <var>beta</var>.
+
+        <p>The returned value <var>dev</var> holds minus twice the log-likelihood.
+
+        <p>The returned values <var>dl</var> and <var>d2l</var> are the vector of first
+and the matrix of second derivatives of the log-likelihood with
+respect to <var>theta</var> and <var>beta</var>.
+
+        <p><var>p</var> holds estimates for the conditional distribution of <var>y</var>
+given <var>x</var>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Multi_002ddimensional-Interpolation.html b/doc/interpreter/HTML/Multi_002ddimensional-Interpolation.html
new file mode 100644
index 0000000..837f658
--- /dev/null
+++ b/doc/interpreter/HTML/Multi_002ddimensional-Interpolation.html
@@ -0,0 +1,252 @@
+<html lang="en">
+<head>
+<title>Multi-dimensional Interpolation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Interpolation.html#Interpolation" title="Interpolation">
+<link rel="prev" href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation" title="One-dimensional Interpolation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Multi-dimensional-Interpolation"></a>
+<a name="Multi_002ddimensional-Interpolation"></a>
+Previous: <a rel="previous" accesskey="p" href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a>,
+Up: <a rel="up" accesskey="u" href="Interpolation.html#Interpolation">Interpolation</a>
+<hr>
+</div>
+
+<h3 class="section">28.2 Multi-dimensional Interpolation</h3>
+
+<p>There are three multi-dimensional interpolation functions in Octave, with
+similar capabilities.  Methods using Delaunay tessellation are described
+in <a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a>.
+
+<!-- ./general/interp2.m -->
+   <p><a name="doc_002dinterp2"></a>
+
+<div class="defun">
+— Function File: <var>zi</var> = <b>interp2</b> (<var>x, y, z, xi, yi</var>)<var><a name="index-interp2-2066"></a></var><br>
+— Function File: <var>zi</var> = <b>interp2</b> (<var>Z, xi, yi</var>)<var><a name="index-interp2-2067"></a></var><br>
+— Function File: <var>zi</var> = <b>interp2</b> (<var>Z, n</var>)<var><a name="index-interp2-2068"></a></var><br>
+— Function File: <var>zi</var> = <b>interp2</b> (<var><small class="dots">...</small>, method</var>)<var><a name="index-interp2-2069"></a></var><br>
+— Function File: <var>zi</var> = <b>interp2</b> (<var><small class="dots">...</small>, method, extrapval</var>)<var><a name="index-interp2-2070"></a></var><br>
+<blockquote>
+        <p>Two-dimensional interpolation.  <var>x</var>, <var>y</var> and <var>z</var> describe a
+surface function.  If <var>x</var> and <var>y</var> are vectors their length
+must correspondent to the size of <var>z</var>.  <var>x</var> and <var>y</var> must be
+monotonic.  If they are matrices they must have the <code>meshgrid</code>
+format.
+
+          <dl>
+<dt><code>interp2 (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>Z</var><code>, </code><var>xi</var><code>, </code><var>yi</var><code>, ...)</code><dd>Returns a matrix corresponding to the points described by the
+matrices <var>xi</var>, <var>yi</var>.
+
+          <p>If the last argument is a string, the interpolation method can
+be specified.  The method can be 'linear', 'nearest' or 'cubic'. 
+If it is omitted 'linear' interpolation is assumed.
+
+          <br><dt><code>interp2 (</code><var>z</var><code>, </code><var>xi</var><code>, </code><var>yi</var><code>)</code><dd>Assumes <var>x</var><code> = 1:rows (</code><var>z</var><code>)</code> and <var>y</var><code> =
+1:columns (</code><var>z</var><code>)</code>
+
+          <br><dt><code>interp2 (</code><var>z</var><code>, </code><var>n</var><code>)</code><dd>Interleaves the matrix <var>z</var> n-times.  If <var>n</var> is omitted a value
+of <var>n</var><code> = 1</code> is assumed. 
+</dl>
+
+        <p>The variable <var>method</var> defines the method to use for the
+interpolation.  It can take one of the following values
+
+          <dl>
+<dt>'nearest'<dd>Return the nearest neighbor. 
+<br><dt>'linear'<dd>Linear interpolation from nearest neighbors. 
+<br><dt>'pchip'<dd>Piece-wise cubic hermite interpolating polynomial (not implemented yet). 
+<br><dt>'cubic'<dd>Cubic interpolation from four nearest neighbors. 
+<br><dt>'spline'<dd>Cubic spline interpolation–smooth first and second derivatives
+throughout the curve. 
+</dl>
+
+        <p>If a scalar value <var>extrapval</var> is defined as the final value, then
+values outside the mesh as set to this value.  Note that in this case
+<var>method</var> must be defined as well.  If <var>extrapval</var> is not
+defined then NA is assumed.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp1.html#doc_002dinterp1">interp1</a>. 
+</p></blockquote></div>
+
+<!-- ./general/interp3.m -->
+   <p><a name="doc_002dinterp3"></a>
+
+<div class="defun">
+— Function File: <var>vi</var> = <b>interp3</b> (<var>x, y,z, v, xi, yi, zi</var>)<var><a name="index-interp3-2071"></a></var><br>
+— Function File: <var>vi</var> = <b>interp3</b> (<var>v, xi, yi, zi</var>)<var><a name="index-interp3-2072"></a></var><br>
+— Function File: <var>vi</var> = <b>interp3</b> (<var>v, m</var>)<var><a name="index-interp3-2073"></a></var><br>
+— Function File: <var>vi</var> = <b>interp3</b> (<var>v</var>)<var><a name="index-interp3-2074"></a></var><br>
+— Function File: <var>vi</var> = <b>interp3</b> (<var><small class="dots">...</small>, method</var>)<var><a name="index-interp3-2075"></a></var><br>
+— Function File: <var>vi</var> = <b>interp3</b> (<var><small class="dots">...</small>, method, extrapval</var>)<var><a name="index-interp3-2076"></a></var><br>
+<blockquote>
+        <p>Perform 3-dimensional interpolation.  Each element of the 3-dimensional
+array <var>v</var> represents a value at a location given by the parameters
+<var>x</var>, <var>y</var>, and <var>z</var>.  The parameters <var>x</var>, <var>x</var>, and
+<var>z</var> are either 3-dimensional arrays of the same size as the array
+<var>v</var> in the 'meshgrid' format or vectors.  The parameters <var>xi</var>, etc. 
+respect a similar format to <var>x</var>, etc., and they represent the points
+at which the array <var>vi</var> is interpolated.
+
+        <p>If <var>x</var>, <var>y</var>, <var>z</var> are omitted, they are assumed to be
+<code>x = 1 : size (</code><var>v</var><code>, 2)</code>, <code>y = 1 : size (</code><var>v</var><code>, 1)</code> and
+<code>z = 1 : size (</code><var>v</var><code>, 3)</code>.  If <var>m</var> is specified, then
+the interpolation adds a point half way between each of the interpolation
+points.  This process is performed <var>m</var> times.  If only <var>v</var> is
+specified, then <var>m</var> is assumed to be <code>1</code>.
+
+        <p>Method is one of:
+
+          <dl>
+<dt>'nearest'<dd>Return the nearest neighbor. 
+<br><dt>'linear'<dd>Linear interpolation from nearest neighbors. 
+<br><dt>'cubic'<dd>Cubic interpolation from four nearest neighbors (not implemented yet). 
+<br><dt>'spline'<dd>Cubic spline interpolation–smooth first and second derivatives
+throughout the curve. 
+</dl>
+
+        <p>The default method is 'linear'.
+
+        <p>If <var>extrap</var> is the string 'extrap', then extrapolate values beyond
+the endpoints.  If <var>extrap</var> is a number, replace values beyond the
+endpoints with that number.  If <var>extrap</var> is missing, assume NA. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp1.html#doc_002dinterp1">interp1</a>, <a href="doc_002dinterp2.html#doc_002dinterp2">interp2</a>, <a href="doc_002dspline.html#doc_002dspline">spline</a>, <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>. 
+</p></blockquote></div>
+
+<!-- ./general/interpn.m -->
+   <p><a name="doc_002dinterpn"></a>
+
+<div class="defun">
+— Function File: <var>vi</var> = <b>interpn</b> (<var>x1, x2, <small class="dots">...</small>, v, y1, y2, <small class="dots">...</small></var>)<var><a name="index-interpn-2077"></a></var><br>
+— Function File: <var>vi</var> = <b>interpn</b> (<var>v, y1, y2, <small class="dots">...</small></var>)<var><a name="index-interpn-2078"></a></var><br>
+— Function File: <var>vi</var> = <b>interpn</b> (<var>v, m</var>)<var><a name="index-interpn-2079"></a></var><br>
+— Function File: <var>vi</var> = <b>interpn</b> (<var>v</var>)<var><a name="index-interpn-2080"></a></var><br>
+— Function File: <var>vi</var> = <b>interpn</b> (<var><small class="dots">...</small>, method</var>)<var><a name="index-interpn-2081"></a></var><br>
+— Function File: <var>vi</var> = <b>interpn</b> (<var><small class="dots">...</small>, method, extrapval</var>)<var><a name="index-interpn-2082"></a></var><br>
+<blockquote>
+        <p>Perform <var>n</var>-dimensional interpolation, where <var>n</var> is at least two. 
+Each element of the <var>n</var>-dimensional array <var>v</var> represents a value
+at a location given by the parameters <var>x1</var>, <var>x2</var>, <small class="dots">...</small>, <var>xn</var>. 
+The parameters <var>x1</var>, <var>x2</var>, <small class="dots">...</small>, <var>xn</var> are either
+<var>n</var>-dimensional arrays of the same size as the array <var>v</var> in
+the 'ndgrid' format or vectors.  The parameters <var>y1</var>, etc. respect a
+similar format to <var>x1</var>, etc., and they represent the points at which
+the array <var>vi</var> is interpolated.
+
+        <p>If <var>x1</var>, <small class="dots">...</small>, <var>xn</var> are omitted, they are assumed to be
+<code>x1 = 1 : size (</code><var>v</var><code>, 1)</code>, etc.  If <var>m</var> is specified, then
+the interpolation adds a point half way between each of the interpolation
+points.  This process is performed <var>m</var> times.  If only <var>v</var> is
+specified, then <var>m</var> is assumed to be <code>1</code>.
+
+        <p>Method is one of:
+
+          <dl>
+<dt>'nearest'<dd>Return the nearest neighbor. 
+<br><dt>'linear'<dd>Linear interpolation from nearest neighbors. 
+<br><dt>'cubic'<dd>Cubic interpolation from four nearest neighbors (not implemented yet). 
+<br><dt>'spline'<dd>Cubic spline interpolation–smooth first and second derivatives
+throughout the curve. 
+</dl>
+
+        <p>The default method is 'linear'.
+
+        <p>If <var>extrapval</var> is the scalar value, use it to replace the values
+beyond the endpoints with that number.  If <var>extrapval</var> is missing,
+assume NA. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp1.html#doc_002dinterp1">interp1</a>, <a href="doc_002dinterp2.html#doc_002dinterp2">interp2</a>, <a href="doc_002dspline.html#doc_002dspline">spline</a>, <a href="doc_002dndgrid.html#doc_002dndgrid">ndgrid</a>. 
+</p></blockquote></div>
+
+   <p>A significant difference between <code>interpn</code> and the other two
+multidimensional interpolation functions is the fashion in which the
+dimensions are treated.  For <code>interp2</code> and <code>interp3</code>, the 'y'
+axis is considered to be the columns of the matrix, whereas the 'x'
+axis corresponds to the rows of the array.  As Octave indexes arrays in
+column major order, the first dimension of any array is the columns, and
+so <code>interpn</code> effectively reverses the 'x' and 'y' dimensions. 
+Consider the example
+
+<pre class="example">     x = y = z = -1:1;
+     f = @(x,y,z) x.^2 - y - z.^2;
+     [xx, yy, zz] = meshgrid (x, y, z);
+     v = f (xx,yy,zz);
+     xi = yi = zi = -1:0.1:1;
+     [xxi, yyi, zzi] = meshgrid (xi, yi, zi);
+     vi = interp3(x, y, z, v, xxi, yyi, zzi, 'spline');
+     [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+     vi2 = interpn(x, y, z, v, xxi, yyi, zzi, 'spline');
+     mesh (zi, yi, squeeze (vi2(1,:,:)));
+</pre>
+   <p class="noindent">where <code>vi</code> and <code>vi2</code> are identical.  The reversal of the
+dimensions is treated in the <code>meshgrid</code> and <code>ndgrid</code> functions
+respectively.
+
+   <p>In additional the support function <code>bicubic</code> that underlies the
+cubic interpolation of <code>interp2</code> function can be called directly.
+
+<!-- ./general/bicubic.m -->
+   <p><a name="doc_002dbicubic"></a>
+
+<div class="defun">
+— Function File: <var>zi</var> = <b>bicubic</b> (<var>x, y, z, xi, yi, extrapval</var>)<var><a name="index-bicubic-2083"></a></var><br>
+<blockquote>
+        <p>Return a matrix <var>zi</var> corresponding to the bicubic
+interpolations at <var>xi</var> and <var>yi</var> of the data supplied
+as <var>x</var>, <var>y</var> and <var>z</var>.  Points outside the grid are set
+to <var>extrapval</var>.
+
+        <p>See <a href="http://wiki.woodpecker.org.cn/moin/Octave/Bicubic">http://wiki.woodpecker.org.cn/moin/Octave/Bicubic</a>
+for further information. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp2.html#doc_002dinterp2">interp2</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Multiple-Plot-Windows.html b/doc/interpreter/HTML/Multiple-Plot-Windows.html
new file mode 100644
index 0000000..9e369c8
--- /dev/null
+++ b/doc/interpreter/HTML/Multiple-Plot-Windows.html
@@ -0,0 +1,62 @@
+<html lang="en">
+<head>
+<title>Multiple Plot Windows - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page" title="Multiple Plots on One Page">
+<link rel="next" href="Printing-Plots.html#Printing-Plots" title="Printing Plots">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Multiple-Plot-Windows"></a>
+Next: <a rel="next" accesskey="n" href="Printing-Plots.html#Printing-Plots">Printing Plots</a>,
+Previous: <a rel="previous" accesskey="p" href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page">Multiple Plots on One Page</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.5 Multiple Plot Windows</h4>
+
+<p>You can open multiple plot windows using the <code>figure</code> function. 
+For example
+
+<pre class="example">     figure (1);
+     fplot (@sin, [-10, 10]);
+     figure (2);
+     fplot (@cos, [-10, 10]);
+</pre>
+   <p class="noindent">creates two figures, with the first displaying a sine wave and
+the second a cosine wave.  Figure numbers must be positive integers.
+
+<!-- ./plot/figure.m -->
+   <p><a name="doc_002dfigure"></a>
+
+<div class="defun">
+— Function File:  <b>figure</b> (<var>n</var>)<var><a name="index-figure-1092"></a></var><br>
+— Function File:  <b>figure</b> (<var>n, property, value, <small class="dots">...</small></var>)<var><a name="index-figure-1093"></a></var><br>
+<blockquote><p>Set the current plot window to plot window <var>n</var>.  If no arguments are
+specified, the next available window number is chosen.
+
+        <p>Multiple property-value pairs may be specified for the figure, but they
+must appear in pairs. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Multiple-Plots-on-One-Page.html b/doc/interpreter/HTML/Multiple-Plots-on-One-Page.html
new file mode 100644
index 0000000..6d2edaa
--- /dev/null
+++ b/doc/interpreter/HTML/Multiple-Plots-on-One-Page.html
@@ -0,0 +1,87 @@
+<html lang="en">
+<head>
+<title>Multiple Plots on One Page - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Plot-Annotations.html#Plot-Annotations" title="Plot Annotations">
+<link rel="next" href="Multiple-Plot-Windows.html#Multiple-Plot-Windows" title="Multiple Plot Windows">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Multiple-Plots-on-One-Page"></a>
+Next: <a rel="next" accesskey="n" href="Multiple-Plot-Windows.html#Multiple-Plot-Windows">Multiple Plot Windows</a>,
+Previous: <a rel="previous" accesskey="p" href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.4 Multiple Plots on One Page</h4>
+
+<p>Octave can display more than one plot in a single figure.  The simplest
+way to do this is to use the <code>subplot</code> function to divide the plot
+area into a series of subplot windows that are indexed by an integer. 
+For example,
+
+<pre class="example">     subplot (2, 1, 1)
+     fplot (@sin, [-10, 10]);
+     subplot (2, 1, 2)
+     fplot (@cos, [-10, 10]);
+</pre>
+   <p class="noindent">creates a figure with two separate axes, one displaying a sine wave and
+the other a cosine wave.  The first call to subplot divides the figure
+into two plotting areas (two rows and one column) and makes the first plot
+area active.  The grid of plot areas created by <code>subplot</code> is
+numbered in column-major order (top to bottom, left to right).
+
+<!-- ./plot/subplot.m -->
+   <p><a name="doc_002dsubplot"></a>
+
+<div class="defun">
+— Function File:  <b>subplot</b> (<var>rows, cols, index</var>)<var><a name="index-subplot-1090"></a></var><br>
+— Function File:  <b>subplot</b> (<var>rcn</var>)<var><a name="index-subplot-1091"></a></var><br>
+<blockquote><p>Set up a plot grid with <var>cols</var> by <var>rows</var> subwindows and plot
+in location given by <var>index</var>.
+
+        <p>If only one argument is supplied, then it must be a three digit value
+specifying the location in digits 1 (rows) and 2 (columns) and the plot
+index in digit 3.
+
+        <p>The plot index runs row-wise.  First all the columns in a row are filled
+and then the next row is filled.
+
+        <p>For example, a plot with 2 by 3 grid will have plot indices running as
+follows:
+     <pre class="display">
+          <pre class="example">               
+               +-----+-----+-----+
+               |  1  |  2  |  3  |
+               +-----+-----+-----+
+               |  4  |  5  |  6  |
+               +-----+-----+-----+
+</pre>
+        </pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Multiple-Return-Values.html b/doc/interpreter/HTML/Multiple-Return-Values.html
new file mode 100644
index 0000000..8f0e240
--- /dev/null
+++ b/doc/interpreter/HTML/Multiple-Return-Values.html
@@ -0,0 +1,177 @@
+<html lang="en">
+<head>
+<title>Multiple Return Values - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Defining-Functions.html#Defining-Functions" title="Defining Functions">
+<link rel="next" href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists" title="Variable-length Argument Lists">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Multiple-Return-Values"></a>
+Next: <a rel="next" accesskey="n" href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a>,
+Previous: <a rel="previous" accesskey="p" href="Defining-Functions.html#Defining-Functions">Defining Functions</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.2 Multiple Return Values</h3>
+
+<p>Unlike many other computer languages, Octave allows you to define
+functions that return more than one value.  The syntax for defining
+functions that return multiple values is
+
+<pre class="example">     function [<var>ret-list</var>] = <var>name</var> (<var>arg-list</var>)
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">where <var>name</var>, <var>arg-list</var>, and <var>body</var> have the same meaning
+as before, and <var>ret-list</var> is a comma-separated list of variable
+names that will hold the values returned from the function.  The list of
+return values must have at least one element.  If <var>ret-list</var> has
+only one element, this form of the <code>function</code> statement is
+equivalent to the form described in the previous section.
+
+   <p>Here is an example of a function that returns two values, the maximum
+element of a vector and the index of its first occurrence in the vector.
+
+<pre class="example">     function [max, idx] = vmax (v)
+       idx = 1;
+       max = v (idx);
+       for i = 2:length (v)
+         if (v (i) > max)
+           max = v (i);
+           idx = i;
+         endif
+       endfor
+     endfunction
+</pre>
+   <p>In this particular case, the two values could have been returned as
+elements of a single array, but that is not always possible or
+convenient.  The values to be returned may not have compatible
+dimensions, and it is often desirable to give the individual return
+values distinct names.
+
+   <p>In addition to setting <code>nargin</code> each time a function is called,
+Octave also automatically initializes <code>nargout</code> to the number of
+values that are expected to be returned.  This allows you to write
+functions that behave differently depending on the number of values that
+the user of the function has requested.  The implicit assignment to the
+built-in variable <code>ans</code> does not figure in the count of output
+arguments, so the value of <code>nargout</code> may be zero.
+
+   <p>The <code>svd</code> and <code>lu</code> functions are examples of built-in
+functions that behave differently depending on the value of
+<code>nargout</code>.
+
+   <p>It is possible to write functions that only set some return values.  For
+example, calling the function
+
+<pre class="example">     function [x, y, z] = f ()
+       x = 1;
+       z = 2;
+     endfunction
+</pre>
+   <p class="noindent">as
+
+<pre class="example">     [a, b, c] = f ()
+</pre>
+   <p class="noindent">produces:
+
+<pre class="example">     a = 1
+     
+     b = [](0x0)
+     
+     c = 2
+</pre>
+   <p class="noindent">along with a warning.
+
+<!-- ov-usr-fcn.cc -->
+   <p><a name="doc_002dnargout"></a>
+
+<div class="defun">
+— Built-in Function:  <b>nargout</b> ()<var><a name="index-nargout-595"></a></var><br>
+— Built-in Function:  <b>nargout</b> (<var>fcn_name</var>)<var><a name="index-nargout-596"></a></var><br>
+<blockquote><p>Within a function, return the number of values the caller expects to
+receive.  If called with the optional argument <var>fcn_name</var>, return the
+maximum number of values the named function can produce, or -1 if the
+function can produce a variable number of values.
+
+        <p>For example,
+
+     <pre class="example">          f ()
+</pre>
+        <p class="noindent">will cause <code>nargout</code> to return 0 inside the function <code>f</code> and
+
+     <pre class="example">          [s, t] = f ()
+</pre>
+        <p class="noindent">will cause <code>nargout</code> to return 2 inside the function
+<code>f</code>.
+
+        <p>At the top level, <code>nargout</code> is undefined. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnargin.html#doc_002dnargin">nargin</a>, <a href="doc_002dvarargin.html#doc_002dvarargin">varargin</a>, <a href="doc_002dvarargout.html#doc_002dvarargout">varargout</a>. 
+</p></blockquote></div>
+
+<!-- ./general/nargchk.m -->
+   <p><a name="doc_002dnargchk"></a>
+
+<div class="defun">
+— Function File: <var>msgstr</var> = <b>nargchk</b> (<var>minargs, maxargs, nargs</var>)<var><a name="index-nargchk-597"></a></var><br>
+— Function File: <var>msgstr</var> = <b>nargchk</b> (<var>minargs, maxargs, nargs, "string"</var>)<var><a name="index-nargchk-598"></a></var><br>
+— Function File: <var>msgstruct</var> = <b>nargchk</b> (<var>minargs, maxargs, nargs, "struct"</var>)<var><a name="index-nargchk-599"></a></var><br>
+<blockquote><p>Return an appropriate error message string (or structure) if the
+number of inputs requested is invalid.
+
+        <p>This is useful for checking to see that the number of input arguments
+supplied to a function is within an acceptable range. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnargoutchk.html#doc_002dnargoutchk">nargoutchk</a>, <a href="doc_002derror.html#doc_002derror">error</a>, <a href="doc_002dnargin.html#doc_002dnargin">nargin</a>, <a href="doc_002dnargout.html#doc_002dnargout">nargout</a>. 
+</p></blockquote></div>
+
+<!-- ./general/nargoutchk.m -->
+   <p><a name="doc_002dnargoutchk"></a>
+
+<div class="defun">
+— Function File: <var>msgstr</var> = <b>nargoutchk</b> (<var>minargs, maxargs, nargs</var>)<var><a name="index-nargoutchk-600"></a></var><br>
+— Function File: <var>msgstr</var> = <b>nargoutchk</b> (<var>minargs, maxargs, nargs, "string"</var>)<var><a name="index-nargoutchk-601"></a></var><br>
+— Function File: <var>msgstruct</var> = <b>nargoutchk</b> (<var>minargs, maxargs, nargs, "struct"</var>)<var><a name="index-nargoutchk-602"></a></var><br>
+<blockquote><p>Return an appropriate error message string (or structure) if the
+number of outputs requested is invalid.
+
+        <p>This is useful for checking to see that the number of output
+arguments supplied to a function is within an acceptable range. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnargchk.html#doc_002dnargchk">nargchk</a>, <a href="doc_002derror.html#doc_002derror">error</a>, <a href="doc_002dnargout.html#doc_002dnargout">nargout</a>, <a href="doc_002dnargin.html#doc_002dnargin">nargin</a>. 
+</p></blockquote></div>
+
+   <p><a name="doc_002dvarargin"></a><a name="doc_002dvarargout"></a>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Networking-Utilities.html b/doc/interpreter/HTML/Networking-Utilities.html
new file mode 100644
index 0000000..73935d9
--- /dev/null
+++ b/doc/interpreter/HTML/Networking-Utilities.html
@@ -0,0 +1,117 @@
+<html lang="en">
+<head>
+<title>Networking Utilities - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="File-Archiving-Utilities.html#File-Archiving-Utilities" title="File Archiving Utilities">
+<link rel="next" href="Controlling-Subprocesses.html#Controlling-Subprocesses" title="Controlling Subprocesses">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Networking-Utilities"></a>
+Next: <a rel="next" accesskey="n" href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a>,
+Previous: <a rel="previous" accesskey="p" href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.4 Networking Utilities</h3>
+
+<!-- ./DLD-FUNCTIONS/urlwrite.cc -->
+<p><a name="doc_002durlread"></a>
+
+<div class="defun">
+— Loadable Function: <var>s</var> = <b>urlread</b> (<var>url</var>)<var><a name="index-urlread-2363"></a></var><br>
+— Loadable Function: [<var>s</var>, <var>success</var>] = <b>urlread</b> (<var>url</var>)<var><a name="index-urlread-2364"></a></var><br>
+— Loadable Function: [<var>s</var>, <var>success</var>, <var>message</var>] = <b>urlread</b> (<var>url</var>)<var><a name="index-urlread-2365"></a></var><br>
+— Loadable Function: [<small class="dots">...</small>] = <b>urlread</b> (<var>url, method, param</var>)<var><a name="index-urlread-2366"></a></var><br>
+<blockquote><p>Download a remote file specified by its <var>URL</var> and return its content
+in string <var>s</var>.  For example,
+
+     <pre class="example">          s = urlread ("ftp://ftp.octave.org/pub/octave/README");
+</pre>
+        <p>The variable <var>success</var> is 1 if the download was successful,
+otherwise it is 0 in which case <var>message</var> contains an error
+message.  If no output argument is specified and if an error occurs,
+then the error is signaled through Octave's error handling mechanism.
+
+        <p>This function uses libcurl.  Curl supports, among others, the HTTP,
+FTP and FILE protocols.  Username and password may be specified in the
+URL.  For example,
+
+     <pre class="example">          s = urlread ("http://user:password@example.com/file.txt");
+</pre>
+        <p>GET and POST requests can be specified by <var>method</var> and <var>param</var>. 
+The parameter <var>method</var> is either ‘<samp><span class="samp">get</span></samp>’ or ‘<samp><span class="samp">post</span></samp>’
+and <var>param</var> is a cell array of parameter and value pairs. 
+For example,
+
+     <pre class="example">          s = urlread ("http://www.google.com/search", "get",
+                       {"query", "octave"});
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002durlwrite.html#doc_002durlwrite">urlwrite</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/urlwrite.cc -->
+   <p><a name="doc_002durlwrite"></a>
+
+<div class="defun">
+— Loadable Function:  <b>urlwrite</b> (<var>URL, localfile</var>)<var><a name="index-urlwrite-2367"></a></var><br>
+— Loadable Function: <var>f</var> = <b>urlwrite</b> (<var>url, localfile</var>)<var><a name="index-urlwrite-2368"></a></var><br>
+— Loadable Function: [<var>f</var>, <var>success</var>] = <b>urlwrite</b> (<var>url, localfile</var>)<var><a name="index-urlwrite-2369"></a></var><br>
+— Loadable Function: [<var>f</var>, <var>success</var>, <var>message</var>] = <b>urlwrite</b> (<var>url, localfile</var>)<var><a name="index-urlwrite-2370"></a></var><br>
+<blockquote><p>Download a remote file specified by its <var>URL</var> and save it as
+<var>localfile</var>.  For example,
+
+     <pre class="example">          urlwrite ("ftp://ftp.octave.org/pub/octave/README",
+                    "README.txt");
+</pre>
+        <p>The full path of the downloaded file is returned in <var>f</var>.  The
+variable <var>success</var> is 1 if the download was successful,
+otherwise it is 0 in which case <var>message</var> contains an error
+message.  If no output argument is specified and if an error occurs,
+then the error is signaled through Octave's error handling mechanism.
+
+        <p>This function uses libcurl.  Curl supports, among others, the HTTP,
+FTP and FILE protocols.  Username and password may be specified in
+the URL, for example:
+
+     <pre class="example">          urlwrite ("http://username:password@example.com/file.txt",
+                    "file.txt");
+</pre>
+        <p>GET and POST requests can be specified by <var>method</var> and <var>param</var>. 
+The parameter <var>method</var> is either ‘<samp><span class="samp">get</span></samp>’ or ‘<samp><span class="samp">post</span></samp>’
+and <var>param</var> is a cell array of parameter and value pairs. 
+For example:
+
+     <pre class="example">          urlwrite ("http://www.google.com/search", "search.html",
+                    "get", {"query", "octave"});
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002durlread.html#doc_002durlread">urlread</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Nonlinear-Equations.html b/doc/interpreter/HTML/Nonlinear-Equations.html
new file mode 100644
index 0000000..6e5b193
--- /dev/null
+++ b/doc/interpreter/HTML/Nonlinear-Equations.html
@@ -0,0 +1,255 @@
+<html lang="en">
+<head>
+<title>Nonlinear Equations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link rel="next" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Nonlinear-Equations"></a>
+Next: <a rel="next" accesskey="n" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>,
+Previous: <a rel="previous" accesskey="p" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">19 Nonlinear Equations</h2>
+
+<p><a name="index-nonlinear-equations-1631"></a><a name="index-equations_002c-nonlinear-1632"></a>
+Octave can solve sets of nonlinear equations of the form
+
+<pre class="example">     F (x) = 0
+</pre>
+   <p class="noindent">using the function <code>fsolve</code>, which is based on the <span class="sc">Minpack</span>
+subroutine <code>hybrd</code>.  This is an iterative technique so a starting
+point will have to be provided.  This also has the consequence that
+convergence is not guaranteed even if a solution exists.
+
+<!-- ./optimization/fsolve.m -->
+   <p><a name="doc_002dfsolve"></a>
+
+<div class="defun">
+— Function File:  <b>fsolve</b> (<var>fcn, x0, options</var>)<var><a name="index-fsolve-1633"></a></var><br>
+— Function File: [<var>x</var>, <var>fvec</var>, <var>info</var>, <var>output</var>, <var>fjac</var>] <b>=</b><var> fsolve </var>(<var>fcn, <small class="dots">...</small></var>)<var><a name="index-g_t_003d-1634"></a></var><br>
+<blockquote><p>Solve a system of nonlinear equations defined by the function <var>fcn</var>. 
+<var>fcn</var> should accepts a vector (array) defining the unknown variables,
+and return a vector of left-hand sides of the equations.  Right-hand sides
+are defined to be zeros. 
+In other words, this function attempts to determine a vector <var>x</var> such
+that <var>fcn</var><code> (</code><var>x</var><code>)</code> gives (approximately) all zeros. 
+<var>x0</var> determines a starting guess.  The shape of <var>x0</var> is preserved
+in all calls to <var>fcn</var>, but otherwise it is treated as a column vector. 
+<var>options</var> is a structure specifying additional options. 
+Currently, <code>fsolve</code> recognizes these options:
+<code>"FunValCheck"</code>, <code>"OutputFcn"</code>, <code>"TolX"</code>,
+<code>"TolFun"</code>, <code>"MaxIter"</code>, <code>"MaxFunEvals"</code>,
+<code>"Jacobian"</code>, <code>"Updating"</code> and <code>"ComplexEqn"</code>.
+
+        <p>If <code>"Jacobian"</code> is <code>"on"</code>, it specifies that <var>fcn</var>,
+called with 2 output arguments, also returns the Jacobian matrix
+of right-hand sides at the requested point.  <code>"TolX"</code> specifies
+the termination tolerance in the unknown variables, while
+<code>"TolFun"</code> is a tolerance for equations.  Default is <code>1e-7</code>
+for both <code>"TolX"</code> and <code>"TolFun"</code>. 
+If <code>"Updating"</code> is "on", the function will attempt to use Broyden
+updates to update the Jacobian, in order to reduce the amount of jacobian
+calculations. 
+If your user function always calculates the Jacobian (regardless of number
+of output arguments), this option provides no advantage and should be set to
+false.
+
+        <p><code>"ComplexEqn"</code> is <code>"on"</code>, <code>fsolve</code> will attempt to solve
+complex equations in complex variables, assuming that the equations possess a
+complex derivative (i.e., are holomorphic).  If this is not what you want,
+should unpack the real and imaginary parts of the system to get a real
+system.
+
+        <p>For description of the other options, see <code>optimset</code>.
+
+        <p>On return, <var>fval</var> contains the value of the function <var>fcn</var>
+evaluated at <var>x</var>, and <var>info</var> may be one of the following values:
+
+          <dl>
+<dt>1<dd>Converged to a solution point.  Relative residual error is less than specified
+by TolFun. 
+<br><dt>2<dd>Last relative step size was less that TolX. 
+<br><dt>3<dd>Last relative decrease in residual was less than TolF. 
+<br><dt>0<dd>Iteration limit exceeded. 
+<br><dt>-3<dd>The trust region radius became excessively small. 
+</dl>
+
+        <p>Note: If you only have a single nonlinear equation of one variable, using
+<code>fzero</code> is usually a much better idea. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfzero.html#doc_002dfzero">fzero</a>, <a href="doc_002doptimset.html#doc_002doptimset">optimset</a>.
+
+        <p>Note about user-supplied jacobians:
+As an inherent property of the algorithm, jacobian is always requested for a
+solution vector whose residual vector is already known, and it is the last
+accepted successful step.  Often this will be one of the last two calls, but
+not always.  If the savings by reusing intermediate results from residual
+calculation in jacobian calculation are significant, the best strategy is to
+employ OutputFcn: After a vector is evaluated for residuals, if OutputFcn is
+called with that vector, then the intermediate results should be saved for
+future jacobian evaluation, and should be kept until a jacobian evaluation
+is requested or until outputfcn is called with a different vector, in which
+case they should be dropped in favor of this most recent vector.  A short
+example how this can be achieved follows:
+
+     <pre class="example">          function [fvec, fjac] = user_func (x, optimvalues, state)
+          persistent sav = [], sav0 = [];
+          if (nargin == 1)
+            ## evaluation call
+            if (nargout == 1)
+              sav0.x = x; # mark saved vector
+              ## calculate fvec, save results to sav0.
+            elseif (nargout == 2)
+              ## calculate fjac using sav.
+            endif
+          else
+            ## outputfcn call.
+            if (all (x == sav0.x))
+              sav = sav0;
+            endif
+            ## maybe output iteration status, etc.
+          endif
+          endfunction
+          
+           ....
+          
+          fsolve (@user_func, x0, optimset ("OutputFcn", @user_func, ...))
+</pre>
+        </blockquote></div>
+
+   <p>Here is a complete example.  To solve the set of equations
+
+<pre class="example">     -2x^2 + 3xy   + 4 sin(y) = 6
+      3x^2 - 2xy^2 + 3 cos(x) = -4
+</pre>
+   <p class="noindent">you first need to write a function to compute the value of the given
+function.  For example:
+
+<pre class="example">     function y = f (x)
+       y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
+       y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
+     endfunction
+</pre>
+   <p>Then, call <code>fsolve</code> with a specified initial condition to find the
+roots of the system of equations.  For example, given the function
+<code>f</code> defined above,
+
+<pre class="example">     [x, fval, info] = fsolve (@f, [1; 2])
+</pre>
+   <p class="noindent">results in the solution
+
+<pre class="example">     x =
+     
+       0.57983
+       2.54621
+     
+     fval =
+     
+       -5.7184e-10
+        5.5460e-10
+     
+     info = 1
+</pre>
+   <p class="noindent">A value of <code>info = 1</code> indicates that the solution has converged.
+
+   <p>The function <code>perror</code> may be used to print English messages
+corresponding to the numeric error codes.  For example,
+
+<pre class="example">     perror ("fsolve", 1)
+          -| solution converged to requested tolerance
+</pre>
+   <p>When no Jacobian is supplied (as in the example above) it is approximated
+numerically.  This requires more function evaluations, and hence is
+less efficient.  In the example above we could compute the Jacobian
+analytically as
+
+<pre class="example">     function J = jacobian(x)
+       J(1,1) =  3*x(2) - 4*x(1);
+       J(1,2) =  4*cos(x(2)) + 3*x(1);
+       J(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
+       J(2,2) = -4*x(1)*x(2);
+     endfunction
+</pre>
+   <p class="noindent">The Jacobian can then be used with the following call to <code>fsolve</code>:
+
+<pre class="example">     [x, fval, info] = fsolve ({@f, @jacobian}, [1; 2]);
+</pre>
+   <p class="noindent">which gives the same solution as before.
+
+<!-- ./optimization/fzero.m -->
+   <p><a name="doc_002dfzero"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>fval</var>, <var>info</var>, <var>output</var>] = <b>fzero</b> (<var>fun, x0, options</var>)<var><a name="index-fzero-1635"></a></var><br>
+<blockquote><p>Find a zero point of a univariate function.  <var>fun</var> should be a function
+handle or name.  <var>x0</var> specifies a starting point.  <var>options</var> is a
+structure specifying additional options.  Currently, <code>fzero</code>
+recognizes these options: <code>"FunValCheck"</code>, <code>"OutputFcn"</code>,
+<code>"TolX"</code>, <code>"MaxIter"</code>, <code>"MaxFunEvals"</code>. 
+For description of these options, see <a href="doc_002doptimset.html#doc_002doptimset">optimset</a>.
+
+        <p>On exit, the function returns <var>x</var>, the approximate zero point
+and <var>fval</var>, the function value thereof. 
+<var>info</var> is an exit flag that can have these values:
+          <ul>
+<li>1
+The algorithm converged to a solution. 
+<li>0
+Maximum number of iterations or function evaluations has been exhausted. 
+<li>-1
+The algorithm has been terminated from user output function. 
+<li>-2
+A general unexpected error. 
+<li>-3
+A non-real value encountered. 
+<li>-4
+A NaN value encountered. 
+</ul>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002doptimset.html#doc_002doptimset">optimset</a>, <a href="doc_002dfsolve.html#doc_002dfsolve">fsolve</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2009 Jaroslav Hajek -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Nonlinear-Programming.html b/doc/interpreter/HTML/Nonlinear-Programming.html
new file mode 100644
index 0000000..bce64a7
--- /dev/null
+++ b/doc/interpreter/HTML/Nonlinear-Programming.html
@@ -0,0 +1,174 @@
+<html lang="en">
+<head>
+<title>Nonlinear Programming - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Quadratic-Programming.html#Quadratic-Programming" title="Quadratic Programming">
+<link rel="next" href="Linear-Least-Squares.html#Linear-Least-Squares" title="Linear Least Squares">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Nonlinear-Programming"></a>
+Next: <a rel="next" accesskey="n" href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a>,
+Previous: <a rel="previous" accesskey="p" href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">24.3 Nonlinear Programming</h3>
+
+<p>Octave can also perform general nonlinear minimization using a
+successive quadratic programming solver.
+
+<!-- ./optimization/sqp.m -->
+   <p><a name="doc_002dsqp"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>obj</var>, <var>info</var>, <var>iter</var>, <var>nf</var>, <var>lambda</var>] = <b>sqp</b> (<var>x, phi, g, h, lb, ub, maxiter, tolerance</var>)<var><a name="index-sqp-1803"></a></var><br>
+<blockquote><p>Solve the nonlinear program
+
+     <pre class="example">               min phi (x)
+                x
+</pre>
+        <p>subject to
+
+     <pre class="example">               g(x)  = 0
+               h(x) >= 0
+               lb <= x <= ub
+</pre>
+        <p class="noindent">using a successive quadratic programming method.
+
+        <p>The first argument is the initial guess for the vector <var>x</var>.
+
+        <p>The second argument is a function handle pointing to the objective
+function.  The objective function must be of the form
+
+     <pre class="example">               y = phi (x)
+</pre>
+        <p class="noindent">in which <var>x</var> is a vector and <var>y</var> is a scalar.
+
+        <p>The second argument may also be a 2- or 3-element cell array of
+function handles.  The first element should point to the objective
+function, the second should point to a function that computes the
+gradient of the objective function, and the third should point to a
+function to compute the hessian of the objective function.  If the
+gradient function is not supplied, the gradient is computed by finite
+differences.  If the hessian function is not supplied, a BFGS update
+formula is used to approximate the hessian.
+
+        <p>If supplied, the gradient function must be of the form
+
+     <pre class="example">          g = gradient (x)
+</pre>
+        <p class="noindent">in which <var>x</var> is a vector and <var>g</var> is a vector.
+
+        <p>If supplied, the hessian function must be of the form
+
+     <pre class="example">          h = hessian (x)
+</pre>
+        <p class="noindent">in which <var>x</var> is a vector and <var>h</var> is a matrix.
+
+        <p>The third and fourth arguments are function handles pointing to
+functions that compute the equality constraints and the inequality
+constraints, respectively.
+
+        <p>If your problem does not have equality (or inequality) constraints,
+you may pass an empty matrix for <var>cef</var> (or <var>cif</var>).
+
+        <p>If supplied, the equality and inequality constraint functions must be
+of the form
+
+     <pre class="example">          r = f (x)
+</pre>
+        <p class="noindent">in which <var>x</var> is a vector and <var>r</var> is a vector.
+
+        <p>The third and fourth arguments may also be 2-element cell arrays of
+function handles.  The first element should point to the constraint
+function and the second should point to a function that computes the
+gradient of the constraint function:
+
+     <pre class="example">                          [ d f(x)   d f(x)        d f(x) ]
+              transpose ( [ ------   -----   ...   ------ ] )
+                          [  dx_1     dx_2          dx_N  ]
+</pre>
+        <p>The fifth and sixth arguments are vectors containing lower and upper bounds
+on <var>x</var>.  These must be consistent with equality and inequality
+constraints <var>g</var> and <var>h</var>.  If the bounds are not specified, or are
+empty, they are set to -<var>realmax</var> and <var>realmax</var> by default.
+
+        <p>The seventh argument is max. number of iterations.  If not specified,
+the default value is 100.
+
+        <p>The eighth argument is tolerance for stopping criteria.  If not specified,
+the default value is <var>eps</var>.
+
+        <p>Here is an example of calling <code>sqp</code>:
+
+     <pre class="example">          function r = g (x)
+            r = [ sumsq(x)-10;
+                  x(2)*x(3)-5*x(4)*x(5);
+                  x(1)^3+x(2)^3+1 ];
+          endfunction
+          
+          function obj = phi (x)
+            obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+          endfunction
+          
+          x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+          
+          [x, obj, info, iter, nf, lambda] = sqp (x0, @phi, @g, [])
+          
+          x =
+          
+            -1.71714
+             1.59571
+             1.82725
+            -0.76364
+            -0.76364
+          
+          obj = 0.053950
+          info = 101
+          iter = 8
+          nf = 10
+          lambda =
+          
+            -0.0401627
+             0.0379578
+            -0.0052227
+</pre>
+        <p>The value returned in <var>info</var> may be one of the following:
+          <dl>
+<dt>101<dd>The algorithm terminated because the norm of the last step was less
+than <code>tol * norm (x))</code> (the value of tol is currently fixed at
+<code>sqrt (eps)</code>—edit <samp><span class="file">sqp.m</span></samp> to modify this value. 
+<br><dt>102<dd>The BFGS update failed. 
+<br><dt>103<dd>The maximum number of iterations was reached (the maximum number of
+allowed iterations is currently fixed at 100—edit <samp><span class="file">sqp.m</span></samp> to
+increase this value). 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dqp.html#doc_002dqp">qp</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Notes-for-the-C-programmer.html b/doc/interpreter/HTML/Notes-for-the-C-programmer.html
new file mode 100644
index 0000000..139e9e8
--- /dev/null
+++ b/doc/interpreter/HTML/Notes-for-the-C-programmer.html
@@ -0,0 +1,69 @@
+<html lang="en">
+<head>
+<title>Notes for the C programmer - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="The-_0040code_007bswitch_007d-Statement.html#The-_0040code_007bswitch_007d-Statement" title="The @code{switch} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Notes-for-the-C-programmer"></a>
+Up: <a rel="up" accesskey="u" href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a>
+<hr>
+</div>
+
+<h4 class="subsection">10.2.1 Notes for the C programmer</h4>
+
+<p>The <code>switch</code> statement is also available in the widely used C
+programming language.  There are, however, some differences
+between the statement in Octave and C
+
+     <ul>
+<li>Cases are exclusive, so they don't `fall through' as do the cases
+in the <code>switch</code> statement of the C language.
+
+     <li>The <var>command_list</var> elements are not optional.  Making the list
+optional would have meant requiring a separator between the label and
+the command list.  Otherwise, things like
+
+     <pre class="example">          switch (foo)
+            case (1) -2
+            ...
+</pre>
+     <p class="noindent">would produce surprising results, as would
+
+     <pre class="example">          switch (foo)
+            case (1)
+            case (2)
+              doit ();
+            ...
+</pre>
+     <p class="noindent">particularly for C programmers.  If <code>doit()</code> should be executed if
+<var>foo</var> is either <code>1</code> or <code>2</code>, the above code should be
+written with a cell array like this
+
+     <pre class="example">          switch (foo)
+            case { 1, 2 }
+              doit ();
+            ...
+</pre>
+     </ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Numeric-Data-Types.html b/doc/interpreter/HTML/Numeric-Data-Types.html
new file mode 100644
index 0000000..18624f7
--- /dev/null
+++ b/doc/interpreter/HTML/Numeric-Data-Types.html
@@ -0,0 +1,127 @@
+<html lang="en">
+<head>
+<title>Numeric Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Data-Types.html#Data-Types" title="Data Types">
+<link rel="next" href="Strings.html#Strings" title="Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Numeric-Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="Strings.html#Strings">Strings</a>,
+Previous: <a rel="previous" accesskey="p" href="Data-Types.html#Data-Types">Data Types</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">4 Numeric Data Types</h2>
+
+<p><a name="index-numeric-constant-211"></a><a name="index-numeric-value-212"></a>
+A <dfn>numeric constant</dfn> may be a scalar, a vector, or a matrix, and it
+may contain complex values.
+
+   <p>The simplest form of a numeric constant, a scalar, is a single number
+that can be an integer, a decimal fraction, a number in scientific
+(exponential) notation, or a complex number.  Note that by default numeric
+constants are represented within Octave in double-precision floating
+point format (complex constants are stored as pairs of double-precision
+floating point values).  It is however possible to represent real
+integers as described in <a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a>.  Here are some
+examples of real-valued numeric constants, which all have the same
+value:
+
+<pre class="example">     105
+     1.05e+2
+     1050e-1
+</pre>
+   <p>To specify complex constants, you can write an expression of the form
+
+<pre class="example">     3 + 4i
+     3.0 + 4.0i
+     0.3e1 + 40e-1i
+</pre>
+   <p class="noindent">all of which are equivalent.  The letter ‘<samp><span class="samp">i</span></samp>’ in the previous example
+stands for the pure imaginary constant, defined as
+  <code>sqrt (-1)</code>.
+
+   <p>For Octave to recognize a value as the imaginary part of a complex
+constant, a space must not appear between the number and the ‘<samp><span class="samp">i</span></samp>’. 
+If it does, Octave will print an error message, like this:
+
+<pre class="example">     octave:13> 3 + 4 i
+     
+     parse error:
+     
+       syntax error
+     
+     >>> 3 + 4 i
+               ^
+</pre>
+   <p class="noindent">You may also use ‘<samp><span class="samp">j</span></samp>’, ‘<samp><span class="samp">I</span></samp>’, or ‘<samp><span class="samp">J</span></samp>’ in place of the
+‘<samp><span class="samp">i</span></samp>’ above.  All four forms are equivalent.
+
+<!-- ov-re-mat.cc -->
+   <p><a name="doc_002ddouble"></a>
+
+<div class="defun">
+— Built-in Function:  <b>double</b> (<var>x</var>)<var><a name="index-double-213"></a></var><br>
+<blockquote><p>Convert <var>x</var> to double precision type. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsingle.html#doc_002dsingle">single</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dcomplex"></a>
+
+<div class="defun">
+— Built-in Function:  <b>complex</b> (<var>x</var>)<var><a name="index-complex-214"></a></var><br>
+— Built-in Function:  <b>complex</b> (<var>re, im</var>)<var><a name="index-complex-215"></a></var><br>
+<blockquote><p>Return a complex result from real arguments.  With 1 real argument <var>x</var>,
+return the complex result <var>x</var><code> + 0i</code>.  With 2 real arguments,
+return the complex result <var>re</var><code> + </code><var>im</var>.  <code>complex</code> can
+often be more convenient than expressions such as <code>a + i*b</code>. 
+For example:
+
+     <pre class="example">          complex ([1, 2], [3, 4])
+          
+             1 + 3i   2 + 4i
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dreal.html#doc_002dreal">real</a>, <a href="doc_002dimag.html#doc_002dimag">imag</a>, <a href="doc_002discomplex.html#doc_002discomplex">iscomplex</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Matrices.html#Matrices">Matrices</a>
+<li><a accesskey="2" href="Ranges.html#Ranges">Ranges</a>
+<li><a accesskey="3" href="Single-Precision-Data-Types.html#Single-Precision-Data-Types">Single Precision Data Types</a>
+<li><a accesskey="4" href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a>
+<li><a accesskey="5" href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a>
+<li><a accesskey="6" href="Logical-Values.html#Logical-Values">Logical Values</a>
+<li><a accesskey="7" href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types">Promotion and Demotion of Data Types</a>
+<li><a accesskey="8" href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Numeric-Input-Conversions.html b/doc/interpreter/HTML/Numeric-Input-Conversions.html
new file mode 100644
index 0000000..f78e118
--- /dev/null
+++ b/doc/interpreter/HTML/Numeric-Input-Conversions.html
@@ -0,0 +1,61 @@
+<html lang="en">
+<head>
+<title>Numeric Input Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Table-of-Input-Conversions.html#Table-of-Input-Conversions" title="Table of Input Conversions">
+<link rel="next" href="String-Input-Conversions.html#String-Input-Conversions" title="String Input Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Numeric-Input-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="String-Input-Conversions.html#String-Input-Conversions">String Input Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">Table of Input Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.14 Numeric Input Conversions</h4>
+
+<p>This section describes the <code>scanf</code> conversions for reading numeric
+values.
+
+   <p>The ‘<samp><span class="samp">%d</span></samp>’ conversion matches an optionally signed integer in decimal
+radix.
+
+   <p>The ‘<samp><span class="samp">%i</span></samp>’ conversion matches an optionally signed integer in any of
+the formats that the C language defines for specifying an integer
+constant.
+
+   <p>For example, any of the strings ‘<samp><span class="samp">10</span></samp>’, ‘<samp><span class="samp">0xa</span></samp>’, or ‘<samp><span class="samp">012</span></samp>’
+could be read in as integers under the ‘<samp><span class="samp">%i</span></samp>’ conversion.  Each of
+these specifies a number with decimal value <code>10</code>.
+
+   <p>The ‘<samp><span class="samp">%o</span></samp>’, ‘<samp><span class="samp">%u</span></samp>’, and ‘<samp><span class="samp">%x</span></samp>’ conversions match unsigned
+integers in octal, decimal, and hexadecimal radices, respectively.
+
+   <p>The ‘<samp><span class="samp">%X</span></samp>’ conversion is identical to the ‘<samp><span class="samp">%x</span></samp>’ conversion.  They
+both permit either uppercase or lowercase letters to be used as digits.
+
+   <p>Unlike the C language <code>scanf</code>, Octave ignores the ‘<samp><span class="samp">h</span></samp>’,
+‘<samp><span class="samp">l</span></samp>’, and ‘<samp><span class="samp">L</span></samp>’ modifiers.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Numeric-Objects.html b/doc/interpreter/HTML/Numeric-Objects.html
new file mode 100644
index 0000000..a99be6c
--- /dev/null
+++ b/doc/interpreter/HTML/Numeric-Objects.html
@@ -0,0 +1,53 @@
+<html lang="en">
+<head>
+<title>Numeric Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Built_002din-Data-Types.html#Built_002din-Data-Types" title="Built-in Data Types">
+<link rel="next" href="Missing-Data.html#Missing-Data" title="Missing Data">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Numeric-Objects"></a>
+Next: <a rel="next" accesskey="n" href="Missing-Data.html#Missing-Data">Missing Data</a>,
+Up: <a rel="up" accesskey="u" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<hr>
+</div>
+
+<h4 class="subsection">3.1.1 Numeric Objects</h4>
+
+<p><a name="index-numeric-constant-182"></a><a name="index-numeric-value-183"></a>
+Octave's built-in numeric objects include real, complex, and integer
+scalars and matrices.  All built-in floating point numeric data is
+currently stored as double precision numbers.  On systems that use the
+IEEE floating point format, values in the range of approximately
+ 2.2251e-308 to 1.7977e+308
+ can be stored, and the relative precision is approximately
+ 2.2204e-16. 
+The exact values are given by the variables <code>realmin</code>,
+<code>realmax</code>, and <code>eps</code>, respectively.
+
+   <p>Matrix objects can be of any size, and can be dynamically reshaped and
+resized.  It is easy to extract individual rows, columns, or submatrices
+using a variety of powerful indexing features.  See <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a>.
+
+   <p>See <a href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>, for more information.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Numerical-Integration.html b/doc/interpreter/HTML/Numerical-Integration.html
new file mode 100644
index 0000000..a031e28
--- /dev/null
+++ b/doc/interpreter/HTML/Numerical-Integration.html
@@ -0,0 +1,47 @@
+<html lang="en">
+<head>
+<title>Numerical Integration - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Sparse-Matrices.html#Sparse-Matrices" title="Sparse Matrices">
+<link rel="next" href="Differential-Equations.html#Differential-Equations" title="Differential Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Numerical-Integration"></a>
+Next: <a rel="next" accesskey="n" href="Differential-Equations.html#Differential-Equations">Differential Equations</a>,
+Previous: <a rel="previous" accesskey="p" href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">22 Numerical Integration</h2>
+
+<p>Octave comes with several built-in functions for computing the integral
+of a function numerically.  These functions all solve 1-dimensional
+integration problems.
+
+<ul class="menu">
+<li><a accesskey="1" href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a>
+<li><a accesskey="2" href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">Functions of Multiple Variables</a>
+<li><a accesskey="3" href="Orthogonal-Collocation.html#Orthogonal-Collocation">Orthogonal Collocation</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Object-Groups.html b/doc/interpreter/HTML/Object-Groups.html
new file mode 100644
index 0000000..2a879f2
--- /dev/null
+++ b/doc/interpreter/HTML/Object-Groups.html
@@ -0,0 +1,290 @@
+<html lang="en">
+<head>
+<title>Object Groups - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link rel="prev" href="Callbacks.html#Callbacks" title="Callbacks">
+<link rel="next" href="Graphics-backends.html#Graphics-backends" title="Graphics backends">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Object-Groups"></a>
+Next: <a rel="next" accesskey="n" href="Graphics-backends.html#Graphics-backends">Graphics backends</a>,
+Previous: <a rel="previous" accesskey="p" href="Callbacks.html#Callbacks">Callbacks</a>,
+Up: <a rel="up" accesskey="u" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.2.8 Object Groups</h4>
+
+<p><a name="index-object-groups-1220"></a>
+A number of Octave high level plot functions return groups of other
+graphics objects or they return graphics objects that are have their
+properties linked in such a way that changes to one of the properties
+results in changes in the others.  A graphic object that groups other
+objects is an <code>hggroup</code>
+
+<!-- ./plot/hggroup.m -->
+   <p><a name="doc_002dhggroup"></a>
+
+<div class="defun">
+— Function File:  <b>hggroup</b> ()<var><a name="index-hggroup-1221"></a></var><br>
+— Function File:  <b>hggroup</b> (<var>h</var>)<var><a name="index-hggroup-1222"></a></var><br>
+— Function File:  <b>hggroup</b> (<var><small class="dots">...</small>, property, value, <small class="dots">...</small></var>)<var><a name="index-hggroup-1223"></a></var><br>
+<blockquote><p>Create group object with parent <var>h</var>.  If no parent is specified,
+the group is created in the current axes.  Return the handle of the
+group object created.
+
+        <p>Multiple property-value pairs may be specified for the group, but they
+must appear in pairs. 
+</p></blockquote></div>
+
+   <p>For example a simple use of a <code>hggroup</code> might be
+
+<pre class="example">     x = 0:0.1:10;
+     hg = hggroup ();
+     plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+     hold on
+     plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+     set (hg, "visible", "off");
+</pre>
+   <p class="noindent">which groups the two plots into a single object and controls their
+visibility directly.  The default properties of an <code>hggroup</code> are
+the same as the set of common properties for the other graphics
+objects.  Additional properties can be added with the <code>addproperty</code>
+function.
+
+<!-- graphics.cc -->
+   <p><a name="doc_002daddproperty"></a>
+
+<div class="defun">
+— Built-in Function:  <b>addproperty</b> (<var>name, h, type, </var>[<var>arg, <small class="dots">...</small></var>])<var><a name="index-addproperty-1224"></a></var><br>
+<blockquote><p>Create a new property named <var>name</var> in graphics object <var>h</var>. 
+<var>type</var> determines the type of the property to create.  <var>args</var>
+usually contains the default value of the property, but additional
+arguments might be given, depending on the type of the property.
+
+        <p>The supported property types are:
+
+          <dl>
+<dt><code>string</code><dd>A string property.  <var>arg</var> contains the default string value. 
+<br><dt><code>any</code><dd>An un-typed property.  This kind of property can hold any octave
+value.  <var>args</var> contains the default value. 
+<br><dt><code>radio</code><dd>A string property with a limited set of accepted values.  The first
+argument must be a string with all accepted values separated by
+a vertical bar ('|').  The default value can be marked by enclosing
+it with a '{' '}' pair.  The default value may also be given as
+an optional second string argument. 
+<br><dt><code>boolean</code><dd>A boolean property.  This property type is equivalent to a radio
+property with "on|off" as accepted values.  <var>arg</var> contains
+the default property value. 
+<br><dt><code>double</code><dd>A scalar double property.  <var>arg</var> contains the default value. 
+<br><dt><code>handle</code><dd>A handle property.  This kind of property holds the handle of a
+graphics object.  <var>arg</var> contains the default handle value. 
+When no default value is given, the property is initialized to
+the empty matrix. 
+<br><dt><code>data</code><dd>A data (matrix) property.  <var>arg</var> contains the default data
+value.  When no default value is given, the data is initialized to
+the empty matrix. 
+<br><dt><code>color</code><dd>A color property.  <var>arg</var> contains the default color value. 
+When no default color is given, the property is set to black. 
+An optional second string argument may be given to specify an
+additional set of accepted string values (like a radio property). 
+</dl>
+
+        <p><var>type</var> may also be the concatenation of a core object type and
+a valid property name for that object type.  The property created
+then has the same characteristics as the referenced property (type,
+possible values, hidden state<small class="dots">...</small>).  This allows to clone an existing
+property into the graphics object <var>h</var>.
+
+        <p>Examples:
+
+     <pre class="example">          addproperty ("my_property", gcf, "string", "a string value");
+          addproperty ("my_radio", gcf, "radio", "val_1|val_2|{val_3}");
+          addproperty ("my_style", gcf, "linelinestyle", "--");
+</pre>
+        </blockquote></div>
+
+   <p>Once a property in added to an <code>hggroup</code>, it is not linked to any
+other property of either the children of the group, or any other
+graphics object.  Add so to control the way in which this newly added
+property is used, the <code>addlistener</code> function is used to define a
+callback function that is executed when the property is altered.
+
+<!-- graphics.cc -->
+   <p><a name="doc_002daddlistener"></a>
+
+<div class="defun">
+— Built-in Function:  <b>addlistener</b> (<var>h, prop, fcn</var>)<var><a name="index-addlistener-1225"></a></var><br>
+<blockquote><p>Register <var>fcn</var> as listener for the property <var>prop</var> of the graphics
+object <var>h</var>.  Property listeners are executed (in order of registration)
+when the property is set.  The new value is already available when the
+listeners are executed.
+
+        <p><var>prop</var> must be a string naming a valid property in <var>h</var>.
+
+        <p><var>fcn</var> can be a function handle, a string or a cell array whose first
+element is a function handle.  If <var>fcn</var> is a function handle, the
+corresponding function should accept at least 2 arguments, that will be
+set to the object handle and the empty matrix respectively.  If <var>fcn</var>
+is a string, it must be any valid octave expression.  If <var>fcn</var> is a cell
+array, the first element must be a function handle with the same signature
+as described above.  The next elements of the cell array are passed
+as additional arguments to the function.
+
+        <p>Example:
+
+     <pre class="example">          function my_listener (h, dummy, p1)
+            fprintf ("my_listener called with p1=%s\n", p1);
+          endfunction
+          
+          addlistener (gcf, "position", {@my_listener, "my string"})
+</pre>
+        </blockquote></div>
+
+<!-- graphics.cc -->
+   <p><a name="doc_002ddellistener"></a>
+
+<div class="defun">
+— Built-in Function:  <b>dellistener</b> (<var>h, prop, fcn</var>)<var><a name="index-dellistener-1226"></a></var><br>
+<blockquote><p>Remove the registration of <var>fcn</var> as a listener for the property
+<var>prop</var> of the graphics object <var>h</var>.  The function <var>fcn</var> must
+be the same variable (not just the same value), as was passed to the
+original call to <code>addlistener</code>.
+
+        <p>If <var>fcn</var> is not defined then all listener functions of <var>prop</var>
+are removed.
+
+        <p>Example:
+
+     <pre class="example">          function my_listener (h, dummy, p1)
+            fprintf ("my_listener called with p1=%s\n", p1);
+          endfunction
+          
+          c = {@my_listener, "my string"};
+          addlistener (gcf, "position", c);
+          dellistener (gcf, "position", c);
+</pre>
+        </blockquote></div>
+
+   <p>An example of the use of these two functions might be
+
+<pre class="example">     x = 0:0.1:10;
+     hg = hggroup ();
+     h = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+     addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+     addlistener (hg, "linestyle", @update_props);
+     hold on
+     plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+     
+     function update_props (h, d)
+       set (get (h, "children"), "linestyle", get (h, "linestyle"));
+     endfunction
+</pre>
+   <p class="noindent">that adds a <code>linestyle</code> property to the <code>hggroup</code> and
+propagating any changes its value to the children of the group.  The
+<code>linkprop</code> function can be used to simplify the above to be
+
+<pre class="example">     x = 0:0.1:10;
+     hg = hggroup ();
+     h1 = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+     addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+     hold on
+     h2 = plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+     hlink = linkprop ([hg, h1, h2], "color");
+</pre>
+   <!-- ./plot/linkprop.m -->
+   <p><a name="doc_002dlinkprop"></a>
+
+<div class="defun">
+— Function File: <var>hlink</var> = <b>linkprop</b> (<var>h, prop</var>)<var><a name="index-linkprop-1227"></a></var><br>
+<blockquote><p>Links graphics object properties, such that a change in one is
+propagated to the others.  The properties to link are given as a
+string of cell string array by <var>prop</var> and the objects containing
+these properties by the handle array <var>h</var>.
+
+        <p>An example of the use of linkprops is
+
+     <pre class="example">          x = 0:0.1:10;
+          subplot (1, 2, 1);
+          h1 = plot (x, sin (x));
+          subplot (1, 2, 2);
+          h2 = plot (x, cos (x));
+          hlink = linkprop ([h1, h2], {"color","linestyle"});
+          set (h1, "color", "green");
+          set (h2, "linestyle", "--");
+</pre>
+        </blockquote></div>
+
+   <p>These capabilities are used in a number of basic graphics objects. 
+The <code>hggroup</code> objects created by the functions of Octave contain
+one or more graphics object and are used to:
+
+     <ul>
+<li>group together multiple graphics objects,
+<li>create linked properties between different graphics objects, and
+<li>to hide the nominal user data, from the actual data of the objects. 
+</ul>
+
+<p class="noindent">For example the <code>stem</code> function creates a stem series where each
+<code>hggroup</code> of the stem series contains two line objects representing
+the body and head of the stem.  The <code>ydata</code> property of the
+<code>hggroup</code> of the stem series represents the head of the stem,
+whereas the body of the stem is between the baseline and this value.  For
+example
+
+<pre class="example">     h = stem (1:4)
+     get (h, "xdata")
+      [  1   2   3   4]'
+     get (get (h, "children")(1), "xdata")
+      [  1   1 NaN   2   2 NaN   3   3 NaN   4   4 NaN]'
+</pre>
+   <p class="noindent">shows the difference between the <code>xdata</code> of the <code>hggroup</code>
+of a stem series object and the underlying line.
+
+   <p>The basic properties of such group objects is that they consist of one
+or more linked <code>hggroup</code>, and that changes in certain properties of
+these groups are propagated to other members of the group.  Whereas,
+certain properties of the members of the group only apply to the current
+member.
+
+   <p>In addition the members of the group can also be linked to other
+graphics objects through callback functions.  For example the baseline of
+the <code>bar</code> or <code>stem</code> functions is a line object, whose length
+and position are automatically adjusted, based on changes to the
+corresponding hggroup elements.
+
+<ul class="menu">
+<li><a accesskey="1" href="Data-sources-in-object-groups.html#Data-sources-in-object-groups">Data sources in object groups</a>
+<li><a accesskey="2" href="Area-series.html#Area-series">Area series</a>
+<li><a accesskey="3" href="Bar-series.html#Bar-series">Bar series</a>
+<li><a accesskey="4" href="Contour-groups.html#Contour-groups">Contour groups</a>
+<li><a accesskey="5" href="Error-bar-series.html#Error-bar-series">Error bar series</a>
+<li><a accesskey="6" href="Line-series.html#Line-series">Line series</a>
+<li><a accesskey="7" href="Quiver-group.html#Quiver-group">Quiver group</a>
+<li><a accesskey="8" href="Scatter-group.html#Scatter-group">Scatter group</a>
+<li><a accesskey="9" href="Stair-group.html#Stair-group">Stair group</a>
+<li><a href="Stem-Series.html#Stem-Series">Stem Series</a>
+<li><a href="Surface-group.html#Surface-group">Surface group</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Object-Oriented-Programming.html b/doc/interpreter/HTML/Object-Oriented-Programming.html
new file mode 100644
index 0000000..d223739
--- /dev/null
+++ b/doc/interpreter/HTML/Object-Oriented-Programming.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Object Oriented Programming - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Audio-Processing.html#Audio-Processing" title="Audio Processing">
+<link rel="next" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Object-Oriented-Programming"></a>
+Next: <a rel="next" accesskey="n" href="System-Utilities.html#System-Utilities">System Utilities</a>,
+Previous: <a rel="previous" accesskey="p" href="Audio-Processing.html#Audio-Processing">Audio Processing</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">33 Object Oriented Programming</h2>
+
+<p>Octave includes the capability to include user classes, including the
+features of operator and function overloading.  Equally a user class
+can be used to encapsulate certain properties of the class so that
+they cannot be altered accidentally and can be set up to address the
+issue of class precedence in mixed class operations.
+
+   <p>This chapter discussions the means of constructing a user class with
+the example of a polynomial class, how to query and set the properties
+of this class, together with the means to overload operators and
+functions.
+
+<ul class="menu">
+<li><a accesskey="1" href="Creating-a-Class.html#Creating-a-Class">Creating a Class</a>
+<li><a accesskey="2" href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a>
+<li><a accesskey="3" href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a>
+<li><a accesskey="4" href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>
+<li><a accesskey="5" href="Inheritance-and-Aggregation.html#Inheritance-and-Aggregation">Inheritance and Aggregation</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Object-Sizes.html b/doc/interpreter/HTML/Object-Sizes.html
new file mode 100644
index 0000000..d553be8
--- /dev/null
+++ b/doc/interpreter/HTML/Object-Sizes.html
@@ -0,0 +1,205 @@
+<html lang="en">
+<head>
+<title>Object Sizes - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Types.html#Data-Types" title="Data Types">
+<link rel="prev" href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types" title="User-defined Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Object-Sizes"></a>
+Previous: <a rel="previous" accesskey="p" href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a>,
+Up: <a rel="up" accesskey="u" href="Data-Types.html#Data-Types">Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">3.3 Object Sizes</h3>
+
+<p>The following functions allow you to determine the size of a variable or
+expression.  These functions are defined for all objects.  They return
+−1 when the operation doesn't make sense.  For example, Octave's
+data structure type doesn't have rows or columns, so the <code>rows</code> and
+<code>columns</code> functions return −1 for structure arguments.
+
+<!-- data.cc -->
+   <p><a name="doc_002dndims"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ndims</b> (<var>a</var>)<var><a name="index-ndims-200"></a></var><br>
+<blockquote><p>Returns the number of dimensions of array <var>a</var>. 
+For any array, the result will always be larger than or equal to 2. 
+Trailing singleton dimensions are not counted. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dcolumns"></a>
+
+<div class="defun">
+— Built-in Function:  <b>columns</b> (<var>a</var>)<var><a name="index-columns-201"></a></var><br>
+<blockquote><p>Return the number of columns of <var>a</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002dnumel.html#doc_002dnumel">numel</a>, <a href="doc_002drows.html#doc_002drows">rows</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002disscalar.html#doc_002disscalar">isscalar</a>, <a href="doc_002disvector.html#doc_002disvector">isvector</a>, <a href="doc_002dismatrix.html#doc_002dismatrix">ismatrix</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002drows"></a>
+
+<div class="defun">
+— Built-in Function:  <b>rows</b> (<var>a</var>)<var><a name="index-rows-202"></a></var><br>
+<blockquote><p>Return the number of rows of <var>a</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002dnumel.html#doc_002dnumel">numel</a>, <a href="doc_002dcolumns.html#doc_002dcolumns">columns</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002disscalar.html#doc_002disscalar">isscalar</a>, <a href="doc_002disvector.html#doc_002disvector">isvector</a>, <a href="doc_002dismatrix.html#doc_002dismatrix">ismatrix</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dnumel"></a>
+
+<div class="defun">
+— Built-in Function:  <b>numel</b> (<var>a</var>)<var><a name="index-numel-203"></a></var><br>
+<blockquote><p>Returns the number of elements in the object <var>a</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dlength"></a>
+
+<div class="defun">
+— Built-in Function:  <b>length</b> (<var>a</var>)<var><a name="index-length-204"></a></var><br>
+<blockquote><p>Return the `length' of the object <var>a</var>.  For matrix objects, the
+length is the number of rows or columns, whichever is greater (this
+odd definition is used for compatibility with <span class="sc">matlab</span>). 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dsize"></a>
+
+<div class="defun">
+— Built-in Function:  <b>size</b> (<var>a, n</var>)<var><a name="index-size-205"></a></var><br>
+<blockquote><p>Return the number rows and columns of <var>a</var>.
+
+        <p>With one input argument and one output argument, the result is returned
+in a row vector.  If there are multiple output arguments, the number of
+rows is assigned to the first, and the number of columns to the second,
+etc.  For example,
+
+     <pre class="example">          size ([1, 2; 3, 4; 5, 6])
+                [ 3, 2 ]
+          
+          [nr, nc] = size ([1, 2; 3, 4; 5, 6])
+                nr = 3
+                nc = 2
+</pre>
+        <p>If given a second argument, <code>size</code> will return the size of the
+corresponding dimension.  For example
+
+     <pre class="example">          size ([1, 2; 3, 4; 5, 6], 2)
+                2
+</pre>
+        <p class="noindent">returns the number of columns in the given matrix. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnumel.html#doc_002dnumel">numel</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002disempty"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isempty</b> (<var>a</var>)<var><a name="index-isempty-206"></a></var><br>
+<blockquote><p>Return 1 if <var>a</var> is an empty matrix (either the number of rows, or
+the number of columns, or both are zero).  Otherwise, return 0. 
+</p></blockquote></div>
+
+<!-- ov-null-mat.cc -->
+   <p><a name="doc_002disnull"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isnull</b> (<var>x</var>)<var><a name="index-isnull-207"></a></var><br>
+<blockquote><p>Return 1 if <var>x</var> is a special null matrix, string or single quoted string. 
+Indexed assignment with such a value as right-hand side should delete array elements. 
+This function should be used when overloading indexed assignment for user-defined
+classes instead of <code>isempty</code>, to distinguish the cases:
+          <dl>
+<dt><code>A(I) = []</code><dd>This should delete elements if <code>I</code> is nonempty. 
+<br><dt><code>X = []; A(I) = X</code><dd>This should give an error if <code>I</code> is nonempty. 
+</dl>
+        </p></blockquote></div>
+
+<!-- ov.cc -->
+   <p><a name="doc_002dsizeof"></a>
+
+<div class="defun">
+— Built-in Function:  <b>sizeof</b> (<var>val</var>)<var><a name="index-sizeof-208"></a></var><br>
+<blockquote><p>Return the size of <var>val</var> in bytes
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dsize_005fequal"></a>
+
+<div class="defun">
+— Built-in Function:  <b>size_equal</b> (<var>a, b, <small class="dots">...</small></var>)<var><a name="index-size_005fequal-209"></a></var><br>
+<blockquote><p>Return true if the dimensions of all arguments agree. 
+Trailing singleton dimensions are ignored. 
+Called with a single argument, size_equal returns true. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002dnumel.html#doc_002dnumel">numel</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dsqueeze"></a>
+
+<div class="defun">
+— Built-in Function:  <b>squeeze</b> (<var>x</var>)<var><a name="index-squeeze-210"></a></var><br>
+<blockquote><p>Remove singleton dimensions from <var>x</var> and return the result. 
+Note that for compatibility with <span class="sc">matlab</span>, all objects have
+a minimum of two dimensions and row vectors are left unchanged. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Oct_002dFiles.html b/doc/interpreter/HTML/Oct_002dFiles.html
new file mode 100644
index 0000000..d61368e
--- /dev/null
+++ b/doc/interpreter/HTML/Oct_002dFiles.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions" title="Dynamically Linked Functions">
+<link rel="next" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Oct-Files"></a>
+<a name="Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>
+<hr>
+</div>
+
+<h3 class="section">A.1 Oct-Files</h3>
+
+<p><a name="index-oct_002dfiles-2469"></a><a name="index-mkoctfile-2470"></a><a name="index-oct-2471"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Getting-Started-with-Oct_002dFiles.html#Getting-Started-with-Oct_002dFiles">Getting Started with Oct-Files</a>
+<li><a accesskey="2" href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a>
+<li><a accesskey="3" href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles">Character Strings in Oct-Files</a>
+<li><a accesskey="4" href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles">Cell Arrays in Oct-Files</a>
+<li><a accesskey="5" href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles">Structures in Oct-Files</a>
+<li><a accesskey="6" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>
+<li><a accesskey="7" href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles">Accessing Global Variables in Oct-Files</a>
+<li><a accesskey="8" href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles">Calling Octave Functions from Oct-Files</a>
+<li><a accesskey="9" href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles">Calling External Code from Oct-Files</a>
+<li><a href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles">Allocating Local Memory in Oct-Files</a>
+<li><a href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles">Input Parameter Checking in Oct-Files</a>
+<li><a href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles">Exception and Error Handling in Oct-Files</a>
+<li><a href="Documentation-and-Test-of-Oct_002dFiles.html#Documentation-and-Test-of-Oct_002dFiles">Documentation and Test of Oct-Files</a>
+<!-- * Application Programming Interface for Oct-Files:: -->
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Octave-Sources-_0028m_002dfiles_0029.html b/doc/interpreter/HTML/Octave-Sources-_0028m_002dfiles_0029.html
new file mode 100644
index 0000000..228a2f1
--- /dev/null
+++ b/doc/interpreter/HTML/Octave-Sources-_0028m_002dfiles_0029.html
@@ -0,0 +1,79 @@
+<html lang="en">
+<head>
+<title>Octave Sources (m-files) - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link rel="prev" href="General-Guidelines.html#General-Guidelines" title="General Guidelines">
+<link rel="next" href="C_002b_002b-Sources.html#C_002b_002b-Sources" title="C++ Sources">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Octave-Sources-(m-files)"></a>
+<a name="Octave-Sources-_0028m_002dfiles_0029"></a>
+Next: <a rel="next" accesskey="n" href="C_002b_002b-Sources.html#C_002b_002b-Sources">C++ Sources</a>,
+Previous: <a rel="previous" accesskey="p" href="General-Guidelines.html#General-Guidelines">General Guidelines</a>,
+Up: <a rel="up" accesskey="u" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>
+<hr>
+</div>
+
+<h3 class="section">D.3 Octave Sources (m-files)</h3>
+
+<p>Don't use tabs.  Tabs cause trouble.  If you are used to them, set up your editor
+so that it converts tabs to spaces.  Indent the bodies of the statement blocks. 
+Recommended indent is 2 spaces.  When calling functions, put spaces after commas
+and before the calling parentheses, like this:
+
+<pre class="example">       x = max (sin (y+3), 2);
+</pre>
+   <p class="noindent">An exception are matrix and vector constructors:
+
+<pre class="example">       [sin(x), cos(x)]
+</pre>
+   <p class="noindent">Here, putting spaces after <code>sin</code>, <code>cos</code> would result in a parse error. 
+In indexing expression, do not put a space after the identifier (this
+differentiates indexing and function calls nicely).  The space after comma is not
+necessary if index expressions are simple, i.e., you may write
+<pre class="example">       A(:,i,j)
+</pre>
+   <p class="noindent">but
+
+<pre class="example">       A([1:i-1;i+1:n], XI(:,2:n-1))
+</pre>
+   <p>Use lowercase names if possible.  Uppercase is acceptable for variable names
+consisting of 1-2 letters.  Do not use mixed case names.  Function names must be
+lowercase.  Function names are global, so choose them wisely.
+
+   <p>Always use a specific end-of-block statement (like <code>endif</code>,
+<code>endswitch</code>) rather than generic <code>end</code>.  Enclose the <code>if</code>,
+<code>while</code>, <code>until</code> and <code>switch</code> conditions in parentheses,
+like in C:
+
+<pre class="example">     if (isvector (a))
+       s = sum(a);
+     endif
+</pre>
+   <p class="noindent">Do not do this, however, with <code>for</code>:
+
+<pre class="example">     for i = 1:n
+       b(i) = sum (a(:,i));
+     endfor
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/One_002ddimensional-Interpolation.html b/doc/interpreter/HTML/One_002ddimensional-Interpolation.html
new file mode 100644
index 0000000..8f6ff05
--- /dev/null
+++ b/doc/interpreter/HTML/One_002ddimensional-Interpolation.html
@@ -0,0 +1,287 @@
+<html lang="en">
+<head>
+<title>One-dimensional Interpolation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Interpolation.html#Interpolation" title="Interpolation">
+<link rel="next" href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation" title="Multi-dimensional Interpolation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="One-dimensional-Interpolation"></a>
+<a name="One_002ddimensional-Interpolation"></a>
+Next: <a rel="next" accesskey="n" href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a>,
+Up: <a rel="up" accesskey="u" href="Interpolation.html#Interpolation">Interpolation</a>
+<hr>
+</div>
+
+<h3 class="section">28.1 One-dimensional Interpolation</h3>
+
+<p>Octave supports several methods for one-dimensional interpolation, most
+of which are described in this section.  <a href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a>
+and <a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a> describe further methods.
+
+<!-- ./general/interp1.m -->
+   <p><a name="doc_002dinterp1"></a>
+
+<div class="defun">
+— Function File: <var>yi</var> = <b>interp1</b> (<var>x, y, xi</var>)<var><a name="index-interp1-2056"></a></var><br>
+— Function File: <var>yi</var> = <b>interp1</b> (<var><small class="dots">...</small>, method</var>)<var><a name="index-interp1-2057"></a></var><br>
+— Function File: <var>yi</var> = <b>interp1</b> (<var><small class="dots">...</small>, extrap</var>)<var><a name="index-interp1-2058"></a></var><br>
+— Function File: <var>pp</var> = <b>interp1</b> (<var><small class="dots">...</small>, 'pp'</var>)<var><a name="index-interp1-2059"></a></var><br>
+<blockquote>
+        <p>One-dimensional interpolation.  Interpolate <var>y</var>, defined at the
+points <var>x</var>, at the points <var>xi</var>.  The sample points <var>x</var>
+must be strictly monotonic.  If <var>y</var> is an array, treat the columns
+of <var>y</var> separately.
+
+        <p>Method is one of:
+
+          <dl>
+<dt>'nearest'<dd>Return the nearest neighbor. 
+<br><dt>'linear'<dd>Linear interpolation from nearest neighbors
+<br><dt>'pchip'<dd>Piece-wise cubic hermite interpolating polynomial
+<br><dt>'cubic'<dd>Cubic interpolation from four nearest neighbors
+<br><dt>'spline'<dd>Cubic spline interpolation–smooth first and second derivatives
+throughout the curve
+</dl>
+
+        <p>Appending '*' to the start of the above method forces <code>interp1</code>
+to assume that <var>x</var> is uniformly spaced, and only <var>x</var><code>
+(1)</code> and <var>x</var><code> (2)</code> are referenced.  This is usually faster,
+and is never slower.  The default method is 'linear'.
+
+        <p>If <var>extrap</var> is the string 'extrap', then extrapolate values beyond
+the endpoints.  If <var>extrap</var> is a number, replace values beyond the
+endpoints with that number.  If <var>extrap</var> is missing, assume NA.
+
+        <p>If the string argument 'pp' is specified, then <var>xi</var> should not be
+supplied and <code>interp1</code> returns the piece-wise polynomial that
+can later be used with <code>ppval</code> to evaluate the interpolation. 
+There is an equivalence, such that <code>ppval (interp1 (</code><var>x</var><code>,
+</code><var>y</var><code>, </code><var>method</var><code>, 'pp'), </code><var>xi</var><code>) == interp1 (</code><var>x</var><code>, </code><var>y</var><code>,
+</code><var>xi</var><code>, </code><var>method</var><code>, 'extrap')</code>.
+
+        <p>An example of the use of <code>interp1</code> is
+
+     <pre class="example">          xf = [0:0.05:10];
+          yf = sin (2*pi*xf/5);
+          xp = [0:10];
+          yp = sin (2*pi*xp/5);
+          lin = interp1 (xp, yp, xf);
+          spl = interp1 (xp, yp, xf, "spline");
+          cub = interp1 (xp, yp, xf, "cubic");
+          near = interp1 (xp, yp, xf, "nearest");
+          plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
+                xf, cub, "c", xf, near, "m", xp, yp, "r*");
+          legend ("original", "linear", "spline", "cubic", "nearest")
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterpft.html#doc_002dinterpft">interpft</a>. 
+</p></blockquote></div>
+
+   <p>There are some important differences between the various interpolation
+methods.  The 'spline' method enforces that both the first and second
+derivatives of the interpolated values have a continuous derivative,
+whereas the other methods do not.  This means that the results of the
+'spline' method are generally smoother.  If the function to be
+interpolated is in fact smooth, then 'spline' will give excellent
+results.  However, if the function to be evaluated is in some manner
+discontinuous, then 'pchip' interpolation might give better results.
+
+   <p>This can be demonstrated by the code
+
+<pre class="example">     t = -2:2;
+     dt = 1;
+     ti =-2:0.025:2;
+     dti = 0.025;
+     y = sign(t);
+     ys = interp1(t,y,ti,'spline');
+     yp = interp1(t,y,ti,'pchip');
+     ddys = diff(diff(ys)./dti)./dti;
+     ddyp = diff(diff(yp)./dti)./dti;
+     figure(1);
+     plot (ti, ys,'r-', ti, yp,'g-');
+     legend('spline','pchip',4);
+     figure(2);
+     plot (ti, ddys,'r+', ti, ddyp,'g*');
+     legend('spline','pchip');
+</pre>
+   <p>A simplified version of <code>interp1</code> that performs only linear
+interpolation is available in <code>interp1q</code>.  This argument is slightly
+faster than <code>interp1</code> as to performs little error checking.
+
+<!-- ./general/interp1q.m -->
+   <p><a name="doc_002dinterp1q"></a>
+
+<div class="defun">
+— Function File: <var>yi</var> = <b>interp1q</b> (<var>x, y, xi</var>)<var><a name="index-interp1q-2060"></a></var><br>
+<blockquote><p>One-dimensional linear interpolation without error checking. 
+Interpolates <var>y</var>, defined at the points <var>x</var>, at the points
+<var>xi</var>.  The sample points <var>x</var> must be a strictly monotonically
+increasing column vector.  If <var>y</var> is an array, treat the columns
+of <var>y</var> separately.  If <var>y</var> is a vector, it must be a column
+vector of the same length as <var>x</var>.
+
+        <p>Values of <var>xi</var> beyond the endpoints of the interpolation result
+in NA being returned.
+
+        <p>Note that the error checking is only a significant portion of the
+execution time of this <code>interp1</code> if the size of the input arguments
+is relatively small.  Therefore, the benefit of using <code>interp1q</code>
+is relatively small. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp1.html#doc_002dinterp1">interp1</a>. 
+</p></blockquote></div>
+
+   <p>Fourier interpolation, is a resampling technique where a signal is
+converted to the frequency domain, padded with zeros and then
+reconverted to the time domain.
+
+<!-- ./general/interpft.m -->
+   <p><a name="doc_002dinterpft"></a>
+
+<div class="defun">
+— Function File:  <b>interpft</b> (<var>x, n</var>)<var><a name="index-interpft-2061"></a></var><br>
+— Function File:  <b>interpft</b> (<var>x, n, dim</var>)<var><a name="index-interpft-2062"></a></var><br>
+<blockquote>
+        <p>Fourier interpolation.  If <var>x</var> is a vector, then <var>x</var> is
+resampled with <var>n</var> points.  The data in <var>x</var> is assumed to be
+equispaced.  If <var>x</var> is an array, then operate along each column of
+the array separately.  If <var>dim</var> is specified, then interpolate
+along the dimension <var>dim</var>.
+
+        <p><code>interpft</code> assumes that the interpolated function is periodic,
+and so assumptions are made about the end points of the interpolation.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp1.html#doc_002dinterp1">interp1</a>. 
+</p></blockquote></div>
+
+   <p>There are two significant limitations on Fourier interpolation.  Firstly,
+the function signal is assumed to be periodic, and so non-periodic
+signals will be poorly represented at the edges.  Secondly, both the
+signal and its interpolation are required to be sampled at equispaced
+points.  An example of the use of <code>interpft</code> is
+
+<pre class="example">     t = 0 : 0.3 : pi; dt = t(2)-t(1);
+     n = length (t); k = 100;
+     ti = t(1) + [0 : k-1]*dt*n/k;
+     y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+     yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
+     plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ...
+           ti, interpft (y, k), 'c', t, y, 'r+');
+     legend ('sin(4t+0.3)cos(3t-0.1','spline','interpft','data');
+</pre>
+   <p class="noindent">which demonstrates the poor behavior of Fourier interpolation for non-periodic functions.
+
+   <p>In additional the support function <code>spline</code> and <code>lookup</code> that
+underlie the <code>interp1</code> function can be called directly.
+
+<!-- ./polynomial/spline.m -->
+   <p><a name="doc_002dspline"></a>
+
+<div class="defun">
+— Function File: <var>pp</var> = <b>spline</b> (<var>x, y</var>)<var><a name="index-spline-2063"></a></var><br>
+— Function File: <var>yi</var> = <b>spline</b> (<var>x, y, xi</var>)<var><a name="index-spline-2064"></a></var><br>
+<blockquote>
+        <p>Return the cubic spline interpolant of <var>y</var> at points <var>x</var>. 
+If called with two arguments, <code>spline</code> returns the piece-wise
+polynomial <var>pp</var> that may later be used with <code>ppval</code> to
+evaluate the polynomial at specific points. 
+If called with a third input argument, <code>spline</code> evaluates the
+spline at the points <var>xi</var>.  There is an equivalence
+between <code>ppval (spline (</code><var>x</var><code>, </code><var>y</var><code>), </code><var>xi</var><code>)</code> and
+<code>spline (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>xi</var><code>)</code>.
+
+        <p>The variable <var>x</var> must be a vector of length <var>n</var>, and <var>y</var>
+can be either a vector or array.  In the case where <var>y</var> is a
+vector, it can have a length of either <var>n</var> or <var>n</var><code> + 2</code>. 
+If the length of <var>y</var> is <var>n</var>, then the 'not-a-knot' end
+condition is used.  If the length of <var>y</var> is <var>n</var><code> + 2</code>,
+then the first and last values of the vector <var>y</var> are the values
+of the first derivative of the cubic spline at the end-points.
+
+        <p>If <var>y</var> is an array, then the size of <var>y</var> must have the form
+<code>[</code><var>s1</var><code>, </code><var>s2</var><code>, ..., </code><var>sk</var><code>, </code><var>n</var><code>]</code>
+or
+<code>[</code><var>s1</var><code>, </code><var>s2</var><code>, ..., </code><var>sk</var><code>, </code><var>n</var><code> + 2]</code>. 
+The array is then reshaped internally to a matrix where the leading
+dimension is given by
+<var>s1</var><code> * </code><var>s2</var><code> * ... * </code><var>sk</var>
+and each row of this matrix is then treated separately.  Note that this
+is exactly the opposite treatment than <code>interp1</code> and is done
+for compatibility. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dppval.html#doc_002dppval">ppval</a>, <a href="doc_002dmkpp.html#doc_002dmkpp">mkpp</a>, <a href="doc_002dunmkpp.html#doc_002dunmkpp">unmkpp</a>. 
+</p></blockquote></div>
+
+   <p>The <code>lookup</code> function is used by other interpolation functions to identify
+the points of the original data that are closest to the current point
+of interest.
+
+<!-- ./DLD-FUNCTIONS/lookup.cc -->
+   <p><a name="doc_002dlookup"></a>
+
+<div class="defun">
+— Loadable Function: <var>idx</var> = <b>lookup</b> (<var>table, y, opt</var>)<var><a name="index-lookup-2065"></a></var><br>
+<blockquote><p>Lookup values in a sorted table.  Usually used as a prelude to
+interpolation.
+
+        <p>If table is strictly increasing and <code>idx = lookup (table, y)</code>, then
+<code>table(idx(i)) <= y(i) < table(idx(i+1))</code> for all <code>y(i)</code>
+within the table.  If <code>y(i) < table (1)</code> then
+<code>idx(i)</code> is 0. If <code>y(i) >= table(end)</code> then
+<code>idx(i)</code> is <code>table(n)</code>.
+
+        <p>If the table is strictly decreasing, then the tests are reversed. 
+There are no guarantees for tables which are non-monotonic or are not
+strictly monotonic.
+
+        <p>The algorithm used by lookup is standard binary search, with optimizations
+to speed up the case of partially ordered arrays (dense downsampling). 
+In particular, looking up a single entry is of logarithmic complexity
+(unless a conversion occurs due to non-numeric or unequal types).
+
+        <p><var>table</var> and <var>y</var> can also be cell arrays of strings
+(or <var>y</var> can be a single string).  In this case, string lookup
+is performed using lexicographical comparison.
+
+        <p>If <var>opts</var> is specified, it shall be a string with letters indicating
+additional options. 
+For numeric lookup, 'l' in <var>opts</var> indicates that
+the leftmost subinterval shall be extended to infinity (i.e., all indices
+at least 1), and 'r' indicates that the rightmost subinterval shall be
+extended to infinity (i.e., all indices at most n-1).
+
+        <p>For string lookup, 'i' indicates case-insensitive comparison. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Opening-and-Closing-Files.html b/doc/interpreter/HTML/Opening-and-Closing-Files.html
new file mode 100644
index 0000000..f13cce1
--- /dev/null
+++ b/doc/interpreter/HTML/Opening-and-Closing-Files.html
@@ -0,0 +1,161 @@
+<html lang="en">
+<head>
+<title>Opening and Closing Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="next" href="Simple-Output.html#Simple-Output" title="Simple Output">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Opening-and-Closing-Files"></a>
+Next: <a rel="next" accesskey="n" href="Simple-Output.html#Simple-Output">Simple Output</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.1 Opening and Closing Files</h4>
+
+<p>When reading data from a file it must be opened for reading first, and
+likewise when writing to a file.  The <code>fopen</code> function returns a
+pointer to an open file that is ready to be read or written.  Once all
+data has been read from or written to the opened file it should be closed. 
+The <code>fclose</code> function does this.  The following code illustrates
+the basic pattern for writing to a file, but a very similar pattern is
+used when reading a file.
+
+<pre class="example">     filename = "myfile.txt";
+     fid = fopen (filename, "w");
+     # Do the actual I/O here...
+     fclose (fid);
+</pre>
+   <!-- file-io.cc -->
+   <p><a name="doc_002dfopen"></a>
+
+<div class="defun">
+— Built-in Function: [<var>fid</var>, <var>msg</var>] = <b>fopen</b> (<var>name, mode, arch</var>)<var><a name="index-fopen-773"></a></var><br>
+— Built-in Function: <var>fid_list</var> = <b>fopen</b> (<var>"all"</var>)<var><a name="index-fopen-774"></a></var><br>
+— Built-in Function: [<var>file</var>, <var>mode</var>, <var>arch</var>] = <b>fopen</b> (<var>fid</var>)<var><a name="index-fopen-775"></a></var><br>
+<blockquote><p>The first form of the <code>fopen</code> function opens the named file with
+the specified mode (read-write, read-only, etc.) and architecture
+interpretation (IEEE big endian, IEEE little endian, etc.), and returns
+an integer value that may be used to refer to the file later.  If an
+error occurs, <var>fid</var> is set to −1 and <var>msg</var> contains the
+corresponding system error message.  The <var>mode</var> is a one or two
+character string that specifies whether the file is to be opened for
+reading, writing, or both.
+
+        <p>The second form of the <code>fopen</code> function returns a vector of file ids
+corresponding to all the currently open files, excluding the
+<code>stdin</code>, <code>stdout</code>, and <code>stderr</code> streams.
+
+        <p>The third form of the <code>fopen</code> function returns information about the
+open file given its file id.
+
+        <p>For example,
+
+     <pre class="example">          myfile = fopen ("splat.dat", "r", "ieee-le");
+</pre>
+        <p class="noindent">opens the file <samp><span class="file">splat.dat</span></samp> for reading.  If necessary, binary
+numeric values will be read assuming they are stored in IEEE format with
+the least significant bit first, and then converted to the native
+representation.
+
+        <p>Opening a file that is already open simply opens it again and returns a
+separate file id.  It is not an error to open a file several times,
+though writing to the same file through several different file ids may
+produce unexpected results.
+
+        <p>The possible values ‘<samp><span class="samp">mode</span></samp>’ may have are
+
+          <dl>
+<dt>‘<samp><span class="samp">r</span></samp>’<dd>Open a file for reading.
+
+          <br><dt>‘<samp><span class="samp">w</span></samp>’<dd>Open a file for writing.  The previous contents are discarded.
+
+          <br><dt>‘<samp><span class="samp">a</span></samp>’<dd>Open or create a file for writing at the end of the file.
+
+          <br><dt>‘<samp><span class="samp">r+</span></samp>’<dd>Open an existing file for reading and writing.
+
+          <br><dt>‘<samp><span class="samp">w+</span></samp>’<dd>Open a file for reading or writing.  The previous contents are
+discarded.
+
+          <br><dt>‘<samp><span class="samp">a+</span></samp>’<dd>Open or create a file for reading or writing at the end of the
+file. 
+</dl>
+
+        <p>Append a "t" to the mode string to open the file in text mode or a
+"b" to open in binary mode.  On Windows and Macintosh systems, text
+mode reading and writing automatically converts linefeeds to the
+appropriate line end character for the system (carriage-return linefeed
+on Windows, carriage-return on Macintosh).  The default if no mode is
+specified is binary mode.
+
+        <p>Additionally, you may append a "z" to the mode string to open a
+gzipped file for reading or writing.  For this to be successful, you
+must also open the file in binary mode.
+
+        <p>The parameter <var>arch</var> is a string specifying the default data format
+for the file.  Valid values for <var>arch</var> are:
+
+          <dl>
+‘<samp><span class="samp">native</span></samp>’
+The format of the current machine (this is the default).
+
+          <p>‘<samp><span class="samp">ieee-be</span></samp>’
+IEEE big endian format.
+
+          <p>‘<samp><span class="samp">ieee-le</span></samp>’
+IEEE little endian format.
+
+          <p>‘<samp><span class="samp">vaxd</span></samp>’
+VAX D floating format.
+
+          <p>‘<samp><span class="samp">vaxg</span></samp>’
+VAX G floating format.
+
+          <p>‘<samp><span class="samp">cray</span></samp>’
+Cray floating format. 
+</dl>
+
+     <p class="noindent">however, conversions are currently only supported for ‘<samp><span class="samp">native</span></samp>’
+‘<samp><span class="samp">ieee-be</span></samp>’, and ‘<samp><span class="samp">ieee-le</span></samp>’ formats. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>, <a href="doc_002dfgets.html#doc_002dfgets">fgets</a>, <a href="doc_002dfputs.html#doc_002dfputs">fputs</a>, <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfseek.html#doc_002dfseek">fseek</a>, <a href="doc_002dferror.html#doc_002dferror">ferror</a>, <a href="doc_002dfprintf.html#doc_002dfprintf">fprintf</a>, <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>, <a href="doc_002dftell.html#doc_002dftell">ftell</a>, <a href="doc_002dfwrite.html#doc_002dfwrite">fwrite</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfclose"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fclose</b> (<var>fid</var>)<var><a name="index-fclose-776"></a></var><br>
+<blockquote><p>Closes the specified file.  If successful, <code>fclose</code> returns 0,
+otherwise, it returns -1. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfseek.html#doc_002dfseek">fseek</a>, <a href="doc_002dftell.html#doc_002dftell">ftell</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Operator-Index.html b/doc/interpreter/HTML/Operator-Index.html
new file mode 100644
index 0000000..056b2b5
--- /dev/null
+++ b/doc/interpreter/HTML/Operator-Index.html
@@ -0,0 +1,84 @@
+<html lang="en">
+<head>
+<title>Operator Index - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Function-Index.html#Function-Index" title="Function Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Operator-Index"></a>
+Previous: <a rel="previous" accesskey="p" href="Function-Index.html#Function-Index">Function Index</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Operator Index</h2>
+
+
+
+<ul class="index-op" compact>
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#index-g_t_0021-522">!</a>: <a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_0021_003d-503">!=</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Strings.html#index-g_t_0022-281">"</a>: <a href="Strings.html#Strings">Strings</a></li>
+<li><a href="String-Objects.html#index-g_t_0022-193">"</a>: <a href="String-Objects.html#String-Objects">String Objects</a></li>
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#index-g_t_0026-519">&</a>: <a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a></li>
+<li><a href="Short_002dcircuit-Boolean-Operators.html#index-g_t_0026_0026-524">&&</a>: <a href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">Short-circuit Boolean Operators</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_0027-487">'</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Strings.html#index-g_t_0027-282">'</a>: <a href="Strings.html#Strings">Strings</a></li>
+<li><a href="String-Objects.html#index-g_t_0027-194">'</a>: <a href="String-Objects.html#String-Objects">String Objects</a></li>
+<li><a href="Index-Expressions.html#index-g_t_0028-448">(</a>: <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a></li>
+<li><a href="Index-Expressions.html#index-g_t_0029-449">)</a>: <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002a-475">*</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002a_002a-481">**</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Assignment-Ops.html#index-g_t_002a_003d-535">*=</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002b-472">+</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Increment-Ops.html#index-g_t_002b_002b-541">++</a>: <a href="Increment-Ops.html#Increment-Ops">Increment Ops</a></li>
+<li><a href="Assignment-Ops.html#index-g_t_002b_003d-533">+=</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Matrices.html#index-g_t_002c-220">,</a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002d-474">-</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Increment-Ops.html#index-g_t_0040code_007b_002d_002d_007d-542"><code>--</code></a>: <a href="Increment-Ops.html#Increment-Ops">Increment Ops</a></li>
+<li><a href="Assignment-Ops.html#index-g_t_002d_003d-534">-=</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_0027-488">.'</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_002a-476">.*</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_002a_002a-483">.**</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_002b-473">.+</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_002f-478">./</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_005c-480">.\</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002e_005e-484">.^</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_002f-477">/</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Assignment-Ops.html#index-g_t_002f_003d-536">/=</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Matrices.html#index-g_t_003b-219">;</a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_003c-498"><</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_003c_003d-499"><=</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Assignment-Ops.html#index-g_t_003d-530">=</a>: <a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_003d_003d-500">==</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_003e-502">></a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_003e_003d-501">>=</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+<li><a href="Matrices.html#index-g_t_005b-217">[</a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_005c-479">\</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Matrices.html#index-g_t_005d-218">]</a>: <a href="Matrices.html#Matrices">Matrices</a></li>
+<li><a href="Arithmetic-Ops.html#index-g_t_005e-482">^</a>: <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a></li>
+<li><a href="Ranges.html#index-colon-233">colon</a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#index-g_t_007c-520">|</a>: <a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a></li>
+<li><a href="Short_002dcircuit-Boolean-Operators.html#index-g_t_007c_007c-525">||</a>: <a href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">Short-circuit Boolean Operators</a></li>
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#index-g_t_007e-521">~</a>: <a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a></li>
+<li><a href="Comparison-Ops.html#index-g_t_007e_003d-504">~=</a>: <a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a></li>
+   </ul></body></html>
+
diff --git a/doc/interpreter/HTML/Operator-Overloading.html b/doc/interpreter/HTML/Operator-Overloading.html
new file mode 100644
index 0000000..fee7716
--- /dev/null
+++ b/doc/interpreter/HTML/Operator-Overloading.html
@@ -0,0 +1,83 @@
+<html lang="en">
+<head>
+<title>Operator Overloading - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Overloading-Objects.html#Overloading-Objects" title="Overloading Objects">
+<link rel="prev" href="Function-Overloading.html#Function-Overloading" title="Function Overloading">
+<link rel="next" href="Precedence-of-Objects.html#Precedence-of-Objects" title="Precedence of Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Operator-Overloading"></a>
+Next: <a rel="next" accesskey="n" href="Precedence-of-Objects.html#Precedence-of-Objects">Precedence of Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="Function-Overloading.html#Function-Overloading">Function Overloading</a>,
+Up: <a rel="up" accesskey="u" href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>
+<hr>
+</div>
+
+<h4 class="subsection">33.4.2 Operator Overloading</h4>
+
+<div class="float">
+<a name="tab_003aoverload_005fops"></a>
+<a name="doc_002drdivide"></a><a name="doc_002dplus"></a><a name="doc_002dminus"></a><a name="doc_002duminus"></a><a name="doc_002duplus"></a><a name="doc_002dtimes"></a><a name="doc_002dmtimes"></a><a name="doc_002dmrdivide"></a><a name="doc_002dldivide"></a><a name="doc_002dmldivide"></a><a name="doc_002dpower"></a><a name="doc_002dmpower"></a><a name="doc_002dlt"></a><a name="doc_002dle"></a><a name="doc_002dgt"></a><a name="doc_002dge"></a><a name="doc_002deq"></a><a name="doc_002dne"></a><a name="doc_002dand"></a><a name="doc_002dor"></a><a name="doc_002dnot"></a><a name="doc_002dctranspose"></a><a name="doc_002dtranspose"></a>
+   <p><table summary=""><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">Operation </td><td valign="top" width="20%">Method </td><td valign="top" width="40%">Description </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a + b </td><td valign="top" width="20%">plus (a, b) </td><td valign="top" width="40%">Binary addition </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a - b$ </td><td valign="top" width="20%">minus (a, b) </td><td valign="top" width="40%">Binary subtraction operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">+ a$ </td><td valign="top" width="20%">uplus (a) </td><td valign="top" width="40%">Unary addition operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">- a$ </td><td valign="top" width="20%">uminus (a) </td><td valign="top" width="40%">Unary subtraction operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a .* b$ </td><td valign="top" width="20%">times (a, b) </td><td valign="top" width="40%">Element-wise multiplication operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a * b$ </td><td valign="top" width="20%">mtimes (a, b) </td><td valign="top" width="40%">Matrix multiplication operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a ./ b$ </td><td valign="top" width="20%">rdivide (a, b) </td><td valign="top" width="40%">Element-wise right division operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a / b$ </td><td valign="top" width="20%">mrdivide (a, b) </td><td valign="top" width="40%">Matrix right division operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a .\ b$ </td><td valign="top" width="20%">ldivide (a, b) </td><td valign="top" width="40%">Element-wise left division operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a \ b$ </td><td valign="top" width="20%">mldivide (a, b) </td><td valign="top" width="40%">Matrix left division operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a .^ b$ </td><td valign="top" width="20%">ldivide (a, b) </td><td valign="top" width="40%">Element-wise power operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a ^ b$ </td><td valign="top" width="20%">mldivide (a, b) </td><td valign="top" width="40%">Matrix power operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a < b$ </td><td valign="top" width="20%">lt (a, b) </td><td valign="top" width="40%">Less than operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a <= b$ </td><td valign="top" width="20%">le (a, b) </td><td valign="top" width="40%">Less than or equal to operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a > b$ </td><td valign="top" width="20%">gt (a, b) </td><td valign="top" width="40%">Greater than operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a >= b$ </td><td valign="top" width="20%">ge (a, b) </td><td valign="top" width="40%">Greater than or equal to operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a == b$ </td><td valign="top" width="20%">eq (a, b) </td><td valign="top" width="40%">Equal to operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a != b$ </td><td valign="top" width="20%">ne (a, b) </td><td valign="top" width="40%">Not equal to operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a \& b$ </td><td valign="top" width="20%">and (a, b) </td><td valign="top" width="40%">Logical and operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a | b$ </td><td valign="top" width="20%">or (a, b) </td><td valign="top" width="40%">Logical or operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">! b$ </td><td valign="top" width="20%">not (a) </td><td valign="top" width="40%">Logical not operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a'$ </td><td valign="top" width="20%">ctranspose (a) </td><td valign="top" width="40%">Complex conjugate transpose operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a.'$ </td><td valign="top" width="20%">transpose (a) </td><td valign="top" width="40%">Transpose operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a : b$ </td><td valign="top" width="20%">colon (a, b) </td><td valign="top" width="40%">Two element range operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a : b : c$ </td><td valign="top" width="20%">colon (a, b, c) </td><td valign="top" width="40%">Three element range operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">[a, b]$ </td><td valign="top" width="20%">horzcat (a, b) </td><td valign="top" width="40%">Horizontal concatenation operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">[a; b]$ </td><td valign="top" width="20%">vertcat (a, b) </td><td valign="top" width="40%">Vertical concatenation operator </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a(s_1, \ldots, s_n)$ </td><td valign="top" width="20%">subsref (a, s) </td><td valign="top" width="40%">Subscripted reference </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">a(s_1, \ldots, s_n) = b$ </td><td valign="top" width="20%">subsasgn (a, s, b) </td><td valign="top" width="40%">Subscripted assignment </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%">b (a)$ </td><td valign="top" width="20%">subsindex (a) </td><td valign="top" width="40%">Convert to zero-based index </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="20%"><dfn>display</dfn> </td><td valign="top" width="20%">display (a) </td><td valign="top" width="40%">Commandline display function </td><td valign="top" width="10%">
+   <br></td></tr></table>
+
+<p><strong class="float-caption">Table 33.1: Available overloaded operators and their corresponding class method</strong></p></div>
+
+   <p>An example <code>mtimes</code> method for our polynomial class might look like
+
+<pre class="example"><pre class="verbatim">     function y = mtimes (a, b)
+       y = polynomial (conv (double(a),double(b)));
+     endfunction</pre>
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Operator-Precedence.html b/doc/interpreter/HTML/Operator-Precedence.html
new file mode 100644
index 0000000..a81469f
--- /dev/null
+++ b/doc/interpreter/HTML/Operator-Precedence.html
@@ -0,0 +1,105 @@
+<html lang="en">
+<head>
+<title>Operator Precedence - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Expressions.html#Expressions" title="Expressions">
+<link rel="prev" href="Increment-Ops.html#Increment-Ops" title="Increment Ops">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Operator-Precedence"></a>
+Previous: <a rel="previous" accesskey="p" href="Increment-Ops.html#Increment-Ops">Increment Ops</a>,
+Up: <a rel="up" accesskey="u" href="Expressions.html#Expressions">Expressions</a>
+<hr>
+</div>
+
+<h3 class="section">8.8 Operator Precedence</h3>
+
+<p><a name="index-operator-precedence-545"></a>
+<dfn>Operator precedence</dfn> determines how operators are grouped, when
+different operators appear close by in one expression.  For example,
+‘<samp><span class="samp">*</span></samp>’ has higher precedence than ‘<samp><span class="samp">+</span></samp>’.  Thus, the expression
+<code>a + b * c</code> means to multiply <code>b</code> and <code>c</code>, and then add
+<code>a</code> to the product (i.e., <code>a + (b * c)</code>).
+
+   <p>You can overrule the precedence of the operators by using parentheses. 
+You can think of the precedence rules as saying where the parentheses
+are assumed if you do not write parentheses yourself.  In fact, it is
+wise to use parentheses whenever you have an unusual combination of
+operators, because other people who read the program may not remember
+what the precedence is in this case.  You might forget as well, and then
+you too could make a mistake.  Explicit parentheses will help prevent
+any such mistake.
+
+   <p>When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment and exponentiation
+operators, which group in the opposite order.  Thus, the expression
+<code>a - b + c</code> groups as <code>(a - b) + c</code>, but the expression
+<code>a = b = c</code> groups as <code>a = (b = c)</code>.
+
+   <p>The precedence of prefix unary operators is important when another
+operator follows the operand.  For example, <code>-x^2</code> means
+<code>-(x^2)</code>, because ‘<samp><span class="samp">-</span></samp>’ has lower precedence than ‘<samp><span class="samp">^</span></samp>’.
+
+   <p>Here is a table of the operators in Octave, in order of increasing
+precedence.
+
+     <dl>
+<dt><code>statement separators</code><dd>‘<samp><span class="samp">;</span></samp>’, ‘<samp><span class="samp">,</span></samp>’.
+
+     <br><dt><code>assignment</code><dd>‘<samp><span class="samp">=</span></samp>’, ‘<samp><span class="samp">+=</span></samp>’, ‘<samp><span class="samp">-=</span></samp>’, ‘<samp><span class="samp">*=</span></samp>’,‘<samp><span class="samp">/=</span></samp>’.  This operator
+groups right to left.
+
+     <br><dt><code>logical "or" and "and"</code><dd>‘<samp><span class="samp">||</span></samp>’, ‘<samp><span class="samp">&&</span></samp>’.
+
+     <br><dt><code>element-wise "or" and "and"</code><dd>‘<samp><span class="samp">|</span></samp>’, ‘<samp><span class="samp">&</span></samp>’.
+
+     <br><dt><code>relational</code><dd>‘<samp><span class="samp"><</span></samp>’, ‘<samp><span class="samp"><=</span></samp>’, ‘<samp><span class="samp">==</span></samp>’, ‘<samp><span class="samp">>=</span></samp>’, ‘<samp><span class="samp">></span></samp>’, ‘<samp><span class="samp">!=</span></samp>’,
+‘<samp><span class="samp">~=</span></samp>’.
+
+     <br><dt><code>colon</code><dd>‘<samp><span class="samp">:</span></samp>’.
+
+     <br><dt><code>add, subtract</code><dd>‘<samp><span class="samp">+</span></samp>’, ‘<samp><span class="samp">-</span></samp>’.
+
+     <br><dt><code>multiply, divide</code><dd>‘<samp><span class="samp">*</span></samp>’, ‘<samp><span class="samp">/</span></samp>’, ‘<samp><span class="samp">\</span></samp>’, ‘<samp><span class="samp">.\</span></samp>’, ‘<samp><span class="samp">.*</span></samp>’, ‘<samp><span class="samp">./</span></samp>’.
+
+     <br><dt><code>transpose</code><dd>‘<samp><span class="samp">'</span></samp>’, ‘<samp><span class="samp">.'</span></samp>’
+
+     <br><dt><code>unary plus, minus, increment, decrement, and ``not''</code><dd>‘<samp><span class="samp">+</span></samp>’, ‘<samp><span class="samp">-</span></samp>’, ‘<samp><span class="samp">++</span></samp>’, ‘<samp><span class="samp">--</span></samp>’, ‘<samp><span class="samp">!</span></samp>’, ‘<samp><span class="samp">~</span></samp>’.
+
+     <br><dt><code>exponentiation</code><dd>‘<samp><span class="samp">^</span></samp>’, ‘<samp><span class="samp">**</span></samp>’, ‘<samp><span class="samp">.^</span></samp>’, ‘<samp><span class="samp">.**</span></samp>’. 
+</dl>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Operators-and-Functions.html b/doc/interpreter/HTML/Operators-and-Functions.html
new file mode 100644
index 0000000..7bb9e9b
--- /dev/null
+++ b/doc/interpreter/HTML/Operators-and-Functions.html
@@ -0,0 +1,42 @@
+<html lang="en">
+<head>
+<title>Operators and Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basics.html#Basics" title="Basics">
+<link rel="prev" href="Information.html#Information" title="Information">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Operators-and-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Information.html#Information">Information</a>,
+Up: <a rel="up" accesskey="u" href="Basics.html#Basics">Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">21.1.4 Basic Operators and Functions on Sparse Matrices</h4>
+
+<ul class="menu">
+<li><a accesskey="1" href="Sparse-Functions.html#Sparse-Functions">Sparse Functions</a>
+<li><a accesskey="2" href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions">Return Types of Operators and Functions</a>
+<li><a accesskey="3" href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a>
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Optimization.html b/doc/interpreter/HTML/Optimization.html
new file mode 100644
index 0000000..38c07f1
--- /dev/null
+++ b/doc/interpreter/HTML/Optimization.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Optimization - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Differential-Equations.html#Differential-Equations" title="Differential Equations">
+<link rel="next" href="Statistics.html#Statistics" title="Statistics">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Optimization"></a>
+Next: <a rel="next" accesskey="n" href="Statistics.html#Statistics">Statistics</a>,
+Previous: <a rel="previous" accesskey="p" href="Differential-Equations.html#Differential-Equations">Differential Equations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">24 Optimization</h2>
+
+<p>Octave comes with support for solving various kinds of optimization
+problems.  Specifically Octave can solve problems in Linear Programming,
+Quadratic Programming, Nonlinear Programming, and Linear Least Squares
+Minimization.
+
+<ul class="menu">
+<li><a accesskey="1" href="Linear-Programming.html#Linear-Programming">Linear Programming</a>
+<li><a accesskey="2" href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>
+<li><a accesskey="3" href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>
+<li><a accesskey="4" href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a>
+</ul>
+
+<!-- @cindex linear programming -->
+   <p><a name="index-quadratic-programming-1795"></a><a name="index-nonlinear-programming-1796"></a><a name="index-optimization-1797"></a><a name="index-LP-1798"></a><a name="index-QP-1799"></a><a name="index-NLP-1800"></a>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Ordinary-Differential-Equations.html b/doc/interpreter/HTML/Ordinary-Differential-Equations.html
new file mode 100644
index 0000000..aea921f
--- /dev/null
+++ b/doc/interpreter/HTML/Ordinary-Differential-Equations.html
@@ -0,0 +1,200 @@
+<html lang="en">
+<head>
+<title>Ordinary Differential Equations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Differential-Equations.html#Differential-Equations" title="Differential Equations">
+<link rel="next" href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations" title="Differential-Algebraic Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Ordinary-Differential-Equations"></a>
+Next: <a rel="next" accesskey="n" href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a>,
+Up: <a rel="up" accesskey="u" href="Differential-Equations.html#Differential-Equations">Differential Equations</a>
+<hr>
+</div>
+
+<h3 class="section">23.1 Ordinary Differential Equations</h3>
+
+<p>The function <code>lsode</code> can be used to solve ODEs of the form
+
+<pre class="example">     dx
+     -- = f (x, t)
+     dt
+</pre>
+   <p class="noindent">using Hindmarsh's ODE solver <span class="sc">Lsode</span>.
+
+<!-- ./DLD-FUNCTIONS/lsode.cc -->
+   <p><a name="doc_002dlsode"></a>
+
+<div class="defun">
+— Loadable Function: [<var>x</var>, <var>istate</var>, <var>msg</var>] = <b>lsode</b> (<var>fcn, x_0, t, t_crit</var>)<var><a name="index-lsode-1786"></a></var><br>
+<blockquote><p>Solve the set of differential equations
+
+     <pre class="example">          dx
+          -- = f(x, t)
+          dt
+</pre>
+        <p>with
+
+     <pre class="example">          x(t_0) = x_0
+</pre>
+        <p>The solution is returned in the matrix <var>x</var>, with each row
+corresponding to an element of the vector <var>t</var>.  The first element
+of <var>t</var> should be t_0 and should correspond to the initial
+state of the system <var>x_0</var>, so that the first row of the output
+is <var>x_0</var>.
+
+        <p>The first argument, <var>fcn</var>, is a string, inline, or function handle
+that names the function f to call to compute the vector of right
+hand sides for the set of equations.  The function must have the form
+
+     <pre class="example">          <var>xdot</var> = f (<var>x</var>, <var>t</var>)
+</pre>
+        <p class="noindent">in which <var>xdot</var> and <var>x</var> are vectors and <var>t</var> is a scalar.
+
+        <p>If <var>fcn</var> is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function f described above, and the second element names a
+function to compute the Jacobian of f.  The Jacobian function
+must have the form
+
+     <pre class="example">          <var>jac</var> = j (<var>x</var>, <var>t</var>)
+</pre>
+        <p>in which <var>jac</var> is the matrix of partial derivatives
+
+     <pre class="example">                       | df_1  df_1       df_1 |
+                       | ----  ----  ...  ---- |
+                       | dx_1  dx_2       dx_N |
+                       |                       |
+                       | df_2  df_2       df_2 |
+                       | ----  ----  ...  ---- |
+                df_i   | dx_1  dx_2       dx_N |
+          jac = ---- = |                       |
+                dx_j   |  .    .     .    .    |
+                       |  .    .      .   .    |
+                       |  .    .       .  .    |
+                       |                       |
+                       | df_N  df_N       df_N |
+                       | ----  ----  ...  ---- |
+                       | dx_1  dx_2       dx_N |
+</pre>
+        <p>The second and third arguments specify the initial state of the system,
+x_0, and the initial value of the independent variable t_0.
+
+        <p>The fourth argument is optional, and may be used to specify a set of
+times that the ODE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+        <p>After a successful computation, the value of <var>istate</var> will be 2
+(consistent with the Fortran version of <span class="sc">Lsode</span>).
+
+        <p>If the computation is not successful, <var>istate</var> will be something
+other than 2 and <var>msg</var> will contain additional information.
+
+        <p>You can use the function <code>lsode_options</code> to set optional
+parameters for <code>lsode</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddaspk.html#doc_002ddaspk">daspk</a>, <a href="doc_002ddassl.html#doc_002ddassl">dassl</a>, <a href="doc_002ddasrt.html#doc_002ddasrt">dasrt</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/lsode.cc -->
+   <p><a name="doc_002dlsode_005foptions"></a>
+
+<div class="defun">
+— Loadable Function:  <b>lsode_options</b> (<var>opt, val</var>)<var><a name="index-lsode_005foptions-1787"></a></var><br>
+<blockquote><p>When called with two arguments, this function
+allows you set options parameters for the function <code>lsode</code>. 
+Given one argument, <code>lsode_options</code> returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+        <p>Options include
+
+          <dl>
+<dt><code>"absolute tolerance"</code><dd>Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector. 
+<br><dt><code>"relative tolerance"</code><dd>Relative tolerance parameter.  Unlike the absolute tolerance, this
+parameter may only be a scalar.
+
+          <p>The local error test applied at each integration step is
+
+          <pre class="example">                 abs (local error in x(i)) <= ...
+                     rtol * abs (y(i)) + atol(i)
+</pre>
+          <br><dt><code>"integration method"</code><dd>A string specifying the method of integration to use to solve the ODE
+system.  Valid values are
+
+               <dl>
+<dt>"adams"<dt>"non-stiff"<dd>No Jacobian used (even if it is available). 
+<br><dt>"bdf"<br><dt>"stiff"<dd>Use stiff backward differentiation formula (BDF) method.  If a
+function to compute the Jacobian is not supplied, <code>lsode</code> will
+compute a finite difference approximation of the Jacobian matrix. 
+</dl>
+          <br><dt><code>"initial step size"</code><dd>The step size to be attempted on the first step (default is determined
+automatically). 
+<br><dt><code>"maximum order"</code><dd>Restrict the maximum order of the solution method.  If using the Adams
+method, this option must be between 1 and 12.  Otherwise, it must be
+between 1 and 5, inclusive. 
+<br><dt><code>"maximum step size"</code><dd>Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified). 
+<br><dt><code>"minimum step size"</code><dd>The minimum absolute step size allowed (default is 0). 
+<br><dt><code>"step limit"</code><dd>Maximum number of steps allowed (default is 100000). 
+</dl>
+        </p></blockquote></div>
+
+   <p>Here is an example of solving a set of three differential equations using
+<code>lsode</code>.  Given the function
+
+   <p><a name="index-oregonator-1788"></a>
+<pre class="example">     function xdot = f (x, t)
+     
+       xdot = zeros (3,1);
+     
+       xdot(1) = 77.27 * (x(2) - x(1)*x(2) + x(1) \
+                 - 8.375e-06*x(1)^2);
+       xdot(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
+       xdot(3) = 0.161*(x(1) - x(3));
+     
+     endfunction
+</pre>
+   <p class="noindent">and the initial condition <code>x0 = [ 4; 1.1; 4 ]</code>, the set of
+equations can be integrated using the command
+
+<pre class="example">     t = linspace (0, 500, 1000);
+     
+     y = lsode ("f", x0, t);
+</pre>
+   <p>If you try this, you will see that the value of the result changes
+dramatically between <var>t</var> = 0 and 5, and again around <var>t</var> = 305. 
+A more efficient set of output points might be
+
+<pre class="example">     t = [0, logspace (-1, log10(303), 150), \
+             logspace (log10(304), log10(500), 150)];
+</pre>
+   <p>See Alan C. Hindmarsh, <cite>ODEPACK, A Systematized Collection of ODE
+Solvers</cite>, in Scientific Computing, R. S. Stepleman, editor, (1983) for
+more information about the inner workings of <code>lsode</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Organization-of-Functions.html b/doc/interpreter/HTML/Organization-of-Functions.html
new file mode 100644
index 0000000..c877f3a
--- /dev/null
+++ b/doc/interpreter/HTML/Organization-of-Functions.html
@@ -0,0 +1,111 @@
+<html lang="en">
+<head>
+<title>Organization of Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Commands.html#Commands" title="Commands">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Organization-of-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Commands.html#Commands">Commands</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.11 Organization of Functions Distributed with Octave</h3>
+
+<p>Many of Octave's standard functions are distributed as function files. 
+They are loosely organized by topic, in subdirectories of
+<samp><var>octave-home</var><span class="file">/lib/octave/</span><var>version</var><span class="file">/m</span></samp>, to make it easier
+to find them.
+
+   <p>The following is a list of all the function file subdirectories, and the
+types of functions you will find there.
+
+     <dl>
+<dt><samp><span class="file">audio</span></samp><dd>Functions for playing and recording sounds.
+
+     <br><dt><samp><span class="file">control</span></samp><dd>Functions for design and simulation of automatic control systems.
+
+     <br><dt><samp><span class="file">elfun</span></samp><dd>Elementary functions.
+
+     <br><dt><samp><span class="file">finance</span></samp><dd>Functions for computing interest payments, investment values, and rates
+of return.
+
+     <br><dt><samp><span class="file">general</span></samp><dd>Miscellaneous matrix manipulations, like <code>flipud</code>, <code>rot90</code>,
+and <code>triu</code>, as well as other basic functions, like
+<code>ismatrix</code>, <code>nargchk</code>, etc.
+
+     <br><dt><samp><span class="file">image</span></samp><dd>Image processing tools.  These functions require the X Window System.
+
+     <br><dt><samp><span class="file">io</span></samp><dd>Input-output functions.
+
+     <br><dt><samp><span class="file">linear-algebra</span></samp><dd>Functions for linear algebra.
+
+     <br><dt><samp><span class="file">miscellaneous</span></samp><dd>Functions that don't really belong anywhere else.
+
+     <br><dt><samp><span class="file">optimization</span></samp><dd>Minimization of functions.
+
+     <br><dt><samp><span class="file">path</span></samp><dd>Functions to manage the directory path Octave uses to find functions.
+
+     <br><dt><samp><span class="file">pkg</span></samp><dd>Install external packages of functions in Octave.
+
+     <br><dt><samp><span class="file">plot</span></samp><dd>Functions for displaying and printing two- and three-dimensional graphs.
+
+     <br><dt><samp><span class="file">polynomial</span></samp><dd>Functions for manipulating polynomials.
+
+     <br><dt><samp><span class="file">set</span></samp><dd>Functions for creating and manipulating sets of unique values.
+
+     <br><dt><samp><span class="file">signal</span></samp><dd>Functions for signal processing applications.
+
+     <br><dt><samp><span class="file">sparse</span></samp><dd>Functions for handling sparse matrices.
+
+     <br><dt><samp><span class="file">specfun</span></samp><dd>Special functions.
+
+     <br><dt><samp><span class="file">special-matrix</span></samp><dd>Functions that create special matrix forms.
+
+     <br><dt><samp><span class="file">startup</span></samp><dd>Octave's system-wide startup file.
+
+     <br><dt><samp><span class="file">statistics</span></samp><dd>Statistical functions.
+
+     <br><dt><samp><span class="file">strings</span></samp><dd>Miscellaneous string-handling functions.
+
+     <br><dt><samp><span class="file">testfun</span></samp><dd>Perform unit tests on other functions.
+
+     <br><dt><samp><span class="file">time</span></samp><dd>Functions related to time keeping. 
+</dl>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Orthogonal-Collocation.html b/doc/interpreter/HTML/Orthogonal-Collocation.html
new file mode 100644
index 0000000..e8660e5
--- /dev/null
+++ b/doc/interpreter/HTML/Orthogonal-Collocation.html
@@ -0,0 +1,69 @@
+<html lang="en">
+<head>
+<title>Orthogonal Collocation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numerical-Integration.html#Numerical-Integration" title="Numerical Integration">
+<link rel="prev" href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables" title="Functions of Multiple Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Orthogonal-Collocation"></a>
+Previous: <a rel="previous" accesskey="p" href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">Functions of Multiple Variables</a>,
+Up: <a rel="up" accesskey="u" href="Numerical-Integration.html#Numerical-Integration">Numerical Integration</a>
+<hr>
+</div>
+
+<h3 class="section">22.2 Orthogonal Collocation</h3>
+
+<!-- ./DLD-FUNCTIONS/colloc.cc -->
+<p><a name="doc_002dcolloc"></a>
+
+<div class="defun">
+— Loadable Function: [<var>r</var>, <var>amat</var>, <var>bmat</var>, <var>q</var>] = <b>colloc</b> (<var>n, "left", "right"</var>)<var><a name="index-colloc-1780"></a></var><br>
+<blockquote><p>Compute derivative and integral weight matrices for orthogonal
+collocation using the subroutines given in J. Villadsen and
+M. L. Michelsen, <cite>Solution of Differential Equation Models by
+Polynomial Approximation</cite>. 
+</p></blockquote></div>
+
+   <p>Here is an example of using <code>colloc</code> to generate weight matrices
+for solving the second order differential equation
+<var>u</var>' - <var>alpha</var> * <var>u</var>” = 0 with the boundary conditions
+<var>u</var>(0) = 0 and <var>u</var>(1) = 1.
+
+   <p>First, we can generate the weight matrices for <var>n</var> points (including
+the endpoints of the interval), and incorporate the boundary conditions
+in the right hand side (for a specific value of
+<var>alpha</var>).
+
+<pre class="example">     n = 7;
+     alpha = 0.1;
+     [r, a, b] = colloc (n-2, "left", "right");
+     at = a(2:n-1,2:n-1);
+     bt = b(2:n-1,2:n-1);
+     rhs = alpha * b(2:n-1,n) - a(2:n-1,n);
+</pre>
+   <p>Then the solution at the roots <var>r</var> is
+
+<pre class="example">     u = [ 0; (at - alpha * bt) \ rhs; 1]
+           [ 0.00; 0.004; 0.01 0.00; 0.12; 0.62; 1.00 ]
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Other-Output-Conversions.html b/doc/interpreter/HTML/Other-Output-Conversions.html
new file mode 100644
index 0000000..5fe8222
--- /dev/null
+++ b/doc/interpreter/HTML/Other-Output-Conversions.html
@@ -0,0 +1,61 @@
+<html lang="en">
+<head>
+<title>Other Output Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions" title="Floating-Point Conversions">
+<link rel="next" href="Formatted-Input.html#Formatted-Input" title="Formatted Input">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Other-Output-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Formatted-Input.html#Formatted-Input">Formatted Input</a>,
+Previous: <a rel="previous" accesskey="p" href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.10 Other Output Conversions</h4>
+
+<p>This section describes miscellaneous conversions for <code>printf</code>.
+
+   <p>The ‘<samp><span class="samp">%c</span></samp>’ conversion prints a single character.  The ‘<samp><span class="samp">-</span></samp>’
+flag can be used to specify left-justification in the field, but no
+other flags are defined, and no precision or type modifier can be given. 
+For example:
+
+<pre class="example">     printf ("%c%c%c%c%c", "h", "e", "l", "l", "o");
+</pre>
+   <p class="noindent">prints ‘<samp><span class="samp">hello</span></samp>’.
+
+   <p>The ‘<samp><span class="samp">%s</span></samp>’ conversion prints a string.  The corresponding argument
+must be a string.  A precision can be specified to indicate the maximum
+number of characters to write; otherwise characters in the string up to
+but not including the terminating null character are written to the
+output stream.  The ‘<samp><span class="samp">-</span></samp>’ flag can be used to specify
+left-justification in the field, but no other flags or type modifiers
+are defined for this conversion.  For example:
+
+<pre class="example">     printf ("%3s%-6s", "no", "where");
+</pre>
+   <p class="noindent">prints ‘<samp><span class="samp"> nowhere </span></samp>’ (note the leading and trailing spaces).
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Other-Sources.html b/doc/interpreter/HTML/Other-Sources.html
new file mode 100644
index 0000000..1c37bc7
--- /dev/null
+++ b/doc/interpreter/HTML/Other-Sources.html
@@ -0,0 +1,81 @@
+<html lang="en">
+<head>
+<title>Other Sources - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link rel="prev" href="C_002b_002b-Sources.html#C_002b_002b-Sources" title="C++ Sources">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Other-Sources"></a>
+Previous: <a rel="previous" accesskey="p" href="C_002b_002b-Sources.html#C_002b_002b-Sources">C++ Sources</a>,
+Up: <a rel="up" accesskey="u" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>
+<hr>
+</div>
+
+<h3 class="section">D.5 Other Sources</h3>
+
+<p>Apart from C++ and Octave language (m-files), Octave's sources include files
+written in C, Fortran, M4, perl, unix shell, AWK, texinfo and TeX.  There are
+not many rules to follow when using these other languages; some of them are
+summarized below.  In any case, the golden rule is: if you modify a source
+file, try to follow any conventions you can detect in the file or other similar
+files.
+
+   <p>For C you should obviously follow all C++ rules that can apply.
+
+   <p>If you happen to modify a Fortran file, you should stay within Fortran 77
+with common extensions like <code>END DO</code>.  Currently, we want all sources
+to be compilable with the f2c and g77 compilers, without special flags if
+possible.  This usually means that non-legacy compilers also accept the sources.
+
+   <p>The M4 macro language is mainly used for autoconf configuration files.  You should
+follow normal M4 rules when contributing to these files.  Some M4 files come
+from external source, namely the Autoconf archive
+<a href="http://autoconf-archive.cryp.to">http://autoconf-archive.cryp.to</a>.
+
+   <p>If you give a code example in the documentation written in texinfo with the
+<code>@example</code> environment, you should be aware that the text within such an
+environment will not be wrapped.  It is recommended that you keep the lines
+short enough to fit on pages in the generated pdf or ps documents.  Here is a
+ruler (in an <code>@example</code> environment) for finding the appropriate line
+width:
+
+<pre class="example">              1         2         3         4         5         6
+     123456789012345678901234567890123456789012345678901234567890
+</pre>
+   <!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2007, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+<!-- The text of this file appears in the file BUGS in the Octave -->
+<!-- distribution, as well as in the Octave manual. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Output-Conversion-Syntax.html b/doc/interpreter/HTML/Output-Conversion-Syntax.html
new file mode 100644
index 0000000..3295965
--- /dev/null
+++ b/doc/interpreter/HTML/Output-Conversion-Syntax.html
@@ -0,0 +1,100 @@
+<html lang="en">
+<head>
+<title>Output Conversion Syntax - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices" title="Output Conversion for Matrices">
+<link rel="next" href="Table-of-Output-Conversions.html#Table-of-Output-Conversions" title="Table of Output Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Output-Conversion-Syntax"></a>
+Next: <a rel="next" accesskey="n" href="Table-of-Output-Conversions.html#Table-of-Output-Conversions">Table of Output Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices">Output Conversion for Matrices</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.6 Output Conversion Syntax</h4>
+
+<p>This section provides details about the precise syntax of conversion
+specifications that can appear in a <code>printf</code> template
+string.
+
+   <p>Characters in the template string that are not part of a
+conversion specification are printed as-is to the output stream.
+
+   <p>The conversion specifications in a <code>printf</code> template string have
+the general form:
+
+<pre class="example">     % <var>flags</var> <var>width</var> <span class="roman">[</span> . <var>precision</var> <span class="roman">]</span> <var>type</var> <var>conversion</var>
+</pre>
+   <p>For example, in the conversion specifier ‘<samp><span class="samp">%-10.8ld</span></samp>’, the ‘<samp><span class="samp">-</span></samp>’
+is a flag, ‘<samp><span class="samp">10</span></samp>’ specifies the field width, the precision is
+‘<samp><span class="samp">8</span></samp>’, the letter ‘<samp><span class="samp">l</span></samp>’ is a type modifier, and ‘<samp><span class="samp">d</span></samp>’ specifies
+the conversion style.  (This particular type specifier says to print a
+numeric argument in decimal notation, with a minimum of 8 digits
+left-justified in a field at least 10 characters wide.)
+
+   <p>In more detail, output conversion specifications consist of an
+initial ‘<samp><span class="samp">%</span></samp>’ character followed in sequence by:
+
+     <ul>
+<li>Zero or more <dfn>flag characters</dfn> that modify the normal behavior of
+the conversion specification. 
+<a name="index-flag-character-_0028_0040code_007bprintf_007d_0029-785"></a>
+<li>An optional decimal integer specifying the <dfn>minimum field width</dfn>. 
+If the normal conversion produces fewer characters than this, the field
+is padded with spaces to the specified width.  This is a <em>minimum</em>
+value; if the normal conversion produces more characters than this, the
+field is <em>not</em> truncated.  Normally, the output is right-justified
+within the field. 
+<a name="index-minimum-field-width-_0028_0040code_007bprintf_007d_0029-786"></a>
+You can also specify a field width of ‘<samp><span class="samp">*</span></samp>’.  This means that the
+next argument in the argument list (before the actual value to be
+printed) is used as the field width.  The value is rounded to the
+nearest integer.  If the value is negative, this means to set the
+‘<samp><span class="samp">-</span></samp>’ flag (see below) and to use the absolute value as the field
+width.
+
+     <li>An optional <dfn>precision</dfn> to specify the number of digits to be
+written for the numeric conversions.  If the precision is specified, it
+consists of a period (‘<samp><span class="samp">.</span></samp>’) followed optionally by a decimal integer
+(which defaults to zero if omitted). 
+<a name="index-precision-_0028_0040code_007bprintf_007d_0029-787"></a>
+You can also specify a precision of ‘<samp><span class="samp">*</span></samp>’.  This means that the next
+argument in the argument list (before the actual value to be printed) is
+used as the precision.  The value must be an integer, and is ignored
+if it is negative.
+
+     <li>An optional <dfn>type modifier character</dfn>.  This character is ignored by
+Octave's <code>printf</code> function, but is recognized to provide
+compatibility with the C language <code>printf</code>.
+
+     <li>A character that specifies the conversion to be applied. 
+</ul>
+
+   <p>The exact options that are permitted and how they are interpreted vary
+between the different conversion specifiers.  See the descriptions of the
+individual conversions for information about the particular options that
+they use.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Output-Conversion-for-Matrices.html b/doc/interpreter/HTML/Output-Conversion-for-Matrices.html
new file mode 100644
index 0000000..56eacb9
--- /dev/null
+++ b/doc/interpreter/HTML/Output-Conversion-for-Matrices.html
@@ -0,0 +1,61 @@
+<html lang="en">
+<head>
+<title>Output Conversion for Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Formatted-Output.html#Formatted-Output" title="Formatted Output">
+<link rel="next" href="Output-Conversion-Syntax.html#Output-Conversion-Syntax" title="Output Conversion Syntax">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Output-Conversion-for-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a>,
+Previous: <a rel="previous" accesskey="p" href="Formatted-Output.html#Formatted-Output">Formatted Output</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.5 Output Conversion for Matrices</h4>
+
+<p>When given a matrix value, Octave's formatted output functions cycle
+through the format template until all the values in the matrix have been
+printed.  For example,
+
+<pre class="example">     printf ("%4.2f %10.2e %8.4g\n", hilb (3));
+     
+          -| 1.00   5.00e-01   0.3333
+          -| 0.50   3.33e-01     0.25
+          -| 0.33   2.50e-01      0.2
+</pre>
+   <p>If more than one value is to be printed in a single call, the output
+functions do not return to the beginning of the format template when
+moving on from one value to the next.  This can lead to confusing output
+if the number of elements in the matrices are not exact multiples of the
+number of conversions in the format template.  For example,
+
+<pre class="example">     printf ("%4.2f %10.2e %8.4g\n", [1, 2], [3, 4]);
+     
+          -| 1.00   2.00e+00        3
+          -| 4.00
+</pre>
+   <p>If this is not what you want, use a series of calls instead of just one.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Overloading-Objects.html b/doc/interpreter/HTML/Overloading-Objects.html
new file mode 100644
index 0000000..df7241e
--- /dev/null
+++ b/doc/interpreter/HTML/Overloading-Objects.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Overloading Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link rel="prev" href="Indexing-Objects.html#Indexing-Objects" title="Indexing Objects">
+<link rel="next" href="Inheritance-and-Aggregation.html#Inheritance-and-Aggregation" title="Inheritance and Aggregation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Overloading-Objects"></a>
+Next: <a rel="next" accesskey="n" href="Inheritance-and-Aggregation.html#Inheritance-and-Aggregation">Inheritance and Aggregation</a>,
+Previous: <a rel="previous" accesskey="p" href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a>,
+Up: <a rel="up" accesskey="u" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>
+<hr>
+</div>
+
+<h3 class="section">33.4 Overloading Objects</h3>
+
+<ul class="menu">
+<li><a accesskey="1" href="Function-Overloading.html#Function-Overloading">Function Overloading</a>
+<li><a accesskey="2" href="Operator-Overloading.html#Operator-Overloading">Operator Overloading</a>
+<li><a accesskey="3" href="Precedence-of-Objects.html#Precedence-of-Objects">Precedence of Objects</a>
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Overloading-and-Autoloading.html b/doc/interpreter/HTML/Overloading-and-Autoloading.html
new file mode 100644
index 0000000..b318cbe
--- /dev/null
+++ b/doc/interpreter/HTML/Overloading-and-Autoloading.html
@@ -0,0 +1,142 @@
+<html lang="en">
+<head>
+<title>Overloading and Autoloading - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="prev" href="Private-Functions.html#Private-Functions" title="Private Functions">
+<link rel="next" href="Function-Locking.html#Function-Locking" title="Function Locking">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Overloading-and-Autoloading"></a>
+Next: <a rel="next" accesskey="n" href="Function-Locking.html#Function-Locking">Function Locking</a>,
+Previous: <a rel="previous" accesskey="p" href="Private-Functions.html#Private-Functions">Private Functions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Files.html#Function-Files">Function Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.7.4 Overloading and Autoloading</h4>
+
+<p>The <code>dispatch</code> function can be used to alias one function name to
+another.  It can be used to alias all calls to a particular function name
+to another function, or the alias can be limited to only a particular
+variable type.  Consider the example
+
+<pre class="example">     function y = spsin (x)
+       printf ("Calling spsin\n");
+       fflush(stdout);
+       y = spfun ("sin", x);
+     endfunction
+     
+     dispatch ("sin", "spsin", "sparse matrix");
+     y0 = sin(eye(3));
+     y1 = sin(speye(3));
+</pre>
+   <p class="noindent">which aliases the user-defined function <code>spsin</code> to <code>sin</code>, but only for real sparse
+matrices.  Note that the builtin <code>sin</code> already correctly treats
+sparse matrices and so this example is only illustrative.
+
+<!-- ./DLD-FUNCTIONS/dispatch.cc -->
+   <p><a name="doc_002ddispatch"></a>
+
+<div class="defun">
+— Loadable Function:  <b>dispatch</b> (<var>f, r, type</var>)<var><a name="index-dispatch-636"></a></var><br>
+<blockquote>
+        <p>Replace the function <var>f</var> with a dispatch so that function <var>r</var>
+is called when <var>f</var> is called with the first argument of the named
+<var>type</var>.  If the type is <var>any</var> then call <var>r</var> if no other type
+matches.  The original function <var>f</var> is accessible using
+<code>builtin (</code><var>f</var><code>, ...)</code>.
+
+        <p>If <var>r</var> is omitted, clear dispatch function associated with <var>type</var>.
+
+        <p>If both <var>r</var> and <var>type</var> are omitted, list dispatch functions
+for <var>f</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbuiltin.html#doc_002dbuiltin">builtin</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dispatch.cc -->
+   <p><a name="doc_002dbuiltin"></a>
+
+<div class="defun">
+— Loadable Function: [<small class="dots">...</small>] <b>builtin</b> (<var>f, <small class="dots">...</small></var>)<var><a name="index-builtin-637"></a></var><br>
+<blockquote><p>Call the base function <var>f</var> even if <var>f</var> is overloaded to
+some other function for the given type signature. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddispatch.html#doc_002ddispatch">dispatch</a>. 
+</p></blockquote></div>
+
+   <p>A single dynamically linked file might define several
+functions.  However, as Octave searches for functions based on the
+functions filename, Octave needs a manner in which to find each of the
+functions in the dynamically linked file.  On operating systems that
+support symbolic links, it is possible to create a symbolic link to the
+original file for each of the functions which it contains.
+
+   <p>However, there is at least one well known operating system that doesn't
+support symbolic links.  Making copies of the original file for each of
+the functions is undesirable as it increases the
+amount of disk space used by Octave.  Instead Octave supplies the
+<code>autoload</code> function, that permits the user to define in which
+file a certain function will be found.
+
+<!-- parse.cc -->
+   <p><a name="doc_002dautoload"></a>
+
+<div class="defun">
+— Built-in Function:  <b>autoload</b> (<var>function, file</var>)<var><a name="index-autoload-638"></a></var><br>
+<blockquote><p>Define <var>function</var> to autoload from <var>file</var>.
+
+        <p>The second argument, <var>file</var>, should be an absolute file name or
+a file name in the same directory as the function or script from which
+the autoload command was run.  <var>file</var> should not depend on the
+Octave load path.
+
+        <p>Normally, calls to <code>autoload</code> appear in PKG_ADD script files that
+are evaluated when a directory is added to the Octave's load path.  To
+avoid having to hardcode directory names in <var>file</var>, if <var>file</var>
+is in the same directory as the PKG_ADD script then
+
+     <pre class="example">          autoload ("foo", "bar.oct");
+</pre>
+        <p>will load the function <code>foo</code> from the file <code>bar.oct</code>.  The above
+when <code>bar.oct</code> is not in the same directory or uses like
+
+     <pre class="example">          autoload ("foo", file_in_loadpath ("bar.oct"))
+</pre>
+        <p class="noindent">are strongly discouraged, as their behavior might be unpredictable.
+
+        <p>With no arguments, return a structure containing the current autoload map. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dPKG_005fADD.html#doc_002dPKG_005fADD">PKG_ADD</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/PKG_005fADD-and-PKG_005fDEL-directives.html b/doc/interpreter/HTML/PKG_005fADD-and-PKG_005fDEL-directives.html
new file mode 100644
index 0000000..ba2f15b
--- /dev/null
+++ b/doc/interpreter/HTML/PKG_005fADD-and-PKG_005fDEL-directives.html
@@ -0,0 +1,80 @@
+<html lang="en">
+<head>
+<title>PKG_ADD and PKG_DEL directives - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Creating-Packages.html#Creating-Packages" title="Creating Packages">
+<link rel="prev" href="The-INDEX-file.html#The-INDEX-file" title="The INDEX file">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="PKG_ADD-and-PKG_DEL-directives"></a>
+<a name="PKG_005fADD-and-PKG_005fDEL-directives"></a>
+Previous: <a rel="previous" accesskey="p" href="The-INDEX-file.html#The-INDEX-file">The INDEX file</a>,
+Up: <a rel="up" accesskey="u" href="Creating-Packages.html#Creating-Packages">Creating Packages</a>
+<hr>
+</div>
+
+<h4 class="subsection">35.4.3 PKG_ADD and PKG_DEL directives</h4>
+
+<p>If the package contains files called <code>PKG_ADD</code><!-- /@w --> or <code>PKG_DEL</code><!-- /@w -->
+the commands in these files will be executed when the package is
+added or removed from the users path.  In some situations such files
+are a bit cumbersome to maintain, so the package manager supports
+automatic creation of such files.  If a source file in the package
+contains a <code>PKG_ADD</code><!-- /@w --> or <code>PKG_DEL</code><!-- /@w --> directive they will be
+added to either the <code>PKG_ADD</code><!-- /@w --> or <code>PKG_DEL</code><!-- /@w --> files.
+
+   <p>In <code>m</code>-files a <code>PKG_ADD</code><!-- /@w --> directive looks like this
+
+<pre class="example">     ## PKG_ADD: some_octave_command
+</pre>
+   <p class="noindent">Such lines should be added before the <code>function</code> keyword. 
+In C++ files a <code>PKG_ADD</code><!-- /@w --> directive looks like this
+
+<pre class="example">     // PKG_ADD: some_octave_command
+</pre>
+   <p class="noindent">In both cases <code>some_octave_command</code> should be replaced by the
+command that should be placed in the <code>PKG_ADD</code><!-- /@w --> file. 
+<code>PKG_DEL</code><!-- /@w --> directives work in the same way, except the <code>PKG_ADD</code><!-- /@w -->
+keyword is replaced with <code>PKG_DEL</code><!-- /@w --> and the commands get added
+to the <code>PKG_DEL</code><!-- /@w --> file.
+
+<!-- maybe add again later, if anyone every writes any really interesting -->
+<!-- fun stuff for Octave. -->
+<!-- @include amuse.texi -->
+<!--  -->
+<!-- Appendices start here. -->
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman -->
+<!-- Copyright (C) 2007 Paul Thomas and Christoph Spiel -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Packages.html b/doc/interpreter/HTML/Packages.html
new file mode 100644
index 0000000..73357be
--- /dev/null
+++ b/doc/interpreter/HTML/Packages.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Packages - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="next" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions" title="Dynamically Linked Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Packages"></a>
+Next: <a rel="next" accesskey="n" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="System-Utilities.html#System-Utilities">System Utilities</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">35 Packages</h2>
+
+<p>Since Octave is Free Software users are encouraged to share their
+programs amongst each other.  To aid this sharing Octave supports the
+installation of extra packages.  The `Octave-Forge' project is a
+community-maintained set of packages that can be downloaded and
+installed in Octave.  At the time of writing the `Octave-Forge' project
+can be found on-line at <a href="http://octave.sourceforge.net">http://octave.sourceforge.net</a>, but
+since the Internet is an ever-changing place this may not be true at
+the time of reading.  Therefore it is recommended to see the Octave
+website for an updated reference.
+
+<ul class="menu">
+<li><a accesskey="1" href="Installing-and-Removing-Packages.html#Installing-and-Removing-Packages">Installing and Removing Packages</a>
+<li><a accesskey="2" href="Using-Packages.html#Using-Packages">Using Packages</a>
+<li><a accesskey="3" href="Administrating-Packages.html#Administrating-Packages">Administrating Packages</a>
+<li><a accesskey="4" href="Creating-Packages.html#Creating-Packages">Creating Packages</a>
+</ul>
+
+   <p><a name="index-pkg-2465"></a>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Paging-Screen-Output.html b/doc/interpreter/HTML/Paging-Screen-Output.html
new file mode 100644
index 0000000..2c5c1d4
--- /dev/null
+++ b/doc/interpreter/HTML/Paging-Screen-Output.html
@@ -0,0 +1,148 @@
+<html lang="en">
+<head>
+<title>Paging Screen Output - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Terminal-Output.html#Terminal-Output" title="Terminal Output">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Paging-Screen-Output"></a>
+Up: <a rel="up" accesskey="u" href="Terminal-Output.html#Terminal-Output">Terminal Output</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">14.1.1.1 Paging Screen Output</h5>
+
+<p>When running interactively, Octave normally sends any output intended
+for your terminal that is more than one screen long to a paging program,
+such as <code>less</code> or <code>more</code>.  This avoids the problem of having a
+large volume of output stream by before you can read it.  With
+<code>less</code> (and some versions of <code>more</code>) you can also scan forward
+and backward, and search for specific items.
+
+   <p>Normally, no output is displayed by the pager until just before Octave
+is ready to print the top level prompt, or read from the standard input
+(for example, by using the <code>fscanf</code> or <code>scanf</code> functions). 
+This means that there may be some delay before any output appears on
+your screen if you have asked Octave to perform a significant amount of
+work with a single command statement.  The function <code>fflush</code> may be
+used to force output to be sent to the pager (or any other stream)
+immediately.
+
+   <p>You can select the program to run as the pager using the <code>PAGER</code>
+function, and you can turn paging off by using the function
+<code>more</code>.
+
+<!-- pager.cc -->
+   <p><a name="doc_002dmore"></a>
+
+<div class="defun">
+— Command: <b>more</b><var><a name="index-more-710"></a></var><br>
+— Command: <b>more</b><var> on<a name="index-more-711"></a></var><br>
+— Command: <b>more</b><var> off<a name="index-more-712"></a></var><br>
+<blockquote><p>Turn output pagination on or off.  Without an argument, <code>more</code>
+toggles the current state. 
+The current state can be determined via <code>page_screen_output</code>. 
+</p></blockquote></div>
+
+<!-- pager.cc -->
+   <p><a name="doc_002dPAGER"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>PAGER</b> ()<var><a name="index-PAGER-713"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>PAGER</b> (<var>new_val</var>)<var><a name="index-PAGER-714"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the program to use
+to display terminal output on your system.  The default value is
+normally <code>"less"</code>, <code>"more"</code>, or
+<code>"pg"</code>, depending on what programs are installed on your system. 
+See <a href="Installation.html#Installation">Installation</a>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmore.html#doc_002dmore">more</a>, <a href="doc_002dpage_005fscreen_005foutput.html#doc_002dpage_005fscreen_005foutput">page_screen_output</a>, <a href="doc_002dpage_005foutput_005fimmediately.html#doc_002dpage_005foutput_005fimmediately">page_output_immediately</a>, <a href="doc_002dPAGER_005fFLAGS.html#doc_002dPAGER_005fFLAGS">PAGER_FLAGS</a>. 
+</p></blockquote></div>
+
+<!-- pager.cc -->
+   <p><a name="doc_002dPAGER_005fFLAGS"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>PAGER_FLAGS</b> ()<var><a name="index-PAGER_005fFLAGS-715"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>PAGER_FLAGS</b> (<var>new_val</var>)<var><a name="index-PAGER_005fFLAGS-716"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the options to pass
+to the pager. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dPAGER.html#doc_002dPAGER">PAGER</a>. 
+</p></blockquote></div>
+
+<!-- pager.cc -->
+   <p><a name="doc_002dpage_005fscreen_005foutput"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>page_screen_output</b> ()<var><a name="index-page_005fscreen_005foutput-717"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>page_screen_output</b> (<var>new_val</var>)<var><a name="index-page_005fscreen_005foutput-718"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether output intended
+for the terminal window that is longer than one page is sent through a
+pager.  This allows you to view one screenful at a time.  Some pagers
+(such as <code>less</code>—see <a href="Installation.html#Installation">Installation</a>) are also capable of moving
+backward on the output. 
+</p></blockquote></div>
+
+<!-- pager.cc -->
+   <p><a name="doc_002dpage_005foutput_005fimmediately"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>page_output_immediately</b> ()<var><a name="index-page_005foutput_005fimmediately-719"></a></var><br>
+— Built-in Function: <var>val</var> = <b>page_output_immediately</b> (<var>new_val</var>)<var><a name="index-page_005foutput_005fimmediately-720"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave sends
+output to the pager as soon as it is available.  Otherwise, Octave
+buffers its output and waits until just before the prompt is printed to
+flush it to the pager. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dfflush"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fflush</b> (<var>fid</var>)<var><a name="index-fflush-721"></a></var><br>
+<blockquote><p>Flush output to <var>fid</var>.  This is useful for ensuring that all
+pending output makes it to the screen before some other event occurs. 
+For example, it is always a good idea to flush the standard output
+stream before calling <code>input</code>.
+
+        <p><code>fflush</code> returns 0 on success and an OS dependent error value
+(−1 on unix) on error. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfopen.html#doc_002dfopen">fopen</a>, <a href="doc_002dfclose.html#doc_002dfclose">fclose</a>. 
+</p></blockquote></div>
+
+<!-- FIXME - maybe this would be a good place to describe the -->
+<!-- following message: -->
+<!-- warning: connection to external pager (pid = 9334) lost - -->
+<!-- warning: pending computations and output may be lost -->
+<!-- warning: broken pipe -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Password-Database-Functions.html b/doc/interpreter/HTML/Password-Database-Functions.html
new file mode 100644
index 0000000..6f5ba2f
--- /dev/null
+++ b/doc/interpreter/HTML/Password-Database-Functions.html
@@ -0,0 +1,106 @@
+<html lang="en">
+<head>
+<title>Password Database Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Current-Working-Directory.html#Current-Working-Directory" title="Current Working Directory">
+<link rel="next" href="Group-Database-Functions.html#Group-Database-Functions" title="Group Database Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Password-Database-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.9 Password Database Functions</h3>
+
+<p>Octave's password database functions return information in a structure
+with the following fields.
+
+     <dl>
+<dt><code>name</code><dd>The user name.
+
+     <br><dt><code>passwd</code><dd>The encrypted password, if available.
+
+     <br><dt><code>uid</code><dd>The numeric user id.
+
+     <br><dt><code>gid</code><dd>The numeric group id.
+
+     <br><dt><code>gecos</code><dd>The GECOS field.
+
+     <br><dt><code>dir</code><dd>The home directory.
+
+     <br><dt><code>shell</code><dd>The initial shell. 
+</dl>
+
+   <p>In the descriptions of the following functions, this data structure is
+referred to as a <var>pw_struct</var>.
+
+<!-- ./DLD-FUNCTIONS/getpwent.cc -->
+   <p><a name="doc_002dgetpwent"></a>
+
+<div class="defun">
+— Loadable Function: <var>pw_struct</var> = <b>getpwent</b> ()<var><a name="index-getpwent-2432"></a></var><br>
+<blockquote><p>Return a structure containing an entry from the password database,
+opening it if necessary.  Once the end of the data has been reached,
+<code>getpwent</code> returns 0. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getpwent.cc -->
+   <p><a name="doc_002dgetpwuid"></a>
+
+<div class="defun">
+— Loadable Function: <var>pw_struct</var> = <b>getpwuid</b> (<var>uid</var>)<var>.<a name="index-getpwuid-2433"></a></var><br>
+<blockquote><p>Return a structure containing the first entry from the password database
+with the user ID <var>uid</var>.  If the user ID does not exist in the
+database, <code>getpwuid</code> returns 0. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getpwent.cc -->
+   <p><a name="doc_002dgetpwnam"></a>
+
+<div class="defun">
+— Loadable Function: <var>pw_struct</var> = <b>getpwnam</b> (<var>name</var>)<var><a name="index-getpwnam-2434"></a></var><br>
+<blockquote><p>Return a structure containing the first entry from the password database
+with the user name <var>name</var>.  If the user name does not exist in the
+database, <code>getpwname</code> returns 0. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getpwent.cc -->
+   <p><a name="doc_002dsetpwent"></a>
+
+<div class="defun">
+— Loadable Function:  <b>setpwent</b> ()<var><a name="index-setpwent-2435"></a></var><br>
+<blockquote><p>Return the internal pointer to the beginning of the password database. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getpwent.cc -->
+   <p><a name="doc_002dendpwent"></a>
+
+<div class="defun">
+— Loadable Function:  <b>endpwent</b> ()<var><a name="index-endpwent-2436"></a></var><br>
+<blockquote><p>Close the password database. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Patch-Properties.html b/doc/interpreter/HTML/Patch-Properties.html
new file mode 100644
index 0000000..7ae7fef
--- /dev/null
+++ b/doc/interpreter/HTML/Patch-Properties.html
@@ -0,0 +1,53 @@
+<html lang="en">
+<head>
+<title>Patch Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Image-Properties.html#Image-Properties" title="Image Properties">
+<link rel="next" href="Surface-Properties.html#Surface-Properties" title="Surface Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Patch-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Surface-Properties.html#Surface-Properties">Surface Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Image-Properties.html#Image-Properties">Image Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.7 Patch Properties</h5>
+
+<p><a name="index-patch-properties-1195"></a>
+     <dl>
+<dt><code>cdata</code><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>Data defining the patch object.
+
+     <br><dt><code>facecolor</code><dd>The fill color of the patch.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>facealpha</code><dd>A number in the range [0, 1] indicating the transparency of the patch.
+
+     <br><dt><code>edgecolor</code><dd>The color of the line defining the patch.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linestyle</code><dt><code>linewidth</code><dd>See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>See <a href="Marker-Styles.html#Marker-Styles">Marker Styles</a>. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Permutation-Matrix-Functions.html b/doc/interpreter/HTML/Permutation-Matrix-Functions.html
new file mode 100644
index 0000000..af8cf5d
--- /dev/null
+++ b/doc/interpreter/HTML/Permutation-Matrix-Functions.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Permutation Matrix Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Support.html#Function-Support" title="Function Support">
+<link rel="prev" href="Diagonal-Matrix-Functions.html#Diagonal-Matrix-Functions" title="Diagonal Matrix Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Permutation-Matrix-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Diagonal-Matrix-Functions.html#Diagonal-Matrix-Functions">Diagonal Matrix Functions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Support.html#Function-Support">Function Support</a>
+<hr>
+</div>
+
+<h4 class="subsection">20.3.2 Permutation Matrix Functions</h4>
+
+<p><dfn>inv</dfn> and <dfn>pinv</dfn> will invert a permutation matrix, preserving its
+specialness.  <dfn>det</dfn> can be applied to a permutation matrix, efficiently
+calculating the sign of the permutation (which is equal to the determinant).
+
+   <p>A permutation matrix can also be returned from the built-in functions
+<dfn>lu</dfn> and <dfn>qr</dfn>, if a pivoted factorization is requested.
+
+   <p>The <dfn>sparse</dfn> function will convert a permutation matrix efficiently to a
+sparse matrix. 
+The <dfn>find</dfn> function will also work efficiently with a permutation matrix,
+making it possible to conveniently obtain the permutation indices.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Persistent-Variables.html b/doc/interpreter/HTML/Persistent-Variables.html
new file mode 100644
index 0000000..eda9f8f
--- /dev/null
+++ b/doc/interpreter/HTML/Persistent-Variables.html
@@ -0,0 +1,139 @@
+<html lang="en">
+<head>
+<title>Persistent Variables - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Variables.html#Variables" title="Variables">
+<link rel="prev" href="Global-Variables.html#Global-Variables" title="Global Variables">
+<link rel="next" href="Status-of-Variables.html#Status-of-Variables" title="Status of Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Persistent-Variables"></a>
+Next: <a rel="next" accesskey="n" href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a>,
+Previous: <a rel="previous" accesskey="p" href="Global-Variables.html#Global-Variables">Global Variables</a>,
+Up: <a rel="up" accesskey="u" href="Variables.html#Variables">Variables</a>
+<hr>
+</div>
+
+<h3 class="section">7.2 Persistent Variables</h3>
+
+<p><a name="index-persistent-variables-427"></a><a name="index-g_t_0040code_007bpersistent_007d-statement-428"></a><a name="index-variables_002c-persistent-429"></a><a name="doc_002dpersistent"></a>A variable that has been declared <dfn>persistent</dfn> within a function
+will retain its contents in memory between subsequent calls to the
+same function.  The difference between persistent variables and global
+variables is that persistent variables are local in scope to a
+particular function and are not visible elsewhere.
+
+   <p>The following example uses a persistent variable to create a function
+that prints the number of times it has been called.
+
+<pre class="example">     function count_calls ()
+       persistent calls = 0;
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+     
+     for i = 1:3
+       count_calls ();
+     endfor
+     
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+     -| 'count_calls' has been called 3 times
+</pre>
+   <p>As the example shows, a variable may be declared persistent using a
+<code>persistent</code> declaration statement.  The following statements are
+all persistent declarations.
+
+<pre class="example">     persistent a
+     persistent a b
+     persistent c = 2
+     persistent d = 3 e f = 5
+</pre>
+   <p>The behavior of persistent variables is equivalent to the behavior of
+static variables in C.  The command <code>static</code> in Octave is also
+recognized and is equivalent to <code>persistent</code>.
+
+   <p>Like global variables, a persistent variable may only be initialized once. 
+For example, after executing the following code
+
+<pre class="example">     persistent pvar = 1
+     persistent pvar = 2
+</pre>
+   <p class="noindent">the value of the persistent variable <code>pvar</code> is 1, not 2.
+
+   <p>If a persistent variable is declared but not initialized to a specific
+value, it will contain an empty matrix.  So, it is also possible to
+initialize a persistent variable by checking whether it is empty, as the
+following example illustrates.
+
+<pre class="example">     function count_calls ()
+       persistent calls;
+       if (isempty (calls))
+         calls = 0;
+       endif
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+</pre>
+   <p class="noindent">This implementation behaves in exactly the same way as the previous
+implementation of <code>count_calls</code>.
+
+   <p>The value of a persistent variable is kept in memory until it is
+explicitly cleared.  Assuming that the implementation of <code>count_calls</code>
+is saved on disk, we get the following behavior.
+
+<pre class="example">     for i = 1:2
+       count_calls ();
+     endfor
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+     
+     clear
+     for i = 1:2
+       count_calls();
+     endfor
+     -| 'count_calls' has been called 3 times
+     -| 'count_calls' has been called 4 times
+     
+     clear all
+     for i = 1:2
+       count_calls();
+     endfor
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+     
+     clear count_calls
+     for i = 1:2
+       count_calls();
+     endfor
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+</pre>
+   <p class="noindent">That is, the persistent variable is only removed from memory when the
+function containing the variable is removed.  Note that if the function
+definition is typed directly into the Octave prompt, the persistent
+variable will be cleared by a simple <code>clear</code> command as the entire
+function definition will be removed from memory.  If you do not want
+a persistent variable to be removed from memory even if the function is
+cleared, you should use the <code>mlock</code> function as described in
+See <a href="Function-Locking.html#Function-Locking">Function Locking</a>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Plot-Annotations.html b/doc/interpreter/HTML/Plot-Annotations.html
new file mode 100644
index 0000000..2dfbf56
--- /dev/null
+++ b/doc/interpreter/HTML/Plot-Annotations.html
@@ -0,0 +1,253 @@
+<html lang="en">
+<head>
+<title>Plot Annotations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting" title="Three-Dimensional Plotting">
+<link rel="next" href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page" title="Multiple Plots on One Page">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Plot-Annotations"></a>
+Next: <a rel="next" accesskey="n" href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page">Multiple Plots on One Page</a>,
+Previous: <a rel="previous" accesskey="p" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.3 Plot Annotations</h4>
+
+<p>You can add titles, axis labels, legends, and arbitrary text to an
+existing plot.  For example,
+
+<pre class="example">     x = -10:0.1:10;
+     plot (x, sin (x));
+     title ("sin(x) for x = -10:0.1:10");
+     xlabel ("x");
+     ylabel ("sin (x)");
+     text (pi, 0.7, "arbitrary text");
+     legend ("sin (x)");
+</pre>
+   <p>The functions <code>grid</code> and <code>box</code> may also be used to add grid
+and border lines to the plot.  By default, the grid is off and the
+border lines are on.
+
+<!-- ./plot/title.m -->
+   <p><a name="doc_002dtitle"></a>
+
+<div class="defun">
+— Function File:  <b>title</b> (<var>title</var>)<var><a name="index-title-1059"></a></var><br>
+— Function File:  <b>title</b> (<var>title, p1, v1, <small class="dots">...</small></var>)<var><a name="index-title-1060"></a></var><br>
+<blockquote><p>Create a title object and return a handle to it. 
+</p></blockquote></div>
+
+<!-- ./plot/legend.m -->
+   <p><a name="doc_002dlegend"></a>
+
+<div class="defun">
+— Function File:  <b>legend</b> (<var>st1, st2, <small class="dots">...</small></var>)<var><a name="index-legend-1061"></a></var><br>
+— Function File:  <b>legend</b> (<var>st1, st2, <small class="dots">...</small>, "location", pos</var>)<var><a name="index-legend-1062"></a></var><br>
+— Function File:  <b>legend</b> (<var>matstr</var>)<var><a name="index-legend-1063"></a></var><br>
+— Function File:  <b>legend</b> (<var>matstr, "location", pos</var>)<var><a name="index-legend-1064"></a></var><br>
+— Function File:  <b>legend</b> (<var>cell</var>)<var><a name="index-legend-1065"></a></var><br>
+— Function File:  <b>legend</b> (<var>cell, "location", pos</var>)<var><a name="index-legend-1066"></a></var><br>
+— Function File:  <b>legend</b> (<var>'func'</var>)<var><a name="index-legend-1067"></a></var><br>
+<blockquote>
+        <p>Display a legend for the current axes using the specified strings
+as labels.  Legend entries may be specified as individual character
+string arguments, a character array, or a cell array of character
+strings.  Legend works on line graphs, bar graphs, etc.  A plot must
+exist before legend is called.
+
+        <p>The optional parameter <var>pos</var> specifies the location of the legend
+as follows:
+
+        <p><table summary=""><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">north </td><td valign="top" width="80%">
+  center top
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">south </td><td valign="top" width="80%">
+  center bottom
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">east </td><td valign="top" width="80%">
+  right center
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">west </td><td valign="top" width="80%">
+  left center
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">northeast </td><td valign="top" width="80%">
+  right top (default)
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">northwest </td><td valign="top" width="80%">
+  left top
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">southeast </td><td valign="top" width="80%">
+  right bottom
+<br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">southwest </td><td valign="top" width="80%">
+  left bottom
+<br></td></tr><tr align="left"><td valign="top" width="6%"><br></td></tr><tr align="left"><td valign="top" width="6%"></td><td valign="top" width="14%">outside </td><td valign="top" width="80%">
+  can be appended to any location string
+        <br></td></tr></table>
+
+        <p>Some specific functions are directly available using <var>func</var>:
+
+          <dl>
+<dt>"show"<dd>  Show legends from the plot
+<br><dt>"hide"<dt>"off"<dd>  Hide legends from the plot
+<br><dt>"boxon"<dd>  Draw a box around legends
+<br><dt>"boxoff"<dd>  Withdraw the box around legends
+<br><dt>"left"<dd>  Text is to the left of the keys
+<br><dt>"right"<dd>  Text is to the right of the keys
+</dl>
+        </p></blockquote></div>
+
+<!-- ./plot/text.m -->
+   <p><a name="doc_002dtext"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>text</b> (<var>x, y, label</var>)<var><a name="index-text-1068"></a></var><br>
+— Function File: <var>h</var> = <b>text</b> (<var>x, y, z, label</var>)<var><a name="index-text-1069"></a></var><br>
+— Function File: <var>h</var> = <b>text</b> (<var>x, y, label, p1, v1, <small class="dots">...</small></var>)<var><a name="index-text-1070"></a></var><br>
+— Function File: <var>h</var> = <b>text</b> (<var>x, y, z, label, p1, v1, <small class="dots">...</small></var>)<var><a name="index-text-1071"></a></var><br>
+<blockquote><p>Create a text object with text <var>label</var> at position <var>x</var>,
+<var>y</var>, <var>z</var> on the current axes.  Property-value pairs following
+<var>label</var> may be used to specify the appearance of the text. 
+</p></blockquote></div>
+
+   <p>See <a href="Text-Properties.html#Text-Properties">Text Properties</a> for the properties that you can set.
+
+   <p><a name="doc_002dylabel"></a><a name="doc_002dzlabel"></a><!-- ./plot/xlabel.m -->
+<a name="doc_002dxlabel"></a>
+
+<div class="defun">
+— Function File:  <b>xlabel</b> (<var>string</var>)<var><a name="index-xlabel-1072"></a></var><br>
+— Function File:  <b>ylabel</b> (<var>string</var>)<var><a name="index-ylabel-1073"></a></var><br>
+— Function File:  <b>zlabel</b> (<var>string</var>)<var><a name="index-zlabel-1074"></a></var><br>
+— Function File:  <b>xlabel</b> (<var>h, string</var>)<var><a name="index-xlabel-1075"></a></var><br>
+<blockquote><p>Specify x, y, and z axis labels for the current figure.  If <var>h</var> is
+specified then label the axis defined by <var>h</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dsemilogx.html#doc_002dsemilogx">semilogx</a>, <a href="doc_002dsemilogy.html#doc_002dsemilogy">semilogy</a>, <a href="doc_002dloglog.html#doc_002dloglog">loglog</a>, <a href="doc_002dpolar.html#doc_002dpolar">polar</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>, <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dstairs.html#doc_002dstairs">stairs</a>, <a href="doc_002dtitle.html#doc_002dtitle">title</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/clabel.m -->
+   <p><a name="doc_002dclabel"></a>
+
+<div class="defun">
+— Function File:  <b>clabel</b> (<var>c, h</var>)<var><a name="index-clabel-1076"></a></var><br>
+— Function File:  <b>clabel</b> (<var>c, h, v</var>)<var><a name="index-clabel-1077"></a></var><br>
+— Function File:  <b>clabel</b> (<var>c, h, "manual"</var>)<var><a name="index-clabel-1078"></a></var><br>
+— Function File:  <b>clabel</b> (<var>c</var>)<var><a name="index-clabel-1079"></a></var><br>
+— Function File:  <b>clabel</b> (<var>c, h</var>)<var><a name="index-clabel-1080"></a></var><br>
+— Function File:  <b>clabel</b> (<var><small class="dots">...</small>, prop, val, <small class="dots">...</small></var>)<var><a name="index-clabel-1081"></a></var><br>
+— Function File: <var>h</var> = <b>clabel</b> (<var><small class="dots">...</small></var>)<var><a name="index-clabel-1082"></a></var><br>
+<blockquote><p>Adds labels to the contours of a contour plot.  The contour plot is specified
+by the contour matrix <var>c</var> and optionally the contourgroup object <var>h</var>
+that are returned by <code>contour</code>, <code>contourf</code> and <code>contour3</code>. 
+The contour labels are rotated and placed in the contour itself.
+
+        <p>By default, all contours are labelled.  However, the contours to label can be
+specified by the vector <var>v</var>.  If the "manual" argument is given then
+the contours to label can be selected with the mouse.
+
+        <p>Additional property/value pairs that are valid properties of text objects
+can be given and are passed to the underlying text objects.  Additionally,
+the property "LabelSpacing" is available allowing the spacing between labels
+on a contour (in points) to be specified.  The default is 144 points, or 2
+inches.
+
+        <p>The returned value <var>h</var> is the set of text object that represent the
+contour labels.  The "userdata" property of the text objects contains the
+numerical value of the contour label.
+
+        <p>An example of the use of <code>clabel</code> is
+
+     <pre class="example">          [c, h] = contour (peaks(), -4 : 6);
+          clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcontour.html#doc_002dcontour">contour</a>, <a href="doc_002dcontourf.html#doc_002dcontourf">contourf</a>, <a href="doc_002dcontour3.html#doc_002dcontour3">contour3</a>, <a href="doc_002dmeshc.html#doc_002dmeshc">meshc</a>, <a href="doc_002dsurfc.html#doc_002dsurfc">surfc</a>, <a href="doc_002dtext.html#doc_002dtext">text</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/box.m -->
+   <p><a name="doc_002dbox"></a>
+
+<div class="defun">
+— Function File:  <b>box</b> (<var>arg</var>)<var><a name="index-box-1083"></a></var><br>
+— Function File:  <b>box</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-box-1084"></a></var><br>
+<blockquote><p>Control the display of a border around the plot. 
+The argument may be either <code>"on"</code> or <code>"off"</code>.  If it is
+omitted, the current box state is toggled. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgrid.html#doc_002dgrid">grid</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/grid.m -->
+   <p><a name="doc_002dgrid"></a>
+
+<div class="defun">
+— Function File:  <b>grid</b> (<var>arg</var>)<var><a name="index-grid-1085"></a></var><br>
+— Function File:  <b>grid</b> (<var>"minor", arg2</var>)<var><a name="index-grid-1086"></a></var><br>
+— Function File:  <b>grid</b> (<var>hax, <small class="dots">...</small></var>)<var><a name="index-grid-1087"></a></var><br>
+<blockquote><p>Force the display of a grid on the plot. 
+The argument may be either <code>"on"</code>, or <code>"off"</code>. 
+If it is omitted, the current grid state is toggled.
+
+        <p>If <var>arg</var> is <code>"minor"</code> then the minor grid is toggled.  When
+using a minor grid a second argument <var>arg2</var> is allowed, which can
+be either <code>"on"</code> or <code>"off"</code> to explicitly set the state of
+the minor grid.
+
+        <p>If the first argument is an axis handle, <var>hax</var>, operate on the
+specified axis object. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/colorbar.m -->
+   <p><a name="doc_002dcolorbar"></a>
+
+<div class="defun">
+— Function File:  <b>colorbar</b> (<var>s</var>)<var><a name="index-colorbar-1088"></a></var><br>
+— Function File:  <b>colorbar</b> (<var>"peer", h, <small class="dots">...</small></var>)<var><a name="index-colorbar-1089"></a></var><br>
+<blockquote><p>Adds a colorbar to the current axes.  Valid values for <var>s</var> are
+
+          <dl>
+<dt>"EastOutside"<dd>Place the colorbar outside the plot to the right.  This is the default. 
+<br><dt>"East"<dd>Place the colorbar inside the plot to the right. 
+<br><dt>"WestOutside"<dd>Place the colorbar outside the plot to the left. 
+<br><dt>"West"<dd>Place the colorbar inside the plot to the left. 
+<br><dt>"NorthOutside"<dd>Place the colorbar above the plot. 
+<br><dt>"North"<dd>Place the colorbar at the top of the plot. 
+<br><dt>"SouthOutside"<dd>Place the colorbar under the plot. 
+<br><dt>"South"<dd>Place the colorbar at the bottom of the plot. 
+<br><dt>"Off", "None"<dd>Remove any existing colorbar from the plot. 
+</dl>
+
+        <p>If the argument "peer" is given, then the following argument is treated
+as the axes handle on which to add the colorbar. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Plotting-Basics.html b/doc/interpreter/HTML/Plotting-Basics.html
new file mode 100644
index 0000000..14da0e1
--- /dev/null
+++ b/doc/interpreter/HTML/Plotting-Basics.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Plotting Basics - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting.html#Plotting" title="Plotting">
+<link rel="next" href="Advanced-Plotting.html#Advanced-Plotting" title="Advanced Plotting">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Plotting-Basics"></a>
+Next: <a rel="next" accesskey="n" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>,
+Up: <a rel="up" accesskey="u" href="Plotting.html#Plotting">Plotting</a>
+<hr>
+</div>
+
+<h3 class="section">15.1 Plotting Basics</h3>
+
+<p>Octave makes it easy to create many different types of two- and
+three-dimensional plots using a few high-level functions.
+
+   <p>If you need finer control over graphics, see <a href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>.
+
+<ul class="menu">
+<li><a accesskey="1" href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a>
+<li><a accesskey="2" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a>
+<li><a accesskey="3" href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a>
+<li><a accesskey="4" href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page">Multiple Plots on One Page</a>
+<li><a accesskey="5" href="Multiple-Plot-Windows.html#Multiple-Plot-Windows">Multiple Plot Windows</a>
+<li><a accesskey="6" href="Printing-Plots.html#Printing-Plots">Printing Plots</a>
+<li><a accesskey="7" href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a>
+<li><a accesskey="8" href="Test-Plotting-Functions.html#Test-Plotting-Functions">Test Plotting Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Plotting-on-top-of-Images.html b/doc/interpreter/HTML/Plotting-on-top-of-Images.html
new file mode 100644
index 0000000..8d10d07
--- /dev/null
+++ b/doc/interpreter/HTML/Plotting-on-top-of-Images.html
@@ -0,0 +1,58 @@
+<html lang="en">
+<head>
+<title>Plotting on top of Images - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link rel="prev" href="Representing-Images.html#Representing-Images" title="Representing Images">
+<link rel="next" href="Color-Conversion.html#Color-Conversion" title="Color Conversion">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Plotting-on-top-of-Images"></a>
+Next: <a rel="next" accesskey="n" href="Color-Conversion.html#Color-Conversion">Color Conversion</a>,
+Previous: <a rel="previous" accesskey="p" href="Representing-Images.html#Representing-Images">Representing Images</a>,
+Up: <a rel="up" accesskey="u" href="Image-Processing.html#Image-Processing">Image Processing</a>
+<hr>
+</div>
+
+<h3 class="section">31.4 Plotting on top of Images</h3>
+
+<p>If gnuplot is being used to display images it is possible to plot on
+top of images.  Since an image is a matrix it is indexed by row and
+column values.  The plotting system is, however, based on the
+traditional (x, y) system.  To minimize the difference between
+the two systems Octave places the origin of the coordinate system in
+the point corresponding to the pixel at (1, 1).  So, to plot
+points given by row and column values on top of an image, one should
+simply call <code>plot</code> with the column values as the first argument
+and the row values as the second.  As an example the following code
+generates an image with random intensities between 0 and 1, and shows
+the image with red circles over pixels with an intensity above
+0.99.
+
+<pre class="example">     I = rand (100, 100);
+     [row, col] = find (I > 0.99);
+     hold ("on");
+     imshow (I);
+     plot (col, row, "ro");
+     hold ("off");
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Plotting-the-Triangulation.html b/doc/interpreter/HTML/Plotting-the-Triangulation.html
new file mode 100644
index 0000000..43565a2
--- /dev/null
+++ b/doc/interpreter/HTML/Plotting-the-Triangulation.html
@@ -0,0 +1,90 @@
+<html lang="en">
+<head>
+<title>Plotting the Triangulation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Delaunay-Triangulation.html#Delaunay-Triangulation" title="Delaunay Triangulation">
+<link rel="next" href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation" title="Identifying points in Triangulation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Plotting-the-Triangulation"></a>
+Next: <a rel="next" accesskey="n" href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a>,
+Up: <a rel="up" accesskey="u" href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a>
+<hr>
+</div>
+
+<h4 class="subsection">29.1.1 Plotting the Triangulation</h4>
+
+<p>Octave has the functions <code>triplot</code> and <code>trimesh</code> to plot the
+Delaunay triangulation of a 2-dimensional set of points.
+
+<!-- ./geometry/triplot.m -->
+   <p><a name="doc_002dtriplot"></a>
+
+<div class="defun">
+— Function File:  <b>triplot</b> (<var>tri, x, y</var>)<var><a name="index-triplot-2090"></a></var><br>
+— Function File:  <b>triplot</b> (<var>tri, x, y, linespec</var>)<var><a name="index-triplot-2091"></a></var><br>
+— Function File: <var>h</var> = <b>triplot</b> (<var><small class="dots">...</small></var>)<var><a name="index-triplot-2092"></a></var><br>
+<blockquote><p>Plot a triangular mesh in 2D.  The variable <var>tri</var> is the triangular
+meshing of the points <code>(</code><var>x</var><code>, </code><var>y</var><code>)</code> which is returned from
+<code>delaunay</code>.  If given, the <var>linespec</var> determines the properties
+to use for the lines.  The output argument <var>h</var> is the graphic handle
+to the plot. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dtrimesh.html#doc_002dtrimesh">trimesh</a>, <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/trimesh.m -->
+   <p><a name="doc_002dtrimesh"></a>
+
+<div class="defun">
+— Function File:  <b>trimesh</b> (<var>tri, x, y, z</var>)<var><a name="index-trimesh-2093"></a></var><br>
+— Function File: <var>h</var> = <b>trimesh</b> (<var><small class="dots">...</small></var>)<var><a name="index-trimesh-2094"></a></var><br>
+<blockquote><p>Plot a triangular mesh in 3D.  The variable <var>tri</var> is the triangular
+meshing of the points <code>(</code><var>x</var><code>, </code><var>y</var><code>)</code> which is returned
+from <code>delaunay</code>.  The variable <var>z</var> is value at the point
+<code>(</code><var>x</var><code>, </code><var>y</var><code>)</code>.  The output argument <var>h</var> is the graphic
+handle to the plot. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtriplot.html#doc_002dtriplot">triplot</a>, <a href="doc_002ddelaunay3.html#doc_002ddelaunay3">delaunay3</a>. 
+</p></blockquote></div>
+
+   <p>The difference between <code>triplot</code> and <code>trimesh</code> is that the
+former only plots the 2-dimensional triangulation itself, whereas the
+second plots the value of some function <code>f (</code><var>x</var><code>, </code><var>y</var><code>)</code>. 
+An example of the use of the <code>triplot</code> function is
+
+<pre class="example">     rand ("state", 2)
+     x = rand (20, 1);
+     y = rand (20, 1);
+     tri = delaunay (x, y);
+     triplot (tri, x, y);
+</pre>
+   <p>that plot the Delaunay triangulation of a set of random points in
+2-dimensions.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Plotting.html b/doc/interpreter/HTML/Plotting.html
new file mode 100644
index 0000000..b2d2129
--- /dev/null
+++ b/doc/interpreter/HTML/Plotting.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Plotting - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Input-and-Output.html#Input-and-Output" title="Input and Output">
+<link rel="next" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Plotting"></a>
+Next: <a rel="next" accesskey="n" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>,
+Previous: <a rel="previous" accesskey="p" href="Input-and-Output.html#Input-and-Output">Input and Output</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">15 Plotting</h2>
+
+<p><a name="index-plotting-815"></a><a name="index-graphics-816"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<li><a accesskey="2" href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Polynomial-Interpolation.html b/doc/interpreter/HTML/Polynomial-Interpolation.html
new file mode 100644
index 0000000..611beb9
--- /dev/null
+++ b/doc/interpreter/HTML/Polynomial-Interpolation.html
@@ -0,0 +1,176 @@
+<html lang="en">
+<head>
+<title>Polynomial Interpolation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="prev" href="Derivatives-and-Integrals.html#Derivatives-and-Integrals" title="Derivatives and Integrals">
+<link rel="next" href="Miscellaneous-Functions.html#Miscellaneous-Functions" title="Miscellaneous Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Polynomial-Interpolation"></a>
+Next: <a rel="next" accesskey="n" href="Miscellaneous-Functions.html#Miscellaneous-Functions">Miscellaneous Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a>,
+Up: <a rel="up" accesskey="u" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<hr>
+</div>
+
+<h3 class="section">27.5 Polynomial Interpolation</h3>
+
+<p>Octave comes with good support for various kinds of interpolation,
+most of which are described in <a href="Interpolation.html#Interpolation">Interpolation</a>.  One simple alternative
+to the functions described in the aforementioned chapter, is to fit
+a single polynomial to some given data points.  To avoid a highly
+fluctuating polynomial, one most often wants to fit a low-order polynomial
+to data.  This usually means that it is necessary to fit the polynomial
+in a least-squares sense, which is what the <code>polyfit</code> function does.
+
+<!-- ./polynomial/polyfit.m -->
+   <p><a name="doc_002dpolyfit"></a>
+
+<div class="defun">
+— Function File: [<var>p</var>, <var>s</var>, <var>mu</var>] = <b>polyfit</b> (<var>x, y, n</var>)<var><a name="index-polyfit-2048"></a></var><br>
+<blockquote><p>Return the coefficients of a polynomial <var>p</var>(<var>x</var>) of degree
+<var>n</var> that minimizes the least-squares-error of the fit.
+
+        <p>The polynomial coefficients are returned in a row vector.
+
+        <p>The second output is a structure containing the following fields:
+
+          <dl>
+<dt>‘<samp><span class="samp">R</span></samp>’<dd>Triangular factor R from the QR decomposition. 
+<br><dt>‘<samp><span class="samp">X</span></samp>’<dd>The Vandermonde matrix used to compute the polynomial coefficients. 
+<br><dt>‘<samp><span class="samp">df</span></samp>’<dd>The degrees of freedom. 
+<br><dt>‘<samp><span class="samp">normr</span></samp>’<dd>The norm of the residuals. 
+<br><dt>‘<samp><span class="samp">yf</span></samp>’<dd>The values of the polynomial for each value of <var>x</var>. 
+</dl>
+
+        <p>The second output may be used by <code>polyval</code> to calculate the
+statistical error limits of the predicted values.
+
+        <p>When the third output, <var>mu</var>, is present the
+coefficients, <var>p</var>, are associated with a polynomial in
+<var>xhat</var> = (<var>x</var>-<var>mu</var>(1))/<var>mu</var>(2). 
+Where <var>mu</var>(1) = mean (<var>x</var>), and <var>mu</var>(2) = std (<var>x</var>). 
+This linear transformation of <var>x</var> improves the numerical
+stability of the fit. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>. 
+</p></blockquote></div>
+
+   <p>In situations where a single polynomial isn't good enough, a solution
+is to use several polynomials pieced together.  The function <code>mkpp</code>
+creates a piece-wise polynomial, <code>ppval</code> evaluates the function
+created by <code>mkpp</code>, and <code>unmkpp</code> returns detailed information
+about the function.
+
+   <p>The following example shows how to combine two linear functions and a
+quadratic into one function.  Each of these functions is expressed
+on adjoined intervals.
+
+<pre class="example">     x = [-2, -1, 1, 2];
+     p = [ 0,  1, 0;
+           1, -2, 1;
+           0, -1, 1 ];
+     pp = mkpp(x, p);
+     xi = linspace(-2, 2, 50);
+     yi = ppval(pp, xi);
+     plot(xi, yi);
+</pre>
+   <!-- ./polynomial/ppval.m -->
+   <p><a name="doc_002dppval"></a>
+
+<div class="defun">
+— Function File: <var>yi</var> = <b>ppval</b> (<var>pp, xi</var>)<var><a name="index-ppval-2049"></a></var><br>
+<blockquote><p>Evaluate piece-wise polynomial <var>pp</var> at the points <var>xi</var>. 
+If <var>pp</var><code>.d</code> is a scalar greater than 1, or an array,
+then the returned value <var>yi</var> will be an array that is
+<code>d1, d1, ..., dk, length (</code><var>xi</var><code>)]</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmkpp.html#doc_002dmkpp">mkpp</a>, <a href="doc_002dunmkpp.html#doc_002dunmkpp">unmkpp</a>, <a href="doc_002dspline.html#doc_002dspline">spline</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/mkpp.m -->
+   <p><a name="doc_002dmkpp"></a>
+
+<div class="defun">
+— Function File: <var>pp</var> = <b>mkpp</b> (<var>x, p</var>)<var><a name="index-mkpp-2050"></a></var><br>
+— Function File: <var>pp</var> = <b>mkpp</b> (<var>x, p, d</var>)<var><a name="index-mkpp-2051"></a></var><br>
+<blockquote>
+        <p>Construct a piece-wise polynomial structure from sample points
+<var>x</var> and coefficients <var>p</var>.  The i-th row of <var>p</var>,
+<var>p</var><code> (</code><var>i</var><code>,:)</code>, contains the coefficients for the polynomial
+over the <var>i</var>-th interval, ordered from highest to
+lowest.  There must be one row for each interval in <var>x</var>, so
+<code>rows (</code><var>p</var><code>) == length (</code><var>x</var><code>) - 1</code>.
+
+        <p>You can concatenate multiple polynomials of the same order over the
+same set of intervals using <var>p</var><code> = [ </code><var>p1</var><code>; </code><var>p2</var><code>;
+...; </code><var>pd</var><code> ]</code>.  In this case, <code>rows (</code><var>p</var><code>) == </code><var>d</var><code>
+* (length (</code><var>x</var><code>) - 1)</code>.
+
+        <p><var>d</var> specifies the shape of the matrix <var>p</var> for all except the
+last dimension.  If <var>d</var> is not specified it will be computed as
+<code>round (rows (</code><var>p</var><code>) / (length (</code><var>x</var><code>) - 1))</code> instead.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunmkpp.html#doc_002dunmkpp">unmkpp</a>, <a href="doc_002dppval.html#doc_002dppval">ppval</a>, <a href="doc_002dspline.html#doc_002dspline">spline</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/unmkpp.m -->
+   <p><a name="doc_002dunmkpp"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>p</var>, <var>n</var>, <var>k</var>, <var>d</var>] = <b>unmkpp</b> (<var>pp</var>)<var><a name="index-unmkpp-2052"></a></var><br>
+<blockquote>
+        <p>Extract the components of a piece-wise polynomial structure <var>pp</var>. 
+These are as follows:
+
+          <dl>
+<dt><var>x</var><dd>Sample points. 
+<br><dt><var>p</var><dd>Polynomial coefficients for points in sample interval.  <var>p</var><code>
+(</code><var>i</var><code>, :)</code> contains the coefficients for the polynomial over
+interval <var>i</var> ordered from highest to lowest.  If <var>d</var><code> >
+1</code>, <var>p</var><code> (</code><var>r</var><code>, </code><var>i</var><code>, :)</code> contains the coefficients for
+the r-th polynomial defined on interval <var>i</var>.  However, this is
+stored as a 2-D array such that <var>c</var><code> = reshape (</code><var>p</var><code> (:,
+</code><var>j</var><code>), </code><var>n</var><code>, </code><var>d</var><code>)</code> gives <var>c</var><code> (</code><var>i</var><code>,  </code><var>r</var><code>)</code>
+is the j-th coefficient of the r-th polynomial over the i-th interval. 
+<br><dt><var>n</var><dd>Number of polynomial pieces. 
+<br><dt><var>k</var><dd>Order of the polynomial plus 1. 
+<br><dt><var>d</var><dd>Number of polynomials defined for each interval. 
+</dl>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmkpp.html#doc_002dmkpp">mkpp</a>, <a href="doc_002dppval.html#doc_002dppval">ppval</a>, <a href="doc_002dspline.html#doc_002dspline">spline</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Polynomial-Manipulations.html b/doc/interpreter/HTML/Polynomial-Manipulations.html
new file mode 100644
index 0000000..00150d9
--- /dev/null
+++ b/doc/interpreter/HTML/Polynomial-Manipulations.html
@@ -0,0 +1,53 @@
+<html lang="en">
+<head>
+<title>Polynomial Manipulations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Sets.html#Sets" title="Sets">
+<link rel="next" href="Interpolation.html#Interpolation" title="Interpolation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Polynomial-Manipulations"></a>
+Next: <a rel="next" accesskey="n" href="Interpolation.html#Interpolation">Interpolation</a>,
+Previous: <a rel="previous" accesskey="p" href="Sets.html#Sets">Sets</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">27 Polynomial Manipulations</h2>
+
+<p>In Octave, a polynomial is represented by its coefficients (arranged
+in descending order).  For example, a vector <var>c</var> of length
+N+1 corresponds to the following polynomial of order
+ <var>N</var>
+
+<pre class="example">     p(x) = <var>c</var>(1) x^<var>N</var> + ... + <var>c</var>(<var>N</var>) x + <var>c</var>(<var>N</var>+1).
+</pre>
+   <ul class="menu">
+<li><a accesskey="1" href="Evaluating-Polynomials.html#Evaluating-Polynomials">Evaluating Polynomials</a>
+<li><a accesskey="2" href="Finding-Roots.html#Finding-Roots">Finding Roots</a>
+<li><a accesskey="3" href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a>
+<li><a accesskey="4" href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a>
+<li><a accesskey="5" href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a>
+<li><a accesskey="6" href="Miscellaneous-Functions.html#Miscellaneous-Functions">Miscellaneous Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Precedence-of-Objects.html b/doc/interpreter/HTML/Precedence-of-Objects.html
new file mode 100644
index 0000000..8312d49
--- /dev/null
+++ b/doc/interpreter/HTML/Precedence-of-Objects.html
@@ -0,0 +1,111 @@
+<html lang="en">
+<head>
+<title>Precedence of Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Overloading-Objects.html#Overloading-Objects" title="Overloading Objects">
+<link rel="prev" href="Operator-Overloading.html#Operator-Overloading" title="Operator Overloading">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Precedence-of-Objects"></a>
+Previous: <a rel="previous" accesskey="p" href="Operator-Overloading.html#Operator-Overloading">Operator Overloading</a>,
+Up: <a rel="up" accesskey="u" href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>
+<hr>
+</div>
+
+<h4 class="subsection">33.4.3 Precedence of Objects</h4>
+
+<p>Many functions and operators take two or more arguments and so the
+case can easily arise that these functions are called with objects of
+different classes.  It is therefore necessary to determine the precedence
+of which method of which class to call when there are mixed objects given
+to a function or operator.  To do this the <code>superiorto</code> and
+<code>inferiorto</code> functions can be used
+
+<!-- ov-class.cc -->
+   <p><a name="doc_002dsuperiorto"></a>
+
+<div class="defun">
+— Built-in Function:  <b>superiorto</b> (<var>class_name, <small class="dots">...</small></var>)<var><a name="index-superiorto-2266"></a></var><br>
+<blockquote><p>When called from a class constructor, mark the object currently
+constructed as having a higher precedence than <var>class_name</var>. 
+More that one such class can be specified in a single call. 
+This function may only be called from a class constructor. 
+</p></blockquote></div>
+
+<!-- ov-class.cc -->
+   <p><a name="doc_002dinferiorto"></a>
+
+<div class="defun">
+— Built-in Function:  <b>inferiorto</b> (<var>class_name, <small class="dots">...</small></var>)<var><a name="index-inferiorto-2267"></a></var><br>
+<blockquote><p>When called from a class constructor, mark the object currently
+constructed as having a lower precedence than <var>class_name</var>. 
+More that one such class can be specified in a single call. 
+This function may only be called from a class constructor. 
+</p></blockquote></div>
+
+   <p>For example with our polynomial class consider the case
+
+<pre class="example">     2 * polynomial ([1, 0, 1]);
+</pre>
+   <p class="noindent">That mixes an object of the class "double" with an object of the class
+"polynomial".  In this case we like to ensure that the return type of
+the above is of the type "polynomial" and so we use the
+<code>superiorto</code> function in the class constructor.  In particular our
+polynomial class constructor would be modified to be
+
+<pre class="example"><pre class="verbatim">     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} polynomial ()
+     ## @deftypefnx {Function File} {} polynomial (@var{a})
+     ## Creates a polynomial object representing the polynomial
+     ##
+     ## @example
+     ## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+     ## @end example
+     ##
+     ## from a vector of coefficients [a0 a1 a2 ... an].
+     ## @end deftypefn
+     
+     function p = polynomial (a)
+       if (nargin == 0)
+         p.poly = [0];
+         p = class (p, "polynomial");
+       elseif (nargin == 1)
+         if (strcmp (class (a), "polynomial"))
+           p = a;
+         elseif (isvector (a) && isreal (a))
+           p.poly = a(:).';
+           p = class (p, "polynomial");
+         else
+           error ("polynomial: expecting real vector");
+         endif
+       else
+         print_usage ();
+       endif
+       superiorto ("double");
+     endfunction
+</pre>
+</pre>
+   <p>Note that user classes always have higher precedence than built-in
+Octave types.  So in fact marking our polynomial class higher than the
+"double" class is in fact not necessary.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Predicates-for-Numeric-Objects.html b/doc/interpreter/HTML/Predicates-for-Numeric-Objects.html
new file mode 100644
index 0000000..181310f
--- /dev/null
+++ b/doc/interpreter/HTML/Predicates-for-Numeric-Objects.html
@@ -0,0 +1,212 @@
+<html lang="en">
+<head>
+<title>Predicates for Numeric Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types" title="Promotion and Demotion of Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Predicates-for-Numeric-Objects"></a>
+Previous: <a rel="previous" accesskey="p" href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types">Promotion and Demotion of Data Types</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.8 Predicates for Numeric Objects</h3>
+
+<p>Since the type of a variable may change during the execution of a
+program, it can be necessary to do type checking at run-time.  Doing this
+also allows you to change the behavior of a function depending on the
+type of the input.  As an example, this naive implementation of <code>abs</code>
+returns the absolute value of the input if it is a real number, and the
+length of the input if it is a complex number.
+
+<pre class="example">     function a = abs (x)
+       if (isreal (x))
+         a = sign (x) .* x;
+       elseif (iscomplex (x))
+         a = sqrt (real(x).^2 + imag(x).^2);
+       endif
+     endfunction
+</pre>
+   <p>The following functions are available for determining the type of a
+variable.
+
+<!-- data.cc -->
+   <p><a name="doc_002disnumeric"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isnumeric</b> (<var>x</var>)<var><a name="index-isnumeric-267"></a></var><br>
+<blockquote><p>Return nonzero if <var>x</var> is a numeric object. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002disreal"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isreal</b> (<var>x</var>)<var><a name="index-isreal-268"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a real-valued numeric object. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002disfloat"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isfloat</b> (<var>x</var>)<var><a name="index-isfloat-269"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a floating-point numeric object. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002discomplex"></a>
+
+<div class="defun">
+— Built-in Function:  <b>iscomplex</b> (<var>x</var>)<var><a name="index-iscomplex-270"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a complex-valued numeric object. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dismatrix"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ismatrix</b> (<var>a</var>)<var><a name="index-ismatrix-271"></a></var><br>
+<blockquote><p>Return 1 if <var>a</var> is a matrix.  Otherwise, return 0. 
+</p></blockquote></div>
+
+<!-- ./general/isvector.m -->
+   <p><a name="doc_002disvector"></a>
+
+<div class="defun">
+— Function File:  <b>isvector</b> (<var>a</var>)<var><a name="index-isvector-272"></a></var><br>
+<blockquote><p>Return 1 if <var>a</var> is a vector.  Otherwise, return 0. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002drows.html#doc_002drows">rows</a>, <a href="doc_002dcolumns.html#doc_002dcolumns">columns</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002disscalar.html#doc_002disscalar">isscalar</a>, <a href="doc_002dismatrix.html#doc_002dismatrix">ismatrix</a>. 
+</p></blockquote></div>
+
+<!-- ./general/isscalar.m -->
+   <p><a name="doc_002disscalar"></a>
+
+<div class="defun">
+— Function File:  <b>isscalar</b> (<var>a</var>)<var><a name="index-isscalar-273"></a></var><br>
+<blockquote><p>Return 1 if <var>a</var> is a scalar.  Otherwise, return 0. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002drows.html#doc_002drows">rows</a>, <a href="doc_002dcolumns.html#doc_002dcolumns">columns</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002disscalar.html#doc_002disscalar">isscalar</a>, <a href="doc_002dismatrix.html#doc_002dismatrix">ismatrix</a>. 
+</p></blockquote></div>
+
+<!-- ./general/issquare.m -->
+   <p><a name="doc_002dissquare"></a>
+
+<div class="defun">
+— Function File:  <b>issquare</b> (<var>x</var>)<var><a name="index-issquare-274"></a></var><br>
+<blockquote><p>If <var>x</var> is a square matrix, then return the dimension of <var>x</var>. 
+Otherwise, return 0. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002drows.html#doc_002drows">rows</a>, <a href="doc_002dcolumns.html#doc_002dcolumns">columns</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002dismatrix.html#doc_002dismatrix">ismatrix</a>, <a href="doc_002disscalar.html#doc_002disscalar">isscalar</a>, <a href="doc_002disvector.html#doc_002disvector">isvector</a>. 
+</p></blockquote></div>
+
+<!-- ./general/issymmetric.m -->
+   <p><a name="doc_002dissymmetric"></a>
+
+<div class="defun">
+— Function File:  <b>issymmetric</b> (<var>x, tol</var>)<var><a name="index-issymmetric-275"></a></var><br>
+<blockquote><p>If <var>x</var> is symmetric within the tolerance specified by <var>tol</var>,
+then return the dimension of <var>x</var>.  Otherwise, return 0.  If
+<var>tol</var> is omitted, use a tolerance equal to the machine precision. 
+Matrix <var>x</var> is considered symmetric if
+<code>norm (</code><var>x</var><code> - </code><var>x</var><code>.', inf) / norm (</code><var>x</var><code>, inf) < </code><var>tol</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsize.html#doc_002dsize">size</a>, <a href="doc_002drows.html#doc_002drows">rows</a>, <a href="doc_002dcolumns.html#doc_002dcolumns">columns</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002dismatrix.html#doc_002dismatrix">ismatrix</a>, <a href="doc_002disscalar.html#doc_002disscalar">isscalar</a>, <a href="doc_002dissquare.html#doc_002dissquare">issquare</a>, <a href="doc_002disvector.html#doc_002disvector">isvector</a>. 
+</p></blockquote></div>
+
+<!-- ./general/isdefinite.m -->
+   <p><a name="doc_002disdefinite"></a>
+
+<div class="defun">
+— Function File:  <b>isdefinite</b> (<var>x, tol</var>)<var><a name="index-isdefinite-276"></a></var><br>
+<blockquote><p>Return 1 if <var>x</var> is symmetric positive definite within the
+tolerance specified by <var>tol</var> or 0 if <var>x</var> is symmetric
+positive semidefinite.  Otherwise, return -1.  If <var>tol</var>
+is omitted, use a tolerance equal to 100 times the machine precision. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dissymmetric.html#doc_002dissymmetric">issymmetric</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dislogical"></a>
+
+<div class="defun">
+— Built-in Function:  <b>islogical</b> (<var>x</var>)<var><a name="index-islogical-277"></a></var><br>
+<blockquote><p>Return true if <var>x</var> is a logical object. 
+</p></blockquote></div>
+
+<!-- ./specfun/isprime.m -->
+   <p><a name="doc_002disprime"></a>
+
+<div class="defun">
+— Function File:  <b>isprime</b> (<var>n</var>)<var><a name="index-isprime-278"></a></var><br>
+<blockquote>
+        <p>Return true if <var>n</var> is a prime number, false otherwise.
+
+        <p>Something like the following is much faster if you need to test a lot
+of small numbers:
+
+     <pre class="example">             <var>t</var> = ismember (<var>n</var>, primes (max (<var>n</var> (:))));
+</pre>
+        <p>If max(n) is very large, then you should be using special purpose
+factorization code.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprimes.html#doc_002dprimes">primes</a>, <a href="doc_002dfactor.html#doc_002dfactor">factor</a>, <a href="doc_002dgcd.html#doc_002dgcd">gcd</a>, <a href="doc_002dlcm.html#doc_002dlcm">lcm</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, -->
+<!-- 2006, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Preface.html b/doc/interpreter/HTML/Preface.html
new file mode 100644
index 0000000..c378f50
--- /dev/null
+++ b/doc/interpreter/HTML/Preface.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Preface - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="index.html#Top" title="Top">
+<link rel="next" href="Introduction.html#Introduction" title="Introduction">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<h1 class="settitle">Untitled</h1>
+<div class="node">
+<p>
+<a name="Preface"></a>
+Next: <a rel="next" accesskey="n" href="Introduction.html#Introduction">Introduction</a>,
+Previous: <a rel="previous" accesskey="p" href="index.html#Top">Top</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Preface</h2>
+
+<p><a name="index-contributors-1"></a><a name="index-history-2"></a>
+Octave was originally intended to be companion software for an
+undergraduate-level textbook on chemical reactor design being written by
+James B. Rawlings of the University of Wisconsin-Madison and John
+G. Ekerdt of the University of Texas.
+
+   <p>Clearly, Octave is now much more than just another `courseware' package
+with limited utility beyond the classroom.  Although our initial goals
+were somewhat vague, we knew that we wanted to create something that
+would enable students to solve realistic problems, and that they could
+use for many things other than chemical reactor design problems.
+
+   <p>There are those who would say that we should be teaching the students
+Fortran instead, because that is the computer language of engineering,
+but every time we have tried that, the students have spent far too much
+time trying to figure out why their Fortran code crashes and not enough
+time learning about chemical engineering.  With Octave, most students
+pick up the basics quickly, and are using it confidently in just a few
+hours.
+
+   <p>Although it was originally intended to be used to teach reactor design,
+it has been used in several other undergraduate and graduate
+courses in the Chemical Engineering Department at the University of
+Texas, and the math department at the University of Texas has been using
+it for teaching differential equations and linear algebra as well.  If
+you find it useful, please let us know.  We are always interested to
+find out how Octave is being used in other places.
+
+   <p>Virtually everyone thinks that the name Octave has something to do with
+music, but it is actually the name of a former professor of mine who
+wrote a famous textbook on chemical reaction engineering, and who was
+also well known for his ability to do quick `back of the envelope'
+calculations.  We hope that this software will make it possible for many
+people to do more ambitious computations just as easily.
+
+   <p>Everyone is encouraged to share this software with others under the
+terms of the GNU General Public License (see <a href="Copying.html#Copying">Copying</a>).  You are
+also encouraged to help make Octave more useful by writing and
+contributing additional functions for it, and by reporting any problems
+you may have.
+
+<ul class="menu">
+<li><a accesskey="1" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>
+<li><a accesskey="2" href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a>
+<li><a accesskey="3" href="Distribution.html#Distribution">Distribution</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Printing-Notation.html b/doc/interpreter/HTML/Printing-Notation.html
new file mode 100644
index 0000000..d48f60e
--- /dev/null
+++ b/doc/interpreter/HTML/Printing-Notation.html
@@ -0,0 +1,49 @@
+<html lang="en">
+<head>
+<title>Printing Notation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Conventions.html#Conventions" title="Conventions">
+<link rel="prev" href="Evaluation-Notation.html#Evaluation-Notation" title="Evaluation Notation">
+<link rel="next" href="Error-Messages.html#Error-Messages" title="Error Messages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Printing-Notation"></a>
+Next: <a rel="next" accesskey="n" href="Error-Messages.html#Error-Messages">Error Messages</a>,
+Previous: <a rel="previous" accesskey="p" href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a>,
+Up: <a rel="up" accesskey="u" href="Conventions.html#Conventions">Conventions</a>
+<hr>
+</div>
+
+<h4 class="subsection">1.3.3 Printing Notation</h4>
+
+<p><a name="index-printing-notation-13"></a>
+Many of the examples in this manual print text when they are
+evaluated.  In this manual the printed text resulting from an example
+is indicated by ‘<samp><span class="samp">-|</span></samp>’.  The value that is returned by
+evaluating the expression is displayed with ‘<samp></samp>’
+(<code>1</code> in the next example) and follows on a separate line.
+
+<pre class="example">     printf ("foo %s\n", "bar")
+          -| foo bar
+           1
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Printing-Plots.html b/doc/interpreter/HTML/Printing-Plots.html
new file mode 100644
index 0000000..eb15db5
--- /dev/null
+++ b/doc/interpreter/HTML/Printing-Plots.html
@@ -0,0 +1,161 @@
+<html lang="en">
+<head>
+<title>Printing Plots - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Multiple-Plot-Windows.html#Multiple-Plot-Windows" title="Multiple Plot Windows">
+<link rel="next" href="Interacting-with-plots.html#Interacting-with-plots" title="Interacting with plots">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Printing-Plots"></a>
+Next: <a rel="next" accesskey="n" href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a>,
+Previous: <a rel="previous" accesskey="p" href="Multiple-Plot-Windows.html#Multiple-Plot-Windows">Multiple Plot Windows</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.6 Printing Plots</h4>
+
+<p>The <code>print</code> command allows you to save plots in a variety of
+formats.  For example,
+
+<pre class="example">     print -deps foo.eps
+</pre>
+   <p class="noindent">writes the current figure to an encapsulated PostScript file called
+<samp><span class="file">foo.eps</span></samp>.
+
+<!-- ./plot/print.m -->
+   <p><a name="doc_002dprint"></a>
+
+<div class="defun">
+— Function File:  <b>print</b> ()<var><a name="index-print-1094"></a></var><br>
+— Function File:  <b>print</b> (<var>options</var>)<var><a name="index-print-1095"></a></var><br>
+— Function File:  <b>print</b> (<var>filename, options</var>)<var><a name="index-print-1096"></a></var><br>
+— Function File:  <b>print</b> (<var>h, filename, options</var>)<var><a name="index-print-1097"></a></var><br>
+<blockquote><p>Print a graph, or save it to a file
+
+        <p><var>filename</var> defines the file name of the output file.  If no
+filename is specified, the output is sent to the printer.
+
+        <p><var>h</var> specifies the figure handle.  If no handle is specified
+the handle for the current figure is used.
+
+        <p><var>options</var>:
+          <dl>
+<dt><code>-P</code><var>printer</var><dd>  Set the <var>printer</var> name to which the graph is sent if no
+<var>filename</var> is specified. 
+<br><dt><code>-G</code><var>ghostscript_command</var><dd>  Specify the command for calling Ghostscript.  For Unix and Windows,
+the defaults are 'gs' and 'gswin32c', respectively. 
+<br><dt><code>-color</code><dt><code>-mono</code><dd>  Monochrome or color lines. 
+<br><dt><code>-solid</code><dt><code>-dashed</code><dd>  Solid or dashed lines. 
+<br><dt><code>-portrait</code><dt><code>-landscape</code><dd>  Specify the orientation of the plot for printed output. 
+<br><dt><code>-d</code><var>device</var><dd>  Output device, where <var>device</var> is one of:
+               <dl>
+<dt><code>ps</code><dt><code>ps2</code><dt><code>psc</code><dt><code>psc2</code><dd>    Postscript (level 1 and 2, mono and color)
+<br><dt><code>eps</code><dt><code>eps2</code><dt><code>epsc</code><dt><code>epsc2</code><dd>    Encapsulated postscript (level 1 and 2, mono and color)
+<br><dt><code>tex</code><dt><code>epslatex</code><dt><code>epslatexstandalone</code><dt><code>pstex</code><dt><code>pslatex</code><dd>    Generate a LaTeX (or TeX) file for labels, and eps/ps for
+graphics.  The file produced by <code>epslatexstandalone</code> can be
+processed directly by LaTeX.  The other formats are intended to
+be included in a LaTeX (or TeX) document.  The <code>tex</code> device
+is the same as the <code>epslatex</code> device. 
+<br><dt><code>ill</code><dt><code>aifm</code><dd>    Adobe Illustrator
+<br><dt><code>cdr</code><dt><code>corel</code><dd>    CorelDraw
+<br><dt><code>dxf</code><dd>    AutoCAD
+<br><dt><code>emf</code><dt><code>meta</code><dd>    Microsoft Enhanced Metafile
+<br><dt><code>fig</code><dd>    XFig.  If this format is selected the additional options
+<code>-textspecial</code> or <code>-textnormal</code> can be used to control
+    whether the special flag should be set for the text in
+    the figure (default is <code>-textnormal</code>). 
+<br><dt><code>hpgl</code><dd>    HP plotter language
+<br><dt><code>mf</code><dd>    Metafont
+<br><dt><code>png</code><dd>    Portable network graphics
+<br><dt><code>jpg</code><dt><code>jpeg</code><dd>    JPEG image
+<br><dt><code>gif</code><dd>    GIF image
+<br><dt><code>pbm</code><dd>    PBMplus
+<br><dt><code>svg</code><dd>    Scalable vector graphics
+<br><dt><code>pdf</code><dd>    Portable document format
+</dl>
+
+          <p>If the device is omitted, it is inferred from the file extension,
+or if there is no filename it is sent to the printer as postscript.
+
+          <br><dt><code>-d</code><var>gs_device</var><dd>  Additional devices are supported by Ghostscript. 
+Some examples are;
+
+               <dl>
+<dt><code>ljet2p</code><dd>    HP LaserJet IIP
+<br><dt><code>ljet3</code><dd>    HP LaserJet III
+<br><dt><code>deskjet</code><dd>    HP DeskJet and DeskJet Plus
+<br><dt><code>cdj550</code><dd>    HP DeskJet 550C
+<br><dt><code>paintjet</code><dd>    HP PointJet
+<br><dt><code>pcx24b</code><dd>    24-bit color PCX file format
+<br><dt><code>ppm</code><dd>    Portable Pixel Map file format
+</dl>
+
+          <p>For a complete list, type `system ("gs -h")' to see what formats
+and devices are available.
+
+          <p>When the ghostscript is sent to a printer the size is determined
+by the figure's "papersize" property.  When the ghostscript output
+is sent to a file the size is determined by the figure's
+"paperposition" property.
+
+          <dt><code>-r</code><var>NUM</var><dd>  Resolution of bitmaps in pixels per inch.  For both metafiles and
+SVG the default is the screen resolution, for other it is 150 dpi. 
+To specify screen resolution, use "-r0".
+
+          <br><dt><code>-tight</code><dd>  Forces a tight bounding box for eps-files.  Since the ghostscript
+devices are conversion of an eps-file, this option works the those
+devices as well.
+
+          <dt><code>-S</code><var>xsize</var><code>,</code><var>ysize</var><dd>  Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG.  If
+using the command form of the print function, you must quote the
+<var>xsize</var>,<var>ysize</var> option.  For example, by writing
+<code>"-S640,480"</code><!-- /@w -->.  The size defaults to that specified by the
+figure's paperposition property.
+
+          <br><dt><code>-F</code><var>fontname</var><dt><code>-F</code><var>fontname</var><code>:</code><var>size</var><dt><code>-F:</code><var>size</var><dd><var>fontname</var> set the postscript font (for use with postscript,
+aifm, corel and fig).  By default, 'Helvetica' is set for PS/Aifm,
+and 'SwitzerlandLight' for Corel.  It can also be 'Times-Roman'. 
+<var>size</var> is given in points.  <var>fontname</var> is ignored for the
+fig device. 
+</dl>
+
+        <p>The filename and options can be given in any order. 
+</p></blockquote></div>
+
+<!-- ./plot/orient.m -->
+   <p><a name="doc_002dorient"></a>
+
+<div class="defun">
+— Function File:  <b>orient</b> (<var>orientation</var>)<var><a name="index-orient-1098"></a></var><br>
+<blockquote><p>Set the default print orientation.  Valid values for
+<var>orientation</var> include <code>"landscape"</code>, <code>"portrait"</code>,
+and <code>"tall"</code>.
+
+        <p>The <code>"tall"</code> option sets the orientation to portait and fills
+the page with the plot, while leaving a 0.25in border.
+
+        <p>If called with no arguments, return the default print orientation. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Private-Functions.html b/doc/interpreter/HTML/Private-Functions.html
new file mode 100644
index 0000000..140beac
--- /dev/null
+++ b/doc/interpreter/HTML/Private-Functions.html
@@ -0,0 +1,58 @@
+<html lang="en">
+<head>
+<title>Private Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="prev" href="Subfunctions.html#Subfunctions" title="Subfunctions">
+<link rel="next" href="Overloading-and-Autoloading.html#Overloading-and-Autoloading" title="Overloading and Autoloading">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Private-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a>,
+Previous: <a rel="previous" accesskey="p" href="Subfunctions.html#Subfunctions">Subfunctions</a>,
+Up: <a rel="up" accesskey="u" href="Function-Files.html#Function-Files">Function Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.7.3 Private Functions</h4>
+
+<p>In many cases one function needs to access one or more helper
+functions.  If the helper function is limited to the scope of a single
+function, then subfunctions as discussed above might be used.  However,
+if a single helper function is used by more than one function, then
+this is no longer possible.  In this case the helper functions might
+be placed in a subdirectory, called "private", of the directory in which
+the functions needing access to this helper function are found.
+
+   <p>As a simple example, consider a function <code>func1</code>, that calls a helper
+function <code>func2</code> to do much of the work.  For example
+
+<pre class="example">     function y = func1 (x)
+       y = func2 (x);
+     endfunction
+</pre>
+   <p class="noindent">Then if the path to <code>func1</code> is <code><directory>/func1.m</code>, and if
+<code>func2</code> is found in the directory <code><directory>/private/func2.m</code>,
+then <code>func2</code> is only available for use of the functions, like
+<code>func1</code>, that are found in <code><directory></code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Process-ID-Information.html b/doc/interpreter/HTML/Process-ID-Information.html
new file mode 100644
index 0000000..9d8efec
--- /dev/null
+++ b/doc/interpreter/HTML/Process-ID-Information.html
@@ -0,0 +1,94 @@
+<html lang="en">
+<head>
+<title>Process ID Information - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Controlling-Subprocesses.html#Controlling-Subprocesses" title="Controlling Subprocesses">
+<link rel="next" href="Environment-Variables.html#Environment-Variables" title="Environment Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Process-ID-Information"></a>
+Next: <a rel="next" accesskey="n" href="Environment-Variables.html#Environment-Variables">Environment Variables</a>,
+Previous: <a rel="previous" accesskey="p" href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.6 Process, Group, and User IDs</h3>
+
+<!-- syscalls.cc -->
+<p><a name="doc_002dgetpgrp"></a>
+
+<div class="defun">
+— Built-in Function: pgid = <b>getpgrp</b> ()<var><a name="index-getpgrp-2415"></a></var><br>
+<blockquote><p>Return the process group id of the current process. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dgetpid"></a>
+
+<div class="defun">
+— Built-in Function: pid = <b>getpid</b> ()<var><a name="index-getpid-2416"></a></var><br>
+<blockquote><p>Return the process id of the current process. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dgetppid"></a>
+
+<div class="defun">
+— Built-in Function: pid = <b>getppid</b> ()<var><a name="index-getppid-2417"></a></var><br>
+<blockquote><p>Return the process id of the parent process. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dgeteuid"></a>
+
+<div class="defun">
+— Built-in Function: euid = <b>geteuid</b> ()<var><a name="index-geteuid-2418"></a></var><br>
+<blockquote><p>Return the effective user id of the current process. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dgetuid"></a>
+
+<div class="defun">
+— Built-in Function: uid = <b>getuid</b> ()<var><a name="index-getuid-2419"></a></var><br>
+<blockquote><p>Return the real user id of the current process. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dgetegid"></a>
+
+<div class="defun">
+— Built-in Function: egid = <b>getegid</b> ()<var><a name="index-getegid-2420"></a></var><br>
+<blockquote><p>Return the effective group id of the current process. 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002dgetgid"></a>
+
+<div class="defun">
+— Built-in Function: gid = <b>getgid</b> ()<var><a name="index-getgid-2421"></a></var><br>
+<blockquote><p>Return the real group id of the current process. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Processing-Data-in-Cell-Arrays.html b/doc/interpreter/HTML/Processing-Data-in-Cell-Arrays.html
new file mode 100644
index 0000000..2544020
--- /dev/null
+++ b/doc/interpreter/HTML/Processing-Data-in-Cell-Arrays.html
@@ -0,0 +1,156 @@
+<html lang="en">
+<head>
+<title>Processing Data in Cell Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Cell-Arrays.html#Cell-Arrays" title="Cell Arrays">
+<link rel="prev" href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings" title="Cell Arrays of Strings">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Processing-Data-in-Cell-Arrays"></a>
+Previous: <a rel="previous" accesskey="p" href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a>,
+Up: <a rel="up" accesskey="u" href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.2.5 Processing Data in Cell Arrays</h4>
+
+<p>Data that is stored in a cell array can be processed in several ways
+depending on the actual data.  The simplest way to process that data
+is to iterate through it using one or more <code>for</code> loops.  The same
+idea can be implemented more easily through the use of the <code>cellfun</code>
+function that calls a user-specified function on all elements of a cell
+array.
+
+<!-- ./DLD-FUNCTIONS/cellfun.cc -->
+   <p><a name="doc_002dcellfun"></a>
+
+<div class="defun">
+— Loadable Function:  <b>cellfun</b> (<var>name, c</var>)<var><a name="index-cellfun-400"></a></var><br>
+— Loadable Function:  <b>cellfun</b> (<var>"size", c, k</var>)<var><a name="index-cellfun-401"></a></var><br>
+— Loadable Function:  <b>cellfun</b> (<var>"isclass", c, class</var>)<var><a name="index-cellfun-402"></a></var><br>
+— Loadable Function:  <b>cellfun</b> (<var>func, c</var>)<var><a name="index-cellfun-403"></a></var><br>
+— Loadable Function:  <b>cellfun</b> (<var>func, c, d</var>)<var><a name="index-cellfun-404"></a></var><br>
+— Loadable Function: [<var>a</var>, <var>b</var>] = <b>cellfun</b> (<var><small class="dots">...</small></var>)<var><a name="index-cellfun-405"></a></var><br>
+— Loadable Function:  <b>cellfun</b> (<var><small class="dots">...</small>, 'ErrorHandler', errfunc</var>)<var><a name="index-cellfun-406"></a></var><br>
+— Loadable Function:  <b>cellfun</b> (<var><small class="dots">...</small>, 'UniformOutput', val</var>)<var><a name="index-cellfun-407"></a></var><br>
+<blockquote>
+        <p>Evaluate the function named <var>name</var> on the elements of the cell array
+<var>c</var>.  Elements in <var>c</var> are passed on to the named function
+individually.  The function <var>name</var> can be one of the functions
+
+          <dl>
+<dt><code>isempty</code><dd>Return 1 for empty elements. 
+<br><dt><code>islogical</code><dd>Return 1 for logical elements. 
+<br><dt><code>isreal</code><dd>Return 1 for real elements. 
+<br><dt><code>length</code><dd>Return a vector of the lengths of cell elements. 
+<br><dt><code>ndims</code><dd>Return the number of dimensions of each element. 
+<br><dt><code>prodofsize</code><dd>Return the product of dimensions of each element. 
+<br><dt><code>size</code><dd>Return the size along the <var>k</var>-th dimension. 
+<br><dt><code>isclass</code><dd>Return 1 for elements of <var>class</var>. 
+</dl>
+
+        <p>Additionally, <code>cellfun</code> accepts an arbitrary function <var>func</var>
+in the form of an inline function, function handle, or the name of a
+function (in a character string).  In the case of a character string
+argument, the function must accept a single argument named <var>x</var>, and
+it must return a string value.  The function can take one or more arguments,
+with the inputs args given by <var>c</var>, <var>d</var>, etc.  Equally the function
+can return one or more output arguments.  For example
+
+     <pre class="example">          cellfun (@atan2, {1, 0}, {0, 1})
+          ans = [1.57080   0.00000]
+</pre>
+        <p>Note that the default output argument is an array of the same size as the
+input arguments.
+
+        <p>If the parameter 'UniformOutput' is set to true (the default), then the function
+must return a single element which will be concatenated into the
+return value.  If 'UniformOutput' is false, the outputs are concatenated in
+a cell array.  For example
+
+     <pre class="example">          cellfun ("tolower(x)", {"Foo", "Bar", "FooBar"},
+                   "UniformOutput",false)
+           ans = {"foo", "bar", "foobar"}
+</pre>
+        <p>Given the parameter 'ErrorHandler', then <var>errfunc</var> defines a function to
+call in case <var>func</var> generates an error.  The form of the function is
+
+     <pre class="example">          function [...] = errfunc (<var>s</var>, ...)
+</pre>
+        <p>where there is an additional input argument to <var>errfunc</var> relative to
+<var>func</var>, given by <var>s</var>.  This is a structure with the elements
+'identifier', 'message' and 'index', giving respectively the error
+identifier, the error message, and the index into the input arguments
+of the element that caused the error.  For example
+
+     <pre class="example">          function y = foo (s, x), y = NaN; endfunction
+          cellfun (@factorial, {-1,2},'ErrorHandler', at foo)
+           ans = [NaN 2]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disempty.html#doc_002disempty">isempty</a>, <a href="doc_002dislogical.html#doc_002dislogical">islogical</a>, <a href="doc_002disreal.html#doc_002disreal">isreal</a>, <a href="doc_002dlength.html#doc_002dlength">length</a>, <a href="doc_002dndims.html#doc_002dndims">ndims</a>, <a href="doc_002dnumel.html#doc_002dnumel">numel</a>, <a href="doc_002dsize.html#doc_002dsize">size</a>. 
+</p></blockquote></div>
+
+   <p>An alternative is to convert the data to a different container, such as
+a matrix or a data structure.  Depending on the data this is possible
+using the <code>cell2mat</code> and <code>cell2struct</code> functions.
+
+<!-- ./general/cell2mat.m -->
+   <p><a name="doc_002dcell2mat"></a>
+
+<div class="defun">
+— Function File: <var>m</var> = <b>cell2mat</b> (<var>c</var>)<var><a name="index-cell2mat-408"></a></var><br>
+<blockquote><p>Convert the cell array <var>c</var> into a matrix by concatenating all
+elements of <var>c</var> into a hyperrectangle.  Elements of <var>c</var> must
+be numeric, logical or char, and <code>cat</code> must be able to
+concatenate them together. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmat2cell.html#doc_002dmat2cell">mat2cell</a>, <a href="doc_002dnum2cell.html#doc_002dnum2cell">num2cell</a>. 
+</p></blockquote></div>
+
+<!-- ov-struct.cc -->
+   <p><a name="doc_002dcell2struct"></a>
+
+<div class="defun">
+— Built-in Function:  <b>cell2struct</b> (<var>cell, fields, dim</var>)<var><a name="index-cell2struct-409"></a></var><br>
+<blockquote><p>Convert <var>cell</var> to a structure.  The number of fields in <var>fields</var>
+must match the number of elements in <var>cell</var> along dimension <var>dim</var>,
+that is <code>numel (</code><var>fields</var><code>) == size (</code><var>cell</var><code>, </code><var>dim</var><code>)</code>.
+
+     <pre class="example">          A = cell2struct ({'Peter', 'Hannah', 'Robert';
+                             185, 170, 168},
+                           {'Name','Height'}, 1);
+          A(1)
+           ans =
+                {
+                  Height = 185
+                  Name   = Peter
+                }
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Processing-Data-in-Structures.html b/doc/interpreter/HTML/Processing-Data-in-Structures.html
new file mode 100644
index 0000000..d174031
--- /dev/null
+++ b/doc/interpreter/HTML/Processing-Data-in-Structures.html
@@ -0,0 +1,107 @@
+<html lang="en">
+<head>
+<title>Processing Data in Structures - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Structures.html#Data-Structures" title="Data Structures">
+<link rel="prev" href="Manipulating-Structures.html#Manipulating-Structures" title="Manipulating Structures">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Processing-Data-in-Structures"></a>
+Previous: <a rel="previous" accesskey="p" href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a>,
+Up: <a rel="up" accesskey="u" href="Data-Structures.html#Data-Structures">Data Structures</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.1.5 Processing Data in Structures</h4>
+
+<p>The simplest way to process data in a structure is within a <code>for</code>
+loop (see <a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a>).  A similar effect can be
+achieved with the <code>structfun</code> function, where a user defined
+function is applied to each field of the structure.
+
+<!-- ./general/structfun.m -->
+   <p><a name="doc_002dstructfun"></a>
+
+<div class="defun">
+— Function File:  <b>structfun</b> (<var>func, s</var>)<var><a name="index-structfun-382"></a></var><br>
+— Function File: [<var>a</var>, <var>b</var>] = <b>structfun</b> (<var><small class="dots">...</small></var>)<var><a name="index-structfun-383"></a></var><br>
+— Function File:  <b>structfun</b> (<var><small class="dots">...</small>, "ErrorHandler", errfunc</var>)<var><a name="index-structfun-384"></a></var><br>
+— Function File:  <b>structfun</b> (<var><small class="dots">...</small>, "UniformOutput", val</var>)<var><a name="index-structfun-385"></a></var><br>
+<blockquote>
+        <p>Evaluate the function named <var>name</var> on the fields of the structure
+<var>s</var>.  The fields of <var>s</var> are passed to the function <var>func</var>
+individually.
+
+        <p><code>structfun</code> accepts an arbitrary function <var>func</var> in the form of
+an inline function, function handle, or the name of a function (in a
+character string).  In the case of a character string argument, the
+function must accept a single argument named <var>x</var>, and it must return
+a string value.  If the function returns more than one argument, they are
+returned as separate output variables.
+
+        <p>If the parameter "UniformOutput" is set to true (the default), then the function
+must return a single element which will be concatenated into the
+return value.  If "UniformOutput" is false, the outputs placed in a structure
+with the same fieldnames as the input structure.
+
+     <pre class="example">          s.name1 = "John Smith";
+          s.name2 = "Jill Jones";
+          structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
+                     "UniformOutput", false)
+</pre>
+        <p>Given the parameter "ErrorHandler", then <var>errfunc</var> defines a function to
+call in case <var>func</var> generates an error.  The form of the function is
+
+     <pre class="example">          function [...] = errfunc (<var>se</var>, ...)
+</pre>
+        <p>where there is an additional input argument to <var>errfunc</var> relative to
+<var>func</var>, given by <var>se</var>.  This is a structure with the elements
+"identifier", "message" and "index", giving respectively the error
+identifier, the error message, and the index into the input arguments
+of the element that caused the error. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcellfun.html#doc_002dcellfun">cellfun</a>, <a href="doc_002darrayfun.html#doc_002darrayfun">arrayfun</a>. 
+</p></blockquote></div>
+
+   <p>Alternatively, to process the data in a structure, the structure might
+be converted to another type of container before being treated.
+
+<!-- ov-cell.cc -->
+   <p><a name="doc_002dstruct2cell"></a>
+
+<div class="defun">
+— Built-in Function:  <b>struct2cell</b> (<var>S</var>)<var><a name="index-struct2cell-386"></a></var><br>
+<blockquote><p>Create a new cell array from the objects stored in the struct object. 
+If <var>f</var> is the number of fields in the structure, the resulting
+cell array will have a dimension vector corresponding to
+<code>[</code><var>F</var><code> size(</code><var>S</var><code>)]</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcell2struct.html#doc_002dcell2struct">cell2struct</a>, <a href="doc_002dfieldnames.html#doc_002dfieldnames">fieldnames</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Products-of-Polynomials.html b/doc/interpreter/HTML/Products-of-Polynomials.html
new file mode 100644
index 0000000..aee972e
--- /dev/null
+++ b/doc/interpreter/HTML/Products-of-Polynomials.html
@@ -0,0 +1,226 @@
+<html lang="en">
+<head>
+<title>Products of Polynomials - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link rel="prev" href="Finding-Roots.html#Finding-Roots" title="Finding Roots">
+<link rel="next" href="Derivatives-and-Integrals.html#Derivatives-and-Integrals" title="Derivatives and Integrals">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Products-of-Polynomials"></a>
+Next: <a rel="next" accesskey="n" href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a>,
+Previous: <a rel="previous" accesskey="p" href="Finding-Roots.html#Finding-Roots">Finding Roots</a>,
+Up: <a rel="up" accesskey="u" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<hr>
+</div>
+
+<h3 class="section">27.3 Products of Polynomials</h3>
+
+<!-- ./polynomial/conv.m -->
+<p><a name="doc_002dconv"></a>
+
+<div class="defun">
+— Function File:  <b>conv</b> (<var>a, b</var>)<var><a name="index-conv-2031"></a></var><br>
+<blockquote><p>Convolve two vectors.
+
+        <p><code>y = conv (a, b)</code> returns a vector of length equal to
+<code>length (a) + length (b) - 1</code>. 
+If <var>a</var> and <var>b</var> are polynomial coefficient vectors, <code>conv</code>
+returns the coefficients of the product polynomial. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/convn.m -->
+   <p><a name="doc_002dconvn"></a>
+
+<div class="defun">
+— Function File: <var>c</var> = <b>convn</b> (<var>a, b, shape</var>)<var><a name="index-convn-2032"></a></var><br>
+<blockquote><p>N-dimensional convolution of matrices <var>a</var> and <var>b</var>.
+
+        <p>The size of the output is determined by the <var>shape</var> argument. 
+This can be any of the following character strings:
+
+          <dl>
+<dt>"full"<dd>The full convolution result is returned.  The size out of the output is
+<code>size (</code><var>a</var><code>) + size (</code><var>b</var><code>)-1</code>.  This is the default behavior. 
+<br><dt>"same"<dd>The central part of the convolution result is returned.  The size out of the
+output is the same as <var>a</var>. 
+<br><dt>"valid"<dd>The valid part of the convolution is returned.  The size of the result is
+<code>max (size (</code><var>a</var><code>) - size (</code><var>b</var><code>)+1, 0)</code>. 
+</dl>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002dconv2.html#doc_002dconv2">conv2</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/deconv.m -->
+   <p><a name="doc_002ddeconv"></a>
+
+<div class="defun">
+— Function File:  <b>deconv</b> (<var>y, a</var>)<var><a name="index-deconv-2033"></a></var><br>
+<blockquote><p>Deconvolve two vectors.
+
+        <p><code>[b, r] = deconv (y, a)</code> solves for <var>b</var> and <var>r</var> such that
+<code>y = conv (a, b) + r</code>.
+
+        <p>If <var>y</var> and <var>a</var> are polynomial coefficient vectors, <var>b</var> will
+contain the coefficients of the polynomial quotient and <var>r</var> will be
+a remainder polynomial of lowest order. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/conv2.cc -->
+   <p><a name="doc_002dconv2"></a>
+
+<div class="defun">
+— Loadable Function: y = <b>conv2</b> (<var>a, b, shape</var>)<var><a name="index-conv2-2034"></a></var><br>
+— Loadable Function: y = <b>conv2</b> (<var>v1, v2, M, shape</var>)<var><a name="index-conv2-2035"></a></var><br>
+<blockquote>
+        <p>Returns 2D convolution of <var>a</var> and <var>b</var> where the size
+of <var>c</var> is given by
+
+          <dl>
+<dt><var>shape</var>= 'full'<dd>returns full 2-D convolution
+<br><dt><var>shape</var>= 'same'<dd>same size as a. 'central' part of convolution
+<br><dt><var>shape</var>= 'valid'<dd>only parts which do not include zero-padded edges
+</dl>
+
+        <p>By default <var>shape</var> is 'full'.  When the third argument is a matrix
+returns the convolution of the matrix <var>M</var> by the vector <var>v1</var>
+in the column direction and by vector <var>v2</var> in the row direction
+</p></blockquote></div>
+
+<!-- ./polynomial/polygcd.m -->
+   <p><a name="doc_002dpolygcd"></a>
+
+<div class="defun">
+— Function File: <var>q</var> = <b>polygcd</b> (<var>b, a, tol</var>)<var><a name="index-polygcd-2036"></a></var><br>
+<blockquote>
+        <p>Find greatest common divisor of two polynomials.  This is equivalent
+to the polynomial found by multiplying together all the common roots. 
+Together with deconv, you can reduce a ratio of two polynomials. 
+Tolerance defaults to
+     <pre class="example">          sqrt(eps).
+</pre>
+        <p>Note that this is an unstable
+algorithm, so don't try it on large polynomials.
+
+        <p>Example
+     <pre class="example">          polygcd (poly(1:8), poly(3:12)) - poly(3:8)
+           [ 0, 0, 0, 0, 0, 0, 0 ]
+          deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))) ...
+            - poly(1:2)
+           [ 0, 0, 0 ]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyreduce.html#doc_002dpolyreduce">polyreduce</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dresidue.html#doc_002dresidue">residue</a>, <a href="doc_002dfilter.html#doc_002dfilter">filter</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyvalm.html#doc_002dpolyvalm">polyvalm</a>. 
+</p></blockquote></div>
+
+<!-- ./polynomial/residue.m -->
+   <p><a name="doc_002dresidue"></a>
+
+<div class="defun">
+— Function File: [<var>r</var>, <var>p</var>, <var>k</var>, <var>e</var>] = <b>residue</b> (<var>b, a</var>)<var><a name="index-residue-2037"></a></var><br>
+<blockquote><p>Compute the partial fraction expansion for the quotient of the
+polynomials, <var>b</var> and <var>a</var>.
+
+     <pre class="example">           B(s)    M       r(m)         N
+           ---- = SUM -------------  + SUM k(i)*s^(N-i)
+           A(s)   m=1 (s-p(m))^e(m)    i=1
+</pre>
+        <p class="noindent">where M is the number of poles (the length of the <var>r</var>,
+<var>p</var>, and <var>e</var>), the <var>k</var> vector is a polynomial of order N-1
+representing the direct contribution, and the <var>e</var> vector specifies
+the multiplicity of the m-th residue's pole.
+
+        <p>For example,
+
+     <pre class="example">          b = [1, 1, 1];
+          a = [1, -5, 8, -4];
+          [r, p, k, e] = residue (b, a);
+                r = [-2; 7; 3]
+                p = [2; 2; 1]
+                k = [](0x0)
+                e = [1; 2; 1]
+</pre>
+        <p class="noindent">which represents the following partial fraction expansion
+
+     <pre class="example">                  s^2 + s + 1       -2        7        3
+             ------------------- = ----- + ------- + -----
+             s^3 - 5s^2 + 8s - 4   (s-2)   (s-2)^2   (s-1)
+</pre>
+        — Function File: [<var>b</var>, <var>a</var>] = <b>residue</b> (<var>r, p, k</var>)<var><a name="index-residue-2038"></a></var><br>
+— Function File: [<var>b</var>, <var>a</var>] = <b>residue</b> (<var>r, p, k, e</var>)<var><a name="index-residue-2039"></a></var><br>
+<blockquote><p>Compute the reconstituted quotient of polynomials,
+<var>b</var>(s)/<var>a</var>(s), from the partial fraction expansion;
+represented by the residues, poles, and a direct polynomial specified
+by <var>r</var>, <var>p</var> and <var>k</var>, and the pole multiplicity <var>e</var>.
+
+        <p>If the multiplicity, <var>e</var>, is not explicitly specified the multiplicity is
+determined by the script mpoles.m.
+
+        <p>For example,
+
+     <pre class="example">          r = [-2; 7; 3];
+          p = [2; 2; 1];
+          k = [1, 0];
+          [b, a] = residue (r, p, k);
+                b = [1, -5, 9, -3, 1]
+                a = [1, -5, 8, -4]
+          
+          where mpoles.m is used to determine e = [1; 2; 1]
+</pre>
+        <p>Alternatively the multiplicity may be defined explicitly, for example,
+
+     <pre class="example">          r = [7; 3; -2];
+          p = [2; 1; 2];
+          k = [1, 0];
+          e = [2; 1; 1];
+          [b, a] = residue (r, p, k, e);
+                b = [1, -5, 9, -3, 1]
+                a = [1, -5, 8, -4]
+</pre>
+        <p class="noindent">which represents the following partial fraction expansion
+
+     <pre class="example">              -2        7        3         s^4 - 5s^3 + 9s^2 - 3s + 1
+             ----- + ------- + ----- + s = --------------------------
+             (s-2)   (s-2)^2   (s-1)          s^3 - 5s^2 + 8s - 4
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpoly.html#doc_002dpoly">poly</a>, <a href="doc_002droots.html#doc_002droots">roots</a>, <a href="doc_002dconv.html#doc_002dconv">conv</a>, <a href="doc_002ddeconv.html#doc_002ddeconv">deconv</a>, <a href="doc_002dmpoles.html#doc_002dmpoles">mpoles</a>, <a href="doc_002dpolyval.html#doc_002dpolyval">polyval</a>, <a href="doc_002dpolyderiv.html#doc_002dpolyderiv">polyderiv</a>, <a href="doc_002dpolyinteg.html#doc_002dpolyinteg">polyinteg</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Promotion-and-Demotion-of-Data-Types.html b/doc/interpreter/HTML/Promotion-and-Demotion-of-Data-Types.html
new file mode 100644
index 0000000..89b9f7d
--- /dev/null
+++ b/doc/interpreter/HTML/Promotion-and-Demotion-of-Data-Types.html
@@ -0,0 +1,90 @@
+<html lang="en">
+<head>
+<title>Promotion and Demotion of Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Logical-Values.html#Logical-Values" title="Logical Values">
+<link rel="next" href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects" title="Predicates for Numeric Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Promotion-and-Demotion-of-Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="Logical-Values.html#Logical-Values">Logical Values</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.7 Promotion and Demotion of Data Types</h3>
+
+<p>Many operators and functions can work with mixed data types.  For example
+
+<pre class="example">     uint8 (1) + 1
+          2
+</pre>
+   <p class="noindent">where the above operator works with an 8-bit integer and a double precision
+value and returns an 8-bit integer value.  Note that the type is demoted
+to an 8-bit integer, rather than promoted to a double precision value as
+might be expected.  The reason is that if Octave promoted values in
+expressions like the above with all numerical constants would need to be
+explicitly cast to the appropriate data type like
+
+<pre class="example">     uint8 (1) + uint8 (1)
+          2
+</pre>
+   <p class="noindent">which becomes difficult for the user to apply uniformly and might allow
+hard to find bugs to be introduced.  The same applies to single precision
+values where a mixed operation such as
+
+<pre class="example">     single (1) + 1
+          2
+</pre>
+   <p class="noindent">returns a single precision value.  The mixed operations that are valid
+and their returned data types are
+
+   <p><table summary=""><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">Mixed Operation </td><td valign="top" width="30%">Result </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">double OP single </td><td valign="top" width="30%">single </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">double OP integer </td><td valign="top" width="30%">integer </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">double OP char </td><td valign="top" width="30%">double </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">double OP logical </td><td valign="top" width="30%">double </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">single OP integer </td><td valign="top" width="30%">integer </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">single OP char </td><td valign="top" width="30%">single </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="30%">single OP logical </td><td valign="top" width="30%">single </td><td valign="top" width="20%">
+   <br></td></tr></table>
+
+   <p>The same logic applies to functions with mixed arguments such as
+
+<pre class="example">     min (single (1), 0)
+         0
+</pre>
+   <p class="noindent">where the returned value is single precision.
+
+   <p>In the case of mixed type indexed assignments, the type is not
+changed.  For example
+
+<pre class="example">     x = ones (2, 2);
+     x (1, 1) = single (2)
+          x = 2   1
+                1   1
+</pre>
+   <p class="noindent">where <code>x</code> remains of the double precision type.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Quadratic-Programming.html b/doc/interpreter/HTML/Quadratic-Programming.html
new file mode 100644
index 0000000..f2dde78
--- /dev/null
+++ b/doc/interpreter/HTML/Quadratic-Programming.html
@@ -0,0 +1,82 @@
+<html lang="en">
+<head>
+<title>Quadratic Programming - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Linear-Programming.html#Linear-Programming" title="Linear Programming">
+<link rel="next" href="Nonlinear-Programming.html#Nonlinear-Programming" title="Nonlinear Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Quadratic-Programming"></a>
+Next: <a rel="next" accesskey="n" href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>,
+Previous: <a rel="previous" accesskey="p" href="Linear-Programming.html#Linear-Programming">Linear Programming</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">24.2 Quadratic Programming</h3>
+
+<p>Octave can also solve Quadratic Programming problems, this is
+<pre class="example">     min 0.5 x'*H*x + x'*q
+</pre>
+   <p>subject to
+<pre class="example">          A*x = b
+          lb <= x <= ub
+          A_lb <= A_in*x <= A_ub
+</pre>
+   <!-- ./optimization/qp.m -->
+   <p><a name="doc_002dqp"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>obj</var>, <var>info</var>, <var>lambda</var>] = <b>qp</b> (<var>x0, H, q, A, b, lb, ub, A_lb, A_in, A_ub</var>)<var><a name="index-qp-1802"></a></var><br>
+<blockquote><p>Solve the quadratic program
+
+     <pre class="example">               min 0.5 x'*H*x + x'*q
+                x
+</pre>
+        <p>subject to
+
+     <pre class="example">               A*x = b
+               lb <= x <= ub
+               A_lb <= A_in*x <= A_ub
+</pre>
+        <p class="noindent">using a null-space active-set method.
+
+        <p>Any bound (<var>A</var>, <var>b</var>, <var>lb</var>, <var>ub</var>, <var>A_lb</var>,
+<var>A_ub</var>) may be set to the empty matrix (<code>[]</code>) if not
+present.  If the initial guess is feasible the algorithm is faster.
+
+        <p>The value <var>info</var> is a structure with the following fields:
+          <dl>
+<dt><code>solveiter</code><dd>The number of iterations required to find the solution. 
+<br><dt><code>info</code><dd>An integer indicating the status of the solution, as follows:
+               <dl>
+<dt>0<dd>The problem is feasible and convex.  Global solution found. 
+<br><dt>1<dd>The problem is not convex.  Local solution found. 
+<br><dt>2<dd>The problem is not convex and unbounded. 
+<br><dt>3<dd>Maximum number of iterations reached. 
+<br><dt>6<dd>The problem is infeasible. 
+</dl>
+          </dl>
+        </p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Quitting-Octave.html b/doc/interpreter/HTML/Quitting-Octave.html
new file mode 100644
index 0000000..ee7919e
--- /dev/null
+++ b/doc/interpreter/HTML/Quitting-Octave.html
@@ -0,0 +1,82 @@
+<html lang="en">
+<head>
+<title>Quitting Octave - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Getting-Started.html#Getting-Started" title="Getting Started">
+<link rel="prev" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line" title="Invoking Octave from the Command Line">
+<link rel="next" href="Getting-Help.html#Getting-Help" title="Getting Help">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Quitting-Octave"></a>
+Next: <a rel="next" accesskey="n" href="Getting-Help.html#Getting-Help">Getting Help</a>,
+Previous: <a rel="previous" accesskey="p" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">Invoking Octave from the Command Line</a>,
+Up: <a rel="up" accesskey="u" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<hr>
+</div>
+
+<h3 class="section">2.2 Quitting Octave</h3>
+
+<p><a name="index-exiting-octave-77"></a><a name="index-quitting-octave-78"></a>
+<!-- toplev.cc -->
+<a name="doc_002dquit"></a>
+
+<div class="defun">
+— Built-in Function:  <b>exit</b> (<var>status</var>)<var><a name="index-exit-79"></a></var><br>
+— Built-in Function:  <b>quit</b> (<var>status</var>)<var><a name="index-quit-80"></a></var><br>
+<blockquote><p>Exit the current Octave session.  If the optional integer value
+<var>status</var> is supplied, pass that value to the operating system as the
+Octave's exit status.  The default value is zero. 
+</p></blockquote></div>
+
+<!-- toplev.cc -->
+   <p><a name="doc_002datexit"></a>
+
+<div class="defun">
+— Built-in Function:  <b>atexit</b> (<var>fcn</var>)<var><a name="index-atexit-81"></a></var><br>
+— Built-in Function:  <b>atexit</b> (<var>fcn, flag</var>)<var><a name="index-atexit-82"></a></var><br>
+<blockquote><p>Register a function to be called when Octave exits.  For example,
+
+     <pre class="example">          function last_words ()
+            disp ("Bye bye");
+          endfunction
+          atexit ("last_words");
+</pre>
+        <p class="noindent">will print the message "Bye bye" when Octave exits.
+
+        <p>The additional argument <var>flag</var> will register or unregister
+<var>fcn</var> from the list of functions to be called when Octave
+exits.  If <var>flag</var> is true, the function is registered, and if
+<var>flag</var> is false, it is unregistered.  For example,
+after registering the function <code>last_words</code> above,
+
+     <pre class="example">          atexit ("last_words", false);
+</pre>
+        <p class="noindent">will remove the function from the list and Octave will not call
+<code>last_words</code> when it exits.
+
+        <p>Note that <code>atexit</code> only removes the first occurrence of a function
+from the list, so if a function was placed in the list multiple
+times with <code>atexit</code>, it must also be removed from the list
+multiple times. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Quiver-group.html b/doc/interpreter/HTML/Quiver-group.html
new file mode 100644
index 0000000..4a31490
--- /dev/null
+++ b/doc/interpreter/HTML/Quiver-group.html
@@ -0,0 +1,70 @@
+<html lang="en">
+<head>
+<title>Quiver group - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Line-series.html#Line-series" title="Line series">
+<link rel="next" href="Scatter-group.html#Scatter-group" title="Scatter group">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Quiver-group"></a>
+Next: <a rel="next" accesskey="n" href="Scatter-group.html#Scatter-group">Scatter group</a>,
+Previous: <a rel="previous" accesskey="p" href="Line-series.html#Line-series">Line series</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.7 Quiver group</h5>
+
+<p><a name="index-group-objects-1242"></a><a name="index-quiver-group-1243"></a>
+Quiver series objects are created by the <code>quiver</code> or <code>quiver3</code>
+functions.  Each <code>hggroup</code> element of the series contains three line
+objects as children representing the body and head of the arrow,
+together with a marker as the point of original of the arrows.  The
+properties of the quiver series are
+
+     <dl>
+<dt><code>autoscale</code><dt><code>autoscalefactor</code><dd>Flag whether the length of the arrows is scaled or defined directly from
+the <var>u</var>, <var>v</var> and <var>w</var> data.  If the arrow length is flagged
+as being scaled by the <code>autoscale</code> property, then the length of the
+autoscaled arrow is controlled by the <code>autoscalefactor</code>.
+
+     <br><dt><code>maxheadsize</code><dd>This property controls the size of the head of the arrows in the quiver
+series.  The default value is 0.2.
+
+     <br><dt><code>showarrowhead</code><dd>Flag whether the arrow heads are displayed in the quiver plot.
+
+     <br><dt><code>color</code><dd>The RGB color or color name of the line objects of the quiver.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the line objects of the quiver.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>The line and fill color of the marker objects at the original of the
+arrows.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>The origins of the values of the vector field.
+
+     <br><dt><code>udata</code><dt><code>vdata</code><dt><code>wdata</code><dd>The values of the vector field to plot.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>zdatasource</code><dt><code>udatasource</code><dt><code>vdatasource</code><dt><code>wdatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Raising-Errors.html b/doc/interpreter/HTML/Raising-Errors.html
new file mode 100644
index 0000000..fe36ce8
--- /dev/null
+++ b/doc/interpreter/HTML/Raising-Errors.html
@@ -0,0 +1,201 @@
+<html lang="en">
+<head>
+<title>Raising Errors - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Handling-Errors.html#Handling-Errors" title="Handling Errors">
+<link rel="next" href="Catching-Errors.html#Catching-Errors" title="Catching Errors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Raising-Errors"></a>
+Next: <a rel="next" accesskey="n" href="Catching-Errors.html#Catching-Errors">Catching Errors</a>,
+Up: <a rel="up" accesskey="u" href="Handling-Errors.html#Handling-Errors">Handling Errors</a>
+<hr>
+</div>
+
+<h4 class="subsection">12.1.1 Raising Errors</h4>
+
+<p>The most common use of errors is for checking input arguments to
+functions.  The following example calls the <code>error</code> function if
+the function <code>f</code> is called without any input arguments.
+
+<pre class="example">     function f (arg1)
+       if (nargin == 0)
+         error("not enough input arguments");
+       endif
+     endfunction
+</pre>
+   <p>When the <code>error</code> function is called, it prints the given message
+and returns to the Octave prompt.  This means that no code following
+a call to <code>error</code> will be executed.
+
+<!-- error.cc -->
+   <p><a name="doc_002derror"></a>
+
+<div class="defun">
+— Built-in Function:  <b>error</b> (<var>template, <small class="dots">...</small></var>)<var><a name="index-error-662"></a></var><br>
+— Built-in Function:  <b>error</b> (<var>id, template, <small class="dots">...</small></var>)<var><a name="index-error-663"></a></var><br>
+<blockquote><p>Format the optional arguments under the control of the template string
+<var>template</var> using the same rules as the <code>printf</code> family of
+functions (see <a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>) and print the resulting message
+on the <code>stderr</code> stream.  The message is prefixed by the character
+string ‘<samp><span class="samp">error: </span></samp>’.
+
+        <p>Calling <code>error</code> also sets Octave's internal error state such that
+control will return to the top level without evaluating any more
+commands.  This is useful for aborting from functions or scripts.
+
+        <p>If the error message does not end with a new line character, Octave will
+print a traceback of all the function calls leading to the error.  For
+example, given the following function definitions:
+
+     <pre class="example">          function f () g (); end
+          function g () h (); end
+          function h () nargin == 1 || error ("nargin != 1"); end
+</pre>
+        <p class="noindent">calling the function <code>f</code> will result in a list of messages that
+can help you to quickly locate the exact location of the error:
+
+     <pre class="example">          f ()
+          error: nargin != 1
+          error: called from:
+          error:   error at line -1, column -1
+          error:   h at line 1, column 27
+          error:   g at line 1, column 15
+          error:   f at line 1, column 15
+</pre>
+        <p>If the error message ends in a new line character, Octave will print the
+message but will not display any traceback messages as it returns
+control to the top level.  For example, modifying the error message
+in the previous example to end in a new line causes Octave to only print
+a single message:
+
+     <pre class="example">          function h () nargin == 1 || error ("nargin != 1\n"); end
+          f ()
+          error: nargin != 1
+</pre>
+        </blockquote></div>
+
+   <p>Since it is common to use errors when there is something wrong with
+the input to a function, Octave supports functions to simplify such code. 
+When the <code>print_usage</code> function is called, it reads the help text
+of the function calling <code>print_usage</code>, and presents a useful error. 
+If the help text is written in Texinfo it is possible to present an
+error message that only contains the function prototypes as described
+by the <code>@deftypefn</code> parts of the help text.  When the help text
+isn't written in Texinfo, the error message contains the entire help
+message.
+
+   <p>Consider the following function.
+<pre class="example">     ## -*- texinfo -*-
+     ## @deftypefn {Function File} f (@var{arg1})
+     ## Function help text goes here...
+     ## @end deftypefn
+     function f (arg1)
+       if (nargin == 0)
+         print_usage ();
+       endif
+     endfunction
+</pre>
+   <p class="noindent">When it is called with no input arguments it produces the following
+error.
+
+<pre class="example">     f ()
+     
+     -|  error: Invalid call to f.  Correct usage is:
+     -|
+     -|   -- Function File: f (ARG1)
+     -|
+     -|
+     -|  Additional help for built-in functions and operators is
+     -|  available in the on-line version of the manual.  Use the command
+     -|  `doc <topic>' to search the manual index.
+     -|
+     -|  Help and information about Octave is also available on the WWW
+     -|  at http://www.octave.org and via the help at octave.org
+     -|  mailing list.
+</pre>
+   <!-- ./help/print_usage.m -->
+   <p><a name="doc_002dprint_005fusage"></a>
+
+<div class="defun">
+— Function File:  <b>print_usage</b> ()<var><a name="index-print_005fusage-664"></a></var><br>
+— Function File:  <b>print_usage</b> (<var>name</var>)<var><a name="index-print_005fusage-665"></a></var><br>
+<blockquote><p>Print the usage message for a function.  When called with no input arguments
+the <code>print_usage</code> function displays the usage message of the currently
+executing function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhelp.html#doc_002dhelp">help</a>. 
+</p></blockquote></div>
+
+<!-- error.cc -->
+   <p><a name="doc_002dusage"></a>
+
+<div class="defun">
+— Built-in Function:  <b>usage</b> (<var>msg</var>)<var><a name="index-usage-666"></a></var><br>
+<blockquote><p>Print the message <var>msg</var>, prefixed by the string ‘<samp><span class="samp">usage: </span></samp>’, and
+set Octave's internal error state such that control will return to the
+top level without evaluating any more commands.  This is useful for
+aborting from functions.
+
+        <p>After <code>usage</code> is evaluated, Octave will print a traceback of all
+the function calls leading to the usage message.
+
+        <p>You should use this function for reporting problems errors that result
+from an improper call to a function, such as calling a function with an
+incorrect number of arguments, or with arguments of the wrong type.  For
+example, most functions distributed with Octave begin with code like
+this
+
+     <pre class="example">          if (nargin != 2)
+            usage ("foo (a, b)");
+          endif
+</pre>
+        <p class="noindent">to check for the proper number of arguments. 
+</p></blockquote></div>
+
+<!-- ./io/beep.m -->
+   <p><a name="doc_002dbeep"></a>
+
+<div class="defun">
+— Function File:  <b>beep</b> ()<var><a name="index-beep-667"></a></var><br>
+<blockquote><p>Produce a beep from the speaker (or visual bell). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dputs.html#doc_002dputs">puts</a>, <a href="doc_002dfputs.html#doc_002dfputs">fputs</a>, <a href="doc_002dprintf.html#doc_002dprintf">printf</a>, <a href="doc_002dfprintf.html#doc_002dfprintf">fprintf</a>. 
+</p></blockquote></div>
+
+<!-- error.cc -->
+   <p><a name="doc_002dbeep_005fon_005ferror"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>beep_on_error</b> ()<var><a name="index-beep_005fon_005ferror-668"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>beep_on_error</b> (<var>new_val</var>)<var><a name="index-beep_005fon_005ferror-669"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave will try
+to ring the terminal bell before printing an error message. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Random-Number-Generation.html b/doc/interpreter/HTML/Random-Number-Generation.html
new file mode 100644
index 0000000..c723736
--- /dev/null
+++ b/doc/interpreter/HTML/Random-Number-Generation.html
@@ -0,0 +1,413 @@
+<html lang="en">
+<head>
+<title>Random Number Generation - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="prev" href="Distributions.html#Distributions" title="Distributions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Random-Number-Generation"></a>
+Previous: <a rel="previous" accesskey="p" href="Distributions.html#Distributions">Distributions</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.7 Random Number Generation</h3>
+
+<p>Octave can generate random numbers from a large number of distributions. 
+The random number generators are based on the random number generators
+described in <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a>. 
+<!-- Should rand, randn, rande, randp, and randg be moved to here? -->
+
+   <p>The following table summarizes the available random number generators
+(in alphabetical order).
+
+   <p><table summary=""><tr align="left"><td valign="top" width="40%"><strong>Distribution</strong>             </td><td valign="top" width="30%"><strong>Function</strong>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Beta Distribution                 </td><td valign="top" width="30%"><code>betarnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Binomial Distribution             </td><td valign="top" width="30%"><code>binornd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Cauchy Distribution               </td><td valign="top" width="30%"><code>cauchy_rnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Chi-Square Distribution           </td><td valign="top" width="30%"><code>chi2rnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Univariate Discrete Distribution  </td><td valign="top" width="30%"><code>discrete_rnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Empirical Distribution            </td><td valign="top" width="30%"><code>empirical_rnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Exponential Distribution          </td><td valign="top" width="30%"><code>exprnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">F Distribution                    </td><td valign="top" width="30%"><code>frnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Gamma Distribution                </td><td valign="top" width="30%"><code>gamrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Geometric Distribution            </td><td valign="top" width="30%"><code>geornd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Hypergeometric Distribution       </td><td valign="top" width="30%"><code>hygernd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Laplace Distribution              </td><td valign="top" width="30%"><code>laplace_rnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Logistic Distribution             </td><td valign="top" width="30%"><code>logistic_rnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Log-Normal Distribution           </td><td valign="top" width="30%"><code>lognrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Pascal Distribution               </td><td valign="top" width="30%"><code>nbinrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Univariate Normal Distribution    </td><td valign="top" width="30%"><code>normrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Poisson Distribution              </td><td valign="top" width="30%"><code>poissrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">t (Student) Distribution          </td><td valign="top" width="30%"><code>trnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Univariate Discrete Distribution  </td><td valign="top" width="30%"><code>unidrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Uniform Distribution              </td><td valign="top" width="30%"><code>unifrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Weibull Distribution              </td><td valign="top" width="30%"><code>wblrnd</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Wiener Process                    </td><td valign="top" width="30%"><code>wienrnd</code>
+   <br></td></tr></table>
+
+<!-- ./statistics/distributions/betarnd.m -->
+   <p><a name="doc_002dbetarnd"></a>
+
+<div class="defun">
+— Function File:  <b>betarnd</b> (<var>a, b, r, c</var>)<var><a name="index-betarnd-1955"></a></var><br>
+— Function File:  <b>betarnd</b> (<var>a, b, sz</var>)<var><a name="index-betarnd-1956"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> or <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the Beta distribution with parameters <var>a</var> and
+<var>b</var>.  Both <var>a</var> and <var>b</var> must be scalar or of size <var>r</var>
+ by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>a</var> and <var>b</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/binornd.m -->
+   <p><a name="doc_002dbinornd"></a>
+
+<div class="defun">
+— Function File:  <b>binornd</b> (<var>n, p, r, c</var>)<var><a name="index-binornd-1957"></a></var><br>
+— Function File:  <b>binornd</b> (<var>n, p, sz</var>)<var><a name="index-binornd-1958"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var>  or a <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the binomial distribution with parameters <var>n</var>
+and <var>p</var>.  Both <var>n</var> and <var>p</var> must be scalar or of size
+<var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>n</var> and <var>p</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/cauchy_rnd.m -->
+   <p><a name="doc_002dcauchy_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>cauchy_rnd</b> (<var>lambda, sigma, r, c</var>)<var><a name="index-cauchy_005frnd-1959"></a></var><br>
+— Function File:  <b>cauchy_rnd</b> (<var>lambda, sigma, sz</var>)<var><a name="index-cauchy_005frnd-1960"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> or a <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the Cauchy distribution with parameters <var>lambda</var>
+and <var>sigma</var> which must both be scalar or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>lambda</var> and <var>sigma</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/chi2rnd.m -->
+   <p><a name="doc_002dchi2rnd"></a>
+
+<div class="defun">
+— Function File:  <b>chi2rnd</b> (<var>n, r, c</var>)<var><a name="index-chi2rnd-1961"></a></var><br>
+— Function File:  <b>chi2rnd</b> (<var>n, sz</var>)<var><a name="index-chi2rnd-1962"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var>  or a <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the chisquare distribution with <var>n</var> degrees
+of freedom.  <var>n</var> must be a scalar or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the size of <var>n</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/discrete_rnd.m -->
+   <p><a name="doc_002ddiscrete_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>discrete_rnd</b> (<var>n, v, p</var>)<var><a name="index-discrete_005frnd-1963"></a></var><br>
+— Function File:  <b>discrete_rnd</b> (<var>v, p, r, c</var>)<var><a name="index-discrete_005frnd-1964"></a></var><br>
+— Function File:  <b>discrete_rnd</b> (<var>v, p, sz</var>)<var><a name="index-discrete_005frnd-1965"></a></var><br>
+<blockquote><p>Generate a row vector containing a random sample of size <var>n</var> from
+the univariate distribution which assumes the values in <var>v</var> with
+probabilities <var>p</var>.  <var>n</var> must be a scalar.
+
+        <p>If <var>r</var> and <var>c</var> are given create a matrix with <var>r</var> rows and
+<var>c</var> columns.  Or if <var>sz</var> is a vector, create a matrix of size
+<var>sz</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/empirical_rnd.m -->
+   <p><a name="doc_002dempirical_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>empirical_rnd</b> (<var>n, data</var>)<var><a name="index-empirical_005frnd-1966"></a></var><br>
+— Function File:  <b>empirical_rnd</b> (<var>data, r, c</var>)<var><a name="index-empirical_005frnd-1967"></a></var><br>
+— Function File:  <b>empirical_rnd</b> (<var>data, sz</var>)<var><a name="index-empirical_005frnd-1968"></a></var><br>
+<blockquote><p>Generate a bootstrap sample of size <var>n</var> from the empirical
+distribution obtained from the univariate sample <var>data</var>.
+
+        <p>If <var>r</var> and <var>c</var> are given create a matrix with <var>r</var> rows and
+<var>c</var> columns.  Or if <var>sz</var> is a vector, create a matrix of size
+<var>sz</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/exprnd.m -->
+   <p><a name="doc_002dexprnd"></a>
+
+<div class="defun">
+— Function File:  <b>exprnd</b> (<var>lambda, r, c</var>)<var><a name="index-exprnd-1969"></a></var><br>
+— Function File:  <b>exprnd</b> (<var>lambda, sz</var>)<var><a name="index-exprnd-1970"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the
+exponential distribution with mean <var>lambda</var>, which must be a
+scalar or of size <var>r</var> by <var>c</var>.  Or if <var>sz</var> is a vector,
+create a matrix of size <var>sz</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the size of <var>lambda</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/frnd.m -->
+   <p><a name="doc_002dfrnd"></a>
+
+<div class="defun">
+— Function File:  <b>frnd</b> (<var>m, n, r, c</var>)<var><a name="index-frnd-1971"></a></var><br>
+— Function File:  <b>frnd</b> (<var>m, n, sz</var>)<var><a name="index-frnd-1972"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the F
+distribution with <var>m</var> and <var>n</var> degrees of freedom.  Both
+<var>m</var> and <var>n</var> must be scalar or of size <var>r</var> by <var>c</var>. 
+If <var>sz</var> is a vector the random samples are in a matrix of
+size <var>sz</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>m</var> and <var>n</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/gamrnd.m -->
+   <p><a name="doc_002dgamrnd"></a>
+
+<div class="defun">
+— Function File:  <b>gamrnd</b> (<var>a, b, r, c</var>)<var><a name="index-gamrnd-1973"></a></var><br>
+— Function File:  <b>gamrnd</b> (<var>a, b, sz</var>)<var><a name="index-gamrnd-1974"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> or a <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the Gamma distribution with parameters <var>a</var>
+and <var>b</var>.  Both <var>a</var> and <var>b</var> must be scalar or of size
+<var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>a</var> and <var>b</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>, <a href="doc_002dgammaln.html#doc_002dgammaln">gammaln</a>, <a href="doc_002dgammainc.html#doc_002dgammainc">gammainc</a>, <a href="doc_002dgampdf.html#doc_002dgampdf">gampdf</a>, <a href="doc_002dgamcdf.html#doc_002dgamcdf">gamcdf</a>, <a href="doc_002dgaminv.html#doc_002dgaminv">gaminv</a>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/geornd.m -->
+   <p><a name="doc_002dgeornd"></a>
+
+<div class="defun">
+— Function File:  <b>geornd</b> (<var>p, r, c</var>)<var><a name="index-geornd-1975"></a></var><br>
+— Function File:  <b>geornd</b> (<var>p, sz</var>)<var><a name="index-geornd-1976"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the
+geometric distribution with parameter <var>p</var>, which must be a scalar
+or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are given create a matrix with <var>r</var> rows and
+<var>c</var> columns.  Or if <var>sz</var> is a vector, create a matrix of size
+<var>sz</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/hygernd.m -->
+   <p><a name="doc_002dhygernd"></a>
+
+<div class="defun">
+— Function File:  <b>hygernd</b> (<var>t, m, n, r, c</var>)<var><a name="index-hygernd-1977"></a></var><br>
+— Function File:  <b>hygernd</b> (<var>t, m, n, sz</var>)<var><a name="index-hygernd-1978"></a></var><br>
+— Function File:  <b>hygernd</b> (<var>t, m, n</var>)<var><a name="index-hygernd-1979"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the
+hypergeometric distribution with parameters <var>t</var>, <var>m</var>,
+and <var>n</var>.
+
+        <p>The parameters <var>t</var>, <var>m</var>, and <var>n</var> must positive integers
+with <var>m</var> and <var>n</var> not greater than <var>t</var>.
+
+        <p>The parameter <var>sz</var> must be scalar or a vector of matrix
+dimensions.  If <var>sz</var> is scalar, then a <var>sz</var> by <var>sz</var>
+matrix of random samples is generated. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/laplace_rnd.m -->
+   <p><a name="doc_002dlaplace_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>laplace_rnd</b> (<var>r, c</var>)<var><a name="index-laplace_005frnd-1980"></a></var><br>
+— Function File:  <b>laplace_rnd</b> (<var>sz</var>)<var>;<a name="index-laplace_005frnd-1981"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random numbers from the
+Laplace distribution.  Or if <var>sz</var> is a vector, create a matrix of
+<var>sz</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/logistic_rnd.m -->
+   <p><a name="doc_002dlogistic_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>logistic_rnd</b> (<var>r, c</var>)<var><a name="index-logistic_005frnd-1982"></a></var><br>
+— Function File:  <b>logistic_rnd</b> (<var>sz</var>)<var><a name="index-logistic_005frnd-1983"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random numbers from the
+logistic distribution.  Or if <var>sz</var> is a vector, create a matrix of
+<var>sz</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/lognrnd.m -->
+   <p><a name="doc_002dlognrnd"></a>
+
+<div class="defun">
+— Function File:  <b>lognrnd</b> (<var>mu, sigma, r, c</var>)<var><a name="index-lognrnd-1984"></a></var><br>
+— Function File:  <b>lognrnd</b> (<var>mu, sigma, sz</var>)<var><a name="index-lognrnd-1985"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the
+lognormal distribution with parameters <var>mu</var> and <var>sigma</var>.  Both
+<var>mu</var> and <var>sigma</var> must be scalar or of size <var>r</var> by <var>c</var>. 
+Or if <var>sz</var> is a vector, create a matrix of size <var>sz</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>mu</var> and <var>sigma</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/nbinrnd.m -->
+   <p><a name="doc_002dnbinrnd"></a>
+
+<div class="defun">
+— Function File:  <b>nbinrnd</b> (<var>n, p, r, c</var>)<var><a name="index-nbinrnd-1986"></a></var><br>
+— Function File:  <b>nbinrnd</b> (<var>n, p, sz</var>)<var><a name="index-nbinrnd-1987"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the Pascal
+(negative binomial) distribution with parameters <var>n</var> and <var>p</var>. 
+Both <var>n</var> and <var>p</var> must be scalar or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>n</var> and <var>p</var>.  Or if <var>sz</var> is a vector,
+create a matrix of size <var>sz</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/normrnd.m -->
+   <p><a name="doc_002dnormrnd"></a>
+
+<div class="defun">
+— Function File:  <b>normrnd</b> (<var>m, s, r, c</var>)<var><a name="index-normrnd-1988"></a></var><br>
+— Function File:  <b>normrnd</b> (<var>m, s, sz</var>)<var><a name="index-normrnd-1989"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var>  or <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the normal distribution with parameters mean <var>m</var>
+and standard deviation <var>s</var>.  Both <var>m</var> and <var>s</var> must be scalar
+or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>m</var> and <var>s</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/poissrnd.m -->
+   <p><a name="doc_002dpoissrnd"></a>
+
+<div class="defun">
+— Function File:  <b>poissrnd</b> (<var>lambda, r, c</var>)<var><a name="index-poissrnd-1990"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the
+Poisson distribution with parameter <var>lambda</var>, which must be a
+scalar or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the size of <var>lambda</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/trnd.m -->
+   <p><a name="doc_002dtrnd"></a>
+
+<div class="defun">
+— Function File:  <b>trnd</b> (<var>n, r, c</var>)<var><a name="index-trnd-1991"></a></var><br>
+— Function File:  <b>trnd</b> (<var>n, sz</var>)<var><a name="index-trnd-1992"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the t
+(Student) distribution with <var>n</var> degrees of freedom.  <var>n</var> must
+be a scalar or of size <var>r</var> by <var>c</var>.  Or if <var>sz</var> is a
+vector create a matrix of size <var>sz</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the size of <var>n</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unidrnd.m -->
+   <p><a name="doc_002dunidrnd"></a>
+
+<div class="defun">
+— Function File:  <b>unidrnd</b> (<var>mx</var>)<var>;<a name="index-unidrnd-1993"></a></var><br>
+— Function File:  <b>unidrnd</b> (<var>mx, v</var>)<var>;<a name="index-unidrnd-1994"></a></var><br>
+— Function File:  <b>unidrnd</b> (<var>mx, m, n, <small class="dots">...</small></var>)<var>;<a name="index-unidrnd-1995"></a></var><br>
+<blockquote><p>Return random values from discrete uniform distribution, with maximum
+value(s) given by the integer <var>mx</var>, which may be a scalar or
+multidimensional array.
+
+        <p>If <var>mx</var> is a scalar, the size of the result is specified by
+the vector <var>v</var>, or by the optional arguments <var>m</var>, <var>n</var>,
+<small class="dots">...</small>.  Otherwise, the size of the result is the same as the size
+of <var>mx</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/unifrnd.m -->
+   <p><a name="doc_002dunifrnd"></a>
+
+<div class="defun">
+— Function File:  <b>unifrnd</b> (<var>a, b, r, c</var>)<var><a name="index-unifrnd-1996"></a></var><br>
+— Function File:  <b>unifrnd</b> (<var>a, b, sz</var>)<var><a name="index-unifrnd-1997"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> or a <code>size (</code><var>sz</var><code>)</code> matrix of
+random samples from the uniform distribution on [<var>a</var>, <var>b</var>]. 
+Both <var>a</var> and <var>b</var> must be scalar or of size <var>r</var> by <var>c</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>a</var> and <var>b</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/wblrnd.m -->
+   <p><a name="doc_002dwblrnd"></a>
+
+<div class="defun">
+— Function File:  <b>wblrnd</b> (<var>scale, shape, r, c</var>)<var><a name="index-wblrnd-1998"></a></var><br>
+— Function File:  <b>wblrnd</b> (<var>scale, shape, sz</var>)<var><a name="index-wblrnd-1999"></a></var><br>
+<blockquote><p>Return an <var>r</var> by <var>c</var> matrix of random samples from the
+Weibull distribution with parameters <var>scale</var> and <var>shape</var>
+which must be scalar or of size <var>r</var> by <var>c</var>.  Or if <var>sz</var>
+is a vector return a matrix of size <var>sz</var>.
+
+        <p>If <var>r</var> and <var>c</var> are omitted, the size of the result matrix is
+the common size of <var>alpha</var> and <var>sigma</var>. 
+</p></blockquote></div>
+
+<!-- ./statistics/distributions/wienrnd.m -->
+   <p><a name="doc_002dwienrnd"></a>
+
+<div class="defun">
+— Function File:  <b>wienrnd</b> (<var>t, d, n</var>)<var><a name="index-wienrnd-2000"></a></var><br>
+<blockquote><p>Return a simulated realization of the <var>d</var>-dimensional Wiener Process
+on the interval [0, <var>t</var>].  If <var>d</var> is omitted, <var>d</var> = 1 is
+used.  The first column of the return matrix contains time, the
+remaining columns contain the Wiener process.
+
+        <p>The optional parameter <var>n</var> gives the number of summands used for
+simulating the process over an interval of length 1.  If <var>n</var> is
+omitted, <var>n</var> = 1000 is used. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Ranges.html b/doc/interpreter/HTML/Ranges.html
new file mode 100644
index 0000000..2061376
--- /dev/null
+++ b/doc/interpreter/HTML/Ranges.html
@@ -0,0 +1,91 @@
+<html lang="en">
+<head>
+<title>Ranges - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Matrices.html#Matrices" title="Matrices">
+<link rel="next" href="Single-Precision-Data-Types.html#Single-Precision-Data-Types" title="Single Precision Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Ranges"></a>
+Next: <a rel="next" accesskey="n" href="Single-Precision-Data-Types.html#Single-Precision-Data-Types">Single Precision Data Types</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrices.html#Matrices">Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.2 Ranges</h3>
+
+<p><a name="index-range-expressions-231"></a><a name="index-expression_002c-range-232"></a>
+<a name="index-colon-233"></a>
+A <dfn>range</dfn> is a convenient way to write a row vector with evenly
+spaced elements.  A range expression is defined by the value of the first
+element in the range, an optional value for the increment between
+elements, and a maximum value which the elements of the range will not
+exceed.  The base, increment, and limit are separated by colons (the
+‘<samp><span class="samp">:</span></samp>’ character) and may contain any arithmetic expressions and
+function calls.  If the increment is omitted, it is assumed to be 1. 
+For example, the range
+
+<pre class="example">     1 : 5
+</pre>
+   <p class="noindent">defines the set of values ‘<samp><span class="samp">[ 1, 2, 3, 4, 5 ]</span></samp>’, and the range
+
+<pre class="example">     1 : 3 : 5
+</pre>
+   <p class="noindent">defines the set of values ‘<samp><span class="samp">[ 1, 4 ]</span></samp>’.
+
+   <p>Although a range constant specifies a row vector, Octave does <em>not</em>
+convert range constants to vectors unless it is necessary to do so. 
+This allows you to write a constant like ‘<samp><span class="samp">1 : 10000</span></samp>’ without using
+80,000 bytes of storage on a typical 32-bit workstation.
+
+   <p>Note that the upper (or lower, if the increment is negative) bound on
+the range is not always included in the set of values, and that ranges
+defined by floating point values can produce surprising results because
+Octave uses floating point arithmetic to compute the values in the
+range.  If it is important to include the endpoints of a range and the
+number of elements is known, you should use the <code>linspace</code> function
+instead (see <a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a>).
+
+   <p>When adding a scalar to a range, subtracting a scalar from it (or subtracting a
+range from a scalar) and multiplying by scalar, Octave will attempt to avoid
+unpacking the range and keep the result as a range, too, if it can determine
+that it is safe to do so.  For instance, doing
+
+<pre class="example">     a = 2*(1:1e7) - 1;
+</pre>
+   <p>will produce the same result as ‘<samp><span class="samp">1:2:2e7-1</span></samp>’, but without ever forming a
+vector with ten million elements.
+
+   <p>Using zero as an increment in the colon notation, as ‘<samp><span class="samp">1:0:1</span></samp>’ is not
+allowed, because a division by zero would occur in determining the number of
+range elements.  However, ranges with zero increment (i.e., all elements equal)
+are useful, especially in indexing, and Octave allows them to be constructed
+using the built-in function <dfn>ones</dfn>.  Note that because a range must be a row
+vector, ‘<samp><span class="samp">ones (1, 10)</span></samp>’ produces a range, while ‘<samp><span class="samp">ones (10, 1)</span></samp>’ does not.
+
+   <p>When Octave parses a range expression, it examines the elements of the
+expression to determine whether they are all constants.  If they are, it
+replaces the range expression with a single range constant.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Rational-Approximations.html b/doc/interpreter/HTML/Rational-Approximations.html
new file mode 100644
index 0000000..3571abf
--- /dev/null
+++ b/doc/interpreter/HTML/Rational-Approximations.html
@@ -0,0 +1,79 @@
+<html lang="en">
+<head>
+<title>Rational Approximations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Input-and-Output.html#Basic-Input-and-Output" title="Basic Input and Output">
+<link rel="prev" href="Simple-File-I_002fO.html#Simple-File-I_002fO" title="Simple File I/O">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Rational-Approximations"></a>
+Previous: <a rel="previous" accesskey="p" href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.1.4 Rational Approximations</h4>
+
+<!-- ./general/rat.m -->
+<p><a name="doc_002drat"></a>
+
+<div class="defun">
+— Function File: <var>s</var> = <b>rat</b> (<var>x, tol</var>)<var><a name="index-rat-767"></a></var><br>
+— Function File: [<var>n</var>, <var>d</var>] = <b>rat</b> (<var>x, tol</var>)<var><a name="index-rat-768"></a></var><br>
+<blockquote>
+        <p>Find a rational approximation to <var>x</var> within the tolerance defined
+by <var>tol</var> using a continued fraction expansion.  For example,
+
+     <pre class="example">          rat(pi) = 3 + 1/(7 + 1/16) = 355/113
+          rat(e) = 3 + 1/(-4 + 1/(2 + 1/(5 + 1/(-2 + 1/(-7)))))
+                 = 1457/536
+</pre>
+        <p>Called with two arguments returns the numerator and denominator separately
+as two matrices. 
+</p></blockquote></div>
+   <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+<p class="noindent"><strong>See also:</strong> <a href="doc_002drats.html#doc_002drats">rats</a>.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002drats"></a>
+
+<div class="defun">
+— Built-in Function:  <b>rats</b> (<var>x, len</var>)<var><a name="index-rats-769"></a></var><br>
+<blockquote><p>Convert <var>x</var> into a rational approximation represented as a string. 
+You can convert the string back into a matrix as follows:
+
+     <pre class="example">             r = rats(hilb(4));
+             x = str2num(r)
+</pre>
+        <p>The optional second argument defines the maximum length of the string
+representing the elements of <var>x</var>.  By default <var>len</var> is 9. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dformat.html#doc_002dformat">format</a>, <a href="doc_002drat.html#doc_002drat">rat</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Real-Life-Example.html b/doc/interpreter/HTML/Real-Life-Example.html
new file mode 100644
index 0000000..5dbc86a
--- /dev/null
+++ b/doc/interpreter/HTML/Real-Life-Example.html
@@ -0,0 +1,219 @@
+<html lang="en">
+<head>
+<title>Real Life Example - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices.html#Sparse-Matrices" title="Sparse Matrices">
+<link rel="prev" href="Iterative-Techniques.html#Iterative-Techniques" title="Iterative Techniques">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Real-Life-Example"></a>
+Previous: <a rel="previous" accesskey="p" href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">21.4 Real Life Example of the use of Sparse Matrices</h3>
+
+<p>A common application for sparse matrices is in the solution of Finite
+Element Models.  Finite element models allow numerical solution of
+partial differential equations that do not have closed form solutions,
+typically because of the complex shape of the domain.
+
+   <p>In order to motivate this application, we consider the boundary value
+Laplace equation.  This system can model scalar potential fields, such
+as heat or electrical potential.  Given a medium
+Omega
+with boundary
+dOmega
+. At all points on the
+dOmega
+the boundary conditions are known, and we wish to calculate the potential in
+Omega
+. Boundary conditions may specify the potential (Dirichlet
+boundary condition), its normal derivative across the boundary
+(Neumann boundary condition), or a weighted sum of the potential and
+its derivative (Cauchy boundary condition).
+
+   <p>In a thermal model, we want to calculate the temperature in
+Omega
+and know the boundary temperature (Dirichlet condition)
+or heat flux (from which we can calculate the Neumann condition
+by dividing by the thermal conductivity at the boundary).  Similarly,
+in an electrical model, we want to calculate the voltage in
+Omega
+and know the boundary voltage (Dirichlet) or current
+(Neumann condition after diving by the electrical conductivity). 
+In an electrical model, it is common for much of the boundary
+to be electrically isolated; this is a Neumann boundary condition
+with the current equal to zero.
+
+   <p>The simplest finite element models will divide
+Omega
+into simplexes (triangles in 2D, pyramids in 3D). 
+We take as an 3D example a cylindrical liquid filled tank with a small
+non-conductive ball from the EIDORS project<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>.  This is model is designed to reflect
+an application of electrical impedance tomography, where current patterns
+are applied to such a tank in order to image the internal conductivity
+distribution.  In order to describe the FEM geometry, we have a matrix of
+vertices <code>nodes</code> and simplices <code>elems</code>.
+
+   <p>The following example creates a simple rectangular 2D electrically
+conductive medium with 10 V and 20 V imposed on opposite sides
+(Dirichlet boundary conditions).  All other edges are electrically
+isolated.
+
+<pre class="example">        node_y= [1;1.2;1.5;1.8;2]*ones(1,11);
+        node_x= ones(5,1)*[1,1.05,1.1,1.2, ...
+                  1.3,1.5,1.7,1.8,1.9,1.95,2];
+        nodes= [node_x(:), node_y(:)];
+     
+        [h,w]= size(node_x);
+        elems= [];
+        for idx= 1:w-1
+          widx= (idx-1)*h;
+          elems= [elems; ...
+            widx+[(1:h-1);(2:h);h+(1:h-1)]'; ...
+            widx+[(2:h);h+(2:h);h+(1:h-1)]' ];
+        endfor
+     
+        E= size(elems,1); # No. of simplices
+        N= size(nodes,1); # No. of vertices
+        D= size(elems,2); # dimensions+1
+</pre>
+   <p>This creates a N-by-2 matrix <code>nodes</code> and a E-by-3 matrix
+<code>elems</code> with values, which define finite element triangles:
+
+<pre class="example">       nodes(1:7,:)'
+         1.00 1.00 1.00 1.00 1.00 1.05 1.05 ...
+         1.00 1.20 1.50 1.80 2.00 1.00 1.20 ...
+     
+       elems(1:7,:)'
+         1    2    3    4    2    3    4 ...
+         2    3    4    5    7    8    9 ...
+         6    7    8    9    6    7    8 ...
+</pre>
+   <p>Using a first order FEM, we approximate the electrical conductivity
+distribution in
+Omega
+as constant on each simplex (represented by the vector <code>conductivity</code>). 
+Based on the finite element geometry, we first calculate a system (or
+stiffness) matrix for each simplex (represented as 3-by-3 elements on the
+diagonal of the element-wise system matrix <code>SE</code>.  Based on <code>SE</code>
+and a N-by-DE connectivity matrix <code>C</code>, representing the connections
+between simplices and vertices, the global connectivity matrix <code>S</code> is
+calculated.
+
+<pre class="example">       # Element conductivity
+       conductivity= [1*ones(1,16), ...
+              2*ones(1,48), 1*ones(1,16)];
+     
+       # Connectivity matrix
+       C = sparse ((1:D*E), reshape (elems', ...
+              D*E, 1), 1, D*E, N);
+     
+       # Calculate system matrix
+       Siidx = floor ([0:D*E-1]'/D) * D * ...
+              ones(1,D) + ones(D*E,1)*(1:D) ;
+       Sjidx = [1:D*E]'*ones(1,D);
+       Sdata = zeros(D*E,D);
+       dfact = factorial(D-1);
+       for j=1:E
+          a = inv([ones(D,1), ...
+              nodes(elems(j,:), :)]);
+          const = conductivity(j) * 2 / ...
+              dfact / abs(det(a));
+          Sdata(D*(j-1)+(1:D),:) = const * ...
+              a(2:D,:)' * a(2:D,:);
+       endfor
+       # Element-wise system matrix
+       SE= sparse(Siidx,Sjidx,Sdata);
+       # Global system matrix
+       S= C'* SE *C;
+</pre>
+   <p>The system matrix acts like the conductivity
+<code>S</code>
+in Ohm's law
+<code>S * V = I</code>. 
+Based on the Dirichlet and Neumann boundary conditions, we are able to
+solve for the voltages at each vertex <code>V</code>.
+
+<pre class="example">       # Dirichlet boundary conditions
+       D_nodes=[1:5, 51:55];
+       D_value=[10*ones(1,5), 20*ones(1,5)];
+     
+       V= zeros(N,1);
+       V(D_nodes) = D_value;
+       idx = 1:N; # vertices without Dirichlet
+                  # boundary condns
+       idx(D_nodes) = [];
+     
+       # Neumann boundary conditions.  Note that
+       # N_value must be normalized by the
+       # boundary length and element conductivity
+       N_nodes=[];
+       N_value=[];
+     
+       Q = zeros(N,1);
+       Q(N_nodes) = N_value;
+     
+       V(idx) = S(idx,idx) \ ( Q(idx) - ...
+                 S(idx,D_nodes) * V(D_nodes));
+</pre>
+   <p>Finally, in order to display the solution, we show each solved voltage
+value in the z-axis for each simplex vertex. 
+See <a href="fig_003afemmodel.html#fig_003afemmodel">fig:femmodel</a>.
+
+<pre class="example">       elemx = elems(:,[1,2,3,1])';
+       xelems = reshape (nodes(elemx, 1), 4, E);
+       yelems = reshape (nodes(elemx, 2), 4, E);
+       velems = reshape (V(elemx), 4, E);
+       plot3 (xelems,yelems,velems,'k');
+       print ('grid.eps');
+</pre>
+   <div class="float">
+<a name="fig_003afemmodel"></a><div align="center"><img src="grid.png" alt="grid.png"></div>
+   <p><strong class="float-caption">Figure 21.6: Example finite element model the showing triangular elements. 
+The height of each vertex corresponds to the solution value.</strong></p></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2002, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> EIDORS - Electrical
+Impedance Tomography and Diffuse optical Tomography Reconstruction Software
+<a href="http://eidors3d.sourceforge.net">http://eidors3d.sourceforge.net</a></p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Rearranging-Matrices.html b/doc/interpreter/HTML/Rearranging-Matrices.html
new file mode 100644
index 0000000..8b54f11
--- /dev/null
+++ b/doc/interpreter/HTML/Rearranging-Matrices.html
@@ -0,0 +1,631 @@
+<html lang="en">
+<head>
+<title>Rearranging Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link rel="prev" href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions" title="Finding Elements and Checking Conditions">
+<link rel="next" href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array" title="Applying a Function to an Array">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Rearranging-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">Applying a Function to an Array</a>,
+Previous: <a rel="previous" accesskey="p" href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>
+<hr>
+</div>
+
+<h3 class="section">16.2 Rearranging Matrices</h3>
+
+<!-- ./general/fliplr.m -->
+<p><a name="doc_002dfliplr"></a>
+
+<div class="defun">
+— Function File:  <b>fliplr</b> (<var>x</var>)<var><a name="index-fliplr-1272"></a></var><br>
+<blockquote><p>Return a copy of <var>x</var> with the order of the columns reversed.  For
+example,
+
+     <pre class="example">          fliplr ([1, 2; 3, 4])
+                 2  1
+                   4  3
+</pre>
+        <p>Note that <code>fliplr</code> only work with 2-D arrays.  To flip N-d arrays
+use <code>flipdim</code> instead. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dflipud.html#doc_002dflipud">flipud</a>, <a href="doc_002dflipdim.html#doc_002dflipdim">flipdim</a>, <a href="doc_002drot90.html#doc_002drot90">rot90</a>, <a href="doc_002drotdim.html#doc_002drotdim">rotdim</a>. 
+</p></blockquote></div>
+
+<!-- ./general/flipud.m -->
+   <p><a name="doc_002dflipud"></a>
+
+<div class="defun">
+— Function File:  <b>flipud</b> (<var>x</var>)<var><a name="index-flipud-1273"></a></var><br>
+<blockquote><p>Return a copy of <var>x</var> with the order of the rows reversed.  For
+example,
+
+     <pre class="example">          flipud ([1, 2; 3, 4])
+                 3  4
+                   1  2
+</pre>
+        <p>Due to the difficulty of defining which axis about which to flip the
+matrix <code>flipud</code> only work with 2-d arrays.  To flip N-d arrays
+use <code>flipdim</code> instead. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfliplr.html#doc_002dfliplr">fliplr</a>, <a href="doc_002dflipdim.html#doc_002dflipdim">flipdim</a>, <a href="doc_002drot90.html#doc_002drot90">rot90</a>, <a href="doc_002drotdim.html#doc_002drotdim">rotdim</a>. 
+</p></blockquote></div>
+
+<!-- ./general/flipdim.m -->
+   <p><a name="doc_002dflipdim"></a>
+
+<div class="defun">
+— Function File:  <b>flipdim</b> (<var>x, dim</var>)<var><a name="index-flipdim-1274"></a></var><br>
+<blockquote><p>Return a copy of <var>x</var> flipped about the dimension <var>dim</var>. 
+For example
+
+     <pre class="example">          flipdim ([1, 2; 3, 4], 2)
+                 2  1
+                   4  3
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfliplr.html#doc_002dfliplr">fliplr</a>, <a href="doc_002dflipud.html#doc_002dflipud">flipud</a>, <a href="doc_002drot90.html#doc_002drot90">rot90</a>, <a href="doc_002drotdim.html#doc_002drotdim">rotdim</a>. 
+</p></blockquote></div>
+
+<!-- ./general/rot90.m -->
+   <p><a name="doc_002drot90"></a>
+
+<div class="defun">
+— Function File:  <b>rot90</b> (<var>x, n</var>)<var><a name="index-rot90-1275"></a></var><br>
+<blockquote><p>Return a copy of <var>x</var> with the elements rotated counterclockwise in
+90-degree increments.  The second argument is optional, and specifies
+how many 90-degree rotations are to be applied (the default value is 1). 
+Negative values of <var>n</var> rotate the matrix in a clockwise direction. 
+For example,
+
+     <pre class="example">          rot90 ([1, 2; 3, 4], -1)
+                 3  1
+                   4  2
+</pre>
+        <p class="noindent">rotates the given matrix clockwise by 90 degrees.  The following are all
+equivalent statements:
+
+     <pre class="example">          rot90 ([1, 2; 3, 4], -1)
+          rot90 ([1, 2; 3, 4], 3)
+          rot90 ([1, 2; 3, 4], 7)
+</pre>
+        <p>Due to the difficulty of defining an axis about which to rotate the
+matrix <code>rot90</code> only work with 2-D arrays.  To rotate N-d arrays
+use <code>rotdim</code> instead. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drotdim.html#doc_002drotdim">rotdim</a>, <a href="doc_002dflipud.html#doc_002dflipud">flipud</a>, <a href="doc_002dfliplr.html#doc_002dfliplr">fliplr</a>, <a href="doc_002dflipdim.html#doc_002dflipdim">flipdim</a>. 
+</p></blockquote></div>
+
+<!-- ./general/rotdim.m -->
+   <p><a name="doc_002drotdim"></a>
+
+<div class="defun">
+— Function File:  <b>rotdim</b> (<var>x, n, plane</var>)<var><a name="index-rotdim-1276"></a></var><br>
+<blockquote><p>Return a copy of <var>x</var> with the elements rotated counterclockwise in
+90-degree increments.  The second argument is optional, and specifies
+how many 90-degree rotations are to be applied (the default value is 1). 
+The third argument is also optional and defines the plane of the
+rotation.  As such <var>plane</var> is a two element vector containing two
+different valid dimensions of the matrix.  If <var>plane</var> is not given
+Then the first two non-singleton dimensions are used.
+
+        <p>Negative values of <var>n</var> rotate the matrix in a clockwise direction. 
+For example,
+
+     <pre class="example">          rotdim ([1, 2; 3, 4], -1, [1, 2])
+                 3  1
+                   4  2
+</pre>
+        <p class="noindent">rotates the given matrix clockwise by 90 degrees.  The following are all
+equivalent statements:
+
+     <pre class="example">          rotdim ([1, 2; 3, 4], -1, [1, 2])
+          rotdim ([1, 2; 3, 4], 3, [1, 2])
+          rotdim ([1, 2; 3, 4], 7, [1, 2])
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drot90.html#doc_002drot90">rot90</a>, <a href="doc_002dflipud.html#doc_002dflipud">flipud</a>, <a href="doc_002dfliplr.html#doc_002dfliplr">fliplr</a>, <a href="doc_002dflipdim.html#doc_002dflipdim">flipdim</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dcat"></a>
+
+<div class="defun">
+— Built-in Function:  <b>cat</b> (<var>dim, array1, array2, <small class="dots">...</small>, arrayN</var>)<var><a name="index-cat-1277"></a></var><br>
+<blockquote><p>Return the concatenation of N-d array objects, <var>array1</var>,
+<var>array2</var>, <small class="dots">...</small>, <var>arrayN</var> along dimension <var>dim</var>.
+
+     <pre class="example">          A = ones (2, 2);
+          B = zeros (2, 2);
+          cat (2, A, B)
+           ans =
+          
+               1 1 0 0
+               1 1 0 0
+</pre>
+        <p>Alternatively, we can concatenate <var>A</var> and <var>B</var> along the
+second dimension the following way:
+
+     <pre class="example">          [A, B].
+</pre>
+        <p><var>dim</var> can be larger than the dimensions of the N-d array objects
+and the result will thus have <var>dim</var> dimensions as the
+following example shows:
+     <pre class="example">          cat (4, ones(2, 2), zeros (2, 2))
+           ans =
+          
+             ans(:,:,1,1) =
+          
+               1 1
+               1 1
+          
+             ans(:,:,1,2) =
+               0 0
+               0 0
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhorzcat.html#doc_002dhorzcat">horzcat</a>, <a href="doc_002dvertcat.html#doc_002dvertcat">vertcat</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dhorzcat"></a>
+
+<div class="defun">
+— Built-in Function:  <b>horzcat</b> (<var>array1, array2, <small class="dots">...</small>, arrayN</var>)<var><a name="index-horzcat-1278"></a></var><br>
+<blockquote><p>Return the horizontal concatenation of N-d array objects, <var>array1</var>,
+<var>array2</var>, <small class="dots">...</small>, <var>arrayN</var> along dimension 2. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcat.html#doc_002dcat">cat</a>, <a href="doc_002dvertcat.html#doc_002dvertcat">vertcat</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dvertcat"></a>
+
+<div class="defun">
+— Built-in Function:  <b>vertcat</b> (<var>array1, array2, <small class="dots">...</small>, arrayN</var>)<var><a name="index-vertcat-1279"></a></var><br>
+<blockquote><p>Return the vertical concatenation of N-d array objects, <var>array1</var>,
+<var>array2</var>, <small class="dots">...</small>, <var>arrayN</var> along dimension 1. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcat.html#doc_002dcat">cat</a>, <a href="doc_002dhorzcat.html#doc_002dhorzcat">horzcat</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dpermute"></a>
+
+<div class="defun">
+— Built-in Function:  <b>permute</b> (<var>a, perm</var>)<var><a name="index-permute-1280"></a></var><br>
+<blockquote><p>Return the generalized transpose for an N-d array object <var>a</var>. 
+The permutation vector <var>perm</var> must contain the elements
+<code>1:ndims(a)</code> (in any order, but each element must appear just once). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dipermute.html#doc_002dipermute">ipermute</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dipermute"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ipermute</b> (<var>a, iperm</var>)<var><a name="index-ipermute-1281"></a></var><br>
+<blockquote><p>The inverse of the <code>permute</code> function.  The expression
+
+     <pre class="example">          ipermute (permute (a, perm), perm)
+</pre>
+        <p>returns the original array <var>a</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpermute.html#doc_002dpermute">permute</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dreshape"></a>
+
+<div class="defun">
+— Built-in Function:  <b>reshape</b> (<var>a, m, n, <small class="dots">...</small></var>)<var><a name="index-reshape-1282"></a></var><br>
+— Built-in Function:  <b>reshape</b> (<var>a, size</var>)<var><a name="index-reshape-1283"></a></var><br>
+<blockquote><p>Return a matrix with the given dimensions whose elements are taken
+from the matrix <var>a</var>.  The elements of the matrix are accessed in
+column-major order (like Fortran arrays are stored).
+
+        <p>For example,
+
+     <pre class="example">          reshape ([1, 2, 3, 4], 2, 2)
+                 1  3
+                   2  4
+</pre>
+        <p class="noindent">Note that the total number of elements in the original
+matrix must match the total number of elements in the new matrix.
+
+        <p>A single dimension of the return matrix can be unknown and is flagged
+by an empty argument. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dresize"></a>
+
+<div class="defun">
+— Built-in Function:  <b>resize</b> (<var>x, m</var>)<var><a name="index-resize-1284"></a></var><br>
+— Built-in Function:  <b>resize</b> (<var>x, m, n</var>)<var><a name="index-resize-1285"></a></var><br>
+— Built-in Function:  <b>resize</b> (<var>x, m, n, <small class="dots">...</small></var>)<var><a name="index-resize-1286"></a></var><br>
+<blockquote><p>Resize <var>x</var> cutting off elements as necessary.
+
+        <p>In the result, element with certain indices is equal to the corresponding
+element of <var>x</var> if the indices are within the bounds of <var>x</var>;
+otherwise, the element is set to zero.
+
+        <p>In other words, the statement
+
+     <pre class="example">            y = resize (x, dv);
+</pre>
+        <p class="noindent">is equivalent to the following code:
+
+     <pre class="example">            y = zeros (dv, class (x));
+            sz = min (dv, size (x));
+            for i = 1:length (sz), idx{i} = 1:sz(i); endfor
+            y(idx{:}) = x(idx{:});
+</pre>
+        <p class="noindent">but is performed more efficiently.
+
+        <p>If only <var>m</var> is supplied and it is a scalar, the dimension of the
+result is <var>m</var>-by-<var>m</var>.  If <var>m</var> is a vector, then the
+dimensions of the result are given by the elements of <var>m</var>. 
+If both <var>m</var> and <var>n</var> are scalars, then the dimensions of
+the result are <var>m</var>-by-<var>n</var>.
+
+        <p>An object can be resized to more dimensions than it has;
+in such case the missing dimensions are assumed to be 1. 
+Resizing an object to fewer dimensions is not possible. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dreshape.html#doc_002dreshape">reshape</a>, <a href="doc_002dpostpad.html#doc_002dpostpad">postpad</a>. 
+</p></blockquote></div>
+
+<!-- ./general/circshift.m -->
+   <p><a name="doc_002dcircshift"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>circshift</b> (<var>x, n</var>)<var><a name="index-circshift-1287"></a></var><br>
+<blockquote><p>Circularly shifts the values of the array <var>x</var>.  <var>n</var> must be
+a vector of integers no longer than the number of dimensions in
+<var>x</var>.  The values of <var>n</var> can be either positive or negative,
+which determines the direction in which the values or <var>x</var> are
+shifted.  If an element of <var>n</var> is zero, then the corresponding
+dimension of <var>x</var> will not be shifted.  For example
+
+     <pre class="example">          x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+          circshift (x, 1)
+            7, 8, 9
+              1, 2, 3
+              4, 5, 6
+          circshift (x, -2)
+            7, 8, 9
+              1, 2, 3
+              4, 5, 6
+          circshift (x, [0,1])
+            3, 1, 2
+              6, 4, 5
+              9, 7, 8
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> permute, ipermute, shiftdim. 
+</p></blockquote></div>
+
+<!-- ./general/shiftdim.m -->
+   <p><a name="doc_002dshiftdim"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>shiftdim</b> (<var>x, n</var>)<var><a name="index-shiftdim-1288"></a></var><br>
+— Function File: [<var>y</var>, <var>ns</var>] = <b>shiftdim</b> (<var>x</var>)<var><a name="index-shiftdim-1289"></a></var><br>
+<blockquote><p>Shifts the dimension of <var>x</var> by <var>n</var>, where <var>n</var> must be
+an integer scalar.  When <var>n</var> is positive, the dimensions of
+<var>x</var> are shifted to the left, with the leading dimensions
+circulated to the end.  If <var>n</var> is negative, then the dimensions
+of <var>x</var> are shifted to the right, with <var>n</var> leading singleton
+dimensions added.
+
+        <p>Called with a single argument, <code>shiftdim</code>, removes the leading
+singleton dimensions, returning the number of dimensions removed
+in the second output argument <var>ns</var>.
+
+        <p>For example
+
+     <pre class="example">          x = ones (1, 2, 3);
+          size (shiftdim (x, -1))
+                [1, 1, 2, 3]
+          size (shiftdim (x, 1))
+                [2, 3]
+          [b, ns] = shiftdim (x);
+                b =  [1, 1, 1; 1, 1, 1]
+                ns = 1
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> reshape, permute, ipermute, circshift, squeeze. 
+</p></blockquote></div>
+
+<!-- ./general/shift.m -->
+   <p><a name="doc_002dshift"></a>
+
+<div class="defun">
+— Function File:  <b>shift</b> (<var>x, b</var>)<var><a name="index-shift-1290"></a></var><br>
+— Function File:  <b>shift</b> (<var>x, b, dim</var>)<var><a name="index-shift-1291"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, perform a circular shift of length <var>b</var> of
+the elements of <var>x</var>.
+
+        <p>If <var>x</var> is a matrix, do the same for each column of <var>x</var>. 
+If the optional <var>dim</var> argument is given, operate along this
+dimension
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dsort"></a>
+
+<div class="defun">
+— Loadable Function: [<var>s</var>, <var>i</var>] = <b>sort</b> (<var>x</var>)<var><a name="index-sort-1292"></a></var><br>
+— Loadable Function: [<var>s</var>, <var>i</var>] = <b>sort</b> (<var>x, dim</var>)<var><a name="index-sort-1293"></a></var><br>
+— Loadable Function: [<var>s</var>, <var>i</var>] = <b>sort</b> (<var>x, mode</var>)<var><a name="index-sort-1294"></a></var><br>
+— Loadable Function: [<var>s</var>, <var>i</var>] = <b>sort</b> (<var>x, dim, mode</var>)<var><a name="index-sort-1295"></a></var><br>
+<blockquote><p>Return a copy of <var>x</var> with the elements arranged in increasing
+order.  For matrices, <code>sort</code> orders the elements in each column.
+
+        <p>For example,
+
+     <pre class="example">          sort ([1, 2; 2, 3; 3, 1])
+                 1  1
+                   2  2
+                   3  3
+</pre>
+        <p>The <code>sort</code> function may also be used to produce a matrix
+containing the original row indices of the elements in the sorted
+matrix.  For example,
+
+     <pre class="example">          [s, i] = sort ([1, 2; 2, 3; 3, 1])
+                s = 1  1
+                      2  2
+                      3  3
+                i = 1  3
+                      2  1
+                      3  2
+</pre>
+        <p>If the optional argument <var>dim</var> is given, then the matrix is sorted
+along the dimension defined by <var>dim</var>.  The optional argument <code>mode</code>
+defines the order in which the values will be sorted.  Valid values of
+<code>mode</code> are `ascend' or `descend'.
+
+        <p>For equal elements, the indices are such that the equal elements are listed
+in the order that appeared in the original list.
+
+        <p>The <code>sort</code> function may also be used to sort strings and cell arrays
+of strings, in which case the dictionary order of the strings is used.
+
+        <p>The algorithm used in <code>sort</code> is optimized for the sorting of partially
+ordered lists. 
+</p></blockquote></div>
+
+<!-- ./general/sortrows.m -->
+   <p><a name="doc_002dsortrows"></a>
+
+<div class="defun">
+— Function File:  <b>sortrows</b> (<var>a, c</var>)<var><a name="index-sortrows-1296"></a></var><br>
+<blockquote><p>Sort the rows of the matrix <var>a</var> according to the order of the
+columns specified in <var>c</var>.  If <var>c</var> is omitted, a
+lexicographical sort is used.  By default ascending order is used
+however if elements of <var>c</var> are negative then the corresponding
+column is sorted in descending order. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dissorted"></a>
+
+<div class="defun">
+— Built-in Function:  <b>issorted</b> (<var>a, rows</var>)<var><a name="index-issorted-1297"></a></var><br>
+<blockquote><p>Returns true if the array is sorted, ascending or descending. 
+NaNs are treated as by <code>sort</code>.  If <var>rows</var> is supplied and
+has the value "rows", checks whether the array is sorted by rows
+as if output by <code>sortrows</code> (with no options).
+
+        <p>This function does not yet support sparse matrices. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsortrows.html#doc_002dsortrows">sortrows</a>, <a href="doc_002dsort.html#doc_002dsort">sort</a>. 
+</p></blockquote></div>
+
+   <p>Since the <code>sort</code> function does not allow sort keys to be specified,
+it can't be used to order the rows of a matrix according to the values
+of the elements in various columns<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>
+in a single call.  Using the second output, however, it is possible to
+sort all rows based on the values in a given column.  Here's an example
+that sorts the rows of a matrix based on the values in the second
+column.
+
+<pre class="example">     a = [1, 2; 2, 3; 3, 1];
+     [s, i] = sort (a (:, 2));
+     a (i, :)
+            3  1
+              1  2
+              2  3
+</pre>
+   <p><a name="doc_002dtriu"></a><!-- ./general/tril.m -->
+<a name="doc_002dtril"></a>
+
+<div class="defun">
+— Function File:  <b>tril</b> (<var>a, k</var>)<var><a name="index-tril-1298"></a></var><br>
+— Function File:  <b>triu</b> (<var>a, k</var>)<var><a name="index-triu-1299"></a></var><br>
+<blockquote><p>Return a new matrix formed by extracting the lower (<code>tril</code>)
+or upper (<code>triu</code>) triangular part of the matrix <var>a</var>, and
+setting all other elements to zero.  The second argument is optional,
+and specifies how many diagonals above or below the main diagonal should
+also be set to zero.
+
+        <p>The default value of <var>k</var> is zero, so that <code>triu</code> and
+<code>tril</code> normally include the main diagonal as part of the result
+matrix.
+
+        <p>If the value of <var>k</var> is negative, additional elements above (for
+<code>tril</code>) or below (for <code>triu</code>) the main diagonal are also
+selected.
+
+        <p>The absolute value of <var>k</var> must not be greater than the number of
+sub- or super-diagonals.
+
+        <p>For example,
+
+     <pre class="example">          tril (ones (3), -1)
+                 0  0  0
+                   1  0  0
+                   1  1  0
+</pre>
+        <p class="noindent">and
+
+     <pre class="example">          tril (ones (3), 1)
+                 1  1  0
+                   1  1  1
+                   1  1  1
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtriu.html#doc_002dtriu">triu</a>, <a href="doc_002ddiag.html#doc_002ddiag">diag</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/vec.m -->
+   <p><a name="doc_002dvec"></a>
+
+<div class="defun">
+— Function File:  <b>vec</b> (<var>x</var>)<var><a name="index-vec-1300"></a></var><br>
+<blockquote><p>Return the vector obtained by stacking the columns of the matrix <var>x</var>
+one above the other. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/vech.m -->
+   <p><a name="doc_002dvech"></a>
+
+<div class="defun">
+— Function File:  <b>vech</b> (<var>x</var>)<var><a name="index-vech-1301"></a></var><br>
+<blockquote><p>Return the vector obtained by eliminating all supradiagonal elements of
+the square matrix <var>x</var> and stacking the result one column above the
+other. 
+</p></blockquote></div>
+
+   <p><a name="doc_002dpostpad"></a><!-- ./general/prepad.m -->
+<a name="doc_002dprepad"></a>
+
+<div class="defun">
+— Function File:  <b>prepad</b> (<var>x, l, c</var>)<var><a name="index-prepad-1302"></a></var><br>
+— Function File:  <b>prepad</b> (<var>x, l, c, dim</var>)<var><a name="index-prepad-1303"></a></var><br>
+<blockquote><p>Prepend (append) the scalar value <var>c</var> to the vector <var>x</var>
+until it is of length <var>l</var>.  If the third argument is not
+supplied, a value of 0 is used.
+
+        <p>If <code>length (</code><var>x</var><code>) > </code><var>l</var>, elements from the beginning (end) of
+<var>x</var> are removed until a vector of length <var>l</var> is obtained.
+
+        <p>If <var>x</var> is a matrix, elements are prepended or removed from each row.
+
+        <p>If the optional <var>dim</var> argument is given, then operate along this
+dimension. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpostpad.html#doc_002dpostpad">postpad</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002ddiag"></a>
+
+<div class="defun">
+— Built-in Function:  <b>diag</b> (<var>v, k</var>)<var><a name="index-diag-1304"></a></var><br>
+<blockquote><p>Return a diagonal matrix with vector <var>v</var> on diagonal <var>k</var>.  The
+second argument is optional.  If it is positive, the vector is placed on
+the <var>k</var>-th super-diagonal.  If it is negative, it is placed on the
+<var>-k</var>-th sub-diagonal.  The default value of <var>k</var> is 0, and the
+vector is placed on the main diagonal.  For example,
+
+     <pre class="example">          diag ([1, 2, 3], 1)
+                 0  1  0  0
+                   0  0  2  0
+                   0  0  0  3
+                   0  0  0  0
+</pre>
+        <p class="noindent">Given a matrix argument, instead of a vector, <code>diag</code> extracts the
+<var>k</var>-th diagonal of the matrix. 
+</p></blockquote></div>
+
+<!-- ./general/blkdiag.m -->
+   <p><a name="doc_002dblkdiag"></a>
+
+<div class="defun">
+— Function File:  <b>blkdiag</b> (<var>a, b, c, <small class="dots">...</small></var>)<var><a name="index-blkdiag-1305"></a></var><br>
+<blockquote><p>Build a block diagonal matrix from <var>a</var>, <var>b</var>, <var>c</var>, <small class="dots">...</small>. 
+All the arguments must be numeric and are two-dimensional matrices or
+scalars. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddiag.html#doc_002ddiag">diag</a>, <a href="doc_002dhorzcat.html#doc_002dhorzcat">horzcat</a>, <a href="doc_002dvertcat.html#doc_002dvertcat">vertcat</a>. 
+</p></blockquote></div>
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> For example, to first sort
+based on the values in column 1, and then, for any values that are
+repeated in column 1, sort based on the values found in column 2, etc.</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Recursion.html b/doc/interpreter/HTML/Recursion.html
new file mode 100644
index 0000000..d83f7f9
--- /dev/null
+++ b/doc/interpreter/HTML/Recursion.html
@@ -0,0 +1,86 @@
+<html lang="en">
+<head>
+<title>Recursion - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Calling-Functions.html#Calling-Functions" title="Calling Functions">
+<link rel="prev" href="Call-by-Value.html#Call-by-Value" title="Call by Value">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Recursion"></a>
+Previous: <a rel="previous" accesskey="p" href="Call-by-Value.html#Call-by-Value">Call by Value</a>,
+Up: <a rel="up" accesskey="u" href="Calling-Functions.html#Calling-Functions">Calling Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">8.2.2 Recursion</h4>
+
+<p><a name="index-factorial-function-454"></a>
+With some restrictions<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>, recursive function calls are allowed.  A
+<dfn>recursive function</dfn> is one which calls itself, either directly or
+indirectly.  For example, here is an inefficient<a rel="footnote" href="#fn-2" name="fnd-2"><sup>2</sup></a> way to compute the factorial of a given integer:
+
+<pre class="example">     function retval = fact (n)
+       if (n > 0)
+         retval = n * fact (n-1);
+       else
+         retval = 1;
+       endif
+     endfunction
+</pre>
+   <p>This function is recursive because it calls itself directly.  It
+eventually terminates because each time it calls itself, it uses an
+argument that is one less than was used for the previous call.  Once the
+argument is no longer greater than zero, it does not call itself, and
+the recursion ends.
+
+   <p>The built-in variable <code>max_recursion_depth</code> specifies a limit to
+the recursion depth and prevents Octave from recursing infinitely.
+
+<!-- ov-usr-fcn.cc -->
+   <p><a name="doc_002dmax_005frecursion_005fdepth"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>max_recursion_depth</b> ()<var><a name="index-max_005frecursion_005fdepth-455"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>max_recursion_depth</b> (<var>new_val</var>)<var><a name="index-max_005frecursion_005fdepth-456"></a></var><br>
+<blockquote><p>Query or set the internal limit on the number of times a function may
+be called recursively.  If the limit is exceeded, an error message is
+printed and control returns to the top level. 
+</p></blockquote></div>
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> Some of Octave's functions are
+implemented in terms of functions that cannot be called recursively. 
+For example, the ODE solver <code>lsode</code> is ultimately implemented in a
+Fortran subroutine that cannot be called recursively, so <code>lsode</code>
+should not be called either directly or indirectly from within the
+user-supplied function that <code>lsode</code> requires.  Doing so will result
+in an error.</p>
+
+   <p class="footnote"><small>[<a name="fn-2" href="#fnd-2">2</a>]</small> It would be
+much better to use <code>prod (1:n)</code>, or <code>gamma (n+1)</code> instead,
+after first checking to ensure that the value <code>n</code> is actually a
+positive integer.</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Reporting-Bugs.html b/doc/interpreter/HTML/Reporting-Bugs.html
new file mode 100644
index 0000000..76caca4
--- /dev/null
+++ b/doc/interpreter/HTML/Reporting-Bugs.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Reporting Bugs - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="prev" href="Actual-Bugs.html#Actual-Bugs" title="Actual Bugs">
+<link rel="next" href="Bug-Criteria.html#Bug-Criteria" title="Bug Criteria">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Reporting-Bugs"></a>
+Next: <a rel="next" accesskey="n" href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a>,
+Previous: <a rel="previous" accesskey="p" href="Actual-Bugs.html#Actual-Bugs">Actual Bugs</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.2 Reporting Bugs</h3>
+
+<p><a name="index-bugs-2517"></a><a name="index-reporting-bugs-2518"></a>
+Your bug reports play an essential role in making Octave reliable.
+
+   <p>When you encounter a problem, the first thing to do is to see if it is
+already known.  See <a href="Trouble.html#Trouble">Trouble</a>.  If it isn't known, then you should
+report the problem.
+
+   <p>Reporting a bug may help you by bringing a solution to your problem, or
+it may not.  In any case, the principal function of a bug report is
+to help the entire community by making the next version of Octave work
+better.  Bug reports are your contribution to the maintenance of Octave.
+
+   <p>In order for a bug report to serve its purpose, you must include the
+information that makes it possible to fix the bug.
+
+   <p><a name="index-bug_005freport-2519"></a>
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function <code>bug_report</code>.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+<!-- ./miscellaneous/bug_report.m -->
+   <p><a name="doc_002dbug_005freport"></a>
+
+<div class="defun">
+— Function File:  <b>bug_report</b> ()<var><a name="index-bug_005freport-2520"></a></var><br>
+<blockquote><p>Have Octave create a bug report template file, invoke your favorite
+editor, and submit the report to the bug-octave mailing list when
+you are finished editing. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a>
+<li><a accesskey="2" href="Bug-Lists.html#Bug-Lists">Where</a>:              Where to send your bug report. 
+<li><a accesskey="3" href="Bug-Reporting.html#Bug-Reporting">Reporting</a>:      How to report a bug effectively. 
+<li><a accesskey="4" href="Sending-Patches.html#Sending-Patches">Patches</a>:      How to send a patch for Octave. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Representing-Images.html b/doc/interpreter/HTML/Representing-Images.html
new file mode 100644
index 0000000..0553988
--- /dev/null
+++ b/doc/interpreter/HTML/Representing-Images.html
@@ -0,0 +1,477 @@
+<html lang="en">
+<head>
+<title>Representing Images - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link rel="prev" href="Displaying-Images.html#Displaying-Images" title="Displaying Images">
+<link rel="next" href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images" title="Plotting on top of Images">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Representing-Images"></a>
+Next: <a rel="next" accesskey="n" href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images">Plotting on top of Images</a>,
+Previous: <a rel="previous" accesskey="p" href="Displaying-Images.html#Displaying-Images">Displaying Images</a>,
+Up: <a rel="up" accesskey="u" href="Image-Processing.html#Image-Processing">Image Processing</a>
+<hr>
+</div>
+
+<h3 class="section">31.3 Representing Images</h3>
+
+<p>In general Octave supports four different kinds of images, gray-scale
+images, RGB images, binary images, and indexed images.  A gray-scale
+image is represented with an M-by-N matrix in which each
+element corresponds to the intensity of a pixel.  An RGB image is
+represented with an M-by-N-by-3 array where each
+3-vector corresponds to the red, green, and blue intensities of each
+pixel.
+
+   <p>The actual meaning of the value of a pixel in a gray-scale or RGB
+image depends on the class of the matrix.  If the matrix is of class
+<code>double</code> pixel intensities are between 0 and 1, if it is of class
+<code>uint8</code> intensities are between 0 and 255, and if it is of class
+<code>uint16</code> intensities are between 0 and 65535.
+
+   <p>A binary image is an M-by-N matrix of class <code>logical</code>. 
+A pixel in a binary image is black if it is <code>false</code> and white
+if it is <code>true</code>.
+
+   <p>An indexed image consists of an M-by-N matrix of integers
+and a C-by-3 color map.  Each integer corresponds to an
+index in the color map, and each row in the color map corresponds to
+an RGB color.  The color map must be of class <code>double</code> with values
+between 0 and 1.
+
+<!-- ./image/gray2ind.m -->
+   <p><a name="doc_002dgray2ind"></a>
+
+<div class="defun">
+— Function File: [<var>img</var>, <var>map</var>] = <b>gray2ind</b> (<var>I, n</var>)<var><a name="index-gray2ind-2203"></a></var><br>
+<blockquote><p>Convert a gray scale intensity image to an Octave indexed image. 
+The indexed image will consist of <var>n</var> different intensity values.  If not
+given <var>n</var> will default to 64. 
+</p></blockquote></div>
+
+<!-- ./image/ind2gray.m -->
+   <p><a name="doc_002dind2gray"></a>
+
+<div class="defun">
+— Function File:  <b>ind2gray</b> (<var>x, map</var>)<var><a name="index-ind2gray-2204"></a></var><br>
+<blockquote><p>Convert an Octave indexed image to a gray scale intensity image. 
+If <var>map</var> is omitted, the current colormap is used to determine the
+intensities. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgray2ind.html#doc_002dgray2ind">gray2ind</a>, <a href="doc_002drgb2ntsc.html#doc_002drgb2ntsc">rgb2ntsc</a>, <a href="doc_002dimage.html#doc_002dimage">image</a>, <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/rgb2ind.m -->
+   <p><a name="doc_002drgb2ind"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>map</var>] = <b>rgb2ind</b> (<var>rgb</var>)<var><a name="index-rgb2ind-2205"></a></var><br>
+— Function File: [<var>x</var>, <var>map</var>] = <b>rgb2ind</b> (<var>r, g, b</var>)<var><a name="index-rgb2ind-2206"></a></var><br>
+<blockquote><p>Convert an RGB image to an Octave indexed image. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dind2rgb.html#doc_002dind2rgb">ind2rgb</a>, <a href="doc_002drgb2ntsc.html#doc_002drgb2ntsc">rgb2ntsc</a>. 
+</p></blockquote></div>
+
+<!-- ./image/ind2rgb.m -->
+   <p><a name="doc_002dind2rgb"></a>
+
+<div class="defun">
+— Function File: <var>rgb</var> = <b>ind2rgb</b> (<var>x, map</var>)<var><a name="index-ind2rgb-2207"></a></var><br>
+— Function File: [<var>r</var>, <var>g</var>, <var>b</var>] = <b>ind2rgb</b> (<var>x, map</var>)<var><a name="index-ind2rgb-2208"></a></var><br>
+<blockquote><p>Convert an indexed image to red, green, and blue color components. 
+If the colormap doesn't contain enough colors, pad it with the
+last color in the map. 
+If <var>map</var> is omitted, the current colormap is used for the conversion. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drgb2ind.html#doc_002drgb2ind">rgb2ind</a>, <a href="doc_002dimage.html#doc_002dimage">image</a>, <a href="doc_002dimshow.html#doc_002dimshow">imshow</a>, <a href="doc_002dind2gray.html#doc_002dind2gray">ind2gray</a>, <a href="doc_002dgray2ind.html#doc_002dgray2ind">gray2ind</a>. 
+</p></blockquote></div>
+
+<!-- ./image/colormap.m -->
+   <p><a name="doc_002dcolormap"></a>
+
+<div class="defun">
+— Function File:  <b>colormap</b> (<var>map</var>)<var><a name="index-colormap-2209"></a></var><br>
+— Function File:  <b>colormap</b> (<var>"default"</var>)<var><a name="index-colormap-2210"></a></var><br>
+<blockquote><p>Set the current colormap.
+
+        <p><code>colormap (</code><var>map</var><code>)</code> sets the current colormap to <var>map</var>.  The
+color map should be an <var>n</var> row by 3 column matrix.  The columns
+contain red, green, and blue intensities respectively.  All entries
+should be between 0 and 1 inclusive.  The new colormap is returned.
+
+        <p><code>colormap ("default")</code> restores the default colormap (the
+<code>jet</code> map with 64 entries).  The default colormap is returned.
+
+        <p>With no arguments, <code>colormap</code> returns the current color map. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002djet.html#doc_002djet">jet</a>. 
+</p></blockquote></div>
+
+<!-- ./image/brighten.m -->
+   <p><a name="doc_002dbrighten"></a>
+
+<div class="defun">
+— Function File: <var>map_out</var> = <b>brighten</b> (<var>map, beta</var>)<var><a name="index-brighten-2211"></a></var><br>
+— Function File: <var>map_out</var> = <b>brighten</b> (<var>h, beta</var>)<var><a name="index-brighten-2212"></a></var><br>
+— Function File: <var>map_out</var> = <b>brighten</b> (<var>beta</var>)<var><a name="index-brighten-2213"></a></var><br>
+<blockquote><p>Darkens or brightens the given colormap.  If the <var>map</var> argument
+is omitted, the function is applied to the current colormap.  The first
+argument can also be a valid graphics handle <var>h</var>, in which case
+<code>brighten</code> is applied to the colormap associated with this handle.
+
+        <p>Should the resulting colormap <var>map_out</var> not be assigned, it will be
+written to the current colormap.
+
+        <p>The argument <var>beta</var> should be a scalar between -1 and 1,
+where a negative value darkens and a positive value brightens
+the colormap. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/autumn.m -->
+   <p><a name="doc_002dautumn"></a>
+
+<div class="defun">
+— Function File:  <b>autumn</b> (<var>n</var>)<var><a name="index-autumn-2214"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is red through orange to yellow. 
+The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/bone.m -->
+   <p><a name="doc_002dbone"></a>
+
+<div class="defun">
+— Function File:  <b>bone</b> (<var>n</var>)<var><a name="index-bone-2215"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is a gray colormap with a light
+blue tone.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/cool.m -->
+   <p><a name="doc_002dcool"></a>
+
+<div class="defun">
+— Function File:  <b>cool</b> (<var>n</var>)<var><a name="index-cool-2216"></a></var><br>
+<blockquote><p>Create color colormap.  The colormap is cyan to magenta.  The argument
+<var>n</var> should be a scalar.  If it is omitted, the length of the current
+colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/copper.m -->
+   <p><a name="doc_002dcopper"></a>
+
+<div class="defun">
+— Function File:  <b>copper</b> (<var>n</var>)<var><a name="index-copper-2217"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is black to a light copper tone. 
+The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/flag.m -->
+   <p><a name="doc_002dflag"></a>
+
+<div class="defun">
+— Function File:  <b>flag</b> (<var>n</var>)<var><a name="index-flag-2218"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap cycles through red, white, blue
+and black.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/gray.m -->
+   <p><a name="doc_002dgray"></a>
+
+<div class="defun">
+— Function File:  <b>gray</b> (<var>n</var>)<var><a name="index-gray-2219"></a></var><br>
+<blockquote><p>Return a gray colormap with <var>n</var> entries corresponding to values from
+0 to <var>n</var>-1.  The argument <var>n</var> should be a scalar.  If it is
+omitted, the length of the current colormap or 64 is assumed. 
+</p></blockquote></div>
+
+<!-- ./image/hot.m -->
+   <p><a name="doc_002dhot"></a>
+
+<div class="defun">
+— Function File:  <b>hot</b> (<var>n</var>)<var><a name="index-hot-2220"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is black through dark red, red,
+orange, yellow to white.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/hsv.m -->
+   <p><a name="doc_002dhsv"></a>
+
+<div class="defun">
+— Function File:  <b>hsv</b> (<var>n</var>)<var><a name="index-hsv-2221"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is red through yellow, green,
+cyan, blue, magenta to red.  It is obtained by linearly varying the
+hue through all possible values while keeping constant maximum
+saturation and value and is equivalent to
+<code>hsv2rgb ([linspace(0,1,N)', ones(N,2)])</code>.
+
+        <p>The argument <var>n</var> should be a scalar.  If it is omitted, the
+length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/jet.m -->
+   <p><a name="doc_002djet"></a>
+
+<div class="defun">
+— Function File:  <b>jet</b> (<var>n</var>)<var><a name="index-jet-2222"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is dark blue through blue, cyan,
+green, yellow, red to dark red.  The argument <var>n</var> should be a scalar. 
+If it is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/ocean.m -->
+   <p><a name="doc_002docean"></a>
+
+<div class="defun">
+— Function File:  <b>ocean</b> (<var>n</var>)<var><a name="index-ocean-2223"></a></var><br>
+<blockquote><p>Create color colormap.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+</p></blockquote></div>
+
+<!-- ./image/pink.m -->
+   <p><a name="doc_002dpink"></a>
+
+<div class="defun">
+— Function File:  <b>pink</b> (<var>n</var>)<var><a name="index-pink-2224"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap gives a sepia tone on black and
+white images.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/prism.m -->
+   <p><a name="doc_002dprism"></a>
+
+<div class="defun">
+— Function File:  <b>prism</b> (<var>n</var>)<var><a name="index-prism-2225"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap cycles trough red, orange, yellow,
+green, blue and violet.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/rainbow.m -->
+   <p><a name="doc_002drainbow"></a>
+
+<div class="defun">
+— Function File:  <b>rainbow</b> (<var>n</var>)<var><a name="index-rainbow-2226"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is red through orange, yellow, green,
+blue to violet.  The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/spring.m -->
+   <p><a name="doc_002dspring"></a>
+
+<div class="defun">
+— Function File:  <b>spring</b> (<var>n</var>)<var><a name="index-spring-2227"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is magenta to yellow. 
+The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/summer.m -->
+   <p><a name="doc_002dsummer"></a>
+
+<div class="defun">
+— Function File:  <b>summer</b> (<var>n</var>)<var><a name="index-summer-2228"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is green to yellow. 
+The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/white.m -->
+   <p><a name="doc_002dwhite"></a>
+
+<div class="defun">
+— Function File:  <b>white</b> (<var>n</var>)<var><a name="index-white-2229"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is completely white. 
+The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/winter.m -->
+   <p><a name="doc_002dwinter"></a>
+
+<div class="defun">
+— Function File:  <b>winter</b> (<var>n</var>)<var><a name="index-winter-2230"></a></var><br>
+<blockquote><p>Create color colormap.  This colormap is blue to green. 
+The argument <var>n</var> should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+<!-- ./image/contrast.m -->
+   <p><a name="doc_002dcontrast"></a>
+
+<div class="defun">
+— Function File:  <b>contrast</b> (<var>x, n</var>)<var><a name="index-contrast-2231"></a></var><br>
+<blockquote><p>Return a gray colormap that maximizes the contrast in an image.  The
+returned colormap will have <var>n</var> rows.  If <var>n</var> is not defined
+then the size of the current colormap is used instead. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+   <p>An additional colormap is <code>gmap40</code>.  This code map contains only
+colors with integer values of the red, green and blue components.  This
+is a workaround for a limitation of gnuplot 4.0, that does not allow the color of
+line or patch objects to be set, and so <code>gmap40</code> is useful for
+gnuplot 4.0 users, and in particular in conjunction with the <var>bar</var>,
+<var>barh</var> or <var>contour</var> functions.
+
+<!-- ./image/gmap40.m -->
+   <p><a name="doc_002dgmap40"></a>
+
+<div class="defun">
+— Function File:  <b>gmap40</b> (<var>n</var>)<var><a name="index-gmap40-2232"></a></var><br>
+<blockquote><p>Create a color colormap.  The colormap is red, green, blue, yellow,
+magenta and cyan.  These are the colors that are allowed with patch
+objects using gnuplot 4.0, and so this colormap function is specially
+designed for users of gnuplot 4.0.  The argument <var>n</var> should be
+a scalar.  If it is omitted, a length of 6 is assumed.  Larger values
+of <var>n</var> result in a repetition of the above colors
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcolormap.html#doc_002dcolormap">colormap</a>. 
+</p></blockquote></div>
+
+   <p>You may use the <code>spinmap</code> function to cycle through the colors in
+the current colormap, displaying the changes for the current figure.
+
+<!-- ./plot/spinmap.m -->
+   <p><a name="doc_002dspinmap"></a>
+
+<div class="defun">
+— Function File:  <b>spinmap</b> (<var>t, inc</var>)<var><a name="index-spinmap-2233"></a></var><br>
+<blockquote><p>Cycle the colormap for <var>t</var> seconds with an increment
+of <var>inc</var>.  Both parameters are optional.  The default cycle time
+is 5 seconds and the default increment is 2.
+
+        <p>A higher value of <var>inc</var> causes a faster cycle through the
+colormap. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgca.html#doc_002dgca">gca</a>, <a href="doc_002dcolorbar.html#doc_002dcolorbar">colorbar</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Return-Types-of-Operators-and-Functions.html b/doc/interpreter/HTML/Return-Types-of-Operators-and-Functions.html
new file mode 100644
index 0000000..961a461
--- /dev/null
+++ b/doc/interpreter/HTML/Return-Types-of-Operators-and-Functions.html
@@ -0,0 +1,109 @@
+<html lang="en">
+<head>
+<title>Return Types of Operators and Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Operators-and-Functions.html#Operators-and-Functions" title="Operators and Functions">
+<link rel="prev" href="Sparse-Functions.html#Sparse-Functions" title="Sparse Functions">
+<link rel="next" href="Mathematical-Considerations.html#Mathematical-Considerations" title="Mathematical Considerations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Return-Types-of-Operators-and-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a>,
+Previous: <a rel="previous" accesskey="p" href="Sparse-Functions.html#Sparse-Functions">Sparse Functions</a>,
+Up: <a rel="up" accesskey="u" href="Operators-and-Functions.html#Operators-and-Functions">Operators and Functions</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">21.1.4.2 The Return Types of Operators and Functions</h5>
+
+<p>The two basic reasons to use sparse matrices are to reduce the memory
+usage and to not have to do calculations on zero elements.  The two are
+closely related in that the computation time on a sparse matrix operator
+or function is roughly linear with the number of non-zero elements.
+
+   <p>Therefore, there is a certain density of non-zero elements of a matrix
+where it no longer makes sense to store it as a sparse matrix, but rather
+as a full matrix.  For this reason operators and functions that have a
+high probability of returning a full matrix will always return one.  For
+example adding a scalar constant to a sparse matrix will almost always
+make it a full matrix, and so the example
+
+<pre class="example">     speye(3) + 0
+        1  0  0
+       0  1  0
+       0  0  1
+</pre>
+   <p>returns a full matrix as can be seen.
+
+   <p>Additionally, if <code>sparse_auto_mutate</code> is true, all sparse functions
+test the amount of memory occupied by the sparse matrix to see if the
+amount of storage used is larger than the amount used by the full
+equivalent.  Therefore <code>speye (2) * 1</code> will return a full matrix as
+the memory used is smaller for the full version than the sparse version.
+
+   <p>As all of the mixed operators and functions between full and sparse
+matrices exist, in general this does not cause any problems.  However,
+one area where it does cause a problem is where a sparse matrix is
+promoted to a full matrix, where subsequent operations would resparsify
+the matrix.  Such cases are rare, but can be artificially created, for
+example <code>(fliplr(speye(3)) + speye(3)) - speye(3)</code> gives a full
+matrix when it should give a sparse one.  In general, where such cases
+occur, they impose only a small memory penalty.
+
+   <p>There is however one known case where this behavior of Octave's
+sparse matrices will cause a problem.  That is in the handling of the
+<dfn>diag</dfn> function.  Whether <dfn>diag</dfn> returns a sparse or full matrix
+depending on the type of its input arguments.  So
+
+<pre class="example">      a = diag (sparse([1,2,3]), -1);
+</pre>
+   <p>should return a sparse matrix.  To ensure this actually happens, the
+<dfn>sparse</dfn> function, and other functions based on it like <dfn>speye</dfn>,
+always returns a sparse matrix, even if the memory used will be larger
+than its full representation.
+
+<!-- ov-base.cc -->
+   <p><a name="doc_002dsparse_005fauto_005fmutate"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>sparse_auto_mutate</b> ()<var><a name="index-sparse_005fauto_005fmutate-1684"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>sparse_auto_mutate</b> (<var>new_val</var>)<var><a name="index-sparse_005fauto_005fmutate-1685"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave will
+automatically mutate sparse matrices to real matrices to save memory. 
+For example,
+
+     <pre class="example">          s = speye(3);
+          sparse_auto_mutate (false)
+          s (:, 1) = 1;
+          typeinfo (s)
+           sparse matrix
+          sparse_auto_mutate (true)
+          s (1, :) = 1;
+          typeinfo (s)
+           matrix
+</pre>
+        </blockquote></div>
+
+   <p>Note that the <code>sparse_auto_mutate</code> option is incompatible with
+<span class="sc">matlab</span>, and so it is off by default.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Returning-From-a-Function.html b/doc/interpreter/HTML/Returning-From-a-Function.html
new file mode 100644
index 0000000..f4cf3ee
--- /dev/null
+++ b/doc/interpreter/HTML/Returning-From-a-Function.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Returning From a Function - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists" title="Variable-length Return Lists">
+<link rel="next" href="Default-Arguments.html#Default-Arguments" title="Default Arguments">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Returning-From-a-Function"></a>
+Next: <a rel="next" accesskey="n" href="Default-Arguments.html#Default-Arguments">Default Arguments</a>,
+Previous: <a rel="previous" accesskey="p" href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.5 Returning From a Function</h3>
+
+<p>The body of a user-defined function can contain a <code>return</code> statement. 
+This statement returns control to the rest of the Octave program.  It
+looks like this:
+
+<pre class="example">     return
+</pre>
+   <p>Unlike the <code>return</code> statement in C, Octave's <code>return</code>
+statement cannot be used to return a value from a function.  Instead,
+you must assign values to the list of return variables that are part of
+the <code>function</code> statement.  The <code>return</code> statement simply makes
+it easier to exit a function from a deeply nested loop or conditional
+statement.
+
+   <p>Here is an example of a function that checks to see if any elements of a
+vector are nonzero.
+
+<pre class="example">     function retval = any_nonzero (v)
+       retval = 0;
+       for i = 1:length (v)
+         if (v (i) != 0)
+           retval = 1;
+           return;
+         endif
+       endfor
+       printf ("no nonzero elements found\n");
+     endfunction
+</pre>
+   <p>Note that this function could not have been written using the
+<code>break</code> statement to exit the loop once a nonzero value is found
+without adding extra logic to avoid printing the message if the vector
+does contain a nonzero element.
+
+<div class="defun">
+— Keyword: <b>return</b><var><a name="index-return-610"></a></var><br>
+<blockquote><p>When Octave encounters the keyword <code>return</code> inside a function or
+script, it returns control to the caller immediately.  At the top level,
+the return statement is ignored.  A <code>return</code> statement is assumed
+at the end of every function definition. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Root-Figure-Properties.html b/doc/interpreter/HTML/Root-Figure-Properties.html
new file mode 100644
index 0000000..e25861f
--- /dev/null
+++ b/doc/interpreter/HTML/Root-Figure-Properties.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Root Figure Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="next" href="Figure-Properties.html#Figure-Properties" title="Figure Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Root-Figure-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Figure-Properties.html#Figure-Properties">Figure Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.1 Root Figure Properties</h5>
+
+     <dl>
+<dt><code>currentfigure</code><dd>Index to graphics object for the current figure.
+
+     <!-- FIXME - does this work? -->
+     <!-- @item visible -->
+     <!-- Either @code{"on"} or @code{"off"} to toggle display of figures. -->
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Running-Octave-From-Within-Emacs.html b/doc/interpreter/HTML/Running-Octave-From-Within-Emacs.html
new file mode 100644
index 0000000..054ed33
--- /dev/null
+++ b/doc/interpreter/HTML/Running-Octave-From-Within-Emacs.html
@@ -0,0 +1,130 @@
+<html lang="en">
+<head>
+<title>Running Octave From Within Emacs - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Emacs-Octave-Support.html#Emacs-Octave-Support" title="Emacs Octave Support">
+<link rel="prev" href="Using-Octave-Mode.html#Using-Octave-Mode" title="Using Octave Mode">
+<link rel="next" href="Using-the-Emacs-Info-Reader-for-Octave.html#Using-the-Emacs-Info-Reader-for-Octave" title="Using the Emacs Info Reader for Octave">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Running-Octave-From-Within-Emacs"></a>
+Next: <a rel="next" accesskey="n" href="Using-the-Emacs-Info-Reader-for-Octave.html#Using-the-Emacs-Info-Reader-for-Octave">Using the Emacs Info Reader for Octave</a>,
+Previous: <a rel="previous" accesskey="p" href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a>,
+Up: <a rel="up" accesskey="u" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">G.3 Running Octave From Within Emacs</h3>
+
+<p>The package <samp><span class="file">octave</span></samp> provides commands for running an inferior
+Octave process in a special Emacs buffer.  Use
+<pre class="lisp">     M-x run-octave
+</pre>
+   <p class="noindent">to directly start an inferior Octave process.  If Emacs does not know
+about this command, add the line
+<pre class="lisp">     (autoload 'run-octave "octave-inf" nil t)
+</pre>
+   <p class="noindent">to your <samp><span class="file">.emacs</span></samp> file.
+
+   <p>This will start Octave in a special buffer the name of which is
+specified by the variable <code>inferior-octave-buffer</code> and defaults to
+<code>"*Inferior Octave*"</code>.  From within this buffer, you can
+interact with the inferior Octave process `as usual', i.e., by entering
+Octave commands at the prompt.  The buffer is in Inferior Octave mode,
+which is derived from the standard Comint mode, a major mode for
+interacting with an inferior interpreter.  See the documentation for
+<code>comint-mode</code> for more details, and use <kbd>C-h b</kbd> to find out
+about available special keybindings.
+
+   <p>You can also communicate with an inferior Octave process from within
+files with Octave code (i.e., buffers in Octave mode), using the
+following commands.
+
+     <dl>
+<dt><kbd>C-c i l</kbd><dd>Send the current line to the inferior Octave process
+(<code>octave-send-line</code>). 
+With positive prefix argument <var>N</var>, send that many lines. 
+If <code>octave-send-line-auto-forward</code> is non-<code>nil</code>, go to the
+next unsent code line. 
+<br><dt><kbd>C-c i b</kbd><dd>Send the current block to the inferior Octave process
+(<code>octave-send-block</code>). 
+<br><dt><kbd>C-c i f</kbd><dd>Send the current function to the inferior Octave process
+(<code>octave-send-defun</code>). 
+<br><dt><kbd>C-c i r</kbd><dd>Send the region to the inferior Octave process
+(<code>octave-send-region</code>). 
+<br><dt><kbd>C-c i s</kbd><dd>Make sure that `inferior-octave-buffer' is displayed
+(<code>octave-show-process-buffer</code>). 
+<br><dt><kbd>C-c i h</kbd><dd>Delete all windows that display the inferior Octave buffer
+(<code>octave-hide-process-buffer</code>). 
+<br><dt><kbd>C-c i k</kbd><dd>Kill the inferior Octave process and its buffer
+(<code>octave-kill-process</code>). 
+</dl>
+
+   <p>The effect of the commands which send code to the Octave process can be
+customized by the following variables.
+     <dl>
+<dt><code>octave-send-echo-input</code><dd>Non-<code>nil</code> means echo input sent to the inferior Octave process. 
+Default is <code>t</code>.
+
+     <br><dt><code>octave-send-show-buffer</code><dd>Non-<code>nil</code> means display the buffer running the Octave process after
+sending a command (but without selecting it). 
+Default is <code>t</code>. 
+</dl>
+
+   <p>If you send code and there is no inferior Octave process yet, it will be
+started automatically.
+
+   <p>The startup of the inferior Octave process is highly customizable. 
+The variable <code>inferior-octave-startup-args</code> can be used for
+specifying command lines arguments to be passed to Octave on startup
+as a list of strings.  For example, to suppress the startup message and
+use `traditional' mode, set this to <code>'("-q" "--traditional")</code>. 
+You can also specify a startup file of Octave commands to be loaded on
+startup;  note that these commands will not produce any visible output
+in the process buffer.  Which file to use is controlled by the variable
+<code>inferior-octave-startup-file</code>.  If this is <code>nil</code>, the file
+<samp><span class="file">~/.emacs-octave</span></samp> is used if it exists.
+
+   <p>And finally, <code>inferior-octave-mode-hook</code> is run after starting the
+process and putting its buffer into Inferior Octave mode.  Hence, if you
+like the up and down arrow keys to behave in the interaction buffer as
+in the shell, and you want this buffer to use nice colors, add
+<pre class="lisp">     (add-hook 'inferior-octave-mode-hook
+               (lambda ()
+                 (turn-on-font-lock)
+                 (define-key inferior-octave-mode-map [up]
+                   'comint-previous-input)
+                 (define-key inferior-octave-mode-map [down]
+                   'comint-next-input)))
+</pre>
+   <p class="noindent">to your <samp><span class="file">.emacs</span></samp> file.  You could also swap the roles of <kbd>C-a</kbd>
+(<code>beginning-of-line</code>) and <code>C-c C-a</code> (<code>comint-bol</code>) using
+this hook.
+
+   <blockquote>
+<strong>Note</strong> that if you set your Octave prompts to something different
+from the defaults, make sure that <code>inferior-octave-prompt</code> matches
+them.  Otherwise, <em>nothing</em> will work, because Emacs will not know
+when Octave is waiting for input, or done sending output. 
+</blockquote>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Running-Octave.html b/doc/interpreter/HTML/Running-Octave.html
new file mode 100644
index 0000000..a913b1c
--- /dev/null
+++ b/doc/interpreter/HTML/Running-Octave.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Running Octave - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Introduction.html#Introduction" title="Introduction">
+<link rel="next" href="Simple-Examples.html#Simple-Examples" title="Simple Examples">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Running-Octave"></a>
+Next: <a rel="next" accesskey="n" href="Simple-Examples.html#Simple-Examples">Simple Examples</a>,
+Up: <a rel="up" accesskey="u" href="Introduction.html#Introduction">Introduction</a>
+<hr>
+</div>
+
+<h3 class="section">1.1 Running Octave</h3>
+
+<p>On most systems, Octave is started with the shell command
+‘<samp><span class="samp">octave</span></samp>’.  Octave displays an initial message and then a prompt
+indicating it is ready to accept input.  You can begin typing Octave
+commands immediately afterward.
+
+   <p>If you get into trouble, you can usually interrupt Octave by typing
+<kbd>Control-C</kbd> (written <kbd>C-c</kbd> for short).  <kbd>C-c</kbd> gets
+its name from the fact that you type it by holding down <CTRL> and
+then pressing <c>.  Doing this will normally return you to Octave's
+prompt.
+
+   <p><a name="index-exiting-octave-8"></a><a name="index-quitting-octave-9"></a>To exit Octave, type <kbd>quit</kbd>, or <kbd>exit</kbd> at the Octave prompt.
+
+   <p>On systems that support job control, you can suspend Octave by sending
+it a <code>SIGTSTP</code> signal, usually by typing <kbd>C-z</kbd>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Saving-Data-on-Unexpected-Exits.html b/doc/interpreter/HTML/Saving-Data-on-Unexpected-Exits.html
new file mode 100644
index 0000000..73a3d56
--- /dev/null
+++ b/doc/interpreter/HTML/Saving-Data-on-Unexpected-Exits.html
@@ -0,0 +1,134 @@
+<html lang="en">
+<head>
+<title>Saving Data on Unexpected Exits - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Simple-File-I_002fO.html#Simple-File-I_002fO" title="Simple File I/O">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Saving-Data-on-Unexpected-Exits"></a>
+Up: <a rel="up" accesskey="u" href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">14.1.3.1 Saving Data on Unexpected Exits</h5>
+
+<p>If Octave for some reason exits unexpectedly it will by default save the
+variables available in the workspace to a file in the current directory. 
+By default this file is named ‘<samp><span class="samp">octave-core</span></samp>’ and can be loaded
+into memory with the <code>load</code> command.  While the default behavior
+most often is reasonable it can be changed through the following
+functions.
+
+<!-- load-save.cc -->
+   <p><a name="doc_002dcrash_005fdumps_005foctave_005fcore"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>crash_dumps_octave_core</b> ()<var><a name="index-crash_005fdumps_005foctave_005fcore-755"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>crash_dumps_octave_core</b> (<var>new_val</var>)<var><a name="index-crash_005fdumps_005foctave_005fcore-756"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it
+crashes or receives a hangup, terminate or similar signal. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002doctave_005fcore_005ffile_005flimit.html#doc_002doctave_005fcore_005ffile_005flimit">octave_core_file_limit</a>, <a href="doc_002doctave_005fcore_005ffile_005fname.html#doc_002doctave_005fcore_005ffile_005fname">octave_core_file_name</a>, <a href="doc_002doctave_005fcore_005ffile_005foptions.html#doc_002doctave_005fcore_005ffile_005foptions">octave_core_file_options</a>. 
+</p></blockquote></div>
+
+<!-- sighandlers.cc -->
+   <p><a name="doc_002dsighup_005fdumps_005foctave_005fcore"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>sighup_dumps_octave_core</b> ()<var><a name="index-sighup_005fdumps_005foctave_005fcore-757"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>sighup_dumps_octave_core</b> (<var>new_val</var>)<var><a name="index-sighup_005fdumps_005foctave_005fcore-758"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it receives
+a hangup signal. 
+</p></blockquote></div>
+
+<!-- sighandlers.cc -->
+   <p><a name="doc_002dsigterm_005fdumps_005foctave_005fcore"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>sigterm_dumps_octave_core</b> ()<var><a name="index-sigterm_005fdumps_005foctave_005fcore-759"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>sigterm_dumps_octave_core</b> (<var>new_val</var>)<var><a name="index-sigterm_005fdumps_005foctave_005fcore-760"></a></var><br>
+<blockquote><p>Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it receives
+a terminate signal. 
+</p></blockquote></div>
+
+<!-- load-save.cc -->
+   <p><a name="doc_002doctave_005fcore_005ffile_005foptions"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>octave_core_file_options</b> ()<var><a name="index-octave_005fcore_005ffile_005foptions-761"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>octave_core_file_options</b> (<var>new_val</var>)<var><a name="index-octave_005fcore_005ffile_005foptions-762"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the options used for
+saving the workspace data if Octave aborts.  The value of
+<code>octave_core_file_options</code> should follow the same format as the
+options for the <code>save</code> function.  The default value is Octave's binary
+format. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcrash_005fdumps_005foctave_005fcore.html#doc_002dcrash_005fdumps_005foctave_005fcore">crash_dumps_octave_core</a>, <a href="doc_002doctave_005fcore_005ffile_005fname.html#doc_002doctave_005fcore_005ffile_005fname">octave_core_file_name</a>, <a href="doc_002doctave_005fcore_005ffile_005flimit.html#doc_002doctave_005fcore_005ffile_005flimit">octave_core_file_limit</a>. 
+</p></blockquote></div>
+
+<!-- load-save.cc -->
+   <p><a name="doc_002doctave_005fcore_005ffile_005flimit"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>octave_core_file_limit</b> ()<var><a name="index-octave_005fcore_005ffile_005flimit-763"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>octave_core_file_limit</b> (<var>new_val</var>)<var><a name="index-octave_005fcore_005ffile_005flimit-764"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the maximum amount
+of memory (in kilobytes) of the top-level workspace that Octave will
+attempt to save when writing data to the crash dump file (the name of
+the file is specified by <var>octave_core_file_name</var>).  If
+<var>octave_core_file_options</var> flags specify a binary format,
+then <var>octave_core_file_limit</var> will be approximately the maximum
+size of the file.  If a text file format is used, then the file could
+be much larger than the limit.  The default value is -1 (unlimited)
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcrash_005fdumps_005foctave_005fcore.html#doc_002dcrash_005fdumps_005foctave_005fcore">crash_dumps_octave_core</a>, <a href="doc_002doctave_005fcore_005ffile_005fname.html#doc_002doctave_005fcore_005ffile_005fname">octave_core_file_name</a>, <a href="doc_002doctave_005fcore_005ffile_005foptions.html#doc_002doctave_005fcore_005ffile_005foptions">octave_core_file_options</a>. 
+</p></blockquote></div>
+
+<!-- load-save.cc -->
+   <p><a name="doc_002doctave_005fcore_005ffile_005fname"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>octave_core_file_name</b> ()<var><a name="index-octave_005fcore_005ffile_005fname-765"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>octave_core_file_name</b> (<var>new_val</var>)<var><a name="index-octave_005fcore_005ffile_005fname-766"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the name of the file
+used for saving data from the top-level workspace if Octave aborts. 
+The default value is <code>"octave-core"</code>
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcrash_005fdumps_005foctave_005fcore.html#doc_002dcrash_005fdumps_005foctave_005fcore">crash_dumps_octave_core</a>, <a href="doc_002doctave_005fcore_005ffile_005fname.html#doc_002doctave_005fcore_005ffile_005fname">octave_core_file_name</a>, <a href="doc_002doctave_005fcore_005ffile_005foptions.html#doc_002doctave_005fcore_005ffile_005foptions">octave_core_file_options</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Scatter-group.html b/doc/interpreter/HTML/Scatter-group.html
new file mode 100644
index 0000000..5674d7c
--- /dev/null
+++ b/doc/interpreter/HTML/Scatter-group.html
@@ -0,0 +1,60 @@
+<html lang="en">
+<head>
+<title>Scatter group - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Quiver-group.html#Quiver-group" title="Quiver group">
+<link rel="next" href="Stair-group.html#Stair-group" title="Stair group">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Scatter-group"></a>
+Next: <a rel="next" accesskey="n" href="Stair-group.html#Stair-group">Stair group</a>,
+Previous: <a rel="previous" accesskey="p" href="Quiver-group.html#Quiver-group">Quiver group</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.8 Scatter group</h5>
+
+<p><a name="index-group-objects-1244"></a><a name="index-scatter-group-1245"></a>
+Scatter series objects are created by the <code>scatter</code> or <code>scatter3</code>
+functions.  A single hggroup element contains as many children as there are
+points in the scatter plot, with each child representing one of the points. 
+The properties of the stem series are
+
+     <dl>
+<dt><code>linewidth</code><dd>The line width of the line objects of the points.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dd>The line and fill color of the markers of the points.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>The original x, y and z data of the stems.
+
+     <br><dt><code>cdata</code><dd>The color data for the points of the plot.  Each point can have a separate
+color, or a unique color can be specified.
+
+     <br><dt><code>sizedata</code><dd>The size data for the points of the plot.  Each point can its own size or a
+unique size can be specified.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>zdatasource</code><dt><code>cdatasource</code><dt><code>sizedatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Script-Files.html b/doc/interpreter/HTML/Script-Files.html
new file mode 100644
index 0000000..ebbcc58
--- /dev/null
+++ b/doc/interpreter/HTML/Script-Files.html
@@ -0,0 +1,134 @@
+<html lang="en">
+<head>
+<title>Script Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="next" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions" title="Function Handles Inline Functions and Anonymous Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Script-Files"></a>
+Next: <a rel="next" accesskey="n" href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Function-Files.html#Function-Files">Function Files</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.8 Script Files</h3>
+
+<p>A script file is a file containing (almost) any sequence of Octave
+commands.  It is read and evaluated just as if you had typed each
+command at the Octave prompt, and provides a convenient way to perform a
+sequence of commands that do not logically belong inside a function.
+
+   <p>Unlike a function file, a script file must <em>not</em> begin with the
+keyword <code>function</code>.  If it does, Octave will assume that it is a
+function file, and that it defines a single function that should be
+evaluated as soon as it is defined.
+
+   <p>A script file also differs from a function file in that the variables
+named in a script file are not local variables, but are in the same
+scope as the other variables that are visible on the command line.
+
+   <p>Even though a script file may not begin with the <code>function</code>
+keyword, it is possible to define more than one function in a single
+script file and load (but not execute) all of them at once.  To do
+this, the first token in the file (ignoring comments and other white
+space) must be something other than <code>function</code>.  If you have no
+other statements to evaluate, you can use a statement that has no
+effect, like this:
+
+<pre class="example">     # Prevent Octave from thinking that this
+     # is a function file:
+     
+     1;
+     
+     # Define function one:
+     
+     function one ()
+       ...
+</pre>
+   <p>To have Octave read and compile these functions into an internal form,
+you need to make sure that the file is in Octave's load path
+(accessible through the <code>path</code> function), then simply type the
+base name of the file that contains the commands.  (Octave uses the
+same rules to search for script files as it does to search for
+function files.)
+
+   <p>If the first token in a file (ignoring comments) is <code>function</code>,
+Octave will compile the function and try to execute it, printing a
+message warning about any non-whitespace characters that appear after
+the function definition.
+
+   <p>Note that Octave does not try to look up the definition of any identifier
+until it needs to evaluate it.  This means that Octave will compile the
+following statements if they appear in a script file, or are typed at
+the command line,
+
+<pre class="example">     # not a function file:
+     1;
+     function foo ()
+       do_something ();
+     endfunction
+     function do_something ()
+       do_something_else ();
+     endfunction
+</pre>
+   <p class="noindent">even though the function <code>do_something</code> is not defined before it is
+referenced in the function <code>foo</code>.  This is not an error because
+Octave does not need to resolve all symbols that are referenced by a
+function until the function is actually evaluated.
+
+   <p>Since Octave doesn't look for definitions until they are needed, the
+following code will always print ‘<samp><span class="samp">bar = 3</span></samp>’ whether it is typed
+directly on the command line, read from a script file, or is part of a
+function body, even if there is a function or script file called
+<samp><span class="file">bar.m</span></samp> in Octave's path.
+
+<pre class="example">     eval ("bar = 3");
+     bar
+</pre>
+   <p>Code like this appearing within a function body could fool Octave if
+definitions were resolved as the function was being compiled.  It would
+be virtually impossible to make Octave clever enough to evaluate this
+code in a consistent fashion.  The parser would have to be able to
+perform the call to <code>eval</code> at compile time, and that would be
+impossible unless all the references in the string to be evaluated could
+also be resolved, and requiring that would be too restrictive (the
+string might come from user input, or depend on things that are not
+known until the function is evaluated).
+
+   <p>Although Octave normally executes commands from script files that have
+the name <samp><var>file</var><span class="file">.m</span></samp>, you can use the function <code>source</code> to
+execute commands from any file.
+
+<!-- parse.cc -->
+   <p><a name="doc_002dsource"></a>
+
+<div class="defun">
+— Built-in Function:  <b>source</b> (<var>file</var>)<var><a name="index-source-642"></a></var><br>
+<blockquote><p>Parse and execute the contents of <var>file</var>.  This is equivalent to
+executing commands from a script file, but without requiring the file to
+be named <samp><var>file</var><span class="file">.m</span></samp>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Searching-Properties.html b/doc/interpreter/HTML/Searching-Properties.html
new file mode 100644
index 0000000..a52f752
--- /dev/null
+++ b/doc/interpreter/HTML/Searching-Properties.html
@@ -0,0 +1,102 @@
+<html lang="en">
+<head>
+<title>Searching Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Surface-Properties.html#Surface-Properties" title="Surface Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Searching-Properties"></a>
+Previous: <a rel="previous" accesskey="p" href="Surface-Properties.html#Surface-Properties">Surface Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.9 Searching Properties</h5>
+
+<!-- ./plot/findobj.m -->
+<p><a name="doc_002dfindobj"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>findobj</b> ()<var><a name="index-findobj-1197"></a></var><br>
+— Function File: <var>h</var> = <b>findobj</b> (<var>prop_name, prop_value</var>)<var><a name="index-findobj-1198"></a></var><br>
+— Function File: <var>h</var> = <b>findobj</b> (<var>'-property', prop_name</var>)<var><a name="index-findobj-1199"></a></var><br>
+— Function File: <var>h</var> = <b>findobj</b> (<var>'-regexp', prop_name, pattern</var>)<var><a name="index-findobj-1200"></a></var><br>
+— Function File: <var>h</var> = <b>findobj</b> (<var>'flat', <small class="dots">...</small></var>)<var><a name="index-findobj-1201"></a></var><br>
+— Function File: <var>h</var> = <b>findobj</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-findobj-1202"></a></var><br>
+— Function File: <var>h</var> = <b>findobj</b> (<var>h, '-depth', d, <small class="dots">...</small></var>)<var><a name="index-findobj-1203"></a></var><br>
+<blockquote><p>Find object with specified property values.  The simplest form is
+
+     <pre class="example">          findobj (<var>prop_name</var>, <var>prop_Value</var>)
+</pre>
+        <p class="noindent">which returns all of the handles to the objects with the name
+<var>prop_name</var> and the name <var>prop_Value</var>.  The search can be limited
+to a particular object or set of objects and their descendants by
+passing a handle or set of handles <var>h</var> as the first argument to
+<code>findobj</code>.
+
+        <p>The depth of hierarchy of objects to which to search to can be limited
+with the '-depth' argument.  To limit the number depth of the hierarchy
+to search to <var>d</var> generations of children, and example is
+
+     <pre class="example">          findobj (<var>h</var>, '-depth', <var>d</var>, <var>prop_Name</var>, <var>prop_Value</var>)
+</pre>
+        <p>Specifying a depth <var>d</var> of 0, limits the search to the set of object
+passed in <var>h</var>.  A depth <var>d</var> of 0 is equivalent to the '-flat'
+argument.
+
+        <p>A specified logical operator may be applied to the pairs of <var>prop_Name</var>
+and <var>prop_Value</var>.  The supported logical operators are '-and', '-or',
+'-xor', '-not'.
+
+        <p>The objects may also be matched by comparing a regular expression to the
+property values, where property values that match <code>regexp
+(</code><var>prop_Value</var><code>, </code><var>pattern</var><code>)</code> are returned.  Finally, objects may be
+matched by property name only, using the '-property' option. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dset.html#doc_002dset">set</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/findall.m -->
+   <p><a name="doc_002dfindall"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>findall</b> ()<var><a name="index-findall-1204"></a></var><br>
+— Function File: <var>h</var> = <b>findall</b> (<var>prop_name, prop_value</var>)<var><a name="index-findall-1205"></a></var><br>
+— Function File: <var>h</var> = <b>findall</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-findall-1206"></a></var><br>
+— Function File: <var>h</var> = <b>findall</b> (<var>h, "-depth", d, <small class="dots">...</small></var>)<var><a name="index-findall-1207"></a></var><br>
+<blockquote><p>Find object with specified property values including hidden handles.
+
+        <p>This function performs the same function as <code>findobj</code>, but it
+includes hidden objects in its search.  For full documentation, see
+<code>findobj</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dset.html#doc_002dset">set</a>, <a href="doc_002dfindobj.html#doc_002dfindobj">findobj</a>, <a href="doc_002dallchild.html#doc_002dallchild">allchild</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sending-Patches.html b/doc/interpreter/HTML/Sending-Patches.html
new file mode 100644
index 0000000..099aac0
--- /dev/null
+++ b/doc/interpreter/HTML/Sending-Patches.html
@@ -0,0 +1,94 @@
+<html lang="en">
+<head>
+<title>Sending Patches - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="prev" href="Bug-Reporting.html#Bug-Reporting" title="Bug Reporting">
+<link rel="next" href="Service.html#Service" title="Service">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sending-Patches"></a>
+Next: <a rel="next" accesskey="n" href="Service.html#Service">Service</a>,
+Previous: <a rel="previous" accesskey="p" href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.6 Sending Patches for Octave</h3>
+
+<p><a name="index-improving-Octave-2550"></a><a name="index-diffs_002c-submitting-2551"></a><a name="index-patches_002c-submitting-2552"></a><a name="index-submitting-diffs-2553"></a><a name="index-submitting-patches-2554"></a>
+If you would like to write bug fixes or improvements for Octave, that is
+very helpful.  When you send your changes, please follow these
+guidelines to avoid causing extra work for us in studying the patches.
+
+   <p>If you don't follow these guidelines, your information might still be
+useful, but using it will take extra work.  Maintaining Octave is a lot
+of work in the best of circumstances, and we can't keep up unless you do
+your best to help.
+
+     <ul>
+<li>Send an explanation with your changes of what problem they fix or what
+improvement they bring about.  For a bug fix, just include a copy of the
+bug report, and explain why the change fixes the bug.
+
+     <li>Always include a proper bug report for the problem you think you have
+fixed.  We need to convince ourselves that the change is right before
+installing it.  Even if it is right, we might have trouble judging it if
+we don't have a way to reproduce the problem.
+
+     <li>Include all the comments that are appropriate to help people reading the
+source in the future understand why this change was needed.
+
+     <li>Don't mix together changes made for different reasons. 
+Send them <em>individually</em>.
+
+     <p>If you make two changes for separate reasons, then we might not want to
+install them both.  We might want to install just one.
+
+     <li>Use ‘<samp><span class="samp">diff -c</span></samp>’ to make your diffs.  Diffs without context are hard
+for us to install reliably.  More than that, they make it hard for us to
+study the diffs to decide whether we want to install them.  Unidiff
+format is better than contextless diffs, but not as easy to read as
+‘<samp><span class="samp">-c</span></samp>’ format.
+
+     <p>If you have GNU diff, use ‘<samp><span class="samp">diff -cp</span></samp>’, which shows the name of the
+function that each change occurs in.
+
+     <li>Write the change log entries for your changes.
+
+     <p>Read the <samp><span class="file">ChangeLog</span></samp> file to see what sorts of information to put
+in, and to learn the style that we use.  The purpose of the change log
+is to show people where to find what was changed.  So you need to be
+specific about what functions you changed; in large functions, it's
+often helpful to indicate where within the function the change was made.
+
+     <p>On the other hand, once you have shown people where to find the change,
+you need not explain its purpose.  Thus, if you add a new function, all
+you need to say about it is that it is new.  If you feel that the
+purpose needs explaining, it probably does—but the explanation will be
+much more useful if you put it in comments in the code.
+
+     <p>If you would like your name to appear in the header line for who made
+the change, send us the header line. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Service.html b/doc/interpreter/HTML/Service.html
new file mode 100644
index 0000000..3b5dcf0
--- /dev/null
+++ b/doc/interpreter/HTML/Service.html
@@ -0,0 +1,66 @@
+<html lang="en">
+<head>
+<title>Service - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Trouble.html#Trouble" title="Trouble">
+<link rel="prev" href="Sending-Patches.html#Sending-Patches" title="Sending Patches">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Service"></a>
+Previous: <a rel="previous" accesskey="p" href="Sending-Patches.html#Sending-Patches">Sending Patches</a>,
+Up: <a rel="up" accesskey="u" href="Trouble.html#Trouble">Trouble</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">E.7 How To Get Help with Octave</h3>
+
+<p><a name="index-help_002c-where-to-find-2555"></a>
+The mailing list <a href="mailto:help at octave.org">help at octave.org</a> exists for the discussion of
+matters related to using and installing Octave.  If would like to join
+the discussion, please send a short note to
+<a href="mailto:help<strong>-request</strong>@octave.org">help<strong>-request</strong>@octave.org</a>.
+
+   <p><strong>Please do not</strong> send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+   <p>If you think you have found a bug in the installation procedure,
+however, you should send a complete bug report for the problem to
+<a href="mailto:bug at octave.org">bug at octave.org</a>.  See <a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a>, for
+information that will help you to submit a useful report.
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+<!-- The text of this file appears in the file INSTALL in the Octave -->
+<!-- distribution, as well as in the Octave manual. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Set-Operations.html b/doc/interpreter/HTML/Set-Operations.html
new file mode 100644
index 0000000..f1a298c
--- /dev/null
+++ b/doc/interpreter/HTML/Set-Operations.html
@@ -0,0 +1,214 @@
+<html lang="en">
+<head>
+<title>Set Operations - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sets.html#Sets" title="Sets">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Set-Operations"></a>
+Up: <a rel="up" accesskey="u" href="Sets.html#Sets">Sets</a>
+<hr>
+</div>
+
+<h3 class="section">26.1 Set Operations</h3>
+
+<p>Octave supports the basic set operations.  That is, Octave can compute
+the union, intersection, complement, and difference of two sets. 
+Octave also supports the <em>Exclusive Or</em> set operation, and
+membership determination.  The functions for set operations all work in
+pretty much the same way.  As an example, assume that <code>x</code> and
+<code>y</code> contains two sets, then
+
+<pre class="example">     union(x, y)
+</pre>
+   <p class="noindent">computes the union of the two sets.
+
+<!-- ./set/ismember.m -->
+   <p><a name="doc_002dismember"></a>
+
+<div class="defun">
+— Function File: [<var>tf</var> = <b>ismember</b> (<var>A, S</var>)<var><a name="index-ismember-2006"></a></var><br>
+— Function File: [<var>tf</var>, <var>S_idx</var>] = <b>ismember</b> (<var>A, S</var>)<var><a name="index-ismember-2007"></a></var><br>
+— Function File: [<var>tf</var>, <var>S_idx</var>] = <b>ismember</b> (<var>A, S, "rows"</var>)<var><a name="index-ismember-2008"></a></var><br>
+<blockquote><p>Return a matrix <var>tf</var> with the same shape as <var>A</var> which has a 1 if
+<code>A(i,j)</code> is in <var>S</var> and 0 if it is not.  If a second output argument
+is requested, the index into <var>S</var> of each of the matching elements is
+also returned.
+
+     <pre class="example">          a = [3, 10, 1];
+          s = [0:9];
+          [tf, s_idx] = ismember (a, s);
+                tf = [1, 0, 1]
+                s_idx = [4, 0, 2]
+</pre>
+        <p>The inputs, <var>A</var> and <var>S</var>, may also be cell arrays.
+
+     <pre class="example">          a = {'abc'};
+          s = {'abc', 'def'};
+          [tf, s_idx] = ismember (a, s);
+                tf = [1, 0]
+                s_idx = [1, 0]
+</pre>
+        <p>With the optional third argument <code>"rows"</code>, and matrices
+<var>A</var> and <var>S</var> with the same number of columns, compare rows in
+<var>A</var> with the rows in <var>S</var>.
+
+     <pre class="example">          a = [1:3; 5:7; 4:6];
+          s = [0:2; 1:3; 2:4; 3:5; 4:6];
+          [tf, s_idx] = ismember(a, s, 'rows');
+                tf = logical ([1; 0; 1])
+                s_idx = [2; 0; 5];
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunique.html#doc_002dunique">unique</a>, <a href="doc_002dunion.html#doc_002dunion">union</a>, <a href="doc_002dintersect.html#doc_002dintersect">intersect</a>, <a href="doc_002dsetxor.html#doc_002dsetxor">setxor</a>, <a href="doc_002dsetdiff.html#doc_002dsetdiff">setdiff</a>. 
+</p></blockquote></div>
+
+<!-- ./set/union.m -->
+   <p><a name="doc_002dunion"></a>
+
+<div class="defun">
+— Function File:  <b>union</b> (<var>a, b</var>)<var><a name="index-union-2009"></a></var><br>
+— Function File:  <b>union</b> (<var>a, b, "rows"</var>)<var><a name="index-union-2010"></a></var><br>
+<blockquote><p>Return the set of elements that are in either of the sets <var>a</var> and
+<var>b</var>.  For example,
+
+     <pre class="example">          union ([1, 2, 4], [2, 3, 5])
+                [1, 2, 3, 4, 5]
+</pre>
+        <p>If the optional third input argument is the string "rows" each row of
+the matrices <var>a</var> and <var>b</var> will be considered an element of sets. 
+For example,
+     <pre class="example">          union([1, 2; 2, 3], [1, 2; 3, 4], "rows")
+                 1   2
+              2   3
+              3   4
+</pre>
+        — Function File: [<var>c</var>, <var>ia</var>, <var>ib</var>] = <b>union</b> (<var>a, b</var>)<var><a name="index-union-2011"></a></var><br>
+<blockquote>
+        <p>Return index vectors <var>ia</var> and <var>ib</var> such that <code>a == c(ia)</code> and
+<code>b == c(ib)</code>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dintersect.html#doc_002dintersect">intersect</a>, <a href="doc_002dcomplement.html#doc_002dcomplement">complement</a>, <a href="doc_002dunique.html#doc_002dunique">unique</a>. 
+</p></blockquote></div>
+
+<!-- ./set/intersect.m -->
+   <p><a name="doc_002dintersect"></a>
+
+<div class="defun">
+— Function File:  <b>intersect</b> (<var>a, b</var>)<var><a name="index-intersect-2012"></a></var><br>
+— Function File: [<var>c</var>, <var>ia</var>, <var>ib</var>] = <b>intersect</b> (<var>a, b</var>)<var><a name="index-intersect-2013"></a></var><br>
+<blockquote>
+        <p>Return the elements in both <var>a</var> and <var>b</var>, sorted in ascending
+order.  If <var>a</var> and <var>b</var> are both column vectors return a column
+vector, otherwise return a row vector.
+
+        <p>Return index vectors <var>ia</var> and <var>ib</var> such that <code>a(ia)==c</code> and
+<code>b(ib)==c</code>.
+
+        </blockquote></div>
+   <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+<p class="noindent"><strong>See also:</strong> <a href="doc_002dunique.html#doc_002dunique">unique</a>, <a href="doc_002dunion.html#doc_002dunion">union</a>, <a href="doc_002dsetxor.html#doc_002dsetxor">setxor</a>, <a href="doc_002dsetdiff.html#doc_002dsetdiff">setdiff</a>, <a href="doc_002dismember.html#doc_002dismember">ismember</a>.
+
+<!-- ./set/complement.m -->
+   <p><a name="doc_002dcomplement"></a>
+
+<div class="defun">
+— Function File:  <b>complement</b> (<var>x, y</var>)<var><a name="index-complement-2014"></a></var><br>
+<blockquote><p>Return the elements of set <var>y</var> that are not in set <var>x</var>.  For
+example,
+
+     <pre class="example">          complement ([ 1, 2, 3 ], [ 2, 3, 5 ])
+                5
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunion.html#doc_002dunion">union</a>, <a href="doc_002dintersect.html#doc_002dintersect">intersect</a>, <a href="doc_002dunique.html#doc_002dunique">unique</a>. 
+</p></blockquote></div>
+
+<!-- ./set/setdiff.m -->
+   <p><a name="doc_002dsetdiff"></a>
+
+<div class="defun">
+— Function File:  <b>setdiff</b> (<var>a, b</var>)<var><a name="index-setdiff-2015"></a></var><br>
+— Function File:  <b>setdiff</b> (<var>a, b, "rows"</var>)<var><a name="index-setdiff-2016"></a></var><br>
+— Function File: [<var>c</var>, <var>i</var>] = <b>setdiff</b> (<var>a, b</var>)<var><a name="index-setdiff-2017"></a></var><br>
+<blockquote><p>Return the elements in <var>a</var> that are not in <var>b</var>, sorted in
+ascending order.  If <var>a</var> and <var>b</var> are both column vectors
+return a column vector, otherwise return a row vector.
+
+        <p>Given the optional third argument ‘<samp><span class="samp">"rows"</span></samp>’, return the rows in
+<var>a</var> that are not in <var>b</var>, sorted in ascending order by rows.
+
+        <p>If requested, return <var>i</var> such that <code>c = a(i)</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunique.html#doc_002dunique">unique</a>, <a href="doc_002dunion.html#doc_002dunion">union</a>, <a href="doc_002dintersect.html#doc_002dintersect">intersect</a>, <a href="doc_002dsetxor.html#doc_002dsetxor">setxor</a>, <a href="doc_002dismember.html#doc_002dismember">ismember</a>. 
+</p></blockquote></div>
+
+<!-- ./set/setxor.m -->
+   <p><a name="doc_002dsetxor"></a>
+
+<div class="defun">
+— Function File:  <b>setxor</b> (<var>a, b</var>)<var><a name="index-setxor-2018"></a></var><br>
+— Function File:  <b>setxor</b> (<var>a, b, 'rows'</var>)<var><a name="index-setxor-2019"></a></var><br>
+<blockquote>
+        <p>Return the elements exclusive to <var>a</var> or <var>b</var>, sorted in ascending
+order.  If <var>a</var> and <var>b</var> are both column vectors return a column
+vector, otherwise return a row vector.
+
+   — Function File: [<var>c</var>, <var>ia</var>, <var>ib</var>] = <b>setxor</b> (<var>a, b</var>)<var><a name="index-setxor-2020"></a></var><br>
+<blockquote>
+        <p>Return index vectors <var>ia</var> and <var>ib</var> such that <code>a == c(ia)</code> and
+<code>b == c(ib)</code>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunique.html#doc_002dunique">unique</a>, <a href="doc_002dunion.html#doc_002dunion">union</a>, <a href="doc_002dintersect.html#doc_002dintersect">intersect</a>, <a href="doc_002dsetdiff.html#doc_002dsetdiff">setdiff</a>, <a href="doc_002dismember.html#doc_002dismember">ismember</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sets.html b/doc/interpreter/HTML/Sets.html
new file mode 100644
index 0000000..6e9f20f
--- /dev/null
+++ b/doc/interpreter/HTML/Sets.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>Sets - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Statistics.html#Statistics" title="Statistics">
+<link rel="next" href="Polynomial-Manipulations.html#Polynomial-Manipulations" title="Polynomial Manipulations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sets"></a>
+Next: <a rel="next" accesskey="n" href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>,
+Previous: <a rel="previous" accesskey="p" href="Statistics.html#Statistics">Statistics</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">26 Sets</h2>
+
+<p>Octave has a limited number of functions for managing sets of data, where a
+set is defined as a collection of unique elements.  In Octave a set is
+represented as a vector of numbers.
+
+<!-- ./set/unique.m -->
+   <p><a name="doc_002dunique"></a>
+
+<div class="defun">
+— Function File:  <b>unique</b> (<var>x</var>)<var><a name="index-unique-2001"></a></var><br>
+— Function File:  <b>unique</b> (<var>x, "rows"</var>)<var><a name="index-unique-2002"></a></var><br>
+— Function File:  <b>unique</b> (<var><small class="dots">...</small>, "first"</var>)<var><a name="index-unique-2003"></a></var><br>
+— Function File:  <b>unique</b> (<var><small class="dots">...</small>, "last"</var>)<var><a name="index-unique-2004"></a></var><br>
+— Function File: [<var>y</var>, <var>i</var>, <var>j</var>] = <b>unique</b> (<var><small class="dots">...</small></var>)<var><a name="index-unique-2005"></a></var><br>
+<blockquote><p>Return the unique elements of <var>x</var>, sorted in ascending order. 
+If <var>x</var> is a row vector, return a row vector, but if <var>x</var>
+is a column vector or a matrix return a column vector.
+
+        <p>If the optional argument <code>"rows"</code> is supplied, return the unique
+rows of <var>x</var>, sorted in ascending order.
+
+        <p>If requested, return index vectors <var>i</var> and <var>j</var> such that
+<code>x(i)==y</code> and <code>y(j)==x</code>.
+
+        <p>Additionally, one of <code>"first"</code> or <code>"last"</code> may be given as
+an argument.  If <code>"last"</code> is specified, return the highest
+possible indices in <var>i</var>, otherwise, if <code>"first"</code> is
+specified, return the lowest.  The default is <code>"last"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dunion.html#doc_002dunion">union</a>, <a href="doc_002dintersect.html#doc_002dintersect">intersect</a>, <a href="doc_002dsetdiff.html#doc_002dsetdiff">setdiff</a>, <a href="doc_002dsetxor.html#doc_002dsetxor">setxor</a>, <a href="doc_002dismember.html#doc_002dismember">ismember</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Set-Operations.html#Set-Operations">Set Operations</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Short_002dcircuit-Boolean-Operators.html b/doc/interpreter/HTML/Short_002dcircuit-Boolean-Operators.html
new file mode 100644
index 0000000..dc2d525
--- /dev/null
+++ b/doc/interpreter/HTML/Short_002dcircuit-Boolean-Operators.html
@@ -0,0 +1,107 @@
+<html lang="en">
+<head>
+<title>Short-circuit Boolean Operators - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Boolean-Expressions.html#Boolean-Expressions" title="Boolean Expressions">
+<link rel="prev" href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators" title="Element-by-element Boolean Operators">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Short-circuit-Boolean-Operators"></a>
+<a name="Short_002dcircuit-Boolean-Operators"></a>
+Previous: <a rel="previous" accesskey="p" href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a>,
+Up: <a rel="up" accesskey="u" href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a>
+<hr>
+</div>
+
+<h4 class="subsection">8.5.2 Short-circuit Boolean Operators</h4>
+
+<p><a name="index-short_002dcircuit-evaluation-523"></a>
+Combined with the implicit conversion to scalar values in <code>if</code> and
+<code>while</code> conditions, Octave's element-by-element boolean operators
+are often sufficient for performing most logical operations.  However,
+it is sometimes desirable to stop evaluating a boolean expression as
+soon as the overall truth value can be determined.  Octave's
+<dfn>short-circuit</dfn> boolean operators work this way.
+
+     <dl>
+<dt><var>boolean1</var><code> && </code><var>boolean2</var><dd><a name="index-g_t_0026_0026-524"></a>The expression <var>boolean1</var> is evaluated and converted to a scalar
+using the equivalent of the operation <code>all (</code><var>boolean1</var><code>(:))</code>. 
+If it is false, the result of the overall expression is 0.  If it is
+true, the expression <var>boolean2</var> is evaluated and converted to a
+scalar using the equivalent of the operation <code>all
+(</code><var>boolean1</var><code>(:))</code>.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+     <p><strong>Warning:</strong> there is one exception to the rule of evaluating
+<code>all (</code><var>boolean1</var><code>(:))</code>, which is when <code>boolean1</code> is the
+empty matrix.  The truth value of an empty matrix is always <code>false</code>
+so <code>[] && true</code> evaluates to <code>false</code> even though
+<code>all ([])</code> is <code>true</code>.
+
+     <br><dt><var>boolean1</var><code> || </code><var>boolean2</var><dd><a name="index-g_t_007c_007c-525"></a>The expression <var>boolean1</var> is evaluated and converted to a scalar
+using the equivalent of the operation <code>all (</code><var>boolean1</var><code>(:))</code>. 
+If it is true, the result of the overall expression is 1.  If it is
+false, the expression <var>boolean2</var> is evaluated and converted to a
+scalar using the equivalent of the operation <code>all
+(</code><var>boolean1</var><code>(:))</code>.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+     <p><strong>Warning:</strong> the truth value of an empty matrix is always <code>false</code>,
+see the previous list item for details. 
+</dl>
+
+   <p>The fact that both operands may not be evaluated before determining the
+overall truth value of the expression can be important.  For example, in
+the expression
+
+<pre class="example">     a && b++
+</pre>
+   <p class="noindent">the value of the variable <var>b</var> is only incremented if the variable
+<var>a</var> is nonzero.
+
+   <p>This can be used to write somewhat more concise code.  For example, it
+is possible write
+
+<pre class="example">     function f (a, b, c)
+       if (nargin > 2 && ischar (c))
+         ...
+</pre>
+   <p class="noindent">instead of having to use two <code>if</code> statements to avoid attempting to
+evaluate an argument that doesn't exist.  For example, without the
+short-circuit feature, it would be necessary to write
+
+<pre class="example">     function f (a, b, c)
+       if (nargin > 2)
+         if (ischar (c))
+           ...
+</pre>
+   <p class="noindent">Writing
+
+<pre class="example">     function f (a, b, c)
+       if (nargin > 2 & ischar (c))
+         ...
+</pre>
+   <p class="noindent">would result in an error if <code>f</code> were called with one or two
+arguments because Octave would be forced to try to evaluate both of the
+operands for the operator ‘<samp><span class="samp">&</span></samp>’.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Signal-Processing.html b/doc/interpreter/HTML/Signal-Processing.html
new file mode 100644
index 0000000..8518e82
--- /dev/null
+++ b/doc/interpreter/HTML/Signal-Processing.html
@@ -0,0 +1,944 @@
+<html lang="en">
+<head>
+<title>Signal Processing - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Geometry.html#Geometry" title="Geometry">
+<link rel="next" href="Image-Processing.html#Image-Processing" title="Image Processing">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Signal-Processing"></a>
+Next: <a rel="next" accesskey="n" href="Image-Processing.html#Image-Processing">Image Processing</a>,
+Previous: <a rel="previous" accesskey="p" href="Geometry.html#Geometry">Geometry</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">30 Signal Processing</h2>
+
+<p>This chapter describes the signal processing and fast Fourier
+transform functions available in Octave.  Fast Fourier transforms are
+computed with the <span class="sc">fftw</span> or <span class="sc">fftpack</span> libraries depending on how
+Octave is built.
+
+<!-- ./signal/detrend.m -->
+   <p><a name="doc_002ddetrend"></a>
+
+<div class="defun">
+— Function File:  <b>detrend</b> (<var>x, p</var>)<var><a name="index-detrend-2122"></a></var><br>
+<blockquote><p>If <var>x</var> is a vector, <code>detrend (</code><var>x</var><code>, </code><var>p</var><code>)</code> removes the
+best fit of a polynomial of order <var>p</var> from the data <var>x</var>.
+
+        <p>If <var>x</var> is a matrix, <code>detrend (</code><var>x</var><code>, </code><var>p</var><code>)</code> does the same
+for each column in <var>x</var>.
+
+        <p>The second argument is optional.  If it is not specified, a value of 1
+is assumed.  This corresponds to removing a linear trend. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/fft.cc -->
+   <p><a name="doc_002dfft"></a>
+
+<div class="defun">
+— Loadable Function:  <b>fft</b> (<var>a, n, dim</var>)<var><a name="index-fft-2123"></a></var><br>
+<blockquote><p>Compute the FFT of <var>a</var> using subroutines from
+<span class="sc">fftw</span>.  The FFT is calculated along the first non-singleton dimension of the
+array.  Thus if <var>a</var> is a matrix, <code>fft (</code><var>a</var><code>)</code> computes the
+FFT for each column of <var>a</var>.
+
+        <p>If called with two arguments, <var>n</var> is expected to be an integer
+specifying the number of elements of <var>a</var> to use, or an empty
+matrix to specify that its value should be ignored.  If <var>n</var> is
+larger than the dimension along which the FFT is calculated, then
+<var>a</var> is resized and padded with zeros.  Otherwise, if <var>n</var> is
+smaller than the dimension along which the FFT is calculated, then
+<var>a</var> is truncated.
+
+        <p>If called with three arguments, <var>dim</var> is an integer specifying the
+dimension of the matrix along which the FFT is performed
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002difft.html#doc_002difft">ifft</a>, <a href="doc_002dfft2.html#doc_002dfft2">fft2</a>, <a href="doc_002dfftn.html#doc_002dfftn">fftn</a>, <a href="doc_002dfftw.html#doc_002dfftw">fftw</a>. 
+</p></blockquote></div>
+
+   <p>Octave uses the <span class="sc">fftw</span> libraries to perform FFT computations.  When Octave
+starts up and initializes the <span class="sc">fftw</span> libraries, they read a system wide
+file (on a Unix system, it is typically <samp><span class="file">/etc/fftw/wisdom</span></samp>) that
+contains information useful to speed up FFT computations.  This
+information is called the <em>wisdom</em>.  The system-wide file allows
+wisdom to be shared between all applications using the <span class="sc">fftw</span> libraries.
+
+   <p>Use the <code>fftw</code> function to generate and save wisdom.  Using the
+utilities provided together with the <span class="sc">fftw</span> libraries
+(<samp><span class="command">fftw-wisdom</span></samp> on Unix systems), you can even add wisdom
+generated by Octave to the system-wide wisdom file.
+
+<!-- ./DLD-FUNCTIONS/fftw.cc -->
+   <p><a name="doc_002dfftw"></a>
+
+<div class="defun">
+— Loadable Function: <var>method</var> = <b>fftw</b> (<var>'planner'</var>)<var><a name="index-fftw-2124"></a></var><br>
+— Loadable Function:  <b>fftw</b> (<var>'planner', method</var>)<var><a name="index-fftw-2125"></a></var><br>
+— Loadable Function: <var>wisdom</var> = <b>fftw</b> (<var>'dwisdom'</var>)<var><a name="index-fftw-2126"></a></var><br>
+— Loadable Function: <var>wisdom</var> = <b>fftw</b> (<var>'dwisdom', wisdom</var>)<var><a name="index-fftw-2127"></a></var><br>
+<blockquote>
+        <p>Manage <span class="sc">fftw</span> wisdom data.  Wisdom data can be used to significantly
+accelerate the calculation of the FFTs but implies an initial cost
+in its calculation.  When the <span class="sc">fftw</span> libraries are initialized, they read
+a system wide wisdom file (typically in <samp><span class="file">/etc/fftw/wisdom</span></samp>), allowing wisdom
+to be shared between applications other than Octave.  Alternatively, the
+<code>fftw</code> function can be used to import wisdom.  For example
+
+     <pre class="example">          <var>wisdom</var> = fftw ('dwisdom')
+</pre>
+        <p>will save the existing wisdom used by Octave to the string <var>wisdom</var>. 
+This string can then be saved to a file and restored using the <code>save</code>
+and <code>load</code> commands respectively.  This existing wisdom can be reimported
+as follows
+
+     <pre class="example">          fftw ('dwisdom', <var>wisdom</var>)
+</pre>
+        <p>If <var>wisdom</var> is an empty matrix, then the wisdom used is cleared.
+
+        <p>During the calculation of Fourier transforms further wisdom is generated. 
+The fashion in which this wisdom is generated is equally controlled by
+the <code>fftw</code> function.  There are five different manners in which the
+wisdom can be treated, these being
+
+          <dl>
+<dt>'estimate'<dd>This specifies that no run-time measurement of the optimal means of
+calculating a particular is performed, and a simple heuristic is used
+to pick a (probably sub-optimal) plan.  The advantage of this method is
+that there is little or no overhead in the generation of the plan, which
+is appropriate for a Fourier transform that will be calculated once.
+
+          <br><dt>'measure'<dd>In this case a range of algorithms to perform the transform is considered
+and the best is selected based on their execution time.
+
+          <br><dt>'patient'<dd>This is like 'measure', but a wider range of algorithms is considered.
+
+          <br><dt>'exhaustive'<dd>This is like 'measure', but all possible algorithms that may be used to
+treat the transform are considered.
+
+          <br><dt>'hybrid'<dd>As run-time measurement of the algorithm can be expensive, this is a
+compromise where 'measure' is used for transforms up to the size of 8192
+and beyond that the 'estimate' method is used. 
+</dl>
+
+        <p>The default method is 'estimate', and the method currently being used can
+be probed with
+
+     <pre class="example">          <var>method</var> = fftw ('planner')
+</pre>
+        <p>and the method used can be set using
+
+     <pre class="example">          fftw ('planner', <var>method</var>)
+</pre>
+        <p>Note that calculated wisdom will be lost when restarting Octave.  However,
+the wisdom data can be reloaded if it is saved to a file as described
+above.  Saved wisdom files should not be used on different platforms since
+they will not be efficient and the point of calculating the wisdom is lost. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfft.html#doc_002dfft">fft</a>, <a href="doc_002difft.html#doc_002difft">ifft</a>, <a href="doc_002dfft2.html#doc_002dfft2">fft2</a>, <a href="doc_002difft2.html#doc_002difft2">ifft2</a>, <a href="doc_002dfftn.html#doc_002dfftn">fftn</a>, <a href="doc_002difftn.html#doc_002difftn">ifftn</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/fft.cc -->
+   <p><a name="doc_002difft"></a>
+
+<div class="defun">
+— Loadable Function:  <b>ifft</b> (<var>a, n, dim</var>)<var><a name="index-ifft-2128"></a></var><br>
+<blockquote><p>Compute the inverse FFT of <var>a</var> using subroutines from
+<span class="sc">fftw</span>.  The inverse FFT is calculated along the first non-singleton dimension
+of the array.  Thus if <var>a</var> is a matrix, <code>fft (</code><var>a</var><code>)</code> computes
+the inverse FFT for each column of <var>a</var>.
+
+        <p>If called with two arguments, <var>n</var> is expected to be an integer
+specifying the number of elements of <var>a</var> to use, or an empty
+matrix to specify that its value should be ignored.  If <var>n</var> is
+larger than the dimension along which the inverse FFT is calculated, then
+<var>a</var> is resized and padded with zeros.  Otherwise, if<var>n</var> is
+smaller than the dimension along which the inverse FFT is calculated,
+then <var>a</var> is truncated.
+
+        <p>If called with three arguments, <var>dim</var> is an integer specifying the
+dimension of the matrix along which the inverse FFT is performed
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfft.html#doc_002dfft">fft</a>, <a href="doc_002difft2.html#doc_002difft2">ifft2</a>, <a href="doc_002difftn.html#doc_002difftn">ifftn</a>, <a href="doc_002dfftw.html#doc_002dfftw">fftw</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/fft2.cc -->
+   <p><a name="doc_002dfft2"></a>
+
+<div class="defun">
+— Loadable Function:  <b>fft2</b> (<var>a, n, m</var>)<var><a name="index-fft2-2129"></a></var><br>
+<blockquote><p>Compute the two-dimensional FFT of <var>a</var> using subroutines from
+<span class="sc">fftw</span>.  The optional arguments <var>n</var> and <var>m</var> may be used specify the
+number of rows and columns of <var>a</var> to use.  If either of these is
+larger than the size of <var>a</var>, <var>a</var> is resized and padded with
+zeros.
+
+        <p>If <var>a</var> is a multi-dimensional matrix, each two-dimensional sub-matrix
+of <var>a</var> is treated separately
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> ifft2, fft, fftn, fftw. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/fft2.cc -->
+   <p><a name="doc_002difft2"></a>
+
+<div class="defun">
+— Loadable Function:  <b>fft2</b> (<var>a, n, m</var>)<var><a name="index-fft2-2130"></a></var><br>
+<blockquote><p>Compute the inverse two-dimensional FFT of <var>a</var> using subroutines from
+<span class="sc">fftw</span>.  The optional arguments <var>n</var> and <var>m</var> may be used specify the
+number of rows and columns of <var>a</var> to use.  If either of these is
+larger than the size of <var>a</var>, <var>a</var> is resized and padded with
+zeros.
+
+        <p>If <var>a</var> is a multi-dimensional matrix, each two-dimensional sub-matrix
+of <var>a</var> is treated separately
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> fft2, ifft, ifftn, fftw. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/fftn.cc -->
+   <p><a name="doc_002dfftn"></a>
+
+<div class="defun">
+— Loadable Function:  <b>fftn</b> (<var>a, size</var>)<var><a name="index-fftn-2131"></a></var><br>
+<blockquote><p>Compute the N-dimensional FFT of <var>a</var> using subroutines from
+<span class="sc">fftw</span>.  The optional vector argument <var>size</var> may be used specify the
+dimensions of the array to be used.  If an element of <var>size</var> is
+smaller than the corresponding dimension, then the dimension is
+truncated prior to performing the FFT.  Otherwise if an element
+of <var>size</var> is larger than the corresponding dimension <var>a</var>
+is resized and padded with zeros. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> ifftn, fft, fft2, fftw. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/fftn.cc -->
+   <p><a name="doc_002difftn"></a>
+
+<div class="defun">
+— Loadable Function:  <b>ifftn</b> (<var>a, size</var>)<var><a name="index-ifftn-2132"></a></var><br>
+<blockquote><p>Compute the inverse N-dimensional FFT of <var>a</var> using subroutines from
+<span class="sc">fftw</span>.  The optional vector argument <var>size</var> may be used specify the
+dimensions of the array to be used.  If an element of <var>size</var> is
+smaller than the corresponding dimension, then the dimension is
+truncated prior to performing the inverse FFT.  Otherwise if an element
+of <var>size</var> is larger than the corresponding dimension <var>a</var>
+is resized and padded with zeros. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> fftn, ifft, ifft2, fftw. 
+</p></blockquote></div>
+
+<!-- ./signal/fftconv.m -->
+   <p><a name="doc_002dfftconv"></a>
+
+<div class="defun">
+— Function File:  <b>fftconv</b> (<var>a, b, n</var>)<var><a name="index-fftconv-2133"></a></var><br>
+<blockquote><p>Return the convolution of the vectors <var>a</var> and <var>b</var>, as a vector
+with length equal to the <code>length (a) + length (b) - 1</code>.  If <var>a</var>
+and <var>b</var> are the coefficient vectors of two polynomials, the returned
+value is the coefficient vector of the product polynomial.
+
+        <p>The computation uses the FFT by calling the function <code>fftfilt</code>.  If
+the optional argument <var>n</var> is specified, an N-point FFT is used. 
+</p></blockquote></div>
+
+<!-- ./signal/fftfilt.m -->
+   <p><a name="doc_002dfftfilt"></a>
+
+<div class="defun">
+— Function File:  <b>fftfilt</b> (<var>b, x, n</var>)<var><a name="index-fftfilt-2134"></a></var><br>
+<blockquote>
+        <p>With two arguments, <code>fftfilt</code> filters <var>x</var> with the FIR filter
+<var>b</var> using the FFT.
+
+        <p>Given the optional third argument, <var>n</var>, <code>fftfilt</code> uses the
+overlap-add method to filter <var>x</var> with <var>b</var> using an N-point FFT.
+
+        <p>If <var>x</var> is a matrix, filter each column of the matrix. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/filter.cc -->
+   <p><a name="doc_002dfilter"></a>
+
+<div class="defun">
+— Loadable Function: y = <b>filter</b> (<var>b, a, x</var>)<var><a name="index-filter-2135"></a></var><br>
+— Loadable Function: [<var>y</var>, <var>sf</var>] = <b>filter</b> (<var>b, a, x, si</var>)<var><a name="index-filter-2136"></a></var><br>
+— Loadable Function: [<var>y</var>, <var>sf</var>] = <b>filter</b> (<var>b, a, x, </var>[]<var>, dim</var>)<var><a name="index-filter-2137"></a></var><br>
+— Loadable Function: [<var>y</var>, <var>sf</var>] = <b>filter</b> (<var>b, a, x, si, dim</var>)<var><a name="index-filter-2138"></a></var><br>
+<blockquote><p>Return the solution to the following linear, time-invariant difference
+equation:
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">             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
+</pre>
+        <p class="noindent">where
+ N=length(a)-1 and M=length(b)-1. 
+over the first non-singleton dimension of <var>x</var> or over <var>dim</var> if
+supplied.  An equivalent form of this equation is:
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">                      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
+</pre>
+        <p class="noindent">where
+ c = a/a(1) and d = b/a(1).
+
+        <p>If the fourth argument <var>si</var> is provided, it is taken as the
+initial state of the system and the final state is returned as
+<var>sf</var>.  The state vector is a column vector whose length is
+equal to the length of the longest coefficient vector minus one. 
+If <var>si</var> is not supplied, the initial state vector is set to all
+zeros.
+
+        <p>In terms of the z-transform, y is the result of passing the discrete-
+time signal x through a system characterized by the following rational
+system function:
+
+     <pre class="example">                       M
+                      SUM d(k+1) z^(-k)
+                      k=0
+            H(z) = ----------------------
+                         N
+                    1 + SUM c(k+1) z^(-k)
+                        k=1
+</pre>
+        </blockquote></div>
+
+<!-- ./signal/filter2.m -->
+   <p><a name="doc_002dfilter2"></a>
+
+<div class="defun">
+— Function File: <var>y</var> = <b>filter2</b> (<var>b, x</var>)<var><a name="index-filter2-2139"></a></var><br>
+— Function File: <var>y</var> = <b>filter2</b> (<var>b, x, shape</var>)<var><a name="index-filter2-2140"></a></var><br>
+<blockquote><p>Apply the 2-D FIR filter <var>b</var> to <var>x</var>.  If the argument
+<var>shape</var> is specified, return an array of the desired shape. 
+Possible values are:
+
+          <dl>
+<dt>'full'<dd>pad <var>x</var> with zeros on all sides before filtering. 
+<br><dt>'same'<dd>unpadded <var>x</var> (default)
+<br><dt>'valid'<dd>trim <var>x</var> after filtering so edge effects are no included. 
+</dl>
+
+        <p>Note this is just a variation on convolution, with the parameters
+reversed and <var>b</var> rotated 180 degrees. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dconv2.html#doc_002dconv2">conv2</a>. 
+</p></blockquote></div>
+
+<!-- ./signal/freqz.m -->
+   <p><a name="doc_002dfreqz"></a>
+
+<div class="defun">
+— Function File: [<var>h</var>, <var>w</var>] = <b>freqz</b> (<var>b, a, n, "whole"</var>)<var><a name="index-freqz-2141"></a></var><br>
+<blockquote><p>Return the complex frequency response <var>h</var> of the rational IIR filter
+whose numerator and denominator coefficients are <var>b</var> and <var>a</var>,
+respectively.  The response is evaluated at <var>n</var> angular frequencies
+between 0 and
+ 2*pi.
+
+     <p class="noindent">The output value <var>w</var> is a vector of the frequencies.
+
+        <p>If the fourth argument is omitted, the response is evaluated at
+frequencies between 0 and
+ pi.
+
+        <p>If <var>n</var> is omitted, a value of 512 is assumed.
+
+        <p>If <var>a</var> is omitted, the denominator is assumed to be 1 (this
+corresponds to a simple FIR filter).
+
+        <p>For fastest computation, <var>n</var> should factor into a small number of
+small primes.
+
+   — Function File: <var>h</var> = <b>freqz</b> (<var>b, a, w</var>)<var><a name="index-freqz-2142"></a></var><br>
+<blockquote><p>Evaluate the response at the specific frequencies in the vector <var>w</var>. 
+The values for <var>w</var> are measured in radians.
+
+   — Function File: [<small class="dots">...</small>] = <b>freqz</b> (<var><small class="dots">...</small>, Fs</var>)<var><a name="index-freqz-2143"></a></var><br>
+<blockquote><p>Return frequencies in Hz instead of radians assuming a sampling rate
+<var>Fs</var>.  If you are evaluating the response at specific frequencies
+<var>w</var>, those frequencies should be requested in Hz rather than radians.
+
+   — Function File:  <b>freqz</b> (<var><small class="dots">...</small></var>)<var><a name="index-freqz-2144"></a></var><br>
+<blockquote><p>Plot the pass band, stop band and phase response of <var>h</var> rather
+than returning them. 
+</p></blockquote></div>
+
+<!-- ./signal/freqz_plot.m -->
+   <p><a name="doc_002dfreqz_005fplot"></a>
+
+<div class="defun">
+— Function File:  <b>freqz_plot</b> (<var>w, h</var>)<var><a name="index-freqz_005fplot-2145"></a></var><br>
+<blockquote><p>Plot the pass band, stop band and phase response of <var>h</var>. 
+</p></blockquote></div>
+
+<!-- ./signal/sinc.m -->
+   <p><a name="doc_002dsinc"></a>
+
+<div class="defun">
+— Function File:  <b>sinc</b> (<var>x</var>)<var><a name="index-sinc-2146"></a></var><br>
+<blockquote><p>Return
+ sin(pi*x)/(pi*x). 
+</p></blockquote></div>
+
+<!-- ./signal/unwrap.m -->
+   <p><a name="doc_002dunwrap"></a>
+
+<div class="defun">
+— Function File: <var>b</var> = <b>unwrap</b> (<var>a, tol, dim</var>)<var><a name="index-unwrap-2147"></a></var><br>
+<blockquote>
+        <p>Unwrap radian phases by adding multiples of 2*pi as appropriate to
+remove jumps greater than <var>tol</var>.  <var>tol</var> defaults to pi.
+
+        <p>Unwrap will unwrap along the first non-singleton dimension of
+<var>a</var>, unless the optional argument <var>dim</var> is given, in
+which case the data will be unwrapped along this dimension
+</p></blockquote></div>
+
+<!-- FIXME - someone needs to organize these... -->
+<!-- ./signal/arch_fit.m -->
+   <p><a name="doc_002darch_005ffit"></a>
+
+<div class="defun">
+— Function File: [<var>a</var>, <var>b</var>] = <b>arch_fit</b> (<var>y, x, p, iter, gamma, a0, b0</var>)<var><a name="index-arch_005ffit-2148"></a></var><br>
+<blockquote><p>Fit an ARCH regression model to the time series <var>y</var> using the
+scoring algorithm in Engle's original ARCH paper.  The model is
+
+     <pre class="example">          y(t) = b(1) * x(t,1) + ... + b(k) * x(t,k) + e(t),
+          h(t) = a(1) + a(2) * e(t-1)^2 + ... + a(p+1) * e(t-p)^2
+</pre>
+        <p class="noindent">in which e(t) is N(0, h(t)), given a time-series vector
+<var>y</var> up to time t-1 and a matrix of (ordinary) regressors
+<var>x</var> up to t.  The order of the regression of the residual
+variance is specified by <var>p</var>.
+
+        <p>If invoked as <code>arch_fit (</code><var>y</var><code>, </code><var>k</var><code>, </code><var>p</var><code>)</code> with a
+positive integer <var>k</var>, fit an ARCH(<var>k</var>, <var>p</var>) process,
+i.e., do the above with the t-th row of <var>x</var> given by
+
+     <pre class="example">          [1, y(t-1), ..., y(t-k)]
+</pre>
+        <p>Optionally, one can specify the number of iterations <var>iter</var>, the
+updating factor <var>gamma</var>, and initial values a0 and
+b0 for the scoring algorithm. 
+</p></blockquote></div>
+
+<!-- ./signal/arch_rnd.m -->
+   <p><a name="doc_002darch_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>arch_rnd</b> (<var>a, b, t</var>)<var><a name="index-arch_005frnd-2149"></a></var><br>
+<blockquote><p>Simulate an ARCH sequence of length <var>t</var> with AR
+coefficients <var>b</var> and CH coefficients <var>a</var>.  I.e., the result
+y(t) follows the model
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">          y(t) = b(1) + b(2) * y(t-1) + ... + b(lb) * y(t-lb+1) + e(t),
+</pre>
+        <p class="noindent">where e(t), given <var>y</var> up to time t-1, is
+N(0, h(t)), with
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">          h(t) = a(1) + a(2) * e(t-1)^2 + ... + a(la) * e(t-la+1)^2
+</pre>
+        </blockquote></div>
+
+<!-- ./signal/arch_test.m -->
+   <p><a name="doc_002darch_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>lm</var>] = <b>arch_test</b> (<var>y, x, p</var>)<var><a name="index-arch_005ftest-2150"></a></var><br>
+<blockquote><p>For a linear regression model
+
+     <pre class="example">          y = x * b + e
+</pre>
+        <p class="noindent">perform a Lagrange Multiplier (LM) test of the null hypothesis of no
+conditional heteroscedascity against the alternative of CH(<var>p</var>).
+
+        <p>I.e., the model is
+
+     <pre class="example">          y(t) = b(1) * x(t,1) + ... + b(k) * x(t,k) + e(t),
+</pre>
+        <p class="noindent">given <var>y</var> up to t-1 and <var>x</var> up to t,
+e(t) is N(0, h(t)) with
+
+     <pre class="example">          h(t) = v + a(1) * e(t-1)^2 + ... + a(p) * e(t-p)^2,
+</pre>
+        <p class="noindent">and the null is a(1) == <small class="dots">...</small> == a(p) == 0.
+
+        <p>If the second argument is a scalar integer, k, perform the same
+test in a linear autoregression model of order k, i.e., with
+
+     <pre class="example">          [1, y(t-1), ..., y(t-<var>k</var>)]
+</pre>
+        <p class="noindent">as the t-th row of <var>x</var>.
+
+        <p>Under the null, LM approximately has a chisquare distribution with
+<var>p</var> degrees of freedom and <var>pval</var> is the p-value (1
+minus the CDF of this distribution at LM) of the test.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./signal/arma_rnd.m -->
+   <p><a name="doc_002darma_005frnd"></a>
+
+<div class="defun">
+— Function File:  <b>arma_rnd</b> (<var>a, b, v, t, n</var>)<var><a name="index-arma_005frnd-2151"></a></var><br>
+<blockquote><p>Return a simulation of the ARMA model
+
+     <pre class="example">          x(n) = a(1) * x(n-1) + ... + a(k) * x(n-k)
+               + e(n) + b(1) * e(n-1) + ... + b(l) * e(n-l)
+</pre>
+        <p class="noindent">in which <var>k</var> is the length of vector <var>a</var>, <var>l</var> is the
+length of vector <var>b</var> and <var>e</var> is Gaussian white noise with
+variance <var>v</var>.  The function returns a vector of length <var>t</var>.
+
+        <p>The optional parameter <var>n</var> gives the number of dummy
+<var>x</var>(<var>i</var>) used for initialization, i.e., a sequence of length
+<var>t</var>+<var>n</var> is generated and <var>x</var>(<var>n</var>+1:<var>t</var>+<var>n</var>)
+is returned.  If <var>n</var> is omitted, <var>n</var> = 100 is used. 
+</p></blockquote></div>
+
+<!-- ./signal/autocor.m -->
+   <p><a name="doc_002dautocor"></a>
+
+<div class="defun">
+— Function File:  <b>autocor</b> (<var>x, h</var>)<var><a name="index-autocor-2152"></a></var><br>
+<blockquote><p>Return the autocorrelations from lag 0 to <var>h</var> of vector <var>x</var>. 
+If <var>h</var> is omitted, all autocorrelations are computed. 
+If <var>x</var> is a matrix, the autocorrelations of each column are
+computed. 
+</p></blockquote></div>
+
+<!-- ./signal/autocov.m -->
+   <p><a name="doc_002dautocov"></a>
+
+<div class="defun">
+— Function File:  <b>autocov</b> (<var>x, h</var>)<var><a name="index-autocov-2153"></a></var><br>
+<blockquote><p>Return the autocovariances from lag 0 to <var>h</var> of vector <var>x</var>. 
+If <var>h</var> is omitted, all autocovariances are computed. 
+If <var>x</var> is a matrix, the autocovariances of each column are
+computed. 
+</p></blockquote></div>
+
+<!-- ./signal/autoreg_matrix.m -->
+   <p><a name="doc_002dautoreg_005fmatrix"></a>
+
+<div class="defun">
+— Function File:  <b>autoreg_matrix</b> (<var>y, k</var>)<var><a name="index-autoreg_005fmatrix-2154"></a></var><br>
+<blockquote><p>Given a time series (vector) <var>y</var>, return a matrix with ones in the
+first column and the first <var>k</var> lagged values of <var>y</var> in the
+other columns.  I.e., for <var>t</var> > <var>k</var>, <code>[1,
+</code><var>y</var><code>(</code><var>t</var><code>-1), ..., </code><var>y</var><code>(</code><var>t</var><code>-</code><var>k</var><code>)]</code> is the t-th row
+of the result.  The resulting matrix may be used as a regressor matrix
+in autoregressions. 
+</p></blockquote></div>
+
+<!-- ./signal/bartlett.m -->
+   <p><a name="doc_002dbartlett"></a>
+
+<div class="defun">
+— Function File:  <b>bartlett</b> (<var>m</var>)<var><a name="index-bartlett-2155"></a></var><br>
+<blockquote><p>Return the filter coefficients of a Bartlett (triangular) window of
+length <var>m</var>.
+
+        <p>For a definition of the Bartlett window, see e.g., A. V. Oppenheim &
+R. W. Schafer, <cite>Discrete-Time Signal Processing</cite>. 
+</p></blockquote></div>
+
+<!-- ./signal/blackman.m -->
+   <p><a name="doc_002dblackman"></a>
+
+<div class="defun">
+— Function File:  <b>blackman</b> (<var>m</var>)<var><a name="index-blackman-2156"></a></var><br>
+<blockquote><p>Return the filter coefficients of a Blackman window of length <var>m</var>.
+
+        <p>For a definition of the Blackman window, see e.g., A. V. Oppenheim &
+R. W. Schafer, <cite>Discrete-Time Signal Processing</cite>. 
+</p></blockquote></div>
+
+<!-- ./signal/diffpara.m -->
+   <p><a name="doc_002ddiffpara"></a>
+
+<div class="defun">
+— Function File: [<var>d</var>, <var>dd</var>] = <b>diffpara</b> (<var>x, a, b</var>)<var><a name="index-diffpara-2157"></a></var><br>
+<blockquote><p>Return the estimator <var>d</var> for the differencing parameter of an
+integrated time series.
+
+        <p>The frequencies from [2*pi*a/t, 2*pi*b/T] are used for the
+estimation.  If <var>b</var> is omitted, the interval
+[2*pi/T, 2*pi*a/T] is used.  If both <var>b</var> and <var>a</var> are
+omitted then a = 0.5 * sqrt (T) and b = 1.5 * sqrt (T)
+is used, where T is the sample size.  If <var>x</var> is a matrix,
+the differencing parameter of each column is estimated.
+
+        <p>The estimators for all frequencies in the intervals
+described above is returned in <var>dd</var>.  The value of <var>d</var> is
+simply the mean of <var>dd</var>.
+
+        <p>Reference: Brockwell, Peter J. & Davis, Richard A. Time Series:
+Theory and Methods Springer 1987. 
+</p></blockquote></div>
+
+<!-- ./signal/durbinlevinson.m -->
+   <p><a name="doc_002ddurbinlevinson"></a>
+
+<div class="defun">
+— Function File:  <b>durbinlevinson</b> (<var>c, oldphi, oldv</var>)<var><a name="index-durbinlevinson-2158"></a></var><br>
+<blockquote><p>Perform one step of the Durbin-Levinson algorithm.
+
+        <p>The vector <var>c</var> specifies the autocovariances <code>[gamma_0, ...,
+gamma_t]</code> from lag 0 to <var>t</var>, <var>oldphi</var> specifies the
+coefficients based on <var>c</var>(<var>t</var>-1) and <var>oldv</var> specifies the
+corresponding error.
+
+        <p>If <var>oldphi</var> and <var>oldv</var> are omitted, all steps from 1 to
+<var>t</var> of the algorithm are performed. 
+</p></blockquote></div>
+
+<!-- ./signal/fftshift.m -->
+   <p><a name="doc_002dfftshift"></a>
+
+<div class="defun">
+— Function File:  <b>fftshift</b> (<var>v</var>)<var><a name="index-fftshift-2159"></a></var><br>
+— Function File:  <b>fftshift</b> (<var>v, dim</var>)<var><a name="index-fftshift-2160"></a></var><br>
+<blockquote><p>Perform a shift of the vector <var>v</var>, for use with the <code>fft</code>
+and <code>ifft</code> functions, in order the move the frequency 0 to the
+center of the vector or matrix.
+
+        <p>If <var>v</var> is a vector of N elements corresponding to N
+time samples spaced of Dt each, then <code>fftshift (fft
+(</code><var>v</var><code>))</code> corresponds to frequencies
+
+     <pre class="example">          f = ((1:N) - ceil(N/2)) / N / Dt
+</pre>
+        <p>If <var>v</var> is a matrix, the same holds for rows and columns.  If
+<var>v</var> is an array, then the same holds along each dimension.
+
+        <p>The optional <var>dim</var> argument can be used to limit the dimension
+along which the permutation occurs. 
+</p></blockquote></div>
+
+<!-- ./signal/ifftshift.m -->
+   <p><a name="doc_002difftshift"></a>
+
+<div class="defun">
+— Function File:  <b>ifftshift</b> (<var>v</var>)<var><a name="index-ifftshift-2161"></a></var><br>
+— Function File:  <b>ifftshift</b> (<var>v, dim</var>)<var><a name="index-ifftshift-2162"></a></var><br>
+<blockquote><p>Undo the action of the <code>fftshift</code> function.  For even length
+<var>v</var>, <code>fftshift</code> is its own inverse, but odd lengths differ
+slightly. 
+</p></blockquote></div>
+
+<!-- ./signal/fractdiff.m -->
+   <p><a name="doc_002dfractdiff"></a>
+
+<div class="defun">
+— Function File:  <b>fractdiff</b> (<var>x, d</var>)<var><a name="index-fractdiff-2163"></a></var><br>
+<blockquote><p>Compute the fractional differences (1-L)^d x where L
+denotes the lag-operator and d is greater than -1. 
+</p></blockquote></div>
+
+<!-- ./signal/hamming.m -->
+   <p><a name="doc_002dhamming"></a>
+
+<div class="defun">
+— Function File:  <b>hamming</b> (<var>m</var>)<var><a name="index-hamming-2164"></a></var><br>
+<blockquote><p>Return the filter coefficients of a Hamming window of length <var>m</var>.
+
+        <p>For a definition of the Hamming window, see e.g., A. V. Oppenheim &
+R. W. Schafer, <cite>Discrete-Time Signal Processing</cite>. 
+</p></blockquote></div>
+
+<!-- ./signal/hanning.m -->
+   <p><a name="doc_002dhanning"></a>
+
+<div class="defun">
+— Function File:  <b>hanning</b> (<var>m</var>)<var><a name="index-hanning-2165"></a></var><br>
+<blockquote><p>Return the filter coefficients of a Hanning window of length <var>m</var>.
+
+        <p>For a definition of this window type, see e.g., A. V. Oppenheim &
+R. W. Schafer, <cite>Discrete-Time Signal Processing</cite>. 
+</p></blockquote></div>
+
+<!-- ./signal/hurst.m -->
+   <p><a name="doc_002dhurst"></a>
+
+<div class="defun">
+— Function File:  <b>hurst</b> (<var>x</var>)<var><a name="index-hurst-2166"></a></var><br>
+<blockquote><p>Estimate the Hurst parameter of sample <var>x</var> via the rescaled range
+statistic.  If <var>x</var> is a matrix, the parameter is estimated for
+every single column. 
+</p></blockquote></div>
+
+<!-- ./polynomial/pchip.m -->
+   <p><a name="doc_002dpchip"></a>
+
+<div class="defun">
+— Function File: <var>pp</var> = <b>pchip</b> (<var>x, y</var>)<var><a name="index-pchip-2167"></a></var><br>
+— Function File: <var>yi</var> = <b>pchip</b> (<var>x, y, xi</var>)<var><a name="index-pchip-2168"></a></var><br>
+<blockquote>
+        <p>Piecewise Cubic Hermite interpolating polynomial.  Called with two
+arguments, the piece-wise polynomial <var>pp</var> is returned, that may
+later be used with <code>ppval</code> to evaluate the polynomial at
+specific points.
+
+        <p>The variable <var>x</var> must be a strictly monotonic vector (either
+increasing or decreasing).  While <var>y</var> can be either a vector or
+array.  In the case where <var>y</var> is a vector, it must have a length
+of <var>n</var>.  If <var>y</var> is an array, then the size of <var>y</var> must
+have the form
+<code>[</code><var>s1</var><code>, </code><var>s2</var><code>, ..., </code><var>sk</var><code>, </code><var>n</var><code>]</code>
+The array is then reshaped internally to a matrix where the leading
+dimension is given by
+<var>s1</var><code> * </code><var>s2</var><code> * ... * </code><var>sk</var>
+and each row in this matrix is then treated separately.  Note that this
+is exactly the opposite treatment than <code>interp1</code> and is done
+for compatibility.
+
+        <p>Called with a third input argument, <code>pchip</code> evaluates the
+piece-wise polynomial at the points <var>xi</var>.  There is an equivalence
+between <code>ppval (pchip (</code><var>x</var><code>, </code><var>y</var><code>), </code><var>xi</var><code>)</code> and
+<code>pchip (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>xi</var><code>)</code>.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dspline.html#doc_002dspline">spline</a>, <a href="doc_002dppval.html#doc_002dppval">ppval</a>, <a href="doc_002dmkpp.html#doc_002dmkpp">mkpp</a>, <a href="doc_002dunmkpp.html#doc_002dunmkpp">unmkpp</a>. 
+</p></blockquote></div>
+
+<!-- ./signal/periodogram.m -->
+   <p><a name="doc_002dperiodogram"></a>
+
+<div class="defun">
+— Function File:  <b>periodogram</b> (<var>x</var>)<var><a name="index-periodogram-2169"></a></var><br>
+<blockquote><p>For a data matrix <var>x</var> from a sample of size <var>n</var>, return the
+periodogram. 
+</p></blockquote></div>
+
+<!-- ./signal/rectangle_lw.m -->
+   <p><a name="doc_002drectangle_005flw"></a>
+
+<div class="defun">
+— Function File:  <b>rectangle_lw</b> (<var>n, b</var>)<var><a name="index-rectangle_005flw-2170"></a></var><br>
+<blockquote><p>Rectangular lag window.  Subfunction used for spectral density
+estimation. 
+</p></blockquote></div>
+
+<!-- ./signal/rectangle_sw.m -->
+   <p><a name="doc_002drectangle_005fsw"></a>
+
+<div class="defun">
+— Function File:  <b>rectangle_sw</b> (<var>n, b</var>)<var><a name="index-rectangle_005fsw-2171"></a></var><br>
+<blockquote><p>Rectangular spectral window.  Subfunction used for spectral density
+estimation. 
+</p></blockquote></div>
+
+<!-- ./signal/sinetone.m -->
+   <p><a name="doc_002dsinetone"></a>
+
+<div class="defun">
+— Function File:  <b>sinetone</b> (<var>freq, rate, sec, ampl</var>)<var><a name="index-sinetone-2172"></a></var><br>
+<blockquote><p>Return a sinetone of frequency <var>freq</var> with length of <var>sec</var>
+seconds at sampling rate <var>rate</var> and with amplitude <var>ampl</var>. 
+The arguments <var>freq</var> and <var>ampl</var> may be vectors of common size.
+
+        <p>Defaults are <var>rate</var> = 8000, <var>sec</var> = 1 and <var>ampl</var> = 64. 
+</p></blockquote></div>
+
+<!-- ./signal/sinewave.m -->
+   <p><a name="doc_002dsinewave"></a>
+
+<div class="defun">
+— Function File:  <b>sinewave</b> (<var>m, n, d</var>)<var><a name="index-sinewave-2173"></a></var><br>
+<blockquote><p>Return an <var>m</var>-element vector with <var>i</var>-th element given by
+<code>sin (2 * pi * (</code><var>i</var><code>+</code><var>d</var><code>-1) / </code><var>n</var><code>)</code>.
+
+        <p>The default value for <var>d</var> is 0 and the default value for <var>n</var>
+is <var>m</var>. 
+</p></blockquote></div>
+
+<!-- ./signal/spectral_adf.m -->
+   <p><a name="doc_002dspectral_005fadf"></a>
+
+<div class="defun">
+— Function File:  <b>spectral_adf</b> (<var>c, win, b</var>)<var><a name="index-spectral_005fadf-2174"></a></var><br>
+<blockquote><p>Return the spectral density estimator given a vector of
+autocovariances <var>c</var>, window name <var>win</var>, and bandwidth,
+<var>b</var>.
+
+        <p>The window name, e.g., <code>"triangle"</code> or <code>"rectangle"</code> is
+used to search for a function called <var>win</var><code>_sw</code>.
+
+        <p>If <var>win</var> is omitted, the triangle window is used.  If <var>b</var> is
+omitted, <code>1 / sqrt (length (</code><var>x</var><code>))</code> is used. 
+</p></blockquote></div>
+
+<!-- ./signal/spectral_xdf.m -->
+   <p><a name="doc_002dspectral_005fxdf"></a>
+
+<div class="defun">
+— Function File:  <b>spectral_xdf</b> (<var>x, win, b</var>)<var><a name="index-spectral_005fxdf-2175"></a></var><br>
+<blockquote><p>Return the spectral density estimator given a data vector <var>x</var>,
+window name <var>win</var>, and bandwidth, <var>b</var>.
+
+        <p>The window name, e.g., <code>"triangle"</code> or <code>"rectangle"</code> is
+used to search for a function called <var>win</var><code>_sw</code>.
+
+        <p>If <var>win</var> is omitted, the triangle window is used.  If <var>b</var> is
+omitted, <code>1 / sqrt (length (</code><var>x</var><code>))</code> is used. 
+</p></blockquote></div>
+
+<!-- ./signal/spencer.m -->
+   <p><a name="doc_002dspencer"></a>
+
+<div class="defun">
+— Function File:  <b>spencer</b> (<var>x</var>)<var><a name="index-spencer-2176"></a></var><br>
+<blockquote><p>Return Spencer's 15 point moving average of every single column of
+<var>x</var>. 
+</p></blockquote></div>
+
+<!-- ./signal/stft.m -->
+   <p><a name="doc_002dstft"></a>
+
+<div class="defun">
+— Function File: [<var>y</var>, <var>c</var>] = <b>stft</b> (<var>x, win_size, inc, num_coef, w_type</var>)<var><a name="index-stft-2177"></a></var><br>
+<blockquote><p>Compute the short-time Fourier transform of the vector <var>x</var> with
+<var>num_coef</var> coefficients by applying a window of <var>win_size</var> data
+points and an increment of <var>inc</var> points.
+
+        <p>Before computing the Fourier transform, one of the following windows
+is applied:
+
+          <dl>
+<dt>hanning<dd>w_type = 1
+<br><dt>hamming<dd>w_type = 2
+<br><dt>rectangle<dd>w_type = 3
+</dl>
+
+        <p>The window names can be passed as strings or by the <var>w_type</var> number.
+
+        <p>If not all arguments are specified, the following defaults are used:
+<var>win_size</var> = 80, <var>inc</var> = 24, <var>num_coef</var> = 64, and
+<var>w_type</var> = 1.
+
+        <p><var>y</var><code> = stft (</code><var>x</var><code>, ...)</code> returns the absolute values
+of the Fourier coefficients according to the <var>num_coef</var> positive
+frequencies.
+
+        <p><code>[</code><var>y</var><code>, </code><var>c</var><code>] = stft (x, ...)</code> returns the
+entire STFT-matrix <var>y</var> and a 3-element vector <var>c</var> containing
+the window size, increment, and window type, which is needed by the
+synthesis function. 
+</p></blockquote></div>
+
+<!-- ./signal/synthesis.m -->
+   <p><a name="doc_002dsynthesis"></a>
+
+<div class="defun">
+— Function File:  <b>synthesis</b> (<var>y, c</var>)<var><a name="index-synthesis-2178"></a></var><br>
+<blockquote><p>Compute a signal from its short-time Fourier transform <var>y</var> and a
+3-element vector <var>c</var> specifying window size, increment, and
+window type.
+
+        <p>The values <var>y</var> and <var>c</var> can be derived by
+
+     <pre class="example">          [<var>y</var>, <var>c</var>] = stft (<var>x</var> , ...)
+</pre>
+        </blockquote></div>
+
+<!-- ./signal/triangle_lw.m -->
+   <p><a name="doc_002dtriangle_005flw"></a>
+
+<div class="defun">
+— Function File:  <b>triangle_lw</b> (<var>n, b</var>)<var><a name="index-triangle_005flw-2179"></a></var><br>
+<blockquote><p>Triangular lag window.  Subfunction used for spectral density
+estimation. 
+</p></blockquote></div>
+
+<!-- ./signal/triangle_sw.m -->
+   <p><a name="doc_002dtriangle_005fsw"></a>
+
+<div class="defun">
+— Function File:  <b>triangle_sw</b> (<var>n, b</var>)<var><a name="index-triangle_005fsw-2180"></a></var><br>
+<blockquote><p>Triangular spectral window.  Subfunction used for spectral density
+estimation. 
+</p></blockquote></div>
+
+<!-- ./signal/yulewalker.m -->
+   <p><a name="doc_002dyulewalker"></a>
+
+<div class="defun">
+— Function File: [<var>a</var>, <var>v</var>] = <b>yulewalker</b> (<var>c</var>)<var><a name="index-yulewalker-2181"></a></var><br>
+<blockquote><p>Fit an AR (p)-model with Yule-Walker estimates given a vector <var>c</var>
+of autocovariances <code>[gamma_0, ..., gamma_p]</code>.
+
+        <p>Returns the AR coefficients, <var>a</var>, and the variance of white
+noise, <var>v</var>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Simple-Examples.html b/doc/interpreter/HTML/Simple-Examples.html
new file mode 100644
index 0000000..4e4930e
--- /dev/null
+++ b/doc/interpreter/HTML/Simple-Examples.html
@@ -0,0 +1,271 @@
+<html lang="en">
+<head>
+<title>Simple Examples - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Introduction.html#Introduction" title="Introduction">
+<link rel="prev" href="Running-Octave.html#Running-Octave" title="Running Octave">
+<link rel="next" href="Conventions.html#Conventions" title="Conventions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Simple-Examples"></a>
+Next: <a rel="next" accesskey="n" href="Conventions.html#Conventions">Conventions</a>,
+Previous: <a rel="previous" accesskey="p" href="Running-Octave.html#Running-Octave">Running Octave</a>,
+Up: <a rel="up" accesskey="u" href="Introduction.html#Introduction">Introduction</a>
+<hr>
+</div>
+
+<h3 class="section">1.2 Simple Examples</h3>
+
+<p>The following chapters describe all of Octave's features in detail, but
+before doing that, it might be helpful to give a sampling of some of its
+capabilities.
+
+   <p>If you are new to Octave, I recommend that you try these examples to
+begin learning Octave by using it.  Lines marked with ‘<samp><span class="samp">octave:13></span></samp>’
+are lines you type, ending each with a carriage return.  Octave will
+respond with an answer, or by displaying a graph.
+
+<h4 class="subsection">1.2.1 Elementary Calculations</h4>
+
+<p>Octave can easily be used for basic numerical calculations.  Octave
+knows about arithmetic operations (+,-,*,/), exponentiation (^),
+natural logarithms/exponents (log, exp), and the trigonometric
+functions (sin, cos, <small class="dots">...</small>).  Moreover, Octave calculations work
+on real or imaginary numbers (i,j).  In addition, some mathematical
+constants such as the base of the natural logarithm (e) and the ratio
+of a circle's circumference to its diameter (pi) are pre-defined.
+
+<p class="noindent">For example, to verify Euler's Identity,
+<pre class="display">     
+      i*pi
+     e     = -1
+</pre>
+   <p class="noindent">type the following which will evaluate to <code>-1</code> within the
+tolerance of the calculation.
+
+<pre class="example">     octave:1> exp(i*pi)
+</pre>
+   <h4 class="subsection">1.2.2 Creating a Matrix</h4>
+
+<p>Vectors and matrices are the basic building blocks for numerical analysis. 
+To create a new matrix and store it in a variable so that you can
+refer to it later, type the command
+
+<pre class="example">     octave:1> A = [ 1, 1, 2; 3, 5, 8; 13, 21, 34 ]
+</pre>
+   <p class="noindent">Octave will respond by printing the matrix in neatly aligned columns. 
+Octave uses a comma or space to separate entries in a row, and a
+semicolon or carriage return to separate one row from the next. 
+Ending a command with a semicolon tells Octave not to print the result
+of the command.  For example,
+
+<pre class="example">     octave:2> B = rand (3, 2);
+</pre>
+   <p class="noindent">will create a 3 row, 2 column matrix with each element set to a random
+value between zero and one.
+
+   <p>To display the value of a variable, simply type the name of the
+variable at the prompt.  For example, to display the value stored in the
+matrix <code>B</code>, type the command
+
+<pre class="example">     octave:3> B
+</pre>
+   <h4 class="subsection">1.2.3 Matrix Arithmetic</h4>
+
+<p>Octave has a convenient operator notation for performing matrix
+arithmetic.  For example, to multiply the matrix <code>A</code> by a scalar
+value, type the command
+
+<pre class="example">     octave:4> 2 * A
+</pre>
+   <p class="noindent">To multiply the two matrices <code>A</code> and <code>B</code>, type the command
+
+<pre class="example">     octave:5> A * B
+</pre>
+   <p class="noindent">and to form the matrix product
+<code>transpose (A) * A</code>,
+type the command
+
+<pre class="example">     octave:6> A' * A
+</pre>
+   <h4 class="subsection">1.2.4 Solving Systems of Linear Equations</h4>
+
+<p>Systems of linear equations are ubiquitous in numerical analysis. 
+To solve the set of linear equations <code>A</code><var>x</var><code> = b</code>,
+use the left division operator, ‘<samp><span class="samp">\</span></samp>’:
+
+<pre class="example">     <var>x</var> = A \ b
+</pre>
+   <p class="noindent">This is conceptually equivalent to
+<code>inv (a) * b</code>,
+but avoids computing the inverse of a matrix directly.
+
+   <p>If the coefficient matrix is singular, Octave will print a warning
+message and compute a minimum norm solution.
+
+   <p>A simple example comes from chemistry and the need to obtain balanced
+chemical equations.  Consider the burning of hydrogen and oxygen to
+produce water.
+
+<pre class="example">     H2 + O2 --> H2O
+</pre>
+   <p class="noindent">The equation above is not accurate.  The Law of Conservation of Mass requires
+that the number of molecules of each type balance on the left- and right-hand
+sides of the equation.  Writing the variable overall reaction with
+individual equations for hydrogen and oxygen one finds:
+
+<pre class="example">     x1*H2 + x2*O2 --> H2O
+     H: 2*x1 + 0*x2 --> 2
+     O: 0*x1 + 2*x2 --> 1
+</pre>
+   <p class="noindent">The solution in Octave is found in just three steps.
+
+<pre class="example">     octave:1> A = [ 2, 0; 0, 2 ];
+     octave:2> b = [ 2; 1 ];
+     octave:3> x = A \ b
+</pre>
+   <h4 class="subsection">1.2.5 Integrating Differential Equations</h4>
+
+<p>Octave has built-in functions for solving nonlinear differential
+equations of the form
+
+<pre class="example">     dx
+     -- = f (x, t)
+     dt
+</pre>
+   <p class="noindent">with the initial condition
+
+<pre class="example">     x(t = t0) = x0
+</pre>
+   <p class="noindent">For Octave to integrate equations of this form, you must first provide a
+definition of the function
+<code>f(x,t)</code>. 
+This is straightforward, and may be accomplished by entering the
+function body directly on the command line.  For example, the following
+commands define the right-hand side function for an interesting pair of
+nonlinear differential equations.  Note that while you are entering a
+function, Octave responds with a different prompt, to indicate that it
+is waiting for you to complete your input.
+
+<pre class="example">     octave:1> function xdot = f (x, t)
+     >
+     >  r = 0.25;
+     >  k = 1.4;
+     >  a = 1.5;
+     >  b = 0.16;
+     >  c = 0.9;
+     >  d = 0.8;
+     >
+     >  xdot(1) = r*x(1)*(1 - x(1)/k) - a*x(1)*x(2)/(1 + b*x(1));
+     >  xdot(2) = c*a*x(1)*x(2)/(1 + b*x(1)) - d*x(2);
+     >
+     > endfunction
+</pre>
+   <p class="noindent">Given the initial condition
+
+<pre class="example">     octave:2> x0 = [1; 2];
+</pre>
+   <p class="noindent">and the set of output times as a column vector (note that the first
+output time corresponds to the initial condition given above)
+
+<pre class="example">     octave:3> t = linspace (0, 50, 200)';
+</pre>
+   <p class="noindent">it is easy to integrate the set of differential equations:
+
+<pre class="example">     octave:4> x = lsode ("f", x0, t);
+</pre>
+   <p class="noindent">The function <code>lsode</code> uses the Livermore Solver for Ordinary
+Differential Equations, described in A. C. Hindmarsh, <cite>ODEPACK, a
+Systematized Collection of ODE Solvers</cite>, in: Scientific Computing, R. S. 
+Stepleman et al. (Eds.), North-Holland, Amsterdam, 1983, pages 55–64.
+
+<h4 class="subsection">1.2.6 Producing Graphical Output</h4>
+
+<p>To display the solution of the previous example graphically, use the
+command
+
+<pre class="example">     octave:1> plot (t, x)
+</pre>
+   <p class="noindent">If you are using a graphical user interface, Octave will automatically create
+a separate window to display the plot.
+
+   <p>To save a plot once it has been displayed on the screen, use the print
+command.  For example,
+
+<pre class="example">     print -deps foo.eps
+</pre>
+   <p class="noindent">will create a file called <samp><span class="file">foo.eps</span></samp> that contains a rendering of
+the current plot in Encapsulated PostScript format.  The command
+
+<pre class="example">     help print
+</pre>
+   <p class="noindent">explains more options for the <code>print</code> command and provides a list
+of additional output file formats.
+
+<h4 class="subsection">1.2.7 Editing What You Have Typed</h4>
+
+<p>At the Octave prompt, you can recall, edit, and reissue previous
+commands using Emacs- or vi-style editing commands.  The default
+keybindings use Emacs-style commands.  For example, to recall the
+previous command, press <kbd>Control-p</kbd> (written <kbd>C-p</kbd> for
+short).  Doing this will normally bring back the previous line of input. 
+<kbd>C-n</kbd> will bring up the next line of input, <kbd>C-b</kbd> will move
+the cursor backward on the line, <kbd>C-f</kbd> will move the cursor forward
+on the line, etc.
+
+   <p>A complete description of the command line editing capability is given
+in this manual in <a href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>.
+
+<h4 class="subsection">1.2.8 Help and Documentation</h4>
+
+<p>Octave has an extensive help facility.  The same documentation that is
+available in printed form is also available from the Octave prompt,
+because both forms of the documentation are created from the same input
+file.
+
+   <p>In order to get good help you first need to know the name of the command
+that you want to use.  This name of the function may not always be
+obvious, but a good place to start is to just type <code>help</code>. 
+This will show you all the operators, reserved words, functions,
+built-in variables, and function files.  An alternative is to search the
+documentation using the <code>lookfor</code> function.  This function is
+described in <a href="Getting-Help.html#Getting-Help">Getting Help</a>.
+
+   <p>Once you know the name of the function you wish to use, you can get more
+help on the function by simply including the name as an argument to help. 
+For example,
+
+<pre class="example">     help plot
+</pre>
+   <p class="noindent">will display the help text for the <code>plot</code> function.
+
+   <p>Octave sends output that is too long to fit on one screen through a
+pager like <code>less</code> or <code>more</code>.  Type a <RET> to advance one
+line, a <SPC> to advance one page, and <q> to exit the pager.
+
+   <p>The part of Octave's help facility that allows you to read the complete
+text of the printed manual from within Octave normally uses a separate
+program called Info.  When you invoke Info you will be put into a menu
+driven program that contains the entire Octave manual.  Help for using
+Info is provided in this manual in <a href="Getting-Help.html#Getting-Help">Getting Help</a>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Simple-File-I_002fO.html b/doc/interpreter/HTML/Simple-File-I_002fO.html
new file mode 100644
index 0000000..9ceeb43
--- /dev/null
+++ b/doc/interpreter/HTML/Simple-File-I_002fO.html
@@ -0,0 +1,441 @@
+<html lang="en">
+<head>
+<title>Simple File I/O - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Input-and-Output.html#Basic-Input-and-Output" title="Basic Input and Output">
+<link rel="prev" href="Terminal-Input.html#Terminal-Input" title="Terminal Input">
+<link rel="next" href="Rational-Approximations.html#Rational-Approximations" title="Rational Approximations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Simple-File-I%2fO"></a>
+<a name="Simple-File-I_002fO"></a>
+Next: <a rel="next" accesskey="n" href="Rational-Approximations.html#Rational-Approximations">Rational Approximations</a>,
+Previous: <a rel="previous" accesskey="p" href="Terminal-Input.html#Terminal-Input">Terminal Input</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.1.3 Simple File I/O</h4>
+
+<p><a name="index-saving-data-727"></a><a name="index-loading-data-728"></a>The <code>save</code> and <code>load</code> commands allow data to be written to and
+read from disk files in various formats.  The default format of files
+written by the <code>save</code> command can be controlled using the functions
+<code>default_save_options</code> and <code>save_precision</code>.
+
+   <p>As an example the following code creates a 3-by-3 matrix and saves it
+to the file ‘<samp><span class="samp">myfile.mat</span></samp>’.
+
+<pre class="example">     A = [ 1:3; 4:6; 7:9 ];
+     save myfile.mat A
+</pre>
+   <p>Once one or more variables have been saved to a file, they can be
+read into memory using the <code>load</code> command.
+
+<pre class="example">     load myfile.mat
+     A
+          -| A =
+          -|
+          -|    1   2   3
+          -|    4   5   6
+          -|    7   8   9
+</pre>
+   <!-- load-save.cc -->
+   <p><a name="doc_002dsave"></a>
+
+<div class="defun">
+— Command: <b>save</b><var> file<a name="index-save-729"></a></var><br>
+— Command: <b>save</b><var> options file<a name="index-save-730"></a></var><br>
+— Command: <b>save</b><var> options file v1 v2 <small class="dots">...</small><a name="index-save-731"></a></var><br>
+— Command: <b>save</b><var> options file -struct STRUCT f1 f2 <small class="dots">...</small><a name="index-save-732"></a></var><br>
+<blockquote><p>Save the named variables <var>v1</var>, <var>v2</var>, <small class="dots">...</small>, in the file
+<var>file</var>.  The special filename ‘<samp><span class="samp">-</span></samp>’ may be used to write
+output to the terminal.  If no variable names are listed, Octave saves
+all the variables in the current scope.  Otherwise, full variable names or
+pattern syntax can be used to specify the variables to save. 
+If the <code>-struct</code> modifier is used, fields <var>f1</var> <var>f2</var> <small class="dots">...</small>
+of the scalar structure <var>STRUCT</var> are saved as if they were variables
+with corresponding names. 
+Valid options for the <code>save</code> command are listed in the following table. 
+Options that modify the output format override the format specified by
+<code>default_save_options</code>.
+
+        <p>If save is invoked using the functional form
+
+     <pre class="example">          save ("-option1", ..., "file", "v1", ...)
+</pre>
+        <p class="noindent">then the <var>options</var>, <var>file</var>, and variable name arguments
+(<var>v1</var>, <small class="dots">...</small>) must be specified as character strings.
+
+          <dl>
+<dt><code>-ascii</code><dd>Save a single matrix in a text file without header or any other information.
+
+          <br><dt><code>-binary</code><dd>Save the data in Octave's binary data format.
+
+          <br><dt><code>-float-binary</code><dd>Save the data in Octave's binary data format but only using single
+precision.  Only use this format if you know that all the
+values to be saved can be represented in single precision.
+
+          <br><dt><code>-hdf5</code><dd>Save the data in HDF5 format. 
+(HDF5 is a free, portable binary format developed by the National
+Center for Supercomputing Applications at the University of Illinois.)
+
+          <br><dt><code>-float-hdf5</code><dd>Save the data in HDF5 format but only using single precision. 
+Only use this format if you know that all the
+values to be saved can be represented in single precision.
+
+          <br><dt><code>-V7</code><dt><code>-v7</code><dt><code>-7</code><dt><code>-mat7-binary</code><dd>Save the data in <span class="sc">matlab</span>'s v7 binary data format.
+
+          <br><dt><code>-V6</code><dt><code>-v6</code><dt><code>-6</code><dt><code>-mat</code><dt><code>-mat-binary</code><dd>Save the data in <span class="sc">matlab</span>'s v6 binary data format.
+
+          <br><dt><code>-V4</code><dt><code>-v4</code><dt><code>-4</code><dt><code>-mat4-binary</code><dd>Save the data in the binary format written by <span class="sc">matlab</span> version 4.
+
+          <br><dt><code>-text</code><dd>Save the data in Octave's text data format.  (default).
+
+          <br><dt><code>-zip</code><dt><code>-z</code><dd>Use the gzip algorithm to compress the file.  This works equally on files that
+are compressed with gzip outside of octave, and gzip can equally be used to
+convert the files for backward compatibility. 
+</dl>
+
+        <p>The list of variables to save may use wildcard patterns containing
+the following special characters:
+          <dl>
+<dt><code>?</code><dd>Match any single character.
+
+          <br><dt><code>*</code><dd>Match zero or more characters.
+
+          <br><dt><code>[ </code><var>list</var><code> ]</code><dd>Match the list of characters specified by <var>list</var>.  If the first
+character is <code>!</code> or <code>^</code>, match all characters except those
+specified by <var>list</var>.  For example, the pattern <code>[a-zA-Z]</code> will
+match all lower and upper case alphabetic characters.
+
+          <p>Wildcards may also be used in the field name specifications when using
+the <code>-struct</code> modifier (but not in the struct name itself).
+
+        </dl>
+
+        <p>Except when using the <span class="sc">matlab</span> binary data file format or the
+‘<samp><span class="samp">-ascii</span></samp>’ format, saving global
+variables also saves the global status of the variable.  If the variable
+is restored at a later time using ‘<samp><span class="samp">load</span></samp>’, it will be restored as a
+global variable.
+
+        <p>The command
+
+     <pre class="example">          save -binary data a b*
+</pre>
+        <p class="noindent">saves the variable ‘<samp><span class="samp">a</span></samp>’ and all variables beginning with ‘<samp><span class="samp">b</span></samp>’ to
+the file <samp><span class="file">data</span></samp> in Octave's binary format. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dload.html#doc_002dload">load</a>, <a href="doc_002ddefault_005fsave_005foptions.html#doc_002ddefault_005fsave_005foptions">default_save_options</a>, <a href="doc_002ddlmread.html#doc_002ddlmread">dlmread</a>, <a href="doc_002dcsvread.html#doc_002dcsvread">csvread</a>, <a href="doc_002dfread.html#doc_002dfread">fread</a>. 
+</p></blockquote></div>
+
+<!-- load-save.cc -->
+   <p><a name="doc_002dload"></a>
+
+<div class="defun">
+— Command: <b>load</b><var> file<a name="index-load-733"></a></var><br>
+— Command: <b>load</b><var> options file<a name="index-load-734"></a></var><br>
+— Command: <b>load</b><var> options file v1 v2 <small class="dots">...</small><a name="index-load-735"></a></var><br>
+— Command: <b>S</b><var> = load</var>(<var>"options", "file", "v1", "v2", <small class="dots">...</small></var>)<var><a name="index-S-736"></a></var><br>
+<blockquote><p>Load the named variables <var>v1</var>, <var>v2</var>, <small class="dots">...</small>, from the file
+<var>file</var>.  If no variables are specified then all variables found in the
+file will be loaded.  As with <code>save</code>, the list of variables to extract
+can be full names or use a pattern syntax.  The format of the file is
+automatically detected but may be overridden by supplying the appropriate
+option.
+
+        <p>If load is invoked using the functional form
+
+     <pre class="example">          load ("-option1", ..., "file", "v1", ...)
+</pre>
+        <p class="noindent">then the <var>options</var>, <var>file</var>, and variable name arguments
+(<var>v1</var>, <small class="dots">...</small>) must be specified as character strings.
+
+        <p>If a variable that is not marked as global is loaded from a file when a
+global symbol with the same name already exists, it is loaded in the
+global symbol table.  Also, if a variable is marked as global in a file
+and a local symbol exists, the local symbol is moved to the global
+symbol table and given the value from the file.
+
+        <p>If invoked with a single output argument, Octave returns data instead
+of inserting variables in the symbol table.  If the data file contains
+only numbers (TAB- or space-delimited columns), a matrix of values is
+returned.  Otherwise, <code>load</code> returns a structure with members
+ corresponding to the names of the variables in the file.
+
+        <p>The <code>load</code> command can read data stored in Octave's text and
+binary formats, and <span class="sc">matlab</span>'s binary format.  If compiled with zlib
+support, it can also load gzip-compressed files.  It will automatically
+detect the type of file and do conversion from different floating point
+formats (currently only IEEE big and little endian, though other formats
+may be added in the future).
+
+        <p>Valid options for <code>load</code> are listed in the following table.
+
+          <dl>
+<dt><code>-force</code><dd>This option is accepted for backward compatibility but is ignored. 
+Octave now overwrites variables currently in memory with
+those of the same name found in the file.
+
+          <br><dt><code>-ascii</code><dd>Force Octave to assume the file contains columns of numbers in text format
+without any header or other information.  Data in the file will be loaded
+as a single numeric matrix with the name of the variable derived from the
+name of the file.
+
+          <br><dt><code>-binary</code><dd>Force Octave to assume the file is in Octave's binary format.
+
+          <br><dt><code>-hdf5</code><dd>Force Octave to assume the file is in HDF5 format. 
+(HDF5 is a free, portable binary format developed by the National
+Center for Supercomputing Applications at the University of Illinois.) 
+Note that Octave can read HDF5 files not created by itself, but may
+skip some datasets in formats that it cannot support.
+
+          <br><dt><code>-import</code><dd>This option is accepted for backward compatibility but is ignored. 
+Octave can now support multi-dimensional HDF data and automatically
+modifies variable names if they are invalid Octave identifiers.
+
+          <br><dt><code>-mat</code><dt><code>-mat-binary</code><dt><code>-6</code><dt><code>-v6</code><dt><code>-7</code><dt><code>-v7</code><dd>Force Octave to assume the file is in <span class="sc">matlab</span>'s version 6 or 7 binary
+format.
+
+          <br><dt><code>-mat4-binary</code><dt><code>-4</code><dt><code>-v4</code><dt><code>-V4</code><dd>Force Octave to assume the file is in the binary format written by
+<span class="sc">matlab</span> version 4.
+
+          <br><dt><code>-text</code><dd>Force Octave to assume the file is in Octave's text format. 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsave.html#doc_002dsave">save</a>, <a href="doc_002ddlmwrite.html#doc_002ddlmwrite">dlmwrite</a>, <a href="doc_002dcsvwrite.html#doc_002dcsvwrite">csvwrite</a>, <a href="doc_002dfwrite.html#doc_002dfwrite">fwrite</a>. 
+</p></blockquote></div>
+
+   <p>There are three functions that modify the behavior of <code>save</code>.
+
+<!-- load-save.cc -->
+   <p><a name="doc_002ddefault_005fsave_005foptions"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>default_save_options</b> ()<var><a name="index-default_005fsave_005foptions-737"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>default_save_options</b> (<var>new_val</var>)<var><a name="index-default_005fsave_005foptions-738"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the default options
+for the <code>save</code> command, and defines the default format. 
+Typical values include <code>"-ascii"</code>, <code>"-text -zip"</code>. 
+The default value is <code>-text</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsave.html#doc_002dsave">save</a>. 
+</p></blockquote></div>
+
+<!-- ls-oct-ascii.cc -->
+   <p><a name="doc_002dsave_005fprecision"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>save_precision</b> ()<var><a name="index-save_005fprecision-739"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>save_precision</b> (<var>new_val</var>)<var><a name="index-save_005fprecision-740"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the number of
+digits to keep when saving data in text format. 
+</p></blockquote></div>
+
+<!-- load-save.cc -->
+   <p><a name="doc_002dsave_005fheader_005fformat_005fstring"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>save_header_format_string</b> ()<var><a name="index-save_005fheader_005fformat_005fstring-741"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>save_header_format_string</b> (<var>new_val</var>)<var><a name="index-save_005fheader_005fformat_005fstring-742"></a></var><br>
+<blockquote><p>Query or set the internal variable that specifies the format
+string used for the comment line written at the beginning of
+text-format data files saved by Octave.  The format string is
+passed to <code>strftime</code> and should begin with the character
+‘<samp><span class="samp">#</span></samp>’ and contain no newline characters.  If the value of
+<code>save_header_format_string</code> is the empty string,
+the header comment is omitted from text-format data files.  The
+default value is
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">          "# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER at HOST>"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dsave.html#doc_002dsave">save</a>. 
+</p></blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dnative_005ffloat_005fformat"></a>
+
+<div class="defun">
+— Built-in Function:  <b>native_float_format</b> ()<var><a name="index-native_005ffloat_005fformat-743"></a></var><br>
+<blockquote><p>Return the native floating point format as a string
+</p></blockquote></div>
+
+   <p>It is possible to write data to a file in a similar way to the
+<code>disp</code> function for writing data to the screen.  The <code>fdisp</code>
+works just like <code>disp</code> except its first argument is a file pointer
+as created by <code>fopen</code>.  As an example, the following code writes
+to data ‘<samp><span class="samp">myfile.txt</span></samp>’.
+
+<pre class="example">     fid = fopen ("myfile.txt", "w");
+     fdisp (fid, "3/8 is ");
+     fdisp (fid, 3/8);
+     fclose (fid);
+</pre>
+   <p class="noindent">See <a href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">Opening and Closing Files</a>, for details on how to use <code>fopen</code>
+and <code>fclose</code>.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002dfdisp"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fdisp</b> (<var>fid, x</var>)<var><a name="index-fdisp-744"></a></var><br>
+<blockquote><p>Display the value of <var>x</var> on the stream <var>fid</var>.  For example,
+
+     <pre class="example">          fdisp (stdout, "The value of pi is:"), fdisp (stdout, pi)
+          
+               -| the value of pi is:
+               -| 3.1416
+</pre>
+        <p class="noindent">Note that the output from <code>fdisp</code> always ends with a newline. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddisp.html#doc_002ddisp">disp</a>. 
+</p></blockquote></div>
+
+   <p>Octave can also read and write matrices text files such as comma
+separated lists.
+
+<!-- ./io/dlmwrite.m -->
+   <p><a name="doc_002ddlmwrite"></a>
+
+<div class="defun">
+— Function File:  <b>dlmwrite</b> (<var>file, a</var>)<var><a name="index-dlmwrite-745"></a></var><br>
+— Function File:  <b>dlmwrite</b> (<var>file, a, delim, r, c</var>)<var><a name="index-dlmwrite-746"></a></var><br>
+— Function File:  <b>dlmwrite</b> (<var>file, a, key, val <small class="dots">...</small></var>)<var><a name="index-dlmwrite-747"></a></var><br>
+— Function File:  <b>dlmwrite</b> (<var>file, a, "-append", <small class="dots">...</small></var>)<var><a name="index-dlmwrite-748"></a></var><br>
+<blockquote><p>Write the matrix <var>a</var> to the named file using delimiters.
+
+        <p>The parameter <var>delim</var> specifies the delimiter to use to separate
+values on a row.
+
+        <p>The value of <var>r</var> specifies the number of delimiter-only lines to
+add to the start of the file.
+
+        <p>The value of <var>c</var> specifies the number of delimiters to prepend to
+each line of data.
+
+        <p>If the argument <code>"-append"</code> is given, append to the end of the
+<var>file</var>.
+
+        <p>In addition, the following keyword value pairs may appear at the end
+of the argument list:
+          <dl>
+<dt><code>"append"</code><dd>Either ‘<samp><span class="samp">"on"</span></samp>’ or ‘<samp><span class="samp">"off"</span></samp>’.  See ‘<samp><span class="samp">"-append"</span></samp>’ above.
+
+          <br><dt><code>"delimiter"</code><dd>See <var>delim</var> above.
+
+          <br><dt><code>"newline"</code><dd>The character(s) to use to separate each row.  Three special cases
+exist for this option.  ‘<samp><span class="samp">"unix"</span></samp>’ is changed into '\n',
+‘<samp><span class="samp">"pc"</span></samp>’ is changed into '\r\n', and ‘<samp><span class="samp">"mac"</span></samp>’ is changed
+into '\r'.  Other values for this option are kept as is.
+
+          <br><dt><code>"roffset"</code><dd>See <var>r</var> above.
+
+          <br><dt><code>"coffset"</code><dd>See <var>c</var> above.
+
+          <br><dt><code>"precision"</code><dd>The precision to use when writing the file.  It can either be a
+format string (as used by fprintf) or a number of significant digits. 
+</dl>
+
+     <pre class="example">          dlmwrite ("file.csv", reshape (1:16, 4, 4));
+</pre>
+        <pre class="example">          dlmwrite ("file.tex", a, "delimiter", "&", "newline", "\\n")
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddlmread.html#doc_002ddlmread">dlmread</a>, <a href="doc_002dcsvread.html#doc_002dcsvread">csvread</a>, <a href="doc_002dcsvwrite.html#doc_002dcsvwrite">csvwrite</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dlmread.cc -->
+   <p><a name="doc_002ddlmread"></a>
+
+<div class="defun">
+— Loadable Function: <var>data</var> = <b>dlmread</b> (<var>file</var>)<var><a name="index-dlmread-749"></a></var><br>
+— Loadable Function: <var>data</var> = <b>dlmread</b> (<var>file, sep</var>)<var><a name="index-dlmread-750"></a></var><br>
+— Loadable Function: <var>data</var> = <b>dlmread</b> (<var>file, sep, r0, c0</var>)<var><a name="index-dlmread-751"></a></var><br>
+— Loadable Function: <var>data</var> = <b>dlmread</b> (<var>file, sep, range</var>)<var><a name="index-dlmread-752"></a></var><br>
+<blockquote><p>Read the matrix <var>data</var> from a text file.  If not defined the separator
+between fields is determined from the file itself.  Otherwise the
+separation character is defined by <var>sep</var>.
+
+        <p>Given two scalar arguments <var>r0</var> and <var>c0</var>, these define the starting
+row and column of the data to be read.  These values are indexed from zero,
+such that the first row corresponds to an index of zero.
+
+        <p>The <var>range</var> parameter must be a 4 element vector containing the upper
+left and lower right corner <code>[</code><var>R0</var><code>,</code><var>C0</var><code>,</code><var>R1</var><code>,</code><var>C1</var><code>]</code> or
+a spreadsheet style range such as 'A2..Q15'.  The lowest index value is zero. 
+</p></blockquote></div>
+
+<!-- ./io/csvwrite.m -->
+   <p><a name="doc_002dcsvwrite"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>csvwrite</b> (<var>filename, x</var>)<var><a name="index-csvwrite-753"></a></var><br>
+<blockquote><p>Write the matrix <var>x</var> to a file.
+
+        <p>This function is equivalent to
+     <pre class="example">          dlmwrite (<var>filename</var>, <var>x</var>, ",", ...)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddlmread.html#doc_002ddlmread">dlmread</a>, <a href="doc_002ddlmwrite.html#doc_002ddlmwrite">dlmwrite</a>, <a href="doc_002dcsvread.html#doc_002dcsvread">csvread</a>. 
+</p></blockquote></div>
+
+<!-- ./io/csvread.m -->
+   <p><a name="doc_002dcsvread"></a>
+
+<div class="defun">
+— Function File: <var>x</var> = <b>csvread</b> (<var>filename</var>)<var><a name="index-csvread-754"></a></var><br>
+<blockquote><p>Read the matrix <var>x</var> from a file.
+
+        <p>This function is equivalent to
+     <pre class="example">          dlmread (<var>filename</var>, "," , ...)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddlmread.html#doc_002ddlmread">dlmread</a>, <a href="doc_002ddlmwrite.html#doc_002ddlmwrite">dlmwrite</a>, <a href="doc_002dcsvwrite.html#doc_002dcsvwrite">csvwrite</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Simple-Output.html b/doc/interpreter/HTML/Simple-Output.html
new file mode 100644
index 0000000..cb0ecf1
--- /dev/null
+++ b/doc/interpreter/HTML/Simple-Output.html
@@ -0,0 +1,77 @@
+<html lang="en">
+<head>
+<title>Simple Output - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Opening-and-Closing-Files.html#Opening-and-Closing-Files" title="Opening and Closing Files">
+<link rel="next" href="Line_002dOriented-Input.html#Line_002dOriented-Input" title="Line-Oriented Input">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Simple-Output"></a>
+Next: <a rel="next" accesskey="n" href="Line_002dOriented-Input.html#Line_002dOriented-Input">Line-Oriented Input</a>,
+Previous: <a rel="previous" accesskey="p" href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">Opening and Closing Files</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.2 Simple Output</h4>
+
+<p>Once a file has been opened for writing a string can be written to the
+file using the <code>fputs</code> function.  The following example shows
+how to write the string ‘<samp><span class="samp">Free Software is needed for Free Science</span></samp>’
+to the file ‘<samp><span class="samp">free.txt</span></samp>’.
+
+<pre class="example">     filename = "free.txt";
+     fid = fopen (filename, "w");
+     fputs (fid, "Free Software is needed for Free Science");
+     fclose (fid);
+</pre>
+   <!-- file-io.cc -->
+   <p><a name="doc_002dfputs"></a>
+
+<div class="defun">
+— Built-in Function:  <b>fputs</b> (<var>fid, string</var>)<var><a name="index-fputs-777"></a></var><br>
+<blockquote><p>Write a string to a file with no formatting.
+
+        <p>Return a non-negative number on success and EOF on error. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dscanf.html#doc_002dscanf">scanf</a>, <a href="doc_002dsscanf.html#doc_002dsscanf">sscanf</a>, <a href="doc_002dfread.html#doc_002dfread">fread</a>, <a href="doc_002dfprintf.html#doc_002dfprintf">fprintf</a>, <a href="doc_002dfgets.html#doc_002dfgets">fgets</a>, <a href="doc_002dfscanf.html#doc_002dfscanf">fscanf</a>. 
+</p></blockquote></div>
+
+   <p>A function much similar to <code>fputs</code> is available for writing data
+to the screen.  The <code>puts</code> function works just like <code>fputs</code>
+except it doesn't take a file pointer as its input.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dputs"></a>
+
+<div class="defun">
+— Built-in Function:  <b>puts</b> (<var>string</var>)<var><a name="index-puts-778"></a></var><br>
+<blockquote><p>Write a string to the standard output with no formatting.
+
+        <p>Return a non-negative number on success and EOF on error. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Single-Line-Comments.html b/doc/interpreter/HTML/Single-Line-Comments.html
new file mode 100644
index 0000000..b5dafee
--- /dev/null
+++ b/doc/interpreter/HTML/Single-Line-Comments.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Single Line Comments - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Comments.html#Comments" title="Comments">
+<link rel="next" href="Block-Comments.html#Block-Comments" title="Block Comments">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Single-Line-Comments"></a>
+Next: <a rel="next" accesskey="n" href="Block-Comments.html#Block-Comments">Block Comments</a>,
+Up: <a rel="up" accesskey="u" href="Comments.html#Comments">Comments</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.7.1 Single Line Comments</h4>
+
+<p><a name="index-g_t_0040samp_007b_0023_007d-162"></a><a name="index-g_t_0040samp_007b_0025_007d-163"></a>
+In the Octave language, a comment starts with either the sharp sign
+character, ‘<samp><span class="samp">#</span></samp>’, or the percent symbol ‘<samp><span class="samp">%</span></samp>’ and continues to the
+end of the line.  Any text following the sharp sign or percent symbol is
+ignored by the Octave interpreter and not executed.  The following example
+shows whole line and partial line comments.
+<pre class="example">     function countdown
+       # Count down for main rocket engines
+       disp(3);
+       disp(2);
+       disp(1);
+       disp("Blast Off!");  # Rocket leaves pad
+     endfunction
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Single-Precision-Data-Types.html b/doc/interpreter/HTML/Single-Precision-Data-Types.html
new file mode 100644
index 0000000..e1c7957
--- /dev/null
+++ b/doc/interpreter/HTML/Single-Precision-Data-Types.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Single Precision Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="prev" href="Ranges.html#Ranges" title="Ranges">
+<link rel="next" href="Integer-Data-Types.html#Integer-Data-Types" title="Integer Data Types">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Single-Precision-Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a>,
+Previous: <a rel="previous" accesskey="p" href="Ranges.html#Ranges">Ranges</a>,
+Up: <a rel="up" accesskey="u" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">4.3 Single Precision Data Types</h3>
+
+<p>Octave includes support for single precision data types, and most of the
+functions in Octave accept single precision values and return single
+precision answers.  A single precision variable is created with the
+<code>single</code> function.
+
+<!-- ov-flt-re-mat.cc -->
+   <p><a name="doc_002dsingle"></a>
+
+<div class="defun">
+— Built-in Function:  <b>single</b> (<var>x</var>)<var><a name="index-single-234"></a></var><br>
+<blockquote><p>Convert <var>x</var> to single precision type. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddouble.html#doc_002ddouble">double</a>. 
+</p></blockquote></div>
+
+   <p>for example
+
+<pre class="example">     sngl = single (rand (2, 2))
+           sngl =
+             0.37569   0.92982
+             0.11962   0.50876
+     class (sngl)
+          single
+</pre>
+   <p>Many functions can also return single precision values directly.  For
+example
+
+<pre class="example">     ones (2, 2, "single")
+     zeros (2, 2, "single")
+     eye (2, 2,  "single")
+     rand (2, 2, "single")
+     NaN (2, 2, "single")
+     NA (2, 2, "single")
+     Inf (2, 2, "single")
+</pre>
+   <p class="noindent">will all return single precision matrices.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sparse-Functions.html b/doc/interpreter/HTML/Sparse-Functions.html
new file mode 100644
index 0000000..4731ea6
--- /dev/null
+++ b/doc/interpreter/HTML/Sparse-Functions.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Sparse Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Operators-and-Functions.html#Operators-and-Functions" title="Operators and Functions">
+<link rel="next" href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions" title="Return Types of Operators and Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sparse-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions">Return Types of Operators and Functions</a>,
+Up: <a rel="up" accesskey="u" href="Operators-and-Functions.html#Operators-and-Functions">Operators and Functions</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">21.1.4.1 Sparse Functions</h5>
+
+<p>An important consideration in the use of the sparse functions of
+Octave is that many of the internal functions of Octave, such as
+<dfn>diag</dfn>, cannot accept sparse matrices as an input.  The sparse
+implementation in Octave therefore uses the <dfn>dispatch</dfn>
+function to overload the normal Octave functions with equivalent
+functions that work with sparse matrices.  However, at any time the
+sparse matrix specific version of the function can be used by
+explicitly calling its function name.
+
+   <p>The table below lists all of the sparse functions of Octave.  Note that
+the names of the
+specific sparse forms of the functions are typically the same as
+the general versions with a <dfn>sp</dfn> prefix.  In the table below, and the
+rest of this article the specific sparse versions of the functions are
+used.
+
+<!-- Table includes in comments the missing sparse functions -->
+     <dl>
+<dt>Generate sparse matrices:<dd>  <dfn>spalloc</dfn>, <dfn>spdiags</dfn>, <dfn>speye</dfn>, <dfn>sprand</dfn>,
+  <dfn>sprandn</dfn>, <dfn>sprandsym</dfn>
+
+     <br><dt>Sparse matrix conversion:<dd>  <dfn>full</dfn>, <dfn>sparse</dfn>, <dfn>spconvert</dfn>
+
+     <br><dt>Manipulate sparse matrices<dd>  <dfn>issparse</dfn>, <dfn>nnz</dfn>, <dfn>nonzeros</dfn>, <dfn>nzmax</dfn>,
+  <dfn>spfun</dfn>, <dfn>spones</dfn>, <dfn>spy</dfn>
+
+     <br><dt>Graph Theory:<dd>  <dfn>etree</dfn>, <dfn>etreeplot</dfn>, <dfn>gplot</dfn>,
+  <dfn>treeplot</dfn>
+<!-- @dfn{treelayout} -->
+
+     <br><dt>Sparse matrix reordering:<dd>  <dfn>amd</dfn>, <dfn>ccolamd</dfn>, <dfn>colamd</dfn>, <dfn>colperm</dfn>, <dfn>csymamd</dfn>,
+  <dfn>dmperm</dfn>, <dfn>symamd</dfn>, <dfn>randperm</dfn>, <dfn>symrcm</dfn>
+
+     <br><dt>Linear algebra:<dd>  <dfn>condest</dfn>, <dfn>eigs</dfn>, <dfn>matrix_type</dfn>, <dfn>normest</dfn>, <dfn>sprank</dfn>,
+  <dfn>spaugment</dfn>, <dfn>svds</dfn>
+
+     <br><dt>Iterative techniques:<dd>  <dfn>luinc</dfn>, <dfn>pcg</dfn>, <dfn>pcr</dfn>
+<!-- @dfn{bicg}, @dfn{bicgstab}, @dfn{cholinc}, @dfn{cgs}, @dfn{gmres}, -->
+<!-- @dfn{lsqr}, @dfn{minres}, @dfn{qmr}, @dfn{symmlq} -->
+
+     <br><dt>Miscellaneous:<dd>  <dfn>spparms</dfn>, <dfn>symbfact</dfn>, <dfn>spstats</dfn>
+</dl>
+
+   <p>In addition all of the standard Octave mapper functions (i.e., basic
+math functions that take a single argument) such as <dfn>abs</dfn>, etc. 
+can accept sparse matrices.  The reader is referred to the documentation
+supplied with these functions within Octave itself for further
+details.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sparse-Linear-Algebra.html b/doc/interpreter/HTML/Sparse-Linear-Algebra.html
new file mode 100644
index 0000000..1991ae5
--- /dev/null
+++ b/doc/interpreter/HTML/Sparse-Linear-Algebra.html
@@ -0,0 +1,603 @@
+<html lang="en">
+<head>
+<title>Sparse Linear Algebra - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices.html#Sparse-Matrices" title="Sparse Matrices">
+<link rel="prev" href="Basics.html#Basics" title="Basics">
+<link rel="next" href="Iterative-Techniques.html#Iterative-Techniques" title="Iterative Techniques">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sparse-Linear-Algebra"></a>
+Next: <a rel="next" accesskey="n" href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a>,
+Previous: <a rel="previous" accesskey="p" href="Basics.html#Basics">Basics</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">21.2 Linear Algebra on Sparse Matrices</h3>
+
+<p>Octave includes a polymorphic solver for sparse matrices, where
+the exact solver used to factorize the matrix, depends on the properties
+of the sparse matrix itself.  Generally, the cost of determining the matrix type
+is small relative to the cost of factorizing the matrix itself, but in any
+case the matrix type is cached once it is calculated, so that it is not
+re-determined each time it is used in a linear equation.
+
+   <p>The selection tree for how the linear equation is solve is
+
+     <ol type=1 start=1>
+<li>If the matrix is diagonal, solve directly and goto 8
+
+     <li>If the matrix is a permuted diagonal, solve directly taking into
+account the permutations.  Goto 8
+
+     <li>If the matrix is square, banded and if the band density is less
+than that given by <code>spparms ("bandden")</code> continue, else goto 4.
+
+          <ol type=a start=1>
+<li>If the matrix is tridiagonal and the right-hand side is not sparse
+continue, else goto 3b.
+
+               <ol type=1 start=1>
+<li>If the matrix is hermitian, with a positive real diagonal, attempt
+      Cholesky factorization using <span class="sc">lapack</span> xPTSV.
+
+               <li>If the above failed or the matrix is not hermitian with a positive
+      real diagonal use Gaussian elimination with pivoting using
+      <span class="sc">lapack</span> xGTSV, and goto 8.
+               </ol>
+
+          <li>If the matrix is hermitian with a positive real diagonal, attempt
+      Cholesky factorization using <span class="sc">lapack</span> xPBTRF.
+
+          <li>if the above failed or the matrix is not hermitian with a positive
+      real diagonal use Gaussian elimination with pivoting using
+      <span class="sc">lapack</span> xGBTRF, and goto 8.
+          </ol>
+
+     <li>If the matrix is upper or lower triangular perform a sparse forward
+or backward substitution, and goto 8
+
+     <li>If the matrix is a upper triangular matrix with column permutations
+or lower triangular matrix with row permutations, perform a sparse forward
+or backward substitution, and goto 8
+
+     <li>If the matrix is square, hermitian with a real positive diagonal, attempt
+sparse Cholesky factorization using CHOLMOD.
+
+     <li>If the sparse Cholesky factorization failed or the matrix is not
+hermitian with a real positive diagonal, and the matrix is square, factorize
+using UMFPACK.
+
+     <li>If the matrix is not square, or any of the previous solvers flags
+a singular or near singular matrix, find a minimum norm solution using
+CXSPARSE<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>.
+        </ol>
+
+   <p>The band density is defined as the number of non-zero values in the matrix
+divided by the number of non-zero values in the matrix.  The banded matrix
+solvers can be entirely disabled by using <dfn>spparms</dfn> to set <code>bandden</code>
+to 1 (i.e., <code>spparms ("bandden", 1)</code>).
+
+   <p>The QR solver factorizes the problem with a Dulmage-Mendelsohn, to
+separate the problem into blocks that can be treated as over-determined,
+multiple well determined blocks, and a final over-determined block.  For
+matrices with blocks of strongly connected nodes this is a big win as
+LU decomposition can be used for many blocks.  It also significantly
+improves the chance of finding a solution to over-determined problems
+rather than just returning a vector of <dfn>NaN</dfn>'s.
+
+   <p>All of the solvers above, can calculate an estimate of the condition
+number.  This can be used to detect numerical stability problems in the
+solution and force a minimum norm solution to be used.  However, for
+narrow banded, triangular or diagonal matrices, the cost of
+calculating the condition number is significant, and can in fact
+exceed the cost of factoring the matrix.  Therefore the condition
+number is not calculated in these cases, and Octave relies on simpler
+techniques to detect singular matrices or the underlying <span class="sc">lapack</span> code in
+the case of banded matrices.
+
+   <p>The user can force the type of the matrix with the <code>matrix_type</code>
+function.  This overcomes the cost of discovering the type of the matrix. 
+However, it should be noted that identifying the type of the matrix incorrectly
+will lead to unpredictable results, and so <code>matrix_type</code> should be
+used with care.
+
+<!-- ./sparse/normest.m -->
+   <p><a name="doc_002dnormest"></a>
+
+<div class="defun">
+— Function File: [<var>n</var>, <var>c</var>] = <b>normest</b> (<var>a, tol</var>)<var><a name="index-normest-1709"></a></var><br>
+<blockquote><p>Estimate the 2-norm of the matrix <var>a</var> using a power series
+analysis.  This is typically used for large matrices, where the cost
+of calculating the <code>norm (</code><var>a</var><code>)</code> is prohibitive and an approximation
+to the 2-norm is acceptable.
+
+        <p><var>tol</var> is the tolerance to which the 2-norm is calculated.  By default
+<var>tol</var> is 1e-6.  <var>c</var> returns the number of iterations needed for
+<code>normest</code> to converge. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/onenormest.m -->
+   <p><a name="doc_002donenormest"></a>
+
+<div class="defun">
+— Function File: [<var>est</var>, <var>v</var>, <var>w</var>, <var>iter</var>] = <b>onenormest</b> (<var>a, t</var>)<var><a name="index-onenormest-1710"></a></var><br>
+— Function File: [<var>est</var>, <var>v</var>, <var>w</var>, <var>iter</var>] = <b>onenormest</b> (<var>apply, apply_t, n, t</var>)<var><a name="index-onenormest-1711"></a></var><br>
+<blockquote>
+        <p>Apply Higham and Tisseur's randomized block 1-norm estimator to
+matrix <var>a</var> using <var>t</var> test vectors.  If <var>t</var> exceeds 5, then
+only 5 test vectors are used.
+
+        <p>If the matrix is not explicit, e.g., when estimating the norm of
+<code>inv (</code><var>A</var><code>)</code> given an LU factorization, <code>onenormest</code> applies
+<var>A</var> and its conjugate transpose through a pair of functions
+<var>apply</var> and <var>apply_t</var>, respectively, to a dense matrix of size
+<var>n</var> by <var>t</var>.  The implicit version requires an explicit dimension
+<var>n</var>.
+
+        <p>Returns the norm estimate <var>est</var>, two vectors <var>v</var> and
+<var>w</var> related by norm
+<code>(</code><var>w</var><code>, 1) = </code><var>est</var><code> * norm (</code><var>v</var><code>, 1)</code>,
+and the number of iterations <var>iter</var>.  The number of
+iterations is limited to 10 and is at least 2.
+
+        <p>References:
+          <ul>
+<li>Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201. 
+<a href="http://dx.doi.org/10.1137/S0895479899356080">http://dx.doi.org/10.1137/S0895479899356080</a>
+<li>Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." <a href="http://citeseer.ist.psu.edu/223007.html">http://citeseer.ist.psu.edu/223007.html</a>
+</ul>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcondest.html#doc_002dcondest">condest</a>, <a href="doc_002dnorm.html#doc_002dnorm">norm</a>, <a href="doc_002dcond.html#doc_002dcond">cond</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/condest.m -->
+   <p><a name="doc_002dcondest"></a>
+
+<div class="defun">
+— Function File: [<var>est</var>, <var>v</var>] = <b>condest</b> (<var>a, t</var>)<var><a name="index-condest-1712"></a></var><br>
+— Function File: [<var>est</var>, <var>v</var>] = <b>condest</b> (<var>a, solve, solve_t, t</var>)<var><a name="index-condest-1713"></a></var><br>
+— Function File: [<var>est</var>, <var>v</var>] = <b>condest</b> (<var>apply, apply_t, solve, solve_t, n, t</var>)<var><a name="index-condest-1714"></a></var><br>
+<blockquote>
+        <p>Estimate the 1-norm condition number of a matrix <var>A</var>
+using <var>t</var> test vectors using a randomized 1-norm estimator. 
+If <var>t</var> exceeds 5, then only 5 test vectors are used.
+
+        <p>If the matrix is not explicit, e.g., when estimating the condition
+number of <var>a</var> given an LU factorization, <code>condest</code> uses the
+following functions:
+
+          <dl>
+<dt><var>apply</var><dd><code>A*x</code> for a matrix <code>x</code> of size <var>n</var> by <var>t</var>. 
+<br><dt><var>apply_t</var><dd><code>A'*x</code> for a matrix <code>x</code> of size <var>n</var> by <var>t</var>. 
+<br><dt><var>solve</var><dd><code>A \ b</code> for a matrix <code>b</code> of size <var>n</var> by <var>t</var>. 
+<br><dt><var>solve_t</var><dd><code>A' \ b</code> for a matrix <code>b</code> of size <var>n</var> by <var>t</var>. 
+</dl>
+
+        <p>The implicit version requires an explicit dimension <var>n</var>.
+
+        <p><code>condest</code> uses a randomized algorithm to approximate
+the 1-norms.
+
+        <p><code>condest</code> returns the 1-norm condition estimate <var>est</var> and
+a vector <var>v</var> satisfying <code>norm (A*v, 1) == norm (A, 1) * norm
+(</code><var>v</var><code>, 1) / </code><var>est</var>.  When <var>est</var> is large, <var>v</var> is an
+approximate null vector.
+
+        <p>References:
+          <ul>
+<li>Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201. 
+<a href="http://dx.doi.org/10.1137/S0895479899356080">http://dx.doi.org/10.1137/S0895479899356080</a>
+<li>Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." <a href="http://citeseer.ist.psu.edu/223007.html">http://citeseer.ist.psu.edu/223007.html</a>
+</ul>
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcond.html#doc_002dcond">cond</a>, <a href="doc_002dnorm.html#doc_002dnorm">norm</a>, <a href="doc_002donenormest.html#doc_002donenormest">onenormest</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/spparms.cc -->
+   <p><a name="doc_002dspparms"></a>
+
+<div class="defun">
+— Loadable Function:  <b>spparms</b> ()<var><a name="index-spparms-1715"></a></var><br>
+— Loadable Function: <var>vals</var> = <b>spparms</b> ()<var><a name="index-spparms-1716"></a></var><br>
+— Loadable Function: [<var>keys</var>, <var>vals</var>] = <b>spparms</b> ()<var><a name="index-spparms-1717"></a></var><br>
+— Loadable Function: <var>val</var> = <b>spparms</b> (<var>key</var>)<var><a name="index-spparms-1718"></a></var><br>
+— Loadable Function:  <b>spparms</b> (<var>vals</var>)<var><a name="index-spparms-1719"></a></var><br>
+— Loadable Function:  <b>spparms</b> (<var>'defaults'</var>)<var><a name="index-spparms-1720"></a></var><br>
+— Loadable Function:  <b>spparms</b> (<var>'tight'</var>)<var><a name="index-spparms-1721"></a></var><br>
+— Loadable Function:  <b>spparms</b> (<var>key, val</var>)<var><a name="index-spparms-1722"></a></var><br>
+<blockquote><p>Sets or displays the parameters used by the sparse solvers and factorization
+functions.  The first four calls above get information about the current
+settings, while the others change the current settings.  The parameters are
+stored as pairs of keys and values, where the values are all floats and the
+keys are one of the following strings:
+
+          <dl>
+<dt><code>spumoni</code><dd>Printing level of debugging information of the solvers (default 0)
+<br><dt><code>ths_rel</code><dd>Included for compatibility.  Not used.  (default 1)
+<br><dt><code>ths_abs</code><dd>Included for compatibility.  Not used.  (default 1)
+<br><dt><code>exact_d</code><dd>Included for compatibility.  Not used.  (default 0)
+<br><dt><code>supernd</code><dd>Included for compatibility.  Not used.  (default 3)
+<br><dt><code>rreduce</code><dd>Included for compatibility.  Not used.  (default 3)
+<br><dt><code>wh_frac</code><dd>Included for compatibility.  Not used.  (default 0.5)
+<br><dt><code>autommd</code><dd>Flag whether the LU/QR and the '\' and '/' operators will automatically
+use the sparsity preserving mmd functions (default 1)
+<br><dt><code>autoamd</code><dd>Flag whether the LU and the '\' and '/' operators will automatically
+use the sparsity preserving amd functions (default 1)
+<br><dt><code>piv_tol</code><dd>The pivot tolerance of the UMFPACK solvers (default 0.1)
+<br><dt><code>sym_tol</code><dd>The pivot tolerance of the UMFPACK symmetric solvers (default 0.001)
+<br><dt><code>bandden</code><dd>The density of non-zero elements in a banded matrix before it is treated
+by the <span class="sc">lapack</span> banded solvers (default 0.5)
+<br><dt><code>umfpack</code><dd>Flag whether the UMFPACK or mmd solvers are used for the LU, '\' and
+'/' operations (default 1)
+</dl>
+
+        <p>The value of individual keys can be set with <code>spparms (</code><var>key</var><code>,
+</code><var>val</var><code>)</code>.  The default values can be restored with the special keyword
+'defaults'.  The special keyword 'tight' can be used to set the mmd solvers
+to attempt for a sparser solution at the potential cost of longer running
+time. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/dmperm.cc -->
+   <p><a name="doc_002dsprank"></a>
+
+<div class="defun">
+— Loadable Function: <var>p</var> = <b>sprank</b> (<var>s</var>)<var><a name="index-sprank-1723"></a></var><br>
+<blockquote>
+        <p><a name="index-Structural-Rank-1724"></a>Calculates the structural rank of a sparse matrix <var>s</var>.  Note that
+only the structure of the matrix is used in this calculation based on
+a Dulmage-Mendelsohn permutation to block triangular form.  As such the numerical
+rank of the matrix <var>s</var> is bounded by <code>sprank (</code><var>s</var><code>) >=
+rank (</code><var>s</var><code>)</code>.  Ignoring floating point errors <code>sprank (</code><var>s</var><code>) ==
+rank (</code><var>s</var><code>)</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddmperm.html#doc_002ddmperm">dmperm</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/symbfact.cc -->
+   <p><a name="doc_002dsymbfact"></a>
+
+<div class="defun">
+— Loadable Function: [<var>count</var>, <var>h</var>, <var>parent</var>, <var>post</var>, <var>r</var>] = <b>symbfact</b> (<var>s, typ, mode</var>)<var><a name="index-symbfact-1725"></a></var><br>
+<blockquote>
+        <p>Performs a symbolic factorization analysis on the sparse matrix <var>s</var>. 
+Where
+
+          <dl>
+<dt><var>s</var><dd><var>s</var> is a complex or real sparse matrix.
+
+          <br><dt><var>typ</var><dd>Is the type of the factorization and can be one of
+
+               <dl>
+<dt><code>sym</code><dd>Factorize <var>s</var>.  This is the default.
+
+               <br><dt><code>col</code><dd>Factorize <var>s</var><code>' * </code><var>s</var>. 
+<br><dt><code>row</code><dd>Factorize <var>s</var><code> * </code><var>s</var><code>'</code>. 
+<br><dt><code>lo</code><dd>Factorize <var>s</var><code>'</code>
+</dl>
+
+          <br><dt><var>mode</var><dd>The default is to return the Cholesky factorization for <var>r</var>, and if
+<var>mode</var> is 'L', the conjugate transpose of the Cholesky factorization
+is returned.  The conjugate transpose version is faster and uses less
+memory, but returns the same values for <var>count</var>, <var>h</var>, <var>parent</var>
+and <var>post</var> outputs. 
+</dl>
+
+        <p>The output variables are
+
+          <dl>
+<dt><var>count</var><dd>The row counts of the Cholesky factorization as determined by <var>typ</var>.
+
+          <br><dt><var>h</var><dd>The height of the elimination tree.
+
+          <br><dt><var>parent</var><dd>The elimination tree itself.
+
+          <br><dt><var>post</var><dd>A sparse boolean matrix whose structure is that of the Cholesky
+factorization as determined by <var>typ</var>. 
+</dl>
+        </p></blockquote></div>
+
+   <p>For non square matrices, the user can also utilize the <code>spaugment</code>
+function to find a least squares solution to a linear equation.
+
+<!-- ./sparse/spaugment.m -->
+   <p><a name="doc_002dspaugment"></a>
+
+<div class="defun">
+— Function File: <var>s</var> = <b>spaugment</b> (<var>a, c</var>)<var><a name="index-spaugment-1726"></a></var><br>
+<blockquote><p>Creates the augmented matrix of <var>a</var>.  This is given by
+
+     <pre class="example">          [<var>c</var> * eye(<var>m</var>, <var>m</var>),<var>a</var>; <var>a</var>', zeros(<var>n</var>,
+          <var>n</var>)]
+</pre>
+        <p class="noindent">This is related to the least squares solution of
+<var>a</var><code> \\ </code><var>b</var>, by
+
+     <pre class="example">          <var>s</var> * [ <var>r</var> / <var>c</var>; x] = [<var>b</var>, zeros(<var>n</var>,
+          columns(<var>b</var>)]
+</pre>
+        <p class="noindent">where <var>r</var> is the residual error
+
+     <pre class="example">          <var>r</var> = <var>b</var> - <var>a</var> * <var>x</var>
+</pre>
+        <p>As the matrix <var>s</var> is symmetric indefinite it can be factorized
+with <code>lu</code>, and the minimum norm solution can therefore be found
+without the need for a <code>qr</code> factorization.  As the residual
+error will be <code>zeros (</code><var>m</var><code>, </code><var>m</var><code>)</code> for under determined
+problems, and example can be
+
+     <pre class="example">          m = 11; n = 10; mn = max(m ,n);
+          a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],
+                       [-1, 0, 1], m, n);
+          x0 = a \ ones (m,1);
+          s = spaugment (a);
+          [L, U, P, Q] = lu (s);
+          x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+          x1 = x1(end - n + 1 : end);
+</pre>
+        <p>To find the solution of an overdetermined problem needs an estimate
+of the residual error <var>r</var> and so it is more complex to formulate
+a minimum norm solution using the <code>spaugment</code> function.
+
+        <p>In general the left division operator is more stable and faster than
+using the <code>spaugment</code> function. 
+</p></blockquote></div>
+
+   <p>Finally, the function <code>eigs</code> can be used to calculate a limited
+number of eigenvalues and eigenvectors based on a selection criteria
+and likewise for <code>svds</code> which calculates a limited number of
+singular values and vectors.
+
+<!-- ./DLD-FUNCTIONS/eigs.cc -->
+   <p><a name="doc_002deigs"></a>
+
+<div class="defun">
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a</var>)<var><a name="index-g_t_003d-1727"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, k</var>)<var><a name="index-g_t_003d-1728"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, k, sigma</var>)<var><a name="index-g_t_003d-1729"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, k, sigma,opts</var>)<var><a name="index-g_t_003d-1730"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, b</var>)<var><a name="index-g_t_003d-1731"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, b, k</var>)<var><a name="index-g_t_003d-1732"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, b, k, sigma</var>)<var><a name="index-g_t_003d-1733"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>a, b, k, sigma, opts</var>)<var><a name="index-g_t_003d-1734"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n</var>)<var><a name="index-g_t_003d-1735"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, b</var>)<var><a name="index-g_t_003d-1736"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, k</var>)<var><a name="index-g_t_003d-1737"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, b, k</var>)<var><a name="index-g_t_003d-1738"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, k, sigma</var>)<var><a name="index-g_t_003d-1739"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, b, k, sigma</var>)<var><a name="index-g_t_003d-1740"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, k, sigma, opts</var>)<var><a name="index-g_t_003d-1741"></a></var><br>
+— Loadable Function: <var>d</var> <b>=</b><var> eigs </var>(<var>af, n, b, k, sigma, opts</var>)<var><a name="index-g_t_003d-1742"></a></var><br>
+— Loadable Function: [<var>v</var>, <var>d</var>] <b>=</b><var> eigs </var>(<var>a, <small class="dots">...</small></var>)<var><a name="index-g_t_003d-1743"></a></var><br>
+— Loadable Function: [<var>v</var>, <var>d</var>] <b>=</b><var> eigs </var>(<var>af, n, <small class="dots">...</small></var>)<var><a name="index-g_t_003d-1744"></a></var><br>
+— Loadable Function: [<var>v</var>, <var>d</var>, <var>flag</var>] <b>=</b><var> eigs </var>(<var>a, <small class="dots">...</small></var>)<var><a name="index-g_t_003d-1745"></a></var><br>
+— Loadable Function: [<var>v</var>, <var>d</var>, <var>flag</var>] <b>=</b><var> eigs </var>(<var>af, n, <small class="dots">...</small></var>)<var><a name="index-g_t_003d-1746"></a></var><br>
+<blockquote><p>Calculate a limited number of eigenvalues and eigenvectors of <var>a</var>,
+based on a selection criteria.  The number eigenvalues and eigenvectors to
+calculate is given by <var>k</var> whose default value is 6.
+
+        <p>By default <code>eigs</code> solve the equation
+<code>A * v = lambda * v</code>
+, where
+<code>lambda</code> is a scalar representing one of the eigenvalues, and <code>v</code>
+is the corresponding eigenvector.  If given the positive definite matrix
+<var>B</var> then <code>eigs</code> solves the general eigenvalue equation
+<code>A * v = lambda * B * v</code>
+.
+
+        <p>The argument <var>sigma</var> determines which eigenvalues are returned. 
+<var>sigma</var> can be either a scalar or a string.  When <var>sigma</var> is a scalar,
+the <var>k</var> eigenvalues closest to <var>sigma</var> are returned.  If <var>sigma</var>
+is a string, it must have one of the values
+
+          <dl>
+<dt>'lm'<dd>Largest magnitude (default).
+
+          <br><dt>'sm'<dd>Smallest magnitude.
+
+          <br><dt>'la'<dd>Largest Algebraic (valid only for real symmetric problems).
+
+          <br><dt>'sa'<dd>Smallest Algebraic (valid only for real symmetric problems).
+
+          <br><dt>'be'<dd>Both ends, with one more from the high-end if <var>k</var> is odd (valid only for
+real symmetric problems).
+
+          <br><dt>'lr'<dd>Largest real part (valid only for complex or unsymmetric problems).
+
+          <br><dt>'sr'<dd>Smallest real part (valid only for complex or unsymmetric problems).
+
+          <br><dt>'li'<dd>Largest imaginary part (valid only for complex or unsymmetric problems).
+
+          <br><dt>'si'<dd>Smallest imaginary part (valid only for complex or unsymmetric problems). 
+</dl>
+
+        <p>If <var>opts</var> is given, it is a structure defining some of the options that
+<code>eigs</code> should use.  The fields of the structure <var>opts</var> are
+
+          <dl>
+<dt><code>issym</code><dd>If <var>af</var> is given, then flags whether the function <var>af</var> defines a
+symmetric problem.  It is ignored if <var>a</var> is given.  The default is false.
+
+          <br><dt><code>isreal</code><dd>If <var>af</var> is given, then flags whether the function <var>af</var> defines a
+real problem.  It is ignored if <var>a</var> is given.  The default is true.
+
+          <br><dt><code>tol</code><dd>Defines the required convergence tolerance, given as <code>tol * norm (A)</code>. 
+The default is <code>eps</code>.
+
+          <br><dt><code>maxit</code><dd>The maximum number of iterations.  The default is 300.
+
+          <br><dt><code>p</code><dd>The number of Lanzcos basis vectors to use.  More vectors will result in
+faster convergence, but a larger amount of memory.  The optimal value of 'p'
+is problem dependent and should be in the range <var>k</var> to <var>n</var>.  The
+default value is <code>2 * </code><var>k</var>.
+
+          <br><dt><code>v0</code><dd>The starting vector for the computation.  The default is to have <span class="sc">Arpack</span>
+randomly generate a starting vector.
+
+          <br><dt><code>disp</code><dd>The level of diagnostic printout.  If <code>disp</code> is 0 then there is no
+printout.  The default value is 1.
+
+          <br><dt><code>cholB</code><dd>Flag if <code>chol (</code><var>b</var><code>)</code> is passed rather than <var>b</var>.  The default is
+false.
+
+          <br><dt><code>permB</code><dd>The permutation vector of the Cholesky factorization of <var>b</var> if
+<code>cholB</code> is true.  That is <code>chol ( </code><var>b</var><code> (permB, permB))</code>.  The
+default is <code>1:</code><var>n</var>.
+
+        </dl>
+
+        <p>It is also possible to represent <var>a</var> by a function denoted <var>af</var>. 
+<var>af</var> must be followed by a scalar argument <var>n</var> defining the length
+of the vector argument accepted by <var>af</var>.  <var>af</var> can be passed either
+as an inline function, function handle or as a string.  In the case where
+<var>af</var> is passed as a string, the name of the string defines the function
+to use.
+
+        <p><var>af</var> is a function of the form <code>function y = af (x), y = ...;
+endfunction</code>, where the required return value of <var>af</var> is determined by
+the value of <var>sigma</var>, and are
+
+          <dl>
+<dt><code>A * x</code><dd>If <var>sigma</var> is not given or is a string other than 'sm'.
+
+          <br><dt><code>A \ x</code><dd>If <var>sigma</var> is 'sm'.
+
+          <br><dt><code>(A - sigma * I) \ x</code><dd>for standard eigenvalue problem, where <code>I</code> is the identity matrix of
+the same size as <code>A</code>.  If <var>sigma</var> is zero, this reduces the
+<code>A \ x</code>.
+
+          <br><dt><code>(A - sigma * B) \ x</code><dd>for the general eigenvalue problem. 
+</dl>
+
+        <p>The return arguments of <code>eigs</code> depends on the number of return
+arguments.  With a single return argument, a vector <var>d</var> of length <var>k</var>
+is returned, represent the <var>k</var> eigenvalues that have been found.  With two
+return arguments, <var>v</var> is a <var>n</var>-by-<var>k</var> matrix whose columns are
+the <var>k</var> eigenvectors corresponding to the returned eigenvalues.  The
+eigenvalues themselves are then returned in <var>d</var> in the form of a
+<var>n</var>-by-<var>k</var> matrix, where the elements on the diagonal are the
+eigenvalues.
+
+        <p>Given a third return argument <var>flag</var>, <code>eigs</code> also returns the status
+of the convergence.  If <var>flag</var> is 0, then all eigenvalues have converged,
+otherwise not.
+
+        <p>This function is based on the <span class="sc">Arpack</span> package, written by R Lehoucq,
+K Maschhoff, D Sorensen and C Yang.  For more information see
+<a href="http://www.caam.rice.edu/software/ARPACK/">http://www.caam.rice.edu/software/ARPACK/</a>.
+
+        </blockquote></div>
+   <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+<p class="noindent"><strong>See also:</strong> <a href="doc_002deig.html#doc_002deig">eig</a>, <a href="doc_002dsvds.html#doc_002dsvds">svds</a>.
+
+<!-- ./sparse/svds.m -->
+   <p><a name="doc_002dsvds"></a>
+
+<div class="defun">
+— Function File: <var>s</var> = <b>svds</b> (<var>a</var>)<var><a name="index-svds-1747"></a></var><br>
+— Function File: <var>s</var> = <b>svds</b> (<var>a, k</var>)<var><a name="index-svds-1748"></a></var><br>
+— Function File: <var>s</var> = <b>svds</b> (<var>a, k, sigma</var>)<var><a name="index-svds-1749"></a></var><br>
+— Function File: <var>s</var> = <b>svds</b> (<var>a, k, sigma, opts</var>)<var><a name="index-svds-1750"></a></var><br>
+— Function File: [<var>u</var>, <var>s</var>, <var>v</var>, <var>flag</var>] = <b>svds</b> (<var><small class="dots">...</small></var>)<var><a name="index-svds-1751"></a></var><br>
+<blockquote>
+        <p>Find a few singular values of the matrix <var>a</var>.  The singular values
+are calculated using
+
+     <pre class="example">          [<var>m</var>, <var>n</var>] = size(<var>a</var>)
+          <var>s</var> = eigs([sparse(<var>m</var>, <var>m</var>), <var>a</var>; ...
+                          <var>a</var>', sparse(<var>n</var>, <var>n</var>)])
+</pre>
+        <p>The eigenvalues returned by <code>eigs</code> correspond to the singular
+values of <var>a</var>.  The number of singular values to calculate is given
+by <var>k</var>, whose default value is 6.
+
+        <p>The argument <var>sigma</var> can be used to specify which singular values
+to find.  <var>sigma</var> can be either the string 'L', the default, in
+which case the largest singular values of <var>a</var> are found.  Otherwise
+<var>sigma</var> should be a real scalar, in which case the singular values
+closest to <var>sigma</var> are found.  Note that for relatively small values
+of <var>sigma</var>, there is the chance that the requested number of singular
+values are not returned.  In that case <var>sigma</var> should be increased.
+
+        <p>If <var>opts</var> is given, then it is a structure that defines options
+that <code>svds</code> will pass to <var>eigs</var>.  The possible fields of this
+structure are therefore determined by <code>eigs</code>.  By default three
+fields of this structure are set by <code>svds</code>.
+
+          <dl>
+<dt><code>tol</code><dd>The required convergence tolerance for the singular values.  <code>eigs</code>
+is passed <var>tol</var> divided by <code>sqrt(2)</code>.  The default value is
+1e-10.
+
+          <br><dt><code>maxit</code><dd>The maximum number of iterations.  The default is 300.
+
+          <br><dt><code>disp</code><dd>The level of diagnostic printout.  If <code>disp</code> is 0 then there is no
+printout.  The default value is 0. 
+</dl>
+
+        <p>If more than one output argument is given, then <code>svds</code> also
+calculates the left and right singular vectors of <var>a</var>.  <var>flag</var>
+is used to signal the convergence of <code>svds</code>.  If <code>svds</code>
+converges to the desired tolerance, then <var>flag</var> given by
+
+     <pre class="example">          norm (<var>a</var> * <var>v</var> - <var>u</var> * <var>s</var>, 1) <= ...
+                  <var>tol</var> * norm (<var>a</var>, 1)
+</pre>
+        <p>will be zero. 
+</p></blockquote></div>
+   <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+<p class="noindent"><strong>See also:</strong> <a href="doc_002deigs.html#doc_002deigs">eigs</a>.
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> The CHOLMOD, UMFPACK and CXSPARSE packages were
+written by Tim Davis and are available at
+http://www.cise.ufl.edu/research/sparse/</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sparse-Matrices-in-Oct_002dFiles.html b/doc/interpreter/HTML/Sparse-Matrices-in-Oct_002dFiles.html
new file mode 100644
index 0000000..a2381b0
--- /dev/null
+++ b/doc/interpreter/HTML/Sparse-Matrices-in-Oct_002dFiles.html
@@ -0,0 +1,70 @@
+<html lang="en">
+<head>
+<title>Sparse Matrices in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles" title="Structures in Oct-Files">
+<link rel="next" href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles" title="Accessing Global Variables in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sparse-Matrices-in-Oct-Files"></a>
+<a name="Sparse-Matrices-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles">Accessing Global Variables in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles">Structures in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.6 Sparse Matrices in Oct-Files</h4>
+
+<p>There are three classes of sparse objects that are of interest to the
+user.
+
+     <dl>
+<dt><code>SparseMatrix</code><dd>A double precision sparse matrix class
+<br><dt><code>SparseComplexMatrix</code><dd>A complex sparse matrix class
+<br><dt><code>SparseBoolMatrix</code><dd>A boolean sparse matrix class
+</dl>
+
+   <p>All of these classes inherit from the <code>Sparse<T></code> template class,
+and so all have similar capabilities and usage.  The <code>Sparse<T></code>
+class was based on Octave <code>Array<T></code> class, and so users familiar
+with Octave's <code>Array</code> classes will be comfortable with the use of
+the sparse classes.
+
+   <p>The sparse classes will not be entirely described in this section, due
+to their similarity with the existing <code>Array</code> classes.  However,
+there are a few differences due the different nature of sparse objects,
+and these will be described.  Firstly, although it is fundamentally
+possible to have N-dimensional sparse objects, the Octave sparse classes do
+not allow them at this time.  So all operations of the sparse classes
+must be 2-dimensional.  This means that in fact <code>SparseMatrix</code> is
+similar to Octave's <code>Matrix</code> class rather than its
+<code>NDArray</code> class.
+
+<ul class="menu">
+<li><a accesskey="1" href="Array-and-Sparse-Differences.html#Array-and-Sparse-Differences">Array and Sparse Differences</a>
+<li><a accesskey="2" href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles">Creating Sparse Matrices in Oct-Files</a>
+<li><a accesskey="3" href="Using-Sparse-Matrices-in-Oct_002dFiles.html#Using-Sparse-Matrices-in-Oct_002dFiles">Using Sparse Matrices in Oct-Files</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sparse-Matrices-with-Mex_002dFiles.html b/doc/interpreter/HTML/Sparse-Matrices-with-Mex_002dFiles.html
new file mode 100644
index 0000000..bab2ce7
--- /dev/null
+++ b/doc/interpreter/HTML/Sparse-Matrices-with-Mex_002dFiles.html
@@ -0,0 +1,201 @@
+<html lang="en">
+<head>
+<title>Sparse Matrices with Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="prev" href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles" title="Structures with Mex-Files">
+<link rel="next" href="Calling-Other-Functions-in-Mex_002dFiles.html#Calling-Other-Functions-in-Mex_002dFiles" title="Calling Other Functions in Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sparse-Matrices-with-Mex-Files"></a>
+<a name="Sparse-Matrices-with-Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Calling-Other-Functions-in-Mex_002dFiles.html#Calling-Other-Functions-in-Mex_002dFiles">Calling Other Functions in Mex-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles">Structures with Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.6 Sparse Matrices with Mex-Files</h4>
+
+<p>The Octave format for sparse matrices is identical to the mex format in
+that it is a compressed column sparse format.  Also in both, sparse
+matrices are required to be two-dimensional.  The only difference is that
+the real and imaginary parts of the matrix are stored separately.
+
+   <p>The mex-file interface, as well as using <code>mxGetM</code>, <code>mxGetN</code>,
+<code>mxSetM</code>, <code>mxSetN</code>, <code>mxGetPr</code>, <code>mxGetPi</code>,
+<code>mxSetPr</code> and <code>mxSetPi</code>, the mex-file interface supplies the
+functions
+
+<pre class="example">     mwIndex *mxGetIr (const mxArray *ptr);
+     mwIndex *mxGetJc (const mxArray *ptr);
+     mwSize mxGetNzmax (const mxArray *ptr);
+     
+     void mxSetIr (mxArray *ptr, mwIndex *ir);
+     void mxSetJc (mxArray *ptr, mwIndex *jc);
+     void mxSetNzmax (mxArray *ptr, mwSize nzmax);
+</pre>
+   <p class="noindent"><code>mxGetNzmax</code> gets the maximum number of elements that can be stored
+in the sparse matrix.  This is not necessarily the number of non-zero
+elements in the sparse matrix.  <code>mxGetJc</code> returns an array with one
+additional value than the number of columns in the sparse matrix.  The
+difference between consecutive values of the array returned by
+<code>mxGetJc</code> define the number of non-zero elements in each column of
+the sparse matrix.  Therefore
+
+<pre class="example">     mwSize nz, n;
+     mwIndex *Jc;
+     mxArray *m;
+     ...
+     n = mxGetN (m);
+     Jc = mxGetJc (m);
+     nz = Jc[n];
+</pre>
+   <p class="noindent">returns the actual number of non-zero elements stored in the matrix in
+<code>nz</code>.  As the arrays returned by <code>mxGetPr</code> and <code>mxGetPi</code>
+only contain the non-zero values of the matrix, we also need a pointer
+to the rows of the non-zero elements, and this is given by
+<code>mxGetIr</code>.  A complete example of the use of sparse matrices in
+mex-files is given by the file <samp><span class="file">mysparse.c</span></samp> as seen below
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+     	     const mxArray *prhs[])
+     {
+       mwSize n, m, nz;
+       mxArray *v;
+       mwIndex i;
+       double *pr, *pi;
+       double *pr2, *pi2;
+       mwIndex *ir, *jc;
+       mwIndex *ir2, *jc2;
+       
+       if (nrhs != 1 || ! mxIsSparse (prhs[0]))
+         mexErrMsgTxt ("expects sparse matrix");
+     
+       m = mxGetM (prhs [0]);
+       n = mxGetN (prhs [0]);
+       nz = mxGetNzmax (prhs [0]);
+       
+       if (mxIsComplex (prhs[0]))
+         {
+           mexPrintf ("Matrix is %d-by-%d complex",
+     		 " sparse matrix", m, n);
+           mexPrintf (" with %d elements\n", nz);
+     
+           pr = mxGetPr (prhs[0]);
+           pi = mxGetPi (prhs[0]);
+           ir = mxGetIr (prhs[0]);
+           jc = mxGetJc (prhs[0]);
+     
+           i = n;
+           while (jc[i] == jc[i-1] && i != 0) i--;
+           mexPrintf ("last non-zero element (%d, %d) =", 
+     		 ir[nz-1]+ 1, i);
+           mexPrintf (" (%g, %g)\n", pr[nz-1], pi[nz-1]);
+     
+           v = mxCreateSparse (m, n, nz, mxCOMPLEX);
+           pr2 = mxGetPr (v);
+           pi2 = mxGetPi (v);
+           ir2 = mxGetIr (v);
+           jc2 = mxGetJc (v);
+           
+           for (i = 0; i < nz; i++)
+             {
+               pr2[i] = 2 * pr[i];
+               pi2[i] = 2 * pi[i];
+               ir2[i] = ir[i];
+             }
+           for (i = 0; i < n + 1; i++)
+             jc2[i] = jc[i];
+     
+           if (nlhs > 0)
+             plhs[0] = v;
+         }
+       else if (mxIsLogical (prhs[0]))
+         {
+           bool *pbr, *pbr2;
+           mexPrintf ("Matrix is %d-by-%d logical",
+     		 " sparse matrix", m, n);
+           mexPrintf (" with %d elements\n", nz);
+     
+           pbr = mxGetLogicals (prhs[0]);
+           ir = mxGetIr (prhs[0]);
+           jc = mxGetJc (prhs[0]);
+     
+           i = n;
+           while (jc[i] == jc[i-1] && i != 0) i--;
+           mexPrintf ("last non-zero element (%d, %d) = %d\n",
+                      ir[nz-1]+ 1, i, pbr[nz-1]);
+     
+           v = mxCreateSparseLogicalMatrix (m, n, nz);
+           pbr2 = mxGetLogicals (v);
+           ir2 = mxGetIr (v);
+           jc2 = mxGetJc (v);
+           
+           for (i = 0; i < nz; i++)
+             {
+               pbr2[i] = pbr[i];
+               ir2[i] = ir[i];
+             }
+           for (i = 0; i < n + 1; i++)
+             jc2[i] = jc[i];
+     
+           if (nlhs > 0)
+             plhs[0] = v;
+         }
+       else
+         {
+           mexPrintf ("Matrix is %d-by-%d real",
+     		 " sparse matrix", m, n);
+           mexPrintf (" with %d elements\n", nz);
+     
+           pr = mxGetPr (prhs[0]);
+           ir = mxGetIr (prhs[0]);
+           jc = mxGetJc (prhs[0]);
+     
+           i = n;
+           while (jc[i] == jc[i-1] && i != 0) i--;
+           mexPrintf ("last non-zero element (%d, %d) = %g\n",
+                     ir[nz-1]+ 1, i, pr[nz-1]);
+     
+           v = mxCreateSparse (m, n, nz, mxREAL);
+           pr2 = mxGetPr (v);
+           ir2 = mxGetIr (v);
+           jc2 = mxGetJc (v);
+           
+           for (i = 0; i < nz; i++)
+             {
+               pr2[i] = 2 * pr[i];
+               ir2[i] = ir[i];
+             }
+           for (i = 0; i < n + 1; i++)
+             jc2[i] = jc[i];
+     
+           if (nlhs > 0)
+             plhs[0] = v;
+         }
+     }
+</pre></pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sparse-Matrices.html b/doc/interpreter/HTML/Sparse-Matrices.html
new file mode 100644
index 0000000..d4df4b7
--- /dev/null
+++ b/doc/interpreter/HTML/Sparse-Matrices.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Sparse Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link rel="next" href="Numerical-Integration.html#Numerical-Integration" title="Numerical Integration">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sparse-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Numerical-Integration.html#Numerical-Integration">Numerical Integration</a>,
+Previous: <a rel="previous" accesskey="p" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">21 Sparse Matrices</h2>
+
+<ul class="menu">
+<li><a accesskey="1" href="Basics.html#Basics">Basics</a>:                       Creation and Manipulation of Sparse Matrices
+<li><a accesskey="2" href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a>:        Linear Algebra on Sparse Matrices
+<li><a accesskey="3" href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a>:         Iterative Techniques
+<li><a accesskey="4" href="Real-Life-Example.html#Real-Life-Example">Real Life Example</a>:            Using Sparse Matrices
+</ul>
+
+</body></html>
+
diff --git a/doc/interpreter/HTML/Special-Functions.html b/doc/interpreter/HTML/Special-Functions.html
new file mode 100644
index 0000000..5a3f533
--- /dev/null
+++ b/doc/interpreter/HTML/Special-Functions.html
@@ -0,0 +1,416 @@
+<html lang="en">
+<head>
+<title>Special Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Utility-Functions.html#Utility-Functions" title="Utility Functions">
+<link rel="next" href="Coordinate-Transformations.html#Coordinate-Transformations" title="Coordinate Transformations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Special-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a>,
+Previous: <a rel="previous" accesskey="p" href="Utility-Functions.html#Utility-Functions">Utility Functions</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.6 Special Functions</h3>
+
+<!-- ./DLD-FUNCTIONS/besselj.cc -->
+<p><a name="doc_002dairy"></a>
+
+<div class="defun">
+— Loadable Function: [<var>a</var>, <var>ierr</var>] = <b>airy</b> (<var>k, z, opt</var>)<var><a name="index-airy-1482"></a></var><br>
+<blockquote><p>Compute Airy functions of the first and second kind, and their
+derivatives.
+
+     <pre class="example">           K   Function   Scale factor (if 'opt' is supplied)
+          ---  --------   ---------------------------------------
+           0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))
+           1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))
+           2   Bi (Z)     exp (-abs (real ((2/3) * Z *sqrt (Z))))
+           3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z *sqrt (Z))))
+</pre>
+        <p>The function call <code>airy (</code><var>z</var><code>)</code> is equivalent to
+<code>airy (0, </code><var>z</var><code>)</code>.
+
+        <p>The result is the same size as <var>z</var>.
+
+        <p>If requested, <var>ierr</var> contains the following status information and
+is the same size as the result.
+
+          <ol type=1 start=0>
+<li>Normal return. 
+<li>Input error, return <code>NaN</code>. 
+<li>Overflow, return <code>Inf</code>. 
+<li>Loss of significance by argument reduction results in less than half
+ of machine accuracy. 
+<li>Complete loss of significance by argument reduction, return <code>NaN</code>. 
+<li>Error—no computation, algorithm termination condition not met,
+return <code>NaN</code>.
+             </ol>
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/besselj.cc -->
+   <p><a name="doc_002dbesselj"></a>
+
+<div class="defun">
+— Loadable Function: [<var>j</var>, <var>ierr</var>] = <b>besselj</b> (<var>alpha, x, opt</var>)<var><a name="index-besselj-1483"></a></var><br>
+— Loadable Function: [<var>y</var>, <var>ierr</var>] = <b>bessely</b> (<var>alpha, x, opt</var>)<var><a name="index-bessely-1484"></a></var><br>
+— Loadable Function: [<var>i</var>, <var>ierr</var>] = <b>besseli</b> (<var>alpha, x, opt</var>)<var><a name="index-besseli-1485"></a></var><br>
+— Loadable Function: [<var>k</var>, <var>ierr</var>] = <b>besselk</b> (<var>alpha, x, opt</var>)<var><a name="index-besselk-1486"></a></var><br>
+— Loadable Function: [<var>h</var>, <var>ierr</var>] = <b>besselh</b> (<var>alpha, k, x, opt</var>)<var><a name="index-besselh-1487"></a></var><br>
+<blockquote><p>Compute Bessel or Hankel functions of various kinds:
+
+          <dl>
+<dt><code>besselj</code><dd>Bessel functions of the first kind.  If the argument <var>opt</var> is supplied,
+the result is multiplied by <code>exp(-abs(imag(x)))</code>. 
+<br><dt><code>bessely</code><dd>Bessel functions of the second kind.  If the argument <var>opt</var> is supplied,
+the result is multiplied by <code>exp(-abs(imag(x)))</code>. 
+<br><dt><code>besseli</code><dd>Modified Bessel functions of the first kind.  If the argument <var>opt</var> is supplied,
+the result is multiplied by <code>exp(-abs(real(x)))</code>. 
+<br><dt><code>besselk</code><dd>Modified Bessel functions of the second kind.  If the argument <var>opt</var> is supplied,
+the result is multiplied by <code>exp(x)</code>. 
+<br><dt><code>besselh</code><dd>Compute Hankel functions of the first (<var>k</var> = 1) or second (<var>k</var>
+= 2) kind.  If the argument <var>opt</var> is supplied, the result is multiplied by
+<code>exp (-I*</code><var>x</var><code>)</code> for <var>k</var> = 1 or <code>exp (I*</code><var>x</var><code>)</code> for
+<var>k</var> = 2. 
+</dl>
+
+        <p>If <var>alpha</var> is a scalar, the result is the same size as <var>x</var>. 
+If <var>x</var> is a scalar, the result is the same size as <var>alpha</var>. 
+If <var>alpha</var> is a row vector and <var>x</var> is a column vector, the
+result is a matrix with <code>length (</code><var>x</var><code>)</code> rows and
+<code>length (</code><var>alpha</var><code>)</code> columns.  Otherwise, <var>alpha</var> and
+<var>x</var> must conform and the result will be the same size.
+
+        <p>The value of <var>alpha</var> must be real.  The value of <var>x</var> may be
+complex.
+
+        <p>If requested, <var>ierr</var> contains the following status information
+and is the same size as the result.
+
+          <ol type=1 start=0>
+<li>Normal return. 
+<li>Input error, return <code>NaN</code>. 
+<li>Overflow, return <code>Inf</code>. 
+<li>Loss of significance by argument reduction results in less than
+half of machine accuracy. 
+<li>Complete loss of significance by argument reduction, return <code>NaN</code>. 
+<li>Error—no computation, algorithm termination condition not met,
+return <code>NaN</code>.
+             </ol>
+</p></blockquote></div>
+
+<!-- ./specfun/beta.m -->
+   <p><a name="doc_002dbeta"></a>
+
+<div class="defun">
+— Mapping Function:  <b>beta</b> (<var>a, b</var>)<var><a name="index-beta-1488"></a></var><br>
+<blockquote><p>For real inputs, return the Beta function,
+
+     <pre class="example">          beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
+</pre>
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/betainc.cc -->
+   <p><a name="doc_002dbetainc"></a>
+
+<div class="defun">
+— Mapping Function:  <b>betainc</b> (<var>x, a, b</var>)<var><a name="index-betainc-1489"></a></var><br>
+<blockquote><p>Return the incomplete Beta function,
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">                                                x
+                                               /
+          betainc (x, a, b) = beta (a, b)^(-1) | t^(a-1) (1-t)^(b-1) dt.
+                                               /
+                                            t=0
+</pre>
+        <p>If x has more than one component, both <var>a</var> and <var>b</var> must be
+scalars.  If <var>x</var> is a scalar, <var>a</var> and <var>b</var> must be of
+compatible dimensions. 
+</p></blockquote></div>
+
+<!-- ./specfun/betaln.m -->
+   <p><a name="doc_002dbetaln"></a>
+
+<div class="defun">
+— Mapping Function:  <b>betaln</b> (<var>a, b</var>)<var><a name="index-betaln-1490"></a></var><br>
+<blockquote><p>Return the log of the Beta function,
+
+     <pre class="example">          betaln (a, b) = gammaln (a) + gammaln (b) - gammaln (a + b)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbeta.html#doc_002dbeta">beta</a>, <a href="doc_002dbetainc.html#doc_002dbetainc">betainc</a>, <a href="doc_002dgammaln.html#doc_002dgammaln">gammaln</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/bincoeff.m -->
+   <p><a name="doc_002dbincoeff"></a>
+
+<div class="defun">
+— Mapping Function:  <b>bincoeff</b> (<var>n, k</var>)<var><a name="index-bincoeff-1491"></a></var><br>
+<blockquote><p>Return the binomial coefficient of <var>n</var> and <var>k</var>, defined as
+
+     <pre class="example">           /   \
+           | n |    n (n-1) (n-2) ... (n-k+1)
+           |   |  = -------------------------
+           | k |               k!
+           \   /
+</pre>
+        <p>For example,
+
+     <pre class="example">          bincoeff (5, 2)
+                10
+</pre>
+        <p>In most cases, the <code>nchoosek</code> function is faster for small
+scalar integer arguments.  It also warns about loss of precision for
+big arguments.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnchoosek.html#doc_002dnchoosek">nchoosek</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/commutation_matrix.m -->
+   <p><a name="doc_002dcommutation_005fmatrix"></a>
+
+<div class="defun">
+— Function File:  <b>commutation_matrix</b> (<var>m, n</var>)<var><a name="index-commutation_005fmatrix-1492"></a></var><br>
+<blockquote><p>Return the commutation matrix
+ K(m,n)
+ which is the unique
+<var>m</var>*<var>n</var> by <var>m</var>*<var>n</var>
+ matrix such that
+K(m,n) * vec(A) = vec(A')
+ for all
+m by n
+ matrices
+A.
+
+        <p>If only one argument <var>m</var> is given,
+K(m,m)
+ is returned.
+
+        <p>See Magnus and Neudecker (1988), Matrix differential calculus with
+applications in statistics and econometrics. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/duplication_matrix.m -->
+   <p><a name="doc_002dduplication_005fmatrix"></a>
+
+<div class="defun">
+— Function File:  <b>duplication_matrix</b> (<var>n</var>)<var><a name="index-duplication_005fmatrix-1493"></a></var><br>
+<blockquote><p>Return the duplication matrix
+Dn
+ which is the unique
+n^2 by n*(n+1)/2
+ matrix such that
+Dn vech (A) = vec (A)
+ for all symmetric
+n by n
+ matrices
+A.
+
+        <p>See Magnus and Neudecker (1988), Matrix differential calculus with
+applications in statistics and econometrics. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002derf"></a>
+
+<div class="defun">
+— Mapping Function:  <b>erf</b> (<var>z</var>)<var><a name="index-erf-1494"></a></var><br>
+<blockquote><p>Computes the error function,
+
+     <pre class="example">                                   z
+                                  /
+          erf (z) = (2/sqrt (pi)) | e^(-t^2) dt
+                                  /
+                               t=0
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derfc.html#doc_002derfc">erfc</a>, <a href="doc_002derfinv.html#doc_002derfinv">erfinv</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002derfc"></a>
+
+<div class="defun">
+— Mapping Function:  <b>erfc</b> (<var>z</var>)<var><a name="index-erfc-1495"></a></var><br>
+<blockquote><p>Computes the complementary error function,
+<code>1 - erf (</code><var>z</var><code>)</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derf.html#doc_002derf">erf</a>, <a href="doc_002derfinv.html#doc_002derfinv">erfinv</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/erfinv.m -->
+   <p><a name="doc_002derfinv"></a>
+
+<div class="defun">
+— Mapping Function:  <b>erfinv</b> (<var>z</var>)<var><a name="index-erfinv-1496"></a></var><br>
+<blockquote><p>Computes the inverse of the error function. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derf.html#doc_002derf">erf</a>, <a href="doc_002derfc.html#doc_002derfc">erfc</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dgamma"></a>
+
+<div class="defun">
+— Mapping Function:  <b>gamma</b> (<var>z</var>)<var><a name="index-gamma-1497"></a></var><br>
+<blockquote><p>Computes the Gamma function,
+
+     <pre class="example">                      infinity
+                      /
+          gamma (z) = | t^(z-1) exp (-t) dt.
+                      /
+                   t=0
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgammainc.html#doc_002dgammainc">gammainc</a>, <a href="doc_002dlgamma.html#doc_002dlgamma">lgamma</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/gammainc.cc -->
+   <p><a name="doc_002dgammainc"></a>
+
+<div class="defun">
+— Mapping Function:  <b>gammainc</b> (<var>x, a</var>)<var><a name="index-gammainc-1498"></a></var><br>
+<blockquote><p>Compute the normalized incomplete gamma function,
+
+     <pre class="smallexample">                                          x
+                                1        /
+          gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
+                            gamma (a)    /
+                                      t=0
+</pre>
+        <p>with the limiting value of 1 as <var>x</var> approaches infinity. 
+The standard notation is P(a,x), e.g., Abramowitz and Stegun (6.5.1).
+
+        <p>If <var>a</var> is scalar, then <code>gammainc (</code><var>x</var><code>, </code><var>a</var><code>)</code> is returned
+for each element of <var>x</var> and vice versa.
+
+        <p>If neither <var>x</var> nor <var>a</var> is scalar, the sizes of <var>x</var> and
+<var>a</var> must agree, and <var>gammainc</var> is applied element-by-element. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>, <a href="doc_002dlgamma.html#doc_002dlgamma">lgamma</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/legendre.m -->
+   <p><a name="doc_002dlegendre"></a>
+
+<div class="defun">
+— Function File: <var>l</var> = <b>legendre</b> (<var>n, x</var>)<var><a name="index-legendre-1499"></a></var><br>
+— Function File: <var>l</var> = <b>legendre</b> (<var>n, x, normalization</var>)<var><a name="index-legendre-1500"></a></var><br>
+<blockquote><p>Compute the Legendre function of degree <var>n</var> and order
+<var>m</var> = 0 <small class="dots">...</small> N.  The optional argument, <var>normalization</var>,
+may be one of <code>"unnorm"</code>, <code>"sch"</code>, or <code>"norm"</code>. 
+The default is <code>"unnorm"</code>.  The value of <var>n</var> must be a
+non-negative scalar integer.
+
+        <p>If the optional argument <var>normalization</var> is missing or is
+<code>"unnorm"</code>, compute the Legendre function of degree <var>n</var> and
+order <var>m</var> and return all values for <var>m</var> = 0 <small class="dots">...</small> <var>n</var>. 
+The return value has one dimension more than <var>x</var>.
+
+        <p>The Legendre Function of degree <var>n</var> and order <var>m</var>:
+
+     <pre class="example">           m        m       2  m/2   d^m
+          P(x) = (-1) * (1-x  )    * ----  P (x)
+           n                         dx^m   n
+</pre>
+        <p class="noindent">with Legendre polynomial of degree <var>n</var>:
+
+     <pre class="example">                    1     d^n   2    n
+          P (x) = ------ [----(x - 1)  ]
+           n      2^n n!  dx^n
+</pre>
+        <p class="noindent"><code>legendre (3, [-1.0, -0.9, -0.8])</code> returns the matrix:
+
+     <pre class="example">           x  |   -1.0   |   -0.9   |  -0.8
+          ------------------------------------
+          m=0 | -1.00000 | -0.47250 | -0.08000
+          m=1 |  0.00000 | -1.99420 | -1.98000
+          m=2 |  0.00000 | -2.56500 | -4.32000
+          m=3 |  0.00000 | -1.24229 | -3.24000
+</pre>
+        <p>If the optional argument <code>normalization</code> is <code>"sch"</code>,
+compute the Schmidt semi-normalized associated Legendre function. 
+The Schmidt semi-normalized associated Legendre function is related
+to the unnormalized Legendre functions by the following:
+
+        <p>For Legendre functions of degree n and order 0:
+
+     <pre class="example">            0       0
+          SP (x) = P (x)
+            n       n
+</pre>
+        <p>For Legendre functions of degree n and order m:
+
+     <pre class="example">            m       m          m    2(n-m)! 0.5
+          SP (x) = P (x) * (-1)  * [-------]
+            n       n               (n+m)!
+</pre>
+        <p>If the optional argument <var>normalization</var> is <code>"norm"</code>,
+compute the fully normalized associated Legendre function. 
+The fully normalized associated Legendre function is related
+to the unnormalized Legendre functions by the following:
+
+        <p>For Legendre functions of degree <var>n</var> and order <var>m</var>
+
+     <pre class="example">            m       m          m    (n+0.5)(n-m)! 0.5
+          NP (x) = P (x) * (-1)  * [-------------]
+            n       n                   (n+m)!
+</pre>
+        </blockquote></div>
+
+   <p><a name="doc_002dgammaln"></a><!-- mappers.cc -->
+<a name="doc_002dlgamma"></a>
+
+<div class="defun">
+— Mapping Function:  <b>lgamma</b> (<var>x</var>)<var><a name="index-lgamma-1501"></a></var><br>
+— Mapping Function:  <b>gammaln</b> (<var>x</var>)<var><a name="index-gammaln-1502"></a></var><br>
+<blockquote><p>Return the natural logarithm of the gamma function of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>, <a href="doc_002dgammainc.html#doc_002dgammainc">gammainc</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Special-Utility-Matrices.html b/doc/interpreter/HTML/Special-Utility-Matrices.html
new file mode 100644
index 0000000..68af6d1
--- /dev/null
+++ b/doc/interpreter/HTML/Special-Utility-Matrices.html
@@ -0,0 +1,443 @@
+<html lang="en">
+<head>
+<title>Special Utility Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Matrix-Manipulation.html#Matrix-Manipulation" title="Matrix Manipulation">
+<link rel="prev" href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array" title="Applying a Function to an Array">
+<link rel="next" href="Famous-Matrices.html#Famous-Matrices" title="Famous Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Special-Utility-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a>,
+Previous: <a rel="previous" accesskey="p" href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">Applying a Function to an Array</a>,
+Up: <a rel="up" accesskey="u" href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>
+<hr>
+</div>
+
+<h3 class="section">16.4 Special Utility Matrices</h3>
+
+<!-- data.cc -->
+<p><a name="doc_002deye"></a>
+
+<div class="defun">
+— Built-in Function:  <b>eye</b> (<var>x</var>)<var><a name="index-eye-1313"></a></var><br>
+— Built-in Function:  <b>eye</b> (<var>n, m</var>)<var><a name="index-eye-1314"></a></var><br>
+— Built-in Function:  <b>eye</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-eye-1315"></a></var><br>
+<blockquote><p>Return an identity matrix.  If invoked with a single scalar argument,
+<code>eye</code> returns a square matrix with the dimension specified.  If you
+supply two scalar arguments, <code>eye</code> takes them to be the number of
+rows and columns.  If given a vector with two elements, <code>eye</code> uses
+the values of the elements as the number of rows and columns,
+respectively.  For example,
+
+     <pre class="example">          eye (3)
+                 1  0  0
+                   0  1  0
+                   0  0  1
+</pre>
+        <p>The following expressions all produce the same result:
+
+     <pre class="example">          eye (2)
+          ==
+          eye (2, 2)
+          ==
+          eye (size ([1, 2; 3, 4])
+</pre>
+        <p>The optional argument <var>class</var>, allows <code>eye</code> to return an array of
+the specified type, like
+
+     <pre class="example">          val = zeros (n,m, "uint8")
+</pre>
+        <p>Calling <code>eye</code> with no arguments is equivalent to calling it
+with an argument of 1.  This odd definition is for compatibility
+with <span class="sc">matlab</span>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dones"></a>
+
+<div class="defun">
+— Built-in Function:  <b>ones</b> (<var>x</var>)<var><a name="index-ones-1316"></a></var><br>
+— Built-in Function:  <b>ones</b> (<var>n, m</var>)<var><a name="index-ones-1317"></a></var><br>
+— Built-in Function:  <b>ones</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-ones-1318"></a></var><br>
+— Built-in Function:  <b>ones</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-ones-1319"></a></var><br>
+<blockquote><p>Return a matrix or N-dimensional array whose elements are all 1. 
+The arguments are handled the same as the arguments for <code>eye</code>.
+
+        <p>If you need to create a matrix whose values are all the same, you should
+use an expression like
+
+     <pre class="example">          val_matrix = val * ones (n, m)
+</pre>
+        <p>The optional argument <var>class</var>, allows <code>ones</code> to return an array of
+the specified type, for example
+
+     <pre class="example">          val = ones (n,m, "uint8")
+</pre>
+        </blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dzeros"></a>
+
+<div class="defun">
+— Built-in Function:  <b>zeros</b> (<var>x</var>)<var><a name="index-zeros-1320"></a></var><br>
+— Built-in Function:  <b>zeros</b> (<var>n, m</var>)<var><a name="index-zeros-1321"></a></var><br>
+— Built-in Function:  <b>zeros</b> (<var>n, m, k, <small class="dots">...</small></var>)<var><a name="index-zeros-1322"></a></var><br>
+— Built-in Function:  <b>zeros</b> (<var><small class="dots">...</small>, class</var>)<var><a name="index-zeros-1323"></a></var><br>
+<blockquote><p>Return a matrix or N-dimensional array whose elements are all 0. 
+The arguments are handled the same as the arguments for <code>eye</code>.
+
+        <p>The optional argument <var>class</var>, allows <code>zeros</code> to return an array of
+the specified type, for example
+
+     <pre class="example">          val = zeros (n,m, "uint8")
+</pre>
+        </blockquote></div>
+
+<!-- ./general/repmat.m -->
+   <p><a name="doc_002drepmat"></a>
+
+<div class="defun">
+— Function File:  <b>repmat</b> (<var>A, m, n</var>)<var><a name="index-repmat-1324"></a></var><br>
+— Function File:  <b>repmat</b> (<var>A, </var>[<var>m n</var>])<var><a name="index-repmat-1325"></a></var><br>
+— Function File:  <b>repmat</b> (<var>A, </var>[<var>m n p <small class="dots">...</small></var>])<var><a name="index-repmat-1326"></a></var><br>
+<blockquote><p>Form a block matrix of size <var>m</var> by <var>n</var>, with a copy of matrix
+<var>A</var> as each element.  If <var>n</var> is not specified, form an
+<var>m</var> by <var>m</var> block matrix. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/rand.cc -->
+   <p><a name="doc_002drand"></a>
+
+<div class="defun">
+— Loadable Function:  <b>rand</b> (<var>x</var>)<var><a name="index-rand-1327"></a></var><br>
+— Loadable Function:  <b>rand</b> (<var>n, m</var>)<var><a name="index-rand-1328"></a></var><br>
+— Loadable Function:  <b>rand</b> (<var>"state", x</var>)<var><a name="index-rand-1329"></a></var><br>
+— Loadable Function:  <b>rand</b> (<var>"seed", x</var>)<var><a name="index-rand-1330"></a></var><br>
+<blockquote><p>Return a matrix with random elements uniformly distributed on the
+interval (0, 1).  The arguments are handled the same as the arguments
+for <code>eye</code>.
+
+        <p>You can query the state of the random number generator using the
+form
+
+     <pre class="example">          v = rand ("state")
+</pre>
+        <p>This returns a column vector <var>v</var> of length 625.  Later, you can
+restore the random number generator to the state <var>v</var>
+using the form
+
+     <pre class="example">          rand ("state", v)
+</pre>
+        <p class="noindent">You may also initialize the state vector from an arbitrary vector of
+length <= 625 for <var>v</var>.  This new state will be a hash based on the
+value of <var>v</var>, not <var>v</var> itself.
+
+        <p>By default, the generator is initialized from <code>/dev/urandom</code> if it is
+available, otherwise from cpu time, wall clock time and the current
+fraction of a second.
+
+        <p>To compute the pseudo-random sequence, <code>rand</code> uses the Mersenne
+Twister with a period of 2^19937-1 (See M. Matsumoto and T. Nishimura,
+<cite>Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator</cite>, ACM Trans. on
+Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998,
+<a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html</a>). 
+Do <strong>not</strong> use for cryptography without securely hashing
+several returned values together, otherwise the generator state
+can be learned after reading 624 consecutive values.
+
+        <p>Older versions of Octave used a different random number generator. 
+The new generator is used by default
+as it is significantly faster than the old generator, and produces
+random numbers with a significantly longer cycle time.  However, in
+some circumstances it might be desirable to obtain the same random
+sequences as used by the old generators.  To do this the keyword
+"seed" is used to specify that the old generators should be use,
+as in
+
+     <pre class="example">          rand ("seed", val)
+</pre>
+        <p>which sets the seed of the generator to <var>val</var>.  The seed of the
+generator can be queried with
+
+     <pre class="example">          s = rand ("seed")
+</pre>
+        <p>However, it should be noted that querying the seed will not cause
+<code>rand</code> to use the old generators, only setting the seed will. 
+To cause <code>rand</code> to once again use the new generators, the
+keyword "state" should be used to reset the state of the <code>rand</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drandn.html#doc_002drandn">randn</a>, <a href="doc_002drande.html#doc_002drande">rande</a>, <a href="doc_002drandg.html#doc_002drandg">randg</a>, <a href="doc_002drandp.html#doc_002drandp">randp</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/rand.cc -->
+   <p><a name="doc_002drandn"></a>
+
+<div class="defun">
+— Loadable Function:  <b>randn</b> (<var>x</var>)<var><a name="index-randn-1331"></a></var><br>
+— Loadable Function:  <b>randn</b> (<var>n, m</var>)<var><a name="index-randn-1332"></a></var><br>
+— Loadable Function:  <b>randn</b> (<var>"state", x</var>)<var><a name="index-randn-1333"></a></var><br>
+— Loadable Function:  <b>randn</b> (<var>"seed", x</var>)<var><a name="index-randn-1334"></a></var><br>
+<blockquote><p>Return a matrix with normally distributed pseudo-random
+elements having zero mean and variance one.  The arguments are
+handled the same as the arguments for <code>rand</code>.
+
+        <p>By default, <code>randn</code> uses the Marsaglia and Tsang “Ziggurat technique” to
+transform from a uniform to a normal distribution.  (G. Marsaglia and
+W.W. Tsang, <cite>Ziggurat method for generating random variables</cite>,
+J. Statistical Software, vol 5, 2000,
+<a href="http://www.jstatsoft.org/v05/i08/">http://www.jstatsoft.org/v05/i08/</a>)
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drand.html#doc_002drand">rand</a>, <a href="doc_002drande.html#doc_002drande">rande</a>, <a href="doc_002drandg.html#doc_002drandg">randg</a>, <a href="doc_002drandp.html#doc_002drandp">randp</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/rand.cc -->
+   <p><a name="doc_002drande"></a>
+
+<div class="defun">
+— Loadable Function:  <b>rande</b> (<var>x</var>)<var><a name="index-rande-1335"></a></var><br>
+— Loadable Function:  <b>rande</b> (<var>n, m</var>)<var><a name="index-rande-1336"></a></var><br>
+— Loadable Function:  <b>rande</b> (<var>"state", x</var>)<var><a name="index-rande-1337"></a></var><br>
+— Loadable Function:  <b>rande</b> (<var>"seed", x</var>)<var><a name="index-rande-1338"></a></var><br>
+<blockquote><p>Return a matrix with exponentially distributed random elements.  The
+arguments are handled the same as the arguments for <code>rand</code>.
+
+        <p>By default, <code>randn</code> uses the Marsaglia and Tsang “Ziggurat technique” to
+transform from a uniform to a exponential distribution.  (G. Marsaglia and
+W.W. Tsang, <cite>Ziggurat method for generating random variables</cite>,
+J. Statistical Software, vol 5, 2000,
+<a href="http://www.jstatsoft.org/v05/i08/">http://www.jstatsoft.org/v05/i08/</a>)
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drand.html#doc_002drand">rand</a>, <a href="doc_002drandn.html#doc_002drandn">randn</a>, <a href="doc_002drandg.html#doc_002drandg">randg</a>, <a href="doc_002drandp.html#doc_002drandp">randp</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/rand.cc -->
+   <p><a name="doc_002drandp"></a>
+
+<div class="defun">
+— Loadable Function:  <b>randp</b> (<var>l, x</var>)<var><a name="index-randp-1339"></a></var><br>
+— Loadable Function:  <b>randp</b> (<var>l, n, m</var>)<var><a name="index-randp-1340"></a></var><br>
+— Loadable Function:  <b>randp</b> (<var>"state", x</var>)<var><a name="index-randp-1341"></a></var><br>
+— Loadable Function:  <b>randp</b> (<var>"seed", x</var>)<var><a name="index-randp-1342"></a></var><br>
+<blockquote><p>Return a matrix with Poisson distributed random elements with mean value parameter given by the first argument, <var>l</var>.  The arguments
+are handled the same as the arguments for <code>rand</code>, except for the
+argument <var>l</var>.
+
+        <p>Five different algorithms are used depending on the range of <var>l</var>
+and whether or not <var>l</var> is a scalar or a matrix.
+
+          <dl>
+<dt>For scalar <var>l</var> <= 12, use direct method.<dd>Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992. 
+<br><dt>For scalar <var>l</var> > 12, use rejection method.[1]<dd>Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992. 
+<br><dt>For matrix <var>l</var> <= 10, use inversion method.[2]<dd>Stadlober E., et al., WinRand source code, available via FTP. 
+<br><dt>For matrix <var>l</var> > 10, use patchwork rejection method.<dd>Stadlober E., et al., WinRand source code, available via FTP, or
+H. Zechner, 'Efficient sampling from continuous and discrete
+unimodal distributions', Doctoral Dissertation, 156pp., Technical
+University Graz, Austria, 1994. 
+<br><dt>For <var>l</var> > 1e8, use normal approximation.<dd>L. Montanet, et al., 'Review of Particle Properties', Physical Review
+D 50 p1284, 1994
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drand.html#doc_002drand">rand</a>, <a href="doc_002drandn.html#doc_002drandn">randn</a>, <a href="doc_002drande.html#doc_002drande">rande</a>, <a href="doc_002drandg.html#doc_002drandg">randg</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/rand.cc -->
+   <p><a name="doc_002drandg"></a>
+
+<div class="defun">
+— Loadable Function:  <b>randg</b> (<var>a, x</var>)<var><a name="index-randg-1343"></a></var><br>
+— Loadable Function:  <b>randg</b> (<var>a, n, m</var>)<var><a name="index-randg-1344"></a></var><br>
+— Loadable Function:  <b>randg</b> (<var>"state", x</var>)<var><a name="index-randg-1345"></a></var><br>
+— Loadable Function:  <b>randg</b> (<var>"seed", x</var>)<var><a name="index-randg-1346"></a></var><br>
+<blockquote><p>Return a matrix with <code>gamma(</code><var>a</var><code>,1)</code> distributed random elements. 
+The arguments are handled the same as the arguments for <code>rand</code>,
+except for the argument <var>a</var>.
+
+        <p>This can be used to generate many distributions:
+
+          <dl>
+<dt><code>gamma (a, b)</code> for <code>a > -1</code>, <code>b > 0</code><dd>
+          <pre class="example">               r = b * randg (a)
+</pre>
+          <br><dt><code>beta (a, b)</code> for <code>a > -1</code>, <code>b > -1</code><dd>
+          <pre class="example">               r1 = randg (a, 1)
+               r = r1 / (r1 + randg (b, 1))
+</pre>
+          <br><dt><code>Erlang (a, n)</code><dd>
+          <pre class="example">               r = a * randg (n)
+</pre>
+          <br><dt><code>chisq (df)</code> for <code>df > 0</code><dd>
+          <pre class="example">               r = 2 * randg (df / 2)
+</pre>
+          <br><dt><code>t(df)</code> for <code>0 < df < inf</code> (use randn if df is infinite)<dd>
+          <pre class="example">               r = randn () / sqrt (2 * randg (df / 2) / df)
+</pre>
+          <br><dt><code>F (n1, n2)</code> for <code>0 < n1</code>, <code>0 < n2</code><dd>
+          <pre class="example">               ## r1 equals 1 if n1 is infinite
+               r1 = 2 * randg (n1 / 2) / n1
+               ## r2 equals 1 if n2 is infinite
+               r2 = 2 * randg (n2 / 2) / n2
+               r = r1 / r2
+</pre>
+          <br><dt>negative <code>binomial (n, p)</code> for <code>n > 0</code>, <code>0 < p <= 1</code><dd>
+          <pre class="example">               r = randp ((1 - p) / p * randg (n))
+</pre>
+          <br><dt>non-central <code>chisq (df, L)</code>, for <code>df >= 0</code> and <code>L > 0</code><dd>(use chisq if <code>L = 0</code>)
+          <pre class="example">               r = randp (L / 2)
+               r(r > 0) = 2 * randg (r(r > 0))
+               r(df > 0) += 2 * randg (df(df > 0)/2)
+</pre>
+          <br><dt><code>Dirichlet (a1, ... ak)</code><dd>
+          <pre class="example">               r = (randg (a1), ..., randg (ak))
+               r = r / sum (r)
+</pre>
+          </dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drand.html#doc_002drand">rand</a>, <a href="doc_002drandn.html#doc_002drandn">randn</a>, <a href="doc_002drande.html#doc_002drande">rande</a>, <a href="doc_002drandp.html#doc_002drandp">randp</a>. 
+</p></blockquote></div>
+
+   <p>The generators operate in the new or old style together, it is not
+possible to mix the two.  Initializing any generator with
+<code>"state"</code> or <code>"seed"</code> causes the others to switch to the
+same style for future calls.
+
+   <p>The state of each generator is independent and calls to different
+generators can be interleaved without affecting the final result.  For
+example,
+
+<pre class="example">     rand ("state", [11, 22, 33]);
+     randn ("state", [44, 55, 66]);
+     u = rand (100, 1);
+     n = randn (100, 1);
+</pre>
+   <p class="noindent">and
+
+<pre class="example">     rand ("state", [11, 22, 33]);
+     randn ("state", [44, 55, 66]);
+     u = zeros (100, 1);
+     n = zeros (100, 1);
+     for i = 1:100
+       u(i) = rand ();
+       n(i) = randn ();
+     end
+</pre>
+   <p class="noindent">produce equivalent results.  When the generators are initialized in
+the old style with <code>"seed"</code> only <code>rand</code> and <code>randn</code> are
+independent, because the old <code>rande</code>, <code>randg</code> and
+<code>randp</code> generators make calls to <code>rand</code> and <code>randn</code>.
+
+   <p>The generators are initialized with random states at start-up, so
+that the sequences of random numbers are not the same each time you run
+Octave.<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a> If you really do
+need to reproduce a sequence of numbers exactly, you can set the state
+or seed to a specific value.
+
+   <p>If invoked without arguments, <code>rand</code> and <code>randn</code> return a
+single element of a random sequence.
+
+   <p>The original <code>rand</code> and <code>randn</code> functions use Fortran code from
+<span class="sc">Ranlib</span>, a library of fortran routines for random number generation,
+compiled by Barry W. Brown and James Lovato of the Department of
+Biomathematics at The University of Texas, M.D. Anderson Cancer Center,
+Houston, TX 77030.
+
+<!-- ./general/randperm.m -->
+   <p><a name="doc_002drandperm"></a>
+
+<div class="defun">
+— Function File:  <b>randperm</b> (<var>n</var>)<var><a name="index-randperm-1347"></a></var><br>
+<blockquote><p>Return a row vector containing a random permutation of the
+integers from 1 to <var>n</var>. 
+</p></blockquote></div>
+
+   <p>The functions <code>linspace</code> and <code>logspace</code> make it very easy to
+create vectors with evenly or logarithmically spaced elements. 
+See <a href="Ranges.html#Ranges">Ranges</a>.
+
+<!-- data.cc -->
+   <p><a name="doc_002dlinspace"></a>
+
+<div class="defun">
+— Built-in Function:  <b>linspace</b> (<var>base, limit, n</var>)<var><a name="index-linspace-1348"></a></var><br>
+<blockquote><p>Return a row vector with <var>n</var> linearly spaced elements between
+<var>base</var> and <var>limit</var>.  If the number of elements is greater than one,
+then the <var>base</var> and <var>limit</var> are always included in
+the range.  If <var>base</var> is greater than <var>limit</var>, the elements are
+stored in decreasing order.  If the number of points is not specified, a
+value of 100 is used.
+
+        <p>The <code>linspace</code> function always returns a row vector.
+
+        <p>For compatibility with <span class="sc">matlab</span>, return the second argument if
+fewer than two values are requested. 
+</p></blockquote></div>
+
+<!-- ./general/logspace.m -->
+   <p><a name="doc_002dlogspace"></a>
+
+<div class="defun">
+— Function File:  <b>logspace</b> (<var>base, limit, n</var>)<var><a name="index-logspace-1349"></a></var><br>
+<blockquote><p>Similar to <code>linspace</code> except that the values are logarithmically
+spaced from
+10^base to 10^limit.
+
+        <p>If <var>limit</var> is equal to
+pi,
+the points are between
+10^base and pi,
+<em>not</em>
+10^base and 10^pi,
+in order to be compatible with the corresponding <span class="sc">matlab</span>
+function.
+
+        <p>Also for compatibility, return the second argument if fewer than two
+values are requested. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlinspace.html#doc_002dlinspace">linspace</a>. 
+</p></blockquote></div>
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> The old versions of <code>rand</code> and <code>randn</code>
+obtain their initial seeds from the system clock.</p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Specialized-Solvers.html b/doc/interpreter/HTML/Specialized-Solvers.html
new file mode 100644
index 0000000..e80edef
--- /dev/null
+++ b/doc/interpreter/HTML/Specialized-Solvers.html
@@ -0,0 +1,91 @@
+<html lang="en">
+<head>
+<title>Specialized Solvers - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link rel="prev" href="Functions-of-a-Matrix.html#Functions-of-a-Matrix" title="Functions of a Matrix">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Specialized-Solvers"></a>
+Previous: <a rel="previous" accesskey="p" href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a>,
+Up: <a rel="up" accesskey="u" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>
+<hr>
+</div>
+
+<h3 class="section">18.5 Specialized Solvers</h3>
+
+<!-- ./sparse/bicgstab.m -->
+<p><a name="doc_002dbicgstab"></a>
+
+<div class="defun">
+— Function File:  <b>bicgstab</b> (<var>A, b</var>)<var><a name="index-bicgstab-1627"></a></var><br>
+— Function File:  <b>bicgstab</b> (<var>A, b, tol, maxit, M1, M2, x0</var>)<var><a name="index-bicgstab-1628"></a></var><br>
+<blockquote><p>This procedure attempts to solve a system of linear equations A*x = b for x. 
+The <var>A</var> must be square, symmetric and positive definite real matrix N*N. 
+The <var>b</var> must be a one column vector with a length of N. 
+The <var>tol</var> specifies the tolerance of the method, the default value is 1e-6. 
+The <var>maxit</var> specifies the maximum number of iterations, the default value is min(20,N). 
+The <var>M1</var> specifies a preconditioner, can also be a function handler which returns M\X. 
+The <var>M2</var> combined with <var>M1</var> defines preconditioner as preconditioner=M1*M2. 
+The <var>x0</var> is the initial guess, the default value is zeros(N,1).
+
+        <p>The value <var>x</var> is a computed result of this procedure. 
+The value <var>flag</var> can be 0 when we reach tolerance in <var>maxit</var> iterations, 1 when
+we don't reach tolerance in <var>maxit</var> iterations and 3 when the procedure stagnates. 
+The value <var>relres</var> is a relative residual - norm(b-A*x)/norm(b). 
+The value <var>iter</var> is an iteration number in which x was computed. 
+The value <var>resvec</var> is a vector of <var>relres</var> for each iteration.
+
+        </blockquote></div>
+
+<!-- ./sparse/cgs.m -->
+   <p><a name="doc_002dcgs"></a>
+
+<div class="defun">
+— Function File:  <b>cgs</b> (<var>A, b</var>)<var><a name="index-cgs-1629"></a></var><br>
+— Function File:  <b>cgs</b> (<var>A, b, tol, maxit, M1, M2, x0</var>)<var><a name="index-cgs-1630"></a></var><br>
+<blockquote><p>This procedure attempts to solve a system of linear equations A*x = b for x. 
+The <var>A</var> must be square, symmetric and positive definite real matrix N*N. 
+The <var>b</var> must be a one column vector with a length of N. 
+The <var>tol</var> specifies the tolerance of the method, default value is 1e-6. 
+The <var>maxit</var> specifies the maximum number of iteration, default value is MIN(20,N). 
+The <var>M1</var> specifies a preconditioner, can also be a function handler which returns M\X. 
+The <var>M2</var> combined with <var>M1</var> defines preconditioner as preconditioner=M1*M2. 
+The <var>x0</var> is initial guess, default value is zeros(N,1).
+
+        </blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Stair-group.html b/doc/interpreter/HTML/Stair-group.html
new file mode 100644
index 0000000..33cf393
--- /dev/null
+++ b/doc/interpreter/HTML/Stair-group.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Stair group - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Scatter-group.html#Scatter-group" title="Scatter group">
+<link rel="next" href="Stem-Series.html#Stem-Series" title="Stem Series">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Stair-group"></a>
+Next: <a rel="next" accesskey="n" href="Stem-Series.html#Stem-Series">Stem Series</a>,
+Previous: <a rel="previous" accesskey="p" href="Scatter-group.html#Scatter-group">Scatter group</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.9 Stair group</h5>
+
+<p><a name="index-group-objects-1246"></a><a name="index-stair-group-1247"></a>
+Stair series objects are created by the <code>stair</code> function.  Each
+<code>hggroup</code> element of the series contains a single line object as a
+child representing the stair.  The properties of the stair series are
+
+     <dl>
+<dt><code>color</code><dd>The RGB color or color name of the line objects of the stairs.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the line objects of the stairs.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>The line and fill color of the markers on the stairs.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dd>The original x and y data of the stairs.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Standalone-Programs.html b/doc/interpreter/HTML/Standalone-Programs.html
new file mode 100644
index 0000000..213049f
--- /dev/null
+++ b/doc/interpreter/HTML/Standalone-Programs.html
@@ -0,0 +1,149 @@
+<html lang="en">
+<head>
+<title>Standalone Programs - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions" title="Dynamically Linked Functions">
+<link rel="prev" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Standalone-Programs"></a>
+Previous: <a rel="previous" accesskey="p" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>
+<hr>
+</div>
+
+<h3 class="section">A.3 Standalone Programs</h3>
+
+<p>The libraries Octave itself uses, can be utilized in standalone
+applications.  These applications then have access, for example, to the
+array and matrix classes as well as to all the Octave algorithms.  The
+following C++ program, uses class Matrix from liboctave.a or
+liboctave.so.
+
+<pre class="example"><pre class="verbatim">     #include <iostream>
+     #include <octave/oct.h>
+     
+     int
+     main (void)
+     {
+       std::cout << "Hello Octave world!\n";
+       int n = 2;
+       Matrix a_matrix = Matrix (n, n);
+       for (octave_idx_type i = 0; i < n; i++)
+         {
+           for (octave_idx_type j = 0; j < n; j++)
+             {
+               a_matrix (i, j) = (i + 1) * 10 + (j + 1);
+             }
+         }
+       std::cout << a_matrix;
+       return 0;
+     }
+</pre>
+</pre>
+   <p class="noindent">mkoctfile can then be used to build a standalone application with a
+command like
+
+<pre class="example">     $ mkoctfile --link-stand-alone standalone.cc -o standalone
+     $ ./standalone
+     Hello Octave world!
+       11 12
+       21 22
+     $
+</pre>
+   <p>Note that the application <code>hello</code> will be dynamically linked
+against the octave libraries and any octave support libraries.  The above
+allows the Octave math libraries to be used by an application.  It does
+not however allow the script files, oct-files or builtin functions of
+Octave to be used by the application.  To do that the Octave interpreter
+needs to be initialized first.  An example of how to do this can then be
+seen in the code
+
+<pre class="example"><pre class="verbatim">     #include <iostream>
+     #include <octave/oct.h>
+     #include <octave/octave.h>
+     #include <octave/parse.h>
+     
+     int
+     main (void)
+     {
+       string_vector argv (2);
+       argv(0) = "embedded";
+       argv(1) = "-q";
+     
+       octave_main (2, argv.c_str_vec(), 1);
+     
+       octave_idx_type n = 2;
+       Matrix a_matrix = Matrix (1, 2);
+     
+       std::cout << "GCD of [";
+       for (octave_idx_type i = 0; i < n; i++)
+         {
+           a_matrix (i) = 5 * (i + 1); 
+           if (i != 0)
+     	std::cout << ", " << 5 * (i + 2);
+           else
+     	std::cout << 5 * (i + 2);
+         }
+       std::cout << "] is ";
+     
+       octave_value_list in = octave_value (a_matrix);
+       octave_value_list out = feval ("gcd", in, 1);
+     
+       if (!error_state && out.length () > 0)
+         {
+           a_matrix = out(0).matrix_value ();
+           if (a_matrix.numel () == 1)
+     	std::cout << a_matrix(0) << "\n";
+           else
+     	std::cout << "invalid\n";
+         }
+       else
+         std::cout << "invalid\n";
+     
+       return 0;
+     }
+</pre>
+</pre>
+   <p class="noindent">which is compiled and run as before as a standalone application with
+
+<pre class="example">     $ mkoctfile --link-stand-alone embedded.cc -o embedded
+     $ ./embedded
+     GCD of [10, 15] is 5
+     $
+</pre>
+   <!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2005, 2007, 2009 David Bateman -->
+<!-- Copyright (C) 2002, 2003, 2004, 2005 Paul Kienzle -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Startup-Files.html b/doc/interpreter/HTML/Startup-Files.html
new file mode 100644
index 0000000..687ba51
--- /dev/null
+++ b/doc/interpreter/HTML/Startup-Files.html
@@ -0,0 +1,77 @@
+<html lang="en">
+<head>
+<title>Startup Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line" title="Invoking Octave from the Command Line">
+<link rel="prev" href="Command-Line-Options.html#Command-Line-Options" title="Command Line Options">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Startup-Files"></a>
+Previous: <a rel="previous" accesskey="p" href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a>,
+Up: <a rel="up" accesskey="u" href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">Invoking Octave from the Command Line</a>
+<hr>
+</div>
+
+<h4 class="subsection">2.1.2 Startup Files</h4>
+
+<p><a name="index-initialization-68"></a><a name="index-startup-69"></a>
+When Octave starts, it looks for commands to execute from the files in
+the following list.  These files may contain any valid Octave commands,
+including function definitions.
+
+   <p><a name="index-startup-files-70"></a>
+     <dl>
+<dt><var>octave-home</var><code>/share/octave/site/m/startup/octaverc</code><dd><a name="index-site-startup-file-71"></a>where <var>octave-home</var> is the directory in which Octave is installed
+(the default is <samp><span class="file">/usr/local</span></samp>). 
+This file is provided so that changes to the default Octave environment
+can be made globally for all users at your site for all versions of Octave
+you have installed.  Care should be taken when making changes to this file
+since all users of Octave at your site will be affected.  The default file
+may be overridden by the environment variable <code>OCTAVE_SITE_INITFILE</code><!-- /@w -->.
+
+     <br><dt><var>octave-home</var><code>/share/octave/</code><var>version</var><code>/m/startup/octaverc</code><dd><a name="index-version-startup-file-72"></a>where <var>octave-home</var> is the directory in which Octave is
+installed (the default is <samp><span class="file">/usr/local</span></samp>), and <var>version</var>
+is the version number of Octave.  This file is provided so that changes
+to the default Octave environment can be made globally for all users of
+a particular version of Octave.  Care should be taken when making
+changes to this file since all users of Octave at your site will be
+affected.  The default file may be overridden by the environment variable
+<code>OCTAVE_VERSION_INITFILE</code><!-- /@w -->.
+
+     <br><dt><code>~/.octaverc</code><dd><a name="index-personal-startup-file-73"></a><a name="index-g_t_0040code_007b_007e_002f_002eoctaverc_007d-74"></a>This file is used to make personal changes to the default
+Octave environment.
+
+     <br><dt><code>.octaverc</code><dd><a name="index-project-startup-file-75"></a><a name="index-g_t_0040code_007b_002eoctaverc_007d-76"></a>This file can be used to make changes to the default Octave environment
+for a particular project.  Octave searches for this file in the current
+directory after it reads <samp><span class="file">~/.octaverc</span></samp>.  Any use of the <code>cd</code>
+command in the <samp><span class="file">~/.octaverc</span></samp> file will affect the directory where
+Octave searches for <samp><span class="file">.octaverc</span></samp>.
+
+     <p>If you start Octave in your home directory, commands from the file
+<samp><span class="file">~/.octaverc</span></samp> will only be executed once. 
+</dl>
+
+   <p>A message will be displayed as each of the startup files is read if you
+invoke Octave with the <code>--verbose</code> option but without the
+<code>--silent</code> option.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Statements.html b/doc/interpreter/HTML/Statements.html
new file mode 100644
index 0000000..44ef3d2
--- /dev/null
+++ b/doc/interpreter/HTML/Statements.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>Statements - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Evaluation.html#Evaluation" title="Evaluation">
+<link rel="next" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Statements"></a>
+Next: <a rel="next" accesskey="n" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>,
+Previous: <a rel="previous" accesskey="p" href="Evaluation.html#Evaluation">Evaluation</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">10 Statements</h2>
+
+<p><a name="index-statements-554"></a>
+Statements may be a simple constant expression or a complicated list of
+nested loops and conditional statements.
+
+   <p><dfn>Control statements</dfn> such as <code>if</code>, <code>while</code>, and so on
+control the flow of execution in Octave programs.  All the control
+statements start with special keywords such as <code>if</code> and
+<code>while</code>, to distinguish them from simple expressions. 
+Many control statements contain other statements; for example, the
+<code>if</code> statement contains another statement which may or may not be
+executed.
+
+   <p><a name="index-g_t_0040code_007bend_007d-statement-555"></a>Each control statement has a corresponding <dfn>end</dfn> statement that
+marks the end of the control statement.  For example, the
+keyword <code>endif</code> marks the end of an <code>if</code> statement, and
+<code>endwhile</code> marks the end of a <code>while</code> statement.  You can use
+the keyword <code>end</code> anywhere a more specific end keyword is expected,
+but using the more specific keywords is preferred because if you use
+them, Octave is able to provide better diagnostics for mismatched or
+missing end tokens.
+
+   <p>The list of statements contained between keywords like <code>if</code> or
+<code>while</code> and the corresponding end statement is called the
+<dfn>body</dfn> of a control statement.
+
+<ul class="menu">
+<li><a accesskey="1" href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a>
+<li><a accesskey="2" href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a>
+<li><a accesskey="3" href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a>
+<li><a accesskey="4" href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement">The <code>do-until</code> Statement</a>
+<li><a accesskey="5" href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a>
+<li><a accesskey="6" href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#The-_003ccode_003ebreak_003c_002fcode_003e-Statement">The <code>break</code> Statement</a>
+<li><a accesskey="7" href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#The-_003ccode_003econtinue_003c_002fcode_003e-Statement">The <code>continue</code> Statement</a>
+<li><a accesskey="8" href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a>
+<li><a accesskey="9" href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>
+<li><a href="Continuation-Lines.html#Continuation-Lines">Continuation Lines</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Statistical-Plots.html b/doc/interpreter/HTML/Statistical-Plots.html
new file mode 100644
index 0000000..229a329
--- /dev/null
+++ b/doc/interpreter/HTML/Statistical-Plots.html
@@ -0,0 +1,104 @@
+<html lang="en">
+<head>
+<title>Statistical Plots - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="prev" href="Basic-Statistical-Functions.html#Basic-Statistical-Functions" title="Basic Statistical Functions">
+<link rel="next" href="Tests.html#Tests" title="Tests">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Statistical-Plots"></a>
+Next: <a rel="next" accesskey="n" href="Tests.html#Tests">Tests</a>,
+Previous: <a rel="previous" accesskey="p" href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.3 Statistical Plots</h3>
+
+<!-- Should hist be moved to here, or perhaps the qqplot and ppplot -->
+<!-- functions should be moved to the Plotting Chapter? -->
+<p>Octave can create Quantile Plots (QQ-Plots), and Probability Plots
+(PP-Plots).  These are simple graphical tests for determining if a
+data set comes from a certain distribution.
+
+   <p>Note that Octave can also show histograms of data
+using the <code>hist</code> function as described in
+<a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a>.
+
+<!-- ./statistics/base/qqplot.m -->
+   <p><a name="doc_002dqqplot"></a>
+
+<div class="defun">
+— Function File: [<var>q</var>, <var>s</var>] = <b>qqplot</b> (<var>x, dist, params</var>)<var><a name="index-qqplot-1863"></a></var><br>
+<blockquote><p>Perform a QQ-plot (quantile plot).
+
+        <p>If F is the CDF of the distribution <var>dist</var> with parameters
+<var>params</var> and G its inverse, and <var>x</var> a sample vector of length
+<var>n</var>, the QQ-plot graphs ordinate <var>s</var>(<var>i</var>) = <var>i</var>-th
+largest element of x versus abscissa <var>q</var>(<var>i</var>f) = G((<var>i</var> -
+0.5)/<var>n</var>).
+
+        <p>If the sample comes from F except for a transformation of location
+and scale, the pairs will approximately follow a straight line.
+
+        <p>The default for <var>dist</var> is the standard normal distribution.  The
+optional argument <var>params</var> contains a list of parameters of
+<var>dist</var>.  For example, for a quantile plot of the uniform
+distribution on [2,4] and <var>x</var>, use
+
+     <pre class="example">          qqplot (x, "uniform", 2, 4)
+</pre>
+        <p class="noindent"><var>dist</var> can be any string for which a function <var>dist_inv</var>
+that calculates the inverse CDF of distribution <var>dist</var> exists.
+
+        <p>If no output arguments are given, the data are plotted directly. 
+</p></blockquote></div>
+
+<!-- ./statistics/base/ppplot.m -->
+   <p><a name="doc_002dppplot"></a>
+
+<div class="defun">
+— Function File: [<var>p</var>, <var>y</var>] = <b>ppplot</b> (<var>x, dist, params</var>)<var><a name="index-ppplot-1864"></a></var><br>
+<blockquote><p>Perform a PP-plot (probability plot).
+
+        <p>If F is the CDF of the distribution <var>dist</var> with parameters
+<var>params</var> and <var>x</var> a sample vector of length <var>n</var>, the
+PP-plot graphs ordinate <var>y</var>(<var>i</var>) = F (<var>i</var>-th largest
+element of <var>x</var>) versus abscissa <var>p</var>(<var>i</var>) = (<var>i</var> -
+0.5)/<var>n</var>.  If the sample comes from F, the pairs will
+approximately follow a straight line.
+
+        <p>The default for <var>dist</var> is the standard normal distribution.  The
+optional argument <var>params</var> contains a list of parameters of
+<var>dist</var>.  For example, for a probability plot of the uniform
+distribution on [2,4] and <var>x</var>, use
+
+     <pre class="example">          ppplot (x, "uniform", 2, 4)
+</pre>
+        <p class="noindent"><var>dist</var> can be any string for which a function <var>dist_cdf</var>
+that calculates the CDF of distribution <var>dist</var> exists.
+
+        <p>If no output arguments are given, the data are plotted directly. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Statistics.html b/doc/interpreter/HTML/Statistics.html
new file mode 100644
index 0000000..d74297f
--- /dev/null
+++ b/doc/interpreter/HTML/Statistics.html
@@ -0,0 +1,66 @@
+<html lang="en">
+<head>
+<title>Statistics - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Optimization.html#Optimization" title="Optimization">
+<link rel="next" href="Sets.html#Sets" title="Sets">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Statistics"></a>
+Next: <a rel="next" accesskey="n" href="Sets.html#Sets">Sets</a>,
+Previous: <a rel="previous" accesskey="p" href="Optimization.html#Optimization">Optimization</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">25 Statistics</h2>
+
+<p>Octave has support for various statistical methods.  This includes
+basic descriptive statistics, statistical tests, random number generation,
+and much more.
+
+   <p>The functions that analyze data all assume that multidimensional data
+is arranged in a matrix where each row is an observation, and each
+column is a variable.  So, the matrix defined by
+
+<pre class="example">     a = [ 0.9, 0.7;
+           0.1, 0.1;
+           0.5, 0.4 ];
+</pre>
+   <p class="noindent">contains three observations from a two-dimensional distribution. 
+While this is the default data arrangement, most functions support
+different arrangements.
+
+   <p>It should be noted that the statistics functions don't test for data
+containing NaN, NA, or Inf.  Such values need to be handled explicitly.
+
+<ul class="menu">
+<li><a accesskey="1" href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a>
+<li><a accesskey="2" href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a>
+<li><a accesskey="3" href="Statistical-Plots.html#Statistical-Plots">Statistical Plots</a>
+<li><a accesskey="4" href="Tests.html#Tests">Tests</a>
+<li><a accesskey="5" href="Models.html#Models">Models</a>
+<li><a accesskey="6" href="Distributions.html#Distributions">Distributions</a>
+<li><a accesskey="7" href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Status-of-Variables.html b/doc/interpreter/HTML/Status-of-Variables.html
new file mode 100644
index 0000000..8bd52f2
--- /dev/null
+++ b/doc/interpreter/HTML/Status-of-Variables.html
@@ -0,0 +1,349 @@
+<html lang="en">
+<head>
+<title>Status of Variables - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Variables.html#Variables" title="Variables">
+<link rel="prev" href="Persistent-Variables.html#Persistent-Variables" title="Persistent Variables">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Status-of-Variables"></a>
+Previous: <a rel="previous" accesskey="p" href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a>,
+Up: <a rel="up" accesskey="u" href="Variables.html#Variables">Variables</a>
+<hr>
+</div>
+
+<h3 class="section">7.3 Status of Variables</h3>
+
+<p>When creating simple one-shot programs it can be very convenient to
+see which variables are available at the prompt.  The function <code>who</code>
+and its siblings <code>whos</code> and <code>whos_line_format</code> will show
+different information about what is in memory, as the following shows.
+
+<pre class="example">     str = "A random string";
+     who -variables
+          -| *** local user variables:
+          -|
+          -| __nargin__  str
+</pre>
+   <!-- variables.cc -->
+   <p><a name="doc_002dwho"></a>
+
+<div class="defun">
+— Command: <b>who</b><var><a name="index-who-430"></a></var><br>
+— Command: <b>who</b><var> pattern <small class="dots">...</small><a name="index-who-431"></a></var><br>
+— Command: <b>who</b><var> option pattern <small class="dots">...</small><a name="index-who-432"></a></var><br>
+— Command: <b>C</b><var> = who</var>(<var>"pattern", <small class="dots">...</small></var>)<var><a name="index-C-433"></a></var><br>
+<blockquote><p>List currently defined variables matching the given patterns.  Valid
+pattern syntax is the same as described for the <code>clear</code> command. 
+If no patterns are supplied, all variables are listed. 
+By default, only variables visible in the local scope are displayed.
+
+        <p>The following are valid options but may not be combined.
+
+          <dl>
+<dt><code>global</code><dd>List variables in the global scope rather than the current scope. 
+<br><dt><code>-regexp</code><dd>The patterns are considered to be regular expressions when matching the
+variables to display.  The same pattern syntax accepted by
+the <code>regexp</code> function is used. 
+<br><dt><code>-file</code><dd>The next argument is treated as a filename.  All variables found within the
+specified file are listed.  No patterns are accepted when reading variables
+from a file. 
+</dl>
+
+        <p>If called as a function, return a cell array of defined variable names
+matching the given patterns. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwhos.html#doc_002dwhos">whos</a>, <a href="doc_002dregexp.html#doc_002dregexp">regexp</a>. 
+</p></blockquote></div>
+
+<!-- variables.cc -->
+   <p><a name="doc_002dwhos"></a>
+
+<div class="defun">
+— Command: <b>whos</b><var><a name="index-whos-434"></a></var><br>
+— Command: <b>whos</b><var> pattern <small class="dots">...</small><a name="index-whos-435"></a></var><br>
+— Command: <b>whos</b><var> option pattern <small class="dots">...</small><a name="index-whos-436"></a></var><br>
+— Command: <b>S</b><var> = whos</var>(<var>"pattern", <small class="dots">...</small></var>)<var><a name="index-S-437"></a></var><br>
+<blockquote><p>Provide detailed information on currently defined variables matching the
+given patterns.  Options and pattern syntax are the same as for the
+<code>who</code> command.  Extended information about each variable is
+summarized in a table with the following default entries.
+
+          <dl>
+<dt>Attr<dd>Attributes of the listed variable.  Possible attributes are:
+               <dl>
+<dt>blank<dd>Variable in local scope
+<br><dt><code>g</code><dd>Variable with global scope
+<br><dt><code>p</code><dd>Persistent variable
+</dl>
+          <br><dt>Name<dd>The name of the variable. 
+<br><dt>Size<dd>The logical size of the variable.  A scalar is 1x1, a vector is 1xN or Nx1,
+a 2-D matrix is MxN. 
+<br><dt>Bytes<dd>The amount of memory currently used to store the variable. 
+<br><dt>Class<dd>The class of the variable.  Examples include double, single, char, uint16,
+cell, and struct. 
+</dl>
+
+        <p>The table can be customized to display more or less information through
+the function <code>whos_line_format</code>.
+
+        <p>If <code>whos</code> is called as a function, return a struct array of defined
+variable names matching the given patterns.  Fields in the structure
+describing each variable are: name, size, bytes, class, global, sparse,
+complex, nesting, persistent. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwho.html#doc_002dwho">who</a>, <a href="doc_002dwhos_005fline_005fformat.html#doc_002dwhos_005fline_005fformat">whos_line_format</a>. 
+</p></blockquote></div>
+
+<!-- variables.cc -->
+   <p><a name="doc_002dwhos_005fline_005fformat"></a>
+
+<div class="defun">
+— Built-in Function: <var>val</var> = <b>whos_line_format</b> ()<var><a name="index-whos_005fline_005fformat-438"></a></var><br>
+— Built-in Function: <var>old_val</var> = <b>whos_line_format</b> (<var>new_val</var>)<var><a name="index-whos_005fline_005fformat-439"></a></var><br>
+<blockquote><p>Query or set the format string used by the command <code>whos</code>.
+
+        <p>A full format string is:
+
+     <!-- Set example in small font to prevent overfull line -->
+     <pre class="smallexample">          %[modifier]<command>[:width[:left-min[:balance]]];
+</pre>
+        <p>The following command sequences are available:
+
+          <dl>
+<dt><code>%a</code><dd>Prints attributes of variables (g=global, p=persistent,
+f=formal parameter, a=automatic variable). 
+<br><dt><code>%b</code><dd>Prints number of bytes occupied by variables. 
+<br><dt><code>%c</code><dd>Prints class names of variables. 
+<br><dt><code>%e</code><dd>Prints elements held by variables. 
+<br><dt><code>%n</code><dd>Prints variable names. 
+<br><dt><code>%s</code><dd>Prints dimensions of variables. 
+<br><dt><code>%t</code><dd>Prints type names of variables. 
+</dl>
+
+        <p>Every command may also have an alignment modifier:
+
+          <dl>
+<dt><code>l</code><dd>Left alignment. 
+<br><dt><code>r</code><dd>Right alignment (default). 
+<br><dt><code>c</code><dd>Column-aligned (only applicable to command %s). 
+</dl>
+
+        <p>The <code>width</code> parameter is a positive integer specifying the minimum
+number of columns used for printing.  No maximum is needed as the field will
+auto-expand as required.
+
+        <p>The parameters <code>left-min</code> and <code>balance</code> are only available when the
+column-aligned modifier is used with the command ‘<samp><span class="samp">%s</span></samp>’. 
+<code>balance</code> specifies the column number within the field width which will
+be aligned between entries.  Numbering starts from 0 which indicates the
+leftmost column.  <code>left-min</code> specifies the minimum field width to the
+left of the specified balance column.
+
+        <p>The default format is
+<code>"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\n"</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwhos.html#doc_002dwhos">whos</a>. 
+</p></blockquote></div>
+
+   <p>Instead of displaying which variables are in memory, it is possible
+to determine if a given variable is available.  That way it is possible
+to alter the behavior of a program depending on the existence of a
+variable.  The following example illustrates this.
+
+<pre class="example">     if (! exist ("meaning", "var"))
+       disp ("The program has no 'meaning'");
+     endif
+</pre>
+   <!-- variables.cc -->
+   <p><a name="doc_002dexist"></a>
+
+<div class="defun">
+— Built-in Function:  <b>exist</b> (<var>name, type</var>)<var><a name="index-exist-440"></a></var><br>
+<blockquote><p>Return 1 if the name exists as a variable, 2 if the name is an
+absolute file name, an ordinary file in Octave's <code>path</code>, or (after
+appending ‘<samp><span class="samp">.m</span></samp>’) a function file in Octave's <code>path</code>, 3 if the
+name is a ‘<samp><span class="samp">.oct</span></samp>’ or ‘<samp><span class="samp">.mex</span></samp>’ file in Octave's <code>path</code>,
+5 if the name is a built-in function, 7 if the name is a directory, or 103
+if the name is a function not associated with a file (entered on
+the command line).
+
+        <p>Otherwise, return 0.
+
+        <p>This function also returns 2 if a regular file called <var>name</var>
+exists in Octave's search path.  If you want information about
+other types of files, you should use some combination of the functions
+<code>file_in_path</code> and <code>stat</code> instead.
+
+        <p>If the optional argument <var>type</var> is supplied, check only for
+symbols of the specified type.  Valid types are
+
+          <dl>
+<dt>‘<samp><span class="samp">"var"</span></samp>’<dd>Check only for variables. 
+<br><dt>‘<samp><span class="samp">"builtin"</span></samp>’<dd>Check only for built-in functions. 
+<br><dt>‘<samp><span class="samp">"file"</span></samp>’<dd>Check only for files. 
+<br><dt>‘<samp><span class="samp">"dir"</span></samp>’<dd>Check only for directories. 
+</dl>
+        </p></blockquote></div>
+
+   <p>Usually Octave will manage the memory, but sometimes it can be practical
+to remove variables from memory manually.  This is usually needed when
+working with large variables that fill a substantial part of the memory. 
+On a computer that uses the IEEE floating point format, the following
+program allocates a matrix that requires around 128 MB memory.
+
+<pre class="example">     large_matrix = zeros (4000, 4000);
+</pre>
+   <p class="noindent">Since having this variable in memory might slow down other computations,
+it can be necessary to remove it manually from memory.  The <code>clear</code>
+function allows this.
+
+<!-- variables.cc -->
+   <p><a name="doc_002dclear"></a>
+
+<div class="defun">
+— Command: <b>clear</b> [<var>options</var>]<var> pattern <small class="dots">...</small><a name="index-clear-441"></a></var><br>
+<blockquote><p>Delete the names matching the given patterns from the symbol table.  The
+pattern may contain the following special characters:
+
+          <dl>
+<dt><code>?</code><dd>Match any single character.
+
+          <br><dt><code>*</code><dd>Match zero or more characters.
+
+          <br><dt><code>[ </code><var>list</var><code> ]</code><dd>Match the list of characters specified by <var>list</var>.  If the first
+character is <code>!</code> or <code>^</code>, match all characters except those
+specified by <var>list</var>.  For example, the pattern ‘<samp><span class="samp">[a-zA-Z]</span></samp>’ will
+match all lower and upper case alphabetic characters. 
+</dl>
+
+        <p>For example, the command
+
+     <pre class="example">          clear foo b*r
+</pre>
+        <p class="noindent">clears the name <code>foo</code> and all names that begin with the letter
+<code>b</code> and end with the letter <code>r</code>.
+
+        <p>If <code>clear</code> is called without any arguments, all user-defined
+variables (local and global) are cleared from the symbol table.  If
+<code>clear</code> is called with at least one argument, only the visible
+names matching the arguments are cleared.  For example, suppose you have
+defined a function <code>foo</code>, and then hidden it by performing the
+assignment <code>foo = 2</code>.  Executing the command <kbd>clear foo</kbd> once
+will clear the variable definition and restore the definition of
+<code>foo</code> as a function.  Executing <kbd>clear foo</kbd> a second time will
+clear the function definition.
+
+        <p>The following options are available in both long and short form
+          <dl>
+<dt><code>-all, -a</code><dd>Clears all local and global user-defined variables and all functions
+from the symbol table.
+
+          <br><dt><code>-exclusive, -x</code><dd>Clears the variables that don't match the following pattern.
+
+          <br><dt><code>-functions, -f</code><dd>Clears the function names and the built-in symbols names. 
+<br><dt><code>-global, -g</code><dd>Clears the global symbol names. 
+<br><dt><code>-variables, -v</code><dd>Clears the local variable names. 
+<br><dt><code>-classes, -c</code><dd>Clears the class structure table and clears all objects. 
+<br><dt><code>-regexp, -r</code><dd>The arguments are treated as regular expressions as any variables that
+match will be cleared. 
+</dl>
+        With the exception of <code>exclusive</code>, all long options can be used
+without the dash as well. 
+</p></blockquote></div>
+
+   <p>Information about a function or variable such as its location in the
+file system can also be acquired from within Octave.  This is usually
+only useful during development of programs, and not within a program.
+
+<!-- ./help/type.m -->
+   <p><a name="doc_002dtype"></a>
+
+<div class="defun">
+— Command: type <b>options</b><var> name <small class="dots">...</small><a name="index-options-442"></a></var><br>
+<blockquote><p>Display the definition of each <var>name</var> that refers to a function.
+
+        <p>Normally also displays whether each <var>name</var> is user-defined or built-in;
+the <code>-q</code> option suppresses this behavior.
+
+        <p>If an output argument is requested nothing is displayed.  Instead, a cell
+array of strings is returned, where each element corresponds to the
+definition of each requested function. 
+</p></blockquote></div>
+
+<!-- ./help/which.m -->
+   <p><a name="doc_002dwhich"></a>
+
+<div class="defun">
+— Command: <b>which</b><var> name <small class="dots">...</small><a name="index-which-443"></a></var><br>
+<blockquote><p>Display the type of each <var>name</var>.  If <var>name</var> is defined from a
+function file, the full name of the file is also displayed. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhelp.html#doc_002dhelp">help</a>, <a href="doc_002dlookfor.html#doc_002dlookfor">lookfor</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/what.m -->
+   <p><a name="doc_002dwhat"></a>
+
+<div class="defun">
+— Command:  <b>what</b><var><a name="index-what-444"></a></var><br>
+— Command:  <b>what</b><var> dir<a name="index-what-445"></a></var><br>
+— Function File: w = <b>what</b> (<var>dir</var>)<var><a name="index-what-446"></a></var><br>
+<blockquote><p>List the Octave specific files in a directory.  If the variable <var>dir</var>
+is given then check that directory rather than the current directory.  If
+a return argument is requested, the files found are returned in the
+structure <var>w</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dwhich.html#doc_002dwhich">which</a>. 
+</p></blockquote></div>
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2006, -->
+<!-- 2007, 2008, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Stem-Series.html b/doc/interpreter/HTML/Stem-Series.html
new file mode 100644
index 0000000..4a9afea
--- /dev/null
+++ b/doc/interpreter/HTML/Stem-Series.html
@@ -0,0 +1,67 @@
+<html lang="en">
+<head>
+<title>Stem Series - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Stair-group.html#Stair-group" title="Stair group">
+<link rel="next" href="Surface-group.html#Surface-group" title="Surface group">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Stem-Series"></a>
+Next: <a rel="next" accesskey="n" href="Surface-group.html#Surface-group">Surface group</a>,
+Previous: <a rel="previous" accesskey="p" href="Stair-group.html#Stair-group">Stair group</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.10 Stem Series</h5>
+
+<p><a name="index-series-objects-1248"></a><a name="index-stem-series-1249"></a>
+Stem series objects are created by the <code>stem</code> or <code>stem3</code>
+functions.  Each <code>hggroup</code> element contains a single line object
+as a child representing the stems.  The properties of the stem series
+are
+
+     <dl>
+<dt><code>showbaseline</code><dt><code>baseline</code><dt><code>basevalue</code><dd>The property <code>showbaseline</code> flags whether the baseline of the
+stem series is displayed (default is "on").  The handle of the graphics
+object representing the baseline is given by the <code>baseline</code>
+property and the y-value (or z-value for <code>stem3</code>) of the baseline
+by the <code>basevalue</code> property.
+
+     <p>Changes to any of these property are propagated to the other members of
+the stem series and to the baseline itself.  Equally changes in the
+properties of the base line itself are propagated to the members of the
+corresponding stem series.
+
+     <br><dt><code>color</code><dd>The RGB color or color name of the line objects of the stems.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the line objects of the stems.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>The line and fill color of the markers on the stems.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>The original x, y and z data of the stems.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>zdatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Storage-of-Sparse-Matrices.html b/doc/interpreter/HTML/Storage-of-Sparse-Matrices.html
new file mode 100644
index 0000000..d2ea8cf
--- /dev/null
+++ b/doc/interpreter/HTML/Storage-of-Sparse-Matrices.html
@@ -0,0 +1,129 @@
+<html lang="en">
+<head>
+<title>Storage of Sparse Matrices - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basics.html#Basics" title="Basics">
+<link rel="next" href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices" title="Creating Sparse Matrices">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Storage-of-Sparse-Matrices"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a>,
+Up: <a rel="up" accesskey="u" href="Basics.html#Basics">Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">21.1.1 Storage of Sparse Matrices</h4>
+
+<p>It is not strictly speaking necessary for the user to understand how
+sparse matrices are stored.  However, such an understanding will help
+to get an understanding of the size of sparse matrices.  Understanding
+the storage technique is also necessary for those users wishing to
+create their own oct-files.
+
+   <p>There are many different means of storing sparse matrix data.  What all
+of the methods have in common is that they attempt to reduce the complexity
+and storage given a-priori knowledge of the particular class of problems
+that will be solved.  A good summary of the available techniques for storing
+sparse matrix is given by Saad <a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>. 
+With full matrices, knowledge of the point of an element of the matrix
+within the matrix is implied by its position in the computers memory. 
+However, this is not the case for sparse matrices, and so the positions
+of the non-zero elements of the matrix must equally be stored.
+
+   <p>An obvious way to do this is by storing the elements of the matrix as
+triplets, with two elements being their position in the array
+(rows and column) and the third being the data itself.  This is conceptually
+easy to grasp, but requires more storage than is strictly needed.
+
+   <p>The storage technique used within Octave is the compressed column
+format.  In this format the position of each element in a row and the
+data are stored as previously.  However, if we assume that all elements
+in the same column are stored adjacent in the computers memory, then
+we only need to store information on the number of non-zero elements
+in each column, rather than their positions.  Thus assuming that the
+matrix has more non-zero elements than there are columns in the
+matrix, we win in terms of the amount of memory used.
+
+   <p>In fact, the column index contains one more element than the number of
+columns, with the first element always being zero.  The advantage of
+this is a simplification in the code, in that there is no special case
+for the first or last columns.  A short example, demonstrating this in
+C is.
+
+<pre class="example">       for (j = 0; j < nc; j++)
+         for (i = cidx (j); i < cidx(j+1); i++)
+            printf ("non-zero element (%i,%i) is %d\n",
+     	   ridx(i), j, data(i));
+</pre>
+   <p>A clear understanding might be had by considering an example of how the
+above applies to an example matrix.  Consider the matrix
+
+<pre class="example">         1   2   0  0
+         0   0   0  3
+         0   0   0  4
+</pre>
+   <p>The non-zero elements of this matrix are
+
+<pre class="example">        (1, 1)   1
+        (1, 2)   2
+        (2, 4)   3
+        (3, 4)   4
+</pre>
+   <p>This will be stored as three vectors <var>cidx</var>, <var>ridx</var> and <var>data</var>,
+representing the column indexing, row indexing and data respectively.  The
+contents of these three vectors for the above matrix will be
+
+<pre class="example">       <var>cidx</var> = [0, 1, 2, 2, 4]
+       <var>ridx</var> = [0, 0, 1, 2]
+       <var>data</var> = [1, 2, 3, 4]
+</pre>
+   <p>Note that this is the representation of these elements with the first row
+and column assumed to start at zero, while in Octave itself the row and
+column indexing starts at one.  Thus the number of elements in the
+<var>i</var>-th column is given by <var>cidx</var><code> (</code><var>i</var><code> + 1) -
+</code><var>cidx</var><code> (</code><var>i</var><code>)</code>.
+
+   <p>Although Octave uses a compressed column format, it should be noted
+that compressed row formats are equally possible.  However, in the
+context of mixed operations between mixed sparse and dense matrices,
+it makes sense that the elements of the sparse matrices are in the
+same order as the dense matrices.  Octave stores dense matrices in
+column major ordering, and so sparse matrices are equally stored in
+this manner.
+
+   <p>A further constraint on the sparse matrix storage used by Octave is that
+all elements in the rows are stored in increasing order of their row
+index, which makes certain operations faster.  However, it imposes
+the need to sort the elements on the creation of sparse matrices.  Having
+disordered elements is potentially an advantage in that it makes operations
+such as concatenating two sparse matrices together easier and faster, however
+it adds complexity and speed problems elsewhere.
+
+   <div class="footnote">
+<hr>
+<h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> Youcef Saad "SPARSKIT: A basic toolkit
+for sparse matrix computation", 1994,
+<a href="http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps">http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps</a></p>
+
+   <hr></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/String-Conversions.html b/doc/interpreter/HTML/String-Conversions.html
new file mode 100644
index 0000000..bf08d1b
--- /dev/null
+++ b/doc/interpreter/HTML/String-Conversions.html
@@ -0,0 +1,434 @@
+<html lang="en">
+<head>
+<title>String Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Strings.html#Strings" title="Strings">
+<link rel="prev" href="Manipulating-Strings.html#Manipulating-Strings" title="Manipulating Strings">
+<link rel="next" href="Character-Class-Functions.html#Character-Class-Functions" title="Character Class Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="String-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a>,
+Up: <a rel="up" accesskey="u" href="Strings.html#Strings">Strings</a>
+<hr>
+</div>
+
+<h3 class="section">5.6 String Conversions</h3>
+
+<p>Octave supports various kinds of conversions between strings and
+numbers.  As an example, it is possible to convert a string containing
+a hexadecimal number to a floating point number.
+
+<pre class="example">     hex2dec ("FF")
+           ans = 255
+</pre>
+   <!-- ./strings/bin2dec.m -->
+   <p><a name="doc_002dbin2dec"></a>
+
+<div class="defun">
+— Function File:  <b>bin2dec</b> (<var>s</var>)<var><a name="index-bin2dec-335"></a></var><br>
+<blockquote><p>Return the decimal number corresponding to the binary number stored
+in the string <var>s</var>.  For example,
+
+     <pre class="example">          bin2dec ("1110")
+                14
+</pre>
+        <p>If <var>s</var> is a string matrix, returns a column vector of converted
+numbers, one per row of <var>s</var>.  Invalid rows evaluate to NaN. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>, <a href="doc_002dbase2dec.html#doc_002dbase2dec">base2dec</a>, <a href="doc_002ddec2base.html#doc_002ddec2base">dec2base</a>, <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2bin.html#doc_002ddec2bin">dec2bin</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/dec2bin.m -->
+   <p><a name="doc_002ddec2bin"></a>
+
+<div class="defun">
+— Function File:  <b>dec2bin</b> (<var>n, len</var>)<var><a name="index-dec2bin-336"></a></var><br>
+<blockquote><p>Return a binary number corresponding to the non-negative decimal number
+<var>n</var>, as a string of ones and zeros.  For example,
+
+     <pre class="example">          dec2bin (14)
+                "1110"
+</pre>
+        <p>If <var>n</var> is a vector, returns a string matrix, one row per value,
+padded with leading zeros to the width of the largest value.
+
+        <p>The optional second argument, <var>len</var>, specifies the minimum
+number of digits in the result. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbin2dec.html#doc_002dbin2dec">bin2dec</a>, <a href="doc_002ddec2base.html#doc_002ddec2base">dec2base</a>, <a href="doc_002dbase2dec.html#doc_002dbase2dec">base2dec</a>, <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/dec2hex.m -->
+   <p><a name="doc_002ddec2hex"></a>
+
+<div class="defun">
+— Function File:  <b>dec2hex</b> (<var>n, len</var>)<var><a name="index-dec2hex-337"></a></var><br>
+<blockquote><p>Return the hexadecimal string corresponding to the non-negative
+integer <var>n</var>.  For example,
+
+     <pre class="example">          dec2hex (2748)
+                "ABC"
+</pre>
+        <p>If <var>n</var> is a vector, returns a string matrix, one row per value,
+padded with leading zeros to the width of the largest value.
+
+        <p>The optional second argument, <var>len</var>, specifies the minimum
+number of digits in the result. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2base.html#doc_002ddec2base">dec2base</a>, <a href="doc_002dbase2dec.html#doc_002dbase2dec">base2dec</a>, <a href="doc_002dbin2dec.html#doc_002dbin2dec">bin2dec</a>, <a href="doc_002ddec2bin.html#doc_002ddec2bin">dec2bin</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/hex2dec.m -->
+   <p><a name="doc_002dhex2dec"></a>
+
+<div class="defun">
+— Function File:  <b>hex2dec</b> (<var>s</var>)<var><a name="index-hex2dec-338"></a></var><br>
+<blockquote><p>Return the integer corresponding to the hexadecimal number stored
+in the string <var>s</var>.  For example,
+
+     <pre class="example">          hex2dec ("12B")
+                299
+          hex2dec ("12b")
+                299
+</pre>
+        <p>If <var>s</var> is a string matrix, returns a column vector of converted
+numbers, one per row of <var>s</var>.  Invalid rows evaluate to NaN. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>, <a href="doc_002dbase2dec.html#doc_002dbase2dec">base2dec</a>, <a href="doc_002ddec2base.html#doc_002ddec2base">dec2base</a>, <a href="doc_002dbin2dec.html#doc_002dbin2dec">bin2dec</a>, <a href="doc_002ddec2bin.html#doc_002ddec2bin">dec2bin</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/dec2base.m -->
+   <p><a name="doc_002ddec2base"></a>
+
+<div class="defun">
+— Function File:  <b>dec2base</b> (<var>n, b, len</var>)<var><a name="index-dec2base-339"></a></var><br>
+<blockquote><p>Return a string of symbols in base <var>b</var> corresponding to
+the non-negative integer <var>n</var>.
+
+     <pre class="example">          dec2base (123, 3)
+                "11120"
+</pre>
+        <p>If <var>n</var> is a vector, return a string matrix with one row per value,
+padded with leading zeros to the width of the largest value.
+
+        <p>If <var>b</var> is a string then the characters of <var>b</var> are used as
+the symbols for the digits of <var>n</var>.  Space (' ') may not be used
+as a symbol.
+
+     <pre class="example">          dec2base (123, "aei")
+                "eeeia"
+</pre>
+        <p>The optional third argument, <var>len</var>, specifies the minimum
+number of digits in the result. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbase2dec.html#doc_002dbase2dec">base2dec</a>, <a href="doc_002ddec2bin.html#doc_002ddec2bin">dec2bin</a>, <a href="doc_002dbin2dec.html#doc_002dbin2dec">bin2dec</a>, <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/base2dec.m -->
+   <p><a name="doc_002dbase2dec"></a>
+
+<div class="defun">
+— Function File:  <b>base2dec</b> (<var>s, b</var>)<var><a name="index-base2dec-340"></a></var><br>
+<blockquote><p>Convert <var>s</var> from a string of digits of base <var>b</var> into an
+integer.
+
+     <pre class="example">          base2dec ("11120", 3)
+                123
+</pre>
+        <p>If <var>s</var> is a matrix, returns a column vector with one value per
+row of <var>s</var>.  If a row contains invalid symbols then the
+corresponding value will be NaN.  Rows are right-justified before
+converting so that trailing spaces are ignored.
+
+        <p>If <var>b</var> is a string, the characters of <var>b</var> are used as the
+symbols for the digits of <var>s</var>.  Space (' ') may not be used as a
+symbol.
+
+     <pre class="example">          base2dec ("yyyzx", "xyz")
+                123
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddec2base.html#doc_002ddec2base">dec2base</a>, <a href="doc_002ddec2bin.html#doc_002ddec2bin">dec2bin</a>, <a href="doc_002dbin2dec.html#doc_002dbin2dec">bin2dec</a>, <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/hex2num.cc -->
+   <p><a name="doc_002dnum2hex"></a>
+
+<div class="defun">
+— Loadable Function: <var>s</var> = <b>num2hex</b> (<var>n</var>)<var><a name="index-num2hex-341"></a></var><br>
+<blockquote><p>Typecast a double precision number or vector to a 16 character hexadecimal
+string of the IEEE 754 representation of the number.  For example
+
+     <pre class="example">          num2hex ([-1, 1, e, Inf, NaN, NA]);
+           "bff0000000000000
+              3ff0000000000000
+              4005bf0a8b145769
+              7ff0000000000000
+              fff8000000000000
+              7ff00000000007a2"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dhex2num.html#doc_002dhex2num">hex2num</a>, <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/hex2num.cc -->
+   <p><a name="doc_002dhex2num"></a>
+
+<div class="defun">
+— Loadable Function: <var>n</var> = <b>hex2num</b> (<var>s</var>)<var><a name="index-hex2num-342"></a></var><br>
+<blockquote><p>Typecast the 16 character hexadecimal character matrix to an IEEE 754
+double precision number.  If fewer than 16 characters are given the
+strings are right padded with '0' characters.
+
+        <p>Given a string matrix, <code>hex2num</code> treats each row as a separate
+number.
+
+     <pre class="example">          hex2num (["4005bf0a8b145769";"4024000000000000"])
+           [2.7183; 10.000]
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dnum2hex.html#doc_002dnum2hex">num2hex</a>, <a href="doc_002dhex2dec.html#doc_002dhex2dec">hex2dec</a>, <a href="doc_002ddec2hex.html#doc_002ddec2hex">dec2hex</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/str2double.m -->
+   <p><a name="doc_002dstr2double"></a>
+
+<div class="defun">
+— Function File: [<var>num</var>, <var>status</var>, <var>strarray</var>] = <b>str2double</b> (<var>str, cdelim, rdelim, ddelim</var>)<var><a name="index-str2double-343"></a></var><br>
+<blockquote><p>Convert strings into numeric values.
+
+        <p><code>str2double</code> can replace <code>str2num</code>, but avoids the use of
+<code>eval</code> on unknown data.
+
+        <p><var>str</var> can be the form ‘<samp><span class="samp">[+-]d[.]dd[[eE][+-]ddd]</span></samp>’ in which
+‘<samp><span class="samp">d</span></samp>’ can be any of digit from 0 to 9, and ‘<samp><span class="samp">[]</span></samp>’ indicate
+optional elements.
+
+        <p><var>num</var> is the corresponding numeric value.  If the conversion
+fails, status is -1 and <var>num</var> is NaN.
+
+        <p><var>status</var> is 0 if the conversion was successful and -1 otherwise.
+
+        <p><var>strarray</var> is a cell array of strings.
+
+        <p>Elements which are not defined or not valid return NaN and the
+<var>status</var> becomes -1.
+
+        <p>If <var>str</var> is a character array or a cell array of strings, then
+<var>num</var> and <var>status</var> return matrices of appropriate size.
+
+        <p><var>str</var> can also contain multiple elements separated by row and
+column delimiters (<var>cdelim</var> and <var>rdelim</var>).
+
+        <p>The parameters <var>cdelim</var>, <var>rdelim</var>, and <var>ddelim</var> are
+optional column, row, and decimal delimiters.
+
+        <p>The default row-delimiters are newline, carriage return and semicolon
+(ASCII 10, 13 and 59).  The default column-delimiters are tab, space
+and comma (ASCII 9, 32, and 44).  The default decimal delimiter is
+‘<samp><span class="samp">.</span></samp>’ (ASCII 46).
+
+        <p><var>cdelim</var>, <var>rdelim</var>, and <var>ddelim</var> must contain only nul,
+newline, carriage return, semicolon, colon, slash, tab, space, comma,
+or ‘<samp><span class="samp">()[]{}</span></samp>’ (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40,
+41, 44, 47, 58, 59, 91, 93, 123, 124, 125).
+
+        <p>Examples:
+
+     <pre class="example">          str2double ("-.1e-5")
+           -1.0000e-006
+          
+          str2double (".314e1, 44.44e-1, .7; -1e+1")
+          
+             3.1400    4.4440    0.7000
+           -10.0000       NaN       NaN
+          
+          line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+          [x, status] = str2double (line)
+           x =
+              200   300   NaN  -Inf   NaN   NaN   999   NaN   NaN
+           status =
+                0     0     0     0    -1    -1     0    -1     0
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstr2num.html#doc_002dstr2num">str2num</a>. 
+</p></blockquote></div>
+
+<!-- ./strings/strjust.m -->
+   <p><a name="doc_002dstrjust"></a>
+
+<div class="defun">
+— Function File:  <b>strjust</b> (<var>s, </var>[<var>"left"|"right"|"center"</var>])<var><a name="index-strjust-344"></a></var><br>
+<blockquote><p>Shift the non-blank text of <var>s</var> to the left, right or center of
+the string.  If <var>s</var> is a string array, justify each string in the
+array.  Null characters are replaced by blanks.  If no justification
+is specified, then all rows are right-justified.  For example:
+
+     <pre class="example">          strjust (["a"; "ab"; "abc"; "abcd"])
+                ans =
+                     a
+                    ab
+                   abc
+                  abcd
+</pre>
+        </blockquote></div>
+
+<!-- ./strings/str2num.m -->
+   <p><a name="doc_002dstr2num"></a>
+
+<div class="defun">
+— Function File:  <b>str2num</b> (<var>s</var>)<var><a name="index-str2num-345"></a></var><br>
+<blockquote><p>Convert the string (or character array) <var>s</var> to a number (or an
+array).  Examples:
+
+     <pre class="example">          str2num("3.141596")
+                3.141596
+          
+          str2num(["1, 2, 3"; "4, 5, 6"]);
+                ans =
+                  1  2  3
+                  4  5  6
+</pre>
+        <p><strong>Caution:</strong> As <code>str2num</code> uses the <code>eval</code> function
+to do the conversion, <code>str2num</code> will execute any code contained
+in the string <var>s</var>.  Use <code>str2double</code> instead if you want to
+avoid the use of <code>eval</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstr2double.html#doc_002dstr2double">str2double</a>, <a href="doc_002deval.html#doc_002deval">eval</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dtoascii"></a>
+
+<div class="defun">
+— Mapping Function:  <b>toascii</b> (<var>s</var>)<var><a name="index-toascii-346"></a></var><br>
+<blockquote><p>Return ASCII representation of <var>s</var> in a matrix.  For example,
+
+     <pre class="example">          toascii ("ASCII")
+                [ 65, 83, 67, 73, 73 ]
+          
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dchar.html#doc_002dchar">char</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dtolower"></a>
+
+<div class="defun">
+— Mapping Function:  <b>tolower</b> (<var>s</var>)<var><a name="index-tolower-347"></a></var><br>
+— Mapping Function:  <b>lower</b> (<var>s</var>)<var><a name="index-lower-348"></a></var><br>
+<blockquote><p>Return a copy of the string or cell string <var>s</var>, with each upper-case
+character replaced by the corresponding lower-case one; non-alphabetic
+characters are left unchanged.  For example,
+
+     <pre class="example">          tolower ("MiXeD cAsE 123")
+                "mixed case 123"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtoupper.html#doc_002dtoupper">toupper</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dtoupper"></a>
+
+<div class="defun">
+— Built-in Function:  <b>toupper</b> (<var>s</var>)<var><a name="index-toupper-349"></a></var><br>
+— Built-in Function:  <b>upper</b> (<var>s</var>)<var><a name="index-upper-350"></a></var><br>
+<blockquote><p>Return a copy of the string or cell string <var>s</var>, with each lower-case
+character replaced by the corresponding upper-case one; non-alphabetic
+characters are left unchanged.  For example,
+
+     <pre class="example">          toupper ("MiXeD cAsE 123")
+                "MIXED CASE 123"
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtolower.html#doc_002dtolower">tolower</a>. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002ddo_005fstring_005fescapes"></a>
+
+<div class="defun">
+— Built-in Function:  <b>do_string_escapes</b> (<var>string</var>)<var><a name="index-do_005fstring_005fescapes-351"></a></var><br>
+<blockquote><p>Convert special characters in <var>string</var> to their escaped forms. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002dundo_005fstring_005fescapes"></a>
+
+<div class="defun">
+— Built-in Function:  <b>undo_string_escapes</b> (<var>s</var>)<var><a name="index-undo_005fstring_005fescapes-352"></a></var><br>
+<blockquote><p>Converts special characters in strings back to their escaped forms.  For
+example, the expression
+
+     <pre class="example">          bell = "\a";
+</pre>
+        <p class="noindent">assigns the value of the alert character (control-g, ASCII code 7) to
+the string variable <code>bell</code>.  If this string is printed, the
+system will ring the terminal bell (if it is possible).  This is
+normally the desired outcome.  However, sometimes it is useful to be
+able to print the original representation of the string, with the
+special characters replaced by their escape sequences.  For example,
+
+     <pre class="example">          octave:13> undo_string_escapes (bell)
+          ans = \a
+</pre>
+        <p class="noindent">replaces the unprintable alert character with its printable
+representation. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/String-Input-Conversions.html b/doc/interpreter/HTML/String-Input-Conversions.html
new file mode 100644
index 0000000..f984a7c
--- /dev/null
+++ b/doc/interpreter/HTML/String-Input-Conversions.html
@@ -0,0 +1,60 @@
+<html lang="en">
+<head>
+<title>String Input Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Numeric-Input-Conversions.html#Numeric-Input-Conversions" title="Numeric Input Conversions">
+<link rel="next" href="Binary-I_002fO.html#Binary-I_002fO" title="Binary I/O">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="String-Input-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Binary-I_002fO.html#Binary-I_002fO">Binary I/O</a>,
+Previous: <a rel="previous" accesskey="p" href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.15 String Input Conversions</h4>
+
+<p>This section describes the <code>scanf</code> input conversions for reading
+string and character values: ‘<samp><span class="samp">%s</span></samp>’ and ‘<samp><span class="samp">%c</span></samp>’.
+
+   <p>The ‘<samp><span class="samp">%c</span></samp>’ conversion is the simplest: it matches a fixed number of
+characters, always.  The maximum field with says how many characters to
+read; if you don't specify the maximum, the default is 1.  This
+conversion does not skip over initial whitespace characters.  It reads
+precisely the next <var>n</var> characters, and fails if it cannot get that
+many.
+
+   <p>The ‘<samp><span class="samp">%s</span></samp>’ conversion matches a string of non-whitespace characters. 
+It skips and discards initial whitespace, but stops when it encounters
+more whitespace after having read something.
+
+   <p>For example, reading the input:
+
+<pre class="example">      hello, world
+</pre>
+   <p class="noindent">with the conversion ‘<samp><span class="samp">%10c</span></samp>’ produces <code>" hello, wo"</code>, but
+reading the same input with the conversion ‘<samp><span class="samp">%10s</span></samp>’ produces
+<code>"hello,"</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/String-Objects.html b/doc/interpreter/HTML/String-Objects.html
new file mode 100644
index 0000000..8d906f4
--- /dev/null
+++ b/doc/interpreter/HTML/String-Objects.html
@@ -0,0 +1,46 @@
+<html lang="en">
+<head>
+<title>String Objects - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Built_002din-Data-Types.html#Built_002din-Data-Types" title="Built-in Data Types">
+<link rel="prev" href="Missing-Data.html#Missing-Data" title="Missing Data">
+<link rel="next" href="Data-Structure-Objects.html#Data-Structure-Objects" title="Data Structure Objects">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="String-Objects"></a>
+Next: <a rel="next" accesskey="n" href="Data-Structure-Objects.html#Data-Structure-Objects">Data Structure Objects</a>,
+Previous: <a rel="previous" accesskey="p" href="Missing-Data.html#Missing-Data">Missing Data</a>,
+Up: <a rel="up" accesskey="u" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<hr>
+</div>
+
+<h4 class="subsection">3.1.3 String Objects</h4>
+
+<p><a name="index-strings-191"></a><a name="index-character-strings-192"></a><a name="index-g_t_0022-193"></a><a name="index-g_t_0027-194"></a>
+A character string in Octave consists of a sequence of characters
+enclosed in either double-quote or single-quote marks.  Internally,
+Octave currently stores strings as matrices of characters.  All the
+indexing operations that work for matrix objects also work for strings.
+
+   <p>See <a href="Strings.html#Strings">Strings</a>, for more information.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Strings.html b/doc/interpreter/HTML/Strings.html
new file mode 100644
index 0000000..79390b5
--- /dev/null
+++ b/doc/interpreter/HTML/Strings.html
@@ -0,0 +1,69 @@
+<html lang="en">
+<head>
+<title>Strings - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Numeric-Data-Types.html#Numeric-Data-Types" title="Numeric Data Types">
+<link rel="next" href="Data-Containers.html#Data-Containers" title="Data Containers">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Strings"></a>
+Next: <a rel="next" accesskey="n" href="Data-Containers.html#Data-Containers">Data Containers</a>,
+Previous: <a rel="previous" accesskey="p" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">5 Strings</h2>
+
+<p><a name="index-strings-279"></a><a name="index-character-strings-280"></a><a name="index-g_t_0022-281"></a><a name="index-g_t_0027-282"></a>
+A <dfn>string constant</dfn> consists of a sequence of characters enclosed in
+either double-quote or single-quote marks.  For example, both of the
+following expressions
+
+<pre class="example">     "parrot"
+     'parrot'
+</pre>
+   <p class="noindent">represent the string whose contents are ‘<samp><span class="samp">parrot</span></samp>’.  Strings in
+Octave can be of any length.
+
+   <p>Since the single-quote mark is also used for the transpose operator
+(see <a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a>) but double-quote marks have no other purpose in Octave,
+it is best to use double-quote marks to denote strings.
+
+   <p>Strings can be concatenated using the notation for defining matrices.  For
+example, the expression
+
+<pre class="example">     [ "foo" , "bar" , "baz" ]
+</pre>
+   <p class="noindent">produces the string whose contents are ‘<samp><span class="samp">foobarbaz</span></samp>’.  See <a href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>, for more information about creating matrices.
+
+<ul class="menu">
+<li><a accesskey="1" href="Escape-Sequences-in-string-constants.html#Escape-Sequences-in-string-constants">Escape Sequences in string constants</a>
+<li><a accesskey="2" href="Character-Arrays.html#Character-Arrays">Character Arrays</a>
+<li><a accesskey="3" href="Creating-Strings.html#Creating-Strings">Creating Strings</a>
+<li><a accesskey="4" href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a>
+<li><a accesskey="5" href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a>
+<li><a accesskey="6" href="String-Conversions.html#String-Conversions">String Conversions</a>
+<li><a accesskey="7" href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Structure-Arrays.html b/doc/interpreter/HTML/Structure-Arrays.html
new file mode 100644
index 0000000..f6a650e
--- /dev/null
+++ b/doc/interpreter/HTML/Structure-Arrays.html
@@ -0,0 +1,131 @@
+<html lang="en">
+<head>
+<title>Structure Arrays - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Structures.html#Data-Structures" title="Data Structures">
+<link rel="prev" href="Basic-Usage-and-Examples.html#Basic-Usage-and-Examples" title="Basic Usage and Examples">
+<link rel="next" href="Creating-Structures.html#Creating-Structures" title="Creating Structures">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Structure-Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Creating-Structures.html#Creating-Structures">Creating Structures</a>,
+Previous: <a rel="previous" accesskey="p" href="Basic-Usage-and-Examples.html#Basic-Usage-and-Examples">Basic Usage and Examples</a>,
+Up: <a rel="up" accesskey="u" href="Data-Structures.html#Data-Structures">Data Structures</a>
+<hr>
+</div>
+
+<h4 class="subsection">6.1.2 Structure Arrays</h4>
+
+<p>A structure array is a particular instance of a structure, where each of
+the fields of the structure is represented by a cell array.  Each of
+these cell arrays has the same dimensions. Conceptually, a structure
+array can also be seen as an array of structures with identical
+fields.  An example of the creation of a structure array is
+
+<pre class="example">     x(1).a = "string1";
+     x(2).a = "string2";
+     x(1).b = 1;
+     x(2).b = 2;
+</pre>
+   <p class="noindent">which creates a 2-by-1 structure array with two fields.  Another way
+to create a structure array is with the <code>struct</code> function
+(see <a href="Creating-Structures.html#Creating-Structures">Creating Structures</a>).  As previously, to print the value of
+the structure array, you can type its name:
+
+<pre class="example">     x
+           x =
+             {
+               1x2 struct array containing the fields:
+     
+                 a
+                 b
+             }
+</pre>
+   <p>Individual elements of the structure array can be returned by indexing
+the variable like <var>x</var><code>(1)</code>, which returns a structure with
+two fields:
+
+<pre class="example">     x(1)
+           ans =
+             {
+               a = string1
+               b =  1
+             }
+</pre>
+   <p>Furthermore, the structure array can return a comma separated list of
+field values (see <a href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>), if indexed by one of its
+own field names.  For example
+
+<pre class="example">     x.a
+          
+             ans = string1
+             ans = string2
+</pre>
+   <p>Here is another example, using this comma separated list on the
+left-hand side of an assignment:
+
+<pre class="example">     [x.a] = deal("new string1", "new string2");
+      x(1).a
+           ans = new string1
+      x(2).a
+           ans = new string2
+</pre>
+   <p>Just as for numerical arrays, it is possible to use vectors as indices (see <a href="Index-Expressions.html#Index-Expressions">Index Expressions</a>):
+
+<pre class="example">     x(3:4) = x(1:2);
+     [x([1,3]).a] = deal("other string1", "other string2");
+     x.a
+          
+             ans = other string1
+             ans = new string2
+             ans = other string2
+             ans = new string2
+</pre>
+   <p>The function <code>size</code> will return the size of the structure.  For
+the example above
+
+<pre class="example">     size(x)
+           ans =
+     
+               1   4
+</pre>
+   <p>Elements can be deleted from a structure array in a similar manner to a
+numerical array, by assigning the elements to an empty matrix.  For
+example
+
+<pre class="example">     in = struct ("call1", {x, Inf, "last"},
+                  "call2", {x, Inf, "first"})
+           in =
+             {
+               1x3 struct array containing the fields:
+     
+                 call1
+                 call2
+             }
+     
+     in(1) = [];
+     in.call1
+          
+            ans = Inf
+            ans = last
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Structures-in-Oct_002dFiles.html b/doc/interpreter/HTML/Structures-in-Oct_002dFiles.html
new file mode 100644
index 0000000..7829b7e
--- /dev/null
+++ b/doc/interpreter/HTML/Structures-in-Oct_002dFiles.html
@@ -0,0 +1,105 @@
+<html lang="en">
+<head>
+<title>Structures in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Oct_002dFiles.html#Oct_002dFiles" title="Oct-Files">
+<link rel="prev" href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles" title="Cell Arrays in Oct-Files">
+<link rel="next" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles" title="Sparse Matrices in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Structures-in-Oct-Files"></a>
+<a name="Structures-in-Oct_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles">Cell Arrays in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.1.5 Structures in Oct-Files</h4>
+
+<p>A structure in Octave is map between a number of fields represented and
+their values.  The Standard Template Library <code>map</code> class is used,
+with the pair consisting of a <code>std::string</code> and an octave
+<code>Cell</code> variable.
+
+   <p>A simple example demonstrating the use of structures within oct-files is
+
+<pre class="example"><pre class="verbatim">     #include <octave/oct.h>
+     #include <octave/ov-struct.h>
+     
+     DEFUN_DLD (structdemo, args, , "Struct demo.")
+     {
+       int nargin = args.length ();
+       octave_value retval;
+     
+       if (nargin != 2)
+         print_usage ();
+       else
+         {
+           Octave_map arg0 = args(0).map_value ();
+           std::string arg1 = args(1).string_value ();
+     
+           if (! error_state && arg0.contains (arg1))
+             {
+               // The following two lines might be written as
+               //    octave_value tmp;
+               //    for (Octave_map::iterator p0 = 
+     	  //        arg0.begin(); 
+               //        p0 != arg0.end(); p0++ )
+               //      if (arg0.key (p0) == arg1)
+               //        {
+               //          tmp = arg0.contents (p0) (0);
+               //          break;
+               //        }
+               // though using seek is more concise.
+               Octave_map::const_iterator p1 = arg0.seek (arg1);
+               octave_value tmp =  arg0.contents(p1)(0);
+               Octave_map st;
+               st.assign ("selected", tmp);
+               retval = octave_value (st);
+             }
+         }
+       return retval; 
+     }
+     
+</pre></pre>
+   <p>An example of its use is
+
+<pre class="example">     x.a = 1; x.b = "test"; x.c = [1, 2];
+     structdemo (x, "b")
+      selected = test
+</pre>
+   <p>The commented code above demonstrates how to iterate over all of the
+fields of the structure, where as the following code demonstrates finding
+a particular field in a more concise manner.
+
+   <p>As can be seen the <code>contents</code> method of the <code>Octave_map</code> class
+returns a <code>Cell</code> which allows structure arrays to be represented. 
+Therefore, to obtain the underlying <code>octave_value</code> we write
+
+<pre class="example">     octave_value tmp = arg0.contents (p1) (0);
+</pre>
+   <p>where the trailing (0) is the () operator on the <code>Cell</code> object.  We
+can equally iterate of the elements of the Cell array to address the
+elements of the structure array.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Structures-with-Mex_002dFiles.html b/doc/interpreter/HTML/Structures-with-Mex_002dFiles.html
new file mode 100644
index 0000000..be7be81
--- /dev/null
+++ b/doc/interpreter/HTML/Structures-with-Mex_002dFiles.html
@@ -0,0 +1,141 @@
+<html lang="en">
+<head>
+<title>Structures with Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="prev" href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles" title="Cell Arrays with Mex-Files">
+<link rel="next" href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles" title="Sparse Matrices with Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Structures-with-Mex-Files"></a>
+<a name="Structures-with-Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles">Sparse Matrices with Mex-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles">Cell Arrays with Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.5 Structures with Mex-Files</h4>
+
+<p>The basic function to create a structure in a mex-file is
+<code>mxCreateStructMatrix</code>, which creates a structure array with a two
+dimensional matrix, or <code>mxCreateStructArray</code>.
+
+<pre class="example">     mxArray *mxCreateStructArray (int ndims, int *dims,
+                                   int num_keys,
+                                   const char **keys);
+     mxArray *mxCreateStructMatrix (int rows, int cols,
+                                    int num_keys,
+                                    const char **keys);
+</pre>
+   <p>Accessing the fields of the structure can then be performed with the
+<code>mxGetField</code> and <code>mxSetField</code> or alternatively with the
+<code>mxGetFieldByNumber</code> and <code>mxSetFieldByNumber</code> functions.
+
+<pre class="example">     mxArray *mxGetField (const mxArray *ptr, mwIndex index,
+                          const char *key);
+     mxArray *mxGetFieldByNumber (const mxArray *ptr,
+                                  mwIndex index, int key_num);
+     void mxSetField (mxArray *ptr, mwIndex index,
+                      const char *key, mxArray *val);
+     void mxSetFieldByNumber (mxArray *ptr, mwIndex index,
+                              int key_num, mxArray *val);
+</pre>
+   <p>A difference between the oct-file interface to structures and the
+mex-file version is that the functions to operate on structures in
+mex-files directly include an <code>index</code> over the elements of the
+arrays of elements per <code>field</code>.  Whereas the oct-file structure
+includes a Cell Array per field of the structure.
+
+   <p>An example that demonstrates the use of structures in mex-file can be
+found in the file <samp><span class="file">mystruct.c</span></samp>, as seen below
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+     	     const mxArray* prhs[])
+     {
+       int i;
+       mwIndex j;
+       mxArray *v;
+       const char *keys[] = { "this", "that" };
+     
+       if (nrhs != 1 || ! mxIsStruct (prhs[0]))
+         mexErrMsgTxt ("expects struct");
+     
+       for (i = 0; i < mxGetNumberOfFields (prhs[0]); i++)
+         for (j = 0; j < mxGetNumberOfElements (prhs[0]); j++)
+           {
+             mexPrintf ("field %s(%d) = ", 
+                        mxGetFieldNameByNumber (prhs[0], i), j);
+             v = mxGetFieldByNumber (prhs[0], j, i);
+             mexCallMATLAB (0, 0, 1, &v, "disp");
+           }
+     
+       v = mxCreateStructMatrix (2, 2, 2, keys);
+     
+       mxSetFieldByNumber (v, 0, 0, mxCreateString ("this1"));
+       mxSetFieldByNumber (v, 0, 1, mxCreateString ("that1"));
+       mxSetFieldByNumber (v, 1, 0, mxCreateString ("this2"));
+       mxSetFieldByNumber (v, 1, 1, mxCreateString ("that2"));
+       mxSetFieldByNumber (v, 2, 0, mxCreateString ("this3"));
+       mxSetFieldByNumber (v, 2, 1, mxCreateString ("that3"));
+       mxSetFieldByNumber (v, 3, 0, mxCreateString ("this4"));
+       mxSetFieldByNumber (v, 3, 1, mxCreateString ("that4"));
+     
+       if (nlhs)
+         plhs[0] = v;
+     }
+</pre></pre>
+   <p>An example of the behavior of this function within Octave is then
+
+<pre class="example">     a(1).f1 = "f11"; a(1).f2 = "f12";
+     a(2).f1 = "f21"; a(2).f2 = "f22";
+     b = mystruct(a)
+      field f1(0) = f11
+         field f1(1) = f21
+         field f2(0) = f12
+         field f2(1) = f22
+         b =
+         {
+           this =
+     
+           (,
+             [1] = this1
+             [2] = this2
+             [3] = this3
+             [4] = this4
+           ,)
+     
+           that =
+     
+           (,
+             [1] = that1
+             [2] = that2
+             [3] = that3
+             [4] = that4
+           ,)
+     
+         }
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Style-Tips.html b/doc/interpreter/HTML/Style-Tips.html
new file mode 100644
index 0000000..d44d4e6
--- /dev/null
+++ b/doc/interpreter/HTML/Style-Tips.html
@@ -0,0 +1,71 @@
+<html lang="en">
+<head>
+<title>Style Tips - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link rel="next" href="Coding-Tips.html#Coding-Tips" title="Coding Tips">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Style-Tips"></a>
+Next: <a rel="next" accesskey="n" href="Coding-Tips.html#Coding-Tips">Coding Tips</a>,
+Up: <a rel="up" accesskey="u" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
+<hr>
+</div>
+
+<h3 class="section">C.1 Writing Clean Octave Programs</h3>
+
+<p>Here are some tips for avoiding common errors in writing Octave code
+intended for widespread use:
+
+     <ul>
+<li>Since all global variables share the same name space, and all functions
+share another name space, you should choose a short word to distinguish
+your program from other Octave programs.  Then take care to begin the
+names of all global variables, constants, and functions with the chosen
+prefix.  This helps avoid name conflicts.
+
+     <p>If you write a function that you think ought to be added to Octave under
+a certain name, such as <code>fiddle_matrix</code>, don't call it by that name
+in your program.  Call it <code>mylib_fiddle_matrix</code> in your program,
+and send mail to <a href="mailto:maintainers at octave.org">maintainers at octave.org</a> suggesting that it
+be added to Octave.  If and when it is, the name can be changed easily
+enough.
+
+     <p>If one prefix is insufficient, your package may use two or three
+alternative common prefixes, so long as they make sense.
+
+     <p>Separate the prefix from the rest of the symbol name with an underscore
+‘<samp><span class="samp">_</span></samp>’.  This will be consistent with Octave itself and with most
+Octave programs.
+
+     <li>When you encounter an error condition, call the function <code>error</code>
+(or <code>usage</code>).  The <code>error</code> and <code>usage</code> functions do not
+return. 
+See <a href="Errors.html#Errors">Errors</a>.
+
+     <li>Please put a copyright notice on the file if you give copies to anyone. 
+Use the same lines that appear at the top of the function files
+distributed with Octave.  If you have not signed papers to assign the
+copyright to anyone else, then place your name in the copyright notice. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Subfunctions.html b/doc/interpreter/HTML/Subfunctions.html
new file mode 100644
index 0000000..de4a960
--- /dev/null
+++ b/doc/interpreter/HTML/Subfunctions.html
@@ -0,0 +1,60 @@
+<html lang="en">
+<head>
+<title>Subfunctions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Function-Files.html#Function-Files" title="Function Files">
+<link rel="prev" href="Manipulating-the-load-path.html#Manipulating-the-load-path" title="Manipulating the load path">
+<link rel="next" href="Private-Functions.html#Private-Functions" title="Private Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Subfunctions"></a>
+Next: <a rel="next" accesskey="n" href="Private-Functions.html#Private-Functions">Private Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a>,
+Up: <a rel="up" accesskey="u" href="Function-Files.html#Function-Files">Function Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">11.7.2 Subfunctions</h4>
+
+<p>A function file may contain secondary functions called
+<dfn>subfunctions</dfn>.  These secondary functions are only visible to the
+other functions in the same function file.  For example, a file
+<samp><span class="file">f.m</span></samp> containing
+
+<pre class="example">     function f ()
+       printf ("in f, calling g\n");
+       g ()
+     endfunction
+     function g ()
+       printf ("in g, calling h\n");
+       h ()
+     endfunction
+     function h ()
+       printf ("in h\n")
+     endfunction
+</pre>
+   <p class="noindent">defines a main function <code>f</code> and two subfunctions.  The
+subfunctions <code>g</code> and <code>h</code> may only be called from the main
+function <code>f</code> or from the other subfunctions, but not from outside
+the file <samp><span class="file">f.m</span></samp>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Sums-and-Products.html b/doc/interpreter/HTML/Sums-and-Products.html
new file mode 100644
index 0000000..9b42e8b
--- /dev/null
+++ b/doc/interpreter/HTML/Sums-and-Products.html
@@ -0,0 +1,188 @@
+<html lang="en">
+<head>
+<title>Sums and Products - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Trigonometry.html#Trigonometry" title="Trigonometry">
+<link rel="next" href="Utility-Functions.html#Utility-Functions" title="Utility Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Sums-and-Products"></a>
+Next: <a rel="next" accesskey="n" href="Utility-Functions.html#Utility-Functions">Utility Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Trigonometry.html#Trigonometry">Trigonometry</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.4 Sums and Products</h3>
+
+<!-- data.cc -->
+<p><a name="doc_002dsum"></a>
+
+<div class="defun">
+— Built-in Function:  <b>sum</b> (<var>x</var>)<var><a name="index-sum-1422"></a></var><br>
+— Built-in Function:  <b>sum</b> (<var>x, dim</var>)<var><a name="index-sum-1423"></a></var><br>
+— Built-in Function:  <b>sum</b> (<var><small class="dots">...</small>, 'native'</var>)<var><a name="index-sum-1424"></a></var><br>
+<blockquote><p>Sum of elements along dimension <var>dim</var>.  If <var>dim</var> is
+omitted, it defaults to 1 (column-wise sum).
+
+        <p>As a special case, if <var>x</var> is a vector and <var>dim</var> is omitted,
+return the sum of the elements.
+
+        <p>If the optional argument 'native' is given, then the sum is performed
+in the same type as the original argument, rather than in the default
+double type.  For example
+
+     <pre class="example">          sum ([true, true])
+             2
+          sum ([true, true], 'native')
+             true
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcumsum.html#doc_002dcumsum">cumsum</a>, <a href="doc_002dsumsq.html#doc_002dsumsq">sumsq</a>, <a href="doc_002dprod.html#doc_002dprod">prod</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dprod"></a>
+
+<div class="defun">
+— Built-in Function:  <b>prod</b> (<var>x</var>)<var><a name="index-prod-1425"></a></var><br>
+— Built-in Function:  <b>prod</b> (<var>x, dim</var>)<var><a name="index-prod-1426"></a></var><br>
+<blockquote><p>Product of elements along dimension <var>dim</var>.  If <var>dim</var> is
+omitted, it defaults to 1 (column-wise products).
+
+        <p>As a special case, if <var>x</var> is a vector and <var>dim</var> is omitted,
+return the product of the elements. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcumprod.html#doc_002dcumprod">cumprod</a>, <a href="doc_002dsum.html#doc_002dsum">sum</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dcumsum"></a>
+
+<div class="defun">
+— Built-in Function:  <b>cumsum</b> (<var>x</var>)<var><a name="index-cumsum-1427"></a></var><br>
+— Built-in Function:  <b>cumsum</b> (<var>x, dim</var>)<var><a name="index-cumsum-1428"></a></var><br>
+— Built-in Function:  <b>cumsum</b> (<var><small class="dots">...</small>, 'native'</var>)<var><a name="index-cumsum-1429"></a></var><br>
+<blockquote><p>Cumulative sum of elements along dimension <var>dim</var>.  If <var>dim</var>
+is omitted, it defaults to 1 (column-wise cumulative sums).
+
+        <p>As a special case, if <var>x</var> is a vector and <var>dim</var> is omitted,
+return the cumulative sum of the elements as a vector with the
+same orientation as <var>x</var>.
+
+        <p>The "native" argument implies the summation is performed in native type. 
+ See <code>sum</code> for a complete description and example of the use of
+"native". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsum.html#doc_002dsum">sum</a>, <a href="doc_002dcumprod.html#doc_002dcumprod">cumprod</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dcumprod"></a>
+
+<div class="defun">
+— Built-in Function:  <b>cumprod</b> (<var>x</var>)<var><a name="index-cumprod-1430"></a></var><br>
+— Built-in Function:  <b>cumprod</b> (<var>x, dim</var>)<var><a name="index-cumprod-1431"></a></var><br>
+<blockquote><p>Cumulative product of elements along dimension <var>dim</var>.  If
+<var>dim</var> is omitted, it defaults to 1 (column-wise cumulative
+products).
+
+        <p>As a special case, if <var>x</var> is a vector and <var>dim</var> is omitted,
+return the cumulative product of the elements as a vector with the
+same orientation as <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprod.html#doc_002dprod">prod</a>, <a href="doc_002dcumsum.html#doc_002dcumsum">cumsum</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dsumsq"></a>
+
+<div class="defun">
+— Built-in Function:  <b>sumsq</b> (<var>x</var>)<var><a name="index-sumsq-1432"></a></var><br>
+— Built-in Function:  <b>sumsq</b> (<var>x, dim</var>)<var><a name="index-sumsq-1433"></a></var><br>
+<blockquote><p>Sum of squares of elements along dimension <var>dim</var>.  If <var>dim</var>
+is omitted, it defaults to 1 (column-wise sum of squares).
+
+        <p>As a special case, if <var>x</var> is a vector and <var>dim</var> is omitted,
+return the sum of squares of the elements.
+
+        <p>This function is conceptually equivalent to computing
+     <pre class="example">          sum (x .* conj (x), dim)
+</pre>
+        <p>but it uses less memory and avoids calling <code>conj</code> if <var>x</var> is real. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsum.html#doc_002dsum">sum</a>. 
+</p></blockquote></div>
+
+<!-- ./general/accumarray.m -->
+   <p><a name="doc_002daccumarray"></a>
+
+<div class="defun">
+— Function File:  <b>accumarray</b> (<var>subs, vals, sz, func, fillval, issparse</var>)<var><a name="index-accumarray-1434"></a></var><br>
+— Function File:  <b>accumarray</b> (<var>csubs, vals, <small class="dots">...</small></var>)<var><a name="index-accumarray-1435"></a></var><br>
+<blockquote>
+        <p>Create an array by accumulating the elements of a vector into the
+positions defined by their subscripts.  The subscripts are defined by
+the rows of the matrix <var>subs</var> and the values by <var>vals</var>.  Each row
+of <var>subs</var> corresponds to one of the values in <var>vals</var>.
+
+        <p>The size of the matrix will be determined by the subscripts themselves. 
+However, if <var>sz</var> is defined it determines the matrix size.  The length
+of <var>sz</var> must correspond to the number of columns in <var>subs</var>.
+
+        <p>The default action of <code>accumarray</code> is to sum the elements with the
+same subscripts.  This behavior can be modified by defining the <var>func</var>
+function.  This should be a function or function handle that accepts a
+column vector and returns a scalar.  The result of the function should not
+depend on the order of the subscripts.
+
+        <p>The elements of the returned array that have no subscripts associated with
+them are set to zero.  Defining <var>fillval</var> to some other value allows
+these values to be defined.
+
+        <p>By default <code>accumarray</code> returns a full matrix.  If <var>issparse</var> is
+logically true, then a sparse matrix is returned instead.
+
+        <p>An example of the use of <code>accumarray</code> is:
+
+     <pre class="example">          accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+           ans(:,:,1) = [101, 0, 0; 0, 0, 0]
+             ans(:,:,2) = [0, 0, 0; 206, 0, 208]
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Surface-Properties.html b/doc/interpreter/HTML/Surface-Properties.html
new file mode 100644
index 0000000..7392172
--- /dev/null
+++ b/doc/interpreter/HTML/Surface-Properties.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Surface Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Patch-Properties.html#Patch-Properties" title="Patch Properties">
+<link rel="next" href="Searching-Properties.html#Searching-Properties" title="Searching Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Surface-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Searching-Properties.html#Searching-Properties">Searching Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Patch-Properties.html#Patch-Properties">Patch Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.8 Surface Properties</h5>
+
+<p><a name="index-surface-properties-1196"></a>
+     <dl>
+<dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><dd>The data determining the surface.  The <code>xdata</code> and <code>ydata</code>
+elements are vectors and <code>zdata</code> must be a matrix.
+
+     <br><dt><code>keylabel</code><dd>The text of the legend entry corresponding to this surface.  Note that
+this property is not compatible with <span class="sc">matlab</span> and may be removed in a
+future version of Octave. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Surface-group.html b/doc/interpreter/HTML/Surface-group.html
new file mode 100644
index 0000000..6f6372a
--- /dev/null
+++ b/doc/interpreter/HTML/Surface-group.html
@@ -0,0 +1,55 @@
+<html lang="en">
+<head>
+<title>Surface group - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Object-Groups.html#Object-Groups" title="Object Groups">
+<link rel="prev" href="Stem-Series.html#Stem-Series" title="Stem Series">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Surface-group"></a>
+Previous: <a rel="previous" accesskey="p" href="Stem-Series.html#Stem-Series">Stem Series</a>,
+Up: <a rel="up" accesskey="u" href="Object-Groups.html#Object-Groups">Object Groups</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.8.11 Surface group</h5>
+
+<p><a name="index-group-objects-1250"></a><a name="index-surface-group-1251"></a>
+Surface group objects are created by the <code>surf</code> or <code>mesh</code>
+functions, but are equally one of the handles returned by the <code>surfc</code>
+or <code>meshc</code> functions.  The surface group is of the type <code>surface</code>.
+
+   <p>The properties of the surface group are
+
+     <dl>
+<dt><code>edgecolor</code><br><dt><code>facecolor</code><dd>The RGB color or color name of the edges or faces of the surface.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>linewidth</code><dt><code>linestyle</code><dd>The line width and style of the lines on the surface.  See <a href="Line-Styles.html#Line-Styles">Line Styles</a>.
+
+     <br><dt><code>marker</code><dt><code>markeredgecolor</code><dt><code>markerfacecolor</code><dt><code>markersize</code><dd>The line and fill color of the markers on the surface.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>xdata</code><dt><code>ydata</code><dt><code>zdata</code><br><dt><code>cdata</code><dd>The original x, y, z and c data.
+
+     <br><dt><code>xdatasource</code><dt><code>ydatasource</code><dt><code>zdatasource</code><dt><code>cdatasource</code><dd>Data source variables. 
+</dl>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/System-Information.html b/doc/interpreter/HTML/System-Information.html
new file mode 100644
index 0000000..38a1e41
--- /dev/null
+++ b/doc/interpreter/HTML/System-Information.html
@@ -0,0 +1,291 @@
+<html lang="en">
+<head>
+<title>System Information - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="prev" href="Group-Database-Functions.html#Group-Database-Functions" title="Group Database Functions">
+<link rel="next" href="Hashing-Functions.html#Hashing-Functions" title="Hashing Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="System-Information"></a>
+Next: <a rel="next" accesskey="n" href="Hashing-Functions.html#Hashing-Functions">Hashing Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.11 System Information</h3>
+
+<!-- ./miscellaneous/computer.m -->
+<p><a name="doc_002dcomputer"></a>
+
+<div class="defun">
+— Function File: [<var>c</var>, <var>maxsize</var>, <var>endian</var>] = <b>computer</b> ()<var><a name="index-computer-2442"></a></var><br>
+<blockquote><p>Print or return a string of the form <var>cpu</var>-<var>vendor</var>-<var>os</var>
+that identifies the kind of computer Octave is running on.  If invoked
+with an output argument, the value is returned instead of printed.  For
+example,
+
+     <pre class="example">          computer ()
+               -| i586-pc-linux-gnu
+          
+          x = computer ()
+                x = "i586-pc-linux-gnu"
+</pre>
+        <p>If two output arguments are requested, also return the maximum number
+of elements for an array.
+
+        <p>If three output arguments are requested, also return the byte order
+of the current system as a character (<code>"B"</code> for big-endian or
+<code>"L"</code> for little-endian). 
+</p></blockquote></div>
+
+<!-- syscalls.cc -->
+   <p><a name="doc_002duname"></a>
+
+<div class="defun">
+— Built-in Function: [<var>uts</var>, <var>err</var>, <var>msg</var>] = <b>uname</b> ()<var><a name="index-uname-2443"></a></var><br>
+<blockquote><p>Return system information in the structure.  For example,
+
+     <pre class="example">          uname ()
+                {
+                     sysname = x86_64
+                     nodename = segfault
+                     release = 2.6.15-1-amd64-k8-smp
+                     version = Linux
+                     machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006
+                   }
+</pre>
+        <p>If successful, <var>err</var> is 0 and <var>msg</var> is an empty string. 
+Otherwise, <var>err</var> is nonzero and <var>msg</var> contains a
+system-dependent error message. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/ispc.m -->
+   <p><a name="doc_002dispc"></a>
+
+<div class="defun">
+— Function File:  <b>ispc</b> ()<var><a name="index-ispc-2444"></a></var><br>
+<blockquote><p>Return 1 if Octave is running on a Windows system and 0 otherwise. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dismac.html#doc_002dismac">ismac</a>, <a href="doc_002disunix.html#doc_002disunix">isunix</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/isunix.m -->
+   <p><a name="doc_002disunix"></a>
+
+<div class="defun">
+— Function File:  <b>isunix</b> ()<var><a name="index-isunix-2445"></a></var><br>
+<blockquote><p>Return 1 if Octave is running on a Unix-like system and 0 otherwise. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dismac.html#doc_002dismac">ismac</a>, <a href="doc_002dispc.html#doc_002dispc">ispc</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/ismac.m -->
+   <p><a name="doc_002dismac"></a>
+
+<div class="defun">
+— Function File:  <b>ismac</b> ()<var><a name="index-ismac-2446"></a></var><br>
+<blockquote><p>Return 1 if Octave is running on a Mac OS X system and 0 otherwise. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dispc.html#doc_002dispc">ispc</a>, <a href="doc_002disunix.html#doc_002disunix">isunix</a>. 
+</p></blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002disieee"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isieee</b> ()<var><a name="index-isieee-2447"></a></var><br>
+<blockquote><p>Return 1 if your computer claims to conform to the IEEE standard for
+floating point calculations. 
+</p></blockquote></div>
+
+<!-- defaults.cc -->
+   <p><a name="doc_002dOCTAVE_005fHOME"></a>
+
+<div class="defun">
+— Built-in Function:  <b>OCTAVE_HOME</b> ()<var><a name="index-OCTAVE_005fHOME-2448"></a></var><br>
+<blockquote><p>Return the name of the top-level Octave installation directory. 
+</p></blockquote></div>
+
+<!-- defaults.cc -->
+   <p><a name="doc_002dOCTAVE_005fVERSION"></a>
+
+<div class="defun">
+— Built-in Function:  <b>OCTAVE_VERSION</b> ()<var><a name="index-OCTAVE_005fVERSION-2449"></a></var><br>
+<blockquote><p>Return the version number of Octave, as a string. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/license.m -->
+   <p><a name="doc_002dlicense"></a>
+
+<div class="defun">
+— Function File:  <b>license</b><var><a name="index-license-2450"></a></var><br>
+<blockquote><p>Display the license of Octave.
+
+   — Function File:  <b>license</b> (<var>"inuse"</var>)<var><a name="index-license-2451"></a></var><br>
+<blockquote><p>Display a list of packages currently being used.
+
+   — Function File: <var>retval</var> = <b>license</b> (<var>"inuse"</var>)<var><a name="index-license-2452"></a></var><br>
+<blockquote><p>Return a structure containing the fields <code>feature</code> and <code>user</code>.
+
+   — Function File: <var>retval</var> = <b>license</b> (<var>"test", feature</var>)<var><a name="index-license-2453"></a></var><br>
+<blockquote><p>Return 1 if a license exists for the product identified by the string
+<var>feature</var> and 0 otherwise.  The argument <var>feature</var> is case
+insensitive and only the first 27 characters are checked.
+
+   — Function File:  <b>license</b> (<var>"test", feature, toggle</var>)<var><a name="index-license-2454"></a></var><br>
+<blockquote><p>Enable or disable license testing for <var>feature</var>, depending on
+<var>toggle</var>, which may be one of:
+
+          <dl>
+<dt>‘<samp><span class="samp">"enable"</span></samp>’<dd>Future tests for the specified license of <var>feature</var> are conducted
+as usual. 
+<br><dt>‘<samp><span class="samp">"disable"</span></samp>’<dd>Future tests for the specified license of <var>feature</var> return 0. 
+</dl>
+
+   — Function File: <var>retval</var> = <b>license</b> (<var>"checkout", feature</var>)<var><a name="index-license-2455"></a></var><br>
+<blockquote><p>Check out a license for <var>feature</var>, returning 1 on success and 0
+on failure.
+
+        <p>This function is provided for compatibility with <span class="sc">matlab</span>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dver.html#doc_002dver">ver</a>, <a href="doc_002dversion.html#doc_002dversion">version</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/version.m -->
+   <p><a name="doc_002dversion"></a>
+
+<div class="defun">
+— Function File:  <b>version</b> ()<var><a name="index-version-2456"></a></var><br>
+<blockquote><p>Return Octave's version number as a string.  This is also the value of
+the built-in variable <code>OCTAVE_VERSION</code><!-- /@w -->. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/ver.m -->
+   <p><a name="doc_002dver"></a>
+
+<div class="defun">
+— Function File:  <b>ver</b> ()<var><a name="index-ver-2457"></a></var><br>
+<blockquote><p>Display a header containing the current Octave version
+number, license string and operating system, followed by
+the installed package names, versions, and installation
+directories.
+
+   — Function File: v = <b>ver</b> ()<var><a name="index-ver-2458"></a></var><br>
+<blockquote><p>Return a vector of structures, respecting Octave and each installed package. 
+The structure includes the following fields.
+
+          <dl>
+<dt><code>Name</code><dd>  Package name. 
+<br><dt><code>Version</code><dd>  Version of the package. 
+<br><dt><code>Revision</code><dd>  Revision of the package. 
+<br><dt><code>Date</code><dd>  Date respecting the version/revision. 
+</dl>
+
+   — Function File: v = <b>ver</b> (<code>"Octave"</code>)<var><a name="index-ver-2459"></a></var><br>
+<blockquote><p>Return version information for Octave only..
+
+   — Function File: v = <b>ver</b> (<var>pkg</var>)<var><a name="index-ver-2460"></a></var><br>
+<blockquote><p>Return version information for the specified package <var>pkg</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlicense.html#doc_002dlicense">license</a>, <a href="doc_002dversion.html#doc_002dversion">version</a>. 
+</p></blockquote></div>
+
+<!-- toplev.cc -->
+   <p><a name="doc_002doctave_005fconfig_005finfo"></a>
+
+<div class="defun">
+— Built-in Function:  <b>octave_config_info</b> (<var>option</var>)<var><a name="index-octave_005fconfig_005finfo-2461"></a></var><br>
+<blockquote><p>Return a structure containing configuration and installation
+information for Octave.
+
+        <p>if <var>option</var> is a string, return the configuration information for the
+specified option.
+
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/getrusage.cc -->
+   <p><a name="doc_002dgetrusage"></a>
+
+<div class="defun">
+— Loadable Function:  <b>getrusage</b> ()<var><a name="index-getrusage-2462"></a></var><br>
+<blockquote><p>Return a structure containing a number of statistics about the current
+Octave process.  Not all fields are available on all systems.  If it is
+not possible to get CPU time statistics, the CPU time slots are set to
+zero.  Other missing data are replaced by NaN.  Here is a list of all
+the possible fields that can be present in the structure returned by
+<code>getrusage</code>:
+
+          <dl>
+<dt><code>idrss</code><dd>Unshared data size.
+
+          <br><dt><code>inblock</code><dd>Number of block input operations.
+
+          <br><dt><code>isrss</code><dd>Unshared stack size.
+
+          <br><dt><code>ixrss</code><dd>Shared memory size.
+
+          <br><dt><code>majflt</code><dd>Number of major page faults.
+
+          <br><dt><code>maxrss</code><dd>Maximum data size.
+
+          <br><dt><code>minflt</code><dd>Number of minor page faults.
+
+          <br><dt><code>msgrcv</code><dd>Number of messages received.
+
+          <br><dt><code>msgsnd</code><dd>Number of messages sent.
+
+          <br><dt><code>nivcsw</code><dd>Number of involuntary context switches.
+
+          <br><dt><code>nsignals</code><dd>Number of signals received.
+
+          <br><dt><code>nswap</code><dd>Number of swaps.
+
+          <br><dt><code>nvcsw</code><dd>Number of voluntary context switches.
+
+          <br><dt><code>oublock</code><dd>Number of block output operations.
+
+          <br><dt><code>stime</code><dd>A structure containing the system CPU time used.  The structure has the
+elements <code>sec</code> (seconds) <code>usec</code> (microseconds).
+
+          <br><dt><code>utime</code><dd>A structure containing the user CPU time used.  The structure has the
+elements <code>sec</code> (seconds) <code>usec</code> (microseconds). 
+</dl>
+        </p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/System-Utilities.html b/doc/interpreter/HTML/System-Utilities.html
new file mode 100644
index 0000000..125b184
--- /dev/null
+++ b/doc/interpreter/HTML/System-Utilities.html
@@ -0,0 +1,58 @@
+<html lang="en">
+<head>
+<title>System Utilities - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Object-Oriented-Programming.html#Object-Oriented-Programming" title="Object Oriented Programming">
+<link rel="next" href="Packages.html#Packages" title="Packages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="System-Utilities"></a>
+Next: <a rel="next" accesskey="n" href="Packages.html#Packages">Packages</a>,
+Previous: <a rel="previous" accesskey="p" href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">34 System Utilities</h2>
+
+<p>This chapter describes the functions that are available to allow you to
+get information about what is happening outside of Octave, while it is
+still running, and use this information in your program.  For example,
+you can get information about environment variables, the current time,
+and even start other programs from the Octave prompt.
+
+<ul class="menu">
+<li><a accesskey="1" href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a>
+<li><a accesskey="2" href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a>
+<li><a accesskey="3" href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a>
+<li><a accesskey="4" href="Networking-Utilities.html#Networking-Utilities">Networking Utilities</a>
+<li><a accesskey="5" href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a>
+<li><a accesskey="6" href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a>
+<li><a accesskey="7" href="Environment-Variables.html#Environment-Variables">Environment Variables</a>
+<li><a accesskey="8" href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a>
+<li><a accesskey="9" href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a>
+<li><a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a>
+<li><a href="System-Information.html#System-Information">System Information</a>
+<li><a href="Hashing-Functions.html#Hashing-Functions">Hashing Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Table-of-Input-Conversions.html b/doc/interpreter/HTML/Table-of-Input-Conversions.html
new file mode 100644
index 0000000..8ea386b
--- /dev/null
+++ b/doc/interpreter/HTML/Table-of-Input-Conversions.html
@@ -0,0 +1,76 @@
+<html lang="en">
+<head>
+<title>Table of Input Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Input-Conversion-Syntax.html#Input-Conversion-Syntax" title="Input Conversion Syntax">
+<link rel="next" href="Numeric-Input-Conversions.html#Numeric-Input-Conversions" title="Numeric Input Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Table-of-Input-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">Input Conversion Syntax</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.13 Table of Input Conversions</h4>
+
+<p><a name="index-input-conversions_002c-for-_0040code_007bscanf_007d-799"></a>
+Here is a table that summarizes the various conversion specifications:
+
+     <dl>
+<dt>‘<samp><span class="samp">%d</span></samp>’<dd>Matches an optionally signed integer written in decimal.  See <a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%i</span></samp>’<dd>Matches an optionally signed integer in any of the formats that the C
+language defines for specifying an integer constant.  See <a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%o</span></samp>’<dd>Matches an unsigned integer written in octal radix. 
+See <a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%u</span></samp>’<dd>Matches an unsigned integer written in decimal radix. 
+See <a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%x</span></samp>’, ‘<samp><span class="samp">%X</span></samp>’<dd>Matches an unsigned integer written in hexadecimal radix. 
+See <a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%e</span></samp>’, ‘<samp><span class="samp">%f</span></samp>’, ‘<samp><span class="samp">%g</span></samp>’, ‘<samp><span class="samp">%E</span></samp>’, ‘<samp><span class="samp">%G</span></samp>’<dd>Matches an optionally signed floating-point number.  See <a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%s</span></samp>’<dd>Matches a string containing only non-whitespace characters. 
+See <a href="String-Input-Conversions.html#String-Input-Conversions">String Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%c</span></samp>’<dd>Matches a string of one or more characters; the number of characters
+read is controlled by the maximum field width given for the conversion. 
+See <a href="String-Input-Conversions.html#String-Input-Conversions">String Input Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%%</span></samp>’<dd>This matches a literal ‘<samp><span class="samp">%</span></samp>’ character in the input stream.  No
+corresponding argument is used. 
+</dl>
+
+   <p>If the syntax of a conversion specification is invalid, the behavior is
+undefined.  If there aren't enough function arguments provided to supply
+addresses for all the conversion specifications in the template strings
+that perform assignments, or if the arguments are not of the correct
+types, the behavior is also undefined.  On the other hand, extra
+arguments are simply ignored.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Table-of-Output-Conversions.html b/doc/interpreter/HTML/Table-of-Output-Conversions.html
new file mode 100644
index 0000000..8f08377
--- /dev/null
+++ b/doc/interpreter/HTML/Table-of-Output-Conversions.html
@@ -0,0 +1,79 @@
+<html lang="en">
+<head>
+<title>Table of Output Conversions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Output-Conversion-Syntax.html#Output-Conversion-Syntax" title="Output Conversion Syntax">
+<link rel="next" href="Integer-Conversions.html#Integer-Conversions" title="Integer Conversions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Table-of-Output-Conversions"></a>
+Next: <a rel="next" accesskey="n" href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>,
+Previous: <a rel="previous" accesskey="p" href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.7 Table of Output Conversions</h4>
+
+<p><a name="index-output-conversions_002c-for-_0040code_007bprintf_007d-788"></a>
+Here is a table summarizing what all the different conversions do:
+
+     <dl>
+<dt>‘<samp><span class="samp">%d</span></samp>’, ‘<samp><span class="samp">%i</span></samp>’<dd>Print an integer as a signed decimal number.  See <a href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>, for details.  ‘<samp><span class="samp">%d</span></samp>’ and ‘<samp><span class="samp">%i</span></samp>’ are synonymous for
+output, but are different when used with <code>scanf</code> for input
+(see <a href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">Table of Input Conversions</a>).
+
+     <br><dt>‘<samp><span class="samp">%o</span></samp>’<dd>Print an integer as an unsigned octal number.  See <a href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>, for details.
+
+     <br><dt>‘<samp><span class="samp">%u</span></samp>’<dd>Print an integer as an unsigned decimal number.  See <a href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>, for details.
+
+     <br><dt>‘<samp><span class="samp">%x</span></samp>’, ‘<samp><span class="samp">%X</span></samp>’<dd>Print an integer as an unsigned hexadecimal number.  ‘<samp><span class="samp">%x</span></samp>’ uses
+lower-case letters and ‘<samp><span class="samp">%X</span></samp>’ uses upper-case.  See <a href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>, for details.
+
+     <br><dt>‘<samp><span class="samp">%f</span></samp>’<dd>Print a floating-point number in normal (fixed-point) notation. 
+See <a href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>, for details.
+
+     <br><dt>‘<samp><span class="samp">%e</span></samp>’, ‘<samp><span class="samp">%E</span></samp>’<dd>Print a floating-point number in exponential notation.  ‘<samp><span class="samp">%e</span></samp>’ uses
+lower-case letters and ‘<samp><span class="samp">%E</span></samp>’ uses upper-case.  See <a href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>, for details.
+
+     <br><dt>‘<samp><span class="samp">%g</span></samp>’, ‘<samp><span class="samp">%G</span></samp>’<dd>Print a floating-point number in either normal (fixed-point) or
+exponential notation, whichever is more appropriate for its magnitude. 
+‘<samp><span class="samp">%g</span></samp>’ uses lower-case letters and ‘<samp><span class="samp">%G</span></samp>’ uses upper-case. 
+See <a href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>, for details.
+
+     <br><dt>‘<samp><span class="samp">%c</span></samp>’<dd>Print a single character.  See <a href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%s</span></samp>’<dd>Print a string.  See <a href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>.
+
+     <br><dt>‘<samp><span class="samp">%%</span></samp>’<dd>Print a literal ‘<samp><span class="samp">%</span></samp>’ character.  See <a href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>. 
+</dl>
+
+   <p>If the syntax of a conversion specification is invalid, unpredictable
+things will happen, so don't do this.  If there aren't enough function
+arguments provided to supply values for all the conversion
+specifications in the template string, or if the arguments are not of
+the correct types, the results are unpredictable.  If you supply more
+arguments than conversion specifications, the extra argument values are
+simply ignored; this is sometimes useful.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Techniques-used-for-Linear-Algebra.html b/doc/interpreter/HTML/Techniques-used-for-Linear-Algebra.html
new file mode 100644
index 0000000..16d8990
--- /dev/null
+++ b/doc/interpreter/HTML/Techniques-used-for-Linear-Algebra.html
@@ -0,0 +1,78 @@
+<html lang="en">
+<head>
+<title>Techniques used for Linear Algebra - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Linear-Algebra.html#Linear-Algebra" title="Linear Algebra">
+<link rel="next" href="Basic-Matrix-Functions.html#Basic-Matrix-Functions" title="Basic Matrix Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Techniques-used-for-Linear-Algebra"></a>
+Next: <a rel="next" accesskey="n" href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a>,
+Up: <a rel="up" accesskey="u" href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>
+<hr>
+</div>
+
+<h3 class="section">18.1 Techniques used for Linear Algebra</h3>
+
+<p>Octave includes a polymorphic solver, that selects an appropriate
+matrix factorization depending on the properties of the matrix itself. 
+Generally, the cost of determining the matrix type is small relative to
+the cost of factorizing the matrix itself, but in any case the matrix
+type is cached once it is calculated, so that it is not re-determined
+each time it is used in a linear equation.
+
+   <p>The selection tree for how the linear equation is solve or a matrix
+inverse is form is given by
+
+     <ol type=1 start=1>
+<li>If the matrix is upper or lower triangular sparse a forward or
+backward substitution using the <span class="sc">lapack</span> xTRTRS function, and goto 4.
+
+     <!-- Permuted triangular matrices currently disabled in the code -->
+     <!-- @item If the matrix is a upper triangular matrix with column permutations -->
+     <!-- or lower triangular matrix with row permutations, perform a forward or -->
+     <!-- backward substitution, and goto 5. -->
+     <li>If the matrix is square, hermitian with a real positive diagonal,
+attempt Cholesky factorization using the <span class="sc">lapack</span> xPOTRF function.
+
+     <li>If the Cholesky factorization failed or the matrix is not
+hermitian with a real positive diagonal, and the matrix is square, factorize
+using the <span class="sc">lapack</span> xGETRF function.
+
+     <li>If the matrix is not square, or any of the previous solvers flags
+a singular or near singular matrix, find a least squares solution using
+the <span class="sc">lapack</span> xGELSD function.
+        </ol>
+
+   <p>The user can force the type of the matrix with the <code>matrix_type</code>
+function.  This overcomes the cost of discovering the type of the matrix. 
+However, it should be noted that identifying the type of the matrix incorrectly
+will lead to unpredictable results, and so <code>matrix_type</code> should be
+used with care.
+
+   <p>It should be noted that the test for whether a matrix is a candidate for
+Cholesky factorization, performed above and by the <code>matrix_type</code>
+function, does not give a certainty that the matrix is
+Hermitian.  However, the attempt to factorize the matrix will quickly
+flag a non-Hermitian matrix.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Temporary-Files.html b/doc/interpreter/HTML/Temporary-Files.html
new file mode 100644
index 0000000..f8861c9
--- /dev/null
+++ b/doc/interpreter/HTML/Temporary-Files.html
@@ -0,0 +1,111 @@
+<html lang="en">
+<head>
+<title>Temporary Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions" title="C-Style I/O Functions">
+<link rel="prev" href="Binary-I_002fO.html#Binary-I_002fO" title="Binary I/O">
+<link rel="next" href="EOF-and-Errors.html#EOF-and-Errors" title="EOF and Errors">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Temporary-Files"></a>
+Next: <a rel="next" accesskey="n" href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a>,
+Previous: <a rel="previous" accesskey="p" href="Binary-I_002fO.html#Binary-I_002fO">Binary I/O</a>,
+Up: <a rel="up" accesskey="u" href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.2.17 Temporary Files</h4>
+
+<p>Sometimes one needs to write data to a file that is only temporary. 
+This is most commonly used when an external program launched from
+within Octave needs to access data.  When Octave exits all temporary
+files will be deleted, so this step need not be executed manually.
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dmkstemp"></a>
+
+<div class="defun">
+— Built-in Function: [<var>fid</var>, <var>name</var>, <var>msg</var>] = <b>mkstemp</b> (<var>template, delete</var>)<var><a name="index-mkstemp-802"></a></var><br>
+<blockquote><p>Return the file ID corresponding to a new temporary file with a unique
+name created from <var>template</var>.  The last six characters of <var>template</var>
+must be <code>XXXXXX</code> and these are replaced with a string that makes the
+filename unique.  The file is then created with mode read/write and
+permissions that are system dependent (on GNU/Linux systems, the permissions
+will be 0600 for versions of glibc 2.0.7 and later).  The file is opened
+with the <code>O_EXCL</code><!-- /@w --> flag.
+
+        <p>If the optional argument <var>delete</var> is supplied and is true,
+the file will be deleted automatically when Octave exits, or when
+the function <code>purge_tmp_files</code> is called.
+
+        <p>If successful, <var>fid</var> is a valid file ID, <var>name</var> is the name of
+the file, and <var>msg</var> is an empty string.  Otherwise, <var>fid</var>
+is -1, <var>name</var> is empty, and <var>msg</var> contains a system-dependent
+error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtmpfile.html#doc_002dtmpfile">tmpfile</a>, <a href="doc_002dtmpnam.html#doc_002dtmpnam">tmpnam</a>, <a href="doc_002dP_005ftmpdir.html#doc_002dP_005ftmpdir">P_tmpdir</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dtmpfile"></a>
+
+<div class="defun">
+— Built-in Function: [<var>fid</var>, <var>msg</var>] = <b>tmpfile</b> ()<var><a name="index-tmpfile-803"></a></var><br>
+<blockquote><p>Return the file ID corresponding to a new temporary file with a unique
+name.  The file is opened in binary read/write (<code>"w+b"</code>) mode. 
+The file will be deleted automatically when it is closed or when Octave
+exits.
+
+        <p>If successful, <var>fid</var> is a valid file ID and <var>msg</var> is an empty
+string.  Otherwise, <var>fid</var> is -1 and <var>msg</var> contains a
+system-dependent error message. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtmpnam.html#doc_002dtmpnam">tmpnam</a>, <a href="doc_002dmkstemp.html#doc_002dmkstemp">mkstemp</a>, <a href="doc_002dP_005ftmpdir.html#doc_002dP_005ftmpdir">P_tmpdir</a>. 
+</p></blockquote></div>
+
+<!-- file-io.cc -->
+   <p><a name="doc_002dtmpnam"></a>
+
+<div class="defun">
+— Built-in Function:  <b>tmpnam</b> (<var>dir, prefix</var>)<var><a name="index-tmpnam-804"></a></var><br>
+<blockquote><p>Return a unique temporary file name as a string.
+
+        <p>If <var>prefix</var> is omitted, a value of <code>"oct-"</code> is used. 
+If <var>dir</var> is also omitted, the default directory for temporary files
+is used.  If <var>dir</var> is provided, it must exist, otherwise the default
+directory for temporary files is used.  Since the named file is not
+opened, by <code>tmpnam</code>, it is possible (though relatively unlikely)
+that it will not be available by the time your program attempts to open it. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtmpfile.html#doc_002dtmpfile">tmpfile</a>, <a href="doc_002dmkstemp.html#doc_002dmkstemp">mkstemp</a>, <a href="doc_002dP_005ftmpdir.html#doc_002dP_005ftmpdir">P_tmpdir</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Terminal-Input.html b/doc/interpreter/HTML/Terminal-Input.html
new file mode 100644
index 0000000..3fa839c
--- /dev/null
+++ b/doc/interpreter/HTML/Terminal-Input.html
@@ -0,0 +1,131 @@
+<html lang="en">
+<head>
+<title>Terminal Input - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Input-and-Output.html#Basic-Input-and-Output" title="Basic Input and Output">
+<link rel="prev" href="Terminal-Output.html#Terminal-Output" title="Terminal Output">
+<link rel="next" href="Simple-File-I_002fO.html#Simple-File-I_002fO" title="Simple File I/O">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Terminal-Input"></a>
+Next: <a rel="next" accesskey="n" href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a>,
+Previous: <a rel="previous" accesskey="p" href="Terminal-Output.html#Terminal-Output">Terminal Output</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.1.2 Terminal Input</h4>
+
+<p>Octave has three functions that make it easy to prompt users for
+input.  The <code>input</code> and <code>menu</code> functions are normally
+used for managing an interactive dialog with a user, and the
+<code>keyboard</code> function is normally used for doing simple debugging.
+
+<!-- input.cc -->
+   <p><a name="doc_002dinput"></a>
+
+<div class="defun">
+— Built-in Function:  <b>input</b> (<var>prompt</var>)<var><a name="index-input-722"></a></var><br>
+— Built-in Function:  <b>input</b> (<var>prompt, "s"</var>)<var><a name="index-input-723"></a></var><br>
+<blockquote><p>Print a prompt and wait for user input.  For example,
+
+     <pre class="example">          input ("Pick a number, any number! ")
+</pre>
+        <p class="noindent">prints the prompt
+
+     <pre class="example">          Pick a number, any number!
+</pre>
+        <p class="noindent">and waits for the user to enter a value.  The string entered by the user
+is evaluated as an expression, so it may be a literal constant, a
+variable name, or any other valid expression.
+
+        <p>Currently, <code>input</code> only returns one value, regardless of the number
+of values produced by the evaluation of the expression.
+
+        <p>If you are only interested in getting a literal string value, you can
+call <code>input</code> with the character string <code>"s"</code> as the second
+argument.  This tells Octave to return the string entered by the user
+directly, without evaluating it first.
+
+        <p>Because there may be output waiting to be displayed by the pager, it is
+a good idea to always call <code>fflush (stdout)</code> before calling
+<code>input</code>.  This will ensure that all pending output is written to
+the screen before your prompt.  See <a href="Input-and-Output.html#Input-and-Output">Input and Output</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/menu.m -->
+   <p><a name="doc_002dmenu"></a>
+
+<div class="defun">
+— Function File:  <b>menu</b> (<var>title, opt1, <small class="dots">...</small></var>)<var><a name="index-menu-724"></a></var><br>
+<blockquote><p>Print a title string followed by a series of options.  Each option will
+be printed along with a number.  The return value is the number of the
+option selected by the user.  This function is useful for interactive
+programs.  There is no limit to the number of options that may be passed
+in, but it may be confusing to present more than will fit easily on one
+screen. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddisp.html#doc_002ddisp">disp</a>, <a href="doc_002dprintf.html#doc_002dprintf">printf</a>, <a href="doc_002dinput.html#doc_002dinput">input</a>. 
+</p></blockquote></div>
+
+<!-- input.cc -->
+   <p><a name="doc_002dyes_005for_005fno"></a>
+
+<div class="defun">
+— Built-in Function:  <b>yes_or_no</b> (<var>prompt</var>)<var><a name="index-yes_005for_005fno-725"></a></var><br>
+<blockquote><p>Ask the user a yes-or-no question.  Return 1 if the answer is yes. 
+Takes one argument, which is the string to display to ask the
+question.  It should end in a space; ‘<samp><span class="samp">yes-or-no-p</span></samp>’ adds
+‘<samp><span class="samp">(yes or no) </span></samp>’ to it.  The user must confirm the answer with
+RET and can edit it until it has been confirmed. 
+</p></blockquote></div>
+
+   <p>For <code>input</code>, the normal command line history and editing functions
+are available at the prompt.
+
+   <p>Octave also has a function that makes it possible to get a single
+character from the keyboard without requiring the user to type a
+carriage return.
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dkbhit"></a>
+
+<div class="defun">
+— Built-in Function:  <b>kbhit</b> ()<var><a name="index-kbhit-726"></a></var><br>
+<blockquote><p>Read a single keystroke from the keyboard.  If called with one
+argument, don't wait for a keypress.  For example,
+
+     <pre class="example">          x = kbhit ();
+</pre>
+        <p class="noindent">will set <var>x</var> to the next character typed at the keyboard as soon as
+it is typed.
+
+     <pre class="example">          x = kbhit (1);
+</pre>
+        <p class="noindent">identical to the above example, but don't wait for a keypress,
+returning the empty string if no key is available. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Terminal-Output.html b/doc/interpreter/HTML/Terminal-Output.html
new file mode 100644
index 0000000..507bd01
--- /dev/null
+++ b/doc/interpreter/HTML/Terminal-Output.html
@@ -0,0 +1,203 @@
+<html lang="en">
+<head>
+<title>Terminal Output - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Basic-Input-and-Output.html#Basic-Input-and-Output" title="Basic Input and Output">
+<link rel="next" href="Terminal-Input.html#Terminal-Input" title="Terminal Input">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Terminal-Output"></a>
+Next: <a rel="next" accesskey="n" href="Terminal-Input.html#Terminal-Input">Terminal Input</a>,
+Up: <a rel="up" accesskey="u" href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>
+<hr>
+</div>
+
+<h4 class="subsection">14.1.1 Terminal Output</h4>
+
+<p>Since Octave normally prints the value of an expression as soon as it
+has been evaluated, the simplest of all I/O functions is a simple
+expression.  For example, the following expression will display the
+value of ‘<samp><span class="samp">pi</span></samp>’
+
+<pre class="example">     pi
+          -| pi = 3.1416
+</pre>
+   <p>This works well as long as it is acceptable to have the name of the
+variable (or ‘<samp><span class="samp">ans</span></samp>’) printed along with the value.  To print the
+value of a variable without printing its name, use the function
+<code>disp</code>.
+
+   <p>The <code>format</code> command offers some control over the way Octave prints
+values with <code>disp</code> and through the normal echoing mechanism.
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002ddisp"></a>
+
+<div class="defun">
+— Built-in Function:  <b>disp</b> (<var>x</var>)<var><a name="index-disp-707"></a></var><br>
+<blockquote><p>Display the value of <var>x</var>.  For example,
+
+     <pre class="example">          disp ("The value of pi is:"), disp (pi)
+          
+               -| the value of pi is:
+               -| 3.1416
+</pre>
+        <p class="noindent">Note that the output from <code>disp</code> always ends with a newline.
+
+        <p>If an output value is requested, <code>disp</code> prints nothing and
+returns the formatted output in a string. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfdisp.html#doc_002dfdisp">fdisp</a>. 
+</p></blockquote></div>
+
+<!-- pr-output.cc -->
+   <p><a name="doc_002dformat"></a>
+
+<div class="defun">
+— Command: <b>format</b><var><a name="index-format-708"></a></var><br>
+— Command: <b>format</b><var> options<a name="index-format-709"></a></var><br>
+<blockquote><p>Reset or specify the format of the output produced by <code>disp</code> and
+Octave's normal echoing mechanism.  This command only affects the display
+of numbers but not how they are stored or computed.  To change the internal
+representation from the default double use one of the conversion functions
+such as <code>single</code>, <code>uint8</code>, <code>int64</code>, etc.
+
+        <p>By default, Octave displays 5 significant digits in a human readable form
+(option ‘<samp><span class="samp">short</span></samp>’ paired with ‘<samp><span class="samp">loose</span></samp>’ format for matrices). 
+If <code>format</code> is invoked without any options, this default format
+is restored.
+
+        <p>Valid formats for floating point numbers are listed in the following
+table.
+
+          <dl>
+<dt><code>short</code><dd>Fixed point format with 5 significant figures in a field that is a maximum
+of 10 characters wide.  (default).
+
+          <p>If Octave is unable to format a matrix so that columns line up on the
+decimal point and all numbers fit within the maximum field width then
+it switches to an exponential ‘<samp><span class="samp">e</span></samp>’ format.
+
+          <br><dt><code>long</code><dd>Fixed point format with 15 significant figures in a field that is a maximum
+of 20 characters wide.
+
+          <p>As with the ‘<samp><span class="samp">short</span></samp>’ format, Octave will switch to an exponential
+‘<samp><span class="samp">e</span></samp>’ format if it is unable to format a matrix properly using the
+current format.
+
+          <br><dt><code>short e</code><dt><code>long e</code><dd>Exponential format.  The number to be represented is split between a mantissa
+and an exponent (power of 10).  The mantissa has 5 significant digits in the
+short format and 15 digits in the long format. 
+For example, with the ‘<samp><span class="samp">short e</span></samp>’ format, <code>pi</code> is displayed as
+<code>3.1416e+00</code>.
+
+          <br><dt><code>short E</code><dt><code>long E</code><dd>Identical to ‘<samp><span class="samp">short e</span></samp>’ or ‘<samp><span class="samp">long e</span></samp>’ but displays an uppercase
+‘<samp><span class="samp">E</span></samp>’ to indicate the exponent. 
+For example, with the ‘<samp><span class="samp">long E</span></samp>’ format, <code>pi</code> is displayed as
+<code>3.14159265358979E+00</code>.
+
+          <br><dt><code>short g</code><dt><code>long g</code><dd>Optimally choose between fixed point and exponential format based on
+the magnitude of the number. 
+For example, with the ‘<samp><span class="samp">short g</span></samp>’ format,
+<code>pi .^ [2; 4; 8; 16; 32]</code> is displayed as
+
+          <pre class="example">               ans =
+               
+                     9.8696
+                     97.409
+                     9488.5
+                 9.0032e+07
+                 8.1058e+15
+</pre>
+          <br><dt><code>long G</code><dt><code>short G</code><dd>Identical to ‘<samp><span class="samp">short g</span></samp>’ or ‘<samp><span class="samp">long g</span></samp>’ but displays an uppercase
+‘<samp><span class="samp">E</span></samp>’ to indicate the exponent.
+
+          <br><dt><code>free</code><dt><code>none</code><dd>Print output in free format, without trying to line up columns of
+matrices on the decimal point.  This also causes complex numbers to be
+formatted as numeric pairs like this ‘<samp><span class="samp">(0.60419, 0.60709)</span></samp>’ instead
+of like this ‘<samp><span class="samp">0.60419 + 0.60709i</span></samp>’. 
+</dl>
+
+        <p>The following formats affect all numeric output (floating point and
+integer types).
+
+          <dl>
+<dt><code>+</code><dt><code>+ </code><var>chars</var><dt><code>plus</code><dt><code>plus </code><var>chars</var><dd>Print a ‘<samp><span class="samp">+</span></samp>’ symbol for nonzero matrix elements and a space for zero
+matrix elements.  This format can be very useful for examining the
+structure of a large sparse matrix.
+
+          <p>The optional argument <var>chars</var> specifies a list of 3 characters to use
+for printing values greater than zero, less than zero and equal to zero. 
+For example, with the ‘<samp><span class="samp">+ "+-."</span></samp>’ format, <code>[1, 0, -1; -1, 0, 1]</code>
+is displayed as
+
+          <pre class="example">               ans =
+               
+               +.-
+               -.+
+</pre>
+          <br><dt><code>bank</code><dd>Print in a fixed format with two digits to the right of the decimal
+point.
+
+          <br><dt><code>native-hex</code><dd>Print the hexadecimal representation of numbers as they are stored in
+memory.  For example, on a workstation which stores 8 byte real values
+in IEEE format with the least significant byte first, the value of
+<code>pi</code> when printed in <code>native-hex</code> format is <code>400921fb54442d18</code>.
+
+          <br><dt><code>hex</code><dd>The same as <code>native-hex</code>, but always print the most significant
+byte first. 
+<br><dt><code>native-bit</code><dd>Print the bit representation of numbers as stored in memory. 
+For example, the value of <code>pi</code> is
+
+          <pre class="example">               01000000000010010010000111111011
+               01010100010001000010110100011000
+</pre>
+          <p>(shown here in two 32 bit sections for typesetting purposes) when
+printed in native-bit format on a workstation which stores 8 byte real values
+in IEEE format with the least significant byte first. 
+<br><dt><code>bit</code><dd>The same as <code>native-bit</code>, but always print the most significant
+bits first.
+
+          <br><dt><code>rat</code><dd>Print a rational approximation, i.e., values are approximated
+as the ratio of small integers. 
+For example, with the ‘<samp><span class="samp">rat</span></samp>’ format,
+<code>pi</code> is displayed as <code>355/113</code>. 
+</dl>
+
+        <p>The following two options affect the display of all matrices.
+
+          <dl>
+<dt><code>compact</code><dd>Remove extra blank space around column number labels producing more compact
+output with more data per page. 
+<br><dt><code>loose</code><dd>Insert blank lines above and below column number labels to produce a more
+readable output with less data per page.  (default). 
+</dl>
+        </p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Test-Functions.html b/doc/interpreter/HTML/Test-Functions.html
new file mode 100644
index 0000000..1dcc945
--- /dev/null
+++ b/doc/interpreter/HTML/Test-Functions.html
@@ -0,0 +1,337 @@
+<html lang="en">
+<head>
+<title>Test Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions" title="Test and Demo Functions">
+<link rel="next" href="Demonstration-Functions.html#Demonstration-Functions" title="Demonstration Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Test-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a>,
+Up: <a rel="up" accesskey="u" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a>
+<hr>
+</div>
+
+<h3 class="section">B.1 Test Functions</h3>
+
+<!-- ./testfun/test.m -->
+<p><a name="doc_002dtest"></a>
+
+<div class="defun">
+— Function File:  <b>test</b><var> name<a name="index-test-2485"></a></var><br>
+— Function File:  <b>test</b><var> name quiet|normal|verbose<a name="index-test-2486"></a></var><br>
+— Function File:  <b>test</b> (<var>'name', 'quiet|normal|verbose', fid</var>)<var><a name="index-test-2487"></a></var><br>
+— Function File:  <b>test</b> ([]<var>, 'explain', fid</var>)<var><a name="index-test-2488"></a></var><br>
+— Function File: <var>success</var> = <b>test</b> (<var><small class="dots">...</small></var>)<var><a name="index-test-2489"></a></var><br>
+— Function File: [<var>n</var>, <var>max</var>] = <b>test</b> (<var><small class="dots">...</small></var>)<var><a name="index-test-2490"></a></var><br>
+— Function File: [<var>code</var>, <var>idx</var>] = <b>test</b> (<var>'name','grabdemo'</var>)<var><a name="index-test-2491"></a></var><br>
+<blockquote>
+        <p>Perform tests from the first file in the loadpath matching <var>name</var>. 
+<code>test</code> can be called as a command or as a function.  Called with
+a single argument <var>name</var>, the tests are run interactively and stop
+after the first error is encountered.
+
+        <p>With a second argument the tests which are performed and the amount of
+output is selected.
+
+          <dl>
+<dt>'quiet'<dd> Don't report all the tests as they happen, just the errors.
+
+          <br><dt>'normal'<dd>Report all tests as they happen, but don't do tests which require
+user interaction.
+
+          <br><dt>'verbose'<dd>Do tests which require user interaction. 
+</dl>
+
+        <p>The argument <var>fid</var> can be used to allow batch processing.  Errors
+can be written to the already open file defined by <var>fid</var>, and
+hopefully when Octave crashes this file will tell you what was happening
+when it did.  You can use <code>stdout</code> if you want to see the results as
+they happen.  You can also give a file name rather than an <var>fid</var>, in
+which case the contents of the file will be replaced with the log from
+the current test.
+
+        <p>Called with a single output argument <var>success</var>, <code>test</code> returns
+true if all of the tests were successful.  Called with two output arguments
+<var>n</var> and <var>max</var>, the number of successful tests and the total number
+of tests in the file <var>name</var> are returned.
+
+        <p>If the second argument is the string 'grabdemo', the contents of the demo
+blocks are extracted but not executed.  Code for all code blocks is
+concatenated and returned as <var>code</var> with <var>idx</var> being a vector of
+positions of the ends of the demo blocks.
+
+        <p>If the second argument is 'explain', then <var>name</var> is ignored and an
+explanation of the line markers used is written to the file <var>fid</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derror.html#doc_002derror">error</a>, <a href="doc_002dassert.html#doc_002dassert">assert</a>, <a href="doc_002dfail.html#doc_002dfail">fail</a>, <a href="doc_002ddemo.html#doc_002ddemo">demo</a>, <a href="doc_002dexample.html#doc_002dexample">example</a>. 
+</p></blockquote></div>
+
+   <p><code>test</code> scans the named script file looking for lines which
+start with <code>%!</code>.  The prefix is stripped off and the rest of the
+line is processed through the Octave interpreter.  If the code
+generates an error, then the test is said to fail.
+
+   <p>Since <code>eval()</code> will stop at the first error it encounters, you must
+divide your tests up into blocks, with anything in a separate
+block evaluated separately.  Blocks are introduced by the keyword
+<code>test</code> immediately following the <code>%!</code>.  For example,
+
+<pre class="example">        %!test error ("this test fails!");
+        %!test "test doesn't fail. it doesn't generate an error";
+</pre>
+   <p>When a test fails, you will see something like:
+
+<pre class="example">          ***** test error ('this test fails!')
+        !!!!! test failed
+        this test fails!
+</pre>
+   <p>Generally, to test if something works, you want to assert that it
+produces a correct value.  A real test might look something like
+
+<pre class="example">        %!test
+        %! <var>a</var> = [1, 2, 3; 4, 5, 6]; B = [1; 2];
+        %! expect = [ <var>a</var> ; 2*<var>a</var> ];
+        %! get = kron (<var>b</var>, <var>a</var>);
+        %! if (any(size(expect) != size(get)))
+        %!    error ("wrong size: expected %d,%d but got %d,%d",
+        %!           size(expect), size(get));
+        %! elseif (any(any(expect!=get)))
+        %!    error ("didn't get what was expected.");
+        %! endif
+</pre>
+   <p>To make the process easier, use the <code>assert</code> function.  For example,
+with <code>assert</code> the previous test is reduced to:
+
+<pre class="example">        %!test
+        %! <var>a</var> = [1, 2, 3; 4, 5, 6]; <var>b</var> = [1; 2];
+        %! assert (kron (<var>b</var>, <var>a</var>), [ <var>a</var>; 2*<var>a</var> ]);
+</pre>
+   <p><code>assert</code> can accept a tolerance so that you can compare results
+absolutely or relatively.  For example, the following all succeed:
+
+<pre class="example">        %!test assert (1+eps, 1, 2*eps)          # absolute error
+        %!test assert (100+100*eps, 100, -2*eps) # relative error
+</pre>
+   <p>You can also do the comparison yourself, but still have assert
+generate the error:
+
+<pre class="example">        %!test assert (isempty([]))
+        %!test assert ([ 1,2; 3,4 ] > 0)
+</pre>
+   <p>Because <code>assert</code> is so frequently used alone in a test block, there
+is a shorthand form:
+
+<pre class="example">        %!assert (...)
+</pre>
+   <p>which is equivalent to:
+
+<pre class="example">        %!test assert (...)
+</pre>
+   <p>Sometimes during development there is a test that should work but is
+known to fail.  You still want to leave the test in because when the
+final code is ready the test should pass, but you may not be able to
+fix it immediately.  To avoid unnecessary bug reports for these known
+failures, mark the block with <code>xtest</code> rather than <code>test</code>:
+
+<pre class="example">        %!xtest assert (1==0)
+        %!xtest fail ('success=1','error'))
+</pre>
+   <p>Another use of <code>xtest</code> is for statistical tests which should
+pass most of the time but are known to fail occasionally.
+
+   <p>Each block is evaluated in its own function environment, which means
+that variables defined in one block are not automatically shared
+with other blocks.  If you do want to share variables, then you
+must declare them as <code>shared</code> before you use them.  For example, the
+following declares the variable <var>a</var>, gives it an initial value (default
+is empty), then uses it in several subsequent tests.
+
+<pre class="example">        %!shared <var>a</var>
+        %! <var>a</var> = [1, 2, 3; 4, 5, 6];
+        %!assert (kron ([1; 2], <var>a</var>), [ <var>a</var>; 2*<var>a</var> ]);
+        %!assert (kron ([1, 2], <var>a</var>), [ <var>a</var>, 2*<var>a</var> ]);
+        %!assert (kron ([1,2; 3,4], <var>a</var>), [ <var>a</var>,2*<var>a</var>; 3*<var>a</var>,4*<var>a</var> ]);
+</pre>
+   <p>You can share several variables at the same time:
+
+<pre class="example">        %!shared <var>a</var>, <var>b</var>
+</pre>
+   <p>You can also share test functions:
+
+<pre class="example">        %!function <var>a</var> = fn(<var>b</var>)
+        %!  <var>a</var> = 2*<var>b</var>;
+        %!assert (<var>a</var>(2),4);
+</pre>
+   <p>Note that all previous variables and values are lost when a new
+shared block is declared.
+
+   <p>Error and warning blocks are like test blocks, but they only succeed
+if the code generates an error.  You can check the text of the error
+is correct using an optional regular expression <code><pattern></code>. 
+For example:
+
+<pre class="example">        %!error <passes!> error('this test passes!');
+</pre>
+   <p>If the code doesn't generate an error, the test fails.  For example,
+
+<pre class="example">        %!error "this is an error because it succeeds.";
+</pre>
+   <p>produces
+
+<pre class="example">        ***** error "this is an error because it succeeds.";
+        !!!!! test failed: no error
+</pre>
+   <p>It is important to automate the tests as much as possible, however
+some tests require user interaction.  These can be isolated into
+demo blocks, which if you are in batch mode, are only run when
+called with <code>demo</code> or <code>verbose</code>.  The code is displayed before
+it is executed.  For example,
+
+<pre class="example">        %!demo
+        %! <var>t</var>=[0:0.01:2*pi]; <var>x</var>=sin(<var>t</var>);
+        %! plot(<var>t</var>,<var>x</var>);
+        %! you should now see a sine wave in your figure window
+</pre>
+   <p>produces
+
+<pre class="example">        > <var>t</var>=[0:0.01:2*pi]; <var>x</var>=sin(<var>t</var>);
+        > plot(<var>t</var>,<var>x</var>);
+        > you should now see a sine wave in your figure window
+        Press <enter> to continue:
+</pre>
+   <p>Note that demo blocks cannot use any shared variables.  This is so
+that they can be executed by themselves, ignoring all other tests.
+
+   <p>If you want to temporarily disable a test block, put <code>#</code> in place
+of the block type.  This creates a comment block which is echoed
+in the log file, but is not executed.  For example:
+
+<pre class="example">        %!#demo
+        %! <var>t</var>=[0:0.01:2*pi]; <var>x</var>=sin(<var>t</var>);
+        %! plot(<var>t</var>,<var>x</var>);
+        %! you should now see a sine wave in your figure window
+</pre>
+   <p>Block type summary:
+
+     <dl>
+<dt><code>%!test</code><dd>check that entire block is correct
+<br><dt><code>%!error</code><dd>check for correct error message
+<br><dt><code>%!warning</code><dd>check for correct warning message
+<br><dt><code>%!demo</code><dd>demo only executes in interactive mode
+<br><dt><code>%!#</code><dd>comment: ignore everything within the block
+<br><dt><code>%!shared x,y,z</code><dd>declares variables for use in multiple tests
+<br><dt><code>%!function</code><dd>defines a function value for a shared variable
+<br><dt><code>%!assert (x, y, tol)</code><dd>shorthand for %!test assert (x, y, tol)
+</dl>
+
+   <p>You can also create test scripts for builtins and your own C++
+functions.  Just put a file of the function name on your path without
+any extension and it will be picked up by the test procedure.  You
+can even embed tests directly in your C++ code:
+
+<pre class="example">        #if 0
+        %!test disp('this is a test')
+        #endif
+</pre>
+   <p>or
+
+<pre class="example">        /*
+        %!test disp('this is a test')
+        */
+</pre>
+   <p>but then the code will have to be on the load path and the user
+will have to remember to type test('name.cc').  Conversely, you
+can separate the tests from normal Octave script files by putting
+them in plain files with no extension rather than in script files. 
+<!-- DO I WANT TO INCLUDE THE EDITOR SPECIFIC STATEMENT BELOW??? -->
+<!-- Don't forget to tell emacs that the plain text file you are using -->
+<!-- is actually octave code, using something like: -->
+<!-- *-octave-*- -->
+
+<!-- ./testfun/assert.m -->
+   <p><a name="doc_002dassert"></a>
+
+<div class="defun">
+— Function File:  <b>assert</b> (<var>cond</var>)<var><a name="index-assert-2492"></a></var><br>
+— Function File:  <b>assert</b> (<var>cond, errmsg, <small class="dots">...</small></var>)<var><a name="index-assert-2493"></a></var><br>
+— Function File:  <b>assert</b> (<var>cond, msg_id, errmsg, <small class="dots">...</small></var>)<var><a name="index-assert-2494"></a></var><br>
+— Function File:  <b>assert</b> (<var>observed,expected</var>)<var><a name="index-assert-2495"></a></var><br>
+— Function File:  <b>assert</b> (<var>observed,expected,tol</var>)<var><a name="index-assert-2496"></a></var><br>
+<blockquote>
+        <p>Produces an error if the condition is not met.  <code>assert</code> can be
+called in three different ways.
+
+          <dl>
+<dt><code>assert (</code><var>cond</var><code>)</code><dt><code>assert (</code><var>cond</var><code>, </code><var>errmsg</var><code>, ...)</code><dt><code>assert (</code><var>cond</var><code>, </code><var>msg_id</var><code>, </code><var>errmsg</var><code>, ...)</code><dd>Called with a single argument <var>cond</var>, <code>assert</code> produces an
+error if <var>cond</var> is zero.  If called with a single argument a
+generic error message.  With more than one argument, the additional
+arguments are passed to the <code>error</code> function.
+
+          <br><dt><code>assert (</code><var>observed</var><code>, </code><var>expected</var><code>)</code><dd>Produce an error if observed is not the same as expected.  Note that
+observed and expected can be strings, scalars, vectors, matrices,
+lists or structures.
+
+          <br><dt><code>assert(</code><var>observed</var><code>, </code><var>expected</var><code>, </code><var>tol</var><code>)</code><dd>Accept a tolerance when comparing numbers. 
+If <var>tol</var> is positive use it as an absolute tolerance, will produce an error if
+<code>abs(</code><var>observed</var><code> - </code><var>expected</var><code>) > abs(</code><var>tol</var><code>)</code>. 
+If <var>tol</var> is negative use it as a relative tolerance, will produce an error if
+<code>abs(</code><var>observed</var><code> - </code><var>expected</var><code>) > abs(</code><var>tol</var><code> * </code><var>expected</var><code>)</code>. 
+If <var>expected</var> is zero <var>tol</var> will always be used as an absolute tolerance. 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtest.html#doc_002dtest">test</a>. 
+</p></blockquote></div>
+
+<!-- ./testfun/fail.m -->
+   <p><a name="doc_002dfail"></a>
+
+<div class="defun">
+— Function File:  <b>fail</b> (<var>code,pattern</var>)<var><a name="index-fail-2497"></a></var><br>
+— Function File:  <b>fail</b> (<var>code,'warning',pattern</var>)<var><a name="index-fail-2498"></a></var><br>
+<blockquote>
+        <p>Return true if <var>code</var> fails with an error message matching
+<var>pattern</var>, otherwise produce an error.  Note that <var>code</var>
+is a string and if <var>code</var> runs successfully, the error produced is:
+
+     <pre class="example">                    expected error but got none
+</pre>
+        <p>If the code fails with a different error, the message produced is:
+
+     <pre class="example">                    expected <pattern>
+                    but got <text of actual error>
+</pre>
+        <p>The angle brackets are not part of the output.
+
+        <p>Called with three arguments, the behavior is similar to
+<code>fail(</code><var>code</var><code>, </code><var>pattern</var><code>)</code>, but produces an error if no
+warning is given during code execution or if the code fails.
+
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Test-Plotting-Functions.html b/doc/interpreter/HTML/Test-Plotting-Functions.html
new file mode 100644
index 0000000..7415ca9
--- /dev/null
+++ b/doc/interpreter/HTML/Test-Plotting-Functions.html
@@ -0,0 +1,91 @@
+<html lang="en">
+<head>
+<title>Test Plotting Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Interacting-with-plots.html#Interacting-with-plots" title="Interacting with plots">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Test-Plotting-Functions"></a>
+Previous: <a rel="previous" accesskey="p" href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.8 Test Plotting Functions</h4>
+
+<p>The functions <code>sombrero</code> and <code>peaks</code> provide a way to check
+that plotting is working.  Typing either <code>sombrero</code> or <code>peaks</code>
+at the Octave prompt should display a three-dimensional plot.
+
+<!-- ./plot/sombrero.m -->
+   <p><a name="doc_002dsombrero"></a>
+
+<div class="defun">
+— Function File:  <b>sombrero</b> (<var>n</var>)<var><a name="index-sombrero-1104"></a></var><br>
+<blockquote><p>Produce the familiar three-dimensional sombrero plot using <var>n</var>
+grid lines.  If <var>n</var> is omitted, a value of 41 is assumed.
+
+        <p>The function plotted is
+
+     <pre class="example">          z = sin (sqrt (x^2 + y^2)) / (sqrt (x^2 + y^2))
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsurf.html#doc_002dsurf">surf</a>, <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/peaks.m -->
+   <p><a name="doc_002dpeaks"></a>
+
+<div class="defun">
+— Function File:  <b>peaks</b> ()<var><a name="index-peaks-1105"></a></var><br>
+— Function File:  <b>peaks</b> (<var>n</var>)<var><a name="index-peaks-1106"></a></var><br>
+— Function File:  <b>peaks</b> (<var>x, y</var>)<var><a name="index-peaks-1107"></a></var><br>
+— Function File: <var>z</var> = <b>peaks</b> (<var><small class="dots">...</small></var>)<var><a name="index-peaks-1108"></a></var><br>
+— Function File: [<var>x</var>, <var>y</var>, <var>z</var>] = <b>peaks</b> (<var><small class="dots">...</small></var>)<var><a name="index-peaks-1109"></a></var><br>
+<blockquote><p>Generate a function with lots of local maxima and minima.  The function
+has the form
+
+     <pre class="verbatim">     
+     f(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) ...
+              - 10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) ...
+              - 1/3*exp(-(x+1)^2 - y^2)
+</pre>
+
+        <p>Called without a return argument, <code>peaks</code> plots the surface of the
+above function using <code>mesh</code>.  If <var>n</var> is a scalar, the <code>peaks</code>
+returns the values of the above function on a <var>n</var>-by-<var>n</var> mesh over
+the range <code>[-3,3]</code>.  The default value for <var>n</var> is 49.
+
+        <p>If <var>n</var> is a vector, then it represents the <var>x</var> and <var>y</var> values
+of the grid on which to calculate the above function.  The <var>x</var> and
+<var>y</var> values can be specified separately. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsurf.html#doc_002dsurf">surf</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Test-and-Demo-Functions.html b/doc/interpreter/HTML/Test-and-Demo-Functions.html
new file mode 100644
index 0000000..8a6efa0
--- /dev/null
+++ b/doc/interpreter/HTML/Test-and-Demo-Functions.html
@@ -0,0 +1,46 @@
+<html lang="en">
+<head>
+<title>Test and Demo Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions" title="Dynamically Linked Functions">
+<link rel="next" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Test-and-Demo-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>,
+Previous: <a rel="previous" accesskey="p" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix B Test and Demo Functions</h2>
+
+<p><a name="index-test-functions-2484"></a>
+Octave includes a number of functions to allow the integration of testing
+and demonstration code in the source code of the functions themselves.
+
+<ul class="menu">
+<li><a accesskey="1" href="Test-Functions.html#Test-Functions">Test Functions</a>
+<li><a accesskey="2" href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Tests.html b/doc/interpreter/HTML/Tests.html
new file mode 100644
index 0000000..7f5b185
--- /dev/null
+++ b/doc/interpreter/HTML/Tests.html
@@ -0,0 +1,676 @@
+<html lang="en">
+<head>
+<title>Tests - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statistics.html#Statistics" title="Statistics">
+<link rel="prev" href="Statistical-Plots.html#Statistical-Plots" title="Statistical Plots">
+<link rel="next" href="Models.html#Models" title="Models">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Tests"></a>
+Next: <a rel="next" accesskey="n" href="Models.html#Models">Models</a>,
+Previous: <a rel="previous" accesskey="p" href="Statistical-Plots.html#Statistical-Plots">Statistical Plots</a>,
+Up: <a rel="up" accesskey="u" href="Statistics.html#Statistics">Statistics</a>
+<hr>
+</div>
+
+<h3 class="section">25.4 Tests</h3>
+
+<p>Octave can perform several different statistical tests.  The following
+table summarizes the available tests.
+
+   <p><table summary=""><tr align="left"><td valign="top" width="40%"><strong>Hypothesis</strong>
+  </td><td valign="top" width="50%"><strong>Test Functions</strong>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Equal mean values
+  </td><td valign="top" width="50%"><code>anova</code>, <code>hotelling_test2</code>, <code>t_test_2</code>,
+       <code>welch_test</code>, <code>wilcoxon_test</code>, <code>z_test_2</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Equal medians
+  </td><td valign="top" width="50%"><code>kruskal_wallis_test</code>, <code>sign_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Equal variances
+  </td><td valign="top" width="50%"><code>bartlett_test</code>, <code>manova</code>, <code>var_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Equal distributions
+  </td><td valign="top" width="50%"><code>chisquare_test_homogeneity</code>, <code>kolmogorov_smirnov_test_2</code>,
+       <code>u_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Equal marginal frequencies
+  </td><td valign="top" width="50%"><code>mcnemar_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Equal success probabilities
+  </td><td valign="top" width="50%"><code>prop_test_2</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Independent observations
+  </td><td valign="top" width="50%"><code>chisquare_test_independence</code>, <code>run_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Uncorrelated observations
+  </td><td valign="top" width="50%"><code>cor_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Given mean value
+  </td><td valign="top" width="50%"><code>hotelling_test</code>, <code>t_test</code>, <code>z_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Observations from given distribution
+  </td><td valign="top" width="50%"><code>kolmogorov_smirnov_test</code>
+<br></td></tr><tr align="left"><td valign="top" width="40%">Regression
+  </td><td valign="top" width="50%"><code>f_test_regression</code>, <code>t_test_regression</code>
+   <br></td></tr></table>
+
+   <p>The tests return a p-value that describes the outcome of the test. 
+Assuming that the test hypothesis is true, the p-value is the probability
+of obtaining a worse result than the observed one.  So large p-values
+corresponds to a successful test.  Usually a test hypothesis is accepted
+if the p-value exceeds 0.05.
+
+<!-- ./statistics/tests/anova.m -->
+   <p><a name="doc_002danova"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>f</var>, <var>df_b</var>, <var>df_w</var>] = <b>anova</b> (<var>y, g</var>)<var><a name="index-anova-1865"></a></var><br>
+<blockquote><p>Perform a one-way analysis of variance (ANOVA).  The goal is to test
+whether the population means of data taken from <var>k</var> different
+groups are all equal.
+
+        <p>Data may be given in a single vector <var>y</var> with groups specified by
+a corresponding vector of group labels <var>g</var> (e.g., numbers from 1
+to <var>k</var>).  This is the general form which does not impose any
+restriction on the number of data in each group or the group labels.
+
+        <p>If <var>y</var> is a matrix and <var>g</var> is omitted, each column of <var>y</var>
+is treated as a group.  This form is only appropriate for balanced
+ANOVA in which the numbers of samples from each group are all equal.
+
+        <p>Under the null of constant means, the statistic <var>f</var> follows an F
+distribution with <var>df_b</var> and <var>df_w</var> degrees of freedom.
+
+        <p>The p-value (1 minus the CDF of this distribution at <var>f</var>) is
+returned in <var>pval</var>.
+
+        <p>If no output argument is given, the standard one-way ANOVA table is
+printed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/bartlett_test.m -->
+   <p><a name="doc_002dbartlett_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>chisq</var>, <var>df</var>] = <b>bartlett_test</b> (<var>x1, <small class="dots">...</small></var>)<var><a name="index-bartlett_005ftest-1866"></a></var><br>
+<blockquote><p>Perform a Bartlett test for the homogeneity of variances in the data
+vectors <var>x1</var>, <var>x2</var>, <small class="dots">...</small>, <var>xk</var>, where <var>k</var> > 1.
+
+        <p>Under the null of equal variances, the test statistic <var>chisq</var>
+approximately follows a chi-square distribution with <var>df</var> degrees of
+freedom.
+
+        <p>The p-value (1 minus the CDF of this distribution at <var>chisq</var>) is
+returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/chisquare_test_homogeneity.m -->
+   <p><a name="doc_002dchisquare_005ftest_005fhomogeneity"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>chisq</var>, <var>df</var>] = <b>chisquare_test_homogeneity</b> (<var>x, y, c</var>)<var><a name="index-chisquare_005ftest_005fhomogeneity-1867"></a></var><br>
+<blockquote><p>Given two samples <var>x</var> and <var>y</var>, perform a chisquare test for
+homogeneity of the null hypothesis that <var>x</var> and <var>y</var> come from
+the same distribution, based on the partition induced by the
+(strictly increasing) entries of <var>c</var>.
+
+        <p>For large samples, the test statistic <var>chisq</var> approximately follows a
+chisquare distribution with <var>df</var> = <code>length (</code><var>c</var><code>)</code>
+degrees of freedom.
+
+        <p>The p-value (1 minus the CDF of this distribution at <var>chisq</var>) is
+returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/chisquare_test_independence.m -->
+   <p><a name="doc_002dchisquare_005ftest_005findependence"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>chisq</var>, <var>df</var>] = <b>chisquare_test_independence</b> (<var>x</var>)<var><a name="index-chisquare_005ftest_005findependence-1868"></a></var><br>
+<blockquote><p>Perform a chi-square test for independence based on the contingency
+table <var>x</var>.  Under the null hypothesis of independence,
+<var>chisq</var> approximately has a chi-square distribution with
+<var>df</var> degrees of freedom.
+
+        <p>The p-value (1 minus the CDF of this distribution at chisq) of the
+test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/cor_test.m -->
+   <p><a name="doc_002dcor_005ftest"></a>
+
+<div class="defun">
+— Function File:  <b>cor_test</b> (<var>x, y, alt, method</var>)<var><a name="index-cor_005ftest-1869"></a></var><br>
+<blockquote><p>Test whether two samples <var>x</var> and <var>y</var> come from uncorrelated
+populations.
+
+        <p>The optional argument string <var>alt</var> describes the alternative
+hypothesis, and can be <code>"!="</code> or <code>"<>"</code> (non-zero),
+<code>">"</code> (greater than 0), or <code>"<"</code> (less than 0).  The
+default is the two-sided case.
+
+        <p>The optional argument string <var>method</var> specifies on which
+correlation coefficient the test should be based.  If <var>method</var> is
+<code>"pearson"</code> (default), the (usual) Pearson's product moment
+correlation coefficient is used.  In this case, the data should come
+from a bivariate normal distribution.  Otherwise, the other two
+methods offer nonparametric alternatives.  If <var>method</var> is
+<code>"kendall"</code>, then Kendall's rank correlation tau is used.  If
+<var>method</var> is <code>"spearman"</code>, then Spearman's rank correlation
+rho is used.  Only the first character is necessary.
+
+        <p>The output is a structure with the following elements:
+
+          <dl>
+<dt><var>pval</var><dd>The p-value of the test. 
+<br><dt><var>stat</var><dd>The value of the test statistic. 
+<br><dt><var>dist</var><dd>The distribution of the test statistic. 
+<br><dt><var>params</var><dd>The parameters of the null distribution of the test statistic. 
+<br><dt><var>alternative</var><dd>The alternative hypothesis. 
+<br><dt><var>method</var><dd>The method used for testing. 
+</dl>
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/f_test_regression.m -->
+   <p><a name="doc_002df_005ftest_005fregression"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>f</var>, <var>df_num</var>, <var>df_den</var>] = <b>f_test_regression</b> (<var>y, x, rr, r</var>)<var><a name="index-f_005ftest_005fregression-1870"></a></var><br>
+<blockquote><p>Perform an F test for the null hypothesis rr * b = r in a classical
+normal regression model y = X * b + e.
+
+        <p>Under the null, the test statistic <var>f</var> follows an F distribution
+with <var>df_num</var> and <var>df_den</var> degrees of freedom.
+
+        <p>The p-value (1 minus the CDF of this distribution at <var>f</var>) is
+returned in <var>pval</var>.
+
+        <p>If not given explicitly, <var>r</var> = 0.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/hotelling_test.m -->
+   <p><a name="doc_002dhotelling_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>tsq</var>] = <b>hotelling_test</b> (<var>x, m</var>)<var><a name="index-hotelling_005ftest-1871"></a></var><br>
+<blockquote><p>For a sample <var>x</var> from a multivariate normal distribution with unknown
+mean and covariance matrix, test the null hypothesis that <code>mean
+(</code><var>x</var><code>) == </code><var>m</var>.
+
+        <p>Hotelling's T^2 is returned in <var>tsq</var>.  Under the null,
+(n-p) T^2 / (p(n-1)) has an F distribution with p and
+n-p degrees of freedom, where n and p are the
+numbers of samples and variables, respectively.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/hotelling_test_2.m -->
+   <p><a name="doc_002dhotelling_005ftest_005f2"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>tsq</var>] = <b>hotelling_test_2</b> (<var>x, y</var>)<var><a name="index-hotelling_005ftest_005f2-1872"></a></var><br>
+<blockquote><p>For two samples <var>x</var> from multivariate normal distributions with
+the same number of variables (columns), unknown means and unknown
+equal covariance matrices, test the null hypothesis <code>mean
+(</code><var>x</var><code>) == mean (</code><var>y</var><code>)</code>.
+
+        <p>Hotelling's two-sample T^2 is returned in <var>tsq</var>.  Under the null,
+
+     <pre class="example">          (n_x+n_y-p-1) T^2 / (p(n_x+n_y-2))
+</pre>
+        <p class="noindent">has an F distribution with p and n_x+n_y-p-1 degrees of
+freedom, where n_x and n_y are the sample sizes and
+p is the number of variables.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/kolmogorov_smirnov_test.m -->
+   <p><a name="doc_002dkolmogorov_005fsmirnov_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>ks</var>] = <b>kolmogorov_smirnov_test</b> (<var>x, dist, params, alt</var>)<var><a name="index-kolmogorov_005fsmirnov_005ftest-1873"></a></var><br>
+<blockquote><p>Perform a Kolmogorov-Smirnov test of the null hypothesis that the
+sample <var>x</var> comes from the (continuous) distribution dist.  I.e.,
+if F and G are the CDFs corresponding to the sample and dist,
+respectively, then the null is that F == G.
+
+        <p>The optional argument <var>params</var> contains a list of parameters of
+<var>dist</var>.  For example, to test whether a sample <var>x</var> comes from
+a uniform distribution on [2,4], use
+
+     <pre class="example">          kolmogorov_smirnov_test(x, "uniform", 2, 4)
+</pre>
+        <p class="noindent"><var>dist</var> can be any string for which a function <var>dist_cdf</var>
+that calculates the CDF of distribution <var>dist</var> exists.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative F
+!= G.  In this case, the test statistic <var>ks</var> follows a two-sided
+Kolmogorov-Smirnov distribution.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative F > G is considered.  Similarly for <code>"<"</code>,
+the one-sided alternative F > G is considered.  In this case, the
+test statistic <var>ks</var> has a one-sided Kolmogorov-Smirnov
+distribution.  The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/kolmogorov_smirnov_test_2.m -->
+   <p><a name="doc_002dkolmogorov_005fsmirnov_005ftest_005f2"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>ks</var>, <var>d</var>] = <b>kolmogorov_smirnov_test_2</b> (<var>x, y, alt</var>)<var><a name="index-kolmogorov_005fsmirnov_005ftest_005f2-1874"></a></var><br>
+<blockquote><p>Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis
+that the samples <var>x</var> and <var>y</var> come from the same (continuous)
+distribution.  I.e., if F and G are the CDFs corresponding to the
+<var>x</var> and <var>y</var> samples, respectively, then the null is that F ==
+G.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative F
+!= G.  In this case, the test statistic <var>ks</var> follows a two-sided
+Kolmogorov-Smirnov distribution.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative F > G is considered.  Similarly for <code>"<"</code>,
+the one-sided alternative F < G is considered.  In this case, the
+test statistic <var>ks</var> has a one-sided Kolmogorov-Smirnov
+distribution.  The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>The third returned value, <var>d</var>, is the test statistic, the maximum
+vertical distance between the two cumulative distribution functions.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/kruskal_wallis_test.m -->
+   <p><a name="doc_002dkruskal_005fwallis_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>k</var>, <var>df</var>] = <b>kruskal_wallis_test</b> (<var>x1, <small class="dots">...</small></var>)<var><a name="index-kruskal_005fwallis_005ftest-1875"></a></var><br>
+<blockquote><p>Perform a Kruskal-Wallis one-factor "analysis of variance".
+
+        <p>Suppose a variable is observed for <var>k</var> > 1 different groups, and
+let <var>x1</var>, <small class="dots">...</small>, <var>xk</var> be the corresponding data vectors.
+
+        <p>Under the null hypothesis that the ranks in the pooled sample are not
+affected by the group memberships, the test statistic <var>k</var> is
+approximately chi-square with <var>df</var> = <var>k</var> - 1 degrees of
+freedom.
+
+        <p>If the data contains ties (some value appears more than once)
+<var>k</var> is divided by
+
+        <p>1 - <var>sum_ties</var> / (<var>n</var>^3 - <var>n</var>)
+
+        <p>where <var>sum_ties</var> is the sum of <var>t</var>^2 - <var>t</var> over each group
+of ties where <var>t</var> is the number of ties in the group and <var>n</var>
+is the total number of values in the input data.  For more info on
+this adjustment see "Use of Ranks in One-Criterion Variance Analysis"
+in Journal of the American Statistical Association, Vol. 47,
+No. 260 (Dec 1952) by William H. Kruskal and W. Allen Wallis.
+
+        <p>The p-value (1 minus the CDF of this distribution at <var>k</var>) is
+returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/manova.m -->
+   <p><a name="doc_002dmanova"></a>
+
+<div class="defun">
+— Function File:  <b>manova</b> (<var>y, g</var>)<var><a name="index-manova-1876"></a></var><br>
+<blockquote><p>Perform a one-way multivariate analysis of variance (MANOVA).  The
+goal is to test whether the p-dimensional population means of data
+taken from <var>k</var> different groups are all equal.  All data are
+assumed drawn independently from p-dimensional normal distributions
+with the same covariance matrix.
+
+        <p>The data matrix is given by <var>y</var>.  As usual, rows are observations
+and columns are variables.  The vector <var>g</var> specifies the
+corresponding group labels (e.g., numbers from 1 to <var>k</var>).
+
+        <p>The LR test statistic (Wilks' Lambda) and approximate p-values are
+computed and displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/mcnemar_test.m -->
+   <p><a name="doc_002dmcnemar_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>chisq</var>, <var>df</var>] = <b>mcnemar_test</b> (<var>x</var>)<var><a name="index-mcnemar_005ftest-1877"></a></var><br>
+<blockquote><p>For a square contingency table <var>x</var> of data cross-classified on
+the row and column variables, McNemar's test can be used for testing
+the null hypothesis of symmetry of the classification probabilities.
+
+        <p>Under the null, <var>chisq</var> is approximately distributed as chisquare
+with <var>df</var> degrees of freedom.
+
+        <p>The p-value (1 minus the CDF of this distribution at <var>chisq</var>) is
+returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/prop_test_2.m -->
+   <p><a name="doc_002dprop_005ftest_005f2"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>z</var>] = <b>prop_test_2</b> (<var>x1, n1, x2, n2, alt</var>)<var><a name="index-prop_005ftest_005f2-1878"></a></var><br>
+<blockquote><p>If <var>x1</var> and <var>n1</var> are the counts of successes and trials in
+one sample, and <var>x2</var> and <var>n2</var> those in a second one, test the
+null hypothesis that the success probabilities <var>p1</var> and <var>p2</var>
+are the same.  Under the null, the test statistic <var>z</var>
+approximately follows a standard normal distribution.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<var>p1</var> != <var>p2</var>.  If <var>alt</var> is <code>">"</code>, the one-sided
+alternative <var>p1</var> > <var>p2</var> is used.  Similarly for <code>"<"</code>,
+the one-sided alternative <var>p1</var> < <var>p2</var> is used. 
+The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/run_test.m -->
+   <p><a name="doc_002drun_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>chisq</var>] = <b>run_test</b> (<var>x</var>)<var><a name="index-run_005ftest-1879"></a></var><br>
+<blockquote><p>Perform a chi-square test with 6 degrees of freedom based on the
+upward runs in the columns of <var>x</var>.  Can be used to test whether
+<var>x</var> contains independent data.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/sign_test.m -->
+   <p><a name="doc_002dsign_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>b</var>, <var>n</var>] = <b>sign_test</b> (<var>x, y, alt</var>)<var><a name="index-sign_005ftest-1880"></a></var><br>
+<blockquote><p>For two matched-pair samples <var>x</var> and <var>y</var>, perform a sign test
+of the null hypothesis PROB (<var>x</var> > <var>y</var>) == PROB (<var>x</var> <
+<var>y</var>) == 1/2.  Under the null, the test statistic <var>b</var> roughly
+follows a binomial distribution with parameters <var>n</var><code> = sum
+(</code><var>x</var><code> != </code><var>y</var><code>)</code> and <var>p</var> = 1/2.
+
+        <p>With the optional argument <code>alt</code>, the alternative of interest
+can be selected.  If <var>alt</var> is <code>"!="</code> or <code>"<>"</code>, the
+null hypothesis is tested against the two-sided alternative PROB
+(<var>x</var> < <var>y</var>) != 1/2.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative PROB (<var>x</var> > <var>y</var>) > 1/2 ("x is
+stochastically greater than y") is considered.  Similarly for
+<code>"<"</code>, the one-sided alternative PROB (<var>x</var> > <var>y</var>) < 1/2
+("x is stochastically less than y") is considered.  The default is
+the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/t_test.m -->
+   <p><a name="doc_002dt_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>t</var>, <var>df</var>] = <b>t_test</b> (<var>x, m, alt</var>)<var><a name="index-t_005ftest-1881"></a></var><br>
+<blockquote><p>For a sample <var>x</var> from a normal distribution with unknown mean and
+variance, perform a t-test of the null hypothesis <code>mean
+(</code><var>x</var><code>) == </code><var>m</var>.  Under the null, the test statistic <var>t</var>
+follows a Student distribution with <var>df</var><code> = length (</code><var>x</var><code>)
+- 1</code> degrees of freedom.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<code>mean (</code><var>x</var><code>) != </code><var>m</var>.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative <code>mean (</code><var>x</var><code>) > </code><var>m</var> is considered. 
+Similarly for <var>"<"</var>, the one-sided alternative <code>mean
+(</code><var>x</var><code>) < </code><var>m</var> is considered.  The default is the two-sided
+case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/t_test_2.m -->
+   <p><a name="doc_002dt_005ftest_005f2"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>t</var>, <var>df</var>] = <b>t_test_2</b> (<var>x, y, alt</var>)<var><a name="index-t_005ftest_005f2-1882"></a></var><br>
+<blockquote><p>For two samples x and y from normal distributions with unknown means
+and unknown equal variances, perform a two-sample t-test of the null
+hypothesis of equal means.  Under the null, the test statistic
+<var>t</var> follows a Student distribution with <var>df</var> degrees of
+freedom.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<code>mean (</code><var>x</var><code>) != mean (</code><var>y</var><code>)</code>.  If <var>alt</var> is <code>">"</code>,
+the one-sided alternative <code>mean (</code><var>x</var><code>) > mean (</code><var>y</var><code>)</code> is
+used.  Similarly for <code>"<"</code>, the one-sided alternative <code>mean
+(</code><var>x</var><code>) < mean (</code><var>y</var><code>)</code> is used.  The default is the two-sided
+case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/t_test_regression.m -->
+   <p><a name="doc_002dt_005ftest_005fregression"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>t</var>, <var>df</var>] = <b>t_test_regression</b> (<var>y, x, rr, r, alt</var>)<var><a name="index-t_005ftest_005fregression-1883"></a></var><br>
+<blockquote><p>Perform an t test for the null hypothesis <var>rr</var><code> * </code><var>b</var><code> =
+</code><var>r</var> in a classical normal regression model <var>y</var><code> =
+</code><var>x</var><code> * </code><var>b</var><code> + </code><var>e</var>.  Under the null, the test statistic <var>t</var>
+follows a <var>t</var> distribution with <var>df</var> degrees of freedom.
+
+        <p>If <var>r</var> is omitted, a value of 0 is assumed.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<var>rr</var><code> * </code><var>b</var><code> != </code><var>r</var>.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative <var>rr</var><code> * </code><var>b</var><code> > </code><var>r</var> is used. 
+Similarly for <var>"<"</var>, the one-sided alternative <var>rr</var><code> *
+</code><var>b</var><code> < </code><var>r</var> is used.  The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/u_test.m -->
+   <p><a name="doc_002du_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>z</var>] = <b>u_test</b> (<var>x, y, alt</var>)<var><a name="index-u_005ftest-1884"></a></var><br>
+<blockquote><p>For two samples <var>x</var> and <var>y</var>, perform a Mann-Whitney U-test of
+the null hypothesis PROB (<var>x</var> > <var>y</var>) == 1/2 == PROB (<var>x</var>
+< <var>y</var>).  Under the null, the test statistic <var>z</var> approximately
+follows a standard normal distribution.  Note that this test is
+equivalent to the Wilcoxon rank-sum test.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+PROB (<var>x</var> > <var>y</var>) != 1/2.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative PROB (<var>x</var> > <var>y</var>) > 1/2 is considered. 
+Similarly for <code>"<"</code>, the one-sided alternative PROB (<var>x</var> >
+<var>y</var>) < 1/2 is considered.  The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/var_test.m -->
+   <p><a name="doc_002dvar_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>f</var>, <var>df_num</var>, <var>df_den</var>] = <b>var_test</b> (<var>x, y, alt</var>)<var><a name="index-var_005ftest-1885"></a></var><br>
+<blockquote><p>For two samples <var>x</var> and <var>y</var> from normal distributions with
+unknown means and unknown variances, perform an F-test of the null
+hypothesis of equal variances.  Under the null, the test statistic
+<var>f</var> follows an F-distribution with <var>df_num</var> and <var>df_den</var>
+degrees of freedom.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<code>var (</code><var>x</var><code>) != var (</code><var>y</var><code>)</code>.  If <var>alt</var> is <code>">"</code>,
+the one-sided alternative <code>var (</code><var>x</var><code>) > var (</code><var>y</var><code>)</code> is
+used.  Similarly for "<", the one-sided alternative <code>var
+(</code><var>x</var><code>) > var (</code><var>y</var><code>)</code> is used.  The default is the two-sided
+case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/welch_test.m -->
+   <p><a name="doc_002dwelch_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>t</var>, <var>df</var>] = <b>welch_test</b> (<var>x, y, alt</var>)<var><a name="index-welch_005ftest-1886"></a></var><br>
+<blockquote><p>For two samples <var>x</var> and <var>y</var> from normal distributions with
+unknown means and unknown and not necessarily equal variances,
+perform a Welch test of the null hypothesis of equal means. 
+Under the null, the test statistic <var>t</var> approximately follows a
+Student distribution with <var>df</var> degrees of freedom.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<code>mean (</code><var>x</var><code>) != </code><var>m</var>.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative mean(x) > <var>m</var> is considered.  Similarly for
+<code>"<"</code>, the one-sided alternative mean(x) < <var>m</var> is
+considered.  The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/wilcoxon_test.m -->
+   <p><a name="doc_002dwilcoxon_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>z</var>] = <b>wilcoxon_test</b> (<var>x, y, alt</var>)<var><a name="index-wilcoxon_005ftest-1887"></a></var><br>
+<blockquote><p>For two matched-pair sample vectors <var>x</var> and <var>y</var>, perform a
+Wilcoxon signed-rank test of the null hypothesis PROB (<var>x</var> >
+<var>y</var>) == 1/2.  Under the null, the test statistic <var>z</var>
+approximately follows a standard normal distribution when <var>n</var> > 25.
+
+        <p><strong>Warning</strong>: This function assumes a normal distribution for <var>z</var>
+and thus is invalid for <var>n</var> <= 25.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+PROB (<var>x</var> > <var>y</var>) != 1/2.  If alt is <code>">"</code>, the one-sided
+alternative PROB (<var>x</var> > <var>y</var>) > 1/2 is considered.  Similarly
+for <code>"<"</code>, the one-sided alternative PROB (<var>x</var> > <var>y</var>) <
+1/2 is considered.  The default is the two-sided case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/z_test.m -->
+   <p><a name="doc_002dz_005ftest"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>z</var>] = <b>z_test</b> (<var>x, m, v, alt</var>)<var><a name="index-z_005ftest-1888"></a></var><br>
+<blockquote><p>Perform a Z-test of the null hypothesis <code>mean (</code><var>x</var><code>) ==
+</code><var>m</var> for a sample <var>x</var> from a normal distribution with unknown
+mean and known variance <var>v</var>.  Under the null, the test statistic
+<var>z</var> follows a standard normal distribution.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<code>mean (</code><var>x</var><code>) != </code><var>m</var>.  If <var>alt</var> is <code>">"</code>, the
+one-sided alternative <code>mean (</code><var>x</var><code>) > </code><var>m</var> is considered. 
+Similarly for <code>"<"</code>, the one-sided alternative <code>mean
+(</code><var>x</var><code>) < </code><var>m</var> is considered.  The default is the two-sided
+case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed
+along with some information. 
+</p></blockquote></div>
+
+<!-- ./statistics/tests/z_test_2.m -->
+   <p><a name="doc_002dz_005ftest_005f2"></a>
+
+<div class="defun">
+— Function File: [<var>pval</var>, <var>z</var>] = <b>z_test_2</b> (<var>x, y, v_x, v_y, alt</var>)<var><a name="index-z_005ftest_005f2-1889"></a></var><br>
+<blockquote><p>For two samples <var>x</var> and <var>y</var> from normal distributions with
+unknown means and known variances <var>v_x</var> and <var>v_y</var>, perform a
+Z-test of the hypothesis of equal means.  Under the null, the test
+statistic <var>z</var> follows a standard normal distribution.
+
+        <p>With the optional argument string <var>alt</var>, the alternative of
+interest can be selected.  If <var>alt</var> is <code>"!="</code> or
+<code>"<>"</code>, the null is tested against the two-sided alternative
+<code>mean (</code><var>x</var><code>) != mean (</code><var>y</var><code>)</code>.  If alt is <code>">"</code>, the
+one-sided alternative <code>mean (</code><var>x</var><code>) > mean (</code><var>y</var><code>)</code> is used. 
+Similarly for <code>"<"</code>, the one-sided alternative <code>mean
+(</code><var>x</var><code>) < mean (</code><var>y</var><code>)</code> is used.  The default is the two-sided
+case.
+
+        <p>The p-value of the test is returned in <var>pval</var>.
+
+        <p>If no output argument is given, the p-value of the test is displayed
+along with some information. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Text-Properties.html b/doc/interpreter/HTML/Text-Properties.html
new file mode 100644
index 0000000..3ed24f4
--- /dev/null
+++ b/doc/interpreter/HTML/Text-Properties.html
@@ -0,0 +1,163 @@
+<html lang="en">
+<head>
+<title>Text Properties - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Graphics-Object-Properties.html#Graphics-Object-Properties" title="Graphics Object Properties">
+<link rel="prev" href="Line-Properties.html#Line-Properties" title="Line Properties">
+<link rel="next" href="Image-Properties.html#Image-Properties" title="Image Properties">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Text-Properties"></a>
+Next: <a rel="next" accesskey="n" href="Image-Properties.html#Image-Properties">Image Properties</a>,
+Previous: <a rel="previous" accesskey="p" href="Line-Properties.html#Line-Properties">Line Properties</a>,
+Up: <a rel="up" accesskey="u" href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.2.2.5 Text Properties</h5>
+
+<p><a name="index-text-properties-1193"></a>
+     <dl>
+<dt><code>string</code><dd>The character string contained by the text object.
+
+     <br><dt><code>units</code><dd>May be <code>"normalized"</code> or <code>"graph"</code>.
+
+     <br><dt><code>position</code><dd>The coordinates of the text object.
+
+     <br><dt><code>rotation</code><dd>The angle of rotation for the displayed text, measured in degrees.
+
+     <br><dt><code>horizontalalignment</code><dd>May be <code>"left"</code>, <code>"center"</code>, or <code>"right"</code>.
+
+     <br><dt><code>color</code><dd>The color of the text.  See <a href="Colors.html#Colors">Colors</a>.
+
+     <br><dt><code>fontname</code><dd>The font used for the text.
+
+     <br><dt><code>fontsize</code><dd>The size of the font, in points to use.
+
+     <br><dt><code>fontangle</code><dd>Flag whether the font is italic or normal.  Valid values are 'normal',
+'italic' and 'oblique'.
+
+     <br><dt><code>fontweight</code><dd>Flag whether the font is bold, etc.  Valid values are 'normal', 'bold',
+'demi' or 'light'.
+
+     <br><dt><code>interpreter</code><dd>Determines how the text is rendered.  Valid values are 'none', 'tex' or
+'latex'. 
+</dl>
+
+   <p>All text objects, including titles, labels, legends, and text, include
+the property 'interpreter', this property determines the manner in which
+special control sequences in the text are rendered.  If the interpreter
+is set to 'none', then no rendering occurs.  At this point the 'latex'
+option is not implemented and so the 'latex' interpreter also does not
+interpret the text.
+
+   <p>The 'tex' option implements a subset of <span class="sc">TeX</span> functionality in the
+rendering of the text.  This allows the insertion of special characters
+such as Greek or mathematical symbols within the text.  The special
+characters are also inserted with a code starting with the back-slash
+(\) character, as in the table <a href="tab_003aextended.html#tab_003aextended">tab:extended</a>.
+
+   <p>In addition, the formatting of the text can be changed within the string
+with the codes
+
+   <p><table summary=""><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="20%">\bf </td><td valign="top" width="60%">Bold font </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="20%">\it </td><td valign="top" width="60%">Italic font </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="20%">\sl </td><td valign="top" width="60%">Oblique Font </td><td valign="top" width="20%">
+<br></td></tr><tr align="left"><td valign="top" width="20%"></td><td valign="top" width="20%">\rm </td><td valign="top" width="60%">Normal font </td><td valign="top" width="20%">
+   <br></td></tr></table>
+
+   <p>These are be used in conjunction with the { and } characters to limit
+the change in the font to part of the string.  For example
+
+<pre class="example">     xlabel ('{\bf H} = a {\bf V}')
+</pre>
+   <p>where the character 'a' will not appear in a bold font.  Note that to
+avoid having Octave interpret the backslash characters in the strings,
+the strings should be in single quotes.
+
+   <p>It is also possible to change the fontname and size within the text
+
+   <p><table summary=""><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="40%">\fontname{<var>fontname</var>} </td><td valign="top" width="60%">Specify the font to use </td><td valign="top" width="10%">
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="40%">\fontsize{<var>size</var>} </td><td valign="top" width="60%">Specify the size of the font to
+use </td><td valign="top" width="10%">
+   <br></td></tr></table>
+
+   <p>Finally, the superscript and subscripting can be controlled with the '^'
+and '_' characters.  If the '^' or '_' is followed by a { character,
+then all of the block surrounded by the { } pair is super- or
+sub-scripted.  Without the { } pair, only the character immediately
+following the '^' or '_' is super- or sub-scripted.
+
+   <div class="float">
+<a name="tab_003aextended"></a>
+   <p><table summary=""><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\forall     </td><td valign="top" width="25%">\exists     </td><td valign="top" width="25%">\ni      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\cong       </td><td valign="top" width="25%">\Delta      </td><td valign="top" width="25%">\Phi     </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\Gamma      </td><td valign="top" width="25%">\vartheta   </td><td valign="top" width="25%">\Lambda  </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\Pi         </td><td valign="top" width="25%">\Theta      </td><td valign="top" width="25%">\Sigma   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\varsigma   </td><td valign="top" width="25%">\Omega      </td><td valign="top" width="25%">\Xi      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\Psi        </td><td valign="top" width="25%">\perp       </td><td valign="top" width="25%">\alpha   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\beta       </td><td valign="top" width="25%">\chi        </td><td valign="top" width="25%">\delta   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\epsilon    </td><td valign="top" width="25%">\phi        </td><td valign="top" width="25%">\gamma   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\eta        </td><td valign="top" width="25%">\iota       </td><td valign="top" width="25%">\varphi  </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\kappa      </td><td valign="top" width="25%">\lambda     </td><td valign="top" width="25%">\mu      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\nu         </td><td valign="top" width="25%">\o          </td><td valign="top" width="25%">\pi      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\theta      </td><td valign="top" width="25%">\rho        </td><td valign="top" width="25%">\sigma   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\tau        </td><td valign="top" width="25%">\upsilon    </td><td valign="top" width="25%">\varpi   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\omega      </td><td valign="top" width="25%">\xi         </td><td valign="top" width="25%">\psi     </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\zeta       </td><td valign="top" width="25%">\sim        </td><td valign="top" width="25%">\Upsilon </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\prime      </td><td valign="top" width="25%">\leq        </td><td valign="top" width="25%">\infty   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\clubsuit   </td><td valign="top" width="25%">\diamondsuit    </td><td valign="top" width="25%">\heartsuit  </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\spadesuit  </td><td valign="top" width="25%">\leftrightarrow </td><td valign="top" width="25%">\leftarrow  </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\uparrow    </td><td valign="top" width="25%">\rightarrow </td><td valign="top" width="25%">\downarrow </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\circ       </td><td valign="top" width="25%">\pm          </td><td valign="top" width="25%">\geq     </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\times      </td><td valign="top" width="25%">\propto     </td><td valign="top" width="25%">\partial </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\bullet     </td><td valign="top" width="25%">\div         </td><td valign="top" width="25%">\neq     </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\equiv      </td><td valign="top" width="25%">\approx     </td><td valign="top" width="25%">\ldots   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\mid        </td><td valign="top" width="25%">\aleph      </td><td valign="top" width="25%">\Im      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\Re         </td><td valign="top" width="25%">\wp          </td><td valign="top" width="25%">\otimes  </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\oplus      </td><td valign="top" width="25%">\oslash      </td><td valign="top" width="25%">\cap     </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\cup        </td><td valign="top" width="25%">\supset    </td><td valign="top" width="25%">\supseteq </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\subset     </td><td valign="top" width="25%">\subseteq    </td><td valign="top" width="25%">\in      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\notin      </td><td valign="top" width="25%">\angle       </td><td valign="top" width="25%">\bigrightriangledown </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\langle     </td><td valign="top" width="25%">\rangle     </td><td valign="top" width="25%">\nabla   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\prod       </td><td valign="top" width="25%">\surd        </td><td valign="top" width="25%">\cdot    </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\neg        </td><td valign="top" width="25%">\wedge      </td><td valign="top" width="25%">\vee      </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\Leftrightarrow </td><td valign="top" width="25%">\Leftarrow </td><td valign="top" width="25%">\Uparrow </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\Rightarrow </td><td valign="top" width="25%">\Downarrow   </td><td valign="top" width="25%">\diamond  </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\copyright  </td><td valign="top" width="25%">\lfloor     </td><td valign="top" width="25%">\lceil   </td><td valign="top" width="13%">
+<br></td></tr><tr align="left"><td valign="top" width="13%"></td><td valign="top" width="25%">\rfloor     </td><td valign="top" width="25%">\rceil      </td><td valign="top" width="25%">\int     </td><td valign="top" width="13%">
+   <br></td></tr></table>
+
+   <p><strong class="float-caption">Table 15.1: Available special characters in <span class="sc">TeX</span> mode</strong></p></div>
+
+   <p>A complete example showing the capabilities of the extended text is
+
+<pre class="example">     x = 0:0.01:3;
+     plot(x,erf(x));
+     hold on;
+     plot(x,x,"r");
+     axis([0, 3, 0, 1]);
+     text(0.65, 0.6175, strcat('\leftarrow x = {2/\surd\pi',
+     ' {\fontsize{16}\int_{\fontsize{8}0}^{\fontsize{8}x}}',
+     ' e^{-t^2} dt} = 0.6175'))
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-DESCRIPTION-File.html b/doc/interpreter/HTML/The-DESCRIPTION-File.html
new file mode 100644
index 0000000..6322e0b
--- /dev/null
+++ b/doc/interpreter/HTML/The-DESCRIPTION-File.html
@@ -0,0 +1,139 @@
+<html lang="en">
+<head>
+<title>The DESCRIPTION File - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Creating-Packages.html#Creating-Packages" title="Creating Packages">
+<link rel="next" href="The-INDEX-file.html#The-INDEX-file" title="The INDEX file">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-DESCRIPTION-File"></a>
+Next: <a rel="next" accesskey="n" href="The-INDEX-file.html#The-INDEX-file">The INDEX file</a>,
+Up: <a rel="up" accesskey="u" href="Creating-Packages.html#Creating-Packages">Creating Packages</a>
+<hr>
+</div>
+
+<h4 class="subsection">35.4.1 The DESCRIPTION File</h4>
+
+<p>The <code>DESCRIPTION</code> file contains various information about the
+package, such as its name, author, and version.  This file has a very
+simple format
+
+<p class="noindent">
+     <ul>
+<li>Lines starting with ‘<samp><span class="samp">#</span></samp>’ are comments.
+
+     <li>Lines starting with a blank character are continuations from the
+previous line.
+
+     <li>Everything else is of the form <code>NameOfOption: ValueOfOption</code>. 
+</ul>
+
+<p class="noindent">The following is a simple example of a <code>DESCRIPTION</code> file
+
+<pre class="example">     Name: The name of my package
+     Version: 1.0.0
+     Date: 2007-18-04
+     Author: The name (and possibly email) of the package author.
+     Maintainer: The name (and possibly email) of the current
+      package maintainer.
+     Title: The title of the package
+     Description: A short description of the package.  If this
+      description gets too long for one line it can continue
+      on the next by adding a space to the beginning of the
+      following lines.
+     License: GPL version 3 or later
+</pre>
+   <p>The package manager currently recognizes the following keywords
+
+<p class="noindent">
+     <dl>
+<dt><code>Name</code><dd>Name of the package.
+
+     <br><dt><code>Version</code><dd>Version of the package.
+
+     <br><dt><code>Date</code><dd>Date of last update.
+
+     <br><dt><code>Author</code><dd>Original author of the package.
+
+     <br><dt><code>Maintainer</code><dd>Maintainer of the package.
+
+     <br><dt><code>Title</code><dd>A one line description of the package.
+
+     <br><dt><code>Description</code><dd>A one paragraph description of the package.
+
+     <br><dt><code>Categories</code><dd>Optional keyword describing the package (if no <code>INDEX</code> file is
+given this is mandatory).
+
+     <br><dt><code>Problems</code><dd>Optional list of known problems.
+
+     <br><dt><code>Url</code><dd>Optional list of homepages related to the package.
+
+     <br><dt><code>Autoload</code><dd>Optional field that sets the default loading behavior for the package. 
+If set to <code>yes</code>, <code>true</code> or <code>on</code>, then Octave will
+automatically load the package when starting.  Otherwise the package
+must be manually loaded with the pkg load command.  This default
+behavior can be overridden when the package is installed.
+
+     <br><dt><code>Depends</code><dd>A list of other Octave packages that this package depends on.  This can
+include dependencies on particular versions, with a format
+
+     <pre class="example">          Depends: package (>= 1.0.0)
+</pre>
+     <p class="noindent">Possible operators are <code><</code>, <code><=</code>, <code>==</code>, <code>>=</code> or
+<code>></code>.  If the part of the dependency in <code>()</code> is missing, any
+version of the package is acceptable.  Multiple dependencies can be
+defined either as a comma separated list or on separate <code>Depends</code>
+lines.
+
+     <br><dt><code>License</code><dd>An optional short description of the used license (e.g., GPL version 3
+or newer).  This is optional since the file <code>COPYING</code> is mandatory.
+
+     <br><dt><code>SystemRequirements</code><dd>These are the external install dependencies of the package and are not
+checked by the package manager.  This is here as a hint to the
+distribution packager.  They follow the same conventions as the
+<code>Depends</code> keyword.
+
+     <br><dt><code>BuildRequires</code><dd>These are the external build dependencies of the package and are not
+checked by the package manager.  This is here as a hint to the
+distribution packager.  They follow the same conventions as the
+<code>Depends</code> keyword.  Note that in general, packaging systems such
+as <code>rpm</code> or <code>deb</code> and autoprobe the install dependencies
+from the build dependencies, and therefore the often a
+<code>BuildRequires</code> dependency removes the need for a
+<code>SystemRequirements</code> dependency.
+
+   </dl>
+
+<p class="noindent">The developer is free to add additional arguments to the
+<code>DESCRIPTION</code> file for their own purposes.  One further detail to
+aid the packager is that the <code>SystemRequirements</code> and
+<code>BuildRequires</code> keywords can have a distribution dependent section,
+and the automatic build process will use these.  An example of the
+format of this is
+
+<pre class="example">     BuildRequires: libtermcap-devel [Mandriva] libtermcap2-devel
+</pre>
+   <p class="noindent">where the first package name will be used as a default and if the
+RPMs are built on a Mandriva distribution, then the second package
+name will be used instead.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-INDEX-file.html b/doc/interpreter/HTML/The-INDEX-file.html
new file mode 100644
index 0000000..356e827
--- /dev/null
+++ b/doc/interpreter/HTML/The-INDEX-file.html
@@ -0,0 +1,106 @@
+<html lang="en">
+<head>
+<title>The INDEX file - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Creating-Packages.html#Creating-Packages" title="Creating Packages">
+<link rel="prev" href="The-DESCRIPTION-File.html#The-DESCRIPTION-File" title="The DESCRIPTION File">
+<link rel="next" href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives" title="PKG_ADD and PKG_DEL directives">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-INDEX-file"></a>
+Next: <a rel="next" accesskey="n" href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives">PKG_ADD and PKG_DEL directives</a>,
+Previous: <a rel="previous" accesskey="p" href="The-DESCRIPTION-File.html#The-DESCRIPTION-File">The DESCRIPTION File</a>,
+Up: <a rel="up" accesskey="u" href="Creating-Packages.html#Creating-Packages">Creating Packages</a>
+<hr>
+</div>
+
+<h4 class="subsection">35.4.2 The INDEX file</h4>
+
+<p>The optional <code>INDEX</code> file provides a categorical view of the
+functions in the package.  This file has a very simple format
+
+<p class="noindent">
+     <ul>
+<li>Lines beginning with ‘<samp><span class="samp">#</span></samp>’ are comments.
+
+     <li>The first non-comment line should look like this
+
+     <pre class="example">          toolbox >> Toolbox name
+</pre>
+     <li>Lines beginning with an alphabetical character indicates a new
+category of functions.
+
+     <li>Lines starting with a white space character indicate that the
+function names on the line belong to the last mentioned category. 
+</ul>
+
+<p class="noindent">The format can be summarized with the following example
+
+<pre class="example">     # A comment
+     toolbox >> Toolbox name
+     Category Name 1
+      function1 function2 function3
+      function4
+     Category Name 2
+      function2 function5
+</pre>
+   <p>If you wish to refer to a function that users might expect
+to find in your package but is not there, providing a work around or
+pointing out that the function is available elsewhere, you can use:
+
+<pre class="example">     fn = workaround description
+</pre>
+   <p class="noindent">This workaround description will not appear when listing functions in the
+package with <code>pkg describe</code> but they will be published
+in the html documentation online. 
+Workaround descriptions can use any html markup, but
+keep in mind that it will be enclosed in a bold-italic environment. 
+For the special case of:
+
+<pre class="example">     fn = use <code>alternate expression</code>
+</pre>
+   <p class="noindent">the bold-italic is automatically suppressed.  You will need
+to use <code><code></code> even in references:
+
+<pre class="example">     fn = use <a href="someothersite.html"><code>fn</code></a>
+</pre>
+   <p class="noindent">Sometimes functions are only partially compatible, in which
+case you can list the non-compatible cases separately.  To
+refer to another function in the package, use <code><f>fn</f></code>. 
+For example,
+
+<pre class="example">     eig (a, b) = use <f>qz</f>
+</pre>
+   <p class="noindent">Since sites may have many missing functions, you can define
+a macro rather than typing the same link over and again.
+
+<pre class="example">     $id = expansion
+</pre>
+   <p class="noindent">defines the macro id.  You can use <code>$id</code> anywhere in the
+description and it will be expanded.  For example,
+
+<pre class="example">     $TSA = see <a href="link_to_spctools">SPC Tools</a>
+     arcov = $TSA <code>armcv</code>
+</pre>
+   <p class="noindent">id is any string of letters, numbers and <code>_</code>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..8dc9667
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html
@@ -0,0 +1,83 @@
+<html lang="en">
+<head>
+<title>The @code{break} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bfor_007d-Statement.html#The-_0040code_007bfor_007d-Statement" title="The @code{for} Statement">
+<link rel="next" href="The-_0040code_007bcontinue_007d-Statement.html#The-_0040code_007bcontinue_007d-Statement" title="The @code{continue} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3ebreak%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003ebreak_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#The-_003ccode_003econtinue_003c_002fcode_003e-Statement">The <code>continue</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.6 The <code>break</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bbreak_007d-statement-573"></a>
+The <code>break</code> statement jumps out of the innermost <code>for</code> or
+<code>while</code> loop that encloses it.  The <code>break</code> statement may only
+be used within the body of a loop.  The following example finds the
+smallest divisor of a given integer, and also identifies prime numbers:
+
+<pre class="example">     num = 103;
+     div = 2;
+     while (div*div <= num)
+       if (rem (num, div) == 0)
+         break;
+       endif
+       div++;
+     endwhile
+     if (rem (num, div) == 0)
+       printf ("Smallest divisor of %d is %d\n", num, div)
+     else
+       printf ("%d is prime\n", num);
+     endif
+</pre>
+   <p>When the remainder is zero in the first <code>while</code> statement, Octave
+immediately <dfn>breaks out</dfn> of the loop.  This means that Octave
+proceeds immediately to the statement following the loop and continues
+processing.  (This is very different from the <code>exit</code> statement
+which stops the entire Octave program.)
+
+   <p>Here is another program equivalent to the previous one.  It illustrates
+how the <var>condition</var> of a <code>while</code> statement could just as well
+be replaced with a <code>break</code> inside an <code>if</code>:
+
+<pre class="example">     num = 103;
+     div = 2;
+     while (1)
+       if (rem (num, div) == 0)
+         printf ("Smallest divisor of %d is %d\n", num, div);
+         break;
+       endif
+       div++;
+       if (div*div > num)
+         printf ("%d is prime\n", num);
+         break;
+       endif
+     endwhile
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..5c4b73f
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html
@@ -0,0 +1,77 @@
+<html lang="en">
+<head>
+<title>The @code{continue} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bbreak_007d-Statement.html#The-_0040code_007bbreak_007d-Statement" title="The @code{break} Statement">
+<link rel="next" href="The-_0040code_007bunwind_005fprotect_007d-Statement.html#The-_0040code_007bunwind_005fprotect_007d-Statement" title="The @code{unwind_protect} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3econtinue%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003econtinue_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#The-_003ccode_003ebreak_003c_002fcode_003e-Statement">The <code>break</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.7 The <code>continue</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bcontinue_007d-statement-574"></a>
+The <code>continue</code> statement, like <code>break</code>, is used only inside
+<code>for</code> or <code>while</code> loops.  It skips over the rest of the loop
+body, causing the next cycle around the loop to begin immediately. 
+Contrast this with <code>break</code>, which jumps out of the loop altogether. 
+Here is an example:
+
+<pre class="example">     # print elements of a vector of random
+     # integers that are even.
+     
+     # first, create a row vector of 10 random
+     # integers with values between 0 and 100:
+     
+     vec = round (rand (1, 10) * 100);
+     
+     # print what we're interested in:
+     
+     for x = vec
+       if (rem (x, 2) != 0)
+         continue;
+       endif
+       printf ("%d\n", x);
+     endfor
+</pre>
+   <p>If one of the elements of <var>vec</var> is an odd number, this example skips
+the print statement for that element, and continues back to the first
+statement in the loop.
+
+   <p>This is not a practical example of the <code>continue</code> statement, but it
+should give you a clear understanding of how it works.  Normally, one
+would probably write the loop like this:
+
+<pre class="example">     for x = vec
+       if (rem (x, 2) == 0)
+         printf ("%d\n", x);
+       endif
+     endfor
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..c7c489f
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html
@@ -0,0 +1,74 @@
+<html lang="en">
+<head>
+<title>The @code{do-until} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bwhile_007d-Statement.html#The-_0040code_007bwhile_007d-Statement" title="The @code{while} Statement">
+<link rel="next" href="The-_0040code_007bfor_007d-Statement.html#The-_0040code_007bfor_007d-Statement" title="The @code{for} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3edo-until%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.4 The <code>do-until</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bdo_002duntil_007d-statement-568"></a>
+The <code>do-until</code> statement is similar to the <code>while</code> statement,
+except that it repeatedly executes a statement until a condition becomes
+true, and the test of the condition is at the end of the loop, so the
+body of the loop is always executed at least once.  As with the
+condition in an <code>if</code> statement, the condition in a <code>do-until</code>
+statement is considered true if its value is non-zero, and false if its
+value is zero.  If the value of the conditional expression in a
+<code>do-until</code> statement is a vector or a matrix, it is considered
+true only if it is non-empty and <em>all</em> of the elements are non-zero.
+
+   <p>Octave's <code>do-until</code> statement looks like this:
+
+<pre class="example">     do
+       <var>body</var>
+     until (<var>condition</var>)
+</pre>
+   <p class="noindent">Here <var>body</var> is a statement or list of statements that we call the
+<dfn>body</dfn> of the loop, and <var>condition</var> is an expression that
+controls how long the loop keeps running.
+
+   <p>This example creates a variable <code>fib</code> that contains the first ten
+elements of the Fibonacci sequence.
+
+<pre class="example">     fib = ones (1, 10);
+     i = 2;
+     do
+       i++;
+       fib (i) = fib (i-1) + fib (i-2);
+     until (i == 10)
+</pre>
+   <p>A newline is not required between the <code>do</code> keyword and the
+body; but using one makes the program clearer unless the body is very
+simple.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003efor_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003efor_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..d36ffcd
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003efor_003c_002fcode_003e-Statement.html
@@ -0,0 +1,118 @@
+<html lang="en">
+<head>
+<title>The @code{for} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bdo_002duntil_007d-Statement.html#The-_0040code_007bdo_002duntil_007d-Statement" title="The @code{do-until} Statement">
+<link rel="next" href="The-_0040code_007bbreak_007d-Statement.html#The-_0040code_007bbreak_007d-Statement" title="The @code{break} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3efor%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003efor_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#The-_003ccode_003ebreak_003c_002fcode_003e-Statement">The <code>break</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement">The <code>do-until</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.5 The <code>for</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bfor_007d-statement-569"></a><a name="index-g_t_0040code_007bendfor_007d-statement-570"></a>
+The <code>for</code> statement makes it more convenient to count iterations of a
+loop.  The general form of the <code>for</code> statement looks like this:
+
+<pre class="example">     for <var>var</var> = <var>expression</var>
+       <var>body</var>
+     endfor
+</pre>
+   <p class="noindent">where <var>body</var> stands for any statement or list of statements,
+<var>expression</var> is any valid expression, and <var>var</var> may take several
+forms.  Usually it is a simple variable name or an indexed variable.  If
+the value of <var>expression</var> is a structure, <var>var</var> may also be a
+vector with two elements.  See <a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a>, below.
+
+   <p>The assignment expression in the <code>for</code> statement works a bit
+differently than Octave's normal assignment statement.  Instead of
+assigning the complete result of the expression, it assigns each column
+of the expression to <var>var</var> in turn.  If <var>expression</var> is a range,
+a row vector, or a scalar, the value of <var>var</var> will be a scalar each
+time the loop body is executed.  If <var>var</var> is a column vector or a
+matrix, <var>var</var> will be a column vector each time the loop body is
+executed.
+
+   <p>The following example shows another way to create a vector containing
+the first ten elements of the Fibonacci sequence, this time using the
+<code>for</code> statement:
+
+<pre class="example">     fib = ones (1, 10);
+     for i = 3:10
+       fib (i) = fib (i-1) + fib (i-2);
+     endfor
+</pre>
+   <p class="noindent">This code works by first evaluating the expression <code>3:10</code>, to
+produce a range of values from 3 to 10 inclusive.  Then the variable
+<code>i</code> is assigned the first element of the range and the body of the
+loop is executed once.  When the end of the loop body is reached, the
+next value in the range is assigned to the variable <code>i</code>, and the
+loop body is executed again.  This process continues until there are no
+more elements to assign.
+
+   <p>Within Octave is it also possible to iterate over matrices or cell arrays
+using the <code>for</code> statement.  For example consider
+
+<pre class="example">     disp("Loop over a matrix")
+     for i = [1,3;2,4]
+       i
+     endfor
+     disp("Loop over a cell array")
+     for i = {1,"two";"three",4}
+       i
+     endfor
+</pre>
+   <p class="noindent">In this case the variable <code>i</code> takes on the value of the columns of
+the matrix or cell matrix.  So the first loop iterates twice, producing
+two column vectors <code>[1;2]</code>, followed by <code>[3;4]</code>, and likewise
+for the loop over the cell array.  This can be extended to loops over
+multidimensional arrays.  For example
+
+<pre class="example">     a = [1,3;2,4]; b = cat(3, a, 2*a);
+     for i = c
+       i
+     endfor
+</pre>
+   <p class="noindent">In the above case, the multidimensional matrix <var>c</var> is reshaped to a
+two-dimensional matrix as <code>reshape (c, rows(c),
+prod(size(c)(2:end)))</code> and then the same behavior as a loop over a two
+dimensional matrix is produced.
+
+   <p>Although it is possible to rewrite all <code>for</code> loops as <code>while</code>
+loops, the Octave language has both statements because often a
+<code>for</code> loop is both less work to type and more natural to think of. 
+Counting the number of iterations is very common in loops and it can be
+easier to think of this counting as part of looping rather than as
+something to do inside the loop.
+
+<ul class="menu">
+<li><a accesskey="1" href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003eif_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003eif_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..633c7c5
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003eif_003c_002fcode_003e-Statement.html
@@ -0,0 +1,147 @@
+<html lang="en">
+<head>
+<title>The @code{if} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="next" href="The-_0040code_007bswitch_007d-Statement.html#The-_0040code_007bswitch_007d-Statement" title="The @code{switch} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3eif%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003eif_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.1 The <code>if</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bif_007d-statement-556"></a><a name="index-g_t_0040code_007belse_007d-statement-557"></a><a name="index-g_t_0040code_007belseif_007d-statement-558"></a><a name="index-g_t_0040code_007bendif_007d-statement-559"></a>
+The <code>if</code> statement is Octave's decision-making statement.  There
+are three basic forms of an <code>if</code> statement.  In its simplest form,
+it looks like this:
+
+<pre class="example">     if (<var>condition</var>)
+       <var>then-body</var>
+     endif
+</pre>
+   <p class="noindent"><var>condition</var> is an expression that controls what the rest of the
+statement will do.  The <var>then-body</var> is executed only if
+<var>condition</var> is true.
+
+   <p>The condition in an <code>if</code> statement is considered true if its value
+is non-zero, and false if its value is zero.  If the value of the
+conditional expression in an <code>if</code> statement is a vector or a
+matrix, it is considered true only if it is non-empty and <em>all</em>
+of the elements are non-zero.
+
+   <p>The second form of an if statement looks like this:
+
+<pre class="example">     if (<var>condition</var>)
+       <var>then-body</var>
+     else
+       <var>else-body</var>
+     endif
+</pre>
+   <p class="noindent">If <var>condition</var> is true, <var>then-body</var> is executed; otherwise,
+<var>else-body</var> is executed.
+
+   <p>Here is an example:
+
+<pre class="example">     if (rem (x, 2) == 0)
+       printf ("x is even\n");
+     else
+       printf ("x is odd\n");
+     endif
+</pre>
+   <p>In this example, if the expression <code>rem (x, 2) == 0</code> is true (that
+is, the value of <code>x</code> is divisible by 2), then the first
+<code>printf</code> statement is evaluated, otherwise the second <code>printf</code>
+statement is evaluated.
+
+   <p>The third and most general form of the <code>if</code> statement allows
+multiple decisions to be combined in a single statement.  It looks like
+this:
+
+<pre class="example">     if (<var>condition</var>)
+       <var>then-body</var>
+     elseif (<var>condition</var>)
+       <var>elseif-body</var>
+     else
+       <var>else-body</var>
+     endif
+</pre>
+   <p class="noindent">Any number of <code>elseif</code> clauses may appear.  Each condition is
+tested in turn, and if one is found to be true, its corresponding
+<var>body</var> is executed.  If none of the conditions are true and the
+<code>else</code> clause is present, its body is executed.  Only one
+<code>else</code> clause may appear, and it must be the last part of the
+statement.
+
+   <p>In the following example, if the first condition is true (that is, the
+value of <code>x</code> is divisible by 2), then the first <code>printf</code>
+statement is executed.  If it is false, then the second condition is
+tested, and if it is true (that is, the value of <code>x</code> is divisible
+by 3), then the second <code>printf</code> statement is executed.  Otherwise,
+the third <code>printf</code> statement is performed.
+
+<pre class="example">     if (rem (x, 2) == 0)
+       printf ("x is even\n");
+     elseif (rem (x, 3) == 0)
+       printf ("x is odd and divisible by 3\n");
+     else
+       printf ("x is odd\n");
+     endif
+</pre>
+   <p>Note that the <code>elseif</code> keyword must not be spelled <code>else if</code>,
+as is allowed in Fortran.  If it is, the space between the <code>else</code>
+and <code>if</code> will tell Octave to treat this as a new <code>if</code>
+statement within another <code>if</code> statement's <code>else</code> clause.  For
+example, if you write
+
+<pre class="example">     if (<var>c1</var>)
+       <var>body-1</var>
+     else if (<var>c2</var>)
+       <var>body-2</var>
+     endif
+</pre>
+   <p class="noindent">Octave will expect additional input to complete the first <code>if</code>
+statement.  If you are using Octave interactively, it will continue to
+prompt you for additional input.  If Octave is reading this input from a
+file, it may complain about missing or mismatched <code>end</code> statements,
+or, if you have not used the more specific <code>end</code> statements
+(<code>endif</code>, <code>endfor</code>, etc.), it may simply produce incorrect
+results, without producing any warning messages.
+
+   <p>It is much easier to see the error if we rewrite the statements above
+like this,
+
+<pre class="example">     if (<var>c1</var>)
+       <var>body-1</var>
+     else
+       if (<var>c2</var>)
+         <var>body-2</var>
+       endif
+</pre>
+   <p class="noindent">using the indentation to show how Octave groups the statements. 
+See <a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..d470c92
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html
@@ -0,0 +1,130 @@
+<html lang="en">
+<head>
+<title>The @code{switch} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bif_007d-Statement.html#The-_0040code_007bif_007d-Statement" title="The @code{if} Statement">
+<link rel="next" href="The-_0040code_007bwhile_007d-Statement.html#The-_0040code_007bwhile_007d-Statement" title="The @code{while} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3eswitch%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003eswitch_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.2 The <code>switch</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bswitch_007d-statement-560"></a><a name="index-g_t_0040code_007bcase_007d-statement-561"></a><a name="index-g_t_0040code_007botherwise_007d-statement-562"></a><a name="index-g_t_0040code_007bendswitch_007d-statement-563"></a>
+It is very common to take different actions depending on the value of
+one variable.  This is possible using the <code>if</code> statement in the
+following way
+
+<pre class="example">     if (X == 1)
+       do_something ();
+     elseif (X == 2)
+       do_something_else ();
+     else
+       do_something_completely_different ();
+     endif
+</pre>
+   <p class="noindent">This kind of code can however be very cumbersome to both write and
+maintain.  To overcome this problem Octave supports the <code>switch</code>
+statement.  Using this statement, the above example becomes
+
+<pre class="example">     switch (X)
+       case 1
+         do_something ();
+       case 2
+         do_something_else ();
+       otherwise
+         do_something_completely_different ();
+     endswitch
+</pre>
+   <p class="noindent">This code makes the repetitive structure of the problem more explicit,
+making the code easier to read, and hence maintain.  Also, if the
+variable <code>X</code> should change its name, only one line would need
+changing compared to one line per case when <code>if</code> statements are
+used.
+
+   <p>The general form of the <code>switch</code> statement is
+
+<pre class="example">     switch <var>expression</var>
+       case <var>label</var>
+         <var>command_list</var>
+       case <var>label</var>
+         <var>command_list</var>
+       ...
+     
+       otherwise
+         <var>command_list</var>
+     endswitch
+</pre>
+   <p class="noindent">where <var>label</var> can be any expression.  However, duplicate
+<var>label</var> values are not detected, and only the <var>command_list</var>
+corresponding to the first match will be executed.  For the
+<code>switch</code> statement to be meaningful at least one
+<code>case </code><var>label</var> <var>command_list</var> clause must be present,
+while the <code>otherwise </code><var>command_list</var> clause is optional.
+
+   <p>If <var>label</var> is a cell array the corresponding <var>command_list</var>
+is executed if <em>any</em> of the elements of the cell array match
+<var>expression</var>.  As an example, the following program will print
+‘<samp><span class="samp">Variable is either 6 or 7</span></samp>’.
+
+<pre class="example">     A = 7;
+     switch A
+       case { 6, 7 }
+         printf ("variable is either 6 or 7\n");
+       otherwise
+         printf ("variable is neither 6 nor 7\n");
+     endswitch
+</pre>
+   <p>As with all other specific <code>end</code> keywords, <code>endswitch</code> may be
+replaced by <code>end</code>, but you can get better diagnostics if you use
+the specific forms.
+
+<!-- Strings can be matched -->
+   <p>One advantage of using the <code>switch</code> statement compared to using
+<code>if</code> statements is that the <var>label</var>s can be strings.  If an
+<code>if</code> statement is used it is <em>not</em> possible to write
+
+<pre class="example">     if (X == "a string") # This is NOT valid
+</pre>
+   <p class="noindent">since a character-to-character comparison between <code>X</code> and the
+string will be made instead of evaluating if the strings are equal. 
+This special-case is handled by the <code>switch</code> statement, and it
+is possible to write programs that look like this
+
+<pre class="example">     switch (X)
+       case "a string"
+         do_something
+       ...
+     endswitch
+</pre>
+   <ul class="menu">
+<li><a accesskey="1" href="Notes-for-the-C-programmer.html#Notes-for-the-C-programmer">Notes for the C programmer</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003etry_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003etry_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..f6bc9ac
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003etry_003c_002fcode_003e-Statement.html
@@ -0,0 +1,66 @@
+<html lang="en">
+<head>
+<title>The @code{try} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bunwind_005fprotect_007d-Statement.html#The-_0040code_007bunwind_005fprotect_007d-Statement" title="The @code{unwind_protect} Statement">
+<link rel="next" href="Continuation-Lines.html#Continuation-Lines" title="Continuation Lines">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3etry%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003etry_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="Continuation-Lines.html#Continuation-Lines">Continuation Lines</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.9 The <code>try</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007btry_007d-statement-578"></a><a name="index-g_t_0040code_007bcatch_007d-579"></a><a name="index-g_t_0040code_007bend_005ftry_005fcatch_007d-580"></a>
+In addition to unwind_protect, Octave supports another limited form of
+exception handling.
+
+   <p>The general form of a <code>try</code> block looks like this:
+
+<pre class="example">     try
+       <var>body</var>
+     catch
+       <var>cleanup</var>
+     end_try_catch
+</pre>
+   <p class="noindent">where <var>body</var> and <var>cleanup</var> are both optional and may contain any
+Octave expressions or commands.  The statements in <var>cleanup</var> are
+only executed if an error occurs in <var>body</var>.
+
+   <p>No warnings or error messages are printed while <var>body</var> is
+executing.  If an error does occur during the execution of <var>body</var>,
+<var>cleanup</var> can use the function <code>lasterr</code> to access the text
+of the message that would have been printed.  This is the same
+as <code>eval (</code><var>try</var><code>, </code><var>catch</var><code>)</code> but it is more efficient since
+the commands do not need to be parsed each time the <var>try</var> and
+<var>catch</var> statements are evaluated.  See <a href="Errors-and-Warnings.html#Errors-and-Warnings">Errors and Warnings</a>, for more
+information about the <code>lasterr</code> function.
+
+   <p><a name="index-continuation-lines-581"></a><a name="index-g_t_0040code_007b_002e_002e_002e_007d-continuation-marker-582"></a><a name="index-g_t_0040code_007b_005c_007d-continuation-marker-583"></a>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..b431b81
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html
@@ -0,0 +1,75 @@
+<html lang="en">
+<head>
+<title>The @code{unwind_protect} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bcontinue_007d-Statement.html#The-_0040code_007bcontinue_007d-Statement" title="The @code{continue} Statement">
+<link rel="next" href="The-_0040code_007btry_007d-Statement.html#The-_0040code_007btry_007d-Statement" title="The @code{try} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3eunwind_protect%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#The-_003ccode_003econtinue_003c_002fcode_003e-Statement">The <code>continue</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.8 The <code>unwind_protect</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bunwind_005fprotect_007d-statement-575"></a><a name="index-g_t_0040code_007bunwind_005fprotect_005fcleanup_007d-576"></a><a name="index-g_t_0040code_007bend_005funwind_005fprotect_007d-577"></a>
+Octave supports a limited form of exception handling modelled after the
+unwind-protect form of Lisp.
+
+   <p>The general form of an <code>unwind_protect</code> block looks like this:
+
+<pre class="example">     unwind_protect
+       <var>body</var>
+     unwind_protect_cleanup
+       <var>cleanup</var>
+     end_unwind_protect
+</pre>
+   <p class="noindent">where <var>body</var> and <var>cleanup</var> are both optional and may contain any
+Octave expressions or commands.  The statements in <var>cleanup</var> are
+guaranteed to be executed regardless of how control exits <var>body</var>.
+
+   <p>This is useful to protect temporary changes to global variables from
+possible errors.  For example, the following code will always restore
+the original value of the global variable <code>frobnosticate</code>
+even if an error occurs in the first part of the <code>unwind_protect</code>
+block.
+
+<pre class="example">     save_frobnosticate = frobnosticate;
+     unwind_protect
+       frobnosticate = true;
+       ...
+     unwind_protect_cleanup
+       frobnosticate = save_frobnosticate;
+     end_unwind_protect
+</pre>
+   <p class="noindent">Without <code>unwind_protect</code>, the value of <var>frobnosticate</var>
+would not be restored if an error occurs while evaluating the first part
+of the <code>unwind_protect</code> block because evaluation would stop at the
+point of the error and the statement to restore the value would not be
+executed.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html b/doc/interpreter/HTML/The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html
new file mode 100644
index 0000000..4d1e7b7
--- /dev/null
+++ b/doc/interpreter/HTML/The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html
@@ -0,0 +1,92 @@
+<html lang="en">
+<head>
+<title>The @code{while} Statement - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Statements.html#Statements" title="Statements">
+<link rel="prev" href="The-_0040code_007bswitch_007d-Statement.html#The-_0040code_007bswitch_007d-Statement" title="The @code{switch} Statement">
+<link rel="next" href="The-_0040code_007bdo_002duntil_007d-Statement.html#The-_0040code_007bdo_002duntil_007d-Statement" title="The @code{do-until} Statement">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="The-%3ccode%3ewhile%3c%2fcode%3e-Statement"></a>
+<a name="The-_003ccode_003ewhile_003c_002fcode_003e-Statement"></a>
+Next: <a rel="next" accesskey="n" href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement">The <code>do-until</code> Statement</a>,
+Previous: <a rel="previous" accesskey="p" href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a>,
+Up: <a rel="up" accesskey="u" href="Statements.html#Statements">Statements</a>
+<hr>
+</div>
+
+<h3 class="section">10.3 The <code>while</code> Statement</h3>
+
+<p><a name="index-g_t_0040code_007bwhile_007d-statement-564"></a><a name="index-g_t_0040code_007bendwhile_007d-statement-565"></a><a name="index-loop-566"></a><a name="index-body-of-a-loop-567"></a>
+In programming, a <dfn>loop</dfn> means a part of a program that is (or at least can
+be) executed two or more times in succession.
+
+   <p>The <code>while</code> statement is the simplest looping statement in Octave. 
+It repeatedly executes a statement as long as a condition is true.  As
+with the condition in an <code>if</code> statement, the condition in a
+<code>while</code> statement is considered true if its value is non-zero, and
+false if its value is zero.  If the value of the conditional expression
+in a <code>while</code> statement is a vector or a matrix, it is considered
+true only if it is non-empty and <em>all</em> of the elements are non-zero.
+
+   <p>Octave's <code>while</code> statement looks like this:
+
+<pre class="example">     while (<var>condition</var>)
+       <var>body</var>
+     endwhile
+</pre>
+   <p class="noindent">Here <var>body</var> is a statement or list of statements that we call the
+<dfn>body</dfn> of the loop, and <var>condition</var> is an expression that
+controls how long the loop keeps running.
+
+   <p>The first thing the <code>while</code> statement does is test <var>condition</var>. 
+If <var>condition</var> is true, it executes the statement <var>body</var>.  After
+<var>body</var> has been executed, <var>condition</var> is tested again, and if it
+is still true, <var>body</var> is executed again.  This process repeats until
+<var>condition</var> is no longer true.  If <var>condition</var> is initially
+false, the body of the loop is never executed.
+
+   <p>This example creates a variable <code>fib</code> that contains the first ten
+elements of the Fibonacci sequence.
+
+<pre class="example">     fib = ones (1, 10);
+     i = 3;
+     while (i <= 10)
+       fib (i) = fib (i-1) + fib (i-2);
+       i++;
+     endwhile
+</pre>
+   <p class="noindent">Here the body of the loop contains two statements.
+
+   <p>The loop works like this: first, the value of <code>i</code> is set to 3. 
+Then, the <code>while</code> tests whether <code>i</code> is less than or equal to
+10.  This is the case when <code>i</code> equals 3, so the value of the
+<code>i</code>-th element of <code>fib</code> is set to the sum of the previous two
+values in the sequence.  Then the <code>i++</code> increments the value of
+<code>i</code> and the loop repeats.  The loop terminates when <code>i</code>
+reaches 11.
+
+   <p>A newline is not required between the condition and the
+body; but using one makes the program clearer unless the body is very
+simple.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Three_002dDimensional-Plotting.html b/doc/interpreter/HTML/Three_002dDimensional-Plotting.html
new file mode 100644
index 0000000..3c69409
--- /dev/null
+++ b/doc/interpreter/HTML/Three_002dDimensional-Plotting.html
@@ -0,0 +1,501 @@
+<html lang="en">
+<head>
+<title>Three-Dimensional Plotting - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="prev" href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots" title="Two-Dimensional Plots">
+<link rel="next" href="Plot-Annotations.html#Plot-Annotations" title="Plot Annotations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Three-Dimensional-Plotting"></a>
+<a name="Three_002dDimensional-Plotting"></a>
+Next: <a rel="next" accesskey="n" href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a>,
+Previous: <a rel="previous" accesskey="p" href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.2 Three-Dimensional Plotting</h4>
+
+<p>The function <code>mesh</code> produces mesh surface plots.  For example,
+
+<pre class="example">     tx = ty = linspace (-8, 8, 41)';
+     [xx, yy] = meshgrid (tx, ty);
+     r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+     tz = sin (r) ./ r;
+     mesh (tx, ty, tz);
+</pre>
+   <p class="noindent">produces the familiar “sombrero” plot shown in <a href="fig_003amesh.html#fig_003amesh">fig:mesh</a>.  Note
+the use of the function <code>meshgrid</code> to create matrices of X and Y
+coordinates to use for plotting the Z data.  The <code>ndgrid</code> function
+is similar to <code>meshgrid</code>, but works for N-dimensional matrices.
+
+   <div class="float">
+<a name="fig_003amesh"></a><div align="center"><img src="mesh.png" alt="mesh.png"></div>
+   <p><strong class="float-caption">Figure 15.5: Mesh plot.</strong></p></div>
+
+   <p>The <code>meshc</code> function is similar to <code>mesh</code>, but also produces a
+plot of contours for the surface.
+
+   <p>The <code>plot3</code> function displays arbitrary three-dimensional data,
+without requiring it to form a surface.  For example
+
+<pre class="example">     t = 0:0.1:10*pi;
+     r = linspace (0, 1, numel (t));
+     z = linspace (0, 1, numel (t));
+     plot3 (r.*sin(t), r.*cos(t), z);
+</pre>
+   <p class="noindent">displays the spiral in three dimensions shown in <a href="fig_003aplot3.html#fig_003aplot3">fig:plot3</a>.
+
+   <div class="float">
+<a name="fig_003aplot3"></a><div align="center"><img src="plot3.png" alt="plot3.png"></div>
+   <p><strong class="float-caption">Figure 15.6: Three dimensional spiral.</strong></p></div>
+
+   <p>Finally, the <code>view</code> function changes the viewpoint for
+three-dimensional plots.
+
+<!-- ./plot/mesh.m -->
+   <p><a name="doc_002dmesh"></a>
+
+<div class="defun">
+— Function File:  <b>mesh</b> (<var>x, y, z</var>)<var><a name="index-mesh-978"></a></var><br>
+<blockquote><p>Plot a mesh given matrices <var>x</var>, and <var>y</var> from <code>meshgrid</code> and
+a matrix <var>z</var> corresponding to the <var>x</var> and <var>y</var> coordinates of
+the mesh.  If <var>x</var> and <var>y</var> are vectors, then a typical vertex
+is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus, columns of <var>z</var>
+correspond to different <var>x</var> values and rows of <var>z</var> correspond
+to different <var>y</var> values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/meshc.m -->
+   <p><a name="doc_002dmeshc"></a>
+
+<div class="defun">
+— Function File:  <b>meshc</b> (<var>x, y, z</var>)<var><a name="index-meshc-979"></a></var><br>
+<blockquote><p>Plot a mesh and contour given matrices <var>x</var>, and <var>y</var> from
+<code>meshgrid</code> and a matrix <var>z</var> corresponding to the <var>x</var> and
+<var>y</var> coordinates of the mesh.  If <var>x</var> and <var>y</var> are vectors,
+then a typical vertex is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus,
+columns of <var>z</var> correspond to different <var>x</var> values and rows of
+<var>z</var> correspond to different <var>y</var> values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/meshz.m -->
+   <p><a name="doc_002dmeshz"></a>
+
+<div class="defun">
+— Function File:  <b>meshz</b> (<var>x, y, z</var>)<var><a name="index-meshz-980"></a></var><br>
+<blockquote><p>Plot a curtain mesh given matrices <var>x</var>, and <var>y</var> from
+<code>meshgrid</code> and a matrix <var>z</var> corresponding to the <var>x</var> and
+<var>y</var> coordinates of the mesh.  If <var>x</var> and <var>y</var> are vectors,
+then a typical vertex is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus,
+columns of <var>z</var> correspond to different <var>x</var> values and rows of
+<var>z</var> correspond to different <var>y</var> values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/hidden.m -->
+   <p><a name="doc_002dhidden"></a>
+
+<div class="defun">
+— Function File:  <b>hidden</b> (<var>mode</var>)<var><a name="index-hidden-981"></a></var><br>
+— Function File:  <b>hidden</b> ()<var><a name="index-hidden-982"></a></var><br>
+<blockquote><p>Manipulation the mesh hidden line removal.  Called with no argument
+the hidden line removal is toggled.  The argument <var>mode</var> can be either
+'on' or 'off' and the set of the hidden line removal is set accordingly. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dmeshc.html#doc_002dmeshc">meshc</a>, <a href="doc_002dsurf.html#doc_002dsurf">surf</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/surf.m -->
+   <p><a name="doc_002dsurf"></a>
+
+<div class="defun">
+— Function File:  <b>surf</b> (<var>x, y, z</var>)<var><a name="index-surf-983"></a></var><br>
+<blockquote><p>Plot a surface given matrices <var>x</var>, and <var>y</var> from <code>meshgrid</code> and
+a matrix <var>z</var> corresponding to the <var>x</var> and <var>y</var> coordinates of
+the mesh.  If <var>x</var> and <var>y</var> are vectors, then a typical vertex
+is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus, columns of <var>z</var>
+correspond to different <var>x</var> values and rows of <var>z</var> correspond
+to different <var>y</var> values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dsurface.html#doc_002dsurface">surface</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/surfc.m -->
+   <p><a name="doc_002dsurfc"></a>
+
+<div class="defun">
+— Function File:  <b>surfc</b> (<var>x, y, z</var>)<var><a name="index-surfc-984"></a></var><br>
+<blockquote><p>Plot a surface and contour given matrices <var>x</var>, and <var>y</var> from
+<code>meshgrid</code> and a matrix <var>z</var> corresponding to the <var>x</var> and
+<var>y</var> coordinates of the mesh.  If <var>x</var> and <var>y</var> are vectors,
+then a typical vertex is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus,
+columns of <var>z</var> correspond to different <var>x</var> values and rows of
+<var>z</var> correspond to different <var>y</var> values. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>, <a href="doc_002dsurf.html#doc_002dsurf">surf</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/surfl.m -->
+   <p><a name="doc_002dsurfl"></a>
+
+<div class="defun">
+— Function File:  <b>surfl</b> (<var>x, y, z</var>)<var><a name="index-surfl-985"></a></var><br>
+— Function File:  <b>surfl</b> (<var>z</var>)<var><a name="index-surfl-986"></a></var><br>
+— Function File:  <b>surfl</b> (<var>x, y, z, L</var>)<var><a name="index-surfl-987"></a></var><br>
+— Function File:  <b>surfl</b> (<var>x, y, z, L, P</var>)<var><a name="index-surfl-988"></a></var><br>
+— Function File:  <b>surfl</b> (<var><small class="dots">...</small>,"light"</var>)<var><a name="index-surfl-989"></a></var><br>
+<blockquote><p>Plot a lighted surface given matrices <var>x</var>, and <var>y</var> from <code>meshgrid</code> and
+a matrix <var>z</var> corresponding to the <var>x</var> and <var>y</var> coordinates of
+the mesh.  If <var>x</var> and <var>y</var> are vectors, then a typical vertex
+is (<var>x</var>(j), <var>y</var>(i), <var>z</var>(i,j)).  Thus, columns of <var>z</var>
+correspond to different <var>x</var> values and rows of <var>z</var> correspond
+to different <var>y</var> values.
+
+        <p>The light direction can be specified using <var>L</var>.  It can be
+given as 2-element vector [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz]. 
+The default value is rotated 45° counter-clockwise from the current view.
+
+        <p>The material properties of the surface can specified using a 4-element vector
+<var>P</var> = [<var>AM</var> <var>D</var> <var>SP</var> <var>exp</var>] which defaults to
+<var>p</var> = [0.55 0.6 0.4 10].
+          <dl>
+<dt><code>"AM" strength of ambient light</code><br><dt><code>"D" strength of diffuse reflection</code><br><dt><code>"SP" strength of specular reflection</code><br><dt><code>"EXP" specular exponent</code><dd></dl>
+
+        <p>The default lighting mode "cdata", changes the cdata property to give the impression
+of a lighted surface.  Please note: the alternative "light" mode, which creates a light
+object to illuminate the surface is not implemented (yet).
+
+        <p>Example:
+
+     <pre class="example">          colormap(bone);
+          surfl(peaks);
+          shading interp;
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsurf.html#doc_002dsurf">surf</a>, <a href="doc_002ddiffuse.html#doc_002ddiffuse">diffuse</a>, <a href="doc_002dspecular.html#doc_002dspecular">specular</a>, <a href="doc_002dsurface.html#doc_002dsurface">surface</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/surfnorm.m -->
+   <p><a name="doc_002dsurfnorm"></a>
+
+<div class="defun">
+— Function File:  <b>surfnorm</b> (<var>x, y, z</var>)<var><a name="index-surfnorm-990"></a></var><br>
+— Function File:  <b>surfnorm</b> (<var>z</var>)<var><a name="index-surfnorm-991"></a></var><br>
+— Function File: [<var>nx</var>, <var>ny</var>, <var>nz</var>] = <b>surfnorm</b> (<var><small class="dots">...</small></var>)<var><a name="index-surfnorm-992"></a></var><br>
+— Function File:  <b>surfnorm</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-surfnorm-993"></a></var><br>
+<blockquote><p>Find the vectors normal to a meshgridded surface.  The meshed gridded
+surface is defined by <var>x</var>, <var>y</var>, and <var>z</var>.  If <var>x</var> and
+<var>y</var> are not defined, then it is assumed that they are given by
+
+     <pre class="example">          [<var>x</var>, <var>y</var>] = meshgrid (1:size(<var>z</var>, 1),
+                               1:size(<var>z</var>, 2));
+</pre>
+        <p>If no return arguments are requested, a surface plot with the normal
+vectors to the surface is plotted.  Otherwise the components of the normal
+vectors at the mesh gridded points are returned in <var>nx</var>, <var>ny</var>,
+and <var>nz</var>.
+
+        <p>The normal vectors are calculated by taking the cross product of the
+diagonals of each of the quadrilaterals in the meshgrid to find the
+normal vectors of the centers of these quadrilaterals.  The four nearest
+normal vectors to the meshgrid points are then averaged to obtain the
+normal to the surface at the meshgridded points.
+
+        <p>An example of the use of <code>surfnorm</code> is
+
+     <pre class="example">          surfnorm (peaks (25));
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsurf.html#doc_002dsurf">surf</a>, <a href="doc_002dquiver3.html#doc_002dquiver3">quiver3</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/diffuse.m -->
+   <p><a name="doc_002ddiffuse"></a>
+
+<div class="defun">
+— Function File:  <b>diffuse</b> (<var>sx, sy, sz, l</var>)<var><a name="index-diffuse-994"></a></var><br>
+<blockquote><p>Calculate diffuse reflection strength of a surface defined by the normal
+vector elements <var>sx</var>, <var>sy</var>, <var>sz</var>. 
+The light vector can be specified using parameter <var>L</var>.  It can be
+given as 2-element vector [azimuth, elevation] in degrees or as 3-element
+vector [lx, ly, lz]. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dspecular.html#doc_002dspecular">specular</a>, <a href="doc_002dsurfl.html#doc_002dsurfl">surfl</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/specular.m -->
+   <p><a name="doc_002dspecular"></a>
+
+<div class="defun">
+— Function File:  <b>specular</b> (<var>sx, sy, sz, l, v</var>)<var><a name="index-specular-995"></a></var><br>
+— Function File:  <b>specular</b> (<var>sx, sy, sz, l, v, se</var>)<var><a name="index-specular-996"></a></var><br>
+<blockquote><p>Calculate specular reflection strength of a surface defined by the normal
+vector elements <var>sx</var>, <var>sy</var>, <var>sz</var> using Phong's approximation. 
+The light and view vectors can be specified using parameter <var>L</var> and <var>V</var> respectively. 
+Both can be given as 2-element vectors [azimuth, elevation] in degrees or as 3-element
+vector [x, y, z].  An optional 6th argument describes the specular exponent (spread) <var>se</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsurfl.html#doc_002dsurfl">surfl</a>, <a href="doc_002ddiffuse.html#doc_002ddiffuse">diffuse</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/meshgrid.m -->
+   <p><a name="doc_002dmeshgrid"></a>
+
+<div class="defun">
+— Function File: [<var>xx</var>, <var>yy</var>, <var>zz</var>] = <b>meshgrid</b> (<var>x, y, z</var>)<var><a name="index-meshgrid-997"></a></var><br>
+— Function File: [<var>xx</var>, <var>yy</var>] = <b>meshgrid</b> (<var>x, y</var>)<var><a name="index-meshgrid-998"></a></var><br>
+— Function File: [<var>xx</var>, <var>yy</var>] = <b>meshgrid</b> (<var>x</var>)<var><a name="index-meshgrid-999"></a></var><br>
+<blockquote><p>Given vectors of <var>x</var> and <var>y</var> and <var>z</var> coordinates, and
+returning 3 arguments, return three-dimensional arrays corresponding
+to the <var>x</var>, <var>y</var>, and <var>z</var> coordinates of a mesh.  When
+returning only 2 arguments, return matrices corresponding to the
+<var>x</var> and <var>y</var> coordinates of a mesh.  The rows of <var>xx</var> are
+copies of <var>x</var>, and the columns of <var>yy</var> are copies of <var>y</var>. 
+If <var>y</var> is omitted, then it is assumed to be the same as <var>x</var>,
+and <var>z</var> is assumed the same as <var>y</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ndgrid.m -->
+   <p><a name="doc_002dndgrid"></a>
+
+<div class="defun">
+— Function File: [<var>y1</var>, <var>y2</var>, <small class="dots">...</small>,  <var>y</var>n] = <b>ndgrid</b> (<var>x1, x2, <small class="dots">...</small>, xn</var>)<var><a name="index-ndgrid-1000"></a></var><br>
+— Function File: [<var>y1</var>, <var>y2</var>, <small class="dots">...</small>,  <var>y</var>n] = <b>ndgrid</b> (<var>x</var>)<var><a name="index-ndgrid-1001"></a></var><br>
+<blockquote><p>Given n vectors <var>x1</var>, <small class="dots">...</small> <var>x</var>n, <code>ndgrid</code> returns
+n arrays of dimension n. The elements of the i-th output argument
+contains the elements of the vector <var>x</var>i repeated over all
+dimensions different from the i-th dimension.  Calling ndgrid with
+only one input argument <var>x</var> is equivalent of calling ndgrid with
+all n input arguments equal to <var>x</var>:
+
+        <p>[<var>y1</var>, <var>y2</var>, <small class="dots">...</small>,  <var>y</var>n] = ndgrid (<var>x</var>, <small class="dots">...</small>, <var>x</var>)
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/plot3.m -->
+   <p><a name="doc_002dplot3"></a>
+
+<div class="defun">
+— Function File:  <b>plot3</b> (<var>args</var>)<var><a name="index-plot3-1002"></a></var><br>
+<blockquote><p>Produce three-dimensional plots.  Many different combinations of
+arguments are possible.  The simplest form is
+
+     <pre class="example">          plot3 (<var>x</var>, <var>y</var>, <var>z</var>)
+</pre>
+        <p class="noindent">in which the arguments are taken to be the vertices of the points to
+be plotted in three dimensions.  If all arguments are vectors of the
+same length, then a single continuous line is drawn.  If all arguments
+are matrices, then each column of the matrices is treated as a
+separate line.  No attempt is made to transpose the arguments to make
+the number of rows match.
+
+        <p>If only two arguments are given, as
+
+     <pre class="example">          plot3 (<var>x</var>, <var>c</var>)
+</pre>
+        <p class="noindent">the real and imaginary parts of the second argument are used
+as the <var>y</var> and <var>z</var> coordinates, respectively.
+
+        <p>If only one argument is given, as
+
+     <pre class="example">          plot3 (<var>c</var>)
+</pre>
+        <p class="noindent">the real and imaginary parts of the argument are used as the <var>y</var>
+and <var>z</var> values, and they are plotted versus their index.
+
+        <p>Arguments may also be given in groups of three as
+
+     <pre class="example">          plot3 (<var>x1</var>, <var>y1</var>, <var>z1</var>, <var>x2</var>, <var>y2</var>, <var>z2</var>, ...)
+</pre>
+        <p class="noindent">in which each set of three arguments is treated as a separate line or
+set of lines in three dimensions.
+
+        <p>To plot multiple one- or two-argument groups, separate each group
+with an empty format string, as
+
+     <pre class="example">          plot3 (<var>x1</var>, <var>c1</var>, "", <var>c2</var>, "", ...)
+</pre>
+        <p>An example of the use of <code>plot3</code> is
+
+     <pre class="example">             z = [0:0.05:5];
+             plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+             plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dxlabel.html#doc_002dxlabel">xlabel</a>, <a href="doc_002dylabel.html#doc_002dylabel">ylabel</a>, <a href="doc_002dzlabel.html#doc_002dzlabel">zlabel</a>, <a href="doc_002dtitle.html#doc_002dtitle">title</a>, <a href="doc_002dprint.html#doc_002dprint">print</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/view.m -->
+   <p><a name="doc_002dview"></a>
+
+<div class="defun">
+— Function File:  <b>view</b> (<var>azimuth, elevation</var>)<var><a name="index-view-1003"></a></var><br>
+— Function File:  <b>view</b> (<var>dims</var>)<var><a name="index-view-1004"></a></var><br>
+— Function File: [<var>azimuth</var>, <var>elevation</var>] = <b>view</b> ()<var><a name="index-view-1005"></a></var><br>
+<blockquote><p>Set or get the viewpoint for the current axes. 
+</p></blockquote></div>
+
+<!-- ./plot/slice.m -->
+   <p><a name="doc_002dslice"></a>
+
+<div class="defun">
+— Function File:  <b>slice</b> (<var>x, y, z, v, sx, sy, sz</var>)<var><a name="index-slice-1006"></a></var><br>
+— Function File:  <b>slice</b> (<var>x, y, z, v, xi, yi, zi</var>)<var><a name="index-slice-1007"></a></var><br>
+— Function File:  <b>slice</b> (<var>v, sx, sy, sz</var>)<var><a name="index-slice-1008"></a></var><br>
+— Function File:  <b>slice</b> (<var>v, xi, yi, zi</var>)<var><a name="index-slice-1009"></a></var><br>
+— Function File: <var>h</var> = <b>slice</b> (<var><small class="dots">...</small></var>)<var><a name="index-slice-1010"></a></var><br>
+— Function File: <var>h</var> = <b>slice</b> (<var><small class="dots">...</small>, method</var>)<var><a name="index-slice-1011"></a></var><br>
+<blockquote><p>Plot slices of 3D data/scalar fields.  Each element of the 3-dimensional
+array <var>v</var> represents a scalar value at a location given by the
+parameters <var>x</var>, <var>y</var>, and <var>z</var>.  The parameters <var>x</var>,
+<var>x</var>, and <var>z</var> are either 3-dimensional arrays of the same size
+as the array <var>v</var> in the "meshgrid" format or vectors.  The
+parameters <var>xi</var>, etc. respect a similar format to <var>x</var>, etc.,
+and they represent the points at which the array <var>vi</var> is
+interpolated using interp3.  The vectors <var>sx</var>, <var>sy</var>, and
+<var>sz</var> contain points of orthogonal slices of the respective axes.
+
+        <p>If <var>x</var>, <var>y</var>, <var>z</var> are omitted, they are assumed to be
+<code>x = 1:size (</code><var>v</var><code>, 2)</code>, <code>y = 1:size (</code><var>v</var><code>, 1)</code> and
+<code>z = 1:size (</code><var>v</var><code>, 3)</code>.
+
+        <p><var>Method</var> is one of:
+
+          <dl>
+<dt><code>"nearest"</code><dd>Return the nearest neighbor. 
+<br><dt><code>"linear"</code><dd>Linear interpolation from nearest neighbors. 
+<br><dt><code>"cubic"</code><dd>Cubic interpolation from four nearest neighbors (not implemented yet). 
+<br><dt><code>"spline"</code><dd>Cubic spline interpolation—smooth first and second derivatives
+throughout the curve. 
+</dl>
+
+        <p>The default method is <code>"linear"</code>. 
+The optional return value <var>h</var> is a vector of handles to the
+surface graphic objects.
+
+        <p>Examples:
+     <pre class="example">          [x, y, z] = meshgrid (linspace (-8, 8, 32));
+          v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+          slice (x, y, z, v, [], 0, []);
+          [xi, yi] = meshgrid (linspace (-7, 7));
+          zi = xi + yi;
+          slice (x, y, z, v, xi, yi, zi);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dinterp3.html#doc_002dinterp3">interp3</a>, <a href="doc_002dsurface.html#doc_002dsurface">surface</a>, <a href="doc_002dpcolor.html#doc_002dpcolor">pcolor</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ribbon.m -->
+   <p><a name="doc_002dribbon"></a>
+
+<div class="defun">
+— Function File:  <b>ribbon</b> (<var>x, y, width</var>)<var><a name="index-ribbon-1012"></a></var><br>
+— Function File:  <b>ribbon</b> (<var>y</var>)<var><a name="index-ribbon-1013"></a></var><br>
+— Function File: <var>h</var> = <b>ribbon</b> (<var><small class="dots">...</small></var>)<var><a name="index-ribbon-1014"></a></var><br>
+<blockquote><p>Plot a ribbon plot for the columns of <var>y</var> vs.  <var>x</var>.  The
+optional parameter <var>width</var> specifies the width of a single ribbon
+(default is 0.75).  If <var>x</var> is omitted, a vector containing the
+row numbers is assumed (1:rows(Y)).  If requested, return a vector
+<var>h</var> of the handles to the surface objects. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgca.html#doc_002dgca">gca</a>, <a href="doc_002dcolorbar.html#doc_002dcolorbar">colorbar</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/shading.m -->
+   <p><a name="doc_002dshading"></a>
+
+<div class="defun">
+— Function File:  <b>shading</b> (<var>type</var>)<var><a name="index-shading-1015"></a></var><br>
+— Function File:  <b>shading</b> (<var>ax, <small class="dots">...</small></var>)<var><a name="index-shading-1016"></a></var><br>
+<blockquote><p>Set the shading of surface or patch graphic objects.  Valid arguments
+for <var>type</var> are
+
+          <dl>
+<dt><code>"flat"</code><dd>Single colored patches with invisible edges.
+
+          <br><dt><code>"faceted"</code><dd>Single colored patches with visible edges.
+
+          <br><dt><code>"interp"</code><dd>Color between patch vertices are interpolated and the patch edges are
+invisible. 
+</dl>
+
+        <p>If <var>ax</var> is given the shading is applied to axis <var>ax</var> instead
+of the current axis. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a>
+<li><a accesskey="2" href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">Three-dimensional Geometric Shapes</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Three_002ddimensional-Function-Plotting.html b/doc/interpreter/HTML/Three_002ddimensional-Function-Plotting.html
new file mode 100644
index 0000000..64fce10
--- /dev/null
+++ b/doc/interpreter/HTML/Three_002ddimensional-Function-Plotting.html
@@ -0,0 +1,256 @@
+<html lang="en">
+<head>
+<title>Three-dimensional Function Plotting - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting" title="Three-Dimensional Plotting">
+<link rel="next" href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes" title="Three-dimensional Geometric Shapes">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Three-dimensional-Function-Plotting"></a>
+<a name="Three_002ddimensional-Function-Plotting"></a>
+Next: <a rel="next" accesskey="n" href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">Three-dimensional Geometric Shapes</a>,
+Up: <a rel="up" accesskey="u" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.1.2.1 Three-dimensional Function Plotting</h5>
+
+<!-- ./plot/ezplot3.m -->
+<p><a name="doc_002dezplot3"></a>
+
+<div class="defun">
+— Function File:  <b>ezplot3</b> (<var>fx, fy, fz</var>)<var><a name="index-ezplot3-1017"></a></var><br>
+— Function File:  <b>ezplot3</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezplot3-1018"></a></var><br>
+— Function File:  <b>ezplot3</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezplot3-1019"></a></var><br>
+— Function File:  <b>ezplot3</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezplot3-1020"></a></var><br>
+— Function File: <var>h</var> = <b>ezplot3</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezplot3-1021"></a></var><br>
+<blockquote>
+        <p>Plots in three-dimensions the curve defined parametrically. 
+<var>fx</var>, <var>fy</var>, and <var>fz</var> are strings, inline functions
+or function handles with one arguments defining the function.  By
+default the plot is over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code>
+with 60 points.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of <var>t</var>.  <var>n</var> is a scalar defining the number of points to use.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          fx = @(t) cos (t);
+          fy = @(t) sin (t);
+          fz = @(t) t;
+          ezplot3 (fx, fy, fz, [0, 10*pi], 100);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot3.html#doc_002dplot3">plot3</a>, <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezsurf.html#doc_002dezsurf">ezsurf</a>, <a href="doc_002dezmesh.html#doc_002dezmesh">ezmesh</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezmesh.m -->
+   <p><a name="doc_002dezmesh"></a>
+
+<div class="defun">
+— Function File:  <b>ezmesh</b> (<var>f</var>)<var><a name="index-ezmesh-1022"></a></var><br>
+— Function File:  <b>ezmesh</b> (<var>fx, fy, fz</var>)<var><a name="index-ezmesh-1023"></a></var><br>
+— Function File:  <b>ezmesh</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezmesh-1024"></a></var><br>
+— Function File:  <b>ezmesh</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezmesh-1025"></a></var><br>
+— Function File:  <b>ezmesh</b> (<var><small class="dots">...</small>, 'circ'</var>)<var><a name="index-ezmesh-1026"></a></var><br>
+— Function File:  <b>ezmesh</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezmesh-1027"></a></var><br>
+— Function File: <var>h</var> = <b>ezmesh</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezmesh-1028"></a></var><br>
+<blockquote>
+        <p>Plots the mesh defined by a function.  <var>f</var> is a string, inline
+function or function handle with two arguments defining the function.  By
+default the plot is over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code> and
+<code>-2*pi < </code><var>y</var><code> < 2*pi</code> with 60 points in each dimension.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>x</var> and <var>y</var>.  If <var>dom</var> is a four element vector,
+then the minimum and maximum value of <var>x</var> and <var>y</var> are specify
+separately.
+
+        <p><var>n</var> is a scalar defining the number of points to use in each dimension.
+
+        <p>If three functions are passed, then plot the parametrically defined
+function <code>[</code><var>fx</var><code> (</code><var>s</var><code>, </code><var>t</var><code>), </code><var>fy</var><code> (</code><var>s</var><code>, </code><var>t</var><code>),
+</code><var>fz</var><code> (</code><var>s</var><code>, </code><var>t</var><code>)]</code>.
+
+        <p>If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain <var>dom</var>.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezmesh (f, [-3, 3]);
+</pre>
+        <p>An example of a parametrically defined function is
+
+     <pre class="example">          fx = @(s,t) cos (s) .* cos(t);
+          fy = @(s,t) sin (s) .* cos(t);
+          fz = @(s,t) sin(t);
+          ezmesh (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezsurf.html#doc_002dezsurf">ezsurf</a>, <a href="doc_002dezsurfc.html#doc_002dezsurfc">ezsurfc</a>, <a href="doc_002dezmeshc.html#doc_002dezmeshc">ezmeshc</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezmeshc.m -->
+   <p><a name="doc_002dezmeshc"></a>
+
+<div class="defun">
+— Function File:  <b>ezmeshc</b> (<var>f</var>)<var><a name="index-ezmeshc-1029"></a></var><br>
+— Function File:  <b>ezmeshc</b> (<var>fx, fy, fz</var>)<var><a name="index-ezmeshc-1030"></a></var><br>
+— Function File:  <b>ezmeshc</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezmeshc-1031"></a></var><br>
+— Function File:  <b>ezmeshc</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezmeshc-1032"></a></var><br>
+— Function File:  <b>ezmeshc</b> (<var><small class="dots">...</small>, 'circ'</var>)<var><a name="index-ezmeshc-1033"></a></var><br>
+— Function File:  <b>ezmeshc</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezmeshc-1034"></a></var><br>
+— Function File: <var>h</var> = <b>ezmeshc</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezmeshc-1035"></a></var><br>
+<blockquote>
+        <p>Plots the mesh and contour lines defined by a function.  <var>f</var> is a string,
+inline function or function handle with two arguments defining the function. 
+By default the plot is over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code> and
+<code>-2*pi < </code><var>y</var><code> < 2*pi</code> with 60 points in each dimension.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>x</var> and <var>y</var>.  If <var>dom</var> is a four element vector,
+then the minimum and maximum value of <var>x</var> and <var>y</var> are specify
+separately.
+
+        <p><var>n</var> is a scalar defining the number of points to use in each dimension.
+
+        <p>If three functions are passed, then plot the parametrically defined
+function <code>[</code><var>fx</var><code> (</code><var>s</var><code>, </code><var>t</var><code>), </code><var>fy</var><code> (</code><var>s</var><code>, </code><var>t</var><code>),
+</code><var>fz</var><code> (</code><var>s</var><code>, </code><var>t</var><code>)]</code>.
+
+        <p>If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain <var>dom</var>.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezmeshc (f, [-3, 3]);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezsurfc.html#doc_002dezsurfc">ezsurfc</a>, <a href="doc_002dezsurf.html#doc_002dezsurf">ezsurf</a>, <a href="doc_002dezmesh.html#doc_002dezmesh">ezmesh</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezsurf.m -->
+   <p><a name="doc_002dezsurf"></a>
+
+<div class="defun">
+— Function File:  <b>ezsurf</b> (<var>f</var>)<var><a name="index-ezsurf-1036"></a></var><br>
+— Function File:  <b>ezsurf</b> (<var>fx, fy, fz</var>)<var><a name="index-ezsurf-1037"></a></var><br>
+— Function File:  <b>ezsurf</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezsurf-1038"></a></var><br>
+— Function File:  <b>ezsurf</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezsurf-1039"></a></var><br>
+— Function File:  <b>ezsurf</b> (<var><small class="dots">...</small>, 'circ'</var>)<var><a name="index-ezsurf-1040"></a></var><br>
+— Function File:  <b>ezsurf</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezsurf-1041"></a></var><br>
+— Function File: <var>h</var> = <b>ezsurf</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezsurf-1042"></a></var><br>
+<blockquote>
+        <p>Plots the surface defined by a function.  <var>f</var> is a string, inline
+function or function handle with two arguments defining the function.  By
+default the plot is over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code> and
+<code>-2*pi < </code><var>y</var><code> < 2*pi</code> with 60 points in each dimension.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>x</var> and <var>y</var>.  If <var>dom</var> is a four element vector,
+then the minimum and maximum value of <var>x</var> and <var>y</var> are specify
+separately.
+
+        <p><var>n</var> is a scalar defining the number of points to use in each dimension.
+
+        <p>If three functions are passed, then plot the parametrically defined
+function <code>[</code><var>fx</var><code> (</code><var>s</var><code>, </code><var>t</var><code>), </code><var>fy</var><code> (</code><var>s</var><code>, </code><var>t</var><code>),
+</code><var>fz</var><code> (</code><var>s</var><code>, </code><var>t</var><code>)]</code>.
+
+        <p>If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain <var>dom</var>.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezsurf (f, [-3, 3]);
+</pre>
+        <p>An example of a parametrically defined function is
+
+     <pre class="example">          fx = @(s,t) cos (s) .* cos(t);
+          fy = @(s,t) sin (s) .* cos(t);
+          fz = @(s,t) sin(t);
+          ezsurf (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezmesh.html#doc_002dezmesh">ezmesh</a>, <a href="doc_002dezsurfc.html#doc_002dezsurfc">ezsurfc</a>, <a href="doc_002dezmeshc.html#doc_002dezmeshc">ezmeshc</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezsurfc.m -->
+   <p><a name="doc_002dezsurfc"></a>
+
+<div class="defun">
+— Function File:  <b>ezsurfc</b> (<var>f</var>)<var><a name="index-ezsurfc-1043"></a></var><br>
+— Function File:  <b>ezsurfc</b> (<var>fx, fy, fz</var>)<var><a name="index-ezsurfc-1044"></a></var><br>
+— Function File:  <b>ezsurfc</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezsurfc-1045"></a></var><br>
+— Function File:  <b>ezsurfc</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezsurfc-1046"></a></var><br>
+— Function File:  <b>ezsurfc</b> (<var><small class="dots">...</small>, 'circ'</var>)<var><a name="index-ezsurfc-1047"></a></var><br>
+— Function File:  <b>ezsurfc</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezsurfc-1048"></a></var><br>
+— Function File: <var>h</var> = <b>ezsurfc</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezsurfc-1049"></a></var><br>
+<blockquote>
+        <p>Plots the surface and contour lines defined by a function.  <var>f</var> is a
+string, inline function or function handle with two arguments defining the
+function.  By default the plot is over the domain <code>-2*pi < </code><var>x</var><code> <
+2*pi</code> and <code>-2*pi < </code><var>y</var><code> < 2*pi</code> with 60 points in each dimension.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>x</var> and <var>y</var>.  If <var>dom</var> is a four element vector,
+then the minimum and maximum value of <var>x</var> and <var>y</var> are specify
+separately.
+
+        <p><var>n</var> is a scalar defining the number of points to use in each dimension.
+
+        <p>If three functions are passed, then plot the parametrically defined
+function <code>[</code><var>fx</var><code> (</code><var>s</var><code>, </code><var>t</var><code>), </code><var>fy</var><code> (</code><var>s</var><code>, </code><var>t</var><code>),
+</code><var>fz</var><code> (</code><var>s</var><code>, </code><var>t</var><code>)]</code>.
+
+        <p>If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain <var>dom</var>.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezsurfc (f, [-3, 3]);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezmeshc.html#doc_002dezmeshc">ezmeshc</a>, <a href="doc_002dezsurf.html#doc_002dezsurf">ezsurf</a>, <a href="doc_002dezmesh.html#doc_002dezmesh">ezmesh</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Three_002ddimensional-Geometric-Shapes.html b/doc/interpreter/HTML/Three_002ddimensional-Geometric-Shapes.html
new file mode 100644
index 0000000..0b76935
--- /dev/null
+++ b/doc/interpreter/HTML/Three_002ddimensional-Geometric-Shapes.html
@@ -0,0 +1,108 @@
+<html lang="en">
+<head>
+<title>Three-dimensional Geometric Shapes - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting" title="Three-Dimensional Plotting">
+<link rel="prev" href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting" title="Three-dimensional Function Plotting">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Three-dimensional-Geometric-Shapes"></a>
+<a name="Three_002ddimensional-Geometric-Shapes"></a>
+Previous: <a rel="previous" accesskey="p" href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a>,
+Up: <a rel="up" accesskey="u" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.1.2.2 Three-dimensional Geometric Shapes</h5>
+
+<!-- ./plot/cylinder.m -->
+<p><a name="doc_002dcylinder"></a>
+
+<div class="defun">
+— Function File:  <b>cylinder</b><var><a name="index-cylinder-1050"></a></var><br>
+— Function File:  <b>cylinder</b> (<var>r</var>)<var><a name="index-cylinder-1051"></a></var><br>
+— Function File:  <b>cylinder</b> (<var>r, n</var>)<var><a name="index-cylinder-1052"></a></var><br>
+— Function File: [<var>x</var>, <var>y</var>, <var>z</var>] = <b>cylinder</b> (<var><small class="dots">...</small></var>)<var><a name="index-cylinder-1053"></a></var><br>
+— Function File:  <b>cylinder</b> (<var>ax, <small class="dots">...</small></var>)<var><a name="index-cylinder-1054"></a></var><br>
+<blockquote><p>Generates three matrices in <code>meshgrid</code> format, such that
+<code>surf (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>z</var><code>)</code> generates a unit cylinder. 
+The matrices are of size <var>n</var><code>+1</code>-by-<var>n</var><code>+1</code>. 
+<var>r</var> is a vector containing the radius along the z-axis. 
+If <var>n</var> or <var>r</var> are omitted then default values of 20 or [1 1]
+are assumed.
+
+        <p>Called with no return arguments, <code>cylinder</code> calls directly
+<code>surf (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>z</var><code>)</code>.  If an axes handle <var>ax</var>
+is passed as the first argument, the surface is plotted to this set
+of axes.
+
+        <p>Examples:
+     <pre class="example">          disp ("plotting a cone")
+          [x, y, z] = cylinder (10:-1:0,50);
+          surf (x, y, z);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsphere.html#doc_002dsphere">sphere</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/sphere.m -->
+   <p><a name="doc_002dsphere"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>y</var>, <var>z</var>] = <b>sphere</b> (<var>n</var>)<var><a name="index-sphere-1055"></a></var><br>
+— Function File:  <b>sphere</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-sphere-1056"></a></var><br>
+<blockquote><p>Generates three matrices in <code>meshgrid</code> format, such that
+<code>surf (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>z</var><code>)</code> generates a unit sphere. 
+The matrices of <var>n</var><code>+1</code>-by-<var>n</var><code>+1</code>.  If <var>n</var> is
+omitted then a default value of 20 is assumed.
+
+        <p>Called with no return arguments, <code>sphere</code> call directly
+<code>surf (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>z</var><code>)</code>.  If an axes handle is passed
+as the first argument, the surface is plotted to this set of axes. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpeaks.html#doc_002dpeaks">peaks</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ellipsoid.m -->
+   <p><a name="doc_002dellipsoid"></a>
+
+<div class="defun">
+— Function File: [<var>x</var>, <var>y</var>, <var>z</var>] = <b>ellipsoid</b> (<var>xc,yc, zc, xr, yr, zr, n</var>)<var><a name="index-ellipsoid-1057"></a></var><br>
+— Function File:  <b>ellipsoid</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ellipsoid-1058"></a></var><br>
+<blockquote><p>Generate three matrices in <code>meshgrid</code> format that define an
+ellipsoid.  Called with no return arguments, <code>ellipsoid</code> calls
+directly <code>surf (</code><var>x</var><code>, </code><var>y</var><code>, </code><var>z</var><code>)</code>.  If an axes handle
+is passed as the first argument, the surface is plotted to this
+set of axes. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsphere.html#doc_002dsphere">sphere</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Timing-Utilities.html b/doc/interpreter/HTML/Timing-Utilities.html
new file mode 100644
index 0000000..657bb90
--- /dev/null
+++ b/doc/interpreter/HTML/Timing-Utilities.html
@@ -0,0 +1,764 @@
+<html lang="en">
+<head>
+<title>Timing Utilities - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="System-Utilities.html#System-Utilities" title="System Utilities">
+<link rel="next" href="Filesystem-Utilities.html#Filesystem-Utilities" title="Filesystem Utilities">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Timing-Utilities"></a>
+Next: <a rel="next" accesskey="n" href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a>,
+Up: <a rel="up" accesskey="u" href="System-Utilities.html#System-Utilities">System Utilities</a>
+<hr>
+</div>
+
+<h3 class="section">34.1 Timing Utilities</h3>
+
+<p>Octave's core set of functions for manipulating time values are
+patterned after the corresponding functions from the standard C library. 
+Several of these functions use a data structure for time that includes
+the following elements:
+
+     <dl>
+<dt><code>usec</code><dd>Microseconds after the second (0-999999).
+
+     <br><dt><code>sec</code><dd>Seconds after the minute (0-61).  This number can be 61 to account
+for leap seconds.
+
+     <br><dt><code>min</code><dd>Minutes after the hour (0-59).
+
+     <br><dt><code>hour</code><dd>Hours since midnight (0-23).
+
+     <br><dt><code>mday</code><dd>Day of the month (1-31).
+
+     <br><dt><code>mon</code><dd>Months since January (0-11).
+
+     <br><dt><code>year</code><dd>Years since 1900.
+
+     <br><dt><code>wday</code><dd>Days since Sunday (0-6).
+
+     <br><dt><code>yday</code><dd>Days since January 1 (0-365).
+
+     <br><dt><code>isdst</code><dd>Daylight Savings Time flag.
+
+     <br><dt><code>zone</code><dd>Time zone. 
+</dl>
+
+<p class="noindent">In the descriptions of the following functions, this structure is
+referred to as a <var>tm_struct</var>.
+
+<!-- ./DLD-FUNCTIONS/time.cc -->
+   <p><a name="doc_002dtime"></a>
+
+<div class="defun">
+— Loadable Function:  <b>time</b> ()<var><a name="index-time-2268"></a></var><br>
+<blockquote><p>Return the current time as the number of seconds since the epoch.  The
+epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan
+1970.  For example, on Monday February 17, 1997 at 07:15:06 CUT, the
+value returned by <code>time</code> was 856163706. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dstrptime.html#doc_002dstrptime">strptime</a>, <a href="doc_002dlocaltime.html#doc_002dlocaltime">localtime</a>, <a href="doc_002dgmtime.html#doc_002dgmtime">gmtime</a>, <a href="doc_002dmktime.html#doc_002dmktime">mktime</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./time/now.m -->
+   <p><a name="doc_002dnow"></a>
+
+<div class="defun">
+— Function File: t = <b>now</b> ()<var><a name="index-now-2269"></a></var><br>
+<blockquote><p>Returns the current local time as the number of days since Jan 1, 0000. 
+By this reckoning, Jan 1, 1970 is day number 719529.
+
+        <p>The integral part, <code>floor (now)</code> corresponds to 00:00:00 today.
+
+        <p>The fractional part, <code>rem (now, 1)</code> corresponds to the current
+time on Jan 1, 0000.
+
+        <p>The returned value is also called a "serial date number"
+(see <code>datenum</code>). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>. 
+</p></blockquote></div>
+
+<!-- ./time/ctime.m -->
+   <p><a name="doc_002dctime"></a>
+
+<div class="defun">
+— Function File:  <b>ctime</b> (<var>t</var>)<var><a name="index-ctime-2270"></a></var><br>
+<blockquote><p>Convert a value returned from <code>time</code> (or any other non-negative
+integer), to the local time and return a string of the same form as
+<code>asctime</code>.  The function <code>ctime (time)</code> is equivalent to
+<code>asctime (localtime (time))</code>.  For example,
+
+     <pre class="example">          ctime (time ())
+                "Mon Feb 17 01:15:06 1997\n"
+</pre>
+        </blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/time.cc -->
+   <p><a name="doc_002dgmtime"></a>
+
+<div class="defun">
+— Loadable Function:  <b>gmtime</b> (<var>t</var>)<var><a name="index-gmtime-2271"></a></var><br>
+<blockquote><p>Given a value returned from time (or any non-negative integer),
+return a time structure corresponding to CUT.  For example,
+
+     <pre class="example">          gmtime (time ())
+                {
+                     usec = 0
+                     year = 97
+                     mon = 1
+                     mday = 17
+                     sec = 6
+                     zone = CST
+                     min = 15
+                     wday = 1
+                     hour = 7
+                     isdst = 0
+                     yday = 47
+                   }
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dstrptime.html#doc_002dstrptime">strptime</a>, <a href="doc_002dlocaltime.html#doc_002dlocaltime">localtime</a>, <a href="doc_002dmktime.html#doc_002dmktime">mktime</a>, <a href="doc_002dtime.html#doc_002dtime">time</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/time.cc -->
+   <p><a name="doc_002dlocaltime"></a>
+
+<div class="defun">
+— Loadable Function:  <b>localtime</b> (<var>t</var>)<var><a name="index-localtime-2272"></a></var><br>
+<blockquote><p>Given a value returned from time (or any non-negative integer),
+return a time structure corresponding to the local time zone.
+
+     <pre class="example">          localtime (time ())
+                {
+                     usec = 0
+                     year = 97
+                     mon = 1
+                     mday = 17
+                     sec = 6
+                     zone = CST
+                     min = 15
+                     wday = 1
+                     hour = 1
+                     isdst = 0
+                     yday = 47
+                   }
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dstrptime.html#doc_002dstrptime">strptime</a>, <a href="doc_002dgmtime.html#doc_002dgmtime">gmtime</a>, <a href="doc_002dmktime.html#doc_002dmktime">mktime</a>, <a href="doc_002dtime.html#doc_002dtime">time</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/time.cc -->
+   <p><a name="doc_002dmktime"></a>
+
+<div class="defun">
+— Loadable Function:  <b>mktime</b> (<var>tm_struct</var>)<var><a name="index-mktime-2273"></a></var><br>
+<blockquote><p>Convert a time structure corresponding to the local time to the number
+of seconds since the epoch.  For example,
+
+     <pre class="example">          mktime (localtime (time ()))
+                856163706
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dstrptime.html#doc_002dstrptime">strptime</a>, <a href="doc_002dlocaltime.html#doc_002dlocaltime">localtime</a>, <a href="doc_002dgmtime.html#doc_002dgmtime">gmtime</a>, <a href="doc_002dtime.html#doc_002dtime">time</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./time/asctime.m -->
+   <p><a name="doc_002dasctime"></a>
+
+<div class="defun">
+— Function File:  <b>asctime</b> (<var>tm_struct</var>)<var><a name="index-asctime-2274"></a></var><br>
+<blockquote><p>Convert a time structure to a string using the following five-field
+format: Thu Mar 28 08:40:14 1996.  For example,
+
+     <pre class="example">          asctime (localtime (time ()))
+                "Mon Feb 17 01:15:06 1997\n"
+</pre>
+        <p>This is equivalent to <code>ctime (time ())</code>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/time.cc -->
+   <p><a name="doc_002dstrftime"></a>
+
+<div class="defun">
+— Loadable Function:  <b>strftime</b> (<var>fmt, tm_struct</var>)<var><a name="index-strftime-2275"></a></var><br>
+<blockquote><p>Format the time structure <var>tm_struct</var> in a flexible way using the
+format string <var>fmt</var> that contains ‘<samp><span class="samp">%</span></samp>’ substitutions
+similar to those in <code>printf</code>.  Except where noted, substituted
+fields have a fixed size; numeric fields are padded if necessary. 
+Padding is with zeros by default; for fields that display a single
+number, padding can be changed or inhibited by following the ‘<samp><span class="samp">%</span></samp>’
+with one of the modifiers described below.  Unknown field specifiers are
+copied as normal characters.  All other characters are copied to the
+output without change.  For example,
+
+     <pre class="example">          strftime ("%r (%Z) %A %e %B %Y", localtime (time ()))
+                "01:15:06 AM (CST) Monday 17 February 1997"
+</pre>
+        <p>Octave's <code>strftime</code> function supports a superset of the ANSI C
+field specifiers.
+
+     <p class="noindent">Literal character fields:
+
+          <dl>
+<dt><code>%</code><dd>% character.
+
+          <br><dt><code>n</code><dd>Newline character.
+
+          <br><dt><code>t</code><dd>Tab character. 
+</dl>
+
+     <p class="noindent">Numeric modifiers (a nonstandard extension):
+
+          <dl>
+<dt><code>- (dash)</code><dd>Do not pad the field.
+
+          <br><dt><code>_ (underscore)</code><dd>Pad the field with spaces. 
+</dl>
+
+     <p class="noindent">Time fields:
+
+          <dl>
+<dt><code>%H</code><dd>Hour (00-23).
+
+          <br><dt><code>%I</code><dd>Hour (01-12).
+
+          <br><dt><code>%k</code><dd>Hour (0-23).
+
+          <br><dt><code>%l</code><dd>Hour (1-12).
+
+          <br><dt><code>%M</code><dd>Minute (00-59).
+
+          <br><dt><code>%p</code><dd>Locale's AM or PM.
+
+          <br><dt><code>%r</code><dd>Time, 12-hour (hh:mm:ss [AP]M).
+
+          <br><dt><code>%R</code><dd>Time, 24-hour (hh:mm).
+
+          <br><dt><code>%s</code><dd>Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).
+
+          <br><dt><code>%S</code><dd>Second (00-61).
+
+          <br><dt><code>%T</code><dd>Time, 24-hour (hh:mm:ss).
+
+          <br><dt><code>%X</code><dd>Locale's time representation (%H:%M:%S).
+
+          <br><dt><code>%Z</code><dd>Time zone (EDT), or nothing if no time zone is determinable. 
+</dl>
+
+     <p class="noindent">Date fields:
+
+          <dl>
+<dt><code>%a</code><dd>Locale's abbreviated weekday name (Sun-Sat).
+
+          <br><dt><code>%A</code><dd>Locale's full weekday name, variable length (Sunday-Saturday).
+
+          <br><dt><code>%b</code><dd>Locale's abbreviated month name (Jan-Dec).
+
+          <br><dt><code>%B</code><dd>Locale's full month name, variable length (January-December).
+
+          <br><dt><code>%c</code><dd>Locale's date and time (Sat Nov 04 12:02:33 EST 1989).
+
+          <br><dt><code>%C</code><dd>Century (00-99).
+
+          <br><dt><code>%d</code><dd>Day of month (01-31).
+
+          <br><dt><code>%e</code><dd>Day of month ( 1-31).
+
+          <br><dt><code>%D</code><dd>Date (mm/dd/yy).
+
+          <br><dt><code>%h</code><dd>Same as %b.
+
+          <br><dt><code>%j</code><dd>Day of year (001-366).
+
+          <br><dt><code>%m</code><dd>Month (01-12).
+
+          <br><dt><code>%U</code><dd>Week number of year with Sunday as first day of week (00-53).
+
+          <br><dt><code>%w</code><dd>Day of week (0-6).
+
+          <br><dt><code>%W</code><dd>Week number of year with Monday as first day of week (00-53).
+
+          <br><dt><code>%x</code><dd>Locale's date representation (mm/dd/yy).
+
+          <br><dt><code>%y</code><dd>Last two digits of year (00-99).
+
+          <br><dt><code>%Y</code><dd>Year (1970-). 
+</dl>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrptime.html#doc_002dstrptime">strptime</a>, <a href="doc_002dlocaltime.html#doc_002dlocaltime">localtime</a>, <a href="doc_002dgmtime.html#doc_002dgmtime">gmtime</a>, <a href="doc_002dmktime.html#doc_002dmktime">mktime</a>, <a href="doc_002dtime.html#doc_002dtime">time</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/time.cc -->
+   <p><a name="doc_002dstrptime"></a>
+
+<div class="defun">
+— Loadable Function: [<var>tm_struct</var>, <var>nchars</var>] = <b>strptime</b> (<var>str, fmt</var>)<var><a name="index-strptime-2276"></a></var><br>
+<blockquote><p>Convert the string <var>str</var> to the time structure <var>tm_struct</var> under
+the control of the format string <var>fmt</var>.
+
+        <p>If <var>fmt</var> fails to match, <var>nchars</var> is 0; otherwise it is set to the
+position of last matched character plus 1. Always check for this unless
+you're absolutely sure the date string will be parsed correctly. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dstrftime.html#doc_002dstrftime">strftime</a>, <a href="doc_002dlocaltime.html#doc_002dlocaltime">localtime</a>, <a href="doc_002dgmtime.html#doc_002dgmtime">gmtime</a>, <a href="doc_002dmktime.html#doc_002dmktime">mktime</a>, <a href="doc_002dtime.html#doc_002dtime">time</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+   <p>Most of the remaining functions described in this section are not
+patterned after the standard C library.  Some are available for
+compatibility with <span class="sc">matlab</span> and others are provided because they are
+useful.
+
+<!-- ./time/clock.m -->
+   <p><a name="doc_002dclock"></a>
+
+<div class="defun">
+— Function File:  <b>clock</b> ()<var><a name="index-clock-2277"></a></var><br>
+<blockquote><p>Return a vector containing the current year, month (1-12), day (1-31),
+hour (0-23), minute (0-59) and second (0-61).  For example,
+
+     <pre class="example">          clock ()
+                [ 1993, 8, 20, 4, 56, 1 ]
+</pre>
+        <p>The function clock is more accurate on systems that have the
+<code>gettimeofday</code> function. 
+</p></blockquote></div>
+
+<!-- ./time/date.m -->
+   <p><a name="doc_002ddate"></a>
+
+<div class="defun">
+— Function File:  <b>date</b> ()<var><a name="index-date-2278"></a></var><br>
+<blockquote><p>Return the date as a character string in the form DD-MMM-YY.  For
+example,
+
+     <pre class="example">          date ()
+                "20-Aug-93"
+</pre>
+        </blockquote></div>
+
+<!-- ./time/etime.m -->
+   <p><a name="doc_002detime"></a>
+
+<div class="defun">
+— Function File:  <b>etime</b> (<var>t1, t2</var>)<var><a name="index-etime-2279"></a></var><br>
+<blockquote><p>Return the difference (in seconds) between two time values returned from
+<code>clock</code>.  For example:
+
+     <pre class="example">          t0 = clock ();
+           many computations later...
+          elapsed_time = etime (clock (), t0);
+</pre>
+        <p class="noindent">will set the variable <code>elapsed_time</code> to the number of seconds since
+the variable <code>t0</code> was set. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtic.html#doc_002dtic">tic</a>, <a href="doc_002dtoc.html#doc_002dtoc">toc</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002dcputime.html#doc_002dcputime">cputime</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dcputime"></a>
+
+<div class="defun">
+— Built-in Function: [<var>total</var>, <var>user</var>, <var>system</var>] = <b>cputime</b> ()<var>;<a name="index-cputime-2280"></a></var><br>
+<blockquote><p>Return the CPU time used by your Octave session.  The first output is
+the total time spent executing your process and is equal to the sum of
+second and third outputs, which are the number of CPU seconds spent
+executing in user mode and the number of CPU seconds spent executing in
+system mode, respectively.  If your system does not have a way to report
+CPU time usage, <code>cputime</code> returns 0 for each of its output values. 
+Note that because Octave used some CPU time to start, it is reasonable
+to check to see if <code>cputime</code> works by checking to see if the total
+CPU time used is nonzero. 
+</p></blockquote></div>
+
+<!-- ./time/is_leap_year.m -->
+   <p><a name="doc_002dis_005fleap_005fyear"></a>
+
+<div class="defun">
+— Function File:  <b>is_leap_year</b> (<var>year</var>)<var><a name="index-is_005fleap_005fyear-2281"></a></var><br>
+<blockquote><p>Return 1 if the given year is a leap year and 0 otherwise.  If no
+arguments are provided, <code>is_leap_year</code> will use the current year. 
+For example,
+
+     <pre class="example">          is_leap_year (2000)
+                1
+</pre>
+        </blockquote></div>
+
+   <p><a name="doc_002dtoc"></a><!-- data.cc -->
+<a name="doc_002dtic"></a>
+
+<div class="defun">
+— Built-in Function:  <b>tic</b> ()<var><a name="index-tic-2282"></a></var><br>
+— Built-in Function:  <b>toc</b> ()<var><a name="index-toc-2283"></a></var><br>
+<blockquote><p>Set or check a wall-clock timer.  Calling <code>tic</code> without an
+output argument sets the timer.  Subsequent calls to <code>toc</code>
+return the number of seconds since the timer was set.  For example,
+
+     <pre class="example">          tic ();
+          # many computations later...
+          elapsed_time = toc ();
+</pre>
+        <p class="noindent">will set the variable <code>elapsed_time</code> to the number of seconds since
+the most recent call to the function <code>tic</code>.
+
+        <p>If called with one output argument then this function returns a scalar
+of type <code>uint64</code> and the wall-clock timer is not started.
+
+     <pre class="example">          t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6
+                5
+</pre>
+        <p>Nested timing with <code>tic</code> and <code>toc</code> is not supported. 
+Therefore <code>toc</code> will always return the elapsed time from the most
+recent call to <code>tic</code>.
+
+        <p>If you are more interested in the CPU time that your process used, you
+should use the <code>cputime</code> function instead.  The <code>tic</code> and
+<code>toc</code> functions report the actual wall clock time that elapsed
+between the calls.  This may include time spent processing other jobs or
+doing nothing at all.  For example,
+
+     <pre class="example">          tic (); sleep (5); toc ()
+                5
+          t = cputime (); sleep (5); cputime () - t
+                0
+</pre>
+        <p class="noindent">(This example also illustrates that the CPU timer may have a fairly
+coarse resolution.) 
+</p></blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dpause"></a>
+
+<div class="defun">
+— Built-in Function:  <b>pause</b> (<var>seconds</var>)<var><a name="index-pause-2284"></a></var><br>
+<blockquote><p>Suspend the execution of the program.  If invoked without any arguments,
+Octave waits until you type a character.  With a numeric argument, it
+pauses for the given number of seconds.  For example, the following
+statement prints a message and then waits 5 seconds before clearing the
+screen.
+
+     <pre class="example">          fprintf (stderr, "wait please...\n");
+          pause (5);
+          clc;
+</pre>
+        </blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dsleep"></a>
+
+<div class="defun">
+— Built-in Function:  <b>sleep</b> (<var>seconds</var>)<var><a name="index-sleep-2285"></a></var><br>
+<blockquote><p>Suspend the execution of the program for the given number of seconds. 
+</p></blockquote></div>
+
+<!-- sysdep.cc -->
+   <p><a name="doc_002dusleep"></a>
+
+<div class="defun">
+— Built-in Function:  <b>usleep</b> (<var>microseconds</var>)<var><a name="index-usleep-2286"></a></var><br>
+<blockquote><p>Suspend the execution of the program for the given number of
+microseconds.  On systems where it is not possible to sleep for periods
+of time less than one second, <code>usleep</code> will pause the execution for
+<code>round (</code><var>microseconds</var><code> / 1e6)</code> seconds. 
+</p></blockquote></div>
+
+<!-- ./time/datenum.m -->
+   <p><a name="doc_002ddatenum"></a>
+
+<div class="defun">
+— Function File:  <b>datenum</b> (<var>year, month, day</var>)<var><a name="index-datenum-2287"></a></var><br>
+— Function File:  <b>datenum</b> (<var>year, month, day, hour</var>)<var><a name="index-datenum-2288"></a></var><br>
+— Function File:  <b>datenum</b> (<var>year, month, day, hour, minute</var>)<var><a name="index-datenum-2289"></a></var><br>
+— Function File:  <b>datenum</b> (<var>year, month, day, hour, minute, second</var>)<var><a name="index-datenum-2290"></a></var><br>
+— Function File:  <b>datenum</b> (<code>"date"</code>)<var><a name="index-datenum-2291"></a></var><br>
+— Function File:  <b>datenum</b> (<code>"date"</code><var>, p</var>)<var><a name="index-datenum-2292"></a></var><br>
+<blockquote><p>Returns the specified local time as a day number, with Jan 1, 0000
+being day 1.  By this reckoning, Jan 1, 1970 is day number 719529. 
+The fractional portion, <var>p</var>, corresponds to the portion of the
+specified day.
+
+        <p>Notes:
+
+          <ul>
+<li>Years can be negative and/or fractional. 
+<li>Months below 1 are considered to be January. 
+<li>Days of the month start at 1. 
+<li>Days beyond the end of the month go into subsequent months. 
+<li>Days before the beginning of the month go to the previous month. 
+<li>Days can be fractional. 
+</ul>
+
+        <p><strong>Warning:</strong> this function does not attempt to handle Julian
+calendars so dates before Octave 15, 1582 are wrong by as much
+as eleven days.  Also be aware that only Roman Catholic countries
+adopted the calendar in 1582.  It took until 1924 for it to be
+adopted everywhere.  See the Wikipedia entry on the Gregorian
+calendar for more details.
+
+        <p><strong>Warning:</strong> leap seconds are ignored.  A table of leap seconds
+is available on the Wikipedia entry for leap seconds. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dcalendar.html#doc_002dcalendar">calendar</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./time/datestr.m -->
+   <p><a name="doc_002ddatestr"></a>
+
+<div class="defun">
+— Function File: <var>str</var> = <b>datestr</b> (<var>date, </var>[<var>f, </var>[<var>p</var>]])<var><a name="index-datestr-2293"></a></var><br>
+<blockquote><p>Format the given date/time according to the format <code>f</code> and return
+the result in <var>str</var>.  <var>date</var> is a serial date number (see
+<code>datenum</code>) or a date vector (see <code>datevec</code>).  The value of
+<var>date</var> may also be a string or cell array of strings.
+
+        <p><var>f</var> can be an integer which corresponds to one of the codes in
+the table below, or a date format string.
+
+        <p><var>p</var> is the year at the start of the century in which two-digit years
+are to be interpreted in.  If not specified, it defaults to the current
+year minus 50.
+
+        <p>For example, the date 730736.65149 (2000-09-07 15:38:09.0934) would be
+formatted as follows:
+
+        <p><table summary=""><tr align="left"><th valign="top" width="10%">Code </th><th valign="top" width="45%">Format </th><th valign="top" width="35%">Example
+<br></th></tr><tr align="left"><td valign="top" width="10%">0 </td><td valign="top" width="45%">dd-mmm-yyyy HH:MM:SS   </td><td valign="top" width="35%">07-Sep-2000 15:38:09
+<br></td></tr><tr align="left"><td valign="top" width="10%">1 </td><td valign="top" width="45%">dd-mmm-yyyy            </td><td valign="top" width="35%">07-Sep-2000
+<br></td></tr><tr align="left"><td valign="top" width="10%">2 </td><td valign="top" width="45%">mm/dd/yy               </td><td valign="top" width="35%">09/07/00
+<br></td></tr><tr align="left"><td valign="top" width="10%">3 </td><td valign="top" width="45%">mmm                    </td><td valign="top" width="35%">Sep
+<br></td></tr><tr align="left"><td valign="top" width="10%">4 </td><td valign="top" width="45%">m                      </td><td valign="top" width="35%">S
+<br></td></tr><tr align="left"><td valign="top" width="10%">5 </td><td valign="top" width="45%">mm                     </td><td valign="top" width="35%">09
+<br></td></tr><tr align="left"><td valign="top" width="10%">6 </td><td valign="top" width="45%">mm/dd                  </td><td valign="top" width="35%">09/07
+<br></td></tr><tr align="left"><td valign="top" width="10%">7 </td><td valign="top" width="45%">dd                     </td><td valign="top" width="35%">07
+<br></td></tr><tr align="left"><td valign="top" width="10%">8 </td><td valign="top" width="45%">ddd                    </td><td valign="top" width="35%">Thu
+<br></td></tr><tr align="left"><td valign="top" width="10%">9 </td><td valign="top" width="45%">d                      </td><td valign="top" width="35%">T
+<br></td></tr><tr align="left"><td valign="top" width="10%">10 </td><td valign="top" width="45%">yyyy                   </td><td valign="top" width="35%">2000
+<br></td></tr><tr align="left"><td valign="top" width="10%">11 </td><td valign="top" width="45%">yy                     </td><td valign="top" width="35%">00
+<br></td></tr><tr align="left"><td valign="top" width="10%">12 </td><td valign="top" width="45%">mmmyy                  </td><td valign="top" width="35%">Sep00
+<br></td></tr><tr align="left"><td valign="top" width="10%">13 </td><td valign="top" width="45%">HH:MM:SS               </td><td valign="top" width="35%">15:38:09
+<br></td></tr><tr align="left"><td valign="top" width="10%">14 </td><td valign="top" width="45%">HH:MM:SS PM            </td><td valign="top" width="35%">03:38:09 PM
+<br></td></tr><tr align="left"><td valign="top" width="10%">15 </td><td valign="top" width="45%">HH:MM                  </td><td valign="top" width="35%">15:38
+<br></td></tr><tr align="left"><td valign="top" width="10%">16 </td><td valign="top" width="45%">HH:MM PM               </td><td valign="top" width="35%">03:38 PM
+<br></td></tr><tr align="left"><td valign="top" width="10%">17 </td><td valign="top" width="45%">QQ-YY                  </td><td valign="top" width="35%">Q3-00
+<br></td></tr><tr align="left"><td valign="top" width="10%">18 </td><td valign="top" width="45%">QQ                     </td><td valign="top" width="35%">Q3
+<br></td></tr><tr align="left"><td valign="top" width="10%">19 </td><td valign="top" width="45%">dd/mm                  </td><td valign="top" width="35%">13/03
+<br></td></tr><tr align="left"><td valign="top" width="10%">20 </td><td valign="top" width="45%">dd/mm/yy               </td><td valign="top" width="35%">13/03/95
+<br></td></tr><tr align="left"><td valign="top" width="10%">21 </td><td valign="top" width="45%">mmm.dd.yyyy HH:MM:SS   </td><td valign="top" width="35%">Mar.03.1962 13:53:06
+<br></td></tr><tr align="left"><td valign="top" width="10%">22 </td><td valign="top" width="45%">mmm.dd.yyyy            </td><td valign="top" width="35%">Mar.03.1962
+<br></td></tr><tr align="left"><td valign="top" width="10%">23 </td><td valign="top" width="45%">mm/dd/yyyy             </td><td valign="top" width="35%">03/13/1962
+<br></td></tr><tr align="left"><td valign="top" width="10%">24 </td><td valign="top" width="45%">dd/mm/yyyy             </td><td valign="top" width="35%">12/03/1962
+<br></td></tr><tr align="left"><td valign="top" width="10%">25 </td><td valign="top" width="45%">yy/mm/dd               </td><td valign="top" width="35%">95/03/13
+<br></td></tr><tr align="left"><td valign="top" width="10%">26 </td><td valign="top" width="45%">yyyy/mm/dd             </td><td valign="top" width="35%">1995/03/13
+<br></td></tr><tr align="left"><td valign="top" width="10%">27 </td><td valign="top" width="45%">QQ-YYYY                </td><td valign="top" width="35%">Q4-2132
+<br></td></tr><tr align="left"><td valign="top" width="10%">28 </td><td valign="top" width="45%">mmmyyyy                </td><td valign="top" width="35%">Mar2047
+<br></td></tr><tr align="left"><td valign="top" width="10%">29 </td><td valign="top" width="45%">yyyymmdd               </td><td valign="top" width="35%">20470313
+<br></td></tr><tr align="left"><td valign="top" width="10%">30 </td><td valign="top" width="45%">yyyymmddTHHMMSS        </td><td valign="top" width="35%">20470313T132603
+<br></td></tr><tr align="left"><td valign="top" width="10%">31 </td><td valign="top" width="45%">yyyy-mm-dd HH:MM:SS    </td><td valign="top" width="35%">1047-03-13 13:26:03
+        <br></td></tr></table>
+
+        <p>If <var>f</var> is a format string, the following symbols are recognized:
+
+        <p><table summary=""><tr align="left"><th valign="top" width="10%">Symbol </th><th valign="top" width="70%">Meaning </th><th valign="top" width="20%">Example
+<br></th></tr><tr align="left"><td valign="top" width="10%">yyyy </td><td valign="top" width="70%">Full year                                    </td><td valign="top" width="20%">2005
+<br></td></tr><tr align="left"><td valign="top" width="10%">yy   </td><td valign="top" width="70%">Two-digit year                               </td><td valign="top" width="20%">2005
+<br></td></tr><tr align="left"><td valign="top" width="10%">mmmm </td><td valign="top" width="70%">Full month name                              </td><td valign="top" width="20%">December
+<br></td></tr><tr align="left"><td valign="top" width="10%">mmm  </td><td valign="top" width="70%">Abbreviated month name                       </td><td valign="top" width="20%">Dec
+<br></td></tr><tr align="left"><td valign="top" width="10%">mm   </td><td valign="top" width="70%">Numeric month number (padded with zeros)     </td><td valign="top" width="20%">01, 08, 12
+<br></td></tr><tr align="left"><td valign="top" width="10%">m    </td><td valign="top" width="70%">First letter of month name (capitalized)     </td><td valign="top" width="20%">D
+<br></td></tr><tr align="left"><td valign="top" width="10%">dddd </td><td valign="top" width="70%">Full weekday name                            </td><td valign="top" width="20%">Sunday
+<br></td></tr><tr align="left"><td valign="top" width="10%">ddd  </td><td valign="top" width="70%">Abbreviated weekday name                     </td><td valign="top" width="20%">Sun
+<br></td></tr><tr align="left"><td valign="top" width="10%">dd   </td><td valign="top" width="70%">Numeric day of month (padded with zeros)     </td><td valign="top" width="20%">11
+<br></td></tr><tr align="left"><td valign="top" width="10%">d    </td><td valign="top" width="70%">First letter of weekday name (capitalized)   </td><td valign="top" width="20%">S
+<br></td></tr><tr align="left"><td valign="top" width="10%">HH   </td><td valign="top" width="70%">Hour of day, padded with zeros if PM is set  </td><td valign="top" width="20%">09:00
+<br></td></tr><tr align="left"><td valign="top" width="10%"></td><td valign="top" width="70%">and not padded with zeros otherwise          </td><td valign="top" width="20%">9:00 AM
+<br></td></tr><tr align="left"><td valign="top" width="10%">MM   </td><td valign="top" width="70%">Minute of hour (padded with zeros)           </td><td valign="top" width="20%">10:05
+<br></td></tr><tr align="left"><td valign="top" width="10%">SS   </td><td valign="top" width="70%">Second of minute (padded with zeros)         </td><td valign="top" width="20%">10:05:03
+<br></td></tr><tr align="left"><td valign="top" width="10%">PM   </td><td valign="top" width="70%">Use 12-hour time format                      </td><td valign="top" width="20%">11:30 PM
+        <br></td></tr></table>
+
+        <p>If <var>f</var> is not specified or is <code>-1</code>, then use 0, 1 or 16,
+depending on whether the date portion or the time portion of
+<var>date</var> is empty.
+
+        <p>If <var>p</var> is nor specified, it defaults to the current year minus 50.
+
+        <p>If a matrix or cell array of dates is given, a vector of date strings is
+returned.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>, <a href="doc_002ddatetick.html#doc_002ddatetick">datetick</a>. 
+</p></blockquote></div>
+
+<!-- ./time/datevec.m -->
+   <p><a name="doc_002ddatevec"></a>
+
+<div class="defun">
+— Function File: <var>v</var> = <b>datevec</b> (<var>date</var>)<var><a name="index-datevec-2294"></a></var><br>
+— Function File: <var>v</var> = <b>datevec</b> (<var>date, f</var>)<var><a name="index-datevec-2295"></a></var><br>
+— Function File: <var>v</var> = <b>datevec</b> (<var>date, p</var>)<var><a name="index-datevec-2296"></a></var><br>
+— Function File: <var>v</var> = <b>datevec</b> (<var>date, f, p</var>)<var><a name="index-datevec-2297"></a></var><br>
+— Function File: [<var>y</var>, <var>m</var>, <var>d</var>, <var>h</var>, <var>mi</var>, <var>s</var>] = <b>datevec</b> (<var><small class="dots">...</small></var>)<var><a name="index-datevec-2298"></a></var><br>
+<blockquote><p>Convert a serial date number (see <code>datenum</code>) or date string (see
+<code>datestr</code>) into a date vector.
+
+        <p>A date vector is a row vector with six members, representing the year,
+month, day, hour, minute, and seconds respectively.
+
+        <p><var>f</var> is the format string used to interpret date strings
+(see <code>datestr</code>).
+
+        <p><var>p</var> is the year at the start of the century in which two-digit years
+are to be interpreted in.  If not specified, it defaults to the current
+year minus 50. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>, <a href="doc_002ddate.html#doc_002ddate">date</a>, <a href="doc_002dclock.html#doc_002dclock">clock</a>, <a href="doc_002dnow.html#doc_002dnow">now</a>. 
+</p></blockquote></div>
+
+<!-- ./time/addtodate.m -->
+   <p><a name="doc_002daddtodate"></a>
+
+<div class="defun">
+— Function File: <var>d</var> = <b>addtodate</b> (<var>d, q, f</var>)<var><a name="index-addtodate-2299"></a></var><br>
+<blockquote><p>Add <var>q</var> amount of time (with units <var>f</var>) to the datenum, <var>d</var>.
+
+        <p><var>f</var> must be one of "year", "month", "day", "hour", "minute", or
+"second". 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>. 
+</p></blockquote></div>
+
+<!-- ./time/calendar.m -->
+   <p><a name="doc_002dcalendar"></a>
+
+<div class="defun">
+— Function File:  <b>calendar</b> (<var><small class="dots">...</small></var>)<var><a name="index-calendar-2300"></a></var><br>
+— Function File: <var>c</var> = <b>calendar</b> ()<var><a name="index-calendar-2301"></a></var><br>
+— Function File: <var>c</var> = <b>calendar</b> (<var>d</var>)<var><a name="index-calendar-2302"></a></var><br>
+— Function File: <var>c</var> = <b>calendar</b> (<var>y, m</var>)<var><a name="index-calendar-2303"></a></var><br>
+<blockquote><p>If called with no arguments, return the current monthly calendar in
+a 6x7 matrix.
+
+        <p>If <var>d</var> is specified, return the calendar for the month containing
+the day <var>d</var>, which must be a serial date number or a date string.
+
+        <p>If <var>y</var> and <var>m</var> are specified, return the calendar for year <var>y</var>
+and month <var>m</var>.
+
+        <p>If no output arguments are specified, print the calendar on the screen
+instead of returning a matrix. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>. 
+</p></blockquote></div>
+
+<!-- ./time/weekday.m -->
+   <p><a name="doc_002dweekday"></a>
+
+<div class="defun">
+— Function File: [<var>n</var>, <var>s</var>] = <b>weekday</b> (<var>d, </var>[<var>form</var>])<var><a name="index-weekday-2304"></a></var><br>
+<blockquote><p>Return the day of week as a number in <var>n</var> and a string in <var>s</var>,
+for example <code>[1, "Sun"]</code>, <code>[2, "Mon"]</code>, <small class="dots">...</small>, or
+<code>[7, "Sat"]</code>.
+
+        <p><var>d</var> is a serial date number or a date string.
+
+        <p>If the string <var>form</var> is given and is <code>"long"</code>, <var>s</var> will
+contain the full name of the weekday; otherwise (or if <var>form</var> is
+<code>"short"</code>), <var>s</var> will contain the abbreviated name of the weekday. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002deomday.html#doc_002deomday">eomday</a>. 
+</p></blockquote></div>
+
+<!-- ./time/eomday.m -->
+   <p><a name="doc_002deomday"></a>
+
+<div class="defun">
+— Function File: <var>e</var> = <b>eomday</b> (<var>y, m</var>)<var><a name="index-eomday-2305"></a></var><br>
+<blockquote><p>Return the last day of the month <var>m</var> for the year <var>y</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatevec.html#doc_002ddatevec">datevec</a>, <a href="doc_002dweekday.html#doc_002dweekday">weekday</a>. 
+</p></blockquote></div>
+
+<!-- ./time/datetick.m -->
+   <p><a name="doc_002ddatetick"></a>
+
+<div class="defun">
+— Function File:  <b>datetick</b> (<var>form</var>)<var><a name="index-datetick-2306"></a></var><br>
+— Function File:  <b>datetick</b> (<var>axis, form</var>)<var><a name="index-datetick-2307"></a></var><br>
+— Function File:  <b>datetick</b> (<var><small class="dots">...</small>, "keeplimits"</var>)<var><a name="index-datetick-2308"></a></var><br>
+— Function File:  <b>datetick</b> (<var><small class="dots">...</small>, "keepticks"</var>)<var><a name="index-datetick-2309"></a></var><br>
+— Function File:  <b>datetick</b> (<var><small class="dots">...</small>ax, <small class="dots">...</small></var>)<var><a name="index-datetick-2310"></a></var><br>
+<blockquote><p>Adds date formatted tick labels to an axis.  The axis the apply the
+ticks to is determined by <var>axis</var> that can take the values "x",
+"y" or "z".  The default value is "x".  The formatting of the labels is
+determined by the variable <var>form</var>, that can either be a string in
+the format needed by <code>dateform</code>, or a positive integer that can
+be accepted by <code>datestr</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddatenum.html#doc_002ddatenum">datenum</a>, <a href="doc_002ddatestr.html#doc_002ddatestr">datestr</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Tips-and-Standards.html b/doc/interpreter/HTML/Tips-and-Standards.html
new file mode 100644
index 0000000..955b824
--- /dev/null
+++ b/doc/interpreter/HTML/Tips-and-Standards.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Tips and Standards - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions" title="Test and Demo Functions">
+<link rel="next" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Tips-and-Standards"></a>
+Next: <a rel="next" accesskey="n" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>,
+Previous: <a rel="previous" accesskey="p" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix C Tips and Standards</h2>
+
+<p><a name="index-tips-2505"></a><a name="index-standards-of-coding-style-2506"></a><a name="index-coding-standards-2507"></a>
+This chapter describes no additional features of Octave.  Instead it
+gives advice on making effective use of the features described in the
+previous chapters.
+
+<ul class="menu">
+<li><a accesskey="1" href="Style-Tips.html#Style-Tips">Style Tips</a>:                   Writing clean and robust programs. 
+<li><a accesskey="2" href="Coding-Tips.html#Coding-Tips">Coding Tips</a>:                  Making code run faster. 
+<li><a accesskey="3" href="Comment-Tips.html#Comment-Tips">Comment Tips</a>:                 Conventions for writing comments. 
+<li><a accesskey="4" href="Function-Headers.html#Function-Headers">Function Headers</a>:             Standard headers for functions. 
+<li><a accesskey="5" href="Documentation-Tips.html#Documentation-Tips">Documentation Tips</a>:           Writing readable documentation strings. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Trigonometry.html b/doc/interpreter/HTML/Trigonometry.html
new file mode 100644
index 0000000..64b884f
--- /dev/null
+++ b/doc/interpreter/HTML/Trigonometry.html
@@ -0,0 +1,539 @@
+<html lang="en">
+<head>
+<title>Trigonometry - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Complex-Arithmetic.html#Complex-Arithmetic" title="Complex Arithmetic">
+<link rel="next" href="Sums-and-Products.html#Sums-and-Products" title="Sums and Products">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Trigonometry"></a>
+Next: <a rel="next" accesskey="n" href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a>,
+Previous: <a rel="previous" accesskey="p" href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.3 Trigonometry</h3>
+
+<p>Octave provides the following trigonometric functions where angles are
+specified in radians.  To convert from degrees to radians multiply by
+<code>pi/180</code>
+(e.g., <code>sin (30 * pi/180)</code> returns the sine of 30 degrees).  As
+an alternative, Octave provides a number of trigonometric functions
+which work directly on an argument specified in degrees.  These functions
+are named after the base trigonometric function with a ‘<samp><span class="samp">d</span></samp>’ suffix.  For
+example, <code>sin</code> expects an angle in radians while <code>sind</code> expects an
+angle in degrees.
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dsin"></a>
+
+<div class="defun">
+— Mapping Function:  <b>sin</b> (<var>x</var>)<var><a name="index-sin-1385"></a></var><br>
+<blockquote><p>Compute the sine for each element of <var>x</var> in radians. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dasin.html#doc_002dasin">asin</a>, <a href="doc_002dsind.html#doc_002dsind">sind</a>, <a href="doc_002dsinh.html#doc_002dsinh">sinh</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dcos"></a>
+
+<div class="defun">
+— Mapping Function:  <b>cos</b> (<var>x</var>)<var><a name="index-cos-1386"></a></var><br>
+<blockquote><p>Compute the cosine for each element of <var>x</var> in radians. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacos.html#doc_002dacos">acos</a>, <a href="doc_002dcosd.html#doc_002dcosd">cosd</a>, <a href="doc_002dcosh.html#doc_002dcosh">cosh</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dtan"></a>
+
+<div class="defun">
+— Mapping Function:  <b>tan</b> (<var>z</var>)<var><a name="index-tan-1387"></a></var><br>
+<blockquote><p>Compute the tangent for each element of <var>x</var> in radians. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002datan.html#doc_002datan">atan</a>, <a href="doc_002dtand.html#doc_002dtand">tand</a>, <a href="doc_002dtanh.html#doc_002dtanh">tanh</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/sec.m -->
+   <p><a name="doc_002dsec"></a>
+
+<div class="defun">
+— Mapping Function:  <b>sec</b> (<var>x</var>)<var><a name="index-sec-1388"></a></var><br>
+<blockquote><p>Compute the secant for each element of <var>x</var> in radians. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dasec.html#doc_002dasec">asec</a>, <a href="doc_002dsecd.html#doc_002dsecd">secd</a>, <a href="doc_002dsech.html#doc_002dsech">sech</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/csc.m -->
+   <p><a name="doc_002dcsc"></a>
+
+<div class="defun">
+— Mapping Function:  <b>csc</b> (<var>x</var>)<var><a name="index-csc-1389"></a></var><br>
+<blockquote><p>Compute the cosecant for each element of <var>x</var> in radians. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacsc.html#doc_002dacsc">acsc</a>, <a href="doc_002dcscd.html#doc_002dcscd">cscd</a>, <a href="doc_002dcsch.html#doc_002dcsch">csch</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/cot.m -->
+   <p><a name="doc_002dcot"></a>
+
+<div class="defun">
+— Mapping Function:  <b>cot</b> (<var>x</var>)<var><a name="index-cot-1390"></a></var><br>
+<blockquote><p>Compute the cotangent for each element of <var>x</var> in radians. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacot.html#doc_002dacot">acot</a>, <a href="doc_002dcotd.html#doc_002dcotd">cotd</a>, <a href="doc_002dcoth.html#doc_002dcoth">coth</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dasin"></a>
+
+<div class="defun">
+— Mapping Function:  <b>asin</b> (<var>x</var>)<var><a name="index-asin-1391"></a></var><br>
+<blockquote><p>Compute the inverse sine in radians for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsin.html#doc_002dsin">sin</a>, <a href="doc_002dasind.html#doc_002dasind">asind</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dacos"></a>
+
+<div class="defun">
+— Mapping Function:  <b>acos</b> (<var>x</var>)<var><a name="index-acos-1392"></a></var><br>
+<blockquote><p>Compute the inverse cosine in radians for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcos.html#doc_002dcos">cos</a>, <a href="doc_002dacosd.html#doc_002dacosd">acosd</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002datan"></a>
+
+<div class="defun">
+— Mapping Function:  <b>atan</b> (<var>x</var>)<var><a name="index-atan-1393"></a></var><br>
+<blockquote><p>Compute the inverse tangent in radians for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtan.html#doc_002dtan">tan</a>, <a href="doc_002datand.html#doc_002datand">atand</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/asec.m -->
+   <p><a name="doc_002dasec"></a>
+
+<div class="defun">
+— Mapping Function:  <b>asec</b> (<var>x</var>)<var><a name="index-asec-1394"></a></var><br>
+<blockquote><p>Compute the inverse secant in radians for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsec.html#doc_002dsec">sec</a>, <a href="doc_002dasecd.html#doc_002dasecd">asecd</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acsc.m -->
+   <p><a name="doc_002dacsc"></a>
+
+<div class="defun">
+— Mapping Function:  <b>acsc</b> (<var>x</var>)<var><a name="index-acsc-1395"></a></var><br>
+<blockquote><p>Compute the inverse cosecant in radians for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcsc.html#doc_002dcsc">csc</a>, <a href="doc_002dacscd.html#doc_002dacscd">acscd</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acot.m -->
+   <p><a name="doc_002dacot"></a>
+
+<div class="defun">
+— Mapping Function:  <b>acot</b> (<var>x</var>)<var><a name="index-acot-1396"></a></var><br>
+<blockquote><p>Compute the inverse cotangent in radians for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcot.html#doc_002dcot">cot</a>, <a href="doc_002dacotd.html#doc_002dacotd">acotd</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dsinh"></a>
+
+<div class="defun">
+— Mapping Function:  <b>sinh</b> (<var>x</var>)<var><a name="index-sinh-1397"></a></var><br>
+<blockquote><p>Compute the hyperbolic sine for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dasinh.html#doc_002dasinh">asinh</a>, <a href="doc_002dcosh.html#doc_002dcosh">cosh</a>, <a href="doc_002dtanh.html#doc_002dtanh">tanh</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dcosh"></a>
+
+<div class="defun">
+— Mapping Function:  <b>cosh</b> (<var>x</var>)<var><a name="index-cosh-1398"></a></var><br>
+<blockquote><p>Compute the hyperbolic cosine for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacosh.html#doc_002dacosh">acosh</a>, <a href="doc_002dsinh.html#doc_002dsinh">sinh</a>, <a href="doc_002dtanh.html#doc_002dtanh">tanh</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dtanh"></a>
+
+<div class="defun">
+— Mapping Function:  <b>tanh</b> (<var>x</var>)<var><a name="index-tanh-1399"></a></var><br>
+<blockquote><p>Compute hyperbolic tangent for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002datanh.html#doc_002datanh">atanh</a>, <a href="doc_002dsinh.html#doc_002dsinh">sinh</a>, <a href="doc_002dcosh.html#doc_002dcosh">cosh</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/sech.m -->
+   <p><a name="doc_002dsech"></a>
+
+<div class="defun">
+— Mapping Function:  <b>sech</b> (<var>x</var>)<var><a name="index-sech-1400"></a></var><br>
+<blockquote><p>Compute the hyperbolic secant of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dasech.html#doc_002dasech">asech</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/csch.m -->
+   <p><a name="doc_002dcsch"></a>
+
+<div class="defun">
+— Mapping Function:  <b>csch</b> (<var>x</var>)<var><a name="index-csch-1401"></a></var><br>
+<blockquote><p>Compute the hyperbolic cosecant of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacsch.html#doc_002dacsch">acsch</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/coth.m -->
+   <p><a name="doc_002dcoth"></a>
+
+<div class="defun">
+— Mapping Function:  <b>coth</b> (<var>x</var>)<var><a name="index-coth-1402"></a></var><br>
+<blockquote><p>Compute the hyperbolic cotangent of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacoth.html#doc_002dacoth">acoth</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dasinh"></a>
+
+<div class="defun">
+— Mapping Function:  <b>asinh</b> (<var>x</var>)<var><a name="index-asinh-1403"></a></var><br>
+<blockquote><p>Compute the inverse hyperbolic sine for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsinh.html#doc_002dsinh">sinh</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dacosh"></a>
+
+<div class="defun">
+— Mapping Function:  <b>acosh</b> (<var>x</var>)<var><a name="index-acosh-1404"></a></var><br>
+<blockquote><p>Compute the inverse hyperbolic cosine for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcosh.html#doc_002dcosh">cosh</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002datanh"></a>
+
+<div class="defun">
+— Mapping Function:  <b>atanh</b> (<var>x</var>)<var><a name="index-atanh-1405"></a></var><br>
+<blockquote><p>Compute the inverse hyperbolic tangent for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtanh.html#doc_002dtanh">tanh</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/asech.m -->
+   <p><a name="doc_002dasech"></a>
+
+<div class="defun">
+— Mapping Function:  <b>asech</b> (<var>x</var>)<var><a name="index-asech-1406"></a></var><br>
+<blockquote><p>Compute the inverse hyperbolic secant of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsech.html#doc_002dsech">sech</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acsch.m -->
+   <p><a name="doc_002dacsch"></a>
+
+<div class="defun">
+— Mapping Function:  <b>acsch</b> (<var>x</var>)<var><a name="index-acsch-1407"></a></var><br>
+<blockquote><p>Compute the inverse hyperbolic cosecant of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcsch.html#doc_002dcsch">csch</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acoth.m -->
+   <p><a name="doc_002dacoth"></a>
+
+<div class="defun">
+— Mapping Function:  <b>acoth</b> (<var>x</var>)<var><a name="index-acoth-1408"></a></var><br>
+<blockquote><p>Compute the inverse hyperbolic cotangent of each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcoth.html#doc_002dcoth">coth</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002datan2"></a>
+
+<div class="defun">
+— Mapping Function:  <b>atan2</b> (<var>y, x</var>)<var><a name="index-atan2-1409"></a></var><br>
+<blockquote><p>Compute atan (<var>y</var> / <var>x</var>) for corresponding elements of <var>y</var>
+and <var>x</var>.  Signal an error if <var>y</var> and <var>x</var> do not match in size
+and orientation. 
+</p></blockquote></div>
+
+   <p>Octave provides the following trigonometric functions where angles are
+specified in degrees.  These functions produce true zeros at the appropriate
+intervals rather than the small roundoff error that occurs when using
+radians.  For example:
+<pre class="example">     cosd (90)
+           0
+     cos (pi/2)
+           6.1230e-17
+</pre>
+   <!-- ./elfun/sind.m -->
+   <p><a name="doc_002dsind"></a>
+
+<div class="defun">
+— Function File:  <b>sind</b> (<var>x</var>)<var><a name="index-sind-1410"></a></var><br>
+<blockquote><p>Compute the sine for each element of <var>x</var> in degrees.  Returns zero
+for elements where <var>x</var><code>/180</code> is an integer. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dasind.html#doc_002dasind">asind</a>, <a href="doc_002dsin.html#doc_002dsin">sin</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/cosd.m -->
+   <p><a name="doc_002dcosd"></a>
+
+<div class="defun">
+— Function File:  <b>cosd</b> (<var>x</var>)<var><a name="index-cosd-1411"></a></var><br>
+<blockquote><p>Compute the cosine for each element of <var>x</var> in degrees.  Returns zero
+for elements where <code>(</code><var>x</var><code>-90)/180</code> is an integer. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacosd.html#doc_002dacosd">acosd</a>, <a href="doc_002dcos.html#doc_002dcos">cos</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/tand.m -->
+   <p><a name="doc_002dtand"></a>
+
+<div class="defun">
+— Function File:  <b>tand</b> (<var>x</var>)<var><a name="index-tand-1412"></a></var><br>
+<blockquote><p>Compute the tangent for each element of <var>x</var> in degrees.  Returns zero
+for elements where <var>x</var><code>/180</code> is an integer and <code>Inf</code> for
+elements where <code>(</code><var>x</var><code>-90)/180</code> is an integer. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002datand.html#doc_002datand">atand</a>, <a href="doc_002dtan.html#doc_002dtan">tan</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/secd.m -->
+   <p><a name="doc_002dsecd"></a>
+
+<div class="defun">
+— Function File:  <b>secd</b> (<var>x</var>)<var><a name="index-secd-1413"></a></var><br>
+<blockquote><p>Compute the secant for each element of <var>x</var> in degrees. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dasecd.html#doc_002dasecd">asecd</a>, <a href="doc_002dsec.html#doc_002dsec">sec</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/cscd.m -->
+   <p><a name="doc_002dcscd"></a>
+
+<div class="defun">
+— Function File:  <b>cscd</b> (<var>x</var>)<var><a name="index-cscd-1414"></a></var><br>
+<blockquote><p>Compute the cosecant for each element of <var>x</var> in degrees. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacscd.html#doc_002dacscd">acscd</a>, <a href="doc_002dcsc.html#doc_002dcsc">csc</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/cotd.m -->
+   <p><a name="doc_002dcotd"></a>
+
+<div class="defun">
+— Function File:  <b>cotd</b> (<var>x</var>)<var><a name="index-cotd-1415"></a></var><br>
+<blockquote><p>Compute the cotangent for each element of <var>x</var> in degrees. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dacotd.html#doc_002dacotd">acotd</a>, <a href="doc_002dcot.html#doc_002dcot">cot</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/asind.m -->
+   <p><a name="doc_002dasind"></a>
+
+<div class="defun">
+— Function File:  <b>asind</b> (<var>x</var>)<var><a name="index-asind-1416"></a></var><br>
+<blockquote><p>Compute the inverse sine in degrees for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsind.html#doc_002dsind">sind</a>, <a href="doc_002dasin.html#doc_002dasin">asin</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acosd.m -->
+   <p><a name="doc_002dacosd"></a>
+
+<div class="defun">
+— Function File:  <b>acosd</b> (<var>x</var>)<var><a name="index-acosd-1417"></a></var><br>
+<blockquote><p>Compute the inverse cosine in degrees for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcosd.html#doc_002dcosd">cosd</a>, <a href="doc_002dacos.html#doc_002dacos">acos</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/atand.m -->
+   <p><a name="doc_002datand"></a>
+
+<div class="defun">
+— Function File:  <b>atand</b> (<var>x</var>)<var><a name="index-atand-1418"></a></var><br>
+<blockquote><p>Compute the inverse tangent in degrees for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dtand.html#doc_002dtand">tand</a>, <a href="doc_002datan.html#doc_002datan">atan</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/asecd.m -->
+   <p><a name="doc_002dasecd"></a>
+
+<div class="defun">
+— Function File:  <b>asecd</b> (<var>x</var>)<var><a name="index-asecd-1419"></a></var><br>
+<blockquote><p>Compute the inverse secant in degrees for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsecd.html#doc_002dsecd">secd</a>, <a href="doc_002dasec.html#doc_002dasec">asec</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acscd.m -->
+   <p><a name="doc_002dacscd"></a>
+
+<div class="defun">
+— Function File:  <b>acscd</b> (<var>x</var>)<var><a name="index-acscd-1420"></a></var><br>
+<blockquote><p>Compute the inverse cosecant in degrees for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcscd.html#doc_002dcscd">cscd</a>, <a href="doc_002dacsc.html#doc_002dacsc">acsc</a>. 
+</p></blockquote></div>
+
+<!-- ./elfun/acotd.m -->
+   <p><a name="doc_002dacotd"></a>
+
+<div class="defun">
+— Function File:  <b>acotd</b> (<var>x</var>)<var><a name="index-acotd-1421"></a></var><br>
+<blockquote><p>Compute the inverse cotangent in degrees for each element of <var>x</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcotd.html#doc_002dcotd">cotd</a>, <a href="doc_002dacot.html#doc_002dacot">acot</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Trouble.html b/doc/interpreter/HTML/Trouble.html
new file mode 100644
index 0000000..e3b1d7b
--- /dev/null
+++ b/doc/interpreter/HTML/Trouble.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Trouble - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Contributing-Guidelines.html#Contributing-Guidelines" title="Contributing Guidelines">
+<link rel="next" href="Installation.html#Installation" title="Installation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Trouble"></a>
+Next: <a rel="next" accesskey="n" href="Installation.html#Installation">Installation</a>,
+Previous: <a rel="previous" accesskey="p" href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="appendix">Appendix E Known Causes of Trouble</h2>
+
+   <p><a name="index-bugs_002c-known-2513"></a><a name="index-installation-trouble-2514"></a><a name="index-known-causes-of-trouble-2515"></a><a name="index-troubleshooting-2516"></a>
+This section describes known problems that affect users of Octave.  Most
+of these are not Octave bugs per se—if they were, we would fix them. 
+But the result for a user may be like the result of a bug.
+
+   <p>Some of these problems are due to bugs in other software, some are
+missing features that are too much work to add, and some are places
+where people's opinions differ as to what is best.
+
+<ul class="menu">
+<li><a accesskey="1" href="Actual-Bugs.html#Actual-Bugs">Actual Bugs</a>:                  Bugs we will fix later. 
+<li><a accesskey="2" href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a>
+<li><a accesskey="3" href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a>
+<li><a accesskey="4" href="Bug-Lists.html#Bug-Lists">Bug Lists</a>
+<li><a accesskey="5" href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a>
+<li><a accesskey="6" href="Sending-Patches.html#Sending-Patches">Sending Patches</a>
+<li><a accesskey="7" href="Service.html#Service">Service</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Two_002dDimensional-Plots.html b/doc/interpreter/HTML/Two_002dDimensional-Plots.html
new file mode 100644
index 0000000..b537854
--- /dev/null
+++ b/doc/interpreter/HTML/Two_002dDimensional-Plots.html
@@ -0,0 +1,1420 @@
+<html lang="en">
+<head>
+<title>Two-Dimensional Plots - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Plotting-Basics.html#Plotting-Basics" title="Plotting Basics">
+<link rel="next" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting" title="Three-Dimensional Plotting">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Two-Dimensional-Plots"></a>
+<a name="Two_002dDimensional-Plots"></a>
+Next: <a rel="next" accesskey="n" href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a>,
+Up: <a rel="up" accesskey="u" href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<hr>
+</div>
+
+<h4 class="subsection">15.1.1 Two-Dimensional Plots</h4>
+
+<p>The <code>plot</code> function allows you to create simple x-y plots with
+linear axes.  For example,
+
+<pre class="example">     x = -10:0.1:10;
+     plot (x, sin (x));
+</pre>
+   <p class="noindent">displays a sine wave shown in <a href="fig_003aplot.html#fig_003aplot">fig:plot</a>.  On most systems, this
+command will open a separate plot window to display the graph.
+
+   <div class="float">
+<a name="fig_003aplot"></a><div align="center"><img src="plot.png" alt="plot.png"></div>
+   <p><strong class="float-caption">Figure 15.1: Simple Two-Dimensional Plot.</strong></p></div>
+
+<!-- ./plot/plot.m -->
+   <p><a name="doc_002dplot"></a>
+
+<div class="defun">
+— Function File:  <b>plot</b> (<var>y</var>)<var><a name="index-plot-817"></a></var><br>
+— Function File:  <b>plot</b> (<var>x, y</var>)<var><a name="index-plot-818"></a></var><br>
+— Function File:  <b>plot</b> (<var>x, y, property, value, <small class="dots">...</small></var>)<var><a name="index-plot-819"></a></var><br>
+— Function File:  <b>plot</b> (<var>x, y, fmt</var>)<var><a name="index-plot-820"></a></var><br>
+— Function File:  <b>plot</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-plot-821"></a></var><br>
+<blockquote><p>Produces two-dimensional plots.  Many different combinations of
+arguments are possible.  The simplest form is
+
+     <pre class="example">          plot (<var>y</var>)
+</pre>
+        <p class="noindent">where the argument is taken as the set of <var>y</var> coordinates and the
+<var>x</var> coordinates are taken to be the indices of the elements,
+starting with 1.
+
+        <p>To save a plot, in one of several image formats such as PostScript
+or PNG, use the <code>print</code> command.
+
+        <p>If more than one argument is given, they are interpreted as
+
+     <pre class="example">          plot (<var>y</var>, <var>property</var>, <var>value</var>, ...)
+</pre>
+        <p class="noindent">or
+
+     <pre class="example">          plot (<var>x</var>, <var>y</var>, <var>property</var>, <var>value</var>, ...)
+</pre>
+        <p class="noindent">or
+
+     <pre class="example">          plot (<var>x</var>, <var>y</var>, <var>fmt</var>, ...)
+</pre>
+        <p class="noindent">and so on.  Any number of argument sets may appear.  The <var>x</var> and
+<var>y</var> values are interpreted as follows:
+
+          <ul>
+<li>If a single data argument is supplied, it is taken as the set of <var>y</var>
+coordinates and the <var>x</var> coordinates are taken to be the indices of
+the elements, starting with 1.
+
+          <li>If the <var>x</var> is a vector and <var>y</var> is a matrix, then
+the columns (or rows) of <var>y</var> are plotted versus <var>x</var>. 
+(using whichever combination matches, with columns tried first.)
+
+          <li>If the <var>x</var> is a matrix and <var>y</var> is a vector,
+<var>y</var> is plotted versus the columns (or rows) of <var>x</var>. 
+(using whichever combination matches, with columns tried first.)
+
+          <li>If both arguments are vectors, the elements of <var>y</var> are plotted versus
+the elements of <var>x</var>.
+
+          <li>If both arguments are matrices, the columns of <var>y</var> are plotted
+versus the columns of <var>x</var>.  In this case, both matrices must have
+the same number of rows and columns and no attempt is made to transpose
+the arguments to make the number of rows match.
+
+          <p>If both arguments are scalars, a single point is plotted. 
+</ul>
+
+        <p>Multiple property-value pairs may be specified, but they must appear
+in pairs.  These arguments are applied to the lines drawn by
+<code>plot</code>.
+
+        <p>If the <var>fmt</var> argument is supplied, it is interpreted as
+follows.  If <var>fmt</var> is missing, the default gnuplot line style
+is assumed.
+
+          <dl>
+<dt>‘<samp><span class="samp">-</span></samp>’<dd>Set lines plot style (default).
+
+          <br><dt>‘<samp><span class="samp">.</span></samp>’<dd>Set dots plot style.
+
+          <br><dt>‘<samp><var>n</var></samp>’<dd>Interpreted as the plot color if <var>n</var> is an integer in the range 1 to
+6.
+
+          <br><dt>‘<samp><var>nm</var></samp>’<dd>If <var>nm</var> is a two digit integer and <var>m</var> is an integer in the
+range 1 to 6, <var>m</var> is interpreted as the point style.  This is only
+valid in combination with the <code>@</code> or <code>-@</code> specifiers.
+
+          <br><dt>‘<samp><var>c</var></samp>’<dd>If <var>c</var> is one of <code>"k"</code> (black), <code>"r"</code> (red), <code>"g"</code>
+(green), <code>"b"</code> (blue), <code>"m"</code> (magenta), <code>"c"</code> (cyan),
+or <code>"w"</code> (white), it is interpreted as the line plot color.
+
+          <br><dt>‘<samp><span class="samp">";title;"</span></samp>’<dd>Here <code>"title"</code> is the label for the key.
+
+          <br><dt>‘<samp><span class="samp">+</span></samp>’<dt>‘<samp><span class="samp">*</span></samp>’<dt>‘<samp><span class="samp">o</span></samp>’<dt>‘<samp><span class="samp">x</span></samp>’<dt>‘<samp><span class="samp">^</span></samp>’<dd>Used in combination with the points or linespoints styles, set the point
+style. 
+</dl>
+
+        <p>The <var>fmt</var> argument may also be used to assign key titles. 
+To do so, include the desired title between semi-colons after the
+formatting sequence described above, e.g., "+3;Key Title;"
+Note that the last semi-colon is required and will generate an error if
+it is left out.
+
+        <p>Here are some plot examples:
+
+     <pre class="example">          plot (x, y, "@12", x, y2, x, y3, "4", x, y4, "+")
+</pre>
+        <p>This command will plot <code>y</code> with points of type 2 (displayed as
+‘<samp><span class="samp">+</span></samp>’) and color 1 (red), <code>y2</code> with lines, <code>y3</code> with lines of
+color 4 (magenta) and <code>y4</code> with points displayed as ‘<samp><span class="samp">+</span></samp>’.
+
+     <pre class="example">          plot (b, "*", "markersize", 3)
+</pre>
+        <p>This command will plot the data in the variable <code>b</code>,
+with points displayed as ‘<samp><span class="samp">*</span></samp>’ with a marker size of 3.
+
+     <pre class="example">          t = 0:0.1:6.3;
+          plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+</pre>
+        <p>This will plot the cosine and sine functions and label them accordingly
+in the key.
+
+        <p>If the first argument is an axis handle, then plot into these axes,
+rather than the current axis handle returned by <code>gca</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsemilogx.html#doc_002dsemilogx">semilogx</a>, <a href="doc_002dsemilogy.html#doc_002dsemilogy">semilogy</a>, <a href="doc_002dloglog.html#doc_002dloglog">loglog</a>, <a href="doc_002dpolar.html#doc_002dpolar">polar</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>, <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dstairs.html#doc_002dstairs">stairs</a>, <a href="doc_002derrorbar.html#doc_002derrorbar">errorbar</a>, <a href="doc_002dxlabel.html#doc_002dxlabel">xlabel</a>, <a href="doc_002dylabel.html#doc_002dylabel">ylabel</a>, <a href="doc_002dtitle.html#doc_002dtitle">title</a>, <a href="doc_002dprint.html#doc_002dprint">print</a>. 
+</p></blockquote></div>
+
+   <p>The <code>plotyy</code> function may be used to create a plot with two
+independent y axes.
+
+<!-- ./plot/plotyy.m -->
+   <p><a name="doc_002dplotyy"></a>
+
+<div class="defun">
+— Function File:  <b>plotyy</b> (<var>x1, y1, x2, y2</var>)<var><a name="index-plotyy-822"></a></var><br>
+— Function File:  <b>plotyy</b> (<var><small class="dots">...</small>, fun</var>)<var><a name="index-plotyy-823"></a></var><br>
+— Function File:  <b>plotyy</b> (<var><small class="dots">...</small>, fun1, fun2</var>)<var><a name="index-plotyy-824"></a></var><br>
+— Function File:  <b>plotyy</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-plotyy-825"></a></var><br>
+— Function File: [<var>ax</var>, <var>h1</var>, <var>h2</var>] = <b>plotyy</b> (<var><small class="dots">...</small></var>)<var><a name="index-plotyy-826"></a></var><br>
+<blockquote><p>Plots two sets of data with independent y-axes.  The arguments <var>x1</var> and
+<var>y1</var> define the arguments for the first plot and <var>x1</var> and <var>y2</var>
+for the second.
+
+        <p>By default the arguments are evaluated with
+<code>feval (@plot, </code><var>x</var><code>, </code><var>y</var><code>)</code>.  However the type of plot can be
+modified with the <var>fun</var> argument, in which case the plots are
+generated by <code>feval (</code><var>fun</var><code>, </code><var>x</var><code>, </code><var>y</var><code>)</code>.  <var>fun</var> can be
+a function handle, an inline function or a string of a function name.
+
+        <p>The function to use for each of the plots can be independently defined
+with <var>fun1</var> and <var>fun2</var>.
+
+        <p>If given, <var>h</var> defines the principal axis in which to plot the <var>x1</var>
+and <var>y1</var> data.  The return value <var>ax</var> is a two element vector with
+the axis handles of the two plots.  <var>h1</var> and <var>h2</var> are handles to
+the objects generated by the plot commands.
+
+     <pre class="example">          x = 0:0.1:2*pi;
+          y1 = sin (x);
+          y2 = exp (x - 1);
+          ax = plotyy (x, y1, x - 1, y2, @plot, @semilogy);
+          xlabel ("X");
+          ylabel (ax(1), "Axis 1");
+          ylabel (ax(2), "Axis 2");
+</pre>
+        </blockquote></div>
+
+   <p>The functions <code>semilogx</code>, <code>semilogy</code>, and <code>loglog</code> are
+similar to the <code>plot</code> function, but produce plots in which one or
+both of the axes use log scales.
+
+<!-- ./plot/semilogx.m -->
+   <p><a name="doc_002dsemilogx"></a>
+
+<div class="defun">
+— Function File:  <b>semilogx</b> (<var>args</var>)<var><a name="index-semilogx-827"></a></var><br>
+<blockquote><p>Produce a two-dimensional plot using a log scale for the <var>x</var>
+axis.  See the description of <code>plot</code> for a description of the
+arguments that <code>semilogx</code> will accept. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dsemilogy.html#doc_002dsemilogy">semilogy</a>, <a href="doc_002dloglog.html#doc_002dloglog">loglog</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/semilogy.m -->
+   <p><a name="doc_002dsemilogy"></a>
+
+<div class="defun">
+— Function File:  <b>semilogy</b> (<var>args</var>)<var><a name="index-semilogy-828"></a></var><br>
+<blockquote><p>Produce a two-dimensional plot using a log scale for the <var>y</var>
+axis.  See the description of <code>plot</code> for a description of the
+arguments that <code>semilogy</code> will accept. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dsemilogx.html#doc_002dsemilogx">semilogx</a>, <a href="doc_002dloglog.html#doc_002dloglog">loglog</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/loglog.m -->
+   <p><a name="doc_002dloglog"></a>
+
+<div class="defun">
+— Function File:  <b>loglog</b> (<var>args</var>)<var><a name="index-loglog-829"></a></var><br>
+<blockquote><p>Produce a two-dimensional plot using log scales for both axes.  See
+the description of <code>plot</code> for a description of the arguments
+that <code>loglog</code> will accept. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dsemilogx.html#doc_002dsemilogx">semilogx</a>, <a href="doc_002dsemilogy.html#doc_002dsemilogy">semilogy</a>. 
+</p></blockquote></div>
+
+   <p>The functions <code>bar</code>, <code>barh</code>, <code>stairs</code>, and <code>stem</code>
+are useful for displaying discrete data.  For example,
+
+<pre class="example">     hist (randn (10000, 1), 30);
+</pre>
+   <p class="noindent">produces the histogram of 10,000 normally distributed random numbers
+shown in <a href="fig_003ahist.html#fig_003ahist">fig:hist</a>.
+
+   <div class="float">
+<a name="fig_003ahist"></a><div align="center"><img src="hist.png" alt="hist.png"></div>
+   <p><strong class="float-caption">Figure 15.2: Histogram.</strong></p></div>
+
+<!-- ./plot/bar.m -->
+   <p><a name="doc_002dbar"></a>
+
+<div class="defun">
+— Function File:  <b>bar</b> (<var>x, y</var>)<var><a name="index-bar-830"></a></var><br>
+— Function File:  <b>bar</b> (<var>y</var>)<var><a name="index-bar-831"></a></var><br>
+— Function File:  <b>bar</b> (<var>x, y, w</var>)<var><a name="index-bar-832"></a></var><br>
+— Function File:  <b>bar</b> (<var>x, y, w, style</var>)<var><a name="index-bar-833"></a></var><br>
+— Function File: <var>h</var> = <b>bar</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-bar-834"></a></var><br>
+— Function File:  <b>bar</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-bar-835"></a></var><br>
+<blockquote><p>Produce a bar graph from two vectors of x-y data.
+
+        <p>If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+        <p>The default width of 0.8 for the bars can be changed using <var>w</var>.
+
+        <p>If <var>y</var> is a matrix, then each column of <var>y</var> is taken to be a
+separate bar graph plotted on the same graph.  By default the columns
+are plotted side-by-side.  This behavior can be changed by the <var>style</var>
+argument, which can take the values <code>"grouped"</code> (the default),
+or <code>"stacked"</code>.
+
+        <p>The optional return value <var>h</var> provides a handle to the "bar series"
+object with one handle per column of the variable <var>y</var>.  This
+series allows common elements of the group of bar series objects to
+be changed in a single bar series and the same properties are changed
+in the other "bar series".  For example
+
+     <pre class="example">          h = bar (rand (5, 10));
+          set (h(1), "basevalue", 0.5);
+</pre>
+        <p class="noindent">changes the position on the base of all of the bar series.
+
+        <p>The optional input handle <var>h</var> allows an axis handle to be passed. 
+Properties of the patch graphics object can be changed using
+<var>prop</var>, <var>val</var> pairs.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbarh.html#doc_002dbarh">barh</a>, <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/barh.m -->
+   <p><a name="doc_002dbarh"></a>
+
+<div class="defun">
+— Function File:  <b>barh</b> (<var>x, y</var>)<var><a name="index-barh-836"></a></var><br>
+— Function File:  <b>barh</b> (<var>y</var>)<var><a name="index-barh-837"></a></var><br>
+— Function File:  <b>barh</b> (<var>x, y, w</var>)<var><a name="index-barh-838"></a></var><br>
+— Function File:  <b>barh</b> (<var>x, y, w, style</var>)<var><a name="index-barh-839"></a></var><br>
+— Function File: <var>h</var> = <b>barh</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-barh-840"></a></var><br>
+— Function File:  <b>barh</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-barh-841"></a></var><br>
+<blockquote><p>Produce a horizontal bar graph from two vectors of x-y data.
+
+        <p>If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+        <p>The default width of 0.8 for the bars can be changed using <var>w</var>.
+
+        <p>If <var>y</var> is a matrix, then each column of <var>y</var> is taken to be a
+separate bar graph plotted on the same graph.  By default the columns
+are plotted side-by-side.  This behavior can be changed by the <var>style</var>
+argument, which can take the values <code>"grouped"</code> (the default),
+or <code>"stacked"</code>.
+
+        <p>The optional return value <var>h</var> provides a handle to the bar series
+object.  See <code>bar</code> for a description of the use of the bar series.
+
+        <p>The optional input handle <var>h</var> allows an axis handle to be passed. 
+Properties of the patch graphics object can be changed using
+<var>prop</var>, <var>val</var> pairs.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/hist.m -->
+   <p><a name="doc_002dhist"></a>
+
+<div class="defun">
+— Function File:  <b>hist</b> (<var>y, x, norm</var>)<var><a name="index-hist-842"></a></var><br>
+<blockquote><p>Produce histogram counts or plots.
+
+        <p>With one vector input argument, plot a histogram of the values with
+10 bins.  The range of the histogram bins is determined by the range
+of the data.  With one matrix input argument, plot a histogram where
+each bin contains a bar per input column.
+
+        <p>Given a second scalar argument, use that as the number of bins.
+
+        <p>Given a second vector argument, use that as the centers of the bins,
+with the width of the bins determined from the adjacent values in
+the vector.
+
+        <p>If third argument is provided, the histogram is normalized such that
+the sum of the bars is equal to <var>norm</var>.
+
+        <p>Extreme values are lumped in the first and last bins.
+
+        <p>With two output arguments, produce the values <var>nn</var> and <var>xx</var> such
+that <code>bar (</code><var>xx</var><code>, </code><var>nn</var><code>)</code> will plot the histogram. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbar.html#doc_002dbar">bar</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/stairs.m -->
+   <p><a name="doc_002dstairs"></a>
+
+<div class="defun">
+— Function File:  <b>stairs</b> (<var>x, y</var>)<var><a name="index-stairs-843"></a></var><br>
+— Function File:  <b>stairs</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-stairs-844"></a></var><br>
+— Function File:  <b>stairs</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-stairs-845"></a></var><br>
+— Function File:  <b>stairs</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-stairs-846"></a></var><br>
+— Function File: <var>h</var> = <b>stairs</b> (<var><small class="dots">...</small></var>)<var><a name="index-stairs-847"></a></var><br>
+<blockquote><p>Produce a stairstep plot.  The arguments may be vectors or matrices.
+
+        <p>If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+        <p>If two output arguments are specified, the data are generated but
+not plotted.  For example,
+
+     <pre class="example">          stairs (x, y);
+</pre>
+        <p class="noindent">and
+
+     <pre class="example">          [xs, ys] = stairs (x, y);
+          plot (xs, ys);
+</pre>
+        <p class="noindent">are equivalent. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dsemilogx.html#doc_002dsemilogx">semilogx</a>, <a href="doc_002dsemilogy.html#doc_002dsemilogy">semilogy</a>, <a href="doc_002dloglog.html#doc_002dloglog">loglog</a>, <a href="doc_002dpolar.html#doc_002dpolar">polar</a>, <a href="doc_002dmesh.html#doc_002dmesh">mesh</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>, <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dxlabel.html#doc_002dxlabel">xlabel</a>, <a href="doc_002dylabel.html#doc_002dylabel">ylabel</a>, <a href="doc_002dtitle.html#doc_002dtitle">title</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/stem.m -->
+   <p><a name="doc_002dstem"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>stem</b> (<var>x, y, linespec</var>)<var><a name="index-stem-848"></a></var><br>
+— Function File: <var>h</var> = <b>stem</b> (<var><small class="dots">...</small>, "filled"</var>)<var><a name="index-stem-849"></a></var><br>
+<blockquote><p>Plot a stem graph from two vectors of x-y data.  If only one argument
+is given, it is taken as the y-values and the x coordinates are taken
+from the indices of the elements.
+
+        <p>If <var>y</var> is a matrix, then each column of the matrix is plotted as
+a separate stem graph.  In this case <var>x</var> can either be a vector,
+the same length as the number of rows in <var>y</var>, or it can be a
+matrix of the same size as <var>y</var>.
+
+        <p>The default color is <code>"r"</code> (red).  The default line style is
+<code>"-"</code> and the default marker is <code>"o"</code>.  The line style can
+be altered by the <code>linespec</code> argument in the same manner as the
+<code>plot</code> command.  For example
+
+     <pre class="example">          x = 1:10;
+          y = ones (1, length (x))*2.*x;
+          stem (x, y, "b");
+</pre>
+        <p class="noindent">plots 10 stems with heights from 2 to 20 in blue;
+
+        <p>The return value of <code>stem</code> is a vector if "stem series" graphics
+handles, with one handle per column of the variable <var>y</var>.  This
+handle regroups the elements of the stem graph together as the
+children of the "stem series" handle, allowing them to be altered
+together.  For example
+
+     <pre class="example">          x = [0 : 10].';
+          y = [sin(x), cos(x)]
+          h = stem (x, y);
+          set (h(2), "color", "g");
+          set (h(1), "basevalue", -1)
+</pre>
+        <p class="noindent">changes the color of the second "stem series"  and moves the base line
+of the first. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dbarh.html#doc_002dbarh">barh</a>, <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/stem3.m -->
+   <p><a name="doc_002dstem3"></a>
+
+<div class="defun">
+— Function File: <var>h</var> = <b>stem3</b> (<var>x, y, z, linespec</var>)<var><a name="index-stem3-850"></a></var><br>
+<blockquote><p>Plot a three-dimensional stem graph and return the handles of the line
+and marker objects used to draw the stems as "stem series" object. 
+The default color is <code>"r"</code> (red).  The default line style is
+<code>"-"</code> and the default marker is <code>"o"</code>.
+
+        <p>For example,
+     <pre class="example">          theta = 0:0.2:6;
+          stem3 (cos (theta), sin (theta), theta)
+</pre>
+        <p class="noindent">plots 31 stems with heights from 0 to 6 lying on a circle.  Color
+definitions with rgb-triples are not valid! 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dbarh.html#doc_002dbarh">barh</a>, <a href="doc_002dstem.html#doc_002dstem">stem</a>, <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/scatter.m -->
+   <p><a name="doc_002dscatter"></a>
+
+<div class="defun">
+— Function File:  <b>scatter</b> (<var>x, y, s, c</var>)<var><a name="index-scatter-851"></a></var><br>
+— Function File:  <b>scatter</b> (<var><small class="dots">...</small>, 'filled'</var>)<var><a name="index-scatter-852"></a></var><br>
+— Function File:  <b>scatter</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-scatter-853"></a></var><br>
+— Function File:  <b>scatter</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-scatter-854"></a></var><br>
+— Function File:  <b>scatter</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-scatter-855"></a></var><br>
+— Function File: <var>h</var> = <b>scatter</b> (<var><small class="dots">...</small></var>)<var><a name="index-scatter-856"></a></var><br>
+<blockquote>
+        <p>Plot a scatter plot of the data.  A marker is plotted at each point
+defined by the points in the vectors <var>x</var> and <var>y</var>.  The size of
+the markers used is determined by the <var>s</var>, which can be a scalar,
+a vector of the same length of <var>x</var> and <var>y</var>.  If <var>s</var> is not
+given or is an empty matrix, then the default value of 8 points is used.
+
+        <p>The color of the markers is determined by <var>c</var>, which can be a string
+defining a fixed color, a 3 element vector giving the red, green and blue
+components of the color, a vector of the same length as <var>x</var> that gives
+a scaled index into the current colormap, or a <var>n</var>-by-3 matrix defining
+the colors of each of the markers individually.
+
+        <p>The marker to use can be changed with the <var>style</var> argument, that is a
+string defining a marker in the same manner as the <code>plot</code> command. 
+If the argument 'filled' is given then the markers as filled.  All
+additional arguments are passed to the underlying patch command.
+
+        <p>The optional return value <var>h</var> provides a handle to the patch object
+
+     <pre class="example">          x = randn (100, 1);
+          y = randn (100, 1);
+          scatter (x, y, [], sqrt(x.^2 + y.^2));
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>, <a href="doc_002dscatter3.html#doc_002dscatter3">scatter3</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/scatter3.m -->
+   <p><a name="doc_002dscatter3"></a>
+
+<div class="defun">
+— Function File:  <b>scatter3</b> (<var>x, y, z, s, c</var>)<var><a name="index-scatter3-857"></a></var><br>
+— Function File:  <b>scatter3</b> (<var><small class="dots">...</small>, 'filled'</var>)<var><a name="index-scatter3-858"></a></var><br>
+— Function File:  <b>scatter3</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-scatter3-859"></a></var><br>
+— Function File:  <b>scatter3</b> (<var><small class="dots">...</small>, prop, val</var>)<var><a name="index-scatter3-860"></a></var><br>
+— Function File:  <b>scatter3</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-scatter3-861"></a></var><br>
+— Function File: <var>h</var> = <b>scatter3</b> (<var><small class="dots">...</small></var>)<var><a name="index-scatter3-862"></a></var><br>
+<blockquote>
+        <p>Plot a scatter plot of the data in 3D.  A marker is plotted at each point
+defined by the points in the vectors <var>x</var>, <var>y</var> and <var>z</var>.  The size
+of the markers used is determined by <var>s</var>, which can be a scalar or
+a vector of the same length of <var>x</var>, <var>y</var> and <var>z</var>.  If <var>s</var> is
+not given or is an empty matrix, then the default value of 8 points is used.
+
+        <p>The color of the markers is determined by <var>c</var>, which can be a string
+defining a fixed color, a 3 element vector giving the red, green and blue
+components of the color, a vector of the same length as <var>x</var> that gives
+a scaled index into the current colormap, or a <var>n</var>-by-3 matrix defining
+the colors of each of the markers individually.
+
+        <p>The marker to use can be changed with the <var>style</var> argument, that is a
+string defining a marker in the same manner as the <code>plot</code> command. 
+If the argument 'filled' is given then the markers as filled.  All
+additional arguments are passed to the underlying patch command.
+
+        <p>The optional return value <var>h</var> provides a handle to the patch object
+
+     <pre class="example">          [x, y, z] = peaks (20);
+          scatter3 (x(:), y(:), z(:), [], z(:));
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>, <a href="doc_002dscatter.html#doc_002dscatter">scatter</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/plotmatrix.m -->
+   <p><a name="doc_002dplotmatrix"></a>
+
+<div class="defun">
+— Function File:  <b>plotmatrix</b> (<var>x, y</var>)<var><a name="index-plotmatrix-863"></a></var><br>
+— Function File:  <b>plotmatrix</b> (<var>x</var>)<var><a name="index-plotmatrix-864"></a></var><br>
+— Function File:  <b>plotmatrix</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-plotmatrix-865"></a></var><br>
+— Function File:  <b>plotmatrix</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-plotmatrix-866"></a></var><br>
+— Function File: [<var>h</var>, <var>ax</var>, <var>bigax</var>, <var>p</var>, <var>pax</var>] = <b>plotmatrix</b> (<var><small class="dots">...</small></var>)<var><a name="index-plotmatrix-867"></a></var><br>
+<blockquote><p>Scatter plot of the columns of one matrix against another.  Given the
+arguments <var>x</var> and <var>y</var>, that have a matching number of rows,
+<code>plotmatrix</code> plots a set of axes corresponding to
+
+     <pre class="example">          plot (<var>x</var> (:, i), <var>y</var> (:, j)
+</pre>
+        <p>Given a single argument <var>x</var>, then this is equivalent to
+
+     <pre class="example">          plotmatrix (<var>x</var>, <var>x</var>)
+</pre>
+        <p class="noindent">except that the diagonal of the set of axes will be replaced with the
+histogram <code>hist (</code><var>x</var><code> (:, i))</code>.
+
+        <p>The marker to use can be changed with the <var>style</var> argument, that is a
+string defining a marker in the same manner as the <code>plot</code>
+command.  If a leading axes handle <var>h</var> is passed to
+<code>plotmatrix</code>, then this axis will be used for the plot.
+
+        <p>The optional return value <var>h</var> provides handles to the individual
+graphics objects in the scatter plots, whereas <var>ax</var> returns the
+handles to the scatter plot axis objects.  <var>bigax</var> is a hidden
+axis object that surrounds the other axes, such that the commands
+<code>xlabel</code>, <code>title</code>, etc., will be associated with this hidden
+axis.  Finally <var>p</var> returns the graphics objects associated with
+the histogram and <var>pax</var> the corresponding axes objects.
+
+     <pre class="example">          plotmatrix (randn (100, 3), 'g+')
+</pre>
+        </blockquote></div>
+
+<!-- ./plot/pareto.m -->
+   <p><a name="doc_002dpareto"></a>
+
+<div class="defun">
+— Function File:  <b>pareto</b> (<var>x</var>)<var><a name="index-pareto-868"></a></var><br>
+— Function File:  <b>pareto</b> (<var>x, y</var>)<var><a name="index-pareto-869"></a></var><br>
+— Function File:  <b>pareto</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-pareto-870"></a></var><br>
+— Function File: <var>h</var> = <b>pareto</b> (<var><small class="dots">...</small></var>)<var><a name="index-pareto-871"></a></var><br>
+<blockquote><p>Draw a Pareto chart, also called ABC chart.  A Pareto chart is a bar graph
+used to arrange information in such a way that priorities for process
+improvement can be established.  It organizes and displays information
+to show the relative importance of data.  The chart is similar to the
+histogram or bar chart, except that the bars are arranged in decreasing
+order from left to right along the abscissa.
+
+        <p>The fundamental idea (Pareto principle) behind the use of Pareto
+diagrams is that the majority of an effect is due to a small subset of the
+causes, so for quality improvement the first few (as presented on the
+diagram) contributing causes to a problem usually account for the majority
+of the result.  Thus, targeting these "major causes" for elimination
+results in the most cost-effective improvement scheme.
+
+        <p>The data are passed as <var>x</var> and the abscissa as <var>y</var>.  If <var>y</var> is
+absent, then the abscissa are assumed to be <code>1 : length (</code><var>x</var><code>)</code>. 
+<var>y</var> can be a string array, a cell array of strings or a numerical
+vector.
+
+        <p>An example of the use of <code>pareto</code> is
+
+     <pre class="example">          Cheese = {"Cheddar", "Swiss", "Camembert", ...
+                    "Munster", "Stilton", "Blue"};
+          Sold = [105, 30, 70, 10, 15, 20];
+          pareto(Sold, Cheese);
+</pre>
+        </blockquote></div>
+
+<!-- ./plot/rose.m -->
+   <p><a name="doc_002drose"></a>
+
+<div class="defun">
+— Function File:  <b>rose</b> (<var>th, r</var>)<var><a name="index-rose-872"></a></var><br>
+— Function File:  <b>rose</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-rose-873"></a></var><br>
+— Function File: <var>h</var> = <b>rose</b> (<var><small class="dots">...</small></var>)<var><a name="index-rose-874"></a></var><br>
+— Function File: [<var>r</var>, <var>th</var>] = <b>rose</b> (<var><small class="dots">...</small></var>)<var><a name="index-rose-875"></a></var><br>
+<blockquote>
+        <p>Plot an angular histogram.  With one vector argument <var>th</var>, plots the
+histogram with 20 angular bins.  If <var>th</var> is a matrix, then each column
+of <var>th</var> produces a separate histogram.
+
+        <p>If <var>r</var> is given and is a scalar, then the histogram is produced with
+<var>r</var> bins.  If <var>r</var> is a vector, then the center of each bin are
+defined by the values of <var>r</var>.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+        <p>If two output arguments are requested, then rather than plotting the
+histogram, the polar vectors necessary to plot the histogram are
+returned.
+
+     <pre class="example">          [r, t] = rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)]);
+          polar (r, t);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dcompass.html#doc_002dcompass">compass</a>, <a href="doc_002dpolar.html#doc_002dpolar">polar</a>, <a href="doc_002dhist.html#doc_002dhist">hist</a>. 
+</p></blockquote></div>
+
+   <p>The <code>contour</code>, <code>contourf</code> and <code>contourc</code> functions
+produce two-dimensional contour plots from three-dimensional data.
+
+<!-- ./plot/contour.m -->
+   <p><a name="doc_002dcontour"></a>
+
+<div class="defun">
+— Function File:  <b>contour</b> (<var>z</var>)<var><a name="index-contour-876"></a></var><br>
+— Function File:  <b>contour</b> (<var>z, vn</var>)<var><a name="index-contour-877"></a></var><br>
+— Function File:  <b>contour</b> (<var>x, y, z</var>)<var><a name="index-contour-878"></a></var><br>
+— Function File:  <b>contour</b> (<var>x, y, z, vn</var>)<var><a name="index-contour-879"></a></var><br>
+— Function File:  <b>contour</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-contour-880"></a></var><br>
+— Function File:  <b>contour</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-contour-881"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contour</b> (<var><small class="dots">...</small></var>)<var><a name="index-contour-882"></a></var><br>
+<blockquote><p>Plot level curves (contour lines) of the matrix <var>z</var>, using the
+contour matrix <var>c</var> computed by <code>contourc</code> from the same
+arguments; see the latter for their interpretation.  The set of
+contour levels, <var>c</var>, is only returned if requested.  For example:
+
+     <pre class="example">          x = 0:2;
+          y = x;
+          z = x' * y;
+          contour (x, y, z, 2:3)
+</pre>
+        <p>The style to use for the plot can be defined with a line style <var>style</var>
+in a similar manner to the line styles used with the <code>plot</code> command. 
+Any markers defined by <var>style</var> are ignored.
+
+        <p>The optional input and output argument <var>h</var> allows an axis handle to
+be passed to <code>contour</code> and the handles to the contour objects to be
+returned. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcontourc.html#doc_002dcontourc">contourc</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>, <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/contourf.m -->
+   <p><a name="doc_002dcontourf"></a>
+
+<div class="defun">
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>x, y, z, lvl</var>)<var><a name="index-contourf-883"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>x, y, z, n</var>)<var><a name="index-contourf-884"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>x, y, z</var>)<var><a name="index-contourf-885"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>z, n</var>)<var><a name="index-contourf-886"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>z, lvl</var>)<var><a name="index-contourf-887"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>z</var>)<var><a name="index-contourf-888"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var>ax, <small class="dots">...</small></var>)<var><a name="index-contourf-889"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contourf</b> (<var><small class="dots">...</small>, "property", val</var>)<var><a name="index-contourf-890"></a></var><br>
+<blockquote><p>Compute and plot filled contours of the matrix <var>z</var>. 
+Parameters <var>x</var>, <var>y</var> and <var>n</var> or <var>lvl</var> are optional.
+
+        <p>The return value <var>c</var> is a 2xn matrix containing the contour lines
+as described in the help to the contourc function.
+
+        <p>The return value <var>h</var> is handle-vector to the patch objects creating
+the filled contours.
+
+        <p>If <var>x</var> and <var>y</var> are omitted they are taken as the row/column
+index of <var>z</var>.  <var>n</var> is a scalar denoting the number of lines
+to compute.  Alternatively <var>lvl</var> is a vector containing the
+contour levels.  If only one value (e.g., lvl0) is wanted, set
+<var>lvl</var> to [lvl0, lvl0].  If both <var>n</var> or <var>lvl</var> are omitted
+a default value of 10 contour level is assumed.
+
+        <p>If provided, the filled contours are added to the axes object
+<var>ax</var> instead of the current axis.
+
+        <p>The following example plots filled contours of the <code>peaks</code>
+function.
+     <pre class="example">          [x, y, z] = peaks (50);
+          contourf (x, y, z, -7:9)
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcontour.html#doc_002dcontour">contour</a>, <a href="doc_002dcontourc.html#doc_002dcontourc">contourc</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/contourc.m -->
+   <p><a name="doc_002dcontourc"></a>
+
+<div class="defun">
+— Function File: [<var>c</var>, <var>lev</var>] = <b>contourc</b> (<var>x, y, z, vn</var>)<var><a name="index-contourc-891"></a></var><br>
+<blockquote><p>Compute isolines (contour lines) of the matrix <var>z</var>. 
+Parameters <var>x</var>, <var>y</var> and <var>vn</var> are optional.
+
+        <p>The return value <var>lev</var> is a vector of the contour levels. 
+The return value <var>c</var> is a 2 by <var>n</var> matrix containing the
+contour lines in the following format
+
+     <pre class="example">          <var>c</var> = [lev1, x1, x2, ..., levn, x1, x2, ...
+               len1, y1, y2, ..., lenn, y1, y2, ...]
+</pre>
+        <p class="noindent">in which contour line <var>n</var> has a level (height) of <var>levn</var> and
+length of <var>lenn</var>.
+
+        <p>If <var>x</var> and <var>y</var> are omitted they are taken as the row/column
+index of <var>z</var>.  <var>vn</var> is either a scalar denoting the number of lines
+to compute or a vector containing the values of the lines.  If only one
+value is wanted, set <var>vn</var><code> = [val, val]</code>;
+If <var>vn</var> is omitted it defaults to 10.
+
+        <p>For example,
+     <pre class="example">          x = 0:2;
+          y = x;
+          z = x' * y;
+          contourc (x, y, z, 2:3)
+                  2.0000   2.0000   1.0000   3.0000   1.5000   2.0000
+               2.0000   1.0000   2.0000   2.0000   2.0000   1.5000
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcontour.html#doc_002dcontour">contour</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/contour3.m -->
+   <p><a name="doc_002dcontour3"></a>
+
+<div class="defun">
+— Function File:  <b>contour3</b> (<var>z</var>)<var><a name="index-contour3-892"></a></var><br>
+— Function File:  <b>contour3</b> (<var>z, vn</var>)<var><a name="index-contour3-893"></a></var><br>
+— Function File:  <b>contour3</b> (<var>x, y, z</var>)<var><a name="index-contour3-894"></a></var><br>
+— Function File:  <b>contour3</b> (<var>x, y, z, vn</var>)<var><a name="index-contour3-895"></a></var><br>
+— Function File:  <b>contour3</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-contour3-896"></a></var><br>
+— Function File:  <b>contour3</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-contour3-897"></a></var><br>
+— Function File: [<var>c</var>, <var>h</var>] = <b>contour3</b> (<var><small class="dots">...</small></var>)<var><a name="index-contour3-898"></a></var><br>
+<blockquote><p>Plot level curves (contour lines) of the matrix <var>z</var>, using the
+contour matrix <var>c</var> computed by <code>contourc</code> from the same
+arguments; see the latter for their interpretation.  The contours are
+plotted at the Z level corresponding to their contour.  The set of
+contour levels, <var>c</var>, is only returned if requested.  For example:
+
+     <pre class="example">          contour3 (peaks (19));
+          hold on
+          surface (peaks (19), "facecolor", "none", "EdgeColor", "black")
+          colormap hot
+</pre>
+        <p>The style to use for the plot can be defined with a line style <var>style</var>
+in a similar manner to the line styles used with the <code>plot</code> command. 
+Any markers defined by <var>style</var> are ignored.
+
+        <p>The optional input and output argument <var>h</var> allows an axis handle to
+be passed to <code>contour</code> and the handles to the contour objects to be
+returned. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcontourc.html#doc_002dcontourc">contourc</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>, <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+   <p>The <code>errorbar</code>, <code>semilogxerr</code>, <code>semilogyerr</code>, and
+<code>loglogerr</code> functions produce plots with error bar markers.  For
+example,
+
+<pre class="example">     x = 0:0.1:10;
+     y = sin (x);
+     yp =  0.1 .* randn (size (x));
+     ym = -0.1 .* randn (size (x));
+     errorbar (x, sin (x), ym, yp);
+</pre>
+   <p class="noindent">produces the figure shown in <a href="fig_003aerrorbar.html#fig_003aerrorbar">fig:errorbar</a>.
+
+   <div class="float">
+<a name="fig_003aerrorbar"></a><div align="center"><img src="errorbar.png" alt="errorbar.png"></div>
+   <p><strong class="float-caption">Figure 15.3: Errorbar plot.</strong></p></div>
+
+<!-- ./plot/errorbar.m -->
+   <p><a name="doc_002derrorbar"></a>
+
+<div class="defun">
+— Function File:  <b>errorbar</b> (<var>args</var>)<var><a name="index-errorbar-899"></a></var><br>
+<blockquote><p>This function produces two-dimensional plots with errorbars.  Many
+different combinations of arguments are possible.  The simplest form is
+
+     <pre class="example">          errorbar (<var>y</var>, <var>ey</var>)
+</pre>
+        <p class="noindent">where the first argument is taken as the set of <var>y</var> coordinates
+and the second argument <var>ey</var> is taken as the errors of the
+<var>y</var> values.  <var>x</var> coordinates are taken to be the indices
+of the elements, starting with 1.
+
+        <p>If more than two arguments are given, they are interpreted as
+
+     <pre class="example">          errorbar (<var>x</var>, <var>y</var>, ..., <var>fmt</var>, ...)
+</pre>
+        <p class="noindent">where after <var>x</var> and <var>y</var> there can be up to four error
+parameters such as <var>ey</var>, <var>ex</var>, <var>ly</var>, <var>uy</var>, etc.,
+depending on the plot type.  Any number of argument sets may appear,
+as long as they are separated with a format string <var>fmt</var>.
+
+        <p>If <var>y</var> is a matrix, <var>x</var> and error parameters must also be matrices
+having same dimensions.  The columns of <var>y</var> are plotted versus the
+corresponding columns of <var>x</var> and errorbars are drawn from
+the corresponding columns of error parameters.
+
+        <p>If <var>fmt</var> is missing, yerrorbars ("~") plot style is assumed.
+
+        <p>If the <var>fmt</var> argument is supplied, it is interpreted as in
+normal plots.  In addition the following plot styles are supported by
+errorbar:
+
+          <dl>
+<dt>‘<samp><span class="samp">~</span></samp>’<dd>Set yerrorbars plot style (default).
+
+          <br><dt>‘<samp><span class="samp">></span></samp>’<dd>Set xerrorbars plot style.
+
+          <br><dt>‘<samp><span class="samp">~></span></samp>’<dd>Set xyerrorbars plot style.
+
+          <br><dt>‘<samp><span class="samp">#</span></samp>’<dd>Set boxes plot style.
+
+          <br><dt>‘<samp><span class="samp">#~</span></samp>’<dd>Set boxerrorbars plot style.
+
+          <br><dt>‘<samp><span class="samp">#~></span></samp>’<dd>Set boxxyerrorbars plot style. 
+</dl>
+
+        <p>Examples:
+
+     <pre class="example">          errorbar (<var>x</var>, <var>y</var>, <var>ex</var>, ">")
+</pre>
+        <p>produces an xerrorbar plot of <var>y</var> versus <var>x</var> with <var>x</var>
+errorbars drawn from <var>x</var>-<var>ex</var> to <var>x</var>+<var>ex</var>.
+
+     <pre class="example">          errorbar (<var>x</var>, <var>y1</var>, <var>ey</var>, "~",
+                    <var>x</var>, <var>y2</var>, <var>ly</var>, <var>uy</var>)
+</pre>
+        <p>produces yerrorbar plots with <var>y1</var> and <var>y2</var> versus <var>x</var>. 
+Errorbars for <var>y1</var> are drawn from <var>y1</var>-<var>ey</var> to
+<var>y1</var>+<var>ey</var>, errorbars for <var>y2</var> from <var>y2</var>-<var>ly</var> to
+<var>y2</var>+<var>uy</var>.
+
+     <pre class="example">          errorbar (<var>x</var>, <var>y</var>, <var>lx</var>, <var>ux</var>,
+                    <var>ly</var>, <var>uy</var>, "~>")
+</pre>
+        <p>produces an xyerrorbar plot of <var>y</var> versus <var>x</var> in which
+<var>x</var> errorbars are drawn from <var>x</var>-<var>lx</var> to <var>x</var>+<var>ux</var>
+and <var>y</var> errorbars from <var>y</var>-<var>ly</var> to <var>y</var>+<var>uy</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dsemilogxerr.html#doc_002dsemilogxerr">semilogxerr</a>, <a href="doc_002dsemilogyerr.html#doc_002dsemilogyerr">semilogyerr</a>, <a href="doc_002dloglogerr.html#doc_002dloglogerr">loglogerr</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/semilogxerr.m -->
+   <p><a name="doc_002dsemilogxerr"></a>
+
+<div class="defun">
+— Function File:  <b>semilogxerr</b> (<var>args</var>)<var><a name="index-semilogxerr-900"></a></var><br>
+<blockquote><p>Produce two-dimensional plots on a semilogarithm axis with errorbars. 
+Many different combinations of arguments are possible.  The most used
+form is
+
+     <pre class="example">          semilogxerr (<var>x</var>, <var>y</var>, <var>ey</var>, <var>fmt</var>)
+</pre>
+        <p class="noindent">which produces a semi-logarithm plot of <var>y</var> versus <var>x</var>
+with errors in the <var>y</var>-scale defined by <var>ey</var> and the plot
+format defined by <var>fmt</var>.  See errorbar for available formats and
+additional information. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derrorbar.html#doc_002derrorbar">errorbar</a>, <a href="doc_002dloglogerr.html#doc_002dloglogerr">loglogerr</a>, <a href="doc_002dsemilogyerr.html#doc_002dsemilogyerr">semilogyerr</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/semilogyerr.m -->
+   <p><a name="doc_002dsemilogyerr"></a>
+
+<div class="defun">
+— Function File:  <b>semilogyerr</b> (<var>args</var>)<var><a name="index-semilogyerr-901"></a></var><br>
+<blockquote><p>Produce two-dimensional plots on a semilogarithm axis with errorbars. 
+Many different combinations of arguments are possible.  The most used
+form is
+
+     <pre class="example">          semilogyerr (<var>x</var>, <var>y</var>, <var>ey</var>, <var>fmt</var>)
+</pre>
+        <p class="noindent">which produces a semi-logarithm plot of <var>y</var> versus <var>x</var>
+with errors in the <var>y</var>-scale defined by <var>ey</var> and the plot
+format defined by <var>fmt</var>.  See errorbar for available formats and
+additional information. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derrorbar.html#doc_002derrorbar">errorbar</a>, <a href="doc_002dloglogerr.html#doc_002dloglogerr">loglogerr</a>, <a href="doc_002dsemilogxerr.html#doc_002dsemilogxerr">semilogxerr</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/loglogerr.m -->
+   <p><a name="doc_002dloglogerr"></a>
+
+<div class="defun">
+— Function File:  <b>loglogerr</b> (<var>args</var>)<var><a name="index-loglogerr-902"></a></var><br>
+<blockquote><p>Produce two-dimensional plots on double logarithm axis with
+errorbars.  Many different combinations of arguments are possible. 
+The most used form is
+
+     <pre class="example">          loglogerr (<var>x</var>, <var>y</var>, <var>ey</var>, <var>fmt</var>)
+</pre>
+        <p class="noindent">which produces a double logarithm plot of <var>y</var> versus <var>x</var>
+with errors in the <var>y</var>-scale defined by <var>ey</var> and the plot
+format defined by <var>fmt</var>.  See errorbar for available formats and
+additional information. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002derrorbar.html#doc_002derrorbar">errorbar</a>, <a href="doc_002dsemilogxerr.html#doc_002dsemilogxerr">semilogxerr</a>, <a href="doc_002dsemilogyerr.html#doc_002dsemilogyerr">semilogyerr</a>. 
+</p></blockquote></div>
+
+   <p>Finally, the <code>polar</code> function allows you to easily plot data in
+polar coordinates.  However, the display coordinates remain rectangular
+and linear.  For example,
+
+<pre class="example">     polar (0:0.1:10*pi, 0:0.1:10*pi);
+</pre>
+   <p class="noindent">produces the spiral plot shown in <a href="fig_003apolar.html#fig_003apolar">fig:polar</a>.
+
+   <div class="float">
+<a name="fig_003apolar"></a><div align="center"><img src="polar.png" alt="polar.png"></div>
+   <p><strong class="float-caption">Figure 15.4: Polar plot.</strong></p></div>
+
+<!-- ./plot/polar.m -->
+   <p><a name="doc_002dpolar"></a>
+
+<div class="defun">
+— Function File:  <b>polar</b> (<var>theta, rho, fmt</var>)<var><a name="index-polar-903"></a></var><br>
+<blockquote><p>Make a two-dimensional plot given the polar coordinates <var>theta</var> and
+<var>rho</var>.
+
+        <p>The optional third argument specifies the line type. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/pie.m -->
+   <p><a name="doc_002dpie"></a>
+
+<div class="defun">
+— Function File:  <b>pie</b> (<var>y</var>)<var><a name="index-pie-904"></a></var><br>
+— Function File:  <b>pie</b> (<var>y, explode</var>)<var><a name="index-pie-905"></a></var><br>
+— Function File:  <b>pie</b> (<var><small class="dots">...</small>, labels</var>)<var><a name="index-pie-906"></a></var><br>
+— Function File:  <b>pie</b> (<var>h, <small class="dots">...</small></var>)<var>;<a name="index-pie-907"></a></var><br>
+— Function File: <var>h</var> = <b>pie</b> (<var><small class="dots">...</small></var>)<var>;<a name="index-pie-908"></a></var><br>
+<blockquote><p>Produce a pie chart.
+
+        <p>Called with a single vector argument, produces a pie chart of the
+elements in <var>x</var>, with the size of the slice determined by percentage
+size of the values of <var>x</var>.
+
+        <p>The variable <var>explode</var> is a vector of the same length as <var>x</var> that
+if non zero 'explodes' the slice from the pie chart.
+
+        <p>If given <var>labels</var> is a cell array of strings of the same length as
+<var>x</var>, giving the labels of each of the slices of the pie chart.
+
+        <p>The optional return value <var>h</var> provides a handle to the patch object.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dbar.html#doc_002dbar">bar</a>, <a href="doc_002dstem.html#doc_002dstem">stem</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/quiver.m -->
+   <p><a name="doc_002dquiver"></a>
+
+<div class="defun">
+— Function File:  <b>quiver</b> (<var>u, v</var>)<var><a name="index-quiver-909"></a></var><br>
+— Function File:  <b>quiver</b> (<var>x, y, u, v</var>)<var><a name="index-quiver-910"></a></var><br>
+— Function File:  <b>quiver</b> (<var><small class="dots">...</small>, s</var>)<var><a name="index-quiver-911"></a></var><br>
+— Function File:  <b>quiver</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-quiver-912"></a></var><br>
+— Function File:  <b>quiver</b> (<var><small class="dots">...</small>, 'filled'</var>)<var><a name="index-quiver-913"></a></var><br>
+— Function File:  <b>quiver</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-quiver-914"></a></var><br>
+— Function File: <var>h</var> = <b>quiver</b> (<var><small class="dots">...</small></var>)<var><a name="index-quiver-915"></a></var><br>
+<blockquote>
+        <p>Plot the <code>(</code><var>u</var><code>, </code><var>v</var><code>)</code> components of a vector field in
+an <code>(</code><var>x</var><code>, </code><var>y</var><code>)</code> meshgrid.  If the grid is uniform, you can
+specify <var>x</var> and <var>y</var> as vectors.
+
+        <p>If <var>x</var> and <var>y</var> are undefined they are assumed to be
+<code>(1:</code><var>m</var><code>, 1:</code><var>n</var><code>)</code> where <code>[</code><var>m</var><code>, </code><var>n</var><code>] =
+size(</code><var>u</var><code>)</code>.
+
+        <p>The variable <var>s</var> is a scalar defining a scaling factor to use for
+ the arrows of the field relative to the mesh spacing.  A value of 0
+disables all scaling.  The default value is 1.
+
+        <p>The style to use for the plot can be defined with a line style <var>style</var>
+in a similar manner to the line styles used with the <code>plot</code> command. 
+If a marker is specified then markers at the grid points of the vectors are
+printed rather than arrows.  If the argument 'filled' is given then the
+markers as filled.
+
+        <p>The optional return value <var>h</var> provides a quiver group that
+regroups the components of the quiver plot (body, arrow and marker),
+and allows them to be changed together
+
+     <pre class="example">          [x, y] = meshgrid (1:2:20);
+          h = quiver (x, y, sin (2*pi*x/10), sin (2*pi*y/10));
+          set (h, "maxheadsize", 0.33);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/quiver3.m -->
+   <p><a name="doc_002dquiver3"></a>
+
+<div class="defun">
+— Function File:  <b>quiver3</b> (<var>u, v, w</var>)<var><a name="index-quiver3-916"></a></var><br>
+— Function File:  <b>quiver3</b> (<var>x, y, z, u, v, w</var>)<var><a name="index-quiver3-917"></a></var><br>
+— Function File:  <b>quiver3</b> (<var><small class="dots">...</small>, s</var>)<var><a name="index-quiver3-918"></a></var><br>
+— Function File:  <b>quiver3</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-quiver3-919"></a></var><br>
+— Function File:  <b>quiver3</b> (<var><small class="dots">...</small>, 'filled'</var>)<var><a name="index-quiver3-920"></a></var><br>
+— Function File:  <b>quiver3</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-quiver3-921"></a></var><br>
+— Function File: <var>h</var> = <b>quiver3</b> (<var><small class="dots">...</small></var>)<var><a name="index-quiver3-922"></a></var><br>
+<blockquote>
+        <p>Plot the <code>(</code><var>u</var><code>, </code><var>v</var><code>, </code><var>w</var><code>)</code> components of a vector field in
+an <code>(</code><var>x</var><code>, </code><var>y</var><code>), </code><var>z</var> meshgrid.  If the grid is uniform, you
+can specify <var>x</var>, <var>y</var> <var>z</var> as vectors.
+
+        <p>If <var>x</var>, <var>y</var> and <var>z</var> are undefined they are assumed to be
+<code>(1:</code><var>m</var><code>, 1:</code><var>n</var><code>, 1:</code><var>p</var><code>)</code> where <code>[</code><var>m</var><code>, </code><var>n</var><code>] =
+size(</code><var>u</var><code>)</code> and <var>p</var><code> = max (size (</code><var>w</var><code>))</code>.
+
+        <p>The variable <var>s</var> is a scalar defining a scaling factor to use for
+ the arrows of the field relative to the mesh spacing.  A value of 0
+disables all scaling.  The default value is 1.
+
+        <p>The style to use for the plot can be defined with a line style <var>style</var>
+in a similar manner to the line styles used with the <code>plot</code> command. 
+If a marker is specified then markers at the grid points of the vectors are
+printed rather than arrows.  If the argument 'filled' is given then the
+markers as filled.
+
+        <p>The optional return value <var>h</var> provides a quiver group that
+regroups the components of the quiver plot (body, arrow and marker),
+and allows them to be changed together
+
+     <pre class="example">          [x, y, z] = peaks (25);
+          surf (x, y, z);
+          hold on;
+          [u, v, w] = surfnorm (x, y, z / 10);
+          h = quiver3 (x, y, z, u, v, w);
+          set (h, "maxheadsize", 0.33);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/compass.m -->
+   <p><a name="doc_002dcompass"></a>
+
+<div class="defun">
+— Function File:  <b>compass</b> (<var>u, v</var>)<var><a name="index-compass-923"></a></var><br>
+— Function File:  <b>compass</b> (<var>z</var>)<var><a name="index-compass-924"></a></var><br>
+— Function File:  <b>compass</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-compass-925"></a></var><br>
+— Function File:  <b>compass</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-compass-926"></a></var><br>
+— Function File: <var>h</var> = <b>compass</b> (<var><small class="dots">...</small></var>)<var><a name="index-compass-927"></a></var><br>
+<blockquote>
+        <p>Plot the <code>(</code><var>u</var><code>, </code><var>v</var><code>)</code> components of a vector field emanating
+from the origin of a polar plot.  If a single complex argument <var>z</var> is
+given, then <var>u</var><code> = real (</code><var>z</var><code>)</code> and <var>v</var><code> = imag
+(</code><var>z</var><code>)</code>.
+
+        <p>The style to use for the plot can be defined with a line style <var>style</var>
+in a similar manner to the line styles used with the <code>plot</code> command.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+          compass (eig (a))
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dpolar.html#doc_002dpolar">polar</a>, <a href="doc_002dquiver.html#doc_002dquiver">quiver</a>, <a href="doc_002dfeather.html#doc_002dfeather">feather</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/feather.m -->
+   <p><a name="doc_002dfeather"></a>
+
+<div class="defun">
+— Function File:  <b>feather</b> (<var>u, v</var>)<var><a name="index-feather-928"></a></var><br>
+— Function File:  <b>feather</b> (<var>z</var>)<var><a name="index-feather-929"></a></var><br>
+— Function File:  <b>feather</b> (<var><small class="dots">...</small>, style</var>)<var><a name="index-feather-930"></a></var><br>
+— Function File:  <b>feather</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-feather-931"></a></var><br>
+— Function File: <var>h</var> = <b>feather</b> (<var><small class="dots">...</small></var>)<var><a name="index-feather-932"></a></var><br>
+<blockquote>
+        <p>Plot the <code>(</code><var>u</var><code>, </code><var>v</var><code>)</code> components of a vector field emanating
+from equidistant points on the x-axis.  If a single complex argument
+<var>z</var> is given, then <var>u</var><code> = real (</code><var>z</var><code>)</code> and
+<var>v</var><code> = imag (</code><var>z</var><code>)</code>.
+
+        <p>The style to use for the plot can be defined with a line style <var>style</var>
+in a similar manner to the line styles used with the <code>plot</code> command.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          phi = [0 : 15 : 360] * pi / 180;
+          feather (sin (phi), cos (phi))
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dquiver.html#doc_002dquiver">quiver</a>, <a href="doc_002dcompass.html#doc_002dcompass">compass</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/pcolor.m -->
+   <p><a name="doc_002dpcolor"></a>
+
+<div class="defun">
+— Function File:  <b>pcolor</b> (<var>x, y, c</var>)<var><a name="index-pcolor-933"></a></var><br>
+— Function File:  <b>pcolor</b> (<var>c</var>)<var><a name="index-pcolor-934"></a></var><br>
+<blockquote><p>Density plot for given matrices <var>x</var>, and <var>y</var> from <code>meshgrid</code> and
+a matrix <var>c</var> corresponding to the <var>x</var> and <var>y</var> coordinates of
+the mesh's vertices.  If <var>x</var> and <var>y</var> are vectors, then a typical vertex
+is (<var>x</var>(j), <var>y</var>(i), <var>c</var>(i,j)).  Thus, columns of <var>c</var>
+correspond to different <var>x</var> values and rows of <var>c</var> correspond
+to different <var>y</var> values.
+
+        <p>The <code>colormap</code> is scaled to the extents of <var>c</var>. 
+Limits may be placed on the color axis by the
+command <code>caxis</code>, or by setting the <code>clim</code> property of the
+parent axis.
+
+        <p>The face color of each cell of the mesh is determined by interpolating
+the values of <var>c</var> for the cell's vertices.  Contrast this with
+<code>imagesc</code> which renders one cell for each element of <var>c</var>.
+
+        <p><code>shading</code> modifies an attribute determining the manner by which the
+face color of each cell is interpolated from the values of <var>c</var>,
+and the visibility of the cells' edges.  By default the attribute is
+"faceted", which renders a single color for each cell's face with the edge
+visible.
+
+        <p><var>h</var> is the handle to the surface object.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcaxis.html#doc_002dcaxis">caxis</a>, <a href="doc_002dcontour.html#doc_002dcontour">contour</a>, <a href="doc_002dmeshgrid.html#doc_002dmeshgrid">meshgrid</a>, <a href="doc_002dimagesc.html#doc_002dimagesc">imagesc</a>, <a href="doc_002dshading.html#doc_002dshading">shading</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/area.m -->
+   <p><a name="doc_002darea"></a>
+
+<div class="defun">
+— Function File:  <b>area</b> (<var>x, y</var>)<var><a name="index-area-935"></a></var><br>
+— Function File:  <b>area</b> (<var>x, y, lvl</var>)<var><a name="index-area-936"></a></var><br>
+— Function File:  <b>area</b> (<var><small class="dots">...</small>, prop, val, <small class="dots">...</small></var>)<var><a name="index-area-937"></a></var><br>
+— Function File:  <b>area</b> (<var>y, <small class="dots">...</small></var>)<var><a name="index-area-938"></a></var><br>
+— Function File:  <b>area</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-area-939"></a></var><br>
+— Function File: <var>h</var> = <b>area</b> (<var><small class="dots">...</small></var>)<var><a name="index-area-940"></a></var><br>
+<blockquote><p>Area plot of cumulative sum of the columns of <var>y</var>.  This shows the
+contributions of a value to a sum, and is functionally similar to
+<code>plot (</code><var>x</var><code>, cumsum (</code><var>y</var><code>, 2))</code>, except that the area under
+the curve is shaded.
+
+        <p>If the <var>x</var> argument is omitted it is assumed to be given by
+<code>1 : rows (</code><var>y</var><code>)</code>.  A value <var>lvl</var> can be defined that determines
+where the base level of the shading under the curve should be defined.
+
+        <p>Additional arguments to the <code>area</code> function are passed to the
+<code>patch</code>.  The optional return value <var>h</var> provides a handle to
+area series object representing the patches of the areas. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dpatch.html#doc_002dpatch">patch</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/comet.m -->
+   <p><a name="doc_002dcomet"></a>
+
+<div class="defun">
+— Function File:  <b>comet</b> (<var>y</var>)<var><a name="index-comet-941"></a></var><br>
+— Function File:  <b>comet</b> (<var>x, y</var>)<var><a name="index-comet-942"></a></var><br>
+— Function File:  <b>comet</b> (<var>x, y, p</var>)<var><a name="index-comet-943"></a></var><br>
+— Function File:  <b>comet</b> (<var>ax, <small class="dots">...</small></var>)<var><a name="index-comet-944"></a></var><br>
+<blockquote><p>Produce a simple comet style animation along the trajectory provided by
+the input coordinate vectors (<var>x</var>, <var>y</var>), where <var>x</var> will default
+to the indices of <var>y</var>.
+
+        <p>The speed of the comet may be controlled by <var>p</var>, which represents the
+time which passes as the animation passes from one point to the next.  The
+default for <var>p</var> is 0.1 seconds.
+
+        <p>If <var>ax</var> is specified the animation is produced in that axis rather than
+the <code>gca</code>. 
+</p></blockquote></div>
+
+   <p>The axis function may be used to change the axis limits of an existing
+plot and various other axis properties, such as the aspect ratio and the
+appearance of tic marks.
+
+<!-- ./plot/axis.m -->
+   <p><a name="doc_002daxis"></a>
+
+<div class="defun">
+— Function File:  <b>axis</b> (<var>limits</var>)<var><a name="index-axis-945"></a></var><br>
+<blockquote><p>Set axis limits for plots.
+
+        <p>The argument <var>limits</var> should be a 2, 4, or 6 element vector.  The
+first and second elements specify the lower and upper limits for the x
+axis.  The third and fourth specify the limits for the y-axis, and the
+fifth and sixth specify the limits for the z-axis.
+
+        <p>Without any arguments, <code>axis</code> turns autoscaling on.
+
+        <p>With one output argument, <code>x = axis</code> returns the current axes
+
+        <p>The vector argument specifying limits is optional, and additional
+string arguments may be used to specify various axis properties.  For
+example,
+
+     <pre class="example">          axis ([1, 2, 3, 4], "square");
+</pre>
+        <p class="noindent">forces a square aspect ratio, and
+
+     <pre class="example">          axis ("labely", "tic");
+</pre>
+        <p class="noindent">turns tic marks on for all axes and tic mark labels on for the y-axis
+only.
+
+     <p class="noindent">The following options control the aspect ratio of the axes.
+
+          <dl>
+<dt><code>"square"</code><dd>Force a square aspect ratio. 
+<br><dt><code>"equal"</code><dd>Force x distance to equal y-distance. 
+<br><dt><code>"normal"</code><dd>Restore the balance. 
+</dl>
+
+     <p class="noindent">The following options control the way axis limits are interpreted.
+
+          <dl>
+<dt><code>"auto"</code><dd>Set the specified axes to have nice limits around the data
+or all if no axes are specified. 
+<br><dt><code>"manual"</code><dd>Fix the current axes limits. 
+<br><dt><code>"tight"</code><dd>Fix axes to the limits of the data. 
+</dl>
+
+     <p class="noindent">The option <code>"image"</code> is equivalent to <code>"tight"</code> and
+<code>"equal"</code>.
+
+     <p class="noindent">The following options affect the appearance of tic marks.
+
+          <dl>
+<dt><code>"on"</code><dd>Turn tic marks and labels on for all axes. 
+<br><dt><code>"off"</code><dd>Turn tic marks off for all axes. 
+<br><dt><code>"tic[xyz]"</code><dd>Turn tic marks on for all axes, or turn them on for the
+specified axes and off for the remainder. 
+<br><dt><code>"label[xyz]"</code><dd>Turn tic labels on for all axes, or turn them on for the
+specified axes and off for the remainder. 
+<br><dt><code>"nolabel"</code><dd>Turn tic labels off for all axes. 
+</dl>
+        Note, if there are no tic marks for an axis, there can be no labels.
+
+     <p class="noindent">The following options affect the direction of increasing values on
+the axes.
+
+          <dl>
+<dt><code>"ij"</code><dd>Reverse y-axis, so lower values are nearer the top. 
+<br><dt><code>"xy"</code><dd>Restore y-axis, so higher values are nearer the top. 
+</dl>
+
+        <p>If an axes handle is passed as the first argument, then operate on
+this axes rather than the current axes. 
+</p></blockquote></div>
+
+   <p>Similarly the axis limits of the colormap can be changed with the caxis
+function.
+
+<!-- ./plot/caxis.m -->
+   <p><a name="doc_002dcaxis"></a>
+
+<div class="defun">
+— Function File:  <b>caxis</b> (<var>limits</var>)<var><a name="index-caxis-946"></a></var><br>
+— Function File:  <b>caxis</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-caxis-947"></a></var><br>
+<blockquote><p>Set color axis limits for plots.
+
+        <p>The argument <var>limits</var> should be a 2 element vector specifying the
+lower and upper limits to assign to the first and last value in the
+colormap.  Values outside this range are clamped to the first and last
+colormap entries.
+
+        <p>If <var>limits</var> is 'auto', then automatic colormap scaling is applied,
+whereas if <var>limits</var> is 'manual' the colormap scaling is set to manual.
+
+        <p>Called without any arguments to current color axis limits are returned.
+
+        <p>If an axes handle is passed as the first argument, then operate on
+this axes rather than the current axes. 
+</p></blockquote></div>
+
+   <p>The <code>xlim</code>, <code>ylim</code>, and <code>zlim</code> functions may be used to
+get or set individual axis limits.  Each has the same form.
+
+   <p><a name="doc_002dylim"></a><a name="doc_002dzlim"></a><!-- ./plot/xlim.m -->
+<a name="doc_002dxlim"></a>
+
+<div class="defun">
+— Function File: <var>xl</var> = <b>xlim</b> ()<var><a name="index-xlim-948"></a></var><br>
+— Function File:  <b>xlim</b> (<var>xl</var>)<var><a name="index-xlim-949"></a></var><br>
+— Function File: <var>m</var> = <b>xlim</b> (<var>'mode'</var>)<var><a name="index-xlim-950"></a></var><br>
+— Function File:  <b>xlim</b> (<var>m</var>)<var><a name="index-xlim-951"></a></var><br>
+— Function File:  <b>xlim</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-xlim-952"></a></var><br>
+<blockquote><p>Get or set the limits of the x-axis of the current plot.  Called without
+arguments <code>xlim</code> returns the x-axis limits of the current plot. 
+If passed a two element vector <var>xl</var>, the limits of the x-axis are set
+to this value.
+
+        <p>The current mode for calculation of the x-axis can be returned with a
+call <code>xlim ('mode')</code>, and can be either 'auto' or 'manual'.  The
+current plotting mode can be set by passing either 'auto' or 'manual'
+as the argument.
+
+        <p>If passed an handle as the first argument, then operate on this handle
+rather than the current axes handle. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dylim.html#doc_002dylim">ylim</a>, <a href="doc_002dzlim.html#doc_002dzlim">zlim</a>, <a href="doc_002dset.html#doc_002dset">set</a>, <a href="doc_002dget.html#doc_002dget">get</a>, <a href="doc_002dgca.html#doc_002dgca">gca</a>. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Two_002ddimensional-Function-Plotting.html b/doc/interpreter/HTML/Two_002ddimensional-Function-Plotting.html
new file mode 100644
index 0000000..5a0d2df
--- /dev/null
+++ b/doc/interpreter/HTML/Two_002ddimensional-Function-Plotting.html
@@ -0,0 +1,225 @@
+<html lang="en">
+<head>
+<title>Two-dimensional Function Plotting - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots" title="Two-Dimensional Plots">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Two-dimensional-Function-Plotting"></a>
+<a name="Two_002ddimensional-Function-Plotting"></a>
+Up: <a rel="up" accesskey="u" href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">15.1.1.1 Two-dimensional Function Plotting</h5>
+
+<p>Octave can plot a function from a function handle inline function or
+string defining the function without the user needing to explicitly
+create the data to be plotted.  The function <code>fplot</code> also generates
+two-dimensional plots with linear axes using a function name and limits
+for the range of the x-coordinate instead of the x and y data.  For
+example,
+
+<pre class="example">     fplot (@sin, [-10, 10], 201);
+</pre>
+   <p class="noindent">produces a plot that is equivalent to the one above, but also includes a
+legend displaying the name of the plotted function.
+
+<!-- ./plot/fplot.m -->
+   <p><a name="doc_002dfplot"></a>
+
+<div class="defun">
+— Function File:  <b>fplot</b> (<var>fn, limits</var>)<var><a name="index-fplot-953"></a></var><br>
+— Function File:  <b>fplot</b> (<var>fn, limits, tol</var>)<var><a name="index-fplot-954"></a></var><br>
+— Function File:  <b>fplot</b> (<var>fn, limits, n</var>)<var><a name="index-fplot-955"></a></var><br>
+— Function File:  <b>fplot</b> (<var><small class="dots">...</small>, fmt</var>)<var><a name="index-fplot-956"></a></var><br>
+<blockquote><p>Plot a function <var>fn</var>, within the defined limits.  <var>fn</var>
+an be either a string, a function handle or an inline function. 
+The limits of the plot are given by <var>limits</var> of the form
+<code>[</code><var>xlo</var><code>, </code><var>xhi</var><code>]</code> or <code>[</code><var>xlo</var><code>, </code><var>xhi</var><code>,
+</code><var>ylo</var><code>, </code><var>yhi</var><code>]</code>.  <var>tol</var> is the default tolerance to use for the
+plot, and if <var>tol</var> is an integer it is assumed that it defines the
+number points to use in the plot.  The <var>fmt</var> argument is passed
+to the plot command.
+
+     <pre class="example">             fplot ("cos", [0, 2*pi])
+             fplot ("[cos(x), sin(x)]", [0, 2*pi])
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>. 
+</p></blockquote></div>
+
+   <p>Other functions that can create two-dimensional plots directly from a
+function include <code>ezplot</code>, <code>ezcontour</code>, <code>ezcontourf</code> and
+<code>ezpolar</code>.
+
+<!-- ./plot/ezplot.m -->
+   <p><a name="doc_002dezplot"></a>
+
+<div class="defun">
+— Function File:  <b>ezplot</b> (<var>f</var>)<var><a name="index-ezplot-957"></a></var><br>
+— Function File:  <b>ezplot</b> (<var>fx, fy</var>)<var><a name="index-ezplot-958"></a></var><br>
+— Function File:  <b>ezplot</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezplot-959"></a></var><br>
+— Function File:  <b>ezplot</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezplot-960"></a></var><br>
+— Function File:  <b>ezplot</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezplot-961"></a></var><br>
+— Function File: <var>h</var> = <b>ezplot</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezplot-962"></a></var><br>
+<blockquote>
+        <p>Plots in two-dimensions the curve defined by <var>f</var>.  The function
+<var>f</var> may be a string, inline function or function handle and can
+have either one or two variables.  If <var>f</var> has one variable, then
+the function is plotted over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code>
+with 500 points.
+
+        <p>If <var>f</var> has two variables then <var>f</var><code>(</code><var>x</var><code>,</code><var>y</var><code>) = 0</code>
+is calculated over the meshed domain <code>-2*pi < </code><var>x</var><code> | </code><var>y</var><code>
+< 2*pi</code> with 60 by 60 in the mesh.  For example
+
+     <pre class="example">          ezplot (@(<var>x</var>, <var>y</var>) <var>x</var> .^ 2 - <var>y</var> .^ 2 - 1)
+</pre>
+        <p>If two functions are passed as strings, inline functions or function
+handles, then the parametric function
+
+     <pre class="example">          <var>x</var> = <var>fx</var> (<var>t</var>)
+          <var>y</var> = <var>fy</var> (<var>t</var>)
+</pre>
+        <p>is plotted over the domain <code>-2*pi < </code><var>t</var><code> < 2*pi</code> with 500
+points.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of <var>x</var>, <var>y</var> and <var>t</var>.  If it is a four element
+vector, then the minimum and maximum values of <var>x</var> and <var>t</var>
+are determined by the first two elements and the minimum and maximum
+of <var>y</var> by the second pair of elements.
+
+        <p><var>n</var> is a scalar defining the number of points to use in plotting
+the function.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the line objects plotted.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dplot.html#doc_002dplot">plot</a>, <a href="doc_002dezplot3.html#doc_002dezplot3">ezplot3</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezcontour.m -->
+   <p><a name="doc_002dezcontour"></a>
+
+<div class="defun">
+— Function File:  <b>ezcontour</b> (<var>f</var>)<var><a name="index-ezcontour-963"></a></var><br>
+— Function File:  <b>ezcontour</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezcontour-964"></a></var><br>
+— Function File:  <b>ezcontour</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezcontour-965"></a></var><br>
+— Function File:  <b>ezcontour</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezcontour-966"></a></var><br>
+— Function File: <var>h</var> = <b>ezcontour</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezcontour-967"></a></var><br>
+<blockquote>
+        <p>Plots the contour lines of a function.  <var>f</var> is a string, inline function
+or function handle with two arguments defining the function.  By default the
+plot is over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code> and <code>-2*pi <
+</code><var>y</var><code> < 2*pi</code> with 60 points in each dimension.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>x</var> and <var>y</var>.  If <var>dom</var> is a four element vector,
+then the minimum and maximum value of <var>x</var> and <var>y</var> are specify
+separately.
+
+        <p><var>n</var> is a scalar defining the number of points to use in each dimension.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezcontour (f, [-3, 3]);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezcontourf.html#doc_002dezcontourf">ezcontourf</a>, <a href="doc_002dezsurfc.html#doc_002dezsurfc">ezsurfc</a>, <a href="doc_002dezmeshc.html#doc_002dezmeshc">ezmeshc</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezcontourf.m -->
+   <p><a name="doc_002dezcontourf"></a>
+
+<div class="defun">
+— Function File:  <b>ezcontourf</b> (<var>f</var>)<var><a name="index-ezcontourf-968"></a></var><br>
+— Function File:  <b>ezcontourf</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezcontourf-969"></a></var><br>
+— Function File:  <b>ezcontourf</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezcontourf-970"></a></var><br>
+— Function File:  <b>ezcontourf</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezcontourf-971"></a></var><br>
+— Function File: <var>h</var> = <b>ezcontourf</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezcontourf-972"></a></var><br>
+<blockquote>
+        <p>Plots the filled contour lines of a function.  <var>f</var> is a string, inline
+function or function handle with two arguments defining the function.  By
+default the plot is over the domain <code>-2*pi < </code><var>x</var><code> < 2*pi</code> and
+<code>-2*pi < </code><var>y</var><code> < 2*pi</code> with 60 points in each dimension.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>x</var> and <var>y</var>.  If <var>dom</var> is a four element vector,
+then the minimum and maximum value of <var>x</var> and <var>y</var> are specify
+separately.
+
+        <p><var>n</var> is a scalar defining the number of points to use in each dimension.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezcontourf (f, [-3, 3]);
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezcontour.html#doc_002dezcontour">ezcontour</a>, <a href="doc_002dezsurfc.html#doc_002dezsurfc">ezsurfc</a>, <a href="doc_002dezmeshc.html#doc_002dezmeshc">ezmeshc</a>. 
+</p></blockquote></div>
+
+<!-- ./plot/ezpolar.m -->
+   <p><a name="doc_002dezpolar"></a>
+
+<div class="defun">
+— Function File:  <b>ezpolar</b> (<var>f</var>)<var><a name="index-ezpolar-973"></a></var><br>
+— Function File:  <b>ezpolar</b> (<var><small class="dots">...</small>, dom</var>)<var><a name="index-ezpolar-974"></a></var><br>
+— Function File:  <b>ezpolar</b> (<var><small class="dots">...</small>, n</var>)<var><a name="index-ezpolar-975"></a></var><br>
+— Function File:  <b>ezpolar</b> (<var>h, <small class="dots">...</small></var>)<var><a name="index-ezpolar-976"></a></var><br>
+— Function File: <var>h</var> = <b>ezpolar</b> (<var><small class="dots">...</small></var>)<var><a name="index-ezpolar-977"></a></var><br>
+<blockquote>
+        <p>Plots in polar plot defined by a function.  The function <var>f</var> is either
+a string, inline function or function handle with one arguments defining
+the function.  By default the plot is over the domain <code>0 < </code><var>x</var><code> <
+2*pi</code> with 60 points.
+
+        <p>If <var>dom</var> is a two element vector, it represents the minimum and maximum
+value of both <var>t</var>.  <var>n</var> is a scalar defining the number of points to
+use.
+
+        <p>The optional return value <var>h</var> provides a list of handles to the
+the parts of the vector field (body, arrow and marker).
+
+     <pre class="example">          ezpolar (@(t) 1 + sin (t));
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolar.html#doc_002dpolar">polar</a>, <a href="doc_002dezplot.html#doc_002dezplot">ezplot</a>, <a href="doc_002dezsurf.html#doc_002dezsurf">ezsurf</a>, <a href="doc_002dezmesh.html#doc_002dezmesh">ezmesh</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/User_002ddefined-Data-Types.html b/doc/interpreter/HTML/User_002ddefined-Data-Types.html
new file mode 100644
index 0000000..cc8cc90
--- /dev/null
+++ b/doc/interpreter/HTML/User_002ddefined-Data-Types.html
@@ -0,0 +1,46 @@
+<html lang="en">
+<head>
+<title>User-defined Data Types - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Data-Types.html#Data-Types" title="Data Types">
+<link rel="prev" href="Built_002din-Data-Types.html#Built_002din-Data-Types" title="Built-in Data Types">
+<link rel="next" href="Object-Sizes.html#Object-Sizes" title="Object Sizes">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="User-defined-Data-Types"></a>
+<a name="User_002ddefined-Data-Types"></a>
+Next: <a rel="next" accesskey="n" href="Object-Sizes.html#Object-Sizes">Object Sizes</a>,
+Previous: <a rel="previous" accesskey="p" href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>,
+Up: <a rel="up" accesskey="u" href="Data-Types.html#Data-Types">Data Types</a>
+<hr>
+</div>
+
+<h3 class="section">3.2 User-defined Data Types</h3>
+
+<p><a name="index-user_002ddefined-data-types-198"></a><a name="index-data-types_002c-user_002ddefined-199"></a>
+Someday I hope to expand this to include a complete description of
+Octave's mechanism for managing user-defined data types.  Until this
+feature is documented here, you will have to make do by reading the code
+in the <samp><span class="file">ov.h</span></samp>, <samp><span class="file">ops.h</span></samp>, and related files from Octave's
+<samp><span class="file">src</span></samp> directory.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Using-Octave-Mode.html b/doc/interpreter/HTML/Using-Octave-Mode.html
new file mode 100644
index 0000000..317504b
--- /dev/null
+++ b/doc/interpreter/HTML/Using-Octave-Mode.html
@@ -0,0 +1,282 @@
+<html lang="en">
+<head>
+<title>Using Octave Mode - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Emacs-Octave-Support.html#Emacs-Octave-Support" title="Emacs Octave Support">
+<link rel="prev" href="Installing-EOS.html#Installing-EOS" title="Installing EOS">
+<link rel="next" href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs" title="Running Octave From Within Emacs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Using-Octave-Mode"></a>
+Next: <a rel="next" accesskey="n" href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs">Running Octave From Within Emacs</a>,
+Previous: <a rel="previous" accesskey="p" href="Installing-EOS.html#Installing-EOS">Installing EOS</a>,
+Up: <a rel="up" accesskey="u" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">G.2 Using Octave Mode</h3>
+
+<p>If you are lucky, your sysadmins have already arranged everything so
+that Emacs automatically goes into Octave mode whenever you visit an
+Octave code file as characterized by its extension <samp><span class="file">.m</span></samp>.  If not,
+proceed as follows.
+
+     <ol type=1 start=1>
+<li>To begin using Octave mode for all <samp><span class="file">.m</span></samp> files you visit, add the
+following lines to a file loaded by Emacs at startup time, typically
+your <samp><span class="file">~/.emacs</span></samp> file:
+
+     <pre class="lisp">          (autoload 'octave-mode "octave-mod" nil t)
+          (setq auto-mode-alist
+                (cons '("\\.m$" . octave-mode) auto-mode-alist))
+</pre>
+     <li>Finally, to turn on the abbrevs, auto-fill and font-lock features
+automatically, also add the following lines to one of the Emacs startup
+files:
+     <pre class="lisp">          (add-hook 'octave-mode-hook
+                    (lambda ()
+                      (abbrev-mode 1)
+                      (auto-fill-mode 1)
+                      (if (eq window-system 'x)
+                          (font-lock-mode 1))))
+</pre>
+     <p>See the Emacs manual for more information about how to customize
+Font-lock mode.
+        </ol>
+
+   <p>In Octave mode, the following special Emacs commands can be used in
+addition to the standard Emacs commands.
+
+     <dl>
+<dt><kbd>C-h m</kbd><dd>Describe the features of Octave mode.
+
+     <br><dt><kbd>LFD</kbd><dd>Reindent the current Octave line, insert a newline and indent the new
+line (<code>octave-reindent-then-newline-and-indent</code>).  An abbrev before
+point is expanded if <code>abbrev-mode</code> is non-<code>nil</code>.
+
+     <br><dt><kbd>TAB</kbd><dd>Indents current Octave line based on its contents and on previous
+lines (<code>indent-according-to-mode</code>).
+
+     <br><dt><kbd>;</kbd><dd>Insert an “electric” semicolon (<code>octave-electric-semi</code>).  If
+<code>octave-auto-indent</code> is non-<code>nil</code>, reindent the current line. 
+If <code>octave-auto-newline</code> is non-<code>nil</code>, automagically insert a
+newline and indent the new line.
+
+     <br><dt><kbd>`</kbd><dd>Start entering an abbreviation (<code>octave-abbrev-start</code>).  If Abbrev
+mode is turned on, typing <kbd>`C-h</kbd> or <kbd>`?</kbd> lists all abbrevs. 
+Any other key combination is executed normally.  Note that all Octave
+abbrevs start with a grave accent.
+
+     <br><dt><kbd>M-LFD</kbd><dd>Break line at point and insert continuation marker and alignment
+(<code>octave-split-line</code>).
+
+     <br><dt><kbd>M-TAB</kbd><dd>Perform completion on Octave symbol preceding point, comparing that
+symbol against Octave's reserved words and built-in variables
+(<code>octave-complete-symbol</code>).
+
+     <br><dt><kbd>M-C-a</kbd><dd>Move backward to the beginning of a function
+(<code>octave-beginning-of-defun</code>). 
+With prefix argument <var>N</var>, do it that many times if <var>N</var> is
+positive;  otherwise, move forward to the <var>N</var>-th following beginning
+of a function.
+
+     <br><dt><kbd>M-C-e</kbd><dd>Move forward to the end of a function (<code>octave-end-of-defun</code>). 
+With prefix argument <var>N</var>, do it that many times if <var>N</var> is
+positive;  otherwise, move back to the <var>N</var>-th preceding end of a
+function.
+
+     <br><dt><kbd>M-C-h</kbd><dd>Puts point at beginning and mark at the end of the current Octave
+function, i.e., the one containing point or following point
+(<code>octave-mark-defun</code>).
+
+     <br><dt><kbd>M-C-q</kbd><dd>Properly indents the Octave function which contains point
+(<code>octave-indent-defun</code>).
+
+     <br><dt><kbd>M-;</kbd><dd>If there is no comment already on this line, create a code-level comment
+(started by two comment characters) if the line is empty, or an in-line
+comment (started by one comment character) otherwise
+(<code>octave-indent-for-comment</code>). 
+Point is left after the start of the comment which is properly aligned.
+
+     <br><dt><kbd>C-c ;</kbd><dd>Puts the comment character ‘<samp><span class="samp">#</span></samp>’ (more precisely, the string value of
+<code>octave-comment-start</code>) at the beginning of every line in the
+region (<code>octave-comment-region</code>).  With just <kbd>C-u</kbd> prefix
+argument, uncomment each line in the region.  A numeric prefix argument
+<var>N</var> means use <var>N</var> comment characters.
+
+     <br><dt><kbd>C-c :</kbd><dd>Uncomments every line in the region (<code>octave-uncomment-region</code>).
+
+     <br><dt><kbd>C-c C-p</kbd><dd>Move one line of Octave code backward, skipping empty and comment lines
+(<code>octave-previous-code-line</code>).  With numeric prefix argument
+<var>N</var>, move that many code lines backward (forward if <var>N</var> is
+negative).
+
+     <br><dt><kbd>C-c C-n</kbd><dd>Move one line of Octave code forward, skipping empty and comment lines
+(<code>octave-next-code-line</code>).  With numeric prefix argument <var>N</var>,
+move that many code lines forward (backward if <var>N</var> is negative).
+
+     <br><dt><kbd>C-c C-a</kbd><dd>Move to the `real' beginning of the current line
+(<code>octave-beginning-of-line</code>).  If point is in an empty or comment
+line, simply go to its beginning;  otherwise, move backwards to the
+beginning of the first code line which is not inside a continuation
+statement, i.e., which does not follow a code line ending in ‘<samp><span class="samp">...</span></samp>’
+or ‘<samp><span class="samp">\</span></samp>’, or is inside an open parenthesis list.
+
+     <br><dt><kbd>C-c C-e</kbd><dd>Move to the `real' end of the current line (<code>octave-end-of-line</code>). 
+If point is in a code line, move forward to the end of the first Octave
+code line which does not end in ‘<samp><span class="samp">...</span></samp>’ or ‘<samp><span class="samp">\</span></samp>’ or is inside an
+open parenthesis list.  Otherwise, simply go to the end of the current
+line.
+
+     <br><dt><kbd>C-c M-C-n</kbd><dd>Move forward across one balanced begin-end block of Octave code
+(<code>octave-forward-block</code>).  With numeric prefix argument <var>N</var>,
+move forward across <var>n</var> such blocks (backward if <var>N</var> is
+negative).
+
+     <br><dt><kbd>C-c M-C-p</kbd><dd>Move back across one balanced begin-end block of Octave code
+(<code>octave-backward-block</code>).  With numeric prefix argument <var>N</var>,
+move backward across <var>N</var> such blocks (forward if <var>N</var> is
+negative).
+
+     <br><dt><kbd>C-c M-C-d</kbd><dd>Move forward down one begin-end block level of Octave code
+(<code>octave-down-block</code>).  With numeric prefix argument, do it that
+many times;  a negative argument means move backward, but still go down
+one level.
+
+     <br><dt><kbd>C-c M-C-u</kbd><dd>Move backward out of one begin-end block level of Octave code
+(<code>octave-backward-up-block</code>).  With numeric prefix argument, do it
+that many times; a negative argument means move forward, but still to a
+less deep spot.
+
+     <br><dt><kbd>C-c M-C-h</kbd><dd>Put point at the beginning of this block, mark at the end
+(<code>octave-mark-block</code>). 
+The block marked is the one that contains point or follows point.
+
+     <br><dt><kbd>C-c ]</kbd><dd>Close the current block on a separate line (<code>octave-close-block</code>). 
+An error is signaled if no block to close is found.
+
+     <br><dt><kbd>C-c f</kbd><dd>Insert a function skeleton, prompting for the function's name, arguments
+and return values which have to be entered without parentheses
+(<code>octave-insert-defun</code>).
+
+     <br><dt><kbd>C-c C-h</kbd><dd>Search the function, operator and variable indices of all info files
+with documentation for Octave for entries (<code>octave-help</code>).  If used
+interactively, the entry is prompted for with completion.  If multiple
+matches are found, one can cycle through them using the standard
+‘<samp><span class="samp">,</span></samp>’ (<code>Info-index-next</code>) command of the Info reader.
+
+     <p>The variable <code>octave-help-files</code> is a list of files to search
+through and defaults to <code>'("octave")</code>.  If there is also an Octave
+Local Guide with corresponding info file, say, <samp><span class="file">octave-LG</span></samp>, you can
+have <code>octave-help</code> search both files by
+     <pre class="lisp">          (setq octave-help-files '("octave" "octave-LG"))
+</pre>
+     <p class="noindent">in one of your Emacs startup files.
+
+   </dl>
+
+   <p>A common problem is that the <RET> key does <em>not</em> indent the
+line to where the new text should go after inserting the newline.  This
+is because the standard Emacs convention is that <RET> (aka
+<kbd>C-m</kbd>) just adds a newline, whereas <LFD> (aka <kbd>C-j</kbd>) adds a
+newline and indents it.  This is particularly inconvenient for users with
+keyboards which do not have a special <LFD> key at all;  in such
+cases, it is typically more convenient to use <RET> as the <LFD>
+key (rather than typing <kbd>C-j</kbd>).
+
+   <p>You can make <RET> do this by adding
+<pre class="lisp">     (define-key octave-mode-map "\C-m"
+       'octave-reindent-then-newline-and-indent)
+</pre>
+   <p class="noindent">to one of your Emacs startup files.  Another, more generally applicable
+solution is
+<pre class="lisp">     (defun RET-behaves-as-LFD ()
+       (let ((x (key-binding "\C-j")))
+         (local-set-key "\C-m" x)))
+     (add-hook 'octave-mode-hook 'RET-behaves-as-LFD)
+</pre>
+   <p class="noindent">(this works for all modes by adding to the startup hooks, without having
+to know the particular binding of <RET> in that mode!).  Similar
+considerations apply for using <M-RET> as <M-LFD>.  As Barry
+A. Warsaw <bwarsaw at cnri.reston.va.us> says in the documentation for his
+<code>cc-mode</code>, “This is a very common question.  <code>:-)</code> If you want
+this to be the default behavior, don't lobby me, lobby RMS!”
+
+   <p>The following variables can be used to customize Octave mode.
+
+     <dl>
+<dt><code>octave-auto-indent</code><dd>Non-<code>nil</code> means auto-indent the current line after a semicolon or
+space.  Default is <code>nil</code>.
+
+     <br><dt><code>octave-auto-newline</code><dd>Non-<code>nil</code> means auto-insert a newline and indent after semicolons
+are typed.  The default value is <code>nil</code>.
+
+     <br><dt><code>octave-blink-matching-block</code><dd>Non-<code>nil</code> means show matching begin of block when inserting a space,
+newline or ‘<samp><span class="samp">;</span></samp>’ after an else or end keyword.  Default is <code>t</code>. 
+This is an extremely useful feature for automatically verifying that the
+keywords match—if they don't, an error message is displayed.
+
+     <br><dt><code>octave-block-offset</code><dd>Extra indentation applied to statements in block structures. 
+Default is 2.
+
+     <br><dt><code>octave-continuation-offset</code><dd>Extra indentation applied to Octave continuation lines. 
+Default is 4.
+
+     <br><dt><code>octave-continuation-string</code><dd>String used for Octave continuation lines. 
+Normally ‘<samp><span class="samp">\</span></samp>’.
+
+     <br><dt><code>octave-mode-startup-message</code><dd>If <code>t</code> (default), a startup message is displayed when Octave mode
+is called.
+
+   </dl>
+
+   <p>If Font Lock mode is enabled, Octave mode will display
+     <ul>
+<li>strings in <code>font-lock-string-face</code>
+<li>comments in <code>font-lock-comment-face</code>
+<li>the Octave reserved words (such as all block keywords) and the text
+functions (such as ‘<samp><span class="samp">cd</span></samp>’ or ‘<samp><span class="samp">who</span></samp>’) which are also reserved
+using <code>font-lock-keyword-face</code>
+<li>the built-in operators (‘<samp><span class="samp">&&</span></samp>’, ‘<samp><span class="samp">==</span></samp>’, <small class="dots">...</small>) using
+<code>font-lock-reference-face</code>
+<li>and the function names in function declarations in
+<code>font-lock-function-name-face</code>. 
+</ul>
+
+   <p>There is also rudimentary support for Imenu (currently, function names
+can be indexed).
+
+   <p><a name="index-TAGS-2557"></a><a name="index-Emacs-TAGS-files-2558"></a><a name="index-g_t_0040code_007boctave_002dtags_007d-2559"></a>You can generate TAGS files for Emacs from Octave <samp><span class="file">.m</span></samp> files using
+the shell script <code>octave-tags</code> that is installed alongside your copy of
+Octave.
+
+   <p>Customization of Octave mode can be performed by modification of the
+variable <code>octave-mode-hook</code>.  If the value of this variable is
+non-<code>nil</code>, turning on Octave mode calls its value.
+
+   <p>If you discover a problem with Octave mode, you can conveniently send a
+bug report using <kbd>C-c C-b</kbd> (<code>octave-submit-bug-report</code>).  This
+automatically sets up a mail buffer with version information already
+added.  You just need to add a description of the problem, including a
+reproducible test case and send the message.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Using-Packages.html b/doc/interpreter/HTML/Using-Packages.html
new file mode 100644
index 0000000..296d6ee
--- /dev/null
+++ b/doc/interpreter/HTML/Using-Packages.html
@@ -0,0 +1,53 @@
+<html lang="en">
+<head>
+<title>Using Packages - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Packages.html#Packages" title="Packages">
+<link rel="prev" href="Installing-and-Removing-Packages.html#Installing-and-Removing-Packages" title="Installing and Removing Packages">
+<link rel="next" href="Administrating-Packages.html#Administrating-Packages" title="Administrating Packages">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Using-Packages"></a>
+Next: <a rel="next" accesskey="n" href="Administrating-Packages.html#Administrating-Packages">Administrating Packages</a>,
+Previous: <a rel="previous" accesskey="p" href="Installing-and-Removing-Packages.html#Installing-and-Removing-Packages">Installing and Removing Packages</a>,
+Up: <a rel="up" accesskey="u" href="Packages.html#Packages">Packages</a>
+<hr>
+</div>
+
+<h3 class="section">35.2 Using Packages</h3>
+
+<p>By default installed packages are available from the Octave prompt,
+but it is possible to control this using the <code>pkg load</code> and
+<code>pkg unload</code> commands.  The functions from a package can be
+removed from the Octave path by typing
+
+<pre class="example">     pkg unload package_name
+</pre>
+   <p class="noindent">where <code>package_name</code> is the name of the package to be removed
+from the path.
+
+   <p>In much the same way a package can be added to the Octave path by
+typing
+
+<pre class="example">     pkg load package_name
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Using-Sparse-Matrices-in-Oct_002dFiles.html b/doc/interpreter/HTML/Using-Sparse-Matrices-in-Oct_002dFiles.html
new file mode 100644
index 0000000..bf902be
--- /dev/null
+++ b/doc/interpreter/HTML/Using-Sparse-Matrices-in-Oct_002dFiles.html
@@ -0,0 +1,57 @@
+<html lang="en">
+<head>
+<title>Using Sparse Matrices in Oct-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles" title="Sparse Matrices in Oct-Files">
+<link rel="prev" href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles" title="Creating Sparse Matrices in Oct-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Using-Sparse-Matrices-in-Oct-Files"></a>
+<a name="Using-Sparse-Matrices-in-Oct_002dFiles"></a>
+Previous: <a rel="previous" accesskey="p" href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles">Creating Sparse Matrices in Oct-Files</a>,
+Up: <a rel="up" accesskey="u" href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>
+<hr>
+</div>
+
+<h5 class="subsubsection">A.1.6.3 Using Sparse Matrices in Oct-Files</h5>
+
+<p>Most of the same operators and functions on sparse matrices that are
+available from the Octave are equally available with oct-files. 
+The basic means of extracting a sparse matrix from an <code>octave_value</code>
+and returning them as an <code>octave_value</code>, can be seen in the
+following example
+
+<pre class="example">     octave_value_list retval;
+     
+     SparseMatrix sm = args(0).sparse_matrix_value ();
+     SparseComplexMatrix scm =
+         args(1).sparse_complex_matrix_value ();
+     SparseBoolMatrix sbm = args(2).sparse_bool_matrix_value ();
+     ...
+     retval(2) = sbm;
+     retval(1) = scm;
+     retval(0) = sm;
+</pre>
+   <p>The conversion to an octave-value is handled by the sparse
+<code>octave_value</code> constructors, and so no special care is needed.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Using-the-Emacs-Info-Reader-for-Octave.html b/doc/interpreter/HTML/Using-the-Emacs-Info-Reader-for-Octave.html
new file mode 100644
index 0000000..7d01502
--- /dev/null
+++ b/doc/interpreter/HTML/Using-the-Emacs-Info-Reader-for-Octave.html
@@ -0,0 +1,60 @@
+<html lang="en">
+<head>
+<title>Using the Emacs Info Reader for Octave - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Emacs-Octave-Support.html#Emacs-Octave-Support" title="Emacs Octave Support">
+<link rel="prev" href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs" title="Running Octave From Within Emacs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Using-the-Emacs-Info-Reader-for-Octave"></a>
+Previous: <a rel="previous" accesskey="p" href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs">Running Octave From Within Emacs</a>,
+Up: <a rel="up" accesskey="u" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>
+<hr>
+</div>
+
+<h3 class="appendixsec">G.4 Using the Emacs Info Reader for Octave</h3>
+
+<p>You may also use the Emacs Info reader with Octave's <code>doc</code> function. 
+For this, the package <samp><span class="file">gnuserv</span></samp> needs to be installed.
+
+   <p>If <samp><span class="file">gnuserv</span></samp> is installed, add the lines
+<pre class="lisp">     (autoload 'octave-help "octave-hlp" nil t)
+     (require 'gnuserv)
+     (gnuserv-start)
+</pre>
+   <p class="noindent">to your <samp><span class="file">.emacs</span></samp> file.
+
+   <p>You can use either `plain' Emacs Info or the function <code>octave-help</code>
+as your Octave info reader (for ‘<samp><span class="samp">help -i</span></samp>’).  In the former case,
+use <code>info_program ("info-emacs-info")</code>. 
+The latter is perhaps more attractive because it allows to look up keys
+in the indices of <em>several</em> info files related to Octave (provided
+that the Emacs variable <code>octave-help-files</code> is set correctly).  In
+this case, use <code>info_program ("info-emacs-octave-help")</code>.
+
+   <p>If you use Octave from within Emacs, it is best to add these settings to
+your <samp><span class="file">~/.emacs-octave</span></samp> startup file (or the file pointed to by the
+Emacs variable <code>inferior-octave-startup-file</code>). 
+<!-- @include grammar.texi -->
+
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Utility-Functions.html b/doc/interpreter/HTML/Utility-Functions.html
new file mode 100644
index 0000000..c968079
--- /dev/null
+++ b/doc/interpreter/HTML/Utility-Functions.html
@@ -0,0 +1,590 @@
+<html lang="en">
+<head>
+<title>Utility Functions - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arithmetic.html#Arithmetic" title="Arithmetic">
+<link rel="prev" href="Sums-and-Products.html#Sums-and-Products" title="Sums and Products">
+<link rel="next" href="Special-Functions.html#Special-Functions" title="Special Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Utility-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Special-Functions.html#Special-Functions">Special Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a>,
+Up: <a rel="up" accesskey="u" href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<hr>
+</div>
+
+<h3 class="section">17.5 Utility Functions</h3>
+
+<!-- mappers.cc -->
+<p><a name="doc_002dceil"></a>
+
+<div class="defun">
+— Mapping Function:  <b>ceil</b> (<var>x</var>)<var><a name="index-ceil-1436"></a></var><br>
+<blockquote><p>Return the smallest integer not less than <var>x</var>.  This is equivalent to
+rounding towards positive infinity.  If <var>x</var> is
+complex, return <code>ceil (real (</code><var>x</var><code>)) + ceil (imag (</code><var>x</var><code>)) * I</code>.
+     <pre class="example">          ceil ([-2.7, 2.7])
+               -2   3
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfloor.html#doc_002dfloor">floor</a>, <a href="doc_002dround.html#doc_002dround">round</a>, <a href="doc_002dfix.html#doc_002dfix">fix</a>. 
+</p></blockquote></div>
+
+<!-- ./linear-algebra/cross.m -->
+   <p><a name="doc_002dcross"></a>
+
+<div class="defun">
+— Function File:  <b>cross</b> (<var>x, y</var>)<var><a name="index-cross-1437"></a></var><br>
+— Function File:  <b>cross</b> (<var>x, y, dim</var>)<var><a name="index-cross-1438"></a></var><br>
+<blockquote><p>Compute the vector cross product of two 3-dimensional vectors
+<var>x</var> and <var>y</var>.
+
+     <pre class="example">          cross ([1,1,0], [0,1,1])
+                [ 1; -1; 1 ]
+</pre>
+        <p>If <var>x</var> and <var>y</var> are matrices, the cross product is applied
+along the first dimension with 3 elements.  The optional argument
+<var>dim</var> forces the cross product to be calculated along
+the specified dimension. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddot.html#doc_002ddot">dot</a>. 
+</p></blockquote></div>
+
+<!-- ./general/del2.m -->
+   <p><a name="doc_002ddel2"></a>
+
+<div class="defun">
+— Function File: <var>d</var> = <b>del2</b> (<var>m</var>)<var><a name="index-del2-1439"></a></var><br>
+— Function File: <var>d</var> = <b>del2</b> (<var>m, h</var>)<var><a name="index-del2-1440"></a></var><br>
+— Function File: <var>d</var> = <b>del2</b> (<var>m, dx, dy, <small class="dots">...</small></var>)<var><a name="index-del2-1441"></a></var><br>
+<blockquote>
+        <p>Calculate the discrete Laplace
+operator. 
+For a 2-dimensional matrix <var>m</var> this is defined as
+
+     <pre class="example">                1    / d^2            d^2         \
+          D  = --- * | ---  M(x,y) +  ---  M(x,y) |
+                4    \ dx^2           dy^2        /
+</pre>
+        <p>For N-dimensional arrays the sum in parentheses is expanded to include second derivatives
+over the additional higher dimensions.
+
+        <p>The spacing between evaluation points may be defined by <var>h</var>, which is a
+scalar defining the equidistant spacing in all dimensions.  Alternatively,
+the spacing in each dimension may be defined separately by <var>dx</var>, <var>dy</var>,
+etc.  A scalar spacing argument defines equidistant spacing, whereas a vector
+argument can be used to specify variable spacing.  The length of the spacing vectors
+must match the respective dimension of <var>m</var>.  The default spacing value
+is 1.
+
+        <p>At least 3 data points are needed for each dimension.  Boundary points are
+calculated from the linear extrapolation of interior points.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgradient.html#doc_002dgradient">gradient</a>, <a href="doc_002ddiff.html#doc_002ddiff">diff</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/factor.m -->
+   <p><a name="doc_002dfactor"></a>
+
+<div class="defun">
+— Function File: <var>p</var> = <b>factor</b> (<var>q</var>)<var><a name="index-factor-1442"></a></var><br>
+— Function File: [<var>p</var>, <var>n</var>] = <b>factor</b> (<var>q</var>)<var><a name="index-factor-1443"></a></var><br>
+<blockquote>
+        <p>Return prime factorization of <var>q</var>.  That is, <code>prod (</code><var>p</var><code>)
+== </code><var>q</var> and every element of <var>p</var> is a prime number.  If
+<var>q</var><code> == 1</code>, returns 1.
+
+        <p>With two output arguments, return the unique primes <var>p</var> and
+their multiplicities.  That is, <code>prod (</code><var>p</var><code> .^ </code><var>n</var><code>) ==
+</code><var>q</var>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dgcd.html#doc_002dgcd">gcd</a>, <a href="doc_002dlcm.html#doc_002dlcm">lcm</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/factorial.m -->
+   <p><a name="doc_002dfactorial"></a>
+
+<div class="defun">
+— Function File:  <b>factorial</b> (<var>n</var>)<var><a name="index-factorial-1444"></a></var><br>
+<blockquote><p>Return the factorial of <var>n</var> where <var>n</var> is a positive integer.  If
+<var>n</var> is a scalar, this is equivalent to <code>prod (1:</code><var>n</var><code>)</code>.  For
+vector or matrix arguments, return the factorial of each element in the
+array.  For non-integers see the generalized factorial function
+<code>gamma</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprod.html#doc_002dprod">prod</a>, <a href="doc_002dgamma.html#doc_002dgamma">gamma</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dfix"></a>
+
+<div class="defun">
+— Mapping Function:  <b>fix</b> (<var>x</var>)<var><a name="index-fix-1445"></a></var><br>
+<blockquote><p>Truncate fractional portion of <var>x</var> and return the integer portion.  This
+is equivalent to rounding towards zero.  If <var>x</var> is complex, return
+<code>fix (real (</code><var>x</var><code>)) + fix (imag (</code><var>x</var><code>)) * I</code>.
+     <pre class="example">          fix ([-2.7, 2.7])
+              -2   2
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dceil.html#doc_002dceil">ceil</a>, <a href="doc_002dfloor.html#doc_002dfloor">floor</a>, <a href="doc_002dround.html#doc_002dround">round</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dfloor"></a>
+
+<div class="defun">
+— Mapping Function:  <b>floor</b> (<var>x</var>)<var><a name="index-floor-1446"></a></var><br>
+<blockquote><p>Return the largest integer not greater than <var>x</var>.  This is equivalent to
+rounding towards negative infinity.  If <var>x</var> is
+complex, return <code>floor (real (</code><var>x</var><code>)) + floor (imag (</code><var>x</var><code>)) * I</code>.
+     <pre class="example">          floor ([-2.7, 2.7])
+                -3   2
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dceil.html#doc_002dceil">ceil</a>, <a href="doc_002dround.html#doc_002dround">round</a>, <a href="doc_002dfix.html#doc_002dfix">fix</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dfmod"></a>
+
+<div class="defun">
+— Mapping Function:  <b>fmod</b> (<var>x, y</var>)<var><a name="index-fmod-1447"></a></var><br>
+<blockquote><p>Compute the floating point remainder of dividing <var>x</var> by <var>y</var>
+using the C library function <code>fmod</code>.  The result has the same
+sign as <var>x</var>.  If <var>y</var> is zero, the result is implementation-dependent. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmod.html#doc_002dmod">mod</a>, <a href="doc_002drem.html#doc_002drem">rem</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/gcd.cc -->
+   <p><a name="doc_002dgcd"></a>
+
+<div class="defun">
+— Loadable Function: <var>g</var> = <b>gcd</b> (<var>a</var>)<var><a name="index-gcd-1448"></a></var><br>
+— Loadable Function: <var>g</var> = <b>gcd</b> (<var>a1, a2, <small class="dots">...</small></var>)<var><a name="index-gcd-1449"></a></var><br>
+— Loadable Function: [<var>g</var>, <var>v1</var>, <small class="dots">...</small>] = <b>gcd</b> (<var>a1, a2, <small class="dots">...</small></var>)<var><a name="index-gcd-1450"></a></var><br>
+<blockquote>
+        <p>Compute the greatest common divisor of the elements of <var>a</var>.  If more
+than one argument is given all arguments must be the same size or scalar. 
+  In this case the greatest common divisor is calculated for each element
+individually.  All elements must be integers.  For example,
+
+     <pre class="example">          gcd ([15, 20])
+                5
+</pre>
+        <p class="noindent">and
+
+     <pre class="example">          gcd ([15, 9], [20, 18])
+                5  9
+</pre>
+        <p>Optional return arguments <var>v1</var>, etc., contain integer vectors such
+that,
+
+     <pre class="example">          <var>g</var> = <var>v1</var> .* <var>a1</var> + <var>v2</var> .* <var>a2</var> + ...
+</pre>
+        <p>For backward compatibility with previous versions of this function, when
+all arguments are scalar, a single return argument <var>v1</var> containing
+all of the values of <var>v1</var>, <small class="dots">...</small> is acceptable. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlcm.html#doc_002dlcm">lcm</a>, <a href="doc_002dfactor.html#doc_002dfactor">factor</a>. 
+</p></blockquote></div>
+
+<!-- ./general/gradient.m -->
+   <p><a name="doc_002dgradient"></a>
+
+<div class="defun">
+— Function File: <var>dx</var> = <b>gradient</b> (<var>m</var>)<var><a name="index-gradient-1451"></a></var><br>
+— Function File: [<var>dx</var>, <var>dy</var>, <var>dz</var>, <small class="dots">...</small>] = <b>gradient</b> (<var>m</var>)<var><a name="index-gradient-1452"></a></var><br>
+— Function File: [<small class="dots">...</small>] = <b>gradient</b> (<var>m, s</var>)<var><a name="index-gradient-1453"></a></var><br>
+— Function File: [<small class="dots">...</small>] = <b>gradient</b> (<var>m, x, y, z, <small class="dots">...</small></var>)<var><a name="index-gradient-1454"></a></var><br>
+— Function File: [<small class="dots">...</small>] = <b>gradient</b> (<var>f, x0</var>)<var><a name="index-gradient-1455"></a></var><br>
+— Function File: [<small class="dots">...</small>] = <b>gradient</b> (<var>f, x0, s</var>)<var><a name="index-gradient-1456"></a></var><br>
+— Function File: [<small class="dots">...</small>] = <b>gradient</b> (<var>f, x0, x, y, <small class="dots">...</small></var>)<var><a name="index-gradient-1457"></a></var><br>
+<blockquote>
+        <p>Calculate the gradient of sampled data or a function.  If <var>m</var>
+is a vector, calculate the one-dimensional gradient of <var>m</var>.  If
+<var>m</var> is a matrix the gradient is calculated for each dimension.
+
+        <p><code>[</code><var>dx</var><code>, </code><var>dy</var><code>] = gradient (</code><var>m</var><code>)</code> calculates the one
+dimensional gradient for <var>x</var> and <var>y</var> direction if <var>m</var> is a
+matrix.  Additional return arguments can be use for multi-dimensional
+matrices.
+
+        <p>A constant spacing between two points can be provided by the
+<var>s</var> parameter.  If <var>s</var> is a scalar, it is assumed to be the spacing
+for all dimensions. 
+Otherwise, separate values of the spacing can be supplied by
+the <var>x</var>, <small class="dots">...</small> arguments.  Scalar values specify an equidistant spacing. 
+Vector values for the <var>x</var>, <small class="dots">...</small> arguments specify the coordinate for that
+dimension.  The length must match their respective dimension of <var>m</var>.
+
+        <p>At boundary points a linear extrapolation is applied.  Interior points
+are calculated with the first approximation of the numerical gradient
+
+     <pre class="example">          y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).
+</pre>
+        <p>If the first argument <var>f</var> is a function handle, the gradient of the
+function at the points in <var>x0</var> is approximated using central
+difference.  For example, <code>gradient (@cos, 0)</code> approximates the
+gradient of the cosine function in the point x0 = 0.  As with
+sampled data, the spacing values between the points from which the
+gradient is estimated can be set via the <var>s</var> or <var>dx</var>,
+<var>dy</var>, <small class="dots">...</small> arguments.  By default a spacing of 1 is used. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002ddiff.html#doc_002ddiff">diff</a>, <a href="doc_002ddel2.html#doc_002ddel2">del2</a>. 
+</p></blockquote></div>
+
+<!-- data.cc -->
+   <p><a name="doc_002dhypot"></a>
+
+<div class="defun">
+— Built-in Function:  <b>hypot</b> (<var>x, y</var>)<var><a name="index-hypot-1458"></a></var><br>
+<blockquote><p>Compute the element-by-element square root of the sum of the squares of
+<var>x</var> and <var>y</var>.  This is equivalent to
+<code>sqrt (</code><var>x</var><code>.^2 + </code><var>y</var><code>.^2)</code>, but calculated in a manner that
+avoids overflows for large values of <var>x</var> or <var>y</var>. 
+</p></blockquote></div>
+
+<!-- ./elfun/lcm.m -->
+   <p><a name="doc_002dlcm"></a>
+
+<div class="defun">
+— Mapping Function:  <b>lcm</b> (<var>x</var>)<var><a name="index-lcm-1459"></a></var><br>
+— Mapping Function:  <b>lcm</b> (<var>x, <small class="dots">...</small></var>)<var><a name="index-lcm-1460"></a></var><br>
+<blockquote><p>Compute the least common multiple of the elements of <var>x</var>, or
+of the list of all arguments.  For example,
+
+     <pre class="example">          lcm (a1, ..., ak)
+</pre>
+        <p class="noindent">is the same as
+
+     <pre class="example">          lcm ([a1, ..., ak]).
+</pre>
+        <p>All elements must be the same size or scalar. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dfactor.html#doc_002dfactor">factor</a>, <a href="doc_002dgcd.html#doc_002dgcd">gcd</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/list_primes.m -->
+   <p><a name="doc_002dlist_005fprimes"></a>
+
+<div class="defun">
+— Function File:  <b>list_primes</b> (<var>n</var>)<var><a name="index-list_005fprimes-1461"></a></var><br>
+<blockquote><p>List the first <var>n</var> primes.  If <var>n</var> is unspecified, the first
+25 primes are listed.
+
+        <p>The algorithm used is from page 218 of the TeXbook. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dprimes.html#doc_002dprimes">primes</a>, <a href="doc_002disprime.html#doc_002disprime">isprime</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/max.cc -->
+   <p><a name="doc_002dmax"></a>
+
+<div class="defun">
+— Loadable Function:  <b>max</b> (<var>x</var>)<var><a name="index-max-1462"></a></var><br>
+— Loadable Function:  <b>max</b> (<var>x, y</var>)<var><a name="index-max-1463"></a></var><br>
+— Loadable Function:  <b>max</b> (<var>x, y, dim</var>)<var><a name="index-max-1464"></a></var><br>
+— Loadable Function: [<var>w</var>, <var>iw</var>] = <b>max</b> (<var>x</var>)<var><a name="index-max-1465"></a></var><br>
+<blockquote><p>For a vector argument, return the maximum value.  For a matrix
+argument, return the maximum value from each column, as a row
+vector, or over the dimension <var>dim</var> if defined.  For two matrices
+(or a matrix and scalar), return the pair-wise maximum. 
+Thus,
+
+     <pre class="example">          max (max (<var>x</var>))
+</pre>
+        <p class="noindent">returns the largest element of the matrix <var>x</var>, and
+
+     <pre class="example">          max (2:5, pi)
+                3.1416  3.1416  4.0000  5.0000
+</pre>
+        <p class="noindent">compares each element of the range <code>2:5</code> with <code>pi</code>, and
+returns a row vector of the maximum values.
+
+        <p>For complex arguments, the magnitude of the elements are used for
+comparison.
+
+        <p>If called with one input and two output arguments,
+<code>max</code> also returns the first index of the
+maximum value(s).  Thus,
+
+     <pre class="example">          [x, ix] = max ([1, 3, 5, 2, 5])
+                x = 5
+                  ix = 3
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmin.html#doc_002dmin">min</a>, <a href="doc_002dcummax.html#doc_002dcummax">cummax</a>, <a href="doc_002dcummin.html#doc_002dcummin">cummin</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/max.cc -->
+   <p><a name="doc_002dmin"></a>
+
+<div class="defun">
+— Loadable Function:  <b>min</b> (<var>x</var>)<var><a name="index-min-1466"></a></var><br>
+— Loadable Function:  <b>min</b> (<var>x, y</var>)<var><a name="index-min-1467"></a></var><br>
+— Loadable Function:  <b>min</b> (<var>x, y, dim</var>)<var><a name="index-min-1468"></a></var><br>
+— Loadable Function: [<var>w</var>, <var>iw</var>] = <b>min</b> (<var>x</var>)<var><a name="index-min-1469"></a></var><br>
+<blockquote><p>For a vector argument, return the minimum value.  For a matrix
+argument, return the minimum value from each column, as a row
+vector, or over the dimension <var>dim</var> if defined.  For two matrices
+(or a matrix and scalar), return the pair-wise minimum. 
+Thus,
+
+     <pre class="example">          min (min (<var>x</var>))
+</pre>
+        <p class="noindent">returns the smallest element of <var>x</var>, and
+
+     <pre class="example">          min (2:5, pi)
+                2.0000  3.0000  3.1416  3.1416
+</pre>
+        <p class="noindent">compares each element of the range <code>2:5</code> with <code>pi</code>, and
+returns a row vector of the minimum values.
+
+        <p>For complex arguments, the magnitude of the elements are used for
+comparison.
+
+        <p>If called with one input and two output arguments,
+<code>min</code> also returns the first index of the
+minimum value(s).  Thus,
+
+     <pre class="example">          [x, ix] = min ([1, 3, 0, 2, 0])
+                x = 0
+                  ix = 3
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmax.html#doc_002dmax">max</a>, <a href="doc_002dcummin.html#doc_002dcummin">cummin</a>, <a href="doc_002dcummax.html#doc_002dcummax">cummax</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/max.cc -->
+   <p><a name="doc_002dcummax"></a>
+
+<div class="defun">
+— Loadable Function:  <b>cummax</b> (<var>x</var>)<var><a name="index-cummax-1470"></a></var><br>
+— Loadable Function:  <b>cummax</b> (<var>x, dim</var>)<var><a name="index-cummax-1471"></a></var><br>
+— Loadable Function: [<var>w</var>, <var>iw</var>] = <b>cummax</b> (<var>x</var>)<var><a name="index-cummax-1472"></a></var><br>
+<blockquote><p>Return the cumulative maximum values along dimension <var>dim</var>.  If <var>dim</var>
+is unspecified it defaults to column-wise operation.  For example,
+
+     <pre class="example">          cummax ([1 3 2 6 4 5])
+                1  3  3  6  6  6
+</pre>
+        <p>The call
+     <pre class="example">          [w, iw] = cummax (x, dim)
+</pre>
+        <p class="noindent">is equivalent to the following code:
+     <pre class="example">          w = iw = zeros (size (x));
+          idxw = idxx = repmat ({':'}, 1, ndims (x));
+          for i = 1:size (x, dim)
+            idxw{dim} = i; idxx{dim} = 1:i;
+            [w(idxw{:}), iw(idxw{:})] = max(x(idxx{:}), [], dim);
+          endfor
+</pre>
+        <p class="noindent">but computed in a much faster manner. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcummin.html#doc_002dcummin">cummin</a>, <a href="doc_002dmax.html#doc_002dmax">max</a>, <a href="doc_002dmin.html#doc_002dmin">min</a>. 
+</p></blockquote></div>
+
+<!-- ./DLD-FUNCTIONS/max.cc -->
+   <p><a name="doc_002dcummin"></a>
+
+<div class="defun">
+— Loadable Function:  <b>cummin</b> (<var>x</var>)<var><a name="index-cummin-1473"></a></var><br>
+— Loadable Function:  <b>cummin</b> (<var>x, dim</var>)<var><a name="index-cummin-1474"></a></var><br>
+— Loadable Function: [<var>w</var>, <var>iw</var>] = <b>cummin</b> (<var>x</var>)<var><a name="index-cummin-1475"></a></var><br>
+<blockquote><p>Return the cumulative minimum values along dimension <var>dim</var>.  If <var>dim</var>
+is unspecified it defaults to column-wise operation.  For example,
+
+     <pre class="example">          cummin ([5 4 6 2 3 1])
+                5  4  4  2  2  1
+</pre>
+        <p>The call
+     <pre class="example">            [w, iw] = cummin (x, dim)
+</pre>
+        <p class="noindent">is equivalent to the following code:
+     <pre class="example">          w = iw = zeros (size (x));
+          idxw = idxx = repmat ({':'}, 1, ndims (x));
+          for i = 1:size (x, dim)
+            idxw{dim} = i; idxx{dim} = 1:i;
+            [w(idxw{:}), iw(idxw{:})] = min(x(idxx{:}), [], dim);
+          endfor
+</pre>
+        <p class="noindent">but computed in a much faster manner. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dcummax.html#doc_002dcummax">cummax</a>, <a href="doc_002dmin.html#doc_002dmin">min</a>, <a href="doc_002dmax.html#doc_002dmax">max</a>. 
+</p></blockquote></div>
+
+<!-- ./general/mod.m -->
+   <p><a name="doc_002dmod"></a>
+
+<div class="defun">
+— Mapping Function:  <b>mod</b> (<var>x, y</var>)<var><a name="index-mod-1476"></a></var><br>
+<blockquote><p>Compute the modulo of <var>x</var> and <var>y</var>.  Conceptually this is given by
+
+     <pre class="example">          x - y .* floor (x ./ y)
+</pre>
+        <p>and is written such that the correct modulus is returned for
+integer types.  This function handles negative values correctly.  That
+is, <code>mod (-1, 3)</code> is 2, not -1, as <code>rem (-1, 3)</code> returns. 
+<code>mod (</code><var>x</var><code>, 0)</code> returns <var>x</var>.
+
+        <p>An error results if the dimensions of the arguments do not agree, or if
+either of the arguments is complex. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002drem.html#doc_002drem">rem</a>, <a href="doc_002dfmod.html#doc_002dfmod">fmod</a>. 
+</p></blockquote></div>
+
+<!-- ./specfun/primes.m -->
+   <p><a name="doc_002dprimes"></a>
+
+<div class="defun">
+— Function File:  <b>primes</b> (<var>n</var>)<var><a name="index-primes-1477"></a></var><br>
+<blockquote>
+        <p>Return all primes up to <var>n</var>.
+
+        <p>The algorithm used is the Sieve of Erastothenes.
+
+        <p>Note that if you need a specific number of primes you can use the
+fact the distance from one prime to the next is, on average,
+proportional to the logarithm of the prime.  Integrating, one finds
+that there are about k primes less than
+k*log(5*k). 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dlist_005fprimes.html#doc_002dlist_005fprimes">list_primes</a>, <a href="doc_002disprime.html#doc_002disprime">isprime</a>. 
+</p></blockquote></div>
+
+<!-- ./general/rem.m -->
+   <p><a name="doc_002drem"></a>
+
+<div class="defun">
+— Mapping Function:  <b>rem</b> (<var>x, y</var>)<var><a name="index-rem-1478"></a></var><br>
+<blockquote><p>Return the remainder of the division <var>x</var><code> / </code><var>y</var>, computed
+using the expression
+
+     <pre class="example">          x - y .* fix (x ./ y)
+</pre>
+        <p>An error message is printed if the dimensions of the arguments do not
+agree, or if either of the arguments is complex. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dmod.html#doc_002dmod">mod</a>, <a href="doc_002dfmod.html#doc_002dfmod">fmod</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dround"></a>
+
+<div class="defun">
+— Mapping Function:  <b>round</b> (<var>x</var>)<var><a name="index-round-1479"></a></var><br>
+<blockquote><p>Return the integer nearest to <var>x</var>.  If <var>x</var> is complex, return
+<code>round (real (</code><var>x</var><code>)) + round (imag (</code><var>x</var><code>)) * I</code>.
+     <pre class="example">          round ([-2.7, 2.7])
+                -3   3
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dceil.html#doc_002dceil">ceil</a>, <a href="doc_002dfloor.html#doc_002dfloor">floor</a>, <a href="doc_002dfix.html#doc_002dfix">fix</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002droundb"></a>
+
+<div class="defun">
+— Mapping Function:  <b>roundb</b> (<var>x</var>)<var><a name="index-roundb-1480"></a></var><br>
+<blockquote><p>Return the integer nearest to <var>x</var>.  If there are two nearest
+integers, return the even one (banker's rounding).  If <var>x</var> is complex,
+return <code>roundb (real (</code><var>x</var><code>)) + roundb (imag (</code><var>x</var><code>)) * I</code>. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dround.html#doc_002dround">round</a>. 
+</p></blockquote></div>
+
+<!-- mappers.cc -->
+   <p><a name="doc_002dsign"></a>
+
+<div class="defun">
+— Mapping Function:  <b>sign</b> (<var>x</var>)<var><a name="index-sign-1481"></a></var><br>
+<blockquote><p>Compute the <dfn>signum</dfn> function, which is defined as
+
+     <pre class="example">                     -1, x < 0;
+          sign (x) =  0, x = 0;
+                      1, x > 0.
+</pre>
+        <p>For complex arguments, <code>sign</code> returns <code>x ./ abs (</code><var>x</var><code>)</code>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Variable_002dlength-Argument-Lists.html b/doc/interpreter/HTML/Variable_002dlength-Argument-Lists.html
new file mode 100644
index 0000000..82b95b7
--- /dev/null
+++ b/doc/interpreter/HTML/Variable_002dlength-Argument-Lists.html
@@ -0,0 +1,129 @@
+<html lang="en">
+<head>
+<title>Variable-length Argument Lists - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Multiple-Return-Values.html#Multiple-Return-Values" title="Multiple Return Values">
+<link rel="next" href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists" title="Variable-length Return Lists">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Variable-length-Argument-Lists"></a>
+<a name="Variable_002dlength-Argument-Lists"></a>
+Next: <a rel="next" accesskey="n" href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a>,
+Previous: <a rel="previous" accesskey="p" href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.3 Variable-length Argument Lists</h3>
+
+<p><a name="index-variable_002dlength-argument-lists-603"></a><a name="index-g_t_0040code_007bvarargin_007d-604"></a>
+Sometimes the number of input arguments is not known when the function
+is defined.  As an example think of a function that returns the smallest
+of all its input arguments.  For example,
+
+<pre class="example">     a = smallest (1, 2, 3);
+     b = smallest (1, 2, 3, 4);
+</pre>
+   <p class="noindent">In this example both <code>a</code> and <code>b</code> would be 1.  One way to write
+the <code>smallest</code> function is
+
+<pre class="example">     function val = smallest (arg1, arg2, arg3, arg4, arg5)
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">and then use the value of <code>nargin</code> to determine which of the input
+arguments should be considered.  The problem with this approach is
+that it can only handle a limited number of input arguments.
+
+   <p>If the special parameter name <code>varargin</code> appears at the end of a
+function parameter list it indicates that the function takes a variable
+number of input arguments.  Using <code>varargin</code> the function
+looks like this
+
+<pre class="example">     function val = smallest (varargin)
+       <var>body</var>
+     endfunction
+</pre>
+   <p class="noindent">In the function body the input arguments can be accessed through the
+variable <code>varargin</code>.  This variable is a cell array containing
+all the input arguments.  See <a href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>, for details on working
+with cell arrays.  The <code>smallest</code> function can now be defined
+like this
+
+<pre class="example">     function val = smallest (varargin)
+       val = min ([varargin{:}]);
+     endfunction
+</pre>
+   <p class="noindent">This implementation handles any number of input arguments, but it's also
+a very simple solution to the problem.
+
+   <p>A slightly more complex example of <code>varargin</code> is a function
+<code>print_arguments</code> that prints all input arguments.  Such a function
+can be defined like this
+
+<pre class="example">     function print_arguments (varargin)
+       for i = 1:length (varargin)
+         printf ("Input argument %d: ", i);
+         disp (varargin{i});
+       endfor
+     endfunction
+</pre>
+   <p class="noindent">This function produces output like this
+
+<pre class="example">     print_arguments (1, "two", 3);
+          -| Input argument 1:  1
+          -| Input argument 2: two
+          -| Input argument 3:  3
+</pre>
+   <!-- ./miscellaneous/parseparams.m -->
+   <p><a name="doc_002dparseparams"></a>
+
+<div class="defun">
+— Function File: [<var>reg</var>, <var>prop</var>] = <b>parseparams</b> (<var>params</var>)<var><a name="index-parseparams-605"></a></var><br>
+<blockquote><p>Return in <var>reg</var> the cell elements of <var>param</var> up to the first
+string element and in <var>prop</var> all remaining elements beginning
+with the first string element.  For example
+
+     <pre class="example">          [reg, prop] = parseparams ({1, 2, "linewidth", 10})
+          reg =
+          {
+            [1,1] = 1
+            [1,2] = 2
+          }
+          prop =
+          {
+            [1,1] = linewidth
+            [1,2] = 10
+          }
+</pre>
+        <p>The parseparams function may be used to separate 'regular'
+arguments and additional arguments given as property/value pairs of
+the <var>varargin</var> cell array. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dvarargin.html#doc_002dvarargin">varargin</a>. 
+</p></blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Variable_002dlength-Return-Lists.html b/doc/interpreter/HTML/Variable_002dlength-Return-Lists.html
new file mode 100644
index 0000000..17decfc
--- /dev/null
+++ b/doc/interpreter/HTML/Variable_002dlength-Return-Lists.html
@@ -0,0 +1,98 @@
+<html lang="en">
+<head>
+<title>Variable-length Return Lists - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Functions-and-Scripts.html#Functions-and-Scripts" title="Functions and Scripts">
+<link rel="prev" href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists" title="Variable-length Argument Lists">
+<link rel="next" href="Returning-From-a-Function.html#Returning-From-a-Function" title="Returning From a Function">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Variable-length-Return-Lists"></a>
+<a name="Variable_002dlength-Return-Lists"></a>
+Next: <a rel="next" accesskey="n" href="Returning-From-a-Function.html#Returning-From-a-Function">Returning From a Function</a>,
+Previous: <a rel="previous" accesskey="p" href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a>,
+Up: <a rel="up" accesskey="u" href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<hr>
+</div>
+
+<h3 class="section">11.4 Variable-length Return Lists</h3>
+
+<p><a name="index-variable_002dlength-return-lists-606"></a><a name="index-g_t_0040code_007bvarargout_007d-607"></a>
+It is possible to return a variable number of output arguments from a
+function using a syntax that's similar to the one used with the
+special <code>varargin</code> parameter name.  To let a function return a
+variable number of output arguments the special output parameter name
+<code>varargout</code> is used.  As with <code>varargin</code>, <code>varargout</code> is
+a cell array that will contain the requested output arguments.
+
+   <p>As an example the following function sets the first output argument to
+1, the second to 2, and so on.
+
+<pre class="example">     function varargout = one_to_n ()
+       for i = 1:nargout
+         varargout{i} = i;
+       endfor
+     endfunction
+</pre>
+   <p class="noindent">When called this function returns values like this
+
+<pre class="example">     [a, b, c] = one_to_n ()
+           a =  1
+           b =  2
+           c =  3
+</pre>
+   <p>If <code>varargin</code> (<code>varargout</code>) does not appear as the last
+element of the input (output) parameter list, then it is not special,
+and is handled the same as any other parameter name.
+
+<!-- ./general/deal.m -->
+   <p><a name="doc_002ddeal"></a>
+
+<div class="defun">
+— Function File: [<var>r1</var>, <var>r2</var>, <small class="dots">...</small>, <var>rn</var>] = <b>deal</b> (<var>a</var>)<var><a name="index-deal-608"></a></var><br>
+— Function File: [<var>r1</var>, <var>r2</var>, <small class="dots">...</small>, <var>rn</var>] = <b>deal</b> (<var>a1, a2, <small class="dots">...</small>, an</var>)<var><a name="index-deal-609"></a></var><br>
+<blockquote>
+        <p>Copy the input parameters into the corresponding output parameters. 
+If only one input parameter is supplied, its value is copied to each
+of the outputs.
+
+        <p>For example,
+
+     <pre class="example">          [a, b, c] = deal (x, y, z);
+</pre>
+        <p class="noindent">is equivalent to
+
+     <pre class="example">          a = x;
+          b = y;
+          c = z;
+</pre>
+        <p class="noindent">and
+
+     <pre class="example">          [a, b, c] = deal (x);
+</pre>
+        <p class="noindent">is equivalent to
+
+     <pre class="example">          a = b = c = x;
+</pre>
+        </blockquote></div>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Variables.html b/doc/interpreter/HTML/Variables.html
new file mode 100644
index 0000000..4602a94
--- /dev/null
+++ b/doc/interpreter/HTML/Variables.html
@@ -0,0 +1,185 @@
+<html lang="en">
+<head>
+<title>Variables - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Data-Containers.html#Data-Containers" title="Data Containers">
+<link rel="next" href="Expressions.html#Expressions" title="Expressions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Variables"></a>
+Next: <a rel="next" accesskey="n" href="Expressions.html#Expressions">Expressions</a>,
+Previous: <a rel="previous" accesskey="p" href="Data-Containers.html#Data-Containers">Data Containers</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">7 Variables</h2>
+
+<p><a name="index-variables_002c-user_002ddefined-412"></a><a name="index-user_002ddefined-variables-413"></a>
+Variables let you give names to values and refer to them later.  You have
+already seen variables in many of the examples.  The name of a variable
+must be a sequence of letters, digits and underscores, but it may not begin
+with a digit.  Octave does not enforce a limit on the length of variable
+names, but it is seldom useful to have variables with names longer than
+about 30 characters.  The following are all valid variable names
+
+   <p><a name="index-job-hunting-414"></a><a name="index-getting-a-good-job-415"></a><a name="index-flying-high-and-fast-416"></a>
+<pre class="example">     x
+     x15
+     __foo_bar_baz__
+     fucnrdthsucngtagdjb
+</pre>
+   <p class="noindent">However, names like <code>__foo_bar_baz__</code> that begin and end with two
+underscores are understood to be reserved for internal use by Octave. 
+You should not use them in code you write, except to access Octave's
+documented internal variables and built-in symbolic constants.
+
+   <p>Case is significant in variable names.  The symbols <code>a</code> and
+<code>A</code> are distinct variables.
+
+   <p>A variable name is a valid expression by itself.  It represents the
+variable's current value.  Variables are given new values with
+<dfn>assignment operators</dfn> and <dfn>increment operators</dfn>. 
+See <a href="Assignment-Ops.html#Assignment-Ops">Assignment Expressions</a>.
+
+   <p>There is one built-in variable with a special meaning.  The <code>ans</code> variable
+always contains the result of the last computation, where the output wasn't
+assigned to any variable.  The code <code>a = cos (pi)</code> will assign the value -1
+to the variable <code>a</code>, but will not change the value of <code>ans</code>.  However,
+the code <code>cos (pi)</code> will set the value of <code>ans</code> to -1.
+
+   <p>Variables in Octave do not have fixed types, so it is possible to first
+store a numeric value in a variable and then to later use the same name
+to hold a string value in the same program.  Variables may not be used
+before they have been given a value.  Doing so results in an error.
+
+   <p><a name="index-g_t_0040code_007bans_007d-417"></a><!-- ./miscellaneous/ans.m -->
+<a name="doc_002dans"></a>
+
+<div class="defun">
+— Automatic Variable: <b>ans</b><var><a name="index-ans-418"></a></var><br>
+<blockquote><p>The most recently computed result that was not
+explicitly assigned to a variable.  For example, after the expression
+
+     <pre class="example">          3^2 + 4^2
+</pre>
+        <p class="noindent">is evaluated, the value returned by <code>ans</code> is 25. 
+</p></blockquote></div>
+
+<!-- utils.cc -->
+   <p><a name="doc_002disvarname"></a>
+
+<div class="defun">
+— Built-in Function:  <b>isvarname</b> (<var>name</var>)<var><a name="index-isvarname-419"></a></var><br>
+<blockquote><p>Return true if <var>name</var> is a valid variable name
+</p></blockquote></div>
+
+<!-- ./general/genvarname.m -->
+   <p><a name="doc_002dgenvarname"></a>
+
+<div class="defun">
+— Function File: <var>varname</var> = <b>genvarname</b> (<var>str</var>)<var><a name="index-genvarname-420"></a></var><br>
+— Function File: <var>varname</var> = <b>genvarname</b> (<var>str, exclusions</var>)<var><a name="index-genvarname-421"></a></var><br>
+<blockquote><p>Create unique variable(s) from <var>str</var>.  If <var>exclusions</var> is
+given, then the variable(s) will be unique to each other and to
+<var>exclusions</var> (<var>exclusions</var> may be either a string or a cellstr).
+
+        <p>If <var>str</var> is a cellstr, then a unique variable is created for each
+cell in <var>str</var>.
+
+     <pre class="example">          x = 3.141;
+          genvarname ("x", who ())
+           x1
+</pre>
+        <p>If <var>wanted</var> is a cell array, genvarname will make sure the returned
+strings are distinct:
+
+     <pre class="example">          genvarname ({"foo", "foo"})
+          
+          {
+            [1,1] = foo
+            [1,2] = foo1
+          }
+</pre>
+        <p>Note that the result is a char array/cell array of strings, not the
+variables themselves.  To define a variable, <code>eval()</code> can be
+used.  The following trivial example sets <code>x</code> to <code>42</code>.
+
+     <pre class="example">          name = genvarname ("x");
+          eval([name " = 42"]);
+           x =  42
+</pre>
+        <p>Also, this can be useful for creating unique struct field names.
+
+     <pre class="example">          x = struct ();
+          for i = 1:3
+            x.(genvarname ("a", fieldnames (x))) = i;
+          endfor
+          
+          x =
+          {
+            a =  1
+            a1 =  2
+            a2 =  3
+          }
+</pre>
+        <p>Since variable names may only contain letters, digits and underscores,
+genvarname replaces any sequence of disallowed characters with
+an underscore.  Also, variables may not begin with a digit; in this
+case an underscore is added before the variable name.
+
+        <p>Variable names beginning and ending with two underscores "__" are valid but
+they are used internally by octave and should generally be avoided, therefore
+genvarname will not generate such names.
+
+        <p>genvarname will also make sure that returned names do not clash with
+keywords such as "for" and "if".  A number will be appended if necessary. 
+Note, however, that this does <strong>not</strong> include function names,
+such as "sin".  Such names should be included in <var>avoid</var> if necessary. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002disvarname.html#doc_002disvarname">isvarname</a>, <a href="doc_002dexist.html#doc_002dexist">exist</a>, <a href="doc_002dtmpnam.html#doc_002dtmpnam">tmpnam</a>, <a href="doc_002deval.html#doc_002deval">eval</a>. 
+</p></blockquote></div>
+
+<!-- ./miscellaneous/namelengthmax.m -->
+   <p><a name="doc_002dnamelengthmax"></a>
+
+<div class="defun">
+— Function File:  <b>namelengthmax</b> ()<var><a name="index-namelengthmax-422"></a></var><br>
+<blockquote><p>Returns the <span class="sc">matlab</span> compatible maximum variable name length.  Octave is
+capable of storing strings up to
+<code>2 ^ 31 - 1</code>
+in length.  However for <span class="sc">matlab</span> compatibility all variable, function
+and structure field names should be shorter than the length supplied by
+<code>namelengthmax</code>.  In particular variables stored to a <span class="sc">matlab</span> file
+format will have their names truncated to this length. 
+</p></blockquote></div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Global-Variables.html#Global-Variables">Global Variables</a>
+<li><a accesskey="2" href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a>
+<li><a accesskey="3" href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Voronoi-Diagrams.html b/doc/interpreter/HTML/Voronoi-Diagrams.html
new file mode 100644
index 0000000..5c7a336
--- /dev/null
+++ b/doc/interpreter/HTML/Voronoi-Diagrams.html
@@ -0,0 +1,191 @@
+<html lang="en">
+<head>
+<title>Voronoi Diagrams - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Geometry.html#Geometry" title="Geometry">
+<link rel="prev" href="Delaunay-Triangulation.html#Delaunay-Triangulation" title="Delaunay Triangulation">
+<link rel="next" href="Convex-Hull.html#Convex-Hull" title="Convex Hull">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Voronoi-Diagrams"></a>
+Next: <a rel="next" accesskey="n" href="Convex-Hull.html#Convex-Hull">Convex Hull</a>,
+Previous: <a rel="previous" accesskey="p" href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a>,
+Up: <a rel="up" accesskey="u" href="Geometry.html#Geometry">Geometry</a>
+<hr>
+</div>
+
+<h3 class="section">29.2 Voronoi Diagrams</h3>
+
+<p>A Voronoi diagram or Voronoi tessellation of a set of points <var>s</var> in
+an N-dimensional space, is the tessellation of the N-dimensional space
+such that all points in <var>v</var><code>(</code><var>p</var><code>)</code>, a partitions of the
+tessellation where <var>p</var> is a member of <var>s</var>, are closer to <var>p</var>
+than any other point in <var>s</var>.  The Voronoi diagram is related to the
+Delaunay triangulation of a set of points, in that the vertexes of the
+Voronoi tessellation are the centers of the circum-circles of the
+simplicies of the Delaunay tessellation.
+
+<!-- ./geometry/voronoi.m -->
+   <p><a name="doc_002dvoronoi"></a>
+
+<div class="defun">
+— Function File:  <b>voronoi</b> (<var>x, y</var>)<var><a name="index-voronoi-2103"></a></var><br>
+— Function File:  <b>voronoi</b> (<var>x, y, "plotstyle"</var>)<var><a name="index-voronoi-2104"></a></var><br>
+— Function File:  <b>voronoi</b> (<var>x, y, "plotstyle", options</var>)<var><a name="index-voronoi-2105"></a></var><br>
+— Function File: [<var>vx</var>, <var>vy</var>] = <b>voronoi</b> (<var><small class="dots">...</small></var>)<var><a name="index-voronoi-2106"></a></var><br>
+<blockquote><p>plots voronoi diagram of points <code>(</code><var>x</var><code>, </code><var>y</var><code>)</code>. 
+The voronoi facets with points at infinity are not drawn. 
+[<var>vx</var>, <var>vy</var>] = voronoi(<small class="dots">...</small>) returns the vertices instead of plotting the
+diagram. plot (<var>vx</var>, <var>vy</var>) shows the voronoi diagram.
+
+        <p>A fourth optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+
+     <pre class="example">            x = rand (10, 1);
+            y = rand (size (x));
+            h = convhull (x, y);
+            [vx, vy] = voronoi (x, y);
+            plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g")
+            legend ("", "points", "hull");
+</pre>
+        <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dvoronoin.html#doc_002dvoronoin">voronoin</a>, <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>, <a href="doc_002dconvhull.html#doc_002dconvhull">convhull</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/voronoin.m -->
+   <p><a name="doc_002dvoronoin"></a>
+
+<div class="defun">
+— Function File: [<var>C</var>, <var>F</var>] = <b>voronoin</b> (<var>pts</var>)<var><a name="index-voronoin-2107"></a></var><br>
+— Function File: [<var>C</var>, <var>F</var>] = <b>voronoin</b> (<var>pts, options</var>)<var><a name="index-voronoin-2108"></a></var><br>
+<blockquote><p>computes n- dimensional voronoi facets.  The input matrix <var>pts</var>
+of size [n, dim] contains n points of dimension dim. 
+<var>C</var> contains the points of the voronoi facets.  The list <var>F</var>
+contains for each facet the indices of the voronoi points.
+
+        <p>A second optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details. 
+<!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+<!-- A simple blank line produces the correct behavior. -->
+<!-- @sp 1 -->
+
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dvoronoin.html#doc_002dvoronoin">voronoin</a>, <a href="doc_002ddelaunay.html#doc_002ddelaunay">delaunay</a>, <a href="doc_002dconvhull.html#doc_002dconvhull">convhull</a>. 
+</p></blockquote></div>
+
+   <p>An example of the use of <code>voronoi</code> is
+
+<pre class="example">     rand("state",9);
+     x = rand(10,1);
+     y = rand(10,1);
+     tri = delaunay (x, y);
+     [vx, vy] = voronoi (x, y, tri);
+     triplot (tri, x, y, "b");
+     hold on;
+     plot (vx, vy, "r");
+</pre>
+   <p>Additional information about the size of the facets of a Voronoi
+diagram, and which points of a set of points is in a polygon can be had
+with the <code>polyarea</code> and <code>inpolygon</code> functions respectively.
+
+<!-- ./general/polyarea.m -->
+   <p><a name="doc_002dpolyarea"></a>
+
+<div class="defun">
+— Function File:  <b>polyarea</b> (<var>x, y</var>)<var><a name="index-polyarea-2109"></a></var><br>
+— Function File:  <b>polyarea</b> (<var>x, y, dim</var>)<var><a name="index-polyarea-2110"></a></var><br>
+<blockquote>
+        <p>Determines area of a polygon by triangle method.  The variables
+<var>x</var> and <var>y</var> define the vertex pairs, and must therefore have
+the same shape.  They can be either vectors or arrays.  If they are
+arrays then the columns of <var>x</var> and <var>y</var> are treated separately
+and an area returned for each.
+
+        <p>If the optional <var>dim</var> argument is given, then <code>polyarea</code>
+works along this dimension of the arrays <var>x</var> and <var>y</var>.
+
+        </blockquote></div>
+
+   <p>An example of the use of <code>polyarea</code> might be
+
+<pre class="example">     rand ("state", 2);
+     x = rand (10, 1);
+     y = rand (10, 1);
+     [c, f] = voronoin ([x, y]);
+     af = zeros (size(f));
+     for i = 1 : length (f)
+       af(i) = polyarea (c (f {i, :}, 1), c (f {i, :}, 2));
+     endfor
+</pre>
+   <p>Facets of the Voronoi diagram with a vertex at infinity have infinity
+area.  A simplified version of <code>polyarea</code> for rectangles is
+available with <code>rectint</code>
+
+<!-- ./geometry/rectint.m -->
+   <p><a name="doc_002drectint"></a>
+
+<div class="defun">
+— Function File: <var>area</var> = <b>rectint</b> (<var>a, b</var>)<var><a name="index-rectint-2111"></a></var><br>
+<blockquote>
+        <p>Compute the area of intersection of rectangles in <var>a</var> and
+rectangles in <var>b</var>.  Rectangles are defined as [x y width height]
+where x and y are the minimum values of the two orthogonal
+dimensions.
+
+        <p>If <var>a</var> or <var>b</var> are matrices, then the output, <var>area</var>, is a
+matrix where the i-th row corresponds to the i-th row of a and the j-th
+column corresponds to the j-th row of b.
+
+     <!-- Texinfo @sp should work but in practice produces ugly results for HTML. -->
+     <!-- A simple blank line produces the correct behavior. -->
+     <!-- @sp 1 -->
+     <p class="noindent"><strong>See also:</strong> <a href="doc_002dpolyarea.html#doc_002dpolyarea">polyarea</a>. 
+</p></blockquote></div>
+
+<!-- ./geometry/inpolygon.m -->
+   <p><a name="doc_002dinpolygon"></a>
+
+<div class="defun">
+— Function File: [<var>in</var>, <var>on</var>] = <b>inpolygon</b> (<var>x, y, xv, xy</var>)<var><a name="index-inpolygon-2112"></a></var><br>
+<blockquote>
+        <p>For a polygon defined by <code>(</code><var>xv</var><code>, </code><var>yv</var><code>)</code> points, determine
+if the points <code>(</code><var>x</var><code>, </code><var>y</var><code>)</code> are inside or outside the polygon. 
+The variables <var>x</var>, <var>y</var>, must have the same dimension.  The optional
+output <var>on</var> gives the points that are on the polygon.
+
+        </blockquote></div>
+
+   <p>An example of the use of <code>inpolygon</code> might be
+
+<pre class="example">     randn ("state", 2);
+     x = randn (100, 1);
+     y = randn (100, 1);
+     vx = cos (pi * [-1 : 0.1: 1]);
+     vy = sin (pi * [-1 : 0.1 : 1]);
+     in = inpolygon (x, y, vx, vy);
+     plot(vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo");
+     axis ([-2, 2, -2, 2]);
+</pre>
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html b/doc/interpreter/HTML/Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html
new file mode 100644
index 0000000..3ee21fe
--- /dev/null
+++ b/doc/interpreter/HTML/Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html
@@ -0,0 +1,138 @@
+<html lang="en">
+<head>
+<title>Working with Matrices and Arrays in Mex-Files - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Mex_002dFiles.html#Mex_002dFiles" title="Mex-Files">
+<link rel="prev" href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles" title="Getting Started with Mex-Files">
+<link rel="next" href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles" title="Character Strings in Mex-Files">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Working-with-Matrices-and-Arrays-in-Mex-Files"></a>
+<a name="Working-with-Matrices-and-Arrays-in-Mex_002dFiles"></a>
+Next: <a rel="next" accesskey="n" href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles">Character Strings in Mex-Files</a>,
+Previous: <a rel="previous" accesskey="p" href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles">Getting Started with Mex-Files</a>,
+Up: <a rel="up" accesskey="u" href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<hr>
+</div>
+
+<h4 class="subsection">A.2.2 Working with Matrices and Arrays in Mex-Files</h4>
+
+<p>The basic mex type of all variables is <code>mxArray</code>.  All variables,
+such as matrices, cell arrays or structures are all stored in this basic
+type, and this type serves basically the same purpose as the
+octave_value class in oct-files.  That is it acts as a container for the
+more specialized types.
+
+   <p>The <code>mxArray</code> structure contains at a minimum, the variable it
+represents name, its dimensions, its type and whether the variable is
+real or complex.  It can however contain a number of additional fields
+depending on the type of the <code>mxArray</code>.  There are a number of
+functions to create <code>mxArray</code> structures, including
+<code>mxCreateCellArray</code>, <code>mxCreateSparse</code> and the generic
+<code>mxCreateNumericArray</code>.
+
+   <p>The basic functions to access the data contained in an array is
+<code>mxGetPr</code>.  As the mex interface assumes that the real and imaginary
+parts of a complex array are stored separately, there is an equivalent
+function <code>mxGetPi</code> that get the imaginary part.  Both of these
+functions are for use only with double precision matrices.  There also
+exists the generic function <code>mxGetData</code> and <code>mxGetImagData</code>
+that perform the same operation on all matrix types.  For example
+
+<pre class="example">     mxArray *m;
+     mwSize *dims;
+     UINT32_T *pr;
+     
+     dims = (mwSize *) mxMalloc (2 * sizeof(mwSize));
+     dims[0] = 2;
+     dims[1] = 2;
+     m = mxCreateNumericArray (2, dims, mxUINT32_CLASS, mxREAL);
+     pr =  = (UINT32_T *) mxGetData (m);
+</pre>
+   <p>There are also the functions <code>mxSetPr</code>, etc., that perform the
+inverse, and set the data of an Array to use the block of memory pointed
+to by the argument of <code>mxSetPr</code>.
+
+   <p>Note the type <code>mwSize</code> used above, and <code>mwIndex</code> are defined
+as the native precision of the indexing in Octave on the platform on
+which the mex-file is built.  This allows both 32- and 64-bit platforms
+to support mex-files.  <code>mwSize</code> is used to define array dimension
+and maximum number or elements, while <code>mwIndex</code> is used to define
+indexing into arrays.
+
+   <p>An example that demonstration how to work with arbitrary real or complex
+double precision arrays is given by the file <samp><span class="file">mypow2.c</span></samp> as given
+below.
+
+<pre class="example"><pre class="verbatim">     #include "mex.h"
+     
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+     	     const mxArray* prhs[])
+     {
+       mwIndex i;
+       mwSize n;
+       double *vri, *vro;
+       
+       if (nrhs != 1 || ! mxIsNumeric (prhs[0]))
+         mexErrMsgTxt ("expects matrix");
+     
+       n = mxGetNumberOfElements (prhs[0]);
+       plhs[0] = (mxArray *) mxCreateNumericArray 
+         (mxGetNumberOfDimensions (prhs[0]),
+          mxGetDimensions (prhs[0]), mxGetClassID (prhs[0]),
+          mxIsComplex (prhs[0]));
+       vri = mxGetPr (prhs[0]);
+       vro = mxGetPr (plhs[0]);
+     
+       if (mxIsComplex (prhs[0]))
+         {
+           double *vii, *vio;
+           vii = mxGetPi (prhs[0]);
+           vio = mxGetPi (plhs[0]);
+     
+           for (i = 0; i < n; i++)
+     	{
+     	  vro [i] = vri [i] * vri [i] - vii [i] * vii [i];
+     	  vio [i] = 2 * vri [i] * vii [i];
+     	}
+         }
+       else
+         {
+           for (i = 0; i < n; i++)
+     	vro [i] = vri [i] * vri [i];
+         }
+     }
+</pre></pre>
+   <p class="noindent">with an example of its use
+
+<pre class="example">     b = randn(4,1) + 1i * randn(4,1);
+     all(b.^2 == mypow2(b))
+      1
+</pre>
+   <p>The example above uses the functions <code>mxGetDimensions</code>,
+<code>mxGetNumberOfElements</code>, and <code>mxGetNumberOfDimensions</code> to work
+with the dimensions of multi-dimensional arrays.  The functions
+<code>mxGetM</code>, and <code>mxGetN</code> are also available to find the number
+of rows and columns in a matrix.
+
+   </body></html>
+
diff --git a/doc/interpreter/HTML/Zeros-Treatment.html b/doc/interpreter/HTML/Zeros-Treatment.html
new file mode 100644
index 0000000..df6cb82
--- /dev/null
+++ b/doc/interpreter/HTML/Zeros-Treatment.html
@@ -0,0 +1,134 @@
+<html lang="en">
+<head>
+<title>Zeros Treatment - Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices" title="Diagonal and Permutation Matrices">
+<link rel="prev" href="Example-Codes.html#Example-Codes" title="Example Codes">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Zeros-Treatment"></a>
+Previous: <a rel="previous" accesskey="p" href="Example-Codes.html#Example-Codes">Example Codes</a>,
+Up: <a rel="up" accesskey="u" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>
+<hr>
+</div>
+
+<h3 class="section">20.5 The Differences in Treatment of Zero Elements</h3>
+
+<p>Making diagonal and permutation matrices special matrix objects in their own
+right and the consequent usage of smarter algorithms for certain operations
+implies, as a side effect, small differences in treating zeros. 
+The contents of this section applies also to sparse matrices, discussed in
+the following chapter.
+
+   <p>The IEEE standard defines the result of the expressions <code>0*Inf</code> and
+<code>0*NaN</code> as <code>NaN</code>, as it has been generally agreed that this is the
+best compromise. 
+Numerical software dealing with structured and sparse matrices (including
+Octave) however, almost always makes a distinction between a "numerical zero"
+and an "assumed zero". 
+A "numerical zero" is a zero value occurring in a place where any floating-point
+value could occur.  It is normally stored somewhere in memory as an explicit
+value. 
+An "assumed zero", on the contrary, is a zero matrix element implied by the
+matrix structure (diagonal, triangular) or a sparsity pattern; its value is
+usually not stored explicitly anywhere, but is implied by the underlying
+data structure.
+
+   <p>The primary distinction is that an assumed zero, when multiplied
+by any number, or divided by any nonzero number,
+yields *always* a zero, even when, e.g., multiplied by <code>Inf</code>
+or divided by <code>NaN</code>. 
+The reason for this behavior is that the numerical multiplication is not
+actually performed anywhere by the underlying algorithm; the result is
+just assumed to be zero.  Equivalently, one can say that the part of the
+computation involving assumed zeros is performed symbolically, not numerically.
+
+   <p>This behavior not only facilitates the most straightforward and efficient
+implementation of algorithms, but also preserves certain useful invariants,
+like:
+     <ul>
+<li>scalar * diagonal matrix is a diagonal matrix
+<li>sparse matrix / scalar preserves the sparsity pattern
+<li>permutation matrix * matrix is equivalent to permuting rows
+</ul>
+   all of these natural mathematical truths would be invalidated by treating
+assumed zeros as numerical ones.
+
+   <p>Note that certain competing software does not strictly follow this principle
+and converts assumed zeros to numerical zeros in certain cases, while not doing
+so in other cases.  As of today, there are no intentions to mimic such behavior
+in Octave.
+
+   <p>Examples of effects of assumed zeros vs. numerical zeros:
+<pre class="example">     Inf * eye (3)
+     
+        Inf     0     0
+          0   Inf     0
+          0     0   Inf
+     
+     Inf * speye (3)
+     
+     Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%])
+     
+       (1, 1) -> Inf
+       (2, 2) -> Inf
+       (3, 3) -> Inf
+     
+     Inf * full (eye (3))
+     
+        Inf   NaN   NaN
+        NaN   Inf   NaN
+        NaN   NaN   Inf
+     
+</pre>
+   <pre class="example">     diag(1:3) * [NaN; 1; 1]
+     
+        NaN
+          2
+          3
+     
+     sparse(1:3,1:3,1:3) * [NaN; 1; 1]
+     
+        NaN
+          2
+          3
+     [1,0,0;0,2,0;0,0,3] * [NaN; 1; 1]
+     
+        NaN
+        NaN
+        NaN
+</pre>
+   <!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/convhull.png b/doc/interpreter/HTML/convhull.png
new file mode 100644
index 0000000..130c4b6
Binary files /dev/null and b/doc/interpreter/HTML/convhull.png differ
diff --git a/doc/interpreter/HTML/delaunay.png b/doc/interpreter/HTML/delaunay.png
new file mode 100644
index 0000000..5033b61
Binary files /dev/null and b/doc/interpreter/HTML/delaunay.png differ
diff --git a/doc/interpreter/HTML/doc_002dEDITOR.html b/doc/interpreter/HTML/doc_002dEDITOR.html
new file mode 100644
index 0000000..59fbdbb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dEDITOR.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dEDITOR">
diff --git a/doc/interpreter/HTML/doc_002dEXEC_005fPATH.html b/doc/interpreter/HTML/doc_002dEXEC_005fPATH.html
new file mode 100644
index 0000000..030cc61
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dEXEC_005fPATH.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dEXEC%5fPATH">
diff --git a/doc/interpreter/HTML/doc_002dI.html b/doc/interpreter/HTML/doc_002dI.html
new file mode 100644
index 0000000..5718dbe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dI.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2dI">
diff --git a/doc/interpreter/HTML/doc_002dIMAGE_005fPATH.html b/doc/interpreter/HTML/doc_002dIMAGE_005fPATH.html
new file mode 100644
index 0000000..a63da29
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dIMAGE_005fPATH.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Loading-and-Saving-Images.html#doc%2dIMAGE%5fPATH">
diff --git a/doc/interpreter/HTML/doc_002dInf.html b/doc/interpreter/HTML/doc_002dInf.html
new file mode 100644
index 0000000..f33ea9a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dInf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2dInf">
diff --git a/doc/interpreter/HTML/doc_002dNA.html b/doc/interpreter/HTML/doc_002dNA.html
new file mode 100644
index 0000000..10ddecf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dNA.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Missing-Data.html#doc%2dNA">
diff --git a/doc/interpreter/HTML/doc_002dNaN.html b/doc/interpreter/HTML/doc_002dNaN.html
new file mode 100644
index 0000000..5eb3a25
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dNaN.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2dNaN">
diff --git a/doc/interpreter/HTML/doc_002dOCTAVE_005fHOME.html b/doc/interpreter/HTML/doc_002dOCTAVE_005fHOME.html
new file mode 100644
index 0000000..5776a0d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dOCTAVE_005fHOME.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dOCTAVE%5fHOME">
diff --git a/doc/interpreter/HTML/doc_002dOCTAVE_005fVERSION.html b/doc/interpreter/HTML/doc_002dOCTAVE_005fVERSION.html
new file mode 100644
index 0000000..079bb1d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dOCTAVE_005fVERSION.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dOCTAVE%5fVERSION">
diff --git a/doc/interpreter/HTML/doc_002dPAGER.html b/doc/interpreter/HTML/doc_002dPAGER.html
new file mode 100644
index 0000000..5fd1678
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dPAGER.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Paging-Screen-Output.html#doc%2dPAGER">
diff --git a/doc/interpreter/HTML/doc_002dPAGER_005fFLAGS.html b/doc/interpreter/HTML/doc_002dPAGER_005fFLAGS.html
new file mode 100644
index 0000000..4cc38b7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dPAGER_005fFLAGS.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Paging-Screen-Output.html#doc%2dPAGER%5fFLAGS">
diff --git a/doc/interpreter/HTML/doc_002dPKG_005fADD.html b/doc/interpreter/HTML/doc_002dPKG_005fADD.html
new file mode 100644
index 0000000..731e722
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dPKG_005fADD.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Packages.html#doc%2dPKG%5fADD">
diff --git a/doc/interpreter/HTML/doc_002dPS1.html b/doc/interpreter/HTML/doc_002dPS1.html
new file mode 100644
index 0000000..80c600d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dPS1.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Customizing-the-Prompt.html#doc%2dPS1">
diff --git a/doc/interpreter/HTML/doc_002dPS2.html b/doc/interpreter/HTML/doc_002dPS2.html
new file mode 100644
index 0000000..dc94dff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dPS2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Customizing-the-Prompt.html#doc%2dPS2">
diff --git a/doc/interpreter/HTML/doc_002dPS4.html b/doc/interpreter/HTML/doc_002dPS4.html
new file mode 100644
index 0000000..a5f4561
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dPS4.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Customizing-the-Prompt.html#doc%2dPS4">
diff --git a/doc/interpreter/HTML/doc_002dP_005ftmpdir.html b/doc/interpreter/HTML/doc_002dP_005ftmpdir.html
new file mode 100644
index 0000000..5dccc0b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dP_005ftmpdir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dP%5ftmpdir">
diff --git a/doc/interpreter/HTML/doc_002dSEEK_005fSET.html b/doc/interpreter/HTML/doc_002dSEEK_005fSET.html
new file mode 100644
index 0000000..791f9e1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dSEEK_005fSET.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Positioning.html#doc%2dSEEK%5fSET">
diff --git a/doc/interpreter/HTML/doc_002dSIG.html b/doc/interpreter/HTML/doc_002dSIG.html
new file mode 100644
index 0000000..2119929
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dSIG.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dSIG">
diff --git a/doc/interpreter/HTML/doc_002dWCONTINUE.html b/doc/interpreter/HTML/doc_002dWCONTINUE.html
new file mode 100644
index 0000000..a77742a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWCONTINUE.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWCONTINUE">
diff --git a/doc/interpreter/HTML/doc_002dWCOREDUMP.html b/doc/interpreter/HTML/doc_002dWCOREDUMP.html
new file mode 100644
index 0000000..6fdd8ba
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWCOREDUMP.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWCOREDUMP">
diff --git a/doc/interpreter/HTML/doc_002dWEXITSTATUS.html b/doc/interpreter/HTML/doc_002dWEXITSTATUS.html
new file mode 100644
index 0000000..a08eed6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWEXITSTATUS.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWEXITSTATUS">
diff --git a/doc/interpreter/HTML/doc_002dWIFCONTINUED.html b/doc/interpreter/HTML/doc_002dWIFCONTINUED.html
new file mode 100644
index 0000000..ac81b90
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWIFCONTINUED.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWIFCONTINUED">
diff --git a/doc/interpreter/HTML/doc_002dWIFEXITED.html b/doc/interpreter/HTML/doc_002dWIFEXITED.html
new file mode 100644
index 0000000..97cccd8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWIFEXITED.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWIFEXITED">
diff --git a/doc/interpreter/HTML/doc_002dWIFSIGNALED.html b/doc/interpreter/HTML/doc_002dWIFSIGNALED.html
new file mode 100644
index 0000000..2dd3308
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWIFSIGNALED.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWIFSIGNALED">
diff --git a/doc/interpreter/HTML/doc_002dWIFSTOPPED.html b/doc/interpreter/HTML/doc_002dWIFSTOPPED.html
new file mode 100644
index 0000000..6326dc0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWIFSTOPPED.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWIFSTOPPED">
diff --git a/doc/interpreter/HTML/doc_002dWNOHANG.html b/doc/interpreter/HTML/doc_002dWNOHANG.html
new file mode 100644
index 0000000..73531d1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWNOHANG.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWNOHANG">
diff --git a/doc/interpreter/HTML/doc_002dWSTOPSIG.html b/doc/interpreter/HTML/doc_002dWSTOPSIG.html
new file mode 100644
index 0000000..8a5f077
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWSTOPSIG.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWSTOPSIG">
diff --git a/doc/interpreter/HTML/doc_002dWTERMSIG.html b/doc/interpreter/HTML/doc_002dWTERMSIG.html
new file mode 100644
index 0000000..40f2783
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWTERMSIG.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWTERMSIG">
diff --git a/doc/interpreter/HTML/doc_002dWUNTRACED.html b/doc/interpreter/HTML/doc_002dWUNTRACED.html
new file mode 100644
index 0000000..36296c6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dWUNTRACED.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dWUNTRACED">
diff --git a/doc/interpreter/HTML/doc_002dabs.html b/doc/interpreter/HTML/doc_002dabs.html
new file mode 100644
index 0000000..b0d6e93
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dabs.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Complex-Arithmetic.html#doc%2dabs">
diff --git a/doc/interpreter/HTML/doc_002daccumarray.html b/doc/interpreter/HTML/doc_002daccumarray.html
new file mode 100644
index 0000000..ee20517
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daccumarray.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sums-and-Products.html#doc%2daccumarray">
diff --git a/doc/interpreter/HTML/doc_002dacos.html b/doc/interpreter/HTML/doc_002dacos.html
new file mode 100644
index 0000000..226fafa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacos.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacos">
diff --git a/doc/interpreter/HTML/doc_002dacosd.html b/doc/interpreter/HTML/doc_002dacosd.html
new file mode 100644
index 0000000..5fcf59f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacosd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacosd">
diff --git a/doc/interpreter/HTML/doc_002dacosh.html b/doc/interpreter/HTML/doc_002dacosh.html
new file mode 100644
index 0000000..1728c58
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacosh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacosh">
diff --git a/doc/interpreter/HTML/doc_002dacot.html b/doc/interpreter/HTML/doc_002dacot.html
new file mode 100644
index 0000000..9ec53ca
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacot">
diff --git a/doc/interpreter/HTML/doc_002dacotd.html b/doc/interpreter/HTML/doc_002dacotd.html
new file mode 100644
index 0000000..873ce09
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacotd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacotd">
diff --git a/doc/interpreter/HTML/doc_002dacoth.html b/doc/interpreter/HTML/doc_002dacoth.html
new file mode 100644
index 0000000..5a44d32
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacoth.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacoth">
diff --git a/doc/interpreter/HTML/doc_002dacsc.html b/doc/interpreter/HTML/doc_002dacsc.html
new file mode 100644
index 0000000..3005206
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacsc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacsc">
diff --git a/doc/interpreter/HTML/doc_002dacscd.html b/doc/interpreter/HTML/doc_002dacscd.html
new file mode 100644
index 0000000..321efb9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacscd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacscd">
diff --git a/doc/interpreter/HTML/doc_002dacsch.html b/doc/interpreter/HTML/doc_002dacsch.html
new file mode 100644
index 0000000..fdc556b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dacsch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dacsch">
diff --git a/doc/interpreter/HTML/doc_002daddlistener.html b/doc/interpreter/HTML/doc_002daddlistener.html
new file mode 100644
index 0000000..78a7bb6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daddlistener.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Groups.html#doc%2daddlistener">
diff --git a/doc/interpreter/HTML/doc_002daddpath.html b/doc/interpreter/HTML/doc_002daddpath.html
new file mode 100644
index 0000000..f12bf37
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daddpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2daddpath">
diff --git a/doc/interpreter/HTML/doc_002daddproperty.html b/doc/interpreter/HTML/doc_002daddproperty.html
new file mode 100644
index 0000000..c2048af
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daddproperty.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Groups.html#doc%2daddproperty">
diff --git a/doc/interpreter/HTML/doc_002daddtodate.html b/doc/interpreter/HTML/doc_002daddtodate.html
new file mode 100644
index 0000000..3341625
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daddtodate.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2daddtodate">
diff --git a/doc/interpreter/HTML/doc_002dairy.html b/doc/interpreter/HTML/doc_002dairy.html
new file mode 100644
index 0000000..f9f3cc6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dairy.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dairy">
diff --git a/doc/interpreter/HTML/doc_002dall.html b/doc/interpreter/HTML/doc_002dall.html
new file mode 100644
index 0000000..712bf96
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dall.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dall">
diff --git a/doc/interpreter/HTML/doc_002dallchild.html b/doc/interpreter/HTML/doc_002dallchild.html
new file mode 100644
index 0000000..6eeb6d1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dallchild.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dallchild">
diff --git a/doc/interpreter/HTML/doc_002damd.html b/doc/interpreter/HTML/doc_002damd.html
new file mode 100644
index 0000000..5a2347b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002damd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2damd">
diff --git a/doc/interpreter/HTML/doc_002dancestor.html b/doc/interpreter/HTML/doc_002dancestor.html
new file mode 100644
index 0000000..cf0e959
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dancestor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dancestor">
diff --git a/doc/interpreter/HTML/doc_002dand.html b/doc/interpreter/HTML/doc_002dand.html
new file mode 100644
index 0000000..43fe634
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dand">
diff --git a/doc/interpreter/HTML/doc_002danova.html b/doc/interpreter/HTML/doc_002danova.html
new file mode 100644
index 0000000..c44b932
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002danova.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2danova">
diff --git a/doc/interpreter/HTML/doc_002dans.html b/doc/interpreter/HTML/doc_002dans.html
new file mode 100644
index 0000000..b3fb466
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dans.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Variables.html#doc%2dans">
diff --git a/doc/interpreter/HTML/doc_002dany.html b/doc/interpreter/HTML/doc_002dany.html
new file mode 100644
index 0000000..b186551
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dany.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dany">
diff --git a/doc/interpreter/HTML/doc_002darch_005ffit.html b/doc/interpreter/HTML/doc_002darch_005ffit.html
new file mode 100644
index 0000000..a29d423
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darch_005ffit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2darch%5ffit">
diff --git a/doc/interpreter/HTML/doc_002darch_005frnd.html b/doc/interpreter/HTML/doc_002darch_005frnd.html
new file mode 100644
index 0000000..0624da4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darch_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2darch%5frnd">
diff --git a/doc/interpreter/HTML/doc_002darch_005ftest.html b/doc/interpreter/HTML/doc_002darch_005ftest.html
new file mode 100644
index 0000000..90a33dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darch_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2darch%5ftest">
diff --git a/doc/interpreter/HTML/doc_002darea.html b/doc/interpreter/HTML/doc_002darea.html
new file mode 100644
index 0000000..5c43673
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darea.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2darea">
diff --git a/doc/interpreter/HTML/doc_002darg.html b/doc/interpreter/HTML/doc_002darg.html
new file mode 100644
index 0000000..0031afd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Complex-Arithmetic.html#doc%2darg">
diff --git a/doc/interpreter/HTML/doc_002dargnames.html b/doc/interpreter/HTML/doc_002dargnames.html
new file mode 100644
index 0000000..228712f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dargnames.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Inline-Functions.html#doc%2dargnames">
diff --git a/doc/interpreter/HTML/doc_002dargv.html b/doc/interpreter/HTML/doc_002dargv.html
new file mode 100644
index 0000000..9fbac65
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dargv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Command-Line-Options.html#doc%2dargv">
diff --git a/doc/interpreter/HTML/doc_002darma_005frnd.html b/doc/interpreter/HTML/doc_002darma_005frnd.html
new file mode 100644
index 0000000..4f5ff70
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darma_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2darma%5frnd">
diff --git a/doc/interpreter/HTML/doc_002darrayfun.html b/doc/interpreter/HTML/doc_002darrayfun.html
new file mode 100644
index 0000000..746d932
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002darrayfun.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Applying-a-Function-to-an-Array.html#doc%2darrayfun">
diff --git a/doc/interpreter/HTML/doc_002dasctime.html b/doc/interpreter/HTML/doc_002dasctime.html
new file mode 100644
index 0000000..0b45980
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasctime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dasctime">
diff --git a/doc/interpreter/HTML/doc_002dasec.html b/doc/interpreter/HTML/doc_002dasec.html
new file mode 100644
index 0000000..bded39b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dasec">
diff --git a/doc/interpreter/HTML/doc_002dasecd.html b/doc/interpreter/HTML/doc_002dasecd.html
new file mode 100644
index 0000000..4f31472
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasecd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dasecd">
diff --git a/doc/interpreter/HTML/doc_002dasech.html b/doc/interpreter/HTML/doc_002dasech.html
new file mode 100644
index 0000000..9addfb5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasech.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dasech">
diff --git a/doc/interpreter/HTML/doc_002dasin.html b/doc/interpreter/HTML/doc_002dasin.html
new file mode 100644
index 0000000..3a9a473
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dasin">
diff --git a/doc/interpreter/HTML/doc_002dasind.html b/doc/interpreter/HTML/doc_002dasind.html
new file mode 100644
index 0000000..8a60c56
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dasind">
diff --git a/doc/interpreter/HTML/doc_002dasinh.html b/doc/interpreter/HTML/doc_002dasinh.html
new file mode 100644
index 0000000..38f581a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dasinh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dasinh">
diff --git a/doc/interpreter/HTML/doc_002dassert.html b/doc/interpreter/HTML/doc_002dassert.html
new file mode 100644
index 0000000..676161d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dassert.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Test-Functions.html#doc%2dassert">
diff --git a/doc/interpreter/HTML/doc_002dassignin.html b/doc/interpreter/HTML/doc_002dassignin.html
new file mode 100644
index 0000000..d076d68
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dassignin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Evaluation-in-a-Different-Context.html#doc%2dassignin">
diff --git a/doc/interpreter/HTML/doc_002datan.html b/doc/interpreter/HTML/doc_002datan.html
new file mode 100644
index 0000000..c266242
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002datan.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2datan">
diff --git a/doc/interpreter/HTML/doc_002datan2.html b/doc/interpreter/HTML/doc_002datan2.html
new file mode 100644
index 0000000..c1af4ba
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002datan2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2datan2">
diff --git a/doc/interpreter/HTML/doc_002datand.html b/doc/interpreter/HTML/doc_002datand.html
new file mode 100644
index 0000000..0048f03
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002datand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2datand">
diff --git a/doc/interpreter/HTML/doc_002datanh.html b/doc/interpreter/HTML/doc_002datanh.html
new file mode 100644
index 0000000..325ec86
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002datanh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2datanh">
diff --git a/doc/interpreter/HTML/doc_002datexit.html b/doc/interpreter/HTML/doc_002datexit.html
new file mode 100644
index 0000000..00157dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002datexit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Quitting-Octave.html#doc%2datexit">
diff --git a/doc/interpreter/HTML/doc_002dautocor.html b/doc/interpreter/HTML/doc_002dautocor.html
new file mode 100644
index 0000000..d5e7624
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dautocor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dautocor">
diff --git a/doc/interpreter/HTML/doc_002dautocov.html b/doc/interpreter/HTML/doc_002dautocov.html
new file mode 100644
index 0000000..1bbd72d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dautocov.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dautocov">
diff --git a/doc/interpreter/HTML/doc_002dautoload.html b/doc/interpreter/HTML/doc_002dautoload.html
new file mode 100644
index 0000000..db67224
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dautoload.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Overloading-and-Autoloading.html#doc%2dautoload">
diff --git a/doc/interpreter/HTML/doc_002dautoreg_005fmatrix.html b/doc/interpreter/HTML/doc_002dautoreg_005fmatrix.html
new file mode 100644
index 0000000..055092f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dautoreg_005fmatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dautoreg%5fmatrix">
diff --git a/doc/interpreter/HTML/doc_002dautumn.html b/doc/interpreter/HTML/doc_002dautumn.html
new file mode 100644
index 0000000..daef982
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dautumn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dautumn">
diff --git a/doc/interpreter/HTML/doc_002davailable_005fbackends.html b/doc/interpreter/HTML/doc_002davailable_005fbackends.html
new file mode 100644
index 0000000..4aa5c87
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002davailable_005fbackends.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-backends.html#doc%2davailable%5fbackends">
diff --git a/doc/interpreter/HTML/doc_002daxes.html b/doc/interpreter/HTML/doc_002daxes.html
new file mode 100644
index 0000000..fca2752
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daxes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2daxes">
diff --git a/doc/interpreter/HTML/doc_002daxis.html b/doc/interpreter/HTML/doc_002daxis.html
new file mode 100644
index 0000000..017acf7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002daxis.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2daxis">
diff --git a/doc/interpreter/HTML/doc_002dbackend.html b/doc/interpreter/HTML/doc_002dbackend.html
new file mode 100644
index 0000000..ad71373
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbackend.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-backends.html#doc%2dbackend">
diff --git a/doc/interpreter/HTML/doc_002dbalance.html b/doc/interpreter/HTML/doc_002dbalance.html
new file mode 100644
index 0000000..d595b92
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbalance.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dbalance">
diff --git a/doc/interpreter/HTML/doc_002dbar.html b/doc/interpreter/HTML/doc_002dbar.html
new file mode 100644
index 0000000..81ce832
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dbar">
diff --git a/doc/interpreter/HTML/doc_002dbarh.html b/doc/interpreter/HTML/doc_002dbarh.html
new file mode 100644
index 0000000..1575cab
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbarh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dbarh">
diff --git a/doc/interpreter/HTML/doc_002dbartlett.html b/doc/interpreter/HTML/doc_002dbartlett.html
new file mode 100644
index 0000000..54aec95
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbartlett.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dbartlett">
diff --git a/doc/interpreter/HTML/doc_002dbartlett_005ftest.html b/doc/interpreter/HTML/doc_002dbartlett_005ftest.html
new file mode 100644
index 0000000..3a735a3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbartlett_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dbartlett%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dbase2dec.html b/doc/interpreter/HTML/doc_002dbase2dec.html
new file mode 100644
index 0000000..9789a74
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbase2dec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dbase2dec">
diff --git a/doc/interpreter/HTML/doc_002dbeep.html b/doc/interpreter/HTML/doc_002dbeep.html
new file mode 100644
index 0000000..dfd4fc9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbeep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Raising-Errors.html#doc%2dbeep">
diff --git a/doc/interpreter/HTML/doc_002dbeep_005fon_005ferror.html b/doc/interpreter/HTML/doc_002dbeep_005fon_005ferror.html
new file mode 100644
index 0000000..5717c6b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbeep_005fon_005ferror.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Raising-Errors.html#doc%2dbeep%5fon%5ferror">
diff --git a/doc/interpreter/HTML/doc_002dbesselj.html b/doc/interpreter/HTML/doc_002dbesselj.html
new file mode 100644
index 0000000..9301974
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbesselj.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dbesselj">
diff --git a/doc/interpreter/HTML/doc_002dbeta.html b/doc/interpreter/HTML/doc_002dbeta.html
new file mode 100644
index 0000000..e513069
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbeta.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dbeta">
diff --git a/doc/interpreter/HTML/doc_002dbetacdf.html b/doc/interpreter/HTML/doc_002dbetacdf.html
new file mode 100644
index 0000000..129dea9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbetacdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dbetacdf">
diff --git a/doc/interpreter/HTML/doc_002dbetainc.html b/doc/interpreter/HTML/doc_002dbetainc.html
new file mode 100644
index 0000000..346a2c6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbetainc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dbetainc">
diff --git a/doc/interpreter/HTML/doc_002dbetainv.html b/doc/interpreter/HTML/doc_002dbetainv.html
new file mode 100644
index 0000000..fb8b3b1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbetainv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dbetainv">
diff --git a/doc/interpreter/HTML/doc_002dbetaln.html b/doc/interpreter/HTML/doc_002dbetaln.html
new file mode 100644
index 0000000..a36a68f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbetaln.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dbetaln">
diff --git a/doc/interpreter/HTML/doc_002dbetapdf.html b/doc/interpreter/HTML/doc_002dbetapdf.html
new file mode 100644
index 0000000..2036be8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbetapdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dbetapdf">
diff --git a/doc/interpreter/HTML/doc_002dbetarnd.html b/doc/interpreter/HTML/doc_002dbetarnd.html
new file mode 100644
index 0000000..1c5049d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbetarnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dbetarnd">
diff --git a/doc/interpreter/HTML/doc_002dbicgstab.html b/doc/interpreter/HTML/doc_002dbicgstab.html
new file mode 100644
index 0000000..48add8b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbicgstab.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Specialized-Solvers.html#doc%2dbicgstab">
diff --git a/doc/interpreter/HTML/doc_002dbicubic.html b/doc/interpreter/HTML/doc_002dbicubic.html
new file mode 100644
index 0000000..870cfa0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbicubic.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multi_002ddimensional-Interpolation.html#doc%2dbicubic">
diff --git a/doc/interpreter/HTML/doc_002dbin2dec.html b/doc/interpreter/HTML/doc_002dbin2dec.html
new file mode 100644
index 0000000..241d6cc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbin2dec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dbin2dec">
diff --git a/doc/interpreter/HTML/doc_002dbincoeff.html b/doc/interpreter/HTML/doc_002dbincoeff.html
new file mode 100644
index 0000000..6589d90
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbincoeff.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dbincoeff">
diff --git a/doc/interpreter/HTML/doc_002dbinocdf.html b/doc/interpreter/HTML/doc_002dbinocdf.html
new file mode 100644
index 0000000..a1ad82b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbinocdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dbinocdf">
diff --git a/doc/interpreter/HTML/doc_002dbinoinv.html b/doc/interpreter/HTML/doc_002dbinoinv.html
new file mode 100644
index 0000000..5bfa963
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbinoinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dbinoinv">
diff --git a/doc/interpreter/HTML/doc_002dbinopdf.html b/doc/interpreter/HTML/doc_002dbinopdf.html
new file mode 100644
index 0000000..68e81a8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbinopdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dbinopdf">
diff --git a/doc/interpreter/HTML/doc_002dbinornd.html b/doc/interpreter/HTML/doc_002dbinornd.html
new file mode 100644
index 0000000..d0a84e9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbinornd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dbinornd">
diff --git a/doc/interpreter/HTML/doc_002dbitand.html b/doc/interpreter/HTML/doc_002dbitand.html
new file mode 100644
index 0000000..34b3ee2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitand">
diff --git a/doc/interpreter/HTML/doc_002dbitcmp.html b/doc/interpreter/HTML/doc_002dbitcmp.html
new file mode 100644
index 0000000..eb4a154
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitcmp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitcmp">
diff --git a/doc/interpreter/HTML/doc_002dbitget.html b/doc/interpreter/HTML/doc_002dbitget.html
new file mode 100644
index 0000000..82bfd17
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitget.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitget">
diff --git a/doc/interpreter/HTML/doc_002dbitmax.html b/doc/interpreter/HTML/doc_002dbitmax.html
new file mode 100644
index 0000000..75918dc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitmax">
diff --git a/doc/interpreter/HTML/doc_002dbitor.html b/doc/interpreter/HTML/doc_002dbitor.html
new file mode 100644
index 0000000..7e7c19e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitor">
diff --git a/doc/interpreter/HTML/doc_002dbitset.html b/doc/interpreter/HTML/doc_002dbitset.html
new file mode 100644
index 0000000..1e0ef0d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitset.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitset">
diff --git a/doc/interpreter/HTML/doc_002dbitshift.html b/doc/interpreter/HTML/doc_002dbitshift.html
new file mode 100644
index 0000000..e191a53
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitshift">
diff --git a/doc/interpreter/HTML/doc_002dbitxor.html b/doc/interpreter/HTML/doc_002dbitxor.html
new file mode 100644
index 0000000..84fa61a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbitxor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Bit-Manipulations.html#doc%2dbitxor">
diff --git a/doc/interpreter/HTML/doc_002dblackman.html b/doc/interpreter/HTML/doc_002dblackman.html
new file mode 100644
index 0000000..526e0e8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dblackman.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dblackman">
diff --git a/doc/interpreter/HTML/doc_002dblanks.html b/doc/interpreter/HTML/doc_002dblanks.html
new file mode 100644
index 0000000..f8c9340
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dblanks.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Strings.html#doc%2dblanks">
diff --git a/doc/interpreter/HTML/doc_002dblkdiag.html b/doc/interpreter/HTML/doc_002dblkdiag.html
new file mode 100644
index 0000000..1efd62e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dblkdiag.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dblkdiag">
diff --git a/doc/interpreter/HTML/doc_002dbone.html b/doc/interpreter/HTML/doc_002dbone.html
new file mode 100644
index 0000000..5432b93
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbone.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dbone">
diff --git a/doc/interpreter/HTML/doc_002dbox.html b/doc/interpreter/HTML/doc_002dbox.html
new file mode 100644
index 0000000..145ab85
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbox.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dbox">
diff --git a/doc/interpreter/HTML/doc_002dbrighten.html b/doc/interpreter/HTML/doc_002dbrighten.html
new file mode 100644
index 0000000..4216f0a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbrighten.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dbrighten">
diff --git a/doc/interpreter/HTML/doc_002dbsxfun.html b/doc/interpreter/HTML/doc_002dbsxfun.html
new file mode 100644
index 0000000..0a6d0fc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbsxfun.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Applying-a-Function-to-an-Array.html#doc%2dbsxfun">
diff --git a/doc/interpreter/HTML/doc_002dbug_005freport.html b/doc/interpreter/HTML/doc_002dbug_005freport.html
new file mode 100644
index 0000000..7d07fd6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbug_005freport.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Reporting-Bugs.html#doc%2dbug%5freport">
diff --git a/doc/interpreter/HTML/doc_002dbuiltin.html b/doc/interpreter/HTML/doc_002dbuiltin.html
new file mode 100644
index 0000000..c93ee96
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbuiltin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Overloading-and-Autoloading.html#doc%2dbuiltin">
diff --git a/doc/interpreter/HTML/doc_002dbunzip2.html b/doc/interpreter/HTML/doc_002dbunzip2.html
new file mode 100644
index 0000000..cf7eb36
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbunzip2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dbunzip2">
diff --git a/doc/interpreter/HTML/doc_002dbzip2.html b/doc/interpreter/HTML/doc_002dbzip2.html
new file mode 100644
index 0000000..eb73640
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dbzip2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dbzip2">
diff --git a/doc/interpreter/HTML/doc_002dcalendar.html b/doc/interpreter/HTML/doc_002dcalendar.html
new file mode 100644
index 0000000..8c544f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcalendar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dcalendar">
diff --git a/doc/interpreter/HTML/doc_002dcanonicalize_005ffile_005fname.html b/doc/interpreter/HTML/doc_002dcanonicalize_005ffile_005fname.html
new file mode 100644
index 0000000..f1594dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcanonicalize_005ffile_005fname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dcanonicalize%5ffile%5fname">
diff --git a/doc/interpreter/HTML/doc_002dcart2pol.html b/doc/interpreter/HTML/doc_002dcart2pol.html
new file mode 100644
index 0000000..fdcbf5f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcart2pol.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Coordinate-Transformations.html#doc%2dcart2pol">
diff --git a/doc/interpreter/HTML/doc_002dcart2sph.html b/doc/interpreter/HTML/doc_002dcart2sph.html
new file mode 100644
index 0000000..4f9a89e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcart2sph.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Coordinate-Transformations.html#doc%2dcart2sph">
diff --git a/doc/interpreter/HTML/doc_002dcast.html b/doc/interpreter/HTML/doc_002dcast.html
new file mode 100644
index 0000000..b82a54d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcast.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Built_002din-Data-Types.html#doc%2dcast">
diff --git a/doc/interpreter/HTML/doc_002dcat.html b/doc/interpreter/HTML/doc_002dcat.html
new file mode 100644
index 0000000..42e65fb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dcat">
diff --git a/doc/interpreter/HTML/doc_002dcauchy_005fcdf.html b/doc/interpreter/HTML/doc_002dcauchy_005fcdf.html
new file mode 100644
index 0000000..9b2daa7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcauchy_005fcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dcauchy%5fcdf">
diff --git a/doc/interpreter/HTML/doc_002dcauchy_005finv.html b/doc/interpreter/HTML/doc_002dcauchy_005finv.html
new file mode 100644
index 0000000..5fff622
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcauchy_005finv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dcauchy%5finv">
diff --git a/doc/interpreter/HTML/doc_002dcauchy_005fpdf.html b/doc/interpreter/HTML/doc_002dcauchy_005fpdf.html
new file mode 100644
index 0000000..1aa5bc6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcauchy_005fpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dcauchy%5fpdf">
diff --git a/doc/interpreter/HTML/doc_002dcauchy_005frnd.html b/doc/interpreter/HTML/doc_002dcauchy_005frnd.html
new file mode 100644
index 0000000..ea3aab7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcauchy_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dcauchy%5frnd">
diff --git a/doc/interpreter/HTML/doc_002dcaxis.html b/doc/interpreter/HTML/doc_002dcaxis.html
new file mode 100644
index 0000000..c80c345
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcaxis.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcaxis">
diff --git a/doc/interpreter/HTML/doc_002dccolamd.html b/doc/interpreter/HTML/doc_002dccolamd.html
new file mode 100644
index 0000000..3cd1ae1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dccolamd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2dccolamd">
diff --git a/doc/interpreter/HTML/doc_002dcd.html b/doc/interpreter/HTML/doc_002dcd.html
new file mode 100644
index 0000000..ac329d0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Current-Working-Directory.html#doc%2dcd">
diff --git a/doc/interpreter/HTML/doc_002dceil.html b/doc/interpreter/HTML/doc_002dceil.html
new file mode 100644
index 0000000..aef793b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dceil.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dceil">
diff --git a/doc/interpreter/HTML/doc_002dcell.html b/doc/interpreter/HTML/doc_002dcell.html
new file mode 100644
index 0000000..27c40cd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcell.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Cell-Arrays.html#doc%2dcell">
diff --git a/doc/interpreter/HTML/doc_002dcell2mat.html b/doc/interpreter/HTML/doc_002dcell2mat.html
new file mode 100644
index 0000000..1976da2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcell2mat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Processing-Data-in-Cell-Arrays.html#doc%2dcell2mat">
diff --git a/doc/interpreter/HTML/doc_002dcell2struct.html b/doc/interpreter/HTML/doc_002dcell2struct.html
new file mode 100644
index 0000000..dc461df
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcell2struct.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Processing-Data-in-Cell-Arrays.html#doc%2dcell2struct">
diff --git a/doc/interpreter/HTML/doc_002dcelldisp.html b/doc/interpreter/HTML/doc_002dcelldisp.html
new file mode 100644
index 0000000..03ad6d6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcelldisp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Usage-of-Cell-Arrays.html#doc%2dcelldisp">
diff --git a/doc/interpreter/HTML/doc_002dcellfun.html b/doc/interpreter/HTML/doc_002dcellfun.html
new file mode 100644
index 0000000..7bb7cc3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcellfun.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Processing-Data-in-Cell-Arrays.html#doc%2dcellfun">
diff --git a/doc/interpreter/HTML/doc_002dcellidx.html b/doc/interpreter/HTML/doc_002dcellidx.html
new file mode 100644
index 0000000..8e3362e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcellidx.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Cell-Arrays-of-Strings.html#doc%2dcellidx">
diff --git a/doc/interpreter/HTML/doc_002dcellstr.html b/doc/interpreter/HTML/doc_002dcellstr.html
new file mode 100644
index 0000000..eeb652b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcellstr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Cell-Arrays-of-Strings.html#doc%2dcellstr">
diff --git a/doc/interpreter/HTML/doc_002dcenter.html b/doc/interpreter/HTML/doc_002dcenter.html
new file mode 100644
index 0000000..fd075d6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcenter.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dcenter">
diff --git a/doc/interpreter/HTML/doc_002dcgs.html b/doc/interpreter/HTML/doc_002dcgs.html
new file mode 100644
index 0000000..e5a09e7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcgs.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Specialized-Solvers.html#doc%2dcgs">
diff --git a/doc/interpreter/HTML/doc_002dchar.html b/doc/interpreter/HTML/doc_002dchar.html
new file mode 100644
index 0000000..1e8e8cb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Concatenating-Strings.html#doc%2dchar">
diff --git a/doc/interpreter/HTML/doc_002dchi2cdf.html b/doc/interpreter/HTML/doc_002dchi2cdf.html
new file mode 100644
index 0000000..33d6749
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchi2cdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dchi2cdf">
diff --git a/doc/interpreter/HTML/doc_002dchi2inv.html b/doc/interpreter/HTML/doc_002dchi2inv.html
new file mode 100644
index 0000000..8c6bb8e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchi2inv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dchi2inv">
diff --git a/doc/interpreter/HTML/doc_002dchi2pdf.html b/doc/interpreter/HTML/doc_002dchi2pdf.html
new file mode 100644
index 0000000..46ad9f0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchi2pdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dchi2pdf">
diff --git a/doc/interpreter/HTML/doc_002dchi2rnd.html b/doc/interpreter/HTML/doc_002dchi2rnd.html
new file mode 100644
index 0000000..abd71c4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchi2rnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dchi2rnd">
diff --git a/doc/interpreter/HTML/doc_002dchisquare_005ftest_005fhomogeneity.html b/doc/interpreter/HTML/doc_002dchisquare_005ftest_005fhomogeneity.html
new file mode 100644
index 0000000..59bb7ce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchisquare_005ftest_005fhomogeneity.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dchisquare%5ftest%5fhomogeneity">
diff --git a/doc/interpreter/HTML/doc_002dchisquare_005ftest_005findependence.html b/doc/interpreter/HTML/doc_002dchisquare_005ftest_005findependence.html
new file mode 100644
index 0000000..726113e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchisquare_005ftest_005findependence.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dchisquare%5ftest%5findependence">
diff --git a/doc/interpreter/HTML/doc_002dchol.html b/doc/interpreter/HTML/doc_002dchol.html
new file mode 100644
index 0000000..01beb61
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchol.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dchol">
diff --git a/doc/interpreter/HTML/doc_002dchol2inv.html b/doc/interpreter/HTML/doc_002dchol2inv.html
new file mode 100644
index 0000000..3f2740b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dchol2inv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dchol2inv">
diff --git a/doc/interpreter/HTML/doc_002dcholdelete.html b/doc/interpreter/HTML/doc_002dcholdelete.html
new file mode 100644
index 0000000..779845a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcholdelete.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dcholdelete">
diff --git a/doc/interpreter/HTML/doc_002dcholinsert.html b/doc/interpreter/HTML/doc_002dcholinsert.html
new file mode 100644
index 0000000..ccaa778
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcholinsert.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dcholinsert">
diff --git a/doc/interpreter/HTML/doc_002dcholinv.html b/doc/interpreter/HTML/doc_002dcholinv.html
new file mode 100644
index 0000000..b945142
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcholinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dcholinv">
diff --git a/doc/interpreter/HTML/doc_002dcholshift.html b/doc/interpreter/HTML/doc_002dcholshift.html
new file mode 100644
index 0000000..414ee5f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcholshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dcholshift">
diff --git a/doc/interpreter/HTML/doc_002dcholupdate.html b/doc/interpreter/HTML/doc_002dcholupdate.html
new file mode 100644
index 0000000..c80b074
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcholupdate.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dcholupdate">
diff --git a/doc/interpreter/HTML/doc_002dcircshift.html b/doc/interpreter/HTML/doc_002dcircshift.html
new file mode 100644
index 0000000..e21dddb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcircshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dcircshift">
diff --git a/doc/interpreter/HTML/doc_002dcla.html b/doc/interpreter/HTML/doc_002dcla.html
new file mode 100644
index 0000000..0fbb9ee
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcla.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dcla">
diff --git a/doc/interpreter/HTML/doc_002dclabel.html b/doc/interpreter/HTML/doc_002dclabel.html
new file mode 100644
index 0000000..98c41f4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclabel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dclabel">
diff --git a/doc/interpreter/HTML/doc_002dclass.html b/doc/interpreter/HTML/doc_002dclass.html
new file mode 100644
index 0000000..f3e6bab
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclass.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Built_002din-Data-Types.html#doc%2dclass">
diff --git a/doc/interpreter/HTML/doc_002dclc.html b/doc/interpreter/HTML/doc_002dclc.html
new file mode 100644
index 0000000..81ea13e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Cursor-Motion.html#doc%2dclc">
diff --git a/doc/interpreter/HTML/doc_002dclear.html b/doc/interpreter/HTML/doc_002dclear.html
new file mode 100644
index 0000000..38132db
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclear.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dclear">
diff --git a/doc/interpreter/HTML/doc_002dclf.html b/doc/interpreter/HTML/doc_002dclf.html
new file mode 100644
index 0000000..d6f2414
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dclf">
diff --git a/doc/interpreter/HTML/doc_002dclock.html b/doc/interpreter/HTML/doc_002dclock.html
new file mode 100644
index 0000000..f89d9b0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclock.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dclock">
diff --git a/doc/interpreter/HTML/doc_002dcloglog.html b/doc/interpreter/HTML/doc_002dcloglog.html
new file mode 100644
index 0000000..9d627d1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcloglog.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dcloglog">
diff --git a/doc/interpreter/HTML/doc_002dclose.html b/doc/interpreter/HTML/doc_002dclose.html
new file mode 100644
index 0000000..0e757a8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclose.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dclose">
diff --git a/doc/interpreter/HTML/doc_002dclosereq.html b/doc/interpreter/HTML/doc_002dclosereq.html
new file mode 100644
index 0000000..fb9dbe1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dclosereq.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dclosereq">
diff --git a/doc/interpreter/HTML/doc_002dcolamd.html b/doc/interpreter/HTML/doc_002dcolamd.html
new file mode 100644
index 0000000..bb3ff43
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolamd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2dcolamd">
diff --git a/doc/interpreter/HTML/doc_002dcolloc.html b/doc/interpreter/HTML/doc_002dcolloc.html
new file mode 100644
index 0000000..7644400
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolloc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Orthogonal-Collocation.html#doc%2dcolloc">
diff --git a/doc/interpreter/HTML/doc_002dcolon.html b/doc/interpreter/HTML/doc_002dcolon.html
new file mode 100644
index 0000000..ef8373e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolon.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Indexing-Objects.html#doc%2dcolon">
diff --git a/doc/interpreter/HTML/doc_002dcolorbar.html b/doc/interpreter/HTML/doc_002dcolorbar.html
new file mode 100644
index 0000000..e5dd6a3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolorbar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dcolorbar">
diff --git a/doc/interpreter/HTML/doc_002dcolormap.html b/doc/interpreter/HTML/doc_002dcolormap.html
new file mode 100644
index 0000000..8fda914
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolormap.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dcolormap">
diff --git a/doc/interpreter/HTML/doc_002dcolperm.html b/doc/interpreter/HTML/doc_002dcolperm.html
new file mode 100644
index 0000000..fb21b6b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolperm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2dcolperm">
diff --git a/doc/interpreter/HTML/doc_002dcolumns.html b/doc/interpreter/HTML/doc_002dcolumns.html
new file mode 100644
index 0000000..b0a434f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcolumns.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dcolumns">
diff --git a/doc/interpreter/HTML/doc_002dcomet.html b/doc/interpreter/HTML/doc_002dcomet.html
new file mode 100644
index 0000000..330749f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcomet.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcomet">
diff --git a/doc/interpreter/HTML/doc_002dcommand_005fline_005fpath.html b/doc/interpreter/HTML/doc_002dcommand_005fline_005fpath.html
new file mode 100644
index 0000000..a228e63
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcommand_005fline_005fpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dcommand%5fline%5fpath">
diff --git a/doc/interpreter/HTML/doc_002dcommon_005fsize.html b/doc/interpreter/HTML/doc_002dcommon_005fsize.html
new file mode 100644
index 0000000..9ecb3f0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcommon_005fsize.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dcommon%5fsize">
diff --git a/doc/interpreter/HTML/doc_002dcommutation_005fmatrix.html b/doc/interpreter/HTML/doc_002dcommutation_005fmatrix.html
new file mode 100644
index 0000000..a411236
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcommutation_005fmatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dcommutation%5fmatrix">
diff --git a/doc/interpreter/HTML/doc_002dcompan.html b/doc/interpreter/HTML/doc_002dcompan.html
new file mode 100644
index 0000000..afe35f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcompan.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Roots.html#doc%2dcompan">
diff --git a/doc/interpreter/HTML/doc_002dcompass.html b/doc/interpreter/HTML/doc_002dcompass.html
new file mode 100644
index 0000000..5c349fd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcompass.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcompass">
diff --git a/doc/interpreter/HTML/doc_002dcomplement.html b/doc/interpreter/HTML/doc_002dcomplement.html
new file mode 100644
index 0000000..63a0017
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcomplement.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Set-Operations.html#doc%2dcomplement">
diff --git a/doc/interpreter/HTML/doc_002dcompletion_005fappend_005fchar.html b/doc/interpreter/HTML/doc_002dcompletion_005fappend_005fchar.html
new file mode 100644
index 0000000..dd5e60f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcompletion_005fappend_005fchar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-Completion.html#doc%2dcompletion%5fappend%5fchar">
diff --git a/doc/interpreter/HTML/doc_002dcompletion_005fmatches.html b/doc/interpreter/HTML/doc_002dcompletion_005fmatches.html
new file mode 100644
index 0000000..eaffb4a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcompletion_005fmatches.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-Completion.html#doc%2dcompletion%5fmatches">
diff --git a/doc/interpreter/HTML/doc_002dcomplex.html b/doc/interpreter/HTML/doc_002dcomplex.html
new file mode 100644
index 0000000..b4feabf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcomplex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Numeric-Data-Types.html#doc%2dcomplex">
diff --git a/doc/interpreter/HTML/doc_002dcomputer.html b/doc/interpreter/HTML/doc_002dcomputer.html
new file mode 100644
index 0000000..1fdbfee
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcomputer.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dcomputer">
diff --git a/doc/interpreter/HTML/doc_002dcond.html b/doc/interpreter/HTML/doc_002dcond.html
new file mode 100644
index 0000000..c61774c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcond.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dcond">
diff --git a/doc/interpreter/HTML/doc_002dcondest.html b/doc/interpreter/HTML/doc_002dcondest.html
new file mode 100644
index 0000000..15de2f6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcondest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dcondest">
diff --git a/doc/interpreter/HTML/doc_002dconfirm_005frecursive_005frmdir.html b/doc/interpreter/HTML/doc_002dconfirm_005frecursive_005frmdir.html
new file mode 100644
index 0000000..54f73f5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconfirm_005frecursive_005frmdir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dconfirm%5frecursive%5frmdir">
diff --git a/doc/interpreter/HTML/doc_002dconj.html b/doc/interpreter/HTML/doc_002dconj.html
new file mode 100644
index 0000000..f73732d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconj.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Complex-Arithmetic.html#doc%2dconj">
diff --git a/doc/interpreter/HTML/doc_002dcontour.html b/doc/interpreter/HTML/doc_002dcontour.html
new file mode 100644
index 0000000..fcb68c3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcontour.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcontour">
diff --git a/doc/interpreter/HTML/doc_002dcontour3.html b/doc/interpreter/HTML/doc_002dcontour3.html
new file mode 100644
index 0000000..e565b46
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcontour3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcontour3">
diff --git a/doc/interpreter/HTML/doc_002dcontourc.html b/doc/interpreter/HTML/doc_002dcontourc.html
new file mode 100644
index 0000000..6f6fc86
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcontourc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcontourc">
diff --git a/doc/interpreter/HTML/doc_002dcontourf.html b/doc/interpreter/HTML/doc_002dcontourf.html
new file mode 100644
index 0000000..cce460b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcontourf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dcontourf">
diff --git a/doc/interpreter/HTML/doc_002dcontrast.html b/doc/interpreter/HTML/doc_002dcontrast.html
new file mode 100644
index 0000000..2937452
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcontrast.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dcontrast">
diff --git a/doc/interpreter/HTML/doc_002dconv.html b/doc/interpreter/HTML/doc_002dconv.html
new file mode 100644
index 0000000..9eca0b3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Products-of-Polynomials.html#doc%2dconv">
diff --git a/doc/interpreter/HTML/doc_002dconv2.html b/doc/interpreter/HTML/doc_002dconv2.html
new file mode 100644
index 0000000..2ea769f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconv2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Products-of-Polynomials.html#doc%2dconv2">
diff --git a/doc/interpreter/HTML/doc_002dconvhull.html b/doc/interpreter/HTML/doc_002dconvhull.html
new file mode 100644
index 0000000..f9d83f1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconvhull.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Convex-Hull.html#doc%2dconvhull">
diff --git a/doc/interpreter/HTML/doc_002dconvhulln.html b/doc/interpreter/HTML/doc_002dconvhulln.html
new file mode 100644
index 0000000..057fe83
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconvhulln.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Convex-Hull.html#doc%2dconvhulln">
diff --git a/doc/interpreter/HTML/doc_002dconvn.html b/doc/interpreter/HTML/doc_002dconvn.html
new file mode 100644
index 0000000..b6085ac
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dconvn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Products-of-Polynomials.html#doc%2dconvn">
diff --git a/doc/interpreter/HTML/doc_002dcool.html b/doc/interpreter/HTML/doc_002dcool.html
new file mode 100644
index 0000000..18b8ad2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcool.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dcool">
diff --git a/doc/interpreter/HTML/doc_002dcopper.html b/doc/interpreter/HTML/doc_002dcopper.html
new file mode 100644
index 0000000..93a1e79
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcopper.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dcopper">
diff --git a/doc/interpreter/HTML/doc_002dcopyfile.html b/doc/interpreter/HTML/doc_002dcopyfile.html
new file mode 100644
index 0000000..d28145f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcopyfile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dcopyfile">
diff --git a/doc/interpreter/HTML/doc_002dcor.html b/doc/interpreter/HTML/doc_002dcor.html
new file mode 100644
index 0000000..e1a06f2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dcor">
diff --git a/doc/interpreter/HTML/doc_002dcor_005ftest.html b/doc/interpreter/HTML/doc_002dcor_005ftest.html
new file mode 100644
index 0000000..0b4d6d5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcor_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dcor%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dcorrcoef.html b/doc/interpreter/HTML/doc_002dcorrcoef.html
new file mode 100644
index 0000000..bcf4ed2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcorrcoef.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dcorrcoef">
diff --git a/doc/interpreter/HTML/doc_002dcos.html b/doc/interpreter/HTML/doc_002dcos.html
new file mode 100644
index 0000000..3a78249
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcos.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcos">
diff --git a/doc/interpreter/HTML/doc_002dcosd.html b/doc/interpreter/HTML/doc_002dcosd.html
new file mode 100644
index 0000000..92dbbe3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcosd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcosd">
diff --git a/doc/interpreter/HTML/doc_002dcosh.html b/doc/interpreter/HTML/doc_002dcosh.html
new file mode 100644
index 0000000..833ecce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcosh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcosh">
diff --git a/doc/interpreter/HTML/doc_002dcot.html b/doc/interpreter/HTML/doc_002dcot.html
new file mode 100644
index 0000000..bb2e81d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcot">
diff --git a/doc/interpreter/HTML/doc_002dcotd.html b/doc/interpreter/HTML/doc_002dcotd.html
new file mode 100644
index 0000000..9eaa1a1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcotd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcotd">
diff --git a/doc/interpreter/HTML/doc_002dcoth.html b/doc/interpreter/HTML/doc_002dcoth.html
new file mode 100644
index 0000000..8ee2abf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcoth.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcoth">
diff --git a/doc/interpreter/HTML/doc_002dcov.html b/doc/interpreter/HTML/doc_002dcov.html
new file mode 100644
index 0000000..024e578
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcov.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dcov">
diff --git a/doc/interpreter/HTML/doc_002dcplxpair.html b/doc/interpreter/HTML/doc_002dcplxpair.html
new file mode 100644
index 0000000..1c3c672
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcplxpair.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Complex-Arithmetic.html#doc%2dcplxpair">
diff --git a/doc/interpreter/HTML/doc_002dcputime.html b/doc/interpreter/HTML/doc_002dcputime.html
new file mode 100644
index 0000000..535bc88
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcputime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dcputime">
diff --git a/doc/interpreter/HTML/doc_002dcrash_005fdumps_005foctave_005fcore.html b/doc/interpreter/HTML/doc_002dcrash_005fdumps_005foctave_005fcore.html
new file mode 100644
index 0000000..16fe30d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcrash_005fdumps_005foctave_005fcore.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Saving-Data-on-Unexpected-Exits.html#doc%2dcrash%5fdumps%5foctave%5fcore">
diff --git a/doc/interpreter/HTML/doc_002dcross.html b/doc/interpreter/HTML/doc_002dcross.html
new file mode 100644
index 0000000..a009cff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcross.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dcross">
diff --git a/doc/interpreter/HTML/doc_002dcsc.html b/doc/interpreter/HTML/doc_002dcsc.html
new file mode 100644
index 0000000..4c1b19d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcsc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcsc">
diff --git a/doc/interpreter/HTML/doc_002dcscd.html b/doc/interpreter/HTML/doc_002dcscd.html
new file mode 100644
index 0000000..974901b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcscd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcscd">
diff --git a/doc/interpreter/HTML/doc_002dcsch.html b/doc/interpreter/HTML/doc_002dcsch.html
new file mode 100644
index 0000000..a073277
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcsch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dcsch">
diff --git a/doc/interpreter/HTML/doc_002dcstrcat.html b/doc/interpreter/HTML/doc_002dcstrcat.html
new file mode 100644
index 0000000..e6107c7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcstrcat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Concatenating-Strings.html#doc%2dcstrcat">
diff --git a/doc/interpreter/HTML/doc_002dcsvread.html b/doc/interpreter/HTML/doc_002dcsvread.html
new file mode 100644
index 0000000..51e2202
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcsvread.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dcsvread">
diff --git a/doc/interpreter/HTML/doc_002dcsvwrite.html b/doc/interpreter/HTML/doc_002dcsvwrite.html
new file mode 100644
index 0000000..94066ac
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcsvwrite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dcsvwrite">
diff --git a/doc/interpreter/HTML/doc_002dcsymamd.html b/doc/interpreter/HTML/doc_002dcsymamd.html
new file mode 100644
index 0000000..80e4d2d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcsymamd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2dcsymamd">
diff --git a/doc/interpreter/HTML/doc_002dctime.html b/doc/interpreter/HTML/doc_002dctime.html
new file mode 100644
index 0000000..f17e72a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dctime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dctime">
diff --git a/doc/interpreter/HTML/doc_002dctranspose.html b/doc/interpreter/HTML/doc_002dctranspose.html
new file mode 100644
index 0000000..316e463
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dctranspose.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dctranspose">
diff --git a/doc/interpreter/HTML/doc_002dcummax.html b/doc/interpreter/HTML/doc_002dcummax.html
new file mode 100644
index 0000000..e372917
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcummax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dcummax">
diff --git a/doc/interpreter/HTML/doc_002dcummin.html b/doc/interpreter/HTML/doc_002dcummin.html
new file mode 100644
index 0000000..59e6158
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcummin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dcummin">
diff --git a/doc/interpreter/HTML/doc_002dcumprod.html b/doc/interpreter/HTML/doc_002dcumprod.html
new file mode 100644
index 0000000..b790c3c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcumprod.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sums-and-Products.html#doc%2dcumprod">
diff --git a/doc/interpreter/HTML/doc_002dcumsum.html b/doc/interpreter/HTML/doc_002dcumsum.html
new file mode 100644
index 0000000..a89fd6e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcumsum.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sums-and-Products.html#doc%2dcumsum">
diff --git a/doc/interpreter/HTML/doc_002dcumtrapz.html b/doc/interpreter/HTML/doc_002dcumtrapz.html
new file mode 100644
index 0000000..b309e2c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcumtrapz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dcumtrapz">
diff --git a/doc/interpreter/HTML/doc_002dcut.html b/doc/interpreter/HTML/doc_002dcut.html
new file mode 100644
index 0000000..6c57c6b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcut.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dcut">
diff --git a/doc/interpreter/HTML/doc_002dcylinder.html b/doc/interpreter/HTML/doc_002dcylinder.html
new file mode 100644
index 0000000..bcc778e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dcylinder.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Geometric-Shapes.html#doc%2dcylinder">
diff --git a/doc/interpreter/HTML/doc_002ddaspk.html b/doc/interpreter/HTML/doc_002ddaspk.html
new file mode 100644
index 0000000..b75b12f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddaspk.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Differential_002dAlgebraic-Equations.html#doc%2ddaspk">
diff --git a/doc/interpreter/HTML/doc_002ddaspk_005foptions.html b/doc/interpreter/HTML/doc_002ddaspk_005foptions.html
new file mode 100644
index 0000000..e805821
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddaspk_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Differential_002dAlgebraic-Equations.html#doc%2ddaspk%5foptions">
diff --git a/doc/interpreter/HTML/doc_002ddasrt.html b/doc/interpreter/HTML/doc_002ddasrt.html
new file mode 100644
index 0000000..f804977
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddasrt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Differential_002dAlgebraic-Equations.html#doc%2ddasrt">
diff --git a/doc/interpreter/HTML/doc_002ddasrt_005foptions.html b/doc/interpreter/HTML/doc_002ddasrt_005foptions.html
new file mode 100644
index 0000000..9da2d9c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddasrt_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Differential_002dAlgebraic-Equations.html#doc%2ddasrt%5foptions">
diff --git a/doc/interpreter/HTML/doc_002ddassl.html b/doc/interpreter/HTML/doc_002ddassl.html
new file mode 100644
index 0000000..c19a3dc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddassl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Differential_002dAlgebraic-Equations.html#doc%2ddassl">
diff --git a/doc/interpreter/HTML/doc_002ddassl_005foptions.html b/doc/interpreter/HTML/doc_002ddassl_005foptions.html
new file mode 100644
index 0000000..6592445
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddassl_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Differential_002dAlgebraic-Equations.html#doc%2ddassl%5foptions">
diff --git a/doc/interpreter/HTML/doc_002ddate.html b/doc/interpreter/HTML/doc_002ddate.html
new file mode 100644
index 0000000..827f247
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddate.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2ddate">
diff --git a/doc/interpreter/HTML/doc_002ddatenum.html b/doc/interpreter/HTML/doc_002ddatenum.html
new file mode 100644
index 0000000..c273aaa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddatenum.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2ddatenum">
diff --git a/doc/interpreter/HTML/doc_002ddatestr.html b/doc/interpreter/HTML/doc_002ddatestr.html
new file mode 100644
index 0000000..2865abe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddatestr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2ddatestr">
diff --git a/doc/interpreter/HTML/doc_002ddatetick.html b/doc/interpreter/HTML/doc_002ddatetick.html
new file mode 100644
index 0000000..c601151
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddatetick.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2ddatetick">
diff --git a/doc/interpreter/HTML/doc_002ddatevec.html b/doc/interpreter/HTML/doc_002ddatevec.html
new file mode 100644
index 0000000..bf3da7c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddatevec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2ddatevec">
diff --git a/doc/interpreter/HTML/doc_002ddbclear.html b/doc/interpreter/HTML/doc_002ddbclear.html
new file mode 100644
index 0000000..60c6780
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbclear.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Breakpoints.html#doc%2ddbclear">
diff --git a/doc/interpreter/HTML/doc_002ddbcont.html b/doc/interpreter/HTML/doc_002ddbcont.html
new file mode 100644
index 0000000..e803176
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbcont.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Leaving-Debug-Mode.html#doc%2ddbcont">
diff --git a/doc/interpreter/HTML/doc_002ddbdown.html b/doc/interpreter/HTML/doc_002ddbdown.html
new file mode 100644
index 0000000..7d946fc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbdown.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Call-Stack.html#doc%2ddbdown">
diff --git a/doc/interpreter/HTML/doc_002ddblquad.html b/doc/interpreter/HTML/doc_002ddblquad.html
new file mode 100644
index 0000000..69eb6db
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddblquad.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-Multiple-Variables.html#doc%2ddblquad">
diff --git a/doc/interpreter/HTML/doc_002ddbquit.html b/doc/interpreter/HTML/doc_002ddbquit.html
new file mode 100644
index 0000000..707e55b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbquit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Leaving-Debug-Mode.html#doc%2ddbquit">
diff --git a/doc/interpreter/HTML/doc_002ddbstack.html b/doc/interpreter/HTML/doc_002ddbstack.html
new file mode 100644
index 0000000..3625b6d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbstack.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Call-Stack.html#doc%2ddbstack">
diff --git a/doc/interpreter/HTML/doc_002ddbstatus.html b/doc/interpreter/HTML/doc_002ddbstatus.html
new file mode 100644
index 0000000..5cbd1c5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbstatus.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Breakpoints.html#doc%2ddbstatus">
diff --git a/doc/interpreter/HTML/doc_002ddbstep.html b/doc/interpreter/HTML/doc_002ddbstep.html
new file mode 100644
index 0000000..ab398f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbstep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Debug-Mode.html#doc%2ddbstep">
diff --git a/doc/interpreter/HTML/doc_002ddbstop.html b/doc/interpreter/HTML/doc_002ddbstop.html
new file mode 100644
index 0000000..f218c6f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbstop.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Breakpoints.html#doc%2ddbstop">
diff --git a/doc/interpreter/HTML/doc_002ddbtype.html b/doc/interpreter/HTML/doc_002ddbtype.html
new file mode 100644
index 0000000..fb23798
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbtype.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Debug-Mode.html#doc%2ddbtype">
diff --git a/doc/interpreter/HTML/doc_002ddbup.html b/doc/interpreter/HTML/doc_002ddbup.html
new file mode 100644
index 0000000..01999be
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbup.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Call-Stack.html#doc%2ddbup">
diff --git a/doc/interpreter/HTML/doc_002ddbwhere.html b/doc/interpreter/HTML/doc_002ddbwhere.html
new file mode 100644
index 0000000..2b0ce33
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddbwhere.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Debug-Mode.html#doc%2ddbwhere">
diff --git a/doc/interpreter/HTML/doc_002ddeal.html b/doc/interpreter/HTML/doc_002ddeal.html
new file mode 100644
index 0000000..3f97b10
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddeal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Variable_002dlength-Return-Lists.html#doc%2ddeal">
diff --git a/doc/interpreter/HTML/doc_002ddeblank.html b/doc/interpreter/HTML/doc_002ddeblank.html
new file mode 100644
index 0000000..274435c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddeblank.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2ddeblank">
diff --git a/doc/interpreter/HTML/doc_002ddebug_005fon_005ferror.html b/doc/interpreter/HTML/doc_002ddebug_005fon_005ferror.html
new file mode 100644
index 0000000..f7f4854
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddebug_005fon_005ferror.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Entering-Debug-Mode.html#doc%2ddebug%5fon%5ferror">
diff --git a/doc/interpreter/HTML/doc_002ddebug_005fon_005finterrupt.html b/doc/interpreter/HTML/doc_002ddebug_005fon_005finterrupt.html
new file mode 100644
index 0000000..3282766
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddebug_005fon_005finterrupt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Entering-Debug-Mode.html#doc%2ddebug%5fon%5finterrupt">
diff --git a/doc/interpreter/HTML/doc_002ddebug_005fon_005fwarning.html b/doc/interpreter/HTML/doc_002ddebug_005fon_005fwarning.html
new file mode 100644
index 0000000..9a21873
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddebug_005fon_005fwarning.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Entering-Debug-Mode.html#doc%2ddebug%5fon%5fwarning">
diff --git a/doc/interpreter/HTML/doc_002ddec2base.html b/doc/interpreter/HTML/doc_002ddec2base.html
new file mode 100644
index 0000000..46968e7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddec2base.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2ddec2base">
diff --git a/doc/interpreter/HTML/doc_002ddec2bin.html b/doc/interpreter/HTML/doc_002ddec2bin.html
new file mode 100644
index 0000000..2ab5f08
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddec2bin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2ddec2bin">
diff --git a/doc/interpreter/HTML/doc_002ddec2hex.html b/doc/interpreter/HTML/doc_002ddec2hex.html
new file mode 100644
index 0000000..74a1a32
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddec2hex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2ddec2hex">
diff --git a/doc/interpreter/HTML/doc_002ddeconv.html b/doc/interpreter/HTML/doc_002ddeconv.html
new file mode 100644
index 0000000..644c11f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddeconv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Products-of-Polynomials.html#doc%2ddeconv">
diff --git a/doc/interpreter/HTML/doc_002ddefault_005fsave_005foptions.html b/doc/interpreter/HTML/doc_002ddefault_005fsave_005foptions.html
new file mode 100644
index 0000000..03e5195
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddefault_005fsave_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2ddefault%5fsave%5foptions">
diff --git a/doc/interpreter/HTML/doc_002ddel2.html b/doc/interpreter/HTML/doc_002ddel2.html
new file mode 100644
index 0000000..6d2018d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddel2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2ddel2">
diff --git a/doc/interpreter/HTML/doc_002ddelaunay.html b/doc/interpreter/HTML/doc_002ddelaunay.html
new file mode 100644
index 0000000..473508a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddelaunay.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Delaunay-Triangulation.html#doc%2ddelaunay">
diff --git a/doc/interpreter/HTML/doc_002ddelaunay3.html b/doc/interpreter/HTML/doc_002ddelaunay3.html
new file mode 100644
index 0000000..7d6bfb2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddelaunay3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Delaunay-Triangulation.html#doc%2ddelaunay3">
diff --git a/doc/interpreter/HTML/doc_002ddelaunayn.html b/doc/interpreter/HTML/doc_002ddelaunayn.html
new file mode 100644
index 0000000..abe72c9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddelaunayn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Delaunay-Triangulation.html#doc%2ddelaunayn">
diff --git a/doc/interpreter/HTML/doc_002ddelete.html b/doc/interpreter/HTML/doc_002ddelete.html
new file mode 100644
index 0000000..dad0bca
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddelete.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2ddelete">
diff --git a/doc/interpreter/HTML/doc_002ddellistener.html b/doc/interpreter/HTML/doc_002ddellistener.html
new file mode 100644
index 0000000..610e246
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddellistener.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Groups.html#doc%2ddellistener">
diff --git a/doc/interpreter/HTML/doc_002ddemo.html b/doc/interpreter/HTML/doc_002ddemo.html
new file mode 100644
index 0000000..8b40983
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddemo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Demonstration-Functions.html#doc%2ddemo">
diff --git a/doc/interpreter/HTML/doc_002ddet.html b/doc/interpreter/HTML/doc_002ddet.html
new file mode 100644
index 0000000..597f616
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddet.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2ddet">
diff --git a/doc/interpreter/HTML/doc_002ddetrend.html b/doc/interpreter/HTML/doc_002ddetrend.html
new file mode 100644
index 0000000..83efec0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddetrend.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2ddetrend">
diff --git a/doc/interpreter/HTML/doc_002ddiag.html b/doc/interpreter/HTML/doc_002ddiag.html
new file mode 100644
index 0000000..987577c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiag.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2ddiag">
diff --git a/doc/interpreter/HTML/doc_002ddiary.html b/doc/interpreter/HTML/doc_002ddiary.html
new file mode 100644
index 0000000..457c654
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiary.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Diary-and-Echo-Commands.html#doc%2ddiary">
diff --git a/doc/interpreter/HTML/doc_002ddiff.html b/doc/interpreter/HTML/doc_002ddiff.html
new file mode 100644
index 0000000..75eff31
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiff.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2ddiff">
diff --git a/doc/interpreter/HTML/doc_002ddiffpara.html b/doc/interpreter/HTML/doc_002ddiffpara.html
new file mode 100644
index 0000000..95d39da
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiffpara.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2ddiffpara">
diff --git a/doc/interpreter/HTML/doc_002ddiffuse.html b/doc/interpreter/HTML/doc_002ddiffuse.html
new file mode 100644
index 0000000..3b9ad89
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiffuse.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2ddiffuse">
diff --git a/doc/interpreter/HTML/doc_002ddir.html b/doc/interpreter/HTML/doc_002ddir.html
new file mode 100644
index 0000000..7179218
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Current-Working-Directory.html#doc%2ddir">
diff --git a/doc/interpreter/HTML/doc_002ddiscrete_005fcdf.html b/doc/interpreter/HTML/doc_002ddiscrete_005fcdf.html
new file mode 100644
index 0000000..fba8918
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiscrete_005fcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2ddiscrete%5fcdf">
diff --git a/doc/interpreter/HTML/doc_002ddiscrete_005finv.html b/doc/interpreter/HTML/doc_002ddiscrete_005finv.html
new file mode 100644
index 0000000..97d0d95
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiscrete_005finv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2ddiscrete%5finv">
diff --git a/doc/interpreter/HTML/doc_002ddiscrete_005fpdf.html b/doc/interpreter/HTML/doc_002ddiscrete_005fpdf.html
new file mode 100644
index 0000000..30f48ac
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiscrete_005fpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2ddiscrete%5fpdf">
diff --git a/doc/interpreter/HTML/doc_002ddiscrete_005frnd.html b/doc/interpreter/HTML/doc_002ddiscrete_005frnd.html
new file mode 100644
index 0000000..39df8aa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddiscrete_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2ddiscrete%5frnd">
diff --git a/doc/interpreter/HTML/doc_002ddisp.html b/doc/interpreter/HTML/doc_002ddisp.html
new file mode 100644
index 0000000..9d97ab3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddisp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Terminal-Output.html#doc%2ddisp">
diff --git a/doc/interpreter/HTML/doc_002ddispatch.html b/doc/interpreter/HTML/doc_002ddispatch.html
new file mode 100644
index 0000000..d50421a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddispatch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Overloading-and-Autoloading.html#doc%2ddispatch">
diff --git a/doc/interpreter/HTML/doc_002ddisplay.html b/doc/interpreter/HTML/doc_002ddisplay.html
new file mode 100644
index 0000000..667ef50
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddisplay.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Classes.html#doc%2ddisplay">
diff --git a/doc/interpreter/HTML/doc_002ddlmread.html b/doc/interpreter/HTML/doc_002ddlmread.html
new file mode 100644
index 0000000..8a4cec4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddlmread.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2ddlmread">
diff --git a/doc/interpreter/HTML/doc_002ddlmwrite.html b/doc/interpreter/HTML/doc_002ddlmwrite.html
new file mode 100644
index 0000000..969bc10
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddlmwrite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2ddlmwrite">
diff --git a/doc/interpreter/HTML/doc_002ddmperm.html b/doc/interpreter/HTML/doc_002ddmperm.html
new file mode 100644
index 0000000..92440b1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddmperm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2ddmperm">
diff --git a/doc/interpreter/HTML/doc_002ddmult.html b/doc/interpreter/HTML/doc_002ddmult.html
new file mode 100644
index 0000000..b7cccd8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddmult.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2ddmult">
diff --git a/doc/interpreter/HTML/doc_002ddo_005fstring_005fescapes.html b/doc/interpreter/HTML/doc_002ddo_005fstring_005fescapes.html
new file mode 100644
index 0000000..3e6d281
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddo_005fstring_005fescapes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2ddo%5fstring%5fescapes">
diff --git a/doc/interpreter/HTML/doc_002ddoc.html b/doc/interpreter/HTML/doc_002ddoc.html
new file mode 100644
index 0000000..d2b2ac7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddoc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2ddoc">
diff --git a/doc/interpreter/HTML/doc_002ddoc_005fcache_005ffile.html b/doc/interpreter/HTML/doc_002ddoc_005fcache_005ffile.html
new file mode 100644
index 0000000..07c70d8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddoc_005fcache_005ffile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2ddoc%5fcache%5ffile">
diff --git a/doc/interpreter/HTML/doc_002ddos.html b/doc/interpreter/HTML/doc_002ddos.html
new file mode 100644
index 0000000..2ff3f00
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddos.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2ddos">
diff --git a/doc/interpreter/HTML/doc_002ddot.html b/doc/interpreter/HTML/doc_002ddot.html
new file mode 100644
index 0000000..de0aaf9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2ddot">
diff --git a/doc/interpreter/HTML/doc_002ddouble.html b/doc/interpreter/HTML/doc_002ddouble.html
new file mode 100644
index 0000000..58c343e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddouble.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Numeric-Data-Types.html#doc%2ddouble">
diff --git a/doc/interpreter/HTML/doc_002ddrawnow.html b/doc/interpreter/HTML/doc_002ddrawnow.html
new file mode 100644
index 0000000..87e3d66
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddrawnow.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2ddrawnow">
diff --git a/doc/interpreter/HTML/doc_002ddsearch.html b/doc/interpreter/HTML/doc_002ddsearch.html
new file mode 100644
index 0000000..64dfacf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddsearch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Identifying-points-in-Triangulation.html#doc%2ddsearch">
diff --git a/doc/interpreter/HTML/doc_002ddsearchn.html b/doc/interpreter/HTML/doc_002ddsearchn.html
new file mode 100644
index 0000000..e2eff24
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddsearchn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Identifying-points-in-Triangulation.html#doc%2ddsearchn">
diff --git a/doc/interpreter/HTML/doc_002ddup2.html b/doc/interpreter/HTML/doc_002ddup2.html
new file mode 100644
index 0000000..a017265
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddup2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2ddup2">
diff --git a/doc/interpreter/HTML/doc_002dduplication_005fmatrix.html b/doc/interpreter/HTML/doc_002dduplication_005fmatrix.html
new file mode 100644
index 0000000..67418b2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dduplication_005fmatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dduplication%5fmatrix">
diff --git a/doc/interpreter/HTML/doc_002ddurbinlevinson.html b/doc/interpreter/HTML/doc_002ddurbinlevinson.html
new file mode 100644
index 0000000..bcee17d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002ddurbinlevinson.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2ddurbinlevinson">
diff --git a/doc/interpreter/HTML/doc_002de.html b/doc/interpreter/HTML/doc_002de.html
new file mode 100644
index 0000000..b1ff8af
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002de.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2de">
diff --git a/doc/interpreter/HTML/doc_002decho.html b/doc/interpreter/HTML/doc_002decho.html
new file mode 100644
index 0000000..13f56e2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002decho.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Diary-and-Echo-Commands.html#doc%2decho">
diff --git a/doc/interpreter/HTML/doc_002decho_005fexecuting_005fcommands.html b/doc/interpreter/HTML/doc_002decho_005fexecuting_005fcommands.html
new file mode 100644
index 0000000..0d65325
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002decho_005fexecuting_005fcommands.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Diary-and-Echo-Commands.html#doc%2decho%5fexecuting%5fcommands">
diff --git a/doc/interpreter/HTML/doc_002dedit.html b/doc/interpreter/HTML/doc_002dedit.html
new file mode 100644
index 0000000..8ac8f50
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dedit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Files.html#doc%2dedit">
diff --git a/doc/interpreter/HTML/doc_002dedit_005fhistory.html b/doc/interpreter/HTML/doc_002dedit_005fhistory.html
new file mode 100644
index 0000000..a303c77
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dedit_005fhistory.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dedit%5fhistory">
diff --git a/doc/interpreter/HTML/doc_002deig.html b/doc/interpreter/HTML/doc_002deig.html
new file mode 100644
index 0000000..0452465
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deig.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2deig">
diff --git a/doc/interpreter/HTML/doc_002deigs.html b/doc/interpreter/HTML/doc_002deigs.html
new file mode 100644
index 0000000..283428c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deigs.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2deigs">
diff --git a/doc/interpreter/HTML/doc_002dellipsoid.html b/doc/interpreter/HTML/doc_002dellipsoid.html
new file mode 100644
index 0000000..581b411
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dellipsoid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Geometric-Shapes.html#doc%2dellipsoid">
diff --git a/doc/interpreter/HTML/doc_002dempirical_005fcdf.html b/doc/interpreter/HTML/doc_002dempirical_005fcdf.html
new file mode 100644
index 0000000..d68c60d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dempirical_005fcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dempirical%5fcdf">
diff --git a/doc/interpreter/HTML/doc_002dempirical_005finv.html b/doc/interpreter/HTML/doc_002dempirical_005finv.html
new file mode 100644
index 0000000..382459f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dempirical_005finv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dempirical%5finv">
diff --git a/doc/interpreter/HTML/doc_002dempirical_005fpdf.html b/doc/interpreter/HTML/doc_002dempirical_005fpdf.html
new file mode 100644
index 0000000..879fe08
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dempirical_005fpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dempirical%5fpdf">
diff --git a/doc/interpreter/HTML/doc_002dempirical_005frnd.html b/doc/interpreter/HTML/doc_002dempirical_005frnd.html
new file mode 100644
index 0000000..0075d9a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dempirical_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dempirical%5frnd">
diff --git a/doc/interpreter/HTML/doc_002dendgrent.html b/doc/interpreter/HTML/doc_002dendgrent.html
new file mode 100644
index 0000000..85dfbd5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dendgrent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Group-Database-Functions.html#doc%2dendgrent">
diff --git a/doc/interpreter/HTML/doc_002dendpwent.html b/doc/interpreter/HTML/doc_002dendpwent.html
new file mode 100644
index 0000000..4b07307
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dendpwent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Password-Database-Functions.html#doc%2dendpwent">
diff --git a/doc/interpreter/HTML/doc_002deomday.html b/doc/interpreter/HTML/doc_002deomday.html
new file mode 100644
index 0000000..3596b5b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deomday.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2deomday">
diff --git a/doc/interpreter/HTML/doc_002deps.html b/doc/interpreter/HTML/doc_002deps.html
new file mode 100644
index 0000000..d5c60e7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deps.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2deps">
diff --git a/doc/interpreter/HTML/doc_002deq.html b/doc/interpreter/HTML/doc_002deq.html
new file mode 100644
index 0000000..1dc412b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deq.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2deq">
diff --git a/doc/interpreter/HTML/doc_002derf.html b/doc/interpreter/HTML/doc_002derf.html
new file mode 100644
index 0000000..9fd064b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2derf">
diff --git a/doc/interpreter/HTML/doc_002derfc.html b/doc/interpreter/HTML/doc_002derfc.html
new file mode 100644
index 0000000..873cbbe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derfc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2derfc">
diff --git a/doc/interpreter/HTML/doc_002derfinv.html b/doc/interpreter/HTML/doc_002derfinv.html
new file mode 100644
index 0000000..c82efec
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derfinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2derfinv">
diff --git a/doc/interpreter/HTML/doc_002derrno.html b/doc/interpreter/HTML/doc_002derrno.html
new file mode 100644
index 0000000..aae4530
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derrno.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Catching-Errors.html#doc%2derrno">
diff --git a/doc/interpreter/HTML/doc_002derrno_005flist.html b/doc/interpreter/HTML/doc_002derrno_005flist.html
new file mode 100644
index 0000000..44d5e22
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derrno_005flist.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Catching-Errors.html#doc%2derrno%5flist">
diff --git a/doc/interpreter/HTML/doc_002derror.html b/doc/interpreter/HTML/doc_002derror.html
new file mode 100644
index 0000000..0727d57
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derror.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Raising-Errors.html#doc%2derror">
diff --git a/doc/interpreter/HTML/doc_002derrorbar.html b/doc/interpreter/HTML/doc_002derrorbar.html
new file mode 100644
index 0000000..51cae30
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002derrorbar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2derrorbar">
diff --git a/doc/interpreter/HTML/doc_002detime.html b/doc/interpreter/HTML/doc_002detime.html
new file mode 100644
index 0000000..837523c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002detime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2detime">
diff --git a/doc/interpreter/HTML/doc_002detree.html b/doc/interpreter/HTML/doc_002detree.html
new file mode 100644
index 0000000..4bf499e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002detree.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2detree">
diff --git a/doc/interpreter/HTML/doc_002detreeplot.html b/doc/interpreter/HTML/doc_002detreeplot.html
new file mode 100644
index 0000000..bb2adc8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002detreeplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2detreeplot">
diff --git a/doc/interpreter/HTML/doc_002deval.html b/doc/interpreter/HTML/doc_002deval.html
new file mode 100644
index 0000000..8fd5235
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deval.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Evaluation.html#doc%2deval">
diff --git a/doc/interpreter/HTML/doc_002devalin.html b/doc/interpreter/HTML/doc_002devalin.html
new file mode 100644
index 0000000..d69c0f4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002devalin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Evaluation-in-a-Different-Context.html#doc%2devalin">
diff --git a/doc/interpreter/HTML/doc_002dexample.html b/doc/interpreter/HTML/doc_002dexample.html
new file mode 100644
index 0000000..9e4793e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexample.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Demonstration-Functions.html#doc%2dexample">
diff --git a/doc/interpreter/HTML/doc_002dexec.html b/doc/interpreter/HTML/doc_002dexec.html
new file mode 100644
index 0000000..3c5b34b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dexec">
diff --git a/doc/interpreter/HTML/doc_002dexist.html b/doc/interpreter/HTML/doc_002dexist.html
new file mode 100644
index 0000000..c9195d2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexist.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dexist">
diff --git a/doc/interpreter/HTML/doc_002dexp.html b/doc/interpreter/HTML/doc_002dexp.html
new file mode 100644
index 0000000..28d3267
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dexp">
diff --git a/doc/interpreter/HTML/doc_002dexpcdf.html b/doc/interpreter/HTML/doc_002dexpcdf.html
new file mode 100644
index 0000000..1c9543c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexpcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dexpcdf">
diff --git a/doc/interpreter/HTML/doc_002dexpinv.html b/doc/interpreter/HTML/doc_002dexpinv.html
new file mode 100644
index 0000000..a205732
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexpinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dexpinv">
diff --git a/doc/interpreter/HTML/doc_002dexpm.html b/doc/interpreter/HTML/doc_002dexpm.html
new file mode 100644
index 0000000..e885a3e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexpm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-a-Matrix.html#doc%2dexpm">
diff --git a/doc/interpreter/HTML/doc_002dexpm1.html b/doc/interpreter/HTML/doc_002dexpm1.html
new file mode 100644
index 0000000..545c11d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexpm1.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dexpm1">
diff --git a/doc/interpreter/HTML/doc_002dexppdf.html b/doc/interpreter/HTML/doc_002dexppdf.html
new file mode 100644
index 0000000..e8440a0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexppdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dexppdf">
diff --git a/doc/interpreter/HTML/doc_002dexprnd.html b/doc/interpreter/HTML/doc_002dexprnd.html
new file mode 100644
index 0000000..95ef279
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dexprnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dexprnd">
diff --git a/doc/interpreter/HTML/doc_002deye.html b/doc/interpreter/HTML/doc_002deye.html
new file mode 100644
index 0000000..1792b9d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002deye.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2deye">
diff --git a/doc/interpreter/HTML/doc_002dezcontour.html b/doc/interpreter/HTML/doc_002dezcontour.html
new file mode 100644
index 0000000..58ed699
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezcontour.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002ddimensional-Function-Plotting.html#doc%2dezcontour">
diff --git a/doc/interpreter/HTML/doc_002dezcontourf.html b/doc/interpreter/HTML/doc_002dezcontourf.html
new file mode 100644
index 0000000..2fedbd4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezcontourf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002ddimensional-Function-Plotting.html#doc%2dezcontourf">
diff --git a/doc/interpreter/HTML/doc_002dezmesh.html b/doc/interpreter/HTML/doc_002dezmesh.html
new file mode 100644
index 0000000..6ae97f0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezmesh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Function-Plotting.html#doc%2dezmesh">
diff --git a/doc/interpreter/HTML/doc_002dezmeshc.html b/doc/interpreter/HTML/doc_002dezmeshc.html
new file mode 100644
index 0000000..9c2cd8c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezmeshc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Function-Plotting.html#doc%2dezmeshc">
diff --git a/doc/interpreter/HTML/doc_002dezplot.html b/doc/interpreter/HTML/doc_002dezplot.html
new file mode 100644
index 0000000..3daa04f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002ddimensional-Function-Plotting.html#doc%2dezplot">
diff --git a/doc/interpreter/HTML/doc_002dezplot3.html b/doc/interpreter/HTML/doc_002dezplot3.html
new file mode 100644
index 0000000..cb238d0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezplot3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Function-Plotting.html#doc%2dezplot3">
diff --git a/doc/interpreter/HTML/doc_002dezpolar.html b/doc/interpreter/HTML/doc_002dezpolar.html
new file mode 100644
index 0000000..040ccb3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezpolar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002ddimensional-Function-Plotting.html#doc%2dezpolar">
diff --git a/doc/interpreter/HTML/doc_002dezsurf.html b/doc/interpreter/HTML/doc_002dezsurf.html
new file mode 100644
index 0000000..82544fe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezsurf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Function-Plotting.html#doc%2dezsurf">
diff --git a/doc/interpreter/HTML/doc_002dezsurfc.html b/doc/interpreter/HTML/doc_002dezsurfc.html
new file mode 100644
index 0000000..2c2636b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dezsurfc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Function-Plotting.html#doc%2dezsurfc">
diff --git a/doc/interpreter/HTML/doc_002df_005ftest_005fregression.html b/doc/interpreter/HTML/doc_002df_005ftest_005fregression.html
new file mode 100644
index 0000000..5de1805
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002df_005ftest_005fregression.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2df%5ftest%5fregression">
diff --git a/doc/interpreter/HTML/doc_002dfactor.html b/doc/interpreter/HTML/doc_002dfactor.html
new file mode 100644
index 0000000..0465909
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfactor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dfactor">
diff --git a/doc/interpreter/HTML/doc_002dfactorial.html b/doc/interpreter/HTML/doc_002dfactorial.html
new file mode 100644
index 0000000..38b6cf0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfactorial.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dfactorial">
diff --git a/doc/interpreter/HTML/doc_002dfail.html b/doc/interpreter/HTML/doc_002dfail.html
new file mode 100644
index 0000000..a17c76e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfail.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Test-Functions.html#doc%2dfail">
diff --git a/doc/interpreter/HTML/doc_002dfalse.html b/doc/interpreter/HTML/doc_002dfalse.html
new file mode 100644
index 0000000..273646f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfalse.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Logical-Values.html#doc%2dfalse">
diff --git a/doc/interpreter/HTML/doc_002dfcdf.html b/doc/interpreter/HTML/doc_002dfcdf.html
new file mode 100644
index 0000000..eabaccf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dfcdf">
diff --git a/doc/interpreter/HTML/doc_002dfclear.html b/doc/interpreter/HTML/doc_002dfclear.html
new file mode 100644
index 0000000..55c2d11
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfclear.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=EOF-and-Errors.html#doc%2dfclear">
diff --git a/doc/interpreter/HTML/doc_002dfclose.html b/doc/interpreter/HTML/doc_002dfclose.html
new file mode 100644
index 0000000..a69d4d0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfclose.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Opening-and-Closing-Files.html#doc%2dfclose">
diff --git a/doc/interpreter/HTML/doc_002dfcntl.html b/doc/interpreter/HTML/doc_002dfcntl.html
new file mode 100644
index 0000000..07cfb06
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfcntl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dfcntl">
diff --git a/doc/interpreter/HTML/doc_002dfdisp.html b/doc/interpreter/HTML/doc_002dfdisp.html
new file mode 100644
index 0000000..c85264d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfdisp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dfdisp">
diff --git a/doc/interpreter/HTML/doc_002dfeather.html b/doc/interpreter/HTML/doc_002dfeather.html
new file mode 100644
index 0000000..a3dd0f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfeather.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dfeather">
diff --git a/doc/interpreter/HTML/doc_002dfeof.html b/doc/interpreter/HTML/doc_002dfeof.html
new file mode 100644
index 0000000..af07baf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfeof.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=EOF-and-Errors.html#doc%2dfeof">
diff --git a/doc/interpreter/HTML/doc_002dferror.html b/doc/interpreter/HTML/doc_002dferror.html
new file mode 100644
index 0000000..529991d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dferror.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=EOF-and-Errors.html#doc%2dferror">
diff --git a/doc/interpreter/HTML/doc_002dfeval.html b/doc/interpreter/HTML/doc_002dfeval.html
new file mode 100644
index 0000000..aed54a3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfeval.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Calling-a-Function-by-its-Name.html#doc%2dfeval">
diff --git a/doc/interpreter/HTML/doc_002dfflush.html b/doc/interpreter/HTML/doc_002dfflush.html
new file mode 100644
index 0000000..96bb1ab
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfflush.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Paging-Screen-Output.html#doc%2dfflush">
diff --git a/doc/interpreter/HTML/doc_002dfft.html b/doc/interpreter/HTML/doc_002dfft.html
new file mode 100644
index 0000000..e24bb15
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfft.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfft">
diff --git a/doc/interpreter/HTML/doc_002dfft2.html b/doc/interpreter/HTML/doc_002dfft2.html
new file mode 100644
index 0000000..88bbf79
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfft2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfft2">
diff --git a/doc/interpreter/HTML/doc_002dfftconv.html b/doc/interpreter/HTML/doc_002dfftconv.html
new file mode 100644
index 0000000..c710776
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfftconv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfftconv">
diff --git a/doc/interpreter/HTML/doc_002dfftfilt.html b/doc/interpreter/HTML/doc_002dfftfilt.html
new file mode 100644
index 0000000..000500d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfftfilt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfftfilt">
diff --git a/doc/interpreter/HTML/doc_002dfftn.html b/doc/interpreter/HTML/doc_002dfftn.html
new file mode 100644
index 0000000..1e0b8e2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfftn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfftn">
diff --git a/doc/interpreter/HTML/doc_002dfftshift.html b/doc/interpreter/HTML/doc_002dfftshift.html
new file mode 100644
index 0000000..4b36429
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfftshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfftshift">
diff --git a/doc/interpreter/HTML/doc_002dfftw.html b/doc/interpreter/HTML/doc_002dfftw.html
new file mode 100644
index 0000000..2e59cae
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfftw.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfftw">
diff --git a/doc/interpreter/HTML/doc_002dfgetl.html b/doc/interpreter/HTML/doc_002dfgetl.html
new file mode 100644
index 0000000..e4182cd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfgetl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Line_002dOriented-Input.html#doc%2dfgetl">
diff --git a/doc/interpreter/HTML/doc_002dfgets.html b/doc/interpreter/HTML/doc_002dfgets.html
new file mode 100644
index 0000000..6199fa8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfgets.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Line_002dOriented-Input.html#doc%2dfgets">
diff --git a/doc/interpreter/HTML/doc_002dfieldnames.html b/doc/interpreter/HTML/doc_002dfieldnames.html
new file mode 100644
index 0000000..1a94d3f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfieldnames.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2dfieldnames">
diff --git a/doc/interpreter/HTML/doc_002dfigure.html b/doc/interpreter/HTML/doc_002dfigure.html
new file mode 100644
index 0000000..2ca1c05
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfigure.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Plot-Windows.html#doc%2dfigure">
diff --git a/doc/interpreter/HTML/doc_002dfile_005fin_005floadpath.html b/doc/interpreter/HTML/doc_002dfile_005fin_005floadpath.html
new file mode 100644
index 0000000..48a42b0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfile_005fin_005floadpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dfile%5fin%5floadpath">
diff --git a/doc/interpreter/HTML/doc_002dfile_005fin_005fpath.html b/doc/interpreter/HTML/doc_002dfile_005fin_005fpath.html
new file mode 100644
index 0000000..07ad09f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfile_005fin_005fpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfile%5fin%5fpath">
diff --git a/doc/interpreter/HTML/doc_002dfileattrib.html b/doc/interpreter/HTML/doc_002dfileattrib.html
new file mode 100644
index 0000000..061a33d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfileattrib.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfileattrib">
diff --git a/doc/interpreter/HTML/doc_002dfilemarker.html b/doc/interpreter/HTML/doc_002dfilemarker.html
new file mode 100644
index 0000000..756bb60
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfilemarker.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfilemarker">
diff --git a/doc/interpreter/HTML/doc_002dfileparts.html b/doc/interpreter/HTML/doc_002dfileparts.html
new file mode 100644
index 0000000..3580fd4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfileparts.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfileparts">
diff --git a/doc/interpreter/HTML/doc_002dfilesep.html b/doc/interpreter/HTML/doc_002dfilesep.html
new file mode 100644
index 0000000..43d4d03
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfilesep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfilesep">
diff --git a/doc/interpreter/HTML/doc_002dfill.html b/doc/interpreter/HTML/doc_002dfill.html
new file mode 100644
index 0000000..13578c2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfill.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dfill">
diff --git a/doc/interpreter/HTML/doc_002dfilter.html b/doc/interpreter/HTML/doc_002dfilter.html
new file mode 100644
index 0000000..d1ad0bb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfilter.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfilter">
diff --git a/doc/interpreter/HTML/doc_002dfilter2.html b/doc/interpreter/HTML/doc_002dfilter2.html
new file mode 100644
index 0000000..6c9b7c7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfilter2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfilter2">
diff --git a/doc/interpreter/HTML/doc_002dfind.html b/doc/interpreter/HTML/doc_002dfind.html
new file mode 100644
index 0000000..271005d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dfind">
diff --git a/doc/interpreter/HTML/doc_002dfind_005fdir_005fin_005fpath.html b/doc/interpreter/HTML/doc_002dfind_005fdir_005fin_005fpath.html
new file mode 100644
index 0000000..8fca005
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfind_005fdir_005fin_005fpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dfind%5fdir%5fin%5fpath">
diff --git a/doc/interpreter/HTML/doc_002dfindall.html b/doc/interpreter/HTML/doc_002dfindall.html
new file mode 100644
index 0000000..8352a45
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfindall.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Searching-Properties.html#doc%2dfindall">
diff --git a/doc/interpreter/HTML/doc_002dfindobj.html b/doc/interpreter/HTML/doc_002dfindobj.html
new file mode 100644
index 0000000..73662ec
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfindobj.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Searching-Properties.html#doc%2dfindobj">
diff --git a/doc/interpreter/HTML/doc_002dfindstr.html b/doc/interpreter/HTML/doc_002dfindstr.html
new file mode 100644
index 0000000..2753fbf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfindstr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dfindstr">
diff --git a/doc/interpreter/HTML/doc_002dfinite.html b/doc/interpreter/HTML/doc_002dfinite.html
new file mode 100644
index 0000000..a5af4cc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfinite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dfinite">
diff --git a/doc/interpreter/HTML/doc_002dfinv.html b/doc/interpreter/HTML/doc_002dfinv.html
new file mode 100644
index 0000000..4071c8e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dfinv">
diff --git a/doc/interpreter/HTML/doc_002dfix.html b/doc/interpreter/HTML/doc_002dfix.html
new file mode 100644
index 0000000..957a5c9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dfix">
diff --git a/doc/interpreter/HTML/doc_002dfixed_005fpoint_005fformat.html b/doc/interpreter/HTML/doc_002dfixed_005fpoint_005fformat.html
new file mode 100644
index 0000000..a7f927e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfixed_005fpoint_005fformat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrices.html#doc%2dfixed%5fpoint%5fformat">
diff --git a/doc/interpreter/HTML/doc_002dflag.html b/doc/interpreter/HTML/doc_002dflag.html
new file mode 100644
index 0000000..caac22d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dflag.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dflag">
diff --git a/doc/interpreter/HTML/doc_002dflipdim.html b/doc/interpreter/HTML/doc_002dflipdim.html
new file mode 100644
index 0000000..dc6f0fb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dflipdim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dflipdim">
diff --git a/doc/interpreter/HTML/doc_002dfliplr.html b/doc/interpreter/HTML/doc_002dfliplr.html
new file mode 100644
index 0000000..9b751ff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfliplr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dfliplr">
diff --git a/doc/interpreter/HTML/doc_002dflipud.html b/doc/interpreter/HTML/doc_002dflipud.html
new file mode 100644
index 0000000..55f1783
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dflipud.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dflipud">
diff --git a/doc/interpreter/HTML/doc_002dfloor.html b/doc/interpreter/HTML/doc_002dfloor.html
new file mode 100644
index 0000000..5f69cda
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfloor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dfloor">
diff --git a/doc/interpreter/HTML/doc_002dfmod.html b/doc/interpreter/HTML/doc_002dfmod.html
new file mode 100644
index 0000000..c6ab6cf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfmod.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dfmod">
diff --git a/doc/interpreter/HTML/doc_002dfnmatch.html b/doc/interpreter/HTML/doc_002dfnmatch.html
new file mode 100644
index 0000000..c2f8474
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfnmatch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfnmatch">
diff --git a/doc/interpreter/HTML/doc_002dfopen.html b/doc/interpreter/HTML/doc_002dfopen.html
new file mode 100644
index 0000000..a3766d2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfopen.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Opening-and-Closing-Files.html#doc%2dfopen">
diff --git a/doc/interpreter/HTML/doc_002dfork.html b/doc/interpreter/HTML/doc_002dfork.html
new file mode 100644
index 0000000..5ca6395
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfork.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dfork">
diff --git a/doc/interpreter/HTML/doc_002dformat.html b/doc/interpreter/HTML/doc_002dformat.html
new file mode 100644
index 0000000..7b8d327
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dformat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Terminal-Output.html#doc%2dformat">
diff --git a/doc/interpreter/HTML/doc_002dformula.html b/doc/interpreter/HTML/doc_002dformula.html
new file mode 100644
index 0000000..d84ad90
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dformula.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Inline-Functions.html#doc%2dformula">
diff --git a/doc/interpreter/HTML/doc_002dfpdf.html b/doc/interpreter/HTML/doc_002dfpdf.html
new file mode 100644
index 0000000..bb72801
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dfpdf">
diff --git a/doc/interpreter/HTML/doc_002dfplot.html b/doc/interpreter/HTML/doc_002dfplot.html
new file mode 100644
index 0000000..37d9303
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002ddimensional-Function-Plotting.html#doc%2dfplot">
diff --git a/doc/interpreter/HTML/doc_002dfprintf.html b/doc/interpreter/HTML/doc_002dfprintf.html
new file mode 100644
index 0000000..f927a66
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfprintf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Formatted-Output.html#doc%2dfprintf">
diff --git a/doc/interpreter/HTML/doc_002dfputs.html b/doc/interpreter/HTML/doc_002dfputs.html
new file mode 100644
index 0000000..c7e0262
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfputs.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-Output.html#doc%2dfputs">
diff --git a/doc/interpreter/HTML/doc_002dfractdiff.html b/doc/interpreter/HTML/doc_002dfractdiff.html
new file mode 100644
index 0000000..1a1e81f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfractdiff.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfractdiff">
diff --git a/doc/interpreter/HTML/doc_002dfread.html b/doc/interpreter/HTML/doc_002dfread.html
new file mode 100644
index 0000000..809f0f6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfread.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Binary-I_002fO.html#doc%2dfread">
diff --git a/doc/interpreter/HTML/doc_002dfreport.html b/doc/interpreter/HTML/doc_002dfreport.html
new file mode 100644
index 0000000..c72264a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfreport.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=EOF-and-Errors.html#doc%2dfreport">
diff --git a/doc/interpreter/HTML/doc_002dfreqz.html b/doc/interpreter/HTML/doc_002dfreqz.html
new file mode 100644
index 0000000..24ccb4b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfreqz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfreqz">
diff --git a/doc/interpreter/HTML/doc_002dfreqz_005fplot.html b/doc/interpreter/HTML/doc_002dfreqz_005fplot.html
new file mode 100644
index 0000000..a3b68b1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfreqz_005fplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dfreqz%5fplot">
diff --git a/doc/interpreter/HTML/doc_002dfrewind.html b/doc/interpreter/HTML/doc_002dfrewind.html
new file mode 100644
index 0000000..95ed4b4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfrewind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Positioning.html#doc%2dfrewind">
diff --git a/doc/interpreter/HTML/doc_002dfrnd.html b/doc/interpreter/HTML/doc_002dfrnd.html
new file mode 100644
index 0000000..e9aabc8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dfrnd">
diff --git a/doc/interpreter/HTML/doc_002dfscanf.html b/doc/interpreter/HTML/doc_002dfscanf.html
new file mode 100644
index 0000000..8bc5347
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfscanf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Formatted-Input.html#doc%2dfscanf">
diff --git a/doc/interpreter/HTML/doc_002dfseek.html b/doc/interpreter/HTML/doc_002dfseek.html
new file mode 100644
index 0000000..1f356cb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfseek.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Positioning.html#doc%2dfseek">
diff --git a/doc/interpreter/HTML/doc_002dfsolve.html b/doc/interpreter/HTML/doc_002dfsolve.html
new file mode 100644
index 0000000..329e30d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfsolve.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Nonlinear-Equations.html#doc%2dfsolve">
diff --git a/doc/interpreter/HTML/doc_002dfstat.html b/doc/interpreter/HTML/doc_002dfstat.html
new file mode 100644
index 0000000..8547720
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfstat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfstat">
diff --git a/doc/interpreter/HTML/doc_002dftell.html b/doc/interpreter/HTML/doc_002dftell.html
new file mode 100644
index 0000000..3c709e9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dftell.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Positioning.html#doc%2dftell">
diff --git a/doc/interpreter/HTML/doc_002dfull.html b/doc/interpreter/HTML/doc_002dfull.html
new file mode 100644
index 0000000..dba7dcc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfull.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dfull">
diff --git a/doc/interpreter/HTML/doc_002dfullfile.html b/doc/interpreter/HTML/doc_002dfullfile.html
new file mode 100644
index 0000000..d29bc5c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfullfile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dfullfile">
diff --git a/doc/interpreter/HTML/doc_002dfunc2str.html b/doc/interpreter/HTML/doc_002dfunc2str.html
new file mode 100644
index 0000000..63da6f9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfunc2str.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Handles.html#doc%2dfunc2str">
diff --git a/doc/interpreter/HTML/doc_002dfunctions.html b/doc/interpreter/HTML/doc_002dfunctions.html
new file mode 100644
index 0000000..bff2689
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfunctions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Handles.html#doc%2dfunctions">
diff --git a/doc/interpreter/HTML/doc_002dfwrite.html b/doc/interpreter/HTML/doc_002dfwrite.html
new file mode 100644
index 0000000..ad70b5e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfwrite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Binary-I_002fO.html#doc%2dfwrite">
diff --git a/doc/interpreter/HTML/doc_002dfzero.html b/doc/interpreter/HTML/doc_002dfzero.html
new file mode 100644
index 0000000..fb0b0ce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dfzero.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Nonlinear-Equations.html#doc%2dfzero">
diff --git a/doc/interpreter/HTML/doc_002dgamcdf.html b/doc/interpreter/HTML/doc_002dgamcdf.html
new file mode 100644
index 0000000..891f718
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgamcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dgamcdf">
diff --git a/doc/interpreter/HTML/doc_002dgaminv.html b/doc/interpreter/HTML/doc_002dgaminv.html
new file mode 100644
index 0000000..090c4d2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgaminv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dgaminv">
diff --git a/doc/interpreter/HTML/doc_002dgamma.html b/doc/interpreter/HTML/doc_002dgamma.html
new file mode 100644
index 0000000..8c2fcab
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgamma.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dgamma">
diff --git a/doc/interpreter/HTML/doc_002dgammainc.html b/doc/interpreter/HTML/doc_002dgammainc.html
new file mode 100644
index 0000000..f7cf586
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgammainc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dgammainc">
diff --git a/doc/interpreter/HTML/doc_002dgammaln.html b/doc/interpreter/HTML/doc_002dgammaln.html
new file mode 100644
index 0000000..6c43121
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgammaln.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dgammaln">
diff --git a/doc/interpreter/HTML/doc_002dgampdf.html b/doc/interpreter/HTML/doc_002dgampdf.html
new file mode 100644
index 0000000..52406a1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgampdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dgampdf">
diff --git a/doc/interpreter/HTML/doc_002dgamrnd.html b/doc/interpreter/HTML/doc_002dgamrnd.html
new file mode 100644
index 0000000..a59ddae
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgamrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dgamrnd">
diff --git a/doc/interpreter/HTML/doc_002dgca.html b/doc/interpreter/HTML/doc_002dgca.html
new file mode 100644
index 0000000..0d04187
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgca.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dgca">
diff --git a/doc/interpreter/HTML/doc_002dgcbf.html b/doc/interpreter/HTML/doc_002dgcbf.html
new file mode 100644
index 0000000..14aaf08
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgcbf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Callbacks.html#doc%2dgcbf">
diff --git a/doc/interpreter/HTML/doc_002dgcbo.html b/doc/interpreter/HTML/doc_002dgcbo.html
new file mode 100644
index 0000000..bd06e1e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgcbo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Callbacks.html#doc%2dgcbo">
diff --git a/doc/interpreter/HTML/doc_002dgcd.html b/doc/interpreter/HTML/doc_002dgcd.html
new file mode 100644
index 0000000..0622809
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgcd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dgcd">
diff --git a/doc/interpreter/HTML/doc_002dgcf.html b/doc/interpreter/HTML/doc_002dgcf.html
new file mode 100644
index 0000000..f086c51
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgcf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dgcf">
diff --git a/doc/interpreter/HTML/doc_002dge.html b/doc/interpreter/HTML/doc_002dge.html
new file mode 100644
index 0000000..51685b1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dge.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dge">
diff --git a/doc/interpreter/HTML/doc_002dgenpath.html b/doc/interpreter/HTML/doc_002dgenpath.html
new file mode 100644
index 0000000..dc900cb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgenpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dgenpath">
diff --git a/doc/interpreter/HTML/doc_002dgenvarname.html b/doc/interpreter/HTML/doc_002dgenvarname.html
new file mode 100644
index 0000000..86125fe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgenvarname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Variables.html#doc%2dgenvarname">
diff --git a/doc/interpreter/HTML/doc_002dgeocdf.html b/doc/interpreter/HTML/doc_002dgeocdf.html
new file mode 100644
index 0000000..5c92675
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgeocdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dgeocdf">
diff --git a/doc/interpreter/HTML/doc_002dgeoinv.html b/doc/interpreter/HTML/doc_002dgeoinv.html
new file mode 100644
index 0000000..1932ff2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgeoinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dgeoinv">
diff --git a/doc/interpreter/HTML/doc_002dgeopdf.html b/doc/interpreter/HTML/doc_002dgeopdf.html
new file mode 100644
index 0000000..84038e5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgeopdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dgeopdf">
diff --git a/doc/interpreter/HTML/doc_002dgeornd.html b/doc/interpreter/HTML/doc_002dgeornd.html
new file mode 100644
index 0000000..19c7fd5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgeornd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dgeornd">
diff --git a/doc/interpreter/HTML/doc_002dget.html b/doc/interpreter/HTML/doc_002dget.html
new file mode 100644
index 0000000..c8aba04
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dget.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dget">
diff --git a/doc/interpreter/HTML/doc_002dgetegid.html b/doc/interpreter/HTML/doc_002dgetegid.html
new file mode 100644
index 0000000..3115a7e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetegid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgetegid">
diff --git a/doc/interpreter/HTML/doc_002dgetenv.html b/doc/interpreter/HTML/doc_002dgetenv.html
new file mode 100644
index 0000000..3cdd81b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetenv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Environment-Variables.html#doc%2dgetenv">
diff --git a/doc/interpreter/HTML/doc_002dgeteuid.html b/doc/interpreter/HTML/doc_002dgeteuid.html
new file mode 100644
index 0000000..5054229
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgeteuid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgeteuid">
diff --git a/doc/interpreter/HTML/doc_002dgetfield.html b/doc/interpreter/HTML/doc_002dgetfield.html
new file mode 100644
index 0000000..3c371e5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetfield.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2dgetfield">
diff --git a/doc/interpreter/HTML/doc_002dgetgid.html b/doc/interpreter/HTML/doc_002dgetgid.html
new file mode 100644
index 0000000..eeb55bf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetgid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgetgid">
diff --git a/doc/interpreter/HTML/doc_002dgetgrent.html b/doc/interpreter/HTML/doc_002dgetgrent.html
new file mode 100644
index 0000000..94ff87d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetgrent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Group-Database-Functions.html#doc%2dgetgrent">
diff --git a/doc/interpreter/HTML/doc_002dgetgrgid.html b/doc/interpreter/HTML/doc_002dgetgrgid.html
new file mode 100644
index 0000000..bd40c05
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetgrgid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Group-Database-Functions.html#doc%2dgetgrgid">
diff --git a/doc/interpreter/HTML/doc_002dgetgrnam.html b/doc/interpreter/HTML/doc_002dgetgrnam.html
new file mode 100644
index 0000000..1b80c61
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetgrnam.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Group-Database-Functions.html#doc%2dgetgrnam">
diff --git a/doc/interpreter/HTML/doc_002dgetpgrp.html b/doc/interpreter/HTML/doc_002dgetpgrp.html
new file mode 100644
index 0000000..3d76c0a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetpgrp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgetpgrp">
diff --git a/doc/interpreter/HTML/doc_002dgetpid.html b/doc/interpreter/HTML/doc_002dgetpid.html
new file mode 100644
index 0000000..cf76ff8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetpid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgetpid">
diff --git a/doc/interpreter/HTML/doc_002dgetppid.html b/doc/interpreter/HTML/doc_002dgetppid.html
new file mode 100644
index 0000000..007107c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetppid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgetppid">
diff --git a/doc/interpreter/HTML/doc_002dgetpwent.html b/doc/interpreter/HTML/doc_002dgetpwent.html
new file mode 100644
index 0000000..04fd423
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetpwent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Password-Database-Functions.html#doc%2dgetpwent">
diff --git a/doc/interpreter/HTML/doc_002dgetpwnam.html b/doc/interpreter/HTML/doc_002dgetpwnam.html
new file mode 100644
index 0000000..e83c97a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetpwnam.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Password-Database-Functions.html#doc%2dgetpwnam">
diff --git a/doc/interpreter/HTML/doc_002dgetpwuid.html b/doc/interpreter/HTML/doc_002dgetpwuid.html
new file mode 100644
index 0000000..f9ab0db
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetpwuid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Password-Database-Functions.html#doc%2dgetpwuid">
diff --git a/doc/interpreter/HTML/doc_002dgetrusage.html b/doc/interpreter/HTML/doc_002dgetrusage.html
new file mode 100644
index 0000000..bca41d7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetrusage.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dgetrusage">
diff --git a/doc/interpreter/HTML/doc_002dgetuid.html b/doc/interpreter/HTML/doc_002dgetuid.html
new file mode 100644
index 0000000..21a199b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgetuid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Process-ID-Information.html#doc%2dgetuid">
diff --git a/doc/interpreter/HTML/doc_002dginput.html b/doc/interpreter/HTML/doc_002dginput.html
new file mode 100644
index 0000000..9af292a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dginput.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interacting-with-plots.html#doc%2dginput">
diff --git a/doc/interpreter/HTML/doc_002dgivens.html b/doc/interpreter/HTML/doc_002dgivens.html
new file mode 100644
index 0000000..5842bac
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgivens.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dgivens">
diff --git a/doc/interpreter/HTML/doc_002dglob.html b/doc/interpreter/HTML/doc_002dglob.html
new file mode 100644
index 0000000..c9eacb9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dglob.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dglob">
diff --git a/doc/interpreter/HTML/doc_002dglpk.html b/doc/interpreter/HTML/doc_002dglpk.html
new file mode 100644
index 0000000..fecc4bf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dglpk.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Linear-Programming.html#doc%2dglpk">
diff --git a/doc/interpreter/HTML/doc_002dgls.html b/doc/interpreter/HTML/doc_002dgls.html
new file mode 100644
index 0000000..baf0dfc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgls.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Linear-Least-Squares.html#doc%2dgls">
diff --git a/doc/interpreter/HTML/doc_002dgmap40.html b/doc/interpreter/HTML/doc_002dgmap40.html
new file mode 100644
index 0000000..09fb7ce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgmap40.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dgmap40">
diff --git a/doc/interpreter/HTML/doc_002dgmtime.html b/doc/interpreter/HTML/doc_002dgmtime.html
new file mode 100644
index 0000000..5c36696
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgmtime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dgmtime">
diff --git a/doc/interpreter/HTML/doc_002dgnuplot_005fbinary.html b/doc/interpreter/HTML/doc_002dgnuplot_005fbinary.html
new file mode 100644
index 0000000..93b9f4f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgnuplot_005fbinary.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interaction-with-gnuplot.html#doc%2dgnuplot%5fbinary">
diff --git a/doc/interpreter/HTML/doc_002dgplot.html b/doc/interpreter/HTML/doc_002dgplot.html
new file mode 100644
index 0000000..1b03485
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dgplot">
diff --git a/doc/interpreter/HTML/doc_002dgradient.html b/doc/interpreter/HTML/doc_002dgradient.html
new file mode 100644
index 0000000..cba139e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgradient.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dgradient">
diff --git a/doc/interpreter/HTML/doc_002dgray.html b/doc/interpreter/HTML/doc_002dgray.html
new file mode 100644
index 0000000..94c9eb0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgray.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dgray">
diff --git a/doc/interpreter/HTML/doc_002dgray2ind.html b/doc/interpreter/HTML/doc_002dgray2ind.html
new file mode 100644
index 0000000..18ecbb5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgray2ind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dgray2ind">
diff --git a/doc/interpreter/HTML/doc_002dgrid.html b/doc/interpreter/HTML/doc_002dgrid.html
new file mode 100644
index 0000000..84d0187
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgrid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dgrid">
diff --git a/doc/interpreter/HTML/doc_002dgriddata.html b/doc/interpreter/HTML/doc_002dgriddata.html
new file mode 100644
index 0000000..415328b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgriddata.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interpolation-on-Scattered-Data.html#doc%2dgriddata">
diff --git a/doc/interpreter/HTML/doc_002dgriddata3.html b/doc/interpreter/HTML/doc_002dgriddata3.html
new file mode 100644
index 0000000..2ddc73d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgriddata3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interpolation-on-Scattered-Data.html#doc%2dgriddata3">
diff --git a/doc/interpreter/HTML/doc_002dgriddatan.html b/doc/interpreter/HTML/doc_002dgriddatan.html
new file mode 100644
index 0000000..eb46d1c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgriddatan.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interpolation-on-Scattered-Data.html#doc%2dgriddatan">
diff --git a/doc/interpreter/HTML/doc_002dgt.html b/doc/interpreter/HTML/doc_002dgt.html
new file mode 100644
index 0000000..65af166
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dgt">
diff --git a/doc/interpreter/HTML/doc_002dgtext.html b/doc/interpreter/HTML/doc_002dgtext.html
new file mode 100644
index 0000000..b0df93c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgtext.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interacting-with-plots.html#doc%2dgtext">
diff --git a/doc/interpreter/HTML/doc_002dgunzip.html b/doc/interpreter/HTML/doc_002dgunzip.html
new file mode 100644
index 0000000..318dbe6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgunzip.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dgunzip">
diff --git a/doc/interpreter/HTML/doc_002dgzip.html b/doc/interpreter/HTML/doc_002dgzip.html
new file mode 100644
index 0000000..e1a771e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dgzip.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dgzip">
diff --git a/doc/interpreter/HTML/doc_002dhadamard.html b/doc/interpreter/HTML/doc_002dhadamard.html
new file mode 100644
index 0000000..999c738
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhadamard.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dhadamard">
diff --git a/doc/interpreter/HTML/doc_002dhamming.html b/doc/interpreter/HTML/doc_002dhamming.html
new file mode 100644
index 0000000..9517bba
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhamming.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dhamming">
diff --git a/doc/interpreter/HTML/doc_002dhankel.html b/doc/interpreter/HTML/doc_002dhankel.html
new file mode 100644
index 0000000..f03fec9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhankel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dhankel">
diff --git a/doc/interpreter/HTML/doc_002dhanning.html b/doc/interpreter/HTML/doc_002dhanning.html
new file mode 100644
index 0000000..0097a43
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhanning.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dhanning">
diff --git a/doc/interpreter/HTML/doc_002dhelp.html b/doc/interpreter/HTML/doc_002dhelp.html
new file mode 100644
index 0000000..87f4674
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhelp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dhelp">
diff --git a/doc/interpreter/HTML/doc_002dhess.html b/doc/interpreter/HTML/doc_002dhess.html
new file mode 100644
index 0000000..95bcd87
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhess.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dhess">
diff --git a/doc/interpreter/HTML/doc_002dhex2dec.html b/doc/interpreter/HTML/doc_002dhex2dec.html
new file mode 100644
index 0000000..6f5d38d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhex2dec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dhex2dec">
diff --git a/doc/interpreter/HTML/doc_002dhex2num.html b/doc/interpreter/HTML/doc_002dhex2num.html
new file mode 100644
index 0000000..bb0dc74
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhex2num.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dhex2num">
diff --git a/doc/interpreter/HTML/doc_002dhggroup.html b/doc/interpreter/HTML/doc_002dhggroup.html
new file mode 100644
index 0000000..cd80c28
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhggroup.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Groups.html#doc%2dhggroup">
diff --git a/doc/interpreter/HTML/doc_002dhidden.html b/doc/interpreter/HTML/doc_002dhidden.html
new file mode 100644
index 0000000..8ed71c0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhidden.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dhidden">
diff --git a/doc/interpreter/HTML/doc_002dhilb.html b/doc/interpreter/HTML/doc_002dhilb.html
new file mode 100644
index 0000000..9bb7622
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhilb.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dhilb">
diff --git a/doc/interpreter/HTML/doc_002dhist.html b/doc/interpreter/HTML/doc_002dhist.html
new file mode 100644
index 0000000..91cc49e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhist.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dhist">
diff --git a/doc/interpreter/HTML/doc_002dhistc.html b/doc/interpreter/HTML/doc_002dhistc.html
new file mode 100644
index 0000000..9066086
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhistc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dhistc">
diff --git a/doc/interpreter/HTML/doc_002dhistory.html b/doc/interpreter/HTML/doc_002dhistory.html
new file mode 100644
index 0000000..4f5ce0d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhistory.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dhistory">
diff --git a/doc/interpreter/HTML/doc_002dhistory_005ffile.html b/doc/interpreter/HTML/doc_002dhistory_005ffile.html
new file mode 100644
index 0000000..922ed17
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhistory_005ffile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dhistory%5ffile">
diff --git a/doc/interpreter/HTML/doc_002dhistory_005fsize.html b/doc/interpreter/HTML/doc_002dhistory_005fsize.html
new file mode 100644
index 0000000..68a59c4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhistory_005fsize.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dhistory%5fsize">
diff --git a/doc/interpreter/HTML/doc_002dhistory_005ftimestamp_005fformat_005fstring.html b/doc/interpreter/HTML/doc_002dhistory_005ftimestamp_005fformat_005fstring.html
new file mode 100644
index 0000000..8aa7cb0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhistory_005ftimestamp_005fformat_005fstring.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dhistory%5ftimestamp%5fformat%5fstring">
diff --git a/doc/interpreter/HTML/doc_002dhold.html b/doc/interpreter/HTML/doc_002dhold.html
new file mode 100644
index 0000000..9d1191a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhold.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dhold">
diff --git a/doc/interpreter/HTML/doc_002dhorzcat.html b/doc/interpreter/HTML/doc_002dhorzcat.html
new file mode 100644
index 0000000..8577c39
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhorzcat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dhorzcat">
diff --git a/doc/interpreter/HTML/doc_002dhot.html b/doc/interpreter/HTML/doc_002dhot.html
new file mode 100644
index 0000000..86894f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dhot">
diff --git a/doc/interpreter/HTML/doc_002dhotelling_005ftest.html b/doc/interpreter/HTML/doc_002dhotelling_005ftest.html
new file mode 100644
index 0000000..fa9ec6b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhotelling_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dhotelling%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dhotelling_005ftest_005f2.html b/doc/interpreter/HTML/doc_002dhotelling_005ftest_005f2.html
new file mode 100644
index 0000000..991ee24
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhotelling_005ftest_005f2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dhotelling%5ftest%5f2">
diff --git a/doc/interpreter/HTML/doc_002dhoush.html b/doc/interpreter/HTML/doc_002dhoush.html
new file mode 100644
index 0000000..783eefa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhoush.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dhoush">
diff --git a/doc/interpreter/HTML/doc_002dhsv.html b/doc/interpreter/HTML/doc_002dhsv.html
new file mode 100644
index 0000000..f06e555
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhsv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dhsv">
diff --git a/doc/interpreter/HTML/doc_002dhsv2rgb.html b/doc/interpreter/HTML/doc_002dhsv2rgb.html
new file mode 100644
index 0000000..1ec71c5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhsv2rgb.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Color-Conversion.html#doc%2dhsv2rgb">
diff --git a/doc/interpreter/HTML/doc_002dhurst.html b/doc/interpreter/HTML/doc_002dhurst.html
new file mode 100644
index 0000000..34b2fa8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhurst.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dhurst">
diff --git a/doc/interpreter/HTML/doc_002dhygecdf.html b/doc/interpreter/HTML/doc_002dhygecdf.html
new file mode 100644
index 0000000..1928696
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhygecdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dhygecdf">
diff --git a/doc/interpreter/HTML/doc_002dhygeinv.html b/doc/interpreter/HTML/doc_002dhygeinv.html
new file mode 100644
index 0000000..f434a45
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhygeinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dhygeinv">
diff --git a/doc/interpreter/HTML/doc_002dhygepdf.html b/doc/interpreter/HTML/doc_002dhygepdf.html
new file mode 100644
index 0000000..76b635f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhygepdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dhygepdf">
diff --git a/doc/interpreter/HTML/doc_002dhygernd.html b/doc/interpreter/HTML/doc_002dhygernd.html
new file mode 100644
index 0000000..67f4d8c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhygernd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dhygernd">
diff --git a/doc/interpreter/HTML/doc_002dhypot.html b/doc/interpreter/HTML/doc_002dhypot.html
new file mode 100644
index 0000000..6730cc9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dhypot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dhypot">
diff --git a/doc/interpreter/HTML/doc_002didivide.html b/doc/interpreter/HTML/doc_002didivide.html
new file mode 100644
index 0000000..cc97223
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002didivide.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Arithmetic.html#doc%2didivide">
diff --git a/doc/interpreter/HTML/doc_002difft.html b/doc/interpreter/HTML/doc_002difft.html
new file mode 100644
index 0000000..393a5e6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002difft.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2difft">
diff --git a/doc/interpreter/HTML/doc_002difft2.html b/doc/interpreter/HTML/doc_002difft2.html
new file mode 100644
index 0000000..e1d901d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002difft2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2difft2">
diff --git a/doc/interpreter/HTML/doc_002difftn.html b/doc/interpreter/HTML/doc_002difftn.html
new file mode 100644
index 0000000..a161ebd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002difftn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2difftn">
diff --git a/doc/interpreter/HTML/doc_002difftshift.html b/doc/interpreter/HTML/doc_002difftshift.html
new file mode 100644
index 0000000..f1e5249
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002difftshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2difftshift">
diff --git a/doc/interpreter/HTML/doc_002dignore_005ffunction_005ftime_005fstamp.html b/doc/interpreter/HTML/doc_002dignore_005ffunction_005ftime_005fstamp.html
new file mode 100644
index 0000000..04ac4d1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dignore_005ffunction_005ftime_005fstamp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Files.html#doc%2dignore%5ffunction%5ftime%5fstamp">
diff --git a/doc/interpreter/HTML/doc_002dimag.html b/doc/interpreter/HTML/doc_002dimag.html
new file mode 100644
index 0000000..c4fd116
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimag.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Complex-Arithmetic.html#doc%2dimag">
diff --git a/doc/interpreter/HTML/doc_002dimage.html b/doc/interpreter/HTML/doc_002dimage.html
new file mode 100644
index 0000000..1be4e3a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimage.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Displaying-Images.html#doc%2dimage">
diff --git a/doc/interpreter/HTML/doc_002dimage_005fviewer.html b/doc/interpreter/HTML/doc_002dimage_005fviewer.html
new file mode 100644
index 0000000..a0fe248
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimage_005fviewer.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Displaying-Images.html#doc%2dimage%5fviewer">
diff --git a/doc/interpreter/HTML/doc_002dimagesc.html b/doc/interpreter/HTML/doc_002dimagesc.html
new file mode 100644
index 0000000..d35fc07
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimagesc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Displaying-Images.html#doc%2dimagesc">
diff --git a/doc/interpreter/HTML/doc_002dimfinfo.html b/doc/interpreter/HTML/doc_002dimfinfo.html
new file mode 100644
index 0000000..0c56350
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimfinfo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Loading-and-Saving-Images.html#doc%2dimfinfo">
diff --git a/doc/interpreter/HTML/doc_002dimread.html b/doc/interpreter/HTML/doc_002dimread.html
new file mode 100644
index 0000000..f346383
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimread.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Loading-and-Saving-Images.html#doc%2dimread">
diff --git a/doc/interpreter/HTML/doc_002dimshow.html b/doc/interpreter/HTML/doc_002dimshow.html
new file mode 100644
index 0000000..e4d50dc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimshow.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Displaying-Images.html#doc%2dimshow">
diff --git a/doc/interpreter/HTML/doc_002dimwrite.html b/doc/interpreter/HTML/doc_002dimwrite.html
new file mode 100644
index 0000000..e712129
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dimwrite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Loading-and-Saving-Images.html#doc%2dimwrite">
diff --git a/doc/interpreter/HTML/doc_002dind2gray.html b/doc/interpreter/HTML/doc_002dind2gray.html
new file mode 100644
index 0000000..3d9ca3d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dind2gray.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dind2gray">
diff --git a/doc/interpreter/HTML/doc_002dind2rgb.html b/doc/interpreter/HTML/doc_002dind2rgb.html
new file mode 100644
index 0000000..d66ab42
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dind2rgb.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dind2rgb">
diff --git a/doc/interpreter/HTML/doc_002dind2sub.html b/doc/interpreter/HTML/doc_002dind2sub.html
new file mode 100644
index 0000000..83365ac
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dind2sub.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Index-Expressions.html#doc%2dind2sub">
diff --git a/doc/interpreter/HTML/doc_002dindex.html b/doc/interpreter/HTML/doc_002dindex.html
new file mode 100644
index 0000000..ef60e72
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dindex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dindex">
diff --git a/doc/interpreter/HTML/doc_002dinferiorto.html b/doc/interpreter/HTML/doc_002dinferiorto.html
new file mode 100644
index 0000000..77ed90f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinferiorto.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Precedence-of-Objects.html#doc%2dinferiorto">
diff --git a/doc/interpreter/HTML/doc_002dinfo.html b/doc/interpreter/HTML/doc_002dinfo.html
new file mode 100644
index 0000000..063ba70
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinfo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dinfo">
diff --git a/doc/interpreter/HTML/doc_002dinfo_005ffile.html b/doc/interpreter/HTML/doc_002dinfo_005ffile.html
new file mode 100644
index 0000000..5607456
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinfo_005ffile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dinfo%5ffile">
diff --git a/doc/interpreter/HTML/doc_002dinfo_005fprogram.html b/doc/interpreter/HTML/doc_002dinfo_005fprogram.html
new file mode 100644
index 0000000..3492443
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinfo_005fprogram.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dinfo%5fprogram">
diff --git a/doc/interpreter/HTML/doc_002dinline.html b/doc/interpreter/HTML/doc_002dinline.html
new file mode 100644
index 0000000..944e03f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinline.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Inline-Functions.html#doc%2dinline">
diff --git a/doc/interpreter/HTML/doc_002dinpolygon.html b/doc/interpreter/HTML/doc_002dinpolygon.html
new file mode 100644
index 0000000..5b430af
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinpolygon.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Voronoi-Diagrams.html#doc%2dinpolygon">
diff --git a/doc/interpreter/HTML/doc_002dinput.html b/doc/interpreter/HTML/doc_002dinput.html
new file mode 100644
index 0000000..25bba16
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinput.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Terminal-Input.html#doc%2dinput">
diff --git a/doc/interpreter/HTML/doc_002dinputname.html b/doc/interpreter/HTML/doc_002dinputname.html
new file mode 100644
index 0000000..d57ebe9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinputname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Defining-Functions.html#doc%2dinputname">
diff --git a/doc/interpreter/HTML/doc_002dint16.html b/doc/interpreter/HTML/doc_002dint16.html
new file mode 100644
index 0000000..771f104
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dint16.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dint16">
diff --git a/doc/interpreter/HTML/doc_002dint2str.html b/doc/interpreter/HTML/doc_002dint2str.html
new file mode 100644
index 0000000..d59879f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dint2str.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Conversion-of-Numerical-Data-to-Strings.html#doc%2dint2str">
diff --git a/doc/interpreter/HTML/doc_002dint32.html b/doc/interpreter/HTML/doc_002dint32.html
new file mode 100644
index 0000000..7b51a70
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dint32.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dint32">
diff --git a/doc/interpreter/HTML/doc_002dint64.html b/doc/interpreter/HTML/doc_002dint64.html
new file mode 100644
index 0000000..a85309a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dint64.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dint64">
diff --git a/doc/interpreter/HTML/doc_002dint8.html b/doc/interpreter/HTML/doc_002dint8.html
new file mode 100644
index 0000000..ef0c451
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dint8.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dint8">
diff --git a/doc/interpreter/HTML/doc_002dinterp1.html b/doc/interpreter/HTML/doc_002dinterp1.html
new file mode 100644
index 0000000..a76de2a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinterp1.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=One_002ddimensional-Interpolation.html#doc%2dinterp1">
diff --git a/doc/interpreter/HTML/doc_002dinterp1q.html b/doc/interpreter/HTML/doc_002dinterp1q.html
new file mode 100644
index 0000000..317b016
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinterp1q.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=One_002ddimensional-Interpolation.html#doc%2dinterp1q">
diff --git a/doc/interpreter/HTML/doc_002dinterp2.html b/doc/interpreter/HTML/doc_002dinterp2.html
new file mode 100644
index 0000000..2e0735a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinterp2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multi_002ddimensional-Interpolation.html#doc%2dinterp2">
diff --git a/doc/interpreter/HTML/doc_002dinterp3.html b/doc/interpreter/HTML/doc_002dinterp3.html
new file mode 100644
index 0000000..a91c410
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinterp3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multi_002ddimensional-Interpolation.html#doc%2dinterp3">
diff --git a/doc/interpreter/HTML/doc_002dinterpft.html b/doc/interpreter/HTML/doc_002dinterpft.html
new file mode 100644
index 0000000..3c09889
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinterpft.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=One_002ddimensional-Interpolation.html#doc%2dinterpft">
diff --git a/doc/interpreter/HTML/doc_002dinterpn.html b/doc/interpreter/HTML/doc_002dinterpn.html
new file mode 100644
index 0000000..e716518
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinterpn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multi_002ddimensional-Interpolation.html#doc%2dinterpn">
diff --git a/doc/interpreter/HTML/doc_002dintersect.html b/doc/interpreter/HTML/doc_002dintersect.html
new file mode 100644
index 0000000..cc4fcc7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dintersect.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Set-Operations.html#doc%2dintersect">
diff --git a/doc/interpreter/HTML/doc_002dintmax.html b/doc/interpreter/HTML/doc_002dintmax.html
new file mode 100644
index 0000000..57be833
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dintmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dintmax">
diff --git a/doc/interpreter/HTML/doc_002dintmin.html b/doc/interpreter/HTML/doc_002dintmin.html
new file mode 100644
index 0000000..5f572c7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dintmin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dintmin">
diff --git a/doc/interpreter/HTML/doc_002dintwarning.html b/doc/interpreter/HTML/doc_002dintwarning.html
new file mode 100644
index 0000000..4b831a6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dintwarning.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2dintwarning">
diff --git a/doc/interpreter/HTML/doc_002dinv.html b/doc/interpreter/HTML/doc_002dinv.html
new file mode 100644
index 0000000..b3f0f94
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dinv">
diff --git a/doc/interpreter/HTML/doc_002dinvhilb.html b/doc/interpreter/HTML/doc_002dinvhilb.html
new file mode 100644
index 0000000..67f4eb1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dinvhilb.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dinvhilb">
diff --git a/doc/interpreter/HTML/doc_002dipermute.html b/doc/interpreter/HTML/doc_002dipermute.html
new file mode 100644
index 0000000..cb9de84
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dipermute.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dipermute">
diff --git a/doc/interpreter/HTML/doc_002diqr.html b/doc/interpreter/HTML/doc_002diqr.html
new file mode 100644
index 0000000..9733715
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002diqr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2diqr">
diff --git a/doc/interpreter/HTML/doc_002dis_005fabsolute_005ffilename.html b/doc/interpreter/HTML/doc_002dis_005fabsolute_005ffilename.html
new file mode 100644
index 0000000..0bd62e5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dis_005fabsolute_005ffilename.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dis%5fabsolute%5ffilename">
diff --git a/doc/interpreter/HTML/doc_002dis_005fduplicate_005fentry.html b/doc/interpreter/HTML/doc_002dis_005fduplicate_005fentry.html
new file mode 100644
index 0000000..9fa1a97
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dis_005fduplicate_005fentry.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dis%5fduplicate%5fentry">
diff --git a/doc/interpreter/HTML/doc_002dis_005fleap_005fyear.html b/doc/interpreter/HTML/doc_002dis_005fleap_005fyear.html
new file mode 100644
index 0000000..40c5742
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dis_005fleap_005fyear.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dis%5fleap%5fyear">
diff --git a/doc/interpreter/HTML/doc_002dis_005frooted_005frelative_005ffilename.html b/doc/interpreter/HTML/doc_002dis_005frooted_005frelative_005ffilename.html
new file mode 100644
index 0000000..fe4dda8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dis_005frooted_005frelative_005ffilename.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dis%5frooted%5frelative%5ffilename">
diff --git a/doc/interpreter/HTML/doc_002disa.html b/doc/interpreter/HTML/doc_002disa.html
new file mode 100644
index 0000000..41ced6b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disa.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Built_002din-Data-Types.html#doc%2disa">
diff --git a/doc/interpreter/HTML/doc_002disalnum.html b/doc/interpreter/HTML/doc_002disalnum.html
new file mode 100644
index 0000000..9f1464e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disalnum.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disalnum">
diff --git a/doc/interpreter/HTML/doc_002disalpha.html b/doc/interpreter/HTML/doc_002disalpha.html
new file mode 100644
index 0000000..47a9c55
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disalpha.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disalpha">
diff --git a/doc/interpreter/HTML/doc_002disascii.html b/doc/interpreter/HTML/doc_002disascii.html
new file mode 100644
index 0000000..2306810
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disascii.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disascii">
diff --git a/doc/interpreter/HTML/doc_002discell.html b/doc/interpreter/HTML/doc_002discell.html
new file mode 100644
index 0000000..8dc6c66
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002discell.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Usage-of-Cell-Arrays.html#doc%2discell">
diff --git a/doc/interpreter/HTML/doc_002discellstr.html b/doc/interpreter/HTML/doc_002discellstr.html
new file mode 100644
index 0000000..3b6b09d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002discellstr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Cell-Arrays-of-Strings.html#doc%2discellstr">
diff --git a/doc/interpreter/HTML/doc_002dischar.html b/doc/interpreter/HTML/doc_002dischar.html
new file mode 100644
index 0000000..b0c641b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dischar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Arrays.html#doc%2dischar">
diff --git a/doc/interpreter/HTML/doc_002discntrl.html b/doc/interpreter/HTML/doc_002discntrl.html
new file mode 100644
index 0000000..96fde57
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002discntrl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2discntrl">
diff --git a/doc/interpreter/HTML/doc_002discommand.html b/doc/interpreter/HTML/doc_002discommand.html
new file mode 100644
index 0000000..0ee33d9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002discommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands.html#doc%2discommand">
diff --git a/doc/interpreter/HTML/doc_002discomplex.html b/doc/interpreter/HTML/doc_002discomplex.html
new file mode 100644
index 0000000..8ab64d8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002discomplex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2discomplex">
diff --git a/doc/interpreter/HTML/doc_002disdebugmode.html b/doc/interpreter/HTML/doc_002disdebugmode.html
new file mode 100644
index 0000000..2715f22
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disdebugmode.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Debug-Mode.html#doc%2disdebugmode">
diff --git a/doc/interpreter/HTML/doc_002disdefinite.html b/doc/interpreter/HTML/doc_002disdefinite.html
new file mode 100644
index 0000000..af32674
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disdefinite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disdefinite">
diff --git a/doc/interpreter/HTML/doc_002disdigit.html b/doc/interpreter/HTML/doc_002disdigit.html
new file mode 100644
index 0000000..c5770c7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disdigit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disdigit">
diff --git a/doc/interpreter/HTML/doc_002disdir.html b/doc/interpreter/HTML/doc_002disdir.html
new file mode 100644
index 0000000..12da002
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disdir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2disdir">
diff --git a/doc/interpreter/HTML/doc_002disempty.html b/doc/interpreter/HTML/doc_002disempty.html
new file mode 100644
index 0000000..93c705a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disempty.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2disempty">
diff --git a/doc/interpreter/HTML/doc_002disequal.html b/doc/interpreter/HTML/doc_002disequal.html
new file mode 100644
index 0000000..c8fea67
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disequal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparison-Ops.html#doc%2disequal">
diff --git a/doc/interpreter/HTML/doc_002disequalwithequalnans.html b/doc/interpreter/HTML/doc_002disequalwithequalnans.html
new file mode 100644
index 0000000..9466b74
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disequalwithequalnans.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparison-Ops.html#doc%2disequalwithequalnans">
diff --git a/doc/interpreter/HTML/doc_002disfield.html b/doc/interpreter/HTML/doc_002disfield.html
new file mode 100644
index 0000000..8830d37
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disfield.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2disfield">
diff --git a/doc/interpreter/HTML/doc_002disfigure.html b/doc/interpreter/HTML/doc_002disfigure.html
new file mode 100644
index 0000000..76d8a36
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disfigure.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2disfigure">
diff --git a/doc/interpreter/HTML/doc_002disfloat.html b/doc/interpreter/HTML/doc_002disfloat.html
new file mode 100644
index 0000000..81f0831
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disfloat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disfloat">
diff --git a/doc/interpreter/HTML/doc_002disglobal.html b/doc/interpreter/HTML/doc_002disglobal.html
new file mode 100644
index 0000000..accb972
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disglobal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Global-Variables.html#doc%2disglobal">
diff --git a/doc/interpreter/HTML/doc_002disgraph.html b/doc/interpreter/HTML/doc_002disgraph.html
new file mode 100644
index 0000000..3c7727c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disgraph.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disgraph">
diff --git a/doc/interpreter/HTML/doc_002dishandle.html b/doc/interpreter/HTML/doc_002dishandle.html
new file mode 100644
index 0000000..855b016
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dishandle.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dishandle">
diff --git a/doc/interpreter/HTML/doc_002dishghandle.html b/doc/interpreter/HTML/doc_002dishghandle.html
new file mode 100644
index 0000000..b3fb414
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dishghandle.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dishghandle">
diff --git a/doc/interpreter/HTML/doc_002dishold.html b/doc/interpreter/HTML/doc_002dishold.html
new file mode 100644
index 0000000..649b552
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dishold.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dishold">
diff --git a/doc/interpreter/HTML/doc_002disieee.html b/doc/interpreter/HTML/doc_002disieee.html
new file mode 100644
index 0000000..35f8394
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disieee.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2disieee">
diff --git a/doc/interpreter/HTML/doc_002disinf.html b/doc/interpreter/HTML/doc_002disinf.html
new file mode 100644
index 0000000..ed87e6e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disinf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2disinf">
diff --git a/doc/interpreter/HTML/doc_002disinteger.html b/doc/interpreter/HTML/doc_002disinteger.html
new file mode 100644
index 0000000..91d685d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disinteger.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2disinteger">
diff --git a/doc/interpreter/HTML/doc_002disletter.html b/doc/interpreter/HTML/doc_002disletter.html
new file mode 100644
index 0000000..b1cd314
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disletter.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disletter">
diff --git a/doc/interpreter/HTML/doc_002dislogical.html b/doc/interpreter/HTML/doc_002dislogical.html
new file mode 100644
index 0000000..9c13633
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dislogical.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2dislogical">
diff --git a/doc/interpreter/HTML/doc_002dislower.html b/doc/interpreter/HTML/doc_002dislower.html
new file mode 100644
index 0000000..1371fe2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dislower.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2dislower">
diff --git a/doc/interpreter/HTML/doc_002dismac.html b/doc/interpreter/HTML/doc_002dismac.html
new file mode 100644
index 0000000..1c37f8c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dismac.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dismac">
diff --git a/doc/interpreter/HTML/doc_002dismatrix.html b/doc/interpreter/HTML/doc_002dismatrix.html
new file mode 100644
index 0000000..b8a52e2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dismatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2dismatrix">
diff --git a/doc/interpreter/HTML/doc_002dismember.html b/doc/interpreter/HTML/doc_002dismember.html
new file mode 100644
index 0000000..00a1188
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dismember.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Set-Operations.html#doc%2dismember">
diff --git a/doc/interpreter/HTML/doc_002dismethod.html b/doc/interpreter/HTML/doc_002dismethod.html
new file mode 100644
index 0000000..c2ab7c7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dismethod.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-a-Class.html#doc%2dismethod">
diff --git a/doc/interpreter/HTML/doc_002disna.html b/doc/interpreter/HTML/doc_002disna.html
new file mode 100644
index 0000000..066e86f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disna.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Missing-Data.html#doc%2disna">
diff --git a/doc/interpreter/HTML/doc_002disnan.html b/doc/interpreter/HTML/doc_002disnan.html
new file mode 100644
index 0000000..d900926
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disnan.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2disnan">
diff --git a/doc/interpreter/HTML/doc_002disnull.html b/doc/interpreter/HTML/doc_002disnull.html
new file mode 100644
index 0000000..52f1b15
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disnull.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2disnull">
diff --git a/doc/interpreter/HTML/doc_002disnumeric.html b/doc/interpreter/HTML/doc_002disnumeric.html
new file mode 100644
index 0000000..7b2f1f9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disnumeric.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disnumeric">
diff --git a/doc/interpreter/HTML/doc_002disobject.html b/doc/interpreter/HTML/doc_002disobject.html
new file mode 100644
index 0000000..a493e0f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disobject.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-a-Class.html#doc%2disobject">
diff --git a/doc/interpreter/HTML/doc_002dispc.html b/doc/interpreter/HTML/doc_002dispc.html
new file mode 100644
index 0000000..ddebf51
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dispc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dispc">
diff --git a/doc/interpreter/HTML/doc_002disprime.html b/doc/interpreter/HTML/doc_002disprime.html
new file mode 100644
index 0000000..6a747ca
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disprime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disprime">
diff --git a/doc/interpreter/HTML/doc_002disprint.html b/doc/interpreter/HTML/doc_002disprint.html
new file mode 100644
index 0000000..9beff17
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disprint.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disprint">
diff --git a/doc/interpreter/HTML/doc_002dispunct.html b/doc/interpreter/HTML/doc_002dispunct.html
new file mode 100644
index 0000000..e8066bc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dispunct.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2dispunct">
diff --git a/doc/interpreter/HTML/doc_002disrawcommand.html b/doc/interpreter/HTML/doc_002disrawcommand.html
new file mode 100644
index 0000000..4b8f87e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disrawcommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands.html#doc%2disrawcommand">
diff --git a/doc/interpreter/HTML/doc_002disreal.html b/doc/interpreter/HTML/doc_002disreal.html
new file mode 100644
index 0000000..7469f65
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disreal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disreal">
diff --git a/doc/interpreter/HTML/doc_002disscalar.html b/doc/interpreter/HTML/doc_002disscalar.html
new file mode 100644
index 0000000..8ea322d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disscalar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disscalar">
diff --git a/doc/interpreter/HTML/doc_002dissorted.html b/doc/interpreter/HTML/doc_002dissorted.html
new file mode 100644
index 0000000..747fcb6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dissorted.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dissorted">
diff --git a/doc/interpreter/HTML/doc_002disspace.html b/doc/interpreter/HTML/doc_002disspace.html
new file mode 100644
index 0000000..9d34a25
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disspace.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disspace">
diff --git a/doc/interpreter/HTML/doc_002dissparse.html b/doc/interpreter/HTML/doc_002dissparse.html
new file mode 100644
index 0000000..3a6b272
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dissparse.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dissparse">
diff --git a/doc/interpreter/HTML/doc_002dissquare.html b/doc/interpreter/HTML/doc_002dissquare.html
new file mode 100644
index 0000000..7f59cf1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dissquare.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2dissquare">
diff --git a/doc/interpreter/HTML/doc_002disstrprop.html b/doc/interpreter/HTML/doc_002disstrprop.html
new file mode 100644
index 0000000..ad7e1f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disstrprop.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disstrprop">
diff --git a/doc/interpreter/HTML/doc_002disstruct.html b/doc/interpreter/HTML/doc_002disstruct.html
new file mode 100644
index 0000000..658875a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disstruct.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Structures.html#doc%2disstruct">
diff --git a/doc/interpreter/HTML/doc_002dissymmetric.html b/doc/interpreter/HTML/doc_002dissymmetric.html
new file mode 100644
index 0000000..189d9bf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dissymmetric.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2dissymmetric">
diff --git a/doc/interpreter/HTML/doc_002disunix.html b/doc/interpreter/HTML/doc_002disunix.html
new file mode 100644
index 0000000..f5c3a31
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disunix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2disunix">
diff --git a/doc/interpreter/HTML/doc_002disupper.html b/doc/interpreter/HTML/doc_002disupper.html
new file mode 100644
index 0000000..8b8d620
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disupper.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disupper">
diff --git a/doc/interpreter/HTML/doc_002disvarname.html b/doc/interpreter/HTML/doc_002disvarname.html
new file mode 100644
index 0000000..e087a2e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disvarname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Variables.html#doc%2disvarname">
diff --git a/doc/interpreter/HTML/doc_002disvector.html b/doc/interpreter/HTML/doc_002disvector.html
new file mode 100644
index 0000000..767a96e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disvector.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Predicates-for-Numeric-Objects.html#doc%2disvector">
diff --git a/doc/interpreter/HTML/doc_002disxdigit.html b/doc/interpreter/HTML/doc_002disxdigit.html
new file mode 100644
index 0000000..bb65651
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002disxdigit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Class-Functions.html#doc%2disxdigit">
diff --git a/doc/interpreter/HTML/doc_002djet.html b/doc/interpreter/HTML/doc_002djet.html
new file mode 100644
index 0000000..f1f6073
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002djet.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2djet">
diff --git a/doc/interpreter/HTML/doc_002dkbhit.html b/doc/interpreter/HTML/doc_002dkbhit.html
new file mode 100644
index 0000000..02d9485
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkbhit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Terminal-Input.html#doc%2dkbhit">
diff --git a/doc/interpreter/HTML/doc_002dkendall.html b/doc/interpreter/HTML/doc_002dkendall.html
new file mode 100644
index 0000000..f55db90
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkendall.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dkendall">
diff --git a/doc/interpreter/HTML/doc_002dkeyboard.html b/doc/interpreter/HTML/doc_002dkeyboard.html
new file mode 100644
index 0000000..03cffa8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkeyboard.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Breakpoints.html#doc%2dkeyboard">
diff --git a/doc/interpreter/HTML/doc_002dkill.html b/doc/interpreter/HTML/doc_002dkill.html
new file mode 100644
index 0000000..09b0c92
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkill.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dkill">
diff --git a/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005fcdf.html b/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005fcdf.html
new file mode 100644
index 0000000..5af691f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005fcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dkolmogorov%5fsmirnov%5fcdf">
diff --git a/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005ftest.html b/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005ftest.html
new file mode 100644
index 0000000..a6ea90c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dkolmogorov%5fsmirnov%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005ftest_005f2.html b/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005ftest_005f2.html
new file mode 100644
index 0000000..3c80dd6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkolmogorov_005fsmirnov_005ftest_005f2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dkolmogorov%5fsmirnov%5ftest%5f2">
diff --git a/doc/interpreter/HTML/doc_002dkron.html b/doc/interpreter/HTML/doc_002dkron.html
new file mode 100644
index 0000000..f714a83
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkron.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-a-Matrix.html#doc%2dkron">
diff --git a/doc/interpreter/HTML/doc_002dkruskal_005fwallis_005ftest.html b/doc/interpreter/HTML/doc_002dkruskal_005fwallis_005ftest.html
new file mode 100644
index 0000000..ffe499d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkruskal_005fwallis_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dkruskal%5fwallis%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dkrylov.html b/doc/interpreter/HTML/doc_002dkrylov.html
new file mode 100644
index 0000000..76d055a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkrylov.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dkrylov">
diff --git a/doc/interpreter/HTML/doc_002dkurtosis.html b/doc/interpreter/HTML/doc_002dkurtosis.html
new file mode 100644
index 0000000..3b12af9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dkurtosis.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dkurtosis">
diff --git a/doc/interpreter/HTML/doc_002dlaplace_005fcdf.html b/doc/interpreter/HTML/doc_002dlaplace_005fcdf.html
new file mode 100644
index 0000000..ef75234
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlaplace_005fcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlaplace%5fcdf">
diff --git a/doc/interpreter/HTML/doc_002dlaplace_005finv.html b/doc/interpreter/HTML/doc_002dlaplace_005finv.html
new file mode 100644
index 0000000..3968162
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlaplace_005finv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlaplace%5finv">
diff --git a/doc/interpreter/HTML/doc_002dlaplace_005fpdf.html b/doc/interpreter/HTML/doc_002dlaplace_005fpdf.html
new file mode 100644
index 0000000..a88cbd1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlaplace_005fpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlaplace%5fpdf">
diff --git a/doc/interpreter/HTML/doc_002dlaplace_005frnd.html b/doc/interpreter/HTML/doc_002dlaplace_005frnd.html
new file mode 100644
index 0000000..af23b6d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlaplace_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dlaplace%5frnd">
diff --git a/doc/interpreter/HTML/doc_002dlasterr.html b/doc/interpreter/HTML/doc_002dlasterr.html
new file mode 100644
index 0000000..c9e5a8a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlasterr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Catching-Errors.html#doc%2dlasterr">
diff --git a/doc/interpreter/HTML/doc_002dlasterror.html b/doc/interpreter/HTML/doc_002dlasterror.html
new file mode 100644
index 0000000..b9d8b13
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlasterror.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Catching-Errors.html#doc%2dlasterror">
diff --git a/doc/interpreter/HTML/doc_002dlastwarn.html b/doc/interpreter/HTML/doc_002dlastwarn.html
new file mode 100644
index 0000000..a1a6ddb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlastwarn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Issuing-Warnings.html#doc%2dlastwarn">
diff --git a/doc/interpreter/HTML/doc_002dlcm.html b/doc/interpreter/HTML/doc_002dlcm.html
new file mode 100644
index 0000000..89f5659
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlcm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dlcm">
diff --git a/doc/interpreter/HTML/doc_002dldivide.html b/doc/interpreter/HTML/doc_002dldivide.html
new file mode 100644
index 0000000..4bb2362
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dldivide.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dldivide">
diff --git a/doc/interpreter/HTML/doc_002dle.html b/doc/interpreter/HTML/doc_002dle.html
new file mode 100644
index 0000000..398f051
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dle.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dle">
diff --git a/doc/interpreter/HTML/doc_002dlegend.html b/doc/interpreter/HTML/doc_002dlegend.html
new file mode 100644
index 0000000..8fa01df
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlegend.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dlegend">
diff --git a/doc/interpreter/HTML/doc_002dlegendre.html b/doc/interpreter/HTML/doc_002dlegendre.html
new file mode 100644
index 0000000..3554476
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlegendre.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dlegendre">
diff --git a/doc/interpreter/HTML/doc_002dlength.html b/doc/interpreter/HTML/doc_002dlength.html
new file mode 100644
index 0000000..5f63c41
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlength.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dlength">
diff --git a/doc/interpreter/HTML/doc_002dlgamma.html b/doc/interpreter/HTML/doc_002dlgamma.html
new file mode 100644
index 0000000..54466db
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlgamma.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Functions.html#doc%2dlgamma">
diff --git a/doc/interpreter/HTML/doc_002dlicense.html b/doc/interpreter/HTML/doc_002dlicense.html
new file mode 100644
index 0000000..d1a4ae6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlicense.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dlicense">
diff --git a/doc/interpreter/HTML/doc_002dlin2mu.html b/doc/interpreter/HTML/doc_002dlin2mu.html
new file mode 100644
index 0000000..96a327f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlin2mu.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dlin2mu">
diff --git a/doc/interpreter/HTML/doc_002dline.html b/doc/interpreter/HTML/doc_002dline.html
new file mode 100644
index 0000000..2b90630
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dline.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dline">
diff --git a/doc/interpreter/HTML/doc_002dlink.html b/doc/interpreter/HTML/doc_002dlink.html
new file mode 100644
index 0000000..f37a9b7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlink.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dlink">
diff --git a/doc/interpreter/HTML/doc_002dlinkdata.html b/doc/interpreter/HTML/doc_002dlinkdata.html
new file mode 100644
index 0000000..1d67edd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlinkdata.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Data-sources-in-object-groups.html#doc%2dlinkdata">
diff --git a/doc/interpreter/HTML/doc_002dlinkprop.html b/doc/interpreter/HTML/doc_002dlinkprop.html
new file mode 100644
index 0000000..4038e09
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlinkprop.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Groups.html#doc%2dlinkprop">
diff --git a/doc/interpreter/HTML/doc_002dlinspace.html b/doc/interpreter/HTML/doc_002dlinspace.html
new file mode 100644
index 0000000..6517aed
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlinspace.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2dlinspace">
diff --git a/doc/interpreter/HTML/doc_002dlist_005fprimes.html b/doc/interpreter/HTML/doc_002dlist_005fprimes.html
new file mode 100644
index 0000000..0a1da82
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlist_005fprimes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dlist%5fprimes">
diff --git a/doc/interpreter/HTML/doc_002dload.html b/doc/interpreter/HTML/doc_002dload.html
new file mode 100644
index 0000000..9b6347c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dload.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dload">
diff --git a/doc/interpreter/HTML/doc_002dloadaudio.html b/doc/interpreter/HTML/doc_002dloadaudio.html
new file mode 100644
index 0000000..7dc4422
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dloadaudio.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dloadaudio">
diff --git a/doc/interpreter/HTML/doc_002dloadobj.html b/doc/interpreter/HTML/doc_002dloadobj.html
new file mode 100644
index 0000000..fa4e040
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dloadobj.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Classes.html#doc%2dloadobj">
diff --git a/doc/interpreter/HTML/doc_002dlocaltime.html b/doc/interpreter/HTML/doc_002dlocaltime.html
new file mode 100644
index 0000000..e47eda0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlocaltime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dlocaltime">
diff --git a/doc/interpreter/HTML/doc_002dlog.html b/doc/interpreter/HTML/doc_002dlog.html
new file mode 100644
index 0000000..47fe25e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlog.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dlog">
diff --git a/doc/interpreter/HTML/doc_002dlog10.html b/doc/interpreter/HTML/doc_002dlog10.html
new file mode 100644
index 0000000..7721f7d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlog10.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dlog10">
diff --git a/doc/interpreter/HTML/doc_002dlog1p.html b/doc/interpreter/HTML/doc_002dlog1p.html
new file mode 100644
index 0000000..074d714
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlog1p.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dlog1p">
diff --git a/doc/interpreter/HTML/doc_002dlog2.html b/doc/interpreter/HTML/doc_002dlog2.html
new file mode 100644
index 0000000..e402256
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlog2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dlog2">
diff --git a/doc/interpreter/HTML/doc_002dlogical.html b/doc/interpreter/HTML/doc_002dlogical.html
new file mode 100644
index 0000000..d925533
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogical.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Logical-Values.html#doc%2dlogical">
diff --git a/doc/interpreter/HTML/doc_002dlogistic_005fcdf.html b/doc/interpreter/HTML/doc_002dlogistic_005fcdf.html
new file mode 100644
index 0000000..91d7e68
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogistic_005fcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlogistic%5fcdf">
diff --git a/doc/interpreter/HTML/doc_002dlogistic_005finv.html b/doc/interpreter/HTML/doc_002dlogistic_005finv.html
new file mode 100644
index 0000000..95aca83
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogistic_005finv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlogistic%5finv">
diff --git a/doc/interpreter/HTML/doc_002dlogistic_005fpdf.html b/doc/interpreter/HTML/doc_002dlogistic_005fpdf.html
new file mode 100644
index 0000000..6e90c9a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogistic_005fpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlogistic%5fpdf">
diff --git a/doc/interpreter/HTML/doc_002dlogistic_005fregression.html b/doc/interpreter/HTML/doc_002dlogistic_005fregression.html
new file mode 100644
index 0000000..f924f11
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogistic_005fregression.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Models.html#doc%2dlogistic%5fregression">
diff --git a/doc/interpreter/HTML/doc_002dlogistic_005frnd.html b/doc/interpreter/HTML/doc_002dlogistic_005frnd.html
new file mode 100644
index 0000000..4adce43
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogistic_005frnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dlogistic%5frnd">
diff --git a/doc/interpreter/HTML/doc_002dlogit.html b/doc/interpreter/HTML/doc_002dlogit.html
new file mode 100644
index 0000000..2943755
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dlogit">
diff --git a/doc/interpreter/HTML/doc_002dloglog.html b/doc/interpreter/HTML/doc_002dloglog.html
new file mode 100644
index 0000000..f725509
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dloglog.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dloglog">
diff --git a/doc/interpreter/HTML/doc_002dloglogerr.html b/doc/interpreter/HTML/doc_002dloglogerr.html
new file mode 100644
index 0000000..8ba10f7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dloglogerr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dloglogerr">
diff --git a/doc/interpreter/HTML/doc_002dlogm.html b/doc/interpreter/HTML/doc_002dlogm.html
new file mode 100644
index 0000000..4947121
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-a-Matrix.html#doc%2dlogm">
diff --git a/doc/interpreter/HTML/doc_002dlogncdf.html b/doc/interpreter/HTML/doc_002dlogncdf.html
new file mode 100644
index 0000000..2b4d60c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogncdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlogncdf">
diff --git a/doc/interpreter/HTML/doc_002dlogninv.html b/doc/interpreter/HTML/doc_002dlogninv.html
new file mode 100644
index 0000000..86ed8b3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogninv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlogninv">
diff --git a/doc/interpreter/HTML/doc_002dlognpdf.html b/doc/interpreter/HTML/doc_002dlognpdf.html
new file mode 100644
index 0000000..bade2eb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlognpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dlognpdf">
diff --git a/doc/interpreter/HTML/doc_002dlognrnd.html b/doc/interpreter/HTML/doc_002dlognrnd.html
new file mode 100644
index 0000000..cfd76ec
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlognrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dlognrnd">
diff --git a/doc/interpreter/HTML/doc_002dlogspace.html b/doc/interpreter/HTML/doc_002dlogspace.html
new file mode 100644
index 0000000..72c0688
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlogspace.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2dlogspace">
diff --git a/doc/interpreter/HTML/doc_002dlookfor.html b/doc/interpreter/HTML/doc_002dlookfor.html
new file mode 100644
index 0000000..425366c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlookfor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dlookfor">
diff --git a/doc/interpreter/HTML/doc_002dlookup.html b/doc/interpreter/HTML/doc_002dlookup.html
new file mode 100644
index 0000000..8afce2f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlookup.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=One_002ddimensional-Interpolation.html#doc%2dlookup">
diff --git a/doc/interpreter/HTML/doc_002dls.html b/doc/interpreter/HTML/doc_002dls.html
new file mode 100644
index 0000000..53d5c43
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dls.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Current-Working-Directory.html#doc%2dls">
diff --git a/doc/interpreter/HTML/doc_002dls_005fcommand.html b/doc/interpreter/HTML/doc_002dls_005fcommand.html
new file mode 100644
index 0000000..9c15153
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dls_005fcommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Current-Working-Directory.html#doc%2dls%5fcommand">
diff --git a/doc/interpreter/HTML/doc_002dlsode.html b/doc/interpreter/HTML/doc_002dlsode.html
new file mode 100644
index 0000000..dff1693
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlsode.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Ordinary-Differential-Equations.html#doc%2dlsode">
diff --git a/doc/interpreter/HTML/doc_002dlsode_005foptions.html b/doc/interpreter/HTML/doc_002dlsode_005foptions.html
new file mode 100644
index 0000000..47c1565
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlsode_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Ordinary-Differential-Equations.html#doc%2dlsode%5foptions">
diff --git a/doc/interpreter/HTML/doc_002dlsqnonneg.html b/doc/interpreter/HTML/doc_002dlsqnonneg.html
new file mode 100644
index 0000000..32c6e3d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlsqnonneg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Linear-Least-Squares.html#doc%2dlsqnonneg">
diff --git a/doc/interpreter/HTML/doc_002dlstat.html b/doc/interpreter/HTML/doc_002dlstat.html
new file mode 100644
index 0000000..2b47840
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlstat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dlstat">
diff --git a/doc/interpreter/HTML/doc_002dlt.html b/doc/interpreter/HTML/doc_002dlt.html
new file mode 100644
index 0000000..9dbdb37
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dlt">
diff --git a/doc/interpreter/HTML/doc_002dlu.html b/doc/interpreter/HTML/doc_002dlu.html
new file mode 100644
index 0000000..0234b51
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dlu.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dlu">
diff --git a/doc/interpreter/HTML/doc_002dluinc.html b/doc/interpreter/HTML/doc_002dluinc.html
new file mode 100644
index 0000000..bd76e06
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dluinc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Iterative-Techniques.html#doc%2dluinc">
diff --git a/doc/interpreter/HTML/doc_002dmagic.html b/doc/interpreter/HTML/doc_002dmagic.html
new file mode 100644
index 0000000..6c9519a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmagic.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dmagic">
diff --git a/doc/interpreter/HTML/doc_002dmahalanobis.html b/doc/interpreter/HTML/doc_002dmahalanobis.html
new file mode 100644
index 0000000..0a4d8ca
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmahalanobis.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dmahalanobis">
diff --git a/doc/interpreter/HTML/doc_002dmake_005fabsolute_005ffilename.html b/doc/interpreter/HTML/doc_002dmake_005fabsolute_005ffilename.html
new file mode 100644
index 0000000..dff15d2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmake_005fabsolute_005ffilename.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dmake%5fabsolute%5ffilename">
diff --git a/doc/interpreter/HTML/doc_002dmakeinfo_005fprogram.html b/doc/interpreter/HTML/doc_002dmakeinfo_005fprogram.html
new file mode 100644
index 0000000..49e1cfd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmakeinfo_005fprogram.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dmakeinfo%5fprogram">
diff --git a/doc/interpreter/HTML/doc_002dmanova.html b/doc/interpreter/HTML/doc_002dmanova.html
new file mode 100644
index 0000000..a35ee30
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmanova.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dmanova">
diff --git a/doc/interpreter/HTML/doc_002dmark_005fas_005fcommand.html b/doc/interpreter/HTML/doc_002dmark_005fas_005fcommand.html
new file mode 100644
index 0000000..281c75b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmark_005fas_005fcommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands.html#doc%2dmark%5fas%5fcommand">
diff --git a/doc/interpreter/HTML/doc_002dmark_005fas_005frawcommand.html b/doc/interpreter/HTML/doc_002dmark_005fas_005frawcommand.html
new file mode 100644
index 0000000..b8efea3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmark_005fas_005frawcommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands.html#doc%2dmark%5fas%5frawcommand">
diff --git a/doc/interpreter/HTML/doc_002dmat2cell.html b/doc/interpreter/HTML/doc_002dmat2cell.html
new file mode 100644
index 0000000..bf61748
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmat2cell.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Cell-Arrays.html#doc%2dmat2cell">
diff --git a/doc/interpreter/HTML/doc_002dmat2str.html b/doc/interpreter/HTML/doc_002dmat2str.html
new file mode 100644
index 0000000..4a01afa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmat2str.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Conversion-of-Numerical-Data-to-Strings.html#doc%2dmat2str">
diff --git a/doc/interpreter/HTML/doc_002dmatrix_005ftype.html b/doc/interpreter/HTML/doc_002dmatrix_005ftype.html
new file mode 100644
index 0000000..7257786
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmatrix_005ftype.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dmatrix%5ftype">
diff --git a/doc/interpreter/HTML/doc_002dmax.html b/doc/interpreter/HTML/doc_002dmax.html
new file mode 100644
index 0000000..bac7d9b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dmax">
diff --git a/doc/interpreter/HTML/doc_002dmax_005frecursion_005fdepth.html b/doc/interpreter/HTML/doc_002dmax_005frecursion_005fdepth.html
new file mode 100644
index 0000000..22ebae7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmax_005frecursion_005fdepth.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Recursion.html#doc%2dmax%5frecursion%5fdepth">
diff --git a/doc/interpreter/HTML/doc_002dmcnemar_005ftest.html b/doc/interpreter/HTML/doc_002dmcnemar_005ftest.html
new file mode 100644
index 0000000..6ea2a40
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmcnemar_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dmcnemar%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dmd5sum.html b/doc/interpreter/HTML/doc_002dmd5sum.html
new file mode 100644
index 0000000..3b927a6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmd5sum.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Hashing-Functions.html#doc%2dmd5sum">
diff --git a/doc/interpreter/HTML/doc_002dmean.html b/doc/interpreter/HTML/doc_002dmean.html
new file mode 100644
index 0000000..f950bb8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmean.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dmean">
diff --git a/doc/interpreter/HTML/doc_002dmeansq.html b/doc/interpreter/HTML/doc_002dmeansq.html
new file mode 100644
index 0000000..abbe9fb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmeansq.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dmeansq">
diff --git a/doc/interpreter/HTML/doc_002dmedian.html b/doc/interpreter/HTML/doc_002dmedian.html
new file mode 100644
index 0000000..6e17f95
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmedian.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dmedian">
diff --git a/doc/interpreter/HTML/doc_002dmenu.html b/doc/interpreter/HTML/doc_002dmenu.html
new file mode 100644
index 0000000..c31228f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmenu.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Terminal-Input.html#doc%2dmenu">
diff --git a/doc/interpreter/HTML/doc_002dmesh.html b/doc/interpreter/HTML/doc_002dmesh.html
new file mode 100644
index 0000000..f008629
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmesh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dmesh">
diff --git a/doc/interpreter/HTML/doc_002dmeshc.html b/doc/interpreter/HTML/doc_002dmeshc.html
new file mode 100644
index 0000000..3e795a3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmeshc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dmeshc">
diff --git a/doc/interpreter/HTML/doc_002dmeshgrid.html b/doc/interpreter/HTML/doc_002dmeshgrid.html
new file mode 100644
index 0000000..a7adf55
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmeshgrid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dmeshgrid">
diff --git a/doc/interpreter/HTML/doc_002dmeshz.html b/doc/interpreter/HTML/doc_002dmeshz.html
new file mode 100644
index 0000000..61575a5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmeshz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dmeshz">
diff --git a/doc/interpreter/HTML/doc_002dmethods.html b/doc/interpreter/HTML/doc_002dmethods.html
new file mode 100644
index 0000000..ddca0e8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmethods.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-a-Class.html#doc%2dmethods">
diff --git a/doc/interpreter/HTML/doc_002dmex.html b/doc/interpreter/HTML/doc_002dmex.html
new file mode 100644
index 0000000..3acb147
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Started-with-Mex_002dFiles.html#doc%2dmex">
diff --git a/doc/interpreter/HTML/doc_002dmexext.html b/doc/interpreter/HTML/doc_002dmexext.html
new file mode 100644
index 0000000..722851a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmexext.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Started-with-Mex_002dFiles.html#doc%2dmexext">
diff --git a/doc/interpreter/HTML/doc_002dmfilename.html b/doc/interpreter/HTML/doc_002dmfilename.html
new file mode 100644
index 0000000..b93887e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmfilename.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Files.html#doc%2dmfilename">
diff --git a/doc/interpreter/HTML/doc_002dmin.html b/doc/interpreter/HTML/doc_002dmin.html
new file mode 100644
index 0000000..85e57d1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dmin">
diff --git a/doc/interpreter/HTML/doc_002dminus.html b/doc/interpreter/HTML/doc_002dminus.html
new file mode 100644
index 0000000..3795f32
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dminus.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dminus">
diff --git a/doc/interpreter/HTML/doc_002dmislocked.html b/doc/interpreter/HTML/doc_002dmislocked.html
new file mode 100644
index 0000000..6c88a67
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmislocked.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Locking.html#doc%2dmislocked">
diff --git a/doc/interpreter/HTML/doc_002dmkdir.html b/doc/interpreter/HTML/doc_002dmkdir.html
new file mode 100644
index 0000000..8efc2fd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmkdir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dmkdir">
diff --git a/doc/interpreter/HTML/doc_002dmkfifo.html b/doc/interpreter/HTML/doc_002dmkfifo.html
new file mode 100644
index 0000000..92223d0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmkfifo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dmkfifo">
diff --git a/doc/interpreter/HTML/doc_002dmkoctfile.html b/doc/interpreter/HTML/doc_002dmkoctfile.html
new file mode 100644
index 0000000..c545ff3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmkoctfile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Started-with-Oct_002dFiles.html#doc%2dmkoctfile">
diff --git a/doc/interpreter/HTML/doc_002dmkpp.html b/doc/interpreter/HTML/doc_002dmkpp.html
new file mode 100644
index 0000000..0b09f74
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmkpp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Polynomial-Interpolation.html#doc%2dmkpp">
diff --git a/doc/interpreter/HTML/doc_002dmkstemp.html b/doc/interpreter/HTML/doc_002dmkstemp.html
new file mode 100644
index 0000000..8c56c92
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmkstemp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Temporary-Files.html#doc%2dmkstemp">
diff --git a/doc/interpreter/HTML/doc_002dmktime.html b/doc/interpreter/HTML/doc_002dmktime.html
new file mode 100644
index 0000000..8376795
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmktime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dmktime">
diff --git a/doc/interpreter/HTML/doc_002dmldivide.html b/doc/interpreter/HTML/doc_002dmldivide.html
new file mode 100644
index 0000000..c1591a8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmldivide.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dmldivide">
diff --git a/doc/interpreter/HTML/doc_002dmlock.html b/doc/interpreter/HTML/doc_002dmlock.html
new file mode 100644
index 0000000..dfd175d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmlock.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Locking.html#doc%2dmlock">
diff --git a/doc/interpreter/HTML/doc_002dmod.html b/doc/interpreter/HTML/doc_002dmod.html
new file mode 100644
index 0000000..46e64b7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmod.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dmod">
diff --git a/doc/interpreter/HTML/doc_002dmode.html b/doc/interpreter/HTML/doc_002dmode.html
new file mode 100644
index 0000000..e68cd37
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmode.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dmode">
diff --git a/doc/interpreter/HTML/doc_002dmoment.html b/doc/interpreter/HTML/doc_002dmoment.html
new file mode 100644
index 0000000..8c26823
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmoment.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dmoment">
diff --git a/doc/interpreter/HTML/doc_002dmore.html b/doc/interpreter/HTML/doc_002dmore.html
new file mode 100644
index 0000000..687a2af
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmore.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Paging-Screen-Output.html#doc%2dmore">
diff --git a/doc/interpreter/HTML/doc_002dmovefile.html b/doc/interpreter/HTML/doc_002dmovefile.html
new file mode 100644
index 0000000..877ba1b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmovefile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dmovefile">
diff --git a/doc/interpreter/HTML/doc_002dmpoles.html b/doc/interpreter/HTML/doc_002dmpoles.html
new file mode 100644
index 0000000..9cee5cc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmpoles.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Roots.html#doc%2dmpoles">
diff --git a/doc/interpreter/HTML/doc_002dmpower.html b/doc/interpreter/HTML/doc_002dmpower.html
new file mode 100644
index 0000000..fb765ed
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmpower.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dmpower">
diff --git a/doc/interpreter/HTML/doc_002dmrdivide.html b/doc/interpreter/HTML/doc_002dmrdivide.html
new file mode 100644
index 0000000..2e481f1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmrdivide.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dmrdivide">
diff --git a/doc/interpreter/HTML/doc_002dmtimes.html b/doc/interpreter/HTML/doc_002dmtimes.html
new file mode 100644
index 0000000..043d10d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmtimes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dmtimes">
diff --git a/doc/interpreter/HTML/doc_002dmu2lin.html b/doc/interpreter/HTML/doc_002dmu2lin.html
new file mode 100644
index 0000000..1342146
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmu2lin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dmu2lin">
diff --git a/doc/interpreter/HTML/doc_002dmunlock.html b/doc/interpreter/HTML/doc_002dmunlock.html
new file mode 100644
index 0000000..85e1e81
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dmunlock.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Locking.html#doc%2dmunlock">
diff --git a/doc/interpreter/HTML/doc_002dnamelengthmax.html b/doc/interpreter/HTML/doc_002dnamelengthmax.html
new file mode 100644
index 0000000..4116a57
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnamelengthmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Variables.html#doc%2dnamelengthmax">
diff --git a/doc/interpreter/HTML/doc_002dnargchk.html b/doc/interpreter/HTML/doc_002dnargchk.html
new file mode 100644
index 0000000..1bf7750
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnargchk.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Return-Values.html#doc%2dnargchk">
diff --git a/doc/interpreter/HTML/doc_002dnargin.html b/doc/interpreter/HTML/doc_002dnargin.html
new file mode 100644
index 0000000..939d1e0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnargin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Defining-Functions.html#doc%2dnargin">
diff --git a/doc/interpreter/HTML/doc_002dnargout.html b/doc/interpreter/HTML/doc_002dnargout.html
new file mode 100644
index 0000000..437c37f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnargout.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Return-Values.html#doc%2dnargout">
diff --git a/doc/interpreter/HTML/doc_002dnargoutchk.html b/doc/interpreter/HTML/doc_002dnargoutchk.html
new file mode 100644
index 0000000..6acd7e3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnargoutchk.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Return-Values.html#doc%2dnargoutchk">
diff --git a/doc/interpreter/HTML/doc_002dnative_005ffloat_005fformat.html b/doc/interpreter/HTML/doc_002dnative_005ffloat_005fformat.html
new file mode 100644
index 0000000..9055e56
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnative_005ffloat_005fformat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dnative%5ffloat%5fformat">
diff --git a/doc/interpreter/HTML/doc_002dnbincdf.html b/doc/interpreter/HTML/doc_002dnbincdf.html
new file mode 100644
index 0000000..670a234
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnbincdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dnbincdf">
diff --git a/doc/interpreter/HTML/doc_002dnbininv.html b/doc/interpreter/HTML/doc_002dnbininv.html
new file mode 100644
index 0000000..b6d8113
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnbininv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dnbininv">
diff --git a/doc/interpreter/HTML/doc_002dnbinpdf.html b/doc/interpreter/HTML/doc_002dnbinpdf.html
new file mode 100644
index 0000000..f002d61
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnbinpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dnbinpdf">
diff --git a/doc/interpreter/HTML/doc_002dnbinrnd.html b/doc/interpreter/HTML/doc_002dnbinrnd.html
new file mode 100644
index 0000000..a6e3725
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnbinrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dnbinrnd">
diff --git a/doc/interpreter/HTML/doc_002dnchoosek.html b/doc/interpreter/HTML/doc_002dnchoosek.html
new file mode 100644
index 0000000..8e99cdf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnchoosek.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dnchoosek">
diff --git a/doc/interpreter/HTML/doc_002dndgrid.html b/doc/interpreter/HTML/doc_002dndgrid.html
new file mode 100644
index 0000000..10c79b7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dndgrid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dndgrid">
diff --git a/doc/interpreter/HTML/doc_002dndims.html b/doc/interpreter/HTML/doc_002dndims.html
new file mode 100644
index 0000000..29b72b5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dndims.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dndims">
diff --git a/doc/interpreter/HTML/doc_002dne.html b/doc/interpreter/HTML/doc_002dne.html
new file mode 100644
index 0000000..0a5f6a2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dne.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dne">
diff --git a/doc/interpreter/HTML/doc_002dnewplot.html b/doc/interpreter/HTML/doc_002dnewplot.html
new file mode 100644
index 0000000..0e188e2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnewplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dnewplot">
diff --git a/doc/interpreter/HTML/doc_002dnews.html b/doc/interpreter/HTML/doc_002dnews.html
new file mode 100644
index 0000000..8b49da4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnews.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dnews">
diff --git a/doc/interpreter/HTML/doc_002dnextpow2.html b/doc/interpreter/HTML/doc_002dnextpow2.html
new file mode 100644
index 0000000..efe8cd1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnextpow2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dnextpow2">
diff --git a/doc/interpreter/HTML/doc_002dnnz.html b/doc/interpreter/HTML/doc_002dnnz.html
new file mode 100644
index 0000000..5d00041
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnnz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dnnz">
diff --git a/doc/interpreter/HTML/doc_002dnonzeros.html b/doc/interpreter/HTML/doc_002dnonzeros.html
new file mode 100644
index 0000000..7ddb569
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnonzeros.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dnonzeros">
diff --git a/doc/interpreter/HTML/doc_002dnorm.html b/doc/interpreter/HTML/doc_002dnorm.html
new file mode 100644
index 0000000..36aa187
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnorm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dnorm">
diff --git a/doc/interpreter/HTML/doc_002dnormcdf.html b/doc/interpreter/HTML/doc_002dnormcdf.html
new file mode 100644
index 0000000..db35051
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnormcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dnormcdf">
diff --git a/doc/interpreter/HTML/doc_002dnormest.html b/doc/interpreter/HTML/doc_002dnormest.html
new file mode 100644
index 0000000..3777ec8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnormest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dnormest">
diff --git a/doc/interpreter/HTML/doc_002dnorminv.html b/doc/interpreter/HTML/doc_002dnorminv.html
new file mode 100644
index 0000000..b9e9581
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnorminv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dnorminv">
diff --git a/doc/interpreter/HTML/doc_002dnormpdf.html b/doc/interpreter/HTML/doc_002dnormpdf.html
new file mode 100644
index 0000000..a312659
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnormpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dnormpdf">
diff --git a/doc/interpreter/HTML/doc_002dnormrnd.html b/doc/interpreter/HTML/doc_002dnormrnd.html
new file mode 100644
index 0000000..2a5030d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnormrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dnormrnd">
diff --git a/doc/interpreter/HTML/doc_002dnot.html b/doc/interpreter/HTML/doc_002dnot.html
new file mode 100644
index 0000000..82167fa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dnot">
diff --git a/doc/interpreter/HTML/doc_002dnow.html b/doc/interpreter/HTML/doc_002dnow.html
new file mode 100644
index 0000000..a6f088a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnow.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dnow">
diff --git a/doc/interpreter/HTML/doc_002dnthroot.html b/doc/interpreter/HTML/doc_002dnthroot.html
new file mode 100644
index 0000000..f09eb83
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnthroot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dnthroot">
diff --git a/doc/interpreter/HTML/doc_002dntsc2rgb.html b/doc/interpreter/HTML/doc_002dntsc2rgb.html
new file mode 100644
index 0000000..4627706
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dntsc2rgb.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Color-Conversion.html#doc%2dntsc2rgb">
diff --git a/doc/interpreter/HTML/doc_002dnull.html b/doc/interpreter/HTML/doc_002dnull.html
new file mode 100644
index 0000000..5aaf94a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnull.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dnull">
diff --git a/doc/interpreter/HTML/doc_002dnum2cell.html b/doc/interpreter/HTML/doc_002dnum2cell.html
new file mode 100644
index 0000000..19a750f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnum2cell.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Cell-Arrays.html#doc%2dnum2cell">
diff --git a/doc/interpreter/HTML/doc_002dnum2hex.html b/doc/interpreter/HTML/doc_002dnum2hex.html
new file mode 100644
index 0000000..c85cc5d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnum2hex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dnum2hex">
diff --git a/doc/interpreter/HTML/doc_002dnum2str.html b/doc/interpreter/HTML/doc_002dnum2str.html
new file mode 100644
index 0000000..7b0a586
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnum2str.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Conversion-of-Numerical-Data-to-Strings.html#doc%2dnum2str">
diff --git a/doc/interpreter/HTML/doc_002dnumel.html b/doc/interpreter/HTML/doc_002dnumel.html
new file mode 100644
index 0000000..d5bdd0f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnumel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dnumel">
diff --git a/doc/interpreter/HTML/doc_002dnzmax.html b/doc/interpreter/HTML/doc_002dnzmax.html
new file mode 100644
index 0000000..711755d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dnzmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dnzmax">
diff --git a/doc/interpreter/HTML/doc_002docean.html b/doc/interpreter/HTML/doc_002docean.html
new file mode 100644
index 0000000..88224af
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002docean.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2docean">
diff --git a/doc/interpreter/HTML/doc_002doctave_005fconfig_005finfo.html b/doc/interpreter/HTML/doc_002doctave_005fconfig_005finfo.html
new file mode 100644
index 0000000..8ccd9ba
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doctave_005fconfig_005finfo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2doctave%5fconfig%5finfo">
diff --git a/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005flimit.html b/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005flimit.html
new file mode 100644
index 0000000..92fdabf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005flimit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Saving-Data-on-Unexpected-Exits.html#doc%2doctave%5fcore%5ffile%5flimit">
diff --git a/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005fname.html b/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005fname.html
new file mode 100644
index 0000000..be0dc88
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005fname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Saving-Data-on-Unexpected-Exits.html#doc%2doctave%5fcore%5ffile%5fname">
diff --git a/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005foptions.html b/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005foptions.html
new file mode 100644
index 0000000..8741e6f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doctave_005fcore_005ffile_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Saving-Data-on-Unexpected-Exits.html#doc%2doctave%5fcore%5ffile%5foptions">
diff --git a/doc/interpreter/HTML/doc_002dols.html b/doc/interpreter/HTML/doc_002dols.html
new file mode 100644
index 0000000..ac2a673
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dols.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Linear-Least-Squares.html#doc%2dols">
diff --git a/doc/interpreter/HTML/doc_002donenormest.html b/doc/interpreter/HTML/doc_002donenormest.html
new file mode 100644
index 0000000..f343129
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002donenormest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2donenormest">
diff --git a/doc/interpreter/HTML/doc_002dones.html b/doc/interpreter/HTML/doc_002dones.html
new file mode 100644
index 0000000..f1175b7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dones.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2dones">
diff --git a/doc/interpreter/HTML/doc_002doptimget.html b/doc/interpreter/HTML/doc_002doptimget.html
new file mode 100644
index 0000000..47a3ff5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doptimget.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Linear-Least-Squares.html#doc%2doptimget">
diff --git a/doc/interpreter/HTML/doc_002doptimset.html b/doc/interpreter/HTML/doc_002doptimset.html
new file mode 100644
index 0000000..90f8904
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doptimset.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Linear-Least-Squares.html#doc%2doptimset">
diff --git a/doc/interpreter/HTML/doc_002dor.html b/doc/interpreter/HTML/doc_002dor.html
new file mode 100644
index 0000000..d3deabe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dor">
diff --git a/doc/interpreter/HTML/doc_002dorderfields.html b/doc/interpreter/HTML/doc_002dorderfields.html
new file mode 100644
index 0000000..054305c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dorderfields.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2dorderfields">
diff --git a/doc/interpreter/HTML/doc_002dorient.html b/doc/interpreter/HTML/doc_002dorient.html
new file mode 100644
index 0000000..b06e2b6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dorient.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Printing-Plots.html#doc%2dorient">
diff --git a/doc/interpreter/HTML/doc_002dorth.html b/doc/interpreter/HTML/doc_002dorth.html
new file mode 100644
index 0000000..158b6f6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dorth.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dorth">
diff --git a/doc/interpreter/HTML/doc_002doutput_005fmax_005ffield_005fwidth.html b/doc/interpreter/HTML/doc_002doutput_005fmax_005ffield_005fwidth.html
new file mode 100644
index 0000000..dd9e823
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doutput_005fmax_005ffield_005fwidth.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrices.html#doc%2doutput%5fmax%5ffield%5fwidth">
diff --git a/doc/interpreter/HTML/doc_002doutput_005fprecision.html b/doc/interpreter/HTML/doc_002doutput_005fprecision.html
new file mode 100644
index 0000000..e4bc824
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002doutput_005fprecision.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrices.html#doc%2doutput%5fprecision">
diff --git a/doc/interpreter/HTML/doc_002dpack.html b/doc/interpreter/HTML/doc_002dpack.html
new file mode 100644
index 0000000..be74b82
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpack.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dpack">
diff --git a/doc/interpreter/HTML/doc_002dpage_005foutput_005fimmediately.html b/doc/interpreter/HTML/doc_002dpage_005foutput_005fimmediately.html
new file mode 100644
index 0000000..b2f8c24
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpage_005foutput_005fimmediately.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Paging-Screen-Output.html#doc%2dpage%5foutput%5fimmediately">
diff --git a/doc/interpreter/HTML/doc_002dpage_005fscreen_005foutput.html b/doc/interpreter/HTML/doc_002dpage_005fscreen_005foutput.html
new file mode 100644
index 0000000..5a87615
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpage_005fscreen_005foutput.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Paging-Screen-Output.html#doc%2dpage%5fscreen%5foutput">
diff --git a/doc/interpreter/HTML/doc_002dpareto.html b/doc/interpreter/HTML/doc_002dpareto.html
new file mode 100644
index 0000000..ae32f6c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpareto.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dpareto">
diff --git a/doc/interpreter/HTML/doc_002dparseparams.html b/doc/interpreter/HTML/doc_002dparseparams.html
new file mode 100644
index 0000000..8b745b9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dparseparams.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Variable_002dlength-Argument-Lists.html#doc%2dparseparams">
diff --git a/doc/interpreter/HTML/doc_002dpascal.html b/doc/interpreter/HTML/doc_002dpascal.html
new file mode 100644
index 0000000..fe0ed58
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpascal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dpascal">
diff --git a/doc/interpreter/HTML/doc_002dpatch.html b/doc/interpreter/HTML/doc_002dpatch.html
new file mode 100644
index 0000000..a1957d6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpatch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dpatch">
diff --git a/doc/interpreter/HTML/doc_002dpath.html b/doc/interpreter/HTML/doc_002dpath.html
new file mode 100644
index 0000000..755d7bc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dpath">
diff --git a/doc/interpreter/HTML/doc_002dpathdef.html b/doc/interpreter/HTML/doc_002dpathdef.html
new file mode 100644
index 0000000..4a70895
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpathdef.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dpathdef">
diff --git a/doc/interpreter/HTML/doc_002dpathsep.html b/doc/interpreter/HTML/doc_002dpathsep.html
new file mode 100644
index 0000000..71e20f1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpathsep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dpathsep">
diff --git a/doc/interpreter/HTML/doc_002dpause.html b/doc/interpreter/HTML/doc_002dpause.html
new file mode 100644
index 0000000..695cdc3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpause.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dpause">
diff --git a/doc/interpreter/HTML/doc_002dpcg.html b/doc/interpreter/HTML/doc_002dpcg.html
new file mode 100644
index 0000000..a80cdff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpcg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Iterative-Techniques.html#doc%2dpcg">
diff --git a/doc/interpreter/HTML/doc_002dpchip.html b/doc/interpreter/HTML/doc_002dpchip.html
new file mode 100644
index 0000000..7cb70ac
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpchip.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dpchip">
diff --git a/doc/interpreter/HTML/doc_002dpclose.html b/doc/interpreter/HTML/doc_002dpclose.html
new file mode 100644
index 0000000..1a3264b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpclose.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dpclose">
diff --git a/doc/interpreter/HTML/doc_002dpcolor.html b/doc/interpreter/HTML/doc_002dpcolor.html
new file mode 100644
index 0000000..979465b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpcolor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dpcolor">
diff --git a/doc/interpreter/HTML/doc_002dpcr.html b/doc/interpreter/HTML/doc_002dpcr.html
new file mode 100644
index 0000000..61c1b52
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpcr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Iterative-Techniques.html#doc%2dpcr">
diff --git a/doc/interpreter/HTML/doc_002dpeaks.html b/doc/interpreter/HTML/doc_002dpeaks.html
new file mode 100644
index 0000000..ff0ad9c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpeaks.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Test-Plotting-Functions.html#doc%2dpeaks">
diff --git a/doc/interpreter/HTML/doc_002dperiodogram.html b/doc/interpreter/HTML/doc_002dperiodogram.html
new file mode 100644
index 0000000..02cae48
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dperiodogram.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dperiodogram">
diff --git a/doc/interpreter/HTML/doc_002dperl.html b/doc/interpreter/HTML/doc_002dperl.html
new file mode 100644
index 0000000..4480da8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dperl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dperl">
diff --git a/doc/interpreter/HTML/doc_002dperms.html b/doc/interpreter/HTML/doc_002dperms.html
new file mode 100644
index 0000000..0adaae3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dperms.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dperms">
diff --git a/doc/interpreter/HTML/doc_002dpermute.html b/doc/interpreter/HTML/doc_002dpermute.html
new file mode 100644
index 0000000..8eb8eae
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpermute.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dpermute">
diff --git a/doc/interpreter/HTML/doc_002dpersistent.html b/doc/interpreter/HTML/doc_002dpersistent.html
new file mode 100644
index 0000000..f733d73
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpersistent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Persistent-Variables.html#doc%2dpersistent">
diff --git a/doc/interpreter/HTML/doc_002dpi.html b/doc/interpreter/HTML/doc_002dpi.html
new file mode 100644
index 0000000..b007a5c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpi.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2dpi">
diff --git a/doc/interpreter/HTML/doc_002dpie.html b/doc/interpreter/HTML/doc_002dpie.html
new file mode 100644
index 0000000..612b00f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpie.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dpie">
diff --git a/doc/interpreter/HTML/doc_002dpink.html b/doc/interpreter/HTML/doc_002dpink.html
new file mode 100644
index 0000000..3e7f8f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpink.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dpink">
diff --git a/doc/interpreter/HTML/doc_002dpinv.html b/doc/interpreter/HTML/doc_002dpinv.html
new file mode 100644
index 0000000..961d477
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dpinv">
diff --git a/doc/interpreter/HTML/doc_002dpipe.html b/doc/interpreter/HTML/doc_002dpipe.html
new file mode 100644
index 0000000..76c0299
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpipe.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dpipe">
diff --git a/doc/interpreter/HTML/doc_002dpkg.html b/doc/interpreter/HTML/doc_002dpkg.html
new file mode 100644
index 0000000..c44dd45
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpkg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Installing-and-Removing-Packages.html#doc%2dpkg">
diff --git a/doc/interpreter/HTML/doc_002dplanerot.html b/doc/interpreter/HTML/doc_002dplanerot.html
new file mode 100644
index 0000000..4868a25
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplanerot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dplanerot">
diff --git a/doc/interpreter/HTML/doc_002dplayaudio.html b/doc/interpreter/HTML/doc_002dplayaudio.html
new file mode 100644
index 0000000..df8a6c8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplayaudio.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dplayaudio">
diff --git a/doc/interpreter/HTML/doc_002dplot.html b/doc/interpreter/HTML/doc_002dplot.html
new file mode 100644
index 0000000..c92e396
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dplot">
diff --git a/doc/interpreter/HTML/doc_002dplot3.html b/doc/interpreter/HTML/doc_002dplot3.html
new file mode 100644
index 0000000..77718b8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplot3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dplot3">
diff --git a/doc/interpreter/HTML/doc_002dplotmatrix.html b/doc/interpreter/HTML/doc_002dplotmatrix.html
new file mode 100644
index 0000000..19f1bf1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplotmatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dplotmatrix">
diff --git a/doc/interpreter/HTML/doc_002dplotyy.html b/doc/interpreter/HTML/doc_002dplotyy.html
new file mode 100644
index 0000000..ddb97cd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplotyy.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dplotyy">
diff --git a/doc/interpreter/HTML/doc_002dplus.html b/doc/interpreter/HTML/doc_002dplus.html
new file mode 100644
index 0000000..e1c50fe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dplus.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dplus">
diff --git a/doc/interpreter/HTML/doc_002dpoisscdf.html b/doc/interpreter/HTML/doc_002dpoisscdf.html
new file mode 100644
index 0000000..3c8ac0b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpoisscdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dpoisscdf">
diff --git a/doc/interpreter/HTML/doc_002dpoissinv.html b/doc/interpreter/HTML/doc_002dpoissinv.html
new file mode 100644
index 0000000..8d1dd17
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpoissinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dpoissinv">
diff --git a/doc/interpreter/HTML/doc_002dpoisspdf.html b/doc/interpreter/HTML/doc_002dpoisspdf.html
new file mode 100644
index 0000000..e6298bf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpoisspdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dpoisspdf">
diff --git a/doc/interpreter/HTML/doc_002dpoissrnd.html b/doc/interpreter/HTML/doc_002dpoissrnd.html
new file mode 100644
index 0000000..b7202ed
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpoissrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dpoissrnd">
diff --git a/doc/interpreter/HTML/doc_002dpol2cart.html b/doc/interpreter/HTML/doc_002dpol2cart.html
new file mode 100644
index 0000000..73673f0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpol2cart.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Coordinate-Transformations.html#doc%2dpol2cart">
diff --git a/doc/interpreter/HTML/doc_002dpolar.html b/doc/interpreter/HTML/doc_002dpolar.html
new file mode 100644
index 0000000..c4c1baf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dpolar">
diff --git a/doc/interpreter/HTML/doc_002dpoly.html b/doc/interpreter/HTML/doc_002dpoly.html
new file mode 100644
index 0000000..50348f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpoly.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Miscellaneous-Functions.html#doc%2dpoly">
diff --git a/doc/interpreter/HTML/doc_002dpolyarea.html b/doc/interpreter/HTML/doc_002dpolyarea.html
new file mode 100644
index 0000000..45453c1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyarea.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Voronoi-Diagrams.html#doc%2dpolyarea">
diff --git a/doc/interpreter/HTML/doc_002dpolyder.html b/doc/interpreter/HTML/doc_002dpolyder.html
new file mode 100644
index 0000000..777035a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyder.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Derivatives-and-Integrals.html#doc%2dpolyder">
diff --git a/doc/interpreter/HTML/doc_002dpolyderiv.html b/doc/interpreter/HTML/doc_002dpolyderiv.html
new file mode 100644
index 0000000..b5393d4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyderiv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Derivatives-and-Integrals.html#doc%2dpolyderiv">
diff --git a/doc/interpreter/HTML/doc_002dpolyfit.html b/doc/interpreter/HTML/doc_002dpolyfit.html
new file mode 100644
index 0000000..1fb418c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyfit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Polynomial-Interpolation.html#doc%2dpolyfit">
diff --git a/doc/interpreter/HTML/doc_002dpolygcd.html b/doc/interpreter/HTML/doc_002dpolygcd.html
new file mode 100644
index 0000000..6f79a84
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolygcd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Products-of-Polynomials.html#doc%2dpolygcd">
diff --git a/doc/interpreter/HTML/doc_002dpolyint.html b/doc/interpreter/HTML/doc_002dpolyint.html
new file mode 100644
index 0000000..1200c61
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyint.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Derivatives-and-Integrals.html#doc%2dpolyint">
diff --git a/doc/interpreter/HTML/doc_002dpolyinteg.html b/doc/interpreter/HTML/doc_002dpolyinteg.html
new file mode 100644
index 0000000..20d6f27
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyinteg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Derivatives-and-Integrals.html#doc%2dpolyinteg">
diff --git a/doc/interpreter/HTML/doc_002dpolyout.html b/doc/interpreter/HTML/doc_002dpolyout.html
new file mode 100644
index 0000000..2dd5df0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyout.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Miscellaneous-Functions.html#doc%2dpolyout">
diff --git a/doc/interpreter/HTML/doc_002dpolyreduce.html b/doc/interpreter/HTML/doc_002dpolyreduce.html
new file mode 100644
index 0000000..8be3ed6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyreduce.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Miscellaneous-Functions.html#doc%2dpolyreduce">
diff --git a/doc/interpreter/HTML/doc_002dpolyval.html b/doc/interpreter/HTML/doc_002dpolyval.html
new file mode 100644
index 0000000..69da76b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyval.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Evaluating-Polynomials.html#doc%2dpolyval">
diff --git a/doc/interpreter/HTML/doc_002dpolyvalm.html b/doc/interpreter/HTML/doc_002dpolyvalm.html
new file mode 100644
index 0000000..f0a8810
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpolyvalm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Evaluating-Polynomials.html#doc%2dpolyvalm">
diff --git a/doc/interpreter/HTML/doc_002dpopen.html b/doc/interpreter/HTML/doc_002dpopen.html
new file mode 100644
index 0000000..47fab2c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpopen.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dpopen">
diff --git a/doc/interpreter/HTML/doc_002dpopen2.html b/doc/interpreter/HTML/doc_002dpopen2.html
new file mode 100644
index 0000000..f461c75
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpopen2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dpopen2">
diff --git a/doc/interpreter/HTML/doc_002dpostpad.html b/doc/interpreter/HTML/doc_002dpostpad.html
new file mode 100644
index 0000000..5748ccd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpostpad.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dpostpad">
diff --git a/doc/interpreter/HTML/doc_002dpow2.html b/doc/interpreter/HTML/doc_002dpow2.html
new file mode 100644
index 0000000..28b3b6c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpow2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dpow2">
diff --git a/doc/interpreter/HTML/doc_002dpower.html b/doc/interpreter/HTML/doc_002dpower.html
new file mode 100644
index 0000000..7d915bd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpower.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dpower">
diff --git a/doc/interpreter/HTML/doc_002dppplot.html b/doc/interpreter/HTML/doc_002dppplot.html
new file mode 100644
index 0000000..a724882
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dppplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Statistical-Plots.html#doc%2dppplot">
diff --git a/doc/interpreter/HTML/doc_002dppval.html b/doc/interpreter/HTML/doc_002dppval.html
new file mode 100644
index 0000000..01d79e8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dppval.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Polynomial-Interpolation.html#doc%2dppval">
diff --git a/doc/interpreter/HTML/doc_002dprctile.html b/doc/interpreter/HTML/doc_002dprctile.html
new file mode 100644
index 0000000..880a7e3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprctile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dprctile">
diff --git a/doc/interpreter/HTML/doc_002dprepad.html b/doc/interpreter/HTML/doc_002dprepad.html
new file mode 100644
index 0000000..c323bab
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprepad.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dprepad">
diff --git a/doc/interpreter/HTML/doc_002dprimes.html b/doc/interpreter/HTML/doc_002dprimes.html
new file mode 100644
index 0000000..010bbf8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprimes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dprimes">
diff --git a/doc/interpreter/HTML/doc_002dprint.html b/doc/interpreter/HTML/doc_002dprint.html
new file mode 100644
index 0000000..2837819
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprint.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Printing-Plots.html#doc%2dprint">
diff --git a/doc/interpreter/HTML/doc_002dprint_005fempty_005fdimensions.html b/doc/interpreter/HTML/doc_002dprint_005fempty_005fdimensions.html
new file mode 100644
index 0000000..c1b2535
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprint_005fempty_005fdimensions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Empty-Matrices.html#doc%2dprint%5fempty%5fdimensions">
diff --git a/doc/interpreter/HTML/doc_002dprint_005fusage.html b/doc/interpreter/HTML/doc_002dprint_005fusage.html
new file mode 100644
index 0000000..0385165
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprint_005fusage.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Raising-Errors.html#doc%2dprint%5fusage">
diff --git a/doc/interpreter/HTML/doc_002dprintf.html b/doc/interpreter/HTML/doc_002dprintf.html
new file mode 100644
index 0000000..182bef1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprintf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Formatted-Output.html#doc%2dprintf">
diff --git a/doc/interpreter/HTML/doc_002dprism.html b/doc/interpreter/HTML/doc_002dprism.html
new file mode 100644
index 0000000..da6d2d4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprism.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dprism">
diff --git a/doc/interpreter/HTML/doc_002dprobit.html b/doc/interpreter/HTML/doc_002dprobit.html
new file mode 100644
index 0000000..a6c27bd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprobit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dprobit">
diff --git a/doc/interpreter/HTML/doc_002dprod.html b/doc/interpreter/HTML/doc_002dprod.html
new file mode 100644
index 0000000..c180ed2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprod.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sums-and-Products.html#doc%2dprod">
diff --git a/doc/interpreter/HTML/doc_002dprogram_005finvocation_005fname.html b/doc/interpreter/HTML/doc_002dprogram_005finvocation_005fname.html
new file mode 100644
index 0000000..553a934
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprogram_005finvocation_005fname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Command-Line-Options.html#doc%2dprogram%5finvocation%5fname">
diff --git a/doc/interpreter/HTML/doc_002dprogram_005fname.html b/doc/interpreter/HTML/doc_002dprogram_005fname.html
new file mode 100644
index 0000000..9fda1b4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprogram_005fname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Command-Line-Options.html#doc%2dprogram%5fname">
diff --git a/doc/interpreter/HTML/doc_002dprop_005ftest_005f2.html b/doc/interpreter/HTML/doc_002dprop_005ftest_005f2.html
new file mode 100644
index 0000000..5621e46
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dprop_005ftest_005f2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dprop%5ftest%5f2">
diff --git a/doc/interpreter/HTML/doc_002dputenv.html b/doc/interpreter/HTML/doc_002dputenv.html
new file mode 100644
index 0000000..72416bb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dputenv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Environment-Variables.html#doc%2dputenv">
diff --git a/doc/interpreter/HTML/doc_002dputs.html b/doc/interpreter/HTML/doc_002dputs.html
new file mode 100644
index 0000000..dec17c2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dputs.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-Output.html#doc%2dputs">
diff --git a/doc/interpreter/HTML/doc_002dpwd.html b/doc/interpreter/HTML/doc_002dpwd.html
new file mode 100644
index 0000000..7c74c6f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dpwd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Current-Working-Directory.html#doc%2dpwd">
diff --git a/doc/interpreter/HTML/doc_002dqp.html b/doc/interpreter/HTML/doc_002dqp.html
new file mode 100644
index 0000000..57c6390
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Quadratic-Programming.html#doc%2dqp">
diff --git a/doc/interpreter/HTML/doc_002dqqplot.html b/doc/interpreter/HTML/doc_002dqqplot.html
new file mode 100644
index 0000000..f5e8679
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqqplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Statistical-Plots.html#doc%2dqqplot">
diff --git a/doc/interpreter/HTML/doc_002dqr.html b/doc/interpreter/HTML/doc_002dqr.html
new file mode 100644
index 0000000..672cf0e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqr">
diff --git a/doc/interpreter/HTML/doc_002dqrdelete.html b/doc/interpreter/HTML/doc_002dqrdelete.html
new file mode 100644
index 0000000..50c5142
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqrdelete.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqrdelete">
diff --git a/doc/interpreter/HTML/doc_002dqrinsert.html b/doc/interpreter/HTML/doc_002dqrinsert.html
new file mode 100644
index 0000000..4bf5018
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqrinsert.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqrinsert">
diff --git a/doc/interpreter/HTML/doc_002dqrshift.html b/doc/interpreter/HTML/doc_002dqrshift.html
new file mode 100644
index 0000000..db258ae
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqrshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqrshift">
diff --git a/doc/interpreter/HTML/doc_002dqrupdate.html b/doc/interpreter/HTML/doc_002dqrupdate.html
new file mode 100644
index 0000000..e4d4616
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqrupdate.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqrupdate">
diff --git a/doc/interpreter/HTML/doc_002dquad.html b/doc/interpreter/HTML/doc_002dquad.html
new file mode 100644
index 0000000..7b61618
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquad.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dquad">
diff --git a/doc/interpreter/HTML/doc_002dquad_005foptions.html b/doc/interpreter/HTML/doc_002dquad_005foptions.html
new file mode 100644
index 0000000..a6f8c58
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquad_005foptions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dquad%5foptions">
diff --git a/doc/interpreter/HTML/doc_002dquadgk.html b/doc/interpreter/HTML/doc_002dquadgk.html
new file mode 100644
index 0000000..8dbcce8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquadgk.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dquadgk">
diff --git a/doc/interpreter/HTML/doc_002dquadl.html b/doc/interpreter/HTML/doc_002dquadl.html
new file mode 100644
index 0000000..286a5a2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquadl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dquadl">
diff --git a/doc/interpreter/HTML/doc_002dquadv.html b/doc/interpreter/HTML/doc_002dquadv.html
new file mode 100644
index 0000000..fb48502
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquadv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dquadv">
diff --git a/doc/interpreter/HTML/doc_002dquantile.html b/doc/interpreter/HTML/doc_002dquantile.html
new file mode 100644
index 0000000..19cedaa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquantile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dquantile">
diff --git a/doc/interpreter/HTML/doc_002dquit.html b/doc/interpreter/HTML/doc_002dquit.html
new file mode 100644
index 0000000..f860f40
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Quitting-Octave.html#doc%2dquit">
diff --git a/doc/interpreter/HTML/doc_002dquiver.html b/doc/interpreter/HTML/doc_002dquiver.html
new file mode 100644
index 0000000..6487dd9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquiver.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dquiver">
diff --git a/doc/interpreter/HTML/doc_002dquiver3.html b/doc/interpreter/HTML/doc_002dquiver3.html
new file mode 100644
index 0000000..ef0d668
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dquiver3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dquiver3">
diff --git a/doc/interpreter/HTML/doc_002dqz.html b/doc/interpreter/HTML/doc_002dqz.html
new file mode 100644
index 0000000..c746261
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqz">
diff --git a/doc/interpreter/HTML/doc_002dqzhess.html b/doc/interpreter/HTML/doc_002dqzhess.html
new file mode 100644
index 0000000..35a395e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dqzhess.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dqzhess">
diff --git a/doc/interpreter/HTML/doc_002drainbow.html b/doc/interpreter/HTML/doc_002drainbow.html
new file mode 100644
index 0000000..e02eac9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drainbow.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2drainbow">
diff --git a/doc/interpreter/HTML/doc_002drand.html b/doc/interpreter/HTML/doc_002drand.html
new file mode 100644
index 0000000..8687b46
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drand">
diff --git a/doc/interpreter/HTML/doc_002drande.html b/doc/interpreter/HTML/doc_002drande.html
new file mode 100644
index 0000000..640b4c8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drande.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drande">
diff --git a/doc/interpreter/HTML/doc_002drandg.html b/doc/interpreter/HTML/doc_002drandg.html
new file mode 100644
index 0000000..fb22c82
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drandg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drandg">
diff --git a/doc/interpreter/HTML/doc_002drandn.html b/doc/interpreter/HTML/doc_002drandn.html
new file mode 100644
index 0000000..de8b1ef
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drandn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drandn">
diff --git a/doc/interpreter/HTML/doc_002drandp.html b/doc/interpreter/HTML/doc_002drandp.html
new file mode 100644
index 0000000..4d51cc6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drandp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drandp">
diff --git a/doc/interpreter/HTML/doc_002drandperm.html b/doc/interpreter/HTML/doc_002drandperm.html
new file mode 100644
index 0000000..7d034ff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drandperm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drandperm">
diff --git a/doc/interpreter/HTML/doc_002drange.html b/doc/interpreter/HTML/doc_002drange.html
new file mode 100644
index 0000000..9b1bb77
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drange.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2drange">
diff --git a/doc/interpreter/HTML/doc_002drank.html b/doc/interpreter/HTML/doc_002drank.html
new file mode 100644
index 0000000..f8f603c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drank.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2drank">
diff --git a/doc/interpreter/HTML/doc_002dranks.html b/doc/interpreter/HTML/doc_002dranks.html
new file mode 100644
index 0000000..10a5da9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dranks.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dranks">
diff --git a/doc/interpreter/HTML/doc_002drat.html b/doc/interpreter/HTML/doc_002drat.html
new file mode 100644
index 0000000..a94e2ce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rational-Approximations.html#doc%2drat">
diff --git a/doc/interpreter/HTML/doc_002drats.html b/doc/interpreter/HTML/doc_002drats.html
new file mode 100644
index 0000000..e50027e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drats.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rational-Approximations.html#doc%2drats">
diff --git a/doc/interpreter/HTML/doc_002drcond.html b/doc/interpreter/HTML/doc_002drcond.html
new file mode 100644
index 0000000..7c0408d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drcond.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2drcond">
diff --git a/doc/interpreter/HTML/doc_002drdivide.html b/doc/interpreter/HTML/doc_002drdivide.html
new file mode 100644
index 0000000..c828f4f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drdivide.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2drdivide">
diff --git a/doc/interpreter/HTML/doc_002dre_005fread_005freadline_005finit_005ffile.html b/doc/interpreter/HTML/doc_002dre_005fread_005freadline_005finit_005ffile.html
new file mode 100644
index 0000000..41fa2b8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dre_005fread_005freadline_005finit_005ffile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Customizing-readline.html#doc%2dre%5fread%5freadline%5finit%5ffile">
diff --git a/doc/interpreter/HTML/doc_002dread_005freadline_005finit_005ffile.html b/doc/interpreter/HTML/doc_002dread_005freadline_005finit_005ffile.html
new file mode 100644
index 0000000..2d597a6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dread_005freadline_005finit_005ffile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Customizing-readline.html#doc%2dread%5freadline%5finit%5ffile">
diff --git a/doc/interpreter/HTML/doc_002dreaddir.html b/doc/interpreter/HTML/doc_002dreaddir.html
new file mode 100644
index 0000000..74b168e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dreaddir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dreaddir">
diff --git a/doc/interpreter/HTML/doc_002dreadlink.html b/doc/interpreter/HTML/doc_002dreadlink.html
new file mode 100644
index 0000000..f29a4ff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dreadlink.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dreadlink">
diff --git a/doc/interpreter/HTML/doc_002dreal.html b/doc/interpreter/HTML/doc_002dreal.html
new file mode 100644
index 0000000..c8d4ca9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dreal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Complex-Arithmetic.html#doc%2dreal">
diff --git a/doc/interpreter/HTML/doc_002dreallog.html b/doc/interpreter/HTML/doc_002dreallog.html
new file mode 100644
index 0000000..c963b78
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dreallog.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dreallog">
diff --git a/doc/interpreter/HTML/doc_002drealmax.html b/doc/interpreter/HTML/doc_002drealmax.html
new file mode 100644
index 0000000..31ce933
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drealmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2drealmax">
diff --git a/doc/interpreter/HTML/doc_002drealmin.html b/doc/interpreter/HTML/doc_002drealmin.html
new file mode 100644
index 0000000..b9c523a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drealmin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Constants.html#doc%2drealmin">
diff --git a/doc/interpreter/HTML/doc_002drealpow.html b/doc/interpreter/HTML/doc_002drealpow.html
new file mode 100644
index 0000000..429f6dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drealpow.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2drealpow">
diff --git a/doc/interpreter/HTML/doc_002drealsqrt.html b/doc/interpreter/HTML/doc_002drealsqrt.html
new file mode 100644
index 0000000..0a6d2ff
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drealsqrt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2drealsqrt">
diff --git a/doc/interpreter/HTML/doc_002drecord.html b/doc/interpreter/HTML/doc_002drecord.html
new file mode 100644
index 0000000..b6fc4ec
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drecord.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2drecord">
diff --git a/doc/interpreter/HTML/doc_002drectangle_005flw.html b/doc/interpreter/HTML/doc_002drectangle_005flw.html
new file mode 100644
index 0000000..e4b10e2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drectangle_005flw.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2drectangle%5flw">
diff --git a/doc/interpreter/HTML/doc_002drectangle_005fsw.html b/doc/interpreter/HTML/doc_002drectangle_005fsw.html
new file mode 100644
index 0000000..760e0f9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drectangle_005fsw.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2drectangle%5fsw">
diff --git a/doc/interpreter/HTML/doc_002drectint.html b/doc/interpreter/HTML/doc_002drectint.html
new file mode 100644
index 0000000..86a2a2b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drectint.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Voronoi-Diagrams.html#doc%2drectint">
diff --git a/doc/interpreter/HTML/doc_002drefresh.html b/doc/interpreter/HTML/doc_002drefresh.html
new file mode 100644
index 0000000..30433a3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drefresh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2drefresh">
diff --git a/doc/interpreter/HTML/doc_002drefreshdata.html b/doc/interpreter/HTML/doc_002drefreshdata.html
new file mode 100644
index 0000000..3f2e842
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drefreshdata.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Data-sources-in-object-groups.html#doc%2drefreshdata">
diff --git a/doc/interpreter/HTML/doc_002dregexp.html b/doc/interpreter/HTML/doc_002dregexp.html
new file mode 100644
index 0000000..0dfa798
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dregexp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dregexp">
diff --git a/doc/interpreter/HTML/doc_002dregexpi.html b/doc/interpreter/HTML/doc_002dregexpi.html
new file mode 100644
index 0000000..790e1f8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dregexpi.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dregexpi">
diff --git a/doc/interpreter/HTML/doc_002dregexprep.html b/doc/interpreter/HTML/doc_002dregexprep.html
new file mode 100644
index 0000000..7d5d240
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dregexprep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dregexprep">
diff --git a/doc/interpreter/HTML/doc_002dregexptranslate.html b/doc/interpreter/HTML/doc_002dregexptranslate.html
new file mode 100644
index 0000000..d948806
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dregexptranslate.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dregexptranslate">
diff --git a/doc/interpreter/HTML/doc_002drehash.html b/doc/interpreter/HTML/doc_002drehash.html
new file mode 100644
index 0000000..6375aad
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drehash.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2drehash">
diff --git a/doc/interpreter/HTML/doc_002drem.html b/doc/interpreter/HTML/doc_002drem.html
new file mode 100644
index 0000000..a64e4ca
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drem.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2drem">
diff --git a/doc/interpreter/HTML/doc_002drename.html b/doc/interpreter/HTML/doc_002drename.html
new file mode 100644
index 0000000..7788b3f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drename.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2drename">
diff --git a/doc/interpreter/HTML/doc_002drepmat.html b/doc/interpreter/HTML/doc_002drepmat.html
new file mode 100644
index 0000000..f82b6e8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drepmat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2drepmat">
diff --git a/doc/interpreter/HTML/doc_002dreshape.html b/doc/interpreter/HTML/doc_002dreshape.html
new file mode 100644
index 0000000..7f864f3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dreshape.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dreshape">
diff --git a/doc/interpreter/HTML/doc_002dresidue.html b/doc/interpreter/HTML/doc_002dresidue.html
new file mode 100644
index 0000000..ff6529d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dresidue.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Products-of-Polynomials.html#doc%2dresidue">
diff --git a/doc/interpreter/HTML/doc_002dresize.html b/doc/interpreter/HTML/doc_002dresize.html
new file mode 100644
index 0000000..c71eb99
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dresize.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dresize">
diff --git a/doc/interpreter/HTML/doc_002drestoredefaultpath.html b/doc/interpreter/HTML/doc_002drestoredefaultpath.html
new file mode 100644
index 0000000..bd13a46
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drestoredefaultpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2drestoredefaultpath">
diff --git a/doc/interpreter/HTML/doc_002drethrow.html b/doc/interpreter/HTML/doc_002drethrow.html
new file mode 100644
index 0000000..ca53137
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drethrow.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Catching-Errors.html#doc%2drethrow">
diff --git a/doc/interpreter/HTML/doc_002drgb2hsv.html b/doc/interpreter/HTML/doc_002drgb2hsv.html
new file mode 100644
index 0000000..0d5cc94
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drgb2hsv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Color-Conversion.html#doc%2drgb2hsv">
diff --git a/doc/interpreter/HTML/doc_002drgb2ind.html b/doc/interpreter/HTML/doc_002drgb2ind.html
new file mode 100644
index 0000000..8fb0fe2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drgb2ind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2drgb2ind">
diff --git a/doc/interpreter/HTML/doc_002drgb2ntsc.html b/doc/interpreter/HTML/doc_002drgb2ntsc.html
new file mode 100644
index 0000000..2391999
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drgb2ntsc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Color-Conversion.html#doc%2drgb2ntsc">
diff --git a/doc/interpreter/HTML/doc_002dribbon.html b/doc/interpreter/HTML/doc_002dribbon.html
new file mode 100644
index 0000000..b96bf23
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dribbon.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dribbon">
diff --git a/doc/interpreter/HTML/doc_002drindex.html b/doc/interpreter/HTML/doc_002drindex.html
new file mode 100644
index 0000000..f9cce8a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drindex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2drindex">
diff --git a/doc/interpreter/HTML/doc_002drmdir.html b/doc/interpreter/HTML/doc_002drmdir.html
new file mode 100644
index 0000000..2f85d27
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drmdir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2drmdir">
diff --git a/doc/interpreter/HTML/doc_002drmfield.html b/doc/interpreter/HTML/doc_002drmfield.html
new file mode 100644
index 0000000..e822b78
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drmfield.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2drmfield">
diff --git a/doc/interpreter/HTML/doc_002drmpath.html b/doc/interpreter/HTML/doc_002drmpath.html
new file mode 100644
index 0000000..5dd973e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drmpath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2drmpath">
diff --git a/doc/interpreter/HTML/doc_002droots.html b/doc/interpreter/HTML/doc_002droots.html
new file mode 100644
index 0000000..66c64b0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002droots.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Roots.html#doc%2droots">
diff --git a/doc/interpreter/HTML/doc_002drose.html b/doc/interpreter/HTML/doc_002drose.html
new file mode 100644
index 0000000..fbf59ce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drose.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2drose">
diff --git a/doc/interpreter/HTML/doc_002drosser.html b/doc/interpreter/HTML/doc_002drosser.html
new file mode 100644
index 0000000..63f1efe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drosser.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2drosser">
diff --git a/doc/interpreter/HTML/doc_002drot90.html b/doc/interpreter/HTML/doc_002drot90.html
new file mode 100644
index 0000000..d65d4e4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drot90.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2drot90">
diff --git a/doc/interpreter/HTML/doc_002drotdim.html b/doc/interpreter/HTML/doc_002drotdim.html
new file mode 100644
index 0000000..8f58db9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drotdim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2drotdim">
diff --git a/doc/interpreter/HTML/doc_002dround.html b/doc/interpreter/HTML/doc_002dround.html
new file mode 100644
index 0000000..80014c3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dround.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dround">
diff --git a/doc/interpreter/HTML/doc_002droundb.html b/doc/interpreter/HTML/doc_002droundb.html
new file mode 100644
index 0000000..4ef9725
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002droundb.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2droundb">
diff --git a/doc/interpreter/HTML/doc_002drows.html b/doc/interpreter/HTML/doc_002drows.html
new file mode 100644
index 0000000..32d5ac6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drows.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2drows">
diff --git a/doc/interpreter/HTML/doc_002drref.html b/doc/interpreter/HTML/doc_002drref.html
new file mode 100644
index 0000000..378885e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drref.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2drref">
diff --git a/doc/interpreter/HTML/doc_002drun.html b/doc/interpreter/HTML/doc_002drun.html
new file mode 100644
index 0000000..ad80d34
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drun.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Calling-a-Function-by-its-Name.html#doc%2drun">
diff --git a/doc/interpreter/HTML/doc_002drun_005fcount.html b/doc/interpreter/HTML/doc_002drun_005fcount.html
new file mode 100644
index 0000000..43848d0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drun_005fcount.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2drun%5fcount">
diff --git a/doc/interpreter/HTML/doc_002drun_005fhistory.html b/doc/interpreter/HTML/doc_002drun_005fhistory.html
new file mode 100644
index 0000000..5d61fa5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drun_005fhistory.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2drun%5fhistory">
diff --git a/doc/interpreter/HTML/doc_002drun_005ftest.html b/doc/interpreter/HTML/doc_002drun_005ftest.html
new file mode 100644
index 0000000..d939d3b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drun_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2drun%5ftest">
diff --git a/doc/interpreter/HTML/doc_002drundemos.html b/doc/interpreter/HTML/doc_002drundemos.html
new file mode 100644
index 0000000..ce838ee
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002drundemos.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Demonstration-Functions.html#doc%2drundemos">
diff --git a/doc/interpreter/HTML/doc_002dsave.html b/doc/interpreter/HTML/doc_002dsave.html
new file mode 100644
index 0000000..9c12ad7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsave.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dsave">
diff --git a/doc/interpreter/HTML/doc_002dsave_005fheader_005fformat_005fstring.html b/doc/interpreter/HTML/doc_002dsave_005fheader_005fformat_005fstring.html
new file mode 100644
index 0000000..11116dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsave_005fheader_005fformat_005fstring.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dsave%5fheader%5fformat%5fstring">
diff --git a/doc/interpreter/HTML/doc_002dsave_005fprecision.html b/doc/interpreter/HTML/doc_002dsave_005fprecision.html
new file mode 100644
index 0000000..2d4047f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsave_005fprecision.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Simple-File-I_002fO.html#doc%2dsave%5fprecision">
diff --git a/doc/interpreter/HTML/doc_002dsaveaudio.html b/doc/interpreter/HTML/doc_002dsaveaudio.html
new file mode 100644
index 0000000..3c81c22
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsaveaudio.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dsaveaudio">
diff --git a/doc/interpreter/HTML/doc_002dsaveobj.html b/doc/interpreter/HTML/doc_002dsaveobj.html
new file mode 100644
index 0000000..8fb7dc1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsaveobj.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Classes.html#doc%2dsaveobj">
diff --git a/doc/interpreter/HTML/doc_002dsavepath.html b/doc/interpreter/HTML/doc_002dsavepath.html
new file mode 100644
index 0000000..b3947f8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsavepath.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-the-load-path.html#doc%2dsavepath">
diff --git a/doc/interpreter/HTML/doc_002dsaving_005fhistory.html b/doc/interpreter/HTML/doc_002dsaving_005fhistory.html
new file mode 100644
index 0000000..987a4c8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsaving_005fhistory.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands-For-History.html#doc%2dsaving%5fhistory">
diff --git a/doc/interpreter/HTML/doc_002dscanf.html b/doc/interpreter/HTML/doc_002dscanf.html
new file mode 100644
index 0000000..54ba97e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dscanf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Formatted-Input.html#doc%2dscanf">
diff --git a/doc/interpreter/HTML/doc_002dscatter.html b/doc/interpreter/HTML/doc_002dscatter.html
new file mode 100644
index 0000000..971ebae
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dscatter.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dscatter">
diff --git a/doc/interpreter/HTML/doc_002dscatter3.html b/doc/interpreter/HTML/doc_002dscatter3.html
new file mode 100644
index 0000000..c55a55c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dscatter3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dscatter3">
diff --git a/doc/interpreter/HTML/doc_002dschur.html b/doc/interpreter/HTML/doc_002dschur.html
new file mode 100644
index 0000000..03eda15
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dschur.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dschur">
diff --git a/doc/interpreter/HTML/doc_002dsec.html b/doc/interpreter/HTML/doc_002dsec.html
new file mode 100644
index 0000000..4e27ec3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dsec">
diff --git a/doc/interpreter/HTML/doc_002dsecd.html b/doc/interpreter/HTML/doc_002dsecd.html
new file mode 100644
index 0000000..091a952
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsecd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dsecd">
diff --git a/doc/interpreter/HTML/doc_002dsech.html b/doc/interpreter/HTML/doc_002dsech.html
new file mode 100644
index 0000000..0f87f07
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsech.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dsech">
diff --git a/doc/interpreter/HTML/doc_002dsemilogx.html b/doc/interpreter/HTML/doc_002dsemilogx.html
new file mode 100644
index 0000000..6f7cb0e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsemilogx.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dsemilogx">
diff --git a/doc/interpreter/HTML/doc_002dsemilogxerr.html b/doc/interpreter/HTML/doc_002dsemilogxerr.html
new file mode 100644
index 0000000..1bed159
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsemilogxerr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dsemilogxerr">
diff --git a/doc/interpreter/HTML/doc_002dsemilogy.html b/doc/interpreter/HTML/doc_002dsemilogy.html
new file mode 100644
index 0000000..d1af93d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsemilogy.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dsemilogy">
diff --git a/doc/interpreter/HTML/doc_002dsemilogyerr.html b/doc/interpreter/HTML/doc_002dsemilogyerr.html
new file mode 100644
index 0000000..48230c2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsemilogyerr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dsemilogyerr">
diff --git a/doc/interpreter/HTML/doc_002dset.html b/doc/interpreter/HTML/doc_002dset.html
new file mode 100644
index 0000000..9270f53
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dset.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dset">
diff --git a/doc/interpreter/HTML/doc_002dsetaudio.html b/doc/interpreter/HTML/doc_002dsetaudio.html
new file mode 100644
index 0000000..17ba99e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsetaudio.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dsetaudio">
diff --git a/doc/interpreter/HTML/doc_002dsetdiff.html b/doc/interpreter/HTML/doc_002dsetdiff.html
new file mode 100644
index 0000000..5e06cea
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsetdiff.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Set-Operations.html#doc%2dsetdiff">
diff --git a/doc/interpreter/HTML/doc_002dsetfield.html b/doc/interpreter/HTML/doc_002dsetfield.html
new file mode 100644
index 0000000..611c319
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsetfield.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2dsetfield">
diff --git a/doc/interpreter/HTML/doc_002dsetgrent.html b/doc/interpreter/HTML/doc_002dsetgrent.html
new file mode 100644
index 0000000..196aaf7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsetgrent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Group-Database-Functions.html#doc%2dsetgrent">
diff --git a/doc/interpreter/HTML/doc_002dsetpwent.html b/doc/interpreter/HTML/doc_002dsetpwent.html
new file mode 100644
index 0000000..5016626
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsetpwent.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Password-Database-Functions.html#doc%2dsetpwent">
diff --git a/doc/interpreter/HTML/doc_002dsetxor.html b/doc/interpreter/HTML/doc_002dsetxor.html
new file mode 100644
index 0000000..3d8ebc3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsetxor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Set-Operations.html#doc%2dsetxor">
diff --git a/doc/interpreter/HTML/doc_002dshading.html b/doc/interpreter/HTML/doc_002dshading.html
new file mode 100644
index 0000000..be3022b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dshading.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dshading">
diff --git a/doc/interpreter/HTML/doc_002dshg.html b/doc/interpreter/HTML/doc_002dshg.html
new file mode 100644
index 0000000..c5e74d6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dshg.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dshg">
diff --git a/doc/interpreter/HTML/doc_002dshift.html b/doc/interpreter/HTML/doc_002dshift.html
new file mode 100644
index 0000000..aee62db
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dshift.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dshift">
diff --git a/doc/interpreter/HTML/doc_002dshiftdim.html b/doc/interpreter/HTML/doc_002dshiftdim.html
new file mode 100644
index 0000000..691f71b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dshiftdim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dshiftdim">
diff --git a/doc/interpreter/HTML/doc_002dsighup_005fdumps_005foctave_005fcore.html b/doc/interpreter/HTML/doc_002dsighup_005fdumps_005foctave_005fcore.html
new file mode 100644
index 0000000..12a40d9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsighup_005fdumps_005foctave_005fcore.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Saving-Data-on-Unexpected-Exits.html#doc%2dsighup%5fdumps%5foctave%5fcore">
diff --git a/doc/interpreter/HTML/doc_002dsign.html b/doc/interpreter/HTML/doc_002dsign.html
new file mode 100644
index 0000000..e45fd12
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsign.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Utility-Functions.html#doc%2dsign">
diff --git a/doc/interpreter/HTML/doc_002dsign_005ftest.html b/doc/interpreter/HTML/doc_002dsign_005ftest.html
new file mode 100644
index 0000000..d922ce0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsign_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dsign%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dsigterm_005fdumps_005foctave_005fcore.html b/doc/interpreter/HTML/doc_002dsigterm_005fdumps_005foctave_005fcore.html
new file mode 100644
index 0000000..38bebc9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsigterm_005fdumps_005foctave_005fcore.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Saving-Data-on-Unexpected-Exits.html#doc%2dsigterm%5fdumps%5foctave%5fcore">
diff --git a/doc/interpreter/HTML/doc_002dsilent_005ffunctions.html b/doc/interpreter/HTML/doc_002dsilent_005ffunctions.html
new file mode 100644
index 0000000..ded22c0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsilent_005ffunctions.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Defining-Functions.html#doc%2dsilent%5ffunctions">
diff --git a/doc/interpreter/HTML/doc_002dsin.html b/doc/interpreter/HTML/doc_002dsin.html
new file mode 100644
index 0000000..112bdb6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dsin">
diff --git a/doc/interpreter/HTML/doc_002dsinc.html b/doc/interpreter/HTML/doc_002dsinc.html
new file mode 100644
index 0000000..e6182f8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsinc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dsinc">
diff --git a/doc/interpreter/HTML/doc_002dsind.html b/doc/interpreter/HTML/doc_002dsind.html
new file mode 100644
index 0000000..0eb155b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dsind">
diff --git a/doc/interpreter/HTML/doc_002dsinetone.html b/doc/interpreter/HTML/doc_002dsinetone.html
new file mode 100644
index 0000000..41438d7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsinetone.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dsinetone">
diff --git a/doc/interpreter/HTML/doc_002dsinewave.html b/doc/interpreter/HTML/doc_002dsinewave.html
new file mode 100644
index 0000000..003602a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsinewave.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dsinewave">
diff --git a/doc/interpreter/HTML/doc_002dsingle.html b/doc/interpreter/HTML/doc_002dsingle.html
new file mode 100644
index 0000000..06d8682
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsingle.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Single-Precision-Data-Types.html#doc%2dsingle">
diff --git a/doc/interpreter/HTML/doc_002dsinh.html b/doc/interpreter/HTML/doc_002dsinh.html
new file mode 100644
index 0000000..26ddb23
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsinh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dsinh">
diff --git a/doc/interpreter/HTML/doc_002dsize.html b/doc/interpreter/HTML/doc_002dsize.html
new file mode 100644
index 0000000..b252084
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsize.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dsize">
diff --git a/doc/interpreter/HTML/doc_002dsize_005fequal.html b/doc/interpreter/HTML/doc_002dsize_005fequal.html
new file mode 100644
index 0000000..0df9676
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsize_005fequal.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dsize%5fequal">
diff --git a/doc/interpreter/HTML/doc_002dsizeof.html b/doc/interpreter/HTML/doc_002dsizeof.html
new file mode 100644
index 0000000..b7b86bd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsizeof.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dsizeof">
diff --git a/doc/interpreter/HTML/doc_002dskewness.html b/doc/interpreter/HTML/doc_002dskewness.html
new file mode 100644
index 0000000..369b8fe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dskewness.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dskewness">
diff --git a/doc/interpreter/HTML/doc_002dsleep.html b/doc/interpreter/HTML/doc_002dsleep.html
new file mode 100644
index 0000000..be91e9c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsleep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dsleep">
diff --git a/doc/interpreter/HTML/doc_002dslice.html b/doc/interpreter/HTML/doc_002dslice.html
new file mode 100644
index 0000000..14829a7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dslice.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dslice">
diff --git a/doc/interpreter/HTML/doc_002dsombrero.html b/doc/interpreter/HTML/doc_002dsombrero.html
new file mode 100644
index 0000000..faee93d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsombrero.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Test-Plotting-Functions.html#doc%2dsombrero">
diff --git a/doc/interpreter/HTML/doc_002dsort.html b/doc/interpreter/HTML/doc_002dsort.html
new file mode 100644
index 0000000..df70de7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsort.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dsort">
diff --git a/doc/interpreter/HTML/doc_002dsortrows.html b/doc/interpreter/HTML/doc_002dsortrows.html
new file mode 100644
index 0000000..8a7c459
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsortrows.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dsortrows">
diff --git a/doc/interpreter/HTML/doc_002dsource.html b/doc/interpreter/HTML/doc_002dsource.html
new file mode 100644
index 0000000..24d92a1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsource.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Script-Files.html#doc%2dsource">
diff --git a/doc/interpreter/HTML/doc_002dspalloc.html b/doc/interpreter/HTML/doc_002dspalloc.html
new file mode 100644
index 0000000..bdddfe8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspalloc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspalloc">
diff --git a/doc/interpreter/HTML/doc_002dsparse.html b/doc/interpreter/HTML/doc_002dsparse.html
new file mode 100644
index 0000000..7cb003e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsparse.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dsparse">
diff --git a/doc/interpreter/HTML/doc_002dsparse_005fauto_005fmutate.html b/doc/interpreter/HTML/doc_002dsparse_005fauto_005fmutate.html
new file mode 100644
index 0000000..3c819fb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsparse_005fauto_005fmutate.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Return-Types-of-Operators-and-Functions.html#doc%2dsparse%5fauto%5fmutate">
diff --git a/doc/interpreter/HTML/doc_002dspaugment.html b/doc/interpreter/HTML/doc_002dspaugment.html
new file mode 100644
index 0000000..2829a02
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspaugment.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dspaugment">
diff --git a/doc/interpreter/HTML/doc_002dspconvert.html b/doc/interpreter/HTML/doc_002dspconvert.html
new file mode 100644
index 0000000..d21cf9f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspconvert.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspconvert">
diff --git a/doc/interpreter/HTML/doc_002dspdiags.html b/doc/interpreter/HTML/doc_002dspdiags.html
new file mode 100644
index 0000000..c836e32
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspdiags.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspdiags">
diff --git a/doc/interpreter/HTML/doc_002dspearman.html b/doc/interpreter/HTML/doc_002dspearman.html
new file mode 100644
index 0000000..e66cc5b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspearman.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dspearman">
diff --git a/doc/interpreter/HTML/doc_002dspectral_005fadf.html b/doc/interpreter/HTML/doc_002dspectral_005fadf.html
new file mode 100644
index 0000000..d5936a9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspectral_005fadf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dspectral%5fadf">
diff --git a/doc/interpreter/HTML/doc_002dspectral_005fxdf.html b/doc/interpreter/HTML/doc_002dspectral_005fxdf.html
new file mode 100644
index 0000000..3b62b5d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspectral_005fxdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dspectral%5fxdf">
diff --git a/doc/interpreter/HTML/doc_002dspecular.html b/doc/interpreter/HTML/doc_002dspecular.html
new file mode 100644
index 0000000..347c940
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspecular.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dspecular">
diff --git a/doc/interpreter/HTML/doc_002dspeed.html b/doc/interpreter/HTML/doc_002dspeed.html
new file mode 100644
index 0000000..74bef07
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspeed.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Demonstration-Functions.html#doc%2dspeed">
diff --git a/doc/interpreter/HTML/doc_002dspencer.html b/doc/interpreter/HTML/doc_002dspencer.html
new file mode 100644
index 0000000..5af62c9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspencer.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dspencer">
diff --git a/doc/interpreter/HTML/doc_002dspeye.html b/doc/interpreter/HTML/doc_002dspeye.html
new file mode 100644
index 0000000..2e5467f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspeye.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspeye">
diff --git a/doc/interpreter/HTML/doc_002dspfun.html b/doc/interpreter/HTML/doc_002dspfun.html
new file mode 100644
index 0000000..6c3ffc6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspfun.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspfun">
diff --git a/doc/interpreter/HTML/doc_002dsph2cart.html b/doc/interpreter/HTML/doc_002dsph2cart.html
new file mode 100644
index 0000000..eeb6d1a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsph2cart.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Coordinate-Transformations.html#doc%2dsph2cart">
diff --git a/doc/interpreter/HTML/doc_002dsphere.html b/doc/interpreter/HTML/doc_002dsphere.html
new file mode 100644
index 0000000..5415017
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsphere.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002ddimensional-Geometric-Shapes.html#doc%2dsphere">
diff --git a/doc/interpreter/HTML/doc_002dspinmap.html b/doc/interpreter/HTML/doc_002dspinmap.html
new file mode 100644
index 0000000..93b61f0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspinmap.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dspinmap">
diff --git a/doc/interpreter/HTML/doc_002dspline.html b/doc/interpreter/HTML/doc_002dspline.html
new file mode 100644
index 0000000..ba2f6e2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspline.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=One_002ddimensional-Interpolation.html#doc%2dspline">
diff --git a/doc/interpreter/HTML/doc_002dsplit_005flong_005frows.html b/doc/interpreter/HTML/doc_002dsplit_005flong_005frows.html
new file mode 100644
index 0000000..b3ff81f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsplit_005flong_005frows.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrices.html#doc%2dsplit%5flong%5frows">
diff --git a/doc/interpreter/HTML/doc_002dspmax.html b/doc/interpreter/HTML/doc_002dspmax.html
new file mode 100644
index 0000000..4bd22cc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspmax.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspmax">
diff --git a/doc/interpreter/HTML/doc_002dspmin.html b/doc/interpreter/HTML/doc_002dspmin.html
new file mode 100644
index 0000000..35c17b0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspmin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspmin">
diff --git a/doc/interpreter/HTML/doc_002dspones.html b/doc/interpreter/HTML/doc_002dspones.html
new file mode 100644
index 0000000..2822308
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspones.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dspones">
diff --git a/doc/interpreter/HTML/doc_002dspparms.html b/doc/interpreter/HTML/doc_002dspparms.html
new file mode 100644
index 0000000..0c43bdc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspparms.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dspparms">
diff --git a/doc/interpreter/HTML/doc_002dsprand.html b/doc/interpreter/HTML/doc_002dsprand.html
new file mode 100644
index 0000000..922406a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsprand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dsprand">
diff --git a/doc/interpreter/HTML/doc_002dsprandn.html b/doc/interpreter/HTML/doc_002dsprandn.html
new file mode 100644
index 0000000..b523afe
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsprandn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dsprandn">
diff --git a/doc/interpreter/HTML/doc_002dsprandsym.html b/doc/interpreter/HTML/doc_002dsprandsym.html
new file mode 100644
index 0000000..64f399a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsprandsym.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Sparse-Matrices.html#doc%2dsprandsym">
diff --git a/doc/interpreter/HTML/doc_002dsprank.html b/doc/interpreter/HTML/doc_002dsprank.html
new file mode 100644
index 0000000..e25e849
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsprank.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dsprank">
diff --git a/doc/interpreter/HTML/doc_002dspring.html b/doc/interpreter/HTML/doc_002dspring.html
new file mode 100644
index 0000000..1712c40
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspring.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dspring">
diff --git a/doc/interpreter/HTML/doc_002dsprintf.html b/doc/interpreter/HTML/doc_002dsprintf.html
new file mode 100644
index 0000000..8fa345f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsprintf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Formatted-Output.html#doc%2dsprintf">
diff --git a/doc/interpreter/HTML/doc_002dspstats.html b/doc/interpreter/HTML/doc_002dspstats.html
new file mode 100644
index 0000000..c346960
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspstats.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dspstats">
diff --git a/doc/interpreter/HTML/doc_002dspy.html b/doc/interpreter/HTML/doc_002dspy.html
new file mode 100644
index 0000000..97c36e1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dspy.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dspy">
diff --git a/doc/interpreter/HTML/doc_002dsqp.html b/doc/interpreter/HTML/doc_002dsqp.html
new file mode 100644
index 0000000..ae11300
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsqp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Nonlinear-Programming.html#doc%2dsqp">
diff --git a/doc/interpreter/HTML/doc_002dsqrt.html b/doc/interpreter/HTML/doc_002dsqrt.html
new file mode 100644
index 0000000..5c77b8d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsqrt.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Exponents-and-Logarithms.html#doc%2dsqrt">
diff --git a/doc/interpreter/HTML/doc_002dsqrtm.html b/doc/interpreter/HTML/doc_002dsqrtm.html
new file mode 100644
index 0000000..4b558de
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsqrtm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-a-Matrix.html#doc%2dsqrtm">
diff --git a/doc/interpreter/HTML/doc_002dsqueeze.html b/doc/interpreter/HTML/doc_002dsqueeze.html
new file mode 100644
index 0000000..a86d81e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsqueeze.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Object-Sizes.html#doc%2dsqueeze">
diff --git a/doc/interpreter/HTML/doc_002dsscanf.html b/doc/interpreter/HTML/doc_002dsscanf.html
new file mode 100644
index 0000000..e819388
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsscanf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Formatted-Input.html#doc%2dsscanf">
diff --git a/doc/interpreter/HTML/doc_002dstairs.html b/doc/interpreter/HTML/doc_002dstairs.html
new file mode 100644
index 0000000..92f6a29
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstairs.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dstairs">
diff --git a/doc/interpreter/HTML/doc_002dstat.html b/doc/interpreter/HTML/doc_002dstat.html
new file mode 100644
index 0000000..4060ade
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dstat">
diff --git a/doc/interpreter/HTML/doc_002dstatistics.html b/doc/interpreter/HTML/doc_002dstatistics.html
new file mode 100644
index 0000000..7ff8670
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstatistics.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dstatistics">
diff --git a/doc/interpreter/HTML/doc_002dstd.html b/doc/interpreter/HTML/doc_002dstd.html
new file mode 100644
index 0000000..1d111ee
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dstd">
diff --git a/doc/interpreter/HTML/doc_002dstderr.html b/doc/interpreter/HTML/doc_002dstderr.html
new file mode 100644
index 0000000..a1a9e35
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstderr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=C_002dStyle-I_002fO-Functions.html#doc%2dstderr">
diff --git a/doc/interpreter/HTML/doc_002dstdin.html b/doc/interpreter/HTML/doc_002dstdin.html
new file mode 100644
index 0000000..ca6f963
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstdin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=C_002dStyle-I_002fO-Functions.html#doc%2dstdin">
diff --git a/doc/interpreter/HTML/doc_002dstdout.html b/doc/interpreter/HTML/doc_002dstdout.html
new file mode 100644
index 0000000..a2aa655
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstdout.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=C_002dStyle-I_002fO-Functions.html#doc%2dstdout">
diff --git a/doc/interpreter/HTML/doc_002dstem.html b/doc/interpreter/HTML/doc_002dstem.html
new file mode 100644
index 0000000..5116f68
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstem.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dstem">
diff --git a/doc/interpreter/HTML/doc_002dstem3.html b/doc/interpreter/HTML/doc_002dstem3.html
new file mode 100644
index 0000000..34ce187
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstem3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dstem3">
diff --git a/doc/interpreter/HTML/doc_002dstft.html b/doc/interpreter/HTML/doc_002dstft.html
new file mode 100644
index 0000000..49fecf7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstft.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dstft">
diff --git a/doc/interpreter/HTML/doc_002dstr2double.html b/doc/interpreter/HTML/doc_002dstr2double.html
new file mode 100644
index 0000000..6369530
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstr2double.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dstr2double">
diff --git a/doc/interpreter/HTML/doc_002dstr2func.html b/doc/interpreter/HTML/doc_002dstr2func.html
new file mode 100644
index 0000000..4ca7fc5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstr2func.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Function-Handles.html#doc%2dstr2func">
diff --git a/doc/interpreter/HTML/doc_002dstr2num.html b/doc/interpreter/HTML/doc_002dstr2num.html
new file mode 100644
index 0000000..55a25c0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstr2num.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dstr2num">
diff --git a/doc/interpreter/HTML/doc_002dstrcat.html b/doc/interpreter/HTML/doc_002dstrcat.html
new file mode 100644
index 0000000..1660164
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrcat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Concatenating-Strings.html#doc%2dstrcat">
diff --git a/doc/interpreter/HTML/doc_002dstrchr.html b/doc/interpreter/HTML/doc_002dstrchr.html
new file mode 100644
index 0000000..a0aaf65
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrchr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrchr">
diff --git a/doc/interpreter/HTML/doc_002dstrcmp.html b/doc/interpreter/HTML/doc_002dstrcmp.html
new file mode 100644
index 0000000..2bc5bfc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrcmp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparing-Strings.html#doc%2dstrcmp">
diff --git a/doc/interpreter/HTML/doc_002dstrcmpi.html b/doc/interpreter/HTML/doc_002dstrcmpi.html
new file mode 100644
index 0000000..1160bad
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrcmpi.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparing-Strings.html#doc%2dstrcmpi">
diff --git a/doc/interpreter/HTML/doc_002dstrfind.html b/doc/interpreter/HTML/doc_002dstrfind.html
new file mode 100644
index 0000000..ffd161d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrfind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrfind">
diff --git a/doc/interpreter/HTML/doc_002dstrftime.html b/doc/interpreter/HTML/doc_002dstrftime.html
new file mode 100644
index 0000000..37106d5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrftime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dstrftime">
diff --git a/doc/interpreter/HTML/doc_002dstring_005ffill_005fchar.html b/doc/interpreter/HTML/doc_002dstring_005ffill_005fchar.html
new file mode 100644
index 0000000..46a596b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstring_005ffill_005fchar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Character-Arrays.html#doc%2dstring%5ffill%5fchar">
diff --git a/doc/interpreter/HTML/doc_002dstrjust.html b/doc/interpreter/HTML/doc_002dstrjust.html
new file mode 100644
index 0000000..3cf4bef
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrjust.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dstrjust">
diff --git a/doc/interpreter/HTML/doc_002dstrmatch.html b/doc/interpreter/HTML/doc_002dstrmatch.html
new file mode 100644
index 0000000..ec633bf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrmatch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrmatch">
diff --git a/doc/interpreter/HTML/doc_002dstrncmp.html b/doc/interpreter/HTML/doc_002dstrncmp.html
new file mode 100644
index 0000000..25ecfce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrncmp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparing-Strings.html#doc%2dstrncmp">
diff --git a/doc/interpreter/HTML/doc_002dstrncmpi.html b/doc/interpreter/HTML/doc_002dstrncmpi.html
new file mode 100644
index 0000000..a7d954a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrncmpi.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparing-Strings.html#doc%2dstrncmpi">
diff --git a/doc/interpreter/HTML/doc_002dstrptime.html b/doc/interpreter/HTML/doc_002dstrptime.html
new file mode 100644
index 0000000..b841660
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrptime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dstrptime">
diff --git a/doc/interpreter/HTML/doc_002dstrrep.html b/doc/interpreter/HTML/doc_002dstrrep.html
new file mode 100644
index 0000000..f91a1cf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrrep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrrep">
diff --git a/doc/interpreter/HTML/doc_002dstrsplit.html b/doc/interpreter/HTML/doc_002dstrsplit.html
new file mode 100644
index 0000000..4fe86cb
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrsplit.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrsplit">
diff --git a/doc/interpreter/HTML/doc_002dstrtok.html b/doc/interpreter/HTML/doc_002dstrtok.html
new file mode 100644
index 0000000..656a506
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrtok.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrtok">
diff --git a/doc/interpreter/HTML/doc_002dstrtrim.html b/doc/interpreter/HTML/doc_002dstrtrim.html
new file mode 100644
index 0000000..ed4eef3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrtrim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrtrim">
diff --git a/doc/interpreter/HTML/doc_002dstrtrunc.html b/doc/interpreter/HTML/doc_002dstrtrunc.html
new file mode 100644
index 0000000..a90822c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrtrunc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dstrtrunc">
diff --git a/doc/interpreter/HTML/doc_002dstruct.html b/doc/interpreter/HTML/doc_002dstruct.html
new file mode 100644
index 0000000..53bb746
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstruct.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Creating-Structures.html#doc%2dstruct">
diff --git a/doc/interpreter/HTML/doc_002dstruct2cell.html b/doc/interpreter/HTML/doc_002dstruct2cell.html
new file mode 100644
index 0000000..c1035cc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstruct2cell.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Processing-Data-in-Structures.html#doc%2dstruct2cell">
diff --git a/doc/interpreter/HTML/doc_002dstruct_005flevels_005fto_005fprint.html b/doc/interpreter/HTML/doc_002dstruct_005flevels_005fto_005fprint.html
new file mode 100644
index 0000000..5e7324a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstruct_005flevels_005fto_005fprint.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Usage-and-Examples.html#doc%2dstruct%5flevels%5fto%5fprint">
diff --git a/doc/interpreter/HTML/doc_002dstructfun.html b/doc/interpreter/HTML/doc_002dstructfun.html
new file mode 100644
index 0000000..cb439c9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstructfun.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Processing-Data-in-Structures.html#doc%2dstructfun">
diff --git a/doc/interpreter/HTML/doc_002dstrvcat.html b/doc/interpreter/HTML/doc_002dstrvcat.html
new file mode 100644
index 0000000..fb532b0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstrvcat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Concatenating-Strings.html#doc%2dstrvcat">
diff --git a/doc/interpreter/HTML/doc_002dstudentize.html b/doc/interpreter/HTML/doc_002dstudentize.html
new file mode 100644
index 0000000..3ba6c00
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dstudentize.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dstudentize">
diff --git a/doc/interpreter/HTML/doc_002dsub2ind.html b/doc/interpreter/HTML/doc_002dsub2ind.html
new file mode 100644
index 0000000..dc293cc
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsub2ind.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Index-Expressions.html#doc%2dsub2ind">
diff --git a/doc/interpreter/HTML/doc_002dsubplot.html b/doc/interpreter/HTML/doc_002dsubplot.html
new file mode 100644
index 0000000..da3ea79
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Plots-on-One-Page.html#doc%2dsubplot">
diff --git a/doc/interpreter/HTML/doc_002dsubsasgn.html b/doc/interpreter/HTML/doc_002dsubsasgn.html
new file mode 100644
index 0000000..013d711
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubsasgn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Indexing-Objects.html#doc%2dsubsasgn">
diff --git a/doc/interpreter/HTML/doc_002dsubsindex.html b/doc/interpreter/HTML/doc_002dsubsindex.html
new file mode 100644
index 0000000..bb174c1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubsindex.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Indexing-Objects.html#doc%2dsubsindex">
diff --git a/doc/interpreter/HTML/doc_002dsubspace.html b/doc/interpreter/HTML/doc_002dsubspace.html
new file mode 100644
index 0000000..a1b0e6c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubspace.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dsubspace">
diff --git a/doc/interpreter/HTML/doc_002dsubsref.html b/doc/interpreter/HTML/doc_002dsubsref.html
new file mode 100644
index 0000000..9c3f6dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubsref.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Indexing-Objects.html#doc%2dsubsref">
diff --git a/doc/interpreter/HTML/doc_002dsubstr.html b/doc/interpreter/HTML/doc_002dsubstr.html
new file mode 100644
index 0000000..4db7429
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubstr.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Strings.html#doc%2dsubstr">
diff --git a/doc/interpreter/HTML/doc_002dsubstruct.html b/doc/interpreter/HTML/doc_002dsubstruct.html
new file mode 100644
index 0000000..f6f36a9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsubstruct.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Manipulating-Structures.html#doc%2dsubstruct">
diff --git a/doc/interpreter/HTML/doc_002dsum.html b/doc/interpreter/HTML/doc_002dsum.html
new file mode 100644
index 0000000..4b98176
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsum.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sums-and-Products.html#doc%2dsum">
diff --git a/doc/interpreter/HTML/doc_002dsummer.html b/doc/interpreter/HTML/doc_002dsummer.html
new file mode 100644
index 0000000..c0f476b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsummer.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dsummer">
diff --git a/doc/interpreter/HTML/doc_002dsumsq.html b/doc/interpreter/HTML/doc_002dsumsq.html
new file mode 100644
index 0000000..6a2c3ba
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsumsq.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sums-and-Products.html#doc%2dsumsq">
diff --git a/doc/interpreter/HTML/doc_002dsuperiorto.html b/doc/interpreter/HTML/doc_002dsuperiorto.html
new file mode 100644
index 0000000..a61387d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsuperiorto.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Precedence-of-Objects.html#doc%2dsuperiorto">
diff --git a/doc/interpreter/HTML/doc_002dsuppress_005fverbose_005fhelp_005fmessage.html b/doc/interpreter/HTML/doc_002dsuppress_005fverbose_005fhelp_005fmessage.html
new file mode 100644
index 0000000..1537ac5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsuppress_005fverbose_005fhelp_005fmessage.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dsuppress%5fverbose%5fhelp%5fmessage">
diff --git a/doc/interpreter/HTML/doc_002dsurf.html b/doc/interpreter/HTML/doc_002dsurf.html
new file mode 100644
index 0000000..8748834
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsurf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dsurf">
diff --git a/doc/interpreter/HTML/doc_002dsurface.html b/doc/interpreter/HTML/doc_002dsurface.html
new file mode 100644
index 0000000..1eb346b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsurface.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Graphics-Objects.html#doc%2dsurface">
diff --git a/doc/interpreter/HTML/doc_002dsurfc.html b/doc/interpreter/HTML/doc_002dsurfc.html
new file mode 100644
index 0000000..acf0dd3
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsurfc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dsurfc">
diff --git a/doc/interpreter/HTML/doc_002dsurfl.html b/doc/interpreter/HTML/doc_002dsurfl.html
new file mode 100644
index 0000000..9e1bbef
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsurfl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dsurfl">
diff --git a/doc/interpreter/HTML/doc_002dsurfnorm.html b/doc/interpreter/HTML/doc_002dsurfnorm.html
new file mode 100644
index 0000000..434814b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsurfnorm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dsurfnorm">
diff --git a/doc/interpreter/HTML/doc_002dsvd.html b/doc/interpreter/HTML/doc_002dsvd.html
new file mode 100644
index 0000000..b64125d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsvd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Matrix-Factorizations.html#doc%2dsvd">
diff --git a/doc/interpreter/HTML/doc_002dsvds.html b/doc/interpreter/HTML/doc_002dsvds.html
new file mode 100644
index 0000000..602ee2e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsvds.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dsvds">
diff --git a/doc/interpreter/HTML/doc_002dswapbytes.html b/doc/interpreter/HTML/doc_002dswapbytes.html
new file mode 100644
index 0000000..b67c4d6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dswapbytes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Built_002din-Data-Types.html#doc%2dswapbytes">
diff --git a/doc/interpreter/HTML/doc_002dsyl.html b/doc/interpreter/HTML/doc_002dsyl.html
new file mode 100644
index 0000000..b52a86a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsyl.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-a-Matrix.html#doc%2dsyl">
diff --git a/doc/interpreter/HTML/doc_002dsylvester_005fmatrix.html b/doc/interpreter/HTML/doc_002dsylvester_005fmatrix.html
new file mode 100644
index 0000000..1e0dc90
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsylvester_005fmatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dsylvester%5fmatrix">
diff --git a/doc/interpreter/HTML/doc_002dsymamd.html b/doc/interpreter/HTML/doc_002dsymamd.html
new file mode 100644
index 0000000..b7fdf6a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsymamd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2dsymamd">
diff --git a/doc/interpreter/HTML/doc_002dsymbfact.html b/doc/interpreter/HTML/doc_002dsymbfact.html
new file mode 100644
index 0000000..08abe8f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsymbfact.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sparse-Linear-Algebra.html#doc%2dsymbfact">
diff --git a/doc/interpreter/HTML/doc_002dsymlink.html b/doc/interpreter/HTML/doc_002dsymlink.html
new file mode 100644
index 0000000..eae168d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsymlink.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dsymlink">
diff --git a/doc/interpreter/HTML/doc_002dsymrcm.html b/doc/interpreter/HTML/doc_002dsymrcm.html
new file mode 100644
index 0000000..add8a58
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsymrcm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#doc%2dsymrcm">
diff --git a/doc/interpreter/HTML/doc_002dsymvar.html b/doc/interpreter/HTML/doc_002dsymvar.html
new file mode 100644
index 0000000..6dde37b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsymvar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Inline-Functions.html#doc%2dsymvar">
diff --git a/doc/interpreter/HTML/doc_002dsynthesis.html b/doc/interpreter/HTML/doc_002dsynthesis.html
new file mode 100644
index 0000000..0015674
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsynthesis.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dsynthesis">
diff --git a/doc/interpreter/HTML/doc_002dsystem.html b/doc/interpreter/HTML/doc_002dsystem.html
new file mode 100644
index 0000000..cc98bbf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dsystem.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dsystem">
diff --git a/doc/interpreter/HTML/doc_002dt_005ftest.html b/doc/interpreter/HTML/doc_002dt_005ftest.html
new file mode 100644
index 0000000..f9162d4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dt_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dt%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dt_005ftest_005f2.html b/doc/interpreter/HTML/doc_002dt_005ftest_005f2.html
new file mode 100644
index 0000000..61a5f6c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dt_005ftest_005f2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dt%5ftest%5f2">
diff --git a/doc/interpreter/HTML/doc_002dt_005ftest_005fregression.html b/doc/interpreter/HTML/doc_002dt_005ftest_005fregression.html
new file mode 100644
index 0000000..5c59bb6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dt_005ftest_005fregression.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dt%5ftest%5fregression">
diff --git a/doc/interpreter/HTML/doc_002dtable.html b/doc/interpreter/HTML/doc_002dtable.html
new file mode 100644
index 0000000..72ae3b5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtable.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dtable">
diff --git a/doc/interpreter/HTML/doc_002dtan.html b/doc/interpreter/HTML/doc_002dtan.html
new file mode 100644
index 0000000..0c05998
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtan.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dtan">
diff --git a/doc/interpreter/HTML/doc_002dtand.html b/doc/interpreter/HTML/doc_002dtand.html
new file mode 100644
index 0000000..477be13
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dtand">
diff --git a/doc/interpreter/HTML/doc_002dtanh.html b/doc/interpreter/HTML/doc_002dtanh.html
new file mode 100644
index 0000000..4628b4e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtanh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Trigonometry.html#doc%2dtanh">
diff --git a/doc/interpreter/HTML/doc_002dtar.html b/doc/interpreter/HTML/doc_002dtar.html
new file mode 100644
index 0000000..caeb187
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dtar">
diff --git a/doc/interpreter/HTML/doc_002dtcdf.html b/doc/interpreter/HTML/doc_002dtcdf.html
new file mode 100644
index 0000000..3dc58bd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dtcdf">
diff --git a/doc/interpreter/HTML/doc_002dtempdir.html b/doc/interpreter/HTML/doc_002dtempdir.html
new file mode 100644
index 0000000..5691903
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtempdir.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dtempdir">
diff --git a/doc/interpreter/HTML/doc_002dtempname.html b/doc/interpreter/HTML/doc_002dtempname.html
new file mode 100644
index 0000000..8a9f02a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtempname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dtempname">
diff --git a/doc/interpreter/HTML/doc_002dtest.html b/doc/interpreter/HTML/doc_002dtest.html
new file mode 100644
index 0000000..57705c6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Test-Functions.html#doc%2dtest">
diff --git a/doc/interpreter/HTML/doc_002dtext.html b/doc/interpreter/HTML/doc_002dtext.html
new file mode 100644
index 0000000..6b34d0e
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtext.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dtext">
diff --git a/doc/interpreter/HTML/doc_002dtic.html b/doc/interpreter/HTML/doc_002dtic.html
new file mode 100644
index 0000000..b581f46
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtic.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dtic">
diff --git a/doc/interpreter/HTML/doc_002dtilde_005fexpand.html b/doc/interpreter/HTML/doc_002dtilde_005fexpand.html
new file mode 100644
index 0000000..cdd121a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtilde_005fexpand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dtilde%5fexpand">
diff --git a/doc/interpreter/HTML/doc_002dtime.html b/doc/interpreter/HTML/doc_002dtime.html
new file mode 100644
index 0000000..817f605
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtime.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dtime">
diff --git a/doc/interpreter/HTML/doc_002dtimes.html b/doc/interpreter/HTML/doc_002dtimes.html
new file mode 100644
index 0000000..125e51c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtimes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dtimes">
diff --git a/doc/interpreter/HTML/doc_002dtinv.html b/doc/interpreter/HTML/doc_002dtinv.html
new file mode 100644
index 0000000..6aa052d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dtinv">
diff --git a/doc/interpreter/HTML/doc_002dtitle.html b/doc/interpreter/HTML/doc_002dtitle.html
new file mode 100644
index 0000000..676193f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtitle.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dtitle">
diff --git a/doc/interpreter/HTML/doc_002dtmpfile.html b/doc/interpreter/HTML/doc_002dtmpfile.html
new file mode 100644
index 0000000..d1d2a2c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtmpfile.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Temporary-Files.html#doc%2dtmpfile">
diff --git a/doc/interpreter/HTML/doc_002dtmpnam.html b/doc/interpreter/HTML/doc_002dtmpnam.html
new file mode 100644
index 0000000..a7ed313
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtmpnam.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Temporary-Files.html#doc%2dtmpnam">
diff --git a/doc/interpreter/HTML/doc_002dtoascii.html b/doc/interpreter/HTML/doc_002dtoascii.html
new file mode 100644
index 0000000..0d1238f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtoascii.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dtoascii">
diff --git a/doc/interpreter/HTML/doc_002dtoc.html b/doc/interpreter/HTML/doc_002dtoc.html
new file mode 100644
index 0000000..6905daf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtoc.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dtoc">
diff --git a/doc/interpreter/HTML/doc_002dtoeplitz.html b/doc/interpreter/HTML/doc_002dtoeplitz.html
new file mode 100644
index 0000000..80a5253
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtoeplitz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dtoeplitz">
diff --git a/doc/interpreter/HTML/doc_002dtolower.html b/doc/interpreter/HTML/doc_002dtolower.html
new file mode 100644
index 0000000..c1abe25
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtolower.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dtolower">
diff --git a/doc/interpreter/HTML/doc_002dtoupper.html b/doc/interpreter/HTML/doc_002dtoupper.html
new file mode 100644
index 0000000..2dd0b12
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtoupper.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dtoupper">
diff --git a/doc/interpreter/HTML/doc_002dtpdf.html b/doc/interpreter/HTML/doc_002dtpdf.html
new file mode 100644
index 0000000..fc79ccd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dtpdf">
diff --git a/doc/interpreter/HTML/doc_002dtrace.html b/doc/interpreter/HTML/doc_002dtrace.html
new file mode 100644
index 0000000..55bb72f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtrace.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Matrix-Functions.html#doc%2dtrace">
diff --git a/doc/interpreter/HTML/doc_002dtranspose.html b/doc/interpreter/HTML/doc_002dtranspose.html
new file mode 100644
index 0000000..1226a2f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtranspose.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2dtranspose">
diff --git a/doc/interpreter/HTML/doc_002dtrapz.html b/doc/interpreter/HTML/doc_002dtrapz.html
new file mode 100644
index 0000000..cda6696
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtrapz.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-One-Variable.html#doc%2dtrapz">
diff --git a/doc/interpreter/HTML/doc_002dtreelayout.html b/doc/interpreter/HTML/doc_002dtreelayout.html
new file mode 100644
index 0000000..4f0623b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtreelayout.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dtreelayout">
diff --git a/doc/interpreter/HTML/doc_002dtreeplot.html b/doc/interpreter/HTML/doc_002dtreeplot.html
new file mode 100644
index 0000000..af3f713
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtreeplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#doc%2dtreeplot">
diff --git a/doc/interpreter/HTML/doc_002dtriangle_005flw.html b/doc/interpreter/HTML/doc_002dtriangle_005flw.html
new file mode 100644
index 0000000..1b35910
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtriangle_005flw.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dtriangle%5flw">
diff --git a/doc/interpreter/HTML/doc_002dtriangle_005fsw.html b/doc/interpreter/HTML/doc_002dtriangle_005fsw.html
new file mode 100644
index 0000000..6d6d93d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtriangle_005fsw.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dtriangle%5fsw">
diff --git a/doc/interpreter/HTML/doc_002dtril.html b/doc/interpreter/HTML/doc_002dtril.html
new file mode 100644
index 0000000..8234fea
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtril.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dtril">
diff --git a/doc/interpreter/HTML/doc_002dtrimesh.html b/doc/interpreter/HTML/doc_002dtrimesh.html
new file mode 100644
index 0000000..45dc5aa
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtrimesh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plotting-the-Triangulation.html#doc%2dtrimesh">
diff --git a/doc/interpreter/HTML/doc_002dtriplequad.html b/doc/interpreter/HTML/doc_002dtriplequad.html
new file mode 100644
index 0000000..fcc4f1f
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtriplequad.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Functions-of-Multiple-Variables.html#doc%2dtriplequad">
diff --git a/doc/interpreter/HTML/doc_002dtriplot.html b/doc/interpreter/HTML/doc_002dtriplot.html
new file mode 100644
index 0000000..bd1bc85
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtriplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plotting-the-Triangulation.html#doc%2dtriplot">
diff --git a/doc/interpreter/HTML/doc_002dtriu.html b/doc/interpreter/HTML/doc_002dtriu.html
new file mode 100644
index 0000000..d816fdd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtriu.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dtriu">
diff --git a/doc/interpreter/HTML/doc_002dtrnd.html b/doc/interpreter/HTML/doc_002dtrnd.html
new file mode 100644
index 0000000..048e3b6
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dtrnd">
diff --git a/doc/interpreter/HTML/doc_002dtrue.html b/doc/interpreter/HTML/doc_002dtrue.html
new file mode 100644
index 0000000..b1976e7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtrue.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Logical-Values.html#doc%2dtrue">
diff --git a/doc/interpreter/HTML/doc_002dtsearch.html b/doc/interpreter/HTML/doc_002dtsearch.html
new file mode 100644
index 0000000..a745618
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtsearch.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Identifying-points-in-Triangulation.html#doc%2dtsearch">
diff --git a/doc/interpreter/HTML/doc_002dtsearchn.html b/doc/interpreter/HTML/doc_002dtsearchn.html
new file mode 100644
index 0000000..7799013
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtsearchn.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Identifying-points-in-Triangulation.html#doc%2dtsearchn">
diff --git a/doc/interpreter/HTML/doc_002dtype.html b/doc/interpreter/HTML/doc_002dtype.html
new file mode 100644
index 0000000..dd31d4a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtype.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dtype">
diff --git a/doc/interpreter/HTML/doc_002dtypecast.html b/doc/interpreter/HTML/doc_002dtypecast.html
new file mode 100644
index 0000000..6c82254
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtypecast.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Built_002din-Data-Types.html#doc%2dtypecast">
diff --git a/doc/interpreter/HTML/doc_002dtypeinfo.html b/doc/interpreter/HTML/doc_002dtypeinfo.html
new file mode 100644
index 0000000..9ef60f8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dtypeinfo.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Data-Types.html#doc%2dtypeinfo">
diff --git a/doc/interpreter/HTML/doc_002du_005ftest.html b/doc/interpreter/HTML/doc_002du_005ftest.html
new file mode 100644
index 0000000..82e6d8d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002du_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2du%5ftest">
diff --git a/doc/interpreter/HTML/doc_002duint16.html b/doc/interpreter/HTML/doc_002duint16.html
new file mode 100644
index 0000000..3155779
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duint16.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2duint16">
diff --git a/doc/interpreter/HTML/doc_002duint32.html b/doc/interpreter/HTML/doc_002duint32.html
new file mode 100644
index 0000000..20e09db
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duint32.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2duint32">
diff --git a/doc/interpreter/HTML/doc_002duint64.html b/doc/interpreter/HTML/doc_002duint64.html
new file mode 100644
index 0000000..9f0eae0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duint64.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2duint64">
diff --git a/doc/interpreter/HTML/doc_002duint8.html b/doc/interpreter/HTML/doc_002duint8.html
new file mode 100644
index 0000000..80451dd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duint8.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Integer-Data-Types.html#doc%2duint8">
diff --git a/doc/interpreter/HTML/doc_002dumask.html b/doc/interpreter/HTML/doc_002dumask.html
new file mode 100644
index 0000000..f9e8f17
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dumask.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dumask">
diff --git a/doc/interpreter/HTML/doc_002duminus.html b/doc/interpreter/HTML/doc_002duminus.html
new file mode 100644
index 0000000..bb295a1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duminus.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2duminus">
diff --git a/doc/interpreter/HTML/doc_002duname.html b/doc/interpreter/HTML/doc_002duname.html
new file mode 100644
index 0000000..8b7c374
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duname.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2duname">
diff --git a/doc/interpreter/HTML/doc_002dundo_005fstring_005fescapes.html b/doc/interpreter/HTML/doc_002dundo_005fstring_005fescapes.html
new file mode 100644
index 0000000..0194fa1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dundo_005fstring_005fescapes.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=String-Conversions.html#doc%2dundo%5fstring%5fescapes">
diff --git a/doc/interpreter/HTML/doc_002dunidcdf.html b/doc/interpreter/HTML/doc_002dunidcdf.html
new file mode 100644
index 0000000..57c874c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunidcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dunidcdf">
diff --git a/doc/interpreter/HTML/doc_002dunidinv.html b/doc/interpreter/HTML/doc_002dunidinv.html
new file mode 100644
index 0000000..e2e0ab9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunidinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dunidinv">
diff --git a/doc/interpreter/HTML/doc_002dunidpdf.html b/doc/interpreter/HTML/doc_002dunidpdf.html
new file mode 100644
index 0000000..a377eb1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunidpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dunidpdf">
diff --git a/doc/interpreter/HTML/doc_002dunidrnd.html b/doc/interpreter/HTML/doc_002dunidrnd.html
new file mode 100644
index 0000000..88ef8b5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunidrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dunidrnd">
diff --git a/doc/interpreter/HTML/doc_002dunifcdf.html b/doc/interpreter/HTML/doc_002dunifcdf.html
new file mode 100644
index 0000000..a673279
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunifcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dunifcdf">
diff --git a/doc/interpreter/HTML/doc_002dunifinv.html b/doc/interpreter/HTML/doc_002dunifinv.html
new file mode 100644
index 0000000..6ff9985
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunifinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dunifinv">
diff --git a/doc/interpreter/HTML/doc_002dunifpdf.html b/doc/interpreter/HTML/doc_002dunifpdf.html
new file mode 100644
index 0000000..a539a29
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunifpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dunifpdf">
diff --git a/doc/interpreter/HTML/doc_002dunifrnd.html b/doc/interpreter/HTML/doc_002dunifrnd.html
new file mode 100644
index 0000000..e2c344b
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunifrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dunifrnd">
diff --git a/doc/interpreter/HTML/doc_002dunion.html b/doc/interpreter/HTML/doc_002dunion.html
new file mode 100644
index 0000000..a3d9397
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunion.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Set-Operations.html#doc%2dunion">
diff --git a/doc/interpreter/HTML/doc_002dunique.html b/doc/interpreter/HTML/doc_002dunique.html
new file mode 100644
index 0000000..8d50b57
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunique.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Sets.html#doc%2dunique">
diff --git a/doc/interpreter/HTML/doc_002dunix.html b/doc/interpreter/HTML/doc_002dunix.html
new file mode 100644
index 0000000..d9cb82d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dunix">
diff --git a/doc/interpreter/HTML/doc_002dunlink.html b/doc/interpreter/HTML/doc_002dunlink.html
new file mode 100644
index 0000000..b00c300
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunlink.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Filesystem-Utilities.html#doc%2dunlink">
diff --git a/doc/interpreter/HTML/doc_002dunmark_005fcommand.html b/doc/interpreter/HTML/doc_002dunmark_005fcommand.html
new file mode 100644
index 0000000..4dcc61d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunmark_005fcommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands.html#doc%2dunmark%5fcommand">
diff --git a/doc/interpreter/HTML/doc_002dunmark_005frawcommand.html b/doc/interpreter/HTML/doc_002dunmark_005frawcommand.html
new file mode 100644
index 0000000..2ee19f1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunmark_005frawcommand.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Commands.html#doc%2dunmark%5frawcommand">
diff --git a/doc/interpreter/HTML/doc_002dunmkpp.html b/doc/interpreter/HTML/doc_002dunmkpp.html
new file mode 100644
index 0000000..e73da36
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunmkpp.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Polynomial-Interpolation.html#doc%2dunmkpp">
diff --git a/doc/interpreter/HTML/doc_002dunpack.html b/doc/interpreter/HTML/doc_002dunpack.html
new file mode 100644
index 0000000..d85142d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunpack.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dunpack">
diff --git a/doc/interpreter/HTML/doc_002duntar.html b/doc/interpreter/HTML/doc_002duntar.html
new file mode 100644
index 0000000..6409885
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duntar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2duntar">
diff --git a/doc/interpreter/HTML/doc_002dunwrap.html b/doc/interpreter/HTML/doc_002dunwrap.html
new file mode 100644
index 0000000..1ba1a73
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunwrap.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dunwrap">
diff --git a/doc/interpreter/HTML/doc_002dunzip.html b/doc/interpreter/HTML/doc_002dunzip.html
new file mode 100644
index 0000000..55009f4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dunzip.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dunzip">
diff --git a/doc/interpreter/HTML/doc_002duplus.html b/doc/interpreter/HTML/doc_002duplus.html
new file mode 100644
index 0000000..06380de
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002duplus.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#doc%2duplus">
diff --git a/doc/interpreter/HTML/doc_002durlread.html b/doc/interpreter/HTML/doc_002durlread.html
new file mode 100644
index 0000000..cee4493
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002durlread.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Networking-Utilities.html#doc%2durlread">
diff --git a/doc/interpreter/HTML/doc_002durlwrite.html b/doc/interpreter/HTML/doc_002durlwrite.html
new file mode 100644
index 0000000..6ba1989
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002durlwrite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Networking-Utilities.html#doc%2durlwrite">
diff --git a/doc/interpreter/HTML/doc_002dusage.html b/doc/interpreter/HTML/doc_002dusage.html
new file mode 100644
index 0000000..9fb68d4
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dusage.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Raising-Errors.html#doc%2dusage">
diff --git a/doc/interpreter/HTML/doc_002dusleep.html b/doc/interpreter/HTML/doc_002dusleep.html
new file mode 100644
index 0000000..0f2d741
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dusleep.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dusleep">
diff --git a/doc/interpreter/HTML/doc_002dvalidatestring.html b/doc/interpreter/HTML/doc_002dvalidatestring.html
new file mode 100644
index 0000000..768ce17
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvalidatestring.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Comparing-Strings.html#doc%2dvalidatestring">
diff --git a/doc/interpreter/HTML/doc_002dvalues.html b/doc/interpreter/HTML/doc_002dvalues.html
new file mode 100644
index 0000000..66c4b88
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvalues.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Basic-Statistical-Functions.html#doc%2dvalues">
diff --git a/doc/interpreter/HTML/doc_002dvander.html b/doc/interpreter/HTML/doc_002dvander.html
new file mode 100644
index 0000000..28f9db5
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvander.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dvander">
diff --git a/doc/interpreter/HTML/doc_002dvar.html b/doc/interpreter/HTML/doc_002dvar.html
new file mode 100644
index 0000000..8d03688
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Descriptive-Statistics.html#doc%2dvar">
diff --git a/doc/interpreter/HTML/doc_002dvar_005ftest.html b/doc/interpreter/HTML/doc_002dvar_005ftest.html
new file mode 100644
index 0000000..123d49d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvar_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dvar%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dvarargin.html b/doc/interpreter/HTML/doc_002dvarargin.html
new file mode 100644
index 0000000..a2fde71
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvarargin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Return-Values.html#doc%2dvarargin">
diff --git a/doc/interpreter/HTML/doc_002dvarargout.html b/doc/interpreter/HTML/doc_002dvarargout.html
new file mode 100644
index 0000000..ff1ea20
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvarargout.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Multiple-Return-Values.html#doc%2dvarargout">
diff --git a/doc/interpreter/HTML/doc_002dvec.html b/doc/interpreter/HTML/doc_002dvec.html
new file mode 100644
index 0000000..de13a90
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvec.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dvec">
diff --git a/doc/interpreter/HTML/doc_002dvech.html b/doc/interpreter/HTML/doc_002dvech.html
new file mode 100644
index 0000000..7205b89
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvech.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dvech">
diff --git a/doc/interpreter/HTML/doc_002dvectorize.html b/doc/interpreter/HTML/doc_002dvectorize.html
new file mode 100644
index 0000000..8f0ae15
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvectorize.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Inline-Functions.html#doc%2dvectorize">
diff --git a/doc/interpreter/HTML/doc_002dver.html b/doc/interpreter/HTML/doc_002dver.html
new file mode 100644
index 0000000..b6e0c22
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dver.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dver">
diff --git a/doc/interpreter/HTML/doc_002dversion.html b/doc/interpreter/HTML/doc_002dversion.html
new file mode 100644
index 0000000..8164422
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dversion.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=System-Information.html#doc%2dversion">
diff --git a/doc/interpreter/HTML/doc_002dvertcat.html b/doc/interpreter/HTML/doc_002dvertcat.html
new file mode 100644
index 0000000..779f916
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvertcat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Rearranging-Matrices.html#doc%2dvertcat">
diff --git a/doc/interpreter/HTML/doc_002dview.html b/doc/interpreter/HTML/doc_002dview.html
new file mode 100644
index 0000000..2b2f3b8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dview.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#doc%2dview">
diff --git a/doc/interpreter/HTML/doc_002dvoronoi.html b/doc/interpreter/HTML/doc_002dvoronoi.html
new file mode 100644
index 0000000..093fc80
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvoronoi.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Voronoi-Diagrams.html#doc%2dvoronoi">
diff --git a/doc/interpreter/HTML/doc_002dvoronoin.html b/doc/interpreter/HTML/doc_002dvoronoin.html
new file mode 100644
index 0000000..13088e9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dvoronoin.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Voronoi-Diagrams.html#doc%2dvoronoin">
diff --git a/doc/interpreter/HTML/doc_002dwaitforbuttonpress.html b/doc/interpreter/HTML/doc_002dwaitforbuttonpress.html
new file mode 100644
index 0000000..4cdca1d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwaitforbuttonpress.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Interacting-with-plots.html#doc%2dwaitforbuttonpress">
diff --git a/doc/interpreter/HTML/doc_002dwaitpid.html b/doc/interpreter/HTML/doc_002dwaitpid.html
new file mode 100644
index 0000000..6830122
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwaitpid.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Controlling-Subprocesses.html#doc%2dwaitpid">
diff --git a/doc/interpreter/HTML/doc_002dwarning.html b/doc/interpreter/HTML/doc_002dwarning.html
new file mode 100644
index 0000000..6e8d335
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwarning.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Issuing-Warnings.html#doc%2dwarning">
diff --git a/doc/interpreter/HTML/doc_002dwarning_005fids.html b/doc/interpreter/HTML/doc_002dwarning_005fids.html
new file mode 100644
index 0000000..173f9ea
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwarning_005fids.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Enabling-and-Disabling-Warnings.html#doc%2dwarning%5fids">
diff --git a/doc/interpreter/HTML/doc_002dwarranty.html b/doc/interpreter/HTML/doc_002dwarranty.html
new file mode 100644
index 0000000..86c6e58
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwarranty.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Getting-Help.html#doc%2dwarranty">
diff --git a/doc/interpreter/HTML/doc_002dwavread.html b/doc/interpreter/HTML/doc_002dwavread.html
new file mode 100644
index 0000000..2514183
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwavread.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dwavread">
diff --git a/doc/interpreter/HTML/doc_002dwavwrite.html b/doc/interpreter/HTML/doc_002dwavwrite.html
new file mode 100644
index 0000000..65968a2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwavwrite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Audio-Processing.html#doc%2dwavwrite">
diff --git a/doc/interpreter/HTML/doc_002dwblcdf.html b/doc/interpreter/HTML/doc_002dwblcdf.html
new file mode 100644
index 0000000..d10c8cd
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwblcdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dwblcdf">
diff --git a/doc/interpreter/HTML/doc_002dwblinv.html b/doc/interpreter/HTML/doc_002dwblinv.html
new file mode 100644
index 0000000..74b63f0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwblinv.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dwblinv">
diff --git a/doc/interpreter/HTML/doc_002dwblpdf.html b/doc/interpreter/HTML/doc_002dwblpdf.html
new file mode 100644
index 0000000..1b60a44
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwblpdf.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Distributions.html#doc%2dwblpdf">
diff --git a/doc/interpreter/HTML/doc_002dwblrnd.html b/doc/interpreter/HTML/doc_002dwblrnd.html
new file mode 100644
index 0000000..09673f1
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwblrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dwblrnd">
diff --git a/doc/interpreter/HTML/doc_002dweekday.html b/doc/interpreter/HTML/doc_002dweekday.html
new file mode 100644
index 0000000..54868cf
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dweekday.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Timing-Utilities.html#doc%2dweekday">
diff --git a/doc/interpreter/HTML/doc_002dwelch_005ftest.html b/doc/interpreter/HTML/doc_002dwelch_005ftest.html
new file mode 100644
index 0000000..01b3a70
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwelch_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dwelch%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dwhat.html b/doc/interpreter/HTML/doc_002dwhat.html
new file mode 100644
index 0000000..4874989
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwhat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dwhat">
diff --git a/doc/interpreter/HTML/doc_002dwhich.html b/doc/interpreter/HTML/doc_002dwhich.html
new file mode 100644
index 0000000..7998360
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwhich.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dwhich">
diff --git a/doc/interpreter/HTML/doc_002dwhite.html b/doc/interpreter/HTML/doc_002dwhite.html
new file mode 100644
index 0000000..e04177c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwhite.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dwhite">
diff --git a/doc/interpreter/HTML/doc_002dwho.html b/doc/interpreter/HTML/doc_002dwho.html
new file mode 100644
index 0000000..a462b32
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwho.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dwho">
diff --git a/doc/interpreter/HTML/doc_002dwhos.html b/doc/interpreter/HTML/doc_002dwhos.html
new file mode 100644
index 0000000..0ac7d48
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwhos.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dwhos">
diff --git a/doc/interpreter/HTML/doc_002dwhos_005fline_005fformat.html b/doc/interpreter/HTML/doc_002dwhos_005fline_005fformat.html
new file mode 100644
index 0000000..6f4032a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwhos_005fline_005fformat.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Status-of-Variables.html#doc%2dwhos%5fline%5fformat">
diff --git a/doc/interpreter/HTML/doc_002dwienrnd.html b/doc/interpreter/HTML/doc_002dwienrnd.html
new file mode 100644
index 0000000..91522d2
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwienrnd.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Random-Number-Generation.html#doc%2dwienrnd">
diff --git a/doc/interpreter/HTML/doc_002dwilcoxon_005ftest.html b/doc/interpreter/HTML/doc_002dwilcoxon_005ftest.html
new file mode 100644
index 0000000..570c1b7
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwilcoxon_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dwilcoxon%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dwilkinson.html b/doc/interpreter/HTML/doc_002dwilkinson.html
new file mode 100644
index 0000000..114f41a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwilkinson.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Famous-Matrices.html#doc%2dwilkinson">
diff --git a/doc/interpreter/HTML/doc_002dwinter.html b/doc/interpreter/HTML/doc_002dwinter.html
new file mode 100644
index 0000000..36ace1d
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dwinter.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Representing-Images.html#doc%2dwinter">
diff --git a/doc/interpreter/HTML/doc_002dxlabel.html b/doc/interpreter/HTML/doc_002dxlabel.html
new file mode 100644
index 0000000..91580d0
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dxlabel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dxlabel">
diff --git a/doc/interpreter/HTML/doc_002dxlim.html b/doc/interpreter/HTML/doc_002dxlim.html
new file mode 100644
index 0000000..fbbdd1a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dxlim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dxlim">
diff --git a/doc/interpreter/HTML/doc_002dxor.html b/doc/interpreter/HTML/doc_002dxor.html
new file mode 100644
index 0000000..4801b41
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dxor.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Finding-Elements-and-Checking-Conditions.html#doc%2dxor">
diff --git a/doc/interpreter/HTML/doc_002dyes_005for_005fno.html b/doc/interpreter/HTML/doc_002dyes_005for_005fno.html
new file mode 100644
index 0000000..b7da04a
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dyes_005for_005fno.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Terminal-Input.html#doc%2dyes%5for%5fno">
diff --git a/doc/interpreter/HTML/doc_002dylabel.html b/doc/interpreter/HTML/doc_002dylabel.html
new file mode 100644
index 0000000..ff690e9
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dylabel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dylabel">
diff --git a/doc/interpreter/HTML/doc_002dylim.html b/doc/interpreter/HTML/doc_002dylim.html
new file mode 100644
index 0000000..94a1768
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dylim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dylim">
diff --git a/doc/interpreter/HTML/doc_002dyulewalker.html b/doc/interpreter/HTML/doc_002dyulewalker.html
new file mode 100644
index 0000000..86f9481
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dyulewalker.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Signal-Processing.html#doc%2dyulewalker">
diff --git a/doc/interpreter/HTML/doc_002dz_005ftest.html b/doc/interpreter/HTML/doc_002dz_005ftest.html
new file mode 100644
index 0000000..c5aba95
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dz_005ftest.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dz%5ftest">
diff --git a/doc/interpreter/HTML/doc_002dz_005ftest_005f2.html b/doc/interpreter/HTML/doc_002dz_005ftest_005f2.html
new file mode 100644
index 0000000..480fa41
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dz_005ftest_005f2.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Tests.html#doc%2dz%5ftest%5f2">
diff --git a/doc/interpreter/HTML/doc_002dzeros.html b/doc/interpreter/HTML/doc_002dzeros.html
new file mode 100644
index 0000000..acee77c
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dzeros.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Special-Utility-Matrices.html#doc%2dzeros">
diff --git a/doc/interpreter/HTML/doc_002dzip.html b/doc/interpreter/HTML/doc_002dzip.html
new file mode 100644
index 0000000..07a31ce
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dzip.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=File-Archiving-Utilities.html#doc%2dzip">
diff --git a/doc/interpreter/HTML/doc_002dzlabel.html b/doc/interpreter/HTML/doc_002dzlabel.html
new file mode 100644
index 0000000..b0b6bf8
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dzlabel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Plot-Annotations.html#doc%2dzlabel">
diff --git a/doc/interpreter/HTML/doc_002dzlim.html b/doc/interpreter/HTML/doc_002dzlim.html
new file mode 100644
index 0000000..b014739
--- /dev/null
+++ b/doc/interpreter/HTML/doc_002dzlim.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#doc%2dzlim">
diff --git a/doc/interpreter/HTML/errorbar.png b/doc/interpreter/HTML/errorbar.png
new file mode 100644
index 0000000..cf320fa
Binary files /dev/null and b/doc/interpreter/HTML/errorbar.png differ
diff --git a/doc/interpreter/HTML/extended.png b/doc/interpreter/HTML/extended.png
new file mode 100644
index 0000000..cf4b7cd
Binary files /dev/null and b/doc/interpreter/HTML/extended.png differ
diff --git a/doc/interpreter/HTML/fig_003aerrorbar.html b/doc/interpreter/HTML/fig_003aerrorbar.html
new file mode 100644
index 0000000..b107341
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003aerrorbar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#fig%3aerrorbar">
diff --git a/doc/interpreter/HTML/fig_003afemmodel.html b/doc/interpreter/HTML/fig_003afemmodel.html
new file mode 100644
index 0000000..e1673e0
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003afemmodel.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Real-Life-Example.html#fig%3afemmodel">
diff --git a/doc/interpreter/HTML/fig_003agplot.html b/doc/interpreter/HTML/fig_003agplot.html
new file mode 100644
index 0000000..3bdf3ac
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003agplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#fig%3agplot">
diff --git a/doc/interpreter/HTML/fig_003ahist.html b/doc/interpreter/HTML/fig_003ahist.html
new file mode 100644
index 0000000..f372c1c
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003ahist.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#fig%3ahist">
diff --git a/doc/interpreter/HTML/fig_003amesh.html b/doc/interpreter/HTML/fig_003amesh.html
new file mode 100644
index 0000000..25adea1
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003amesh.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#fig%3amesh">
diff --git a/doc/interpreter/HTML/fig_003aplot.html b/doc/interpreter/HTML/fig_003aplot.html
new file mode 100644
index 0000000..b513998
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003aplot.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#fig%3aplot">
diff --git a/doc/interpreter/HTML/fig_003aplot3.html b/doc/interpreter/HTML/fig_003aplot3.html
new file mode 100644
index 0000000..4ae7f96
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003aplot3.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Three_002dDimensional-Plotting.html#fig%3aplot3">
diff --git a/doc/interpreter/HTML/fig_003apolar.html b/doc/interpreter/HTML/fig_003apolar.html
new file mode 100644
index 0000000..fc78c02
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003apolar.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Two_002dDimensional-Plots.html#fig%3apolar">
diff --git a/doc/interpreter/HTML/fig_003asimplechol.html b/doc/interpreter/HTML/fig_003asimplechol.html
new file mode 100644
index 0000000..c747567
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003asimplechol.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#fig%3asimplechol">
diff --git a/doc/interpreter/HTML/fig_003asimplecholperm.html b/doc/interpreter/HTML/fig_003asimplecholperm.html
new file mode 100644
index 0000000..67710a0
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003asimplecholperm.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#fig%3asimplecholperm">
diff --git a/doc/interpreter/HTML/fig_003asimplematrix.html b/doc/interpreter/HTML/fig_003asimplematrix.html
new file mode 100644
index 0000000..2817710
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003asimplematrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Mathematical-Considerations.html#fig%3asimplematrix">
diff --git a/doc/interpreter/HTML/fig_003aspmatrix.html b/doc/interpreter/HTML/fig_003aspmatrix.html
new file mode 100644
index 0000000..122e386
--- /dev/null
+++ b/doc/interpreter/HTML/fig_003aspmatrix.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Information.html#fig%3aspmatrix">
diff --git a/doc/interpreter/HTML/gplot.png b/doc/interpreter/HTML/gplot.png
new file mode 100644
index 0000000..0a3f1bb
Binary files /dev/null and b/doc/interpreter/HTML/gplot.png differ
diff --git a/doc/interpreter/HTML/grid.png b/doc/interpreter/HTML/grid.png
new file mode 100644
index 0000000..b50685b
Binary files /dev/null and b/doc/interpreter/HTML/grid.png differ
diff --git a/doc/interpreter/HTML/griddata.png b/doc/interpreter/HTML/griddata.png
new file mode 100644
index 0000000..14e94bc
Binary files /dev/null and b/doc/interpreter/HTML/griddata.png differ
diff --git a/doc/interpreter/HTML/hist.png b/doc/interpreter/HTML/hist.png
new file mode 100644
index 0000000..8f05444
Binary files /dev/null and b/doc/interpreter/HTML/hist.png differ
diff --git a/doc/interpreter/HTML/index.html b/doc/interpreter/HTML/index.html
new file mode 100644
index 0000000..dacac7e
--- /dev/null
+++ b/doc/interpreter/HTML/index.html
@@ -0,0 +1,1587 @@
+<html lang="en">
+<head>
+<title>Untitled</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Untitled">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="#Top">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<pre class="format">START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+</pre>
+   <!-- Settings for printing on 8-1/2 by 11 inch paper: -->
+<!--  -->
+<!-- Settings for small book format: -->
+<!--  -->
+<!-- Things like the Octave version number are defined in conf.texi. -->
+<!-- This file doesn't include a chapter, so it must not be included -->
+<!-- if you want to run the Emacs function texinfo-multiple-files-update. -->
+<!-- Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   <p>Copyright © 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006,
+2007 John W. Eaton.
+
+   <p>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.
+
+   <p>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.
+
+   <p>Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for
+modified versions.
+
+<div class="contents">
+<h2>Table of Contents</h2>
+<ul>
+<li><a name="toc_Top" href="index.html#Top">GNU Octave</a>
+<li><a name="toc_Preface" href="Preface.html#Preface">Preface</a>
+<ul>
+<li><a href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>
+<li><a href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a>
+<li><a href="Distribution.html#Distribution">Distribution</a>
+</li></ul>
+<li><a name="toc_Introduction" href="Introduction.html#Introduction">1 A Brief Introduction to Octave</a>
+<ul>
+<li><a href="Running-Octave.html#Running-Octave">1.1 Running Octave</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2 Simple Examples</a>
+<ul>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.1 Elementary Calculations</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.2 Creating a Matrix</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.3 Matrix Arithmetic</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.4 Solving Systems of Linear Equations</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.5 Integrating Differential Equations</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.6 Producing Graphical Output</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.7 Editing What You Have Typed</a>
+<li><a href="Simple-Examples.html#Simple-Examples">1.2.8 Help and Documentation</a>
+</li></ul>
+<li><a href="Conventions.html#Conventions">1.3 Conventions</a>
+<ul>
+<li><a href="Fonts.html#Fonts">1.3.1 Fonts</a>
+<li><a href="Evaluation-Notation.html#Evaluation-Notation">1.3.2 Evaluation Notation</a>
+<li><a href="Printing-Notation.html#Printing-Notation">1.3.3 Printing Notation</a>
+<li><a href="Error-Messages.html#Error-Messages">1.3.4 Error Messages</a>
+<li><a href="Format-of-Descriptions.html#Format-of-Descriptions">1.3.5 Format of Descriptions</a>
+<ul>
+<li><a href="A-Sample-Function-Description.html#A-Sample-Function-Description">1.3.5.1 A Sample Function Description</a>
+<li><a href="A-Sample-Command-Description.html#A-Sample-Command-Description">1.3.5.2 A Sample Command Description</a>
+<li><a href="A-Sample-Variable-Description.html#A-Sample-Variable-Description">1.3.5.3 A Sample Variable Description</a>
+</li></ul>
+</li></ul>
+</li></ul>
+<li><a name="toc_Getting-Started" href="Getting-Started.html#Getting-Started">2 Getting Started</a>
+<ul>
+<li><a href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">2.1 Invoking Octave from the Command Line</a>
+<ul>
+<li><a href="Command-Line-Options.html#Command-Line-Options">2.1.1 Command Line Options</a>
+<li><a href="Startup-Files.html#Startup-Files">2.1.2 Startup Files</a>
+</li></ul>
+<li><a href="Quitting-Octave.html#Quitting-Octave">2.2 Quitting Octave</a>
+<li><a href="Getting-Help.html#Getting-Help">2.3 Commands for Getting Help</a>
+<li><a href="Command-Line-Editing.html#Command-Line-Editing">2.4 Command Line Editing</a>
+<ul>
+<li><a href="Cursor-Motion.html#Cursor-Motion">2.4.1 Cursor Motion</a>
+<li><a href="Killing-and-Yanking.html#Killing-and-Yanking">2.4.2 Killing and Yanking</a>
+<li><a href="Commands-For-Text.html#Commands-For-Text">2.4.3 Commands For Changing Text</a>
+<li><a href="Commands-For-Completion.html#Commands-For-Completion">2.4.4 Letting Readline Type For You</a>
+<li><a href="Commands-For-History.html#Commands-For-History">2.4.5 Commands For Manipulating The History</a>
+<li><a href="Customizing-readline.html#Customizing-readline">2.4.6 Customizing <code>readline</code></a>
+<li><a href="Customizing-the-Prompt.html#Customizing-the-Prompt">2.4.7 Customizing the Prompt</a>
+<li><a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">2.4.8 Diary and Echo Commands</a>
+</li></ul>
+<li><a href="Errors.html#Errors">2.5 How Octave Reports Errors</a>
+<li><a href="Executable-Octave-Programs.html#Executable-Octave-Programs">2.6 Executable Octave Programs</a>
+<li><a href="Comments.html#Comments">2.7 Comments in Octave Programs</a>
+<ul>
+<li><a href="Single-Line-Comments.html#Single-Line-Comments">2.7.1 Single Line Comments</a>
+<li><a href="Block-Comments.html#Block-Comments">2.7.2 Block Comments</a>
+<li><a href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">2.7.3 Comments and the Help System</a>
+</li></ul>
+</li></ul>
+<li><a name="toc_Data-Types" href="Data-Types.html#Data-Types">3 Data Types</a>
+<ul>
+<li><a href="Built_002din-Data-Types.html#Built_002din-Data-Types">3.1 Built-in Data Types</a>
+<ul>
+<li><a href="Numeric-Objects.html#Numeric-Objects">3.1.1 Numeric Objects</a>
+<li><a href="Missing-Data.html#Missing-Data">3.1.2 Missing Data</a>
+<li><a href="String-Objects.html#String-Objects">3.1.3 String Objects</a>
+<li><a href="Data-Structure-Objects.html#Data-Structure-Objects">3.1.4 Data Structure Objects</a>
+<li><a href="Cell-Array-Objects.html#Cell-Array-Objects">3.1.5 Cell Array Objects</a>
+</li></ul>
+<li><a href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">3.2 User-defined Data Types</a>
+<li><a href="Object-Sizes.html#Object-Sizes">3.3 Object Sizes</a>
+</li></ul>
+<li><a name="toc_Numeric-Data-Types" href="Numeric-Data-Types.html#Numeric-Data-Types">4 Numeric Data Types</a>
+<ul>
+<li><a href="Matrices.html#Matrices">4.1 Matrices</a>
+<ul>
+<li><a href="Empty-Matrices.html#Empty-Matrices">4.1.1 Empty Matrices</a>
+</li></ul>
+<li><a href="Ranges.html#Ranges">4.2 Ranges</a>
+<li><a href="Single-Precision-Data-Types.html#Single-Precision-Data-Types">4.3 Single Precision Data Types</a>
+<li><a href="Integer-Data-Types.html#Integer-Data-Types">4.4 Integer Data Types</a>
+<ul>
+<li><a href="Integer-Arithmetic.html#Integer-Arithmetic">4.4.1 Integer Arithmetic</a>
+</li></ul>
+<li><a href="Bit-Manipulations.html#Bit-Manipulations">4.5 Bit Manipulations</a>
+<li><a href="Logical-Values.html#Logical-Values">4.6 Logical Values</a>
+<li><a href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types">4.7 Promotion and Demotion of Data Types</a>
+<li><a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">4.8 Predicates for Numeric Objects</a>
+</li></ul>
+<li><a name="toc_Strings" href="Strings.html#Strings">5 Strings</a>
+<ul>
+<li><a href="Escape-Sequences-in-string-constants.html#Escape-Sequences-in-string-constants">5.1 Escape Sequences in string constants</a>
+<li><a href="Character-Arrays.html#Character-Arrays">5.2 Character Arrays</a>
+<li><a href="Creating-Strings.html#Creating-Strings">5.3 Creating Strings</a>
+<ul>
+<li><a href="Concatenating-Strings.html#Concatenating-Strings">5.3.1 Concatenating Strings</a>
+<li><a href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">5.3.2 Conversion of Numerical Data to Strings</a>
+</li></ul>
+<li><a href="Comparing-Strings.html#Comparing-Strings">5.4 Comparing Strings</a>
+<li><a href="Manipulating-Strings.html#Manipulating-Strings">5.5 Manipulating Strings</a>
+<li><a href="String-Conversions.html#String-Conversions">5.6 String Conversions</a>
+<li><a href="Character-Class-Functions.html#Character-Class-Functions">5.7 Character Class Functions</a>
+</li></ul>
+<li><a name="toc_Data-Containers" href="Data-Containers.html#Data-Containers">6 Data Containers</a>
+<ul>
+<li><a href="Data-Structures.html#Data-Structures">6.1 Data Structures</a>
+<ul>
+<li><a href="Basic-Usage-and-Examples.html#Basic-Usage-and-Examples">6.1.1 Basic Usage and Examples</a>
+<li><a href="Structure-Arrays.html#Structure-Arrays">6.1.2 Structure Arrays</a>
+<li><a href="Creating-Structures.html#Creating-Structures">6.1.3 Creating Structures</a>
+<li><a href="Manipulating-Structures.html#Manipulating-Structures">6.1.4 Manipulating Structures</a>
+<li><a href="Processing-Data-in-Structures.html#Processing-Data-in-Structures">6.1.5 Processing Data in Structures</a>
+</li></ul>
+<li><a href="Cell-Arrays.html#Cell-Arrays">6.2 Cell Arrays</a>
+<ul>
+<li><a href="Basic-Usage-of-Cell-Arrays.html#Basic-Usage-of-Cell-Arrays">6.2.1 Basic Usage of Cell Arrays</a>
+<li><a href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">6.2.2 Creating Cell Array</a>
+<li><a href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">6.2.3 Indexing Cell Arrays</a>
+<li><a href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">6.2.4 Cell Arrays of Strings</a>
+<li><a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">6.2.5 Processing Data in Cell Arrays</a>
+</li></ul>
+<li><a href="Comma-Separated-Lists.html#Comma-Separated-Lists">6.3 Comma Separated Lists</a>
+<ul>
+<li><a href="Comma-Separated-Lists-Generated-from-Cell-Arrays.html#Comma-Separated-Lists-Generated-from-Cell-Arrays">6.3.1 Comma Separated Lists Generated from Cell Arrays</a>
+<li><a href="Comma-Separated-Lists-Generated-from-Structure-Arrays.html#Comma-Separated-Lists-Generated-from-Structure-Arrays">6.3.2 Comma Separated Lists Generated from Structure Arrays</a>
+</li></ul>
+</li></ul>
+<li><a name="toc_Variables" href="Variables.html#Variables">7 Variables</a>
+<ul>
+<li><a href="Global-Variables.html#Global-Variables">7.1 Global Variables</a>
+<li><a href="Persistent-Variables.html#Persistent-Variables">7.2 Persistent Variables</a>
+<li><a href="Status-of-Variables.html#Status-of-Variables">7.3 Status of Variables</a>
+</li></ul>
+<li><a name="toc_Expressions" href="Expressions.html#Expressions">8 Expressions</a>
+<ul>
+<li><a href="Index-Expressions.html#Index-Expressions">8.1 Index Expressions</a>
+<li><a href="Calling-Functions.html#Calling-Functions">8.2 Calling Functions</a>
+<ul>
+<li><a href="Call-by-Value.html#Call-by-Value">8.2.1 Call by Value</a>
+<li><a href="Recursion.html#Recursion">8.2.2 Recursion</a>
+</li></ul>
+<li><a href="Arithmetic-Ops.html#Arithmetic-Ops">8.3 Arithmetic Operators</a>
+<li><a href="Comparison-Ops.html#Comparison-Ops">8.4 Comparison Operators</a>
+<li><a href="Boolean-Expressions.html#Boolean-Expressions">8.5 Boolean Expressions</a>
+<ul>
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">8.5.1 Element-by-element Boolean Operators</a>
+<li><a href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">8.5.2 Short-circuit Boolean Operators</a>
+</li></ul>
+<li><a href="Assignment-Ops.html#Assignment-Ops">8.6 Assignment Expressions</a>
+<li><a href="Increment-Ops.html#Increment-Ops">8.7 Increment Operators</a>
+<li><a href="Operator-Precedence.html#Operator-Precedence">8.8 Operator Precedence</a>
+</li></ul>
+<li><a name="toc_Evaluation" href="Evaluation.html#Evaluation">9 Evaluation</a>
+<ul>
+<li><a href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">9.1 Calling a Function by its Name</a>
+<li><a href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context">9.2 Evaluation in a Different Context</a>
+</li></ul>
+<li><a name="toc_Statements" href="Statements.html#Statements">10 Statements</a>
+<ul>
+<li><a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">10.1 The <code>if</code> Statement</a>
+<li><a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">10.2 The <code>switch</code> Statement</a>
+<ul>
+<li><a href="Notes-for-the-C-programmer.html#Notes-for-the-C-programmer">10.2.1 Notes for the C programmer</a>
+</li></ul>
+<li><a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">10.3 The <code>while</code> Statement</a>
+<li><a href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement">10.4 The <code>do-until</code> Statement</a>
+<li><a href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">10.5 The <code>for</code> Statement</a>
+<ul>
+<li><a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">10.5.1 Looping Over Structure Elements</a>
+</li></ul>
+<li><a href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#The-_003ccode_003ebreak_003c_002fcode_003e-Statement">10.6 The <code>break</code> Statement</a>
+<li><a href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#The-_003ccode_003econtinue_003c_002fcode_003e-Statement">10.7 The <code>continue</code> Statement</a>
+<li><a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">10.8 The <code>unwind_protect</code> Statement</a>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">10.9 The <code>try</code> Statement</a>
+<li><a href="Continuation-Lines.html#Continuation-Lines">10.10 Continuation Lines</a>
+</li></ul>
+<li><a name="toc_Functions-and-Scripts" href="Functions-and-Scripts.html#Functions-and-Scripts">11 Functions and Scripts</a>
+<ul>
+<li><a href="Defining-Functions.html#Defining-Functions">11.1 Defining Functions</a>
+<li><a href="Multiple-Return-Values.html#Multiple-Return-Values">11.2 Multiple Return Values</a>
+<li><a href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">11.3 Variable-length Argument Lists</a>
+<li><a href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">11.4 Variable-length Return Lists</a>
+<li><a href="Returning-From-a-Function.html#Returning-From-a-Function">11.5 Returning From a Function</a>
+<li><a href="Default-Arguments.html#Default-Arguments">11.6 Default Arguments</a>
+<li><a href="Function-Files.html#Function-Files">11.7 Function Files</a>
+<ul>
+<li><a href="Manipulating-the-load-path.html#Manipulating-the-load-path">11.7.1 Manipulating the load path</a>
+<li><a href="Subfunctions.html#Subfunctions">11.7.2 Subfunctions</a>
+<li><a href="Private-Functions.html#Private-Functions">11.7.3 Private Functions</a>
+<li><a href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">11.7.4 Overloading and Autoloading</a>
+<li><a href="Function-Locking.html#Function-Locking">11.7.5 Function Locking</a>
+<li><a href="Function-Precedence.html#Function-Precedence">11.7.6 Function Precedence</a>
+</li></ul>
+<li><a href="Script-Files.html#Script-Files">11.8 Script Files</a>
+<li><a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">11.9 Function Handles, Inline Functions, and Anonymous Functions</a>
+<ul>
+<li><a href="Function-Handles.html#Function-Handles">11.9.1 Function Handles</a>
+<li><a href="Anonymous-Functions.html#Anonymous-Functions">11.9.2 Anonymous Functions</a>
+<li><a href="Inline-Functions.html#Inline-Functions">11.9.3 Inline Functions</a>
+</li></ul>
+<li><a href="Commands.html#Commands">11.10 Commands</a>
+<li><a href="Organization-of-Functions.html#Organization-of-Functions">11.11 Organization of Functions Distributed with Octave</a>
+</li></ul>
+<li><a name="toc_Errors-and-Warnings" href="Errors-and-Warnings.html#Errors-and-Warnings">12 Errors and Warnings</a>
+<ul>
+<li><a href="Handling-Errors.html#Handling-Errors">12.1 Handling Errors</a>
+<ul>
+<li><a href="Raising-Errors.html#Raising-Errors">12.1.1 Raising Errors</a>
+<li><a href="Catching-Errors.html#Catching-Errors">12.1.2 Catching Errors</a>
+</li></ul>
+<li><a href="Handling-Warnings.html#Handling-Warnings">12.2 Handling Warnings</a>
+<ul>
+<li><a href="Issuing-Warnings.html#Issuing-Warnings">12.2.1 Issuing Warnings</a>
+<li><a href="Enabling-and-Disabling-Warnings.html#Enabling-and-Disabling-Warnings">12.2.2 Enabling and Disabling Warnings</a>
+</li></ul>
+</li></ul>
+<li><a name="toc_Debugging" href="Debugging.html#Debugging">13 Debugging</a>
+<ul>
+<li><a href="Entering-Debug-Mode.html#Entering-Debug-Mode">13.1 Entering Debug Mode</a>
+<li><a href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">13.2 Leavinging Debug Mode</a>
+<li><a href="Breakpoints.html#Breakpoints">13.3 Breakpoints</a>
+<li><a href="Debug-Mode.html#Debug-Mode">13.4 Debug Mode</a>
+<li><a href="Call-Stack.html#Call-Stack">13.5 Call Stack</a>
+</li></ul>
+<li><a name="toc_Input-and-Output" href="Input-and-Output.html#Input-and-Output">14 Input and Output</a>
+<ul>
+<li><a href="Basic-Input-and-Output.html#Basic-Input-and-Output">14.1 Basic Input and Output</a>
+<ul>
+<li><a href="Terminal-Output.html#Terminal-Output">14.1.1 Terminal Output</a>
+<ul>
+<li><a href="Paging-Screen-Output.html#Paging-Screen-Output">14.1.1.1 Paging Screen Output</a>
+</li></ul>
+<li><a href="Terminal-Input.html#Terminal-Input">14.1.2 Terminal Input</a>
+<li><a href="Simple-File-I_002fO.html#Simple-File-I_002fO">14.1.3 Simple File I/O</a>
+<ul>
+<li><a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">14.1.3.1 Saving Data on Unexpected Exits</a>
+</li></ul>
+<li><a href="Rational-Approximations.html#Rational-Approximations">14.1.4 Rational Approximations</a>
+</li></ul>
+<li><a href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">14.2 C-Style I/O Functions</a>
+<ul>
+<li><a href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">14.2.1 Opening and Closing Files</a>
+<li><a href="Simple-Output.html#Simple-Output">14.2.2 Simple Output</a>
+<li><a href="Line_002dOriented-Input.html#Line_002dOriented-Input">14.2.3 Line-Oriented Input</a>
+<li><a href="Formatted-Output.html#Formatted-Output">14.2.4 Formatted Output</a>
+<li><a href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices">14.2.5 Output Conversion for Matrices</a>
+<li><a href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">14.2.6 Output Conversion Syntax</a>
+<li><a href="Table-of-Output-Conversions.html#Table-of-Output-Conversions">14.2.7 Table of Output Conversions</a>
+<li><a href="Integer-Conversions.html#Integer-Conversions">14.2.8 Integer Conversions</a>
+<li><a href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">14.2.9 Floating-Point Conversions</a>
+<li><a href="Other-Output-Conversions.html#Other-Output-Conversions">14.2.10 Other Output Conversions</a>
+<li><a href="Formatted-Input.html#Formatted-Input">14.2.11 Formatted Input</a>
+<li><a href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">14.2.12 Input Conversion Syntax</a>
+<li><a href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">14.2.13 Table of Input Conversions</a>
+<li><a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">14.2.14 Numeric Input Conversions</a>
+<li><a href="String-Input-Conversions.html#String-Input-Conversions">14.2.15 String Input Conversions</a>
+<li><a href="Binary-I_002fO.html#Binary-I_002fO">14.2.16 Binary I/O</a>
+<li><a href="Temporary-Files.html#Temporary-Files">14.2.17 Temporary Files</a>
+<li><a href="EOF-and-Errors.html#EOF-and-Errors">14.2.18 End of File and Errors</a>
+<li><a href="File-Positioning.html#File-Positioning">14.2.19 File Positioning</a>
+</li></ul>
+</li></ul>
+<li><a name="toc_Plotting" href="Plotting.html#Plotting">15 Plotting</a>
+<ul>
+<li><a href="Plotting-Basics.html#Plotting-Basics">15.1 Plotting Basics</a>
+<ul>
+<li><a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">15.1.1 Two-Dimensional Plots</a>
+<ul>
+<li><a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">15.1.1.1 Two-dimensional Function Plotting</a>
+</li></ul>
+<li><a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">15.1.2 Three-Dimensional Plotting</a>
+<ul>
+<li><a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">15.1.2.1 Three-dimensional Function Plotting</a>
+<li><a href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">15.1.2.2 Three-dimensional Geometric Shapes</a>
+</li></ul>
+<li><a href="Plot-Annotations.html#Plot-Annotations">15.1.3 Plot Annotations</a>
+<li><a href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page">15.1.4 Multiple Plots on One Page</a>
+<li><a href="Multiple-Plot-Windows.html#Multiple-Plot-Windows">15.1.5 Multiple Plot Windows</a>
+<li><a href="Printing-Plots.html#Printing-Plots">15.1.6 Printing Plots</a>
+<li><a href="Interacting-with-plots.html#Interacting-with-plots">15.1.7 Interacting with plots</a>
+<li><a href="Test-Plotting-Functions.html#Test-Plotting-Functions">15.1.8 Test Plotting Functions</a>
+</li></ul>
+<li><a href="Advanced-Plotting.html#Advanced-Plotting">15.2 Advanced Plotting</a>
+<ul>
+<li><a href="Graphics-Objects.html#Graphics-Objects">15.2.1 Graphics Objects</a>
+<li><a href="Graphics-Object-Properties.html#Graphics-Object-Properties">15.2.2 Graphics Object Properties</a>
+<ul>
+<li><a href="Root-Figure-Properties.html#Root-Figure-Properties">15.2.2.1 Root Figure Properties</a>
+<li><a href="Figure-Properties.html#Figure-Properties">15.2.2.2 Figure Properties</a>
+<li><a href="Axes-Properties.html#Axes-Properties">15.2.2.3 Axes Properties</a>
+<li><a href="Line-Properties.html#Line-Properties">15.2.2.4 Line Properties</a>
+<li><a href="Text-Properties.html#Text-Properties">15.2.2.5 Text Properties</a>
+<li><a href="Image-Properties.html#Image-Properties">15.2.2.6 Image Properties</a>
+<li><a href="Patch-Properties.html#Patch-Properties">15.2.2.7 Patch Properties</a>
+<li><a href="Surface-Properties.html#Surface-Properties">15.2.2.8 Surface Properties</a>
+<li><a href="Searching-Properties.html#Searching-Properties">15.2.2.9 Searching Properties</a>
+</li></ul>
+<li><a href="Managing-Default-Properties.html#Managing-Default-Properties">15.2.3 Managing Default Properties</a>
+<li><a href="Colors.html#Colors">15.2.4 Colors</a>
+<li><a href="Line-Styles.html#Line-Styles">15.2.5 Line Styles</a>
+<li><a href="Marker-Styles.html#Marker-Styles">15.2.6 Marker Styles</a>
+<li><a href="Callbacks.html#Callbacks">15.2.7 Callbacks</a>
+<li><a href="Object-Groups.html#Object-Groups">15.2.8 Object Groups</a>
+<ul>
+<li><a href="Data-sources-in-object-groups.html#Data-sources-in-object-groups">15.2.8.1 Data sources in object groups</a>
+<li><a href="Area-series.html#Area-series">15.2.8.2 Area series</a>
+<li><a href="Bar-series.html#Bar-series">15.2.8.3 Bar series</a>
+<li><a href="Contour-groups.html#Contour-groups">15.2.8.4 Contour groups</a>
+<li><a href="Error-bar-series.html#Error-bar-series">15.2.8.5 Error bar series</a>
+<li><a href="Line-series.html#Line-series">15.2.8.6 Line series</a>
+<li><a href="Quiver-group.html#Quiver-group">15.2.8.7 Quiver group</a>
+<li><a href="Scatter-group.html#Scatter-group">15.2.8.8 Scatter group</a>
+<li><a href="Stair-group.html#Stair-group">15.2.8.9 Stair group</a>
+<li><a href="Stem-Series.html#Stem-Series">15.2.8.10 Stem Series</a>
+<li><a href="Surface-group.html#Surface-group">15.2.8.11 Surface group</a>
+</li></ul>
+<li><a href="Graphics-backends.html#Graphics-backends">15.2.9 Graphics backends</a>
+<ul>
+<li><a href="Interaction-with-gnuplot.html#Interaction-with-gnuplot">15.2.9.1 Interaction with <code>gnuplot</code></a>
+</li></ul>
+</li></ul>
+</li></ul>
+<li><a name="toc_Matrix-Manipulation" href="Matrix-Manipulation.html#Matrix-Manipulation">16 Matrix Manipulation</a>
+<ul>
+<li><a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">16.1 Finding Elements and Checking Conditions</a>
+<li><a href="Rearranging-Matrices.html#Rearranging-Matrices">16.2 Rearranging Matrices</a>
+<li><a href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">16.3 Applying a Function to an Array</a>
+<li><a href="Special-Utility-Matrices.html#Special-Utility-Matrices">16.4 Special Utility Matrices</a>
+<li><a href="Famous-Matrices.html#Famous-Matrices">16.5 Famous Matrices</a>
+</li></ul>
+<li><a name="toc_Arithmetic" href="Arithmetic.html#Arithmetic">17 Arithmetic</a>
+<ul>
+<li><a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">17.1 Exponents and Logarithms</a>
+<li><a href="Complex-Arithmetic.html#Complex-Arithmetic">17.2 Complex Arithmetic</a>
+<li><a href="Trigonometry.html#Trigonometry">17.3 Trigonometry</a>
+<li><a href="Sums-and-Products.html#Sums-and-Products">17.4 Sums and Products</a>
+<li><a href="Utility-Functions.html#Utility-Functions">17.5 Utility Functions</a>
+<li><a href="Special-Functions.html#Special-Functions">17.6 Special Functions</a>
+<li><a href="Coordinate-Transformations.html#Coordinate-Transformations">17.7 Coordinate Transformations</a>
+<li><a href="Mathematical-Constants.html#Mathematical-Constants">17.8 Mathematical Constants</a>
+</li></ul>
+<li><a name="toc_Linear-Algebra" href="Linear-Algebra.html#Linear-Algebra">18 Linear Algebra</a>
+<ul>
+<li><a href="Techniques-used-for-Linear-Algebra.html#Techniques-used-for-Linear-Algebra">18.1 Techniques used for Linear Algebra</a>
+<li><a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">18.2 Basic Matrix Functions</a>
+<li><a href="Matrix-Factorizations.html#Matrix-Factorizations">18.3 Matrix Factorizations</a>
+<li><a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">18.4 Functions of a Matrix</a>
+<li><a href="Specialized-Solvers.html#Specialized-Solvers">18.5 Specialized Solvers</a>
+</li></ul>
+<li><a name="toc_Nonlinear-Equations" href="Nonlinear-Equations.html#Nonlinear-Equations">19 Nonlinear Equations</a>
+<li><a name="toc_Diagonal-and-Permutation-Matrices" href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">20 Diagonal and Permutation Matrices</a>
+<ul>
+<li><a href="Basic-Usage.html#Basic-Usage">20.1 Creating and Manipulating Diagonal and Permutation Matrices</a>
+<ul>
+<li><a href="Creating-Diagonal-Matrices.html#Creating-Diagonal-Matrices">20.1.1 Creating Diagonal Matrices</a>
+<li><a href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices">20.1.2 Creating Permutation Matrices</a>
+<li><a href="Explicit-and-Implicit-Conversions.html#Explicit-and-Implicit-Conversions">20.1.3 Explicit and Implicit Conversions</a>
+</li></ul>
+<li><a href="Matrix-Algebra.html#Matrix-Algebra">20.2 Linear Algebra with Diagonal and Permutation Matrices</a>
+<ul>
+<li><a href="Expressions-Involving-Diagonal-Matrices.html#Expressions-Involving-Diagonal-Matrices">20.2.1 Expressions Involving Diagonal Matrices</a>
+<li><a href="Expressions-Involving-Permutation-Matrices.html#Expressions-Involving-Permutation-Matrices">20.2.2 Expressions Involving Permutation Matrices</a>
+</li></ul>
+<li><a href="Function-Support.html#Function-Support">20.3 Functions That Are Aware of These Matrices</a>
+<ul>
+<li><a href="Diagonal-Matrix-Functions.html#Diagonal-Matrix-Functions">20.3.1 Diagonal Matrix Functions</a>
+<li><a href="Permutation-Matrix-Functions.html#Permutation-Matrix-Functions">20.3.2 Permutation Matrix Functions</a>
+</li></ul>
+<li><a href="Example-Codes.html#Example-Codes">20.4 Some Examples of Usage</a>
+<li><a href="Zeros-Treatment.html#Zeros-Treatment">20.5 The Differences in Treatment of Zero Elements</a>
+</li></ul>
+<li><a name="toc_Sparse-Matrices" href="Sparse-Matrices.html#Sparse-Matrices">21 Sparse Matrices</a>
+<ul>
+<li><a href="Basics.html#Basics">21.1 The Creation and Manipulation of Sparse Matrices</a>
+<ul>
+<li><a href="Storage-of-Sparse-Matrices.html#Storage-of-Sparse-Matrices">21.1.1 Storage of Sparse Matrices</a>
+<li><a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">21.1.2 Creating Sparse Matrices</a>
+<li><a href="Information.html#Information">21.1.3 Finding out Information about Sparse Matrices</a>
+<li><a href="Operators-and-Functions.html#Operators-and-Functions">21.1.4 Basic Operators and Functions on Sparse Matrices</a>
+<ul>
+<li><a href="Sparse-Functions.html#Sparse-Functions">21.1.4.1 Sparse Functions</a>
+<li><a href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions">21.1.4.2 The Return Types of Operators and Functions</a>
+<li><a href="Mathematical-Considerations.html#Mathematical-Considerations">21.1.4.3 Mathematical Considerations</a>
+</li></ul>
+</li></ul>
+<li><a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">21.2 Linear Algebra on Sparse Matrices</a>
+<li><a href="Iterative-Techniques.html#Iterative-Techniques">21.3 Iterative Techniques applied to sparse matrices</a>
+<li><a href="Real-Life-Example.html#Real-Life-Example">21.4 Real Life Example of the use of Sparse Matrices</a>
+</li></ul>
+<li><a name="toc_Numerical-Integration" href="Numerical-Integration.html#Numerical-Integration">22 Numerical Integration</a>
+<ul>
+<li><a href="Functions-of-One-Variable.html#Functions-of-One-Variable">22.1 Functions of One Variable</a>
+<li><a href="Orthogonal-Collocation.html#Orthogonal-Collocation">22.2 Orthogonal Collocation</a>
+<li><a href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">22.3 Functions of Multiple Variables</a>
+</li></ul>
+<li><a name="toc_Differential-Equations" href="Differential-Equations.html#Differential-Equations">23 Differential Equations</a>
+<ul>
+<li><a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">23.1 Ordinary Differential Equations</a>
+<li><a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">23.2 Differential-Algebraic Equations</a>
+</li></ul>
+<li><a name="toc_Optimization" href="Optimization.html#Optimization">24 Optimization</a>
+<ul>
+<li><a href="Linear-Programming.html#Linear-Programming">24.1 Linear Programming</a>
+<li><a href="Quadratic-Programming.html#Quadratic-Programming">24.2 Quadratic Programming</a>
+<li><a href="Nonlinear-Programming.html#Nonlinear-Programming">24.3 Nonlinear Programming</a>
+<li><a href="Linear-Least-Squares.html#Linear-Least-Squares">24.4 Linear Least Squares</a>
+</li></ul>
+<li><a name="toc_Statistics" href="Statistics.html#Statistics">25 Statistics</a>
+<ul>
+<li><a href="Descriptive-Statistics.html#Descriptive-Statistics">25.1 Descriptive Statistics</a>
+<li><a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">25.2 Basic Statistical Functions</a>
+<li><a href="Statistical-Plots.html#Statistical-Plots">25.3 Statistical Plots</a>
+<li><a href="Tests.html#Tests">25.4 Tests</a>
+<li><a href="Models.html#Models">25.5 Models</a>
+<li><a href="Distributions.html#Distributions">25.6 Distributions</a>
+<li><a href="Random-Number-Generation.html#Random-Number-Generation">25.7 Random Number Generation</a>
+</li></ul>
+<li><a name="toc_Sets" href="Sets.html#Sets">26 Sets</a>
+<ul>
+<li><a href="Set-Operations.html#Set-Operations">26.1 Set Operations</a>
+</li></ul>
+<li><a name="toc_Polynomial-Manipulations" href="Polynomial-Manipulations.html#Polynomial-Manipulations">27 Polynomial Manipulations</a>
+<ul>
+<li><a href="Evaluating-Polynomials.html#Evaluating-Polynomials">27.1 Evaluating Polynomials</a>
+<li><a href="Finding-Roots.html#Finding-Roots">27.2 Finding Roots</a>
+<li><a href="Products-of-Polynomials.html#Products-of-Polynomials">27.3 Products of Polynomials</a>
+<li><a href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">27.4 Derivatives and Integrals</a>
+<li><a href="Polynomial-Interpolation.html#Polynomial-Interpolation">27.5 Polynomial Interpolation</a>
+<li><a href="Miscellaneous-Functions.html#Miscellaneous-Functions">27.6 Miscellaneous Functions</a>
+</li></ul>
+<li><a name="toc_Interpolation" href="Interpolation.html#Interpolation">28 Interpolation</a>
+<ul>
+<li><a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">28.1 One-dimensional Interpolation</a>
+<li><a href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">28.2 Multi-dimensional Interpolation</a>
+</li></ul>
+<li><a name="toc_Geometry" href="Geometry.html#Geometry">29 Geometry</a>
+<ul>
+<li><a href="Delaunay-Triangulation.html#Delaunay-Triangulation">29.1 Delaunay Triangulation</a>
+<ul>
+<li><a href="Plotting-the-Triangulation.html#Plotting-the-Triangulation">29.1.1 Plotting the Triangulation</a>
+<li><a href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">29.1.2 Identifying points in Triangulation</a>
+</li></ul>
+<li><a href="Voronoi-Diagrams.html#Voronoi-Diagrams">29.2 Voronoi Diagrams</a>
+<li><a href="Convex-Hull.html#Convex-Hull">29.3 Convex Hull</a>
+<li><a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">29.4 Interpolation on Scattered Data</a>
+</li></ul>
+<li><a name="toc_Signal-Processing" href="Signal-Processing.html#Signal-Processing">30 Signal Processing</a>
+<li><a name="toc_Image-Processing" href="Image-Processing.html#Image-Processing">31 Image Processing</a>
+<ul>
+<li><a href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">31.1 Loading and Saving Images</a>
+<li><a href="Displaying-Images.html#Displaying-Images">31.2 Displaying Images</a>
+<li><a href="Representing-Images.html#Representing-Images">31.3 Representing Images</a>
+<li><a href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images">31.4 Plotting on top of Images</a>
+<li><a href="Color-Conversion.html#Color-Conversion">31.5 Color Conversion</a>
+</li></ul>
+<li><a name="toc_Audio-Processing" href="Audio-Processing.html#Audio-Processing">32 Audio Processing</a>
+<li><a name="toc_Object-Oriented-Programming" href="Object-Oriented-Programming.html#Object-Oriented-Programming">33 Object Oriented Programming</a>
+<ul>
+<li><a href="Creating-a-Class.html#Creating-a-Class">33.1 Creating a Class</a>
+<li><a href="Manipulating-Classes.html#Manipulating-Classes">33.2 Manipulating Classes</a>
+<li><a href="Indexing-Objects.html#Indexing-Objects">33.3 Indexing Objects</a>
+<li><a href="Overloading-Objects.html#Overloading-Objects">33.4 Overloading Objects</a>
+<ul>
+<li><a href="Function-Overloading.html#Function-Overloading">33.4.1 Function Overloading</a>
+<li><a href="Operator-Overloading.html#Operator-Overloading">33.4.2 Operator Overloading</a>
+<li><a href="Precedence-of-Objects.html#Precedence-of-Objects">33.4.3 Precedence of Objects</a>
+</li></ul>
+<li><a href="Inheritance-and-Aggregation.html#Inheritance-and-Aggregation">33.5 Inheritance and Aggregation</a>
+</li></ul>
+<li><a name="toc_System-Utilities" href="System-Utilities.html#System-Utilities">34 System Utilities</a>
+<ul>
+<li><a href="Timing-Utilities.html#Timing-Utilities">34.1 Timing Utilities</a>
+<li><a href="Filesystem-Utilities.html#Filesystem-Utilities">34.2 Filesystem Utilities</a>
+<li><a href="File-Archiving-Utilities.html#File-Archiving-Utilities">34.3 File Archiving Utilities</a>
+<li><a href="Networking-Utilities.html#Networking-Utilities">34.4 Networking Utilities</a>
+<li><a href="Controlling-Subprocesses.html#Controlling-Subprocesses">34.5 Controlling Subprocesses</a>
+<li><a href="Process-ID-Information.html#Process-ID-Information">34.6 Process, Group, and User IDs</a>
+<li><a href="Environment-Variables.html#Environment-Variables">34.7 Environment Variables</a>
+<li><a href="Current-Working-Directory.html#Current-Working-Directory">34.8 Current Working Directory</a>
+<li><a href="Password-Database-Functions.html#Password-Database-Functions">34.9 Password Database Functions</a>
+<li><a href="Group-Database-Functions.html#Group-Database-Functions">34.10 Group Database Functions</a>
+<li><a href="System-Information.html#System-Information">34.11 System Information</a>
+<li><a href="Hashing-Functions.html#Hashing-Functions">34.12 Hashing Functions</a>
+</li></ul>
+<li><a name="toc_Packages" href="Packages.html#Packages">35 Packages</a>
+<ul>
+<li><a href="Installing-and-Removing-Packages.html#Installing-and-Removing-Packages">35.1 Installing and Removing Packages</a>
+<li><a href="Using-Packages.html#Using-Packages">35.2 Using Packages</a>
+<li><a href="Administrating-Packages.html#Administrating-Packages">35.3 Administrating Packages</a>
+<li><a href="Creating-Packages.html#Creating-Packages">35.4 Creating Packages</a>
+<ul>
+<li><a href="The-DESCRIPTION-File.html#The-DESCRIPTION-File">35.4.1 The DESCRIPTION File</a>
+<li><a href="The-INDEX-file.html#The-INDEX-file">35.4.2 The INDEX file</a>
+<li><a href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives">35.4.3 PKG_ADD and PKG_DEL directives</a>
+</li></ul>
+</li></ul>
+<li><a name="toc_Dynamically-Linked-Functions" href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Appendix A Dynamically Linked Functions</a>
+<ul>
+<li><a href="Oct_002dFiles.html#Oct_002dFiles">A.1 Oct-Files</a>
+<ul>
+<li><a href="Getting-Started-with-Oct_002dFiles.html#Getting-Started-with-Oct_002dFiles">A.1.1 Getting Started with Oct-Files</a>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">A.1.2 Matrices and Arrays in Oct-Files</a>
+<li><a href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles">A.1.3 Character Strings in Oct-Files</a>
+<li><a href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles">A.1.4 Cell Arrays in Oct-Files</a>
+<li><a href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles">A.1.5 Structures in Oct-Files</a>
+<li><a href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">A.1.6 Sparse Matrices in Oct-Files</a>
+<ul>
+<li><a href="Array-and-Sparse-Differences.html#Array-and-Sparse-Differences">A.1.6.1 The Differences between the Array and Sparse Classes</a>
+<li><a href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles">A.1.6.2 Creating Sparse Matrices in Oct-Files</a>
+<li><a href="Using-Sparse-Matrices-in-Oct_002dFiles.html#Using-Sparse-Matrices-in-Oct_002dFiles">A.1.6.3 Using Sparse Matrices in Oct-Files</a>
+</li></ul>
+<li><a href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles">A.1.7 Accessing Global Variables in Oct-Files</a>
+<li><a href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles">A.1.8 Calling Octave Functions from Oct-Files</a>
+<li><a href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles">A.1.9 Calling External Code from Oct-Files</a>
+<li><a href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles">A.1.10 Allocating Local Memory in Oct-Files</a>
+<li><a href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles">A.1.11 Input Parameter Checking in Oct-Files</a>
+<li><a href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles">A.1.12 Exception and Error Handling in Oct-Files</a>
+<li><a href="Documentation-and-Test-of-Oct_002dFiles.html#Documentation-and-Test-of-Oct_002dFiles">A.1.13 Documentation and Test of Oct-Files</a>
+</li></ul>
+<li><a href="Mex_002dFiles.html#Mex_002dFiles">A.2 Mex-Files</a>
+<ul>
+<li><a href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles">A.2.1 Getting Started with Mex-Files</a>
+<li><a href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles">A.2.2 Working with Matrices and Arrays in Mex-Files</a>
+<li><a href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles">A.2.3 Character Strings in Mex-Files</a>
+<li><a href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles">A.2.4 Cell Arrays with Mex-Files</a>
+<li><a href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles">A.2.5 Structures with Mex-Files</a>
+<li><a href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles">A.2.6 Sparse Matrices with Mex-Files</a>
+<li><a href="Calling-Other-Functions-in-Mex_002dFiles.html#Calling-Other-Functions-in-Mex_002dFiles">A.2.7 Calling Other Functions in Mex-Files</a>
+</li></ul>
+<li><a href="Standalone-Programs.html#Standalone-Programs">A.3 Standalone Programs</a>
+</li></ul>
+<li><a name="toc_Test-and-Demo-Functions" href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Appendix B Test and Demo Functions</a>
+<ul>
+<li><a href="Test-Functions.html#Test-Functions">B.1 Test Functions</a>
+<li><a href="Demonstration-Functions.html#Demonstration-Functions">B.2 Demonstration Functions</a>
+</li></ul>
+<li><a name="toc_Tips-and-Standards" href="Tips-and-Standards.html#Tips-and-Standards">Appendix C Tips and Standards</a>
+<ul>
+<li><a href="Style-Tips.html#Style-Tips">C.1 Writing Clean Octave Programs</a>
+<li><a href="Coding-Tips.html#Coding-Tips">C.2 Tips for Making Code Run Faster.</a>
+<li><a href="Comment-Tips.html#Comment-Tips">C.3 Tips on Writing Comments</a>
+<li><a href="Function-Headers.html#Function-Headers">C.4 Conventional Headers for Octave Functions</a>
+<li><a href="Documentation-Tips.html#Documentation-Tips">C.5 Tips for Documentation Strings</a>
+</li></ul>
+<li><a name="toc_Contributing-Guidelines" href="Contributing-Guidelines.html#Contributing-Guidelines">Appendix D Contributing Guidelines</a>
+<ul>
+<li><a href="How-to-Contribute.html#How-to-Contribute">D.1 How to Contribute</a>
+<li><a href="General-Guidelines.html#General-Guidelines">D.2 General Guidelines</a>
+<li><a href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029">D.3 Octave Sources (m-files)</a>
+<li><a href="C_002b_002b-Sources.html#C_002b_002b-Sources">D.4 C++ Sources</a>
+<li><a href="Other-Sources.html#Other-Sources">D.5 Other Sources</a>
+</li></ul>
+<li><a name="toc_Trouble" href="Trouble.html#Trouble">Appendix E Known Causes of Trouble</a>
+<ul>
+<li><a href="Actual-Bugs.html#Actual-Bugs">E.1 Actual Bugs We Haven't Fixed Yet</a>
+<li><a href="Reporting-Bugs.html#Reporting-Bugs">E.2 Reporting Bugs</a>
+<li><a href="Bug-Criteria.html#Bug-Criteria">E.3 Have You Found a Bug?</a>
+<li><a href="Bug-Lists.html#Bug-Lists">E.4 Where to Report Bugs</a>
+<li><a href="Bug-Reporting.html#Bug-Reporting">E.5 How to Report Bugs</a>
+<li><a href="Sending-Patches.html#Sending-Patches">E.6 Sending Patches for Octave</a>
+<li><a href="Service.html#Service">E.7 How To Get Help with Octave</a>
+</li></ul>
+<li><a name="toc_Installation" href="Installation.html#Installation">Appendix F Installing Octave</a>
+<ul>
+<li><a href="Installation-Problems.html#Installation-Problems">F.1 Installation Problems</a>
+</li></ul>
+<li><a name="toc_Emacs-Octave-Support" href="Emacs-Octave-Support.html#Emacs-Octave-Support">Appendix G Emacs Octave Support</a>
+<ul>
+<li><a href="Installing-EOS.html#Installing-EOS">G.1 Installing EOS</a>
+<li><a href="Using-Octave-Mode.html#Using-Octave-Mode">G.2 Using Octave Mode</a>
+<li><a href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs">G.3 Running Octave From Within Emacs</a>
+<li><a href="Using-the-Emacs-Info-Reader-for-Octave.html#Using-the-Emacs-Info-Reader-for-Octave">G.4 Using the Emacs Info Reader for Octave</a>
+</li></ul>
+<li><a name="toc_Copying" href="Copying.html#Copying">Appendix H GNU GENERAL PUBLIC LICENSE</a>
+<li><a name="toc_Concept-Index" href="Concept-Index.html#Concept-Index">Concept Index</a>
+<li><a name="toc_Function-Index" href="Function-Index.html#Function-Index">Function Index</a>
+<li><a name="toc_Operator-Index" href="Operator-Index.html#Operator-Index">Operator Index</a>
+</li></ul>
+</div>
+
+<div class="node">
+<p>
+<a name="Top"></a>
+Next: <a rel="next" accesskey="n" href="Preface.html#Preface">Preface</a>,
+Up: <a rel="up" accesskey="u" href="../index.html#dir">(dir)</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">GNU Octave</h2>
+
+<p>This manual documents how to run, install and port GNU Octave, as well
+as its new features and incompatibilities, and how to report bugs. 
+It corresponds to GNU Octave version 3.2.4.
+
+<!--  -->
+<ul class="menu">
+<li><a accesskey="1" href="Preface.html#Preface">Preface</a>
+<li><a accesskey="2" href="Introduction.html#Introduction">Introduction</a>:                 A brief introduction to Octave. 
+<li><a accesskey="3" href="Getting-Started.html#Getting-Started">Getting Started</a>
+<li><a accesskey="4" href="Data-Types.html#Data-Types">Data Types</a>
+<li><a accesskey="5" href="Numeric-Data-Types.html#Numeric-Data-Types">Numeric Data Types</a>
+<li><a accesskey="6" href="Strings.html#Strings">Strings</a>
+<li><a accesskey="7" href="Data-Containers.html#Data-Containers">Data Containers</a>
+<li><a accesskey="8" href="Variables.html#Variables">Variables</a>
+<li><a accesskey="9" href="Expressions.html#Expressions">Expressions</a>
+<li><a href="Evaluation.html#Evaluation">Evaluation</a>
+<li><a href="Statements.html#Statements">Statements</a>:                   Looping and program flow control. 
+<li><a href="Functions-and-Scripts.html#Functions-and-Scripts">Functions and Scripts</a>
+<li><a href="Errors-and-Warnings.html#Errors-and-Warnings">Errors and Warnings</a>
+<li><a href="Debugging.html#Debugging">Debugging</a>
+<li><a href="Input-and-Output.html#Input-and-Output">Input and Output</a>
+<li><a href="Plotting.html#Plotting">Plotting</a>
+<li><a href="Matrix-Manipulation.html#Matrix-Manipulation">Matrix Manipulation</a>
+<li><a href="Arithmetic.html#Arithmetic">Arithmetic</a>
+<li><a href="Linear-Algebra.html#Linear-Algebra">Linear Algebra</a>
+<li><a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a>
+<li><a href="Diagonal-and-Permutation-Matrices.html#Diagonal-and-Permutation-Matrices">Diagonal and Permutation Matrices</a>
+<li><a href="Sparse-Matrices.html#Sparse-Matrices">Sparse Matrices</a>
+<li><a href="Numerical-Integration.html#Numerical-Integration">Numerical Integration</a>
+<li><a href="Differential-Equations.html#Differential-Equations">Differential Equations</a>
+<li><a href="Optimization.html#Optimization">Optimization</a>
+<li><a href="Statistics.html#Statistics">Statistics</a>
+<li><a href="Sets.html#Sets">Sets</a>
+<li><a href="Polynomial-Manipulations.html#Polynomial-Manipulations">Polynomial Manipulations</a>
+<li><a href="Interpolation.html#Interpolation">Interpolation</a>
+<li><a href="Geometry.html#Geometry">Geometry</a>
+<li><a href="Signal-Processing.html#Signal-Processing">Signal Processing</a>
+<li><a href="Image-Processing.html#Image-Processing">Image Processing</a>
+<li><a href="Audio-Processing.html#Audio-Processing">Audio Processing</a>
+<li><a href="Object-Oriented-Programming.html#Object-Oriented-Programming">Object Oriented Programming</a>
+<li><a href="System-Utilities.html#System-Utilities">System Utilities</a>
+<li><a href="Packages.html#Packages">Packages</a>
+<li><a href="Dynamically-Linked-Functions.html#Dynamically-Linked-Functions">Dynamically Linked Functions</a>
+<li><a href="Test-and-Demo-Functions.html#Test-and-Demo-Functions">Test and Demo Functions</a>
+<li><a href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
+<li><a href="Contributing-Guidelines.html#Contributing-Guidelines">Contributing Guidelines</a>
+<li><a href="Trouble.html#Trouble">Trouble</a>:                      If you have trouble installing Octave. 
+<li><a href="Installation.html#Installation">Installation</a>:                 How to configure, compile and install Octave. 
+<li><a href="Emacs-Octave-Support.html#Emacs-Octave-Support">Emacs Octave Support</a>
+<!-- * Grammar:: -->
+<li><a href="Copying.html#Copying">Copying</a>:                      The GNU General Public License. 
+<li><a href="Concept-Index.html#Concept-Index">Concept Index</a>:                An item for each concept. 
+<li><a href="Function-Index.html#Function-Index">Function Index</a>:               An item for each documented function. 
+<li><a href="Operator-Index.html#Operator-Index">Operator Index</a>:               An item for each documented operator.
+
+</li></ul>
+<p>--- The Detailed Node Listing ---
+
+<p>Preface
+
+</p>
+<ul class="menu">
+<li><a href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>
+<li><a href="How-You-Can-Contribute-to-Octave.html#How-You-Can-Contribute-to-Octave">How You Can Contribute to Octave</a>
+<li><a href="Distribution.html#Distribution">Distribution</a>
+
+</li></ul>
+<p>Introduction
+
+</p>
+<ul class="menu">
+<li><a href="Running-Octave.html#Running-Octave">Running Octave</a>
+<li><a href="Simple-Examples.html#Simple-Examples">Simple Examples</a>
+<li><a href="Conventions.html#Conventions">Conventions</a>
+
+</li></ul>
+<p>Conventions
+
+</p>
+<ul class="menu">
+<li><a href="Fonts.html#Fonts">Fonts</a>
+<li><a href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a>
+<li><a href="Printing-Notation.html#Printing-Notation">Printing Notation</a>
+<li><a href="Error-Messages.html#Error-Messages">Error Messages</a>
+<li><a href="Format-of-Descriptions.html#Format-of-Descriptions">Format of Descriptions</a>
+
+</li></ul>
+<p>Format of Descriptions
+
+</p>
+<ul class="menu">
+<li><a href="A-Sample-Function-Description.html#A-Sample-Function-Description">A Sample Function Description</a>
+<li><a href="A-Sample-Command-Description.html#A-Sample-Command-Description">A Sample Command Description</a>
+<li><a href="A-Sample-Variable-Description.html#A-Sample-Variable-Description">A Sample Variable Description</a>
+
+</li></ul>
+<p>Getting Started
+
+</p>
+<ul class="menu">
+<li><a href="Invoking-Octave-from-the-Command-Line.html#Invoking-Octave-from-the-Command-Line">Invoking Octave from the Command Line</a>
+<li><a href="Quitting-Octave.html#Quitting-Octave">Quitting Octave</a>
+<li><a href="Getting-Help.html#Getting-Help">Getting Help</a>
+<li><a href="Command-Line-Editing.html#Command-Line-Editing">Command Line Editing</a>
+<li><a href="Errors.html#Errors">Errors</a>
+<li><a href="Executable-Octave-Programs.html#Executable-Octave-Programs">Executable Octave Programs</a>
+<li><a href="Comments.html#Comments">Comments</a>
+
+</li></ul>
+<p>Invoking Octave from the Command Line
+
+</p>
+<ul class="menu">
+<li><a href="Command-Line-Options.html#Command-Line-Options">Command Line Options</a>
+<li><a href="Startup-Files.html#Startup-Files">Startup Files</a>
+
+</li></ul>
+<p>Command Line Editing
+
+</p>
+<ul class="menu">
+<li><a href="Cursor-Motion.html#Cursor-Motion">Cursor Motion</a>
+<li><a href="Killing-and-Yanking.html#Killing-and-Yanking">Killing and Yanking</a>
+<li><a href="Commands-For-Text.html#Commands-For-Text">Commands For Text</a>
+<li><a href="Commands-For-Completion.html#Commands-For-Completion">Commands For Completion</a>
+<li><a href="Commands-For-History.html#Commands-For-History">Commands For History</a>
+<li><a href="Customizing-readline.html#Customizing-readline">Customizing readline</a>
+<li><a href="Customizing-the-Prompt.html#Customizing-the-Prompt">Customizing the Prompt</a>
+<li><a href="Diary-and-Echo-Commands.html#Diary-and-Echo-Commands">Diary and Echo Commands</a>
+
+</li></ul>
+<p>Comments
+
+</p>
+<ul class="menu">
+<li><a href="Single-Line-Comments.html#Single-Line-Comments">Single Line Comments</a>
+<li><a href="Block-Comments.html#Block-Comments">Block Comments</a>
+<li><a href="Comments-and-the-Help-System.html#Comments-and-the-Help-System">Comments and the Help System</a>
+
+</li></ul>
+<p>Data Types
+
+</p>
+<ul class="menu">
+<li><a href="Built_002din-Data-Types.html#Built_002din-Data-Types">Built-in Data Types</a>
+<li><a href="User_002ddefined-Data-Types.html#User_002ddefined-Data-Types">User-defined Data Types</a>
+<li><a href="Object-Sizes.html#Object-Sizes">Object Sizes</a>
+
+</li></ul>
+<p>Built-in Data Types
+
+</p>
+<ul class="menu">
+<li><a href="Numeric-Objects.html#Numeric-Objects">Numeric Objects</a>
+<li><a href="Missing-Data.html#Missing-Data">Missing Data</a>
+<li><a href="String-Objects.html#String-Objects">String Objects</a>
+<li><a href="Data-Structure-Objects.html#Data-Structure-Objects">Data Structure Objects</a>
+<li><a href="Cell-Array-Objects.html#Cell-Array-Objects">Cell Array Objects</a>
+
+</li></ul>
+<p>Numeric Data Types
+
+</p>
+<ul class="menu">
+<li><a href="Matrices.html#Matrices">Matrices</a>
+<li><a href="Ranges.html#Ranges">Ranges</a>
+<li><a href="Single-Precision-Data-Types.html#Single-Precision-Data-Types">Single Precision Data Types</a>
+<li><a href="Integer-Data-Types.html#Integer-Data-Types">Integer Data Types</a>
+<li><a href="Bit-Manipulations.html#Bit-Manipulations">Bit Manipulations</a>
+<li><a href="Logical-Values.html#Logical-Values">Logical Values</a>
+<li><a href="Promotion-and-Demotion-of-Data-Types.html#Promotion-and-Demotion-of-Data-Types">Promotion and Demotion of Data Types</a>
+<li><a href="Predicates-for-Numeric-Objects.html#Predicates-for-Numeric-Objects">Predicates for Numeric Objects</a>
+
+</li></ul>
+<p>Matrices
+
+</p>
+<ul class="menu">
+<li><a href="Empty-Matrices.html#Empty-Matrices">Empty Matrices</a>
+
+</li></ul>
+<p>Integer Data Types
+
+</p>
+<ul class="menu">
+<li><a href="Integer-Arithmetic.html#Integer-Arithmetic">Integer Arithmetic</a>
+
+</li></ul>
+<p>Strings
+
+</p>
+<ul class="menu">
+<li><a href="Escape-Sequences-in-string-constants.html#Escape-Sequences-in-string-constants">Escape Sequences in string constants</a>
+<li><a href="Character-Arrays.html#Character-Arrays">Character Arrays</a>
+<li><a href="Creating-Strings.html#Creating-Strings">Creating Strings</a>
+<li><a href="Comparing-Strings.html#Comparing-Strings">Comparing Strings</a>
+<li><a href="Manipulating-Strings.html#Manipulating-Strings">Manipulating Strings</a>
+<li><a href="String-Conversions.html#String-Conversions">String Conversions</a>
+<li><a href="Character-Class-Functions.html#Character-Class-Functions">Character Class Functions</a>
+
+</li></ul>
+<p>Creating Strings
+
+</p>
+<ul class="menu">
+<li><a href="Concatenating-Strings.html#Concatenating-Strings">Concatenating Strings</a>
+<li><a href="Conversion-of-Numerical-Data-to-Strings.html#Conversion-of-Numerical-Data-to-Strings">Conversion of Numerical Data to Strings</a>
+
+</li></ul>
+<p>Data Containers
+
+</p>
+<ul class="menu">
+<li><a href="Data-Structures.html#Data-Structures">Data Structures</a>
+<li><a href="Cell-Arrays.html#Cell-Arrays">Cell Arrays</a>
+<li><a href="Comma-Separated-Lists.html#Comma-Separated-Lists">Comma Separated Lists</a>
+
+</li></ul>
+<p>Data Structures
+
+</p>
+<ul class="menu">
+<li><a href="Structure-Arrays.html#Structure-Arrays">Structure Arrays</a>
+<li><a href="Creating-Structures.html#Creating-Structures">Creating Structures</a>
+<li><a href="Manipulating-Structures.html#Manipulating-Structures">Manipulating Structures</a>
+<li><a href="Processing-Data-in-Structures.html#Processing-Data-in-Structures">Processing Data in Structures</a>
+
+</li></ul>
+<p>Cell Arrays
+
+</p>
+<ul class="menu">
+<li><a href="Creating-Cell-Arrays.html#Creating-Cell-Arrays">Creating Cell Arrays</a>
+<li><a href="Indexing-Cell-Arrays.html#Indexing-Cell-Arrays">Indexing Cell Arrays</a>
+<li><a href="Cell-Arrays-of-Strings.html#Cell-Arrays-of-Strings">Cell Arrays of Strings</a>
+<li><a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a>
+
+</li></ul>
+<p>Variables
+
+</p>
+<ul class="menu">
+<li><a href="Global-Variables.html#Global-Variables">Global Variables</a>
+<li><a href="Persistent-Variables.html#Persistent-Variables">Persistent Variables</a>
+<li><a href="Status-of-Variables.html#Status-of-Variables">Status of Variables</a>
+
+</li></ul>
+<p>Expressions
+
+</p>
+<ul class="menu">
+<li><a href="Index-Expressions.html#Index-Expressions">Index Expressions</a>
+<li><a href="Calling-Functions.html#Calling-Functions">Calling Functions</a>
+<li><a href="Arithmetic-Ops.html#Arithmetic-Ops">Arithmetic Ops</a>
+<li><a href="Comparison-Ops.html#Comparison-Ops">Comparison Ops</a>
+<li><a href="Boolean-Expressions.html#Boolean-Expressions">Boolean Expressions</a>
+<li><a href="Assignment-Ops.html#Assignment-Ops">Assignment Ops</a>
+<li><a href="Increment-Ops.html#Increment-Ops">Increment Ops</a>
+<li><a href="Operator-Precedence.html#Operator-Precedence">Operator Precedence</a>
+
+</li></ul>
+<p>Calling Functions
+
+</p>
+<ul class="menu">
+<li><a href="Call-by-Value.html#Call-by-Value">Call by Value</a>
+<li><a href="Recursion.html#Recursion">Recursion</a>
+
+</li></ul>
+<p>Boolean Expressions
+
+</p>
+<ul class="menu">
+<li><a href="Element_002dby_002delement-Boolean-Operators.html#Element_002dby_002delement-Boolean-Operators">Element-by-element Boolean Operators</a>
+<li><a href="Short_002dcircuit-Boolean-Operators.html#Short_002dcircuit-Boolean-Operators">Short-circuit Boolean Operators</a>
+
+</li></ul>
+<p>Evaluation
+
+</p>
+<ul class="menu">
+<li><a href="Calling-a-Function-by-its-Name.html#Calling-a-Function-by-its-Name">Calling a Function by its Name</a>
+<li><a href="Evaluation-in-a-Different-Context.html#Evaluation-in-a-Different-Context">Evaluation in a Different Context</a>
+
+</li></ul>
+<p>Statements
+
+</p>
+<ul class="menu">
+<li><a href="The-_003ccode_003eif_003c_002fcode_003e-Statement.html#The-_003ccode_003eif_003c_002fcode_003e-Statement">The <code>if</code> Statement</a>
+<li><a href="The-_003ccode_003eswitch_003c_002fcode_003e-Statement.html#The-_003ccode_003eswitch_003c_002fcode_003e-Statement">The <code>switch</code> Statement</a>
+<li><a href="The-_003ccode_003ewhile_003c_002fcode_003e-Statement.html#The-_003ccode_003ewhile_003c_002fcode_003e-Statement">The <code>while</code> Statement</a>
+<li><a href="The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement.html#The-_003ccode_003edo_002duntil_003c_002fcode_003e-Statement">The <code>do-until</code> Statement</a>
+<li><a href="The-_003ccode_003efor_003c_002fcode_003e-Statement.html#The-_003ccode_003efor_003c_002fcode_003e-Statement">The <code>for</code> Statement</a>
+<li><a href="The-_003ccode_003ebreak_003c_002fcode_003e-Statement.html#The-_003ccode_003ebreak_003c_002fcode_003e-Statement">The <code>break</code> Statement</a>
+<li><a href="The-_003ccode_003econtinue_003c_002fcode_003e-Statement.html#The-_003ccode_003econtinue_003c_002fcode_003e-Statement">The <code>continue</code> Statement</a>
+<li><a href="The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement.html#The-_003ccode_003eunwind_005fprotect_003c_002fcode_003e-Statement">The <code>unwind_protect</code> Statement</a>
+<li><a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>
+<li><a href="Continuation-Lines.html#Continuation-Lines">Continuation Lines</a>
+
+</li></ul>
+<p>The <code>switch</code> Statement
+
+</p>
+<ul class="menu">
+<li><a href="Notes-for-the-C-programmer.html#Notes-for-the-C-programmer">Notes for the C programmer</a>
+
+</li></ul>
+<p>The <code>for</code> Statement
+
+</p>
+<ul class="menu">
+<li><a href="Looping-Over-Structure-Elements.html#Looping-Over-Structure-Elements">Looping Over Structure Elements</a>
+
+</li></ul>
+<p>Functions and Scripts
+
+</p>
+<ul class="menu">
+<li><a href="Defining-Functions.html#Defining-Functions">Defining Functions</a>
+<li><a href="Multiple-Return-Values.html#Multiple-Return-Values">Multiple Return Values</a>
+<li><a href="Variable_002dlength-Argument-Lists.html#Variable_002dlength-Argument-Lists">Variable-length Argument Lists</a>
+<li><a href="Variable_002dlength-Return-Lists.html#Variable_002dlength-Return-Lists">Variable-length Return Lists</a>
+<li><a href="Returning-From-a-Function.html#Returning-From-a-Function">Returning From a Function</a>
+<li><a href="Default-Arguments.html#Default-Arguments">Default Arguments</a>
+<li><a href="Function-Files.html#Function-Files">Function Files</a>
+<li><a href="Script-Files.html#Script-Files">Script Files</a>
+<li><a href="Function-Handles-Inline-Functions-and-Anonymous-Functions.html#Function-Handles-Inline-Functions-and-Anonymous-Functions">Function Handles Inline Functions and Anonymous Functions</a>
+<li><a href="Commands.html#Commands">Commands</a>
+<li><a href="Organization-of-Functions.html#Organization-of-Functions">Organization of Functions</a>
+
+</li></ul>
+<p>Function Files
+
+</p>
+<ul class="menu">
+<li><a href="Manipulating-the-load-path.html#Manipulating-the-load-path">Manipulating the load path</a>
+<li><a href="Subfunctions.html#Subfunctions">Subfunctions</a>
+<li><a href="Private-Functions.html#Private-Functions">Private Functions</a>
+<li><a href="Overloading-and-Autoloading.html#Overloading-and-Autoloading">Overloading and Autoloading</a>
+<li><a href="Function-Locking.html#Function-Locking">Function Locking</a>
+<li><a href="Function-Precedence.html#Function-Precedence">Function Precedence</a>
+
+</li></ul>
+<p>Function Handles Inline Functions and Anonymous Functions
+
+</p>
+<ul class="menu">
+<li><a href="Function-Handles.html#Function-Handles">Function Handles</a>
+<li><a href="Anonymous-Functions.html#Anonymous-Functions">Anonymous Functions</a>
+<li><a href="Inline-Functions.html#Inline-Functions">Inline Functions</a>
+
+</li></ul>
+<p>Errors and Warnings
+
+</p>
+<ul class="menu">
+<li><a href="Handling-Errors.html#Handling-Errors">Handling Errors</a>
+<li><a href="Handling-Warnings.html#Handling-Warnings">Handling Warnings</a>
+
+</li></ul>
+<p>Handling Errors
+
+</p>
+<ul class="menu">
+<li><a href="Raising-Errors.html#Raising-Errors">Raising Errors</a>
+<li><a href="Catching-Errors.html#Catching-Errors">Catching Errors</a>
+
+</li></ul>
+<p>Handling Warnings
+
+</p>
+<ul class="menu">
+<li><a href="Issuing-Warnings.html#Issuing-Warnings">Issuing Warnings</a>
+<li><a href="Enabling-and-Disabling-Warnings.html#Enabling-and-Disabling-Warnings">Enabling and Disabling Warnings</a>
+
+</li></ul>
+<p>Debugging
+
+</p>
+<ul class="menu">
+<li><a href="Entering-Debug-Mode.html#Entering-Debug-Mode">Entering Debug Mode</a>
+<li><a href="Leaving-Debug-Mode.html#Leaving-Debug-Mode">Leaving Debug Mode</a>
+<li><a href="Breakpoints.html#Breakpoints">Breakpoints</a>
+<li><a href="Debug-Mode.html#Debug-Mode">Debug Mode</a>
+<li><a href="Call-Stack.html#Call-Stack">Call Stack</a>
+
+</li></ul>
+<p>Input and Output
+
+</p>
+<ul class="menu">
+<li><a href="Basic-Input-and-Output.html#Basic-Input-and-Output">Basic Input and Output</a>
+<li><a href="C_002dStyle-I_002fO-Functions.html#C_002dStyle-I_002fO-Functions">C-Style I/O Functions</a>
+
+</li></ul>
+<p>Basic Input and Output
+
+</p>
+<ul class="menu">
+<li><a href="Terminal-Output.html#Terminal-Output">Terminal Output</a>
+<li><a href="Terminal-Input.html#Terminal-Input">Terminal Input</a>
+<li><a href="Simple-File-I_002fO.html#Simple-File-I_002fO">Simple File I/O</a>
+<li><a href="Rational-Approximations.html#Rational-Approximations">Rational Approximations</a>
+
+</li></ul>
+<p>Terminal Output
+
+</p>
+<ul class="menu">
+<li><a href="Paging-Screen-Output.html#Paging-Screen-Output">Paging Screen Output</a>
+
+</li></ul>
+<p>Simple File I/O
+
+</p>
+<ul class="menu">
+<li><a href="Saving-Data-on-Unexpected-Exits.html#Saving-Data-on-Unexpected-Exits">Saving Data on Unexpected Exits</a>
+
+</li></ul>
+<p>C-Style I/O Functions
+
+</p>
+<ul class="menu">
+<li><a href="Opening-and-Closing-Files.html#Opening-and-Closing-Files">Opening and Closing Files</a>
+<li><a href="Simple-Output.html#Simple-Output">Simple Output</a>
+<li><a href="Line_002dOriented-Input.html#Line_002dOriented-Input">Line-Oriented Input</a>
+<li><a href="Formatted-Output.html#Formatted-Output">Formatted Output</a>
+<li><a href="Output-Conversion-for-Matrices.html#Output-Conversion-for-Matrices">Output Conversion for Matrices</a>
+<li><a href="Output-Conversion-Syntax.html#Output-Conversion-Syntax">Output Conversion Syntax</a>
+<li><a href="Table-of-Output-Conversions.html#Table-of-Output-Conversions">Table of Output Conversions</a>
+<li><a href="Integer-Conversions.html#Integer-Conversions">Integer Conversions</a>
+<li><a href="Floating_002dPoint-Conversions.html#Floating_002dPoint-Conversions">Floating-Point Conversions</a>
+<li><a href="Other-Output-Conversions.html#Other-Output-Conversions">Other Output Conversions</a>
+<li><a href="Formatted-Input.html#Formatted-Input">Formatted Input</a>
+<li><a href="Input-Conversion-Syntax.html#Input-Conversion-Syntax">Input Conversion Syntax</a>
+<li><a href="Table-of-Input-Conversions.html#Table-of-Input-Conversions">Table of Input Conversions</a>
+<li><a href="Numeric-Input-Conversions.html#Numeric-Input-Conversions">Numeric Input Conversions</a>
+<li><a href="String-Input-Conversions.html#String-Input-Conversions">String Input Conversions</a>
+<li><a href="Binary-I_002fO.html#Binary-I_002fO">Binary I/O</a>
+<li><a href="Temporary-Files.html#Temporary-Files">Temporary Files</a>
+<li><a href="EOF-and-Errors.html#EOF-and-Errors">EOF and Errors</a>
+<li><a href="File-Positioning.html#File-Positioning">File Positioning</a>
+
+</li></ul>
+<p>Plotting
+
+</p>
+<ul class="menu">
+<li><a href="Plotting-Basics.html#Plotting-Basics">Plotting Basics</a>
+<li><a href="Advanced-Plotting.html#Advanced-Plotting">Advanced Plotting</a>
+
+</li></ul>
+<p>Plotting Basics
+
+</p>
+<ul class="menu">
+<li><a href="Two_002dDimensional-Plots.html#Two_002dDimensional-Plots">Two-Dimensional Plots</a>
+<li><a href="Three_002dDimensional-Plotting.html#Three_002dDimensional-Plotting">Three-Dimensional Plotting</a>
+<li><a href="Plot-Annotations.html#Plot-Annotations">Plot Annotations</a>
+<li><a href="Multiple-Plots-on-One-Page.html#Multiple-Plots-on-One-Page">Multiple Plots on One Page</a>
+<li><a href="Multiple-Plot-Windows.html#Multiple-Plot-Windows">Multiple Plot Windows</a>
+<li><a href="Printing-Plots.html#Printing-Plots">Printing Plots</a>
+<li><a href="Interacting-with-plots.html#Interacting-with-plots">Interacting with plots</a>
+<li><a href="Test-Plotting-Functions.html#Test-Plotting-Functions">Test Plotting Functions</a>
+
+</li></ul>
+<p>Two-Dimensional Plots
+
+</p>
+<ul class="menu">
+<li><a href="Two_002ddimensional-Function-Plotting.html#Two_002ddimensional-Function-Plotting">Two-dimensional Function Plotting</a>
+
+</li></ul>
+<p>Three-Dimensional Plotting
+
+</p>
+<ul class="menu">
+<li><a href="Three_002ddimensional-Function-Plotting.html#Three_002ddimensional-Function-Plotting">Three-dimensional Function Plotting</a>
+<li><a href="Three_002ddimensional-Geometric-Shapes.html#Three_002ddimensional-Geometric-Shapes">Three-dimensional Geometric Shapes</a>
+
+</li></ul>
+<p>Advanced Plotting
+
+</p>
+<ul class="menu">
+<li><a href="Graphics-Objects.html#Graphics-Objects">Graphics Objects</a>
+<li><a href="Graphics-Object-Properties.html#Graphics-Object-Properties">Graphics Object Properties</a>
+<li><a href="Managing-Default-Properties.html#Managing-Default-Properties">Managing Default Properties</a>
+<li><a href="Colors.html#Colors">Colors</a>
+<li><a href="Line-Styles.html#Line-Styles">Line Styles</a>
+<li><a href="Marker-Styles.html#Marker-Styles">Marker Styles</a>
+<li><a href="Callbacks.html#Callbacks">Callbacks</a>
+<li><a href="Object-Groups.html#Object-Groups">Object Groups</a>
+<li><a href="Graphics-backends.html#Graphics-backends">Graphics backends</a>
+
+</li></ul>
+<p>Graphics Object Properties
+
+</p>
+<ul class="menu">
+<li><a href="Root-Figure-Properties.html#Root-Figure-Properties">Root Figure Properties</a>
+<li><a href="Figure-Properties.html#Figure-Properties">Figure Properties</a>
+<li><a href="Axes-Properties.html#Axes-Properties">Axes Properties</a>
+<li><a href="Line-Properties.html#Line-Properties">Line Properties</a>
+<li><a href="Text-Properties.html#Text-Properties">Text Properties</a>
+<li><a href="Image-Properties.html#Image-Properties">Image Properties</a>
+<li><a href="Patch-Properties.html#Patch-Properties">Patch Properties</a>
+<li><a href="Surface-Properties.html#Surface-Properties">Surface Properties</a>
+<li><a href="Searching-Properties.html#Searching-Properties">Searching Properties</a>
+
+</li></ul>
+<p>Object Groups
+
+</p>
+<ul class="menu">
+<li><a href="Data-sources-in-object-groups.html#Data-sources-in-object-groups">Data sources in object groups</a>
+<li><a href="Area-series.html#Area-series">Area series</a>
+<li><a href="Bar-series.html#Bar-series">Bar series</a>
+<li><a href="Contour-groups.html#Contour-groups">Contour groups</a>
+<li><a href="Error-bar-series.html#Error-bar-series">Error bar series</a>
+<li><a href="Line-series.html#Line-series">Line series</a>
+<li><a href="Quiver-group.html#Quiver-group">Quiver group</a>
+<li><a href="Scatter-group.html#Scatter-group">Scatter group</a>
+<li><a href="Stair-group.html#Stair-group">Stair group</a>
+<li><a href="Stem-Series.html#Stem-Series">Stem Series</a>
+<li><a href="Surface-group.html#Surface-group">Surface group</a>
+
+</li></ul>
+<p>Graphics backends
+
+</p>
+<ul class="menu">
+<li><a href="Interaction-with-gnuplot.html#Interaction-with-gnuplot">Interaction with gnuplot</a>
+
+</li></ul>
+<p>Matrix Manipulation
+
+</p>
+<ul class="menu">
+<li><a href="Finding-Elements-and-Checking-Conditions.html#Finding-Elements-and-Checking-Conditions">Finding Elements and Checking Conditions</a>
+<li><a href="Rearranging-Matrices.html#Rearranging-Matrices">Rearranging Matrices</a>
+<li><a href="Applying-a-Function-to-an-Array.html#Applying-a-Function-to-an-Array">Applying a Function to an Array</a>
+<li><a href="Special-Utility-Matrices.html#Special-Utility-Matrices">Special Utility Matrices</a>
+<li><a href="Famous-Matrices.html#Famous-Matrices">Famous Matrices</a>
+
+</li></ul>
+<p>Arithmetic
+
+</p>
+<ul class="menu">
+<li><a href="Exponents-and-Logarithms.html#Exponents-and-Logarithms">Exponents and Logarithms</a>
+<li><a href="Complex-Arithmetic.html#Complex-Arithmetic">Complex Arithmetic</a>
+<li><a href="Trigonometry.html#Trigonometry">Trigonometry</a>
+<li><a href="Sums-and-Products.html#Sums-and-Products">Sums and Products</a>
+<li><a href="Utility-Functions.html#Utility-Functions">Utility Functions</a>
+<li><a href="Special-Functions.html#Special-Functions">Special Functions</a>
+<li><a href="Coordinate-Transformations.html#Coordinate-Transformations">Coordinate Transformations</a>
+<li><a href="Mathematical-Constants.html#Mathematical-Constants">Mathematical Constants</a>
+
+</li></ul>
+<p>Linear Algebra
+
+</p>
+<ul class="menu">
+<li><a href="Techniques-used-for-Linear-Algebra.html#Techniques-used-for-Linear-Algebra">Techniques used for Linear Algebra</a>
+<li><a href="Basic-Matrix-Functions.html#Basic-Matrix-Functions">Basic Matrix Functions</a>
+<li><a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>
+<li><a href="Functions-of-a-Matrix.html#Functions-of-a-Matrix">Functions of a Matrix</a>
+<li><a href="Specialized-Solvers.html#Specialized-Solvers">Specialized Solvers</a>
+
+</li></ul>
+<p>Diagonal and Permutation Matrices
+
+</p>
+<ul class="menu">
+<li><a href="Basic-Usage.html#Basic-Usage">Basic Usage</a>:           Creation and Manipulation of Diagonal and Permutation Matrices
+<li><a href="Matrix-Algebra.html#Matrix-Algebra">Matrix Algebra</a>:        Linear Algebra with Diagonal and Permutation Matrices
+<li><a href="Function-Support.html#Function-Support">Function Support</a>:      Functions That Are Aware of These Matrices
+<li><a href="Example-Codes.html#Example-Codes">Example Codes</a>:         Some Examples of Usage
+<li><a href="Zeros-Treatment.html#Zeros-Treatment">Zeros Treatment</a>:       The Differences in Treatment of Zero Elements
+
+</li></ul>
+<p>Basic Usage
+
+</p>
+<ul class="menu">
+<li><a href="Creating-Diagonal-Matrices.html#Creating-Diagonal-Matrices">Creating Diagonal Matrices</a>
+<li><a href="Creating-Permutation-Matrices.html#Creating-Permutation-Matrices">Creating Permutation Matrices</a>
+<li><a href="Explicit-and-Implicit-Conversions.html#Explicit-and-Implicit-Conversions">Explicit and Implicit Conversions</a>
+
+</li></ul>
+<p>Matrix Algebra
+
+</p>
+<ul class="menu">
+<li><a href="Expressions-Involving-Diagonal-Matrices.html#Expressions-Involving-Diagonal-Matrices">Expressions Involving Diagonal Matrices</a>
+<li><a href="Expressions-Involving-Permutation-Matrices.html#Expressions-Involving-Permutation-Matrices">Expressions Involving Permutation Matrices</a>
+
+</li></ul>
+<p>Function Support
+
+</p>
+<ul class="menu">
+<li><a href="Diagonal-Matrix-Functions.html#Diagonal-Matrix-Functions">Diagonal Matrix Functions</a>
+<li><a href="Permutation-Matrix-Functions.html#Permutation-Matrix-Functions">Permutation Matrix Functions</a>
+
+</li></ul>
+<p>Sparse Matrices
+
+</p>
+<ul class="menu">
+<li><a href="Basics.html#Basics">Basics</a>:                       Creation and Manipulation of Sparse Matrices
+<li><a href="Sparse-Linear-Algebra.html#Sparse-Linear-Algebra">Sparse Linear Algebra</a>:        Linear Algebra on Sparse Matrices
+<li><a href="Iterative-Techniques.html#Iterative-Techniques">Iterative Techniques</a>:         Iterative Techniques
+<li><a href="Real-Life-Example.html#Real-Life-Example">Real Life Example</a>:            Using Sparse Matrices
+
+</li></ul>
+<p>Basics
+
+</p>
+<ul class="menu">
+<li><a href="Storage-of-Sparse-Matrices.html#Storage-of-Sparse-Matrices">Storage of Sparse Matrices</a>
+<li><a href="Creating-Sparse-Matrices.html#Creating-Sparse-Matrices">Creating Sparse Matrices</a>
+<li><a href="Information.html#Information">Information</a>
+<li><a href="Operators-and-Functions.html#Operators-and-Functions">Operators and Functions</a>
+
+</li></ul>
+<p>Operators and Functions
+
+</p>
+<ul class="menu">
+<li><a href="Sparse-Functions.html#Sparse-Functions">Sparse Functions</a>
+<li><a href="Return-Types-of-Operators-and-Functions.html#Return-Types-of-Operators-and-Functions">Return Types of Operators and Functions</a>
+<li><a href="Mathematical-Considerations.html#Mathematical-Considerations">Mathematical Considerations</a>
+
+</li></ul>
+<p>Numerical Integration
+
+</p>
+<ul class="menu">
+<li><a href="Functions-of-One-Variable.html#Functions-of-One-Variable">Functions of One Variable</a>
+<li><a href="Functions-of-Multiple-Variables.html#Functions-of-Multiple-Variables">Functions of Multiple Variables</a>
+<li><a href="Orthogonal-Collocation.html#Orthogonal-Collocation">Orthogonal Collocation</a>
+
+</li></ul>
+<p>Differential Equations
+
+</p>
+<ul class="menu">
+<li><a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a>
+<li><a href="Differential_002dAlgebraic-Equations.html#Differential_002dAlgebraic-Equations">Differential-Algebraic Equations</a>
+
+</li></ul>
+<p>Optimization
+
+</p>
+<ul class="menu">
+<li><a href="Linear-Programming.html#Linear-Programming">Linear Programming</a>
+<li><a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>
+<li><a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>
+<li><a href="Linear-Least-Squares.html#Linear-Least-Squares">Linear Least Squares</a>
+
+</li></ul>
+<p>Statistics
+
+</p>
+<ul class="menu">
+<li><a href="Descriptive-Statistics.html#Descriptive-Statistics">Descriptive Statistics</a>
+<li><a href="Basic-Statistical-Functions.html#Basic-Statistical-Functions">Basic Statistical Functions</a>
+<li><a href="Statistical-Plots.html#Statistical-Plots">Statistical Plots</a>
+<li><a href="Tests.html#Tests">Tests</a>
+<li><a href="Models.html#Models">Models</a>
+<li><a href="Distributions.html#Distributions">Distributions</a>
+<li><a href="Random-Number-Generation.html#Random-Number-Generation">Random Number Generation</a>
+
+</li></ul>
+<p>Sets
+
+</p>
+<ul class="menu">
+<li><a href="Set-Operations.html#Set-Operations">Set Operations</a>
+
+</li></ul>
+<p>Polynomial Manipulations
+
+</p>
+<ul class="menu">
+<li><a href="Evaluating-Polynomials.html#Evaluating-Polynomials">Evaluating Polynomials</a>
+<li><a href="Finding-Roots.html#Finding-Roots">Finding Roots</a>
+<li><a href="Products-of-Polynomials.html#Products-of-Polynomials">Products of Polynomials</a>
+<li><a href="Derivatives-and-Integrals.html#Derivatives-and-Integrals">Derivatives and Integrals</a>
+<li><a href="Polynomial-Interpolation.html#Polynomial-Interpolation">Polynomial Interpolation</a>
+<li><a href="Miscellaneous-Functions.html#Miscellaneous-Functions">Miscellaneous Functions</a>
+
+</li></ul>
+<p>Interpolation
+
+</p>
+<ul class="menu">
+<li><a href="One_002ddimensional-Interpolation.html#One_002ddimensional-Interpolation">One-dimensional Interpolation</a>
+<li><a href="Multi_002ddimensional-Interpolation.html#Multi_002ddimensional-Interpolation">Multi-dimensional Interpolation</a>
+
+</li></ul>
+<p>Geometry
+
+</p>
+<ul class="menu">
+<li><a href="Delaunay-Triangulation.html#Delaunay-Triangulation">Delaunay Triangulation</a>
+<li><a href="Voronoi-Diagrams.html#Voronoi-Diagrams">Voronoi Diagrams</a>
+<li><a href="Convex-Hull.html#Convex-Hull">Convex Hull</a>
+<li><a href="Interpolation-on-Scattered-Data.html#Interpolation-on-Scattered-Data">Interpolation on Scattered Data</a>
+
+</li></ul>
+<p>Delaunay Triangulation
+
+</p>
+<ul class="menu">
+<li><a href="Plotting-the-Triangulation.html#Plotting-the-Triangulation">Plotting the Triangulation</a>
+<li><a href="Identifying-points-in-Triangulation.html#Identifying-points-in-Triangulation">Identifying points in Triangulation</a>
+
+</li></ul>
+<p>Image Processing
+
+</p>
+<ul class="menu">
+<li><a href="Loading-and-Saving-Images.html#Loading-and-Saving-Images">Loading and Saving Images</a>
+<li><a href="Displaying-Images.html#Displaying-Images">Displaying Images</a>
+<li><a href="Representing-Images.html#Representing-Images">Representing Images</a>
+<li><a href="Plotting-on-top-of-Images.html#Plotting-on-top-of-Images">Plotting on top of Images</a>
+<li><a href="Color-Conversion.html#Color-Conversion">Color Conversion</a>
+
+</li></ul>
+<p>Object Oriented Programming
+
+</p>
+<ul class="menu">
+<li><a href="Creating-a-Class.html#Creating-a-Class">Creating a Class</a>
+<li><a href="Manipulating-Classes.html#Manipulating-Classes">Manipulating Classes</a>
+<li><a href="Indexing-Objects.html#Indexing-Objects">Indexing Objects</a>
+<li><a href="Overloading-Objects.html#Overloading-Objects">Overloading Objects</a>
+
+</li></ul>
+<p>Overloading Objects
+
+</p>
+<ul class="menu">
+<li><a href="Function-Overloading.html#Function-Overloading">Function Overloading</a>
+<li><a href="Operator-Overloading.html#Operator-Overloading">Operator Overloading</a>
+<li><a href="Precedence-of-Objects.html#Precedence-of-Objects">Precedence of Objects</a>
+
+</li></ul>
+<p>System Utilities
+
+</p>
+<ul class="menu">
+<li><a href="Timing-Utilities.html#Timing-Utilities">Timing Utilities</a>
+<li><a href="Filesystem-Utilities.html#Filesystem-Utilities">Filesystem Utilities</a>
+<li><a href="File-Archiving-Utilities.html#File-Archiving-Utilities">File Archiving Utilities</a>
+<li><a href="Networking-Utilities.html#Networking-Utilities">Networking Utilities</a>
+<li><a href="Controlling-Subprocesses.html#Controlling-Subprocesses">Controlling Subprocesses</a>
+<li><a href="Process-ID-Information.html#Process-ID-Information">Process ID Information</a>
+<li><a href="Environment-Variables.html#Environment-Variables">Environment Variables</a>
+<li><a href="Current-Working-Directory.html#Current-Working-Directory">Current Working Directory</a>
+<li><a href="Password-Database-Functions.html#Password-Database-Functions">Password Database Functions</a>
+<li><a href="Group-Database-Functions.html#Group-Database-Functions">Group Database Functions</a>
+<li><a href="System-Information.html#System-Information">System Information</a>
+<li><a href="Hashing-Functions.html#Hashing-Functions">Hashing Functions</a>
+
+</li></ul>
+<p>Packages
+
+</p>
+<ul class="menu">
+<li><a href="Installing-and-Removing-Packages.html#Installing-and-Removing-Packages">Installing and Removing Packages</a>
+<li><a href="Using-Packages.html#Using-Packages">Using Packages</a>
+<li><a href="Administrating-Packages.html#Administrating-Packages">Administrating Packages</a>
+<li><a href="Creating-Packages.html#Creating-Packages">Creating Packages</a>
+
+</li></ul>
+<p>Creating Packages
+
+</p>
+<ul class="menu">
+<li><a href="The-DESCRIPTION-File.html#The-DESCRIPTION-File">The DESCRIPTION File</a>
+<li><a href="The-INDEX-file.html#The-INDEX-file">The INDEX file</a>
+<li><a href="PKG_005fADD-and-PKG_005fDEL-directives.html#PKG_005fADD-and-PKG_005fDEL-directives">PKG_ADD and PKG_DEL directives</a>
+
+</li></ul>
+<p>Dynamically Linked Functions
+
+</p>
+<ul class="menu">
+<li><a href="Oct_002dFiles.html#Oct_002dFiles">Oct-Files</a>
+<li><a href="Mex_002dFiles.html#Mex_002dFiles">Mex-Files</a>
+<li><a href="Standalone-Programs.html#Standalone-Programs">Standalone Programs</a>
+
+</li></ul>
+<p>Oct-Files
+
+</p>
+<ul class="menu">
+<li><a href="Getting-Started-with-Oct_002dFiles.html#Getting-Started-with-Oct_002dFiles">Getting Started with Oct-Files</a>
+<li><a href="Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles">Matrices and Arrays in Oct-Files</a>
+<li><a href="Character-Strings-in-Oct_002dFiles.html#Character-Strings-in-Oct_002dFiles">Character Strings in Oct-Files</a>
+<li><a href="Cell-Arrays-in-Oct_002dFiles.html#Cell-Arrays-in-Oct_002dFiles">Cell Arrays in Oct-Files</a>
+<li><a href="Structures-in-Oct_002dFiles.html#Structures-in-Oct_002dFiles">Structures in Oct-Files</a>
+<li><a href="Sparse-Matrices-in-Oct_002dFiles.html#Sparse-Matrices-in-Oct_002dFiles">Sparse Matrices in Oct-Files</a>
+<li><a href="Accessing-Global-Variables-in-Oct_002dFiles.html#Accessing-Global-Variables-in-Oct_002dFiles">Accessing Global Variables in Oct-Files</a>
+<li><a href="Calling-Octave-Functions-from-Oct_002dFiles.html#Calling-Octave-Functions-from-Oct_002dFiles">Calling Octave Functions from Oct-Files</a>
+<li><a href="Calling-External-Code-from-Oct_002dFiles.html#Calling-External-Code-from-Oct_002dFiles">Calling External Code from Oct-Files</a>
+<li><a href="Allocating-Local-Memory-in-Oct_002dFiles.html#Allocating-Local-Memory-in-Oct_002dFiles">Allocating Local Memory in Oct-Files</a>
+<li><a href="Input-Parameter-Checking-in-Oct_002dFiles.html#Input-Parameter-Checking-in-Oct_002dFiles">Input Parameter Checking in Oct-Files</a>
+<li><a href="Exception-and-Error-Handling-in-Oct_002dFiles.html#Exception-and-Error-Handling-in-Oct_002dFiles">Exception and Error Handling in Oct-Files</a>
+<li><a href="Documentation-and-Test-of-Oct_002dFiles.html#Documentation-and-Test-of-Oct_002dFiles">Documentation and Test of Oct-Files</a>
+
+</li></ul>
+<p>Sparse Matrices in Oct-Files
+
+</p>
+<ul class="menu">
+<li><a href="Array-and-Sparse-Differences.html#Array-and-Sparse-Differences">Array and Sparse Differences</a>
+<li><a href="Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles">Creating Sparse Matrices in Oct-Files</a>
+<li><a href="Using-Sparse-Matrices-in-Oct_002dFiles.html#Using-Sparse-Matrices-in-Oct_002dFiles">Using Sparse Matrices in Oct-Files</a>
+
+</li></ul>
+<p>Mex-Files
+
+</p>
+<ul class="menu">
+<li><a href="Getting-Started-with-Mex_002dFiles.html#Getting-Started-with-Mex_002dFiles">Getting Started with Mex-Files</a>
+<li><a href="Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html#Working-with-Matrices-and-Arrays-in-Mex_002dFiles">Working with Matrices and Arrays in Mex-Files</a>
+<li><a href="Character-Strings-in-Mex_002dFiles.html#Character-Strings-in-Mex_002dFiles">Character Strings in Mex-Files</a>
+<li><a href="Cell-Arrays-with-Mex_002dFiles.html#Cell-Arrays-with-Mex_002dFiles">Cell Arrays with Mex-Files</a>
+<li><a href="Structures-with-Mex_002dFiles.html#Structures-with-Mex_002dFiles">Structures with Mex-Files</a>
+<li><a href="Sparse-Matrices-with-Mex_002dFiles.html#Sparse-Matrices-with-Mex_002dFiles">Sparse Matrices with Mex-Files</a>
+<li><a href="Calling-Other-Functions-in-Mex_002dFiles.html#Calling-Other-Functions-in-Mex_002dFiles">Calling Other Functions in Mex-Files</a>
+
+</li></ul>
+<p>Test and Demo Functions
+
+</p>
+<ul class="menu">
+<li><a href="Test-Functions.html#Test-Functions">Test Functions</a>
+<li><a href="Demonstration-Functions.html#Demonstration-Functions">Demonstration Functions</a>
+
+</li></ul>
+<p>Tips and Standards
+
+</p>
+<ul class="menu">
+<li><a href="Style-Tips.html#Style-Tips">Style Tips</a>:                   Writing clean and robust programs. 
+<li><a href="Coding-Tips.html#Coding-Tips">Coding Tips</a>:                  Making code run faster. 
+<li><a href="Comment-Tips.html#Comment-Tips">Comment Tips</a>:                 Conventions for writing comments. 
+<li><a href="Function-Headers.html#Function-Headers">Function Headers</a>:             Standard headers for functions. 
+<li><a href="Documentation-Tips.html#Documentation-Tips">Documentation Tips</a>:           Writing readable documentation strings.
+
+</li></ul>
+<p>Contributing Guidelines
+
+</p>
+<ul class="menu">
+<li><a href="How-to-Contribute.html#How-to-Contribute">How to Contribute</a>
+<li><a href="General-Guidelines.html#General-Guidelines">General Guidelines</a>
+<li><a href="Octave-Sources-_0028m_002dfiles_0029.html#Octave-Sources-_0028m_002dfiles_0029">Octave Sources (m-files)</a>
+<li><a href="C_002b_002b-Sources.html#C_002b_002b-Sources">C++ Sources</a>
+<li><a href="Other-Sources.html#Other-Sources">Other Sources</a>
+
+</li></ul>
+<p>Trouble
+
+</p>
+<ul class="menu">
+<li><a href="Actual-Bugs.html#Actual-Bugs">Actual Bugs</a>:                  Bugs we will fix later. 
+<li><a href="Reporting-Bugs.html#Reporting-Bugs">Reporting Bugs</a>
+<li><a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a>
+<li><a href="Bug-Lists.html#Bug-Lists">Bug Lists</a>
+<li><a href="Bug-Reporting.html#Bug-Reporting">Bug Reporting</a>
+<li><a href="Sending-Patches.html#Sending-Patches">Sending Patches</a>
+<li><a href="Service.html#Service">Service</a>
+
+</li></ul>
+<p>Reporting Bugs
+
+</p>
+<ul class="menu">
+<li><a href="Bug-Criteria.html#Bug-Criteria">Bug Criteria</a>
+<li><a href="Bug-Lists.html#Bug-Lists">Where</a>:              Where to send your bug report. 
+<li><a href="Bug-Reporting.html#Bug-Reporting">Reporting</a>:      How to report a bug effectively. 
+<li><a href="Sending-Patches.html#Sending-Patches">Patches</a>:      How to send a patch for Octave.
+
+</li></ul>
+<p>Installation
+
+</p>
+<ul class="menu">
+<li><a href="Installation-Problems.html#Installation-Problems">Installation Problems</a>
+
+</li></ul>
+<p>Emacs Octave Support
+
+</p>
+<ul class="menu">
+<li><a href="Installing-EOS.html#Installing-EOS">Installing EOS</a>
+<li><a href="Using-Octave-Mode.html#Using-Octave-Mode">Using Octave Mode</a>
+<li><a href="Running-Octave-From-Within-Emacs.html#Running-Octave-From-Within-Emacs">Running Octave From Within Emacs</a>
+<li><a href="Using-the-Emacs-Info-Reader-for-Octave.html#Using-the-Emacs-Info-Reader-for-Octave">Using the Emacs Info Reader for Octave</a>
+</ul>
+
+<!--  -->
+<!-- DO NOT EDIT!  Generated automatically by munge-texi. -->
+<!-- Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, -->
+<!-- 2005, 2006, 2007, 2009 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/interpreter/HTML/inpolygon.png b/doc/interpreter/HTML/inpolygon.png
new file mode 100644
index 0000000..b3e3cd7
Binary files /dev/null and b/doc/interpreter/HTML/inpolygon.png differ
diff --git a/doc/interpreter/HTML/interpderiv1.png b/doc/interpreter/HTML/interpderiv1.png
new file mode 100644
index 0000000..a65b6f3
Binary files /dev/null and b/doc/interpreter/HTML/interpderiv1.png differ
diff --git a/doc/interpreter/HTML/interpderiv2.png b/doc/interpreter/HTML/interpderiv2.png
new file mode 100644
index 0000000..bb7826c
Binary files /dev/null and b/doc/interpreter/HTML/interpderiv2.png differ
diff --git a/doc/interpreter/HTML/interpft.png b/doc/interpreter/HTML/interpft.png
new file mode 100644
index 0000000..23d6304
Binary files /dev/null and b/doc/interpreter/HTML/interpft.png differ
diff --git a/doc/interpreter/HTML/interpn.png b/doc/interpreter/HTML/interpn.png
new file mode 100644
index 0000000..156420b
Binary files /dev/null and b/doc/interpreter/HTML/interpn.png differ
diff --git a/doc/interpreter/HTML/mesh.png b/doc/interpreter/HTML/mesh.png
new file mode 100644
index 0000000..3dd304e
Binary files /dev/null and b/doc/interpreter/HTML/mesh.png differ
diff --git a/doc/interpreter/HTML/plot.png b/doc/interpreter/HTML/plot.png
new file mode 100644
index 0000000..635acdd
Binary files /dev/null and b/doc/interpreter/HTML/plot.png differ
diff --git a/doc/interpreter/HTML/plot3.png b/doc/interpreter/HTML/plot3.png
new file mode 100644
index 0000000..cf09c14
Binary files /dev/null and b/doc/interpreter/HTML/plot3.png differ
diff --git a/doc/interpreter/HTML/polar.png b/doc/interpreter/HTML/polar.png
new file mode 100644
index 0000000..339d5c0
Binary files /dev/null and b/doc/interpreter/HTML/polar.png differ
diff --git a/doc/interpreter/HTML/spchol.png b/doc/interpreter/HTML/spchol.png
new file mode 100644
index 0000000..016b8da
Binary files /dev/null and b/doc/interpreter/HTML/spchol.png differ
diff --git a/doc/interpreter/HTML/spcholperm.png b/doc/interpreter/HTML/spcholperm.png
new file mode 100644
index 0000000..612a86f
Binary files /dev/null and b/doc/interpreter/HTML/spcholperm.png differ
diff --git a/doc/interpreter/HTML/spmatrix.png b/doc/interpreter/HTML/spmatrix.png
new file mode 100644
index 0000000..2b7a325
Binary files /dev/null and b/doc/interpreter/HTML/spmatrix.png differ
diff --git a/doc/interpreter/HTML/tab_003aextended.html b/doc/interpreter/HTML/tab_003aextended.html
new file mode 100644
index 0000000..ae15ce7
--- /dev/null
+++ b/doc/interpreter/HTML/tab_003aextended.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Text-Properties.html#tab%3aextended">
diff --git a/doc/interpreter/HTML/tab_003aoverload_005fops.html b/doc/interpreter/HTML/tab_003aoverload_005fops.html
new file mode 100644
index 0000000..cbba8bb
--- /dev/null
+++ b/doc/interpreter/HTML/tab_003aoverload_005fops.html
@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=Operator-Overloading.html#tab%3aoverload%5fops">
diff --git a/doc/interpreter/HTML/triplot.png b/doc/interpreter/HTML/triplot.png
new file mode 100644
index 0000000..1a2ccf9
Binary files /dev/null and b/doc/interpreter/HTML/triplot.png differ
diff --git a/doc/interpreter/HTML/voronoi.png b/doc/interpreter/HTML/voronoi.png
new file mode 100644
index 0000000..e69de29
diff --git a/doc/interpreter/Makefile.in b/doc/interpreter/Makefile.in
new file mode 100644
index 0000000..f0f3a85
--- /dev/null
+++ b/doc/interpreter/Makefile.in
@@ -0,0 +1,394 @@
+# Makefile for octave's doc/interpreter directory
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+#               2002, 2003, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SCRIPT_SOURCES = sparseimages.m interpimages.m geometryimages.m plotimages.m
+
+POLYNOMIAL_FILES_NODIR = \
+  display.m \
+  double.m \
+  end.m \
+  get.m \
+  mtimes.m \
+  plot.m \
+  polynomial.m \
+  polynomial_superiorto.m \
+  polyval.m \
+  set.m \
+  subsasgn.m \
+  subsref.m
+
+EXAMPLE_FILES_NODIR = \
+  addtwomatrices.cc \
+  celldemo.cc \
+  firstmexdemo.c \
+  fortdemo.cc \
+  fortsub.f \
+  funcdemo.cc \
+  globaldemo.cc \
+  helloworld.cc \
+  mycell.c \
+  myfeval.c \
+  myfunc.c \
+  mypow2.c \
+  mysparse.c \
+  mystring.c \
+  mystruct.c \
+  paramdemo.cc \
+  stringdemo.cc \
+  structdemo.cc \
+  unwinddemo.cc \
+  $(addprefix @polynomial/, $(POLYNOMIAL_FILES_NODIR))
+
+EXAMPLE_FILES = $(addprefix $(top_srcdir)/examples/, $(EXAMPLE_FILES_NODIR))
+
+GEOMETRYIMAGES = voronoi triplot griddata convhull delaunay inpolygon
+GEOMETRYIMAGES_EPS = $(addsuffix .eps, $(GEOMETRYIMAGES))
+GEOMETRYIMAGES_PDF = $(addsuffix .pdf, $(GEOMETRYIMAGES))
+GEOMETRYIMAGES_PNG = $(addsuffix .png, $(GEOMETRYIMAGES))
+GEOMETRYIMAGES_TXT = $(addsuffix .txt, $(GEOMETRYIMAGES))
+
+PLOTIMAGES = plot hist errorbar polar mesh plot3 extended
+PLOTIMAGES_EPS = $(addsuffix .eps, $(PLOTIMAGES))
+PLOTIMAGES_PDF = $(addsuffix .pdf, $(PLOTIMAGES))
+PLOTIMAGES_PNG = $(addsuffix .png, $(PLOTIMAGES))
+PLOTIMAGES_TXT = $(addsuffix .txt, $(PLOTIMAGES))
+
+INTERPIMAGES = interpft interpn interpderiv1 interpderiv2
+INTERPIMAGES_EPS = $(addsuffix .eps, $(INTERPIMAGES))
+INTERPIMAGES_PDF = $(addsuffix .pdf, $(INTERPIMAGES))
+INTERPIMAGES_PNG = $(addsuffix .png, $(INTERPIMAGES))
+INTERPIMAGES_TXT = $(addsuffix .txt, $(INTERPIMAGES))
+
+SPARSEIMAGES_1 = gplot grid spmatrix spchol spcholperm
+SPARSEIMAGES_EPS = $(addsuffix .eps, $(SPARSEIMAGES_1))
+SPARSEIMAGES_PDF = $(addsuffix .pdf, $(SPARSEIMAGES_1))
+SPARSEIMAGES_PNG = $(addsuffix .png, $(SPARSEIMAGES_1))
+SPARSEIMAGES_TXT = $(addsuffix .txt, $(SPARSEIMAGES_1))
+
+IMAGES_EPS = $(SPARSEIMAGES_EPS) $(INTERPIMAGES_EPS) \
+	$(GEOMETRYIMAGES_EPS) $(PLOTIMAGES_EPS)
+IMAGES_PDF = $(SPARSEIMAGES_PDF) $(INTERPIMAGES_PDF) \
+	$(GEOMETRYIMAGES_PDF) $(PLOTIMAGES_PDF)
+IMAGES_PNG = $(SPARSEIMAGES_PNG) $(INTERPIMAGES_PNG) \
+	$(GEOMETRYIMAGES_PNG) $(PLOTIMAGES_PNG)
+IMAGES_TXT = $(SPARSEIMAGES_TXT) $(INTERPIMAGES_TXT) \
+	$(GEOMETRYIMAGES_TXT) $(PLOTIMAGES_TXT)
+
+HTML_IMAGES_PNG = $(addprefix HTML/, $(IMAGES_PNG))
+
+IMAGES = $(IMAGES_EPS) $(IMAGES_PDF) $(IMAGES_PNG) $(IMAGES_TXT)
+
+SUB_SOURCE := arith.txi audio.txi basics.txi bugs.txi \
+	container.txi contrib.txi cp-idx.txi data.txi \
+	debug.txi diffeq.txi diagperm.txi dynamic.txi emacs.txi \
+	errors.txi eval.txi expr.txi fn-idx.txi func.txi geometry.txi \
+	gpl.txi grammar.txi image.txi install.txi interp.txi \
+	intro.txi io.txi linalg.txi matrix.txi nonlin.txi numbers.txi \
+	oop.txi op-idx.txi optim.txi package.txi plot.txi poly.txi preface.txi \
+	quad.txi set.txi signal.txi sparse.txi stats.txi \
+	stmt.txi strings.txi system.txi testfun.txi tips.txi var.txi
+
+SOURCES := $(SUB_SOURCE) $(SCRIPT_SOURCES)
+
+MAIN_TEXINFO := $(srcdir)/octave.texi
+
+SUB_TEXINFO := $(SUB_SOURCE:.txi=.texi)
+
+# Don't list ../conf.texi here.
+TEXINFO_SOURCE := $(MAIN_TEXINFO) $(SUB_TEXINFO) contributors.texi
+
+TEXINFO := $(TEXINFO_SOURCE) ../conf.texi
+
+# Do not use --output option argument, because this is not supported
+# by MiKTeX (compilation under Windows/MSVC assumes the use of MiKTeX
+# to build the doc).  Instead, copy the source .texi using the
+# targeted file name (e.g. to generate octave-a4.pdf, copy to
+# octave-a4.texi) and call texi2[dvi|pdf] on it.
+
+TEXI2DVICOMMAND = TEXINPUTS="..$(sepchar)$(srcdir)$(sepchar)$(srcdir)/..$(sepchar)$(TEXINPUTS)$(sepchar)" \
+	TEXMFCNF="..$(sepchar)$(srcdir)$(sepchar)$(srcdir)/..$(sepchar)$(TEXMFCNF)$(sepchar)" \
+	  $(TEXI2DVI)
+
+TEXI2PDFCOMMAND = TEXINPUTS="..$(sepchar)$(srcdir)$(sepchar)$(srcdir)/..$(sepchar)$(TEXINPUTS)$(sepchar)" \
+	TEXMFCNF="..$(sepchar)$(srcdir)$(sepchar)$(srcdir)/..$(sepchar)$(TEXMFCNF)$(sepchar)" \
+	  $(TEXI2PDF)
+
+FORMATTED = octave.info octave.pdf octave-a4.pdf octave.info-[0-9]*
+
+MAN_BASE := mkoctfile octave octave-bug octave-config
+MAN_SRC := $(addsuffix .1, $(MAN_BASE))
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in contributors.in \
+  mkcontrib.awk dir  munge-texi.cc $(MAN_SRC) $(SOURCES) $(MAIN_TEXINFO)) \
+  $(SUB_TEXINFO) contributors.texi $(FORMATTED) $(IMAGES) mk_doc_cache.m \
+  doc-cache stmp-html
+
+DISTDIRS = HTML
+
+DISTSUBDIRS :=
+
+SUBDIRS :=
+
+# Look for version.h to get version information.
+xfiles := $(TOPDIR)/src/version.h $(srcdir)/$(TOPDIR)/src/version.h
+
+version_file := $(firstword $(foreach file, $(xfiles), $(wildcard $(file))))
+
+SPELL = $(patsubst %.texi, %.spell, $(TEXINFO))
+
+%.spell : %.texi
+	rm -f $@
+	$(SED) -e 's/@@/ at /g' -e 's/@[a-zA-Z]*//g' $< | spell > $@-t
+	mv $@-t $@
+
+all: octave.info octave.pdf octave-a4.pdf HTML/index.html doc-cache
+.PHONY: all
+
+DOCSTRING_FILES := $(TOPDIR)/src/DOCSTRINGS $(TOPDIR)/scripts/DOCSTRINGS
+
+doc-cache: $(DOCSTRING_FILES) mk_doc_cache.m
+	$(TOPDIR)/run-octave -f -q -H $(srcdir)/mk_doc_cache.m doc-cache $(DOCSTRING_FILES) || rm -f doc-cache
+
+$(TEXINFO): $(DOCSTRING_FILES) munge-texi$(BUILD_EXEEXT)
+
+munge-texi$(BUILD_EXEEXT): munge-texi.cc
+	$(BUILD_CXX) $(BUILD_CXXFLAGS) -o $@ $^ $(BUILD_LDFLAGS)
+
+$(DOCSTRING_FILES):
+	$(MAKE) -C $(dir $@) $(notdir $@)
+
+contributors.texi: contributors.in
+	$(AWK) -f $(srcdir)/mkcontrib.awk $(srcdir)/contributors.in > $@-t
+	mv $@-t $@
+
+octave-a4.texi: $(MAIN_TEXINFO)
+	cp $< $@
+
+octave-smallbook.texi: $(MAIN_TEXINFO)
+	cp $< $@
+
+$(SUB_TEXINFO) : %.texi : %.txi
+	./munge-texi $(foreach f, $(DOCSTRING_FILES), -d $(f)) < $< > $@-t
+	mv $@-t $@
+
+octave.info: $(IMAGES_TXT) $(TEXINFO) $(EXAMPLE_FILES)
+	-$(MAKEINFO) -I.. -I$(srcdir) -I$(srcdir)/.. $(MAIN_TEXINFO)
+
+octave.dvi: $(IMAGES_EPS) $(TEXINFO) $(EXAMPLE_FILES)
+	-$(TEXI2DVICOMMAND) $(MAIN_TEXINFO)
+
+octave-a4.dvi: $(IMAGES_EPS) $(TEXINFO) $(EXAMPLE_FILES) octave-a4.texi
+	-$(TEXI2DVICOMMAND) octave-a4.texi -t @afourpaper
+
+octave-smallbook.dvi: $(IMAGES_EPS) $(TEXINFO) $(EXAMPLE_FILES) octave-smallbook.texi
+	-$(TEXI2DVICOMMAND) octave-smallbook.texi -t @smallbook
+
+octave.ps: octave.dvi
+	-dvips -o $@ $<
+
+octave-a4.ps: octave-a4.dvi
+	-dvips -o $@ $<
+
+octave-smallbook.ps: octave-smallbook.dvi
+	-dvips -o $@ $<
+
+octave.pdf: $(IMAGES_PDF) $(TEXINFO) $(EXAMPLE_FILES)
+	-$(TEXI2PDFCOMMAND) $(MAIN_TEXINFO)
+
+octave-a4.pdf: $(IMAGES_PDF) $(TEXINFO) $(EXAMPLE_FILES) octave-a4.texi
+	-$(TEXI2PDFCOMMAND) octave-a4.texi -t @afourpaper
+
+octave-smallbook.pdf: $(IMAGES_PDF) $(TEXINFO) $(EXAMPLE_FILES) octave-smallbook.texi
+	-$(TEXI2PDFCOMMAND) octave-smallbook.texi -t @smallbook
+
+../../INSTALL.OCTAVE: install.texi
+	rm -f INSTALL
+	-$(MAKEINFO) -D INSTALLONLY \
+	  --no-validate --no-headers --no-split --output INSTALL \
+	  -I.. -I$(srcdir) -I$(srcdir)/.. $<
+	mv INSTALL ../../INSTALL.OCTAVE
+
+../../BUGS: bugs.texi
+	rm -f BUGS
+	-$(MAKEINFO) -D BUGSONLY \
+	  --no-validate --no-headers --no-split --output BUGS \
+	  -I.. -I$(srcdir) -I$(srcdir)/.. $<
+	mv BUGS ../../BUGS
+
+HTML/index.html: $(HTML_IMAGES_PNG) $(TEXINFO) $(EXAMPLE_FILES)
+	-$(MAKEINFO) --html --ifinfo --output=HTML -I.. -I$(srcdir) -I$(srcdir)/.. $(MAIN_TEXINFO)
+
+stmp-html: HTML
+	@if [ -f stmp-html ]; then \
+	  true; \
+	else \
+	  echo "touch stmp-html"; \
+	  touch stmp-html; \
+	fi
+
+HTML:
+	@if [ -d HTML ]; then \
+	  true; \
+	else \
+	  echo "mkdir HTML"; \
+	  mkdir HTML; \
+	fi
+
+$(HTML_IMAGES_PNG): HTML/%.png : %.png stmp-html
+	cp $(filter-out html-dir, $<) HTML
+
+define run-octave
+  $(TOPDIR)/run-octave -f -q -H -p $(srcdir) \
+    --eval "$(notdir $(basename $<)) ('$(notdir $(basename $@))', '$(patsubst .%,%, $(suffix $@))');"
+endef
+
+$(GEOMETRYIMAGES_EPS) $(GEOMETRYIMAGES_PNG) $(GEOMETRYIMAGES_TXT): geometryimages.m
+	$(run-octave)
+
+$(PLOTIMAGES_EPS) $(PLOTIMAGES_PNG) $(PLOTIMAGES_TXT): plotimages.m
+	$(run-octave)
+
+$(INTERPIMAGES_EPS) $(INTERPIMAGES_PNG) $(INTERPIMAGES_TXT): interpimages.m
+	$(run-octave)
+
+$(SPARSEIMAGES_EPS) $(SPARSEIMAGES_PNG) $(SPARSEIMAGES_TXT): sparseimages.m
+	$(run-octave)
+
+$(IMAGES_PDF) : %.pdf : %.eps
+	if [ -f $< ] ; then $(GHOSTSCRIPT) -dBATCH -dEPSCrop -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=$@ $< ; fi
+
+check: all
+.PHONY: check
+
+install install-strip: all
+	@$(subdir-for-command)
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(man1dir) $(DESTDIR)$(infodir) $(DESTDIR)$(octetcdir)
+	@if test -d $(DESTDIR)$(man1dir); then \
+	  for f in $(MAN_BASE); do \
+	    rm -f $(DESTDIR)$(man1dir)/$$f$(man1ext); \
+	    echo "installing $(srcdir)/$$f.1 in $(DESTDIR)$(man1dir)"; \
+	    $(INSTALL_DATA) $(srcdir)/$$f.1 $(DESTDIR)$(man1dir)/$$f$(man1ext); \
+	  done ; \
+	fi
+	@if test -d $(DESTDIR)$(infodir); then \
+	  rm -f $(DESTDIR)$(infodir)/octave.info*; \
+	  echo "installing info files in $(DESTDIR)$(infodir)"; \
+	  if test -f octave.info; then \
+	    for f in octave.info*; do \
+	      $(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/$$f; \
+	    done; \
+	  else \
+	    for f in $(srcdir)/octave.info*; do \
+	      $(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/`basename $$f`; \
+	    done; \
+	  fi; \
+	  if test -f $(DESTDIR)$(infodir)/dir; then \
+	    if grep "^\* Octave: (octave)." $(DESTDIR)$(infodir)/dir > /dev/null; then \
+	      true; \
+	    else \
+	      echo ""; \
+	      echo "You should add the following entry"; \
+	      echo ""; \
+	      echo "* Octave: (octave)."; \
+	      echo "	Interactive language for numerical computations."; \
+	      echo ""; \
+	      echo "to $(DESTDIR)$(infodir)/dir."; \
+	      echo ""; \
+	    fi; \
+	  else \
+	    echo "installing $(srcdir)/dir in $(DESTDIR)$(infodir)"; \
+	    $(INSTALL_DATA) $(srcdir)/dir $(DESTDIR)$(infodir)/dir; \
+	  fi; \
+	fi
+	$(INSTALL_DATA) doc-cache $(DESTDIR)$(octetcdir)/doc-cache
+.PHONY: install install-strip
+
+uninstall:
+	@$(subdir-for-command)
+	rm -f $(DESTDIR)$(infodir)/octave.info*
+	rm -f $(DESTDIR)$(infodir)/dir
+	rm -f $(DESTDIR)$(octetcdir)/doc-cache
+	for f in $(MAN_BASE); do rm -f $(DESTDIR)$(man1dir)/$$f$(man1ext); done
+.PHONY: uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+spell: $(SPELL)
+.PHONY: spell
+
+mostlyclean clean:
+	@$(subdir-for-command)
+	rm -f octave.cp octave.fn octave.in \
+	octave.ky octave.op octave.pg octave.rd octave.tp octave.vr \
+	octave.cps octave.fns octave.ins octave.kys octave.ops \
+	octave.pgs octave.rds octave.tps octave.vrs octave.aux \
+	octave.log octave.toc \
+	munge-texi$(BUILD_EXEEXT) munge-texi.o \
+	octave-a4.cp octave-a4.fn octave-a4.in \
+	octave-a4.ky octave-a4.op octave-a4.pg octave-a4.rd octave-a4.tp octave-a4.vr \
+	octave-a4.cps octave-a4.fns octave-a4.ins octave-a4.kys octave-a4.ops \
+	octave-a4.pgs octave-a4.rds octave-a4.tps octave-a4.vrs octave-a4.aux \
+	octave-a4.log octave-a4.toc \
+	octave-smallbook.cp octave-smallbook.fn octave-smallbook.in \
+	octave-smallbook.ky octave-smallbook.op octave-smallbook.pg octave-smallbook.rd octave-smallbook.tp octave-smallbook.vr \
+	octave-smallbook.cps octave-smallbook.fns octave-smallbook.ins octave-smallbook.kys octave-smallbook.ops \
+	octave-smallbook.pgs octave-smallbook.rds octave-smallbook.tps octave-smallbook.vrs octave-smallbook.aux \
+	octave-smallbook.log octave-smallbook.toc
+.PHONY: mostlyclean clean 
+
+distclean: clean
+	@$(subdir-for-command)
+	rm -f tags TAGS Makefile
+.PHONY: distclean
+
+maintainer-clean: distclean clean-texi
+	rm -f doc-cache stmp-html $(FORMATTED) $(IMAGES)
+	rm -rf HTML
+.PHONY: maintainer-clean
+
+clean-texi:
+	rm -f $(SUB_TEXINFO) contributors.texi octave-a4.texi octave-smallbook.texi
+.PHONY: clean-texi
+
+dist: clean-texi all
+	ln $(DISTFILES) ../../`cat ../../.fname`/doc/interpreter
+	for dir in $(DISTDIRS); do \
+	  mkdir ../../`cat ../../.fname`/doc/interpreter/$$dir; \
+	  ln ../../doc/interpreter/$$dir/* ../../`cat ../../.fname`/doc/interpreter/$$dir; \
+	done
+	for dir in $(DISTSUBDIRS); do mkdir ../../`cat ../../.fname`/doc/interpreter/$$dir; $(MAKE) -C $$dir $@; done
+.PHONY: dist
diff --git a/doc/interpreter/arith.texi b/doc/interpreter/arith.texi
new file mode 100644
index 0000000..824ff54
--- /dev/null
+++ b/doc/interpreter/arith.texi
@@ -0,0 +1,2195 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2007, 2008,
+ at c               2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Arithmetic
+ at chapter Arithmetic
+
+Unless otherwise noted, all of the functions described in this chapter
+will work for real and complex scalar, vector, or matrix arguments.  Functions
+described as @dfn{mapping functions} apply the given operation individually to 
+each element when given a matrix argument.  For example,
+
+ at example
+ at group
+sin ([1, 2; 3, 4])
+     @result{}  0.84147   0.90930
+         0.14112  -0.75680
+ at end group
+ at end example
+
+ at menu
+* Exponents and Logarithms::
+* Complex Arithmetic::          
+* Trigonometry::                
+* Sums and Products::           
+* Utility Functions::           
+* Special Functions::           
+* Coordinate Transformations::
+* Mathematical Constants::      
+ at end menu
+
+ at node Exponents and Logarithms
+ at section Exponents and Logarithms
+
+ at c mappers.cc
+ at anchor{doc-exp}
+ at deftypefn {Mapping Function} {} exp (@var{x})
+Compute
+ at tex
+$e^{x}$
+ at end tex
+ at ifnottex
+ at code{e^x}
+ at end ifnottex
+for each element of @var{x}.  To compute the matrix
+exponential, see @ref{Linear Algebra}.
+ at seealso{@ref{doc-log,,log}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-expm1}
+ at deftypefn {Mapping Function} {} expm1 (@var{x})
+Compute
+ at tex
+$ e^{x} - 1 $
+ at end tex
+ at ifnottex
+ at code{exp (@var{x}) - 1}
+ at end ifnottex
+accurately in the neighborhood of zero.
+ at seealso{@ref{doc-exp,,exp}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-log}
+ at deftypefn {Mapping Function} {} log (@var{x})
+Compute the natural logarithm,
+ at tex
+$\ln{(x)},$
+ at end tex
+ at ifnottex
+ at code{ln (@var{x})},
+ at end ifnottex
+for each element of @var{x}.  To compute the
+matrix logarithm, see @ref{Linear Algebra}.
+ at seealso{@ref{doc-exp,,exp}, @ref{doc-log1p,,log1p}, @ref{doc-log2,,log2}, @ref{doc-log10,,log10}, @ref{doc-logspace,,logspace}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-log1p}
+ at deftypefn {Mapping Function} {} log1p (@var{x})
+Compute
+ at tex
+$\ln{(1 + x)}$
+ at end tex
+ at ifnottex
+ at code{log (1 + @var{x})}
+ at end ifnottex
+accurately in the neighborhood of zero.
+ at seealso{@ref{doc-log,,log}, @ref{doc-exp,,exp}, @ref{doc-expm1,,expm1}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-log10}
+ at deftypefn {Mapping Function} {} log10 (@var{x})
+Compute the base-10 logarithm of each element of @var{x}.
+ at seealso{@ref{doc-log,,log}, @ref{doc-log2,,log2}, @ref{doc-logspace,,logspace}, @ref{doc-exp,,exp}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-log2}
+ at deftypefn {Mapping Function} {} log2 (@var{x})
+ at deftypefnx {Mapping Function} {[@var{f}, @var{e}] =} log2 (@var{x})
+Compute the base-2 logarithm of each element of @var{x}.
+
+If called with two output arguments, split @var{x} into
+binary mantissa and exponent so that
+ at tex
+${1 \over 2} \le \left| f \right| < 1$
+ at end tex
+ at ifnottex
+ at code{1/2 <= abs(f) < 1}
+ at end ifnottex
+and @var{e} is an integer.  If
+ at tex
+$x = 0$, $f = e = 0$.
+ at end tex
+ at ifnottex
+ at code{x = 0}, @code{f = e = 0}.
+ at end ifnottex
+ at seealso{@ref{doc-pow2,,pow2}, @ref{doc-log,,log}, @ref{doc-log10,,log10}, @ref{doc-exp,,exp}}
+ at end deftypefn
+
+
+ at c ./general/nextpow2.m
+ at anchor{doc-nextpow2}
+ at deftypefn {Function File} {} nextpow2 (@var{x})
+If @var{x} is a scalar, return the first integer @var{n} such that
+ at tex
+$2^n \ge |x|$.
+ at end tex
+ at ifnottex
+2^n >= abs (x).
+ at end ifnottex
+
+If @var{x} is a vector, return @code{nextpow2 (length (@var{x}))}.
+ at seealso{@ref{doc-pow2,,pow2}, @ref{doc-log2,,log2}}
+ at end deftypefn
+
+
+ at c ./general/nthroot.m
+ at anchor{doc-nthroot}
+ at deftypefn {Function File} {} nthroot (@var{x}, @var{n})
+
+Compute the n-th root of @var{x}, returning real results for real 
+components of @var{x}.  For example
+
+ at example
+ at group
+nthroot (-1, 3)
+ at result{} -1
+(-1) ^ (1 / 3)
+ at result{} 0.50000 - 0.86603i
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+ at c ./specfun/pow2.m
+ at anchor{doc-pow2}
+ at deftypefn {Mapping Function} {} pow2 (@var{x})
+ at deftypefnx {Mapping Function} {} pow2 (@var{f}, @var{e})
+With one argument, computes
+ at tex
+$2^x$
+ at end tex
+ at ifnottex
+2 .^ x
+ at end ifnottex
+for each element of @var{x}.
+
+With two arguments, returns
+ at tex
+$f \cdot 2^e$.
+ at end tex
+ at ifnottex
+f .* (2 .^ e).
+ at end ifnottex
+ at seealso{@ref{doc-log2,,log2}, @ref{doc-nextpow2,,nextpow2}}
+ at end deftypefn
+
+
+ at c ./specfun/reallog.m
+ at anchor{doc-reallog}
+ at deftypefn {Function File} {} reallog (@var{x})
+Return the real-valued natural logarithm of each element of @var{x}.  Report 
+an error if any element results in a complex return value.
+ at seealso{@ref{doc-log,,log}, @ref{doc-realpow,,realpow}, @ref{doc-realsqrt,,realsqrt}}
+ at end deftypefn
+
+
+ at c ./specfun/realpow.m
+ at anchor{doc-realpow}
+ at deftypefn {Function File} {} realpow (@var{x}, @var{y})
+Compute the real-valued, element-by-element power operator.  This is 
+equivalent to @w{@code{@var{x} .^ @var{y}}}, except that @code{realpow}
+reports an error if any return value is complex.
+ at seealso{@ref{doc-reallog,,reallog}, @ref{doc-realsqrt,,realsqrt}}
+ at end deftypefn
+
+
+ at c ./specfun/realsqrt.m
+ at anchor{doc-realsqrt}
+ at deftypefn {Function File} {} realsqrt (@var{x})
+Return the real-valued square root of each element of @var{x}.  Report an
+error if any element results in a complex return value.
+ at seealso{@ref{doc-sqrt,,sqrt}, @ref{doc-realpow,,realpow}, @ref{doc-reallog,,reallog}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-sqrt}
+ at deftypefn {Mapping Function} {} sqrt (@var{x})
+Compute the square root of each element of @var{x}.  If @var{x} is negative,
+a complex result is returned.  To compute the matrix square root, see
+ at ref{Linear Algebra}.
+ at seealso{@ref{doc-realsqrt,,realsqrt}}
+ at end deftypefn
+
+
+ at node Complex Arithmetic
+ at section Complex Arithmetic
+
+In the descriptions of the following functions,
+ at tex
+$z$ is the complex number $x + iy$, where $i$ is defined as
+$\sqrt{-1}$.
+ at end tex
+ at ifinfo
+ at var{z} is the complex number @var{x} + @var{i}@var{y}, where @var{i} is
+defined as @code{sqrt (-1)}.
+ at end ifinfo
+
+ at c mappers.cc
+ at anchor{doc-abs}
+ at deftypefn {Mapping Function} {} abs (@var{z})
+Compute the magnitude of @var{z}, defined as
+ at tex
+$|z| = \sqrt{x^2 + y^2}$.
+ at end tex
+ at ifnottex
+|@var{z}| = @code{sqrt (x^2 + y^2)}.
+ at end ifnottex
+
+For example,
+
+ at example
+ at group
+abs (3 + 4i)
+     @result{} 5
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-arg}
+ at deftypefn {Mapping Function} {} arg (@var{z})
+ at deftypefnx {Mapping Function} {} angle (@var{z})
+Compute the argument of @var{z}, defined as,
+ at tex
+$\theta = atan2 (y, x),$
+ at end tex
+ at ifnottex
+ at var{theta} = @code{atan2 (@var{y}, @var{x})},
+ at end ifnottex
+in radians.
+
+For example,
+
+ at example
+ at group
+arg (3 + 4i)
+     @result{} 0.92730
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-conj}
+ at deftypefn {Mapping Function} {} conj (@var{z})
+Return the complex conjugate of @var{z}, defined as
+ at tex
+$\bar{z} = x - iy$.
+ at end tex
+ at ifnottex
+ at code{conj (@var{z})} = @var{x} - @var{i}@var{y}.
+ at end ifnottex
+ at seealso{@ref{doc-real,,real}, @ref{doc-imag,,imag}}
+ at end deftypefn
+
+
+ at c ./general/cplxpair.m
+ at anchor{doc-cplxpair}
+ at deftypefn  {Function File} {} cplxpair (@var{z})
+ at deftypefnx {Function File} {} cplxpair (@var{z}, @var{tol})
+ at deftypefnx {Function File} {} cplxpair (@var{z}, @var{tol}, @var{dim})
+Sort the numbers @var{z} into complex conjugate pairs ordered by 
+increasing real part.  Place the negative imaginary complex number
+first within each pair.  Place all the real numbers (those with
+ at code{abs (imag (@var{z}) / @var{z}) < @var{tol})}) after the
+complex pairs.
+
+If @var{tol} is unspecified the default value is 100*@code{eps}.
+
+By default the complex pairs are sorted along the first non-singleton
+dimension of @var{z}.  If @var{dim} is specified, then the complex
+pairs are sorted along this dimension.
+
+Signal an error if some complex numbers could not be paired.  Signal an
+error if all complex numbers are not exact conjugates (to within
+ at var{tol}).  Note that there is no defined order for pairs with identical
+real parts but differing imaginary parts.
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+cplxpair (exp(2i*pi*[0:4]'/5)) == exp(2i*pi*[3; 2; 4; 1; 0]/5)
+ at end smallexample
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-imag}
+ at deftypefn {Mapping Function} {} imag (@var{z})
+Return the imaginary part of @var{z} as a real number.
+ at seealso{@ref{doc-real,,real}, @ref{doc-conj,,conj}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-real}
+ at deftypefn {Mapping Function} {} real (@var{z})
+Return the real part of @var{z}.
+ at seealso{@ref{doc-imag,,imag}, @ref{doc-conj,,conj}}
+ at end deftypefn
+
+
+ at node Trigonometry
+ at section Trigonometry
+
+Octave provides the following trigonometric functions where angles are
+specified in radians.  To convert from degrees to radians multiply by
+ at tex
+$\pi/180$
+ at end tex
+ at ifnottex
+ at code{pi/180}
+ at end ifnottex
+(e.g., @code{sin (30 * pi/180)} returns the sine of 30 degrees).  As
+an alternative, Octave provides a number of trigonometric functions
+which work directly on an argument specified in degrees.  These functions
+are named after the base trigonometric function with a @samp{d} suffix.  For
+example, @code{sin} expects an angle in radians while @code{sind} expects an
+angle in degrees.
+
+ at c mappers.cc
+ at anchor{doc-sin}
+ at deftypefn {Mapping Function} {} sin (@var{x})
+Compute the sine for each element of @var{x} in radians.
+ at seealso{@ref{doc-asin,,asin}, @ref{doc-sind,,sind}, @ref{doc-sinh,,sinh}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-cos}
+ at deftypefn {Mapping Function} {} cos (@var{x})
+Compute the cosine for each element of @var{x} in radians.
+ at seealso{@ref{doc-acos,,acos}, @ref{doc-cosd,,cosd}, @ref{doc-cosh,,cosh}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-tan}
+ at deftypefn {Mapping Function} {} tan (@var{z})
+Compute the tangent for each element of @var{x} in radians.
+ at seealso{@ref{doc-atan,,atan}, @ref{doc-tand,,tand}, @ref{doc-tanh,,tanh}}
+ at end deftypefn
+
+ at c ./elfun/sec.m
+ at anchor{doc-sec}
+ at deftypefn {Mapping Function} {} sec (@var{x})
+Compute the secant for each element of @var{x} in radians.
+ at seealso{@ref{doc-asec,,asec}, @ref{doc-secd,,secd}, @ref{doc-sech,,sech}}
+ at end deftypefn
+
+ at c ./elfun/csc.m
+ at anchor{doc-csc}
+ at deftypefn {Mapping Function} {} csc (@var{x})
+Compute the cosecant for each element of @var{x} in radians.
+ at seealso{@ref{doc-acsc,,acsc}, @ref{doc-cscd,,cscd}, @ref{doc-csch,,csch}}
+ at end deftypefn
+
+ at c ./elfun/cot.m
+ at anchor{doc-cot}
+ at deftypefn {Mapping Function} {} cot (@var{x})
+Compute the cotangent for each element of @var{x} in radians.
+ at seealso{@ref{doc-acot,,acot}, @ref{doc-cotd,,cotd}, @ref{doc-coth,,coth}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-asin}
+ at deftypefn {Mapping Function} {} asin (@var{x})
+Compute the inverse sine in radians for each element of @var{x}.
+ at seealso{@ref{doc-sin,,sin}, @ref{doc-asind,,asind}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-acos}
+ at deftypefn {Mapping Function} {} acos (@var{x})
+Compute the inverse cosine in radians for each element of @var{x}.
+ at seealso{@ref{doc-cos,,cos}, @ref{doc-acosd,,acosd}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-atan}
+ at deftypefn {Mapping Function} {} atan (@var{x})
+Compute the inverse tangent in radians for each element of @var{x}.
+ at seealso{@ref{doc-tan,,tan}, @ref{doc-atand,,atand}}
+ at end deftypefn
+
+ at c ./elfun/asec.m
+ at anchor{doc-asec}
+ at deftypefn {Mapping Function} {} asec (@var{x})
+Compute the inverse secant in radians for each element of @var{x}.
+ at seealso{@ref{doc-sec,,sec}, @ref{doc-asecd,,asecd}}
+ at end deftypefn
+
+ at c ./elfun/acsc.m
+ at anchor{doc-acsc}
+ at deftypefn {Mapping Function} {} acsc (@var{x})
+Compute the inverse cosecant in radians for each element of @var{x}.
+ at seealso{@ref{doc-csc,,csc}, @ref{doc-acscd,,acscd}}
+ at end deftypefn
+
+ at c ./elfun/acot.m
+ at anchor{doc-acot}
+ at deftypefn {Mapping Function} {} acot (@var{x})
+Compute the inverse cotangent in radians for each element of @var{x}.
+ at seealso{@ref{doc-cot,,cot}, @ref{doc-acotd,,acotd}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-sinh}
+ at deftypefn {Mapping Function} {} sinh (@var{x})
+Compute the hyperbolic sine for each element of @var{x}.
+ at seealso{@ref{doc-asinh,,asinh}, @ref{doc-cosh,,cosh}, @ref{doc-tanh,,tanh}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-cosh}
+ at deftypefn {Mapping Function} {} cosh (@var{x})
+Compute the hyperbolic cosine for each element of @var{x}.
+ at seealso{@ref{doc-acosh,,acosh}, @ref{doc-sinh,,sinh}, @ref{doc-tanh,,tanh}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-tanh}
+ at deftypefn {Mapping Function} {} tanh (@var{x})
+Compute hyperbolic tangent for each element of @var{x}.
+ at seealso{@ref{doc-atanh,,atanh}, @ref{doc-sinh,,sinh}, @ref{doc-cosh,,cosh}}
+ at end deftypefn
+
+ at c ./elfun/sech.m
+ at anchor{doc-sech}
+ at deftypefn {Mapping Function} {} sech (@var{x})
+Compute the hyperbolic secant of each element of @var{x}.
+ at seealso{@ref{doc-asech,,asech}}
+ at end deftypefn
+
+ at c ./elfun/csch.m
+ at anchor{doc-csch}
+ at deftypefn {Mapping Function} {} csch (@var{x})
+Compute the hyperbolic cosecant of each element of @var{x}.
+ at seealso{@ref{doc-acsch,,acsch}}
+ at end deftypefn
+
+ at c ./elfun/coth.m
+ at anchor{doc-coth}
+ at deftypefn {Mapping Function} {} coth (@var{x})
+Compute the hyperbolic cotangent of each element of @var{x}.
+ at seealso{@ref{doc-acoth,,acoth}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-asinh}
+ at deftypefn {Mapping Function} {} asinh (@var{x})
+Compute the inverse hyperbolic sine for each element of @var{x}.
+ at seealso{@ref{doc-sinh,,sinh}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-acosh}
+ at deftypefn {Mapping Function} {} acosh (@var{x})
+Compute the inverse hyperbolic cosine for each element of @var{x}.
+ at seealso{@ref{doc-cosh,,cosh}}
+ at end deftypefn
+
+ at c mappers.cc
+ at anchor{doc-atanh}
+ at deftypefn {Mapping Function} {} atanh (@var{x})
+Compute the inverse hyperbolic tangent for each element of @var{x}.
+ at seealso{@ref{doc-tanh,,tanh}}
+ at end deftypefn
+
+ at c ./elfun/asech.m
+ at anchor{doc-asech}
+ at deftypefn {Mapping Function} {} asech (@var{x})
+Compute the inverse hyperbolic secant of each element of @var{x}.
+ at seealso{@ref{doc-sech,,sech}}
+ at end deftypefn
+
+ at c ./elfun/acsch.m
+ at anchor{doc-acsch}
+ at deftypefn {Mapping Function} {} acsch (@var{x})
+Compute the inverse hyperbolic cosecant of each element of @var{x}.
+ at seealso{@ref{doc-csch,,csch}}
+ at end deftypefn
+
+ at c ./elfun/acoth.m
+ at anchor{doc-acoth}
+ at deftypefn {Mapping Function} {} acoth (@var{x})
+Compute the inverse hyperbolic cotangent of each element of @var{x}.
+ at seealso{@ref{doc-coth,,coth}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-atan2}
+ at deftypefn {Mapping Function} {} atan2 (@var{y}, @var{x})
+Compute atan (@var{y} / @var{x}) for corresponding elements of @var{y}
+and @var{x}.  Signal an error if @var{y} and @var{x} do not match in size
+and orientation.
+ at end deftypefn
+
+
+Octave provides the following trigonometric functions where angles are
+specified in degrees.  These functions produce true zeros at the appropriate
+intervals rather than the small roundoff error that occurs when using
+radians.  For example:
+ at example
+ at group
+cosd (90)
+     @result{} 0
+cos (pi/2)
+     @result{} 6.1230e-17
+ at end group
+ at end example
+
+ at c ./elfun/sind.m
+ at anchor{doc-sind}
+ at deftypefn {Function File} {} sind (@var{x})
+Compute the sine for each element of @var{x} in degrees.  Returns zero 
+for elements where @code{@var{x}/180} is an integer.
+ at seealso{@ref{doc-asind,,asind}, @ref{doc-sin,,sin}}
+ at end deftypefn
+
+ at c ./elfun/cosd.m
+ at anchor{doc-cosd}
+ at deftypefn {Function File} {} cosd (@var{x})
+Compute the cosine for each element of @var{x} in degrees.  Returns zero 
+for elements where @code{(@var{x}-90)/180} is an integer.
+ at seealso{@ref{doc-acosd,,acosd}, @ref{doc-cos,,cos}}
+ at end deftypefn
+
+ at c ./elfun/tand.m
+ at anchor{doc-tand}
+ at deftypefn {Function File} {} tand (@var{x})
+Compute the tangent for each element of @var{x} in degrees.  Returns zero 
+for elements where @code{@var{x}/180} is an integer and @code{Inf} for
+elements where @code{(@var{x}-90)/180} is an integer.
+ at seealso{@ref{doc-atand,,atand}, @ref{doc-tan,,tan}}
+ at end deftypefn
+
+ at c ./elfun/secd.m
+ at anchor{doc-secd}
+ at deftypefn {Function File} {} secd (@var{x})
+Compute the secant for each element of @var{x} in degrees.
+ at seealso{@ref{doc-asecd,,asecd}, @ref{doc-sec,,sec}}
+ at end deftypefn
+
+ at c ./elfun/cscd.m
+ at anchor{doc-cscd}
+ at deftypefn {Function File} {} cscd (@var{x})
+Compute the cosecant for each element of @var{x} in degrees.
+ at seealso{@ref{doc-acscd,,acscd}, @ref{doc-csc,,csc}}
+ at end deftypefn
+
+ at c ./elfun/cotd.m
+ at anchor{doc-cotd}
+ at deftypefn {Function File} {} cotd (@var{x})
+Compute the cotangent for each element of @var{x} in degrees.
+ at seealso{@ref{doc-acotd,,acotd}, @ref{doc-cot,,cot}}
+ at end deftypefn
+
+
+ at c ./elfun/asind.m
+ at anchor{doc-asind}
+ at deftypefn {Function File} {} asind (@var{x})
+Compute the inverse sine in degrees for each element of @var{x}.
+ at seealso{@ref{doc-sind,,sind}, @ref{doc-asin,,asin}}
+ at end deftypefn
+
+ at c ./elfun/acosd.m
+ at anchor{doc-acosd}
+ at deftypefn {Function File} {} acosd (@var{x})
+Compute the inverse cosine in degrees for each element of @var{x}.
+ at seealso{@ref{doc-cosd,,cosd}, @ref{doc-acos,,acos}}
+ at end deftypefn
+
+ at c ./elfun/atand.m
+ at anchor{doc-atand}
+ at deftypefn {Function File} {} atand (@var{x})
+Compute the inverse tangent in degrees for each element of @var{x}.
+ at seealso{@ref{doc-tand,,tand}, @ref{doc-atan,,atan}}
+ at end deftypefn
+
+ at c ./elfun/asecd.m
+ at anchor{doc-asecd}
+ at deftypefn {Function File} {} asecd (@var{x})
+Compute the inverse secant in degrees for each element of @var{x}.
+ at seealso{@ref{doc-secd,,secd}, @ref{doc-asec,,asec}}
+ at end deftypefn
+
+ at c ./elfun/acscd.m
+ at anchor{doc-acscd}
+ at deftypefn {Function File} {} acscd (@var{x})
+Compute the inverse cosecant in degrees for each element of @var{x}.
+ at seealso{@ref{doc-cscd,,cscd}, @ref{doc-acsc,,acsc}}
+ at end deftypefn
+
+ at c ./elfun/acotd.m
+ at anchor{doc-acotd}
+ at deftypefn {Function File} {} acotd (@var{x})
+Compute the inverse cotangent in degrees for each element of @var{x}.
+ at seealso{@ref{doc-cotd,,cotd}, @ref{doc-acot,,acot}}
+ at end deftypefn
+
+
+ at node Sums and Products
+ at section Sums and Products
+
+ at c data.cc
+ at anchor{doc-sum}
+ at deftypefn  {Built-in Function} {} sum (@var{x})
+ at deftypefnx {Built-in Function} {} sum (@var{x}, @var{dim})
+ at deftypefnx {Built-in Function} {} sum (@dots{}, 'native')
+Sum of elements along dimension @var{dim}.  If @var{dim} is
+omitted, it defaults to 1 (column-wise sum).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the sum of the elements.
+
+If the optional argument 'native' is given, then the sum is performed
+in the same type as the original argument, rather than in the default
+double type.  For example
+
+ at example
+ at group
+sum ([true, true])
+  @result{} 2
+sum ([true, true], 'native')
+  @result{} true
+ at end group
+ at end example
+ at seealso{@ref{doc-cumsum,,cumsum}, @ref{doc-sumsq,,sumsq}, @ref{doc-prod,,prod}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-prod}
+ at deftypefn  {Built-in Function} {} prod (@var{x})
+ at deftypefnx {Built-in Function} {} prod (@var{x}, @var{dim})
+Product of elements along dimension @var{dim}.  If @var{dim} is
+omitted, it defaults to 1 (column-wise products).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the product of the elements.
+ at seealso{@ref{doc-cumprod,,cumprod}, @ref{doc-sum,,sum}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-cumsum}
+ at deftypefn  {Built-in Function} {} cumsum (@var{x})
+ at deftypefnx {Built-in Function} {} cumsum (@var{x}, @var{dim})
+ at deftypefnx {Built-in Function} {} cumsum (@dots{}, 'native')
+Cumulative sum of elements along dimension @var{dim}.  If @var{dim}
+is omitted, it defaults to 1 (column-wise cumulative sums).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the cumulative sum of the elements as a vector with the
+same orientation as @var{x}.
+
+The "native" argument implies the summation is performed in native type.
+ See @code{sum} for a complete description and example of the use of
+"native".
+ at seealso{@ref{doc-sum,,sum}, @ref{doc-cumprod,,cumprod}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-cumprod}
+ at deftypefn  {Built-in Function} {} cumprod (@var{x})
+ at deftypefnx {Built-in Function} {} cumprod (@var{x}, @var{dim})
+Cumulative product of elements along dimension @var{dim}.  If
+ at var{dim} is omitted, it defaults to 1 (column-wise cumulative
+products).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the cumulative product of the elements as a vector with the
+same orientation as @var{x}.
+ at seealso{@ref{doc-prod,,prod}, @ref{doc-cumsum,,cumsum}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-sumsq}
+ at deftypefn  {Built-in Function} {} sumsq (@var{x})
+ at deftypefnx {Built-in Function} {} sumsq (@var{x}, @var{dim})
+Sum of squares of elements along dimension @var{dim}.  If @var{dim}
+is omitted, it defaults to 1 (column-wise sum of squares).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the sum of squares of the elements.
+
+This function is conceptually equivalent to computing
+ at example
+sum (x .* conj (x), dim)
+ at end example
+but it uses less memory and avoids calling @code{conj} if @var{x} is real.
+ at seealso{@ref{doc-sum,,sum}}
+ at end deftypefn
+
+
+ at c ./general/accumarray.m
+ at anchor{doc-accumarray}
+ at deftypefn {Function File} {} accumarray (@var{subs}, @var{vals}, @var{sz}, @var{func}, @var{fillval}, @var{issparse})
+ at deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, @dots{})
+
+Create an array by accumulating the elements of a vector into the
+positions defined by their subscripts.  The subscripts are defined by
+the rows of the matrix @var{subs} and the values by @var{vals}.  Each row
+of @var{subs} corresponds to one of the values in @var{vals}.
+
+The size of the matrix will be determined by the subscripts themselves.
+However, if @var{sz} is defined it determines the matrix size.  The length
+of @var{sz} must correspond to the number of columns in @var{subs}.
+
+The default action of @code{accumarray} is to sum the elements with the
+same subscripts.  This behavior can be modified by defining the @var{func}
+function.  This should be a function or function handle that accepts a 
+column vector and returns a scalar.  The result of the function should not
+depend on the order of the subscripts.
+
+The elements of the returned array that have no subscripts associated with
+them are set to zero.  Defining @var{fillval} to some other value allows
+these values to be defined.
+
+By default @code{accumarray} returns a full matrix.  If @var{issparse} is
+logically true, then a sparse matrix is returned instead.
+
+An example of the use of @code{accumarray} is:
+
+ at example
+ at group
+accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+ at result{} ans(:,:,1) = [101, 0, 0; 0, 0, 0]
+   ans(:,:,2) = [0, 0, 0; 206, 0, 208]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at node Utility Functions
+ at section Utility Functions
+
+ at c mappers.cc
+ at anchor{doc-ceil}
+ at deftypefn {Mapping Function} {} ceil (@var{x})
+Return the smallest integer not less than @var{x}.  This is equivalent to
+rounding towards positive infinity.  If @var{x} is
+complex, return @code{ceil (real (@var{x})) + ceil (imag (@var{x})) * I}.
+ at example
+ at group
+ceil ([-2.7, 2.7])
+   @result{}  -2   3
+ at end group
+ at end example
+ at seealso{@ref{doc-floor,,floor}, @ref{doc-round,,round}, @ref{doc-fix,,fix}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/cross.m
+ at anchor{doc-cross}
+ at deftypefn  {Function File} {} cross (@var{x}, @var{y})
+ at deftypefnx {Function File} {} cross (@var{x}, @var{y}, @var{dim})
+Compute the vector cross product of two 3-dimensional vectors
+ at var{x} and @var{y}.
+
+ at example
+ at group
+cross ([1,1,0], [0,1,1])
+     @result{} [ 1; -1; 1 ]
+ at end group
+ at end example
+
+If @var{x} and @var{y} are matrices, the cross product is applied 
+along the first dimension with 3 elements.  The optional argument 
+ at var{dim} forces the cross product to be calculated along
+the specified dimension.
+ at seealso{@ref{doc-dot,,dot}}
+ at end deftypefn
+
+
+ at c ./general/del2.m
+ at anchor{doc-del2}
+ at deftypefn  {Function File} {@var{d} =} del2 (@var{m})
+ at deftypefnx {Function File} {@var{d} =} del2 (@var{m}, @var{h})
+ at deftypefnx {Function File} {@var{d} =} del2 (@var{m}, @var{dx}, @var{dy}, @dots{})
+
+Calculate the discrete Laplace
+ at tex
+operator $( \nabla^2 )$.
+ at end tex
+ at ifnottex
+operator.
+ at end ifnottex
+For a 2-dimensional matrix @var{m} this is defined as
+
+ at tex
+$$d = {1 \over 4} \left( {d^2 \over dx^2} M(x,y) + {d^2 \over dy^2} M(x,y) \right)$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+      1    / d^2            d^2         \
+D  = --- * | ---  M(x,y) +  ---  M(x,y) | 
+      4    \ dx^2           dy^2        /
+ at end group
+ at end example
+ at end ifnottex
+
+For N-dimensional arrays the sum in parentheses is expanded to include second derivatives 
+over the additional higher dimensions.
+
+The spacing between evaluation points may be defined by @var{h}, which is a
+scalar defining the equidistant spacing in all dimensions.  Alternatively, 
+the spacing in each dimension may be defined separately by @var{dx}, @var{dy},
+etc.  A scalar spacing argument defines equidistant spacing, whereas a vector
+argument can be used to specify variable spacing.  The length of the spacing vectors
+must match the respective dimension of @var{m}.  The default spacing value
+is 1.
+
+At least 3 data points are needed for each dimension.  Boundary points are
+calculated from the linear extrapolation of interior points.
+
+ at seealso{@ref{doc-gradient,,gradient}, @ref{doc-diff,,diff}}
+ at end deftypefn
+
+
+ at c ./specfun/factor.m
+ at anchor{doc-factor}
+ at deftypefn  {Function File} {@var{p} =} factor (@var{q})
+ at deftypefnx {Function File} {[@var{p}, @var{n}] =} factor (@var{q})
+
+Return prime factorization of @var{q}.  That is, @code{prod (@var{p})
+== @var{q}} and every element of @var{p} is a prime number.  If
+ at code{@var{q} == 1}, returns 1. 
+
+With two output arguments, return the unique primes @var{p} and
+their multiplicities.  That is, @code{prod (@var{p} .^ @var{n}) ==
+ at var{q}}.
+ at seealso{@ref{doc-gcd,,gcd}, @ref{doc-lcm,,lcm}}
+ at end deftypefn
+
+
+ at c ./specfun/factorial.m
+ at anchor{doc-factorial}
+ at deftypefn {Function File} {} factorial (@var{n})
+Return the factorial of @var{n} where @var{n} is a positive integer.  If
+ at var{n} is a scalar, this is equivalent to @code{prod (1:@var{n})}.  For
+vector or matrix arguments, return the factorial of each element in the
+array.  For non-integers see the generalized factorial function
+ at code{gamma}.
+ at seealso{@ref{doc-prod,,prod}, @ref{doc-gamma,,gamma}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-fix}
+ at deftypefn {Mapping Function} {} fix (@var{x})
+Truncate fractional portion of @var{x} and return the integer portion.  This
+is equivalent to rounding towards zero.  If @var{x} is complex, return
+ at code{fix (real (@var{x})) + fix (imag (@var{x})) * I}.
+ at example
+ at group
+fix ([-2.7, 2.7])
+   @result{} -2   2
+ at end group
+ at end example
+ at seealso{@ref{doc-ceil,,ceil}, @ref{doc-floor,,floor}, @ref{doc-round,,round}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-floor}
+ at deftypefn {Mapping Function} {} floor (@var{x})
+Return the largest integer not greater than @var{x}.  This is equivalent to
+rounding towards negative infinity.  If @var{x} is
+complex, return @code{floor (real (@var{x})) + floor (imag (@var{x})) * I}.
+ at example
+ at group
+floor ([-2.7, 2.7])
+     @result{} -3   2
+ at end group
+ at end example
+ at seealso{@ref{doc-ceil,,ceil}, @ref{doc-round,,round}, @ref{doc-fix,,fix}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-fmod}
+ at deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})
+Compute the floating point remainder of dividing @var{x} by @var{y}
+using the C library function @code{fmod}.  The result has the same
+sign as @var{x}.  If @var{y} is zero, the result is implementation-dependent.
+ at seealso{@ref{doc-mod,,mod}, @ref{doc-rem,,rem}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/gcd.cc
+ at anchor{doc-gcd}
+ at deftypefn  {Loadable Function} {@var{g} =} gcd (@var{a})
+ at deftypefnx {Loadable Function} {@var{g} =} gcd (@var{a1}, @var{a2}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{g}, @var{v1}, @dots{}] =} gcd (@var{a1}, @var{a2}, @dots{})
+
+Compute the greatest common divisor of the elements of @var{a}.  If more
+than one argument is given all arguments must be the same size or scalar.
+  In this case the greatest common divisor is calculated for each element
+individually.  All elements must be integers.  For example,
+
+ at example
+ at group
+gcd ([15, 20])
+    @result{}  5
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+gcd ([15, 9], [20, 18])
+    @result{}  5  9
+ at end group
+ at end example
+
+Optional return arguments @var{v1}, etc., contain integer vectors such
+that,
+
+ at tex
+$g = v_1 a_1 + v_2 a_2 + \cdots$
+ at end tex
+ at ifnottex
+ at example
+ at var{g} = @var{v1} .* @var{a1} + @var{v2} .* @var{a2} + @dots{}
+ at end example
+ at end ifnottex
+
+For backward compatibility with previous versions of this function, when
+all arguments are scalar, a single return argument @var{v1} containing
+all of the values of @var{v1}, @dots{} is acceptable.
+ at seealso{@ref{doc-lcm,,lcm}, @ref{doc-factor,,factor}}
+ at end deftypefn
+
+
+ at c ./general/gradient.m
+ at anchor{doc-gradient}
+ at deftypefn {Function File} {@var{dx} =} gradient (@var{m})
+ at deftypefnx {Function File} {[@var{dx}, @var{dy}, @var{dz}, @dots{}] =} gradient (@var{m})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{m}, @var{s})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{m}, @var{x}, @var{y}, @var{z}, @dots{})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0}, @var{s})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0}, @var{x}, @var{y}, @dots{})
+
+Calculate the gradient of sampled data or a function.  If @var{m}
+is a vector, calculate the one-dimensional gradient of @var{m}.  If
+ at var{m} is a matrix the gradient is calculated for each dimension.
+
+ at code{[@var{dx}, @var{dy}] = gradient (@var{m})} calculates the one
+dimensional gradient for @var{x} and @var{y} direction if @var{m} is a
+matrix.  Additional return arguments can be use for multi-dimensional
+matrices.
+
+A constant spacing between two points can be provided by the
+ at var{s} parameter.  If @var{s} is a scalar, it is assumed to be the spacing
+for all dimensions. 
+Otherwise, separate values of the spacing can be supplied by
+the @var{x}, @dots{} arguments.  Scalar values specify an equidistant spacing.
+Vector values for the @var{x}, @dots{} arguments specify the coordinate for that
+dimension.  The length must match their respective dimension of @var{m}.
+
+At boundary points a linear extrapolation is applied.  Interior points
+are calculated with the first approximation of the numerical gradient
+
+ at example
+y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).
+ at end example
+
+If the first argument @var{f} is a function handle, the gradient of the
+function at the points in @var{x0} is approximated using central
+difference.  For example, @code{gradient (@@cos, 0)} approximates the
+gradient of the cosine function in the point @math{x0 = 0}.  As with
+sampled data, the spacing values between the points from which the
+gradient is estimated can be set via the @var{s} or @var{dx},
+ at var{dy}, @dots{} arguments.  By default a spacing of 1 is used.
+ at seealso{@ref{doc-diff,,diff}, @ref{doc-del2,,del2}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-hypot}
+ at deftypefn {Built-in Function} {} hypot (@var{x}, @var{y})
+Compute the element-by-element square root of the sum of the squares of
+ at var{x} and @var{y}.  This is equivalent to
+ at code{sqrt (@var{x}.^2 + @var{y}.^2)}, but calculated in a manner that
+avoids overflows for large values of @var{x} or @var{y}.
+ at end deftypefn
+
+
+ at c ./elfun/lcm.m
+ at anchor{doc-lcm}
+ at deftypefn  {Mapping Function} {} lcm (@var{x})
+ at deftypefnx {Mapping Function} {} lcm (@var{x}, @dots{})
+Compute the least common multiple of the elements of @var{x}, or
+of the list of all arguments.  For example,
+
+ at example
+lcm (a1, @dots{}, ak)
+ at end example
+
+ at noindent
+is the same as
+
+ at example
+lcm ([a1, @dots{}, ak]).
+ at end example
+
+All elements must be the same size or scalar.
+ at seealso{@ref{doc-factor,,factor}, @ref{doc-gcd,,gcd}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/list_primes.m
+ at anchor{doc-list_primes}
+ at deftypefn {Function File} {} list_primes (@var{n})
+List the first @var{n} primes.  If @var{n} is unspecified, the first
+25 primes are listed.
+
+The algorithm used is from page 218 of the @TeX{}book.
+ at seealso{@ref{doc-primes,,primes}, @ref{doc-isprime,,isprime}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/max.cc
+ at anchor{doc-max}
+ at deftypefn  {Loadable Function} {} max (@var{x})
+ at deftypefnx {Loadable Function} {} max (@var{x}, @var{y})
+ at deftypefnx {Loadable Function} {} max (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} max (@var{x})
+For a vector argument, return the maximum value.  For a matrix
+argument, return the maximum value from each column, as a row
+vector, or over the dimension @var{dim} if defined.  For two matrices
+(or a matrix and scalar), return the pair-wise maximum.
+Thus,
+
+ at example
+max (max (@var{x}))
+ at end example
+
+ at noindent
+returns the largest element of the matrix @var{x}, and
+
+ at example
+ at group
+max (2:5, pi)
+    @result{}  3.1416  3.1416  4.0000  5.0000
+ at end group
+ at end example
+ at noindent
+compares each element of the range @code{2:5} with @code{pi}, and
+returns a row vector of the maximum values.
+
+For complex arguments, the magnitude of the elements are used for
+comparison.
+
+If called with one input and two output arguments,
+ at code{max} also returns the first index of the
+maximum value(s).  Thus,
+
+ at example
+ at group
+[x, ix] = max ([1, 3, 5, 2, 5])
+    @result{}  x = 5
+        ix = 3
+ at end group
+ at end example
+ at seealso{@ref{doc-min,,min}, @ref{doc-cummax,,cummax}, @ref{doc-cummin,,cummin}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/max.cc
+ at anchor{doc-min}
+ at deftypefn  {Loadable Function} {} min (@var{x})
+ at deftypefnx {Loadable Function} {} min (@var{x}, @var{y})
+ at deftypefnx {Loadable Function} {} min (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} min (@var{x})
+For a vector argument, return the minimum value.  For a matrix
+argument, return the minimum value from each column, as a row
+vector, or over the dimension @var{dim} if defined.  For two matrices
+(or a matrix and scalar), return the pair-wise minimum.
+Thus,
+
+ at example
+min (min (@var{x}))
+ at end example
+
+ at noindent
+returns the smallest element of @var{x}, and
+
+ at example
+ at group
+min (2:5, pi)
+    @result{}  2.0000  3.0000  3.1416  3.1416
+ at end group
+ at end example
+ at noindent
+compares each element of the range @code{2:5} with @code{pi}, and
+returns a row vector of the minimum values.
+
+For complex arguments, the magnitude of the elements are used for
+comparison.
+
+If called with one input and two output arguments,
+ at code{min} also returns the first index of the
+minimum value(s).  Thus,
+
+ at example
+ at group
+[x, ix] = min ([1, 3, 0, 2, 0])
+    @result{}  x = 0
+        ix = 3
+ at end group
+ at end example
+ at seealso{@ref{doc-max,,max}, @ref{doc-cummin,,cummin}, @ref{doc-cummax,,cummax}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/max.cc
+ at anchor{doc-cummax}
+ at deftypefn  {Loadable Function} {} cummax (@var{x})
+ at deftypefnx {Loadable Function} {} cummax (@var{x}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} cummax (@var{x})
+Return the cumulative maximum values along dimension @var{dim}.  If @var{dim}
+is unspecified it defaults to column-wise operation.  For example,
+
+ at example
+ at group
+cummax ([1 3 2 6 4 5])
+    @result{}  1  3  3  6  6  6
+ at end group
+ at end example
+
+The call
+ at example
+[w, iw] = cummax (x, dim)
+ at end example
+
+ at noindent
+is equivalent to the following code:
+ at example
+ at group
+w = iw = zeros (size (x));
+idxw = idxx = repmat (@{':'@}, 1, ndims (x));
+for i = 1:size (x, dim)
+  idxw@{dim@} = i; idxx@{dim@} = 1:i;
+  [w(idxw@{:@}), iw(idxw@{:@})] = max(x(idxx@{:@}), [], dim);
+endfor
+ at end group
+ at end example
+
+ at noindent
+but computed in a much faster manner.
+ at seealso{@ref{doc-cummin,,cummin}, @ref{doc-max,,max}, @ref{doc-min,,min}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/max.cc
+ at anchor{doc-cummin}
+ at deftypefn  {Loadable Function} {} cummin (@var{x})
+ at deftypefnx {Loadable Function} {} cummin (@var{x}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} cummin (@var{x})
+Return the cumulative minimum values along dimension @var{dim}.  If @var{dim}
+is unspecified it defaults to column-wise operation.  For example,
+
+ at example
+ at group
+cummin ([5 4 6 2 3 1])
+    @result{}  5  4  4  2  2  1
+ at end group
+ at end example
+
+
+The call
+ at example
+  [w, iw] = cummin (x, dim)
+ at end example
+
+ at noindent
+is equivalent to the following code:
+ at example
+ at group
+w = iw = zeros (size (x));
+idxw = idxx = repmat (@{':'@}, 1, ndims (x));
+for i = 1:size (x, dim)
+  idxw@{dim@} = i; idxx@{dim@} = 1:i;
+  [w(idxw@{:@}), iw(idxw@{:@})] = min(x(idxx@{:@}), [], dim);
+endfor
+ at end group
+ at end example
+
+ at noindent
+but computed in a much faster manner.
+ at seealso{@ref{doc-cummax,,cummax}, @ref{doc-min,,min}, @ref{doc-max,,max}}
+ at end deftypefn
+
+
+ at c ./general/mod.m
+ at anchor{doc-mod}
+ at deftypefn {Mapping Function} {} mod (@var{x}, @var{y})
+Compute the modulo of @var{x} and @var{y}.  Conceptually this is given by
+
+ at example
+x - y .* floor (x ./ y)
+ at end example
+
+and is written such that the correct modulus is returned for
+integer types.  This function handles negative values correctly.  That
+is, @code{mod (-1, 3)} is 2, not -1, as @code{rem (-1, 3)} returns.
+ at code{mod (@var{x}, 0)} returns @var{x}.
+
+An error results if the dimensions of the arguments do not agree, or if
+either of the arguments is complex.
+ at seealso{@ref{doc-rem,,rem}, @ref{doc-fmod,,fmod}}
+ at end deftypefn
+
+
+ at c ./specfun/primes.m
+ at anchor{doc-primes}
+ at deftypefn {Function File} {} primes (@var{n})
+
+Return all primes up to @var{n}.  
+
+The algorithm used is the Sieve of Erastothenes.
+
+Note that if you need a specific number of primes you can use the
+fact the distance from one prime to the next is, on average,
+proportional to the logarithm of the prime.  Integrating, one finds
+that there are about @math{k} primes less than
+ at tex
+$k \log (5 k)$.
+ at end tex
+ at ifnottex
+k*log(5*k).
+ at end ifnottex
+ at seealso{@ref{doc-list_primes,,list_primes}, @ref{doc-isprime,,isprime}}
+ at end deftypefn
+
+
+ at c ./general/rem.m
+ at anchor{doc-rem}
+ at deftypefn {Mapping Function} {} rem (@var{x}, @var{y})
+Return the remainder of the division @code{@var{x} / @var{y}}, computed 
+using the expression
+
+ at example
+x - y .* fix (x ./ y)
+ at end example
+
+An error message is printed if the dimensions of the arguments do not
+agree, or if either of the arguments is complex.
+ at seealso{@ref{doc-mod,,mod}, @ref{doc-fmod,,fmod}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-round}
+ at deftypefn {Mapping Function} {} round (@var{x})
+Return the integer nearest to @var{x}.  If @var{x} is complex, return
+ at code{round (real (@var{x})) + round (imag (@var{x})) * I}.
+ at example
+ at group
+round ([-2.7, 2.7])
+     @result{} -3   3
+ at end group
+ at end example
+ at seealso{@ref{doc-ceil,,ceil}, @ref{doc-floor,,floor}, @ref{doc-fix,,fix}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-roundb}
+ at deftypefn {Mapping Function} {} roundb (@var{x})
+Return the integer nearest to @var{x}.  If there are two nearest
+integers, return the even one (banker's rounding).  If @var{x} is complex,
+return @code{roundb (real (@var{x})) + roundb (imag (@var{x})) * I}.
+ at seealso{@ref{doc-round,,round}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-sign}
+ at deftypefn {Mapping Function} {} sign (@var{x})
+Compute the @dfn{signum} function, which is defined as
+ at tex
+$$
+{\rm sign} (@var{x}) = \cases{1,&$x>0$;\cr 0,&$x=0$;\cr -1,&$x<0$.\cr}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+           -1, x < 0;
+sign (x) =  0, x = 0;
+            1, x > 0.
+ at end group
+ at end example
+ at end ifnottex
+
+For complex arguments, @code{sign} returns @code{x ./ abs (@var{x})}.
+ at end deftypefn
+
+
+ at node Special Functions
+ at section Special Functions
+
+ at c ./DLD-FUNCTIONS/besselj.cc
+ at anchor{doc-airy}
+ at deftypefn {Loadable Function} {[@var{a}, @var{ierr}] =} airy (@var{k}, @var{z}, @var{opt})
+Compute Airy functions of the first and second kind, and their
+derivatives.
+
+ at example
+ at group
+ K   Function   Scale factor (if 'opt' is supplied)
+---  --------   ---------------------------------------
+ 0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))
+ 1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))
+ 2   Bi (Z)     exp (-abs (real ((2/3) * Z *sqrt (Z))))
+ 3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z *sqrt (Z))))
+ at end group
+ at end example
+
+The function call @code{airy (@var{z})} is equivalent to
+ at code{airy (0, @var{z})}.
+
+The result is the same size as @var{z}.
+
+If requested, @var{ierr} contains the following status information and
+is the same size as the result.
+
+ at enumerate 0
+ at item
+Normal return.
+ at item
+Input error, return @code{NaN}.
+ at item
+Overflow, return @code{Inf}.
+ at item
+Loss of significance by argument reduction results in less than half
+ of machine accuracy.
+ at item
+Complete loss of significance by argument reduction, return @code{NaN}.
+ at item
+Error---no computation, algorithm termination condition not met,
+return @code{NaN}.
+ at end enumerate
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/besselj.cc
+ at anchor{doc-besselj}
+ at deftypefn {Loadable Function} {[@var{j}, @var{ierr}] =} besselj (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})
+Compute Bessel or Hankel functions of various kinds:
+
+ at table @code
+ at item besselj
+Bessel functions of the first kind.  If the argument @var{opt} is supplied, 
+the result is multiplied by @code{exp(-abs(imag(x)))}.
+ at item bessely
+Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(-abs(imag(x)))}.
+ at item besseli
+Modified Bessel functions of the first kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(-abs(real(x)))}.
+ at item besselk
+Modified Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(x)}.
+ at item besselh
+Compute Hankel functions of the first (@var{k} = 1) or second (@var{k}
+= 2) kind.  If the argument @var{opt} is supplied, the result is multiplied by
+ at code{exp (-I*@var{x})} for @var{k} = 1 or @code{exp (I*@var{x})} for
+ at var{k} = 2.
+ at end table
+
+If @var{alpha} is a scalar, the result is the same size as @var{x}.
+If @var{x} is a scalar, the result is the same size as @var{alpha}.
+If @var{alpha} is a row vector and @var{x} is a column vector, the
+result is a matrix with @code{length (@var{x})} rows and
+ at code{length (@var{alpha})} columns.  Otherwise, @var{alpha} and
+ at var{x} must conform and the result will be the same size.
+
+The value of @var{alpha} must be real.  The value of @var{x} may be
+complex.
+
+If requested, @var{ierr} contains the following status information
+and is the same size as the result.
+
+ at enumerate 0
+ at item
+Normal return.
+ at item
+Input error, return @code{NaN}.
+ at item
+Overflow, return @code{Inf}.
+ at item
+Loss of significance by argument reduction results in less than
+half of machine accuracy.
+ at item
+Complete loss of significance by argument reduction, return @code{NaN}.
+ at item
+Error---no computation, algorithm termination condition not met,
+return @code{NaN}.
+ at end enumerate
+ at end deftypefn
+
+
+ at c ./specfun/beta.m
+ at anchor{doc-beta}
+ at deftypefn {Mapping Function} {} beta (@var{a}, @var{b})
+For real inputs, return the Beta function,
+ at tex
+$$
+ B (a, b) = {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
+ at end example
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/betainc.cc
+ at anchor{doc-betainc}
+ at deftypefn {Mapping Function} {} betainc (@var{x}, @var{a}, @var{b})
+Return the incomplete Beta function,
+ at iftex
+ at tex
+$$
+ \beta (x, a, b) = B (a, b)^{-1} \int_0^x t^{(a-z)} (1-t)^{(b-1)} dt.
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+                                      x
+                                     /
+betainc (x, a, b) = beta (a, b)^(-1) | t^(a-1) (1-t)^(b-1) dt.
+                                     /
+                                  t=0
+ at end smallexample
+ at end ifnottex
+
+If x has more than one component, both @var{a} and @var{b} must be
+scalars.  If @var{x} is a scalar, @var{a} and @var{b} must be of
+compatible dimensions.
+ at end deftypefn
+
+
+ at c ./specfun/betaln.m
+ at anchor{doc-betaln}
+ at deftypefn {Mapping Function} {} betaln (@var{a}, @var{b})
+Return the log of the Beta function,
+ at tex
+$$
+ B (a, b) = \log {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+betaln (a, b) = gammaln (a) + gammaln (b) - gammaln (a + b)
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-beta,,beta}, @ref{doc-betainc,,betainc}, @ref{doc-gammaln,,gammaln}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/bincoeff.m
+ at anchor{doc-bincoeff}
+ at deftypefn {Mapping Function} {} bincoeff (@var{n}, @var{k})
+Return the binomial coefficient of @var{n} and @var{k}, defined as
+ at tex
+$$
+ {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+ /   \
+ | n |    n (n-1) (n-2) @dots{} (n-k+1)
+ |   |  = -------------------------
+ | k |               k!
+ \   /
+ at end group
+ at end example
+ at end ifnottex
+
+For example,
+
+ at example
+ at group
+bincoeff (5, 2)
+     @result{} 10
+ at end group
+ at end example
+
+In most cases, the @code{nchoosek} function is faster for small
+scalar integer arguments.  It also warns about loss of precision for
+big arguments.
+
+ at seealso{@ref{doc-nchoosek,,nchoosek}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/commutation_matrix.m
+ at anchor{doc-commutation_matrix}
+ at deftypefn {Function File} {} commutation_matrix (@var{m}, @var{n})
+Return the commutation matrix
+ at tex
+ $K_{m,n}$
+ at end tex
+ at ifnottex
+ K(m,n)
+ at end ifnottex
+ which is the unique
+ at tex
+ $m n \times m n$
+ at end tex
+ at ifnottex
+ at var{m}*@var{n} by @var{m}*@var{n}
+ at end ifnottex
+ matrix such that
+ at tex
+ $K_{m,n} \cdot {\rm vec} (A) = {\rm vec} (A^T)$
+ at end tex
+ at ifnottex
+ at math{K(m,n) * vec(A) = vec(A')}
+ at end ifnottex
+ for all
+ at tex
+ $m\times n$
+ at end tex
+ at ifnottex
+ at math{m} by @math{n}
+ at end ifnottex
+ matrices
+ at tex
+ $A$.
+ at end tex
+ at ifnottex
+ at math{A}.
+ at end ifnottex
+
+If only one argument @var{m} is given,
+ at tex
+ $K_{m,m}$
+ at end tex
+ at ifnottex
+ at math{K(m,m)}
+ at end ifnottex
+ is returned.
+
+See Magnus and Neudecker (1988), Matrix differential calculus with
+applications in statistics and econometrics.
+ at end deftypefn
+
+
+ at c ./linear-algebra/duplication_matrix.m
+ at anchor{doc-duplication_matrix}
+ at deftypefn {Function File} {} duplication_matrix (@var{n})
+Return the duplication matrix
+ at tex
+ $D_n$
+ at end tex
+ at ifnottex
+ at math{Dn}
+ at end ifnottex
+ which is the unique
+ at tex
+ $n^2 \times n(n+1)/2$
+ at end tex
+ at ifnottex
+ at math{n^2} by @math{n*(n+1)/2}
+ at end ifnottex
+ matrix such that
+ at tex
+ $D_n * {\rm vech} (A) = {\rm vec} (A)$
+ at end tex
+ at ifnottex
+ at math{Dn vech (A) = vec (A)}
+ at end ifnottex
+ for all symmetric
+ at tex
+ $n \times n$
+ at end tex
+ at ifnottex
+ at math{n} by @math{n}
+ at end ifnottex
+ matrices
+ at tex
+ $A$.
+ at end tex
+ at ifnottex
+ at math{A}.
+ at end ifnottex
+
+See Magnus and Neudecker (1988), Matrix differential calculus with
+applications in statistics and econometrics.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-erf}
+ at deftypefn {Mapping Function} {} erf (@var{z})
+Computes the error function,
+ at iftex
+ at tex
+$$
+ {\rm erf} (z) = {2 \over \sqrt{\pi}}\int_0^z e^{-t^2} dt
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at group
+                         z
+                        /
+erf (z) = (2/sqrt (pi)) | e^(-t^2) dt
+                        /
+                     t=0
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-erfc,,erfc}, @ref{doc-erfinv,,erfinv}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-erfc}
+ at deftypefn {Mapping Function} {} erfc (@var{z})
+Computes the complementary error function,
+ at iftex
+ at tex
+$1 - {\rm erf} (z)$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{1 - erf (@var{z})}.
+ at end ifnottex
+ at seealso{@ref{doc-erf,,erf}, @ref{doc-erfinv,,erfinv}}
+ at end deftypefn
+
+
+ at c ./specfun/erfinv.m
+ at anchor{doc-erfinv}
+ at deftypefn {Mapping Function} {} erfinv (@var{z})
+Computes the inverse of the error function.
+ at seealso{@ref{doc-erf,,erf}, @ref{doc-erfc,,erfc}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-gamma}
+ at deftypefn {Mapping Function} {} gamma (@var{z})
+Computes the Gamma function,
+ at iftex
+ at tex
+$$
+ \Gamma (z) = \int_0^\infty t^{z-1} e^{-t} dt.
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at group
+            infinity
+            /
+gamma (z) = | t^(z-1) exp (-t) dt.
+            /
+         t=0
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-gammainc,,gammainc}, @ref{doc-lgamma,,lgamma}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/gammainc.cc
+ at anchor{doc-gammainc}
+ at deftypefn {Mapping Function} {} gammainc (@var{x}, @var{a})
+Compute the normalized incomplete gamma function,
+ at iftex
+ at tex
+$$
+ \gamma (x, a) = {\displaystyle\int_0^x e^{-t} t^{a-1} dt \over \Gamma (a)}
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at smallexample
+                                x
+                      1        /
+gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
+                  gamma (a)    /
+                            t=0
+ at end smallexample
+
+ at end ifnottex
+with the limiting value of 1 as @var{x} approaches infinity.
+The standard notation is @math{P(a,x)}, e.g., Abramowitz and Stegun (6.5.1).
+
+If @var{a} is scalar, then @code{gammainc (@var{x}, @var{a})} is returned
+for each element of @var{x} and vice versa.
+
+If neither @var{x} nor @var{a} is scalar, the sizes of @var{x} and
+ at var{a} must agree, and @var{gammainc} is applied element-by-element.
+ at seealso{@ref{doc-gamma,,gamma}, @ref{doc-lgamma,,lgamma}}
+ at end deftypefn
+
+
+ at c ./specfun/legendre.m
+ at anchor{doc-legendre}
+ at deftypefn {Function File} {@var{l} =} legendre (@var{n}, @var{x})
+ at deftypefnx {Function File} {@var{l} =} legendre (@var{n}, @var{x}, @var{normalization})
+Compute the Legendre function of degree @var{n} and order 
+ at var{m} = 0 @dots{} N.  The optional argument, @var{normalization}, 
+may be one of @code{"unnorm"}, @code{"sch"}, or @code{"norm"}.
+The default is @code{"unnorm"}.  The value of @var{n} must be a 
+non-negative scalar integer.  
+
+If the optional argument @var{normalization} is missing or is
+ at code{"unnorm"}, compute the Legendre function of degree @var{n} and
+order @var{m} and return all values for @var{m} = 0 @dots{} @var{n}.
+The return value has one dimension more than @var{x}.
+
+The Legendre Function of degree @var{n} and order @var{m}:
+
+ at example
+ at group
+ m        m       2  m/2   d^m
+P(x) = (-1) * (1-x  )    * ----  P (x)
+ n                         dx^m   n
+ at end group
+ at end example
+
+ at noindent
+with Legendre polynomial of degree @var{n}:
+
+ at example
+ at group
+          1     d^n   2    n
+P (x) = ------ [----(x - 1)  ]
+ n      2^n n!  dx^n
+ at end group
+ at end example
+
+ at noindent
+ at code{legendre (3, [-1.0, -0.9, -0.8])} returns the matrix:
+
+ at example
+ at group
+ x  |   -1.0   |   -0.9   |  -0.8
+------------------------------------
+m=0 | -1.00000 | -0.47250 | -0.08000
+m=1 |  0.00000 | -1.99420 | -1.98000
+m=2 |  0.00000 | -2.56500 | -4.32000
+m=3 |  0.00000 | -1.24229 | -3.24000 
+ at end group
+ at end example
+
+If the optional argument @code{normalization} is @code{"sch"}, 
+compute the Schmidt semi-normalized associated Legendre function.
+The Schmidt semi-normalized associated Legendre function is related
+to the unnormalized Legendre functions by the following:
+
+For Legendre functions of degree n and order 0:
+
+ at example
+ at group
+  0       0
+SP (x) = P (x)
+  n       n
+ at end group
+ at end example
+
+For Legendre functions of degree n and order m:
+
+ at example
+ at group
+  m       m          m    2(n-m)! 0.5
+SP (x) = P (x) * (-1)  * [-------]
+  n       n               (n+m)!
+ at end group
+ at end example
+
+If the optional argument @var{normalization} is @code{"norm"}, 
+compute the fully normalized associated Legendre function.
+The fully normalized associated Legendre function is related
+to the unnormalized Legendre functions by the following:
+
+For Legendre functions of degree @var{n} and order @var{m}
+
+ at example
+ at group
+  m       m          m    (n+0.5)(n-m)! 0.5
+NP (x) = P (x) * (-1)  * [-------------]
+  n       n                   (n+m)!    
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at anchor{doc-gammaln}
+ at c mappers.cc
+ at anchor{doc-lgamma}
+ at deftypefn {Mapping Function} {} lgamma (@var{x})
+ at deftypefnx {Mapping Function} {} gammaln (@var{x})
+Return the natural logarithm of the gamma function of @var{x}.
+ at seealso{@ref{doc-gamma,,gamma}, @ref{doc-gammainc,,gammainc}}
+ at end deftypefn
+
+
+ at node Coordinate Transformations
+ at section Coordinate Transformations
+
+ at c ./general/cart2pol.m
+ at anchor{doc-cart2pol}
+ at deftypefn  {Function File} {[@var{theta}, @var{r}] =} cart2pol (@var{x}, @var{y})
+ at deftypefnx {Function File} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{x}, @var{y}, @var{z})
+Transform Cartesian to polar or cylindrical coordinates.
+ at var{x}, @var{y} (and @var{z}) must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{r} is the distance to the z-axis (0, 0, z).
+ at seealso{@ref{doc-pol2cart,,pol2cart}, @ref{doc-cart2sph,,cart2sph}, @ref{doc-sph2cart,,sph2cart}}
+ at end deftypefn
+
+
+ at c ./general/pol2cart.m
+ at anchor{doc-pol2cart}
+ at deftypefn {Function File} {[@var{x}, @var{y}] =} pol2cart (@var{theta}, @var{r})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{theta}, @var{r}, @var{z})
+Transform polar or cylindrical to Cartesian coordinates.
+ at var{theta}, @var{r} (and @var{z}) must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{r} is the distance to the z-axis (0, 0, z).
+ at seealso{@ref{doc-cart2pol,,cart2pol}, @ref{doc-cart2sph,,cart2sph}, @ref{doc-sph2cart,,sph2cart}}
+ at end deftypefn
+
+
+ at c ./general/cart2sph.m
+ at anchor{doc-cart2sph}
+ at deftypefn {Function File} {[@var{theta}, @var{phi}, @var{r}] =} cart2sph (@var{x}, @var{y}, @var{z})
+Transform Cartesian to spherical coordinates.
+ at var{x}, @var{y} and @var{z} must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{phi} is the angle relative to the xy-plane.
+ at var{r} is the distance to the origin (0, 0, 0).
+ at seealso{@ref{doc-pol2cart,,pol2cart}, @ref{doc-cart2pol,,cart2pol}, @ref{doc-sph2cart,,sph2cart}}
+ at end deftypefn
+
+
+ at c ./general/sph2cart.m
+ at anchor{doc-sph2cart}
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{theta}, @var{phi}, @var{r})
+Transform spherical to Cartesian coordinates.
+ at var{x}, @var{y} and @var{z} must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{phi} is the angle relative to the xy-plane.
+ at var{r} is the distance to the origin (0, 0, 0).
+ at seealso{@ref{doc-pol2cart,,pol2cart}, @ref{doc-cart2pol,,cart2pol}, @ref{doc-cart2sph,,cart2sph}}
+ at end deftypefn
+
+
+ at node Mathematical Constants
+ at section Mathematical Constants
+
+ at c data.cc
+ at anchor{doc-e}
+ at deftypefn  {Built-in Function} {} e
+ at deftypefnx {Built-in Function} {} e (@var{n})
+ at deftypefnx {Built-in Function} {} e (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} e (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} e (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the base of natural logarithms.  The constant
+ at tex
+$e$ satisfies the equation $\log (e) = 1$.
+ at end tex
+ at ifnottex
+ at samp{e} satisfies the equation @code{log} (e) = 1.
+ at end ifnottex
+
+When called with no arguments, return a scalar with the value @math{e}.  When
+called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-pi}
+ at deftypefn  {Built-in Function} {} pi
+ at deftypefnx {Built-in Function} {} pi (@var{n})
+ at deftypefnx {Built-in Function} {} pi (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} pi (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} pi (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the ratio of the circumference of a circle to its
+ at tex
+diameter($\pi$).
+ at end tex
+ at ifnottex
+diameter.
+ at end ifnottex
+Internally, @code{pi} is computed as @samp{4.0 * atan (1.0)}.
+
+When called with no arguments, return a scalar with the value of
+ at tex
+$\pi$.
+ at end tex
+ at ifnottex
+pi.
+ at end ifnottex
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-I}
+ at deftypefn  {Built-in Function} {} I
+ at deftypefnx {Built-in Function} {} I (@var{n})
+ at deftypefnx {Built-in Function} {} I (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} I (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} I (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the pure imaginary unit, defined as
+ at tex
+$\sqrt{-1}$.
+ at end tex
+ at ifnottex
+ at code{sqrt (-1)}.
+ at end ifnottex
+ I, and its equivalents i, J, and j, are functions so any of the names may
+be reused for other purposes (such as i for a counter variable).
+
+When called with no arguments, return a scalar with the value @math{i}.  When
+called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-Inf}
+ at deftypefn  {Built-in Function} {} Inf
+ at deftypefnx {Built-in Function} {} Inf (@var{n})
+ at deftypefnx {Built-in Function} {} Inf (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} Inf (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} Inf (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the IEEE representation for positive infinity.
+
+Infinity is produced when results are too large to be represented using the
+the IEEE floating point format for numbers.  Two common examples which
+produce infinity are division by zero and overflow.
+ at example
+ at group
+[1/0 e^800]
+ at result{}
+Inf   Inf
+ at end group
+ at end example
+
+When called with no arguments, return a scalar with the value @samp{Inf}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{@ref{doc-isinf,,isinf}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-NaN}
+ at deftypefn  {Built-in Function} {} NaN
+ at deftypefnx {Built-in Function} {} NaN (@var{n})
+ at deftypefnx {Built-in Function} {} NaN (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} NaN (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} NaN (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the IEEE symbol NaN (Not a Number).
+NaN is the result of operations which do not produce a well defined numerical
+result.  Common operations which produce a NaN are arithmetic with infinity
+ at tex
+($\infty - \infty$), zero divided by zero ($0/0$),
+ at end tex
+ at ifnottex
+(Inf - Inf), zero divided by zero (0/0),
+ at end ifnottex
+and any operation involving another NaN value (5 + NaN).
+
+Note that NaN always compares not equal to NaN (NaN != NaN).  This behavior
+is specified by the IEEE standard for floating point arithmetic.  To
+find NaN values, use the @code{isnan} function.
+
+When called with no arguments, return a scalar with the value @samp{NaN}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{@ref{doc-isnan,,isnan}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-eps}
+ at deftypefn  {Built-in Function} {} eps
+ at deftypefnx {Built-in Function} {} eps (@var{x})
+ at deftypefnx {Built-in Function} {} eps (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} eps (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} eps (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all eps,
+the machine precision.  More precisely, @code{eps} is the relative spacing
+between any two adjacent numbers in the machine's floating point system.
+This number is obviously system dependent.  On machines that support IEEE
+floating point arithmetic, @code{eps} is approximately
+ at tex
+$2.2204\times10^{-16}$ for double precision and $1.1921\times10^{-7}$
+ at end tex
+ at ifnottex
+2.2204e-16 for double precision and 1.1921e-07
+ at end ifnottex
+for single precision.
+
+When called with no arguments, return a scalar with the value
+ at code{eps(1.0)}.
+Given a single argument @var{x}, return the distance between @var{x} and
+the next largest value.
+When called with more than one argument the first two arguments are taken as
+the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-realmax}
+ at deftypefn  {Built-in Function} {} realmax
+ at deftypefnx {Built-in Function} {} realmax (@var{n})
+ at deftypefnx {Built-in Function} {} realmax (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} realmax (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} realmax (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the largest floating point number that is representable.  The actual
+value is system dependent.  On machines that support IEEE
+floating point arithmetic, @code{realmax} is approximately
+ at tex
+$1.7977\times10^{308}$ for double precision and $3.4028\times10^{38}$
+ at end tex
+ at ifnottex
+1.7977e+308 for double precision and 3.4028e+38
+ at end ifnottex
+for single precision.
+
+When called with no arguments, return a scalar with the value
+ at code{realmax("double")}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{@ref{doc-realmin,,realmin}, @ref{doc-intmax,,intmax}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-realmin}
+ at deftypefn  {Built-in Function} {} realmin
+ at deftypefnx {Built-in Function} {} realmin (@var{n})
+ at deftypefnx {Built-in Function} {} realmin (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} realmin (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} realmin (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the smallest normalized floating point number that is representable.
+The actual value is system dependent.  On machines that support
+IEEE floating point arithmetic, @code{realmin} is approximately
+ at tex
+$2.2251\times10^{-308}$ for double precision and $1.1755\times10^{-38}$
+ at end tex
+ at ifnottex
+2.2251e-308 for double precision and 1.1755e-38
+ at end ifnottex
+for single precision.
+
+When called with no arguments, return a scalar with the value
+ at code{realmin("double")}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{@ref{doc-realmax,,realmax}, @ref{doc-intmin,,intmin}}
+ at end deftypefn
+
diff --git a/doc/interpreter/arith.txi b/doc/interpreter/arith.txi
new file mode 100644
index 0000000..3d98727
--- /dev/null
+++ b/doc/interpreter/arith.txi
@@ -0,0 +1,302 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2007, 2008,
+ at c               2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Arithmetic
+ at chapter Arithmetic
+
+Unless otherwise noted, all of the functions described in this chapter
+will work for real and complex scalar, vector, or matrix arguments.  Functions
+described as @dfn{mapping functions} apply the given operation individually to 
+each element when given a matrix argument.  For example,
+
+ at example
+ at group
+sin ([1, 2; 3, 4])
+     @result{}  0.84147   0.90930
+         0.14112  -0.75680
+ at end group
+ at end example
+
+ at menu
+* Exponents and Logarithms::
+* Complex Arithmetic::          
+* Trigonometry::                
+* Sums and Products::           
+* Utility Functions::           
+* Special Functions::           
+* Coordinate Transformations::
+* Mathematical Constants::      
+ at end menu
+
+ at node Exponents and Logarithms
+ at section Exponents and Logarithms
+
+ at DOCSTRING(exp)
+
+ at DOCSTRING(expm1)
+
+ at DOCSTRING(log)
+
+ at DOCSTRING(log1p)
+
+ at DOCSTRING(log10)
+
+ at DOCSTRING(log2)
+
+ at DOCSTRING(nextpow2)
+
+ at DOCSTRING(nthroot)
+
+ at DOCSTRING(pow2)
+
+ at DOCSTRING(reallog)
+
+ at DOCSTRING(realpow)
+
+ at DOCSTRING(realsqrt)
+
+ at DOCSTRING(sqrt)
+
+ at node Complex Arithmetic
+ at section Complex Arithmetic
+
+In the descriptions of the following functions,
+ at tex
+$z$ is the complex number $x + iy$, where $i$ is defined as
+$\sqrt{-1}$.
+ at end tex
+ at ifinfo
+ at var{z} is the complex number @var{x} + @var{i}@var{y}, where @var{i} is
+defined as @code{sqrt (-1)}.
+ at end ifinfo
+
+ at DOCSTRING(abs)
+
+ at DOCSTRING(arg)
+
+ at DOCSTRING(conj)
+
+ at DOCSTRING(cplxpair)
+
+ at DOCSTRING(imag)
+
+ at DOCSTRING(real)
+
+ at node Trigonometry
+ at section Trigonometry
+
+Octave provides the following trigonometric functions where angles are
+specified in radians.  To convert from degrees to radians multiply by
+ at tex
+$\pi/180$
+ at end tex
+ at ifnottex
+ at code{pi/180}
+ at end ifnottex
+(e.g., @code{sin (30 * pi/180)} returns the sine of 30 degrees).  As
+an alternative, Octave provides a number of trigonometric functions
+which work directly on an argument specified in degrees.  These functions
+are named after the base trigonometric function with a @samp{d} suffix.  For
+example, @code{sin} expects an angle in radians while @code{sind} expects an
+angle in degrees.
+
+ at DOCSTRING(sin)
+ at DOCSTRING(cos)
+ at DOCSTRING(tan)
+ at DOCSTRING(sec)
+ at DOCSTRING(csc)
+ at DOCSTRING(cot)
+
+ at DOCSTRING(asin)
+ at DOCSTRING(acos)
+ at DOCSTRING(atan)
+ at DOCSTRING(asec)
+ at DOCSTRING(acsc)
+ at DOCSTRING(acot)
+
+ at DOCSTRING(sinh)
+ at DOCSTRING(cosh)
+ at DOCSTRING(tanh)
+ at DOCSTRING(sech)
+ at DOCSTRING(csch)
+ at DOCSTRING(coth)
+
+ at DOCSTRING(asinh)
+ at DOCSTRING(acosh)
+ at DOCSTRING(atanh)
+ at DOCSTRING(asech)
+ at DOCSTRING(acsch)
+ at DOCSTRING(acoth)
+
+ at DOCSTRING(atan2)
+
+Octave provides the following trigonometric functions where angles are
+specified in degrees.  These functions produce true zeros at the appropriate
+intervals rather than the small roundoff error that occurs when using
+radians.  For example:
+ at example
+ at group
+cosd (90)
+     @result{} 0
+cos (pi/2)
+     @result{} 6.1230e-17
+ at end group
+ at end example
+
+ at DOCSTRING(sind)
+ at DOCSTRING(cosd)
+ at DOCSTRING(tand)
+ at DOCSTRING(secd)
+ at DOCSTRING(cscd)
+ at DOCSTRING(cotd)
+
+ at DOCSTRING(asind)
+ at DOCSTRING(acosd)
+ at DOCSTRING(atand)
+ at DOCSTRING(asecd)
+ at DOCSTRING(acscd)
+ at DOCSTRING(acotd)
+
+ at node Sums and Products
+ at section Sums and Products
+
+ at DOCSTRING(sum)
+
+ at DOCSTRING(prod)
+
+ at DOCSTRING(cumsum)
+
+ at DOCSTRING(cumprod)
+
+ at DOCSTRING(sumsq)
+
+ at DOCSTRING(accumarray)
+
+ at node Utility Functions
+ at section Utility Functions
+
+ at DOCSTRING(ceil)
+
+ at DOCSTRING(cross)
+
+ at DOCSTRING(del2)
+
+ at DOCSTRING(factor)
+
+ at DOCSTRING(factorial)
+
+ at DOCSTRING(fix)
+
+ at DOCSTRING(floor)
+
+ at DOCSTRING(fmod)
+
+ at DOCSTRING(gcd)
+
+ at DOCSTRING(gradient)
+
+ at DOCSTRING(hypot)
+
+ at DOCSTRING(lcm)
+
+ at DOCSTRING(list_primes)
+
+ at DOCSTRING(max)
+
+ at DOCSTRING(min)
+
+ at DOCSTRING(cummax)
+
+ at DOCSTRING(cummin)
+
+ at DOCSTRING(mod)
+
+ at DOCSTRING(primes)
+
+ at DOCSTRING(rem)
+
+ at DOCSTRING(round)
+
+ at DOCSTRING(roundb)
+
+ at DOCSTRING(sign)
+
+ at node Special Functions
+ at section Special Functions
+
+ at DOCSTRING(airy)
+
+ at DOCSTRING(besselj)
+
+ at DOCSTRING(beta)
+
+ at DOCSTRING(betainc)
+
+ at DOCSTRING(betaln)
+
+ at DOCSTRING(bincoeff)
+
+ at DOCSTRING(commutation_matrix)
+
+ at DOCSTRING(duplication_matrix)
+
+ at DOCSTRING(erf)
+
+ at DOCSTRING(erfc)
+
+ at DOCSTRING(erfinv)
+
+ at DOCSTRING(gamma)
+
+ at DOCSTRING(gammainc)
+
+ at DOCSTRING(legendre)
+
+ at anchor{doc-gammaln}
+ at DOCSTRING(lgamma)
+
+ at node Coordinate Transformations
+ at section Coordinate Transformations
+
+ at DOCSTRING(cart2pol)
+
+ at DOCSTRING(pol2cart)
+
+ at DOCSTRING(cart2sph)
+
+ at DOCSTRING(sph2cart)
+
+ at node Mathematical Constants
+ at section Mathematical Constants
+
+ at DOCSTRING(e)
+
+ at DOCSTRING(pi)
+
+ at DOCSTRING(I)
+
+ at DOCSTRING(Inf)
+
+ at DOCSTRING(NaN)
+
+ at DOCSTRING(eps)
+
+ at DOCSTRING(realmax)
+
+ at DOCSTRING(realmin)
diff --git a/doc/interpreter/audio.texi b/doc/interpreter/audio.texi
new file mode 100644
index 0000000..73007e4
--- /dev/null
+++ b/doc/interpreter/audio.texi
@@ -0,0 +1,171 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2005, 2007, 2009 Kurt Hornik
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/05/14
+
+ at node Audio Processing
+ at chapter Audio Processing
+
+Octave provides a few functions for dealing with audio data.  An audio
+`sample' is a single output value from an A/D converter, i.e., a small
+integer number (usually 8 or 16 bits), and audio data is just a series
+of such samples.  It can be characterized by three parameters:  the
+sampling rate (measured in samples per second or Hz, e.g., 8000 or
+44100), the number of bits per sample (e.g., 8 or 16), and the number of
+channels (1 for mono, 2 for stereo, etc.).
+
+There are many different formats for representing such data.  Currently,
+only the two most popular, @emph{linear encoding} and @emph{mu-law
+encoding}, are supported by Octave.  There is an excellent FAQ on audio
+formats by Guido van Rossum <guido@@cwi.nl> which can be found at any
+FAQ ftp site, in particular in the directory
+ at file{/pub/usenet/news.answers/audio-fmts} of the archive site
+ at code{rtfm.mit.edu}.
+
+Octave simply treats audio data as vectors of samples (non-mono data are
+not supported yet).  It is assumed that audio files using linear
+encoding have one of the extensions @file{lin} or @file{raw}, and that
+files holding data in mu-law encoding end in @file{au}, @file{mu}, or
+ at file{snd}.
+
+ at c ./audio/lin2mu.m
+ at anchor{doc-lin2mu}
+ at deftypefn {Function File} {} lin2mu (@var{x}, @var{n})
+Converts audio data from linear to mu-law.  Mu-law values use 8-bit
+unsigned integers.  Linear values use @var{n}-bit signed integers or 
+floating point values in the range -1<=@var{x}<=1 if @var{n} is 0.  
+If @var{n} is not specified it defaults to 0, 8 or 16 depending on 
+the range values in @var{x}.
+ at seealso{@ref{doc-mu2lin,,mu2lin}, @ref{doc-loadaudio,,loadaudio}, @ref{doc-saveaudio,,saveaudio}, @ref{doc-playaudio,,playaudio}, @ref{doc-setaudio,,setaudio}, @ref{doc-record,,record}}
+ at end deftypefn
+
+
+ at c ./audio/mu2lin.m
+ at anchor{doc-mu2lin}
+ at deftypefn {Function File} {} mu2lin (@var{x}, @var{bps})
+Converts audio data from linear to mu-law.  Mu-law values are 8-bit
+unsigned integers.  Linear values use @var{n}-bit signed integers
+or floating point values in the range -1<=y<=1 if @var{n} is 0.  If
+ at var{n} is not specified it defaults to 8.
+ at seealso{@ref{doc-lin2mu,,lin2mu}, @ref{doc-loadaudio,,loadaudio}, @ref{doc-saveaudio,,saveaudio}, @ref{doc-playaudio,,playaudio}, @ref{doc-setaudio,,setaudio}, @ref{doc-record,,record}}
+ at end deftypefn
+
+
+ at c ./audio/loadaudio.m
+ at anchor{doc-loadaudio}
+ at deftypefn {Function File} {} loadaudio (@var{name}, @var{ext}, @var{bps})
+Loads audio data from the file @file{@var{name}. at var{ext}} into the
+vector @var{x}.
+
+The extension @var{ext} determines how the data in the audio file is
+interpreted;  the extensions @file{lin} (default) and @file{raw}
+correspond to linear, the extensions @file{au}, @file{mu}, or @file{snd}
+to mu-law encoding.
+
+The argument @var{bps} can be either 8 (default) or 16, and specifies
+the number of bits per sample used in the audio file.
+ at seealso{@ref{doc-lin2mu,,lin2mu}, @ref{doc-mu2lin,,mu2lin}, @ref{doc-saveaudio,,saveaudio}, @ref{doc-playaudio,,playaudio}, @ref{doc-setaudio,,setaudio}, @ref{doc-record,,record}}
+ at end deftypefn
+
+
+ at c ./audio/saveaudio.m
+ at anchor{doc-saveaudio}
+ at deftypefn {Function File} {} saveaudio (@var{name}, @var{x}, @var{ext}, @var{bps})
+Saves a vector @var{x} of audio data to the file
+ at file{@var{name}. at var{ext}}.  The optional parameters @var{ext} and
+ at var{bps} determine the encoding and the number of bits per sample used
+in the audio file (see @code{loadaudio});  defaults are @file{lin} and
+8, respectively.
+ at seealso{@ref{doc-lin2mu,,lin2mu}, @ref{doc-mu2lin,,mu2lin}, @ref{doc-loadaudio,,loadaudio}, @ref{doc-playaudio,,playaudio}, @ref{doc-setaudio,,setaudio}, @ref{doc-record,,record}}
+ at end deftypefn
+
+
+The following functions for audio I/O require special A/D hardware and
+operating system support.  It is assumed that audio data in linear
+encoding can be played and recorded by reading from and writing to
+ at file{/dev/dsp}, and that similarly @file{/dev/audio} is used for mu-law
+encoding.  These file names are system-dependent.  Improvements so that
+these functions will work without modification on a wide variety of
+hardware are welcome.
+
+ at c ./audio/playaudio.m
+ at anchor{doc-playaudio}
+ at deftypefn {Function File} {} playaudio (@var{name}, @var{ext})
+ at deftypefnx {Function File} {} playaudio (@var{x})
+Plays the audio file @file{@var{name}. at var{ext}} or the audio data
+stored in the vector @var{x}.
+ at seealso{@ref{doc-lin2mu,,lin2mu}, @ref{doc-mu2lin,,mu2lin}, @ref{doc-loadaudio,,loadaudio}, @ref{doc-saveaudio,,saveaudio}, @ref{doc-setaudio,,setaudio}, @ref{doc-record,,record}}
+ at end deftypefn
+
+
+ at c ./audio/record.m
+ at anchor{doc-record}
+ at deftypefn {Function File} {} record (@var{sec}, @var{sampling_rate})
+Records @var{sec} seconds of audio input into the vector @var{x}.  The
+default value for @var{sampling_rate} is 8000 samples per second, or
+8kHz.  The program waits until the user types @key{RET} and then
+immediately starts to record.
+ at seealso{@ref{doc-lin2mu,,lin2mu}, @ref{doc-mu2lin,,mu2lin}, @ref{doc-loadaudio,,loadaudio}, @ref{doc-saveaudio,,saveaudio}, @ref{doc-playaudio,,playaudio}, @ref{doc-setaudio,,setaudio}}
+ at end deftypefn
+
+
+ at c ./audio/setaudio.m
+ at anchor{doc-setaudio}
+ at deftypefn {Function File} {} setaudio ([@var{w_type} [, @var{value}]])
+Execute the shell command @samp{mixer [@var{w_type} [, @var{value}]]}
+ at end deftypefn
+
+
+ at c ./audio/wavread.m
+ at anchor{doc-wavread}
+ at deftypefn {Function File} {@var{y} =} wavread (@var{filename})
+Load the RIFF/WAVE sound file @var{filename}, and return the samples
+in vector @var{y}.  If the file contains multichannel data, then
+ at var{y} is a matrix with the channels represented as columns.
+
+ at deftypefnx {Function File} {[@var{y}, @var{Fs}, @var{bits}] =} wavread (@var{filename})
+Additionally return the sample rate (@var{fs}) in Hz and the number of bits 
+per sample (@var{bits}).
+
+ at deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, @var{n})
+Read only the first @var{n} samples from each channel.
+
+ at deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename},[@var{n1} @var{n2}])
+Read only samples @var{n1} through @var{n2} from each channel.
+
+ at deftypefnx {Function File} {[@var{samples}, @var{channels}] =} wavread (@var{filename}, "size")
+Return the number of samples (@var{n}) and channels (@var{ch})
+instead of the audio data.
+ at seealso{@ref{doc-wavwrite,,wavwrite}}
+ at end deftypefn
+
+
+ at c ./audio/wavwrite.m
+ at anchor{doc-wavwrite}
+ at deftypefn {Function File} {} wavwrite (@var{y}, @var{filename})
+ at deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{filename})
+ at deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{bits}, @var{filename})
+Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}
+with sample rate @var{fs} and bits per sample @var{bits}.  The
+default sample rate is 8000 Hz with 16-bits per sample.  Each column
+of the data represents a separate channel.
+ at seealso{@ref{doc-wavread,,wavread}}
+ at end deftypefn
+
diff --git a/doc/interpreter/audio.txi b/doc/interpreter/audio.txi
new file mode 100644
index 0000000..8c1737f
--- /dev/null
+++ b/doc/interpreter/audio.txi
@@ -0,0 +1,70 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2005, 2007, 2009 Kurt Hornik
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/05/14
+
+ at node Audio Processing
+ at chapter Audio Processing
+
+Octave provides a few functions for dealing with audio data.  An audio
+`sample' is a single output value from an A/D converter, i.e., a small
+integer number (usually 8 or 16 bits), and audio data is just a series
+of such samples.  It can be characterized by three parameters:  the
+sampling rate (measured in samples per second or Hz, e.g., 8000 or
+44100), the number of bits per sample (e.g., 8 or 16), and the number of
+channels (1 for mono, 2 for stereo, etc.).
+
+There are many different formats for representing such data.  Currently,
+only the two most popular, @emph{linear encoding} and @emph{mu-law
+encoding}, are supported by Octave.  There is an excellent FAQ on audio
+formats by Guido van Rossum <guido@@cwi.nl> which can be found at any
+FAQ ftp site, in particular in the directory
+ at file{/pub/usenet/news.answers/audio-fmts} of the archive site
+ at code{rtfm.mit.edu}.
+
+Octave simply treats audio data as vectors of samples (non-mono data are
+not supported yet).  It is assumed that audio files using linear
+encoding have one of the extensions @file{lin} or @file{raw}, and that
+files holding data in mu-law encoding end in @file{au}, @file{mu}, or
+ at file{snd}.
+
+ at DOCSTRING(lin2mu)
+
+ at DOCSTRING(mu2lin)
+
+ at DOCSTRING(loadaudio)
+
+ at DOCSTRING(saveaudio)
+
+The following functions for audio I/O require special A/D hardware and
+operating system support.  It is assumed that audio data in linear
+encoding can be played and recorded by reading from and writing to
+ at file{/dev/dsp}, and that similarly @file{/dev/audio} is used for mu-law
+encoding.  These file names are system-dependent.  Improvements so that
+these functions will work without modification on a wide variety of
+hardware are welcome.
+
+ at DOCSTRING(playaudio)
+
+ at DOCSTRING(record)
+
+ at DOCSTRING(setaudio)
+
+ at DOCSTRING(wavread)
+
+ at DOCSTRING(wavwrite)
diff --git a/doc/interpreter/basics.texi b/doc/interpreter/basics.texi
new file mode 100644
index 0000000..e862141
--- /dev/null
+++ b/doc/interpreter/basics.texi
@@ -0,0 +1,1571 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
+ at c               2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Getting Started
+ at chapter Getting Started
+
+This chapter explains some of Octave's basic features, including how to
+start an Octave session, get help at the command prompt, edit the
+command line, and write Octave programs that can be executed as commands
+from your shell.
+
+ at menu
+* Invoking Octave from the Command Line::             
+* Quitting Octave::             
+* Getting Help::                
+* Command Line Editing::        
+* Errors::                      
+* Executable Octave Programs::  
+* Comments::                    
+ at end menu
+
+ at node Invoking Octave from the Command Line
+ at section Invoking Octave from the Command Line
+
+Normally, Octave is used interactively by running the program
+ at samp{octave} without any arguments.  Once started, Octave reads
+commands from the terminal until you tell it to exit.
+
+You can also specify the name of a file on the command line, and Octave
+will read and execute the commands from the named file and then exit
+when it is finished.
+
+You can further control how Octave starts by using the command-line
+options described in the next section, and Octave itself can remind you
+of the options available.  Type @samp{octave --help} to display all
+available options and briefly describe their use (@samp{octave -h} is a
+shorter equivalent).
+
+ at menu
+* Command Line Options::        
+* Startup Files::               
+ at end menu
+
+ at node Command Line Options
+ at subsection Command Line Options
+ at cindex Octave command options
+ at cindex command options
+ at cindex options, Octave command
+
+Here is a complete list of the command line options that Octave
+accepts.
+
+
+ at table @code
+ at item  --debug
+ at itemx -d
+ at cindex @code{--debug}
+ at cindex @code{-d}
+Enter parser debugging mode.  Using this option will cause Octave's
+parser to print a lot of information about the commands it reads, and is
+probably only useful if you are actually trying to debug the parser.
+
+ at item --doc-cache-file @var{filename}
+ at cindex @code{--doc-cache-file @var{filename}}
+Specify the name of the doc cache file to use.  The value of @var{filename}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_DOC_CACHE_FILE}} found in the environment, but not any commands
+in the system or user startup files that use the @code{doc_cache_file}
+function.
+
+ at item  --echo-commands
+ at itemx -x
+ at cindex @code{--echo-commands}
+ at cindex @code{-x}
+Echo commands as they are executed.
+
+ at item --eval @var{code}
+Evaluate @var{code} and exit when finished unless @code{--persist} is also
+specified.
+
+ at item --exec-path @var{path}
+ at cindex @code{--exec-path @var{path}}
+Specify the path to search for programs to run.  The value of @var{path}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_EXEC_PATH}} found in the environment, but not any commands
+in the system or user startup files that set the built-in variable
+ at w{@code{EXEC_PATH}}.
+
+ at item  --help
+ at itemx -h
+ at itemx -?
+ at cindex @code{--help}
+ at cindex @code{-h}
+ at cindex @code{-?}
+Print short help message and exit.
+
+ at item --image-path @var{path}
+ at cindex @code{--image-path @var{path}}
+Add path to the head of the search path for images.  The value of 
+ at var{path} specified on the command line will override any value of 
+ at w{@code{OCTAVE_IMAGE_PATH}} found in the environment, but not any commands 
+in the system or user startup files that set the built-in variable 
+ at w{@code{IMAGE_PATH}}.
+
+ at item --info-file @var{filename}
+ at cindex @code{--info-file @var{filename}}
+Specify the name of the info file to use.  The value of @var{filename}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_INFO_FILE}} found in the environment, but not any commands
+in the system or user startup files that use the @code{info_file}
+function.
+
+ at item --info-program @var{program}
+ at cindex @code{--info-program @var{program}}
+Specify the name of the info program to use.  The value of @var{program}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_INFO_PROGRAM}} found in the environment, but not any
+commands in the system or user startup files that use the
+ at code{info_program} function.
+
+ at item  --interactive
+ at itemx -i
+ at cindex @code{--interactive}
+ at cindex @code{-i}
+Force interactive behavior.  This can be useful for running Octave via a
+remote shell command or inside an Emacs shell buffer.  For another way
+to run Octave within Emacs, see @ref{Emacs Octave Support}.
+
+ at item --line-editing
+ at cindex @code{--line-editing}
+Force readline use for command-line editing.
+
+ at item  --no-history
+ at itemx -H
+ at cindex @code{--no-history}
+ at cindex @code{-H}
+Disable recording of command-line history.
+
+ at item --no-init-file
+ at cindex @code{--no-init-file}
+Don't read the initialization files @file{~/.octaverc} and @file{.octaverc}.
+
+ at item --no-init-path
+ at cindex @code{--no-init-path}
+Don't initialize the search path for function files to include default 
+locations.
+
+ at item --no-line-editing
+ at cindex @code{--no-line-editing}
+Disable command-line editing.
+
+ at item --no-site-file
+ at cindex @code{--no-site-file}
+Don't read the site-wide @file{octaverc} initialization files.
+
+ at item  --norc
+ at itemx -f
+ at cindex @code{--norc}
+ at cindex @code{-f}
+Don't read any of the system or user initialization files at startup.
+This is equivalent to using both of the options @code{--no-init-file}
+and @code{--no-site-file}.
+
+ at item  --path @var{path}
+ at itemx -p @var{path}
+ at cindex @code{--path @var{path}}
+ at cindex @code{-p @var{path}}
+Add path to the head of the search path for function files.  The 
+value of @var{path} specified on the command line will override any value
+of @w{@code{OCTAVE_PATH}} found in the environment, but not any commands in the
+system or user startup files that set the internal load path through one
+of the path functions.
+
+ at item --persist
+ at cindex @code{--persist}
+Go to interactive mode after @code{--eval} or reading from a file
+named on the command line.
+
+ at item  --silent
+ at itemx --quiet
+ at itemx -q
+ at cindex @code{--silent}
+ at cindex @code{--quiet}
+ at cindex @code{-q}
+Don't print the usual greeting and version message at startup.
+
+ at item  --traditional
+ at itemx --braindead
+ at cindex @code{--traditional}
+ at cindex @code{--braindead}
+For compatibility with @sc{matlab}, set initial values for
+user preferences to the following values
+
+ at example
+ at group
+PS1                     = ">> "
+PS2                     = ""
+beep_on_error           = true
+confirm_recursive_rmdir = false
+crash_dumps_octave_core = false
+default_save_options    = "-mat-binary"
+fixed_point_format      = true
+history_timestamp_format_string
+                        = "%%-- %D %I:%M %p --%%"
+page_screen_output      = false
+print_empty_dimensions  = false
+ at end group
+ at end example
+
+ at noindent
+and disable the following warnings
+ at example
+ at group
+Octave:fopen-file-in-path
+Octave:function-name-clash
+Octave:load-file-in-path
+ at end group
+ at end example
+
+ at item  --verbose
+ at itemx -V
+ at cindex @code{--verbose}
+ at cindex @code{-V}
+Turn on verbose output.
+
+ at item  --version
+ at itemx -v
+ at cindex @code{--version}
+ at cindex @code{-v}
+Print the program version number and exit.
+
+ at item @var{file}
+Execute commands from @var{file}.  Exit when done unless
+ at code{--persist} is also specified.
+ at end table
+
+Octave also includes several functions which return information 
+about the command line, including the number of arguments and all of the
+options.
+
+ at c octave.cc
+ at anchor{doc-argv}
+ at deftypefn {Built-in Function} {} argv ()
+Return the command line arguments passed to Octave.  For example,
+if you invoked Octave using the command
+
+ at example
+octave --no-line-editing --silent
+ at end example
+
+ at noindent
+ at code{argv} would return a cell array of strings with the elements
+ at code{--no-line-editing} and @code{--silent}.
+
+If you write an executable Octave script, @code{argv} will return the
+list of arguments passed to the script.  @xref{Executable Octave Programs},
+for an example of how to create an executable Octave script.
+ at end deftypefn
+
+
+ at c octave.cc
+ at anchor{doc-program_name}
+ at deftypefn {Built-in Function} {} program_name ()
+Return the last component of the value returned by
+ at code{program_invocation_name}.
+ at seealso{@ref{doc-program_invocation_name,,program_invocation_name}}
+ at end deftypefn
+
+
+ at c octave.cc
+ at anchor{doc-program_invocation_name}
+ at deftypefn {Built-in Function} program_invocation_name ()
+Return the name that was typed at the shell prompt to run Octave.
+
+If executing a script from the command line (e.g., @code{octave foo.m})
+or using an executable Octave script, the program name is set to the
+name of the script.  @xref{Executable Octave Programs}, for an example of
+how to create an executable Octave script.
+ at seealso{@ref{doc-program_name,,program_name}}
+ at end deftypefn
+
+
+Here is an example of using these functions to reproduce the command 
+line which invoked Octave.
+
+ at example
+ at group
+printf ("%s", program_name ());
+arg_list = argv ();
+for i = 1:nargin
+  printf (" %s", arg_list@{i@});
+endfor
+printf ("\n");
+ at end group
+ at end example
+
+ at noindent
+ at xref{Indexing Cell Arrays}, for an explanation of how to retrieve objects
+from cell arrays, and @ref{Defining Functions}, for information about the 
+variable @code{nargin}.
+
+ at node Startup Files
+ at subsection Startup Files
+ at cindex initialization
+ at cindex startup
+
+When Octave starts, it looks for commands to execute from the files in
+the following list.  These files may contain any valid Octave commands,
+including function definitions.
+
+ at cindex startup files
+
+ at table @code
+ at item @var{octave-home}/share/octave/site/m/startup/octaverc
+ at cindex site startup file
+where @var{octave-home} is the directory in which Octave is installed
+(the default is @file{@value{OCTAVEHOME}}).
+This file is provided so that changes to the default Octave environment 
+can be made globally for all users at your site for all versions of Octave
+you have installed.  Care should be taken when making changes to this file 
+since all users of Octave at your site will be affected.  The default file 
+may be overridden by the environment variable @w{@code{OCTAVE_SITE_INITFILE}}.
+
+ at item @var{octave-home}/share/octave/@var{version}/m/startup/octaverc
+ at cindex version startup file
+where @var{octave-home} is the directory in which Octave is
+installed (the default is @file{@value{OCTAVEHOME}}), and @var{version}
+is the version number of Octave.  This file is provided so that changes
+to the default Octave environment can be made globally for all users of
+a particular version of Octave.  Care should be taken when making
+changes to this file since all users of Octave at your site will be
+affected.  The default file may be overridden by the environment variable
+ at w{@code{OCTAVE_VERSION_INITFILE}}.
+
+ at item ~/.octaverc
+ at cindex personal startup file
+ at cindex @code{~/.octaverc}
+This file is used to make personal changes to the default 
+Octave environment.
+
+ at item .octaverc
+ at cindex project startup file
+ at cindex @code{.octaverc}
+This file can be used to make changes to the default Octave environment
+for a particular project.  Octave searches for this file in the current
+directory after it reads @file{~/.octaverc}.  Any use of the @code{cd}
+command in the @file{~/.octaverc} file will affect the directory where
+Octave searches for @file{.octaverc}.
+
+If you start Octave in your home directory, commands from the file
+ at file{~/.octaverc} will only be executed once.
+ at end table
+
+A message will be displayed as each of the startup files is read if you
+invoke Octave with the @code{--verbose} option but without the
+ at code{--silent} option.
+
+ at node Quitting Octave
+ at section Quitting Octave
+ at cindex exiting octave
+ at cindex quitting octave
+
+ at c toplev.cc
+ at anchor{doc-quit}
+ at deftypefn {Built-in Function} {} exit (@var{status})
+ at deftypefnx {Built-in Function} {} quit (@var{status})
+Exit the current Octave session.  If the optional integer value
+ at var{status} is supplied, pass that value to the operating system as the
+Octave's exit status.  The default value is zero.
+ at end deftypefn
+
+
+ at c toplev.cc
+ at anchor{doc-atexit}
+ at deftypefn {Built-in Function} {} atexit (@var{fcn})
+ at deftypefnx {Built-in Function} {} atexit (@var{fcn}, @var{flag})
+Register a function to be called when Octave exits.  For example,
+
+ at example
+ at group
+function last_words ()
+  disp ("Bye bye");
+endfunction
+atexit ("last_words");
+ at end group
+ at end example
+
+ at noindent
+will print the message "Bye bye" when Octave exits.
+
+The additional argument @var{flag} will register or unregister
+ at var{fcn} from the list of functions to be called when Octave
+exits.  If @var{flag} is true, the function is registered, and if
+ at var{flag} is false, it is unregistered.  For example,
+after registering the function @code{last_words} above,
+
+ at example
+atexit ("last_words", false);
+ at end example
+
+ at noindent
+will remove the function from the list and Octave will not call
+ at code{last_words} when it exits.
+
+Note that @code{atexit} only removes the first occurrence of a function
+from the list, so if a function was placed in the list multiple
+times with @code{atexit}, it must also be removed from the list
+multiple times.
+ at end deftypefn
+
+
+ at node Getting Help
+ at section Commands for Getting Help
+ at cindex on-line help
+ at cindex help, on-line
+
+The entire text of this manual is available from the Octave prompt
+via the command @kbd{doc}.  In addition, the documentation for
+individual user-written functions and variables is also available via
+the @kbd{help} command.  This section describes the commands used for
+reading the manual and the documentation strings for user-supplied
+functions and variables.  @xref{Function Files}, for more information
+about how to document the functions you write.
+
+ at c ./help/help.m
+ at anchor{doc-help}
+ at deftypefn {Command} help @var{name}
+Display the help text for @var{name}.
+If invoked without any arguments, @code{help} prints a list
+of all the available operators and functions.
+
+For example, the command @kbd{help help} prints a short message
+describing the @code{help} command.
+
+The help command can give you information about operators, but not the
+comma and semicolons that are used as command separators.  To get help
+for those, you must type @kbd{help comma} or @kbd{help semicolon}.
+ at seealso{@ref{doc-doc,,doc}, @ref{doc-lookfor,,lookfor}, @ref{doc-which,,which}}
+ at end deftypefn
+
+
+ at c ./help/doc.m
+ at anchor{doc-doc}
+ at deftypefn {Command} doc @var{function_name}
+Display documentation for the function @var{function_name}
+directly from an on-line version of
+the printed manual, using the GNU Info browser.  If invoked without
+any arguments, the manual is shown from the beginning.
+
+For example, the command @kbd{doc rand} starts the GNU Info browser
+at the @code{rand} node in the on-line version of the manual.
+
+Once the GNU Info browser is running, help for using it is available
+using the command @kbd{C-h}.
+ at seealso{@ref{doc-help,,help}}
+ at end deftypefn
+
+
+ at c ./help/lookfor.m
+ at anchor{doc-lookfor}
+ at deftypefn {Command} lookfor @var{str}
+ at deftypefnx {Command} lookfor -all @var{str}
+ at deftypefnx {Function} {[@var{func}, @var{helpstring}] =} lookfor (@var{str})
+ at deftypefnx {Function} {[@var{func}, @var{helpstring}] =} lookfor ('-all', @var{str})
+Search for the string @var{str} in all functions found in the current 
+function search path.  By default, @code{lookfor} searches for @var{str}
+in the first sentence of the help string of each function found.  The entire
+help text of each function can be searched if the '-all' argument is 
+supplied.  All searches are case insensitive.
+
+Called with no output arguments, @code{lookfor} prints the list of 
+matching functions to the terminal.  Otherwise, the output arguments 
+ at var{func} and @var{helpstring} define the matching functions and the 
+first sentence of each of their help strings.
+
+The ability of @code{lookfor} to correctly identify the first
+sentence of the help text is dependent on the format of the
+function's help.  All Octave core functions are correctly
+formatted, but the same can not be guaranteed for external packages and
+user-supplied functions.  Therefore, the use of the '-all' argument may 
+be necessary to find related functions that are not a part of Octave.
+ at seealso{@ref{doc-help,,help}, @ref{doc-doc,,doc}, @ref{doc-which,,which}}
+ at end deftypefn
+
+
+To see what is new in the current release of Octave, use the @code{news}
+function.
+
+ at c ./miscellaneous/news.m
+ at anchor{doc-news}
+ at deftypefn {Function File} {} news ()
+Display the current NEWS file for Octave.
+ at end deftypefn
+
+
+ at c ./miscellaneous/info.m
+ at anchor{doc-info}
+ at deftypefn {Function File} {} info ()
+Display contact information for the GNU Octave community.
+ at end deftypefn
+
+
+ at c toplev.cc
+ at anchor{doc-warranty}
+ at deftypefn {Built-in Function} {} warranty ()
+Describe the conditions for copying and distributing Octave.
+ at end deftypefn
+
+
+The following functions can be used to change which programs are used
+for displaying the documentation, and where the documentation can be
+found.
+
+ at c help.cc
+ at anchor{doc-info_file}
+ at deftypefn {Built-in Function} {@var{val} =} info_file ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} info_file (@var{new_val})
+Query or set the internal variable that specifies the name of the
+Octave info file.  The default value is
+ at file{@var{octave-home}/info/octave.info}, in
+which @var{octave-home} is the root directory of the Octave installation.
+The default value may be overridden by the environment variable
+ at w{@code{OCTAVE_INFO_FILE}}, or the command line argument
+ at samp{--info-file NAME}.
+ at seealso{@ref{doc-info_program,,info_program}, @ref{doc-doc,,doc}, @ref{doc-help,,help}, @ref{doc-makeinfo_program,,makeinfo_program}}
+ at end deftypefn
+
+
+ at c help.cc
+ at anchor{doc-info_program}
+ at deftypefn {Built-in Function} {@var{val} =} info_program ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} info_program (@var{new_val})
+Query or set the internal variable that specifies the name of the
+info program to run.  The default value is
+ at file{@var{octave-home}/libexec/octave/@var{version}/exec/@var{arch}/info}
+in which @var{octave-home} is the root directory of the Octave installation,
+ at var{version} is the Octave version number, and @var{arch}
+is the system type (for example, @code{i686-pc-linux-gnu}).  The
+default value may be overridden by the environment variable
+ at w{@code{OCTAVE_INFO_PROGRAM}}, or the command line argument
+ at samp{--info-program NAME}.
+ at seealso{@ref{doc-info_file,,info_file}, @ref{doc-doc,,doc}, @ref{doc-help,,help}, @ref{doc-makeinfo_program,,makeinfo_program}}
+ at end deftypefn
+
+
+ at c help.cc
+ at anchor{doc-makeinfo_program}
+ at deftypefn {Built-in Function} {@var{val} =} makeinfo_program ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} makeinfo_program (@var{new_val})
+Query or set the internal variable that specifies the name of the
+program that Octave runs to format help text containing
+Texinfo markup commands.  The default value is @code{makeinfo}.
+ at seealso{@ref{doc-info_file,,info_file}, @ref{doc-info_program,,info_program}, @ref{doc-doc,,doc}, @ref{doc-help,,help}}
+ at end deftypefn
+
+
+ at c help.cc
+ at anchor{doc-doc_cache_file}
+ at deftypefn {Built-in Function} {@var{val} =} doc_cache_file ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} doc_cache_file (@var{new_val})
+Query or set the internal variable that specifies the name of the
+Octave documentation cache file.  A cache file significantly improves
+the performance of the @code{lookfor} command.  The default value is 
+ at file{@var{octave-home}/share/octave/@var{version}/etc/doc-cache},
+in which @var{octave-home} is the root directory of the Octave installation,
+and @var{version} is the Octave version number.
+The default value may be overridden by the environment variable
+ at w{@code{OCTAVE_DOC_CACHE_FILE}}, or the command line argument
+ at samp{--doc-cache-file NAME}.
+ at seealso{@ref{doc-lookfor,,lookfor}, @ref{doc-info_program,,info_program}, @ref{doc-doc,,doc}, @ref{doc-help,,help}, @ref{doc-makeinfo_program,,makeinfo_program}}
+ at end deftypefn
+
+
+ at c help.cc
+ at anchor{doc-suppress_verbose_help_message}
+ at deftypefn {Built-in Function} {@var{val} =} suppress_verbose_help_message ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} suppress_verbose_help_message (@var{new_val})
+Query or set the internal variable that controls whether Octave
+will add additional help information to the end of the output from
+the @code{help} command and usage messages for built-in commands.
+ at end deftypefn
+
+
+ at node Command Line Editing
+ at section Command Line Editing
+ at cindex command-line editing
+ at cindex editing the command line
+
+Octave uses the GNU Readline library to provide an extensive set of
+command-line editing and history features.  Only the most common
+features are described in this manual.  In addition, all of the editing
+functions can be bound to different key strokes at the user's discretion.  
+This manual assumes no changes from the default Emacs bindings.  See the GNU 
+Readline Library manual for more information on customizing Readline and 
+for a complete feature list.
+
+To insert printing characters (letters, digits, symbols, etc.), simply
+type the character.  Octave will insert the character at the cursor and
+advance the cursor forward.
+
+Many of the command-line editing functions operate using control
+characters.  For example, the character @kbd{Control-a} moves the cursor
+to the beginning of the line.  To type @kbd{C-a}, hold down @key{CTRL}
+and then press @key{a}.  In the following sections, control characters
+such as @kbd{Control-a} are written as @kbd{C-a}.
+
+Another set of command-line editing functions use Meta characters.  To 
+type @kbd{M-u}, hold down the @key{META} key and press @key{u}.  Depending
+on the keyboard, the @key{META} key may be labeled @key{ALT} or
+even @key{WINDOWS}.  If your terminal does not have a @key{META} key, you
+can still type Meta characters using two-character sequences starting
+with @kbd{ESC}.  Thus, to enter @kbd{M-u}, you would type
+ at key{ESC} @key{u}.  The @kbd{ESC} character sequences are also allowed on
+terminals with real Meta keys.  In the following sections, Meta
+characters such as @kbd{Meta-u} are written as @kbd{M-u}.
+
+
+ at menu
+* Cursor Motion::               
+* Killing and Yanking::         
+* Commands For Text::           
+* Commands For Completion::     
+* Commands For History::        
+* Customizing readline::        
+* Customizing the Prompt::      
+* Diary and Echo Commands::     
+ at end menu
+
+ at node Cursor Motion
+ at subsection Cursor Motion
+
+The following commands allow you to position the cursor.
+
+ at table @kbd
+ at item C-b
+Move back one character.
+
+ at item C-f
+Move forward one character.
+
+ at item @key{DEL}
+Delete the character to the left of the cursor.
+
+ at item C-d
+Delete the character underneath the cursor.
+
+ at item M-f
+Move forward a word.
+
+ at item M-b
+Move backward a word.
+
+ at item C-a
+Move to the start of the line.
+
+ at item C-e
+Move to the end of the line.
+
+ at item C-l
+Clear the screen, reprinting the current line at the top.
+
+ at item C-_
+ at itemx C-/
+Undo the last action.  You can undo all the way back to an empty line.
+
+ at item M-r
+Undo all changes made to this line.  This is like typing the `undo'
+command enough times to get back to the beginning.
+ at end table
+
+The above table describes the most basic possible keystrokes that you need
+in order to do editing of the input line.  On most terminals, you can
+also use the left and right arrow keys in place of @kbd{C-f} and @kbd{C-b}
+to move forward and backward.
+
+Notice how @kbd{C-f} moves forward a character, while @kbd{M-f} moves
+forward a word.  It is a loose convention that control keystrokes
+operate on characters while meta keystrokes operate on words.
+
+ at cindex clearing the screen
+
+The function @code{clc} will allow you to clear the screen from within
+Octave programs.
+
+ at c sysdep.cc
+ at anchor{doc-clc}
+ at deftypefn {Built-in Function} {} clc ()
+ at deftypefnx {Built-in Function} {} home ()
+Clear the terminal screen and move the cursor to the upper left corner.
+ at end deftypefn
+
+
+ at node Killing and Yanking
+ at subsection Killing and Yanking
+
+ at dfn{Killing} text means to delete the text from the line, but to save
+it away for later use, usually by @dfn{yanking} it back into the line.
+If the description for a command says that it `kills' text, then you can
+be sure that you can get the text back in a different (or the same)
+place later.
+
+Here is the list of commands for killing text.
+
+ at table @kbd
+ at item C-k
+Kill the text from the current cursor position to the end of the line.
+
+ at item M-d
+Kill from the cursor to the end of the current word, or if between
+words, to the end of the next word.
+
+ at item M- at key{DEL}
+Kill from the cursor to the start of the previous word, or if between
+words, to the start of the previous word. 
+
+ at item C-w
+Kill from the cursor to the previous whitespace.  This is different than
+ at kbd{M- at key{DEL}} because the word boundaries differ.
+ at end table
+
+And, here is how to @dfn{yank} the text back into the line.  Yanking
+means to copy the most-recently-killed text from the kill buffer.
+
+ at table @kbd
+ at item C-y
+Yank the most recently killed text back into the buffer at the cursor.
+
+ at item M-y
+Rotate the kill-ring, and yank the new top.  You can only do this if
+the prior command is @kbd{C-y} or @kbd{M-y}.
+ at end table
+
+When you use a kill command, the text is saved in a @dfn{kill-ring}.
+Any number of consecutive kills save all of the killed text together, so
+that when you yank it back, you get it in one clean sweep.  The kill
+ring is not line specific; the text that you killed on a previously
+typed line is available to be yanked back later, when you are typing
+another line.
+
+ at node Commands For Text
+ at subsection Commands For Changing Text
+
+The following commands can be used for entering characters that would
+otherwise have a special meaning (e.g., @key{TAB}, @kbd{C-q}, etc.), or
+for quickly correcting typing mistakes.
+
+ at table @kbd
+ at item C-q
+ at itemx C-v
+Add the next character that you type to the line verbatim.  This is
+how to insert things like @kbd{C-q} for example.
+
+ at item M- at key{TAB}
+Insert a tab character.
+
+ at item C-t
+Drag the character before the cursor forward over the character at the
+cursor, also moving the cursor forward.  If the cursor is at the end of
+the line, then transpose the two characters before it.
+
+ at item M-t
+Drag the word behind the cursor past the word in front of the cursor
+moving the cursor over that word as well.
+
+ at item M-u
+Uppercase the characters following the cursor to the end of the current
+(or following) word, moving the cursor to the end of the word.
+
+ at item M-l
+Lowercase the characters following the cursor to the end of the current
+(or following) word, moving the cursor to the end of the word.
+
+ at item M-c
+Uppercase the character following the cursor (or the beginning of the
+next word if the cursor is between words), moving the cursor to the end
+of the word.
+ at end table
+
+ at node Commands For Completion
+ at subsection Letting Readline Type For You
+ at cindex command completion
+
+The following commands allow Octave to complete command and variable
+names for you.
+
+ at table @kbd
+ at item @key{TAB}
+Attempt to do completion on the text before the cursor.  Octave can
+complete the names of commands and variables.
+
+ at item M-?
+List the possible completions of the text before the cursor.
+ at end table
+
+ at c input.cc
+ at anchor{doc-completion_append_char}
+ at deftypefn {Built-in Function} {@var{val} =} completion_append_char ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} completion_append_char (@var{new_val})
+Query or set the internal character variable that is appended to
+successful command-line completion attempts.  The default
+value is @code{" "} (a single space).
+ at end deftypefn
+
+
+ at c input.cc
+ at anchor{doc-completion_matches}
+ at deftypefn {Built-in Function} {} completion_matches (@var{hint})
+Generate possible completions given @var{hint}.
+
+This function is provided for the benefit of programs like Emacs which
+might be controlling Octave and handling user input.  The current
+command number is not incremented when this function is called.  This is
+a feature, not a bug.
+ at end deftypefn
+
+
+ at node Commands For History
+ at subsection Commands For Manipulating The History
+ at cindex command history
+ at cindex input history
+ at cindex history of commands
+
+Octave normally keeps track of the commands you type so that you can
+recall previous commands to edit or execute them again.  When you exit
+Octave, the most recent commands you have typed, up to the number
+specified by the variable @code{history_size}, are saved in a file.
+When Octave starts, it loads an initial list of commands from the file
+named by the variable @code{history_file}.
+
+Here are the commands for simple browsing and searching the history
+list.
+
+ at table @kbd
+ at item @key{LFD}
+ at itemx @key{RET}
+Accept the current line regardless of where the cursor is.  If the line is
+non-empty, add it to the history list.  If the line was a history
+line, then restore the history line to its original state.
+
+ at item C-p
+Move `up' through the history list.
+
+ at item C-n
+Move `down' through the history list.
+
+ at item M-<
+Move to the first line in the history.
+
+ at item M->
+Move to the end of the input history, i.e., the line you are entering!
+
+ at item C-r
+Search backward starting at the current line and moving `up' through
+the history as necessary.  This is an incremental search.
+
+ at item C-s
+Search forward starting at the current line and moving `down' through
+the history as necessary.
+ at end table
+
+On most terminals, you can also use the up and down arrow keys in place 
+of @kbd{C-p} and @kbd{C-n} to move through the history list.
+
+In addition to the keyboard commands for moving through the history
+list, Octave provides three functions for viewing, editing, and
+re-running chunks of commands from the history list.
+
+ at c oct-hist.cc
+ at anchor{doc-history}
+ at deffn {Command} history options
+If invoked with no arguments, @code{history} displays a list of commands
+that you have executed.  Valid options are:
+
+ at table @code
+ at item -w @var{file}
+Write the current history to the file @var{file}.  If the name is
+omitted, use the default history file (normally @file{~/.octave_hist}).
+
+ at item -r @var{file}
+Read the file @var{file}, replacing the current history list with its
+contents.  If the name is omitted, use the default history file
+(normally @file{~/.octave_hist}).
+
+ at item @var{n}
+Display only the most recent @var{n} lines of history.
+
+ at item -q
+Don't number the displayed lines of history.  This is useful for cutting
+and pasting commands using the X Window System.
+ at end table
+
+For example, to display the five most recent commands that you have
+typed without displaying line numbers, use the command
+ at kbd{history -q 5}.
+ at end deffn
+
+
+ at c oct-hist.cc
+ at anchor{doc-edit_history}
+ at deffn {Command} edit_history [@var{first}] [@var{last}]
+If invoked with no arguments, @code{edit_history} allows you to edit the
+history list using the editor named by the variable @w{@code{EDITOR}}.  The
+commands to be edited are first copied to a temporary file.  When you
+exit the editor, Octave executes the commands that remain in the file.
+It is often more convenient to use @code{edit_history} to define functions 
+rather than attempting to enter them directly on the command line.
+By default, the block of commands is executed as soon as you exit the
+editor.  To avoid executing any commands, simply delete all the lines
+from the buffer before exiting the editor.
+
+The @code{edit_history} command takes two optional arguments specifying
+the history numbers of first and last commands to edit.  For example,
+the command
+
+ at example
+edit_history 13
+ at end example
+
+ at noindent
+extracts all the commands from the 13th through the last in the history
+list.  The command
+
+ at example
+edit_history 13 169
+ at end example
+
+ at noindent
+only extracts commands 13 through 169.  Specifying a larger number for
+the first command than the last command reverses the list of commands
+before placing them in the buffer to be edited.  If both arguments are
+omitted, the previous command in the history list is used.
+ at seealso{@ref{doc-run_history,,run_history}}
+ at end deffn
+
+
+ at c oct-hist.cc
+ at anchor{doc-run_history}
+ at deffn {Command} run_history [@var{first}] [@var{last}]
+Similar to @code{edit_history}, except that the editor is not invoked,
+and the commands are simply executed as they appear in the history list.
+ at seealso{@ref{doc-edit_history,,edit_history}}
+ at end deffn
+
+
+ at noindent
+Octave also allows you customize the details of when, where, and how history
+is saved.
+
+ at c oct-hist.cc
+ at anchor{doc-saving_history}
+ at deftypefn {Built-in Function} {@var{val} =} saving_history ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} saving_history (@var{new_val})
+Query or set the internal variable that controls whether commands entered
+on the command line are saved in the history file.
+ at seealso{@ref{doc-history_file,,history_file}, @ref{doc-history_size,,history_size}, @ref{doc-history_timestamp_format_string,,history_timestamp_format_string}}
+ at end deftypefn
+
+
+ at c oct-hist.cc
+ at anchor{doc-history_file}
+ at deftypefn {Built-in Function} {@var{val} =} history_file ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_file (@var{new_val})
+Query or set the internal variable that specifies the name of the
+file used to store command history.  The default value is
+ at file{~/.octave_hist}, but may be overridden by the environment
+variable @w{@code{OCTAVE_HISTFILE}}.
+ at seealso{@ref{doc-history_size,,history_size}, @ref{doc-saving_history,,saving_history}, @ref{doc-history_timestamp_format_string,,history_timestamp_format_string}}
+ at end deftypefn
+
+
+ at c oct-hist.cc
+ at anchor{doc-history_size}
+ at deftypefn {Built-in Function} {@var{val} =} history_size ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_size (@var{new_val})
+Query or set the internal variable that specifies how many entries
+to store in the history file.  The default value is @code{1024},
+but may be overridden by the environment variable @w{@code{OCTAVE_HISTSIZE}}.
+ at seealso{@ref{doc-history_file,,history_file}, @ref{doc-history_timestamp_format_string,,history_timestamp_format_string}, @ref{doc-saving_history,,saving_history}}
+ at end deftypefn
+
+
+ at c oct-hist.cc
+ at anchor{doc-history_timestamp_format_string}
+ at deftypefn {Built-in Function} {@var{val} =} history_timestamp_format_string ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_timestamp_format_string (@var{new_val})
+Query or set the internal variable that specifies the format string
+for the comment line that is written to the history file when Octave
+exits.  The format string is passed to @code{strftime}.  The default
+value is
+
+ at example
+"# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>"
+ at end example
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-history_file,,history_file}, @ref{doc-history_size,,history_size}, @ref{doc-saving_history,,saving_history}}
+ at end deftypefn
+
+
+ at c defaults.cc
+ at anchor{doc-EDITOR}
+ at deftypefn {Built-in Function} {@var{val} =} EDITOR ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} EDITOR (@var{new_val})
+Query or set the internal variable that specifies the editor to
+use with the @code{edit_history} command.  The default value is taken from
+the environment variable @w{@code{EDITOR}} when Octave starts.  If the
+environment variable is not initialized, @w{@code{EDITOR}} will be set to
+ at code{"emacs"}.
+ at seealso{@ref{doc-edit_history,,edit_history}}
+ at end deftypefn
+
+
+ at node Customizing readline
+ at subsection Customizing @code{readline}
+ at cindex @file{~/.inputrc}
+ at cindex customizing @code{readline}
+ at cindex @code{readline} customization
+
+Octave uses the GNU Readline library for command-line editing and
+history features.  Readline is very flexible and can be modified through
+a configuration file of commands (See the GNU Readline library for the
+exact command syntax).  The default configuration file is normally
+ at file{~/.inputrc}.
+
+Octave provides two commands for initializing Readline and thereby changing
+the command line behavior.
+
+ at c input.cc
+ at anchor{doc-read_readline_init_file}
+ at deftypefn {Built-in Function} {} read_readline_init_file (@var{file})
+Read the readline library initialization file @var{file}.  If
+ at var{file} is omitted, read the default initialization file (normally
+ at file{~/.inputrc}).
+
+ at xref{Readline Init File, , , readline, GNU Readline Library},
+for details.
+ at end deftypefn
+
+
+ at c input.cc
+ at anchor{doc-re_read_readline_init_file}
+ at deftypefn {Built-in Function} {} re_read_readline_init_file ()
+Re-read the last readline library initialization file that was read.
+ at xref{Readline Init File, , , readline, GNU Readline Library},
+for details.
+ at end deftypefn
+
+
+ at node Customizing the Prompt
+ at subsection Customizing the Prompt
+ at cindex prompt customization
+ at cindex customizing the prompt
+
+The following variables are available for customizing the appearance of
+the command-line prompts.  Octave allows the prompt to be customized by
+inserting a number of backslash-escaped special characters that are
+decoded as follows:
+
+ at table @samp
+ at item \t
+The time.
+
+ at item \d
+The date.
+
+ at item \n
+Begins a new line by printing the equivalent of a carriage return
+followed by a line feed.
+
+ at item \s
+The name of the program (usually just @samp{octave}).
+
+ at item \w
+The current working directory.
+
+ at item \W
+The basename of the current working directory.
+
+ at item \u
+The username of the current user.
+
+ at item \h
+The hostname, up to the first `.'.
+
+ at item \H
+The hostname.
+
+ at item \#
+The command number of this command, counting from when Octave starts.
+
+ at item \!
+The history number of this command.  This differs from @samp{\#} by the
+number of commands in the history list when Octave starts.
+
+ at item \$
+If the effective UID is 0, a @samp{#}, otherwise a @samp{$}.
+
+ at item \nnn
+The character whose character code in octal is @var{nnn}.
+
+ at item \\
+A backslash.
+ at end table
+
+ at c input.cc
+ at anchor{doc-PS1}
+ at deftypefn {Built-in Function} {@var{val} =} PS1 ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS1 (@var{new_val})
+Query or set the primary prompt string.  When executing interactively,
+Octave displays the primary prompt when it is ready to read a command.
+
+The default value of the primary prompt string is @code{"\s:\#> "}.
+To change it, use a command like
+
+ at example
+octave:13> PS1 ("\\u@@\\H> ")
+ at end example
+
+ at noindent
+which will result in the prompt @samp{boris@@kremvax> } for the user
+ at samp{boris} logged in on the host @samp{kremvax.kgb.su}.  Note that two
+backslashes are required to enter a backslash into a double-quoted
+character string.
+ at xref{Strings}.
+ at seealso{@ref{doc-PS2,,PS2}, @ref{doc-PS4,,PS4}}
+ at end deftypefn
+
+
+ at c input.cc
+ at anchor{doc-PS2}
+ at deftypefn {Built-in Function} {@var{val} =} PS2 ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS2 (@var{new_val})
+Query or set the secondary prompt string.  The secondary prompt is
+printed when Octave is expecting additional input to complete a
+command.  For example, if you are typing a @code{for} loop that spans several
+lines, Octave will print the secondary prompt at the beginning of
+each line after the first.  The default value of the secondary prompt
+string is @code{"> "}.
+ at seealso{@ref{doc-PS1,,PS1}, @ref{doc-PS4,,PS4}}
+ at end deftypefn
+
+
+ at c input.cc
+ at anchor{doc-PS4}
+ at deftypefn {Built-in Function} {@var{val} =} PS4 ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS4 (@var{new_val})
+Query or set the character string used to prefix output produced
+when echoing commands is enabled.
+The default value is @code{"+ "}.
+ at xref{Diary and Echo Commands}, for a description of echoing commands.
+ at seealso{@ref{doc-echo,,echo}, @ref{doc-echo_executing_commands,,echo_executing_commands}, @ref{doc-PS1,,PS1}, @ref{doc-PS2,,PS2}}
+ at end deftypefn
+
+
+ at node Diary and Echo Commands
+ at subsection Diary and Echo Commands
+ at cindex diary of commands and output
+ at cindex command and output logs
+ at cindex logging commands and output
+ at cindex echoing executing commands
+ at cindex command echoing
+
+Octave's diary feature allows you to keep a log of all or part of an
+interactive session by recording the input you type and the output that
+Octave produces in a separate file.
+
+ at c pager.cc
+ at anchor{doc-diary}
+ at deffn {Command} diary options
+Record a list of all commands @emph{and} the output they produce, mixed
+together just as you see them on your terminal.  Valid options are:
+
+ at table @code
+ at item on
+Start recording your session in a file called @file{diary} in your
+current working directory.
+
+ at item off
+Stop recording your session in the diary file.
+
+ at item @var{file}
+Record your session in the file named @var{file}.
+ at end table
+
+With no arguments, @code{diary} toggles the current diary state.
+ at end deffn
+
+
+Sometimes it is useful to see the commands in a function or script as
+they are being evaluated.  This can be especially helpful for debugging
+some kinds of problems.
+
+ at c input.cc
+ at anchor{doc-echo}
+ at deffn {Command} echo options
+Control whether commands are displayed as they are executed.  Valid
+options are:
+
+ at table @code
+ at item on
+Enable echoing of commands as they are executed in script files.
+
+ at item off
+Disable echoing of commands as they are executed in script files.
+
+ at item on all
+Enable echoing of commands as they are executed in script files and
+functions.
+
+ at item off all
+Disable echoing of commands as they are executed in script files and
+functions.
+ at end table
+
+ at noindent
+With no arguments, @code{echo} toggles the current echo state.
+ at end deffn
+
+
+ at c input.cc
+ at anchor{doc-echo_executing_commands}
+ at deftypefn {Built-in Function} {@var{val} =} echo_executing_commands ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} echo_executing_commands (@var{new_val})
+Query or set the internal variable that controls the echo state.
+It may be the sum of the following values:
+
+ at table @asis
+ at item 1
+Echo commands read from script files.
+
+ at item 2
+Echo commands from functions.
+
+ at item 4
+Echo commands read from command line.
+ at end table
+
+More than one state can be active at once.  For example, a value of 3 is
+equivalent to the command @kbd{echo on all}.
+
+The value of @code{echo_executing_commands} may be set by the @kbd{echo}
+command or the command line option @code{--echo-commands}.
+ at end deftypefn
+
+
+ at node Errors
+ at section How Octave Reports Errors
+ at cindex error messages
+ at cindex messages, error
+
+Octave reports two kinds of errors for invalid programs.
+
+A @dfn{parse error} occurs if Octave cannot understand something you
+have typed.  For example, if you misspell a keyword,
+
+ at example
+octave:13> function y = f (x) y = x***2; endfunction
+ at end example
+
+ at noindent
+Octave will respond immediately with a message like this:
+
+ at example
+ at group
+parse error:
+
+  syntax error
+
+>>> function y = f (x) y = x***2; endfunction
+                              ^
+ at end group
+ at end example
+
+ at noindent
+For most parse errors, Octave uses a caret (@samp{^}) to mark the point
+on the line where it was unable to make sense of your input.  In this
+case, Octave generated an error message because the keyword for
+exponentiation (@code{**}) was misspelled.  It marked the error at the
+third @samp{*} because the code leading up to this was correct but the final
+ at samp{*} was not understood.
+
+Another class of error message occurs at evaluation time.  These
+errors are called @dfn{run-time errors}, or sometimes
+ at dfn{evaluation errors}, because they occur when your program is being
+ at dfn{run}, or @dfn{evaluated}.  For example, if after correcting the
+mistake in the previous function definition, you type
+
+ at example
+octave:13> f ()
+ at end example
+
+ at noindent
+Octave will respond with
+
+ at example
+ at group
+error: `x' undefined near line 1 column 24
+error: called from:
+error:   f at line 1, column 22
+ at end group
+ at end example
+
+ at noindent
+This error message has several parts, and gives quite a bit of
+information to help you locate the source of the error.  The messages
+are generated from the point of the innermost error, and provide a
+traceback of enclosing expressions and function calls.
+
+In the example above, the first line indicates that a variable named
+ at samp{x} was found to be undefined near line 1 and column 24 of some
+function or expression.  For errors occurring within functions, lines
+are counted from the beginning of the file containing the function
+definition.  For errors occurring outside of an enclosing function, 
+the line number indicates the input line number, which is usually displayed 
+in the primary prompt string.
+
+The second and third lines of the error message indicate that the error 
+occurred within the function @code{f}.  If the function @code{f} had been 
+called from within another function, for example, @code{g}, the list of 
+errors would have ended with one more line:
+
+ at example
+error:   g at line 1, column 17
+ at end example
+
+These lists of function calls make it fairly easy to trace the
+path your program took before the error occurred, and to correct the
+error before trying again.
+
+ at node Executable Octave Programs
+ at section Executable Octave Programs
+ at cindex executable scripts
+ at cindex scripts
+ at cindex batch processing
+ at cindex self contained programs
+ at cindex program, self contained
+ at cindex @samp{#!}
+
+Once you have learned Octave, you may want to write self-contained
+Octave scripts, using the @samp{#!} script mechanism.  You can do this
+on GNU systems and on many Unix systems @footnote{The @samp{#!}
+mechanism works on Unix systems derived from Berkeley Unix, System V
+Release 4, and some System V Release 3 systems.}.
+
+Self-contained Octave scripts are useful when you want to write a
+program which users can invoke without knowing that the program is
+written in the Octave language.  Octave scripts are also used for batch
+processing of data files.  Once an algorithm has been developed and tested
+in the interactive portion of Octave, it can be committed to an executable
+script and used again and again on new data files.
+
+As a trivial example of an executable Octave script, you might create a
+text file named @file{hello}, containing the following lines:
+
+ at example
+ at group
+#! @var{octave-interpreter-name} -qf
+# a sample Octave program
+printf ("Hello, world!\n");
+ at end group
+ at end example
+
+ at noindent
+(where @var{octave-interpreter-name} should be replaced with the full
+path and name of your Octave binary).  Note that this will only work if
+ at samp{#!} appears at the very beginning of the file.  After making the
+file executable (with the @code{chmod} command on Unix systems), you can
+simply type:
+
+ at example
+hello
+ at end example
+
+ at noindent
+at the shell, and the system will arrange to run Octave as if you had
+typed:
+
+ at example
+octave hello
+ at end example
+
+The line beginning with @samp{#!} lists the full path and filename of an
+interpreter to be run, and an optional initial command line argument to
+pass to that interpreter.  The operating system then runs the
+interpreter with the given argument and the full argument list of the
+executed program.  The first argument in the list is the full file name
+of the Octave executable.  The rest of the argument list will either be
+options to Octave, or data files, or both.  The @samp{-qf} options are
+usually specified in stand-alone Octave programs to prevent them from
+printing the normal startup message, and to keep them from behaving
+differently depending on the contents of a particular user's
+ at file{~/.octaverc} file.  @xref{Invoking Octave from the Command Line}.
+
+Note that some operating systems may place a limit on the number of
+characters that are recognized after @samp{#!}.  Also, the arguments 
+appearing in a @samp{#!} line are parsed differently by various 
+shells/systems.  The majority of them group all the arguments together in one 
+string and pass it to the interpreter as a single argument.  In this case, the
+following script:
+
+ at example
+ at group
+#! @var{octave-interpreter-name} -q -f # comment
+ at end group
+ at end example
+
+ at noindent
+is equivalent to typing at the command line:
+
+ at example
+ at group
+octave "-q -f # comment"
+ at end group
+ at end example
+
+ at noindent
+which will produce an error message.  Unfortunately, it is
+not possible for Octave to determine whether it has been called from the 
+command line or from a @samp{#!} script, so some care is needed when using the
+ at samp{#!} mechanism.
+
+Note that when Octave is started from an executable script, the built-in
+function @code{argv} returns a cell array containing the command line
+arguments passed to the executable Octave script, not the arguments
+passed to the Octave interpreter on the @samp{#!} line of the script.
+For example, the following program will reproduce the command line that
+was used to execute the script, not @samp{-qf}.
+
+ at example
+ at group
+#! /bin/octave -qf
+printf ("%s", program_name ());
+arg_list = argv ();
+for i = 1:nargin
+  printf (" %s", arg_list@{i@});
+endfor
+printf ("\n");
+ at end group
+ at end example
+
+ at node Comments
+ at section Comments in Octave Programs
+ at cindex comments
+ at cindex use of comments
+ at cindex documenting Octave programs
+
+A @dfn{comment} is some text that is included in a program for the sake
+of human readers, and which is NOT an executable part of the program.  
+Comments can explain what the program does, and how it works.  Nearly all
+programming languages have provisions for comments, because programs are
+typically hard to understand without them.
+
+ at menu
+* Single Line Comments::
+* Block Comments::
+* Comments and the Help System::                    
+ at end menu
+
+ at node Single Line Comments
+ at subsection Single Line Comments
+ at cindex @samp{#}
+ at cindex @samp{%}
+
+In the Octave language, a comment starts with either the sharp sign
+character, @samp{#}, or the percent symbol @samp{%} and continues to the
+end of the line.  Any text following the sharp sign or percent symbol is
+ignored by the Octave interpreter and not executed.  The following example
+shows whole line and partial line comments.
+ at example
+ at group
+function countdown
+  # Count down for main rocket engines 
+  disp(3);
+  disp(2);
+  disp(1);
+  disp("Blast Off!");  # Rocket leaves pad
+endfunction
+ at end group
+ at end example
+
+ at node Block Comments
+ at subsection Block Comments
+ at cindex block comments
+ at cindex multi-line comments
+ at cindex @samp{#@{}
+ at cindex @samp{%@{}
+
+Entire blocks of code can be commented by enclosing the code between 
+matching @samp{#@{} and @samp{#@}} or @samp{%@{} and @samp{%@}} markers.  
+For example,
+ at example
+ at group
+function quick_countdown
+  # Count down for main rocket engines 
+  disp(3);
+ #@{
+  disp(2);
+  disp(1);
+ #@}
+  disp("Blast Off!");  # Rocket leaves pad
+endfunction
+ at end group
+ at end example
+
+ at noindent
+will produce a very quick countdown from '3' to 'Blast Off' as the
+lines "@code{disp(2);}" and "@code{disp(1);}" won't be executed.
+
+ at node Comments and the Help System
+ at subsection Comments and the Help System
+ at cindex documenting functions
+ at cindex documenting user scripts
+ at cindex help, user-defined functions
+
+The @code{help} command (@pxref{Getting Help}) is able to find the first
+block of comments in a function and return those as a documentation
+string.  This means that the same commands used to get help
+on built-in functions are available for properly formatted user-defined
+functions.  For example, after defining the function @code{f} below,
+ at example
+ at group
+function xdot = f (x, t)
+
+# usage: f (x, t)
+#
+# This function defines the right-hand
+# side functions for a set of nonlinear
+# differential equations.
+
+  r = 0.25;
+  @dots{}
+endfunction
+ at end group
+ at end example
+
+the command @kbd{help f} produces the output
+
+ at example
+ at group
+ usage: f (x, t)
+
+ This function defines the right-hand
+ side functions for a set of nonlinear
+ differential equations.
+ at end group
+ at end example
+
+Although it is possible to put comment lines into keyboard-composed,
+throw-away Octave programs, it usually isn't very useful because the
+purpose of a comment is to help you or another person understand the
+program at a later time.
+
+The @code{help} parser currently only recognizes single line comments
+(@pxref{Single Line Comments}) and not block comments for the initial 
+help text. 
diff --git a/doc/interpreter/basics.txi b/doc/interpreter/basics.txi
new file mode 100644
index 0000000..492b753
--- /dev/null
+++ b/doc/interpreter/basics.txi
@@ -0,0 +1,1081 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
+ at c               2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Getting Started
+ at chapter Getting Started
+
+This chapter explains some of Octave's basic features, including how to
+start an Octave session, get help at the command prompt, edit the
+command line, and write Octave programs that can be executed as commands
+from your shell.
+
+ at menu
+* Invoking Octave from the Command Line::             
+* Quitting Octave::             
+* Getting Help::                
+* Command Line Editing::        
+* Errors::                      
+* Executable Octave Programs::  
+* Comments::                    
+ at end menu
+
+ at node Invoking Octave from the Command Line
+ at section Invoking Octave from the Command Line
+
+Normally, Octave is used interactively by running the program
+ at samp{octave} without any arguments.  Once started, Octave reads
+commands from the terminal until you tell it to exit.
+
+You can also specify the name of a file on the command line, and Octave
+will read and execute the commands from the named file and then exit
+when it is finished.
+
+You can further control how Octave starts by using the command-line
+options described in the next section, and Octave itself can remind you
+of the options available.  Type @samp{octave --help} to display all
+available options and briefly describe their use (@samp{octave -h} is a
+shorter equivalent).
+
+ at menu
+* Command Line Options::        
+* Startup Files::               
+ at end menu
+
+ at node Command Line Options
+ at subsection Command Line Options
+ at cindex Octave command options
+ at cindex command options
+ at cindex options, Octave command
+
+Here is a complete list of the command line options that Octave
+accepts.
+
+
+ at table @code
+ at item  --debug
+ at itemx -d
+ at cindex @code{--debug}
+ at cindex @code{-d}
+Enter parser debugging mode.  Using this option will cause Octave's
+parser to print a lot of information about the commands it reads, and is
+probably only useful if you are actually trying to debug the parser.
+
+ at item --doc-cache-file @var{filename}
+ at cindex @code{--doc-cache-file @var{filename}}
+Specify the name of the doc cache file to use.  The value of @var{filename}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_DOC_CACHE_FILE}} found in the environment, but not any commands
+in the system or user startup files that use the @code{doc_cache_file}
+function.
+
+ at item  --echo-commands
+ at itemx -x
+ at cindex @code{--echo-commands}
+ at cindex @code{-x}
+Echo commands as they are executed.
+
+ at item --eval @var{code}
+Evaluate @var{code} and exit when finished unless @code{--persist} is also
+specified.
+
+ at item --exec-path @var{path}
+ at cindex @code{--exec-path @var{path}}
+Specify the path to search for programs to run.  The value of @var{path}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_EXEC_PATH}} found in the environment, but not any commands
+in the system or user startup files that set the built-in variable
+ at w{@code{EXEC_PATH}}.
+
+ at item  --help
+ at itemx -h
+ at itemx -?
+ at cindex @code{--help}
+ at cindex @code{-h}
+ at cindex @code{-?}
+Print short help message and exit.
+
+ at item --image-path @var{path}
+ at cindex @code{--image-path @var{path}}
+Add path to the head of the search path for images.  The value of 
+ at var{path} specified on the command line will override any value of 
+ at w{@code{OCTAVE_IMAGE_PATH}} found in the environment, but not any commands 
+in the system or user startup files that set the built-in variable 
+ at w{@code{IMAGE_PATH}}.
+
+ at item --info-file @var{filename}
+ at cindex @code{--info-file @var{filename}}
+Specify the name of the info file to use.  The value of @var{filename}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_INFO_FILE}} found in the environment, but not any commands
+in the system or user startup files that use the @code{info_file}
+function.
+
+ at item --info-program @var{program}
+ at cindex @code{--info-program @var{program}}
+Specify the name of the info program to use.  The value of @var{program}
+specified on the command line will override any value of
+ at w{@code{OCTAVE_INFO_PROGRAM}} found in the environment, but not any
+commands in the system or user startup files that use the
+ at code{info_program} function.
+
+ at item  --interactive
+ at itemx -i
+ at cindex @code{--interactive}
+ at cindex @code{-i}
+Force interactive behavior.  This can be useful for running Octave via a
+remote shell command or inside an Emacs shell buffer.  For another way
+to run Octave within Emacs, see @ref{Emacs Octave Support}.
+
+ at item --line-editing
+ at cindex @code{--line-editing}
+Force readline use for command-line editing.
+
+ at item  --no-history
+ at itemx -H
+ at cindex @code{--no-history}
+ at cindex @code{-H}
+Disable recording of command-line history.
+
+ at item --no-init-file
+ at cindex @code{--no-init-file}
+Don't read the initialization files @file{~/.octaverc} and @file{.octaverc}.
+
+ at item --no-init-path
+ at cindex @code{--no-init-path}
+Don't initialize the search path for function files to include default 
+locations.
+
+ at item --no-line-editing
+ at cindex @code{--no-line-editing}
+Disable command-line editing.
+
+ at item --no-site-file
+ at cindex @code{--no-site-file}
+Don't read the site-wide @file{octaverc} initialization files.
+
+ at item  --norc
+ at itemx -f
+ at cindex @code{--norc}
+ at cindex @code{-f}
+Don't read any of the system or user initialization files at startup.
+This is equivalent to using both of the options @code{--no-init-file}
+and @code{--no-site-file}.
+
+ at item  --path @var{path}
+ at itemx -p @var{path}
+ at cindex @code{--path @var{path}}
+ at cindex @code{-p @var{path}}
+Add path to the head of the search path for function files.  The 
+value of @var{path} specified on the command line will override any value
+of @w{@code{OCTAVE_PATH}} found in the environment, but not any commands in the
+system or user startup files that set the internal load path through one
+of the path functions.
+
+ at item --persist
+ at cindex @code{--persist}
+Go to interactive mode after @code{--eval} or reading from a file
+named on the command line.
+
+ at item  --silent
+ at itemx --quiet
+ at itemx -q
+ at cindex @code{--silent}
+ at cindex @code{--quiet}
+ at cindex @code{-q}
+Don't print the usual greeting and version message at startup.
+
+ at item  --traditional
+ at itemx --braindead
+ at cindex @code{--traditional}
+ at cindex @code{--braindead}
+For compatibility with @sc{matlab}, set initial values for
+user preferences to the following values
+
+ at example
+ at group
+PS1                     = ">> "
+PS2                     = ""
+beep_on_error           = true
+confirm_recursive_rmdir = false
+crash_dumps_octave_core = false
+default_save_options    = "-mat-binary"
+fixed_point_format      = true
+history_timestamp_format_string
+                        = "%%-- %D %I:%M %p --%%"
+page_screen_output      = false
+print_empty_dimensions  = false
+ at end group
+ at end example
+
+ at noindent
+and disable the following warnings
+ at example
+ at group
+Octave:fopen-file-in-path
+Octave:function-name-clash
+Octave:load-file-in-path
+ at end group
+ at end example
+
+ at item  --verbose
+ at itemx -V
+ at cindex @code{--verbose}
+ at cindex @code{-V}
+Turn on verbose output.
+
+ at item  --version
+ at itemx -v
+ at cindex @code{--version}
+ at cindex @code{-v}
+Print the program version number and exit.
+
+ at item @var{file}
+Execute commands from @var{file}.  Exit when done unless
+ at code{--persist} is also specified.
+ at end table
+
+Octave also includes several functions which return information 
+about the command line, including the number of arguments and all of the
+options.
+
+ at DOCSTRING(argv)
+
+ at DOCSTRING(program_name)
+
+ at DOCSTRING(program_invocation_name)
+
+Here is an example of using these functions to reproduce the command 
+line which invoked Octave.
+
+ at example
+ at group
+printf ("%s", program_name ());
+arg_list = argv ();
+for i = 1:nargin
+  printf (" %s", arg_list@{i@});
+endfor
+printf ("\n");
+ at end group
+ at end example
+
+ at noindent
+ at xref{Indexing Cell Arrays}, for an explanation of how to retrieve objects
+from cell arrays, and @ref{Defining Functions}, for information about the 
+variable @code{nargin}.
+
+ at node Startup Files
+ at subsection Startup Files
+ at cindex initialization
+ at cindex startup
+
+When Octave starts, it looks for commands to execute from the files in
+the following list.  These files may contain any valid Octave commands,
+including function definitions.
+
+ at cindex startup files
+
+ at table @code
+ at item @var{octave-home}/share/octave/site/m/startup/octaverc
+ at cindex site startup file
+where @var{octave-home} is the directory in which Octave is installed
+(the default is @file{@value{OCTAVEHOME}}).
+This file is provided so that changes to the default Octave environment 
+can be made globally for all users at your site for all versions of Octave
+you have installed.  Care should be taken when making changes to this file 
+since all users of Octave at your site will be affected.  The default file 
+may be overridden by the environment variable @w{@code{OCTAVE_SITE_INITFILE}}.
+
+ at item @var{octave-home}/share/octave/@var{version}/m/startup/octaverc
+ at cindex version startup file
+where @var{octave-home} is the directory in which Octave is
+installed (the default is @file{@value{OCTAVEHOME}}), and @var{version}
+is the version number of Octave.  This file is provided so that changes
+to the default Octave environment can be made globally for all users of
+a particular version of Octave.  Care should be taken when making
+changes to this file since all users of Octave at your site will be
+affected.  The default file may be overridden by the environment variable
+ at w{@code{OCTAVE_VERSION_INITFILE}}.
+
+ at item ~/.octaverc
+ at cindex personal startup file
+ at cindex @code{~/.octaverc}
+This file is used to make personal changes to the default 
+Octave environment.
+
+ at item .octaverc
+ at cindex project startup file
+ at cindex @code{.octaverc}
+This file can be used to make changes to the default Octave environment
+for a particular project.  Octave searches for this file in the current
+directory after it reads @file{~/.octaverc}.  Any use of the @code{cd}
+command in the @file{~/.octaverc} file will affect the directory where
+Octave searches for @file{.octaverc}.
+
+If you start Octave in your home directory, commands from the file
+ at file{~/.octaverc} will only be executed once.
+ at end table
+
+A message will be displayed as each of the startup files is read if you
+invoke Octave with the @code{--verbose} option but without the
+ at code{--silent} option.
+
+ at node Quitting Octave
+ at section Quitting Octave
+ at cindex exiting octave
+ at cindex quitting octave
+
+ at DOCSTRING(quit)
+
+ at DOCSTRING(atexit)
+
+ at node Getting Help
+ at section Commands for Getting Help
+ at cindex on-line help
+ at cindex help, on-line
+
+The entire text of this manual is available from the Octave prompt
+via the command @kbd{doc}.  In addition, the documentation for
+individual user-written functions and variables is also available via
+the @kbd{help} command.  This section describes the commands used for
+reading the manual and the documentation strings for user-supplied
+functions and variables.  @xref{Function Files}, for more information
+about how to document the functions you write.
+
+ at DOCSTRING(help)
+
+ at DOCSTRING(doc)
+
+ at DOCSTRING(lookfor)
+
+To see what is new in the current release of Octave, use the @code{news}
+function.
+
+ at DOCSTRING(news)
+
+ at DOCSTRING(info)
+
+ at DOCSTRING(warranty)
+
+The following functions can be used to change which programs are used
+for displaying the documentation, and where the documentation can be
+found.
+
+ at DOCSTRING(info_file)
+
+ at DOCSTRING(info_program)
+
+ at DOCSTRING(makeinfo_program)
+
+ at DOCSTRING(doc_cache_file)
+
+ at DOCSTRING(suppress_verbose_help_message)
+
+ at node Command Line Editing
+ at section Command Line Editing
+ at cindex command-line editing
+ at cindex editing the command line
+
+Octave uses the GNU Readline library to provide an extensive set of
+command-line editing and history features.  Only the most common
+features are described in this manual.  In addition, all of the editing
+functions can be bound to different key strokes at the user's discretion.  
+This manual assumes no changes from the default Emacs bindings.  See the GNU 
+Readline Library manual for more information on customizing Readline and 
+for a complete feature list.
+
+To insert printing characters (letters, digits, symbols, etc.), simply
+type the character.  Octave will insert the character at the cursor and
+advance the cursor forward.
+
+Many of the command-line editing functions operate using control
+characters.  For example, the character @kbd{Control-a} moves the cursor
+to the beginning of the line.  To type @kbd{C-a}, hold down @key{CTRL}
+and then press @key{a}.  In the following sections, control characters
+such as @kbd{Control-a} are written as @kbd{C-a}.
+
+Another set of command-line editing functions use Meta characters.  To 
+type @kbd{M-u}, hold down the @key{META} key and press @key{u}.  Depending
+on the keyboard, the @key{META} key may be labeled @key{ALT} or
+even @key{WINDOWS}.  If your terminal does not have a @key{META} key, you
+can still type Meta characters using two-character sequences starting
+with @kbd{ESC}.  Thus, to enter @kbd{M-u}, you would type
+ at key{ESC} @key{u}.  The @kbd{ESC} character sequences are also allowed on
+terminals with real Meta keys.  In the following sections, Meta
+characters such as @kbd{Meta-u} are written as @kbd{M-u}.
+
+
+ at menu
+* Cursor Motion::               
+* Killing and Yanking::         
+* Commands For Text::           
+* Commands For Completion::     
+* Commands For History::        
+* Customizing readline::        
+* Customizing the Prompt::      
+* Diary and Echo Commands::     
+ at end menu
+
+ at node Cursor Motion
+ at subsection Cursor Motion
+
+The following commands allow you to position the cursor.
+
+ at table @kbd
+ at item C-b
+Move back one character.
+
+ at item C-f
+Move forward one character.
+
+ at item @key{DEL}
+Delete the character to the left of the cursor.
+
+ at item C-d
+Delete the character underneath the cursor.
+
+ at item M-f
+Move forward a word.
+
+ at item M-b
+Move backward a word.
+
+ at item C-a
+Move to the start of the line.
+
+ at item C-e
+Move to the end of the line.
+
+ at item C-l
+Clear the screen, reprinting the current line at the top.
+
+ at item C-_
+ at itemx C-/
+Undo the last action.  You can undo all the way back to an empty line.
+
+ at item M-r
+Undo all changes made to this line.  This is like typing the `undo'
+command enough times to get back to the beginning.
+ at end table
+
+The above table describes the most basic possible keystrokes that you need
+in order to do editing of the input line.  On most terminals, you can
+also use the left and right arrow keys in place of @kbd{C-f} and @kbd{C-b}
+to move forward and backward.
+
+Notice how @kbd{C-f} moves forward a character, while @kbd{M-f} moves
+forward a word.  It is a loose convention that control keystrokes
+operate on characters while meta keystrokes operate on words.
+
+ at cindex clearing the screen
+
+The function @code{clc} will allow you to clear the screen from within
+Octave programs.
+
+ at DOCSTRING(clc)
+
+ at node Killing and Yanking
+ at subsection Killing and Yanking
+
+ at dfn{Killing} text means to delete the text from the line, but to save
+it away for later use, usually by @dfn{yanking} it back into the line.
+If the description for a command says that it `kills' text, then you can
+be sure that you can get the text back in a different (or the same)
+place later.
+
+Here is the list of commands for killing text.
+
+ at table @kbd
+ at item C-k
+Kill the text from the current cursor position to the end of the line.
+
+ at item M-d
+Kill from the cursor to the end of the current word, or if between
+words, to the end of the next word.
+
+ at item M- at key{DEL}
+Kill from the cursor to the start of the previous word, or if between
+words, to the start of the previous word. 
+
+ at item C-w
+Kill from the cursor to the previous whitespace.  This is different than
+ at kbd{M- at key{DEL}} because the word boundaries differ.
+ at end table
+
+And, here is how to @dfn{yank} the text back into the line.  Yanking
+means to copy the most-recently-killed text from the kill buffer.
+
+ at table @kbd
+ at item C-y
+Yank the most recently killed text back into the buffer at the cursor.
+
+ at item M-y
+Rotate the kill-ring, and yank the new top.  You can only do this if
+the prior command is @kbd{C-y} or @kbd{M-y}.
+ at end table
+
+When you use a kill command, the text is saved in a @dfn{kill-ring}.
+Any number of consecutive kills save all of the killed text together, so
+that when you yank it back, you get it in one clean sweep.  The kill
+ring is not line specific; the text that you killed on a previously
+typed line is available to be yanked back later, when you are typing
+another line.
+
+ at node Commands For Text
+ at subsection Commands For Changing Text
+
+The following commands can be used for entering characters that would
+otherwise have a special meaning (e.g., @key{TAB}, @kbd{C-q}, etc.), or
+for quickly correcting typing mistakes.
+
+ at table @kbd
+ at item C-q
+ at itemx C-v
+Add the next character that you type to the line verbatim.  This is
+how to insert things like @kbd{C-q} for example.
+
+ at item M- at key{TAB}
+Insert a tab character.
+
+ at item C-t
+Drag the character before the cursor forward over the character at the
+cursor, also moving the cursor forward.  If the cursor is at the end of
+the line, then transpose the two characters before it.
+
+ at item M-t
+Drag the word behind the cursor past the word in front of the cursor
+moving the cursor over that word as well.
+
+ at item M-u
+Uppercase the characters following the cursor to the end of the current
+(or following) word, moving the cursor to the end of the word.
+
+ at item M-l
+Lowercase the characters following the cursor to the end of the current
+(or following) word, moving the cursor to the end of the word.
+
+ at item M-c
+Uppercase the character following the cursor (or the beginning of the
+next word if the cursor is between words), moving the cursor to the end
+of the word.
+ at end table
+
+ at node Commands For Completion
+ at subsection Letting Readline Type For You
+ at cindex command completion
+
+The following commands allow Octave to complete command and variable
+names for you.
+
+ at table @kbd
+ at item @key{TAB}
+Attempt to do completion on the text before the cursor.  Octave can
+complete the names of commands and variables.
+
+ at item M-?
+List the possible completions of the text before the cursor.
+ at end table
+
+ at DOCSTRING(completion_append_char)
+
+ at DOCSTRING(completion_matches)
+
+ at node Commands For History
+ at subsection Commands For Manipulating The History
+ at cindex command history
+ at cindex input history
+ at cindex history of commands
+
+Octave normally keeps track of the commands you type so that you can
+recall previous commands to edit or execute them again.  When you exit
+Octave, the most recent commands you have typed, up to the number
+specified by the variable @code{history_size}, are saved in a file.
+When Octave starts, it loads an initial list of commands from the file
+named by the variable @code{history_file}.
+
+Here are the commands for simple browsing and searching the history
+list.
+
+ at table @kbd
+ at item @key{LFD}
+ at itemx @key{RET}
+Accept the current line regardless of where the cursor is.  If the line is
+non-empty, add it to the history list.  If the line was a history
+line, then restore the history line to its original state.
+
+ at item C-p
+Move `up' through the history list.
+
+ at item C-n
+Move `down' through the history list.
+
+ at item M-<
+Move to the first line in the history.
+
+ at item M->
+Move to the end of the input history, i.e., the line you are entering!
+
+ at item C-r
+Search backward starting at the current line and moving `up' through
+the history as necessary.  This is an incremental search.
+
+ at item C-s
+Search forward starting at the current line and moving `down' through
+the history as necessary.
+ at end table
+
+On most terminals, you can also use the up and down arrow keys in place 
+of @kbd{C-p} and @kbd{C-n} to move through the history list.
+
+In addition to the keyboard commands for moving through the history
+list, Octave provides three functions for viewing, editing, and
+re-running chunks of commands from the history list.
+
+ at DOCSTRING(history)
+
+ at DOCSTRING(edit_history)
+
+ at DOCSTRING(run_history)
+
+ at noindent
+Octave also allows you customize the details of when, where, and how history
+is saved.
+
+ at DOCSTRING(saving_history)
+
+ at DOCSTRING(history_file)
+
+ at DOCSTRING(history_size)
+
+ at DOCSTRING(history_timestamp_format_string)
+
+ at DOCSTRING(EDITOR)
+
+ at node Customizing readline
+ at subsection Customizing @code{readline}
+ at cindex @file{~/.inputrc}
+ at cindex customizing @code{readline}
+ at cindex @code{readline} customization
+
+Octave uses the GNU Readline library for command-line editing and
+history features.  Readline is very flexible and can be modified through
+a configuration file of commands (See the GNU Readline library for the
+exact command syntax).  The default configuration file is normally
+ at file{~/.inputrc}.
+
+Octave provides two commands for initializing Readline and thereby changing
+the command line behavior.
+
+ at DOCSTRING(read_readline_init_file)
+
+ at DOCSTRING(re_read_readline_init_file)
+
+ at node Customizing the Prompt
+ at subsection Customizing the Prompt
+ at cindex prompt customization
+ at cindex customizing the prompt
+
+The following variables are available for customizing the appearance of
+the command-line prompts.  Octave allows the prompt to be customized by
+inserting a number of backslash-escaped special characters that are
+decoded as follows:
+
+ at table @samp
+ at item \t
+The time.
+
+ at item \d
+The date.
+
+ at item \n
+Begins a new line by printing the equivalent of a carriage return
+followed by a line feed.
+
+ at item \s
+The name of the program (usually just @samp{octave}).
+
+ at item \w
+The current working directory.
+
+ at item \W
+The basename of the current working directory.
+
+ at item \u
+The username of the current user.
+
+ at item \h
+The hostname, up to the first `.'.
+
+ at item \H
+The hostname.
+
+ at item \#
+The command number of this command, counting from when Octave starts.
+
+ at item \!
+The history number of this command.  This differs from @samp{\#} by the
+number of commands in the history list when Octave starts.
+
+ at item \$
+If the effective UID is 0, a @samp{#}, otherwise a @samp{$}.
+
+ at item \nnn
+The character whose character code in octal is @var{nnn}.
+
+ at item \\
+A backslash.
+ at end table
+
+ at DOCSTRING(PS1)
+
+ at DOCSTRING(PS2)
+
+ at DOCSTRING(PS4)
+
+ at node Diary and Echo Commands
+ at subsection Diary and Echo Commands
+ at cindex diary of commands and output
+ at cindex command and output logs
+ at cindex logging commands and output
+ at cindex echoing executing commands
+ at cindex command echoing
+
+Octave's diary feature allows you to keep a log of all or part of an
+interactive session by recording the input you type and the output that
+Octave produces in a separate file.
+
+ at DOCSTRING(diary)
+
+Sometimes it is useful to see the commands in a function or script as
+they are being evaluated.  This can be especially helpful for debugging
+some kinds of problems.
+
+ at DOCSTRING(echo)
+
+ at DOCSTRING(echo_executing_commands)
+
+ at node Errors
+ at section How Octave Reports Errors
+ at cindex error messages
+ at cindex messages, error
+
+Octave reports two kinds of errors for invalid programs.
+
+A @dfn{parse error} occurs if Octave cannot understand something you
+have typed.  For example, if you misspell a keyword,
+
+ at example
+octave:13> function y = f (x) y = x***2; endfunction
+ at end example
+
+ at noindent
+Octave will respond immediately with a message like this:
+
+ at example
+ at group
+parse error:
+
+  syntax error
+
+>>> function y = f (x) y = x***2; endfunction
+                              ^
+ at end group
+ at end example
+
+ at noindent
+For most parse errors, Octave uses a caret (@samp{^}) to mark the point
+on the line where it was unable to make sense of your input.  In this
+case, Octave generated an error message because the keyword for
+exponentiation (@code{**}) was misspelled.  It marked the error at the
+third @samp{*} because the code leading up to this was correct but the final
+ at samp{*} was not understood.
+
+Another class of error message occurs at evaluation time.  These
+errors are called @dfn{run-time errors}, or sometimes
+ at dfn{evaluation errors}, because they occur when your program is being
+ at dfn{run}, or @dfn{evaluated}.  For example, if after correcting the
+mistake in the previous function definition, you type
+
+ at example
+octave:13> f ()
+ at end example
+
+ at noindent
+Octave will respond with
+
+ at example
+ at group
+error: `x' undefined near line 1 column 24
+error: called from:
+error:   f at line 1, column 22
+ at end group
+ at end example
+
+ at noindent
+This error message has several parts, and gives quite a bit of
+information to help you locate the source of the error.  The messages
+are generated from the point of the innermost error, and provide a
+traceback of enclosing expressions and function calls.
+
+In the example above, the first line indicates that a variable named
+ at samp{x} was found to be undefined near line 1 and column 24 of some
+function or expression.  For errors occurring within functions, lines
+are counted from the beginning of the file containing the function
+definition.  For errors occurring outside of an enclosing function, 
+the line number indicates the input line number, which is usually displayed 
+in the primary prompt string.
+
+The second and third lines of the error message indicate that the error 
+occurred within the function @code{f}.  If the function @code{f} had been 
+called from within another function, for example, @code{g}, the list of 
+errors would have ended with one more line:
+
+ at example
+error:   g at line 1, column 17
+ at end example
+
+These lists of function calls make it fairly easy to trace the
+path your program took before the error occurred, and to correct the
+error before trying again.
+
+ at node Executable Octave Programs
+ at section Executable Octave Programs
+ at cindex executable scripts
+ at cindex scripts
+ at cindex batch processing
+ at cindex self contained programs
+ at cindex program, self contained
+ at cindex @samp{#!}
+
+Once you have learned Octave, you may want to write self-contained
+Octave scripts, using the @samp{#!} script mechanism.  You can do this
+on GNU systems and on many Unix systems @footnote{The @samp{#!}
+mechanism works on Unix systems derived from Berkeley Unix, System V
+Release 4, and some System V Release 3 systems.}.
+
+Self-contained Octave scripts are useful when you want to write a
+program which users can invoke without knowing that the program is
+written in the Octave language.  Octave scripts are also used for batch
+processing of data files.  Once an algorithm has been developed and tested
+in the interactive portion of Octave, it can be committed to an executable
+script and used again and again on new data files.
+
+As a trivial example of an executable Octave script, you might create a
+text file named @file{hello}, containing the following lines:
+
+ at example
+ at group
+#! @var{octave-interpreter-name} -qf
+# a sample Octave program
+printf ("Hello, world!\n");
+ at end group
+ at end example
+
+ at noindent
+(where @var{octave-interpreter-name} should be replaced with the full
+path and name of your Octave binary).  Note that this will only work if
+ at samp{#!} appears at the very beginning of the file.  After making the
+file executable (with the @code{chmod} command on Unix systems), you can
+simply type:
+
+ at example
+hello
+ at end example
+
+ at noindent
+at the shell, and the system will arrange to run Octave as if you had
+typed:
+
+ at example
+octave hello
+ at end example
+
+The line beginning with @samp{#!} lists the full path and filename of an
+interpreter to be run, and an optional initial command line argument to
+pass to that interpreter.  The operating system then runs the
+interpreter with the given argument and the full argument list of the
+executed program.  The first argument in the list is the full file name
+of the Octave executable.  The rest of the argument list will either be
+options to Octave, or data files, or both.  The @samp{-qf} options are
+usually specified in stand-alone Octave programs to prevent them from
+printing the normal startup message, and to keep them from behaving
+differently depending on the contents of a particular user's
+ at file{~/.octaverc} file.  @xref{Invoking Octave from the Command Line}.
+
+Note that some operating systems may place a limit on the number of
+characters that are recognized after @samp{#!}.  Also, the arguments 
+appearing in a @samp{#!} line are parsed differently by various 
+shells/systems.  The majority of them group all the arguments together in one 
+string and pass it to the interpreter as a single argument.  In this case, the
+following script:
+
+ at example
+ at group
+#! @var{octave-interpreter-name} -q -f # comment
+ at end group
+ at end example
+
+ at noindent
+is equivalent to typing at the command line:
+
+ at example
+ at group
+octave "-q -f # comment"
+ at end group
+ at end example
+
+ at noindent
+which will produce an error message.  Unfortunately, it is
+not possible for Octave to determine whether it has been called from the 
+command line or from a @samp{#!} script, so some care is needed when using the
+ at samp{#!} mechanism.
+
+Note that when Octave is started from an executable script, the built-in
+function @code{argv} returns a cell array containing the command line
+arguments passed to the executable Octave script, not the arguments
+passed to the Octave interpreter on the @samp{#!} line of the script.
+For example, the following program will reproduce the command line that
+was used to execute the script, not @samp{-qf}.
+
+ at example
+ at group
+#! /bin/octave -qf
+printf ("%s", program_name ());
+arg_list = argv ();
+for i = 1:nargin
+  printf (" %s", arg_list@{i@});
+endfor
+printf ("\n");
+ at end group
+ at end example
+
+ at node Comments
+ at section Comments in Octave Programs
+ at cindex comments
+ at cindex use of comments
+ at cindex documenting Octave programs
+
+A @dfn{comment} is some text that is included in a program for the sake
+of human readers, and which is NOT an executable part of the program.  
+Comments can explain what the program does, and how it works.  Nearly all
+programming languages have provisions for comments, because programs are
+typically hard to understand without them.
+
+ at menu
+* Single Line Comments::
+* Block Comments::
+* Comments and the Help System::                    
+ at end menu
+
+ at node Single Line Comments
+ at subsection Single Line Comments
+ at cindex @samp{#}
+ at cindex @samp{%}
+
+In the Octave language, a comment starts with either the sharp sign
+character, @samp{#}, or the percent symbol @samp{%} and continues to the
+end of the line.  Any text following the sharp sign or percent symbol is
+ignored by the Octave interpreter and not executed.  The following example
+shows whole line and partial line comments.
+ at example
+ at group
+function countdown
+  # Count down for main rocket engines 
+  disp(3);
+  disp(2);
+  disp(1);
+  disp("Blast Off!");  # Rocket leaves pad
+endfunction
+ at end group
+ at end example
+
+ at node Block Comments
+ at subsection Block Comments
+ at cindex block comments
+ at cindex multi-line comments
+ at cindex @samp{#@{}
+ at cindex @samp{%@{}
+
+Entire blocks of code can be commented by enclosing the code between 
+matching @samp{#@{} and @samp{#@}} or @samp{%@{} and @samp{%@}} markers.  
+For example,
+ at example
+ at group
+function quick_countdown
+  # Count down for main rocket engines 
+  disp(3);
+ #@{
+  disp(2);
+  disp(1);
+ #@}
+  disp("Blast Off!");  # Rocket leaves pad
+endfunction
+ at end group
+ at end example
+
+ at noindent
+will produce a very quick countdown from '3' to 'Blast Off' as the
+lines "@code{disp(2);}" and "@code{disp(1);}" won't be executed.
+
+ at node Comments and the Help System
+ at subsection Comments and the Help System
+ at cindex documenting functions
+ at cindex documenting user scripts
+ at cindex help, user-defined functions
+
+The @code{help} command (@pxref{Getting Help}) is able to find the first
+block of comments in a function and return those as a documentation
+string.  This means that the same commands used to get help
+on built-in functions are available for properly formatted user-defined
+functions.  For example, after defining the function @code{f} below,
+ at example
+ at group
+function xdot = f (x, t)
+
+# usage: f (x, t)
+#
+# This function defines the right-hand
+# side functions for a set of nonlinear
+# differential equations.
+
+  r = 0.25;
+  @dots{}
+endfunction
+ at end group
+ at end example
+
+the command @kbd{help f} produces the output
+
+ at example
+ at group
+ usage: f (x, t)
+
+ This function defines the right-hand
+ side functions for a set of nonlinear
+ differential equations.
+ at end group
+ at end example
+
+Although it is possible to put comment lines into keyboard-composed,
+throw-away Octave programs, it usually isn't very useful because the
+purpose of a comment is to help you or another person understand the
+program at a later time.
+
+The @code{help} parser currently only recognizes single line comments
+(@pxref{Single Line Comments}) and not block comments for the initial 
+help text. 
diff --git a/doc/interpreter/bugs.texi b/doc/interpreter/bugs.texi
new file mode 100644
index 0000000..72bf9bb
--- /dev/null
+++ b/doc/interpreter/bugs.texi
@@ -0,0 +1,434 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2007, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c The text of this file appears in the file BUGS in the Octave
+ at c distribution, as well as in the Octave manual.
+
+ at ifclear BUGSONLY
+ at node Trouble
+ at appendix Known Causes of Trouble
+ at end ifclear
+
+ at ifset BUGSONLY
+ at include conf.texi
+
+This file documents known bugs in Octave and describes where and how to
+report any bugs that you may find.
+
+Copyright (C) 1996, 1997, 2007 John W. Eaton.  You may copy, distribute, and
+modify it freely as long as you preserve this copyright notice and
+permission notice.
+
+ at node Trouble
+ at chapter Known Causes of Trouble with Octave
+ at end ifset
+
+ at cindex bugs, known
+ at cindex installation trouble
+ at cindex known causes of trouble
+ at cindex troubleshooting
+
+This section describes known problems that affect users of Octave.  Most
+of these are not Octave bugs per se---if they were, we would fix them.
+But the result for a user may be like the result of a bug.
+
+Some of these problems are due to bugs in other software, some are
+missing features that are too much work to add, and some are places
+where people's opinions differ as to what is best.
+
+ at menu
+* Actual Bugs::                 Bugs we will fix later.
+* Reporting Bugs::              
+* Bug Criteria::                
+* Bug Lists::                   
+* Bug Reporting::               
+* Sending Patches::             
+* Service::                     
+ at end menu
+
+ at node Actual Bugs
+ at appendixsec Actual Bugs We Haven't Fixed Yet
+
+ at itemize @bullet
+ at item
+Output that comes directly from Fortran functions is not sent through
+the pager and may appear out of sequence with other output that is sent
+through the pager.  One way to avoid this is to force pending output to
+be flushed before calling a function that will produce output from
+within Fortran functions.  To do this, use the command
+
+ at example
+fflush (stdout)
+ at end example
+
+Another possible workaround is to use the command
+
+ at example
+page_screen_output (false);
+ at end example
+
+ at noindent
+to turn the pager off.
+ at end itemize
+
+A list of ideas for future enhancements is distributed with Octave.  See
+the file @file{PROJECTS} in the top level directory in the source
+distribution.
+
+ at node Reporting Bugs
+ at appendixsec Reporting Bugs
+ at cindex bugs
+ at cindex reporting bugs
+
+Your bug reports play an essential role in making Octave reliable.
+
+When you encounter a problem, the first thing to do is to see if it is
+already known.  @xref{Trouble}.  If it isn't known, then you should
+report the problem.
+
+Reporting a bug may help you by bringing a solution to your problem, or
+it may not.  In any case, the principal function of a bug report is
+to help the entire community by making the next version of Octave work
+better.  Bug reports are your contribution to the maintenance of Octave.
+
+In order for a bug report to serve its purpose, you must include the
+information that makes it possible to fix the bug.
+
+ at findex bug_report
+
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function @code{bug_report}.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+ at c ./miscellaneous/bug_report.m
+ at anchor{doc-bug_report}
+ at deftypefn {Function File} {} bug_report ()
+Have Octave create a bug report template file, invoke your favorite
+editor, and submit the report to the bug-octave mailing list when
+you are finished editing.
+ at end deftypefn
+
+
+ at menu
+* Bug Criteria::                
+* Where: Bug Lists.             Where to send your bug report.
+* Reporting: Bug Reporting.     How to report a bug effectively.
+* Patches: Sending Patches.     How to send a patch for Octave.
+ at end menu
+
+ at node Bug Criteria
+ at appendixsec Have You Found a Bug?
+ at cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+ at itemize @bullet
+ at cindex fatal signal
+ at cindex core dump
+ at item
+If Octave gets a fatal signal, for any input whatever, that is
+a bug.  Reliable interpreters never crash.
+
+ at cindex incorrect output
+ at cindex incorrect results
+ at cindex results, incorrect
+ at cindex answers, incorrect
+ at cindex erroneous results
+ at cindex wrong answers
+ at item
+If Octave produces incorrect results, for any input whatever,
+that is a bug.
+
+ at cindex undefined behavior
+ at cindex undefined function value
+ at item
+Some output may appear to be incorrect when it is in fact due to a
+program whose behavior is undefined, which happened by chance to give
+the desired results on another system.  For example, the range operator
+may produce different results because of differences in the way floating
+point arithmetic is handled on various systems.
+
+ at cindex erroneous messages
+ at cindex incorrect error messages
+ at cindex error messages, incorrect
+ at item
+If Octave produces an error message for valid input, that is a bug.
+
+ at cindex invalid input
+ at item
+If Octave does not produce an error message for invalid input, that is
+a bug.  However, you should note that your idea of ``invalid input''
+might be my idea of ``an extension'' or ``support for traditional
+practice''.
+
+ at cindex improving Octave
+ at cindex suggestions
+ at item
+If you are an experienced user of programs like Octave, your suggestions
+for improvement are welcome in any case.
+ at end itemize
+
+ at node Bug Lists
+ at appendixsec Where to Report Bugs
+ at cindex bug report mailing lists
+ at cindex reporting bugs
+ at cindex bugs, reporting
+
+ at findex bug_report
+
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function @code{bug_report}.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+If for some reason you cannot use Octave's @code{bug_report} function,
+send bug reports for Octave to @email{bug@@octave.org}.
+
+ at strong{Do not send bug reports to @samp{help-octave}}.  Most users of
+Octave do not want to receive bug reports.  Those that do have asked to
+be on the mailing list.
+
+ at node Bug Reporting
+ at appendixsec How to Report Bugs
+ at cindex bugs, reporting
+
+Send bug reports for Octave to one of the addresses listed in
+ at ref{Bug Lists}.
+
+The fundamental principle of reporting bugs usefully is this:
+ at strong{report all the facts}.  If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the
+problem and they conclude that some details don't matter.  Thus, you might
+assume that the name of the variable you use in an example does not matter.
+Well, probably it doesn't, but one cannot be sure.  Perhaps the bug is a
+stray memory reference which happens to fetch from the location where that
+name is stored in memory; perhaps, if the name were different, the contents
+of that location would fool the interpreter into doing the right thing
+despite the bug.  Play it safe and give a specific, complete example.
+
+Keep in mind that the purpose of a bug report is to enable someone to
+fix the bug if it is not known.  Always write your bug reports on
+the assumption that the bug is not known.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?''  This cannot help us fix a bug.  It is better to send a complete
+bug report to begin with.
+
+Try to make your bug report self-contained.  If we have to ask you for
+more information, it is best if you include all the previous information
+in your response, as well as the information that was missing.
+
+To enable someone to investigate the bug, you should include all these
+things:
+
+ at itemize @bullet
+ at item
+The version of Octave.  You can get this by noting the version number
+that is printed when Octave starts, or running it with the @samp{-v}
+option.
+
+ at item
+A complete input file that will reproduce the bug.
+
+A single statement may not be enough of an example---the bug might
+depend on other details that are missing from the single statement where
+the error finally occurs.
+
+ at item
+The command arguments you gave Octave to execute that example
+and observe the bug.  To guarantee you won't omit something important,
+list all the options. 
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we would not encounter the bug.
+
+ at item
+The type of machine you are using, and the operating system name and
+version number.
+
+ at item
+The command-line arguments you gave to the @code{configure} command when
+you installed the interpreter.
+
+ at item
+A complete list of any modifications you have made to the interpreter
+source.
+
+Be precise about these changes---show a context diff for them.
+
+ at item
+Details of any other deviations from the standard procedure for installing
+Octave.
+
+ at cindex incorrect output
+ at cindex incorrect results
+ at cindex results, incorrect
+ at cindex answers, incorrect
+ at cindex erroneous results
+ at cindex wrong answers
+ at item
+A description of what behavior you observe that you believe is
+incorrect.  For example, "The interpreter gets a fatal signal," or, "The
+output produced at line 208 is incorrect."
+
+Of course, if the bug is that the interpreter gets a fatal signal, then
+one can't miss it.  But if the bug is incorrect output, we might not
+notice unless it is glaringly wrong.
+
+Even if the problem you experience is a fatal signal, you should still
+say so explicitly.  Suppose something strange is going on, such as, your
+copy of the interpreter is out of synch, or you have encountered a bug
+in the C library on your system.  Your copy might crash and the copy
+here would not.  If you said to expect a crash, then when the
+interpreter here fails to crash, we would know that the bug was not
+happening.  If you don't say to expect a crash, then we would not know
+whether the bug was happening.  We would not be able to draw any
+conclusion from our observations.
+
+Often the observed symptom is incorrect output when your program is run.
+Unfortunately, this is not enough information unless the program is
+short and simple.  It is very helpful if you can include an explanation
+of the expected output, and why the actual output is incorrect.
+
+ at item
+If you wish to suggest changes to the Octave source, send them as
+context diffs.  If you even discuss something in the Octave source,
+refer to it by context, not by line number, because the line numbers in
+the development sources probably won't match those in your sources.
+ at end itemize
+
+Here are some things that are not necessary:
+
+ at itemize @bullet
+ at cindex bugs, investigating
+ at item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating which
+changes to the input file will make the bug go away and which changes
+will not affect it.  Such information is usually not necessary to enable
+us to fix bugs in Octave, but if you can find a simpler example to
+report @emph{instead} of the original one, that is a convenience.
+Errors in the output will be easier to spot, running under the debugger
+will take less time, etc.  Most Octave bugs involve just one function, so
+the most straightforward way to simplify an example is to delete all the
+function definitions except the one in which the bug occurs.
+
+However, simplification is not vital; if you don't want to do
+this, report the bug anyway and send the entire test case you
+used.
+
+ at item
+A patch for the bug.  Patches can be helpful, but if you find a bug, you
+should report it, even if you cannot send a fix for the problem.
+ at end itemize
+
+ at node Sending Patches
+ at appendixsec Sending Patches for Octave
+ at cindex improving Octave
+ at cindex diffs, submitting
+ at cindex patches, submitting
+ at cindex submitting diffs
+ at cindex submitting patches
+
+If you would like to write bug fixes or improvements for Octave, that is
+very helpful.  When you send your changes, please follow these
+guidelines to avoid causing extra work for us in studying the patches.
+
+If you don't follow these guidelines, your information might still be
+useful, but using it will take extra work.  Maintaining Octave is a lot
+of work in the best of circumstances, and we can't keep up unless you do
+your best to help.
+
+ at itemize @bullet
+ at item
+Send an explanation with your changes of what problem they fix or what
+improvement they bring about.  For a bug fix, just include a copy of the
+bug report, and explain why the change fixes the bug.
+
+ at item
+Always include a proper bug report for the problem you think you have
+fixed.  We need to convince ourselves that the change is right before
+installing it.  Even if it is right, we might have trouble judging it if
+we don't have a way to reproduce the problem.
+
+ at item
+Include all the comments that are appropriate to help people reading the
+source in the future understand why this change was needed.
+
+ at item
+Don't mix together changes made for different reasons.
+Send them @emph{individually}.
+
+If you make two changes for separate reasons, then we might not want to
+install them both.  We might want to install just one.
+
+ at item
+Use @samp{diff -c} to make your diffs.  Diffs without context are hard
+for us to install reliably.  More than that, they make it hard for us to
+study the diffs to decide whether we want to install them.  Unidiff
+format is better than contextless diffs, but not as easy to read as
+ at samp{-c} format.
+
+If you have GNU diff, use @samp{diff -cp}, which shows the name of the
+function that each change occurs in.
+
+ at item
+Write the change log entries for your changes.
+
+Read the @file{ChangeLog} file to see what sorts of information to put
+in, and to learn the style that we use.  The purpose of the change log
+is to show people where to find what was changed.  So you need to be
+specific about what functions you changed; in large functions, it's
+often helpful to indicate where within the function the change was made.
+
+On the other hand, once you have shown people where to find the change,
+you need not explain its purpose.  Thus, if you add a new function, all
+you need to say about it is that it is new.  If you feel that the
+purpose needs explaining, it probably does---but the explanation will be
+much more useful if you put it in comments in the code.
+
+If you would like your name to appear in the header line for who made
+the change, send us the header line.
+ at end itemize
+
+ at node Service
+ at appendixsec How To Get Help with Octave
+ at cindex help, where to find
+
+The mailing list @email{help@@octave.org} exists for the discussion of
+matters related to using and installing Octave.  If would like to join
+the discussion, please send a short note to
+ at email{help at strong{-request}@@octave.org}.
+
+ at strong{Please do not} send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+If you think you have found a bug in the installation procedure,
+however, you should send a complete bug report for the problem to
+ at email{bug@@octave.org}.  @xref{Bug Reporting}, for
+information that will help you to submit a useful report.
diff --git a/doc/interpreter/bugs.txi b/doc/interpreter/bugs.txi
new file mode 100644
index 0000000..a068a1e
--- /dev/null
+++ b/doc/interpreter/bugs.txi
@@ -0,0 +1,425 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2007, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c The text of this file appears in the file BUGS in the Octave
+ at c distribution, as well as in the Octave manual.
+
+ at ifclear BUGSONLY
+ at node Trouble
+ at appendix Known Causes of Trouble
+ at end ifclear
+
+ at ifset BUGSONLY
+ at include conf.texi
+
+This file documents known bugs in Octave and describes where and how to
+report any bugs that you may find.
+
+Copyright (C) 1996, 1997, 2007 John W. Eaton.  You may copy, distribute, and
+modify it freely as long as you preserve this copyright notice and
+permission notice.
+
+ at node Trouble
+ at chapter Known Causes of Trouble with Octave
+ at end ifset
+
+ at cindex bugs, known
+ at cindex installation trouble
+ at cindex known causes of trouble
+ at cindex troubleshooting
+
+This section describes known problems that affect users of Octave.  Most
+of these are not Octave bugs per se---if they were, we would fix them.
+But the result for a user may be like the result of a bug.
+
+Some of these problems are due to bugs in other software, some are
+missing features that are too much work to add, and some are places
+where people's opinions differ as to what is best.
+
+ at menu
+* Actual Bugs::                 Bugs we will fix later.
+* Reporting Bugs::              
+* Bug Criteria::                
+* Bug Lists::                   
+* Bug Reporting::               
+* Sending Patches::             
+* Service::                     
+ at end menu
+
+ at node Actual Bugs
+ at appendixsec Actual Bugs We Haven't Fixed Yet
+
+ at itemize @bullet
+ at item
+Output that comes directly from Fortran functions is not sent through
+the pager and may appear out of sequence with other output that is sent
+through the pager.  One way to avoid this is to force pending output to
+be flushed before calling a function that will produce output from
+within Fortran functions.  To do this, use the command
+
+ at example
+fflush (stdout)
+ at end example
+
+Another possible workaround is to use the command
+
+ at example
+page_screen_output (false);
+ at end example
+
+ at noindent
+to turn the pager off.
+ at end itemize
+
+A list of ideas for future enhancements is distributed with Octave.  See
+the file @file{PROJECTS} in the top level directory in the source
+distribution.
+
+ at node Reporting Bugs
+ at appendixsec Reporting Bugs
+ at cindex bugs
+ at cindex reporting bugs
+
+Your bug reports play an essential role in making Octave reliable.
+
+When you encounter a problem, the first thing to do is to see if it is
+already known.  @xref{Trouble}.  If it isn't known, then you should
+report the problem.
+
+Reporting a bug may help you by bringing a solution to your problem, or
+it may not.  In any case, the principal function of a bug report is
+to help the entire community by making the next version of Octave work
+better.  Bug reports are your contribution to the maintenance of Octave.
+
+In order for a bug report to serve its purpose, you must include the
+information that makes it possible to fix the bug.
+
+ at findex bug_report
+
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function @code{bug_report}.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+ at DOCSTRING(bug_report)
+
+ at menu
+* Bug Criteria::                
+* Where: Bug Lists.             Where to send your bug report.
+* Reporting: Bug Reporting.     How to report a bug effectively.
+* Patches: Sending Patches.     How to send a patch for Octave.
+ at end menu
+
+ at node Bug Criteria
+ at appendixsec Have You Found a Bug?
+ at cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+ at itemize @bullet
+ at cindex fatal signal
+ at cindex core dump
+ at item
+If Octave gets a fatal signal, for any input whatever, that is
+a bug.  Reliable interpreters never crash.
+
+ at cindex incorrect output
+ at cindex incorrect results
+ at cindex results, incorrect
+ at cindex answers, incorrect
+ at cindex erroneous results
+ at cindex wrong answers
+ at item
+If Octave produces incorrect results, for any input whatever,
+that is a bug.
+
+ at cindex undefined behavior
+ at cindex undefined function value
+ at item
+Some output may appear to be incorrect when it is in fact due to a
+program whose behavior is undefined, which happened by chance to give
+the desired results on another system.  For example, the range operator
+may produce different results because of differences in the way floating
+point arithmetic is handled on various systems.
+
+ at cindex erroneous messages
+ at cindex incorrect error messages
+ at cindex error messages, incorrect
+ at item
+If Octave produces an error message for valid input, that is a bug.
+
+ at cindex invalid input
+ at item
+If Octave does not produce an error message for invalid input, that is
+a bug.  However, you should note that your idea of ``invalid input''
+might be my idea of ``an extension'' or ``support for traditional
+practice''.
+
+ at cindex improving Octave
+ at cindex suggestions
+ at item
+If you are an experienced user of programs like Octave, your suggestions
+for improvement are welcome in any case.
+ at end itemize
+
+ at node Bug Lists
+ at appendixsec Where to Report Bugs
+ at cindex bug report mailing lists
+ at cindex reporting bugs
+ at cindex bugs, reporting
+
+ at findex bug_report
+
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function @code{bug_report}.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+If for some reason you cannot use Octave's @code{bug_report} function,
+send bug reports for Octave to @email{bug@@octave.org}.
+
+ at strong{Do not send bug reports to @samp{help-octave}}.  Most users of
+Octave do not want to receive bug reports.  Those that do have asked to
+be on the mailing list.
+
+ at node Bug Reporting
+ at appendixsec How to Report Bugs
+ at cindex bugs, reporting
+
+Send bug reports for Octave to one of the addresses listed in
+ at ref{Bug Lists}.
+
+The fundamental principle of reporting bugs usefully is this:
+ at strong{report all the facts}.  If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the
+problem and they conclude that some details don't matter.  Thus, you might
+assume that the name of the variable you use in an example does not matter.
+Well, probably it doesn't, but one cannot be sure.  Perhaps the bug is a
+stray memory reference which happens to fetch from the location where that
+name is stored in memory; perhaps, if the name were different, the contents
+of that location would fool the interpreter into doing the right thing
+despite the bug.  Play it safe and give a specific, complete example.
+
+Keep in mind that the purpose of a bug report is to enable someone to
+fix the bug if it is not known.  Always write your bug reports on
+the assumption that the bug is not known.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?''  This cannot help us fix a bug.  It is better to send a complete
+bug report to begin with.
+
+Try to make your bug report self-contained.  If we have to ask you for
+more information, it is best if you include all the previous information
+in your response, as well as the information that was missing.
+
+To enable someone to investigate the bug, you should include all these
+things:
+
+ at itemize @bullet
+ at item
+The version of Octave.  You can get this by noting the version number
+that is printed when Octave starts, or running it with the @samp{-v}
+option.
+
+ at item
+A complete input file that will reproduce the bug.
+
+A single statement may not be enough of an example---the bug might
+depend on other details that are missing from the single statement where
+the error finally occurs.
+
+ at item
+The command arguments you gave Octave to execute that example
+and observe the bug.  To guarantee you won't omit something important,
+list all the options. 
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we would not encounter the bug.
+
+ at item
+The type of machine you are using, and the operating system name and
+version number.
+
+ at item
+The command-line arguments you gave to the @code{configure} command when
+you installed the interpreter.
+
+ at item
+A complete list of any modifications you have made to the interpreter
+source.
+
+Be precise about these changes---show a context diff for them.
+
+ at item
+Details of any other deviations from the standard procedure for installing
+Octave.
+
+ at cindex incorrect output
+ at cindex incorrect results
+ at cindex results, incorrect
+ at cindex answers, incorrect
+ at cindex erroneous results
+ at cindex wrong answers
+ at item
+A description of what behavior you observe that you believe is
+incorrect.  For example, "The interpreter gets a fatal signal," or, "The
+output produced at line 208 is incorrect."
+
+Of course, if the bug is that the interpreter gets a fatal signal, then
+one can't miss it.  But if the bug is incorrect output, we might not
+notice unless it is glaringly wrong.
+
+Even if the problem you experience is a fatal signal, you should still
+say so explicitly.  Suppose something strange is going on, such as, your
+copy of the interpreter is out of synch, or you have encountered a bug
+in the C library on your system.  Your copy might crash and the copy
+here would not.  If you said to expect a crash, then when the
+interpreter here fails to crash, we would know that the bug was not
+happening.  If you don't say to expect a crash, then we would not know
+whether the bug was happening.  We would not be able to draw any
+conclusion from our observations.
+
+Often the observed symptom is incorrect output when your program is run.
+Unfortunately, this is not enough information unless the program is
+short and simple.  It is very helpful if you can include an explanation
+of the expected output, and why the actual output is incorrect.
+
+ at item
+If you wish to suggest changes to the Octave source, send them as
+context diffs.  If you even discuss something in the Octave source,
+refer to it by context, not by line number, because the line numbers in
+the development sources probably won't match those in your sources.
+ at end itemize
+
+Here are some things that are not necessary:
+
+ at itemize @bullet
+ at cindex bugs, investigating
+ at item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating which
+changes to the input file will make the bug go away and which changes
+will not affect it.  Such information is usually not necessary to enable
+us to fix bugs in Octave, but if you can find a simpler example to
+report @emph{instead} of the original one, that is a convenience.
+Errors in the output will be easier to spot, running under the debugger
+will take less time, etc.  Most Octave bugs involve just one function, so
+the most straightforward way to simplify an example is to delete all the
+function definitions except the one in which the bug occurs.
+
+However, simplification is not vital; if you don't want to do
+this, report the bug anyway and send the entire test case you
+used.
+
+ at item
+A patch for the bug.  Patches can be helpful, but if you find a bug, you
+should report it, even if you cannot send a fix for the problem.
+ at end itemize
+
+ at node Sending Patches
+ at appendixsec Sending Patches for Octave
+ at cindex improving Octave
+ at cindex diffs, submitting
+ at cindex patches, submitting
+ at cindex submitting diffs
+ at cindex submitting patches
+
+If you would like to write bug fixes or improvements for Octave, that is
+very helpful.  When you send your changes, please follow these
+guidelines to avoid causing extra work for us in studying the patches.
+
+If you don't follow these guidelines, your information might still be
+useful, but using it will take extra work.  Maintaining Octave is a lot
+of work in the best of circumstances, and we can't keep up unless you do
+your best to help.
+
+ at itemize @bullet
+ at item
+Send an explanation with your changes of what problem they fix or what
+improvement they bring about.  For a bug fix, just include a copy of the
+bug report, and explain why the change fixes the bug.
+
+ at item
+Always include a proper bug report for the problem you think you have
+fixed.  We need to convince ourselves that the change is right before
+installing it.  Even if it is right, we might have trouble judging it if
+we don't have a way to reproduce the problem.
+
+ at item
+Include all the comments that are appropriate to help people reading the
+source in the future understand why this change was needed.
+
+ at item
+Don't mix together changes made for different reasons.
+Send them @emph{individually}.
+
+If you make two changes for separate reasons, then we might not want to
+install them both.  We might want to install just one.
+
+ at item
+Use @samp{diff -c} to make your diffs.  Diffs without context are hard
+for us to install reliably.  More than that, they make it hard for us to
+study the diffs to decide whether we want to install them.  Unidiff
+format is better than contextless diffs, but not as easy to read as
+ at samp{-c} format.
+
+If you have GNU diff, use @samp{diff -cp}, which shows the name of the
+function that each change occurs in.
+
+ at item
+Write the change log entries for your changes.
+
+Read the @file{ChangeLog} file to see what sorts of information to put
+in, and to learn the style that we use.  The purpose of the change log
+is to show people where to find what was changed.  So you need to be
+specific about what functions you changed; in large functions, it's
+often helpful to indicate where within the function the change was made.
+
+On the other hand, once you have shown people where to find the change,
+you need not explain its purpose.  Thus, if you add a new function, all
+you need to say about it is that it is new.  If you feel that the
+purpose needs explaining, it probably does---but the explanation will be
+much more useful if you put it in comments in the code.
+
+If you would like your name to appear in the header line for who made
+the change, send us the header line.
+ at end itemize
+
+ at node Service
+ at appendixsec How To Get Help with Octave
+ at cindex help, where to find
+
+The mailing list @email{help@@octave.org} exists for the discussion of
+matters related to using and installing Octave.  If would like to join
+the discussion, please send a short note to
+ at email{help at strong{-request}@@octave.org}.
+
+ at strong{Please do not} send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+If you think you have found a bug in the installation procedure,
+however, you should send a complete bug report for the problem to
+ at email{bug@@octave.org}.  @xref{Bug Reporting}, for
+information that will help you to submit a useful report.
diff --git a/doc/interpreter/container.texi b/doc/interpreter/container.texi
new file mode 100644
index 0000000..ae3dac3
--- /dev/null
+++ b/doc/interpreter/container.texi
@@ -0,0 +1,1391 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Data Containers
+ at chapter Data Containers
+ at cindex containers
+
+Octave includes support for two different mechanisms to contain
+arbitrary data types in the same variable.  Structures, which are C-like,
+and are indexed with named fields, and cell arrays, where each element
+of the array can have a different data type and or shape. Multiple
+input arguments and return values of functions are organized as
+another data container, the comma separated list.
+
+ at menu
+* Data Structures::
+* Cell Arrays::
+* Comma Separated Lists::
+ at end menu
+
+ at node Data Structures
+ at section Data Structures
+ at cindex structures
+ at cindex data structures
+
+Octave includes support for organizing data in structures.  The current
+implementation uses an associative array with indices limited to
+strings, but the syntax is more like C-style structures.  
+
+ at menu
+* Basic Usage and Examples::
+* Structure Arrays::
+* Creating Structures::
+* Manipulating Structures::
+* Processing Data in Structures::
+ at end menu
+
+ at node Basic Usage and Examples
+ at subsection Basic Usage and Examples
+
+Here are some examples of using data structures in Octave.
+
+Elements of structures can be of any value type.  For example, the three
+expressions
+
+ at example
+ at group
+x.a = 1;
+x.b = [1, 2; 3, 4];
+x.c = "string";
+ at end group
+ at end example
+
+ at noindent
+create a structure with three elements.  To print the value of the
+structure, you can type its name, just as for any other variable:
+
+ at example
+ at group
+x
+     @result{} x =
+        @{
+          a = 1
+          b =
+
+            1  2
+            3  4
+
+          c = string
+        @}
+ at end group
+ at end example
+
+ at noindent
+Note that Octave may print the elements in any order.
+
+Structures may be copied just like any other variable:
+
+ at example
+ at group
+y = x
+     @result{} y =
+        @{
+          a = 1
+          b =
+
+            1  2
+            3  4
+
+          c = string
+        @}
+ at end group
+ at end example
+
+Since structures are themselves values, structure elements may reference
+other structures.  The following statements change the value of the
+element @code{b} of the structure @code{x} to be a data structure
+containing the single element @code{d}, which has a value of 3.
+
+ at example
+ at group
+x.b.d = 3;
+x.b
+     @result{} ans =
+        @{
+          d = 3
+        @}
+
+x
+     @result{} x =
+        @{
+          a = 1
+          b =
+          @{
+            d = 3
+          @}
+
+          c = string
+        @}
+ at end group
+ at end example
+
+Note that when Octave prints the value of a structure that contains
+other structures, only a few levels are displayed.  For example,
+
+ at example
+ at group
+a.b.c.d.e = 1;
+a
+     @result{} a =
+        @{
+          b =
+          @{
+            c =
+            @{
+              1x1 struct array containing the fields:
+
+              d: 1x1 struct
+            @}
+          @}
+        @}
+ at end group
+ at end example
+
+ at noindent
+This prevents long and confusing output from large deeply nested
+structures. The number of levels to print for nested structures can be
+set with the function @code{struct_levels_to_print}:
+
+ at c pr-output.cc
+ at anchor{doc-struct_levels_to_print}
+ at deftypefn {Built-in Function} {@var{val} =} struct_levels_to_print ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} struct_levels_to_print (@var{new_val})
+Query or set the internal variable that specifies the number of
+structure levels to display.
+ at end deftypefn
+
+
+Functions can return structures.  For example, the following function
+separates the real and complex parts of a matrix and stores them in two
+elements of the same structure variable.
+
+ at example
+ at group
+function y = f (x)
+  y.re = real (x);
+  y.im = imag (x);
+endfunction
+ at end group
+ at end example
+
+When called with a complex-valued argument, @code{f} returns the data
+structure containing the real and imaginary parts of the original
+function argument.
+
+ at example
+ at group
+f (rand (2) + rand (2) * I)
+     @result{} ans =
+        @{
+          im =
+
+            0.26475  0.14828
+            0.18436  0.83669
+
+          re =
+
+            0.040239  0.242160
+            0.238081  0.402523
+
+        @}
+ at end group
+ at end example
+
+Function return lists can include structure elements, and they may be
+indexed like any other variable.  For example,
+
+ at example
+ at group
+[ x.u, x.s(2:3,2:3), x.v ] = svd ([1, 2; 3, 4]);
+x
+     @result{} x =
+        @{
+          u =
+
+            -0.40455  -0.91451
+            -0.91451   0.40455
+
+          s =
+
+             0.00000   0.00000   0.00000
+             0.00000   5.46499   0.00000
+             0.00000   0.00000   0.36597
+
+          v =
+
+            -0.57605   0.81742
+            -0.81742  -0.57605
+
+        @}
+ at end group
+ at end example
+
+It is also possible to cycle through all the elements of a structure in
+a loop, using a special form of the @code{for} statement
+(@pxref{Looping Over Structure Elements}).
+
+ at node Structure Arrays
+ at subsection Structure Arrays
+
+A structure array is a particular instance of a structure, where each of
+the fields of the structure is represented by a cell array.  Each of
+these cell arrays has the same dimensions. Conceptually, a structure
+array can also be seen as an array of structures with identical
+fields.  An example of the creation of a structure array is
+
+ at example
+ at group
+x(1).a = "string1";
+x(2).a = "string2";
+x(1).b = 1;
+x(2).b = 2;
+ at end group
+ at end example
+
+ at noindent
+which creates a 2-by-1 structure array with two fields.  Another way
+to create a structure array is with the @code{struct} function
+(@pxref{Creating Structures}).  As previously, to print the value of
+the structure array, you can type its name: 
+
+ at example
+ at group
+x
+     @result{} x =
+        @{
+          1x2 struct array containing the fields:
+
+            a
+            b
+        @}  
+ at end group
+ at end example
+
+Individual elements of the structure array can be returned by indexing
+the variable like @code{@var{x}(1)}, which returns a structure with 
+two fields:
+
+ at example
+ at group
+x(1)
+     @result{} ans =
+        @{
+          a = string1
+          b =  1
+        @}
+ at end group
+ at end example
+
+Furthermore, the structure array can return a comma separated list of
+field values (@pxref{Comma Separated Lists}), if indexed by one of its
+own field names.  For example
+
+ at example
+ at group
+x.a
+     @result{}
+        ans = string1
+        ans = string2
+ at end group
+ at end example
+
+Here is another example, using this comma separated list on the
+left-hand side of an assignment:
+
+ at example
+ at group
+[x.a] = deal("new string1", "new string2");
+ x(1).a
+     @result{} ans = new string1
+ x(2).a
+     @result{} ans = new string2
+ at end group
+ at end example
+
+Just as for numerical arrays, it is possible to use vectors as indices (@pxref{Index Expressions}):
+
+ at example
+ at group
+x(3:4) = x(1:2);
+[x([1,3]).a] = deal("other string1", "other string2");
+x.a
+     @result{}
+        ans = other string1
+        ans = new string2
+        ans = other string2
+        ans = new string2
+ at end group
+ at end example
+
+The function @code{size} will return the size of the structure.  For
+the example above
+
+ at example
+ at group
+size(x)
+     @result{} ans =
+
+          1   4
+ at end group
+ at end example
+
+Elements can be deleted from a structure array in a similar manner to a
+numerical array, by assigning the elements to an empty matrix.  For
+example
+
+ at example
+in = struct ("call1", @{x, Inf, "last"@}, 
+             "call2", @{x, Inf, "first"@})
+     @result{} in =
+        @{
+          1x3 struct array containing the fields:
+
+            call1
+            call2
+        @}
+
+in(1) = [];
+in.call1
+     @result{}
+       ans = Inf
+       ans = last
+ at end example
+
+ at node Creating Structures
+ at subsection Creating Structures
+
+As well as indexing a structure with ".", Octave can create a structure
+with the @code{struct} command.  @code{struct} takes pairs of arguments,
+where the first argument in the pair is the fieldname to include in the
+structure and the second is a scalar or cell array, representing the
+values to include in the structure or structure array.  For example
+
+ at example
+ at group
+struct ("field1", 1, "field2", 2)
+ at result{} ans =
+      @{
+        field1 =  1
+        field2 =  2
+      @}
+ at end group
+ at end example
+
+If the values passed to @code{struct} are a mix of scalar and cell
+arrays, then the scalar arguments are expanded to create a 
+structure array with a consistent dimension.  For example
+
+ at example
+s = struct ("field1", @{1, "one"@}, "field2", @{2, "two"@},
+        "field3", 3);
+s.field1
+     @result{} 
+        ans =  1
+        ans = one
+
+s.field2
+     @result{}
+        ans =  2
+        ans = two
+
+s.field3
+     @result{}
+        ans =  3
+        ans =  3
+ at end example
+
+If you want to create a struct which contains a cell array as an
+individual field, you have to put it into another cell array like in
+the following example:
+
+ at example
+struct ("field1", @{@{1, "one"@}@}, "field2", 2)
+     @result{} ans =
+        @{
+          field1 =
+        
+        @{
+          [1,1] =  1
+          [1,2] = one
+        @}
+        
+          field2 =  2
+        @}
+ @end example       
+
+ at c ov-struct.cc
+ at anchor{doc-struct}
+ at deftypefn {Built-in Function} {} struct ("field", @var{value}, "field", @var{value}, @dots{})
+
+Create a structure and initialize its value.
+
+If the values are cell arrays, create a structure array and initialize
+its values.  The dimensions of each cell array of values must match.
+Singleton cells and non-cell values are repeated so that they fill
+the entire array.  If the cells are empty, create an empty structure
+array with the specified field names.
+
+If the argument is an object, return the underlying struct.
+ at end deftypefn
+
+
+The function @code{isstruct} can be used to test if an object is a
+structure or a structure array.
+
+ at c ov-struct.cc
+ at anchor{doc-isstruct}
+ at deftypefn {Built-in Function} {} isstruct (@var{expr})
+Return 1 if the value of the expression @var{expr} is a structure.
+ at end deftypefn
+
+
+ at node Manipulating Structures
+ at subsection Manipulating Structures
+
+Other functions that can manipulate the fields of a structure are given below.
+
+ at c ov-struct.cc
+ at anchor{doc-rmfield}
+ at deftypefn {Built-in Function} {} rmfield (@var{s}, @var{f})
+Remove field @var{f} from the structure @var{s}.  If @var{f} is a
+cell array of character strings or a character array, remove the
+named fields.
+ at seealso{@ref{doc-cellstr,,cellstr}, @ref{doc-iscellstr,,iscellstr}, @ref{doc-setfield,,setfield}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/setfield.m
+ at anchor{doc-setfield}
+ at deftypefn {Function File} {[@var{k1}, @dots{}, @var{v1}] =} setfield (@var{s}, @var{k1}, @var{v1}, @dots{})
+Set field members in a structure.
+
+ at example
+ at group
+oo(1,1).f0 = 1;
+oo = setfield (oo, @{1,2@}, "fd", @{3@}, "b", 6);
+oo(1,2).fd(3).b == 6
+ at result{} ans = 1
+ at end group
+ at end example
+
+Note that this function could be written
+
+ at example
+ at group
+i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4 = "b";
+oo(i1@{:@}).(i2)(i3@{:@}).(i4) == 6;
+ at end group
+ at end example
+ at seealso{@ref{doc-getfield,,getfield}, @ref{doc-rmfield,,rmfield}, @ref{doc-isfield,,isfield}, @ref{doc-isstruct,,isstruct}, @ref{doc-fieldnames,,fieldnames}, @ref{doc-struct,,struct}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/orderfields.m
+ at anchor{doc-orderfields}
+ at deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2})
+Return a struct with fields arranged alphabetically or as specified
+by @var{s2} and a corresponding permutation vector.
+
+Given one struct, arrange field names in @var{s1} alphabetically.
+
+Given two structs, arrange field names in @var{s1} as they appear
+in @var{s2}.  The second argument may also specify the order in
+a permutation vector or a cell array of strings.
+
+ at seealso{@ref{doc-getfield,,getfield}, @ref{doc-rmfield,,rmfield}, @ref{doc-isfield,,isfield}, @ref{doc-isstruct,,isstruct}, @ref{doc-fieldnames,,fieldnames}, @ref{doc-struct,,struct}}
+ at end deftypefn
+
+
+ at c ov-struct.cc
+ at anchor{doc-fieldnames}
+ at deftypefn {Built-in Function} {} fieldnames (@var{struct})
+Return a cell array of strings naming the elements of the structure
+ at var{struct}.  It is an error to call @code{fieldnames} with an
+argument that is not a structure.
+ at end deftypefn
+
+
+ at c ov-struct.cc
+ at anchor{doc-isfield}
+ at deftypefn {Built-in Function} {} isfield (@var{expr}, @var{name})
+Return true if the expression @var{expr} is a structure and it includes an
+element named @var{name}.  The first argument must be a structure and
+the second must be a string.
+ at end deftypefn
+
+
+ at c ./miscellaneous/getfield.m
+ at anchor{doc-getfield}
+ at deftypefn {Function File} {[@var{v1}, @dots{}] =} getfield (@var{s}, @var{key}, @dots{}) 
+Extract fields from a structure.  For example
+
+ at example
+ at group
+ss(1,2).fd(3).b = 5;
+getfield (ss, @{1,2@}, "fd", @{3@}, "b")
+ at result{} ans = 5
+ at end group
+ at end example
+
+Note that the function call in the previous example is equivalent to
+the expression
+
+ at example
+ at group
+i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4= "b";
+ss(i1@{:@}).(i2)(i3@{:@}).(i4)
+ at end group
+ at end example
+ at seealso{@ref{doc-setfield,,setfield}, @ref{doc-rmfield,,rmfield}, @ref{doc-isfield,,isfield}, @ref{doc-isstruct,,isstruct}, @ref{doc-fieldnames,,fieldnames}, @ref{doc-struct,,struct}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/substruct.m
+ at anchor{doc-substruct}
+ at deftypefn {Function File} {} substruct (@var{type}, @var{subs}, @dots{})
+Create a subscript structure for use with @code{subsref} or
+ at code{subsasgn}.
+ at seealso{@ref{doc-subsref,,subsref}, @ref{doc-subsasgn,,subsasgn}}
+ at end deftypefn
+
+
+ at node Processing Data in Structures
+ at subsection Processing Data in Structures
+
+The simplest way to process data in a structure is within a @code{for}
+loop (@pxref{Looping Over Structure Elements}).  A similar effect can be
+achieved with the @code{structfun} function, where a user defined
+function is applied to each field of the structure.
+
+ at c ./general/structfun.m
+ at anchor{doc-structfun}
+ at deftypefn {Function File} {} structfun (@var{func}, @var{s})
+ at deftypefnx {Function File} {[@var{a}, @var{b}] =} structfun (@dots{})
+ at deftypefnx {Function File} {} structfun (@dots{}, "ErrorHandler", @var{errfunc})
+ at deftypefnx {Function File} {} structfun (@dots{}, "UniformOutput", @var{val})
+
+Evaluate the function named @var{name} on the fields of the structure
+ at var{s}.  The fields of @var{s} are passed to the function @var{func}
+individually.
+
+ at code{structfun} accepts an arbitrary function @var{func} in the form of 
+an inline function, function handle, or the name of a function (in a 
+character string).  In the case of a character string argument, the 
+function must accept a single argument named @var{x}, and it must return 
+a string value.  If the function returns more than one argument, they are
+returned as separate output variables.
+
+If the parameter "UniformOutput" is set to true (the default), then the function
+must return a single element which will be concatenated into the
+return value.  If "UniformOutput" is false, the outputs placed in a structure
+with the same fieldnames as the input structure.
+
+ at example
+ at group
+s.name1 = "John Smith"; 
+s.name2 = "Jill Jones"; 
+structfun (@@(x) regexp (x, '(\w+)$', "matches")@{1@}, s, 
+           "UniformOutput", false)
+ at end group
+ at end example
+
+Given the parameter "ErrorHandler", then @var{errfunc} defines a function to
+call in case @var{func} generates an error.  The form of the function is
+
+ at example
+function [@dots{}] = errfunc (@var{se}, @dots{})
+ at end example
+
+where there is an additional input argument to @var{errfunc} relative to
+ at var{func}, given by @var{se}.  This is a structure with the elements
+"identifier", "message" and "index", giving respectively the error
+identifier, the error message, and the index into the input arguments
+of the element that caused the error.
+ at seealso{@ref{doc-cellfun,,cellfun}, @ref{doc-arrayfun,,arrayfun}}
+ at end deftypefn
+
+
+Alternatively, to process the data in a structure, the structure might
+be converted to another type of container before being treated.
+
+ at c ov-cell.cc
+ at anchor{doc-struct2cell}
+ at deftypefn {Built-in Function} {} struct2cell (@var{S})
+Create a new cell array from the objects stored in the struct object.
+If @var{f} is the number of fields in the structure, the resulting
+cell array will have a dimension vector corresponding to
+ at code{[@var{F} size(@var{S})]}.
+ at seealso{@ref{doc-cell2struct,,cell2struct}, @ref{doc-fieldnames,,fieldnames}}
+ at end deftypefn
+
+
+ at node Cell Arrays
+ at section Cell Arrays
+ at cindex cell arrays
+
+It can be both necessary and convenient to store several variables of
+different size or type in one variable.  A cell array is a container
+class able to do just that.  In general cell arrays work just like
+ at math{N}-dimensional arrays with the exception of the use of @samp{@{}
+and @samp{@}} as allocation and indexing operators.
+
+ at menu
+* Basic Usage of Cell Arrays::
+* Creating Cell Arrays::
+* Indexing Cell Arrays::
+* Cell Arrays of Strings::
+* Processing Data in Cell Arrays::
+ at end menu
+
+ at node Basic Usage of Cell Arrays
+ at subsection Basic Usage of Cell Arrays
+
+As an example, the following code creates a cell array containing a
+string and a 2-by-2 random matrix
+
+ at example
+c = @{"a string", rand(2, 2)@};
+ at end example
+
+ at noindent
+To access the elements of a cell array, it can be indexed with the @{
+and @} operators.  Thus, the variable created in the previous example
+can be indexed like this:
+
+ at example
+ at group
+c@{1@}
+     @result{} ans = a string
+ at end group
+ at end example
+
+ at noindent
+As with numerical arrays several elements of a cell array can be
+extracted by indexing with a vector of indexes
+
+ at example
+ at group
+c@{1:2@}
+     @result{} ans =
+          
+          (,
+            [1] = a string
+            [2] =
+          
+               0.593993   0.627732
+               0.377037   0.033643
+          
+          ,)
+ at end group
+ at end example
+
+The indexing operators can also be used to insert or overwrite elements
+of a cell array.  The following code inserts the scalar 3 on the
+third place of the previously created cell array
+
+ at example
+ at group
+c@{3@} = 3
+     @result{} c =
+         
+         @{
+           [1,1] = a string
+           [1,2] =
+         
+              0.593993   0.627732
+              0.377037   0.033643
+         
+           [1,3] =  3
+         @}
+ at end group
+ at end example
+
+Details on indexing cell arrays are explained in @ref{Indexing Cell Arrays}.
+
+In general nested cell arrays are displayed hierarchically as in the
+previous example.  In some circumstances it makes sense to reference
+them by their index, and this can be performed by the @code{celldisp}
+function.
+
+ at c ./general/celldisp.m
+ at anchor{doc-celldisp}
+ at deftypefn {Function File} {} celldisp (@var{c}, @var{name})
+Recursively display the contents of a cell array.  By default the values
+are displayed with the name of the variable @var{c}.  However, this name
+can be replaced with the variable @var{name}.
+ at seealso{@ref{doc-disp,,disp}}
+ at end deftypefn
+
+
+To test if an object is a cell array, use the @code{iscell}
+function. For example:
+
+ at example
+ at group
+iscell(c)
+     @result{} ans = 1
+
+iscell(3)
+     @result{} ans = 0
+
+ at end group
+ at end example
+
+ at c ov-cell.cc
+ at anchor{doc-iscell}
+ at deftypefn {Built-in Function} {} iscell (@var{x})
+Return true if @var{x} is a cell array object.  Otherwise, return
+false.
+ at end deftypefn
+
+
+ at node Creating Cell Arrays
+ at subsection Creating Cell Array
+
+The introductory example (@pxref{Basic Usage of Cell Arrays}) showed
+how to create a cell array containing currently available variables.
+In many situations, however, it is useful to create a cell array and
+then fill it with data. 
+
+The @code{cell} function returns a cell array of a given size, containing
+empty matrices.  This function is similar to the @code{zeros}
+function for creating new numerical arrays.  The following example creates
+a 2-by-2 cell array containing empty matrices
+
+ at example
+ at group
+c = cell(2,2)
+     @result{} c =
+         
+         @{
+           [1,1] = [](0x0)
+           [2,1] = [](0x0)
+           [1,2] = [](0x0)
+           [2,2] = [](0x0)
+         @}
+ at end group
+ at end example
+
+Just like numerical arrays, cell arrays can be multidimensional.  The
+ at code{cell} function accepts any number of positive integers to describe
+the size of the returned cell array.  It is also possible to set the size
+of the cell array through a vector of positive integers.  In the
+following example two cell arrays of equal size are created, and the size
+of the first one is displayed
+
+ at example
+ at group
+c1 = cell(3, 4, 5);
+c2 = cell( [3, 4, 5] );
+size(c1)
+     @result{} ans =
+         3   4   5
+ at end group
+ at end example
+
+ at noindent
+As can be seen, the @ref{doc-size, @code{size}} function also works
+for cell arrays.  As do other functions describing the size of an
+object, such as @ref{doc-length, @code{length}}, @ref{doc-numel,
+ at code{numel}}, @ref{doc-rows, @code{rows}}, and @ref{doc-columns,
+ at code{columns}}.
+
+ at c ov-cell.cc
+ at anchor{doc-cell}
+ at deftypefn {Built-in Function} {} cell (@var{x})
+ at deftypefnx {Built-in Function} {} cell (@var{n}, @var{m})
+Create a new cell array object.  If invoked with a single scalar
+argument, @code{cell} returns a square cell array with the dimension
+specified.  If you supply two scalar arguments, @code{cell} takes
+them to be the number of rows and columns.  If given a vector with two
+elements, @code{cell} uses the values of the elements as the number of
+rows and columns, respectively.
+ at end deftypefn
+
+
+As an alternative to creating empty cell arrays, and then filling them, it
+is possible to convert numerical arrays into cell arrays using the
+ at code{num2cell} and @code{mat2cell} functions.
+
+ at c ./DLD-FUNCTIONS/cellfun.cc
+ at anchor{doc-num2cell}
+ at deftypefn  {Loadable Function} {@var{c} =} num2cell (@var{m})
+ at deftypefnx {Loadable Function} {@var{c} =} num2cell (@var{m}, @var{dim})
+Convert the matrix @var{m} to a cell array.  If @var{dim} is defined, the
+value @var{c} is of dimension 1 in this dimension and the elements of
+ at var{m} are placed in slices in @var{c}.
+ at seealso{@ref{doc-mat2cell,,mat2cell}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/cellfun.cc
+ at anchor{doc-mat2cell}
+ at deftypefn {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{m}, @var{n})
+ at deftypefnx {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{d1}, @var{d2}, @dots{})
+ at deftypefnx {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{r})
+Convert the matrix @var{a} to a cell array.  If @var{a} is 2-D, then
+it is required that @code{sum (@var{m}) == size (@var{a}, 1)} and
+ at code{sum (@var{n}) == size (@var{a}, 2)}.  Similarly, if @var{a} is
+a multi-dimensional and the number of dimensional arguments is equal
+to the dimensions of @var{a}, then it is required that @code{sum (@var{di})
+== size (@var{a}, i)}.
+
+Given a single dimensional argument @var{r}, the other dimensional
+arguments are assumed to equal @code{size (@var{a}, at var{i})}.
+
+An example of the use of mat2cell is
+
+ at example
+mat2cell (reshape(1:16,4,4),[3,1],[3,1])
+ at result{} @{
+  [1,1] =
+
+     1   5   9
+     2   6  10
+     3   7  11
+
+  [2,1] =
+
+     4   8  12
+
+  [1,2] =
+
+    13
+    14
+    15
+
+  [2,2] = 16
+@}
+ at end example
+ at seealso{@ref{doc-num2cell,,num2cell}, @ref{doc-cell2mat,,cell2mat}}
+ at end deftypefn
+
+
+ at node Indexing Cell Arrays
+ at subsection Indexing Cell Arrays
+
+As shown in @pxref{Basic Usage of Cell Arrays} elements can be
+extracted from cell arrays using the @samp{@{} and @samp{@}}
+operators.  If you want to extract or access subarrays which are still 
+cell arrays, you need to use the @samp{(} and @samp{)} operators. The
+following example illustrates the difference:
+
+ at example
+ at group
+c = @{"1", "2", "3"; "a", "b", "c"; "4", "5", "6"@};
+c@{2,3@}
+     @result{} ans = c
+
+c(2,3)
+     @result{} ans = 
+        @{
+          [1,1] = c
+        @}
+ at end group
+ at end example
+
+ at noindent So with @samp{@{@}} you access elements of a cell
+array, while with @samp{()} you access a sub array of a cell
+array.
+
+Using the @samp{(} and @samp{)} operators, indexing works for cell
+arrays like for multidimensional arrays.  As an example, all the rows
+of the first and third column of a cell array can be set to @code{0}
+with the following command:
+
+ at example
+ at group
+c(:, [1, 3]) = @{0@}
+     @result{}  =
+        @{
+          [1,1] = 0
+          [2,1] = 0
+          [3,1] = 0
+          [1,2] = 2
+          [2,2] =  10
+          [3,2] =  20
+          [1,3] = 0
+          [2,3] = 0
+          [3,3] = 0
+        @}
+ at end group
+ at end example
+
+Note, that the above can also be achieved like this:
+
+ at example
+c(:, [1, 3]) = 0;
+ at end example
+
+ at noindent Here, the scalar @samp{0} is automatically promoted to 
+cell array @samp{@{0@}} and then assigned to the subarray of @code{c}.
+
+To give another example for indexing cell arrays with @samp{()}, you
+can exchange the first and the second row of a cell array as in the
+following command: 
+
+ at example
+ at group
+c = @{1, 2, 3; 4, 5, 6@};
+c([1, 2], :) = c([2, 1], :)
+     @result{} = 
+        @{
+          [1,1] =  4
+          [2,1] =  1
+          [1,2] =  5
+          [2,2] =  2
+          [1,3] =  6
+          [2,3] =  3
+        @}
+ at end group
+ at end example
+
+Accessing multiple elements of a cell array with the @samp{@{} and
+ at samp{@}} operators will result in a comma-separated list of all the
+requested elements (@pxref{Comma Separated Lists}). Using the
+ at samp{@{} and @samp{@}} operators the first two rows in the above
+example can be swapped back like this:
+
+ at example
+ at group
+[c@{[1,2], :@}] = deal(c@{[2, 1], :@})
+     @result{} = 
+        @{
+          [1,1] =  1
+          [2,1] =  4
+          [1,2] =  2
+          [2,2] =  5
+          [1,3] =  3
+          [2,3] =  6
+        @}
+ at end group
+ at end example
+
+As for struct arrays and numerical arrays, the empty matrix @samp{[]}
+can be used to delete elements from a cell array:
+
+ at example
+ at group
+x = @{"1", "2"; "3", "4"@};
+x(1, :) = []
+     @result{} x =
+        @{
+          [1,1] = 3
+          [1,2] = 4
+        @}
+ at end group
+ at end example
+
+The following example shows how to just remove the contents of cell
+array elements but not delete the space for them:
+
+ at example
+ at group
+x = @{"1", "2"; "3", "4"@};
+x@{1, :@} = []
+ at result{} x =
+      @{
+        [1,1] = [](0x0)
+        [2,1] = 3
+        [1,2] = [](0x0)
+        [2,2] = 4
+      @}
+ at end group
+ at end example
+
+ at node Cell Arrays of Strings
+ at subsection Cell Arrays of Strings
+
+One common use of cell arrays is to store multiple strings in the same
+variable.  It is also possible to store multiple strings in a
+character matrix by letting each row be a string.  This, however,
+introduces the problem that all strings must be of equal length.
+Therefore, it is recommended to use cell arrays to store multiple
+strings.  For cases, where the character matrix representation is required
+for an operation, there are several functions that convert a cell
+array of strings to a character array and back.  @code{char} and
+ at code{strvcat} convert cell arrays to a character array
+(@pxref{Concatenating Strings}), while the function @code{cellstr}
+converts a character array to a cell array of strings: 
+
+ at example
+ at group
+a = ["hello"; "world"];
+c = cellstr (a)
+     @result{} c =
+         @{
+           [1,1] = hello
+           [2,1] = world
+         @}
+ at end group
+ at end example
+
+ at c ov-cell.cc
+ at anchor{doc-cellstr}
+ at deftypefn {Built-in Function} {} cellstr (@var{string})
+Create a new cell array object from the elements of the string
+array @var{string}.
+ at end deftypefn
+
+
+One further advantage of using cell arrays to store multiple strings is
+that most functions for string manipulations included with Octave
+support this representation.  As an example, it is possible to compare
+one string with many others using the @code{strcmp} function.  If one of
+the arguments to this function is a string and the other is a cell array
+of strings, each element of the cell array will be compared to the string
+argument:
+
+ at example
+ at group
+c = @{"hello", "world"@};
+strcmp ("hello", c)
+     @result{} ans =
+        1   0
+ at end group
+ at end example
+
+ at noindent
+The following string functions support cell arrays of strings:
+ at code{char}, @code{strvcat}, @code{strcat} (@pxref{Concatenating
+Strings}), @code{strcmp}, @code{strncmp}, @code{strcmpi},
+ at code{strncmpi} (@pxref{Comparing Strings}), @code{str2double},
+ at code{deblank}, @code{strtrim}, @code{strtrunc}, @code{strfind},
+ at code{strmatch}, , @code{regexp}, @code{regexpi} (@pxref{Manipulating 
+Strings}) and @code{str2double} (@pxref{String Conversions}).
+
+The function @code{iscellstr} can be used to test if an object is a
+cell array of strings.
+
+ at c ov-cell.cc
+ at anchor{doc-iscellstr}
+ at deftypefn {Built-in Function} {} iscellstr (@var{cell})
+Return true if every element of the cell array @var{cell} is a
+character string
+ at end deftypefn
+
+
+ at c ./general/cellidx.m
+ at anchor{doc-cellidx}
+ at deftypefn {Function File} {[@var{idxvec}, @var{errmsg}] =} cellidx (@var{listvar}, @var{strlist})
+Return indices of string entries in @var{listvar} that match strings
+in @var{strlist}.
+
+Both @var{listvar} and @var{strlist} may be passed as strings or
+string matrices.  If they are passed as string matrices, each entry
+is processed by @code{deblank} prior to searching for the entries.
+
+The first output is the vector of indices in @var{listvar}.
+
+If @var{strlist} contains a string not in @var{listvar}, then
+an error message is returned in @var{errmsg}.  If only one output
+argument is requested, then @var{cellidx} prints @var{errmsg} to the
+screen and exits with an error.
+ at end deftypefn
+
+
+ at node Processing Data in Cell Arrays
+ at subsection Processing Data in Cell Arrays
+
+Data that is stored in a cell array can be processed in several ways
+depending on the actual data.  The simplest way to process that data
+is to iterate through it using one or more @code{for} loops.  The same
+idea can be implemented more easily through the use of the @code{cellfun}
+function that calls a user-specified function on all elements of a cell
+array.
+
+ at c ./DLD-FUNCTIONS/cellfun.cc
+ at anchor{doc-cellfun}
+ at deftypefn {Loadable Function} {} cellfun (@var{name}, @var{c})
+ at deftypefnx {Loadable Function} {} cellfun ("size", @var{c}, @var{k})
+ at deftypefnx {Loadable Function} {} cellfun ("isclass", @var{c}, @var{class})
+ at deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c})
+ at deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c}, @var{d})
+ at deftypefnx {Loadable Function} {[@var{a}, @var{b}] =} cellfun (@dots{})
+ at deftypefnx {Loadable Function} {} cellfun (@dots{}, 'ErrorHandler', @var{errfunc})
+ at deftypefnx {Loadable Function} {} cellfun (@dots{}, 'UniformOutput', @var{val})
+
+Evaluate the function named @var{name} on the elements of the cell array
+ at var{c}.  Elements in @var{c} are passed on to the named function
+individually.  The function @var{name} can be one of the functions
+
+ at table @code
+ at item isempty
+Return 1 for empty elements.
+ at item islogical
+Return 1 for logical elements.
+ at item isreal
+Return 1 for real elements.
+ at item length
+Return a vector of the lengths of cell elements.
+ at item ndims
+Return the number of dimensions of each element.
+ at item prodofsize
+Return the product of dimensions of each element.
+ at item size
+Return the size along the @var{k}-th dimension.
+ at item isclass
+Return 1 for elements of @var{class}.
+ at end table
+
+Additionally, @code{cellfun} accepts an arbitrary function @var{func}
+in the form of an inline function, function handle, or the name of a
+function (in a character string).  In the case of a character string
+argument, the function must accept a single argument named @var{x}, and
+it must return a string value.  The function can take one or more arguments,
+with the inputs args given by @var{c}, @var{d}, etc.  Equally the function
+can return one or more output arguments.  For example
+
+ at example
+ at group
+cellfun (@@atan2, @{1, 0@}, @{0, 1@})
+ at result{}ans = [1.57080   0.00000]
+ at end group
+ at end example
+
+Note that the default output argument is an array of the same size as the
+input arguments.
+
+If the parameter 'UniformOutput' is set to true (the default), then the function
+must return a single element which will be concatenated into the
+return value.  If 'UniformOutput' is false, the outputs are concatenated in
+a cell array.  For example
+
+ at example
+ at group
+cellfun ("tolower(x)", @{"Foo", "Bar", "FooBar"@},
+         "UniformOutput",false)
+ at result{} ans = @{"foo", "bar", "foobar"@}
+ at end group
+ at end example
+
+Given the parameter 'ErrorHandler', then @var{errfunc} defines a function to
+call in case @var{func} generates an error.  The form of the function is
+
+ at example
+function [@dots{}] = errfunc (@var{s}, @dots{})
+ at end example
+
+where there is an additional input argument to @var{errfunc} relative to
+ at var{func}, given by @var{s}.  This is a structure with the elements
+'identifier', 'message' and 'index', giving respectively the error
+identifier, the error message, and the index into the input arguments
+of the element that caused the error.  For example
+
+ at example
+ at group
+function y = foo (s, x), y = NaN; endfunction
+cellfun (@@factorial, @{-1,2@},'ErrorHandler',@@foo)
+ at result{} ans = [NaN 2]
+ at end group
+ at end example
+
+ at seealso{@ref{doc-isempty,,isempty}, @ref{doc-islogical,,islogical}, @ref{doc-isreal,,isreal}, @ref{doc-length,,length}, @ref{doc-ndims,,ndims}, @ref{doc-numel,,numel}, @ref{doc-size,,size}}
+ at end deftypefn
+
+
+An alternative is to convert the data to a different container, such as
+a matrix or a data structure.  Depending on the data this is possible
+using the @code{cell2mat} and @code{cell2struct} functions.
+
+ at c ./general/cell2mat.m
+ at anchor{doc-cell2mat}
+ at deftypefn {Function File} {@var{m} =} cell2mat (@var{c})
+Convert the cell array @var{c} into a matrix by concatenating all
+elements of @var{c} into a hyperrectangle.  Elements of @var{c} must
+be numeric, logical or char, and @code{cat} must be able to
+concatenate them together.
+ at seealso{@ref{doc-mat2cell,,mat2cell}, @ref{doc-num2cell,,num2cell}}
+ at end deftypefn
+
+
+ at c ov-struct.cc
+ at anchor{doc-cell2struct}
+ at deftypefn {Built-in Function} {} cell2struct (@var{cell}, @var{fields}, @var{dim})
+Convert @var{cell} to a structure.  The number of fields in @var{fields}
+must match the number of elements in @var{cell} along dimension @var{dim},
+that is @code{numel (@var{fields}) == size (@var{cell}, @var{dim})}.
+
+ at example
+ at group
+A = cell2struct (@{'Peter', 'Hannah', 'Robert';
+                   185, 170, 168@},
+                 @{'Name','Height'@}, 1);
+A(1)
+ at result{} ans =
+      @{
+        Height = 185
+        Name   = Peter
+      @}
+
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at node Comma Separated Lists
+ at section Comma Separated Lists
+ at cindex comma separated lists
+ at cindex cs-lists
+
+Comma separated lists @footnote{Comma-separated lists are also sometimes
+informally referred to as @dfn{cs-lists}.} are the basic argument type
+to all Octave functions - both for input and return arguments.  In the
+example
+
+ at example
+max (@var{a}, @var{b})
+ at end example
+
+ at noindent
+ at samp{@var{a}, @var{b}} is a comma separated list.  Comma separated lists
+can appear on both the right and left hand side of an assignment.  For
+example
+
+ at example
+ at group
+x = [1 0 1 0 0 1 1; 0 0 0 0 0 0 7];
+[@var{i}, @var{j}] = find (@var{x}, 2, "last");
+ at end group
+ at end example
+
+ at noindent
+Here, @samp{@var{x}, 2, "last"} is a comma separated list constituting
+the input arguments of @code{find}.  @code{find} returns a comma
+separated list of output arguments which is assigned element by
+element to the comma separated list @samp{@var{i}, @var{j}}.
+
+Another example of where comma separated lists are used is in the
+creation of a new array with @code{[]} (@pxref{Matrices}) or the
+creation of a cell array with @code{@{@}} (@pxref{Basic Usage of Cell
+Arrays}). In the expressions 
+
+ at example
+a = [1, 2, 3, 4];
+c = @{4, 5, 6, 7@};
+ at end example
+
+ at noindent
+both @samp{1, 2, 3, 4} and @samp{4, 5, 6, 7} are comma separated lists.
+
+Comma separated lists cannot be directly manipulated by the
+user.  However, both structure arrays and cell arrays can be converted
+into comma separated lists, and thus used in place of explicitly
+written comma separated lists.  This feature is useful in many ways,
+as will be shown in the following subsections.
+
+ at menu
+* Comma Separated Lists Generated from Cell Arrays::
+* Comma Separated Lists Generated from Structure Arrays::
+ at end menu
+
+ at node Comma Separated Lists Generated from Cell Arrays
+ at subsection Comma Separated Lists Generated from Cell Arrays
+
+As has been mentioned above (@pxref{Indexing Cell Arrays}), elements
+of a cell array can be extracted into a comma separated list with the
+ at code{@{} and @code{@}} operators. By surrounding this list with
+ at code{[} and @code{]}, it can be concatenated into an array. For example:
+
+ at example
+ at group
+a = @{1, [2, 3], 4, 5, 6@};
+b = [a@{1:4@}]
+     @result{} b =
+         1   2   3   4
+ at end group
+ at end example
+
+Similarly, it is possible to create a new cell array containing cell
+elements selected with @code{@{@}}.  By surrounding the list with  
+ at samp{@{} and @samp{@}} a new cell array will be created, as the
+following example illustrates:
+
+ at example
+ at group
+a = @{1, rand(2, 2), "three"@};
+b = @{ a@{ [1, 3] @} @}
+     @result{} b =
+         @{
+           [1,1] =  1
+           [1,2] = three
+         @}
+ at end group
+ at end example
+
+Furthermore, cell elements (accessed by @code{@{@}}) can be passed
+directly to a function.  The list of elements from the cell array will
+be passed as an argument list to a given function as if it is called
+with the elements as individual arguments.  The two calls to
+ at code{printf} in the following example are identical but the latter is
+simpler and can handle cell arrays of an arbitrary size:
+
+ at example
+ at group
+c = @{"GNU", "Octave", "is", "Free", "Software"@};
+printf ("%s ", c@{1@}, c@{2@}, c@{3@}, c@{4@}, c@{5@});
+     @print{} GNU Octave is Free Software 
+printf ("%s ", c@{:@});
+     @print{} GNU Octave is Free Software 
+ at end group
+ at end example
+
+If used on the left-hand side of an assignment, a comma separated list
+generated with @code{@{@}} can be assigned to.  An example is 
+
+ at example
+ at group
+in@{1@} = [10, 20, 30, 40, 50, 60, 70, 80, 90];
+in@{2@} = inf;
+in@{3@} = "last";
+in@{4@} = "first";
+out = cell (4, 1);
+[out@{1:3@}] = find (in@{1 : 3@});
+[out@{4:6@}] = find (in@{[1, 2, 4]@})
+     @result{} out =
+        @{
+          [1,1] = 1
+          [2,1] = 9
+          [3,1] = 90
+          [4,1] = 1
+          [3,1] = 1
+          [4,1] = 10
+        @}
+ at end group
+ at end example
+
+
+ at node Comma Separated Lists Generated from Structure Arrays
+ at subsection Comma Separated Lists Generated from Structure Arrays
+Structure arrays can equally be used to create comma separated
+lists.  This is done by addressing one of the fields of a structure
+array.  For example
+
+ at example
+ at group
+x = ceil (randn (10, 1)); 
+in = struct ("call1", @{x, 3, "last"@}, 
+             "call2", @{x, inf, "first"@});
+out = struct ("call1", cell (2, 1), "call2", cell (2, 1));
+[out.call1] = find (in.call1);
+[out.call2] = find (in.call2);
+ at end group
+ at end example
diff --git a/doc/interpreter/container.txi b/doc/interpreter/container.txi
new file mode 100644
index 0000000..782e640
--- /dev/null
+++ b/doc/interpreter/container.txi
@@ -0,0 +1,994 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Data Containers
+ at chapter Data Containers
+ at cindex containers
+
+Octave includes support for two different mechanisms to contain
+arbitrary data types in the same variable.  Structures, which are C-like,
+and are indexed with named fields, and cell arrays, where each element
+of the array can have a different data type and or shape. Multiple
+input arguments and return values of functions are organized as
+another data container, the comma separated list.
+
+ at menu
+* Data Structures::
+* Cell Arrays::
+* Comma Separated Lists::
+ at end menu
+
+ at node Data Structures
+ at section Data Structures
+ at cindex structures
+ at cindex data structures
+
+Octave includes support for organizing data in structures.  The current
+implementation uses an associative array with indices limited to
+strings, but the syntax is more like C-style structures.  
+
+ at menu
+* Basic Usage and Examples::
+* Structure Arrays::
+* Creating Structures::
+* Manipulating Structures::
+* Processing Data in Structures::
+ at end menu
+
+ at node Basic Usage and Examples
+ at subsection Basic Usage and Examples
+
+Here are some examples of using data structures in Octave.
+
+Elements of structures can be of any value type.  For example, the three
+expressions
+
+ at example
+ at group
+x.a = 1;
+x.b = [1, 2; 3, 4];
+x.c = "string";
+ at end group
+ at end example
+
+ at noindent
+create a structure with three elements.  To print the value of the
+structure, you can type its name, just as for any other variable:
+
+ at example
+ at group
+x
+     @result{} x =
+        @{
+          a = 1
+          b =
+
+            1  2
+            3  4
+
+          c = string
+        @}
+ at end group
+ at end example
+
+ at noindent
+Note that Octave may print the elements in any order.
+
+Structures may be copied just like any other variable:
+
+ at example
+ at group
+y = x
+     @result{} y =
+        @{
+          a = 1
+          b =
+
+            1  2
+            3  4
+
+          c = string
+        @}
+ at end group
+ at end example
+
+Since structures are themselves values, structure elements may reference
+other structures.  The following statements change the value of the
+element @code{b} of the structure @code{x} to be a data structure
+containing the single element @code{d}, which has a value of 3.
+
+ at example
+ at group
+x.b.d = 3;
+x.b
+     @result{} ans =
+        @{
+          d = 3
+        @}
+
+x
+     @result{} x =
+        @{
+          a = 1
+          b =
+          @{
+            d = 3
+          @}
+
+          c = string
+        @}
+ at end group
+ at end example
+
+Note that when Octave prints the value of a structure that contains
+other structures, only a few levels are displayed.  For example,
+
+ at example
+ at group
+a.b.c.d.e = 1;
+a
+     @result{} a =
+        @{
+          b =
+          @{
+            c =
+            @{
+              1x1 struct array containing the fields:
+
+              d: 1x1 struct
+            @}
+          @}
+        @}
+ at end group
+ at end example
+
+ at noindent
+This prevents long and confusing output from large deeply nested
+structures. The number of levels to print for nested structures can be
+set with the function @code{struct_levels_to_print}:
+
+ at DOCSTRING(struct_levels_to_print)
+
+Functions can return structures.  For example, the following function
+separates the real and complex parts of a matrix and stores them in two
+elements of the same structure variable.
+
+ at example
+ at group
+function y = f (x)
+  y.re = real (x);
+  y.im = imag (x);
+endfunction
+ at end group
+ at end example
+
+When called with a complex-valued argument, @code{f} returns the data
+structure containing the real and imaginary parts of the original
+function argument.
+
+ at example
+ at group
+f (rand (2) + rand (2) * I)
+     @result{} ans =
+        @{
+          im =
+
+            0.26475  0.14828
+            0.18436  0.83669
+
+          re =
+
+            0.040239  0.242160
+            0.238081  0.402523
+
+        @}
+ at end group
+ at end example
+
+Function return lists can include structure elements, and they may be
+indexed like any other variable.  For example,
+
+ at example
+ at group
+[ x.u, x.s(2:3,2:3), x.v ] = svd ([1, 2; 3, 4]);
+x
+     @result{} x =
+        @{
+          u =
+
+            -0.40455  -0.91451
+            -0.91451   0.40455
+
+          s =
+
+             0.00000   0.00000   0.00000
+             0.00000   5.46499   0.00000
+             0.00000   0.00000   0.36597
+
+          v =
+
+            -0.57605   0.81742
+            -0.81742  -0.57605
+
+        @}
+ at end group
+ at end example
+
+It is also possible to cycle through all the elements of a structure in
+a loop, using a special form of the @code{for} statement
+(@pxref{Looping Over Structure Elements}).
+
+ at node Structure Arrays
+ at subsection Structure Arrays
+
+A structure array is a particular instance of a structure, where each of
+the fields of the structure is represented by a cell array.  Each of
+these cell arrays has the same dimensions. Conceptually, a structure
+array can also be seen as an array of structures with identical
+fields.  An example of the creation of a structure array is
+
+ at example
+ at group
+x(1).a = "string1";
+x(2).a = "string2";
+x(1).b = 1;
+x(2).b = 2;
+ at end group
+ at end example
+
+ at noindent
+which creates a 2-by-1 structure array with two fields.  Another way
+to create a structure array is with the @code{struct} function
+(@pxref{Creating Structures}).  As previously, to print the value of
+the structure array, you can type its name: 
+
+ at example
+ at group
+x
+     @result{} x =
+        @{
+          1x2 struct array containing the fields:
+
+            a
+            b
+        @}  
+ at end group
+ at end example
+
+Individual elements of the structure array can be returned by indexing
+the variable like @code{@var{x}(1)}, which returns a structure with 
+two fields:
+
+ at example
+ at group
+x(1)
+     @result{} ans =
+        @{
+          a = string1
+          b =  1
+        @}
+ at end group
+ at end example
+
+Furthermore, the structure array can return a comma separated list of
+field values (@pxref{Comma Separated Lists}), if indexed by one of its
+own field names.  For example
+
+ at example
+ at group
+x.a
+     @result{}
+        ans = string1
+        ans = string2
+ at end group
+ at end example
+
+Here is another example, using this comma separated list on the
+left-hand side of an assignment:
+
+ at example
+ at group
+[x.a] = deal("new string1", "new string2");
+ x(1).a
+     @result{} ans = new string1
+ x(2).a
+     @result{} ans = new string2
+ at end group
+ at end example
+
+Just as for numerical arrays, it is possible to use vectors as indices (@pxref{Index Expressions}):
+
+ at example
+ at group
+x(3:4) = x(1:2);
+[x([1,3]).a] = deal("other string1", "other string2");
+x.a
+     @result{}
+        ans = other string1
+        ans = new string2
+        ans = other string2
+        ans = new string2
+ at end group
+ at end example
+
+The function @code{size} will return the size of the structure.  For
+the example above
+
+ at example
+ at group
+size(x)
+     @result{} ans =
+
+          1   4
+ at end group
+ at end example
+
+Elements can be deleted from a structure array in a similar manner to a
+numerical array, by assigning the elements to an empty matrix.  For
+example
+
+ at example
+in = struct ("call1", @{x, Inf, "last"@}, 
+             "call2", @{x, Inf, "first"@})
+     @result{} in =
+        @{
+          1x3 struct array containing the fields:
+
+            call1
+            call2
+        @}
+
+in(1) = [];
+in.call1
+     @result{}
+       ans = Inf
+       ans = last
+ at end example
+
+ at node Creating Structures
+ at subsection Creating Structures
+
+As well as indexing a structure with ".", Octave can create a structure
+with the @code{struct} command.  @code{struct} takes pairs of arguments,
+where the first argument in the pair is the fieldname to include in the
+structure and the second is a scalar or cell array, representing the
+values to include in the structure or structure array.  For example
+
+ at example
+ at group
+struct ("field1", 1, "field2", 2)
+ at result{} ans =
+      @{
+        field1 =  1
+        field2 =  2
+      @}
+ at end group
+ at end example
+
+If the values passed to @code{struct} are a mix of scalar and cell
+arrays, then the scalar arguments are expanded to create a 
+structure array with a consistent dimension.  For example
+
+ at example
+s = struct ("field1", @{1, "one"@}, "field2", @{2, "two"@},
+        "field3", 3);
+s.field1
+     @result{} 
+        ans =  1
+        ans = one
+
+s.field2
+     @result{}
+        ans =  2
+        ans = two
+
+s.field3
+     @result{}
+        ans =  3
+        ans =  3
+ at end example
+
+If you want to create a struct which contains a cell array as an
+individual field, you have to put it into another cell array like in
+the following example:
+
+ at example
+struct ("field1", @{@{1, "one"@}@}, "field2", 2)
+     @result{} ans =
+        @{
+          field1 =
+        
+        @{
+          [1,1] =  1
+          [1,2] = one
+        @}
+        
+          field2 =  2
+        @}
+ @end example       
+
+ at DOCSTRING(struct)
+
+The function @code{isstruct} can be used to test if an object is a
+structure or a structure array.
+
+ at DOCSTRING(isstruct)
+
+ at node Manipulating Structures
+ at subsection Manipulating Structures
+
+Other functions that can manipulate the fields of a structure are given below.
+
+ at DOCSTRING(rmfield)
+
+ at DOCSTRING(setfield)
+
+ at DOCSTRING(orderfields)
+
+ at DOCSTRING(fieldnames)
+
+ at DOCSTRING(isfield)
+
+ at DOCSTRING(getfield)
+
+ at DOCSTRING(substruct)
+
+ at node Processing Data in Structures
+ at subsection Processing Data in Structures
+
+The simplest way to process data in a structure is within a @code{for}
+loop (@pxref{Looping Over Structure Elements}).  A similar effect can be
+achieved with the @code{structfun} function, where a user defined
+function is applied to each field of the structure.
+
+ at DOCSTRING(structfun)
+
+Alternatively, to process the data in a structure, the structure might
+be converted to another type of container before being treated.
+
+ at DOCSTRING(struct2cell)
+
+ at node Cell Arrays
+ at section Cell Arrays
+ at cindex cell arrays
+
+It can be both necessary and convenient to store several variables of
+different size or type in one variable.  A cell array is a container
+class able to do just that.  In general cell arrays work just like
+ at math{N}-dimensional arrays with the exception of the use of @samp{@{}
+and @samp{@}} as allocation and indexing operators.
+
+ at menu
+* Basic Usage of Cell Arrays::
+* Creating Cell Arrays::
+* Indexing Cell Arrays::
+* Cell Arrays of Strings::
+* Processing Data in Cell Arrays::
+ at end menu
+
+ at node Basic Usage of Cell Arrays
+ at subsection Basic Usage of Cell Arrays
+
+As an example, the following code creates a cell array containing a
+string and a 2-by-2 random matrix
+
+ at example
+c = @{"a string", rand(2, 2)@};
+ at end example
+
+ at noindent
+To access the elements of a cell array, it can be indexed with the @{
+and @} operators.  Thus, the variable created in the previous example
+can be indexed like this:
+
+ at example
+ at group
+c@{1@}
+     @result{} ans = a string
+ at end group
+ at end example
+
+ at noindent
+As with numerical arrays several elements of a cell array can be
+extracted by indexing with a vector of indexes
+
+ at example
+ at group
+c@{1:2@}
+     @result{} ans =
+          
+          (,
+            [1] = a string
+            [2] =
+          
+               0.593993   0.627732
+               0.377037   0.033643
+          
+          ,)
+ at end group
+ at end example
+
+The indexing operators can also be used to insert or overwrite elements
+of a cell array.  The following code inserts the scalar 3 on the
+third place of the previously created cell array
+
+ at example
+ at group
+c@{3@} = 3
+     @result{} c =
+         
+         @{
+           [1,1] = a string
+           [1,2] =
+         
+              0.593993   0.627732
+              0.377037   0.033643
+         
+           [1,3] =  3
+         @}
+ at end group
+ at end example
+
+Details on indexing cell arrays are explained in @ref{Indexing Cell Arrays}.
+
+In general nested cell arrays are displayed hierarchically as in the
+previous example.  In some circumstances it makes sense to reference
+them by their index, and this can be performed by the @code{celldisp}
+function.
+
+ at DOCSTRING(celldisp)
+
+To test if an object is a cell array, use the @code{iscell}
+function. For example:
+
+ at example
+ at group
+iscell(c)
+     @result{} ans = 1
+
+iscell(3)
+     @result{} ans = 0
+
+ at end group
+ at end example
+
+ at DOCSTRING(iscell)
+
+ at node Creating Cell Arrays
+ at subsection Creating Cell Array
+
+The introductory example (@pxref{Basic Usage of Cell Arrays}) showed
+how to create a cell array containing currently available variables.
+In many situations, however, it is useful to create a cell array and
+then fill it with data. 
+
+The @code{cell} function returns a cell array of a given size, containing
+empty matrices.  This function is similar to the @code{zeros}
+function for creating new numerical arrays.  The following example creates
+a 2-by-2 cell array containing empty matrices
+
+ at example
+ at group
+c = cell(2,2)
+     @result{} c =
+         
+         @{
+           [1,1] = [](0x0)
+           [2,1] = [](0x0)
+           [1,2] = [](0x0)
+           [2,2] = [](0x0)
+         @}
+ at end group
+ at end example
+
+Just like numerical arrays, cell arrays can be multidimensional.  The
+ at code{cell} function accepts any number of positive integers to describe
+the size of the returned cell array.  It is also possible to set the size
+of the cell array through a vector of positive integers.  In the
+following example two cell arrays of equal size are created, and the size
+of the first one is displayed
+
+ at example
+ at group
+c1 = cell(3, 4, 5);
+c2 = cell( [3, 4, 5] );
+size(c1)
+     @result{} ans =
+         3   4   5
+ at end group
+ at end example
+
+ at noindent
+As can be seen, the @ref{doc-size, @code{size}} function also works
+for cell arrays.  As do other functions describing the size of an
+object, such as @ref{doc-length, @code{length}}, @ref{doc-numel,
+ at code{numel}}, @ref{doc-rows, @code{rows}}, and @ref{doc-columns,
+ at code{columns}}.
+
+ at DOCSTRING(cell)
+
+As an alternative to creating empty cell arrays, and then filling them, it
+is possible to convert numerical arrays into cell arrays using the
+ at code{num2cell} and @code{mat2cell} functions.
+
+ at DOCSTRING(num2cell)
+
+ at DOCSTRING(mat2cell)
+
+ at node Indexing Cell Arrays
+ at subsection Indexing Cell Arrays
+
+As shown in @pxref{Basic Usage of Cell Arrays} elements can be
+extracted from cell arrays using the @samp{@{} and @samp{@}}
+operators.  If you want to extract or access subarrays which are still 
+cell arrays, you need to use the @samp{(} and @samp{)} operators. The
+following example illustrates the difference:
+
+ at example
+ at group
+c = @{"1", "2", "3"; "a", "b", "c"; "4", "5", "6"@};
+c@{2,3@}
+     @result{} ans = c
+
+c(2,3)
+     @result{} ans = 
+        @{
+          [1,1] = c
+        @}
+ at end group
+ at end example
+
+ at noindent So with @samp{@{@}} you access elements of a cell
+array, while with @samp{()} you access a sub array of a cell
+array.
+
+Using the @samp{(} and @samp{)} operators, indexing works for cell
+arrays like for multidimensional arrays.  As an example, all the rows
+of the first and third column of a cell array can be set to @code{0}
+with the following command:
+
+ at example
+ at group
+c(:, [1, 3]) = @{0@}
+     @result{}  =
+        @{
+          [1,1] = 0
+          [2,1] = 0
+          [3,1] = 0
+          [1,2] = 2
+          [2,2] =  10
+          [3,2] =  20
+          [1,3] = 0
+          [2,3] = 0
+          [3,3] = 0
+        @}
+ at end group
+ at end example
+
+Note, that the above can also be achieved like this:
+
+ at example
+c(:, [1, 3]) = 0;
+ at end example
+
+ at noindent Here, the scalar @samp{0} is automatically promoted to 
+cell array @samp{@{0@}} and then assigned to the subarray of @code{c}.
+
+To give another example for indexing cell arrays with @samp{()}, you
+can exchange the first and the second row of a cell array as in the
+following command: 
+
+ at example
+ at group
+c = @{1, 2, 3; 4, 5, 6@};
+c([1, 2], :) = c([2, 1], :)
+     @result{} = 
+        @{
+          [1,1] =  4
+          [2,1] =  1
+          [1,2] =  5
+          [2,2] =  2
+          [1,3] =  6
+          [2,3] =  3
+        @}
+ at end group
+ at end example
+
+Accessing multiple elements of a cell array with the @samp{@{} and
+ at samp{@}} operators will result in a comma-separated list of all the
+requested elements (@pxref{Comma Separated Lists}). Using the
+ at samp{@{} and @samp{@}} operators the first two rows in the above
+example can be swapped back like this:
+
+ at example
+ at group
+[c@{[1,2], :@}] = deal(c@{[2, 1], :@})
+     @result{} = 
+        @{
+          [1,1] =  1
+          [2,1] =  4
+          [1,2] =  2
+          [2,2] =  5
+          [1,3] =  3
+          [2,3] =  6
+        @}
+ at end group
+ at end example
+
+As for struct arrays and numerical arrays, the empty matrix @samp{[]}
+can be used to delete elements from a cell array:
+
+ at example
+ at group
+x = @{"1", "2"; "3", "4"@};
+x(1, :) = []
+     @result{} x =
+        @{
+          [1,1] = 3
+          [1,2] = 4
+        @}
+ at end group
+ at end example
+
+The following example shows how to just remove the contents of cell
+array elements but not delete the space for them:
+
+ at example
+ at group
+x = @{"1", "2"; "3", "4"@};
+x@{1, :@} = []
+ at result{} x =
+      @{
+        [1,1] = [](0x0)
+        [2,1] = 3
+        [1,2] = [](0x0)
+        [2,2] = 4
+      @}
+ at end group
+ at end example
+
+ at node Cell Arrays of Strings
+ at subsection Cell Arrays of Strings
+
+One common use of cell arrays is to store multiple strings in the same
+variable.  It is also possible to store multiple strings in a
+character matrix by letting each row be a string.  This, however,
+introduces the problem that all strings must be of equal length.
+Therefore, it is recommended to use cell arrays to store multiple
+strings.  For cases, where the character matrix representation is required
+for an operation, there are several functions that convert a cell
+array of strings to a character array and back.  @code{char} and
+ at code{strvcat} convert cell arrays to a character array
+(@pxref{Concatenating Strings}), while the function @code{cellstr}
+converts a character array to a cell array of strings: 
+
+ at example
+ at group
+a = ["hello"; "world"];
+c = cellstr (a)
+     @result{} c =
+         @{
+           [1,1] = hello
+           [2,1] = world
+         @}
+ at end group
+ at end example
+
+ at DOCSTRING(cellstr)
+
+One further advantage of using cell arrays to store multiple strings is
+that most functions for string manipulations included with Octave
+support this representation.  As an example, it is possible to compare
+one string with many others using the @code{strcmp} function.  If one of
+the arguments to this function is a string and the other is a cell array
+of strings, each element of the cell array will be compared to the string
+argument:
+
+ at example
+ at group
+c = @{"hello", "world"@};
+strcmp ("hello", c)
+     @result{} ans =
+        1   0
+ at end group
+ at end example
+
+ at noindent
+The following string functions support cell arrays of strings:
+ at code{char}, @code{strvcat}, @code{strcat} (@pxref{Concatenating
+Strings}), @code{strcmp}, @code{strncmp}, @code{strcmpi},
+ at code{strncmpi} (@pxref{Comparing Strings}), @code{str2double},
+ at code{deblank}, @code{strtrim}, @code{strtrunc}, @code{strfind},
+ at code{strmatch}, , @code{regexp}, @code{regexpi} (@pxref{Manipulating 
+Strings}) and @code{str2double} (@pxref{String Conversions}).
+
+The function @code{iscellstr} can be used to test if an object is a
+cell array of strings.
+
+ at DOCSTRING(iscellstr)
+
+ at DOCSTRING(cellidx)
+
+ at node Processing Data in Cell Arrays
+ at subsection Processing Data in Cell Arrays
+
+Data that is stored in a cell array can be processed in several ways
+depending on the actual data.  The simplest way to process that data
+is to iterate through it using one or more @code{for} loops.  The same
+idea can be implemented more easily through the use of the @code{cellfun}
+function that calls a user-specified function on all elements of a cell
+array.
+
+ at DOCSTRING(cellfun)
+
+An alternative is to convert the data to a different container, such as
+a matrix or a data structure.  Depending on the data this is possible
+using the @code{cell2mat} and @code{cell2struct} functions.
+
+ at DOCSTRING(cell2mat)
+
+ at DOCSTRING(cell2struct)
+
+ at node Comma Separated Lists
+ at section Comma Separated Lists
+ at cindex comma separated lists
+ at cindex cs-lists
+
+Comma separated lists @footnote{Comma-separated lists are also sometimes
+informally referred to as @dfn{cs-lists}.} are the basic argument type
+to all Octave functions - both for input and return arguments.  In the
+example
+
+ at example
+max (@var{a}, @var{b})
+ at end example
+
+ at noindent
+ at samp{@var{a}, @var{b}} is a comma separated list.  Comma separated lists
+can appear on both the right and left hand side of an assignment.  For
+example
+
+ at example
+ at group
+x = [1 0 1 0 0 1 1; 0 0 0 0 0 0 7];
+[@var{i}, @var{j}] = find (@var{x}, 2, "last");
+ at end group
+ at end example
+
+ at noindent
+Here, @samp{@var{x}, 2, "last"} is a comma separated list constituting
+the input arguments of @code{find}.  @code{find} returns a comma
+separated list of output arguments which is assigned element by
+element to the comma separated list @samp{@var{i}, @var{j}}.
+
+Another example of where comma separated lists are used is in the
+creation of a new array with @code{[]} (@pxref{Matrices}) or the
+creation of a cell array with @code{@{@}} (@pxref{Basic Usage of Cell
+Arrays}). In the expressions 
+
+ at example
+a = [1, 2, 3, 4];
+c = @{4, 5, 6, 7@};
+ at end example
+
+ at noindent
+both @samp{1, 2, 3, 4} and @samp{4, 5, 6, 7} are comma separated lists.
+
+Comma separated lists cannot be directly manipulated by the
+user.  However, both structure arrays and cell arrays can be converted
+into comma separated lists, and thus used in place of explicitly
+written comma separated lists.  This feature is useful in many ways,
+as will be shown in the following subsections.
+
+ at menu
+* Comma Separated Lists Generated from Cell Arrays::
+* Comma Separated Lists Generated from Structure Arrays::
+ at end menu
+
+ at node Comma Separated Lists Generated from Cell Arrays
+ at subsection Comma Separated Lists Generated from Cell Arrays
+
+As has been mentioned above (@pxref{Indexing Cell Arrays}), elements
+of a cell array can be extracted into a comma separated list with the
+ at code{@{} and @code{@}} operators. By surrounding this list with
+ at code{[} and @code{]}, it can be concatenated into an array. For example:
+
+ at example
+ at group
+a = @{1, [2, 3], 4, 5, 6@};
+b = [a@{1:4@}]
+     @result{} b =
+         1   2   3   4
+ at end group
+ at end example
+
+Similarly, it is possible to create a new cell array containing cell
+elements selected with @code{@{@}}.  By surrounding the list with  
+ at samp{@{} and @samp{@}} a new cell array will be created, as the
+following example illustrates:
+
+ at example
+ at group
+a = @{1, rand(2, 2), "three"@};
+b = @{ a@{ [1, 3] @} @}
+     @result{} b =
+         @{
+           [1,1] =  1
+           [1,2] = three
+         @}
+ at end group
+ at end example
+
+Furthermore, cell elements (accessed by @code{@{@}}) can be passed
+directly to a function.  The list of elements from the cell array will
+be passed as an argument list to a given function as if it is called
+with the elements as individual arguments.  The two calls to
+ at code{printf} in the following example are identical but the latter is
+simpler and can handle cell arrays of an arbitrary size:
+
+ at example
+ at group
+c = @{"GNU", "Octave", "is", "Free", "Software"@};
+printf ("%s ", c@{1@}, c@{2@}, c@{3@}, c@{4@}, c@{5@});
+     @print{} GNU Octave is Free Software 
+printf ("%s ", c@{:@});
+     @print{} GNU Octave is Free Software 
+ at end group
+ at end example
+
+If used on the left-hand side of an assignment, a comma separated list
+generated with @code{@{@}} can be assigned to.  An example is 
+
+ at example
+ at group
+in@{1@} = [10, 20, 30, 40, 50, 60, 70, 80, 90];
+in@{2@} = inf;
+in@{3@} = "last";
+in@{4@} = "first";
+out = cell (4, 1);
+[out@{1:3@}] = find (in@{1 : 3@});
+[out@{4:6@}] = find (in@{[1, 2, 4]@})
+     @result{} out =
+        @{
+          [1,1] = 1
+          [2,1] = 9
+          [3,1] = 90
+          [4,1] = 1
+          [3,1] = 1
+          [4,1] = 10
+        @}
+ at end group
+ at end example
+
+
+ at node Comma Separated Lists Generated from Structure Arrays
+ at subsection Comma Separated Lists Generated from Structure Arrays
+Structure arrays can equally be used to create comma separated
+lists.  This is done by addressing one of the fields of a structure
+array.  For example
+
+ at example
+ at group
+x = ceil (randn (10, 1)); 
+in = struct ("call1", @{x, 3, "last"@}, 
+             "call2", @{x, inf, "first"@});
+out = struct ("call1", cell (2, 1), "call2", cell (2, 1));
+[out.call1] = find (in.call1);
+[out.call2] = find (in.call2);
+ at end group
+ at end example
diff --git a/doc/interpreter/contrib.texi b/doc/interpreter/contrib.texi
new file mode 100644
index 0000000..4266286
--- /dev/null
+++ b/doc/interpreter/contrib.texi
@@ -0,0 +1,342 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2008, 2009 Jaroslav Hajek
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Contributing Guidelines
+ at appendix Contributing Guidelines
+ at cindex coding standards
+ at cindex Octave development
+
+This chapter is dedicated to those who wish to contribute code to Octave.
+
+ at menu 
+* How to Contribute::
+* General Guidelines::
+* Octave Sources (m-files)::
+* C++ Sources::
+* Other Sources::	
+ at end menu
+
+ at node How to Contribute
+ at section How to Contribute
+The mailing list for Octave development discussion and sending contributions is
+ at email{maintainers@@octave.org}.  This concerns the development of Octave core,
+i.e., code that goes to Octave directly.  You may consider developing and
+publishing a package instead; a great place for this is the allied Octave-Forge
+project (@url{http://octave.sf.net}).  Note that the Octave project is
+inherently more conservative and follows narrower rules.
+
+The preferable form of contribution is creating a Mercurial changeset and
+sending it via e-mail to the octave-maintainers mailing list.  Mercurial is the
+source code management system currently used to develop Octave.  Other forms of 
+contributions (e.g., simple diff patches) are also acceptable, but they slow 
+down the review process.  If you want to make more contributions, you should 
+really get familiar with Mercurial.  A good place to start is 
+ at url{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial}.  There you will
+also find help how to install Mercurial.
+
+A simple contribution sequence could look like this:
+ at example
+ at group
+hg clone http://www.octave.org/hg/octave
+                             # make a local copy of the octave 
+                             # source repository
+cd octave
+# change some sources at dots{}
+hg commit -m "make Octave the coolest software ever"
+                             # commit the changeset into your
+                             # local repository
+hg export -o ../cool.diff tip
+                             # export the changeset to a diff
+                             # file
+# send ../cool.diff via email
+ at end group
+ at end example
+
+You may want to get familiar with Mercurial queues to manage your changesets.
+Here is a slightly less simple example using Mercurial queues, where you work 
+on two unrelated changesets in parallel and update one of the changesets after 
+discussion in the maintainers mailing list:
+ at example
+hg qnew nasty_bug            # create a new patch 
+# change sources at dots{}
+hg qref                      # save the changes into the patch
+# change even more at dots{}
+hg qref -m "solution to nasty bug!"
+                             # save again with commit message
+hg export -o ../nasty.diff tip
+                             # export the patch
+# send ../nasty.diff via email
+hg qpop                      # undo the application of the patch
+                             # and remove the changes from the
+                             # source tree
+hg qnew doc_improvements     # create an unrelated patch 
+# change doc sources at dots{}
+hg qref -m "could not find myfav.m in the doc"
+                             # save the changes into the patch
+hg export -o ../doc.diff tip
+                             # export the second patch
+# send ../doc.diff tip via email
+hg qpop
+# discussion in the maintainers mailing list @dots{}
+hg qpush nasty_bug           # apply the patch again
+# change sources yet again @dots{}
+hg qref
+hg export -o ../nasty2.diff tip
+# send ../nasty2.diff via email
+ at end example
+
+ at node General Guidelines
+ at section General Guidelines
+
+All Octave's sources are distributed under the General Public License (GPL).
+Currently, Octave uses GPL version 3.  For details about this license, see
+ at url{http://www.gnu.org/licenses/gpl.html}.  Therefore, whenever you create a
+new source file, it should have the following comment header (use appropriate
+year, name and comment marks):
+
+ at example
+## Copyright (C) 1996, 1997, 2007 John W. Eaton <jwe@@octave.org>
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public
+## License as published by the Free Software Foundation;
+## either version 3 of the License, or (at your option) any 
+## later version.
+##
+## Octave is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied
+## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+## PURPOSE.  See the GNU General Public License for more
+## details.
+##
+## You should have received a copy of the GNU General Public
+## License along with Octave; see the file COPYING.  If not,
+## see <http://www.gnu.org/licenses/>.
+ at end example
+
+Always include ChangeLog entries in changesets.  After making your source
+changes, record and briefly describe the changes in the nearest ChangeLog file
+upwards in the directory tree.  Use the previous entries as a template.  Your
+entry should contain your name and email, and the path to the modified source
+file relative to the parent directory of the ChangeLog file.  If there are more
+functions in the file, you should also include the name of the modified function
+(in parentheses after file path).  Example:
+
+ at example
+ at group
+2008-04-02  David Bateman  <dbateman@@free.fr>
+
+        * graphics.cc (void gnuplot_backend::close_figure (const
+        octave_value&) const): Allow for an input and output stream.
+ at end group
+ at end example
+
+ at noindent
+The ChangeLog entries should describe what is changed, not why.  Any
+explanation of why a change is needed should appear as comments in the
+code, particularly if there is something that might not be obvious to
+someone reading it later.
+
+The preferred comment mark for places that may need further attention is FIXME.
+
+ at node Octave Sources (m-files)
+ at section Octave Sources (m-files)
+
+Don't use tabs.  Tabs cause trouble.  If you are used to them, set up your editor
+so that it converts tabs to spaces.  Indent the bodies of the statement blocks.
+Recommended indent is 2 spaces.  When calling functions, put spaces after commas
+and before the calling parentheses, like this:
+
+ at example
+  x = max (sin (y+3), 2);
+ at end example
+
+ at noindent
+An exception are matrix and vector constructors:
+
+ at example
+  [sin(x), cos(x)]
+ at end example
+
+ at noindent
+Here, putting spaces after @code{sin}, @code{cos} would result in a parse error.
+In indexing expression, do not put a space after the identifier (this
+differentiates indexing and function calls nicely).  The space after comma is not
+necessary if index expressions are simple, i.e., you may write
+ at example
+  A(:,i,j)
+ at end example
+
+ at noindent
+but 
+
+ at example
+  A([1:i-1;i+1:n], XI(:,2:n-1))
+ at end example
+
+Use lowercase names if possible.  Uppercase is acceptable for variable names
+consisting of 1-2 letters.  Do not use mixed case names.  Function names must be
+lowercase.  Function names are global, so choose them wisely.
+
+Always use a specific end-of-block statement (like @code{endif},
+ at code{endswitch}) rather than generic @code{end}.  Enclose the @code{if},
+ at code{while}, @code{until} and @code{switch} conditions in parentheses, 
+like in C: 
+
+ at example
+ at group
+if (isvector (a))
+  s = sum(a);
+endif
+ at end group
+ at end example
+
+ at noindent
+Do not do this, however, with @code{for}:
+
+ at example
+ at group
+for i = 1:n
+  b(i) = sum (a(:,i));
+endfor
+ at end group
+ at end example
+
+ at node C++ Sources
+ at section C++ Sources
+
+Don't use tabs.  Tabs cause trouble.  If you are used to them, set up your editor
+so that it converts tabs to spaces.  Format function headers like this:
+
+ at example
+ at group
+static bool
+matches_patterns (const string_vector& patterns, int pat_idx,
+		  int num_pat, const std::string& name)
+ at end group
+ at end example
+
+ at noindent
+The function name should start in column 1, and multi-line argument lists should
+be aligned on the first char after the open parenthesis.  You should put a space
+after the left open parenthesis and after commas, for both function definitions
+and function calls.
+
+Recommended indent is 2 spaces.  When indenting, indent the statement after
+control structures (like @code{if}, @code{while}, etc.). If there is a compound
+statement, indent @i{both} the curly braces and the body of the statement (so
+that the body gets indented by @i{two} indents).  Example:
+
+ at example
+ at group
+if (have_args)
+  @{
+    idx.push_back (first_args);
+    have_args = false;
+  @}
+else
+  idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
+ at end group
+ at end example
+
+ at noindent
+If you have nested @code{if} statements, use extra braces for extra
+clarification. 
+
+Split long expressions in such a way that a continuation line starts with an
+operator rather than identifier.  If the split occurs inside braces, continuation
+should be aligned with the first char after the innermost braces enclosing the
+split.  Example:
+
+ at example
+ at group
+SVD::type type = ((nargout == 0 || nargout == 1)
+                  ? SVD::sigma_only
+                  : (nargin == 2) ? SVD::economy : SVD::std);
+ at end group
+ at end example
+
+ at noindent
+Consider putting extra braces around a multiline expression to make it more
+readable, even if they are not necessary.  Also, do not hesitate to put extra
+braces anywhere if it improves clarity.
+
+Try declaring variables just before they're needed.  Use local variables of
+blocks - it helps optimization.  Don't write multi-line variable declaration
+with a single type specification and multiple variables.  If the variables don't
+fit on single line, repeat the type specification.  Example:
+
+ at example
+ at group
+octave_value retval;
+
+octave_idx_type nr = b.rows ();
+octave_idx_type nc = b.cols ();
+
+double d1, d2;
+ at end group
+ at end example
+
+Use lowercase names if possible.  Uppercase is acceptable for variable names
+consisting of 1-2 letters.  Do not use mixed case names.
+
+Try to use Octave's types and classes if possible.  Otherwise, try to use C++
+standard library.  Use of STL containers and algorithms is encouraged.  Use
+templates wisely to reduce code duplication.  Avoid comma expressions, labels
+and gotos, and explicit typecasts.  If you need to typecast, use the modern C++
+casting operators.  In functions, try to reduce the number of @code{return}
+statements - use nested @code{if} statements if possible.
+
+ at node Other Sources
+ at section Other Sources
+Apart from C++ and Octave language (m-files), Octave's sources include files
+written in C, Fortran, M4, perl, unix shell, AWK, texinfo and @TeX{}.  There are
+not many rules to follow when using these other languages; some of them are
+summarized below.  In any case, the golden rule is: if you modify a source
+file, try to follow any conventions you can detect in the file or other similar
+files.
+
+For C you should obviously follow all C++ rules that can apply.
+
+If you happen to modify a Fortran file, you should stay within Fortran 77
+with common extensions like @code{END DO}.  Currently, we want all sources
+to be compilable with the f2c and g77 compilers, without special flags if
+possible.  This usually means that non-legacy compilers also accept the sources.
+
+The M4 macro language is mainly used for autoconf configuration files.  You should
+follow normal M4 rules when contributing to these files.  Some M4 files come
+from external source, namely the Autoconf archive
+ at url{http://autoconf-archive.cryp.to}.
+
+If you give a code example in the documentation written in texinfo with the 
+ at code{@@example} environment, you should be aware that the text within such an 
+environment will not be wrapped.  It is recommended that you keep the lines
+short enough to fit on pages in the generated pdf or ps documents.  Here is a 
+ruler (in an @code{@@example} environment) for finding the appropriate line 
+width:
+
+ at example
+ at group
+         1         2         3         4         5         6
+123456789012345678901234567890123456789012345678901234567890
+ at end group
+ at end example
diff --git a/doc/interpreter/contrib.txi b/doc/interpreter/contrib.txi
new file mode 100644
index 0000000..ff2564b
--- /dev/null
+++ b/doc/interpreter/contrib.txi
@@ -0,0 +1,340 @@
+ at c Copyright (C) 2008, 2009 Jaroslav Hajek
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Contributing Guidelines
+ at appendix Contributing Guidelines
+ at cindex coding standards
+ at cindex Octave development
+
+This chapter is dedicated to those who wish to contribute code to Octave.
+
+ at menu 
+* How to Contribute::
+* General Guidelines::
+* Octave Sources (m-files)::
+* C++ Sources::
+* Other Sources::	
+ at end menu
+
+ at node How to Contribute
+ at section How to Contribute
+The mailing list for Octave development discussion and sending contributions is
+ at email{maintainers@@octave.org}.  This concerns the development of Octave core,
+i.e., code that goes to Octave directly.  You may consider developing and
+publishing a package instead; a great place for this is the allied Octave-Forge
+project (@url{http://octave.sf.net}).  Note that the Octave project is
+inherently more conservative and follows narrower rules.
+
+The preferable form of contribution is creating a Mercurial changeset and
+sending it via e-mail to the octave-maintainers mailing list.  Mercurial is the
+source code management system currently used to develop Octave.  Other forms of 
+contributions (e.g., simple diff patches) are also acceptable, but they slow 
+down the review process.  If you want to make more contributions, you should 
+really get familiar with Mercurial.  A good place to start is 
+ at url{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial}.  There you will
+also find help how to install Mercurial.
+
+A simple contribution sequence could look like this:
+ at example
+ at group
+hg clone http://www.octave.org/hg/octave
+                             # make a local copy of the octave 
+                             # source repository
+cd octave
+# change some sources at dots{}
+hg commit -m "make Octave the coolest software ever"
+                             # commit the changeset into your
+                             # local repository
+hg export -o ../cool.diff tip
+                             # export the changeset to a diff
+                             # file
+# send ../cool.diff via email
+ at end group
+ at end example
+
+You may want to get familiar with Mercurial queues to manage your changesets.
+Here is a slightly less simple example using Mercurial queues, where you work 
+on two unrelated changesets in parallel and update one of the changesets after 
+discussion in the maintainers mailing list:
+ at example
+hg qnew nasty_bug            # create a new patch 
+# change sources at dots{}
+hg qref                      # save the changes into the patch
+# change even more at dots{}
+hg qref -m "solution to nasty bug!"
+                             # save again with commit message
+hg export -o ../nasty.diff tip
+                             # export the patch
+# send ../nasty.diff via email
+hg qpop                      # undo the application of the patch
+                             # and remove the changes from the
+                             # source tree
+hg qnew doc_improvements     # create an unrelated patch 
+# change doc sources at dots{}
+hg qref -m "could not find myfav.m in the doc"
+                             # save the changes into the patch
+hg export -o ../doc.diff tip
+                             # export the second patch
+# send ../doc.diff tip via email
+hg qpop
+# discussion in the maintainers mailing list @dots{}
+hg qpush nasty_bug           # apply the patch again
+# change sources yet again @dots{}
+hg qref
+hg export -o ../nasty2.diff tip
+# send ../nasty2.diff via email
+ at end example
+
+ at node General Guidelines
+ at section General Guidelines
+
+All Octave's sources are distributed under the General Public License (GPL).
+Currently, Octave uses GPL version 3.  For details about this license, see
+ at url{http://www.gnu.org/licenses/gpl.html}.  Therefore, whenever you create a
+new source file, it should have the following comment header (use appropriate
+year, name and comment marks):
+
+ at example
+## Copyright (C) 1996, 1997, 2007 John W. Eaton <jwe@@octave.org>
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public
+## License as published by the Free Software Foundation;
+## either version 3 of the License, or (at your option) any 
+## later version.
+##
+## Octave is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied
+## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+## PURPOSE.  See the GNU General Public License for more
+## details.
+##
+## You should have received a copy of the GNU General Public
+## License along with Octave; see the file COPYING.  If not,
+## see <http://www.gnu.org/licenses/>.
+ at end example
+
+Always include ChangeLog entries in changesets.  After making your source
+changes, record and briefly describe the changes in the nearest ChangeLog file
+upwards in the directory tree.  Use the previous entries as a template.  Your
+entry should contain your name and email, and the path to the modified source
+file relative to the parent directory of the ChangeLog file.  If there are more
+functions in the file, you should also include the name of the modified function
+(in parentheses after file path).  Example:
+
+ at example
+ at group
+2008-04-02  David Bateman  <dbateman@@free.fr>
+
+        * graphics.cc (void gnuplot_backend::close_figure (const
+        octave_value&) const): Allow for an input and output stream.
+ at end group
+ at end example
+
+ at noindent
+The ChangeLog entries should describe what is changed, not why.  Any
+explanation of why a change is needed should appear as comments in the
+code, particularly if there is something that might not be obvious to
+someone reading it later.
+
+The preferred comment mark for places that may need further attention is FIXME.
+
+ at node Octave Sources (m-files)
+ at section Octave Sources (m-files)
+
+Don't use tabs.  Tabs cause trouble.  If you are used to them, set up your editor
+so that it converts tabs to spaces.  Indent the bodies of the statement blocks.
+Recommended indent is 2 spaces.  When calling functions, put spaces after commas
+and before the calling parentheses, like this:
+
+ at example
+  x = max (sin (y+3), 2);
+ at end example
+
+ at noindent
+An exception are matrix and vector constructors:
+
+ at example
+  [sin(x), cos(x)]
+ at end example
+
+ at noindent
+Here, putting spaces after @code{sin}, @code{cos} would result in a parse error.
+In indexing expression, do not put a space after the identifier (this
+differentiates indexing and function calls nicely).  The space after comma is not
+necessary if index expressions are simple, i.e., you may write
+ at example
+  A(:,i,j)
+ at end example
+
+ at noindent
+but 
+
+ at example
+  A([1:i-1;i+1:n], XI(:,2:n-1))
+ at end example
+
+Use lowercase names if possible.  Uppercase is acceptable for variable names
+consisting of 1-2 letters.  Do not use mixed case names.  Function names must be
+lowercase.  Function names are global, so choose them wisely.
+
+Always use a specific end-of-block statement (like @code{endif},
+ at code{endswitch}) rather than generic @code{end}.  Enclose the @code{if},
+ at code{while}, @code{until} and @code{switch} conditions in parentheses, 
+like in C: 
+
+ at example
+ at group
+if (isvector (a))
+  s = sum(a);
+endif
+ at end group
+ at end example
+
+ at noindent
+Do not do this, however, with @code{for}:
+
+ at example
+ at group
+for i = 1:n
+  b(i) = sum (a(:,i));
+endfor
+ at end group
+ at end example
+
+ at node C++ Sources
+ at section C++ Sources
+
+Don't use tabs.  Tabs cause trouble.  If you are used to them, set up your editor
+so that it converts tabs to spaces.  Format function headers like this:
+
+ at example
+ at group
+static bool
+matches_patterns (const string_vector& patterns, int pat_idx,
+		  int num_pat, const std::string& name)
+ at end group
+ at end example
+
+ at noindent
+The function name should start in column 1, and multi-line argument lists should
+be aligned on the first char after the open parenthesis.  You should put a space
+after the left open parenthesis and after commas, for both function definitions
+and function calls.
+
+Recommended indent is 2 spaces.  When indenting, indent the statement after
+control structures (like @code{if}, @code{while}, etc.). If there is a compound
+statement, indent @i{both} the curly braces and the body of the statement (so
+that the body gets indented by @i{two} indents).  Example:
+
+ at example
+ at group
+if (have_args)
+  @{
+    idx.push_back (first_args);
+    have_args = false;
+  @}
+else
+  idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
+ at end group
+ at end example
+
+ at noindent
+If you have nested @code{if} statements, use extra braces for extra
+clarification. 
+
+Split long expressions in such a way that a continuation line starts with an
+operator rather than identifier.  If the split occurs inside braces, continuation
+should be aligned with the first char after the innermost braces enclosing the
+split.  Example:
+
+ at example
+ at group
+SVD::type type = ((nargout == 0 || nargout == 1)
+                  ? SVD::sigma_only
+                  : (nargin == 2) ? SVD::economy : SVD::std);
+ at end group
+ at end example
+
+ at noindent
+Consider putting extra braces around a multiline expression to make it more
+readable, even if they are not necessary.  Also, do not hesitate to put extra
+braces anywhere if it improves clarity.
+
+Try declaring variables just before they're needed.  Use local variables of
+blocks - it helps optimization.  Don't write multi-line variable declaration
+with a single type specification and multiple variables.  If the variables don't
+fit on single line, repeat the type specification.  Example:
+
+ at example
+ at group
+octave_value retval;
+
+octave_idx_type nr = b.rows ();
+octave_idx_type nc = b.cols ();
+
+double d1, d2;
+ at end group
+ at end example
+
+Use lowercase names if possible.  Uppercase is acceptable for variable names
+consisting of 1-2 letters.  Do not use mixed case names.
+
+Try to use Octave's types and classes if possible.  Otherwise, try to use C++
+standard library.  Use of STL containers and algorithms is encouraged.  Use
+templates wisely to reduce code duplication.  Avoid comma expressions, labels
+and gotos, and explicit typecasts.  If you need to typecast, use the modern C++
+casting operators.  In functions, try to reduce the number of @code{return}
+statements - use nested @code{if} statements if possible.
+
+ at node Other Sources
+ at section Other Sources
+Apart from C++ and Octave language (m-files), Octave's sources include files
+written in C, Fortran, M4, perl, unix shell, AWK, texinfo and @TeX{}.  There are
+not many rules to follow when using these other languages; some of them are
+summarized below.  In any case, the golden rule is: if you modify a source
+file, try to follow any conventions you can detect in the file or other similar
+files.
+
+For C you should obviously follow all C++ rules that can apply.
+
+If you happen to modify a Fortran file, you should stay within Fortran 77
+with common extensions like @code{END DO}.  Currently, we want all sources
+to be compilable with the f2c and g77 compilers, without special flags if
+possible.  This usually means that non-legacy compilers also accept the sources.
+
+The M4 macro language is mainly used for autoconf configuration files.  You should
+follow normal M4 rules when contributing to these files.  Some M4 files come
+from external source, namely the Autoconf archive
+ at url{http://autoconf-archive.cryp.to}.
+
+If you give a code example in the documentation written in texinfo with the 
+ at code{@@example} environment, you should be aware that the text within such an 
+environment will not be wrapped.  It is recommended that you keep the lines
+short enough to fit on pages in the generated pdf or ps documents.  Here is a 
+ruler (in an @code{@@example} environment) for finding the appropriate line 
+width:
+
+ at example
+ at group
+         1         2         3         4         5         6
+123456789012345678901234567890123456789012345678901234567890
+ at end group
+ at end example
diff --git a/doc/interpreter/contributors.in b/doc/interpreter/contributors.in
new file mode 100644
index 0000000..ee6c301
--- /dev/null
+++ b/doc/interpreter/contributors.in
@@ -0,0 +1,235 @@
+Ben Abbott
+Andy Adler
+Joel Andersson
+Muthiah Annamalai
+Shai Ayal
+Roger Banks
+Ben Barrowes
+Alexander Barth
+David Bateman
+Heinz Bauschke
+Karl Berry
+David Billinghurst
+Don Bindner
+Jakub Bogusz
+Moritz Borgmann
+Richard Bovey
+Marcus Brinkmann
+Remy Bruno
+Marco Caliari
+Daniel Calvelo
+John C. Campbell
+Jean-Francois Cardoso
+Joao Cardoso
+Larrie Carr
+David Castelow
+Vincent Cautaerts
+Clinton Chee
+Albert Chin-A-Young
+Carsten Clark
+J. D. Cole
+Martin Costabel
+Michael Creel
+Jeff Cunningham
+Martin Dalecki
+Jorge Barros de Abreu
+Carlo de Falco
+Thomas D. Dean
+Philippe Defert
+Bill Denney
+David M. Doolin
+Pascal A. Dupuis
+John W. Eaton
+Dirk Eddelbuettel
+Paul Eggert
+Stephen Eglen
+Peter Ekberg
+Rolf Fabian
+Stephen Fegan
+Ramon Garcia Fernandez
+Torsten Finke
+Jose Daniel Munoz Frias
+Castor Fu
+Eduardo Gallestey
+Walter Gautschi
+Klaus Gebhardt
+Driss Ghaddab
+Nicolo Giorgetti
+Michael Goffioul
+Glenn Golden
+Tomislav Goles
+Keith Goodman
+Brian Gough
+Steffen Groot
+Etienne Grossmann
+Peter Gustafson
+Kai Habel
+William P. Y. Hadisoeseno
+Jaroslav Hajek
+Benjamin Hall
+Kim Hansen
+Soren Hauberg
+Dave Hawthorne
+Daniel Heiserer
+Martin Helm
+Stefan Hepp
+Yozo Hida
+Ryan Hinton
+Roman Hodek
+A. Scottedward Hodel
+Richard Allan Holcombe
+Tom Holroyd
+David Hoover
+Kurt Hornik
+Christopher Hulbert
+Cyril Humbert
+Teemu Ikonen
+Alan W. Irwin
+Geoff Jacobsen
+Mats Jansson
+Cai Jianming
+Steven G. Johnson
+Heikki Junes
+Atsushi Kajita
+Jarkko Kaleva
+Mohamed Kamoun
+Lute Kamstra
+Thomas Kasper
+Joel Keay
+Mumit Khan
+Paul Kienzle
+Aaron A. King
+Arno J. Klaassen
+Geoffrey Knauth
+Heine Kolltveit
+Ken Kouno
+Oyvind Kristiansen
+Piotr Krzyzanowski
+Volker Kuhlmann
+Tetsuro Kurita
+Miroslaw Kwasniak
+Rafael Laboissiere
+Kai Labusch
+Claude Lacoursiere
+Walter Landry
+Bill Lash
+Dirk Laurie
+Maurice LeBrun
+Friedrich Leisch
+Timo Lindfors
+Benjamin Lindner
+Ross Lippert
+David Livings
+Erik de Castro Lopo
+Massimo Lorenzin
+Emil Lucretiu
+Hoxide Ma
+James Macnicol
+Jens-Uwe Mager
+Ricardo Marranita
+Orestes Mas
+Makoto Matsumoto
+Tatsuro Matsuoka
+Laurent Mazet
+G. D. McBain
+Alexander Mamonov
+Christoph Mayer
+Thorsten Meyer
+Petr Mikulik
+Stefan Monnier
+Antoine Moreau
+Kai P. Mueller
+Victor Munoz
+Carmen Navarrete
+Todd Neal
+Al Niessner
+Rick Niles
+Takuji Nishimura
+Kai Noda
+Eric Norum
+Krzesimir Nowak
+Michael O'Brien
+Peter O'Gorman
+Thorsten Ohl
+Arno Onken
+Luis F. Ortiz
+Scott Pakin
+Gabriele Pannocchia
+Sylvain Pelissier
+Per Persson
+Primozz Peterlin
+Jim Peterson
+Danilo Piazzalunga
+Nicholas Piper
+Robert Platt
+Hans Ekkehard Plesser
+Tom Poage
+Orion Poplawski
+Ondrej Popp
+Jef Poskanzer
+Francesco Potorti
+James B. Rawlings
+Eric S. Raymond
+Balint Reczey
+Michael Reifenberger
+Jason Riedy
+Petter Risholm
+Matthew W. Roberts
+Andrew Ross
+Mark van Rossum
+Kevin Ruland
+Ryan Rusaw
+Olli Saarela
+Toni Saarela
+Juhani Saastamoinen
+Radek Salac
+Ben Sapp
+Aleksej Saushev
+Alois Schloegl
+Michel D. Schmid
+Julian Schnidder
+Nicol N. Schraudolph
+Sebastian Schubert
+Ludwig Schwardt
+Thomas L. Scofield
+Daniel J. Sebald
+Dmitri A. Sergatskov
+Baylis Shanks
+Joseph P. Skudlarek
+John Smith
+Julius Smith
+Shan G. Smith
+Joerg Specht
+Quentin H. Spencer
+Christoph Spiel
+Richard Stallman
+Russell Standish
+Doug Stewart
+Jonathan Stickel
+Thomas Stuart
+Ivan Sutoris
+John Swensen
+Ariel Tankus
+Georg Thimm
+Duncan Temple Lang
+Kris Thielemans
+Olaf Till
+Thomas Treichl
+Frederick Umminger
+Utkarsh Upadhyay
+Stefan van der Walt
+Peter Van Wieren
+James R. Van Zandt
+Gregory Vanuxem
+Ivana Varekova
+Thomas Walter
+Olaf Weber
+Thomas Weber
+Rik Wehbring
+Bob Weigel
+Andreas Weingessel
+Michael Weitzel
+Fook Fah Yap
+Michael Zeising
+Federico Zenith
+Alex Zvoleff
diff --git a/doc/interpreter/contributors.texi b/doc/interpreter/contributors.texi
new file mode 100644
index 0000000..d87d90f
--- /dev/null
+++ b/doc/interpreter/contributors.texi
@@ -0,0 +1,81 @@
+ at multitable @columnfractions .33 .33 .33
+ at item Ben Abbott @tab Andy Adler @tab Joel Andersson
+ at item Muthiah Annamalai @tab Shai Ayal @tab Roger Banks
+ at item Ben Barrowes @tab Alexander Barth @tab David Bateman
+ at item Heinz Bauschke @tab Karl Berry @tab David Billinghurst
+ at item Don Bindner @tab Jakub Bogusz @tab Moritz Borgmann
+ at item Richard Bovey @tab Marcus Brinkmann @tab Remy Bruno
+ at item Marco Caliari @tab Daniel Calvelo @tab John C. Campbell
+ at item Jean-Francois Cardoso @tab Joao Cardoso @tab Larrie Carr
+ at item David Castelow @tab Vincent Cautaerts @tab Clinton Chee
+ at item Albert Chin-A-Young @tab Carsten Clark @tab J. D. Cole
+ at item Martin Costabel @tab Michael Creel @tab Jeff Cunningham
+ at item Martin Dalecki @tab Jorge Barros de Abreu @tab Carlo de Falco
+ at item Thomas D. Dean @tab Philippe Defert @tab Bill Denney
+ at item David M. Doolin @tab Pascal A. Dupuis @tab John W. Eaton
+ at item Dirk Eddelbuettel @tab Paul Eggert @tab Stephen Eglen
+ at item Peter Ekberg @tab Rolf Fabian @tab Stephen Fegan
+ at item Ramon Garcia Fernandez @tab Torsten Finke @tab Jose Daniel Munoz Frias
+ at item Castor Fu @tab Eduardo Gallestey @tab Walter Gautschi
+ at item Klaus Gebhardt @tab Driss Ghaddab @tab Nicolo Giorgetti
+ at item Michael Goffioul @tab Glenn Golden @tab Tomislav Goles
+ at item Keith Goodman @tab Brian Gough @tab Steffen Groot
+ at item Etienne Grossmann @tab Peter Gustafson @tab Kai Habel
+ at item William P. Y. Hadisoeseno @tab Jaroslav Hajek @tab Benjamin Hall
+ at item Kim Hansen @tab Soren Hauberg @tab Dave Hawthorne
+ at item Daniel Heiserer @tab Martin Helm @tab Stefan Hepp
+ at item Yozo Hida @tab Ryan Hinton @tab Roman Hodek
+ at item A. Scottedward Hodel @tab Richard Allan Holcombe @tab Tom Holroyd
+ at item David Hoover @tab Kurt Hornik @tab Christopher Hulbert
+ at item Cyril Humbert @tab Teemu Ikonen @tab Alan W. Irwin
+ at item Geoff Jacobsen @tab Mats Jansson @tab Cai Jianming
+ at item Steven G. Johnson @tab Heikki Junes @tab Atsushi Kajita
+ at item Jarkko Kaleva @tab Mohamed Kamoun @tab Lute Kamstra
+ at item Thomas Kasper @tab Joel Keay @tab Mumit Khan
+ at item Paul Kienzle @tab Aaron A. King @tab Arno J. Klaassen
+ at item Geoffrey Knauth @tab Heine Kolltveit @tab Ken Kouno
+ at item Oyvind Kristiansen @tab Piotr Krzyzanowski @tab Volker Kuhlmann
+ at item Tetsuro Kurita @tab Miroslaw Kwasniak @tab Rafael Laboissiere
+ at item Kai Labusch @tab Claude Lacoursiere @tab Walter Landry
+ at item Bill Lash @tab Dirk Laurie @tab Maurice LeBrun
+ at item Friedrich Leisch @tab Timo Lindfors @tab Benjamin Lindner
+ at item Ross Lippert @tab David Livings @tab Erik de Castro Lopo
+ at item Massimo Lorenzin @tab Emil Lucretiu @tab Hoxide Ma
+ at item James Macnicol @tab Jens-Uwe Mager @tab Ricardo Marranita
+ at item Orestes Mas @tab Makoto Matsumoto @tab Tatsuro Matsuoka
+ at item Laurent Mazet @tab G. D. McBain @tab Alexander Mamonov
+ at item Christoph Mayer @tab Thorsten Meyer @tab Petr Mikulik
+ at item Stefan Monnier @tab Antoine Moreau @tab Kai P. Mueller
+ at item Victor Munoz @tab Carmen Navarrete @tab Todd Neal
+ at item Al Niessner @tab Rick Niles @tab Takuji Nishimura
+ at item Kai Noda @tab Eric Norum @tab Krzesimir Nowak
+ at item Michael O'Brien @tab Peter O'Gorman @tab Thorsten Ohl
+ at item Arno Onken @tab Luis F. Ortiz @tab Scott Pakin
+ at item Gabriele Pannocchia @tab Sylvain Pelissier @tab Per Persson
+ at item Primozz Peterlin @tab Jim Peterson @tab Danilo Piazzalunga
+ at item Nicholas Piper @tab Robert Platt @tab Hans Ekkehard Plesser
+ at item Tom Poage @tab Orion Poplawski @tab Ondrej Popp
+ at item Jef Poskanzer @tab Francesco Potorti @tab James B. Rawlings
+ at item Eric S. Raymond @tab Balint Reczey @tab Michael Reifenberger
+ at item Jason Riedy @tab Petter Risholm @tab Matthew W. Roberts
+ at item Andrew Ross @tab Mark van Rossum @tab Kevin Ruland
+ at item Ryan Rusaw @tab Olli Saarela @tab Toni Saarela
+ at item Juhani Saastamoinen @tab Radek Salac @tab Ben Sapp
+ at item Aleksej Saushev @tab Alois Schloegl @tab Michel D. Schmid
+ at item Julian Schnidder @tab Nicol N. Schraudolph @tab Sebastian Schubert
+ at item Ludwig Schwardt @tab Thomas L. Scofield @tab Daniel J. Sebald
+ at item Dmitri A. Sergatskov @tab Baylis Shanks @tab Joseph P. Skudlarek
+ at item John Smith @tab Julius Smith @tab Shan G. Smith
+ at item Joerg Specht @tab Quentin H. Spencer @tab Christoph Spiel
+ at item Richard Stallman @tab Russell Standish @tab Doug Stewart
+ at item Jonathan Stickel @tab Thomas Stuart @tab Ivan Sutoris
+ at item John Swensen @tab Ariel Tankus @tab Georg Thimm
+ at item Duncan Temple Lang @tab Kris Thielemans @tab Olaf Till
+ at item Thomas Treichl @tab Frederick Umminger @tab Utkarsh Upadhyay
+ at item Stefan van der Walt @tab Peter Van Wieren @tab James R. Van Zandt
+ at item Gregory Vanuxem @tab Ivana Varekova @tab Thomas Walter
+ at item Olaf Weber @tab Thomas Weber @tab Rik Wehbring
+ at item Bob Weigel @tab Andreas Weingessel @tab Michael Weitzel
+ at item Fook Fah Yap @tab Michael Zeising @tab Federico Zenith
+ at item Alex Zvoleff
+ at end multitable
diff --git a/doc/interpreter/convhull.eps b/doc/interpreter/convhull.eps
new file mode 100644
index 0000000..ae81638
--- /dev/null
+++ b/doc/interpreter/convhull.eps
@@ -0,0 +1,896 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: convhull.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:47:02 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (convhull.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:47:02 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 1248 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 1248 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2527 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2527 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3806 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3806 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5084 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5084 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6363 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6363 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7642 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7642 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1548 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1548 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-3)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3011 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3011 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4473 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4473 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5936 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5936 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+7398 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 7398 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8860 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8860 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10323 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10323 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+1.00 0.00 0.00 C 1548 2150 M
+5936 1248 L
+4387 902 V
+-73 315 V
+-73 313 V
+-73 308 V
+-74 304 V
+-73 298 V
+-73 293 V
+-73 285 V
+-73 278 V
+-73 270 V
+-73 261 V
+-73 251 V
+-74 241 V
+-73 230 V
+-73 219 V
+-73 207 V
+-73 195 V
+-73 181 V
+-73 169 V
+-73 154 V
+-74 140 V
+-73 126 V
+-73 111 V
+-73 96 V
+-73 80 V
+-73 65 V
+-73 49 V
+-73 33 V
+-74 18 V
+-73 1 V
+-4533 0 V
+-73 -1 V
+-74 -18 V
+-73 -33 V
+-73 -49 V
+-73 -65 V
+-73 -80 V
+-73 -96 V
+-73 -111 V
+-73 -126 V
+-74 -140 V
+-73 -154 V
+-73 -169 V
+-73 -181 V
+-73 -195 V
+-73 -207 V
+-73 -219 V
+-73 -230 V
+-74 -241 V
+-73 -251 V
+-73 -261 V
+-73 -270 V
+-73 -278 V
+-73 -285 V
+-73 -293 V
+-73 -298 V
+-74 -304 V
+-73 -308 V
+-73 -313 V
+-73 -315 V
+% End plot #1
+% Begin plot #2
+2.000 UP
+stroke
+LT1
+0.00 0.00 1.00 C 1548 2150 Pls
+1621 2465 Pls
+1694 2778 Pls
+1767 3086 Pls
+1841 3390 Pls
+1914 3688 Pls
+1987 3981 Pls
+2060 4266 Pls
+2133 4544 Pls
+2206 4814 Pls
+2279 5075 Pls
+2352 5326 Pls
+2426 5567 Pls
+2499 5797 Pls
+2572 6016 Pls
+2645 6223 Pls
+2718 6418 Pls
+2791 6599 Pls
+2864 6768 Pls
+2937 6922 Pls
+3011 7062 Pls
+3084 7188 Pls
+3157 7299 Pls
+3230 7395 Pls
+3303 7475 Pls
+3376 7540 Pls
+3449 7589 Pls
+3522 7622 Pls
+3596 7640 Pls
+3669 7641 Pls
+3742 7626 Pls
+3815 7596 Pls
+3888 7549 Pls
+3961 7487 Pls
+4034 7409 Pls
+4107 7316 Pls
+4181 7208 Pls
+4254 7084 Pls
+4327 6947 Pls
+4400 6795 Pls
+4473 6629 Pls
+4546 6449 Pls
+4619 6257 Pls
+4692 6052 Pls
+4766 5835 Pls
+4839 5606 Pls
+4912 5367 Pls
+4985 5118 Pls
+5058 4858 Pls
+5131 4590 Pls
+5204 4313 Pls
+5277 4029 Pls
+5351 3738 Pls
+5424 3440 Pls
+5497 3137 Pls
+5570 2830 Pls
+5643 2518 Pls
+5716 2203 Pls
+5789 1886 Pls
+5862 1567 Pls
+5936 1248 Pls
+6009 1567 Pls
+6082 1886 Pls
+6155 2203 Pls
+6228 2518 Pls
+6301 2830 Pls
+6374 3137 Pls
+6447 3440 Pls
+6520 3738 Pls
+6594 4029 Pls
+6667 4313 Pls
+6740 4590 Pls
+6813 4858 Pls
+6886 5118 Pls
+6959 5367 Pls
+7032 5606 Pls
+7105 5835 Pls
+7179 6052 Pls
+7252 6257 Pls
+7325 6449 Pls
+7398 6629 Pls
+7471 6795 Pls
+7544 6947 Pls
+7617 7084 Pls
+7690 7208 Pls
+7764 7316 Pls
+7837 7409 Pls
+7910 7487 Pls
+7983 7549 Pls
+8056 7596 Pls
+8129 7626 Pls
+8202 7641 Pls
+8275 7640 Pls
+8349 7622 Pls
+8422 7589 Pls
+8495 7540 Pls
+8568 7475 Pls
+8641 7395 Pls
+8714 7299 Pls
+8787 7188 Pls
+8860 7062 Pls
+8934 6922 Pls
+9007 6768 Pls
+9080 6599 Pls
+9153 6418 Pls
+9226 6223 Pls
+9299 6016 Pls
+9372 5797 Pls
+9445 5567 Pls
+9519 5326 Pls
+9592 5075 Pls
+9665 4814 Pls
+9738 4544 Pls
+9811 4266 Pls
+9884 3981 Pls
+9957 3688 Pls
+10030 3390 Pls
+10104 3086 Pls
+10177 2778 Pls
+10250 2465 Pls
+10323 2150 Pls
+% End plot #2
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/convhull.pdf b/doc/interpreter/convhull.pdf
new file mode 100644
index 0000000..f50d8b1
Binary files /dev/null and b/doc/interpreter/convhull.pdf differ
diff --git a/doc/interpreter/convhull.png b/doc/interpreter/convhull.png
new file mode 100644
index 0000000..130c4b6
Binary files /dev/null and b/doc/interpreter/convhull.png differ
diff --git a/doc/interpreter/convhull.txt b/doc/interpreter/convhull.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/convhull.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/cp-idx.texi b/doc/interpreter/cp-idx.texi
new file mode 100644
index 0000000..76eae6c
--- /dev/null
+++ b/doc/interpreter/cp-idx.texi
@@ -0,0 +1,24 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Concept Index
+ at unnumbered Concept Index
+
+ at printindex cp
diff --git a/doc/interpreter/cp-idx.txi b/doc/interpreter/cp-idx.txi
new file mode 100644
index 0000000..58c51f0
--- /dev/null
+++ b/doc/interpreter/cp-idx.txi
@@ -0,0 +1,22 @@
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Concept Index
+ at unnumbered Concept Index
+
+ at printindex cp
diff --git a/doc/interpreter/data.texi b/doc/interpreter/data.texi
new file mode 100644
index 0000000..26aab4e
--- /dev/null
+++ b/doc/interpreter/data.texi
@@ -0,0 +1,404 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Data Types
+ at chapter Data Types
+ at cindex data types
+
+All versions of Octave include a number of built-in data types,
+including real and complex scalars and matrices, character strings,
+a data structure type, and an array that can contain all data types.
+
+It is also possible to define new specialized data types by writing a
+small amount of C++ code.  On some systems, new data types can be loaded
+dynamically while Octave is running, so it is not necessary to recompile
+all of Octave just to add a new type.  @xref{Dynamically Linked
+Functions}, for more information about Octave's dynamic linking
+capabilities.  @ref{User-defined Data Types} describes what you must do
+to define a new data type for Octave.
+
+ at c ov-typeinfo.cc
+ at anchor{doc-typeinfo}
+ at deftypefn {Built-in Function} {} typeinfo (@var{expr})
+
+Return the type of the expression @var{expr}, as a string.  If
+ at var{expr} is omitted, return an array of strings containing all the
+currently installed data types.
+ at end deftypefn
+
+
+ at menu
+* Built-in Data Types::         
+* User-defined Data Types::     
+* Object Sizes::                
+ at end menu
+
+ at node Built-in Data Types
+ at section Built-in Data Types
+ at cindex data types, built-in
+ at cindex built-in data types
+
+The standard built-in data types are real and complex scalars and
+matrices, ranges, character strings, a data structure type, and cell
+arrays.  Additional built-in data types may be added in future versions.
+If you need a specialized data type that is not currently provided as a
+built-in type, you are encouraged to write your own user-defined data
+type and contribute it for distribution in a future release of Octave.
+
+The data type of a variable can be determined and changed through the
+use of the following functions.
+
+ at c ov-class.cc
+ at anchor{doc-class}
+ at deftypefn {Built-in Function} {} class (@var{expr})
+ at deftypefnx {Built-in Function} {} class (@var{s}, @var{id})
+ at deftypefnx {Built-in Function} {} class (@var{s}, @var{id}, @var{p}, @dots{})
+Return the class of the expression @var{expr} or create a class with
+fields from structure @var{s} and name (string) @var{id}.  Additional
+arguments name a list of parent classes from which the new class is
+derived.
+ at end deftypefn
+
+
+ at c ./general/isa.m
+ at anchor{doc-isa}
+ at deftypefn {Function File} {} isa (@var{x}, @var{class})
+Return true if @var{x} is a value from the class @var{class}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/cast.m
+ at anchor{doc-cast}
+ at deftypefn {Function File} {} cast (@var{val}, @var{type})
+Convert @var{val} to data type @var{type}.
+ at seealso{@ref{doc-int8,,int8}, @ref{doc-uint8,,uint8}, @ref{doc-int16,,int16}, @ref{doc-uint16,,uint16}, @ref{doc-int32,,int32}, @ref{doc-uint32,,uint32}, @ref{doc-int64,,int64}, @ref{doc-uint64,,uint64}, @ref{doc-double,,double}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/typecast.cc
+ at anchor{doc-typecast}
+ at deftypefn {Loadable Function} {} typecast (@var{x}, @var{type})
+Convert from one datatype to another without changing the underlying
+data.  The argument @var{type} defines the type of the return argument
+and must be one of 'uint8', 'uint16', 'uint32', 'uint64', 'int8', 'int16',
+'int32', 'int64', 'single' or 'double'.
+
+An example of the use of typecast on a little-endian machine is
+
+ at example
+ at group
+ at var{x} = uint16 ([1, 65535]);
+typecast (@var{x}, 'uint8')
+ at result{} [   0,   1, 255, 255]
+ at end group
+ at end example
+ at seealso{@ref{doc-cast,,cast}, @ref{doc-swapbytes,,swapbytes}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/swapbytes.m
+ at anchor{doc-swapbytes}
+ at deftypefn {Function File} {} swapbytes (@var{x})
+Swaps the byte order on values, converting from little endian to big 
+endian and vice versa.  For example
+
+ at example
+ at group
+swapbytes (uint16 (1:4))
+ at result{} [   256   512   768  1024]
+ at end group
+ at end example
+
+ at seealso{@ref{doc-typecast,,typecast}, @ref{doc-cast,,cast}}
+ at end deftypefn
+
+
+ at menu
+* Numeric Objects::             
+* Missing Data::                
+* String Objects::              
+* Data Structure Objects::      
+* Cell Array Objects::          
+ at end menu
+
+ at node Numeric Objects
+ at subsection Numeric Objects
+ at cindex numeric constant
+ at cindex numeric value
+
+Octave's built-in numeric objects include real, complex, and integer
+scalars and matrices.  All built-in floating point numeric data is
+currently stored as double precision numbers.  On systems that use the
+IEEE floating point format, values in the range of approximately
+ at tex
+ $2.2251\times10^{-308}$ to $1.7977\times10^{308}$
+ at end tex
+ at ifnottex
+ 2.2251e-308 to 1.7977e+308
+ at end ifnottex
+ can be stored, and the relative precision is approximately
+ at tex
+ $2.2204\times10^{-16}$.
+ at end tex
+ at ifnottex
+ 2.2204e-16.
+ at end ifnottex
+The exact values are given by the variables @code{realmin},
+ at code{realmax}, and @code{eps}, respectively.
+
+Matrix objects can be of any size, and can be dynamically reshaped and
+resized.  It is easy to extract individual rows, columns, or submatrices
+using a variety of powerful indexing features.  @xref{Index Expressions}.
+
+ at xref{Numeric Data Types}, for more information.
+
+ at node Missing Data
+ at subsection Missing Data
+ at cindex missing data
+
+It is possible to represent missing data explicitly in Octave using
+ at code{NA} (short for ``Not Available'').  Missing data can only be
+represented when data is represented as floating point numbers.  In this
+case missing data is represented as a special case of the representation
+of @code{NaN}.
+
+ at c data.cc
+ at anchor{doc-NA}
+ at deftypefn  {Built-in Function} {} NA
+ at deftypefnx {Built-in Function} {} NA (@var{n})
+ at deftypefnx {Built-in Function} {} NA (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} NA (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} NA (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the special constant used to designate missing values.
+
+Note that NA always compares not equal to NA (NA != NA).
+To find NA values, use the @code{isna} function.
+
+When called with no arguments, return a scalar with the value @samp{NA}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{@ref{doc-isna,,isna}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isna}
+ at deftypefn {Mapping Function} {} isna (@var{x})
+Return 1 for elements of @var{x} that are NA (missing) values and zero
+otherwise.  For example,
+
+ at example
+ at group
+isna ([13, Inf, NA, NaN])
+     @result{} [ 0, 0, 1, 0 ]
+ at end group
+ at end example
+ at seealso{@ref{doc-isnan,,isnan}}
+ at end deftypefn
+
+
+ at node String Objects
+ at subsection String Objects
+ at cindex strings
+ at cindex character strings
+ at opindex "
+ at opindex '
+
+A character string in Octave consists of a sequence of characters
+enclosed in either double-quote or single-quote marks.  Internally,
+Octave currently stores strings as matrices of characters.  All the
+indexing operations that work for matrix objects also work for strings.
+
+ at xref{Strings}, for more information.
+
+ at node Data Structure Objects
+ at subsection Data Structure Objects
+ at cindex structures
+ at cindex data structures
+
+Octave's data structure type can help you to organize related objects of
+different types.  The current implementation uses an associative array
+with indices limited to strings, but the syntax is more like C-style
+structures.
+
+ at xref{Data Structures}, for more information.
+
+ at node Cell Array Objects
+ at subsection Cell Array Objects
+ at cindex cell arrays
+
+A Cell Array in Octave is general array that can hold any number of
+different data types.
+
+ at xref{Cell Arrays}, for more information.
+
+ at node User-defined Data Types
+ at section User-defined Data Types
+ at cindex user-defined data types
+ at cindex data types, user-defined
+
+Someday I hope to expand this to include a complete description of
+Octave's mechanism for managing user-defined data types.  Until this
+feature is documented here, you will have to make do by reading the code
+in the @file{ov.h}, @file{ops.h}, and related files from Octave's
+ at file{src} directory.
+
+ at node Object Sizes
+ at section Object Sizes
+
+The following functions allow you to determine the size of a variable or
+expression.  These functions are defined for all objects.  They return
+ at minus{}1 when the operation doesn't make sense.  For example, Octave's
+data structure type doesn't have rows or columns, so the @code{rows} and
+ at code{columns} functions return @minus{}1 for structure arguments.
+
+ at c data.cc
+ at anchor{doc-ndims}
+ at deftypefn {Built-in Function} {} ndims (@var{a})
+Returns the number of dimensions of array @var{a}.
+For any array, the result will always be larger than or equal to 2.
+Trailing singleton dimensions are not counted.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-columns}
+ at deftypefn {Built-in Function} {} columns (@var{a})
+Return the number of columns of @var{a}.
+ at seealso{@ref{doc-size,,size}, @ref{doc-numel,,numel}, @ref{doc-rows,,rows}, @ref{doc-length,,length}, @ref{doc-isscalar,,isscalar}, @ref{doc-isvector,,isvector}, @ref{doc-ismatrix,,ismatrix}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-rows}
+ at deftypefn {Built-in Function} {} rows (@var{a})
+Return the number of rows of @var{a}.
+ at seealso{@ref{doc-size,,size}, @ref{doc-numel,,numel}, @ref{doc-columns,,columns}, @ref{doc-length,,length}, @ref{doc-isscalar,,isscalar}, @ref{doc-isvector,,isvector}, @ref{doc-ismatrix,,ismatrix}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-numel}
+ at deftypefn {Built-in Function} {} numel (@var{a})
+Returns the number of elements in the object @var{a}.
+ at seealso{@ref{doc-size,,size}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-length}
+ at deftypefn {Built-in Function} {} length (@var{a})
+Return the `length' of the object @var{a}.  For matrix objects, the
+length is the number of rows or columns, whichever is greater (this
+odd definition is used for compatibility with @sc{matlab}).
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-size}
+ at deftypefn {Built-in Function} {} size (@var{a}, @var{n})
+Return the number rows and columns of @var{a}.
+
+With one input argument and one output argument, the result is returned
+in a row vector.  If there are multiple output arguments, the number of
+rows is assigned to the first, and the number of columns to the second,
+etc.  For example,
+
+ at example
+ at group
+size ([1, 2; 3, 4; 5, 6])
+     @result{} [ 3, 2 ]
+
+[nr, nc] = size ([1, 2; 3, 4; 5, 6])
+     @result{} nr = 3
+     @result{} nc = 2
+ at end group
+ at end example
+
+If given a second argument, @code{size} will return the size of the
+corresponding dimension.  For example
+
+ at example
+ at group
+size ([1, 2; 3, 4; 5, 6], 2)
+     @result{} 2
+ at end group
+ at end example
+
+ at noindent
+returns the number of columns in the given matrix.
+ at seealso{@ref{doc-numel,,numel}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-isempty}
+ at deftypefn {Built-in Function} {} isempty (@var{a})
+Return 1 if @var{a} is an empty matrix (either the number of rows, or
+the number of columns, or both are zero).  Otherwise, return 0.
+ at end deftypefn
+
+
+ at c ov-null-mat.cc
+ at anchor{doc-isnull}
+ at deftypefn {Built-in Function} {} isnull (@var{x})
+Return 1 if @var{x} is a special null matrix, string or single quoted string.
+Indexed assignment with such a value as right-hand side should delete array elements.
+This function should be used when overloading indexed assignment for user-defined 
+classes instead of @code{isempty}, to distinguish the cases:
+ at table @asis
+ at item @code{A(I) = []}
+This should delete elements if @code{I} is nonempty.
+ at item @code{X = []; A(I) = X}
+This should give an error if @code{I} is nonempty.
+ at end table
+ at end deftypefn
+
+
+ at c ov.cc
+ at anchor{doc-sizeof}
+ at deftypefn {Built-in Function} {} sizeof (@var{val})
+Return the size of @var{val} in bytes
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-size_equal}
+ at deftypefn {Built-in Function} {} size_equal (@var{a}, @var{b}, @dots{})
+Return true if the dimensions of all arguments agree.
+Trailing singleton dimensions are ignored.
+Called with a single argument, size_equal returns true.
+ at seealso{@ref{doc-size,,size}, @ref{doc-numel,,numel}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-squeeze}
+ at deftypefn {Built-in Function} {} squeeze (@var{x})
+Remove singleton dimensions from @var{x} and return the result.
+Note that for compatibility with @sc{matlab}, all objects have
+a minimum of two dimensions and row vectors are left unchanged.
+ at end deftypefn
+
diff --git a/doc/interpreter/data.txi b/doc/interpreter/data.txi
new file mode 100644
index 0000000..75946ee
--- /dev/null
+++ b/doc/interpreter/data.txi
@@ -0,0 +1,196 @@
+ at c Copyright (C) 1996, 1997, 2007, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Data Types
+ at chapter Data Types
+ at cindex data types
+
+All versions of Octave include a number of built-in data types,
+including real and complex scalars and matrices, character strings,
+a data structure type, and an array that can contain all data types.
+
+It is also possible to define new specialized data types by writing a
+small amount of C++ code.  On some systems, new data types can be loaded
+dynamically while Octave is running, so it is not necessary to recompile
+all of Octave just to add a new type.  @xref{Dynamically Linked
+Functions}, for more information about Octave's dynamic linking
+capabilities.  @ref{User-defined Data Types} describes what you must do
+to define a new data type for Octave.
+
+ at DOCSTRING(typeinfo)
+
+ at menu
+* Built-in Data Types::         
+* User-defined Data Types::     
+* Object Sizes::                
+ at end menu
+
+ at node Built-in Data Types
+ at section Built-in Data Types
+ at cindex data types, built-in
+ at cindex built-in data types
+
+The standard built-in data types are real and complex scalars and
+matrices, ranges, character strings, a data structure type, and cell
+arrays.  Additional built-in data types may be added in future versions.
+If you need a specialized data type that is not currently provided as a
+built-in type, you are encouraged to write your own user-defined data
+type and contribute it for distribution in a future release of Octave.
+
+The data type of a variable can be determined and changed through the
+use of the following functions.
+
+ at DOCSTRING(class)
+
+ at DOCSTRING(isa)
+
+ at DOCSTRING(cast)
+
+ at DOCSTRING(typecast)
+
+ at DOCSTRING(swapbytes)
+
+ at menu
+* Numeric Objects::             
+* Missing Data::                
+* String Objects::              
+* Data Structure Objects::      
+* Cell Array Objects::          
+ at end menu
+
+ at node Numeric Objects
+ at subsection Numeric Objects
+ at cindex numeric constant
+ at cindex numeric value
+
+Octave's built-in numeric objects include real, complex, and integer
+scalars and matrices.  All built-in floating point numeric data is
+currently stored as double precision numbers.  On systems that use the
+IEEE floating point format, values in the range of approximately
+ at tex
+ $2.2251\times10^{-308}$ to $1.7977\times10^{308}$
+ at end tex
+ at ifnottex
+ 2.2251e-308 to 1.7977e+308
+ at end ifnottex
+ can be stored, and the relative precision is approximately
+ at tex
+ $2.2204\times10^{-16}$.
+ at end tex
+ at ifnottex
+ 2.2204e-16.
+ at end ifnottex
+The exact values are given by the variables @code{realmin},
+ at code{realmax}, and @code{eps}, respectively.
+
+Matrix objects can be of any size, and can be dynamically reshaped and
+resized.  It is easy to extract individual rows, columns, or submatrices
+using a variety of powerful indexing features.  @xref{Index Expressions}.
+
+ at xref{Numeric Data Types}, for more information.
+
+ at node Missing Data
+ at subsection Missing Data
+ at cindex missing data
+
+It is possible to represent missing data explicitly in Octave using
+ at code{NA} (short for ``Not Available'').  Missing data can only be
+represented when data is represented as floating point numbers.  In this
+case missing data is represented as a special case of the representation
+of @code{NaN}.
+
+ at DOCSTRING(NA)
+
+ at DOCSTRING(isna)
+
+ at node String Objects
+ at subsection String Objects
+ at cindex strings
+ at cindex character strings
+ at opindex "
+ at opindex '
+
+A character string in Octave consists of a sequence of characters
+enclosed in either double-quote or single-quote marks.  Internally,
+Octave currently stores strings as matrices of characters.  All the
+indexing operations that work for matrix objects also work for strings.
+
+ at xref{Strings}, for more information.
+
+ at node Data Structure Objects
+ at subsection Data Structure Objects
+ at cindex structures
+ at cindex data structures
+
+Octave's data structure type can help you to organize related objects of
+different types.  The current implementation uses an associative array
+with indices limited to strings, but the syntax is more like C-style
+structures.
+
+ at xref{Data Structures}, for more information.
+
+ at node Cell Array Objects
+ at subsection Cell Array Objects
+ at cindex cell arrays
+
+A Cell Array in Octave is general array that can hold any number of
+different data types.
+
+ at xref{Cell Arrays}, for more information.
+
+ at node User-defined Data Types
+ at section User-defined Data Types
+ at cindex user-defined data types
+ at cindex data types, user-defined
+
+Someday I hope to expand this to include a complete description of
+Octave's mechanism for managing user-defined data types.  Until this
+feature is documented here, you will have to make do by reading the code
+in the @file{ov.h}, @file{ops.h}, and related files from Octave's
+ at file{src} directory.
+
+ at node Object Sizes
+ at section Object Sizes
+
+The following functions allow you to determine the size of a variable or
+expression.  These functions are defined for all objects.  They return
+ at minus{}1 when the operation doesn't make sense.  For example, Octave's
+data structure type doesn't have rows or columns, so the @code{rows} and
+ at code{columns} functions return @minus{}1 for structure arguments.
+
+ at DOCSTRING(ndims)
+
+ at DOCSTRING(columns)
+
+ at DOCSTRING(rows)
+
+ at DOCSTRING(numel)
+
+ at DOCSTRING(length)
+
+ at DOCSTRING(size)
+
+ at DOCSTRING(isempty)
+
+ at DOCSTRING(isnull)
+
+ at DOCSTRING(sizeof)
+
+ at DOCSTRING(size_equal)
+
+ at DOCSTRING(squeeze)
diff --git a/doc/interpreter/debug.texi b/doc/interpreter/debug.texi
new file mode 100644
index 0000000..86f2540
--- /dev/null
+++ b/doc/interpreter/debug.texi
@@ -0,0 +1,335 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Debugging
+ at chapter Debugging
+
+Octave includes a built-in debugger to aid in the development of
+scripts.  This can be used to interrupt the execution of an Octave script
+at a certain point, or when certain conditions are met.  Once execution
+has stopped, and debug mode is entered, the symbol table at the point
+where execution has stopped can be examined and modified to check for
+errors.
+
+The normal command-line editing and history functions are available in
+debug mode.
+
+ at menu
+* Entering Debug Mode::
+* Leaving Debug Mode::
+* Breakpoints::
+* Debug Mode::
+* Call Stack::
+ at end menu
+
+ at node Entering Debug Mode
+ at section Entering Debug Mode
+
+There are two basic means of interrupting the execution of an Octave
+script.  These are breakpoints @pxref{Breakpoints}, discussed in the next
+section and interruption based on some condition.
+
+Octave supports three means to stop execution based on the values set in
+the functions @code{debug_on_interrupt}, @code{debug_on_warning} and
+ at code{debug_on_error}.
+
+ at c sighandlers.cc
+ at anchor{doc-debug_on_interrupt}
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_interrupt (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to enter debugging mode when it receives an interrupt signal (typically
+generated with @kbd{C-c}).  If a second interrupt signal is received
+before reaching the debugging mode, a normal interrupt will occur.
+ at end deftypefn
+
+
+ at c error.cc
+ at anchor{doc-debug_on_warning}
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_warning ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_warning (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to enter the debugger when a warning is encountered.
+ at end deftypefn
+
+
+ at c error.cc
+ at anchor{doc-debug_on_error}
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_error ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_error (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to enter the debugger when an error is encountered.  This will also
+inhibit printing of the normal traceback message (you will only see
+the top-level error message).
+ at end deftypefn
+
+
+ at node Leaving Debug Mode
+ at section Leavinging Debug Mode
+
+To leave the debug mode, use either @code{dbcont} 
+or @code{return}.
+
+ at c debug.cc
+ at anchor{doc-dbcont}
+ at deftypefn {Command} {} dbcont ()
+In debugging mode, quit debugging mode and continue execution.
+ at seealso{@ref{doc-dbstep,,dbstep}, @ref{doc-dbstep,,dbstep}}
+ at end deftypefn
+
+
+To quit debug mode and return directly to the prompt @code{dbquit}
+should be used instead
+
+ at c debug.cc
+ at anchor{doc-dbquit}
+ at deftypefn {Command} {} dbquit ()
+In debugging mode, quit debugging mode and return to the top level.
+ at seealso{@ref{doc-dbstep,,dbstep}, @ref{doc-dbcont,,dbcont}}
+ at end deftypefn
+
+
+Finally, typing @code{exit} or @code{quit} at the debug prompt will
+result in Octave terminating normally.
+
+ at node Breakpoints
+ at section Breakpoints
+
+Breakpoints can be set in any Octave function, using the @code{dbstop}
+function.
+
+ at c debug.cc
+ at anchor{doc-dbstop}
+ at deftypefn {Loadable Function} {@var{rline} =} dbstop (@var{func}, @var{line}, @dots{})
+Set a breakpoint in a function
+ at table @code
+ at item func
+String representing the function name.  When already in debug
+mode this should be left out and only the line should be given.
+ at item line
+Line number you would like the breakpoint to be set on.  Multiple
+lines might be given as separate arguments or as a vector.
+ at end table
+
+The rline returned is the real line that the breakpoint was set at.
+ at seealso{@ref{doc-dbclear,,dbclear}, @ref{doc-dbstatus,,dbstatus}, @ref{doc-dbstep,,dbstep}}
+ at end deftypefn
+
+
+ at noindent
+Note that breakpoints cannot be set in built-in functions
+(e.g., @code{sin}, etc.) or dynamically loaded function (i.e., oct-files).  To
+set a breakpoint immediately on entering a function, the breakpoint
+should be set to line 1. The leading comment block will be ignored and
+the breakpoint will be set to the first executable statement in the
+function.  For example
+
+ at example
+ at group
+dbstop ("asind", 1)
+ at result{} 27
+ at end group
+ at end example
+
+ at noindent
+Note that the return value of @code{27} means that the breakpoint was
+effectively set to line 27.  The status of breakpoints in a function can
+be queried with the @code{dbstatus} function.
+
+ at c debug.cc
+ at anchor{doc-dbstatus}
+ at deftypefn {Loadable Function} {lst =} dbstatus (@var{func})
+Return a vector containing the lines on which a function has 
+breakpoints set.
+ at table @code
+ at item func
+String representing the function name.  When already in debug
+mode this should be left out.
+ at end table
+ at seealso{@ref{doc-dbclear,,dbclear}, @ref{doc-dbwhere,,dbwhere}}
+ at end deftypefn
+
+
+ at noindent
+Taking the above as an example, @code{dbstatus ("asind")} should return
+27.  The breakpoints can then be cleared with the @code{dbclear} function
+
+ at c debug.cc
+ at anchor{doc-dbclear}
+ at deftypefn {Loadable Function} {} dbclear (@var{func}, @var{line}, @dots{})
+Delete a breakpoint in a function
+ at table @code
+ at item func
+String representing the function name.  When already in debug
+mode this should be left out and only the line should be given.
+ at item line
+Line number where you would like to remove the breakpoint.  Multiple
+lines might be given as separate arguments or as a vector.
+ at end table
+No checking is done to make sure that the line you requested is really
+a breakpoint.  If you get the wrong line nothing will happen.
+ at seealso{@ref{doc-dbstop,,dbstop}, @ref{doc-dbstatus,,dbstatus}, @ref{doc-dbwhere,,dbwhere}}
+ at end deftypefn
+
+
+ at noindent
+These functions can be used to clear all the breakpoints in a function.  For example,
+
+ at example
+dbclear ("asind", dbstatus ("asind"));
+ at end example
+
+A breakpoint can be set in a subfunction.  For example if a file contains
+the functions
+
+ at example
+ at group
+function y = func1 (x)
+  y = func2 (x);
+endfunction
+function y = func2 (x)
+  y = x + 1;
+endfunction
+ at end group
+ at end example
+
+ at noindent
+then a breakpoint can be set at the start of the subfunction directly
+with
+
+ at example
+ at group
+dbstop (["func1", filemarker(), "func2"])
+ at result{} 5
+ at end group
+ at end example
+
+Note that @code{filemarker} returns a character that marks the
+subfunctions from the file containing them.
+
+Another simple way of setting a breakpoint in an Octave script is the
+use of the @code{keyboard} function.
+
+ at c input.cc
+ at anchor{doc-keyboard}
+ at deftypefn  {Built-in Function} {} keyboard ()
+ at deftypefnx {Built-in Function} {} keyboard (@var{prompt})
+This function is normally used for simple debugging.  When the
+ at code{keyboard} function is executed, Octave prints a prompt and waits
+for user input.  The input strings are then evaluated and the results
+are printed.  This makes it possible to examine the values of variables
+within a function, and to assign new values if necessary.  To leave the
+prompt and return to normal execution type @samp{return} or @samp{dbcont}.
+The @code{keyboard} function does not return an exit status.
+
+If @code{keyboard} is invoked without arguments, a default prompt of
+ at samp{debug> } is used.
+ at seealso{@ref{doc-dbcont,,dbcont}, @ref{doc-dbquit,,dbquit}}
+ at end deftypefn
+
+
+ at noindent
+The @code{keyboard} function is typically placed in a script at the
+point where the user desires that the execution is stopped.  It
+automatically sets the running script into the debug mode.
+
+ at node Debug Mode
+ at section Debug Mode
+
+There are two additional support functions that allow the user to
+interrogate where in the execution of a script Octave entered the debug
+mode and to print the code in the script surrounding the point where
+Octave entered debug mode.
+
+ at c debug.cc
+ at anchor{doc-dbwhere}
+ at deftypefn {Loadable Function} {} dbwhere ()
+Show where we are in the code
+ at seealso{@ref{doc-dbclear,,dbclear}, @ref{doc-dbstatus,,dbstatus}, @ref{doc-dbstop,,dbstop}}
+ at end deftypefn
+
+
+ at c debug.cc
+ at anchor{doc-dbtype}
+ at deftypefn {Loadable Function} {} dbtype ()
+List script file with line numbers.
+ at seealso{@ref{doc-dbclear,,dbclear}, @ref{doc-dbstatus,,dbstatus}, @ref{doc-dbstop,,dbstop}}
+ at end deftypefn
+
+
+You may also use @code{isdebugmode} to determine whether the debugger is
+currently active.
+
+ at c debug.cc
+ at anchor{doc-isdebugmode}
+ at deftypefn {Command} {} isdebugmode ()
+Return true if debug mode is on, otherwise false.
+ at seealso{@ref{doc-dbstack,,dbstack}, @ref{doc-dbclear,,dbclear}, @ref{doc-dbstop,,dbstop}, @ref{doc-dbstatus,,dbstatus}}
+ at end deftypefn
+
+
+Debug mode also allows single line stepping through a function using
+the commands @code{dbstep}.
+
+ at c debug.cc
+ at anchor{doc-dbstep}
+ at deftypefn {Command} {} dbstep @var{n}
+ at deftypefnx {Command} {} dbstep in
+ at deftypefnx {Command} {} dbstep out
+In debugging mode, execute the next @var{n} lines of code.  If @var{n} is
+omitted execute the next line of code.  If the next line of code is itself
+defined in terms of an m-file remain in the existing function.
+
+Using @code{dbstep in} will cause execution of the next line to step into
+any m-files defined on the next line.  Using @code{dbstep out} with cause
+execution to continue until the current function returns.
+ at seealso{@ref{doc-dbcont,,dbcont}, @ref{doc-dbquit,,dbquit}}
+ at end deftypefn
+
+
+ at node Call Stack
+ at section Call Stack
+
+ at c debug.cc
+ at anchor{doc-dbstack}
+ at deftypefn {Loadable Function} {[@var{stack}, @var{idx}]} dbstack (@var{n})
+Print or return current stack information.  With optional argument
+ at var{n}, omit the @var{n} innermost stack frames.
+ at seealso{@ref{doc-dbclear,,dbclear}, @ref{doc-dbstatus,,dbstatus}, @ref{doc-dbstop,,dbstop}}
+ at end deftypefn
+
+
+ at c debug.cc
+ at anchor{doc-dbup}
+ at deftypefn {Loadable Function} {} dbup (@var{n})
+In debugging mode, move up the execution stack @var{n} frames.
+If @var{n} is omitted, move up one frame.
+ at seealso{@ref{doc-dbstack,,dbstack}}
+ at end deftypefn
+
+
+ at c debug.cc
+ at anchor{doc-dbdown}
+ at deftypefn {Loadable Function} {} dbdown (@var{n})
+In debugging mode, move down the execution stack @var{n} frames.
+If @var{n} is omitted, move down one frame.
+ at seealso{@ref{doc-dbstack,,dbstack}}
+ at end deftypefn
+
diff --git a/doc/interpreter/debug.txi b/doc/interpreter/debug.txi
new file mode 100644
index 0000000..d2ba919
--- /dev/null
+++ b/doc/interpreter/debug.txi
@@ -0,0 +1,183 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Debugging
+ at chapter Debugging
+
+Octave includes a built-in debugger to aid in the development of
+scripts.  This can be used to interrupt the execution of an Octave script
+at a certain point, or when certain conditions are met.  Once execution
+has stopped, and debug mode is entered, the symbol table at the point
+where execution has stopped can be examined and modified to check for
+errors.
+
+The normal command-line editing and history functions are available in
+debug mode.
+
+ at menu
+* Entering Debug Mode::
+* Leaving Debug Mode::
+* Breakpoints::
+* Debug Mode::
+* Call Stack::
+ at end menu
+
+ at node Entering Debug Mode
+ at section Entering Debug Mode
+
+There are two basic means of interrupting the execution of an Octave
+script.  These are breakpoints @pxref{Breakpoints}, discussed in the next
+section and interruption based on some condition.
+
+Octave supports three means to stop execution based on the values set in
+the functions @code{debug_on_interrupt}, @code{debug_on_warning} and
+ at code{debug_on_error}.
+
+ at DOCSTRING(debug_on_interrupt)
+
+ at DOCSTRING(debug_on_warning)
+
+ at DOCSTRING(debug_on_error)
+
+ at node Leaving Debug Mode
+ at section Leavinging Debug Mode
+
+To leave the debug mode, use either @code{dbcont} 
+or @code{return}.
+
+ at DOCSTRING(dbcont)
+
+To quit debug mode and return directly to the prompt @code{dbquit}
+should be used instead
+
+ at DOCSTRING(dbquit)
+
+Finally, typing @code{exit} or @code{quit} at the debug prompt will
+result in Octave terminating normally.
+
+ at node Breakpoints
+ at section Breakpoints
+
+Breakpoints can be set in any Octave function, using the @code{dbstop}
+function.
+
+ at DOCSTRING(dbstop)
+
+ at noindent
+Note that breakpoints cannot be set in built-in functions
+(e.g., @code{sin}, etc.) or dynamically loaded function (i.e., oct-files).  To
+set a breakpoint immediately on entering a function, the breakpoint
+should be set to line 1. The leading comment block will be ignored and
+the breakpoint will be set to the first executable statement in the
+function.  For example
+
+ at example
+ at group
+dbstop ("asind", 1)
+ at result{} 27
+ at end group
+ at end example
+
+ at noindent
+Note that the return value of @code{27} means that the breakpoint was
+effectively set to line 27.  The status of breakpoints in a function can
+be queried with the @code{dbstatus} function.
+
+ at DOCSTRING(dbstatus)
+
+ at noindent
+Taking the above as an example, @code{dbstatus ("asind")} should return
+27.  The breakpoints can then be cleared with the @code{dbclear} function
+
+ at DOCSTRING(dbclear)
+
+ at noindent
+These functions can be used to clear all the breakpoints in a function.  For example,
+
+ at example
+dbclear ("asind", dbstatus ("asind"));
+ at end example
+
+A breakpoint can be set in a subfunction.  For example if a file contains
+the functions
+
+ at example
+ at group
+function y = func1 (x)
+  y = func2 (x);
+endfunction
+function y = func2 (x)
+  y = x + 1;
+endfunction
+ at end group
+ at end example
+
+ at noindent
+then a breakpoint can be set at the start of the subfunction directly
+with
+
+ at example
+ at group
+dbstop (["func1", filemarker(), "func2"])
+ at result{} 5
+ at end group
+ at end example
+
+Note that @code{filemarker} returns a character that marks the
+subfunctions from the file containing them.
+
+Another simple way of setting a breakpoint in an Octave script is the
+use of the @code{keyboard} function.
+
+ at DOCSTRING(keyboard)
+
+ at noindent
+The @code{keyboard} function is typically placed in a script at the
+point where the user desires that the execution is stopped.  It
+automatically sets the running script into the debug mode.
+
+ at node Debug Mode
+ at section Debug Mode
+
+There are two additional support functions that allow the user to
+interrogate where in the execution of a script Octave entered the debug
+mode and to print the code in the script surrounding the point where
+Octave entered debug mode.
+
+ at DOCSTRING(dbwhere)
+
+ at DOCSTRING(dbtype)
+
+You may also use @code{isdebugmode} to determine whether the debugger is
+currently active.
+
+ at DOCSTRING(isdebugmode)
+
+Debug mode also allows single line stepping through a function using
+the commands @code{dbstep}.
+
+ at DOCSTRING(dbstep)
+
+ at node Call Stack
+ at section Call Stack
+
+ at DOCSTRING(dbstack)
+
+ at DOCSTRING(dbup)
+
+ at DOCSTRING(dbdown)
diff --git a/doc/interpreter/delaunay.eps b/doc/interpreter/delaunay.eps
new file mode 100644
index 0000000..d5ecc75
--- /dev/null
+++ b/doc/interpreter/delaunay.eps
@@ -0,0 +1,805 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: delaunay.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:47:03 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (delaunay.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:47:03 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2335 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2335 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3742 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3742 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5148 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5148 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6555 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6555 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3259 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3259 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5043 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5043 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6828 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6828 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8612 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8612 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 2312 7269 M
+362 -462 V
+1728 1143 L
+584 6126 V
+% End plot #1
+% Begin plot #2
+stroke
+LT1
+0.00 0.00 1.00 C 5895 4061 M
+3750 943 L
+1728 1143 L
+5895 4061 L
+% End plot #2
+% Begin plot #3
+stroke
+LT2
+0.00 0.00 1.00 C 5895 4061 M
+2674 6807 L
+1728 1143 L
+5895 4061 L
+% End plot #3
+% Begin plot #4
+stroke
+LT3
+0.00 0.00 1.00 C 7288 2537 M
+5895 4061 L
+3140 -89 V
+7288 2537 L
+% End plot #4
+% Begin plot #5
+stroke
+LT4
+0.00 0.00 1.00 C 7288 2537 M
+5895 4061 L
+3750 943 L
+7288 2537 L
+% End plot #5
+% Begin plot #6
+stroke
+LT5
+0.00 0.00 1.00 C 5485 6003 M
+5895 4061 L
+2674 6807 L
+5485 6003 L
+% End plot #6
+% Begin plot #7
+stroke
+LT6
+0.00 0.00 1.00 C 5485 6003 M
+2312 7269 L
+6199 308 V
+5485 6003 L
+% End plot #7
+% Begin plot #8
+stroke
+LT7
+0.00 0.00 1.00 C 5485 6003 M
+2312 7269 L
+362 -462 V
+5485 6003 L
+% End plot #8
+% Begin plot #9
+stroke
+LT8
+0.00 0.00 1.00 C 8289 6290 M
+222 1287 V
+9035 3972 L
+8289 6290 L
+% End plot #9
+% Begin plot #10
+stroke
+LT0
+0.00 0.00 1.00 C 8289 6290 M
+5485 6003 L
+8511 7577 L
+8289 6290 L
+% End plot #10
+% Begin plot #11
+stroke
+LT1
+0.00 0.00 1.00 C 8289 6290 M
+5895 4061 L
+3140 -89 V
+8289 6290 L
+% End plot #11
+% Begin plot #12
+stroke
+LT2
+0.00 0.00 1.00 C 8289 6290 M
+5485 6003 L
+5895 4061 L
+8289 6290 L
+% End plot #12
+% Begin plot #13
+2.000 UP
+stroke
+LT3
+1.00 0.00 0.00 C 2674 6807 Star
+9035 3972 Star
+8289 6290 Star
+3750 943 Star
+5895 4061 Star
+5485 6003 Star
+7288 2537 Star
+8511 7577 Star
+2312 7269 Star
+1728 1143 Star
+% End plot #13
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/delaunay.pdf b/doc/interpreter/delaunay.pdf
new file mode 100644
index 0000000..3225783
Binary files /dev/null and b/doc/interpreter/delaunay.pdf differ
diff --git a/doc/interpreter/delaunay.png b/doc/interpreter/delaunay.png
new file mode 100644
index 0000000..5033b61
Binary files /dev/null and b/doc/interpreter/delaunay.png differ
diff --git a/doc/interpreter/delaunay.txt b/doc/interpreter/delaunay.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/delaunay.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/diagperm.texi b/doc/interpreter/diagperm.texi
new file mode 100644
index 0000000..c9de76e
--- /dev/null
+++ b/doc/interpreter/diagperm.texi
@@ -0,0 +1,527 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2009 Jaroslav Hajek
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Diagonal and Permutation Matrices 
+ at chapter Diagonal and Permutation Matrices
+
+ at menu
+* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Function Support::     Functions That Are Aware of These Matrices
+* Example Codes::        Some Examples of Usage
+* Zeros Treatment::      The Differences in Treatment of Zero Elements
+ at end menu
+
+ at node Basic Usage
+ at section Creating and Manipulating Diagonal and Permutation Matrices
+
+A diagonal matrix is defined as a matrix that has zero entries outside the main diagonal;
+that is, 
+ at tex
+$D_{ij} = 0$ if $i \neq j$
+ at end tex
+ at ifnottex
+ at code{D(i,j) == 0} if @code{i != j}.
+ at end ifnottex
+Most often, square diagonal matrices are considered; however, the definition can equally
+be applied to nonsquare matrices, in which case we usually speak of a rectangular diagonal 
+matrix.
+
+A permutation matrix is defined as a square matrix that has a single element equal to unity
+in each row and each column; all other elements are zero.  That is, there exists a 
+permutation (vector) 
+ at tex
+$p$ such that $P_{ij}=1$ if $j = p_i$ and
+$P_{ij}=0$ otherwise.  
+ at end tex
+ at ifnottex
+ at code{p} such that @code{P(i,j) == 1} if @code{j == p(i)} and 
+ at code{P(i,j) == 0} otherwise.  
+ at end ifnottex
+
+Octave provides special treatment of real and complex rectangular diagonal matrices,
+as well as permutation matrices.  They are stored as special objects, using efficient 
+storage and algorithms, facilitating writing both readable and efficient matrix algebra
+expressions in the Octave language.
+
+ at menu
+* Creating Diagonal Matrices::
+* Creating Permutation Matrices::
+* Explicit and Implicit Conversions::
+ at end menu
+
+ at node Creating Diagonal Matrices
+ at subsection Creating Diagonal Matrices
+
+The most common and easiest way to create a diagonal matrix is using the built-in
+function @dfn{diag}.  The expression @code{diag (v)}, with @var{v} a vector,
+will create a square diagonal matrix with elements on the main diagonal given
+by the elements of @var{v}, and size equal to the length of @var{v}.
+ at code{diag (v, m, n)} can be used to construct a rectangular diagonal matrix.
+The result of these expressions will be a special diagonal matrix object, rather
+than a general matrix object.
+
+Diagonal matrix with unit elements can be created using @dfn{eye}.
+Some other built-in functions can also return diagonal matrices.  Examples include
+ at dfn{balance} or @dfn{inv}.
+
+Example:
+ at example
+  diag (1:4)
+ at result{}
+Diagonal Matrix
+
+   1   0   0   0
+   0   2   0   0
+   0   0   3   0
+   0   0   0   4
+
+  diag(1:3,5,3)
+
+ at result{}
+Diagonal Matrix
+
+   1   0   0
+   0   2   0
+   0   0   3
+   0   0   0
+   0   0   0
+ at end example  
+
+ at node Creating Permutation Matrices
+ at subsection Creating Permutation Matrices
+
+For creating permutation matrices, Octave does not introduce a new function, but
+rather overrides an existing syntax: permutation matrices can be conveniently
+created by indexing an identity matrix by permutation vectors.
+That is, if @var{q} is a permutation vector of length @var{n}, the expression
+ at example
+  P = eye (n) (:, q);
+ at end example
+will create a permutation matrix - a special matrix object.
+ at example
+eye (n) (q, :) 
+ at end example
+will also work (and create a row permutation matrix), as well as 
+ at example
+eye (n) (q1, q2).
+ at end example
+
+For example:
+ at example
+ at group
+  eye (4) ([1,3,2,4],:)
+ at result{}
+Permutation Matrix
+
+   1   0   0   0
+   0   0   1   0
+   0   1   0   0
+   0   0   0   1
+
+  eye (4) (:,[1,3,2,4])
+ at result{}
+Permutation Matrix
+
+   1   0   0   0
+   0   0   1   0
+   0   1   0   0
+   0   0   0   1
+ at end group
+ at end example
+
+Mathematically, an identity matrix is both diagonal and permutation matrix.
+In Octave, @code{eye (n)} returns a diagonal matrix, because a matrix
+can only have one class.  You can convert this diagonal matrix to a permutation
+matrix by indexing it by an identity permutation, as shown below.
+This is a special property of the identity matrix; indexing other diagonal
+matrices generally produces a full matrix.
+
+ at example
+ at group
+  eye (3)
+ at result{}
+Diagonal Matrix
+
+   1   0   0
+   0   1   0
+   0   0   1
+
+  eye(3)(1:3,:)
+ at result{}
+Permutation Matrix
+
+   1   0   0
+   0   1   0
+   0   0   1
+ at end group
+ at end example
+
+Some other built-in functions can also return permutation matrices.  Examples include
+ at dfn{inv} or @dfn{lu}.
+
+ at node Explicit and Implicit Conversions
+ at subsection Explicit and Implicit Conversions
+
+The diagonal and permutation matrices are special objects in their own right.  A number
+of operations and built-in functions are defined for these matrices to use special,
+more efficient code than would be used for a full matrix in the same place.  Examples
+are given in further sections.
+
+To facilitate smooth mixing with full matrices, backward compatibility, and
+compatibility with @sc{matlab}, the diagonal and permutation matrices should allow
+any operation that works on full matrices, and will either treat it specially,
+or implicitly convert themselves to full matrices.
+
+Instances include matrix indexing, except for extracting a single element or
+a leading submatrix, indexed assignment, or applying most mapper functions,
+such as @dfn{exp}.
+
+An explicit conversion to a full matrix can be requested using the built-in
+function @dfn{full}.  It should also be noted that the diagonal and permutation
+matrix objects will cache the result of the conversion after it is first
+requested (explicitly or implicitly), so that subsequent conversions will
+be very cheap.
+
+ at node Matrix Algebra
+ at section Linear Algebra with Diagonal and Permutation Matrices
+
+As has been already said, diagonal and permutation matrices make it
+possible to use efficient algorithms while preserving natural linear
+algebra syntax.  This section describes in detail the operations that
+are treated specially when performed on these special matrix objects.
+
+ at menu
+* Expressions Involving Diagonal Matrices::
+* Expressions Involving Permutation Matrices::
+ at end menu
+
+ at node Expressions Involving Diagonal Matrices
+ at subsection Expressions Involving Diagonal Matrices
+
+Assume @var{D} is a diagonal matrix.  If @var{M} is a full matrix,
+then @code{D*M} will scale the rows of @var{M}.  That means,
+if @code{S = D*M}, then for each pair of indices
+i,j it holds 
+ at tex
+$$S_{ij} = D_{ii} M_{ij}$$
+ at end tex
+ at ifnottex
+ at example
+S(i,j) = D(i,i) * M(i,j).
+ at end example
+ at end ifnottex
+Similarly, @code{M*D} will do a column scaling.
+
+The matrix @var{D} may also be rectangular, m-by-n where @code{m != n}.
+If @code{m < n}, then the expression @code{D*M} is equivalent to
+ at example
+D(:,1:m) * M(1:m,:),
+ at end example
+i.e., trailing @code{n-m} rows of @var{M} are ignored.  If @code{m > n}, 
+then @code{D*M} is equivalent to 
+ at example
+[D(1:n,n) * M; zeros(m-n, columns (M))],
+ at end example
+i.e., null rows are appended to the result.
+The situation for right-multiplication @code{M*D} is analogous.
+
+The expressions @code{D \ M} and @code{M / D} perform inverse scaling.
+They are equivalent to solving a diagonal (or rectangular diagonal)
+in a least-squares minimum-norm sense.  In exact arithmetics, this is
+equivalent to multiplying by a pseudoinverse.  The pseudoinverse of
+a rectangular diagonal matrix is again a rectangular diagonal matrix
+with swapped dimensions, where each nonzero diagonal element is replaced
+by its reciprocal.
+The matrix division algorithms do, in fact, use division rather than 
+multiplication by reciprocals for better numerical accuracy; otherwise, they
+honor the above definition.  Note that a diagonal matrix is never truncated due
+to ill-conditioning; otherwise, it would not be much useful for scaling.  This
+is typically consistent with linear algebra needs.  A full matrix that only
+happens to be diagonal (an is thus not a special object) is of course treated
+normally.
+
+Multiplication and division by diagonal matrices works efficiently also when
+combined with sparse matrices, i.e., @code{D*S}, where @var{D} is a diagonal
+matrix and @var{S} is a sparse matrix scales the rows of the sparse matrix and
+returns a sparse matrix.  The expressions @code{S*D}, @code{D\S}, @code{S/D} work
+analogically.
+
+If @var{D1} and @var{D2} are both diagonal matrices, then the expressions
+ at example
+ at group
+D1 + D2
+D1 - D2 
+D1 * D2 
+D1 / D2 
+D1 \ D2
+ at end group
+ at end example
+again produce diagonal matrices, provided that normal
+dimension matching rules are obeyed.  The relations used are same as described above.
+
+Also, a diagonal matrix @var{D} can be multiplied or divided by a scalar, or raised
+to a scalar power if it is square, producing diagonal matrix result in all cases. 
+
+A diagonal matrix can also be transposed or conjugate-transposed, giving the expected
+result.  Extracting a leading submatrix of a diagonal matrix, i.e., @code{D(1:m,1:n)},
+will produce a diagonal matrix, other indexing expressions will implicitly convert to
+full matrix.
+
+Adding a diagonal matrix to a full matrix only operates on the diagonal elements.  Thus,
+ at example
+A = A + eps * eye (n)
+ at end example
+is an efficient method of augmenting the diagonal of a matrix.  Subtraction works
+analogically.
+
+When involved in expressions with other element-by-element operators, @code{.*},
+ at code{./}, @code{.\} or @code{.^}, an implicit conversion to full matrix will
+take place.  This is not always strictly necessary but chosen to facilitate
+better consistency with @sc{matlab}.
+
+ at node Expressions Involving Permutation Matrices
+ at subsection Expressions Involving Permutation Matrices
+
+If @var{P} is a permutation matrix and @var{M} a matrix, the expression
+ at code{P*M} will permute the rows of @var{M}.  Similarly, @code{M*P} will
+yield a column permutation. 
+Matrix division @code{P\M} and @code{M/P} can be used to do inverse permutation.
+
+The previously described syntax for creating permutation matrices can actually
+help an user to understand the connection between a permutation matrix and
+a permuting vector.  Namely, the following holds, where @code{I = eye (n)}
+is an identity matrix:
+ at example
+  I(p,:) * M = (I*M) (p,:) = M(p,:)
+ at end example
+Similarly,
+ at example
+  M * I(:,p) = (M*I) (:,p) = M(:,p)
+ at end example
+
+The expressions @code{I(p,:)} and @code{I(:,p)} are permutation matrices.
+
+A permutation matrix can be transposed (or conjugate-transposed, which is the
+same, because a permutation matrix is never complex), inverting the
+permutation, or equivalently, turning a row-permutation matrix into a
+column-permutation one.  For permutation matrices, transpose is equivalent to
+inversion, thus @code{P\M} is equivalent to @code{P'*M}.  Transpose of a
+permutation matrix (or inverse) is a constant-time operation, flipping only a
+flag internally, and thus the choice between the two above equivalent
+expressions for inverse permuting is completely up to the user's taste.
+
+Multiplication and division by permutation matrices works efficiently also when
+combined with sparse matrices, i.e., @code{P*S}, where @var{P} is a permutation
+matrix and @var{S} is a sparse matrix permutes the rows of the sparse matrix and
+returns a sparse matrix.  The expressions @code{S*P}, @code{P\S}, @code{S/P} work
+analogically.
+
+Two permutation matrices can be multiplied or divided (if their sizes match), performing
+a composition of permutations.  Also a permutation matrix can be indexed by a permutation
+vector (or two vectors), giving again a permutation matrix.
+Any other operations do not generally yield a permutation matrix and will thus
+trigger the implicit conversion.
+
+ at node Function Support
+ at section Functions That Are Aware of These Matrices
+
+This section lists the built-in functions that are aware of diagonal and
+permutation matrices on input, or can return them as output.  Passed to other
+functions, these matrices will in general trigger an implicit conversion.
+(Of course, user-defined dynamically linked functions may also work with
+diagonal or permutation matrices).
+
+ at menu
+* Diagonal Matrix Functions::
+* Permutation Matrix Functions::
+ at end menu
+
+ at node Diagonal Matrix Functions
+ at subsection Diagonal Matrix Functions
+
+ at dfn{inv} and @dfn{pinv} can be applied to a diagonal matrix, yielding again
+a diagonal matrix.  @dfn{det} will use an efficient straightforward calculation
+when given a diagonal matrix, as well as @dfn{cond}.
+The following mapper functions can be applied to a diagonal matrix
+without converting it to a full one:
+ at dfn{abs}, @dfn{real}, @dfn{imag}, @dfn{conj}, @dfn{sqrt}. 
+A diagonal matrix can also be returned from the @dfn{balance}
+and @dfn{svd} functions.
+The @dfn{sparse} function will convert a diagonal matrix efficiently to a
+sparse matrix.
+
+ at node Permutation Matrix Functions
+ at subsection Permutation Matrix Functions
+
+ at dfn{inv} and @dfn{pinv} will invert a permutation matrix, preserving its
+specialness.  @dfn{det} can be applied to a permutation matrix, efficiently
+calculating the sign of the permutation (which is equal to the determinant).
+
+A permutation matrix can also be returned from the built-in functions
+ at dfn{lu} and @dfn{qr}, if a pivoted factorization is requested.
+
+The @dfn{sparse} function will convert a permutation matrix efficiently to a
+sparse matrix.
+The @dfn{find} function will also work efficiently with a permutation matrix,
+making it possible to conveniently obtain the permutation indices.
+
+ at node Example Codes
+ at section Some Examples of Usage
+
+The following can be used to solve a linear system @code{A*x = b}
+using the pivoted LU factorization:
+ at example
+ at group
+  [L, U, P] = lu (A); ## now L*U = P*A
+  x = U \ L \ P*b;
+ at end group
+ at end example
+
+ at noindent
+This is how you normalize columns of a matrix @var{X} to unit norm:
+ at example
+ at group
+  s = norm (X, "columns");
+  X = diag (s) \ X;
+ at end group
+ at end example
+
+ at noindent
+The following expression is a way to efficiently calculate the sign of a
+permutation, given by a permutation vector @var{p}.  It will also work
+in earlier versions of Octave, but slowly.
+ at example
+  det (eye (length (p))(p, :))
+ at end example
+
+ at noindent
+Finally, here's how you solve a linear system @code{A*x = b} 
+with Tikhonov regularization (ridge regression) using SVD (a skeleton only):
+ at example
+ at group
+  m = rows (A); n = columns (A);
+  [U, S, V] = svd (A);
+  ## determine the regularization factor alpha
+  ## alpha = @dots{}
+  ## transform to orthogonal basis
+  b = U'*b;
+  ## Use the standard formula, replacing A with S.
+  ## S is diagonal, so the following will be very fast and accurate.
+  x = (S'*S + alpha^2 * eye (n)) \ (S' * b);
+  ## transform to solution basis
+  x = V*x;
+ at end group
+ at end example
+
+
+ at node Zeros Treatment
+ at section The Differences in Treatment of Zero Elements
+
+Making diagonal and permutation matrices special matrix objects in their own
+right and the consequent usage of smarter algorithms for certain operations
+implies, as a side effect, small differences in treating zeros.
+The contents of this section applies also to sparse matrices, discussed in
+the following chapter.
+
+The IEEE standard defines the result of the expressions @code{0*Inf} and 
+ at code{0*NaN} as @code{NaN}, as it has been generally agreed that this is the
+best compromise.
+Numerical software dealing with structured and sparse matrices (including
+Octave) however, almost always makes a distinction between a "numerical zero"
+and an "assumed zero". 
+A "numerical zero" is a zero value occurring in a place where any floating-point
+value could occur.  It is normally stored somewhere in memory as an explicit
+value. 
+An "assumed zero", on the contrary, is a zero matrix element implied by the
+matrix structure (diagonal, triangular) or a sparsity pattern; its value is
+usually not stored explicitly anywhere, but is implied by the underlying
+data structure.
+
+The primary distinction is that an assumed zero, when multiplied 
+by any number, or divided by any nonzero number,
+yields *always* a zero, even when, e.g., multiplied by @code{Inf}
+or divided by @code{NaN}.
+The reason for this behavior is that the numerical multiplication is not
+actually performed anywhere by the underlying algorithm; the result is
+just assumed to be zero.  Equivalently, one can say that the part of the
+computation involving assumed zeros is performed symbolically, not numerically.
+
+This behavior not only facilitates the most straightforward and efficient
+implementation of algorithms, but also preserves certain useful invariants,
+like:
+ at itemize
+ at item scalar * diagonal matrix is a diagonal matrix
+ at item sparse matrix / scalar preserves the sparsity pattern
+ at item permutation matrix * matrix is equivalent to permuting rows
+ at end itemize
+all of these natural mathematical truths would be invalidated by treating
+assumed zeros as numerical ones.
+
+Note that certain competing software does not strictly follow this principle
+and converts assumed zeros to numerical zeros in certain cases, while not doing
+so in other cases.  As of today, there are no intentions to mimic such behavior 
+in Octave.
+
+Examples of effects of assumed zeros vs. numerical zeros:
+ at example
+Inf * eye (3)
+ at result{}
+   Inf     0     0
+     0   Inf     0
+     0     0   Inf
+
+Inf * speye (3)
+ at result{}
+Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%])
+
+  (1, 1) -> Inf
+  (2, 2) -> Inf
+  (3, 3) -> Inf
+
+Inf * full (eye (3))
+ at result{}
+   Inf   NaN   NaN
+   NaN   Inf   NaN
+   NaN   NaN   Inf
+
+ at end example
+
+ at example
+ at group
+diag(1:3) * [NaN; 1; 1]
+ at result{}
+   NaN
+     2
+     3
+
+sparse(1:3,1:3,1:3) * [NaN; 1; 1]
+ at result{}
+   NaN
+     2
+     3
+[1,0,0;0,2,0;0,0,3] * [NaN; 1; 1]
+ at result{}
+   NaN
+   NaN
+   NaN
+ at end group
+ at end example
+
diff --git a/doc/interpreter/diagperm.txi b/doc/interpreter/diagperm.txi
new file mode 100644
index 0000000..693a2aa
--- /dev/null
+++ b/doc/interpreter/diagperm.txi
@@ -0,0 +1,525 @@
+ at c Copyright (C) 2009 Jaroslav Hajek
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Diagonal and Permutation Matrices 
+ at chapter Diagonal and Permutation Matrices
+
+ at menu
+* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Function Support::     Functions That Are Aware of These Matrices
+* Example Codes::        Some Examples of Usage
+* Zeros Treatment::      The Differences in Treatment of Zero Elements
+ at end menu
+
+ at node Basic Usage
+ at section Creating and Manipulating Diagonal and Permutation Matrices
+
+A diagonal matrix is defined as a matrix that has zero entries outside the main diagonal;
+that is, 
+ at tex
+$D_{ij} = 0$ if $i \neq j$
+ at end tex
+ at ifnottex
+ at code{D(i,j) == 0} if @code{i != j}.
+ at end ifnottex
+Most often, square diagonal matrices are considered; however, the definition can equally
+be applied to nonsquare matrices, in which case we usually speak of a rectangular diagonal 
+matrix.
+
+A permutation matrix is defined as a square matrix that has a single element equal to unity
+in each row and each column; all other elements are zero.  That is, there exists a 
+permutation (vector) 
+ at tex
+$p$ such that $P_{ij}=1$ if $j = p_i$ and
+$P_{ij}=0$ otherwise.  
+ at end tex
+ at ifnottex
+ at code{p} such that @code{P(i,j) == 1} if @code{j == p(i)} and 
+ at code{P(i,j) == 0} otherwise.  
+ at end ifnottex
+
+Octave provides special treatment of real and complex rectangular diagonal matrices,
+as well as permutation matrices.  They are stored as special objects, using efficient 
+storage and algorithms, facilitating writing both readable and efficient matrix algebra
+expressions in the Octave language.
+
+ at menu
+* Creating Diagonal Matrices::
+* Creating Permutation Matrices::
+* Explicit and Implicit Conversions::
+ at end menu
+
+ at node Creating Diagonal Matrices
+ at subsection Creating Diagonal Matrices
+
+The most common and easiest way to create a diagonal matrix is using the built-in
+function @dfn{diag}.  The expression @code{diag (v)}, with @var{v} a vector,
+will create a square diagonal matrix with elements on the main diagonal given
+by the elements of @var{v}, and size equal to the length of @var{v}.
+ at code{diag (v, m, n)} can be used to construct a rectangular diagonal matrix.
+The result of these expressions will be a special diagonal matrix object, rather
+than a general matrix object.
+
+Diagonal matrix with unit elements can be created using @dfn{eye}.
+Some other built-in functions can also return diagonal matrices.  Examples include
+ at dfn{balance} or @dfn{inv}.
+
+Example:
+ at example
+  diag (1:4)
+ at result{}
+Diagonal Matrix
+
+   1   0   0   0
+   0   2   0   0
+   0   0   3   0
+   0   0   0   4
+
+  diag(1:3,5,3)
+
+ at result{}
+Diagonal Matrix
+
+   1   0   0
+   0   2   0
+   0   0   3
+   0   0   0
+   0   0   0
+ at end example  
+
+ at node Creating Permutation Matrices
+ at subsection Creating Permutation Matrices
+
+For creating permutation matrices, Octave does not introduce a new function, but
+rather overrides an existing syntax: permutation matrices can be conveniently
+created by indexing an identity matrix by permutation vectors.
+That is, if @var{q} is a permutation vector of length @var{n}, the expression
+ at example
+  P = eye (n) (:, q);
+ at end example
+will create a permutation matrix - a special matrix object.
+ at example
+eye (n) (q, :) 
+ at end example
+will also work (and create a row permutation matrix), as well as 
+ at example
+eye (n) (q1, q2).
+ at end example
+
+For example:
+ at example
+ at group
+  eye (4) ([1,3,2,4],:)
+ at result{}
+Permutation Matrix
+
+   1   0   0   0
+   0   0   1   0
+   0   1   0   0
+   0   0   0   1
+
+  eye (4) (:,[1,3,2,4])
+ at result{}
+Permutation Matrix
+
+   1   0   0   0
+   0   0   1   0
+   0   1   0   0
+   0   0   0   1
+ at end group
+ at end example
+
+Mathematically, an identity matrix is both diagonal and permutation matrix.
+In Octave, @code{eye (n)} returns a diagonal matrix, because a matrix
+can only have one class.  You can convert this diagonal matrix to a permutation
+matrix by indexing it by an identity permutation, as shown below.
+This is a special property of the identity matrix; indexing other diagonal
+matrices generally produces a full matrix.
+
+ at example
+ at group
+  eye (3)
+ at result{}
+Diagonal Matrix
+
+   1   0   0
+   0   1   0
+   0   0   1
+
+  eye(3)(1:3,:)
+ at result{}
+Permutation Matrix
+
+   1   0   0
+   0   1   0
+   0   0   1
+ at end group
+ at end example
+
+Some other built-in functions can also return permutation matrices.  Examples include
+ at dfn{inv} or @dfn{lu}.
+
+ at node Explicit and Implicit Conversions
+ at subsection Explicit and Implicit Conversions
+
+The diagonal and permutation matrices are special objects in their own right.  A number
+of operations and built-in functions are defined for these matrices to use special,
+more efficient code than would be used for a full matrix in the same place.  Examples
+are given in further sections.
+
+To facilitate smooth mixing with full matrices, backward compatibility, and
+compatibility with @sc{matlab}, the diagonal and permutation matrices should allow
+any operation that works on full matrices, and will either treat it specially,
+or implicitly convert themselves to full matrices.
+
+Instances include matrix indexing, except for extracting a single element or
+a leading submatrix, indexed assignment, or applying most mapper functions,
+such as @dfn{exp}.
+
+An explicit conversion to a full matrix can be requested using the built-in
+function @dfn{full}.  It should also be noted that the diagonal and permutation
+matrix objects will cache the result of the conversion after it is first
+requested (explicitly or implicitly), so that subsequent conversions will
+be very cheap.
+
+ at node Matrix Algebra
+ at section Linear Algebra with Diagonal and Permutation Matrices
+
+As has been already said, diagonal and permutation matrices make it
+possible to use efficient algorithms while preserving natural linear
+algebra syntax.  This section describes in detail the operations that
+are treated specially when performed on these special matrix objects.
+
+ at menu
+* Expressions Involving Diagonal Matrices::
+* Expressions Involving Permutation Matrices::
+ at end menu
+
+ at node Expressions Involving Diagonal Matrices
+ at subsection Expressions Involving Diagonal Matrices
+
+Assume @var{D} is a diagonal matrix.  If @var{M} is a full matrix,
+then @code{D*M} will scale the rows of @var{M}.  That means,
+if @code{S = D*M}, then for each pair of indices
+i,j it holds 
+ at tex
+$$S_{ij} = D_{ii} M_{ij}$$
+ at end tex
+ at ifnottex
+ at example
+S(i,j) = D(i,i) * M(i,j).
+ at end example
+ at end ifnottex
+Similarly, @code{M*D} will do a column scaling.
+
+The matrix @var{D} may also be rectangular, m-by-n where @code{m != n}.
+If @code{m < n}, then the expression @code{D*M} is equivalent to
+ at example
+D(:,1:m) * M(1:m,:),
+ at end example
+i.e., trailing @code{n-m} rows of @var{M} are ignored.  If @code{m > n}, 
+then @code{D*M} is equivalent to 
+ at example
+[D(1:n,n) * M; zeros(m-n, columns (M))],
+ at end example
+i.e., null rows are appended to the result.
+The situation for right-multiplication @code{M*D} is analogous.
+
+The expressions @code{D \ M} and @code{M / D} perform inverse scaling.
+They are equivalent to solving a diagonal (or rectangular diagonal)
+in a least-squares minimum-norm sense.  In exact arithmetics, this is
+equivalent to multiplying by a pseudoinverse.  The pseudoinverse of
+a rectangular diagonal matrix is again a rectangular diagonal matrix
+with swapped dimensions, where each nonzero diagonal element is replaced
+by its reciprocal.
+The matrix division algorithms do, in fact, use division rather than 
+multiplication by reciprocals for better numerical accuracy; otherwise, they
+honor the above definition.  Note that a diagonal matrix is never truncated due
+to ill-conditioning; otherwise, it would not be much useful for scaling.  This
+is typically consistent with linear algebra needs.  A full matrix that only
+happens to be diagonal (an is thus not a special object) is of course treated
+normally.
+
+Multiplication and division by diagonal matrices works efficiently also when
+combined with sparse matrices, i.e., @code{D*S}, where @var{D} is a diagonal
+matrix and @var{S} is a sparse matrix scales the rows of the sparse matrix and
+returns a sparse matrix.  The expressions @code{S*D}, @code{D\S}, @code{S/D} work
+analogically.
+
+If @var{D1} and @var{D2} are both diagonal matrices, then the expressions
+ at example
+ at group
+D1 + D2
+D1 - D2 
+D1 * D2 
+D1 / D2 
+D1 \ D2
+ at end group
+ at end example
+again produce diagonal matrices, provided that normal
+dimension matching rules are obeyed.  The relations used are same as described above.
+
+Also, a diagonal matrix @var{D} can be multiplied or divided by a scalar, or raised
+to a scalar power if it is square, producing diagonal matrix result in all cases. 
+
+A diagonal matrix can also be transposed or conjugate-transposed, giving the expected
+result.  Extracting a leading submatrix of a diagonal matrix, i.e., @code{D(1:m,1:n)},
+will produce a diagonal matrix, other indexing expressions will implicitly convert to
+full matrix.
+
+Adding a diagonal matrix to a full matrix only operates on the diagonal elements.  Thus,
+ at example
+A = A + eps * eye (n)
+ at end example
+is an efficient method of augmenting the diagonal of a matrix.  Subtraction works
+analogically.
+
+When involved in expressions with other element-by-element operators, @code{.*},
+ at code{./}, @code{.\} or @code{.^}, an implicit conversion to full matrix will
+take place.  This is not always strictly necessary but chosen to facilitate
+better consistency with @sc{matlab}.
+
+ at node Expressions Involving Permutation Matrices
+ at subsection Expressions Involving Permutation Matrices
+
+If @var{P} is a permutation matrix and @var{M} a matrix, the expression
+ at code{P*M} will permute the rows of @var{M}.  Similarly, @code{M*P} will
+yield a column permutation. 
+Matrix division @code{P\M} and @code{M/P} can be used to do inverse permutation.
+
+The previously described syntax for creating permutation matrices can actually
+help an user to understand the connection between a permutation matrix and
+a permuting vector.  Namely, the following holds, where @code{I = eye (n)}
+is an identity matrix:
+ at example
+  I(p,:) * M = (I*M) (p,:) = M(p,:)
+ at end example
+Similarly,
+ at example
+  M * I(:,p) = (M*I) (:,p) = M(:,p)
+ at end example
+
+The expressions @code{I(p,:)} and @code{I(:,p)} are permutation matrices.
+
+A permutation matrix can be transposed (or conjugate-transposed, which is the
+same, because a permutation matrix is never complex), inverting the
+permutation, or equivalently, turning a row-permutation matrix into a
+column-permutation one.  For permutation matrices, transpose is equivalent to
+inversion, thus @code{P\M} is equivalent to @code{P'*M}.  Transpose of a
+permutation matrix (or inverse) is a constant-time operation, flipping only a
+flag internally, and thus the choice between the two above equivalent
+expressions for inverse permuting is completely up to the user's taste.
+
+Multiplication and division by permutation matrices works efficiently also when
+combined with sparse matrices, i.e., @code{P*S}, where @var{P} is a permutation
+matrix and @var{S} is a sparse matrix permutes the rows of the sparse matrix and
+returns a sparse matrix.  The expressions @code{S*P}, @code{P\S}, @code{S/P} work
+analogically.
+
+Two permutation matrices can be multiplied or divided (if their sizes match), performing
+a composition of permutations.  Also a permutation matrix can be indexed by a permutation
+vector (or two vectors), giving again a permutation matrix.
+Any other operations do not generally yield a permutation matrix and will thus
+trigger the implicit conversion.
+
+ at node Function Support
+ at section Functions That Are Aware of These Matrices
+
+This section lists the built-in functions that are aware of diagonal and
+permutation matrices on input, or can return them as output.  Passed to other
+functions, these matrices will in general trigger an implicit conversion.
+(Of course, user-defined dynamically linked functions may also work with
+diagonal or permutation matrices).
+
+ at menu
+* Diagonal Matrix Functions::
+* Permutation Matrix Functions::
+ at end menu
+
+ at node Diagonal Matrix Functions
+ at subsection Diagonal Matrix Functions
+
+ at dfn{inv} and @dfn{pinv} can be applied to a diagonal matrix, yielding again
+a diagonal matrix.  @dfn{det} will use an efficient straightforward calculation
+when given a diagonal matrix, as well as @dfn{cond}.
+The following mapper functions can be applied to a diagonal matrix
+without converting it to a full one:
+ at dfn{abs}, @dfn{real}, @dfn{imag}, @dfn{conj}, @dfn{sqrt}. 
+A diagonal matrix can also be returned from the @dfn{balance}
+and @dfn{svd} functions.
+The @dfn{sparse} function will convert a diagonal matrix efficiently to a
+sparse matrix.
+
+ at node Permutation Matrix Functions
+ at subsection Permutation Matrix Functions
+
+ at dfn{inv} and @dfn{pinv} will invert a permutation matrix, preserving its
+specialness.  @dfn{det} can be applied to a permutation matrix, efficiently
+calculating the sign of the permutation (which is equal to the determinant).
+
+A permutation matrix can also be returned from the built-in functions
+ at dfn{lu} and @dfn{qr}, if a pivoted factorization is requested.
+
+The @dfn{sparse} function will convert a permutation matrix efficiently to a
+sparse matrix.
+The @dfn{find} function will also work efficiently with a permutation matrix,
+making it possible to conveniently obtain the permutation indices.
+
+ at node Example Codes
+ at section Some Examples of Usage
+
+The following can be used to solve a linear system @code{A*x = b}
+using the pivoted LU factorization:
+ at example
+ at group
+  [L, U, P] = lu (A); ## now L*U = P*A
+  x = U \ L \ P*b;
+ at end group
+ at end example
+
+ at noindent
+This is how you normalize columns of a matrix @var{X} to unit norm:
+ at example
+ at group
+  s = norm (X, "columns");
+  X = diag (s) \ X;
+ at end group
+ at end example
+
+ at noindent
+The following expression is a way to efficiently calculate the sign of a
+permutation, given by a permutation vector @var{p}.  It will also work
+in earlier versions of Octave, but slowly.
+ at example
+  det (eye (length (p))(p, :))
+ at end example
+
+ at noindent
+Finally, here's how you solve a linear system @code{A*x = b} 
+with Tikhonov regularization (ridge regression) using SVD (a skeleton only):
+ at example
+ at group
+  m = rows (A); n = columns (A);
+  [U, S, V] = svd (A);
+  ## determine the regularization factor alpha
+  ## alpha = @dots{}
+  ## transform to orthogonal basis
+  b = U'*b;
+  ## Use the standard formula, replacing A with S.
+  ## S is diagonal, so the following will be very fast and accurate.
+  x = (S'*S + alpha^2 * eye (n)) \ (S' * b);
+  ## transform to solution basis
+  x = V*x;
+ at end group
+ at end example
+
+
+ at node Zeros Treatment
+ at section The Differences in Treatment of Zero Elements
+
+Making diagonal and permutation matrices special matrix objects in their own
+right and the consequent usage of smarter algorithms for certain operations
+implies, as a side effect, small differences in treating zeros.
+The contents of this section applies also to sparse matrices, discussed in
+the following chapter.
+
+The IEEE standard defines the result of the expressions @code{0*Inf} and 
+ at code{0*NaN} as @code{NaN}, as it has been generally agreed that this is the
+best compromise.
+Numerical software dealing with structured and sparse matrices (including
+Octave) however, almost always makes a distinction between a "numerical zero"
+and an "assumed zero". 
+A "numerical zero" is a zero value occurring in a place where any floating-point
+value could occur.  It is normally stored somewhere in memory as an explicit
+value. 
+An "assumed zero", on the contrary, is a zero matrix element implied by the
+matrix structure (diagonal, triangular) or a sparsity pattern; its value is
+usually not stored explicitly anywhere, but is implied by the underlying
+data structure.
+
+The primary distinction is that an assumed zero, when multiplied 
+by any number, or divided by any nonzero number,
+yields *always* a zero, even when, e.g., multiplied by @code{Inf}
+or divided by @code{NaN}.
+The reason for this behavior is that the numerical multiplication is not
+actually performed anywhere by the underlying algorithm; the result is
+just assumed to be zero.  Equivalently, one can say that the part of the
+computation involving assumed zeros is performed symbolically, not numerically.
+
+This behavior not only facilitates the most straightforward and efficient
+implementation of algorithms, but also preserves certain useful invariants,
+like:
+ at itemize
+ at item scalar * diagonal matrix is a diagonal matrix
+ at item sparse matrix / scalar preserves the sparsity pattern
+ at item permutation matrix * matrix is equivalent to permuting rows
+ at end itemize
+all of these natural mathematical truths would be invalidated by treating
+assumed zeros as numerical ones.
+
+Note that certain competing software does not strictly follow this principle
+and converts assumed zeros to numerical zeros in certain cases, while not doing
+so in other cases.  As of today, there are no intentions to mimic such behavior 
+in Octave.
+
+Examples of effects of assumed zeros vs. numerical zeros:
+ at example
+Inf * eye (3)
+ at result{}
+   Inf     0     0
+     0   Inf     0
+     0     0   Inf
+
+Inf * speye (3)
+ at result{}
+Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%])
+
+  (1, 1) -> Inf
+  (2, 2) -> Inf
+  (3, 3) -> Inf
+
+Inf * full (eye (3))
+ at result{}
+   Inf   NaN   NaN
+   NaN   Inf   NaN
+   NaN   NaN   Inf
+
+ at end example
+
+ at example
+ at group
+diag(1:3) * [NaN; 1; 1]
+ at result{}
+   NaN
+     2
+     3
+
+sparse(1:3,1:3,1:3) * [NaN; 1; 1]
+ at result{}
+   NaN
+     2
+     3
+[1,0,0;0,2,0;0,0,3] * [NaN; 1; 1]
+ at result{}
+   NaN
+   NaN
+   NaN
+ at end group
+ at end example
+
diff --git a/doc/interpreter/diffeq.texi b/doc/interpreter/diffeq.texi
new file mode 100644
index 0000000..ea5e9de
--- /dev/null
+++ b/doc/interpreter/diffeq.texi
@@ -0,0 +1,905 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Differential Equations
+ at chapter Differential Equations
+
+Octave has built-in functions for solving ordinary differential equations,
+and differential-algebraic equations.
+All solvers are based on reliable ODE routines written in Fortran.
+
+ at menu
+* Ordinary Differential Equations::  
+* Differential-Algebraic Equations::  
+ at end menu
+
+ at cindex Differential Equations
+ at cindex ODE
+ at cindex DAE
+
+ at node Ordinary Differential Equations
+ at section Ordinary Differential Equations
+
+The function @code{lsode} can be used to solve ODEs of the form
+ at tex
+$$
+ {dx\over dt} = f (x, t)
+$$
+ at end tex
+ at ifinfo
+
+ at example
+ at group
+dx
+-- = f (x, t)
+dt
+ at end group
+ at end example
+ at end ifinfo
+
+ at noindent
+using Hindmarsh's ODE solver @sc{Lsode}.
+
+
+
+ at c ./DLD-FUNCTIONS/lsode.cc
+ at anchor{doc-lsode}
+ at deftypefn {Loadable Function} {[@var{x}, @var{istate}, @var{msg}] =} lsode (@var{fcn}, @var{x_0}, @var{t}, @var{t_crit})
+Solve the set of differential equations
+ at tex
+$$ {dx \over dt} = f (x, t) $$
+with
+$$ x(t_0) = x_0 $$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+dx
+-- = f(x, t)
+dt
+ at end group
+ at end example
+
+with
+
+ at example
+x(t_0) = x_0
+ at end example
+
+ at end ifnottex
+The solution is returned in the matrix @var{x}, with each row
+corresponding to an element of the vector @var{t}.  The first element
+of @var{t} should be @math{t_0} and should correspond to the initial
+state of the system @var{x_0}, so that the first row of the output
+is @var{x_0}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of right
+hand sides for the set of equations.  The function must have the form
+
+ at example
+ at var{xdot} = f (@var{x}, @var{t})
+ at end example
+
+ at noindent
+in which @var{xdot} and @var{x} are vectors and @var{t} is a scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the Jacobian of @math{f}.  The Jacobian function
+must have the form
+
+ at example
+ at var{jac} = j (@var{x}, @var{t})
+ at end example
+
+in which @var{jac} is the matrix of partial derivatives
+ at tex
+$$ J = {\partial f_i \over \partial x_j} = \left[\matrix{
+{\partial f_1 \over \partial x_1}
+  & {\partial f_1 \over \partial x_2}
+  & \cdots
+  & {\partial f_1 \over \partial x_N} \cr
+{\partial f_2 \over \partial x_1}
+  & {\partial f_2 \over \partial x_2}
+  & \cdots
+  & {\partial f_2 \over \partial x_N} \cr
+ \vdots & \vdots & \ddots & \vdots \cr
+{\partial f_3 \over \partial x_1}
+  & {\partial f_3 \over \partial x_2}
+  & \cdots
+  & {\partial f_3 \over \partial x_N} \cr}\right]$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+             | df_1  df_1       df_1 |
+             | ----  ----  ...  ---- |
+             | dx_1  dx_2       dx_N |
+             |                       |
+             | df_2  df_2       df_2 |
+             | ----  ----  ...  ---- |
+      df_i   | dx_1  dx_2       dx_N |
+jac = ---- = |                       |
+      dx_j   |  .    .     .    .    |
+             |  .    .      .   .    |
+             |  .    .       .  .    |
+             |                       |
+             | df_N  df_N       df_N |
+             | ----  ----  ...  ---- |
+             | dx_1  dx_2       dx_N |
+ at end group
+ at end example
+
+ at end ifnottex
+
+The second and third arguments specify the initial state of the system,
+ at math{x_0}, and the initial value of the independent variable @math{t_0}.
+
+The fourth argument is optional, and may be used to specify a set of
+times that the ODE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be 2
+(consistent with the Fortran version of @sc{Lsode}).
+
+If the computation is not successful, @var{istate} will be something
+other than 2 and @var{msg} will contain additional information.
+
+You can use the function @code{lsode_options} to set optional
+parameters for @code{lsode}.
+ at seealso{@ref{doc-daspk,,daspk}, @ref{doc-dassl,,dassl}, @ref{doc-dasrt,,dasrt}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/lsode.cc
+ at anchor{doc-lsode_options}
+ at deftypefn {Loadable Function} {} lsode_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{lsode}.
+Given one argument, @code{lsode_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector.
+ at item "relative tolerance"
+Relative tolerance parameter.  Unlike the absolute tolerance, this
+parameter may only be a scalar.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i)) <= ...
+      rtol * abs (y(i)) + atol(i)
+ at end group
+ at end example
+ at item "integration method"
+A string specifying the method of integration to use to solve the ODE
+system.  Valid values are
+
+ at table @asis
+ at item "adams"
+ at itemx "non-stiff"
+No Jacobian used (even if it is available).
+ at item "bdf"
+ at item "stiff"
+Use stiff backward differentiation formula (BDF) method.  If a
+function to compute the Jacobian is not supplied, @code{lsode} will
+compute a finite difference approximation of the Jacobian matrix.
+ at end table
+ at item "initial step size"
+The step size to be attempted on the first step (default is determined
+automatically).
+ at item "maximum order"
+Restrict the maximum order of the solution method.  If using the Adams
+method, this option must be between 1 and 12.  Otherwise, it must be
+between 1 and 5, inclusive.
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified).
+ at item "minimum step size"
+The minimum absolute step size allowed (default is 0).
+ at item "step limit"
+Maximum number of steps allowed (default is 100000).
+ at end table
+ at end deftypefn
+
+
+Here is an example of solving a set of three differential equations using
+ at code{lsode}.  Given the function
+
+ at cindex oregonator
+
+ at example
+ at group
+function xdot = f (x, t)
+
+  xdot = zeros (3,1);
+
+  xdot(1) = 77.27 * (x(2) - x(1)*x(2) + x(1) \
+            - 8.375e-06*x(1)^2);
+  xdot(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
+  xdot(3) = 0.161*(x(1) - x(3));
+
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and the initial condition @code{x0 = [ 4; 1.1; 4 ]}, the set of
+equations can be integrated using the command
+
+ at example
+ at group
+t = linspace (0, 500, 1000);
+
+y = lsode ("f", x0, t);
+ at end group
+ at end example
+
+If you try this, you will see that the value of the result changes
+dramatically between @var{t} = 0 and 5, and again around @var{t} = 305.
+A more efficient set of output points might be
+
+ at example
+ at group
+t = [0, logspace (-1, log10(303), 150), \
+        logspace (log10(304), log10(500), 150)];
+ at end group
+ at end example
+
+See Alan C. Hindmarsh, @cite{ODEPACK, A Systematized Collection of ODE
+Solvers}, in Scientific Computing, R. S. Stepleman, editor, (1983) for
+more information about the inner workings of @code{lsode}.
+
+ at node Differential-Algebraic Equations
+ at section Differential-Algebraic Equations
+
+The function @code{daspk} can be used to solve DAEs of the form
+ at tex
+$$
+ 0 = f (\dot{x}, x, t), \qquad x(t=0) = x_0, \dot{x}(t=0) = \dot{x}_0
+$$
+ at end tex
+ at ifnottex
+
+ at example
+0 = f (x-dot, x, t),    x(t=0) = x_0, x-dot(t=0) = x-dot_0
+ at end example
+ at end ifnottex
+
+ at noindent
+where
+ at tex
+$\dot{x} = {dx \over dt}$
+ at end tex
+ at ifnottex
+ at math{x-dot}
+ at end ifnottex
+is the derivative of @math{x}.  The equation is solved using Petzold's
+DAE solver @sc{Daspk}.
+
+ at c ./DLD-FUNCTIONS/daspk.cc
+ at anchor{doc-daspk}
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} daspk (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
+Solve the set of differential-algebraic equations
+ at tex
+$$ 0 = f (x, \dot{x}, t) $$
+with
+$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
+ at end tex
+ at ifnottex
+
+ at example
+0 = f (x, xdot, t)
+ at end example
+
+with
+
+ at example
+x(t_0) = x_0, xdot(t_0) = xdot_0
+ at end example
+
+ at end ifnottex
+The solution is returned in the matrices @var{x} and @var{xdot},
+with each row in the result matrices corresponding to one of the
+elements in the vector @var{t}.  The first element of @var{t}
+should be @math{t_0} and correspond to the initial state of the
+system @var{x_0} and its derivative @var{xdot_0}, so that the first
+row of the output @var{x} is @var{x_0} and the first row
+of the output @var{xdot} is @var{xdot_0}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+ at example
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})
+ at end example
+
+ at noindent
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
+scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the modified Jacobian
+ at tex
+$$
+J = {\partial f \over \partial x}
+  + c {\partial f \over \partial \dot{x}}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+      df       df
+jac = -- + c ------
+      dx     d xdot
+ at end group
+ at end example
+ at end ifnottex
+
+The modified Jacobian function must have the form
+
+ at example
+ at group
+
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})
+
+ at end group
+ at end example
+
+The second and third arguments to @code{daspk} specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+The set of initial states and derivatives are not strictly required to
+be consistent.  If they are not consistent, you must use the
+ at code{daspk_options} function to provide additional information so
+that @code{daspk} can compute a consistent starting point.
+
+The fifth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be
+greater than zero (consistent with the Fortran version of @sc{Daspk}).
+
+If the computation is not successful, the value of @var{istate} will be
+less than zero and @var{msg} will contain additional information.
+
+You can use the function @code{daspk_options} to set optional
+parameters for @code{daspk}.
+ at seealso{@ref{doc-dassl,,dassl}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/daspk.cc
+ at anchor{doc-daspk_options}
+ at deftypefn {Loadable Function} {} daspk_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{daspk}.
+Given one argument, @code{daspk_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+ at item "relative tolerance"
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i))
+       <= rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+ at item "compute consistent initial condition"
+Denoting the differential variables in the state vector by @samp{Y_d}
+and the algebraic variables by @samp{Y_a}, @code{ddaspk} can solve
+one of two initialization problems:
+
+ at enumerate
+ at item Given Y_d, calculate Y_a and Y'_d
+ at item Given Y', calculate Y.
+ at end enumerate
+
+In either case, initial values for the given components are input, and
+initial guesses for the unknown components must also be provided as
+input.  Set this option to 1 to solve the first problem, or 2 to solve
+the second (the default is 0, so you must provide a set of
+initial conditions that are consistent).
+
+If this option is set to a nonzero value, you must also set the
+ at code{"algebraic variables"} option to declare which variables in the
+problem are algebraic.
+ at item "use initial condition heuristics"
+Set to a nonzero value to use the initial condition heuristics options
+described below.
+ at item "initial condition heuristics"
+A vector of the following parameters that can be used to control the
+initial condition calculation.
+
+ at table @code
+ at item MXNIT
+Maximum number of Newton iterations (default is 5).
+ at item MXNJ
+Maximum number of Jacobian evaluations (default is 6).
+ at item MXNH
+Maximum number of values of the artificial stepsize parameter to be
+tried if the @code{"compute consistent initial condition"} option has
+been set to 1 (default is 5).
+
+Note that the maximum total number of Newton iterations allowed is
+ at code{MXNIT*MXNJ*MXNH} if the @code{"compute consistent initial
+condition"} option has been set to 1 and @code{MXNIT*MXNJ} if it is
+set to 2.
+ at item LSOFF
+Set to a nonzero value to disable the linesearch algorithm (default is
+0).
+ at item STPTOL
+Minimum scaled step in linesearch algorithm (default is eps^(2/3)).
+ at item EPINIT
+Swing factor in the Newton iteration convergence test.  The test is
+applied to the residual vector, premultiplied by the approximate
+Jacobian.  For convergence, the weighted RMS norm of this vector
+(scaled by the error weights) must be less than @code{EPINIT*EPCON},
+where @code{EPCON} = 0.33 is the analogous test constant used in the
+time steps.  The default is @code{EPINIT} = 0.01.
+ at end table
+ at item "print initial condition info"
+Set this option to a nonzero value to display detailed information
+about the initial condition calculation (default is 0).
+ at item "exclude algebraic variables from error test"
+Set to a nonzero value to exclude algebraic variables from the error
+test.  You must also set the @code{"algebraic variables"} option to
+declare which variables in the problem are algebraic (default is 0).
+ at item "algebraic variables"
+A vector of the same length as the state vector.  A nonzero element
+indicates that the corresponding element of the state vector is an
+algebraic variable (i.e., its derivative does not appear explicitly
+in the equation set.
+
+This option is required by the
+ at code{compute consistent initial condition"} and
+ at code{"exclude algebraic variables from error test"} options.
+ at item "enforce inequality constraints"
+Set to one of the following values to enforce the inequality
+constraints specified by the @code{"inequality constraint types"}
+option (default is 0).
+
+ at enumerate
+ at item To have constraint checking only in the initial condition calculation.
+ at item To enforce constraint checking during the integration.
+ at item To enforce both options 1 and 2.
+ at end enumerate
+ at item "inequality constraint types"
+A vector of the same length as the state specifying the type of
+inequality constraint.  Each element of the vector corresponds to an
+element of the state and should be assigned one of the following
+codes 
+
+ at table @asis
+ at item -2
+Less than zero.
+ at item -1
+Less than or equal to zero.
+ at item 0
+Not constrained.
+ at item 1
+Greater than or equal to zero.
+ at item 2
+Greater than zero.
+ at end table
+
+This option only has an effect if the
+ at code{"enforce inequality constraints"} option is nonzero.
+ at item "initial step size"
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize (default is computed
+automatically).
+ at item "maximum order"
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive (default is 5).
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions (default is not specified).
+ at end table
+ at end deftypefn
+
+
+Octave also includes @sc{Dassl}, an earlier version of @var{Daspk},
+and @var{dasrt}, which can be used to solve DAEs with constraints
+(stopping conditions).
+
+ at c ./DLD-FUNCTIONS/dassl.cc
+ at anchor{doc-dassl}
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} dassl (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
+Solve the set of differential-algebraic equations
+ at iftex
+ at tex
+$$ 0 = f (x, \dot{x}, t) $$
+with
+$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+0 = f (x, xdot, t)
+ at end example
+
+ at noindent
+with
+
+ at example
+x(t_0) = x_0, xdot(t_0) = xdot_0
+ at end example
+
+ at end ifnottex
+The solution is returned in the matrices @var{x} and @var{xdot},
+with each row in the result matrices corresponding to one of the
+elements in the vector @var{t}.  The first element of @var{t}
+should be @math{t_0} and correspond to the initial state of the
+system @var{x_0} and its derivative @var{xdot_0}, so that the first
+row of the output @var{x} is @var{x_0} and the first row
+of the output @var{xdot} is @var{xdot_0}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+ at example
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})
+ at end example
+
+ at noindent
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
+scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the modified Jacobian
+
+ at iftex
+ at tex
+$$
+J = {\partial f \over \partial x}
+  + c {\partial f \over \partial \dot{x}}
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+ at example
+ at group
+      df       df
+jac = -- + c ------
+      dx     d xdot
+ at end group
+ at end example
+ at end ifnottex
+
+The modified Jacobian function must have the form
+
+ at example
+ at group
+
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})
+
+ at end group
+ at end example
+
+The second and third arguments to @code{dassl} specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+The set of initial states and derivatives are not strictly required to
+be consistent.  In practice, however, @sc{Dassl} is not very good at
+determining a consistent set for you, so it is best if you ensure that
+the initial values result in the function evaluating to zero.
+
+The fifth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be
+greater than zero (consistent with the Fortran version of @sc{Dassl}).
+
+If the computation is not successful, the value of @var{istate} will be
+less than zero and @var{msg} will contain additional information.
+
+You can use the function @code{dassl_options} to set optional
+parameters for @code{dassl}.
+ at seealso{@ref{doc-daspk,,daspk}, @ref{doc-dasrt,,dasrt}, @ref{doc-lsode,,lsode}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dassl.cc
+ at anchor{doc-dassl_options}
+ at deftypefn {Loadable Function} {} dassl_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{dassl}.
+Given one argument, @code{dassl_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+ at item "relative tolerance"
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i))
+       <= rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+ at item "compute consistent initial condition"
+If nonzero, @code{dassl} will attempt to compute a consistent set of initial
+conditions.  This is generally not reliable, so it is best to provide
+a consistent set and leave this option set to zero.
+ at item "enforce nonnegativity constraints"
+If you know that the solutions to your equations will always be
+nonnegative, it may help to set this parameter to a nonzero
+value.  However, it is probably best to try leaving this option set to
+zero first, and only setting it to a nonzero value if that doesn't
+work very well.
+ at item "initial step size"
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize.
+ at item "maximum order"
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive.
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified).
+ at item "step limit"
+Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code.
+ at end table
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dasrt.cc
+ at anchor{doc-dasrt}
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{t_out}, @var{istat}, @var{msg}] =} dasrt (@var{fcn} [, @var{g}], @var{x_0}, @var{xdot_0}, @var{t} [, @var{t_crit}])
+Solve the set of differential-algebraic equations
+ at tex
+$$ 0 = f (x, \dot{x}, t) $$
+with
+$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
+ at end tex
+ at ifnottex
+
+ at example
+0 = f (x, xdot, t)
+ at end example
+
+with
+
+ at example
+x(t_0) = x_0, xdot(t_0) = xdot_0
+ at end example
+
+ at end ifnottex
+with functional stopping criteria (root solving).
+
+The solution is returned in the matrices @var{x} and @var{xdot},
+with each row in the result matrices corresponding to one of the
+elements in the vector @var{t_out}.  The first element of @var{t}
+should be @math{t_0} and correspond to the initial state of the
+system @var{x_0} and its derivative @var{xdot_0}, so that the first
+row of the output @var{x} is @var{x_0} and the first row
+of the output @var{xdot} is @var{xdot_0}.
+
+The vector @var{t} provides an upper limit on the length of the
+integration.  If the stopping condition is met, the vector
+ at var{t_out} will be shorter than @var{t}, and the final element of
+ at var{t_out} will be the point at which the stopping condition was met,
+and may not correspond to any element of the vector @var{t}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+ at example
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})
+ at end example
+
+ at noindent
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
+scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the modified Jacobian
+
+ at tex
+$$
+J = {\partial f \over \partial x}
+  + c {\partial f \over \partial \dot{x}}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+      df       df
+jac = -- + c ------
+      dx     d xdot
+ at end group
+ at end example
+
+ at end ifnottex
+
+The modified Jacobian function must have the form
+
+ at example
+ at group
+
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})
+
+ at end group
+ at end example
+
+The optional second argument names a function that defines the
+constraint functions whose roots are desired during the integration.
+This function must have the form
+
+ at example
+ at var{g_out} = g (@var{x}, @var{t})
+ at end example
+
+and return a vector of the constraint function values.
+If the value of any of the constraint functions changes sign, @sc{Dasrt}
+will attempt to stop the integration at the point of the sign change.
+
+If the name of the constraint function is omitted, @code{dasrt} solves
+the same problem as @code{daspk} or @code{dassl}.
+
+Note that because of numerical errors in the constraint functions
+due to roundoff and integration error, @sc{Dasrt} may return false
+roots, or return the same root at two or more nearly equal values of
+ at var{T}.  If such false roots are suspected, the user should consider
+smaller error tolerances or higher precision in the evaluation of the
+constraint functions.
+
+If a root of some constraint function defines the end of the problem,
+the input to @sc{Dasrt} should nevertheless allow integration to a
+point slightly past that root, so that @sc{Dasrt} can locate the root
+by interpolation.
+
+The third and fourth arguments to @code{dasrt} specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+The set of initial states and derivatives are not strictly required to
+be consistent.  In practice, however, @sc{Dassl} is not very good at
+determining a consistent set for you, so it is best if you ensure that
+the initial values result in the function evaluating to zero.
+
+The sixth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be
+greater than zero (consistent with the Fortran version of @sc{Dassl}).
+
+If the computation is not successful, the value of @var{istate} will be
+less than zero and @var{msg} will contain additional information.
+
+You can use the function @code{dasrt_options} to set optional
+parameters for @code{dasrt}.
+ at seealso{@ref{doc-daspk,,daspk}, @ref{doc-dasrt,,dasrt}, @ref{doc-lsode,,lsode}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dasrt.cc
+ at anchor{doc-dasrt_options}
+ at deftypefn {Loadable Function} {} dasrt_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{dasrt}.
+Given one argument, @code{dasrt_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+ at item "relative tolerance"
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+ at example
+ at group
+  abs (local error in x(i)) <= ...
+      rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+ at item "initial step size"
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize.
+ at item "maximum order"
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive.
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions.
+ at item "step limit"
+Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code.
+ at end table
+ at end deftypefn
+
+
+See K. E. Brenan, et al., @cite{Numerical Solution of Initial-Value
+Problems in Differential-Algebraic Equations}, North-Holland (1989) for
+more information about the implementation of @sc{Dassl}.
diff --git a/doc/interpreter/diffeq.txi b/doc/interpreter/diffeq.txi
new file mode 100644
index 0000000..70a1e7b
--- /dev/null
+++ b/doc/interpreter/diffeq.txi
@@ -0,0 +1,156 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Differential Equations
+ at chapter Differential Equations
+
+Octave has built-in functions for solving ordinary differential equations,
+and differential-algebraic equations.
+All solvers are based on reliable ODE routines written in Fortran.
+
+ at menu
+* Ordinary Differential Equations::  
+* Differential-Algebraic Equations::  
+ at end menu
+
+ at cindex Differential Equations
+ at cindex ODE
+ at cindex DAE
+
+ at node Ordinary Differential Equations
+ at section Ordinary Differential Equations
+
+The function @code{lsode} can be used to solve ODEs of the form
+ at tex
+$$
+ {dx\over dt} = f (x, t)
+$$
+ at end tex
+ at ifinfo
+
+ at example
+ at group
+dx
+-- = f (x, t)
+dt
+ at end group
+ at end example
+ at end ifinfo
+
+ at noindent
+using Hindmarsh's ODE solver @sc{Lsode}.
+
+
+
+ at DOCSTRING(lsode)
+
+ at DOCSTRING(lsode_options)
+
+Here is an example of solving a set of three differential equations using
+ at code{lsode}.  Given the function
+
+ at cindex oregonator
+
+ at example
+ at group
+function xdot = f (x, t)
+
+  xdot = zeros (3,1);
+
+  xdot(1) = 77.27 * (x(2) - x(1)*x(2) + x(1) \
+            - 8.375e-06*x(1)^2);
+  xdot(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
+  xdot(3) = 0.161*(x(1) - x(3));
+
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and the initial condition @code{x0 = [ 4; 1.1; 4 ]}, the set of
+equations can be integrated using the command
+
+ at example
+ at group
+t = linspace (0, 500, 1000);
+
+y = lsode ("f", x0, t);
+ at end group
+ at end example
+
+If you try this, you will see that the value of the result changes
+dramatically between @var{t} = 0 and 5, and again around @var{t} = 305.
+A more efficient set of output points might be
+
+ at example
+ at group
+t = [0, logspace (-1, log10(303), 150), \
+        logspace (log10(304), log10(500), 150)];
+ at end group
+ at end example
+
+See Alan C. Hindmarsh, @cite{ODEPACK, A Systematized Collection of ODE
+Solvers}, in Scientific Computing, R. S. Stepleman, editor, (1983) for
+more information about the inner workings of @code{lsode}.
+
+ at node Differential-Algebraic Equations
+ at section Differential-Algebraic Equations
+
+The function @code{daspk} can be used to solve DAEs of the form
+ at tex
+$$
+ 0 = f (\dot{x}, x, t), \qquad x(t=0) = x_0, \dot{x}(t=0) = \dot{x}_0
+$$
+ at end tex
+ at ifnottex
+
+ at example
+0 = f (x-dot, x, t),    x(t=0) = x_0, x-dot(t=0) = x-dot_0
+ at end example
+ at end ifnottex
+
+ at noindent
+where
+ at tex
+$\dot{x} = {dx \over dt}$
+ at end tex
+ at ifnottex
+ at math{x-dot}
+ at end ifnottex
+is the derivative of @math{x}.  The equation is solved using Petzold's
+DAE solver @sc{Daspk}.
+
+ at DOCSTRING(daspk)
+
+ at DOCSTRING(daspk_options)
+
+Octave also includes @sc{Dassl}, an earlier version of @var{Daspk},
+and @var{dasrt}, which can be used to solve DAEs with constraints
+(stopping conditions).
+
+ at DOCSTRING(dassl)
+
+ at DOCSTRING(dassl_options)
+
+ at DOCSTRING(dasrt)
+
+ at DOCSTRING(dasrt_options)
+
+See K. E. Brenan, et al., @cite{Numerical Solution of Initial-Value
+Problems in Differential-Algebraic Equations}, North-Holland (1989) for
+more information about the implementation of @sc{Dassl}.
diff --git a/doc/interpreter/dir b/doc/interpreter/dir
new file mode 100644
index 0000000..3d96eba
--- /dev/null
+++ b/doc/interpreter/dir
@@ -0,0 +1,14 @@
+-*- Text -*-
+This is the file .../info/dir, which contains the topmost node of the
+Info hierarchy.	 The first time you invoke Info you start off
+looking at that node, which is (dir)Top.
+
+File: dir	Node: Top	This is the top of the INFO tree
+  This (the Directory node) gives a menu of major topics. 
+  Typing "d" returns here, "q" exits, "?" lists all INFO commands, "h" 
+  gives a primer for first-timers, "mItem<Return>" visits the menu
+  item named `Item', etc.
+
+* Menu: The list of major topics begins on the next line.
+
+* Octave: (octave).	Interactive language for numerical computations.
diff --git a/doc/interpreter/doc-cache b/doc/interpreter/doc-cache
new file mode 100644
index 0000000..924aac6
--- /dev/null
+++ b/doc/interpreter/doc-cache
@@ -0,0 +1,35719 @@
+# Created by Octave 3.2.4, Fri Jan 22 10:34:21 2010 CET <hajek at hajek>
+# name: cache
+# type: cell
+# rows: 3
+# columns: 1422
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+amd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1170
+ -- Loadable Function: P = amd (S)
+ -- Loadable Function: P = amd (S, OPTS)
+     Returns the approximate minimum degree permutation of a matrix.  This permutation such that the Cholesky factorization of `S (P, P)' tends to be sparser than the Cholesky factorization of S itself.  `amd' is typically faster than `symamd' but serves a similar purpose.
+
+     The optional parameter OPTS is a structure that controls the behavior of `amd'.  The fields of these structure are
+
+    opts.dense
+          Determines what `amd' considers to be a dense row or column of the input matrix.  Rows or columns with more than `max(16, (dense * sqrt (N)' entries, where N is the order of the matrix S, are ignored by `amd' during the calculation of the permutation The value of dense must be a positive scalar and its default value is 10.0
+
+    opts.aggressive
+          If this value is a non zero scalar, then `amd' performs aggressive absorption.  The default is not to perform aggressive absorption.
+
+     The author of the code itself is Timothy A. Davis (davis at cise.ufl.edu), University of Florida (see `http://www.cise.ufl.edu/research/sparse/amd').  See also: symamd, colamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Returns the approximate minimum degree permutation of a matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+balance
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1424
+ -- Loadable Function: AA = balance (A, OPT)
+ -- Loadable Function: [DD, AA] = balance (A, OPT)
+ -- Loadable Function: [D, P, AA] = balance (A, OPT)
+ -- Loadable Function: [CC, DD, AA, BB] = balance (A, B, OPT)
+     Compute `aa = dd \ a * dd' in which `aa' is a matrix whose row and column norms are roughly equal in magnitude, and `dd' = `p * d', in which `p' is a permutation matrix and `d' is a diagonal matrix of powers of two.  This allows the equilibration to be computed without roundoff.  Results of eigenvalue calculation are typically improved by balancing first.
+
+     If two output values are requested, `balance' returns the diagonal `d' and the permutation `p' separately as vectors.  In this case, `dd = eye(n)(:,p) * diag (d)', where `n' is the matrix size.
+
+     If four output values are requested, compute `aa = cc*a*dd' and `bb = cc*b*dd)', in which `aa' and `bb' have non-zero elements of approximately the same magnitude and `cc' and `dd' are permuted diagonal matrices as in `dd' for the algebraic eigenvalue problem.
+
+     The eigenvalue balancing option `opt' may be one of:
+
+    `"noperm"', `"S"'
+          Scale only; do not permute.
+
+    `"noscal"', `"P"'
+          Permute only; do not scale.
+
+     Algebraic eigenvalue balancing uses standard LAPACK routines.
+
+     Generalized eigenvalue problem balancing uses Ward's algorithm (SIAM Journal on Scientific and Statistical Computing, 1981).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 215
+Compute `aa = dd \ a * dd' in which `aa' is a matrix whose row and column norms are roughly equal in magnitude, and `dd' = `p * d', in which `p' is a permutation matrix and `d' is a diagonal matrix of powers of two.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+besselj
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2013
+ -- Loadable Function: [J, IERR] = besselj (ALPHA, X, OPT)
+ -- Loadable Function: [Y, IERR] = bessely (ALPHA, X, OPT)
+ -- Loadable Function: [I, IERR] = besseli (ALPHA, X, OPT)
+ -- Loadable Function: [K, IERR] = besselk (ALPHA, X, OPT)
+ -- Loadable Function: [H, IERR] = besselh (ALPHA, K, X, OPT)
+     Compute Bessel or Hankel functions of various kinds:
+
+    `besselj'
+          Bessel functions of the first kind.  If the argument OPT is supplied, the result is multiplied by `exp(-abs(imag(x)))'.
+
+    `bessely'
+          Bessel functions of the second kind.  If the argument OPT is supplied, the result is multiplied by `exp(-abs(imag(x)))'.
+
+    `besseli'
+          Modified Bessel functions of the first kind.  If the argument OPT is supplied, the result is multiplied by `exp(-abs(real(x)))'.
+
+    `besselk'
+          Modified Bessel functions of the second kind.  If the argument OPT is supplied, the result is multiplied by `exp(x)'.
+
+    `besselh'
+          Compute Hankel functions of the first (K = 1) or second (K = 2) kind.  If the argument OPT is supplied, the result is multiplied by `exp (-I*X)' for K = 1 or `exp (I*X)' for K = 2.
+
+     If ALPHA is a scalar, the result is the same size as X.  If X is a scalar, the result is the same size as ALPHA.  If ALPHA is a row vector and X is a column vector, the result is a matrix with `length (X)' rows and `length (ALPHA)' columns.  Otherwise, ALPHA and X must conform and the result will be the same size.
+
+     The value of ALPHA must be real.  The value of X may be complex.
+
+     If requested, IERR contains the following status information and is the same size as the result.
+
+       0. Normal return.
+
+       1. Input error, return `NaN'.
+
+       2. Overflow, return `Inf'.
+
+       3. Loss of significance by argument reduction results in less than half of machine accuracy.
+
+       4. Complete loss of significance by argument reduction, return `NaN'.
+
+       5. Error--no computation, algorithm termination condition not met, return `NaN'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compute Bessel or Hankel functions of various kinds: 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+bessely
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+ -- Loadable Function: [Y, IERR] = bessely (ALPHA, X, OPT)
+     See besselj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+See besselj.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+besseli
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+ -- Loadable Function: [I, IERR] = besseli (ALPHA, X, OPT)
+     See besselj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+See besselj.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+besselk
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+ -- Loadable Function: [K, IERR] = besselk (ALPHA, X, OPT)
+     See besselj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+See besselj.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+besselh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+ -- Loadable Function: [H, IERR] = besselh (ALPHA, K, X, OPT)
+     See besselj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+See besselj.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+airy
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1078
+ -- Loadable Function: [A, IERR] = airy (K, Z, OPT)
+     Compute Airy functions of the first and second kind, and their derivatives.
+
+           K   Function   Scale factor (if 'opt' is supplied)
+          ---  --------   ---------------------------------------
+           0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))
+           1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))
+           2   Bi (Z)     exp (-abs (real ((2/3) * Z *sqrt (Z))))
+           3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z *sqrt (Z))))
+
+     The function call `airy (Z)' is equivalent to `airy (0, Z)'.
+
+     The result is the same size as Z.
+
+     If requested, IERR contains the following status information and is the same size as the result.
+
+       0. Normal return.
+
+       1. Input error, return `NaN'.
+
+       2. Overflow, return `Inf'.
+
+       3. Loss of significance by argument reduction results in less than half  of machine accuracy.
+
+       4. Complete loss of significance by argument reduction, return `NaN'.
+
+       5. Error--no computation, algorithm termination condition not met, return `NaN'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Compute Airy functions of the first and second kind, and their derivatives.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+betainc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 487
+ -- Mapping Function:  betainc (X, A, B)
+     Return the incomplete Beta function,
+
+                                                x
+                                               /
+          betainc (x, a, b) = beta (a, b)^(-1) | t^(a-1) (1-t)^(b-1) dt.
+                                               /
+                                            t=0
+
+     If x has more than one component, both A and B must be scalars.  If X is a scalar, A and B must be of compatible dimensions.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return the incomplete Beta function, 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bitand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Built-in Function:  bitand (X, Y)
+     Return the bitwise AND of non-negative integers.  X, Y must be in the range [0,bitmax] See also: bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return the bitwise AND of non-negative integers.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+bitor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 198
+ -- Built-in Function:  bitor (X, Y)
+     Return the bitwise OR of non-negative integers.  X, Y must be in the range [0,bitmax] See also: bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Return the bitwise OR of non-negative integers.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bitxor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Built-in Function:  bitxor (X, Y)
+     Return the bitwise XOR of non-negative integers.  X, Y must be in the range [0,bitmax] See also: bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return the bitwise XOR of non-negative integers.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+bitshift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 565
+ -- Built-in Function:  bitshift (A, K)
+ -- Built-in Function:  bitshift (A, K, N)
+     Return a K bit shift of N-digit unsigned integers in A.  A positive K leads to a left shift.  A negative value to a right shift.  If N is omitted it defaults to log2(bitmax)+1.  N must be in the range [1,log2(bitmax)+1] usually [1,33]
+
+          bitshift (eye (3), 1)
+          =>
+          2 0 0
+          0 2 0
+          0 0 2
+
+          bitshift (10, [-2, -1, 0, 1, 2])
+          => 2   5  10  20  40
+     See also: bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return a K bit shift of N-digit unsigned integers in A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bitmax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 177
+ -- Built-in Function:  bitmax ()
+     Return the largest integer that can be represented as a floating point value.  On IEEE-754 compatible systems, `bitmax' is `2^53 - 1'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Return the largest integer that can be represented as a floating point value.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+intmax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 586
+ -- Built-in Function:  intmax (TYPE)
+     Return the largest integer that can be represented in an integer type.  The variable TYPE can be
+
+    `int8'
+          signed 8-bit integer.
+
+    `int16'
+          signed 16-bit integer.
+
+    `int32'
+          signed 32-bit integer.
+
+    `int64'
+          signed 64-bit integer.
+
+    `uint8'
+          unsigned 8-bit integer.
+
+    `uint16'
+          unsigned 16-bit integer.
+
+    `uint32'
+          unsigned 32-bit integer.
+
+    `uint64'
+          unsigned 64-bit integer.
+
+     The default for TYPE is `uint32'.  See also: intmin, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Return the largest integer that can be represented in an integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+intmin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 587
+ -- Built-in Function:  intmin (TYPE)
+     Return the smallest integer that can be represented in an integer type.  The variable TYPE can be
+
+    `int8'
+          signed 8-bit integer.
+
+    `int16'
+          signed 16-bit integer.
+
+    `int32'
+          signed 32-bit integer.
+
+    `int64'
+          signed 64-bit integer.
+
+    `uint8'
+          unsigned 8-bit integer.
+
+    `uint16'
+          unsigned 16-bit integer.
+
+    `uint32'
+          unsigned 32-bit integer.
+
+    `uint64'
+          unsigned 64-bit integer.
+
+     The default for TYPE is `uint32'.  See also: intmax, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return the smallest integer that can be represented in an integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bsxfun
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 459
+ -- Loadable Function:  bsxfun (F, A, B)
+     Applies a binary function F element-wise to two matrix arguments A and B.  The function F must be capable of accepting two column vector arguments of equal length, or one column vector argument and a scalar.
+
+     The dimensions of A and B must be equal or singleton.  The singleton dimensions of the matrices will be expanded to the same dimensionality as the other matrix.
+
+     See also: arrayfun, cellfun.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Applies a binary function F element-wise to two matrix arguments A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ccolamd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3636
+ -- Loadable Function: P = ccolamd (S)
+ -- Loadable Function: P = ccolamd (S, KNOBS)
+ -- Loadable Function: P = ccolamd (S, KNOBS, CMEMBER)
+ -- Loadable Function: [P, STATS] = ccolamd (...)
+     Constrained column approximate minimum degree permutation.  `P = ccolamd (S)' returns the column approximate minimum degree permutation vector for the sparse matrix S.  For a non-symmetric matrix S, `S (:, P)' tends to have sparser LU factors than S.  `chol (S (:, P)' * S (:, P))' also tends to be sparser than `chol (S' * S)'.  `P = ccolamd (S, 1)' optimizes the ordering for `lu (S (:, P))'.  The ordering is followed by a column elimination tree post-ordering.
+
+     KNOBS is an optional one- to five-element input vector, with a default value of `[0 10 10 1 0]' if not present or empty.  Entries not present are set to their defaults.
+
+    `KNOBS(1)'
+          if nonzero, the ordering is optimized for `lu (S (:, p))'.  It will be a poor ordering for `chol (S (:, P)' * S (:, P))'.  This is the most important knob for ccolamd.
+
+    `KNOB(2)'
+          if S is m-by-n, rows with more than `max (16, KNOBS (2) * sqrt (n))' entries are ignored.
+
+    `KNOB(3)'
+          columns with more than `max (16, KNOBS (3) * sqrt (min (M, N)))' entries are ignored and ordered last in the output permutation (subject to the cmember constraints).
+
+    `KNOB(4)'
+          if nonzero, aggressive absorption is performed.
+
+    `KNOB(5)'
+          if nonzero, statistics and knobs are printed.
+
+
+     CMEMBER is an optional vector of length n.  It defines the constraints on the column ordering.  If `CMEMBER (j) = C', then column J is in constraint set C (C must be in the range 1 to N).  In the output permutation P, all columns in set 1 appear first, followed by all columns in set 2, and so on.  `CMEMBER = ones(1,n)' if not present or empty.  `ccolamd (S, [], 1 : N)' returns `1 : N'
+
+     `P = ccolamd (S)' is about the same as `P = colamd (S)'.  KNOBS and its default values differ.  `colamd' always does aggressive absorption, and it finds an ordering suitable for both `lu (S (:, P))' and `chol (S (:, P)' * S (:, P))'; it cannot optimize its ordering for `lu (S (:, P))' to the extent that `ccolamd (S, 1)' can.
+
+     STATS is an optional 20-element output vector that provides data about the ordering and the validity of the input matrix S.  Ordering statistics are in `STATS (1 : 3)'.  `STATS (1)' and `STATS (2)' are the number of dense or empty rows and columns ignored by CCOLAMD and `STATS (3)' is the number of garbage collections performed on the internal data structure used by CCOLAMD (roughly of size `2.2 * nnz (S) + 4 * M + 7 * N' integers).
+
+     `STATS (4 : 7)' provide information if CCOLAMD was able to continue.  The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS (5)' is the rightmost column index that is unsorted or contains duplicate entries, or zero if no such column exists.  `STATS (6)' is the last seen duplicate or out-of-order row index in the column index given by `STATS (5)', or zero if no such row index exists.  `STATS (7)' is the number of duplicate or out-of-order row indices.  `STATS (8 : 20)' is always zero in the current version of CCOLAMD (reserved for future use).
+
+     The authors of the code itself are S. Larimore, T. Davis (Uni of Florida) and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270), and a grant from Sandia National Lab.  See `http://www.cise.ufl.edu/research/sparse' for ccolamd, csymamd, amd, colamd, symamd, and other related orderings.  See also: colamd, csymamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Constrained column approximate minimum degree permutation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+csymamd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2582
+ -- Loadable Function: P = csymamd (S)
+ -- Loadable Function: P = csymamd (S, KNOBS)
+ -- Loadable Function: P = csymamd (S, KNOBS, CMEMBER)
+ -- Loadable Function: [P, STATS] = csymamd (...)
+     For a symmetric positive definite matrix S, returns the permutation vector P such that `S(P,P)' tends to have a sparser Cholesky factor than S.  Sometimes `csymamd' works well for symmetric indefinite matrices too.  The matrix S is assumed to be symmetric; only the strictly lower triangular part is referenced.  S must be square.  The ordering is followed by an elimination tree post-ordering.
+
+     KNOBS is an optional one- to three-element input vector, with a default value of `[10 1 0]' if present or empty.  Entries not present are set to their defaults.
+
+    `KNOBS(1)'
+          If S is n-by-n, then rows and columns with more than `max(16,KNOBS(1)*sqrt(n))' entries are ignored, and ordered last in the output permutation (subject to the cmember constraints).
+
+    `KNOBS(2)'
+          If nonzero, aggressive absorption is performed.
+
+    `KNOBS(3)'
+          If nonzero, statistics and knobs are printed.
+
+
+     CMEMBER is an optional vector of length n. It defines the constraints on the ordering.  If `CMEMBER(j) = S', then row/column j is in constraint set C (C must be in the range 1 to n).  In the output permutation P, rows/columns in set 1 appear first, followed by all rows/columns in set 2, and so on.  `CMEMBER = ones(1,n)' if not present or empty.  `csymamd(S,[],1:n)' returns `1:n'.
+
+     `P = csymamd(S)' is about the same as `P = symamd(S)'.  KNOBS and its default values differ.
+
+     `STATS (4:7)' provide information if CCOLAMD was able to continue.  The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS (5)' is the rightmost column index that is unsorted or contains duplicate entries, or zero if no such column exists.  `STATS (6)' is the last seen duplicate or out-of-order row index in the column index given by `STATS (5)', or zero if no such row index exists.  `STATS (7)' is the number of duplicate or out-of-order row indices.  `STATS (8:20)' is always zero in the current version of CCOLAMD (reserved for future use).
+
+     The authors of the code itself are S. Larimore, T. Davis (Uni of Florida) and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270), and a grant from Sandia National Lab.  See `http://www.cise.ufl.edu/research/sparse' for ccolamd, csymamd, amd, colamd, symamd, and other related orderings.  See also: symamd, ccolamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+For a symmetric positive definite matrix S, returns the permutation vector P such that `S(P,P)' tends to have a sparser Cholesky factor than S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cellfun
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2862
+ -- Loadable Function:  cellfun (NAME, C)
+ -- Loadable Function:  cellfun ("size", C, K)
+ -- Loadable Function:  cellfun ("isclass", C, CLASS)
+ -- Loadable Function:  cellfun (FUNC, C)
+ -- Loadable Function:  cellfun (FUNC, C, D)
+ -- Loadable Function: [A, B] = cellfun (...)
+ -- Loadable Function:  cellfun (..., 'ErrorHandler', ERRFUNC)
+ -- Loadable Function:  cellfun (..., 'UniformOutput', VAL)
+     Evaluate the function named NAME on the elements of the cell array C.  Elements in C are passed on to the named function individually.  The function NAME can be one of the functions
+
+    `isempty'
+          Return 1 for empty elements.
+
+    `islogical'
+          Return 1 for logical elements.
+
+    `isreal'
+          Return 1 for real elements.
+
+    `length'
+          Return a vector of the lengths of cell elements.
+
+    `ndims'
+          Return the number of dimensions of each element.
+
+    `prodofsize'
+          Return the product of dimensions of each element.
+
+    `size'
+          Return the size along the K-th dimension.
+
+    `isclass'
+          Return 1 for elements of CLASS.
+
+     Additionally, `cellfun' accepts an arbitrary function FUNC in the form of an inline function, function handle, or the name of a function (in a character string).  In the case of a character string argument, the function must accept a single argument named X, and it must return a string value.  The function can take one or more arguments, with the inputs args given by C, D, etc.  Equally the function can return one or more output arguments.  For example
+
+          cellfun (@atan2, {1, 0}, {0, 1})
+          =>ans = [1.57080   0.00000]
+
+     Note that the default output argument is an array of the same size as the input arguments.
+
+     If the parameter 'UniformOutput' is set to true (the default), then the function must return a single element which will be concatenated into the return value.  If 'UniformOutput' is false, the outputs are concatenated in a cell array.  For example
+
+          cellfun ("tolower(x)", {"Foo", "Bar", "FooBar"},
+                   "UniformOutput",false)
+          => ans = {"foo", "bar", "foobar"}
+
+     Given the parameter 'ErrorHandler', then ERRFUNC defines a function to call in case FUNC generates an error.  The form of the function is
+
+          function [...] = errfunc (S, ...)
+
+     where there is an additional input argument to ERRFUNC relative to FUNC, given by S.  This is a structure with the elements 'identifier', 'message' and 'index', giving respectively the error identifier, the error message, and the index into the input arguments of the element that caused the error.  For example
+
+          function y = foo (s, x), y = NaN; endfunction
+          cellfun (@factorial, {-1,2},'ErrorHandler', at foo)
+          => ans = [NaN 2]
+
+     See also: isempty, islogical, isreal, length, ndims, numel, size.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Evaluate the function named NAME on the elements of the cell array C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+num2cell
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 269
+ -- Loadable Function: C = num2cell (M)
+ -- Loadable Function: C = num2cell (M, DIM)
+     Convert the matrix M to a cell array.  If DIM is defined, the value C is of dimension 1 in this dimension and the elements of M are placed in slices in C.  See also: mat2cell.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Convert the matrix M to a cell array.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+mat2cell
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 956
+ -- Loadable Function: B = mat2cell (A, M, N)
+ -- Loadable Function: B = mat2cell (A, D1, D2, ...)
+ -- Loadable Function: B = mat2cell (A, R)
+     Convert the matrix A to a cell array.  If A is 2-D, then it is required that `sum (M) == size (A, 1)' and `sum (N) == size (A, 2)'.  Similarly, if A is a multi-dimensional and the number of dimensional arguments is equal to the dimensions of A, then it is required that `sum (DI) == size (A, i)'.
+
+     Given a single dimensional argument R, the other dimensional arguments are assumed to equal `size (A,I)'.
+
+     An example of the use of mat2cell is
+
+          mat2cell (reshape(1:16,4,4),[3,1],[3,1])
+          => {
+            [1,1] =
+
+               1   5   9
+               2   6  10
+               3   7  11
+
+            [2,1] =
+
+               4   8  12
+
+            [1,2] =
+
+              13
+              14
+              15
+
+            [2,2] = 16
+          }
+     See also: num2cell, cell2mat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Convert the matrix A to a cell array.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cellslices
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 516
+ -- Loadable Function: SL = cellslices (X, LB, UB)
+     Given a vector X, this function produces a cell array of slices from the vector determined by the index vectors LB, UB, for lower and upper bounds, respectively.  In other words, it is equivalent to the following code:
+
+          n = length (lb);
+          sl = cell (1, n);
+          for i = 1:length (lb)
+            sl{i} = x(lb(i):ub(i));
+          endfor
+
+     If X is a matrix or array, indexing is done along the last dimension.  See also: mat2cell.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 161
+Given a vector X, this function produces a cell array of slices from the vector determined by the index vectors LB, UB, for lower and upper bounds, respectively.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+chol
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1362
+ -- Loadable Function: R = chol (A)
+ -- Loadable Function: [R, P] = chol (A)
+ -- Loadable Function: [R, P, Q] = chol (S)
+ -- Loadable Function: [R, P, Q] = chol (S, 'vector')
+ -- Loadable Function: [L, ...] = chol (..., 'lower')
+     Compute the Cholesky factor, R, of the symmetric positive definite matrix A, where
+
+          R' * R = A.
+
+     Called with one output argument `chol' fails if A or S is not positive definite.  With two or more output arguments P flags whether the matrix was positive definite and `chol' does not fail.  A zero value indicated that the matrix was positive definite and the R gives the factorization, and P will have a positive value otherwise.
+
+     If called with 3 outputs then a sparsity preserving row/column permutation is applied to A prior to the factorization.  That is R is the factorization of `A(Q,Q)' such that
+
+          R' * R = Q' * A * Q.
+
+     The sparsity preserving permutation is generally returned as a matrix.  However, given the flag 'vector', Q will be returned as a vector such that
+
+          R' * R = a (Q, Q).
+
+     Called with either a sparse or full matrix and using the 'lower' flag, `chol' returns the lower triangular factorization such that
+
+          L * L' = A.
+
+     In general the lower triangular factorization is significantly faster for sparse matrices.  See also: cholinv, chol2inv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Compute the Cholesky factor, R, of the symmetric positive definite matrix A, where 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cholinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 170
+ -- Loadable Function:  cholinv (A)
+     Use the Cholesky factorization to compute the inverse of the symmetric positive definite matrix A.  See also: chol, chol2inv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Use the Cholesky factorization to compute the inverse of the symmetric positive definite matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+chol2inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 320
+ -- Loadable Function:  chol2inv (U)
+     Invert a symmetric, positive definite square matrix from its Cholesky decomposition, U.  Note that U should be an upper-triangular matrix with positive diagonal elements.  `chol2inv (U)' provides `inv (U'*U)' but it is much faster than using `inv'.  See also: chol, cholinv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 87
+Invert a symmetric, positive definite square matrix from its Cholesky decomposition, U.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cholupdate
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 592
+ -- Loadable Function: [R1, INFO] = cholupdate (R, U, OP)
+     Update or downdate a Cholesky factorization.  Given an upper triangular matrix R and a column vector U, attempt to determine another upper triangular matrix R1 such that
+        * R1'*R1 = R'*R + U*U' if OP is "+"
+
+        * R1'*R1 = R'*R - U*U' if OP is "-"
+
+     If OP is "-", INFO is set to
+        * 0 if the downdate was successful,
+
+        * 1 if R'*R - U*U' is not positive definite,
+
+        * 2 if R is singular.
+
+     If INFO is not present, an error message is printed in cases 1 and 2.  See also: chol, qrupdate.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Update or downdate a Cholesky factorization.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cholinsert
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 591
+ -- Loadable Function: [R1, INFO] = cholinsert (R, J, U)
+     Given a Cholesky factorization of a real symmetric or complex hermitian positive definite matrix A = R'*R, R upper triangular, return the Cholesky factorization of A1, where A1(p,p) = A, A1(:,j) = A1(j,:)' = u and p = [1:j-1,j+1:n+1].  u(j) should be positive.  On return, INFO is set to
+        * 0 if the insertion was successful,
+
+        * 1 if A1 is not positive definite,
+
+        * 2 if R is singular.
+
+     If INFO is not present, an error message is printed in cases 1 and 2.  See also: chol, cholupdate, choldelete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 234
+Given a Cholesky factorization of a real symmetric or complex hermitian positive definite matrix A = R'*R, R upper triangular, return the Cholesky factorization of A1, where A1(p,p) = A, A1(:,j) = A1(j,:)' = u and p = [1:j-1,j+1:n+1].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+choldelete
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 294
+ -- Loadable Function: R1 = choldelete (R, J)
+     Given a Cholesky factorization of a real symmetric or complex hermitian positive definite matrix A = R'*R, R upper triangular, return the Cholesky factorization of A(p,p), where p = [1:j-1,j+1:n+1].  See also: chol, cholupdate, cholinsert.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 198
+Given a Cholesky factorization of a real symmetric or complex hermitian positive definite matrix A = R'*R, R upper triangular, return the Cholesky factorization of A(p,p), where p = [1:j-1,j+1:n+1].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+cholshift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 409
+ -- Loadable Function: R1 = cholshift (R, I, J)
+     Given a Cholesky factorization of a real symmetric or complex hermitian positive definite matrix A = R'*R, R upper triangular, return the Cholesky factorization of A(p,p), where p is the permutation
+     `p = [1:i-1, shift(i:j, 1), j+1:n]' if I < J
+     or
+     `p = [1:j-1, shift(j:i,-1), i+1:n]' if J < I.
+     See also: chol, cholinsert, choldelete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 295
+Given a Cholesky factorization of a real symmetric or complex hermitian positive definite matrix A = R'*R, R upper triangular, return the Cholesky factorization of A(p,p), where p is the permutation  `p = [1:i-1, shift(i:j, 1), j+1:n]' if I < J  or  `p = [1:j-1, shift(j:i,-1), i+1:n]' if J < I.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+colamd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3341
+ -- Loadable Function: P = colamd (S)
+ -- Loadable Function: P = colamd (S, KNOBS)
+ -- Loadable Function: [P, STATS] = colamd (S)
+ -- Loadable Function: [P, STATS] = colamd (S, KNOBS)
+     Column approximate minimum degree permutation.  `P = colamd (S)' returns the column approximate minimum degree permutation vector for the sparse matrix S.  For a non-symmetric matrix S, `S (:,P)' tends to have sparser LU factors than S.  The Cholesky factorization of `S (:,P)' * S (:,P)' also tends to be sparser than that of `S' * S'.
+
+     KNOBS is an optional one- to three-element input vector.  If S is m-by-n, then rows with more than `max(16,KNOBS(1)*sqrt(n))' entries are ignored.  Columns with more than `max(16,knobs(2)*sqrt(min(m,n)))' entries are removed prior to ordering, and ordered last in the output permutation P.  Only completely dense rows or columns are removed if `KNOBS (1)' and `KNOBS (2)' are < 0, respectively.  If `KNOBS (3)' is nonzero, STATS and KNOBS are printed.  The default is `KNOBS = [10 10 0]'.  Note that KNOBS differs from earlier versions of colamd
+
+     STATS is an optional 20-element output vector that provides data about the ordering and the validity of the input matrix S.  Ordering statistics are in `STATS (1:3)'.  `STATS (1)' and `STATS (2)' are the number of dense or empty rows and columns ignored by COLAMD and `STATS (3)' is the number of garbage collections performed on the internal data structure used by COLAMD (roughly of size `2.2 * nnz(S) + 4 * M + 7 * N' integers).
+
+     Octave built-in functions are intended to generate valid sparse matrices, with no duplicate entries, with ascending row indices of the nonzeros in each column, with a non-negative number of entries in each column (!)  and so on.  If a matrix is invalid, then COLAMD may or may not be able to continue.  If there are duplicate entries (a row index appears two or more times in the same column) or if the row indices in a column are out of order, then COLAMD can correct these errors by ignoring the duplicate entries and sorting each column of its internal copy of the matrix S (the input matrix S is not repaired, however).  If a matrix is invalid in other ways then COLAMD cannot continue, an error message is printed, and no output arguments (P or STATS) are returned.  COLAMD is thus a simple way to check a sparse matrix to see if it's valid.
+
+     `STATS (4:7)' provide information if COLAMD was able to continue.  The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS (5)' is the rightmost column index that is unsorted or contains duplicate entries, or zero if no such column exists.  `STATS (6)' is the last seen duplicate or out-of-order row index in the column index given by `STATS (5)', or zero if no such row index exists.  `STATS (7)' is the number of duplicate or out-of-order row indices.  `STATS (8:20)' is always zero in the current version of COLAMD (reserved for future use).
+
+     The ordering is followed by a column elimination tree post-ordering.
+
+     The authors of the code itself are Stefan I. Larimore and Timothy A.  Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was developed in collaboration with John Gilbert, Xerox PARC, and Esmond Ng, Oak Ridge National Laboratory.  (see `http://www.cise.ufl.edu/research/sparse/colamd') See also: colperm, symamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Column approximate minimum degree permutation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+symamd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3207
+ -- Loadable Function: P = symamd (S)
+ -- Loadable Function: P = symamd (S, KNOBS)
+ -- Loadable Function: [P, STATS] = symamd (S)
+ -- Loadable Function: [P, STATS] = symamd (S, KNOBS)
+     For a symmetric positive definite matrix S, returns the permutation vector p such that `S (P, P)' tends to have a sparser Cholesky factor than S.  Sometimes SYMAMD works well for symmetric indefinite matrices too.  The matrix S is assumed to be symmetric; only the strictly lower triangular part is referenced.  S must be square.
+
+     KNOBS is an optional one- to two-element input vector.  If S is n-by-n, then rows and columns with more than `max(16,KNOBS(1)*sqrt(n))' entries are removed prior to ordering, and ordered last in the output permutation P.  No rows/columns are removed if `KNOBS(1) < 0'.  If `KNOBS (2)' is nonzero, `stats' and KNOBS are printed.  The default is `KNOBS = [10 0]'.  Note that KNOBS differs from earlier versions of symamd.
+
+     STATS is an optional 20-element output vector that provides data about the ordering and the validity of the input matrix S.  Ordering statistics are in `STATS (1:3)'.  `STATS (1) = STATS (2)' is the number of dense or empty rows and columns ignored by SYMAMD and `STATS (3)' is the number of garbage collections performed on the internal data structure used by SYMAMD (roughly of size `8.4 * nnz (tril (S, -1)) + 9 * N' integers).
+
+     Octave built-in functions are intended to generate valid sparse matrices, with no duplicate entries, with ascending row indices of the nonzeros in each column, with a non-negative number of entries in each column (!)  and so on.  If a matrix is invalid, then SYMAMD may or may not be able to continue.  If there are duplicate entries (a row index appears two or more times in the same column) or if the row indices in a column are out of order, then SYMAMD can correct these errors by ignoring the duplicate entries and sorting each column of its internal copy of the matrix S (the input matrix S is not repaired, however).  If a matrix is invalid in other ways then SYMAMD cannot continue, an error message is printed, and no output arguments (P or STATS) are returned.  SYMAMD is thus a simple way to check a sparse matrix to see if it's valid.
+
+     `STATS (4:7)' provide information if SYMAMD was able to continue.  The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS (5)' is the rightmost column index that is unsorted or contains duplicate entries, or zero if no such column exists.  `STATS (6)' is the last seen duplicate or out-of-order row index in the column index given by `STATS (5)', or zero if no such row index exists.  `STATS (7)' is the number of duplicate or out-of-order row indices.  `STATS (8:20)' is always zero in the current version of SYMAMD (reserved for future use).
+
+     The ordering is followed by a column elimination tree post-ordering.
+
+     The authors of the code itself are Stefan I. Larimore and Timothy A.  Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was developed in collaboration with John Gilbert, Xerox PARC, and Esmond Ng, Oak Ridge National Laboratory.  (see `http://www.cise.ufl.edu/research/sparse/colamd') See also: colperm, colamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 145
+For a symmetric positive definite matrix S, returns the permutation vector p such that `S (P, P)' tends to have a sparser Cholesky factor than S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+etree
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 550
+ -- Loadable Function: P = etree (S)
+ -- Loadable Function: P = etree (S, TYP)
+ -- Loadable Function: [P, Q] = etree (S, TYP)
+     Returns the elimination tree for the matrix S.  By default S is assumed to be symmetric and the symmetric elimination tree is returned.  The argument TYP controls whether a symmetric or column elimination tree is returned.  Valid values of TYP are 'sym' or 'col', for symmetric or column elimination tree respectively
+
+     Called with a second argument, "etree" also returns the postorder permutations on the tree.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Returns the elimination tree for the matrix S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+colloc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 292
+ -- Loadable Function: [R, AMAT, BMAT, Q] = colloc (N, "left", "right")
+     Compute derivative and integral weight matrices for orthogonal collocation using the subroutines given in J. Villadsen and M. L. Michelsen, `Solution of Differential Equation Models by Polynomial Approximation'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Compute derivative and integral weight matrices for orthogonal collocation using the subroutines given in J.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+conv2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 576
+ -- Loadable Function: y = conv2 (A, B, SHAPE)
+ -- Loadable Function: y = conv2 (V1, V2, M, SHAPE)
+     Returns 2D convolution of A and B where the size of C is given by
+
+    SHAPE= 'full'
+          returns full 2-D convolution
+
+    SHAPE= 'same'
+          same size as a. 'central' part of convolution
+
+    SHAPE= 'valid'
+          only parts which do not include zero-padded edges
+
+     By default SHAPE is 'full'.  When the third argument is a matrix returns the convolution of the matrix M by the vector V1 in the column direction and by vector V2 in the row direction
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Returns 2D convolution of A and B where the size of C is given by 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+convhulln
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 640
+ -- Loadable Function: H = convhulln (P)
+ -- Loadable Function: H = convhulln (P, OPT)
+ -- Loadable Function: [H, V] = convhulln (...)
+     Return an index vector to the points of the enclosing convex hull.  The input matrix of size [n, dim] contains n points of dimension dim.
+
+     If a second optional argument is given, it must be a string or cell array of strings containing options for the underlying qhull command.  (See the Qhull documentation for the available options.)  The default options are "s Qci Tcv".  If the second output V is requested the volume of the convex hull is calculated.
+
+     See also: convhull, delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return an index vector to the points of the enclosing convex hull.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+daspk_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5703
+ -- Loadable Function:  daspk_options (OPT, VAL)
+     When called with two arguments, this function allows you set options parameters for the function `daspk'.  Given one argument, `daspk_options' returns the value of the corresponding option.  If no arguments are supplied, the names of all the available options and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector, and the relative tolerance must also be a vector of the same length.
+
+    `"relative tolerance"'
+          Relative tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector, and the absolute tolerance must also be a vector of the same length.
+
+          The local error test applied at each integration step is
+
+                 abs (local error in x(i))
+                      <= rtol(i) * abs (Y(i)) + atol(i)
+
+    `"compute consistent initial condition"'
+          Denoting the differential variables in the state vector by `Y_d' and the algebraic variables by `Y_a', `ddaspk' can solve one of two initialization problems:
+
+            1. Given Y_d, calculate Y_a and Y'_d
+
+            2. Given Y', calculate Y.
+
+          In either case, initial values for the given components are input, and initial guesses for the unknown components must also be provided as input.  Set this option to 1 to solve the first problem, or 2 to solve the second (the default is 0, so you must provide a set of initial conditions that are consistent).
+
+          If this option is set to a nonzero value, you must also set the `"algebraic variables"' option to declare which variables in the problem are algebraic.
+
+    `"use initial condition heuristics"'
+          Set to a nonzero value to use the initial condition heuristics options described below.
+
+    `"initial condition heuristics"'
+          A vector of the following parameters that can be used to control the initial condition calculation.
+
+         `MXNIT'
+               Maximum number of Newton iterations (default is 5).
+
+         `MXNJ'
+               Maximum number of Jacobian evaluations (default is 6).
+
+         `MXNH'
+               Maximum number of values of the artificial stepsize parameter to be tried if the `"compute consistent initial condition"' option has been set to 1 (default is 5).
+
+               Note that the maximum total number of Newton iterations allowed is `MXNIT*MXNJ*MXNH' if the `"compute consistent initial condition"' option has been set to 1 and `MXNIT*MXNJ' if it is set to 2.
+
+         `LSOFF'
+               Set to a nonzero value to disable the linesearch algorithm (default is 0).
+
+         `STPTOL'
+               Minimum scaled step in linesearch algorithm (default is eps^(2/3)).
+
+         `EPINIT'
+               Swing factor in the Newton iteration convergence test.  The test is applied to the residual vector, premultiplied by the approximate Jacobian.  For convergence, the weighted RMS norm of this vector (scaled by the error weights) must be less than `EPINIT*EPCON', where `EPCON' = 0.33 is the analogous test constant used in the time steps.  The default is `EPINIT' = 0.01.
+
+    `"print initial condition info"'
+          Set this option to a nonzero value to display detailed information about the initial condition calculation (default is 0).
+
+    `"exclude algebraic variables from error test"'
+          Set to a nonzero value to exclude algebraic variables from the error test.  You must also set the `"algebraic variables"' option to declare which variables in the problem are algebraic (default is 0).
+
+    `"algebraic variables"'
+          A vector of the same length as the state vector.  A nonzero element indicates that the corresponding element of the state vector is an algebraic variable (i.e., its derivative does not appear explicitly in the equation set.
+
+          This option is required by the `compute consistent initial condition"' and `"exclude algebraic variables from error test"' options.
+
+    `"enforce inequality constraints"'
+          Set to one of the following values to enforce the inequality constraints specified by the `"inequality constraint types"' option (default is 0).
+
+            1. To have constraint checking only in the initial condition calculation.
+
+            2. To enforce constraint checking during the integration.
+
+            3. To enforce both options 1 and 2.
+
+    `"inequality constraint types"'
+          A vector of the same length as the state specifying the type of inequality constraint.  Each element of the vector corresponds to an element of the state and should be assigned one of the following codes
+
+         -2
+               Less than zero.
+
+         -1
+               Less than or equal to zero.
+
+         0
+               Not constrained.
+
+         1
+               Greater than or equal to zero.
+
+         2
+               Greater than zero.
+
+          This option only has an effect if the `"enforce inequality constraints"' option is nonzero.
+
+    `"initial step size"'
+          Differential-algebraic problems may occasionally suffer from severe scaling difficulties on the first step.  If you know a great deal about the scaling of your problem, you can help to alleviate this problem by specifying an initial stepsize (default is computed automatically).
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  This option must be between 1 and 5, inclusive (default is 5).
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very large regions (default is not specified).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+When called with two arguments, this function allows you set options parameters for the function `daspk'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+daspk
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2443
+ -- Loadable Function: [X, XDOT, ISTATE, MSG] = daspk (FCN, X_0, XDOT_0, T, T_CRIT)
+     Solve the set of differential-algebraic equations
+
+          0 = f (x, xdot, t)
+
+     with
+
+          x(t_0) = x_0, xdot(t_0) = xdot_0
+
+     The solution is returned in the matrices X and XDOT, with each row in the result matrices corresponding to one of the elements in the vector T.  The first element of T should be t_0 and correspond to the initial state of the system X_0 and its derivative XDOT_0, so that the first row of the output X is X_0 and the first row of the output XDOT is XDOT_0.
+
+     The first argument, FCN, is a string, inline, or function handle that names the function f to call to compute the vector of residuals for the set of equations.  It must have the form
+
+          RES = f (X, XDOT, T)
+
+     in which X, XDOT, and RES are vectors, and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array of strings, inline functions, or function handles, the first element names the function f described above, and the second element names a function to compute the modified Jacobian
+
+                df       df
+          jac = -- + c ------
+                dx     d xdot
+
+     The modified Jacobian function must have the form
+
+
+          JAC = j (X, XDOT, T, C)
+
+     The second and third arguments to `daspk' specify the initial condition of the states and their derivatives, and the fourth argument specifies a vector of output times at which the solution is desired, including the time corresponding to the initial condition.
+
+     The set of initial states and derivatives are not strictly required to be consistent.  If they are not consistent, you must use the `daspk_options' function to provide additional information so that `daspk' can compute a consistent starting point.
+
+     The fifth argument is optional, and may be used to specify a set of times that the DAE solver should not integrate past.  It is useful for avoiding difficulties with singularities and points where there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be greater than zero (consistent with the Fortran version of DASPK).
+
+     If the computation is not successful, the value of ISTATE will be less than zero and MSG will contain additional information.
+
+     You can use the function `daspk_options' to set optional parameters for `daspk'.  See also: dassl.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Solve the set of differential-algebraic equations 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+dasrt_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1641
+ -- Loadable Function:  dasrt_options (OPT, VAL)
+     When called with two arguments, this function allows you set options parameters for the function `dasrt'.  Given one argument, `dasrt_options' returns the value of the corresponding option.  If no arguments are supplied, the names of all the available options and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector, and the relative tolerance must also be a vector of the same length.
+
+    `"relative tolerance"'
+          Relative tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector, and the absolute tolerance must also be a vector of the same length.
+
+          The local error test applied at each integration step is
+                 abs (local error in x(i)) <= ...
+                     rtol(i) * abs (Y(i)) + atol(i)
+
+    `"initial step size"'
+          Differential-algebraic problems may occasionally suffer from severe scaling difficulties on the first step.  If you know a great deal about the scaling of your problem, you can help to alleviate this problem by specifying an initial stepsize.
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  This option must be between 1 and 5, inclusive.
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very large regions.
+
+    `"step limit"'
+          Maximum number of integration steps to attempt on a single call to the underlying Fortran code.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+When called with two arguments, this function allows you set options parameters for the function `dasrt'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+dasrt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3942
+ -- Loadable Function: [X, XDOT, T_OUT, ISTAT, MSG] = dasrt (FCN [, G], X_0, XDOT_0, T [, T_CRIT])
+     Solve the set of differential-algebraic equations
+
+          0 = f (x, xdot, t)
+
+     with
+
+          x(t_0) = x_0, xdot(t_0) = xdot_0
+
+     with functional stopping criteria (root solving).
+
+     The solution is returned in the matrices X and XDOT, with each row in the result matrices corresponding to one of the elements in the vector T_OUT.  The first element of T should be t_0 and correspond to the initial state of the system X_0 and its derivative XDOT_0, so that the first row of the output X is X_0 and the first row of the output XDOT is XDOT_0.
+
+     The vector T provides an upper limit on the length of the integration.  If the stopping condition is met, the vector T_OUT will be shorter than T, and the final element of T_OUT will be the point at which the stopping condition was met, and may not correspond to any element of the vector T.
+
+     The first argument, FCN, is a string, inline, or function handle that names the function f to call to compute the vector of residuals for the set of equations.  It must have the form
+
+          RES = f (X, XDOT, T)
+
+     in which X, XDOT, and RES are vectors, and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array of strings, inline functions, or function handles, the first element names the function f described above, and the second element names a function to compute the modified Jacobian
+
+                df       df
+          jac = -- + c ------
+                dx     d xdot
+
+     The modified Jacobian function must have the form
+
+
+          JAC = j (X, XDOT, T, C)
+
+     The optional second argument names a function that defines the constraint functions whose roots are desired during the integration.  This function must have the form
+
+          G_OUT = g (X, T)
+
+     and return a vector of the constraint function values.  If the value of any of the constraint functions changes sign, DASRT will attempt to stop the integration at the point of the sign change.
+
+     If the name of the constraint function is omitted, `dasrt' solves the same problem as `daspk' or `dassl'.
+
+     Note that because of numerical errors in the constraint functions due to roundoff and integration error, DASRT may return false roots, or return the same root at two or more nearly equal values of T.  If such false roots are suspected, the user should consider smaller error tolerances or higher precision in the evaluation of the constraint functions.
+
+     If a root of some constraint function defines the end of the problem, the input to DASRT should nevertheless allow integration to a point slightly past that root, so that DASRT can locate the root by interpolation.
+
+     The third and fourth arguments to `dasrt' specify the initial condition of the states and their derivatives, and the fourth argument specifies a vector of output times at which the solution is desired, including the time corresponding to the initial condition.
+
+     The set of initial states and derivatives are not strictly required to be consistent.  In practice, however, DASSL is not very good at determining a consistent set for you, so it is best if you ensure that the initial values result in the function evaluating to zero.
+
+     The sixth argument is optional, and may be used to specify a set of times that the DAE solver should not integrate past.  It is useful for avoiding difficulties with singularities and points where there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be greater than zero (consistent with the Fortran version of DASSL).
+
+     If the computation is not successful, the value of ISTATE will be less than zero and MSG will contain additional information.
+
+     You can use the function `dasrt_options' to set optional parameters for `dasrt'.  See also: daspk, dasrt, lsode.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Solve the set of differential-algebraic equations 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+dassl_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2248
+ -- Loadable Function:  dassl_options (OPT, VAL)
+     When called with two arguments, this function allows you set options parameters for the function `dassl'.  Given one argument, `dassl_options' returns the value of the corresponding option.  If no arguments are supplied, the names of all the available options and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector, and the relative tolerance must also be a vector of the same length.
+
+    `"relative tolerance"'
+          Relative tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector, and the absolute tolerance must also be a vector of the same length.
+
+          The local error test applied at each integration step is
+
+                 abs (local error in x(i))
+                      <= rtol(i) * abs (Y(i)) + atol(i)
+
+    `"compute consistent initial condition"'
+          If nonzero, `dassl' will attempt to compute a consistent set of initial conditions.  This is generally not reliable, so it is best to provide a consistent set and leave this option set to zero.
+
+    `"enforce nonnegativity constraints"'
+          If you know that the solutions to your equations will always be nonnegative, it may help to set this parameter to a nonzero value.  However, it is probably best to try leaving this option set to zero first, and only setting it to a nonzero value if that doesn't work very well.
+
+    `"initial step size"'
+          Differential-algebraic problems may occasionally suffer from severe scaling difficulties on the first step.  If you know a great deal about the scaling of your problem, you can help to alleviate this problem by specifying an initial stepsize.
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  This option must be between 1 and 5, inclusive.
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very large regions  (default is not specified).
+
+    `"step limit"'
+          Maximum number of integration steps to attempt on a single call to the underlying Fortran code.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+When called with two arguments, this function allows you set options parameters for the function `dassl'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+dassl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2477
+ -- Loadable Function: [X, XDOT, ISTATE, MSG] = dassl (FCN, X_0, XDOT_0, T, T_CRIT)
+     Solve the set of differential-algebraic equations
+
+          0 = f (x, xdot, t)
+
+     with
+
+          x(t_0) = x_0, xdot(t_0) = xdot_0
+
+     The solution is returned in the matrices X and XDOT, with each row in the result matrices corresponding to one of the elements in the vector T.  The first element of T should be t_0 and correspond to the initial state of the system X_0 and its derivative XDOT_0, so that the first row of the output X is X_0 and the first row of the output XDOT is XDOT_0.
+
+     The first argument, FCN, is a string, inline, or function handle that names the function f to call to compute the vector of residuals for the set of equations.  It must have the form
+
+          RES = f (X, XDOT, T)
+
+     in which X, XDOT, and RES are vectors, and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array of strings, inline functions, or function handles, the first element names the function f described above, and the second element names a function to compute the modified Jacobian
+
+                df       df
+          jac = -- + c ------
+                dx     d xdot
+
+     The modified Jacobian function must have the form
+
+
+          JAC = j (X, XDOT, T, C)
+
+     The second and third arguments to `dassl' specify the initial condition of the states and their derivatives, and the fourth argument specifies a vector of output times at which the solution is desired, including the time corresponding to the initial condition.
+
+     The set of initial states and derivatives are not strictly required to be consistent.  In practice, however, DASSL is not very good at determining a consistent set for you, so it is best if you ensure that the initial values result in the function evaluating to zero.
+
+     The fifth argument is optional, and may be used to specify a set of times that the DAE solver should not integrate past.  It is useful for avoiding difficulties with singularities and points where there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be greater than zero (consistent with the Fortran version of DASSL).
+
+     If the computation is not successful, the value of ISTATE will be less than zero and MSG will contain additional information.
+
+     You can use the function `dassl_options' to set optional parameters for `dassl'.  See also: daspk, dasrt, lsode.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Solve the set of differential-algebraic equations 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+all
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 229
+ -- Built-in Function:  all (X, DIM)
+     The function `all' behaves like the function `any', except that it returns true only if all the elements of a vector, or all the elements along dimension DIM of a matrix, are nonzero.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 183
+The function `all' behaves like the function `any', except that it returns true only if all the elements of a vector, or all the elements along dimension DIM of a matrix, are nonzero.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+any
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 515
+ -- Built-in Function:  any (X, DIM)
+     For a vector argument, return 1 if any element of the vector is nonzero.
+
+     For a matrix argument, return a row vector of ones and zeros with each element indicating whether any of the elements of the corresponding column of the matrix are nonzero.  For example,
+
+          any (eye (2, 4))
+               => [ 1, 1, 0, 0 ]
+
+     If the optional argument DIM is supplied, work along dimension DIM.  For example,
+
+          any (eye (2, 4), 2)
+               => [ 1; 1 ]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+For a vector argument, return 1 if any element of the vector is nonzero.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+atan2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 170
+ -- Mapping Function:  atan2 (Y, X)
+     Compute atan (Y / X) for corresponding elements of Y and X.  Signal an error if Y and X do not match in size and orientation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Compute atan (Y / X) for corresponding elements of Y and X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+hypot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 248
+ -- Built-in Function:  hypot (X, Y)
+     Compute the element-by-element square root of the sum of the squares of X and Y.  This is equivalent to `sqrt (X.^2 + Y.^2)', but calculated in a manner that avoids overflows for large values of X or Y.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+Compute the element-by-element square root of the sum of the squares of X and Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+log2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 325
+ -- Mapping Function:  log2 (X)
+ -- Mapping Function: [F, E] = log2 (X)
+     Compute the base-2 logarithm of each element of X.
+
+     If called with two output arguments, split X into binary mantissa and exponent so that `1/2 <= abs(f) < 1' and E is an integer.  If `x = 0', `f = e = 0'.  See also: pow2, log, log10, exp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Compute the base-2 logarithm of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fmod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 248
+ -- Mapping Function:  fmod (X, Y)
+     Compute the floating point remainder of dividing X by Y using the C library function `fmod'.  The result has the same sign as X.  If Y is zero, the result is implementation-dependent.  See also: mod, rem.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Compute the floating point remainder of dividing X by Y using the C library function `fmod'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cumprod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 386
+ -- Built-in Function:  cumprod (X)
+ -- Built-in Function:  cumprod (X, DIM)
+     Cumulative product of elements along dimension DIM.  If DIM is omitted, it defaults to 1 (column-wise cumulative products).
+
+     As a special case, if X is a vector and DIM is omitted, return the cumulative product of the elements as a vector with the same orientation as X.  See also: prod, cumsum.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Cumulative product of elements along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+cumsum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 573
+ -- Built-in Function:  cumsum (X)
+ -- Built-in Function:  cumsum (X, DIM)
+ -- Built-in Function:  cumsum (..., 'native')
+     Cumulative sum of elements along dimension DIM.  If DIM is omitted, it defaults to 1 (column-wise cumulative sums).
+
+     As a special case, if X is a vector and DIM is omitted, return the cumulative sum of the elements as a vector with the same orientation as X.
+
+     The "native" argument implies the summation is performed in native type.   See `sum' for a complete description and example of the use of "native".  See also: sum, cumprod.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Cumulative sum of elements along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+diag
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 604
+ -- Built-in Function:  diag (V, K)
+     Return a diagonal matrix with 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 ([1, 2, 3], 1)
+               =>  0  1  0  0
+                   0  0  2  0
+                   0  0  0  3
+                   0  0  0  0
+
+     Given a matrix argument, instead of a vector, `diag' extracts the K-th diagonal of the matrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Return a diagonal matrix with vector V on diagonal K.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+prod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 304
+ -- Built-in Function:  prod (X)
+ -- Built-in Function:  prod (X, DIM)
+     Product of elements along dimension DIM.  If DIM is omitted, it defaults to 1 (column-wise products).
+
+     As a special case, if X is a vector and DIM is omitted, return the product of the elements.  See also: cumprod, sum.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Product of elements along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+horzcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Built-in Function:  horzcat (ARRAY1, ARRAY2, ..., ARRAYN)
+     Return the horizontal concatenation of N-d array objects, ARRAY1, ARRAY2, ..., ARRAYN along dimension 2.  See also: cat, vertcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Return the horizontal concatenation of N-d array objects, ARRAY1, ARRAY2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+vertcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 198
+ -- Built-in Function:  vertcat (ARRAY1, ARRAY2, ..., ARRAYN)
+     Return the vertical concatenation of N-d array objects, ARRAY1, ARRAY2, ..., ARRAYN along dimension 1.  See also: cat, horzcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Return the vertical concatenation of N-d array objects, ARRAY1, ARRAY2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 803
+ -- Built-in Function:  cat (DIM, ARRAY1, ARRAY2, ..., ARRAYN)
+     Return the concatenation of N-d array objects, ARRAY1, ARRAY2, ..., ARRAYN along dimension DIM.
+
+          A = ones (2, 2);
+          B = zeros (2, 2);
+          cat (2, A, B)
+          => ans =
+
+               1 1 0 0
+               1 1 0 0
+
+     Alternatively, we can concatenate A and B along the second dimension the following way:
+
+          [A, B].
+
+     DIM can be larger than the dimensions of the N-d array objects and the result will thus have DIM dimensions as the following example shows:
+          cat (4, ones(2, 2), zeros (2, 2))
+          => ans =
+
+             ans(:,:,1,1) =
+
+               1 1
+               1 1
+
+             ans(:,:,1,2) =
+               0 0
+               0 0
+     See also: horzcat, vertcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return the concatenation of N-d array objects, ARRAY1, ARRAY2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+permute
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 255
+ -- Built-in Function:  permute (A, PERM)
+     Return the generalized transpose for an N-d array object A.  The permutation vector PERM must contain the elements `1:ndims(a)' (in any order, but each element must appear just once).  See also: ipermute.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Return the generalized transpose for an N-d array object A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ipermute
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 208
+ -- Built-in Function:  ipermute (A, IPERM)
+     The inverse of the `permute' function.  The expression
+
+          ipermute (permute (a, perm), perm)
+     returns the original array A.  See also: permute.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+The inverse of the `permute' function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+length
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 228
+ -- Built-in Function:  length (A)
+     Return the `length' of the object A.  For matrix objects, the length is the number of rows or columns, whichever is greater (this odd definition is used for compatibility with MATLAB).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Return the `length' of the object A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ndims
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 204
+ -- Built-in Function:  ndims (A)
+     Returns the number of dimensions of array A.  For any array, the result will always be larger than or equal to 2.  Trailing singleton dimensions are not counted.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Returns the number of dimensions of array A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+numel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+ -- Built-in Function:  numel (A)
+     Returns the number of elements in the object A.  See also: size.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Returns the number of elements in the object A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+size
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 730
+ -- Built-in Function:  size (A, N)
+     Return the number rows and columns of A.
+
+     With one input argument and one output argument, the result is returned in a row vector.  If there are multiple output arguments, the number of rows is assigned to the first, and the number of columns to the second, etc.  For example,
+
+          size ([1, 2; 3, 4; 5, 6])
+               => [ 3, 2 ]
+
+          [nr, nc] = size ([1, 2; 3, 4; 5, 6])
+               => nr = 3
+               => nc = 2
+
+     If given a second argument, `size' will return the size of the corresponding dimension.  For example
+
+          size ([1, 2; 3, 4; 5, 6], 2)
+               => 2
+
+     returns the number of columns in the given matrix.  See also: numel.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Return the number rows and columns of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+size_equal
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 234
+ -- Built-in Function:  size_equal (A, B, ...)
+     Return true if the dimensions of all arguments agree.  Trailing singleton dimensions are ignored.  Called with a single argument, size_equal returns true.  See also: size, numel.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Return true if the dimensions of all arguments agree.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+nnz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Built-in Function: SCALAR = nnz (A)
+     Returns the number of non zero elements in A.  See also: sparse.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Returns the number of non zero elements in A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+nzmax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 401
+ -- Built-in Function: SCALAR = nzmax (SM)
+     Return the amount of storage allocated to the sparse matrix SM.  Note that Octave tends to crop unused memory at the first opportunity for sparse objects.  There are some cases of user created sparse objects where the value returned by "nzmax" will not be the same as "nnz", but in general they will give the same result.  See also: sparse, spalloc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return the amount of storage allocated to the sparse matrix SM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+rows
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 144
+ -- Built-in Function:  rows (A)
+     Return the number of rows of A.  See also: size, numel, columns, length, isscalar, isvector, ismatrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Return the number of rows of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+columns
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+ -- Built-in Function:  columns (A)
+     Return the number of columns of A.  See also: size, numel, rows, length, isscalar, isvector, ismatrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Return the number of columns of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+sum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 622
+ -- Built-in Function:  sum (X)
+ -- Built-in Function:  sum (X, DIM)
+ -- Built-in Function:  sum (..., 'native')
+     Sum of elements along dimension DIM.  If DIM is omitted, it defaults to 1 (column-wise sum).
+
+     As a special case, if X is a vector and DIM is omitted, return the sum of the elements.
+
+     If the optional argument 'native' is given, then the sum is performed in the same type as the original argument, rather than in the default double type.  For example
+
+          sum ([true, true])
+            => 2
+          sum ([true, true], 'native')
+            => true
+     See also: cumsum, sumsq, prod.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Sum of elements along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+sumsq
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 481
+ -- Built-in Function:  sumsq (X)
+ -- Built-in Function:  sumsq (X, DIM)
+     Sum of squares of elements along dimension DIM.  If DIM is omitted, it defaults to 1 (column-wise sum of squares).
+
+     As a special case, if X is a vector and DIM is omitted, return the sum of squares of the elements.
+
+     This function is conceptually equivalent to computing
+          sum (x .* conj (x), dim)
+     but it uses less memory and avoids calling `conj' if X is real.  See also: sum.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Sum of squares of elements along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+islogical
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Built-in Function:  islogical (X)
+     Return true if X is a logical object.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return true if X is a logical object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+isinteger
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 271
+ -- Built-in Function:  isinteger (X)
+     Return true if X is an integer object (int8, uint8, int16, etc.).  Note that `isinteger (14)' is false because numeric constants in Octave are double precision floating point values.  See also: isreal, isnumeric, class, isa.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return true if X is an integer object (int8, uint8, int16, etc.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+iscomplex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+ -- Built-in Function:  iscomplex (X)
+     Return true if X is a complex-valued numeric object.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return true if X is a complex-valued numeric object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isfloat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+ -- Built-in Function:  isfloat (X)
+     Return true if X is a floating-point numeric object.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return true if X is a floating-point numeric object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+complex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 458
+ -- Built-in Function:  complex (X)
+ -- Built-in Function:  complex (RE, IM)
+     Return a complex result from real arguments.  With 1 real argument X, return the complex result `X + 0i'.  With 2 real arguments, return the complex result `RE + IM'.  `complex' can often be more convenient than expressions such as `a + i*b'.  For example:
+
+          complex ([1, 2], [3, 4])
+          =>
+             1 + 3i   2 + 4i
+     See also: real, imag, iscomplex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Return a complex result from real arguments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+isreal
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+ -- Built-in Function:  isreal (X)
+     Return true if X is a real-valued numeric object.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Return true if X is a real-valued numeric object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isempty
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 172
+ -- Built-in Function:  isempty (A)
+     Return 1 if A is an empty matrix (either the number of rows, or the number of columns, or both are zero).  Otherwise, return 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+Return 1 if A is an empty matrix (either the number of rows, or the number of columns, or both are zero).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+isnumeric
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 87
+ -- Built-in Function:  isnumeric (X)
+     Return nonzero if X is a numeric object.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Return nonzero if X is a numeric object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+islist
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+ -- Built-in Function:  islist (X)
+     Return nonzero if X is a list.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Return nonzero if X is a list.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ismatrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+ -- Built-in Function:  ismatrix (A)
+     Return 1 if A is a matrix.  Otherwise, return 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Return 1 if A is a matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+ones
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 573
+ -- Built-in Function:  ones (X)
+ -- Built-in Function:  ones (N, M)
+ -- Built-in Function:  ones (N, M, K, ...)
+ -- Built-in Function:  ones (..., CLASS)
+     Return a matrix or N-dimensional array whose elements are all 1.  The arguments are handled the same as the arguments for `eye'.
+
+     If you need to create a matrix whose values are all the same, you should use an expression like
+
+          val_matrix = val * ones (n, m)
+
+     The optional argument CLASS, allows `ones' to return an array of the specified type, for example
+
+          val = ones (n,m, "uint8")
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return a matrix or N-dimensional array whose elements are all 1.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+zeros
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 435
+ -- Built-in Function:  zeros (X)
+ -- Built-in Function:  zeros (N, M)
+ -- Built-in Function:  zeros (N, M, K, ...)
+ -- Built-in Function:  zeros (..., CLASS)
+     Return a matrix or N-dimensional array whose elements are all 0.  The arguments are handled the same as the arguments for `eye'.
+
+     The optional argument CLASS, allows `zeros' to return an array of the specified type, for example
+
+          val = zeros (n,m, "uint8")
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return a matrix or N-dimensional array whose elements are all 0.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+Inf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1031
+ -- Built-in Function:  Inf
+ -- Built-in Function:  Inf (N)
+ -- Built-in Function:  Inf (N, M)
+ -- Built-in Function:  Inf (N, M, K, ...)
+ -- Built-in Function:  Inf (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are all equal to the IEEE representation for positive infinity.
+
+     Infinity is produced when results are too large to be represented using the the IEEE floating point format for numbers.  Two common examples which produce infinity are division by zero and overflow.
+          [1/0 e^800]
+          =>
+          Inf   Inf
+
+     When called with no arguments, return a scalar with the value `Inf'.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".  See also: isinf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+Return a scalar, matrix or N-dimensional array whose elements are all equal to the IEEE representation for positive infinity.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+NaN
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1208
+ -- Built-in Function:  NaN
+ -- Built-in Function:  NaN (N)
+ -- Built-in Function:  NaN (N, M)
+ -- Built-in Function:  NaN (N, M, K, ...)
+ -- Built-in Function:  NaN (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are all equal to the IEEE symbol NaN (Not a Number).  NaN is the result of operations which do not produce a well defined numerical result.  Common operations which produce a NaN are arithmetic with infinity (Inf - Inf), zero divided by zero (0/0), and any operation involving another NaN value (5 + NaN).
+
+     Note that NaN always compares not equal to NaN (NaN != NaN).  This behavior is specified by the IEEE standard for floating point arithmetic.  To find NaN values, use the `isnan' function.
+
+     When called with no arguments, return a scalar with the value `NaN'.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".  See also: isnan.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+Return a scalar, matrix, or N-dimensional array whose elements are all equal to the IEEE symbol NaN (Not a Number).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1
+e
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 781
+ -- Built-in Function:  e
+ -- Built-in Function:  e (N)
+ -- Built-in Function:  e (N, M)
+ -- Built-in Function:  e (N, M, K, ...)
+ -- Built-in Function:  e (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are all equal to the base of natural logarithms.  The constant `e' satisfies the equation `log' (e) = 1.
+
+     When called with no arguments, return a scalar with the value e.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Return a scalar, matrix, or N-dimensional array whose elements are all equal to the base of natural logarithms.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+eps
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1033
+ -- Built-in Function:  eps
+ -- Built-in Function:  eps (X)
+ -- Built-in Function:  eps (N, M)
+ -- Built-in Function:  eps (N, M, K, ...)
+ -- Built-in Function:  eps (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are all eps, the machine precision.  More precisely, `eps' is the relative spacing between any two adjacent numbers in the machine's floating point system.  This number is obviously system dependent.  On machines that support IEEE floating point arithmetic, `eps' is approximately 2.2204e-16 for double precision and 1.1921e-07 for single precision.
+
+     When called with no arguments, return a scalar with the value `eps(1.0)'.  Given a single argument X, return the distance between X and the next largest value.  When called with more than one argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Return a scalar, matrix or N-dimensional array whose elements are all eps, the machine precision.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+pi
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 815
+ -- Built-in Function:  pi
+ -- Built-in Function:  pi (N)
+ -- Built-in Function:  pi (N, M)
+ -- Built-in Function:  pi (N, M, K, ...)
+ -- Built-in Function:  pi (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are all equal to the ratio of the circumference of a circle to its diameter.  Internally, `pi' is computed as `4.0 * atan (1.0)'.
+
+     When called with no arguments, return a scalar with the value of pi.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 139
+Return a scalar, matrix, or N-dimensional array whose elements are all equal to the ratio of the circumference of a circle to its diameter.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+realmax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1027
+ -- Built-in Function:  realmax
+ -- Built-in Function:  realmax (N)
+ -- Built-in Function:  realmax (N, M)
+ -- Built-in Function:  realmax (N, M, K, ...)
+ -- Built-in Function:  realmax (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are all equal to the largest floating point number that is representable.  The actual value is system dependent.  On machines that support IEEE floating point arithmetic, `realmax' is approximately 1.7977e+308 for double precision and 3.4028e+38 for single precision.
+
+     When called with no arguments, return a scalar with the value `realmax("double")'.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".  See also: realmin, intmax, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+Return a scalar, matrix or N-dimensional array whose elements are all equal to the largest floating point number that is representable.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+realmin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1031
+ -- Built-in Function:  realmin
+ -- Built-in Function:  realmin (N)
+ -- Built-in Function:  realmin (N, M)
+ -- Built-in Function:  realmin (N, M, K, ...)
+ -- Built-in Function:  realmin (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are all equal to the smallest normalized floating point number that is representable.  The actual value is system dependent.  On machines that support IEEE floating point arithmetic, `realmin' is approximately 2.2251e-308 for double precision and 1.1755e-38 for single precision.
+
+     When called with no arguments, return a scalar with the value `realmin("double")'.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".  See also: realmax, intmin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+Return a scalar, matrix or N-dimensional array whose elements are all equal to the smallest normalized floating point number that is representable.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1
+I
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 883
+ -- Built-in Function:  I
+ -- Built-in Function:  I (N)
+ -- Built-in Function:  I (N, M)
+ -- Built-in Function:  I (N, M, K, ...)
+ -- Built-in Function:  I (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are all equal to the pure imaginary unit, defined as `sqrt (-1)'.   I, and its equivalents i, J, and j, are functions so any of the names may be reused for other purposes (such as i for a counter variable).
+
+     When called with no arguments, return a scalar with the value i.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+Return a scalar, matrix, or N-dimensional array whose elements are all equal to the pure imaginary unit, defined as `sqrt (-1)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+NA
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 881
+ -- Built-in Function:  NA
+ -- Built-in Function:  NA (N)
+ -- Built-in Function:  NA (N, M)
+ -- Built-in Function:  NA (N, M, K, ...)
+ -- Built-in Function:  NA (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are all equal to the special constant used to designate missing values.
+
+     Note that NA always compares not equal to NA (NA != NA).  To find NA values, use the `isna' function.
+
+     When called with no arguments, return a scalar with the value `NA'.  When called with a single argument, return a square matrix with the dimension specified.  When called with more than one scalar argument the first two arguments are taken as the number of rows and columns and any further arguments specify additional matrix dimensions.  The optional argument CLASS specifies the return type and may be either "double" or "single".  See also: isna.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+Return a scalar, matrix, or N-dimensional array whose elements are all equal to the special constant used to designate missing values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+false
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 261
+ -- Built-in Function:  false (X)
+ -- Built-in Function:  false (N, M)
+ -- Built-in Function:  false (N, M, K, ...)
+     Return a matrix or N-dimensional array whose elements are all logical 0.  The arguments are handled the same as the arguments for `eye'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Return a matrix or N-dimensional array whose elements are all logical 0.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+true
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 258
+ -- Built-in Function:  true (X)
+ -- Built-in Function:  true (N, M)
+ -- Built-in Function:  true (N, M, K, ...)
+     Return a matrix or N-dimensional array whose elements are all logical 1.  The arguments are handled the same as the arguments for `eye'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Return a matrix or N-dimensional array whose elements are all logical 1.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+eye
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1016
+ -- Built-in Function:  eye (X)
+ -- Built-in Function:  eye (N, M)
+ -- Built-in Function:  eye (..., CLASS)
+     Return an identity matrix.  If invoked with a single scalar argument, `eye' returns a square matrix with the dimension specified.  If you supply two scalar arguments, `eye' takes them to be the number of rows and columns.  If given a vector with two elements, `eye' uses the values of the elements as the number of rows and columns, respectively.  For example,
+
+          eye (3)
+               =>  1  0  0
+                   0  1  0
+                   0  0  1
+
+     The following expressions all produce the same result:
+
+          eye (2)
+          ==
+          eye (2, 2)
+          ==
+          eye (size ([1, 2; 3, 4])
+
+     The optional argument CLASS, allows `eye' to return an array of the specified type, like
+
+          val = zeros (n,m, "uint8")
+
+     Calling `eye' with no arguments is equivalent to calling it with an argument of 1.  This odd definition is for compatibility with MATLAB.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Return an identity matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+linspace
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 547
+ -- Built-in Function:  linspace (BASE, LIMIT, N)
+     Return a row vector with N linearly spaced elements between BASE and LIMIT.  If the number of elements is greater than one, then the BASE and LIMIT are always included in the range.  If BASE is greater than LIMIT, the elements are stored in decreasing order.  If the number of points is not specified, a value of 100 is used.
+
+     The `linspace' function always returns a row vector.
+
+     For compatibility with MATLAB, return the second argument if fewer than two values are requested.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Return a row vector with N linearly spaced elements between BASE and LIMIT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+resize
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1131
+ -- Built-in Function:  resize (X, M)
+ -- Built-in Function:  resize (X, M, N)
+ -- Built-in Function:  resize (X, M, N, ...)
+     Resize X cutting off elements as necessary.
+
+     In the result, element with certain indices is equal to the corresponding element of X if the indices are within the bounds of X; otherwise, the element is set to zero.
+
+     In other words, the statement
+
+            y = resize (x, dv);
+
+     is equivalent to the following code:
+
+            y = zeros (dv, class (x));
+            sz = min (dv, size (x));
+            for i = 1:length (sz), idx{i} = 1:sz(i); endfor
+            y(idx{:}) = x(idx{:});
+
+     but is performed more efficiently.
+
+     If only M is supplied and it is a scalar, the dimension of the result is M-by-M.  If M is a vector, then the dimensions of the result are given by the elements of M.  If both M and N are scalars, then the dimensions of the result are M-by-N.
+
+     An object can be resized to more dimensions than it has; in such case the missing dimensions are assumed to be 1.  Resizing an object to fewer dimensions is not possible.  See also: reshape, postpad.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Resize X cutting off elements as necessary.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+reshape
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 612
+ -- Built-in Function:  reshape (A, M, N, ...)
+ -- Built-in Function:  reshape (A, SIZE)
+     Return a matrix with the given dimensions whose elements are taken from the matrix A.  The elements of the matrix are accessed in column-major order (like Fortran arrays are stored).
+
+     For example,
+
+          reshape ([1, 2, 3, 4], 2, 2)
+               =>  1  3
+                   2  4
+
+     Note that the total number of elements in the original matrix must match the total number of elements in the new matrix.
+
+     A single dimension of the return matrix can be unknown and is flagged by an empty argument.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+Return a matrix with the given dimensions whose elements are taken from the matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+squeeze
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Built-in Function:  squeeze (X)
+     Remove singleton dimensions from X and return the result.  Note that for compatibility with MATLAB, all objects have a minimum of two dimensions and row vectors are left unchanged.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Remove singleton dimensions from X and return the result.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+full
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+ -- Loadable Function: FM = full (SM)
+     returns a full storage matrix from a sparse, diagonal, permutation matrix or a range.  See also: sparse.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+returns a full storage matrix from a sparse, diagonal, permutation matrix or a range.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+norm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1203
+ -- Built-in Function:  norm (A, P, OPT)
+     Compute the p-norm of the matrix A.  If the second argument is missing, `p = 2' is assumed.
+
+     If A is a matrix (or sparse matrix):
+
+    P = `1'
+          1-norm, the largest column sum of the absolute values of A.
+
+    P = `2'
+          Largest singular value of A.
+
+    P = `Inf' or `"inf"'
+          Infinity norm, the largest row sum of the absolute values of A.
+
+    P = `"fro"'
+          Frobenius norm of A, `sqrt (sum (diag (A' * A)))'.
+
+    other P, `P > 1'
+          maximum `norm (A*x, p)' such that `norm (x, p) == 1'
+
+     If A is a vector or a scalar:
+
+    P = `Inf' or `"inf"'
+          `max (abs (A))'.
+
+    P = `-Inf'
+          `min (abs (A))'.
+
+    P = `"fro"'
+          Frobenius norm of A, `sqrt (sumsq (abs (a)))'.
+
+    P = 0
+          Hamming norm - the number of nonzero elements.
+
+    other P, `P > 1'
+          p-norm of A, `(sum (abs (A) .^ P)) ^ (1/P)'.
+
+    other P `P < 1'
+          the p-pseudonorm defined as above.
+
+     If `"rows"' is given as OPT, the norms of all rows of the matrix A are returned as a column vector.  Similarly, if `"columns"' or `"cols"' is passed column norms are computed.  See also: cond, svd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Compute the p-norm of the matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+not
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+ -- Built-in Function:  not (X)
+     This function is equivalent to `! x'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+This function is equivalent to `! x'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+uplus
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+ -- Built-in Function:  uplus (X)
+     This function is equivalent to `+ x'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+This function is equivalent to `+ x'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+uminus
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+ -- Built-in Function:  uminus (X)
+     This function is equivalent to `- x'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+This function is equivalent to `- x'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+transpose
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Built-in Function:  transpose (X)
+     This function is equivalent to `x.''.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function is equivalent to `x.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+ctranspose
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Built-in Function:  ctranspose (X)
+     This function is equivalent to `x''.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+This function is equivalent to `x''.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+plus
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Built-in Function:  plus (X, Y)
+     This function is equivalent to `x + y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x + y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+minus
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+ -- Built-in Function:  minus (X, Y)
+     This function is equivalent to `x - y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x - y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mtimes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  mtimes (X, Y)
+     This function is equivalent to `x * y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x * y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+mrdivide
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+ -- Built-in Function:  mrdivide (X, Y)
+     This function is equivalent to `x / y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x / y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mpower
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  mpower (X, Y)
+     This function is equivalent to `x ^ y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x ^ y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+mldivide
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+ -- Built-in Function:  mldivide (X, Y)
+     This function is equivalent to `x \ y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x \ y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+lt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+ -- Built-in Function:  lt (X, Y)
+     This function is equivalent to `x < y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x < y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+le
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+ -- Built-in Function:  le (X, Y)
+     This function is equivalent to `x <= y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+This function is equivalent to `x <= y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+eq
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+ -- Built-in Function:  eq (X, Y)
+     This function is equivalent to `x == y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+This function is equivalent to `x == y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+ge
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+ -- Built-in Function:  ge (X, Y)
+     This function is equivalent to `x >= y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+This function is equivalent to `x >= y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+gt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+ -- Built-in Function:  gt (X, Y)
+     This function is equivalent to `x > y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x > y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+ne
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+ -- Built-in Function:  ne (X, Y)
+     This function is equivalent to `x != y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+This function is equivalent to `x != y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+times
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  times (X, Y)
+     This function is equivalent to `x .* y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+This function is equivalent to `x .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rdivide
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+ -- Built-in Function:  rdivide (X, Y)
+     This function is equivalent to `x ./ y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+This function is equivalent to `x .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+power
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  power (X, Y)
+     This function is equivalent to `x .^ y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+This function is equivalent to `x .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ldivide
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+ -- Built-in Function:  ldivide (X, Y)
+     This function is equivalent to `x .\ y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+This function is equivalent to `x .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+and
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+ -- Built-in Function:  and (X, Y)
+     This function is equivalent to `x & y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x & y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+or
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+ -- Built-in Function:  or (X, Y)
+     This function is equivalent to `x | y'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is equivalent to `x | y'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+tic
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1367
+ -- Built-in Function:  tic ()
+ -- Built-in Function:  toc ()
+     Set or check a wall-clock timer.  Calling `tic' without an output argument sets the timer.  Subsequent calls to `toc' return the number of seconds since the timer was set.  For example,
+
+          tic ();
+          # many computations later...
+          elapsed_time = toc ();
+
+     will set the variable `elapsed_time' to the number of seconds since the most recent call to the function `tic'.
+
+     If called with one output argument then this function returns a scalar of type `uint64' and the wall-clock timer is not started.
+
+          t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6
+               => 5
+
+     Nested timing with `tic' and `toc' is not supported.  Therefore `toc' will always return the elapsed time from the most recent call to `tic'.
+
+     If you are more interested in the CPU time that your process used, you should use the `cputime' function instead.  The `tic' and `toc' functions report the actual wall clock time that elapsed between the calls.  This may include time spent processing other jobs or doing nothing at all.  For example,
+
+          tic (); sleep (5); toc ()
+               => 5
+          t = cputime (); sleep (5); cputime () - t
+               => 0
+
+     (This example also illustrates that the CPU timer may have a fairly coarse resolution.)
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Set or check a wall-clock timer.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+toc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+ -- Built-in Function:  toc ()
+     See tic.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+See tic.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cputime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 653
+ -- Built-in Function: [TOTAL, USER, SYSTEM] = cputime ();
+     Return the CPU time used by your Octave session.  The first output is the total time spent executing your process and is equal to the sum of second and third outputs, which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode, respectively.  If your system does not have a way to report CPU time usage, `cputime' returns 0 for each of its output values.  Note that because Octave used some CPU time to start, it is reasonable to check to see if `cputime' works by checking to see if the total CPU time used is nonzero.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return the CPU time used by your Octave session.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sort
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1417
+ -- Loadable Function: [S, I] = sort (X)
+ -- Loadable Function: [S, I] = sort (X, DIM)
+ -- Loadable Function: [S, I] = sort (X, MODE)
+ -- Loadable Function: [S, I] = sort (X, DIM, MODE)
+     Return a copy of X with the elements arranged in increasing order.  For matrices, `sort' orders the elements in each column.
+
+     For example,
+
+          sort ([1, 2; 2, 3; 3, 1])
+               =>  1  1
+                   2  2
+                   3  3
+
+     The `sort' function may also be used to produce a matrix containing the original row indices of the elements in the sorted matrix.  For example,
+
+          [s, i] = sort ([1, 2; 2, 3; 3, 1])
+               => s = 1  1
+                      2  2
+                      3  3
+               => i = 1  3
+                      2  1
+                      3  2
+
+     If the optional argument DIM is given, then the matrix is sorted along the dimension defined by DIM.  The optional argument `mode' defines the order in which the values will be sorted.  Valid values of `mode' are `ascend' or `descend'.
+
+     For equal elements, the indices are such that the equal elements are listed in the order that appeared in the original list.
+
+     The `sort' function may also be used to sort strings and cell arrays of strings, in which case the dictionary order of the strings is used.
+
+     The algorithm used in `sort' is optimized for the sorting of partially ordered lists.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return a copy of X with the elements arranged in increasing order.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+issorted
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 367
+ -- Built-in Function:  issorted (A, ROWS)
+     Returns true if the array is sorted, ascending or descending.  NaNs are treated as by `sort'.  If ROWS is supplied and has the value "rows", checks whether the array is sorted by rows as if output by `sortrows' (with no options).
+
+     This function does not yet support sparse matrices.  See also: sortrows, sort.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Returns true if the array is sorted, ascending or descending.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dbstop
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 501
+ -- Loadable Function: RLINE = dbstop (FUNC, LINE, ...)
+     Set a breakpoint in a function
+    `func'
+          String representing the function name.  When already in debug mode this should be left out and only the line should be given.
+
+    `line'
+          Line number you would like the breakpoint to be set on.  Multiple lines might be given as separate arguments or as a vector.
+
+     The rline returned is the real line that the breakpoint was set at.  See also: dbclear, dbstatus, dbstep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+Set a breakpoint in a function  `func'  String representing the function name.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dbclear
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 565
+ -- Loadable Function:  dbclear (FUNC, LINE, ...)
+     Delete a breakpoint in a function
+    `func'
+          String representing the function name.  When already in debug mode this should be left out and only the line should be given.
+
+    `line'
+          Line number where you would like to remove the breakpoint.  Multiple lines might be given as separate arguments or as a vector.
+     No checking is done to make sure that the line you requested is really a breakpoint.  If you get the wrong line nothing will happen.  See also: dbstop, dbstatus, dbwhere.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+Delete a breakpoint in a function  `func'  String representing the function name.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+dbstatus
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 277
+ -- Loadable Function: lst = dbstatus (FUNC)
+     Return a vector containing the lines on which a function has breakpoints set.
+    `func'
+          String representing the function name.  When already in debug mode this should be left out.
+     See also: dbclear, dbwhere.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Return a vector containing the lines on which a function has breakpoints set.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dbwhere
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+ -- Loadable Function:  dbwhere ()
+     Show where we are in the code See also: dbclear, dbstatus, dbstop.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Show where we are in the code See also: dbclear, dbstatus, dbstop.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dbtype
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 116
+ -- Loadable Function:  dbtype ()
+     List script file with line numbers.  See also: dbclear, dbstatus, dbstop.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+List script file with line numbers.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dbstack
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 199
+ -- Loadable Function: [STACK, IDX] dbstack (N)
+     Print or return current stack information.  With optional argument N, omit the N innermost stack frames.  See also: dbclear, dbstatus, dbstop.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Print or return current stack information.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+dbup
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 155
+ -- Loadable Function:  dbup (N)
+     In debugging mode, move up the execution stack N frames.  If N is omitted, move up one frame.  See also: dbstack.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+In debugging mode, move up the execution stack N frames.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dbdown
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 161
+ -- Loadable Function:  dbdown (N)
+     In debugging mode, move down the execution stack N frames.  If N is omitted, move down one frame.  See also: dbstack.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+In debugging mode, move down the execution stack N frames.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dbstep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 509
+ -- Command:  dbstep N
+ -- Command:  dbstep in
+ -- Command:  dbstep out
+     In debugging mode, execute the next N lines of code.  If N is omitted execute the next line of code.  If the next line of code is itself defined in terms of an m-file remain in the existing function.
+
+     Using `dbstep in' will cause execution of the next line to step into any m-files defined on the next line.  Using `dbstep out' with cause execution to continue until the current function returns.  See also: dbcont, dbquit.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+In debugging mode, execute the next N lines of code.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dbcont
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Command:  dbcont ()
+     In debugging mode, quit debugging mode and continue execution.  See also: dbstep, dbstep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+In debugging mode, quit debugging mode and continue execution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dbquit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+ -- Command:  dbquit ()
+     In debugging mode, quit debugging mode and return to the top level.  See also: dbstep, dbcont.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+In debugging mode, quit debugging mode and return to the top level.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+isdebugmode
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+ -- Command:  isdebugmode ()
+     Return true if debug mode is on, otherwise false.  See also: dbstack, dbclear, dbstop, dbstatus.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Return true if debug mode is on, otherwise false.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+EDITOR
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 394
+ -- Built-in Function: VAL = EDITOR ()
+ -- Built-in Function: OLD_VAL = EDITOR (NEW_VAL)
+     Query or set the internal variable that specifies the editor to use with the `edit_history' command.  The default value is taken from the environment variable `EDITOR' when Octave starts.  If the environment variable is not initialized, `EDITOR' will be set to `"emacs"'.  See also: edit_history.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+Query or set the internal variable that specifies the editor to use with the `edit_history' command.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+EXEC_PATH
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 690
+ -- Built-in Function: VAL = EXEC_PATH ()
+ -- Built-in Function: OLD_VAL = EXEC_PATH (NEW_VAL)
+     Query or set the internal variable that specifies a colon separated list of directories to search when executing external programs.  Its initial value is taken from the environment variable `OCTAVE_EXEC_PATH' (if it exists) or `PATH', but that value can be overridden by the command line argument `--exec-path PATH'.  At startup, an additional set of directories (including the shell PATH) is appended to the path specified in the environment or on the command line.  If you use the `EXEC_PATH' function to modify the path, you should take care to preserve these additional directories.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+Query or set the internal variable that specifies a colon separated list of directories to search when executing external programs.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+IMAGE_PATH
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 229
+ -- Built-in Function: VAL = IMAGE_PATH ()
+ -- Built-in Function: OLD_VAL = IMAGE_PATH (NEW_VAL)
+     Query or set the internal variable that specifies a colon separated list of directories in which to search for image files.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+Query or set the internal variable that specifies a colon separated list of directories in which to search for image files.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+OCTAVE_HOME
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+ -- Built-in Function:  OCTAVE_HOME ()
+     Return the name of the top-level Octave installation directory.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return the name of the top-level Octave installation directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+OCTAVE_VERSION
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Built-in Function:  OCTAVE_VERSION ()
+     Return the version number of Octave, as a string.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Return the version number of Octave, as a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+det
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 205
+ -- Loadable Function: [D, RCOND] = det (A)
+     Compute the determinant of A using LAPACK for full and UMFPACK for sparse matrices.  Return an estimate of the reciprocal condition number if requested.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Compute the determinant of A using LAPACK for full and UMFPACK for sparse matrices.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+cd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 409
+ -- Command: cd dir
+ -- Command: chdir dir
+     Change the current working directory to DIR.  If DIR is omitted, the current directory is changed to the user's home directory.  For example,
+
+          cd ~/octave
+
+     Changes the current working directory to `~/octave'.  If the directory does not exist, an error message is printed and the working directory is not changed.  See also: mkdir, rmdir, dir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Change the current working directory to DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+pwd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+ -- Built-in Function:  pwd ()
+     Return the current working directory.  See also: dir, ls.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return the current working directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+readdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 356
+ -- Built-in Function: [FILES, ERR, MSG] = readdir (DIR)
+     Return names of the files in the directory DIR as a cell array of strings.  If an error occurs, return an empty cell array in FILES.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.  See also: dir, glob.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Return names of the files in the directory DIR as a cell array of strings.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+mkdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 402
+ -- Built-in Function: [STATUS, MSG, MSGID] = mkdir (DIR)
+ -- Built-in Function: [STATUS, MSG, MSGID] = mkdir (PARENT, DIR)
+     Create a directory named DIR in the directory PARENT.
+
+     If successful, STATUS is 1, with MSG and MSGID empty character strings.  Otherwise, STATUS is 0, MSG contains a system-dependent error message, and MSGID contains a unique message identifier.  See also: rmdir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Create a directory named DIR in the directory PARENT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+rmdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 520
+ -- Built-in Function: [STATUS, MSG, MSGID] = rmdir (DIR)
+ -- Built-in Function: [STATUS, MSG, MSGID] = rmdir (DIR, `"s"')
+     Remove the directory named DIR.
+
+     If successful, STATUS is 1, with MSG and MSGID empty character strings.  Otherwise, STATUS is 0, MSG contains a system-dependent error message, and MSGID contains a unique message identifier.
+
+     If the optional second parameter is supplied with value `"s"', recursively remove all subdirectories as well.  See also: mkdir, confirm_recursive_rmdir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Remove the directory named DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+link
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 283
+ -- Built-in Function: [ERR, MSG] = link (OLD, NEW)
+     Create a new link (also known as a hard link) to an existing file.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.  See also: symlink.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Create a new link (also known as a hard link) to an existing file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+symlink
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 284
+ -- Built-in Function: [ERR, MSG] = symlink (OLD, NEW)
+     Create a symbolic link NEW which contains the string OLD.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.  See also: link, readlink.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Create a symbolic link NEW which contains the string OLD.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+readlink
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 337
+ -- Built-in Function: [RESULT, ERR, MSG] = readlink (SYMLINK)
+     Read the value of the symbolic link SYMLINK.
+
+     If successful, RESULT contains the contents of the symbolic link SYMLINK, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.  See also: link, symlink.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Read the value of the symbolic link SYMLINK.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+rename
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 254
+ -- Built-in Function: [ERR, MSG] = rename (OLD, NEW)
+     Change the name of file OLD to NEW.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.  See also: ls, dir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Change the name of file OLD to NEW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+glob
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 423
+ -- Built-in Function:  glob (PATTERN)
+     Given an array of strings (as a char array or a cell array) in PATTERN, return a cell array of file names that match any of them, or an empty cell array if no patterns match.  Tilde expansion is performed on each of the patterns before looking for matching file names.  For example,
+
+          glob ("/vm*")
+               => "/vmlinuz"
+     See also: dir, ls, stat, readdir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 174
+Given an array of strings (as a char array or a cell array) in PATTERN, return a cell array of file names that match any of them, or an empty cell array if no patterns match.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+fnmatch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 304
+ -- Built-in Function:  fnmatch (PATTERN, STRING)
+     Return 1 or zero for each element of STRING that matches any of the elements of the string array PATTERN, using the rules of filename pattern matching.  For example,
+
+          fnmatch ("a*b", {"ab"; "axyzb"; "xyzab"})
+               => [ 1; 1; 0 ]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+Return 1 or zero for each element of STRING that matches any of the elements of the string array PATTERN, using the rules of filename pattern matching.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+filesep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 433
+ -- Built-in Function:  filesep ()
+ -- Built-in Function:  filesep ('all')
+     Return the system-dependent character used to separate directory names.
+
+     If 'all' is given, the function return all valid file separators in the form of a string.  The list of file separators is system-dependent.  It is / (forward slash) under UNIX or Mac OS X, / and \ (forward and backward slashes) under Windows.  See also: pathsep, dir, ls.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return the system-dependent character used to separate directory names.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+pathsep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 195
+ -- Built-in Function: VAL = pathsep ()
+ -- Built-in Function: OLD_VAL = pathsep (NEW_VAL)
+     Query or set the character used to separate directories in a path.  See also: filesep, dir, ls.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Query or set the character used to separate directories in a path.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+confirm_recursive_rmdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 267
+ -- Built-in Function: VAL = confirm_recursive_rmdir ()
+ -- Built-in Function: OLD_VAL = confirm_recursive_rmdir (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will ask for confirmation before recursively removing a directory tree.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+Query or set the internal variable that controls whether Octave will ask for confirmation before recursively removing a directory tree.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+builtin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 177
+ -- Loadable Function: [...] builtin (F, ...)
+     Call the base function F even if F is overloaded to some other function for the given type signature.  See also: dispatch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+Call the base function F even if F is overloaded to some other function for the given type signature.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+dispatch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 463
+ -- Loadable Function:  dispatch (F, R, TYPE)
+     Replace the function F with a dispatch so that function R is called when F is called with the first argument of the named TYPE.  If the type is ANY then call R if no other type matches.  The original function F is accessible using `builtin (F, ...)'.
+
+     If R is omitted, clear dispatch function associated with TYPE.
+
+     If both R and TYPE are omitted, list dispatch functions for F.  See also: builtin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+Replace the function F with a dispatch so that function R is called when F is called with the first argument of the named TYPE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dlmread
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 795
+ -- Loadable Function: DATA = dlmread (FILE)
+ -- Loadable Function: DATA = dlmread (FILE, SEP)
+ -- Loadable Function: DATA = dlmread (FILE, SEP, R0, C0)
+ -- Loadable Function: DATA = dlmread (FILE, SEP, RANGE)
+     Read the matrix DATA from a text file.  If not defined the separator between fields is determined from the file itself.  Otherwise the separation character is defined by SEP.
+
+     Given two scalar arguments R0 and C0, these define the starting row and column of the data to be read.  These values are indexed from zero, such that the first row corresponds to an index of zero.
+
+     The RANGE parameter must be a 4 element vector containing the upper left and lower right corner `[R0,C0,R1,C1]' or a spreadsheet style range such as 'A2..Q15'.  The lowest index value is zero.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Read the matrix DATA from a text file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+dmperm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 714
+ -- Loadable Function: P = dmperm (S)
+ -- Loadable Function: [P, Q, R, S] = dmperm (S)
+     Perform a Dulmage-Mendelsohn permutation on the sparse matrix S.  With a single output argument "dmperm" performs the row permutations P such that `S (P,:)' has no zero elements on the diagonal.
+
+     Called with two or more output arguments, returns the row and column permutations, such that `S (P, Q)' is in block triangular form.  The values of R and S define the boundaries of the blocks.  If S is square then `R == S'.
+
+     The method used is described in: A. Pothen & C.-J. Fan. Computing the block triangular form of a sparse matrix. ACM Trans. Math. Software, 16(4):303-324, 1990.  See also: colamd, ccolamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Perform a Dulmage-Mendelsohn permutation on the sparse matrix S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sprank
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 400
+ -- Loadable Function: P = sprank (S)
+     Calculates the structural rank of a sparse matrix S.  Note that only the structure of the matrix is used in this calculation based on a Dulmage-Mendelsohn permutation to block triangular form.  As such the numerical rank of the matrix S is bounded by `sprank (S) >= rank (S)'.  Ignoring floating point errors `sprank (S) == rank (S)'.  See also: dmperm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Calculates the structural rank of a sparse matrix S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+eig
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 565
+ -- Loadable Function: LAMBDA = eig (A)
+ -- Loadable Function: LAMBDA = eig (A, B)
+ -- Loadable Function: [V, LAMBDA] = eig (A)
+ -- Loadable Function: [V, LAMBDA] = eig (A, B)
+     The eigenvalues (and eigenvectors) of a matrix are computed in a several step process which begins with a Hessenberg decomposition, followed by a Schur decomposition, from which the eigenvalues are apparent.  The eigenvectors, when desired, are computed by further manipulations of the Schur decomposition.
+
+     The eigenvalues returned by `eig' are not ordered.  See also: eigs.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 207
+The eigenvalues (and eigenvectors) of a matrix are computed in a several step process which begins with a Hessenberg decomposition, followed by a Schur decomposition, from which the eigenvalues are apparent.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+eigs
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5508
+ -- Loadable Function: D = eigs (A)
+ -- Loadable Function: D = eigs (A, K)
+ -- Loadable Function: D = eigs (A, K, SIGMA)
+ -- Loadable Function: D = eigs (A, K, SIGMA,OPTS)
+ -- Loadable Function: D = eigs (A, B)
+ -- Loadable Function: D = eigs (A, B, K)
+ -- Loadable Function: D = eigs (A, B, K, SIGMA)
+ -- Loadable Function: D = eigs (A, B, K, SIGMA, OPTS)
+ -- Loadable Function: D = eigs (AF, N)
+ -- Loadable Function: D = eigs (AF, N, B)
+ -- Loadable Function: D = eigs (AF, N, K)
+ -- Loadable Function: D = eigs (AF, N, B, K)
+ -- Loadable Function: D = eigs (AF, N, K, SIGMA)
+ -- Loadable Function: D = eigs (AF, N, B, K, SIGMA)
+ -- Loadable Function: D = eigs (AF, N, K, SIGMA, OPTS)
+ -- Loadable Function: D = eigs (AF, N, B, K, SIGMA, OPTS)
+ -- Loadable Function: [V, D] = eigs (A, ...)
+ -- Loadable Function: [V, D] = eigs (AF, N, ...)
+ -- Loadable Function: [V, D, FLAG] = eigs (A, ...)
+ -- Loadable Function: [V, D, FLAG] = eigs (AF, N, ...)
+     Calculate a limited number of eigenvalues and eigenvectors of A, based on a selection criteria.  The number eigenvalues and eigenvectors to calculate is given by K whose default value is 6.
+
+     By default `eigs' solve the equation `A * v = lambda * v' , where `lambda' is a scalar representing one of the eigenvalues, and `v' is the corresponding eigenvector.  If given the positive definite matrix B then `eigs' solves the general eigenvalue equation `A * v = lambda * B * v' .
+
+     The argument SIGMA determines which eigenvalues are returned.  SIGMA can be either a scalar or a string.  When SIGMA is a scalar, the K eigenvalues closest to SIGMA are returned.  If SIGMA is a string, it must have one of the values
+
+    'lm'
+          Largest magnitude (default).
+
+    'sm'
+          Smallest magnitude.
+
+    'la'
+          Largest Algebraic (valid only for real symmetric problems).
+
+    'sa'
+          Smallest Algebraic (valid only for real symmetric problems).
+
+    'be'
+          Both ends, with one more from the high-end if K is odd (valid only for real symmetric problems).
+
+    'lr'
+          Largest real part (valid only for complex or unsymmetric problems).
+
+    'sr'
+          Smallest real part (valid only for complex or unsymmetric problems).
+
+    'li'
+          Largest imaginary part (valid only for complex or unsymmetric problems).
+
+    'si'
+          Smallest imaginary part (valid only for complex or unsymmetric problems).
+
+     If OPTS is given, it is a structure defining some of the options that `eigs' should use.  The fields of the structure OPTS are
+
+    `issym'
+          If AF is given, then flags whether the function AF defines a symmetric problem.  It is ignored if A is given.  The default is false.
+
+    `isreal'
+          If AF is given, then flags whether the function AF defines a real problem.  It is ignored if A is given.  The default is true.
+
+    `tol'
+          Defines the required convergence tolerance, given as `tol * norm (A)'.  The default is `eps'.
+
+    `maxit'
+          The maximum number of iterations.  The default is 300.
+
+    `p'
+          The number of Lanzcos basis vectors to use.  More vectors will result in faster convergence, but a larger amount of memory.  The optimal value of 'p' is problem dependent and should be in the range K to N.  The default value is `2 * K'.
+
+    `v0'
+          The starting vector for the computation.  The default is to have ARPACK randomly generate a starting vector.
+
+    `disp'
+          The level of diagnostic printout.  If `disp' is 0 then there is no printout.  The default value is 1.
+
+    `cholB'
+          Flag if `chol (B)' is passed rather than B.  The default is false.
+
+    `permB'
+          The permutation vector of the Cholesky factorization of B if `cholB' is true.  That is `chol ( B (permB, permB))'.  The default is `1:N'.
+
+
+     It is also possible to represent A by a function denoted AF.  AF must be followed by a scalar argument N defining the length of the vector argument accepted by AF.  AF can be passed either as an inline function, function handle or as a string.  In the case where AF is passed as a string, the name of the string defines the function to use.
+
+     AF is a function of the form `function y = af (x), y = ...; endfunction', where the required return value of AF is determined by the value of SIGMA, and are
+
+    `A * x'
+          If SIGMA is not given or is a string other than 'sm'.
+
+    `A \ x'
+          If SIGMA is 'sm'.
+
+    `(A - sigma * I) \ x'
+          for standard eigenvalue problem, where `I' is the identity matrix of the same size as `A'.  If SIGMA is zero, this reduces the `A \ x'.
+
+    `(A - sigma * B) \ x'
+          for the general eigenvalue problem.
+
+     The return arguments of `eigs' depends on the number of return arguments.  With a single return argument, a vector D of length K is returned, represent the K eigenvalues that have been found.  With two return arguments, V is a N-by-K matrix whose columns are the K eigenvectors corresponding to the returned eigenvalues.  The eigenvalues themselves are then returned in D in the form of a N-by-K matrix, where the elements on the diagonal are the eigenvalues.
+
+     Given a third return argument FLAG, `eigs' also returns the status of the convergence.  If FLAG is 0, then all eigenvalues have converged, otherwise not.
+
+     This function is based on the ARPACK package, written by R Lehoucq, K Maschhoff, D Sorensen and C Yang.  For more information see `http://www.caam.rice.edu/software/ARPACK/'.
+
+   See also: eig, svds.  
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Calculate a limited number of eigenvalues and eigenvectors of A, based on a selection criteria.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rethrow
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 359
+ -- Built-in Function:  rethrow (ERR)
+     Reissues a previous error as defined by ERR.  ERR is a structure that must contain at least the 'message' and 'identifier' fields.  ERR can also contain a field 'stack' that gives information on the assumed location of the error.  Typically ERR is returned from `lasterror'.  See also: lasterror, lasterr, error.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Reissues a previous error as defined by ERR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+error
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1719
+ -- Built-in Function:  error (TEMPLATE, ...)
+ -- Built-in Function:  error (ID, TEMPLATE, ...)
+     Format the optional arguments under the control of the template string TEMPLATE using the same rules as the `printf' family of functions (*note Formatted Output::) and print the resulting message on the `stderr' stream.  The message is prefixed by the character string `error: '.
+
+     Calling `error' also sets Octave's internal error state such that control will return to the top level without evaluating any more commands.  This is useful for aborting from functions or scripts.
+
+     If the error message does not end with a new line character, Octave will print a traceback of all the function calls leading to the error.  For example, given the following function definitions:
+
+          function f () g (); end
+          function g () h (); end
+          function h () nargin == 1 || error ("nargin != 1"); end
+
+     calling the function `f' will result in a list of messages that can help you to quickly locate the exact location of the error:
+
+          f ()
+          error: nargin != 1
+          error: called from:
+          error:   error at line -1, column -1
+          error:   h at line 1, column 27
+          error:   g at line 1, column 15
+          error:   f at line 1, column 15
+
+     If the error message ends in a new line character, Octave will print the message but will not display any traceback messages as it returns control to the top level.  For example, modifying the error message in the previous example to end in a new line causes Octave to only print a single message:
+
+          function h () nargin == 1 || error ("nargin != 1\n"); end
+          f ()
+          error: nargin != 1
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 219
+Format the optional arguments under the control of the template string TEMPLATE using the same rules as the `printf' family of functions (*note Formatted Output::) and print the resulting message on the `stderr' stream.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+warning
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1166
+ -- Built-in Function:  warning (TEMPLATE, ...)
+ -- Built-in Function:  warning (ID, TEMPLATE, ...)
+     Format the optional arguments under the control of the template string TEMPLATE using the same rules as the `printf' family of functions (*note Formatted Output::) and print the resulting message on the `stderr' stream.  The message is prefixed by the character string `warning: '.  You should use this function when you want to notify the user of an unusual condition, but only when it makes sense for your program to go on.
+
+     The optional message identifier allows users to enable or disable warnings tagged by ID.  The special identifier `"all"' may be used to set the state of all warnings.
+
+ -- Built-in Function:  warning ("on", ID)
+ -- Built-in Function:  warning ("off", ID)
+ -- Built-in Function:  warning ("error", ID)
+ -- Built-in Function:  warning ("query", ID)
+     Set or query the state of a particular warning using the identifier ID.  If the identifier is omitted, a value of `"all"' is assumed.  If you set the state of a warning to `"error"', the warning named by ID is handled as if it were an error instead.  See also: warning_ids.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Set or query the state of a particular warning using the identifier ID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+lasterror
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1405
+ -- Built-in Function: ERR = lasterror (ERR)
+ -- Built-in Function:  lasterror ('reset')
+     Returns or sets the last error message.  Called without any arguments returns a structure containing the last error message, as well as other information related to this error.  The elements of this structure are:
+
+    'message'
+          The text of the last error message
+
+    'identifier'
+          The message identifier of this error message
+
+    'stack'
+          A structure containing information on where the message occurred.  This might be an empty structure if this in the case where this information cannot be obtained.  The fields of this structure are:
+
+         'file'
+               The name of the file where the error occurred
+
+         'name'
+               The name of function in which the error occurred
+
+         'line'
+               The line number at which the error occurred
+
+         'column'
+               An optional field with the column number at which the error occurred
+
+     The ERR structure may also be passed to `lasterror' to set the information about the last error.  The only constraint on ERR in that case is that it is a scalar structure.  Any fields of ERR that match the above are set to the value passed in ERR, while other fields are set to their default values.
+
+     If `lasterror' is called with the argument 'reset', all values take their default values.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Returns or sets the last error message.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+lasterr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 235
+ -- Built-in Function: [MSG, MSGID] = lasterr (MSG, MSGID)
+     Without any arguments, return the last error message.  With one argument, set the last error message to MSG.  With two arguments, also set the last message identifier.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Without any arguments, return the last error message.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+lastwarn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 240
+ -- Built-in Function: [MSG, MSGID] = lastwarn (MSG, MSGID)
+     Without any arguments, return the last warning message.  With one argument, set the last warning message to MSG.  With two arguments, also set the last message identifier.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Without any arguments, return the last warning message.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+usage
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 814
+ -- Built-in Function:  usage (MSG)
+     Print the message MSG, prefixed by the string `usage: ', and set Octave's internal error state such that control will return to the top level without evaluating any more commands.  This is useful for aborting from functions.
+
+     After `usage' is evaluated, Octave will print a traceback of all the function calls leading to the usage message.
+
+     You should use this function for reporting problems errors that result from an improper call to a function, such as calling a function with an incorrect number of arguments, or with arguments of the wrong type.  For example, most functions distributed with Octave begin with code like this
+
+          if (nargin != 2)
+            usage ("foo (a, b)");
+          endif
+
+     to check for the proper number of arguments.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 179
+Print the message MSG, prefixed by the string `usage: ', and set Octave's internal error state such that control will return to the top level without evaluating any more commands.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+beep_on_error
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+ -- Built-in Function: VAL = beep_on_error ()
+ -- Built-in Function: OLD_VAL = beep_on_error (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will try to ring the terminal bell before printing an error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Query or set the internal variable that controls whether Octave will try to ring the terminal bell before printing an error message.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+debug_on_error
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 352
+ -- Built-in Function: VAL = debug_on_error ()
+ -- Built-in Function: OLD_VAL = debug_on_error (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will try to enter the debugger when an error is encountered.  This will also inhibit printing of the normal traceback message (you will only see the top-level error message).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+Query or set the internal variable that controls whether Octave will try to enter the debugger when an error is encountered.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+debug_on_warning
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 243
+ -- Built-in Function: VAL = debug_on_warning ()
+ -- Built-in Function: OLD_VAL = debug_on_warning (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will try to enter the debugger when a warning is encountered.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+Query or set the internal variable that controls whether Octave will try to enter the debugger when a warning is encountered.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+fft
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 802
+ -- Loadable Function:  fft (A, N, DIM)
+     Compute the FFT of A using subroutines from FFTW.  The FFT is calculated along the first non-singleton dimension of the array.  Thus if A is a matrix, `fft (A)' computes the FFT for each column of A.
+
+     If called with two arguments, N is expected to be an integer specifying the number of elements of A to use, or an empty matrix to specify that its value should be ignored.  If N is larger than the dimension along which the FFT is calculated, then A is resized and padded with zeros.  Otherwise, if N is smaller than the dimension along which the FFT is calculated, then A is truncated.
+
+     If called with three arguments, DIM is an integer specifying the dimension of the matrix along which the FFT is performed See also: ifft, fft2, fftn, fftw.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Compute the FFT of A using subroutines from FFTW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+ifft
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 851
+ -- Loadable Function:  ifft (A, N, DIM)
+     Compute the inverse FFT of A using subroutines from FFTW.  The inverse FFT is calculated along the first non-singleton dimension of the array.  Thus if A is a matrix, `fft (A)' computes the inverse FFT for each column of A.
+
+     If called with two arguments, N is expected to be an integer specifying the number of elements of A to use, or an empty matrix to specify that its value should be ignored.  If N is larger than the dimension along which the inverse FFT is calculated, then A is resized and padded with zeros.  Otherwise, ifN is smaller than the dimension along which the inverse FFT is calculated, then A is truncated.
+
+     If called with three arguments, DIM is an integer specifying the dimension of the matrix along which the inverse FFT is performed See also: fft, ifft2, ifftn, fftw.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Compute the inverse FFT of A using subroutines from FFTW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fft2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 430
+ -- Loadable Function:  fft2 (A, N, M)
+     Compute the two-dimensional FFT of A using subroutines from FFTW.  The optional arguments N and M may be used specify the number of rows and columns of A to use.  If either of these is larger than the size of A, A is resized and padded with zeros.
+
+     If A is a multi-dimensional matrix, each two-dimensional sub-matrix of A is treated separately See also: ifft2, fft, fftn, fftw.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Compute the two-dimensional FFT of A using subroutines from FFTW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ifft2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 439
+ -- Loadable Function:  fft2 (A, N, M)
+     Compute the inverse two-dimensional FFT of A using subroutines from FFTW.  The optional arguments N and M may be used specify the number of rows and columns of A to use.  If either of these is larger than the size of A, A is resized and padded with zeros.
+
+     If A is a multi-dimensional matrix, each two-dimensional sub-matrix of A is treated separately See also: fft2, ifft, ifftn, fftw.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Compute the inverse two-dimensional FFT of A using subroutines from FFTW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fftn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 482
+ -- Loadable Function:  fftn (A, SIZE)
+     Compute the N-dimensional FFT of A using subroutines from FFTW.  The optional vector argument SIZE may be used specify the dimensions of the array to be used.  If an element of SIZE is smaller than the corresponding dimension, then the dimension is truncated prior to performing the FFT.  Otherwise if an element of SIZE is larger than the corresponding dimension A is resized and padded with zeros.  See also: ifftn, fft, fft2, fftw.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Compute the N-dimensional FFT of A using subroutines from FFTW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ifftn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 500
+ -- Loadable Function:  ifftn (A, SIZE)
+     Compute the inverse N-dimensional FFT of A using subroutines from FFTW.  The optional vector argument SIZE may be used specify the dimensions of the array to be used.  If an element of SIZE is smaller than the corresponding dimension, then the dimension is truncated prior to performing the inverse FFT.  Otherwise if an element of SIZE is larger than the corresponding dimension A is resized and padded with zeros.  See also: fftn, ifft, ifft2, fftw.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Compute the inverse N-dimensional FFT of A using subroutines from FFTW.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fftw
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2792
+ -- Loadable Function: METHOD = fftw ('planner')
+ -- Loadable Function:  fftw ('planner', METHOD)
+ -- Loadable Function: WISDOM = fftw ('dwisdom')
+ -- Loadable Function: WISDOM = fftw ('dwisdom', WISDOM)
+     Manage FFTW wisdom data.  Wisdom data can be used to significantly accelerate the calculation of the FFTs but implies an initial cost in its calculation.  When the FFTW libraries are initialized, they read a system wide wisdom file (typically in `/etc/fftw/wisdom'), allowing wisdom to be shared between applications other than Octave.  Alternatively, the `fftw' function can be used to import wisdom.  For example
+
+          WISDOM = fftw ('dwisdom')
+
+     will save the existing wisdom used by Octave to the string WISDOM.  This string can then be saved to a file and restored using the `save' and `load' commands respectively.  This existing wisdom can be reimported as follows
+
+          fftw ('dwisdom', WISDOM)
+
+     If WISDOM is an empty matrix, then the wisdom used is cleared.
+
+     During the calculation of Fourier transforms further wisdom is generated.  The fashion in which this wisdom is generated is equally controlled by the `fftw' function.  There are five different manners in which the wisdom can be treated, these being
+
+    'estimate'
+          This specifies that no run-time measurement of the optimal means of calculating a particular is performed, and a simple heuristic is used to pick a (probably sub-optimal) plan.  The advantage of this method is that there is little or no overhead in the generation of the plan, which is appropriate for a Fourier transform that will be calculated once.
+
+    'measure'
+          In this case a range of algorithms to perform the transform is considered and the best is selected based on their execution time.
+
+    'patient'
+          This is like 'measure', but a wider range of algorithms is considered.
+
+    'exhaustive'
+          This is like 'measure', but all possible algorithms that may be used to treat the transform are considered.
+
+    'hybrid'
+          As run-time measurement of the algorithm can be expensive, this is a compromise where 'measure' is used for transforms up to the size of 8192 and beyond that the 'estimate' method is used.
+
+     The default method is 'estimate', and the method currently being used can be probed with
+
+          METHOD = fftw ('planner')
+
+     and the method used can be set using
+
+          fftw ('planner', METHOD)
+
+     Note that calculated wisdom will be lost when restarting Octave.  However, the wisdom data can be reloaded if it is saved to a file as described above.  Saved wisdom files should not be used on different platforms since they will not be efficient and the point of calculating the wisdom is lost.  See also: fft, ifft, fft2, ifft2, fftn, ifftn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+Manage FFTW wisdom data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fclose
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 166
+ -- Built-in Function:  fclose (FID)
+     Closes the specified file.  If successful, `fclose' returns 0, otherwise, it returns -1.  See also: fopen, fseek, ftell.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Closes the specified file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fclear
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+ -- Built-in Function:  fclear (FID)
+     Clear the stream state for the specified file.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Clear the stream state for the specified file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fflush
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 390
+ -- Built-in Function:  fflush (FID)
+     Flush output to FID.  This is useful for ensuring that all pending output makes it to the screen before some other event occurs.  For example, it is always a good idea to flush the standard output stream before calling `input'.
+
+     `fflush' returns 0 on success and an OS dependent error value (-1 on unix) on error.  See also: fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+Flush output to FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fgetl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 401
+ -- Built-in Function:  fgetl (FID, LEN)
+     Read characters from a file, stopping after a newline, or EOF, or LEN characters have been read.  The characters read, excluding the possible trailing newline, are returned as a string.
+
+     If LEN is omitted, `fgetl' reads until the next newline character.
+
+     If there are no more characters to read, `fgetl' returns -1.  See also: fread, fscanf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+Read characters from a file, stopping after a newline, or EOF, or LEN characters have been read.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fgets
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 415
+ -- Built-in Function:  fgets (FID, LEN)
+     Read characters from a file, stopping after a newline, or EOF, or LEN characters have been read.  The characters read, including the possible trailing newline, are returned as a string.
+
+     If LEN is omitted, `fgets' reads until the next newline character.
+
+     If there are no more characters to read, `fgets' returns -1.  See also: fputs, fopen, fread, fscanf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+Read characters from a file, stopping after a newline, or EOF, or LEN characters have been read.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fopen
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3128
+ -- Built-in Function: [FID, MSG] = fopen (NAME, MODE, ARCH)
+ -- Built-in Function: FID_LIST = fopen ("all")
+ -- Built-in Function: [FILE, MODE, ARCH] = fopen (FID)
+     The first form of the `fopen' function opens the named file with the specified mode (read-write, read-only, etc.) and architecture interpretation (IEEE big endian, IEEE little endian, etc.), and returns an integer value that may be used to refer to the file later.  If an error occurs, FID is set to -1 and MSG contains the corresponding system error message.  The MODE is a one or two character string that specifies whether the file is to be opened for reading, writing, or both.
+
+     The second form of the `fopen' function returns a vector of file ids corresponding to all the currently open files, excluding the `stdin', `stdout', and `stderr' streams.
+
+     The third form of the `fopen' function returns information about the open file given its file id.
+
+     For example,
+
+          myfile = fopen ("splat.dat", "r", "ieee-le");
+
+     opens the file `splat.dat' for reading.  If necessary, binary numeric values will be read assuming they are stored in IEEE format with the least significant bit first, and then converted to the native representation.
+
+     Opening a file that is already open simply opens it again and returns a separate file id.  It is not an error to open a file several times, though writing to the same file through several different file ids may produce unexpected results.
+
+     The possible values `mode' may have are
+
+    `r'
+          Open a file for reading.
+
+    `w'
+          Open a file for writing.  The previous contents are discarded.
+
+    `a'
+          Open or create a file for writing at the end of the file.
+
+    `r+'
+          Open an existing file for reading and writing.
+
+    `w+'
+          Open a file for reading or writing.  The previous contents are discarded.
+
+    `a+'
+          Open or create a file for reading or writing at the end of the file.
+
+     Append a "t" to the mode string to open the file in text mode or a "b" to open in binary mode.  On Windows and Macintosh systems, text mode reading and writing automatically converts linefeeds to the appropriate line end character for the system (carriage-return linefeed on Windows, carriage-return on Macintosh).  The default if no mode is specified is binary mode.
+
+     Additionally, you may append a "z" to the mode string to open a gzipped file for reading or writing.  For this to be successful, you must also open the file in binary mode.
+
+     The parameter ARCH is a string specifying the default data format for the file.  Valid values for ARCH are:
+
+          `native' The format of the current machine (this is the default).
+
+          `ieee-be' IEEE big endian format.
+
+          `ieee-le' IEEE little endian format.
+
+          `vaxd' VAX D floating format.
+
+          `vaxg' VAX G floating format.
+
+          `cray' Cray floating format.
+
+     however, conversions are currently only supported for `native' `ieee-be', and `ieee-le' formats.  See also: fclose, fgets, fputs, fread, fseek, ferror, fprintf, fscanf, ftell, fwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+The first form of the `fopen' function opens the named file with the specified mode (read-write, read-only, etc.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+freport
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 395
+ -- Built-in Function:  freport ()
+     Print a list of which files have been opened, and whether they are open for reading, writing, or both.  For example,
+
+          freport ()
+
+               -|  number  mode  name
+               -|
+               -|       0     r  stdin
+               -|       1     w  stdout
+               -|       2     w  stderr
+               -|       3     r  myfile
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+Print a list of which files have been opened, and whether they are open for reading, writing, or both.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+frewind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 212
+ -- Built-in Function:  frewind (FID)
+     Move the file pointer to the beginning of the file FID, returning 0 for success, and -1 if an error was encountered.  It is equivalent to `fseek (FID, 0, SEEK_SET)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 116
+Move the file pointer to the beginning of the file FID, returning 0 for success, and -1 if an error was encountered.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fseek
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 569
+ -- Built-in Function:  fseek (FID, OFFSET, ORIGIN)
+     Set the file pointer to any location within the file FID.
+
+     The pointer is positioned OFFSET characters from the ORIGIN, which may be one of the predefined variables `SEEK_CUR' (current position), `SEEK_SET' (beginning), or `SEEK_END' (end of file) or strings "cof", "bof" or "eof".  If ORIGIN is omitted, `SEEK_SET' is assumed.  The offset must be zero, or a value returned by `ftell' (in which case ORIGIN must be `SEEK_SET').
+
+     Return 0 on success and -1 on error.  See also: ftell, fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Set the file pointer to any location within the file FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ftell
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 181
+ -- Built-in Function:  ftell (FID)
+     Return the position of the file pointer as the number of characters from the beginning of the file FID.  See also: fseek, fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+Return the position of the file pointer as the number of characters from the beginning of the file FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+fprintf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 284
+ -- Built-in Function:  fprintf (FID, TEMPLATE, ...)
+     This function is just like `printf', except that the output is written to the stream FID instead of `stdout'.  If FID is omitted, the output is written to `stdout'.  See also: printf, sprintf, fread, fscanf, fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+This function is just like `printf', except that the output is written to the stream FID instead of `stdout'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+printf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 363
+ -- Built-in Function:  printf (TEMPLATE, ...)
+     Print optional arguments under the control of the template string TEMPLATE to the stream `stdout' and return the number of characters printed.
+
+     See the Formatted Output section of the GNU Octave manual for a complete description of the syntax of the template string.  See also: fprintf, sprintf, scanf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 142
+Print optional arguments under the control of the template string TEMPLATE to the stream `stdout' and return the number of characters printed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fputs
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 218
+ -- Built-in Function:  fputs (FID, STRING)
+     Write a string to a file with no formatting.
+
+     Return a non-negative number on success and EOF on error.  See also: scanf, sscanf, fread, fprintf, fgets, fscanf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Write a string to a file with no formatting.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+puts
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+ -- Built-in Function:  puts (STRING)
+     Write a string to the standard output with no formatting.
+
+     Return a non-negative number on success and EOF on error.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Write a string to the standard output with no formatting.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+sprintf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 369
+ -- Built-in Function:  sprintf (TEMPLATE, ...)
+     This is like `printf', except that the output is returned as a string.  Unlike the C library function, which requires you to provide a suitably sized string as an argument, Octave's `sprintf' function returns the string, automatically sized to hold all of the items converted.  See also: printf, fprintf, sscanf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+This is like `printf', except that the output is returned as a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fscanf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1535
+ -- Built-in Function: [VAL, COUNT] = fscanf (FID, TEMPLATE, SIZE)
+ -- Built-in Function: [V1, V2, ..., COUNT] = fscanf (FID, TEMPLATE, "C")
+     In the first form, read from FID according to TEMPLATE, returning the result in the matrix VAL.
+
+     The optional argument SIZE specifies the amount of data to read and may be one of
+
+    `Inf'
+          Read as much as possible, returning a column vector.
+
+    `NR'
+          Read up to NR elements, returning a column vector.
+
+    `[NR, Inf]'
+          Read as much as possible, returning a matrix with NR rows.  If the number of elements read is not an exact multiple of NR, the last column is padded with zeros.
+
+    `[NR, NC]'
+          Read up to `NR * NC' elements, returning a matrix with NR rows.  If the number of elements read is not an exact multiple of NR, the last column is padded with zeros.
+
+     If SIZE is omitted, a value of `Inf' is assumed.
+
+     A string is returned if TEMPLATE specifies only character conversions.
+
+     The number of items successfully read is returned in COUNT.
+
+     In the second form, read from FID according to TEMPLATE, with each conversion specifier in TEMPLATE corresponding to a single scalar return value.  This form is more `C-like', and also compatible with previous versions of Octave.  The number of successful conversions is returned in COUNT
+
+     See the Formatted Input section of the GNU Octave manual for a complete description of the syntax of the template string.  See also: scanf, sscanf, fread, fprintf, fgets, fputs.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+In the first form, read from FID according to TEMPLATE, returning the result in the matrix VAL.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sscanf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 371
+ -- Built-in Function: [VAL, COUNT] = sscanf (STRING, TEMPLATE, SIZE)
+ -- Built-in Function: [V1, V2, ..., COUNT] = sscanf (STRING, TEMPLATE, "C")
+     This is like `fscanf', except that the characters are taken from the string STRING instead of from a stream.  Reaching the end of the string is treated as an end-of-file condition.  See also: fscanf, scanf, sprintf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+This is like `fscanf', except that the characters are taken from the string STRING instead of from a stream.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+scanf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 306
+ -- Built-in Function: [VAL, COUNT] = scanf (TEMPLATE, SIZE)
+ -- Built-in Function: [V1, V2, ..., COUNT]] = scanf (TEMPLATE, "C")
+     This is equivalent to calling `fscanf' with FID = `stdin'.
+
+     It is currently not useful to call `scanf' in interactive programs.  See also: fscanf, sscanf, printf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+This is equivalent to calling `fscanf' with FID = `stdin'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fread
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4231
+ -- Built-in Function: [VAL, COUNT] = fread (FID, SIZE, PRECISION, SKIP, ARCH)
+     Read binary data of type PRECISION from the specified file ID FID.
+
+     The optional argument SIZE specifies the amount of data to read and may be one of
+
+    `Inf'
+          Read as much as possible, returning a column vector.
+
+    `NR'
+          Read up to NR elements, returning a column vector.
+
+    `[NR, Inf]'
+          Read as much as possible, returning a matrix with NR rows.  If the number of elements read is not an exact multiple of NR, the last column is padded with zeros.
+
+    `[NR, NC]'
+          Read up to `NR * NC' elements, returning a matrix with NR rows.  If the number of elements read is not an exact multiple of NR, the last column is padded with zeros.
+
+     If SIZE is omitted, a value of `Inf' is assumed.
+
+     The optional argument PRECISION is a string specifying the type of data to read and may be one of
+
+    `"schar"'
+    `"signed char"'
+          Signed character.
+
+    `"uchar"'
+    `"unsigned char"'
+          Unsigned character.
+
+    `"int8"'
+    `"integer*1"'
+          8-bit signed integer.
+
+    `"int16"'
+    `"integer*2"'
+          16-bit signed integer.
+
+    `"int32"'
+    `"integer*4"'
+          32-bit signed integer.
+
+    `"int64"'
+    `"integer*8"'
+          64-bit signed integer.
+
+    `"uint8"'
+          8-bit unsigned integer.
+
+    `"uint16"'
+          16-bit unsigned integer.
+
+    `"uint32"'
+          32-bit unsigned integer.
+
+    `"uint64"'
+          64-bit unsigned integer.
+
+    `"single"'
+    `"float32"'
+    `"real*4"'
+          32-bit floating point number.
+
+    `"double"'
+    `"float64"'
+    `"real*8"'
+          64-bit floating point number.
+
+    `"char"'
+    `"char*1"'
+          Single character.
+
+    `"short"'
+          Short integer (size is platform dependent).
+
+    `"int"'
+          Integer (size is platform dependent).
+
+    `"long"'
+          Long integer (size is platform dependent).
+
+    `"ushort"'
+    `"unsigned short"'
+          Unsigned short integer (size is platform dependent).
+
+    `"uint"'
+    `"unsigned int"'
+          Unsigned integer (size is platform dependent).
+
+    `"ulong"'
+    `"unsigned long"'
+          Unsigned long integer (size is platform dependent).
+
+    `"float"'
+          Single precision floating point number (size is platform dependent).
+
+     The default precision is `"uchar"'.
+
+     The PRECISION argument may also specify an optional repeat count.  For example, `32*single' causes `fread' to read a block of 32 single precision floating point numbers.  Reading in blocks is useful in combination with the SKIP argument.
+
+     The PRECISION argument may also specify a type conversion.  For example, `int16=>int32' causes `fread' to read 16-bit integer values and return an array of 32-bit integer values.  By default, `fread' returns a double precision array.  The special form `*TYPE' is shorthand for `TYPE=>TYPE'.
+
+     The conversion and repeat counts may be combined.  For example, the specification `32*single=>single' causes `fread' to read blocks of single precision floating point values and return an array of single precision values instead of the default array of double precision values.
+
+     The optional argument SKIP specifies the number of bytes to skip after each element (or block of elements) is read.  If it is not specified, a value of 0 is assumed.  If the final block read is not complete, the final skip is omitted.  For example,
+
+          fread (f, 10, "3*single=>single", 8)
+
+     will omit the final 8-byte skip because the last read will not be a complete block of 3 values.
+
+     The optional argument ARCH is a string specifying the data format for the file.  Valid values are
+
+    `"native"'
+          The format of the current machine.
+
+    `"ieee-be"'
+          IEEE big endian.
+
+    `"ieee-le"'
+          IEEE little endian.
+
+    `"vaxd"'
+          VAX D floating format.
+
+    `"vaxg"'
+          VAX G floating format.
+
+    `"cray"'
+          Cray floating format.
+
+     Conversions are currently only supported for `"ieee-be"' and `"ieee-le"' formats.
+
+     The data read from the file is returned in VAL, and the number of values read is returned in `count' See also: fwrite, fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Read binary data of type PRECISION from the specified file ID FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fwrite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 615
+ -- Built-in Function: COUNT = fwrite (FID, DATA, PRECISION, SKIP, ARCH)
+     Write data in binary form of type PRECISION to the specified file ID FID, returning the number of values successfully written to the file.
+
+     The argument DATA is a matrix of values that are to be written to the file.  The values are extracted in column-major order.
+
+     The remaining arguments PRECISION, SKIP, and ARCH are optional, and are interpreted as described for `fread'.
+
+     The behavior of `fwrite' is undefined if the values in DATA are too large to fit in the specified precision.  See also: fread, fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+Write data in binary form of type PRECISION to the specified file ID FID, returning the number of values successfully written to the file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+feof
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 326
+ -- Built-in Function:  feof (FID)
+     Return 1 if an end-of-file condition has been encountered for a given file and 0 otherwise.  Note that it will only return 1 if the end of the file has already been encountered, not if the next read operation will result in an end-of-file condition.  See also: fread, fopen, fclose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+Return 1 if an end-of-file condition has been encountered for a given file and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ferror
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 267
+ -- Built-in Function:  ferror (FID)
+     Return 1 if an error condition has been encountered for a given file and 0 otherwise.  Note that it will only return 1 if an error has already been encountered, not if the next operation will result in an error condition.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+Return 1 if an error condition has been encountered for a given file and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+popen
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 853
+ -- Built-in Function: FID = popen (COMMAND, MODE)
+     Start a process and create a pipe.  The name of the command to run is given by COMMAND.  The file identifier corresponding to the input or output stream of the process is returned in FID.  The argument MODE may be
+
+    `"r"'
+          The pipe will be connected to the standard output of the process, and open for reading.
+
+    `"w"'
+          The pipe will be connected to the standard input of the process, and open for writing.
+
+     For example,
+
+          fid = popen ("ls -ltr / | tail -3", "r");
+          while (ischar (s = fgets (fid)))
+            fputs (stdout, s);
+          endwhile
+               -| drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc
+               -| drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib
+               -| drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Start a process and create a pipe.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+pclose
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+ -- Built-in Function:  pclose (FID)
+     Close a file identifier that was opened by `popen'.  You may also use `fclose' for the same purpose.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Close a file identifier that was opened by `popen'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+tmpnam
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 541
+ -- Built-in Function:  tmpnam (DIR, PREFIX)
+     Return a unique temporary file name as a string.
+
+     If PREFIX is omitted, a value of `"oct-"' is used.  If DIR is also omitted, the default directory for temporary files is used.  If DIR is provided, it must exist, otherwise the default directory for temporary files is used.  Since the named file is not opened, by `tmpnam', it is possible (though relatively unlikely) that it will not be available by the time your program attempts to open it.  See also: tmpfile, mkstemp, P_tmpdir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return a unique temporary file name as a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+tmpfile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 452
+ -- Built-in Function: [FID, MSG] = tmpfile ()
+     Return the file ID corresponding to a new temporary file with a unique name.  The file is opened in binary read/write (`"w+b"') mode.  The file will be deleted automatically when it is closed or when Octave exits.
+
+     If successful, FID is a valid file ID and MSG is an empty string.  Otherwise, FID is -1 and MSG contains a system-dependent error message.  See also: tmpnam, mkstemp, P_tmpdir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Return the file ID corresponding to a new temporary file with a unique name.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+mkstemp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 925
+ -- Built-in Function: [FID, NAME, MSG] = mkstemp (TEMPLATE, DELETE)
+     Return the file ID corresponding to a new temporary file with a unique name created from TEMPLATE.  The last six characters of TEMPLATE must be `XXXXXX' and these are replaced with a string that makes the filename unique.  The file is then created with mode read/write and permissions that are system dependent (on GNU/Linux systems, the permissions will be 0600 for versions of glibc 2.0.7 and later).  The file is opened with the `O_EXCL' flag.
+
+     If the optional argument DELETE is supplied and is true, the file will be deleted automatically when Octave exits, or when the function `purge_tmp_files' is called.
+
+     If successful, FID is a valid file ID, NAME is the name of the file, and MSG is an empty string.  Otherwise, FID is -1, NAME is empty, and MSG contains a system-dependent error message.  See also: tmpfile, tmpnam, P_tmpdir.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Return the file ID corresponding to a new temporary file with a unique name created from TEMPLATE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+umask
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 303
+ -- Built-in Function:  umask (MASK)
+     Set the permission mask for file creation.  The parameter MASK is an integer, interpreted as an octal number.  If successful, returns the previous value of the mask (as an integer to be interpreted as an octal number); otherwise an error message is printed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Set the permission mask for file creation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+P_tmpdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 170
+ -- Built-in Function:  P_tmpdir ()
+     Return the default name of the directory for temporary files on this system.  The name of this directory is system dependent.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Return the default name of the directory for temporary files on this system.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+SEEK_SET
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 402
+ -- Built-in Function:  SEEK_SET ()
+ -- Built-in Function:  SEEK_CUR ()
+ -- Built-in Function:  SEEK_END ()
+     Return the value required to request that `fseek' perform one of the following actions:
+    `SEEK_SET'
+          Position file relative to the beginning.
+
+    `SEEK_CUR'
+          Position file relative to the current position.
+
+    `SEEK_END'
+          Position file relative to the end.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 141
+Return the value required to request that `fseek' perform one of the following actions:  `SEEK_SET'  Position file relative to the beginning.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+SEEK_CUR
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+ -- Built-in Function:  SEEK_CUR ()
+     See SEEK_SET.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+See SEEK_SET.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+SEEK_END
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+ -- Built-in Function:  SEEK_END ()
+     See SEEK_SET.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+See SEEK_SET.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+stdin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 234
+ -- Built-in Function:  stdin ()
+     Return the numeric value corresponding to the standard input stream.  When Octave is used interactively, this is filtered through the command line editing functions.  See also: stdout, stderr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Return the numeric value corresponding to the standard input stream.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+stdout
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 215
+ -- Built-in Function:  stdout ()
+     Return the numeric value corresponding to the standard output stream.  Data written to the standard output is normally filtered through the pager.  See also: stdin, stderr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Return the numeric value corresponding to the standard output stream.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+stderr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 258
+ -- Built-in Function:  stderr ()
+     Return the numeric value corresponding to the standard error stream.  Even if paging is turned on, the standard error is not sent to the pager.  It is useful for error messages and prompts.  See also: stdin, stdout.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Return the numeric value corresponding to the standard error stream.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+filter
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1530
+ -- Loadable Function: y = filter (B, A, X)
+ -- Loadable Function: [Y, SF] = filter (B, A, X, SI)
+ -- Loadable Function: [Y, SF] = filter (B, A, X, [], DIM)
+ -- Loadable Function: [Y, SF] = filter (B, A, X, SI, DIM)
+     Return the solution to the following linear, time-invariant difference equation:
+
+             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.  over the first non-singleton dimension of X or over DIM if supplied.  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.
+
+     In terms of the z-transform, y is the result of passing the discrete- time signal x through a system characterized by the following rational system function:
+
+                       M
+                      SUM d(k+1) z^(-k)
+                      k=0
+            H(z) = ----------------------
+                         N
+                    1 + SUM c(k+1) z^(-k)
+                        k=1
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+Return the solution to the following linear, time-invariant difference equation: 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+find
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1566
+ -- Loadable Function:  find (X)
+ -- Loadable Function:  find (X, N)
+ -- Loadable Function:  find (X, N, DIRECTION)
+     Return a vector of indices of nonzero elements of a matrix, as a row if X is a row or as a column otherwise.  To obtain a single index for each matrix element, Octave pretends that the columns of a matrix form one long vector (like Fortran arrays are stored).  For example,
+
+          find (eye (2))
+               => [ 1; 4 ]
+
+     If two outputs are requested, `find' returns the row and column indices of nonzero elements of a matrix.  For example,
+
+          [i, j] = find (2 * eye (2))
+               => i = [ 1; 2 ]
+               => j = [ 1; 2 ]
+
+     If three outputs are requested, `find' also returns a vector containing the nonzero values.  For example,
+
+          [i, j, v] = find (3 * eye (2))
+               => i = [ 1; 2 ]
+               => j = [ 1; 2 ]
+               => v = [ 3; 3 ]
+
+     If two inputs are given, N indicates the maximum number of elements to find from the beginning of the matrix or vector.
+
+     If three inputs are given, DIRECTION should be one of "first" or "last", requesting only the first or last N indices, respectively.  However, the indices are always returned in ascending order.
+
+     Note that this function is particularly useful for sparse matrices, as it extracts the non-zero elements as vectors, which can then be used to create the original matrix.  For example,
+
+          sz = size(a);
+          [i, j, v] = find (a);
+          b = sparse(i, j, v, sz(1), sz(2));
+     See also: sparse.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Return a vector of indices of nonzero elements of a matrix, as a row if X is a row or as a column otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+gammainc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 699
+ -- Mapping Function:  gammainc (X, A)
+     Compute the normalized incomplete gamma function,
+
+                                          x
+                                1        /
+          gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
+                            gamma (a)    /
+                                      t=0
+
+     with the limiting value of 1 as X approaches infinity.  The standard notation is P(a,x), e.g., Abramowitz and Stegun (6.5.1).
+
+     If A is scalar, then `gammainc (X, A)' is returned for each element of X and vice versa.
+
+     If neither X nor A is scalar, the sizes of X and A must agree, and GAMMAINC is applied element-by-element.  See also: gamma, lgamma.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Compute the normalized incomplete gamma function, 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+gcd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 864
+ -- Loadable Function: G = gcd (A)
+ -- Loadable Function: G = gcd (A1, A2, ...)
+ -- Loadable Function: [G, V1, ...] = gcd (A1, A2, ...)
+     Compute the greatest common divisor of the elements of A.  If more than one argument is given all arguments must be the same size or scalar.    In this case the greatest common divisor is calculated for each element individually.  All elements must be integers.  For example,
+
+          gcd ([15, 20])
+              =>  5
+
+     and
+
+          gcd ([15, 9], [20, 18])
+              =>  5  9
+
+     Optional return arguments V1, etc., contain integer vectors such that,
+
+          G = V1 .* A1 + V2 .* A2 + ...
+
+     For backward compatibility with previous versions of this function, when all arguments are scalar, a single return argument V1 containing all of the values of V1, ... is acceptable.  See also: lcm, factor.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Compute the greatest common divisor of the elements of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getgrent
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 188
+ -- Loadable Function: GRP_STRUCT = getgrent ()
+     Return an entry from the group database, opening it if necessary.  Once the end of the data has been reached, `getgrent' returns 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Return an entry from the group database, opening it if necessary.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getgrgid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 201
+ -- Loadable Function: GRP_STRUCT = getgrgid (GID).
+     Return the first entry from the group database with the group ID GID.  If the group ID does not exist in the database, `getgrgid' returns 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Return the first entry from the group database with the group ID GID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getgrnam
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 206
+ -- Loadable Function: GRP_STRUCT = getgrnam (NAME)
+     Return the first entry from the group database with the group name NAME.  If the group name does not exist in the database, `getgrnam' returns 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Return the first entry from the group database with the group name NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+setgrent
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+ -- Loadable Function:  setgrent ()
+     Return the internal pointer to the beginning of the group database.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Return the internal pointer to the beginning of the group database.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+endgrent
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+ -- Loadable Function:  endgrent ()
+     Close the group database.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+Close the group database.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getpwent
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 213
+ -- Loadable Function: PW_STRUCT = getpwent ()
+     Return a structure containing an entry from the password database, opening it if necessary.  Once the end of the data has been reached, `getpwent' returns 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+Return a structure containing an entry from the password database, opening it if necessary.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getpwuid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 224
+ -- Loadable Function: PW_STRUCT = getpwuid (UID).
+     Return a structure containing the first entry from the password database with the user ID UID.  If the user ID does not exist in the database, `getpwuid' returns 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+Return a structure containing the first entry from the password database with the user ID UID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getpwnam
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 230
+ -- Loadable Function: PW_STRUCT = getpwnam (NAME)
+     Return a structure containing the first entry from the password database with the user name NAME.  If the user name does not exist in the database, `getpwname' returns 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Return a structure containing the first entry from the password database with the user name NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+setpwent
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+ -- Loadable Function:  setpwent ()
+     Return the internal pointer to the beginning of the password database.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Return the internal pointer to the beginning of the password database.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+endpwent
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+ -- Loadable Function:  endpwent ()
+     Close the password database.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 28
+Close the password database.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+getrusage
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1411
+ -- Loadable Function:  getrusage ()
+     Return a structure containing a number of statistics about the current Octave process.  Not all fields are available on all systems.  If it is not possible to get CPU time statistics, the CPU time slots are set to zero.  Other missing data are replaced by NaN.  Here is a list of all the possible fields that can be present in the structure returned by `getrusage':
+
+    `idrss'
+          Unshared data size.
+
+    `inblock'
+          Number of block input operations.
+
+    `isrss'
+          Unshared stack size.
+
+    `ixrss'
+          Shared memory size.
+
+    `majflt'
+          Number of major page faults.
+
+    `maxrss'
+          Maximum data size.
+
+    `minflt'
+          Number of minor page faults.
+
+    `msgrcv'
+          Number of messages received.
+
+    `msgsnd'
+          Number of messages sent.
+
+    `nivcsw'
+          Number of involuntary context switches.
+
+    `nsignals'
+          Number of signals received.
+
+    `nswap'
+          Number of swaps.
+
+    `nvcsw'
+          Number of voluntary context switches.
+
+    `oublock'
+          Number of block output operations.
+
+    `stime'
+          A structure containing the system CPU time used.  The structure has the elements `sec' (seconds) `usec' (microseconds).
+
+    `utime'
+          A structure containing the user CPU time used.  The structure has the elements `sec' (seconds) `usec' (microseconds).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Return a structure containing a number of statistics about the current Octave process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+givens
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 317
+ -- Loadable Function: G = givens (X, Y)
+ -- Loadable Function: [C, S] = givens (X, Y)
+     Return a 2 by 2 orthogonal matrix `G = [C S; -S' C]' such that `G [X; Y] = [*; 0]' with X and Y scalars.
+
+     For example,
+
+          givens (1, 1)
+               =>   0.70711   0.70711
+                   -0.70711   0.70711
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+Return a 2 by 2 orthogonal matrix `G = [C S; -S' C]' such that `G [X; Y] = [*; 0]' with X and Y scalars.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ishandle
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+ -- Built-in Function:  ishandle (H)
+     Return true if H is a graphics handle and false otherwise.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Return true if H is a graphics handle and false otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+set
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+ -- Built-in Function:  set (H, P, V, ...)
+     Set the named property value or vector P to the value V for the graphics handle H.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+Set the named property value or vector P to the value V for the graphics handle H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+get
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 250
+ -- Built-in Function:  get (H, P)
+     Return the named property P from the graphics handle H.  If P is omitted, return the complete property list for H.  If H is a vector, return a cell array including the property values or lists respectively.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return the named property P from the graphics handle H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+available_backends
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+ -- Built-in Function:  available_backends ()
+     Return a cell array of registered graphics backends.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return a cell array of registered graphics backends.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+drawnow
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 457
+ -- Built-in Function:  drawnow ()
+ -- Built-in Function:  drawnow ("expose")
+ -- Built-in Function:  drawnow (TERM, FILE, MONO, DEBUG_FILE)
+     Update figure windows and their children.  The event queue is flushed and any callbacks generated are executed.  With the optional argument `"expose"', only graphic objects are updated and no other events or callbacks are processed.  The third calling form of `drawnow' is for debugging and is undocumented.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Update figure windows and their children.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+addlistener
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1093
+ -- Built-in Function:  addlistener (H, PROP, FCN)
+     Register FCN as listener for the property PROP of the graphics object H.  Property listeners are executed (in order of registration) when the property is set.  The new value is already available when the listeners are executed.
+
+     PROP must be a string naming a valid property in H.
+
+     FCN can be a function handle, a string or a cell array whose first element is a function handle.  If FCN is a function handle, the corresponding function should accept at least 2 arguments, that will be set to the object handle and the empty matrix respectively.  If FCN is a string, it must be any valid octave expression.  If FCN is a cell array, the first element must be a function handle with the same signature as described above.  The next elements of the cell array are passed as additional arguments to the function.
+
+     Example:
+
+          function my_listener (h, dummy, p1)
+            fprintf ("my_listener called with p1=%s\n", p1);
+          endfunction
+
+          addlistener (gcf, "position", {@my_listener, "my string"})
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Register FCN as listener for the property PROP of the graphics object H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+dellistener
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 631
+ -- Built-in Function:  dellistener (H, PROP, FCN)
+     Remove the registration of FCN as a listener for the property PROP of the graphics object H.  The function FCN must be the same variable (not just the same value), as was passed to the original call to `addlistener'.
+
+     If FCN is not defined then all listener functions of PROP are removed.
+
+     Example:
+
+          function my_listener (h, dummy, p1)
+            fprintf ("my_listener called with p1=%s\n", p1);
+          endfunction
+
+          c = {@my_listener, "my string"};
+          addlistener (gcf, "position", c);
+          dellistener (gcf, "position", c);
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Remove the registration of FCN as a listener for the property PROP of the graphics object H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+addproperty
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2346
+ -- Built-in Function:  addproperty (NAME, H, TYPE, [ARG, ...])
+     Create a new property named NAME in graphics object H.  TYPE determines the type of the property to create.  ARGS usually contains the default value of the property, but additional arguments might be given, depending on the type of the property.
+
+     The supported property types are:
+
+    `string'
+          A string property.  ARG contains the default string value.
+
+    `any'
+          An un-typed property.  This kind of property can hold any octave value.  ARGS contains the default value.
+
+    `radio'
+          A string property with a limited set of accepted values.  The first argument must be a string with all accepted values separated by a vertical bar ('|').  The default value can be marked by enclosing it with a '{' '}' pair.  The default value may also be given as an optional second string argument.
+
+    `boolean'
+          A boolean property.  This property type is equivalent to a radio property with "on|off" as accepted values.  ARG contains the default property value.
+
+    `double'
+          A scalar double property.  ARG contains the default value.
+
+    `handle'
+          A handle property.  This kind of property holds the handle of a graphics object.  ARG contains the default handle value.  When no default value is given, the property is initialized to the empty matrix.
+
+    `data'
+          A data (matrix) property.  ARG contains the default data value.  When no default value is given, the data is initialized to the empty matrix.
+
+    `color'
+          A color property.  ARG contains the default color value.  When no default color is given, the property is set to black.  An optional second string argument may be given to specify an additional set of accepted string values (like a radio property).
+
+     TYPE may also be the concatenation of a core object type and a valid property name for that object type.  The property created then has the same characteristics as the referenced property (type, possible values, hidden state...).  This allows to clone an existing property into the graphics object H.
+
+     Examples:
+
+          addproperty ("my_property", gcf, "string", "a string value");
+          addproperty ("my_radio", gcf, "radio", "val_1|val_2|{val_3}");
+          addproperty ("my_style", gcf, "linelinestyle", "--");
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Create a new property named NAME in graphics object H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+get_help_text
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 419
+ -- Loadable Function: [TEXT, FORMAT] = get_help_text (NAME)
+     Returns the help text of a given function.
+
+     This function returns the raw help text TEXT and an indication of its format for the function NAME.  The format indication FORMAT is a string that can be either "texinfo", "html", or "plain text".
+
+     To convert the help text to other formats, use the `makeinfo' function.
+
+     See also: makeinfo.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Returns the help text of a given function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+doc_cache_file
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 683
+ -- Built-in Function: VAL = doc_cache_file ()
+ -- Built-in Function: OLD_VAL = doc_cache_file (NEW_VAL)
+     Query or set the internal variable that specifies the name of the Octave documentation cache file.  A cache file significantly improves the performance of the `lookfor' command.  The default value is `OCTAVE-HOME/share/octave/VERSION/etc/doc-cache', in which OCTAVE-HOME is the root directory of the Octave installation, and VERSION is the Octave version number.  The default value may be overridden by the environment variable `OCTAVE_DOC_CACHE_FILE', or the command line argument `--doc-cache-file NAME'.  See also: lookfor, info_program, doc, help, makeinfo_program.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Query or set the internal variable that specifies the name of the Octave documentation cache file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+info_file
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 500
+ -- Built-in Function: VAL = info_file ()
+ -- Built-in Function: OLD_VAL = info_file (NEW_VAL)
+     Query or set the internal variable that specifies the name of the Octave info file.  The default value is `OCTAVE-HOME/info/octave.info', in which OCTAVE-HOME is the root directory of the Octave installation.  The default value may be overridden by the environment variable `OCTAVE_INFO_FILE', or the command line argument `--info-file NAME'.  See also: info_program, doc, help, makeinfo_program.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Query or set the internal variable that specifies the name of the Octave info file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+info_program
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 634
+ -- Built-in Function: VAL = info_program ()
+ -- Built-in Function: OLD_VAL = info_program (NEW_VAL)
+     Query or set the internal variable that specifies the name of the info program to run.  The default value is `OCTAVE-HOME/libexec/octave/VERSION/exec/ARCH/info' in which OCTAVE-HOME is the root directory of the Octave installation, VERSION is the Octave version number, and ARCH is the system type (for example, `i686-pc-linux-gnu').  The default value may be overridden by the environment variable `OCTAVE_INFO_PROGRAM', or the command line argument `--info-program NAME'.  See also: info_file, doc, help, makeinfo_program.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Query or set the internal variable that specifies the name of the info program to run.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+makeinfo_program
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 345
+ -- Built-in Function: VAL = makeinfo_program ()
+ -- Built-in Function: OLD_VAL = makeinfo_program (NEW_VAL)
+     Query or set the internal variable that specifies the name of the program that Octave runs to format help text containing Texinfo markup commands.  The default value is `makeinfo'.  See also: info_file, info_program, doc, help.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+Query or set the internal variable that specifies the name of the program that Octave runs to format help text containing Texinfo markup commands.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+suppress_verbose_help_message
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 335
+ -- Built-in Function: VAL = suppress_verbose_help_message ()
+ -- Built-in Function: OLD_VAL = suppress_verbose_help_message (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will add additional help information to the end of the output from the `help' command and usage messages for built-in commands.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 191
+Query or set the internal variable that controls whether Octave will add additional help information to the end of the output from the `help' command and usage messages for built-in commands.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+hess
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 551
+ -- Loadable Function: H = hess (A)
+ -- Loadable Function: [P, H] = hess (A)
+     Compute the Hessenberg decomposition of the matrix A.
+
+     The Hessenberg decomposition is usually used as the first step in an eigenvalue computation, but has other applications as well (see Golub, Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).  The Hessenberg decomposition is `p * h * p' = a' where `p' is a square unitary matrix (`p' * p = I', using complex-conjugate transposition) and `h' is upper Hessenberg (`i >= j+1 => h (i, j) = 0').
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compute the Hessenberg decomposition of the matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hex2num
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 441
+ -- Loadable Function: N = hex2num (S)
+     Typecast the 16 character hexadecimal character matrix to an IEEE 754 double precision number.  If fewer than 16 characters are given the strings are right padded with '0' characters.
+
+     Given a string matrix, `hex2num' treats each row as a separate number.
+
+          hex2num (["4005bf0a8b145769";"4024000000000000"])
+          => [2.7183; 10.000]
+     See also: num2hex, hex2dec, dec2hex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+Typecast the 16 character hexadecimal character matrix to an IEEE 754 double precision number.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+num2hex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 464
+ -- Loadable Function: S = num2hex (N)
+     Typecast a double precision number or vector to a 16 character hexadecimal string of the IEEE 754 representation of the number.  For example
+
+          num2hex ([-1, 1, e, Inf, NaN, NA]);
+          => "bff0000000000000
+              3ff0000000000000
+              4005bf0a8b145769
+              7ff0000000000000
+              fff8000000000000
+              7ff00000000007a2"
+     See also: hex2num, hex2dec, dec2hex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+Typecast a double precision number or vector to a 16 character hexadecimal string of the IEEE 754 representation of the number.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+input
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1082
+ -- Built-in Function:  input (PROMPT)
+ -- Built-in Function:  input (PROMPT, "s")
+     Print a prompt and wait for user input.  For example,
+
+          input ("Pick a number, any number! ")
+
+     prints the prompt
+
+          Pick a number, any number!
+
+     and waits for the user to enter a value.  The string entered by the user is evaluated as an expression, so it may be a literal constant, a variable name, or any other valid expression.
+
+     Currently, `input' only returns one value, regardless of the number of values produced by the evaluation of the expression.
+
+     If you are only interested in getting a literal string value, you can call `input' with the character string `"s"' as the second argument.  This tells Octave to return the string entered by the user directly, without evaluating it first.
+
+     Because there may be output waiting to be displayed by the pager, it is a good idea to always call `fflush (stdout)' before calling `input'.  This will ensure that all pending output is written to the screen before your prompt.  *Note Input and Output::.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Print a prompt and wait for user input.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+yes_or_no
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 347
+ -- Built-in Function:  yes_or_no (PROMPT)
+     Ask the user a yes-or-no question.  Return 1 if the answer is yes.  Takes one argument, which is the string to display to ask the question.  It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.  The user must confirm the answer with RET and can edit it until it has been confirmed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Ask the user a yes-or-no question.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+keyboard
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 667
+ -- Built-in Function:  keyboard ()
+ -- Built-in Function:  keyboard (PROMPT)
+     This function is normally used for simple debugging.  When the `keyboard' function is executed, Octave prints a prompt and waits for user input.  The input strings are then evaluated and the results are printed.  This makes it possible to examine the values of variables within a function, and to assign new values if necessary.  To leave the prompt and return to normal execution type `return' or `dbcont'.  The `keyboard' function does not return an exit status.
+
+     If `keyboard' is invoked without arguments, a default prompt of `debug> ' is used.  See also: dbcont, dbquit.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+This function is normally used for simple debugging.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+echo
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 559
+ -- Command: echo options
+     Control whether commands are displayed as they are executed.  Valid options are:
+
+    `on'
+          Enable echoing of commands as they are executed in script files.
+
+    `off'
+          Disable echoing of commands as they are executed in script files.
+
+    `on all'
+          Enable echoing of commands as they are executed in script files and functions.
+
+    `off all'
+          Disable echoing of commands as they are executed in script files and functions.
+
+     With no arguments, `echo' toggles the current echo state.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Control whether commands are displayed as they are executed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+completion_matches
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 338
+ -- Built-in Function:  completion_matches (HINT)
+     Generate possible completions given HINT.
+
+     This function is provided for the benefit of programs like Emacs which might be controlling Octave and handling user input.  The current command number is not incremented when this function is called.  This is a feature, not a bug.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Generate possible completions given HINT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+read_readline_init_file
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 273
+ -- Built-in Function:  read_readline_init_file (FILE)
+     Read the readline library initialization file FILE.  If FILE is omitted, read the default initialization file (normally `~/.inputrc').
+
+     *Note Readline Init File: (readline)Readline Init File, for details.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Read the readline library initialization file FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+re_read_readline_init_file
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 201
+ -- Built-in Function:  re_read_readline_init_file ()
+     Re-read the last readline library initialization file that was read.  *Note Readline Init File: (readline)Readline Init File, for details.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Re-read the last readline library initialization file that was read.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+add_input_event_hook
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 339
+ -- Built-in Function:  add_input_event_hook (FCN, DATA)
+     Add the named function FCN to the list of functions to call periodically when Octave is waiting for input.  The function should have the form
+          FCN (DATA)
+
+     If DATA is omitted, Octave calls the function without any arguments.  See also: remove_input_event_hook.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 106
+Add the named function FCN to the list of functions to call periodically when Octave is waiting for input.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+remove_input_event_hook
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 205
+ -- Built-in Function:  remove_input_event_hook (FCN)
+     Remove the named function FCN to the list of functions to call periodically when Octave is waiting for input.  See also: add_input_event_hook.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Remove the named function FCN to the list of functions to call periodically when Octave is waiting for input.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+PS1
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 632
+ -- Built-in Function: VAL = PS1 ()
+ -- Built-in Function: OLD_VAL = PS1 (NEW_VAL)
+     Query or set the primary prompt string.  When executing interactively, Octave displays the primary prompt when it is ready to read a command.
+
+     The default value of the primary prompt string is `"\s:\#> "'.  To change it, use a command like
+
+          octave:13> PS1 ("\\u@\\H> ")
+
+     which will result in the prompt `boris at kremvax> ' for the user `boris' logged in on the host `kremvax.kgb.su'.  Note that two backslashes are required to enter a backslash into a double-quoted character string.  *Note Strings::.  See also: PS2, PS4.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Query or set the primary prompt string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+PS2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 470
+ -- Built-in Function: VAL = PS2 ()
+ -- Built-in Function: OLD_VAL = PS2 (NEW_VAL)
+     Query or set the secondary prompt string.  The secondary prompt is printed when Octave is expecting additional input to complete a command.  For example, if you are typing a `for' loop that spans several lines, Octave will print the secondary prompt at the beginning of each line after the first.  The default value of the secondary prompt string is `"> "'.  See also: PS1, PS4.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Query or set the secondary prompt string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+PS4
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 345
+ -- Built-in Function: VAL = PS4 ()
+ -- Built-in Function: OLD_VAL = PS4 (NEW_VAL)
+     Query or set the character string used to prefix output produced when echoing commands is enabled.  The default value is `"+ "'.  *Note Diary and Echo Commands::, for a description of echoing commands.  See also: echo, echo_executing_commands, PS1, PS2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Query or set the character string used to prefix output produced when echoing commands is enabled.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+completion_append_char
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 285
+ -- Built-in Function: VAL = completion_append_char ()
+ -- Built-in Function: OLD_VAL = completion_append_char (NEW_VAL)
+     Query or set the internal character variable that is appended to successful command-line completion attempts.  The default value is `" "' (a single space).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Query or set the internal character variable that is appended to successful command-line completion attempts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+echo_executing_commands
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 641
+ -- Built-in Function: VAL = echo_executing_commands ()
+ -- Built-in Function: OLD_VAL = echo_executing_commands (NEW_VAL)
+     Query or set the internal variable that controls the echo state.  It may be the sum of the following values:
+
+    1
+          Echo commands read from script files.
+
+    2
+          Echo commands from functions.
+
+    4
+          Echo commands read from command line.
+
+     More than one state can be active at once.  For example, a value of 3 is equivalent to the command `echo on all'.
+
+     The value of `echo_executing_commands' may be set by the `echo' command or the command line option `--echo-commands'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Query or set the internal variable that controls the echo state.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+filemarker
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 655
+ -- Built-in Function:  filemarker ()
+     Returns or sets the character used to separate filename from the the subfunction names contained within the file.  This can be used in a generic manner to interact with subfunctions.  For example
+
+          help (["myfunc", filemarker, "mysubfunc"])
+
+     returns the help string associated with the sub-function `mysubfunc' of the function `myfunc'.  Another use of `filemarker' is when debugging it allows easier placement of breakpoints within sub-functions.  For example
+
+          dbstop (["myfunc", filemarker, "mysubfunc"])
+
+     will set a breakpoint at the first line of the subfunction `mysubfunc'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+Returns or sets the character used to separate filename from the the subfunction names contained within the file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 554
+ -- Loadable Function: [X, RCOND] = inv (A)
+ -- Loadable Function: [X, RCOND] = inverse (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.
+
+     If called with a sparse matrix, then in general X will be a full matrix, and so if possible forming the inverse of a sparse matrix should be avoided.  It is significantly more accurate and faster to do `Y = A \ B', rather than `Y = inv (A) * B'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Compute the inverse of the square matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+inverse
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+ -- Loadable Function:  inverse (A)
+     See inv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+See inv.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+kron
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 285
+ -- Loadable Function:  kron (A, B)
+     Form the kronecker product of two matrices, defined block by block as
+
+          x = [a(i, j) b]
+
+     For example,
+
+          kron (1:4, ones (3, 1))
+                =>  1  2  3  4
+                    1  2  3  4
+                    1  2  3  4
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Form the kronecker product of two matrices, defined block by block as 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+iskeyword
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 139
+ -- Built-in Function:  iskeyword (NAME)
+     Return true if NAME is an Octave keyword.  If NAME is omitted, return a list of keywords.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Return true if NAME is an Octave keyword.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+genpath
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+ -- Built-in Function:  genpath (DIR)
+     Return a path constructed from DIR and all its subdirectories.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Return a path constructed from DIR and all its subdirectories.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+rehash
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+ -- Built-in Function:  rehash ()
+     Reinitialize Octave's load path directory cache.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Reinitialize Octave's load path directory cache.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+command_line_path
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 171
+ -- Built-in Function:  command_line_path (...)
+     Return the command line path variable.
+
+     See also: path, addpath, rmpath, genpath, pathdef, savepath, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Return the command line path variable.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+restoredefaultpath
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 189
+ -- Built-in Function:  restoredefaultpath (...)
+     Restore Octave's path to it's initial state at startup.
+
+     See also: path, addpath, rmpath, genpath, pathdef, savepath, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Restore Octave's path to it's initial state at startup.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+path
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 549
+ -- Built-in Function:  path (...)
+     Modify or display Octave's load path.
+
+     If NARGIN and NARGOUT are zero, display the elements of Octave's load path in an easy to read format.
+
+     If NARGIN is zero and nargout is greater than zero, return the current load path.
+
+     If NARGIN is greater than zero, concatenate the arguments, separating them with `pathsep()'.  Set the internal search path to the result and return it.
+
+     No checks are made for duplicate elements.  See also: addpath, rmpath, genpath, pathdef, savepath, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Modify or display Octave's load path.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+addpath
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 429
+ -- Built-in Function:  addpath (DIR1, ...)
+ -- Built-in Function:  addpath (DIR1, ..., OPTION)
+     Add DIR1, ... to the current function search path.  If OPTION is `"-begin"' or 0 (the default), prepend the directory name to the current path.  If OPTION is `"-end"' or 1, append the directory name to the current path.  Directories added to the path must exist.  See also: path, rmpath, genpath, pathdef, savepath, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+Add DIR1, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+rmpath
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 175
+ -- Built-in Function:  rmpath (DIR1, ...)
+     Remove DIR1, ... from the current function search path.
+
+     See also: path, addpath, genpath, pathdef, savepath, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+Remove DIR1, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+load
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3368
+ -- Command: load file
+ -- Command: load options file
+ -- Command: load options file v1 v2 ...
+ -- Command: S = load("options", "file", "v1", "v2", ...)
+     Load the named variables V1, V2, ..., from the file FILE.  If no variables are specified then all variables found in the file will be loaded.  As with `save', the list of variables to extract can be full names or use a pattern syntax.  The format of the file is automatically detected but may be overridden by supplying the appropriate option.
+
+     If load is invoked using the functional form
+
+          load ("-option1", ..., "file", "v1", ...)
+
+     then the OPTIONS, FILE, and variable name arguments (V1, ...) must be specified as character strings.
+
+     If a variable that is not marked as global is loaded from a file when a global symbol with the same name already exists, it is loaded in the global symbol table.  Also, if a variable is marked as global in a file and a local symbol exists, the local symbol is moved to the global symbol table and given the value from the file.
+
+     If invoked with a single output argument, Octave returns data instead of inserting variables in the symbol table.  If the data file contains only numbers (TAB- or space-delimited columns), a matrix of values is returned.  Otherwise, `load' returns a structure with members  corresponding to the names of the variables in the file.
+
+     The `load' command can read data stored in Octave's text and binary formats, and MATLAB's binary format.  If compiled with zlib support, it can also load gzip-compressed files.  It will automatically detect the type of file and do conversion from different floating point formats (currently only IEEE big and little endian, though other formats may be added in the future).
+
+     Valid options for `load' are listed in the following table.
+
+    `-force'
+          This option is accepted for backward compatibility but is ignored.  Octave now overwrites variables currently in memory with those of the same name found in the file.
+
+    `-ascii'
+          Force Octave to assume the file contains columns of numbers in text format without any header or other information.  Data in the file will be loaded as a single numeric matrix with the name of the variable derived from the name of the file.
+
+    `-binary'
+          Force Octave to assume the file is in Octave's binary format.
+
+    `-hdf5'
+          Force Octave to assume the file is in HDF5 format.  (HDF5 is a free, portable binary format developed by the National Center for Supercomputing Applications at the University of Illinois.)  Note that Octave can read HDF5 files not created by itself, but may skip some datasets in formats that it cannot support.
+
+    `-import'
+          This option is accepted for backward compatibility but is ignored.  Octave can now support multi-dimensional HDF data and automatically modifies variable names if they are invalid Octave identifiers.
+
+    `-mat'
+    `-mat-binary'
+    `-6'
+    `-v6'
+    `-7'
+    `-v7'
+          Force Octave to assume the file is in MATLAB's version 6 or 7 binary format.
+
+    `-mat4-binary'
+    `-4'
+    `-v4'
+    `-V4'
+          Force Octave to assume the file is in the binary format written by MATLAB version 4.
+
+    `-text'
+          Force Octave to assume the file is in Octave's text format.
+     See also: save, dlmwrite, csvwrite, fwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Load the named variables V1, V2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+save
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3522
+ -- Command: save file
+ -- Command: save options file
+ -- Command: save options file V1 V2 ...
+ -- Command: save options file -struct STRUCT F1 F2 ...
+     Save the named variables V1, V2, ..., in the file FILE.  The special filename `-' may be used to write output to the terminal.  If no variable names are listed, Octave saves all the variables in the current scope.  Otherwise, full variable names or pattern syntax can be used to specify the variables to save.  If the `-struct' modifier is used, fields F1 F2 ...  of the scalar structure STRUCT are saved as if they were variables with corresponding names.  Valid options for the `save' command are listed in the following table.  Options that modify the output format override the format specified by `default_save_options'.
+
+     If save is invoked using the functional form
+
+          save ("-option1", ..., "file", "v1", ...)
+
+     then the OPTIONS, FILE, and variable name arguments (V1, ...) must be specified as character strings.
+
+    `-ascii'
+          Save a single matrix in a text file without header or any other information.
+
+    `-binary'
+          Save the data in Octave's binary data format.
+
+    `-float-binary'
+          Save the data in Octave's binary data format but only using single precision.  Only use this format if you know that all the values to be saved can be represented in single precision.
+
+    `-hdf5'
+          Save the data in HDF5 format.  (HDF5 is a free, portable binary format developed by the National Center for Supercomputing Applications at the University of Illinois.)
+
+    `-float-hdf5'
+          Save the data in HDF5 format but only using single precision.  Only use this format if you know that all the values to be saved can be represented in single precision.
+
+    `-V7'
+    `-v7'
+    `-7'
+    `-mat7-binary'
+          Save the data in MATLAB's v7 binary data format.
+
+    `-V6'
+    `-v6'
+    `-6'
+    `-mat'
+    `-mat-binary'
+          Save the data in MATLAB's v6 binary data format.
+
+    `-V4'
+    `-v4'
+    `-4'
+    `-mat4-binary'
+          Save the data in the binary format written by MATLAB version 4.
+
+    `-text'
+          Save the data in Octave's text data format.  (default).
+
+    `-zip'
+    `-z'
+          Use the gzip algorithm to compress the file.  This works equally on files that are compressed with gzip outside of octave, and gzip can equally be used to convert the files for backward compatibility.
+
+     The list of variables to save may use wildcard patterns containing the following special characters:
+    `?'
+          Match any single character.
+
+    `*'
+          Match zero or more characters.
+
+    `[ LIST ]'
+          Match the list of characters specified by LIST.  If the first character is `!' or `^', match all characters except those specified by LIST.  For example, the pattern `[a-zA-Z]' will match all lower and upper case alphabetic characters.
+
+          Wildcards may also be used in the field name specifications when using the `-struct' modifier (but not in the struct name itself).
+
+
+     Except when using the MATLAB binary data file format or the `-ascii' format, saving global variables also saves the global status of the variable.  If the variable is restored at a later time using `load', it will be restored as a global variable.
+
+     The command
+
+          save -binary data a b*
+
+     saves the variable `a' and all variables beginning with `b' to the file `data' in Octave's binary format.  See also: load, default_save_options, dlmread, csvread, fread.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Save the named variables V1, V2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+crash_dumps_octave_core
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 406
+ -- Built-in Function: VAL = crash_dumps_octave_core ()
+ -- Built-in Function: OLD_VAL = crash_dumps_octave_core (NEW_VAL)
+     Query or set the internal variable that controls whether Octave tries to save all current variables to the file "octave-core" if it crashes or receives a hangup, terminate or similar signal.  See also: octave_core_file_limit, octave_core_file_name, octave_core_file_options.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 190
+Query or set the internal variable that controls whether Octave tries to save all current variables to the file "octave-core" if it crashes or receives a hangup, terminate or similar signal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+default_save_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 351
+ -- Built-in Function: VAL = default_save_options ()
+ -- Built-in Function: OLD_VAL = default_save_options (NEW_VAL)
+     Query or set the internal variable that specifies the default options for the `save' command, and defines the default format.  Typical values include `"-ascii"', `"-text -zip"'.  The default value is `-text'.  See also: save.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+Query or set the internal variable that specifies the default options for the `save' command, and defines the default format.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+octave_core_file_limit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 730
+ -- Built-in Function: VAL = octave_core_file_limit ()
+ -- Built-in Function: OLD_VAL = octave_core_file_limit (NEW_VAL)
+     Query or set the internal variable that specifies the maximum amount of memory (in kilobytes) of the top-level workspace that Octave will attempt to save when writing data to the crash dump file (the name of the file is specified by OCTAVE_CORE_FILE_NAME).  If OCTAVE_CORE_FILE_OPTIONS flags specify a binary format, then OCTAVE_CORE_FILE_LIMIT will be approximately the maximum size of the file.  If a text file format is used, then the file could be much larger than the limit.  The default value is -1 (unlimited) See also: crash_dumps_octave_core, octave_core_file_name, octave_core_file_options.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 256
+Query or set the internal variable that specifies the maximum amount of memory (in kilobytes) of the top-level workspace that Octave will attempt to save when writing data to the crash dump file (the name of the file is specified by OCTAVE_CORE_FILE_NAME).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 21
+octave_core_file_name
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 388
+ -- Built-in Function: VAL = octave_core_file_name ()
+ -- Built-in Function: OLD_VAL = octave_core_file_name (NEW_VAL)
+     Query or set the internal variable that specifies the name of the file used for saving data from the top-level workspace if Octave aborts.  The default value is `"octave-core"' See also: crash_dumps_octave_core, octave_core_file_name, octave_core_file_options.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+Query or set the internal variable that specifies the name of the file used for saving data from the top-level workspace if Octave aborts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+octave_core_file_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 488
+ -- Built-in Function: VAL = octave_core_file_options ()
+ -- Built-in Function: OLD_VAL = octave_core_file_options (NEW_VAL)
+     Query or set the internal variable that specifies the options used for saving the workspace data if Octave aborts.  The value of `octave_core_file_options' should follow the same format as the options for the `save' function.  The default value is Octave's binary format.  See also: crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Query or set the internal variable that specifies the options used for saving the workspace data if Octave aborts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+save_header_format_string
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 671
+ -- Built-in Function: VAL = save_header_format_string ()
+ -- Built-in Function: OLD_VAL = save_header_format_string (NEW_VAL)
+     Query or set the internal variable that specifies the format string used for the comment line written at the beginning of text-format data files saved by Octave.  The format string is passed to `strftime' and should begin with the character `#' and contain no newline characters.  If the value of `save_header_format_string' is the empty string, the header comment is omitted from text-format data files.  The default value is
+
+          "# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER at HOST>"
+     See also: strftime, save.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 161
+Query or set the internal variable that specifies the format string used for the comment line written at the beginning of text-format data files saved by Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+lookup
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1403
+ -- Loadable Function: IDX = lookup (TABLE, Y, OPT)
+     Lookup values in a sorted table.  Usually used as a prelude to interpolation.
+
+     If table is strictly increasing and `idx = lookup (table, y)', then `table(idx(i)) <= y(i) < table(idx(i+1))' for all `y(i)' within the table.  If `y(i) < table (1)' then `idx(i)' is 0. If `y(i) >= table(end)' then `idx(i)' is `table(n)'.
+
+     If the table is strictly decreasing, then the tests are reversed.  There are no guarantees for tables which are non-monotonic or are not strictly monotonic.
+
+     The algorithm used by lookup is standard binary search, with optimizations to speed up the case of partially ordered arrays (dense downsampling).  In particular, looking up a single entry is of logarithmic complexity (unless a conversion occurs due to non-numeric or unequal types).
+
+     TABLE and Y can also be cell arrays of strings (or Y can be a single string).  In this case, string lookup is performed using lexicographical comparison.
+
+     If OPTS is specified, it shall be a string with letters indicating additional options.  For numeric lookup, 'l' in OPTS indicates that the leftmost subinterval shall be extended to infinity (i.e., all indices at least 1), and 'r' indicates that the rightmost subinterval shall be extended to infinity (i.e., all indices at most n-1).
+
+     For string lookup, 'i' indicates case-insensitive comparison.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Lookup values in a sorted table.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+save_precision
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Built-in Function: VAL = save_precision ()
+ -- Built-in Function: OLD_VAL = save_precision (NEW_VAL)
+     Query or set the internal variable that specifies the number of digits to keep when saving data in text format.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Query or set the internal variable that specifies the number of digits to keep when saving data in text format.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+lsode_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1946
+ -- Loadable Function:  lsode_options (OPT, VAL)
+     When called with two arguments, this function allows you set options parameters for the function `lsode'.  Given one argument, `lsode_options' returns the value of the corresponding option.  If no arguments are supplied, the names of all the available options and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a vector, it must match the dimension of the state vector.
+
+    `"relative tolerance"'
+          Relative tolerance parameter.  Unlike the absolute tolerance, this parameter may only be a scalar.
+
+          The local error test applied at each integration step is
+
+                 abs (local error in x(i)) <= ...
+                     rtol * abs (y(i)) + atol(i)
+
+    `"integration method"'
+          A string specifying the method of integration to use to solve the ODE system.  Valid values are
+
+         "adams"
+         "non-stiff"
+               No Jacobian used (even if it is available).
+
+         "bdf"
+
+         "stiff"
+               Use stiff backward differentiation formula (BDF) method.  If a function to compute the Jacobian is not supplied, `lsode' will compute a finite difference approximation of the Jacobian matrix.
+
+    `"initial step size"'
+          The step size to be attempted on the first step (default is determined automatically).
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  If using the Adams method, this option must be between 1 and 12.  Otherwise, it must be between 1 and 5, inclusive.
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very large regions  (default is not specified).
+
+    `"minimum step size"'
+          The minimum absolute step size allowed (default is 0).
+
+    `"step limit"'
+          Maximum number of steps allowed (default is 100000).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+When called with two arguments, this function allows you set options parameters for the function `lsode'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+lsode
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2600
+ -- Loadable Function: [X, ISTATE, MSG] = lsode (FCN, X_0, T, T_CRIT)
+     Solve the set of differential equations
+
+          dx
+          -- = f(x, t)
+          dt
+
+     with
+
+          x(t_0) = x_0
+
+     The solution is returned in the matrix X, with each row corresponding to an element of the vector T.  The first element of T should be t_0 and should correspond to the initial state of the system X_0, so that the first row of the output is X_0.
+
+     The first argument, FCN, is a string, inline, or function handle that names the function f to call to compute the vector of right hand sides for the set of equations.  The function must have the form
+
+          XDOT = f (X, T)
+
+     in which XDOT and X are vectors and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array of strings, inline functions, or function handles, the first element names the function f described above, and the second element names a function to compute the Jacobian of f.  The Jacobian function must have the form
+
+          JAC = j (X, T)
+
+     in which JAC is the matrix of partial derivatives
+
+                       | df_1  df_1       df_1 |
+                       | ----  ----  ...  ---- |
+                       | dx_1  dx_2       dx_N |
+                       |                       |
+                       | df_2  df_2       df_2 |
+                       | ----  ----  ...  ---- |
+                df_i   | dx_1  dx_2       dx_N |
+          jac = ---- = |                       |
+                dx_j   |  .    .     .    .    |
+                       |  .    .      .   .    |
+                       |  .    .       .  .    |
+                       |                       |
+                       | df_N  df_N       df_N |
+                       | ----  ----  ...  ---- |
+                       | dx_1  dx_2       dx_N |
+
+     The second and third arguments specify the initial state of the system, x_0, and the initial value of the independent variable t_0.
+
+     The fourth argument is optional, and may be used to specify a set of times that the ODE solver should not integrate past.  It is useful for avoiding difficulties with singularities and points where there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be 2 (consistent with the Fortran version of LSODE).
+
+     If the computation is not successful, ISTATE will be something other than 2 and MSG will contain additional information.
+
+     You can use the function `lsode_options' to set optional parameters for `lsode'.  See also: daspk, dassl, dasrt.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Solve the set of differential equations 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+lu
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2398
+ -- Loadable Function: [L, U, P] = lu (A)
+ -- Loadable Function: [L, U, P, Q] = lu (S)
+ -- Loadable Function: [L, U, P, Q, R] = lu (S)
+ -- Loadable Function: [...] = lu (S, THRES)
+ -- Loadable Function: Y = lu (...)
+ -- Loadable Function: [...] = lu (..., 'vector')
+     Compute the LU decomposition of A.  If A is full subroutines from LAPACK are used and if A is sparse then UMFPACK is used.  The result is returned in a permuted form, according to the optional return value P.  For example, given the matrix `a = [1, 2; 3, 4]',
+
+          [l, u, p] = lu (a)
+
+     returns
+
+          l =
+
+            1.00000  0.00000
+            0.33333  1.00000
+
+          u =
+
+            3.00000  4.00000
+            0.00000  0.66667
+
+          p =
+
+            0  1
+            1  0
+
+     The matrix is not required to be square.
+
+     Called with two or three output arguments and a spare input matrix, then "lu" does not attempt to perform sparsity preserving column permutations.  Called with a fourth output argument, the sparsity preserving column transformation Q is returned, such that `P * A * Q = L * U'.
+
+     Called with a fifth output argument and a sparse input matrix, then "lu" attempts to use a scaling factor R on the input matrix such that `P * (R \ A) * Q = L * U'.  This typically leads to a sparser and more stable factorization.
+
+     An additional input argument THRES, that defines the pivoting threshold can be given.  THRES can be a scalar, in which case it defines UMFPACK pivoting tolerance for both symmetric and unsymmetric cases.  If THRES is a two element vector, then the first element defines the pivoting tolerance for the unsymmetric UMFPACK pivoting strategy and the second the symmetric strategy.  By default, the values defined by `spparms' are used and are by default `[0.1, 0.001]'.
+
+     Given the string argument 'vector', "lu" returns the values of P Q as vector values, such that for full matrix, `A (P,:) = L * U', and `R(P,:) * A (:, Q) = L * U'.
+
+     With two output arguments, returns the permuted forms of the upper and lower triangular matrices, such that `A = L * U'.  With one output argument Y, then the matrix returned by the LAPACK routines is returned.  If the input matrix is sparse then the matrix L is embedded into U to give a return value similar to the full case.  For both full and sparse matrices, "lu" looses the permutation information.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Compute the LU decomposition of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+luinc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2264
+ -- Loadable Function: [L, U, P, Q] = luinc (A, '0')
+ -- Loadable Function: [L, U, P, Q] = luinc (A, DROPTOL)
+ -- Loadable Function: [L, U, P, Q] = luinc (A, OPTS)
+     Produce the incomplete LU factorization of the sparse matrix A.  Two types of incomplete factorization are possible, and the type is determined by the second argument to "luinc".
+
+     Called with a second argument of '0', the zero-level incomplete LU factorization is produced.  This creates a factorization of A where the position of the non-zero arguments correspond to the same positions as in the matrix A.
+
+     Alternatively, the fill-in of the incomplete LU factorization can be controlled through the variable DROPTOL or the structure OPTS.  The UMFPACK multifrontal factorization code by Tim A.  Davis is used for the incomplete LU factorization, (availability `http://www.cise.ufl.edu/research/sparse/umfpack/')
+
+     DROPTOL determines the values below which the values in the LU factorization are dropped and replaced by zero.  It must be a positive scalar, and any values in the factorization whose absolute value are less than this value are dropped, expect if leaving them increase the sparsity of the matrix.  Setting DROPTOL to zero results in a complete LU factorization which is the default.
+
+     OPTS is a structure containing one or more of the fields
+
+    `droptol'
+          The drop tolerance as above.  If OPTS only contains `droptol' then this is equivalent to using the variable DROPTOL.
+
+    `milu'
+          A logical variable flagging whether to use the modified incomplete LU factorization.  In the case that `milu' is true, the dropped values are subtracted from the diagonal of the matrix U of the factorization.  The default is `false'.
+
+    `udiag'
+          A logical variable that flags whether zero elements on the diagonal of U should be replaced with DROPTOL to attempt to avoid singular factors.  The default is `false'.
+
+    `thresh'
+          Defines the pivot threshold in the interval [0,1].  Values outside that range are ignored.
+
+     All other fields in OPTS are ignored.  The outputs from "luinc" are the same as for "lu".
+
+     Given the string argument 'vector', "luinc" returns the values of P Q as vector values.  See also: sparse, lu.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Produce the incomplete LU factorization of the sparse matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+abs
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 164
+ -- Mapping Function:  abs (Z)
+     Compute the magnitude of Z, defined as |Z| = `sqrt (x^2 + y^2)'.
+
+     For example,
+
+          abs (3 + 4i)
+               => 5
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Compute the magnitude of Z, defined as |Z| = `sqrt (x^2 + y^2)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+acos
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+ -- Mapping Function:  acos (X)
+     Compute the inverse cosine in radians for each element of X.  See also: cos, acosd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Compute the inverse cosine in radians for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+acosh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+ -- Mapping Function:  acosh (X)
+     Compute the inverse hyperbolic cosine for each element of X.  See also: cosh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Compute the inverse hyperbolic cosine for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+angle
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+ -- Mapping Function:  angle (Z)
+     See arg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+See arg.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+arg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 213
+ -- Mapping Function:  arg (Z)
+ -- Mapping Function:  angle (Z)
+     Compute the argument of Z, defined as, THETA = `atan2 (Y, X)', in radians.
+
+     For example,
+
+          arg (3 + 4i)
+               => 0.92730
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Compute the argument of Z, defined as, THETA = `atan2 (Y, X)', in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+asin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Mapping Function:  asin (X)
+     Compute the inverse sine in radians for each element of X.  See also: sin, asind.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Compute the inverse sine in radians for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+asinh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+ -- Mapping Function:  asinh (X)
+     Compute the inverse hyperbolic sine for each element of X.  See also: sinh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Compute the inverse hyperbolic sine for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+atan
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+ -- Mapping Function:  atan (X)
+     Compute the inverse tangent in radians for each element of X.  See also: tan, atand.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Compute the inverse tangent in radians for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+atanh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+ -- Mapping Function:  atanh (X)
+     Compute the inverse hyperbolic tangent for each element of X.  See also: tanh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Compute the inverse hyperbolic tangent for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+ceil
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 297
+ -- Mapping Function:  ceil (X)
+     Return the smallest integer not less than X.  This is equivalent to rounding towards positive infinity.  If X is complex, return `ceil (real (X)) + ceil (imag (X)) * I'.
+          ceil ([-2.7, 2.7])
+             =>  -2   3
+     See also: floor, round, fix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Return the smallest integer not less than X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+conj
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+ -- Mapping Function:  conj (Z)
+     Return the complex conjugate of Z, defined as `conj (Z)' = X - IY.  See also: real, imag.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return the complex conjugate of Z, defined as `conj (Z)' = X - IY.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cos
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Mapping Function:  cos (X)
+     Compute the cosine for each element of X in radians.  See also: acos, cosd, cosh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Compute the cosine for each element of X in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cosh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+ -- Mapping Function:  cosh (X)
+     Compute the hyperbolic cosine for each element of X.  See also: acosh, sinh, tanh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Compute the hyperbolic cosine for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+erf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 290
+ -- Mapping Function:  erf (Z)
+     Computes the error function,
+
+                                   z
+                                  /
+          erf (z) = (2/sqrt (pi)) | e^(-t^2) dt
+                                  /
+                               t=0
+     See also: erfc, erfinv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+Computes the error function, 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+erfc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Mapping Function:  erfc (Z)
+     Computes the complementary error function, `1 - erf (Z)'.  See also: erf, erfinv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Computes the complementary error function, `1 - erf (Z)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+exp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 156
+ -- Mapping Function:  exp (X)
+     Compute `e^x' for each element of X.  To compute the matrix exponential, see *note Linear Algebra::.  See also: log.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Compute `e^x' for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+expm1
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+ -- Mapping Function:  expm1 (X)
+     Compute `exp (X) - 1' accurately in the neighborhood of zero.  See also: exp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Compute `exp (X) - 1' accurately in the neighborhood of zero.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+finite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 195
+ -- Mapping Function:  finite (X)
+     Return 1 for elements of X that are finite values and zero otherwise.  For example,
+
+          finite ([13, Inf, NA, NaN])
+               => [ 1, 0, 0, 0 ]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Return 1 for elements of X that are finite values and zero otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+fix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 300
+ -- Mapping Function:  fix (X)
+     Truncate fractional portion of X and return the integer portion.  This is equivalent to rounding towards zero.  If X is complex, return `fix (real (X)) + fix (imag (X)) * I'.
+          fix ([-2.7, 2.7])
+             => -2   2
+     See also: ceil, floor, round.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Truncate fractional portion of X and return the integer portion.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+floor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 303
+ -- Mapping Function:  floor (X)
+     Return the largest integer not greater than X.  This is equivalent to rounding towards negative infinity.  If X is complex, return `floor (real (X)) + floor (imag (X)) * I'.
+          floor ([-2.7, 2.7])
+               => -3   2
+     See also: ceil, round, fix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Return the largest integer not greater than X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+gamma
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 251
+ -- Mapping Function:  gamma (Z)
+     Computes the Gamma function,
+
+                      infinity
+                      /
+          gamma (z) = | t^(z-1) exp (-t) dt.
+                      /
+                   t=0
+     See also: gammainc, lgamma.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+Computes the Gamma function, 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+imag
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+ -- Mapping Function:  imag (Z)
+     Return the imaginary part of Z as a real number.  See also: real, conj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return the imaginary part of Z as a real number.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isalnum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+ -- Mapping Function:  isalnum (S)
+     Return 1 for characters that are letters or digits (`isalpha (S)' or `isdigit (S)' is true).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Return 1 for characters that are letters or digits (`isalpha (S)' or `isdigit (S)' is true).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isalpha
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 165
+ -- Mapping Function:  isalpha (S)
+ -- Mapping Function:  isletter (S)
+     Return true for characters that are letters (`isupper (S)' or `islower (S)' is true).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+Return true for characters that are letters (`isupper (S)' or `islower (S)' is true).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isascii
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+ -- Mapping Function:  isascii (S)
+     Return 1 for characters that are ASCII (in the range 0 to 127 decimal).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return 1 for characters that are ASCII (in the range 0 to 127 decimal).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+iscntrl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+ -- Mapping Function:  iscntrl (S)
+     Return 1 for control characters.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return 1 for control characters.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isdigit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+ -- Mapping Function:  isdigit (S)
+     Return 1 for characters that are decimal digits.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return 1 for characters that are decimal digits.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+isinf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 188
+ -- Mapping Function:  isinf (X)
+     Return 1 for elements of X that are infinite and zero otherwise.  For example,
+
+          isinf ([13, Inf, NA, NaN])
+               => [ 0, 1, 0, 0 ]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return 1 for elements of X that are infinite and zero otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isgraph
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+ -- Mapping Function:  isgraph (S)
+     Return 1 for printable characters (but not the space character).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return 1 for printable characters (but not the space character).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+islower
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+ -- Mapping Function:  islower (S)
+     Return 1 for characters that are lower case letters.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return 1 for characters that are lower case letters.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+isna
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Mapping Function:  isna (X)
+     Return 1 for elements of X that are NA (missing) values and zero otherwise.  For example,
+
+          isna ([13, Inf, NA, NaN])
+               => [ 0, 0, 1, 0 ]
+     See also: isnan.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Return 1 for elements of X that are NA (missing) values and zero otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+isnan
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 257
+ -- Mapping Function:  isnan (X)
+     Return 1 for elements of X that are NaN values and zero otherwise.  NA values are also considered NaN values.  For example,
+
+          isnan ([13, Inf, NA, NaN])
+               => [ 0, 0, 1, 1 ]
+     See also: isna.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return 1 for elements of X that are NaN values and zero otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isprint
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+ -- Mapping Function:  isprint (S)
+     Return 1 for printable characters (including the space character).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return 1 for printable characters (including the space character).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ispunct
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+ -- Mapping Function:  ispunct (S)
+     Return 1 for punctuation characters.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Return 1 for punctuation characters.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isspace
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+ -- Mapping Function:  isspace (S)
+     Return 1 for whitespace characters (space, formfeed, newline, carriage return, tab, and vertical tab).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+Return 1 for whitespace characters (space, formfeed, newline, carriage return, tab, and vertical tab).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isupper
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+ -- Mapping Function:  isupper (S)
+     Return 1 for upper case letters.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return 1 for upper case letters.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isxdigit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+ -- Mapping Function:  isxdigit (S)
+     Return 1 for characters that are hexadecimal digits.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return 1 for characters that are hexadecimal digits.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+lgamma
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 162
+ -- Mapping Function:  lgamma (X)
+ -- Mapping Function:  gammaln (X)
+     Return the natural logarithm of the gamma function of X.  See also: gamma, gammainc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Return the natural logarithm of the gamma function of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+log
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 211
+ -- Mapping Function:  log (X)
+     Compute the natural logarithm, `ln (X)', for each element of X.  To compute the matrix logarithm, see *note Linear Algebra::.  See also: exp, log1p, log2, log10, logspace.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Compute the natural logarithm, `ln (X)', for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+log10
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+ -- Mapping Function:  log10 (X)
+     Compute the base-10 logarithm of each element of X.  See also: log, log2, logspace, exp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Compute the base-10 logarithm of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+log1p
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+ -- Mapping Function:  log1p (X)
+     Compute `log (1 + X)' accurately in the neighborhood of zero.  See also: log, exp, expm1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Compute `log (1 + X)' accurately in the neighborhood of zero.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+real
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 90
+ -- Mapping Function:  real (Z)
+     Return the real part of Z.  See also: imag, conj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Return the real part of Z.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+round
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 230
+ -- Mapping Function:  round (X)
+     Return the integer nearest to X.  If X is complex, return `round (real (X)) + round (imag (X)) * I'.
+          round ([-2.7, 2.7])
+               => -3   3
+     See also: ceil, floor, fix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return the integer nearest to X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+roundb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 240
+ -- Mapping Function:  roundb (X)
+     Return the integer nearest to X.  If there are two nearest integers, return the even one (banker's rounding).  If X is complex, return `roundb (real (X)) + roundb (imag (X)) * I'.  See also: round.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return the integer nearest to X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sign
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 248
+ -- Mapping Function:  sign (X)
+     Compute the "signum" function, which is defined as
+
+                     -1, x < 0;
+          sign (x) =  0, x = 0;
+                      1, x > 0.
+
+     For complex arguments, `sign' returns `x ./ abs (X)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Compute the "signum" function, which is defined as 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+sin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+ -- Mapping Function:  sin (X)
+     Compute the sine for each element of X in radians.  See also: asin, sind, sinh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Compute the sine for each element of X in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sinh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Mapping Function:  sinh (X)
+     Compute the hyperbolic sine for each element of X.  See also: asinh, cosh, tanh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Compute the hyperbolic sine for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sqrt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 220
+ -- Mapping Function:  sqrt (X)
+     Compute the square root of each element of X.  If X is negative, a complex result is returned.  To compute the matrix square root, see *note Linear Algebra::.  See also: realsqrt.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Compute the square root of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+tan
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Mapping Function:  tan (Z)
+     Compute the tangent for each element of X in radians.  See also: atan, tand, tanh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compute the tangent for each element of X in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+tanh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+ -- Mapping Function:  tanh (X)
+     Compute hyperbolic tangent for each element of X.  See also: atanh, sinh, cosh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Compute hyperbolic tangent for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+toascii
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 195
+ -- Mapping Function:  toascii (S)
+     Return ASCII representation of S in a matrix.  For example,
+
+          toascii ("ASCII")
+               => [ 65, 83, 67, 73, 73 ]
+
+     See also: char.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Return ASCII representation of S in a matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+tolower
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 356
+ -- Mapping Function:  tolower (S)
+ -- Mapping Function:  lower (S)
+     Return a copy of the string or cell string S, with each upper-case character replaced by the corresponding lower-case one; non-alphabetic characters are left unchanged.  For example,
+
+          tolower ("MiXeD cAsE 123")
+               => "mixed case 123"
+     See also: toupper.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+Return a copy of the string or cell string S, with each upper-case character replaced by the corresponding lower-case one; non-alphabetic characters are left unchanged.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+toupper
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 358
+ -- Built-in Function:  toupper (S)
+ -- Built-in Function:  upper (S)
+     Return a copy of the string or cell string S, with each lower-case character replaced by the corresponding upper-case one; non-alphabetic characters are left unchanged.  For example,
+
+          toupper ("MiXeD cAsE 123")
+               => "MIXED CASE 123"
+     See also: tolower.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+Return a copy of the string or cell string S, with each lower-case character replaced by the corresponding upper-case one; non-alphabetic characters are left unchanged.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+matrix_type
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2920
+ -- Loadable Function: TYPE = matrix_type (A)
+ -- Loadable Function: A = matrix_type (A, TYPE)
+ -- Loadable Function: A = matrix_type (A, 'upper', PERM)
+ -- Loadable Function: A = matrix_type (A, 'lower', PERM)
+ -- Loadable Function: A = matrix_type (A, 'banded', NL, NU)
+     Identify the matrix type or mark a matrix as a particular type.  This allows rapid for solutions of linear equations involving A to be performed.  Called with a single argument, `matrix_type' returns the type of the matrix and caches it for future use.  Called with more than one argument, `matrix_type' allows the type of the matrix to be defined.
+
+     The possible matrix types depend on whether the matrix is full or sparse, and can be one of the following
+
+    'unknown'
+          Remove any previously cached matrix type, and mark type as unknown
+
+    'full'
+          Mark the matrix as full.
+
+    'positive definite'
+          Probable full positive definite matrix.
+
+    'diagonal'
+          Diagonal Matrix.  (Sparse matrices only)
+
+    'permuted diagonal'
+          Permuted Diagonal matrix.  The permutation does not need to be specifically indicated, as the structure of the matrix explicitly gives this.  (Sparse matrices only)
+
+    'upper'
+          Upper triangular.  If the optional third argument PERM is given, the matrix is assumed to be a permuted upper triangular with the permutations defined by the vector PERM.
+
+    'lower'
+          Lower triangular.  If the optional third argument PERM is given, the matrix is assumed to be a permuted lower triangular with the permutations defined by the vector PERM.
+
+    'banded'
+    'banded positive definite'
+          Banded matrix with the band size of NL below the diagonal and NU above it.  If NL and NU are 1, then the matrix is tridiagonal and treated with specialized code.  In addition the matrix can be marked as probably a positive definite (Sparse matrices only)
+
+    'singular'
+          The matrix is assumed to be singular and will be treated with a minimum norm solution
+
+
+     Note that the matrix type will be discovered automatically on the first attempt to solve a linear equation involving A.  Therefore `matrix_type' is only useful to give Octave hints of the matrix type.  Incorrectly defining the matrix type will result in incorrect results from solutions of linear equations, and so it is entirely the responsibility of the user to correctly identify the matrix type.
+
+     Also the test for positive definiteness is a low-cost test for a hermitian matrix with a real positive diagonal.  This does not guarantee that the matrix is positive definite, but only that it is a probable candidate.  When such a matrix is factorized, a Cholesky factorization is first attempted, and if that fails the matrix is then treated with an LU factorization.  Once the matrix has been factorized, `matrix_type' will return the correct classification of the matrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Identify the matrix type or mark a matrix as a particular type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+min
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 993
+ -- Loadable Function:  min (X)
+ -- Loadable Function:  min (X, Y)
+ -- Loadable Function:  min (X, Y, DIM)
+ -- Loadable Function: [W, IW] = min (X)
+     For a vector argument, return the minimum value.  For a matrix argument, return the minimum value from each column, as a row vector, or over the dimension DIM if defined.  For two matrices (or a matrix and scalar), return the pair-wise minimum.  Thus,
+
+          min (min (X))
+
+     returns the smallest element of X, and
+
+          min (2:5, pi)
+              =>  2.0000  3.0000  3.1416  3.1416
+     compares each element of the range `2:5' with `pi', and returns a row vector of the minimum values.
+
+     For complex arguments, the magnitude of the elements are used for comparison.
+
+     If called with one input and two output arguments, `min' also returns the first index of the minimum value(s).  Thus,
+
+          [x, ix] = min ([1, 3, 0, 2, 0])
+              =>  x = 0
+                  ix = 3
+     See also: max, cummin, cummax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+For a vector argument, return the minimum value.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+max
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1003
+ -- Loadable Function:  max (X)
+ -- Loadable Function:  max (X, Y)
+ -- Loadable Function:  max (X, Y, DIM)
+ -- Loadable Function: [W, IW] = max (X)
+     For a vector argument, return the maximum value.  For a matrix argument, return the maximum value from each column, as a row vector, or over the dimension DIM if defined.  For two matrices (or a matrix and scalar), return the pair-wise maximum.  Thus,
+
+          max (max (X))
+
+     returns the largest element of the matrix X, and
+
+          max (2:5, pi)
+              =>  3.1416  3.1416  4.0000  5.0000
+     compares each element of the range `2:5' with `pi', and returns a row vector of the maximum values.
+
+     For complex arguments, the magnitude of the elements are used for comparison.
+
+     If called with one input and two output arguments, `max' also returns the first index of the maximum value(s).  Thus,
+
+          [x, ix] = max ([1, 3, 5, 2, 5])
+              =>  x = 5
+                  ix = 3
+     See also: min, cummax, cummin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+For a vector argument, return the maximum value.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+cummin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 750
+ -- Loadable Function:  cummin (X)
+ -- Loadable Function:  cummin (X, DIM)
+ -- Loadable Function: [W, IW] = cummin (X)
+     Return the cumulative minimum values along dimension DIM.  If DIM is unspecified it defaults to column-wise operation.  For example,
+
+          cummin ([5 4 6 2 3 1])
+              =>  5  4  4  2  2  1
+
+     The call
+            [w, iw] = cummin (x, dim)
+
+     is equivalent to the following code:
+          w = iw = zeros (size (x));
+          idxw = idxx = repmat ({':'}, 1, ndims (x));
+          for i = 1:size (x, dim)
+            idxw{dim} = i; idxx{dim} = 1:i;
+            [w(idxw{:}), iw(idxw{:})] = min(x(idxx{:}), [], dim);
+          endfor
+
+     but computed in a much faster manner.  See also: cummax, min, max.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Return the cumulative minimum values along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+cummax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 748
+ -- Loadable Function:  cummax (X)
+ -- Loadable Function:  cummax (X, DIM)
+ -- Loadable Function: [W, IW] = cummax (X)
+     Return the cumulative maximum values along dimension DIM.  If DIM is unspecified it defaults to column-wise operation.  For example,
+
+          cummax ([1 3 2 6 4 5])
+              =>  1  3  3  6  6  6
+
+     The call
+          [w, iw] = cummax (x, dim)
+
+     is equivalent to the following code:
+          w = iw = zeros (size (x));
+          idxw = idxx = repmat ({':'}, 1, ndims (x));
+          for i = 1:size (x, dim)
+            idxw{dim} = i; idxx{dim} = 1:i;
+            [w(idxw{:}), iw(idxw{:})] = max(x(idxx{:}), [], dim);
+          endfor
+
+     but computed in a much faster manner.  See also: cummin, max, min.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Return the cumulative maximum values along dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+md5sum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 224
+ -- Loadable Function:  md5sum (FILE)
+ -- Loadable Function:  md5sum (STR, OPT)
+     Calculates the MD5 sum of the file FILE.  If the second parameter OPT exists and is true, then calculate the MD5 sum of the string STR.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Calculates the MD5 sum of the file FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+edit_history
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1258
+ -- Command: edit_history [FIRST] [LAST]
+     If invoked with no arguments, `edit_history' allows you to edit the history list using the editor named by the variable `EDITOR'.  The commands to be edited are first copied to a temporary file.  When you exit the editor, Octave executes the commands that remain in the file.  It is often more convenient to use `edit_history' to define functions rather than attempting to enter them directly on the command line.  By default, the block of commands is executed as soon as you exit the editor.  To avoid executing any commands, simply delete all the lines from the buffer before exiting the editor.
+
+     The `edit_history' command takes two optional arguments specifying the history numbers of first and last commands to edit.  For example, the command
+
+          edit_history 13
+
+     extracts all the commands from the 13th through the last in the history list.  The command
+
+          edit_history 13 169
+
+     only extracts commands 13 through 169.  Specifying a larger number for the first command than the last command reverses the list of commands before placing them in the buffer to be edited.  If both arguments are omitted, the previous command in the history list is used.  See also: run_history.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+If invoked with no arguments, `edit_history' allows you to edit the history list using the editor named by the variable `EDITOR'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+history
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 837
+ -- Command: history options
+     If invoked with no arguments, `history' displays a list of commands that you have executed.  Valid options are:
+
+    `-w FILE'
+          Write the current history to the file FILE.  If the name is omitted, use the default history file (normally `~/.octave_hist').
+
+    `-r FILE'
+          Read the file FILE, replacing the current history list with its contents.  If the name is omitted, use the default history file (normally `~/.octave_hist').
+
+    `N'
+          Display only the most recent N lines of history.
+
+    `-q'
+          Don't number the displayed lines of history.  This is useful for cutting and pasting commands using the X Window System.
+
+     For example, to display the five most recent commands that you have typed without displaying line numbers, use the command `history -q 5'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+If invoked with no arguments, `history' displays a list of commands that you have executed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+run_history
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 212
+ -- Command: run_history [FIRST] [LAST]
+     Similar to `edit_history', except that the editor is not invoked, and the commands are simply executed as they appear in the history list.  See also: edit_history.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+Similar to `edit_history', except that the editor is not invoked, and the commands are simply executed as they appear in the history list.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+history_size
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 379
+ -- Built-in Function: VAL = history_size ()
+ -- Built-in Function: OLD_VAL = history_size (NEW_VAL)
+     Query or set the internal variable that specifies how many entries to store in the history file.  The default value is `1024', but may be overridden by the environment variable `OCTAVE_HISTSIZE'.  See also: history_file, history_timestamp_format_string, saving_history.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+Query or set the internal variable that specifies how many entries to store in the history file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+history_file
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 394
+ -- Built-in Function: VAL = history_file ()
+ -- Built-in Function: OLD_VAL = history_file (NEW_VAL)
+     Query or set the internal variable that specifies the name of the file used to store command history.  The default value is `~/.octave_hist', but may be overridden by the environment variable `OCTAVE_HISTFILE'.  See also: history_size, saving_history, history_timestamp_format_string.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+Query or set the internal variable that specifies the name of the file used to store command history.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+history_timestamp_format_string
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 493
+ -- Built-in Function: VAL = history_timestamp_format_string ()
+ -- Built-in Function: OLD_VAL = history_timestamp_format_string (NEW_VAL)
+     Query or set the internal variable that specifies the format string for the comment line that is written to the history file when Octave exits.  The format string is passed to `strftime'.  The default value is
+
+          "# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER at HOST>"
+     See also: strftime, history_file, history_size, saving_history.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Query or set the internal variable that specifies the format string for the comment line that is written to the history file when Octave exits.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+saving_history
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 310
+ -- Built-in Function: VAL = saving_history ()
+ -- Built-in Function: OLD_VAL = saving_history (NEW_VAL)
+     Query or set the internal variable that controls whether commands entered on the command line are saved in the history file.  See also: history_file, history_size, history_timestamp_format_string.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+Query or set the internal variable that controls whether commands entered on the command line are saved in the history file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+argv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 504
+ -- Built-in Function:  argv ()
+     Return the command line arguments passed to Octave.  For example, if you invoked Octave using the command
+
+          octave --no-line-editing --silent
+
+     `argv' would return a cell array of strings with the elements `--no-line-editing' and `--silent'.
+
+     If you write an executable Octave script, `argv' will return the list of arguments passed to the script.  *Note Executable Octave Programs::, for an example of how to create an executable Octave script.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Return the command line arguments passed to Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+program_invocation_name
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 409
+ -- Built-in Function: program_invocation_name ()
+     Return the name that was typed at the shell prompt to run Octave.
+
+     If executing a script from the command line (e.g., `octave foo.m') or using an executable Octave script, the program name is set to the name of the script.  *Note Executable Octave Programs::, for an example of how to create an executable Octave script.  See also: program_name.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Return the name that was typed at the shell prompt to run Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+program_name
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 162
+ -- Built-in Function:  program_name ()
+     Return the last component of the value returned by `program_invocation_name'.  See also: program_invocation_name.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Return the last component of the value returned by `program_invocation_name'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+sparse_auto_mutate
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 510
+ -- Built-in Function: VAL = sparse_auto_mutate ()
+ -- Built-in Function: OLD_VAL = sparse_auto_mutate (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will automatically mutate sparse matrices to real matrices to save memory.  For example,
+
+          s = speye(3);
+          sparse_auto_mutate (false)
+          s (:, 1) = 1;
+          typeinfo (s)
+          => sparse matrix
+          sparse_auto_mutate (true)
+          s (1, :) = 1;
+          typeinfo (s)
+          => matrix
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+Query or set the internal variable that controls whether Octave will automatically mutate sparse matrices to real matrices to save memory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+iscell
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+ -- Built-in Function:  iscell (X)
+     Return true if X is a cell array object.  Otherwise, return false.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Return true if X is a cell array object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cell
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 436
+ -- Built-in Function:  cell (X)
+ -- Built-in Function:  cell (N, M)
+     Create a new cell array object.  If invoked with a single scalar argument, `cell' returns a square cell array with the dimension specified.  If you supply two scalar arguments, `cell' takes them to be the number of rows and columns.  If given a vector with two elements, `cell' uses the values of the elements as the number of rows and columns, respectively.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Create a new cell array object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+iscellstr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+ -- Built-in Function:  iscellstr (CELL)
+     Return true if every element of the cell array CELL is a character string
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Return true if every element of the cell array CELL is a character string  
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cellstr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+ -- Built-in Function:  cellstr (STRING)
+     Create a new cell array object from the elements of the string array STRING.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Create a new cell array object from the elements of the string array STRING.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+struct2cell
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 288
+ -- Built-in Function:  struct2cell (S)
+     Create a new cell array from the objects stored in the struct object.  If F is the number of fields in the structure, the resulting cell array will have a dimension vector corresponding to `[F size(S)]'.  See also: cell2struct, fieldnames.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Create a new cell array from the objects stored in the struct object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+class
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 327
+ -- Built-in Function:  class (EXPR)
+ -- Built-in Function:  class (S, ID)
+ -- Built-in Function:  class (S, ID, P, ...)
+     Return the class of the expression EXPR or create a class with fields from structure S and name (string) ID.  Additional arguments name a list of parent classes from which the new class is derived.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Return the class of the expression EXPR or create a class with fields from structure S and name (string) ID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isobject
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+ -- Built-in Function:  isobject (X)
+     Return true if X is a class object.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Return true if X is a class object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ismethod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 137
+ -- Built-in Function:  ismethod (X, METHOD)
+     Return true if X is a class object and the string METHOD is a method of this class.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Return true if X is a class object and the string METHOD is a method of this class.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+methods
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 183
+ -- Built-in Function:  methods (X)
+ -- Built-in Function:  methods ("classname")
+     Return a cell array containing the names of the methods for the object X or the named class.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Return a cell array containing the names of the methods for the object X or the named class.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+superiorto
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 305
+ -- Built-in Function:  superiorto (CLASS_NAME, ...)
+     When called from a class constructor, mark the object currently constructed as having a higher precedence than CLASS_NAME.  More that one such class can be specified in a single call.  This function may only be called from a class constructor.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+When called from a class constructor, mark the object currently constructed as having a higher precedence than CLASS_NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+inferiorto
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 304
+ -- Built-in Function:  inferiorto (CLASS_NAME, ...)
+     When called from a class constructor, mark the object currently constructed as having a lower precedence than CLASS_NAME.  More that one such class can be specified in a single call.  This function may only be called from a class constructor.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+When called from a class constructor, mark the object currently constructed as having a lower precedence than CLASS_NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+functions
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+ -- Built-in Function:  functions (FCN_HANDLE)
+     Return a struct containing information about the function handle FCN_HANDLE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Return a struct containing information about the function handle FCN_HANDLE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+func2str
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+ -- Built-in Function:  func2str (FCN_HANDLE)
+     Return a string containing the name of the function referenced by the function handle FCN_HANDLE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Return a string containing the name of the function referenced by the function handle FCN_HANDLE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+str2func
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+ -- Built-in Function:  str2func (FCN_NAME)
+     Return a function handle constructed from the string FCN_NAME.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Return a function handle constructed from the string FCN_NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+inline
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 851
+ -- Built-in Function:  inline (STR)
+ -- Built-in Function:  inline (STR, ARG1, ...)
+ -- Built-in Function:  inline (STR, N)
+     Create an inline function from the character string STR.  If called with a single argument, the arguments of the generated function are extracted from the function itself.  The generated function arguments will then be in alphabetical order.  It should be noted that i, and j are ignored as arguments due to the ambiguity between their use as a variable or their use as an inbuilt constant.  All arguments followed by a parenthesis are considered to be functions.
+
+     If the second and subsequent arguments are character strings, they are the names of the arguments of the function.
+
+     If the second argument is an integer N, the arguments are `"x"', `"P1"', ..., `"PN"'.  See also: argnames, formula, vectorize.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Create an inline function from the character string STR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+formula
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 208
+ -- Built-in Function:  formula (FUN)
+     Return a character string representing the inline function FUN.  Note that `char (FUN)' is equivalent to `formula (FUN)'.  See also: argnames, inline, vectorize.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return a character string representing the inline function FUN.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+argnames
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 193
+ -- Built-in Function:  argnames (FUN)
+     Return a cell array of character strings containing the names of the arguments of the inline function FUN.  See also: inline, formula, vectorize.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 106
+Return a cell array of character strings containing the names of the arguments of the inline function FUN.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+vectorize
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Built-in Function:  vectorize (FUN)
+     Create a vectorized version of the inline function FUN by replacing all occurrences of `*', `/', etc., with `.*', `./', etc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+Create a vectorized version of the inline function FUN by replacing all occurrences of `*', `/', etc.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+single
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+ -- Built-in Function:  single (X)
+     Convert X to single precision type.  See also: double.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Convert X to single precision type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+int16
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+ -- Built-in Function:  int16 (X)
+     Convert X to 16-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Convert X to 16-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+int32
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+ -- Built-in Function:  int32 (X)
+     Convert X to 32-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Convert X to 32-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+int64
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+ -- Built-in Function:  int64 (X)
+     Convert X to 64-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Convert X to 64-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+int8
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+ -- Built-in Function:  int8 (X)
+     Convert X to 8-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Convert X to 8-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+list
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+ -- Built-in Function:  list (A1, A2, ...)
+     Create a new list with elements given by the arguments A1, A2, ....
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Create a new list with elements given by the arguments A1, A2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+nth
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 79
+ -- Built-in Function:  nth (LIST, N)
+     Return the N-th element of LIST.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return the N-th element of LIST.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+append
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 429
+ -- Built-in Function:  append (LIST, A1, A2, ...)
+     Return a new list created by appending A1, A2, ..., to LIST.  If any of the arguments to be appended is a list, its elements are appended individually.  For example,
+
+          x = list (1, 2);
+          y = list (3, 4);
+          append (x, y);
+
+     results in the list containing the four elements `(1 2 3 4)', not a list containing the three elements `(1 2 (3 4))'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return a new list created by appending A1, A2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+reverse
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+ -- Built-in Function:  reverse (LIST)
+     Return a new list created by reversing the elements of LIST.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Return a new list created by reversing the elements of LIST.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+splice
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 386
+ -- Built-in Function:  splice (LIST_1, OFFSET, LENGTH, LIST_2)
+     Replace LENGTH elements of LIST_1 beginning at OFFSET with the contents of LIST_2 (if any).  If LENGTH is omitted, all elements from OFFSET to the end of LIST_1 are replaced.  As a special case, if OFFSET is one greater than the length of LIST_1 and LENGTH is 0, splice is equivalent to `append (LIST_1, LIST_2)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+Replace LENGTH elements of LIST_1 beginning at OFFSET with the contents of LIST_2 (if any).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+isnull
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 492
+ -- Built-in Function:  isnull (X)
+     Return 1 if X is a special null matrix, string or single quoted string.  Indexed assignment with such a value as right-hand side should delete array elements.  This function should be used when overloading indexed assignment for user-defined classes instead of `isempty', to distinguish the cases:
+    `A(I) = []'
+          This should delete elements if `I' is nonempty.
+
+    `X = []; A(I) = X'
+          This should give an error if `I' is nonempty.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return 1 if X is a special null matrix, string or single quoted string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+double
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+ -- Built-in Function:  double (X)
+     Convert X to double precision type.  See also: single.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Convert X to double precision type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+struct
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 509
+ -- Built-in Function:  struct ("field", VALUE, "field", VALUE, ...)
+     Create a structure and initialize its value.
+
+     If the values are cell arrays, create a structure array and initialize its values.  The dimensions of each cell array of values must match.  Singleton cells and non-cell values are repeated so that they fill the entire array.  If the cells are empty, create an empty structure array with the specified field names.
+
+     If the argument is an object, return the underlying struct.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Create a structure and initialize its value.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isstruct
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+ -- Built-in Function:  isstruct (EXPR)
+     Return 1 if the value of the expression EXPR is a structure.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Return 1 if the value of the expression EXPR is a structure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+fieldnames
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 207
+ -- Built-in Function:  fieldnames (STRUCT)
+     Return a cell array of strings naming the elements of the structure STRUCT.  It is an error to call `fieldnames' with an argument that is not a structure.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Return a cell array of strings naming the elements of the structure STRUCT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isfield
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 215
+ -- Built-in Function:  isfield (EXPR, NAME)
+     Return true if the expression EXPR is a structure and it includes an element named NAME.  The first argument must be a structure and the second must be a string.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+Return true if the expression EXPR is a structure and it includes an element named NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+cell2struct
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 518
+ -- Built-in Function:  cell2struct (CELL, FIELDS, DIM)
+     Convert CELL to a structure.  The number of fields in FIELDS must match the number of elements in CELL along dimension DIM, that is `numel (FIELDS) == size (CELL, DIM)'.
+
+          A = cell2struct ({'Peter', 'Hannah', 'Robert';
+                             185, 170, 168},
+                           {'Name','Height'}, 1);
+          A(1)
+          => ans =
+                {
+                  Height = 185
+                  Name   = Peter
+                }
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 28
+Convert CELL to a structure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rmfield
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 215
+ -- Built-in Function:  rmfield (S, F)
+     Remove field F from the structure S.  If F is a cell array of character strings or a character array, remove the named fields.  See also: cellstr, iscellstr, setfield.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Remove field F from the structure S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+typeinfo
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Built-in Function:  typeinfo (EXPR)
+     Return the type of the expression EXPR, as a string.  If EXPR is omitted, return an array of strings containing all the currently installed data types.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return the type of the expression EXPR, as a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+uint16
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  uint16 (X)
+     Convert X to unsigned 16-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Convert X to unsigned 16-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+uint32
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  uint32 (X)
+     Convert X to unsigned 32-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Convert X to unsigned 32-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+uint64
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+ -- Built-in Function:  uint64 (X)
+     Convert X to unsigned 64-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Convert X to unsigned 64-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+uint8
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Built-in Function:  uint8 (X)
+     Convert X to unsigned 8-bit integer type.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Convert X to unsigned 8-bit integer type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+nargin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 460
+ -- Built-in Function:  nargin ()
+ -- Built-in Function:  nargin (FCN_NAME)
+     Within a function, return the number of arguments passed to the function.  At the top level, return the number of command line arguments passed to Octave.  If called with the optional argument FCN_NAME, return the maximum number of arguments the named function can accept, or -1 if the function accepts a variable number of arguments.  See also: nargout, varargin, varargout.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Within a function, return the number of arguments passed to the function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nargout
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 622
+ -- Built-in Function:  nargout ()
+ -- Built-in Function:  nargout (FCN_NAME)
+     Within a function, return the number of values the caller expects to receive.  If called with the optional argument FCN_NAME, return the maximum number of values the named function can produce, or -1 if the function can produce a variable number of values.
+
+     For example,
+
+          f ()
+
+     will cause `nargout' to return 0 inside the function `f' and
+
+          [s, t] = f ()
+
+     will cause `nargout' to return 2 inside the function `f'.
+
+     At the top level, `nargout' is undefined.  See also: nargin, varargin, varargout.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Within a function, return the number of values the caller expects to receive.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 19
+max_recursion_depth
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 309
+ -- Built-in Function: VAL = max_recursion_depth ()
+ -- Built-in Function: OLD_VAL = max_recursion_depth (NEW_VAL)
+     Query or set the internal limit on the number of times a function may be called recursively.  If the limit is exceeded, an error message is printed and control returns to the top level.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Query or set the internal limit on the number of times a function may be called recursively.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sizeof
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+ -- Built-in Function:  sizeof (VAL)
+     Return the size of VAL in bytes
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Return the size of VAL in bytes  
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+subsref
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 843
+ -- Built-in Function:  subsref (VAL, IDX)
+     Perform the subscripted element selection operation according to the subscript specified by IDX.
+
+     The subscript IDX is expected to be a structure array with fields `type' and `subs'.  Valid values for `type' are `"()"', `"{}"', and `"."'.  The `subs' field may be either `":"' or a cell array of index values.
+
+     The following example shows how to extract the two first columns of a matrix
+
+          val = magic(3)
+               => val = [ 8   1   6
+                          3   5   7
+                          4   9   2 ]
+          idx.type = "()";
+          idx.subs = {":", 1:2};
+          subsref(val, idx)
+               => [ 8   1
+                    3   5
+                    4   9 ]
+
+     Note that this is the same as writing `val(:,1:2)'.  See also: subsasgn, substruct.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+Perform the subscripted element selection operation according to the subscript specified by IDX.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+subsasgn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 765
+ -- Built-in Function:  subsasgn (VAL, IDX, RHS)
+     Perform the subscripted assignment operation according to the subscript specified by IDX.
+
+     The subscript IDX is expected to be a structure array with fields `type' and `subs'.  Valid values for `type' are `"()"', `"{}"', and `"."'.  The `subs' field may be either `":"' or a cell array of index values.
+
+     The following example shows how to set the two first columns of a 3-by-3 matrix to zero.
+
+          val = magic(3);
+          idx.type = "()";
+          idx.subs = {":", 1:2};
+          subsasgn (val, idx, 0)
+               => [ 0   0   6
+                    0   0   7
+                    0   0   2 ]
+
+     Note that this is the same as writing `val(:,1:2) = 0'.  See also: subsref, substruct.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 89
+Perform the subscripted assignment operation according to the subscript specified by IDX.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+diary
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 479
+ -- Command: diary options
+     Record a list of all commands _and_ the output they produce, mixed together just as you see them on your terminal.  Valid options are:
+
+    `on'
+          Start recording your session in a file called `diary' in your current working directory.
+
+    `off'
+          Stop recording your session in the diary file.
+
+    `FILE'
+          Record your session in the file named FILE.
+
+     With no arguments, `diary' toggles the current diary state.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Record a list of all commands _and_ the output they produce, mixed together just as you see them on your terminal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+more
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Command: more
+ -- Command: more on
+ -- Command: more off
+     Turn output pagination on or off.  Without an argument, `more' toggles the current state.  The current state can be determined via `page_screen_output'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Turn output pagination on or off.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+terminal_size
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 194
+ -- Built-in Function:  terminal_size ()
+     Return a two-element row vector containing the current size of the terminal window in characters (rows and columns).  See also: list_in_columns.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 116
+Return a two-element row vector containing the current size of the terminal window in characters (rows and columns).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+page_output_immediately
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 359
+ -- Built-in Function: VAL = page_output_immediately ()
+ -- Built-in Function: VAL = page_output_immediately (NEW_VAL)
+     Query or set the internal variable that controls whether Octave sends output to the pager as soon as it is available.  Otherwise, Octave buffers its output and waits until just before the prompt is printed to flush it to the pager.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+Query or set the internal variable that controls whether Octave sends output to the pager as soon as it is available.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+page_screen_output
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 429
+ -- Built-in Function: VAL = page_screen_output ()
+ -- Built-in Function: OLD_VAL = page_screen_output (NEW_VAL)
+     Query or set the internal variable that controls whether output intended for the terminal window that is longer than one page is sent through a pager.  This allows you to view one screenful at a time.  Some pagers (such as `less'--see *note Installation::) are also capable of moving backward on the output.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+Query or set the internal variable that controls whether output intended for the terminal window that is longer than one page is sent through a pager.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+PAGER
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 424
+ -- Built-in Function: VAL = PAGER ()
+ -- Built-in Function: OLD_VAL = PAGER (NEW_VAL)
+     Query or set the internal variable that specifies the program to use to display terminal output on your system.  The default value is normally `"less"', `"more"', or `"pg"', depending on what programs are installed on your system.  *Note Installation::.  See also: more, page_screen_output, page_output_immediately, PAGER_FLAGS.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Query or set the internal variable that specifies the program to use to display terminal output on your system.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+PAGER_FLAGS
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 209
+ -- Built-in Function: VAL = PAGER_FLAGS ()
+ -- Built-in Function: OLD_VAL = PAGER_FLAGS (NEW_VAL)
+     Query or set the internal variable that specifies the options to pass to the pager.  See also: PAGER.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Query or set the internal variable that specifies the options to pass to the pager.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+autoload
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 969
+ -- Built-in Function:  autoload (FUNCTION, FILE)
+     Define FUNCTION to autoload from FILE.
+
+     The second argument, FILE, should be an absolute file name or a file name in the same directory as the function or script from which the autoload command was run.  FILE should not depend on the Octave load path.
+
+     Normally, calls to `autoload' appear in PKG_ADD script files that are evaluated when a directory is added to the Octave's load path.  To avoid having to hardcode directory names in FILE, if FILE is in the same directory as the PKG_ADD script then
+
+          autoload ("foo", "bar.oct");
+
+     will load the function `foo' from the file `bar.oct'.  The above when `bar.oct' is not in the same directory or uses like
+
+          autoload ("foo", file_in_loadpath ("bar.oct"))
+
+     are strongly discouraged, as their behavior might be unpredictable.
+
+     With no arguments, return a structure containing the current autoload map.  See also: PKG_ADD.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Define FUNCTION to autoload from FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+mfilename
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 441
+ -- Built-in Function:  mfilename ()
+ -- Built-in Function:  mfilename (`"fullpath"')
+ -- Built-in Function:  mfilename (`"fullpathext"')
+     Return the name of the currently executing file.  At the top-level, return the empty string.  Given the argument `"fullpath"', include the directory part of the file name, but not the extension.  Given the argument `"fullpathext"', include the directory part of the file name and the extension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return the name of the currently executing file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+source
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 201
+ -- Built-in Function:  source (FILE)
+     Parse and execute the contents of FILE.  This is equivalent to executing commands from a script file, but without requiring the file to be named `FILE.m'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Parse and execute the contents of FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+feval
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 666
+ -- Built-in Function:  feval (NAME, ...)
+     Evaluate the function named NAME.  Any arguments after the first are passed on to the named function.  For example,
+
+          feval ("acos", -1)
+               => 3.1416
+
+     calls the function `acos' with the argument `-1'.
+
+     The function `feval' is necessary in order to be able to write functions that call user-supplied functions, because Octave does not have a way to declare a pointer to a function (like C) or to declare a special kind of variable that can be used to hold the name of a function (like `EXTERNAL' in Fortran).  Instead, you must refer to functions by name, and use `feval' to call them.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Evaluate the function named NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+eval
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 724
+ -- Built-in Function:  eval (TRY, CATCH)
+     Parse the string TRY and evaluate it as if it were an Octave program.  If that fails, evaluate the optional string CATCH.  The string TRY is evaluated in the current context, so any results remain available after `eval' returns.
+
+     The following example makes the variable A with the approximate value 3.1416 available.
+
+          eval("a = acos(-1);");
+
+     If an error occurs during the evaluation of TRY the CATCH string is evaluated, as the following example shows:
+
+          eval ('error ("This is a bad example");',
+                'printf ("This error occurred:\n%s\n", lasterr ());');
+               -| This error occurred:
+                  This is a bad example
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Parse the string TRY and evaluate it as if it were an Octave program.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+assignin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 155
+ -- Built-in Function:  assignin (CONTEXT, VARNAME, VALUE)
+     Assign VALUE to VARNAME in context CONTEXT, which may be either `"base"' or `"caller"'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 87
+Assign VALUE to VARNAME in context CONTEXT, which may be either `"base"' or `"caller"'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+evalin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 184
+ -- Built-in Function:  evalin (CONTEXT, TRY, CATCH)
+     Like `eval', except that the expressions are evaluated in the context CONTEXT, which may be either `"caller"' or `"base"'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+Like `eval', except that the expressions are evaluated in the context CONTEXT, which may be either `"caller"' or `"base"'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+pinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 300
+ -- Loadable Function:  pinv (X, TOL)
+     Return the pseudoinverse of X.  Singular values less than TOL are ignored.
+
+     If the second argument is omitted, it is assumed that
+
+          tol = max (size (X)) * sigma_max (X) * eps,
+
+     where `sigma_max (X)' is the maximal singular value of X.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Return the pseudoinverse of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+rats
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 385
+ -- Built-in Function:  rats (X, LEN)
+     Convert X into a rational approximation represented as a string.  You can convert the string back into a matrix as follows:
+
+             r = rats(hilb(4));
+             x = str2num(r)
+
+     The optional second argument defines the maximum length of the string representing the elements of X.  By default LEN is 9.  See also: format, rat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Convert X into a rational approximation represented as a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+disp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 386
+ -- Built-in Function:  disp (X)
+     Display the value of X.  For example,
+
+          disp ("The value of pi is:"), disp (pi)
+
+               -| the value of pi is:
+               -| 3.1416
+
+     Note that the output from `disp' always ends with a newline.
+
+     If an output value is requested, `disp' prints nothing and returns the formatted output in a string.  See also: fdisp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+Display the value of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fdisp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 321
+ -- Built-in Function:  fdisp (FID, X)
+     Display the value of X on the stream FID.  For example,
+
+          fdisp (stdout, "The value of pi is:"), fdisp (stdout, pi)
+
+               -| the value of pi is:
+               -| 3.1416
+
+     Note that the output from `fdisp' always ends with a newline.  See also: disp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Display the value of X on the stream FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+format
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4769
+ -- Command: format
+ -- Command: format options
+     Reset or specify the format of the output produced by `disp' and Octave's normal echoing mechanism.  This command only affects the display of numbers but not how they are stored or computed.  To change the internal representation from the default double use one of the conversion functions such as `single', `uint8', `int64', etc.
+
+     By default, Octave displays 5 significant digits in a human readable form (option `short' paired with `loose' format for matrices).  If `format' is invoked without any options, this default format is restored.
+
+     Valid formats for floating point numbers are listed in the following table.
+
+    `short'
+          Fixed point format with 5 significant figures in a field that is a maximum of 10 characters wide.  (default).
+
+          If Octave is unable to format a matrix so that columns line up on the decimal point and all numbers fit within the maximum field width then it switches to an exponential `e' format.
+
+    `long'
+          Fixed point format with 15 significant figures in a field that is a maximum of 20 characters wide.
+
+          As with the `short' format, Octave will switch to an exponential `e' format if it is unable to format a matrix properly using the current format.
+
+    `short e'
+    `long e'
+          Exponential format.  The number to be represented is split between a mantissa and an exponent (power of 10).  The mantissa has 5 significant digits in the short format and 15 digits in the long format.  For example, with the `short e' format, `pi' is displayed as `3.1416e+00'.
+
+    `short E'
+    `long E'
+          Identical to `short e' or `long e' but displays an uppercase `E' to indicate the exponent.  For example, with the `long E' format, `pi' is displayed as `3.14159265358979E+00'.
+
+    `short g'
+    `long g'
+          Optimally choose between fixed point and exponential format based on the magnitude of the number.  For example, with the `short g' format, `pi .^ [2; 4; 8; 16; 32]' is displayed as
+
+               ans =
+
+                     9.8696
+                     97.409
+                     9488.5
+                 9.0032e+07
+                 8.1058e+15
+
+    `long G'
+    `short G'
+          Identical to `short g' or `long g' but displays an uppercase `E' to indicate the exponent.
+
+    `free'
+    `none'
+          Print output in free format, without trying to line up columns of matrices on the decimal point.  This also causes complex numbers to be formatted as numeric pairs like this `(0.60419, 0.60709)' instead of like this `0.60419 + 0.60709i'.
+
+     The following formats affect all numeric output (floating point and integer types).
+
+    `+'
+    `+ CHARS'
+    `plus'
+    `plus CHARS'
+          Print a `+' symbol for nonzero matrix elements and a space for zero matrix elements.  This format can be very useful for examining the structure of a large sparse matrix.
+
+          The optional argument CHARS specifies a list of 3 characters to use for printing values greater than zero, less than zero and equal to zero.  For example, with the `+ "+-."' format, `[1, 0, -1; -1, 0, 1]' is displayed as
+
+               ans =
+
+               +.-
+               -.+
+
+    `bank'
+          Print in a fixed format with two digits to the right of the decimal point.
+
+    `native-hex'
+          Print the hexadecimal representation of numbers as they are stored in memory.  For example, on a workstation which stores 8 byte real values in IEEE format with the least significant byte first, the value of `pi' when printed in `native-hex' format is `400921fb54442d18'.
+
+    `hex'
+          The same as `native-hex', but always print the most significant byte first.
+
+    `native-bit'
+          Print the bit representation of numbers as stored in memory.  For example, the value of `pi' is
+
+               01000000000010010010000111111011
+               01010100010001000010110100011000
+
+          (shown here in two 32 bit sections for typesetting purposes) when printed in native-bit format on a workstation which stores 8 byte real values in IEEE format with the least significant byte first.
+
+    `bit'
+          The same as `native-bit', but always print the most significant bits first.
+
+    `rat'
+          Print a rational approximation, i.e., values are approximated as the ratio of small integers.  For example, with the `rat' format, `pi' is displayed as `355/113'.
+
+     The following two options affect the display of all matrices.
+
+    `compact'
+          Remove extra blank space around column number labels producing more compact output with more data per page.
+
+    `loose'
+          Insert blank lines above and below column number labels to produce a more readable output with less data per page.  (default).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Reset or specify the format of the output produced by `disp' and Octave's normal echoing mechanism.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+fixed_point_format
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 732
+ -- Built-in Function: VAL = fixed_point_format ()
+ -- Built-in Function: OLD_VAL = fixed_point_format (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will use a scaled format to print matrix values such that the largest element may be written with a single leading digit with the scaling factor is printed on the first line of output.  For example,
+
+          octave:1> logspace (1, 7, 5)'
+          ans =
+
+            1.0e+07  *
+
+            0.00000
+            0.00003
+            0.00100
+            0.03162
+            1.00000
+
+     Notice that first value appears to be zero when it is actually 1.  For this reason, you should be careful when setting `fixed_point_format' to a nonzero value.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 248
+Query or set the internal variable that controls whether Octave will use a scaled format to print matrix values such that the largest element may be written with a single leading digit with the scaling factor is printed on the first line of output.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+print_empty_dimensions
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 365
+ -- Built-in Function: VAL = print_empty_dimensions ()
+ -- Built-in Function: OLD_VAL = print_empty_dimensions (NEW_VAL)
+     Query or set the internal variable that controls whether the dimensions of empty matrices are printed along with the empty matrix symbol, `[]'.  For example, the expression
+
+          zeros (3, 0)
+
+     will print
+
+          ans = [](3x0)
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Query or set the internal variable that controls whether the dimensions of empty matrices are printed along with the empty matrix symbol, `[]'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+split_long_rows
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 846
+ -- Built-in Function: VAL = split_long_rows ()
+ -- Built-in Function: OLD_VAL = split_long_rows (NEW_VAL)
+     Query or set the internal variable that controls whether rows of a matrix may be split when displayed to a terminal window.  If the rows are split, Octave will display the matrix in a series of smaller pieces, each of which can fit within the limits of your terminal width and each set of rows is labeled so that you can easily see which columns are currently being displayed.  For example:
+
+          octave:13> rand (2,10)
+          ans =
+
+           Columns 1 through 6:
+
+            0.75883  0.93290  0.40064  0.43818  0.94958  0.16467
+            0.75697  0.51942  0.40031  0.61784  0.92309  0.40201
+
+           Columns 7 through 10:
+
+            0.90174  0.11854  0.72313  0.73326
+            0.44672  0.94303  0.56564  0.82150
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+Query or set the internal variable that controls whether rows of a matrix may be split when displayed to a terminal window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+output_max_field_width
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 261
+ -- Built-in Function: VAL = output_max_field_width ()
+ -- Built-in Function: OLD_VAL = output_max_field_width (NEW_VAL)
+     Query or set the internal variable that specifies the maximum width of a numeric output field.  See also: format, output_precision.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+Query or set the internal variable that specifies the maximum width of a numeric output field.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+output_precision
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 283
+ -- Built-in Function: VAL = output_precision ()
+ -- Built-in Function: OLD_VAL = output_precision (NEW_VAL)
+     Query or set the internal variable that specifies the minimum number of significant figures to display for numeric output.  See also: format, output_max_field_width.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+Query or set the internal variable that specifies the minimum number of significant figures to display for numeric output.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+struct_levels_to_print
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Built-in Function: VAL = struct_levels_to_print ()
+ -- Built-in Function: OLD_VAL = struct_levels_to_print (NEW_VAL)
+     Query or set the internal variable that specifies the number of structure levels to display.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Query or set the internal variable that specifies the number of structure levels to display.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+silent_functions
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 382
+ -- Built-in Function: VAL = silent_functions ()
+ -- Built-in Function: OLD_VAL = silent_functions (NEW_VAL)
+     Query or set the internal variable that controls whether internal output from a function is suppressed.  If this option is disabled, Octave will display the results produced by evaluating expressions within a function body that are not terminated with a semicolon.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+Query or set the internal variable that controls whether internal output from a function is suppressed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+string_fill_char
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 463
+ -- Built-in Function: VAL = string_fill_char ()
+ -- Built-in Function: OLD_VAL = string_fill_char (NEW_VAL)
+     Query or set the internal variable used to pad all rows of a character matrix to the same length.  It must be a single character.  The default value is `" "' (a single space).  For example,
+
+          string_fill_char ("X");
+          [ "these"; "are"; "strings" ]
+               => "theseXX"
+                  "areXXXX"
+                  "strings"
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Query or set the internal variable used to pad all rows of a character matrix to the same length.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+qr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2115
+ -- Loadable Function: [Q, R, P] = qr (A)
+ -- Loadable Function: [Q, R, P] = qr (A, '0')
+     Compute the QR factorization of A, using standard LAPACK subroutines.  For example, given the matrix `a = [1, 2; 3, 4]',
+
+          [q, r] = qr (a)
+
+     returns
+
+          q =
+
+            -0.31623  -0.94868
+            -0.94868   0.31623
+
+          r =
+
+            -3.16228  -4.42719
+             0.00000  -0.63246
+
+     The `qr' factorization has applications in the solution of least squares problems
+
+          `min norm(A x - b)'
+
+     for overdetermined systems of equations (i.e., `a'  is a tall, thin matrix).  The QR factorization is `q * r = a' where `q' is an orthogonal matrix and `r' is upper triangular.
+
+     If given a second argument of '0', `qr' returns an economy-sized QR factorization, omitting zero rows of R and the corresponding columns of Q.
+
+     If the matrix A is full, the permuted QR factorization `[Q, R, P] = qr (A)' forms the QR factorization such that the diagonal entries of `r' are decreasing in magnitude order.  For example,given the matrix `a = [1, 2; 3, 4]',
+
+          [q, r, p] = qr(a)
+
+     returns
+
+          q =
+
+            -0.44721  -0.89443
+            -0.89443   0.44721
+
+          r =
+
+            -4.47214  -3.13050
+             0.00000   0.44721
+
+          p =
+
+             0  1
+             1  0
+
+     The permuted `qr' factorization `[q, r, p] = qr (a)' factorization allows the construction of an orthogonal basis of `span (a)'.
+
+     If the matrix A is sparse, then compute the sparse QR factorization of A, using CSPARSE.  As the matrix Q is in general a full matrix, this function returns the Q-less factorization R of A, such that `R = chol (A' * A)'.
+
+     If the final argument is the scalar `0' and the number of rows is larger than the number of columns, then an economy factorization is returned.  That is R will have only `size (A,1)' rows.
+
+     If an additional matrix B is supplied, then `qr' returns C, where `C = Q' * B'.  This allows the least squares approximation of `A \ B' to be calculated as
+
+          [C,R] = spqr (A,B)
+          X = R \ C
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Compute the QR factorization of A, using standard LAPACK subroutines.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+qrupdate
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 629
+ -- Loadable Function: [Q1, R1] = qrupdate (Q, R, U, V)
+     Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of A + U*V', where U and V are column vectors (rank-1 update) or matrices with equal number of columns (rank-k update).  Notice that the latter case is done as a sequence of rank-1 updates; thus, for k large enough, it will be both faster and more accurate to recompute the factorization from scratch.
+
+     The QR factorization supplied may be either full (Q is square) or economized (R is square).
+
+     See also: qr, qrinsert, qrdelete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of A + U*V', where U and V are column vectors (rank-1 update) or matrices with equal number of columns (rank-k update).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+qrinsert
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1020
+ -- Loadable Function: [Q1, R1] = qrinsert (Q, R, J, X, ORIENT)
+     Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of [A(:,1:j-1) x A(:,j:n)], where U is a column vector to be inserted into A (if ORIENT is `"col"'), or the QR factorization of [A(1:j-1,:);x;A(:,j:n)], where X is a row vector to be inserted into A (if ORIENT is `"row"').
+
+     The default value of ORIENT is `"col"'.  If ORIENT is `"col"', U may be a matrix and J an index vector resulting in the QR factorization of a matrix B such that B(:,J) gives U and B(:,J) = [] gives A.  Notice that the latter case is done as a sequence of k insertions; thus, for k large enough, it will be both faster and more accurate to recompute the factorization from scratch.
+
+     If ORIENT is `"col"', the QR factorization supplied may be either full (Q is square) or economized (R is square).
+
+     If ORIENT is `"row"', full factorization is needed.  See also: qr, qrupdate, qrdelete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 347
+Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of [A(:,1:j-1) x A(:,j:n)], where U is a column vector to be inserted into A (if ORIENT is `"col"'), or the QR factorization of [A(1:j-1,:);x;A(:,j:n)], where X is a row vector to be inserted into A (if ORIENT is `"row"').
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+qrdelete
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 947
+ -- Loadable Function: [Q1, R1] = qrdelete (Q, R, J, ORIENT)
+     Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of [A(:,1:j-1) A(:,j+1:n)], i.e., A with one column deleted (if ORIENT is "col"), or the QR factorization of [A(1:j-1,:);A(:,j+1:n)], i.e., A with one row deleted (if ORIENT is "row").
+
+     The default value of ORIENT is "col".
+
+     If ORIENT is `"col"', J may be an index vector resulting in the QR factorization of a matrix B such that A(:,J) = [] gives B.  Notice that the latter case is done as a sequence of k deletions; thus, for k large enough, it will be both faster and more accurate to recompute the factorization from scratch.
+
+     If ORIENT is `"col"', the QR factorization supplied may be either full (Q is square) or economized (R is square).
+
+     If ORIENT is `"row"', full factorization is needed.  See also: qr, qrinsert, qrupdate.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 155
+Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of [A(:,1:j-1) A(:,j+1:n)], i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+qrshift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 374
+ -- Loadable Function: [Q1, R1] = qrshift (Q, R, I, J)
+     Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of A(:,p), where p is the permutation
+     `p = [1:i-1, shift(i:j, 1), j+1:n]' if I < J
+     or
+     `p = [1:j-1, shift(j:i,-1), i+1:n]' if J < I.
+     See also: qr, qrinsert, qrdelete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 259
+Given a QR factorization of a real or complex matrix A = Q*R, Q unitary and R upper trapezoidal, return the QR factorization of A(:,p), where p is the permutation  `p = [1:i-1, shift(i:j, 1), j+1:n]' if I < J  or  `p = [1:j-1, shift(j:i,-1), i+1:n]' if J < I.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+quad_options
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1023
+ -- Loadable Function:  quad_options (OPT, VAL)
+     When called with two arguments, this function allows you set options parameters for the function `quad'.  Given one argument, `quad_options' returns the value of the corresponding option.  If no arguments are supplied, the names of all the available options and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance; may be zero for pure relative error test.
+
+    `"relative tolerance"'
+          Nonnegative relative tolerance.  If the absolute tolerance is zero, the relative tolerance must be greater than or equal to `max (50*eps, 0.5e-28)'.
+
+    `"single precision absolute tolerance"'
+          Absolute tolerance for single precision; may be zero for pure relative error test.
+
+    `"single precision relative tolerance"'
+          Nonnegative relative tolerance for single precision.  If the absolute tolerance is zero, the relative tolerance must be greater than or equal to `max (50*eps, 0.5e-28)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+When called with two arguments, this function allows you set options parameters for the function `quad'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+quad
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1366
+ -- Loadable Function: [V, IER, NFUN, ERR] = quad (F, A, B, TOL, SING)
+     Integrate a nonlinear function of one variable using Quadpack.  The first argument is the name of the function, the function handle or the inline function to call to compute the value of the integrand.  It must have the form
+
+          y = f (x)
+
+     where Y and X are scalars.
+
+     The second and third arguments are limits of integration.  Either or both may be infinite.
+
+     The optional argument TOL is a vector that specifies the desired accuracy of the result.  The first element of the vector is the desired absolute tolerance, and the second element is the desired relative tolerance.  To choose a relative test only, set the absolute tolerance to zero.  To choose an absolute test only, set the relative tolerance to zero.
+
+     The optional argument SING is a vector of values at which the integrand is known to be singular.
+
+     The result of the integration is returned in V and IER contains an integer error code (0 indicates a successful integration).  The value of NFUN indicates how many function evaluations were required, and ERR contains an estimate of the error in the solution.
+
+     You can use the function `quad_options' to set optional parameters for `quad'.
+
+     It should be noted that since `quad' is written in Fortran it cannot be called recursively.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Integrate a nonlinear function of one variable using Quadpack.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+qz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1734
+ -- Loadable Function: LAMBDA = qz (A, B)
+     Generalized eigenvalue problem A x = s B x, QZ decomposition.  There are three ways to call this function:
+       1. `lambda = qz(A,B)'
+
+          Computes the generalized eigenvalues LAMBDA of (A - s B).
+
+       2. `[AA, BB, Q, Z, V, W, lambda] = qz (A, B)'
+
+          Computes qz decomposition, generalized eigenvectors, and generalized eigenvalues of (A - sB)
+
+                   A*V = B*V*diag(lambda)
+                   W'*A = diag(lambda)*W'*B
+                   AA = Q'*A*Z, BB = Q'*B*Z
+          with Q and Z orthogonal (unitary)= I
+
+       3. `[AA,BB,Z{, lambda}] = qz(A,B,opt)'
+
+          As in form [2], but allows ordering of generalized eigenpairs for (e.g.) solution of discrete time algebraic Riccati equations.  Form 3 is not available for complex matrices, and does not compute the generalized eigenvectors V, W, nor the orthogonal matrix Q.
+         OPT
+               for ordering eigenvalues of the GEP pencil.  The leading block of the revised pencil contains all eigenvalues that satisfy:
+              `"N"'
+                    = unordered (default)
+
+              `"S"'
+                    = small: leading block has all |lambda| <=1
+
+              `"B"'
+                    = big: leading block has all |lambda| >= 1
+
+              `"-"'
+                    = negative real part: leading block has all eigenvalues in the open left half-plane
+
+              `"+"'
+                    = non-negative real part: leading block has all eigenvalues in the closed right half-plane
+
+     Note: qz performs permutation balancing, but not scaling (see balance).  Order of output arguments was selected for compatibility with MATLAB
+
+     See also: balance, eig, schur.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Generalized eigenvalue problem A x = s B x, QZ decomposition.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+rand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2365
+ -- Loadable Function:  rand (X)
+ -- Loadable Function:  rand (N, M)
+ -- Loadable Function:  rand ("state", X)
+ -- Loadable Function:  rand ("seed", X)
+     Return a matrix with random elements uniformly distributed on the interval (0, 1).  The arguments are handled the same as the arguments for `eye'.
+
+     You can query the state of the random number generator using the form
+
+          v = rand ("state")
+
+     This returns a column vector V of length 625.  Later, you can restore the random number generator to the state V using the form
+
+          rand ("state", v)
+
+     You may also initialize the state vector from an arbitrary vector of length <= 625 for V.  This new state will be a hash based on the value of V, not V itself.
+
+     By default, the generator is initialized from `/dev/urandom' if it is available, otherwise from cpu time, wall clock time and the current fraction of a second.
+
+     To compute the pseudo-random sequence, `rand' uses the Mersenne Twister with a period of 2^19937-1 (See M. Matsumoto and T. Nishimura, `Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator', ACM Trans. on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998, `http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html').  Do *not* use for cryptography without securely hashing several returned values together, otherwise the generator state can be learned after reading 624 consecutive values.
+
+     Older versions of Octave used a different random number generator.  The new generator is used by default as it is significantly faster than the old generator, and produces random numbers with a significantly longer cycle time.  However, in some circumstances it might be desirable to obtain the same random sequences as used by the old generators.  To do this the keyword "seed" is used to specify that the old generators should be use, as in
+
+          rand ("seed", val)
+
+     which sets the seed of the generator to VAL.  The seed of the generator can be queried with
+
+          s = rand ("seed")
+
+     However, it should be noted that querying the seed will not cause `rand' to use the old generators, only setting the seed will.  To cause `rand' to once again use the new generators, the keyword "state" should be used to reset the state of the `rand'.  See also: randn, rande, randg, randp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+Return a matrix with random elements uniformly distributed on the interval (0, 1).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+randn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 659
+ -- Loadable Function:  randn (X)
+ -- Loadable Function:  randn (N, M)
+ -- Loadable Function:  randn ("state", X)
+ -- Loadable Function:  randn ("seed", X)
+     Return a matrix with normally distributed pseudo-random elements having zero mean and variance one.  The arguments are handled the same as the arguments for `rand'.
+
+     By default, `randn' uses the Marsaglia and Tsang "Ziggurat technique" to transform from a uniform to a normal distribution.  (G. Marsaglia and W.W. Tsang, `Ziggurat method for generating random variables', J. Statistical Software, vol 5, 2000, `http://www.jstatsoft.org/v05/i08/')
+
+     See also: rand, rande, randg, randp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Return a matrix with normally distributed pseudo-random elements having zero mean and variance one.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+rande
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 622
+ -- Loadable Function:  rande (X)
+ -- Loadable Function:  rande (N, M)
+ -- Loadable Function:  rande ("state", X)
+ -- Loadable Function:  rande ("seed", X)
+     Return a matrix with exponentially distributed random elements.  The arguments are handled the same as the arguments for `rand'.
+
+     By default, `randn' uses the Marsaglia and Tsang "Ziggurat technique" to transform from a uniform to a exponential distribution.  (G. Marsaglia and W.W. Tsang, `Ziggurat method for generating random variables', J. Statistical Software, vol 5, 2000, `http://www.jstatsoft.org/v05/i08/') See also: rand, randn, randg, randp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return a matrix with exponentially distributed random elements.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+randg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1559
+ -- Loadable Function:  randg (A, X)
+ -- Loadable Function:  randg (A, N, M)
+ -- Loadable Function:  randg ("state", X)
+ -- Loadable Function:  randg ("seed", X)
+     Return a matrix with `gamma(A,1)' distributed random elements.  The arguments are handled the same as the arguments for `rand', except for the argument A.
+
+     This can be used to generate many distributions:
+
+    `gamma (a, b)' for `a > -1', `b > 0'
+               r = b * randg (a)
+
+    `beta (a, b)' for `a > -1', `b > -1'
+               r1 = randg (a, 1)
+               r = r1 / (r1 + randg (b, 1))
+
+    `Erlang (a, n)'
+               r = a * randg (n)
+
+    `chisq (df)' for `df > 0'
+               r = 2 * randg (df / 2)
+
+    `t(df)' for `0 < df < inf' (use randn if df is infinite)
+               r = randn () / sqrt (2 * randg (df / 2) / df)
+
+    `F (n1, n2)' for `0 < n1', `0 < n2'
+               ## r1 equals 1 if n1 is infinite
+               r1 = 2 * randg (n1 / 2) / n1
+               ## r2 equals 1 if n2 is infinite
+               r2 = 2 * randg (n2 / 2) / n2
+               r = r1 / r2
+
+    negative `binomial (n, p)' for `n > 0', `0 < p <= 1'
+               r = randp ((1 - p) / p * randg (n))
+
+    non-central `chisq (df, L)', for `df >= 0' and `L > 0'
+          (use chisq if `L = 0')
+               r = randp (L / 2)
+               r(r > 0) = 2 * randg (r(r > 0))
+               r(df > 0) += 2 * randg (df(df > 0)/2)
+
+    `Dirichlet (a1, ... ak)'
+               r = (randg (a1), ..., randg (ak))
+               r = r / sum (r)
+     See also: rand, randn, rande, randp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Return a matrix with `gamma(A,1)' distributed random elements.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+randp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1350
+ -- Loadable Function:  randp (L, X)
+ -- Loadable Function:  randp (L, N, M)
+ -- Loadable Function:  randp ("state", X)
+ -- Loadable Function:  randp ("seed", X)
+     Return a matrix with Poisson distributed random elements with mean value parameter given by the first argument, L.  The arguments are handled the same as the arguments for `rand', except for the argument L.
+
+     Five different algorithms are used depending on the range of L and whether or not L is a scalar or a matrix.
+
+    For scalar L <= 12, use direct method.
+          Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.
+
+    For scalar L > 12, use rejection method.[1]
+          Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.
+
+    For matrix L <= 10, use inversion method.[2]
+          Stadlober E., et al., WinRand source code, available via FTP.
+
+    For matrix L > 10, use patchwork rejection method.
+          Stadlober E., et al., WinRand source code, available via FTP, or H. Zechner, 'Efficient sampling from continuous and discrete unimodal distributions', Doctoral Dissertation, 156pp., Technical University Graz, Austria, 1994.
+
+    For L > 1e8, use normal approximation.
+          L. Montanet, et al., 'Review of Particle Properties', Physical Review D 50 p1284, 1994
+     See also: rand, randn, rande, randg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Return a matrix with Poisson distributed random elements with mean value parameter given by the first argument, L.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+rcond
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 392
+ -- Loadable Function: C = rcond (A)
+     Compute the 1-norm estimate of the reciprocal condition as returned by LAPACK.  If the matrix is well-conditioned then C will be near 1 and if the matrix is poorly conditioned it will be close to zero.
+
+     The matrix A must not be sparse.  If the matrix is sparse then `condest (A)' or `rcond (full (A))' should be used instead.  See also: inv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+Compute the 1-norm estimate of the reciprocal condition as returned by LAPACK.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+regexp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8476
+ -- Loadable Function: [S, E, TE, M, T, NM] = regexp (STR, PAT)
+ -- Loadable Function: [...] = regexp (STR, PAT, OPTS, ...)
+     Regular expression string matching.  Matches PAT in STR and returns the position and matching substrings or empty values if there are none.
+
+     The matched pattern PAT can include any of the standard regex operators, including:
+
+    `.'
+          Match any character
+
+    `* + ? {}'
+          Repetition operators, representing
+         `*'
+               Match zero or more times
+
+         `+'
+               Match one or more times
+
+         `?'
+               Match zero or one times
+
+         `{}'
+               Match range operator, which is of the form `{N}' to match exactly N times, `{M,}' to match M or more times, `{M,N}' to match between M and N times.
+
+    `[...] [^...]'
+          List operators, where for example `[ab]c' matches `ac' and `bc'
+
+    `()'
+          Grouping operator
+
+    `|'
+          Alternation operator.  Match one of a choice of regular expressions.  The alternatives must be delimited by the grouping operator `()' above
+
+    `^ $'
+          Anchoring operator.  `^' matches the start of the string STR and `$' the end
+
+     In addition the following escaped characters have special meaning.  It should be noted that it is recommended to quote PAT in single quotes rather than double quotes, to avoid the escape sequences being interpreted by Octave before being passed to `regexp'.
+
+    `\b'
+          Match a word boundary
+
+    `\B'
+          Match within a word
+
+    `\w'
+          Matches any word character
+
+    `\W'
+          Matches any non word character
+
+    `\<'
+          Matches the beginning of a word
+
+    `\>'
+          Matches the end of a word
+
+    `\s'
+          Matches any whitespace character
+
+    `\S'
+          Matches any non whitespace character
+
+    `\d'
+          Matches any digit
+
+    `\D'
+          Matches any non-digit
+
+     The outputs of `regexp' by default are in the order as given below
+
+    S
+          The start indices of each of the matching substrings
+
+    E
+          The end indices of each matching substring
+
+    TE
+          The extents of each of the matched token surrounded by `(...)' in PAT.
+
+    M
+          A cell array of the text of each match.
+
+    T
+          A cell array of the text of each token matched.
+
+    NM
+          A structure containing the text of each matched named token, with the name being used as the fieldname.  A named token is denoted as `(?<name>...)'
+
+     Particular output arguments or the order of the output arguments can be selected by additional OPTS arguments.  These are strings and the correspondence between the output arguments and the optional argument are
+
+                                                                                                                                                                                                                  'start'                                                                                                                                                                                                                                                                                                            S                                                                                                                                                                                                                                                                                                                  
+                                                                                                                                                                                                                  'end'                                                                                                                                                                                                                                                                                                              E                                                                                                                                                                                                                                                                                                                  
+                                                                                                                                                                                                                  'tokenExtents'                                                                                                                                                                                                                                                                                                     TE                                                                                                                                                                                                                                                                                                                 
+                                                                                                                                                                                                                  'match'                                                                                                                                                                                                                                                                                                            M                                                                                                                                                                                                                                                                                                                  
+                                                                                                                                                                                                                  'tokens'                                                                                                                                                                                                                                                                                                           T                                                                                                                                                                                                                                                                                                                  
+                                                                                                                                                                                                                  'names'                                                                                                                                                                                                                                                                                                            NM                                                                                                                                                                                                                                                                                                                 
+
+     A further optional argument is 'once', that limits the number of returned matches to the first match.  Additional arguments are
+
+    matchcase
+          Make the matching case sensitive.
+
+    ignorecase
+          Make the matching case insensitive.
+
+    stringanchors
+          Match the anchor characters at the beginning and end of the string.
+
+    lineanchors
+          Match the anchor characters at the beginning and end of the line.
+
+    dotall
+          The character `.' matches the newline character.
+
+    dotexceptnewline
+          The character `.' matches all but the newline character.
+
+    freespacing
+          The pattern can include arbitrary whitespace and comments starting with `#'.
+
+    literalspacing
+          The pattern is taken literally.
+     See also: regexpi, regexprep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Regular expression string matching.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+regexpi
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 335
+ -- Loadable Function: [S, E, TE, M, T, NM] = regexpi (STR, PAT)
+ -- Loadable Function: [...] = regexpi (STR, PAT, OPTS, ...)
+     Case insensitive regular expression string matching.  Matches PAT in STR and returns the position and matching substrings or empty values if there are none.  *Note regexp: doc-regexp, for more details
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Case insensitive regular expression string matching.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+regexprep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1203
+ -- Loadable Function: STRING = regexprep (STRING, PAT, REPSTR, OPTIONS)
+     Replace matches of PAT in  STRING with REPSTR.
+
+     The replacement can contain `$i', which substitutes for the ith set of parentheses in the match string.  E.g.,
+
+             regexprep("Bill Dunn",'(\w+) (\w+)','$2, $1')
+     returns "Dunn, Bill"
+
+     OPTIONS may be zero or more of
+    `once'
+          Replace only the first occurrence of PAT in the result.
+
+    `warnings'
+          This option is present for compatibility but is ignored.
+
+    `ignorecase or matchcase'
+          Ignore case for the pattern matching (see `regexpi').  Alternatively, use (?i) or (?-i) in the pattern.
+
+    `lineanchors and stringanchors'
+          Whether characters ^ and $ match the beginning and ending of lines.  Alternatively, use (?m) or (?-m) in the pattern.
+
+    `dotexceptnewline and dotall'
+          Whether . matches newlines in the string.  Alternatively, use (?s) or (?-s) in the pattern.
+
+    `freespacing or literalspacing'
+          Whether whitespace and # comments can be used to make the regular expression more readable.  Alternatively, use (?x) or (?-x) in the pattern.
+
+     See also: regexp,regexpi,strrep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Replace matches of PAT in STRING with REPSTR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+schur
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1362
+ -- Loadable Function: S = schur (A)
+ -- Loadable Function: [U, S] = schur (A, OPT)
+     The Schur decomposition is used to compute eigenvalues of a square matrix, and has applications in the solution of algebraic Riccati equations in control (see `are' and `dare').  `schur' always returns `s = u' * a * u' where `u'  is a unitary matrix (`u'* u' is identity) and `s' is upper triangular.  The eigenvalues of `a' (and `s') are the diagonal elements of `s'.  If the matrix `a' is real, then the real Schur decomposition is computed, in which the matrix `u' is orthogonal and `s' is block upper triangular with blocks of size at most `2 x 2' along the diagonal.  The diagonal elements of `s' (or the eigenvalues of the `2 x 2' blocks, when appropriate) are the eigenvalues of `a' and `s'.
+
+     The eigenvalues are optionally ordered along the diagonal according to the value of `opt'.  `opt = "a"' indicates that all eigenvalues with negative real parts should be moved to the leading block of `s' (used in `are'), `opt = "d"' indicates that all eigenvalues with magnitude less than one should be moved to the leading block of `s' (used in `dare'), and `opt = "u"', the default, indicates that no ordering of eigenvalues should occur.  The leading `k' columns of `u' always span the `a'-invariant subspace corresponding to the `k' leading eigenvalues of `s'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 177
+The Schur decomposition is used to compute eigenvalues of a square matrix, and has applications in the solution of algebraic Riccati equations in control (see `are' and `dare').
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+SIG
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Built-in Function:  SIG ()
+     Return a structure containing Unix signal names and their defined values.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Return a structure containing Unix signal names and their defined values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+debug_on_interrupt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 398
+ -- Built-in Function: VAL = debug_on_interrupt ()
+ -- Built-in Function: OLD_VAL = debug_on_interrupt (NEW_VAL)
+     Query or set the internal variable that controls whether Octave will try to enter debugging mode when it receives an interrupt signal (typically generated with `C-c').  If a second interrupt signal is received before reaching the debugging mode, a normal interrupt will occur.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 167
+Query or set the internal variable that controls whether Octave will try to enter debugging mode when it receives an interrupt signal (typically generated with `C-c').
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+sighup_dumps_octave_core
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 291
+ -- Built-in Function: VAL = sighup_dumps_octave_core ()
+ -- Built-in Function: OLD_VAL = sighup_dumps_octave_core (NEW_VAL)
+     Query or set the internal variable that controls whether Octave tries to save all current variables to the file "octave-core" if it receives a hangup signal.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 157
+Query or set the internal variable that controls whether Octave tries to save all current variables to the file "octave-core" if it receives a hangup signal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+sigterm_dumps_octave_core
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 296
+ -- Built-in Function: VAL = sigterm_dumps_octave_core ()
+ -- Built-in Function: OLD_VAL = sigterm_dumps_octave_core (NEW_VAL)
+     Query or set the internal variable that controls whether Octave tries to save all current variables to the file "octave-core" if it receives a terminate signal.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 160
+Query or set the internal variable that controls whether Octave tries to save all current variables to the file "octave-core" if it receives a terminate signal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+issparse
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Loadable Function:  issparse (EXPR)
+     Return 1 if the value of the expression EXPR is a sparse matrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return 1 if the value of the expression EXPR is a sparse matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sparse
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1398
+ -- Loadable Function: S = sparse (A)
+ -- Loadable Function: S = sparse (I, J, SV, M, N, NZMAX)
+ -- Loadable Function: S = sparse (I, J, SV)
+ -- Loadable Function: S = sparse (I, J, S, M, N, "unique")
+ -- Loadable Function: S = sparse (M, N)
+     Create a sparse matrix from the full matrix or row, column, value triplets.  If A is a full matrix, convert it to a sparse matrix representation, removing all zero values in the process.
+
+     Given the integer index vectors I and J, a 1-by-`nnz' vector of real of complex values SV, overall dimensions M and N of the sparse matrix.  The argument `nzmax' is ignored but accepted for compatibility with MATLAB.  If M or N are not specified their values are derived from the maximum index in the vectors I and J as given by `M = max (I)', `N = max (J)'.
+
+     *Note*: if multiple values are specified with the same I, J indices, the corresponding values in S will be added.
+
+     The following are all equivalent:
+
+          s = sparse (i, j, s, m, n)
+          s = sparse (i, j, s, m, n, "summation")
+          s = sparse (i, j, s, m, n, "sum")
+
+     Given the option "unique". if more than two values are specified for the same I, J indices, the last specified value will be used.
+
+     `sparse(M, N)' is equivalent to `sparse ([], [], [], M, N, 0)'
+
+     If any of SV, I or J are scalars, they are expanded to have a common size.  See also: full.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Create a sparse matrix from the full matrix or row, column, value triplets.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spparms
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2274
+ -- Loadable Function:   spparms ()
+ -- Loadable Function: VALS = spparms ()
+ -- Loadable Function: [KEYS, VALS] = spparms ()
+ -- Loadable Function: VAL = spparms (KEY)
+ -- Loadable Function:   spparms (VALS)
+ -- Loadable Function:   spparms ('defaults')
+ -- Loadable Function:   spparms ('tight')
+ -- Loadable Function:   spparms (KEY, VAL)
+     Sets or displays the parameters used by the sparse solvers and factorization functions.  The first four calls above get information about the current settings, while the others change the current settings.  The parameters are stored as pairs of keys and values, where the values are all floats and the keys are one of the following strings:
+
+    `spumoni'
+          Printing level of debugging information of the solvers (default 0)
+
+    `ths_rel'
+          Included for compatibility.  Not used.  (default 1)
+
+    `ths_abs'
+          Included for compatibility.  Not used.  (default 1)
+
+    `exact_d'
+          Included for compatibility.  Not used.  (default 0)
+
+    `supernd'
+          Included for compatibility.  Not used.  (default 3)
+
+    `rreduce'
+          Included for compatibility.  Not used.  (default 3)
+
+    `wh_frac'
+          Included for compatibility.  Not used.  (default 0.5)
+
+    `autommd'
+          Flag whether the LU/QR and the '\' and '/' operators will automatically use the sparsity preserving mmd functions (default 1)
+
+    `autoamd'
+          Flag whether the LU and the '\' and '/' operators will automatically use the sparsity preserving amd functions (default 1)
+
+    `piv_tol'
+          The pivot tolerance of the UMFPACK solvers (default 0.1)
+
+    `sym_tol'
+          The pivot tolerance of the UMFPACK symmetric solvers (default 0.001)
+
+    `bandden'
+          The density of non-zero elements in a banded matrix before it is treated by the LAPACK banded solvers (default 0.5)
+
+    `umfpack'
+          Flag whether the UMFPACK or mmd solvers are used for the LU, '\' and '/' operations (default 1)
+
+     The value of individual keys can be set with `spparms (KEY, VAL)'.  The default values can be restored with the special keyword 'defaults'.  The special keyword 'tight' can be used to set the mmd solvers to attempt for a sparser solution at the potential cost of longer running time.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 87
+Sets or displays the parameters used by the sparse solvers and factorization functions.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+sqrtm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 322
+ -- Loadable Function: [RESULT, ERROR_ESTIMATE] = sqrtm (A)
+     Compute the matrix square root of the square matrix A.
+
+     Ref: Nicholas J. Higham.  A new sqrtm for MATLAB.  Numerical Analysis Report No. 336, Manchester Centre for Computational Mathematics, Manchester, England, January 1999.  See also: expm, logm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Compute the matrix square root of the square matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+char
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1120
+ -- Built-in Function:  char (X)
+ -- Built-in Function:  char (X, ...)
+ -- Built-in Function:  char (S1, S2, ...)
+ -- Built-in Function:  char (CELL_ARRAY)
+     Create a string array from one or more numeric matrices, character matrices, or cell arrays.  Arguments are concatenated vertically.  The returned values are padded with blanks as needed to make each row of the string array have the same length.  Empty input strings are significant and will concatenated in the output.
+
+     For numerical input, each element is converted to the corresponding ASCII character.  A range error results if an input is outside the ASCII range (0-255).
+
+     For cell arrays, each element is concatenated separately.  Cell arrays converted through `char' can mostly be converted back with `cellstr'.  For example,
+
+          char ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
+               => ["abc    "
+                   "       "
+                   "98     "
+                   "99     "
+                   "d      "
+                   "str1   "
+                   "half   "]
+     See also: strvcat, cellstr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Create a string array from one or more numeric matrices, character matrices, or cell arrays.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+strvcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1120
+ -- Built-in Function:  strvcat (X)
+ -- Built-in Function:  strvcat (X, ...)
+ -- Built-in Function:  strvcat (S1, S2, ...)
+ -- Built-in Function:  strvcat (CELL_ARRAY)
+     Create a character array from one or more numeric matrices, character matrices, or cell arrays.  Arguments are concatenated vertically.  The returned values are padded with blanks as needed to make each row of the string array have the same length.  Unlike `char', empty strings are removed and will not appear in the output.
+
+     For numerical input, each element is converted to the corresponding ASCII character.  A range error results if an input is outside the ASCII range (0-255).
+
+     For cell arrays, each element is concatenated separately.  Cell arrays converted through `strvcat' can mostly be converted back with `cellstr'.  For example,
+
+          strvcat ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
+               => ["abc    "
+                   "98     "
+                   "99     "
+                   "d      "
+                   "str1   "
+                   "half   "]
+     See also: char, strcat, cstrcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Create a character array from one or more numeric matrices, character matrices, or cell arrays.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ischar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+ -- Built-in Function:  ischar (A)
+     Return 1 if A is a character array.  Otherwise, return 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Return 1 if A is a character array.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+strcmp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 671
+ -- Built-in Function:  strcmp (S1, S2)
+     Return 1 if the character strings S1 and S2 are the same, and 0 otherwise.
+
+     If either S1 or S2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.
+
+     *Caution:* For compatibility with MATLAB, Octave's strcmp function returns 1 if the character strings are equal, and 0 otherwise.  This is just the opposite of the corresponding C library function.  See also: strcmpi, strncmp, strncmpi.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Return 1 if the character strings S1 and S2 are the same, and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+strncmp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 829
+ -- Built-in Function:  strncmp (S1, S2, N)
+     Return 1 if the first N characters of strings S1 and S2 are the same, and 0 otherwise.
+
+          strncmp ("abce", "abcd", 3)
+               => 1
+
+     If either S1 or S2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.
+
+          strncmp ("abce", {"abcd", "bca", "abc"}, 3)
+               => [1, 0, 1]
+
+     *Caution:* For compatibility with MATLAB, Octave's strncmp function returns 1 if the character strings are equal, and 0 otherwise.  This is just the opposite of the corresponding C library function.  See also: strncmpi, strcmp, strcmpi.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Return 1 if the first N characters of strings S1 and S2 are the same, and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+list_in_columns
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 971
+ -- Built-in Function:  list_in_columns (ARG, WIDTH)
+     Return a string containing the elements of ARG listed in columns with an overall maximum width of WIDTH.  The argument ARG must be a cell array of character strings or a character array.  If WIDTH is not specified, the width of the terminal screen is used.  Newline characters are used to break the lines in the output string.  For example:
+
+          list_in_columns ({"abc", "def", "ghijkl", "mnop", "qrs", "tuv"}, 20)
+               => ans = abc     mnop
+                      def     qrs
+                      ghijkl  tuv
+
+          whos ans
+               =>
+               Variables in the current scope:
+
+                 Attr Name        Size                     Bytes  Class
+                 ==== ====        ====                     =====  =====
+                      ans         1x37                        37  char
+
+               Total is 37 elements using 37 bytes
+
+     See also: terminal_size.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+Return a string containing the elements of ARG listed in columns with an overall maximum width of WIDTH.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+svd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1030
+ -- Loadable Function: S = svd (A)
+ -- Loadable Function: [U, S, V] = svd (A)
+     Compute the singular value decomposition of A
+
+          A = U*S*V'
+
+     The function `svd' normally returns the vector of singular values.  If asked for three return values, it computes U, S, and V.  For example,
+
+          svd (hilb (3))
+
+     returns
+
+          ans =
+
+            1.4083189
+            0.1223271
+            0.0026873
+
+     and
+
+          [u, s, v] = svd (hilb (3))
+
+     returns
+
+          u =
+
+            -0.82704   0.54745   0.12766
+            -0.45986  -0.52829  -0.71375
+            -0.32330  -0.64901   0.68867
+
+          s =
+
+            1.40832  0.00000  0.00000
+            0.00000  0.12233  0.00000
+            0.00000  0.00000  0.00269
+
+          v =
+
+            -0.82704   0.54745   0.12766
+            -0.45986  -0.52829  -0.71375
+            -0.32330  -0.64901   0.68867
+
+     If given a second argument, `svd' returns an economy-sized decomposition, eliminating the unnecessary rows or columns of U or V.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Compute the singular value decomposition of A 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+syl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 280
+ -- Loadable Function: X = syl (A, B, C)
+     Solve the Sylvester equation
+
+          A X + X B + C = 0
+     using standard LAPACK subroutines.  For example,
+
+          syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
+               => [ -0.50000, -0.66667; -0.66667, -0.50000 ]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+Solve the Sylvester equation 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+symbfact
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1135
+ -- Loadable Function: [COUNT, H, PARENT, POST, R] = symbfact (S, TYP, MODE)
+     Performs a symbolic factorization analysis on the sparse matrix S.  Where
+
+    S
+          S is a complex or real sparse matrix.
+
+    TYP
+          Is the type of the factorization and can be one of
+
+         `sym'
+               Factorize S.  This is the default.
+
+         `col'
+               Factorize `S' * S'.
+
+         `row'
+               Factorize `S * S''.
+
+         `lo'
+               Factorize `S''
+
+    MODE
+          The default is to return the Cholesky factorization for R, and if MODE is 'L', the conjugate transpose of the Cholesky factorization is returned.  The conjugate transpose version is faster and uses less memory, but returns the same values for COUNT, H, PARENT and POST outputs.
+
+     The output variables are
+
+    COUNT
+          The row counts of the Cholesky factorization as determined by TYP.
+
+    H
+          The height of the elimination tree.
+
+    PARENT
+          The elimination tree itself.
+
+    POST
+          A sparse boolean matrix whose structure is that of the Cholesky factorization as determined by TYP.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Performs a symbolic factorization analysis on the sparse matrix S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+symrcm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 923
+ -- Loadable Function: P = symrcm (S)
+     Symmetric reverse Cuthill-McKee permutation of S.  Return a permutation vector P such that `S (P, P)' tends to have its diagonal elements closer to the diagonal than S.  This is a good preordering for LU or Cholesky factorization of matrices that come from 'long, skinny' problems.  It works for both symmetric and asymmetric S.
+
+     The algorithm represents a heuristic approach to the NP-complete bandwidth minimization problem.  The implementation is based in the descriptions found in
+
+     E. Cuthill, J. McKee: Reducing the Bandwidth of Sparse Symmetric Matrices. Proceedings of the 24th ACM National Conference, 157-172 1969, Brandon Press, New Jersey.
+
+     Alan George, Joseph W. H. Liu: Computer Solution of Large Sparse Positive Definite Systems, Prentice Hall Series in Computational Mathematics, ISBN 0-13-165274-5, 1981.
+
+     See also: colperm, colamd, symamd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Symmetric reverse Cuthill-McKee permutation of S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+ignore_function_time_stamp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 826
+ -- Built-in Function: VAL = ignore_function_time_stamp ()
+ -- Built-in Function: OLD_VAL = ignore_function_time_stamp (NEW_VAL)
+     Query or set the internal variable that controls whether Octave checks the time stamp on files each time it looks up functions defined in function files.  If the internal variable is set to `"system"', Octave will not automatically recompile function files in subdirectories of `OCTAVE-HOME/lib/VERSION' if they have changed since they were last compiled, but will recompile other function files in the search path if they change.  If set to `"all"', Octave will not recompile any function files unless their definitions are removed with `clear'.  If set to "none", Octave will always check time stamps on files to determine whether functions defined in function files need to recompiled.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 153
+Query or set the internal variable that controls whether Octave checks the time stamp on files each time it looks up functions defined in function files.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+dup2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+ -- Built-in Function: [FID, MSG] = dup2 (OLD, NEW)
+     Duplicate a file descriptor.
+
+     If successful, FID is greater than zero and contains the new file ID.  Otherwise, FID is negative and MSG contains a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 28
+Duplicate a file descriptor.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+exec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 485
+ -- Built-in Function: [ERR, MSG] = exec (FILE, ARGS)
+     Replace current process with a new process.  Calling `exec' without first calling `fork' will terminate your current Octave process and replace it with the program named by FILE.  For example,
+
+          exec ("ls" "-l")
+
+     will run `ls' and return you to your shell prompt.
+
+     If successful, `exec' does not return.  If `exec' does return, ERR will be nonzero, and MSG will contain a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Replace current process with a new process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+popen2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1255
+ -- Built-in Function: [IN, OUT, PID] = popen2 (COMMAND, ARGS)
+     Start a subprocess with two-way communication.  The name of the process is given by COMMAND, and ARGS is an array of strings containing options for the command.  The file identifiers for the input and output streams of the subprocess are returned in IN and OUT.  If execution of the command is successful, PID contains the process ID of the subprocess.  Otherwise, PID is -1.
+
+     For example,
+
+          [in, out, pid] = popen2 ("sort", "-r");
+          fputs (in, "these\nare\nsome\nstrings\n");
+          fclose (in);
+          EAGAIN = errno ("EAGAIN");
+          done = false;
+          do
+            s = fgets (out);
+            if (ischar (s))
+              fputs (stdout, s);
+            elseif (errno () == EAGAIN)
+              sleep (0.1);
+              fclear (out);
+            else
+              done = true;
+            endif
+          until (done)
+          fclose (out);
+          waitpid (pid);
+               -| these
+               -| strings
+               -| some
+               -| are
+
+     Note that `popen2', unlike `popen', will not "reap" the child process.  If you don't use `waitpid' to check the child's exit status, it will linger until Octave exits.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Start a subprocess with two-way communication.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fcntl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1288
+ -- Built-in Function: [ERR, MSG] = fcntl (FID, REQUEST, ARG)
+     Change the properties of the open file FID.  The following values may be passed as REQUEST:
+
+    `F_DUPFD'
+          Return a duplicate file descriptor.
+
+    `F_GETFD'
+          Return the file descriptor flags for FID.
+
+    `F_SETFD'
+          Set the file descriptor flags for FID.
+
+    `F_GETFL'
+          Return the file status flags for FID.  The following codes may be returned (some of the flags may be undefined on some systems).
+
+         `O_RDONLY'
+               Open for reading only.
+
+         `O_WRONLY'
+               Open for writing only.
+
+         `O_RDWR'
+               Open for reading and writing.
+
+         `O_APPEND'
+               Append on each write.
+
+         `O_CREAT'
+               Create the file if it does not exist.
+
+         `O_NONBLOCK'
+               Nonblocking mode.
+
+         `O_SYNC'
+               Wait for writes to complete.
+
+         `O_ASYNC'
+               Asynchronous I/O.
+
+    `F_SETFL'
+          Set the file status flags for FID to the value specified by ARG.  The only flags that can be changed are `O_APPEND' and `O_NONBLOCK'.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Change the properties of the open file FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fork
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 624
+ -- Built-in Function: [PID, MSG] = fork ()
+     Create a copy of the current process.
+
+     Fork can return one of the following values:
+
+    > 0
+          You are in the parent process.  The value returned from `fork' is the process id of the child process.  You should probably arrange to wait for any child processes to exit.
+
+    0
+          You are in the child process.  You can call `exec' to start another process.  If that fails, you should probably call `exit'.
+
+    < 0
+          The call to `fork' failed for some reason.  You must take evasive action.  A system dependent error message will be waiting in MSG.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Create a copy of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+getpgrp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+ -- Built-in Function: pgid = getpgrp ()
+     Return the process group id of the current process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Return the process group id of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+getpid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+ -- Built-in Function: pid = getpid ()
+     Return the process id of the current process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Return the process id of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+getppid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+ -- Built-in Function: pid = getppid ()
+     Return the process id of the parent process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Return the process id of the parent process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+getegid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+ -- Built-in Function: egid = getegid ()
+     Return the effective group id of the current process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Return the effective group id of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+getgid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+ -- Built-in Function: gid = getgid ()
+     Return the real group id of the current process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Return the real group id of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+geteuid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+ -- Built-in Function: euid = geteuid ()
+     Return the effective user id of the current process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return the effective user id of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+getuid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+ -- Built-in Function: uid = getuid ()
+     Return the real user id of the current process.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Return the real user id of the current process.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+kill
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 565
+ -- Built-in Function: [ERR, MSG] = kill (PID, SIG)
+     Send signal SIG to process PID.
+
+     If PID is positive, then signal SIG is sent to PID.
+
+     If PID is 0, then signal SIG is sent to every process in the process group of the current process.
+
+     If PID is -1, then signal SIG is sent to every process except process 1.
+
+     If PID is less than -1, then signal SIG is sent to every process in the process group -PID.
+
+     If SIG is 0, then no signal is sent, but error checking is still performed.
+
+     Return 0 if successful, otherwise return -1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Send signal SIG to process PID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fstat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 161
+ -- Built-in Function: [INFO, ERR, MSG] = fstat (FID)
+     Return information about the open file FID.  See `stat' for a description of the contents of INFO.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Return information about the open file FID.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+lstat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+ -- Built-in Function: [INFO, ERR, MSG] = lstat (FILE)
+     See stat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+See stat.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mkfifo
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 258
+ -- Built-in Function: [ERR, MSG] = mkfifo (NAME, MODE)
+     Create a FIFO special file named NAME with file mode MODE
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Create a FIFO special file named NAME with file mode MODE 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+pipe
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 313
+ -- Built-in Function: [READ_FD, WRITE_FD, ERR, MSG] = pipe ()
+     Create a pipe and return the reading and writing ends of the pipe into READ_FD and WRITE_FD respectively.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+Create a pipe and return the reading and writing ends of the pipe into READ_FD and WRITE_FD respectively.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+stat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2402
+ -- Built-in Function: [INFO, ERR, MSG] = stat (FILE)
+ -- Built-in Function: [INFO, ERR, MSG] = lstat (FILE)
+     Return a structure S containing the following information about FILE.
+
+    `dev'
+          ID of device containing a directory entry for this file.
+
+    `ino'
+          File number of the file.
+
+    `mode'
+          File mode, as an integer.  Use the functions `S_ISREG', `S_ISDIR', `S_ISCHR', `S_ISBLK', `S_ISFIFO', `S_ISLNK', or `S_ISSOCK' to extract information from this value.
+
+    `modestr'
+          File mode, as a string of ten letters or dashes as would be returned by `ls -l'.
+
+    `nlink'
+          Number of links.
+
+    `uid'
+          User ID of file's owner.
+
+    `gid'
+          Group ID of file's group.
+
+    `rdev'
+          ID of device for block or character special files.
+
+    `size'
+          Size in bytes.
+
+    `atime'
+          Time of last access in the same form as time values returned from `time'.  *Note Timing Utilities::.
+
+    `mtime'
+          Time of last modification in the same form as time values returned from `time'.  *Note Timing Utilities::.
+
+    `ctime'
+          Time of last file status change in the same form as time values returned from `time'.  *Note Timing Utilities::.
+
+    `blksize'
+          Size of blocks in the file.
+
+    `blocks'
+          Number of blocks allocated for file.
+
+     If the call is successful ERR is 0 and MSG is an empty string.  If the file does not exist, or some other error occurs, S is an empty matrix, ERR is -1, and MSG contains the corresponding system error message.
+
+     If FILE is a symbolic link, `stat' will return information about the actual file that is referenced by the link.  Use `lstat' if you want information about the symbolic link itself.
+
+     For example,
+
+          [s, err, msg] = stat ("/vmlinuz")
+                => s =
+                  {
+                    atime = 855399756
+                    rdev = 0
+                    ctime = 847219094
+                    uid = 0
+                    size = 389218
+                    blksize = 4096
+                    mtime = 847219094
+                    gid = 6
+                    nlink = 1
+                    blocks = 768
+                    mode = -rw-r--r--
+                    modestr = -rw-r--r--
+                    ino = 9316
+                    dev = 2049
+                  }
+               => err = 0
+               => msg =
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Return a structure S containing the following information about FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+S_ISREG
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 190
+ -- Built-in Function:  S_ISREG (MODE)
+     Return true if MODE corresponds to a regular file.  The value of MODE is assumed to be returned from a call to `stat'.  See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Return true if MODE corresponds to a regular file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+S_ISDIR
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 187
+ -- Built-in Function:  S_ISDIR (MODE)
+     Return true if MODE corresponds to a directory.  The value of MODE is assumed to be returned from a call to `stat'.  See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Return true if MODE corresponds to a directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+S_ISCHR
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 195
+ -- Built-in Function:  S_ISCHR (MODE)
+     Return true if MODE corresponds to a character devicey.  The value of MODE is assumed to be returned from a call to `stat'.  See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return true if MODE corresponds to a character devicey.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+S_ISBLK
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 190
+ -- Built-in Function:  S_ISBLK (MODE)
+     Return true if MODE corresponds to a block device.  The value of MODE is assumed to be returned from a call to `stat'.  See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Return true if MODE corresponds to a block device.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+S_ISFIFO
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 183
+ -- Built-in Function:  S_ISFIFO (MODE)
+     Return true if MODE corresponds to a fifo.  The value of MODE is assumed to be returned from a call to `stat'.  See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Return true if MODE corresponds to a fifo.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+S_ISLNK
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 191
+ -- Built-in Function:  S_ISLNK (MODE)
+     Return true if MODE corresponds to a symbolic link.  The value of MODE is assumed to be returned from a call to `stat'.  See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Return true if MODE corresponds to a symbolic link.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+S_ISSOCK
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+ -- Built-in Function:  S_ISSOCK (MODE)
+     See also: stat, lstat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+See also: stat, lstat.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+uname
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 549
+ -- Built-in Function: [UTS, ERR, MSG] = uname ()
+     Return system information in the structure.  For example,
+
+          uname ()
+               => {
+                     sysname = x86_64
+                     nodename = segfault
+                     release = 2.6.15-1-amd64-k8-smp
+                     version = Linux
+                     machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006
+                   }
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Return system information in the structure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+unlink
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Built-in Function: [ERR, MSG] = unlink (FILE)
+     Delete the file named FILE.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise, ERR is nonzero and MSG contains a system-dependent error message.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 27
+Delete the file named FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+waitpid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1411
+ -- Built-in Function: [PID, STATUS, MSG] = waitpid (PID, OPTIONS)
+     Wait for process PID to terminate.  The PID argument can be:
+
+    -1
+          Wait for any child process.
+
+    0
+          Wait for any child process whose process group ID is equal to that of the Octave interpreter process.
+
+    > 0
+          Wait for termination of the child process with ID PID.
+
+     The OPTIONS argument can be a bitwise OR of zero or more of the following constants:
+
+    `0'
+          Wait until signal is received or a child process exits (this is the default if the OPTIONS argument is missing).
+
+    `WNOHANG'
+          Do not hang if status is not immediately available.
+
+    `WUNTRACED'
+          Report the status of any child processes that are stopped, and whose status has not yet been reported since they stopped.
+
+    `WCONTINUE'
+          Return if a stopped child has been resumed by delivery of `SIGCONT'.  This value may not be meaningful on all systems.
+
+     If the returned value of PID is greater than 0, it is the process ID of the child process that exited.  If an error occurs, PID will be less than zero and MSG will contain a system-dependent error message.  The value of STATUS contains additional system-dependent information about the subprocess that exited.  See also: WCONTINUE, WCOREDUMP, WEXITSTATUS, WIFCONTINUED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Wait for process PID to terminate.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+WIFEXITED
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 239
+ -- Built-in Function:  WIFEXITED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child terminated normally.  See also: waitpid, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Given STATUS from a call to `waitpid', return true if the child terminated normally.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+WEXITSTATUS
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 299
+ -- Built-in Function:  WEXITSTATUS (STATUS)
+     Given STATUS from a call to `waitpid', return the exit status of the child.  This function should only be employed if `WIFEXITED' returned true.  See also: waitpid, WIFEXITED, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Given STATUS from a call to `waitpid', return the exit status of the child.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+WIFSIGNALED
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 254
+ -- Built-in Function:  WIFSIGNALED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child process was terminated by a signal.  See also: waitpid, WIFEXITED, WEXITSTATUS, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Given STATUS from a call to `waitpid', return true if the child process was terminated by a signal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+WTERMSIG
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 340
+ -- Built-in Function:  WTERMSIG (STATUS)
+     Given STATUS from a call to `waitpid', return the number of the signal that caused the child process to terminate.  This function should only be employed if `WIFSIGNALED' returned true.  See also: waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Given STATUS from a call to `waitpid', return the number of the signal that caused the child process to terminate.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+WCOREDUMP
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 457
+ -- Built-in Function:  WCOREDUMP (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child produced a core dump.  This function should only be employed if `WIFSIGNALED' returned true.  The macro used to implement this function is not specified in POSIX.1-2001 and is not available on some Unix implementations (e.g., AIX, SunOS).  See also: waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+Given STATUS from a call to `waitpid', return true if the child produced a core dump.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+WIFSTOPPED
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 375
+ -- Built-in Function:  WIFSTOPPED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child process was stopped by delivery of a signal; this is only possible if the call was done using `WUNTRACED' or when the child is being traced (see ptrace(2)).  See also: waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WSTOPSIG, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 220
+Given STATUS from a call to `waitpid', return true if the child process was stopped by delivery of a signal; this is only possible if the call was done using `WUNTRACED' or when the child is being traced (see ptrace(2)).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+WSTOPSIG
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 327
+ -- Built-in Function:  WSTOPSIG (STATUS)
+     Given STATUS from a call to `waitpid', return the number of the signal which caused the child to stop.  This function should only be employed if `WIFSTOPPED' returned true.  See also: waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WIFCONTINUED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+Given STATUS from a call to `waitpid', return the number of the signal which caused the child to stop.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+WIFCONTINUED
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 264
+ -- Built-in Function:  WIFCONTINUED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child process was resumed by delivery of `SIGCONT'.  See also: waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Given STATUS from a call to `waitpid', return true if the child process was resumed by delivery of `SIGCONT'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+canonicalize_file_name
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Built-in Function: [CNAME, STATUS, MSG] canonicalize_file_name (NAME)
+     Return the canonical name of file NAME.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Return the canonical name of file NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+F_DUPFD
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 183
+ -- Built-in Function:  F_DUPFD ()
+     Return the value required to request that `fcntl' return a duplicate file descriptor.  See also: fcntl, F_GETFD, F_GETFL, F_SETFD, F_SETFL.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+Return the value required to request that `fcntl' return a duplicate file descriptor.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+F_GETFD
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 184
+ -- Built-in Function:  F_GETFD ()
+     Return the value required to request that `fcntl' to return the file descriptor flags.  See also: fcntl, F_DUPFD, F_GETFL, F_SETFD, F_SETFL.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Return the value required to request that `fcntl' to return the file descriptor flags.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+F_GETFL
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 180
+ -- Built-in Function:  F_GETFL ()
+     Return the value required to request that `fcntl' to return the file status flags.  See also: fcntl, F_DUPFD, F_GETFD, F_SETFD, F_SETFL.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+Return the value required to request that `fcntl' to return the file status flags.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+F_SETFD
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 181
+ -- Built-in Function:  F_SETFD ()
+     Return the value required to request that `fcntl' to set the file descriptor flags.  See also: fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFL.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Return the value required to request that `fcntl' to set the file descriptor flags.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+F_SETFL
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 177
+ -- Built-in Function:  F_SETFL ()
+     Return the value required to request that `fcntl' to set the file status flags.  See also: fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFD.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 79
+Return the value required to request that `fcntl' to set the file status flags.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+O_APPEND
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 336
+ -- Built-in Function:  O_APPEND ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate each write operation appends, or that may be passed to `fcntl' to set the write mode to append.\nSee also: fcntl, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 190
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate each write operation appends, or that may be passed to `fcntl' to set the write mode to append.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+O_ASYNC
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 258
+ -- Built-in Function:  O_ASYNC ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate asynchronous I/O.  See also: fcntl, O_APPEND, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate asynchronous I/O.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+O_CREAT
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 292
+ -- Built-in Function:  O_CREAT ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file should be created if it does not exist.  See also: fcntl, O_APPEND, O_ASYNC, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file should be created if it does not exist.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+O_EXCL
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 267
+ -- Built-in Function:  O_EXCL ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that file locking is used.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that file locking is used.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+O_NONBLOCK
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 332
+ -- Built-in Function:  O_NONBLOCK ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that non-blocking I/O is in use, or that may be passsed to `fcntl' to set non-blocking I/O.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 186
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that non-blocking I/O is in use, or that may be passsed to `fcntl' to set non-blocking I/O.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+O_RDONLY
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 278
+ -- Built-in Function:  O_RDONLY ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for reading only.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for reading only.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+O_RDWR
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 290
+ -- Built-in Function:  O_RDWR ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for both reading and writing.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_SYNC, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 144
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for both reading and writing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+O_SYNC
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 281
+ -- Built-in Function:  O_SYNC ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for synchronous I/O.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for synchronous I/O.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+O_TRUNC
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 297
+ -- Built-in Variable: O_TRUNC ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that if file exists, it should be truncated when writing.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_WRONLY.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that if file exists, it should be truncated when writing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+O_WRONLY
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 278
+ -- Built-in Function:  O_WRONLY ()
+     Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for writing only.  See also: fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Return the numerical value of the file status flag that may be returned by `fcntl' to indicate that a file is open for writing only.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+WNOHANG
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 266
+ -- Built-in Function:  WNOHANG ()
+     Return the numerical value of the option argument that may be passed to `waitpid' to indicate that it should return its status immediately instead of waiting for a process to exit.  See also: waitpid, WUNTRACED, WCONTINUE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 180
+Return the numerical value of the option argument that may be passed to `waitpid' to indicate that it should return its status immediately instead of waiting for a process to exit.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+WUNTRACED
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 285
+ -- Built-in Function:  WUNTRACED ()
+     Return the numerical value of the option argument that may be passed to `waitpid' to indicate that it should also return if the child process has stopped but is not traced via the `ptrace' system call See also: waitpid, WNOHANG, WCONTINUE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 239
+Return the numerical value of the option argument that may be passed to `waitpid' to indicate that it should also return if the child process has stopped but is not traced via the `ptrace' system call See also: waitpid, WNOHANG, WCONTINUE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+WCONTINUE
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 276
+ -- Built-in Function: WCONINTUE ()
+     Return the numerical value of the option argument that may be passed to `waitpid' to indicate that it should also return if a stopped child has been resumed by delivery of a `SIGCONT' signal.  See also: waitpid, WNOHANG, WUNTRACED.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 191
+Return the numerical value of the option argument that may be passed to `waitpid' to indicate that it should also return if a stopped child has been resumed by delivery of a `SIGCONT' signal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+clc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+ -- Built-in Function:  clc ()
+ -- Built-in Function:  home ()
+     Clear the terminal screen and move the cursor to the upper left corner.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Clear the terminal screen and move the cursor to the upper left corner.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+getenv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 194
+ -- Built-in Function:  getenv (VAR)
+     Return the value of the environment variable VAR.  For example,
+
+          getenv ("PATH")
+
+     returns a string containing the value of your path.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Return the value of the environment variable VAR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+putenv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+ -- Built-in Function:  putenv (VAR, VALUE)
+ -- Built-in Function:  setenv (VAR, VALUE)
+     Set the value of the environment variable VAR to VALUE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Set the value of the environment variable VAR to VALUE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+kbhit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 411
+ -- Built-in Function:  kbhit ()
+     Read a single keystroke from the keyboard.  If called with one argument, don't wait for a keypress.  For example,
+
+          x = kbhit ();
+
+     will set X to the next character typed at the keyboard as soon as it is typed.
+
+          x = kbhit (1);
+
+     identical to the above example, but don't wait for a keypress, returning the empty string if no key is available.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Read a single keystroke from the keyboard.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+pause
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 421
+ -- Built-in Function:  pause (SECONDS)
+     Suspend the execution of the program.  If invoked without any arguments, Octave waits until you type a character.  With a numeric argument, it pauses for the given number of seconds.  For example, the following statement prints a message and then waits 5 seconds before clearing the screen.
+
+          fprintf (stderr, "wait please...\n");
+          pause (5);
+          clc;
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Suspend the execution of the program.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+sleep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+ -- Built-in Function:  sleep (SECONDS)
+     Suspend the execution of the program for the given number of seconds.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Suspend the execution of the program for the given number of seconds.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+usleep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 293
+ -- Built-in Function:  usleep (MICROSECONDS)
+     Suspend the execution of the program for the given number of microseconds.  On systems where it is not possible to sleep for periods of time less than one second, `usleep' will pause the execution for `round (MICROSECONDS / 1e6)' seconds.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Suspend the execution of the program for the given number of microseconds.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+isieee
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 140
+ -- Built-in Function:  isieee ()
+     Return 1 if your computer claims to conform to the IEEE standard for floating point calculations.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Return 1 if your computer claims to conform to the IEEE standard for floating point calculations.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 19
+native_float_format
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+ -- Built-in Function:  native_float_format ()
+     Return the native floating point format as a string
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Return the native floating point format as a string  
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+tilde_expand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 658
+ -- Built-in Function:  tilde_expand (STRING)
+     Performs tilde expansion on STRING.  If STRING begins with a tilde character, (`~'), all of the characters preceding the first slash (or all characters, if there is no slash) are treated as a possible user name, and the tilde and the following characters up to the slash are replaced by the home directory of the named user.  If the tilde is followed immediately by a slash, the tilde is replaced by the home directory of the user running Octave.  For example,
+
+          tilde_expand ("~joeuser/bin")
+               => "/home/joeuser/bin"
+          tilde_expand ("~/bin")
+               => "/home/jwe/bin"
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Performs tilde expansion on STRING.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+time
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 413
+ -- Loadable Function:  time ()
+     Return the current time as the number of seconds since the epoch.  The epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan 1970.  For example, on Monday February 17, 1997 at 07:15:06 CUT, the value returned by `time' was 856163706.  See also: strftime, strptime, localtime, gmtime, mktime, now, date, clock, datenum, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Return the current time as the number of seconds since the epoch.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gmtime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 694
+ -- Loadable Function:  gmtime (T)
+     Given a value returned from time (or any non-negative integer), return a time structure corresponding to CUT.  For example,
+
+          gmtime (time ())
+               => {
+                     usec = 0
+                     year = 97
+                     mon = 1
+                     mday = 17
+                     sec = 6
+                     zone = CST
+                     min = 15
+                     wday = 1
+                     hour = 7
+                     isdst = 0
+                     yday = 47
+                   }
+     See also: strftime, strptime, localtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Given a value returned from time (or any non-negative integer), return a time structure corresponding to CUT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+localtime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 699
+ -- Loadable Function:  localtime (T)
+     Given a value returned from time (or any non-negative integer), return a time structure corresponding to the local time zone.
+
+          localtime (time ())
+               => {
+                     usec = 0
+                     year = 97
+                     mon = 1
+                     mday = 17
+                     sec = 6
+                     zone = CST
+                     min = 15
+                     wday = 1
+                     hour = 1
+                     isdst = 0
+                     yday = 47
+                   }
+     See also: strftime, strptime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+Given a value returned from time (or any non-negative integer), return a time structure corresponding to the local time zone.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mktime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 356
+ -- Loadable Function:  mktime (TM_STRUCT)
+     Convert a time structure corresponding to the local time to the number of seconds since the epoch.  For example,
+
+          mktime (localtime (time ()))
+               => 856163706
+     See also: strftime, strptime, localtime, gmtime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Convert a time structure corresponding to the local time to the number of seconds since the epoch.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strftime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2887
+ -- Loadable Function:  strftime (FMT, TM_STRUCT)
+     Format the time structure TM_STRUCT in a flexible way using the format string FMT that contains `%' substitutions similar to those in `printf'.  Except where noted, substituted fields have a fixed size; numeric fields are padded if necessary.  Padding is with zeros by default; for fields that display a single number, padding can be changed or inhibited by following the `%' with one of the modifiers described below.  Unknown field specifiers are copied as normal characters.  All other characters are copied to the output without change.  For example,
+
+          strftime ("%r (%Z) %A %e %B %Y", localtime (time ()))
+               => "01:15:06 AM (CST) Monday 17 February 1997"
+
+     Octave's `strftime' function supports a superset of the ANSI C field specifiers.
+
+     Literal character fields:
+
+    `%'
+          % character.
+
+    `n'
+          Newline character.
+
+    `t'
+          Tab character.
+
+     Numeric modifiers (a nonstandard extension):
+
+    `- (dash)'
+          Do not pad the field.
+
+    `_ (underscore)'
+          Pad the field with spaces.
+
+     Time fields:
+
+    `%H'
+          Hour (00-23).
+
+    `%I'
+          Hour (01-12).
+
+    `%k'
+          Hour (0-23).
+
+    `%l'
+          Hour (1-12).
+
+    `%M'
+          Minute (00-59).
+
+    `%p'
+          Locale's AM or PM.
+
+    `%r'
+          Time, 12-hour (hh:mm:ss [AP]M).
+
+    `%R'
+          Time, 24-hour (hh:mm).
+
+    `%s'
+          Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).
+
+    `%S'
+          Second (00-61).
+
+    `%T'
+          Time, 24-hour (hh:mm:ss).
+
+    `%X'
+          Locale's time representation (%H:%M:%S).
+
+    `%Z'
+          Time zone (EDT), or nothing if no time zone is determinable.
+
+     Date fields:
+
+    `%a'
+          Locale's abbreviated weekday name (Sun-Sat).
+
+    `%A'
+          Locale's full weekday name, variable length (Sunday-Saturday).
+
+    `%b'
+          Locale's abbreviated month name (Jan-Dec).
+
+    `%B'
+          Locale's full month name, variable length (January-December).
+
+    `%c'
+          Locale's date and time (Sat Nov 04 12:02:33 EST 1989).
+
+    `%C'
+          Century (00-99).
+
+    `%d'
+          Day of month (01-31).
+
+    `%e'
+          Day of month ( 1-31).
+
+    `%D'
+          Date (mm/dd/yy).
+
+    `%h'
+          Same as %b.
+
+    `%j'
+          Day of year (001-366).
+
+    `%m'
+          Month (01-12).
+
+    `%U'
+          Week number of year with Sunday as first day of week (00-53).
+
+    `%w'
+          Day of week (0-6).
+
+    `%W'
+          Week number of year with Monday as first day of week (00-53).
+
+    `%x'
+          Locale's date representation (mm/dd/yy).
+
+    `%y'
+          Last two digits of year (00-99).
+
+    `%Y'
+          Year (1970-).
+     See also: strptime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Format the time structure TM_STRUCT in a flexible way using the format string FMT that contains `%' substitutions similar to those in `printf'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strptime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 496
+ -- Loadable Function: [TM_STRUCT, NCHARS] = strptime (STR, FMT)
+     Convert the string STR to the time structure TM_STRUCT under the control of the format string FMT.
+
+     If FMT fails to match, NCHARS is 0; otherwise it is set to the position of last matched character plus 1. Always check for this unless you're absolutely sure the date string will be parsed correctly.  See also: strftime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Convert the string STR to the time structure TM_STRUCT under the control of the format string FMT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+quit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 265
+ -- Built-in Function:  exit (STATUS)
+ -- Built-in Function:  quit (STATUS)
+     Exit the current Octave session.  If the optional integer value STATUS is supplied, pass that value to the operating system as the Octave's exit status.  The default value is zero.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Exit the current Octave session.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+warranty
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+ -- Built-in Function:  warranty ()
+     Describe the conditions for copying and distributing Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Describe the conditions for copying and distributing Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+system
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1316
+ -- Built-in Function:  system (STRING, RETURN_OUTPUT, TYPE)
+     Execute a shell command specified by STRING.  The second argument is optional.  If TYPE is `"async"', the process is started in the background and the process id of the child process is returned immediately.  Otherwise, the process is started, and Octave waits until it exits.  If the TYPE argument is omitted, a value of `"sync"' is assumed.
+
+     If two input arguments are given (the actual value of RETURN_OUTPUT is irrelevant) and the subprocess is started synchronously, or if SYSTEM is called with one input argument and one or more output arguments, the output from the command is returned.  Otherwise, if the subprocess is executed synchronously, its output is sent to the standard output.  To send the output of a command executed with SYSTEM through the pager, use a command like
+
+          disp (system (cmd, 1));
+
+     or
+
+          printf ("%s\n", system (cmd, 1));
+
+     The `system' function can return two values.  The first is the exit status of the command and the second is any output from the command that was written to the standard output stream.  For example,
+
+          [status, output] = system ("echo foo; exit 2");
+
+     will set the variable `output' to the string `foo', and the variable `status' to the integer `2'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Execute a shell command specified by STRING.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+atexit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 961
+ -- Built-in Function:  atexit (FCN)
+ -- Built-in Function:  atexit (FCN, FLAG)
+     Register a function to be called when Octave exits.  For example,
+
+          function last_words ()
+            disp ("Bye bye");
+          endfunction
+          atexit ("last_words");
+
+     will print the message "Bye bye" when Octave exits.
+
+     The additional argument FLAG will register or unregister FCN from the list of functions to be called when Octave exits.  If FLAG is true, the function is registered, and if FLAG is false, it is unregistered.  For example, after registering the function `last_words' above,
+
+          atexit ("last_words", false);
+
+     will remove the function from the list and Octave will not call `last_words' when it exits.
+
+     Note that `atexit' only removes the first occurrence of a function from the list, so if a function was placed in the list multiple times with `atexit', it must also be removed from the list multiple times.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Register a function to be called when Octave exits.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+octave_config_info
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 238
+ -- Built-in Function:  octave_config_info (OPTION)
+     Return a structure containing configuration and installation information for Octave.
+
+     if OPTION is a string, return the configuration information for the specified option.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Return a structure containing configuration and installation information for Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+tsearch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 276
+ -- Loadable Function: IDX = tsearch (X, Y, T, XI, YI)
+     Searches for the enclosing Delaunay convex hull.  For `T = delaunay (X, Y)', finds the index in T containing the points `(XI, YI)'.  For points outside the convex hull, IDX is NaN.  See also: delaunay, delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Searches for the enclosing Delaunay convex hull.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+typecast
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 505
+ -- Loadable Function:  typecast (X, TYPE)
+     Convert from one datatype to another without changing the underlying data.  The argument TYPE defines the type of the return argument and must be one of 'uint8', 'uint16', 'uint32', 'uint64', 'int8', 'int16', 'int32', 'int64', 'single' or 'double'.
+
+     An example of the use of typecast on a little-endian machine is
+
+          X = uint16 ([1, 65535]);
+          typecast (X, 'uint8')
+          => [   0,   1, 255, 255]
+     See also: cast, swapbytes.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Convert from one datatype to another without changing the underlying data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+urlwrite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1338
+ -- Loadable Function:  urlwrite (URL, LOCALFILE)
+ -- Loadable Function: F = urlwrite (URL, LOCALFILE)
+ -- Loadable Function: [F, SUCCESS] = urlwrite (URL, LOCALFILE)
+ -- Loadable Function: [F, SUCCESS, MESSAGE] = urlwrite (URL, LOCALFILE)
+     Download a remote file specified by its URL and save it as LOCALFILE.  For example,
+
+          urlwrite ("ftp://ftp.octave.org/pub/octave/README",
+                    "README.txt");
+
+     The full path of the downloaded file is returned in F.  The variable SUCCESS is 1 if the download was successful, otherwise it is 0 in which case MESSAGE contains an error message.  If no output argument is specified and if an error occurs, then the error is signaled through Octave's error handling mechanism.
+
+     This function uses libcurl.  Curl supports, among others, the HTTP, FTP and FILE protocols.  Username and password may be specified in the URL, for example:
+
+          urlwrite ("http://username:password@example.com/file.txt",
+                    "file.txt");
+
+     GET and POST requests can be specified by METHOD and PARAM.  The parameter METHOD is either `get' or `post' and PARAM is a cell array of parameter and value pairs.  For example:
+
+          urlwrite ("http://www.google.com/search", "search.html",
+                    "get", {"query", "octave"});
+     See also: urlread.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Download a remote file specified by its URL and save it as LOCALFILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+urlread
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1195
+ -- Loadable Function: S = urlread (URL)
+ -- Loadable Function: [S, SUCCESS] = urlread (URL)
+ -- Loadable Function: [S, SUCCESS, MESSAGE] = urlread (URL)
+ -- Loadable Function: [...] = urlread (URL, METHOD, PARAM)
+     Download a remote file specified by its URL and return its content in string S.  For example,
+
+          s = urlread ("ftp://ftp.octave.org/pub/octave/README");
+
+     The variable SUCCESS is 1 if the download was successful, otherwise it is 0 in which case MESSAGE contains an error message.  If no output argument is specified and if an error occurs, then the error is signaled through Octave's error handling mechanism.
+
+     This function uses libcurl.  Curl supports, among others, the HTTP, FTP and FILE protocols.  Username and password may be specified in the URL.  For example,
+
+          s = urlread ("http://user:password@example.com/file.txt");
+
+     GET and POST requests can be specified by METHOD and PARAM.  The parameter METHOD is either `get' or `post' and PARAM is a cell array of parameter and value pairs.  For example,
+
+          s = urlread ("http://www.google.com/search", "get",
+                       {"query", "octave"});
+     See also: urlwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 79
+Download a remote file specified by its URL and return its content in string S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+isvarname
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+ -- Built-in Function:  isvarname (NAME)
+     Return true if NAME is a valid variable name
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Return true if NAME is a valid variable name  
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+file_in_loadpath
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 648
+ -- Built-in Function:  file_in_loadpath (FILE)
+ -- Built-in Function:  file_in_loadpath (FILE, "all")
+     Return the absolute name of FILE if it can be found in the list of directories specified by `path'.  If no file is found, return an empty matrix.
+
+     If the first argument is a cell array of strings, search each directory of the loadpath for element of the cell array and return the first that matches.
+
+     If the second optional argument `"all"' is supplied, return a cell array containing the list of all files that have the same name in the path.  If no files are found, return an empty cell array.  See also: file_in_path, path.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Return the absolute name of FILE if it can be found in the list of directories specified by `path'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+file_in_path
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 794
+ -- Built-in Function:  file_in_path (PATH, FILE)
+ -- Built-in Function:  file_in_path (PATH, FILE, "all")
+     Return the absolute name of FILE if it can be found in PATH.  The value of PATH should be a colon-separated list of directories in the format described for `path'.  If no file is found, return an empty matrix.  For example,
+
+          file_in_path (EXEC_PATH, "sh")
+               => "/bin/sh"
+
+     If the second argument is a cell array of strings, search each directory of the path for element of the cell array and return the first that matches.
+
+     If the third optional argument `"all"' is supplied, return a cell array containing the list of all files that have the same name in the path.  If no files are found, return an empty cell array.  See also: file_in_loadpath.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Return the absolute name of FILE if it can be found in PATH.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+do_string_escapes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+ -- Built-in Function:  do_string_escapes (STRING)
+     Convert special characters in STRING to their escaped forms.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Convert special characters in STRING to their escaped forms.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 19
+undo_string_escapes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 732
+ -- Built-in Function:  undo_string_escapes (S)
+     Converts special characters in strings back to their escaped forms.  For example, the expression
+
+          bell = "\a";
+
+     assigns the value of the alert character (control-g, ASCII code 7) to the string variable `bell'.  If this string is printed, the system will ring the terminal bell (if it is possible).  This is normally the desired outcome.  However, sometimes it is useful to be able to print the original representation of the string, with the special characters replaced by their escape sequences.  For example,
+
+          octave:13> undo_string_escapes (bell)
+          ans = \a
+
+     replaces the unprintable alert character with its printable representation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Converts special characters in strings back to their escaped forms.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+is_absolute_filename
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+ -- Built-in Function:  is_absolute_filename (FILE)
+     Return true if FILE is an absolute filename.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Return true if FILE is an absolute filename.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 27
+is_rooted_relative_filename
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+ -- Built-in Function:  is_rooted_relative_filename (FILE)
+     Return true if FILE is a rooted-relative filename.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Return true if FILE is a rooted-relative filename.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+make_absolute_filename
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+ -- Built-in Function:  make_absolute_filename (FILE)
+     Return the full name of FILE, relative to the current directory.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return the full name of FILE, relative to the current directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+find_dir_in_path
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 318
+ -- Built-in Function:  find_dir_in_path (DIR)
+     Return the full name of the path element matching DIR.  The match is performed at the end of each path element.  For example, if DIR is `"foo/bar"', it matches the path element `"/some/dir/foo/bar"', but not `"/some/dir/foo/bar/baz"' or `"/some/dir/allfoo/bar"'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Return the full name of the path element matching DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+errno
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 339
+ -- Built-in Function: ERR = errno ()
+ -- Built-in Function: ERR = errno (VAL)
+ -- Built-in Function: ERR = errno (NAME)
+     Return the current value of the system-dependent variable errno, set its value to VAL and return the previous value, or return the named error code given NAME as a character string, or -1 if NAME is not found.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 209
+Return the current value of the system-dependent variable errno, set its value to VAL and return the previous value, or return the named error code given NAME as a character string, or -1 if NAME is not found.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+errno_list
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+ -- Built-in Function:  errno_list ()
+     Return a structure containing the system-dependent errno values.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return a structure containing the system-dependent errno values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isglobal
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 184
+ -- Built-in Function:  isglobal (NAME)
+     Return 1 if NAME is globally visible.  Otherwise, return 0.  For example,
+
+          global x
+          isglobal ("x")
+               => 1
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return 1 if NAME is globally visible.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_global
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 106
+ -- Built-in Function:  isglobal (NAME)
+     This function has been deprecated.  Use isglobal instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+exist
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1031
+ -- Built-in Function:  exist (NAME, TYPE)
+     Return 1 if the name exists as a variable, 2 if the name is an absolute file name, an ordinary file in Octave's `path', or (after appending `.m') a function file in Octave's `path', 3 if the name is a `.oct' or `.mex' file in Octave's `path', 5 if the name is a built-in function, 7 if the name is a directory, or 103 if the name is a function not associated with a file (entered on the command line).
+
+     Otherwise, return 0.
+
+     This function also returns 2 if a regular file called NAME exists in Octave's search path.  If you want information about other types of files, you should use some combination of the functions `file_in_path' and `stat' instead.
+
+     If the optional argument TYPE is supplied, check only for symbols of the specified type.  Valid types are
+
+    `"var"'
+          Check only for variables.
+
+    `"builtin"'
+          Check only for built-in functions.
+
+    `"file"'
+          Check only for files.
+
+    `"dir"'
+          Check only for directories.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 142
+Return 1 if the name exists as a variable, 2 if the name is an absolute file name, an ordinary file in Octave's `path', or (after appending `.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+who
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1046
+ -- Command: who
+ -- Command: who pattern ...
+ -- Command: who option pattern ...
+ -- Command: C = who("pattern", ...)
+     List currently defined variables matching the given patterns.  Valid pattern syntax is the same as described for the `clear' command.  If no patterns are supplied, all variables are listed.  By default, only variables visible in the local scope are displayed.
+
+     The following are valid options but may not be combined.
+
+    `global'
+          List variables in the global scope rather than the current scope.
+
+    `-regexp'
+          The patterns are considered to be regular expressions when matching the variables to display.  The same pattern syntax accepted by the `regexp' function is used.
+
+    `-file'
+          The next argument is treated as a filename.  All variables found within the specified file are listed.  No patterns are accepted when reading variables from a file.
+
+     If called as a function, return a cell array of defined variable names matching the given patterns.  See also: whos, regexp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+List currently defined variables matching the given patterns.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+whos
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1377
+ -- Command: whos
+ -- Command: whos pattern ...
+ -- Command: whos option pattern ...
+ -- Command: S = whos("pattern", ...)
+     Provide detailed information on currently defined variables matching the given patterns.  Options and pattern syntax are the same as for the `who' command.  Extended information about each variable is summarized in a table with the following default entries.
+
+    Attr
+          Attributes of the listed variable.  Possible attributes are:
+         blank
+               Variable in local scope
+
+         `g'
+               Variable with global scope
+
+         `p'
+               Persistent variable
+
+    Name
+          The name of the variable.
+
+    Size
+          The logical size of the variable.  A scalar is 1x1, a vector is 1xN or Nx1, a 2-D matrix is MxN.
+
+    Bytes
+          The amount of memory currently used to store the variable.
+
+    Class
+          The class of the variable.  Examples include double, single, char, uint16, cell, and struct.
+
+     The table can be customized to display more or less information through the function `whos_line_format'.
+
+     If `whos' is called as a function, return a struct array of defined variable names matching the given patterns.  Fields in the structure describing each variable are: name, size, bytes, class, global, sparse, complex, nesting, persistent.  See also: who, whos_line_format.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+Provide detailed information on currently defined variables matching the given patterns.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+mlock
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+ -- Built-in Function:  mlock ()
+     Lock the current function into memory so that it can't be cleared.  See also: munlock, mislocked, persistent.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Lock the current function into memory so that it can't be cleared.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+munlock
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Built-in Function:  munlock (FCN)
+     Unlock the named function.  If no function is named then unlock the current function.  See also: mlock, mislocked, persistent.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Unlock the named function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+mislocked
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 209
+ -- Built-in Function:  mislocked (FCN)
+     Return true if the named function is locked.  If no function is named then return true if the current function is locked.  See also: mlock, munlock, persistent.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Return true if the named function is locked.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+clear
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2049
+ -- Command: clear [options] pattern ...
+     Delete the names matching the given patterns from the symbol table.  The pattern may contain the following special characters:
+
+    `?'
+          Match any single character.
+
+    `*'
+          Match zero or more characters.
+
+    `[ LIST ]'
+          Match the list of characters specified by LIST.  If the first character is `!' or `^', match all characters except those specified by LIST.  For example, the pattern `[a-zA-Z]' will match all lower and upper case alphabetic characters.
+
+     For example, the command
+
+          clear foo b*r
+
+     clears the name `foo' and all names that begin with the letter `b' and end with the letter `r'.
+
+     If `clear' is called without any arguments, all user-defined variables (local and global) are cleared from the symbol table.  If `clear' is called with at least one argument, only the visible names matching the arguments are cleared.  For example, suppose you have defined a function `foo', and then hidden it by performing the assignment `foo = 2'.  Executing the command `clear foo' once will clear the variable definition and restore the definition of `foo' as a function.  Executing `clear foo' a second time will clear the function definition.
+
+     The following options are available in both long and short form
+    `-all, -a'
+          Clears all local and global user-defined variables and all functions from the symbol table.
+
+    `-exclusive, -x'
+          Clears the variables that don't match the following pattern.
+
+    `-functions, -f'
+          Clears the function names and the built-in symbols names.
+
+    `-global, -g'
+          Clears the global symbol names.
+
+    `-variables, -v'
+          Clears the local variable names.
+
+    `-classes, -c'
+          Clears the class structure table and clears all objects.
+
+    `-regexp, -r'
+          The arguments are treated as regular expressions as any variables that match will be cleared.
+     With the exception of `exclusive', all long options can be used without the dash as well.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Delete the names matching the given patterns from the symbol table.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+whos_line_format
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1622
+ -- Built-in Function: VAL = whos_line_format ()
+ -- Built-in Function: OLD_VAL = whos_line_format (NEW_VAL)
+     Query or set the format string used by the command `whos'.
+
+     A full format string is:
+
+          %[modifier]<command>[:width[:left-min[:balance]]];
+
+     The following command sequences are available:
+
+    `%a'
+          Prints attributes of variables (g=global, p=persistent, f=formal parameter, a=automatic variable).
+
+    `%b'
+          Prints number of bytes occupied by variables.
+
+    `%c'
+          Prints class names of variables.
+
+    `%e'
+          Prints elements held by variables.
+
+    `%n'
+          Prints variable names.
+
+    `%s'
+          Prints dimensions of variables.
+
+    `%t'
+          Prints type names of variables.
+
+     Every command may also have an alignment modifier:
+
+    `l'
+          Left alignment.
+
+    `r'
+          Right alignment (default).
+
+    `c'
+          Column-aligned (only applicable to command %s).
+
+     The `width' parameter is a positive integer specifying the minimum number of columns used for printing.  No maximum is needed as the field will auto-expand as required.
+
+     The parameters `left-min' and `balance' are only available when the column-aligned modifier is used with the command `%s'.  `balance' specifies the column number within the field width which will be aligned between entries.  Numbering starts from 0 which indicates the leftmost column.  `left-min' specifies the minimum field width to the left of the specified balance column.
+
+     The default format is `"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\n"'.  See also: whos.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Query or set the format string used by the command `whos'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+geometric_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 349
+ -- Function File:  geometric_rnd (P, R, C)
+ -- Function File:  geometric_rnd (P, SZ)
+     Return an R by C matrix of random samples from the geometric distribution with parameter P, which must be a scalar or of size R by C.
+
+     If R and C are given create a matrix with R rows and C columns.  Or if SZ is a vector, create a matrix of size SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+Return an R by C matrix of random samples from the geometric distribution with parameter P, which must be a scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+meshdom
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+ -- Function File:  meshdom (X, Y)
+     This function has been deprecated.  Use `meshgrid' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_square
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  is_square (X)
+     This function has been deprecated.  Use issquare instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+poisson_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 178
+ -- Function File:  poisson_pdf (X, LAMBDA)
+     For each element of X, compute the probability density function (PDF) at X of the poisson distribution with parameter LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+For each element of X, compute the probability density function (PDF) at X of the poisson distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spkron
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+ -- Function File:  spkron (A, B)
+     This function has been deprecated.  Use `kron' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+spcholinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+ -- Function File:  spcholinv (U)
+     This function has been deprecated.  Use `cholinv' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+weibull_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 260
+ -- Function File:  weibull_cdf (X, SHAPE, SCALE)
+     Compute the cumulative distribution function (CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE, which is
+
+          1 - exp(-(x/shape)^scale)
+
+     for X >= 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+Compute the cumulative distribution function (CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE, which is 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+weibpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 297
+ -- Function File:  weibpdf (X, SCALE, SHAPE)
+     Compute the probability density function (PDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE which is given by
+
+             scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+
+     for X > 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+Compute the probability density function (PDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE which is given by 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+normal_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Function File:  normal_cdf (X, M, V)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the normal distribution with mean M and variance V.
+
+     Default values are M = 0, V = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+For each element of X, compute the cumulative distribution function (CDF) at X of the normal distribution with mean M and variance V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+chisquare_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 180
+ -- Function File:  chisquare_inv (X, N)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the chisquare distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+For each element of X, compute the quantile (the inverse of the CDF) at X of the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+splu
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 299
+ -- Loadable Function: [L, U] = splu (A)
+ -- Loadable Function: [L, U, P] = splu (A)
+ -- Loadable Function: [L, U, P, Q] = splu (A)
+ -- Loadable Function: [L, U, P, Q] = splu (..., THRES)
+ -- Loadable Function: [L, U, P] = splu (..., Q)
+     This function has been deprecated.  Use `lu' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+gamma_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Function File:  gamma_pdf (X, A, B)
+     For each element of X, return the probability density function (PDF) at X of the Gamma distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+For each element of X, return the probability density function (PDF) at X of the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+t_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 167
+ -- Function File:  t_inv (X, N)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the t (Student) distribution with parameter N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+For each component of X, compute the quantile (the inverse of the CDF) at X of the t (Student) distribution with parameter N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+pascal_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 329
+ -- Function File:  pascal_pdf (X, N, P)
+     For each element of X, compute the probability density function (PDF) at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success probability P before the N-th success follows this distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+For each element of X, compute the probability density function (PDF) at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+isstr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+ -- Function File:  isstr (A)
+     This function has been deprecated.  Use ischar instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_struct
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  is_struct (A)
+     This function has been deprecated.  Use isstruct instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+chisquare_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 181
+ -- Function File:  chisquare_pdf (X, N)
+     For each element of X, compute the probability density function (PDF) at X of the chisquare distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+For each element of X, compute the probability density function (PDF) at X of the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spdiag
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Function File:  spdiag (V, K)
+     This function has been deprecated.  Use `sparse (diag (...))' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+setstr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+ -- Function File:  setstr (S)
+     This function has been deprecated.  Use char instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+spmin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+ -- Mapping Function:  spmin (X, Y, DIM)
+ -- Mapping Function: [W, IW] = spmin (X)
+     This function has been deprecated.  Use `min' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+uniform_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 182
+ -- Function File:  uniform_cdf (X, A, B)
+     Return the CDF at X of the uniform distribution on [A, B], i.e., PROB (uniform (A, B) <= x).
+
+     Default values are A = 0, B = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Return the CDF at X of the uniform distribution on [A, B], i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+weibull_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 301
+ -- Function File:  weibull_pdf (X, SHAPE, SCALE)
+     Compute the probability density function (PDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE which is given by
+
+             scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+
+     for X > 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+Compute the probability density function (PDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE which is given by 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+spcumprod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 106
+ -- Function File:  spcumprod (X, DIM)
+     This function has been deprecated.  Use `cumprod' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spprod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  spprod (X, DIM)
+     This function has been deprecated.  Use `prod' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+str2mat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 349
+ -- Function File:  str2mat (S_1, ..., S_N)
+     Return a matrix containing the strings S_1, ..., S_N as its rows.  Each string is padded with blanks in order to form a valid matrix.
+
+     This function is modelled after MATLAB.  In Octave, you can create a matrix of strings by `[S_1; ...; S_N]' even if the strings are not all the same length.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Return a matrix containing the strings S_1, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+is_complex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+ -- Function File:  is_complex (A)
+     This function has been deprecated.  Use iscomplex instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+lognormal_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 343
+ -- Function File:  lognormal_inv (X, A, V)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the lognormal distribution with parameters A and V.  If a random variable follows this distribution, its logarithm is normally distributed with mean `log (A)' and variance V.
+
+     Default values are A = 1, V = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+For each element of X, compute the quantile (the inverse of the CDF) at X of the lognormal distribution with parameters A and V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+t_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 175
+ -- Function File:  t_pdf (X, N)
+     For each element of X, compute the probability density function (PDF) at X of the T (Student) distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+For each element of X, compute the probability density function (PDF) at X of the T (Student) distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+com2str
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 319
+ -- Function File:  com2str (ZZ, FLG)
+     This function has been deprecated.  Use num2str instead.
+
+     Convert complex number to a string.  *Inputs*
+    ZZ
+          complex number
+
+    FLG
+          format flag 0 (default):            -1, 0, 1,   1i,   1 + 0.5i 1 (for use with zpout): -1, 0, + 1, + 1i, + 1 + 0.5i
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+polyinteg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 308
+ -- Function File:  polyinteg (C)
+     Return the coefficients of the integral of the polynomial whose coefficients are represented by the vector C.
+
+     The constant of integration is set to zero.  See also: polyint, poly, polyderiv, polyreduce, roots, conv, deconv, residue, filter, polyval, polyvalm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Return the coefficients of the integral of the polynomial whose coefficients are represented by the vector C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+f_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 388
+ -- Function File:  f_rnd (M, N, R, C)
+ -- Function File:  f_rnd (M, N, SZ)
+     Return an R by C matrix of random samples from the F distribution with M and N degrees of freedom.  Both M and N must be scalar or of size R by C.  If SZ is a vector the random samples are in a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of M and N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Return an R by C matrix of random samples from the F distribution with M and N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+exponential_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 383
+ -- Function File:  exponential_rnd (LAMBDA, R, C)
+ -- Function File:  exponential_rnd (LAMBDA, SZ)
+     Return an R by C matrix of random samples from the exponential distribution with parameter LAMBDA, which must be a scalar or of size R by C.  Or if SZ is a vector, create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the size of LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 140
+Return an R by C matrix of random samples from the exponential distribution with parameter LAMBDA, which must be a scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+lognormal_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 389
+ -- Function File:  lognormal_rnd (A, V, R, C)
+ -- Function File:  lognormal_rnd (A, V, SZ)
+     Return an R by C matrix of random samples from the lognormal distribution with parameters A and V.  Both A and V must be scalar or of size R by C.  Or if SZ is a vector, create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and V.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Return an R by C matrix of random samples from the lognormal distribution with parameters A and V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+binomial_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 154
+ -- Function File:  binomial_inv (X, N, P)
+     For each element of X, compute the quantile at X of the binomial distribution with parameters N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+For each element of X, compute the quantile at X of the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+poisson_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 275
+ -- Function File:  poisson_rnd (LAMBDA, R, C)
+     Return an R by C matrix of random samples from the Poisson distribution with parameter LAMBDA, which must be a scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the size of LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+Return an R by C matrix of random samples from the Poisson distribution with parameter LAMBDA, which must be a scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+weibinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 187
+ -- Function File:  weibinv (X, SCALE, SHAPE)
+     Compute the quantile (the inverse of the CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Compute the quantile (the inverse of the CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+spcumsum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+ -- Function File:  spcumsum (X, DIM)
+     This function has been deprecated.  Use `cumsum' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_matrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  is_matrix (A)
+     This function has been deprecated.  Use ismatrix instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+exponential_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 185
+ -- Function File:  exponential_inv (X, LAMBDA)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the exponential distribution with parameter LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+For each element of X, compute the quantile (the inverse of the CDF) at X of the exponential distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+geometric_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+ -- Function File:  geometric_inv (X, P)
+     For each element of X, compute the quantile at X of the geometric distribution with parameter P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+For each element of X, compute the quantile at X of the geometric distribution with parameter P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spatan2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  spatan2 (Y, X)
+     This function has been deprecated.  Use `atan2' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+lognormal_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 348
+ -- Function File:  lognormal_cdf (X, A, V)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the lognormal distribution with parameters A and V.  If a random variable follows this distribution, its logarithm is normally distributed with mean `log (A)' and variance V.
+
+     Default values are A = 1, V = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+For each element of X, compute the cumulative distribution function (CDF) at X of the lognormal distribution with parameters A and V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+gamma_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 178
+ -- Function File:  gamma_cdf (X, A, B)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the Gamma distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the cumulative distribution function (CDF) at X of the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+clearplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+ -- Function File:  clearplot ()
+     This function has been deprecated.  Use clf instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+unmark_command
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+ -- Built-in Function:  unmark_command (NAME)
+     This function is obsolete and will be removed from a future version of Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+This function is obsolete and will be removed from a future version of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+dmult
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 163
+ -- Function File:  dmult (A, B)
+     This function has been deprecated.  Use the direct syntax `diag(A)*B' which is more readable and now also more efficient.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+struct_contains
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+ -- Function File:  struct_contains (EXPR, NAME)
+     This function has been deprecated.  Use isfield instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+normal_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 345
+ -- Function File:  normal_rnd (M, V, R, C)
+ -- Function File:  normal_rnd (M, V, SZ)
+     Return an R by C  or `size (SZ)' matrix of random samples from the normal distribution with parameters M and V.  Both M and V must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of M and V.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+Return an R by C or `size (SZ)' matrix of random samples from the normal distribution with parameters M and V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+spmax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+ -- Mapping Function:  spmax (X, Y, DIM)
+ -- Mapping Function: [W, IW] = spmax (X)
+     This function has been deprecated.  Use `max' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+spchol2inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+ -- Function File:  spchol2inv (U)
+     This function has been deprecated.  Use `chol2inv' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+is_bool
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+ -- Function File:  is_bool (A)
+     This function has been deprecated.  Use isbool instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+gamma_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 343
+ -- Function File:  gamma_rnd (A, B, R, C)
+ -- Function File:  gamma_rnd (A, B, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from the Gamma distribution with parameters A and B.  Both A and B must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Return an R by C or a `size (SZ)' matrix of random samples from the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+pascal_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 303
+ -- Function File:  pascal_inv (X, N, P)
+     For each element of X, compute the quantile at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success probability P before the N-th success follows this distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+For each element of X, compute the quantile at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+uniform_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 172
+ -- Function File:  uniform_pdf (X, A, B)
+     For each element of X, compute the PDF at X of the uniform distribution on [A, B].
+
+     Default values are A = 0, B = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+For each element of X, compute the PDF at X of the uniform distribution on [A, B].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+exponential_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 243
+ -- Function File:  exponential_cdf (X, LAMBDA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the exponential distribution with parameter LAMBDA.
+
+     The arguments can be of common size or scalar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+For each element of X, compute the cumulative distribution function (CDF) at X of the exponential distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+hypergeometric_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 262
+ -- Function File:  hypergeometric_inv (X, M, T, N)
+     For each element of X, compute the quantile at X of the hypergeometric distribution with parameters M, T, and N.
+
+     The parameters M, T, and N must positive integers with M and N not greater than T.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+For each element of X, compute the quantile at X of the hypergeometric distribution with parameters M, T, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+wiener_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 435
+ -- Function File:  wiener_rnd (T, D, N)
+     Return a simulated realization of the D-dimensional Wiener Process on the interval [0, T].  If D is omitted, D = 1 is used.  The first column of the return matrix contains time, the remaining columns contain the Wiener process.
+
+     The optional parameter N gives the number of summands used for simulating the process over an interval of length 1.  If N is omitted, N = 1000 is used.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 90
+Return a simulated realization of the D-dimensional Wiener Process on the interval [0, T].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spfind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 231
+ -- Loadable Function:  spfind (X)
+ -- Loadable Function:  spfind (X, N)
+ -- Loadable Function:  spfind (X, N, DIRECTION)
+ -- Loadable Function: [I, J, V spfind (...)
+     This function has been deprecated.  Use `find' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+iscommand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+ -- Built-in Function:  iscommand (NAME)
+     This function is obsolete and will be removed from a future version of Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+This function is obsolete and will be removed from a future version of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+lognormal_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 344
+ -- Function File:  lognormal_pdf (X, A, V)
+     For each element of X, compute the probability density function (PDF) at X of the lognormal distribution with parameters A and V.  If a random variable follows this distribution, its logarithm is normally distributed with mean `log (A)' and variance V.
+
+     Default values are A = 1, V = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the probability density function (PDF) at X of the lognormal distribution with parameters A and V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+beta_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 141
+ -- Function File:  beta_pdf (X, A, B)
+     For each element of X, returns the PDF at X of the beta distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+For each element of X, returns the PDF at X of the beta distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+weibrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 397
+ -- Function File:  weibrnd (SCALE, SHAPE, R, C)
+ -- Function File:  weibrnd (SCALE, SHAPE, SZ)
+     Return an R by C matrix of random samples from the Weibull distribution with parameters SCALE and SHAPE which must be scalar or of size R by C.  Or if SZ is a vector return a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of ALPHA and SIGMA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Return an R by C matrix of random samples from the Weibull distribution with parameters SCALE and SHAPE which must be scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+intersection
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+ -- Function File:  intersection (X, Y)
+     This function has been deprecated.  Use intersect instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+weibull_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 191
+ -- Function File:  weibull_inv (X, SHAPE, SCALE)
+     Compute the quantile (the inverse of the CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Compute the quantile (the inverse of the CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+weibcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 256
+ -- Function File:  weibcdf (X, SCALE, SHAPE)
+     Compute the cumulative distribution function (CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE, which is
+
+          1 - exp(-(x/shape)^scale)
+
+     for X >= 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+Compute the cumulative distribution function (CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE, which is 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+t_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 348
+ -- Function File:  t_rnd (N, R, C)
+ -- Function File:  t_rnd (N, SZ)
+     Return an R by C matrix of random samples from the t (Student) distribution with N degrees of freedom.  N must be a scalar or of size R by C.  Or if SZ is a vector create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the size of N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+Return an R by C matrix of random samples from the t (Student) distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spchol
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 191
+ -- Loadable Function: R = spchol (A)
+ -- Loadable Function: [R, P] = spchol (A)
+ -- Loadable Function: [R, P, Q] = spchol (A)
+     This function has been deprecated.  Use `chol' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+hypergeometric_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 405
+ -- Function File:  hypergeometric_pdf (X, M, T, N)
+     Compute the probability density function (PDF) at X of the hypergeometric distribution with parameters M, T, and N.  This is the probability of obtaining X marked items when randomly drawing a sample of size N without replacement from a population of total size T containing M marked items.
+
+     The arguments must be of common size or scalar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+Compute the probability density function (PDF) at X of the hypergeometric distribution with parameters M, T, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+loadimage
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 214
+ -- Function File: [X, MAP] = loadimage (FILE)
+     Load an image file and its associated color map from the specified FILE.  The image must be stored in Octave's image format.  See also: saveimage, load, save.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Load an image file and its associated color map from the specified FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+binomial_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 180
+ -- Function File:  binomial_pdf (X, N, P)
+     For each element of X, compute the probability density function (PDF) at X of the binomial distribution with parameters N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+For each element of X, compute the probability density function (PDF) at X of the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spsumsq
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+ -- Function File:  spsumsq (X, DIM)
+     This function has been deprecated.  Use `sumsq' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+chisquare_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 330
+ -- Function File:  chisquare_rnd (N, R, C)
+ -- Function File:  chisquare_rnd (N, SZ)
+     Return an R by C  or a `size (SZ)' matrix of random samples from the chisquare distribution with N degrees of freedom.  N must be a scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the size of N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+Return an R by C or a `size (SZ)' matrix of random samples from the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+splchol
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 208
+ -- Loadable Function: L = splchol (A)
+ -- Loadable Function: [L, P] = splchol (A)
+ -- Loadable Function: [L, P, Q] = splchol (A)
+     This function has been deprecated.  Use `chol (...,'lower')' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+spinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+ -- Function File: [X, RCOND] = spinv (A)
+     This function has been deprecated.  Use `inv' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+spsum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+ -- Function File:  spsum (X, DIM)
+     This function has been deprecated.  Use `sum' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+poisson_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 179
+ -- Function File:  poisson_inv (X, LAMBDA)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the Poisson distribution with parameter LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+For each component of X, compute the quantile (the inverse of the CDF) at X of the Poisson distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+beta_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 339
+ -- Function File:  beta_rnd (A, B, R, C)
+ -- Function File:  beta_rnd (A, B, SZ)
+     Return an R by C or `size (SZ)' matrix of random samples from the Beta distribution with parameters A and B.  Both A and B must be scalar or of size R  by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Return an R by C or `size (SZ)' matrix of random samples from the Beta distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+chisquare_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 185
+ -- Function File:  chisquare_cdf (X, N)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the chisquare distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+For each element of X, compute the cumulative distribution function (CDF) at X of the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+mark_as_command
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+ -- Built-in Function:  mark_as_command (NAME)
+     This function is obsolete and will be removed from a future version of Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+This function is obsolete and will be removed from a future version of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+hypergeometric_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 458
+ -- Function File:  hypergeometric_cdf (X, M, T, N)
+     Compute the cumulative distribution function (CDF) at X of the hypergeometric distribution with parameters M, T, and N.  This is the probability of obtaining not more than X marked items when randomly drawing a sample of size N without replacement from a population of total size T containing M marked items.
+
+     The parameters M, T, and N must positive integers with M and N not greater than T.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+Compute the cumulative distribution function (CDF) at X of the hypergeometric distribution with parameters M, T, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_scalar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  is_scalar (A)
+     This function has been deprecated.  Use isscalar instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+uniform_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 335
+ -- Function File:  uniform_rnd (A, B, R, C)
+ -- Function File:  uniform_rnd (A, B, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from the uniform distribution on [A, B].  Both A and B must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Return an R by C or a `size (SZ)' matrix of random samples from the uniform distribution on [A, B].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+create_set
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 142
+ -- Function File:  create_set (X)
+ -- Function File:  create_set (X, "rows")
+     This function has been deprecated.  Use unique instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+unmark_rawcommand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+ -- Built-in Function:  unmark_rawcommand (NAME)
+     This function is obsolete and will be removed from a future version of Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+This function is obsolete and will be removed from a future version of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+struct_elements
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Function File:  struct_elements (STRUCT)
+     This function has been deprecated.  Use fieldnames instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+beta_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Function File:  beta_inv (X, A, B)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the Beta distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+For each component of X, compute the quantile (the inverse of the CDF) at X of the Beta distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+gamma_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 175
+ -- Function File:  gamma_inv (X, A, B)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the Gamma distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+For each component of X, compute the quantile (the inverse of the CDF) at X of the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+split
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+ -- Function File:  split (S, T, N)
+     This function has been deprecated.  Use `char (strsplit (s, t))' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+clg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+ -- Function File:  clg ()
+     This function has been deprecated.  Use clf instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+exponential_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 181
+ -- Function File:  exponential_pdf (X, LAMBDA)
+     For each element of X, compute the probability density function (PDF) of the exponential distribution with parameter LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+For each element of X, compute the probability density function (PDF) of the exponential distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+f_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 167
+ -- Function File:  f_inv (X, M, N)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the F distribution with parameters M and N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+For each component of X, compute the quantile (the inverse of the CDF) at X of the F distribution with parameters M and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+normal_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 218
+ -- Function File:  normal_pdf (X, M, V)
+     For each element of X, compute the probability density function (PDF) at X of the normal distribution with mean M and variance V.
+
+     Default values are M = 0, V = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the probability density function (PDF) at X of the normal distribution with mean M and variance V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+binomial_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 353
+ -- Function File:  binomial_rnd (N, P, R, C)
+ -- Function File:  binomial_rnd (N, P, SZ)
+     Return an R by C  or a `size (SZ)' matrix of random samples from the binomial distribution with parameters N and P.  Both N and P must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Return an R by C or a `size (SZ)' matrix of random samples from the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+pascal_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 298
+ -- Function File:  pascal_cdf (X, N, P)
+     For each element of X, compute the CDF at x of the Pascal (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success probability P before the N-th success follows this distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+For each element of X, compute the CDF at x of the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+geometric_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 172
+ -- Function File:  geometric_pdf (X, P)
+     For each element of X, compute the probability density function (PDF) at X of the geometric distribution with parameter P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+For each element of X, compute the probability density function (PDF) at X of the geometric distribution with parameter P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+mark_as_rawcommand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 137
+ -- Built-in Function:  mark_as_rawcommand (NAME)
+     This function is obsolete and will be removed from a future version of Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+This function is obsolete and will be removed from a future version of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_vector
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  is_vector (A)
+     This function has been deprecated.  Use isvector instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+f_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 171
+ -- Function File:  f_cdf (X, M, N)
+     For each element of X, compute the CDF at X of the F distribution with M and N degrees of freedom, i.e., PROB (F (M, N) <= X).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+For each element of X, compute the CDF at X of the F distribution with M and N degrees of freedom, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+normal_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 217
+ -- Function File:  normal_inv (X, M, V)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the normal distribution with mean M and variance V.
+
+     Default values are M = 0, V = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+For each element of X, compute the quantile (the inverse of the CDF) at X of the normal distribution with mean M and variance V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+israwcommand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+ -- Built-in Function:  israwcommand (NAME)
+     This function is obsolete and will be removed from a future version of Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+This function is obsolete and will be removed from a future version of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+uniform_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 202
+ -- Function File:  uniform_inv (X, A, B)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the uniform distribution on [A, B].
+
+     Default values are A = 0, B = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+For each element of X, compute the quantile (the inverse of the CDF) at X of the uniform distribution on [A, B].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+geometric_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 141
+ -- Function File:  geometric_cdf (X, P)
+     For each element of X, compute the CDF at X of the geometric distribution with parameter P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+For each element of X, compute the CDF at X of the geometric distribution with parameter P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+binomial_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 149
+ -- Function File:  binomial_cdf (X, N, P)
+     For each element of X, compute the CDF at X of the binomial distribution with parameters N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+For each element of X, compute the CDF at X of the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+hypergeometric_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 302
+ -- Function File:  hypergeometric_rnd (M, T, N, R, C)
+ -- Function File:  hygernd (M, T, N, SZ)
+     Return an R by C matrix of random samples from the hypergeometric distribution with parameters M, T, and N.
+
+     The parameters M, T, and N must positive integers with M and N not greater than T.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+Return an R by C matrix of random samples from the hypergeometric distribution with parameters M, T, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+beta_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 172
+ -- Function File:  beta_cdf (X, A, B)
+     For each element of X, returns the CDF at X of the beta distribution with parameters A and B, i.e., PROB (beta (A, B) <= X).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+For each element of X, returns the CDF at X of the beta distribution with parameters A and B, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+is_symmetric
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+ -- Function File:  issymmetric (X, TOL)
+     This function has been deprecated.  Use issymmetric instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+weibull_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 405
+ -- Function File:  weibull_rnd (SHAPE, SCALE, R, C)
+ -- Function File:  weibull_rnd (SHAPE, SCALE, SZ)
+     Return an R by C matrix of random samples from the Weibull distribution with parameters SCALE and SHAPE which must be scalar or of size R by C.  Or if SZ is a vector return a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of ALPHA and SIGMA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Return an R by C matrix of random samples from the Weibull distribution with parameters SCALE and SHAPE which must be scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+lchol
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 157
+ -- Loadable Function: L = lchol (A)
+ -- Loadable Function: [L, P] = lchol (A)
+     This function has been deprecated.  Use `chol (...,'lower')' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+is_list
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+ -- Function File:  is_list (A)
+     This function has been deprecated.  Use islist instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+spqr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 224
+ -- Loadable Function: R = spqr (A)
+ -- Loadable Function: R = spqr (A,0)
+ -- Loadable Function: [C, R] = spqr (A,B)
+ -- Loadable Function: [C, R] = spqr (A,B,0)
+     This function has been deprecated.  Use `qr' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+t_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+ -- Function File:  t_cdf (X, N)
+     For each element of X, compute the CDF at X of the t (Student) distribution with N degrees of freedom, i.e., PROB (t(N) <= X).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+For each element of X, compute the CDF at X of the t (Student) distribution with N degrees of freedom, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+poisson_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 182
+ -- Function File:  poisson_cdf (X, LAMBDA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the Poisson distribution with parameter lambda.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the cumulative distribution function (CDF) at X of the Poisson distribution with parameter lambda.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+f_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 174
+ -- Function File:  f_pdf (X, M, N)
+     For each element of X, compute the probability density function (PDF) at X of the F distribution with M and N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the probability density function (PDF) at X of the F distribution with M and N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+spdet
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+ -- Loadable Function: [D, RCOND] = spdet (A)
+     This function has been deprecated.  Use `det' instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+is_stream
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Function File:  is_stream (A)
+     This function has been deprecated.  Use isstream instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+This function has been deprecated.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+pascal_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 400
+ -- Function File:  pascal_rnd (N, P, R, C)
+ -- Function File:  pascal_rnd (N, P, SZ)
+     Return an R by C matrix of random samples from the Pascal (negative binomial) distribution with parameters N and P.  Both N and P must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of N and P.  Or if SZ is a vector, create a matrix of size SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+Return an R by C matrix of random samples from the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+hotelling_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 540
+ -- Function File: [PVAL, TSQ] = hotelling_test (X, M)
+     For a sample X from a multivariate normal distribution with unknown mean and covariance matrix, test the null hypothesis that `mean (X) == M'.
+
+     Hotelling's T^2 is returned in TSQ.  Under the null, (n-p) T^2 / (p(n-1)) has an F distribution with p and n-p degrees of freedom, where n and p are the numbers of samples and variables, respectively.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 142
+For a sample X from a multivariate normal distribution with unknown mean and covariance matrix, test the null hypothesis that `mean (X) == M'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+t_test_2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 839
+ -- Function File: [PVAL, T, DF] = t_test_2 (X, Y, ALT)
+     For two samples x and y from normal distributions with unknown means and unknown equal variances, perform a two-sample t-test of the null hypothesis of equal means.  Under the null, the test statistic T follows a Student distribution with DF degrees of freedom.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `mean (X) != mean (Y)'.  If ALT is `">"', the one-sided alternative `mean (X) > mean (Y)' is used.  Similarly for `"<"', the one-sided alternative `mean (X) < mean (Y)' is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 164
+For two samples x and y from normal distributions with unknown means and unknown equal variances, perform a two-sample t-test of the null hypothesis of equal means.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+t_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 811
+ -- Function File: [PVAL, T, DF] = t_test (X, M, ALT)
+     For a sample X from a normal distribution with unknown mean and variance, perform a t-test of the null hypothesis `mean (X) == M'.  Under the null, the test statistic T follows a Student distribution with `DF = length (X) - 1' degrees of freedom.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `mean (X) != M'.  If ALT is `">"', the one-sided alternative `mean (X) > M' is considered.  Similarly for "<", the one-sided alternative `mean (X) < M' is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+For a sample X from a normal distribution with unknown mean and variance, perform a t-test of the null hypothesis `mean (X) == M'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cor_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1347
+ -- Function File:  cor_test (X, Y, ALT, METHOD)
+     Test whether two samples X and Y come from uncorrelated populations.
+
+     The optional argument string ALT describes the alternative hypothesis, and can be `"!="' or `"<>"' (non-zero), `">"' (greater than 0), or `"<"' (less than 0).  The default is the two-sided case.
+
+     The optional argument string METHOD specifies on which correlation coefficient the test should be based.  If METHOD is `"pearson"' (default), the (usual) Pearson's product moment correlation coefficient is used.  In this case, the data should come from a bivariate normal distribution.  Otherwise, the other two methods offer nonparametric alternatives.  If METHOD is `"kendall"', then Kendall's rank correlation tau is used.  If METHOD is `"spearman"', then Spearman's rank correlation rho is used.  Only the first character is necessary.
+
+     The output is a structure with the following elements:
+
+    PVAL
+          The p-value of the test.
+
+    STAT
+          The value of the test statistic.
+
+    DIST
+          The distribution of the test statistic.
+
+    PARAMS
+          The parameters of the null distribution of the test statistic.
+
+    ALTERNATIVE
+          The alternative hypothesis.
+
+    METHOD
+          The method used for testing.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Test whether two samples X and Y come from uncorrelated populations.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+f_test_regression
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 491
+ -- Function File: [PVAL, F, DF_NUM, DF_DEN] = f_test_regression (Y, X, RR, R)
+     Perform an F test for the null hypothesis rr * b = r in a classical normal regression model y = X * b + e.
+
+     Under the null, the test statistic F follows an F distribution with DF_NUM and DF_DEN degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at F) is returned in PVAL.
+
+     If not given explicitly, R = 0.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 106
+Perform an F test for the null hypothesis rr * b = r in a classical normal regression model y = X * b + e.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+z_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 809
+ -- Function File: [PVAL, Z] = z_test (X, M, V, ALT)
+     Perform a Z-test of the null hypothesis `mean (X) == M' for a sample X from a normal distribution with unknown mean and known variance V.  Under the null, the test statistic Z follows a standard normal distribution.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `mean (X) != M'.  If ALT is `">"', the one-sided alternative `mean (X) > M' is considered.  Similarly for `"<"', the one-sided alternative `mean (X) < M' is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed along with some information.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 137
+Perform a Z-test of the null hypothesis `mean (X) == M' for a sample X from a normal distribution with unknown mean and known variance V.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+welch_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 853
+ -- Function File: [PVAL, T, DF] = welch_test (X, Y, ALT)
+     For two samples X and Y from normal distributions with unknown means and unknown and not necessarily equal variances, perform a Welch test of the null hypothesis of equal means.  Under the null, the test statistic T approximately follows a Student distribution with DF degrees of freedom.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `mean (X) != M'.  If ALT is `">"', the one-sided alternative mean(x) > M is considered.  Similarly for `"<"', the one-sided alternative mean(x) < M is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 177
+For two samples X and Y from normal distributions with unknown means and unknown and not necessarily equal variances, perform a Welch test of the null hypothesis of equal means.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+mcnemar_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 524
+ -- Function File: [PVAL, CHISQ, DF] = mcnemar_test (X)
+     For a square contingency table X of data cross-classified on the row and column variables, McNemar's test can be used for testing the null hypothesis of symmetry of the classification probabilities.
+
+     Under the null, CHISQ is approximately distributed as chisquare with DF degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at CHISQ) is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 198
+For a square contingency table X of data cross-classified on the row and column variables, McNemar's test can be used for testing the null hypothesis of symmetry of the classification probabilities.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+anova
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 957
+ -- Function File: [PVAL, F, DF_B, DF_W] = anova (Y, G)
+     Perform a one-way analysis of variance (ANOVA).  The goal is to test whether the population means of data taken from K different groups are all equal.
+
+     Data may be given in a single vector Y with groups specified by a corresponding vector of group labels G (e.g., numbers from 1 to K).  This is the general form which does not impose any restriction on the number of data in each group or the group labels.
+
+     If Y is a matrix and G is omitted, each column of Y is treated as a group.  This form is only appropriate for balanced ANOVA in which the numbers of samples from each group are all equal.
+
+     Under the null of constant means, the statistic F follows an F distribution with DF_B and DF_W degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at F) is returned in PVAL.
+
+     If no output argument is given, the standard one-way ANOVA table is printed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Perform a one-way analysis of variance (ANOVA).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+kolmogorov_smirnov_test_2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1111
+ -- Function File: [PVAL, KS, D] = kolmogorov_smirnov_test_2 (X, Y, ALT)
+     Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis that the samples X and Y come from the same (continuous) distribution.  I.e., if F and G are the CDFs corresponding to the X and Y samples, respectively, then the null is that F == G.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative F != G.  In this case, the test statistic KS follows a two-sided Kolmogorov-Smirnov distribution.  If ALT is `">"', the one-sided alternative F > G is considered.  Similarly for `"<"', the one-sided alternative F < G is considered.  In this case, the test statistic KS has a one-sided Kolmogorov-Smirnov distribution.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     The third returned value, D, is the test statistic, the maximum vertical distance between the two cumulative distribution functions.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis that the samples X and Y come from the same (continuous) distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 27
+chisquare_test_independence
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 441
+ -- Function File: [PVAL, CHISQ, DF] = chisquare_test_independence (X)
+     Perform a chi-square test for independence based on the contingency table X.  Under the null hypothesis of independence, CHISQ approximately has a chi-square distribution with DF degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at chisq) of the test is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Perform a chi-square test for independence based on the contingency table X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 19
+kruskal_wallis_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1087
+ -- Function File: [PVAL, K, DF] = kruskal_wallis_test (X1, ...)
+     Perform a Kruskal-Wallis one-factor "analysis of variance".
+
+     Suppose a variable is observed for K > 1 different groups, and let X1, ..., XK be the corresponding data vectors.
+
+     Under the null hypothesis that the ranks in the pooled sample are not affected by the group memberships, the test statistic K is approximately chi-square with DF = K - 1 degrees of freedom.
+
+     If the data contains ties (some value appears more than once) K is divided by
+
+     1 - SUM_TIES / (N^3 - N)
+
+     where SUM_TIES is the sum of T^2 - T over each group of ties where T is the number of ties in the group and N is the total number of values in the input data.  For more info on this adjustment see "Use of Ranks in One-Criterion Variance Analysis" in Journal of the American Statistical Association, Vol. 47, No. 260 (Dec 1952) by William H. Kruskal and W. Allen Wallis.
+
+     The p-value (1 minus the CDF of this distribution at K) is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Perform a Kruskal-Wallis one-factor "analysis of variance".
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+run_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 327
+ -- Function File: [PVAL, CHISQ] = run_test (X)
+     Perform a chi-square test with 6 degrees of freedom based on the upward runs in the columns of X.  Can be used to test whether X contains independent data.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Perform a chi-square test with 6 degrees of freedom based on the upward runs in the columns of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+t_test_regression
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 814
+ -- Function File: [PVAL, T, DF] = t_test_regression (Y, X, RR, R, ALT)
+     Perform an t test for the null hypothesis `RR * B = R' in a classical normal regression model `Y = X * B + E'.  Under the null, the test statistic T follows a T distribution with DF degrees of freedom.
+
+     If R is omitted, a value of 0 is assumed.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `RR * B != R'.  If ALT is `">"', the one-sided alternative `RR * B > R' is used.  Similarly for "<", the one-sided alternative `RR * B < R' is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+Perform an t test for the null hypothesis `RR * B = R' in a classical normal regression model `Y = X * B + E'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+z_test_2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 842
+ -- Function File: [PVAL, Z] = z_test_2 (X, Y, V_X, V_Y, ALT)
+     For two samples X and Y from normal distributions with unknown means and known variances V_X and V_Y, perform a Z-test of the hypothesis of equal means.  Under the null, the test statistic Z follows a standard normal distribution.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `mean (X) != mean (Y)'.  If alt is `">"', the one-sided alternative `mean (X) > mean (Y)' is used.  Similarly for `"<"', the one-sided alternative `mean (X) < mean (Y)' is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed along with some information.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+For two samples X and Y from normal distributions with unknown means and known variances V_X and V_Y, perform a Z-test of the hypothesis of equal means.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+kolmogorov_smirnov_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1293
+ -- Function File: [PVAL, KS] = kolmogorov_smirnov_test (X, DIST, PARAMS, ALT)
+     Perform a Kolmogorov-Smirnov test of the null hypothesis that the sample X comes from the (continuous) distribution dist.  I.e., if F and G are the CDFs corresponding to the sample and dist, respectively, then the null is that F == G.
+
+     The optional argument PARAMS contains a list of parameters of DIST.  For example, to test whether a sample X comes from a uniform distribution on [2,4], use
+
+          kolmogorov_smirnov_test(x, "uniform", 2, 4)
+
+     DIST can be any string for which a function DIST_CDF that calculates the CDF of distribution DIST exists.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative F != G.  In this case, the test statistic KS follows a two-sided Kolmogorov-Smirnov distribution.  If ALT is `">"', the one-sided alternative F > G is considered.  Similarly for `"<"', the one-sided alternative F > G is considered.  In this case, the test statistic KS has a one-sided Kolmogorov-Smirnov distribution.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+Perform a Kolmogorov-Smirnov test of the null hypothesis that the sample X comes from the (continuous) distribution dist.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+u_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 847
+ -- Function File: [PVAL, Z] = u_test (X, Y, ALT)
+     For two samples X and Y, perform a Mann-Whitney U-test of the null hypothesis PROB (X > Y) == 1/2 == PROB (X < Y).  Under the null, the test statistic Z approximately follows a standard normal distribution.  Note that this test is equivalent to the Wilcoxon rank-sum test.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative PROB (X > Y) != 1/2.  If ALT is `">"', the one-sided alternative PROB (X > Y) > 1/2 is considered.  Similarly for `"<"', the one-sided alternative PROB (X > Y) < 1/2 is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+For two samples X and Y, perform a Mann-Whitney U-test of the null hypothesis PROB (X > Y) == 1/2 == PROB (X < Y).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+var_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 841
+ -- Function File: [PVAL, F, DF_NUM, DF_DEN] = var_test (X, Y, ALT)
+     For two samples X and Y from normal distributions with unknown means and unknown variances, perform an F-test of the null hypothesis of equal variances.  Under the null, the test statistic F follows an F-distribution with DF_NUM and DF_DEN degrees of freedom.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative `var (X) != var (Y)'.  If ALT is `">"', the one-sided alternative `var (X) > var (Y)' is used.  Similarly for "<", the one-sided alternative `var (X) > var (Y)' is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+For two samples X and Y from normal distributions with unknown means and unknown variances, perform an F-test of the null hypothesis of equal variances.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+sign_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 905
+ -- Function File: [PVAL, B, N] = sign_test (X, Y, ALT)
+     For two matched-pair samples X and Y, perform a sign test of the null hypothesis PROB (X > Y) == PROB (X < Y) == 1/2.  Under the null, the test statistic B roughly follows a binomial distribution with parameters `N = sum (X != Y)' and P = 1/2.
+
+     With the optional argument `alt', the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null hypothesis is tested against the two-sided alternative PROB (X < Y) != 1/2.  If ALT is `">"', the one-sided alternative PROB (X > Y) > 1/2 ("x is stochastically greater than y") is considered.  Similarly for `"<"', the one-sided alternative PROB (X > Y) < 1/2 ("x is stochastically less than y") is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+For two matched-pair samples X and Y, perform a sign test of the null hypothesis PROB (X > Y) == PROB (X < Y) == 1/2.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+manova
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 614
+ -- Function File:  manova (Y, G)
+     Perform a one-way multivariate analysis of variance (MANOVA).  The goal is to test whether the p-dimensional population means of data taken from K different groups are all equal.  All data are assumed drawn independently from p-dimensional normal distributions with the same covariance matrix.
+
+     The data matrix is given by Y.  As usual, rows are observations and columns are variables.  The vector G specifies the corresponding group labels (e.g., numbers from 1 to K).
+
+     The LR test statistic (Wilks' Lambda) and approximate p-values are computed and displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Perform a one-way multivariate analysis of variance (MANOVA).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+wilcoxon_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 910
+ -- Function File: [PVAL, Z] = wilcoxon_test (X, Y, ALT)
+     For two matched-pair sample vectors X and Y, perform a Wilcoxon signed-rank test of the null hypothesis PROB (X > Y) == 1/2.  Under the null, the test statistic Z approximately follows a standard normal distribution when N > 25.
+
+     *Warning*: This function assumes a normal distribution for Z and thus is invalid for N <= 25.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative PROB (X > Y) != 1/2.  If alt is `">"', the one-sided alternative PROB (X > Y) > 1/2 is considered.  Similarly for `"<"', the one-sided alternative PROB (X > Y) < 1/2 is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+For two matched-pair sample vectors X and Y, perform a Wilcoxon signed-rank test of the null hypothesis PROB (X > Y) == 1/2.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+hotelling_test_2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 656
+ -- Function File: [PVAL, TSQ] = hotelling_test_2 (X, Y)
+     For two samples X from multivariate normal distributions with the same number of variables (columns), unknown means and unknown equal covariance matrices, test the null hypothesis `mean (X) == mean (Y)'.
+
+     Hotelling's two-sample T^2 is returned in TSQ.  Under the null,
+
+          (n_x+n_y-p-1) T^2 / (p(n_x+n_y-2))
+
+     has an F distribution with p and n_x+n_y-p-1 degrees of freedom, where n_x and n_y are the sample sizes and p is the number of variables.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 203
+For two samples X from multivariate normal distributions with the same number of variables (columns), unknown means and unknown equal covariance matrices, test the null hypothesis `mean (X) == mean (Y)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+prop_test_2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 820
+ -- Function File: [PVAL, Z] = prop_test_2 (X1, N1, X2, N2, ALT)
+     If X1 and N1 are the counts of successes and trials in one sample, and X2 and N2 those in a second one, test the null hypothesis that the success probabilities P1 and P2 are the same.  Under the null, the test statistic Z approximately follows a standard normal distribution.
+
+     With the optional argument string ALT, the alternative of interest can be selected.  If ALT is `"!="' or `"<>"', the null is tested against the two-sided alternative P1 != P2.  If ALT is `">"', the one-sided alternative P1 > P2 is used.  Similarly for `"<"', the one-sided alternative P1 < P2 is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 183
+If X1 and N1 are the counts of successes and trials in one sample, and X2 and N2 those in a second one, test the null hypothesis that the success probabilities P1 and P2 are the same.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+bartlett_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 471
+ -- Function File: [PVAL, CHISQ, DF] = bartlett_test (X1, ...)
+     Perform a Bartlett test for the homogeneity of variances in the data vectors X1, X2, ..., XK, where K > 1.
+
+     Under the null of equal variances, the test statistic CHISQ approximately follows a chi-square distribution with DF degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at CHISQ) is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Perform a Bartlett test for the homogeneity of variances in the data vectors X1, X2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+chisquare_test_homogeneity
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 586
+ -- Function File: [PVAL, CHISQ, DF] = chisquare_test_homogeneity (X, Y, C)
+     Given two samples X and Y, perform a chisquare test for homogeneity of the null hypothesis that X and Y come from the same distribution, based on the partition induced by the (strictly increasing) entries of C.
+
+     For large samples, the test statistic CHISQ approximately follows a chisquare distribution with DF = `length (C)' degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at CHISQ) is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 210
+Given two samples X and Y, perform a chisquare test for homogeneity of the null hypothesis that X and Y come from the same distribution, based on the partition induced by the (strictly increasing) entries of C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+stdnormal_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 158
+ -- Function File:  stdnormal_pdf (X)
+     For each element of X, compute the probability density function (PDF) of the standard normal distribution at X.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+For each element of X, compute the probability density function (PDF) of the standard normal distribution at X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+binoinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 149
+ -- Function File:  binoinv (X, N, P)
+     For each element of X, compute the quantile at X of the binomial distribution with parameters N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+For each element of X, compute the quantile at X of the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+frnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 386
+ -- Function File:  frnd (M, N, R, C)
+ -- Function File:  frnd (M, N, SZ)
+     Return an R by C matrix of random samples from the F distribution with M and N degrees of freedom.  Both M and N must be scalar or of size R by C.  If SZ is a vector the random samples are in a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of M and N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Return an R by C matrix of random samples from the F distribution with M and N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gamrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 398
+ -- Function File:  gamrnd (A, B, R, C)
+ -- Function File:  gamrnd (A, B, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from the Gamma distribution with parameters A and B.  Both A and B must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and B.  See also: gamma, gammaln, gammainc, gampdf, gamcdf, gaminv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Return an R by C or a `size (SZ)' matrix of random samples from the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+norminv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 224
+ -- Function File:  norminv (X, M, S)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the normal distribution with mean M and standard deviation S.
+
+     Default values are M = 0, S = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+For each element of X, compute the quantile (the inverse of the CDF) at X of the normal distribution with mean M and standard deviation S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+poisscdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 179
+ -- Function File:  poisscdf (X, LAMBDA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the Poisson distribution with parameter lambda.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the cumulative distribution function (CDF) at X of the Poisson distribution with parameter lambda.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+poisspdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 175
+ -- Function File:  poisspdf (X, LAMBDA)
+     For each element of X, compute the probability density function (PDF) at X of the poisson distribution with parameter LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+For each element of X, compute the probability density function (PDF) at X of the poisson distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+geocdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+ -- Function File:  geocdf (X, P)
+     For each element of X, compute the CDF at X of the geometric distribution with parameter P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+For each element of X, compute the CDF at X of the geometric distribution with parameter P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+empirical_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 198
+ -- Function File:  empirical_inv (X, DATA)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the empirical distribution obtained from the univariate sample DATA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 145
+For each element of X, compute the quantile (the inverse of the CDF) at X of the empirical distribution obtained from the univariate sample DATA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gaminv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 233
+ -- Function File:  gaminv (X, A, B)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the Gamma distribution with parameters A and B.  See also: gamma, gammaln, gammainc, gampdf, gamcdf, gamrnd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+For each component of X, compute the quantile (the inverse of the CDF) at X of the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+discrete_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 220
+ -- Function File:  discrete_cdf (X, V, P)
+     For each element of X, compute the cumulative distribution function (CDF) at X of a univariate discrete distribution which assumes the values in V with probabilities P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+For each element of X, compute the cumulative distribution function (CDF) at X of a univariate discrete distribution which assumes the values in V with probabilities P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cauchy_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 265
+ -- Function File:  cauchy_pdf (X, LAMBDA, SIGMA)
+     For each element of X, compute the probability density function (PDF) at X of the Cauchy distribution with location parameter LAMBDA and scale parameter SIGMA > 0.  Default values are LAMBDA = 0, SIGMA = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 163
+For each element of X, compute the probability density function (PDF) at X of the Cauchy distribution with location parameter LAMBDA and scale parameter SIGMA > 0.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+betarnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 337
+ -- Function File:  betarnd (A, B, R, C)
+ -- Function File:  betarnd (A, B, SZ)
+     Return an R by C or `size (SZ)' matrix of random samples from the Beta distribution with parameters A and B.  Both A and B must be scalar or of size R  by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Return an R by C or `size (SZ)' matrix of random samples from the Beta distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+empirical_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 377
+ -- Function File:  empirical_rnd (N, DATA)
+ -- Function File:  empirical_rnd (DATA, R, C)
+ -- Function File:  empirical_rnd (DATA, SZ)
+     Generate a bootstrap sample of size N from the empirical distribution obtained from the univariate sample DATA.
+
+     If R and C are given create a matrix with R rows and C columns.  Or if SZ is a vector, create a matrix of size SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Generate a bootstrap sample of size N from the empirical distribution obtained from the univariate sample DATA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+stdnormal_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 159
+ -- Function File:  stdnormal_inv (X)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the standard normal distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+For each component of X, compute the quantile (the inverse of the CDF) at X of the standard normal distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+normcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 229
+ -- Function File:  normcdf (X, M, S)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the normal distribution with mean M and standard deviation S.
+
+     Default values are M = 0, S = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+For each element of X, compute the cumulative distribution function (CDF) at X of the normal distribution with mean M and standard deviation S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gampdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 231
+ -- Function File:  gampdf (X, A, B)
+     For each element of X, return the probability density function (PDF) at X of the Gamma distribution with parameters A and B.  See also: gamma, gammaln, gammainc, gamcdf, gaminv, gamrnd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+For each element of X, return the probability density function (PDF) at X of the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+discrete_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 427
+ -- Function File:  discrete_rnd (N, V, P)
+ -- Function File:  discrete_rnd (V, P, R, C)
+ -- Function File:  discrete_rnd (V, P, SZ)
+     Generate a row vector containing a random sample of size N from the univariate distribution which assumes the values in V with probabilities P.  N must be a scalar.
+
+     If R and C are given create a matrix with R rows and C columns.  Or if SZ is a vector, create a matrix of size SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Generate a row vector containing a random sample of size N from the univariate distribution which assumes the values in V with probabilities P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+chi2cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 179
+ -- Function File:  chi2cdf (X, N)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the chisquare distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+For each element of X, compute the cumulative distribution function (CDF) at X of the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+expinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 171
+ -- Function File:  expinv (X, LAMBDA)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the exponential distribution with mean LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+For each element of X, compute the quantile (the inverse of the CDF) at X of the exponential distribution with mean LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+chi2pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 181
+ -- Function File:  chisquare_pdf (X, N)
+     For each element of X, compute the probability density function (PDF) at X of the chisquare distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+For each element of X, compute the probability density function (PDF) at X of the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unifcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 178
+ -- Function File:  unifcdf (X, A, B)
+     Return the CDF at X of the uniform distribution on [A, B], i.e., PROB (uniform (A, B) <= x).
+
+     Default values are A = 0, B = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Return the CDF at X of the uniform distribution on [A, B], i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+betapdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 140
+ -- Function File:  betapdf (X, A, B)
+     For each element of X, returns the PDF at X of the beta distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+For each element of X, returns the PDF at X of the beta distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+stdnormal_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 184
+ -- Function File:  stdnormal_rnd (R, C)
+ -- Function File:  stdnormal_rnd (SZ)
+     Return an R by C or `size (SZ)' matrix of random numbers from the standard normal distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Return an R by C or `size (SZ)' matrix of random numbers from the standard normal distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unidrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 461
+ -- Function File:  unidrnd (MX);
+ -- Function File:  unidrnd (MX, V);
+ -- Function File:  unidrnd (MX, M, N, ...);
+     Return random values from discrete uniform distribution, with maximum value(s) given by the integer MX, which may be a scalar or multidimensional array.
+
+     If MX is a scalar, the size of the result is specified by the vector V, or by the optional arguments M, N, ....  Otherwise, the size of the result is the same as the size of MX.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+Return random values from discrete uniform distribution, with maximum value(s) given by the integer MX, which may be a scalar or multidimensional array.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hygepdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 394
+ -- Function File:  hygepdf (X, T, M, N)
+     Compute the probability density function (PDF) at X of the hypergeometric distribution with parameters T, M, and N.  This is the probability of obtaining X marked items when randomly drawing a sample of size N without replacement from a population of total size T containing M marked items.
+
+     The arguments must be of common size or scalar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+Compute the probability density function (PDF) at X of the hypergeometric distribution with parameters T, M, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+wblrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 395
+ -- Function File:  wblrnd (SCALE, SHAPE, R, C)
+ -- Function File:  wblrnd (SCALE, SHAPE, SZ)
+     Return an R by C matrix of random samples from the Weibull distribution with parameters SCALE and SHAPE which must be scalar or of size R by C.  Or if SZ is a vector return a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of ALPHA and SIGMA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Return an R by C matrix of random samples from the Weibull distribution with parameters SCALE and SHAPE which must be scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cauchy_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 265
+ -- Function File:  cauchy_cdf (X, LAMBDA, SIGMA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the Cauchy distribution with location parameter LAMBDA and scale parameter SIGMA.  Default values are LAMBDA = 0, SIGMA = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 163
+For each element of X, compute the cumulative distribution function (CDF) at X of the Cauchy distribution with location parameter LAMBDA and scale parameter SIGMA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+normrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 363
+ -- Function File:  normrnd (M, S, R, C)
+ -- Function File:  normrnd (M, S, SZ)
+     Return an R by C  or `size (SZ)' matrix of random samples from the normal distribution with parameters mean M and standard deviation S.  Both M and S must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of M and S.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+Return an R by C or `size (SZ)' matrix of random samples from the normal distribution with parameters mean M and standard deviation S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+exppdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 167
+ -- Function File:  exppdf (X, LAMBDA)
+     For each element of X, compute the probability density function (PDF) of the exponential distribution with mean LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+For each element of X, compute the probability density function (PDF) of the exponential distribution with mean LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unidinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 212
+ -- Function File:  unidinv (X, V)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the univariate discrete distribution which assumes the values in V with equal probability
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 170
+For each component of X, compute the quantile (the inverse of the CDF) at X of the univariate discrete distribution which assumes the values in V with equal probability  
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+finv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 166
+ -- Function File:  finv (X, M, N)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the F distribution with parameters M and N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+For each component of X, compute the quantile (the inverse of the CDF) at X of the F distribution with parameters M and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+normpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Function File:  normpdf (X, M, S)
+     For each element of X, compute the probability density function (PDF) at X of the normal distribution with mean M and standard deviation S.
+
+     Default values are M = 0, S = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 139
+For each element of X, compute the probability density function (PDF) at X of the normal distribution with mean M and standard deviation S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+logninv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 357
+ -- Function File:  logninv (X, MU, SIGMA)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the lognormal distribution with parameters MU and SIGMA.  If a random variable follows this distribution, its logarithm is normally distributed with mean `log (MU)' and variance SIGMA.
+
+     Default values are MU = 1, SIGMA = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+For each element of X, compute the quantile (the inverse of the CDF) at X of the lognormal distribution with parameters MU and SIGMA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+expcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 229
+ -- Function File:  expcdf (X, LAMBDA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the exponential distribution with mean LAMBDA.
+
+     The arguments can be of common size or scalar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+For each element of X, compute the cumulative distribution function (CDF) at X of the exponential distribution with mean LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+logncdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 364
+ -- Function File:  logncdf (X, MU, SIGMA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the lognormal distribution with parameters MU and SIGMA.  If a random variable follows this distribution, its logarithm is normally distributed with mean MU and standard deviation SIGMA.
+
+     Default values are MU = 1, SIGMA = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+For each element of X, compute the cumulative distribution function (CDF) at X of the lognormal distribution with parameters MU and SIGMA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+laplace_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 148
+ -- Function File:  laplace_pdf (X)
+     For each element of X, compute the probability density function (PDF) at X of the Laplace distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+For each element of X, compute the probability density function (PDF) at X of the Laplace distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+laplace_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 204
+ -- Function File:  laplace_rnd (R, C)
+ -- Function File:  laplace_rnd (SZ);
+     Return an R by C matrix of random numbers from the Laplace distribution.  Or if SZ is a vector, create a matrix of SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Return an R by C matrix of random numbers from the Laplace distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+lognrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 402
+ -- Function File:  lognrnd (MU, SIGMA, R, C)
+ -- Function File:  lognrnd (MU, SIGMA, SZ)
+     Return an R by C matrix of random samples from the lognormal distribution with parameters MU and SIGMA.  Both MU and SIGMA must be scalar or of size R by C.  Or if SZ is a vector, create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the common size of MU and SIGMA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+Return an R by C matrix of random samples from the lognormal distribution with parameters MU and SIGMA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+poissinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 176
+ -- Function File:  poissinv (X, LAMBDA)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the Poisson distribution with parameter LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+For each component of X, compute the quantile (the inverse of the CDF) at X of the Poisson distribution with parameter LAMBDA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hygeinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 251
+ -- Function File:  hygeinv (X, T, M, N)
+     For each element of X, compute the quantile at X of the hypergeometric distribution with parameters T, M, and N.
+
+     The parameters T, M, and N must positive integers with M and N not greater than T.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+For each element of X, compute the quantile at X of the hypergeometric distribution with parameters T, M, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 170
+ -- Function File:  fcdf (X, M, N)
+     For each element of X, compute the CDF at X of the F distribution with M and N degrees of freedom, i.e., PROB (F (M, N) <= X).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+For each element of X, compute the CDF at X of the F distribution with M and N degrees of freedom, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+stdnormal_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+ -- Function File:  stdnormal_cdf (X)
+     For each component of X, compute the CDF of the standard normal distribution at X.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+For each component of X, compute the CDF of the standard normal distribution at X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nbininv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 300
+ -- Function File:  nbininv (X, N, P)
+     For each element of X, compute the quantile at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success probability P before the N-th success follows this distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+For each element of X, compute the quantile at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+logistic_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+ -- Function File:  logistic_inv (X)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the logistic distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+For each component of X, compute the quantile (the inverse of the CDF) at X of the logistic distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hygecdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 447
+ -- Function File:  hygecdf (X, T, M, N)
+     Compute the cumulative distribution function (CDF) at X of the hypergeometric distribution with parameters T, M, and N.  This is the probability of obtaining not more than X marked items when randomly drawing a sample of size N without replacement from a population of total size T containing M marked items.
+
+     The parameters T, M, and N must positive integers with M and N not greater than T.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 119
+Compute the cumulative distribution function (CDF) at X of the hypergeometric distribution with parameters T, M, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unidpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 210
+ -- Function File:  unidpdf (X, V)
+     For each element of X, compute the probability density function (PDF) at X of a univariate discrete distribution which assumes the values in V with equal probability.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 166
+For each element of X, compute the probability density function (PDF) at X of a univariate discrete distribution which assumes the values in V with equal probability.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+logistic_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Function File:  logistic_cdf (X)
+     For each component of X, compute the CDF at X of the logistic distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+For each component of X, compute the CDF at X of the logistic distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gamcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 236
+ -- Function File:  gamcdf (X, A, B)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the Gamma distribution with parameters A and B.  See also: gamma, gammaln, gammainc, gampdf, gaminv, gamrnd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the cumulative distribution function (CDF) at X of the Gamma distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unifinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 198
+ -- Function File:  unifinv (X, A, B)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the uniform distribution on [A, B].
+
+     Default values are A = 0, B = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+For each element of X, compute the quantile (the inverse of the CDF) at X of the uniform distribution on [A, B].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+tpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 174
+ -- Function File:  tpdf (X, N)
+     For each element of X, compute the probability density function (PDF) at X of the T (Student) distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+For each element of X, compute the probability density function (PDF) at X of the T (Student) distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nbinpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 326
+ -- Function File:  nbinpdf (X, N, P)
+     For each element of X, compute the probability density function (PDF) at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success probability P before the N-th success follows this distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+For each element of X, compute the probability density function (PDF) at X of the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+geoinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 139
+ -- Function File:  geoinv (X, P)
+     For each element of X, compute the quantile at X of the geometric distribution with parameter P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+For each element of X, compute the quantile at X of the geometric distribution with parameter P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+discrete_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 210
+ -- Function File:  discrete_inv (X, V, P)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the univariate distribution which assumes the values in V with probabilities P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 158
+For each component of X, compute the quantile (the inverse of the CDF) at X of the univariate distribution which assumes the values in V with probabilities P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unidcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 214
+ -- Function File:  unidcdf (X, V)
+     For each element of X, compute the cumulative distribution function (CDF) at X of a univariate discrete distribution which assumes the values in V with equal probability.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 170
+For each element of X, compute the cumulative distribution function (CDF) at X of a univariate discrete distribution which assumes the values in V with equal probability.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+binopdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 175
+ -- Function File:  binopdf (X, N, P)
+     For each element of X, compute the probability density function (PDF) at X of the binomial distribution with parameters N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+For each element of X, compute the probability density function (PDF) at X of the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+wblcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 254
+ -- Function File:  wblcdf (X, SCALE, SHAPE)
+     Compute the cumulative distribution function (CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE, which is
+
+          1 - exp(-(x/shape)^scale)
+     for X >= 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+Compute the cumulative distribution function (CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE, which is 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hygernd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 474
+ -- Function File:  hygernd (T, M, N, R, C)
+ -- Function File:  hygernd (T, M, N, SZ)
+ -- Function File:  hygernd (T, M, N)
+     Return an R by C matrix of random samples from the hypergeometric distribution with parameters T, M, and N.
+
+     The parameters T, M, and N must positive integers with M and N not greater than T.
+
+     The parameter SZ must be scalar or a vector of matrix dimensions.  If SZ is scalar, then a SZ by SZ matrix of random samples is generated.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+Return an R by C matrix of random samples from the hypergeometric distribution with parameters T, M, and N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+trnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 346
+ -- Function File:  trnd (N, R, C)
+ -- Function File:  trnd (N, SZ)
+     Return an R by C matrix of random samples from the t (Student) distribution with N degrees of freedom.  N must be a scalar or of size R by C.  Or if SZ is a vector create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the size of N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+Return an R by C matrix of random samples from the t (Student) distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+kolmogorov_smirnov_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 365
+ -- Function File:  kolmogorov_smirnov_cdf (X, TOL)
+     Return the CDF at X of the Kolmogorov-Smirnov distribution,
+                   Inf
+          Q(x) =   SUM    (-1)^k exp(-2 k^2 x^2)
+                 k = -Inf
+
+     for X > 0.
+
+     The optional parameter TOL specifies the precision up to which the series should be evaluated;  the default is TOL = `eps'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+Return the CDF at X of the Kolmogorov-Smirnov distribution,  Inf  Q(x) = SUM (-1)^k exp(-2 k^2 x^2)  k = -Inf 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+laplace_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 152
+ -- Function File:  laplace_cdf (X)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the Laplace distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+For each element of X, compute the cumulative distribution function (CDF) at X of the Laplace distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+exprnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 360
+ -- Function File:  exprnd (LAMBDA, R, C)
+ -- Function File:  exprnd (LAMBDA, SZ)
+     Return an R by C matrix of random samples from the exponential distribution with mean LAMBDA, which must be a scalar or of size R by C.  Or if SZ is a vector, create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the size of LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+Return an R by C matrix of random samples from the exponential distribution with mean LAMBDA, which must be a scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+poissrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 272
+ -- Function File:  poissrnd (LAMBDA, R, C)
+     Return an R by C matrix of random samples from the Poisson distribution with parameter LAMBDA, which must be a scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the size of LAMBDA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+Return an R by C matrix of random samples from the Poisson distribution with parameter LAMBDA, which must be a scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+chi2inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 174
+ -- Function File:  chi2inv (X, N)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the chisquare distribution with N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+For each element of X, compute the quantile (the inverse of the CDF) at X of the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unifrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 327
+ -- Function File:  unifrnd (A, B, R, C)
+ -- Function File:  unifrnd (A, B, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from the uniform distribution on [A, B].  Both A and B must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Return an R by C or a `size (SZ)' matrix of random samples from the uniform distribution on [A, B].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+logistic_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 206
+ -- Function File:  logistic_rnd (R, C)
+ -- Function File:  logistic_rnd (SZ)
+     Return an R by C matrix of random numbers from the logistic distribution.  Or if SZ is a vector, create a matrix of SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Return an R by C matrix of random numbers from the logistic distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cauchy_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 378
+ -- Function File:  cauchy_rnd (LAMBDA, SIGMA, R, C)
+ -- Function File:  cauchy_rnd (LAMBDA, SIGMA, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from the Cauchy distribution with parameters LAMBDA and SIGMA which must both be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of LAMBDA and SIGMA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 165
+Return an R by C or a `size (SZ)' matrix of random samples from the Cauchy distribution with parameters LAMBDA and SIGMA which must both be scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+betainv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 172
+ -- Function File:  betainv (X, A, B)
+     For each component of X, compute the quantile (the inverse of the CDF) at X of the Beta distribution with parameters A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+For each component of X, compute the quantile (the inverse of the CDF) at X of the Beta distribution with parameters A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+unifpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+ -- Function File:  unifpdf (X, A, B)
+     For each element of X, compute the PDF at X of the uniform distribution on [A, B].
+
+     Default values are A = 0, B = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+For each element of X, compute the PDF at X of the uniform distribution on [A, B].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+betacdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 171
+ -- Function File:  betacdf (X, A, B)
+     For each element of X, returns the CDF at X of the beta distribution with parameters A and B, i.e., PROB (beta (A, B) <= X).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+For each element of X, returns the CDF at X of the beta distribution with parameters A and B, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+lognpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 360
+ -- Function File:  lognpdf (X, MU, SIGMA)
+     For each element of X, compute the probability density function (PDF) at X of the lognormal distribution with parameters MU and SIGMA.  If a random variable follows this distribution, its logarithm is normally distributed with mean MU and standard deviation SIGMA.
+
+     Default values are MU = 1, SIGMA = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+For each element of X, compute the probability density function (PDF) at X of the lognormal distribution with parameters MU and SIGMA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nbincdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 295
+ -- Function File:  nbincdf (X, N, P)
+     For each element of X, compute the CDF at x of the Pascal (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success probability P before the N-th success follows this distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+For each element of X, compute the CDF at x of the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+geopdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 165
+ -- Function File:  geopdf (X, P)
+     For each element of X, compute the probability density function (PDF) at X of the geometric distribution with parameter P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+For each element of X, compute the probability density function (PDF) at X of the geometric distribution with parameter P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+wienrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 432
+ -- Function File:  wienrnd (T, D, N)
+     Return a simulated realization of the D-dimensional Wiener Process on the interval [0, T].  If D is omitted, D = 1 is used.  The first column of the return matrix contains time, the remaining columns contain the Wiener process.
+
+     The optional parameter N gives the number of summands used for simulating the process over an interval of length 1.  If N is omitted, N = 1000 is used.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 90
+Return a simulated realization of the D-dimensional Wiener Process on the interval [0, T].
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+empirical_cdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 203
+ -- Function File:  empirical_cdf (X, DATA)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the empirical distribution obtained from the univariate sample DATA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+For each element of X, compute the cumulative distribution function (CDF) at X of the empirical distribution obtained from the univariate sample DATA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+geornd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 335
+ -- Function File:  geornd (P, R, C)
+ -- Function File:  geornd (P, SZ)
+     Return an R by C matrix of random samples from the geometric distribution with parameter P, which must be a scalar or of size R by C.
+
+     If R and C are given create a matrix with R rows and C columns.  Or if SZ is a vector, create a matrix of size SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+Return an R by C matrix of random samples from the geometric distribution with parameter P, which must be a scalar or of size R by C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+binocdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 144
+ -- Function File:  binocdf (X, N, P)
+     For each element of X, compute the CDF at X of the binomial distribution with parameters N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+For each element of X, compute the CDF at X of the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+tinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 294
+ -- Function File:  tinv (X, N)
+     For each probability value X, compute the inverse of the cumulative distribution function (CDF) of the t (Student) distribution with degrees of freedom N.  This function is analogous to looking in a table for the t-value of a single-tailed distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 154
+For each probability value X, compute the inverse of the cumulative distribution function (CDF) of the t (Student) distribution with degrees of freedom N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+binornd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 343
+ -- Function File:  binornd (N, P, R, C)
+ -- Function File:  binornd (N, P, SZ)
+     Return an R by C  or a `size (SZ)' matrix of random samples from the binomial distribution with parameters N and P.  Both N and P must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of N and P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Return an R by C or a `size (SZ)' matrix of random samples from the binomial distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+tcdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 202
+ -- Function File:  tcdf (X, N)
+     For each element of X, compute the cumulative distribution function (CDF) at X of the t (Student) distribution with N degrees of freedom, i.e., PROB (t(N) <= X).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 140
+For each element of X, compute the cumulative distribution function (CDF) at X of the t (Student) distribution with N degrees of freedom, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Function File:  fpdf (X, M, N)
+     For each element of X, compute the probability density function (PDF) at X of the F distribution with M and N degrees of freedom.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+For each element of X, compute the probability density function (PDF) at X of the F distribution with M and N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+wblinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 186
+ -- Function File:  wblinv (X, SCALE, SHAPE)
+     Compute the quantile (the inverse of the CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Compute the quantile (the inverse of the CDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+cauchy_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 260
+ -- Function File:  cauchy_inv (X, LAMBDA, SIGMA)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the Cauchy distribution with location parameter LAMBDA and scale parameter SIGMA.  Default values are LAMBDA = 0, SIGMA = 1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 158
+For each element of X, compute the quantile (the inverse of the CDF) at X of the Cauchy distribution with location parameter LAMBDA and scale parameter SIGMA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nbinrnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 394
+ -- Function File:  nbinrnd (N, P, R, C)
+ -- Function File:  nbinrnd (N, P, SZ)
+     Return an R by C matrix of random samples from the Pascal (negative binomial) distribution with parameters N and P.  Both N and P must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the common size of N and P.  Or if SZ is a vector, create a matrix of size SZ.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+Return an R by C matrix of random samples from the Pascal (negative binomial) distribution with parameters N and P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+empirical_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 199
+ -- Function File:  empirical_pdf (X, DATA)
+     For each element of X, compute the probability density function (PDF) at X of the empirical distribution obtained from the univariate sample DATA.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 146
+For each element of X, compute the probability density function (PDF) at X of the empirical distribution obtained from the univariate sample DATA.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+wblpdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 296
+ -- Function File:  wblpdf (X, SCALE, SHAPE)
+     Compute the probability density function (PDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE which is given by
+
+             scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+
+     for X > 0.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+Compute the probability density function (PDF) at X of the Weibull distribution with shape parameter SCALE and scale parameter SHAPE which is given by 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+laplace_inv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+ -- Function File:  laplace_inv (X)
+     For each element of X, compute the quantile (the inverse of the CDF) at X of the Laplace distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+For each element of X, compute the quantile (the inverse of the CDF) at X of the Laplace distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+chi2rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 318
+ -- Function File:  chi2rnd (N, R, C)
+ -- Function File:  chi2rnd (N, SZ)
+     Return an R by C  or a `size (SZ)' matrix of random samples from the chisquare distribution with N degrees of freedom.  N must be a scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the size of N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+Return an R by C or a `size (SZ)' matrix of random samples from the chisquare distribution with N degrees of freedom.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+discrete_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 216
+ -- Function File:  discrete_pdf (X, V, P)
+     For each element of X, compute the probability density function (PDF) at X of a univariate discrete distribution which assumes the values in V with probabilities P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 164
+For each element of X, compute the probability density function (PDF) at X of a univariate discrete distribution which assumes the values in V with probabilities P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+logistic_pdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Function File:  logistic_pdf (X)
+     For each component of X, compute the PDF at X of the logistic distribution.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+For each component of X, compute the PDF at X of the logistic distribution.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+logistic_regression_derivatives
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 206
+ -- Function File: [DL, D2L] = logistic_regression_derivatives (X, Z, Z1, G, G1, P)
+     Called by logistic_regression.  Calculates derivates of the log-likelihood for ordinal logistic regression model.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Called by logistic_regression.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 19
+logistic_regression
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1609
+ -- Function File: [THETA, BETA, DEV, DL, D2L, P] = logistic_regression (Y, X, PRINT, THETA, BETA)
+     Perform ordinal logistic regression.
+
+     Suppose Y takes values in K ordered categories, and let `gamma_i (X)' be the cumulative probability that Y falls in one of the first I categories given the covariate X.  Then
+
+          [theta, beta] = logistic_regression (y, x)
+
+     fits the model
+
+          logit (gamma_i (x)) = theta_i - beta' * x,   i = 1 ... k-1
+
+     The number of ordinal categories, K, is taken to be the number of distinct values of `round (Y)'.  If K equals 2, Y is binary and the model is ordinary logistic regression.  The matrix X is assumed to have full column rank.
+
+     Given Y only, `theta = logistic_regression (y)' fits the model with baseline logit odds only.
+
+     The full form is
+
+          [theta, beta, dev, dl, d2l, gamma]
+             = logistic_regression (y, x, print, theta, beta)
+
+     in which all output arguments and all input arguments except Y are optional.
+
+     Setting PRINT to 1 requests summary information about the fitted model to be displayed.  Setting PRINT to 2 requests information about convergence at each iteration.  Other values request no information to be displayed.  The input arguments THETA and BETA give initial estimates for THETA and BETA.
+
+     The returned value DEV holds minus twice the log-likelihood.
+
+     The returned values DL and D2L are the vector of first and the matrix of second derivatives of the log-likelihood with respect to THETA and BETA.
+
+     P holds estimates for the conditional distribution of Y given X.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Perform ordinal logistic regression.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+logistic_regression_likelihood
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 193
+ -- Function File: [G, G1, P, DEV] = logistic_regression_likelihood (Y, X, BETA, Z, Z1)
+     Calculates likelihood for the ordinal logistic regression model.  Called by logistic_regression.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Calculates likelihood for the ordinal logistic regression model.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+spearman
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 598
+ -- Function File:  spearman (X, Y)
+     Compute Spearman's rank correlation coefficient RHO for each of the variables specified by the input arguments.
+
+     For matrices, each row is an observation and each column a variable; vectors are always observations and may be row or column vectors.
+
+     `spearman (X)' is equivalent to `spearman (X, X)'.
+
+     For two data vectors X and Y, Spearman's RHO is the correlation of the ranks of X and Y.
+
+     If X and Y are drawn from independent distributions, RHO has zero mean and variance `1 / (n - 1)', and is asymptotically normally distributed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Compute Spearman's rank correlation coefficient RHO for each of the variables specified by the input arguments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+ols
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 754
+ -- Function File: [BETA, SIGMA, R] = ols (Y, X)
+     Ordinary least squares estimation for the multivariate model y = x b + e with mean (e) = 0 and cov (vec (e)) = kron (s, I).   where y is a t by p matrix, x is a t by k matrix, b is a k by p matrix, and e is a t by p matrix.
+
+     Each row of Y and X is an observation and each column a variable.
+
+     The return values BETA, SIGMA, and R are defined as follows.
+
+    BETA
+          The OLS estimator for B, `BETA = pinv (X) * Y', where `pinv (X)' denotes the pseudoinverse of X.
+
+    SIGMA
+          The OLS estimator for the matrix S,
+
+               SIGMA = (Y-X*BETA)'
+                 * (Y-X*BETA)
+                 / (T-rank(X))
+
+    R
+          The matrix of OLS residuals, `R = Y - X * BETA'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+Ordinary least squares estimation for the multivariate model y = x b + e with mean (e) = 0 and cov (vec (e)) = kron (s, I).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+mode
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 497
+ -- Function File: [M, F, C] = mode (X, DIM)
+     Count the most frequently appearing value.  `mode' counts the frequency along the first non-singleton dimension and if two or more values have the same frequency returns the smallest of the two in M.  The dimension along which to count can be specified by the DIM parameter.
+
+     The variable F counts the frequency of each of the most frequently occurring elements.  The cell array C contains all of the elements with the maximum frequency .
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Count the most frequently appearing value.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+probit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 139
+ -- Function File:  probit (P)
+     For each component of P, return the probit (the quantile of the standard normal distribution) of P.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+For each component of P, return the probit (the quantile of the standard normal distribution) of P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ppplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 827
+ -- Function File: [P, Y] = ppplot (X, DIST, PARAMS)
+     Perform a PP-plot (probability plot).
+
+     If F is the CDF of the distribution DIST with parameters PARAMS and X a sample vector of length N, the PP-plot graphs ordinate Y(I) = F (I-th largest element of X) versus abscissa P(I) = (I - 0.5)/N.  If the sample comes from F, the pairs will approximately follow a straight line.
+
+     The default for DIST is the standard normal distribution.  The optional argument PARAMS contains a list of parameters of DIST.  For example, for a probability plot of the uniform distribution on [2,4] and X, use
+
+          ppplot (x, "uniform", 2, 4)
+
+     DIST can be any string for which a function DIST_CDF that calculates the CDF of distribution DIST exists.
+
+     If no output arguments are given, the data are plotted directly.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Perform a PP-plot (probability plot).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+qqplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 903
+ -- Function File: [Q, S] = qqplot (X, DIST, PARAMS)
+     Perform a QQ-plot (quantile plot).
+
+     If F is the CDF of the distribution DIST with parameters PARAMS and G its inverse, and X a sample vector of length N, the QQ-plot graphs ordinate S(I) = I-th largest element of x versus abscissa Q(If) = G((I - 0.5)/N).
+
+     If the sample comes from F except for a transformation of location and scale, the pairs will approximately follow a straight line.
+
+     The default for DIST is the standard normal distribution.  The optional argument PARAMS contains a list of parameters of DIST.  For example, for a quantile plot of the uniform distribution on [2,4] and X, use
+
+          qqplot (x, "uniform", 2, 4)
+
+     DIST can be any string for which a function DIST_INV that calculates the inverse CDF of distribution DIST exists.
+
+     If no output arguments are given, the data are plotted directly.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Perform a QQ-plot (quantile plot).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+median
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 489
+ -- Function File:  median (X, DIM)
+     If X is a vector, compute the median value of the elements of X.  If the elements of X are sorted, the median is defined as
+
+                      x(ceil(N/2)),             N odd
+          median(x) =
+                      (x(N/2) + x((N/2)+1))/2,  N even
+     If X is a matrix, compute the median value for each column and return them in a row vector.  If the optional DIM argument is given, operate along this dimension.  See also: std, mean.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+If X is a vector, compute the median value of the elements of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cov
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 302
+ -- Function File:  cov (X, Y)
+     Compute covariance.
+
+     If each row of X and Y is an observation and each column is a variable, the (I, J)-th entry of `cov (X, Y)' is the covariance between the I-th variable in X and the J-th variable in Y.  If called with one argument, compute `cov (X, X)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 19
+Compute covariance.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+table
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 254
+ -- Function File: [T, L_X] = table (X)
+ -- Function File: [T, L_X, L_Y] = table (X, Y)
+     Create a contingency table T from data vectors.  The L vectors are the corresponding levels.
+
+     Currently, only 1- and 2-dimensional tables are supported.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Create a contingency table T from data vectors.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+histc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1039
+ -- Function File: N = histc (Y, EDGES)
+ -- Function File: N = histc (Y, EDGES, DIM)
+ -- Function File: [N, IDX] = histc (...)
+     Produce histogram counts.
+
+     When Y is a vector, the function counts the number of elements of Y that fall in the histogram bins defined by EDGES.  This must be a vector of monotonically non-decreasing values that define the edges of the histogram bins.  So, `N (k)' contains the number of elements in Y for which `EDGES (k) <= Y < EDGES (k+1)'.  The final element of N contains the number of elements of Y that was equal to the last element of EDGES.
+
+     When Y is a N-dimensional array, the same operation as above is repeated along dimension DIM.  If this argument is given, the operation is performed along the first non-singleton dimension.
+
+     If a second output argument is requested an index matrix is also returned.  The IDX matrix has same size as Y.  Each element of IDX contains the index of the histogram bin in which the corresponding element of Y was counted.
+
+     See also: hist.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+Produce histogram counts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+std
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 780
+ -- Function File:  std (X)
+ -- Function File:  std (X, OPT)
+ -- Function File:  std (X, OPT, DIM)
+     If X is a vector, compute the standard deviation of the elements of X.
+
+          std (x) = sqrt (sumsq (x - mean (x)) / (n - 1))
+     If X is a matrix, compute the standard deviation for each column and return them in a row vector.
+
+     The argument OPT determines the type of normalization to use.  Valid values are
+
+    0:
+          normalizes with N-1, provides the square root of best unbiased estimator of   the variance [default]
+
+    1:
+          normalizes with N, this provides the square root of the second moment around   the mean
+
+     The third argument DIM determines the dimension along which the standard deviation is calculated.  See also: mean, median.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+If X is a vector, compute the standard deviation of the elements of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+range
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 319
+ -- Function File:  range (X)
+ -- Function File:  range (X, DIM)
+     If X is a vector, return the range, i.e., the difference between the maximum and the minimum, of the input data.
+
+     If X is a matrix, do the above for each column of X.
+
+     If the optional argument DIM is supplied, work along dimension DIM.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+If X is a vector, return the range, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+skewness
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 340
+ -- Function File:  skewness (X, DIM)
+     If X is a vector of length n, return the skewness
+
+          skewness (x) = N^(-1) std(x)^(-3) sum ((x - mean(x)).^3)
+
+     of X.  If X is a matrix, return the skewness along the first non-singleton dimension of the matrix.  If the optional DIM argument is given, operate along this dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+If X is a vector of length n, return the skewness 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+studentize
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 274
+ -- Function File:  studentize (X, DIM)
+     If X is a vector, subtract its mean and divide by its standard deviation.
+
+     If X is a matrix, do the above along the first non-singleton dimension.  If the optional argument DIM is given then operate along this dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+If X is a vector, subtract its mean and divide by its standard deviation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+var
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 553
+ -- Function File:  var (X)
+     For vector arguments, return the (real) variance of the values.  For matrix arguments, return a row vector containing the variance for each column.
+
+     The argument OPT determines the type of normalization to use.  Valid values are
+
+    0:
+          Normalizes with N-1, provides the best unbiased estimator of the variance [default].
+
+    1:
+          Normalizes with N, this provides the second moment around the mean.
+
+     The third argument DIM determines the dimension along which the variance is calculated.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+For vector arguments, return the (real) variance of the values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+values
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 192
+ -- Function File:  values (X)
+     Return the different values in a column vector, arranged in ascending order.
+
+     As an example, `values([1, 2, 3, 1])' returns the vector `[1, 2, 3]'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Return the different values in a column vector, arranged in ascending order.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ranks
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 192
+ -- Function File:  ranks (X, DIM)
+     Return the ranks of X along the first non-singleton dimension adjust for ties.  If the optional argument DIM is given, operate along this dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+Return the ranks of X along the first non-singleton dimension adjust for ties.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+prctile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 721
+ -- Function File: Y = prctile (X, P)
+ -- Function File: Q = prctile (X, P, DIM)
+     For a sample X, compute the quantiles, Y, corresponding to the cumulative probability values, P, in percent.  All non-numeric values (NaNs) of X are ignored.
+
+     If X is a matrix, compute the percentiles for each column and return them in a matrix, such that the i-th row of Y contains the P(i)th percentiles of each column of X.
+
+     The optional argument DIM determines the dimension along which the percentiles are calculated.  If DIM is omitted, and X is a vector or matrix, it defaults to 1 (column wise quantiles).  In the instance that X is a N-d array, DIM defaults to the first dimension whose size greater than unity.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+For a sample X, compute the quantiles, Y, corresponding to the cumulative probability values, P, in percent.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+kendall
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 859
+ -- Function File:  kendall (X, Y)
+     Compute Kendall's TAU for each of the variables specified by the input arguments.
+
+     For matrices, each row is an observation and each column a variable; vectors are always observations and may be row or column vectors.
+
+     `kendall (X)' is equivalent to `kendall (X, X)'.
+
+     For two data vectors X, Y of common length N, Kendall's TAU is the correlation of the signs of all rank differences of X and Y;  i.e., if both X and Y have distinct entries, then
+
+                   1
+          tau = -------   SUM sign (q(i) - q(j)) * sign (r(i) - r(j))
+                n (n-1)   i,j
+
+     in which the Q(I) and R(I)  are the ranks of X and Y, respectively.
+
+     If X and Y are drawn from independent distributions, Kendall's TAU is asymptotically normal with mean 0 and variance `(2 * (2N+5)) / (9 * N * (N-1))'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+Compute Kendall's TAU for each of the variables specified by the input arguments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+center
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 250
+ -- Function File:  center (X)
+ -- Function File:  center (X, DIM)
+     If X is a vector, subtract its mean.  If X is a matrix, do the above for each column.  If the optional argument DIM is given, perform the above operation along this dimension
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+If X is a vector, subtract its mean.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+iqr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 319
+ -- Function File:  iqr (X, DIM)
+     If X is a vector, return the interquartile range, i.e., the difference between the upper and lower quartile, of the input data.
+
+     If X is a matrix, do the above for first non-singleton dimension of X.  If the option DIM argument is given, then operate along this dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+If X is a vector, return the interquartile range, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+statistics
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 312
+ -- Function File:  statistics (X)
+     If X is a matrix, return a matrix with the minimum, first quartile, median, third quartile, maximum, mean, standard deviation, skewness and kurtosis of the columns of X as its columns.
+
+     If X is a vector, calculate the statistics along the non-singleton dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 184
+If X is a matrix, return a matrix with the minimum, first quartile, median, third quartile, maximum, mean, standard deviation, skewness and kurtosis of the columns of X as its columns.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+meansq
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 315
+ -- Function File:  meansq (X)
+ -- Function File:  meansq (X, DIM)
+     For vector arguments, return the mean square of the values.  For matrix arguments, return a row vector containing the mean square of each column.  With the optional DIM argument, returns the mean squared of the values along this dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+For vector arguments, return the mean square of the values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+mahalanobis
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+ -- Function File:  mahalanobis (X, Y)
+     Return the Mahalanobis' D-square distance between the multivariate samples X and Y, which must have the same number of components (columns), but may have a different number of observations (rows).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 196
+Return the Mahalanobis' D-square distance between the multivariate samples X and Y, which must have the same number of components (columns), but may have a different number of observations (rows).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cloglog
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+ -- Function File:  cloglog (X)
+     Return the complementary log-log function of X, defined as
+
+          cloglog(x) = - log (- log (X))
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Return the complementary log-log function of X, defined as 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+quantile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2540
+ -- Function File: Q = quantile (X, P)
+ -- Function File: Q = quantile (X, P, DIM)
+ -- Function File: Q = quantile (X, P, DIM, METHOD)
+     For a sample, X, calculate the quantiles, Q, corresponding to the cumulative probability values in P.  All non-numeric values (NaNs) of X are ignored.
+
+     If X is a matrix, compute the quantiles for each column and return them in a matrix, such that the i-th row of Q contains the P(i)th quantiles of each column of X.
+
+     The optional argument DIM determines the dimension along which the percentiles are calculated.  If DIM is omitted, and X is a vector or matrix, it defaults to 1 (column wise quantiles).  In the instance that X is a N-d array, DIM defaults to the first dimension whose size greater than unity.
+
+     The methods available to calculate sample quantiles are the nine methods used by R (http://www.r-project.org/).  The default value is METHOD = 5.
+
+     Discontinuous sample quantile methods 1, 2, and 3
+
+       1. Method 1: Inverse of empirical distribution function.
+
+       2. Method 2: Similar to method 1 but with averaging at discontinuities.
+
+       3. Method 3: SAS definition: nearest even order statistic.
+
+     Continuous sample quantile methods 4 through 9, where p(k) is the linear interpolation function respecting each methods' representative cdf.
+
+       4. Method 4: p(k) = k / n. That is, linear interpolation of the empirical cdf.
+
+       5. Method 5: p(k) = (k - 0.5) / n. That is a piecewise linear function where the knots are the values midway through the steps of the empirical cdf.
+
+       6. Method 6: p(k) = k / (n + 1).
+
+       7. Method 7: p(k) = (k - 1) / (n - 1).
+
+       8. Method 8: p(k) = (k - 1/3) / (n + 1/3).  The resulting quantile estimates are approximately median-unbiased regardless of the distribution of X.
+
+       9. Method 9: p(k) = (k - 3/8) / (n + 1/4).  The resulting quantile estimates are approximately unbiased for the expected order statistics if X is normally distributed.
+
+     Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R (versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS use method 6.  MATLAB uses method 5.
+
+     References:
+
+        * Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language.  Wadsworth & Brooks/Cole.
+
+        * Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in statistical packages, American Statistician, 50, 361-365.
+
+        * R: A Language and Environment for Statistical Computing; `http://cran.r-project.org/doc/manuals/fullrefman.pdf'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+For a sample, X, calculate the quantiles, Q, corresponding to the cumulative probability values in P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+moment
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 530
+ -- Function File:  moment (X, P, OPT, DIM)
+     If X is a vector, compute the P-th moment of X.
+
+     If X is a matrix, return the row vector containing the P-th moment of each column.
+
+     With the optional string opt, the kind of moment to be computed can be specified.  If opt contains `"c"' or `"a"', central and/or absolute moments are returned.  For example,
+
+          moment (x, 3, "ac")
+
+     computes the third central absolute moment of X.
+
+     If the optional argument DIM is supplied, work along dimension DIM.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+If X is a vector, compute the P-th moment of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+corrcoef
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 376
+ -- Function File:  corrcoef (X, Y)
+     Compute correlation.
+
+     If each row of X and Y is an observation and each column is a variable, the (I, J)-th entry of `corrcoef (X, Y)' is the correlation between the I-th variable in X and the J-th variable in Y.
+
+          corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+
+     If called with one argument, compute `corrcoef (X, X)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+Compute correlation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+logit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+ -- Function File:  logit (P)
+     For each component of P, return the logit of P defined as
+          logit(P) = log (P / (1-P))
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+For each component of P, return the logit of P defined as  logit(P) = log (P / (1-P)) 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 484
+ -- Function File:  cor (X, Y)
+     Compute correlation.
+
+     The (I, J)-th entry of `cor (X, Y)' is the correlation between the I-th variable in X and the J-th variable in Y.
+
+          corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+
+     For matrices, each row is an observation and each column a variable; vectors are always observations and may be row or column vectors.
+
+     `cor (X)' is equivalent to `cor (X, X)'.
+
+     Note that the `corrcoef' function does the same as `cor'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+Compute correlation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+kurtosis
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 354
+ -- Function File:  kurtosis (X, DIM)
+     If X is a vector of length N, return the kurtosis
+
+          kurtosis (x) = N^(-1) std(x)^(-4) sum ((x - mean(x)).^4) - 3
+
+     of X.  If X is a matrix, return the kurtosis over the first non-singleton dimension.  The optional argument DIM can be given to force the kurtosis to be given over that dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+If X is a vector of length N, return the kurtosis 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cut
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 519
+ -- Function File:  cut (X, BREAKS)
+     Create categorical data out of numerical or continuous data by cutting into intervals.
+
+     If BREAKS is a scalar, the data is cut into that many equal-width intervals.  If BREAKS is a vector of break points, the category has `length (BREAKS) - 1' groups.
+
+     The returned value is a vector of the same size as X telling which group each point in X belongs to.  Groups are labelled from 1 to the number of groups; points outside the range of BREAKS are labelled by `NaN'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Create categorical data out of numerical or continuous data by cutting into intervals.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+gls
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 582
+ -- Function File: [BETA, V, R] = gls (Y, X, O)
+     Generalized least squares estimation for the multivariate model y = x b + e with mean (e) = 0 and cov (vec (e)) = (s^2) o,  where y is a t by p matrix, x is a t by k matrix, b is a k by p matrix, e is a t by p matrix, and o is a t p by t p matrix.
+
+     Each row of Y and X is an observation and each column a variable.  The return values BETA, V, and R are defined as follows.
+
+    BETA
+          The GLS estimator for b.
+
+    V
+          The GLS estimator for s^2.
+
+    R
+          The matrix of GLS residuals, r = y - x beta.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 246
+Generalized least squares estimation for the multivariate model y = x b + e with mean (e) = 0 and cov (vec (e)) = (s^2) o, where y is a t by p matrix, x is a t by k matrix, b is a k by p matrix, e is a t by p matrix, and o is a t p by t p matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+run_count
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 237
+ -- Function File:  run_count (X, N)
+     Count the upward runs along the first non-singleton dimension of X of length 1, 2, ..., N-1 and greater than or equal to N.  If the optional argument DIM is given operate along this dimension
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Count the upward runs along the first non-singleton dimension of X of length 1, 2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+mean
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 688
+ -- Function File:  mean (X, DIM, OPT)
+     If X is a vector, compute the mean of the elements of X
+
+          mean (x) = SUM_i x(i) / N
+     If X is a matrix, compute the mean for each column and return them in a row vector.
+
+     With the optional argument OPT, the kind of mean computed can be selected.  The following options are recognized:
+
+    `"a"'
+          Compute the (ordinary) arithmetic mean.  This is the default.
+
+    `"g"'
+          Compute the geometric mean.
+
+    `"h"'
+          Compute the harmonic mean.
+
+     If the optional argument DIM is supplied, work along dimension DIM.
+
+     Both DIM and OPT are optional.  If both are supplied, either may appear first.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+If X is a vector, compute the mean of the elements of X 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+griddatan
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 360
+ -- Function File: YI = griddatan (X, Y, XI, METHOD, OPTIONS)
+     Generate a regular mesh from irregular data using interpolation.  The function is defined by `Y = f (X)'.  The interpolation points are all XI.
+
+     The interpolation method can be `"nearest"' or `"linear"'.  If method is omitted it defaults to `"linear"'.  See also: griddata, delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Generate a regular mesh from irregular data using interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+delaunay3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 481
+ -- Function File: T = delaunay3 (X, Y, Z)
+ -- Function File: T = delaunay3 (X, Y, Z, OPT)
+     A matrix of size [n, 4] is returned.  Each row contains a set of tetrahedron which are described by the indices to the data point vectors (x,y,z).
+
+     A fourth optional argument, which must be a string or cell array of strings, contains extra options passed to the underlying qhull command.  See the documentation for the Qhull library for details.  See also: delaunay,delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+A matrix of size [n, 4] is returned.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+griddata3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 377
+ -- Function File: VI = griddata3 (X, Y, Z, V XI, YI, ZI, METHOD, OPTIONS)
+     Generate a regular mesh from irregular data using interpolation.  The function is defined by `Y = f (X,Y,Z)'.  The interpolation points are all XI.
+
+     The interpolation method can be `"nearest"' or `"linear"'.  If method is omitted it defaults to `"linear"'.  See also: griddata, delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Generate a regular mesh from irregular data using interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+trisurf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 360
+ -- Function File:  trisurf (TRI, X, Y, Z)
+ -- Function File: H = trisurf (...)
+     Plot a triangular surface in 3D.  The variable TRI is the triangular meshing of the points `(X, Y)' which is returned from `delaunay'.  The variable Z is value at the point `(X, Y)'.  The output argument H is the graphic handle to the plot.  See also: triplot, delaunay3.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Plot a triangular surface in 3D.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rectint
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 436
+ -- Function File: AREA = rectint (A, B)
+     Compute the area of intersection of rectangles in A and rectangles in B.  Rectangles are defined as [x y width height] where x and y are the minimum values of the two orthogonal dimensions.
+
+     If A or B are matrices, then the output, AREA, is a matrix where the i-th row corresponds to the i-th row of a and the j-th column corresponds to the j-th row of b.
+
+     See also: polyarea.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Compute the area of intersection of rectangles in A and rectangles in B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+voronoi
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 878
+ -- Function File:  voronoi (X, Y)
+ -- Function File:  voronoi (X, Y, "plotstyle")
+ -- Function File:  voronoi (X, Y, "plotstyle", OPTIONS)
+ -- Function File: [VX, VY] = voronoi (...)
+     plots voronoi diagram of points `(X, Y)'.  The voronoi facets with points at infinity are not drawn.  [VX, VY] = voronoi(...) returns the vertices instead of plotting the diagram. plot (VX, VY) shows the voronoi diagram.
+
+     A fourth optional argument, which must be a string, contains extra options passed to the underlying qhull command.  See the documentation for the Qhull library for details.
+
+            x = rand (10, 1);
+            y = rand (size (x));
+            h = convhull (x, y);
+            [vx, vy] = voronoi (x, y);
+            plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g")
+            legend ("", "points", "hull");
+
+     See also: voronoin, delaunay, convhull.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+plots voronoi diagram of points `(X, Y)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dsearch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 293
+ -- Function File: IDX = dsearch (X, Y, TRI, XI, YI)
+ -- Function File: IDX = dsearch (X, Y, TRI, XI, YI, S)
+     Returns the index IDX or the closest point in `X, Y' to the elements `[XI(:), YI(:)]'.  The variable S is accepted but ignored for compatibility.  See also: dsearchn, tsearch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Returns the index IDX or the closest point in `X, Y' to the elements `[XI(:), YI(:)]'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+delaunayn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1199
+ -- Function File: T = delaunayn (P)
+ -- Function File: T = delaunayn (P, OPT)
+     Form the Delaunay triangulation for a set of points.  The Delaunay triangulation is a tessellation of the convex hull of the points such that no n-sphere defined by the n-triangles contains any other points from the set.  The input matrix P of size `[n, dim]' contains N points in a space of dimension dim.  The return matrix T has the size `[m, dim+1]'.  It contains for each row a set of indices to the points, which describes a simplex of dimension dim.  For example, a 2d simplex is a triangle and 3d simplex is a tetrahedron.
+
+     Extra options for the underlying Qhull command can be specified by the second argument.  This argument is a cell array of strings.  The default options depend on the dimension of the input:
+
+        * 2D and 3D: OPT = `{"Qt", "Qbb", "Qc"}'
+
+        * 4D and higher: OPT = `{"Qt", "Qbb", "Qc", "Qz"}'
+
+     If OPT is [], then the default arguments are used.  If OPT is `{""}', then none of the default arguments are used by Qhull.  See the Qhull documentation for the available options.
+
+     All options can also be specified as single string, for example `"Qt Qbb Qc Qz"'.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Form the Delaunay triangulation for a set of points.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+tsearchn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 357
+ -- Function File: [IDX, P] = tsearchn (X, T, XI)
+     Searches for the enclosing Delaunay convex hull.  For `T = delaunayn (X)', finds the index in T containing the points XI.  For points outside the convex hull, IDX is NaN.  If requested `tsearchn' also returns the Barycentric coordinates P of the enclosing triangles.  See also: delaunay, delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Searches for the enclosing Delaunay convex hull.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+convhull
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 428
+ -- Function File: H = convhull (X, Y)
+ -- Function File: H = convhull (X, Y, OPT)
+     Returns the index vector to the points of the enclosing convex hull.  The data points are defined by the x and y vectors.
+
+     A third optional argument, which must be a string, contains extra options passed to the underlying qhull command.  See the documentation for the Qhull library for details.
+
+     See also: delaunay, convhulln.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Returns the index vector to the points of the enclosing convex hull.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+voronoin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 555
+ -- Function File: [C, F] = voronoin (PTS)
+ -- Function File: [C, F] = voronoin (PTS, OPTIONS)
+     computes n- dimensional voronoi facets.  The input matrix PTS of size [n, dim] contains n points of dimension dim.  C contains the points of the voronoi facets.  The list F contains for each facet the indices of the voronoi points.
+
+     A second optional argument, which must be a string, contains extra options passed to the underlying qhull command.  See the documentation for the Qhull library for details.  See also: voronoin, delaunay, convhull.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+computes n- dimensional voronoi facets.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+inpolygon
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 293
+ -- Function File: [IN, ON] = inpolygon (X, Y, XV, XY)
+     For a polygon defined by `(XV, YV)' points, determine if the points `(X, Y)' are inside or outside the polygon.  The variables X, Y, must have the same dimension.  The optional output ON gives the points that are on the polygon.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+For a polygon defined by `(XV, YV)' points, determine if the points `(X, Y)' are inside or outside the polygon.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+griddata
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 495
+ -- Function File: ZI = griddata (X, Y, Z, XI, YI, METHOD)
+ -- Function File: [XI, YI, ZI] = griddata (X, Y, Z, XI, YI, METHOD)
+     Generate a regular mesh from irregular data using interpolation.  The function is defined by `Z = f (X, Y)'.  The interpolation points are all `(XI, YI)'.  If XI, YI are vectors then they are made into a 2D mesh.
+
+     The interpolation method can be `"nearest"', `"cubic"' or `"linear"'.  If method is omitted it defaults to `"linear"'.  See also: delaunay.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Generate a regular mesh from irregular data using interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+trimesh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 357
+ -- Function File:  trimesh (TRI, X, Y, Z)
+ -- Function File: H = trimesh (...)
+     Plot a triangular mesh in 3D.  The variable TRI is the triangular meshing of the points `(X, Y)' which is returned from `delaunay'.  The variable Z is value at the point `(X, Y)'.  The output argument H is the graphic handle to the plot.  See also: triplot, delaunay3.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+Plot a triangular mesh in 3D.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+dsearchn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 465
+ -- Function File: IDX = dsearchn (X, TRI, XI)
+ -- Function File: IDX = dsearchn (X, TRI, XI, OUTVAL)
+ -- Function File: IDX = dsearchn (X, XI)
+ -- Function File: [IDX, D] = dsearchn (...)
+     Returns the index IDX or the closest point in X to the elements XI.  If OUTVAL is supplied, then the values of XI that are not contained within one of the simplicies TRI are set to OUTVAL.  Generally, TRI is returned from `delaunayn (X)'.  See also: dsearch, tsearch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Returns the index IDX or the closest point in X to the elements XI.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+triplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 433
+ -- Function File:  triplot (TRI, X, Y)
+ -- Function File:  triplot (TRI, X, Y, LINESPEC)
+ -- Function File: H = triplot (...)
+     Plot a triangular mesh in 2D.  The variable TRI is the triangular meshing of the points `(X, Y)' which is returned from `delaunay'.  If given, the LINESPEC determines the properties to use for the lines.  The output argument H is the graphic handle to the plot.  See also: plot, trimesh, delaunay.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+Plot a triangular mesh in 2D.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+delaunay
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 863
+ -- Function File: TRI = delaunay (X, Y)
+ -- Function File: TRI = delaunay (X, Y, OPT)
+     The return matrix of size [n, 3] contains a set triangles which are described by the indices to the data point x and y vector.  The triangulation satisfies the Delaunay circum-circle criterion.  No other data point is in the circum-circle of the defining triangle.
+
+     A third optional argument, which must be a string, contains extra options passed to the underlying qhull command.  See the documentation for the Qhull library for details.
+
+          x = rand (1, 10);
+          y = rand (size (x));
+          T = delaunay (x, y);
+          X = [x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1))];
+          Y = [y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1))];
+          axis ([0,1,0,1]);
+          plot (X, Y, "b", x, y, "r*");
+     See also: voronoi, delaunay3, delaunayn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+The return matrix of size [n, 3] contains a set triangles which are described by the indices to the data point x and y vector.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+isonormals
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3208
+ -- Function File: [N] = isonormals (VAL, V)
+ -- Function File: [N] = isonormals (VAL, P)
+ -- Function File: [N] = isonormals (X, Y, Z, VAL, V)
+ -- Function File: [N] = isonormals (X, Y, Z, VAL, P)
+ -- Function File: [N] = isonormals (..., "negate")
+ -- Function File: isonormals (..., P)
+     If called with one output argument and the first input argument VAL is a three-dimensional array that contains the data for an isosurface geometry and the second input argument V keeps the vertices of an isosurface then return the normals N in form of a matrix with the same size than V at computed points `[x, y, z] = meshgrid (1:l, 1:m, 1:n)'.  The output argument N can be taken to manually set VERTEXNORMALS of a patch.
+
+     If called with further input arguments X, Y and Z which are three-dimensional arrays with the same size than VAL then the volume data is taken at those given points.  Instead of the vertices data V a patch handle P can be passed to this function.
+
+     If given the string input argument "negate" as last input argument then compute the reverse vector normals of an isosurface geometry.
+
+     If no output argument is given then directly redraw the patch that is given by the patch handle P.
+
+     For example,
+          function [] = isofinish (p)
+            set (gca, "DataAspectRatioMode","manual","DataAspectRatio",[1 1 1]);
+            set (p, "VertexNormals", -get(p,"VertexNormals")); ## Revert normals
+            set (p, "FaceColor", "interp");
+            ## set (p, "FaceLighting", "phong");
+            ## light ("Position", [1 1 5]); ## Available with JHandles
+          endfunction
+
+          N = 15;    ## Increase number of vertices in each direction
+          iso = .4;  ## Change isovalue to .1 to display a sphere
+          lin = linspace (0, 2, N);
+          [x, y, z] = meshgrid (lin, lin, lin);
+          c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
+          figure (); ## Open another figure window
+
+          subplot (2, 2, 1); view (-38, 20);
+          [f, v, cdat] = isosurface (x, y, z, c, iso, y);
+          p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+          	   "FaceColor", "interp", "EdgeColor", "none");
+          isofinish (p); ## Call user function isofinish
+
+          subplot (2, 2, 2); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+          	   "FaceColor", "interp", "EdgeColor", "none");
+          isonormals (x, y, z, c, p); ## Directly modify patch
+          isofinish (p);
+
+          subplot (2, 2, 3); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+          	   "FaceColor", "interp", "EdgeColor", "none");
+          n = isonormals (x, y, z, c, v); ## Compute normals of isosurface
+          set (p, "VertexNormals", n);    ## Manually set vertex normals
+          isofinish (p);
+
+          subplot (2, 2, 4); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+          	   "FaceColor", "interp", "EdgeColor", "none");
+          isonormals (x, y, z, c, v, "negate"); ## Use reverse directly
+          isofinish (p);
+
+     See also: isosurface, isocolors, isocaps, marching_cube.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 345
+If called with one output argument and the first input argument VAL is a three-dimensional array that contains the data for an isosurface geometry and the second input argument V keeps the vertices of an isosurface then return the normals N in form of a matrix with the same size than V at computed points `[x, y, z] = meshgrid (1:l, 1:m, 1:n)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+grid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 569
+ -- Function File:  grid (ARG)
+ -- Function File:  grid ("minor", ARG2)
+ -- Function File:  grid (HAX, ...)
+     Force the display of a grid on the plot.  The argument may be either `"on"', or `"off"'.  If it is omitted, the current grid state is toggled.
+
+     If ARG is `"minor"' then the minor grid is toggled.  When using a minor grid a second argument ARG2 is allowed, which can be either `"on"' or `"off"' to explicitly set the state of the minor grid.
+
+     If the first argument is an axis handle, HAX, operate on the specified axis object.  See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Force the display of a grid on the plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+semilogx
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 239
+ -- Function File:  semilogx (ARGS)
+     Produce a two-dimensional plot using a log scale for the X axis.  See the description of `plot' for a description of the arguments that `semilogx' will accept.  See also: plot, semilogy, loglog.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Produce a two-dimensional plot using a log scale for the X axis.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+surface
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 765
+ -- Function File:  surface (X, Y, Z, C)
+ -- Function File:  surface (X, Y, Z)
+ -- Function File:  surface (Z, C)
+ -- Function File:  surface (Z)
+ -- Function File:  surface (..., PROP, VAL)
+ -- Function File:  surface (H, ...)
+ -- Function File: H = surface (...)
+     Plot a surface graphic object given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the surface.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.  If X and Y are missing, they are constructed from size of the matrix Z.
+
+     Any additional properties passed are assigned to the surface.  See also: surf, mesh, patch, line.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 141
+Plot a surface graphic object given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the surface.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+title
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+ -- Function File:  title (TITLE)
+ -- Function File:  title (TITLE, P1, V1, ...)
+     Create a title object and return a handle to it.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Create a title object and return a handle to it.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+ellipsoid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 380
+ -- Function File: [X, Y, Z] = ellipsoid (XC,YC, ZC, XR, YR, ZR, N)
+ -- Function File:  ellipsoid (H, ...)
+     Generate three matrices in `meshgrid' format that define an ellipsoid.  Called with no return arguments, `ellipsoid' calls directly `surf (X, Y, Z)'.  If an axes handle is passed as the first argument, the surface is plotted to this set of axes.  See also: sphere.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Generate three matrices in `meshgrid' format that define an ellipsoid.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isfigure
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+ -- Function File:  isfigure (H)
+     Return true if H is a graphics handle that contains a figure object and false otherwise.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+Return true if H is a graphics handle that contains a figure object and false otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+findobj
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1576
+ -- Function File: H = findobj ()
+ -- Function File: H = findobj (PROP_NAME, PROP_VALUE)
+ -- Function File: H = findobj ('-property', PROP_NAME)
+ -- Function File: H = findobj ('-regexp', PROP_NAME, PATTERN)
+ -- Function File: H = findobj ('flat', ...)
+ -- Function File: H = findobj (H, ...)
+ -- Function File: H = findobj (H, '-depth', D, ...)
+     Find object with specified property values.  The simplest form is
+
+          findobj (PROP_NAME, PROP_VALUE)
+
+     which returns all of the handles to the objects with the name PROP_NAME and the name PROP_VALUE.  The search can be limited to a particular object or set of objects and their descendants by passing a handle or set of handles H as the first argument to `findobj'.
+
+     The depth of hierarchy of objects to which to search to can be limited with the '-depth' argument.  To limit the number depth of the hierarchy to search to D generations of children, and example is
+
+          findobj (H, '-depth', D, PROP_NAME, PROP_VALUE)
+
+     Specifying a depth D of 0, limits the search to the set of object passed in H.  A depth D of 0 is equivalent to the '-flat' argument.
+
+     A specified logical operator may be applied to the pairs of PROP_NAME and PROP_VALUE.  The supported logical operators are '-and', '-or', '-xor', '-not'.
+
+     The objects may also be matched by comparing a regular expression to the property values, where property values that match `regexp (PROP_VALUE, PATTERN)' are returned.  Finally, objects may be matched by property name only, using the '-property' option.  See also: get, set.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Find object with specified property values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+loglogerr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 479
+ -- Function File:  loglogerr (ARGS)
+     Produce two-dimensional plots on double logarithm axis with errorbars.  Many different combinations of arguments are possible.  The most used form is
+
+          loglogerr (X, Y, EY, FMT)
+
+     which produces a double logarithm plot of Y versus X with errors in the Y-scale defined by EY and the plot format defined by FMT.  See errorbar for available formats and additional information.  See also: errorbar, semilogxerr, semilogyerr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Produce two-dimensional plots on double logarithm axis with errorbars.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+gcbo
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 514
+ -- Function File: H = gcbo ()
+ -- Function File: [H, FIG] = gcbo ()
+     Return a handle to the object whose callback is currently executing.  If no callback is executing, this function returns the empty matrix.  This handle is obtained from the root object property "CallbackObject".
+
+     Additionally return the handle of the figure containing the object whose callback is currently executing.  If no callback is executing, the second output is also set to the empty matrix.
+
+     See also: gcf, gca, gcbf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Return a handle to the object whose callback is currently executing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+stem
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1419
+ -- Function File: H = stem (X, Y, LINESPEC)
+ -- Function File: H = stem (..., "filled")
+     Plot a stem graph from two vectors of x-y data.  If only one argument is given, it is taken as the y-values and the x coordinates are taken from the indices of the elements.
+
+     If Y is a matrix, then each column of the matrix is plotted as a separate stem graph.  In this case X can either be a vector, the same length as the number of rows in Y, or it can be a matrix of the same size as Y.
+
+     The default color is `"r"' (red).  The default line style is `"-"' and the default marker is `"o"'.  The line style can be altered by the `linespec' argument in the same manner as the `plot' command.  For example
+
+          x = 1:10;
+          y = ones (1, length (x))*2.*x;
+          stem (x, y, "b");
+
+     plots 10 stems with heights from 2 to 20 in blue;
+
+     The return value of `stem' is a vector if "stem series" graphics handles, with one handle per column of the variable Y.  This handle regroups the elements of the stem graph together as the children of the "stem series" handle, allowing them to be altered together.  For example
+
+          x = [0 : 10].';
+          y = [sin(x), cos(x)]
+          h = stem (x, y);
+          set (h(2), "color", "g");
+          set (h(1), "basevalue", -1)
+
+     changes the color of the second "stem series"  and moves the base line of the first.  See also: bar, barh, plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Plot a stem graph from two vectors of x-y data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ezplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1395
+ -- Function File:  ezplot (F)
+ -- Function File:  ezplot (FX, FY)
+ -- Function File:  ezplot (..., DOM)
+ -- Function File:  ezplot (..., N)
+ -- Function File:  ezplot (H, ...)
+ -- Function File: H = ezplot (...)
+     Plots in two-dimensions the curve defined by F.  The function F may be a string, inline function or function handle and can have either one or two variables.  If F has one variable, then the function is plotted over the domain `-2*pi < X < 2*pi' with 500 points.
+
+     If F has two variables then `F(X,Y) = 0' is calculated over the meshed domain `-2*pi < X | Y < 2*pi' with 60 by 60 in the mesh.  For example
+
+          ezplot (@(X, Y) X .^ 2 - Y .^ 2 - 1)
+
+     If two functions are passed as strings, inline functions or function handles, then the parametric function
+
+          X = FX (T)
+          Y = FY (T)
+
+     is plotted over the domain `-2*pi < T < 2*pi' with 500 points.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of X, Y and T.  If it is a four element vector, then the minimum and maximum values of X and T are determined by the first two elements and the minimum and maximum of Y by the second pair of elements.
+
+     N is a scalar defining the number of points to use in plotting the function.
+
+     The optional return value H provides a list of handles to the the line objects plotted.
+
+     See also: plot, ezplot3.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Plots in two-dimensions the curve defined by F.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+ezcontourf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1013
+ -- Function File:  ezcontourf (F)
+ -- Function File:  ezcontourf (..., DOM)
+ -- Function File:  ezcontourf (..., N)
+ -- Function File:  ezcontourf (H, ...)
+ -- Function File: H = ezcontourf (...)
+     Plots the filled contour lines of a function.  F is a string, inline function or function handle with two arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both X and Y.  If DOM is a four element vector, then the minimum and maximum value of X and Y are specify separately.
+
+     N is a scalar defining the number of points to use in each dimension.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezcontourf (f, [-3, 3]);
+
+     See also: ezplot, ezcontour, ezsurfc, ezmeshc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Plots the filled contour lines of a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+ezcontour
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1001
+ -- Function File:  ezcontour (F)
+ -- Function File:  ezcontour (..., DOM)
+ -- Function File:  ezcontour (..., N)
+ -- Function File:  ezcontour (H, ...)
+ -- Function File: H = ezcontour (...)
+     Plots the contour lines of a function.  F is a string, inline function or function handle with two arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both X and Y.  If DOM is a four element vector, then the minimum and maximum value of X and Y are specify separately.
+
+     N is a scalar defining the number of points to use in each dimension.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezcontour (f, [-3, 3]);
+
+     See also: ezplot, ezcontourf, ezsurfc, ezmeshc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Plots the contour lines of a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+orient
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 361
+ -- Function File:  orient (ORIENTATION)
+     Set the default print orientation.  Valid values for ORIENTATION include `"landscape"', `"portrait"', and `"tall"'.
+
+     The `"tall"' option sets the orientation to portait and fills the page with the plot, while leaving a 0.25in border.
+
+     If called with no arguments, return the default print orientation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Set the default print orientation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ginput
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 281
+ -- Function File: [X, Y, BUTTONS] = ginput (N)
+     Return which mouse buttons were pressed and keys were hit on the current figure.  If N is defined, then wait for N mouse clicks before returning.  If N is not defined, then `ginput' will loop until the return key is pressed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+Return which mouse buttons were pressed and keys were hit on the current figure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+gnuplot_binary
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 236
+ -- Loadable Function: VAL = gnuplot_binary ()
+ -- Loadable Function: OLD_VAL = gnuplot_binary (NEW_VAL)
+     Query or set the name of the program invoked by the plot command.  The default value `\"gnuplot\"'.  *Note Installation::.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Query or set the name of the program invoked by the plot command.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+barh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1088
+ -- Function File:  barh (X, Y)
+ -- Function File:  barh (Y)
+ -- Function File:  barh (X, Y, W)
+ -- Function File:  barh (X, Y, W, STYLE)
+ -- Function File: H = barh (..., PROP, VAL)
+ -- Function File:  barh (H, ...)
+     Produce a horizontal bar graph from two vectors of x-y data.
+
+     If only one argument is given, it is taken as a vector of y-values and the x coordinates are taken to be the indices of the elements.
+
+     The default width of 0.8 for the bars can be changed using W.
+
+     If Y is a matrix, then each column of Y is taken to be a separate bar graph plotted on the same graph.  By default the columns are plotted side-by-side.  This behavior can be changed by the STYLE argument, which can take the values `"grouped"' (the default), or `"stacked"'.
+
+     The optional return value H provides a handle to the bar series object.  See `bar' for a description of the use of the bar series.
+
+     The optional input handle H allows an axis handle to be passed.  Properties of the patch graphics object can be changed using PROP, VAL pairs.
+
+     See also: bar, plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Produce a horizontal bar graph from two vectors of x-y data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+ylim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 771
+ -- Function File: XL = ylim ()
+ -- Function File:  ylim (XL)
+ -- Function File: M = ylim ('mode')
+ -- Function File:  ylim (M)
+ -- Function File:  ylim (H, ...)
+     Get or set the limits of the y-axis of the current plot.  Called without arguments `ylim' returns the y-axis limits of the current plot.  If passed a two element vector XL, the limits of the y-axis are set to this value.
+
+     The current mode for calculation of the y-axis can be returned with a call `ylim ('mode')', and can be either 'auto' or 'manual'.  The current plotting mode can be set by passing either 'auto' or 'manual' as the argument.
+
+     If passed an handle as the first argument, then operate on this handle rather than the current axes handle.  See also: xlim, zlim, set, get, gca.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Get or set the limits of the y-axis of the current plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+scatter3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1391
+ -- Function File:  scatter3 (X, Y, Z, S, C)
+ -- Function File:  scatter3 (..., 'filled')
+ -- Function File:  scatter3 (..., STYLE)
+ -- Function File:  scatter3 (..., PROP, VAL)
+ -- Function File:  scatter3 (H, ...)
+ -- Function File: H = scatter3 (...)
+     Plot a scatter plot of the data in 3D.  A marker is plotted at each point defined by the points in the vectors X, Y and Z.  The size of the markers used is determined by S, which can be a scalar or a vector of the same length of X, Y and Z.  If S is not given or is an empty matrix, then the default value of 8 points is used.
+
+     The color of the markers is determined by C, which can be a string defining a fixed color, a 3 element vector giving the red, green and blue components of the color, a vector of the same length as X that gives a scaled index into the current colormap, or a N-by-3 matrix defining the colors of each of the markers individually.
+
+     The marker to use can be changed with the STYLE argument, that is a string defining a marker in the same manner as the `plot' command.  If the argument 'filled' is given then the markers as filled.  All additional arguments are passed to the underlying patch command.
+
+     The optional return value H provides a handle to the patch object
+
+          [x, y, z] = peaks (20);
+          scatter3 (x(:), y(:), z(:), [], z(:));
+
+     See also: plot, patch, scatter.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Plot a scatter plot of the data in 3D.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+patch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 741
+ -- Function File:  patch ()
+ -- Function File:  patch (X, Y, C)
+ -- Function File:  patch (X, Y, Z, C)
+ -- Function File:  patch (FV)
+ -- Function File:  patch ('Faces', F, 'Vertices', V, ...)
+ -- Function File:  patch (..., PROP, VAL)
+ -- Function File:  patch (H, ...)
+ -- Function File: H = patch (...)
+     Create patch object from X and Y with color C and insert in the current axes object.  Return handle to patch object.
+
+     For a uniform colored patch, C can be given as an RGB vector, scalar value referring to the current colormap, or string value (for example, "r" or "red").
+
+     If passed a structure FV contain the fields "vertices", "faces" and optionally "facevertexcdata", create the patch based on these properties.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Create patch object from X and Y with color C and insert in the current axes object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+allchild
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 413
+ -- Function File: H = allchild (HANDLES)
+     Find all children, including hidden children, of a graphics object.
+
+     This function is similar to `get (h, "children")', but also returns includes hidden objects.  If HANDLES is a scalar, H will be a vector.  Otherwise, H will be a cell matrix of the same size as HANDLES and each cell will contain a vector of handles.  See also: get, set, findall, findobj.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Find all children, including hidden children, of a graphics object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ezsurf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1533
+ -- Function File:  ezsurf (F)
+ -- Function File:  ezsurf (FX, FY, FZ)
+ -- Function File:  ezsurf (..., DOM)
+ -- Function File:  ezsurf (..., N)
+ -- Function File:  ezsurf (..., 'circ')
+ -- Function File:  ezsurf (H, ...)
+ -- Function File: H = ezsurf (...)
+     Plots the surface defined by a function.  F is a string, inline function or function handle with two arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both X and Y.  If DOM is a four element vector, then the minimum and maximum value of X and Y are specify separately.
+
+     N is a scalar defining the number of points to use in each dimension.
+
+     If three functions are passed, then plot the parametrically defined function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezsurf (f, [-3, 3]);
+
+     An example of a parametrically defined function is
+
+          fx = @(s,t) cos (s) .* cos(t);
+          fy = @(s,t) sin (s) .* cos(t);
+          fz = @(s,t) sin(t);
+          ezsurf (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+
+     See also: ezplot, ezmesh, ezsurfc, ezmeshc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Plots the surface defined by a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+view
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 183
+ -- Function File:  view (AZIMUTH, ELEVATION)
+ -- Function File:  view (DIMS)
+ -- Function File: [AZIMUTH, ELEVATION] = view ()
+     Set or get the viewpoint for the current axes.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Set or get the viewpoint for the current axes.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+findall
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 446
+ -- Function File: H = findall ()
+ -- Function File: H = findall (PROP_NAME, PROP_VALUE)
+ -- Function File: H = findall (H, ...)
+ -- Function File: H = findall (H, "-depth", D, ...)
+     Find object with specified property values including hidden handles.
+
+     This function performs the same function as `findobj', but it includes hidden objects in its search.  For full documentation, see `findobj'.  See also: get, set, findobj, allchild.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Find object with specified property values including hidden handles.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+gca
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 417
+ -- Function File:  gca ()
+     Return a handle to the current axis object.  If no axis object exists, create one and return its handle.  The handle may then be used to examine or set properties of the axes.  For example,
+
+          ax = gca ();
+          set (ax, "position", [0.5, 0.5, 0.5, 0.5]);
+
+     creates an empty axes object, then changes its location and size in the figure window.  See also: get, set.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Return a handle to the current axis object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+semilogxerr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 477
+ -- Function File:  semilogxerr (ARGS)
+     Produce two-dimensional plots on a semilogarithm axis with errorbars.  Many different combinations of arguments are possible.  The most used form is
+
+          semilogxerr (X, Y, EY, FMT)
+
+     which produces a semi-logarithm plot of Y versus X with errors in the Y-scale defined by EY and the plot format defined by FMT.  See errorbar for available formats and additional information.  See also: errorbar, loglogerr semilogyerr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Produce two-dimensional plots on a semilogarithm axis with errorbars.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+semilogyerr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 477
+ -- Function File:  semilogyerr (ARGS)
+     Produce two-dimensional plots on a semilogarithm axis with errorbars.  Many different combinations of arguments are possible.  The most used form is
+
+          semilogyerr (X, Y, EY, FMT)
+
+     which produces a semi-logarithm plot of Y versus X with errors in the Y-scale defined by EY and the plot format defined by FMT.  See errorbar for available formats and additional information.  See also: errorbar, loglogerr semilogxerr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Produce two-dimensional plots on a semilogarithm axis with errorbars.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sphere
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 468
+ -- Function File: [X, Y, Z] = sphere (N)
+ -- Function File:  sphere (H, ...)
+     Generates three matrices in `meshgrid' format, such that `surf (X, Y, Z)' generates a unit sphere.  The matrices of `N+1'-by-`N+1'.  If N is omitted then a default value of 20 is assumed.
+
+     Called with no return arguments, `sphere' call directly `surf (X, Y, Z)'.  If an axes handle is passed as the first argument, the surface is plotted to this set of axes.  See also: peaks.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Generates three matrices in `meshgrid' format, such that `surf (X, Y, Z)' generates a unit sphere.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+xlabel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 351
+ -- Function File:  xlabel (STRING)
+ -- Function File:  ylabel (STRING)
+ -- Function File:  zlabel (STRING)
+ -- Function File:  xlabel (H, STRING)
+     Specify x, y, and z axis labels for the current figure.  If H is specified then label the axis defined by H.  See also: plot, semilogx, semilogy, loglog, polar, mesh, contour, bar, stairs, title.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Specify x, y, and z axis labels for the current figure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+meshz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 382
+ -- Function File:  meshz (X, Y, Z)
+     Plot a curtain mesh given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.  See also: meshgrid, mesh, contour.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+Plot a curtain mesh given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ezplot3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 885
+ -- Function File:  ezplot3 (FX, FY, FZ)
+ -- Function File:  ezplot3 (..., DOM)
+ -- Function File:  ezplot3 (..., N)
+ -- Function File:  ezplot3 (H, ...)
+ -- Function File: H = ezplot3 (...)
+     Plots in three-dimensions the curve defined parametrically.  FX, FY, and FZ are strings, inline functions or function handles with one arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' with 60 points.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of T.  N is a scalar defining the number of points to use.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          fx = @(t) cos (t);
+          fy = @(t) sin (t);
+          fz = @(t) t;
+          ezplot3 (fx, fy, fz, [0, 10*pi], 100);
+
+     See also: plot3, ezplot, ezsurf, ezmesh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Plots in three-dimensions the curve defined parametrically.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+hidden
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 312
+ -- Function File:  hidden (MODE)
+ -- Function File:  hidden ()
+     Manipulation the mesh hidden line removal.  Called with no argument the hidden line removal is toggled.  The argument MODE can be either 'on' or 'off' and the set of the hidden line removal is set accordingly.  See also: mesh, meshc, surf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Manipulation the mesh hidden line removal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+shg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+ -- Function File:  shg
+     Show the graph window.  Currently, this is the same as executing `drawnow'.  See also: drawnow, figure.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Show the graph window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+specular
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 525
+ -- Function File:  specular (SX, SY, SZ, L, V)
+ -- Function File:  specular (SX, SY, SZ, L, V, SE)
+     Calculate specular reflection strength of a surface defined by the normal vector elements SX, SY, SZ using Phong's approximation.  The light and view vectors can be specified using parameter L and V respectively.  Both can be given as 2-element vectors [azimuth, elevation] in degrees or as 3-element vector [x, y, z].  An optional 6th argument describes the specular exponent (spread) SE.  See also: surfl, diffuse.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+Calculate specular reflection strength of a surface defined by the normal vector elements SX, SY, SZ using Phong's approximation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+gcf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 533
+ -- Function File:  gcf ()
+     Return the current figure handle.  If a figure does not exist, create one and return its handle.  The handle may then be used to examine or set properties of the figure.  For example,
+
+          fplot (@sin, [-10, 10]);
+          fig = gcf ();
+          set (fig, "visible", "off");
+
+     plots a sine wave, finds the handle of the current figure, and then makes that figure invisible.  Setting the visible property of the figure to `"on"' will cause it to be displayed again.  See also: get, set.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Return the current figure handle.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ezmesh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1530
+ -- Function File:  ezmesh (F)
+ -- Function File:  ezmesh (FX, FY, FZ)
+ -- Function File:  ezmesh (..., DOM)
+ -- Function File:  ezmesh (..., N)
+ -- Function File:  ezmesh (..., 'circ')
+ -- Function File:  ezmesh (H, ...)
+ -- Function File: H = ezmesh (...)
+     Plots the mesh defined by a function.  F is a string, inline function or function handle with two arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both X and Y.  If DOM is a four element vector, then the minimum and maximum value of X and Y are specify separately.
+
+     N is a scalar defining the number of points to use in each dimension.
+
+     If three functions are passed, then plot the parametrically defined function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezmesh (f, [-3, 3]);
+
+     An example of a parametrically defined function is
+
+          fx = @(s,t) cos (s) .* cos(t);
+          fy = @(s,t) sin (s) .* cos(t);
+          fz = @(s,t) sin(t);
+          ezmesh (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+
+     See also: ezplot, ezsurf, ezsurfc, ezmeshc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Plots the mesh defined by a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+bar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1384
+ -- Function File:  bar (X, Y)
+ -- Function File:  bar (Y)
+ -- Function File:  bar (X, Y, W)
+ -- Function File:  bar (X, Y, W, STYLE)
+ -- Function File: H = bar (..., PROP, VAL)
+ -- Function File:  bar (H, ...)
+     Produce a bar graph from two vectors of x-y data.
+
+     If only one argument is given, it is taken as a vector of y-values and the x coordinates are taken to be the indices of the elements.
+
+     The default width of 0.8 for the bars can be changed using W.
+
+     If Y is a matrix, then each column of Y is taken to be a separate bar graph plotted on the same graph.  By default the columns are plotted side-by-side.  This behavior can be changed by the STYLE argument, which can take the values `"grouped"' (the default), or `"stacked"'.
+
+     The optional return value H provides a handle to the "bar series" object with one handle per column of the variable Y.  This series allows common elements of the group of bar series objects to be changed in a single bar series and the same properties are changed in the other "bar series".  For example
+
+          h = bar (rand (5, 10));
+          set (h(1), "basevalue", 0.5);
+
+     changes the position on the base of all of the bar series.
+
+     The optional input handle H allows an axis handle to be passed.  Properties of the patch graphics object can be changed using PROP, VAL pairs.
+
+     See also: barh, plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Produce a bar graph from two vectors of x-y data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+waitforbuttonpress
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 208
+ -- Function File: B = waitforbuttonpress ()
+     Wait for button or mouse press.over a figure window.  The value of B returns 0 if a mouse button was pressed or 1 is a key was pressed.  See also: ginput.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Wait for button or mouse press.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+pie
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 717
+ -- Function File:  pie (Y)
+ -- Function File:  pie (Y, EXPLODE)
+ -- Function File:  pie (..., LABELS)
+ -- Function File:  pie (H, ...);
+ -- Function File: H = pie (...);
+     Produce a pie chart.
+
+     Called with a single vector argument, produces a pie chart of the elements in X, with the size of the slice determined by percentage size of the values of X.
+
+     The variable EXPLODE is a vector of the same length as X that if non zero 'explodes' the slice from the pie chart.
+
+     If given LABELS is a cell array of strings of the same length as X, giving the labels of each of the slices of the pie chart.
+
+     The optional return value H provides a handle to the patch object.
+
+     See also: bar, stem.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+Produce a pie chart.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+surfc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 389
+ -- Function File:  surfc (X, Y, Z)
+     Plot a surface and contour given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.  See also: meshgrid, surf, contour.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 135
+Plot a surface and contour given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 685
+ -- Function File:  fplot (FN, LIMITS)
+ -- Function File:  fplot (FN, LIMITS, TOL)
+ -- Function File:  fplot (FN, LIMITS, N)
+ -- Function File:  fplot (..., FMT)
+     Plot a function FN, within the defined limits.  FN an be either a string, a function handle or an inline function.  The limits of the plot are given by LIMITS of the form `[XLO, XHI]' or `[XLO, XHI, YLO, YHI]'.  TOL is the default tolerance to use for the plot, and if TOL is an integer it is assumed that it defines the number points to use in the plot.  The FMT argument is passed to the plot command.
+
+             fplot ("cos", [0, 2*pi])
+             fplot ("[cos(x), sin(x)]", [0, 2*pi])
+     See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Plot a function FN, within the defined limits.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ylabel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+ -- Function File:  ylabel (STRING)
+ -- Function File:  ylabel (H, STRING)
+     See also: xlabel..
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+See also: xlabel.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+sombrero
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 284
+ -- Function File:  sombrero (N)
+     Produce the familiar three-dimensional sombrero plot using N grid lines.  If N is omitted, a value of 41 is assumed.
+
+     The function plotted is
+
+          z = sin (sqrt (x^2 + y^2)) / (sqrt (x^2 + y^2))
+     See also: surf, meshgrid, mesh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 72
+Produce the familiar three-dimensional sombrero plot using N grid lines.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+pcolor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1144
+ -- Function File:  pcolor (X, Y, C)
+ -- Function File:  pcolor (C)
+     Density plot for given matrices X, and Y from `meshgrid' and a matrix C corresponding to the X and Y coordinates of the mesh's vertices.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), C(i,j)).  Thus, columns of C correspond to different X values and rows of C correspond to different Y values.
+
+     The `colormap' is scaled to the extents of C.  Limits may be placed on the color axis by the command `caxis', or by setting the `clim' property of the parent axis.
+
+     The face color of each cell of the mesh is determined by interpolating the values of C for the cell's vertices.  Contrast this with `imagesc' which renders one cell for each element of C.
+
+     `shading' modifies an attribute determining the manner by which the face color of each cell is interpolated from the values of C, and the visibility of the cells' edges.  By default the attribute is "faceted", which renders a single color for each cell's face with the edge visible.
+
+     H is the handle to the surface object.
+
+     See also: caxis, contour, meshgrid, imagesc, shading.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+Density plot for given matrices X, and Y from `meshgrid' and a matrix C corresponding to the X and Y coordinates of the mesh's vertices.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+surfnorm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1094
+ -- Function File:  surfnorm (X, Y, Z)
+ -- Function File:  surfnorm (Z)
+ -- Function File: [NX, NY, NZ] = surfnorm (...)
+ -- Function File:  surfnorm (H, ...)
+     Find the vectors normal to a meshgridded surface.  The meshed gridded surface is defined by X, Y, and Z.  If X and Y are not defined, then it is assumed that they are given by
+
+          [X, Y] = meshgrid (1:size(Z, 1),
+                               1:size(Z, 2));
+
+     If no return arguments are requested, a surface plot with the normal vectors to the surface is plotted.  Otherwise the components of the normal vectors at the mesh gridded points are returned in NX, NY, and NZ.
+
+     The normal vectors are calculated by taking the cross product of the diagonals of each of the quadrilaterals in the meshgrid to find the normal vectors of the centers of these quadrilaterals.  The four nearest normal vectors to the meshgrid points are then averaged to obtain the normal to the surface at the meshgridded points.
+
+     An example of the use of `surfnorm' is
+
+          surfnorm (peaks (25));
+     See also: surf, quiver3.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Find the vectors normal to a meshgridded surface.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+text
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 375
+ -- Function File: H = text (X, Y, LABEL)
+ -- Function File: H = text (X, Y, Z, LABEL)
+ -- Function File: H = text (X, Y, LABEL, P1, V1, ...)
+ -- Function File: H = text (X, Y, Z, LABEL, P1, V1, ...)
+     Create a text object with text LABEL at position X, Y, Z on the current axes.  Property-value pairs following LABEL may be used to specify the appearance of the text.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Create a text object with text LABEL at position X, Y, Z on the current axes.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ezmeshc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1326
+ -- Function File:  ezmeshc (F)
+ -- Function File:  ezmeshc (FX, FY, FZ)
+ -- Function File:  ezmeshc (..., DOM)
+ -- Function File:  ezmeshc (..., N)
+ -- Function File:  ezmeshc (..., 'circ')
+ -- Function File:  ezmeshc (H, ...)
+ -- Function File: H = ezmeshc (...)
+     Plots the mesh and contour lines defined by a function.  F is a string, inline function or function handle with two arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both X and Y.  If DOM is a four element vector, then the minimum and maximum value of X and Y are specify separately.
+
+     N is a scalar defining the number of points to use in each dimension.
+
+     If three functions are passed, then plot the parametrically defined function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezmeshc (f, [-3, 3]);
+
+     See also: ezplot, ezsurfc, ezsurf, ezmesh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Plots the mesh and contour lines defined by a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+plotyy
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1209
+ -- Function File:  plotyy (X1, Y1, X2, Y2)
+ -- Function File:  plotyy (..., FUN)
+ -- Function File:  plotyy (..., FUN1, FUN2)
+ -- Function File:  plotyy (H, ...)
+ -- Function File: [AX, H1, H2] = plotyy (...)
+     Plots two sets of data with independent y-axes.  The arguments X1 and Y1 define the arguments for the first plot and X1 and Y2 for the second.
+
+     By default the arguments are evaluated with `feval (@plot, X, Y)'.  However the type of plot can be modified with the FUN argument, in which case the plots are generated by `feval (FUN, X, Y)'.  FUN can be a function handle, an inline function or a string of a function name.
+
+     The function to use for each of the plots can be independently defined with FUN1 and FUN2.
+
+     If given, H defines the principal axis in which to plot the X1 and Y1 data.  The return value AX is a two element vector with the axis handles of the two plots.  H1 and H2 are handles to the objects generated by the plot commands.
+
+          x = 0:0.1:2*pi;
+          y1 = sin (x);
+          y2 = exp (x - 1);
+          ax = plotyy (x, y1, x - 1, y2, @plot, @semilogy);
+          xlabel ("X");
+          ylabel (ax(1), "Axis 1");
+          ylabel (ax(2), "Axis 2");
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Plots two sets of data with independent y-axes.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+rose
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 892
+ -- Function File:  rose (TH, R)
+ -- Function File:  rose (H, ...)
+ -- Function File: H = rose (...)
+ -- Function File: [R, TH] = rose (...)
+     Plot an angular histogram.  With one vector argument TH, plots the histogram with 20 angular bins.  If TH is a matrix, then each column of TH produces a separate histogram.
+
+     If R is given and is a scalar, then the histogram is produced with R bins.  If R is a vector, then the center of each bin are defined by the values of R.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+     If two output arguments are requested, then rather than plotting the histogram, the polar vectors necessary to plot the histogram are returned.
+
+          [r, t] = rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)]);
+          polar (r, t);
+
+     See also: plot, compass, polar, hist.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Plot an angular histogram.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+comet
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 560
+ -- Function File:  comet (Y)
+ -- Function File:  comet (X, Y)
+ -- Function File:  comet (X, Y, P)
+ -- Function File:  comet (AX, ...)
+     Produce a simple comet style animation along the trajectory provided by the input coordinate vectors (X, Y), where X will default to the indices of Y.
+
+     The speed of the comet may be controlled by P, which represents the time which passes as the animation passes from one point to the next.  The default for P is 0.1 seconds.
+
+     If AX is specified the animation is produced in that axis rather than the `gca'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+Produce a simple comet style animation along the trajectory provided by the input coordinate vectors (X, Y), where X will default to the indices of Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+clabel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1453
+ -- Function File:  clabel (C, H)
+ -- Function File:  clabel (C, H, V)
+ -- Function File:  clabel (C, H, "manual")
+ -- Function File:  clabel (C)
+ -- Function File:  clabel (C, H)
+ -- Function File:  clabel (..., PROP, VAL, ...)
+ -- Function File: H = clabel (...)
+     Adds labels to the contours of a contour plot.  The contour plot is specified by the contour matrix C and optionally the contourgroup object H that are returned by `contour', `contourf' and `contour3'.  The contour labels are rotated and placed in the contour itself.
+
+     By default, all contours are labelled.  However, the contours to label can be specified by the vector V.  If the "manual" argument is given then the contours to label can be selected with the mouse.
+
+     Additional property/value pairs that are valid properties of text objects can be given and are passed to the underlying text objects.  Additionally, the property "LabelSpacing" is available allowing the spacing between labels on a contour (in points) to be specified.  The default is 144 points, or 2 inches.
+
+     The returned value H is the set of text object that represent the contour labels.  The "userdata" property of the text objects contains the numerical value of the contour label.
+
+     An example of the use of `clabel' is
+
+          [c, h] = contour (peaks(), -4 : 6);
+          clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+
+     See also: contour, contourf, contour3, meshc, surfc, text.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Adds labels to the contours of a contour plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+axis
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2333
+ -- Function File:  axis (LIMITS)
+     Set axis limits for plots.
+
+     The argument LIMITS should be a 2, 4, or 6 element vector.  The first and second elements specify the lower and upper limits for the x axis.  The third and fourth specify the limits for the y-axis, and the fifth and sixth specify the limits for the z-axis.
+
+     Without any arguments, `axis' turns autoscaling on.
+
+     With one output argument, `x = axis' returns the current axes
+
+     The vector argument specifying limits is optional, and additional string arguments may be used to specify various axis properties.  For example,
+
+          axis ([1, 2, 3, 4], "square");
+
+     forces a square aspect ratio, and
+
+          axis ("labely", "tic");
+
+     turns tic marks on for all axes and tic mark labels on for the y-axis only.
+
+     The following options control the aspect ratio of the axes.
+
+    `"square"'
+          Force a square aspect ratio.
+
+    `"equal"'
+          Force x distance to equal y-distance.
+
+    `"normal"'
+          Restore the balance.
+
+     The following options control the way axis limits are interpreted.
+
+    `"auto"'
+          Set the specified axes to have nice limits around the data or all if no axes are specified.
+
+    `"manual"'
+          Fix the current axes limits.
+
+    `"tight"'
+          Fix axes to the limits of the data.
+
+     The option `"image"' is equivalent to `"tight"' and `"equal"'.
+
+     The following options affect the appearance of tic marks.
+
+    `"on"'
+          Turn tic marks and labels on for all axes.
+
+    `"off"'
+          Turn tic marks off for all axes.
+
+    `"tic[xyz]"'
+          Turn tic marks on for all axes, or turn them on for the specified axes and off for the remainder.
+
+    `"label[xyz]"'
+          Turn tic labels on for all axes, or turn them on for the specified axes and off for the remainder.
+
+    `"nolabel"'
+          Turn tic labels off for all axes.
+     Note, if there are no tic marks for an axis, there can be no labels.
+
+     The following options affect the direction of increasing values on the axes.
+
+    `"ij"'
+          Reverse y-axis, so lower values are nearer the top.
+
+    `"xy"'
+          Restore y-axis, so higher values are nearer the top.
+
+     If an axes handle is passed as the first argument, then operate on this axes rather than the current axes.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Set axis limits for plots.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cla
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 406
+ -- Function File:  cla ()
+ -- Function File:  cla ("reset")
+ -- Function File:  cla (HAX)
+ -- Function File:  cla (HAX, "reset")
+     Delete the children of the current axes with visible handles.  If HAX is specified and is an axes object handle, operate on it instead of the current axes.  If the optional argument `"reset"' is specified, also delete the children with hidden handles.  See also: clf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Delete the children of the current axes with visible handles.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+surfl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1410
+ -- Function File:  surfl (X, Y, Z)
+ -- Function File:  surfl (Z)
+ -- Function File:  surfl (X, Y, Z, L)
+ -- Function File:  surfl (X, Y, Z, L, P)
+ -- Function File:  surfl (...,"light")
+     Plot a lighted surface given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.
+
+     The light direction can be specified using L.  It can be given as 2-element vector [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz].  The default value is rotated 45° counter-clockwise from the current view.
+
+     The material properties of the surface can specified using a 4-element vector P = [AM D SP EXP] which defaults to P = [0.55 0.6 0.4 10].
+    `"AM" strength of ambient light'
+
+    `"D" strength of diffuse reflection'
+
+    `"SP" strength of specular reflection'
+
+    `"EXP" specular exponent'
+
+     The default lighting mode "cdata", changes the cdata property to give the impression of a lighted surface.  Please note: the alternative "light" mode, which creates a light object to illuminate the surface is not implemented (yet).
+
+     Example:
+
+          colormap(bone);
+          surfl(peaks);
+          shading interp;
+     See also: surf, diffuse, specular, surface.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+Plot a lighted surface given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+subplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 736
+ -- Function File:  subplot (ROWS, COLS, INDEX)
+ -- Function File:  subplot (RCN)
+     Set up a plot grid with COLS by ROWS subwindows and plot in location given by INDEX.
+
+     If only one argument is supplied, then it must be a three digit value specifying the location in digits 1 (rows) and 2 (columns) and the plot index in digit 3.
+
+     The plot index runs row-wise.  First all the columns in a row are filled and then the next row is filled.
+
+     For example, a plot with 2 by 3 grid will have plot indices running as follows:
+
+               +-----+-----+-----+
+               |  1  |  2  |  3  |
+               +-----+-----+-----+
+               |  4  |  5  |  6  |
+               +-----+-----+-----+
+     See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Set up a plot grid with COLS by ROWS subwindows and plot in location given by INDEX.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+contourc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1036
+ -- Function File: [C, LEV] = contourc (X, Y, Z, VN)
+     Compute isolines (contour lines) of the matrix Z.  Parameters X, Y and VN are optional.
+
+     The return value LEV is a vector of the contour levels.  The return value C is a 2 by N matrix containing the contour lines in the following format
+
+          C = [lev1, x1, x2, ..., levn, x1, x2, ...
+               len1, y1, y2, ..., lenn, y1, y2, ...]
+
+     in which contour line N has a level (height) of LEVN and length of LENN.
+
+     If X and Y are omitted they are taken as the row/column index of Z.  VN is either a scalar denoting the number of lines to compute or a vector containing the values of the lines.  If only one value is wanted, set `VN = [val, val]'; If VN is omitted it defaults to 10.
+
+     For example,
+          x = 0:2;
+          y = x;
+          z = x' * y;
+          contourc (x, y, z, 2:3)
+               =>   2.0000   2.0000   1.0000   3.0000   1.5000   2.0000
+               2.0000   1.0000   2.0000   2.0000   2.0000   1.5000
+     See also: contour.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Compute isolines (contour lines) of the matrix Z.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+plot3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1525
+ -- Function File:  plot3 (ARGS)
+     Produce three-dimensional plots.  Many different combinations of arguments are possible.  The simplest form is
+
+          plot3 (X, Y, Z)
+
+     in which the arguments are taken to be the vertices of the points to be plotted in three dimensions.  If all arguments are vectors of the same length, then a single continuous line is drawn.  If all arguments are matrices, then each column of the matrices is treated as a separate line.  No attempt is made to transpose the arguments to make the number of rows match.
+
+     If only two arguments are given, as
+
+          plot3 (X, C)
+
+     the real and imaginary parts of the second argument are used as the Y and Z coordinates, respectively.
+
+     If only one argument is given, as
+
+          plot3 (C)
+
+     the real and imaginary parts of the argument are used as the Y and Z values, and they are plotted versus their index.
+
+     Arguments may also be given in groups of three as
+
+          plot3 (X1, Y1, Z1, X2, Y2, Z2, ...)
+
+     in which each set of three arguments is treated as a separate line or set of lines in three dimensions.
+
+     To plot multiple one- or two-argument groups, separate each group with an empty format string, as
+
+          plot3 (X1, C1, "", C2, "", ...)
+
+     An example of the use of `plot3' is
+
+             z = [0:0.05:5];
+             plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+             plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
+     See also: plot, xlabel, ylabel, zlabel, title, print.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Produce three-dimensional plots.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ezpolar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 773
+ -- Function File:  ezpolar (F)
+ -- Function File:  ezpolar (..., DOM)
+ -- Function File:  ezpolar (..., N)
+ -- Function File:  ezpolar (H, ...)
+ -- Function File: H = ezpolar (...)
+     Plots in polar plot defined by a function.  The function F is either a string, inline function or function handle with one arguments defining the function.  By default the plot is over the domain `0 < X < 2*pi' with 60 points.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both T.  N is a scalar defining the number of points to use.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          ezpolar (@(t) 1 + sin (t));
+
+     See also: polar, ezplot, ezsurf, ezmesh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Plots in polar plot defined by a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ribbon
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 428
+ -- Function File:  ribbon (X, Y, WIDTH)
+ -- Function File:  ribbon (Y)
+ -- Function File: H = ribbon (...)
+     Plot a ribbon plot for the columns of Y vs.  X.  The optional parameter WIDTH specifies the width of a single ribbon (default is 0.75).  If X is omitted, a vector containing the row numbers is assumed (1:rows(Y)).  If requested, return a vector H of the handles to the surface objects.  See also: gca, colorbar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Plot a ribbon plot for the columns of Y vs.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+pareto
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1386
+ -- Function File:  pareto (X)
+ -- Function File:  pareto (X, Y)
+ -- Function File:  pareto (H, ...)
+ -- Function File: H = pareto (...)
+     Draw a Pareto chart, also called ABC chart.  A Pareto chart is a bar graph used to arrange information in such a way that priorities for process improvement can be established.  It organizes and displays information to show the relative importance of data.  The chart is similar to the histogram or bar chart, except that the bars are arranged in decreasing order from left to right along the abscissa.
+
+     The fundamental idea (Pareto principle) behind the use of Pareto diagrams is that the majority of an effect is due to a small subset of the causes, so for quality improvement the first few (as presented on the diagram) contributing causes to a problem usually account for the majority of the result.  Thus, targeting these "major causes" for elimination results in the most cost-effective improvement scheme.
+
+     The data are passed as X and the abscissa as Y.  If Y is absent, then the abscissa are assumed to be `1 : length (X)'.  Y can be a string array, a cell array of strings or a numerical vector.
+
+     An example of the use of `pareto' is
+
+          Cheese = {"Cheddar", "Swiss", "Camembert", ...
+                    "Munster", "Stilton", "Blue"};
+          Sold = [105, 30, 70, 10, 15, 20];
+          pareto(Sold, Cheese);
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Draw a Pareto chart, also called ABC chart.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+legend
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3141
+ -- Function File:  legend (ST1, ST2, ...)
+ -- Function File:  legend (ST1, ST2, ..., "location", POS)
+ -- Function File:  legend (MATSTR)
+ -- Function File:  legend (MATSTR, "location", POS)
+ -- Function File:  legend (CELL)
+ -- Function File:  legend (CELL, "location", POS)
+ -- Function File:  legend ('FUNC')
+     Display a legend for the current axes using the specified strings as labels.  Legend entries may be specified as individual character string arguments, a character array, or a cell array of character strings.  Legend works on line graphs, bar graphs, etc.  A plot must exist before legend is called.
+
+     The optional parameter POS specifies the location of the legend as follows:
+
+                                                                   north                                                                                                                                            center top
+                                                                   south                                                                                                                                            center bottom
+                                                                   east                                                                                                                                             right center
+                                                                   west                                                                                                                                             left center
+                                                                   northeast                                                                                                                                        right top (default)
+                                                                   northwest                                                                                                                                        left top
+                                                                   southeast                                                                                                                                        right bottom
+                                                                   southwest                                                                                                                                        left bottom
+
+                                                                   outside                                                                                                                                          can be appended to any location string
+
+     Some specific functions are directly available using FUNC:
+
+    "show"
+          Show legends from the plot
+
+    "hide"
+    "off"
+          Hide legends from the plot
+
+    "boxon"
+          Draw a box around legends
+
+    "boxoff"
+          Withdraw the box around legends
+
+    "left"
+          Text is to the left of the keys
+
+    "right"
+          Text is to the right of the keys
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Display a legend for the current axes using the specified strings as labels.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+mesh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 367
+ -- Function File:  mesh (X, Y, Z)
+     Plot a mesh given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.  See also: meshgrid, contour.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+Plot a mesh given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+peaks
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 854
+ -- Function File:  peaks ()
+ -- Function File:  peaks (N)
+ -- Function File:  peaks (X, Y)
+ -- Function File: Z = peaks (...)
+ -- Function File: [X, Y, Z] = peaks (...)
+     Generate a function with lots of local maxima and minima.  The function has the form
+
+
+     f(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) ...
+              - 10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) ...
+              - 1/3*exp(-(x+1)^2 - y^2)
+
+     Called without a return argument, `peaks' plots the surface of the above function using `mesh'.  If N is a scalar, the `peaks' returns the values of the above function on a N-by-N mesh over the range `[-3,3]'.  The default value for N is 49.
+
+     If N is a vector, then it represents the X and Y values of the grid on which to calculate the above function.  The X and Y values can be specified separately.  See also: surf, mesh, meshgrid.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Generate a function with lots of local maxima and minima.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+contour
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 982
+ -- Function File:  contour (Z)
+ -- Function File:  contour (Z, VN)
+ -- Function File:  contour (X, Y, Z)
+ -- Function File:  contour (X, Y, Z, VN)
+ -- Function File:  contour (..., STYLE)
+ -- Function File:  contour (H, ...)
+ -- Function File: [C, H] = contour (...)
+     Plot level curves (contour lines) of the matrix Z, using the contour matrix C computed by `contourc' from the same arguments; see the latter for their interpretation.  The set of contour levels, C, is only returned if requested.  For example:
+
+          x = 0:2;
+          y = x;
+          z = x' * y;
+          contour (x, y, z, 2:3)
+
+     The style to use for the plot can be defined with a line style STYLE in a similar manner to the line styles used with the `plot' command.  Any markers defined by STYLE are ignored.
+
+     The optional input and output argument H allows an axis handle to be passed to `contour' and the handles to the contour objects to be returned.  See also: contourc, patch, plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 166
+Plot level curves (contour lines) of the matrix Z, using the contour matrix C computed by `contourc' from the same arguments; see the latter for their interpretation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+isosurface
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3902
+ -- Function File: [FV] = isosurface (VAL, ISO)
+ -- Function File: [FV] = isosurface (X, Y, Z, VAL, ISO)
+ -- Function File: [FV] = isosurface (..., "noshare", "verbose")
+ -- Function File: [FVC] = isosurface (..., COL)
+ -- Function File: [F, V] = isosurface (X, Y, Z, VAL, ISO)
+ -- Function File: [F, V, C] = isosurface (X, Y, Z, VAL, ISO, COL)
+ -- Function File:  isosurface (X, Y, Z, VAL, ISO, COL, OPT)
+     If called with one output argument and the first input argument VAL is a three-dimensional array that contains the data of an isosurface geometry and the second input argument ISO keeps the isovalue as a scalar value then return a structure array FV that contains the fields FACES and VERTICES at computed points `[x, y, z] = meshgrid (1:l, 1:m, 1:n)'.  The output argument FV can directly be taken as an input argument for the `patch' function.
+
+     If called with further input arguments X, Y and Z which are three-dimensional arrays with the same size than VAL then the volume data is taken at those given points.
+
+     The string input argument "noshare" is only for compatibility and has no effect. If given the string input argument "verbose" then print messages to the command line interface about the current progress.
+
+     If called with the input argument COL which is a three-dimensional array of the same size than VAL then take those values for the interpolation of coloring the isosurface geometry.  Add the field FACEVERTEXCDATA to the structure array FV.
+
+     If called with two or three output arguments then return the information about the faces F, vertices V and color data C as seperate arrays instead of a single structure array.
+
+     If called with no output argument then directly process the isosurface geometry with the `patch' command.
+
+     For example
+
+          [x, y, z] = meshgrid (1:5, 1:5, 1:5);
+          val = rand (5, 5, 5);
+          isosurface (x, y, z, val, .5);
+
+     will directly draw a random isosurface geometry in a graphics window.  Another example for an isosurface geometry with different additional coloring
+
+          N = 15;    ## Increase number of vertices in each direction
+          iso = .4;  ## Change isovalue to .1 to display a sphere
+          lin = linspace (0, 2, N);
+          [x, y, z] = meshgrid (lin, lin, lin);
+          c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
+          figure (); ## Open another figure window
+
+          subplot (2, 2, 1); view (-38, 20);
+          [f, v] = isosurface (x, y, z, c, iso);
+          p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+          set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+           set (p, "FaceColor", "green", "FaceLighting", "phong");
+           light ("Position", [1 1 5]); ## Available with the JHandles package
+
+          subplot (2, 2, 2); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "EdgeColor", "blue");
+          set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+           set (p, "FaceColor", "none", "FaceLighting", "phong");
+           light ("Position", [1 1 5]);
+
+          subplot (2, 2, 3); view (-38, 20);
+          [f, v, c] = isosurface (x, y, z, c, iso, y);
+          p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \
+                     "FaceColor", "interp", "EdgeColor", "none");
+          set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+           set (p, "FaceLighting", "phong");
+           light ("Position", [1 1 5]);
+
+          subplot (2, 2, 4); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \
+                     "FaceColor", "interp", "EdgeColor", "blue");
+          set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+           set (p, "FaceLighting", "phong");
+           light ("Position", [1 1 5]);
+
+     See also: isocolors, isonormals, isocaps.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 352
+If called with one output argument and the first input argument VAL is a three-dimensional array that contains the data of an isosurface geometry and the second input argument ISO keeps the isovalue as a scalar value then return a structure array FV that contains the fields FACES and VERTICES at computed points `[x, y, z] = meshgrid (1:l, 1:m, 1:n)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+isocolors
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3332
+ -- Function File: [CD] = isocolors (C, V)
+ -- Function File: [CD] = isocolors (X, Y, Z, C, V)
+ -- Function File: [CD] = isocolors (X, Y, Z, R, G, B, V)
+ -- Function File: [CD] = isocolors (R, G, B, V)
+ -- Function File: [CD] = isocolors (..., P)
+ -- Function File: isocolors (...)
+     If called with one output argument and the first input argument C is a three-dimensional array that contains color values and the second input argument V keeps the vertices of a geometry then return a matrix CD with color data information for the geometry at computed points `[x, y, z] = meshgrid (1:l, 1:m, 1:n)'.  The output argument CD can be taken to manually set FaceVertexCData of a patch.
+
+     If called with further input arguments X, Y and Z which are three-dimensional arrays of the same size than C then the color data is taken at those given points.  Instead of the color data C this function can also be called with RGB values R, G, B.  If input argumnets X, Y, Z are not given then again `meshgrid' computed values are taken.
+
+     Optionally, the patch handle P can be given as the last input argument to all variations of function calls instead of the vertices data V.  Finally, if no output argument is given then directly change the colors of a patch that is given by the patch handle P.
+
+     For example,
+          function [] = isofinish (p)
+            set (gca, "DataAspectRatioMode", "manual", \
+                 "DataAspectRatio", [1 1 1]);
+            set (p, "FaceColor", "interp");
+            ## set (p, "FaceLighting", "flat");
+            ## light ("Position", [1 1 5]); ## Available with JHandles
+          endfunction
+
+          N = 15;    ## Increase number of vertices in each direction
+          iso = .4;  ## Change isovalue to .1 to display a sphere
+          lin = linspace (0, 2, N);
+          [x, y, z] = meshgrid (lin, lin, lin);
+          c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
+          figure (); ## Open another figure window
+
+          subplot (2, 2, 1); view (-38, 20);
+          [f, v] = isosurface (x, y, z, c, iso);
+          p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+          cdat = rand (size (c));       ## Compute random patch color data
+          isocolors (x, y, z, cdat, p); ## Directly set colors of patch
+          isofinish (p);                ## Call user function isofinish
+
+          subplot (2, 2, 2); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+          [r, g, b] = meshgrid (lin, 2-lin, 2-lin);
+          cdat = isocolors (x, y, z, c, v); ## Compute color data vertices
+          set (p, "FaceVertexCData", cdat); ## Set color data manually
+          isofinish (p);
+
+          subplot (2, 2, 3); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+          cdat = isocolors (r, g, b, c, p); ## Compute color data patch
+          set (p, "FaceVertexCData", cdat); ## Set color data manually
+          isofinish (p);
+
+          subplot (2, 2, 4); view (-38, 20);
+          p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+          r = g = b = repmat ([1:N] / N, [N, 1, N]); ## Black to white
+          cdat = isocolors (x, y, z, r, g, b, v);
+          set (p, "FaceVertexCData", cdat);
+          isofinish (p);
+
+     See also: isosurface, isonormals, isocaps.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 314
+If called with one output argument and the first input argument C is a three-dimensional array that contains color values and the second input argument V keeps the vertices of a geometry then return a matrix CD with color data information for the geometry at computed points `[x, y, z] = meshgrid (1:l, 1:m, 1:n)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+gnuplot_drawnow
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 228
+ -- Function File:  drawnow ()
+     Update and display the current graphics.
+
+     Octave automatically calls drawnow just before printing a prompt, when `sleep' or `pause' is called, or while waiting for command-line input.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Update and display the current graphics.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+quiver3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1453
+ -- Function File:  quiver3 (U, V, W)
+ -- Function File:  quiver3 (X, Y, Z, U, V, W)
+ -- Function File:  quiver3 (..., S)
+ -- Function File:  quiver3 (..., STYLE)
+ -- Function File:  quiver3 (..., 'filled')
+ -- Function File:  quiver3 (H, ...)
+ -- Function File: H = quiver3 (...)
+     Plot the `(U, V, W)' components of a vector field in an `(X, Y), Z' meshgrid.  If the grid is uniform, you can specify X, Y Z as vectors.
+
+     If X, Y and Z are undefined they are assumed to be `(1:M, 1:N, 1:P)' where `[M, N] = size(U)' and `P = max (size (W))'.
+
+     The variable S is a scalar defining a scaling factor to use for  the arrows of the field relative to the mesh spacing.  A value of 0 disables all scaling.  The default value is 1.
+
+     The style to use for the plot can be defined with a line style STYLE in a similar manner to the line styles used with the `plot' command.  If a marker is specified then markers at the grid points of the vectors are printed rather than arrows.  If the argument 'filled' is given then the markers as filled.
+
+     The optional return value H provides a quiver group that regroups the components of the quiver plot (body, arrow and marker), and allows them to be changed together
+
+          [x, y, z] = peaks (25);
+          surf (x, y, z);
+          hold on;
+          [u, v, w] = surfnorm (x, y, z / 10);
+          h = quiver3 (x, y, z, u, v, w);
+          set (h, "maxheadsize", 0.33);
+
+     See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Plot the `(U, V, W)' components of a vector field in an `(X, Y), Z' meshgrid.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+clf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 481
+ -- Function File:  clf ()
+ -- Function File:  clf ("reset")
+ -- Function File:  clf (HFIG)
+ -- Function File:  clf (HFIG, "reset")
+     Clear the current figure window.  `clf' operates by deleting child graphics objects with visible handles (`HandleVisibility' = on).  If HFIG is specified operate on it instead of the current figure.  If the optional argument `"reset"' is specified, all objects including those with hidden handles are deleted.  See also: cla, close, delete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Clear the current figure window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hggroup
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 379
+ -- Function File:  hggroup ()
+ -- Function File:  hggroup (H)
+ -- Function File:  hggroup (..., PROPERTY, VALUE, ...)
+     Create group object with parent H.  If no parent is specified, the group is created in the current axes.  Return the handle of the group object created.
+
+     Multiple property-value pairs may be specified for the group, but they must appear in pairs.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Create group object with parent H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+backend
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 399
+ -- Function File:  backend (NAME)
+ -- Function File:  backend (HLIST, NAME)
+     Change the default graphics backend to NAME.  If the backend is not already loaded, it is first initialized (initialization is done through the execution of `__init_NAME__').
+
+     When called with a list of figure handles, HLIST, the backend is changed only for the listed figures.  See also: available_backends.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Change the default graphics backend to NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+refreshdata
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 886
+ -- Function File:  refreshdata ()
+ -- Function File:  refreshdata (H)
+ -- Function File:  refreshdata (H, WORKSPACE)
+     Evaluate any `datasource' properties of the current figure and update the plot if the corresponding data has changed.  If called with one or more arguments H is a scalar or array of figure handles to refresh.  The optional second argument WORKSPACE can take the following values.
+
+    `"base"'
+          Evaluate the datasource properties in the base workspace.  (default).
+
+    `"caller"'
+          Evaluate the datasource properties in the workspace of the function that called `refreshdata'.
+
+     An example of the use of `refreshdata' is:
+
+          x = 0:0.1:10;
+          y = sin (x);
+          plot (x, y, "ydatasource", "y");
+          for i = 1 : 100
+            pause(0.1)
+            y = sin (x + 0.1 * i);
+            refreshdata();
+          endfor
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+Evaluate any `datasource' properties of the current figure and update the plot if the corresponding data has changed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+line
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 394
+ -- Function File:  line ()
+ -- Function File:  line (X, Y)
+ -- Function File:  line (X, Y, Z)
+ -- Function File:  line (X, Y, Z, PROPERTY, VALUE, ...)
+     Create line object from X and Y and insert in current axes object.  Return a handle (or vector of handles) to the line objects created.
+
+     Multiple property-value pairs may be specified for the line, but they must appear in pairs.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Create line object from X and Y and insert in current axes object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ezsurfc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1329
+ -- Function File:  ezsurfc (F)
+ -- Function File:  ezsurfc (FX, FY, FZ)
+ -- Function File:  ezsurfc (..., DOM)
+ -- Function File:  ezsurfc (..., N)
+ -- Function File:  ezsurfc (..., 'circ')
+ -- Function File:  ezsurfc (H, ...)
+ -- Function File: H = ezsurfc (...)
+     Plots the surface and contour lines defined by a function.  F is a string, inline function or function handle with two arguments defining the function.  By default the plot is over the domain `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and maximum value of both X and Y.  If DOM is a four element vector, then the minimum and maximum value of X and Y are specify separately.
+
+     N is a scalar defining the number of points to use in each dimension.
+
+     If three functions are passed, then plot the parametrically defined function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezsurfc (f, [-3, 3]);
+
+     See also: ezplot, ezmeshc, ezsurf, ezmesh.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Plots the surface and contour lines defined by a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+refresh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 243
+ -- Function File:  refresh ()
+ -- Function File:  refresh (H)
+     Refresh a figure, forcing it to be redrawn.  Called without an argument the current figure is redrawn, otherwise the figure pointed to by H is redrawn.  See also: drawnow.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Refresh a figure, forcing it to be redrawn.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+caxis
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 669
+ -- Function File:  caxis (LIMITS)
+ -- Function File:  caxis (H, ...)
+     Set color axis limits for plots.
+
+     The argument LIMITS should be a 2 element vector specifying the lower and upper limits to assign to the first and last value in the colormap.  Values outside this range are clamped to the first and last colormap entries.
+
+     If LIMITS is 'auto', then automatic colormap scaling is applied, whereas if LIMITS is 'manual' the colormap scaling is set to manual.
+
+     Called without any arguments to current color axis limits are returned.
+
+     If an axes handle is passed as the first argument, then operate on this axes rather than the current axes.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Set color axis limits for plots.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+quiver
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1332
+ -- Function File:  quiver (U, V)
+ -- Function File:  quiver (X, Y, U, V)
+ -- Function File:  quiver (..., S)
+ -- Function File:  quiver (..., STYLE)
+ -- Function File:  quiver (..., 'filled')
+ -- Function File:  quiver (H, ...)
+ -- Function File: H = quiver (...)
+     Plot the `(U, V)' components of a vector field in an `(X, Y)' meshgrid.  If the grid is uniform, you can specify X and Y as vectors.
+
+     If X and Y are undefined they are assumed to be `(1:M, 1:N)' where `[M, N] = size(U)'.
+
+     The variable S is a scalar defining a scaling factor to use for  the arrows of the field relative to the mesh spacing.  A value of 0 disables all scaling.  The default value is 1.
+
+     The style to use for the plot can be defined with a line style STYLE in a similar manner to the line styles used with the `plot' command.  If a marker is specified then markers at the grid points of the vectors are printed rather than arrows.  If the argument 'filled' is given then the markers as filled.
+
+     The optional return value H provides a quiver group that regroups the components of the quiver plot (body, arrow and marker), and allows them to be changed together
+
+          [x, y] = meshgrid (1:2:20);
+          h = quiver (x, y, sin (2*pi*x/10), sin (2*pi*y/10));
+          set (h, "maxheadsize", 0.33);
+
+     See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Plot the `(U, V)' components of a vector field in an `(X, Y)' meshgrid.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+plot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3989
+ -- Function File:  plot (Y)
+ -- Function File:  plot (X, Y)
+ -- Function File:  plot (X, Y, PROPERTY, VALUE, ...)
+ -- Function File:  plot (X, Y, FMT)
+ -- Function File:  plot (H, ...)
+     Produces two-dimensional plots.  Many different combinations of arguments are possible.  The simplest form is
+
+          plot (Y)
+
+     where the argument is taken as the set of Y coordinates and the X coordinates are taken to be the indices of the elements, starting with 1.
+
+     To save a plot, in one of several image formats such as PostScript or PNG, use the `print' command.
+
+     If more than one argument is given, they are interpreted as
+
+          plot (Y, PROPERTY, VALUE, ...)
+
+     or
+
+          plot (X, Y, PROPERTY, VALUE, ...)
+
+     or
+
+          plot (X, Y, FMT, ...)
+
+     and so on.  Any number of argument sets may appear.  The X and Y values are interpreted as follows:
+
+        * If a single data argument is supplied, it is taken as the set of Y coordinates and the X coordinates are taken to be the indices of the elements, starting with 1.
+
+        * If the X is a vector and Y is a matrix, then the columns (or rows) of Y are plotted versus X.  (using whichever combination matches, with columns tried first.)
+
+        * If the X is a matrix and Y is a vector, Y is plotted versus the columns (or rows) of X.  (using whichever combination matches, with columns tried first.)
+
+        * If both arguments are vectors, the elements of Y are plotted versus the elements of X.
+
+        * If both arguments are matrices, the columns of Y are plotted versus the columns of X.  In this case, both matrices must have the same number of rows and columns and no attempt is made to transpose the arguments to make the number of rows match.
+
+          If both arguments are scalars, a single point is plotted.
+
+     Multiple property-value pairs may be specified, but they must appear in pairs.  These arguments are applied to the lines drawn by `plot'.
+
+     If the FMT argument is supplied, it is interpreted as follows.  If FMT is missing, the default gnuplot line style is assumed.
+
+    `-'
+          Set lines plot style (default).
+
+    `.'
+          Set dots plot style.
+
+    `N'
+          Interpreted as the plot color if N is an integer in the range 1 to 6.
+
+    `NM'
+          If NM is a two digit integer and M is an integer in the range 1 to 6, M is interpreted as the point style.  This is only valid in combination with the `@' or `-@' specifiers.
+
+    `C'
+          If C is one of `"k"' (black), `"r"' (red), `"g"' (green), `"b"' (blue), `"m"' (magenta), `"c"' (cyan), or `"w"' (white), it is interpreted as the line plot color.
+
+    `";title;"'
+          Here `"title"' is the label for the key.
+
+    `+'
+    `*'
+    `o'
+    `x'
+    `^'
+          Used in combination with the points or linespoints styles, set the point style.
+
+     The FMT argument may also be used to assign key titles.  To do so, include the desired title between semi-colons after the formatting sequence described above, e.g., "+3;Key Title;" Note that the last semi-colon is required and will generate an error if it is left out.
+
+     Here are some plot examples:
+
+          plot (x, y, "@12", x, y2, x, y3, "4", x, y4, "+")
+
+     This command will plot `y' with points of type 2 (displayed as `+') and color 1 (red), `y2' with lines, `y3' with lines of color 4 (magenta) and `y4' with points displayed as `+'.
+
+          plot (b, "*", "markersize", 3)
+
+     This command will plot the data in the variable `b', with points displayed as `*' with a marker size of 3.
+
+          t = 0:0.1:6.3;
+          plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+
+     This will plot the cosine and sine functions and label them accordingly in the key.
+
+     If the first argument is an axis handle, then plot into these axes, rather than the current axis handle returned by `gca'.  See also: semilogx, semilogy, loglog, polar, mesh, contour, bar, stairs, errorbar, xlabel, ylabel, title, print.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Produces two-dimensional plots.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+scatter
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1399
+ -- Function File:  scatter (X, Y, S, C)
+ -- Function File:  scatter (..., 'filled')
+ -- Function File:  scatter (..., STYLE)
+ -- Function File:  scatter (..., PROP, VAL)
+ -- Function File:  scatter (H, ...)
+ -- Function File: H = scatter (...)
+     Plot a scatter plot of the data.  A marker is plotted at each point defined by the points in the vectors X and Y.  The size of the markers used is determined by the S, which can be a scalar, a vector of the same length of X and Y.  If S is not given or is an empty matrix, then the default value of 8 points is used.
+
+     The color of the markers is determined by C, which can be a string defining a fixed color, a 3 element vector giving the red, green and blue components of the color, a vector of the same length as X that gives a scaled index into the current colormap, or a N-by-3 matrix defining the colors of each of the markers individually.
+
+     The marker to use can be changed with the STYLE argument, that is a string defining a marker in the same manner as the `plot' command.  If the argument 'filled' is given then the markers as filled.  All additional arguments are passed to the underlying patch command.
+
+     The optional return value H provides a handle to the patch object
+
+          x = randn (100, 1);
+          y = randn (100, 1);
+          scatter (x, y, [], sqrt(x.^2 + y.^2));
+
+     See also: plot, patch, scatter3.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Plot a scatter plot of the data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+surf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 366
+ -- Function File:  surf (X, Y, Z)
+     Plot a surface given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.  See also: mesh, surface.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+Plot a surface given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+feather
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 760
+ -- Function File:  feather (U, V)
+ -- Function File:  feather (Z)
+ -- Function File:  feather (..., STYLE)
+ -- Function File:  feather (H, ...)
+ -- Function File: H = feather (...)
+     Plot the `(U, V)' components of a vector field emanating from equidistant points on the x-axis.  If a single complex argument Z is given, then `U = real (Z)' and `V = imag (Z)'.
+
+     The style to use for the plot can be defined with a line style STYLE in a similar manner to the line styles used with the `plot' command.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          phi = [0 : 15 : 360] * pi / 180;
+          feather (sin (phi), cos (phi))
+
+     See also: plot, quiver, compass.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Plot the `(U, V)' components of a vector field emanating from equidistant points on the x-axis.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+newplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Function File:  newplot ()
+     Prepare graphics engine to produce a new plot.  This function should be called at the beginning of all high-level plotting functions.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Prepare graphics engine to produce a new plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+polar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 199
+ -- Function File:  polar (THETA, RHO, FMT)
+     Make a two-dimensional plot given the polar coordinates THETA and RHO.
+
+     The optional third argument specifies the line type.  See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Make a two-dimensional plot given the polar coordinates THETA and RHO.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+closereq
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+ -- Function File:  closereq ()
+     Close the current figure and delete all graphics objects associated with it.  See also: close, delete.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Close the current figure and delete all graphics objects associated with it.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+area
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 836
+ -- Function File:  area (X, Y)
+ -- Function File:  area (X, Y, LVL)
+ -- Function File:  area (..., PROP, VAL, ...)
+ -- Function File:  area (Y, ...)
+ -- Function File:  area (H, ...)
+ -- Function File: H = area (...)
+     Area plot of cumulative sum of the columns of Y.  This shows the contributions of a value to a sum, and is functionally similar to `plot (X, cumsum (Y, 2))', except that the area under the curve is shaded.
+
+     If the X argument is omitted it is assumed to be given by `1 : rows (Y)'.  A value LVL can be defined that determines where the base level of the shading under the curve should be defined.
+
+     Additional arguments to the `area' function are passed to the `patch'.  The optional return value H provides a handle to area series object representing the patches of the areas.  See also: plot, patch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Area plot of cumulative sum of the columns of Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+xlim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 771
+ -- Function File: XL = xlim ()
+ -- Function File:  xlim (XL)
+ -- Function File: M = xlim ('mode')
+ -- Function File:  xlim (M)
+ -- Function File:  xlim (H, ...)
+     Get or set the limits of the x-axis of the current plot.  Called without arguments `xlim' returns the x-axis limits of the current plot.  If passed a two element vector XL, the limits of the x-axis are set to this value.
+
+     The current mode for calculation of the x-axis can be returned with a call `xlim ('mode')', and can be either 'auto' or 'manual'.  The current plotting mode can be set by passing either 'auto' or 'manual' as the argument.
+
+     If passed an handle as the first argument, then operate on this handle rather than the current axes handle.  See also: ylim, zlim, set, get, gca.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Get or set the limits of the x-axis of the current plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ancestor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 570
+ -- Function File: PARENT = ancestor (H, TYPE)
+ -- Function File: PARENT = ancestor (H, TYPE, 'toplevel')
+     Return the first ancestor of handle object H whose type matches TYPE, where TYPE is a character string.  If TYPE is a cell array of strings, return the first parent whose type matches any of the given type strings.
+
+     If the handle object H is of type TYPE, return H.
+
+     If `"toplevel"' is given as a 3rd argument, return the highest parent in the object hierarchy that matches the condition, instead of the first (nearest) one.  See also: get, set.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+Return the first ancestor of handle object H whose type matches TYPE, where TYPE is a character string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+gtext
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 399
+ -- Function File:  gtext (S)
+ -- Function File:  gtext ({S1; S2; ...})
+ -- Function File:  gtext (..., PROP, VAL)
+     Place text on the current figure using the mouse.  The text is defined by the string S.  If S is a cell array, each element of the cell array is written to a separate line.  Additional arguments are passed to the underlying text object as properties.  See also: ginput, text.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Place text on the current figure using the mouse.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spinmap
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 302
+ -- Function File:  spinmap (T, INC)
+     Cycle the colormap for T seconds with an increment of INC.  Both parameters are optional.  The default cycle time is 5 seconds and the default increment is 2.
+
+     A higher value of INC causes a faster cycle through the colormap.  See also: gca, colorbar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Cycle the colormap for T seconds with an increment of INC.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ishold
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 173
+ -- Function File:  ishold
+     Return true if the next line will be added to the current plot, or false if the plot device will be cleared before drawing the next line.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 137
+Return true if the next line will be added to the current plot, or false if the plot device will be cleared before drawing the next line.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+diffuse
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 341
+ -- Function File:  diffuse (SX, SY, SZ, L)
+     Calculate diffuse reflection strength of a surface defined by the normal vector elements SX, SY, SZ.  The light vector can be specified using parameter L.  It can be given as 2-element vector [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz].  See also: specular, surfl.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+Calculate diffuse reflection strength of a surface defined by the normal vector elements SX, SY, SZ.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+semilogy
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 239
+ -- Function File:  semilogy (ARGS)
+     Produce a two-dimensional plot using a log scale for the Y axis.  See the description of `plot' for a description of the arguments that `semilogy' will accept.  See also: plot, semilogx, loglog.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Produce a two-dimensional plot using a log scale for the Y axis.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+figure
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 314
+ -- Function File:  figure (N)
+ -- Function File:  figure (N, PROPERTY, VALUE, ...)
+     Set the current plot window to plot window N.  If no arguments are specified, the next available window number is chosen.
+
+     Multiple property-value pairs may be specified for the figure, but they must appear in pairs.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Set the current plot window to plot window N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+stem3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 542
+ -- Function File: H = stem3 (X, Y, Z, LINESPEC)
+     Plot a three-dimensional stem graph and return the handles of the line and marker objects used to draw the stems as "stem series" object.  The default color is `"r"' (red).  The default line style is `"-"' and the default marker is `"o"'.
+
+     For example,
+          theta = 0:0.2:6;
+          stem3 (cos (theta), sin (theta), theta)
+
+     plots 31 stems with heights from 0 to 6 lying on a circle.  Color definitions with rgb-triples are not valid!  See also: bar, barh, stem, plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 137
+Plot a three-dimensional stem graph and return the handles of the line and marker objects used to draw the stems as "stem series" object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+zlabel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+ -- Function File:  zlabel (STRING)
+ -- Function File:  zlabel (H, STRING)
+     See also: xlabel..
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 17
+See also: xlabel.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+print
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4534
+ -- Function File:  print ()
+ -- Function File:  print (OPTIONS)
+ -- Function File:  print (FILENAME, OPTIONS)
+ -- Function File:  print (H, FILENAME, OPTIONS)
+     Print a graph, or save it to a file
+
+     FILENAME defines the file name of the output file.  If no filename is specified, the output is sent to the printer.
+
+     H specifies the figure handle.  If no handle is specified the handle for the current figure is used.
+
+     OPTIONS:
+    `-PPRINTER'
+          Set the PRINTER name to which the graph is sent if no FILENAME is specified.
+
+    `-GGHOSTSCRIPT_COMMAND'
+          Specify the command for calling Ghostscript.  For Unix and Windows, the defaults are 'gs' and 'gswin32c', respectively.
+
+    `-color'
+    `-mono'
+          Monochrome or color lines.
+
+    `-solid'
+    `-dashed'
+          Solid or dashed lines.
+
+    `-portrait'
+    `-landscape'
+          Specify the orientation of the plot for printed output.
+
+    `-dDEVICE'
+          Output device, where DEVICE is one of:
+         `ps'
+         `ps2'
+         `psc'
+         `psc2'
+               Postscript (level 1 and 2, mono and color)
+
+         `eps'
+         `eps2'
+         `epsc'
+         `epsc2'
+               Encapsulated postscript (level 1 and 2, mono and color)
+
+         `tex'
+         `epslatex'
+         `epslatexstandalone'
+         `pstex'
+         `pslatex'
+               Generate a LaTeX (or TeX) file for labels, and eps/ps for graphics.  The file produced by `epslatexstandalone' can be processed directly by LaTeX.  The other formats are intended to be included in a LaTeX (or TeX) document.  The `tex' device is the same as the `epslatex' device.
+
+         `ill'
+         `aifm'
+               Adobe Illustrator
+
+         `cdr'
+         `corel'
+               CorelDraw
+
+         `dxf'
+               AutoCAD
+
+         `emf'
+         `meta'
+               Microsoft Enhanced Metafile
+
+         `fig'
+               XFig.  If this format is selected the additional options `-textspecial' or `-textnormal' can be used to control     whether the special flag should be set for the text in     the figure (default is `-textnormal').
+
+         `hpgl'
+               HP plotter language
+
+         `mf'
+               Metafont
+
+         `png'
+               Portable network graphics
+
+         `jpg'
+         `jpeg'
+               JPEG image
+
+         `gif'
+               GIF image
+
+         `pbm'
+               PBMplus
+
+         `svg'
+               Scalable vector graphics
+
+         `pdf'
+               Portable document format
+
+          If the device is omitted, it is inferred from the file extension, or if there is no filename it is sent to the printer as postscript.
+
+    `-dGS_DEVICE'
+          Additional devices are supported by Ghostscript.  Some examples are;
+
+         `ljet2p'
+               HP LaserJet IIP
+
+         `ljet3'
+               HP LaserJet III
+
+         `deskjet'
+               HP DeskJet and DeskJet Plus
+
+         `cdj550'
+               HP DeskJet 550C
+
+         `paintjet'
+               HP PointJet
+
+         `pcx24b'
+               24-bit color PCX file format
+
+         `ppm'
+               Portable Pixel Map file format
+
+          For a complete list, type `system ("gs -h")' to see what formats and devices are available.
+
+          When the ghostscript is sent to a printer the size is determined by the figure's "papersize" property.  When the ghostscript output is sent to a file the size is determined by the figure's "paperposition" property.
+
+    `-rNUM'
+          Resolution of bitmaps in pixels per inch.  For both metafiles and SVG the default is the screen resolution, for other it is 150 dpi.  To specify screen resolution, use "-r0".
+
+    `-tight'
+          Forces a tight bounding box for eps-files.  Since the ghostscript devices are conversion of an eps-file, this option works the those devices as well.
+
+    `-SXSIZE,YSIZE'
+          Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG.  If using the command form of the print function, you must quote the XSIZE,YSIZE option.  For example, by writing `"-S640,480"'.  The size defaults to that specified by the figure's paperposition property.
+
+    `-FFONTNAME'
+    `-FFONTNAME:SIZE'
+    `-F:SIZE'
+          FONTNAME set the postscript font (for use with postscript, aifm, corel and fig).  By default, 'Helvetica' is set for PS/Aifm, and 'SwitzerlandLight' for Corel.  It can also be 'Times-Roman'.  SIZE is given in points.  FONTNAME is ignored for the fig device.
+
+     The filename and options can be given in any order.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Print a graph, or save it to a file 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+plotmatrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1351
+ -- Function File:  plotmatrix (X, Y)
+ -- Function File:  plotmatrix (X)
+ -- Function File:  plotmatrix (..., STYLE)
+ -- Function File:  plotmatrix (H, ...)
+ -- Function File: [H, AX, BIGAX, P, PAX] = plotmatrix (...)
+     Scatter plot of the columns of one matrix against another.  Given the arguments X and Y, that have a matching number of rows, `plotmatrix' plots a set of axes corresponding to
+
+          plot (X (:, i), Y (:, j)
+
+     Given a single argument X, then this is equivalent to
+
+          plotmatrix (X, X)
+
+     except that the diagonal of the set of axes will be replaced with the histogram `hist (X (:, i))'.
+
+     The marker to use can be changed with the STYLE argument, that is a string defining a marker in the same manner as the `plot' command.  If a leading axes handle H is passed to `plotmatrix', then this axis will be used for the plot.
+
+     The optional return value H provides handles to the individual graphics objects in the scatter plots, whereas AX returns the handles to the scatter plot axis objects.  BIGAX is a hidden axis object that surrounds the other axes, such that the commands `xlabel', `title', etc., will be associated with this hidden axis.  Finally P returns the graphics objects associated with the histogram and PAX the corresponding axes objects.
+
+          plotmatrix (randn (100, 3), 'g+')
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Scatter plot of the columns of one matrix against another.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fill
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 279
+ -- Function File:  fill (X, Y, C)
+ -- Function File:  fill (X1, Y1, C1, X2, Y2, C2)
+ -- Function File:  fill (..., PROP, VAL)
+ -- Function File:  fill (H, ...)
+ -- Function File: H = fill (...)
+     Create one or more filled patch objects, returning a patch object for each.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Create one or more filled patch objects, returning a patch object for each.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cylinder
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 787
+ -- Function File:  cylinder
+ -- Function File:  cylinder (R)
+ -- Function File:  cylinder (R, N)
+ -- Function File: [X, Y, Z] = cylinder (...)
+ -- Function File:  cylinder (AX, ...)
+     Generates three matrices in `meshgrid' format, such that `surf (X, Y, Z)' generates a unit cylinder.  The matrices are of size `N+1'-by-`N+1'.  R is a vector containing the radius along the z-axis.  If N or R are omitted then default values of 20 or [1 1] are assumed.
+
+     Called with no return arguments, `cylinder' calls directly `surf (X, Y, Z)'.  If an axes handle AX is passed as the first argument, the surface is plotted to this set of axes.
+
+     Examples:
+          disp ("plotting a cone")
+          [x, y, z] = cylinder (10:-1:0,50);
+          surf (x, y, z);
+     See also: sphere.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+Generates three matrices in `meshgrid' format, such that `surf (X, Y, Z)' generates a unit cylinder.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+meshc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 386
+ -- Function File:  meshc (X, Y, Z)
+     Plot a mesh and contour given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.  If X and Y are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different X values and rows of Z correspond to different Y values.  See also: meshgrid, mesh, contour.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 132
+Plot a mesh and contour given matrices X, and Y from `meshgrid' and a matrix Z corresponding to the X and Y coordinates of the mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+box
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 237
+ -- Function File:  box (ARG)
+ -- Function File:  box (H, ...)
+     Control the display of a border around the plot.  The argument may be either `"on"' or `"off"'.  If it is omitted, the current box state is toggled.  See also: grid.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Control the display of a border around the plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+gcbf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 323
+ -- Function File: FIG = gcbf ()
+     Return a handle to the figure containing the object whose callback is currently executing.  If no callback is executing, this function returns the empty matrix.  The handle returned by this function is the same as the second output argument of gcbo.
+
+     See also: gcf, gca, gcbo.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 90
+Return a handle to the figure containing the object whose callback is currently executing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+compass
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 760
+ -- Function File:  compass (U, V)
+ -- Function File:  compass (Z)
+ -- Function File:  compass (..., STYLE)
+ -- Function File:  compass (H, ...)
+ -- Function File: H = compass (...)
+     Plot the `(U, V)' components of a vector field emanating from the origin of a polar plot.  If a single complex argument Z is given, then `U = real (Z)' and `V = imag (Z)'.
+
+     The style to use for the plot can be defined with a line style STYLE in a similar manner to the line styles used with the `plot' command.
+
+     The optional return value H provides a list of handles to the the parts of the vector field (body, arrow and marker).
+
+          a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+          compass (eig (a))
+
+     See also: plot, polar, quiver, feather.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 89
+Plot the `(U, V)' components of a vector field emanating from the origin of a polar plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+loglog
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 235
+ -- Function File:  loglog (ARGS)
+     Produce a two-dimensional plot using log scales for both axes.  See the description of `plot' for a description of the arguments that `loglog' will accept.  See also: plot, semilogx, semilogy.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Produce a two-dimensional plot using log scales for both axes.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+meshgrid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 599
+ -- Function File: [XX, YY, ZZ] = meshgrid (X, Y, Z)
+ -- Function File: [XX, YY] = meshgrid (X, Y)
+ -- Function File: [XX, YY] = meshgrid (X)
+     Given vectors of X and Y and Z coordinates, and returning 3 arguments, return three-dimensional arrays corresponding to the X, Y, and Z coordinates of a mesh.  When returning only 2 arguments, return matrices corresponding to the X and Y coordinates of a mesh.  The rows of XX are copies of X, and the columns of YY are copies of Y.  If Y is omitted, then it is assumed to be the same as X, and Z is assumed the same as Y.  See also: mesh, contour.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 158
+Given vectors of X and Y and Z coordinates, and returning 3 arguments, return three-dimensional arrays corresponding to the X, Y, and Z coordinates of a mesh.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+ndgrid
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 522
+ -- Function File: [Y1, Y2, ...,  Yn] = ndgrid (X1, X2, ..., Xn)
+ -- Function File: [Y1, Y2, ...,  Yn] = ndgrid (X)
+     Given n vectors X1, ... Xn, `ndgrid' returns n arrays of dimension n. The elements of the i-th output argument contains the elements of the vector Xi repeated over all dimensions different from the i-th dimension.  Calling ndgrid with only one input argument X is equivalent of calling ndgrid with all n input arguments equal to X:
+
+     [Y1, Y2, ...,  Yn] = ndgrid (X, ..., X) See also: meshgrid.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 21
+Given n vectors X1, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+hist
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 859
+ -- Function File:  hist (Y, X, NORM)
+     Produce histogram counts or plots.
+
+     With one vector input argument, plot a histogram of the values with 10 bins.  The range of the histogram bins is determined by the range of the data.  With one matrix input argument, plot a histogram where each bin contains a bar per input column.
+
+     Given a second scalar argument, use that as the number of bins.
+
+     Given a second vector argument, use that as the centers of the bins, with the width of the bins determined from the adjacent values in the vector.
+
+     If third argument is provided, the histogram is normalized such that the sum of the bars is equal to NORM.
+
+     Extreme values are lumped in the first and last bins.
+
+     With two output arguments, produce the values NN and XX such that `bar (XX, NN)' will plot the histogram.  See also: bar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Produce histogram counts or plots.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+errorbar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2097
+ -- Function File:  errorbar (ARGS)
+     This function produces two-dimensional plots with errorbars.  Many different combinations of arguments are possible.  The simplest form is
+
+          errorbar (Y, EY)
+
+     where the first argument is taken as the set of Y coordinates and the second argument EY is taken as the errors of the Y values.  X coordinates are taken to be the indices of the elements, starting with 1.
+
+     If more than two arguments are given, they are interpreted as
+
+          errorbar (X, Y, ..., FMT, ...)
+
+     where after X and Y there can be up to four error parameters such as EY, EX, LY, UY, etc., depending on the plot type.  Any number of argument sets may appear, as long as they are separated with a format string FMT.
+
+     If Y is a matrix, X and error parameters must also be matrices having same dimensions.  The columns of Y are plotted versus the corresponding columns of X and errorbars are drawn from the corresponding columns of error parameters.
+
+     If FMT is missing, yerrorbars ("~") plot style is assumed.
+
+     If the FMT argument is supplied, it is interpreted as in normal plots.  In addition the following plot styles are supported by errorbar:
+
+    `~'
+          Set yerrorbars plot style (default).
+
+    `>'
+          Set xerrorbars plot style.
+
+    `~>'
+          Set xyerrorbars plot style.
+
+    `#'
+          Set boxes plot style.
+
+    `#~'
+          Set boxerrorbars plot style.
+
+    `#~>'
+          Set boxxyerrorbars plot style.
+
+     Examples:
+
+          errorbar (X, Y, EX, ">")
+
+     produces an xerrorbar plot of Y versus X with X errorbars drawn from X-EX to X+EX.
+
+          errorbar (X, Y1, EY, "~",
+                    X, Y2, LY, UY)
+
+     produces yerrorbar plots with Y1 and Y2 versus X.  Errorbars for Y1 are drawn from Y1-EY to Y1+EY, errorbars for Y2 from Y2-LY to Y2+UY.
+
+          errorbar (X, Y, LX, UX,
+                    LY, UY, "~>")
+
+     produces an xyerrorbar plot of Y versus X in which X errorbars are drawn from X-LX to X+UX and Y errorbars from Y-LY to Y+UY.  See also: semilogxerr, semilogyerr, loglogerr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+This function produces two-dimensional plots with errorbars.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+zlim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 771
+ -- Function File: XL = zlim ()
+ -- Function File:  zlim (XL)
+ -- Function File: M = zlim ('mode')
+ -- Function File:  zlim (M)
+ -- Function File:  zlim (H, ...)
+     Get or set the limits of the z-axis of the current plot.  Called without arguments `zlim' returns the z-axis limits of the current plot.  If passed a two element vector XL, the limits of the z-axis are set to this value.
+
+     The current mode for calculation of the z-axis can be returned with a call `zlim ('mode')', and can be either 'auto' or 'manual'.  The current plotting mode can be set by passing either 'auto' or 'manual' as the argument.
+
+     If passed an handle as the first argument, then operate on this handle rather than the current axes handle.  See also: xlim, ylim, set, get, gca.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Get or set the limits of the z-axis of the current plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+ishghandle
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 102
+ -- Function File:  ishghandle (H)
+     Return true if H is a graphics handle and false otherwise.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Return true if H is a graphics handle and false otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+contour3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1119
+ -- Function File:  contour3 (Z)
+ -- Function File:  contour3 (Z, VN)
+ -- Function File:  contour3 (X, Y, Z)
+ -- Function File:  contour3 (X, Y, Z, VN)
+ -- Function File:  contour3 (..., STYLE)
+ -- Function File:  contour3 (H, ...)
+ -- Function File: [C, H] = contour3 (...)
+     Plot level curves (contour lines) of the matrix Z, using the contour matrix C computed by `contourc' from the same arguments; see the latter for their interpretation.  The contours are plotted at the Z level corresponding to their contour.  The set of contour levels, C, is only returned if requested.  For example:
+
+          contour3 (peaks (19));
+          hold on
+          surface (peaks (19), "facecolor", "none", "EdgeColor", "black")
+          colormap hot
+
+     The style to use for the plot can be defined with a line style STYLE in a similar manner to the line styles used with the `plot' command.  Any markers defined by STYLE are ignored.
+
+     The optional input and output argument H allows an axis handle to be passed to `contour' and the handles to the contour objects to be returned.  See also: contourc, patch, plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 166
+Plot level curves (contour lines) of the matrix Z, using the contour matrix C computed by `contourc' from the same arguments; see the latter for their interpretation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+stairs
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 721
+ -- Function File:  stairs (X, Y)
+ -- Function File:  stairs (..., STYLE)
+ -- Function File:  stairs (..., PROP, VAL)
+ -- Function File:  stairs (H, ...)
+ -- Function File: H = stairs (...)
+     Produce a stairstep plot.  The arguments may be vectors or matrices.
+
+     If only one argument is given, it is taken as a vector of y-values and the x coordinates are taken to be the indices of the elements.
+
+     If two output arguments are specified, the data are generated but not plotted.  For example,
+
+          stairs (x, y);
+
+     and
+
+          [xs, ys] = stairs (x, y);
+          plot (xs, ys);
+
+     are equivalent.  See also: plot, semilogx, semilogy, loglog, polar, mesh, contour, bar, xlabel, ylabel, title.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+Produce a stairstep plot.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+close
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 284
+ -- Command:  close
+ -- Command:  close (N)
+ -- Command:  close all
+ -- Command:  close all hidden
+     Close figure window(s) by calling the function specified by the `"closerequestfcn"' property for each figure.  By default, the function `closereq' is used.  See also: closereq.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Close figure window(s) by calling the function specified by the `"closerequestfcn"' property for each figure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+axes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 162
+ -- Function File:  axes ()
+ -- Function File:  axes (PROPERTY, VALUE, ...)
+ -- Function File:  axes (H)
+     Create an axes object and return a handle to it.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Create an axes object and return a handle to it.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+colorbar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 933
+ -- Function File:  colorbar (S)
+ -- Function File:  colorbar ("peer", H, ...)
+     Adds a colorbar to the current axes.  Valid values for S are
+
+    "EastOutside"
+          Place the colorbar outside the plot to the right.  This is the default.
+
+    "East"
+          Place the colorbar inside the plot to the right.
+
+    "WestOutside"
+          Place the colorbar outside the plot to the left.
+
+    "West"
+          Place the colorbar inside the plot to the left.
+
+    "NorthOutside"
+          Place the colorbar above the plot.
+
+    "North"
+          Place the colorbar at the top of the plot.
+
+    "SouthOutside"
+          Place the colorbar under the plot.
+
+    "South"
+          Place the colorbar at the bottom of the plot.
+
+    "Off", "None"
+          Remove any existing colorbar from the plot.
+
+     If the argument "peer" is given, then the following argument is treated as the axes handle on which to add the colorbar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Adds a colorbar to the current axes.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+shading
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 494
+ -- Function File:  shading (TYPE)
+ -- Function File:  shading (AX, ...)
+     Set the shading of surface or patch graphic objects.  Valid arguments for TYPE are
+
+    `"flat"'
+          Single colored patches with invisible edges.
+
+    `"faceted"'
+          Single colored patches with visible edges.
+
+    `"interp"'
+          Color between patch vertices are interpolated and the patch edges are invisible.
+
+     If AX is given the shading is applied to axis AX instead of the current axis.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Set the shading of surface or patch graphic objects.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+contourf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1326
+ -- Function File: [C, H] = contourf (X, Y, Z, LVL)
+ -- Function File: [C, H] = contourf (X, Y, Z, N)
+ -- Function File: [C, H] = contourf (X, Y, Z)
+ -- Function File: [C, H] = contourf (Z, N)
+ -- Function File: [C, H] = contourf (Z, LVL)
+ -- Function File: [C, H] = contourf (Z)
+ -- Function File: [C, H] = contourf (AX, ...)
+ -- Function File: [C, H] = contourf (..., "PROPERTY", VAL)
+     Compute and plot filled contours of the matrix Z.  Parameters X, Y and N or LVL are optional.
+
+     The return value C is a 2xn matrix containing the contour lines as described in the help to the contourc function.
+
+     The return value H is handle-vector to the patch objects creating the filled contours.
+
+     If X and Y are omitted they are taken as the row/column index of Z.  N is a scalar denoting the number of lines to compute.  Alternatively LVL is a vector containing the contour levels.  If only one value (e.g., lvl0) is wanted, set LVL to [lvl0, lvl0].  If both N or LVL are omitted a default value of 10 contour level is assumed.
+
+     If provided, the filled contours are added to the axes object AX instead of the current axis.
+
+     The following example plots filled contours of the `peaks' function.
+          [x, y, z] = peaks (50);
+          contourf (x, y, z, -7:9)
+     See also: contour, contourc, patch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Compute and plot filled contours of the matrix Z.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+replot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+ -- Function File:  replot ()
+     Refresh the plot window.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+Refresh the plot window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+hold
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 757
+ -- Function File:  hold
+ -- Function File:  hold STATE
+ -- Function File:  hold (HAX, ...)
+     Toggle or set the 'hold' state of the plotting engine which determines whether new graphic objects are added to the plot or replace the existing objects.
+
+    `hold on'
+          Retain plot data and settings so that subsequent plot commands are displayed on a single graph.
+
+    `hold off'
+          Clear plot and restore default graphics settings before each new plot command.  (default).
+
+    `hold'
+          Toggle the current 'hold' state.
+
+     When given the additional argument HAX, the hold state is modified only for the given axis handle.
+
+     To query the current 'hold' state use the `ishold' function.  See also: ishold, cla, newplot, clf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 153
+Toggle or set the 'hold' state of the plotting engine which determines whether new graphic objects are added to the plot or replace the existing objects.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+slice
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1741
+ -- Function File:  slice (X, Y, Z, V, SX, SY, SZ)
+ -- Function File:  slice (X, Y, Z, V, XI, YI, ZI)
+ -- Function File:  slice (V, SX, SY, SZ)
+ -- Function File:  slice (V, XI, YI, ZI)
+ -- Function File: H = slice (...)
+ -- Function File: H = slice (..., METHOD)
+     Plot slices of 3D data/scalar fields.  Each element of the 3-dimensional array V represents a scalar value at a location given by the parameters X, Y, and Z.  The parameters X, X, and Z are either 3-dimensional arrays of the same size as the array V in the "meshgrid" format or vectors.  The parameters XI, etc. respect a similar format to X, etc., and they represent the points at which the array VI is interpolated using interp3.  The vectors SX, SY, and SZ contain points of orthogonal slices of the respective axes.
+
+     If X, Y, Z are omitted, they are assumed to be `x = 1:size (V, 2)', `y = 1:size (V, 1)' and `z = 1:size (V, 3)'.
+
+     METHOD is one of:
+
+    `"nearest"'
+          Return the nearest neighbor.
+
+    `"linear"'
+          Linear interpolation from nearest neighbors.
+
+    `"cubic"'
+          Cubic interpolation from four nearest neighbors (not implemented yet).
+
+    `"spline"'
+          Cubic spline interpolation--smooth first and second derivatives throughout the curve.
+
+     The default method is `"linear"'.  The optional return value H is a vector of handles to the surface graphic objects.
+
+     Examples:
+          [x, y, z] = meshgrid (linspace (-8, 8, 32));
+          v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+          slice (x, y, z, v, [], 0, []);
+          [xi, yi] = meshgrid (linspace (-7, 7));
+          zi = xi + yi;
+          slice (x, y, z, v, xi, yi, zi);
+     See also: interp3, surface, pcolor.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Plot slices of 3D data/scalar fields.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+linkprop
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 620
+ -- Function File: HLINK = linkprop (H, PROP)
+     Links graphics object properties, such that a change in one is propagated to the others.  The properties to link are given as a string of cell string array by PROP and the objects containing these properties by the handle array H.
+
+     An example of the use of linkprops is
+
+          x = 0:0.1:10;
+          subplot (1, 2, 1);
+          h1 = plot (x, sin (x));
+          subplot (1, 2, 2);
+          h2 = plot (x, cos (x));
+          hlink = linkprop ([h1, h2], {"color","linestyle"});
+          set (h1, "color", "green");
+          set (h2, "linestyle", "--");
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+Links graphics object properties, such that a change in one is propagated to the others.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+unpack
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 558
+ -- Function File: FILES = unpack (FILE, DIR)
+ -- Function File: FILES = unpack (FILE, DIR, FILETYPE)
+     Unpack the archive FILE based on its extension to the directory DIR.  If FILE is a cellstr, then all files will be handled individually.  If DIR is not specified, it defaults to the current directory.  It returns a list of FILES unpacked.  If a directory is in the file list, then the FILETYPE to unpack must also be specified.
+
+     The FILES includes the entire path to the output files.  See also: bunzip2, tar, untar, gzip, gunzip, zip, unzip.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Unpack the archive FILE based on its extension to the directory DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+orderfields
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 484
+ -- Function File: [T, P] = orderfields (S1, S2)
+     Return a struct with fields arranged alphabetically or as specified by S2 and a corresponding permutation vector.
+
+     Given one struct, arrange field names in S1 alphabetically.
+
+     Given two structs, arrange field names in S1 as they appear in S2.  The second argument may also specify the order in a permutation vector or a cell array of strings.
+
+     See also: getfield, rmfield, isfield, isstruct, fieldnames, struct.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+Return a struct with fields arranged alphabetically or as specified by S2 and a corresponding permutation vector.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+movefile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 438
+ -- Function File: [STATUS, MSG, MSGID] = movefile (F1, F2)
+     Move the file F1 to the new name F2.  The name F1 may contain globbing patterns.  If F1 expands to multiple file names, F2 must be a directory.
+
+     If successful, STATUS is 1, with MSG and MSGID empty\n\ character strings.  Otherwise, STATUS is 0, MSG contains a\n\ system-dependent error message, and MSGID contains a unique\n\ message identifier.\n\ See also: glob.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Move the file F1 to the new name F2.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+tempname
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 90
+ -- Function File: filename = tempname ()
+     This function is an alias for `tmpnam'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+This function is an alias for `tmpnam'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+unzip
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Function File:  unzip (ZIPFILE, DIR)
+     Unpack the ZIP archive ZIPFILE to the directory DIR.  If DIR is not specified, it defaults to the current directory.  See also: unpack, bunzip2, tar, untar, gzip, gunzip, zip.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Unpack the ZIP archive ZIPFILE to the directory DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+perl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 292
+ -- Function File: [OUTPUT, STATUS] = perl (SCRIPTFILE)
+ -- Function File: [OUTPUT, STATUS] = perl (SCRIPTFILE, ARGUMENT1, ARGUMENT2, ...)
+     Invoke perl script SCRIPTFILE with possibly a list of command line arguments.  Returns output in OUTPUT and status in STATUS.  See also: system.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Invoke perl script SCRIPTFILE with possibly a list of command line arguments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+ispc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+ -- Function File:  ispc ()
+     Return 1 if Octave is running on a Windows system and 0 otherwise.  See also: ismac, isunix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return 1 if Octave is running on a Windows system and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+debug
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1567
+ -- Function File:  debug ()
+     Summary of the debugging commands.  The debugging commands that are available in Octave are
+
+    `keyboard'
+          Force entry into debug mode.
+
+    `dbstop'
+          Add a breakpoint.
+
+    `dbclear'
+          Remove a breakpoint.
+
+    `dbstatus'
+          List all breakpoints.
+
+    `dbcont'
+          Continue execution from the debug prompt.
+
+    `dbstack'
+          Print a backtrace of the execution stack.
+
+    `dbstep'
+          Execute one or more lines and re-enter debug mode
+
+    `dbtype'
+          List the function where execution is currently stopped, enumerating the lines.
+
+    `dbup'
+          The workspace up the execution stack.
+
+    `dbdown'
+          The workspace down the execution stack.
+
+    `dbquit'
+          Quit debugging mode and return to the main prompt.
+
+    `debug_on_error'
+          Flag whether to enter debug mode in case Octave encounters an error.
+
+    `debug_on_warning'
+          Flag whether to enter debug mode in case Octave encounters a warning.
+
+    `debug_on_interrupt'
+          Flag whether to enter debug mode in case Octave encounters an interupt.
+
+
+     when Octave encounters a breakpoint or other reason to enter debug mode, the prompt changes to `"debug>"'.  The workspace of the function where the breakpoint was encountered becomes available and any Octave command that works within that workspace may be executed.
+
+     See also: dbstop, dbclear, dbstatus, dbcont, dbstack, dbstep, dbtype, dbup, dbdown, dbquit, debug_on_error, debug_on_warning, debug_on_interrupt.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Summary of the debugging commands.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+tar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 413
+ -- Function File: ENTRIES = tar (TARFILE, FILES, ROOT)
+     Pack FILES FILES into the TAR archive TARFILE.  The list of files must be a string or a cell array of strings.
+
+     The optional argument ROOT changes the relative path of FILES from the current directory.
+
+     If an output argument is requested the entries in the archive are returned in a cell array.  See also: untar, gzip, gunzip, zip, unzip.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Pack FILES FILES into the TAR archive TARFILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+dir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 864
+ -- Function File:  dir (DIRECTORY)
+ -- Function File: [LIST] = dir (DIRECTORY)
+     Display file listing for directory DIRECTORY.  If a return value is requested, return a structure array with the fields
+
+          name
+          bytes
+          date
+          isdir
+          statinfo
+
+     in which `statinfo' is the structure returned from `stat'.
+
+     If DIRECTORY is not a directory, return information about the named FILENAME.  DIRECTORY may be a list of directories specified either by name or with wildcard characters (like * and ?)  which will be expanded with glob.
+
+     Note that for symbolic links, `dir' returns information about the file that a symbolic link points to instead of the link itself.  However, if the link points to a nonexistent file, `dir' returns information about the link.  See also: ls, stat, lstat, readdir, glob, filesep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Display file listing for directory DIRECTORY.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+license
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1080
+ -- Function File:  license
+     Display the license of Octave.
+
+ -- Function File:  license ("inuse")
+     Display a list of packages currently being used.
+
+ -- Function File: RETVAL = license ("inuse")
+     Return a structure containing the fields `feature' and `user'.
+
+ -- Function File: RETVAL = license ("test", FEATURE)
+     Return 1 if a license exists for the product identified by the string FEATURE and 0 otherwise.  The argument FEATURE is case insensitive and only the first 27 characters are checked.
+
+ -- Function File:  license ("test", FEATURE, TOGGLE)
+     Enable or disable license testing for FEATURE, depending on TOGGLE, which may be one of:
+
+    `"enable"'
+          Future tests for the specified license of FEATURE are conducted as usual.
+
+    `"disable"'
+          Future tests for the specified license of FEATURE return 0.
+
+ -- Function File: RETVAL = license ("checkout", FEATURE)
+     Check out a license for FEATURE, returning 1 on success and 0 on failure.
+
+     This function is provided for compatibility with MATLAB.  See also: ver, version.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Check out a license for FEATURE, returning 1 on success and 0 on failure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+xor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 215
+ -- Mapping Function:  xor (X, Y)
+     Return the `exclusive or' of the entries of X and Y.  For boolean expressions X and Y, `xor (X, Y)' is true if and only if X or Y is true, but not if both X and Y are true.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return the `exclusive or' of the entries of X and Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+menu
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 450
+ -- Function File:  menu (TITLE, OPT1, ...)
+     Print a title string followed by a series of options.  Each option will be printed along with a number.  The return value is the number of the option selected by the user.  This function is useful for interactive programs.  There is no limit to the number of options that may be passed in, but it may be confusing to present more than will fit easily on one screen.  See also: disp, printf, input.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Print a title string followed by a series of options.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+compare_versions
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1140
+ -- Function File:  compare_versions (V1, V2, OPERATOR)
+     Compares to version strings using the given OPERATOR.
+
+     This function assumes that versions V1 and V2 are arbitrarily long strings made of numeric and period characters possibly followed by an arbitrary string (e.g., "1.2.3", "0.3", "0.1.2+", or "1.2.3.4-test1").
+
+     The version is first split into the numeric and the character parts then the parts are padded to be the same length (i.e., "1.1" would be padded to be like "1.1.0" when being compared with "1.1.1", and separately, the character parts of the strings are padded with nulls).
+
+     The operator can be any logical operator from the set
+
+        * "==" equal
+
+        * "<" less than
+
+        * "<=" less than or equal to
+
+        * ">" greater than
+
+        * ">=" greater than or equal to
+
+        * "!=" not equal
+
+        * "~=" not equal
+
+     Note that version "1.1-test2" would compare as greater than "1.1-test10".  Also, since the numeric part is compared first, "a" compares less than "1a" because the second string starts with a numeric part even though double("a") is greater than double("1").
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compares to version strings using the given OPERATOR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+bincoeff
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 505
+ -- Mapping Function:  bincoeff (N, K)
+     Return the binomial coefficient of N and K, defined as
+
+           /   \
+           | n |    n (n-1) (n-2) ... (n-k+1)
+           |   |  = -------------------------
+           | k |               k!
+           \   /
+
+     For example,
+
+          bincoeff (5, 2)
+               => 10
+
+     In most cases, the `nchoosek' function is faster for small scalar integer arguments.  It also warns about loss of precision for big arguments.
+
+     See also: nchoosek.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return the binomial coefficient of N and K, defined as 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+delete
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 258
+ -- Function File:  delete (FILE)
+ -- Function File:  delete (HANDLE)
+     Delete the named file or graphics handle.
+
+     Deleting graphics objects is the proper way to remove features from a plot without clearing the entire figure.  See also: clf, cla.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Delete the named file or graphics handle.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+ans
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 229
+ -- Automatic Variable: ans
+     The most recently computed result that was not explicitly assigned to a variable.  For example, after the expression
+
+          3^2 + 4^2
+
+     is evaluated, the value returned by `ans' is 25.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+The most recently computed result that was not explicitly assigned to a variable.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+list_primes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 209
+ -- Function File:  list_primes (N)
+     List the first N primes.  If N is unspecified, the first 25 primes are listed.
+
+     The algorithm used is from page 218 of the TeXbook.  See also: primes, isprime.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+List the first N primes.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+comma
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+ -- Operator: ,
+     Array index, function argument, or command separator.  See also: semicolon.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Array index, function argument, or command separator.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+mkoctfile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3026
+ -- Function File:  mkoctfile [-options] file ...
+     The `mkoctfile' function compiles source code written in C, C++, or Fortran.  Depending on the options used with `mkoctfile', the compiled code can be called within Octave or can be used as a stand-alone application.
+
+     `mkoctfile' can be called from the shell prompt or from the Octave prompt.
+
+     `mkoctfile' accepts the following options, all of which are optional except for the file name of the code you wish to compile:
+
+    `-I DIR'
+          Add the include directory DIR to compile commands.
+
+    `-D DEF'
+          Add the definition DEF to the compiler call.
+
+    `-l LIB'
+          Add the library LIB to the link command.
+
+    `-L DIR'
+          Add the library directory DIR to the link command.
+
+    `-M'
+    `--depend'
+          Generate dependency files (.d) for C and C++ source files.
+
+    `-c'
+          Compile but do not link.
+
+    `-g'
+          Enable debugging options for compilers.
+
+    `-o FILE'
+    `--output FILE'
+          Output file name.  Default extension is .oct (or .mex if -mex is specified) unless linking a stand-alone executable.
+
+    `-p VAR'
+    `--print VAR'
+          Print the configuration variable VAR.  Recognized variables are:
+
+                  ALL_CFLAGS                FFTW_LIBS
+                  ALL_CXXFLAGS              FLIBS
+                  ALL_FFLAGS                FPICFLAG
+                  ALL_LDFLAGS               INCFLAGS
+                  BLAS_LIBS                 LDFLAGS
+                  CC                        LD_CXX
+                  CFLAGS                    LD_STATIC_FLAG
+                  CPICFLAG                  LFLAGS
+                  CPPFLAGS                  LIBCRUFT
+                  CXX                       LIBOCTAVE
+                  CXXFLAGS                  LIBOCTINTERP
+                  CXXPICFLAG                LIBREADLINE
+                  DEPEND_EXTRA_SED_PATTERN  LIBS
+                  DEPEND_FLAGS              OCTAVE_LIBS
+                  DL_LD                     RDYNAMIC_FLAG
+                  DL_LDFLAGS                RLD_FLAG
+                  F2C                       SED
+                  F2CFLAGS                  XTRA_CFLAGS
+                  F77                       XTRA_CXXFLAGS
+                  FFLAGS
+
+    `--link-stand-alone'
+          Link a stand-alone executable file.
+
+    `--mex'
+          Assume we are creating a MEX file.  Set the default output extension to ".mex".
+
+    `-s'
+    `--strip'
+          Strip the output file.
+
+    `-v'
+    `--verbose'
+          Echo commands as they are executed.
+
+    `file'
+          The file to compile or link.  Recognized file types are
+
+                                 .c    C source
+                                 .cc   C++ source
+                                 .C    C++ source
+                                 .cpp  C++ source
+                                 .f    Fortran source
+                                 .F    Fortran source
+                                 .o    object file
+
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+The `mkoctfile' function compiles source code written in C, C++, or Fortran.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+dump_prefs
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 216
+ -- Function File:  dump_prefs (FILE)
+     Have Octave dump all the current user preference variables to FILE in a format that can be parsed by Octave later.  If FILE is omitted, the listing is printed to stdout.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Have Octave dump all the current user preference variables to FILE in a format that can be parsed by Octave later.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+untar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Function File:  untar (TARFILE, DIR)
+     Unpack the TAR archive TARFILE to the directory DIR.  If DIR is not specified, it defaults to the current directory.  See also: unpack, bunzip2, tar, gzip, gunzip, zip, unzip.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Unpack the TAR archive TARFILE to the directory DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+fullfile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 159
+ -- Function File: FILENAME = fullfile (DIR1, DIR2, ..., FILE)
+     Return a complete filename constructed from the given components.  See also: fileparts.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Return a complete filename constructed from the given components.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+fileattrib
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1167
+ -- Function File: [STATUS, MSG, MSGID] = fileattrib (FILE)
+     Return information about FILE.
+
+     If successful, STATUS is 1, with RESULT containing a structure with the following fields:
+
+    `Name'
+          Full name of FILE.
+
+    `archive'
+          True if FILE is an archive (Windows).
+
+    `system'
+          True if FILE is a system file (Windows).
+
+    `hidden'
+          True if FILE is a hidden file (Windows).
+
+    `directory'
+          True if FILE is a directory.
+
+    `UserRead'
+    `GroupRead'
+    `OtherRead'
+          True if the user (group; other users) has read permission for FILE.
+
+    `UserWrite'
+    `GroupWrite'
+    `OtherWrite'
+          True if the user (group; other users) has write permission for FILE.
+
+    `UserExecute'
+    `GroupExecute'
+    `OtherExecute'
+          True if the user (group; other users) has execute permission for FILE.
+     If an attribute does not apply (i.e., archive on a Unix system) then the field is set to NaN.
+
+     With no input arguments, return information about the current directory.
+
+     If FILE contains globbing characters, return information about all the matching files.  See also: glob.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Return information about FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+setfield
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 455
+ -- Function File: [K1, ..., V1] = setfield (S, K1, V1, ...)
+     Set field members in a structure.
+
+          oo(1,1).f0 = 1;
+          oo = setfield (oo, {1,2}, "fd", {3}, "b", 6);
+          oo(1,2).fd(3).b == 6
+          => ans = 1
+
+     Note that this function could be written
+
+          i1 = {1,2}; i2 = "fd"; i3 = {3}; i4 = "b";
+          oo(i1{:}).(i2)(i3{:}).(i4) == 6;
+     See also: getfield, rmfield, isfield, isstruct, fieldnames, struct.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Set field members in a structure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+what
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 325
+ -- Command:  what
+ -- Command:  what DIR
+ -- Function File: w = what (DIR)
+     List the Octave specific files in a directory.  If the variable DIR is given then check that directory rather than the current directory.  If a return argument is requested, the files found are returned in the structure W.  See also: which.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+List the Octave specific files in a directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+computer
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 657
+ -- Function File: [C, MAXSIZE, ENDIAN] = computer ()
+     Print or return a string of the form CPU-VENDOR-OS that identifies the kind of computer Octave is running on.  If invoked with an output argument, the value is returned instead of printed.  For example,
+
+          computer ()
+               -| i586-pc-linux-gnu
+
+          x = computer ()
+               => x = "i586-pc-linux-gnu"
+
+     If two output arguments are requested, also return the maximum number of elements for an array.
+
+     If three output arguments are requested, also return the byte order of the current system as a character (`"B"' for big-endian or `"L"' for little-endian).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Print or return a string of the form CPU-VENDOR-OS that identifies the kind of computer Octave is running on.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+ls_command
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 233
+ -- Function File: [OLD_CMD = ls_command (CMD)
+     Set or return the shell command used by Octave's `ls' command.  The value of CMD must be a character string.  With no arguments, simply return the previous value.  See also: ls.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Set or return the shell command used by Octave's `ls' command.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+flops
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+ -- Function File:  flops ()
+     This function is provided for MATLAB compatibility, but it doesn't actually do anything.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+This function is provided for MATLAB compatibility, but it doesn't actually do anything.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+copyfile
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 535
+ -- Function File: [STATUS, MSG, MSGID] = copyfile (F1, F2, FORCE)
+     Copy the file F1 to the new name F2.  The name F1 may contain globbing patterns.  If F1 expands to multiple file names, F2 must be a directory.  If FORCE is given and equals the string "f" the copy operation will be forced.
+
+     If successful, STATUS is 1, with MSG and MSGID empty\n\ character strings.  Otherwise, STATUS is 0, MSG contains a\n\ system-dependent error message, and MSGID contains a unique\n\ message identifier.\n\ See also: glob, movefile.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Copy the file F1 to the new name F2.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+zip
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 350
+ -- Function File: ENTRIES = zip (ZIPFILE, FILES)
+ -- Function File: ENTRIES = zip (ZIPFILE, FILES, ROOTDIR)
+     Compress the list of files and/or directories specified in FILES into the archive ZIPFILES in the same directory.  If ROOTDIR is defined the FILES is located relative to ROOTDIR rather than the current directory See also: unzip,tar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+Compress the list of files and/or directories specified in FILES into the archive ZIPFILES in the same directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+tempdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+ -- Function File: DIR = tempdir ()
+     Return the name of the system's directory for temporary files.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Return the name of the system's directory for temporary files.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+intwarning
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1533
+ -- Function File:  intwarning (ACTION)
+ -- Function File:  intwarning (S)
+ -- Function File: S = intwarning (...)
+     Control the state of the warning for integer conversions and math operations.
+
+    "query"
+          The state of the Octave integer conversion and math warnings is queried.  If there is no output argument, then the state is printed.  Otherwise it is returned in a structure with the fields "identifier" and "state".
+
+               intwarning ("query")
+               The state of warning "Octave:int-convert-nan" is "off"
+               The state of warning "Octave:int-convert-non-int-val" is "off"
+               The state of warning "Octave:int-convert-overflow" is "off"
+               The state of warning "Octave:int-math-overflow" is "off"
+
+    "on"
+          Turn integer conversion and math warnings "on".  If there is no output argument, then nothing is printed.  Otherwise the original state of the state of the integer conversion and math warnings is returned in a structure array.
+
+    "off"
+          Turn integer conversion and math warnings "on".  If there is no output argument, then nothing is printed.  Otherwise the original state of the state of the integer conversion and math warnings is returned in a structure array.
+
+     The original state of the integer warnings can be restored by passing the structure array returned by `intwarning' to a later call to `intwarning'.  For example
+
+          s = intwarning ("off");
+          ...
+          intwarning (s);
+     See also: warning.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Control the state of the warning for integer conversions and math operations.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+semicolon
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+ -- Operator: ;
+     Array row or command separator.  See also: comma.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Array row or command separator.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+pack
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+ -- Function File:  pack ()
+     This function is provided for compatibility with MATLAB, but it doesn't actually do anything.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+This function is provided for compatibility with MATLAB, but it doesn't actually do anything.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+version
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+ -- Function File:  version ()
+     Return Octave's version number as a string.  This is also the value of the built-in variable `OCTAVE_VERSION'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Return Octave's version number as a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cast
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 153
+ -- Function File:  cast (VAL, TYPE)
+     Convert VAL to data type TYPE.  See also: int8, uint8, int16, uint16, int32, uint32, int64, uint64, double.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Convert VAL to data type TYPE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+bunzip2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 232
+ -- Function File:  bunzip2 (BZFILE, DIR)
+     Unpack the bzip2 archive BZFILE to the directory DIR.  If DIR is not specified, it defaults to the current directory.  See also: unpack, bzip2, tar, untar, gzip, gunzip, zip, unzip.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Unpack the bzip2 archive BZFILE to the directory DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+bug_report
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 202
+ -- Function File:  bug_report ()
+     Have Octave create a bug report template file, invoke your favorite editor, and submit the report to the bug-octave mailing list when you are finished editing.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 159
+Have Octave create a bug report template file, invoke your favorite editor, and submit the report to the bug-octave mailing list when you are finished editing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+isunix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 131
+ -- Function File:  isunix ()
+     Return 1 if Octave is running on a Unix-like system and 0 otherwise.  See also: ismac, ispc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Return 1 if Octave is running on a Unix-like system and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+getfield
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 461
+ -- Function File: [V1, ...] = getfield (S, KEY, ...)
+     Extract fields from a structure.  For example
+
+          ss(1,2).fd(3).b = 5;
+          getfield (ss, {1,2}, "fd", {3}, "b")
+          => ans = 5
+
+     Note that the function call in the previous example is equivalent to the expression
+
+          i1 = {1,2}; i2 = "fd"; i3 = {3}; i4= "b";
+          ss(i1{:}).(i2)(i3{:}).(i4)
+     See also: setfield, rmfield, isfield, isstruct, fieldnames, struct.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Extract fields from a structure.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+ver
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 788
+ -- Function File:  ver ()
+     Display a header containing the current Octave version number, license string and operating system, followed by the installed package names, versions, and installation directories.
+
+ -- Function File: v = ver ()
+     Return a vector of structures, respecting Octave and each installed package.  The structure includes the following fields.
+
+    `Name'
+          Package name.
+
+    `Version'
+          Version of the package.
+
+    `Revision'
+          Revision of the package.
+
+    `Date'
+          Date respecting the version/revision.
+
+ -- Function File: v = ver (`"Octave"')
+     Return version information for Octave only..
+
+ -- Function File: v = ver (PKG)
+     Return version information for the specified package PKG.  See also: license, version.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Return version information for the specified package PKG.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+news
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+ -- Function File:  news ()
+     Display the current NEWS file for Octave.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Display the current NEWS file for Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+gzip
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 467
+ -- Function File: ENTRIES = gzip (FILES)
+ -- Function File: ENTRIES = gzip (FILES, OUTDIR)
+     Compress the list of files and/or directories specified in FILES.  Each file is compressed separately and a new file with a '.gz' extension is created.  The original files are not touched.  Existing compressed files are silently overwritten.  If OUTDIR is defined the compressed versions of the files are placed in this directory.  See also: gunzip, bzip2, zip, tar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Compress the list of files and/or directories specified in FILES.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+parseparams
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 643
+ -- Function File: [REG, PROP] = parseparams (PARAMS)
+     Return in REG the cell elements of PARAM up to the first string element and in PROP all remaining elements beginning with the first string element.  For example
+
+          [reg, prop] = parseparams ({1, 2, "linewidth", 10})
+          reg =
+          {
+            [1,1] = 1
+            [1,2] = 2
+          }
+          prop =
+          {
+            [1,1] = linewidth
+            [1,2] = 10
+          }
+
+     The parseparams function may be used to separate 'regular' arguments and additional arguments given as property/value pairs of the VARARGIN cell array.  See also: varargin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+Return in REG the cell elements of PARAM up to the first string element and in PROP all remaining elements beginning with the first string element.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+ls
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 470
+ -- Command: ls options
+     List directory contents.  For example,
+
+          ls -l
+               -| total 12
+               -| -rw-r--r--   1 jwe  users  4488 Aug 19 04:02 foo.m
+               -| -rw-r--r--   1 jwe  users  1315 Aug 17 23:14 bar.m
+
+     The `dir' and `ls' commands are implemented by calling your system's directory listing command, so the available options may vary from system to system.  See also: dir, stat, readdir, glob, filesep, ls_command.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+List directory contents.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ismac
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 130
+ -- Function File:  ismac ()
+     Return 1 if Octave is running on a Mac OS X system and 0 otherwise.  See also: ispc, isunix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Return 1 if Octave is running on a Mac OS X system and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+unix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 463
+ -- Function File: [STATUS, TEXT] unix (COMMAND)
+ -- Function File: [STATUS, TEXT] unix (COMMAND, "-echo")
+     Execute a system command if running under a Unix-like operating system, otherwise do nothing.  Return the exit status of the program in STATUS and any output sent to the standard output in TEXT.  If the optional second argument `"-echo"' is given, then also send the output from the command to the standard output.  See also: isunix, ispc, system.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+Execute a system command if running under a Unix-like operating system, otherwise do nothing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+inputname
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+ -- Function File:  inputname (N)
+     Return the text defining N-th input to the function.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return the text defining N-th input to the function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+fileparts
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 168
+ -- Function File: [DIR, NAME, EXT, VER] = fileparts (FILENAME)
+     Return the directory, name, extension, and version components of FILENAME.  See also: fullfile.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Return the directory, name, extension, and version components of FILENAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+substruct
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 153
+ -- Function File:  substruct (TYPE, SUBS, ...)
+     Create a subscript structure for use with `subsref' or `subsasgn'.  See also: subsref, subsasgn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Create a subscript structure for use with `subsref' or `subsasgn'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+info
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+ -- Function File:  info ()
+     Display contact information for the GNU Octave community.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Display contact information for the GNU Octave community.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+bzip2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 449
+ -- Function File: ENTRIES = bzip2 (FILES)
+ -- Function File: ENTRIES = bzip2 (FILES, OUTDIR)
+     Compress the list of files specified in FILES.  Each file is compressed separately and a new file with a '.bz2' extension is created.  The original files are not touched.  Existing compressed files are silently overwritten.If OUTDIR is defined the compressed versions of the files are placed in this directory.  See also: bunzip2, gzip, zip, tar.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Compress the list of files specified in FILES.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+swapbytes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 255
+ -- Function File:  swapbytes (X)
+     Swaps the byte order on values, converting from little endian to big endian and vice versa.  For example
+
+          swapbytes (uint16 (1:4))
+          => [   256   512   768  1024]
+
+     See also: typecast, cast.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 91
+Swaps the byte order on values, converting from little endian to big endian and vice versa.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mexext
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+ -- Function File:  mexext ()
+     Return the filename extension used for MEX files.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Return the filename extension used for MEX files.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+paren
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Operator: (
+ -- Operator: )
+     Array index or function argument delimeter.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Array index or function argument delimeter.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+dos
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 474
+ -- Function File: [STATUS, TEXT] = dos (COMMAND)
+ -- Function File: [STATUS, TEXT] = dos (COMMAND, "-echo")
+     Execute a system command if running under a Windows-like operating system, otherwise do nothing.  Return the exit status of the program in STATUS and any output sent to the standard output in TEXT.  If the optional second argument `"-echo"' is given, then also send the output from the command to the standard output.  See also: unix, isunix, ispc, system.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+Execute a system command if running under a Windows-like operating system, otherwise do nothing.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+run
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 337
+ -- Function File:  run (F)
+ -- Command:  run F
+     Run scripts in the current workspace that are not necessarily on the path.  If F is the script to run, including its path, then `run' change the directory to the directory where F is found.  `run' then executes the script, and returns to the original directory.  See also: system.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Run scripts in the current workspace that are not necessarily on the path.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+texas_lotto
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+ -- Function File:  texas_lotto ()
+     Pick 6 unique numbers between 1 and 50 that are guaranteed to win the Texas Lotto.  See also: rand.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+Pick 6 unique numbers between 1 and 50 that are guaranteed to win the Texas Lotto.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+mex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 196
+ -- Function File:  mex [options] file ...
+     Compile source code written in C, C++, or Fortran, to a MEX file.  This is equivalent to `mkoctfile --mex [options] file'.  See also: mkoctfile.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 65
+Compile source code written in C, C++, or Fortran, to a MEX file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gunzip
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 321
+ -- Function File:  gunzip (GZFILE, DIR)
+     Unpack the gzip archive GZFILE to the directory DIR.  If DIR is not specified, it defaults to the current directory.  If the GZFILE is a directory, all files in the directory will be recursively gunzipped.  See also: unpack, bunzip2, tar, untar, gzip, gunzip, zip, unzip.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Unpack the gzip archive GZFILE to the directory DIR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+namelengthmax
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 423
+ -- Function File:  namelengthmax ()
+     Returns the MATLAB compatible maximum variable name length.  Octave is capable of storing strings up to `2 ^ 31 - 1' in length.  However for MATLAB compatibility all variable, function and structure field names should be shorter than the length supplied by `namelengthmax'.  In particular variables stored to a MATLAB file format will have their names truncated to this length.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Returns the MATLAB compatible maximum variable name length.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+symvar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 325
+ -- Function File:  symvar (S)
+     Identifies the argument names in the function defined by a string.  Common constant names such as `pi', `NaN', `Inf', `eps', `i' or `j' are ignored.  The arguments that are found are returned in a cell array of strings.  If no variables are found then the returned cell array is empty.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Identifies the argument names in the function defined by a string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+edit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4371
+ -- Command: edit NAME
+ -- Command: edit FIELD VALUE
+ -- Command: VALUE = edit get FIELD
+     Edit the named function, or change editor settings.
+
+     If `edit' is called with the name of a file or function as its argument it will be opened in a text editor.
+
+        * If the function NAME is available in a file on your path and that file is modifiable, then it will be edited in place.  If it is a system function, then it will first be copied to the directory `HOME' (see further down) and then edited.  If no file is found, then the m-file variant, ending with ".m", will be considered.  If still no file is found, then variants with a leading "@" and then with both a leading "@" and trailing ".m" will be considered.
+
+        * If NAME is the name of a function defined in the interpreter but not in an m-file, then an m-file will be created in `HOME' to contain that function along with its current definition.
+
+        * If `name.cc' is specified, then it will search for `name.cc' in the path and try to modify it, otherwise it will create a new `.cc' file in `HOME'.  If NAME happens to be an m-file or interpreter defined function, then the text of that function will be inserted into the .cc file as a comment.
+
+        * If NAME.EXT is on your path then it will be edited, otherwise the editor will be started with `HOME/name.ext' as the filename.  If `name.ext' is not modifiable, it will be copied to `HOME' before editing.
+
+          *WARNING!* You may need to clear name before the new definition is available.  If you are editing a .cc file, you will need to mkoctfile `name.cc' before the definition will be available.
+
+     If `edit' is called with FIELD and VALUE variables, the value of the control field FIELD will be VALUE.  If an output argument is requested and the first argument is `get' then `edit' will return the value of the control field FIELD.  If the control field does not exist, edit will return a structure containing all fields and values.  Thus, `edit get all' returns a complete control structure.  The following control fields are used:
+
+    `editor'
+          This is the editor to use to modify the functions.  By default it uses Octave's `EDITOR' built-in function, which comes from `getenv("EDITOR")' and defaults to `emacs'.  Use `%s' In place of the function name.  For example,
+         `[EDITOR, " %s"]'
+               Use the editor which Octave uses for `bug_report'.
+
+         `"xedit %s &"'
+               pop up simple X11 editor in a separate window
+
+         `"gnudoit -q \"(find-file \\\"%s\\\")\""'
+               Send it to current Emacs; must have `(gnuserv-start)' in `.emacs'.
+
+          See also field 'mode', which controls how the editor is run by Octave.
+
+          On Cygwin, you will need to convert the Cygwin path to a Windows path if you are using a native Windows editor.  For example
+               '"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+
+    `home'
+          This is the location of user local m-files.  Be be sure it is in your path.  The default is `~/octave'.
+
+    `author'
+          This is the name to put after the "## Author:" field of new functions.  By default it guesses from the `gecos' field of password database.
+
+    `email'
+          This is the e-mail address to list after the name in the author field.  By default it guesses `<$LOGNAME@$HOSTNAME>', and if `$HOSTNAME' is not defined it uses `uname -n'.  You probably want to override this.  Be sure to use `<user at host>' as your format.
+
+    `license'
+
+         `gpl'
+               GNU General Public License (default).
+
+         `bsd'
+               BSD-style license without advertising clause.
+
+         `pd'
+               Public domain.
+
+         `"text"'
+               Your own default copyright and license.
+
+          Unless you specify `pd', edit will prepend the copyright statement with "Copyright (C) yyyy Function Author".
+
+    `mode'
+          This value determines whether the editor should be started in async mode (editor is started in the background and Octave continues) or sync mode (Octave waits until the editor exits).  Set it to "async" to start the editor in async mode.  The default is "sync" (see also "system").
+
+    `editinplace'
+          Determines whether files should be edited in place, without regard to whether they are modifiable or not.  The default is `false'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Edit the named function, or change editor settings.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+pkg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5938
+ -- Command: pkg COMMAND PKG_NAME
+ -- Command: pkg COMMAND OPTION PKG_NAME
+     This command interacts with the package manager.  Different actions will be taken depending on the value of COMMAND.
+
+    `install'
+          Install named packages.  For example,
+               pkg install image-1.0.0.tar.gz
+          installs the package found in the file `image-1.0.0.tar.gz'.
+
+          The OPTION variable can contain options that affect the manner in which a package is installed.  These options can be one or more of
+
+         `-nodeps'
+               The package manager will disable the dependency checking.  That way it is possible to install a package even if it depends on another package that's not installed on the system.  *Use this option with care.*
+
+         `-noauto'
+               The package manager will not automatically load the installed package when starting Octave, even if the package requests that it is.
+
+         `-auto'
+               The package manager will automatically load the installed package when starting Octave, even if the package requests that it isn't.
+
+         `-local'
+               A local installation is forced, even if the user has system privileges.
+
+         `-global'
+               A global installation is forced, even if the user doesn't normally have system privileges
+
+         `-verbose'
+               The package manager will print the output of all of the commands that are performed.
+
+    `uninstall'
+          Uninstall named packages.  For example,
+               pkg uninstall image
+          removes the `image' package from the system.  If another installed package depends on the `image' package an error will be issued.  The package can be uninstalled anyway by using the `-nodeps' option.
+
+    `load'
+          Add named packages to the path.  After loading a package it is possible to use the functions provided by the package.  For example,
+               pkg load image
+          adds the `image' package to the path.  It is possible to load all installed packages at once with the command
+               pkg load all
+
+    `unload'
+          Removes named packages from the path.  After unloading a package it is no longer possible to use the functions provided by the package.  This command behaves like the `load' command.
+
+    `list'
+          Show a list of the currently installed packages.  By requesting one or two output argument it is possible to get a list of the currently installed packages.  For example,
+               installed_packages = pkg list;
+          returns a cell array containing a structure for each installed package.  The command
+               [USER_PACKAGES, SYSTEM_PACKAGES] = pkg list
+          splits the list of installed packages into those who are installed by the current user, and those installed by the system administrator.
+
+    `describe'
+          Show a short description of the named installed packages, with the option '-verbose' also list functions provided by the package, e.g.:
+                pkg describe -verbose all
+          will describe all installed packages and the functions they provide.  If one output is requested a cell of structure containing the description and list of functions of each package is returned as output rather than printed on screen:
+                desc = pkg ("describe", "secs1d", "image")
+          If any of the requested packages is not installed, pkg returns an error, unless a second output is requested:
+                [ desc, flag] = pkg ("describe", "secs1d", "image")
+          FLAG will take one of the values "Not installed", "Loaded" or "Not loaded" for each of the named packages.
+
+    `prefix'
+          Set the installation prefix directory.  For example,
+               pkg prefix ~/my_octave_packages
+          sets the installation prefix to `~/my_octave_packages'.  Packages will be installed in this directory.
+
+          It is possible to get the current installation prefix by requesting an output argument.  For example,
+               p = pkg prefix
+
+          The location in which to install the architecture dependent files can be independent specified with an addition argument.  For example
+
+               pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
+
+    `local_list'
+          Set the file in which to look for information on the locally installed packages.  Locally installed packages are those that are typically available only to the current user.  For example
+               pkg local_list ~/.octave_packages
+          It is possible to get the current value of local_list with the following
+               pkg local_list
+
+    `global_list'
+          Set the file in which to look for, for information on the globally installed packages.  Globally installed packages are those that are typically available to all users.  For example
+               pkg global_list /usr/share/octave/octave_packages
+          It is possible to get the current value of global_list with the following
+               pkg global_list
+
+    `rebuild'
+          Rebuilds the package database from the installed directories.  This can be used in cases where for some reason the package database is corrupted.  It can also take the `-auto' and `-noauto' options to allow the autoloading state of a package to be changed.  For example
+
+               pkg rebuild -noauto image
+
+          will remove the autoloading status of the image package.
+
+    `build'
+          Builds a binary form of a package or packages.  The binary file produced will itself be an Octave package that can be installed normally with `pkg'.  The form of the command to build a binary package is
+
+               pkg build builddir image-1.0.0.tar.gz ...
+
+          where `builddir' is the name of a directory where the temporary installation will be produced and the binary packages will be found.  The options `-verbose' and `-nodeps' are respected, while the other options are ignored.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+This command interacts with the package manager.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+csvread
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 203
+ -- Function File: X = csvread (FILENAME)
+     Read the matrix X from a file.
+
+     This function is equivalent to
+          dlmread (FILENAME, "," , ...)
+
+     See also: dlmread, dlmwrite, csvwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Read the matrix X from a file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+beep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+ -- Function File:  beep ()
+     Produce a beep from the speaker (or visual bell).  See also: puts, fputs, printf, fprintf.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Produce a beep from the speaker (or visual bell).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+dlmwrite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1504
+ -- Function File:  dlmwrite (FILE, A)
+ -- Function File:  dlmwrite (FILE, A, DELIM, R, C)
+ -- Function File:  dlmwrite (FILE, A, KEY, VAL ...)
+ -- Function File:  dlmwrite (FILE, A, "-append", ...)
+     Write the matrix A to the named file using delimiters.
+
+     The parameter DELIM specifies the delimiter to use to separate values on a row.
+
+     The value of R specifies the number of delimiter-only lines to add to the start of the file.
+
+     The value of C specifies the number of delimiters to prepend to each line of data.
+
+     If the argument `"-append"' is given, append to the end of the FILE.
+
+     In addition, the following keyword value pairs may appear at the end of the argument list:
+    `"append"'
+          Either `"on"' or `"off"'.  See `"-append"' above.
+
+    `"delimiter"'
+          See DELIM above.
+
+    `"newline"'
+          The character(s) to use to separate each row.  Three special cases exist for this option.  `"unix"' is changed into '\n', `"pc"' is changed into '\r\n', and `"mac"' is changed into '\r'.  Other values for this option are kept as is.
+
+    `"roffset"'
+          See R above.
+
+    `"coffset"'
+          See C above.
+
+    `"precision"'
+          The precision to use when writing the file.  It can either be a format string (as used by fprintf) or a number of significant digits.
+
+          dlmwrite ("file.csv", reshape (1:16, 4, 4));
+
+          dlmwrite ("file.tex", a, "delimiter", "&", "newline", "\\n")
+
+     See also: dlmread, csvread, csvwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Write the matrix A to the named file using delimiters.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+csvwrite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 208
+ -- Function File: X = csvwrite (FILENAME, X)
+     Write the matrix X to a file.
+
+     This function is equivalent to
+          dlmwrite (FILENAME, X, ",", ...)
+
+     See also: dlmread, dlmwrite, csvread.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 29
+Write the matrix X to a file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+magic
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 145
+ -- Function File:  magic (N)
+     Create an N-by-N magic square.  Note that `magic (2)' is undefined since there is no 2-by-2 magic square.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Create an N-by-N magic square.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+hankel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 571
+ -- Function File:  hankel (C, R)
+     Return the Hankel matrix constructed given the first column C, and (optionally) the last row R.  If the last element of C is not the same as the first element of R, the last element of C is used.  If the second argument is omitted, it is assumed to be a vector of zeros with the same size as C.
+
+     A Hankel matrix formed from an m-vector C, and an n-vector R, has the elements
+
+          H(i,j) = c(i+j-1),  i+j-1 <= m;
+          H(i,j) = r(i+j-m),  otherwise
+     See also: vander, sylvester_matrix, hilb, invhilb, toeplitz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Return the Hankel matrix constructed given the first column C, and (optionally) the last row R.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+hilb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 233
+ -- Function File:  hilb (N)
+     Return the Hilbert matrix of order N.  The i, j element of a Hilbert matrix is defined as
+
+          H (i, j) = 1 / (i + j - 1)
+     See also: hankel, vander, sylvester_matrix, invhilb, toeplitz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return the Hilbert matrix of order N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+pascal
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 646
+ -- Function File:  pascal (N, T)
+     Return the Pascal matrix of order N if `T = 0'.  T defaults to 0. Return lower triangular Cholesky factor of the Pascal matrix if `T = 1'.  This matrix is its own inverse, that is `pascal (N, 1) ^ 2 == eye (N)'.  If `T = -1', return its absolute value.  This is the standard pascal triangle as a lower-triangular matrix.  If `T = 2', return a transposed and permuted version of `pascal (N, 1)', which is the cube-root of the identity matrix.  That is `pascal (N, 2) ^ 3 == eye (N)'.
+
+     See also: hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz           hadamard, wilkinson, compan, rosser.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Return the Pascal matrix of order N if `T = 0'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+vander
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 569
+ -- Function File:  vander (C, N)
+     Return the Vandermonde matrix whose next to last column is C.  If N is specified, it determines the number of columns; otherwise, N is taken to be equal to the length of C.
+
+     A Vandermonde matrix has the form:
+
+          c(1)^(n-1) ... c(1)^2  c(1)  1
+          c(2)^(n-1) ... c(2)^2  c(2)  1
+              .     .      .      .    .
+              .       .    .      .    .
+              .         .  .      .    .
+          c(n)^(n-1) ... c(n)^2  c(n)  1
+     See also: hankel, sylvester_matrix, hilb, invhilb, toeplitz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Return the Vandermonde matrix whose next to last column is C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+wilkinson
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Function File:  wilkinson (N)
+     Return the Wilkinson matrix of order N.
+
+     See also: hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz           hadamard, rosser, compan, pascal.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Return the Wilkinson matrix of order N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 16
+sylvester_matrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+ -- Function File:  sylvester_matrix (K)
+     Return the Sylvester matrix of order n = 2^k.  See also: hankel, vander, hilb, invhilb, toeplitz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Return the Sylvester matrix of order n = 2^k.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+invhilb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1020
+ -- Function File:  invhilb (N)
+     Return the inverse of a Hilbert matrix of order N.  This can be computed exactly using
+
+                      (i+j)         /n+i-1\  /n+j-1\   /i+j-2\ 2
+           A(i,j) = -1      (i+j-1)(       )(       ) (       )
+                                    \ n-j /  \ n-i /   \ i-2 /
+
+                  = p(i) p(j) / (i+j-1)
+     where
+                       k  /k+n-1\   /n\
+              p(k) = -1  (       ) (   )
+                          \ k-1 /   \k/
+
+     The validity of this formula can easily be checked by expanding the binomial coefficients in both formulas as factorials.  It can be derived more directly via the theory of Cauchy matrices: see J. W. Demmel, Applied Numerical Linear Algebra, page 92.
+
+     Compare this with the numerical calculation of `inverse (hilb (n))', which suffers from the ill-conditioning of the Hilbert matrix, and the finite precision of your computer's floating point arithmetic.  See also: hankel, vander, sylvester_matrix, hilb, toeplitz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Return the inverse of a Hilbert matrix of order N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+hadamard
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 602
+ -- Function File:  hadamard (N)
+     Construct a Hadamard matrix HN of size N-by-N.  The size N must be of the form `2 ^ K * P' in which P is one of 1, 12, 20 or 28.  The returned matrix is normalized, meaning `Hn(:,1) == 1' and `H(1,:) == 1'.
+
+     Some of the properties of Hadamard matrices are:
+
+        * `kron (HM, HN)' is a Hadamard matrix of size M-by-N.
+
+        * `Hn * Hn' == N * eye (N)'.
+
+        * The rows of HN are orthogonal.
+
+        * `det (A) <= abs(det (HN))' for all A with `abs (A (I, J)) <= 1'.
+
+        * Multiply any row or column by -1 and still have a Hadamard matrix.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Construct a Hadamard matrix HN of size N-by-N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+rosser
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 253
+ -- Function File:  rosser ()
+     Returns the Rosser matrix.  This is a difficult test case used to test eigenvalue algorithms.
+
+     See also: hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz           hadamard, wilkinson, compan, pascal.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Returns the Rosser matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+toeplitz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 719
+ -- Function File:  toeplitz (C, R)
+     Return the Toeplitz matrix constructed given the first column C, and (optionally) the first row R.  If the first element of C is not the same as the first element of R, the first element of C is used.  If the second argument is omitted, the first row is taken to be the same as the first column.
+
+     A square Toeplitz matrix has the form:
+
+          c(0)  r(1)   r(2)  ...  r(n)
+          c(1)  c(0)   r(1)  ... r(n-1)
+          c(2)  c(1)   c(0)  ... r(n-2)
+           .     ,      ,   .      .
+           .     ,      ,     .    .
+           .     ,      ,       .  .
+          c(n) c(n-1) c(n-2) ...  c(0)
+     See also: hankel, vander, sylvester_matrix, hilb, invhilb.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+Return the Toeplitz matrix constructed given the first column C, and (optionally) the first row R.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+logm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 211
+ -- Function File:  logm (A)
+     Compute the matrix logarithm of the square matrix A.  Note that this is currently implemented in terms of an eigenvalue expansion and needs to be improved to be more robust.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Compute the matrix logarithm of the square matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+commutation_matrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 375
+ -- Function File:  commutation_matrix (M, N)
+     Return the commutation matrix  K(m,n)  which is the unique M*N by M*N  matrix such that K(m,n) * vec(A) = vec(A')  for all m by n  matrices A.
+
+     If only one argument M is given, K(m,m)  is returned.
+
+     See Magnus and Neudecker (1988), Matrix differential calculus with applications in statistics and econometrics.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 137
+Return the commutation matrix K(m,n) which is the unique M*N by M*N matrix such that K(m,n) * vec(A) = vec(A') for all m by n matrices A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+expm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 842
+ -- Function File:  expm (A)
+     Return the exponential of a matrix, defined as the infinite Taylor series
+
+          expm(a) = I + a + a^2/2! + a^3/3! + ...
+
+     The Taylor series is _not_ the way to compute the matrix exponential; see Moler and Van Loan, `Nineteen Dubious Ways to Compute the Exponential of a Matrix', SIAM Review, 1978.  This routine uses Ward's diagonal Pade' approximation method with three step preconditioning (SIAM Journal on Numerical Analysis, 1977).  Diagonal Pade'  approximations are rational polynomials of matrices
+
+               -1
+          D (a)   N (a)
+
+     whose Taylor series matches the first `2q+1' terms of the Taylor series above; direct evaluation of the Taylor series (with the same preconditioning steps) may be desirable in lieu of the Pade' approximation when `Dq(a)' is ill-conditioned.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Return the exponential of a matrix, defined as the infinite Taylor series 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+dot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 266
+ -- Function File:  dot (X, Y, DIM)
+     Computes the dot product of two vectors.  If X and Y are matrices, calculate the dot-product along the first non-singleton dimension.  If the optional argument DIM is given, calculate the dot-product along this dimension.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Computes the dot product of two vectors.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+cross
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 436
+ -- Function File:  cross (X, Y)
+ -- Function File:  cross (X, Y, DIM)
+     Compute the vector cross product of two 3-dimensional vectors X and Y.
+
+          cross ([1,1,0], [0,1,1])
+               => [ 1; -1; 1 ]
+
+     If X and Y are matrices, the cross product is applied along the first dimension with 3 elements.  The optional argument DIM forces the cross product to be calculated along the specified dimension.  See also: dot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Compute the vector cross product of two 3-dimensional vectors X and Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cond
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 367
+ -- Function File:  cond (A,P)
+     Compute the P-norm condition number of a matrix.  `cond (A)' is defined as `norm (A, P) * norm (inv (A), P)'.  By default `P=2' is used which implies a (relatively slow) singular value decomposition.  Other possible selections are `P= 1, Inf, inf, 'Inf', 'fro'' which are generally faster.  See also: condest, rcond, norm, svd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Compute the P-norm condition number of a matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+planerot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 180
+ -- Function File: [G, Y] = planerot (X)
+     Given a two-element column vector, returns the 2 by 2 orthogonal matrix G such that `Y = G * X' and `Y(2) = 0'.  See also: givens.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Given a two-element column vector, returns the 2 by 2 orthogonal matrix G such that `Y = G * X' and `Y(2) = 0'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+duplication_matrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 319
+ -- Function File:  duplication_matrix (N)
+     Return the duplication matrix Dn  which is the unique n^2 by n*(n+1)/2  matrix such that Dn vech (A) = vec (A)  for all symmetric n by n  matrices A.
+
+     See Magnus and Neudecker (1988), Matrix differential calculus with applications in statistics and econometrics.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 145
+Return the duplication matrix Dn which is the unique n^2 by n*(n+1)/2 matrix such that Dn vech (A) = vec (A) for all symmetric n by n matrices A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+onenormest
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1270
+ -- Function File: [EST, V, W, ITER] = onenormest (A, T)
+ -- Function File: [EST, V, W, ITER] = onenormest (APPLY, APPLY_T, N, T)
+     Apply Higham and Tisseur's randomized block 1-norm estimator to matrix A using T test vectors.  If T exceeds 5, then only 5 test vectors are used.
+
+     If the matrix is not explicit, e.g., when estimating the norm of `inv (A)' given an LU factorization, `onenormest' applies A and its conjugate transpose through a pair of functions APPLY and APPLY_T, respectively, to a dense matrix of size N by T.  The implicit version requires an explicit dimension N.
+
+     Returns the norm estimate EST, two vectors V and W related by norm `(W, 1) = EST * norm (V, 1)', and the number of iterations ITER.  The number of iterations is limited to 10 and is at least 2.
+
+     References:
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm for Matrix 1-Norm Estimation, with an Application to 1-Norm Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.  `http://dx.doi.org/10.1137/S0895479899356080'
+
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm for Matrix 1-Norm Estimation, with an Application to 1-Norm Pseudospectra." `http://citeseer.ist.psu.edu/223007.html'
+
+     See also: condest, norm, cond.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+Apply Higham and Tisseur's randomized block 1-norm estimator to matrix A using T test vectors.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+housh
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 593
+ -- Function File: [HOUSV, BETA, ZER] = housh (X, J, Z)
+     Compute Householder reflection vector HOUSV to reflect X to be the j-th column of identity, i.e.,
+
+          (I - beta*housv*housv')x =  norm(x)*e(j) if x(1) < 0,
+          (I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0
+
+     Inputs
+
+    X
+          vector
+
+    J
+          index into vector
+
+    Z
+          threshold for zero  (usually should be the number 0)
+
+     Outputs (see Golub and Van Loan):
+
+    BETA
+          If beta = 0, then no reflection need be applied (zer set to 0)
+
+    HOUSV
+          householder vector
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 94
+Compute Householder reflection vector HOUSV to reflect X to be the j-th column of identity, i.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+rref
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 299
+ -- Function File: [R, K] = rref (A, TOL)
+     Returns the reduced row echelon form of A.  TOL defaults to `eps * max (size (A)) * norm (A, inf)'.
+
+     Called with two return arguments, K returns the vector of "bound variables", which are those columns on which elimination has been performed.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Returns the reduced row echelon form of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+krylov
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1133
+ -- Function File: [U, H, NU] = krylov (A, V, K, EPS1, PFLG)
+     Construct an orthogonal basis U of block Krylov subspace
+
+          [v a*v a^2*v ... a^(k+1)*v]
+
+     Using Householder reflections to guard against loss of orthogonality.
+
+     If V is a vector, then H contains the Hessenberg matrix such that `a*u == u*h+rk*ek'', in which `rk = a*u(:,k)-u*h(:,k)', and `ek'' is the vector `[0, 0, ..., 1]' of length `k'.  Otherwise, H is meaningless.
+
+     If V is a vector and K is greater than `length(A)-1', then H contains the Hessenberg matrix such that `a*u == u*h'.
+
+     The value of NU is the dimension of the span of the krylov subspace (based on EPS1).
+
+     If B is a vector and K is greater than M-1, then H contains the Hessenberg decomposition of A.
+
+     The optional parameter EPS1 is the threshold for zero.  The default value is 1e-12.
+
+     If the optional parameter PFLG is nonzero, row pivoting is used to improve numerical behavior.  The default value is 0.
+
+     Reference: Hodel and Misra, "Partial Pivoting in the Computation of Krylov Subspaces", to be submitted to Linear Algebra and its Applications
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 57
+Construct an orthogonal basis U of block Krylov subspace 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+qzhess
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 720
+ -- Function File: [AA, BB, Q, Z] = qzhess (A, B)
+     Compute the Hessenberg-triangular decomposition of the matrix pencil `(A, B)', returning `AA = Q * A * Z', `BB = Q * B * Z', with Q and Z orthogonal.  For example,
+
+          [aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
+               => aa = [ -3.02244, -4.41741;  0.92998,  0.69749 ]
+               => bb = [ -8.60233, -9.99730;  0.00000, -0.23250 ]
+               =>  q = [ -0.58124, -0.81373; -0.81373,  0.58124 ]
+               =>  z = [ 1, 0; 0, 1 ]
+
+     The Hessenberg-triangular decomposition is the first step in Moler and Stewart's QZ decomposition algorithm.
+
+     Algorithm taken from Golub and Van Loan, `Matrix Computations, 2nd edition'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 149
+Compute the Hessenberg-triangular decomposition of the matrix pencil `(A, B)', returning `AA = Q * A * Z', `BB = Q * B * Z', with Q and Z orthogonal.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+subspace
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 151
+ -- Function File: ANGLE = subspace (A, B)
+     Determine the largest principal angle between two subspaces spanned by columns of matrices A and B.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Determine the largest principal angle between two subspaces spanned by columns of matrices A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+vech
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 181
+ -- Function File:  vech (X)
+     Return the vector obtained by eliminating all supradiagonal elements of the square matrix X and stacking the result one column above the other.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 143
+Return the vector obtained by eliminating all supradiagonal elements of the square matrix X and stacking the result one column above the other.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+krylovb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+ -- Function File: [U, UCOLS] = krylovb (A, V, K, EPS1, PFLG)
+     See `krylov'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+See `krylov'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+condest
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1554
+ -- Function File: [EST, V] = condest (A, T)
+ -- Function File: [EST, V] = condest (A, SOLVE, SOLVE_T, T)
+ -- Function File: [EST, V] = condest (APPLY, APPLY_T, SOLVE, SOLVE_T, N, T)
+     Estimate the 1-norm condition number of a matrix A using T test vectors using a randomized 1-norm estimator.  If T exceeds 5, then only 5 test vectors are used.
+
+     If the matrix is not explicit, e.g., when estimating the condition number of A given an LU factorization, `condest' uses the following functions:
+
+    APPLY
+          `A*x' for a matrix `x' of size N by T.
+
+    APPLY_T
+          `A'*x' for a matrix `x' of size N by T.
+
+    SOLVE
+          `A \ b' for a matrix `b' of size N by T.
+
+    SOLVE_T
+          `A' \ b' for a matrix `b' of size N by T.
+
+     The implicit version requires an explicit dimension N.
+
+     `condest' uses a randomized algorithm to approximate the 1-norms.
+
+     `condest' returns the 1-norm condition estimate EST and a vector V satisfying `norm (A*v, 1) == norm (A, 1) * norm (V, 1) / EST'.  When EST is large, V is an approximate null vector.
+
+     References:
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm for Matrix 1-Norm Estimation, with an Application to 1-Norm Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.  `http://dx.doi.org/10.1137/S0895479899356080'
+
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm for Matrix 1-Norm Estimation, with an Application to 1-Norm Pseudospectra." `http://citeseer.ist.psu.edu/223007.html'
+
+     See also: cond, norm, onenormest.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Estimate the 1-norm condition number of a matrix A using T test vectors using a randomized 1-norm estimator.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+rank
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 410
+ -- Function File:  rank (A, TOL)
+     Compute the rank of A, using the singular value decomposition.  The rank is taken to be the number of singular values of A that are greater than the specified tolerance TOL.  If the second argument is omitted, it is taken to be
+
+          tol = max (size (A)) * sigma(1) * eps;
+
+     where `eps' is machine precision and `sigma(1)' is the largest singular value of A.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Compute the rank of A, using the singular value decomposition.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+trace
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+ -- Function File:  trace (A)
+     Compute the trace of A, `sum (diag (A))'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 41
+Compute the trace of A, `sum (diag (A))'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+null
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 297
+ -- Function File:  null (A, TOL)
+     Return an orthonormal basis of the null space of A.
+
+     The dimension of the null space is taken as the number of singular values of A not greater than TOL.  If the argument TOL is missing, it is computed as
+
+          max (size (A)) * max (svd (A)) * eps
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Return an orthonormal basis of the null space of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+orth
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 295
+ -- Function File:  orth (A, TOL)
+     Return an orthonormal basis of the range space of A.
+
+     The dimension of the range space is taken as the number of singular values of A greater than TOL.  If the argument TOL is missing, it is computed as
+
+          max (size (A)) * max (svd (A)) * eps
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return an orthonormal basis of the range space of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+vec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+ -- Function File:  vec (X)
+     Return the vector obtained by stacking the columns of the matrix X one above the other.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 87
+Return the vector obtained by stacking the columns of the matrix X one above the other.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+findstr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 523
+ -- Function File:  findstr (S, T, OVERLAP)
+     Return the vector of all positions in the longer of the two strings S and T where an occurrence of the shorter of the two starts.  If the optional argument OVERLAP is nonzero, the returned vector can include overlapping positions (this is the default).  For example,
+
+          findstr ("ababab", "a")
+               => [1, 3, 5]
+          findstr ("abababa", "aba", 0)
+               => [1, 5]
+     See also: strfind, strmatch, strcmp, strncmp, strcmpi, strncmpi, find.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+Return the vector of all positions in the longer of the two strings S and T where an occurrence of the shorter of the two starts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strtrunc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 275
+ -- Function File:  strtrunc (S, N)
+     Truncate the character string S to length N.  If S is a char matrix, then the number of columns is adjusted.
+
+     If S is a cell array of strings, then the operation is performed on its members and the new cell array is returned.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Truncate the character string S to length N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+isstrprop
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1385
+ -- Function File:  isstrprop (STR, PRED)
+     Test character string properties.  For example,
+
+          isstrprop ("abc123", "alpha")
+          => [1, 1, 1, 0, 0, 0]
+
+     If STR is a cell array, `isstrpop' is applied recursively to each element of the cell array.
+
+     Numeric arrays are converted to character strings.
+
+     The second argument PRED may be one of
+
+    `"alpha"'
+          True for characters that are alphabetic
+
+    `"alnum"'
+    `"alphanum"'
+          True for characters that are alphabetic or digits.
+
+    `"ascii"'
+          True for characters that are in the range of ASCII encoding.
+
+    `"cntrl"'
+          True for control characters.
+
+    `"digit"'
+          True for decimal digits.
+
+    `"graph"'
+    `"graphic"'
+          True for printing characters except space.
+
+    `"lower"'
+          True for lower-case letters.
+
+    `"print"'
+          True for printing characters including space.
+
+    `"punct"'
+          True for printing characters except space or letter or digit.
+
+    `"space"'
+    `"wspace"'
+          True for whitespace characters (space, formfeed, newline, carriage return, tab, vertical tab).
+
+    `"upper"'
+          True for upper-case letters.
+
+    `"xdigit"'
+          True for hexadecimal digits.
+
+     See also: isalnum, isalpha, isascii, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Test character string properties.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+bin2dec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 372
+ -- Function File:  bin2dec (S)
+     Return the decimal number corresponding to the binary number stored in the string S.  For example,
+
+          bin2dec ("1110")
+               => 14
+
+     If S is a string matrix, returns a column vector of converted numbers, one per row of S.  Invalid rows evaluate to NaN.  See also: dec2hex, base2dec, dec2base, hex2dec, dec2bin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Return the decimal number corresponding to the binary number stored in the string S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+strcmpi
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 705
+ -- Function File:  strcmpi (S1, S2)
+     Ignoring case, return 1 if the character strings (or character arrays) S1 and S2 are the same, and 0 otherwise.
+
+     If either S1 or S2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.
+
+     *Caution:* For compatibility with MATLAB, Octave's strcmpi function returns 1 if the character strings are equal, and 0 otherwise.  This is just the opposite of the corresponding C library function.  See also: strcmp, strncmp, strncmpi.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Ignoring case, return 1 if the character strings (or character arrays) S1 and S2 are the same, and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isletter
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+ -- Function File:  isletter (S)
+     Returns true if S is a letter, false otherwise.  See also: isalpha.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Returns true if S is a letter, false otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strsplit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 320
+ -- Function File: [S] = strsplit (P, SEP, STRIP_EMPTY)
+     Split a single string using one or more delimiters and return a cell array of strings.  Consecutive delimiters and delimiters at boundaries result in empty strings, unless STRIP_EMPTY is true.  The default value of STRIP_EMPTY is false.  See also: strtok.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Split a single string using one or more delimiters and return a cell array of strings.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cstrcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 417
+ -- Function File:  cstrcat (S1, S2, ...)
+     Return a string containing all the arguments concatenated horizontally.  Trailing white space is preserved.  For example,
+
+          cstrcat ("ab   ", "cd")
+               => "ab   cd"
+
+          s = [ "ab"; "cde" ];
+          cstrcat (s, s, s)
+               => ans =
+                  "ab ab ab "
+                  "cdecdecde"
+     See also: strcat, char, strvcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return a string containing all the arguments concatenated horizontally.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+mat2str
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1032
+ -- Function File: S = mat2str (X, N)
+ -- Function File: S = mat2str (..., 'class')
+     Format real/complex numerical matrices as strings.  This function returns values that are suitable for the use of the `eval' function.
+
+     The precision of the values is given by N.  If N is a scalar then both real and imaginary parts of the matrix are printed to the same precision.  Otherwise `N (1)' defines the precision of the real part and `N (2)' defines the precision of the imaginary part.  The default for N is 17.
+
+     If the argument 'class' is given, then the class of X is included in the string in such a way that the eval will result in the construction of a matrix of the same class.
+
+          mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
+               => "[-0.3333+0.14i;0.3333-0.14i]"
+
+          mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
+               => "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]"
+
+          mat2str (int16([1 -1]), 'class')
+               => "int16([1,-1])"
+
+     See also: sprintf, num2str, int2str.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Format real/complex numerical matrices as strings.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+base2dec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 646
+ -- Function File:  base2dec (S, B)
+     Convert S from a string of digits of base B into an integer.
+
+          base2dec ("11120", 3)
+               => 123
+
+     If S is a matrix, returns a column vector with one value per row of S.  If a row contains invalid symbols then the corresponding value will be NaN.  Rows are right-justified before converting so that trailing spaces are ignored.
+
+     If B is a string, the characters of B are used as the symbols for the digits of S.  Space (' ') may not be used as a symbol.
+
+          base2dec ("yyyzx", "xyz")
+               => 123
+     See also: dec2base, dec2bin, bin2dec, hex2dec, dec2hex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Convert S from a string of digits of base B into an integer.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strmatch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 700
+ -- Function File:  strmatch (S, A, "exact")
+     Return indices of entries of A that match the string S.  The second argument A may be a string matrix or a cell array of strings.  If the third argument `"exact"' is not given, then S only needs to match A up to the length of S.  Nul characters match blanks.  Results are returned as a column vector.  For example:
+
+          strmatch ("apple", "apple juice")
+               => 1
+
+          strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
+               => [1; 2]
+
+          strmatch ("apple", {"apple pie"; "apple juice"; "tomato"})
+               => [1; 2]
+     See also: strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return indices of entries of A that match the string S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strncmpi
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 731
+ -- Function File:  strncmpi (S1, S2, N)
+     Ignoring case, return 1 if the first N characters of character strings (or character arrays) S1 and S2 are the same, and 0 otherwise.
+
+     If either S1 or S2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.
+
+     *Caution:* For compatibility with MATLAB, Octave's strncmpi function returns 1 if the character strings are equal, and 0 otherwise.  This is just the opposite of the corresponding C library function.  See also: strcmp, strcmpi, strncmp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+Ignoring case, return 1 if the first N characters of character strings (or character arrays) S1 and S2 are the same, and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+strfind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 868
+ -- Function File: IDX = strfind (STR, PATTERN)
+ -- Function File: IDX = strfind (CELLSTR, PATTERN)
+     Search for PATTERN in the string STR and return the starting index of every such occurrence in the vector IDX.  If there is no such occurrence, or if PATTERN is longer than STR, then IDX is the empty array `[]'.
+
+     If the cell array of strings CELLSTR is specified instead of the string STR, then IDX is a cell array of vectors, as specified above.  Examples:
+
+          strfind ("abababa", "aba")
+               => [1, 3, 5]
+
+          strfind ({"abababa", "bebebe", "ab"}, "aba")
+               => ans =
+                  {
+                    [1,1] =
+
+                       1   3   5
+
+                    [1,2] = [](1x0)
+                    [1,3] = [](1x0)
+                  }
+     See also: findstr, strmatch, strcmp, strncmp, strcmpi, strncmpi, find.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+Search for PATTERN in the string STR and return the starting index of every such occurrence in the vector IDX.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+validatestring
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 855
+ -- Function File: VALIDSTR = validatestring (STR, STRARRAY)
+ -- Function File: VALIDSTR = validatestring (STR, STRARRAY, FUNCNAME)
+ -- Function File: VALIDSTR = validatestring (STR, STRARRAY, FUNCNAME, VARNAME)
+ -- Function File: VALIDSTR = validatestring (..., POSITION)
+     Verify that STR is a string or substring of an element of STRARRAY.
+
+     STR is a character string to be tested, and STRARRAY is a cellstr of valid values.  VALIDSTR will be the validated form of STR where validation is defined as STR being a member or substring of VALIDSTR.  If STR is a substring of VALIDSTR and there are multiple matches, the shortest match will be returned if all matches are substrings of each other, and an error will be raised if the matches are not substrings of each other.
+
+     All comparisons are case insensitive.  See also: strcmp, strcmpi.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Verify that STR is a string or substring of an element of STRARRAY.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+strtok
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 567
+ -- Function File: [TOK, REM] = strtok (STR, DELIM)
+     Find all characters up to but not including the first character which is in the string delim.  If REM is requested, it contains the remainder of the string, starting at the first delimiter.  Leading delimiters are ignored.  If DELIM is not specified, space is assumed.  For example:
+
+          strtok ("this is the life")
+               => "this"
+
+          [tok, rem] = strtok ("14*27+31", "+-*/")
+               =>
+                  tok = 14
+                  rem = *27+31
+     See also: index, strsplit.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+Find all characters up to but not including the first character which is in the string delim.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+strrep
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 304
+ -- Function File:  strrep (S, X, Y)
+     Replace all occurrences of the substring X of the string S with the string Y and return the result.  For example,
+
+          strrep ("This is a test string", "is", "&%$")
+               => "Th&%$ &%$ a test string"
+     See also: regexprep, strfind, findstr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+Replace all occurrences of the substring X of the string S with the string Y and return the result.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+dec2base
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 663
+ -- Function File:  dec2base (N, B, LEN)
+     Return a string of symbols in base B corresponding to the non-negative integer N.
+
+          dec2base (123, 3)
+               => "11120"
+
+     If N is a vector, return a string matrix with one row per value, padded with leading zeros to the width of the largest value.
+
+     If B is a string then the characters of B are used as the symbols for the digits of N.  Space (' ') may not be used as a symbol.
+
+          dec2base (123, "aei")
+               => "eeeia"
+
+     The optional third argument, LEN, specifies the minimum number of digits in the result.  See also: base2dec, dec2bin, bin2dec, hex2dec, dec2hex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+Return a string of symbols in base B corresponding to the non-negative integer N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dec2hex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 466
+ -- Function File:  dec2hex (N, LEN)
+     Return the hexadecimal string corresponding to the non-negative integer N.  For example,
+
+          dec2hex (2748)
+               => "ABC"
+
+     If N is a vector, returns a string matrix, one row per value, padded with leading zeros to the width of the largest value.
+
+     The optional second argument, LEN, specifies the minimum number of digits in the result.  See also: hex2dec, dec2base, base2dec, bin2dec, dec2bin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Return the hexadecimal string corresponding to the non-negative integer N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+str2double
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1962
+ -- Function File: [NUM, STATUS, STRARRAY] = str2double (STR, CDELIM, RDELIM, DDELIM)
+     Convert strings into numeric values.
+
+     `str2double' can replace `str2num', but avoids the use of `eval' on unknown data.
+
+     STR can be the form `[+-]d[.]dd[[eE][+-]ddd]' in which `d' can be any of digit from 0 to 9, and `[]' indicate optional elements.
+
+     NUM is the corresponding numeric value.  If the conversion fails, status is -1 and NUM is NaN.
+
+     STATUS is 0 if the conversion was successful and -1 otherwise.
+
+     STRARRAY is a cell array of strings.
+
+     Elements which are not defined or not valid return NaN and the STATUS becomes -1.
+
+     If STR is a character array or a cell array of strings, then NUM and STATUS return matrices of appropriate size.
+
+     STR can also contain multiple elements separated by row and column delimiters (CDELIM and RDELIM).
+
+     The parameters CDELIM, RDELIM, and DDELIM are optional column, row, and decimal delimiters.
+
+     The default row-delimiters are newline, carriage return and semicolon (ASCII 10, 13 and 59).  The default column-delimiters are tab, space and comma (ASCII 9, 32, and 44).  The default decimal delimiter is `.' (ASCII 46).
+
+     CDELIM, RDELIM, and DDELIM must contain only nul, newline, carriage return, semicolon, colon, slash, tab, space, comma, or `()[]{}' (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40, 41, 44, 47, 58, 59, 91, 93, 123, 124, 125).
+
+     Examples:
+
+          str2double ("-.1e-5")
+          => -1.0000e-006
+
+          str2double (".314e1, 44.44e-1, .7; -1e+1")
+          =>
+             3.1400    4.4440    0.7000
+           -10.0000       NaN       NaN
+
+          line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+          [x, status] = str2double (line)
+          => x =
+              200   300   NaN  -Inf   NaN   NaN   999   NaN   NaN
+          => status =
+                0     0     0     0    -1    -1     0    -1     0
+     See also: str2num.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Convert strings into numeric values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+strtrim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 397
+ -- Function File:  strtrim (S)
+     Remove leading and trailing blanks and nulls from S.  If S is a matrix, STRTRIM trims each row to the length of longest string.  If S is a cell array, operate recursively on each element of the cell array.  For example:
+
+          strtrim ("    abc  ")
+               => "abc"
+
+          strtrim ([" abc   "; "   def   "])
+               => ["abc  "; "  def"]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Remove leading and trailing blanks and nulls from S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+substr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 498
+ -- Function File:  substr (S, OFFSET, LEN)
+     Return the substring of S which starts at character number OFFSET and is LEN characters long.
+
+     If OFFSET is negative, extraction starts that far from the end of the string.  If LEN is omitted, the substring extends to the end of S.
+
+     For example,
+
+          substr ("This is a test string", 6, 9)
+               => "is a test"
+
+     This function is patterned after AWK.  You can get the same result by `S(OFFSET : (OFFSET + LEN - 1))'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+Return the substring of S which starts at character number OFFSET and is LEN characters long.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+deblank
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 234
+ -- Function File:  deblank (S)
+     Remove trailing blanks and nulls from S.  If S is a matrix, DEBLANK trims each row to the length of longest string.  If S is a cell array, operate recursively on each element of the cell array.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Remove trailing blanks and nulls from S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dec2bin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 496
+ -- Function File:  dec2bin (N, LEN)
+     Return a binary number corresponding to the non-negative decimal number N, as a string of ones and zeros.  For example,
+
+          dec2bin (14)
+               => "1110"
+
+     If N is a vector, returns a string matrix, one row per value, padded with leading zeros to the width of the largest value.
+
+     The optional second argument, LEN, specifies the minimum number of digits in the result.  See also: bin2dec, dec2base, base2dec, hex2dec, dec2hex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+Return a binary number corresponding to the non-negative decimal number N, as a string of ones and zeros.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+blanks
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 377
+ -- Function File:  blanks (N)
+     Return a string of N blanks, for example:
+
+          blanks(10);
+          whos ans;
+               =>
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     ans         1x10                        10  char
+     See also: repmat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Return a string of N blanks, for example: 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+str2num
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 529
+ -- Function File:  str2num (S)
+     Convert the string (or character array) S to a number (or an array).  Examples:
+
+          str2num("3.141596")
+               => 3.141596
+
+          str2num(["1, 2, 3"; "4, 5, 6"]);
+               => ans =
+                  1  2  3
+                  4  5  6
+
+     *Caution:* As `str2num' uses the `eval' function to do the conversion, `str2num' will execute any code contained in the string S.  Use `str2double' instead if you want to avoid the use of `eval'.  See also: str2double, eval.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+Convert the string (or character array) S to a number (or an array).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hex2dec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 418
+ -- Function File:  hex2dec (S)
+     Return the integer corresponding to the hexadecimal number stored in the string S.  For example,
+
+          hex2dec ("12B")
+               => 299
+          hex2dec ("12b")
+               => 299
+
+     If S is a string matrix, returns a column vector of converted numbers, one per row of S.  Invalid rows evaluate to NaN.  See also: dec2hex, base2dec, dec2base, bin2dec, dec2bin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 82
+Return the integer corresponding to the hexadecimal number stored in the string S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+strcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 746
+ -- Function File:  strcat (S1, S2, ...)
+     Return a string containing all the arguments concatenated horizontally.  If the arguments are cells strings,  `strcat' returns a cell string with the individual cells concatenated.  For numerical input, each element is converted to the corresponding ASCII character.  Trailing white space is eliminated.  For example,
+
+          s = [ "ab"; "cde" ];
+          strcat (s, s, s)
+               => ans =
+                  "ab ab ab "
+                  "cdecdecde"
+
+          s = { "ab"; "cde" };
+          strcat (s, s, s)
+               => ans =
+                  {
+                    [1,1] = ababab
+                    [2,1] = cdecdecde
+                  }
+
+     See also: cstrcat, char, strvcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return a string containing all the arguments concatenated horizontally.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+index
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 572
+ -- Function File:  index (S, T)
+ -- Function File:  index (S, T, DIRECTION)
+     Return the position of the first occurrence of the string T in the string S, or 0 if no occurrence is found.  For example,
+
+          index ("Teststring", "t")
+               => 4
+
+     If DIRECTION is `"first"', return the first element found.  If DIRECTION is `"last"', return the last element found.  The `rindex' function is equivalent to `index' with DIRECTION set to `"last"'.
+
+     *Caution:*  This function does not work for arrays of character strings.  See also: find, rindex.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Return the position of the first occurrence of the string T in the string S, or 0 if no occurrence is found.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+strjust
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 486
+ -- Function File:  strjust (S, ["left"|"right"|"center"])
+     Shift the non-blank text of S to the left, right or center of the string.  If S is a string array, justify each string in the array.  Null characters are replaced by blanks.  If no justification is specified, then all rows are right-justified.  For example:
+
+          strjust (["a"; "ab"; "abc"; "abcd"])
+               => ans =
+                     a
+                    ab
+                   abc
+                  abcd
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 73
+Shift the non-blank text of S to the left, right or center of the string.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+strchr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 410
+ -- Function File: IDX = strchr (STR, CHARS)
+ -- Function File: IDX = strchr (STR, CHARS, N)
+ -- Function File: IDX = strchr (STR, CHARS, N, DIRECTION)
+     Search for the string STR for occurrences of characters from the set CHARS.  The return value, as well as the N and DIRECTION arguments behave identically as in `find'.
+
+     This will be faster than using regexp in most cases.
+
+     See also: find.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 75
+Search for the string STR for occurrences of characters from the set CHARS.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 15
+regexptranslate
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 772
+ -- Function File:  regexptranslate (OP, S)
+     Translate a string for use in a regular expression.  This might include either wildcard replacement or special character escaping.  The behavior can be controlled by the OP that can have the values
+
+    "wildcard"
+          The wildcard characters `.', `*' and `?' are replaced with wildcards that are appropriate for a regular expression.  For example:
+               regexptranslate ("wildcard", "*.m")
+                    => ".*\.m"
+
+    "escape"
+          The characters `$.?[]', that have special meaning for regular expressions are escaped so that they are treated literally.  For example:
+               regexptranslate ("escape", "12.5")
+                    => "12\.5"
+     See also: regexp, regexpi, regexprep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Translate a string for use in a regular expression.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+rindex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 345
+ -- Function File:  rindex (S, T)
+     Return the position of the last occurrence of the character string T in the character string S, or 0 if no occurrence is found.  For example,
+
+          rindex ("Teststring", "t")
+               => 6
+
+     *Caution:*  This function does not work for arrays of character strings.  See also: find, index.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+Return the position of the last occurrence of the character string T in the character string S, or 0 if no occurrence is found.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+glpk
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11571
+ -- Function File: [XOPT, FMIN, STATUS, EXTRA] = glpk (C, A, B, LB, UB, CTYPE, VARTYPE, SENSE, PARAM)
+     Solve a linear program using the GNU GLPK library.  Given three arguments, `glpk' solves the following standard LP:
+
+          min C'*x
+
+     subject to
+
+          A*x  = b
+            x >= 0
+
+     but may also solve problems of the form
+
+          [ min | max ] C'*x
+
+     subject to
+
+          A*x [ "=" | "<=" | ">=" ] b
+            x >= LB
+            x <= UB
+
+     Input arguments:
+
+    C
+          A column array containing the objective function coefficients.
+
+    A
+          A matrix containing the constraints coefficients.
+
+    B
+          A column array containing the right-hand side value for each constraint in the constraint matrix.
+
+    LB
+          An array containing the lower bound on each of the variables.  If LB is not supplied, the default lower bound for the variables is zero.
+
+    UB
+          An array containing the upper bound on each of the variables.  If UB is not supplied, the default upper bound is assumed to be infinite.
+
+    CTYPE
+          An array of characters containing the sense of each constraint in the constraint matrix.  Each element of the array may be one of the following values
+         `"F"'
+               A free (unbounded) constraint (the constraint is ignored).
+
+         `"U"'
+               An inequality constraint with an upper bound (`A(i,:)*x <= b(i)').
+
+         `"S"'
+               An equality constraint (`A(i,:)*x = b(i)').
+
+         `"L"'
+               An inequality with a lower bound (`A(i,:)*x >= b(i)').
+
+         `"D"'
+               An inequality constraint with both upper and lower bounds (`A(i,:)*x >= -b(i)' _and_ (`A(i,:)*x <= b(i)').
+
+    VARTYPE
+          A column array containing the types of the variables.
+         `"C"'
+               A continuous variable.
+
+         `"I"'
+               An integer variable.
+
+    SENSE
+          If SENSE is 1, the problem is a minimization.  If SENSE is -1, the problem is a maximization.  The default value is 1.
+
+    PARAM
+          A structure containing the following parameters used to define the behavior of solver.  Missing elements in the structure take on default values, so you only need to set the elements that you wish to change from the default.
+
+          Integer parameters:
+
+         `msglev (`LPX_K_MSGLEV', default: 1)'
+               Level of messages output by solver routines:
+              0
+                    No output.
+
+              1
+                    Error messages only.
+
+              2
+                    Normal output .
+
+              3
+                    Full output (includes informational messages).
+
+         `scale (`LPX_K_SCALE', default: 1)'
+               Scaling option:
+              0
+                    No scaling.
+
+              1
+                    Equilibration scaling.
+
+              2
+                    Geometric mean scaling, then equilibration scaling.
+
+         `dual	 (`LPX_K_DUAL', default: 0)'
+               Dual simplex option:
+              0
+                    Do not use the dual simplex.
+
+              1
+                    If initial basic solution is dual feasible, use the dual simplex.
+
+         `price	 (`LPX_K_PRICE', default: 1)'
+               Pricing option (for both primal and dual simplex):
+              0
+                    Textbook pricing.
+
+              1
+                    Steepest edge pricing.
+
+         `round	 (`LPX_K_ROUND', default: 0)'
+               Solution rounding option:
+              0
+                    Report all primal and dual values "as is".
+
+              1
+                    Replace tiny primal and dual values by exact zero.
+
+         `itlim	 (`LPX_K_ITLIM', default: -1)'
+               Simplex iterations limit.  If this value is positive, it is decreased by one each time when one simplex iteration has been performed, and reaching zero value signals the solver to stop the search.  Negative value means no iterations limit.
+
+         `itcnt (`LPX_K_OUTFRQ', default: 200)'
+               Output frequency, in iterations.  This parameter specifies how frequently the solver sends information about the solution to the standard output.
+
+         `branch (`LPX_K_BRANCH', default: 2)'
+               Branching heuristic option (for MIP only):
+              0
+                    Branch on the first variable.
+
+              1
+                    Branch on the last variable.
+
+              2
+                    Branch using a heuristic by Driebeck and Tomlin.
+
+         `btrack (`LPX_K_BTRACK', default: 2)'
+               Backtracking heuristic option (for MIP only):
+              0
+                    Depth first search.
+
+              1
+                    Breadth first search.
+
+              2
+                    Backtrack using the best projection heuristic.
+
+         `presol (`LPX_K_PRESOL', default: 1)'
+               If this flag is set, the routine lpx_simplex solves the problem using the built-in LP presolver.  Otherwise the LP presolver is not used.
+
+         `lpsolver (default: 1)'
+               Select which solver to use.  If the problem is a MIP problem this flag will be ignored.
+              1
+                    Revised simplex method.
+
+              2
+                    Interior point method.
+
+         `save (default: 0)'
+               If this parameter is nonzero, save a copy of the problem in CPLEX LP format to the file `"outpb.lp"'.  There is currently no way to change the name of the output file.
+
+          Real parameters:
+
+         `relax (`LPX_K_RELAX', default: 0.07)'
+               Relaxation parameter used in the ratio test.  If it is zero, the textbook ratio test is used.  If it is non-zero (should be positive), Harris' two-pass ratio test is used.  In the latter case on the first pass of the ratio test basic variables (in the case of primal simplex) or reduced costs of non-basic variables (in the case of dual simplex) are allowed to slightly violate their bounds, but not more than `relax*tolbnd' or `relax*toldj (thus, `relax' is a percentage of `tolbnd' or `toldj''.
+
+         `tolbnd (`LPX_K_TOLBND', default: 10e-7)'
+               Relative tolerance used to check if the current basic solution is primal feasible.  It is not recommended that you change this parameter unless you have a detailed understanding of its purpose.
+
+         `toldj (`LPX_K_TOLDJ', default: 10e-7)'
+               Absolute tolerance used to check if the current basic solution is dual feasible.  It is not recommended that you change this parameter unless you have a detailed understanding of its purpose.
+
+         `tolpiv (`LPX_K_TOLPIV', default: 10e-9)'
+               Relative tolerance used to choose eligible pivotal elements of the simplex table.  It is not recommended that you change this parameter unless you have a detailed understanding of its purpose.
+
+         `objll (`LPX_K_OBJLL', default: -DBL_MAX)'
+               Lower limit of the objective function.  If on the phase II the objective function reaches this limit and continues decreasing, the solver stops the search.  This parameter is used in the dual simplex method only.
+
+         `objul (`LPX_K_OBJUL', default: +DBL_MAX)'
+               Upper limit of the objective function.  If on the phase II the objective function reaches this limit and continues increasing, the solver stops the search.  This parameter is used in the dual simplex only.
+
+         `tmlim (`LPX_K_TMLIM', default: -1.0)'
+               Searching time limit, in seconds.  If this value is positive, it is decreased each time when one simplex iteration has been performed by the amount of time spent for the iteration, and reaching zero value signals the solver to stop the search.  Negative value means no time limit.
+
+         `outdly (`LPX_K_OUTDLY', default: 0.0)'
+               Output delay, in seconds.  This parameter specifies how long the solver should delay sending information about the solution to the standard output.  Non-positive value means no delay.
+
+         `tolint (`LPX_K_TOLINT', default: 10e-5)'
+               Relative tolerance used to check if the current basic solution is integer feasible.  It is not recommended that you change this parameter unless you have a detailed understanding of its purpose.
+
+         `tolobj (`LPX_K_TOLOBJ', default: 10e-7)'
+               Relative tolerance used to check if the value of the objective function is not better than in the best known integer feasible solution.  It is not recommended that you change this parameter unless you have a detailed understanding of its purpose.
+
+     Output values:
+
+    XOPT
+          The optimizer (the value of the decision variables at the optimum).
+
+    FOPT
+          The optimum value of the objective function.
+
+    STATUS
+          Status of the optimization.
+
+          Simplex Method:
+         180 (`LPX_OPT')
+               Solution is optimal.
+
+         181 (`LPX_FEAS')
+               Solution is feasible.
+
+         182 (`LPX_INFEAS')
+               Solution is infeasible.
+
+         183 (`LPX_NOFEAS')
+               Problem has no feasible solution.
+
+         184 (`LPX_UNBND')
+               Problem has no unbounded solution.
+
+         185 (`LPX_UNDEF')
+               Solution status is undefined.
+          Interior Point Method:
+         150 (`LPX_T_UNDEF')
+               The interior point method is undefined.
+
+         151 (`LPX_T_OPT')
+               The interior point method is optimal.
+          Mixed Integer Method:
+         170 (`LPX_I_UNDEF')
+               The status is undefined.
+
+         171 (`LPX_I_OPT')
+               The solution is integer optimal.
+
+         172 (`LPX_I_FEAS')
+               Solution integer feasible but its optimality has not been proven
+
+         173 (`LPX_I_NOFEAS')
+               No integer feasible solution.
+          If an error occurs, STATUS will contain one of the following codes:
+
+         204 (`LPX_E_FAULT')
+               Unable to start the search.
+
+         205 (`LPX_E_OBJLL')
+               Objective function lower limit reached.
+
+         206 (`LPX_E_OBJUL')
+               Objective function upper limit reached.
+
+         207 (`LPX_E_ITLIM')
+               Iterations limit exhausted.
+
+         208 (`LPX_E_TMLIM')
+               Time limit exhausted.
+
+         209 (`LPX_E_NOFEAS')
+               No feasible solution.
+
+         210 (`LPX_E_INSTAB')
+               Numerical instability.
+
+         211 (`LPX_E_SING')
+               Problems with basis matrix.
+
+         212 (`LPX_E_NOCONV')
+               No convergence (interior).
+
+         213 (`LPX_E_NOPFS')
+               No primal feasible solution (LP presolver).
+
+         214 (`LPX_E_NODFS')
+               No dual feasible solution (LP presolver).
+
+    EXTRA
+          A data structure containing the following fields:
+         `lambda'
+               Dual variables.
+
+         `redcosts'
+               Reduced Costs.
+
+         `time'
+               Time (in seconds) used for solving LP/MIP problem.
+
+         `mem'
+               Memory (in bytes) used for solving LP/MIP problem (this is not available if the version of GLPK is 4.15 or later).
+
+     Example:
+
+          c = [10, 6, 4]';
+          a = [ 1, 1, 1;
+               10, 4, 5;
+                2, 2, 6];
+          b = [100, 600, 300]';
+          lb = [0, 0, 0]';
+          ub = [];
+          ctype = "UUU";
+          vartype = "CCC";
+          s = -1;
+
+          param.msglev = 1;
+          param.itlim = 100;
+
+          [xmin, fmin, status, extra] = ...
+             glpk (c, a, b, lb, ub, ctype, vartype, s, param);
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Solve a linear program using the GNU GLPK library.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+lsqnonneg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1204
+ -- Function File: X = lsqnonneg (C, D)
+ -- Function File: X = lsqnonneg (C, D, X0)
+ -- Function File: [X, RESNORM] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL, EXITFLAG] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL, EXITFLAG, OUTPUT] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL, EXITFLAG, OUTPUT, LAMBDA] = lsqnonneg (...)
+     Minimize `norm (C*X-d)' subject to `X >= 0'.  C and D must be real.  X0 is an optional initial guess for X.
+
+     Outputs:
+        * resnorm
+
+          The squared 2-norm of the residual: norm(C*X-D)^2
+
+        * residual
+
+          The residual: D-C*X
+
+        * exitflag
+
+          An indicator of convergence.  0 indicates that the iteration count was exceeded, and therefore convergence was not reached; >0 indicates that the algorithm converged.  (The algorithm is stable and will converge given enough iterations.)
+
+        * output
+
+          A structure with two fields:
+             * "algorithm": The algorithm used ("nnls")
+
+             * "iterations": The number of iterations taken.
+
+        * lambda
+
+          Not implemented.
+     See also: optimset.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Minimize `norm (C*X-d)' subject to `X >= 0'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fsolve
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4012
+ -- Function File:  fsolve (FCN, X0, OPTIONS)
+ -- Function File: [X, FVEC, INFO, OUTPUT, FJAC] = fsolve (FCN, ...)
+     Solve a system of nonlinear equations defined by the function FCN.  FCN should accepts a vector (array) defining the unknown variables, and return a vector of left-hand sides of the equations.  Right-hand sides are defined to be zeros.  In other words, this function attempts to determine a vector X such that `FCN (X)' gives (approximately) all zeros.  X0 determines a starting guess.  The shape of X0 is preserved in all calls to FCN, but otherwise it is treated as a column vector.  OPTIONS is a structure specifying additional options.  Currently, `fsolve' recognizes these options: `"FunValCheck"', `"OutputFcn"', `"TolX"', `"TolFun"', `"MaxIter"', `"MaxFunEvals"', `"Jacobian"', `"Updating"' and `"ComplexEqn"'.
+
+     If `"Jacobian"' is `"on"', it specifies that FCN, called with 2 output arguments, also returns the Jacobian matrix of right-hand sides at the requested point.  `"TolX"' specifies the termination tolerance in the unknown variables, while `"TolFun"' is a tolerance for equations.  Default is `1e-7' for both `"TolX"' and `"TolFun"'.  If `"Updating"' is "on", the function will attempt to use Broyden updates to update the Jacobian, in order to reduce the amount of jacobian calculations.  If your user function always calculates the Jacobian (regardless of number of output arguments), this option provides no advantage and should be set to false.
+
+     `"ComplexEqn"' is `"on"', `fsolve' will attempt to solve complex equations in complex variables, assuming that the equations possess a complex derivative (i.e., are holomorphic).  If this is not what you want, should unpack the real and imaginary parts of the system to get a real system.
+
+     For description of the other options, see `optimset'.
+
+     On return, FVAL contains the value of the function FCN evaluated at X, and INFO may be one of the following values:
+
+    1
+          Converged to a solution point.  Relative residual error is less than specified by TolFun.
+
+    2
+          Last relative step size was less that TolX.
+
+    3
+          Last relative decrease in residual was less than TolF.
+
+    0
+          Iteration limit exceeded.
+
+    -3
+          The trust region radius became excessively small.
+
+     Note: If you only have a single nonlinear equation of one variable, using `fzero' is usually a much better idea.  See also: fzero, optimset.
+
+     Note about user-supplied jacobians: As an inherent property of the algorithm, jacobian is always requested for a solution vector whose residual vector is already known, and it is the last accepted successful step.  Often this will be one of the last two calls, but not always.  If the savings by reusing intermediate results from residual calculation in jacobian calculation are significant, the best strategy is to employ OutputFcn: After a vector is evaluated for residuals, if OutputFcn is called with that vector, then the intermediate results should be saved for future jacobian evaluation, and should be kept until a jacobian evaluation is requested or until outputfcn is called with a different vector, in which case they should be dropped in favor of this most recent vector.  A short example how this can be achieved follows:
+
+          function [fvec, fjac] = user_func (x, optimvalues, state)
+          persistent sav = [], sav0 = [];
+          if (nargin == 1)
+            ## evaluation call
+            if (nargout == 1)
+              sav0.x = x; # mark saved vector
+              ## calculate fvec, save results to sav0.
+            elseif (nargout == 2)
+              ## calculate fjac using sav.
+            endif
+          else
+            ## outputfcn call.
+            if (all (x == sav0.x))
+              sav = sav0;
+            endif
+            ## maybe output iteration status, etc.
+          endif
+          endfunction
+
+           ....
+
+          fsolve (@user_func, x0, optimset ("OutputFcn", @user_func, ...))
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Solve a system of nonlinear equations defined by the function FCN.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+optimget
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 293
+ -- Function File:  optimget (OPTIONS, PARNAME)
+ -- Function File:  optimget (OPTIONS, PARNAME, DEFAULT)
+     Return a specific option from a structure created by `optimset'.  If PARNAME is not a field of the OPTIONS structure, return DEFAULT if supplied, otherwise return an empty matrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return a specific option from a structure created by `optimset'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+fzero
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 962
+ -- Function File: [X, FVAL, INFO, OUTPUT] = fzero (FUN, X0, OPTIONS)
+     Find a zero point of a univariate function.  FUN should be a function handle or name.  X0 specifies a starting point.  OPTIONS is a structure specifying additional options.  Currently, `fzero' recognizes these options: `"FunValCheck"', `"OutputFcn"', `"TolX"', `"MaxIter"', `"MaxFunEvals"'.  For description of these options, see *note optimset: doc-optimset.
+
+     On exit, the function returns X, the approximate zero point and FVAL, the function value thereof.  INFO is an exit flag that can have these values:
+        * 1 The algorithm converged to a solution.
+
+        * 0 Maximum number of iterations or function evaluations has been exhausted.
+
+        * -1 The algorithm has been terminated from user output function.
+
+        * -2 A general unexpected error.
+
+        * -3 A non-real value encountered.
+
+        * -4 A NaN value encountered.
+     See also: optimset, fsolve.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Find a zero point of a univariate function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+glpkmex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 293
+ -- Function File: [XOPT, FMIN, STATUS, EXTRA] = glpkmex (SENSE, C, A, B, CTYPE, LB, UB, VARTYPE, PARAM, LPSOLVER, SAVE_PB)
+     This function is provided for compatibility with the old MATLAB interface to the GNU GLPK library.  For Octave code, you should use the `glpk' function instead.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 98
+This function is provided for compatibility with the old MATLAB interface to the GNU GLPK library.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2
+qp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1066
+ -- Function File: [X, OBJ, INFO, LAMBDA] = qp (X0, H, Q, A, B, LB, UB, A_LB, A_IN, A_UB)
+     Solve the quadratic program
+
+               min 0.5 x'*H*x + x'*q
+                x
+
+     subject to
+
+               A*x = b
+               lb <= x <= ub
+               A_lb <= A_in*x <= A_ub
+
+     using a null-space active-set method.
+
+     Any bound (A, B, LB, UB, A_LB, A_UB) may be set to the empty matrix (`[]') if not present.  If the initial guess is feasible the algorithm is faster.
+
+     The value INFO is a structure with the following fields:
+    `solveiter'
+          The number of iterations required to find the solution.
+
+    `info'
+          An integer indicating the status of the solution, as follows:
+         0
+               The problem is feasible and convex.  Global solution found.
+
+         1
+               The problem is not convex.  Local solution found.
+
+         2
+               The problem is not convex and unbounded.
+
+         3
+               Maximum number of iterations reached.
+
+         6
+               The problem is infeasible.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 28
+Solve the quadratic program 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+fminunc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1805
+ -- Function File:  fminunc (FCN, X0, OPTIONS)
+ -- Function File: [X, FVEC, INFO, OUTPUT, FJAC] = fminunc (FCN, ...)
+     Solve a unconstrained optimization problem defined by the function FCN.  FCN should accepts a vector (array) defining the unknown variables, and return the objective function value, optionally with gradient.  In other words, this function attempts to determine a vector X such that `FCN (X)' is a local minimum.  X0 determines a starting guess. The shape of X0 is preserved in all calls to FCN, but otherwise it is treated as a column vector.  OPTIONS is a structure specifying additional options.  Currently, `fminunc' recognizes these options: `"FunValCheck"', `"OutputFcn"', `"TolX"', `"TolFun"', `"MaxIter"', `"MaxFunEvals"', `"GradObj"', `"FinDiffType"'.
+
+     If `"GradObj"' is `"on"', it specifies that FCN, called with 2 output arguments, also returns the Jacobian matrix of right-hand sides at the requested point.  `"TolX"' specifies the termination tolerance in the unknown variables, while `"TolFun"' is a tolerance for equations. Default is `1e-7' for both `"TolX"' and `"TolFun"'.
+
+     For description of the other options, see `optimset'.
+
+     On return, FVAL contains the value of the function FCN evaluated at X, and INFO may be one of the following values:
+
+    1
+          Converged to a solution point. Relative gradient error is less than specified by TolFun.
+
+    2
+          Last relative step size was less that TolX.
+
+    3
+          Last relative decrease in func value was less than TolF.
+
+    0
+          Iteration limit exceeded.
+
+    -3
+          The trust region radius became excessively small.
+
+     Note: If you only have a single nonlinear equation of one variable, using `fminbnd' is usually a much better idea.  See also: fminbnd, optimset.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Solve a unconstrained optimization problem defined by the function FCN.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+sqp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3958
+ -- Function File: [X, OBJ, INFO, ITER, NF, LAMBDA] = sqp (X, PHI, G, H, LB, UB, MAXITER, TOLERANCE)
+     Solve the nonlinear program
+
+               min phi (x)
+                x
+
+     subject to
+
+               g(x)  = 0
+               h(x) >= 0
+               lb <= x <= ub
+
+     using a successive quadratic programming method.
+
+     The first argument is the initial guess for the vector X.
+
+     The second argument is a function handle pointing to the objective function.  The objective function must be of the form
+
+               y = phi (x)
+
+     in which X is a vector and Y is a scalar.
+
+     The second argument may also be a 2- or 3-element cell array of function handles.  The first element should point to the objective function, the second should point to a function that computes the gradient of the objective function, and the third should point to a function to compute the hessian of the objective function.  If the gradient function is not supplied, the gradient is computed by finite differences.  If the hessian function is not supplied, a BFGS update formula is used to approximate the hessian.
+
+     If supplied, the gradient function must be of the form
+
+          g = gradient (x)
+
+     in which X is a vector and G is a vector.
+
+     If supplied, the hessian function must be of the form
+
+          h = hessian (x)
+
+     in which X is a vector and H is a matrix.
+
+     The third and fourth arguments are function handles pointing to functions that compute the equality constraints and the inequality constraints, respectively.
+
+     If your problem does not have equality (or inequality) constraints, you may pass an empty matrix for CEF (or CIF).
+
+     If supplied, the equality and inequality constraint functions must be of the form
+
+          r = f (x)
+
+     in which X is a vector and R is a vector.
+
+     The third and fourth arguments may also be 2-element cell arrays of function handles.  The first element should point to the constraint function and the second should point to a function that computes the gradient of the constraint function:
+
+                          [ d f(x)   d f(x)        d f(x) ]
+              transpose ( [ ------   -----   ...   ------ ] )
+                          [  dx_1     dx_2          dx_N  ]
+
+     The fifth and sixth arguments are vectors containing lower and upper bounds on X.  These must be consistent with equality and inequality constraints G and H.  If the bounds are not specified, or are empty, they are set to -REALMAX and REALMAX by default.
+
+     The seventh argument is max. number of iterations.  If not specified, the default value is 100.
+
+     The eighth argument is tolerance for stopping criteria.  If not specified, the default value is EPS.
+
+     Here is an example of calling `sqp':
+
+          function r = g (x)
+            r = [ sumsq(x)-10;
+                  x(2)*x(3)-5*x(4)*x(5);
+                  x(1)^3+x(2)^3+1 ];
+          endfunction
+
+          function obj = phi (x)
+            obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+          endfunction
+
+          x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+
+          [x, obj, info, iter, nf, lambda] = sqp (x0, @phi, @g, [])
+
+          x =
+
+            -1.71714
+             1.59571
+             1.82725
+            -0.76364
+            -0.76364
+
+          obj = 0.053950
+          info = 101
+          iter = 8
+          nf = 10
+          lambda =
+
+            -0.0401627
+             0.0379578
+            -0.0052227
+
+     The value returned in INFO may be one of the following:
+    101
+          The algorithm terminated because the norm of the last step was less than `tol * norm (x))' (the value of tol is currently fixed at `sqrt (eps)'--edit `sqp.m' to modify this value.
+
+    102
+          The BFGS update failed.
+
+    103
+          The maximum number of iterations was reached (the maximum number of allowed iterations is currently fixed at 100--edit `sqp.m' to increase this value).
+     See also: qp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 28
+Solve the nonlinear program 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+optimset
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Function File:  optimset ()
+ -- Function File:  optimset (PAR, VAL, ...)
+ -- Function File:  optimset (OLD, PAR, VAL, ...)
+ -- Function File:  optimset (OLD, NEW)
+     Create options struct for optimization functions.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Create options struct for optimization functions.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+acoth
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Mapping Function:  acoth (X)
+     Compute the inverse hyperbolic cotangent of each element of X.  See also: coth.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Compute the inverse hyperbolic cotangent of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+acotd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 125
+ -- Function File:  acotd (X)
+     Compute the inverse cotangent in degrees for each element of X.  See also: cotd, acot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Compute the inverse cotangent in degrees for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+tand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 226
+ -- Function File:  tand (X)
+     Compute the tangent for each element of X in degrees.  Returns zero for elements where `X/180' is an integer and `Inf' for elements where `(X-90)/180' is an integer.  See also: atand, tan.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compute the tangent for each element of X in degrees.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+acot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 127
+ -- Mapping Function:  acot (X)
+     Compute the inverse cotangent in radians for each element of X.  See also: cot, acotd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Compute the inverse cotangent in radians for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+coth
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Mapping Function:  coth (X)
+     Compute the hyperbolic cotangent of each element of X.  See also: acoth.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Compute the hyperbolic cotangent of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+sec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Mapping Function:  sec (X)
+     Compute the secant for each element of X in radians.  See also: asec, secd, sech.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Compute the secant for each element of X in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+atand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+ -- Function File:  atand (X)
+     Compute the inverse tangent in degrees for each element of X.  See also: tand, atan.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Compute the inverse tangent in degrees for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+lcm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 336
+ -- Mapping Function:  lcm (X)
+ -- Mapping Function:  lcm (X, ...)
+     Compute the least common multiple of the elements of X, or of the list of all arguments.  For example,
+
+          lcm (a1, ..., ak)
+
+     is the same as
+
+          lcm ([a1, ..., ak]).
+
+     All elements must be the same size or scalar.  See also: factor, gcd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+Compute the least common multiple of the elements of X, or of the list of all arguments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+secd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Function File:  secd (X)
+     Compute the secant for each element of X in degrees.  See also: asecd, sec.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Compute the secant for each element of X in degrees.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cotd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 116
+ -- Function File:  cotd (X)
+     Compute the cotangent for each element of X in degrees.  See also: acotd, cot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Compute the cotangent for each element of X in degrees.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+csch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+ -- Mapping Function:  csch (X)
+     Compute the hyperbolic cosecant of each element of X.  See also: acsch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compute the hyperbolic cosecant of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+asind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+ -- Function File:  asind (X)
+     Compute the inverse sine in degrees for each element of X.  See also: sind, asin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Compute the inverse sine in degrees for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+asec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+ -- Mapping Function:  asec (X)
+     Compute the inverse secant in radians for each element of X.  See also: sec, asecd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Compute the inverse secant in radians for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+acosd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Function File:  acosd (X)
+     Compute the inverse cosine in degrees for each element of X.  See also: cosd, acos.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Compute the inverse cosine in degrees for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+acsc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+ -- Mapping Function:  acsc (X)
+     Compute the inverse cosecant in radians for each element of X.  See also: csc, acscd.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Compute the inverse cosecant in radians for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+csc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+ -- Mapping Function:  csc (X)
+     Compute the cosecant for each element of X in radians.  See also: acsc, cscd, csch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Compute the cosecant for each element of X in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+ -- Mapping Function:  cot (X)
+     Compute the cotangent for each element of X in radians.  See also: acot, cotd, coth.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Compute the cotangent for each element of X in radians.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 167
+ -- Function File:  sind (X)
+     Compute the sine for each element of X in degrees.  Returns zero for elements where `X/180' is an integer.  See also: asind, sin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Compute the sine for each element of X in degrees.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sech
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+ -- Mapping Function:  sech (X)
+     Compute the hyperbolic secant of each element of X.  See also: asech.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Compute the hyperbolic secant of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+asech
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+ -- Mapping Function:  asech (X)
+     Compute the inverse hyperbolic secant of each element of X.  See also: sech.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Compute the inverse hyperbolic secant of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+asecd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Function File:  asecd (X)
+     Compute the inverse secant in degrees for each element of X.  See also: secd, asec.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Compute the inverse secant in degrees for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cosd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 174
+ -- Function File:  cosd (X)
+     Compute the cosine for each element of X in degrees.  Returns zero for elements where `(X-90)/180' is an integer.  See also: acosd, cos.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Compute the cosine for each element of X in degrees.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cscd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+ -- Function File:  cscd (X)
+     Compute the cosecant for each element of X in degrees.  See also: acscd, csc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Compute the cosecant for each element of X in degrees.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+acscd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 124
+ -- Function File:  acscd (X)
+     Compute the inverse cosecant in degrees for each element of X.  See also: cscd, acsc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Compute the inverse cosecant in degrees for each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+acsch
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 120
+ -- Mapping Function:  acsch (X)
+     Compute the inverse hyperbolic cosecant of each element of X.  See also: csch.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Compute the inverse hyperbolic cosecant of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+etreeplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 286
+ -- Function File:  etreeplot (TREE)
+ -- Function File:  etreeplot (TREE, NODE_STYLE, EDGE_STYLE)
+     Plot the elimination tree of the matrix S or `S+S''  if S in non-symmetric.  The optional parameters LINE_STYLE and EDGE_STYLE define the output style.  See also: treeplot, gplot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Plot the elimination tree of the matrix S or `S+S'' if S in non-symmetric.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+gplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 564
+ -- Function File:  gplot (A, XY)
+ -- Function File:  gplot (A, XY, LINE_STYLE)
+ -- Function File: [X, Y] = gplot (A, XY)
+     Plot a graph defined by A and XY in the graph theory sense.  A is the adjacency matrix of the array to be plotted and XY is an N-by-2 matrix containing the coordinates of the nodes of the graph.
+
+     The optional parameter LINE_STYLE defines the output style for the plot.  Called with no output arguments the graph is plotted directly.  Otherwise, return the coordinates of the plot in X and Y.  See also: treeplot, etreeplot, spy.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Plot a graph defined by A and XY in the graph theory sense.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spstats
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 570
+ -- Function File: [COUNT, MEAN, VAR] = spstats (S)
+ -- Function File: [COUNT, MEAN, VAR] = spstats (S, J)
+     Return the stats for the non-zero elements of the sparse matrix S.  COUNT is the number of non-zeros in each column, MEAN is the mean of the non-zeros in each column, and VAR is the variance of the non-zeros in each column.
+
+     Called with two input arguments, if S is the data and J is the bin number for the data, compute the stats for each bin.  In this case, bins can contain data values of zero, whereas with `spstats (S)' the zeros may disappear.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return the stats for the non-zero elements of the sparse matrix S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+treeplot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 373
+ -- Function File:  treeplot (TREE)
+ -- Function File:  treeplot (TREE, LINE_STYLE, EDGE_STYLE)
+     Produces a graph of tree or forest.  The first argument is vector of predecessors, optional parameters LINE_STYLE and EDGE_STYLE define the output style.  The complexity of the algorithm is O(n) in terms of is time and memory requirements.  See also: etreeplot, gplot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Produces a graph of tree or forest.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spones
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+ -- Function File: Y = spones (X)
+     Replace the non-zero entries of X with ones.  This creates a sparse matrix with the same structure as X.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Replace the non-zero entries of X with ones.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+nonzeros
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 105
+ -- Function File:  nonzeros (S)
+     Returns a vector of the non-zero values of the sparse matrix S.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Returns a vector of the non-zero values of the sparse matrix S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+bicgstab
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1097
+ -- Function File:  bicgstab (A, B)
+ -- Function File:  bicgstab (A, B, TOL, MAXIT, M1, M2, X0)
+     This procedure attempts to solve a system of linear equations A*x = b for x.  The A must be square, symmetric and positive definite real matrix N*N.  The B must be a one column vector with a length of N.  The TOL specifies the tolerance of the method, the default value is 1e-6.  The MAXIT specifies the maximum number of iterations, the default value is min(20,N).  The M1 specifies a preconditioner, can also be a function handler which returns M\X.  The M2 combined with M1 defines preconditioner as preconditioner=M1*M2.  The X0 is the initial guess, the default value is zeros(N,1).
+
+     The value X is a computed result of this procedure.  The value FLAG can be 0 when we reach tolerance in MAXIT iterations, 1 when we don't reach tolerance in MAXIT iterations and 3 when the procedure stagnates.  The value RELRES is a relative residual - norm(b-A*x)/norm(b).  The value ITER is an iteration number in which x was computed.  The value RESVEC is a vector of RELRES for each iteration.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+This procedure attempts to solve a system of linear equations A*x = b for x.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+treelayout
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 381
+ -- Function File:  treelayout (TREE)
+ -- Function File:  treelayout (TREE, PERMUTATION)
+     treelayout lays out a tree or a forest.  The first argument TREE is a vector of predecessors, optional parameter PERMUTATION is an optional postorder permutation.  The complexity of the algorithm is O(n) in terms of time and memory requirements.  See also: etreeplot, gplot,treeplot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+treelayout lays out a tree or a forest.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sphcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 211
+ -- Function File: Y = sphcat (A1, A2, ..., AN)
+     Return the horizontal concatenation of sparse matrices.  This function is obselete and `horzcat' should be used.  See also: spvcat, vertcat, horzcat, cat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return the horizontal concatenation of sparse matrices.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+sprandsym
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 606
+ -- Function File:  sprandsym (N, D)
+ -- Function File:  sprandsym (S)
+     Generate a symmetric random sparse matrix.  The size of the matrix will be N by N, with a density of values given by D.  D should be between 0 and 1. Values will be normally distributed with mean of zero and variance 1.
+
+     Note: sometimes the actual density may be a bit smaller than D.  This is unlikely to happen for large really sparse matrices.
+
+     If called with a single matrix argument, a random sparse matrix is generated wherever the matrix S is non-zero in its lower triangular part.  See also: sprand, sprandn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Generate a symmetric random sparse matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+cgs
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 666
+ -- Function File:  cgs (A, B)
+ -- Function File:  cgs (A, B, TOL, MAXIT, M1, M2, X0)
+     This procedure attempts to solve a system of linear equations A*x = b for x.  The A must be square, symmetric and positive definite real matrix N*N.  The B must be a one column vector with a length of N.  The TOL specifies the tolerance of the method, default value is 1e-6.  The MAXIT specifies the maximum number of iteration, default value is MIN(20,N).  The M1 specifies a preconditioner, can also be a function handler which returns M\X.  The M2 combined with M1 defines preconditioner as preconditioner=M1*M2.  The X0 is initial guess, default value is zeros(N,1).
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+This procedure attempts to solve a system of linear equations A*x = b for x.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+pcg
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5631
+ -- Function File: X = pcg (A, B, TOL, MAXIT, M1, M2, X0, ...)
+ -- Function File: [X, FLAG, RELRES, ITER, RESVEC, EIGEST] = pcg (...)
+     Solves the linear system of equations `A * X = B' by means of the Preconditioned Conjugate Gradient iterative method.  The input arguments are
+
+        * A can be either a square (preferably sparse) matrix or a function handle, inline function or string containing the name of a function which computes `A * X'.  In principle A should be symmetric and positive definite; if `pcg' finds A to not be positive definite, you will get a warning message and the FLAG output parameter will be set.
+
+        * B is the right hand side vector.
+
+        * TOL is the required relative tolerance for the residual error, `B - A * X'.  The iteration stops if `norm (B - A * X) <= TOL * norm (B - A * X0)'.  If TOL is empty or is omitted, the function sets `TOL = 1e-6' by default.
+
+        * MAXIT is the maximum allowable number of iterations; if `[]' is supplied for `maxit', or `pcg' has less arguments, a default value equal to 20 is used.
+
+        * M = M1 * M2 is the (left) preconditioning matrix, so that the iteration is (theoretically) equivalent to solving by `pcg' `P * X = M \ B', with `P = M \ A'.  Note that a proper choice of the preconditioner may dramatically improve the overall performance of the method.  Instead of matrices M1 and M2, the user may pass two functions which return the results of applying the inverse of M1 and M2 to a vector (usually this is the preferred way of using the preconditioner).  If `[]' is supplied for M1, or M1 is omitted, no preconditioning is applied.  If M2 is omitted, M = M1 will be used as preconditioner.
+
+        * X0 is the initial guess.  If X0 is empty or omitted, the function sets X0 to a zero vector by default.
+
+     The arguments which follow X0 are treated as parameters, and passed in a proper way to any of the functions (A or M) which are passed to `pcg'.  See the examples below for further details.  The output arguments are
+
+        * X is the computed approximation to the solution of `A * X = B'.
+
+        * FLAG reports on the convergence.  `FLAG = 0' means the solution converged and the tolerance criterion given by TOL is satisfied.  `FLAG = 1' means that the MAXIT limit for the iteration count was reached.  `FLAG = 3' reports that the (preconditioned) matrix was found not positive definite.
+
+        * RELRES is the ratio of the final residual to its initial value, measured in the Euclidean norm.
+
+        * ITER is the actual number of iterations performed.
+
+        * RESVEC describes the convergence history of the method.  `RESVEC (i,1)' is the Euclidean norm of the residual, and `RESVEC (i,2)' is the preconditioned residual norm, after the (I-1)-th iteration, `I = 1, 2, ..., ITER+1'.  The preconditioned residual norm is defined as `norm (R) ^ 2 = R' * (M \ R)' where `R = B - A * X', see also the description of M.  If EIGEST is not required, only `RESVEC (:,1)' is returned.
+
+        * EIGEST returns the estimate for the smallest `EIGEST (1)' and largest `EIGEST (2)' eigenvalues of the preconditioned matrix `P = M \ A'.  In particular, if no preconditioning is used, the estimates for the extreme eigenvalues of A are returned.  `EIGEST (1)' is an overestimate and `EIGEST (2)' is an underestimate, so that `EIGEST (2) / EIGEST (1)' is a lower bound for `cond (P, 2)', which nevertheless in the limit should theoretically be equal to the actual value of the condition number.  The method which computes EIGEST works only for symmetric positive definite A and M, and the user is responsible for verifying this assumption.
+
+     Let us consider a trivial problem with a diagonal matrix (we exploit the sparsity of A)
+
+          	n = 10;
+          	a = diag (sparse (1:n));
+          	b = rand (n, 1);
+               [l, u, p, q] = luinc (a, 1.e-3);
+
+     EXAMPLE 1: Simplest use of `pcg'
+
+            x = pcg(A,b)
+
+     EXAMPLE 2: `pcg' with a function which computes `A * X'
+
+            function y = apply_a (x)
+              y = [1:N]'.*x;
+            endfunction
+
+            x = pcg ("apply_a", b)
+
+     EXAMPLE 3: `pcg' with a preconditioner: L * U
+
+          x = pcg (a, b, 1.e-6, 500, l*u);
+
+     EXAMPLE 4: `pcg' with a preconditioner: L * U.  Faster than EXAMPLE 3 since lower and upper triangular matrices are easier to invert
+
+          x = pcg (a, b, 1.e-6, 500, l, u);
+
+     EXAMPLE 5: Preconditioned iteration, with full diagnostics.  The preconditioner (quite strange, because even the original matrix A is trivial) is defined as a function
+
+            function y = apply_m (x)
+              k = floor (length (x) - 2);
+              y = x;
+              y(1:k) = x(1:k)./[1:k]';
+            endfunction
+
+            [x, flag, relres, iter, resvec, eigest] = ...
+                               pcg (a, b, [], [], "apply_m");
+            semilogy (1:iter+1, resvec);
+
+     EXAMPLE 6: Finally, a preconditioner which depends on a parameter K.
+
+            function y = apply_M (x, varargin)
+            K = varargin{1};
+            y = x;
+            y(1:K) = x(1:K)./[1:K]';
+            endfunction
+
+            [x, flag, relres, iter, resvec, eigest] = ...
+                 pcg (A, b, [], [], "apply_m", [], [], 3)
+
+     REFERENCES
+
+     	[1] C.T.Kelley, 'Iterative methods for linear and nonlinear equations', 	SIAM, 1995 (the base PCG algorithm)
+
+     	[2] Y.Saad, 'Iterative methods for sparse linear systems', PWS 1996 	(condition number estimate from PCG) Revised version of this book is 	available online at http://www-users.cs.umn.edu/~saad/books.html
+
+     See also: sparse, pcr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 117
+Solves the linear system of equations `A * X = B' by means of the Preconditioned Conjugate Gradient iterative method.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spvcat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 207
+ -- Function File: Y = spvcat (A1, A2, ..., AN)
+     Return the vertical concatenation of sparse matrices.  This function is obselete and `vertcat' should be used See also: sphcat, vertcat, horzcat, cat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Return the vertical concatenation of sparse matrices.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+normest
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 431
+ -- Function File: [N, C] = normest (A, TOL)
+     Estimate the 2-norm of the matrix A using a power series analysis.  This is typically used for large matrices, where the cost of calculating the `norm (A)' is prohibitive and an approximation to the 2-norm is acceptable.
+
+     TOL is the tolerance to which the 2-norm is calculated.  By default TOL is 1e-6.  C returns the number of iterations needed for `normest' to converge.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Estimate the 2-norm of the matrix A using a power series analysis.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+pcr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4058
+ -- Function File: X = pcr (A, B, TOL, MAXIT, M, X0, ...)
+ -- Function File: [X, FLAG, RELRES, ITER, RESVEC] = pcr (...)
+     Solves the linear system of equations `A * X = B' by means of the Preconditioned Conjugate Residuals iterative method.  The input arguments are
+
+        * A can be either a square (preferably sparse) matrix or a function handle, inline function or string containing the name of a function which computes `A * X'.  In principle A should be symmetric and non-singular; if `pcr' finds A to be numerically singular, you will get a warning message and the FLAG output parameter will be set.
+
+        * B is the right hand side vector.
+
+        * TOL is the required relative tolerance for the residual error, `B - A * X'.  The iteration stops if `norm (B - A * X) <= TOL * norm (B - A * X0)'.  If TOL is empty or is omitted, the function sets `TOL = 1e-6' by default.
+
+        * MAXIT is the maximum allowable number of iterations; if `[]' is supplied for `maxit', or `pcr' has less arguments, a default value equal to 20 is used.
+
+        * M is the (left) preconditioning matrix, so that the iteration is (theoretically) equivalent to solving by `pcr' `P * X = M \ B', with `P = M \ A'.  Note that a proper choice of the preconditioner may dramatically improve the overall performance of the method.  Instead of matrix M, the user may pass a function which returns the results of applying the inverse of M to a vector (usually this is the preferred way of using the preconditioner).  If `[]' is supplied for M, or M is omitted, no preconditioning is applied.
+
+        * X0 is the initial guess.  If X0 is empty or omitted, the function sets X0 to a zero vector by default.
+
+     The arguments which follow X0 are treated as parameters, and passed in a proper way to any of the functions (A or M) which are passed to `pcr'.  See the examples below for further details.  The output arguments are
+
+        * X is the computed approximation to the solution of `A * X = B'.
+
+        * FLAG reports on the convergence.  `FLAG = 0' means the solution converged and the tolerance criterion given by TOL is satisfied.  `FLAG = 1' means that the MAXIT limit for the iteration count was reached.  `FLAG = 3' reports t `pcr' breakdown, see [1] for details.
+
+        * RELRES is the ratio of the final residual to its initial value, measured in the Euclidean norm.
+
+        * ITER is the actual number of iterations performed.
+
+        * RESVEC describes the convergence history of the method, so that `RESVEC (i)' contains the Euclidean norms of the residual after the (I-1)-th iteration, `I = 1,2, ..., ITER+1'.
+
+     Let us consider a trivial problem with a diagonal matrix (we exploit the sparsity of A)
+
+          	n = 10;
+          	a = sparse (diag (1:n));
+          	b = rand (N, 1);
+
+     EXAMPLE 1: Simplest use of `pcr'
+
+            x = pcr(A, b)
+
+     EXAMPLE 2: `pcr' with a function which computes `A * X'.
+
+            function y = apply_a (x)
+              y = [1:10]'.*x;
+            endfunction
+
+            x = pcr ("apply_a", b)
+
+     EXAMPLE 3:  Preconditioned iteration, with full diagnostics.  The preconditioner (quite strange, because even the original matrix A is trivial) is defined as a function
+
+            function y = apply_m (x)
+              k = floor (length(x)-2);
+              y = x;
+              y(1:k) = x(1:k)./[1:k]';
+            endfunction
+
+            [x, flag, relres, iter, resvec] = ...
+                               pcr (a, b, [], [], "apply_m")
+            semilogy([1:iter+1], resvec);
+
+     EXAMPLE 4: Finally, a preconditioner which depends on a parameter K.
+
+            function y = apply_m (x, varargin)
+              k = varargin{1};
+              y = x; y(1:k) = x(1:k)./[1:k]';
+            endfunction
+
+            [x, flag, relres, iter, resvec] = ...
+                               pcr (a, b, [], [], "apply_m"', [], 3)
+
+     REFERENCES
+
+     	[1] W. Hackbusch, "Iterative Solution of Large Sparse Systems of  	Equations", section 9.5.4; Springer, 1994
+
+     See also: sparse, pcg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+Solves the linear system of equations `A * X = B' by means of the Preconditioned Conjugate Residuals iterative method.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+spy
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 395
+ -- Function File:  spy (X)
+ -- Function File:  spy (..., MARKERSIZE)
+ -- Function File:  spy (..., LINE_SPEC)
+     Plot the sparsity pattern of the sparse matrix X.  If the argument MARKERSIZE is given as an scalar value, it is used to determine the point size in the plot.  If the string LINE_SPEC is given it is passed to `plot' and determines the appearance of the plot.  See also: plot.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Plot the sparsity pattern of the sparse matrix X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+spconvert
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 412
+ -- Function File: X = spconvert (M)
+     This function converts for a simple sparse matrix format easily produced by other programs into Octave's internal sparse format.  The input X is either a 3 or 4 column real matrix, containing the row, column, real and imaginary parts of the elements of the sparse matrix.  An element with a zero real and imaginary part can be used to force a particular matrix size.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+This function converts for a simple sparse matrix format easily produced by other programs into Octave's internal sparse format.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spalloc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 703
+ -- Function File: S = spalloc (R, C, NZ)
+     Returns an empty sparse matrix of size R-by-C.  As Octave resizes sparse matrices at the first opportunity, so that no additional space is needed, the argument NZ is ignored.  This function is provided only for compatibility reasons.
+
+     It should be noted that this means that code like
+
+          k = 5;
+          nz = r * k;
+          s = spalloc (r, c, nz)
+          for j = 1:c
+            idx = randperm (r);
+            s (:, j) = [zeros(r - k, 1); rand(k, 1)] (idx);
+          endfor
+
+     will reallocate memory at each step.  It is therefore vitally important that code like this is vectorized as much as possible.  See also: sparse, nzmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Returns an empty sparse matrix of size R-by-C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+svds
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1986
+ -- Function File: S = svds (A)
+ -- Function File: S = svds (A, K)
+ -- Function File: S = svds (A, K, SIGMA)
+ -- Function File: S = svds (A, K, SIGMA, OPTS)
+ -- Function File: [U, S, V, FLAG] = svds (...)
+     Find a few singular values of the matrix A.  The singular values are calculated using
+
+          [M, N] = size(A)
+          S = eigs([sparse(M, M), A; ...
+                          A', sparse(N, N)])
+
+     The eigenvalues returned by `eigs' correspond to the singular values of A.  The number of singular values to calculate is given by K, whose default value is 6.
+
+     The argument SIGMA can be used to specify which singular values to find.  SIGMA can be either the string 'L', the default, in which case the largest singular values of A are found.  Otherwise SIGMA should be a real scalar, in which case the singular values closest to SIGMA are found.  Note that for relatively small values of SIGMA, there is the chance that the requested number of singular values are not returned.  In that case SIGMA should be increased.
+
+     If OPTS is given, then it is a structure that defines options that `svds' will pass to EIGS.  The possible fields of this structure are therefore determined by `eigs'.  By default three fields of this structure are set by `svds'.
+
+    `tol'
+          The required convergence tolerance for the singular values.  `eigs' is passed TOL divided by `sqrt(2)'.  The default value is 1e-10.
+
+    `maxit'
+          The maximum number of iterations.  The default is 300.
+
+    `disp'
+          The level of diagnostic printout.  If `disp' is 0 then there is no printout.  The default value is 0.
+
+     If more than one output argument is given, then `svds' also calculates the left and right singular vectors of A.  FLAG is used to signal the convergence of `svds'.  If `svds' converges to the desired tolerance, then FLAG given by
+
+          norm (A * V - U * S, 1) <= ...
+                  TOL * norm (A, 1)
+
+     will be zero.
+   See also: eigs.  
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Find a few singular values of the matrix A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spdiags
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1036
+ -- Function File: [B, C] = spdiags (A)
+ -- Function File: B = spdiags (A, C)
+ -- Function File: B = spdiags (V, C, A)
+ -- Function File: B = spdiags (V, C, M, N)
+     A generalization of the function `diag'.  Called with a single input argument, the non-zero diagonals C of A are extracted.  With two arguments the diagonals to extract are given by the vector C.
+
+     The other two forms of `spdiags' modify the input matrix by replacing the diagonals.  They use the columns of V to replace the columns represented by the vector C.  If the sparse matrix A is defined then the diagonals of this matrix are replaced.  Otherwise a matrix of M by N is created with the diagonals given by V.
+
+     Negative values of C represent diagonals below the main diagonal, and positive values of C diagonals above the main diagonal.
+
+     For example
+
+          spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
+          =>    5 10  0  0
+                1  6 11  0
+                0  2  7 12
+                0  0  3  8
+                0  0  0  4
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+A generalization of the function `diag'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+spfun
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 235
+ -- Function File: Y = spfun (F,X)
+     Compute `f(X)' for the non-zero values of X.  This results in a sparse matrix with the same structure as X.  The function F can be passed as a string, a function handle or an inline function.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Compute `f(X)' for the non-zero values of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+colperm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 305
+ -- Function File: P = colperm (S)
+     Returns the column permutations such that the columns of `S (:, P)' are ordered in terms of increase number of non-zero elements.  If S is symmetric, then P is chosen such that `S (P, P)' orders the rows and columns with increasing number of non zeros elements.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 129
+Returns the column permutations such that the columns of `S (:, P)' are ordered in terms of increase number of non-zero elements.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+sprand
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 540
+ -- Function File:  sprand (M, N, D)
+ -- Function File:  sprand (S)
+     Generate a random sparse matrix.  The size of the matrix will be M by N, with a density of values given by D.  D should be between 0 and 1. Values will be uniformly distributed between 0 and 1.
+
+     Note: sometimes the actual density may be a bit smaller than D.  This is unlikely to happen for large really sparse matrices.
+
+     If called with a single matrix argument, a random sparse matrix is generated wherever the matrix S is non-zero.  See also: sprandn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Generate a random sparse matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+spaugment
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1264
+ -- Function File: S = spaugment (A, C)
+     Creates the augmented matrix of A.  This is given by
+
+          [C * eye(M, M),A; A', zeros(N,
+          N)]
+
+     This is related to the least squares solution of `A \\ B', by
+
+          S * [ R / C; x] = [B, zeros(N,
+          columns(B)]
+
+     where R is the residual error
+
+          R = B - A * X
+
+     As the matrix S is symmetric indefinite it can be factorized with `lu', and the minimum norm solution can therefore be found without the need for a `qr' factorization.  As the residual error will be `zeros (M, M)' for under determined problems, and example can be
+
+          m = 11; n = 10; mn = max(m ,n);
+          a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],
+                       [-1, 0, 1], m, n);
+          x0 = a \ ones (m,1);
+          s = spaugment (a);
+          [L, U, P, Q] = lu (s);
+          x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+          x1 = x1(end - n + 1 : end);
+
+     To find the solution of an overdetermined problem needs an estimate of the residual error R and so it is more complex to formulate a minimum norm solution using the `spaugment' function.
+
+     In general the left division operator is more stable and faster than using the `spaugment' function.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Creates the augmented matrix of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+speye
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 472
+ -- Function File: Y = speye (M)
+ -- Function File: Y = speye (M, N)
+ -- Function File: Y = speye (SZ)
+     Returns a sparse identity matrix.  This is significantly more efficient than `sparse (eye (M))' as the full matrix is not constructed.
+
+     Called with a single argument a square matrix of size M by M is created.  Otherwise a matrix of M by N is created.  If called with a single vector argument, this argument is taken to be the size of the matrix to create.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 33
+Returns a sparse identity matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+sprandn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 557
+ -- Function File:  sprandn (M, N, D)
+ -- Function File:  sprandn (S)
+     Generate a random sparse matrix.  The size of the matrix will be M by N, with a density of values given by D.  D should be between 0 and 1. Values will be normally distributed with mean of zero and variance 1.
+
+     Note: sometimes the actual density may be a bit smaller than D.  This is unlikely to happen for large really sparse matrices.
+
+     If called with a single matrix argument, a random sparse matrix is generated wherever the matrix S is non-zero.  See also: sprand.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Generate a random sparse matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+assert
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1302
+ -- Function File:  assert (COND)
+ -- Function File:  assert (COND, ERRMSG, ...)
+ -- Function File:  assert (COND, MSG_ID, ERRMSG, ...)
+ -- Function File:  assert (OBSERVED,EXPECTED)
+ -- Function File:  assert (OBSERVED,EXPECTED,TOL)
+     Produces an error if the condition is not met.  `assert' can be called in three different ways.
+
+    `assert (COND)'
+    `assert (COND, ERRMSG, ...)'
+    `assert (COND, MSG_ID, ERRMSG, ...)'
+          Called with a single argument COND, `assert' produces an error if COND is zero.  If called with a single argument a generic error message.  With more than one argument, the additional arguments are passed to the `error' function.
+
+    `assert (OBSERVED, EXPECTED)'
+          Produce an error if observed is not the same as expected.  Note that observed and expected can be strings, scalars, vectors, matrices, lists or structures.
+
+    `assert(OBSERVED, EXPECTED, TOL)'
+          Accept a tolerance when comparing numbers.  If TOL is positive use it as an absolute tolerance, will produce an error if `abs(OBSERVED - EXPECTED) > abs(TOL)'.  If TOL is negative use it as a relative tolerance, will produce an error if `abs(OBSERVED - EXPECTED) > abs(TOL * EXPECTED)'.  If EXPECTED is zero TOL will always be used as an absolute tolerance.
+     See also: test.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Produces an error if the condition is not met.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+rundemos
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+ -- Function File:  rundemos (DIRECTORY)
+   
+# name: <cell-element>
+# type: string
+# elements: 0
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+example
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 453
+ -- Function File:  example ('NAME',N)
+ -- Function File: [X, IDX] = example ('NAME',N)
+     Display the code for example N associated with the function 'NAME', but do not run it.  If N is not given, all examples are displayed.
+
+     Called with output arguments, the examples are returned in the form of a string X, with IDX indicating the ending position of the various examples.
+
+     See `demo' for a complete explanation.  See also: demo, test.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Display the code for example N associated with the function 'NAME', but do not run it.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+speed
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4706
+ -- Function File:  speed (F, INIT, MAX_N, F2, TOL)
+ -- Function File: [ORDER, N, T_F, T_F2] = speed (...)
+     Determine the execution time of an expression for various N.  The N are log-spaced from 1 to MAX_N.  For each N, an initialization expression is computed to create whatever data are needed for the test.  If a second expression is given, the execution times of the two expressions will be compared.  Called without output arguments the results are presented graphically.
+
+    `F'
+          The expression to evaluate.
+
+    `MAX_N'
+          The maximum test length to run.  Default value is 100.  Alternatively, use `[min_n,max_n]' or for complete control, `[n1,n2,...,nk]'.
+
+    `INIT'
+          Initialization expression for function argument values.  Use K for the test number and N for the size of the test.  This should compute values for all variables listed in args.  Note that init will be evaluated first for k = 0, so things which are constant throughout the test can be computed then.  The default value is `X = randn (N, 1);'.
+
+    `F2'
+          An alternative expression to evaluate, so the speed of the two can be compared.  Default is `[]'.
+
+    `TOL'
+          If TOL is `Inf', then no comparison will be made between the results of expression F and expression F2.  Otherwise, expression F should produce a value V and expression F2 should produce a value V2, and these shall be compared using `assert(V,V2,TOL)'.  If TOL is positive, the tolerance is assumed to be absolute.  If TOL is negative, the tolerance is assumed to be relative.  The default is `eps'.
+
+    `ORDER'
+          The time complexity of the expression `O(a n^p)'.  This is a structure with fields `a' and `p'.
+
+    `N'
+          The values N for which the expression was calculated and the execution time was greater than zero.
+
+    `T_F'
+          The nonzero execution times recorded for the expression F in seconds.
+
+    `T_F2'
+          The nonzero execution times recorded for the expression F2 in seconds.  If it is needed, the mean time ratio is just `mean(T_f./T_f2)'.
+
+
+     The slope of the execution time graph shows the approximate power of the asymptotic running time `O(n^p)'.  This power is plotted for the region over which it is approximated (the latter half of the graph).  The estimated power is not very accurate, but should be sufficient to determine the general order of your algorithm.  It should indicate if for example your implementation is unexpectedly `O(n^2)' rather than `O(n)' because it extends a vector each time through the loop rather than preallocating one which is big enough.  For example, in the current version of Octave, the following is not the expected `O(n)':
+
+          speed ("for i = 1:n, y{i} = x(i); end", "", [1000,10000])
+
+     but it is if you preallocate the cell array `y':
+
+          speed ("for i = 1:n, y{i} = x(i); end", ...
+                 "x = rand (n, 1); y = cell (size (x));", [1000, 10000])
+
+     An attempt is made to approximate the cost of the individual operations, but it is wildly inaccurate.  You can improve the stability somewhat by doing more work for each `n'.  For example:
+
+          speed ("airy(x)", "x = rand (n, 10)", [10000, 100000])
+
+     When comparing a new and original expression, the line on the speedup ratio graph should be larger than 1 if the new expression is faster.  Better algorithms have a shallow slope.  Generally, vectorizing an algorithm will not change the slope of the execution time graph, but it will shift it relative to the original.  For example:
+
+          speed ("v = sum (x)", "", [10000, 100000], ...
+                 "v = 0; for i = 1:length (x), v += x(i); end")
+
+     A more complex example, if you had an original version of `xcorr' using for loops and another version using an FFT, you could compare the run speed for various lags as follows, or for a fixed lag with varying vector lengths as follows:
+
+          speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100,
+                 "v2 = xcorr_orig (x, n)", -100*eps)
+          speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100,
+                 "v2 = xcorr_orig (x, n)", -100*eps)
+
+     Assuming one of the two versions is in XCORR_ORIG, this would compare their speed and their output values.  Note that the FFT version is not exact, so we specify an acceptable tolerance on the comparison `100*eps', and the errors should be computed relatively, as `abs((X - Y)./Y)' rather than absolutely as `abs(X - Y)'.
+
+     Type `example('speed')' to see some real examples.  Note for obscure reasons, you can't run examples 1 and 2 directly using `demo('speed')'.  Instead use, `eval(example('speed',1))' and `eval(example('speed',2))'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Determine the execution time of an expression for various N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2033
+ -- Function File:  test NAME
+ -- Function File:  test NAME quiet|normal|verbose
+ -- Function File:  test ('NAME', 'quiet|normal|verbose', FID)
+ -- Function File:  test ([], 'explain', FID)
+ -- Function File: SUCCESS = test (...)
+ -- Function File: [N, MAX] = test (...)
+ -- Function File: [CODE, IDX] = test ('NAME','grabdemo')
+     Perform tests from the first file in the loadpath matching NAME.  `test' can be called as a command or as a function.  Called with a single argument NAME, the tests are run interactively and stop after the first error is encountered.
+
+     With a second argument the tests which are performed and the amount of output is selected.
+
+    'quiet'
+          Don't report all the tests as they happen, just the errors.
+
+    'normal'
+          Report all tests as they happen, but don't do tests which require user interaction.
+
+    'verbose'
+          Do tests which require user interaction.
+
+     The argument FID can be used to allow batch processing.  Errors can be written to the already open file defined by FID, and hopefully when Octave crashes this file will tell you what was happening when it did.  You can use `stdout' if you want to see the results as they happen.  You can also give a file name rather than an FID, in which case the contents of the file will be replaced with the log from the current test.
+
+     Called with a single output argument SUCCESS, `test' returns true if all of the tests were successful.  Called with two output arguments N and MAX, the number of successful tests and the total number of tests in the file NAME are returned.
+
+     If the second argument is the string 'grabdemo', the contents of the demo blocks are extracted but not executed.  Code for all code blocks is concatenated and returned as CODE with IDX being a vector of positions of the ends of the demo blocks.
+
+     If the second argument is 'explain', then NAME is ignored and an explanation of the line markers used is written to the file FID.  See also: error, assert, fail, demo, example.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Perform tests from the first file in the loadpath matching NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+fail
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 715
+ -- Function File:  fail (CODE,PATTERN)
+ -- Function File:  fail (CODE,'warning',PATTERN)
+     Return true if CODE fails with an error message matching PATTERN, otherwise produce an error.  Note that CODE is a string and if CODE runs successfully, the error produced is:
+
+                    expected error but got none
+
+     If the code fails with a different error, the message produced is:
+
+                    expected <pattern>
+                    but got <text of actual error>
+
+     The angle brackets are not part of the output.
+
+     Called with three arguments, the behavior is similar to `fail(CODE, PATTERN)', but produces an error if no warning is given during code execution or if the code fails.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+Return true if CODE fails with an error message matching PATTERN, otherwise produce an error.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+demo
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1935
+ -- Function File:  demo ('NAME',N)
+     Runs any examples associated with the function 'NAME'.  Examples are stored in the script file, or in a file with the same name but no extension somewhere on your path.  To keep them separate from the usual script code, all lines are prefixed by `%!'.  Each example is introduced by the keyword 'demo' flush left to the prefix, with no intervening spaces.  The remainder of the example can contain arbitrary Octave code.  For example:
+
+             %!demo
+             %! t=0:0.01:2*pi; x = sin(t);
+             %! plot(t,x)
+             %! %-------------------------------------------------
+             %! % the figure window shows one cycle of a sine wave
+
+     Note that the code is displayed before it is executed, so a simple comment at the end suffices.  It is generally not necessary to use disp or printf within the demo.
+
+     Demos are run in a function environment with no access to external variables.  This means that all demos in your function must use separate initialization code.  Alternatively, you can combine your demos into one huge demo, with the code:
+
+             %! input("Press <enter> to continue: ","s");
+
+     between the sections, but this is discouraged.  Other techniques include using multiple plots by saying figure between each, or using subplot to put multiple plots in the same window.
+
+     Also, since demo evaluates inside a function context, you cannot define new functions inside a demo.  Instead you will have to use `eval(example('function',n))' to see them.  Because eval only evaluates one line, or one statement if the statement crosses multiple lines, you must wrap your demo in "if 1 <demo stuff> endif" with the 'if' on the same line as 'demo'.  For example,
+
+            %!demo if 1
+            %!  function y=f(x)
+            %!    y=x;
+            %!  endfunction
+            %!  f(3)
+            %! endif
+     See also: test, example.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Runs any examples associated with the function 'NAME'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+setdiff
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 522
+ -- Function File:  setdiff (A, B)
+ -- Function File:  setdiff (A, B, "rows")
+ -- Function File: [C, I] = setdiff (A, B)
+     Return the elements in A that are not in B, sorted in ascending order.  If A and B are both column vectors return a column vector, otherwise return a row vector.
+
+     Given the optional third argument `"rows"', return the rows in A that are not in B, sorted in ascending order by rows.
+
+     If requested, return I such that `c = a(i)'.  See also: unique, union, intersect, setxor, ismember.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+Return the elements in A that are not in B, sorted in ascending order.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+intersect
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 378
+ -- Function File:  intersect (A, B)
+ -- Function File: [C, IA, IB] = intersect (A, B)
+     Return the elements in both A and B, sorted in ascending order.  If A and B are both column vectors return a column vector, otherwise return a row vector.
+
+     Return index vectors IA and IB such that `a(ia)==c' and `b(ib)==c'.
+
+   See also: unique, union, setxor, setdiff, ismember.  
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return the elements in both A and B, sorted in ascending order.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+complement
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Function File:  complement (X, Y)
+     Return the elements of set Y that are not in set X.  For example,
+
+          complement ([ 1, 2, 3 ], [ 2, 3, 5 ])
+               => 5
+     See also: union, intersect, unique.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Return the elements of set Y that are not in set X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+union
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 675
+ -- Function File:  union (A, B)
+ -- Function File:  union (A, B, "rows")
+     Return the set of elements that are in either of the sets A and B.  For example,
+
+          union ([1, 2, 4], [2, 3, 5])
+               => [1, 2, 3, 4, 5]
+
+     If the optional third input argument is the string "rows" each row of the matrices A and B will be considered an element of sets.  For example,
+          union([1, 2; 2, 3], [1, 2; 3, 4], "rows")
+               =>  1   2
+              2   3
+              3   4
+
+ -- Function File: [C, IA, IB] = union (A, B)
+     Return index vectors IA and IB such that `a == c(ia)' and `b == c(ib)'.
+
+     See also: intersect, complement, unique.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return index vectors IA and IB such that `a == c(ia)' and `b == c(ib)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+unique
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 852
+ -- Function File:  unique (X)
+ -- Function File:  unique (X, "rows")
+ -- Function File:  unique (..., "first")
+ -- Function File:  unique (..., "last")
+ -- Function File: [Y, I, J] = unique (...)
+     Return the unique elements of X, sorted in ascending order.  If X is a row vector, return a row vector, but if X is a column vector or a matrix return a column vector.
+
+     If the optional argument `"rows"' is supplied, return the unique rows of X, sorted in ascending order.
+
+     If requested, return index vectors I and J such that `x(i)==y' and `y(j)==x'.
+
+     Additionally, one of `"first"' or `"last"' may be given as an argument.  If `"last"' is specified, return the highest possible indices in I, otherwise, if `"first"' is specified, return the lowest.  The default is `"last"'.  See also: union, intersect, setdiff, setxor, ismember.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Return the unique elements of X, sorted in ascending order.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ismember
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1133
+ -- Function File: [TF = ismember (A, S)
+ -- Function File: [TF, S_IDX] = ismember (A, S)
+ -- Function File: [TF, S_IDX] = ismember (A, S, "rows")
+     Return a matrix TF with the same shape as A which has a 1 if `A(i,j)' is in S and 0 if it is not.  If a second output argument is requested, the index into S of each of the matching elements is also returned.
+
+          a = [3, 10, 1];
+          s = [0:9];
+          [tf, s_idx] = ismember (a, s);
+               => tf = [1, 0, 1]
+               => s_idx = [4, 0, 2]
+
+     The inputs, A and S, may also be cell arrays.
+
+          a = {'abc'};
+          s = {'abc', 'def'};
+          [tf, s_idx] = ismember (a, s);
+               => tf = [1, 0]
+               => s_idx = [1, 0]
+
+     With the optional third argument `"rows"', and matrices A and S with the same number of columns, compare rows in A with the rows in S.
+
+          a = [1:3; 5:7; 4:6];
+          s = [0:2; 1:3; 2:4; 3:5; 4:6];
+          [tf, s_idx] = ismember(a, s, 'rows');
+               => tf = logical ([1; 0; 1])
+               => s_idx = [2; 0; 5];
+
+     See also: unique, union, intersect, setxor, setdiff.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Return a matrix TF with the same shape as A which has a 1 if `A(i,j)' is in S and 0 if it is not.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+setxor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 429
+ -- Function File:  setxor (A, B)
+ -- Function File:  setxor (A, B, 'rows')
+     Return the elements exclusive to A or B, sorted in ascending order.  If A and B are both column vectors return a column vector, otherwise return a row vector.
+
+ -- Function File: [C, IA, IB] = setxor (A, B)
+     Return index vectors IA and IB such that `a == c(ia)' and `b == c(ib)'.
+
+     See also: unique, union, intersect, setdiff, ismember.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Return index vectors IA and IB such that `a == c(ia)' and `b == c(ib)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+imfinfo
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2213
+ -- Function File: INFO = imfinfo (FILENAME)
+ -- Function File: INFO = imfinfo (URL)
+     Read image information from a file.
+
+     `imfinfo' returns a structure containing information about the image stored in the file FILENAME.  The output structure contains the following fields.
+
+    `Filename'
+          The full name of the image file.
+
+    `FileSize'
+          Number of bytes of the image on disk
+
+    `FileModDate'
+          Date of last modification to the file.
+
+    `Height'
+          Image height in pixels.
+
+    `Width'
+          Image Width in pixels.
+
+    `BitDepth'
+          Number of bits per channel per pixel.
+
+    `Format'
+          Image format (e.g., `"jpeg"').
+
+    `LongFormat'
+          Long form image format description.
+
+    `XResolution'
+          X resolution of the image.
+
+    `YResolution'
+          Y resolution of the image.
+
+    `TotalColors'
+          Number of unique colors in the image.
+
+    `TileName'
+          Tile name.
+
+    `AnimationDelay'
+          Time in 1/100ths of a second (0 to 65535) which must expire before displaying the next image in an animated sequence.
+
+    `AnimationIterations'
+          Number of iterations to loop an animation (e.g., Netscape loop extension) for.
+
+    `ByteOrder'
+          Endian option for formats that support it.  Is either `"little-endian"', `"big-endian"', or `"undefined"'.
+
+    `Gamma'
+          Gamma level of the image.  The same color image displayed on two different workstations may look different due to differences in the display monitor.
+
+    `Matte'
+          `true' if the image has transparency.
+
+    `ModulusDepth'
+          Image modulus depth (minimum number of bits required to support red/green/blue components without loss of accuracy).
+
+    `Quality'
+          JPEG/MIFF/PNG compression level.
+
+    `QuantizeColors'
+          Preferred number of colors in the image.
+
+    `ResolutionUnits'
+          Units of image resolution.  Is either `"pixels per inch"', `"pixels per centimeter"', or `"undefined"'.
+
+    `ColorType'
+          Image type.  Is either `"grayscale"', `"indexed"', `"truecolor"', or `"undefined"'.
+
+    `View'
+          FlashPix viewing parameters.
+
+     See also: imread, imwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Read image information from a file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+imread
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 473
+ -- Function File: [IMG, MAP, ALPHA] = imread (FILENAME)
+     Read images from various file formats.
+
+     The size and numeric class of the output depends on the format of the image.  A color image is returned as an MxNx3 matrix.  Grey-level and black-and-white images are of size MxN.  The color depth of the image determines the numeric class of the output: "uint8" or "uint16" for grey and color, and "logical" for black and white.
+
+     See also: imwrite, imfinfo.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Read images from various file formats.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+brighten
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 677
+ -- Function File: MAP_OUT = brighten (MAP, BETA)
+ -- Function File: MAP_OUT = brighten (H, BETA)
+ -- Function File: MAP_OUT = brighten (BETA)
+     Darkens or brightens the given colormap.  If the MAP argument is omitted, the function is applied to the current colormap.  The first argument can also be a valid graphics handle H, in which case `brighten' is applied to the colormap associated with this handle.
+
+     Should the resulting colormap MAP_OUT not be assigned, it will be written to the current colormap.
+
+     The argument BETA should be a scalar between -1 and 1, where a negative value darkens and a positive value brightens the colormap.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Darkens or brightens the given colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gmap40
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 444
+ -- Function File:  gmap40 (N)
+     Create a color colormap.  The colormap is red, green, blue, yellow, magenta and cyan.  These are the colors that are allowed with patch objects using gnuplot 4.0, and so this colormap function is specially designed for users of gnuplot 4.0.  The argument N should be a scalar.  If it is omitted, a length of 6 is assumed.  Larger values of N result in a repetition of the above colors See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+Create a color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+imshow
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1061
+ -- Function File:  imshow (IM)
+ -- Function File:  imshow (IM, LIMITS)
+ -- Function File:  imshow (IM, MAP)
+ -- Function File:  imshow (RGB, ...)
+ -- Function File:  imshow (FILENAME)
+ -- Function File:  imshow (..., STRING_PARAM1, VALUE1, ...)
+     Display the image IM, where IM can be a 2-dimensional (gray-scale image) or a 3-dimensional (RGB image) matrix.
+
+     If LIMITS is a 2-element vector `[LOW, HIGH]', the image is shown using a display range between LOW and HIGH.  If an empty matrix is passed for LIMITS, the display range is computed as the range between the minimal and the maximal value in the image.
+
+     If MAP is a valid color map, the image will be shown as an indexed image using the supplied color map.
+
+     If a file name is given instead of an image, the file will be read and shown.
+
+     If given, the parameter STRING_PARAM1 has value VALUE1.  STRING_PARAM1 can be any of the following:
+    `"displayrange"'
+          VALUE1 is the display range as described above.
+     See also: image, imagesc, colormap, gray2ind, rgb2ind.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Display the image IM, where IM can be a 2-dimensional (gray-scale image) or a 3-dimensional (RGB image) matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+gray2ind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Function File: [IMG, MAP] = gray2ind (I, N)
+     Convert a gray scale intensity image to an Octave indexed image.  The indexed image will consist of N different intensity values.  If not given N will default to 64.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Convert a gray scale intensity image to an Octave indexed image.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spring
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 228
+ -- Function File:  spring (N)
+     Create color colormap.  This colormap is magenta to yellow.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+winter
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 224
+ -- Function File:  winter (N)
+     Create color colormap.  This colormap is blue to green.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+prism
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 264
+ -- Function File:  prism (N)
+     Create color colormap.  This colormap cycles trough red, orange, yellow, green, blue and violet.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+gray
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Function File:  gray (N)
+     Return a gray colormap with N entries corresponding to values from 0 to N-1.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Return a gray colormap with N entries corresponding to values from 0 to N-1.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+autumn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 239
+ -- Function File:  autumn (N)
+     Create color colormap.  This colormap is red through orange to yellow.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ind2gray
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 238
+ -- Function File:  ind2gray (X, MAP)
+     Convert an Octave indexed image to a gray scale intensity image.  If MAP is omitted, the current colormap is used to determine the intensities.  See also: gray2ind, rgb2ntsc, image, colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Convert an Octave indexed image to a gray scale intensity image.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+flag
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 247
+ -- Function File:  flag (N)
+     Create color colormap.  This colormap cycles through red, white, blue and black.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+saveimage
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 891
+ -- Function File:  saveimage (FILE, X, FMT, MAP)
+     Save the matrix X to FILE in image format FMT.  Valid values for FMT are
+
+    `"img"'
+          Octave's image format.  The current colormap is also saved in the file.
+
+    `"ppm"'
+          Portable pixmap format.
+
+    `"ps"'
+          PostScript format.  Note that images saved in PostScript format cannot be read back into Octave with loadimage.
+
+     If the fourth argument is supplied, the specified colormap will also be saved along with the image.
+
+     Note: if the colormap contains only two entries and these entries are black and white, the bitmap ppm and PostScript formats are used.  If the image is a gray scale image (the entries within each row of the colormap are equal) the gray scale ppm and PostScript image formats are used, otherwise the full color formats are used.  See also: loadimage, save, load, colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+Save the matrix X to FILE in image format FMT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+ntsc2rgb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+ -- Function File:  ntsc2rgb (YIQ)
+     Transform a colormap or image from NTSC to RGB.  See also: rgb2ntsc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Transform a colormap or image from NTSC to RGB.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ind2rgb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 376
+ -- Function File: RGB = ind2rgb (X, MAP)
+ -- Function File: [R, G, B] = ind2rgb (X, MAP)
+     Convert an indexed image to red, green, and blue color components.  If the colormap doesn't contain enough colors, pad it with the last color in the map.  If MAP is omitted, the current colormap is used for the conversion.  See also: rgb2ind, image, imshow, ind2gray, gray2ind.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Convert an indexed image to red, green, and blue color components.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rgb2ind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 179
+ -- Function File: [X, MAP] = rgb2ind (RGB)
+ -- Function File: [X, MAP] = rgb2ind (R, G, B)
+     Convert an RGB image to an Octave indexed image.  See also: ind2rgb, rgb2ntsc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Convert an RGB image to an Octave indexed image.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+jet
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 268
+ -- Function File:  jet (N)
+     Create color colormap.  This colormap is dark blue through blue, cyan, green, yellow, red to dark red.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+hot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 260
+ -- Function File:  hot (N)
+     Create color colormap.  This colormap is black through dark red, red, orange, yellow to white.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+colormap
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 580
+ -- Function File:  colormap (MAP)
+ -- Function File:  colormap ("default")
+     Set the current colormap.
+
+     `colormap (MAP)' sets the current colormap to MAP.  The color map should be an N row by 3 column matrix.  The columns contain red, green, and blue intensities respectively.  All entries should be between 0 and 1 inclusive.  The new colormap is returned.
+
+     `colormap ("default")' restores the default colormap (the `jet' map with 64 entries).  The default colormap is returned.
+
+     With no arguments, `colormap' returns the current color map.  See also: jet.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+Set the current colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ocean
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 169
+ -- Function File:  ocean (N)
+     Create color colormap.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+bone
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 247
+ -- Function File:  bone (N)
+     Create color colormap.  This colormap is a gray colormap with a light blue tone.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rgb2hsv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 461
+ -- Function File: HSV_MAP = rgb2hsv (RGB_MAP)
+     Transform a colormap or image from the rgb space to the hsv space.
+
+     A color n the RGB space consists of the red, green and blue intensities.
+
+     In the HSV space each color is represented by their hue, saturation and value (brightness).  Value gives the amount of light in the color.  Hue describes the dominant wavelength.  Saturation is the amount of Hue mixed into the color.  See also: hsv2rgb.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Transform a colormap or image from the rgb space to the hsv space.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+cool
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 223
+ -- Function File:  cool (N)
+     Create color colormap.  The colormap is cyan to magenta.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+rainbow
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 261
+ -- Function File:  rainbow (N)
+     Create color colormap.  This colormap is red through orange, yellow, green, blue to violet.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+imagesc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 686
+ -- Function File:  imagesc (A)
+ -- Function File:  imagesc (X, Y, A)
+ -- Function File:  imagesc (..., LIMITS)
+ -- Function File:  imagesc (H, ...)
+ -- Function File: H = imagesc (...)
+     Display a scaled version of the matrix A as a color image.  The colormap is scaled so that the entries of the matrix occupy the entire colormap.  If LIMITS = [LO, HI] are given, then that range is set to the 'clim' of the current axes.
+
+     The axis values corresponding to the matrix elements are specified in X and Y, either as pairs giving the minimum and maximum values for the respective axes, or as values for each row and column of the matrix A.
+
+     See also: image, imshow, caxis.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Display a scaled version of the matrix A as a color image.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+summer
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 226
+ -- Function File:  summer (N)
+     Create color colormap.  This colormap is green to yellow.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+hsv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 454
+ -- Function File:  hsv (N)
+     Create color colormap.  This colormap is red through yellow, green, cyan, blue, magenta to red.  It is obtained by linearly varying the hue through all possible values while keeping constant maximum saturation and value and is equivalent to `hsv2rgb ([linspace(0,1,N)', ones(N,2)])'.
+
+     The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+image
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 665
+ -- Function File:  image (IMG)
+ -- Function File:  image (X, Y, IMG)
+     Display a matrix as a color image.  The elements of X are indices into the current colormap, and the colormap will be scaled so that the extremes of X are mapped to the extremes of the colormap.
+
+     It first tries to use `gnuplot', then `display' from `ImageMagick', then `xv', and then `xloadimage'.  The actual program used can be changed using the `image_viewer' function.
+
+     The axis values corresponding to the matrix elements are specified in X and Y.  If you're not using gnuplot 4.2 or later, these variables are ignored.  See also: imshow, imagesc, colormap, image_viewer.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Display a matrix as a color image.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+white
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 226
+ -- Function File:  white (N)
+     Create color colormap.  This colormap is completely white.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+image_viewer
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1707
+ -- Function File: [FCN, DEFAULT_ZOOM] = image_viewer (FCN, DEFAULT_ZOOM)
+     Change the program or function used for viewing images and return the previous values.
+
+     When the `image' or `imshow' function is called it will launch an external program to display the image.  The default behavior is to use gnuplot if the installed version supports image viewing, and otherwise try the programs `display', `xv', and `xloadimage'.  Using this function it is possible to change that behavior.
+
+     When called with one input argument images will be displayed by saving the image to a file and the system command COMMAND will be called to view the image.  The COMMAND must be a string containing `%s' and possibly `%f'.  The `%s' will be replaced by the filename of the image, and the `%f' will (if present) be replaced by the zoom factor given to the `image' function.  For example,
+          image_viewer ("eog %s");
+     changes the image viewer to the `eog' program.
+
+     With two input arguments, images will be displayed by calling the function FUNCTION_HANDLE.  For example,
+          image_viewer (data, @my_image_viewer);
+     sets the image viewer function to `my_image_viewer'.  The image viewer function is called with
+          my_image_viewer (X, Y, IM, ZOOM, DATA)
+     where X and Y are the axis of the image, IM is the image variable, and DATA is extra user-supplied data to be passed to the viewer function.
+
+     With three input arguments it is possible to change the zooming.  Some programs (like `xloadimage') require the zoom factor to be between 0 and 100, and not 0 and 1 like Octave assumes.  This is solved by setting the third argument to 100.
+
+     See also: image, imshow.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Change the program or function used for viewing images and return the previous values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hsv2rgb
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 142
+ -- Function File: RGB_MAP = hsv2rgb (HSV_MAP)
+     Transform a colormap or image from the hsv space to the rgb space.  See also: rgb2hsv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Transform a colormap or image from the hsv space to the rgb space.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+imwrite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 627
+ -- Function File:  imwrite (IMG, FILENAME, FMT, P1, V1, ...)
+ -- Function File:  imwrite (IMG, MAP, FILENAME, FMT, P1, V1, ...)
+     Write images in various file formats.
+
+     If FMT is missing, the file extension (if any) of FILENAME is used to determine the format.
+
+     The parameter-value pairs (P1, V1, ...) are optional.  Currently the following options are supported for JPEG images
+
+    `Quality'
+          Sets the quality of the compression.  The corresponding value should be an integer between 0 and 100, with larger values meaning higher visual quality and less compression.
+
+     See also: imread, imfinfo.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Write images in various file formats.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+contrast
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 246
+ -- Function File:  contrast (X, N)
+     Return a gray colormap that maximizes the contrast in an image.  The returned colormap will have N rows.  If N is not defined then the size of the current colormap is used instead.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return a gray colormap that maximizes the contrast in an image.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+rgb2ntsc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 112
+ -- Function File:  rgb2ntsc (RGB)
+     Transform a colormap or image from RGB to NTSC.  See also: ntsc2rgb.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Transform a colormap or image from RGB to NTSC.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+pink
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 250
+ -- Function File:  pink (N)
+     Create color colormap.  This colormap gives a sepia tone on black and white images.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+copper
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 239
+ -- Function File:  copper (N)
+     Create color colormap.  This colormap is black to a light copper tone.  The argument N should be a scalar.  If it is omitted, the length of the current colormap or 64 is assumed.  See also: colormap.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Create color colormap.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+reallog
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 205
+ -- Function File:  reallog (X)
+     Return the real-valued natural logarithm of each element of X.  Report an error if any element results in a complex return value.  See also: log, realpow, realsqrt.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Return the real-valued natural logarithm of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+factor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 346
+ -- Function File: P = factor (Q)
+ -- Function File: [P, N] = factor (Q)
+     Return prime factorization of Q.  That is, `prod (P) == Q' and every element of P is a prime number.  If `Q == 1', returns 1.
+
+     With two output arguments, return the unique primes P and their multiplicities.  That is, `prod (P .^ N) == Q'.  See also: gcd, lcm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return prime factorization of Q.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+legendre
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2244
+ -- Function File: L = legendre (N, X)
+ -- Function File: L = legendre (N, X, NORMALIZATION)
+     Compute the Legendre function of degree N and order M = 0 ... N.  The optional argument, NORMALIZATION, may be one of `"unnorm"', `"sch"', or `"norm"'.  The default is `"unnorm"'.  The value of N must be a non-negative scalar integer.
+
+     If the optional argument NORMALIZATION is missing or is `"unnorm"', compute the Legendre function of degree N and order M and return all values for M = 0 ... N.  The return value has one dimension more than X.
+
+     The Legendre Function of degree N and order M:
+
+           m        m       2  m/2   d^m
+          P(x) = (-1) * (1-x  )    * ----  P (x)
+           n                         dx^m   n
+
+     with Legendre polynomial of degree N:
+
+                    1     d^n   2    n
+          P (x) = ------ [----(x - 1)  ]
+           n      2^n n!  dx^n
+
+     `legendre (3, [-1.0, -0.9, -0.8])' returns the matrix:
+
+           x  |   -1.0   |   -0.9   |  -0.8
+          ------------------------------------
+          m=0 | -1.00000 | -0.47250 | -0.08000
+          m=1 |  0.00000 | -1.99420 | -1.98000
+          m=2 |  0.00000 | -2.56500 | -4.32000
+          m=3 |  0.00000 | -1.24229 | -3.24000
+
+     If the optional argument `normalization' is `"sch"', compute the Schmidt semi-normalized associated Legendre function.  The Schmidt semi-normalized associated Legendre function is related to the unnormalized Legendre functions by the following:
+
+     For Legendre functions of degree n and order 0:
+
+            0       0
+          SP (x) = P (x)
+            n       n
+
+     For Legendre functions of degree n and order m:
+
+            m       m          m    2(n-m)! 0.5
+          SP (x) = P (x) * (-1)  * [-------]
+            n       n               (n+m)!
+
+     If the optional argument NORMALIZATION is `"norm"', compute the fully normalized associated Legendre function.  The fully normalized associated Legendre function is related to the unnormalized Legendre functions by the following:
+
+     For Legendre functions of degree N and order M
+
+            m       m          m    (n+0.5)(n-m)! 0.5
+          NP (x) = P (x) * (-1)  * [-------------]
+            n       n                   (n+m)!
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Compute the Legendre function of degree N and order M = 0 .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+betai
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 221
+ -- Function File:  betai (A, B, X)
+     This function is provided for compatibility with older versions of Octave.  New programs should use betainc instead.
+
+     `betai (A, B, X)' is the same as `betainc (X, A, B)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+This function is provided for compatibility with older versions of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+perms
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 353
+ -- Function File:  perms (V)
+     Generate all permutations of V, one row per permutation.  The result has size `factorial (N) * N', where N is the length of V.
+
+     As an example, `perms([1, 2, 3])' returns the matrix
+            1   2   3
+            2   1   3
+            1   3   2
+            2   3   1
+            3   1   2
+            3   2   1
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Generate all permutations of V, one row per permutation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+realsqrt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Function File:  realsqrt (X)
+     Return the real-valued square root of each element of X.  Report an error if any element results in a complex return value.  See also: sqrt, realpow, reallog.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Return the real-valued square root of each element of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isprime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 375
+ -- Function File:  isprime (N)
+     Return true if N is a prime number, false otherwise.
+
+     Something like the following is much faster if you need to test a lot of small numbers:
+
+             T = ismember (N, primes (max (N (:))));
+
+     If max(n) is very large, then you should be using special purpose factorization code.
+
+     See also: primes, factor, gcd, lcm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Return true if N is a prime number, false otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+factorial
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 328
+ -- Function File:  factorial (N)
+     Return the factorial of N where N is a positive integer.  If N is a scalar, this is equivalent to `prod (1:N)'.  For vector or matrix arguments, return the factorial of each element in the array.  For non-integers see the generalized factorial function `gamma'.  See also: prod, gamma.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Return the factorial of N where N is a positive integer.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+erfinv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+ -- Mapping Function:  erfinv (Z)
+     Computes the inverse of the error function.  See also: erf, erfc.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Computes the inverse of the error function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+betaln
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 192
+ -- Mapping Function:  betaln (A, B)
+     Return the log of the Beta function,
+
+          betaln (a, b) = gammaln (a) + gammaln (b) - gammaln (a + b)
+     See also: beta, betainc, gammaln.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return the log of the Beta function, 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+realpow
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 237
+ -- Function File:  realpow (X, Y)
+     Compute the real-valued, element-by-element power operator.  This is equivalent to `X .^ Y', except that `realpow' reports an error if any return value is complex.  See also: reallog, realsqrt.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 59
+Compute the real-valued, element-by-element power operator.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bessel
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2013
+ -- Loadable Function: [J, IERR] = besselj (ALPHA, X, OPT)
+ -- Loadable Function: [Y, IERR] = bessely (ALPHA, X, OPT)
+ -- Loadable Function: [I, IERR] = besseli (ALPHA, X, OPT)
+ -- Loadable Function: [K, IERR] = besselk (ALPHA, X, OPT)
+ -- Loadable Function: [H, IERR] = besselh (ALPHA, K, X, OPT)
+     Compute Bessel or Hankel functions of various kinds:
+
+    `besselj'
+          Bessel functions of the first kind.  If the argument OPT is supplied, the result is multiplied by `exp(-abs(imag(x)))'.
+
+    `bessely'
+          Bessel functions of the second kind.  If the argument OPT is supplied, the result is multiplied by `exp(-abs(imag(x)))'.
+
+    `besseli'
+          Modified Bessel functions of the first kind.  If the argument OPT is supplied, the result is multiplied by `exp(-abs(real(x)))'.
+
+    `besselk'
+          Modified Bessel functions of the second kind.  If the argument OPT is supplied, the result is multiplied by `exp(x)'.
+
+    `besselh'
+          Compute Hankel functions of the first (K = 1) or second (K = 2) kind.  If the argument OPT is supplied, the result is multiplied by `exp (-I*X)' for K = 1 or `exp (I*X)' for K = 2.
+
+     If ALPHA is a scalar, the result is the same size as X.  If X is a scalar, the result is the same size as ALPHA.  If ALPHA is a row vector and X is a column vector, the result is a matrix with `length (X)' rows and `length (ALPHA)' columns.  Otherwise, ALPHA and X must conform and the result will be the same size.
+
+     The value of ALPHA must be real.  The value of X may be complex.
+
+     If requested, IERR contains the following status information and is the same size as the result.
+
+       0. Normal return.
+
+       1. Input error, return `NaN'.
+
+       2. Overflow, return `Inf'.
+
+       3. Loss of significance by argument reduction results in less than half of machine accuracy.
+
+       4. Complete loss of significance by argument reduction, return `NaN'.
+
+       5. Error--no computation, algorithm termination condition not met, return `NaN'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Compute Bessel or Hankel functions of various kinds: 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+gammai
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 218
+ -- Function File:  gammai (A, X)
+     This function is provided for compatibility with older versions of Octave.  New programs should use `gammainc' instead.
+
+     `gammai (A, X)' is the same as `gammainc (X, A)'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+This function is provided for compatibility with older versions of Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+primes
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 407
+ -- Function File:  primes (N)
+     Return all primes up to N.
+
+     The algorithm used is the Sieve of Erastothenes.
+
+     Note that if you need a specific number of primes you can use the fact the distance from one prime to the next is, on average, proportional to the logarithm of the prime.  Integrating, one finds that there are about k primes less than k*log(5*k).  See also: list_primes, isprime.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Return all primes up to N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+pow2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 209
+ -- Mapping Function:  pow2 (X)
+ -- Mapping Function:  pow2 (F, E)
+     With one argument, computes 2 .^ x for each element of X.
+
+     With two arguments, returns f .* (2 .^ e).  See also: log2, nextpow2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+With one argument, computes 2 .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+beta
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 147
+ -- Mapping Function:  beta (A, B)
+     For real inputs, return the Beta function,
+
+          beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+For real inputs, return the Beta function, 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+nchoosek
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 777
+ -- Function File: C = nchoosek (N, K)
+     Compute the binomial coefficient or all combinations of N.  If N is a scalar then, calculate the binomial coefficient of N and K, defined as
+
+           /   \
+           | n |    n (n-1) (n-2) ... (n-k+1)       n!
+           |   |  = ------------------------- =  ---------
+           | k |               k!                k! (n-k)!
+           \   /
+
+     If N is a vector generate all combinations of the elements of N, taken K at a time, one row per combination.  The resulting C has size `[nchoosek (length (N), K), K]'.
+
+     `nchoosek' works only for non-negative integer arguments; use `bincoeff' for non-integer scalar arguments and for using vector arguments to compute many coefficients at once.
+
+     See also: bincoeff.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Compute the binomial coefficient or all combinations of N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+wavread
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 765
+ -- Function File: Y = wavread (FILENAME)
+     Load the RIFF/WAVE sound file FILENAME, and return the samples in vector Y.  If the file contains multichannel data, then Y is a matrix with the channels represented as columns.
+
+ -- Function File: [Y, FS, BITS] = wavread (FILENAME)
+     Additionally return the sample rate (FS) in Hz and the number of bits per sample (BITS).
+
+ -- Function File: [...] = wavread (FILENAME, N)
+     Read only the first N samples from each channel.
+
+ -- Function File: [...] = wavread (FILENAME,[N1 N2])
+     Read only samples N1 through N2 from each channel.
+
+ -- Function File: [SAMPLES, CHANNELS] = wavread (FILENAME, "size")
+     Return the number of samples (N) and channels (CH) instead of the audio data.  See also: wavwrite.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Return the number of samples (N) and channels (CH) instead of the audio data.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+lin2mu
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 383
+ -- Function File:  lin2mu (X, N)
+     Converts audio data from linear to mu-law.  Mu-law values use 8-bit unsigned integers.  Linear values use N-bit signed integers or floating point values in the range -1<=X<=1 if N is 0.  If N is not specified it defaults to 0, 8 or 16 depending on the range values in X.  See also: mu2lin, loadaudio, saveaudio, playaudio, setaudio, record.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Converts audio data from linear to mu-law.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+setaudio
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+ -- Function File:  setaudio ([W_TYPE [, VALUE]])
+     Execute the shell command `mixer [W_TYPE [, VALUE]]'
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Execute the shell command `mixer [W_TYPE [, VALUE]]'  
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+record
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 339
+ -- Function File:  record (SEC, SAMPLING_RATE)
+     Records SEC seconds of audio input into the vector X.  The default value for SAMPLING_RATE is 8000 samples per second, or 8kHz.  The program waits until the user types <RET> and then immediately starts to record.  See also: lin2mu, mu2lin, loadaudio, saveaudio, playaudio, setaudio.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Records SEC seconds of audio input into the vector X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mu2lin
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 341
+ -- Function File:  mu2lin (X, BPS)
+     Converts audio data from linear to mu-law.  Mu-law values are 8-bit unsigned integers.  Linear values use N-bit signed integers or floating point values in the range -1<=y<=1 if N is 0.  If N is not specified it defaults to 8.  See also: lin2mu, loadaudio, saveaudio, playaudio, setaudio, record.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Converts audio data from linear to mu-law.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+saveaudio
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 357
+ -- Function File:  saveaudio (NAME, X, EXT, BPS)
+     Saves a vector X of audio data to the file `NAME.EXT'.  The optional parameters EXT and BPS determine the encoding and the number of bits per sample used in the audio file (see `loadaudio');  defaults are `lin' and 8, respectively.  See also: lin2mu, mu2lin, loadaudio, playaudio, setaudio, record.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Saves a vector X of audio data to the file `NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+wavwrite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 389
+ -- Function File:  wavwrite (Y, FILENAME)
+ -- Function File:  wavwrite (Y, FS, FILENAME)
+ -- Function File:  wavwrite (Y, FS, BITS, FILENAME)
+     Write Y to the canonical RIFF/WAVE sound file FILENAME with sample rate FS and bits per sample BITS.  The default sample rate is 8000 Hz with 16-bits per sample.  Each column of the data represents a separate channel.  See also: wavread.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+Write Y to the canonical RIFF/WAVE sound file FILENAME with sample rate FS and bits per sample BITS.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+playaudio
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 225
+ -- Function File:  playaudio (NAME, EXT)
+ -- Function File:  playaudio (X)
+     Plays the audio file `NAME.EXT' or the audio data stored in the vector X.  See also: lin2mu, mu2lin, loadaudio, saveaudio, setaudio, record.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 27
+Plays the audio file `NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+loadaudio
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 509
+ -- Function File:  loadaudio (NAME, EXT, BPS)
+     Loads audio data from the file `NAME.EXT' into the vector X.
+
+     The extension EXT determines how the data in the audio file is interpreted;  the extensions `lin' (default) and `raw' correspond to linear, the extensions `au', `mu', or `snd' to mu-law encoding.
+
+     The argument BPS can be either 8 (default) or 16, and specifies the number of bits per sample used in the audio file.  See also: lin2mu, mu2lin, saveaudio, playaudio, setaudio, record.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Loads audio data from the file `NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+lookfor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1152
+ -- Command: lookfor STR
+ -- Command: lookfor -all STR
+ -- Function: [FUNC, HELPSTRING] = lookfor (STR)
+ -- Function: [FUNC, HELPSTRING] = lookfor ('-all', STR)
+     Search for the string STR in all functions found in the current function search path.  By default, `lookfor' searches for STR in the first sentence of the help string of each function found.  The entire help text of each function can be searched if the '-all' argument is supplied.  All searches are case insensitive.
+
+     Called with no output arguments, `lookfor' prints the list of matching functions to the terminal.  Otherwise, the output arguments FUNC and HELPSTRING define the matching functions and the first sentence of each of their help strings.
+
+     The ability of `lookfor' to correctly identify the first sentence of the help text is dependent on the format of the function's help.  All Octave core functions are correctly formatted, but the same can not be guaranteed for external packages and user-supplied functions.  Therefore, the use of the '-all' argument may be necessary to find related functions that are not a part of Octave.  See also: help, doc, which.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 85
+Search for the string STR in all functions found in the current function search path.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 13
+gen_doc_cache
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 441
+ -- Function File: gen_doc_cache (OUT_FILE, DIRECTORY)
+     Generate documentation caches for all functions in a given directory.
+
+     A documentation cache is generated for all functions in DIRECTORY.  The resulting cache is saved in the file OUT_FILE.  The cache is used to speed up `lookfor'.
+
+     If no directory is given (or it is the empty matrix), a cache for builtin operators, etc. is generated.
+
+     See also: lookfor, path.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Generate documentation caches for all functions in a given directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+get_first_help_sentence
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 837
+ -- Function File: [RETVAL, STATUS] = get_first_help_sentence (NAME, MAX_LEN)
+     Return the first sentence of a function help text.
+
+     The function reads the first sentence of the help text of the function NAME.  The first sentence is defined as the text after the function declaration until either the first period (".") or the first appearance of two consecutive end-lines ("\n\n").  The text is truncated to a maximum length of MAX_LEN, which defaults to 80.
+
+     The optional output argument STATUS returns the status reported by `makeinfo'.  If only one output argument is requested, and STATUS is non-zero, a warning is displayed.
+
+     As an example, the first sentence of this help text is
+
+          get_first_help_sentence ("get_first_help_sentence")
+          -| ans = Return the first sentence of a function help text.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Return the first sentence of a function help text.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+help
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 501
+ -- Command: help NAME
+     Display the help text for NAME.  If invoked without any arguments, `help' prints a list of all the available operators and functions.
+
+     For example, the command `help help' prints a short message describing the `help' command.
+
+     The help command can give you information about operators, but not the comma and semicolons that are used as command separators.  To get help for those, you must type `help comma' or `help semicolon'.  See also: doc, lookfor, which.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Display the help text for NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+type
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 411
+ -- Command: type options name ...
+     Display the definition of each NAME that refers to a function.
+
+     Normally also displays whether each NAME is user-defined or built-in; the `-q' option suppresses this behavior.
+
+     If an output argument is requested nothing is displayed.  Instead, a cell array of strings is returned, where each element corresponds to the definition of each requested function.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 62
+Display the definition of each NAME that refers to a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+which
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 180
+ -- Command: which name ...
+     Display the type of each NAME.  If NAME is defined from a function file, the full name of the file is also displayed.  See also: help, lookfor.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Display the type of each NAME.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+print_usage
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 267
+ -- Function File:  print_usage ()
+ -- Function File:  print_usage (NAME)
+     Print the usage message for a function.  When called with no input arguments the `print_usage' function displays the usage message of the currently executing function.  See also: help.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Print the usage message for a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+doc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 495
+ -- Command: doc FUNCTION_NAME
+     Display documentation for the function FUNCTION_NAME directly from an on-line version of the printed manual, using the GNU Info browser.  If invoked without any arguments, the manual is shown from the beginning.
+
+     For example, the command `doc rand' starts the GNU Info browser at the `rand' node in the on-line version of the manual.
+
+     Once the GNU Info browser is running, help for using it is available using the command `C-h'.  See also: help.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 136
+Display documentation for the function FUNCTION_NAME directly from an on-line version of the printed manual, using the GNU Info browser.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+savepath
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 306
+ -- Function File:  savepath (FILE)
+     Save the portion of the current function search path, that is not set during Octave's initialization process, to FILE.  If FILE is omitted, `~/.octaverc' is used.  If successful, `savepath' returns 0.  See also: path, addpath, rmpath, genpath, pathdef, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+Save the portion of the current function search path, that is not set during Octave's initialization process, to FILE.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+pathdef
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 393
+ -- Function File: VAL = pathdef ()
+     Return the default path for Octave.  The path information is extracted from one of three sources.  In order of preference, those are;
+
+       1. `~/.octaverc'
+
+       2. `<octave-home>/.../<version>/m/startup/octaverc'
+
+       3. Octave's path prior to changes by any octaverc.
+          See also: path, addpath, rmpath, genpath, savepath, pathsep.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Return the default path for Octave.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+matlabroot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+ -- Function File: VAL = matlabroot ()
+     Return the location of Octave's home.  See also: OCTAVE_HOME.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Return the location of Octave's home.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+ind2sub
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 414
+ -- Function File: [S1, S2, ..., SN] = ind2sub (DIMS, IND)
+     Convert a linear index into subscripts.
+
+     The following example shows how to convert the linear index `8' in a 3-by-3 matrix into a subscript.  The matrix is linearly indexed moving from one column to next, filling up all rows in each column.
+          [r, c] = ind2sub ([3, 3], 8)
+          => r =  2
+          c =  3
+     See also: sub2ind.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Convert a linear index into subscripts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+celldisp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+ -- Function File:  celldisp (C, NAME)
+     Recursively display the contents of a cell array.  By default the values are displayed with the name of the variable C.  However, this name can be replaced with the variable NAME.  See also: disp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Recursively display the contents of a cell array.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+sub2ind
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 460
+ -- Function File: IND = sub2ind (DIMS, I, J)
+ -- Function File: IND = sub2ind (DIMS, S1, S2, ..., SN)
+     Convert subscripts into a linear index.
+
+     The following example shows how to convert the two-dimensional index `(2,3)' of a 3-by-3 matrix to a linear index.  The matrix is linearly indexed moving from one column to next, filling up all rows in each column.
+
+          linear_index = sub2ind ([3, 3], 2, 3)
+          => 8
+     See also: ind2sub.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Convert subscripts into a linear index.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+pol2cart
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 365
+ -- Function File: [X, Y] = pol2cart (THETA, R)
+ -- Function File: [X, Y, Z] = pol2cart (THETA, R, Z)
+     Transform polar or cylindrical to Cartesian coordinates.  THETA, R (and Z) must be the same shape, or scalar.  THETA describes the angle relative to the positive x-axis.  R is the distance to the z-axis (0, 0, z).  See also: cart2pol, cart2sph, sph2cart.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Transform polar or cylindrical to Cartesian coordinates.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+issymmetric
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 390
+ -- Function File:  issymmetric (X, TOL)
+     If X is symmetric within the tolerance specified by TOL, then return the dimension of X.  Otherwise, return 0.  If TOL is omitted, use a tolerance equal to the machine precision.  Matrix X is considered symmetric if `norm (X - X.', inf) / norm (X, inf) < TOL'.  See also: size, rows, columns, length, ismatrix, isscalar, issquare, isvector.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 88
+If X is symmetric within the tolerance specified by TOL, then return the dimension of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+runlength
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 241
+ -- Function File:  runlength (X)
+     Find the lengths of all sequences of common values.  Return the vector of lengths and the value that was repeated.
+
+          runlength ([2, 2, 0, 4, 4, 4, 0, 1, 1, 1, 1])
+          =>  [2, 1, 3, 1, 4]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Find the lengths of all sequences of common values.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+circshift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 766
+ -- Function File: Y = circshift (X, N)
+     Circularly shifts the values of the array X.  N must be a vector of integers no longer than the number of dimensions in X.  The values of N can be either positive or negative, which determines the direction in which the values or X are shifted.  If an element of N is zero, then the corresponding dimension of X will not be shifted.  For example
+
+          x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+          circshift (x, 1)
+          =>  7, 8, 9
+              1, 2, 3
+              4, 5, 6
+          circshift (x, -2)
+          =>  7, 8, 9
+              1, 2, 3
+              4, 5, 6
+          circshift (x, [0,1])
+          =>  3, 1, 2
+              6, 4, 5
+              9, 7, 8
+     See also: permute, ipermute, shiftdim.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Circularly shifts the values of the array X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+common_size
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 626
+ -- Function File: [ERR, Y1, ...] = common_size (X1, ...)
+     Determine if all input arguments are either scalar or of common size.  If so, ERR is zero, and YI is a matrix of the common size with all entries equal to XI if this is a scalar or XI otherwise.  If the inputs cannot be brought to a common size, errorcode is 1, and YI is XI.  For example,
+
+          [errorcode, a, b] = common_size ([1 2; 3 4], 5)
+               => errorcode = 0
+               => a = [ 1, 2; 3, 4 ]
+               => b = [ 5, 5; 5, 5 ]
+
+     This is useful for implementing functions where arguments can either be scalars or of common size.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Determine if all input arguments are either scalar or of common size.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+shift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 283
+ -- Function File:  shift (X, B)
+ -- Function File:  shift (X, B, DIM)
+     If X is a vector, perform a circular shift of length B of the elements of X.
+
+     If X is a matrix, do the same for each column of X.  If the optional DIM argument is given, operate along this dimension
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+If X is a vector, perform a circular shift of length B of the elements of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cumtrapz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 452
+ -- Function File: Z = cumtrapz (Y)
+ -- Function File: Z = cumtrapz (X, Y)
+ -- Function File: Z = cumtrapz (..., DIM)
+     Cumulative numerical integration using trapezoidal method.  `cumtrapz (Y)' computes the cumulative integral of the Y along the first non-singleton dimension.  If the argument X is omitted a equally spaced vector is assumed.  `cumtrapz (X, Y)' evaluates the cumulative integral with respect to X.
+
+     See also: trapz,cumsum.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Cumulative numerical integration using trapezoidal method.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+gradient
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1783
+ -- Function File: DX = gradient (M)
+ -- Function File: [DX, DY, DZ, ...] = gradient (M)
+ -- Function File: [...] = gradient (M, S)
+ -- Function File: [...] = gradient (M, X, Y, Z, ...)
+ -- Function File: [...] = gradient (F, X0)
+ -- Function File: [...] = gradient (F, X0, S)
+ -- Function File: [...] = gradient (F, X0, X, Y, ...)
+     Calculate the gradient of sampled data or a function.  If M is a vector, calculate the one-dimensional gradient of M.  If M is a matrix the gradient is calculated for each dimension.
+
+     `[DX, DY] = gradient (M)' calculates the one dimensional gradient for X and Y direction if M is a matrix.  Additional return arguments can be use for multi-dimensional matrices.
+
+     A constant spacing between two points can be provided by the S parameter.  If S is a scalar, it is assumed to be the spacing for all dimensions.  Otherwise, separate values of the spacing can be supplied by the X, ... arguments.  Scalar values specify an equidistant spacing.  Vector values for the X, ... arguments specify the coordinate for that dimension.  The length must match their respective dimension of M.
+
+     At boundary points a linear extrapolation is applied.  Interior points are calculated with the first approximation of the numerical gradient
+
+          y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).
+
+     If the first argument F is a function handle, the gradient of the function at the points in X0 is approximated using central difference.  For example, `gradient (@cos, 0)' approximates the gradient of the cosine function in the point x0 = 0.  As with sampled data, the spacing values between the points from which the gradient is estimated can be set via the S or DX, DY, ... arguments.  By default a spacing of 1 is used.  See also: diff, del2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Calculate the gradient of sampled data or a function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+triplequad
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 636
+ -- Function File:  triplequad (F, XA, XB, YA, YB, ZA, ZB, TOL, QUADF, ...)
+     Numerically evaluate a triple integral.  The function over which to integrate is defined by `F', and the interval for the integration is defined by `[XA, XB, YA, YB, ZA, ZB]'.  The function F must accept a vector X and a scalar Y, and return a vector of the same length as X.
+
+     If defined, TOL defines the absolute tolerance to which to which to integrate each sub-integral.
+
+     Additional arguments, are passed directly to F.  To use the default value for TOL one may pass an empty matrix.  See also: dblquad, quad, quadv, quadl, quadgk, trapz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Numerically evaluate a triple integral.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+prepad
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 517
+ -- Function File:  prepad (X, L, C)
+ -- Function File:  prepad (X, L, C, DIM)
+     Prepend (append) the scalar value C to the vector X until it is of length L.  If the third argument is not supplied, a value of 0 is used.
+
+     If `length (X) > L', elements from the beginning (end) of X are removed until a vector of length L is obtained.
+
+     If X is a matrix, elements are prepended or removed from each row.
+
+     If the optional DIM argument is given, then operate along this dimension.  See also: postpad.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Prepend (append) the scalar value C to the vector X until it is of length L.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+cellidx
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 602
+ -- Function File: [IDXVEC, ERRMSG] = cellidx (LISTVAR, STRLIST)
+     Return indices of string entries in LISTVAR that match strings in STRLIST.
+
+     Both LISTVAR and STRLIST may be passed as strings or string matrices.  If they are passed as string matrices, each entry is processed by `deblank' prior to searching for the entries.
+
+     The first output is the vector of indices in LISTVAR.
+
+     If STRLIST contains a string not in LISTVAR, then an error message is returned in ERRMSG.  If only one output argument is requested, then CELLIDX prints ERRMSG to the screen and exits with an error.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Return indices of string entries in LISTVAR that match strings in STRLIST.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bitget
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 277
+ -- Function File: X = bitget (A,N)
+     Return the status of bit(s) N of unsigned integers in A the lowest significant bit is N = 1.
+
+          bitget (100, 8:-1:1)
+          => 0  1  1  0  0  1  0  0
+     See also: bitand, bitor, bitxor, bitset, bitcmp, bitshift, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Return the status of bit(s) N of unsigned integers in A the lowest significant bit is N = 1.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+tril
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 988
+ -- Function File:  tril (A, K)
+ -- Function File:  triu (A, K)
+     Return a new matrix formed by extracting the lower (`tril') or upper (`triu') triangular part of the matrix A, and setting all other elements to zero.  The second argument is optional, and specifies how many diagonals above or below the main diagonal should also be set to zero.
+
+     The default value of K is zero, so that `triu' and `tril' normally include the main diagonal as part of the result matrix.
+
+     If the value of K is negative, additional elements above (for `tril') or below (for `triu') the main diagonal are also selected.
+
+     The absolute value of K must not be greater than the number of sub- or super-diagonals.
+
+     For example,
+
+          tril (ones (3), -1)
+               =>  0  0  0
+                   1  0  0
+                   1  1  0
+
+     and
+
+          tril (ones (3), 1)
+               =>  1  1  0
+                   1  1  1
+                   1  1  1
+     See also: triu, diag.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+Return a new matrix formed by extracting the lower (`tril') or upper (`triu') triangular part of the matrix A, and setting all other elements to zero.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+num2str
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1331
+ -- Function File:  num2str (X)
+ -- Function File:  num2str (X, PRECISION)
+ -- Function File:  num2str (X, FORMAT)
+     Convert a number (or array) to a string (or a character array).  The optional second argument may either give the number of significant digits (PRECISION) to be used in the output or a format template string (FORMAT) as in `sprintf' (*note Formatted Output::).  `num2str' can also handle complex numbers.  For example:
+
+          num2str (123.456)
+               => "123.46"
+
+          num2str (123.456, 4)
+               => "123.5"
+
+          s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
+               => s =
+                  1.0  1.3
+                  3.0  3.6
+          whos s
+               =>
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     s           2x8                         16  char
+
+          num2str (1.234 + 27.3i)
+               => "1.234+27.3i"
+
+     The `num2str' function is not very flexible.  For better control over the results, use `sprintf' (*note Formatted Output::).  Note that for complex X, the format string may only contain one output conversion specification and nothing else.  Otherwise, you will get unpredictable results.  See also: sprintf, int2str, mat2str.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Convert a number (or array) to a string (or a character array).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bitcmp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 352
+ -- Function File:  bitcmp (A, K)
+     Return the K-bit complement of integers in A.  If K is omitted `k = log2 (bitmax) + 1' is assumed.
+
+          bitcmp(7,4)
+          => 8
+          dec2bin(11)
+          => 1011
+          dec2bin(bitcmp(11, 6))
+          => 110100
+     See also: bitand, bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Return the K-bit complement of integers in A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+rem
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 298
+ -- Mapping Function:  rem (X, Y)
+     Return the remainder of the division `X / Y', computed using the expression
+
+          x - y .* fix (x ./ y)
+
+     An error message is printed if the dimensions of the arguments do not agree, or if either of the arguments is complex.  See also: mod, fmod.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Return the remainder of the division `X / Y', computed using the expression 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+interp1q
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 714
+ -- Function File: YI = interp1q (X, Y, XI)
+     One-dimensional linear interpolation without error checking.  Interpolates Y, defined at the points X, at the points XI.  The sample points X must be a strictly monotonically increasing column vector.  If Y is an array, treat the columns of Y separately.  If Y is a vector, it must be a column vector of the same length as X.
+
+     Values of XI beyond the endpoints of the interpolation result in NA being returned.
+
+     Note that the error checking is only a significant portion of the execution time of this `interp1' if the size of the input arguments is relatively small.  Therefore, the benefit of using `interp1q' is relatively small.  See also: interp1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+One-dimensional linear interpolation without error checking.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 18
+is_duplicate_entry
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 118
+ -- Function File:  is_duplicate_entry (X)
+     Return non-zero if any entries in X are duplicates of one another.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Return non-zero if any entries in X are duplicates of one another.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+polyarea
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 475
+ -- Function File:  polyarea (X, Y)
+ -- Function File:  polyarea (X, Y, DIM)
+     Determines area of a polygon by triangle method.  The variables X and Y define the vertex pairs, and must therefore have the same shape.  They can be either vectors or arrays.  If they are arrays then the columns of X and Y are treated separately and an area returned for each.
+
+     If the optional DIM argument is given, then `polyarea' works along this dimension of the arrays X and Y.
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Determines area of a polygon by triangle method.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+structfun
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1710
+ -- Function File:  structfun (FUNC, S)
+ -- Function File: [A, B] = structfun (...)
+ -- Function File:  structfun (..., "ErrorHandler", ERRFUNC)
+ -- Function File:  structfun (..., "UniformOutput", VAL)
+     Evaluate the function named NAME on the fields of the structure S.  The fields of S are passed to the function FUNC individually.
+
+     `structfun' accepts an arbitrary function FUNC in the form of an inline function, function handle, or the name of a function (in a character string).  In the case of a character string argument, the function must accept a single argument named X, and it must return a string value.  If the function returns more than one argument, they are returned as separate output variables.
+
+     If the parameter "UniformOutput" is set to true (the default), then the function must return a single element which will be concatenated into the return value.  If "UniformOutput" is false, the outputs placed in a structure with the same fieldnames as the input structure.
+
+          s.name1 = "John Smith";
+          s.name2 = "Jill Jones";
+          structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
+                     "UniformOutput", false)
+
+     Given the parameter "ErrorHandler", then ERRFUNC defines a function to call in case FUNC generates an error.  The form of the function is
+
+          function [...] = errfunc (SE, ...)
+
+     where there is an additional input argument to ERRFUNC relative to FUNC, given by SE.  This is a structure with the elements "identifier", "message" and "index", giving respectively the error identifier, the error message, and the index into the input arguments of the element that caused the error.  See also: cellfun, arrayfun.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Evaluate the function named NAME on the fields of the structure S.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+isa
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 93
+ -- Function File:  isa (X, CLASS)
+     Return true if X is a value from the class CLASS.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Return true if X is a value from the class CLASS.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+del2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1132
+ -- Function File: D = del2 (M)
+ -- Function File: D = del2 (M, H)
+ -- Function File: D = del2 (M, DX, DY, ...)
+     Calculate the discrete Laplace operator.  For a 2-dimensional matrix M this is defined as
+
+                1    / d^2            d^2         \
+          D  = --- * | ---  M(x,y) +  ---  M(x,y) |
+                4    \ dx^2           dy^2        /
+
+     For N-dimensional arrays the sum in parentheses is expanded to include second derivatives over the additional higher dimensions.
+
+     The spacing between evaluation points may be defined by H, which is a scalar defining the equidistant spacing in all dimensions.  Alternatively, the spacing in each dimension may be defined separately by DX, DY, etc.  A scalar spacing argument defines equidistant spacing, whereas a vector argument can be used to specify variable spacing.  The length of the spacing vectors must match the respective dimension of M.  The default spacing value is 1.
+
+     At least 3 data points are needed for each dimension.  Boundary points are calculated from the linear extrapolation of interior points.
+
+     See also: gradient, diff.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 40
+Calculate the discrete Laplace operator.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+logspace
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 431
+ -- Function File:  logspace (BASE, LIMIT, N)
+     Similar to `linspace' except that the values are logarithmically spaced from 10^base to 10^limit.
+
+     If LIMIT is equal to pi, the points are between 10^base and pi, _not_ 10^base and 10^pi, in order to be compatible with the corresponding MATLAB function.
+
+     Also for compatibility, return the second argument if fewer than two values are requested.  See also: linspace.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Similar to `linspace' except that the values are logarithmically spaced from 10^base to 10^limit.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+bicubic
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 335
+ -- Function File: ZI = bicubic (X, Y, Z, XI, YI, EXTRAPVAL)
+     Return a matrix ZI corresponding to the bicubic interpolations at XI and YI of the data supplied as X, Y and Z.  Points outside the grid are set to EXTRAPVAL.
+
+     See `http://wiki.woodpecker.org.cn/moin/Octave/Bicubic' for further information.  See also: interp2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 111
+Return a matrix ZI corresponding to the bicubic interpolations at XI and YI of the data supplied as X, Y and Z.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+sortrows
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 313
+ -- Function File:  sortrows (A, C)
+     Sort the rows of the matrix A according to the order of the columns specified in C.  If C is omitted, a lexicographical sort is used.  By default ascending order is used however if elements of C are negative then the corresponding column is sorted in descending order.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Sort the rows of the matrix A according to the order of the columns specified in C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+subsindex
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 824
+ -- Function File: IDX = subsindex (A)
+     Convert an object to an index vector.  When A is a class object defined with a class constructor, then `subsindex' is the overloading method that allows the conversion of this class object to a valid indexing vector.  It is important to note that `subsindex' must return a zero-based real integer vector of the class "double".  For example, if the class constructor
+
+          function b = myclass (a)
+           b = myclass (struct ("a", a), "myclass");
+          endfunction
+
+     then the `subsindex' function
+
+          function idx = subsindex (a)
+           idx = double (a.a) - 1.0;
+          endfunction
+
+     can then be used as follows
+
+          a = myclass (1:4);
+          b = 1:10;
+          b(a)
+          => 1  2  3  4
+
+     See also: class, subsref, subsasgn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 37
+Convert an object to an index vector.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+interp2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1759
+ -- Function File: ZI = interp2 (X, Y, Z, XI, YI)
+ -- Function File: ZI = interp2 (Z, XI, YI)
+ -- Function File: ZI = interp2 (Z, N)
+ -- Function File: ZI = interp2 (..., METHOD)
+ -- Function File: ZI = interp2 (..., METHOD, EXTRAPVAL)
+     Two-dimensional interpolation.  X, Y and Z describe a surface function.  If X and Y are vectors their length must correspondent to the size of Z.  X and Y must be monotonic.  If they are matrices they must have the `meshgrid' format.
+
+    `interp2 (X, Y, Z, XI, YI, ...)'
+          Returns a matrix corresponding to the points described by the matrices XI, YI.
+
+          If the last argument is a string, the interpolation method can be specified.  The method can be 'linear', 'nearest' or 'cubic'.  If it is omitted 'linear' interpolation is assumed.
+
+    `interp2 (Z, XI, YI)'
+          Assumes `X = 1:rows (Z)' and `Y = 1:columns (Z)'
+
+    `interp2 (Z, N)'
+          Interleaves the matrix Z n-times.  If N is omitted a value of `N = 1' is assumed.
+
+     The variable METHOD defines the method to use for the interpolation.  It can take one of the following values
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors.
+
+    'pchip'
+          Piece-wise cubic hermite interpolating polynomial (not implemented yet).
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors.
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives throughout the curve.
+
+     If a scalar value EXTRAPVAL is defined as the final value, then values outside the mesh as set to this value.  Note that in this case METHOD must be defined as well.  If EXTRAPVAL is not defined then NA is assumed.
+
+     See also: interp1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Two-dimensional interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+repmat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 257
+ -- Function File:  repmat (A, M, N)
+ -- Function File:  repmat (A, [M N])
+ -- Function File:  repmat (A, [M N P ...])
+     Form a block matrix of size M by N, with a copy of matrix A as each element.  If N is not specified, form an M by M block matrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Form a block matrix of size M by N, with a copy of matrix A as each element.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+isequal
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+ -- Function File:  isequal (X1, X2, ...)
+     Return true if all of X1, X2, ... are equal.  See also: isequalwithequalnans.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Return true if all of X1, X2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+deal
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 494
+ -- Function File: [R1, R2, ..., RN] = deal (A)
+ -- Function File: [R1, R2, ..., RN] = deal (A1, A2, ..., AN)
+     Copy the input parameters into the corresponding output parameters.  If only one input parameter is supplied, its value is copied to each of the outputs.
+
+     For example,
+
+          [a, b, c] = deal (x, y, z);
+
+     is equivalent to
+
+          a = x;
+          b = y;
+          c = z;
+
+     and
+
+          [a, b, c] = deal (x);
+
+     is equivalent to
+
+          a = b = c = x;
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 67
+Copy the input parameters into the corresponding output parameters.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+quadv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1075
+ -- Function File: Q = quadv (F, A, B)
+ -- Function File: Q = quadl (F, A, B, TOL)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE, P1, P2, ...)
+ -- Function File: [Q, FCNT] = quadl (...)
+     Numerically evaluate integral using adaptive Simpson's rule.  `quadv (F, A, B)' approximates the integral of `F(X)' to the default absolute tolerance of `1e-6'.  F is either a function handle, inline function or string containing the name of the function to evaluate.  The function F must accept a string, and can return a vector representing the approximation to N different sub-functions.
+
+     If defined, TOL defines the absolute tolerance to which to which to integrate each sub-interval of `F(X)'.  While if TRACE is defined, displays the left end point of the current interval, the interval length, and the partial integral.
+
+     Additional arguments P1, etc., are passed directly to F.  To use default values for TOL and TRACE, one may pass empty matrices.  See also: triplequad, dblquad, quad, quadl, quadgk, trapz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Numerically evaluate integral using adaptive Simpson's rule.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+randperm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 122
+ -- Function File:  randperm (N)
+     Return a row vector containing a random permutation of the integers from 1 to N.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+Return a row vector containing a random permutation of the integers from 1 to N.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+interpn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1600
+ -- Function File: VI = interpn (X1, X2, ..., V, Y1, Y2, ...)
+ -- Function File: VI = interpn (V, Y1, Y2, ...)
+ -- Function File: VI = interpn (V, M)
+ -- Function File: VI = interpn (V)
+ -- Function File: VI = interpn (..., METHOD)
+ -- Function File: VI = interpn (..., METHOD, EXTRAPVAL)
+     Perform N-dimensional interpolation, where N is at least two.  Each element of the N-dimensional array V represents a value at a location given by the parameters X1, X2, ..., XN.  The parameters X1, X2, ..., XN are either N-dimensional arrays of the same size as the array V in the 'ndgrid' format or vectors.  The parameters Y1, etc. respect a similar format to X1, etc., and they represent the points at which the array VI is interpolated.
+
+     If X1, ..., XN are omitted, they are assumed to be `x1 = 1 : size (V, 1)', etc.  If M is specified, then the interpolation adds a point half way between each of the interpolation points.  This process is performed M times.  If only V is specified, then M is assumed to be `1'.
+
+     Method is one of:
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors.
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors (not implemented yet).
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives throughout the curve.
+
+     The default method is 'linear'.
+
+     If EXTRAPVAL is the scalar value, use it to replace the values beyond the endpoints with that number.  If EXTRAPVAL is missing, assume NA.  See also: interp1, interp2, spline, ndgrid.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Perform N-dimensional interpolation, where N is at least two.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+fliplr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 331
+ -- Function File:  fliplr (X)
+     Return a copy of X with the order of the columns reversed.  For example,
+
+          fliplr ([1, 2; 3, 4])
+               =>  2  1
+                   4  3
+
+     Note that `fliplr' only work with 2-D arrays.  To flip N-d arrays use `flipdim' instead.  See also: flipud, flipdim, rot90, rotdim.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Return a copy of X with the order of the columns reversed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+blkdiag
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 215
+ -- Function File:  blkdiag (A, B, C, ...)
+     Build a block diagonal matrix from A, B, C, ....  All the arguments must be numeric and are two-dimensional matrices or scalars.  See also: diag, horzcat, vertcat.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Build a block diagonal matrix from A, B, C, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cell2mat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 274
+ -- Function File: M = cell2mat (C)
+     Convert the cell array C into a matrix by concatenating all elements of C into a hyperrectangle.  Elements of C must be numeric, logical or char, and `cat' must be able to concatenate them together.  See also: mat2cell, num2cell.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 96
+Convert the cell array C into a matrix by concatenating all elements of C into a hyperrectangle.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+interpft
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 510
+ -- Function File:  interpft (X, N)
+ -- Function File:  interpft (X, N, DIM)
+     Fourier interpolation.  If X is a vector, then X is resampled with N points.  The data in X is assumed to be equispaced.  If X is an array, then operate along each column of the array separately.  If DIM is specified, then interpolate along the dimension DIM.
+
+     `interpft' assumes that the interpolated function is periodic, and so assumptions are made about the end points of the interpolation.
+
+     See also: interp1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Fourier interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+triu
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+ -- Function File:  triu (A, K)
+     See tril.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+See tril.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+strerror
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 264
+ -- Function File:  strerror (NAME, NUM)
+     Return the text of an error message for function NAME corresponding to the error number NUM.  This function is intended to be used to print useful error messages for those functions that return numeric error codes.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 92
+Return the text of an error message for function NAME corresponding to the error number NUM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+nargoutchk
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 506
+ -- Function File: MSGSTR = nargoutchk (MINARGS, MAXARGS, NARGS)
+ -- Function File: MSGSTR = nargoutchk (MINARGS, MAXARGS, NARGS, "string")
+ -- Function File: MSGSTRUCT = nargoutchk (MINARGS, MAXARGS, NARGS, "struct")
+     Return an appropriate error message string (or structure) if the number of outputs requested is invalid.
+
+     This is useful for checking to see that the number of output arguments supplied to a function is within an acceptable range.  See also: nargchk, error, nargout, nargin.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+Return an appropriate error message string (or structure) if the number of outputs requested is invalid.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+trapz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 400
+ -- Function File: Z = trapz (Y)
+ -- Function File: Z = trapz (X, Y)
+ -- Function File: Z = trapz (..., DIM)
+     Numerical integration using trapezoidal method.  `trapz (Y)' computes the integral of the Y along the first non-singleton dimension.  If the argument X is omitted a equally spaced vector is assumed.  `trapz (X, Y)' evaluates the integral with respect to X.
+
+     See also: cumtrapz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Numerical integration using trapezoidal method.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+dblquad
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 619
+ -- Function File:  dblquad (F, XA, XB, YA, YB, TOL, QUADF, ...)
+     Numerically evaluate a double integral.  The function over with to integrate is defined by `F', and the interval for the integration is defined by `[XA, XB, YA, YB]'.  The function F must accept a vector X and a scalar Y, and return a vector of the same length as X.
+
+     If defined, TOL defines the absolute tolerance to which to which to integrate each sub-integral.
+
+     Additional arguments, are passed directly to F.  To use the default value for TOL one may pass an empty matrix.  See also: triplequad, quad, quadv, quadl, quadgk, trapz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 39
+Numerically evaluate a double integral.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+isdir
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+ -- Function File:  isdir (F)
+     Return true if F is a directory.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Return true if F is a directory.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isvector
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+ -- Function File:  isvector (A)
+     Return 1 if A is a vector.  Otherwise, return 0.  See also: size, rows, columns, length, isscalar, ismatrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Return 1 if A is a vector.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cart2pol
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 361
+ -- Function File: [THETA, R] = cart2pol (X, Y)
+ -- Function File: [THETA, R, Z] = cart2pol (X, Y, Z)
+     Transform Cartesian to polar or cylindrical coordinates.  X, Y (and Z) must be the same shape, or scalar.  THETA describes the angle relative to the positive x-axis.  R is the distance to the z-axis (0, 0, z).  See also: pol2cart, cart2sph, sph2cart.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Transform Cartesian to polar or cylindrical coordinates.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+idivide
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1283
+ -- Function File:  idivide (X, Y, OP)
+     Integer division with different round rules.  The standard behavior of the an integer division such as `A ./ B' is to round the result to the nearest integer.  This is not always the desired behavior and `idivide' permits integer element-by-element division to be performed with different treatment for the fractional part of the division as determined by the OP flag.  OP is a string with one of the values:
+
+    "fix"
+          Calculate `A ./ B' with the fractional part rounded towards zero.
+
+    "round"
+          Calculate `A ./ B' with the fractional part rounded towards the nearest integer.
+
+    "floor"
+          Calculate `A ./ B' with the fractional part rounded downwards.
+
+    "ceil"
+          Calculate `A ./ B' with the fractional part rounded upwards.
+
+     If OP is not given it is assumed that it is `"fix"'.  An example demonstrating these rounding rules is
+
+          idivide (int8 ([-3, 3]), int8 (4), "fix")
+          => int8 ([0, 0])
+          idivide (int8 ([-3, 3]), int8 (4), "round")
+          => int8 ([-1, 1])
+          idivide (int8 ([-3, 3]), int8 (4), "ceil")
+          => int8 ([0, 1])
+          idivide (int8 ([-3, 3]), int8 (4), "floor")
+          => int8 ([-1, 0])
+
+     See also: ldivide, rdivide.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 44
+Integer division with different round rules.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+diff
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 852
+ -- Function File:  diff (X, K, DIM)
+     If X is a vector of length N, `diff (X)' is the vector of first differences X(2) - X(1), ..., X(n) - X(n-1).
+
+     If X is a matrix, `diff (X)' is the matrix of column differences along the first non-singleton dimension.
+
+     The second argument is optional.  If supplied, `diff (X, K)', where K is a non-negative integer, returns the K-th differences.  It is possible that K is larger than then first non-singleton dimension of the matrix.  In this case, `diff' continues to take the differences along the next non-singleton dimension.
+
+     The dimension along which to take the difference can be explicitly stated with the optional variable DIM.  In this case the K-th order differences are calculated along this dimension.  In the case where K exceeds `size (X, DIM)' then an empty matrix is returned.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 90
+If X is a vector of length N, `diff (X)' is the vector of first differences X(2) - X(1), .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+loadobj
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 479
+ -- Function File: B = loadobj (A)
+     Method of a class to manipulate an object after loading it from a file.  The function `loadobj' is called when the object A is loaded using the `load' function.  An example of the use of `saveobj' might be to add fields to an object that don't make sense to be saved.  For example
+
+          function b = loadobj (a)
+            b = a;
+            b.addmissingfield = addfield (b);
+          endfunction
+
+     See also: saveobj, class.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Method of a class to manipulate an object after loading it from a file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+sph2cart
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 346
+ -- Function File: [X, Y, Z] = sph2cart (THETA, PHI, R)
+     Transform spherical to Cartesian coordinates.  X, Y and Z must be the same shape, or scalar.  THETA describes the angle relative to the positive x-axis.  PHI is the angle relative to the xy-plane.  R is the distance to the origin (0, 0, 0).  See also: pol2cart, cart2pol, cart2sph.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Transform spherical to Cartesian coordinates.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cart2sph
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 346
+ -- Function File: [THETA, PHI, R] = cart2sph (X, Y, Z)
+     Transform Cartesian to spherical coordinates.  X, Y and Z must be the same shape, or scalar.  THETA describes the angle relative to the positive x-axis.  PHI is the angle relative to the xy-plane.  R is the distance to the origin (0, 0, 0).  See also: pol2cart, cart2pol, sph2cart.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 45
+Transform Cartesian to spherical coordinates.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+flipdim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 241
+ -- Function File:  flipdim (X, DIM)
+     Return a copy of X flipped about the dimension DIM.  For example
+
+          flipdim ([1, 2; 3, 4], 2)
+               =>  2  1
+                   4  3
+     See also: fliplr, flipud, rot90, rotdim.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Return a copy of X flipped about the dimension DIM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+quadgk
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3565
+ -- Function File:  quadgk (F, A, B, ABSTOL, TRACE)
+ -- Function File:  quadgk (F, A, B, PROP, VAL, ...)
+ -- Function File: [Q, ERR] = quadgk (...)
+     Numerically evaluate integral using adaptive Gauss-Konrod quadrature.  The formulation is based on a proposal by L.F. Shampine, `"Vectorized adaptive quadrature in MATLAB", Journal of Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2, Feb 2008' where all function evaluations at an iteration are calculated with a single call to F.  Therefore the function F must be of the form `F (X)' and accept vector values of X and return a vector of the same length representing the function evaluations at the given values of X.  The function F can be defined in terms of a function handle, inline function or string.
+
+     The bounds of the quadrature `[A, B]' can be finite or infinite and contain weak end singularities.  Variable transformation will be used to treat infinite intervals and weaken the singularities.  For example
+
+          quadgk(@(x) 1 ./ (sqrt (x) .* (x + 1)), 0, Inf)
+
+     Note that the formulation of the integrand uses the element-by-element operator `./' and all user functions to `quadgk' should do the same.
+
+     The absolute tolerance can be passed as a fourth argument in a manner compatible with `quadv'.  Equally the user can request that information on the convergence can be printed is the fifth argument is logically true.
+
+     Alternatively, certain properties of `quadgk' can be passed as pairs `PROP, VAL'.  Valid properties are
+
+    `AbsTol'
+          Defines the absolute error tolerance for the quadrature.  The default absolute tolerance is 1e-10.
+
+    `RelTol'
+          Defines the relative error tolerance for the quadrature.  The default relative tolerance is 1e-5.
+
+    `MaxIntervalCount'
+          `quadgk' initially subdivides the interval on which to perform the quadrature into 10 intervals.  Sub-intervals that have an unacceptable error are sub-divided and re-evaluated.  If the number of sub-intervals exceeds at any point 650 sub-intervals then a poor convergence is signaled and the current estimate of the integral is returned.  The property 'MaxIntervalCount' can be used to alter the number of sub-intervals that can exist before exiting.
+
+    `WayPoints'
+          If there exists discontinuities in the first derivative of the function to integrate, then these can be flagged with the `"WayPoints"' property.  This forces the ends of a sub-interval to fall on the breakpoints of the function and can result in significantly improved estimation of the error in the integral, faster computation or both.  For example,
+
+               quadgk (@(x) abs (1 - x .^ 2), 0, 2, 'Waypoints', 1)
+
+          signals the breakpoint in the integrand at `X = 1'.
+
+    `Trace'
+          If logically true, then `quadgk' prints information on the convergence of the quadrature at each iteration.
+
+     If any of A, B or WAYPOINTS is complex, then the quadrature is treated as a contour integral along a piecewise continuous path defined by the above.  In this case the integral is assumed to have no edge singularities.  For example
+
+          quadgk (@(z) log (z), 1+1i, 1+1i, "WayPoints",
+                  [1-1i, -1,-1i, -1+1i])
+
+     integrates `log (z)' along the square defined by `[1+1i,  1-1i, -1-1i, -1+1i]'
+
+     If two output arguments are requested, then ERR returns the approximate bounds on the error in the integral `abs (Q - I)', where I is the exact value of the integral.
+
+     See also: triplequad, dblquad, quad, quadl, quadv, trapz.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Numerically evaluate integral using adaptive Gauss-Konrod quadrature.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+perror
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 271
+ -- Function File:  perror (NAME, NUM)
+     Print the error message for function NAME corresponding to the error number NUM.  This function is intended to be used to print useful error messages for those functions that return numeric error codes.  See also: strerror.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+Print the error message for function NAME corresponding to the error number NUM.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+saveobj
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 635
+ -- Function File: B = saveobj (A)
+     Method of a class to manipulate an object prior to saving it to a file.  The function `saveobj' is called when the object A is saved using the `save' function.  An example of the use of `saveobj' might be to remove fields of the object that don't make sense to be saved or it might be used to ensure that certain fields of the object are initialized before the object is saved.  For example
+
+          function b = saveobj (a)
+            b = a;
+            if (isempty (b.field))
+               b.field = initfield(b);
+            endif
+          endfunction
+
+     See also: loadobj, class.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Method of a class to manipulate an object prior to saving it to a file.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+interp3
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1656
+ -- Function File: VI = interp3 (X, Y,Z, V, XI, YI, ZI)
+ -- Function File: VI = interp3 (V, XI, YI, ZI)
+ -- Function File: VI = interp3 (V, M)
+ -- Function File: VI = interp3 (V)
+ -- Function File: VI = interp3 (..., METHOD)
+ -- Function File: VI = interp3 (..., METHOD, EXTRAPVAL)
+     Perform 3-dimensional interpolation.  Each element of the 3-dimensional array V represents a value at a location given by the parameters X, Y, and Z.  The parameters X, X, and Z are either 3-dimensional arrays of the same size as the array V in the 'meshgrid' format or vectors.  The parameters XI, etc.  respect a similar format to X, etc., and they represent the points at which the array VI is interpolated.
+
+     If X, Y, Z are omitted, they are assumed to be `x = 1 : size (V, 2)', `y = 1 : size (V, 1)' and `z = 1 : size (V, 3)'.  If M is specified, then the interpolation adds a point half way between each of the interpolation points.  This process is performed M times.  If only V is specified, then M is assumed to be `1'.
+
+     Method is one of:
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors.
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors (not implemented yet).
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives throughout the curve.
+
+     The default method is 'linear'.
+
+     If EXTRAP is the string 'extrap', then extrapolate values beyond the endpoints.  If EXTRAP is a number, replace values beyond the endpoints with that number.  If EXTRAP is missing, assume NA.  See also: interp1, interp2, spline, meshgrid.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 36
+Perform 3-dimensional interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+isscalar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+ -- Function File:  isscalar (A)
+     Return 1 if A is a scalar.  Otherwise, return 0.  See also: size, rows, columns, length, isscalar, ismatrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 26
+Return 1 if A is a scalar.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+shiftdim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 890
+ -- Function File: Y = shiftdim (X, N)
+ -- Function File: [Y, NS] = shiftdim (X)
+     Shifts the dimension of X by N, where N must be an integer scalar.  When N is positive, the dimensions of X are shifted to the left, with the leading dimensions circulated to the end.  If N is negative, then the dimensions of X are shifted to the right, with N leading singleton dimensions added.
+
+     Called with a single argument, `shiftdim', removes the leading singleton dimensions, returning the number of dimensions removed in the second output argument NS.
+
+     For example
+
+          x = ones (1, 2, 3);
+          size (shiftdim (x, -1))
+               => [1, 1, 2, 3]
+          size (shiftdim (x, 1))
+               => [2, 3]
+          [b, ns] = shiftdim (x);
+               => b =  [1, 1, 1; 1, 1, 1]
+               => ns = 1
+     See also: reshape, permute, ipermute, circshift, squeeze.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 66
+Shifts the dimension of X by N, where N must be an integer scalar.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+rat
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 463
+ -- Function File: S = rat (X, TOL)
+ -- Function File: [N, D] = rat (X, TOL)
+     Find a rational approximation to X within the tolerance defined by TOL using a continued fraction expansion.  For example,
+
+          rat(pi) = 3 + 1/(7 + 1/16) = 355/113
+          rat(e) = 3 + 1/(-4 + 1/(2 + 1/(5 + 1/(-2 + 1/(-7)))))
+                 = 1457/536
+
+     Called with two arguments returns the numerator and denominator separately as two matrices.
+   See also: rats.  
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 108
+Find a rational approximation to X within the tolerance defined by TOL using a continued fraction expansion.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+isdefinite
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 302
+ -- Function File:  isdefinite (X, TOL)
+     Return 1 if X is symmetric positive definite within the tolerance specified by TOL or 0 if X is symmetric positive semidefinite.  Otherwise, return -1.  If TOL is omitted, use a tolerance equal to 100 times the machine precision.  See also: issymmetric.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+Return 1 if X is symmetric positive definite within the tolerance specified by TOL or 0 if X is symmetric positive semidefinite.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nthroot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 234
+ -- Function File:  nthroot (X, N)
+     Compute the n-th root of X, returning real results for real components of X.  For example
+
+          nthroot (-1, 3)
+          => -1
+          (-1) ^ (1 / 3)
+          => 0.50000 - 0.86603i
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+Compute the n-th root of X, returning real results for real components of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+flipud
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 394
+ -- Function File:  flipud (X)
+     Return a copy of X with the order of the rows reversed.  For example,
+
+          flipud ([1, 2; 3, 4])
+               =>  3  4
+                   1  2
+
+     Due to the difficulty of defining which axis about which to flip the matrix `flipud' only work with 2-d arrays.  To flip N-d arrays use `flipdim' instead.  See also: fliplr, flipdim, rot90, rotdim.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return a copy of X with the order of the rows reversed.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+postpad
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 115
+ -- Function File:  postpad (X, L, C)
+ -- Function File:  postpad (X, L, C, DIM)
+     See also: prepad, resize.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 25
+See also: prepad, resize.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+nextpow2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 191
+ -- Function File:  nextpow2 (X)
+     If X is a scalar, return the first integer N such that 2^n >= abs (x).
+
+     If X is a vector, return `nextpow2 (length (X))'.  See also: pow2, log2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 70
+If X is a scalar, return the first integer N such that 2^n >= abs (x).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+accumarray
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1419
+ -- Function File:  accumarray (SUBS, VALS, SZ, FUNC, FILLVAL, ISSPARSE)
+ -- Function File:  accumarray (CSUBS, VALS, ...)
+     Create an array by accumulating the elements of a vector into the positions defined by their subscripts.  The subscripts are defined by the rows of the matrix SUBS and the values by VALS.  Each row of SUBS corresponds to one of the values in VALS.
+
+     The size of the matrix will be determined by the subscripts themselves.  However, if SZ is defined it determines the matrix size.  The length of SZ must correspond to the number of columns in SUBS.
+
+     The default action of `accumarray' is to sum the elements with the same subscripts.  This behavior can be modified by defining the FUNC function.  This should be a function or function handle that accepts a column vector and returns a scalar.  The result of the function should not depend on the order of the subscripts.
+
+     The elements of the returned array that have no subscripts associated with them are set to zero.  Defining FILLVAL to some other value allows these values to be defined.
+
+     By default `accumarray' returns a full matrix.  If ISSPARSE is logically true, then a sparse matrix is returned instead.
+
+     An example of the use of `accumarray' is:
+
+          accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+          => ans(:,:,1) = [101, 0, 0; 0, 0, 0]
+             ans(:,:,2) = [0, 0, 0; 206, 0, 208]
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+Create an array by accumulating the elements of a vector into the positions defined by their subscripts.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+colon
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 278
+ -- Function File: R = colon (A, B)
+ -- Function File: R = colon (A, B, C)
+     Method of a class to construct a range with the `:' operator.  For example.
+
+          a = myclass (...)
+          b = myclass (...)
+          c = a : b
+
+     See also: class, subsref, subsasgn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 61
+Method of a class to construct a range with the `:' operator.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+display
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 317
+ -- Function File:  display (A)
+     Display the contents of an object.  If A is an object of the class "myclass", then `display' is called in a case like
+
+          myclass (...)
+
+     where Octave is required to display the contents of a variable of the type "myclass".
+
+     See also: class, subsref, subsasgn.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 34
+Display the contents of an object.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+rotdim
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 964
+ -- Function File:  rotdim (X, N, PLANE)
+     Return a copy of X with the elements rotated counterclockwise in 90-degree increments.  The second argument is optional, and specifies how many 90-degree rotations are to be applied (the default value is 1).  The third argument is also optional and defines the plane of the rotation.  As such PLANE is a two element vector containing two different valid dimensions of the matrix.  If PLANE is not given Then the first two non-singleton dimensions are used.
+
+     Negative values of N rotate the matrix in a clockwise direction.  For example,
+
+          rotdim ([1, 2; 3, 4], -1, [1, 2])
+               =>  3  1
+                   4  2
+
+     rotates the given matrix clockwise by 90 degrees.  The following are all equivalent statements:
+
+          rotdim ([1, 2; 3, 4], -1, [1, 2])
+          rotdim ([1, 2; 3, 4], 3, [1, 2])
+          rotdim ([1, 2; 3, 4], 7, [1, 2])
+     See also: rot90, flipud, fliplr, flipdim.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Return a copy of X with the elements rotated counterclockwise in 90-degree increments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+issquare
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 190
+ -- Function File:  issquare (X)
+     If X is a square matrix, then return the dimension of X.  Otherwise, return 0.  See also: size, rows, columns, length, ismatrix, isscalar, isvector.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+If X is a square matrix, then return the dimension of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+logical
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 167
+ -- Function File:  logical (ARG)
+     Convert ARG to a logical value.  For example,
+
+          logical ([-1, 0, 1])
+
+     is equivalent to
+
+          [-1, 0, 1] != 0
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 31
+Convert ARG to a logical value.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+bitset
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 337
+ -- Function File: X = bitset (A, N)
+ -- Function File: X = bitset (A, N, V)
+     Set or reset bit(s) N of unsigned integers in A.  V = 0 resets and V = 1 sets the bits.  The lowest significant bit is: N = 1
+
+          dec2bin (bitset (10, 1))
+          => 1011
+     See also: bitand, bitor, bitxor, bitget, bitcmp, bitshift, bitmax.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Set or reset bit(s) N of unsigned integers in A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+arrayfun
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3319
+ -- Function File:  arrayfun (FUNC, A)
+ -- Function File: X = arrayfun (FUNC, A)
+ -- Function File: X = arrayfun (FUNC, A, B, ...)
+ -- Function File: [X, Y, ...] = arrayfun (FUNC, A, ...)
+ -- Function File:  arrayfun (..., "UniformOutput", VAL)
+ -- Function File:  arrayfun (..., "ErrorHandler", ERRFUNC)
+     Execute a function on each element of an array.  This is useful for functions that do not accept array arguments.  If the function does accept array arguments it is better to call the function directly.
+
+     The first input argument FUNC can be a string, a function handle, an inline function or an anonymous function.  The input argument A can be a logic array, a numeric array, a string array, a structure array or a cell array.  By a call of the function `arrayfun' all elements of A are passed on to the named function FUNC individually.
+
+     The named function can also take more than two input arguments, with the input arguments given as third input argument B, fourth input argument C, ...  If given more than one array input argument then all input arguments must have the same sizes, for example
+
+          arrayfun (@atan2, [1, 0], [0, 1])
+          => ans = [1.5708   0.0000]
+
+     If the parameter VAL after a further string input argument "UniformOutput" is set `true' (the default), then the named function FUNC must return a single element which then will be concatenated into the return value and is of type matrix.  Otherwise, if that parameter is set to `false', then the outputs are concatenated in a cell array.  For example
+
+          arrayfun (@(x,y) x:y, "abc", "def", "UniformOutput", false)
+          => ans =
+          {
+            [1,1] = abcd
+            [1,2] = bcde
+            [1,3] = cdef
+          }
+
+     If more than one output arguments are given then the named function must return the number of return values that also are expected, for example
+
+          [A, B, C] = arrayfun (@find, [10; 0], "UniformOutput", false)
+          =>
+          A =
+          {
+            [1,1] =  1
+            [2,1] = [](0x0)
+          }
+          B =
+          {
+            [1,1] =  1
+            [2,1] = [](0x0)
+          }
+          C =
+          {
+            [1,1] =  10
+            [2,1] = [](0x0)
+          }
+
+     If the parameter ERRFUNC after a further string input argument "ErrorHandler" is another string, a function handle, an inline function or an anonymous function, then ERRFUNC defines a function to call in the case that FUNC generates an error.  The definition of the function must be of the form
+
+          function [...] = errfunc (S, ...)
+
+     where there is an additional input argument to ERRFUNC relative to FUNC, given by S.  This is a structure with the elements "identifier", "message" and "index", giving respectively the error identifier, the error message and the index of the array elements that caused the error.  The size of the output argument of ERRFUNC must have the same size as the output argument of FUNC, otherwise a real error is thrown.  For example
+
+          function y = ferr (s, x), y = "MyString"; endfunction
+          arrayfun (@str2num, [1234], \
+                    "UniformOutput", false, "ErrorHandler", @ferr)
+          => ans =
+          {
+           [1,1] = MyString
+          }
+
+     See also: cellfun, spfun, structfun.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 47
+Execute a function on each element of an array.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+nargchk
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 498
+ -- Function File: MSGSTR = nargchk (MINARGS, MAXARGS, NARGS)
+ -- Function File: MSGSTR = nargchk (MINARGS, MAXARGS, NARGS, "string")
+ -- Function File: MSGSTRUCT = nargchk (MINARGS, MAXARGS, NARGS, "struct")
+     Return an appropriate error message string (or structure) if the number of inputs requested is invalid.
+
+     This is useful for checking to see that the number of input arguments supplied to a function is within an acceptable range.  See also: nargoutchk, error, nargin, nargout.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+Return an appropriate error message string (or structure) if the number of inputs requested is invalid.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+int2str
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 698
+ -- Function File:  int2str (N)
+     Convert an integer (or array of integers) to a string (or a character array).
+
+
+          int2str (123)
+               => "123"
+
+          s = int2str ([1, 2, 3; 4, 5, 6])
+               => s =
+                  1  2  3
+                  4  5  6
+
+          whos s
+               => s =
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     s           2x7                         14  char
+
+     This function is not very flexible.  For better control over the results, use `sprintf' (*note Formatted Output::).  See also: sprintf, num2str, mat2str.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Convert an integer (or array of integers) to a string (or a character array).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+mod
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 496
+ -- Mapping Function:  mod (X, Y)
+     Compute the modulo of X and Y.  Conceptually this is given by
+
+          x - y .* floor (x ./ y)
+
+     and is written such that the correct modulus is returned for integer types.  This function handles negative values correctly.  That is, `mod (-1, 3)' is 2, not -1, as `rem (-1, 3)' returns.  `mod (X, 0)' returns X.
+
+     An error results if the dimensions of the arguments do not agree, or if either of the arguments is complex.  See also: rem, fmod.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+Compute the modulo of X and Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+rot90
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 823
+ -- Function File:  rot90 (X, N)
+     Return a copy of X with the elements rotated counterclockwise in 90-degree increments.  The second argument is optional, and specifies how many 90-degree rotations are to be applied (the default value is 1).  Negative values of N rotate the matrix in a clockwise direction.  For example,
+
+          rot90 ([1, 2; 3, 4], -1)
+               =>  3  1
+                   4  2
+
+     rotates the given matrix clockwise by 90 degrees.  The following are all equivalent statements:
+
+          rot90 ([1, 2; 3, 4], -1)
+          rot90 ([1, 2; 3, 4], 3)
+          rot90 ([1, 2; 3, 4], 7)
+
+     Due to the difficulty of defining an axis about which to rotate the matrix `rot90' only work with 2-D arrays.  To rotate N-d arrays use `rotdim' instead.  See also: rotdim, flipud, fliplr, flipdim.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 86
+Return a copy of X with the elements rotated counterclockwise in 90-degree increments.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+quadl
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1059
+ -- Function File: Q = quadl (F, A, B)
+ -- Function File: Q = quadl (F, A, B, TOL)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE, P1, P2, ...)
+     Numerically evaluate integral using adaptive Lobatto rule.  `quadl (F, A, B)' approximates the integral of `F(X)' to machine precision.  F is either a function handle, inline function or string containing the name of the function to evaluate.  The function F must return a vector of output values if given a vector of input values.
+
+     If defined, TOL defines the relative tolerance to which to which to integrate `F(X)'.  While if TRACE is defined, displays the left end point of the current interval, the interval length, and the partial integral.
+
+     Additional arguments P1, etc., are passed directly to F.  To use default values for TOL and TRACE, one may pass empty matrices.
+
+     Reference: W. Gander and W. Gautschi, 'Adaptive Quadrature - Revisited', BIT Vol. 40, No. 1, March 2000, pp. 84-101.  `http://www.inf.ethz.ch/personal/gander/'
+
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Numerically evaluate integral using adaptive Lobatto rule.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 20
+isequalwithequalnans
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+ -- Function File:  isequalwithequalnans (X1, X2, ...)
+     Assuming NaN == NaN, return true if all of X1, X2, ...  are equal.  See also: isequal.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 52
+Assuming NaN == NaN, return true if all of X1, X2, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+interp1
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2078
+ -- Function File: YI = interp1 (X, Y, XI)
+ -- Function File: YI = interp1 (..., METHOD)
+ -- Function File: YI = interp1 (..., EXTRAP)
+ -- Function File: PP = interp1 (..., 'pp')
+     One-dimensional interpolation.  Interpolate Y, defined at the points X, at the points XI.  The sample points X must be strictly monotonic.  If Y is an array, treat the columns of Y separately.
+
+     Method is one of:
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors
+
+    'pchip'
+          Piece-wise cubic hermite interpolating polynomial
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives throughout the curve
+
+     Appending '*' to the start of the above method forces `interp1' to assume that X is uniformly spaced, and only `X (1)' and `X (2)' are referenced.  This is usually faster, and is never slower.  The default method is 'linear'.
+
+     If EXTRAP is the string 'extrap', then extrapolate values beyond the endpoints.  If EXTRAP is a number, replace values beyond the endpoints with that number.  If EXTRAP is missing, assume NA.
+
+     If the string argument 'pp' is specified, then XI should not be supplied and `interp1' returns the piece-wise polynomial that can later be used with `ppval' to evaluate the interpolation.  There is an equivalence, such that `ppval (interp1 (X, Y, METHOD, 'pp'), XI) == interp1 (X, Y, XI, METHOD, 'extrap')'.
+
+     An example of the use of `interp1' is
+
+          xf = [0:0.05:10];
+          yf = sin (2*pi*xf/5);
+          xp = [0:10];
+          yp = sin (2*pi*xp/5);
+          lin = interp1 (xp, yp, xf);
+          spl = interp1 (xp, yp, xf, "spline");
+          cub = interp1 (xp, yp, xf, "cubic");
+          near = interp1 (xp, yp, xf, "nearest");
+          plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
+                xf, cub, "c", xf, near, "m", xp, yp, "r*");
+          legend ("original", "linear", "spline", "cubic", "nearest")
+
+     See also: interpft.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+One-dimensional interpolation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+cplxpair
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 920
+ -- Function File:  cplxpair (Z)
+ -- Function File:  cplxpair (Z, TOL)
+ -- Function File:  cplxpair (Z, TOL, DIM)
+     Sort the numbers Z into complex conjugate pairs ordered by increasing real part.  Place the negative imaginary complex number first within each pair.  Place all the real numbers (those with `abs (imag (Z) / Z) < TOL)') after the complex pairs.
+
+     If TOL is unspecified the default value is 100*`eps'.
+
+     By default the complex pairs are sorted along the first non-singleton dimension of Z.  If DIM is specified, then the complex pairs are sorted along this dimension.
+
+     Signal an error if some complex numbers could not be paired.  Signal an error if all complex numbers are not exact conjugates (to within TOL).  Note that there is no defined order for pairs with identical real parts but differing imaginary parts.
+
+          cplxpair (exp(2i*pi*[0:4]'/5)) == exp(2i*pi*[3; 2; 4; 1; 0]/5)
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 80
+Sort the numbers Z into complex conjugate pairs ordered by increasing real part.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+genvarname
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2030
+ -- Function File: VARNAME = genvarname (STR)
+ -- Function File: VARNAME = genvarname (STR, EXCLUSIONS)
+     Create unique variable(s) from STR.  If EXCLUSIONS is given, then the variable(s) will be unique to each other and to EXCLUSIONS (EXCLUSIONS may be either a string or a cellstr).
+
+     If STR is a cellstr, then a unique variable is created for each cell in STR.
+
+          x = 3.141;
+          genvarname ("x", who ())
+          => x1
+
+     If WANTED is a cell array, genvarname will make sure the returned strings are distinct:
+
+          genvarname ({"foo", "foo"})
+          =>
+          {
+            [1,1] = foo
+            [1,2] = foo1
+          }
+
+     Note that the result is a char array/cell array of strings, not the variables themselves.  To define a variable, `eval()' can be used.  The following trivial example sets `x' to `42'.
+
+          name = genvarname ("x");
+          eval([name " = 42"]);
+          => x =  42
+
+     Also, this can be useful for creating unique struct field names.
+
+          x = struct ();
+          for i = 1:3
+            x.(genvarname ("a", fieldnames (x))) = i;
+          endfor
+          =>
+          x =
+          {
+            a =  1
+            a1 =  2
+            a2 =  3
+          }
+
+     Since variable names may only contain letters, digits and underscores, genvarname replaces any sequence of disallowed characters with an underscore.  Also, variables may not begin with a digit; in this case an underscore is added before the variable name.
+
+     Variable names beginning and ending with two underscores "__" are valid but they are used internally by octave and should generally be avoided, therefore genvarname will not generate such names.
+
+     genvarname will also make sure that returned names do not clash with keywords such as "for" and "if".  A number will be appended if necessary.  Note, however, that this does *not* include function names, such as "sin".  Such names should be included in AVOID if necessary.  See also: isvarname, exist, tmpnam, eval.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35
+Create unique variable(s) from STR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+fractdiff
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 149
+ -- Function File:  fractdiff (X, D)
+     Compute the fractional differences (1-L)^d x where L denotes the lag-operator and d is greater than -1.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 103
+Compute the fractional differences (1-L)^d x where L denotes the lag-operator and d is greater than -1.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hanning
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 226
+ -- Function File:  hanning (M)
+     Return the filter coefficients of a Hanning window of length M.
+
+     For a definition of this window type, see e.g., A. V. Oppenheim & R. W. Schafer, `Discrete-Time Signal Processing'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return the filter coefficients of a Hanning window of length M.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+fftshift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 640
+ -- Function File:  fftshift (V)
+ -- Function File:  fftshift (V, DIM)
+     Perform a shift of the vector V, for use with the `fft' and `ifft' functions, in order the move the frequency 0 to the center of the vector or matrix.
+
+     If V is a vector of N elements corresponding to N time samples spaced of Dt each, then `fftshift (fft (V))' corresponds to frequencies
+
+          f = ((1:N) - ceil(N/2)) / N / Dt
+
+     If V is a matrix, the same holds for rows and columns.  If V is an array, then the same holds along each dimension.
+
+     The optional DIM argument can be used to limit the dimension along which the permutation occurs.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 150
+Perform a shift of the vector V, for use with the `fft' and `ifft' functions, in order the move the frequency 0 to the center of the vector or matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+freqz_plot
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+ -- Function File:  freqz_plot (W, H)
+     Plot the pass band, stop band and phase response of H.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Plot the pass band, stop band and phase response of H.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+sinewave
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 200
+ -- Function File:  sinewave (M, N, D)
+     Return an M-element vector with I-th element given by `sin (2 * pi * (I+D-1) / N)'.
+
+     The default value for D is 0 and the default value for N is M.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Return an M-element vector with I-th element given by `sin (2 * pi * (I+D-1) / N)'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+autocov
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 219
+ -- Function File:  autocov (X, H)
+     Return the autocovariances from lag 0 to H of vector X.  If H is omitted, all autocovariances are computed.  If X is a matrix, the autocovariances of each column are computed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 55
+Return the autocovariances from lag 0 to H of vector X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+freqz
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1191
+ -- Function File: [H, W] = freqz (B, A, N, "whole")
+     Return the complex frequency response H of the rational IIR filter whose numerator and denominator coefficients are B and A, respectively.  The response is evaluated at N angular frequencies between 0 and  2*pi.
+
+     The output value W is a vector of the frequencies.
+
+     If the fourth argument is omitted, the response is evaluated at frequencies between 0 and  pi.
+
+     If N is omitted, a value of 512 is assumed.
+
+     If A is omitted, the denominator is assumed to be 1 (this corresponds to a simple FIR filter).
+
+     For fastest computation, N should factor into a small number of small primes.
+
+ -- Function File: H = freqz (B, A, W)
+     Evaluate the response at the specific frequencies in the vector W.  The values for W are measured in radians.
+
+ -- Function File: [...] = freqz (..., FS)
+     Return frequencies in Hz instead of radians assuming a sampling rate FS.  If you are evaluating the response at specific frequencies W, those frequencies should be requested in Hz rather than radians.
+
+ -- Function File:  freqz (...)
+     Plot the pass band, stop band and phase response of H rather than returning them.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+Plot the pass band, stop band and phase response of H rather than returning them.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+periodogram
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+ -- Function File:  periodogram (X)
+     For a data matrix X from a sample of size N, return the periodogram.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 68
+For a data matrix X from a sample of size N, return the periodogram.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+arch_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 373
+ -- Function File:  arch_rnd (A, B, T)
+     Simulate an ARCH sequence of length T with AR coefficients B and CH coefficients A.  I.e., the result y(t) follows the model
+
+          y(t) = b(1) + b(2) * y(t-1) + ... + b(lb) * y(t-lb+1) + e(t),
+
+     where e(t), given Y up to time t-1, is N(0, h(t)), with
+
+          h(t) = a(1) + a(2) * e(t-1)^2 + ... + a(la) * e(t-la+1)^2
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Simulate an ARCH sequence of length T with AR coefficients B and CH coefficients A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+sinetone
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 286
+ -- Function File:  sinetone (FREQ, RATE, SEC, AMPL)
+     Return a sinetone of frequency FREQ with length of SEC seconds at sampling rate RATE and with amplitude AMPL.  The arguments FREQ and AMPL may be vectors of common size.
+
+     Defaults are RATE = 8000, SEC = 1 and AMPL = 64.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Return a sinetone of frequency FREQ with length of SEC seconds at sampling rate RATE and with amplitude AMPL.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+triangle_sw
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 126
+ -- Function File:  triangle_sw (N, B)
+     Triangular spectral window.  Subfunction used for spectral density estimation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 27
+Triangular spectral window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+hamming
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 228
+ -- Function File:  hamming (M)
+     Return the filter coefficients of a Hamming window of length M.
+
+     For a definition of the Hamming window, see e.g., A. V. Oppenheim & R. W. Schafer, `Discrete-Time Signal Processing'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Return the filter coefficients of a Hamming window of length M.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+diffpara
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 703
+ -- Function File: [D, DD] = diffpara (X, A, B)
+     Return the estimator D for the differencing parameter of an integrated time series.
+
+     The frequencies from [2*pi*a/t, 2*pi*b/T] are used for the estimation.  If B is omitted, the interval [2*pi/T, 2*pi*a/T] is used.  If both B and A are omitted then a = 0.5 * sqrt (T) and b = 1.5 * sqrt (T) is used, where T is the sample size.  If X is a matrix, the differencing parameter of each column is estimated.
+
+     The estimators for all frequencies in the intervals described above is returned in DD.  The value of D is simply the mean of DD.
+
+     Reference: Brockwell, Peter J. & Davis, Richard A. Time Series: Theory and Methods Springer 1987.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 83
+Return the estimator D for the differencing parameter of an integrated time series.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+rectangle_lw
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 123
+ -- Function File:  rectangle_lw (N, B)
+     Rectangular lag window.  Subfunction used for spectral density estimation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+Rectangular lag window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+blackman
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 231
+ -- Function File:  blackman (M)
+     Return the filter coefficients of a Blackman window of length M.
+
+     For a definition of the Blackman window, see e.g., A. V. Oppenheim & R. W. Schafer, `Discrete-Time Signal Processing'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 64
+Return the filter coefficients of a Blackman window of length M.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+detrend
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 355
+ -- Function File:  detrend (X, P)
+     If X is a vector, `detrend (X, P)' removes the best fit of a polynomial of order P from the data X.
+
+     If X is a matrix, `detrend (X, P)' does the same for each column in X.
+
+     The second argument is optional.  If it is not specified, a value of 1 is assumed.  This corresponds to removing a linear trend.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 99
+If X is a vector, `detrend (X, P)' removes the best fit of a polynomial of order P from the data X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+stft
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 954
+ -- Function File: [Y, C] = stft (X, WIN_SIZE, INC, NUM_COEF, W_TYPE)
+     Compute the short-time Fourier transform of the vector X with NUM_COEF coefficients by applying a window of WIN_SIZE data points and an increment of INC points.
+
+     Before computing the Fourier transform, one of the following windows is applied:
+
+    hanning
+          w_type = 1
+
+    hamming
+          w_type = 2
+
+    rectangle
+          w_type = 3
+
+     The window names can be passed as strings or by the W_TYPE number.
+
+     If not all arguments are specified, the following defaults are used: WIN_SIZE = 80, INC = 24, NUM_COEF = 64, and W_TYPE = 1.
+
+     `Y = stft (X, ...)' returns the absolute values of the Fourier coefficients according to the NUM_COEF positive frequencies.
+
+     `[Y, C] = stft (`x', ...)' returns the entire STFT-matrix Y and a 3-element vector C containing the window size, increment, and window type, which is needed by the synthesis function.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 160
+Compute the short-time Fourier transform of the vector X with NUM_COEF coefficients by applying a window of WIN_SIZE data points and an increment of INC points.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+spectral_adf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 377
+ -- Function File:  spectral_adf (C, WIN, B)
+     Return the spectral density estimator given a vector of autocovariances C, window name WIN, and bandwidth, B.
+
+     The window name, e.g., `"triangle"' or `"rectangle"' is used to search for a function called `WIN_sw'.
+
+     If WIN is omitted, the triangle window is used.  If B is omitted, `1 / sqrt (length (X))' is used.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Return the spectral density estimator given a vector of autocovariances C, window name WIN, and bandwidth, B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+filter2
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 539
+ -- Function File: Y = filter2 (B, X)
+ -- Function File: Y = filter2 (B, X, SHAPE)
+     Apply the 2-D FIR filter B to X.  If the argument SHAPE is specified, return an array of the desired shape.  Possible values are:
+
+    'full'
+          pad X with zeros on all sides before filtering.
+
+    'same'
+          unpadded X (default)
+
+    'valid'
+          trim X after filtering so edge effects are no included.
+
+     Note this is just a variation on convolution, with the parameters reversed and B rotated 180 degrees.  See also: conv2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 32
+Apply the 2-D FIR filter B to X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+fftfilt
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 304
+ -- Function File:  fftfilt (B, X, N)
+     With two arguments, `fftfilt' filters X with the FIR filter B using the FFT.
+
+     Given the optional third argument, N, `fftfilt' uses the overlap-add method to filter X with B using an N-point FFT.
+
+     If X is a matrix, filter each column of the matrix.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 76
+With two arguments, `fftfilt' filters X with the FIR filter B using the FFT.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+fftconv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 429
+ -- Function File:  fftconv (A, B, N)
+     Return the convolution of the vectors A and B, as a vector with length equal to the `length (a) + length (b) - 1'.  If A and B are the coefficient vectors of two polynomials, the returned value is the coefficient vector of the product polynomial.
+
+     The computation uses the FFT by calling the function `fftfilt'.  If the optional argument N is specified, an N-point FFT is used.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 114
+Return the convolution of the vectors A and B, as a vector with length equal to the `length (a) + length (b) - 1'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 11
+triangle_lw
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 121
+ -- Function File:  triangle_lw (N, B)
+     Triangular lag window.  Subfunction used for spectral density estimation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 22
+Triangular lag window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+ifftshift
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 209
+ -- Function File:  ifftshift (V)
+ -- Function File:  ifftshift (V, DIM)
+     Undo the action of the `fftshift' function.  For even length V, `fftshift' is its own inverse, but odd lengths differ slightly.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Undo the action of the `fftshift' function.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+durbinlevinson
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 390
+ -- Function File:  durbinlevinson (C, OLDPHI, OLDV)
+     Perform one step of the Durbin-Levinson algorithm.
+
+     The vector C specifies the autocovariances `[gamma_0, ..., gamma_t]' from lag 0 to T, OLDPHI specifies the coefficients based on C(T-1) and OLDV specifies the corresponding error.
+
+     If OLDPHI and OLDV are omitted, all steps from 1 to T of the algorithm are performed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Perform one step of the Durbin-Levinson algorithm.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+unwrap
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 347
+ -- Function File: B = unwrap (A, TOL, DIM)
+     Unwrap radian phases by adding multiples of 2*pi as appropriate to remove jumps greater than TOL.  TOL defaults to pi.
+
+     Unwrap will unwrap along the first non-singleton dimension of A, unless the optional argument DIM is given, in which case the data will be unwrapped along this dimension
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 97
+Unwrap radian phases by adding multiples of 2*pi as appropriate to remove jumps greater than TOL.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+arch_fit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 859
+ -- Function File: [A, B] = arch_fit (Y, X, P, ITER, GAMMA, A0, B0)
+     Fit an ARCH regression model to the time series Y using the scoring algorithm in Engle's original ARCH paper.  The model is
+
+          y(t) = b(1) * x(t,1) + ... + b(k) * x(t,k) + e(t),
+          h(t) = a(1) + a(2) * e(t-1)^2 + ... + a(p+1) * e(t-p)^2
+
+     in which e(t) is N(0, h(t)), given a time-series vector Y up to time t-1 and a matrix of (ordinary) regressors X up to t.  The order of the regression of the residual variance is specified by P.
+
+     If invoked as `arch_fit (Y, K, P)' with a positive integer K, fit an ARCH(K, P) process, i.e., do the above with the t-th row of X given by
+
+          [1, y(t-1), ..., y(t-k)]
+
+     Optionally, one can specify the number of iterations ITER, the updating factor GAMMA, and initial values a0 and b0 for the scoring algorithm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Fit an ARCH regression model to the time series Y using the scoring algorithm in Engle's original ARCH paper.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+spectral_xdf
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 363
+ -- Function File:  spectral_xdf (X, WIN, B)
+     Return the spectral density estimator given a data vector X, window name WIN, and bandwidth, B.
+
+     The window name, e.g., `"triangle"' or `"rectangle"' is used to search for a function called `WIN_sw'.
+
+     If WIN is omitted, the triangle window is used.  If B is omitted, `1 / sqrt (length (X))' is used.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Return the spectral density estimator given a data vector X, window name WIN, and bandwidth, B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+synthesis
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 254
+ -- Function File:  synthesis (Y, C)
+     Compute a signal from its short-time Fourier transform Y and a 3-element vector C specifying window size, increment, and window type.
+
+     The values Y and C can be derived by
+
+          [Y, C] = stft (X , ...)
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 133
+Compute a signal from its short-time Fourier transform Y and a 3-element vector C specifying window size, increment, and window type.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+rectangle_sw
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 128
+ -- Function File:  rectangle_sw (N, B)
+     Rectangular spectral window.  Subfunction used for spectral density estimation.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 28
+Rectangular spectral window.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+yulewalker
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 235
+ -- Function File: [A, V] = yulewalker (C)
+     Fit an AR (p)-model with Yule-Walker estimates given a vector C of autocovariances `[gamma_0, ..., gamma_p]'.
+
+     Returns the AR coefficients, A, and the variance of white noise, V.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Fit an AR (p)-model with Yule-Walker estimates given a vector C of autocovariances `[gamma_0, .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+arch_test
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 949
+ -- Function File: [PVAL, LM] = arch_test (Y, X, P)
+     For a linear regression model
+
+          y = x * b + e
+
+     perform a Lagrange Multiplier (LM) test of the null hypothesis of no conditional heteroscedascity against the alternative of CH(P).
+
+     I.e., the model is
+
+          y(t) = b(1) * x(t,1) + ... + b(k) * x(t,k) + e(t),
+
+     given Y up to t-1 and X up to t, e(t) is N(0, h(t)) with
+
+          h(t) = v + a(1) * e(t-1)^2 + ... + a(p) * e(t-p)^2,
+
+     and the null is a(1) == ... == a(p) == 0.
+
+     If the second argument is a scalar integer, k, perform the same test in a linear autoregression model of order k, i.e., with
+
+          [1, y(t-1), ..., y(t-K)]
+
+     as the t-th row of X.
+
+     Under the null, LM approximately has a chisquare distribution with P degrees of freedom and PVAL is the p-value (1 minus the CDF of this distribution at LM) of the test.
+
+     If no output argument is given, the p-value is displayed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 30
+For a linear regression model 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+arma_rnd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 562
+ -- Function File:  arma_rnd (A, B, V, T, N)
+     Return a simulation of the ARMA model
+
+          x(n) = a(1) * x(n-1) + ... + a(k) * x(n-k)
+               + e(n) + b(1) * e(n-1) + ... + b(l) * e(n-l)
+
+     in which K is the length of vector A, L is the length of vector B and E is Gaussian white noise with variance V.  The function returns a vector of length T.
+
+     The optional parameter N gives the number of dummy X(I) used for initialization, i.e., a sequence of length T+N is generated and X(N+1:T+N) is returned.  If N is omitted, N = 100 is used.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 38
+Return a simulation of the ARMA model 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+sinc
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+ -- Function File:  sinc (X)
+     Return  sin(pi*x)/(pi*x).
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 24
+Return sin(pi*x)/(pi*x).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+autoreg_matrix
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 337
+ -- Function File:  autoreg_matrix (Y, K)
+     Given a time series (vector) Y, return a matrix with ones in the first column and the first K lagged values of Y in the other columns.  I.e., for T > K, `[1, Y(T-1), ..., Y(T-K)]' is the t-th row of the result.  The resulting matrix may be used as a regressor matrix in autoregressions.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+Given a time series (vector) Y, return a matrix with ones in the first column and the first K lagged values of Y in the other columns.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+autocor
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 222
+ -- Function File:  autocor (X, H)
+     Return the autocorrelations from lag 0 to H of vector X.  If H is omitted, all autocorrelations are computed.  If X is a matrix, the autocorrelations of each column are computed.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 56
+Return the autocorrelations from lag 0 to H of vector X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+bartlett
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+ -- Function File:  bartlett (M)
+     Return the filter coefficients of a Bartlett (triangular) window of length M.
+
+     For a definition of the Bartlett window, see e.g., A. V. Oppenheim & R. W. Schafer, `Discrete-Time Signal Processing'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 77
+Return the filter coefficients of a Bartlett (triangular) window of length M.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+hurst
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 184
+ -- Function File:  hurst (X)
+     Estimate the Hurst parameter of sample X via the rescaled range statistic.  If X is a matrix, the parameter is estimated for every single column.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 74
+Estimate the Hurst parameter of sample X via the rescaled range statistic.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+spencer
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 110
+ -- Function File:  spencer (X)
+     Return Spencer's 15 point moving average of every single column of X.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+Return Spencer's 15 point moving average of every single column of X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+conv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 332
+ -- Function File:  conv (A, B)
+     Convolve two 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, poly, roots, residue, polyval, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 21
+Convolve two vectors.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+roots
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 451
+ -- Function File:  roots (V)
+     For a vector V with N components, return the roots of the polynomial
+
+          v(1) * z^(N-1) + ... + v(N-1) * z + v(N)
+
+     As an example, the following code finds the roots of the quadratic polynomial
+          p(x) = x^2 - 5.
+
+          c = [1, 0, -5];
+          roots(c)
+          =>  2.2361
+          => -2.2361
+     Note that the true result is +/- sqrt(5) which is roughly +/- 2.2361.  See also: compan.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 69
+For a vector V with N components, return the roots of the polynomial 
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+pchip
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1061
+ -- Function File: PP = pchip (X, Y)
+ -- Function File: YI = pchip (X, Y, XI)
+     Piecewise Cubic Hermite interpolating polynomial.  Called with two arguments, the piece-wise polynomial PP is returned, that may later be used with `ppval' to evaluate the polynomial at specific points.
+
+     The variable X must be a strictly monotonic vector (either increasing or decreasing).  While Y can be either a vector or array.  In the case where Y is a vector, it must have a length of N.  If Y is an array, then the size of Y must have the form `[S1, S2, ..., SK, N]' The array is then reshaped internally to a matrix where the leading dimension is given by `S1 * S2 * ... * SK' and each row in this matrix is then treated separately.  Note that this is exactly the opposite treatment than `interp1' and is done for compatibility.
+
+     Called with a third input argument, `pchip' evaluates the piece-wise polynomial at the points XI.  There is an equivalence between `ppval (pchip (X, Y), XI)' and `pchip (X, Y, XI)'.
+
+     See also: spline, ppval, mkpp, unmkpp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Piecewise Cubic Hermite interpolating polynomial.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+polyreduce
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 244
+ -- Function File:  polyreduce (C)
+     Reduces a polynomial coefficient vector to a minimum number of terms by stripping off any leading zeros.  See also: poly, roots, conv, deconv, residue, filter, polyval, polyvalm, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 104
+Reduces a polynomial coefficient vector to a minimum number of terms by stripping off any leading zeros.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+compan
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 914
+ -- Function File:  compan (C)
+     Compute the companion matrix corresponding to polynomial coefficient vector C.
+
+     The companion matrix is
+
+               _                                                        _
+              |  -c(2)/c(1)   -c(3)/c(1)  ...  -c(N)/c(1)  -c(N+1)/c(1)  |
+              |       1            0      ...       0             0      |
+              |       0            1      ...       0             0      |
+          A = |       .            .   .            .             .      |
+              |       .            .       .        .             .      |
+              |       .            .           .    .             .      |
+              |_      0            0      ...       1             0     _|
+
+     The eigenvalues of the companion matrix are equal to the roots of the polynomial.  See also: poly, roots, residue, conv, deconv, polyval, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 78
+Compute the companion matrix corresponding to polynomial coefficient vector C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+residue
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 2331
+ -- Function File: [R, P, K, E] = residue (B, A)
+     Compute the partial fraction expansion for the quotient of the polynomials, B and A.
+
+           B(s)    M       r(m)         N
+           ---- = SUM -------------  + SUM k(i)*s^(N-i)
+           A(s)   m=1 (s-p(m))^e(m)    i=1
+
+     where M is the number of poles (the length of the R, P, and E), the K vector is a polynomial of order N-1 representing the direct contribution, and the E vector specifies the multiplicity of the m-th residue's pole.
+
+     For example,
+
+          b = [1, 1, 1];
+          a = [1, -5, 8, -4];
+          [r, p, k, e] = residue (b, a);
+               => r = [-2; 7; 3]
+               => p = [2; 2; 1]
+               => k = [](0x0)
+               => e = [1; 2; 1]
+
+     which represents the following partial fraction expansion
+
+                  s^2 + s + 1       -2        7        3
+             ------------------- = ----- + ------- + -----
+             s^3 - 5s^2 + 8s - 4   (s-2)   (s-2)^2   (s-1)
+
+ -- Function File: [B, A] = residue (R, P, K)
+ -- Function File: [B, A] = residue (R, P, K, E)
+     Compute the reconstituted quotient of polynomials, B(s)/A(s), from the partial fraction expansion; represented by the residues, poles, and a direct polynomial specified by R, P and K, and the pole multiplicity E.
+
+     If the multiplicity, E, is not explicitly specified the multiplicity is determined by the script mpoles.m.
+
+     For example,
+
+          r = [-2; 7; 3];
+          p = [2; 2; 1];
+          k = [1, 0];
+          [b, a] = residue (r, p, k);
+               => b = [1, -5, 9, -3, 1]
+               => a = [1, -5, 8, -4]
+
+          where mpoles.m is used to determine e = [1; 2; 1]
+
+     Alternatively the multiplicity may be defined explicitly, for example,
+
+          r = [7; 3; -2];
+          p = [2; 1; 2];
+          k = [1, 0];
+          e = [2; 1; 1];
+          [b, a] = residue (r, p, k, e);
+               => b = [1, -5, 9, -3, 1]
+               => a = [1, -5, 8, -4]
+
+     which represents the following partial fraction expansion
+
+              -2        7        3         s^4 - 5s^3 + 9s^2 - 3s + 1
+             ----- + ------- + ----- + s = --------------------------
+             (s-2)   (s-2)^2   (s-1)          s^3 - 5s^2 + 8s - 4
+     See also: poly, roots, conv, deconv, mpoles, polyval, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 212
+Compute the reconstituted quotient of polynomials, B(s)/A(s), from the partial fraction expansion; represented by the residues, poles, and a direct polynomial specified by R, P and K, and the pole multiplicity E.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+polyint
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 331
+ -- Function File:  polyint (C, K)
+     Return the coefficients of the integral of the polynomial whose coefficients are represented by the vector C.  The variable K is the constant of integration, which by default is set to zero.  See also: poly, polyderiv, polyreduce, roots, conv, deconv, residue, filter, polyval, polyvalm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 109
+Return the coefficients of the integral of the polynomial whose coefficients are represented by the vector C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ppval
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 269
+ -- Function File: YI = ppval (PP, XI)
+     Evaluate piece-wise polynomial PP at the points XI.  If `PP.d' is a scalar greater than 1, or an array, then the returned value YI will be an array that is `d1, d1, ..., dk, length (XI)]'.  See also: mkpp, unmkpp, spline.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 51
+Evaluate piece-wise polynomial PP at the points XI.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+spline
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1285
+ -- Function File: PP = spline (X, Y)
+ -- Function File: YI = spline (X, Y, XI)
+     Return the cubic spline interpolant of Y at points X.  If called with two arguments, `spline' returns the piece-wise polynomial PP that may later be used with `ppval' to evaluate the polynomial at specific points.  If called with a third input argument, `spline' evaluates the spline at the points XI.  There is an equivalence between `ppval (spline (X, Y), XI)' and `spline (X, Y, XI)'.
+
+     The variable X must be a vector of length N, and Y can be either a vector or array.  In the case where Y is a vector, it can have a length of either N or `N + 2'.  If the length of Y is N, then the 'not-a-knot' end condition is used.  If the length of Y is `N + 2', then the first and last values of the vector Y are the values of the first derivative of the cubic spline at the end-points.
+
+     If Y is an array, then the size of Y must have the form `[S1, S2, ..., SK, N]' or `[S1, S2, ..., SK, N + 2]'.  The array is then reshaped internally to a matrix where the leading dimension is given by `S1 * S2 * ... * SK' and each row of this matrix is then treated separately.  Note that this is exactly the opposite treatment than `interp1' and is done for compatibility.  See also: ppval, mkpp, unmkpp.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 53
+Return the cubic spline interpolant of Y at points X.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+polyfit
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1013
+ -- Function File: [P, S, MU] = polyfit (X, Y, N)
+     Return the coefficients of a polynomial P(X) of degree N that minimizes the least-squares-error of the fit.
+
+     The polynomial coefficients are returned in a row vector.
+
+     The second output is a structure containing the following fields:
+
+    `R'
+          Triangular factor R from the QR decomposition.
+
+    `X'
+          The Vandermonde matrix used to compute the polynomial coefficients.
+
+    `df'
+          The degrees of freedom.
+
+    `normr'
+          The norm of the residuals.
+
+    `yf'
+          The values of the polynomial for each value of X.
+
+     The second output may be used by `polyval' to calculate the statistical error limits of the predicted values.
+
+     When the third output, MU, is present the coefficients, P, are associated with a polynomial in XHAT = (X-MU(1))/MU(2).  Where MU(1) = mean (X), and MU(2) = std (X).  This linear transformation of X improves the numerical stability of the fit.  See also: polyval, residue.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 107
+Return the coefficients of a polynomial P(X) of degree N that minimizes the least-squares-error of the fit.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+polyder
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 138
+ -- Function File:  polyder (C)
+ -- Function File: [Q] = polyder (B, A)
+ -- Function File: [Q, R] = polyder (B, A)
+     See polyderiv.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 14
+See polyderiv.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+polygcd
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 717
+ -- Function File: Q = polygcd (B, A, TOL)
+     Find greatest common divisor of two polynomials.  This is equivalent to the polynomial found by multiplying together all the common roots.  Together with deconv, you can reduce a ratio of two polynomials.  Tolerance defaults to
+          sqrt(eps).
+      Note that this is an unstable algorithm, so don't try it on large polynomials.
+
+     Example
+          polygcd (poly(1:8), poly(3:12)) - poly(3:8)
+          => [ 0, 0, 0, 0, 0, 0, 0 ]
+          deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))) ...
+            - poly(1:2)
+          => [ 0, 0, 0 ]
+     See also: poly, polyinteg, polyderiv, polyreduce, roots, conv, deconv, residue, filter, polyval, polyvalm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 48
+Find greatest common divisor of two polynomials.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+polyderiv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 495
+ -- Function File:  polyderiv (C)
+ -- Function File: [Q] = polyderiv (B, A)
+ -- Function File: [Q, R] = polyderiv (B, A)
+     Return the coefficients of the derivative of the polynomial whose coefficients are given by vector C.  If a pair of polynomials is given B and A, the derivative of the product is returned in Q, or the quotient numerator in Q and the quotient denominator in R.  See also: poly, polyinteg, polyreduce, roots, conv, deconv, residue, filter, polygcd, polyval, polyvalm.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+Return the coefficients of the derivative of the polynomial whose coefficients are given by vector C.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+deconv
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 385
+ -- Function File:  deconv (Y, A)
+     Deconvolve two 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, poly, roots, residue, polyval, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 23
+Deconvolve two vectors.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+mkpp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 771
+ -- Function File: PP = mkpp (X, P)
+ -- Function File: PP = mkpp (X, P, D)
+     Construct a piece-wise polynomial structure from sample points X and coefficients P.  The i-th row of P, `P (I,:)', contains the coefficients for the polynomial over the I-th interval, ordered from highest to lowest.  There must be one row for each interval in X, so `rows (P) == length (X) - 1'.
+
+     You can concatenate multiple polynomials of the same order over the same set of intervals using `P = [ P1; P2; ...; PD ]'.  In this case, `rows (P) == D * (length (X) - 1)'.
+
+     D specifies the shape of the matrix P for all except the last dimension.  If D is not specified it will be computed as `round (rows (P) / (length (X) - 1))' instead.
+
+     See also: unmkpp, ppval, spline.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Construct a piece-wise polynomial structure from sample points X and coefficients P.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+mpoles
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 873
+ -- Function File: [MULTP, INDX] = mpoles (P)
+ -- Function File: [MULTP, INDX] = mpoles (P, TOL)
+ -- Function File: [MULTP, INDX] = mpoles (P, TOL, REORDER)
+     Identify unique poles in P and associates their multiplicity, ordering them from largest to smallest.
+
+     If the relative difference of the poles is less than TOL, then they are considered to be multiples.  The default value for TOL is 0.001.
+
+     If the optional parameter REORDER is zero, poles are not sorted.
+
+     The value MULTP is a vector specifying the multiplicity of the poles.  MULTP(:) refers to multiplicity of P(INDX(:)).
+
+     For example,
+
+          p = [2 3 1 1 2];
+          [m, n] = mpoles(p);
+            => m = [1; 1; 2; 1; 2]
+            => n = [2; 5; 1; 4; 3]
+            => p(n) = [3, 2, 2, 1, 1]
+
+     See also: poly, roots, conv, deconv, polyval, polyderiv, polyinteg, residue.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+Identify unique poles in P and associates their multiplicity, ordering them from largest to smallest.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+polyval
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 775
+ -- Function File: Y = polyval (P, X)
+ -- Function File: Y = polyval (P, X, [], MU)
+     Evaluate the polynomial at of the specified values for X.  When MU is present evaluate the polynomial for (X-MU(1))/MU(2).  If X is a vector or matrix, the polynomial is evaluated for each of the elements of X.
+
+ -- Function File: [Y, DY] = polyval (P, X, S)
+ -- Function File: [Y, DY] = polyval (P, X, S, MU)
+     In addition to evaluating the polynomial, the second output represents the prediction interval, Y +/- DY, which contains at least 50% of the future predictions.  To calculate the prediction interval, the structured variable S, originating form `polyfit', must be present.  See also: polyfit, polyvalm, poly, roots, conv, deconv, residue, filter, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 160
+In addition to evaluating the polynomial, the second output represents the prediction interval, Y +/- DY, which contains at least 50% of the future predictions.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+convn
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 651
+ -- Function File: C = convn (A, B, SHAPE)
+     N-dimensional convolution of matrices A and B.
+
+     The size of the output is determined by the SHAPE argument.  This can be any of the following character strings:
+
+    "full"
+          The full convolution result is returned.  The size out of the output is `size (A) + size (B)-1'.  This is the default behavior.
+
+    "same"
+          The central part of the convolution result is returned.  The size out of the output is the same as A.
+
+    "valid"
+          The valid part of the convolution is returned.  The size of the result is `max (size (A) - size (B)+1, 0)'.
+
+     See also: conv, conv2.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 46
+N-dimensional convolution of matrices A and B.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+polyvalm
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 397
+ -- Function File:  polyvalm (C, X)
+     Evaluate a polynomial in the matrix sense.
+
+     `polyvalm (C, X)' will evaluate the polynomial in the matrix sense, i.e., matrix multiplication is used instead of element by element multiplication as is used in polyval.
+
+     The argument X must be a square matrix.  See also: polyval, poly, roots, conv, deconv, residue, filter, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 42
+Evaluate a polynomial in the matrix sense.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+polyout
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 334
+ -- Function File:  polyout (C, X)
+     Write formatted polynomial
+             c(x) = c(1) * x^n + ... + c(n) x + c(n+1)
+      and return it as a string or write it to the screen (if NARGOUT is zero).  X defaults to the string `"s"'.  See also: polyval, polyvalm, poly, roots, conv, deconv, residue, filter, polyderiv, polyinteg.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 49
+Write formatted polynomial  c(x) = c(1) * x^n + .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+unmkpp
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 821
+ -- Function File: [X, P, N, K, D] = unmkpp (PP)
+     Extract the components of a piece-wise polynomial structure PP.  These are as follows:
+
+    X
+          Sample points.
+
+    P
+          Polynomial coefficients for points in sample interval.  `P (I, :)' contains the coefficients for the polynomial over interval I ordered from highest to lowest.  If `D > 1', `P (R, I, :)' contains the coefficients for the r-th polynomial defined on interval I.  However, this is stored as a 2-D array such that `C = reshape (P (:, J), N, D)' gives `C (I,  R)' is the j-th coefficient of the r-th polynomial over the i-th interval.
+
+    N
+          Number of polynomial pieces.
+
+    K
+          Order of the polynomial plus 1.
+
+    D
+          Number of polynomials defined for each interval.
+
+     See also: mkpp, ppval, spline.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 63
+Extract the components of a piece-wise polynomial structure PP.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 10
+polyaffine
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 330
+ -- Function File:  polyaffine (F, MU)
+     Return the coefficients of the polynomial whose coefficients are given by vector F after an affine tranformation. If F is the vector representing the polynomial f(x), then G = polytrans (F, MU) is the vector representing
+          g(x) = f((x-MU(1))/MU(2)).
+
+     See also: polyval.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 113
+Return the coefficients of the polynomial whose coefficients are given by vector F after an affine tranformation.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+poly
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 811
+ -- Function File:  poly (A)
+     If A is a square N-by-N matrix, `poly (A)' is the row vector of the coefficients of `det (z * eye (N) - a)', the characteristic polynomial of A.  As an example we can use this to find the eigenvalues of A as the roots of `poly (A)'.
+          roots(poly(eye(3)))
+          => 1.00000 + 0.00000i
+          => 1.00000 - 0.00000i
+          => 1.00000 + 0.00000i
+     In real-life examples you should, however, use the `eig' function for computing eigenvalues.
+
+     If X is a vector, `poly (X)' is a vector of coefficients of the polynomial whose roots are the elements of X.  That is, of C is a polynomial, then the elements of `D = roots (poly (C))' are contained in C.  The vectors C and D are, however, not equal due to sorting and numerical errors.  See also: eig, roots.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 144
+If A is a square N-by-N matrix, `poly (A)' is the row vector of the coefficients of `det (z * eye (N) - a)', the characteristic polynomial of A.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+datetick
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 609
+ -- Function File:  datetick (FORM)
+ -- Function File:  datetick (AXIS, FORM)
+ -- Function File:  datetick (..., "keeplimits")
+ -- Function File:  datetick (..., "keepticks")
+ -- Function File:  datetick (...ax, ...)
+     Adds date formatted tick labels to an axis.  The axis the apply the ticks to is determined by AXIS that can take the values "x", "y" or "z".  The default value is "x".  The formatting of the labels is determined by the variable FORM, that can either be a string in the format needed by `dateform', or a positive integer that can be accepted by `datestr'.  See also: datenum, datestr.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 43
+Adds date formatted tick labels to an axis.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 12
+is_leap_year
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 242
+ -- Function File:  is_leap_year (YEAR)
+     Return 1 if the given year is a leap year and 0 otherwise.  If no arguments are provided, `is_leap_year' will use the current year.  For example,
+
+          is_leap_year (2000)
+               => 1
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 58
+Return 1 if the given year is a leap year and 0 otherwise.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+datenum
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 1408
+ -- Function File:  datenum (YEAR, MONTH, DAY)
+ -- Function File:  datenum (YEAR, MONTH, DAY, HOUR)
+ -- Function File:  datenum (YEAR, MONTH, DAY, HOUR, MINUTE)
+ -- Function File:  datenum (YEAR, MONTH, DAY, HOUR, MINUTE, SECOND)
+ -- Function File:  datenum (`"date"')
+ -- Function File:  datenum (`"date"', P)
+     Returns the specified local time as a day number, with Jan 1, 0000 being day 1.  By this reckoning, Jan 1, 1970 is day number 719529.  The fractional portion, P, corresponds to the portion of the specified day.
+
+     Notes:
+
+        * Years can be negative and/or fractional.
+
+        * Months below 1 are considered to be January.
+
+        * Days of the month start at 1.
+
+        * Days beyond the end of the month go into subsequent months.
+
+        * Days before the beginning of the month go to the previous month.
+
+        * Days can be fractional.
+
+     *Warning:* this function does not attempt to handle Julian calendars so dates before Octave 15, 1582 are wrong by as much as eleven days.  Also be aware that only Roman Catholic countries adopted the calendar in 1582.  It took until 1924 for it to be adopted everywhere.  See the Wikipedia entry on the Gregorian calendar for more details.
+
+     *Warning:* leap seconds are ignored.  A table of leap seconds is available on the Wikipedia entry for leap seconds.  See also: date, clock, now, datestr, datevec, calendar, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 79
+Returns the specified local time as a day number, with Jan 1, 0000 being day 1.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+weekday
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 449
+ -- Function File: [N, S] = weekday (D, [FORM])
+     Return the day of week as a number in N and a string in S, for example `[1, "Sun"]', `[2, "Mon"]', ..., or `[7, "Sat"]'.
+
+     D is a serial date number or a date string.
+
+     If the string FORM is given and is `"long"', S will contain the full name of the weekday; otherwise (or if FORM is `"short"'), S will contain the abbreviated name of the weekday.  See also: datenum, datevec, eomday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 100
+Return the day of week as a number in N and a string in S, for example `[1, "Sun"]', `[2, "Mon"]', .
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 8
+calendar
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 573
+ -- Function File:  calendar (...)
+ -- Function File: C = calendar ()
+ -- Function File: C = calendar (D)
+ -- Function File: C = calendar (Y, M)
+     If called with no arguments, return the current monthly calendar in a 6x7 matrix.
+
+     If D is specified, return the calendar for the month containing the day D, which must be a serial date number or a date string.
+
+     If Y and M are specified, return the calendar for year Y and month M.
+
+     If no output arguments are specified, print the calendar on the screen instead of returning a matrix.  See also: datenum.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+If called with no arguments, return the current monthly calendar in a 6x7 matrix.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 4
+date
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 157
+ -- Function File:  date ()
+     Return the date as a character string in the form DD-MMM-YY.  For example,
+
+          date ()
+               => "20-Aug-93"
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 60
+Return the date as a character string in the form DD-MMM-YY.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+asctime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 299
+ -- Function File:  asctime (TM_STRUCT)
+     Convert a time structure to a string using the following five-field format: Thu Mar 28 08:40:14 1996.  For example,
+
+          asctime (localtime (time ()))
+               => "Mon Feb 17 01:15:06 1997\n"
+
+     This is equivalent to `ctime (time ())'.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 101
+Convert a time structure to a string using the following five-field format: Thu Mar 28 08:40:14 1996.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 9
+addtodate
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 213
+ -- Function File: D = addtodate (D, Q, F)
+     Add Q amount of time (with units F) to the datenum, D.
+
+     F must be one of "year", "month", "day", "hour", "minute", or "second".  See also: datenum, datevec.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 54
+Add Q amount of time (with units F) to the datenum, D.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 6
+eomday
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 134
+ -- Function File: E = eomday (Y, M)
+     Return the last day of the month M for the year Y.  See also: datenum, datevec, weekday.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 50
+Return the last day of the month M for the year Y.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+datevec
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 736
+ -- Function File: V = datevec (DATE)
+ -- Function File: V = datevec (DATE, F)
+ -- Function File: V = datevec (DATE, P)
+ -- Function File: V = datevec (DATE, F, P)
+ -- Function File: [Y, M, D, H, MI, S] = datevec (...)
+     Convert a serial date number (see `datenum') or date string (see `datestr') into a date vector.
+
+     A date vector is a row vector with six members, representing the year, month, day, hour, minute, and seconds respectively.
+
+     F is the format string used to interpret date strings (see `datestr').
+
+     P is the year at the start of the century in which two-digit years are to be interpreted in.  If not specified, it defaults to the current year minus 50.  See also: datenum, datestr, date, clock, now.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 95
+Convert a serial date number (see `datenum') or date string (see `datestr') into a date vector.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+clock
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 324
+ -- Function File:  clock ()
+     Return a vector containing the current year, month (1-12), day (1-31), hour (0-23), minute (0-59) and second (0-61).  For example,
+
+          clock ()
+               => [ 1993, 8, 20, 4, 56, 1 ]
+
+     The function clock is more accurate on systems that have the `gettimeofday' function.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 116
+Return a vector containing the current year, month (1-12), day (1-31), hour (0-23), minute (0-59) and second (0-61).
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+etime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 388
+ -- Function File:  etime (T1, T2)
+     Return the difference (in seconds) between two time values returned from `clock'.  For example:
+
+          t0 = clock ();
+           many computations later...
+          elapsed_time = etime (clock (), t0);
+
+     will set the variable `elapsed_time' to the number of seconds since the variable `t0' was set.  See also: tic, toc, clock, cputime.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 81
+Return the difference (in seconds) between two time values returned from `clock'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 5
+ctime
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 342
+ -- Function File:  ctime (T)
+     Convert a value returned from `time' (or any other non-negative integer), to the local time and return a string of the same form as `asctime'.  The function `ctime (time)' is equivalent to `asctime (localtime (time))'.  For example,
+
+          ctime (time ())
+               => "Mon Feb 17 01:15:06 1997\n"
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 142
+Convert a value returned from `time' (or any other non-negative integer), to the local time and return a string of the same form as `asctime'.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 7
+datestr
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 35322
+ -- Function File: STR = datestr (DATE, [F, [P]])
+     Format the given date/time according to the format `f' and return the result in STR.  DATE is a serial date number (see `datenum') or a date vector (see `datevec').  The value of DATE may also be a string or cell array of strings.
+
+     F can be an integer which corresponds to one of the codes in the table below, or a date format string.
+
+     P is the year at the start of the century in which two-digit years are to be interpreted in.  If not specified, it defaults to the current year minus 50.
+
+     For example, the date 730736.65149 (2000-09-07 15:38:09.0934) would be formatted as follows:
+
+     Code                                                                                                   Format                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Example
+     --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
+     0                                                                                                      dd-mmm-yyyy HH:MM:SS                                                                                                                                                                                                                                                                                                                                                                                                                                                        07-Sep-2000 15:38:09
+     1                                                                                                      dd-mmm-yyyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                 07-Sep-2000
+     2                                                                                                      mm/dd/yy                                                                                                                                                                                                                                                                                                                                                                                                                                                                    09/07/00
+     3                                                                                                      mmm                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Sep
+     4                                                                                                      m                                                                                                                                                                                                                                                                                                                                                                                                                                                                           S
+     5                                                                                                      mm                                                                                                                                                                                                                                                                                                                                                                                                                                                                          09
+     6                                                                                                      mm/dd                                                                                                                                                                                                                                                                                                                                                                                                                                                                       09/07
+     7                                                                                                      dd                                                                                                                                                                                                                                                                                                                                                                                                                                                                          07
+     8                                                                                                      ddd                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Thu
+     9                                                                                                      d                                                                                                                                                                                                                                                                                                                                                                                                                                                                           T
+     10                                                                                                     yyyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2000
+     11                                                                                                     yy                                                                                                                                                                                                                                                                                                                                                                                                                                                                          00
+     12                                                                                                     mmmyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Sep00
+     13                                                                                                     HH:MM:SS                                                                                                                                                                                                                                                                                                                                                                                                                                                                    15:38:09
+     14                                                                                                     HH:MM:SS PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                 03:38:09 PM
+     15                                                                                                     HH:MM                                                                                                                                                                                                                                                                                                                                                                                                                                                                       15:38
+     16                                                                                                     HH:MM PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                    03:38 PM
+     17                                                                                                     QQ-YY                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Q3-00
+     18                                                                                                     QQ                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Q3
+     19                                                                                                     dd/mm                                                                                                                                                                                                                                                                                                                                                                                                                                                                       13/03
+     20                                                                                                     dd/mm/yy                                                                                                                                                                                                                                                                                                                                                                                                                                                                    13/03/95
+     21                                                                                                     mmm.dd.yyyy HH:MM:SS                                                                                                                                                                                                                                                                                                                                                                                                                                                        Mar.03.1962 13:53:06
+     22                                                                                                     mmm.dd.yyyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                 Mar.03.1962
+     23                                                                                                     mm/dd/yyyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                  03/13/1962
+     24                                                                                                     dd/mm/yyyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                  12/03/1962
+     25                                                                                                     yy/mm/dd                                                                                                                                                                                                                                                                                                                                                                                                                                                                    95/03/13
+     26                                                                                                     yyyy/mm/dd                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1995/03/13
+     27                                                                                                     QQ-YYYY                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Q4-2132
+     28                                                                                                     mmmyyyy                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Mar2047
+     29                                                                                                     yyyymmdd                                                                                                                                                                                                                                                                                                                                                                                                                                                                    20470313
+     30                                                                                                     yyyymmddTHHMMSS                                                                                                                                                                                                                                                                                                                                                                                                                                                             20470313T132603
+     31                                                                                                     yyyy-mm-dd HH:MM:SS                                                                                                                                                                                                                                                                                                                                                                                                                                                         1047-03-13 13:26:03
+
+     If F is a format string, the following symbols are recognized:
+
+     Symbol                                                                                                 Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Example
+     -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
+     yyyy                                                                                                   Full year                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 2005
+     yy                                                                                                     Two-digit year                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            2005
+     mmmm                                                                                                   Full month name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           December
+     mmm                                                                                                    Abbreviated month name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Dec
+     mm                                                                                                     Numeric month number (padded with zeros)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  01, 08, 12
+     m                                                                                                      First letter of month name (capitalized)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  D
+     dddd                                                                                                   Full weekday name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Sunday
+     ddd                                                                                                    Abbreviated weekday name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Sun
+     dd                                                                                                     Numeric day of month (padded with zeros)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  11
+     d                                                                                                      First letter of weekday name (capitalized)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                S
+     HH                                                                                                     Hour of day, padded with zeros if PM is set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               09:00
+                                                                                                            and not padded with zeros otherwise                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       9:00 AM
+     MM                                                                                                     Minute of hour (padded with zeros)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        10:05
+     SS                                                                                                     Second of minute (padded with zeros)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      10:05:03
+     PM                                                                                                     Use 12-hour time format                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   11:30 PM
+
+     If F is not specified or is `-1', then use 0, 1 or 16, depending on whether the date portion or the time portion of DATE is empty.
+
+     If P is nor specified, it defaults to the current year minus 50.
+
+     If a matrix or cell array of dates is given, a vector of date strings is returned.
+
+     See also: datenum, datevec, date, clock, now, datetick.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 84
+Format the given date/time according to the format `f' and return the result in STR.
+
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 3
+now
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 437
+ -- Function File: t = now ()
+     Returns the current local time as the number of days since Jan 1, 0000.  By this reckoning, Jan 1, 1970 is day number 719529.
+
+     The integral part, `floor (now)' corresponds to 00:00:00 today.
+
+     The fractional part, `rem (now, 1)' corresponds to the current time on Jan 1, 0000.
+
+     The returned value is also called a "serial date number" (see `datenum').  See also: clock, date, datenum.
+   
+# name: <cell-element>
+# type: string
+# elements: 1
+# length: 71
+Returns the current local time as the number of days since Jan 1, 0000.
+
diff --git a/doc/interpreter/dynamic.texi b/doc/interpreter/dynamic.texi
new file mode 100644
index 0000000..95225cb
--- /dev/null
+++ b/doc/interpreter/dynamic.texi
@@ -0,0 +1,1776 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman
+ at c Copyright (C) 2007 Paul Thomas and Christoph Spiel
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at macro examplefile{file}
+ at example
+ at group
+ at verbatiminclude @value{abs_top_srcdir}/examples/\file\
+ at end group
+ at end example
+ at end macro
+
+ at macro longexamplefile{file}
+ at example
+ at verbatiminclude @value{abs_top_srcdir}/examples/\file\
+ at end example
+ at end macro
+
+ at node Dynamically Linked Functions
+ at appendix Dynamically Linked Functions
+ at cindex dynamic-linking
+
+Octave has the possibility of including compiled code as dynamically
+linked extensions and then using these extensions as if they were part
+of Octave itself.  Octave can call C++ code
+through its native oct-file interface or C code through its mex
+interface.  It can also indirectly call functions written in any other
+language through a simple wrapper.  The reasons to write code in a
+compiled language might be either to link to an existing piece of code
+and allow it to be used within Octave, or to allow improved performance
+for key pieces of code.
+
+Before going further, you should first determine if you really need to
+use dynamically linked functions at all.  Before proceeding with writing
+any dynamically linked function to improve performance you should
+address ask yourself
+
+ at itemize @bullet
+ at item
+Can I get the same functionality using the Octave scripting language only?
+ at item
+Is it thoroughly optimized Octave code?  Vectorization of Octave code,
+doesn't just make it concise, it generally significantly improves its
+performance.  Above all, if loops must be used, make sure that the
+allocation of space for variables takes place outside the loops using an
+assignment to a matrix of the right size, or zeros.
+ at item
+Does it make as much use as possible of existing built-in library
+routines?  These are highly optimized and many do not carry the overhead
+of being interpreted.
+ at item
+Does writing a dynamically linked function represent useful investment
+of your time, relative to staying in Octave?
+ at end itemize
+
+Also, as oct- and mex-files are dynamically linked to Octave, they
+introduce the possibility of Octave crashing due to errors in
+the user code.  For example a segmentation violation in the user's code
+will cause Octave to abort.
+
+ at menu
+* Oct-Files::                   
+* Mex-Files::                   
+* Standalone Programs::         
+ at end menu
+
+ at node Oct-Files
+ at section Oct-Files
+ at cindex oct-files
+ at cindex mkoctfile
+ at cindex oct
+
+ at menu
+* Getting Started with Oct-Files::  
+* Matrices and Arrays in Oct-Files::  
+* Character Strings in Oct-Files::  
+* Cell Arrays in Oct-Files::    
+* Structures in Oct-Files::  
+* Sparse Matrices in Oct-Files::  
+* Accessing Global Variables in Oct-Files::  
+* Calling Octave Functions from Oct-Files::  
+* Calling External Code from Oct-Files::  
+* Allocating Local Memory in Oct-Files::  
+* Input Parameter Checking in Oct-Files::  
+* Exception and Error Handling in Oct-Files::  
+* Documentation and Test of Oct-Files::  
+ at c * Application Programming Interface for Oct-Files::  
+ at end menu
+
+ at node Getting Started with Oct-Files
+ at subsection Getting Started with Oct-Files
+
+The basic command to build oct-files is @code{mkoctfile} and it can be
+call from within octave or from the command line.
+
+ at c ./miscellaneous/mkoctfile.m
+ at anchor{doc-mkoctfile}
+ at deftypefn {Function File} {} mkoctfile [-options] file @dots{}
+
+The @code{mkoctfile} function compiles source code written in C,
+C++, or Fortran.  Depending on the options used with @code{mkoctfile}, the
+compiled code can be called within Octave or can be used as a stand-alone
+application.
+
+ at code{mkoctfile} can be called from the shell prompt or from the Octave
+prompt.
+
+ at code{mkoctfile} accepts the following options, all of which are optional
+except for the file name of the code you wish to compile:
+
+ at table @samp
+ at item -I DIR
+Add the include directory DIR to compile commands.
+
+ at item -D DEF
+Add the definition DEF to the compiler call.
+
+ at item -l LIB
+Add the library LIB to the link command.
+         
+ at item -L DIR
+Add the library directory DIR to the link command.
+
+ at item -M
+ at itemx --depend 
+Generate dependency files (.d) for C and C++ source files.
+         
+ at item -c
+Compile but do not link.
+
+ at item -g
+Enable debugging options for compilers.
+
+ at item -o FILE
+ at itemx --output FILE  
+Output file name.  Default extension is .oct
+(or .mex if --mex is specified) unless linking
+a stand-alone executable.
+
+ at item -p VAR
+ at itemx --print VAR
+Print the configuration variable VAR.  Recognized variables are: 
+
+ at example             
+ at group
+   ALL_CFLAGS                FFTW_LIBS     
+   ALL_CXXFLAGS              FLIBS       
+   ALL_FFLAGS                FPICFLAG      
+   ALL_LDFLAGS               INCFLAGS      
+   BLAS_LIBS                 LDFLAGS             
+   CC                        LD_CXX              
+   CFLAGS                    LD_STATIC_FLAG
+   CPICFLAG                  LFLAGS              
+   CPPFLAGS                  LIBCRUFT      
+   CXX                       LIBOCTAVE     
+   CXXFLAGS                  LIBOCTINTERP  
+   CXXPICFLAG                LIBREADLINE   
+   DEPEND_EXTRA_SED_PATTERN  LIBS        
+   DEPEND_FLAGS              OCTAVE_LIBS   
+   DL_LD                     RDYNAMIC_FLAG 
+   DL_LDFLAGS                RLD_FLAG      
+   F2C                       SED         
+   F2CFLAGS                  XTRA_CFLAGS   
+   F77                       XTRA_CXXFLAGS 
+   FFLAGS
+ at end group
+ at end example
+
+ at item --link-stand-alone
+Link a stand-alone executable file.
+
+ at item --mex
+Assume we are creating a MEX file.  Set the default output extension 
+to ".mex".
+
+ at item -s
+ at itemx --strip
+Strip the output file.
+
+ at item -v
+ at itemx --verbose
+Echo commands as they are executed.
+
+ at item file
+The file to compile or link.  Recognized file types are
+
+ at example
+ at group
+                  .c    C source
+                  .cc   C++ source
+                  .C    C++ source
+                  .cpp  C++ source
+                  .f    Fortran source
+                  .F    Fortran source
+                  .o    object file
+ at end group
+ at end example
+
+ at end table
+ at end deftypefn
+
+
+Consider the short example
+
+ at examplefile{helloworld.cc}
+
+This example although short introduces the basics of writing a C++
+function that can be dynamically linked to Octave.  The easiest way to
+make available most of the definitions that might be necessary for an
+oct-file in Octave is to use the @code{#include <octave/oct.h>}
+header.
+
+The macro that defines the entry point into the dynamically loaded
+function is @w{@code{DEFUN_DLD}}.  This macro takes four arguments, these being
+
+ at enumerate 1
+ at item The function name as it will be seen in Octave,
+ at item The list of arguments to the function of type @code{octave_value_list},
+ at item The number of output arguments, which can and often is omitted if
+not used, and
+ at item The string that will be seen as the help text of the function.
+ at end enumerate
+
+The return type of functions defined with @w{@code{DEFUN_DLD}} is always
+ at code{octave_value_list}.
+
+There are a couple of important considerations in the choice of function
+name.  Firstly, it must be a valid Octave function name and so must be a
+sequence of letters, digits and underscores, not starting with a
+digit.  Secondly, as Octave uses the function name to define the filename
+it attempts to find the function in, the function name in the @w{@code{DEFUN_DLD}}
+macro must match the filename of the oct-file.  Therefore, the above
+function should be in a file @file{helloworld.cc}, and it should be
+compiled to an oct-file using the command
+
+ at example
+mkoctfile helloworld.cc
+ at end example
+
+This will create a file called @file{helloworld.oct}, that is the compiled
+version of the function.  It should be noted that it is perfectly
+acceptable to have more than one @w{@code{DEFUN_DLD}} function in a source
+file.  However, there must either be a symbolic link to the oct-file for
+each of the functions defined in the source code with the @w{@code{DEFUN_DLD}}
+macro or the autoload (@ref{Function Files}) function should be used.
+
+The rest of this function then shows how to find the number of input
+arguments, how to print through the octave pager, and return from the
+function.  After compiling this function as above, an example of its use
+is
+
+ at example
+ at group
+helloworld (1, 2, 3)
+ at print{} Hello World has 3 input arguments and 0 output arguments.
+ at end group
+ at end example
+
+ at node Matrices and Arrays in Oct-Files
+ at subsection Matrices and Arrays in Oct-Files
+
+Octave supports a number of different array and matrix classes, the
+majority of which are based on the Array class.  The exception is the
+sparse matrix types discussed separately below.  There are three basic
+matrix types
+
+ at table @code
+ at item Matrix
+A double precision matrix class defined in dMatrix.h,
+ at item ComplexMatrix
+A complex matrix class defined in CMatrix.h, and
+ at item BoolMatrix
+A boolean matrix class defined in boolMatrix.h.
+ at end table
+
+These are the basic two-dimensional matrix types of octave.  In
+additional there are a number of multi-dimensional array types, these
+being
+
+ at table @code
+ at item NDArray
+A double precision array class defined in @file{dNDArray.h}
+ at item ComplexNDarray
+A complex array class defined in @file{CNDArray.h}
+ at item boolNDArray
+A boolean array class defined in @file{boolNDArray.h}
+ at item int8NDArray
+ at itemx int16NDArray
+ at itemx int32NDArray
+ at itemx int64NDArray
+8, 16, 32 and 64-bit signed array classes defined in
+ at file{int8NDArray.h}, @file{int16NDArray.h}, etc.
+ at item uint8NDArray
+ at itemx uint16NDArray
+ at itemx uint32NDArray
+ at itemx uint64NDArray
+8, 16, 32 and 64-bit unsigned array classes defined in
+ at file{uint8NDArray.h}, @file{uint16NDArray.h}, etc.
+ at end table
+
+There are several basic means of constructing matrices of
+multi-dimensional arrays.  Considering the @code{Matrix} type as an
+example
+
+ at itemize @bullet
+ at item
+We can create an empty matrix or array with the empty constructor.  For
+example
+
+ at example
+Matrix a;
+ at end example
+
+This can be used on all matrix and array types
+ at item
+Define the dimensions of the matrix or array with a dim_vector.  For
+example
+
+ at example
+ at group
+dim_vector dv (2);
+dv(0) = 2; dv(1) = 2;
+Matrix a (dv);
+ at end group
+ at end example
+
+This can be used on all matrix and array types
+ at item
+Define the number of rows and columns in the matrix.  For example
+
+ at example
+Matrix a (2, 2)
+ at end example
+
+However, this constructor can only be used with the matrix types.
+ at end itemize
+
+These types all share a number of basic methods and operators, a
+selection of which include
+
+ at deftypefn Method T& {operator ()} (octave_idx_type)
+ at deftypefnx Method T& elem (octave_idx_type)
+The @code{()} operator or @code{elem} method allow the values of the
+matrix or array to be read or set.  These can take a single argument,
+which is of type @code{octave_idx_type}, that is the index into the matrix or
+array.  Additionally, the matrix type allows two argument versions of the
+ at code{()} operator and elem method, giving the row and column index of the
+value to obtain or set.
+ at end deftypefn
+
+Note that these functions do significant error checking and so in some
+circumstances the user might prefer to access the data of the array or
+matrix directly through the fortran_vec method discussed below.
+
+ at deftypefn Method octave_idx_type nelem (void) const
+The total number of elements in the matrix or array.
+ at end deftypefn
+
+ at deftypefn Method size_t byte_size (void) const
+The number of bytes used to store the matrix or array.
+ at end deftypefn
+
+ at deftypefn Method dim_vector dims (void) const
+The dimensions of the matrix or array in value of type dim_vector.
+ at end deftypefn
+
+ at deftypefn Method void resize (const dim_vector&)
+A method taking either an argument of type @code{dim_vector}, or in the
+case of a matrix two arguments of type @code{octave_idx_type} defining
+the number of rows and columns in the matrix.
+ at end deftypefn
+
+ at deftypefn Method T* fortran_vec (void)
+This method returns a pointer to the underlying data of the matrix or a
+array so that it can be manipulated directly, either within Octave or by
+an external library.
+ at end deftypefn
+
+Operators such an @code{+}, @code{-}, or @code{*} can be used on the
+majority of the above types.  In addition there are a number of methods
+that are of interest only for matrices such as @code{transpose},
+ at code{hermitian}, @code{solve}, etc.
+
+The typical way to extract a matrix or array from the input arguments of
+ at w{@code{DEFUN_DLD}} function is as follows
+
+ at examplefile{addtwomatrices.cc}
+
+To avoid segmentation faults causing Octave to abort, this function
+explicitly checks that there are sufficient arguments available before
+accessing these arguments.  It then obtains two multi-dimensional arrays
+of type @code{NDArray} and adds these together.  Note that the array_value
+method is called without using the @code{is_matrix_type} type, and instead the
+error_state is checked before returning @code{A + B}.  The reason to
+prefer this is that the arguments might be a type that is not an
+ at code{NDArray}, but it would make sense to convert it to one.  The
+ at code{array_value} method allows this conversion to be performed
+transparently if possible, and sets @code{error_state} if it is not.
+
+ at code{A + B}, operating on two @code{NDArray}'s returns an
+ at code{NDArray}, which is cast to an @code{octave_value} on the return
+from the function.  An example of the use of this demonstration function
+is
+
+ at example
+ at group
+addtwomatrices (ones (2, 2), ones (2, 2))
+      @result{}  2  2
+          2  2
+ at end group
+ at end example
+
+A list of the basic @code{Matrix} and @code{Array} types, the methods to
+extract these from an @code{octave_value} and the associated header is
+listed below.
+
+ at multitable @columnfractions .3 .4 .3
+ at item @code{RowVector} @tab @code{row_vector_value} @tab @file{dRowVector.h}
+ at item @code{ComplexRowVector} @tab @code{complex_row_vector_value} @tab @file{CRowVector.h}
+ at item @code{ColumnVector} @tab @code{column_vector_value} @tab @file{dColVector.h}
+ at item @code{ComplexColumnVector} @tab @code{complex_column_vector_value} @tab @file{CColVector.h}
+ at item @code{Matrix} @tab @code{matrix_value} @tab @file{dMatrix.h}
+ at item @code{ComplexMatrix} @tab @code{complex_matrix_value} @tab @file{CMatrix.h}
+ at item @code{boolMatrix} @tab @code{bool_matrix_value} @tab @file{boolMatrix.h}
+ at item @code{charMatrix} @tab @code{char_matrix_value} @tab @file{chMatrix.h}
+ at item @code{NDArray} @tab @code{array_value} @tab @file{dNDArray.h}
+ at item @code{ComplexNDArray} @tab @code{complex_array_value} @tab @file{CNDArray.h}
+ at item @code{boolNDArray} @tab @code{bool_array_value} @tab @file{boolNDArray.h}
+ at item @code{charNDArray} @tab @code{char_array_value} @tab @file{charNDArray.h}
+ at item @code{int8NDArray} @tab @code{int8_array_value} @tab @file{int8NDArray.h}
+ at item @code{int16NDArray} @tab @code{int16_array_value} @tab @file{int16NDArray.h}
+ at item @code{int32NDArray} @tab @code{int32_array_value} @tab @file{int32NDArray.h}
+ at item @code{int64NDArray} @tab @code{int64_array_value} @tab @file{int64NDArray.h}
+ at item @code{uint8NDArray} @tab @code{uint8_array_value} @tab @file{uint8NDArray.h}
+ at item @code{uint16NDArray} @tab @code{uint16_array_value} @tab @file{uint16NDArray.h}
+ at item @code{uint32NDArray} @tab @code{uint32_array_value} @tab @file{uint32NDArray.h}
+ at item @code{uint64NDArray} @tab @code{uint64_array_value} @tab @file{uint64NDArray.h}
+ at end multitable
+
+ at node Character Strings in Oct-Files
+ at subsection Character Strings in Oct-Files
+
+In Octave a character string is just a special @code{Array} class.
+Consider the example 
+
+ at longexamplefile{stringdemo.cc}
+
+An example of the use of this function is
+
+ at example
+ at group
+s0 = ["First String"; "Second String"];
+[s1,s2] = stringdemo (s0)
+ at result{} s1 = Second String
+        First String
+
+ at result{} s2 = First String
+        Second String
+
+typeinfo (s2)
+ at result{} sq_string
+typeinfo (s1)
+ at result{} string
+ at end group
+ at end example
+
+One additional complication of strings in Octave is the difference
+between single quoted and double quoted strings.  To find out if an
+ at code{octave_value} contains a single or double quoted string an example is
+
+ at example
+ at group
+    if (args(0).is_sq_string ())
+      octave_stdout << 
+        "First argument is a singularly quoted string\n";
+    else if (args(0).is_dq_string ())
+      octave_stdout << 
+        "First argument is a doubly quoted string\n";
+ at end group
+ at end example
+
+Note however, that both types of strings are represented by the
+ at code{charNDArray} type, and so when assigning to an
+ at code{octave_value}, the type of string should be specified.  For example
+
+ at example
+ at group
+octave_value_list retval;
+charNDArray c;
+ at dots{}
+// Create single quoted string
+retval(1) = octave_value (ch, true, '\'');
+
+// Create a double quoted string
+retval(0) = octave_value (ch, true);
+ at end group
+ at end example
+
+ at node Cell Arrays in Oct-Files
+ at subsection Cell Arrays in Oct-Files
+
+Octave's cell type is equally accessible within oct-files.  A cell
+array is just an array of @code{octave_value}s, and so each element of the cell
+array can then be treated just like any other @code{octave_value}.  A simple
+example is
+
+ at examplefile{celldemo.cc}
+
+Note that cell arrays are used less often in standard oct-files and so
+the @file{Cell.h} header file must be explicitly included.  The rest of this
+example extracts the @code{octave_value}s one by one from the cell array and
+returns be as individual return arguments.  For example consider
+
+ at example
+ at group
+[b1, b2, b3] = celldemo (@{1, [1, 2], "test"@})
+ at result{}
+b1 =  1
+b2 =
+
+   1   2
+
+b3 = test
+ at end group
+ at end example
+
+ at node Structures in Oct-Files
+ at subsection Structures in Oct-Files
+
+A structure in Octave is map between a number of fields represented and
+their values.  The Standard Template Library @code{map} class is used,
+with the pair consisting of a @code{std::string} and an octave
+ at code{Cell} variable.
+
+A simple example demonstrating the use of structures within oct-files is
+
+ at longexamplefile{structdemo.cc}
+
+An example of its use is
+
+ at example
+ at group
+x.a = 1; x.b = "test"; x.c = [1, 2];
+structdemo (x, "b")
+ at result{} selected = test
+ at end group
+ at end example
+
+The commented code above demonstrates how to iterate over all of the
+fields of the structure, where as the following code demonstrates finding
+a particular field in a more concise manner.
+
+As can be seen the @code{contents} method of the @code{Octave_map} class
+returns a @code{Cell} which allows structure arrays to be represented.
+Therefore, to obtain the underlying @code{octave_value} we write
+
+ at example
+octave_value tmp = arg0.contents (p1) (0);
+ at end example
+
+where the trailing (0) is the () operator on the @code{Cell} object.  We
+can equally iterate of the elements of the Cell array to address the
+elements of the structure array.
+
+ at node Sparse Matrices in Oct-Files
+ at subsection Sparse Matrices in Oct-Files
+
+There are three classes of sparse objects that are of interest to the
+user.
+
+ at table @code
+ at item SparseMatrix
+A double precision sparse matrix class
+ at item SparseComplexMatrix
+A complex sparse matrix class
+ at item SparseBoolMatrix
+A boolean sparse matrix class
+ at end table
+
+All of these classes inherit from the @code{Sparse<T>} template class,
+and so all have similar capabilities and usage.  The @code{Sparse<T>}
+class was based on Octave @code{Array<T>} class, and so users familiar
+with Octave's @code{Array} classes will be comfortable with the use of
+the sparse classes.
+
+The sparse classes will not be entirely described in this section, due
+to their similarity with the existing @code{Array} classes.  However,
+there are a few differences due the different nature of sparse objects,
+and these will be described.  Firstly, although it is fundamentally
+possible to have N-dimensional sparse objects, the Octave sparse classes do
+not allow them at this time.  So all operations of the sparse classes
+must be 2-dimensional.  This means that in fact @code{SparseMatrix} is
+similar to Octave's @code{Matrix} class rather than its
+ at code{NDArray} class.
+
+ at menu
+* Array and Sparse Differences::  
+* Creating Sparse Matrices in Oct-Files::  
+* Using Sparse Matrices in Oct-Files::  
+ at end menu
+
+ at node Array and Sparse Differences
+ at subsubsection The Differences between the Array and Sparse Classes
+
+The number of elements in a sparse matrix is considered to be the number
+of non-zero elements rather than the product of the dimensions.  Therefore
+
+ at example
+ at group
+SparseMatrix sm;
+ at dots{}
+int nel = sm.nelem ();
+ at end group
+ at end example
+
+returns the number of non-zero elements.  If the user really requires the
+number of elements in the matrix, including the non-zero elements, they
+should use @code{numel} rather than @code{nelem}.  Note that for very
+large matrices, where the product of the two dimensions is larger than
+the representation of an unsigned int, then @code{numel} can overflow.
+An example is @code{speye(1e6)} which will create a matrix with a million
+rows and columns, but only a million non-zero elements.  Therefore the
+number of rows by the number of columns in this case is more than two
+hundred times the maximum value that can be represented by an unsigned int.
+The use of @code{numel} should therefore be avoided useless it is known
+it won't overflow.
+
+Extreme care must be take with the elem method and the "()" operator,
+which perform basically the same function.  The reason is that if a
+sparse object is non-const, then Octave will assume that a
+request for a zero element in a sparse matrix is in fact a request
+to create this element so it can be filled.  Therefore a piece of
+code like
+
+ at example
+ at group
+SparseMatrix sm;
+ at dots{}
+for (int j = 0; j < nc; j++)
+  for (int i = 0; i < nr; i++)
+    std::cerr << " (" << i << "," << j << "): " << sm(i,j)
+              << std::endl;
+ at end group
+ at end example
+
+is a great way of turning the sparse matrix into a dense one, and a
+very slow way at that since it reallocates the sparse object at each
+zero element in the matrix.
+
+An easy way of preventing the above from happening is to create a temporary
+constant version of the sparse matrix.  Note that only the container for
+the sparse matrix will be copied, while the actual representation of the
+data will be shared between the two versions of the sparse matrix.  So this
+is not a costly operation.  For example, the above would become
+
+ at example
+ at group
+SparseMatrix sm;
+ at dots{}
+const SparseMatrix tmp (sm);
+for (int j = 0; j < nc; j++)
+  for (int i = 0; i < nr; i++)
+    std::cerr << " (" << i << "," << j << "): " << tmp(i,j)
+              << std::endl;
+ at end group
+ at end example
+
+Finally, as the sparse types aren't just represented as a contiguous
+block of memory, the @code{fortran_vec} method of the @code{Array<T>}
+is not available.  It is however replaced by three separate methods
+ at code{ridx}, @code{cidx} and @code{data}, that access the raw compressed
+column format that the Octave sparse matrices are stored in.
+Additionally, these methods can be used in a manner similar to @code{elem},
+to allow the matrix to be accessed or filled.  However, in that case it is
+up to the user to respect the sparse matrix compressed column format
+discussed previous.
+
+ at node Creating Sparse Matrices in Oct-Files
+ at subsubsection Creating Sparse Matrices in Oct-Files
+
+You have several alternatives for creating a sparse matrix.
+You can first create the data as three vectors representing the
+row and column indexes and the data, and from those create the matrix.
+Or alternatively, you can create a sparse matrix with the appropriate
+amount of space and then fill in the values.  Both techniques have their
+advantages and disadvantages.
+
+Here is an example of how to create a small sparse matrix with the first
+technique
+
+ at example
+ at group
+int nz = 4, nr = 3, nc = 4;
+
+ColumnVector ridx (nz);
+ColumnVector cidx (nz);
+ColumnVector data (nz);
+
+ridx(0) = 0; ridx(1) = 0; ridx(2) = 1; ridx(3) = 2;
+cidx(0) = 0; cidx(1) = 1; cidx(2) = 3; cidx(3) = 3;
+data(0) = 1; data(1) = 2; data(2) = 3; data(3) = 4;
+
+SparseMatrix sm (data, ridx, cidx, nr, nc);
+ at end group
+ at end example
+
+ at noindent
+which creates the matrix given in section
+ at ref{Storage of Sparse Matrices}.  Note that the compressed matrix
+format is not used at the time of the creation of the matrix itself,
+however it is used internally.
+
+As previously mentioned, the values of the sparse matrix are stored
+in increasing column-major ordering.  Although the data passed by the
+user does not need to respect this requirement, the pre-sorting the
+data significantly speeds up the creation of the sparse matrix.
+
+The disadvantage of this technique of creating a sparse matrix is
+that there is a brief time where two copies of the data exists.  Therefore
+for extremely memory constrained problems this might not be the right
+technique to create the sparse matrix.
+
+The alternative is to first create the sparse matrix with the desired
+number of non-zero elements and then later fill those elements in.  The
+easiest way to do this is
+
+ at example
+ at group
+int nz = 4, nr = 3, nc = 4;
+SparseMatrix sm (nr, nc, nz);
+sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+ at end group
+ at end example
+
+That creates the same matrix as previously.  Again, although it is not
+strictly necessary, it is significantly faster if the sparse matrix is
+created in this manner that the elements are added in column-major
+ordering.  The reason for this is that if the elements are inserted
+at the end of the current list of known elements then no element
+in the matrix needs to be moved to allow the new element to be
+inserted.  Only the column indexes need to be updated.
+
+There are a few further points to note about this technique of creating
+a sparse matrix.  Firstly, it is possible to create a sparse matrix
+with fewer elements than are actually inserted in the matrix.  Therefore
+
+ at example
+ at group
+int nz = 4, nr = 3, nc = 4;
+SparseMatrix sm (nr, nc, 0);
+sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+ at end group
+ at end example
+
+ at noindent 
+is perfectly valid.  However it is a very bad idea.  The reason is that
+as each new element is added to the sparse matrix the space allocated
+to it is increased by reallocating the memory.  This is an expensive
+operation, that will significantly slow this means of creating a sparse
+matrix.  Furthermore, it is possible to create a sparse matrix with
+too much storage, so having @var{nz} above equaling 6 is also valid.
+The disadvantage is that the matrix occupies more memory than strictly
+needed.
+
+It is not always easy to know the number of non-zero elements prior
+to filling a matrix.  For this reason the additional storage for the
+sparse matrix can be removed after its creation with the
+ at dfn{maybe_compress} function.  Furthermore, the maybe_compress can
+deallocate the unused storage, but it can equally remove zero elements
+from the matrix.  The removal of zero elements from the matrix is
+controlled by setting the argument of the @dfn{maybe_compress} function
+to be @samp{true}.  However, the cost of removing the zeros is high because it
+implies resorting the elements.  Therefore, if possible it is better
+is the user doesn't add the zeros in the first place.  An example of
+the use of @dfn{maybe_compress} is
+
+ at example
+ at group
+  int nz = 6, nr = 3, nc = 4;
+
+  SparseMatrix sm1 (nr, nc, nz);
+  sm1(0,0) = 1; sm1(0,1) = 2; sm1(1,3) = 3; sm1(2,3) = 4;
+  sm1.maybe_compress ();  // No zero elements were added
+
+  SparseMatrix sm2 (nr, nc, nz);
+  sm2(0,0) = 1; sm2(0,1) = 2; sm(0,2) = 0; sm(1,2) = 0;
+  sm1(1,3) = 3; sm1(2,3) = 4;
+  sm2.maybe_compress (true);  // Zero elements were added
+ at end group
+ at end example
+
+The use of the @dfn{maybe_compress} function should be avoided if
+possible, as it will slow the creation of the matrices.
+
+A third means of creating a sparse matrix is to work directly with
+the data in compressed row format.  An example of this technique might
+be
+
+ at c Note the @verbatim environment is a relatively new addition to texinfo.
+ at c Therefore use the @example environment and replace @, with @@,
+ at c { with @{, etc
+
+ at example
+octave_value arg;
+ at dots{}
+int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+SparseMatrix sm (nr, nc, nz);
+Matrix m = arg.matrix_value ();
+
+int ii = 0;
+sm.cidx (0) = 0;
+for (int j = 1; j < nc; j++)
+  @{
+    for (int i = 0; i < nr; i++)
+      @{
+        double tmp = foo (m(i,j));
+        if (tmp != 0.)
+          @{
+            sm.data(ii) = tmp;
+            sm.ridx(ii) = i;
+            ii++;
+          @}
+      @}
+    sm.cidx(j+1) = ii;
+ @}
+sm.maybe_compress ();  // If don't know a-priori 
+                       // the final no of nz.
+ at end example
+
+ at noindent
+which is probably the most efficient means of creating the sparse matrix.
+
+Finally, it might sometimes arise that the amount of storage initially
+created is insufficient to completely store the sparse matrix.  Therefore,
+the method @code{change_capacity} exists to reallocate the sparse memory.
+The above example would then be modified as
+
+ at example
+octave_value arg;
+ at dots{}
+int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+SparseMatrix sm (nr, nc, nz);
+Matrix m = arg.matrix_value ();
+
+int ii = 0;
+sm.cidx (0) = 0;
+for (int j = 1; j < nc; j++)
+  @{
+    for (int i = 0; i < nr; i++)
+      @{
+        double tmp = foo (m(i,j));
+        if (tmp != 0.)
+          @{
+            if (ii == nz)
+              @{
+                nz += 2;   // Add 2 more elements
+                sm.change_capacity (nz);
+              @}
+            sm.data(ii) = tmp;
+            sm.ridx(ii) = i;
+            ii++;
+          @}
+      @}
+    sm.cidx(j+1) = ii;
+ @}
+sm.maybe_mutate ();  // If don't know a-priori 
+                     // the final no of nz.
+ at end example
+
+Note that both increasing and decreasing the number of non-zero elements in
+a sparse matrix is expensive, as it involves memory reallocation.  Also as
+parts of the matrix, though not its entirety, exist as the old and new copy
+at the same time, additional memory is needed.  Therefore if possible this
+should be avoided.
+
+ at node Using Sparse Matrices in Oct-Files
+ at subsubsection Using Sparse Matrices in Oct-Files
+
+Most of the same operators and functions on sparse matrices that are
+available from the Octave are equally available with oct-files.
+The basic means of extracting a sparse matrix from an @code{octave_value}
+and returning them as an @code{octave_value}, can be seen in the
+following example
+
+ at example
+ at group
+octave_value_list retval;
+
+SparseMatrix sm = args(0).sparse_matrix_value ();
+SparseComplexMatrix scm = 
+    args(1).sparse_complex_matrix_value ();
+SparseBoolMatrix sbm = args(2).sparse_bool_matrix_value ();
+ at dots{}
+retval(2) = sbm;
+retval(1) = scm;
+retval(0) = sm;
+ at end group
+ at end example
+
+The conversion to an octave-value is handled by the sparse
+ at code{octave_value} constructors, and so no special care is needed.
+
+ at node Accessing Global Variables in Oct-Files
+ at subsection Accessing Global Variables in Oct-Files
+
+Global variables allow variables in the global scope to be
+accessed.  Global variables can easily be accessed with oct-files using
+the support functions @code{get_global_value} and
+ at code{set_global_value}.  @code{get_global_value} takes two arguments,
+the first is a string representing the variable name to obtain.  The
+second argument is a boolean argument specifying what to do in the case
+that no global variable of the desired name is found.  An example of the
+use of these two functions is
+
+ at longexamplefile{globaldemo.cc}
+
+An example of its use is
+
+ at example
+ at group
+global a b
+b = 10;
+globaldemo ("b")
+ at result{} 10
+globaldemo ("c")
+ at result{} "Global variable not found"
+num2str (a)
+ at result{} 42
+ at end group
+ at end example
+
+ at node Calling Octave Functions from Oct-Files
+ at subsection Calling Octave Functions from Oct-Files
+
+There is often a need to be able to call another octave function from
+within an oct-file, and there are many examples of such within octave
+itself.  For example the @code{quad} function is an oct-file that
+calculates the definite integral by quadrature over a user supplied
+function.
+
+There are also many ways in which a function might be passed.  It might
+be passed as one of
+
+ at enumerate 1
+ at item Function Handle
+ at item Anonymous Function Handle
+ at item Inline Function
+ at item String
+ at end enumerate
+
+The example below demonstrates an example that accepts all four means of
+passing a function to an oct-file.
+
+ at longexamplefile{funcdemo.cc}
+
+The first argument to this demonstration is the user supplied function
+and the following arguments are all passed to the user function.
+
+ at example
+ at group
+funcdemo (@@sin,1)
+ at result{} 0.84147
+funcdemo (@@(x) sin(x), 1)
+ at result{} 0.84147
+funcdemo (inline ("sin(x)"), 1)
+ at result{} 0.84147
+funcdemo ("sin",1)
+ at result{} 0.84147
+funcdemo (@@atan2, 1, 1)
+ at result{} 0.78540
+ at end group
+ at end example
+
+When the user function is passed as a string, the treatment of the
+function is different.  In some cases it is necessary to always have the
+user supplied function as an @code{octave_function} object.  In that
+case the string argument can be used to create a temporary function like
+
+ at example
+ at group
+std::octave fcn_name = unique_symbol_name ("__fcn__");
+std::string fname = "function y = ";
+fname.append (fcn_name);
+fname.append ("(x) y = ");
+fcn = extract_function (args(0), "funcdemo", fcn_name,
+                        fname, "; endfunction");
+ at dots{}
+if (fcn_name.length ())
+  clear_function (fcn_name);
+ at end group
+ at end example
+
+There are two important things to know in this case.  The number of input
+arguments to the user function is fixed, and in the above is a single
+argument, and secondly to avoid leaving the temporary function in the
+Octave symbol table it should be cleared after use.
+
+ at node Calling External Code from Oct-Files
+ at subsection Calling External Code from Oct-Files
+
+Linking external C code to Octave is relatively simple, as the C
+functions can easily be called directly from C++.  One possible issue is
+the declarations of the external C functions might need to be explicitly
+defined as C functions to the compiler.  If the declarations of the
+external C functions are in the header @code{foo.h}, then the manner in
+which to ensure that the C++ compiler treats these declarations as C
+code is
+
+ at example
+ at group
+#ifdef __cplusplus
+extern "C"
+@{
+#endif
+#include "foo.h"
+#ifdef __cplusplus
+@}  /* end extern "C" */
+#endif
+ at end group
+ at end example
+
+Calling Fortran code however can pose some difficulties.  This is due to
+differences in the manner in compilers treat the linking of Fortran code
+with C or C++ code.  Octave supplies a number of macros that allow
+consistent behavior across a number of compilers.
+
+The underlying Fortran code should use the @code{XSTOPX} function to
+replace the Fortran @code{STOP} function.  @code{XSTOPX} uses the Octave
+exception handler to treat failing cases in the fortran code
+explicitly.  Note that Octave supplies its own replacement @sc{blas}
+ at code{XERBLA} function, which uses @code{XSTOPX}.
+
+If the underlying code calls @code{XSTOPX}, then the @w{@code{F77_XFCN}}
+macro should be used to call the underlying fortran function.  The Fortran
+exception state can then be checked with the global variable
+ at code{f77_exception_encountered}.  If @code{XSTOPX} will not be called,
+then the @w{@code{F77_FCN}} macro should be used instead to call the Fortran
+code.
+
+There is no harm in using @w{@code{F77_XFCN}} in all cases, except that for
+Fortran code that is short running and executes a large number of times,
+there is potentially an overhead in doing so.  However, if @w{@code{F77_FCN}}
+is used with code that calls @code{XSTOP}, Octave can generate a
+segmentation fault.
+
+An example of the inclusion of a Fortran function in an oct-file is
+given in the following example, where the C++ wrapper is
+
+ at longexamplefile{fortdemo.cc}
+
+ at noindent
+and the fortran function is
+
+ at longexamplefile{fortsub.f}
+
+This example demonstrates most of the features needed to link to an
+external Fortran function, including passing arrays and strings, as well
+as exception handling.  An example of the behavior of this function is
+
+ at example
+ at group
+[b, s] = fortdemo (1:3)
+ at result{}
+  b = 1.00000   0.50000   0.33333
+  s = There are   3 values in the input vector
+[b, s] = fortdemo(0:3)
+error: fortsub:divide by zero
+error: exception encountered in Fortran subroutine fortsub_
+error: fortdemo: error in fortran
+ at end group
+ at end example
+
+ at node Allocating Local Memory in Oct-Files
+ at subsection Allocating Local Memory in Oct-Files
+
+Allocating memory within an oct-file might seem easy as the C++
+new/delete operators can be used.  However, in that case care must be
+taken to avoid memory leaks.  The preferred manner in which to allocate
+memory for use locally is to use the @w{@code{OCTAVE_LOCAL_BUFFER}} macro.
+An example of its use is
+
+ at example
+OCTAVE_LOCAL_BUFFER (double, tmp, len)
+ at end example
+
+that returns a pointer @code{tmp} of type @code{double *} of length
+ at code{len}.
+
+ at node Input Parameter Checking in Oct-Files
+ at subsection Input Parameter Checking in Oct-Files
+
+As oct-files are compiled functions they have the possibility of causing
+Octave to abort abnormally.  It is therefore important that
+each and every function has the minimum of parameter
+checking needed to ensure that Octave behaves well.
+
+The minimum requirement, as previously discussed, is to check the number
+of input arguments before using them to avoid referencing a non existent
+argument.  However, it some case this might not be sufficient as the
+underlying code imposes further constraints.  For example an external
+function call might be undefined if the input arguments are not
+integers, or if one of the arguments is zero.  Therefore, oct-files often
+need additional input parameter checking.
+
+There are several functions within Octave that might be useful for the
+purposes of parameter checking.  These include the methods of the
+octave_value class like @code{is_real_matrix}, etc., but equally include
+more specialized functions.  Some of the more common ones are
+demonstrated in the following example
+
+ at longexamplefile{paramdemo.cc}
+
+ at noindent
+and an example of its use is
+
+ at example
+ at group
+paramdemo ([1, 2, NaN, Inf])
+ at result{} Properties of input array:
+      includes Inf or NaN values
+      includes other values than 1 and 0
+      includes only int, Inf or NaN values
+ at end group
+ at end example
+
+ at node Exception and Error Handling in Oct-Files
+ at subsection Exception and Error Handling in Oct-Files
+
+Another important feature of Octave is its ability to react to the user
+typing @kbd{Control-C} even during calculations.  This ability is based on the
+C++ exception handler, where memory allocated by the C++ new/delete
+methods are automatically released when the exception is treated.  When
+writing an oct-file, to allow Octave to treat the user typing @kbd{Control-C},
+the @w{@code{OCTAVE_QUIT}} macro is supplied.  For example
+
+ at example
+ at group
+for (octave_idx_type i = 0; i < a.nelem (); i++)
+  @{
+    OCTAVE_QUIT;
+    b.elem(i) = 2. * a.elem(i);
+  @}
+ at end group
+ at end example
+
+The presence of the @w{@code{OCTAVE_QUIT}} macro in the inner loop allows Octave to
+treat the user request with the @kbd{Control-C}.  Without this macro, the user
+must either wait for the function to return before the interrupt is
+processed, or press @kbd{Control-C} three times to force Octave to exit.
+
+The @w{@code{OCTAVE_QUIT}} macro does impose a very small speed penalty, and so for
+loops that are known to be small it might not make sense to include
+ at w{@code{OCTAVE_QUIT}}.
+
+When creating an oct-file that uses an external libraries, the function
+might spend a significant portion of its time in the external
+library.  It is not generally possible to use the @w{@code{OCTAVE_QUIT}} macro in
+this case.  The alternative in this case is
+
+ at example
+ at group
+BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+ at dots{}  some code that calls a "foreign" function @dots{}
+END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+ at end group
+ at end example
+
+The disadvantage of this is that if the foreign code allocates any
+memory internally, then this memory might be lost during an interrupt,
+without being deallocated.  Therefore, ideally Octave itself should
+allocate any memory that is needed by the foreign code, with either the
+fortran_vec method or the @w{@code{OCTAVE_LOCAL_BUFFER}} macro.
+
+The Octave unwind_protect mechanism (@ref{The @code{unwind_protect} Statement})
+can also be used in oct-files.  In conjunction with the exception
+handling of Octave, it is important to enforce that certain code is run
+to allow variables, etc. to be restored even if an exception occurs.  An
+example of the use of this mechanism is
+
+ at longexamplefile{unwinddemo.cc}
+
+As can be seen in the example
+
+ at example
+ at group
+unwinddemo (1, 0)
+ at result{} Inf
+1 / 0
+ at result{} warning: division by zero
+   Inf
+ at end group
+ at end example
+
+The division by zero (and in fact all warnings) is disabled in the
+ at code{unwinddemo} function.
+
+ at node Documentation and Test of Oct-Files
+ at subsection Documentation and Test of Oct-Files
+
+The documentation of an oct-file is the fourth string parameter of the
+ at w{@code{DEFUN_DLD}} macro.  This string can be formatted in the same manner
+as the help strings for user functions (@ref{Documentation Tips}),
+however there are some issue that are particular to the formatting of
+help strings within oct-files.
+
+The major issue is that the help string will typically be longer than a
+single line of text, and so the formatting of long help strings need to
+be taken into account.  There are several manners in which to treat this
+issue, but the most common is illustrated in the following example
+
+ at example
+ at group
+DEFUN_DLD (do_what_i_want, args, nargout, 
+  "-*- texinfo -*-\n\
+@@deftypefn @{Function File@} @{@} do_what_i_say (@@var@{n@})\n\
+A function that does what the user actually wants rather\n\
+than what they requested.\n\
+@@end deftypefn")
+@{
+ at dots{}
+@}
+ at end group
+ at end example
+
+ at noindent
+where, as can be seen, end line of text within the help string is
+terminated by @code{\n\} which is an embedded new-line in the string
+together with a C++ string continuation character.  Note that the final
+ at code{\} must be the last character on the line.
+
+Octave also includes the ability to embed the test and demonstration
+code for a function within the code itself (@ref{Test and Demo Functions}).
+This can be used from within oct-files (or in fact any file) with
+certain provisos.  Firstly, the test and demo functions of Octave look
+for a @code{%!} as the first characters on a new-line to identify test
+and demonstration code.  This is equally a requirement for
+oct-files.  Furthermore the test and demonstration code must be included
+in a comment block of the compiled code to avoid it being interpreted by
+the compiler.  Finally, the Octave test and demonstration code must have
+access to the source code of the oct-file and not just the compiled code
+as the tests are stripped from the compiled code.  An example in an
+oct-file might be
+
+ at example
+ at group
+/*
+
+%!error (sin())
+%!error (sin(1,1))
+%!assert (sin([1,2]),[sin(1),sin(2)])
+
+*/
+ at end group
+ at end example
+
+ at c @node Application Programming Interface for Oct-Files
+ at c @subsection Application Programming Interface for Oct-Files
+ at c 
+ at c WRITE ME, using Coda section 1.3 as a starting point.
+
+ at node Mex-Files
+ at section Mex-Files
+ at cindex mex-files
+ at cindex mex
+
+Octave includes an interface to allow legacy mex-files to be compiled
+and used with Octave.  This interface can also be used to share code
+between Octave and non Octave users.  However, as mex-files expose the
+internal API of an alternative product to Octave, and the internal
+structure of Octave is different to this product, a mex-file can never
+have the same performance in Octave as the equivalent oct-file.  In
+particular to support the manner in which mex-files access the variables
+passed to mex functions, there are a significant number of additional
+copies of memory when calling or returning from a mex function.  For
+this reason, new code should be written using the oct-file interface
+discussed above if possible.
+
+ at menu
+* Getting Started with Mex-Files::  
+* Working with Matrices and Arrays in Mex-Files::  
+* Character Strings in Mex-Files::  
+* Cell Arrays with Mex-Files::  
+* Structures with Mex-Files::  
+* Sparse Matrices with Mex-Files::  
+* Calling Other Functions in Mex-Files::  
+ at c * Application Programming Interface for Mex-Files::  
+ at end menu
+
+ at node Getting Started with Mex-Files
+ at subsection Getting Started with Mex-Files
+
+The basic command to build a mex-file is either @code{mkoctfile --mex} or
+ at code{mex}.  The first can either be used from within Octave or from the
+command line.  However, to avoid issues with the installation of other
+products, the use of the command @code{mex} is limited to within Octave.
+
+ at c ./miscellaneous/mex.m
+ at anchor{doc-mex}
+ at deftypefn {Function File} {} mex [options] file @dots{}
+Compile source code written in C, C++, or Fortran, to a MEX file.
+This is equivalent to @code{mkoctfile --mex [options] file}.
+ at seealso{@ref{doc-mkoctfile,,mkoctfile}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/mexext.m
+ at anchor{doc-mexext}
+ at deftypefn {Function File} {} mexext ()
+Return the filename extension used for MEX files.
+ at end deftypefn
+
+
+One important difference between the use of mex with other products and
+with Octave is that the header file "matrix.h" is implicitly included
+through the inclusion of "mex.h".  This is to avoid a conflict with the
+Octave file "Matrix.h" with operating systems and compilers that don't
+distinguish between filenames in upper and lower case
+
+Consider the short example
+
+ at examplefile{firstmexdemo.c}
+
+This simple example demonstrates the basics of writing a mex-file.  The
+entry point into the mex-file is defined by @code{mexFunction}.  Note
+that the function name is not explicitly included in the
+ at code{mexFunction} and so there can only be a single @code{mexFunction}
+entry point per-file.  Also the name of the function is determined by the
+name of the mex-file itself.  Therefore if the above function is in the
+file @file{firstmexdemo.c}, it can be compiled with
+
+ at example
+mkoctfile --mex firstmexdemo.c
+ at end example
+
+ at noindent
+which creates a file @file{firstmexdemo.mex}.  The function can then be run
+from Octave as
+
+ at example
+ at group
+firstmexdemo()
+ at result{} 1.2346
+ at end group
+ at end example
+
+It should be noted that the mex-file contains no help string for the
+functions it contains.  To document mex-files, there should exist an
+m-file in the same directory as the mex-file itself.  Taking the above as
+an example, we would therefore have a file @file{firstmexdemo.m} that might
+contain the text
+
+ at example
+%FIRSTMEXDEMO Simple test of the functionality of a mex-file.
+ at end example
+
+In this case, the function that will be executed within Octave will be
+given by the mex-file, while the help string will come from the
+m-file.  This can also be useful to allow a sample implementation of the
+mex-file within the Octave language itself for testing purposes.
+
+Although we cannot have multiple entry points into a single mex-file,
+we can use the @code{mexFunctionName} function to determine what name
+the mex-file was called with.  This can be used to alter the behavior of
+the mex-file based on the function name.  For example if
+
+ at examplefile{myfunc.c}
+
+ at noindent
+is in file @file{myfunc.c}, and it is compiled with
+
+ at example
+ at group
+mkoctfile --mex myfunc.c
+ln -s myfunc.mex myfunc2.mex
+ at end group
+ at end example
+
+Then as can be seen by
+
+ at example
+ at group
+myfunc()
+ at result{} You called function: myfunc
+    This is the principal function
+myfunc2()
+ at result{} You called function: myfunc2
+ at end group
+ at end example
+
+ at noindent
+the behavior of the mex-file can be altered depending on the functions
+name.
+
+Allow the user should only include @code{mex.h} in their code, Octave
+declares additional functions, typedefs, etc., available to the user to
+write mex-files in the headers @code{mexproto.h} and @code{mxarray.h}.
+
+ at node Working with Matrices and Arrays in Mex-Files
+ at subsection Working with Matrices and Arrays in Mex-Files
+
+The basic mex type of all variables is @code{mxArray}.  All variables,
+such as matrices, cell arrays or structures are all stored in this basic
+type, and this type serves basically the same purpose as the
+octave_value class in oct-files.  That is it acts as a container for the
+more specialized types.
+
+The @code{mxArray} structure contains at a minimum, the variable it
+represents name, its dimensions, its type and whether the variable is
+real or complex.  It can however contain a number of additional fields
+depending on the type of the @code{mxArray}.  There are a number of
+functions to create @code{mxArray} structures, including
+ at code{mxCreateCellArray}, @code{mxCreateSparse} and the generic
+ at code{mxCreateNumericArray}.
+
+The basic functions to access the data contained in an array is
+ at code{mxGetPr}.  As the mex interface assumes that the real and imaginary
+parts of a complex array are stored separately, there is an equivalent
+function @code{mxGetPi} that get the imaginary part.  Both of these
+functions are for use only with double precision matrices.  There also
+exists the generic function @code{mxGetData} and @code{mxGetImagData}
+that perform the same operation on all matrix types.  For example
+
+ at example
+ at group
+mxArray *m;
+mwSize *dims;
+UINT32_T *pr;
+
+dims = (mwSize *) mxMalloc (2 * sizeof(mwSize));
+dims[0] = 2;
+dims[1] = 2;
+m = mxCreateNumericArray (2, dims, mxUINT32_CLASS, mxREAL);
+pr =  = (UINT32_T *) mxGetData (m);
+ at end group
+ at end example
+
+There are also the functions @code{mxSetPr}, etc., that perform the
+inverse, and set the data of an Array to use the block of memory pointed
+to by the argument of @code{mxSetPr}.
+
+Note the type @code{mwSize} used above, and @code{mwIndex} are defined
+as the native precision of the indexing in Octave on the platform on
+which the mex-file is built.  This allows both 32- and 64-bit platforms
+to support mex-files.  @code{mwSize} is used to define array dimension
+and maximum number or elements, while @code{mwIndex} is used to define
+indexing into arrays.
+
+An example that demonstration how to work with arbitrary real or complex
+double precision arrays is given by the file @file{mypow2.c} as given
+below.
+
+ at longexamplefile{mypow2.c}
+
+ at noindent
+with an example of its use
+
+ at example
+ at group
+b = randn(4,1) + 1i * randn(4,1);
+all(b.^2 == mypow2(b))
+ at result{} 1
+ at end group
+ at end example
+
+
+The example above uses the functions @code{mxGetDimensions},
+ at code{mxGetNumberOfElements}, and @code{mxGetNumberOfDimensions} to work
+with the dimensions of multi-dimensional arrays.  The functions
+ at code{mxGetM}, and @code{mxGetN} are also available to find the number
+of rows and columns in a matrix.
+
+ at node Character Strings in Mex-Files
+ at subsection Character Strings in Mex-Files
+
+As mex-files do not make the distinction between single and double
+quoted strings within Octave, there is perhaps less complexity in the
+use of strings and character matrices in mex-files.  An example of their
+use, that parallels the demo in @file{stringdemo.cc}, is given in the
+file @file{mystring.c}, as seen below.
+
+ at longexamplefile{mystring.c}
+
+ at noindent
+An example of its expected output is
+
+ at example
+ at group
+mystring(["First String"; "Second String"])
+ at result{} s1 = Second String
+        First String
+ at end group
+ at end example
+
+Other functions in the mex interface for handling character strings are
+ at code{mxCreateString}, @code{mxArrayToString}, and
+ at code{mxCreateCharMatrixFromStrings}.  In a mex-file, a character string
+is considered to be a vector rather than a matrix.  This is perhaps an
+arbitrary distinction as the data in the mxArray for the matrix is
+consecutive in any case.
+
+ at node Cell Arrays with Mex-Files
+ at subsection Cell Arrays with Mex-Files
+
+We can perform exactly the same operations in Cell arrays in mex-files
+as we can in oct-files.  An example that reduplicates the functional of
+the @file{celldemo.cc} oct-file in a mex-file is given by
+ at file{mycell.c} as below
+
+ at examplefile{mycell.c}
+
+ at noindent
+which as can be seen below has exactly the same behavior as the oct-file
+version.
+
+ at example
+ at group
+[b1, b2, b3] = mycell (@{1, [1, 2], "test"@})
+ at result{}
+b1 =  1
+b2 =
+
+   1   2
+
+b3 = test
+ at end group
+ at end example
+
+Note in the example the use of the @code{mxDuplicateArray} function.  This
+is needed as the @code{mxArray} pointer returned by @code{mxGetCell}
+might be deallocated.  The inverse function to @code{mxGetCell} is
+ at code{mcSetCell} and is defined as
+
+ at example
+void mxSetCell (mxArray *ptr, int idx, mxArray *val);
+ at end example
+
+Finally, to create a cell array or matrix, the appropriate functions are
+
+ at example
+ at group
+mxArray *mxCreateCellArray (int ndims, const int *dims);
+mxArray *mxCreateCellMatrix (int m, int n);
+ at end group
+ at end example
+
+ at node Structures with Mex-Files
+ at subsection Structures with Mex-Files
+
+The basic function to create a structure in a mex-file is
+ at code{mxCreateStructMatrix}, which creates a structure array with a two
+dimensional matrix, or @code{mxCreateStructArray}.
+
+ at example
+ at group
+mxArray *mxCreateStructArray (int ndims, int *dims, 
+                              int num_keys, 
+                              const char **keys);
+mxArray *mxCreateStructMatrix (int rows, int cols, 
+                               int num_keys, 
+                               const char **keys);
+ at end group
+ at end example
+
+Accessing the fields of the structure can then be performed with the
+ at code{mxGetField} and @code{mxSetField} or alternatively with the
+ at code{mxGetFieldByNumber} and @code{mxSetFieldByNumber} functions.
+
+ at example
+ at group
+mxArray *mxGetField (const mxArray *ptr, mwIndex index,
+                     const char *key);
+mxArray *mxGetFieldByNumber (const mxArray *ptr, 
+                             mwIndex index, int key_num);
+void mxSetField (mxArray *ptr, mwIndex index, 
+                 const char *key, mxArray *val);
+void mxSetFieldByNumber (mxArray *ptr, mwIndex index, 
+                         int key_num, mxArray *val);
+ at end group
+ at end example
+
+A difference between the oct-file interface to structures and the
+mex-file version is that the functions to operate on structures in
+mex-files directly include an @code{index} over the elements of the
+arrays of elements per @code{field}.  Whereas the oct-file structure
+includes a Cell Array per field of the structure.
+
+An example that demonstrates the use of structures in mex-file can be
+found in the file @file{mystruct.c}, as seen below
+
+ at longexamplefile{mystruct.c}
+
+An example of the behavior of this function within Octave is then
+
+ at example
+a(1).f1 = "f11"; a(1).f2 = "f12"; 
+a(2).f1 = "f21"; a(2).f2 = "f22";
+b = mystruct(a)
+ at result{} field f1(0) = f11
+    field f1(1) = f21
+    field f2(0) = f12
+    field f2(1) = f22
+    b =
+    @{
+      this =
+    
+      (,
+        [1] = this1
+        [2] = this2
+        [3] = this3
+        [4] = this4
+      ,)
+    
+      that =
+    
+      (,
+        [1] = that1
+        [2] = that2
+        [3] = that3
+        [4] = that4
+      ,)
+    
+    @}
+ at end example
+
+ at node Sparse Matrices with Mex-Files
+ at subsection Sparse Matrices with Mex-Files
+
+The Octave format for sparse matrices is identical to the mex format in
+that it is a compressed column sparse format.  Also in both, sparse
+matrices are required to be two-dimensional.  The only difference is that
+the real and imaginary parts of the matrix are stored separately.
+
+The mex-file interface, as well as using @code{mxGetM}, @code{mxGetN},
+ at code{mxSetM}, @code{mxSetN}, @code{mxGetPr}, @code{mxGetPi},
+ at code{mxSetPr} and @code{mxSetPi}, the mex-file interface supplies the
+functions
+
+ at example
+ at group
+mwIndex *mxGetIr (const mxArray *ptr);
+mwIndex *mxGetJc (const mxArray *ptr);
+mwSize mxGetNzmax (const mxArray *ptr);
+
+void mxSetIr (mxArray *ptr, mwIndex *ir);
+void mxSetJc (mxArray *ptr, mwIndex *jc);
+void mxSetNzmax (mxArray *ptr, mwSize nzmax);
+ at end group
+ at end example
+
+ at noindent
+ at code{mxGetNzmax} gets the maximum number of elements that can be stored
+in the sparse matrix.  This is not necessarily the number of non-zero
+elements in the sparse matrix.  @code{mxGetJc} returns an array with one
+additional value than the number of columns in the sparse matrix.  The
+difference between consecutive values of the array returned by
+ at code{mxGetJc} define the number of non-zero elements in each column of
+the sparse matrix.  Therefore
+
+ at example
+ at group
+mwSize nz, n;
+mwIndex *Jc;
+mxArray *m;
+ at dots{}
+n = mxGetN (m);
+Jc = mxGetJc (m);
+nz = Jc[n];
+ at end group
+ at end example
+
+ at noindent
+returns the actual number of non-zero elements stored in the matrix in
+ at code{nz}.  As the arrays returned by @code{mxGetPr} and @code{mxGetPi}
+only contain the non-zero values of the matrix, we also need a pointer
+to the rows of the non-zero elements, and this is given by
+ at code{mxGetIr}.  A complete example of the use of sparse matrices in
+mex-files is given by the file @file{mysparse.c} as seen below
+
+ at longexamplefile{mysparse.c}
+
+ at node Calling Other Functions in Mex-Files
+ at subsection Calling Other Functions in Mex-Files
+
+It is also possible call other Octave functions from within a mex-file
+using @code{mexCallMATLAB}.  An example of the use of
+ at code{mexCallMATLAB} can be see in the example below
+
+ at longexamplefile{myfeval.c}
+
+If this code is in the file @file{myfeval.c}, and is compiled to
+ at file{myfeval.mex}, then an example of its use is
+
+ at example
+ at group
+myfeval("sin", 1)
+a = myfeval("sin", 1)
+ at result{} Hello, World!
+    I have 2 inputs and 1 outputs
+    I'm going to call the interpreter function sin
+    a =  0.84147
+ at end group
+ at end example
+
+Note that it is not possible to use function handles or inline functions
+within a mex-file.
+
+ at c @node Application Programming Interface for Mex-Files
+ at c @subsection Application Programming Interface for Mex-Files
+ at c 
+ at c WRITE ME, refer to mex.h and mexproto.h
+
+ at node Standalone Programs
+ at section Standalone Programs
+
+The libraries Octave itself uses, can be utilized in standalone
+applications.  These applications then have access, for example, to the
+array and matrix classes as well as to all the Octave algorithms.  The
+following C++ program, uses class Matrix from liboctave.a or
+liboctave.so.
+
+ at examplefile{standalone.cc}
+
+ at noindent
+mkoctfile can then be used to build a standalone application with a
+command like
+
+ at example
+ at group
+$ mkoctfile --link-stand-alone standalone.cc -o standalone
+$ ./standalone
+Hello Octave world!
+  11 12
+  21 22
+$
+ at end group
+ at end example
+
+Note that the application @code{hello} will be dynamically linked
+against the octave libraries and any octave support libraries.  The above
+allows the Octave math libraries to be used by an application.  It does
+not however allow the script files, oct-files or builtin functions of
+Octave to be used by the application.  To do that the Octave interpreter
+needs to be initialized first.  An example of how to do this can then be
+seen in the code
+
+ at examplefile{embedded.cc}
+
+ at noindent
+which is compiled and run as before as a standalone application with
+
+ at example
+ at group
+$ mkoctfile --link-stand-alone embedded.cc -o embedded
+$ ./embedded
+GCD of [10, 15] is 5
+$
+ at end group
+ at end example
+
diff --git a/doc/interpreter/dynamic.txi b/doc/interpreter/dynamic.txi
new file mode 100644
index 0000000..dac87ef
--- /dev/null
+++ b/doc/interpreter/dynamic.txi
@@ -0,0 +1,1657 @@
+ at c Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman
+ at c Copyright (C) 2007 Paul Thomas and Christoph Spiel
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at macro examplefile{file}
+ at example
+ at group
+ at verbatiminclude @value{abs_top_srcdir}/examples/\file\
+ at end group
+ at end example
+ at end macro
+
+ at macro longexamplefile{file}
+ at example
+ at verbatiminclude @value{abs_top_srcdir}/examples/\file\
+ at end example
+ at end macro
+
+ at node Dynamically Linked Functions
+ at appendix Dynamically Linked Functions
+ at cindex dynamic-linking
+
+Octave has the possibility of including compiled code as dynamically
+linked extensions and then using these extensions as if they were part
+of Octave itself.  Octave can call C++ code
+through its native oct-file interface or C code through its mex
+interface.  It can also indirectly call functions written in any other
+language through a simple wrapper.  The reasons to write code in a
+compiled language might be either to link to an existing piece of code
+and allow it to be used within Octave, or to allow improved performance
+for key pieces of code.
+
+Before going further, you should first determine if you really need to
+use dynamically linked functions at all.  Before proceeding with writing
+any dynamically linked function to improve performance you should
+address ask yourself
+
+ at itemize @bullet
+ at item
+Can I get the same functionality using the Octave scripting language only?
+ at item
+Is it thoroughly optimized Octave code?  Vectorization of Octave code,
+doesn't just make it concise, it generally significantly improves its
+performance.  Above all, if loops must be used, make sure that the
+allocation of space for variables takes place outside the loops using an
+assignment to a matrix of the right size, or zeros.
+ at item
+Does it make as much use as possible of existing built-in library
+routines?  These are highly optimized and many do not carry the overhead
+of being interpreted.
+ at item
+Does writing a dynamically linked function represent useful investment
+of your time, relative to staying in Octave?
+ at end itemize
+
+Also, as oct- and mex-files are dynamically linked to Octave, they
+introduce the possibility of Octave crashing due to errors in
+the user code.  For example a segmentation violation in the user's code
+will cause Octave to abort.
+
+ at menu
+* Oct-Files::                   
+* Mex-Files::                   
+* Standalone Programs::         
+ at end menu
+
+ at node Oct-Files
+ at section Oct-Files
+ at cindex oct-files
+ at cindex mkoctfile
+ at cindex oct
+
+ at menu
+* Getting Started with Oct-Files::  
+* Matrices and Arrays in Oct-Files::  
+* Character Strings in Oct-Files::  
+* Cell Arrays in Oct-Files::    
+* Structures in Oct-Files::  
+* Sparse Matrices in Oct-Files::  
+* Accessing Global Variables in Oct-Files::  
+* Calling Octave Functions from Oct-Files::  
+* Calling External Code from Oct-Files::  
+* Allocating Local Memory in Oct-Files::  
+* Input Parameter Checking in Oct-Files::  
+* Exception and Error Handling in Oct-Files::  
+* Documentation and Test of Oct-Files::  
+ at c * Application Programming Interface for Oct-Files::  
+ at end menu
+
+ at node Getting Started with Oct-Files
+ at subsection Getting Started with Oct-Files
+
+The basic command to build oct-files is @code{mkoctfile} and it can be
+call from within octave or from the command line.
+
+ at DOCSTRING(mkoctfile)
+
+Consider the short example
+
+ at examplefile{helloworld.cc}
+
+This example although short introduces the basics of writing a C++
+function that can be dynamically linked to Octave.  The easiest way to
+make available most of the definitions that might be necessary for an
+oct-file in Octave is to use the @code{#include <octave/oct.h>}
+header.
+
+The macro that defines the entry point into the dynamically loaded
+function is @w{@code{DEFUN_DLD}}.  This macro takes four arguments, these being
+
+ at enumerate 1
+ at item The function name as it will be seen in Octave,
+ at item The list of arguments to the function of type @code{octave_value_list},
+ at item The number of output arguments, which can and often is omitted if
+not used, and
+ at item The string that will be seen as the help text of the function.
+ at end enumerate
+
+The return type of functions defined with @w{@code{DEFUN_DLD}} is always
+ at code{octave_value_list}.
+
+There are a couple of important considerations in the choice of function
+name.  Firstly, it must be a valid Octave function name and so must be a
+sequence of letters, digits and underscores, not starting with a
+digit.  Secondly, as Octave uses the function name to define the filename
+it attempts to find the function in, the function name in the @w{@code{DEFUN_DLD}}
+macro must match the filename of the oct-file.  Therefore, the above
+function should be in a file @file{helloworld.cc}, and it should be
+compiled to an oct-file using the command
+
+ at example
+mkoctfile helloworld.cc
+ at end example
+
+This will create a file called @file{helloworld.oct}, that is the compiled
+version of the function.  It should be noted that it is perfectly
+acceptable to have more than one @w{@code{DEFUN_DLD}} function in a source
+file.  However, there must either be a symbolic link to the oct-file for
+each of the functions defined in the source code with the @w{@code{DEFUN_DLD}}
+macro or the autoload (@ref{Function Files}) function should be used.
+
+The rest of this function then shows how to find the number of input
+arguments, how to print through the octave pager, and return from the
+function.  After compiling this function as above, an example of its use
+is
+
+ at example
+ at group
+helloworld (1, 2, 3)
+ at print{} Hello World has 3 input arguments and 0 output arguments.
+ at end group
+ at end example
+
+ at node Matrices and Arrays in Oct-Files
+ at subsection Matrices and Arrays in Oct-Files
+
+Octave supports a number of different array and matrix classes, the
+majority of which are based on the Array class.  The exception is the
+sparse matrix types discussed separately below.  There are three basic
+matrix types
+
+ at table @code
+ at item Matrix
+A double precision matrix class defined in dMatrix.h,
+ at item ComplexMatrix
+A complex matrix class defined in CMatrix.h, and
+ at item BoolMatrix
+A boolean matrix class defined in boolMatrix.h.
+ at end table
+
+These are the basic two-dimensional matrix types of octave.  In
+additional there are a number of multi-dimensional array types, these
+being
+
+ at table @code
+ at item NDArray
+A double precision array class defined in @file{dNDArray.h}
+ at item ComplexNDarray
+A complex array class defined in @file{CNDArray.h}
+ at item boolNDArray
+A boolean array class defined in @file{boolNDArray.h}
+ at item int8NDArray
+ at itemx int16NDArray
+ at itemx int32NDArray
+ at itemx int64NDArray
+8, 16, 32 and 64-bit signed array classes defined in
+ at file{int8NDArray.h}, @file{int16NDArray.h}, etc.
+ at item uint8NDArray
+ at itemx uint16NDArray
+ at itemx uint32NDArray
+ at itemx uint64NDArray
+8, 16, 32 and 64-bit unsigned array classes defined in
+ at file{uint8NDArray.h}, @file{uint16NDArray.h}, etc.
+ at end table
+
+There are several basic means of constructing matrices of
+multi-dimensional arrays.  Considering the @code{Matrix} type as an
+example
+
+ at itemize @bullet
+ at item
+We can create an empty matrix or array with the empty constructor.  For
+example
+
+ at example
+Matrix a;
+ at end example
+
+This can be used on all matrix and array types
+ at item
+Define the dimensions of the matrix or array with a dim_vector.  For
+example
+
+ at example
+ at group
+dim_vector dv (2);
+dv(0) = 2; dv(1) = 2;
+Matrix a (dv);
+ at end group
+ at end example
+
+This can be used on all matrix and array types
+ at item
+Define the number of rows and columns in the matrix.  For example
+
+ at example
+Matrix a (2, 2)
+ at end example
+
+However, this constructor can only be used with the matrix types.
+ at end itemize
+
+These types all share a number of basic methods and operators, a
+selection of which include
+
+ at deftypefn Method T& {operator ()} (octave_idx_type)
+ at deftypefnx Method T& elem (octave_idx_type)
+The @code{()} operator or @code{elem} method allow the values of the
+matrix or array to be read or set.  These can take a single argument,
+which is of type @code{octave_idx_type}, that is the index into the matrix or
+array.  Additionally, the matrix type allows two argument versions of the
+ at code{()} operator and elem method, giving the row and column index of the
+value to obtain or set.
+ at end deftypefn
+
+Note that these functions do significant error checking and so in some
+circumstances the user might prefer to access the data of the array or
+matrix directly through the fortran_vec method discussed below.
+
+ at deftypefn Method octave_idx_type nelem (void) const
+The total number of elements in the matrix or array.
+ at end deftypefn
+
+ at deftypefn Method size_t byte_size (void) const
+The number of bytes used to store the matrix or array.
+ at end deftypefn
+
+ at deftypefn Method dim_vector dims (void) const
+The dimensions of the matrix or array in value of type dim_vector.
+ at end deftypefn
+
+ at deftypefn Method void resize (const dim_vector&)
+A method taking either an argument of type @code{dim_vector}, or in the
+case of a matrix two arguments of type @code{octave_idx_type} defining
+the number of rows and columns in the matrix.
+ at end deftypefn
+
+ at deftypefn Method T* fortran_vec (void)
+This method returns a pointer to the underlying data of the matrix or a
+array so that it can be manipulated directly, either within Octave or by
+an external library.
+ at end deftypefn
+
+Operators such an @code{+}, @code{-}, or @code{*} can be used on the
+majority of the above types.  In addition there are a number of methods
+that are of interest only for matrices such as @code{transpose},
+ at code{hermitian}, @code{solve}, etc.
+
+The typical way to extract a matrix or array from the input arguments of
+ at w{@code{DEFUN_DLD}} function is as follows
+
+ at examplefile{addtwomatrices.cc}
+
+To avoid segmentation faults causing Octave to abort, this function
+explicitly checks that there are sufficient arguments available before
+accessing these arguments.  It then obtains two multi-dimensional arrays
+of type @code{NDArray} and adds these together.  Note that the array_value
+method is called without using the @code{is_matrix_type} type, and instead the
+error_state is checked before returning @code{A + B}.  The reason to
+prefer this is that the arguments might be a type that is not an
+ at code{NDArray}, but it would make sense to convert it to one.  The
+ at code{array_value} method allows this conversion to be performed
+transparently if possible, and sets @code{error_state} if it is not.
+
+ at code{A + B}, operating on two @code{NDArray}'s returns an
+ at code{NDArray}, which is cast to an @code{octave_value} on the return
+from the function.  An example of the use of this demonstration function
+is
+
+ at example
+ at group
+addtwomatrices (ones (2, 2), ones (2, 2))
+      @result{}  2  2
+          2  2
+ at end group
+ at end example
+
+A list of the basic @code{Matrix} and @code{Array} types, the methods to
+extract these from an @code{octave_value} and the associated header is
+listed below.
+
+ at multitable @columnfractions .3 .4 .3
+ at item @code{RowVector} @tab @code{row_vector_value} @tab @file{dRowVector.h}
+ at item @code{ComplexRowVector} @tab @code{complex_row_vector_value} @tab @file{CRowVector.h}
+ at item @code{ColumnVector} @tab @code{column_vector_value} @tab @file{dColVector.h}
+ at item @code{ComplexColumnVector} @tab @code{complex_column_vector_value} @tab @file{CColVector.h}
+ at item @code{Matrix} @tab @code{matrix_value} @tab @file{dMatrix.h}
+ at item @code{ComplexMatrix} @tab @code{complex_matrix_value} @tab @file{CMatrix.h}
+ at item @code{boolMatrix} @tab @code{bool_matrix_value} @tab @file{boolMatrix.h}
+ at item @code{charMatrix} @tab @code{char_matrix_value} @tab @file{chMatrix.h}
+ at item @code{NDArray} @tab @code{array_value} @tab @file{dNDArray.h}
+ at item @code{ComplexNDArray} @tab @code{complex_array_value} @tab @file{CNDArray.h}
+ at item @code{boolNDArray} @tab @code{bool_array_value} @tab @file{boolNDArray.h}
+ at item @code{charNDArray} @tab @code{char_array_value} @tab @file{charNDArray.h}
+ at item @code{int8NDArray} @tab @code{int8_array_value} @tab @file{int8NDArray.h}
+ at item @code{int16NDArray} @tab @code{int16_array_value} @tab @file{int16NDArray.h}
+ at item @code{int32NDArray} @tab @code{int32_array_value} @tab @file{int32NDArray.h}
+ at item @code{int64NDArray} @tab @code{int64_array_value} @tab @file{int64NDArray.h}
+ at item @code{uint8NDArray} @tab @code{uint8_array_value} @tab @file{uint8NDArray.h}
+ at item @code{uint16NDArray} @tab @code{uint16_array_value} @tab @file{uint16NDArray.h}
+ at item @code{uint32NDArray} @tab @code{uint32_array_value} @tab @file{uint32NDArray.h}
+ at item @code{uint64NDArray} @tab @code{uint64_array_value} @tab @file{uint64NDArray.h}
+ at end multitable
+
+ at node Character Strings in Oct-Files
+ at subsection Character Strings in Oct-Files
+
+In Octave a character string is just a special @code{Array} class.
+Consider the example 
+
+ at longexamplefile{stringdemo.cc}
+
+An example of the use of this function is
+
+ at example
+ at group
+s0 = ["First String"; "Second String"];
+[s1,s2] = stringdemo (s0)
+ at result{} s1 = Second String
+        First String
+
+ at result{} s2 = First String
+        Second String
+
+typeinfo (s2)
+ at result{} sq_string
+typeinfo (s1)
+ at result{} string
+ at end group
+ at end example
+
+One additional complication of strings in Octave is the difference
+between single quoted and double quoted strings.  To find out if an
+ at code{octave_value} contains a single or double quoted string an example is
+
+ at example
+ at group
+    if (args(0).is_sq_string ())
+      octave_stdout << 
+        "First argument is a singularly quoted string\n";
+    else if (args(0).is_dq_string ())
+      octave_stdout << 
+        "First argument is a doubly quoted string\n";
+ at end group
+ at end example
+
+Note however, that both types of strings are represented by the
+ at code{charNDArray} type, and so when assigning to an
+ at code{octave_value}, the type of string should be specified.  For example
+
+ at example
+ at group
+octave_value_list retval;
+charNDArray c;
+ at dots{}
+// Create single quoted string
+retval(1) = octave_value (ch, true, '\'');
+
+// Create a double quoted string
+retval(0) = octave_value (ch, true);
+ at end group
+ at end example
+
+ at node Cell Arrays in Oct-Files
+ at subsection Cell Arrays in Oct-Files
+
+Octave's cell type is equally accessible within oct-files.  A cell
+array is just an array of @code{octave_value}s, and so each element of the cell
+array can then be treated just like any other @code{octave_value}.  A simple
+example is
+
+ at examplefile{celldemo.cc}
+
+Note that cell arrays are used less often in standard oct-files and so
+the @file{Cell.h} header file must be explicitly included.  The rest of this
+example extracts the @code{octave_value}s one by one from the cell array and
+returns be as individual return arguments.  For example consider
+
+ at example
+ at group
+[b1, b2, b3] = celldemo (@{1, [1, 2], "test"@})
+ at result{}
+b1 =  1
+b2 =
+
+   1   2
+
+b3 = test
+ at end group
+ at end example
+
+ at node Structures in Oct-Files
+ at subsection Structures in Oct-Files
+
+A structure in Octave is map between a number of fields represented and
+their values.  The Standard Template Library @code{map} class is used,
+with the pair consisting of a @code{std::string} and an octave
+ at code{Cell} variable.
+
+A simple example demonstrating the use of structures within oct-files is
+
+ at longexamplefile{structdemo.cc}
+
+An example of its use is
+
+ at example
+ at group
+x.a = 1; x.b = "test"; x.c = [1, 2];
+structdemo (x, "b")
+ at result{} selected = test
+ at end group
+ at end example
+
+The commented code above demonstrates how to iterate over all of the
+fields of the structure, where as the following code demonstrates finding
+a particular field in a more concise manner.
+
+As can be seen the @code{contents} method of the @code{Octave_map} class
+returns a @code{Cell} which allows structure arrays to be represented.
+Therefore, to obtain the underlying @code{octave_value} we write
+
+ at example
+octave_value tmp = arg0.contents (p1) (0);
+ at end example
+
+where the trailing (0) is the () operator on the @code{Cell} object.  We
+can equally iterate of the elements of the Cell array to address the
+elements of the structure array.
+
+ at node Sparse Matrices in Oct-Files
+ at subsection Sparse Matrices in Oct-Files
+
+There are three classes of sparse objects that are of interest to the
+user.
+
+ at table @code
+ at item SparseMatrix
+A double precision sparse matrix class
+ at item SparseComplexMatrix
+A complex sparse matrix class
+ at item SparseBoolMatrix
+A boolean sparse matrix class
+ at end table
+
+All of these classes inherit from the @code{Sparse<T>} template class,
+and so all have similar capabilities and usage.  The @code{Sparse<T>}
+class was based on Octave @code{Array<T>} class, and so users familiar
+with Octave's @code{Array} classes will be comfortable with the use of
+the sparse classes.
+
+The sparse classes will not be entirely described in this section, due
+to their similarity with the existing @code{Array} classes.  However,
+there are a few differences due the different nature of sparse objects,
+and these will be described.  Firstly, although it is fundamentally
+possible to have N-dimensional sparse objects, the Octave sparse classes do
+not allow them at this time.  So all operations of the sparse classes
+must be 2-dimensional.  This means that in fact @code{SparseMatrix} is
+similar to Octave's @code{Matrix} class rather than its
+ at code{NDArray} class.
+
+ at menu
+* Array and Sparse Differences::  
+* Creating Sparse Matrices in Oct-Files::  
+* Using Sparse Matrices in Oct-Files::  
+ at end menu
+
+ at node Array and Sparse Differences
+ at subsubsection The Differences between the Array and Sparse Classes
+
+The number of elements in a sparse matrix is considered to be the number
+of non-zero elements rather than the product of the dimensions.  Therefore
+
+ at example
+ at group
+SparseMatrix sm;
+ at dots{}
+int nel = sm.nelem ();
+ at end group
+ at end example
+
+returns the number of non-zero elements.  If the user really requires the
+number of elements in the matrix, including the non-zero elements, they
+should use @code{numel} rather than @code{nelem}.  Note that for very
+large matrices, where the product of the two dimensions is larger than
+the representation of an unsigned int, then @code{numel} can overflow.
+An example is @code{speye(1e6)} which will create a matrix with a million
+rows and columns, but only a million non-zero elements.  Therefore the
+number of rows by the number of columns in this case is more than two
+hundred times the maximum value that can be represented by an unsigned int.
+The use of @code{numel} should therefore be avoided useless it is known
+it won't overflow.
+
+Extreme care must be take with the elem method and the "()" operator,
+which perform basically the same function.  The reason is that if a
+sparse object is non-const, then Octave will assume that a
+request for a zero element in a sparse matrix is in fact a request
+to create this element so it can be filled.  Therefore a piece of
+code like
+
+ at example
+ at group
+SparseMatrix sm;
+ at dots{}
+for (int j = 0; j < nc; j++)
+  for (int i = 0; i < nr; i++)
+    std::cerr << " (" << i << "," << j << "): " << sm(i,j)
+              << std::endl;
+ at end group
+ at end example
+
+is a great way of turning the sparse matrix into a dense one, and a
+very slow way at that since it reallocates the sparse object at each
+zero element in the matrix.
+
+An easy way of preventing the above from happening is to create a temporary
+constant version of the sparse matrix.  Note that only the container for
+the sparse matrix will be copied, while the actual representation of the
+data will be shared between the two versions of the sparse matrix.  So this
+is not a costly operation.  For example, the above would become
+
+ at example
+ at group
+SparseMatrix sm;
+ at dots{}
+const SparseMatrix tmp (sm);
+for (int j = 0; j < nc; j++)
+  for (int i = 0; i < nr; i++)
+    std::cerr << " (" << i << "," << j << "): " << tmp(i,j)
+              << std::endl;
+ at end group
+ at end example
+
+Finally, as the sparse types aren't just represented as a contiguous
+block of memory, the @code{fortran_vec} method of the @code{Array<T>}
+is not available.  It is however replaced by three separate methods
+ at code{ridx}, @code{cidx} and @code{data}, that access the raw compressed
+column format that the Octave sparse matrices are stored in.
+Additionally, these methods can be used in a manner similar to @code{elem},
+to allow the matrix to be accessed or filled.  However, in that case it is
+up to the user to respect the sparse matrix compressed column format
+discussed previous.
+
+ at node Creating Sparse Matrices in Oct-Files
+ at subsubsection Creating Sparse Matrices in Oct-Files
+
+You have several alternatives for creating a sparse matrix.
+You can first create the data as three vectors representing the
+row and column indexes and the data, and from those create the matrix.
+Or alternatively, you can create a sparse matrix with the appropriate
+amount of space and then fill in the values.  Both techniques have their
+advantages and disadvantages.
+
+Here is an example of how to create a small sparse matrix with the first
+technique
+
+ at example
+ at group
+int nz = 4, nr = 3, nc = 4;
+
+ColumnVector ridx (nz);
+ColumnVector cidx (nz);
+ColumnVector data (nz);
+
+ridx(0) = 0; ridx(1) = 0; ridx(2) = 1; ridx(3) = 2;
+cidx(0) = 0; cidx(1) = 1; cidx(2) = 3; cidx(3) = 3;
+data(0) = 1; data(1) = 2; data(2) = 3; data(3) = 4;
+
+SparseMatrix sm (data, ridx, cidx, nr, nc);
+ at end group
+ at end example
+
+ at noindent
+which creates the matrix given in section
+ at ref{Storage of Sparse Matrices}.  Note that the compressed matrix
+format is not used at the time of the creation of the matrix itself,
+however it is used internally.
+
+As previously mentioned, the values of the sparse matrix are stored
+in increasing column-major ordering.  Although the data passed by the
+user does not need to respect this requirement, the pre-sorting the
+data significantly speeds up the creation of the sparse matrix.
+
+The disadvantage of this technique of creating a sparse matrix is
+that there is a brief time where two copies of the data exists.  Therefore
+for extremely memory constrained problems this might not be the right
+technique to create the sparse matrix.
+
+The alternative is to first create the sparse matrix with the desired
+number of non-zero elements and then later fill those elements in.  The
+easiest way to do this is
+
+ at example
+ at group
+int nz = 4, nr = 3, nc = 4;
+SparseMatrix sm (nr, nc, nz);
+sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+ at end group
+ at end example
+
+That creates the same matrix as previously.  Again, although it is not
+strictly necessary, it is significantly faster if the sparse matrix is
+created in this manner that the elements are added in column-major
+ordering.  The reason for this is that if the elements are inserted
+at the end of the current list of known elements then no element
+in the matrix needs to be moved to allow the new element to be
+inserted.  Only the column indexes need to be updated.
+
+There are a few further points to note about this technique of creating
+a sparse matrix.  Firstly, it is possible to create a sparse matrix
+with fewer elements than are actually inserted in the matrix.  Therefore
+
+ at example
+ at group
+int nz = 4, nr = 3, nc = 4;
+SparseMatrix sm (nr, nc, 0);
+sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+ at end group
+ at end example
+
+ at noindent 
+is perfectly valid.  However it is a very bad idea.  The reason is that
+as each new element is added to the sparse matrix the space allocated
+to it is increased by reallocating the memory.  This is an expensive
+operation, that will significantly slow this means of creating a sparse
+matrix.  Furthermore, it is possible to create a sparse matrix with
+too much storage, so having @var{nz} above equaling 6 is also valid.
+The disadvantage is that the matrix occupies more memory than strictly
+needed.
+
+It is not always easy to know the number of non-zero elements prior
+to filling a matrix.  For this reason the additional storage for the
+sparse matrix can be removed after its creation with the
+ at dfn{maybe_compress} function.  Furthermore, the maybe_compress can
+deallocate the unused storage, but it can equally remove zero elements
+from the matrix.  The removal of zero elements from the matrix is
+controlled by setting the argument of the @dfn{maybe_compress} function
+to be @samp{true}.  However, the cost of removing the zeros is high because it
+implies resorting the elements.  Therefore, if possible it is better
+is the user doesn't add the zeros in the first place.  An example of
+the use of @dfn{maybe_compress} is
+
+ at example
+ at group
+  int nz = 6, nr = 3, nc = 4;
+
+  SparseMatrix sm1 (nr, nc, nz);
+  sm1(0,0) = 1; sm1(0,1) = 2; sm1(1,3) = 3; sm1(2,3) = 4;
+  sm1.maybe_compress ();  // No zero elements were added
+
+  SparseMatrix sm2 (nr, nc, nz);
+  sm2(0,0) = 1; sm2(0,1) = 2; sm(0,2) = 0; sm(1,2) = 0;
+  sm1(1,3) = 3; sm1(2,3) = 4;
+  sm2.maybe_compress (true);  // Zero elements were added
+ at end group
+ at end example
+
+The use of the @dfn{maybe_compress} function should be avoided if
+possible, as it will slow the creation of the matrices.
+
+A third means of creating a sparse matrix is to work directly with
+the data in compressed row format.  An example of this technique might
+be
+
+ at c Note the @verbatim environment is a relatively new addition to texinfo.
+ at c Therefore use the @example environment and replace @, with @@,
+ at c { with @{, etc
+
+ at example
+octave_value arg;
+ at dots{}
+int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+SparseMatrix sm (nr, nc, nz);
+Matrix m = arg.matrix_value ();
+
+int ii = 0;
+sm.cidx (0) = 0;
+for (int j = 1; j < nc; j++)
+  @{
+    for (int i = 0; i < nr; i++)
+      @{
+        double tmp = foo (m(i,j));
+        if (tmp != 0.)
+          @{
+            sm.data(ii) = tmp;
+            sm.ridx(ii) = i;
+            ii++;
+          @}
+      @}
+    sm.cidx(j+1) = ii;
+ @}
+sm.maybe_compress ();  // If don't know a-priori 
+                       // the final no of nz.
+ at end example
+
+ at noindent
+which is probably the most efficient means of creating the sparse matrix.
+
+Finally, it might sometimes arise that the amount of storage initially
+created is insufficient to completely store the sparse matrix.  Therefore,
+the method @code{change_capacity} exists to reallocate the sparse memory.
+The above example would then be modified as
+
+ at example
+octave_value arg;
+ at dots{}
+int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+SparseMatrix sm (nr, nc, nz);
+Matrix m = arg.matrix_value ();
+
+int ii = 0;
+sm.cidx (0) = 0;
+for (int j = 1; j < nc; j++)
+  @{
+    for (int i = 0; i < nr; i++)
+      @{
+        double tmp = foo (m(i,j));
+        if (tmp != 0.)
+          @{
+            if (ii == nz)
+              @{
+                nz += 2;   // Add 2 more elements
+                sm.change_capacity (nz);
+              @}
+            sm.data(ii) = tmp;
+            sm.ridx(ii) = i;
+            ii++;
+          @}
+      @}
+    sm.cidx(j+1) = ii;
+ @}
+sm.maybe_mutate ();  // If don't know a-priori 
+                     // the final no of nz.
+ at end example
+
+Note that both increasing and decreasing the number of non-zero elements in
+a sparse matrix is expensive, as it involves memory reallocation.  Also as
+parts of the matrix, though not its entirety, exist as the old and new copy
+at the same time, additional memory is needed.  Therefore if possible this
+should be avoided.
+
+ at node Using Sparse Matrices in Oct-Files
+ at subsubsection Using Sparse Matrices in Oct-Files
+
+Most of the same operators and functions on sparse matrices that are
+available from the Octave are equally available with oct-files.
+The basic means of extracting a sparse matrix from an @code{octave_value}
+and returning them as an @code{octave_value}, can be seen in the
+following example
+
+ at example
+ at group
+octave_value_list retval;
+
+SparseMatrix sm = args(0).sparse_matrix_value ();
+SparseComplexMatrix scm = 
+    args(1).sparse_complex_matrix_value ();
+SparseBoolMatrix sbm = args(2).sparse_bool_matrix_value ();
+ at dots{}
+retval(2) = sbm;
+retval(1) = scm;
+retval(0) = sm;
+ at end group
+ at end example
+
+The conversion to an octave-value is handled by the sparse
+ at code{octave_value} constructors, and so no special care is needed.
+
+ at node Accessing Global Variables in Oct-Files
+ at subsection Accessing Global Variables in Oct-Files
+
+Global variables allow variables in the global scope to be
+accessed.  Global variables can easily be accessed with oct-files using
+the support functions @code{get_global_value} and
+ at code{set_global_value}.  @code{get_global_value} takes two arguments,
+the first is a string representing the variable name to obtain.  The
+second argument is a boolean argument specifying what to do in the case
+that no global variable of the desired name is found.  An example of the
+use of these two functions is
+
+ at longexamplefile{globaldemo.cc}
+
+An example of its use is
+
+ at example
+ at group
+global a b
+b = 10;
+globaldemo ("b")
+ at result{} 10
+globaldemo ("c")
+ at result{} "Global variable not found"
+num2str (a)
+ at result{} 42
+ at end group
+ at end example
+
+ at node Calling Octave Functions from Oct-Files
+ at subsection Calling Octave Functions from Oct-Files
+
+There is often a need to be able to call another octave function from
+within an oct-file, and there are many examples of such within octave
+itself.  For example the @code{quad} function is an oct-file that
+calculates the definite integral by quadrature over a user supplied
+function.
+
+There are also many ways in which a function might be passed.  It might
+be passed as one of
+
+ at enumerate 1
+ at item Function Handle
+ at item Anonymous Function Handle
+ at item Inline Function
+ at item String
+ at end enumerate
+
+The example below demonstrates an example that accepts all four means of
+passing a function to an oct-file.
+
+ at longexamplefile{funcdemo.cc}
+
+The first argument to this demonstration is the user supplied function
+and the following arguments are all passed to the user function.
+
+ at example
+ at group
+funcdemo (@@sin,1)
+ at result{} 0.84147
+funcdemo (@@(x) sin(x), 1)
+ at result{} 0.84147
+funcdemo (inline ("sin(x)"), 1)
+ at result{} 0.84147
+funcdemo ("sin",1)
+ at result{} 0.84147
+funcdemo (@@atan2, 1, 1)
+ at result{} 0.78540
+ at end group
+ at end example
+
+When the user function is passed as a string, the treatment of the
+function is different.  In some cases it is necessary to always have the
+user supplied function as an @code{octave_function} object.  In that
+case the string argument can be used to create a temporary function like
+
+ at example
+ at group
+std::octave fcn_name = unique_symbol_name ("__fcn__");
+std::string fname = "function y = ";
+fname.append (fcn_name);
+fname.append ("(x) y = ");
+fcn = extract_function (args(0), "funcdemo", fcn_name,
+                        fname, "; endfunction");
+ at dots{}
+if (fcn_name.length ())
+  clear_function (fcn_name);
+ at end group
+ at end example
+
+There are two important things to know in this case.  The number of input
+arguments to the user function is fixed, and in the above is a single
+argument, and secondly to avoid leaving the temporary function in the
+Octave symbol table it should be cleared after use.
+
+ at node Calling External Code from Oct-Files
+ at subsection Calling External Code from Oct-Files
+
+Linking external C code to Octave is relatively simple, as the C
+functions can easily be called directly from C++.  One possible issue is
+the declarations of the external C functions might need to be explicitly
+defined as C functions to the compiler.  If the declarations of the
+external C functions are in the header @code{foo.h}, then the manner in
+which to ensure that the C++ compiler treats these declarations as C
+code is
+
+ at example
+ at group
+#ifdef __cplusplus
+extern "C"
+@{
+#endif
+#include "foo.h"
+#ifdef __cplusplus
+@}  /* end extern "C" */
+#endif
+ at end group
+ at end example
+
+Calling Fortran code however can pose some difficulties.  This is due to
+differences in the manner in compilers treat the linking of Fortran code
+with C or C++ code.  Octave supplies a number of macros that allow
+consistent behavior across a number of compilers.
+
+The underlying Fortran code should use the @code{XSTOPX} function to
+replace the Fortran @code{STOP} function.  @code{XSTOPX} uses the Octave
+exception handler to treat failing cases in the fortran code
+explicitly.  Note that Octave supplies its own replacement @sc{blas}
+ at code{XERBLA} function, which uses @code{XSTOPX}.
+
+If the underlying code calls @code{XSTOPX}, then the @w{@code{F77_XFCN}}
+macro should be used to call the underlying fortran function.  The Fortran
+exception state can then be checked with the global variable
+ at code{f77_exception_encountered}.  If @code{XSTOPX} will not be called,
+then the @w{@code{F77_FCN}} macro should be used instead to call the Fortran
+code.
+
+There is no harm in using @w{@code{F77_XFCN}} in all cases, except that for
+Fortran code that is short running and executes a large number of times,
+there is potentially an overhead in doing so.  However, if @w{@code{F77_FCN}}
+is used with code that calls @code{XSTOP}, Octave can generate a
+segmentation fault.
+
+An example of the inclusion of a Fortran function in an oct-file is
+given in the following example, where the C++ wrapper is
+
+ at longexamplefile{fortdemo.cc}
+
+ at noindent
+and the fortran function is
+
+ at longexamplefile{fortsub.f}
+
+This example demonstrates most of the features needed to link to an
+external Fortran function, including passing arrays and strings, as well
+as exception handling.  An example of the behavior of this function is
+
+ at example
+ at group
+[b, s] = fortdemo (1:3)
+ at result{}
+  b = 1.00000   0.50000   0.33333
+  s = There are   3 values in the input vector
+[b, s] = fortdemo(0:3)
+error: fortsub:divide by zero
+error: exception encountered in Fortran subroutine fortsub_
+error: fortdemo: error in fortran
+ at end group
+ at end example
+
+ at node Allocating Local Memory in Oct-Files
+ at subsection Allocating Local Memory in Oct-Files
+
+Allocating memory within an oct-file might seem easy as the C++
+new/delete operators can be used.  However, in that case care must be
+taken to avoid memory leaks.  The preferred manner in which to allocate
+memory for use locally is to use the @w{@code{OCTAVE_LOCAL_BUFFER}} macro.
+An example of its use is
+
+ at example
+OCTAVE_LOCAL_BUFFER (double, tmp, len)
+ at end example
+
+that returns a pointer @code{tmp} of type @code{double *} of length
+ at code{len}.
+
+ at node Input Parameter Checking in Oct-Files
+ at subsection Input Parameter Checking in Oct-Files
+
+As oct-files are compiled functions they have the possibility of causing
+Octave to abort abnormally.  It is therefore important that
+each and every function has the minimum of parameter
+checking needed to ensure that Octave behaves well.
+
+The minimum requirement, as previously discussed, is to check the number
+of input arguments before using them to avoid referencing a non existent
+argument.  However, it some case this might not be sufficient as the
+underlying code imposes further constraints.  For example an external
+function call might be undefined if the input arguments are not
+integers, or if one of the arguments is zero.  Therefore, oct-files often
+need additional input parameter checking.
+
+There are several functions within Octave that might be useful for the
+purposes of parameter checking.  These include the methods of the
+octave_value class like @code{is_real_matrix}, etc., but equally include
+more specialized functions.  Some of the more common ones are
+demonstrated in the following example
+
+ at longexamplefile{paramdemo.cc}
+
+ at noindent
+and an example of its use is
+
+ at example
+ at group
+paramdemo ([1, 2, NaN, Inf])
+ at result{} Properties of input array:
+      includes Inf or NaN values
+      includes other values than 1 and 0
+      includes only int, Inf or NaN values
+ at end group
+ at end example
+
+ at node Exception and Error Handling in Oct-Files
+ at subsection Exception and Error Handling in Oct-Files
+
+Another important feature of Octave is its ability to react to the user
+typing @kbd{Control-C} even during calculations.  This ability is based on the
+C++ exception handler, where memory allocated by the C++ new/delete
+methods are automatically released when the exception is treated.  When
+writing an oct-file, to allow Octave to treat the user typing @kbd{Control-C},
+the @w{@code{OCTAVE_QUIT}} macro is supplied.  For example
+
+ at example
+ at group
+for (octave_idx_type i = 0; i < a.nelem (); i++)
+  @{
+    OCTAVE_QUIT;
+    b.elem(i) = 2. * a.elem(i);
+  @}
+ at end group
+ at end example
+
+The presence of the @w{@code{OCTAVE_QUIT}} macro in the inner loop allows Octave to
+treat the user request with the @kbd{Control-C}.  Without this macro, the user
+must either wait for the function to return before the interrupt is
+processed, or press @kbd{Control-C} three times to force Octave to exit.
+
+The @w{@code{OCTAVE_QUIT}} macro does impose a very small speed penalty, and so for
+loops that are known to be small it might not make sense to include
+ at w{@code{OCTAVE_QUIT}}.
+
+When creating an oct-file that uses an external libraries, the function
+might spend a significant portion of its time in the external
+library.  It is not generally possible to use the @w{@code{OCTAVE_QUIT}} macro in
+this case.  The alternative in this case is
+
+ at example
+ at group
+BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+ at dots{}  some code that calls a "foreign" function @dots{}
+END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+ at end group
+ at end example
+
+The disadvantage of this is that if the foreign code allocates any
+memory internally, then this memory might be lost during an interrupt,
+without being deallocated.  Therefore, ideally Octave itself should
+allocate any memory that is needed by the foreign code, with either the
+fortran_vec method or the @w{@code{OCTAVE_LOCAL_BUFFER}} macro.
+
+The Octave unwind_protect mechanism (@ref{The @code{unwind_protect} Statement})
+can also be used in oct-files.  In conjunction with the exception
+handling of Octave, it is important to enforce that certain code is run
+to allow variables, etc. to be restored even if an exception occurs.  An
+example of the use of this mechanism is
+
+ at longexamplefile{unwinddemo.cc}
+
+As can be seen in the example
+
+ at example
+ at group
+unwinddemo (1, 0)
+ at result{} Inf
+1 / 0
+ at result{} warning: division by zero
+   Inf
+ at end group
+ at end example
+
+The division by zero (and in fact all warnings) is disabled in the
+ at code{unwinddemo} function.
+
+ at node Documentation and Test of Oct-Files
+ at subsection Documentation and Test of Oct-Files
+
+The documentation of an oct-file is the fourth string parameter of the
+ at w{@code{DEFUN_DLD}} macro.  This string can be formatted in the same manner
+as the help strings for user functions (@ref{Documentation Tips}),
+however there are some issue that are particular to the formatting of
+help strings within oct-files.
+
+The major issue is that the help string will typically be longer than a
+single line of text, and so the formatting of long help strings need to
+be taken into account.  There are several manners in which to treat this
+issue, but the most common is illustrated in the following example
+
+ at example
+ at group
+DEFUN_DLD (do_what_i_want, args, nargout, 
+  "-*- texinfo -*-\n\
+@@deftypefn @{Function File@} @{@} do_what_i_say (@@var@{n@})\n\
+A function that does what the user actually wants rather\n\
+than what they requested.\n\
+@@end deftypefn")
+@{
+ at dots{}
+@}
+ at end group
+ at end example
+
+ at noindent
+where, as can be seen, end line of text within the help string is
+terminated by @code{\n\} which is an embedded new-line in the string
+together with a C++ string continuation character.  Note that the final
+ at code{\} must be the last character on the line.
+
+Octave also includes the ability to embed the test and demonstration
+code for a function within the code itself (@ref{Test and Demo Functions}).
+This can be used from within oct-files (or in fact any file) with
+certain provisos.  Firstly, the test and demo functions of Octave look
+for a @code{%!} as the first characters on a new-line to identify test
+and demonstration code.  This is equally a requirement for
+oct-files.  Furthermore the test and demonstration code must be included
+in a comment block of the compiled code to avoid it being interpreted by
+the compiler.  Finally, the Octave test and demonstration code must have
+access to the source code of the oct-file and not just the compiled code
+as the tests are stripped from the compiled code.  An example in an
+oct-file might be
+
+ at example
+ at group
+/*
+
+%!error (sin())
+%!error (sin(1,1))
+%!assert (sin([1,2]),[sin(1),sin(2)])
+
+*/
+ at end group
+ at end example
+
+ at c @node Application Programming Interface for Oct-Files
+ at c @subsection Application Programming Interface for Oct-Files
+ at c 
+ at c WRITE ME, using Coda section 1.3 as a starting point.
+
+ at node Mex-Files
+ at section Mex-Files
+ at cindex mex-files
+ at cindex mex
+
+Octave includes an interface to allow legacy mex-files to be compiled
+and used with Octave.  This interface can also be used to share code
+between Octave and non Octave users.  However, as mex-files expose the
+internal API of an alternative product to Octave, and the internal
+structure of Octave is different to this product, a mex-file can never
+have the same performance in Octave as the equivalent oct-file.  In
+particular to support the manner in which mex-files access the variables
+passed to mex functions, there are a significant number of additional
+copies of memory when calling or returning from a mex function.  For
+this reason, new code should be written using the oct-file interface
+discussed above if possible.
+
+ at menu
+* Getting Started with Mex-Files::  
+* Working with Matrices and Arrays in Mex-Files::  
+* Character Strings in Mex-Files::  
+* Cell Arrays with Mex-Files::  
+* Structures with Mex-Files::  
+* Sparse Matrices with Mex-Files::  
+* Calling Other Functions in Mex-Files::  
+ at c * Application Programming Interface for Mex-Files::  
+ at end menu
+
+ at node Getting Started with Mex-Files
+ at subsection Getting Started with Mex-Files
+
+The basic command to build a mex-file is either @code{mkoctfile --mex} or
+ at code{mex}.  The first can either be used from within Octave or from the
+command line.  However, to avoid issues with the installation of other
+products, the use of the command @code{mex} is limited to within Octave.
+
+ at DOCSTRING(mex)
+
+ at DOCSTRING(mexext)
+
+One important difference between the use of mex with other products and
+with Octave is that the header file "matrix.h" is implicitly included
+through the inclusion of "mex.h".  This is to avoid a conflict with the
+Octave file "Matrix.h" with operating systems and compilers that don't
+distinguish between filenames in upper and lower case
+
+Consider the short example
+
+ at examplefile{firstmexdemo.c}
+
+This simple example demonstrates the basics of writing a mex-file.  The
+entry point into the mex-file is defined by @code{mexFunction}.  Note
+that the function name is not explicitly included in the
+ at code{mexFunction} and so there can only be a single @code{mexFunction}
+entry point per-file.  Also the name of the function is determined by the
+name of the mex-file itself.  Therefore if the above function is in the
+file @file{firstmexdemo.c}, it can be compiled with
+
+ at example
+mkoctfile --mex firstmexdemo.c
+ at end example
+
+ at noindent
+which creates a file @file{firstmexdemo.mex}.  The function can then be run
+from Octave as
+
+ at example
+ at group
+firstmexdemo()
+ at result{} 1.2346
+ at end group
+ at end example
+
+It should be noted that the mex-file contains no help string for the
+functions it contains.  To document mex-files, there should exist an
+m-file in the same directory as the mex-file itself.  Taking the above as
+an example, we would therefore have a file @file{firstmexdemo.m} that might
+contain the text
+
+ at example
+%FIRSTMEXDEMO Simple test of the functionality of a mex-file.
+ at end example
+
+In this case, the function that will be executed within Octave will be
+given by the mex-file, while the help string will come from the
+m-file.  This can also be useful to allow a sample implementation of the
+mex-file within the Octave language itself for testing purposes.
+
+Although we cannot have multiple entry points into a single mex-file,
+we can use the @code{mexFunctionName} function to determine what name
+the mex-file was called with.  This can be used to alter the behavior of
+the mex-file based on the function name.  For example if
+
+ at examplefile{myfunc.c}
+
+ at noindent
+is in file @file{myfunc.c}, and it is compiled with
+
+ at example
+ at group
+mkoctfile --mex myfunc.c
+ln -s myfunc.mex myfunc2.mex
+ at end group
+ at end example
+
+Then as can be seen by
+
+ at example
+ at group
+myfunc()
+ at result{} You called function: myfunc
+    This is the principal function
+myfunc2()
+ at result{} You called function: myfunc2
+ at end group
+ at end example
+
+ at noindent
+the behavior of the mex-file can be altered depending on the functions
+name.
+
+Allow the user should only include @code{mex.h} in their code, Octave
+declares additional functions, typedefs, etc., available to the user to
+write mex-files in the headers @code{mexproto.h} and @code{mxarray.h}.
+
+ at node Working with Matrices and Arrays in Mex-Files
+ at subsection Working with Matrices and Arrays in Mex-Files
+
+The basic mex type of all variables is @code{mxArray}.  All variables,
+such as matrices, cell arrays or structures are all stored in this basic
+type, and this type serves basically the same purpose as the
+octave_value class in oct-files.  That is it acts as a container for the
+more specialized types.
+
+The @code{mxArray} structure contains at a minimum, the variable it
+represents name, its dimensions, its type and whether the variable is
+real or complex.  It can however contain a number of additional fields
+depending on the type of the @code{mxArray}.  There are a number of
+functions to create @code{mxArray} structures, including
+ at code{mxCreateCellArray}, @code{mxCreateSparse} and the generic
+ at code{mxCreateNumericArray}.
+
+The basic functions to access the data contained in an array is
+ at code{mxGetPr}.  As the mex interface assumes that the real and imaginary
+parts of a complex array are stored separately, there is an equivalent
+function @code{mxGetPi} that get the imaginary part.  Both of these
+functions are for use only with double precision matrices.  There also
+exists the generic function @code{mxGetData} and @code{mxGetImagData}
+that perform the same operation on all matrix types.  For example
+
+ at example
+ at group
+mxArray *m;
+mwSize *dims;
+UINT32_T *pr;
+
+dims = (mwSize *) mxMalloc (2 * sizeof(mwSize));
+dims[0] = 2;
+dims[1] = 2;
+m = mxCreateNumericArray (2, dims, mxUINT32_CLASS, mxREAL);
+pr =  = (UINT32_T *) mxGetData (m);
+ at end group
+ at end example
+
+There are also the functions @code{mxSetPr}, etc., that perform the
+inverse, and set the data of an Array to use the block of memory pointed
+to by the argument of @code{mxSetPr}.
+
+Note the type @code{mwSize} used above, and @code{mwIndex} are defined
+as the native precision of the indexing in Octave on the platform on
+which the mex-file is built.  This allows both 32- and 64-bit platforms
+to support mex-files.  @code{mwSize} is used to define array dimension
+and maximum number or elements, while @code{mwIndex} is used to define
+indexing into arrays.
+
+An example that demonstration how to work with arbitrary real or complex
+double precision arrays is given by the file @file{mypow2.c} as given
+below.
+
+ at longexamplefile{mypow2.c}
+
+ at noindent
+with an example of its use
+
+ at example
+ at group
+b = randn(4,1) + 1i * randn(4,1);
+all(b.^2 == mypow2(b))
+ at result{} 1
+ at end group
+ at end example
+
+
+The example above uses the functions @code{mxGetDimensions},
+ at code{mxGetNumberOfElements}, and @code{mxGetNumberOfDimensions} to work
+with the dimensions of multi-dimensional arrays.  The functions
+ at code{mxGetM}, and @code{mxGetN} are also available to find the number
+of rows and columns in a matrix.
+
+ at node Character Strings in Mex-Files
+ at subsection Character Strings in Mex-Files
+
+As mex-files do not make the distinction between single and double
+quoted strings within Octave, there is perhaps less complexity in the
+use of strings and character matrices in mex-files.  An example of their
+use, that parallels the demo in @file{stringdemo.cc}, is given in the
+file @file{mystring.c}, as seen below.
+
+ at longexamplefile{mystring.c}
+
+ at noindent
+An example of its expected output is
+
+ at example
+ at group
+mystring(["First String"; "Second String"])
+ at result{} s1 = Second String
+        First String
+ at end group
+ at end example
+
+Other functions in the mex interface for handling character strings are
+ at code{mxCreateString}, @code{mxArrayToString}, and
+ at code{mxCreateCharMatrixFromStrings}.  In a mex-file, a character string
+is considered to be a vector rather than a matrix.  This is perhaps an
+arbitrary distinction as the data in the mxArray for the matrix is
+consecutive in any case.
+
+ at node Cell Arrays with Mex-Files
+ at subsection Cell Arrays with Mex-Files
+
+We can perform exactly the same operations in Cell arrays in mex-files
+as we can in oct-files.  An example that reduplicates the functional of
+the @file{celldemo.cc} oct-file in a mex-file is given by
+ at file{mycell.c} as below
+
+ at examplefile{mycell.c}
+
+ at noindent
+which as can be seen below has exactly the same behavior as the oct-file
+version.
+
+ at example
+ at group
+[b1, b2, b3] = mycell (@{1, [1, 2], "test"@})
+ at result{}
+b1 =  1
+b2 =
+
+   1   2
+
+b3 = test
+ at end group
+ at end example
+
+Note in the example the use of the @code{mxDuplicateArray} function.  This
+is needed as the @code{mxArray} pointer returned by @code{mxGetCell}
+might be deallocated.  The inverse function to @code{mxGetCell} is
+ at code{mcSetCell} and is defined as
+
+ at example
+void mxSetCell (mxArray *ptr, int idx, mxArray *val);
+ at end example
+
+Finally, to create a cell array or matrix, the appropriate functions are
+
+ at example
+ at group
+mxArray *mxCreateCellArray (int ndims, const int *dims);
+mxArray *mxCreateCellMatrix (int m, int n);
+ at end group
+ at end example
+
+ at node Structures with Mex-Files
+ at subsection Structures with Mex-Files
+
+The basic function to create a structure in a mex-file is
+ at code{mxCreateStructMatrix}, which creates a structure array with a two
+dimensional matrix, or @code{mxCreateStructArray}.
+
+ at example
+ at group
+mxArray *mxCreateStructArray (int ndims, int *dims, 
+                              int num_keys, 
+                              const char **keys);
+mxArray *mxCreateStructMatrix (int rows, int cols, 
+                               int num_keys, 
+                               const char **keys);
+ at end group
+ at end example
+
+Accessing the fields of the structure can then be performed with the
+ at code{mxGetField} and @code{mxSetField} or alternatively with the
+ at code{mxGetFieldByNumber} and @code{mxSetFieldByNumber} functions.
+
+ at example
+ at group
+mxArray *mxGetField (const mxArray *ptr, mwIndex index,
+                     const char *key);
+mxArray *mxGetFieldByNumber (const mxArray *ptr, 
+                             mwIndex index, int key_num);
+void mxSetField (mxArray *ptr, mwIndex index, 
+                 const char *key, mxArray *val);
+void mxSetFieldByNumber (mxArray *ptr, mwIndex index, 
+                         int key_num, mxArray *val);
+ at end group
+ at end example
+
+A difference between the oct-file interface to structures and the
+mex-file version is that the functions to operate on structures in
+mex-files directly include an @code{index} over the elements of the
+arrays of elements per @code{field}.  Whereas the oct-file structure
+includes a Cell Array per field of the structure.
+
+An example that demonstrates the use of structures in mex-file can be
+found in the file @file{mystruct.c}, as seen below
+
+ at longexamplefile{mystruct.c}
+
+An example of the behavior of this function within Octave is then
+
+ at example
+a(1).f1 = "f11"; a(1).f2 = "f12"; 
+a(2).f1 = "f21"; a(2).f2 = "f22";
+b = mystruct(a)
+ at result{} field f1(0) = f11
+    field f1(1) = f21
+    field f2(0) = f12
+    field f2(1) = f22
+    b =
+    @{
+      this =
+    
+      (,
+        [1] = this1
+        [2] = this2
+        [3] = this3
+        [4] = this4
+      ,)
+    
+      that =
+    
+      (,
+        [1] = that1
+        [2] = that2
+        [3] = that3
+        [4] = that4
+      ,)
+    
+    @}
+ at end example
+
+ at node Sparse Matrices with Mex-Files
+ at subsection Sparse Matrices with Mex-Files
+
+The Octave format for sparse matrices is identical to the mex format in
+that it is a compressed column sparse format.  Also in both, sparse
+matrices are required to be two-dimensional.  The only difference is that
+the real and imaginary parts of the matrix are stored separately.
+
+The mex-file interface, as well as using @code{mxGetM}, @code{mxGetN},
+ at code{mxSetM}, @code{mxSetN}, @code{mxGetPr}, @code{mxGetPi},
+ at code{mxSetPr} and @code{mxSetPi}, the mex-file interface supplies the
+functions
+
+ at example
+ at group
+mwIndex *mxGetIr (const mxArray *ptr);
+mwIndex *mxGetJc (const mxArray *ptr);
+mwSize mxGetNzmax (const mxArray *ptr);
+
+void mxSetIr (mxArray *ptr, mwIndex *ir);
+void mxSetJc (mxArray *ptr, mwIndex *jc);
+void mxSetNzmax (mxArray *ptr, mwSize nzmax);
+ at end group
+ at end example
+
+ at noindent
+ at code{mxGetNzmax} gets the maximum number of elements that can be stored
+in the sparse matrix.  This is not necessarily the number of non-zero
+elements in the sparse matrix.  @code{mxGetJc} returns an array with one
+additional value than the number of columns in the sparse matrix.  The
+difference between consecutive values of the array returned by
+ at code{mxGetJc} define the number of non-zero elements in each column of
+the sparse matrix.  Therefore
+
+ at example
+ at group
+mwSize nz, n;
+mwIndex *Jc;
+mxArray *m;
+ at dots{}
+n = mxGetN (m);
+Jc = mxGetJc (m);
+nz = Jc[n];
+ at end group
+ at end example
+
+ at noindent
+returns the actual number of non-zero elements stored in the matrix in
+ at code{nz}.  As the arrays returned by @code{mxGetPr} and @code{mxGetPi}
+only contain the non-zero values of the matrix, we also need a pointer
+to the rows of the non-zero elements, and this is given by
+ at code{mxGetIr}.  A complete example of the use of sparse matrices in
+mex-files is given by the file @file{mysparse.c} as seen below
+
+ at longexamplefile{mysparse.c}
+
+ at node Calling Other Functions in Mex-Files
+ at subsection Calling Other Functions in Mex-Files
+
+It is also possible call other Octave functions from within a mex-file
+using @code{mexCallMATLAB}.  An example of the use of
+ at code{mexCallMATLAB} can be see in the example below
+
+ at longexamplefile{myfeval.c}
+
+If this code is in the file @file{myfeval.c}, and is compiled to
+ at file{myfeval.mex}, then an example of its use is
+
+ at example
+ at group
+myfeval("sin", 1)
+a = myfeval("sin", 1)
+ at result{} Hello, World!
+    I have 2 inputs and 1 outputs
+    I'm going to call the interpreter function sin
+    a =  0.84147
+ at end group
+ at end example
+
+Note that it is not possible to use function handles or inline functions
+within a mex-file.
+
+ at c @node Application Programming Interface for Mex-Files
+ at c @subsection Application Programming Interface for Mex-Files
+ at c 
+ at c WRITE ME, refer to mex.h and mexproto.h
+
+ at node Standalone Programs
+ at section Standalone Programs
+
+The libraries Octave itself uses, can be utilized in standalone
+applications.  These applications then have access, for example, to the
+array and matrix classes as well as to all the Octave algorithms.  The
+following C++ program, uses class Matrix from liboctave.a or
+liboctave.so.
+
+ at examplefile{standalone.cc}
+
+ at noindent
+mkoctfile can then be used to build a standalone application with a
+command like
+
+ at example
+ at group
+$ mkoctfile --link-stand-alone standalone.cc -o standalone
+$ ./standalone
+Hello Octave world!
+  11 12
+  21 22
+$
+ at end group
+ at end example
+
+Note that the application @code{hello} will be dynamically linked
+against the octave libraries and any octave support libraries.  The above
+allows the Octave math libraries to be used by an application.  It does
+not however allow the script files, oct-files or builtin functions of
+Octave to be used by the application.  To do that the Octave interpreter
+needs to be initialized first.  An example of how to do this can then be
+seen in the code
+
+ at examplefile{embedded.cc}
+
+ at noindent
+which is compiled and run as before as a standalone application with
+
+ at example
+ at group
+$ mkoctfile --link-stand-alone embedded.cc -o embedded
+$ ./embedded
+GCD of [10, 15] is 5
+$
+ at end group
+ at end example
+
diff --git a/doc/interpreter/emacs.texi b/doc/interpreter/emacs.texi
new file mode 100644
index 0000000..3407c3c
--- /dev/null
+++ b/doc/interpreter/emacs.texi
@@ -0,0 +1,507 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2001, 2002, 2003, 2005,
+ at c               2006, 2007, 2008, 2009 Kurt Hornik
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/05/17.
+ at c Last updated by KH on 1997/07/31.
+
+ at node Emacs Octave Support
+ at appendix Emacs Octave Support
+
+The development of Octave code can greatly be facilitated using Emacs
+with Octave mode, a major mode for editing Octave files which can e.g.@:
+automatically indent the code, do some of the typing (with Abbrev mode)
+and show keywords, comments, strings, etc.@: in different faces (with
+Font-lock mode on devices that support it).
+
+It is also possible to run Octave from within Emacs, either by directly
+entering commands at the prompt in a buffer in Inferior Octave mode, or
+by interacting with Octave from within a file with Octave code.  This is
+useful in particular for debugging Octave code.
+
+Finally, you can convince Octave to use the Emacs info reader for
+ at kbd{help -i}.
+
+All functionality is provided by the Emacs Lisp package EOS (for ``Emacs
+Octave Support'').  This chapter describes how to set up and use this
+package.
+
+Please contact <Kurt.Hornik@@wu-wien.ac.at> if you have any questions
+or suggestions on using EOS.
+
+ at menu
+* Installing EOS::              
+* Using Octave Mode::           
+* Running Octave From Within Emacs::  
+* Using the Emacs Info Reader for Octave::  
+ at end menu
+
+ at node Installing EOS
+ at appendixsec Installing EOS
+
+The Emacs package EOS consists of the three files @file{octave-mod.el},
+ at file{octave-inf.el}, and @file{octave-hlp.el}.  These files, or better
+yet their byte-compiled versions, should be somewhere in your Emacs
+load-path.
+
+If you have GNU Emacs with a version number at least as high as 19.35,
+you are all set up, because EOS is respectively will be part of GNU
+Emacs as of version 19.35.
+
+Otherwise, copy the three files from the @file{emacs} subdirectory of
+the Octave distribution to a place where Emacs can find them (this
+depends on how your Emacs was installed).  Byte-compile them for speed
+if you want.
+
+ at node Using Octave Mode
+ at appendixsec Using Octave Mode
+
+If you are lucky, your sysadmins have already arranged everything so
+that Emacs automatically goes into Octave mode whenever you visit an
+Octave code file as characterized by its extension @file{.m}.  If not,
+proceed as follows.
+
+ at enumerate
+ at item
+To begin using Octave mode for all @file{.m} files you visit, add the
+following lines to a file loaded by Emacs at startup time, typically
+your @file{~/.emacs} file:
+
+ at lisp
+(autoload 'octave-mode "octave-mod" nil t)
+(setq auto-mode-alist
+      (cons '("\\.m$" . octave-mode) auto-mode-alist))
+ at end lisp
+
+ at item
+Finally, to turn on the abbrevs, auto-fill and font-lock features
+automatically, also add the following lines to one of the Emacs startup
+files:
+ at lisp
+(add-hook 'octave-mode-hook
+          (lambda ()
+            (abbrev-mode 1)
+            (auto-fill-mode 1)
+            (if (eq window-system 'x)
+                (font-lock-mode 1))))
+ at end lisp
+See the Emacs manual for more information about how to customize
+Font-lock mode.
+ at end enumerate
+
+In Octave mode, the following special Emacs commands can be used in
+addition to the standard Emacs commands.
+
+ at table @kbd
+ at item C-h m
+Describe the features of Octave mode.
+
+ at item LFD
+Reindent the current Octave line, insert a newline and indent the new
+line (@code{octave-reindent-then-newline-and-indent}).  An abbrev before
+point is expanded if @code{abbrev-mode} is non- at code{nil}.
+
+ at item TAB
+Indents current Octave line based on its contents and on previous
+lines (@code{indent-according-to-mode}). 
+
+ at item ;
+Insert an ``electric'' semicolon (@code{octave-electric-semi}).  If
+ at code{octave-auto-indent} is non- at code{nil}, reindent the current line.
+If @code{octave-auto-newline} is non- at code{nil}, automagically insert a
+newline and indent the new line.
+
+ at item `
+Start entering an abbreviation (@code{octave-abbrev-start}).  If Abbrev
+mode is turned on, typing @kbd{`C-h} or @kbd{`?} lists all abbrevs.
+Any other key combination is executed normally.  Note that all Octave
+abbrevs start with a grave accent.
+
+ at item M-LFD
+Break line at point and insert continuation marker and alignment
+(@code{octave-split-line}).
+
+ at item M-TAB
+Perform completion on Octave symbol preceding point, comparing that
+symbol against Octave's reserved words and built-in variables
+(@code{octave-complete-symbol}). 
+
+ at item M-C-a
+Move backward to the beginning of a function
+(@code{octave-beginning-of-defun}).
+With prefix argument @var{N}, do it that many times if @var{N} is
+positive;  otherwise, move forward to the @var{N}-th following beginning
+of a function.
+
+ at item M-C-e
+Move forward to the end of a function (@code{octave-end-of-defun}).
+With prefix argument @var{N}, do it that many times if @var{N} is
+positive;  otherwise, move back to the @var{N}-th preceding end of a
+function.
+
+ at item M-C-h
+Puts point at beginning and mark at the end of the current Octave
+function, i.e., the one containing point or following point
+(@code{octave-mark-defun}).
+
+ at item M-C-q
+Properly indents the Octave function which contains point
+(@code{octave-indent-defun}).
+
+ at item M-;
+If there is no comment already on this line, create a code-level comment
+(started by two comment characters) if the line is empty, or an in-line
+comment (started by one comment character) otherwise
+(@code{octave-indent-for-comment}).
+Point is left after the start of the comment which is properly aligned.
+
+ at item C-c ;
+Puts the comment character @samp{#} (more precisely, the string value of
+ at code{octave-comment-start}) at the beginning of every line in the
+region (@code{octave-comment-region}).  With just @kbd{C-u} prefix
+argument, uncomment each line in the region.  A numeric prefix argument
+ at var{N} means use @var{N} comment characters.
+
+ at item C-c :
+Uncomments every line in the region (@code{octave-uncomment-region}).
+
+ at item C-c C-p
+Move one line of Octave code backward, skipping empty and comment lines
+(@code{octave-previous-code-line}).  With numeric prefix argument
+ at var{N}, move that many code lines backward (forward if @var{N} is
+negative).
+
+ at item C-c C-n
+Move one line of Octave code forward, skipping empty and comment lines
+(@code{octave-next-code-line}).  With numeric prefix argument @var{N},
+move that many code lines forward (backward if @var{N} is negative).
+
+ at item C-c C-a
+Move to the `real' beginning of the current line
+(@code{octave-beginning-of-line}).  If point is in an empty or comment
+line, simply go to its beginning;  otherwise, move backwards to the
+beginning of the first code line which is not inside a continuation
+statement, i.e., which does not follow a code line ending in @samp{...}
+or @samp{\}, or is inside an open parenthesis list.
+
+ at item C-c C-e
+Move to the `real' end of the current line (@code{octave-end-of-line}).
+If point is in a code line, move forward to the end of the first Octave
+code line which does not end in @samp{...} or @samp{\} or is inside an
+open parenthesis list.  Otherwise, simply go to the end of the current
+line.
+
+ at item C-c M-C-n
+Move forward across one balanced begin-end block of Octave code
+(@code{octave-forward-block}).  With numeric prefix argument @var{N},
+move forward across @var{n} such blocks (backward if @var{N} is
+negative).
+
+ at item C-c M-C-p
+Move back across one balanced begin-end block of Octave code
+(@code{octave-backward-block}).  With numeric prefix argument @var{N},
+move backward across @var{N} such blocks (forward if @var{N} is
+negative).
+
+ at item C-c M-C-d
+Move forward down one begin-end block level of Octave code
+(@code{octave-down-block}).  With numeric prefix argument, do it that
+many times;  a negative argument means move backward, but still go down
+one level.
+
+ at item C-c M-C-u
+Move backward out of one begin-end block level of Octave code
+(@code{octave-backward-up-block}).  With numeric prefix argument, do it
+that many times; a negative argument means move forward, but still to a
+less deep spot.
+
+ at item C-c M-C-h
+Put point at the beginning of this block, mark at the end
+(@code{octave-mark-block}).
+The block marked is the one that contains point or follows point.
+
+ at item C-c ]
+Close the current block on a separate line (@code{octave-close-block}).
+An error is signaled if no block to close is found.
+
+ at item C-c f
+Insert a function skeleton, prompting for the function's name, arguments
+and return values which have to be entered without parentheses
+(@code{octave-insert-defun}).
+
+ at item C-c C-h
+Search the function, operator and variable indices of all info files
+with documentation for Octave for entries (@code{octave-help}).  If used
+interactively, the entry is prompted for with completion.  If multiple
+matches are found, one can cycle through them using the standard
+ at samp{,} (@code{Info-index-next}) command of the Info reader.
+
+The variable @code{octave-help-files} is a list of files to search
+through and defaults to @code{'("octave")}.  If there is also an Octave
+Local Guide with corresponding info file, say, @file{octave-LG}, you can
+have @code{octave-help} search both files by 
+ at lisp
+(setq octave-help-files '("octave" "octave-LG"))
+ at end lisp
+ at noindent
+in one of your Emacs startup files.
+
+ at end table
+
+A common problem is that the @key{RET} key does @emph{not} indent the
+line to where the new text should go after inserting the newline.  This
+is because the standard Emacs convention is that @key{RET} (aka
+ at kbd{C-m}) just adds a newline, whereas @key{LFD} (aka @kbd{C-j}) adds a
+newline and indents it.  This is particularly inconvenient for users with
+keyboards which do not have a special @key{LFD} key at all;  in such
+cases, it is typically more convenient to use @key{RET} as the @key{LFD}
+key (rather than typing @kbd{C-j}).  
+
+You can make @key{RET} do this by adding
+ at lisp
+(define-key octave-mode-map "\C-m"
+  'octave-reindent-then-newline-and-indent)
+ at end lisp
+ at noindent
+to one of your Emacs startup files.  Another, more generally applicable
+solution is
+ at lisp
+(defun RET-behaves-as-LFD ()
+  (let ((x (key-binding "\C-j")))
+    (local-set-key "\C-m" x)))
+(add-hook 'octave-mode-hook 'RET-behaves-as-LFD)
+ at end lisp
+ at noindent
+(this works for all modes by adding to the startup hooks, without having
+to know the particular binding of @key{RET} in that mode!).  Similar
+considerations apply for using @key{M-RET} as @key{M-LFD}.  As Barry
+A. Warsaw <bwarsaw@@cnri.reston.va.us> says in the documentation for his
+ at code{cc-mode}, ``This is a very common question.  @code{:-)} If you want
+this to be the default behavior, don't lobby me, lobby RMS!''
+
+The following variables can be used to customize Octave mode.
+
+ at table @code
+ at item octave-auto-indent
+Non- at code{nil} means auto-indent the current line after a semicolon or
+space.  Default is @code{nil}.
+
+ at item octave-auto-newline
+Non- at code{nil} means auto-insert a newline and indent after semicolons
+are typed.  The default value is @code{nil}.
+
+ at item octave-blink-matching-block
+Non- at code{nil} means show matching begin of block when inserting a space,
+newline or @samp{;} after an else or end keyword.  Default is @code{t}.
+This is an extremely useful feature for automatically verifying that the
+keywords match---if they don't, an error message is displayed.
+
+ at item octave-block-offset
+Extra indentation applied to statements in block structures.
+Default is 2.
+
+ at item octave-continuation-offset
+Extra indentation applied to Octave continuation lines.
+Default is 4. 
+
+ at item octave-continuation-string
+String used for Octave continuation lines.
+Normally @samp{\}.
+
+ at item octave-mode-startup-message
+If @code{t} (default), a startup message is displayed when Octave mode
+is called.
+
+ at end table
+
+If Font Lock mode is enabled, Octave mode will display
+ at itemize @bullet
+ at item
+strings in @code{font-lock-string-face}
+ at item
+comments in @code{font-lock-comment-face}
+ at item
+the Octave reserved words (such as all block keywords) and the text
+functions (such as @samp{cd} or @samp{who}) which are also reserved
+using @code{font-lock-keyword-face}
+ at item
+the built-in operators (@samp{&&}, @samp{==}, @dots{}) using
+ at code{font-lock-reference-face}
+ at item
+and the function names in function declarations in
+ at code{font-lock-function-name-face}.
+ at end itemize
+
+There is also rudimentary support for Imenu (currently, function names
+can be indexed).
+
+ at cindex TAGS
+ at cindex Emacs TAGS files
+ at cindex @code{octave-tags}
+You can generate TAGS files for Emacs from Octave @file{.m} files using
+the shell script @code{octave-tags} that is installed alongside your copy of
+Octave.
+
+Customization of Octave mode can be performed by modification of the
+variable @code{octave-mode-hook}.  If the value of this variable is
+non- at code{nil}, turning on Octave mode calls its value.
+
+If you discover a problem with Octave mode, you can conveniently send a
+bug report using @kbd{C-c C-b} (@code{octave-submit-bug-report}).  This
+automatically sets up a mail buffer with version information already
+added.  You just need to add a description of the problem, including a
+reproducible test case and send the message.
+
+ at node Running Octave From Within Emacs
+ at appendixsec Running Octave From Within Emacs
+
+The package @file{octave} provides commands for running an inferior
+Octave process in a special Emacs buffer.  Use 
+ at lisp
+M-x run-octave
+ at end lisp
+ at noindent
+to directly start an inferior Octave process.  If Emacs does not know
+about this command, add the line
+ at lisp
+(autoload 'run-octave "octave-inf" nil t)
+ at end lisp
+ at noindent
+to your @file{.emacs} file.
+
+This will start Octave in a special buffer the name of which is
+specified by the variable @code{inferior-octave-buffer} and defaults to
+ at code{"*Inferior Octave*"}.  From within this buffer, you can
+interact with the inferior Octave process `as usual', i.e., by entering
+Octave commands at the prompt.  The buffer is in Inferior Octave mode,
+which is derived from the standard Comint mode, a major mode for
+interacting with an inferior interpreter.  See the documentation for
+ at code{comint-mode} for more details, and use @kbd{C-h b} to find out
+about available special keybindings.
+
+You can also communicate with an inferior Octave process from within
+files with Octave code (i.e., buffers in Octave mode), using the
+following commands.
+
+ at table @kbd
+ at item C-c i l
+Send the current line to the inferior Octave process
+(@code{octave-send-line}).
+With positive prefix argument @var{N}, send that many lines.
+If @code{octave-send-line-auto-forward} is non- at code{nil}, go to the
+next unsent code line.
+ at item C-c i b
+Send the current block to the inferior Octave process
+(@code{octave-send-block}).
+ at item C-c i f
+Send the current function to the inferior Octave process
+(@code{octave-send-defun}).
+ at item C-c i r
+Send the region to the inferior Octave process
+(@code{octave-send-region}).
+ at item C-c i s
+Make sure that `inferior-octave-buffer' is displayed
+(@code{octave-show-process-buffer}).
+ at item C-c i h
+Delete all windows that display the inferior Octave buffer
+(@code{octave-hide-process-buffer}).
+ at item C-c i k
+Kill the inferior Octave process and its buffer
+(@code{octave-kill-process}).
+ at end table
+
+The effect of the commands which send code to the Octave process can be
+customized by the following variables.
+ at table @code
+ at item octave-send-echo-input
+Non- at code{nil} means echo input sent to the inferior Octave process.
+Default is @code{t}.
+
+ at item octave-send-show-buffer
+Non- at code{nil} means display the buffer running the Octave process after
+sending a command (but without selecting it).
+Default is @code{t}.
+ at end table
+
+If you send code and there is no inferior Octave process yet, it will be
+started automatically.
+
+The startup of the inferior Octave process is highly customizable.
+The variable @code{inferior-octave-startup-args} can be used for
+specifying command lines arguments to be passed to Octave on startup
+as a list of strings.  For example, to suppress the startup message and
+use `traditional' mode, set this to @code{'("-q" "--traditional")}.
+You can also specify a startup file of Octave commands to be loaded on
+startup;  note that these commands will not produce any visible output
+in the process buffer.  Which file to use is controlled by the variable
+ at code{inferior-octave-startup-file}.  If this is @code{nil}, the file
+ at file{~/.emacs-octave} is used if it exists.
+
+And finally, @code{inferior-octave-mode-hook} is run after starting the
+process and putting its buffer into Inferior Octave mode.  Hence, if you
+like the up and down arrow keys to behave in the interaction buffer as
+in the shell, and you want this buffer to use nice colors, add
+ at lisp
+(add-hook 'inferior-octave-mode-hook
+          (lambda ()
+            (turn-on-font-lock)
+            (define-key inferior-octave-mode-map [up]
+              'comint-previous-input)
+            (define-key inferior-octave-mode-map [down]
+              'comint-next-input)))
+ at end lisp
+ at noindent
+to your @file{.emacs} file.  You could also swap the roles of @kbd{C-a}
+(@code{beginning-of-line}) and @code{C-c C-a} (@code{comint-bol}) using
+this hook.
+
+ at quotation
+ at strong{Note} that if you set your Octave prompts to something different
+from the defaults, make sure that @code{inferior-octave-prompt} matches
+them.  Otherwise, @emph{nothing} will work, because Emacs will not know
+when Octave is waiting for input, or done sending output.
+ at end quotation
+
+ at node Using the Emacs Info Reader for Octave
+ at appendixsec Using the Emacs Info Reader for Octave
+
+You may also use the Emacs Info reader with Octave's @code{doc} function.
+For this, the package @file{gnuserv} needs to be installed.
+
+If @file{gnuserv} is installed, add the lines
+ at lisp
+(autoload 'octave-help "octave-hlp" nil t)
+(require 'gnuserv)
+(gnuserv-start)
+ at end lisp
+ at noindent
+to your @file{.emacs} file.
+
+You can use either `plain' Emacs Info or the function @code{octave-help}
+as your Octave info reader (for @samp{help -i}).  In the former case,
+use @code{info_program ("info-emacs-info")}.
+The latter is perhaps more attractive because it allows to look up keys
+in the indices of @emph{several} info files related to Octave (provided
+that the Emacs variable @code{octave-help-files} is set correctly).  In
+this case, use @code{info_program ("info-emacs-octave-help")}.
+
+If you use Octave from within Emacs, it is best to add these settings to
+your @file{~/.emacs-octave} startup file (or the file pointed to by the
+Emacs variable @code{inferior-octave-startup-file}).
diff --git a/doc/interpreter/emacs.txi b/doc/interpreter/emacs.txi
new file mode 100644
index 0000000..6cf1aed
--- /dev/null
+++ b/doc/interpreter/emacs.txi
@@ -0,0 +1,505 @@
+ at c Copyright (C) 1996, 1997, 1999, 2001, 2002, 2003, 2005,
+ at c               2006, 2007, 2008, 2009 Kurt Hornik
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/05/17.
+ at c Last updated by KH on 1997/07/31.
+
+ at node Emacs Octave Support
+ at appendix Emacs Octave Support
+
+The development of Octave code can greatly be facilitated using Emacs
+with Octave mode, a major mode for editing Octave files which can e.g.@:
+automatically indent the code, do some of the typing (with Abbrev mode)
+and show keywords, comments, strings, etc.@: in different faces (with
+Font-lock mode on devices that support it).
+
+It is also possible to run Octave from within Emacs, either by directly
+entering commands at the prompt in a buffer in Inferior Octave mode, or
+by interacting with Octave from within a file with Octave code.  This is
+useful in particular for debugging Octave code.
+
+Finally, you can convince Octave to use the Emacs info reader for
+ at kbd{help -i}.
+
+All functionality is provided by the Emacs Lisp package EOS (for ``Emacs
+Octave Support'').  This chapter describes how to set up and use this
+package.
+
+Please contact <Kurt.Hornik@@wu-wien.ac.at> if you have any questions
+or suggestions on using EOS.
+
+ at menu
+* Installing EOS::              
+* Using Octave Mode::           
+* Running Octave From Within Emacs::  
+* Using the Emacs Info Reader for Octave::  
+ at end menu
+
+ at node Installing EOS
+ at appendixsec Installing EOS
+
+The Emacs package EOS consists of the three files @file{octave-mod.el},
+ at file{octave-inf.el}, and @file{octave-hlp.el}.  These files, or better
+yet their byte-compiled versions, should be somewhere in your Emacs
+load-path.
+
+If you have GNU Emacs with a version number at least as high as 19.35,
+you are all set up, because EOS is respectively will be part of GNU
+Emacs as of version 19.35.
+
+Otherwise, copy the three files from the @file{emacs} subdirectory of
+the Octave distribution to a place where Emacs can find them (this
+depends on how your Emacs was installed).  Byte-compile them for speed
+if you want.
+
+ at node Using Octave Mode
+ at appendixsec Using Octave Mode
+
+If you are lucky, your sysadmins have already arranged everything so
+that Emacs automatically goes into Octave mode whenever you visit an
+Octave code file as characterized by its extension @file{.m}.  If not,
+proceed as follows.
+
+ at enumerate
+ at item
+To begin using Octave mode for all @file{.m} files you visit, add the
+following lines to a file loaded by Emacs at startup time, typically
+your @file{~/.emacs} file:
+
+ at lisp
+(autoload 'octave-mode "octave-mod" nil t)
+(setq auto-mode-alist
+      (cons '("\\.m$" . octave-mode) auto-mode-alist))
+ at end lisp
+
+ at item
+Finally, to turn on the abbrevs, auto-fill and font-lock features
+automatically, also add the following lines to one of the Emacs startup
+files:
+ at lisp
+(add-hook 'octave-mode-hook
+          (lambda ()
+            (abbrev-mode 1)
+            (auto-fill-mode 1)
+            (if (eq window-system 'x)
+                (font-lock-mode 1))))
+ at end lisp
+See the Emacs manual for more information about how to customize
+Font-lock mode.
+ at end enumerate
+
+In Octave mode, the following special Emacs commands can be used in
+addition to the standard Emacs commands.
+
+ at table @kbd
+ at item C-h m
+Describe the features of Octave mode.
+
+ at item LFD
+Reindent the current Octave line, insert a newline and indent the new
+line (@code{octave-reindent-then-newline-and-indent}).  An abbrev before
+point is expanded if @code{abbrev-mode} is non- at code{nil}.
+
+ at item TAB
+Indents current Octave line based on its contents and on previous
+lines (@code{indent-according-to-mode}). 
+
+ at item ;
+Insert an ``electric'' semicolon (@code{octave-electric-semi}).  If
+ at code{octave-auto-indent} is non- at code{nil}, reindent the current line.
+If @code{octave-auto-newline} is non- at code{nil}, automagically insert a
+newline and indent the new line.
+
+ at item `
+Start entering an abbreviation (@code{octave-abbrev-start}).  If Abbrev
+mode is turned on, typing @kbd{`C-h} or @kbd{`?} lists all abbrevs.
+Any other key combination is executed normally.  Note that all Octave
+abbrevs start with a grave accent.
+
+ at item M-LFD
+Break line at point and insert continuation marker and alignment
+(@code{octave-split-line}).
+
+ at item M-TAB
+Perform completion on Octave symbol preceding point, comparing that
+symbol against Octave's reserved words and built-in variables
+(@code{octave-complete-symbol}). 
+
+ at item M-C-a
+Move backward to the beginning of a function
+(@code{octave-beginning-of-defun}).
+With prefix argument @var{N}, do it that many times if @var{N} is
+positive;  otherwise, move forward to the @var{N}-th following beginning
+of a function.
+
+ at item M-C-e
+Move forward to the end of a function (@code{octave-end-of-defun}).
+With prefix argument @var{N}, do it that many times if @var{N} is
+positive;  otherwise, move back to the @var{N}-th preceding end of a
+function.
+
+ at item M-C-h
+Puts point at beginning and mark at the end of the current Octave
+function, i.e., the one containing point or following point
+(@code{octave-mark-defun}).
+
+ at item M-C-q
+Properly indents the Octave function which contains point
+(@code{octave-indent-defun}).
+
+ at item M-;
+If there is no comment already on this line, create a code-level comment
+(started by two comment characters) if the line is empty, or an in-line
+comment (started by one comment character) otherwise
+(@code{octave-indent-for-comment}).
+Point is left after the start of the comment which is properly aligned.
+
+ at item C-c ;
+Puts the comment character @samp{#} (more precisely, the string value of
+ at code{octave-comment-start}) at the beginning of every line in the
+region (@code{octave-comment-region}).  With just @kbd{C-u} prefix
+argument, uncomment each line in the region.  A numeric prefix argument
+ at var{N} means use @var{N} comment characters.
+
+ at item C-c :
+Uncomments every line in the region (@code{octave-uncomment-region}).
+
+ at item C-c C-p
+Move one line of Octave code backward, skipping empty and comment lines
+(@code{octave-previous-code-line}).  With numeric prefix argument
+ at var{N}, move that many code lines backward (forward if @var{N} is
+negative).
+
+ at item C-c C-n
+Move one line of Octave code forward, skipping empty and comment lines
+(@code{octave-next-code-line}).  With numeric prefix argument @var{N},
+move that many code lines forward (backward if @var{N} is negative).
+
+ at item C-c C-a
+Move to the `real' beginning of the current line
+(@code{octave-beginning-of-line}).  If point is in an empty or comment
+line, simply go to its beginning;  otherwise, move backwards to the
+beginning of the first code line which is not inside a continuation
+statement, i.e., which does not follow a code line ending in @samp{...}
+or @samp{\}, or is inside an open parenthesis list.
+
+ at item C-c C-e
+Move to the `real' end of the current line (@code{octave-end-of-line}).
+If point is in a code line, move forward to the end of the first Octave
+code line which does not end in @samp{...} or @samp{\} or is inside an
+open parenthesis list.  Otherwise, simply go to the end of the current
+line.
+
+ at item C-c M-C-n
+Move forward across one balanced begin-end block of Octave code
+(@code{octave-forward-block}).  With numeric prefix argument @var{N},
+move forward across @var{n} such blocks (backward if @var{N} is
+negative).
+
+ at item C-c M-C-p
+Move back across one balanced begin-end block of Octave code
+(@code{octave-backward-block}).  With numeric prefix argument @var{N},
+move backward across @var{N} such blocks (forward if @var{N} is
+negative).
+
+ at item C-c M-C-d
+Move forward down one begin-end block level of Octave code
+(@code{octave-down-block}).  With numeric prefix argument, do it that
+many times;  a negative argument means move backward, but still go down
+one level.
+
+ at item C-c M-C-u
+Move backward out of one begin-end block level of Octave code
+(@code{octave-backward-up-block}).  With numeric prefix argument, do it
+that many times; a negative argument means move forward, but still to a
+less deep spot.
+
+ at item C-c M-C-h
+Put point at the beginning of this block, mark at the end
+(@code{octave-mark-block}).
+The block marked is the one that contains point or follows point.
+
+ at item C-c ]
+Close the current block on a separate line (@code{octave-close-block}).
+An error is signaled if no block to close is found.
+
+ at item C-c f
+Insert a function skeleton, prompting for the function's name, arguments
+and return values which have to be entered without parentheses
+(@code{octave-insert-defun}).
+
+ at item C-c C-h
+Search the function, operator and variable indices of all info files
+with documentation for Octave for entries (@code{octave-help}).  If used
+interactively, the entry is prompted for with completion.  If multiple
+matches are found, one can cycle through them using the standard
+ at samp{,} (@code{Info-index-next}) command of the Info reader.
+
+The variable @code{octave-help-files} is a list of files to search
+through and defaults to @code{'("octave")}.  If there is also an Octave
+Local Guide with corresponding info file, say, @file{octave-LG}, you can
+have @code{octave-help} search both files by 
+ at lisp
+(setq octave-help-files '("octave" "octave-LG"))
+ at end lisp
+ at noindent
+in one of your Emacs startup files.
+
+ at end table
+
+A common problem is that the @key{RET} key does @emph{not} indent the
+line to where the new text should go after inserting the newline.  This
+is because the standard Emacs convention is that @key{RET} (aka
+ at kbd{C-m}) just adds a newline, whereas @key{LFD} (aka @kbd{C-j}) adds a
+newline and indents it.  This is particularly inconvenient for users with
+keyboards which do not have a special @key{LFD} key at all;  in such
+cases, it is typically more convenient to use @key{RET} as the @key{LFD}
+key (rather than typing @kbd{C-j}).  
+
+You can make @key{RET} do this by adding
+ at lisp
+(define-key octave-mode-map "\C-m"
+  'octave-reindent-then-newline-and-indent)
+ at end lisp
+ at noindent
+to one of your Emacs startup files.  Another, more generally applicable
+solution is
+ at lisp
+(defun RET-behaves-as-LFD ()
+  (let ((x (key-binding "\C-j")))
+    (local-set-key "\C-m" x)))
+(add-hook 'octave-mode-hook 'RET-behaves-as-LFD)
+ at end lisp
+ at noindent
+(this works for all modes by adding to the startup hooks, without having
+to know the particular binding of @key{RET} in that mode!).  Similar
+considerations apply for using @key{M-RET} as @key{M-LFD}.  As Barry
+A. Warsaw <bwarsaw@@cnri.reston.va.us> says in the documentation for his
+ at code{cc-mode}, ``This is a very common question.  @code{:-)} If you want
+this to be the default behavior, don't lobby me, lobby RMS!''
+
+The following variables can be used to customize Octave mode.
+
+ at table @code
+ at item octave-auto-indent
+Non- at code{nil} means auto-indent the current line after a semicolon or
+space.  Default is @code{nil}.
+
+ at item octave-auto-newline
+Non- at code{nil} means auto-insert a newline and indent after semicolons
+are typed.  The default value is @code{nil}.
+
+ at item octave-blink-matching-block
+Non- at code{nil} means show matching begin of block when inserting a space,
+newline or @samp{;} after an else or end keyword.  Default is @code{t}.
+This is an extremely useful feature for automatically verifying that the
+keywords match---if they don't, an error message is displayed.
+
+ at item octave-block-offset
+Extra indentation applied to statements in block structures.
+Default is 2.
+
+ at item octave-continuation-offset
+Extra indentation applied to Octave continuation lines.
+Default is 4. 
+
+ at item octave-continuation-string
+String used for Octave continuation lines.
+Normally @samp{\}.
+
+ at item octave-mode-startup-message
+If @code{t} (default), a startup message is displayed when Octave mode
+is called.
+
+ at end table
+
+If Font Lock mode is enabled, Octave mode will display
+ at itemize @bullet
+ at item
+strings in @code{font-lock-string-face}
+ at item
+comments in @code{font-lock-comment-face}
+ at item
+the Octave reserved words (such as all block keywords) and the text
+functions (such as @samp{cd} or @samp{who}) which are also reserved
+using @code{font-lock-keyword-face}
+ at item
+the built-in operators (@samp{&&}, @samp{==}, @dots{}) using
+ at code{font-lock-reference-face}
+ at item
+and the function names in function declarations in
+ at code{font-lock-function-name-face}.
+ at end itemize
+
+There is also rudimentary support for Imenu (currently, function names
+can be indexed).
+
+ at cindex TAGS
+ at cindex Emacs TAGS files
+ at cindex @code{octave-tags}
+You can generate TAGS files for Emacs from Octave @file{.m} files using
+the shell script @code{octave-tags} that is installed alongside your copy of
+Octave.
+
+Customization of Octave mode can be performed by modification of the
+variable @code{octave-mode-hook}.  If the value of this variable is
+non- at code{nil}, turning on Octave mode calls its value.
+
+If you discover a problem with Octave mode, you can conveniently send a
+bug report using @kbd{C-c C-b} (@code{octave-submit-bug-report}).  This
+automatically sets up a mail buffer with version information already
+added.  You just need to add a description of the problem, including a
+reproducible test case and send the message.
+
+ at node Running Octave From Within Emacs
+ at appendixsec Running Octave From Within Emacs
+
+The package @file{octave} provides commands for running an inferior
+Octave process in a special Emacs buffer.  Use 
+ at lisp
+M-x run-octave
+ at end lisp
+ at noindent
+to directly start an inferior Octave process.  If Emacs does not know
+about this command, add the line
+ at lisp
+(autoload 'run-octave "octave-inf" nil t)
+ at end lisp
+ at noindent
+to your @file{.emacs} file.
+
+This will start Octave in a special buffer the name of which is
+specified by the variable @code{inferior-octave-buffer} and defaults to
+ at code{"*Inferior Octave*"}.  From within this buffer, you can
+interact with the inferior Octave process `as usual', i.e., by entering
+Octave commands at the prompt.  The buffer is in Inferior Octave mode,
+which is derived from the standard Comint mode, a major mode for
+interacting with an inferior interpreter.  See the documentation for
+ at code{comint-mode} for more details, and use @kbd{C-h b} to find out
+about available special keybindings.
+
+You can also communicate with an inferior Octave process from within
+files with Octave code (i.e., buffers in Octave mode), using the
+following commands.
+
+ at table @kbd
+ at item C-c i l
+Send the current line to the inferior Octave process
+(@code{octave-send-line}).
+With positive prefix argument @var{N}, send that many lines.
+If @code{octave-send-line-auto-forward} is non- at code{nil}, go to the
+next unsent code line.
+ at item C-c i b
+Send the current block to the inferior Octave process
+(@code{octave-send-block}).
+ at item C-c i f
+Send the current function to the inferior Octave process
+(@code{octave-send-defun}).
+ at item C-c i r
+Send the region to the inferior Octave process
+(@code{octave-send-region}).
+ at item C-c i s
+Make sure that `inferior-octave-buffer' is displayed
+(@code{octave-show-process-buffer}).
+ at item C-c i h
+Delete all windows that display the inferior Octave buffer
+(@code{octave-hide-process-buffer}).
+ at item C-c i k
+Kill the inferior Octave process and its buffer
+(@code{octave-kill-process}).
+ at end table
+
+The effect of the commands which send code to the Octave process can be
+customized by the following variables.
+ at table @code
+ at item octave-send-echo-input
+Non- at code{nil} means echo input sent to the inferior Octave process.
+Default is @code{t}.
+
+ at item octave-send-show-buffer
+Non- at code{nil} means display the buffer running the Octave process after
+sending a command (but without selecting it).
+Default is @code{t}.
+ at end table
+
+If you send code and there is no inferior Octave process yet, it will be
+started automatically.
+
+The startup of the inferior Octave process is highly customizable.
+The variable @code{inferior-octave-startup-args} can be used for
+specifying command lines arguments to be passed to Octave on startup
+as a list of strings.  For example, to suppress the startup message and
+use `traditional' mode, set this to @code{'("-q" "--traditional")}.
+You can also specify a startup file of Octave commands to be loaded on
+startup;  note that these commands will not produce any visible output
+in the process buffer.  Which file to use is controlled by the variable
+ at code{inferior-octave-startup-file}.  If this is @code{nil}, the file
+ at file{~/.emacs-octave} is used if it exists.
+
+And finally, @code{inferior-octave-mode-hook} is run after starting the
+process and putting its buffer into Inferior Octave mode.  Hence, if you
+like the up and down arrow keys to behave in the interaction buffer as
+in the shell, and you want this buffer to use nice colors, add
+ at lisp
+(add-hook 'inferior-octave-mode-hook
+          (lambda ()
+            (turn-on-font-lock)
+            (define-key inferior-octave-mode-map [up]
+              'comint-previous-input)
+            (define-key inferior-octave-mode-map [down]
+              'comint-next-input)))
+ at end lisp
+ at noindent
+to your @file{.emacs} file.  You could also swap the roles of @kbd{C-a}
+(@code{beginning-of-line}) and @code{C-c C-a} (@code{comint-bol}) using
+this hook.
+
+ at quotation
+ at strong{Note} that if you set your Octave prompts to something different
+from the defaults, make sure that @code{inferior-octave-prompt} matches
+them.  Otherwise, @emph{nothing} will work, because Emacs will not know
+when Octave is waiting for input, or done sending output.
+ at end quotation
+
+ at node Using the Emacs Info Reader for Octave
+ at appendixsec Using the Emacs Info Reader for Octave
+
+You may also use the Emacs Info reader with Octave's @code{doc} function.
+For this, the package @file{gnuserv} needs to be installed.
+
+If @file{gnuserv} is installed, add the lines
+ at lisp
+(autoload 'octave-help "octave-hlp" nil t)
+(require 'gnuserv)
+(gnuserv-start)
+ at end lisp
+ at noindent
+to your @file{.emacs} file.
+
+You can use either `plain' Emacs Info or the function @code{octave-help}
+as your Octave info reader (for @samp{help -i}).  In the former case,
+use @code{info_program ("info-emacs-info")}.
+The latter is perhaps more attractive because it allows to look up keys
+in the indices of @emph{several} info files related to Octave (provided
+that the Emacs variable @code{octave-help-files} is set correctly).  In
+this case, use @code{info_program ("info-emacs-octave-help")}.
+
+If you use Octave from within Emacs, it is best to add these settings to
+your @file{~/.emacs-octave} startup file (or the file pointed to by the
+Emacs variable @code{inferior-octave-startup-file}).
diff --git a/doc/interpreter/errorbar.eps b/doc/interpreter/errorbar.eps
new file mode 100644
index 0000000..3abc04d
--- /dev/null
+++ b/doc/interpreter/errorbar.eps
@@ -0,0 +1,1506 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: errorbar.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:55 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (errorbar.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:55 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+913 718 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 718 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 1650 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 1650 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 2582 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 2582 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 3514 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 3514 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 4446 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 4446 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 913 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2028 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2028 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3143 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3143 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4257 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4257 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5372 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5372 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (8)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6487 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6487 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+1.000 UP
+0.500 UL
+LT0
+0.00 0.00 1.00 C 913 2404 M
+0 246 V
+882 2404 M
+62 0 V
+-62 246 R
+62 0 V
+25 -59 R
+0 209 V
+938 2591 M
+62 0 V
+-62 209 R
+62 0 V
+24 142 R
+0 136 V
+993 2942 M
+62 0 V
+-62 136 R
+62 0 V
+25 39 R
+0 31 V
+-31 -31 R
+62 0 V
+-62 31 R
+62 0 V
+25 4 R
+0 334 V
+-31 -334 R
+62 0 V
+-62 334 R
+62 0 V
+25 -148 R
+0 142 V
+-31 -142 R
+62 0 V
+-62 142 R
+62 0 V
+24 29 R
+0 261 V
+-31 -261 R
+62 0 V
+-62 261 R
+62 0 V
+25 -45 R
+0 62 V
+-31 -62 R
+62 0 V
+-62 62 R
+62 0 V
+25 19 R
+0 161 V
+-31 -161 R
+62 0 V
+-62 161 R
+62 0 V
+25 -38 R
+0 264 V
+-31 -264 R
+62 0 V
+-62 264 R
+62 0 V
+24 -151 R
+0 137 V
+-31 -137 R
+62 0 V
+-62 137 R
+62 0 V
+25 34 R
+0 64 V
+-31 -64 R
+62 0 V
+-62 64 R
+62 0 V
+25 -38 R
+0 209 V
+-31 -209 R
+62 0 V
+-62 209 R
+62 0 V
+25 -144 R
+0 146 V
+-31 -146 R
+62 0 V
+-62 146 R
+62 0 V
+24 -166 R
+0 143 V
+-31 -143 R
+62 0 V
+-62 143 R
+62 0 V
+25 -171 R
+0 369 V
+-31 -369 R
+62 0 V
+-62 369 R
+62 0 V
+25 -357 R
+0 205 V
+-31 -205 R
+62 0 V
+-62 205 R
+62 0 V
+25 -144 R
+0 108 V
+-31 -108 R
+62 0 V
+stroke 1892 4329 M
+-62 108 R
+62 0 V
+24 -123 R
+0 147 V
+-31 -147 R
+62 0 V
+-62 147 R
+62 0 V
+25 -165 R
+0 164 V
+-31 -164 R
+62 0 V
+-62 164 R
+62 0 V
+25 -190 R
+0 145 V
+-31 -145 R
+62 0 V
+-62 145 R
+62 0 V
+25 -229 R
+0 26 V
+-31 -26 R
+62 0 V
+-62 26 R
+62 0 V
+24 -210 R
+0 150 V
+-31 -150 R
+62 0 V
+-62 150 R
+62 0 V
+25 -240 R
+0 65 V
+-31 -65 R
+62 0 V
+-62 65 R
+62 0 V
+25 -207 R
+0 154 V
+-31 -154 R
+62 0 V
+-62 154 R
+62 0 V
+25 -393 R
+0 309 V
+-31 -309 R
+62 0 V
+-62 309 R
+62 0 V
+24 -395 R
+0 236 V
+-31 -236 R
+62 0 V
+-62 236 R
+62 0 V
+25 -407 R
+0 273 V
+-31 -273 R
+62 0 V
+-62 273 R
+62 0 V
+25 -385 R
+0 185 V
+-31 -185 R
+62 0 V
+-62 185 R
+62 0 V
+24 -324 R
+0 166 V
+-31 -166 R
+62 0 V
+-62 166 R
+62 0 V
+25 -405 R
+0 192 V
+-31 -192 R
+62 0 V
+-62 192 R
+62 0 V
+25 -342 R
+0 114 V
+-31 -114 R
+62 0 V
+-62 114 R
+62 0 V
+25 -370 R
+0 137 V
+-31 -137 R
+62 0 V
+-62 137 R
+62 0 V
+24 -413 R
+0 309 V
+-31 -309 R
+62 0 V
+-62 309 R
+62 0 V
+25 -431 R
+0 185 V
+-31 -185 R
+62 0 V
+-62 185 R
+62 0 V
+stroke 2839 2165 M
+25 -271 R
+0 53 V
+-31 -53 R
+62 0 V
+-62 53 R
+62 0 V
+25 -356 R
+0 250 V
+-31 -250 R
+62 0 V
+-62 250 R
+62 0 V
+24 -395 R
+0 312 V
+-31 -312 R
+62 0 V
+-62 312 R
+62 0 V
+25 -453 R
+0 160 V
+-31 -160 R
+62 0 V
+-62 160 R
+62 0 V
+25 -334 R
+0 278 V
+-31 -278 R
+62 0 V
+-62 278 R
+62 0 V
+25 -380 R
+0 216 V
+-31 -216 R
+62 0 V
+-62 216 R
+62 0 V
+24 -335 R
+0 243 V
+3167 910 M
+62 0 V
+-62 243 R
+62 0 V
+25 -261 R
+0 93 V
+-31 -93 R
+62 0 V
+-62 93 R
+62 0 V
+25 -293 R
+0 361 V
+3279 692 M
+62 0 V
+-62 361 R
+62 0 V
+25 -424 R
+0 228 V
+3335 629 M
+62 0 V
+-62 228 R
+62 0 V
+24 -127 R
+0 143 V
+3390 730 M
+62 0 V
+-62 143 R
+62 0 V
+25 -283 R
+0 218 V
+3446 590 M
+62 0 V
+-62 218 R
+62 0 V
+25 -223 R
+0 137 V
+3502 585 M
+62 0 V
+-62 137 R
+62 0 V
+25 -82 R
+0 189 V
+3558 640 M
+62 0 V
+-62 189 R
+62 0 V
+24 -177 R
+0 125 V
+3613 652 M
+62 0 V
+-62 125 R
+62 0 V
+25 -73 R
+0 101 V
+3669 704 M
+62 0 V
+-62 101 R
+62 0 V
+25 -121 R
+0 179 V
+3725 684 M
+62 0 V
+-62 179 R
+62 0 V
+24 -21 R
+0 124 V
+stroke 3811 966 M
+3780 842 M
+62 0 V
+-62 124 R
+62 0 V
+25 -90 R
+0 173 V
+3836 876 M
+62 0 V
+-62 173 R
+62 0 V
+25 27 R
+0 184 V
+-31 -184 R
+62 0 V
+-62 184 R
+62 0 V
+25 -157 R
+0 259 V
+-31 -259 R
+62 0 V
+-62 259 R
+62 0 V
+24 -124 R
+0 351 V
+-31 -351 R
+62 0 V
+-62 351 R
+62 0 V
+25 -119 R
+0 260 V
+-31 -260 R
+62 0 V
+-62 260 R
+62 0 V
+25 -120 R
+0 291 V
+-31 -291 R
+62 0 V
+-62 291 R
+62 0 V
+25 -187 R
+0 215 V
+-31 -215 R
+62 0 V
+-62 215 R
+62 0 V
+24 -3 R
+0 218 V
+-31 -218 R
+62 0 V
+-62 218 R
+62 0 V
+25 8 R
+0 137 V
+-31 -137 R
+62 0 V
+-62 137 R
+62 0 V
+25 97 R
+0 151 V
+-31 -151 R
+62 0 V
+-62 151 R
+62 0 V
+25 16 R
+0 177 V
+-31 -177 R
+62 0 V
+-62 177 R
+62 0 V
+24 -61 R
+0 279 V
+-31 -279 R
+62 0 V
+-62 279 R
+62 0 V
+25 4 R
+0 163 V
+-31 -163 R
+62 0 V
+-62 163 R
+62 0 V
+25 -122 R
+0 217 V
+-31 -217 R
+62 0 V
+-62 217 R
+62 0 V
+25 77 R
+0 128 V
+-31 -128 R
+62 0 V
+-62 128 R
+62 0 V
+24 -82 R
+0 268 V
+-31 -268 R
+62 0 V
+-62 268 R
+62 0 V
+25 1 R
+0 59 V
+-31 -59 R
+62 0 V
+stroke 4790 3602 M
+-62 59 R
+62 0 V
+25 -33 R
+0 185 V
+-31 -185 R
+62 0 V
+-62 185 R
+62 0 V
+25 -4 R
+0 208 V
+-31 -208 R
+62 0 V
+-62 208 R
+62 0 V
+24 -50 R
+0 115 V
+-31 -115 R
+62 0 V
+-62 115 R
+62 0 V
+25 -12 R
+0 232 V
+-31 -232 R
+62 0 V
+-62 232 R
+62 0 V
+25 -167 R
+0 167 V
+-31 -167 R
+62 0 V
+-62 167 R
+62 0 V
+25 -81 R
+0 128 V
+-31 -128 R
+62 0 V
+-62 128 R
+62 0 V
+24 -21 R
+0 92 V
+-31 -92 R
+62 0 V
+-62 92 R
+62 0 V
+25 -35 R
+0 82 V
+-31 -82 R
+62 0 V
+-62 82 R
+62 0 V
+25 -119 R
+0 135 V
+-31 -135 R
+62 0 V
+-62 135 R
+62 0 V
+24 -213 R
+0 271 V
+-31 -271 R
+62 0 V
+-62 271 R
+62 0 V
+25 -231 R
+0 202 V
+-31 -202 R
+62 0 V
+-62 202 R
+62 0 V
+25 -137 R
+0 72 V
+-31 -72 R
+62 0 V
+-62 72 R
+62 0 V
+25 -265 R
+0 273 V
+-31 -273 R
+62 0 V
+-62 273 R
+62 0 V
+24 -327 R
+0 175 V
+-31 -175 R
+62 0 V
+-62 175 R
+62 0 V
+25 -297 R
+0 338 V
+-31 -338 R
+62 0 V
+-62 338 R
+62 0 V
+25 -310 R
+0 216 V
+-31 -216 R
+62 0 V
+-62 216 R
+62 0 V
+25 -438 R
+0 274 V
+-31 -274 R
+62 0 V
+-62 274 R
+62 0 V
+stroke 5738 4086 M
+24 -279 R
+0 91 V
+-31 -91 R
+62 0 V
+-62 91 R
+62 0 V
+25 -348 R
+0 217 V
+-31 -217 R
+62 0 V
+-62 217 R
+62 0 V
+25 -302 R
+0 159 V
+-31 -159 R
+62 0 V
+-62 159 R
+62 0 V
+25 -316 R
+0 52 V
+-31 -52 R
+62 0 V
+-62 52 R
+62 0 V
+24 -346 R
+0 241 V
+-31 -241 R
+62 0 V
+-62 241 R
+62 0 V
+25 -277 R
+0 117 V
+-31 -117 R
+62 0 V
+-62 117 R
+62 0 V
+25 -378 R
+0 131 V
+-31 -131 R
+62 0 V
+-62 131 R
+62 0 V
+25 -379 R
+0 177 V
+-31 -177 R
+62 0 V
+-62 177 R
+62 0 V
+24 -250 R
+0 196 V
+-31 -196 R
+62 0 V
+-62 196 R
+62 0 V
+25 -374 R
+0 107 V
+-31 -107 R
+62 0 V
+-62 107 R
+62 0 V
+25 -414 R
+0 261 V
+-31 -261 R
+62 0 V
+-62 261 R
+62 0 V
+25 -352 R
+0 251 V
+-31 -251 R
+62 0 V
+-62 251 R
+62 0 V
+24 -475 R
+0 247 V
+-31 -247 R
+62 0 V
+-62 247 R
+62 0 V
+25 -281 R
+0 60 V
+-31 -60 R
+62 0 V
+-62 60 R
+62 0 V
+913 2582 Pls
+969 2768 Pls
+1024 2952 Pls
+1080 3133 Pls
+1136 3308 Pls
+1192 3475 Pls
+1247 3634 Pls
+1303 3783 Pls
+1359 3919 Pls
+1415 4042 Pls
+1470 4150 Pls
+1526 4243 Pls
+1582 4319 Pls
+1638 4378 Pls
+1693 4419 Pls
+1749 4441 Pls
+1805 4445 Pls
+1861 4430 Pls
+1916 4397 Pls
+1972 4346 Pls
+2028 4277 Pls
+2084 4191 Pls
+2139 4089 Pls
+2195 3972 Pls
+2251 3841 Pls
+2307 3697 Pls
+2362 3543 Pls
+2418 3378 Pls
+2474 3206 Pls
+2529 3028 Pls
+2585 2845 Pls
+2641 2659 Pls
+2697 2473 Pls
+2752 2288 Pls
+2808 2106 Pls
+2864 1928 Pls
+2920 1757 Pls
+2975 1595 Pls
+3031 1442 Pls
+3087 1300 Pls
+3143 1172 Pls
+3198 1057 Pls
+3254 958 Pls
+3310 875 Pls
+3366 809 Pls
+3421 760 Pls
+3477 730 Pls
+3533 719 Pls
+3589 726 Pls
+3644 751 Pls
+3700 795 Pls
+3756 857 Pls
+3811 936 Pls
+3867 1031 Pls
+3923 1142 Pls
+3979 1267 Pls
+4034 1406 Pls
+4090 1556 Pls
+4146 1716 Pls
+4202 1885 Pls
+4257 2061 Pls
+4313 2243 Pls
+4369 2427 Pls
+4425 2613 Pls
+4480 2799 Pls
+4536 2983 Pls
+4592 3163 Pls
+4648 3336 Pls
+4703 3503 Pls
+4759 3660 Pls
+4815 3806 Pls
+4871 3941 Pls
+4926 4061 Pls
+4982 4167 Pls
+5038 4257 Pls
+5094 4330 Pls
+5149 4386 Pls
+5205 4424 Pls
+5261 4443 Pls
+5316 4444 Pls
+5372 4426 Pls
+5428 4390 Pls
+5484 4335 Pls
+5539 4263 Pls
+5595 4175 Pls
+5651 4070 Pls
+5707 3951 Pls
+5762 3818 Pls
+5818 3672 Pls
+5874 3516 Pls
+5930 3350 Pls
+5985 3177 Pls
+6041 2997 Pls
+6097 2814 Pls
+6153 2628 Pls
+6208 2442 Pls
+6264 2257 Pls
+6320 2076 Pls
+6376 1899 Pls
+6431 1729 Pls
+6487 1568 Pls
+% End plot #1
+% Begin plot #2
+0.500 UL
+LT1
+0.00 0.00 1.00 C 913 2582 M
+56 186 V
+55 184 V
+56 181 V
+56 175 V
+56 167 V
+55 159 V
+56 149 V
+56 136 V
+56 123 V
+55 108 V
+56 93 V
+56 76 V
+56 59 V
+55 41 V
+56 22 V
+56 4 V
+56 -15 V
+55 -33 V
+56 -51 V
+56 -69 V
+56 -86 V
+55 -102 V
+56 -117 V
+56 -131 V
+56 -144 V
+55 -154 V
+56 -165 V
+56 -172 V
+55 -178 V
+56 -183 V
+56 -186 V
+56 -186 V
+55 -185 V
+56 -182 V
+56 -178 V
+56 -171 V
+55 -162 V
+56 -153 V
+56 -142 V
+56 -128 V
+55 -115 V
+56 -99 V
+56 -83 V
+56 -66 V
+55 -49 V
+56 -30 V
+56 -11 V
+56 7 V
+55 25 V
+56 44 V
+56 62 V
+55 79 V
+56 95 V
+56 111 V
+56 125 V
+55 139 V
+56 150 V
+56 160 V
+56 169 V
+55 176 V
+56 182 V
+56 184 V
+56 186 V
+55 186 V
+56 184 V
+56 180 V
+56 173 V
+55 167 V
+56 157 V
+56 146 V
+56 135 V
+55 120 V
+56 106 V
+56 90 V
+56 73 V
+55 56 V
+56 38 V
+56 19 V
+55 1 V
+56 -18 V
+56 -36 V
+56 -55 V
+55 -72 V
+56 -88 V
+56 -105 V
+56 -119 V
+55 -133 V
+56 -146 V
+56 -156 V
+56 -166 V
+55 -173 V
+56 -180 V
+56 -183 V
+56 -186 V
+55 -186 V
+56 -185 V
+56 -181 V
+56 -177 V
+55 -170 V
+56 -161 V
+% End plot #2
+stroke
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/errorbar.pdf b/doc/interpreter/errorbar.pdf
new file mode 100644
index 0000000..ea4a741
Binary files /dev/null and b/doc/interpreter/errorbar.pdf differ
diff --git a/doc/interpreter/errorbar.png b/doc/interpreter/errorbar.png
new file mode 100644
index 0000000..cf320fa
Binary files /dev/null and b/doc/interpreter/errorbar.png differ
diff --git a/doc/interpreter/errorbar.txt b/doc/interpreter/errorbar.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/errorbar.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/errors.texi b/doc/interpreter/errors.texi
new file mode 100644
index 0000000..0509adb
--- /dev/null
+++ b/doc/interpreter/errors.texi
@@ -0,0 +1,748 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Errors and Warnings
+ at chapter Errors and Warnings
+
+Octave includes several functions for printing error and warning
+messages.  When you write functions that need to take special action
+when they encounter abnormal conditions, you should print the error
+messages using the functions described in this chapter.
+
+Since many of Octave's functions use these functions, it is also useful
+to understand them, so that errors and warnings can be handled.
+
+ at menu
+* Handling Errors::
+* Handling Warnings::
+ at end menu
+
+ at node Handling Errors
+ at section Handling Errors
+
+An error is something that occurs when a program is in a state where
+it doesn't make sense to continue.  An example is when a function is
+called with too few input arguments.  In this situation the function
+should abort with an error message informing the user of the lacking
+input arguments.
+
+Since an error can occur during the evaluation of a program, it is
+very convenient to be able to detect that an error occurred, so that
+the error can be fixed.  This is possible with the @code{try} statement
+described in @ref{The @code{try} Statement}.
+
+ at menu
+* Raising Errors::
+* Catching Errors::
+ at end menu
+
+ at node Raising Errors
+ at subsection Raising Errors
+
+The most common use of errors is for checking input arguments to
+functions.  The following example calls the @code{error} function if
+the function @code{f} is called without any input arguments.
+
+ at example
+ at group
+function f (arg1)
+  if (nargin == 0)
+    error("not enough input arguments");
+  endif
+endfunction
+ at end group
+ at end example
+
+When the @code{error} function is called, it prints the given message
+and returns to the Octave prompt.  This means that no code following
+a call to @code{error} will be executed.
+
+ at c error.cc
+ at anchor{doc-error}
+ at deftypefn {Built-in Function} {} error (@var{template}, @dots{})
+ at deftypefnx {Built-in Function} {} error (@var{id}, @var{template}, @dots{})
+Format the optional arguments under the control of the template string
+ at var{template} using the same rules as the @code{printf} family of
+functions (@pxref{Formatted Output}) and print the resulting message
+on the @code{stderr} stream.  The message is prefixed by the character
+string @samp{error: }.
+
+Calling @code{error} also sets Octave's internal error state such that
+control will return to the top level without evaluating any more
+commands.  This is useful for aborting from functions or scripts.
+
+If the error message does not end with a new line character, Octave will
+print a traceback of all the function calls leading to the error.  For
+example, given the following function definitions:
+
+ at example
+ at group
+function f () g (); end
+function g () h (); end
+function h () nargin == 1 || error ("nargin != 1"); end
+ at end group
+ at end example
+
+ at noindent
+calling the function @code{f} will result in a list of messages that
+can help you to quickly locate the exact location of the error:
+
+ at example
+ at group
+f ()
+error: nargin != 1
+error: called from:
+error:   error at line -1, column -1
+error:   h at line 1, column 27
+error:   g at line 1, column 15
+error:   f at line 1, column 15
+ at end group
+ at end example
+
+If the error message ends in a new line character, Octave will print the
+message but will not display any traceback messages as it returns
+control to the top level.  For example, modifying the error message
+in the previous example to end in a new line causes Octave to only print
+a single message:
+
+ at example
+ at group
+function h () nargin == 1 || error ("nargin != 1\n"); end
+f ()
+error: nargin != 1
+ at end group
+ at end example
+ at end deftypefn
+
+
+Since it is common to use errors when there is something wrong with
+the input to a function, Octave supports functions to simplify such code.
+When the @code{print_usage} function is called, it reads the help text
+of the function calling @code{print_usage}, and presents a useful error.
+If the help text is written in Texinfo it is possible to present an
+error message that only contains the function prototypes as described
+by the @code{@@deftypefn} parts of the help text.  When the help text
+isn't written in Texinfo, the error message contains the entire help
+message.
+
+Consider the following function.
+ at example
+ at group
+## -*- texinfo -*-
+## @@deftypefn @{Function File@} f (@@var@{arg1@})
+## Function help text goes here at dots{}
+## @@end deftypefn
+function f (arg1)
+  if (nargin == 0)
+    print_usage ();
+  endif
+endfunction
+ at end group
+ at end example
+
+ at noindent
+When it is called with no input arguments it produces the following
+error.
+
+ at example
+ at group
+f ()
+
+ at print{}  error: Invalid call to f.  Correct usage is:
+ at print{}  
+ at print{}   -- Function File: f (ARG1)
+ at print{}  
+ at print{}  
+ at print{}  Additional help for built-in functions and operators is
+ at print{}  available in the on-line version of the manual.  Use the command
+ at print{}  `doc <topic>' to search the manual index.
+ at print{}  
+ at print{}  Help and information about Octave is also available on the WWW
+ at print{}  at http://www.octave.org and via the help@@octave.org
+ at print{}  mailing list.
+ at end group
+ at end example
+
+ at c ./help/print_usage.m
+ at anchor{doc-print_usage}
+ at deftypefn {Function File} {} print_usage ()
+ at deftypefnx{Function File} {} print_usage (@var{name})
+Print the usage message for a function.  When called with no input arguments
+the @code{print_usage} function displays the usage message of the currently
+executing function.
+ at seealso{@ref{doc-help,,help}}
+ at end deftypefn
+
+
+ at c error.cc
+ at anchor{doc-usage}
+ at deftypefn {Built-in Function} {} usage (@var{msg})
+Print the message @var{msg}, prefixed by the string @samp{usage: }, and
+set Octave's internal error state such that control will return to the
+top level without evaluating any more commands.  This is useful for
+aborting from functions.
+
+After @code{usage} is evaluated, Octave will print a traceback of all
+the function calls leading to the usage message.
+
+You should use this function for reporting problems errors that result
+from an improper call to a function, such as calling a function with an
+incorrect number of arguments, or with arguments of the wrong type.  For
+example, most functions distributed with Octave begin with code like
+this
+
+ at example
+ at group
+if (nargin != 2)
+  usage ("foo (a, b)");
+endif
+ at end group
+ at end example
+
+ at noindent
+to check for the proper number of arguments.
+ at end deftypefn
+
+
+ at c ./io/beep.m
+ at anchor{doc-beep}
+ at deftypefn {Function File} {} beep ()
+Produce a beep from the speaker (or visual bell).
+ at seealso{@ref{doc-puts,,puts}, @ref{doc-fputs,,fputs}, @ref{doc-printf,,printf}, @ref{doc-fprintf,,fprintf}}
+ at end deftypefn
+
+
+ at c error.cc
+ at anchor{doc-beep_on_error}
+ at deftypefn {Built-in Function} {@var{val} =} beep_on_error ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} beep_on_error (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to ring the terminal bell before printing an error message.
+ at end deftypefn
+
+
+ at node Catching Errors
+ at subsection Catching Errors
+
+When an error occurs, it can be detected and handled using the
+ at code{try} statement as described in @ref{The @code{try} Statement}.
+As an example, the following piece of code counts the number of errors
+that occurs during a @code{for} loop.
+
+ at example
+ at group
+number_of_errors = 0;
+for n = 1:100
+  try
+    @dots{}
+  catch
+    number_of_errors++;
+  end_try_catch
+endfor
+ at end group
+ at end example
+
+The above example treats all errors the same.  In many situations it
+can however be necessary to discriminate between errors, and take
+different actions depending on the error.  The @code{lasterror}
+function returns a structure containing information about the last
+error that occurred.  As an example, the code above could be changed
+to count the number of errors related to the @samp{*} operator.
+
+ at example
+ at group
+number_of_errors = 0;
+for n = 1:100
+  try
+    @dots{}
+  catch
+    msg = lasterror.message;
+    if (strfind (msg, "operator *"))
+      number_of_errors++;
+    endif
+  end_try_catch
+endfor
+ at end group
+ at end example
+
+ at c error.cc
+ at anchor{doc-lasterror}
+ at deftypefn {Built-in Function} {@var{err} =} lasterror (@var{err})
+ at deftypefnx {Built-in Function} {} lasterror ('reset')
+Returns or sets the last error message.  Called without any arguments
+returns a structure containing the last error message, as well as other
+information related to this error.  The elements of this structure are:
+
+ at table @asis
+ at item 'message'
+The text of the last error message
+ at item 'identifier'
+The message identifier of this error message
+ at item 'stack'
+A structure containing information on where the message occurred.  This might
+be an empty structure if this in the case where this information cannot
+be obtained.  The fields of this structure are:
+
+ at table @asis
+ at item 'file'
+The name of the file where the error occurred
+ at item 'name'
+The name of function in which the error occurred
+ at item 'line'
+The line number at which the error occurred
+ at item 'column'
+An optional field with the column number at which the error occurred
+ at end table
+ at end table
+
+The @var{err} structure may also be passed to @code{lasterror} to set the
+information about the last error.  The only constraint on @var{err} in that
+case is that it is a scalar structure.  Any fields of @var{err} that match
+the above are set to the value passed in @var{err}, while other fields are
+set to their default values.
+
+If @code{lasterror} is called with the argument 'reset', all values take
+their default values.
+ at end deftypefn
+
+
+ at c error.cc
+ at anchor{doc-lasterr}
+ at deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lasterr (@var{msg}, @var{msgid})
+Without any arguments, return the last error message.  With one
+argument, set the last error message to @var{msg}.  With two arguments,
+also set the last message identifier.
+ at end deftypefn
+
+
+When an error has been handled it is possible to raise it again.  This
+can be useful when an error needs to be detected, but the program should
+still abort.  This is possible using the @code{rethrow} function.  The
+previous example can now be changed to count the number of errors
+related to the @samp{*} operator, but still abort if another kind of
+error occurs.
+
+ at example
+ at group
+number_of_errors = 0;
+for n = 1:100
+  try
+    @dots{}
+  catch
+    msg = lasterror.message;
+    if (strfind (msg, "operator *"))
+      number_of_errors++;
+    else
+      rethrow (lasterror);
+    endif
+  end_try_catch
+endfor
+ at end group
+ at end example
+
+ at c error.cc
+ at anchor{doc-rethrow}
+ at deftypefn {Built-in Function} {} rethrow (@var{err})
+Reissues a previous error as defined by @var{err}.  @var{err} is a structure
+that must contain at least the 'message' and 'identifier' fields.  @var{err}
+can also contain a field 'stack' that gives information on the assumed
+location of the error.  Typically @var{err} is returned from
+ at code{lasterror}.
+ at seealso{@ref{doc-lasterror,,lasterror}, @ref{doc-lasterr,,lasterr}, @ref{doc-error,,error}}
+ at end deftypefn
+
+
+ at c FIXME: I have no idea what the rest of the functions are used for...
+
+ at c utils.cc
+ at anchor{doc-errno}
+ at deftypefn {Built-in Function} {@var{err} =} errno ()
+ at deftypefnx {Built-in Function} {@var{err} =} errno (@var{val})
+ at deftypefnx {Built-in Function} {@var{err} =} errno (@var{name})
+Return the current value of the system-dependent variable errno,
+set its value to @var{val} and return the previous value, or return
+the named error code given @var{name} as a character string, or -1
+if @var{name} is not found.
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-errno_list}
+ at deftypefn {Built-in Function} {} errno_list ()
+Return a structure containing the system-dependent errno values.
+ at end deftypefn
+
+
+ at node Handling Warnings
+ at section Handling Warnings
+
+Like an error, a warning is issued when something unexpected happens.
+Unlike an error, a warning doesn't abort the currently running program.
+A simple example of a warning is when a number is divided by zero.  In
+this case Octave will issue a warning and assign the value @code{Inf}
+to the result.
+
+ at example
+ at group
+a = 1/0
+     @print{} warning: division by zero
+     @result{} a = Inf
+ at end group
+ at end example
+
+ at menu
+* Issuing Warnings::
+* Enabling and Disabling Warnings::
+ at end menu
+
+ at node Issuing Warnings
+ at subsection Issuing Warnings
+
+It is possible to issue warnings from any code using the @code{warning}
+function.  In its most simple form, the @code{warning} function takes a
+string describing the warning as its input argument.  As an example,
+the following code controls if the variable @samp{a} is non-negative,
+and if not issues a warning and sets @samp{a} to zero.
+
+ at example
+ at group
+a = -1;
+if (a < 0)
+  warning ("'a' must be non-negative.  Setting 'a' to zero.");
+  a = 0;
+endif
+     @print{} 'a' must be non-negative.  Setting 'a' to zero.
+ at end group
+ at end example
+
+Since warnings aren't fatal to a running program, it is not possible
+to catch a warning using the @code{try} statement or something similar.
+It is however possible to access the last warning as a string using the
+ at code{lastwarn} function.
+
+It is also possible to assign an identification string to a warning.
+If a warning has such an ID the user can enable and disable this warning
+as will be described in the next section.  To assign an ID to a warning,
+simply call @code{warning} with two string arguments, where the first
+is the identification string, and the second is the actual warning.
+
+ at c error.cc
+ at anchor{doc-warning}
+ at deftypefn {Built-in Function} {} warning (@var{template}, @dots{})
+ at deftypefnx {Built-in Function} {} warning (@var{id}, @var{template}, @dots{})
+Format the optional arguments under the control of the template string
+ at var{template} using the same rules as the @code{printf} family of
+functions (@pxref{Formatted Output}) and print the resulting message
+on the @code{stderr} stream.  The message is prefixed by the character
+string @samp{warning: }.
+You should use this function when you want to notify the user
+of an unusual condition, but only when it makes sense for your program
+to go on.
+
+The optional message identifier allows users to enable or disable
+warnings tagged by @var{id}.  The special identifier @samp{"all"} may
+be used to set the state of all warnings.
+
+ at deftypefnx {Built-in Function} {} warning ("on", @var{id})
+ at deftypefnx {Built-in Function} {} warning ("off", @var{id})
+ at deftypefnx {Built-in Function} {} warning ("error", @var{id})
+ at deftypefnx {Built-in Function} {} warning ("query", @var{id})
+Set or query the state of a particular warning using the identifier
+ at var{id}.  If the identifier is omitted, a value of @samp{"all"} is
+assumed.  If you set the state of a warning to @samp{"error"}, the
+warning named by @var{id} is handled as if it were an error instead.
+ at seealso{@ref{doc-warning_ids,,warning_ids}}
+ at end deftypefn
+
+
+ at c error.cc
+ at anchor{doc-lastwarn}
+ at deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lastwarn (@var{msg}, @var{msgid})
+Without any arguments, return the last warning message.  With one
+argument, set the last warning message to @var{msg}.  With two arguments,
+also set the last message identifier.
+ at end deftypefn
+
+
+ at node Enabling and Disabling Warnings
+ at subsection Enabling and Disabling Warnings
+
+The @code{warning} function also allows you to control which warnings
+are actually printed to the screen.  If the @code{warning} function
+is called with a string argument that is either @code{"on"} or @code{"off"}
+all warnings will be enabled or disabled.
+
+It is also possible to enable and disable individual warnings through
+their string identifications.  The following code will issue a warning
+
+ at example
+ at group
+warning ("non-negative-variable", 
+         "'a' must be non-negative.  Setting 'a' to zero.");
+ at end group
+ at end example
+
+ at noindent
+while the following won't issue a warning
+
+ at example
+ at group
+warning ("off", "non-negative-variable");
+warning ("non-negative-variable", 
+         "'a' must be non-negative.  Setting 'a' to zero.");
+ at end group
+ at end example
+
+The functions distributed with Octave can issue one of the following
+warnings.
+
+ at c ./miscellaneous/warning_ids.m
+ at anchor{doc-warning_ids}
+ at table @code
+ at item Octave:array-to-scalar
+If the @code{Octave:array-to-scalar} warning is enabled, Octave will
+warn when an implicit conversion from an array to a scalar value is
+attempted.  By default, the @code{Octave:array-to-scalar} warning is
+disabled.
+
+ at item Octave:array-to-vector
+If the @code{Octave:array-to-vector} warning is enabled, Octave will
+warn when an implicit conversion from an array to a vector value is
+attempted.  By default, the @code{Octave:array-to-vector} warning is
+disabled.
+
+ at item Octave:assign-as-truth-value
+If the @code{Octave:assign-as-truth-value} warning is
+enabled, a warning is issued for statements like
+
+ at example
+ at group
+if (s = t)
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+since such statements are not common, and it is likely that the intent
+was to write
+
+ at example
+ at group
+if (s == t)
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+instead.
+
+There are times when it is useful to write code that contains
+assignments within the condition of a @code{while} or @code{if}
+statement.  For example, statements like
+
+ at example
+ at group
+while (c = getc())
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+are common in C programming.
+
+It is possible to avoid all warnings about such statements by
+disabling the @code{Octave:assign-as-truth-value} warning,
+but that may also let real errors like
+
+ at example
+ at group
+if (x = 1)  # intended to test (x == 1)!
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+slip by.
+
+In such cases, it is possible suppress errors for specific statements by
+writing them with an extra set of parentheses.  For example, writing the
+previous example as
+
+ at example
+ at group
+while ((c = getc()))
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+will prevent the warning from being printed for this statement, while
+allowing Octave to warn about other assignments used in conditional
+contexts.
+
+By default, the @code{Octave:assign-as-truth-value} warning is enabled.
+
+ at item Octave:associativity-change
+If the @code{Octave:associativity-change} warning is
+enabled, Octave will warn about possible changes in the meaning of
+some code due to changes in associativity for some operators.
+Associativity changes have typically been made for @sc{matlab}
+compatibility.  By default, the @code{Octave:associativity-change}
+warning is enabled.
+
+ at item Octave:divide-by-zero
+If the @code{Octave:divide-by-zero} warning is enabled, a
+warning is issued when Octave encounters a division by zero.  By
+default, the @code{Octave:divide-by-zero} warning is enabled.
+
+ at item Octave:empty-list-elements
+If the @code{Octave:empty-list-elements} warning is enabled, a
+warning is issued when an empty matrix is found in a matrix list.
+For example,
+
+ at example
+a = [1, [], 3, [], 5]
+ at end example
+
+ at noindent
+By default, the @code{Octave:empty-list-elements} warning is enabled.
+
+ at item Octave:fortran-indexing
+If the @code{Octave:fortran-indexing} warning is enabled, a warning is
+printed for expressions which select elements of a two-dimensional matrix
+using a single index.  By default, the @code{Octave:fortran-indexing}
+warning is disabled.
+
+ at item Octave:function-name-clash
+If the @code{Octave:function-name-clash} warning is enabled, a
+warning is issued when Octave finds that the name of a function
+defined in a function file differs from the name of the file.  (If
+the names disagree, the name declared inside the file is ignored.)
+By default, the @code{Octave:function-name-clash} warning is enabled.
+
+ at item Octave:future-time-stamp
+If the @code{Octave:future-time-stamp} warning is enabled, Octave
+will print a warning if it finds a function file with a time stamp
+that is in the future.  By default, the
+ at code{Octave:future-time-stamp} warning is enabled.
+
+ at item Octave:imag-to-real
+If the @code{Octave:imag-to-real} warning is enabled, a warning is
+printed for implicit conversions of complex numbers to real numbers.
+By default, the @code{Octave:imag-to-real} warning is disabled.
+
+ at item Octave:matlab-incompatible
+Print warnings for Octave language features that may cause
+compatibility problems with @sc{matlab}.
+
+ at item Octave:missing-semicolon
+If the @code{Octave:missing-semicolon} warning is enabled, Octave
+will warn when statements in function definitions don't end in
+semicolons.  By default the @code{Octave:missing-semicolon} warning
+is disabled.
+
+ at item Octave:neg-dim-as-zero
+If the @code{Octave:neg-dim-as-zero} warning is enabled, print a warning
+for expressions like
+
+ at example
+eye (-1)
+ at end example
+
+ at noindent
+By default, the @code{Octave:neg-dim-as-zero} warning is disabled.
+
+ at item Octave:num-to-str
+If the @code{Octave:num-to-str} warning is enable, a warning is
+printed for implicit conversions of numbers to their ASCII character
+equivalents when strings are constructed using a mixture of strings and
+numbers in matrix notation.  For example,
+
+ at example
+ at group
+[ "f", 111, 111 ]
+     @result{} "foo"
+ at end group
+ at end example
+elicits a warning if the @code{Octave:num-to-str} warning is
+enabled.  By default, the @code{Octave:num-to-str} warning is enabled.
+
+ at item Octave:precedence-change
+If the @code{Octave:precedence-change} warning is enabled, Octave
+will warn about possible changes in the meaning of some code due to
+changes in precedence for some operators.  Precedence changes have
+typically been made for @sc{matlab} compatibility.  By default, the
+ at code{Octave:precedence-change} warning is enabled.
+
+ at item Octave:reload-forces-clear
+If several functions have been loaded from the same file, Octave must
+clear all the functions before any one of them can be reloaded.  If
+the @code{Octave:reload-forces-clear} warning is enabled, Octave will
+warn you when this happens, and print a list of the additional
+functions that it is forced to clear.  By default, the
+ at code{Octave:reload-forces-clear} warning is enabled.
+
+ at item Octave:resize-on-range-error
+If the @code{Octave:resize-on-range-error} warning is enabled, print a
+warning when a matrix is resized by an indexed assignment with
+indices outside the current bounds.  By default, the
+ at code{Octave:resize-on-range-error} warning is disabled.
+
+ at item Octave:separator-insert
+Print warning if commas or semicolons might be inserted
+automatically in literal matrices.
+
+ at item Octave:single-quote-string
+Print warning if a single quote character is used to introduce a
+string constant.
+
+ at item Octave:str-to-num
+If the @code{Octave:str-to-num} warning is enabled, a warning is printed
+for implicit conversions of strings to their numeric ASCII equivalents.
+For example,
+ at example
+ at group
+"abc" + 0
+     @result{} 97 98 99
+ at end group
+ at end example
+elicits a warning if the @code{Octave:str-to-num} warning is enabled.
+By default, the @code{Octave:str-to-num} warning is disabled.
+
+ at item Octave:string-concat
+If the @code{Octave:string-concat} warning is enabled, print a
+warning when concatenating a mixture of double and single quoted strings.
+By default, the @code{Octave:string-concat} warning is disabled.
+
+ at item Octave:undefined-return-values
+If the @code{Octave:undefined-return-values} warning is disabled,
+print a warning if a function does not define all the values in
+the return list which are expected.  By default, the
+ at code{Octave:undefined-return-values} warning is enabled.
+
+ at item Octave:variable-switch-label
+If the @code{Octave:variable-switch-label} warning is enabled, Octave
+will print a warning if a switch label is not a constant or constant
+expression.  By default, the @code{Octave:variable-switch-label}
+warning is disabled.
+ at end table
+
+
+
diff --git a/doc/interpreter/errors.txi b/doc/interpreter/errors.txi
new file mode 100644
index 0000000..fbb5139
--- /dev/null
+++ b/doc/interpreter/errors.txi
@@ -0,0 +1,305 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Errors and Warnings
+ at chapter Errors and Warnings
+
+Octave includes several functions for printing error and warning
+messages.  When you write functions that need to take special action
+when they encounter abnormal conditions, you should print the error
+messages using the functions described in this chapter.
+
+Since many of Octave's functions use these functions, it is also useful
+to understand them, so that errors and warnings can be handled.
+
+ at menu
+* Handling Errors::
+* Handling Warnings::
+ at end menu
+
+ at node Handling Errors
+ at section Handling Errors
+
+An error is something that occurs when a program is in a state where
+it doesn't make sense to continue.  An example is when a function is
+called with too few input arguments.  In this situation the function
+should abort with an error message informing the user of the lacking
+input arguments.
+
+Since an error can occur during the evaluation of a program, it is
+very convenient to be able to detect that an error occurred, so that
+the error can be fixed.  This is possible with the @code{try} statement
+described in @ref{The @code{try} Statement}.
+
+ at menu
+* Raising Errors::
+* Catching Errors::
+ at end menu
+
+ at node Raising Errors
+ at subsection Raising Errors
+
+The most common use of errors is for checking input arguments to
+functions.  The following example calls the @code{error} function if
+the function @code{f} is called without any input arguments.
+
+ at example
+ at group
+function f (arg1)
+  if (nargin == 0)
+    error("not enough input arguments");
+  endif
+endfunction
+ at end group
+ at end example
+
+When the @code{error} function is called, it prints the given message
+and returns to the Octave prompt.  This means that no code following
+a call to @code{error} will be executed.
+
+ at DOCSTRING(error)
+
+Since it is common to use errors when there is something wrong with
+the input to a function, Octave supports functions to simplify such code.
+When the @code{print_usage} function is called, it reads the help text
+of the function calling @code{print_usage}, and presents a useful error.
+If the help text is written in Texinfo it is possible to present an
+error message that only contains the function prototypes as described
+by the @code{@@deftypefn} parts of the help text.  When the help text
+isn't written in Texinfo, the error message contains the entire help
+message.
+
+Consider the following function.
+ at example
+ at group
+## -*- texinfo -*-
+## @@deftypefn @{Function File@} f (@@var@{arg1@})
+## Function help text goes here at dots{}
+## @@end deftypefn
+function f (arg1)
+  if (nargin == 0)
+    print_usage ();
+  endif
+endfunction
+ at end group
+ at end example
+
+ at noindent
+When it is called with no input arguments it produces the following
+error.
+
+ at example
+ at group
+f ()
+
+ at print{}  error: Invalid call to f.  Correct usage is:
+ at print{}  
+ at print{}   -- Function File: f (ARG1)
+ at print{}  
+ at print{}  
+ at print{}  Additional help for built-in functions and operators is
+ at print{}  available in the on-line version of the manual.  Use the command
+ at print{}  `doc <topic>' to search the manual index.
+ at print{}  
+ at print{}  Help and information about Octave is also available on the WWW
+ at print{}  at http://www.octave.org and via the help@@octave.org
+ at print{}  mailing list.
+ at end group
+ at end example
+
+ at DOCSTRING(print_usage)
+
+ at DOCSTRING(usage)
+
+ at DOCSTRING(beep)
+
+ at DOCSTRING(beep_on_error)
+
+ at node Catching Errors
+ at subsection Catching Errors
+
+When an error occurs, it can be detected and handled using the
+ at code{try} statement as described in @ref{The @code{try} Statement}.
+As an example, the following piece of code counts the number of errors
+that occurs during a @code{for} loop.
+
+ at example
+ at group
+number_of_errors = 0;
+for n = 1:100
+  try
+    @dots{}
+  catch
+    number_of_errors++;
+  end_try_catch
+endfor
+ at end group
+ at end example
+
+The above example treats all errors the same.  In many situations it
+can however be necessary to discriminate between errors, and take
+different actions depending on the error.  The @code{lasterror}
+function returns a structure containing information about the last
+error that occurred.  As an example, the code above could be changed
+to count the number of errors related to the @samp{*} operator.
+
+ at example
+ at group
+number_of_errors = 0;
+for n = 1:100
+  try
+    @dots{}
+  catch
+    msg = lasterror.message;
+    if (strfind (msg, "operator *"))
+      number_of_errors++;
+    endif
+  end_try_catch
+endfor
+ at end group
+ at end example
+
+ at DOCSTRING(lasterror)
+
+ at DOCSTRING(lasterr)
+
+When an error has been handled it is possible to raise it again.  This
+can be useful when an error needs to be detected, but the program should
+still abort.  This is possible using the @code{rethrow} function.  The
+previous example can now be changed to count the number of errors
+related to the @samp{*} operator, but still abort if another kind of
+error occurs.
+
+ at example
+ at group
+number_of_errors = 0;
+for n = 1:100
+  try
+    @dots{}
+  catch
+    msg = lasterror.message;
+    if (strfind (msg, "operator *"))
+      number_of_errors++;
+    else
+      rethrow (lasterror);
+    endif
+  end_try_catch
+endfor
+ at end group
+ at end example
+
+ at DOCSTRING(rethrow)
+
+ at c FIXME: I have no idea what the rest of the functions are used for...
+
+ at DOCSTRING(errno)
+
+ at DOCSTRING(errno_list)
+
+ at node Handling Warnings
+ at section Handling Warnings
+
+Like an error, a warning is issued when something unexpected happens.
+Unlike an error, a warning doesn't abort the currently running program.
+A simple example of a warning is when a number is divided by zero.  In
+this case Octave will issue a warning and assign the value @code{Inf}
+to the result.
+
+ at example
+ at group
+a = 1/0
+     @print{} warning: division by zero
+     @result{} a = Inf
+ at end group
+ at end example
+
+ at menu
+* Issuing Warnings::
+* Enabling and Disabling Warnings::
+ at end menu
+
+ at node Issuing Warnings
+ at subsection Issuing Warnings
+
+It is possible to issue warnings from any code using the @code{warning}
+function.  In its most simple form, the @code{warning} function takes a
+string describing the warning as its input argument.  As an example,
+the following code controls if the variable @samp{a} is non-negative,
+and if not issues a warning and sets @samp{a} to zero.
+
+ at example
+ at group
+a = -1;
+if (a < 0)
+  warning ("'a' must be non-negative.  Setting 'a' to zero.");
+  a = 0;
+endif
+     @print{} 'a' must be non-negative.  Setting 'a' to zero.
+ at end group
+ at end example
+
+Since warnings aren't fatal to a running program, it is not possible
+to catch a warning using the @code{try} statement or something similar.
+It is however possible to access the last warning as a string using the
+ at code{lastwarn} function.
+
+It is also possible to assign an identification string to a warning.
+If a warning has such an ID the user can enable and disable this warning
+as will be described in the next section.  To assign an ID to a warning,
+simply call @code{warning} with two string arguments, where the first
+is the identification string, and the second is the actual warning.
+
+ at DOCSTRING(warning)
+
+ at DOCSTRING(lastwarn)
+
+ at node Enabling and Disabling Warnings
+ at subsection Enabling and Disabling Warnings
+
+The @code{warning} function also allows you to control which warnings
+are actually printed to the screen.  If the @code{warning} function
+is called with a string argument that is either @code{"on"} or @code{"off"}
+all warnings will be enabled or disabled.
+
+It is also possible to enable and disable individual warnings through
+their string identifications.  The following code will issue a warning
+
+ at example
+ at group
+warning ("non-negative-variable", 
+         "'a' must be non-negative.  Setting 'a' to zero.");
+ at end group
+ at end example
+
+ at noindent
+while the following won't issue a warning
+
+ at example
+ at group
+warning ("off", "non-negative-variable");
+warning ("non-negative-variable", 
+         "'a' must be non-negative.  Setting 'a' to zero.");
+ at end group
+ at end example
+
+The functions distributed with Octave can issue one of the following
+warnings.
+
+ at DOCSTRING(warning_ids)
+
+
diff --git a/doc/interpreter/eval.texi b/doc/interpreter/eval.texi
new file mode 100644
index 0000000..f287767
--- /dev/null
+++ b/doc/interpreter/eval.texi
@@ -0,0 +1,256 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Evaluation
+ at chapter Evaluation
+
+Normally, you evaluate expressions simply by typing them at the Octave
+prompt, or by asking Octave to interpret commands that you have saved in
+a file.
+
+Sometimes, you may find it necessary to evaluate an expression that has
+been computed and stored in a string, which is exactly what the
+ at code{eval} function lets you do.
+
+ at c parse.cc
+ at anchor{doc-eval}
+ at deftypefn {Built-in Function} {} eval (@var{try}, @var{catch})
+Parse the string @var{try} and evaluate it as if it were an Octave
+program.  If that fails, evaluate the optional string @var{catch}.
+The string @var{try} is evaluated in the current context,
+so any results remain available after @code{eval} returns.
+
+The following example makes the variable @var{a} with the approximate
+value 3.1416 available.
+
+ at example
+eval("a = acos(-1);");
+ at end example
+
+If an error occurs during the evaluation of @var{try} the @var{catch}
+string is evaluated, as the following example shows:
+
+ at example
+eval ('error ("This is a bad example");',
+      'printf ("This error occurred:\n%s\n", lasterr ());');
+     @print{} This error occurred:
+        This is a bad example
+ at end example
+ at end deftypefn
+
+
+ at menu
+* Calling a Function by its Name::
+* Evaluation in a Different Context::
+ at end menu
+
+ at node Calling a Function by its Name
+ at section Calling a Function by its Name
+
+The @code{feval} function allows you to call a function from a string
+containing its name.  This is useful when writing a function that needs to
+call user-supplied functions.  The @code{feval} function takes the name
+of the function to call as its first argument, and the remaining 
+arguments are given to the function.
+
+The following example is a simple-minded function using @code{feval}
+that finds the root of a user-supplied function of one variable using
+Newton's method.
+
+ at example
+ at cindex Fordyce, A. P.
+ at findex newtroot
+function result = newtroot (fname, x)
+
+# usage: newtroot (fname, x)
+#
+#   fname : a string naming a function f(x).
+#   x     : initial guess
+
+  delta = tol = sqrt (eps);
+  maxit = 200;
+  fx = feval (fname, x);
+  for i = 1:maxit
+    if (abs (fx) < tol)
+      result = x;
+      return;
+    else
+      fx_new = feval (fname, x + delta);
+      deriv = (fx_new - fx) / delta;
+      x = x - fx / deriv;
+      fx = fx_new;
+    endif
+  endfor
+
+  result = x;
+
+endfunction
+ at end example
+
+Note that this is only meant to be an example of calling user-supplied
+functions and should not be taken too seriously.  In addition to using a
+more robust algorithm, any serious code would check the number and type
+of all the arguments, ensure that the supplied function really was a
+function, etc.  @xref{Predicates for Numeric Objects}, for example,
+for a list of predicates for numeric objects, and see @ref{Status of
+Variables}, for a description of the @code{exist} function.
+
+ at c parse.cc
+ at anchor{doc-feval}
+ at deftypefn {Built-in Function} {} feval (@var{name}, @dots{})
+Evaluate the function named @var{name}.  Any arguments after the first
+are passed on to the named function.  For example,
+
+ at example
+feval ("acos", -1)
+     @result{} 3.1416
+ at end example
+
+ at noindent
+calls the function @code{acos} with the argument @samp{-1}.
+
+The function @code{feval} is necessary in order to be able to write
+functions that call user-supplied functions, because Octave does not
+have a way to declare a pointer to a function (like C) or to declare a
+special kind of variable that can be used to hold the name of a function
+(like @code{EXTERNAL} in Fortran).  Instead, you must refer to functions
+by name, and use @code{feval} to call them.
+ at end deftypefn
+
+
+A similar function @code{run} exists for calling user script files, that
+are not necessarily on the user path
+
+ at c ./miscellaneous/run.m
+ at anchor{doc-run}
+ at deftypefn {Function File} {} run (@var{f})
+ at deftypefnx {Command} {} run @var{f}
+Run scripts in the current workspace that are not necessarily on the
+path.  If @var{f} is the script to run, including its path, then @code{run}
+change the directory to the directory where @var{f} is found.  @code{run}
+then executes the script, and returns to the original directory.
+ at seealso{@ref{doc-system,,system}}
+ at end deftypefn
+
+
+ at node Evaluation in a Different Context
+ at section Evaluation in a Different Context
+
+Before you evaluate an expression you need to substitute
+the values of the variables used in the expression.  These
+are stored in the symbol table.  Whenever the interpreter
+starts a new function it saves the current symbol table
+and creates a new one, initializing it with the list of
+function parameters and a couple of predefined variables
+such as @code{nargin}.  Expressions inside the function use the
+new symbol table.
+
+Sometimes you want to write a function so that when you
+call it, it modifies variables in your own context.  This
+allows you to use a pass-by-name style of function,
+which is similar to using a pointer in programming languages such
+as C.
+
+Consider how you might write @code{save} and @code{load} as
+m-files.  For example,
+
+ at example
+ at group
+function create_data
+  x = linspace (0, 10, 10);
+  y = sin (x);
+  save mydata x y
+endfunction
+ at end group
+ at end example
+
+With @code{evalin}, you could write @code{save} as follows:
+
+ at example
+ at group
+function save (file, name1, name2)
+  f = open_save_file (file);
+  save_var(f, name1, evalin ("caller", name1));
+  save_var(f, name2, evalin ("caller", name2));
+endfunction
+ at end group
+ at end example
+
+ at noindent
+Here, @samp{caller} is the @code{create_data} function and @code{name1}
+is the string @code{"x"}, which evaluates simply as the value of @code{x}.
+
+You later want to load the values back from @code{mydata}
+in a different context:
+
+ at example
+ at group
+function process_data
+  load mydata
+  @dots{} do work @dots{}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+With @code{assignin}, you could write @code{load} as follows:
+
+ at example
+ at group
+function load (file)
+  f = open_load_file (file);
+  [name, val] = load_var (f);
+  assignin ("caller", name, val);
+  [name, val] = load_var (f);
+  assignin ("caller", name, val);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+Here, @samp{caller} is the @code{process_data} function.
+
+You can set and use variables at the command prompt
+using the context @samp{base} rather than @samp{caller}.
+
+These functions are rarely used in practice.  One
+example is the @code{fail (@samp{code}, @samp{pattern})} function
+which evaluates @samp{code} in the caller's context and
+checks that the error message it produces matches
+the given pattern.  Other examples such as @code{save} and @code{load}
+are written in C++ where all Octave variables
+are in the @samp{caller} context and @code{evalin} is not needed.
+
+ at c parse.cc
+ at anchor{doc-evalin}
+ at deftypefn {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})
+Like @code{eval}, except that the expressions are evaluated in the
+context @var{context}, which may be either @code{"caller"} or
+ at code{"base"}.
+ at end deftypefn
+
+
+ at c parse.cc
+ at anchor{doc-assignin}
+ at deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})
+Assign @var{value} to @var{varname} in context @var{context}, which
+may be either @code{"base"} or @code{"caller"}.
+ at end deftypefn
+
diff --git a/doc/interpreter/eval.txi b/doc/interpreter/eval.txi
new file mode 100644
index 0000000..6002ed3
--- /dev/null
+++ b/doc/interpreter/eval.txi
@@ -0,0 +1,185 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Evaluation
+ at chapter Evaluation
+
+Normally, you evaluate expressions simply by typing them at the Octave
+prompt, or by asking Octave to interpret commands that you have saved in
+a file.
+
+Sometimes, you may find it necessary to evaluate an expression that has
+been computed and stored in a string, which is exactly what the
+ at code{eval} function lets you do.
+
+ at DOCSTRING(eval)
+
+ at menu
+* Calling a Function by its Name::
+* Evaluation in a Different Context::
+ at end menu
+
+ at node Calling a Function by its Name
+ at section Calling a Function by its Name
+
+The @code{feval} function allows you to call a function from a string
+containing its name.  This is useful when writing a function that needs to
+call user-supplied functions.  The @code{feval} function takes the name
+of the function to call as its first argument, and the remaining 
+arguments are given to the function.
+
+The following example is a simple-minded function using @code{feval}
+that finds the root of a user-supplied function of one variable using
+Newton's method.
+
+ at example
+ at cindex Fordyce, A. P.
+ at findex newtroot
+function result = newtroot (fname, x)
+
+# usage: newtroot (fname, x)
+#
+#   fname : a string naming a function f(x).
+#   x     : initial guess
+
+  delta = tol = sqrt (eps);
+  maxit = 200;
+  fx = feval (fname, x);
+  for i = 1:maxit
+    if (abs (fx) < tol)
+      result = x;
+      return;
+    else
+      fx_new = feval (fname, x + delta);
+      deriv = (fx_new - fx) / delta;
+      x = x - fx / deriv;
+      fx = fx_new;
+    endif
+  endfor
+
+  result = x;
+
+endfunction
+ at end example
+
+Note that this is only meant to be an example of calling user-supplied
+functions and should not be taken too seriously.  In addition to using a
+more robust algorithm, any serious code would check the number and type
+of all the arguments, ensure that the supplied function really was a
+function, etc.  @xref{Predicates for Numeric Objects}, for example,
+for a list of predicates for numeric objects, and see @ref{Status of
+Variables}, for a description of the @code{exist} function.
+
+ at DOCSTRING(feval)
+
+A similar function @code{run} exists for calling user script files, that
+are not necessarily on the user path
+
+ at DOCSTRING(run)
+
+ at node Evaluation in a Different Context
+ at section Evaluation in a Different Context
+
+Before you evaluate an expression you need to substitute
+the values of the variables used in the expression.  These
+are stored in the symbol table.  Whenever the interpreter
+starts a new function it saves the current symbol table
+and creates a new one, initializing it with the list of
+function parameters and a couple of predefined variables
+such as @code{nargin}.  Expressions inside the function use the
+new symbol table.
+
+Sometimes you want to write a function so that when you
+call it, it modifies variables in your own context.  This
+allows you to use a pass-by-name style of function,
+which is similar to using a pointer in programming languages such
+as C.
+
+Consider how you might write @code{save} and @code{load} as
+m-files.  For example,
+
+ at example
+ at group
+function create_data
+  x = linspace (0, 10, 10);
+  y = sin (x);
+  save mydata x y
+endfunction
+ at end group
+ at end example
+
+With @code{evalin}, you could write @code{save} as follows:
+
+ at example
+ at group
+function save (file, name1, name2)
+  f = open_save_file (file);
+  save_var(f, name1, evalin ("caller", name1));
+  save_var(f, name2, evalin ("caller", name2));
+endfunction
+ at end group
+ at end example
+
+ at noindent
+Here, @samp{caller} is the @code{create_data} function and @code{name1}
+is the string @code{"x"}, which evaluates simply as the value of @code{x}.
+
+You later want to load the values back from @code{mydata}
+in a different context:
+
+ at example
+ at group
+function process_data
+  load mydata
+  @dots{} do work @dots{}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+With @code{assignin}, you could write @code{load} as follows:
+
+ at example
+ at group
+function load (file)
+  f = open_load_file (file);
+  [name, val] = load_var (f);
+  assignin ("caller", name, val);
+  [name, val] = load_var (f);
+  assignin ("caller", name, val);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+Here, @samp{caller} is the @code{process_data} function.
+
+You can set and use variables at the command prompt
+using the context @samp{base} rather than @samp{caller}.
+
+These functions are rarely used in practice.  One
+example is the @code{fail (@samp{code}, @samp{pattern})} function
+which evaluates @samp{code} in the caller's context and
+checks that the error message it produces matches
+the given pattern.  Other examples such as @code{save} and @code{load}
+are written in C++ where all Octave variables
+are in the @samp{caller} context and @code{evalin} is not needed.
+
+ at DOCSTRING(evalin)
+
+ at DOCSTRING(assignin)
diff --git a/doc/interpreter/expr.texi b/doc/interpreter/expr.texi
new file mode 100644
index 0000000..d28d103
--- /dev/null
+++ b/doc/interpreter/expr.texi
@@ -0,0 +1,1225 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2006,
+ at c               2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Expressions
+ at chapter Expressions
+ at cindex expressions
+
+Expressions are the basic building block of statements in Octave.  An
+expression evaluates to a value, which you can print, test, store in a
+variable, pass to a function, or assign a new value to a variable with
+an assignment operator.
+
+An expression can serve as a statement on its own.  Most other kinds of
+statements contain one or more expressions which specify data to be
+operated on.  As in other languages, expressions in Octave include
+variables, array references, constants, and function calls, as well as
+combinations of these with various operators.
+
+ at menu
+* Index Expressions::           
+* Calling Functions::           
+* Arithmetic Ops::              
+* Comparison Ops::              
+* Boolean Expressions::         
+* Assignment Ops::              
+* Increment Ops::               
+* Operator Precedence::         
+ at end menu
+
+ at node Index Expressions
+ at section Index Expressions
+
+ at opindex (
+ at opindex )
+
+An @dfn{index expression} allows you to reference or extract selected
+elements of a matrix or vector.
+
+Indices may be scalars, vectors, ranges, or the special operator
+ at samp{:}, which may be used to select entire rows or columns.
+
+Vectors are indexed using a single index expression.  Matrices may be
+indexed using one or two indices.  When using a single index
+expression, the elements of the matrix are taken in column-first order;
+the dimensions of the output match those of the index expression.  For
+example,
+ at example
+ at group
+a (2)       # a scalar
+a (1:2)     # a row vector
+a ([1; 2])  # a column vector
+ at end group
+ at end example
+
+As a special case, when a colon is used as a single index, the output
+is a column vector containing all the elements of the vector or matrix.
+For example
+ at example
+a (:)       # a column vector
+ at end example
+
+Given the matrix
+
+ at example
+a = [1, 2; 3, 4]
+ at end example
+
+ at noindent
+all of the following expressions are equivalent
+
+ at example
+ at group
+a (1, [1, 2])
+a (1, 1:2)
+a (1, :)
+ at end group
+ at end example
+
+ at noindent
+and select the first row of the matrix.
+
+In general, an array with @samp{n} dimensions can be indexed using @samp{m}
+indices.  If @code{n == m}, each index corresponds to its respective dimension.
+The set of index tuples determining the result is formed by the Cartesian product
+of the index vectors (or ranges or scalars).
+If @code{n < m}, then the array is padded by trailing singleton dimensions.
+If @code{n > m}, the last @code{n-m+1} dimensions are folded into a single
+dimension with extent equal to product of extents of the original dimensions.
+
+ at c FIXED -- sections on variable prefer_zero_one_indexing were removed
+
+Indexing a scalar with a vector of ones can be used to create a
+vector the same size as the index vector, with each element equal to
+the value of the original scalar.  For example, the following statements
+
+ at example
+ at group
+a = 13;
+a (ones (1, 4))
+ at end group
+ at end example
+
+ at noindent
+produce a vector whose four elements are all equal to 13.
+
+Similarly, indexing a scalar with two vectors of ones can be used to
+create a matrix.  For example the following statements
+
+ at example
+ at group
+a = 13;
+a (ones (1, 2), ones (1, 3))
+ at end group
+ at end example
+
+ at noindent
+create a 2 by 3 matrix with all elements equal to 13.
+
+The last example could also be written as
+
+ at example
+ at group
+13 (ones (2, 3))
+ at end group
+ at end example
+
+It should be, noted that @code{ones (1, n)} (a row vector of ones) results in a
+range (with zero increment), and is therefore more efficient when used in index
+expression than other forms of @dfn{ones}.  In particular, when @samp{r} is a row
+vector, the expressions
+
+ at example
+  r(ones (1, n), :)
+ at end example
+
+ at example
+  r(ones (n, 1), :)
+ at end example
+
+will produce identical results, but the first one will be significantly
+faster, at least for @samp{r} and @samp{n} large enough.  The reason is that
+in the first case the index is kept in a compressed form, which allows Octave
+to choose a more efficient algorithm to handle the expression.
+
+In general, for an user unaware of these subtleties, it is best to use
+the function @dfn{repmat} for spreading arrays into bigger ones.
+
+It is also possible to create a matrix with different values.  The
+following example creates a 10 dimensional row vector @math{a} containing
+the values
+ at tex
+$a_i = \sqrt{i}$.
+ at end tex
+ at ifnottex
+a(i) = sqrt(i).
+ at end ifnottex
+
+ at example
+ at group
+for i = 1:10
+  a(i) = sqrt (i);
+endfor
+ at end group
+ at end example
+
+ at noindent
+Note that it is quite inefficient to create a vector using a loop like
+the one shown in the example above.  In this particular case, it would
+have been much more efficient to use the expression
+
+ at example
+a = sqrt (1:10);
+ at end example
+
+ at noindent
+thus avoiding the loop entirely.  In cases where a loop is still
+required, or a number of values must be combined to form a larger
+matrix, it is generally much faster to set the size of the matrix first,
+and then insert elements using indexing commands.  For example, given a
+matrix @code{a},
+
+ at example
+ at group
+[nr, nc] = size (a);
+x = zeros (nr, n * nc);
+for i = 1:n
+  x(:,(i-1)*nc+1:i*nc) = a;
+endfor
+ at end group
+ at end example
+
+ at noindent
+is considerably faster than
+
+ at example
+ at group
+x = a;
+for i = 1:n-1
+  x = [x, a];
+endfor
+ at end group
+ at end example
+
+ at noindent
+particularly for large matrices because Octave does not have to
+repeatedly resize the result.
+
+ at c ./general/sub2ind.m
+ at anchor{doc-sub2ind}
+ at deftypefn {Function File} {@var{ind} =} sub2ind (@var{dims}, @var{i}, @var{j})
+ at deftypefnx {Function File} {@var{ind} =} sub2ind (@var{dims}, @var{s1}, @var{s2}, @dots{}, @var{sN})
+Convert subscripts into a linear index.
+
+The following example shows how to convert the two-dimensional
+index @code{(2,3)} of a 3-by-3 matrix to a linear index.  The matrix
+is linearly indexed moving from one column to next, filling up
+all rows in each column.
+
+ at example
+ at group
+linear_index = sub2ind ([3, 3], 2, 3)
+ at result{} 8
+ at end group
+ at end example
+ at seealso{@ref{doc-ind2sub,,ind2sub}}
+ at end deftypefn
+
+
+ at c ./general/ind2sub.m
+ at anchor{doc-ind2sub}
+ at deftypefn {Function File} {[@var{s1}, @var{s2}, @dots{}, @var{sN}] =} ind2sub (@var{dims}, @var{ind})
+Convert a linear index into subscripts.
+
+The following example shows how to convert the linear index @code{8}
+in a 3-by-3 matrix into a subscript.  The matrix is linearly indexed
+moving from one column to next, filling up all rows in each column.
+ at example
+ at group
+[r, c] = ind2sub ([3, 3], 8)
+ at result{} r =  2
+c =  3
+ at end group
+ at end example
+ at seealso{@ref{doc-sub2ind,,sub2ind}}
+ at end deftypefn
+
+
+ at node Calling Functions
+ at section Calling Functions
+
+A @dfn{function} is a name for a particular calculation.  Because it has
+a name, you can ask for it by name at any point in the program.  For
+example, the function @code{sqrt} computes the square root of a number.
+
+A fixed set of functions are @dfn{built-in}, which means they are
+available in every Octave program.  The @code{sqrt} function is one of
+these.  In addition, you can define your own functions.
+ at xref{Functions and Scripts}, for information about how to do this.
+
+ at cindex arguments in function call
+The way to use a function is with a @dfn{function call} expression,
+which consists of the function name followed by a list of
+ at dfn{arguments} in parentheses.  The arguments are expressions which give
+the raw materials for the calculation that the function will do.  When
+there is more than one argument, they are separated by commas.  If there
+are no arguments, you can omit the parentheses, but it is a good idea to
+include them anyway, to clearly indicate that a function call was
+intended.  Here are some examples:
+
+ at example
+ at group
+sqrt (x^2 + y^2)      # @r{One argument}
+ones (n, m)           # @r{Two arguments}
+rand ()               # @r{No arguments}
+ at end group
+ at end example
+
+Each function expects a particular number of arguments.  For example, the
+ at code{sqrt} function must be called with a single argument, the number
+to take the square root of:
+
+ at example
+sqrt (@var{argument})
+ at end example
+
+Some of the built-in functions take a variable number of arguments,
+depending on the particular usage, and their behavior is different
+depending on the number of arguments supplied.
+
+Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it.  In this
+example, the value of @code{sqrt (@var{argument})} is the square root of
+the argument.  A function can also have side effects, such as assigning
+the values of certain variables or doing input or output operations.
+
+Unlike most languages, functions in Octave may return multiple values.
+For example, the following statement
+
+ at example
+[u, s, v] = svd (a)
+ at end example
+
+ at noindent
+computes the singular value decomposition of the matrix @code{a} and
+assigns the three result matrices to @code{u}, @code{s}, and @code{v}.
+
+The left side of a multiple assignment expression is itself a list of
+expressions, and is allowed to be a list of variable names or index
+expressions.  See also @ref{Index Expressions}, and @ref{Assignment Ops}.
+
+ at menu
+* Call by Value::               
+* Recursion::                   
+ at end menu
+
+ at node Call by Value
+ at subsection Call by Value
+
+In Octave, unlike Fortran, function arguments are passed by value, which
+means that each argument in a function call is evaluated and assigned to
+a temporary location in memory before being passed to the function.
+There is currently no way to specify that a function parameter should be
+passed by reference instead of by value.  This means that it is
+impossible to directly alter the value of a function parameter in the
+calling function.  It can only change the local copy within the function
+body.  For example, the function
+
+ at example
+ at group
+function f (x, n)
+  while (n-- > 0)
+    disp (x);
+  endwhile
+endfunction
+ at end group
+ at end example
+
+ at noindent
+displays the value of the first argument @var{n} times.  In this
+function, the variable @var{n} is used as a temporary variable without
+having to worry that its value might also change in the calling
+function.  Call by value is also useful because it is always possible to
+pass constants for any function parameter without first having to
+determine that the function will not attempt to modify the parameter.
+
+The caller may use a variable as the expression for the argument, but
+the called function does not know this: it only knows what value the
+argument had.  For example, given a function called as
+
+ at example
+ at group
+foo = "bar";
+fcn (foo)
+ at end group
+ at end example
+
+ at noindent
+you should not think of the argument as being ``the variable
+ at code{foo}.''  Instead, think of the argument as the string value,
+ at code{"bar"}.
+
+Even though Octave uses pass-by-value semantics for function arguments,
+values are not copied unnecessarily.  For example,
+
+ at example
+ at group
+x = rand (1000);
+f (x);
+ at end group
+ at end example
+
+ at noindent
+does not actually force two 1000 by 1000 element matrices to exist
+ at emph{unless} the function @code{f} modifies the value of its
+argument.  Then Octave must create a copy to avoid changing the
+value outside the scope of the function @code{f}, or attempting (and
+probably failing!) to modify the value of a constant or the value of a
+temporary result.
+
+ at node Recursion
+ at subsection Recursion
+ at cindex factorial function
+
+With some restrictions at footnote{Some of Octave's functions are
+implemented in terms of functions that cannot be called recursively.
+For example, the ODE solver @code{lsode} is ultimately implemented in a
+Fortran subroutine that cannot be called recursively, so @code{lsode}
+should not be called either directly or indirectly from within the
+user-supplied function that @code{lsode} requires.  Doing so will result
+in an error.}, recursive function calls are allowed.  A
+ at dfn{recursive function} is one which calls itself, either directly or
+indirectly.  For example, here is an inefficient at footnote{It would be
+much better to use @code{prod (1:n)}, or @code{gamma (n+1)} instead,
+after first checking to ensure that the value @code{n} is actually a
+positive integer.} way to compute the factorial of a given integer:
+
+ at example
+ at group
+function retval = fact (n)
+  if (n > 0)
+    retval = n * fact (n-1);
+  else
+    retval = 1;
+  endif
+endfunction
+ at end group
+ at end example
+
+This function is recursive because it calls itself directly.  It
+eventually terminates because each time it calls itself, it uses an
+argument that is one less than was used for the previous call.  Once the
+argument is no longer greater than zero, it does not call itself, and
+the recursion ends.
+
+The built-in variable @code{max_recursion_depth} specifies a limit to
+the recursion depth and prevents Octave from recursing infinitely.
+
+ at c ov-usr-fcn.cc
+ at anchor{doc-max_recursion_depth}
+ at deftypefn {Built-in Function} {@var{val} =} max_recursion_depth ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} max_recursion_depth (@var{new_val})
+Query or set the internal limit on the number of times a function may
+be called recursively.  If the limit is exceeded, an error message is
+printed and control returns to the top level.
+ at end deftypefn
+
+
+ at node Arithmetic Ops
+ at section Arithmetic Operators
+ at cindex arithmetic operators
+ at cindex operators, arithmetic
+ at cindex addition
+ at cindex subtraction
+ at cindex multiplication
+ at cindex matrix multiplication
+ at cindex division
+ at cindex quotient
+ at cindex negation
+ at cindex unary minus
+ at cindex exponentiation
+ at cindex transpose
+ at cindex Hermitian operator
+ at cindex transpose, complex-conjugate
+ at cindex complex-conjugate transpose
+
+The following arithmetic operators are available, and work on scalars
+and matrices.
+
+ at table @code
+ at item @var{x} + @var{y}
+ at opindex +
+Addition.  If both operands are matrices, the number of rows and columns
+must both agree.  If one operand is a scalar, its value is added to
+all the elements of the other operand.
+
+ at item @var{x} .+ @var{y}
+ at opindex .+
+Element by element addition.  This operator is equivalent to @code{+}.
+
+ at item @var{x} - @var{y}
+ at opindex -
+Subtraction.  If both operands are matrices, the number of rows and
+columns of both must agree.
+
+ at item @var{x} .- @var{y}
+Element by element subtraction.  This operator is equivalent to @code{-}.
+
+ at item @var{x} * @var{y}
+ at opindex *
+Matrix multiplication.  The number of columns of @var{x} must agree
+with the number of rows of @var{y}.
+
+ at item @var{x} .* @var{y}
+ at opindex .*
+Element by element multiplication.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+ at item @var{x} / @var{y}
+ at opindex /
+Right division.  This is conceptually equivalent to the expression
+
+ at example
+(inverse (y') * x')'
+ at end example
+
+ at noindent
+but it is computed without forming the inverse of @var{y'}.
+
+If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+ at item @var{x} ./ @var{y}
+ at opindex ./
+Element by element right division.
+
+ at item @var{x} \ @var{y}
+ at opindex \
+Left division.  This is conceptually equivalent to the expression
+
+ at example
+inverse (x) * y
+ at end example
+
+ at noindent
+but it is computed without forming the inverse of @var{x}.
+
+If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+ at item @var{x} .\ @var{y}
+ at opindex .\
+Element by element left division.  Each element of @var{y} is divided
+by each corresponding element of @var{x}.
+
+ at item @var{x} ^ @var{y}
+ at itemx @var{x} ** @var{y}
+ at opindex **
+ at opindex ^
+Power operator.  If @var{x} and @var{y} are both scalars, this operator
+returns @var{x} raised to the power @var{y}.  If @var{x} is a scalar and
+ at var{y} is a square matrix, the result is computed using an eigenvalue
+expansion.  If @var{x} is a square matrix, the result is computed by
+repeated multiplication if @var{y} is an integer, and by an eigenvalue
+expansion if @var{y} is not an integer.  An error results if both
+ at var{x} and @var{y} are matrices.
+
+The implementation of this operator needs to be improved.
+
+ at item @var{x} .^ @var{y}
+ at item @var{x} .** @var{y}
+ at opindex .**
+ at opindex .^
+Element by element power operator.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+ at item - at var{x}
+ at opindex -
+Negation.
+
+ at item + at var{x}
+ at opindex +
+Unary plus.  This operator has no effect on the operand.
+
+ at item @var{x}'
+ at opindex '
+Complex conjugate transpose.  For real arguments, this operator is the
+same as the transpose operator.  For complex arguments, this operator is
+equivalent to the expression
+
+ at example
+conj (x.')
+ at end example
+
+ at item @var{x}.'
+ at opindex .'
+Transpose.
+ at end table
+
+Note that because Octave's element by element operators begin with a
+ at samp{.}, there is a possible ambiguity for statements like
+
+ at example
+1./m
+ at end example
+
+ at noindent
+because the period could be interpreted either as part of the constant
+or as part of the operator.  To resolve this conflict, Octave treats the
+expression as if you had typed
+
+ at example
+(1) ./ m
+ at end example
+
+ at noindent
+and not
+
+ at example
+(1.) / m
+ at end example
+
+ at noindent
+Although this is inconsistent with the normal behavior of Octave's
+lexer, which usually prefers to break the input into tokens by
+preferring the longest possible match at any given point, it is more
+useful in this case.
+
+ at node Comparison Ops
+ at section Comparison Operators
+ at cindex comparison expressions
+ at cindex expressions, comparison
+ at cindex relational operators
+ at cindex operators, relational
+ at cindex less than operator
+ at cindex greater than operator
+ at cindex equality operator
+ at cindex tests for equality
+ at cindex equality, tests for
+
+ at dfn{Comparison operators} compare numeric values for relationships
+such as equality.  They are written using
+ at emph{relational operators}.
+
+All of Octave's comparison operators return a value of 1 if the
+comparison is true, or 0 if it is false.  For matrix values, they all
+work on an element-by-element basis.  For example,
+
+ at example
+ at group
+[1, 2; 3, 4] == [1, 3; 2, 4]
+     @result{}  1  0
+         0  1
+ at end group
+ at end example
+
+If one operand is a scalar and the other is a matrix, the scalar is
+compared to each element of the matrix in turn, and the result is the
+same size as the matrix.
+
+ at table @code
+ at item @var{x} < @var{y}
+ at opindex <
+True if @var{x} is less than @var{y}.
+
+ at item @var{x} <= @var{y}
+ at opindex <=
+True if @var{x} is less than or equal to @var{y}.
+
+ at item @var{x} == @var{y}
+ at opindex ==
+True if @var{x} is equal to @var{y}.
+
+ at item @var{x} >= @var{y}
+ at opindex >=
+True if @var{x} is greater than or equal to @var{y}.
+
+ at item @var{x} > @var{y}
+ at opindex >
+True if @var{x} is greater than @var{y}.
+
+ at item @var{x} != @var{y}
+ at itemx @var{x} ~= @var{y}
+ at opindex !=
+ at opindex ~=
+True if @var{x} is not equal to @var{y}.
+ at end table
+
+String comparisons may also be performed with the @code{strcmp}
+function, not with the comparison operators listed above.
+ at xref{Strings}.
+
+ at c ./general/isequal.m
+ at anchor{doc-isequal}
+ at deftypefn {Function File} {} isequal (@var{x1}, @var{x2}, @dots{})
+Return true if all of @var{x1}, @var{x2}, @dots{} are equal.
+ at seealso{@ref{doc-isequalwithequalnans,,isequalwithequalnans}}
+ at end deftypefn
+
+
+ at c ./general/isequalwithequalnans.m
+ at anchor{doc-isequalwithequalnans}
+ at deftypefn {Function File} {} isequalwithequalnans (@var{x1}, @var{x2}, @dots{})
+Assuming NaN == NaN, return true if all of @var{x1}, @var{x2}, @dots{}
+are equal.
+ at seealso{@ref{doc-isequal,,isequal}}
+ at end deftypefn
+
+
+ at node Boolean Expressions
+ at section Boolean Expressions
+ at cindex expressions, boolean
+ at cindex boolean expressions
+ at cindex expressions, logical
+ at cindex logical expressions
+ at cindex operators, boolean
+ at cindex boolean operators
+ at cindex logical operators
+ at cindex operators, logical
+ at cindex and operator
+ at cindex or operator
+ at cindex not operator
+
+ at menu
+* Element-by-element Boolean Operators::  
+* Short-circuit Boolean Operators::  
+ at end menu
+
+ at node Element-by-element Boolean Operators
+ at subsection Element-by-element Boolean Operators
+ at cindex element-by-element evaluation
+
+An @dfn{element-by-element boolean expression} is a combination of
+comparison expressions using the boolean
+operators ``or'' (@samp{|}), ``and'' (@samp{&}), and ``not'' (@samp{!}),
+along with parentheses to control nesting.  The truth of the boolean
+expression is computed by combining the truth values of the
+corresponding elements of the component expressions.  A value is
+considered to be false if it is zero, and true otherwise.
+
+Element-by-element boolean expressions can be used wherever comparison
+expressions can be used.  They can be used in @code{if} and @code{while}
+statements.  However, a matrix value used as the condition in an
+ at code{if} or @code{while} statement is only true if @emph{all} of its
+elements are nonzero.
+
+Like comparison operations, each element of an element-by-element
+boolean expression also has a numeric value (1 if true, 0 if false) that
+comes into play if the result of the boolean expression is stored in a
+variable, or used in arithmetic.
+
+Here are descriptions of the three element-by-element boolean operators.
+
+ at table @code
+ at item @var{boolean1} & @var{boolean2}
+ at opindex &
+Elements of the result are true if both corresponding elements of
+ at var{boolean1} and @var{boolean2} are true.
+
+ at item @var{boolean1} | @var{boolean2}
+ at opindex |
+Elements of the result are true if either of the corresponding elements
+of @var{boolean1} or @var{boolean2} is true.
+
+ at item ! @var{boolean}
+ at itemx ~ @var{boolean}
+ at opindex ~
+ at opindex !
+Each element of the result is true if the corresponding element of
+ at var{boolean} is false.
+ at end table
+
+For matrix operands, these operators work on an element-by-element
+basis.  For example, the expression
+
+ at example
+[1, 0; 0, 1] & [1, 0; 2, 3]
+ at end example
+
+ at noindent
+returns a two by two identity matrix.
+
+For the binary operators, the dimensions of the operands must conform if
+both are matrices.  If one of the operands is a scalar and the other a
+matrix, the operator is applied to the scalar and each element of the
+matrix.
+
+For the binary element-by-element boolean operators, both subexpressions
+ at var{boolean1} and @var{boolean2} are evaluated before computing the
+result.  This can make a difference when the expressions have side
+effects.  For example, in the expression
+
+ at example
+a & b++
+ at end example
+
+ at noindent
+the value of the variable @var{b} is incremented even if the variable
+ at var{a} is zero.
+
+This behavior is necessary for the boolean operators to work as
+described for matrix-valued operands.
+
+ at node Short-circuit Boolean Operators
+ at subsection Short-circuit Boolean Operators
+ at cindex short-circuit evaluation
+
+Combined with the implicit conversion to scalar values in @code{if} and
+ at code{while} conditions, Octave's element-by-element boolean operators
+are often sufficient for performing most logical operations.  However,
+it is sometimes desirable to stop evaluating a boolean expression as
+soon as the overall truth value can be determined.  Octave's
+ at dfn{short-circuit} boolean operators work this way.
+
+ at table @code
+ at item @var{boolean1} && @var{boolean2}
+ at opindex &&
+The expression @var{boolean1} is evaluated and converted to a scalar
+using the equivalent of the operation @code{all (@var{boolean1}(:))}.
+If it is false, the result of the overall expression is 0.  If it is
+true, the expression @var{boolean2} is evaluated and converted to a
+scalar using the equivalent of the operation @code{all
+(@var{boolean1}(:))}.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+ at strong{Warning:} there is one exception to the rule of evaluating
+ at code{all (@var{boolean1}(:))}, which is when @code{boolean1} is the
+empty matrix.  The truth value of an empty matrix is always @code{false}
+so @code{[] && true} evaluates to @code{false} even though
+ at code{all ([])} is @code{true}.
+
+ at item @var{boolean1} || @var{boolean2}
+ at opindex ||
+The expression @var{boolean1} is evaluated and converted to a scalar
+using the equivalent of the operation @code{all (@var{boolean1}(:))}.
+If it is true, the result of the overall expression is 1.  If it is
+false, the expression @var{boolean2} is evaluated and converted to a
+scalar using the equivalent of the operation @code{all
+(@var{boolean1}(:))}.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+ at strong{Warning:} the truth value of an empty matrix is always @code{false},
+see the previous list item for details.
+ at end table
+
+The fact that both operands may not be evaluated before determining the
+overall truth value of the expression can be important.  For example, in
+the expression
+
+ at example
+a && b++
+ at end example
+
+ at noindent
+the value of the variable @var{b} is only incremented if the variable
+ at var{a} is nonzero.
+
+This can be used to write somewhat more concise code.  For example, it
+is possible write
+
+ at example
+ at group
+function f (a, b, c)
+  if (nargin > 2 && ischar (c))
+    @dots{}
+ at end group
+ at end example
+
+ at noindent
+instead of having to use two @code{if} statements to avoid attempting to
+evaluate an argument that doesn't exist.  For example, without the
+short-circuit feature, it would be necessary to write
+
+ at example
+ at group
+function f (a, b, c)
+  if (nargin > 2)
+    if (ischar (c))
+      @dots{}
+ at end group
+ at end example
+
+ at noindent
+Writing
+
+ at example
+ at group
+function f (a, b, c)
+  if (nargin > 2 & ischar (c))
+    @dots{}
+ at end group
+ at end example
+
+ at noindent
+would result in an error if @code{f} were called with one or two
+arguments because Octave would be forced to try to evaluate both of the
+operands for the operator @samp{&}.
+
+ at node Assignment Ops
+ at section Assignment Expressions
+ at cindex assignment expressions
+ at cindex assignment operators
+ at cindex operators, assignment
+ at cindex expressions, assignment
+
+ at opindex =
+
+An @dfn{assignment} is an expression that stores a new value into a
+variable.  For example, the following expression assigns the value 1 to
+the variable @code{z}:
+
+ at example
+z = 1
+ at end example
+
+ at noindent
+After this expression is executed, the variable @code{z} has the value 1.
+Whatever old value @code{z} had before the assignment is forgotten.
+The @samp{=} sign is called an @dfn{assignment operator}.
+
+Assignments can store string values also.  For example, the following
+expression would store the value @code{"this food is good"} in the
+variable @code{message}:
+
+ at example
+ at group
+thing = "food"
+predicate = "good"
+message = [ "this " , thing , " is " , predicate ]
+ at end group
+ at end example
+
+ at noindent
+(This also illustrates concatenation of strings.)
+
+ at cindex side effect
+Most operators (addition, concatenation, and so on) have no effect
+except to compute a value.  If you ignore the value, you might as well
+not use the operator.  An assignment operator is different.  It does
+produce a value, but even if you ignore the value, the assignment still
+makes itself felt through the alteration of the variable.  We call this
+a @dfn{side effect}.
+
+ at cindex lvalue
+The left-hand operand of an assignment need not be a variable
+(@pxref{Variables}).  It can also be an element of a matrix
+(@pxref{Index Expressions}) or a list of return values
+(@pxref{Calling Functions}).  These are all called @dfn{lvalues}, which
+means they can appear on the left-hand side of an assignment operator.
+The right-hand operand may be any expression.  It produces the new value
+which the assignment stores in the specified variable, matrix element,
+or list of return values.
+
+It is important to note that variables do @emph{not} have permanent types.
+The type of a variable is simply the type of whatever value it happens
+to hold at the moment.  In the following program fragment, the variable
+ at code{foo} has a numeric value at first, and a string value later on:
+
+ at example
+ at group
+octave:13> foo = 1
+foo = 1
+octave:13> foo = "bar"
+foo = bar
+ at end group
+ at end example
+
+ at noindent
+When the second assignment gives @code{foo} a string value, the fact that
+it previously had a numeric value is forgotten.
+
+Assignment of a scalar to an indexed matrix sets all of the elements
+that are referenced by the indices to the scalar value.  For example, if
+ at code{a} is a matrix with at least two columns,
+
+ at example
+ at group
+a(:, 2) = 5
+ at end group
+ at end example
+
+ at noindent
+sets all the elements in the second column of @code{a} to 5.
+
+Assigning an empty matrix @samp{[]} works in most cases to allow you to
+delete rows or columns of matrices and vectors.  @xref{Empty Matrices}.
+For example, given a 4 by 5 matrix @var{A}, the assignment
+
+ at example
+A (3, :) = []
+ at end example
+
+ at noindent
+deletes the third row of @var{A}, and the assignment
+
+ at example
+A (:, 1:2:5) = []
+ at end example
+
+ at noindent
+deletes the first, third, and fifth columns.
+
+An assignment is an expression, so it has a value.  Thus, @code{z = 1}
+as an expression has the value 1.  One consequence of this is that you
+can write multiple assignments together:
+
+ at example
+x = y = z = 0
+ at end example
+
+ at noindent
+stores the value 0 in all three variables.  It does this because the
+value of @code{z = 0}, which is 0, is stored into @code{y}, and then
+the value of @code{y = z = 0}, which is 0, is stored into @code{x}.
+
+This is also true of assignments to lists of values, so the following is
+a valid expression
+
+ at example
+[a, b, c] = [u, s, v] = svd (a)
+ at end example
+
+ at noindent
+that is exactly equivalent to
+
+ at example
+ at group
+[u, s, v] = svd (a)
+a = u
+b = s
+c = v
+ at end group
+ at end example
+
+In expressions like this, the number of values in each part of the
+expression need not match.  For example, the expression
+
+ at example
+[a, b] = [u, s, v] = svd (a)
+ at end example
+
+ at noindent
+is equivalent to 
+
+ at example
+ at group
+[u, s, v] = svd (a)
+a = u
+b = s
+ at end group
+ at end example
+
+ at noindent
+The number of values on the left side of the expression can, however,
+not exceed the number of values on the right side.  For example, the
+following will produce an error.
+
+ at example
+ at group
+[a, b, c, d] = [u, s, v] = svd (a);
+ at print{} error: element number 4 undefined in return list
+ at end group
+ at end example
+
+ at opindex +=
+A very common programming pattern is to increment an existing variable
+with a given value, like this
+
+ at example
+a = a + 2;
+ at end example
+
+ at noindent
+This can be written in a clearer and more condensed form using the
+ at code{+=} operator
+
+ at example
+a += 2;
+ at end example
+
+ at noindent
+ at opindex -=
+ at opindex *=
+ at opindex /=
+Similar operators also exist for subtraction (@code{-=}),
+multiplication (@code{*=}), and division (@code{/=}).  An expression
+of the form
+
+ at example
+ at var{expr1} @var{op}= @var{expr2}
+ at end example
+
+ at noindent
+is evaluated as
+
+ at example
+ at var{expr1} = (@var{expr1}) @var{op} (@var{expr2})
+ at end example
+
+ at noindent
+where @var{op} can be either @code{+}, @code{-}, @code{*}, or @code{/}.
+So, the expression
+
+ at example
+a *= b+1
+ at end example
+
+ at noindent
+is evaluated as
+
+ at example
+a = a * (b+1)
+ at end example
+
+ at noindent
+and @emph{not}
+
+ at example
+a = a * b + 1
+ at end example
+
+You can use an assignment anywhere an expression is called for.  For
+example, it is valid to write @code{x != (y = 1)} to set @code{y} to 1
+and then test whether @code{x} equals 1.  But this style tends to make
+programs hard to read.  Except in a one-shot program, you should rewrite
+it to get rid of such nesting of assignments.  This is never very hard.
+
+ at cindex increment operator
+ at cindex decrement operator
+ at cindex operators, increment
+ at cindex operators, decrement
+
+ at node Increment Ops
+ at section Increment Operators
+
+ at emph{Increment operators} increase or decrease the value of a variable
+by 1.  The operator to increment a variable is written as @samp{++}.  It
+may be used to increment a variable either before or after taking its
+value.
+
+For example, to pre-increment the variable @var{x}, you would write
+ at code{++ at var{x}}.  This would add one to @var{x} and then return the new
+value of @var{x} as the result of the expression.  It is exactly the
+same as the expression @code{@var{x} = @var{x} + 1}.
+
+To post-increment a variable @var{x}, you would write @code{@var{x}++}.
+This adds one to the variable @var{x}, but returns the value that
+ at var{x} had prior to incrementing it.  For example, if @var{x} is equal
+to 2, the result of the expression @code{@var{x}++} is 2, and the new
+value of @var{x} is 3.
+
+For matrix and vector arguments, the increment and decrement operators
+work on each element of the operand.
+
+Here is a list of all the increment and decrement expressions.
+
+ at table @code
+ at item ++ at var{x}
+ at opindex ++
+This expression increments the variable @var{x}.  The value of the
+expression is the @emph{new} value of @var{x}.  It is equivalent to the
+expression @code{@var{x} = @var{x} + 1}.
+
+ at item -- at var{x}
+ at opindex @code{--}
+This expression decrements the variable @var{x}.  The value of the
+expression is the @emph{new} value of @var{x}.  It is equivalent to the
+expression @code{@var{x} = @var{x} - 1}.
+
+ at item @var{x}++
+ at opindex ++
+This expression causes the variable @var{x} to be incremented.  The
+value of the expression is the @emph{old} value of @var{x}.
+
+ at item @var{x}--
+ at opindex @code{--}
+This expression causes the variable @var{x} to be decremented.  The
+value of the expression is the @emph{old} value of @var{x}.
+ at end table
+
+ at node Operator Precedence
+ at section Operator Precedence
+ at cindex operator precedence
+
+ at dfn{Operator precedence} determines how operators are grouped, when
+different operators appear close by in one expression.  For example,
+ at samp{*} has higher precedence than @samp{+}.  Thus, the expression
+ at code{a + b * c} means to multiply @code{b} and @code{c}, and then add
+ at code{a} to the product (i.e., @code{a + (b * c)}).
+
+You can overrule the precedence of the operators by using parentheses.
+You can think of the precedence rules as saying where the parentheses
+are assumed if you do not write parentheses yourself.  In fact, it is
+wise to use parentheses whenever you have an unusual combination of
+operators, because other people who read the program may not remember
+what the precedence is in this case.  You might forget as well, and then
+you too could make a mistake.  Explicit parentheses will help prevent
+any such mistake.
+
+When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment and exponentiation
+operators, which group in the opposite order.  Thus, the expression
+ at code{a - b + c} groups as @code{(a - b) + c}, but the expression
+ at code{a = b = c} groups as @code{a = (b = c)}.
+
+The precedence of prefix unary operators is important when another
+operator follows the operand.  For example, @code{-x^2} means
+ at code{-(x^2)}, because @samp{-} has lower precedence than @samp{^}.
+
+Here is a table of the operators in Octave, in order of increasing
+precedence.
+
+ at table @code
+ at item statement separators
+ at samp{;}, @samp{,}.
+
+ at item assignment
+ at samp{=}, @samp{+=}, @samp{-=}, @samp{*=}, at samp{/=}.  This operator
+groups right to left.
+
+ at item logical "or" and "and"
+ at samp{||}, @samp{&&}.
+
+ at item element-wise "or" and "and"
+ at samp{|}, @samp{&}.
+
+ at item relational
+ at samp{<}, @samp{<=}, @samp{==}, @samp{>=}, @samp{>}, @samp{!=},
+ at samp{~=}.
+
+ at item colon
+ at samp{:}.
+
+ at item add, subtract
+ at samp{+}, @samp{-}.
+
+ at item multiply, divide
+ at samp{*}, @samp{/}, @samp{\}, @samp{.\}, @samp{.*}, @samp{./}.
+
+ at item transpose
+ at samp{'}, @samp{.'}
+
+ at item unary plus, minus, increment, decrement, and ``not''
+ at samp{+}, @samp{-}, @samp{++}, @samp{--}, @samp{!}, @samp{~}.
+
+ at item exponentiation
+ at samp{^}, @samp{**}, @samp{.^}, @samp{.**}.
+ at end table
diff --git a/doc/interpreter/expr.txi b/doc/interpreter/expr.txi
new file mode 100644
index 0000000..ae70728
--- /dev/null
+++ b/doc/interpreter/expr.txi
@@ -0,0 +1,1166 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2006,
+ at c               2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Expressions
+ at chapter Expressions
+ at cindex expressions
+
+Expressions are the basic building block of statements in Octave.  An
+expression evaluates to a value, which you can print, test, store in a
+variable, pass to a function, or assign a new value to a variable with
+an assignment operator.
+
+An expression can serve as a statement on its own.  Most other kinds of
+statements contain one or more expressions which specify data to be
+operated on.  As in other languages, expressions in Octave include
+variables, array references, constants, and function calls, as well as
+combinations of these with various operators.
+
+ at menu
+* Index Expressions::           
+* Calling Functions::           
+* Arithmetic Ops::              
+* Comparison Ops::              
+* Boolean Expressions::         
+* Assignment Ops::              
+* Increment Ops::               
+* Operator Precedence::         
+ at end menu
+
+ at node Index Expressions
+ at section Index Expressions
+
+ at opindex (
+ at opindex )
+
+An @dfn{index expression} allows you to reference or extract selected
+elements of a matrix or vector.
+
+Indices may be scalars, vectors, ranges, or the special operator
+ at samp{:}, which may be used to select entire rows or columns.
+
+Vectors are indexed using a single index expression.  Matrices may be
+indexed using one or two indices.  When using a single index
+expression, the elements of the matrix are taken in column-first order;
+the dimensions of the output match those of the index expression.  For
+example,
+ at example
+ at group
+a (2)       # a scalar
+a (1:2)     # a row vector
+a ([1; 2])  # a column vector
+ at end group
+ at end example
+
+As a special case, when a colon is used as a single index, the output
+is a column vector containing all the elements of the vector or matrix.
+For example
+ at example
+a (:)       # a column vector
+ at end example
+
+Given the matrix
+
+ at example
+a = [1, 2; 3, 4]
+ at end example
+
+ at noindent
+all of the following expressions are equivalent
+
+ at example
+ at group
+a (1, [1, 2])
+a (1, 1:2)
+a (1, :)
+ at end group
+ at end example
+
+ at noindent
+and select the first row of the matrix.
+
+In general, an array with @samp{n} dimensions can be indexed using @samp{m}
+indices.  If @code{n == m}, each index corresponds to its respective dimension.
+The set of index tuples determining the result is formed by the Cartesian product
+of the index vectors (or ranges or scalars).
+If @code{n < m}, then the array is padded by trailing singleton dimensions.
+If @code{n > m}, the last @code{n-m+1} dimensions are folded into a single
+dimension with extent equal to product of extents of the original dimensions.
+
+ at c FIXED -- sections on variable prefer_zero_one_indexing were removed
+
+Indexing a scalar with a vector of ones can be used to create a
+vector the same size as the index vector, with each element equal to
+the value of the original scalar.  For example, the following statements
+
+ at example
+ at group
+a = 13;
+a (ones (1, 4))
+ at end group
+ at end example
+
+ at noindent
+produce a vector whose four elements are all equal to 13.
+
+Similarly, indexing a scalar with two vectors of ones can be used to
+create a matrix.  For example the following statements
+
+ at example
+ at group
+a = 13;
+a (ones (1, 2), ones (1, 3))
+ at end group
+ at end example
+
+ at noindent
+create a 2 by 3 matrix with all elements equal to 13.
+
+The last example could also be written as
+
+ at example
+ at group
+13 (ones (2, 3))
+ at end group
+ at end example
+
+It should be, noted that @code{ones (1, n)} (a row vector of ones) results in a
+range (with zero increment), and is therefore more efficient when used in index
+expression than other forms of @dfn{ones}.  In particular, when @samp{r} is a row
+vector, the expressions
+
+ at example
+  r(ones (1, n), :)
+ at end example
+
+ at example
+  r(ones (n, 1), :)
+ at end example
+
+will produce identical results, but the first one will be significantly
+faster, at least for @samp{r} and @samp{n} large enough.  The reason is that
+in the first case the index is kept in a compressed form, which allows Octave
+to choose a more efficient algorithm to handle the expression.
+
+In general, for an user unaware of these subtleties, it is best to use
+the function @dfn{repmat} for spreading arrays into bigger ones.
+
+It is also possible to create a matrix with different values.  The
+following example creates a 10 dimensional row vector @math{a} containing
+the values
+ at tex
+$a_i = \sqrt{i}$.
+ at end tex
+ at ifnottex
+a(i) = sqrt(i).
+ at end ifnottex
+
+ at example
+ at group
+for i = 1:10
+  a(i) = sqrt (i);
+endfor
+ at end group
+ at end example
+
+ at noindent
+Note that it is quite inefficient to create a vector using a loop like
+the one shown in the example above.  In this particular case, it would
+have been much more efficient to use the expression
+
+ at example
+a = sqrt (1:10);
+ at end example
+
+ at noindent
+thus avoiding the loop entirely.  In cases where a loop is still
+required, or a number of values must be combined to form a larger
+matrix, it is generally much faster to set the size of the matrix first,
+and then insert elements using indexing commands.  For example, given a
+matrix @code{a},
+
+ at example
+ at group
+[nr, nc] = size (a);
+x = zeros (nr, n * nc);
+for i = 1:n
+  x(:,(i-1)*nc+1:i*nc) = a;
+endfor
+ at end group
+ at end example
+
+ at noindent
+is considerably faster than
+
+ at example
+ at group
+x = a;
+for i = 1:n-1
+  x = [x, a];
+endfor
+ at end group
+ at end example
+
+ at noindent
+particularly for large matrices because Octave does not have to
+repeatedly resize the result.
+
+ at DOCSTRING(sub2ind)
+
+ at DOCSTRING(ind2sub)
+
+ at node Calling Functions
+ at section Calling Functions
+
+A @dfn{function} is a name for a particular calculation.  Because it has
+a name, you can ask for it by name at any point in the program.  For
+example, the function @code{sqrt} computes the square root of a number.
+
+A fixed set of functions are @dfn{built-in}, which means they are
+available in every Octave program.  The @code{sqrt} function is one of
+these.  In addition, you can define your own functions.
+ at xref{Functions and Scripts}, for information about how to do this.
+
+ at cindex arguments in function call
+The way to use a function is with a @dfn{function call} expression,
+which consists of the function name followed by a list of
+ at dfn{arguments} in parentheses.  The arguments are expressions which give
+the raw materials for the calculation that the function will do.  When
+there is more than one argument, they are separated by commas.  If there
+are no arguments, you can omit the parentheses, but it is a good idea to
+include them anyway, to clearly indicate that a function call was
+intended.  Here are some examples:
+
+ at example
+ at group
+sqrt (x^2 + y^2)      # @r{One argument}
+ones (n, m)           # @r{Two arguments}
+rand ()               # @r{No arguments}
+ at end group
+ at end example
+
+Each function expects a particular number of arguments.  For example, the
+ at code{sqrt} function must be called with a single argument, the number
+to take the square root of:
+
+ at example
+sqrt (@var{argument})
+ at end example
+
+Some of the built-in functions take a variable number of arguments,
+depending on the particular usage, and their behavior is different
+depending on the number of arguments supplied.
+
+Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it.  In this
+example, the value of @code{sqrt (@var{argument})} is the square root of
+the argument.  A function can also have side effects, such as assigning
+the values of certain variables or doing input or output operations.
+
+Unlike most languages, functions in Octave may return multiple values.
+For example, the following statement
+
+ at example
+[u, s, v] = svd (a)
+ at end example
+
+ at noindent
+computes the singular value decomposition of the matrix @code{a} and
+assigns the three result matrices to @code{u}, @code{s}, and @code{v}.
+
+The left side of a multiple assignment expression is itself a list of
+expressions, and is allowed to be a list of variable names or index
+expressions.  See also @ref{Index Expressions}, and @ref{Assignment Ops}.
+
+ at menu
+* Call by Value::               
+* Recursion::                   
+ at end menu
+
+ at node Call by Value
+ at subsection Call by Value
+
+In Octave, unlike Fortran, function arguments are passed by value, which
+means that each argument in a function call is evaluated and assigned to
+a temporary location in memory before being passed to the function.
+There is currently no way to specify that a function parameter should be
+passed by reference instead of by value.  This means that it is
+impossible to directly alter the value of a function parameter in the
+calling function.  It can only change the local copy within the function
+body.  For example, the function
+
+ at example
+ at group
+function f (x, n)
+  while (n-- > 0)
+    disp (x);
+  endwhile
+endfunction
+ at end group
+ at end example
+
+ at noindent
+displays the value of the first argument @var{n} times.  In this
+function, the variable @var{n} is used as a temporary variable without
+having to worry that its value might also change in the calling
+function.  Call by value is also useful because it is always possible to
+pass constants for any function parameter without first having to
+determine that the function will not attempt to modify the parameter.
+
+The caller may use a variable as the expression for the argument, but
+the called function does not know this: it only knows what value the
+argument had.  For example, given a function called as
+
+ at example
+ at group
+foo = "bar";
+fcn (foo)
+ at end group
+ at end example
+
+ at noindent
+you should not think of the argument as being ``the variable
+ at code{foo}.''  Instead, think of the argument as the string value,
+ at code{"bar"}.
+
+Even though Octave uses pass-by-value semantics for function arguments,
+values are not copied unnecessarily.  For example,
+
+ at example
+ at group
+x = rand (1000);
+f (x);
+ at end group
+ at end example
+
+ at noindent
+does not actually force two 1000 by 1000 element matrices to exist
+ at emph{unless} the function @code{f} modifies the value of its
+argument.  Then Octave must create a copy to avoid changing the
+value outside the scope of the function @code{f}, or attempting (and
+probably failing!) to modify the value of a constant or the value of a
+temporary result.
+
+ at node Recursion
+ at subsection Recursion
+ at cindex factorial function
+
+With some restrictions at footnote{Some of Octave's functions are
+implemented in terms of functions that cannot be called recursively.
+For example, the ODE solver @code{lsode} is ultimately implemented in a
+Fortran subroutine that cannot be called recursively, so @code{lsode}
+should not be called either directly or indirectly from within the
+user-supplied function that @code{lsode} requires.  Doing so will result
+in an error.}, recursive function calls are allowed.  A
+ at dfn{recursive function} is one which calls itself, either directly or
+indirectly.  For example, here is an inefficient at footnote{It would be
+much better to use @code{prod (1:n)}, or @code{gamma (n+1)} instead,
+after first checking to ensure that the value @code{n} is actually a
+positive integer.} way to compute the factorial of a given integer:
+
+ at example
+ at group
+function retval = fact (n)
+  if (n > 0)
+    retval = n * fact (n-1);
+  else
+    retval = 1;
+  endif
+endfunction
+ at end group
+ at end example
+
+This function is recursive because it calls itself directly.  It
+eventually terminates because each time it calls itself, it uses an
+argument that is one less than was used for the previous call.  Once the
+argument is no longer greater than zero, it does not call itself, and
+the recursion ends.
+
+The built-in variable @code{max_recursion_depth} specifies a limit to
+the recursion depth and prevents Octave from recursing infinitely.
+
+ at DOCSTRING(max_recursion_depth)
+
+ at node Arithmetic Ops
+ at section Arithmetic Operators
+ at cindex arithmetic operators
+ at cindex operators, arithmetic
+ at cindex addition
+ at cindex subtraction
+ at cindex multiplication
+ at cindex matrix multiplication
+ at cindex division
+ at cindex quotient
+ at cindex negation
+ at cindex unary minus
+ at cindex exponentiation
+ at cindex transpose
+ at cindex Hermitian operator
+ at cindex transpose, complex-conjugate
+ at cindex complex-conjugate transpose
+
+The following arithmetic operators are available, and work on scalars
+and matrices.
+
+ at table @code
+ at item @var{x} + @var{y}
+ at opindex +
+Addition.  If both operands are matrices, the number of rows and columns
+must both agree.  If one operand is a scalar, its value is added to
+all the elements of the other operand.
+
+ at item @var{x} .+ @var{y}
+ at opindex .+
+Element by element addition.  This operator is equivalent to @code{+}.
+
+ at item @var{x} - @var{y}
+ at opindex -
+Subtraction.  If both operands are matrices, the number of rows and
+columns of both must agree.
+
+ at item @var{x} .- @var{y}
+Element by element subtraction.  This operator is equivalent to @code{-}.
+
+ at item @var{x} * @var{y}
+ at opindex *
+Matrix multiplication.  The number of columns of @var{x} must agree
+with the number of rows of @var{y}.
+
+ at item @var{x} .* @var{y}
+ at opindex .*
+Element by element multiplication.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+ at item @var{x} / @var{y}
+ at opindex /
+Right division.  This is conceptually equivalent to the expression
+
+ at example
+(inverse (y') * x')'
+ at end example
+
+ at noindent
+but it is computed without forming the inverse of @var{y'}.
+
+If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+ at item @var{x} ./ @var{y}
+ at opindex ./
+Element by element right division.
+
+ at item @var{x} \ @var{y}
+ at opindex \
+Left division.  This is conceptually equivalent to the expression
+
+ at example
+inverse (x) * y
+ at end example
+
+ at noindent
+but it is computed without forming the inverse of @var{x}.
+
+If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+ at item @var{x} .\ @var{y}
+ at opindex .\
+Element by element left division.  Each element of @var{y} is divided
+by each corresponding element of @var{x}.
+
+ at item @var{x} ^ @var{y}
+ at itemx @var{x} ** @var{y}
+ at opindex **
+ at opindex ^
+Power operator.  If @var{x} and @var{y} are both scalars, this operator
+returns @var{x} raised to the power @var{y}.  If @var{x} is a scalar and
+ at var{y} is a square matrix, the result is computed using an eigenvalue
+expansion.  If @var{x} is a square matrix, the result is computed by
+repeated multiplication if @var{y} is an integer, and by an eigenvalue
+expansion if @var{y} is not an integer.  An error results if both
+ at var{x} and @var{y} are matrices.
+
+The implementation of this operator needs to be improved.
+
+ at item @var{x} .^ @var{y}
+ at item @var{x} .** @var{y}
+ at opindex .**
+ at opindex .^
+Element by element power operator.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+ at item - at var{x}
+ at opindex -
+Negation.
+
+ at item + at var{x}
+ at opindex +
+Unary plus.  This operator has no effect on the operand.
+
+ at item @var{x}'
+ at opindex '
+Complex conjugate transpose.  For real arguments, this operator is the
+same as the transpose operator.  For complex arguments, this operator is
+equivalent to the expression
+
+ at example
+conj (x.')
+ at end example
+
+ at item @var{x}.'
+ at opindex .'
+Transpose.
+ at end table
+
+Note that because Octave's element by element operators begin with a
+ at samp{.}, there is a possible ambiguity for statements like
+
+ at example
+1./m
+ at end example
+
+ at noindent
+because the period could be interpreted either as part of the constant
+or as part of the operator.  To resolve this conflict, Octave treats the
+expression as if you had typed
+
+ at example
+(1) ./ m
+ at end example
+
+ at noindent
+and not
+
+ at example
+(1.) / m
+ at end example
+
+ at noindent
+Although this is inconsistent with the normal behavior of Octave's
+lexer, which usually prefers to break the input into tokens by
+preferring the longest possible match at any given point, it is more
+useful in this case.
+
+ at node Comparison Ops
+ at section Comparison Operators
+ at cindex comparison expressions
+ at cindex expressions, comparison
+ at cindex relational operators
+ at cindex operators, relational
+ at cindex less than operator
+ at cindex greater than operator
+ at cindex equality operator
+ at cindex tests for equality
+ at cindex equality, tests for
+
+ at dfn{Comparison operators} compare numeric values for relationships
+such as equality.  They are written using
+ at emph{relational operators}.
+
+All of Octave's comparison operators return a value of 1 if the
+comparison is true, or 0 if it is false.  For matrix values, they all
+work on an element-by-element basis.  For example,
+
+ at example
+ at group
+[1, 2; 3, 4] == [1, 3; 2, 4]
+     @result{}  1  0
+         0  1
+ at end group
+ at end example
+
+If one operand is a scalar and the other is a matrix, the scalar is
+compared to each element of the matrix in turn, and the result is the
+same size as the matrix.
+
+ at table @code
+ at item @var{x} < @var{y}
+ at opindex <
+True if @var{x} is less than @var{y}.
+
+ at item @var{x} <= @var{y}
+ at opindex <=
+True if @var{x} is less than or equal to @var{y}.
+
+ at item @var{x} == @var{y}
+ at opindex ==
+True if @var{x} is equal to @var{y}.
+
+ at item @var{x} >= @var{y}
+ at opindex >=
+True if @var{x} is greater than or equal to @var{y}.
+
+ at item @var{x} > @var{y}
+ at opindex >
+True if @var{x} is greater than @var{y}.
+
+ at item @var{x} != @var{y}
+ at itemx @var{x} ~= @var{y}
+ at opindex !=
+ at opindex ~=
+True if @var{x} is not equal to @var{y}.
+ at end table
+
+String comparisons may also be performed with the @code{strcmp}
+function, not with the comparison operators listed above.
+ at xref{Strings}.
+
+ at DOCSTRING(isequal)
+
+ at DOCSTRING(isequalwithequalnans)
+
+ at node Boolean Expressions
+ at section Boolean Expressions
+ at cindex expressions, boolean
+ at cindex boolean expressions
+ at cindex expressions, logical
+ at cindex logical expressions
+ at cindex operators, boolean
+ at cindex boolean operators
+ at cindex logical operators
+ at cindex operators, logical
+ at cindex and operator
+ at cindex or operator
+ at cindex not operator
+
+ at menu
+* Element-by-element Boolean Operators::  
+* Short-circuit Boolean Operators::  
+ at end menu
+
+ at node Element-by-element Boolean Operators
+ at subsection Element-by-element Boolean Operators
+ at cindex element-by-element evaluation
+
+An @dfn{element-by-element boolean expression} is a combination of
+comparison expressions using the boolean
+operators ``or'' (@samp{|}), ``and'' (@samp{&}), and ``not'' (@samp{!}),
+along with parentheses to control nesting.  The truth of the boolean
+expression is computed by combining the truth values of the
+corresponding elements of the component expressions.  A value is
+considered to be false if it is zero, and true otherwise.
+
+Element-by-element boolean expressions can be used wherever comparison
+expressions can be used.  They can be used in @code{if} and @code{while}
+statements.  However, a matrix value used as the condition in an
+ at code{if} or @code{while} statement is only true if @emph{all} of its
+elements are nonzero.
+
+Like comparison operations, each element of an element-by-element
+boolean expression also has a numeric value (1 if true, 0 if false) that
+comes into play if the result of the boolean expression is stored in a
+variable, or used in arithmetic.
+
+Here are descriptions of the three element-by-element boolean operators.
+
+ at table @code
+ at item @var{boolean1} & @var{boolean2}
+ at opindex &
+Elements of the result are true if both corresponding elements of
+ at var{boolean1} and @var{boolean2} are true.
+
+ at item @var{boolean1} | @var{boolean2}
+ at opindex |
+Elements of the result are true if either of the corresponding elements
+of @var{boolean1} or @var{boolean2} is true.
+
+ at item ! @var{boolean}
+ at itemx ~ @var{boolean}
+ at opindex ~
+ at opindex !
+Each element of the result is true if the corresponding element of
+ at var{boolean} is false.
+ at end table
+
+For matrix operands, these operators work on an element-by-element
+basis.  For example, the expression
+
+ at example
+[1, 0; 0, 1] & [1, 0; 2, 3]
+ at end example
+
+ at noindent
+returns a two by two identity matrix.
+
+For the binary operators, the dimensions of the operands must conform if
+both are matrices.  If one of the operands is a scalar and the other a
+matrix, the operator is applied to the scalar and each element of the
+matrix.
+
+For the binary element-by-element boolean operators, both subexpressions
+ at var{boolean1} and @var{boolean2} are evaluated before computing the
+result.  This can make a difference when the expressions have side
+effects.  For example, in the expression
+
+ at example
+a & b++
+ at end example
+
+ at noindent
+the value of the variable @var{b} is incremented even if the variable
+ at var{a} is zero.
+
+This behavior is necessary for the boolean operators to work as
+described for matrix-valued operands.
+
+ at node Short-circuit Boolean Operators
+ at subsection Short-circuit Boolean Operators
+ at cindex short-circuit evaluation
+
+Combined with the implicit conversion to scalar values in @code{if} and
+ at code{while} conditions, Octave's element-by-element boolean operators
+are often sufficient for performing most logical operations.  However,
+it is sometimes desirable to stop evaluating a boolean expression as
+soon as the overall truth value can be determined.  Octave's
+ at dfn{short-circuit} boolean operators work this way.
+
+ at table @code
+ at item @var{boolean1} && @var{boolean2}
+ at opindex &&
+The expression @var{boolean1} is evaluated and converted to a scalar
+using the equivalent of the operation @code{all (@var{boolean1}(:))}.
+If it is false, the result of the overall expression is 0.  If it is
+true, the expression @var{boolean2} is evaluated and converted to a
+scalar using the equivalent of the operation @code{all
+(@var{boolean1}(:))}.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+ at strong{Warning:} there is one exception to the rule of evaluating
+ at code{all (@var{boolean1}(:))}, which is when @code{boolean1} is the
+empty matrix.  The truth value of an empty matrix is always @code{false}
+so @code{[] && true} evaluates to @code{false} even though
+ at code{all ([])} is @code{true}.
+
+ at item @var{boolean1} || @var{boolean2}
+ at opindex ||
+The expression @var{boolean1} is evaluated and converted to a scalar
+using the equivalent of the operation @code{all (@var{boolean1}(:))}.
+If it is true, the result of the overall expression is 1.  If it is
+false, the expression @var{boolean2} is evaluated and converted to a
+scalar using the equivalent of the operation @code{all
+(@var{boolean1}(:))}.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+ at strong{Warning:} the truth value of an empty matrix is always @code{false},
+see the previous list item for details.
+ at end table
+
+The fact that both operands may not be evaluated before determining the
+overall truth value of the expression can be important.  For example, in
+the expression
+
+ at example
+a && b++
+ at end example
+
+ at noindent
+the value of the variable @var{b} is only incremented if the variable
+ at var{a} is nonzero.
+
+This can be used to write somewhat more concise code.  For example, it
+is possible write
+
+ at example
+ at group
+function f (a, b, c)
+  if (nargin > 2 && ischar (c))
+    @dots{}
+ at end group
+ at end example
+
+ at noindent
+instead of having to use two @code{if} statements to avoid attempting to
+evaluate an argument that doesn't exist.  For example, without the
+short-circuit feature, it would be necessary to write
+
+ at example
+ at group
+function f (a, b, c)
+  if (nargin > 2)
+    if (ischar (c))
+      @dots{}
+ at end group
+ at end example
+
+ at noindent
+Writing
+
+ at example
+ at group
+function f (a, b, c)
+  if (nargin > 2 & ischar (c))
+    @dots{}
+ at end group
+ at end example
+
+ at noindent
+would result in an error if @code{f} were called with one or two
+arguments because Octave would be forced to try to evaluate both of the
+operands for the operator @samp{&}.
+
+ at node Assignment Ops
+ at section Assignment Expressions
+ at cindex assignment expressions
+ at cindex assignment operators
+ at cindex operators, assignment
+ at cindex expressions, assignment
+
+ at opindex =
+
+An @dfn{assignment} is an expression that stores a new value into a
+variable.  For example, the following expression assigns the value 1 to
+the variable @code{z}:
+
+ at example
+z = 1
+ at end example
+
+ at noindent
+After this expression is executed, the variable @code{z} has the value 1.
+Whatever old value @code{z} had before the assignment is forgotten.
+The @samp{=} sign is called an @dfn{assignment operator}.
+
+Assignments can store string values also.  For example, the following
+expression would store the value @code{"this food is good"} in the
+variable @code{message}:
+
+ at example
+ at group
+thing = "food"
+predicate = "good"
+message = [ "this " , thing , " is " , predicate ]
+ at end group
+ at end example
+
+ at noindent
+(This also illustrates concatenation of strings.)
+
+ at cindex side effect
+Most operators (addition, concatenation, and so on) have no effect
+except to compute a value.  If you ignore the value, you might as well
+not use the operator.  An assignment operator is different.  It does
+produce a value, but even if you ignore the value, the assignment still
+makes itself felt through the alteration of the variable.  We call this
+a @dfn{side effect}.
+
+ at cindex lvalue
+The left-hand operand of an assignment need not be a variable
+(@pxref{Variables}).  It can also be an element of a matrix
+(@pxref{Index Expressions}) or a list of return values
+(@pxref{Calling Functions}).  These are all called @dfn{lvalues}, which
+means they can appear on the left-hand side of an assignment operator.
+The right-hand operand may be any expression.  It produces the new value
+which the assignment stores in the specified variable, matrix element,
+or list of return values.
+
+It is important to note that variables do @emph{not} have permanent types.
+The type of a variable is simply the type of whatever value it happens
+to hold at the moment.  In the following program fragment, the variable
+ at code{foo} has a numeric value at first, and a string value later on:
+
+ at example
+ at group
+octave:13> foo = 1
+foo = 1
+octave:13> foo = "bar"
+foo = bar
+ at end group
+ at end example
+
+ at noindent
+When the second assignment gives @code{foo} a string value, the fact that
+it previously had a numeric value is forgotten.
+
+Assignment of a scalar to an indexed matrix sets all of the elements
+that are referenced by the indices to the scalar value.  For example, if
+ at code{a} is a matrix with at least two columns,
+
+ at example
+ at group
+a(:, 2) = 5
+ at end group
+ at end example
+
+ at noindent
+sets all the elements in the second column of @code{a} to 5.
+
+Assigning an empty matrix @samp{[]} works in most cases to allow you to
+delete rows or columns of matrices and vectors.  @xref{Empty Matrices}.
+For example, given a 4 by 5 matrix @var{A}, the assignment
+
+ at example
+A (3, :) = []
+ at end example
+
+ at noindent
+deletes the third row of @var{A}, and the assignment
+
+ at example
+A (:, 1:2:5) = []
+ at end example
+
+ at noindent
+deletes the first, third, and fifth columns.
+
+An assignment is an expression, so it has a value.  Thus, @code{z = 1}
+as an expression has the value 1.  One consequence of this is that you
+can write multiple assignments together:
+
+ at example
+x = y = z = 0
+ at end example
+
+ at noindent
+stores the value 0 in all three variables.  It does this because the
+value of @code{z = 0}, which is 0, is stored into @code{y}, and then
+the value of @code{y = z = 0}, which is 0, is stored into @code{x}.
+
+This is also true of assignments to lists of values, so the following is
+a valid expression
+
+ at example
+[a, b, c] = [u, s, v] = svd (a)
+ at end example
+
+ at noindent
+that is exactly equivalent to
+
+ at example
+ at group
+[u, s, v] = svd (a)
+a = u
+b = s
+c = v
+ at end group
+ at end example
+
+In expressions like this, the number of values in each part of the
+expression need not match.  For example, the expression
+
+ at example
+[a, b] = [u, s, v] = svd (a)
+ at end example
+
+ at noindent
+is equivalent to 
+
+ at example
+ at group
+[u, s, v] = svd (a)
+a = u
+b = s
+ at end group
+ at end example
+
+ at noindent
+The number of values on the left side of the expression can, however,
+not exceed the number of values on the right side.  For example, the
+following will produce an error.
+
+ at example
+ at group
+[a, b, c, d] = [u, s, v] = svd (a);
+ at print{} error: element number 4 undefined in return list
+ at end group
+ at end example
+
+ at opindex +=
+A very common programming pattern is to increment an existing variable
+with a given value, like this
+
+ at example
+a = a + 2;
+ at end example
+
+ at noindent
+This can be written in a clearer and more condensed form using the
+ at code{+=} operator
+
+ at example
+a += 2;
+ at end example
+
+ at noindent
+ at opindex -=
+ at opindex *=
+ at opindex /=
+Similar operators also exist for subtraction (@code{-=}),
+multiplication (@code{*=}), and division (@code{/=}).  An expression
+of the form
+
+ at example
+ at var{expr1} @var{op}= @var{expr2}
+ at end example
+
+ at noindent
+is evaluated as
+
+ at example
+ at var{expr1} = (@var{expr1}) @var{op} (@var{expr2})
+ at end example
+
+ at noindent
+where @var{op} can be either @code{+}, @code{-}, @code{*}, or @code{/}.
+So, the expression
+
+ at example
+a *= b+1
+ at end example
+
+ at noindent
+is evaluated as
+
+ at example
+a = a * (b+1)
+ at end example
+
+ at noindent
+and @emph{not}
+
+ at example
+a = a * b + 1
+ at end example
+
+You can use an assignment anywhere an expression is called for.  For
+example, it is valid to write @code{x != (y = 1)} to set @code{y} to 1
+and then test whether @code{x} equals 1.  But this style tends to make
+programs hard to read.  Except in a one-shot program, you should rewrite
+it to get rid of such nesting of assignments.  This is never very hard.
+
+ at cindex increment operator
+ at cindex decrement operator
+ at cindex operators, increment
+ at cindex operators, decrement
+
+ at node Increment Ops
+ at section Increment Operators
+
+ at emph{Increment operators} increase or decrease the value of a variable
+by 1.  The operator to increment a variable is written as @samp{++}.  It
+may be used to increment a variable either before or after taking its
+value.
+
+For example, to pre-increment the variable @var{x}, you would write
+ at code{++ at var{x}}.  This would add one to @var{x} and then return the new
+value of @var{x} as the result of the expression.  It is exactly the
+same as the expression @code{@var{x} = @var{x} + 1}.
+
+To post-increment a variable @var{x}, you would write @code{@var{x}++}.
+This adds one to the variable @var{x}, but returns the value that
+ at var{x} had prior to incrementing it.  For example, if @var{x} is equal
+to 2, the result of the expression @code{@var{x}++} is 2, and the new
+value of @var{x} is 3.
+
+For matrix and vector arguments, the increment and decrement operators
+work on each element of the operand.
+
+Here is a list of all the increment and decrement expressions.
+
+ at table @code
+ at item ++ at var{x}
+ at opindex ++
+This expression increments the variable @var{x}.  The value of the
+expression is the @emph{new} value of @var{x}.  It is equivalent to the
+expression @code{@var{x} = @var{x} + 1}.
+
+ at item -- at var{x}
+ at opindex @code{--}
+This expression decrements the variable @var{x}.  The value of the
+expression is the @emph{new} value of @var{x}.  It is equivalent to the
+expression @code{@var{x} = @var{x} - 1}.
+
+ at item @var{x}++
+ at opindex ++
+This expression causes the variable @var{x} to be incremented.  The
+value of the expression is the @emph{old} value of @var{x}.
+
+ at item @var{x}--
+ at opindex @code{--}
+This expression causes the variable @var{x} to be decremented.  The
+value of the expression is the @emph{old} value of @var{x}.
+ at end table
+
+ at node Operator Precedence
+ at section Operator Precedence
+ at cindex operator precedence
+
+ at dfn{Operator precedence} determines how operators are grouped, when
+different operators appear close by in one expression.  For example,
+ at samp{*} has higher precedence than @samp{+}.  Thus, the expression
+ at code{a + b * c} means to multiply @code{b} and @code{c}, and then add
+ at code{a} to the product (i.e., @code{a + (b * c)}).
+
+You can overrule the precedence of the operators by using parentheses.
+You can think of the precedence rules as saying where the parentheses
+are assumed if you do not write parentheses yourself.  In fact, it is
+wise to use parentheses whenever you have an unusual combination of
+operators, because other people who read the program may not remember
+what the precedence is in this case.  You might forget as well, and then
+you too could make a mistake.  Explicit parentheses will help prevent
+any such mistake.
+
+When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment and exponentiation
+operators, which group in the opposite order.  Thus, the expression
+ at code{a - b + c} groups as @code{(a - b) + c}, but the expression
+ at code{a = b = c} groups as @code{a = (b = c)}.
+
+The precedence of prefix unary operators is important when another
+operator follows the operand.  For example, @code{-x^2} means
+ at code{-(x^2)}, because @samp{-} has lower precedence than @samp{^}.
+
+Here is a table of the operators in Octave, in order of increasing
+precedence.
+
+ at table @code
+ at item statement separators
+ at samp{;}, @samp{,}.
+
+ at item assignment
+ at samp{=}, @samp{+=}, @samp{-=}, @samp{*=}, at samp{/=}.  This operator
+groups right to left.
+
+ at item logical "or" and "and"
+ at samp{||}, @samp{&&}.
+
+ at item element-wise "or" and "and"
+ at samp{|}, @samp{&}.
+
+ at item relational
+ at samp{<}, @samp{<=}, @samp{==}, @samp{>=}, @samp{>}, @samp{!=},
+ at samp{~=}.
+
+ at item colon
+ at samp{:}.
+
+ at item add, subtract
+ at samp{+}, @samp{-}.
+
+ at item multiply, divide
+ at samp{*}, @samp{/}, @samp{\}, @samp{.\}, @samp{.*}, @samp{./}.
+
+ at item transpose
+ at samp{'}, @samp{.'}
+
+ at item unary plus, minus, increment, decrement, and ``not''
+ at samp{+}, @samp{-}, @samp{++}, @samp{--}, @samp{!}, @samp{~}.
+
+ at item exponentiation
+ at samp{^}, @samp{**}, @samp{.^}, @samp{.**}.
+ at end table
diff --git a/doc/interpreter/extended.eps b/doc/interpreter/extended.eps
new file mode 100644
index 0000000..c46dacc
--- /dev/null
+++ b/doc/interpreter/extended.eps
@@ -0,0 +1,1134 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: extended.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:56 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (extended.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:56 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+913 532 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 532 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 1352 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 1352 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 2172 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 2172 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 2992 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 2992 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 3812 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 3812 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 4632 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 4632 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 913 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+1842 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1842 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2771 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2771 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3700 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3700 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4629 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4629 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5558 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5558 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6487 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6487 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 913 532 M
+19 46 V
+18 47 V
+19 46 V
+18 46 V
+19 46 V
+18 46 V
+19 46 V
+19 46 V
+18 46 V
+19 46 V
+18 46 V
+19 46 V
+19 45 V
+18 45 V
+19 46 V
+18 45 V
+19 45 V
+18 45 V
+19 45 V
+19 44 V
+18 44 V
+19 45 V
+18 44 V
+19 43 V
+19 44 V
+18 43 V
+19 43 V
+18 43 V
+19 43 V
+18 42 V
+19 43 V
+19 41 V
+18 42 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 40 V
+19 40 V
+18 39 V
+19 40 V
+18 39 V
+19 38 V
+19 39 V
+18 37 V
+19 38 V
+18 37 V
+19 37 V
+18 37 V
+19 36 V
+19 36 V
+18 35 V
+19 36 V
+18 34 V
+19 35 V
+18 34 V
+19 33 V
+19 33 V
+18 33 V
+19 33 V
+18 32 V
+19 32 V
+19 31 V
+18 31 V
+19 30 V
+18 30 V
+19 30 V
+18 30 V
+19 28 V
+19 29 V
+18 28 V
+19 28 V
+18 27 V
+19 27 V
+19 27 V
+18 26 V
+19 26 V
+18 25 V
+19 25 V
+18 25 V
+19 24 V
+19 24 V
+18 23 V
+19 23 V
+18 23 V
+19 22 V
+18 22 V
+19 21 V
+19 22 V
+18 20 V
+19 21 V
+18 20 V
+19 19 V
+19 20 V
+18 19 V
+19 18 V
+18 18 V
+19 18 V
+18 18 V
+19 17 V
+19 17 V
+18 16 V
+19 17 V
+18 15 V
+stroke 2845 4052 M
+19 16 V
+18 15 V
+19 15 V
+19 15 V
+18 14 V
+19 14 V
+18 13 V
+19 14 V
+19 13 V
+18 13 V
+19 12 V
+18 12 V
+19 12 V
+18 12 V
+19 11 V
+19 11 V
+18 11 V
+19 11 V
+18 10 V
+19 10 V
+19 10 V
+18 9 V
+19 10 V
+18 9 V
+19 9 V
+18 8 V
+19 9 V
+19 8 V
+18 8 V
+19 8 V
+18 7 V
+19 8 V
+18 7 V
+19 7 V
+19 7 V
+18 6 V
+19 7 V
+18 6 V
+19 6 V
+19 6 V
+18 6 V
+19 5 V
+18 6 V
+19 5 V
+18 5 V
+19 5 V
+19 5 V
+18 4 V
+19 5 V
+18 4 V
+19 5 V
+18 4 V
+19 4 V
+19 4 V
+18 3 V
+19 4 V
+18 4 V
+19 3 V
+19 3 V
+18 3 V
+19 4 V
+18 3 V
+19 2 V
+18 3 V
+19 3 V
+19 3 V
+18 2 V
+19 3 V
+18 2 V
+19 2 V
+19 2 V
+18 2 V
+19 3 V
+18 2 V
+19 1 V
+18 2 V
+19 2 V
+19 2 V
+18 1 V
+19 2 V
+18 2 V
+19 1 V
+18 1 V
+19 2 V
+19 1 V
+18 1 V
+19 2 V
+18 1 V
+19 1 V
+19 1 V
+18 1 V
+19 1 V
+18 1 V
+19 1 V
+18 1 V
+19 1 V
+19 1 V
+18 0 V
+19 1 V
+18 1 V
+19 1 V
+18 0 V
+19 1 V
+19 1 V
+stroke 4778 4619 M
+18 0 V
+19 1 V
+18 0 V
+19 1 V
+19 0 V
+18 1 V
+19 0 V
+18 1 V
+19 0 V
+18 1 V
+19 0 V
+19 0 V
+18 1 V
+19 0 V
+18 0 V
+19 1 V
+19 0 V
+18 0 V
+19 1 V
+18 0 V
+19 0 V
+18 0 V
+19 1 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 1 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 1 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 1 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 1 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+18 0 V
+19 0 V
+% End plot #1
+% Begin plot #2
+stroke
+LT1
+1.00 0.00 0.00 C 913 532 M
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+18 41 V
+19 41 V
+% End plot #2
+stroke
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.00 0.00 0.00 C 2121 3064 M
+[ [(Symbol) 100.0 0.0 true true 0 (\254)]
+[(Helvetica) 100.0 0.0 true true 0 ( x = )]
+[(Helvetica) 100.0 0.0 true true 0 (2/)]
+[(Symbol) 100.0 0.0 true true 0 (\326)]
+[(Symbol) 100.0 0.0 true true 0 (p)]
+[(Helvetica) 100.0 0.0 true true 0 ( )]
+[(Symbol) 160.0 0.0 true true 0 (\362)]
+XYsave
+[(Helvetica) 80.0 -48.0 true true 0 (0)]
+XYrestore
+[(Helvetica) 80.0 80.0 true true 0 (x)]
+[(Helvetica) 100.0 0.0 true true 0 ( e)]
+[(Helvetica) 80.0 50.0 true true 0 (-t)]
+[(Helvetica) 64.0 90.0 true true 0 (2)]
+[(Helvetica) 100.0 0.0 true true 0 ( dt)]
+[(Helvetica) 100.0 0.0 true true 0 ( = 0.6175)]
+] -53.3 MLshow
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Symbol Helvetica
diff --git a/doc/interpreter/extended.pdf b/doc/interpreter/extended.pdf
new file mode 100644
index 0000000..7688329
Binary files /dev/null and b/doc/interpreter/extended.pdf differ
diff --git a/doc/interpreter/extended.png b/doc/interpreter/extended.png
new file mode 100644
index 0000000..cf4b7cd
Binary files /dev/null and b/doc/interpreter/extended.png differ
diff --git a/doc/interpreter/extended.txt b/doc/interpreter/extended.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/extended.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/fn-idx.texi b/doc/interpreter/fn-idx.texi
new file mode 100644
index 0000000..f4731c0
--- /dev/null
+++ b/doc/interpreter/fn-idx.texi
@@ -0,0 +1,24 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Function Index
+ at unnumbered Function Index
+
+ at printindex fn
diff --git a/doc/interpreter/fn-idx.txi b/doc/interpreter/fn-idx.txi
new file mode 100644
index 0000000..cc01d98
--- /dev/null
+++ b/doc/interpreter/fn-idx.txi
@@ -0,0 +1,22 @@
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Function Index
+ at unnumbered Function Index
+
+ at printindex fn
diff --git a/doc/interpreter/func.texi b/doc/interpreter/func.texi
new file mode 100644
index 0000000..59058b3
--- /dev/null
+++ b/doc/interpreter/func.texi
@@ -0,0 +1,1926 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Functions and Scripts
+ at chapter Functions and Scripts
+ at cindex defining functions
+ at cindex user-defined functions
+ at cindex functions, user-defined
+ at cindex script files
+
+Complicated Octave programs can often be simplified by defining
+functions.  Functions can be defined directly on the command line during
+interactive Octave sessions, or in external files, and can be called just
+like built-in functions.
+
+ at menu
+* Defining Functions::          
+* Multiple Return Values::      
+* Variable-length Argument Lists::  
+* Variable-length Return Lists::  
+* Returning From a Function::   
+* Default Arguments::   
+* Function Files::              
+* Script Files::                
+* Function Handles Inline Functions and Anonymous Functions::
+* Commands::
+* Organization of Functions::   
+ at end menu
+
+ at node Defining Functions
+ at section Defining Functions
+ at cindex @code{function} statement
+ at cindex @code{endfunction} statement
+
+In its simplest form, the definition of a function named @var{name}
+looks like this:
+
+ at example
+ at group
+function @var{name}
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+A valid function name is like a valid variable name: a sequence of
+letters, digits and underscores, not starting with a digit.  Functions
+share the same pool of names as variables.
+
+The function @var{body} consists of Octave statements.  It is the
+most important part of the definition, because it says what the function
+should actually @emph{do}.
+
+For example, here is a function that, when executed, will ring the bell
+on your terminal (assuming that it is possible to do so):
+
+ at example
+ at group
+function wakeup
+  printf ("\a");
+endfunction
+ at end group
+ at end example
+
+The @code{printf} statement (@pxref{Input and Output}) simply tells
+Octave to print the string @code{"\a"}.  The special character @samp{\a}
+stands for the alert character (ASCII 7).  @xref{Strings}.
+
+Once this function is defined, you can ask Octave to evaluate it by
+typing the name of the function.
+
+Normally, you will want to pass some information to the functions you
+define.  The syntax for passing parameters to a function in Octave is
+
+ at example
+ at group
+function @var{name} (@var{arg-list})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+where @var{arg-list} is a comma-separated list of the function's
+arguments.  When the function is called, the argument names are used to
+hold the argument values given in the call.  The list of arguments may
+be empty, in which case this form is equivalent to the one shown above.
+
+To print a message along with ringing the bell, you might modify the
+ at code{wakeup} to look like this:
+
+ at example
+ at group
+function wakeup (message)
+  printf ("\a%s\n", message);
+endfunction
+ at end group
+ at end example
+
+Calling this function using a statement like this
+
+ at example
+wakeup ("Rise and shine!");
+ at end example
+
+ at noindent
+will cause Octave to ring your terminal's bell and print the message
+ at samp{Rise and shine!}, followed by a newline character (the @samp{\n}
+in the first argument to the @code{printf} statement).
+
+In most cases, you will also want to get some information back from the
+functions you define.  Here is the syntax for writing a function that
+returns a single value:
+
+ at example
+ at group
+function @var{ret-var} = @var{name} (@var{arg-list})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+The symbol @var{ret-var} is the name of the variable that will hold the
+value to be returned by the function.  This variable must be defined
+before the end of the function body in order for the function to return
+a value.
+
+Variables used in the body of a function are local to the
+function.  Variables named in @var{arg-list} and @var{ret-var} are also
+local to the function.  @xref{Global Variables}, for information about
+how to access global variables inside a function.
+
+For example, here is a function that computes the average of the
+elements of a vector:
+
+ at example
+ at group
+function retval = avg (v)
+  retval = sum (v) / length (v);
+endfunction
+ at end group
+ at end example
+
+If we had written @code{avg} like this instead,
+
+ at example
+ at group
+function retval = avg (v)
+  if (isvector (v))
+    retval = sum (v) / length (v);
+  endif
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and then called the function with a matrix instead of a vector as the
+argument, Octave would have printed an error message like this:
+
+ at example
+ at group
+error: value on right hand side of assignment is undefined
+ at end group
+ at end example
+
+ at noindent
+because the body of the @code{if} statement was never executed, and
+ at code{retval} was never defined.  To prevent obscure errors like this,
+it is a good idea to always make sure that the return variables will
+always have values, and to produce meaningful error messages when
+problems are encountered.  For example, @code{avg} could have been
+written like this:
+
+ at example
+ at group
+function retval = avg (v)
+  retval = 0;
+  if (isvector (v))
+    retval = sum (v) / length (v);
+  else
+    error ("avg: expecting vector argument");
+  endif
+endfunction
+ at end group
+ at end example
+
+There is still one additional problem with this function.  What if it is
+called without an argument?  Without additional error checking, Octave
+will probably print an error message that won't really help you track
+down the source of the error.  To allow you to catch errors like this,
+Octave provides each function with an automatic variable called
+ at code{nargin}.  Each time a function is called, @code{nargin} is
+automatically initialized to the number of arguments that have actually
+been passed to the function.  For example, we might rewrite the
+ at code{avg} function like this:
+
+ at example
+ at group
+function retval = avg (v)
+  retval = 0;
+  if (nargin != 1)
+    usage ("avg (vector)");
+  endif
+  if (isvector (v))
+    retval = sum (v) / length (v);
+  else
+    error ("avg: expecting vector argument");
+  endif
+endfunction
+ at end group
+ at end example
+
+Although Octave does not automatically report an error if you call a
+function with more arguments than expected, doing so probably indicates
+that something is wrong.  Octave also does not automatically report an
+error if a function is called with too few arguments, but any attempt to
+use a variable that has not been given a value will result in an error.
+To avoid such problems and to provide useful messages, we check for both
+possibilities and issue our own error message.
+
+ at c ov-usr-fcn.cc
+ at anchor{doc-nargin}
+ at deftypefn {Built-in Function} {} nargin ()
+ at deftypefnx {Built-in Function} {} nargin (@var{fcn_name})
+Within a function, return the number of arguments passed to the function.
+At the top level, return the number of command line arguments passed to
+Octave.  If called with the optional argument @var{fcn_name}, return the
+maximum number of arguments the named function can accept, or -1 if the
+function accepts a variable number of arguments.
+ at seealso{@ref{doc-nargout,,nargout}, @ref{doc-varargin,,varargin}, @ref{doc-varargout,,varargout}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/inputname.m
+ at anchor{doc-inputname}
+ at deftypefn {Function File} {} inputname (@var{n})
+Return the text defining @var{n}-th input to the function.
+ at end deftypefn
+
+
+ at c pt-eval.cc
+ at anchor{doc-silent_functions}
+ at deftypefn {Built-in Function} {@var{val} =} silent_functions ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} silent_functions (@var{new_val})
+Query or set the internal variable that controls whether internal
+output from a function is suppressed.  If this option is disabled,
+Octave will display the results produced by evaluating expressions
+within a function body that are not terminated with a semicolon.
+ at end deftypefn
+
+
+ at node Multiple Return Values
+ at section Multiple Return Values
+
+Unlike many other computer languages, Octave allows you to define
+functions that return more than one value.  The syntax for defining
+functions that return multiple values is
+
+ at example
+ at group
+function [@var{ret-list}] = @var{name} (@var{arg-list})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+where @var{name}, @var{arg-list}, and @var{body} have the same meaning
+as before, and @var{ret-list} is a comma-separated list of variable
+names that will hold the values returned from the function.  The list of
+return values must have at least one element.  If @var{ret-list} has
+only one element, this form of the @code{function} statement is
+equivalent to the form described in the previous section.
+
+Here is an example of a function that returns two values, the maximum
+element of a vector and the index of its first occurrence in the vector.
+
+ at example
+ at group
+function [max, idx] = vmax (v)
+  idx = 1;
+  max = v (idx);
+  for i = 2:length (v)
+    if (v (i) > max)
+      max = v (i);
+      idx = i;
+    endif
+  endfor
+endfunction
+ at end group
+ at end example
+
+In this particular case, the two values could have been returned as
+elements of a single array, but that is not always possible or
+convenient.  The values to be returned may not have compatible
+dimensions, and it is often desirable to give the individual return
+values distinct names.
+
+In addition to setting @code{nargin} each time a function is called,
+Octave also automatically initializes @code{nargout} to the number of
+values that are expected to be returned.  This allows you to write
+functions that behave differently depending on the number of values that
+the user of the function has requested.  The implicit assignment to the
+built-in variable @code{ans} does not figure in the count of output
+arguments, so the value of @code{nargout} may be zero.
+
+The @code{svd} and @code{lu} functions are examples of built-in
+functions that behave differently depending on the value of
+ at code{nargout}.
+
+It is possible to write functions that only set some return values.  For
+example, calling the function
+
+ at example
+ at group
+function [x, y, z] = f ()
+  x = 1;
+  z = 2;
+endfunction
+ at end group
+ at end example
+
+ at noindent
+as
+
+ at example
+[a, b, c] = f ()
+ at end example
+
+ at noindent
+produces:
+
+ at example
+ at group
+a = 1
+
+b = [](0x0)
+
+c = 2
+ at end group
+ at end example
+
+ at noindent
+along with a warning.
+
+ at c ov-usr-fcn.cc
+ at anchor{doc-nargout}
+ at deftypefn {Built-in Function} {} nargout ()
+ at deftypefnx {Built-in Function} {} nargout (@var{fcn_name})
+Within a function, return the number of values the caller expects to
+receive.  If called with the optional argument @var{fcn_name}, return the
+maximum number of values the named function can produce, or -1 if the
+function can produce a variable number of values.
+
+For example,
+
+ at example
+f ()
+ at end example
+
+ at noindent
+will cause @code{nargout} to return 0 inside the function @code{f} and
+
+ at example
+[s, t] = f ()
+ at end example
+
+ at noindent
+will cause @code{nargout} to return 2 inside the function
+ at code{f}.
+
+At the top level, @code{nargout} is undefined.
+ at seealso{@ref{doc-nargin,,nargin}, @ref{doc-varargin,,varargin}, @ref{doc-varargout,,varargout}}
+ at end deftypefn
+
+
+ at c ./general/nargchk.m
+ at anchor{doc-nargchk}
+ at deftypefn {Function File} {@var{msgstr} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs})
+ at deftypefnx {Function File} {@var{msgstr} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string")
+ at deftypefnx {Function File} {@var{msgstruct} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct")
+Return an appropriate error message string (or structure) if the
+number of inputs requested is invalid.
+
+This is useful for checking to see that the number of input arguments
+supplied to a function is within an acceptable range.
+ at seealso{@ref{doc-nargoutchk,,nargoutchk}, @ref{doc-error,,error}, @ref{doc-nargin,,nargin}, @ref{doc-nargout,,nargout}}
+ at end deftypefn
+
+
+ at c ./general/nargoutchk.m
+ at anchor{doc-nargoutchk}
+ at deftypefn {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs})
+ at deftypefnx {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string")
+ at deftypefnx {Function File} {@var{msgstruct} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct")
+Return an appropriate error message string (or structure) if the
+number of outputs requested is invalid.
+
+This is useful for checking to see that the number of output
+arguments supplied to a function is within an acceptable range.
+ at seealso{@ref{doc-nargchk,,nargchk}, @ref{doc-error,,error}, @ref{doc-nargout,,nargout}, @ref{doc-nargin,,nargin}}
+ at end deftypefn
+
+
+ at anchor{doc-varargin} @anchor{doc-varargout}
+ at node Variable-length Argument Lists
+ at section Variable-length Argument Lists
+ at cindex variable-length argument lists
+ at cindex @code{varargin}
+
+Sometimes the number of input arguments is not known when the function
+is defined.  As an example think of a function that returns the smallest
+of all its input arguments.  For example,
+
+ at example
+ at group
+a = smallest (1, 2, 3);
+b = smallest (1, 2, 3, 4);
+ at end group
+ at end example
+
+ at noindent
+In this example both @code{a} and @code{b} would be 1.  One way to write
+the @code{smallest} function is
+
+ at example
+ at group
+function val = smallest (arg1, arg2, arg3, arg4, arg5)
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and then use the value of @code{nargin} to determine which of the input
+arguments should be considered.  The problem with this approach is
+that it can only handle a limited number of input arguments.
+
+If the special parameter name @code{varargin} appears at the end of a
+function parameter list it indicates that the function takes a variable
+number of input arguments.  Using @code{varargin} the function
+looks like this
+
+ at example
+ at group
+function val = smallest (varargin)
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+In the function body the input arguments can be accessed through the
+variable @code{varargin}.  This variable is a cell array containing
+all the input arguments.  @xref{Cell Arrays}, for details on working
+with cell arrays.  The @code{smallest} function can now be defined
+like this
+
+ at example
+ at group
+function val = smallest (varargin)
+  val = min ([varargin@{:@}]);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+This implementation handles any number of input arguments, but it's also
+a very simple solution to the problem.
+
+A slightly more complex example of @code{varargin} is a function 
+ at code{print_arguments} that prints all input arguments.  Such a function
+can be defined like this
+
+ at example
+ at group
+function print_arguments (varargin)
+  for i = 1:length (varargin)
+    printf ("Input argument %d: ", i);
+    disp (varargin@{i@});
+  endfor
+endfunction
+ at end group
+ at end example
+
+ at noindent
+This function produces output like this
+
+ at example
+ at group
+print_arguments (1, "two", 3);
+     @print{} Input argument 1:  1
+     @print{} Input argument 2: two
+     @print{} Input argument 3:  3
+ at end group
+ at end example
+
+ at c ./miscellaneous/parseparams.m
+ at anchor{doc-parseparams}
+ at deftypefn {Function File} {[@var{reg}, @var{prop}] =} parseparams (@var{params})
+Return in @var{reg} the cell elements of @var{param} up to the first
+string element and in @var{prop} all remaining elements beginning
+with the first string element.  For example 
+
+ at example
+ at group
+[reg, prop] = parseparams (@{1, 2, "linewidth", 10@})
+reg =
+@{
+  [1,1] = 1
+  [1,2] = 2
+@}
+prop =
+@{
+  [1,1] = linewidth
+  [1,2] = 10
+@}
+ at end group
+ at end example
+
+The parseparams function may be used to separate 'regular'
+arguments and additional arguments given as property/value pairs of
+the @var{varargin} cell array.
+ at seealso{@ref{doc-varargin,,varargin}}
+ at end deftypefn
+
+
+ at node Variable-length Return Lists
+ at section Variable-length Return Lists
+ at cindex variable-length return lists
+ at cindex @code{varargout}
+
+It is possible to return a variable number of output arguments from a
+function using a syntax that's similar to the one used with the
+special @code{varargin} parameter name.  To let a function return a
+variable number of output arguments the special output parameter name
+ at code{varargout} is used.  As with @code{varargin}, @code{varargout} is
+a cell array that will contain the requested output arguments.
+
+As an example the following function sets the first output argument to
+1, the second to 2, and so on.
+
+ at example
+ at group
+function varargout = one_to_n ()
+  for i = 1:nargout
+    varargout@{i@} = i;
+  endfor
+endfunction
+ at end group
+ at end example
+
+ at noindent
+When called this function returns values like this
+
+ at example
+ at group
+[a, b, c] = one_to_n ()
+     @result{} a =  1
+     @result{} b =  2
+     @result{} c =  3
+ at end group
+ at end example
+
+If @code{varargin} (@code{varargout}) does not appear as the last
+element of the input (output) parameter list, then it is not special,
+and is handled the same as any other parameter name.
+
+ at c ./general/deal.m
+ at anchor{doc-deal}
+ at deftypefn {Function File} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} deal (@var{a})
+ at deftypefnx {Function File} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} deal (@var{a1}, @var{a2}, @dots{}, @var{an})
+
+Copy the input parameters into the corresponding output parameters.
+If only one input parameter is supplied, its value is copied to each
+of the outputs.
+
+For example,
+
+ at example
+[a, b, c] = deal (x, y, z);
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+ at group
+a = x;
+b = y;
+c = z;
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+[a, b, c] = deal (x);
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+a = b = c = x;
+ at end example
+ at end deftypefn
+
+
+ at node Returning From a Function
+ at section Returning From a Function
+
+The body of a user-defined function can contain a @code{return} statement.
+This statement returns control to the rest of the Octave program.  It
+looks like this:
+
+ at example
+return
+ at end example
+
+Unlike the @code{return} statement in C, Octave's @code{return}
+statement cannot be used to return a value from a function.  Instead,
+you must assign values to the list of return variables that are part of
+the @code{function} statement.  The @code{return} statement simply makes
+it easier to exit a function from a deeply nested loop or conditional
+statement.
+
+Here is an example of a function that checks to see if any elements of a
+vector are nonzero.
+
+ at example
+ at group
+function retval = any_nonzero (v)
+  retval = 0;
+  for i = 1:length (v)
+    if (v (i) != 0)
+      retval = 1;
+      return;
+    endif
+  endfor
+  printf ("no nonzero elements found\n");
+endfunction
+ at end group
+ at end example
+
+Note that this function could not have been written using the
+ at code{break} statement to exit the loop once a nonzero value is found
+without adding extra logic to avoid printing the message if the vector
+does contain a nonzero element.
+
+ at deffn {Keyword} return
+When Octave encounters the keyword @code{return} inside a function or
+script, it returns control to the caller immediately.  At the top level,
+the return statement is ignored.  A @code{return} statement is assumed
+at the end of every function definition.
+ at end deffn
+
+ at node Default Arguments
+ at section Default Arguments
+ at cindex default arguments
+
+Since Octave supports variable number of input arguments, it is very useful
+to assign default values to some input arguments.  When an input argument
+is declared in the argument list it is possible to assign a default
+value to the argument like this
+
+ at example
+ at group
+function @var{name} (@var{arg1} = @var{val1}, @dots{})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+If no value is assigned to @var{arg1} by the user, it will have the
+value @var{val1}.
+
+As an example, the following function implements a variant of the classic
+``Hello, World'' program.
+ at example
+ at group
+function hello (who = "World")
+  printf ("Hello, %s!\n", who);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+When called without an input argument the function prints the following
+ at example
+ at group
+hello ();
+     @print{} Hello, World!
+ at end group
+ at end example
+
+ at noindent
+and when it's called with an input argument it prints the following
+ at example
+ at group
+hello ("Beautiful World of Free Software");
+     @print{} Hello, Beautiful World of Free Software!
+ at end group
+ at end example
+
+Sometimes it is useful to explicitly tell Octave to use the default value
+of an input argument.  This can be done writing a @samp{:} as the value
+of the input argument when calling the function.
+ at example
+ at group
+hello (:);
+     @print{} Hello, World!
+ at end group
+ at end example
+
+ at node Function Files
+ at section Function Files
+ at cindex function file
+
+Except for simple one-shot programs, it is not practical to have to
+define all the functions you need each time you need them.  Instead, you
+will normally want to save them in a file so that you can easily edit
+them, and save them for use at a later time.
+
+Octave does not require you to load function definitions from files
+before using them.  You simply need to put the function definitions in a
+place where Octave can find them.
+
+When Octave encounters an identifier that is undefined, it first looks
+for variables or functions that are already compiled and currently
+listed in its symbol table.  If it fails to find a definition there, it
+searches a list of directories (the @dfn{path}) for files ending in
+ at file{.m} that have the same base name as the undefined
+identifier. at footnote{The @samp{.m} suffix was chosen for compatibility
+with @sc{matlab}.}  Once Octave finds a file with a name that matches,
+the contents of the file are read.  If it defines a @emph{single}
+function, it is compiled and executed.  @xref{Script Files}, for more
+information about how you can define more than one function in a single
+file.
+
+When Octave defines a function from a function file, it saves the full
+name of the file it read and the time stamp on the file.  If the time
+stamp on the file changes, Octave may reload the file.  When Octave is
+running interactively, time stamp checking normally happens at most once
+each time Octave prints the prompt.  Searching for new function
+definitions also occurs if the current working directory changes.
+
+Checking the time stamp allows you to edit the definition of a function
+while Octave is running, and automatically use the new function
+definition without having to restart your Octave session.
+
+To avoid degrading performance unnecessarily by checking the time stamps
+on functions that are not likely to change, Octave assumes that function
+files in the directory tree
+ at file{@var{octave-home}/share/octave/@var{version}/m}
+will not change, so it doesn't have to check their time stamps every time the
+functions defined in those files are used.  This is normally a very good
+assumption and provides a significant improvement in performance for the
+function files that are distributed with Octave.
+
+If you know that your own function files will not change while you are
+running Octave, you can improve performance by calling
+ at code{ignore_function_time_stamp ("all")}, so that Octave will
+ignore the time stamps for all function files.  Passing
+ at code{"system"} to this function resets the default behavior.
+
+ at c FIXME -- note about time stamps on files in NFS environments?
+
+ at c ./miscellaneous/edit.m
+ at anchor{doc-edit}
+ at deftypefn {Command} edit @var{name}
+ at deftypefnx {Command} edit @var{field} @var{value}
+ at deftypefnx {Command} {@var{value} =} edit get @var{field}
+Edit the named function, or change editor settings.
+
+If @code{edit} is called with the name of a file or function as
+its argument it will be opened in a text editor.
+
+ at itemize @bullet
+ at item
+If the function @var{name} is available in a file on your path and
+that file is modifiable, then it will be edited in place.  If it 
+is a system function, then it will first be copied to the directory
+ at code{HOME} (see further down) and then edited.  
+If no file is found, then the m-file 
+variant, ending with ".m", will be considered.  If still no file
+is found, then variants with a leading "@@" and then with both a
+leading "@@" and trailing ".m" will be considered.
+
+ at item
+If @var{name} is the name of a function defined in the interpreter but 
+not in an m-file, then an m-file will be created in @code{HOME}
+to contain that function along with its current definition.  
+
+ at item
+If @code{name.cc} is specified, then it will search for @code{name.cc}
+in the path and try to modify it, otherwise it will create a new
+ at file{.cc} file in @code{HOME}.  If @var{name} happens to be an
+m-file or interpreter defined function, then the text of that
+function will be inserted into the .cc file as a comment.
+
+ at item
+If @var{name.ext} is on your path then it will be edited, otherwise
+the editor will be started with @file{HOME/name.ext} as the
+filename.  If @file{name.ext} is not modifiable, it will be copied to
+ at code{HOME} before editing.
+
+ at strong{WARNING!} You may need to clear name before the new definition
+is available.  If you are editing a .cc file, you will need
+to mkoctfile @file{name.cc} before the definition will be available.
+ at end itemize
+
+If @code{edit} is called with @var{field} and @var{value} variables,
+the value of the control field @var{field} will be @var{value}.
+If an output argument is requested and the first argument is @code{get}
+then @code{edit} will return the value of the control field @var{field}.
+If the control field does not exist, edit will return a structure 
+containing all fields and values.  Thus, @code{edit get all} returns
+a complete control structure.
+The following control fields are used:
+
+ at table @samp
+ at item editor
+This is the editor to use to modify the functions.  By default it uses
+Octave's @code{EDITOR} built-in function, which comes from 
+ at code{getenv("EDITOR")} and defaults to @code{emacs}.  Use @code{%s}
+In place of the function name.  For example,
+ at table @samp
+ at item [EDITOR, " %s"]
+Use the editor which Octave uses for @code{bug_report}.
+ at item "xedit %s &"           
+pop up simple X11 editor in a separate window
+ at item "gnudoit -q \"(find-file \\\"%s\\\")\""   
+Send it to current Emacs; must have @code{(gnuserv-start)} in @file{.emacs}.
+ at end table
+
+See also field 'mode', which controls how the editor is run by Octave.
+
+On Cygwin, you will need to convert the Cygwin path to a Windows
+path if you are using a native Windows editor.  For example
+ at c Set example in small font to prevent overfull line
+ at smallexample
+'"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+ at end smallexample
+
+ at item home
+This is the location of user local m-files.  Be be sure it is in your
+path.  The default is @file{~/octave}.
+
+ at item author
+This is the name to put after the "## Author:" field of new functions.
+By default it guesses from the @code{gecos} field of password database.
+
+ at item email
+This is the e-mail address to list after the name in the author field.
+By default it guesses @code{<$LOGNAME@@$HOSTNAME>}, and if @code{$HOSTNAME}
+is not defined it uses @code{uname -n}.  You probably want to override this.
+Be sure to use @code{<user@@host>} as your format.
+
+ at item license
+ at table @samp
+ at item gpl
+GNU General Public License (default).
+ at item bsd
+BSD-style license without advertising clause.
+ at item pd
+Public domain.
+ at item "text"
+Your own default copyright and license.
+ at end table
+
+Unless you specify @samp{pd}, edit will prepend the copyright statement 
+with "Copyright (C) yyyy Function Author".
+
+ at item mode
+This value determines whether the editor should be started in async mode
+(editor is started in the background and Octave continues) or sync mode
+(Octave waits until the editor exits).  Set it to "async" to start the editor
+in async mode.  The default is "sync" (see also "system").
+
+ at item editinplace
+Determines whether files should be edited in place, without regard to 
+whether they are modifiable or not.  The default is @code{false}.
+ at end table
+ at end deftypefn
+
+
+ at c parse.cc
+ at anchor{doc-mfilename}
+ at deftypefn {Built-in Function} {} mfilename ()
+ at deftypefnx {Built-in Function} {} mfilename (@code{"fullpath"})
+ at deftypefnx {Built-in Function} {} mfilename (@code{"fullpathext"})
+Return the name of the currently executing file.  At the top-level,
+return the empty string.  Given the argument @code{"fullpath"},
+include the directory part of the file name, but not the extension.
+Given the argument @code{"fullpathext"}, include the directory part
+of the file name and the extension.
+ at end deftypefn
+
+
+ at c symtab.cc
+ at anchor{doc-ignore_function_time_stamp}
+ at deftypefn {Built-in Function} {@var{val} =} ignore_function_time_stamp ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})
+Query or set the internal variable that controls whether Octave checks
+the time stamp on files each time it looks up functions defined in
+function files.  If the internal variable is set to @code{"system"},
+Octave will not automatically recompile function files in subdirectories of
+ at file{@var{octave-home}/lib/@var{version}} if they have changed since
+they were last compiled, but will recompile other function files in the
+search path if they change.  If set to @code{"all"}, Octave will not
+recompile any function files unless their definitions are removed with
+ at code{clear}.  If set to "none", Octave will always check time stamps
+on files to determine whether functions defined in function files
+need to recompiled.
+ at end deftypefn
+
+
+ at menu
+* Manipulating the load path::
+* Subfunctions::
+* Private Functions::
+* Overloading and Autoloading::
+* Function Locking::
+* Function Precedence::
+ at end menu
+
+ at node Manipulating the load path
+ at subsection Manipulating the load path
+
+When a function is called, Octave searches a list of directories for
+a file that contains the function declaration.  This list of directories
+is known as the load path.  By default the load path contains
+a list of directories distributed with Octave plus the current
+working directory.  To see your current load path call the @code{path}
+function without any input or output arguments.
+
+It is possible to add or remove directories to or from the load path
+using @code{addpath} and @code{rmpath}.  As an example, the following
+code adds @samp{~/Octave} to the load path.
+
+ at example
+addpath("~/Octave")
+ at end example
+
+ at noindent
+After this the directory @samp{~/Octave} will be searched for functions.
+ 
+ at c load-path.cc
+ at anchor{doc-addpath}
+ at deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})
+ at deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})
+Add @var{dir1}, @dots{} to the current function search path.  If
+ at var{option} is @samp{"-begin"} or 0 (the default), prepend the
+directory name to the current path.  If @var{option} is @samp{"-end"}
+or 1, append the directory name to the current path.
+Directories added to the path must exist.
+ at seealso{@ref{doc-path,,path}, @ref{doc-rmpath,,rmpath}, @ref{doc-genpath,,genpath}, @ref{doc-pathdef,,pathdef}, @ref{doc-savepath,,savepath}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c load-path.cc
+ at anchor{doc-genpath}
+ at deftypefn {Built-in Function} {} genpath (@var{dir})
+Return a path constructed from @var{dir} and all its subdirectories.
+ at end deftypefn
+
+
+ at c load-path.cc
+ at anchor{doc-rmpath}
+ at deftypefn {Built-in Function} {} rmpath (@var{dir1}, @dots{})
+Remove @var{dir1}, @dots{} from the current function search path.
+
+ at seealso{@ref{doc-path,,path}, @ref{doc-addpath,,addpath}, @ref{doc-genpath,,genpath}, @ref{doc-pathdef,,pathdef}, @ref{doc-savepath,,savepath}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c ./path/savepath.m
+ at anchor{doc-savepath}
+ at deftypefn {Function File} {} savepath (@var{file})
+Save the portion of the current function search path, that is
+not set during Octave's initialization process, to @var{file}.
+If @var{file} is omitted, @file{~/.octaverc} is used.  If successful,
+ at code{savepath} returns 0.
+ at seealso{@ref{doc-path,,path}, @ref{doc-addpath,,addpath}, @ref{doc-rmpath,,rmpath}, @ref{doc-genpath,,genpath}, @ref{doc-pathdef,,pathdef}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c load-path.cc
+ at anchor{doc-path}
+ at deftypefn {Built-in Function} {} path (@dots{})
+Modify or display Octave's load path.
+
+If @var{nargin} and @var{nargout} are zero, display the elements of
+Octave's load path in an easy to read format.
+
+If @var{nargin} is zero and nargout is greater than zero, return the
+current load path.
+
+If @var{nargin} is greater than zero, concatenate the arguments,
+separating them with @code{pathsep()}.  Set the internal search path
+to the result and return it.
+
+No checks are made for duplicate elements.
+ at seealso{@ref{doc-addpath,,addpath}, @ref{doc-rmpath,,rmpath}, @ref{doc-genpath,,genpath}, @ref{doc-pathdef,,pathdef}, @ref{doc-savepath,,savepath}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c ./path/pathdef.m
+ at anchor{doc-pathdef}
+ at deftypefn {Function File} {@var{val} =} pathdef ()
+Return the default path for Octave.
+The path information is extracted from one of three sources.
+In order of preference, those are;
+
+ at enumerate
+ at item @file{~/.octaverc}
+ at item @file{<octave-home>/@dots{}/<version>/m/startup/octaverc}
+ at item Octave's path prior to changes by any octaverc.
+ at end enumerate
+ at seealso{@ref{doc-path,,path}, @ref{doc-addpath,,addpath}, @ref{doc-rmpath,,rmpath}, @ref{doc-genpath,,genpath}, @ref{doc-savepath,,savepath}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-pathsep}
+ at deftypefn {Built-in Function} {@var{val} =} pathsep ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} pathsep (@var{new_val})
+Query or set the character used to separate directories in
+a path.
+ at seealso{@ref{doc-filesep,,filesep}, @ref{doc-dir,,dir}, @ref{doc-ls,,ls}}
+ at end deftypefn
+
+
+ at c load-path.cc
+ at anchor{doc-rehash}
+ at deftypefn {Built-in Function} {} rehash ()
+Reinitialize Octave's load path directory cache.
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-file_in_loadpath}
+ at deftypefn {Built-in Function} {} file_in_loadpath (@var{file})
+ at deftypefnx {Built-in Function} {} file_in_loadpath (@var{file}, "all")
+
+Return the absolute name of @var{file} if it can be found in
+the list of directories specified by @code{path}.
+If no file is found, return an empty matrix.
+
+If the first argument is a cell array of strings, search each
+directory of the loadpath for element of the cell array and return
+the first that matches.
+
+If the second optional argument @code{"all"} is supplied, return
+a cell array containing the list of all files that have the same
+name in the path.  If no files are found, return an empty cell array.
+ at seealso{@ref{doc-file_in_path,,file_in_path}, @ref{doc-path,,path}}
+ at end deftypefn
+
+
+ at c load-path.cc
+ at anchor{doc-restoredefaultpath}
+ at deftypefn {Built-in Function} {} restoredefaultpath (@dots{})
+Restore Octave's path to it's initial state at startup.
+
+ at seealso{@ref{doc-path,,path}, @ref{doc-addpath,,addpath}, @ref{doc-rmpath,,rmpath}, @ref{doc-genpath,,genpath}, @ref{doc-pathdef,,pathdef}, @ref{doc-savepath,,savepath}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c load-path.cc
+ at anchor{doc-command_line_path}
+ at deftypefn {Built-in Function} {} command_line_path (@dots{})
+Return the command line path variable.
+
+ at seealso{@ref{doc-path,,path}, @ref{doc-addpath,,addpath}, @ref{doc-rmpath,,rmpath}, @ref{doc-genpath,,genpath}, @ref{doc-pathdef,,pathdef}, @ref{doc-savepath,,savepath}, @ref{doc-pathsep,,pathsep}}
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-find_dir_in_path}
+ at deftypefn {Built-in Function} {} find_dir_in_path (@var{dir})
+Return the full name of the path element matching @var{dir}.  The
+match is performed at the end of each path element.  For example, if
+ at var{dir} is @code{"foo/bar"}, it matches the path element
+ at code{"/some/dir/foo/bar"}, but not @code{"/some/dir/foo/bar/baz"}
+or @code{"/some/dir/allfoo/bar"}.
+ at end deftypefn
+
+
+ at node Subfunctions
+ at subsection Subfunctions
+
+A function file may contain secondary functions called
+ at dfn{subfunctions}.  These secondary functions are only visible to the
+other functions in the same function file.  For example, a file
+ at file{f.m} containing
+
+ at example
+ at group
+function f ()
+  printf ("in f, calling g\n");
+  g ()
+endfunction
+function g ()
+  printf ("in g, calling h\n");
+  h ()
+endfunction
+function h ()
+  printf ("in h\n")
+endfunction
+ at end group
+ at end example
+
+ at noindent
+defines a main function @code{f} and two subfunctions.  The
+subfunctions @code{g} and @code{h} may only be called from the main
+function @code{f} or from the other subfunctions, but not from outside
+the file @file{f.m}.
+
+ at node Private Functions
+ at subsection Private Functions
+
+In many cases one function needs to access one or more helper
+functions.  If the helper function is limited to the scope of a single
+function, then subfunctions as discussed above might be used.  However,
+if a single helper function is used by more than one function, then
+this is no longer possible.  In this case the helper functions might
+be placed in a subdirectory, called "private", of the directory in which
+the functions needing access to this helper function are found.
+
+As a simple example, consider a function @code{func1}, that calls a helper
+function @code{func2} to do much of the work.  For example
+
+ at example
+ at group
+function y = func1 (x)
+  y = func2 (x);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+Then if the path to @code{func1} is @code{<directory>/func1.m}, and if
+ at code{func2} is found in the directory @code{<directory>/private/func2.m}, 
+then @code{func2} is only available for use of the functions, like 
+ at code{func1}, that are found in @code{<directory>}.
+
+ at node Overloading and Autoloading
+ at subsection Overloading and Autoloading
+
+The @code{dispatch} function can be used to alias one function name to
+another.  It can be used to alias all calls to a particular function name
+to another function, or the alias can be limited to only a particular
+variable type.  Consider the example
+
+ at example
+ at group
+function y = spsin (x)
+  printf ("Calling spsin\n");
+  fflush(stdout);
+  y = spfun ("sin", x);
+endfunction
+
+dispatch ("sin", "spsin", "sparse matrix");
+y0 = sin(eye(3));
+y1 = sin(speye(3));
+ at end group
+ at end example
+
+ at noindent
+which aliases the user-defined function @code{spsin} to @code{sin}, but only for real sparse
+matrices.  Note that the builtin @code{sin} already correctly treats
+sparse matrices and so this example is only illustrative.
+
+ at c ./DLD-FUNCTIONS/dispatch.cc
+ at anchor{doc-dispatch}
+ at deftypefn {Loadable Function} {} dispatch (@var{f}, @var{r}, @var{type})
+
+Replace the function @var{f} with a dispatch so that function @var{r}
+is called when @var{f} is called with the first argument of the named
+ at var{type}.  If the type is @var{any} then call @var{r} if no other type
+matches.  The original function @var{f} is accessible using
+ at code{builtin (@var{f}, @dots{})}.
+
+If @var{r} is omitted, clear dispatch function associated with @var{type}.
+
+If both @var{r} and @var{type} are omitted, list dispatch functions
+for @var{f}.
+ at seealso{@ref{doc-builtin,,builtin}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dispatch.cc
+ at anchor{doc-builtin}
+ at deftypefn {Loadable Function} {[@dots{}]} builtin (@var{f}, @dots{})
+Call the base function @var{f} even if @var{f} is overloaded to
+some other function for the given type signature.
+ at seealso{@ref{doc-dispatch,,dispatch}}
+ at end deftypefn
+
+
+A single dynamically linked file might define several
+functions.  However, as Octave searches for functions based on the
+functions filename, Octave needs a manner in which to find each of the
+functions in the dynamically linked file.  On operating systems that
+support symbolic links, it is possible to create a symbolic link to the
+original file for each of the functions which it contains.
+
+However, there is at least one well known operating system that doesn't
+support symbolic links.  Making copies of the original file for each of
+the functions is undesirable as it increases the
+amount of disk space used by Octave.  Instead Octave supplies the
+ at code{autoload} function, that permits the user to define in which
+file a certain function will be found.
+
+ at c parse.cc
+ at anchor{doc-autoload}
+ at deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})
+Define @var{function} to autoload from @var{file}.
+
+The second argument, @var{file}, should be an absolute file name or
+a file name in the same directory as the function or script from which
+the autoload command was run.  @var{file} should not depend on the
+Octave load path.
+
+Normally, calls to @code{autoload} appear in PKG_ADD script files that
+are evaluated when a directory is added to the Octave's load path.  To
+avoid having to hardcode directory names in @var{file}, if @var{file}
+is in the same directory as the PKG_ADD script then
+
+ at example
+autoload ("foo", "bar.oct");
+ at end example
+
+will load the function @code{foo} from the file @code{bar.oct}.  The above
+when @code{bar.oct} is not in the same directory or uses like
+
+ at example
+autoload ("foo", file_in_loadpath ("bar.oct"))
+ at end example
+
+ at noindent
+are strongly discouraged, as their behavior might be unpredictable.
+
+With no arguments, return a structure containing the current autoload map.
+ at seealso{@ref{doc-PKG_ADD,,PKG_ADD}}
+ at end deftypefn
+
+
+ at node Function Locking
+ at subsection Function Locking
+
+It is sometime desirable to lock a function into memory with the
+ at code{mlock} function.  This is typically used for dynamically linked
+functions in Oct-files or mex-files that contain some initialization,
+and it is desirable that calling @code{clear} does not remove this
+initialization.
+
+As an example,
+
+ at example
+mlock ("my_function");
+ at end example
+
+ at noindent
+prevents @code{my_function} from being removed from memory, even if
+ at code{clear} is called.  It is possible to determine if a function is
+locked into memory with the @code{mislocked}, and to unlock a function
+with @code{munlock}, which the following illustrates.
+
+ at example
+ at group
+mlock ("my_function");
+mislocked ("my_function")
+ at result{} ans = 1
+munlock ("my_function");
+mislocked ("my_function")
+ at result{} ans = 0
+ at end group
+ at end example
+
+A common use of @code{mlock} is to prevent persistent variables from
+being removed from memory, as the following example shows:
+
+ at example
+ at group
+function count_calls()
+  persistent calls = 0;
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+mlock ("count_calls");
+
+count_calls ();
+ at print{} 'count_calls' has been called 1 times
+
+clear count_calls
+count_calls ();
+ at print{} 'count_calls' has been called 2 times
+ at end group
+ at end example
+
+ at noindent
+It is, however, often inconvenient to lock a function from the prompt,
+so it is also possible to lock a function from within its body.  This
+is simply done by calling @code{mlock} from within the function.
+
+ at example
+ at group
+function count_calls ()
+  mlock ();
+  persistent calls = 0;
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+ at end group
+ at end example
+
+ at code{mlock} might equally be used to prevent changes to a function from having
+effect in Octave, though a similar effect can be had with the
+ at code{ignore_function_time_stamp} function.
+
+ at c variables.cc
+ at anchor{doc-mlock}
+ at deftypefn {Built-in Function} {} mlock ()
+Lock the current function into memory so that it can't be cleared.
+ at seealso{@ref{doc-munlock,,munlock}, @ref{doc-mislocked,,mislocked}, @ref{doc-persistent,,persistent}}
+ at end deftypefn
+
+
+ at c variables.cc
+ at anchor{doc-munlock}
+ at deftypefn {Built-in Function} {} munlock (@var{fcn})
+Unlock the named function.  If no function is named
+then unlock the current function.
+ at seealso{@ref{doc-mlock,,mlock}, @ref{doc-mislocked,,mislocked}, @ref{doc-persistent,,persistent}}
+ at end deftypefn
+
+
+ at c variables.cc
+ at anchor{doc-mislocked}
+ at deftypefn {Built-in Function} {} mislocked (@var{fcn})
+Return true if the named function is locked.  If no function is named
+then return true if the current function is locked.
+ at seealso{@ref{doc-mlock,,mlock}, @ref{doc-munlock,,munlock}, @ref{doc-persistent,,persistent}}
+ at end deftypefn
+
+
+ at node Function Precedence
+ at subsection Function Precedence
+
+Given the numerous different ways that Octave can define a function, it
+is possible and even likely that multiple versions of a function, might be
+defined within a particular scope.  The precedence of which function will be
+used within a particular scope is given by
+
+ at enumerate 1
+ at item Subfunction
+A subfunction with the required function name in the given scope.
+
+ at item Private function
+A function defined within a private directory of the directory 
+which contains the current function.
+
+ at item Class constructor
+A function that constuctors a user class as defined in chapter 
+ at ref{Object Oriented Programming}.
+
+ at item Class method
+An overloaded function of a class as in chapter
+ at ref{Object Oriented Programming}.
+
+ at item Legacy Dispatch
+An overloaded function as defined by @xref{doc-dispatch}.
+
+ at item Command-line Function
+A function that has been defined on the command-line.
+
+ at item Autoload function
+A function that is marked as autoloaded with @xref{doc-autoload}.
+
+ at item A Function on the Path
+A function that can be found on the users load-path.  There can also be
+Oct-file, mex-file or m-file versions of this function and the precedence
+between these versions are in that order.
+
+ at item Built-in function
+A function that is builtin to Octave itself such as @code{numel},
+ at code{size}, etc.
+ at end enumerate
+
+ at node Script Files
+ at section Script Files
+
+A script file is a file containing (almost) any sequence of Octave
+commands.  It is read and evaluated just as if you had typed each
+command at the Octave prompt, and provides a convenient way to perform a
+sequence of commands that do not logically belong inside a function.
+
+Unlike a function file, a script file must @emph{not} begin with the
+keyword @code{function}.  If it does, Octave will assume that it is a
+function file, and that it defines a single function that should be
+evaluated as soon as it is defined.
+
+A script file also differs from a function file in that the variables
+named in a script file are not local variables, but are in the same
+scope as the other variables that are visible on the command line.
+
+Even though a script file may not begin with the @code{function}
+keyword, it is possible to define more than one function in a single
+script file and load (but not execute) all of them at once.  To do 
+this, the first token in the file (ignoring comments and other white
+space) must be something other than @code{function}.  If you have no
+other statements to evaluate, you can use a statement that has no
+effect, like this:
+
+ at example
+ at group
+# Prevent Octave from thinking that this
+# is a function file:
+
+1;
+
+# Define function one:
+
+function one ()
+  @dots{}
+ at end group
+ at end example
+
+To have Octave read and compile these functions into an internal form,
+you need to make sure that the file is in Octave's load path
+(accessible through the @code{path} function), then simply type the
+base name of the file that contains the commands.  (Octave uses the
+same rules to search for script files as it does to search for
+function files.)
+
+If the first token in a file (ignoring comments) is @code{function},
+Octave will compile the function and try to execute it, printing a
+message warning about any non-whitespace characters that appear after
+the function definition.
+
+Note that Octave does not try to look up the definition of any identifier
+until it needs to evaluate it.  This means that Octave will compile the
+following statements if they appear in a script file, or are typed at
+the command line,
+
+ at example
+ at group
+# not a function file:
+1;
+function foo ()
+  do_something ();
+endfunction
+function do_something ()
+  do_something_else ();
+endfunction
+ at end group
+ at end example
+
+ at noindent
+even though the function @code{do_something} is not defined before it is
+referenced in the function @code{foo}.  This is not an error because
+Octave does not need to resolve all symbols that are referenced by a
+function until the function is actually evaluated.
+
+Since Octave doesn't look for definitions until they are needed, the
+following code will always print @samp{bar = 3} whether it is typed
+directly on the command line, read from a script file, or is part of a
+function body, even if there is a function or script file called
+ at file{bar.m} in Octave's path.
+
+ at example
+ at group
+eval ("bar = 3");
+bar
+ at end group
+ at end example
+
+Code like this appearing within a function body could fool Octave if
+definitions were resolved as the function was being compiled.  It would
+be virtually impossible to make Octave clever enough to evaluate this
+code in a consistent fashion.  The parser would have to be able to
+perform the call to @code{eval} at compile time, and that would be
+impossible unless all the references in the string to be evaluated could
+also be resolved, and requiring that would be too restrictive (the
+string might come from user input, or depend on things that are not
+known until the function is evaluated).
+
+Although Octave normally executes commands from script files that have
+the name @file{@var{file}.m}, you can use the function @code{source} to
+execute commands from any file.
+
+ at c parse.cc
+ at anchor{doc-source}
+ at deftypefn {Built-in Function} {} source (@var{file})
+Parse and execute the contents of @var{file}.  This is equivalent to
+executing commands from a script file, but without requiring the file to
+be named @file{@var{file}.m}.
+ at end deftypefn
+
+
+ at node Function Handles Inline Functions and Anonymous Functions
+ at section Function Handles, Inline Functions, and Anonymous Functions
+ at cindex handle, function handles
+ at cindex inline, inline functions
+ at cindex anonymous functions
+
+It can be very convenient store a function in a variable so that it
+can be passed to a different function.  For example, a function that
+performs numerical minimization needs access to the function that 
+should be minimized.
+
+ at menu
+* Function Handles::
+* Anonymous Functions::
+* Inline Functions::
+ at end menu
+
+ at node Function Handles
+ at subsection Function Handles
+
+A function handle is a pointer to another function and is defined with
+the syntax
+
+ at example
+@@@var{function-name}
+ at end example
+
+ at noindent
+For example
+
+ at example
+f = @@sin;
+ at end example
+
+ at noindent
+Creates a function handle called @code{f} that refers to the
+function @code{sin}.
+
+Function handles are used to call other functions indirectly, or to pass
+a function as an argument to another function like @code{quad} or
+ at code{fsolve}.  For example
+
+ at example
+ at group
+f = @@sin;
+quad (f, 0, pi)
+    @result{} 2
+ at end group
+ at end example
+
+You may use @code{feval} to call a function using function handle, or
+simply write the name of the function handle followed by an argument
+list.  If there are no arguments, you must use an empty argument list
+ at samp{()}.  For example
+
+ at example
+ at group
+f = @@sin;
+feval (f, pi/4)
+    @result{} 0.70711
+f (pi/4)
+    @result{} 0.70711
+ at end group
+ at end example
+
+ at c ov-fcn-handle.cc
+ at anchor{doc-functions}
+ at deftypefn {Built-in Function} {} functions (@var{fcn_handle})
+Return a struct containing information about the function handle
+ at var{fcn_handle}.
+ at end deftypefn
+
+
+ at c ov-fcn-handle.cc
+ at anchor{doc-func2str}
+ at deftypefn {Built-in Function} {} func2str (@var{fcn_handle})
+Return a string containing the name of the function referenced by
+the function handle @var{fcn_handle}.
+ at end deftypefn
+
+
+ at c ov-fcn-handle.cc
+ at anchor{doc-str2func}
+ at deftypefn {Built-in Function} {} str2func (@var{fcn_name})
+Return a function handle constructed from the string @var{fcn_name}.
+ at end deftypefn
+
+
+ at node Anonymous Functions
+ at subsection Anonymous Functions
+
+Anonymous functions are defined using the syntax
+
+ at example
+@@(@var{argument-list}) @var{expression}
+ at end example
+
+ at noindent
+Any variables that are not found in the argument list are inherited from
+the enclosing scope.  Anonymous functions are useful for creating simple
+unnamed functions from expressions or for wrapping calls to other
+functions to adapt them for use by functions like @code{quad}.  For
+example,
+
+ at example
+ at group
+f = @@(x) x.^2;
+quad (f, 0, 10)
+    @result{} 333.33
+ at end group
+ at end example
+
+ at noindent
+creates a simple unnamed function from the expression @code{x.^2} and
+passes it to @code{quad},
+
+ at example
+ at group
+quad (@@(x) sin (x), 0, pi)
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+wraps another function, and
+
+ at example
+ at group
+a = 1;
+b = 2;
+quad (@@(x) betainc (x, a, b), 0, 0.4)
+    @result{} 0.13867
+ at end group
+ at end example
+
+ at noindent
+adapts a function with several parameters to the form required by
+ at code{quad}.  In this example, the values of @var{a} and @var{b} that
+are passed to @code{betainc} are inherited from the current
+environment.
+
+ at node Inline Functions
+ at subsection Inline Functions
+
+An inline function is created from a string containing the function
+body using the @code{inline} function.  The following code defines the
+function @math{f(x) = x^2 + 2}.
+
+ at example
+f = inline("x^2 + 2");
+ at end example
+
+ at noindent
+After this it is possible to evaluate @math{f} at any @math{x} by
+writing @code{f(x)}.
+
+ at c ov-fcn-inline.cc
+ at anchor{doc-inline}
+ at deftypefn {Built-in Function} {} inline (@var{str})
+ at deftypefnx {Built-in Function} {} inline (@var{str}, @var{arg1}, @dots{})
+ at deftypefnx {Built-in Function} {} inline (@var{str}, @var{n})
+Create an inline function from the character string @var{str}.
+If called with a single argument, the arguments of the generated
+function are extracted from the function itself.  The generated
+function arguments will then be in alphabetical order.  It should
+be noted that i, and j are ignored as arguments due to the
+ambiguity between their use as a variable or their use as an inbuilt
+constant.  All arguments followed by a parenthesis are considered
+to be functions.
+
+If the second and subsequent arguments are character strings,
+they are the names of the arguments of the function.
+
+If the second argument is an integer @var{n}, the arguments are
+ at code{"x"}, @code{"P1"}, @dots{}, @code{"P at var{N}"}.
+ at seealso{@ref{doc-argnames,,argnames}, @ref{doc-formula,,formula}, @ref{doc-vectorize,,vectorize}}
+ at end deftypefn
+
+
+ at c ov-fcn-inline.cc
+ at anchor{doc-argnames}
+ at deftypefn {Built-in Function} {} argnames (@var{fun})
+Return a cell array of character strings containing the names of
+the arguments of the inline function @var{fun}.
+ at seealso{@ref{doc-inline,,inline}, @ref{doc-formula,,formula}, @ref{doc-vectorize,,vectorize}}
+ at end deftypefn
+
+
+ at c ov-fcn-inline.cc
+ at anchor{doc-formula}
+ at deftypefn {Built-in Function} {} formula (@var{fun})
+Return a character string representing the inline function @var{fun}.
+Note that @code{char (@var{fun})} is equivalent to
+ at code{formula (@var{fun})}.
+ at seealso{@ref{doc-argnames,,argnames}, @ref{doc-inline,,inline}, @ref{doc-vectorize,,vectorize}}
+ at end deftypefn
+
+
+ at c ov-fcn-inline.cc
+ at anchor{doc-vectorize}
+ at deftypefn {Built-in Function} {} vectorize (@var{fun})
+Create a vectorized version of the inline function @var{fun}
+by replacing all occurrences of @code{*}, @code{/}, etc., with
+ at code{.*}, @code{./}, etc.
+ at end deftypefn
+
+
+ at c ./miscellaneous/symvar.m
+ at anchor{doc-symvar}
+ at deftypefn {Function File} {} symvar (@var{s})
+Identifies the argument names in the function defined by a string.
+Common constant names such as @code{pi}, @code{NaN}, @code{Inf},
+ at code{eps}, @code{i} or @code{j} are ignored.  The arguments that are
+found are returned in a cell array of strings.  If no variables are
+found then the returned cell array is empty.
+ at end deftypefn
+
+
+ at node Commands
+ at section Commands
+
+Commands are a special class of functions that only accept string
+input arguments.  A command can be called as an ordinary function, but
+it can also be called without the parentheses like the following example
+shows
+
+ at example
+my_command hello world
+ at end example
+
+ at noindent
+which is the same as
+
+ at example
+my_command("hello", "world")
+ at end example
+
+The general form of a command call is
+
+ at example
+ at var{name} @var{arg1} @var{arg2} @dots{}
+ at end example
+
+ at noindent
+which translates directly to
+
+ at example
+ at var{name} ("@var{arg1}", "@var{arg2}", @dots{})
+ at end example
+
+A function can be used as a command if it accepts string input arguments.
+To do this, the function must be marked as a command, which can be done
+with the @code{mark_as_command} command like this
+
+ at example
+mark_as_command name
+ at end example
+
+ at noindent
+where @code{name} is the function to be marked as a command.
+
+One difficulty of commands occurs when one of the string input arguments
+are stored in a variable.  Since Octave can't tell the difference between
+a variable name, and an ordinary string, it is not possible to pass a
+variable as input to a command.  In such a situation a command must be
+called as a function.
+
+ at c ./deprecated/mark_as_command.m
+ at anchor{doc-mark_as_command}
+ at deftypefn {Built-in Function} {} mark_as_command (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+
+
+ at c ./deprecated/unmark_command.m
+ at anchor{doc-unmark_command}
+ at deftypefn {Built-in Function} {} unmark_command (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+
+
+ at c ./deprecated/iscommand.m
+ at anchor{doc-iscommand}
+ at deftypefn {Built-in Function} {} iscommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+
+
+ at c ./deprecated/mark_as_rawcommand.m
+ at anchor{doc-mark_as_rawcommand}
+ at deftypefn {Built-in Function} {} mark_as_rawcommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+
+
+ at c ./deprecated/unmark_rawcommand.m
+ at anchor{doc-unmark_rawcommand}
+ at deftypefn {Built-in Function} {} unmark_rawcommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+
+
+ at c ./deprecated/israwcommand.m
+ at anchor{doc-israwcommand}
+ at deftypefn {Built-in Function} {} israwcommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+
+
+ at node Organization of Functions
+ at section Organization of Functions Distributed with Octave
+
+Many of Octave's standard functions are distributed as function files.
+They are loosely organized by topic, in subdirectories of
+ at file{@var{octave-home}/lib/octave/@var{version}/m}, to make it easier
+to find them.
+
+The following is a list of all the function file subdirectories, and the
+types of functions you will find there.
+
+ at table @file
+ at item audio
+Functions for playing and recording sounds.
+
+ at item control
+Functions for design and simulation of automatic control systems.
+
+ at item elfun
+Elementary functions.
+
+ at item finance
+Functions for computing interest payments, investment values, and rates
+of return.
+
+ at item general
+Miscellaneous matrix manipulations, like @code{flipud}, @code{rot90},
+and @code{triu}, as well as other basic functions, like
+ at code{ismatrix}, @code{nargchk}, etc.
+
+ at item image
+Image processing tools.  These functions require the X Window System.
+
+ at item io
+Input-output functions.
+
+ at item linear-algebra
+Functions for linear algebra.
+
+ at item miscellaneous
+Functions that don't really belong anywhere else.
+
+ at item optimization
+Minimization of functions.
+
+ at item path
+Functions to manage the directory path Octave uses to find functions.
+
+ at item pkg
+Install external packages of functions in Octave.
+
+ at item plot
+Functions for displaying and printing two- and three-dimensional graphs.
+
+ at item polynomial
+Functions for manipulating polynomials.
+
+ at item set
+Functions for creating and manipulating sets of unique values.
+
+ at item signal
+Functions for signal processing applications.
+
+ at item sparse
+Functions for handling sparse matrices.
+
+ at item specfun
+Special functions.
+
+ at item special-matrix
+Functions that create special matrix forms.
+
+ at item startup
+Octave's system-wide startup file.
+
+ at item statistics
+Statistical functions.
+
+ at item strings
+Miscellaneous string-handling functions.
+
+ at item testfun
+Perform unit tests on other functions.
+
+ at item time
+Functions related to time keeping.
+ at end table
diff --git a/doc/interpreter/func.txi b/doc/interpreter/func.txi
new file mode 100644
index 0000000..7db0f19
--- /dev/null
+++ b/doc/interpreter/func.txi
@@ -0,0 +1,1329 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Functions and Scripts
+ at chapter Functions and Scripts
+ at cindex defining functions
+ at cindex user-defined functions
+ at cindex functions, user-defined
+ at cindex script files
+
+Complicated Octave programs can often be simplified by defining
+functions.  Functions can be defined directly on the command line during
+interactive Octave sessions, or in external files, and can be called just
+like built-in functions.
+
+ at menu
+* Defining Functions::          
+* Multiple Return Values::      
+* Variable-length Argument Lists::  
+* Variable-length Return Lists::  
+* Returning From a Function::   
+* Default Arguments::   
+* Function Files::              
+* Script Files::                
+* Function Handles Inline Functions and Anonymous Functions::
+* Commands::
+* Organization of Functions::   
+ at end menu
+
+ at node Defining Functions
+ at section Defining Functions
+ at cindex @code{function} statement
+ at cindex @code{endfunction} statement
+
+In its simplest form, the definition of a function named @var{name}
+looks like this:
+
+ at example
+ at group
+function @var{name}
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+A valid function name is like a valid variable name: a sequence of
+letters, digits and underscores, not starting with a digit.  Functions
+share the same pool of names as variables.
+
+The function @var{body} consists of Octave statements.  It is the
+most important part of the definition, because it says what the function
+should actually @emph{do}.
+
+For example, here is a function that, when executed, will ring the bell
+on your terminal (assuming that it is possible to do so):
+
+ at example
+ at group
+function wakeup
+  printf ("\a");
+endfunction
+ at end group
+ at end example
+
+The @code{printf} statement (@pxref{Input and Output}) simply tells
+Octave to print the string @code{"\a"}.  The special character @samp{\a}
+stands for the alert character (ASCII 7).  @xref{Strings}.
+
+Once this function is defined, you can ask Octave to evaluate it by
+typing the name of the function.
+
+Normally, you will want to pass some information to the functions you
+define.  The syntax for passing parameters to a function in Octave is
+
+ at example
+ at group
+function @var{name} (@var{arg-list})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+where @var{arg-list} is a comma-separated list of the function's
+arguments.  When the function is called, the argument names are used to
+hold the argument values given in the call.  The list of arguments may
+be empty, in which case this form is equivalent to the one shown above.
+
+To print a message along with ringing the bell, you might modify the
+ at code{wakeup} to look like this:
+
+ at example
+ at group
+function wakeup (message)
+  printf ("\a%s\n", message);
+endfunction
+ at end group
+ at end example
+
+Calling this function using a statement like this
+
+ at example
+wakeup ("Rise and shine!");
+ at end example
+
+ at noindent
+will cause Octave to ring your terminal's bell and print the message
+ at samp{Rise and shine!}, followed by a newline character (the @samp{\n}
+in the first argument to the @code{printf} statement).
+
+In most cases, you will also want to get some information back from the
+functions you define.  Here is the syntax for writing a function that
+returns a single value:
+
+ at example
+ at group
+function @var{ret-var} = @var{name} (@var{arg-list})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+The symbol @var{ret-var} is the name of the variable that will hold the
+value to be returned by the function.  This variable must be defined
+before the end of the function body in order for the function to return
+a value.
+
+Variables used in the body of a function are local to the
+function.  Variables named in @var{arg-list} and @var{ret-var} are also
+local to the function.  @xref{Global Variables}, for information about
+how to access global variables inside a function.
+
+For example, here is a function that computes the average of the
+elements of a vector:
+
+ at example
+ at group
+function retval = avg (v)
+  retval = sum (v) / length (v);
+endfunction
+ at end group
+ at end example
+
+If we had written @code{avg} like this instead,
+
+ at example
+ at group
+function retval = avg (v)
+  if (isvector (v))
+    retval = sum (v) / length (v);
+  endif
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and then called the function with a matrix instead of a vector as the
+argument, Octave would have printed an error message like this:
+
+ at example
+ at group
+error: value on right hand side of assignment is undefined
+ at end group
+ at end example
+
+ at noindent
+because the body of the @code{if} statement was never executed, and
+ at code{retval} was never defined.  To prevent obscure errors like this,
+it is a good idea to always make sure that the return variables will
+always have values, and to produce meaningful error messages when
+problems are encountered.  For example, @code{avg} could have been
+written like this:
+
+ at example
+ at group
+function retval = avg (v)
+  retval = 0;
+  if (isvector (v))
+    retval = sum (v) / length (v);
+  else
+    error ("avg: expecting vector argument");
+  endif
+endfunction
+ at end group
+ at end example
+
+There is still one additional problem with this function.  What if it is
+called without an argument?  Without additional error checking, Octave
+will probably print an error message that won't really help you track
+down the source of the error.  To allow you to catch errors like this,
+Octave provides each function with an automatic variable called
+ at code{nargin}.  Each time a function is called, @code{nargin} is
+automatically initialized to the number of arguments that have actually
+been passed to the function.  For example, we might rewrite the
+ at code{avg} function like this:
+
+ at example
+ at group
+function retval = avg (v)
+  retval = 0;
+  if (nargin != 1)
+    usage ("avg (vector)");
+  endif
+  if (isvector (v))
+    retval = sum (v) / length (v);
+  else
+    error ("avg: expecting vector argument");
+  endif
+endfunction
+ at end group
+ at end example
+
+Although Octave does not automatically report an error if you call a
+function with more arguments than expected, doing so probably indicates
+that something is wrong.  Octave also does not automatically report an
+error if a function is called with too few arguments, but any attempt to
+use a variable that has not been given a value will result in an error.
+To avoid such problems and to provide useful messages, we check for both
+possibilities and issue our own error message.
+
+ at DOCSTRING(nargin)
+
+ at DOCSTRING(inputname)
+
+ at DOCSTRING(silent_functions)
+
+ at node Multiple Return Values
+ at section Multiple Return Values
+
+Unlike many other computer languages, Octave allows you to define
+functions that return more than one value.  The syntax for defining
+functions that return multiple values is
+
+ at example
+ at group
+function [@var{ret-list}] = @var{name} (@var{arg-list})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+where @var{name}, @var{arg-list}, and @var{body} have the same meaning
+as before, and @var{ret-list} is a comma-separated list of variable
+names that will hold the values returned from the function.  The list of
+return values must have at least one element.  If @var{ret-list} has
+only one element, this form of the @code{function} statement is
+equivalent to the form described in the previous section.
+
+Here is an example of a function that returns two values, the maximum
+element of a vector and the index of its first occurrence in the vector.
+
+ at example
+ at group
+function [max, idx] = vmax (v)
+  idx = 1;
+  max = v (idx);
+  for i = 2:length (v)
+    if (v (i) > max)
+      max = v (i);
+      idx = i;
+    endif
+  endfor
+endfunction
+ at end group
+ at end example
+
+In this particular case, the two values could have been returned as
+elements of a single array, but that is not always possible or
+convenient.  The values to be returned may not have compatible
+dimensions, and it is often desirable to give the individual return
+values distinct names.
+
+In addition to setting @code{nargin} each time a function is called,
+Octave also automatically initializes @code{nargout} to the number of
+values that are expected to be returned.  This allows you to write
+functions that behave differently depending on the number of values that
+the user of the function has requested.  The implicit assignment to the
+built-in variable @code{ans} does not figure in the count of output
+arguments, so the value of @code{nargout} may be zero.
+
+The @code{svd} and @code{lu} functions are examples of built-in
+functions that behave differently depending on the value of
+ at code{nargout}.
+
+It is possible to write functions that only set some return values.  For
+example, calling the function
+
+ at example
+ at group
+function [x, y, z] = f ()
+  x = 1;
+  z = 2;
+endfunction
+ at end group
+ at end example
+
+ at noindent
+as
+
+ at example
+[a, b, c] = f ()
+ at end example
+
+ at noindent
+produces:
+
+ at example
+ at group
+a = 1
+
+b = [](0x0)
+
+c = 2
+ at end group
+ at end example
+
+ at noindent
+along with a warning.
+
+ at DOCSTRING(nargout)
+
+ at DOCSTRING(nargchk)
+
+ at DOCSTRING(nargoutchk)
+
+ at anchor{doc-varargin} @anchor{doc-varargout}
+ at node Variable-length Argument Lists
+ at section Variable-length Argument Lists
+ at cindex variable-length argument lists
+ at cindex @code{varargin}
+
+Sometimes the number of input arguments is not known when the function
+is defined.  As an example think of a function that returns the smallest
+of all its input arguments.  For example,
+
+ at example
+ at group
+a = smallest (1, 2, 3);
+b = smallest (1, 2, 3, 4);
+ at end group
+ at end example
+
+ at noindent
+In this example both @code{a} and @code{b} would be 1.  One way to write
+the @code{smallest} function is
+
+ at example
+ at group
+function val = smallest (arg1, arg2, arg3, arg4, arg5)
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and then use the value of @code{nargin} to determine which of the input
+arguments should be considered.  The problem with this approach is
+that it can only handle a limited number of input arguments.
+
+If the special parameter name @code{varargin} appears at the end of a
+function parameter list it indicates that the function takes a variable
+number of input arguments.  Using @code{varargin} the function
+looks like this
+
+ at example
+ at group
+function val = smallest (varargin)
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+In the function body the input arguments can be accessed through the
+variable @code{varargin}.  This variable is a cell array containing
+all the input arguments.  @xref{Cell Arrays}, for details on working
+with cell arrays.  The @code{smallest} function can now be defined
+like this
+
+ at example
+ at group
+function val = smallest (varargin)
+  val = min ([varargin@{:@}]);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+This implementation handles any number of input arguments, but it's also
+a very simple solution to the problem.
+
+A slightly more complex example of @code{varargin} is a function 
+ at code{print_arguments} that prints all input arguments.  Such a function
+can be defined like this
+
+ at example
+ at group
+function print_arguments (varargin)
+  for i = 1:length (varargin)
+    printf ("Input argument %d: ", i);
+    disp (varargin@{i@});
+  endfor
+endfunction
+ at end group
+ at end example
+
+ at noindent
+This function produces output like this
+
+ at example
+ at group
+print_arguments (1, "two", 3);
+     @print{} Input argument 1:  1
+     @print{} Input argument 2: two
+     @print{} Input argument 3:  3
+ at end group
+ at end example
+
+ at DOCSTRING(parseparams)
+
+ at node Variable-length Return Lists
+ at section Variable-length Return Lists
+ at cindex variable-length return lists
+ at cindex @code{varargout}
+
+It is possible to return a variable number of output arguments from a
+function using a syntax that's similar to the one used with the
+special @code{varargin} parameter name.  To let a function return a
+variable number of output arguments the special output parameter name
+ at code{varargout} is used.  As with @code{varargin}, @code{varargout} is
+a cell array that will contain the requested output arguments.
+
+As an example the following function sets the first output argument to
+1, the second to 2, and so on.
+
+ at example
+ at group
+function varargout = one_to_n ()
+  for i = 1:nargout
+    varargout@{i@} = i;
+  endfor
+endfunction
+ at end group
+ at end example
+
+ at noindent
+When called this function returns values like this
+
+ at example
+ at group
+[a, b, c] = one_to_n ()
+     @result{} a =  1
+     @result{} b =  2
+     @result{} c =  3
+ at end group
+ at end example
+
+If @code{varargin} (@code{varargout}) does not appear as the last
+element of the input (output) parameter list, then it is not special,
+and is handled the same as any other parameter name.
+
+ at DOCSTRING(deal)
+
+ at node Returning From a Function
+ at section Returning From a Function
+
+The body of a user-defined function can contain a @code{return} statement.
+This statement returns control to the rest of the Octave program.  It
+looks like this:
+
+ at example
+return
+ at end example
+
+Unlike the @code{return} statement in C, Octave's @code{return}
+statement cannot be used to return a value from a function.  Instead,
+you must assign values to the list of return variables that are part of
+the @code{function} statement.  The @code{return} statement simply makes
+it easier to exit a function from a deeply nested loop or conditional
+statement.
+
+Here is an example of a function that checks to see if any elements of a
+vector are nonzero.
+
+ at example
+ at group
+function retval = any_nonzero (v)
+  retval = 0;
+  for i = 1:length (v)
+    if (v (i) != 0)
+      retval = 1;
+      return;
+    endif
+  endfor
+  printf ("no nonzero elements found\n");
+endfunction
+ at end group
+ at end example
+
+Note that this function could not have been written using the
+ at code{break} statement to exit the loop once a nonzero value is found
+without adding extra logic to avoid printing the message if the vector
+does contain a nonzero element.
+
+ at deffn {Keyword} return
+When Octave encounters the keyword @code{return} inside a function or
+script, it returns control to the caller immediately.  At the top level,
+the return statement is ignored.  A @code{return} statement is assumed
+at the end of every function definition.
+ at end deffn
+
+ at node Default Arguments
+ at section Default Arguments
+ at cindex default arguments
+
+Since Octave supports variable number of input arguments, it is very useful
+to assign default values to some input arguments.  When an input argument
+is declared in the argument list it is possible to assign a default
+value to the argument like this
+
+ at example
+ at group
+function @var{name} (@var{arg1} = @var{val1}, @dots{})
+  @var{body}
+endfunction
+ at end group
+ at end example
+
+ at noindent
+If no value is assigned to @var{arg1} by the user, it will have the
+value @var{val1}.
+
+As an example, the following function implements a variant of the classic
+``Hello, World'' program.
+ at example
+ at group
+function hello (who = "World")
+  printf ("Hello, %s!\n", who);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+When called without an input argument the function prints the following
+ at example
+ at group
+hello ();
+     @print{} Hello, World!
+ at end group
+ at end example
+
+ at noindent
+and when it's called with an input argument it prints the following
+ at example
+ at group
+hello ("Beautiful World of Free Software");
+     @print{} Hello, Beautiful World of Free Software!
+ at end group
+ at end example
+
+Sometimes it is useful to explicitly tell Octave to use the default value
+of an input argument.  This can be done writing a @samp{:} as the value
+of the input argument when calling the function.
+ at example
+ at group
+hello (:);
+     @print{} Hello, World!
+ at end group
+ at end example
+
+ at node Function Files
+ at section Function Files
+ at cindex function file
+
+Except for simple one-shot programs, it is not practical to have to
+define all the functions you need each time you need them.  Instead, you
+will normally want to save them in a file so that you can easily edit
+them, and save them for use at a later time.
+
+Octave does not require you to load function definitions from files
+before using them.  You simply need to put the function definitions in a
+place where Octave can find them.
+
+When Octave encounters an identifier that is undefined, it first looks
+for variables or functions that are already compiled and currently
+listed in its symbol table.  If it fails to find a definition there, it
+searches a list of directories (the @dfn{path}) for files ending in
+ at file{.m} that have the same base name as the undefined
+identifier. at footnote{The @samp{.m} suffix was chosen for compatibility
+with @sc{matlab}.}  Once Octave finds a file with a name that matches,
+the contents of the file are read.  If it defines a @emph{single}
+function, it is compiled and executed.  @xref{Script Files}, for more
+information about how you can define more than one function in a single
+file.
+
+When Octave defines a function from a function file, it saves the full
+name of the file it read and the time stamp on the file.  If the time
+stamp on the file changes, Octave may reload the file.  When Octave is
+running interactively, time stamp checking normally happens at most once
+each time Octave prints the prompt.  Searching for new function
+definitions also occurs if the current working directory changes.
+
+Checking the time stamp allows you to edit the definition of a function
+while Octave is running, and automatically use the new function
+definition without having to restart your Octave session.
+
+To avoid degrading performance unnecessarily by checking the time stamps
+on functions that are not likely to change, Octave assumes that function
+files in the directory tree
+ at file{@var{octave-home}/share/octave/@var{version}/m}
+will not change, so it doesn't have to check their time stamps every time the
+functions defined in those files are used.  This is normally a very good
+assumption and provides a significant improvement in performance for the
+function files that are distributed with Octave.
+
+If you know that your own function files will not change while you are
+running Octave, you can improve performance by calling
+ at code{ignore_function_time_stamp ("all")}, so that Octave will
+ignore the time stamps for all function files.  Passing
+ at code{"system"} to this function resets the default behavior.
+
+ at c FIXME -- note about time stamps on files in NFS environments?
+
+ at DOCSTRING(edit)
+
+ at DOCSTRING(mfilename)
+
+ at DOCSTRING(ignore_function_time_stamp)
+
+ at menu
+* Manipulating the load path::
+* Subfunctions::
+* Private Functions::
+* Overloading and Autoloading::
+* Function Locking::
+* Function Precedence::
+ at end menu
+
+ at node Manipulating the load path
+ at subsection Manipulating the load path
+
+When a function is called, Octave searches a list of directories for
+a file that contains the function declaration.  This list of directories
+is known as the load path.  By default the load path contains
+a list of directories distributed with Octave plus the current
+working directory.  To see your current load path call the @code{path}
+function without any input or output arguments.
+
+It is possible to add or remove directories to or from the load path
+using @code{addpath} and @code{rmpath}.  As an example, the following
+code adds @samp{~/Octave} to the load path.
+
+ at example
+addpath("~/Octave")
+ at end example
+
+ at noindent
+After this the directory @samp{~/Octave} will be searched for functions.
+ 
+ at DOCSTRING(addpath)
+
+ at DOCSTRING(genpath)
+
+ at DOCSTRING(rmpath)
+
+ at DOCSTRING(savepath)
+
+ at DOCSTRING(path)
+
+ at DOCSTRING(pathdef)
+
+ at DOCSTRING(pathsep)
+
+ at DOCSTRING(rehash)
+
+ at DOCSTRING(file_in_loadpath)
+
+ at DOCSTRING(restoredefaultpath)
+
+ at DOCSTRING(command_line_path)
+
+ at DOCSTRING(find_dir_in_path)
+
+ at node Subfunctions
+ at subsection Subfunctions
+
+A function file may contain secondary functions called
+ at dfn{subfunctions}.  These secondary functions are only visible to the
+other functions in the same function file.  For example, a file
+ at file{f.m} containing
+
+ at example
+ at group
+function f ()
+  printf ("in f, calling g\n");
+  g ()
+endfunction
+function g ()
+  printf ("in g, calling h\n");
+  h ()
+endfunction
+function h ()
+  printf ("in h\n")
+endfunction
+ at end group
+ at end example
+
+ at noindent
+defines a main function @code{f} and two subfunctions.  The
+subfunctions @code{g} and @code{h} may only be called from the main
+function @code{f} or from the other subfunctions, but not from outside
+the file @file{f.m}.
+
+ at node Private Functions
+ at subsection Private Functions
+
+In many cases one function needs to access one or more helper
+functions.  If the helper function is limited to the scope of a single
+function, then subfunctions as discussed above might be used.  However,
+if a single helper function is used by more than one function, then
+this is no longer possible.  In this case the helper functions might
+be placed in a subdirectory, called "private", of the directory in which
+the functions needing access to this helper function are found.
+
+As a simple example, consider a function @code{func1}, that calls a helper
+function @code{func2} to do much of the work.  For example
+
+ at example
+ at group
+function y = func1 (x)
+  y = func2 (x);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+Then if the path to @code{func1} is @code{<directory>/func1.m}, and if
+ at code{func2} is found in the directory @code{<directory>/private/func2.m}, 
+then @code{func2} is only available for use of the functions, like 
+ at code{func1}, that are found in @code{<directory>}.
+
+ at node Overloading and Autoloading
+ at subsection Overloading and Autoloading
+
+The @code{dispatch} function can be used to alias one function name to
+another.  It can be used to alias all calls to a particular function name
+to another function, or the alias can be limited to only a particular
+variable type.  Consider the example
+
+ at example
+ at group
+function y = spsin (x)
+  printf ("Calling spsin\n");
+  fflush(stdout);
+  y = spfun ("sin", x);
+endfunction
+
+dispatch ("sin", "spsin", "sparse matrix");
+y0 = sin(eye(3));
+y1 = sin(speye(3));
+ at end group
+ at end example
+
+ at noindent
+which aliases the user-defined function @code{spsin} to @code{sin}, but only for real sparse
+matrices.  Note that the builtin @code{sin} already correctly treats
+sparse matrices and so this example is only illustrative.
+
+ at DOCSTRING(dispatch)
+
+ at DOCSTRING(builtin)
+
+A single dynamically linked file might define several
+functions.  However, as Octave searches for functions based on the
+functions filename, Octave needs a manner in which to find each of the
+functions in the dynamically linked file.  On operating systems that
+support symbolic links, it is possible to create a symbolic link to the
+original file for each of the functions which it contains.
+
+However, there is at least one well known operating system that doesn't
+support symbolic links.  Making copies of the original file for each of
+the functions is undesirable as it increases the
+amount of disk space used by Octave.  Instead Octave supplies the
+ at code{autoload} function, that permits the user to define in which
+file a certain function will be found.
+
+ at DOCSTRING(autoload)
+
+ at node Function Locking
+ at subsection Function Locking
+
+It is sometime desirable to lock a function into memory with the
+ at code{mlock} function.  This is typically used for dynamically linked
+functions in Oct-files or mex-files that contain some initialization,
+and it is desirable that calling @code{clear} does not remove this
+initialization.
+
+As an example,
+
+ at example
+mlock ("my_function");
+ at end example
+
+ at noindent
+prevents @code{my_function} from being removed from memory, even if
+ at code{clear} is called.  It is possible to determine if a function is
+locked into memory with the @code{mislocked}, and to unlock a function
+with @code{munlock}, which the following illustrates.
+
+ at example
+ at group
+mlock ("my_function");
+mislocked ("my_function")
+ at result{} ans = 1
+munlock ("my_function");
+mislocked ("my_function")
+ at result{} ans = 0
+ at end group
+ at end example
+
+A common use of @code{mlock} is to prevent persistent variables from
+being removed from memory, as the following example shows:
+
+ at example
+ at group
+function count_calls()
+  persistent calls = 0;
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+mlock ("count_calls");
+
+count_calls ();
+ at print{} 'count_calls' has been called 1 times
+
+clear count_calls
+count_calls ();
+ at print{} 'count_calls' has been called 2 times
+ at end group
+ at end example
+
+ at noindent
+It is, however, often inconvenient to lock a function from the prompt,
+so it is also possible to lock a function from within its body.  This
+is simply done by calling @code{mlock} from within the function.
+
+ at example
+ at group
+function count_calls ()
+  mlock ();
+  persistent calls = 0;
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+ at end group
+ at end example
+
+ at code{mlock} might equally be used to prevent changes to a function from having
+effect in Octave, though a similar effect can be had with the
+ at code{ignore_function_time_stamp} function.
+
+ at DOCSTRING(mlock)
+
+ at DOCSTRING(munlock)
+
+ at DOCSTRING(mislocked)
+
+ at node Function Precedence
+ at subsection Function Precedence
+
+Given the numerous different ways that Octave can define a function, it
+is possible and even likely that multiple versions of a function, might be
+defined within a particular scope.  The precedence of which function will be
+used within a particular scope is given by
+
+ at enumerate 1
+ at item Subfunction
+A subfunction with the required function name in the given scope.
+
+ at item Private function
+A function defined within a private directory of the directory 
+which contains the current function.
+
+ at item Class constructor
+A function that constuctors a user class as defined in chapter 
+ at ref{Object Oriented Programming}.
+
+ at item Class method
+An overloaded function of a class as in chapter
+ at ref{Object Oriented Programming}.
+
+ at item Legacy Dispatch
+An overloaded function as defined by @xref{doc-dispatch}.
+
+ at item Command-line Function
+A function that has been defined on the command-line.
+
+ at item Autoload function
+A function that is marked as autoloaded with @xref{doc-autoload}.
+
+ at item A Function on the Path
+A function that can be found on the users load-path.  There can also be
+Oct-file, mex-file or m-file versions of this function and the precedence
+between these versions are in that order.
+
+ at item Built-in function
+A function that is builtin to Octave itself such as @code{numel},
+ at code{size}, etc.
+ at end enumerate
+
+ at node Script Files
+ at section Script Files
+
+A script file is a file containing (almost) any sequence of Octave
+commands.  It is read and evaluated just as if you had typed each
+command at the Octave prompt, and provides a convenient way to perform a
+sequence of commands that do not logically belong inside a function.
+
+Unlike a function file, a script file must @emph{not} begin with the
+keyword @code{function}.  If it does, Octave will assume that it is a
+function file, and that it defines a single function that should be
+evaluated as soon as it is defined.
+
+A script file also differs from a function file in that the variables
+named in a script file are not local variables, but are in the same
+scope as the other variables that are visible on the command line.
+
+Even though a script file may not begin with the @code{function}
+keyword, it is possible to define more than one function in a single
+script file and load (but not execute) all of them at once.  To do 
+this, the first token in the file (ignoring comments and other white
+space) must be something other than @code{function}.  If you have no
+other statements to evaluate, you can use a statement that has no
+effect, like this:
+
+ at example
+ at group
+# Prevent Octave from thinking that this
+# is a function file:
+
+1;
+
+# Define function one:
+
+function one ()
+  @dots{}
+ at end group
+ at end example
+
+To have Octave read and compile these functions into an internal form,
+you need to make sure that the file is in Octave's load path
+(accessible through the @code{path} function), then simply type the
+base name of the file that contains the commands.  (Octave uses the
+same rules to search for script files as it does to search for
+function files.)
+
+If the first token in a file (ignoring comments) is @code{function},
+Octave will compile the function and try to execute it, printing a
+message warning about any non-whitespace characters that appear after
+the function definition.
+
+Note that Octave does not try to look up the definition of any identifier
+until it needs to evaluate it.  This means that Octave will compile the
+following statements if they appear in a script file, or are typed at
+the command line,
+
+ at example
+ at group
+# not a function file:
+1;
+function foo ()
+  do_something ();
+endfunction
+function do_something ()
+  do_something_else ();
+endfunction
+ at end group
+ at end example
+
+ at noindent
+even though the function @code{do_something} is not defined before it is
+referenced in the function @code{foo}.  This is not an error because
+Octave does not need to resolve all symbols that are referenced by a
+function until the function is actually evaluated.
+
+Since Octave doesn't look for definitions until they are needed, the
+following code will always print @samp{bar = 3} whether it is typed
+directly on the command line, read from a script file, or is part of a
+function body, even if there is a function or script file called
+ at file{bar.m} in Octave's path.
+
+ at example
+ at group
+eval ("bar = 3");
+bar
+ at end group
+ at end example
+
+Code like this appearing within a function body could fool Octave if
+definitions were resolved as the function was being compiled.  It would
+be virtually impossible to make Octave clever enough to evaluate this
+code in a consistent fashion.  The parser would have to be able to
+perform the call to @code{eval} at compile time, and that would be
+impossible unless all the references in the string to be evaluated could
+also be resolved, and requiring that would be too restrictive (the
+string might come from user input, or depend on things that are not
+known until the function is evaluated).
+
+Although Octave normally executes commands from script files that have
+the name @file{@var{file}.m}, you can use the function @code{source} to
+execute commands from any file.
+
+ at DOCSTRING(source)
+
+ at node Function Handles Inline Functions and Anonymous Functions
+ at section Function Handles, Inline Functions, and Anonymous Functions
+ at cindex handle, function handles
+ at cindex inline, inline functions
+ at cindex anonymous functions
+
+It can be very convenient store a function in a variable so that it
+can be passed to a different function.  For example, a function that
+performs numerical minimization needs access to the function that 
+should be minimized.
+
+ at menu
+* Function Handles::
+* Anonymous Functions::
+* Inline Functions::
+ at end menu
+
+ at node Function Handles
+ at subsection Function Handles
+
+A function handle is a pointer to another function and is defined with
+the syntax
+
+ at example
+@@@var{function-name}
+ at end example
+
+ at noindent
+For example
+
+ at example
+f = @@sin;
+ at end example
+
+ at noindent
+Creates a function handle called @code{f} that refers to the
+function @code{sin}.
+
+Function handles are used to call other functions indirectly, or to pass
+a function as an argument to another function like @code{quad} or
+ at code{fsolve}.  For example
+
+ at example
+ at group
+f = @@sin;
+quad (f, 0, pi)
+    @result{} 2
+ at end group
+ at end example
+
+You may use @code{feval} to call a function using function handle, or
+simply write the name of the function handle followed by an argument
+list.  If there are no arguments, you must use an empty argument list
+ at samp{()}.  For example
+
+ at example
+ at group
+f = @@sin;
+feval (f, pi/4)
+    @result{} 0.70711
+f (pi/4)
+    @result{} 0.70711
+ at end group
+ at end example
+
+ at DOCSTRING(functions)
+
+ at DOCSTRING(func2str)
+
+ at DOCSTRING(str2func)
+
+ at node Anonymous Functions
+ at subsection Anonymous Functions
+
+Anonymous functions are defined using the syntax
+
+ at example
+@@(@var{argument-list}) @var{expression}
+ at end example
+
+ at noindent
+Any variables that are not found in the argument list are inherited from
+the enclosing scope.  Anonymous functions are useful for creating simple
+unnamed functions from expressions or for wrapping calls to other
+functions to adapt them for use by functions like @code{quad}.  For
+example,
+
+ at example
+ at group
+f = @@(x) x.^2;
+quad (f, 0, 10)
+    @result{} 333.33
+ at end group
+ at end example
+
+ at noindent
+creates a simple unnamed function from the expression @code{x.^2} and
+passes it to @code{quad},
+
+ at example
+ at group
+quad (@@(x) sin (x), 0, pi)
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+wraps another function, and
+
+ at example
+ at group
+a = 1;
+b = 2;
+quad (@@(x) betainc (x, a, b), 0, 0.4)
+    @result{} 0.13867
+ at end group
+ at end example
+
+ at noindent
+adapts a function with several parameters to the form required by
+ at code{quad}.  In this example, the values of @var{a} and @var{b} that
+are passed to @code{betainc} are inherited from the current
+environment.
+
+ at node Inline Functions
+ at subsection Inline Functions
+
+An inline function is created from a string containing the function
+body using the @code{inline} function.  The following code defines the
+function @math{f(x) = x^2 + 2}.
+
+ at example
+f = inline("x^2 + 2");
+ at end example
+
+ at noindent
+After this it is possible to evaluate @math{f} at any @math{x} by
+writing @code{f(x)}.
+
+ at DOCSTRING(inline)
+
+ at DOCSTRING(argnames)
+
+ at DOCSTRING(formula)
+
+ at DOCSTRING(vectorize)
+
+ at DOCSTRING(symvar)
+
+ at node Commands
+ at section Commands
+
+Commands are a special class of functions that only accept string
+input arguments.  A command can be called as an ordinary function, but
+it can also be called without the parentheses like the following example
+shows
+
+ at example
+my_command hello world
+ at end example
+
+ at noindent
+which is the same as
+
+ at example
+my_command("hello", "world")
+ at end example
+
+The general form of a command call is
+
+ at example
+ at var{name} @var{arg1} @var{arg2} @dots{}
+ at end example
+
+ at noindent
+which translates directly to
+
+ at example
+ at var{name} ("@var{arg1}", "@var{arg2}", @dots{})
+ at end example
+
+A function can be used as a command if it accepts string input arguments.
+To do this, the function must be marked as a command, which can be done
+with the @code{mark_as_command} command like this
+
+ at example
+mark_as_command name
+ at end example
+
+ at noindent
+where @code{name} is the function to be marked as a command.
+
+One difficulty of commands occurs when one of the string input arguments
+are stored in a variable.  Since Octave can't tell the difference between
+a variable name, and an ordinary string, it is not possible to pass a
+variable as input to a command.  In such a situation a command must be
+called as a function.
+
+ at DOCSTRING(mark_as_command)
+
+ at DOCSTRING(unmark_command)
+
+ at DOCSTRING(iscommand)
+
+ at DOCSTRING(mark_as_rawcommand)
+
+ at DOCSTRING(unmark_rawcommand)
+
+ at DOCSTRING(israwcommand)
+
+ at node Organization of Functions
+ at section Organization of Functions Distributed with Octave
+
+Many of Octave's standard functions are distributed as function files.
+They are loosely organized by topic, in subdirectories of
+ at file{@var{octave-home}/lib/octave/@var{version}/m}, to make it easier
+to find them.
+
+The following is a list of all the function file subdirectories, and the
+types of functions you will find there.
+
+ at table @file
+ at item audio
+Functions for playing and recording sounds.
+
+ at item control
+Functions for design and simulation of automatic control systems.
+
+ at item elfun
+Elementary functions.
+
+ at item finance
+Functions for computing interest payments, investment values, and rates
+of return.
+
+ at item general
+Miscellaneous matrix manipulations, like @code{flipud}, @code{rot90},
+and @code{triu}, as well as other basic functions, like
+ at code{ismatrix}, @code{nargchk}, etc.
+
+ at item image
+Image processing tools.  These functions require the X Window System.
+
+ at item io
+Input-output functions.
+
+ at item linear-algebra
+Functions for linear algebra.
+
+ at item miscellaneous
+Functions that don't really belong anywhere else.
+
+ at item optimization
+Minimization of functions.
+
+ at item path
+Functions to manage the directory path Octave uses to find functions.
+
+ at item pkg
+Install external packages of functions in Octave.
+
+ at item plot
+Functions for displaying and printing two- and three-dimensional graphs.
+
+ at item polynomial
+Functions for manipulating polynomials.
+
+ at item set
+Functions for creating and manipulating sets of unique values.
+
+ at item signal
+Functions for signal processing applications.
+
+ at item sparse
+Functions for handling sparse matrices.
+
+ at item specfun
+Special functions.
+
+ at item special-matrix
+Functions that create special matrix forms.
+
+ at item startup
+Octave's system-wide startup file.
+
+ at item statistics
+Statistical functions.
+
+ at item strings
+Miscellaneous string-handling functions.
+
+ at item testfun
+Perform unit tests on other functions.
+
+ at item time
+Functions related to time keeping.
+ at end table
diff --git a/doc/interpreter/geometry.texi b/doc/interpreter/geometry.texi
new file mode 100644
index 0000000..46adf53
--- /dev/null
+++ b/doc/interpreter/geometry.texi
@@ -0,0 +1,744 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Geometry
+ at chapter Geometry
+
+Much of the geometry code in Octave is based on the Qhull 
+library at footnote{Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., 
+"The Quickhull algorithm for convex hulls," ACM Trans. on Mathematical 
+Software, 22(4):469--483, Dec 1996, @url{http://www.qhull.org}}.  
+Some of the documentation for Qhull, particularly for the options that 
+can be passed to @code{delaunay}, @code{voronoi} and @code{convhull}, 
+etc., is relevant to Octave users.
+
+ at menu
+* Delaunay Triangulation::
+* Voronoi Diagrams::
+* Convex Hull::
+* Interpolation on Scattered Data::
+ at end menu
+
+ at node Delaunay Triangulation
+ at section Delaunay Triangulation
+
+The Delaunay triangulation is constructed from a set of
+circum-circles.  These circum-circles are chosen so that there are at
+least three of the points in the set to triangulation on the
+circumference of the circum-circle.  None of the points in the set of
+points falls within any of the circum-circles.
+
+In general there are only three points on the circumference of any
+circum-circle.  However, in some cases, and in particular for the
+case of a regular grid, 4 or more points can be on a single
+circum-circle.  In this case the Delaunay triangulation is not unique. 
+
+ at c ./geometry/delaunay.m
+ at anchor{doc-delaunay}
+ at deftypefn {Function File} {@var{tri} =} delaunay (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{tri} =} delaunay (@var{x}, @var{y}, @var{opt})
+The return matrix of size [n, 3] contains a set triangles which are
+described by the indices to the data point x and y vector.
+The triangulation satisfies the Delaunay circum-circle criterion.
+No other data point is in the circum-circle of the defining triangle.
+
+A third optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the 
+Qhull library for details.
+
+ at example
+ at group
+x = rand (1, 10);
+y = rand (size (x));
+T = delaunay (x, y);
+X = [x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1))];
+Y = [y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1))];
+axis ([0,1,0,1]);
+plot (X, Y, "b", x, y, "r*");
+ at end group
+ at end example
+ at seealso{@ref{doc-voronoi,,voronoi}, @ref{doc-delaunay3,,delaunay3}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+The 3- and N-dimensional extension of the Delaunay triangulation are
+given by @code{delaunay3} and @code{delaunayn} respectively.  
+ at code{delaunay3} returns a set of tetrahedra that satisfy the
+Delaunay circum-circle criteria.  Similarly, @code{delaunayn} returns the
+N-dimensional simplex satisfying the Delaunay circum-circle criteria.  
+The N-dimensional extension of a triangulation is called a tessellation.
+
+ at c ./geometry/delaunay3.m
+ at anchor{doc-delaunay3}
+ at deftypefn {Function File} {@var{T} =} delaunay3 (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {@var{T} =} delaunay3 (@var{x}, @var{y}, @var{z}, @var{opt})
+A matrix of size [n, 4] is returned.  Each row contains a 
+set of tetrahedron which are
+described by the indices to the data point vectors (x,y,z).
+
+A fourth optional argument, which must be a string or cell array of strings,
+contains extra options passed to the underlying qhull command.  See the 
+documentation for the Qhull library for details.
+ at seealso{@ref{doc-delaunay,,delaunay}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+ at c ./geometry/delaunayn.m
+ at anchor{doc-delaunayn}
+ at deftypefn {Function File} {@var{T} =} delaunayn (@var{P})
+ at deftypefnx {Function File} {@var{T} =} delaunayn (@var{P}, @var{opt})
+Form the Delaunay triangulation for a set of points.
+The Delaunay triangulation is a tessellation of the convex hull of the
+points such that no n-sphere defined by the n-triangles contains
+any other points from the set.
+The input matrix @var{P} of size @code{[n, dim]} contains @var{n}
+points in a space of dimension dim.  The return matrix @var{T} has the
+size @code{[m, dim+1]}.  It contains for each row a set of indices to
+the points, which describes a simplex of dimension dim.  For example,
+a 2d simplex is a triangle and 3d simplex is a tetrahedron.
+
+Extra options for the underlying Qhull command can be specified by the
+second argument.  This argument is a cell array of strings.  The default
+options depend on the dimension of the input: 
+
+ at itemize 
+ at item 2D and 3D: @var{opt} = @code{@{"Qt", "Qbb", "Qc"@}}
+ at item 4D and higher: @var{opt} = @code{@{"Qt", "Qbb", "Qc", "Qz"@}} 
+ at end itemize
+
+If @var{opt} is [], then the default arguments are used.  If @var{opt}
+is @code{@{"@w{}"@}}, then none of the default arguments are used by Qhull. 
+See the Qhull documentation for the available options. 
+
+All options can also be specified as single string, for example
+ at code{"Qt Qbb Qc Qz"}.
+
+ at end deftypefn
+
+
+An example of a Delaunay triangulation of a set of points is
+
+ at example
+ at group
+rand ("state", 2);
+x = rand (10, 1);
+y = rand (10, 1);
+T = delaunay (x, y);
+X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
+Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+axis ([0, 1, 0, 1]);
+plot(X, Y, "b", x, y, "r*");
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:delaunay}.
+
+ at float Figure,fig:delaunay
+ at center @image{delaunay,4in}
+ at caption{Delaunay triangulation of a random set of points}
+ at end float
+ at end ifnotinfo
+ at end ifset
+
+ at menu
+* Plotting the Triangulation::
+* Identifying points in Triangulation::
+ at end menu
+
+ at node Plotting the Triangulation
+ at subsection Plotting the Triangulation
+
+Octave has the functions @code{triplot} and @code{trimesh} to plot the
+Delaunay triangulation of a 2-dimensional set of points.
+
+ at c ./geometry/triplot.m
+ at anchor{doc-triplot}
+ at deftypefn {Function File} {} triplot (@var{tri}, @var{x}, @var{y})
+ at deftypefnx {Function File} {} triplot (@var{tri}, @var{x}, @var{y}, @var{linespec})
+ at deftypefnx {Function File} {@var{h} =} triplot (@dots{})
+Plot a triangular mesh in 2D.  The variable @var{tri} is the triangular
+meshing of the points @code{(@var{x}, @var{y})} which is returned from
+ at code{delaunay}.  If given, the @var{linespec} determines the properties
+to use for the lines.  The output argument @var{h} is the graphic handle
+to the plot.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-trimesh,,trimesh}, @ref{doc-delaunay,,delaunay}}
+ at end deftypefn
+
+
+ at c ./geometry/trimesh.m
+ at anchor{doc-trimesh}
+ at deftypefn {Function File} {} trimesh (@var{tri}, @var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {@var{h} =} trimesh (@dots{})
+Plot a triangular mesh in 3D.  The variable @var{tri} is the triangular
+meshing of the points @code{(@var{x}, @var{y})} which is returned 
+from @code{delaunay}.  The variable @var{z} is value at the point 
+ at code{(@var{x}, @var{y})}.  The output argument @var{h} is the graphic 
+handle to the plot.
+ at seealso{@ref{doc-triplot,,triplot}, @ref{doc-delaunay3,,delaunay3}}
+ at end deftypefn
+
+
+The difference between @code{triplot} and @code{trimesh} is that the
+former only plots the 2-dimensional triangulation itself, whereas the
+second plots the value of some function @code{f (@var{x}, @var{y})}.
+An example of the use of the @code{triplot} function is
+
+ at example
+ at group
+rand ("state", 2)
+x = rand (20, 1);
+y = rand (20, 1);
+tri = delaunay (x, y);
+triplot (tri, x, y);
+ at end group
+ at end example
+
+that plot the Delaunay triangulation of a set of random points in
+2-dimensions.
+ at ifnotinfo
+The output of the above can be seen in @ref{fig:triplot}.
+
+ at float Figure,fig:triplot
+ at center @image{triplot,4in}
+ at caption{Delaunay triangulation of a random set of points}
+ at end float
+ at end ifnotinfo
+
+ at node Identifying points in Triangulation
+ at subsection Identifying points in Triangulation
+
+It is often necessary to identify whether a particular point in the
+N-dimensional space is within the Delaunay tessellation of a set of
+points in this N-dimensional space, and if so which N-simplex contains
+the point and which point in the tessellation is closest to the desired
+point.  The functions @code{tsearch} and @code{dsearch} perform this
+function in a triangulation, and @code{tsearchn} and @code{dsearchn} in
+an N-dimensional tessellation.
+
+To identify whether a particular point represented by a vector @var{p}
+falls within one of the simplices of an N-simplex, we can write the
+Cartesian coordinates of the point in a parametric form with respect to
+the N-simplex.  This parametric form is called the Barycentric
+Coordinates of the point.  If the points defining the N-simplex are given
+by @code{@var{N} + 1} vectors @var{t}(@var{i},:), then the Barycentric
+coordinates defining the point @var{p} are given by
+
+ at example
+ at var{p} = sum (@var{beta}(1:@var{N}+1) * @var{t}(1:@var{N}+1),:)
+ at end example
+
+ at noindent
+where there are @code{@var{N} + 1} values @code{@var{beta}(@var{i})}
+that together as a vector represent the Barycentric coordinates of the
+point @var{p}.  To ensure a unique solution for the values of
+ at code{@var{beta}(@var{i})} an additional criteria of
+
+ at example
+sum (@var{beta}(1:@var{N}+1)) == 1
+ at end example
+
+ at noindent
+is imposed, and we can therefore write the above as
+
+ at example
+ at group
+ at var{p} - @var{t}(end, :) = @var{beta}(1:end-1) * (@var{t}(1:end-1, :)
+      - ones(@var{N}, 1) * @var{t}(end, :)
+ at end group
+ at end example
+
+ at noindent
+Solving for @var{beta} we can then write
+
+ at example
+ at group
+ at var{beta}(1:end-1) = (@var{p} - @var{t}(end, :)) / (@var{t}(1:end-1, :)
+      - ones(@var{N}, 1) * @var{t}(end, :))
+ at var{beta}(end) = sum(@var{beta}(1:end-1))
+ at end group
+ at end example
+
+ at noindent
+which gives the formula for the conversion of the Cartesian coordinates
+of the point @var{p} to the Barycentric coordinates @var{beta}.  An
+important property of the Barycentric coordinates is that for all points
+in the N-simplex
+
+ at example
+0 <= @var{beta}(@var{i}) <= 1
+ at end example
+
+ at noindent
+Therefore, the test in @code{tsearch} and @code{tsearchn} essentially
+only needs to express each point in terms of the Barycentric coordinates
+of each of the simplices of the N-simplex and test the values of
+ at var{beta}.  This is exactly the implementation used in
+ at code{tsearchn}.  @code{tsearch} is optimized for 2-dimensions and the
+Barycentric coordinates are not explicitly formed.
+
+ at c ./DLD-FUNCTIONS/tsearch.cc
+ at anchor{doc-tsearch}
+ at deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})
+Searches for the enclosing Delaunay convex hull.  For @code{@var{t} =
+delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the
+points @code{(@var{xi}, @var{yi})}.  For points outside the convex hull,
+ at var{idx} is NaN.
+ at seealso{@ref{doc-delaunay,,delaunay}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+ at c ./geometry/tsearchn.m
+ at anchor{doc-tsearchn}
+ at deftypefn {Function File} {[@var{idx}, @var{p}] =} tsearchn (@var{x}, @var{t}, @var{xi})
+Searches for the enclosing Delaunay convex hull.  For @code{@var{t} =
+delaunayn (@var{x})}, finds the index in @var{t} containing the
+points @var{xi}.  For points outside the convex hull, @var{idx} is NaN.
+If requested @code{tsearchn} also returns the Barycentric coordinates @var{p}
+of the enclosing triangles.
+ at seealso{@ref{doc-delaunay,,delaunay}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+An example of the use of @code{tsearch} can be seen with the simple
+triangulation
+
+ at example
+ at group
+ at var{x} = [-1; -1; 1; 1];
+ at var{y} = [-1; 1; -1; 1];
+ at var{tri} = [1, 2, 3; 2, 3, 1];
+ at end group
+ at end example
+
+ at noindent
+consisting of two triangles defined by @var{tri}.  We can then identify
+which triangle a point falls in like
+
+ at example
+ at group
+tsearch (@var{x}, @var{y}, @var{tri}, -0.5, -0.5)
+ at result{} 1
+tsearch (@var{x}, @var{y}, @var{tri}, 0.5, 0.5)
+ at result{} 2
+ at end group
+ at end example
+
+ at noindent
+and we can confirm that a point doesn't lie within one of the triangles like
+
+ at example
+ at group
+tsearch (@var{x}, @var{y}, @var{tri}, 2, 2)
+ at result{} NaN
+ at end group
+ at end example
+
+The @code{dsearch} and @code{dsearchn} find the closest point in a
+tessellation to the desired point.  The desired point does not
+necessarily have to be in the tessellation, and even if it the returned
+point of the tessellation does not have to be one of the vertexes of the
+N-simplex within which the desired point is found.
+
+ at c ./geometry/dsearch.m
+ at anchor{doc-dsearch}
+ at deftypefn {Function File} {@var{idx} =} dsearch (@var{x}, @var{y}, @var{tri}, @var{xi}, @var{yi})
+ at deftypefnx {Function File} {@var{idx} =} dsearch (@var{x}, @var{y}, @var{tri}, @var{xi}, @var{yi}, @var{s})
+Returns the index @var{idx} or the closest point in @code{@var{x}, @var{y}}
+to the elements @code{[@var{xi}(:), @var{yi}(:)]}.  The variable @var{s} is
+accepted but ignored for compatibility.
+ at seealso{@ref{doc-dsearchn,,dsearchn}, @ref{doc-tsearch,,tsearch}}
+ at end deftypefn
+
+
+ at c ./geometry/dsearchn.m
+ at anchor{doc-dsearchn}
+ at deftypefn {Function File} {@var{idx} =} dsearchn (@var{x}, @var{tri}, @var{xi})
+ at deftypefnx {Function File} {@var{idx} =} dsearchn (@var{x}, @var{tri}, @var{xi}, @var{outval})
+ at deftypefnx {Function File} {@var{idx} =} dsearchn (@var{x}, @var{xi})
+ at deftypefnx {Function File} {[@var{idx}, @var{d}] =} dsearchn (@dots{})
+Returns the index @var{idx} or the closest point in @var{x} to the elements
+ at var{xi}.  If @var{outval} is supplied, then the values of @var{xi} that are
+not contained within one of the simplicies @var{tri} are set to 
+ at var{outval}.  Generally, @var{tri} is returned from @code{delaunayn 
+(@var{x})}.
+ at seealso{@ref{doc-dsearch,,dsearch}, @ref{doc-tsearch,,tsearch}}
+ at end deftypefn
+
+
+An example of the use of @code{dsearch}, using the above values of
+ at var{x}, @var{y} and @var{tri} is
+
+ at example
+ at group
+dsearch (@var{x}, @var{y}, @var{tri}, -2, -2)
+ at result{} 1
+ at end group
+ at end example
+
+If you wish the points that are outside the tessellation to be flagged,
+then @code{dsearchn} can be used as
+
+ at example
+ at group
+dsearchn ([@var{x}, @var{y}], @var{tri}, [-2, -2], NaN)
+ at result{} NaN
+dsearchn ([@var{x}, @var{y}], @var{tri}, [-0.5, -0.5], NaN)
+ at result{} 1
+ at end group
+ at end example
+
+ at noindent
+where the point outside the tessellation are then flagged with @code{NaN}.
+
+ at node Voronoi Diagrams
+ at section Voronoi Diagrams
+
+A Voronoi diagram or Voronoi tessellation of a set of points @var{s} in
+an N-dimensional space, is the tessellation of the N-dimensional space
+such that all points in @code{@var{v}(@var{p})}, a partitions of the
+tessellation where @var{p} is a member of @var{s}, are closer to @var{p}
+than any other point in @var{s}.  The Voronoi diagram is related to the
+Delaunay triangulation of a set of points, in that the vertexes of the
+Voronoi tessellation are the centers of the circum-circles of the
+simplicies of the Delaunay tessellation. 
+
+ at c ./geometry/voronoi.m
+ at anchor{doc-voronoi}
+ at deftypefn {Function File} {} voronoi (@var{x}, @var{y})
+ at deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle")
+ at deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle", @var{options})
+ at deftypefnx {Function File} {[@var{vx}, @var{vy}] =} voronoi (@dots{})
+plots voronoi diagram of points @code{(@var{x}, @var{y})}.
+The voronoi facets with points at infinity are not drawn.
+[@var{vx}, @var{vy}] = voronoi(@dots{}) returns the vertices instead of plotting the
+diagram. plot (@var{vx}, @var{vy}) shows the voronoi diagram.
+
+A fourth optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+
+ at example
+ at group
+  x = rand (10, 1);
+  y = rand (size (x));
+  h = convhull (x, y);
+  [vx, vy] = voronoi (x, y);
+  plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g")
+  legend ("", "points", "hull");
+ at end group
+ at end example
+
+ at seealso{@ref{doc-voronoin,,voronoin}, @ref{doc-delaunay,,delaunay}, @ref{doc-convhull,,convhull}}
+ at end deftypefn
+
+
+ at c ./geometry/voronoin.m
+ at anchor{doc-voronoin}
+ at deftypefn {Function File} {[@var{C}, @var{F}] =} voronoin (@var{pts})
+ at deftypefnx {Function File} {[@var{C}, @var{F}] =} voronoin (@var{pts}, @var{options})
+computes n- dimensional voronoi facets.  The input matrix @var{pts}
+of size [n, dim] contains n points of dimension dim.
+ at var{C} contains the points of the voronoi facets.  The list @var{F}
+contains for each facet the indices of the voronoi points.
+
+A second optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+ at seealso{@ref{doc-voronoin,,voronoin}, @ref{doc-delaunay,,delaunay}, @ref{doc-convhull,,convhull}}
+ at end deftypefn
+
+
+An example of the use of @code{voronoi} is
+
+ at example
+ at group
+rand("state",9);
+x = rand(10,1);
+y = rand(10,1);
+tri = delaunay (x, y);
+[vx, vy] = voronoi (x, y, tri);
+triplot (tri, x, y, "b");
+hold on;
+plot (vx, vy, "r");
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:voronoi}.  Note that the
+circum-circle of one of the triangles has been added to this figure, to
+make the relationship between the Delaunay tessellation and the Voronoi
+diagram clearer.
+
+ at float Figure,fig:voronoi
+ at center @image{voronoi,4in}
+ at caption{Delaunay triangulation and Voronoi diagram of a random set of points}
+ at end float
+ at end ifnotinfo
+ at end ifset
+
+Additional information about the size of the facets of a Voronoi
+diagram, and which points of a set of points is in a polygon can be had
+with the @code{polyarea} and @code{inpolygon} functions respectively.
+
+ at c ./general/polyarea.m
+ at anchor{doc-polyarea}
+ at deftypefn {Function File} {} polyarea (@var{x}, @var{y})
+ at deftypefnx {Function File} {} polyarea (@var{x}, @var{y}, @var{dim})
+
+Determines area of a polygon by triangle method.  The variables
+ at var{x} and @var{y} define the vertex pairs, and must therefore have
+the same shape.  They can be either vectors or arrays.  If they are
+arrays then the columns of @var{x} and @var{y} are treated separately
+and an area returned for each.
+
+If the optional @var{dim} argument is given, then @code{polyarea}
+works along this dimension of the arrays @var{x} and @var{y}.
+
+ at end deftypefn
+
+
+An example of the use of @code{polyarea} might be 
+
+ at example
+ at group
+rand ("state", 2);
+x = rand (10, 1);
+y = rand (10, 1);
+[c, f] = voronoin ([x, y]);
+af = zeros (size(f));
+for i = 1 : length (f)
+  af(i) = polyarea (c (f @{i, :@}, 1), c (f @{i, :@}, 2));
+endfor
+ at end group
+ at end example
+
+Facets of the Voronoi diagram with a vertex at infinity have infinity
+area.  A simplified version of @code{polyarea} for rectangles is
+available with @code{rectint}
+
+ at c ./geometry/rectint.m
+ at anchor{doc-rectint}
+ at deftypefn {Function File} {@var{area} =} rectint (@var{a}, @var{b})
+
+Compute the area of intersection of rectangles in @var{a} and
+rectangles in @var{b}.  Rectangles are defined as [x y width height]
+where x and y are the minimum values of the two orthogonal
+dimensions.
+
+If @var{a} or @var{b} are matrices, then the output, @var{area}, is a
+matrix where the i-th row corresponds to the i-th row of a and the j-th
+column corresponds to the j-th row of b.
+
+ at seealso{@ref{doc-polyarea,,polyarea}}
+ at end deftypefn
+
+
+ at c ./geometry/inpolygon.m
+ at anchor{doc-inpolygon}
+ at deftypefn {Function File} {[@var{in}, @var{on}] =} inpolygon (@var{x}, @var{y}, @var{xv}, @var{xy})
+
+For a polygon defined by @code{(@var{xv}, @var{yv})} points, determine
+if the points @code{(@var{x}, @var{y})} are inside or outside the polygon.
+The variables @var{x}, @var{y}, must have the same dimension.  The optional
+output @var{on} gives the points that are on the polygon.
+
+ at end deftypefn
+
+
+An example of the use of @code{inpolygon} might be
+
+ at example
+ at group
+randn ("state", 2);
+x = randn (100, 1);
+y = randn (100, 1);
+vx = cos (pi * [-1 : 0.1: 1]);
+vy = sin (pi * [-1 : 0.1 : 1]);
+in = inpolygon (x, y, vx, vy);
+plot(vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo");
+axis ([-2, 2, -2, 2]);
+ at end group
+ at end example
+
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:inpolygon}.
+
+ at float Figure,fig:inpolygon
+ at center @image{inpolygon,4in}
+ at caption{Demonstration of the @code{inpolygon} function to determine the
+points inside a polygon}
+ at end float
+ at end ifnotinfo
+
+ at node Convex Hull
+ at section Convex Hull
+
+The convex hull of a set of points is the minimum convex envelope
+containing all of the points.  Octave has the functions @code{convhull}
+and @code{convhulln} to calculate the convex hull of 2-dimensional and
+N-dimensional sets of points.
+
+ at c ./geometry/convhull.m
+ at anchor{doc-convhull}
+ at deftypefn {Function File} {@var{H} =} convhull (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{H} =} convhull (@var{x}, @var{y}, @var{opt})
+Returns the index vector to the points of the enclosing convex hull.  The
+data points are defined by the x and y vectors.
+
+A third optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the 
+Qhull library for details.
+
+ at seealso{@ref{doc-delaunay,,delaunay}, @ref{doc-convhulln,,convhulln}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/convhulln.cc
+ at anchor{doc-convhulln}
+ at deftypefn {Loadable Function} {@var{h} =} convhulln (@var{p})
+ at deftypefnx {Loadable Function} {@var{h} =} convhulln (@var{p}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{h}, @var{v}] =} convhulln (@dots{})
+Return an index vector to the points of the enclosing convex hull.
+The input matrix of size [n, dim] contains n points of dimension dim.
+
+If a second optional argument is given, it must be a string or cell array
+of strings containing options for the underlying qhull command.  (See
+the Qhull documentation for the available options.)  The default options
+are "s Qci Tcv".
+If the second output @var{V} is requested the volume of the convex hull is
+calculated.
+
+ at seealso{@ref{doc-convhull,,convhull}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+An example of the use of @code{convhull} is
+
+ at example
+ at group
+x = -3:0.05:3;
+y = abs (sin (x));
+k = convhull (x, y);
+plot (x(k), y(k), "r-", x, y, "b+");
+axis ([-3.05, 3.05, -0.05, 1.05]);
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at ifnotinfo
+ at noindent
+The output of the above can be seen in @ref{fig:convhull}.
+
+ at float Figure,fig:convhull
+ at center @image{convhull,4in}
+ at caption{The convex hull of a simple set of points}
+ at end float
+ at end ifnotinfo
+ at end ifset
+
+ at node Interpolation on Scattered Data
+ at section Interpolation on Scattered Data
+
+An important use of the Delaunay tessellation is that it can be used to
+interpolate from scattered data to an arbitrary set of points.  To do
+this the N-simplex of the known set of points is calculated with
+ at code{delaunay}, @code{delaunay3} or @code{delaunayn}.  Then the
+simplicies in to which the desired points are found are
+identified.  Finally the vertices of the simplicies are used to
+interpolate to the desired points.  The functions that perform this
+interpolation are @code{griddata}, @code{griddata3} and
+ at code{griddatan}.
+
+ at c ./geometry/griddata.m
+ at anchor{doc-griddata}
+ at deftypefn {Function File} {@var{zi} =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
+ at deftypefnx {Function File} {[@var{xi}, @var{yi}, @var{zi}] =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
+
+Generate a regular mesh from irregular data using interpolation.
+The function is defined by @code{@var{z} = f (@var{x}, @var{y})}.
+The interpolation points are all @code{(@var{xi}, @var{yi})}.  If
+ at var{xi}, @var{yi} are vectors then they are made into a 2D mesh.
+
+The interpolation method can be @code{"nearest"}, @code{"cubic"} or
+ at code{"linear"}.  If method is omitted it defaults to @code{"linear"}.
+ at seealso{@ref{doc-delaunay,,delaunay}}
+ at end deftypefn
+
+
+ at c ./geometry/griddata3.m
+ at anchor{doc-griddata3}
+ at deftypefn {Function File} {@var{vi} =} griddata3 (@var{x}, @var{y}, @var{z}, @var{v} @var{xi}, @var{yi}, @var{zi}, @var{method}, @var{options})
+
+Generate a regular mesh from irregular data using interpolation.
+The function is defined by @code{@var{y} = f (@var{x}, at var{y}, at var{z})}.
+The interpolation points are all @var{xi}.  
+
+The interpolation method can be @code{"nearest"} or @code{"linear"}.
+If method is omitted it defaults to @code{"linear"}.
+ at seealso{@ref{doc-griddata,,griddata}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+ at c ./geometry/griddatan.m
+ at anchor{doc-griddatan}
+ at deftypefn {Function File} {@var{yi} =} griddatan (@var{x}, @var{y}, @var{xi}, @var{method}, @var{options})
+
+Generate a regular mesh from irregular data using interpolation.
+The function is defined by @code{@var{y} = f (@var{x})}.
+The interpolation points are all @var{xi}.  
+
+The interpolation method can be @code{"nearest"} or @code{"linear"}.
+If method is omitted it defaults to @code{"linear"}.
+ at seealso{@ref{doc-griddata,,griddata}, @ref{doc-delaunayn,,delaunayn}}
+ at end deftypefn
+
+
+An example of the use of the @code{griddata} function is
+
+ at example
+ at group
+rand("state",1);
+x=2*rand(1000,1)-1;
+y=2*rand(size(x))-1;
+z=sin(2*(x.^2+y.^2));
+[xx,yy]=meshgrid(linspace(-1,1,32));
+griddata(x,y,z,xx,yy);
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at noindent
+that interpolates from a random scattering of points, to a uniform
+grid. 
+ at ifnotinfo
+The output of the above can be seen in @ref{fig:griddata}.
+
+ at float Figure,fig:griddata
+ at center @image{griddata,4in}
+ at caption{Interpolation from a scattered data to a regular grid}
+ at end float
+ at end ifnotinfo
+ at end ifset
diff --git a/doc/interpreter/geometry.txi b/doc/interpreter/geometry.txi
new file mode 100644
index 0000000..d3ff8f8
--- /dev/null
+++ b/doc/interpreter/geometry.txi
@@ -0,0 +1,458 @@
+ at c Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Geometry
+ at chapter Geometry
+
+Much of the geometry code in Octave is based on the Qhull 
+library at footnote{Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., 
+"The Quickhull algorithm for convex hulls," ACM Trans. on Mathematical 
+Software, 22(4):469--483, Dec 1996, @url{http://www.qhull.org}}.  
+Some of the documentation for Qhull, particularly for the options that 
+can be passed to @code{delaunay}, @code{voronoi} and @code{convhull}, 
+etc., is relevant to Octave users.
+
+ at menu
+* Delaunay Triangulation::
+* Voronoi Diagrams::
+* Convex Hull::
+* Interpolation on Scattered Data::
+ at end menu
+
+ at node Delaunay Triangulation
+ at section Delaunay Triangulation
+
+The Delaunay triangulation is constructed from a set of
+circum-circles.  These circum-circles are chosen so that there are at
+least three of the points in the set to triangulation on the
+circumference of the circum-circle.  None of the points in the set of
+points falls within any of the circum-circles.
+
+In general there are only three points on the circumference of any
+circum-circle.  However, in some cases, and in particular for the
+case of a regular grid, 4 or more points can be on a single
+circum-circle.  In this case the Delaunay triangulation is not unique. 
+
+ at DOCSTRING(delaunay)
+
+The 3- and N-dimensional extension of the Delaunay triangulation are
+given by @code{delaunay3} and @code{delaunayn} respectively.  
+ at code{delaunay3} returns a set of tetrahedra that satisfy the
+Delaunay circum-circle criteria.  Similarly, @code{delaunayn} returns the
+N-dimensional simplex satisfying the Delaunay circum-circle criteria.  
+The N-dimensional extension of a triangulation is called a tessellation.
+
+ at DOCSTRING(delaunay3)
+
+ at DOCSTRING(delaunayn)
+
+An example of a Delaunay triangulation of a set of points is
+
+ at example
+ at group
+rand ("state", 2);
+x = rand (10, 1);
+y = rand (10, 1);
+T = delaunay (x, y);
+X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
+Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+axis ([0, 1, 0, 1]);
+plot(X, Y, "b", x, y, "r*");
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:delaunay}.
+
+ at float Figure,fig:delaunay
+ at center @image{delaunay,4in}
+ at caption{Delaunay triangulation of a random set of points}
+ at end float
+ at end ifnotinfo
+ at end ifset
+
+ at menu
+* Plotting the Triangulation::
+* Identifying points in Triangulation::
+ at end menu
+
+ at node Plotting the Triangulation
+ at subsection Plotting the Triangulation
+
+Octave has the functions @code{triplot} and @code{trimesh} to plot the
+Delaunay triangulation of a 2-dimensional set of points.
+
+ at DOCSTRING(triplot)
+
+ at DOCSTRING(trimesh)
+
+The difference between @code{triplot} and @code{trimesh} is that the
+former only plots the 2-dimensional triangulation itself, whereas the
+second plots the value of some function @code{f (@var{x}, @var{y})}.
+An example of the use of the @code{triplot} function is
+
+ at example
+ at group
+rand ("state", 2)
+x = rand (20, 1);
+y = rand (20, 1);
+tri = delaunay (x, y);
+triplot (tri, x, y);
+ at end group
+ at end example
+
+that plot the Delaunay triangulation of a set of random points in
+2-dimensions.
+ at ifnotinfo
+The output of the above can be seen in @ref{fig:triplot}.
+
+ at float Figure,fig:triplot
+ at center @image{triplot,4in}
+ at caption{Delaunay triangulation of a random set of points}
+ at end float
+ at end ifnotinfo
+
+ at node Identifying points in Triangulation
+ at subsection Identifying points in Triangulation
+
+It is often necessary to identify whether a particular point in the
+N-dimensional space is within the Delaunay tessellation of a set of
+points in this N-dimensional space, and if so which N-simplex contains
+the point and which point in the tessellation is closest to the desired
+point.  The functions @code{tsearch} and @code{dsearch} perform this
+function in a triangulation, and @code{tsearchn} and @code{dsearchn} in
+an N-dimensional tessellation.
+
+To identify whether a particular point represented by a vector @var{p}
+falls within one of the simplices of an N-simplex, we can write the
+Cartesian coordinates of the point in a parametric form with respect to
+the N-simplex.  This parametric form is called the Barycentric
+Coordinates of the point.  If the points defining the N-simplex are given
+by @code{@var{N} + 1} vectors @var{t}(@var{i},:), then the Barycentric
+coordinates defining the point @var{p} are given by
+
+ at example
+ at var{p} = sum (@var{beta}(1:@var{N}+1) * @var{t}(1:@var{N}+1),:)
+ at end example
+
+ at noindent
+where there are @code{@var{N} + 1} values @code{@var{beta}(@var{i})}
+that together as a vector represent the Barycentric coordinates of the
+point @var{p}.  To ensure a unique solution for the values of
+ at code{@var{beta}(@var{i})} an additional criteria of
+
+ at example
+sum (@var{beta}(1:@var{N}+1)) == 1
+ at end example
+
+ at noindent
+is imposed, and we can therefore write the above as
+
+ at example
+ at group
+ at var{p} - @var{t}(end, :) = @var{beta}(1:end-1) * (@var{t}(1:end-1, :)
+      - ones(@var{N}, 1) * @var{t}(end, :)
+ at end group
+ at end example
+
+ at noindent
+Solving for @var{beta} we can then write
+
+ at example
+ at group
+ at var{beta}(1:end-1) = (@var{p} - @var{t}(end, :)) / (@var{t}(1:end-1, :)
+      - ones(@var{N}, 1) * @var{t}(end, :))
+ at var{beta}(end) = sum(@var{beta}(1:end-1))
+ at end group
+ at end example
+
+ at noindent
+which gives the formula for the conversion of the Cartesian coordinates
+of the point @var{p} to the Barycentric coordinates @var{beta}.  An
+important property of the Barycentric coordinates is that for all points
+in the N-simplex
+
+ at example
+0 <= @var{beta}(@var{i}) <= 1
+ at end example
+
+ at noindent
+Therefore, the test in @code{tsearch} and @code{tsearchn} essentially
+only needs to express each point in terms of the Barycentric coordinates
+of each of the simplices of the N-simplex and test the values of
+ at var{beta}.  This is exactly the implementation used in
+ at code{tsearchn}.  @code{tsearch} is optimized for 2-dimensions and the
+Barycentric coordinates are not explicitly formed.
+
+ at DOCSTRING(tsearch)
+
+ at DOCSTRING(tsearchn)
+
+An example of the use of @code{tsearch} can be seen with the simple
+triangulation
+
+ at example
+ at group
+ at var{x} = [-1; -1; 1; 1];
+ at var{y} = [-1; 1; -1; 1];
+ at var{tri} = [1, 2, 3; 2, 3, 1];
+ at end group
+ at end example
+
+ at noindent
+consisting of two triangles defined by @var{tri}.  We can then identify
+which triangle a point falls in like
+
+ at example
+ at group
+tsearch (@var{x}, @var{y}, @var{tri}, -0.5, -0.5)
+ at result{} 1
+tsearch (@var{x}, @var{y}, @var{tri}, 0.5, 0.5)
+ at result{} 2
+ at end group
+ at end example
+
+ at noindent
+and we can confirm that a point doesn't lie within one of the triangles like
+
+ at example
+ at group
+tsearch (@var{x}, @var{y}, @var{tri}, 2, 2)
+ at result{} NaN
+ at end group
+ at end example
+
+The @code{dsearch} and @code{dsearchn} find the closest point in a
+tessellation to the desired point.  The desired point does not
+necessarily have to be in the tessellation, and even if it the returned
+point of the tessellation does not have to be one of the vertexes of the
+N-simplex within which the desired point is found.
+
+ at DOCSTRING(dsearch)
+
+ at DOCSTRING(dsearchn)
+
+An example of the use of @code{dsearch}, using the above values of
+ at var{x}, @var{y} and @var{tri} is
+
+ at example
+ at group
+dsearch (@var{x}, @var{y}, @var{tri}, -2, -2)
+ at result{} 1
+ at end group
+ at end example
+
+If you wish the points that are outside the tessellation to be flagged,
+then @code{dsearchn} can be used as
+
+ at example
+ at group
+dsearchn ([@var{x}, @var{y}], @var{tri}, [-2, -2], NaN)
+ at result{} NaN
+dsearchn ([@var{x}, @var{y}], @var{tri}, [-0.5, -0.5], NaN)
+ at result{} 1
+ at end group
+ at end example
+
+ at noindent
+where the point outside the tessellation are then flagged with @code{NaN}.
+
+ at node Voronoi Diagrams
+ at section Voronoi Diagrams
+
+A Voronoi diagram or Voronoi tessellation of a set of points @var{s} in
+an N-dimensional space, is the tessellation of the N-dimensional space
+such that all points in @code{@var{v}(@var{p})}, a partitions of the
+tessellation where @var{p} is a member of @var{s}, are closer to @var{p}
+than any other point in @var{s}.  The Voronoi diagram is related to the
+Delaunay triangulation of a set of points, in that the vertexes of the
+Voronoi tessellation are the centers of the circum-circles of the
+simplicies of the Delaunay tessellation. 
+
+ at DOCSTRING(voronoi)
+
+ at DOCSTRING(voronoin)
+
+An example of the use of @code{voronoi} is
+
+ at example
+ at group
+rand("state",9);
+x = rand(10,1);
+y = rand(10,1);
+tri = delaunay (x, y);
+[vx, vy] = voronoi (x, y, tri);
+triplot (tri, x, y, "b");
+hold on;
+plot (vx, vy, "r");
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:voronoi}.  Note that the
+circum-circle of one of the triangles has been added to this figure, to
+make the relationship between the Delaunay tessellation and the Voronoi
+diagram clearer.
+
+ at float Figure,fig:voronoi
+ at center @image{voronoi,4in}
+ at caption{Delaunay triangulation and Voronoi diagram of a random set of points}
+ at end float
+ at end ifnotinfo
+ at end ifset
+
+Additional information about the size of the facets of a Voronoi
+diagram, and which points of a set of points is in a polygon can be had
+with the @code{polyarea} and @code{inpolygon} functions respectively.
+
+ at DOCSTRING(polyarea)
+
+An example of the use of @code{polyarea} might be 
+
+ at example
+ at group
+rand ("state", 2);
+x = rand (10, 1);
+y = rand (10, 1);
+[c, f] = voronoin ([x, y]);
+af = zeros (size(f));
+for i = 1 : length (f)
+  af(i) = polyarea (c (f @{i, :@}, 1), c (f @{i, :@}, 2));
+endfor
+ at end group
+ at end example
+
+Facets of the Voronoi diagram with a vertex at infinity have infinity
+area.  A simplified version of @code{polyarea} for rectangles is
+available with @code{rectint}
+
+ at DOCSTRING(rectint)
+
+ at DOCSTRING(inpolygon)
+
+An example of the use of @code{inpolygon} might be
+
+ at example
+ at group
+randn ("state", 2);
+x = randn (100, 1);
+y = randn (100, 1);
+vx = cos (pi * [-1 : 0.1: 1]);
+vy = sin (pi * [-1 : 0.1 : 1]);
+in = inpolygon (x, y, vx, vy);
+plot(vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo");
+axis ([-2, 2, -2, 2]);
+ at end group
+ at end example
+
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:inpolygon}.
+
+ at float Figure,fig:inpolygon
+ at center @image{inpolygon,4in}
+ at caption{Demonstration of the @code{inpolygon} function to determine the
+points inside a polygon}
+ at end float
+ at end ifnotinfo
+
+ at node Convex Hull
+ at section Convex Hull
+
+The convex hull of a set of points is the minimum convex envelope
+containing all of the points.  Octave has the functions @code{convhull}
+and @code{convhulln} to calculate the convex hull of 2-dimensional and
+N-dimensional sets of points.
+
+ at DOCSTRING(convhull)
+
+ at DOCSTRING(convhulln)
+
+An example of the use of @code{convhull} is
+
+ at example
+ at group
+x = -3:0.05:3;
+y = abs (sin (x));
+k = convhull (x, y);
+plot (x(k), y(k), "r-", x, y, "b+");
+axis ([-3.05, 3.05, -0.05, 1.05]);
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at ifnotinfo
+ at noindent
+The output of the above can be seen in @ref{fig:convhull}.
+
+ at float Figure,fig:convhull
+ at center @image{convhull,4in}
+ at caption{The convex hull of a simple set of points}
+ at end float
+ at end ifnotinfo
+ at end ifset
+
+ at node Interpolation on Scattered Data
+ at section Interpolation on Scattered Data
+
+An important use of the Delaunay tessellation is that it can be used to
+interpolate from scattered data to an arbitrary set of points.  To do
+this the N-simplex of the known set of points is calculated with
+ at code{delaunay}, @code{delaunay3} or @code{delaunayn}.  Then the
+simplicies in to which the desired points are found are
+identified.  Finally the vertices of the simplicies are used to
+interpolate to the desired points.  The functions that perform this
+interpolation are @code{griddata}, @code{griddata3} and
+ at code{griddatan}.
+
+ at DOCSTRING(griddata)
+
+ at DOCSTRING(griddata3)
+
+ at DOCSTRING(griddatan)
+
+An example of the use of the @code{griddata} function is
+
+ at example
+ at group
+rand("state",1);
+x=2*rand(1000,1)-1;
+y=2*rand(size(x))-1;
+z=sin(2*(x.^2+y.^2));
+[xx,yy]=meshgrid(linspace(-1,1,32));
+griddata(x,y,z,xx,yy);
+ at end group
+ at end example
+
+ at ifset HAVE_QHULL
+ at noindent
+that interpolates from a random scattering of points, to a uniform
+grid. 
+ at ifnotinfo
+The output of the above can be seen in @ref{fig:griddata}.
+
+ at float Figure,fig:griddata
+ at center @image{griddata,4in}
+ at caption{Interpolation from a scattered data to a regular grid}
+ at end float
+ at end ifnotinfo
+ at end ifset
diff --git a/doc/interpreter/geometryimages.m b/doc/interpreter/geometryimages.m
new file mode 100644
index 0000000..3248170
--- /dev/null
+++ b/doc/interpreter/geometryimages.m
@@ -0,0 +1,208 @@
+## Copyright (C) 2007, 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+function geometryimages (nm, typ)
+  bury_output ();
+  if (strcmp (typ, "png"))
+    set (0, "defaulttextfontname", "*");
+  endif
+  if (isempty (findstr (octave_config_info ("DEFS"), "HAVE_QHULL"))
+      && (strcmp (nm, "voronoi") || strcmp (nm, "griddata")
+	  || strcmp (nm, "convhull") || strcmp (nm, "delaunay")
+	  || strcmp (nm, "triplot")))
+    sombreroimage (nm, typ);
+  elseif (strcmp (typ, "txt"))
+    image_as_txt (nm);
+  elseif (strcmp (nm, "voronoi"))
+    rand("state",9);
+    x = rand(10,1);
+    y = rand(10,1);
+    tri = delaunay (x, y);
+    [vx, vy] = voronoi (x, y, tri);
+    triplot (tri, x, y, "b");
+    hold on;
+    plot (vx, vy, "r");
+    [r, c] = tri2circ (tri(end,:), x, y);
+    pc = [-1:0.01:1];
+    xc = r * sin(pi*pc) + c(1);
+    yc = r * cos(pi*pc) + c(2);
+    plot (xc, yc, "g-", "LineWidth", 3);
+    axis([0, 1, 0, 1]);
+    legend ("Delaunay Triangulation", "Voronoi Diagram");
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "triplot"))
+    rand ("state", 2)
+    x = rand (20, 1);
+    y = rand (20, 1);
+    tri = delaunay (x, y);
+    triplot (tri, x, y);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "griddata"))
+    rand("state",1);
+    x=2*rand(1000,1)-1;
+    y=2*rand(size(x))-1;
+    z=sin(2*(x.^2+y.^2));
+    [xx,yy]=meshgrid(linspace(-1,1,32));
+    griddata(x,y,z,xx,yy);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "convhull"))
+    x = -3:0.05:3;
+    y = abs (sin (x));
+    k = convhull (x, y);
+    plot (x(k),y(k),'r-',x,y,'b+');
+    axis ([-3.05, 3.05, -0.05, 1.05]);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ)) 
+  elseif (strcmp (nm, "delaunay"))
+    rand ("state", 1);
+    x = rand (1, 10);
+    y = rand (1, 10);
+    T = delaunay (x, y);
+    X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
+    Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+    axis ([0, 1, 0, 1]);
+    plot(X, Y, "b", x, y, "r*");
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ)) 
+  elseif (strcmp (nm, "inpolygon"))
+    randn ("state", 2);
+    x = randn (100, 1);
+    y = randn (100, 1);
+    vx = cos (pi * [-1 : 0.1: 1]);
+    vy = sin (pi * [-1 : 0.1 : 1]);
+    in = inpolygon (x, y, vx, vy);
+    plot(vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo");
+    axis ([-2, 2, -2, 2]);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ)) 
+  else
+    error ("unrecognized plot requested");
+  endif
+  bury_output ();
+endfunction
+
+function [r, c] = tri2circ (tri, xx, yy)
+  x = xx(tri);
+  y = yy(tri);
+  m = (y(1:end-1) - y(2:end)) ./ (x(1:end-1) - x(2:end));
+  xc = (prod(m) .* (y(1) - y(end)) + m(end)*(x(1)+x(2)) - m(1)*(x(2)+x(3))) ...
+        ./ (2 * (m(end) - m(1))); 
+  yc = - (xc - (x(2) + x(3))./2) ./ m(end) + (y(2) + y(3)) / 2;
+  c = [xc, yc];
+  r = sqrt ((xc - x(1)).^2 + (yc - y(1)).^2);
+endfunction
+
+## Use this function before plotting commands and after every call to
+## print since print() resets output to stdout (unfortunately, gnpulot
+## can't pop output as it can the terminal type).
+function bury_output ()
+  f = figure (1);
+  set (f, "visible", "off");
+endfunction
+function geometryimages (nm, typ)
+  bury_output ();
+  if (strcmp (nm, "voronoi"))
+    rand("state",9);
+    x = rand(10,1);
+    y = rand(10,1);
+    tri = delaunay (x, y);
+    [vx, vy] = voronoi (x, y, tri);
+    triplot (tri, x, y, "b");
+    hold on;
+    plot (vx, vy, "r");
+    [r, c] = tri2circ (tri(end,:), x, y);
+    pc = [-1:0.01:1];
+    xc = r * sin(pi*pc) + c(1);
+    yc = r * cos(pi*pc) + c(2);
+    plot (xc, yc, "g-", "LineWidth", 3);
+    axis([0, 1, 0, 1]);
+    legend ("Delaunay Triangulation", "Voronoi Diagram");
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "triplot"))
+    rand ("state", 2)
+    x = rand (20, 1);
+    y = rand (20, 1);
+    tri = delaunay (x, y);
+    triplot (tri, x, y);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "griddata"))
+    rand("state",1);
+    x=2*rand(1000,1)-1;
+    y=2*rand(size(x))-1;
+    z=sin(2*(x.^2+y.^2));
+    [xx,yy]=meshgrid(linspace(-1,1,32));
+    griddata(x,y,z,xx,yy);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  else
+    error ("unrecognized plot requested");
+  endif
+  bury_output ();
+endfunction
+
+function [r, c] = tri2circ (tri, xx, yy)
+  x = xx(tri);
+  y = yy(tri);
+  m = (y(1:end-1) - y(2:end)) ./ (x(1:end-1) - x(2:end));
+  xc = (prod(m) .* (y(1) - y(end)) + m(end)*(x(1)+x(2)) - m(1)*(x(2)+x(3))) ...
+        ./ (2 * (m(end) - m(1))); 
+  yc = - (xc - (x(2) + x(3))./2) ./ m(end) + (y(2) + y(3)) / 2;
+  c = [xc, yc];
+  r = sqrt ((xc - x(1)).^2 + (yc - y(1)).^2);
+endfunction
+
+## Use this function before plotting commands and after every call to
+## print since print() resets output to stdout (unfortunately, gnpulot
+## can't pop output as it can the terminal type).
+function bury_output ()
+  f = figure (1);
+  set (f, "visible", "off");
+endfunction
+
+function sombreroimage (nm, typ)
+  if (strcmp (typ, "txt"))
+    fid = fopen (sprintf ("%s.txt", nm), "wt");
+    fputs (fid, "+-----------------------------+\n");
+    fputs (fid, "| Image unavailable because   |\n");
+    fputs (fid, "| of a missing QHULL library. |\n");
+    fputs (fid, "+-----------------------------+\n");
+    fclose (fid);
+    return;
+  else ## if (!strcmp (typ, "txt"))
+
+    bury_output ();
+
+    x = y = linspace (-8, 8, 41)';
+    [xx, yy] = meshgrid (x, y);
+    r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+    z = sin (r) ./ r;
+    unwind_protect
+      mesh (x, y, z);
+      title ("Sorry, graphics not available because octave was\\ncompiled without the QHULL library.");
+    unwind_protect_cleanup
+      print (cstrcat (nm, ".", typ), cstrcat ("-d", typ));
+      bury_output ();
+    end_unwind_protect
+  endif
+endfunction
+
+## generate something for the texinfo @image command to process
+function image_as_txt(nm)
+  fid = fopen (sprintf ("%s.txt", nm), "wt");
+  fputs (fid, "\n");
+  fputs (fid, "+---------------------------------+\n");
+  fputs (fid, "| Image unavailable in text mode. |\n");
+  fputs (fid, "+---------------------------------+\n");
+  fclose (fid);
+endfunction
diff --git a/doc/interpreter/gpl.texi b/doc/interpreter/gpl.texi
new file mode 100644
index 0000000..38711b1
--- /dev/null
+++ b/doc/interpreter/gpl.texi
@@ -0,0 +1,720 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at node Copying
+ at appendix GNU GENERAL PUBLIC LICENSE
+ at cindex warranty
+ at cindex copyright
+
+ at center Version 3, 29 June 2007
+
+ at display
+Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+ at end display
+
+ at heading 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.
+
+ at heading TERMS AND CONDITIONS
+
+ at enumerate 0
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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:
+
+ at enumerate a
+ at item 
+The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+ at item
+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''.
+
+ at item
+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.
+
+ at item
+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.
+ at end enumerate
+
+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.
+
+ at item  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:
+
+ at enumerate a
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at end enumerate
+
+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.
+
+ at item 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:
+
+ at enumerate a
+ at item
+Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+ at item
+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
+
+ at item
+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
+
+ at item
+Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+ at item
+Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+ at item
+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.
+ at end enumerate
+
+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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at end enumerate
+
+ at heading END OF TERMS AND CONDITIONS
+
+ at heading 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.
+
+ at smallexample
+ at var{one line to give the program's name and a brief idea of what it does.}  
+Copyright (C) @var{year} @var{name of author}
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see @url{http://www.gnu.org/licenses/}.
+ at end smallexample
+
+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:
+
+ at smallexample
+ at var{program} Copyright (C) @var{year} @var{name of author} 
+This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type @samp{show c} for details.
+ at end smallexample
+
+The hypothetical commands @samp{show w} and @samp{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
+ at url{http://www.gnu.org/licenses/}.
+
+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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
diff --git a/doc/interpreter/gpl.txi b/doc/interpreter/gpl.txi
new file mode 100644
index 0000000..fa2745b
--- /dev/null
+++ b/doc/interpreter/gpl.txi
@@ -0,0 +1,718 @@
+ at node Copying
+ at appendix GNU GENERAL PUBLIC LICENSE
+ at cindex warranty
+ at cindex copyright
+
+ at center Version 3, 29 June 2007
+
+ at display
+Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+ at end display
+
+ at heading 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.
+
+ at heading TERMS AND CONDITIONS
+
+ at enumerate 0
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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:
+
+ at enumerate a
+ at item 
+The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+ at item
+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''.
+
+ at item
+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.
+
+ at item
+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.
+ at end enumerate
+
+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.
+
+ at item  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:
+
+ at enumerate a
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at end enumerate
+
+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.
+
+ at item 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:
+
+ at enumerate a
+ at item
+Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+ at item
+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
+
+ at item
+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
+
+ at item
+Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+ at item
+Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+ at item
+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.
+ at end enumerate
+
+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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at end enumerate
+
+ at heading END OF TERMS AND CONDITIONS
+
+ at heading 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.
+
+ at smallexample
+ at var{one line to give the program's name and a brief idea of what it does.}  
+Copyright (C) @var{year} @var{name of author}
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see @url{http://www.gnu.org/licenses/}.
+ at end smallexample
+
+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:
+
+ at smallexample
+ at var{program} Copyright (C) @var{year} @var{name of author} 
+This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type @samp{show c} for details.
+ at end smallexample
+
+The hypothetical commands @samp{show w} and @samp{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
+ at url{http://www.gnu.org/licenses/}.
+
+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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
diff --git a/doc/interpreter/gplot.eps b/doc/interpreter/gplot.eps
new file mode 100644
index 0000000..17c6184
--- /dev/null
+++ b/doc/interpreter/gplot.eps
@@ -0,0 +1,768 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: gplot.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:46:54 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (gplot.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:46:54 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 1933 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 1933 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2938 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2938 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3943 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3943 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4947 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4947 M
+[ [(Helvetica) 120.0 0.0 true true 0 (4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5952 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5952 M
+[ [(Helvetica) 120.0 0.0 true true 0 (5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6957 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6957 M
+[ [(Helvetica) 120.0 0.0 true true 0 (6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (7)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2590 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2590 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3705 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3705 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4820 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4820 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5936 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5936 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+7051 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 7051 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8166 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8166 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+9281 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 9281 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (7)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (8)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 5936 928 M
+1475 5952 L
+3705 7962 M
+1475 5952 L
+5936 928 L
+4460 5024 R
+5936 928 L
+4460 5024 V
+8166 7962 M
+10396 5952 L
+8166 7962 L
+5936 5952 M
+8166 7962 L
+5936 5952 L
+3705 7962 M
+5936 5952 L
+-4461 0 R
+3705 7962 L
+5936 5952 M
+3705 7962 L
+% End plot #1
+stroke
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/gplot.pdf b/doc/interpreter/gplot.pdf
new file mode 100644
index 0000000..fa87347
Binary files /dev/null and b/doc/interpreter/gplot.pdf differ
diff --git a/doc/interpreter/gplot.png b/doc/interpreter/gplot.png
new file mode 100644
index 0000000..0a3f1bb
Binary files /dev/null and b/doc/interpreter/gplot.png differ
diff --git a/doc/interpreter/gplot.txt b/doc/interpreter/gplot.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/gplot.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/grammar.texi b/doc/interpreter/grammar.texi
new file mode 100644
index 0000000..d606c44
--- /dev/null
+++ b/doc/interpreter/grammar.texi
@@ -0,0 +1,60 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Grammar
+ at appendix Grammar
+ at cindex grammar rules
+ at cindex language definition
+
+This appendix should eventually contain a semi-formal description of
+Octave's language.
+
+ at menu
+* Keywords::                    
+ at end menu
+
+ at node Keywords
+ at section Keywords
+ at cindex keywords
+
+The following identifiers are keywords, and may not be used as variable
+or function names:
+
+ at multitable @columnfractions .33 .33 .33
+ at item @code{break} @tab @code{case} @tab @code{catch}
+ at item @code{continue} @tab @code{do} @tab @code{else}
+ at item @code{elseif} @tab @code{end} @tab @code{end_try_catch}
+ at item @code{end_unwind_protect} @tab @code{endfor} @tab @code{endfunction}
+ at item @code{endif} @tab @code{endswitch} @tab @code{endwhile}
+ at item @code{for} @tab @code{function} @tab @code{global}
+ at item @code{if} @tab @code{otherwise} @tab @code{persistent}
+ at item @code{return} @tab @code{static} @tab @code{switch}
+ at item @code{try} @tab @code{until} @tab @code{unwind_protect}
+ at item @code{unwind_protect_cleanup} @tab @code{varargin} @tab @code{varargout}
+ at item @code{while} @tab @code{__FILE__} @tab @code{__LINE__}
+ at end multitable
+
+ at c lex.cc
+ at anchor{doc-iskeyword}
+ at deftypefn {Built-in Function} {} iskeyword (@var{name})
+Return true if @var{name} is an Octave keyword.  If @var{name}
+is omitted, return a list of keywords.
+ at end deftypefn
+
diff --git a/doc/interpreter/grammar.txi b/doc/interpreter/grammar.txi
new file mode 100644
index 0000000..5c19121
--- /dev/null
+++ b/doc/interpreter/grammar.txi
@@ -0,0 +1,52 @@
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Grammar
+ at appendix Grammar
+ at cindex grammar rules
+ at cindex language definition
+
+This appendix should eventually contain a semi-formal description of
+Octave's language.
+
+ at menu
+* Keywords::                    
+ at end menu
+
+ at node Keywords
+ at section Keywords
+ at cindex keywords
+
+The following identifiers are keywords, and may not be used as variable
+or function names:
+
+ at multitable @columnfractions .33 .33 .33
+ at item @code{break} @tab @code{case} @tab @code{catch}
+ at item @code{continue} @tab @code{do} @tab @code{else}
+ at item @code{elseif} @tab @code{end} @tab @code{end_try_catch}
+ at item @code{end_unwind_protect} @tab @code{endfor} @tab @code{endfunction}
+ at item @code{endif} @tab @code{endswitch} @tab @code{endwhile}
+ at item @code{for} @tab @code{function} @tab @code{global}
+ at item @code{if} @tab @code{otherwise} @tab @code{persistent}
+ at item @code{return} @tab @code{static} @tab @code{switch}
+ at item @code{try} @tab @code{until} @tab @code{unwind_protect}
+ at item @code{unwind_protect_cleanup} @tab @code{varargin} @tab @code{varargout}
+ at item @code{while} @tab @code{__FILE__} @tab @code{__LINE__}
+ at end multitable
+
+ at DOCSTRING(iskeyword)
diff --git a/doc/interpreter/grid.eps b/doc/interpreter/grid.eps
new file mode 100644
index 0000000..ce48101
--- /dev/null
+++ b/doc/interpreter/grid.eps
@@ -0,0 +1,2237 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: grid.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:46:55 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (grid.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:46:55 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1.000 UP
+0.500 UL
+LT3
+0.00 0.75 0.75 C 3159 2551 M
+219 152 V
+stroke
+LT3
+0.00 0.75 0.75 C 3469 2909 M
+-91 -206 V
+stroke
+LT7
+0.00 0.00 1.00 C 3688 3061 M
+3378 2703 L
+stroke
+LT7
+0.00 0.00 1.00 C 3469 2909 M
+-91 -206 V
+stroke
+LT7
+0.00 0.00 1.00 C 3469 2909 M
+219 152 V
+stroke
+LT2
+0.75 0.00 0.75 C 3469 2909 M
+219 152 V
+stroke
+LT2
+0.75 0.00 0.75 C 3780 3268 M
+-92 -207 V
+stroke
+LT6
+0.00 0.50 0.00 C 3999 3420 M
+3688 3061 L
+stroke
+LT6
+0.00 0.50 0.00 C 3780 3268 M
+-92 -207 V
+stroke
+LT6
+0.00 0.50 0.00 C 3780 3268 M
+219 152 V
+stroke
+LT1
+0.75 0.75 0.00 C 3780 3268 M
+219 152 V
+stroke
+LT1
+0.75 0.75 0.00 C 4401 3619 M
+3999 3420 L
+stroke
+LT5
+1.00 0.00 0.00 C 4620 3772 M
+3999 3420 L
+stroke
+LT5
+1.00 0.00 0.00 C 4401 3619 M
+3999 3420 L
+stroke
+LT5
+1.00 0.00 0.00 C 4401 3619 M
+219 153 V
+stroke
+LT0
+0.25 0.25 0.25 C 4401 3619 M
+219 153 V
+stroke
+LT0
+0.25 0.25 0.25 C 5023 3971 M
+4620 3772 L
+stroke
+LT4
+0.00 0.75 0.75 C 5242 4123 M
+4620 3772 L
+stroke
+LT4
+0.00 0.75 0.75 C 5023 3971 M
+4620 3772 L
+stroke
+LT4
+0.00 0.75 0.75 C 5023 3971 M
+219 152 V
+stroke
+LT8
+0.00 0.00 1.00 C 5023 3971 M
+219 152 V
+stroke
+LT8
+0.00 0.00 1.00 C 6264 4674 M
+5242 4123 L
+stroke
+LT3
+0.75 0.00 0.75 C 6483 4826 M
+5242 4123 L
+stroke
+LT3
+0.75 0.00 0.75 C 6264 4674 M
+5242 4123 L
+stroke
+LT3
+0.75 0.00 0.75 C 6264 4674 M
+219 152 V
+stroke
+LT7
+0.00 0.50 0.00 C 6264 4674 M
+219 152 V
+stroke
+LT7
+0.00 0.50 0.00 C 7507 5377 M
+6483 4826 L
+stroke
+LT2
+0.75 0.75 0.00 C 7726 5530 M
+6483 4826 L
+stroke
+LT2
+0.75 0.75 0.00 C 7507 5377 M
+6483 4826 L
+stroke
+LT2
+1.00 0.00 0.00 C 2830 2322 M
+329 229 V
+stroke
+LT2
+1.00 0.00 0.00 C 3141 2681 M
+18 -130 V
+stroke
+LT3
+0.00 0.75 0.75 C 3469 2909 M
+3159 2551 L
+stroke
+LT6
+0.25 0.25 0.25 C 3469 2909 M
+3159 2551 L
+stroke
+LT6
+0.25 0.25 0.25 C 3141 2681 M
+18 -130 V
+stroke
+LT6
+0.25 0.25 0.25 C 3141 2681 M
+328 228 V
+stroke
+LT1
+0.00 0.75 0.75 C 3141 2681 M
+328 228 V
+stroke
+LT1
+0.00 0.75 0.75 C 3451 3039 M
+18 -130 V
+stroke
+LT2
+0.75 0.00 0.75 C 3780 3268 M
+3469 2909 L
+stroke
+LT5
+0.00 0.00 1.00 C 3780 3268 M
+3469 2909 L
+stroke
+LT5
+0.00 0.00 1.00 C 3451 3039 M
+18 -130 V
+stroke
+LT2
+0.75 0.75 0.00 C 7507 5377 M
+219 153 V
+stroke
+LT6
+1.00 0.00 0.00 C 7507 5377 M
+219 153 V
+stroke
+LT6
+1.00 0.00 0.00 C 8128 5729 M
+7726 5530 L
+stroke
+LT1
+0.25 0.25 0.25 C 8347 5881 M
+7726 5530 L
+stroke
+LT1
+0.25 0.25 0.25 C 8128 5729 M
+7726 5530 L
+stroke
+LT5
+0.00 0.00 1.00 C 3451 3039 M
+329 229 V
+stroke
+LT0
+0.75 0.00 0.75 C 3451 3039 M
+329 229 V
+stroke
+LT0
+0.75 0.00 0.75 C 4073 3391 M
+3780 3268 L
+stroke
+LT1
+0.75 0.75 0.00 C 4401 3619 M
+3780 3268 L
+stroke
+LT4
+0.00 0.50 0.00 C 4401 3619 M
+3780 3268 L
+stroke
+LT4
+0.00 0.50 0.00 C 4073 3391 M
+3780 3268 L
+stroke
+LT1
+0.25 0.25 0.25 C 8128 5729 M
+219 152 V
+stroke
+LT5
+0.00 0.75 0.75 C 8128 5729 M
+219 152 V
+stroke
+LT5
+0.00 0.75 0.75 C 8749 6081 M
+8347 5881 L
+stroke
+LT0
+0.00 0.00 1.00 C 8969 6233 M
+8347 5881 L
+stroke
+LT0
+0.00 0.00 1.00 C 8749 6081 M
+8347 5881 L
+stroke
+LT4
+0.00 0.50 0.00 C 4073 3391 M
+328 228 V
+stroke
+LT8
+0.75 0.75 0.00 C 4073 3391 M
+328 228 V
+stroke
+LT8
+0.75 0.75 0.00 C 4694 3743 M
+4401 3619 L
+stroke
+LT0
+0.25 0.25 0.25 C 5023 3971 M
+4401 3619 L
+stroke
+LT3
+1.00 0.00 0.00 C 5023 3971 M
+4401 3619 L
+stroke
+LT3
+1.00 0.00 0.00 C 4694 3743 M
+4401 3619 L
+stroke
+LT0
+0.00 0.00 1.00 C 8749 6081 M
+220 152 V
+stroke
+LT4
+0.75 0.00 0.75 C 8749 6081 M
+220 152 V
+stroke
+LT4
+0.75 0.00 0.75 C 9060 6439 M
+-91 -206 V
+stroke
+LT8
+0.00 0.50 0.00 C 9279 6592 M
+8969 6233 L
+stroke
+LT8
+0.00 0.50 0.00 C 9060 6439 M
+-91 -206 V
+stroke
+LT3
+1.00 0.00 0.00 C 4694 3743 M
+329 228 V
+stroke
+LT7
+0.25 0.25 0.25 C 4694 3743 M
+329 228 V
+stroke
+LT7
+0.25 0.25 0.25 C 5936 4446 M
+5023 3971 L
+stroke
+LT8
+0.00 0.00 1.00 C 6264 4674 M
+5023 3971 L
+stroke
+LT2
+0.00 0.75 0.75 C 6264 4674 M
+5023 3971 L
+stroke
+LT2
+0.00 0.75 0.75 C 5936 4446 M
+5023 3971 L
+stroke
+LT8
+0.00 0.50 0.00 C 9060 6439 M
+219 153 V
+stroke
+LT3
+0.75 0.75 0.00 C 9060 6439 M
+219 153 V
+stroke
+LT3
+0.75 0.75 0.00 C 9371 6798 M
+-92 -206 V
+stroke
+LT7
+1.00 0.00 0.00 C 9590 6950 M
+9279 6592 L
+stroke
+LT7
+1.00 0.00 0.00 C 9371 6798 M
+-92 -206 V
+stroke
+LT7
+1.00 0.00 0.00 C 9371 6798 M
+219 152 V
+stroke
+LT2
+0.00 0.75 0.75 C 5936 4446 M
+328 228 V
+stroke
+LT6
+0.00 0.00 1.00 C 5936 4446 M
+328 228 V
+stroke
+LT6
+0.00 0.00 1.00 C 7178 5149 M
+6264 4674 L
+stroke
+LT7
+0.00 0.50 0.00 C 7507 5377 M
+6264 4674 L
+stroke
+LT1
+0.75 0.00 0.75 C 7507 5377 M
+6264 4674 L
+stroke
+LT1
+0.75 0.00 0.75 C 7178 5149 M
+6264 4674 L
+stroke
+LT1
+0.75 0.00 0.75 C 7178 5149 M
+329 228 V
+stroke
+LT5
+0.00 0.50 0.00 C 7178 5149 M
+329 228 V
+stroke
+LT5
+0.00 0.50 0.00 C 7799 5501 M
+7507 5377 L
+stroke
+LT6
+1.00 0.00 0.00 C 8128 5729 M
+7507 5377 L
+stroke
+LT0
+0.75 0.75 0.00 C 8128 5729 M
+7507 5377 L
+stroke
+LT0
+0.75 0.75 0.00 C 7799 5501 M
+7507 5377 L
+stroke
+LT0
+0.75 0.75 0.00 C 7799 5501 M
+329 228 V
+stroke
+LT4
+1.00 0.00 0.00 C 7799 5501 M
+329 228 V
+stroke
+LT4
+1.00 0.00 0.00 C 8421 5853 M
+8128 5729 L
+stroke
+LT5
+0.00 0.75 0.75 C 8749 6081 M
+8128 5729 L
+stroke
+LT8
+0.25 0.25 0.25 C 8749 6081 M
+8128 5729 L
+stroke
+LT8
+0.25 0.25 0.25 C 8421 5853 M
+8128 5729 L
+stroke
+LT1
+0.00 0.50 0.00 C 2501 2094 M
+329 228 V
+stroke
+LT1
+0.00 0.50 0.00 C 2812 2453 M
+18 -131 V
+stroke
+LT2
+1.00 0.00 0.00 C 3141 2681 M
+2830 2322 L
+stroke
+LT5
+0.75 0.75 0.00 C 3141 2681 M
+2830 2322 L
+stroke
+LT5
+0.75 0.75 0.00 C 2812 2453 M
+18 -131 V
+stroke
+LT8
+0.25 0.25 0.25 C 8421 5853 M
+328 228 V
+stroke
+LT3
+0.00 0.75 0.75 C 8421 5853 M
+328 228 V
+stroke
+LT3
+0.00 0.75 0.75 C 8731 6211 M
+18 -130 V
+stroke
+LT4
+0.75 0.00 0.75 C 9060 6439 M
+8749 6081 L
+stroke
+LT7
+0.00 0.00 1.00 C 9060 6439 M
+8749 6081 L
+stroke
+LT7
+0.00 0.00 1.00 C 8731 6211 M
+18 -130 V
+stroke
+LT5
+0.75 0.75 0.00 C 2812 2453 M
+329 228 V
+stroke
+LT0
+1.00 0.00 0.00 C 2812 2453 M
+329 228 V
+stroke
+LT0
+1.00 0.00 0.00 C 3123 2811 M
+18 -130 V
+stroke
+LT1
+0.00 0.75 0.75 C 3451 3039 M
+3141 2681 L
+stroke
+LT4
+0.25 0.25 0.25 C 3451 3039 M
+3141 2681 L
+stroke
+LT4
+0.25 0.25 0.25 C 3123 2811 M
+18 -130 V
+stroke
+LT7
+0.00 0.00 1.00 C 8731 6211 M
+329 228 V
+stroke
+LT2
+0.75 0.00 0.75 C 8731 6211 M
+329 228 V
+stroke
+LT2
+0.75 0.00 0.75 C 9042 6570 M
+18 -131 V
+stroke
+LT3
+0.75 0.75 0.00 C 9371 6798 M
+9060 6439 L
+stroke
+LT6
+0.00 0.50 0.00 C 9371 6798 M
+9060 6439 L
+stroke
+LT6
+0.00 0.50 0.00 C 9042 6570 M
+18 -131 V
+stroke
+LT4
+0.25 0.25 0.25 C 3123 2811 M
+328 228 V
+stroke
+LT8
+0.00 0.75 0.75 C 3123 2811 M
+328 228 V
+stroke
+LT8
+0.00 0.75 0.75 C 3744 3163 M
+3451 3039 L
+stroke
+LT0
+0.75 0.00 0.75 C 4073 3391 M
+3451 3039 L
+stroke
+LT3
+0.00 0.00 1.00 C 4073 3391 M
+3451 3039 L
+stroke
+LT3
+0.00 0.00 1.00 C 3744 3163 M
+3451 3039 L
+stroke
+LT6
+0.00 0.50 0.00 C 9042 6570 M
+329 228 V
+stroke
+LT3
+0.00 0.00 1.00 C 3744 3163 M
+329 228 V
+stroke
+LT7
+0.75 0.00 0.75 C 3744 3163 M
+329 228 V
+stroke
+LT7
+0.75 0.00 0.75 C 4365 3515 M
+4073 3391 L
+stroke
+LT8
+0.75 0.75 0.00 C 4694 3743 M
+4073 3391 L
+stroke
+LT2
+0.00 0.50 0.00 C 4694 3743 M
+4073 3391 L
+stroke
+LT2
+0.00 0.50 0.00 C 4365 3515 M
+4073 3391 L
+stroke
+LT2
+0.00 0.50 0.00 C 4365 3515 M
+329 228 V
+stroke
+LT6
+0.75 0.75 0.00 C 4365 3515 M
+329 228 V
+stroke
+LT6
+0.75 0.75 0.00 C 5608 4218 M
+4694 3743 L
+stroke
+LT7
+0.25 0.25 0.25 C 5936 4446 M
+4694 3743 L
+stroke
+LT1
+1.00 0.00 0.00 C 5936 4446 M
+4694 3743 L
+stroke
+LT1
+1.00 0.00 0.00 C 5608 4218 M
+4694 3743 L
+stroke
+LT1
+1.00 0.00 0.00 C 5608 4218 M
+328 228 V
+stroke
+LT5
+0.25 0.25 0.25 C 5608 4218 M
+328 228 V
+stroke
+LT5
+0.25 0.25 0.25 C 6849 4921 M
+5936 4446 L
+stroke
+LT6
+0.00 0.00 1.00 C 7178 5149 M
+5936 4446 L
+stroke
+LT0
+0.00 0.75 0.75 C 7178 5149 M
+5936 4446 L
+stroke
+LT0
+0.00 0.75 0.75 C 6849 4921 M
+5936 4446 L
+stroke
+LT0
+0.00 0.75 0.75 C 6849 4921 M
+329 228 V
+stroke
+LT4
+0.00 0.00 1.00 C 6849 4921 M
+329 228 V
+stroke
+LT4
+0.00 0.00 1.00 C 7471 5273 M
+7178 5149 L
+stroke
+LT5
+0.00 0.50 0.00 C 7799 5501 M
+7178 5149 L
+stroke
+LT8
+0.75 0.00 0.75 C 7799 5501 M
+7178 5149 L
+stroke
+LT8
+0.75 0.00 0.75 C 7471 5273 M
+7178 5149 L
+stroke
+LT8
+0.75 0.00 0.75 C 7471 5273 M
+328 228 V
+stroke
+LT3
+0.00 0.50 0.00 C 7471 5273 M
+328 228 V
+stroke
+LT3
+0.00 0.50 0.00 C 8092 5624 M
+7799 5501 L
+stroke
+LT4
+1.00 0.00 0.00 C 8421 5853 M
+7799 5501 L
+stroke
+LT7
+0.75 0.75 0.00 C 8421 5853 M
+7799 5501 L
+stroke
+LT7
+0.75 0.75 0.00 C 8092 5624 M
+7799 5501 L
+stroke
+LT0
+0.00 0.00 1.00 C 2282 1942 M
+219 152 V
+stroke
+LT0
+0.00 0.00 1.00 C 2593 2300 M
+-92 -206 V
+stroke
+LT1
+0.00 0.50 0.00 C 2812 2453 M
+2501 2094 L
+stroke
+LT4
+0.75 0.00 0.75 C 2812 2453 M
+2501 2094 L
+stroke
+LT4
+0.75 0.00 0.75 C 2593 2300 M
+-92 -206 V
+stroke
+LT7
+0.75 0.75 0.00 C 8092 5624 M
+329 229 V
+stroke
+LT2
+1.00 0.00 0.00 C 8092 5624 M
+329 229 V
+stroke
+LT2
+1.00 0.00 0.00 C 8403 5983 M
+18 -130 V
+stroke
+LT3
+0.00 0.75 0.75 C 8731 6211 M
+8421 5853 L
+stroke
+LT6
+0.25 0.25 0.25 C 8731 6211 M
+8421 5853 L
+stroke
+LT6
+0.25 0.25 0.25 C 8403 5983 M
+18 -130 V
+stroke
+LT4
+0.75 0.00 0.75 C 2593 2300 M
+219 153 V
+stroke
+LT8
+0.00 0.50 0.00 C 2593 2300 M
+219 153 V
+stroke
+LT8
+0.00 0.50 0.00 C 2903 2659 M
+-91 -206 V
+stroke
+LT0
+1.00 0.00 0.00 C 3123 2811 M
+2812 2453 L
+stroke
+LT3
+0.75 0.75 0.00 C 3123 2811 M
+2812 2453 L
+stroke
+LT3
+0.75 0.75 0.00 C 2903 2659 M
+-91 -206 V
+stroke
+LT6
+0.25 0.25 0.25 C 8403 5983 M
+328 228 V
+stroke
+LT1
+0.00 0.75 0.75 C 8403 5983 M
+328 228 V
+stroke
+LT1
+0.00 0.75 0.75 C 8713 6341 M
+18 -130 V
+stroke
+LT2
+0.75 0.00 0.75 C 9042 6570 M
+8731 6211 L
+stroke
+LT5
+0.00 0.00 1.00 C 9042 6570 M
+8731 6211 L
+stroke
+LT5
+0.00 0.00 1.00 C 8713 6341 M
+18 -130 V
+stroke
+LT3
+0.75 0.75 0.00 C 2903 2659 M
+220 152 V
+stroke
+LT7
+1.00 0.00 0.00 C 2903 2659 M
+220 152 V
+stroke
+LT7
+1.00 0.00 0.00 C 3525 3011 M
+3123 2811 L
+stroke
+LT8
+0.00 0.75 0.75 C 3744 3163 M
+3123 2811 L
+stroke
+LT2
+0.25 0.25 0.25 C 3744 3163 M
+3123 2811 L
+stroke
+LT2
+0.25 0.25 0.25 C 3525 3011 M
+3123 2811 L
+stroke
+LT5
+0.00 0.00 1.00 C 8713 6341 M
+329 229 V
+stroke
+LT2
+0.25 0.25 0.25 C 3525 3011 M
+219 152 V
+stroke
+LT6
+0.00 0.75 0.75 C 3525 3011 M
+219 152 V
+stroke
+LT6
+0.00 0.75 0.75 C 4146 3362 M
+3744 3163 L
+stroke
+LT7
+0.75 0.00 0.75 C 4365 3515 M
+3744 3163 L
+stroke
+LT1
+0.00 0.00 1.00 C 4365 3515 M
+3744 3163 L
+stroke
+LT1
+0.00 0.00 1.00 C 4146 3362 M
+3744 3163 L
+stroke
+LT1
+0.00 0.00 1.00 C 4146 3362 M
+219 153 V
+stroke
+LT5
+0.75 0.00 0.75 C 4146 3362 M
+219 153 V
+stroke
+LT5
+0.75 0.00 0.75 C 5389 4066 M
+4365 3515 L
+stroke
+LT6
+0.75 0.75 0.00 C 5608 4218 M
+4365 3515 L
+stroke
+LT0
+0.00 0.50 0.00 C 5608 4218 M
+4365 3515 L
+stroke
+LT0
+0.00 0.50 0.00 C 5389 4066 M
+4365 3515 L
+stroke
+LT0
+0.00 0.50 0.00 C 5389 4066 M
+219 152 V
+stroke
+LT4
+0.75 0.75 0.00 C 5389 4066 M
+219 152 V
+stroke
+LT4
+0.75 0.75 0.00 C 6630 4769 M
+5608 4218 L
+stroke
+LT5
+0.25 0.25 0.25 C 6849 4921 M
+5608 4218 L
+stroke
+LT8
+1.00 0.00 0.00 C 6849 4921 M
+5608 4218 L
+stroke
+LT8
+1.00 0.00 0.00 C 6630 4769 M
+5608 4218 L
+stroke
+LT0
+0.00 0.00 1.00 C 2593 2300 M
+2282 1942 L
+stroke
+LT8
+0.00 0.50 0.00 C 2903 2659 M
+2593 2300 L
+stroke
+LT8
+1.00 0.00 0.00 C 6630 4769 M
+219 152 V
+stroke
+LT3
+0.25 0.25 0.25 C 6630 4769 M
+219 152 V
+stroke
+LT3
+0.25 0.25 0.25 C 7252 5120 M
+6849 4921 L
+stroke
+LT4
+0.00 0.00 1.00 C 7471 5273 M
+6849 4921 L
+stroke
+LT7
+0.00 0.75 0.75 C 7471 5273 M
+6849 4921 L
+stroke
+LT7
+0.00 0.75 0.75 C 7252 5120 M
+6849 4921 L
+stroke
+LT7
+1.00 0.00 0.00 C 3525 3011 M
+2903 2659 L
+stroke
+LT7
+0.00 0.75 0.75 C 7252 5120 M
+219 153 V
+stroke
+LT2
+0.00 0.00 1.00 C 7252 5120 M
+219 153 V
+stroke
+LT2
+0.00 0.00 1.00 C 7873 5472 M
+7471 5273 L
+stroke
+LT3
+0.00 0.50 0.00 C 8092 5624 M
+7471 5273 L
+stroke
+LT6
+0.75 0.00 0.75 C 8092 5624 M
+7471 5273 L
+stroke
+LT6
+0.75 0.00 0.75 C 7873 5472 M
+7471 5273 L
+stroke
+LT6
+0.00 0.75 0.75 C 4146 3362 M
+3525 3011 L
+stroke
+LT6
+0.75 0.00 0.75 C 7873 5472 M
+219 152 V
+stroke
+LT1
+0.00 0.50 0.00 C 7873 5472 M
+219 152 V
+stroke
+LT1
+0.00 0.50 0.00 C 8184 5831 M
+-92 -207 V
+stroke
+LT2
+1.00 0.00 0.00 C 8403 5983 M
+8092 5624 L
+stroke
+LT5
+0.75 0.75 0.00 C 8403 5983 M
+8092 5624 L
+stroke
+LT5
+0.75 0.75 0.00 C 8184 5831 M
+-92 -207 V
+stroke
+LT5
+0.75 0.00 0.75 C 5389 4066 M
+4146 3362 L
+stroke
+LT5
+0.75 0.75 0.00 C 8184 5831 M
+219 152 V
+stroke
+LT0
+1.00 0.00 0.00 C 8184 5831 M
+219 152 V
+stroke
+LT0
+1.00 0.00 0.00 C 8494 6189 M
+-91 -206 V
+stroke
+LT1
+0.00 0.75 0.75 C 8713 6341 M
+8403 5983 L
+stroke
+LT4
+0.25 0.25 0.25 C 8713 6341 M
+8403 5983 L
+stroke
+LT4
+0.25 0.25 0.25 C 8494 6189 M
+-91 -206 V
+stroke
+LT4
+0.25 0.25 0.25 C 8494 6189 M
+219 152 V
+stroke
+LT4
+0.75 0.75 0.00 C 6630 4769 M
+5389 4066 L
+stroke
+LT3
+0.25 0.25 0.25 C 7252 5120 M
+6630 4769 L
+stroke
+LT2
+0.00 0.00 1.00 C 7873 5472 M
+7252 5120 L
+stroke
+LT1
+0.00 0.50 0.00 C 8184 5831 M
+7873 5472 L
+stroke
+LT0
+1.00 0.00 0.00 C 8494 6189 M
+8184 5831 L
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #1
+stroke
+LT0
+0.00 0.00 1.00 C % End plot #1
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #2
+0.500 UL
+LT1
+0.00 0.50 0.00 C % End plot #2
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #3
+0.500 UL
+LT2
+1.00 0.00 0.00 C % End plot #3
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #4
+0.500 UL
+LT3
+0.00 0.75 0.75 C % End plot #4
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #5
+0.500 UL
+LT4
+0.75 0.00 0.75 C % End plot #5
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #6
+0.500 UL
+LT5
+0.75 0.75 0.00 C % End plot #6
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #7
+0.500 UL
+LT6
+0.25 0.25 0.25 C % End plot #7
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #8
+0.500 UL
+LT7
+0.00 0.00 1.00 C % End plot #8
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #9
+0.500 UL
+LT8
+0.00 0.50 0.00 C % End plot #9
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #10
+0.500 UL
+LT0
+1.00 0.00 0.00 C % End plot #10
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #11
+0.500 UL
+LT1
+0.00 0.75 0.75 C % End plot #11
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #12
+0.500 UL
+LT2
+0.75 0.00 0.75 C % End plot #12
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #13
+0.500 UL
+LT3
+0.75 0.75 0.00 C % End plot #13
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #14
+0.500 UL
+LT4
+0.25 0.25 0.25 C % End plot #14
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #15
+0.500 UL
+LT5
+0.00 0.00 1.00 C % End plot #15
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #16
+0.500 UL
+LT6
+0.00 0.50 0.00 C % End plot #16
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #17
+0.500 UL
+LT7
+1.00 0.00 0.00 C % End plot #17
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #18
+0.500 UL
+LT8
+0.00 0.75 0.75 C % End plot #18
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #19
+0.500 UL
+LT0
+0.75 0.00 0.75 C % End plot #19
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #20
+0.500 UL
+LT1
+0.75 0.75 0.00 C % End plot #20
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #21
+0.500 UL
+LT2
+0.25 0.25 0.25 C % End plot #21
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #22
+0.500 UL
+LT3
+0.00 0.00 1.00 C % End plot #22
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #23
+0.500 UL
+LT4
+0.00 0.50 0.00 C % End plot #23
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #24
+0.500 UL
+LT5
+1.00 0.00 0.00 C % End plot #24
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #25
+0.500 UL
+LT6
+0.00 0.75 0.75 C % End plot #25
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #26
+0.500 UL
+LT7
+0.75 0.00 0.75 C % End plot #26
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #27
+0.500 UL
+LT8
+0.75 0.75 0.00 C % End plot #27
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #28
+0.500 UL
+LT0
+0.25 0.25 0.25 C % End plot #28
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #29
+0.500 UL
+LT1
+0.00 0.00 1.00 C % End plot #29
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #30
+0.500 UL
+LT2
+0.00 0.50 0.00 C % End plot #30
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #31
+0.500 UL
+LT3
+1.00 0.00 0.00 C % End plot #31
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #32
+0.500 UL
+LT4
+0.00 0.75 0.75 C % End plot #32
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #33
+0.500 UL
+LT5
+0.75 0.00 0.75 C % End plot #33
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #34
+0.500 UL
+LT6
+0.75 0.75 0.00 C % End plot #34
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #35
+0.500 UL
+LT7
+0.25 0.25 0.25 C % End plot #35
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #36
+0.500 UL
+LT8
+0.00 0.00 1.00 C % End plot #36
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #37
+0.500 UL
+LT0
+0.00 0.50 0.00 C % End plot #37
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #38
+0.500 UL
+LT1
+1.00 0.00 0.00 C % End plot #38
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #39
+0.500 UL
+LT2
+0.00 0.75 0.75 C % End plot #39
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #40
+0.500 UL
+LT3
+0.75 0.00 0.75 C % End plot #40
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #41
+0.500 UL
+LT4
+0.75 0.75 0.00 C % End plot #41
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #42
+0.500 UL
+LT5
+0.25 0.25 0.25 C % End plot #42
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #43
+0.500 UL
+LT6
+0.00 0.00 1.00 C % End plot #43
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #44
+0.500 UL
+LT7
+0.00 0.50 0.00 C % End plot #44
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #45
+0.500 UL
+LT8
+1.00 0.00 0.00 C % End plot #45
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #46
+0.500 UL
+LT0
+0.00 0.75 0.75 C % End plot #46
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #47
+0.500 UL
+LT1
+0.75 0.00 0.75 C % End plot #47
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #48
+0.500 UL
+LT2
+0.75 0.75 0.00 C % End plot #48
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #49
+0.500 UL
+LT3
+0.25 0.25 0.25 C % End plot #49
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #50
+0.500 UL
+LT4
+0.00 0.00 1.00 C % End plot #50
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #51
+0.500 UL
+LT5
+0.00 0.50 0.00 C % End plot #51
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #52
+0.500 UL
+LT6
+1.00 0.00 0.00 C % End plot #52
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #53
+0.500 UL
+LT7
+0.00 0.75 0.75 C % End plot #53
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #54
+0.500 UL
+LT8
+0.75 0.00 0.75 C % End plot #54
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #55
+0.500 UL
+LT0
+0.75 0.75 0.00 C % End plot #55
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #56
+0.500 UL
+LT1
+0.25 0.25 0.25 C % End plot #56
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #57
+0.500 UL
+LT2
+0.00 0.00 1.00 C % End plot #57
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #58
+0.500 UL
+LT3
+0.00 0.50 0.00 C % End plot #58
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #59
+0.500 UL
+LT4
+1.00 0.00 0.00 C % End plot #59
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #60
+0.500 UL
+LT5
+0.00 0.75 0.75 C % End plot #60
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #61
+0.500 UL
+LT6
+0.75 0.00 0.75 C % End plot #61
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #62
+0.500 UL
+LT7
+0.75 0.75 0.00 C % End plot #62
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #63
+0.500 UL
+LT8
+0.25 0.25 0.25 C % End plot #63
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #64
+0.500 UL
+LT0
+0.00 0.00 1.00 C % End plot #64
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #65
+0.500 UL
+LT1
+0.00 0.50 0.00 C % End plot #65
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #66
+0.500 UL
+LT2
+1.00 0.00 0.00 C % End plot #66
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #67
+0.500 UL
+LT3
+0.00 0.75 0.75 C % End plot #67
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #68
+0.500 UL
+LT4
+0.75 0.00 0.75 C % End plot #68
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #69
+0.500 UL
+LT5
+0.75 0.75 0.00 C % End plot #69
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #70
+0.500 UL
+LT6
+0.25 0.25 0.25 C % End plot #70
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #71
+0.500 UL
+LT7
+0.00 0.00 1.00 C % End plot #71
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #72
+0.500 UL
+LT8
+0.00 0.50 0.00 C % End plot #72
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #73
+0.500 UL
+LT0
+1.00 0.00 0.00 C % End plot #73
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #74
+0.500 UL
+LT1
+0.00 0.75 0.75 C % End plot #74
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #75
+0.500 UL
+LT2
+0.75 0.00 0.75 C % End plot #75
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #76
+0.500 UL
+LT3
+0.75 0.75 0.00 C % End plot #76
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #77
+0.500 UL
+LT4
+0.25 0.25 0.25 C % End plot #77
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #78
+0.500 UL
+LT5
+0.00 0.00 1.00 C % End plot #78
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #79
+0.500 UL
+LT6
+0.00 0.50 0.00 C % End plot #79
+%pm3d_map_begin
+%pm3d_map_end
+% Begin plot #80
+0.500 UL
+LT7
+1.00 0.00 0.00 C % End plot #80
+0.500 UL
+LTb
+9590 2569 M
+8494 1808 L
+2282 1942 M
+8494 1808 L
+2282 1942 M
+1096 761 V
+9590 2569 M
+3378 2703 L
+2282 1942 M
+0 4381 V
+3378 2703 M
+0 4381 V
+9590 2569 M
+0 4381 V
+8494 1808 M
+0 4381 V
+2282 6323 M
+1096 761 V
+9590 6950 M
+3378 7084 L
+2282 6323 M
+8494 6189 L
+1096 761 R
+8494 6189 L
+2282 1942 M
+22 15 V
+stroke
+0.00 0.00 0.00 C 2261 1918 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+3378 2703 M
+-22 -15 V
+169 -773 R
+21 15 V
+stroke
+0.00 0.00 0.00 C 3504 1891 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+4620 2676 M
+-21 -15 V
+168 -773 R
+22 15 V
+stroke
+0.00 0.00 0.00 C 4747 1864 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5863 2649 M
+-22 -15 V
+168 -773 R
+22 15 V
+stroke
+0.00 0.00 0.00 C 5988 1837 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+7105 2622 M
+-22 -15 V
+169 -772 R
+21 15 V
+stroke
+0.00 0.00 0.00 C 7231 1811 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.8)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+8347 2596 M
+-21 -16 V
+168 -772 R
+22 15 V
+stroke
+0.00 0.00 0.00 C 8474 1784 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 2569 M
+-22 -15 V
+8494 1808 M
+-87 2 V
+stroke
+0.00 0.00 0.00 C 8577 1805 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2282 1942 M
+87 -2 V
+6344 20 R
+-86 2 V
+stroke
+0.00 0.00 0.00 C 8796 1957 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.2)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2501 2094 M
+87 -2 V
+6345 20 R
+-87 2 V
+stroke
+0.00 0.00 0.00 C 9015 2109 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.4)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2720 2246 M
+87 -2 V
+6345 20 R
+-87 2 V
+stroke
+0.00 0.00 0.00 C 9234 2261 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.6)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2939 2398 M
+87 -1 V
+6345 20 R
+-87 1 V
+stroke
+0.00 0.00 0.00 C 9453 2414 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.8)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+3159 2551 M
+86 -2 V
+6345 20 R
+-87 2 V
+stroke
+0.00 0.00 0.00 C 9673 2566 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+3378 2703 M
+87 -2 V
+2282 1942 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 2156 1942 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 2569 M
+-88 0 V
+2282 2818 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 2156 2818 M
+[ [(Helvetica) 120.0 0.0 true true 0 (12)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 3445 M
+-88 0 V
+2282 3695 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 2156 3695 M
+[ [(Helvetica) 120.0 0.0 true true 0 (14)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 4322 M
+-88 0 V
+2282 4570 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 2156 4570 M
+[ [(Helvetica) 120.0 0.0 true true 0 (16)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 5197 M
+-88 0 V
+2282 5447 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 2156 5447 M
+[ [(Helvetica) 120.0 0.0 true true 0 (18)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 6074 M
+-88 0 V
+2282 6323 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 2156 6323 M
+[ [(Helvetica) 120.0 0.0 true true 0 (20)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9590 6950 M
+-88 0 V
+1.000 UP
+stroke
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/grid.pdf b/doc/interpreter/grid.pdf
new file mode 100644
index 0000000..1537750
Binary files /dev/null and b/doc/interpreter/grid.pdf differ
diff --git a/doc/interpreter/grid.png b/doc/interpreter/grid.png
new file mode 100644
index 0000000..b50685b
Binary files /dev/null and b/doc/interpreter/grid.png differ
diff --git a/doc/interpreter/grid.txt b/doc/interpreter/grid.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/grid.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/griddata.eps b/doc/interpreter/griddata.eps
new file mode 100644
index 0000000..1bb764b
--- /dev/null
+++ b/doc/interpreter/griddata.eps
@@ -0,0 +1,5142 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: griddata.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:47:01 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (griddata.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:47:01 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1.000 UP
+1.000 UL
+LT1
+.0847 g 1923 3406 M
+1799 2841 L
+stroke
+LT1
+.0835 g 1960 3497 M
+1799 2841 L
+stroke
+LT1
+.2494 g 2084 4065 M
+1960 3497 L
+stroke
+LT1
+.2448 g 2122 4131 M
+1960 3497 L
+stroke
+LT1
+.2477 g 2047 3942 M
+1923 3406 L
+stroke
+LT1
+.2506 g 2084 4065 M
+1923 3406 L
+stroke
+LT1
+.3962 g 2232 4618 M
+2122 4131 L
+stroke
+LT1
+.3918 g 2283 4679 M
+2122 4131 L
+stroke
+LT0
+.6087 g 6142 5511 M
+-70 -110 V
+stroke
+LT0
+.6138 g 5858 5566 M
+67 -167 V
+stroke
+LT0
+.0854 g 9949 3133 M
+124 -668 V
+stroke
+LT0
+.0856 g 9912 3034 M
+161 -569 V
+stroke
+LT0
+.6174 g 6427 5540 M
+-70 -130 V
+stroke
+LT0
+.61 g 6142 5511 M
+47 -104 V
+stroke
+LT0
+.9907 g 6007 7296 M
+-123 73 V
+stroke
+LT0
+.9891 g 6168 7328 M
+-284 41 V
+stroke
+LT0
+.9962 g 5723 7351 M
+161 18 V
+stroke
+LT0
+.9896 g 6292 7302 M
+-124 26 V
+stroke
+LT0
+.987 g 6007 7296 M
+161 32 V
+stroke
+LT0
+.6175 g 5411 5531 M
+46 -122 V
+stroke
+LT0
+.6153 g 5858 5566 M
+5709 5400 L
+stroke
+LT0
+.6335 g 5572 5713 M
+119 -313 V
+stroke
+LT0
+.6519 g 6304 5785 M
+6142 5511 L
+stroke
+LT0
+.6513 g 6018 5794 M
+124 -283 V
+stroke
+LT0
+.6569 g 6018 5794 M
+5858 5566 L
+stroke
+LT0
+.6687 g 5734 5895 M
+124 -329 V
+stroke
+LT0
+.9741 g 4829 7210 M
+-124 27 V
+stroke
+LT0
+.9815 g 4991 7308 M
+-286 -71 V
+stroke
+LT0
+.9674 g 4559 7177 M
+146 60 V
+stroke
+LT0
+.9885 g 6863 7277 M
+-124 16 V
+stroke
+LT0
+.9889 g 6578 7293 M
+161 0 V
+stroke
+LT1
+.3576 g 2122 4230 M
+-38 -165 V
+stroke
+LT1
+.3952 g 2215 4562 M
+2084 4065 L
+stroke
+LT0
+.7114 g 6180 6059 M
+6018 5794 L
+stroke
+LT0
+.7163 g 5895 6109 M
+123 -315 V
+stroke
+LT0
+.9778 g 7142 7213 M
+-117 41 V
+stroke
+LT0
+.985 g 6863 7277 M
+162 -23 V
+stroke
+LT0
+.988 g 5561 7240 M
+-124 104 V
+stroke
+LT0
+.997 g 5723 7351 M
+-286 -7 V
+stroke
+LT0
+.9958 g 5276 7311 M
+161 33 V
+stroke
+LT0
+.6347 g 6713 5636 M
+6597 5404 L
+stroke
+LT0
+.6181 g 6427 5540 M
+77 -141 V
+stroke
+LT0
+.6676 g 6589 5847 M
+6427 5540 L
+stroke
+LT0
+.6576 g 6304 5785 M
+123 -245 V
+stroke
+LT1
+.5035 g 2353 4975 M
+-70 -296 V
+stroke
+LT1
+.5225 g 2445 5192 M
+2283 4679 L
+stroke
+LT0
+.6497 g 5572 5713 M
+5411 5531 L
+stroke
+LT0
+.6717 g 5287 5891 M
+124 -360 V
+stroke
+LT0
+.6216 g 5273 5423 M
+138 108 V
+stroke
+LT0
+.6867 g 5734 5895 M
+5572 5713 L
+stroke
+LT0
+.7063 g 5449 6054 M
+123 -341 V
+stroke
+LT0
+.7185 g 6465 6094 M
+6304 5785 L
+stroke
+LT0
+.7121 g 6180 6059 M
+124 -274 V
+stroke
+LT0
+.7281 g 5895 6109 M
+5734 5895 L
+stroke
+LT0
+.7415 g 5610 6222 M
+124 -327 V
+stroke
+LT0
+.984 g 6131 7205 M
+-124 91 V
+stroke
+LT0
+.9858 g 5847 7232 M
+160 64 V
+stroke
+LT0
+.9913 g 5847 7232 M
+-124 119 V
+stroke
+LT0
+.9906 g 5561 7240 M
+162 111 V
+stroke
+LT0
+.6279 g 6837 5461 M
+-10 -19 V
+stroke
+LT0
+.6544 g 5126 5783 M
+116 -357 V
+stroke
+LT0
+.7751 g 6056 6333 M
+5895 6109 L
+stroke
+LT0
+.7855 g 5771 6423 M
+124 -314 V
+stroke
+LT0
+.7704 g 6341 6321 M
+6180 6059 L
+stroke
+LT0
+.7702 g 6056 6333 M
+124 -274 V
+stroke
+LT0
+.9934 g 5114 7255 M
+-123 53 V
+stroke
+LT0
+.995 g 5276 7311 M
+-285 -3 V
+stroke
+LT0
+.9854 g 4829 7210 M
+162 98 V
+stroke
+LT0
+.9841 g 6416 7173 M
+-124 129 V
+stroke
+LT0
+.9943 g 6578 7293 M
+-286 9 V
+stroke
+LT0
+.9866 g 6131 7205 M
+161 97 V
+stroke
+LT0
+.9731 g 5685 7120 M
+-124 120 V
+stroke
+LT0
+.9751 g 5400 7148 M
+161 92 V
+stroke
+LT0
+.8264 g 6217 6579 M
+6056 6333 L
+stroke
+LT0
+.832 g 5933 6633 M
+123 -300 V
+stroke
+LT0
+.7989 g 5771 6423 M
+5610 6222 L
+stroke
+LT0
+.8136 g 5486 6546 M
+124 -324 V
+stroke
+LT0
+.7611 g 5449 6054 M
+161 168 V
+stroke
+LT0
+.9829 g 5400 7148 M
+-124 163 V
+stroke
+LT0
+.9955 g 5114 7255 M
+162 56 V
+stroke
+LT0
+.7823 g 5325 6393 M
+124 -339 V
+stroke
+LT0
+.7283 g 5287 5891 M
+162 163 V
+stroke
+LT0
+.6823 g 6713 5636 M
+-124 211 V
+stroke
+LT0
+.7404 g 6750 6169 M
+6589 5847 L
+stroke
+LT0
+.7284 g 6465 6094 M
+124 -247 V
+stroke
+LT0
+.753 g 5163 6251 M
+124 -360 V
+stroke
+LT0
+.7037 g 5126 5783 M
+161 108 V
+stroke
+LT0
+.989 g 6702 7193 M
+-124 100 V
+stroke
+LT0
+.9845 g 6416 7173 M
+162 120 V
+stroke
+LT0
+.981 g 4953 7174 M
+-124 36 V
+stroke
+LT0
+.9783 g 4668 7168 M
+161 42 V
+stroke
+LT0
+.8424 g 5933 6633 M
+5771 6423 L
+stroke
+LT0
+.8492 g 5648 6698 M
+123 -275 V
+stroke
+LT0
+.6458 g 6837 5461 M
+-124 175 V
+stroke
+LT0
+.7011 g 6874 5974 M
+6713 5636 L
+stroke
+LT0
+.7768 g 6465 6094 M
+-124 227 V
+stroke
+LT0
+.8311 g 6503 6599 M
+6341 6321 L
+stroke
+LT0
+.8266 g 6217 6579 M
+124 -258 V
+stroke
+LT0
+.9693 g 5969 7073 M
+-122 159 V
+stroke
+LT0
+.9738 g 5685 7120 M
+162 112 V
+stroke
+LT0
+.7872 g 6627 6385 M
+6465 6094 L
+stroke
+LT0
+.6564 g 4964 5698 M
+82 -244 V
+stroke
+LT0
+.9834 g 7272 7181 M
+-124 29 V
+stroke
+LT0
+.9849 g 6987 7205 M
+161 5 V
+stroke
+LT0
+.9623 g 6255 7021 M
+-124 184 V
+stroke
+LT0
+.9675 g 5969 7073 M
+162 132 V
+stroke
+LT0
+.992 g 6987 7205 M
+-124 72 V
+stroke
+LT0
+.9886 g 6702 7193 M
+161 84 V
+stroke
+LT0
+.8808 g 6379 6825 M
+6217 6579 L
+stroke
+LT0
+.8818 g 6093 6846 M
+124 -267 V
+stroke
+LT0
+.8873 g 6093 6846 M
+5933 6633 L
+stroke
+LT0
+.8921 g 5809 6895 M
+124 -262 V
+stroke
+LT0
+.9552 g 5524 6990 M
+-124 158 V
+stroke
+LT0
+.96 g 5238 7040 M
+162 108 V
+stroke
+LT0
+.899 g 5809 6895 M
+5648 6698 L
+stroke
+LT0
+.91 g 5524 6990 M
+124 -292 V
+stroke
+LT0
+.8639 g 5486 6546 M
+162 152 V
+stroke
+LT0
+.9618 g 6540 7022 M
+-124 151 V
+stroke
+LT0
+.9597 g 6255 7021 M
+161 152 V
+stroke
+LT0
+.629 g 6849 5448 M
+-12 13 V
+stroke
+LT0
+.671 g 6998 5810 M
+6837 5461 L
+stroke
+LT0
+.7367 g 5002 6150 M
+124 -367 V
+stroke
+LT0
+.6896 g 4964 5698 M
+162 85 V
+stroke
+LT0
+.9421 g 5809 6895 M
+-124 225 V
+stroke
+LT0
+.9531 g 5524 6990 M
+161 130 V
+stroke
+LT0
+.9376 g 5969 7073 M
+5809 6895 L
+stroke
+LT0
+.8827 g 5362 6851 M
+124 -305 V
+stroke
+LT0
+.8348 g 5325 6393 M
+161 153 V
+stroke
+LT0
+.9328 g 6093 6846 M
+-124 227 V
+stroke
+LT0
+.9266 g 6379 6825 M
+-124 196 V
+stroke
+LT0
+.9276 g 6093 6846 M
+162 175 V
+stroke
+LT0
+.8557 g 5201 6715 M
+124 -322 V
+stroke
+LT0
+.807 g 5163 6251 M
+162 142 V
+stroke
+LT0
+.9726 g 5238 7040 M
+-124 215 V
+stroke
+LT0
+.9889 g 4953 7174 M
+161 81 V
+stroke
+LT0
+.9845 g 4506 7157 M
+-124 35 V
+stroke
+LT0
+.98 g 4668 7168 M
+-286 24 V
+stroke
+LT0
+.9827 g 4221 7157 M
+161 35 V
+stroke
+LT1
+.3983 g 2171 4414 M
+2047 3942 L
+stroke
+LT0
+.4099 g 2208 4600 M
+2047 3942 L
+stroke
+LT1
+.3928 g 2174 4424 M
+2047 3942 L
+stroke
+LT0
+.8854 g 6503 6599 M
+-124 226 V
+stroke
+LT0
+.9286 g 6540 7022 M
+6379 6825 L
+stroke
+LT0
+.8415 g 6627 6385 M
+-124 214 V
+stroke
+LT0
+.8928 g 6664 6868 M
+6503 6599 L
+stroke
+LT0
+.9337 g 5362 6851 M
+-124 189 V
+stroke
+LT0
+.9484 g 5077 6974 M
+161 66 V
+stroke
+LT0
+.9289 g 5362 6851 M
+162 139 V
+stroke
+LT0
+.7991 g 6750 6169 M
+-123 216 V
+stroke
+LT0
+.8523 g 6788 6666 M
+6627 6385 L
+stroke
+LT0
+.9744 g 6826 7070 M
+-124 123 V
+stroke
+LT0
+.9662 g 6540 7022 M
+162 171 V
+stroke
+LT0
+.8324 g 5039 6596 M
+124 -345 V
+stroke
+LT0
+.786 g 5002 6150 M
+161 101 V
+stroke
+LT0
+.9361 g 6664 6868 M
+-124 154 V
+stroke
+LT0
+.9812 g 4791 7130 M
+-123 38 V
+stroke
+LT0
+.983 g 4506 7157 M
+162 11 V
+stroke
+LT0
+.7592 g 6874 5974 M
+-124 195 V
+stroke
+LT0
+.814 g 6912 6483 M
+6750 6169 L
+stroke
+LT0
+.6647 g 4803 5658 M
+59 -178 V
+stroke
+LT0
+.6681 g 7122 5680 M
+-93 -206 V
+stroke
+LT0
+.2464 g 9825 3778 M
+124 -645 V
+stroke
+LT0
+.2529 g 9788 3726 M
+161 -593 V
+stroke
+LT0
+.9036 g 5201 6715 M
+161 136 V
+stroke
+LT0
+.7259 g 4840 6067 M
+124 -369 V
+stroke
+LT0
+.6846 g 4803 5658 M
+161 40 V
+stroke
+LT0
+.7263 g 6998 5810 M
+-124 164 V
+stroke
+LT0
+.7793 g 7036 6306 M
+6874 5974 L
+stroke
+LT0
+.9183 g 5077 6974 M
+124 -259 V
+stroke
+LT0
+.8811 g 5039 6596 M
+162 119 V
+stroke
+LT0
+.9862 g 7111 7119 M
+-124 86 V
+stroke
+LT0
+.9778 g 6826 7070 M
+161 135 V
+stroke
+LT0
+.9647 g 5077 6974 M
+-124 200 V
+stroke
+LT0
+.9839 g 4791 7130 M
+162 44 V
+stroke
+LT0
+.8155 g 4878 6484 M
+124 -334 V
+stroke
+LT0
+.773 g 4840 6067 M
+162 83 V
+stroke
+LT0
+.9036 g 6788 6666 M
+-124 202 V
+stroke
+LT0
+.9443 g 6826 7070 M
+6664 6868 L
+stroke
+LT0
+.9411 g 4915 6898 M
+162 76 V
+stroke
+LT0
+.9898 g 7396 7144 M
+-124 37 V
+stroke
+LT0
+.9849 g 7558 7152 M
+-286 29 V
+stroke
+LT0
+.9847 g 7111 7119 M
+161 62 V
+stroke
+LT0
+.8672 g 6912 6483 M
+-124 183 V
+stroke
+LT0
+.9106 g 6949 6907 M
+6788 6666 L
+stroke
+LT0
+.9513 g 6949 6907 M
+-123 163 V
+stroke
+LT0
+.7022 g 7122 5680 M
+-124 130 V
+stroke
+LT0
+.7529 g 7160 6158 M
+6998 5810 L
+stroke
+LT0
+.9882 g 4345 7132 M
+-124 25 V
+stroke
+LT0
+.9847 g 4059 7119 M
+162 38 V
+stroke
+LT0
+.9038 g 4915 6898 M
+124 -302 V
+stroke
+LT0
+.8618 g 4878 6484 M
+161 112 V
+stroke
+LT0
+.9895 g 7682 7144 M
+-124 8 V
+stroke
+LT0
+.9877 g 7396 7144 M
+162 8 V
+stroke
+LT0
+.8341 g 7036 6306 M
+-124 177 V
+stroke
+LT0
+.8785 g 7073 6738 M
+6912 6483 L
+stroke
+LT0
+.6718 g 7246 5585 M
+-40 -88 V
+stroke
+LT0
+.7283 g 4679 6037 M
+124 -379 V
+stroke
+LT0
+.6896 g 4641 5649 M
+162 9 V
+stroke
+LT0
+.8085 g 4716 6428 M
+124 -361 V
+stroke
+LT0
+.7696 g 4679 6037 M
+161 30 V
+stroke
+LT0
+.9219 g 7073 6738 M
+-124 169 V
+stroke
+LT0
+.9597 g 7111 7119 M
+6949 6907 L
+stroke
+LT0
+.9818 g 4630 7058 M
+-124 99 V
+stroke
+LT0
+.99 g 4345 7132 M
+161 25 V
+stroke
+LT0
+.8891 g 4754 6812 M
+124 -328 V
+stroke
+LT0
+.851 g 4716 6428 M
+162 56 V
+stroke
+LT0
+.9603 g 4791 7130 M
+124 -232 V
+stroke
+LT0
+.9311 g 4754 6812 M
+161 86 V
+stroke
+LT0
+.98 g 4630 7058 M
+161 72 V
+stroke
+LT0
+.8059 g 7160 6158 M
+-124 148 V
+stroke
+LT0
+.8546 g 7197 6622 M
+7036 6306 L
+stroke
+LT0
+.6873 g 7246 5585 M
+-124 95 V
+stroke
+LT0
+.7369 g 7284 6056 M
+7122 5680 L
+stroke
+LT0
+.6766 g 4641 5649 M
+56 -157 V
+stroke
+LT0
+.9716 g 7235 6983 M
+-124 136 V
+stroke
+LT0
+.8991 g 7197 6622 M
+-124 116 V
+stroke
+LT0
+.9339 g 7235 6983 M
+7073 6738 L
+stroke
+LT0
+.9908 g 4183 7103 M
+-124 16 V
+stroke
+LT0
+.9846 g 3898 7069 M
+161 50 V
+stroke
+LT0
+.7876 g 7284 6056 M
+-124 102 V
+stroke
+LT0
+.8334 g 7321 6498 M
+7160 6158 L
+stroke
+LT0
+.9508 g 4630 7058 M
+124 -246 V
+stroke
+LT0
+.9234 g 4592 6753 M
+162 59 V
+stroke
+LT0
+.991 g 7520 7076 M
+-124 68 V
+stroke
+LT0
+.9767 g 7235 6983 M
+161 161 V
+stroke
+LT0
+.952 g 7359 6860 M
+-124 123 V
+stroke
+LT0
+.8853 g 4592 6753 M
+124 -325 V
+stroke
+LT0
+.9747 g 4469 7004 M
+161 54 V
+stroke
+LT0
+.8496 g 4555 6386 M
+161 42 V
+stroke
+LT0
+.9783 g 8091 7009 M
+-124 55 V
+stroke
+LT0
+.9868 g 7805 7085 M
+162 -21 V
+stroke
+LT0
+.9871 g 7682 7144 M
+285 -80 V
+stroke
+LT0
+.8107 g 4555 6386 M
+124 -349 V
+stroke
+LT0
+.7736 g 4517 6009 M
+162 28 V
+stroke
+LT0
+.9829 g 4469 7004 M
+-124 128 V
+stroke
+LT0
+.9944 g 4183 7103 M
+162 29 V
+stroke
+LT0
+.6834 g 7370 5539 M
+-7 -15 V
+stroke
+LT0
+.735 g 4517 6009 M
+124 -360 V
+stroke
+LT0
+.703 g 4480 5671 M
+161 -22 V
+stroke
+LT0
+.2531 g 9788 3726 M
+124 -692 V
+stroke
+LT0
+.2466 g 9750 3578 M
+162 -544 V
+stroke
+LT0
+.6837 g 7370 5539 M
+-124 46 V
+stroke
+LT0
+.7258 g 7407 5954 M
+7246 5585 L
+stroke
+LT0
+.9958 g 7805 7085 M
+-123 59 V
+stroke
+LT0
+.9929 g 7520 7076 M
+162 68 V
+stroke
+LT0
+.8821 g 7321 6498 M
+-124 124 V
+stroke
+LT0
+.9172 g 7359 6860 M
+7197 6622 L
+stroke
+LT1
+.2923 g 6165 3614 M
+-124 -33 V
+stroke
+LT1
+.2913 g 6326 3651 M
+-285 -70 V
+stroke
+LT0
+.9913 g 4022 7068 M
+-124 1 V
+stroke
+LT0
+.9815 g 3736 7009 M
+162 60 V
+stroke
+LT0
+.6943 g 4480 5671 M
+54 -156 V
+stroke
+LT0
+.9473 g 4469 7004 M
+123 -251 V
+stroke
+LT0
+.9197 g 4431 6697 M
+161 56 V
+stroke
+LT0
+.9379 g 7483 6763 M
+-124 97 V
+stroke
+LT0
+.9664 g 7520 7076 M
+7359 6860 L
+stroke
+LT0
+.7754 g 7407 5954 M
+-123 102 V
+stroke
+LT0
+.8192 g 7445 6380 M
+7284 6056 L
+stroke
+LT0
+.9732 g 4307 6959 M
+162 45 V
+stroke
+LT0
+.884 g 4431 6697 M
+124 -311 V
+stroke
+LT0
+.8536 g 4393 6370 M
+162 16 V
+stroke
+LT0
+.3936 g 9701 4344 M
+124 -566 V
+stroke
+LT0
+.4096 g 9664 4363 M
+161 -585 V
+stroke
+LT0
+.8649 g 7445 6380 M
+-124 118 V
+stroke
+LT0
+.9028 g 7483 6763 M
+7321 6498 L
+stroke
+LT0
+.9862 g 7644 6994 M
+-124 82 V
+stroke
+LT0
+.8165 g 4393 6370 M
+124 -361 V
+stroke
+LT0
+.785 g 4356 6035 M
+161 -26 V
+stroke
+LT0
+.557 g 2332 5024 M
+2208 4600 L
+stroke
+LT0
+.5629 g 2370 5169 M
+2208 4600 L
+stroke
+LT0
+.9847 g 4307 6959 M
+-124 144 V
+stroke
+LT0
+.9975 g 4022 7068 M
+161 35 V
+stroke
+LT1
+.3223 g 6450 3742 M
+-124 -91 V
+stroke
+LT1
+.3272 g 6611 3822 M
+6326 3651 L
+stroke
+LT1
+.3034 g 6165 3614 M
+161 37 V
+stroke
+LT0
+.9811 g 8215 6971 M
+-124 38 V
+stroke
+LT0
+.9891 g 7929 7044 M
+162 -35 V
+stroke
+LT0
+.9896 g 3860 7029 M
+-124 -20 V
+stroke
+LT0
+.9738 g 3600 6932 M
+136 77 V
+stroke
+LT0
+.9976 g 7929 7044 M
+-124 41 V
+stroke
+LT0
+.9892 g 7644 6994 M
+161 91 V
+stroke
+LT0
+.9455 g 4307 6959 M
+124 -262 V
+stroke
+LT0
+.9196 g 4270 6666 M
+161 31 V
+stroke
+LT0
+.6862 g 7405 5531 M
+-35 8 V
+stroke
+LT0
+.7278 g 7531 5901 M
+7370 5539 L
+stroke
+LT0
+.7531 g 4356 6035 M
+124 -364 V
+stroke
+LT0
+.7264 g 4318 5736 M
+162 -65 V
+stroke
+LT0
+.7699 g 7531 5901 M
+-124 53 V
+stroke
+LT0
+.8097 g 7569 6298 M
+7407 5954 L
+stroke
+LT0
+.9294 g 7606 6683 M
+-123 80 V
+stroke
+LT0
+.9577 g 7644 6994 M
+7483 6763 L
+stroke
+LT0
+.9744 g 4146 6925 M
+161 34 V
+stroke
+LT0
+.8534 g 7569 6298 M
+-124 82 V
+stroke
+LT0
+.8915 g 7606 6683 M
+7445 6380 L
+stroke
+LT0
+.9798 g 7768 6915 M
+-124 79 V
+stroke
+LT0
+.8892 g 4270 6666 M
+123 -296 V
+stroke
+LT0
+.8636 g 4232 6374 M
+161 -4 V
+stroke
+LT0
+.9873 g 4146 6925 M
+-124 143 V
+stroke
+LT0
+.9994 g 3860 7029 M
+162 39 V
+stroke
+LT1
+.3224 g 6288 3692 M
+-123 -78 V
+stroke
+LT1
+.3086 g 6048 3614 M
+117 0 V
+stroke
+LT0
+.7213 g 4318 5736 M
+63 -176 V
+stroke
+LT0
+.8322 g 4232 6374 M
+124 -339 V
+stroke
+LT0
+.8064 g 4194 6081 M
+162 -46 V
+stroke
+LT0
+.9485 g 4146 6925 M
+124 -259 V
+stroke
+LT0
+.9285 g 4108 6676 M
+162 -10 V
+stroke
+LT0
+.9831 g 8339 6909 M
+-124 62 V
+stroke
+LT0
+.9909 g 8053 6981 M
+162 -10 V
+stroke
+LT0
+.5319 g 2294 4823 M
+2171 4414 L
+stroke
+LT0
+.5454 g 2332 5024 M
+2171 4414 L
+stroke
+LT0
+.9241 g 7730 6610 M
+-124 73 V
+stroke
+LT0
+.9515 g 7768 6915 M
+7606 6683 L
+stroke
+LT0
+.976 g 3984 6884 M
+162 41 V
+stroke
+LT0
+.9989 g 8053 6981 M
+-124 63 V
+stroke
+LT0
+.9882 g 7768 6915 M
+161 129 V
+stroke
+LT0
+.85 g 7693 6241 M
+-124 57 V
+stroke
+LT0
+.886 g 7730 6610 M
+7569 6298 L
+stroke
+LT0
+.7736 g 7655 5867 M
+-124 34 V
+stroke
+LT0
+.8103 g 7693 6241 M
+7531 5901 L
+stroke
+LT1
+.3767 g 6735 3950 M
+6611 3822 L
+stroke
+LT1
+.3898 g 6897 4091 M
+6611 3822 L
+stroke
+LT1
+.3471 g 6450 3742 M
+161 80 V
+stroke
+LT0
+.7397 g 7655 5867 M
+7513 5553 L
+stroke
+LT0
+.975 g 7892 6844 M
+-124 71 V
+stroke
+LT0
+.9881 g 3984 6884 M
+-124 145 V
+stroke
+LT0
+.9976 g 3699 6968 M
+161 61 V
+stroke
+LT0
+.7797 g 4194 6081 M
+124 -345 V
+stroke
+LT0
+.7591 g 4157 5827 M
+161 -91 V
+stroke
+LT0
+.9029 g 4108 6676 M
+124 -302 V
+stroke
+LT0
+.881 g 4071 6412 M
+161 -38 V
+stroke
+LT0
+.5281 g 9578 4894 M
+123 -550 V
+stroke
+LT0
+.537 g 9540 4859 M
+161 -515 V
+stroke
+LT0
+.4161 g 9664 4363 M
+124 -637 V
+stroke
+LT0
+.4165 g 9626 4265 M
+162 -539 V
+stroke
+LT1
+.3431 g 6127 3693 M
+-64 -41 V
+stroke
+LT1
+.3672 g 6574 3872 M
+6450 3742 L
+stroke
+LT1
+.3413 g 6288 3692 M
+162 50 V
+stroke
+LT0
+.956 g 4108 6676 M
+-124 208 V
+stroke
+LT0
+.9805 g 3823 6872 M
+161 12 V
+stroke
+LT0
+.921 g 7854 6545 M
+-124 65 V
+stroke
+LT0
+.9476 g 7892 6844 M
+7730 6610 L
+stroke
+LT0
+.9777 g 8463 6818 M
+-124 91 V
+stroke
+LT0
+.9907 g 8177 6928 M
+162 -19 V
+stroke
+LT0
+.9426 g 3947 6683 M
+161 -7 V
+stroke
+LT0
+.99 g 3823 6872 M
+-124 96 V
+stroke
+LT0
+.9932 g 3537 6909 M
+162 59 V
+stroke
+LT0
+.6928 g 2493 5555 M
+2370 5169 L
+stroke
+LT0
+.7436 g 2531 5672 M
+-34 -106 V
+stroke
+LT0
+.9986 g 8177 6928 M
+-124 53 V
+stroke
+LT0
+.9856 g 7892 6844 M
+161 137 V
+stroke
+LT0
+.853 g 7817 6206 M
+-124 35 V
+stroke
+LT0
+.885 g 7854 6545 M
+7693 6241 L
+stroke
+LT0
+.8553 g 4071 6412 M
+123 -331 V
+stroke
+LT0
+.8346 g 4033 6158 M
+161 -77 V
+stroke
+LT0
+.9732 g 8016 6788 M
+-124 56 V
+stroke
+LT0
+.7857 g 7779 5877 M
+-124 -10 V
+stroke
+LT0
+.8164 g 7817 6206 M
+7655 5867 L
+stroke
+LT1
+.3669 g 6412 3832 M
+6288 3692 L
+stroke
+LT1
+.3465 g 6127 3693 M
+161 -1 V
+stroke
+LT0
+.7525 g 4157 5827 M
+84 -223 V
+stroke
+LT0
+.7612 g 7779 5877 M
+7647 5592 L
+stroke
+LT0
+.9929 g 3661 6865 M
+-124 44 V
+stroke
+LT0
+.983 g 3376 6805 M
+161 104 V
+stroke
+LT0
+.9753 g 8586 6777 M
+-123 41 V
+stroke
+LT0
+.9808 g 8301 6831 M
+162 -13 V
+stroke
+LT0
+.9208 g 3947 6683 M
+124 -271 V
+stroke
+LT0
+.9031 g 3909 6451 M
+162 -39 V
+stroke
+LT0
+.9672 g 3947 6683 M
+-124 189 V
+stroke
+LT0
+.9898 g 3661 6865 M
+162 7 V
+stroke
+LT0
+.9235 g 7978 6515 M
+-124 30 V
+stroke
+LT0
+.9466 g 8016 6788 M
+7854 6545 L
+stroke
+LT1
+.4919 g 7182 4429 M
+7058 4262 L
+stroke
+LT1
+.5137 g 7343 4634 M
+7058 4262 L
+stroke
+LT1
+.4448 g 6897 4091 M
+161 171 V
+stroke
+LT0
+.9577 g 3785 6701 M
+162 -18 V
+stroke
+LT0
+.8139 g 4033 6158 M
+124 -331 V
+stroke
+LT0
+.7978 g 3995 5937 M
+162 -110 V
+stroke
+LT1
+.4558 g 7021 4244 M
+6897 4091 L
+stroke
+LT1
+.4145 g 6735 3950 M
+162 141 V
+stroke
+LT0
+.9938 g 8301 6831 M
+-124 97 V
+stroke
+LT0
+.9862 g 8016 6788 M
+161 140 V
+stroke
+LT0
+.9875 g 3500 6841 M
+-124 -36 V
+stroke
+LT0
+.9744 g 3366 6798 M
+10 7 V
+stroke
+LT0
+.41 g 9626 4265 M
+124 -687 V
+stroke
+LT0
+.3968 g 9589 4066 M
+161 -488 V
+stroke
+LT1
+.4333 g 6859 4130 M
+6735 3950 L
+stroke
+LT1
+.3969 g 6574 3872 M
+161 78 V
+stroke
+LT0
+.8626 g 7941 6199 M
+-124 7 V
+stroke
+LT0
+.8915 g 7978 6515 M
+7817 6206 L
+stroke
+LT0
+.9752 g 8140 6745 M
+-124 43 V
+stroke
+LT1
+.5479 g 4577 4569 M
+32 -43 V
+stroke
+LT0
+.6444 g 9454 5324 M
+124 -430 V
+stroke
+LT0
+.6609 g 9416 5346 M
+162 -452 V
+stroke
+LT1
+.3775 g 6251 3822 M
+6127 3693 L
+stroke
+LT1
+.3564 g 6085 3711 M
+42 -18 V
+stroke
+LT0
+.6798 g 2456 5402 M
+2332 5024 L
+stroke
+LT0
+.6869 g 2493 5555 M
+2332 5024 L
+stroke
+LT0
+.8824 g 3909 6451 M
+124 -293 V
+stroke
+LT0
+.8673 g 3871 6238 M
+162 -80 V
+stroke
+LT0
+.8066 g 7903 5910 M
+-124 -33 V
+stroke
+LT0
+.8319 g 7941 6199 M
+7779 5877 L
+stroke
+LT0
+.9803 g 3785 6701 M
+-124 164 V
+stroke
+LT0
+.9974 g 3500 6841 M
+161 24 V
+stroke
+LT1
+.4204 g 6698 4025 M
+6574 3872 L
+stroke
+LT1
+.3928 g 6412 3832 M
+162 40 V
+stroke
+LT0
+.9528 g 3171 6663 M
+-86 -64 V
+stroke
+LT0
+.9799 g 3338 6789 M
+3172 6664 L
+stroke
+LT0
+.9745 g 8710 6698 M
+-124 79 V
+stroke
+LT0
+.985 g 8425 6789 M
+161 -12 V
+stroke
+LT0
+.9905 g 8425 6789 M
+-124 42 V
+stroke
+LT0
+.9829 g 8140 6745 M
+161 86 V
+stroke
+LT0
+.8065 g 2655 5987 M
+2531 5672 L
+stroke
+LT0
+.94 g 3785 6701 M
+124 -250 V
+stroke
+LT0
+.9269 g 3748 6502 M
+161 -51 V
+stroke
+LT0
+.9319 g 8102 6494 M
+-124 21 V
+stroke
+LT0
+.9521 g 8140 6745 M
+7978 6515 L
+stroke
+LT0
+.553 g 9540 4859 M
+124 -496 V
+stroke
+LT0
+.5664 g 9502 4858 M
+162 -495 V
+stroke
+LT0
+.9743 g 3624 6720 M
+161 -19 V
+stroke
+LT0
+.7865 g 3995 5937 M
+114 -291 V
+stroke
+LT0
+.7811 g 3958 5775 M
+128 -122 V
+stroke
+LT0
+.7552 g 7775 5645 M
+-6 -14 V
+stroke
+LT0
+.7879 g 7903 5910 M
+7776 5646 L
+stroke
+LT0
+.9798 g 8263 6708 M
+-123 37 V
+stroke
+LT0
+.8802 g 8064 6224 M
+-123 -25 V
+stroke
+LT0
+.903 g 8102 6494 M
+7941 6199 L
+stroke
+LT1
+.4223 g 6536 3991 M
+6412 3832 L
+stroke
+LT1
+.3979 g 6251 3822 M
+161 10 V
+stroke
+LT0
+.7343 g 9330 5678 M
+124 -354 V
+stroke
+LT0
+.7513 g 9292 5704 M
+162 -380 V
+stroke
+LT0
+.9914 g 3624 6720 M
+-124 121 V
+stroke
+LT0
+.9989 g 3338 6789 M
+162 52 V
+stroke
+LT0
+.963 g 8834 6577 M
+-124 121 V
+stroke
+LT0
+.9836 g 8549 6744 M
+161 -46 V
+stroke
+LT0
+.8512 g 3871 6238 M
+124 -301 V
+stroke
+LT0
+.8416 g 3834 6066 M
+161 -129 V
+stroke
+LT0
+.6453 g 2418 5144 M
+2294 4823 L
+stroke
+LT0
+.6664 g 2456 5402 M
+2294 4823 L
+stroke
+LT0
+.9941 g 8549 6744 M
+-124 45 V
+stroke
+LT0
+.9875 g 8263 6708 M
+162 81 V
+stroke
+LT0
+.9083 g 2854 6341 M
+-20 -38 V
+stroke
+LT0
+.9118 g 3748 6502 M
+123 -264 V
+stroke
+LT0
+.8997 g 3710 6311 M
+161 -73 V
+stroke
+LT0
+.8334 g 8027 5963 M
+-124 -53 V
+stroke
+LT0
+.8549 g 8064 6224 M
+7903 5910 L
+stroke
+LT0
+.9413 g 8226 6471 M
+-124 23 V
+stroke
+LT0
+.9597 g 8263 6708 M
+8102 6494 L
+stroke
+LT1
+.519 g 7144 4447 M
+7021 4244 L
+stroke
+LT1
+.5029 g 7182 4429 M
+7021 4244 L
+stroke
+LT1
+.4745 g 6859 4130 M
+162 114 V
+stroke
+LT0
+.9612 g 3748 6502 M
+-124 218 V
+stroke
+LT0
+.985 g 3462 6693 M
+162 27 V
+stroke
+LT0
+.9435 g 8923 6455 M
+-89 122 V
+stroke
+LT0
+.9285 g 8958 6408 M
+-35 47 V
+stroke
+LT0
+.9735 g 8673 6676 M
+161 -99 V
+stroke
+LT1
+.5551 g 7306 4618 M
+7182 4429 L
+stroke
+LT1
+.5437 g 7343 4634 M
+7182 4429 L
+stroke
+LT0
+.9533 g 3586 6561 M
+162 -59 V
+stroke
+LT0
+.9925 g 3462 6693 M
+-124 96 V
+stroke
+LT0
+.9869 g 3177 6665 M
+161 124 V
+stroke
+LT0
+.8313 g 9168 6059 M
+162 -381 V
+stroke
+LT1
+.5705 g 4577 4569 M
+-124 174 V
+stroke
+LT1
+.6241 g 4292 4981 M
+161 -238 V
+stroke
+LT0
+.9841 g 8387 6663 M
+-124 45 V
+stroke
+LT1
+.5983 g 7467 4821 M
+7343 4634 L
+stroke
+LT1
+.6243 g 7629 5059 M
+7343 4634 L
+stroke
+LT1
+.4317 g 6375 3983 M
+6251 3822 L
+stroke
+LT1
+.4121 g 6144 3865 M
+107 -43 V
+stroke
+LT0
+.6698 g 9416 5346 M
+124 -487 V
+stroke
+LT0
+.6854 g 9379 5362 M
+161 -503 V
+stroke
+LT1
+.4985 g 6983 4322 M
+6859 4130 L
+stroke
+LT1
+.4569 g 6698 4025 M
+161 105 V
+stroke
+LT0
+.7936 g 2617 5807 M
+2493 5555 L
+stroke
+LT0
+.8042 g 2655 5987 M
+2493 5555 L
+stroke
+LT0
+.9873 g 3301 6691 M
+-124 -26 V
+stroke
+LT0
+.9756 g 3169 6659 M
+8 6 V
+stroke
+LT0
+.9659 g 3015 6549 M
+153 109 V
+stroke
+LT0
+.8812 g 9082 6244 M
+57 -132 V
+stroke
+LT1
+.5521 g 4604 4537 M
+-27 32 V
+stroke
+LT1
+.5926 g 4416 4807 M
+161 -238 V
+stroke
+LT0
+.7916 g 3958 5775 M
+43 -98 V
+stroke
+LT0
+.5667 g 9502 4858 M
+124 -593 V
+stroke
+LT0
+.56 g 9465 4708 M
+161 -443 V
+stroke
+LT0
+.9252 g 2918 6405 M
+-64 -64 V
+stroke
+LT0
+.9494 g 2978 6464 M
+-60 -59 V
+stroke
+LT0
+.9193 g 2902 6403 M
+-48 -62 V
+stroke
+LT0
+.9414 g 3015 6549 M
+2902 6403 L
+stroke
+LT0
+.9941 g 8673 6676 M
+-124 68 V
+stroke
+LT0
+.9907 g 8387 6663 M
+162 81 V
+stroke
+LT0
+.9017 g 8188 6245 M
+-124 -21 V
+stroke
+LT0
+.9185 g 8226 6471 M
+8064 6224 L
+stroke
+LT0
+.9752 g 3139 6629 M
+-124 -80 V
+stroke
+LT1
+.4838 g 6822 4230 M
+6698 4025 L
+stroke
+LT1
+.4499 g 6536 3991 M
+162 34 V
+stroke
+LT0
+.9299 g 8921 6457 M
+161 -213 V
+stroke
+LT0
+.8019 g 7989 5754 M
+-102 -82 V
+stroke
+LT0
+.7801 g 7872 5668 M
+-1 -2 V
+stroke
+LT0
+.8144 g 8027 5963 M
+7873 5669 L
+stroke
+LT0
+.8334 g 3834 6066 M
+124 -291 V
+stroke
+LT0
+.8294 g 3796 5935 M
+162 -160 V
+stroke
+LT0
+.9771 g 3586 6561 M
+-124 132 V
+stroke
+LT0
+.9928 g 3301 6691 M
+161 2 V
+stroke
+LT1
+.6046 g 4540 4671 M
+18 -29 V
+stroke
+LT0
+.954 g 8350 6475 M
+-124 -4 V
+stroke
+LT0
+.9657 g 8387 6663 M
+8226 6471 L
+stroke
+LT0
+.8901 g 3710 6311 M
+124 -245 V
+stroke
+LT0
+.8869 g 3672 6187 M
+162 -121 V
+stroke
+LT0
+.9899 g 8511 6638 M
+-124 25 V
+stroke
+LT0
+.9412 g 3586 6561 M
+124 -250 V
+stroke
+LT0
+.9355 g 3549 6418 M
+161 -107 V
+stroke
+LT0
+.9764 g 3425 6587 M
+161 -26 V
+stroke
+LT0
+.8653 g 8151 6033 M
+-124 -70 V
+stroke
+LT0
+.8802 g 8188 6245 M
+8027 5963 L
+stroke
+LT1
+.4854 g 6660 4188 M
+6536 3991 L
+stroke
+LT1
+.4561 g 6375 3983 M
+161 8 V
+stroke
+LT0
+.9885 g 8797 6588 M
+-124 88 V
+stroke
+LT0
+.9933 g 8511 6638 M
+162 38 V
+stroke
+LT0
+.5468 g 9465 4708 M
+124 -642 V
+stroke
+LT0
+.5328 g 9427 4503 M
+162 -437 V
+stroke
+LT0
+.7774 g 2580 5638 M
+2456 5402 L
+stroke
+LT0
+.7866 g 2617 5807 M
+2456 5402 L
+stroke
+LT0
+.8882 g 2779 6167 M
+2655 5987 L
+stroke
+LT0
+.8902 g 2816 6283 M
+2655 5987 L
+stroke
+LT0
+.7678 g 9292 5704 M
+124 -358 V
+stroke
+LT0
+.7867 g 9255 5744 M
+161 -398 V
+stroke
+LT0
+.9921 g 3425 6587 M
+-124 104 V
+stroke
+LT0
+.996 g 3139 6629 M
+162 62 V
+stroke
+LT0
+.813 g 7989 5754 M
+-29 -54 V
+stroke
+LT0
+.927 g 8312 6298 M
+-124 -53 V
+stroke
+LT0
+.9372 g 8350 6475 M
+8188 6245 L
+stroke
+LT0
+.9954 g 8635 6590 M
+-124 48 V
+stroke
+LT0
+.9781 g 8350 6475 M
+161 163 V
+stroke
+LT0
+.9744 g 8921 6457 M
+-124 131 V
+stroke
+LT0
+.9905 g 8635 6590 M
+162 -2 V
+stroke
+LT1
+.6252 g 7430 4837 M
+7306 4618 L
+stroke
+LT1
+.6097 g 7467 4821 M
+7306 4618 L
+stroke
+LT1
+.5711 g 7144 4447 M
+162 171 V
+stroke
+LT0
+.9728 g 8474 6497 M
+-124 -22 V
+stroke
+LT1
+.5922 g 7268 4675 M
+7144 4447 L
+stroke
+LT1
+.5429 g 6983 4322 M
+161 125 V
+stroke
+LT1
+.6462 g 4416 4807 M
+-124 174 V
+stroke
+LT1
+.701 g 4130 5229 M
+162 -248 V
+stroke
+LT0
+.992 g 3263 6561 M
+-124 68 V
+stroke
+LT0
+.9773 g 2978 6464 M
+161 165 V
+stroke
+LT1
+.4972 g 6499 4196 M
+6375 3983 L
+stroke
+LT1
+.4743 g 6214 4040 M
+161 -57 V
+stroke
+LT0
+.9484 g 2940 6407 M
+2816 6283 L
+stroke
+LT0
+.9366 g 2925 6405 M
+2816 6283 L
+stroke
+LT0
+.9551 g 2978 6464 M
+-52 -58 V
+stroke
+LT0
+.9721 g 3102 6490 M
+-124 -26 V
+stroke
+LT0
+.9708 g 3549 6418 M
+-124 169 V
+stroke
+LT0
+.9882 g 3263 6561 M
+162 26 V
+stroke
+LT0
+.8483 g 9168 6059 M
+124 -355 V
+stroke
+LT0
+.8356 g 9209 5886 M
+83 -182 V
+stroke
+LT0
+.889 g 9131 6057 M
+77 -170 V
+stroke
+LT0
+.8339 g 3796 5935 M
+106 -218 V
+stroke
+LT0
+.8415 g 3759 5855 M
+114 -124 V
+stroke
+LT0
+.7348 g 2542 5376 M
+2418 5144 L
+stroke
+LT0
+.7564 g 2580 5638 M
+2418 5144 L
+stroke
+LT1
+.6667 g 7591 5030 M
+7467 4821 L
+stroke
+LT1
+.657 g 7629 5059 M
+7467 4821 L
+stroke
+LT0
+.6988 g 9379 5362 M
+123 -504 V
+stroke
+LT0
+.691 g 9341 5203 M
+161 -345 V
+stroke
+LT0
+.8416 g 8113 5864 M
+7989 5754 L
+stroke
+LT0
+.8508 g 8151 6033 M
+7989 5754 L
+stroke
+LT0
+.8828 g 3672 6187 M
+124 -252 V
+stroke
+LT0
+.8821 g 3635 6081 M
+161 -146 V
+stroke
+LT1
+.57 g 7107 4548 M
+6983 4322 L
+stroke
+LT1
+.5254 g 6822 4230 M
+161 92 V
+stroke
+LT1
+.6197 g 4540 4671 M
+-124 136 V
+stroke
+LT1
+.6718 g 4254 5072 M
+162 -265 V
+stroke
+LT0
+.9323 g 3549 6418 M
+123 -231 V
+stroke
+LT0
+.9298 g 3511 6298 M
+161 -111 V
+stroke
+LT0
+.9693 g 3387 6476 M
+162 -58 V
+stroke
+LT0
+.9478 g 9044 6276 M
+-123 181 V
+stroke
+LT0
+.9805 g 8759 6533 M
+162 -76 V
+stroke
+LT1
+.716 g 7753 5248 M
+7629 5059 L
+stroke
+LT0
+.866 g 2741 5981 M
+2617 5807 L
+stroke
+LT0
+.8776 g 2779 6167 M
+2617 5807 L
+stroke
+LT1
+.5583 g 6945 4465 M
+6822 4230 L
+stroke
+LT1
+.5192 g 6660 4188 M
+162 42 V
+stroke
+LT0
+.9098 g 9168 6059 M
+-124 217 V
+stroke
+LT0
+.9582 g 8883 6433 M
+161 -157 V
+stroke
+LT0
+.9012 g 8275 6117 M
+-124 -84 V
+stroke
+LT0
+.9121 g 8312 6298 M
+8151 6033 L
+stroke
+LT0
+.9233 g 9007 6276 M
+161 -217 V
+stroke
+LT1
+.6087 g 4549 4664 M
+-9 7 V
+stroke
+LT1
+.6507 g 4378 4937 M
+162 -266 V
+stroke
+LT0
+.9868 g 3387 6476 M
+-124 85 V
+stroke
+LT0
+.9868 g 3102 6490 M
+161 71 V
+stroke
+LT0
+.9967 g 8759 6533 M
+-124 57 V
+stroke
+LT0
+.99 g 8474 6497 M
+161 93 V
+stroke
+LT0
+.9534 g 8436 6328 M
+-124 -30 V
+stroke
+LT0
+.9626 g 8474 6497 M
+8312 6298 L
+stroke
+LT1
+.5243 g 6337 4245 M
+6218 4047 L
+stroke
+LT0
+.9869 g 8598 6466 M
+-124 31 V
+stroke
+LT1
+.5588 g 6784 4424 M
+6660 4188 L
+stroke
+LT1
+.5264 g 6499 4196 M
+161 -8 V
+stroke
+LT0
+.9832 g 3226 6433 M
+-124 57 V
+stroke
+LT0
+.9779 g 2940 6407 M
+162 83 V
+stroke
+LT0
+.8486 g 8113 5864 M
+-80 -136 V
+stroke
+LT0
+.6842 g 9341 5203 M
+124 -495 V
+stroke
+LT0
+.6826 g 9303 5090 M
+162 -382 V
+stroke
+LT0
+.9445 g 2903 6293 M
+2779 6167 L
+stroke
+LT0
+.9464 g 2940 6407 M
+2779 6167 L
+stroke
+LT0
+.8023 g 9255 5744 M
+124 -382 V
+stroke
+LT0
+.8055 g 9217 5667 M
+162 -305 V
+stroke
+LT0
+.9667 g 3511 6298 M
+-124 178 V
+stroke
+LT0
+.9831 g 3226 6433 M
+161 43 V
+stroke
+LT0
+.9909 g 8883 6433 M
+-124 100 V
+stroke
+LT0
+.9935 g 8598 6466 M
+161 67 V
+stroke
+LT0
+.8478 g 2704 5813 M
+2580 5638 L
+stroke
+LT0
+.8569 g 2741 5981 M
+2580 5638 L
+stroke
+LT0
+.929 g 3635 6081 M
+-124 217 V
+stroke
+LT0
+.9625 g 3350 6344 M
+161 -46 V
+stroke
+LT0
+.9821 g 3064 6420 M
+-124 -13 V
+stroke
+LT0
+.8849 g 3759 5855 M
+-124 226 V
+stroke
+LT0
+.9314 g 3473 6215 M
+162 -134 V
+stroke
+LT0
+.8858 g 8237 5969 M
+8113 5864 L
+stroke
+LT0
+.8921 g 8275 6117 M
+8113 5864 L
+stroke
+LT0
+.8528 g 3814 5759 M
+-55 96 V
+stroke
+LT0
+.8881 g 3597 6003 M
+162 -148 V
+stroke
+LT0
+.8761 g 3721 5834 M
+38 -46 V
+stroke
+LT1
+.7266 g 4254 5072 M
+-124 157 V
+stroke
+LT1
+.7707 g 4011 5425 M
+119 -196 V
+stroke
+LT1
+.7699 g 3973 5459 M
+157 -230 V
+stroke
+LT0
+.979 g 3350 6344 M
+-124 89 V
+stroke
+LT0
+.9874 g 3064 6420 M
+162 13 V
+stroke
+LT1
+.7022 g 7554 5078 M
+7430 4837 L
+stroke
+LT1
+.6823 g 7591 5030 M
+7430 4837 L
+stroke
+LT1
+.6463 g 7268 4675 M
+162 162 V
+stroke
+LT0
+.9936 g 8721 6433 M
+-123 33 V
+stroke
+LT0
+.9776 g 8436 6328 M
+162 138 V
+stroke
+LT0
+.9376 g 8399 6191 M
+-124 -74 V
+stroke
+LT0
+.9425 g 8436 6328 M
+8275 6117 L
+stroke
+LT1
+.5711 g 6623 4420 M
+6499 4196 L
+stroke
+LT1
+.5458 g 6337 4245 M
+162 -49 V
+stroke
+LT1
+.6714 g 7392 4923 M
+7268 4675 L
+stroke
+LT1
+.6193 g 7107 4548 M
+161 127 V
+stroke
+LT0
+.8803 g 9131 6057 M
+124 -313 V
+stroke
+LT0
+.8858 g 9093 5997 M
+162 -253 V
+stroke
+LT1
+.7398 g 7715 5252 M
+7591 5030 L
+stroke
+LT1
+.7257 g 7753 5248 M
+7591 5030 L
+stroke
+LT0
+.9717 g 9007 6276 M
+-124 157 V
+stroke
+LT0
+.9909 g 8721 6433 M
+162 0 V
+stroke
+LT0
+.6686 g 9303 5090 M
+124 -587 V
+stroke
+LT0
+.6464 g 9266 4824 M
+161 -321 V
+stroke
+LT0
+.9757 g 8560 6351 M
+-124 -23 V
+stroke
+LT0
+.8105 g 2666 5595 M
+2542 5376 L
+stroke
+LT0
+.8262 g 2704 5813 M
+2542 5376 L
+stroke
+LT1
+.7027 g 4378 4937 M
+-124 135 V
+stroke
+LT1
+.7545 g 4093 5336 M
+161 -264 V
+stroke
+LT1
+.6502 g 7231 4804 M
+7107 4548 L
+stroke
+LT1
+.6028 g 6945 4465 M
+162 83 V
+stroke
+LT1
+.7841 g 7877 5452 M
+7753 5248 L
+stroke
+LT1
+.7894 g 7956 5539 M
+7753 5248 L
+stroke
+LT0
+.9273 g 2865 6149 M
+2741 5981 L
+stroke
+LT0
+.9147 g 2821 6134 M
+-80 -153 V
+stroke
+LT0
+.9507 g 2903 6293 M
+-82 -159 V
+stroke
+LT0
+.9367 g 9129 6059 M
+-122 217 V
+stroke
+LT0
+.9724 g 8847 6338 M
+160 -62 V
+stroke
+LT0
+.9419 g 8969 6217 M
+162 -160 V
+stroke
+LT0
+.7976 g 9217 5667 M
+124 -464 V
+stroke
+LT0
+.7962 g 9179 5555 M
+162 -352 V
+stroke
+LT0
+.9649 g 3473 6215 M
+-123 129 V
+stroke
+LT0
+.9817 g 3188 6353 M
+162 -9 V
+stroke
+LT1
+.6911 g 4408 4914 M
+-30 23 V
+stroke
+LT1
+.7345 g 4217 5208 M
+161 -271 V
+stroke
+LT1
+.6402 g 7069 4726 M
+6945 4465 L
+stroke
+LT1
+.5979 g 6784 4424 M
+161 41 V
+stroke
+LT0
+.9902 g 3188 6353 M
+-124 67 V
+stroke
+LT0
+.9803 g 2903 6293 M
+161 127 V
+stroke
+LT0
+.9918 g 8845 6339 M
+-124 94 V
+stroke
+LT0
+.9916 g 8560 6351 M
+161 82 V
+stroke
+LT0
+.9774 g 3027 6299 M
+-124 -6 V
+stroke
+LT0
+.8934 g 8200 5881 M
+-83 -93 V
+stroke
+LT0
+.8653 g 8102 5778 M
+-6 -7 V
+stroke
+LT0
+.887 g 8237 5969 M
+8103 5780 L
+stroke
+LT1
+.5966 g 6461 4473 M
+6337 4245 L
+stroke
+LT1
+.5603 g 6315 4254 M
+22 -9 V
+stroke
+LT0
+.9345 g 3597 6003 M
+-124 212 V
+stroke
+LT0
+.965 g 3312 6244 M
+161 -29 V
+stroke
+LT0
+.9003 g 3708 5852 M
+-111 151 V
+stroke
+LT0
+.8851 g 3721 5834 M
+-12 17 V
+stroke
+LT0
+.9372 g 3436 6134 M
+161 -131 V
+stroke
+LT0
+.9292 g 8361 6074 M
+8237 5969 L
+stroke
+LT0
+.9313 g 8399 6191 M
+8237 5969 L
+stroke
+LT1
+.6404 g 6908 4681 M
+6784 4424 L
+stroke
+LT1
+.6034 g 6623 4420 M
+161 4 V
+stroke
+LT0
+.9923 g 8684 6338 M
+-124 13 V
+stroke
+LT0
+.9708 g 8399 6191 M
+161 160 V
+stroke
+LT0
+.9026 g 2828 5932 M
+2704 5813 L
+stroke
+LT0
+.9182 g 2865 6149 M
+2704 5813 L
+stroke
+LT0
+.9683 g 8522 6231 M
+-123 -40 V
+stroke
+LT0
+.8807 g 3742 5803 M
+-21 31 V
+stroke
+LT0
+.8874 g 3699 5856 M
+22 -22 V
+stroke
+LT0
+.9152 g 3560 5995 M
+137 -137 V
+stroke
+LT0
+.9818 g 3312 6244 M
+-124 109 V
+stroke
+LT0
+.9874 g 3027 6299 M
+161 54 V
+stroke
+LT0
+.978 g 8969 6217 M
+-124 122 V
+stroke
+LT0
+.9925 g 8684 6338 M
+161 1 V
+stroke
+LT0
+.8889 g 9093 5997 M
+124 -330 V
+stroke
+LT0
+.8886 g 9056 5894 M
+161 -227 V
+stroke
+LT0
+.7945 g 9179 5555 M
+124 -465 V
+stroke
+LT0
+.7833 g 9142 5371 M
+161 -281 V
+stroke
+LT0
+.9474 g 9093 5997 M
+-124 220 V
+stroke
+LT0
+.9792 g 8808 6247 M
+161 -30 V
+stroke
+LT0
+.9677 g 3436 6134 M
+-124 110 V
+stroke
+LT0
+.9807 g 3151 6244 M
+161 0 V
+stroke
+LT0
+.9863 g 3151 6244 M
+-124 55 V
+stroke
+LT0
+.972 g 2868 6152 M
+159 147 V
+stroke
+LT0
+.95 g 8932 6135 M
+161 -138 V
+stroke
+LT1
+.6505 g 6746 4674 M
+6623 4420 L
+stroke
+LT1
+.6219 g 6461 4473 M
+162 -53 V
+stroke
+LT0
+.9708 g 2989 6192 M
+-124 -43 V
+stroke
+LT1
+.8131 g 7839 5463 M
+7715 5252 L
+stroke
+LT1
+.7982 g 7877 5452 M
+7715 5252 L
+stroke
+LT1
+.7597 g 7554 5078 M
+161 174 V
+stroke
+LT1
+.7806 g 7678 5307 M
+7554 5078 L
+stroke
+LT1
+.7272 g 7392 4923 M
+162 155 V
+stroke
+LT0
+.8702 g 2790 5707 M
+2666 5595 L
+stroke
+LT0
+.8869 g 2828 5932 M
+2666 5595 L
+stroke
+LT1
+.7535 g 7516 5173 M
+7392 4923 L
+stroke
+LT1
+.7022 g 7231 4804 M
+161 119 V
+stroke
+LT1
+.8336 g 7931 5534 M
+-54 -82 V
+stroke
+LT1
+.8309 g 7944 5537 M
+-67 -85 V
+stroke
+LT1
+.7862 g 4217 5208 M
+-124 128 V
+stroke
+LT1
+.8044 g 4056 5390 M
+37 -54 V
+stroke
+LT1
+.804 g 4043 5399 M
+50 -63 V
+stroke
+LT0
+.9937 g 8808 6247 M
+-124 91 V
+stroke
+LT0
+.9898 g 8522 6231 M
+162 107 V
+stroke
+LT0
+.9043 g 8200 5881 M
+-45 -61 V
+stroke
+LT0
+.7612 g 9142 5371 M
+124 -547 V
+stroke
+LT0
+.7377 g 9104 5095 M
+162 -271 V
+stroke
+LT1
+.7344 g 7355 5062 M
+7231 4804 L
+stroke
+LT1
+.6875 g 7069 4726 M
+162 78 V
+stroke
+LT0
+.9496 g 3560 5995 M
+-124 139 V
+stroke
+LT0
+.972 g 3274 6175 M
+162 -41 V
+stroke
+LT0
+.9326 g 8322 5987 M
+8200 5881 L
+stroke
+LT0
+.9191 g 8266 5961 M
+-66 -80 V
+stroke
+LT0
+.9394 g 8361 6074 M
+-93 -111 V
+stroke
+LT0
+.9886 g 8646 6228 M
+-124 3 V
+stroke
+LT0
+.9661 g 8361 6074 M
+161 157 V
+stroke
+LT0
+.9651 g 8485 6123 M
+-124 -49 V
+stroke
+LT1
+.7742 g 4281 5160 M
+-64 48 V
+stroke
+LT1
+.7948 g 4143 5323 M
+74 -115 V
+stroke
+LT0
+.985 g 3274 6175 M
+-123 69 V
+stroke
+LT0
+.9854 g 2989 6192 M
+162 52 V
+stroke
+LT0
+.8871 g 9056 5894 M
+123 -339 V
+stroke
+LT0
+.8777 g 9018 5723 M
+161 -168 V
+stroke
+LT1
+.7251 g 7193 4984 M
+7069 4726 L
+stroke
+LT1
+.6827 g 6908 4681 M
+161 45 V
+stroke
+LT0
+.9818 g 8932 6135 M
+-124 112 V
+stroke
+LT0
+.9925 g 8646 6228 M
+162 19 V
+stroke
+LT0
+.9298 g 3636 5895 M
+-76 100 V
+stroke
+LT0
+.9557 g 3398 6079 M
+162 -84 V
+stroke
+LT0
+.9423 g 2951 5995 M
+-123 -63 V
+stroke
+LT0
+.9552 g 2989 6192 M
+2828 5932 L
+stroke
+LT1
+.674 g 6585 4707 M
+6461 4473 L
+stroke
+LT1
+.6369 g 6440 4481 M
+21 -8 V
+stroke
+LT0
+.9912 g 3113 6187 M
+-124 5 V
+stroke
+LT0
+.9497 g 8932 6135 M
+124 -241 V
+stroke
+LT0
+.9464 g 8894 6010 M
+162 -116 V
+stroke
+LT0
+.9848 g 8770 6169 M
+162 -34 V
+stroke
+LT1
+.7253 g 7032 4942 M
+6908 4681 L
+stroke
+LT1
+.6875 g 6746 4674 M
+162 7 V
+stroke
+LT0
+.9781 g 3398 6079 M
+-124 96 V
+stroke
+LT0
+.9908 g 3113 6187 M
+161 -12 V
+stroke
+LT0
+.9955 g 8770 6169 M
+-124 59 V
+stroke
+LT0
+.9876 g 8485 6123 M
+161 105 V
+stroke
+LT0
+.9107 g 2914 5783 M
+-124 -76 V
+stroke
+LT0
+.9257 g 2951 5995 M
+2790 5707 L
+stroke
+LT0
+.8665 g 9018 5723 M
+124 -352 V
+stroke
+LT0
+.8576 g 8980 5556 M
+162 -185 V
+stroke
+LT0
+.9868 g 8609 6122 M
+-124 1 V
+stroke
+LT0
+.9671 g 8323 5988 M
+162 135 V
+stroke
+LT0
+.9695 g 3522 5997 M
+-124 82 V
+stroke
+LT0
+.9833 g 3237 6113 M
+161 -34 V
+stroke
+LT1
+.8595 g 7876 5524 M
+-37 -61 V
+stroke
+LT1
+.8556 g 7899 5528 M
+-60 -65 V
+stroke
+LT1
+.834 g 7678 5307 M
+161 156 V
+stroke
+LT0
+.9379 g 8268 5928 M
+-44 -48 V
+stroke
+LT0
+.9488 g 8322 5987 M
+-53 -58 V
+stroke
+LT0
+.9703 g 8447 6046 M
+-124 -58 V
+stroke
+LT1
+.8517 g 7786 5500 M
+7678 5307 L
+stroke
+LT1
+.8069 g 7516 5173 M
+162 134 V
+stroke
+LT1
+.7344 g 6870 4930 M
+6746 4674 L
+stroke
+LT1
+.7027 g 6585 4707 M
+161 -33 V
+stroke
+LT0
+.9718 g 3075 6038 M
+-124 -43 V
+stroke
+LT0
+.9783 g 3113 6187 M
+2951 5995 L
+stroke
+LT0
+.996 g 3237 6113 M
+-124 74 V
+stroke
+LT0
+.9815 g 8894 6010 M
+-124 159 V
+stroke
+LT0
+.9948 g 8614 6124 M
+156 45 V
+stroke
+LT1
+.8324 g 7640 5397 M
+7516 5173 L
+stroke
+LT1
+.7857 g 7355 5062 M
+161 111 V
+stroke
+LT0
+.937 g 8894 6010 M
+124 -287 V
+stroke
+LT0
+.9304 g 8857 5860 M
+161 -137 V
+stroke
+LT0
+.8342 g 8980 5556 M
+124 -461 V
+stroke
+LT0
+.8138 g 8943 5304 M
+161 -209 V
+stroke
+LT1
+.816 g 7479 5298 M
+7355 5062 L
+stroke
+LT1
+.772 g 7193 4984 M
+162 78 V
+stroke
+LT0
+.9782 g 8733 6043 M
+161 -33 V
+stroke
+LT0
+.9589 g 3646 5886 M
+-124 111 V
+stroke
+LT0
+.9781 g 3361 6042 M
+161 -45 V
+stroke
+LT0
+.0828 g 5553 1846 M
+5392 1185 L
+stroke
+LT0
+.0838 g 5268 1866 M
+124 -681 V
+stroke
+LT0
+.9914 g 8733 6043 M
+-123 79 V
+stroke
+LT0
+.99 g 8447 6046 M
+162 76 V
+stroke
+LT0
+.9918 g 3361 6042 M
+-124 71 V
+stroke
+LT0
+.9895 g 3075 6038 M
+162 75 V
+stroke
+LT1
+.8074 g 7317 5225 M
+7193 4984 L
+stroke
+LT1
+.7677 g 7032 4942 M
+161 42 V
+stroke
+LT0
+.9384 g 3038 5800 M
+-124 -17 V
+stroke
+LT0
+.9568 g 3075 6038 M
+2914 5783 L
+stroke
+LT1
+.7186 g 6602 4741 M
+-17 -34 V
+stroke
+LT1
+.7133 g 6581 4708 M
+4 -1 V
+stroke
+LT0
+.9459 g 3748 5797 M
+-102 89 V
+stroke
+LT0
+.9398 g 3757 5790 M
+-7 6 V
+stroke
+LT0
+.9696 g 3485 5976 M
+161 -90 V
+stroke
+LT0
+.992 g 8571 6036 M
+-124 10 V
+stroke
+LT0
+.9765 g 8286 5934 M
+161 112 V
+stroke
+LT0
+.9898 g 3199 6016 M
+-124 22 V
+stroke
+LT0
+.9215 g 8857 5860 M
+123 -304 V
+stroke
+LT0
+.9116 g 8819 5686 M
+161 -130 V
+stroke
+LT0
+.9716 g 8857 5860 M
+-124 183 V
+stroke
+LT0
+.9934 g 8571 6036 M
+162 7 V
+stroke
+LT0
+.9803 g 8410 5974 M
+-124 -40 V
+stroke
+LT0
+.9543 g 8124 5793 M
+162 141 V
+stroke
+LT1
+.8065 g 7156 5173 M
+7032 4942 L
+stroke
+LT1
+.7722 g 6870 4930 M
+162 12 V
+stroke
+LT0
+.9887 g 3485 5976 M
+-124 66 V
+stroke
+LT0
+.9922 g 3199 6016 M
+162 26 V
+stroke
+LT0
+.9704 g 8695 5934 M
+162 -74 V
+stroke
+LT0
+.957 g 8236 5859 M
+-112 -66 V
+stroke
+LT0
+.936 g 8049 5734 M
+75 59 V
+stroke
+LT0
+.8912 g 8819 5686 M
+124 -382 V
+stroke
+LT0
+.8717 g 8781 5439 M
+162 -135 V
+stroke
+LT1
+.8777 g 7640 5397 M
+107 86 V
+stroke
+LT0
+.9585 g 3162 5818 M
+-124 -18 V
+stroke
+LT0
+.9714 g 3199 6016 M
+3038 5800 L
+stroke
+LT0
+.9922 g 8695 5934 M
+-124 102 V
+stroke
+LT0
+.9958 g 8410 5974 M
+161 62 V
+stroke
+LT0
+.9958 g 3323 5969 M
+-124 47 V
+stroke
+LT1
+.8802 g 7681 5454 M
+-41 -57 V
+stroke
+LT1
+.8627 g 7479 5298 M
+161 99 V
+stroke
+LT1
+.7989 g 6940 5066 M
+-70 -136 V
+stroke
+LT1
+.782 g 6764 4943 M
+106 -13 V
+stroke
+LT0
+.9822 g 3609 5879 M
+-124 97 V
+stroke
+LT0
+.9924 g 3323 5969 M
+162 7 V
+stroke
+LT1
+.8734 g 7541 5404 M
+-62 -106 V
+stroke
+LT1
+.8514 g 7317 5225 M
+162 73 V
+stroke
+LT0
+.9604 g 8695 5934 M
+124 -248 V
+stroke
+LT0
+.9479 g 8658 5740 M
+161 -54 V
+stroke
+LT0
+.993 g 8534 5915 M
+-124 59 V
+stroke
+LT0
+.9848 g 8248 5867 M
+162 107 V
+stroke
+LT0
+.9894 g 8534 5915 M
+161 19 V
+stroke
+LT0
+.2516 g 5429 2536 M
+5268 1866 L
+stroke
+LT0
+.2422 g 5144 2480 M
+124 -614 V
+stroke
+LT0
+.9742 g 3732 5803 M
+-123 76 V
+stroke
+LT0
+.9882 g 3447 5921 M
+162 -42 V
+stroke
+LT0
+.2462 g 5715 2490 M
+5553 1846 L
+stroke
+LT0
+.2506 g 5429 2536 M
+124 -690 V
+stroke
+LT0
+.985 g 8372 5875 M
+-124 -8 V
+stroke
+LT0
+.9671 g 8087 5754 M
+161 113 V
+stroke
+LT1
+.8659 g 7378 5335 M
+-61 -110 V
+stroke
+LT1
+.8463 g 7156 5173 M
+161 52 V
+stroke
+LT0
+.9984 g 3447 5921 M
+-124 48 V
+stroke
+LT0
+.9829 g 3162 5818 M
+161 151 V
+stroke
+LT0
+.9724 g 3286 5790 M
+-124 28 V
+stroke
+LT0
+.9284 g 8658 5740 M
+123 -301 V
+stroke
+LT0
+.9127 g 8620 5522 M
+161 -83 V
+stroke
+LT0
+.9769 g 8658 5740 M
+-124 175 V
+stroke
+LT0
+.9932 g 8372 5875 M
+162 40 V
+stroke
+LT0
+.9702 g 3856 5736 M
+-124 67 V
+stroke
+LT0
+.9854 g 3571 5862 M
+161 -59 V
+stroke
+LT1
+.8502 g 7172 5203 M
+-16 -30 V
+stroke
+LT1
+.8462 g 7125 5173 M
+31 0 V
+stroke
+LT0
+.9718 g 8496 5776 M
+162 -36 V
+stroke
+LT0
+.9994 g 3571 5862 M
+-124 59 V
+stroke
+LT0
+.9879 g 3286 5790 M
+161 131 V
+stroke
+LT0
+.9783 g 3409 5748 M
+-123 42 V
+stroke
+LT0
+.9881 g 8496 5776 M
+-124 99 V
+stroke
+LT0
+.9923 g 8211 5821 M
+161 54 V
+stroke
+LT0
+.9695 g 3980 5683 M
+-124 53 V
+stroke
+LT0
+.9817 g 3695 5788 M
+161 -52 V
+stroke
+LT0
+.4017 g 5305 3155 M
+5144 2480 L
+stroke
+LT0
+.3769 g 5020 2984 M
+124 -504 V
+stroke
+LT0
+.9562 g 8496 5776 M
+124 -254 V
+stroke
+LT0
+.942 g 8459 5570 M
+161 -48 V
+stroke
+LT0
+.9969 g 3695 5788 M
+-124 74 V
+stroke
+LT0
+.9898 g 3409 5748 M
+162 114 V
+stroke
+LT0
+.9922 g 8335 5774 M
+-124 47 V
+stroke
+LT0
+.9851 g 8049 5734 M
+162 87 V
+stroke
+LT0
+.9881 g 8335 5774 M
+161 2 V
+stroke
+LT0
+.9816 g 3533 5701 M
+-124 47 V
+stroke
+LT0
+.9879 g 8173 5741 M
+-124 -7 V
+stroke
+LT0
+.977 g 7888 5672 M
+161 62 V
+stroke
+LT0
+.4103 g 5591 3136 M
+5429 2536 L
+stroke
+LT0
+.4111 g 5305 3155 M
+124 -619 V
+stroke
+LT0
+.3979 g 5876 3064 M
+5715 2490 L
+stroke
+LT0
+.4059 g 5591 3136 M
+124 -646 V
+stroke
+LT0
+.9726 g 4104 5646 M
+-124 37 V
+stroke
+LT0
+.9821 g 3819 5730 M
+161 -47 V
+stroke
+LT0
+.9943 g 3819 5730 M
+-124 58 V
+stroke
+LT0
+.9887 g 3533 5701 M
+162 87 V
+stroke
+LT0
+.9739 g 8459 5570 M
+-124 204 V
+stroke
+LT0
+.9949 g 8190 5744 M
+145 30 V
+stroke
+LT0
+.9862 g 8012 5702 M
+-124 -30 V
+stroke
+LT0
+.9624 g 8297 5587 M
+162 -17 V
+stroke
+LT0
+.984 g 3657 5652 M
+-124 49 V
+stroke
+LT0
+.524 g 5182 3677 M
+5020 2984 L
+stroke
+LT0
+.4987 g 4896 3501 M
+124 -517 V
+stroke
+LT0
+.9775 g 4228 5606 M
+-124 40 V
+stroke
+LT0
+.9827 g 3943 5658 M
+161 -12 V
+stroke
+LT0
+.9922 g 3943 5658 M
+-124 72 V
+stroke
+LT0
+.9897 g 3657 5652 M
+162 78 V
+stroke
+LT0
+.9834 g 8297 5587 M
+-123 153 V
+stroke
+LT0
+.9971 g 8012 5702 M
+161 39 V
+stroke
+LT0
+.9745 g 8136 5573 M
+161 14 V
+stroke
+LT0
+.985 g 3781 5594 M
+-124 58 V
+stroke
+LT0
+.9881 g 8136 5573 M
+-124 129 V
+stroke
+LT0
+.9977 g 7850 5658 M
+162 44 V
+stroke
+LT0
+.9937 g 4067 5627 M
+-124 31 V
+stroke
+LT0
+.9875 g 3781 5594 M
+162 64 V
+stroke
+LT0
+.9825 g 4352 5569 M
+-124 37 V
+stroke
+LT0
+.9885 g 4067 5627 M
+161 -21 V
+stroke
+LT0
+.5546 g 5467 3707 M
+5305 3155 L
+stroke
+LT0
+.5488 g 5182 3677 M
+123 -522 V
+stroke
+LT0
+.5329 g 6037 3584 M
+5876 3064 L
+stroke
+LT0
+.5422 g 5752 3667 M
+124 -603 V
+stroke
+LT0
+.5502 g 5752 3667 M
+5591 3136 L
+stroke
+LT0
+.5538 g 5467 3707 M
+124 -571 V
+stroke
+LT0
+.6453 g 5058 4177 M
+4896 3501 L
+stroke
+LT0
+.6261 g 4772 4047 M
+124 -546 V
+stroke
+LT0
+.9802 g 7974 5543 M
+162 30 V
+stroke
+LT0
+.9858 g 7689 5604 M
+-204 -59 V
+stroke
+LT0
+.9822 g 3905 5518 M
+-124 76 V
+stroke
+LT0
+.9898 g 7974 5543 M
+-124 115 V
+stroke
+LT0
+.9964 g 7689 5604 M
+161 54 V
+stroke
+LT0
+.9791 g 4352 5569 M
+176 -53 V
+stroke
+LT0
+.9866 g 4476 5523 M
+-124 46 V
+stroke
+LT0
+.9921 g 4190 5577 M
+162 -8 V
+stroke
+LT0
+.9981 g 4190 5577 M
+-123 50 V
+stroke
+LT0
+.9883 g 3905 5518 M
+162 109 V
+stroke
+LT0
+.9838 g 7813 5512 M
+161 31 V
+stroke
+LT0
+.9903 g 7813 5512 M
+-124 92 V
+stroke
+LT0
+.994 g 7527 5552 M
+162 52 V
+stroke
+LT0
+.9846 g 7366 5510 M
+-124 -7 V
+stroke
+LT0
+.9845 g 7527 5552 M
+-285 -49 V
+stroke
+LT0
+.9779 g 7101 5479 M
+141 24 V
+stroke
+LT0
+.9728 g 4029 5410 M
+-124 108 V
+stroke
+LT0
+.6818 g 5343 4248 M
+5182 3677 L
+stroke
+LT0
+.6706 g 5058 4177 M
+124 -500 V
+stroke
+LT0
+.9855 g 7651 5441 M
+-124 111 V
+stroke
+LT0
+.993 g 7366 5510 M
+161 42 V
+stroke
+LT0
+.6475 g 6198 4005 M
+6037 3584 L
+stroke
+LT0
+.6525 g 5914 4056 M
+123 -472 V
+stroke
+LT0
+.9818 g 7651 5441 M
+162 71 V
+stroke
+LT0
+.9839 g 4600 5434 M
+-124 89 V
+stroke
+LT0
+.9845 g 4761 5483 M
+-285 40 V
+stroke
+LT0
+.984 g 4314 5448 M
+162 75 V
+stroke
+LT0
+.9894 g 4314 5448 M
+-124 129 V
+stroke
+LT0
+.9825 g 4029 5410 M
+161 167 V
+stroke
+LT0
+.6885 g 5628 4241 M
+5467 3707 L
+stroke
+LT0
+.6877 g 5343 4248 M
+124 -541 V
+stroke
+LT0
+.961 g 4153 5316 M
+-124 94 V
+stroke
+LT0
+.7563 g 4934 4572 M
+4772 4047 L
+stroke
+LT0
+.7363 g 4648 4437 M
+124 -390 V
+stroke
+LT0
+.988 g 4885 5479 M
+-124 4 V
+stroke
+LT0
+.9803 g 4600 5434 M
+161 49 V
+stroke
+LT0
+.6619 g 5914 4056 M
+5752 3667 L
+stroke
+LT0
+.6849 g 5628 4241 M
+124 -574 V
+stroke
+LT0
+.9805 g 6919 5466 M
+-221 -57 V
+stroke
+LT0
+.9767 g 7490 5387 M
+161 54 V
+stroke
+LT0
+.9704 g 4438 5321 M
+-124 127 V
+stroke
+LT0
+.968 g 4153 5316 M
+161 132 V
+stroke
+LT0
+.9842 g 7490 5387 M
+-124 123 V
+stroke
+LT0
+.9957 g 7204 5486 M
+162 24 V
+stroke
+LT0
+.9834 g 4724 5406 M
+-124 28 V
+stroke
+LT0
+.9704 g 4438 5321 M
+162 113 V
+stroke
+LT0
+.9439 g 4277 5169 M
+-124 147 V
+stroke
+LT0
+.836 g 4810 4890 M
+4648 4437 L
+stroke
+LT0
+.8113 g 4525 4719 M
+123 -282 V
+stroke
+LT0
+.9809 g 7043 5344 M
+-124 122 V
+stroke
+LT0
+.994 g 7204 5486 M
+-285 -20 V
+stroke
+LT0
+.9882 g 6758 5412 M
+161 54 V
+stroke
+LT0
+.7891 g 5219 4660 M
+5058 4177 L
+stroke
+LT0
+.7755 g 4934 4572 M
+124 -395 V
+stroke
+LT0
+.9526 g 4562 5201 M
+-124 120 V
+stroke
+LT0
+.9464 g 4277 5169 M
+161 152 V
+stroke
+LT0
+.8619 g 4525 4719 M
+-124 208 V
+stroke
+LT0
+.9131 g 4562 5201 M
+4401 4927 L
+stroke
+LT0
+.907 g 4277 5169 M
+124 -242 V
+stroke
+LT0
+.9711 g 7328 5311 M
+162 76 V
+stroke
+LT0
+.8764 g 4686 5022 M
+4525 4719 L
+stroke
+LT0
+.7546 g 6074 4445 M
+5914 4056 L
+stroke
+LT0
+.7703 g 5790 4575 M
+124 -519 V
+stroke
+LT0
+.7386 g 6360 4350 M
+6198 4005 L
+stroke
+LT0
+.7496 g 6074 4445 M
+124 -440 V
+stroke
+LT0
+.9965 g 5009 5432 M
+-124 47 V
+stroke
+LT0
+.9909 g 5170 5434 M
+-285 45 V
+stroke
+LT0
+.9912 g 4724 5406 M
+161 73 V
+stroke
+LT0
+.9833 g 6758 5412 M
+-260 -14 V
+stroke
+LT0
+.9923 g 5294 5418 M
+-124 16 V
+stroke
+LT0
+.9923 g 5009 5432 M
+161 2 V
+stroke
+LT0
+.9826 g 7328 5311 M
+-124 175 V
+stroke
+LT0
+.9853 g 7043 5344 M
+161 142 V
+stroke
+LT0
+.9603 g 7167 5199 M
+-124 145 V
+stroke
+LT0
+.9658 g 6881 5253 M
+162 91 V
+stroke
+LT0
+.9276 g 4686 5022 M
+-124 179 V
+stroke
+LT0
+.9656 g 4724 5406 M
+4562 5201 L
+stroke
+LT0
+.9731 g 6881 5253 M
+-123 159 V
+stroke
+LT0
+.9897 g 6596 5391 M
+162 21 V
+stroke
+LT0
+.8043 g 5504 4675 M
+5343 4248 L
+stroke
+LT0
+.8004 g 5219 4660 M
+124 -412 V
+stroke
+LT0
+.9577 g 7167 5199 M
+161 112 V
+stroke
+LT0
+.976 g 4847 5265 M
+-123 141 V
+stroke
+LT0
+.9012 g 4810 4890 M
+-124 132 V
+stroke
+LT0
+.938 g 4847 5265 M
+4686 5022 L
+stroke
+LT0
+.866 g 5095 4951 M
+4934 4572 L
+stroke
+LT0
+.856 g 4810 4890 M
+124 -318 V
+stroke
+LT0
+.7933 g 5790 4575 M
+5628 4241 L
+stroke
+LT0
+.8051 g 5504 4675 M
+124 -434 V
+stroke
+LT0
+.9938 g 6149 5386 M
+-124 13 V
+stroke
+LT0
+.9916 g 6311 5414 M
+-286 -15 V
+stroke
+LT0
+.9936 g 5865 5399 M
+160 0 V
+stroke
+LT0
+.9406 g 7005 5097 M
+162 102 V
+stroke
+LT0
+.9461 g 7005 5097 M
+-124 156 V
+stroke
+LT0
+.9618 g 6720 5226 M
+161 27 V
+stroke
+LT0
+.8088 g 6521 4615 M
+6360 4350 L
+stroke
+LT0
+.8319 g 6236 4800 M
+124 -450 V
+stroke
+LT0
+.9925 g 5133 5335 M
+-124 97 V
+stroke
+LT0
+.9813 g 4847 5265 M
+162 167 V
+stroke
+LT0
+.9594 g 4971 5168 M
+-124 97 V
+stroke
+LT0
+.9952 g 6435 5356 M
+-124 58 V
+stroke
+LT0
+.9941 g 6596 5391 M
+-285 23 V
+stroke
+LT0
+.9975 g 6149 5386 M
+162 28 V
+stroke
+LT0
+.8429 g 6236 4800 M
+6074 4445 L
+stroke
+LT0
+.8537 g 5950 4894 M
+124 -449 V
+stroke
+LT0
+.9226 g 4971 5168 M
+4810 4890 L
+stroke
+LT0
+.9283 g 6844 5020 M
+161 77 V
+stroke
+LT0
+.9924 g 5418 5322 M
+-124 96 V
+stroke
+LT0
+.9972 g 5580 5401 M
+-286 17 V
+stroke
+LT0
+.9925 g 5133 5335 M
+161 83 V
+stroke
+LT0
+.9784 g 6720 5226 M
+-124 165 V
+stroke
+LT0
+.9939 g 6435 5356 M
+161 35 V
+stroke
+LT0
+.9914 g 5704 5305 M
+-124 96 V
+stroke
+LT0
+.9981 g 5865 5399 M
+-285 2 V
+stroke
+LT0
+.9919 g 5418 5322 M
+162 79 V
+stroke
+LT0
+.8663 g 6682 4865 M
+6521 4615 L
+stroke
+LT0
+.8842 g 6397 5011 M
+124 -396 V
+stroke
+LT0
+.8862 g 5381 4987 M
+5219 4660 L
+stroke
+LT0
+.8796 g 5095 4951 M
+124 -291 V
+stroke
+LT0
+.8694 g 5950 4894 M
+5790 4575 L
+stroke
+LT0
+.8776 g 5666 4968 M
+124 -393 V
+stroke
+LT0
+.9439 g 6844 5020 M
+-124 206 V
+stroke
+LT0
+.9629 g 6559 5175 M
+161 51 V
+stroke
+LT0
+.996 g 5988 5316 M
+-123 83 V
+stroke
+LT0
+.9928 g 5704 5305 M
+161 94 V
+stroke
+LT0
+.9699 g 5257 5150 M
+-124 185 V
+stroke
+LT0
+.9706 g 4971 5168 M
+162 167 V
+stroke
+LT0
+.9089 g 6682 4865 M
+162 155 V
+stroke
+LT0
+.9326 g 5095 4951 M
+-124 217 V
+stroke
+LT0
+.9319 g 5257 5150 M
+5095 4951 L
+stroke
+LT0
+.9279 g 6559 5175 M
+123 -310 V
+stroke
+LT0
+.8893 g 5666 4968 M
+5504 4675 L
+stroke
+LT0
+.8901 g 5381 4987 M
+123 -312 V
+stroke
+LT0
+.9909 g 6273 5263 M
+-124 123 V
+stroke
+LT0
+.9962 g 5988 5316 M
+161 70 V
+stroke
+LT0
+.9777 g 5542 5195 M
+-124 127 V
+stroke
+LT0
+.9698 g 5257 5150 M
+161 172 V
+stroke
+LT0
+.9384 g 5381 4987 M
+-124 163 V
+stroke
+LT0
+.9785 g 6559 5175 M
+-124 181 V
+stroke
+LT0
+.9886 g 6273 5263 M
+162 93 V
+stroke
+LT0
+.9754 g 5827 5168 M
+-123 137 V
+stroke
+LT0
+.9772 g 5542 5195 M
+162 110 V
+stroke
+LT0
+.9073 g 6397 5011 M
+6236 4800 L
+stroke
+LT0
+.9225 g 6112 5138 M
+124 -338 V
+stroke
+LT0
+.9458 g 6397 5011 M
+162 164 V
+stroke
+LT0
+.9463 g 5542 5195 M
+5381 4987 L
+stroke
+LT0
+.9559 g 6273 5263 M
+124 -252 V
+stroke
+LT0
+.9333 g 6112 5138 M
+5950 4894 L
+stroke
+LT0
+.9356 g 5827 5168 M
+123 -274 V
+stroke
+LT0
+.9763 g 6112 5138 M
+-124 178 V
+stroke
+LT0
+.9787 g 5827 5168 M
+161 148 V
+stroke
+LT0
+.9711 g 6112 5138 M
+161 125 V
+stroke
+LT0
+.9455 g 5666 4968 M
+-124 227 V
+stroke
+LT0
+.9437 g 5827 5168 M
+5666 4968 L
+% Begin plot #1
+stroke
+LT0
+.262 g % End plot #1
+0.500 UL
+LTb
+5354 960 M
+5004 1354 V
+5354 960 M
+1514 2725 L
+3352 907 V
+10358 2314 M
+6764 3966 L
+1514 6578 M
+0 -3853 V
+6518 7932 M
+0 -637 V
+10358 6167 M
+0 -3853 V
+5105 7550 M
+1413 382 V
+1514 6578 M
+3589 971 V
+10358 6167 M
+6518 7932 L
+5354 960 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 5427 904 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1590 2690 M
+-76 35 V
+6605 1298 M
+-77 35 V
+stroke
+0.00 0.00 0.00 C 6677 1243 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2841 3029 M
+-76 35 V
+7856 1637 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 7928 1581 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+4092 3367 M
+-76 35 V
+9107 1976 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 9180 1920 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10358 2314 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 10431 2259 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5354 960 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 5288 930 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10288 2295 M
+70 19 V
+4394 1401 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 4327 1371 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9328 2737 M
+70 19 V
+3434 1842 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 3367 1812 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+8368 3178 M
+70 19 V
+2474 2284 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 2407 2254 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+7408 3619 M
+70 19 V
+1514 2725 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 1447 2695 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1602 2725 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 2725 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 2314 M
+88 0 V
+1602 3275 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 3275 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 2865 M
+88 0 V
+1602 3826 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 3826 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 3415 M
+88 0 V
+1602 4377 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 4377 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 3966 M
+88 0 V
+1602 4926 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 4926 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 4515 M
+88 0 V
+1602 5477 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 5477 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 5066 M
+88 0 V
+1602 6027 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 6027 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 5617 M
+88 0 V
+1602 6578 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 6578 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 6167 M
+88 0 V
+1.000 UP
+stroke
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/griddata.pdf b/doc/interpreter/griddata.pdf
new file mode 100644
index 0000000..1a1641d
Binary files /dev/null and b/doc/interpreter/griddata.pdf differ
diff --git a/doc/interpreter/griddata.png b/doc/interpreter/griddata.png
new file mode 100644
index 0000000..807e6f4
Binary files /dev/null and b/doc/interpreter/griddata.png differ
diff --git a/doc/interpreter/griddata.txt b/doc/interpreter/griddata.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/griddata.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/hist.eps b/doc/interpreter/hist.eps
new file mode 100644
index 0000000..cb63872
--- /dev/null
+++ b/doc/interpreter/hist.eps
@@ -0,0 +1,1312 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: hist.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:55 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (hist.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:55 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+913 532 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 532 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 1215 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 1215 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 1899 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 1899 M
+[ [(Helvetica) 120.0 0.0 true true 0 (400)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 2582 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 2582 M
+[ [(Helvetica) 120.0 0.0 true true 0 (600)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 3265 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 3265 M
+[ [(Helvetica) 120.0 0.0 true true 0 (800)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 3949 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 3949 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1000)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 4632 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 4632 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1200)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 913 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+1842 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1842 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2771 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2771 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3700 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3700 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4629 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4629 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5558 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5558 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6487 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6487 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 0.00 C 913 532 M
+5574 0 V
+% End plot #1
+% Begin plot #2
+stroke
+1.000 UL
+LT1
+0.00 0.00 0.50 C gsave 1744 532 N 0 0 V 0 3 V 131 0 V 0 -3 V 1 PolyFill
+1744 532 M
+0 3 V
+131 0 V
+0 -3 V
+% End plot #2
+% Begin plot #3
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 1744 532 M
+0 3 V
+131 0 V
+0 -3 V
+-131 0 V
+% End plot #3
+% Begin plot #4
+stroke
+1.000 UL
+LT3
+0.00 0.00 0.50 C gsave 1875 532 N 0 0 V 0 0 V 131 0 V 0 0 V 1 PolyFill
+1875 532 M
+131 0 V
+% End plot #4
+% Begin plot #5
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 1875 532 M
+131 0 V
+-131 0 V
+% End plot #5
+% Begin plot #6
+stroke
+1.000 UL
+LT5
+0.00 0.00 0.50 C gsave 2006 532 N 0 0 V 0 3 V 132 0 V 0 -3 V 1 PolyFill
+2006 532 M
+0 3 V
+132 0 V
+0 -3 V
+% End plot #6
+% Begin plot #7
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2006 532 M
+0 3 V
+132 0 V
+0 -3 V
+-132 0 V
+% End plot #7
+% Begin plot #8
+stroke
+1.000 UL
+LT7
+0.00 0.00 0.50 C gsave 2138 532 N 0 0 V 0 31 V 131 0 V 0 -31 V 1 PolyFill
+2138 532 M
+0 31 V
+131 0 V
+0 -31 V
+% End plot #8
+% Begin plot #9
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2138 532 M
+0 31 V
+131 0 V
+0 -31 V
+-131 0 V
+% End plot #9
+% Begin plot #10
+stroke
+1.000 UL
+LT0
+0.00 0.00 0.50 C gsave 2269 532 N 0 0 V 0 62 V 131 0 V 0 -62 V 1 PolyFill
+2269 532 M
+0 62 V
+131 0 V
+0 -62 V
+% End plot #10
+% Begin plot #11
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2269 532 M
+0 62 V
+131 0 V
+0 -62 V
+-131 0 V
+% End plot #11
+% Begin plot #12
+stroke
+1.000 UL
+LT2
+0.00 0.00 0.50 C gsave 2400 532 N 0 0 V 0 140 V 131 0 V 0 -140 V 1 PolyFill
+2400 532 M
+0 140 V
+131 0 V
+0 -140 V
+% End plot #12
+% Begin plot #13
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2400 532 M
+0 140 V
+131 0 V
+0 -140 V
+-131 0 V
+% End plot #13
+% Begin plot #14
+stroke
+1.000 UL
+LT4
+0.00 0.00 0.50 C gsave 2531 532 N 0 0 V 0 215 V 132 0 V 0 -215 V 1 PolyFill
+2531 532 M
+0 215 V
+132 0 V
+0 -215 V
+% End plot #14
+% Begin plot #15
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2531 532 M
+0 215 V
+132 0 V
+0 -215 V
+-132 0 V
+% End plot #15
+% Begin plot #16
+stroke
+1.000 UL
+LT6
+0.00 0.00 0.50 C gsave 2663 532 N 0 0 V 0 461 V 131 0 V 0 -461 V 1 PolyFill
+2663 532 M
+0 461 V
+131 0 V
+0 -461 V
+% End plot #16
+% Begin plot #17
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2663 532 M
+0 461 V
+131 0 V
+0 -461 V
+-131 0 V
+% End plot #17
+% Begin plot #18
+stroke
+1.000 UL
+LT8
+0.00 0.00 0.50 C gsave 2794 532 N 0 0 V 0 844 V 131 0 V 0 -844 V 1 PolyFill
+2794 532 M
+0 844 V
+131 0 V
+0 -844 V
+% End plot #18
+% Begin plot #19
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2794 532 M
+0 844 V
+131 0 V
+0 -844 V
+-131 0 V
+% End plot #19
+% Begin plot #20
+stroke
+1.000 UL
+LT1
+0.00 0.00 0.50 C gsave 2925 532 N 0 0 V 0 1141 V 131 0 V 0 -1141 V 1 PolyFill
+2925 532 M
+0 1141 V
+131 0 V
+0 -1141 V
+% End plot #20
+% Begin plot #21
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 2925 532 M
+0 1141 V
+131 0 V
+0 -1141 V
+-131 0 V
+% End plot #21
+% Begin plot #22
+stroke
+1.000 UL
+LT3
+0.00 0.00 0.50 C gsave 3056 532 N 0 0 V 0 1777 V 132 0 V 0 -1777 V 1 PolyFill
+3056 532 M
+0 1777 V
+132 0 V
+0 -1777 V
+% End plot #22
+% Begin plot #23
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3056 532 M
+0 1777 V
+132 0 V
+0 -1777 V
+-132 0 V
+% End plot #23
+% Begin plot #24
+stroke
+1.000 UL
+LT5
+0.00 0.00 0.50 C gsave 3188 532 N 0 0 V 0 2504 V 131 0 V 0 -2504 V 1 PolyFill
+3188 532 M
+0 2504 V
+131 0 V
+0 -2504 V
+% End plot #24
+% Begin plot #25
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3188 532 M
+0 2504 V
+131 0 V
+0 -2504 V
+-131 0 V
+% End plot #25
+% Begin plot #26
+stroke
+1.000 UL
+LT7
+0.00 0.00 0.50 C gsave 3319 532 N 0 0 V 0 3058 V 131 0 V 0 -3058 V 1 PolyFill
+3319 532 M
+0 3058 V
+131 0 V
+0 -3058 V
+% End plot #26
+% Begin plot #27
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3319 532 M
+0 3058 V
+131 0 V
+0 -3058 V
+-131 0 V
+% End plot #27
+% Begin plot #28
+stroke
+1.000 UL
+LT0
+0.00 0.00 0.50 C gsave 3450 532 N 0 0 V 0 3488 V 131 0 V 0 -3488 V 1 PolyFill
+3450 532 M
+0 3488 V
+131 0 V
+0 -3488 V
+% End plot #28
+% Begin plot #29
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3450 532 M
+0 3488 V
+131 0 V
+0 -3488 V
+-131 0 V
+% End plot #29
+% Begin plot #30
+stroke
+1.000 UL
+LT2
+0.00 0.00 0.50 C gsave 3581 532 N 0 0 V 0 3888 V 132 0 V 0 -3888 V 1 PolyFill
+3581 532 M
+0 3888 V
+132 0 V
+0 -3888 V
+% End plot #30
+% Begin plot #31
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3581 532 M
+0 3888 V
+132 0 V
+0 -3888 V
+-132 0 V
+% End plot #31
+% Begin plot #32
+stroke
+1.000 UL
+LT4
+0.00 0.00 0.50 C gsave 3713 532 N 0 0 V 0 3752 V 131 0 V 0 -3752 V 1 PolyFill
+3713 532 M
+0 3752 V
+131 0 V
+0 -3752 V
+% End plot #32
+% Begin plot #33
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3713 532 M
+0 3752 V
+131 0 V
+0 -3752 V
+-131 0 V
+% End plot #33
+% Begin plot #34
+stroke
+1.000 UL
+LT6
+0.00 0.00 0.50 C gsave 3844 532 N 0 0 V 0 3553 V 131 0 V 0 -3553 V 1 PolyFill
+3844 532 M
+0 3553 V
+131 0 V
+0 -3553 V
+% End plot #34
+% Begin plot #35
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3844 532 M
+0 3553 V
+131 0 V
+0 -3553 V
+-131 0 V
+% End plot #35
+% Begin plot #36
+stroke
+1.000 UL
+LT8
+0.00 0.00 0.50 C gsave 3975 532 N 0 0 V 0 2791 V 131 0 V 0 -2791 V 1 PolyFill
+3975 532 M
+0 2791 V
+131 0 V
+0 -2791 V
+% End plot #36
+% Begin plot #37
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 3975 532 M
+0 2791 V
+131 0 V
+0 -2791 V
+-131 0 V
+% End plot #37
+% Begin plot #38
+stroke
+1.000 UL
+LT1
+0.00 0.00 0.50 C gsave 4106 532 N 0 0 V 0 2238 V 132 0 V 0 -2238 V 1 PolyFill
+4106 532 M
+0 2238 V
+132 0 V
+0 -2238 V
+% End plot #38
+% Begin plot #39
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4106 532 M
+0 2238 V
+132 0 V
+0 -2238 V
+-132 0 V
+% End plot #39
+% Begin plot #40
+stroke
+1.000 UL
+LT3
+0.00 0.00 0.50 C gsave 4238 532 N 0 0 V 0 1705 V 131 0 V 0 -1705 V 1 PolyFill
+4238 532 M
+0 1705 V
+131 0 V
+0 -1705 V
+% End plot #40
+% Begin plot #41
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4238 532 M
+0 1705 V
+131 0 V
+0 -1705 V
+-131 0 V
+% End plot #41
+% Begin plot #42
+stroke
+1.000 UL
+LT5
+0.00 0.00 0.50 C gsave 4369 532 N 0 0 V 0 1090 V 131 0 V 0 -1090 V 1 PolyFill
+4369 532 M
+0 1090 V
+131 0 V
+0 -1090 V
+% End plot #42
+% Begin plot #43
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4369 532 M
+0 1090 V
+131 0 V
+0 -1090 V
+-131 0 V
+% End plot #43
+% Begin plot #44
+stroke
+1.000 UL
+LT7
+0.00 0.00 0.50 C gsave 4500 532 N 0 0 V 0 639 V 131 0 V 0 -639 V 1 PolyFill
+4500 532 M
+0 639 V
+131 0 V
+0 -639 V
+% End plot #44
+% Begin plot #45
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4500 532 M
+0 639 V
+131 0 V
+0 -639 V
+-131 0 V
+% End plot #45
+% Begin plot #46
+stroke
+1.000 UL
+LT0
+0.00 0.00 0.50 C gsave 4631 532 N 0 0 V 0 369 V 132 0 V 0 -369 V 1 PolyFill
+4631 532 M
+0 369 V
+132 0 V
+0 -369 V
+% End plot #46
+% Begin plot #47
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4631 532 M
+0 369 V
+132 0 V
+0 -369 V
+-132 0 V
+% End plot #47
+% Begin plot #48
+stroke
+1.000 UL
+LT2
+0.00 0.00 0.50 C gsave 4763 532 N 0 0 V 0 205 V 131 0 V 0 -205 V 1 PolyFill
+4763 532 M
+0 205 V
+131 0 V
+0 -205 V
+% End plot #48
+% Begin plot #49
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4763 532 M
+0 205 V
+131 0 V
+0 -205 V
+-131 0 V
+% End plot #49
+% Begin plot #50
+stroke
+1.000 UL
+LT4
+0.00 0.00 0.50 C gsave 4894 532 N 0 0 V 0 113 V 131 0 V 0 -113 V 1 PolyFill
+4894 532 M
+0 113 V
+131 0 V
+0 -113 V
+% End plot #50
+% Begin plot #51
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 4894 532 M
+0 113 V
+131 0 V
+0 -113 V
+-131 0 V
+% End plot #51
+% Begin plot #52
+stroke
+1.000 UL
+LT6
+0.00 0.00 0.50 C gsave 5025 532 N 0 0 V 0 41 V 131 0 V 0 -41 V 1 PolyFill
+5025 532 M
+0 41 V
+131 0 V
+0 -41 V
+% End plot #52
+% Begin plot #53
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 5025 532 M
+0 41 V
+131 0 V
+0 -41 V
+-131 0 V
+% End plot #53
+% Begin plot #54
+stroke
+1.000 UL
+LT8
+0.00 0.00 0.50 C gsave 5156 532 N 0 0 V 0 27 V 132 0 V 0 -27 V 1 PolyFill
+5156 532 M
+0 27 V
+132 0 V
+0 -27 V
+% End plot #54
+% Begin plot #55
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 5156 532 M
+0 27 V
+132 0 V
+0 -27 V
+-132 0 V
+% End plot #55
+% Begin plot #56
+stroke
+1.000 UL
+LT1
+0.00 0.00 0.50 C gsave 5288 532 N 0 0 V 0 21 V 131 0 V 0 -21 V 1 PolyFill
+5288 532 M
+0 21 V
+131 0 V
+0 -21 V
+% End plot #56
+% Begin plot #57
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 5288 532 M
+0 21 V
+131 0 V
+0 -21 V
+-131 0 V
+% End plot #57
+% Begin plot #58
+stroke
+1.000 UL
+LT3
+0.00 0.00 0.50 C gsave 5419 532 N 0 0 V 0 0 V 131 0 V 0 0 V 1 PolyFill
+5419 532 M
+131 0 V
+% End plot #58
+% Begin plot #59
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 5419 532 M
+131 0 V
+-131 0 V
+% End plot #59
+% Begin plot #60
+stroke
+1.000 UL
+LT5
+0.00 0.00 0.50 C gsave 5550 532 N 0 0 V 0 7 V 131 0 V 0 -7 V 1 PolyFill
+5550 532 M
+0 7 V
+131 0 V
+0 -7 V
+% End plot #60
+% Begin plot #61
+stroke
+0.500 UL
+LT0
+0.00 0.00 0.00 C 5550 532 M
+0 7 V
+131 0 V
+0 -7 V
+-131 0 V
+% End plot #61
+stroke
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/hist.pdf b/doc/interpreter/hist.pdf
new file mode 100644
index 0000000..4980a05
Binary files /dev/null and b/doc/interpreter/hist.pdf differ
diff --git a/doc/interpreter/hist.png b/doc/interpreter/hist.png
new file mode 100644
index 0000000..8f05444
Binary files /dev/null and b/doc/interpreter/hist.png differ
diff --git a/doc/interpreter/hist.txt b/doc/interpreter/hist.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/hist.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/image.texi b/doc/interpreter/image.texi
new file mode 100644
index 0000000..56dfcf7
--- /dev/null
+++ b/doc/interpreter/image.texi
@@ -0,0 +1,721 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Image Processing
+ at chapter Image Processing
+
+Since an image basically is a matrix Octave is a very powerful
+environment for processing and analyzing images.  To illustrate
+how easy it is to do image processing in Octave, the following
+example will load an image, smooth it by a 5-by-5 averaging filter,
+and compute the gradient of the smoothed image.
+
+ at example
+ at group
+I = imread ("myimage.jpg");
+S = conv2 (I, ones (5, 5) / 25, "same");
+[Dx, Dy] = gradient (S);
+ at end group
+ at end example
+
+ at noindent
+In this example @code{S} contains the smoothed image, and @code{Dx}
+and @code{Dy} contains the partial spatial derivatives of the image.
+
+ at menu
+* Loading and Saving Images::   
+* Displaying Images::           
+* Representing Images::         
+* Plotting on top of Images::   
+* Color Conversion::            
+ at end menu
+
+ at node Loading and Saving Images
+ at section Loading and Saving Images
+
+The first step in most image processing tasks is to load an image
+into Octave.  This is done using the @code{imread} function, which uses the
+ at code{GraphicsMagick} library for reading.  This means a vast number of image
+formats is supported.  The @code{imwrite} function is the corresponding function
+for writing images to the disk.
+
+In summary, most image processing code will follow the structure of this code
+
+ at example
+ at group
+I = imread ("my_input_image.img");
+J = process_my_image (I);
+imwrite ("my_output_image.img", J);
+ at end group
+ at end example
+
+ at c ./image/imread.m
+ at anchor{doc-imread}
+ at deftypefn {Function File} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename})
+Read images from various file formats.
+
+The size and numeric class of the output depends on the
+format of the image.  A color image is returned as an
+MxNx3 matrix.  Grey-level and black-and-white images are
+of size MxN.
+The color depth of the image determines the numeric
+class of the output: "uint8" or "uint16" for grey
+and color, and "logical" for black and white.
+
+ at seealso{@ref{doc-imwrite,,imwrite}, @ref{doc-imfinfo,,imfinfo}}
+ at end deftypefn
+
+
+ at c ./image/imwrite.m
+ at anchor{doc-imwrite}
+ at deftypefn {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
+ at deftypefnx {Function File} {} imwrite (@var{img}, @var{map}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
+Write images in various file formats.
+
+If @var{fmt} is missing, the file extension (if any) of
+ at var{filename} is used to determine the format.
+
+The parameter-value pairs (@var{p1}, @var{v1}, @dots{}) are optional.  Currently
+the following options are supported for @t{JPEG} images
+
+ at table @samp
+ at item Quality
+Sets the quality of the compression.  The corresponding value should be an
+integer between 0 and 100, with larger values meaning higher visual quality
+and less compression.
+ at end table
+
+ at seealso{@ref{doc-imread,,imread}, @ref{doc-imfinfo,,imfinfo}}
+ at end deftypefn
+
+
+ at c defaults.cc
+ at anchor{doc-IMAGE_PATH}
+ at deftypefn {Built-in Function} {@var{val} =} IMAGE_PATH ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} IMAGE_PATH (@var{new_val})
+Query or set the internal variable that specifies a colon separated
+list of directories in which to search for image files.
+ at end deftypefn
+
+
+It is possible to get information about an image file on disk, without actually
+reading it into Octave.  This is done using the @code{imfinfo} function which
+provides read access to many of the parameters stored in the header of the image
+file.
+
+ at c ./image/imfinfo.m
+ at anchor{doc-imfinfo}
+ at deftypefn  {Function File} {@var{info} =} imfinfo (@var{filename})
+ at deftypefnx {Function File} {@var{info} =} imfinfo (@var{url})
+Read image information from a file.
+
+ at code{imfinfo} returns a structure containing information about the image
+stored in the file @var{filename}.  The output structure contains the
+following fields.
+
+ at table @samp
+ at item Filename
+The full name of the image file.
+ at item FileSize
+Number of bytes of the image on disk
+ at item FileModDate
+Date of last modification to the file.
+ at item Height
+Image height in pixels.
+ at item Width
+Image Width in pixels.
+ at item BitDepth
+Number of bits per channel per pixel.
+ at item Format
+Image format (e.g., @code{"jpeg"}).
+ at item LongFormat
+Long form image format description.
+ at item XResolution
+X resolution of the image.
+ at item YResolution
+Y resolution of the image.
+ at item TotalColors
+Number of unique colors in the image.
+ at item TileName
+Tile name.
+ at item AnimationDelay
+Time in 1/100ths of a second (0 to 65535) which must expire before displaying
+the next image in an animated sequence.
+ at item AnimationIterations
+Number of iterations to loop an animation (e.g., Netscape loop extension) for.
+ at item ByteOrder
+Endian option for formats that support it.  Is either @code{"little-endian"},
+ at code{"big-endian"}, or @code{"undefined"}.
+ at item Gamma
+Gamma level of the image.  The same color image displayed on two different
+workstations may look different due to differences in the display monitor.
+ at item Matte
+ at code{true} if the image has transparency.
+ at item ModulusDepth
+Image modulus depth (minimum number of bits required to support red/green/blue
+components without loss of accuracy).
+ at item Quality
+JPEG/MIFF/PNG compression level.
+ at item QuantizeColors
+Preferred number of colors in the image.
+ at item ResolutionUnits
+Units of image resolution.  Is either @code{"pixels per inch"},
+ at code{"pixels per centimeter"}, or @code{"undefined"}.
+ at item ColorType
+Image type.  Is either @code{"grayscale"}, @code{"indexed"}, @code{"truecolor"},
+or @code{"undefined"}.
+ at item View
+FlashPix viewing parameters.
+ at end table
+
+ at seealso{@ref{doc-imread,,imread}, @ref{doc-imwrite,,imwrite}}
+ at end deftypefn
+
+
+ at node Displaying Images
+ at section Displaying Images
+
+A natural part of image processing is visualization of an image.
+The most basic function for this is the @code{imshow} function that
+shows the image given in the first input argument.  This function uses
+an external program to show the image.  If gnuplot 4.2 or later is 
+available it will be used to display the image, otherwise the
+ at code{display}, @code{xv}, or @code{xloadimage} program is used.  The
+actual program can be selected with the @code{image_viewer} function.
+
+ at c ./image/imshow.m
+ at anchor{doc-imshow}
+ at deftypefn {Function File} {} imshow (@var{im})
+ at deftypefnx {Function File} {} imshow (@var{im}, @var{limits})
+ at deftypefnx {Function File} {} imshow (@var{im}, @var{map})
+ at deftypefnx {Function File} {} imshow (@var{rgb}, @dots{})
+ at deftypefnx {Function File} {} imshow (@var{filename})
+ at deftypefnx {Function File} {} imshow (@dots{}, @var{string_param1}, @var{value1}, @dots{})
+Display the image @var{im}, where @var{im} can be a 2-dimensional
+(gray-scale image) or a 3-dimensional (RGB image) matrix.
+
+If @var{limits} is a 2-element vector @code{[@var{low}, @var{high}]},
+the image is shown using a display range between @var{low} and
+ at var{high}.  If an empty matrix is passed for @var{limits}, the
+display range is computed as the range between the minimal and the
+maximal value in the image.
+
+If @var{map} is a valid color map, the image will be shown as an indexed
+image using the supplied color map.
+
+If a file name is given instead of an image, the file will be read and
+shown.
+
+If given, the parameter @var{string_param1} has value
+ at var{value1}.  @var{string_param1} can be any of the following:
+ at table @samp
+ at item "displayrange"
+ at var{value1} is the display range as described above.
+ at end table
+ at seealso{@ref{doc-image,,image}, @ref{doc-imagesc,,imagesc}, @ref{doc-colormap,,colormap}, @ref{doc-gray2ind,,gray2ind}, @ref{doc-rgb2ind,,rgb2ind}}
+ at end deftypefn
+
+
+ at c ./image/image.m
+ at anchor{doc-image}
+ at deftypefn {Function File} {} image (@var{img})
+ at deftypefnx {Function File} {} image (@var{x}, @var{y}, @var{img})
+Display a matrix as a color image.  The elements of @var{x} are indices
+into the current colormap, and the colormap will be scaled so that the
+extremes of @var{x} are mapped to the extremes of the colormap.
+
+It first tries to use @code{gnuplot}, then @code{display} from 
+ at code{ImageMagick}, then @code{xv}, and then @code{xloadimage}.
+The actual program used can be changed using the @code{image_viewer}
+function.
+
+The axis values corresponding to the matrix elements are specified in
+ at var{x} and @var{y}.  If you're not using gnuplot 4.2 or later, these
+variables are ignored.
+ at seealso{@ref{doc-imshow,,imshow}, @ref{doc-imagesc,,imagesc}, @ref{doc-colormap,,colormap}, @ref{doc-image_viewer,,image_viewer}}
+ at end deftypefn
+
+
+ at c ./image/imagesc.m
+ at anchor{doc-imagesc}
+ at deftypefn {Function File} {} imagesc (@var{a})
+ at deftypefnx {Function File} {} imagesc (@var{x}, @var{y}, @var{a})
+ at deftypefnx {Function File} {} imagesc (@dots{}, @var{limits})
+ at deftypefnx {Function File} {} imagesc (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} imagesc (@dots{})
+Display a scaled version of the matrix @var{a} as a color image.  The
+colormap is scaled so that the entries of the matrix occupy the entire
+colormap.  If @var{limits} = [@var{lo}, @var{hi}] are given, then that
+range is set to the 'clim' of the current axes.
+
+The axis values corresponding to the matrix elements are specified in
+ at var{x} and @var{y}, either as pairs giving the minimum and maximum
+values for the respective axes, or as values for each row and column
+of the matrix @var{a}.
+
+ at seealso{@ref{doc-image,,image}, @ref{doc-imshow,,imshow}, @ref{doc-caxis,,caxis}}
+ at end deftypefn
+
+
+ at c ./image/image_viewer.m
+ at anchor{doc-image_viewer}
+ at deftypefn {Function File} {[@var{fcn}, @var{default_zoom}] =} image_viewer (@var{fcn}, @var{default_zoom})
+Change the program or function used for viewing images and return the
+previous values.
+
+When the @code{image} or @code{imshow} function is called it will
+launch an external program to display the image.  The default behavior
+is to use gnuplot if the installed version supports image viewing,
+and otherwise try the programs @code{display}, @code{xv}, and
+ at code{xloadimage}.  Using this function it is possible to change that
+behavior.
+
+When called with one input argument images will be displayed by saving
+the image to a file and the system command @var{command} will be called
+to view the image.  The @var{command} must be a string containing
+ at code{%s} and possibly @code{%f}.  The @code{%s} will be replaced by
+the filename of the image, and the @code{%f} will (if present) be
+replaced by the zoom factor given to the @code{image} function.
+For example,
+ at example
+image_viewer ("eog %s");
+ at end example
+changes the image viewer to the @code{eog} program.
+
+With two input arguments, images will be displayed by calling
+the function @var{function_handle}.  For example,
+ at example
+image_viewer (data, @@my_image_viewer);
+ at end example
+sets the image viewer function to @code{my_image_viewer}.  The image
+viewer function is called with
+ at example
+my_image_viewer (@var{x}, @var{y}, @var{im}, @var{zoom}, @var{data})
+ at end example
+where @var{x} and @var{y} are the axis of the image, @var{im} is the image
+variable, and @var{data} is extra user-supplied data to be passed to
+the viewer function.
+
+With three input arguments it is possible to change the zooming.
+Some programs (like @code{xloadimage}) require the zoom factor to be
+between 0 and 100, and not 0 and 1 like Octave assumes.  This is
+solved by setting the third argument to 100.
+
+ at seealso{@ref{doc-image,,image}, @ref{doc-imshow,,imshow}}
+ at end deftypefn
+
+
+ at node Representing Images
+ at section Representing Images
+
+In general Octave supports four different kinds of images, gray-scale
+images, RGB images, binary images, and indexed images.  A gray-scale
+image is represented with an M-by-N matrix in which each
+element corresponds to the intensity of a pixel.  An RGB image is
+represented with an M-by-N-by-3 array where each
+3-vector corresponds to the red, green, and blue intensities of each
+pixel.
+
+The actual meaning of the value of a pixel in a gray-scale or RGB
+image depends on the class of the matrix.  If the matrix is of class
+ at code{double} pixel intensities are between 0 and 1, if it is of class
+ at code{uint8} intensities are between 0 and 255, and if it is of class
+ at code{uint16} intensities are between 0 and 65535.
+
+A binary image is an M-by-N matrix of class @code{logical}.
+A pixel in a binary image is black if it is @code{false} and white
+if it is @code{true}.
+
+An indexed image consists of an M-by-N matrix of integers
+and a C-by-3 color map.  Each integer corresponds to an
+index in the color map, and each row in the color map corresponds to
+an RGB color.  The color map must be of class @code{double} with values
+between 0 and 1.
+
+ at c ./image/gray2ind.m
+ at anchor{doc-gray2ind}
+ at deftypefn {Function File} {[@var{img}, @var{map}] =} gray2ind (@var{I}, @var{n})
+Convert a gray scale intensity image to an Octave indexed image.
+The indexed image will consist of @var{n} different intensity values.  If not
+given @var{n} will default to 64.
+ at end deftypefn
+
+
+ at c ./image/ind2gray.m
+ at anchor{doc-ind2gray}
+ at deftypefn {Function File} {} ind2gray (@var{x}, @var{map})
+Convert an Octave indexed image to a gray scale intensity image.
+If @var{map} is omitted, the current colormap is used to determine the
+intensities.
+ at seealso{@ref{doc-gray2ind,,gray2ind}, @ref{doc-rgb2ntsc,,rgb2ntsc}, @ref{doc-image,,image}, @ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/rgb2ind.m
+ at anchor{doc-rgb2ind}
+ at deftypefn  {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb})
+ at deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{r}, @var{g}, @var{b})
+Convert an RGB image to an Octave indexed image.
+ at seealso{@ref{doc-ind2rgb,,ind2rgb}, @ref{doc-rgb2ntsc,,rgb2ntsc}}
+ at end deftypefn
+
+
+ at c ./image/ind2rgb.m
+ at anchor{doc-ind2rgb}
+ at deftypefn {Function File} {@var{rgb} =} ind2rgb (@var{x}, @var{map})
+ at deftypefnx {Function File} {[@var{r}, @var{g}, @var{b}] =} ind2rgb (@var{x}, @var{map})
+Convert an indexed image to red, green, and blue color components.
+If the colormap doesn't contain enough colors, pad it with the
+last color in the map.
+If @var{map} is omitted, the current colormap is used for the conversion.
+ at seealso{@ref{doc-rgb2ind,,rgb2ind}, @ref{doc-image,,image}, @ref{doc-imshow,,imshow}, @ref{doc-ind2gray,,ind2gray}, @ref{doc-gray2ind,,gray2ind}}
+ at end deftypefn
+
+
+ at c ./image/colormap.m
+ at anchor{doc-colormap}
+ at deftypefn {Function File} {} colormap (@var{map})
+ at deftypefnx {Function File} {} colormap ("default")
+Set the current colormap.
+
+ at code{colormap (@var{map})} sets the current colormap to @var{map}.  The
+color map should be an @var{n} row by 3 column matrix.  The columns
+contain red, green, and blue intensities respectively.  All entries
+should be between 0 and 1 inclusive.  The new colormap is returned.
+
+ at code{colormap ("default")} restores the default colormap (the
+ at code{jet} map with 64 entries).  The default colormap is returned.
+
+With no arguments, @code{colormap} returns the current color map.
+ at seealso{@ref{doc-jet,,jet}}
+ at end deftypefn
+
+
+ at c ./image/brighten.m
+ at anchor{doc-brighten}
+ at deftypefn {Function File} {@var{map_out} =} brighten (@var{map}, @var{beta})
+ at deftypefnx {Function File} {@var{map_out} =} brighten (@var{h}, @var{beta})
+ at deftypefnx {Function File} {@var{map_out} =} brighten (@var{beta})
+Darkens or brightens the given colormap.  If the @var{map} argument 
+is omitted, the function is applied to the current colormap.  The first
+argument can also be a valid graphics handle @var{h}, in which case 
+ at code{brighten} is applied to the colormap associated with this handle.
+
+Should the resulting colormap @var{map_out} not be assigned, it will be
+written to the current colormap.
+
+The argument @var{beta} should be a scalar between -1 and 1,
+where a negative value darkens and a positive value brightens
+the colormap.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/autumn.m
+ at anchor{doc-autumn}
+ at deftypefn {Function File} {} autumn (@var{n})
+Create color colormap.  This colormap is red through orange to yellow.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/bone.m
+ at anchor{doc-bone}
+ at deftypefn {Function File} {} bone (@var{n})
+Create color colormap.  This colormap is a gray colormap with a light 
+blue tone.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/cool.m
+ at anchor{doc-cool}
+ at deftypefn {Function File} {} cool (@var{n})
+Create color colormap.  The colormap is cyan to magenta.  The argument 
+ at var{n} should be a scalar.  If it is omitted, the length of the current
+colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/copper.m
+ at anchor{doc-copper}
+ at deftypefn {Function File} {} copper (@var{n})
+Create color colormap.  This colormap is black to a light copper tone.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/flag.m
+ at anchor{doc-flag}
+ at deftypefn {Function File} {} flag (@var{n})
+Create color colormap.  This colormap cycles through red, white, blue 
+and black.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/gray.m
+ at anchor{doc-gray}
+ at deftypefn {Function File} {} gray (@var{n})
+Return a gray colormap with @var{n} entries corresponding to values from
+0 to @var{n}-1.  The argument @var{n} should be a scalar.  If it is
+omitted, the length of the current colormap or 64 is assumed.
+ at end deftypefn
+
+
+ at c ./image/hot.m
+ at anchor{doc-hot}
+ at deftypefn {Function File} {} hot (@var{n})
+Create color colormap.  This colormap is black through dark red, red, 
+orange, yellow to white.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/hsv.m
+ at anchor{doc-hsv}
+ at deftypefn {Function File} {} hsv (@var{n})
+Create color colormap.  This colormap is red through yellow, green,
+cyan, blue, magenta to red.  It is obtained by linearly varying the
+hue through all possible values while keeping constant maximum
+saturation and value and is equivalent to
+ at code{hsv2rgb ([linspace(0,1,N)', ones(N,2)])}.
+
+The argument @var{n} should be a scalar.  If it is omitted, the
+length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/jet.m
+ at anchor{doc-jet}
+ at deftypefn {Function File} {} jet (@var{n})
+Create color colormap.  This colormap is dark blue through blue, cyan, 
+green, yellow, red to dark red.  The argument @var{n} should be a scalar. 
+If it is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/ocean.m
+ at anchor{doc-ocean}
+ at deftypefn {Function File} {} ocean (@var{n})
+Create color colormap.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at end deftypefn
+
+
+ at c ./image/pink.m
+ at anchor{doc-pink}
+ at deftypefn {Function File} {} pink (@var{n})
+Create color colormap.  This colormap gives a sepia tone on black and
+white images.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/prism.m
+ at anchor{doc-prism}
+ at deftypefn {Function File} {} prism (@var{n})
+Create color colormap.  This colormap cycles trough red, orange, yellow,
+green, blue and violet.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/rainbow.m
+ at anchor{doc-rainbow}
+ at deftypefn {Function File} {} rainbow (@var{n})
+Create color colormap.  This colormap is red through orange, yellow, green, 
+blue to violet.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/spring.m
+ at anchor{doc-spring}
+ at deftypefn {Function File} {} spring (@var{n})
+Create color colormap.  This colormap is magenta to yellow.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/summer.m
+ at anchor{doc-summer}
+ at deftypefn {Function File} {} summer (@var{n})
+Create color colormap.  This colormap is green to yellow.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/white.m
+ at anchor{doc-white}
+ at deftypefn {Function File} {} white (@var{n})
+Create color colormap.  This colormap is completely white.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/winter.m
+ at anchor{doc-winter}
+ at deftypefn {Function File} {} winter (@var{n})
+Create color colormap.  This colormap is blue to green.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+ at c ./image/contrast.m
+ at anchor{doc-contrast}
+ at deftypefn {Function File} {} contrast (@var{x}, @var{n})
+Return a gray colormap that maximizes the contrast in an image.  The
+returned colormap will have @var{n} rows.  If @var{n} is not defined
+then the size of the current colormap is used instead.
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+An additional colormap is @code{gmap40}.  This code map contains only
+colors with integer values of the red, green and blue components.  This
+is a workaround for a limitation of gnuplot 4.0, that does not allow the color of
+line or patch objects to be set, and so @code{gmap40} is useful for
+gnuplot 4.0 users, and in particular in conjunction with the @var{bar},
+ at var{barh} or @var{contour} functions.
+
+ at c ./image/gmap40.m
+ at anchor{doc-gmap40}
+ at deftypefn {Function File} {} gmap40 (@var{n})
+Create a color colormap.  The colormap is red, green, blue, yellow,
+magenta and cyan.  These are the colors that are allowed with patch
+objects using gnuplot 4.0, and so this colormap function is specially
+designed for users of gnuplot 4.0.  The argument @var{n} should be 
+a scalar.  If it is omitted, a length of 6 is assumed.  Larger values
+of @var{n} result in a repetition of the above colors
+ at seealso{@ref{doc-colormap,,colormap}}
+ at end deftypefn
+
+
+You may use the @code{spinmap} function to cycle through the colors in
+the current colormap, displaying the changes for the current figure.
+
+ at c ./plot/spinmap.m
+ at anchor{doc-spinmap}
+ at deftypefn {Function File} {} spinmap (@var{t}, @var{inc})
+Cycle the colormap for @var{t} seconds with an increment
+of @var{inc}.  Both parameters are optional.  The default cycle time
+is 5 seconds and the default increment is 2.
+
+A higher value of @var{inc} causes a faster cycle through the
+colormap.
+ at seealso{@ref{doc-gca,,gca}, @ref{doc-colorbar,,colorbar}}
+ at end deftypefn
+
+
+ at node Plotting on top of Images
+ at section Plotting on top of Images
+
+If gnuplot is being used to display images it is possible to plot on
+top of images.  Since an image is a matrix it is indexed by row and
+column values.  The plotting system is, however, based on the 
+traditional @math{(x, y)} system.  To minimize the difference between
+the two systems Octave places the origin of the coordinate system in
+the point corresponding to the pixel at @math{(1, 1)}.  So, to plot
+points given by row and column values on top of an image, one should
+simply call @code{plot} with the column values as the first argument
+and the row values as the second.  As an example the following code
+generates an image with random intensities between 0 and 1, and shows
+the image with red circles over pixels with an intensity above 
+ at math{0.99}.
+
+ at example
+ at group
+I = rand (100, 100);
+[row, col] = find (I > 0.99);
+hold ("on");
+imshow (I);
+plot (col, row, "ro");
+hold ("off");
+ at end group
+ at end example
+
+ at node Color Conversion
+ at section Color Conversion
+
+Octave supports conversion from the RGB color system to NTSC and HSV
+and vice versa. 
+
+ at c ./image/rgb2hsv.m
+ at anchor{doc-rgb2hsv}
+ at deftypefn {Function File} {@var{hsv_map} =} rgb2hsv (@var{rgb_map})
+Transform a colormap or image from the rgb space to the hsv space.
+
+A color n the RGB space consists of the red, green and blue intensities.
+
+In the HSV space each color is represented by their hue, saturation
+and value (brightness).  Value gives the amount of light in the color.
+Hue describes the dominant wavelength. 
+Saturation is the amount of Hue mixed into the color.
+ at seealso{@ref{doc-hsv2rgb,,hsv2rgb}}
+ at end deftypefn
+
+
+ at c ./image/hsv2rgb.m
+ at anchor{doc-hsv2rgb}
+ at deftypefn {Function File} {@var{rgb_map} =} hsv2rgb (@var{hsv_map})
+Transform a colormap or image from the hsv space to the rgb space. 
+ at seealso{@ref{doc-rgb2hsv,,rgb2hsv}}
+ at end deftypefn
+
+
+ at c ./image/rgb2ntsc.m
+ at anchor{doc-rgb2ntsc}
+ at deftypefn {Function File} {} rgb2ntsc (@var{rgb})
+Transform a colormap or image from RGB to NTSC.
+ at seealso{@ref{doc-ntsc2rgb,,ntsc2rgb}}
+ at end deftypefn
+
+
+ at c ./image/ntsc2rgb.m
+ at anchor{doc-ntsc2rgb}
+ at deftypefn {Function File} {} ntsc2rgb (@var{yiq})
+Transform a colormap or image from NTSC to RGB.
+ at seealso{@ref{doc-rgb2ntsc,,rgb2ntsc}}
+ at end deftypefn
+
+
+
diff --git a/doc/interpreter/image.txi b/doc/interpreter/image.txi
new file mode 100644
index 0000000..fc3a076
--- /dev/null
+++ b/doc/interpreter/image.txi
@@ -0,0 +1,229 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Image Processing
+ at chapter Image Processing
+
+Since an image basically is a matrix Octave is a very powerful
+environment for processing and analyzing images.  To illustrate
+how easy it is to do image processing in Octave, the following
+example will load an image, smooth it by a 5-by-5 averaging filter,
+and compute the gradient of the smoothed image.
+
+ at example
+ at group
+I = imread ("myimage.jpg");
+S = conv2 (I, ones (5, 5) / 25, "same");
+[Dx, Dy] = gradient (S);
+ at end group
+ at end example
+
+ at noindent
+In this example @code{S} contains the smoothed image, and @code{Dx}
+and @code{Dy} contains the partial spatial derivatives of the image.
+
+ at menu
+* Loading and Saving Images::   
+* Displaying Images::           
+* Representing Images::         
+* Plotting on top of Images::   
+* Color Conversion::            
+ at end menu
+
+ at node Loading and Saving Images
+ at section Loading and Saving Images
+
+The first step in most image processing tasks is to load an image
+into Octave.  This is done using the @code{imread} function, which uses the
+ at code{GraphicsMagick} library for reading.  This means a vast number of image
+formats is supported.  The @code{imwrite} function is the corresponding function
+for writing images to the disk.
+
+In summary, most image processing code will follow the structure of this code
+
+ at example
+ at group
+I = imread ("my_input_image.img");
+J = process_my_image (I);
+imwrite ("my_output_image.img", J);
+ at end group
+ at end example
+
+ at DOCSTRING(imread)
+
+ at DOCSTRING(imwrite)
+
+ at DOCSTRING(IMAGE_PATH)
+
+It is possible to get information about an image file on disk, without actually
+reading it into Octave.  This is done using the @code{imfinfo} function which
+provides read access to many of the parameters stored in the header of the image
+file.
+
+ at DOCSTRING(imfinfo)
+
+ at node Displaying Images
+ at section Displaying Images
+
+A natural part of image processing is visualization of an image.
+The most basic function for this is the @code{imshow} function that
+shows the image given in the first input argument.  This function uses
+an external program to show the image.  If gnuplot 4.2 or later is 
+available it will be used to display the image, otherwise the
+ at code{display}, @code{xv}, or @code{xloadimage} program is used.  The
+actual program can be selected with the @code{image_viewer} function.
+
+ at DOCSTRING(imshow)
+
+ at DOCSTRING(image)
+
+ at DOCSTRING(imagesc)
+
+ at DOCSTRING(image_viewer)
+
+ at node Representing Images
+ at section Representing Images
+
+In general Octave supports four different kinds of images, gray-scale
+images, RGB images, binary images, and indexed images.  A gray-scale
+image is represented with an M-by-N matrix in which each
+element corresponds to the intensity of a pixel.  An RGB image is
+represented with an M-by-N-by-3 array where each
+3-vector corresponds to the red, green, and blue intensities of each
+pixel.
+
+The actual meaning of the value of a pixel in a gray-scale or RGB
+image depends on the class of the matrix.  If the matrix is of class
+ at code{double} pixel intensities are between 0 and 1, if it is of class
+ at code{uint8} intensities are between 0 and 255, and if it is of class
+ at code{uint16} intensities are between 0 and 65535.
+
+A binary image is an M-by-N matrix of class @code{logical}.
+A pixel in a binary image is black if it is @code{false} and white
+if it is @code{true}.
+
+An indexed image consists of an M-by-N matrix of integers
+and a C-by-3 color map.  Each integer corresponds to an
+index in the color map, and each row in the color map corresponds to
+an RGB color.  The color map must be of class @code{double} with values
+between 0 and 1.
+
+ at DOCSTRING(gray2ind)
+
+ at DOCSTRING(ind2gray)
+
+ at DOCSTRING(rgb2ind)
+
+ at DOCSTRING(ind2rgb)
+
+ at DOCSTRING(colormap)
+
+ at DOCSTRING(brighten)
+
+ at DOCSTRING(autumn)
+
+ at DOCSTRING(bone)
+
+ at DOCSTRING(cool)
+
+ at DOCSTRING(copper)
+
+ at DOCSTRING(flag)
+
+ at DOCSTRING(gray)
+
+ at DOCSTRING(hot)
+
+ at DOCSTRING(hsv)
+
+ at DOCSTRING(jet)
+
+ at DOCSTRING(ocean)
+
+ at DOCSTRING(pink)
+
+ at DOCSTRING(prism)
+
+ at DOCSTRING(rainbow)
+
+ at DOCSTRING(spring)
+
+ at DOCSTRING(summer)
+
+ at DOCSTRING(white)
+
+ at DOCSTRING(winter)
+
+ at DOCSTRING(contrast)
+
+An additional colormap is @code{gmap40}.  This code map contains only
+colors with integer values of the red, green and blue components.  This
+is a workaround for a limitation of gnuplot 4.0, that does not allow the color of
+line or patch objects to be set, and so @code{gmap40} is useful for
+gnuplot 4.0 users, and in particular in conjunction with the @var{bar},
+ at var{barh} or @var{contour} functions.
+
+ at DOCSTRING(gmap40)
+
+You may use the @code{spinmap} function to cycle through the colors in
+the current colormap, displaying the changes for the current figure.
+
+ at DOCSTRING(spinmap)
+
+ at node Plotting on top of Images
+ at section Plotting on top of Images
+
+If gnuplot is being used to display images it is possible to plot on
+top of images.  Since an image is a matrix it is indexed by row and
+column values.  The plotting system is, however, based on the 
+traditional @math{(x, y)} system.  To minimize the difference between
+the two systems Octave places the origin of the coordinate system in
+the point corresponding to the pixel at @math{(1, 1)}.  So, to plot
+points given by row and column values on top of an image, one should
+simply call @code{plot} with the column values as the first argument
+and the row values as the second.  As an example the following code
+generates an image with random intensities between 0 and 1, and shows
+the image with red circles over pixels with an intensity above 
+ at math{0.99}.
+
+ at example
+ at group
+I = rand (100, 100);
+[row, col] = find (I > 0.99);
+hold ("on");
+imshow (I);
+plot (col, row, "ro");
+hold ("off");
+ at end group
+ at end example
+
+ at node Color Conversion
+ at section Color Conversion
+
+Octave supports conversion from the RGB color system to NTSC and HSV
+and vice versa. 
+
+ at DOCSTRING(rgb2hsv)
+
+ at DOCSTRING(hsv2rgb)
+
+ at DOCSTRING(rgb2ntsc)
+
+ at DOCSTRING(ntsc2rgb)
+
+
diff --git a/doc/interpreter/inpolygon.eps b/doc/interpreter/inpolygon.eps
new file mode 100644
index 0000000..3779a44
--- /dev/null
+++ b/doc/interpreter/inpolygon.eps
@@ -0,0 +1,880 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: inpolygon.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:47:03 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (inpolygon.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:47:03 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 1807 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 1807 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2687 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2687 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3566 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3566 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4445 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4445 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5324 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5324 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6204 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6204 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7083 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7083 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2590 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2590 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3705 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3705 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4820 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4820 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5936 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5936 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+7051 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 7051 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8166 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8166 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+9281 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 9281 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 3705 4445 M
+109 -543 V
+317 -491 V
+494 -389 V
+621 -249 V
+690 -86 V
+689 86 V
+621 249 V
+494 389 V
+317 491 V
+109 543 V
+-109 543 V
+-317 491 V
+-494 389 V
+-621 249 V
+-689 87 V
+-690 -87 V
+4625 5868 L
+4131 5479 L
+3814 4988 L
+3705 4445 L
+% End plot #1
+% Begin plot #2
+2.000 UP
+stroke
+LT1
+1.00 0.00 0.00 C 4900 4775 Pls
+6460 4496 Pls
+4412 4992 Pls
+4091 3953 Pls
+4154 3674 Pls
+5357 2927 Pls
+5490 4320 Pls
+6222 3724 Pls
+4751 5250 Pls
+4418 4186 Pls
+7691 4380 Pls
+5855 4848 Pls
+3806 4676 Pls
+7730 4696 Pls
+4330 4649 Pls
+6488 4446 Pls
+6690 5443 Pls
+6446 3708 Pls
+6689 3292 Pls
+5299 5157 Pls
+5880 5590 Pls
+6723 3887 Pls
+6697 4830 Pls
+5620 4812 Pls
+5077 4695 Pls
+6213 6053 Pls
+7902 3911 Pls
+7873 5265 Pls
+6402 5088 Pls
+5955 3207 Pls
+% End plot #2
+% Begin plot #3
+2.000 UP
+0.500 UL
+LT2
+0.00 0.00 1.00 C 2329 6350 Circle
+1653 1644 Circle
+7609 7241 Circle
+6440 7025 Circle
+2595 5852 Circle
+8358 4750 Circle
+2719 5164 Circle
+5117 2529 Circle
+9280 1212 Circle
+5034 2334 Circle
+6296 1810 Circle
+8488 5269 Circle
+7346 5833 Circle
+4522 2852 Circle
+6505 6362 Circle
+6831 6797 Circle
+8397 5874 Circle
+9018 5028 Circle
+7516 2778 Circle
+3044 2832 Circle
+7951 5721 Circle
+7527 2761 Circle
+6881 7006 Circle
+8404 5158 Circle
+2456 2661 Circle
+8573 7831 Circle
+10299 5230 Circle
+7048 6035 Circle
+9511 4548 Circle
+3844 5979 Circle
+2431 5616 Circle
+3738 4141 Circle
+9026 2941 Circle
+8358 5429 Circle
+4054 2988 Circle
+8139 2833 Circle
+6595 1565 Circle
+6082 1073 Circle
+8414 5128 Circle
+7729 3084 Circle
+5092 1388 Circle
+3392 4156 Circle
+8646 5312 Circle
+2192 3812 Circle
+7837 5369 Circle
+8229 4513 Circle
+8750 5396 Circle
+7276 6902 Circle
+8696 5636 Circle
+3977 2885 Circle
+6491 2537 Circle
+9372 3266 Circle
+7914 5344 Circle
+2685 7829 Circle
+7781 3060 Circle
+5351 1044 Circle
+7875 2353 Circle
+4438 6009 Circle
+8357 3265 Circle
+5253 1830 Circle
+4636 7321 Circle
+% End plot #3
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/inpolygon.pdf b/doc/interpreter/inpolygon.pdf
new file mode 100644
index 0000000..16353ea
Binary files /dev/null and b/doc/interpreter/inpolygon.pdf differ
diff --git a/doc/interpreter/inpolygon.png b/doc/interpreter/inpolygon.png
new file mode 100644
index 0000000..b3e3cd7
Binary files /dev/null and b/doc/interpreter/inpolygon.png differ
diff --git a/doc/interpreter/inpolygon.txt b/doc/interpreter/inpolygon.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/inpolygon.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/install.texi b/doc/interpreter/install.texi
new file mode 100644
index 0000000..994b117
--- /dev/null
+++ b/doc/interpreter/install.texi
@@ -0,0 +1,512 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c The text of this file appears in the file INSTALL in the Octave
+ at c distribution, as well as in the Octave manual.
+
+ at ifclear INSTALLONLY
+ at node Installation
+ at appendix Installing Octave
+ at end ifclear
+
+ at ifset INSTALLONLY
+ at include conf.texi
+
+This file documents the installation of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation.
+
+ at strong{Note:} This file is automatically generated from
+ at file{doc/interpreter/install.txi} in the Octave sources.  To update
+the documentation make changes to the .txi source file rather than this
+derived file.
+
+ at node Installation
+ at chapter Installing Octave
+ at end ifset
+
+ at cindex installing Octave
+
+Here is the procedure for installing Octave from scratch on a Unix
+system.
+
+ at itemize @bullet
+ at item
+Run the shell script @file{configure}.  This will determine the features
+your system has (or doesn't have) and create a file named
+ at file{Makefile} from each of the files named @file{Makefile.in}.
+
+Here is a summary of the configure options that are most frequently used
+when building Octave:
+
+ at table @code
+ at item --prefix=@var{prefix}
+Install Octave in subdirectories below @var{prefix}.  The default value
+of @var{prefix} is @file{/usr/local}.
+
+ at item --srcdir=@var{dir}
+Look for Octave sources in the directory @var{dir}.
+
+ at item --enable-bounds-check
+Enable bounds checking for indexing operators in the internal array
+classes.  This option is primarily used for debugging Octave.  Building
+Octave with this option has a negative impact on performance and is not
+recommended for general use.
+
+ at item --enable-64
+This is an @strong{experimental} option to enable Octave to use 64-bit
+integers for array dimensions and indexing on 64-bit platforms.  You
+probably don't want to use this option unless you know what you are
+doing.
+
+If you use @code{--enable-64}, you must ensure that your Fortran
+compiler generates code with 8 byte signed @code{INTEGER} values, and
+that your @sc{blas} and @sc{lapack} libraries are compiled to use 8 byte
+signed integers for array dimensions and indexing.
+
+ at item --enable-shared
+Create shared libraries (this is the default).  If you are planning to
+use the dynamic loading features, you will probably want to use this
+option.  It will make your @file{.oct} files much smaller and on some
+systems it may be necessary to build shared libraries in order to use
+dynamically linked functions.
+
+You may also want to build a shared version of @code{libstdc++}, if your
+system doesn't already have one.
+
+ at item --enable-dl
+Use @code{dlopen} and friends to make Octave capable of dynamically
+linking externally compiled functions (this is the default if
+ at code{--enable-shared} is specified).  This option only works on systems
+that actually have these functions.  If you plan on using this feature, you
+should probably also use @code{--enable-shared} to reduce the size of
+your @file{.oct} files.
+
+ at item --without-blas
+Compile and use the generic @sc{blas} and @sc{lapack} versions included with
+Octave.  By default, configure first looks for @sc{blas} and @sc{lapack} matrix
+libraries on your system, including optimized @sc{blas} implementations such
+as the free ATLAS 3.0, as well as vendor-tuned libraries.  (The use of
+an optimized @sc{blas} will generally result in several-times faster matrix
+operations.)  Only use this option if your system has @sc{blas}/@sc{lapack}
+libraries that cause problems for some reason.  You can also use
+ at code{--with-blas=lib} to specify a particular @sc{blas} library
+ that configure doesn't check for automatically.
+
+ at item --without-ccolamd
+Don't use CCOLAMD, disable some sparse matrix functionality.
+
+ at item --without-colamd
+Don't use COLAMD, disable some sparse matrix functionality.
+
+ at item --without-curl
+Don't use the cURL, disable the @code{urlread} and @code{urlwrite}
+functions.
+
+ at item --without-cxsparse
+Don't use CXSPARSE, disable some sparse matrix functionality.
+
+ at item --without-umfpack
+Don't use UMFPACK, disable some sparse matrix functionality.
+
+ at item --without-fftw
+Use the included @sc{fftpack} library instead of the @sc{fftw} library.
+
+ at item --without-glpk
+Don't use the GLPK library for linear programming.
+
+ at item --without-hdf5
+Don't use the HDF5 library for reading and writing HDF5 files.
+
+ at item --without-zlib
+Don't use the zlib library, disable data file compression and support
+for recent MAT file formats.
+
+ at item --without-lapack
+Compile and use the generic @sc{blas} and @sc{lapack} versions included with
+Octave.  By default, configure first looks for @sc{blas} and @sc{lapack} matrix
+libraries on your system, including optimized @sc{blas} implementations such
+as the free ATLAS 3.0, as well as vendor-tuned libraries.  (The use of
+an optimized @sc{blas} will generally result in several-times faster matrix
+operations.)  Only use this option if your system has @sc{blas}/@sc{lapack}
+libraries that cause problems for some reason.  You can also use
+ at code{--with-blas=lib} to specify a particular @sc{blas} library
+ that configure doesn't check for automatically.
+
+ at item --without-framework-carbon
+Don't use framework Carbon headers, libraries and specific source code
+for compilation even if the configure test succeeds (the default value
+is @code{--with-framework-carbon}).  This is a platform specific configure
+option for Mac systems.
+
+ at item --without-framework-opengl
+Don't use framework OpenGL headers, libraries and specific source code
+for compilation even if the configure test succeeds.  If this option is
+given then OpenGL headers and libraries in standard system locations are
+tested (the default value is @code{--with-framework-opengl}).  This is a
+platform specific configure option for Mac systems.
+
+ at item --help
+Print a summary of the options recognized by the configure script.
+ at end table
+
+See the file @file{INSTALL} for more general information about the 
+command line options used by configure.  That file also contains 
+instructions for compiling in a directory other than where the source 
+is located.
+
+ at item
+Run make.
+
+You will need a recent version of GNU Make.  Modifying Octave's
+makefiles to work with other make programs is probably not worth
+your time.  We recommend you get and compile GNU Make instead.
+
+For plotting, you will need to have gnuplot installed on your system.
+Gnuplot is a command-driven interactive function plotting program.
+Gnuplot is copyrighted, but freely distributable.  The `gnu' in gnuplot
+is a coincidence---it is not related to the GNU project or the FSF in
+any but the most peripheral sense.
+
+To compile Octave, you will need a recent version of GNU Make.  You will
+also need a recent version of @code{g++} or other ANSI C++ compiler.  You
+will also need a Fortran 77 compiler or @code{f2c}.  If you use
+ at code{f2c}, you will need a script like @code{fort77} that works like a
+normal Fortran compiler by combining @code{f2c} with your C compiler in
+a single script.
+
+If you plan to modify the parser you will also need GNU @code{bison} and
+ at code{flex}.  If you modify the documentation, you will need GNU
+Texinfo, along with the patch for the @code{makeinfo} program that is
+distributed with Octave.
+
+GNU Make, @code{gcc}, and @code{libstdc++}, @code{gnuplot},
+ at code{bison}, @code{flex}, and Texinfo are all available from many
+anonymous ftp archives.  The primary site is @url{ftp.gnu.org}, but it
+is often very busy.  A list of sites that mirror the software on
+ at url{ftp.gnu.org} is available by anonymous ftp from
+ at url{ftp://ftp.gnu.org/pub/gnu/GNUinfo/FTP}.
+
+You will need about 1 gigabyte of disk storage to work with when
+building Octave from source (considerably less if you don't compile with
+debugging symbols).  To do that, use the command
+
+ at example
+make CFLAGS=-O CXXFLAGS=-O LDFLAGS=
+ at end example
+
+ at noindent
+instead of just @samp{make}.
+
+ at item
+If you encounter errors while compiling Octave, first check the list of
+known problems below to see if there is a workaround or solution for
+your problem.  If not,
+ at ifclear INSTALLONLY
+see @ref{Trouble},
+ at end ifclear
+ at ifset INSTALLONLY
+see the file BUGS
+ at end ifset
+for information about how to report bugs.
+
+ at item
+Once you have successfully compiled Octave, run @samp{make install}.
+
+This will install a copy of Octave, its libraries, and its documentation
+in the destination directory.  As distributed, Octave is installed in
+the following directories.  In the table below, @var{prefix} defaults to
+ at file{/usr/local}, @var{version} stands for the current version number
+of the interpreter, and @var{arch} is the type of computer on which
+Octave is installed (for example, @samp{i586-unknown-gnu}).
+
+ at table @file
+ at item @var{prefix}/bin
+Octave and other binaries that people will want to run directly.
+
+ at item @var{prefix}/lib
+Libraries like libcruft.a and liboctave.a.
+
+ at item @var{prefix}/share
+Architecture-independent data files.
+
+ at item @var{prefix}/include/octave
+Include files distributed with Octave.
+
+ at item @var{prefix}/man/man1
+Unix-style man pages describing Octave.
+
+ at item @var{prefix}/info
+Info files describing Octave.
+
+ at item @var{prefix}/share/octave/@var{version}/m
+Function files distributed with Octave.  This includes the Octave
+version, so that multiple versions of Octave may be installed at the
+same time.
+
+ at item @var{prefix}/lib/octave/@var{version}/exec/@var{arch}
+Executables to be run by Octave rather than the user.
+
+ at item @var{prefix}/lib/octave/@var{version}/oct/@var{arch}
+Object files that will be dynamically loaded.
+
+ at item @var{prefix}/share/octave/@var{version}/imagelib
+Image files that are distributed with Octave.
+ at end table
+ at end itemize
+
+ at menu
+* Installation Problems::       
+ at end menu
+
+ at node Installation Problems
+ at appendixsec Installation Problems
+
+This section contains a list of problems (and some apparent problems
+that don't really mean anything is wrong) that may show up during
+installation of Octave.
+
+ at itemize @bullet
+ at item
+On some SCO systems, @code{info} fails to compile if
+ at w{@code{HAVE_TERMIOS_H}} is defined in @file{config.h}.  Simply removing
+the definition from @file{info/config.h} should allow it to compile.
+
+ at item
+If @code{configure} finds @code{dlopen}, @code{dlsym}, @code{dlclose},
+and @code{dlerror}, but not the header file @file{dlfcn.h}, you need to
+find the source for the header file and install it in the directory
+ at file{usr/include}.  This is reportedly a problem with Slackware 3.1.
+For Linux/GNU systems, the source for @file{dlfcn.h} is in the
+ at code{ldso} package.
+
+ at item
+Building @file{.oct} files doesn't work.
+
+You should probably have a shared version of @code{libstdc++}.  A patch
+is needed to build shared versions of version 2.7.2 of @code{libstdc++}
+on the HP-PA architecture.  You can find the patch at
+ at url{ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix}.
+
+ at item
+On some alpha systems there may be a problem with the @code{libdxml}
+library, resulting in floating point errors and/or segmentation faults in
+the linear algebra routines called by Octave.  If you encounter such
+problems, then you should modify the configure script so that
+ at w{@code{SPECIAL_MATH_LIB}} is not set to @code{-ldxml}.
+
+ at item
+On FreeBSD systems Octave may hang while initializing some internal
+constants.  The fix appears to be to use
+
+ at example
+options      GPL_MATH_EMULATE
+ at end example
+
+ at noindent
+rather than 
+
+ at example
+options      MATH_EMULATE 
+ at end example
+
+ at noindent
+in the kernel configuration files (typically found in the directory
+ at file{/sys/i386/conf}.  After making this change, you'll need to rebuild
+the kernel, install it, and reboot.
+
+ at item
+If you encounter errors like
+
+ at example
+ at group
+passing `void (*)()' as argument 2 of
+  `octave_set_signal_handler(int, void (*)(int))'
+ at end group
+ at end example
+
+ at noindent
+or
+
+ at example
+ at group
+warning: ANSI C++ prohibits conversion from `(int)' 
+         to `(@dots{})'
+ at end group
+ at end example
+
+ at noindent
+while compiling @file{sighandlers.cc}, you may need to edit some files
+in the @code{gcc} include subdirectory to add proper prototypes for functions
+there.  For example, Ultrix 4.2 needs proper declarations for the
+ at code{signal} function and the @w{@code{SIG_IGN}} macro in the file
+ at file{signal.h}.
+
+On some systems the @w{@code{SIG_IGN}} macro is defined to be something like
+this:
+
+ at example
+#define  SIG_IGN  (void (*)())1
+ at end example
+
+ at noindent
+when it should really be something like:
+
+ at example
+#define  SIG_IGN  (void (*)(int))1
+ at end example
+
+ at noindent
+to match the prototype declaration for the @code{signal} function.  This
+change should also be made for the @w{@code{SIG_DFL}} and @w{@code{SIG_ERR}}
+symbols.  It may be necessary to change the definitions in
+ at file{sys/signal.h} as well.
+
+The @code{gcc} @code{fixincludes} and @code{fixproto} scripts should
+probably fix these problems when @code{gcc} installs its modified set of
+header files, but I don't think that's been done yet.
+
+ at strong{You should not change the files in @file{/usr/include}}.  You
+can find the @code{gcc} include directory tree by running the command
+
+ at example
+gcc -print-libgcc-file-name
+ at end example
+
+ at noindent
+The directory of @code{gcc} include files normally begins in the same directory
+that contains the file @file{libgcc.a}.
+
+ at item
+Some of the Fortran subroutines may fail to compile with older versions
+of the Sun Fortran compiler.  If you get errors like
+
+ at example
+ at group
+zgemm.f:
+	zgemm:
+warning: unexpected parent of complex expression subtree
+zgemm.f, line 245: warning: unexpected parent of complex
+  expression subtree
+warning: unexpected parent of complex expression subtree
+zgemm.f, line 304: warning: unexpected parent of complex
+  expression subtree
+warning: unexpected parent of complex expression subtree
+zgemm.f, line 327: warning: unexpected parent of complex
+  expression subtree
+pcc_binval: missing IR_CONV in complex op
+make[2]: *** [zgemm.o] Error 1
+ at end group
+ at end example
+
+ at noindent
+when compiling the Fortran subroutines in the @file{libcruft}
+subdirectory, you should either upgrade your compiler or try compiling
+with optimization turned off.
+
+ at item
+On NeXT systems, if you get errors like this:
+
+ at example
+ at group
+/usr/tmp/cc007458.s:unknown:Undefined local 
+      symbol LBB7656
+/usr/tmp/cc007458.s:unknown:Undefined local
+      symbol LBE7656
+ at end group
+ at end example
+
+ at noindent
+when compiling @file{Array.cc} and @file{Matrix.cc}, try recompiling
+these files without @code{-g}.
+
+ at item
+Some people have reported that calls to shell_cmd and the pager do not
+work on SunOS systems.  This is apparently due to having
+ at w{@code{G_HAVE_SYS_WAIT}} defined to be 0 instead of 1 when compiling
+ at code{libg++}.
+
+ at item
+On NeXT systems, linking to @file{libsys_s.a} may fail to resolve the
+following functions
+
+ at example
+ at group
+_tcgetattr
+_tcsetattr
+_tcflow
+ at end group
+ at end example
+
+ at noindent
+which are part of @file{libposix.a}.  Unfortunately, linking Octave with
+ at code{-posix} results in the following undefined symbols.
+
+ at example
+ at group
+.destructors_used
+.constructors_used
+_objc_msgSend
+_NXGetDefaultValue
+_NXRegisterDefaults
+.objc_class_name_NXStringTable
+.objc_class_name_NXBundle
+ at end group
+ at end example
+
+One kluge around this problem is to extract @file{termios.o} from
+ at file{libposix.a}, put it in Octave's @file{src} directory, and add it
+to the list of files to link together in the makefile.  Suggestions for
+better ways to solve this problem are welcome!
+
+ at item
+If Octave crashes immediately with a floating point exception, it is
+likely that it is failing to initialize the IEEE floating point values
+for infinity and NaN.
+
+If your system actually does support IEEE arithmetic, you should be able
+to fix this problem by modifying the function @code{octave_ieee_init} in
+the file @file{lo-ieee.cc} to correctly initialize Octave's internal
+infinity and NaN variables.
+
+If your system does not support IEEE arithmetic but Octave's configure
+script incorrectly determined that it does, you can work around the
+problem by editing the file @file{config.h} to not define
+ at w{@code{HAVE_ISINF}}, @w{@code{HAVE_FINITE}}, and @w{@code{HAVE_ISNAN}}.
+
+In any case, please report this as a bug since it might be possible to
+modify Octave's configuration script to automatically determine the
+proper thing to do.
+
+ at item
+If Octave is unable to find a header file because it is installed in a
+location that is not normally searched by the compiler, you can add the
+directory to the include search path by specifying (for example)
+ at code{CPPFLAGS=-I/some/nonstandard/directory} as an argument to
+ at code{configure}.  Other variables that can be specified this way are
+ at code{CFLAGS}, @code{CXXFLAGS}, @code{FFLAGS}, and @code{LDFLAGS}.
+Passing them as options to the configure script also records them in the
+ at file{config.status} file.  By default, @code{CPPFLAGS} and
+ at code{LDFLAGS} are empty, @code{CFLAGS} and @code{CXXFLAGS} are set to
+ at code{"-g -O"} and @code{FFLAGS} is set to @code{"-O"}.
+
+ at end itemize
diff --git a/doc/interpreter/install.txi b/doc/interpreter/install.txi
new file mode 100644
index 0000000..c2a5968
--- /dev/null
+++ b/doc/interpreter/install.txi
@@ -0,0 +1,510 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c The text of this file appears in the file INSTALL in the Octave
+ at c distribution, as well as in the Octave manual.
+
+ at ifclear INSTALLONLY
+ at node Installation
+ at appendix Installing Octave
+ at end ifclear
+
+ at ifset INSTALLONLY
+ at include conf.texi
+
+This file documents the installation of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation.
+
+ at strong{Note:} This file is automatically generated from
+ at file{doc/interpreter/install.txi} in the Octave sources.  To update
+the documentation make changes to the .txi source file rather than this
+derived file.
+
+ at node Installation
+ at chapter Installing Octave
+ at end ifset
+
+ at cindex installing Octave
+
+Here is the procedure for installing Octave from scratch on a Unix
+system.
+
+ at itemize @bullet
+ at item
+Run the shell script @file{configure}.  This will determine the features
+your system has (or doesn't have) and create a file named
+ at file{Makefile} from each of the files named @file{Makefile.in}.
+
+Here is a summary of the configure options that are most frequently used
+when building Octave:
+
+ at table @code
+ at item --prefix=@var{prefix}
+Install Octave in subdirectories below @var{prefix}.  The default value
+of @var{prefix} is @file{/usr/local}.
+
+ at item --srcdir=@var{dir}
+Look for Octave sources in the directory @var{dir}.
+
+ at item --enable-bounds-check
+Enable bounds checking for indexing operators in the internal array
+classes.  This option is primarily used for debugging Octave.  Building
+Octave with this option has a negative impact on performance and is not
+recommended for general use.
+
+ at item --enable-64
+This is an @strong{experimental} option to enable Octave to use 64-bit
+integers for array dimensions and indexing on 64-bit platforms.  You
+probably don't want to use this option unless you know what you are
+doing.
+
+If you use @code{--enable-64}, you must ensure that your Fortran
+compiler generates code with 8 byte signed @code{INTEGER} values, and
+that your @sc{blas} and @sc{lapack} libraries are compiled to use 8 byte
+signed integers for array dimensions and indexing.
+
+ at item --enable-shared
+Create shared libraries (this is the default).  If you are planning to
+use the dynamic loading features, you will probably want to use this
+option.  It will make your @file{.oct} files much smaller and on some
+systems it may be necessary to build shared libraries in order to use
+dynamically linked functions.
+
+You may also want to build a shared version of @code{libstdc++}, if your
+system doesn't already have one.
+
+ at item --enable-dl
+Use @code{dlopen} and friends to make Octave capable of dynamically
+linking externally compiled functions (this is the default if
+ at code{--enable-shared} is specified).  This option only works on systems
+that actually have these functions.  If you plan on using this feature, you
+should probably also use @code{--enable-shared} to reduce the size of
+your @file{.oct} files.
+
+ at item --without-blas
+Compile and use the generic @sc{blas} and @sc{lapack} versions included with
+Octave.  By default, configure first looks for @sc{blas} and @sc{lapack} matrix
+libraries on your system, including optimized @sc{blas} implementations such
+as the free ATLAS 3.0, as well as vendor-tuned libraries.  (The use of
+an optimized @sc{blas} will generally result in several-times faster matrix
+operations.)  Only use this option if your system has @sc{blas}/@sc{lapack}
+libraries that cause problems for some reason.  You can also use
+ at code{--with-blas=lib} to specify a particular @sc{blas} library
+ that configure doesn't check for automatically.
+
+ at item --without-ccolamd
+Don't use CCOLAMD, disable some sparse matrix functionality.
+
+ at item --without-colamd
+Don't use COLAMD, disable some sparse matrix functionality.
+
+ at item --without-curl
+Don't use the cURL, disable the @code{urlread} and @code{urlwrite}
+functions.
+
+ at item --without-cxsparse
+Don't use CXSPARSE, disable some sparse matrix functionality.
+
+ at item --without-umfpack
+Don't use UMFPACK, disable some sparse matrix functionality.
+
+ at item --without-fftw
+Use the included @sc{fftpack} library instead of the @sc{fftw} library.
+
+ at item --without-glpk
+Don't use the GLPK library for linear programming.
+
+ at item --without-hdf5
+Don't use the HDF5 library for reading and writing HDF5 files.
+
+ at item --without-zlib
+Don't use the zlib library, disable data file compression and support
+for recent MAT file formats.
+
+ at item --without-lapack
+Compile and use the generic @sc{blas} and @sc{lapack} versions included with
+Octave.  By default, configure first looks for @sc{blas} and @sc{lapack} matrix
+libraries on your system, including optimized @sc{blas} implementations such
+as the free ATLAS 3.0, as well as vendor-tuned libraries.  (The use of
+an optimized @sc{blas} will generally result in several-times faster matrix
+operations.)  Only use this option if your system has @sc{blas}/@sc{lapack}
+libraries that cause problems for some reason.  You can also use
+ at code{--with-blas=lib} to specify a particular @sc{blas} library
+ that configure doesn't check for automatically.
+
+ at item --without-framework-carbon
+Don't use framework Carbon headers, libraries and specific source code
+for compilation even if the configure test succeeds (the default value
+is @code{--with-framework-carbon}).  This is a platform specific configure
+option for Mac systems.
+
+ at item --without-framework-opengl
+Don't use framework OpenGL headers, libraries and specific source code
+for compilation even if the configure test succeeds.  If this option is
+given then OpenGL headers and libraries in standard system locations are
+tested (the default value is @code{--with-framework-opengl}).  This is a
+platform specific configure option for Mac systems.
+
+ at item --help
+Print a summary of the options recognized by the configure script.
+ at end table
+
+See the file @file{INSTALL} for more general information about the 
+command line options used by configure.  That file also contains 
+instructions for compiling in a directory other than where the source 
+is located.
+
+ at item
+Run make.
+
+You will need a recent version of GNU Make.  Modifying Octave's
+makefiles to work with other make programs is probably not worth
+your time.  We recommend you get and compile GNU Make instead.
+
+For plotting, you will need to have gnuplot installed on your system.
+Gnuplot is a command-driven interactive function plotting program.
+Gnuplot is copyrighted, but freely distributable.  The `gnu' in gnuplot
+is a coincidence---it is not related to the GNU project or the FSF in
+any but the most peripheral sense.
+
+To compile Octave, you will need a recent version of GNU Make.  You will
+also need a recent version of @code{g++} or other ANSI C++ compiler.  You
+will also need a Fortran 77 compiler or @code{f2c}.  If you use
+ at code{f2c}, you will need a script like @code{fort77} that works like a
+normal Fortran compiler by combining @code{f2c} with your C compiler in
+a single script.
+
+If you plan to modify the parser you will also need GNU @code{bison} and
+ at code{flex}.  If you modify the documentation, you will need GNU
+Texinfo, along with the patch for the @code{makeinfo} program that is
+distributed with Octave.
+
+GNU Make, @code{gcc}, and @code{libstdc++}, @code{gnuplot},
+ at code{bison}, @code{flex}, and Texinfo are all available from many
+anonymous ftp archives.  The primary site is @url{ftp.gnu.org}, but it
+is often very busy.  A list of sites that mirror the software on
+ at url{ftp.gnu.org} is available by anonymous ftp from
+ at url{ftp://ftp.gnu.org/pub/gnu/GNUinfo/FTP}.
+
+You will need about 1 gigabyte of disk storage to work with when
+building Octave from source (considerably less if you don't compile with
+debugging symbols).  To do that, use the command
+
+ at example
+make CFLAGS=-O CXXFLAGS=-O LDFLAGS=
+ at end example
+
+ at noindent
+instead of just @samp{make}.
+
+ at item
+If you encounter errors while compiling Octave, first check the list of
+known problems below to see if there is a workaround or solution for
+your problem.  If not,
+ at ifclear INSTALLONLY
+see @ref{Trouble},
+ at end ifclear
+ at ifset INSTALLONLY
+see the file BUGS
+ at end ifset
+for information about how to report bugs.
+
+ at item
+Once you have successfully compiled Octave, run @samp{make install}.
+
+This will install a copy of Octave, its libraries, and its documentation
+in the destination directory.  As distributed, Octave is installed in
+the following directories.  In the table below, @var{prefix} defaults to
+ at file{/usr/local}, @var{version} stands for the current version number
+of the interpreter, and @var{arch} is the type of computer on which
+Octave is installed (for example, @samp{i586-unknown-gnu}).
+
+ at table @file
+ at item @var{prefix}/bin
+Octave and other binaries that people will want to run directly.
+
+ at item @var{prefix}/lib
+Libraries like libcruft.a and liboctave.a.
+
+ at item @var{prefix}/share
+Architecture-independent data files.
+
+ at item @var{prefix}/include/octave
+Include files distributed with Octave.
+
+ at item @var{prefix}/man/man1
+Unix-style man pages describing Octave.
+
+ at item @var{prefix}/info
+Info files describing Octave.
+
+ at item @var{prefix}/share/octave/@var{version}/m
+Function files distributed with Octave.  This includes the Octave
+version, so that multiple versions of Octave may be installed at the
+same time.
+
+ at item @var{prefix}/lib/octave/@var{version}/exec/@var{arch}
+Executables to be run by Octave rather than the user.
+
+ at item @var{prefix}/lib/octave/@var{version}/oct/@var{arch}
+Object files that will be dynamically loaded.
+
+ at item @var{prefix}/share/octave/@var{version}/imagelib
+Image files that are distributed with Octave.
+ at end table
+ at end itemize
+
+ at menu
+* Installation Problems::       
+ at end menu
+
+ at node Installation Problems
+ at appendixsec Installation Problems
+
+This section contains a list of problems (and some apparent problems
+that don't really mean anything is wrong) that may show up during
+installation of Octave.
+
+ at itemize @bullet
+ at item
+On some SCO systems, @code{info} fails to compile if
+ at w{@code{HAVE_TERMIOS_H}} is defined in @file{config.h}.  Simply removing
+the definition from @file{info/config.h} should allow it to compile.
+
+ at item
+If @code{configure} finds @code{dlopen}, @code{dlsym}, @code{dlclose},
+and @code{dlerror}, but not the header file @file{dlfcn.h}, you need to
+find the source for the header file and install it in the directory
+ at file{usr/include}.  This is reportedly a problem with Slackware 3.1.
+For Linux/GNU systems, the source for @file{dlfcn.h} is in the
+ at code{ldso} package.
+
+ at item
+Building @file{.oct} files doesn't work.
+
+You should probably have a shared version of @code{libstdc++}.  A patch
+is needed to build shared versions of version 2.7.2 of @code{libstdc++}
+on the HP-PA architecture.  You can find the patch at
+ at url{ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix}.
+
+ at item
+On some alpha systems there may be a problem with the @code{libdxml}
+library, resulting in floating point errors and/or segmentation faults in
+the linear algebra routines called by Octave.  If you encounter such
+problems, then you should modify the configure script so that
+ at w{@code{SPECIAL_MATH_LIB}} is not set to @code{-ldxml}.
+
+ at item
+On FreeBSD systems Octave may hang while initializing some internal
+constants.  The fix appears to be to use
+
+ at example
+options      GPL_MATH_EMULATE
+ at end example
+
+ at noindent
+rather than 
+
+ at example
+options      MATH_EMULATE 
+ at end example
+
+ at noindent
+in the kernel configuration files (typically found in the directory
+ at file{/sys/i386/conf}.  After making this change, you'll need to rebuild
+the kernel, install it, and reboot.
+
+ at item
+If you encounter errors like
+
+ at example
+ at group
+passing `void (*)()' as argument 2 of
+  `octave_set_signal_handler(int, void (*)(int))'
+ at end group
+ at end example
+
+ at noindent
+or
+
+ at example
+ at group
+warning: ANSI C++ prohibits conversion from `(int)' 
+         to `(@dots{})'
+ at end group
+ at end example
+
+ at noindent
+while compiling @file{sighandlers.cc}, you may need to edit some files
+in the @code{gcc} include subdirectory to add proper prototypes for functions
+there.  For example, Ultrix 4.2 needs proper declarations for the
+ at code{signal} function and the @w{@code{SIG_IGN}} macro in the file
+ at file{signal.h}.
+
+On some systems the @w{@code{SIG_IGN}} macro is defined to be something like
+this:
+
+ at example
+#define  SIG_IGN  (void (*)())1
+ at end example
+
+ at noindent
+when it should really be something like:
+
+ at example
+#define  SIG_IGN  (void (*)(int))1
+ at end example
+
+ at noindent
+to match the prototype declaration for the @code{signal} function.  This
+change should also be made for the @w{@code{SIG_DFL}} and @w{@code{SIG_ERR}}
+symbols.  It may be necessary to change the definitions in
+ at file{sys/signal.h} as well.
+
+The @code{gcc} @code{fixincludes} and @code{fixproto} scripts should
+probably fix these problems when @code{gcc} installs its modified set of
+header files, but I don't think that's been done yet.
+
+ at strong{You should not change the files in @file{/usr/include}}.  You
+can find the @code{gcc} include directory tree by running the command
+
+ at example
+gcc -print-libgcc-file-name
+ at end example
+
+ at noindent
+The directory of @code{gcc} include files normally begins in the same directory
+that contains the file @file{libgcc.a}.
+
+ at item
+Some of the Fortran subroutines may fail to compile with older versions
+of the Sun Fortran compiler.  If you get errors like
+
+ at example
+ at group
+zgemm.f:
+	zgemm:
+warning: unexpected parent of complex expression subtree
+zgemm.f, line 245: warning: unexpected parent of complex
+  expression subtree
+warning: unexpected parent of complex expression subtree
+zgemm.f, line 304: warning: unexpected parent of complex
+  expression subtree
+warning: unexpected parent of complex expression subtree
+zgemm.f, line 327: warning: unexpected parent of complex
+  expression subtree
+pcc_binval: missing IR_CONV in complex op
+make[2]: *** [zgemm.o] Error 1
+ at end group
+ at end example
+
+ at noindent
+when compiling the Fortran subroutines in the @file{libcruft}
+subdirectory, you should either upgrade your compiler or try compiling
+with optimization turned off.
+
+ at item
+On NeXT systems, if you get errors like this:
+
+ at example
+ at group
+/usr/tmp/cc007458.s:unknown:Undefined local 
+      symbol LBB7656
+/usr/tmp/cc007458.s:unknown:Undefined local
+      symbol LBE7656
+ at end group
+ at end example
+
+ at noindent
+when compiling @file{Array.cc} and @file{Matrix.cc}, try recompiling
+these files without @code{-g}.
+
+ at item
+Some people have reported that calls to shell_cmd and the pager do not
+work on SunOS systems.  This is apparently due to having
+ at w{@code{G_HAVE_SYS_WAIT}} defined to be 0 instead of 1 when compiling
+ at code{libg++}.
+
+ at item
+On NeXT systems, linking to @file{libsys_s.a} may fail to resolve the
+following functions
+
+ at example
+ at group
+_tcgetattr
+_tcsetattr
+_tcflow
+ at end group
+ at end example
+
+ at noindent
+which are part of @file{libposix.a}.  Unfortunately, linking Octave with
+ at code{-posix} results in the following undefined symbols.
+
+ at example
+ at group
+.destructors_used
+.constructors_used
+_objc_msgSend
+_NXGetDefaultValue
+_NXRegisterDefaults
+.objc_class_name_NXStringTable
+.objc_class_name_NXBundle
+ at end group
+ at end example
+
+One kluge around this problem is to extract @file{termios.o} from
+ at file{libposix.a}, put it in Octave's @file{src} directory, and add it
+to the list of files to link together in the makefile.  Suggestions for
+better ways to solve this problem are welcome!
+
+ at item
+If Octave crashes immediately with a floating point exception, it is
+likely that it is failing to initialize the IEEE floating point values
+for infinity and NaN.
+
+If your system actually does support IEEE arithmetic, you should be able
+to fix this problem by modifying the function @code{octave_ieee_init} in
+the file @file{lo-ieee.cc} to correctly initialize Octave's internal
+infinity and NaN variables.
+
+If your system does not support IEEE arithmetic but Octave's configure
+script incorrectly determined that it does, you can work around the
+problem by editing the file @file{config.h} to not define
+ at w{@code{HAVE_ISINF}}, @w{@code{HAVE_FINITE}}, and @w{@code{HAVE_ISNAN}}.
+
+In any case, please report this as a bug since it might be possible to
+modify Octave's configuration script to automatically determine the
+proper thing to do.
+
+ at item
+If Octave is unable to find a header file because it is installed in a
+location that is not normally searched by the compiler, you can add the
+directory to the include search path by specifying (for example)
+ at code{CPPFLAGS=-I/some/nonstandard/directory} as an argument to
+ at code{configure}.  Other variables that can be specified this way are
+ at code{CFLAGS}, @code{CXXFLAGS}, @code{FFLAGS}, and @code{LDFLAGS}.
+Passing them as options to the configure script also records them in the
+ at file{config.status} file.  By default, @code{CPPFLAGS} and
+ at code{LDFLAGS} are empty, @code{CFLAGS} and @code{CXXFLAGS} are set to
+ at code{"-g -O"} and @code{FFLAGS} is set to @code{"-O"}.
+
+ at end itemize
diff --git a/doc/interpreter/interp.texi b/doc/interpreter/interp.texi
new file mode 100644
index 0000000..86d1c76
--- /dev/null
+++ b/doc/interpreter/interp.texi
@@ -0,0 +1,536 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Interpolation
+ at chapter Interpolation
+
+ at menu
+* One-dimensional Interpolation::
+* Multi-dimensional Interpolation::
+ at end menu
+
+ at node One-dimensional Interpolation
+ at section One-dimensional Interpolation
+
+Octave supports several methods for one-dimensional interpolation, most
+of which are described in this section.  @ref{Polynomial Interpolation}
+and @ref{Interpolation on Scattered Data} describe further methods.
+
+ at c ./general/interp1.m
+ at anchor{doc-interp1}
+ at deftypefn {Function File} {@var{yi} =} interp1 (@var{x}, @var{y}, @var{xi})
+ at deftypefnx {Function File} {@var{yi} =} interp1 (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{yi} =} interp1 (@dots{}, @var{extrap})
+ at deftypefnx {Function File} {@var{pp} =} interp1 (@dots{}, 'pp')
+
+One-dimensional interpolation.  Interpolate @var{y}, defined at the
+points @var{x}, at the points @var{xi}.  The sample points @var{x} 
+must be strictly monotonic.  If @var{y} is an array, treat the columns
+of @var{y} separately.
+
+Method is one of:
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors
+ at item 'pchip'
+Piece-wise cubic hermite interpolating polynomial
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve
+ at end table
+
+Appending '*' to the start of the above method forces @code{interp1}
+to assume that @var{x} is uniformly spaced, and only @code{@var{x}
+(1)} and @code{@var{x} (2)} are referenced.  This is usually faster,
+and is never slower.  The default method is 'linear'.
+
+If @var{extrap} is the string 'extrap', then extrapolate values beyond
+the endpoints.  If @var{extrap} is a number, replace values beyond the
+endpoints with that number.  If @var{extrap} is missing, assume NA.
+
+If the string argument 'pp' is specified, then @var{xi} should not be
+supplied and @code{interp1} returns the piece-wise polynomial that
+can later be used with @code{ppval} to evaluate the interpolation.
+There is an equivalence, such that @code{ppval (interp1 (@var{x},
+ at var{y}, @var{method}, 'pp'), @var{xi}) == interp1 (@var{x}, @var{y},
+ at var{xi}, @var{method}, 'extrap')}.
+
+An example of the use of @code{interp1} is
+
+ at example
+ at group
+xf = [0:0.05:10];
+yf = sin (2*pi*xf/5);
+xp = [0:10];
+yp = sin (2*pi*xp/5);
+lin = interp1 (xp, yp, xf);
+spl = interp1 (xp, yp, xf, "spline");
+cub = interp1 (xp, yp, xf, "cubic");
+near = interp1 (xp, yp, xf, "nearest");
+plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
+      xf, cub, "c", xf, near, "m", xp, yp, "r*");
+legend ("original", "linear", "spline", "cubic", "nearest")
+ at end group
+ at end example
+
+ at seealso{@ref{doc-interpft,,interpft}}
+ at end deftypefn
+
+
+There are some important differences between the various interpolation
+methods.  The 'spline' method enforces that both the first and second
+derivatives of the interpolated values have a continuous derivative,
+whereas the other methods do not.  This means that the results of the
+'spline' method are generally smoother.  If the function to be
+interpolated is in fact smooth, then 'spline' will give excellent
+results.  However, if the function to be evaluated is in some manner
+discontinuous, then 'pchip' interpolation might give better results.
+
+This can be demonstrated by the code
+
+ at example
+ at group
+t = -2:2;
+dt = 1;
+ti =-2:0.025:2;
+dti = 0.025;
+y = sign(t);
+ys = interp1(t,y,ti,'spline');
+yp = interp1(t,y,ti,'pchip');
+ddys = diff(diff(ys)./dti)./dti;
+ddyp = diff(diff(yp)./dti)./dti;
+figure(1);
+plot (ti, ys,'r-', ti, yp,'g-');
+legend('spline','pchip',4);
+figure(2);
+plot (ti, ddys,'r+', ti, ddyp,'g*');
+legend('spline','pchip');
+ at end group
+ at end example
+
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:interpderiv1} and
+ at ref{fig:interpderiv2}.
+
+ at float Figure,fig:interpderiv1
+ at center @image{interpderiv1,4in}
+ at caption{Comparison of 'pchip' and 'spline' interpolation methods for a 
+step function}
+ at end float
+
+ at float Figure,fig:interpderiv2
+ at center @image{interpderiv2,4in}
+ at caption{Comparison of the second derivative of the 'pchip' and 'spline' 
+interpolation methods for a step function}
+ at end float
+ at end ifnotinfo
+
+A simplified version of @code{interp1} that performs only linear
+interpolation is available in @code{interp1q}.  This argument is slightly
+faster than @code{interp1} as to performs little error checking.
+
+ at c ./general/interp1q.m
+ at anchor{doc-interp1q}
+ at deftypefn {Function File} {@var{yi} =} interp1q (@var{x}, @var{y}, @var{xi})
+One-dimensional linear interpolation without error checking.
+Interpolates @var{y}, defined at the points @var{x}, at the points
+ at var{xi}.  The sample points @var{x} must be a strictly monotonically
+increasing column vector.  If @var{y} is an array, treat the columns
+of @var{y} separately.  If @var{y} is a vector, it must be a column
+vector of the same length as @var{x}.
+
+Values of @var{xi} beyond the endpoints of the interpolation result
+in NA being returned.
+
+Note that the error checking is only a significant portion of the
+execution time of this @code{interp1} if the size of the input arguments
+is relatively small.  Therefore, the benefit of using @code{interp1q}
+is relatively small.
+ at seealso{@ref{doc-interp1,,interp1}}
+ at end deftypefn
+
+
+Fourier interpolation, is a resampling technique where a signal is
+converted to the frequency domain, padded with zeros and then
+reconverted to the time domain.
+
+ at c ./general/interpft.m
+ at anchor{doc-interpft}
+ at deftypefn {Function File} {} interpft (@var{x}, @var{n})
+ at deftypefnx {Function File} {} interpft (@var{x}, @var{n}, @var{dim})
+
+Fourier interpolation.  If @var{x} is a vector, then @var{x} is
+resampled with @var{n} points.  The data in @var{x} is assumed to be
+equispaced.  If @var{x} is an array, then operate along each column of
+the array separately.  If @var{dim} is specified, then interpolate
+along the dimension @var{dim}.
+
+ at code{interpft} assumes that the interpolated function is periodic,
+and so assumptions are made about the end points of the interpolation.
+
+ at seealso{@ref{doc-interp1,,interp1}}
+ at end deftypefn
+
+
+There are two significant limitations on Fourier interpolation.  Firstly,
+the function signal is assumed to be periodic, and so non-periodic
+signals will be poorly represented at the edges.  Secondly, both the
+signal and its interpolation are required to be sampled at equispaced
+points.  An example of the use of @code{interpft} is
+
+ at example
+ at group
+t = 0 : 0.3 : pi; dt = t(2)-t(1);
+n = length (t); k = 100;
+ti = t(1) + [0 : k-1]*dt*n/k;
+y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
+plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ...
+      ti, interpft (y, k), 'c', t, y, 'r+');
+legend ('sin(4t+0.3)cos(3t-0.1','spline','interpft','data');
+ at end group
+ at end example
+
+ at noindent
+ at ifinfo
+which demonstrates the poor behavior of Fourier interpolation for non-periodic functions.
+ at end ifinfo
+ at ifnotinfo
+which demonstrates the poor behavior of Fourier interpolation for non-periodic functions, as can be seen in @ref{fig:interpft}.
+
+ at float Figure,fig:interpft
+ at center @image{interpft,4in}
+ at caption{Comparison of @code{interp1} and @code{interpft} for non-periodic data}
+ at end float
+ at end ifnotinfo
+
+In additional the support function @code{spline} and @code{lookup} that
+underlie the @code{interp1} function can be called directly.
+
+ at c ./polynomial/spline.m
+ at anchor{doc-spline}
+ at deftypefn {Function File} {@var{pp} =} spline (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{yi} =} spline (@var{x}, @var{y}, @var{xi})
+
+Return the cubic spline interpolant of @var{y} at points @var{x}. 
+If called with two arguments, @code{spline} returns the piece-wise
+polynomial @var{pp} that may later be used with @code{ppval} to
+evaluate the polynomial at specific points.
+If called with a third input argument, @code{spline} evaluates the 
+spline at the points @var{xi}.  There is an equivalence
+between @code{ppval (spline (@var{x}, @var{y}), @var{xi})} and
+ at code{spline (@var{x}, @var{y}, @var{xi})}.
+
+The variable @var{x} must be a vector of length @var{n}, and @var{y}
+can be either a vector or array.  In the case where @var{y} is a
+vector, it can have a length of either @var{n} or @code{@var{n} + 2}.
+If the length of @var{y} is @var{n}, then the 'not-a-knot' end
+condition is used.  If the length of @var{y} is @code{@var{n} + 2},
+then the first and last values of the vector @var{y} are the values
+of the first derivative of the cubic spline at the end-points.
+
+If @var{y} is an array, then the size of @var{y} must have the form
+ at tex
+$$[s_1, s_2, \cdots, s_k, n]$$
+ at end tex
+ at ifnottex
+ at code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]}
+ at end ifnottex
+or
+ at tex
+$$[s_1, s_2, \cdots, s_k, n + 2].$$
+ at end tex
+ at ifnottex
+ at code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n} + 2]}.
+ at end ifnottex
+The array is then reshaped internally to a matrix where the leading
+dimension is given by 
+ at tex
+$$s_1 s_2 \cdots s_k$$
+ at end tex
+ at ifnottex
+ at code{@var{s1} * @var{s2} * @dots{} * @var{sk}}
+ at end ifnottex
+and each row of this matrix is then treated separately.  Note that this
+is exactly the opposite treatment than @code{interp1} and is done
+for compatibility.
+ at seealso{@ref{doc-ppval,,ppval}, @ref{doc-mkpp,,mkpp}, @ref{doc-unmkpp,,unmkpp}}
+ at end deftypefn
+
+
+The @code{lookup} function is used by other interpolation functions to identify
+the points of the original data that are closest to the current point
+of interest.
+
+ at c ./DLD-FUNCTIONS/lookup.cc
+ at anchor{doc-lookup}
+ at deftypefn {Loadable Function} {@var{idx} =} lookup (@var{table}, @var{y}, @var{opt})
+Lookup values in a sorted table.  Usually used as a prelude to
+interpolation.
+
+If table is strictly increasing and @code{idx = lookup (table, y)}, then
+ at code{table(idx(i)) <= y(i) < table(idx(i+1))} for all @code{y(i)}
+within the table.  If @code{y(i) < table (1)} then
+ at code{idx(i)} is 0. If @code{y(i) >= table(end)} then
+ at code{idx(i)} is @code{table(n)}.
+
+If the table is strictly decreasing, then the tests are reversed.
+There are no guarantees for tables which are non-monotonic or are not
+strictly monotonic.
+
+The algorithm used by lookup is standard binary search, with optimizations
+to speed up the case of partially ordered arrays (dense downsampling).
+In particular, looking up a single entry is of logarithmic complexity
+(unless a conversion occurs due to non-numeric or unequal types).
+
+ at var{table} and @var{y} can also be cell arrays of strings
+(or @var{y} can be a single string).  In this case, string lookup
+is performed using lexicographical comparison.
+
+If @var{opts} is specified, it shall be a string with letters indicating
+additional options.
+For numeric lookup, 'l' in @var{opts} indicates that
+the leftmost subinterval shall be extended to infinity (i.e., all indices
+at least 1), and 'r' indicates that the rightmost subinterval shall be
+extended to infinity (i.e., all indices at most n-1).
+
+For string lookup, 'i' indicates case-insensitive comparison.
+ at end deftypefn
+
+
+ at node Multi-dimensional Interpolation
+ at section Multi-dimensional Interpolation
+
+There are three multi-dimensional interpolation functions in Octave, with
+similar capabilities.  Methods using Delaunay tessellation are described
+in @ref{Interpolation on Scattered Data}.
+
+ at c ./general/interp2.m
+ at anchor{doc-interp2}
+ at deftypefn {Function File} {@var{zi} =} interp2 (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{xi}, @var{yi})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{n})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method}, @var{extrapval})
+
+Two-dimensional interpolation.  @var{x}, @var{y} and @var{z} describe a
+surface function.  If @var{x} and @var{y} are vectors their length
+must correspondent to the size of @var{z}.  @var{x} and @var{y} must be
+monotonic.  If they are matrices they must have the @code{meshgrid} 
+format. 
+
+ at table @code
+ at item interp2 (@var{x}, @var{y}, @var{Z}, @var{xi}, @var{yi}, @dots{}) 
+Returns a matrix corresponding to the points described by the
+matrices @var{xi}, @var{yi}.  
+
+If the last argument is a string, the interpolation method can
+be specified.  The method can be 'linear', 'nearest' or 'cubic'.
+If it is omitted 'linear' interpolation is assumed.
+
+ at item interp2 (@var{z}, @var{xi}, @var{yi})
+Assumes @code{@var{x} = 1:rows (@var{z})} and @code{@var{y} = 
+1:columns (@var{z})}
+
+ at item interp2 (@var{z}, @var{n}) 
+Interleaves the matrix @var{z} n-times.  If @var{n} is omitted a value
+of @code{@var{n} = 1} is assumed.
+ at end table
+
+The variable @var{method} defines the method to use for the
+interpolation.  It can take one of the following values 
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors.
+ at item 'pchip'
+Piece-wise cubic hermite interpolating polynomial (not implemented yet).
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors.
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve.
+ at end table
+
+If a scalar value @var{extrapval} is defined as the final value, then
+values outside the mesh as set to this value.  Note that in this case 
+ at var{method} must be defined as well.  If @var{extrapval} is not
+defined then NA is assumed. 
+
+ at seealso{@ref{doc-interp1,,interp1}}
+ at end deftypefn
+
+
+ at c ./general/interp3.m
+ at anchor{doc-interp3}
+ at deftypefn {Function File} {@var{vi} =} interp3 (@var{x}, @var{y}, at var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{m})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@var{v})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method}, @var{extrapval})
+
+Perform 3-dimensional interpolation.  Each element of the 3-dimensional 
+array @var{v} represents a value at a location given by the parameters 
+ at var{x}, @var{y}, and @var{z}.  The parameters @var{x}, @var{x}, and 
+ at var{z} are either 3-dimensional arrays of the same size as the array 
+ at var{v} in the 'meshgrid' format or vectors.  The parameters @var{xi}, etc. 
+respect a similar format to @var{x}, etc., and they represent the points 
+at which the array @var{vi} is interpolated.
+
+If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be 
+ at code{x = 1 : size (@var{v}, 2)}, @code{y = 1 : size (@var{v}, 1)} and
+ at code{z = 1 : size (@var{v}, 3)}.  If @var{m} is specified, then
+the interpolation adds a point half way between each of the interpolation 
+points.  This process is performed @var{m} times.  If only @var{v} is 
+specified, then @var{m} is assumed to be @code{1}.
+
+Method is one of:
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors.
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors (not implemented yet).
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve.
+ at end table
+
+The default method is 'linear'.
+
+If @var{extrap} is the string 'extrap', then extrapolate values beyond
+the endpoints.  If @var{extrap} is a number, replace values beyond the
+endpoints with that number.  If @var{extrap} is missing, assume NA.
+ at seealso{@ref{doc-interp1,,interp1}, @ref{doc-interp2,,interp2}, @ref{doc-spline,,spline}, @ref{doc-meshgrid,,meshgrid}}
+ at end deftypefn
+
+
+ at c ./general/interpn.m
+ at anchor{doc-interpn}
+ at deftypefn {Function File} {@var{vi} =} interpn (@var{x1}, @var{x2}, @dots{}, @var{v}, @var{y1}, @var{y2}, @dots{})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@var{v}, @var{y1}, @var{y2}, @dots{})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@var{v}, @var{m})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@var{v})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@dots{}, @var{method}, @var{extrapval})
+
+Perform @var{n}-dimensional interpolation, where @var{n} is at least two. 
+Each element of the @var{n}-dimensional array @var{v} represents a value 
+at a location given by the parameters @var{x1}, @var{x2}, @dots{}, @var{xn}. 
+The parameters @var{x1}, @var{x2}, @dots{}, @var{xn} are either 
+ at var{n}-dimensional arrays of the same size as the array @var{v} in 
+the 'ndgrid' format or vectors.  The parameters @var{y1}, etc. respect a 
+similar format to @var{x1}, etc., and they represent the points at which
+the array @var{vi} is interpolated.
+
+If @var{x1}, @dots{}, @var{xn} are omitted, they are assumed to be 
+ at code{x1 = 1 : size (@var{v}, 1)}, etc.  If @var{m} is specified, then
+the interpolation adds a point half way between each of the interpolation 
+points.  This process is performed @var{m} times.  If only @var{v} is 
+specified, then @var{m} is assumed to be @code{1}.
+
+Method is one of:
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors.
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors (not implemented yet).
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve.
+ at end table
+
+The default method is 'linear'.
+
+If @var{extrapval} is the scalar value, use it to replace the values
+beyond the endpoints with that number.  If @var{extrapval} is missing,
+assume NA.
+ at seealso{@ref{doc-interp1,,interp1}, @ref{doc-interp2,,interp2}, @ref{doc-spline,,spline}, @ref{doc-ndgrid,,ndgrid}}
+ at end deftypefn
+
+
+A significant difference between @code{interpn} and the other two
+multidimensional interpolation functions is the fashion in which the
+dimensions are treated.  For @code{interp2} and @code{interp3}, the 'y'
+axis is considered to be the columns of the matrix, whereas the 'x'
+axis corresponds to the rows of the array.  As Octave indexes arrays in
+column major order, the first dimension of any array is the columns, and
+so @code{interpn} effectively reverses the 'x' and 'y' dimensions. 
+Consider the example
+
+ at example
+ at group
+x = y = z = -1:1;
+f = @@(x,y,z) x.^2 - y - z.^2;
+[xx, yy, zz] = meshgrid (x, y, z);
+v = f (xx,yy,zz);
+xi = yi = zi = -1:0.1:1;
+[xxi, yyi, zzi] = meshgrid (xi, yi, zi);
+vi = interp3(x, y, z, v, xxi, yyi, zzi, 'spline');
+[xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+vi2 = interpn(x, y, z, v, xxi, yyi, zzi, 'spline');
+mesh (zi, yi, squeeze (vi2(1,:,:)));
+ at end group
+ at end example
+
+ at noindent
+where @code{vi} and @code{vi2} are identical.  The reversal of the
+dimensions is treated in the @code{meshgrid} and @code{ndgrid} functions
+respectively.
+ at ifnotinfo
+The result of this code can be seen in @ref{fig:interpn}.
+
+ at float Figure,fig:interpn
+ at center @image{interpn,4in}
+ at caption{Demonstration of the use of @code{interpn}}
+ at end float
+ at end ifnotinfo
+
+In additional the support function @code{bicubic} that underlies the
+cubic interpolation of @code{interp2} function can be called directly.
+
+ at c ./general/bicubic.m
+ at anchor{doc-bicubic}
+ at deftypefn {Function File} {@var{zi} =} bicubic (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{extrapval})
+
+Return a matrix @var{zi} corresponding to the bicubic
+interpolations at @var{xi} and @var{yi} of the data supplied
+as @var{x}, @var{y} and @var{z}.  Points outside the grid are set
+to @var{extrapval}.
+
+See @url{http://wiki.woodpecker.org.cn/moin/Octave/Bicubic}
+for further information.
+ at seealso{@ref{doc-interp2,,interp2}}
+ at end deftypefn
+
diff --git a/doc/interpreter/interp.txi b/doc/interpreter/interp.txi
new file mode 100644
index 0000000..c105209
--- /dev/null
+++ b/doc/interpreter/interp.txi
@@ -0,0 +1,193 @@
+ at c Copyright (C) 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Interpolation
+ at chapter Interpolation
+
+ at menu
+* One-dimensional Interpolation::
+* Multi-dimensional Interpolation::
+ at end menu
+
+ at node One-dimensional Interpolation
+ at section One-dimensional Interpolation
+
+Octave supports several methods for one-dimensional interpolation, most
+of which are described in this section.  @ref{Polynomial Interpolation}
+and @ref{Interpolation on Scattered Data} describe further methods.
+
+ at DOCSTRING(interp1)
+
+There are some important differences between the various interpolation
+methods.  The 'spline' method enforces that both the first and second
+derivatives of the interpolated values have a continuous derivative,
+whereas the other methods do not.  This means that the results of the
+'spline' method are generally smoother.  If the function to be
+interpolated is in fact smooth, then 'spline' will give excellent
+results.  However, if the function to be evaluated is in some manner
+discontinuous, then 'pchip' interpolation might give better results.
+
+This can be demonstrated by the code
+
+ at example
+ at group
+t = -2:2;
+dt = 1;
+ti =-2:0.025:2;
+dti = 0.025;
+y = sign(t);
+ys = interp1(t,y,ti,'spline');
+yp = interp1(t,y,ti,'pchip');
+ddys = diff(diff(ys)./dti)./dti;
+ddyp = diff(diff(yp)./dti)./dti;
+figure(1);
+plot (ti, ys,'r-', ti, yp,'g-');
+legend('spline','pchip',4);
+figure(2);
+plot (ti, ddys,'r+', ti, ddyp,'g*');
+legend('spline','pchip');
+ at end group
+ at end example
+
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:interpderiv1} and
+ at ref{fig:interpderiv2}.
+
+ at float Figure,fig:interpderiv1
+ at center @image{interpderiv1,4in}
+ at caption{Comparison of 'pchip' and 'spline' interpolation methods for a 
+step function}
+ at end float
+
+ at float Figure,fig:interpderiv2
+ at center @image{interpderiv2,4in}
+ at caption{Comparison of the second derivative of the 'pchip' and 'spline' 
+interpolation methods for a step function}
+ at end float
+ at end ifnotinfo
+
+A simplified version of @code{interp1} that performs only linear
+interpolation is available in @code{interp1q}.  This argument is slightly
+faster than @code{interp1} as to performs little error checking.
+
+ at DOCSTRING(interp1q)
+
+Fourier interpolation, is a resampling technique where a signal is
+converted to the frequency domain, padded with zeros and then
+reconverted to the time domain.
+
+ at DOCSTRING(interpft)
+
+There are two significant limitations on Fourier interpolation.  Firstly,
+the function signal is assumed to be periodic, and so non-periodic
+signals will be poorly represented at the edges.  Secondly, both the
+signal and its interpolation are required to be sampled at equispaced
+points.  An example of the use of @code{interpft} is
+
+ at example
+ at group
+t = 0 : 0.3 : pi; dt = t(2)-t(1);
+n = length (t); k = 100;
+ti = t(1) + [0 : k-1]*dt*n/k;
+y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
+plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ...
+      ti, interpft (y, k), 'c', t, y, 'r+');
+legend ('sin(4t+0.3)cos(3t-0.1','spline','interpft','data');
+ at end group
+ at end example
+
+ at noindent
+ at ifinfo
+which demonstrates the poor behavior of Fourier interpolation for non-periodic functions.
+ at end ifinfo
+ at ifnotinfo
+which demonstrates the poor behavior of Fourier interpolation for non-periodic functions, as can be seen in @ref{fig:interpft}.
+
+ at float Figure,fig:interpft
+ at center @image{interpft,4in}
+ at caption{Comparison of @code{interp1} and @code{interpft} for non-periodic data}
+ at end float
+ at end ifnotinfo
+
+In additional the support function @code{spline} and @code{lookup} that
+underlie the @code{interp1} function can be called directly.
+
+ at DOCSTRING(spline)
+
+The @code{lookup} function is used by other interpolation functions to identify
+the points of the original data that are closest to the current point
+of interest.
+
+ at DOCSTRING(lookup)
+
+ at node Multi-dimensional Interpolation
+ at section Multi-dimensional Interpolation
+
+There are three multi-dimensional interpolation functions in Octave, with
+similar capabilities.  Methods using Delaunay tessellation are described
+in @ref{Interpolation on Scattered Data}.
+
+ at DOCSTRING(interp2)
+
+ at DOCSTRING(interp3)
+
+ at DOCSTRING(interpn)
+
+A significant difference between @code{interpn} and the other two
+multidimensional interpolation functions is the fashion in which the
+dimensions are treated.  For @code{interp2} and @code{interp3}, the 'y'
+axis is considered to be the columns of the matrix, whereas the 'x'
+axis corresponds to the rows of the array.  As Octave indexes arrays in
+column major order, the first dimension of any array is the columns, and
+so @code{interpn} effectively reverses the 'x' and 'y' dimensions. 
+Consider the example
+
+ at example
+ at group
+x = y = z = -1:1;
+f = @@(x,y,z) x.^2 - y - z.^2;
+[xx, yy, zz] = meshgrid (x, y, z);
+v = f (xx,yy,zz);
+xi = yi = zi = -1:0.1:1;
+[xxi, yyi, zzi] = meshgrid (xi, yi, zi);
+vi = interp3(x, y, z, v, xxi, yyi, zzi, 'spline');
+[xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+vi2 = interpn(x, y, z, v, xxi, yyi, zzi, 'spline');
+mesh (zi, yi, squeeze (vi2(1,:,:)));
+ at end group
+ at end example
+
+ at noindent
+where @code{vi} and @code{vi2} are identical.  The reversal of the
+dimensions is treated in the @code{meshgrid} and @code{ndgrid} functions
+respectively.
+ at ifnotinfo
+The result of this code can be seen in @ref{fig:interpn}.
+
+ at float Figure,fig:interpn
+ at center @image{interpn,4in}
+ at caption{Demonstration of the use of @code{interpn}}
+ at end float
+ at end ifnotinfo
+
+In additional the support function @code{bicubic} that underlies the
+cubic interpolation of @code{interp2} function can be called directly.
+
+ at DOCSTRING(bicubic)
diff --git a/doc/interpreter/interpderiv1.eps b/doc/interpreter/interpderiv1.eps
new file mode 100644
index 0000000..69f0e64
--- /dev/null
+++ b/doc/interpreter/interpderiv1.eps
@@ -0,0 +1,1080 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: interpderiv1.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:54 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (interpderiv1.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:54 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2100 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2100 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3273 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3273 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4445 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4445 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5617 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5617 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6790 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6790 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2590 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2590 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3705 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3705 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4820 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4820 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5936 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5936 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+7051 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 7051 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8166 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8166 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+9281 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 9281 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+1.00 0.00 0.00 C LCb setrgbcolor
+9745 1201 M
+[ [(Helvetica) 120.0 0.0 true true 0 (spline)]
+] -40.0 MRshow
+LT0
+1.00 0.00 0.00 C 9829 1201 M
+399 0 V
+1475 2100 M
+56 -47 V
+56 -45 V
+55 -41 V
+56 -39 V
+56 -36 V
+56 -33 V
+55 -31 V
+56 -28 V
+56 -25 V
+56 -23 V
+55 -20 V
+56 -17 V
+56 -15 V
+56 -13 V
+55 -10 V
+56 -8 V
+56 -6 V
+56 -3 V
+55 -1 V
+56 2 V
+56 3 V
+56 6 V
+55 8 V
+56 10 V
+56 12 V
+56 14 V
+55 16 V
+56 17 V
+56 20 V
+56 22 V
+55 23 V
+56 26 V
+56 27 V
+56 29 V
+55 30 V
+56 32 V
+56 34 V
+56 35 V
+55 37 V
+56 38 V
+56 40 V
+56 41 V
+56 43 V
+55 44 V
+56 45 V
+56 47 V
+56 48 V
+55 49 V
+56 50 V
+56 51 V
+56 53 V
+55 53 V
+56 55 V
+56 55 V
+56 57 V
+55 57 V
+56 58 V
+56 60 V
+56 59 V
+55 61 V
+56 62 V
+56 62 V
+56 62 V
+55 64 V
+56 64 V
+56 64 V
+56 65 V
+55 66 V
+56 66 V
+56 66 V
+56 67 V
+55 67 V
+56 67 V
+56 68 V
+56 68 V
+55 68 V
+56 68 V
+56 68 V
+56 69 V
+56 68 V
+55 68 V
+56 69 V
+56 68 V
+56 68 V
+55 68 V
+56 68 V
+56 68 V
+56 67 V
+55 67 V
+56 67 V
+56 66 V
+56 66 V
+55 66 V
+56 65 V
+56 64 V
+56 64 V
+55 64 V
+56 62 V
+56 62 V
+56 62 V
+55 61 V
+56 59 V
+stroke 7162 5884 M
+56 60 V
+56 58 V
+55 57 V
+56 57 V
+56 55 V
+56 55 V
+55 53 V
+56 53 V
+56 51 V
+56 50 V
+55 49 V
+56 48 V
+56 47 V
+56 45 V
+55 44 V
+56 43 V
+56 41 V
+56 40 V
+56 38 V
+55 37 V
+56 35 V
+56 34 V
+56 32 V
+55 30 V
+56 29 V
+56 27 V
+56 26 V
+55 23 V
+56 22 V
+56 20 V
+56 17 V
+55 16 V
+56 14 V
+56 12 V
+56 10 V
+55 8 V
+56 6 V
+56 3 V
+56 2 V
+55 -1 V
+56 -3 V
+56 -6 V
+56 -8 V
+55 -10 V
+56 -13 V
+56 -15 V
+56 -17 V
+55 -20 V
+56 -23 V
+56 -25 V
+56 -28 V
+55 -31 V
+56 -33 V
+56 -36 V
+56 -39 V
+55 -41 V
+56 -45 V
+56 -47 V
+% End plot #1
+% Begin plot #2
+stroke
+LT1
+0.00 1.00 0.00 C LCb setrgbcolor
+9745 1061 M
+[ [(Helvetica) 120.0 0.0 true true 0 (pchip)]
+] -40.0 MRshow
+LT1
+0.00 1.00 0.00 C 9829 1061 M
+399 0 V
+1475 2100 M
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 3 V
+56 9 V
+56 14 V
+55 19 V
+56 24 V
+56 29 V
+56 33 V
+55 38 V
+56 42 V
+56 46 V
+56 49 V
+55 53 V
+56 56 V
+56 59 V
+56 62 V
+55 65 V
+56 66 V
+56 69 V
+56 71 V
+55 73 V
+56 74 V
+56 75 V
+56 76 V
+55 77 V
+56 78 V
+56 78 V
+56 78 V
+55 78 V
+56 78 V
+56 77 V
+56 76 V
+55 76 V
+56 74 V
+56 73 V
+56 72 V
+55 69 V
+56 68 V
+56 65 V
+56 63 V
+56 60 V
+55 60 V
+56 63 V
+56 65 V
+56 68 V
+55 69 V
+56 72 V
+56 73 V
+56 74 V
+55 76 V
+56 76 V
+56 77 V
+56 78 V
+55 78 V
+56 78 V
+56 78 V
+56 78 V
+55 77 V
+56 76 V
+56 75 V
+56 74 V
+55 73 V
+56 71 V
+stroke 7162 6054 M
+56 69 V
+56 66 V
+55 65 V
+56 62 V
+56 59 V
+56 56 V
+55 53 V
+56 49 V
+56 46 V
+56 42 V
+55 38 V
+56 33 V
+56 29 V
+56 24 V
+55 19 V
+56 14 V
+56 9 V
+56 3 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+56 0 V
+55 0 V
+56 0 V
+56 0 V
+% End plot #2
+stroke
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/interpderiv1.pdf b/doc/interpreter/interpderiv1.pdf
new file mode 100644
index 0000000..823eb6e
Binary files /dev/null and b/doc/interpreter/interpderiv1.pdf differ
diff --git a/doc/interpreter/interpderiv1.png b/doc/interpreter/interpderiv1.png
new file mode 100644
index 0000000..a65b6f3
Binary files /dev/null and b/doc/interpreter/interpderiv1.png differ
diff --git a/doc/interpreter/interpderiv1.txt b/doc/interpreter/interpderiv1.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/interpderiv1.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/interpderiv2.eps b/doc/interpreter/interpderiv2.eps
new file mode 100644
index 0000000..750da2b
--- /dev/null
+++ b/doc/interpreter/interpderiv2.eps
@@ -0,0 +1,1094 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: interpderiv2.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:54 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (interpderiv2.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:54 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 1807 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 1807 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-3)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2687 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2687 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3566 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3566 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4445 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4445 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5324 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5324 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6204 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6204 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7083 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7083 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2590 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2590 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3705 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3705 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4820 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4820 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5936 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5936 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+7051 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 7051 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8166 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8166 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+9281 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 9281 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+2.000 UP
+0.500 UL
+LT0
+1.00 0.00 0.00 C LCb setrgbcolor
+9745 7829 M
+[ [(Helvetica) 120.0 0.0 true true 0 (spline)]
+] -40.0 MRshow
+LT0
+1.00 0.00 0.00 C 1531 6182 Star
+1587 6160 Star
+1642 6138 Star
+1698 6116 Star
+1754 6094 Star
+1810 6072 Star
+1865 6050 Star
+1921 6028 Star
+1977 6006 Star
+2033 5984 Star
+2088 5962 Star
+2144 5940 Star
+2200 5918 Star
+2256 5896 Star
+2311 5874 Star
+2367 5852 Star
+2423 5830 Star
+2479 5808 Star
+2534 5786 Star
+2590 5764 Star
+2646 5742 Star
+2702 5720 Star
+2757 5698 Star
+2813 5676 Star
+2869 5654 Star
+2925 5632 Star
+2980 5610 Star
+3036 5588 Star
+3092 5566 Star
+3148 5544 Star
+3203 5522 Star
+3259 5500 Star
+3315 5478 Star
+3371 5456 Star
+3426 5434 Star
+3482 5412 Star
+3538 5390 Star
+3594 5368 Star
+3649 5346 Star
+3705 5324 Star
+3761 5302 Star
+3817 5280 Star
+3873 5258 Star
+3928 5236 Star
+3984 5214 Star
+4040 5192 Star
+4096 5170 Star
+4151 5148 Star
+4207 5126 Star
+4263 5104 Star
+4319 5082 Star
+4374 5060 Star
+4430 5038 Star
+4486 5017 Star
+4542 4995 Star
+4597 4973 Star
+4653 4951 Star
+4709 4929 Star
+4765 4907 Star
+4820 4885 Star
+4876 4863 Star
+4932 4841 Star
+4988 4819 Star
+5043 4797 Star
+5099 4775 Star
+5155 4753 Star
+5211 4731 Star
+5266 4709 Star
+5322 4687 Star
+5378 4665 Star
+5434 4643 Star
+5489 4621 Star
+5545 4599 Star
+5601 4577 Star
+5657 4555 Star
+5712 4533 Star
+5768 4511 Star
+5824 4489 Star
+5880 4467 Star
+5936 4445 Star
+5991 4423 Star
+6047 4401 Star
+6103 4379 Star
+6159 4357 Star
+6214 4335 Star
+6270 4313 Star
+6326 4291 Star
+6382 4269 Star
+6437 4247 Star
+6493 4225 Star
+6549 4203 Star
+6605 4181 Star
+6660 4159 Star
+6716 4137 Star
+6772 4115 Star
+6828 4093 Star
+6883 4071 Star
+6939 4049 Star
+6995 4027 Star
+7051 4005 Star
+7106 3983 Star
+7162 3961 Star
+7218 3939 Star
+7274 3917 Star
+7329 3895 Star
+7385 3873 Star
+7441 3852 Star
+7497 3830 Star
+7552 3808 Star
+7608 3786 Star
+7664 3764 Star
+7720 3742 Star
+7775 3720 Star
+7831 3698 Star
+7887 3676 Star
+7943 3654 Star
+7998 3632 Star
+8054 3610 Star
+8110 3588 Star
+8166 3566 Star
+8222 3544 Star
+8277 3522 Star
+8333 3500 Star
+8389 3478 Star
+8445 3456 Star
+8500 3434 Star
+8556 3412 Star
+8612 3390 Star
+8668 3368 Star
+8723 3346 Star
+8779 3324 Star
+8835 3302 Star
+8891 3280 Star
+8946 3258 Star
+9002 3236 Star
+9058 3214 Star
+9114 3192 Star
+9169 3170 Star
+9225 3148 Star
+9281 3126 Star
+9337 3104 Star
+9392 3082 Star
+9448 3060 Star
+9504 3038 Star
+9560 3016 Star
+9615 2994 Star
+9671 2972 Star
+9727 2950 Star
+9783 2928 Star
+9838 2906 Star
+9894 2884 Star
+9950 2862 Star
+10006 2840 Star
+10061 2818 Star
+10117 2796 Star
+10173 2774 Star
+10229 2752 Star
+10284 2730 Star
+10340 2708 Star
+10028 7829 Star
+% End plot #1
+% Begin plot #2
+2.000 UP
+0.500 UL
+LT1
+0.00 1.00 0.00 C LCb setrgbcolor
+9745 7689 M
+[ [(Helvetica) 120.0 0.0 true true 0 (pchip)]
+] -40.0 MRshow
+LT1
+0.00 1.00 0.00 C 1531 4445 Pls
+1587 4445 Pls
+1642 4445 Pls
+1698 4445 Pls
+1754 4445 Pls
+1810 4445 Pls
+1865 4445 Pls
+1921 4445 Pls
+1977 4445 Pls
+2033 4445 Pls
+2088 4445 Pls
+2144 4445 Pls
+2200 4445 Pls
+2256 4445 Pls
+2311 4445 Pls
+2367 4445 Pls
+2423 4445 Pls
+2479 4445 Pls
+2534 4445 Pls
+2590 4445 Pls
+2646 4445 Pls
+2702 4445 Pls
+2757 4445 Pls
+2813 4445 Pls
+2869 4445 Pls
+2925 4445 Pls
+2980 4445 Pls
+3036 4445 Pls
+3092 4445 Pls
+3148 4445 Pls
+3203 4445 Pls
+3259 4445 Pls
+3315 4445 Pls
+3371 4445 Pls
+3426 4445 Pls
+3482 4445 Pls
+3538 4445 Pls
+3594 4445 Pls
+3649 4445 Pls
+3705 6182 Pls
+3761 7830 Pls
+3817 7698 Pls
+3873 7566 Pls
+3928 7434 Pls
+3984 7303 Pls
+4040 7171 Pls
+4096 7039 Pls
+4151 6907 Pls
+4207 6775 Pls
+4263 6643 Pls
+4319 6511 Pls
+4374 6379 Pls
+4430 6247 Pls
+4486 6116 Pls
+4542 5984 Pls
+4597 5852 Pls
+4653 5720 Pls
+4709 5588 Pls
+4765 5456 Pls
+4820 5324 Pls
+4876 5192 Pls
+4932 5060 Pls
+4988 4929 Pls
+5043 4797 Pls
+5099 4665 Pls
+5155 4533 Pls
+5211 4401 Pls
+5266 4269 Pls
+5322 4137 Pls
+5378 4005 Pls
+5434 3873 Pls
+5489 3742 Pls
+5545 3610 Pls
+5601 3478 Pls
+5657 3346 Pls
+5712 3214 Pls
+5768 3082 Pls
+5824 2950 Pls
+5880 2818 Pls
+5936 4445 Pls
+5991 6072 Pls
+6047 5940 Pls
+6103 5808 Pls
+6159 5676 Pls
+6214 5544 Pls
+6270 5412 Pls
+6326 5280 Pls
+6382 5148 Pls
+6437 5017 Pls
+6493 4885 Pls
+6549 4753 Pls
+6605 4621 Pls
+6660 4489 Pls
+6716 4357 Pls
+6772 4225 Pls
+6828 4093 Pls
+6883 3961 Pls
+6939 3830 Pls
+6995 3698 Pls
+7051 3566 Pls
+7106 3434 Pls
+7162 3302 Pls
+7218 3170 Pls
+7274 3038 Pls
+7329 2906 Pls
+7385 2774 Pls
+7441 2643 Pls
+7497 2511 Pls
+7552 2379 Pls
+7608 2247 Pls
+7664 2115 Pls
+7720 1983 Pls
+7775 1851 Pls
+7831 1719 Pls
+7887 1587 Pls
+7943 1456 Pls
+7998 1324 Pls
+8054 1192 Pls
+8110 1060 Pls
+8166 2708 Pls
+8222 4445 Pls
+8277 4445 Pls
+8333 4445 Pls
+8389 4445 Pls
+8445 4445 Pls
+8500 4445 Pls
+8556 4445 Pls
+8612 4445 Pls
+8668 4445 Pls
+8723 4445 Pls
+8779 4445 Pls
+8835 4445 Pls
+8891 4445 Pls
+8946 4445 Pls
+9002 4445 Pls
+9058 4445 Pls
+9114 4445 Pls
+9169 4445 Pls
+9225 4445 Pls
+9281 4445 Pls
+9337 4445 Pls
+9392 4445 Pls
+9448 4445 Pls
+9504 4445 Pls
+9560 4445 Pls
+9615 4445 Pls
+9671 4445 Pls
+9727 4445 Pls
+9783 4445 Pls
+9838 4445 Pls
+9894 4445 Pls
+9950 4445 Pls
+10006 4445 Pls
+10061 4445 Pls
+10117 4445 Pls
+10173 4445 Pls
+10229 4445 Pls
+10284 4445 Pls
+10340 4445 Pls
+10028 7689 Pls
+% End plot #2
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/interpderiv2.pdf b/doc/interpreter/interpderiv2.pdf
new file mode 100644
index 0000000..df9c173
Binary files /dev/null and b/doc/interpreter/interpderiv2.pdf differ
diff --git a/doc/interpreter/interpderiv2.png b/doc/interpreter/interpderiv2.png
new file mode 100644
index 0000000..bb7826c
Binary files /dev/null and b/doc/interpreter/interpderiv2.png differ
diff --git a/doc/interpreter/interpderiv2.txt b/doc/interpreter/interpderiv2.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/interpderiv2.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/interpft.eps b/doc/interpreter/interpft.eps
new file mode 100644
index 0000000..3c9efb1
--- /dev/null
+++ b/doc/interpreter/interpft.eps
@@ -0,0 +1,1060 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: interpft.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:54 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (interpft.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:54 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2335 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2335 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3742 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3742 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5148 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5148 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6555 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6555 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2749 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2749 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4024 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 4024 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5298 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5298 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6573 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6573 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+7847 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 7847 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+9122 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 9122 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (3.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 1.00 0.00 C LCb setrgbcolor
+9745 7829 M
+[ [(Helvetica) 120.0 0.0 true true 0 (sin\(4t+0.3\)cos\(3t-0.1\))]
+] -40.0 MRshow
+LT0
+0.00 1.00 0.00 C 9829 7829 M
+399 0 V
+1475 4569 M
+84 351 V
+84 318 V
+84 273 V
+84 213 V
+85 145 V
+84 71 V
+84 -4 V
+84 -78 V
+84 -145 V
+84 -203 V
+84 -248 V
+84 -278 V
+84 -292 V
+85 -288 V
+84 -268 V
+84 -232 V
+84 -182 V
+84 -121 V
+84 -52 V
+84 21 V
+84 94 V
+84 163 V
+85 224 V
+84 275 V
+84 312 V
+84 334 V
+84 337 V
+84 325 V
+84 295 V
+84 250 V
+84 193 V
+85 126 V
+84 52 V
+84 -25 V
+84 -99 V
+84 -168 V
+84 -229 V
+84 -278 V
+84 -311 V
+84 -329 V
+85 -329 V
+84 -312 V
+84 -280 V
+84 -232 V
+84 -174 V
+84 -106 V
+84 -34 V
+84 39 V
+85 109 V
+84 173 V
+84 226 V
+84 265 V
+84 291 V
+84 298 V
+84 289 V
+84 263 V
+84 221 V
+85 167 V
+84 101 V
+84 29 V
+84 -47 V
+84 -121 V
+84 -192 V
+84 -253 V
+84 -304 V
+84 -341 V
+85 -360 V
+84 -363 V
+84 -350 V
+84 -319 V
+84 -273 V
+84 -216 V
+84 -149 V
+84 -77 V
+84 -2 V
+85 70 V
+84 135 V
+84 193 V
+84 236 V
+84 265 V
+84 277 V
+84 273 V
+84 251 V
+84 214 V
+85 163 V
+84 101 V
+84 30 V
+84 -43 V
+84 -118 V
+84 -187 V
+84 -251 V
+84 -301 V
+84 -340 V
+85 -362 V
+84 -367 V
+84 -355 V
+84 -327 V
+84 -282 V
+84 -226 V
+% End plot #1
+% Begin plot #2
+stroke
+LT1
+0.00 0.00 1.00 C LCb setrgbcolor
+9745 7689 M
+[ [(Helvetica) 120.0 0.0 true true 0 (spline)]
+] -40.0 MRshow
+LT1
+0.00 0.00 1.00 C 9829 7689 M
+399 0 V
+1475 4569 M
+84 602 V
+84 452 V
+84 314 V
+84 191 V
+85 82 V
+84 -14 V
+84 -96 V
+84 -163 V
+84 -218 V
+84 -258 V
+84 -285 V
+84 -298 V
+84 -297 V
+85 -282 V
+84 -254 V
+84 -211 V
+84 -155 V
+84 -85 V
+84 -4 V
+84 72 V
+84 138 V
+84 190 V
+85 232 V
+84 261 V
+84 279 V
+84 285 V
+84 279 V
+84 262 V
+84 236 V
+84 205 V
+84 167 V
+85 123 V
+84 72 V
+84 15 V
+84 -47 V
+84 -117 V
+84 -191 V
+84 -257 V
+84 -303 V
+84 -330 V
+85 -337 V
+84 -327 V
+84 -295 V
+84 -246 V
+84 -177 V
+84 -89 V
+84 0 V
+84 77 V
+85 139 V
+84 189 V
+84 225 V
+84 247 V
+84 256 V
+84 251 V
+84 234 V
+84 206 V
+84 173 V
+85 134 V
+84 90 V
+84 41 V
+84 -13 V
+84 -74 V
+84 -139 V
+84 -210 V
+84 -277 V
+84 -325 V
+85 -356 V
+84 -367 V
+84 -361 V
+84 -335 V
+84 -291 V
+84 -228 V
+84 -147 V
+84 -57 V
+84 23 V
+85 90 V
+84 147 V
+84 191 V
+84 224 V
+84 244 V
+84 253 V
+84 249 V
+84 235 V
+84 208 V
+85 170 V
+84 119 V
+84 57 V
+84 -17 V
+84 -104 V
+84 -201 V
+% End plot #2
+% Begin plot #3
+stroke
+LT2
+0.00 1.00 1.00 C LCb setrgbcolor
+9745 7549 M
+[ [(Helvetica) 120.0 0.0 true true 0 (interpft)]
+] -40.0 MRshow
+LT2
+0.00 1.00 1.00 C 9829 7549 M
+399 0 V
+1475 4569 M
+84 192 V
+84 208 V
+84 210 V
+84 198 V
+85 170 V
+84 129 V
+84 75 V
+84 11 V
+84 -57 V
+84 -124 V
+84 -187 V
+84 -239 V
+84 -277 V
+85 -297 V
+84 -295 V
+84 -274 V
+84 -231 V
+84 -171 V
+84 -97 V
+84 -15 V
+84 71 V
+84 154 V
+85 229 V
+84 291 V
+84 335 V
+84 360 V
+84 364 V
+84 348 V
+84 312 V
+84 260 V
+84 195 V
+85 121 V
+84 43 V
+84 -35 V
+84 -110 V
+84 -176 V
+84 -234 V
+84 -277 V
+84 -309 V
+84 -323 V
+85 -324 V
+84 -308 V
+84 -279 V
+84 -235 V
+84 -182 V
+84 -118 V
+84 -49 V
+84 25 V
+85 97 V
+84 164 V
+84 225 V
+84 273 V
+84 305 V
+84 320 V
+84 315 V
+84 291 V
+84 248 V
+85 186 V
+84 113 V
+84 28 V
+84 -59 V
+84 -147 V
+84 -226 V
+84 -293 V
+84 -346 V
+84 -377 V
+85 -389 V
+84 -379 V
+84 -349 V
+84 -301 V
+84 -240 V
+84 -170 V
+84 -94 V
+84 -19 V
+84 50 V
+85 111 V
+84 159 V
+84 196 V
+84 215 V
+84 221 V
+84 214 V
+84 193 V
+84 164 V
+84 128 V
+85 88 V
+84 47 V
+84 8 V
+84 -27 V
+84 -55 V
+84 -75 V
+84 -85 V
+84 -86 V
+84 -76 V
+85 -56 V
+84 -28 V
+84 8 V
+84 48 V
+84 89 V
+84 130 V
+% End plot #3
+% Begin plot #4
+2.000 UP
+stroke
+LT3
+1.00 0.00 0.00 C LCb setrgbcolor
+9745 7409 M
+[ [(Helvetica) 120.0 0.0 true true 0 (data)]
+] -40.0 MRshow
+LT3
+1.00 0.00 0.00 C 1475 4569 Pls
+2240 5697 Pls
+3004 3587 Pls
+3769 5400 Pls
+4534 6181 Pls
+5298 3727 Pls
+6063 5205 Pls
+6828 5600 Pls
+7592 2860 Pls
+8357 4149 Pls
+9122 4383 Pls
+10028 7409 Pls
+% End plot #4
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/interpft.pdf b/doc/interpreter/interpft.pdf
new file mode 100644
index 0000000..a09fde8
Binary files /dev/null and b/doc/interpreter/interpft.pdf differ
diff --git a/doc/interpreter/interpft.png b/doc/interpreter/interpft.png
new file mode 100644
index 0000000..23d6304
Binary files /dev/null and b/doc/interpreter/interpft.png differ
diff --git a/doc/interpreter/interpft.txt b/doc/interpreter/interpft.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/interpft.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/interpimages.m b/doc/interpreter/interpimages.m
new file mode 100644
index 0000000..2dab76e
--- /dev/null
+++ b/doc/interpreter/interpimages.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2007, 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+function interpimages (nm, typ)
+  bury_output ();
+  if (strcmp (typ, "png"))
+    set (0, "defaulttextfontname", "*");
+  endif
+  if (strcmp (typ, "txt"))
+    image_as_txt (nm);
+  elseif (strcmp (nm, "interpft"))
+    t = 0 : 0.3 : pi; dt = t(2)-t(1);
+    n = length (t); k = 100;
+    ti = t(1) + [0 : k-1]*dt*n/k;
+    y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+    yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
+    plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ...
+	  ti, interpft (y, k), 'c', t, y, 'r+');
+    legend ('sin(4t+0.3)cos(3t-0.1)','spline','interpft','data');
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))
+  elseif (strcmp (nm, "interpn"))
+    x = y = z = -1:1;
+    f = @(x,y,z) x.^2 - y - z.^2;
+    [xx, yy, zz] = meshgrid (x, y, z);
+    v = f (xx,yy,zz);
+    xi = yi = zi = -1:0.1:1;
+    [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+    vi = interpn(x, y, z, v, xxi, yyi, zzi, 'spline');
+    mesh (zi, yi, squeeze (vi(1,:,:)));
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))
+  elseif (strcmp (nm, "interpderiv1"))
+    t = -2:2;
+    dt = 1;
+    ti =-2:0.025:2;
+    dti = 0.025;
+    y = sign(t);
+    ys = interp1(t,y,ti,'spline');
+    yp = interp1(t,y,ti,'pchip');
+    plot (ti, ys,'r-', ti, yp,'g-');
+    legend('spline','pchip', 4);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))
+  elseif (strcmp (nm, "interpderiv2"))
+    t = -2:2;
+    dt = 1;
+    ti =-2:0.025:2;
+    dti = 0.025;
+    y = sign(t);
+    ddys = diff(diff(interp1(t,y,ti,'spline'))./dti)./dti;
+    ddyp = diff(diff(interp1(t,y,ti,'pchip'))./dti)./dti;
+    plot (ti(2:end-1),ddys,'r*', ti(2:end-1),ddyp,'g+');
+    legend('spline','pchip');
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))
+  endif
+  bury_output ();  
+endfunction
+
+## Use this function before plotting commands and after every call to
+## print since print() resets output to stdout (unfortunately, gnpulot
+## can't pop output as it can the terminal type).
+function bury_output ()
+  f = figure (1);
+  set (f, "visible", "off");
+endfunction
+
+## generate something for the texinfo @image command to process
+function image_as_txt(nm)
+  fid = fopen (sprintf ("%s.txt", nm), "wt");
+  fputs (fid, "\n");
+  fputs (fid, "+---------------------------------+\n");
+  fputs (fid, "| Image unavailable in text mode. |\n");
+  fputs (fid, "+---------------------------------+\n");
+  fclose (fid);
+endfunction
diff --git a/doc/interpreter/interpn.eps b/doc/interpreter/interpn.eps
new file mode 100644
index 0000000..43aa247
--- /dev/null
+++ b/doc/interpreter/interpn.eps
@@ -0,0 +1,3781 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: interpn.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:54 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (interpn.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:54 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1.000 UP
+1.000 UL
+LT0
+.4675 g 6710 5746 M
+-192 259 V
+stroke
+LT0
+.5325 g 6268 6108 M
+250 -103 V
+stroke
+LT0
+.4031 g 6902 5490 M
+-192 256 V
+stroke
+LT0
+.4675 g 6460 5849 M
+250 -103 V
+stroke
+LT0
+.3401 g 7094 5238 M
+-192 252 V
+stroke
+LT0
+.4036 g 6652 5593 M
+250 -103 V
+stroke
+LT0
+.2795 g 7286 4995 M
+-192 243 V
+stroke
+LT0
+.3416 g 6844 5341 M
+250 -103 V
+stroke
+LT0
+.5325 g 6460 5849 M
+-192 259 V
+stroke
+LT0
+.5969 g 6017 6209 M
+251 -101 V
+stroke
+LT0
+.2238 g 7468 4773 M
+-182 222 V
+stroke
+LT0
+.2825 g 7036 5098 M
+250 -103 V
+stroke
+LT0
+.468 g 6652 5593 M
+-192 256 V
+stroke
+LT0
+.532 g 6209 5950 M
+251 -101 V
+stroke
+LT0
+.23 g 7228 4864 M
+229 -94 V
+stroke
+LT0
+.405 g 6844 5341 M
+-192 252 V
+stroke
+LT0
+.468 g 6401 5693 M
+251 -100 V
+stroke
+LT0
+.3445 g 7036 5098 M
+-192 243 V
+stroke
+LT0
+.406 g 6593 5442 M
+251 -101 V
+stroke
+LT0
+.5964 g 6209 5950 M
+-192 259 V
+stroke
+LT0
+.6599 g 5768 6304 M
+249 -95 V
+stroke
+LT0
+.2874 g 7228 4864 M
+-192 234 V
+stroke
+LT0
+.3469 g 6785 5198 M
+251 -100 V
+stroke
+LT0
+.532 g 6401 5693 M
+-192 257 V
+stroke
+LT0
+.595 g 5959 6045 M
+250 -95 V
+stroke
+LT0
+.2452 g 7339 4737 M
+-111 127 V
+stroke
+LT0
+.2917 g 6977 4965 M
+251 -101 V
+stroke
+LT0
+.469 g 6593 5442 M
+-192 251 V
+stroke
+LT0
+.531 g 6151 5789 M
+250 -96 V
+stroke
+LT0
+.2615 g 7169 4744 M
+94 -37 V
+stroke
+LT0
+.4084 g 6785 5198 M
+-192 244 V
+stroke
+LT0
+.469 g 6343 5537 M
+250 -95 V
+stroke
+LT0
+.6584 g 5959 6045 M
+-191 259 V
+stroke
+LT0
+.7205 g 5518 6392 M
+250 -88 V
+stroke
+LT0
+.3513 g 6977 4965 M
+-192 233 V
+stroke
+LT0
+.4099 g 6535 5294 M
+250 -96 V
+stroke
+LT0
+.594 g 6151 5789 M
+-192 256 V
+stroke
+LT0
+.6555 g 5710 6133 M
+249 -88 V
+stroke
+LT0
+.2986 g 7169 4744 M
+-192 221 V
+stroke
+LT0
+.3547 g 6727 5060 M
+250 -95 V
+stroke
+LT0
+.531 g 6343 5537 M
+-192 252 V
+stroke
+LT0
+.5916 g 5902 5877 M
+249 -88 V
+stroke
+LT0
+.2676 g 7220 4690 M
+-51 54 V
+stroke
+LT0
+.3044 g 6919 4840 M
+250 -96 V
+stroke
+LT0
+.4705 g 6535 5294 M
+-192 243 V
+stroke
+LT0
+.5295 g 6093 5625 M
+250 -88 V
+stroke
+LT0
+.7175 g 5710 6133 M
+-192 259 V
+stroke
+LT0
+.7776 g 5267 6470 M
+251 -78 V
+stroke
+LT0
+.4133 g 6727 5060 M
+-192 234 V
+stroke
+LT0
+.4705 g 6285 5381 M
+250 -87 V
+stroke
+LT0
+.6531 g 5902 5877 M
+-192 256 V
+stroke
+LT0
+.7126 g 5460 6210 M
+250 -77 V
+stroke
+LT0
+.3606 g 6919 4840 M
+-192 220 V
+stroke
+LT0
+.4153 g 6477 5148 M
+250 -88 V
+stroke
+LT0
+.5901 g 6093 5625 M
+-191 252 V
+stroke
+LT0
+.6487 g 5652 5954 M
+250 -77 V
+stroke
+LT0
+.5295 g 6285 5381 M
+-192 244 V
+stroke
+LT0
+.5867 g 5844 5703 M
+249 -78 V
+stroke
+LT0
+.3143 g 7102 4644 M
+-183 196 V
+stroke
+LT0
+.365 g 6669 4927 M
+250 -87 V
+stroke
+LT0
+.7727 g 5460 6210 M
+-193 260 V
+stroke
+LT0
+.8303 g 5017 6534 M
+250 -64 V
+stroke
+LT1
+.0056 g 9014 3573 M
+-192 59 V
+stroke
+LT1
+.0325 g 8572 3735 M
+250 -103 V
+stroke
+LT0
+.4724 g 6477 5148 M
+-192 233 V
+stroke
+LT0
+.5276 g 6035 5459 M
+250 -78 V
+stroke
+LT0
+.7083 g 5652 5954 M
+-192 256 V
+stroke
+LT0
+.7654 g 5209 6275 M
+251 -65 V
+stroke
+LT0
+.3225 g 6861 4722 M
+234 -82 V
+stroke
+LT0
+.4197 g 6669 4927 M
+-192 221 V
+stroke
+LT0
+.4724 g 6227 5225 M
+250 -77 V
+stroke
+LT0
+.6453 g 5844 5703 M
+-192 251 V
+stroke
+LT0
+.7014 g 5401 6019 M
+251 -65 V
+stroke
+LT0
+.5847 g 6035 5459 M
+-191 244 V
+stroke
+LT0
+.6394 g 5593 5767 M
+251 -64 V
+stroke
+LT0
+.3723 g 6861 4722 M
+-192 205 V
+stroke
+LT0
+.4221 g 6419 5005 M
+250 -78 V
+stroke
+LT0
+.823 g 5209 6275 M
+-192 259 V
+stroke
+LT0
+.8777 g 4767 6583 M
+250 -49 V
+stroke
+LT1
+.0232 g 9206 3548 M
+-192 25 V
+stroke
+LT1
+.0437 g 8764 3676 M
+250 -103 V
+stroke
+LT0
+.5276 g 6227 5225 M
+-192 234 V
+stroke
+LT0
+.5803 g 5785 5523 M
+250 -64 V
+stroke
+LT1
+.0706 g 8764 3676 M
+-192 59 V
+stroke
+LT1
+.0969 g 8322 3835 M
+250 -100 V
+stroke
+LT0
+.7585 g 5401 6019 M
+-192 256 V
+stroke
+LT0
+.8127 g 4959 6324 M
+250 -49 V
+stroke
+LT0
+.3368 g 6997 4589 M
+-136 133 V
+stroke
+LT0
+.3777 g 6611 4800 M
+250 -78 V
+stroke
+LT0
+.4749 g 6419 5005 M
+-192 220 V
+stroke
+LT0
+.5251 g 5976 5290 M
+251 -65 V
+stroke
+LT0
+.6956 g 5593 5767 M
+-192 252 V
+stroke
+LT0
+.7488 g 5151 6068 M
+250 -49 V
+stroke
+LT0
+.3511 g 6803 4613 M
+150 -47 V
+stroke
+LT0
+.635 g 5785 5523 M
+-192 244 V
+stroke
+LT0
+.6868 g 5343 5816 M
+250 -49 V
+stroke
+LT0
+.4275 g 6611 4800 M
+-192 205 V
+stroke
+LT0
+.4749 g 6168 5069 M
+251 -64 V
+stroke
+LT0
+.8674 g 4959 6324 M
+-192 259 V
+stroke
+LT0
+.9187 g 4517 6615 M
+250 -32 V
+stroke
+LT1
+.054 g 9398 3558 M
+-192 -10 V
+stroke
+LT1
+.0676 g 8956 3651 M
+250 -103 V
+stroke
+LT1
+.0881 g 8956 3651 M
+-192 25 V
+stroke
+LT1
+.1082 g 8514 3777 M
+250 -101 V
+stroke
+LT0
+.5779 g 5976 5290 M
+-191 233 V
+stroke
+LT0
+.6277 g 5535 5573 M
+250 -50 V
+stroke
+LT0
+.803 g 5151 6068 M
+-192 256 V
+stroke
+LT0
+.8538 g 4709 6355 M
+250 -31 V
+stroke
+LT1
+.1345 g 8514 3777 M
+-192 58 V
+stroke
+LT1
+.1599 g 8071 3931 M
+251 -96 V
+stroke
+LT0
+.3865 g 6803 4613 M
+-192 187 V
+stroke
+LT0
+.4304 g 6360 4864 M
+251 -64 V
+stroke
+LT0
+.74 g 5343 5816 M
+-192 252 V
+stroke
+LT0
+.7898 g 4901 6099 M
+250 -31 V
+stroke
+LT0
+.5251 g 6168 5069 M
+-192 221 V
+stroke
+LT0
+.5725 g 5727 5339 M
+249 -49 V
+stroke
+LT0
+.6794 g 5535 5573 M
+-192 243 V
+stroke
+LT0
+.7278 g 5093 5847 M
+250 -31 V
+stroke
+LT0
+.905 g 4709 6355 M
+-192 260 V
+stroke
+LT0
+.9524 g 4266 6625 M
+251 -10 V
+stroke
+LT0
+.3607 g 6893 4535 M
+-90 78 V
+stroke
+LT0
+.3928 g 6552 4677 M
+251 -64 V
+stroke
+LT0
+.4778 g 6360 4864 M
+-192 205 V
+stroke
+LT0
+.5222 g 5919 5119 M
+249 -50 V
+stroke
+LT1
+.0989 g 9590 3608 M
+-192 -50 V
+stroke
+LT1
+.1052 g 9148 3662 M
+250 -104 V
+stroke
+LT1
+.1189 g 9148 3662 M
+-192 -11 V
+stroke
+LT1
+.1321 g 8706 3751 M
+250 -100 V
+stroke
+LT0
+.8406 g 4901 6099 M
+-192 256 V
+stroke
+LT0
+.8875 g 4458 6366 M
+251 -11 V
+stroke
+LT0
+.6223 g 5727 5339 M
+-192 234 V
+stroke
+LT0
+.6687 g 5285 5604 M
+250 -31 V
+stroke
+LT1
+.1521 g 8706 3751 M
+-192 26 V
+stroke
+LT1
+.1711 g 8263 3872 M
+251 -95 V
+stroke
+LT0
+.4368 g 6552 4677 M
+-192 187 V
+stroke
+LT0
+.4778 g 6110 4913 M
+250 -49 V
+stroke
+LT0
+.7776 g 5093 5847 M
+-192 252 V
+stroke
+LT0
+.8235 g 4650 6110 M
+251 -11 V
+stroke
+LT0
+.3807 g 6745 4510 M
+74 -19 V
+stroke
+LT1
+.1965 g 8263 3872 M
+-192 59 V
+stroke
+LT1
+.2205 g 7821 4019 M
+250 -88 V
+stroke
+LT0
+.5696 g 5919 5119 M
+-192 220 V
+stroke
+LT0
+.6135 g 5477 5370 M
+250 -31 V
+stroke
+LT0
+.9348 g 4458 6366 M
+-192 259 V
+stroke
+LT0
+.9778 g 4016 6613 M
+250 12 V
+stroke
+LT0
+.717 g 5285 5604 M
+-192 243 V
+stroke
+LT0
+.7615 g 4843 5858 M
+250 -11 V
+stroke
+LT0
+.4031 g 6745 4510 M
+-193 167 V
+stroke
+LT0
+.4402 g 6302 4726 M
+250 -49 V
+stroke
+LT0
+.5222 g 6110 4913 M
+-191 206 V
+stroke
+LT0
+.5632 g 5669 5150 M
+250 -31 V
+stroke
+LT0
+.8704 g 4650 6110 M
+-192 256 V
+stroke
+LT0
+.9128 g 4208 6354 M
+250 12 V
+stroke
+LT0
+.6599 g 5477 5370 M
+-192 234 V
+stroke
+LT0
+.7024 g 5035 5614 M
+250 -10 V
+stroke
+LT1
+.1638 g 9340 3711 M
+-192 -49 V
+stroke
+LT1
+.1697 g 8898 3762 M
+250 -100 V
+stroke
+LT1
+.1829 g 8898 3762 M
+-192 -11 V
+stroke
+LT1
+.1951 g 8455 3847 M
+251 -96 V
+stroke
+LT0
+.8074 g 4843 5858 M
+-193 252 V
+stroke
+LT0
+.8489 g 4400 6097 M
+250 13 V
+stroke
+LT1
+.1589 g 9782 3698 M
+-192 -90 V
+stroke
+LT1
+.1575 g 9340 3711 M
+250 -103 V
+stroke
+LT1
+.2141 g 8455 3847 M
+-192 25 V
+stroke
+LT1
+.2317 g 8013 3960 M
+250 -88 V
+stroke
+LT0
+.4812 g 6302 4726 M
+-192 187 V
+stroke
+LT0
+.5188 g 5861 4945 M
+249 -32 V
+stroke
+LT0
+.6072 g 5669 5150 M
+-192 220 V
+stroke
+LT0
+.6472 g 5227 5381 M
+250 -11 V
+stroke
+LT0
+.3855 g 6793 4474 M
+-48 36 V
+stroke
+LT0
+.4104 g 6494 4560 M
+251 -50 V
+stroke
+LT0
+.9558 g 4208 6354 M
+-192 259 V
+stroke
+LT0
+.9939 g 3766 6575 M
+250 38 V
+stroke
+LT0
+.7468 g 5035 5614 M
+-192 244 V
+stroke
+LT0
+.7869 g 4592 5846 M
+251 12 V
+stroke
+LT0
+.8914 g 4400 6097 M
+-192 257 V
+stroke
+LT0
+.929 g 3958 6315 M
+250 39 V
+stroke
+LT0
+.5598 g 5861 4945 M
+-192 205 V
+stroke
+LT0
+.5969 g 5419 5160 M
+250 -10 V
+stroke
+LT0
+.4475 g 6494 4560 M
+-192 166 V
+stroke
+LT0
+.4812 g 6052 4757 M
+250 -31 V
+stroke
+LT0
+.6897 g 5227 5381 M
+-192 233 V
+stroke
+LT0
+.7278 g 4784 5602 M
+251 12 V
+stroke
+LT0
+.8284 g 4592 5846 M
+-192 251 V
+stroke
+LT0
+.865 g 4150 6059 M
+250 38 V
+stroke
+LT0
+.4102 g 6686 4417 M
+16 -3 V
+stroke
+LT0
+.967 g 3958 6315 M
+-192 260 V
+stroke
+LT0
+.9998 g 3516 6508 M
+250 67 V
+stroke
+LT0
+.5188 g 6052 4757 M
+-191 188 V
+stroke
+LT0
+.5525 g 5611 4955 M
+250 -10 V
+stroke
+LT0
+.637 g 5419 5160 M
+-192 221 V
+stroke
+LT0
+.6726 g 4976 5369 M
+251 12 V
+stroke
+LT1
+.2278 g 9090 3811 M
+-192 -49 V
+stroke
+LT1
+.2327 g 8648 3858 M
+250 -96 V
+stroke
+LT1
+.2449 g 8648 3858 M
+-193 -11 V
+stroke
+LT1
+.2556 g 8205 3935 M
+250 -88 V
+stroke
+LT0
+.7678 g 4784 5602 M
+-192 244 V
+stroke
+LT0
+.803 g 4342 5807 M
+250 39 V
+stroke
+LT1
+.2239 g 9532 3801 M
+-192 -90 V
+stroke
+LT1
+.2219 g 9090 3811 M
+250 -100 V
+stroke
+LT1
+.2735 g 8205 3935 M
+-187 24 V
+stroke
+LT1
+.2888 g 7763 4037 M
+250 -77 V
+stroke
+LT0
+.4221 g 6686 4417 M
+-192 143 V
+stroke
+LT0
+.4514 g 6244 4591 M
+250 -31 V
+stroke
+LT0
+.9026 g 4150 6059 M
+-192 256 V
+stroke
+LT0
+.9348 g 3708 6249 M
+250 66 V
+stroke
+LT1
+.2351 g 9974 3832 M
+9782 3698 L
+stroke
+LT1
+.2253 g 9532 3801 M
+250 -103 V
+stroke
+LT0
+.5896 g 5611 4955 M
+-192 205 V
+stroke
+LT0
+.6223 g 5168 5148 M
+251 12 V
+stroke
+LT0
+.7107 g 4976 5369 M
+-192 233 V
+stroke
+LT0
+.7439 g 4534 5564 M
+250 38 V
+stroke
+LT0
+.8396 g 4342 5807 M
+-192 252 V
+stroke
+LT0
+.8708 g 3900 5992 M
+250 67 V
+stroke
+LT0
+.4851 g 6244 4591 M
+-192 166 V
+stroke
+LT0
+.5149 g 5803 4768 M
+249 -11 V
+stroke
+LT0
+.9675 g 3708 6249 M
+-192 259 V
+stroke
+LT0
+.9944 g 3265 6411 M
+251 97 V
+stroke
+LT0
+.658 g 5168 5148 M
+-192 221 V
+stroke
+LT0
+.6887 g 4726 5330 M
+250 39 V
+stroke
+LT0
+.4113 g 6697 4411 M
+-11 6 V
+stroke
+LT0
+.4304 g 6436 4447 M
+250 -30 V
+stroke
+LT0
+.7791 g 4534 5564 M
+-192 243 V
+stroke
+LT0
+.8088 g 4092 5741 M
+250 66 V
+stroke
+LT0
+.9031 g 3900 5992 M
+-192 257 V
+stroke
+LT0
+.9294 g 3457 6152 M
+251 97 V
+stroke
+LT0
+.5486 g 5803 4768 M
+-192 187 V
+stroke
+LT0
+.5779 g 5360 4943 M
+251 12 V
+stroke
+LT0
+.9563 g 3457 6152 M
+-192 259 V
+stroke
+LT0
+.9768 g 3015 6280 M
+250 131 V
+stroke
+LT0
+.4597 g 6436 4447 M
+-192 144 V
+stroke
+LT0
+.4851 g 5994 4601 M
+250 -10 V
+stroke
+LT0
+.8401 g 4092 5741 M
+-192 251 V
+stroke
+LT0
+.8655 g 3649 5895 M
+251 97 V
+stroke
+LT0
+.7219 g 4726 5330 M
+-192 234 V
+stroke
+LT0
+.7498 g 4284 5497 M
+250 67 V
+stroke
+LT1
+.304 g 8397 3945 M
+-192 -10 V
+stroke
+LT1
+.3127 g 7955 4012 M
+250 -77 V
+stroke
+LT1
+.2898 g 8840 3907 M
+-192 -49 V
+stroke
+LT1
+.2932 g 8397 3945 M
+251 -87 V
+stroke
+LT0
+.6106 g 5360 4943 M
+-192 205 V
+stroke
+LT0
+.6384 g 4918 5110 M
+250 38 V
+stroke
+LT1
+.3284 g 7955 4012 M
+-192 25 V
+stroke
+LT1
+.3416 g 7513 4102 M
+250 -65 V
+stroke
+LT1
+.2878 g 9282 3902 M
+-192 -91 V
+stroke
+LT1
+.2849 g 8840 3907 M
+250 -96 V
+stroke
+LT0
+.8918 g 3649 5895 M
+-192 257 V
+stroke
+LT0
+.9119 g 3207 6021 M
+250 131 V
+stroke
+LT0
+.5149 g 5994 4601 M
+-191 167 V
+stroke
+LT0
+.5403 g 5552 4756 M
+251 12 V
+stroke
+LT0
+.7795 g 4284 5497 M
+-192 244 V
+stroke
+LT0
+.8035 g 3841 5644 M
+251 97 V
+stroke
+LT0
+.4675 g 1706 4393 M
+-192 258 V
+stroke
+LT0
+.5603 g 1764 5036 M
+1514 4651 L
+stroke
+LT1
+.3 g 9724 3935 M
+9532 3801 L
+stroke
+LT1
+.2898 g 9282 3902 M
+250 -101 V
+stroke
+LT0
+.9324 g 3207 6021 M
+-192 259 V
+stroke
+LT0
+.946 g 2765 6114 M
+250 166 V
+stroke
+LT0
+.6692 g 4918 5110 M
+-192 220 V
+stroke
+LT0
+.6946 g 4476 5264 M
+250 66 V
+stroke
+LT0
+.8289 g 3841 5644 M
+-192 251 V
+stroke
+LT0
+.8479 g 3399 5764 M
+250 131 V
+stroke
+LT0
+.5696 g 5552 4756 M
+-192 187 V
+stroke
+LT0
+.594 g 5110 4905 M
+250 38 V
+stroke
+LT0
+.4444 g 6602 4347 M
+-166 100 V
+stroke
+LT0
+.4641 g 6186 4458 M
+250 -11 V
+stroke
+LT0
+.7224 g 4476 5264 M
+-192 233 V
+stroke
+LT0
+.7444 g 4034 5400 M
+250 97 V
+stroke
+LT0
+.4031 g 1898 4136 M
+-192 257 V
+stroke
+LT0
+.4954 g 1956 4777 M
+1706 4393 L
+stroke
+LT0
+.8679 g 3399 5764 M
+-192 257 V
+stroke
+LT0
+.8811 g 2957 5854 M
+250 167 V
+stroke
+LT0
+.8948 g 2957 5854 M
+-192 260 V
+stroke
+LT0
+.9011 g 2515 5908 M
+250 206 V
+stroke
+LT0
+.5881 g 1956 4777 M
+-192 259 V
+stroke
+LT0
+.6716 g 2014 5372 M
+1764 5036 L
+stroke
+LT1
+.3284 g 10166 4012 M
+9974 3832 L
+stroke
+LT1
+.3098 g 9724 3935 M
+250 -103 V
+stroke
+LT0
+.6218 g 5110 4905 M
+-192 205 V
+stroke
+LT0
+.6443 g 4668 5043 M
+250 67 V
+stroke
+LT0
+.4895 g 6186 4458 M
+-192 143 V
+stroke
+LT0
+.5105 g 5744 4589 M
+250 12 V
+stroke
+LT0
+.7683 g 4034 5400 M
+-193 244 V
+stroke
+LT0
+.7859 g 3591 5513 M
+250 131 V
+stroke
+LT0
+.8425 g 2707 5649 M
+-192 259 V
+stroke
+LT0
+.8411 g 2264 5662 M
+251 246 V
+stroke
+LT0
+.6902 g 2206 5113 M
+-192 259 V
+stroke
+LT0
+.7649 g 2264 5662 M
+2014 5372 L
+stroke
+LT0
+.3401 g 2090 3885 M
+-192 251 V
+stroke
+LT0
+.4314 g 2148 4520 M
+1898 4136 L
+stroke
+LT0
+.8049 g 3591 5513 M
+-192 251 V
+stroke
+LT0
+.8171 g 3149 5598 M
+250 166 V
+stroke
+LT0
+.7747 g 2456 5403 M
+-192 259 V
+stroke
+LT0
+.8303 g 3149 5598 M
+-192 256 V
+stroke
+LT0
+.8362 g 2707 5649 M
+250 205 V
+stroke
+LT0
+.5237 g 2148 4520 M
+-192 257 V
+stroke
+LT0
+.6067 g 2206 5113 M
+1956 4777 L
+stroke
+LT0
+.6697 g 4668 5043 M
+-192 221 V
+stroke
+LT0
+.6892 g 4226 5167 M
+250 97 V
+stroke
+LT0
+.5359 g 5744 4589 M
+-192 167 V
+stroke
+LT0
+.5564 g 5302 4717 M
+250 39 V
+stroke
+LT1
+.3591 g 8147 4023 M
+-192 -11 V
+stroke
+LT1
+.3655 g 7705 4077 M
+250 -65 V
+stroke
+LT1
+.3787 g 7705 4077 M
+-192 25 V
+stroke
+LT1
+.3864 g 7290 4146 M
+223 -44 V
+stroke
+LT1
+.3489 g 8589 3994 M
+-192 -49 V
+stroke
+LT1
+.3503 g 8147 4023 M
+250 -78 V
+stroke
+LT0
+.7112 g 4226 5167 M
+-192 233 V
+stroke
+LT0
+.7268 g 3783 5269 M
+251 131 V
+stroke
+LT0
+.7781 g 2899 5393 M
+-192 256 V
+stroke
+LT0
+.7761 g 2456 5403 M
+251 246 V
+stroke
+LT0
+.6257 g 2398 4856 M
+-192 257 V
+stroke
+LT0
+.7 g 2456 5403 M
+2206 5113 L
+stroke
+LT0
+.5808 g 5302 4717 M
+-192 188 V
+stroke
+LT0
+.5999 g 4860 4838 M
+250 67 V
+stroke
+LT0
+.2795 g 2282 3641 M
+-192 244 V
+stroke
+LT0
+.3694 g 2340 4270 M
+2090 3885 L
+stroke
+LT0
+.7102 g 2648 5146 M
+-192 257 V
+stroke
+LT0
+.7444 g 3783 5269 M
+-192 244 V
+stroke
+LT0
+.7551 g 3341 5346 M
+250 167 V
+stroke
+LT1
+.3499 g 9032 3997 M
+-192 -90 V
+stroke
+LT1
+.3455 g 8589 3994 M
+251 -87 V
+stroke
+LT0
+.7673 g 3341 5346 M
+-192 252 V
+stroke
+LT0
+.7722 g 2899 5393 M
+250 205 V
+stroke
+LT0
+.4607 g 2340 4270 M
+-192 250 V
+stroke
+LT0
+.5427 g 2398 4856 M
+2148 4520 L
+stroke
+LT0
+.4555 g 6378 4341 M
+206 -9 V
+stroke
+LT0
+.6223 g 4860 4838 M
+-192 205 V
+stroke
+LT0
+.6389 g 4418 4946 M
+250 97 V
+stroke
+LT0
+.4734 g 6378 4341 M
+-192 117 V
+stroke
+LT0
+.4895 g 5936 4446 M
+250 12 V
+stroke
+LT0
+.7151 g 3091 5141 M
+-192 252 V
+stroke
+LT0
+.7122 g 2648 5146 M
+251 247 V
+stroke
+LT0
+.5627 g 2590 4605 M
+-192 251 V
+stroke
+LT0
+.636 g 2648 5146 M
+2398 4856 L
+stroke
+LT1
+.364 g 9474 4036 M
+9282 3902 L
+stroke
+LT1
+.3528 g 9032 3997 M
+250 -95 V
+stroke
+LT0
+.6584 g 4418 4946 M
+-192 221 V
+stroke
+LT0
+.6716 g 3975 5036 M
+251 131 V
+stroke
+LT0
+.6472 g 2840 4895 M
+-192 251 V
+stroke
+LT0
+.7068 g 3533 5103 M
+-192 243 V
+stroke
+LT0
+.7102 g 3091 5141 M
+250 205 V
+stroke
+LT0
+.2224 g 2474 3408 M
+-192 233 V
+stroke
+LT0
+.3103 g 2532 4026 M
+2282 3641 L
+stroke
+LT0
+.6873 g 3975 5036 M
+-192 233 V
+stroke
+LT0
+.696 g 3533 5103 M
+250 166 V
+stroke
+LT0
+.4001 g 2532 4026 M
+-192 244 V
+stroke
+LT0
+.4807 g 2590 4605 M
+2340 4270 L
+stroke
+LT0
+.5105 g 5936 4446 M
+-192 143 V
+stroke
+LT0
+.5266 g 5494 4551 M
+250 38 V
+stroke
+LT0
+.5471 g 5494 4551 M
+-192 166 V
+stroke
+LT0
+.5623 g 5052 4651 M
+250 66 V
+stroke
+LT0
+.6545 g 3283 4898 M
+-192 243 V
+stroke
+LT0
+.6501 g 2840 4895 M
+251 246 V
+stroke
+LT0
+.5022 g 2782 4362 M
+-192 243 V
+stroke
+LT0
+.574 g 2840 4895 M
+2590 4605 L
+stroke
+LT0
+.5867 g 3032 4651 M
+-192 244 V
+stroke
+LT1
+.3933 g 9916 4115 M
+9724 3935 L
+stroke
+LT1
+.3743 g 9474 4036 M
+250 -101 V
+stroke
+LT0
+.5813 g 5052 4651 M
+-192 187 V
+stroke
+LT0
+.5945 g 4610 4741 M
+250 97 V
+stroke
+LT0
+.6497 g 3725 4869 M
+-192 234 V
+stroke
+LT0
+.6511 g 3283 4898 M
+250 205 V
+stroke
+LT0
+.343 g 2724 3793 M
+-192 233 V
+stroke
+LT0
+.4216 g 2782 4362 M
+2532 4026 L
+stroke
+LT0
+.6111 g 4610 4741 M
+-192 205 V
+stroke
+LT0
+.6213 g 4167 4815 M
+251 131 V
+stroke
+LT0
+.1697 g 2666 3187 M
+-192 221 V
+stroke
+LT0
+.2551 g 2724 3793 M
+2474 3408 L
+stroke
+LT0
+.6345 g 4167 4815 M
+-192 221 V
+stroke
+LT0
+.6409 g 3725 4869 M
+250 167 V
+stroke
+LT1
+.4094 g 7897 4087 M
+-192 -10 V
+stroke
+LT1
+.4128 g 7454 4126 M
+251 -49 V
+stroke
+LT0
+.5974 g 3475 4664 M
+-192 234 V
+stroke
+LT0
+.5911 g 3032 4651 M
+251 247 V
+stroke
+LT0
+.4451 g 2974 4129 M
+-192 233 V
+stroke
+LT0
+.5149 g 3032 4651 M
+2782 4362 L
+stroke
+LT0
+.4676 g 6516 4277 M
+-138 64 V
+stroke
+LT0
+.4783 g 6128 4329 M
+250 12 V
+stroke
+LT0
+.5295 g 3224 4419 M
+-192 232 V
+stroke
+LT1
+.4041 g 8339 4072 M
+-192 -49 V
+stroke
+LT1
+.4031 g 7897 4087 M
+250 -64 V
+stroke
+LT0
+.4944 g 6128 4329 M
+-192 117 V
+stroke
+LT0
+.5056 g 5686 4408 M
+250 38 V
+stroke
+LT0
+.5969 g 3917 4649 M
+-192 220 V
+stroke
+LT0
+.5959 g 3475 4664 M
+250 205 V
+stroke
+LT0
+.2903 g 2916 3572 M
+-192 221 V
+stroke
+LT0
+.3665 g 2974 4129 M
+2724 3793 L
+stroke
+LT0
+.5217 g 5686 4408 M
+-192 143 V
+stroke
+LT0
+.5325 g 5244 4484 M
+250 67 V
+stroke
+LT1
+.4397 g 10358 4241 M
+-192 -229 V
+stroke
+LT1
+.4119 g 9916 4115 M
+250 -103 V
+stroke
+LT0
+.1223 g 2858 2982 M
+-192 205 V
+stroke
+LT0
+.2048 g 2916 3572 M
+2666 3187 L
+stroke
+LT1
+.4089 g 8781 4085 M
+-192 -91 V
+stroke
+LT1
+.4026 g 8339 4072 M
+250 -78 V
+stroke
+LT0
+.5476 g 5244 4484 M
+-192 167 V
+stroke
+LT0
+.5569 g 4802 4554 M
+250 97 V
+stroke
+LT0
+.5872 g 4359 4610 M
+-192 205 V
+stroke
+LT0
+.5906 g 3917 4649 M
+250 166 V
+stroke
+LT0
+.5701 g 4802 4554 M
+-192 187 V
+stroke
+LT0
+.5769 g 4359 4610 M
+251 131 V
+stroke
+LT0
+.5447 g 3667 4445 M
+-192 219 V
+stroke
+LT0
+.5359 g 3224 4419 M
+251 245 V
+stroke
+LT0
+.3923 g 3166 3908 M
+-192 221 V
+stroke
+LT0
+.4597 g 3224 4419 M
+2974 4129 L
+stroke
+LT0
+.4768 g 3417 4198 M
+-193 221 V
+stroke
+LT1
+.426 g 9224 4131 M
+9032 3997 L
+stroke
+LT1
+.4133 g 8781 4085 M
+251 -88 V
+stroke
+LT0
+.5496 g 4109 4445 M
+-192 204 V
+stroke
+LT0
+.5457 g 3667 4445 M
+250 204 V
+stroke
+LT0
+.2429 g 3108 3367 M
+-192 205 V
+stroke
+LT0
+.3162 g 3166 3908 M
+2916 3572 L
+stroke
+LT0
+.0813 g 3050 2795 M
+-192 187 V
+stroke
+LT0
+.1604 g 3108 3367 M
+2858 2982 L
+stroke
+LT0
+.5461 g 4551 4424 M
+-192 186 V
+stroke
+LT0
+.5461 g 4109 4445 M
+250 165 V
+stroke
+LT0
+.4973 g 3859 4239 M
+-192 206 V
+stroke
+LT0
+.4856 g 3417 4198 M
+250 247 V
+stroke
+LT0
+.5364 g 4994 4388 M
+-192 166 V
+stroke
+LT0
+.5393 g 4551 4424 M
+251 130 V
+stroke
+LT0
+.345 g 3358 3703 M
+-192 205 V
+stroke
+LT0
+.4094 g 3417 4198 M
+3166 3908 L
+stroke
+LT0
+.5222 g 5436 4342 M
+-192 142 V
+stroke
+LT0
+.5271 g 4994 4388 M
+250 96 V
+stroke
+LT0
+.5056 g 5878 4291 M
+-192 117 V
+stroke
+LT0
+.5115 g 5436 4342 M
+250 66 V
+stroke
+LT0
+.4885 g 6320 4239 M
+-192 90 V
+stroke
+LT0
+.4944 g 5878 4291 M
+250 38 V
+stroke
+LT0
+.4294 g 3609 3993 M
+-192 205 V
+stroke
+LT0
+.4816 g 6320 4239 M
+160 8 V
+stroke
+LT1
+.4573 g 9666 4216 M
+9474 4036 L
+stroke
+LT1
+.4373 g 9224 4131 M
+250 -95 V
+stroke
+LT1
+.4539 g 7646 4136 M
+-192 -10 V
+stroke
+LT1
+.4539 g 7204 4157 M
+250 -31 V
+stroke
+LT0
+.5085 g 4301 4257 M
+-192 188 V
+stroke
+LT0
+.5012 g 3859 4239 M
+250 206 V
+stroke
+LT0
+.2019 g 3300 3180 M
+-192 187 V
+stroke
+LT0
+.2717 g 3358 3703 M
+3108 3367 L
+stroke
+LT1
+.4543 g 8089 4136 M
+-192 -49 V
+stroke
+LT1
+.4504 g 7646 4136 M
+251 -49 V
+stroke
+LT0
+.0476 g 3242 2628 M
+-192 167 V
+stroke
+LT0
+.1228 g 3300 3180 M
+3050 2795 L
+stroke
+LT0
+.5125 g 4743 4257 M
+-192 167 V
+stroke
+LT0
+.5085 g 4301 4257 M
+250 167 V
+stroke
+LT0
+.4563 g 4051 4052 M
+-192 187 V
+stroke
+LT0
+.4412 g 3609 3993 M
+250 246 V
+stroke
+LT0
+.304 g 3550 3516 M
+-192 187 V
+stroke
+LT0
+.365 g 3609 3993 M
+3358 3703 L
+stroke
+LT0
+.3884 g 3801 3806 M
+-192 187 V
+stroke
+LT1
+.4641 g 8531 4162 M
+-192 -90 V
+stroke
+LT1
+.4553 g 8089 4136 M
+250 -64 V
+stroke
+LT0
+.511 g 5186 4245 M
+-192 143 V
+stroke
+LT0
+.5095 g 4743 4257 M
+251 131 V
+stroke
+LT1
+.5046 g 10108 4344 M
+9916 4115 L
+stroke
+LT1
+.4763 g 9666 4216 M
+250 -101 V
+stroke
+LT0
+.5061 g 5628 4224 M
+-192 118 V
+stroke
+LT0
+.5061 g 5186 4245 M
+250 97 V
+stroke
+LT0
+.4749 g 4493 4091 M
+-192 166 V
+stroke
+LT0
+.4636 g 4051 4052 M
+250 205 V
+stroke
+LT0
+.1682 g 3492 3013 M
+-192 167 V
+stroke
+LT0
+.2341 g 3550 3516 M
+3300 3180 L
+stroke
+LT0
+.4998 g 6069 4201 M
+-191 90 V
+stroke
+LT0
+.5002 g 5628 4224 M
+250 67 V
+stroke
+LT1
+.4851 g 8973 4219 M
+8781 4085 L
+stroke
+LT1
+.4705 g 8531 4162 M
+250 -77 V
+stroke
+LT0
+.4915 g 6429 4206 M
+-109 33 V
+stroke
+LT0
+.4939 g 6069 4201 M
+251 38 V
+stroke
+LT0
+.4226 g 4243 3886 M
+-192 166 V
+stroke
+LT0
+.4036 g 3801 3806 M
+250 246 V
+stroke
+LT0
+.2703 g 3742 3349 M
+-192 167 V
+stroke
+LT0
+.3274 g 3801 3806 M
+3550 3516 L
+stroke
+LT0
+.0222 g 3434 2485 M
+-192 143 V
+stroke
+LT0
+.093 g 3492 3013 M
+3242 2628 L
+stroke
+LT0
+.4871 g 4935 4114 M
+-192 143 V
+stroke
+LT0
+.4788 g 4493 4091 M
+250 166 V
+stroke
+LT0
+.3547 g 3993 3639 M
+-192 167 V
+stroke
+LT1
+.4915 g 7396 4168 M
+-192 -11 V
+stroke
+LT1
+.4875 g 6954 4168 M
+250 -11 V
+stroke
+LT0
+.4949 g 5378 4127 M
+-192 118 V
+stroke
+LT0
+.4885 g 4935 4114 M
+251 131 V
+stroke
+LT1
+.5193 g 9416 4311 M
+9224 4131 L
+stroke
+LT1
+.4978 g 8973 4219 M
+251 -88 V
+stroke
+LT1
+.5325 g 10108 4344 M
+250 -103 V
+stroke
+LT1
+.4988 g 7838 4186 M
+-192 -50 V
+stroke
+LT1
+.4915 g 7396 4168 M
+250 -32 V
+stroke
+LT0
+.4495 g 4685 3947 M
+-192 144 V
+stroke
+LT0
+.4338 g 4243 3886 M
+250 205 V
+stroke
+LT0
+.1428 g 3684 2870 M
+-192 143 V
+stroke
+LT0
+.2043 g 3742 3349 M
+3492 3013 L
+stroke
+LT0
+.5002 g 5820 4135 M
+-192 89 V
+stroke
+LT0
+.4949 g 5378 4127 M
+250 97 V
+stroke
+LT0
+.3972 g 4435 3742 M
+-192 144 V
+stroke
+LT0
+.3738 g 3993 3639 M
+250 247 V
+stroke
+LT0
+.2449 g 3934 3206 M
+-192 143 V
+stroke
+LT0
+.2976 g 3993 3639 M
+3742 3349 L
+stroke
+LT1
+.5144 g 8281 4227 M
+-192 -91 V
+stroke
+LT1
+.5027 g 7838 4186 M
+251 -50 V
+stroke
+LT0
+.5051 g 6261 4142 M
+-192 59 V
+stroke
+LT0
+.4998 g 5820 4135 M
+249 66 V
+stroke
+LT0
+.3293 g 4185 3496 M
+-192 143 V
+stroke
+LT0
+.0061 g 3626 2367 M
+-192 118 V
+stroke
+LT0
+.072 g 3684 2870 M
+3434 2485 L
+stroke
+LT0
+.4709 g 5127 3996 M
+-192 118 V
+stroke
+LT0
+.4578 g 4685 3947 M
+250 167 V
+stroke
+LT1
+.5686 g 9858 4445 M
+9666 4216 L
+stroke
+LT1
+.5393 g 9416 4311 M
+250 -95 V
+stroke
+LT0
+.5082 g 6261 4142 M
+112 17 V
+stroke
+LT1
+.5403 g 8723 4296 M
+8531 4162 L
+stroke
+LT1
+.5232 g 8281 4227 M
+250 -65 V
+stroke
+LT0
+.489 g 5570 4037 M
+-192 90 V
+stroke
+LT0
+.4773 g 5127 3996 M
+251 131 V
+stroke
+LT0
+.4333 g 4877 3829 M
+-192 118 V
+stroke
+LT0
+.4128 g 4435 3742 M
+250 205 V
+stroke
+LT0
+.1267 g 3876 2752 M
+-192 118 V
+stroke
+LT0
+.1833 g 3934 3206 M
+3684 2870 L
+stroke
+LT0
+.3811 g 4627 3624 M
+-192 118 V
+stroke
+LT0
+.3528 g 4185 3496 M
+250 246 V
+stroke
+LT0
+.2288 g 4126 3088 M
+-192 118 V
+stroke
+LT0
+.2766 g 4185 3496 M
+3934 3206 L
+stroke
+LT0
+.5056 g 6011 4076 M
+-191 59 V
+stroke
+LT0
+.4944 g 5570 4037 M
+250 98 V
+stroke
+LT1
+.5364 g 7588 4217 M
+-192 -49 V
+stroke
+LT1
+.5251 g 7146 4178 M
+250 -10 V
+stroke
+LT0
+.3132 g 4377 3378 M
+-192 118 V
+stroke
+LT1
+.5784 g 9165 4399 M
+8973 4219 L
+stroke
+LT1
+.5549 g 8723 4296 M
+250 -77 V
+stroke
+LT0
+.0002 g 3818 2277 M
+-192 90 V
+stroke
+LT0
+.0608 g 3876 2752 M
+3626 2367 L
+stroke
+LT0
+.4651 g 5320 3907 M
+-193 89 V
+stroke
+LT0
+.4465 g 4877 3829 M
+250 167 V
+stroke
+LT1
+.5969 g 9858 4445 M
+250 -101 V
+stroke
+LT0
+.5157 g 6342 4132 M
+-81 10 V
+stroke
+LT0
+.511 g 6011 4076 M
+250 66 V
+stroke
+LT1
+.5588 g 8031 4276 M
+-193 -90 V
+stroke
+LT1
+.5437 g 7588 4217 M
+250 -31 V
+stroke
+LT0
+.4275 g 5069 3740 M
+-192 89 V
+stroke
+LT0
+.4016 g 4627 3624 M
+250 205 V
+stroke
+LT0
+.1208 g 4068 2662 M
+-192 90 V
+stroke
+LT0
+.1721 g 4126 3088 M
+3876 2752 L
+stroke
+LT0
+.4944 g 5762 3979 M
+-192 58 V
+stroke
+LT0
+.4768 g 5320 3907 M
+250 130 V
+stroke
+LT1
+.6306 g 9608 4539 M
+9416 4311 L
+stroke
+LT1
+.5999 g 9165 4399 M
+251 -88 V
+stroke
+LT0
+.3752 g 4819 3535 M
+-192 89 V
+stroke
+LT0
+.3416 g 4377 3378 M
+250 246 V
+stroke
+LT0
+.2229 g 4318 2999 M
+-192 89 V
+stroke
+LT0
+.2654 g 4377 3378 M
+4126 3088 L
+stroke
+LT1
+.5906 g 8473 4361 M
+8281 4227 L
+stroke
+LT1
+.5706 g 8031 4276 M
+250 -49 V
+stroke
+LT0
+.3074 g 4569 3288 M
+-192 90 V
+stroke
+LT1
+.5662 g 7338 4227 M
+-192 -49 V
+stroke
+LT1
+.5505 g 6896 4166 M
+250 12 V
+stroke
+LT0
+.5232 g 6203 4050 M
+-192 26 V
+stroke
+LT0
+.5056 g 5762 3979 M
+249 97 V
+stroke
+LT0
+.0056 g 4010 2219 M
+-192 58 V
+stroke
+LT0
+.0603 g 4068 2662 M
+3818 2277 L
+stroke
+LT0
+.4705 g 5512 3848 M
+-192 59 V
+stroke
+LT0
+.446 g 5069 3740 M
+251 167 V
+stroke
+LT1
+.6335 g 8915 4475 M
+8723 4296 L
+stroke
+LT1
+.6077 g 8473 4361 M
+250 -65 V
+stroke
+LT1
+.5964 g 7780 4307 M
+-192 -90 V
+stroke
+LT1
+.5774 g 7338 4227 M
+250 -10 V
+stroke
+LT0
+.5351 g 6203 4050 M
+77 21 V
+stroke
+LT0
+.4329 g 5261 3681 M
+-192 59 V
+stroke
+LT0
+.4011 g 4819 3535 M
+250 205 V
+stroke
+LT0
+.1262 g 4260 2604 M
+-192 58 V
+stroke
+LT0
+.1716 g 4318 2999 M
+4068 2662 L
+stroke
+LT1
+.6599 g 9608 4539 M
+250 -94 V
+stroke
+LT0
+.512 g 5953 3953 M
+-191 26 V
+stroke
+LT0
+.488 g 5512 3848 M
+250 131 V
+stroke
+LT0
+.3806 g 5011 3476 M
+-192 59 V
+stroke
+LT0
+.3411 g 4569 3288 M
+250 247 V
+stroke
+LT0
+.2283 g 4510 2940 M
+-192 59 V
+stroke
+LT0
+.2649 g 4569 3288 M
+4318 2999 L
+stroke
+LT0
+.3127 g 4761 3230 M
+-192 58 V
+stroke
+LT1
+.5872 g 7088 4215 M
+-192 -49 V
+stroke
+LT1
+.5661 g 6668 4131 M
+228 35 V
+stroke
+LT1
+.635 g 8223 4410 M
+8031 4276 L
+stroke
+LT1
+.6116 g 7780 4307 M
+251 -31 V
+stroke
+LT1
+.6897 g 9357 4627 M
+9165 4399 L
+stroke
+LT1
+.657 g 8915 4475 M
+250 -76 V
+stroke
+LT0
+.0232 g 4202 2193 M
+-192 26 V
+stroke
+LT0
+.0715 g 4260 2604 M
+4010 2219 L
+stroke
+LT0
+.488 g 5704 3823 M
+-192 25 V
+stroke
+LT0
+.4573 g 5261 3681 M
+251 167 V
+stroke
+LT0
+.541 g 6262 4054 M
+-59 -4 V
+stroke
+LT0
+.5295 g 5953 3953 M
+250 97 V
+stroke
+LT1
+.6262 g 7530 4318 M
+-192 -91 V
+stroke
+LT1
+.6028 g 7088 4215 M
+250 12 V
+stroke
+LT0
+.4504 g 5453 3656 M
+-192 25 V
+stroke
+LT0
+.4124 g 5011 3476 M
+250 205 V
+stroke
+LT0
+.1438 g 4452 2578 M
+-192 26 V
+stroke
+LT0
+.1829 g 4510 2940 M
+4260 2604 L
+stroke
+LT1
+.6838 g 8665 4540 M
+8473 4361 L
+stroke
+LT1
+.655 g 8223 4410 M
+250 -49 V
+stroke
+LT0
+.3982 g 5203 3451 M
+-192 25 V
+stroke
+LT0
+.3523 g 4761 3230 M
+250 246 V
+stroke
+LT0
+.2458 g 4703 2914 M
+-193 26 V
+stroke
+LT0
+.2761 g 4761 3230 M
+4510 2940 L
+stroke
+LT1
+.7205 g 9357 4627 M
+251 -88 V
+stroke
+LT0
+.5427 g 6145 3964 M
+-192 -11 V
+stroke
+LT0
+.512 g 5704 3823 M
+249 130 V
+stroke
+LT0
+.3303 g 4953 3204 M
+-192 26 V
+stroke
+LT1
+.6726 g 7972 4441 M
+7780 4307 L
+stroke
+LT1
+.6453 g 7530 4318 M
+250 -11 V
+stroke
+LT1
+.7449 g 9107 4704 M
+8915 4475 L
+stroke
+LT1
+.7097 g 8665 4540 M
+250 -65 V
+stroke
+LT0
+.054 g 4394 2204 M
+-192 -11 V
+stroke
+LT0
+.0955 g 4452 2578 M
+4202 2193 L
+stroke
+LT0
+.5188 g 5896 3833 M
+-192 -10 V
+stroke
+LT0
+.4812 g 5453 3656 M
+251 167 V
+stroke
+LT1
+.6472 g 7280 4305 M
+-192 -90 V
+stroke
+LT1
+.6189 g 6837 4177 M
+251 38 V
+stroke
+LT0
+.5625 g 6145 3964 M
+43 17 V
+stroke
+LT1
+.7283 g 8415 4589 M
+8223 4410 L
+stroke
+LT1
+.696 g 7972 4441 M
+251 -31 V
+stroke
+LT0
+.4812 g 5645 3667 M
+-192 -11 V
+stroke
+LT0
+.4363 g 5203 3451 M
+250 205 V
+stroke
+LT0
+.1746 g 4644 2589 M
+-192 -11 V
+stroke
+LT0
+.2068 g 4703 2914 M
+4452 2578 L
+stroke
+LT0
+.429 g 5395 3461 M
+-192 -10 V
+stroke
+LT0
+.3762 g 4953 3204 M
+250 247 V
+stroke
+LT0
+.2766 g 4895 2925 M
+-192 -11 V
+stroke
+LT0
+.3 g 4953 3204 M
+4703 2914 L
+stroke
+LT0
+.3611 g 5145 3215 M
+-192 -11 V
+stroke
+LT1
+.7024 g 7722 4451 M
+7530 4318 L
+stroke
+LT1
+.6707 g 7280 4305 M
+250 13 V
+stroke
+LT1
+.7776 g 9107 4704 M
+250 -77 V
+stroke
+LT0
+.5663 g 6180 3973 M
+-35 -9 V
+stroke
+LT0
+.5496 g 5896 3833 M
+249 131 V
+stroke
+LT1
+.6584 g 7029 4267 M
+-192 -90 V
+stroke
+LT1
+.6248 g 6587 4110 M
+250 67 V
+stroke
+LT1
+.7952 g 8857 4769 M
+8665 4540 L
+stroke
+LT1
+.7571 g 8415 4589 M
+250 -49 V
+stroke
+LT0
+.0989 g 4586 2253 M
+-192 -49 V
+stroke
+LT0
+.1331 g 4644 2589 M
+4394 2204 L
+stroke
+LT0
+.5637 g 6087 3882 M
+-191 -49 V
+stroke
+LT0
+.5188 g 5645 3667 M
+251 166 V
+stroke
+LT1
+.7659 g 8164 4620 M
+7972 4441 L
+stroke
+LT1
+.7297 g 7722 4451 M
+250 -10 V
+stroke
+LT1
+.6589 g 6779 4201 M
+-192 -91 V
+stroke
+LT1
+.6211 g 6412 4042 M
+175 68 V
+stroke
+LT1
+.7234 g 7472 4439 M
+7280 4305 L
+stroke
+LT1
+.6868 g 7029 4267 M
+251 38 V
+stroke
+LT0
+.5261 g 5837 3716 M
+-192 -49 V
+stroke
+LT0
+.4739 g 5395 3461 M
+250 206 V
+stroke
+LT0
+.2195 g 4836 2638 M
+-192 -49 V
+stroke
+LT0
+.2444 g 4895 2925 M
+4644 2589 L
+stroke
+LT0
+.4739 g 5587 3511 M
+-192 -50 V
+stroke
+LT0
+.4138 g 5145 3215 M
+250 246 V
+stroke
+LT0
+.3215 g 5087 2974 M
+-192 -49 V
+stroke
+LT0
+.3376 g 5145 3215 M
+4895 2925 L
+stroke
+LT0
+.406 g 5337 3264 M
+-192 -49 V
+stroke
+LT1
+.8303 g 8857 4769 M
+250 -65 V
+stroke
+LT0
+.5902 g 6087 3882 M
+7 4 V
+stroke
+LT1
+.8396 g 8607 4818 M
+8415 4589 L
+stroke
+LT1
+.7981 g 8164 4620 M
+251 -31 V
+stroke
+LT1
+.7957 g 7914 4631 M
+7722 4451 L
+stroke
+LT1
+.7551 g 7472 4439 M
+250 12 V
+stroke
+LT1
+.7346 g 7222 4401 M
+7029 4267 L
+stroke
+LT1
+.6926 g 6779 4201 M
+250 66 V
+stroke
+LT0
+.1589 g 4778 2343 M
+-192 -90 V
+stroke
+LT0
+.1853 g 4836 2638 M
+4586 2253 L
+stroke
+LT0
+.591 g 6093 3886 M
+-6 -4 V
+stroke
+LT0
+.571 g 5837 3716 M
+250 166 V
+stroke
+LT0
+.5851 g 6022 3803 M
+-185 -87 V
+stroke
+LT0
+.5261 g 5587 3511 M
+250 205 V
+stroke
+LT0
+.2795 g 5028 2728 M
+-192 -90 V
+stroke
+LT0
+.2966 g 5087 2974 M
+4836 2638 L
+stroke
+LT1
+.7351 g 6971 4335 M
+6779 4201 L
+stroke
+LT1
+.6873 g 6529 4103 M
+250 98 V
+stroke
+LT1
+.8777 g 8607 4818 M
+250 -49 V
+stroke
+LT0
+.5339 g 5779 3601 M
+-192 -90 V
+stroke
+LT0
+.4661 g 5337 3264 M
+250 247 V
+stroke
+LT1
+.8772 g 8356 4849 M
+8164 4620 L
+stroke
+LT1
+.8318 g 7914 4631 M
+250 -11 V
+stroke
+LT0
+.3816 g 5279 3065 M
+-192 -91 V
+stroke
+LT0
+.3899 g 5337 3264 M
+5087 2974 L
+stroke
+LT1
+.8167 g 7664 4618 M
+7472 4439 L
+stroke
+LT1
+.7712 g 7222 4401 M
+250 38 V
+stroke
+LT0
+.4661 g 5529 3355 M
+-192 -91 V
+stroke
+LT1
+.7239 g 6721 4237 M
+6529 4103 L
+stroke
+LT1
+.6697 g 6279 3973 M
+250 130 V
+stroke
+LT1
+.8279 g 7414 4580 M
+7222 4401 L
+stroke
+LT1
+.7771 g 6971 4335 M
+251 66 V
+stroke
+LT0
+.2351 g 4970 2477 M
+4778 2343 L
+stroke
+LT0
+.2532 g 5028 2728 M
+4778 2343 L
+stroke
+LT1
+.7 g 6471 4107 M
+6279 3973 L
+stroke
+LT1
+.6504 g 6181 3908 M
+98 65 V
+stroke
+LT1
+.9187 g 8356 4849 M
+251 -31 V
+stroke
+LT1
+.907 g 8106 4860 M
+7914 4631 L
+stroke
+LT1
+.8572 g 7664 4618 M
+250 13 V
+stroke
+LT0
+.5927 g 5779 3601 M
+237 195 V
+stroke
+LT0
+.3557 g 5220 2862 M
+5028 2728 L
+stroke
+LT0
+.3645 g 5279 3065 M
+5028 2728 L
+stroke
+LT0
+.6063 g 5953 3723 M
+5779 3601 L
+stroke
+LT0
+.5339 g 5529 3355 M
+250 246 V
+stroke
+LT1
+.8284 g 7163 4514 M
+6971 4335 L
+stroke
+LT1
+.7717 g 6721 4237 M
+250 98 V
+stroke
+LT0
+.4578 g 5471 3199 M
+5279 3065 L
+stroke
+LT0
+.4578 g 5529 3355 M
+5279 3065 L
+stroke
+LT0
+.5422 g 5721 3489 M
+5529 3355 L
+stroke
+LT1
+.928 g 7856 4847 M
+7664 4618 L
+stroke
+LT1
+.8733 g 7414 4580 M
+250 38 V
+stroke
+LT1
+.9524 g 8106 4860 M
+250 -11 V
+stroke
+LT1
+.8171 g 6913 4418 M
+6721 4237 L
+stroke
+LT1
+.7542 g 6471 4107 M
+250 130 V
+stroke
+LT0
+.3284 g 5162 2658 M
+4970 2477 L
+stroke
+LT0
+.3376 g 5220 2862 M
+4970 2477 L
+stroke
+LT1
+.7932 g 6663 4287 M
+6471 4107 L
+stroke
+LT1
+.7234 g 6220 3940 M
+251 167 V
+stroke
+LT1
+.9392 g 7606 4809 M
+7414 4580 L
+stroke
+LT1
+.8792 g 7163 4514 M
+251 66 V
+stroke
+LT1
+.7556 g 6412 4120 M
+6220 3940 L
+stroke
+LT1
+.684 g 6024 3779 M
+196 161 V
+stroke
+LT1
+.9778 g 7856 4847 M
+250 13 V
+stroke
+LT0
+.449 g 5412 3043 M
+5220 2862 L
+stroke
+LT0
+.449 g 5471 3199 M
+5220 2862 L
+stroke
+LT0
+.6122 g 5721 3489 M
+205 201 V
+stroke
+LT0
+.551 g 5663 3379 M
+5471 3199 L
+stroke
+LT0
+.5422 g 5721 3489 M
+5471 3199 L
+stroke
+LT0
+.6266 g 5879 3637 M
+5721 3489 L
+stroke
+LT1
+.9397 g 7355 4743 M
+7163 4514 L
+stroke
+LT1
+.8738 g 6913 4418 M
+250 96 V
+stroke
+LT1
+.9939 g 7606 4809 M
+250 38 V
+stroke
+LT1
+.9285 g 7105 4646 M
+6913 4418 L
+stroke
+LT1
+.8562 g 6663 4287 M
+250 131 V
+stroke
+LT0
+.4397 g 5354 2887 M
+5162 2658 L
+stroke
+LT0
+.4397 g 5412 3043 M
+5162 2658 L
+stroke
+LT1
+.9045 g 6855 4515 M
+6663 4287 L
+stroke
+LT1
+.8254 g 6412 4120 M
+251 167 V
+stroke
+LT1
+.9998 g 7355 4743 M
+251 66 V
+stroke
+LT1
+.8669 g 6605 4349 M
+6412 4120 L
+stroke
+LT1
+.7805 g 6162 3915 M
+250 205 V
+stroke
+LT0
+.5603 g 5604 3272 M
+5412 3043 L
+stroke
+LT0
+.551 g 5663 3379 M
+5412 3043 L
+stroke
+LT1
+.8147 g 6354 4144 M
+6162 3915 L
+stroke
+LT1
+.7205 g 5913 3669 M
+249 246 V
+stroke
+LT0
+.6624 g 5855 3608 M
+5663 3379 L
+stroke
+LT1
+.6707 g 5913 3669 M
+-94 -109 V
+stroke
+LT1
+.7468 g 6104 3898 M
+5913 3669 L
+stroke
+LT1
+.9944 g 7105 4646 M
+250 97 V
+stroke
+LT1
+.9768 g 6855 4515 M
+250 131 V
+stroke
+LT0
+.5603 g 5604 3272 M
+5354 2887 L
+stroke
+LT1
+.946 g 6605 4349 M
+250 166 V
+stroke
+LT1
+.9011 g 6354 4144 M
+251 205 V
+stroke
+LT0
+.6716 g 5855 3608 M
+5604 3272 L
+stroke
+LT1
+.8411 g 6104 3898 M
+250 246 V
+stroke
+LT1
+.7649 g 6104 3898 M
+5855 3608 L
+% Begin plot #1
+stroke
+LT0
+.0117 g % End plot #1
+0.500 UL
+LTb
+5354 960 M
+5004 1354 V
+5354 960 M
+1514 2725 L
+6484 4070 M
+34 9 V
+1514 2725 M
+1264 342 V
+7580 -753 R
+6518 4079 L
+1514 6578 M
+0 -3853 V
+6518 4083 M
+0 -4 V
+0 3853 R
+0 -1927 V
+3840 162 R
+0 -3853 V
+5354 2887 M
+0 -1927 V
+1514 6578 M
+6518 7932 L
+10358 6167 M
+6518 7932 L
+5354 960 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 5427 904 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1590 2690 M
+-76 35 V
+6605 1298 M
+-77 35 V
+stroke
+0.00 0.00 0.00 C 6677 1243 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2794 3050 M
+-29 14 V
+7856 1637 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 7928 1581 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9107 1976 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 9180 1920 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10358 2314 M
+-76 35 V
+stroke
+0.00 0.00 0.00 C 10431 2259 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6594 4044 M
+-76 35 V
+5354 960 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 5288 930 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10288 2295 M
+70 19 V
+4394 1401 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 4327 1371 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+9328 2737 M
+70 19 V
+3434 1842 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 3367 1812 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+8368 3178 M
+70 19 V
+2474 2284 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 2407 2254 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+7408 3619 M
+70 19 V
+1514 2725 M
+70 19 V
+stroke
+0.00 0.00 0.00 C 1447 2695 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6484 4070 M
+34 9 V
+1602 2725 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 2725 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 2314 M
+88 0 V
+1602 3367 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 3367 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 2957 M
+88 0 V
+1602 4010 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 4010 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 3599 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 1388 4651 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1602 5293 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 5293 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 4882 M
+88 0 V
+1602 5935 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 5935 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 5525 M
+88 0 V
+1602 6578 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1388 6578 M
+[ [(Helvetica) 120.0 0.0 true true 0 (2.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+10270 6167 M
+88 0 V
+1.000 UP
+stroke
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/interpn.pdf b/doc/interpreter/interpn.pdf
new file mode 100644
index 0000000..6bb9808
Binary files /dev/null and b/doc/interpreter/interpn.pdf differ
diff --git a/doc/interpreter/interpn.png b/doc/interpreter/interpn.png
new file mode 100644
index 0000000..156420b
Binary files /dev/null and b/doc/interpreter/interpn.png differ
diff --git a/doc/interpreter/interpn.txt b/doc/interpreter/interpn.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/interpn.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/intro.texi b/doc/interpreter/intro.texi
new file mode 100644
index 0000000..00adf7b
--- /dev/null
+++ b/doc/interpreter/intro.texi
@@ -0,0 +1,669 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Introduction
+ at chapter A Brief Introduction to Octave
+ at cindex introduction
+
+GNU Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient interactive command line 
+interface for solving linear and nonlinear problems numerically, and 
+for performing other numerical experiments.  It may also be used as a 
+batch-oriented language for data processing.
+
+GNU Octave is freely redistributable software.  You may redistribute 
+it and/or modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation.  The GPL is included in 
+this manual in @ref{Copying}.
+
+This manual provides comprehensive documentation on how to install, 
+run, use, and extend GNU Octave.  Additional chapters describe how 
+to report bugs and help contribute code.
+
+This document corresponds to Octave version @value{VERSION}.
+
+ at menu
+* Running Octave::              
+* Simple Examples::             
+* Conventions::                 
+ at end menu
+
+ at node Running Octave
+ at section Running Octave
+
+On most systems, Octave is started with the shell command 
+ at samp{octave}.  Octave displays an initial message and then a prompt
+indicating it is ready to accept input.  You can begin typing Octave
+commands immediately afterward.
+
+If you get into trouble, you can usually interrupt Octave by typing
+ at kbd{Control-C} (written @kbd{C-c} for short).  @kbd{C-c} gets
+its name from the fact that you type it by holding down @key{CTRL} and
+then pressing @key{c}.  Doing this will normally return you to Octave's
+prompt.
+
+ at cindex exiting octave
+ at cindex quitting octave
+To exit Octave, type @kbd{quit}, or @kbd{exit} at the Octave prompt.
+
+On systems that support job control, you can suspend Octave by sending
+it a @code{SIGTSTP} signal, usually by typing @kbd{C-z}.
+
+ at node Simple Examples
+ at section Simple Examples
+
+The following chapters describe all of Octave's features in detail, but
+before doing that, it might be helpful to give a sampling of some of its
+capabilities.
+
+If you are new to Octave, I recommend that you try these examples to
+begin learning Octave by using it.  Lines marked with @samp{octave:13>}
+are lines you type, ending each with a carriage return.  Octave will
+respond with an answer, or by displaying a graph.
+
+ at subsection Elementary Calculations
+
+Octave can easily be used for basic numerical calculations.  Octave 
+knows about arithmetic operations (+,-,*,/), exponentiation (^), 
+natural logarithms/exponents (log, exp), and the trigonometric 
+functions (sin, cos, @dots{}).  Moreover, Octave calculations work 
+on real or imaginary numbers (i,j).  In addition, some mathematical 
+constants such as the base of the natural logarithm (e) and the ratio 
+of a circle's circumference to its diameter (pi) are pre-defined.
+
+ at noindent
+For example, to verify Euler's Identity,
+ at tex
+$$e^{\imath\pi} = -1$$
+ at end tex
+ at ifnottex
+ at display
+
+ i*pi
+e     = -1
+ at end display
+ at end ifnottex
+
+ at noindent
+type the following which will evaluate to @code{-1} within the
+tolerance of the calculation. 
+
+ at example
+octave:1> exp(i*pi)
+ at end example
+
+ at subsection Creating a Matrix
+
+Vectors and matrices are the basic building blocks for numerical analysis.  
+To create a new matrix and store it in a variable so that you can
+refer to it later, type the command
+
+ at example
+octave:1> A = [ 1, 1, 2; 3, 5, 8; 13, 21, 34 ]
+ at end example
+
+ at noindent
+Octave will respond by printing the matrix in neatly aligned columns.  
+Octave uses a comma or space to separate entries in a row, and a 
+semicolon or carriage return to separate one row from the next.  
+Ending a command with a semicolon tells Octave not to print the result
+of the command.  For example,
+
+ at example
+octave:2> B = rand (3, 2);
+ at end example
+
+ at noindent
+will create a 3 row, 2 column matrix with each element set to a random
+value between zero and one.
+
+To display the value of a variable, simply type the name of the
+variable at the prompt.  For example, to display the value stored in the 
+matrix @code{B}, type the command
+
+ at example
+octave:3> B
+ at end example
+
+ at subsection Matrix Arithmetic
+
+Octave has a convenient operator notation for performing matrix
+arithmetic.  For example, to multiply the matrix @code{A} by a scalar
+value, type the command
+
+ at example
+octave:4> 2 * A
+ at end example
+
+ at noindent
+To multiply the two matrices @code{A} and @code{B}, type the command
+
+ at example
+octave:5> A * B
+ at end example
+
+ at noindent
+and to form the matrix product
+ at tex
+$@code{A}^T at code{A}$,
+ at end tex
+ at ifnottex
+ at code{transpose (A) * A},
+ at end ifnottex
+type the command
+
+ at example
+octave:6> A' * A
+ at end example
+
+ at subsection Solving Systems of Linear Equations
+
+Systems of linear equations are ubiquitous in numerical analysis.
+To solve the set of linear equations @code{A at var{x} = b},
+use the left division operator, @samp{\}:
+
+ at example
+ at var{x} = A \ b
+ at end example
+
+ at noindent
+This is conceptually equivalent to
+ at tex
+$@code{A}^{-1}@code{b}$,
+ at end tex
+ at ifnottex
+ at code{inv (a) * b},
+ at end ifnottex
+but avoids computing the inverse of a matrix directly.
+
+If the coefficient matrix is singular, Octave will print a warning
+message and compute a minimum norm solution.
+
+A simple example comes from chemistry and the need to obtain balanced 
+chemical equations.  Consider the burning of hydrogen and oxygen to 
+produce water.
+
+ at tex
+$$ {\rm H_{2}} + {\rm O_{2}} \rightarrow {\rm H_{2}O} $$
+ at end tex
+ at ifnottex
+ at example
+H2 + O2 --> H2O
+ at end example
+ at end ifnottex
+
+ at noindent
+The equation above is not accurate.  The Law of Conservation of Mass requires 
+that the number of molecules of each type balance on the left- and right-hand 
+sides of the equation.  Writing the variable overall reaction with 
+individual equations for hydrogen and oxygen one finds:
+
+ at tex
+\vbox{
+$$ x_{1}{\rm H_{2}} + x_{2}{\rm O_{2}} \rightarrow {\rm H_{2}O} $$
+$$ {\rm H:}\quad 2x_{1} + 0x_{2} \rightarrow 2 $$
+$$ {\rm O:}\quad 0x_{1} + 2x_{2} \rightarrow 1 $$
+}
+ at end tex
+ at ifnottex
+ at example
+ at group
+x1*H2 + x2*O2 --> H2O
+H: 2*x1 + 0*x2 --> 2
+O: 0*x1 + 2*x2 --> 1
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+The solution in Octave is found in just three steps.
+
+ at example
+ at group
+octave:1> A = [ 2, 0; 0, 2 ];
+octave:2> b = [ 2; 1 ];
+octave:3> x = A \ b
+ at end group
+ at end example
+
+ at subsection Integrating Differential Equations
+
+Octave has built-in functions for solving nonlinear differential
+equations of the form
+ at tex
+$$
+ {dx \over dt} = f(x,t), \qquad x(t=t_0) = x_0
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+dx
+-- = f (x, t)
+dt
+ at end group
+ at end example
+
+ at noindent
+with the initial condition
+
+ at example
+x(t = t0) = x0
+ at end example
+ at end ifnottex
+
+ at noindent
+For Octave to integrate equations of this form, you must first provide a
+definition of the function
+ at tex
+$f (x, t)$.
+ at end tex
+ at ifnottex
+ at code{f(x,t)}.
+ at end ifnottex
+This is straightforward, and may be accomplished by entering the
+function body directly on the command line.  For example, the following
+commands define the right-hand side function for an interesting pair of
+nonlinear differential equations.  Note that while you are entering a
+function, Octave responds with a different prompt, to indicate that it
+is waiting for you to complete your input.
+
+ at example
+ at group
+octave:1> function xdot = f (x, t) 
+>
+>  r = 0.25;
+>  k = 1.4;
+>  a = 1.5;
+>  b = 0.16;
+>  c = 0.9;
+>  d = 0.8;
+>
+>  xdot(1) = r*x(1)*(1 - x(1)/k) - a*x(1)*x(2)/(1 + b*x(1));
+>  xdot(2) = c*a*x(1)*x(2)/(1 + b*x(1)) - d*x(2);
+>
+> endfunction
+ at end group
+ at end example
+
+ at noindent
+Given the initial condition
+
+ at example
+octave:2> x0 = [1; 2];
+ at end example
+
+ at noindent
+and the set of output times as a column vector (note that the first
+output time corresponds to the initial condition given above)
+
+ at example
+octave:3> t = linspace (0, 50, 200)';
+ at end example
+
+ at noindent
+it is easy to integrate the set of differential equations:
+
+ at example
+octave:4> x = lsode ("f", x0, t);
+ at end example
+
+ at noindent
+The function @code{lsode} uses the Livermore Solver for Ordinary
+Differential Equations, described in A. C. Hindmarsh, @cite{ODEPACK, a
+Systematized Collection of ODE Solvers}, in: Scientific Computing, R. S.
+Stepleman et al. (Eds.), North-Holland, Amsterdam, 1983, pages 55--64.
+
+ at subsection Producing Graphical Output
+
+To display the solution of the previous example graphically, use the
+command
+
+ at example
+octave:1> plot (t, x)
+ at end example
+
+ at noindent
+If you are using a graphical user interface, Octave will automatically create
+a separate window to display the plot.
+
+To save a plot once it has been displayed on the screen, use the print
+command.  For example,
+
+ at example
+print -deps foo.eps
+ at end example
+
+ at noindent
+will create a file called @file{foo.eps} that contains a rendering of
+the current plot in Encapsulated PostScript format.  The command
+
+ at example
+help print
+ at end example
+
+ at noindent
+explains more options for the @code{print} command and provides a list
+of additional output file formats.
+
+ at subsection Editing What You Have Typed
+
+At the Octave prompt, you can recall, edit, and reissue previous
+commands using Emacs- or vi-style editing commands.  The default
+keybindings use Emacs-style commands.  For example, to recall the
+previous command, press @kbd{Control-p} (written @kbd{C-p} for
+short).  Doing this will normally bring back the previous line of input.
+ at kbd{C-n} will bring up the next line of input, @kbd{C-b} will move
+the cursor backward on the line, @kbd{C-f} will move the cursor forward
+on the line, etc.
+
+A complete description of the command line editing capability is given
+in this manual in @ref{Command Line Editing}.
+
+ at subsection Help and Documentation
+
+Octave has an extensive help facility.  The same documentation that is
+available in printed form is also available from the Octave prompt,
+because both forms of the documentation are created from the same input
+file.
+
+In order to get good help you first need to know the name of the command
+that you want to use.  This name of the function may not always be
+obvious, but a good place to start is to just type @code{help}.
+This will show you all the operators, reserved words, functions,
+built-in variables, and function files.  An alternative is to search the
+documentation using the @code{lookfor} function.  This function is
+described in @ref{Getting Help}.
+
+Once you know the name of the function you wish to use, you can get more
+help on the function by simply including the name as an argument to help.
+For example,
+
+ at example
+help plot
+ at end example
+
+ at noindent
+will display the help text for the @code{plot} function.
+
+Octave sends output that is too long to fit on one screen through a
+pager like @code{less} or @code{more}.  Type a @key{RET} to advance one
+line, a @key{SPC} to advance one page, and @key{q} to exit the pager.
+
+The part of Octave's help facility that allows you to read the complete
+text of the printed manual from within Octave normally uses a separate
+program called Info.  When you invoke Info you will be put into a menu
+driven program that contains the entire Octave manual.  Help for using
+Info is provided in this manual in @ref{Getting Help}.
+
+ at node Conventions
+ at section Conventions
+
+This section explains the notational conventions that are used in this
+manual.  You may want to skip this section and refer back to it later.
+
+ at menu
+* Fonts::                       
+* Evaluation Notation::         
+* Printing Notation::           
+* Error Messages::              
+* Format of Descriptions::      
+ at end menu
+
+ at node Fonts
+ at subsection Fonts
+ at cindex documentation fonts
+
+Examples of Octave code appear in this font or form: @code{svd (a)}.
+Names that represent variables or function arguments appear
+in this font or form: @var{first-number}.  Commands that you type at the
+shell prompt appear in this font or form: @samp{octave --no-init-file}.  
+Commands that you type at the Octave prompt sometimes appear in this font 
+or form: @kbd{foo --bar --baz}.  Specific keys on your keyboard appear 
+in this font or form: @key{ANY}.
+
+ at node Evaluation Notation
+ at subsection Evaluation Notation
+ at cindex evaluation notation
+ at cindex documentation notation
+
+In the examples in this manual, results from expressions that you
+evaluate are indicated with @samp{@result{}}.  For example,
+
+ at example
+ at group
+sqrt (2)
+     @result{} 1.4142
+ at end group
+ at end example
+
+ at noindent
+You can read this as ``@code{sqrt (2)} evaluates to 1.4142''.
+
+In some cases, matrix values that are returned by expressions are
+displayed like this
+
+ at example
+ at group
+[1, 2; 3, 4] == [1, 3; 2, 4]
+     @result{} [ 1, 0; 0, 1 ]
+ at end group
+ at end example
+
+ at noindent
+and in other cases, they are displayed like this
+
+ at example
+ at group
+eye (3)
+     @result{}  1  0  0
+         0  1  0
+         0  0  1
+ at end group
+ at end example
+
+ at noindent
+in order to clearly show the structure of the result.
+
+Sometimes to help describe one expression, another expression is
+shown that produces identical results.  The exact equivalence of
+expressions is indicated with @samp{@equiv{}}.  For example,
+
+ at example
+ at group
+rot90 ([1, 2; 3, 4], -1)
+ at equiv{}
+rot90 ([1, 2; 3, 4], 3)
+ at equiv{}
+rot90 ([1, 2; 3, 4], 7)
+ at end group
+ at end example
+
+ at node Printing Notation
+ at subsection Printing Notation
+ at cindex printing notation
+
+Many of the examples in this manual print text when they are
+evaluated.  In this manual the printed text resulting from an example 
+is indicated by @samp{@print{}}.  The value that is returned by 
+evaluating the expression is displayed with @samp{@result{}} 
+(@code{1} in the next example) and follows on a separate line.
+
+ at example
+ at group
+printf ("foo %s\n", "bar")
+     @print{} foo bar
+     @result{} 1
+ at end group
+ at end example
+
+ at node Error Messages
+ at subsection Error Messages
+ at cindex error message notation
+
+Some examples signal errors.  This normally displays an error message
+on your terminal.  Error messages are shown on a line beginning with
+ at code{error:}.
+
+ at example
+ at group
+fieldnames ([1, 2; 3, 4])
+error: fieldnames: wrong type argument `matrix'
+ at end group
+ at end example
+
+ at node Format of Descriptions
+ at subsection Format of Descriptions
+ at cindex description format
+
+Functions, commands, and variables are described in this manual in a 
+uniform format.  The first line of a description contains the name of
+the item followed by its arguments, if any.
+ at ifinfo
+The category---function, variable, or whatever---appears at the
+beginning of the line.
+ at end ifinfo
+ at iftex
+The category---function, variable, or whatever---is printed next to the
+right margin.
+ at end iftex
+The description follows on succeeding lines, sometimes with examples.
+
+ at menu
+* A Sample Function Description::  
+* A Sample Command Description::  
+* A Sample Variable Description::  
+ at end menu
+
+ at node A Sample Function Description
+ at subsubsection A Sample Function Description
+ at cindex function descriptions
+
+In a function description, the name of the function being described
+appears first.  It is followed on the same line by a list of parameters.
+The names used for the parameters are also used in the body of the
+description.
+
+Here is a description of an imaginary function @code{foo}:
+
+ at deftypefn {Function} {} foo (@var{x}, @var{y}, @dots{})
+The function @code{foo} subtracts @var{x} from @var{y}, then adds the
+remaining arguments to the result.  If @var{y} is not supplied, then the
+number 19 is used by default.
+
+ at example
+ at group
+foo (1, [3, 5], 3, 9)
+     @result{} [ 14, 16 ]
+foo (5)
+     @result{} 14
+ at end group
+ at end example
+
+More generally,
+
+ at example
+ at group
+foo (@var{w}, @var{x}, @var{y}, @dots{})
+ at equiv{}
+ at var{x} - @var{w} + @var{y} + @dots{}
+ at end group
+ at end example
+ at end deftypefn
+
+Any parameter whose name contains the name of a type (e.g.,
+ at var{integer} or @var{matrix}) is expected to be of that
+type.  Parameters named @var{object} may be of any type.  Parameters
+with other sorts of names (e.g., @var{new_file}) are discussed
+specifically in the description of the function.  In some sections,
+features common to parameters of several functions are described at the
+beginning.
+
+Functions in Octave may be defined in several different ways.  The
+category name for functions may include another name that indicates the
+way that the function is defined.  These additional tags include
+
+ at table @asis
+ at item Function File
+ at cindex function file
+The function described is defined using Octave commands stored in a text
+file.  @xref{Function Files}.
+
+ at item Built-in Function
+ at cindex built-in function
+The function described is written in a language like C++, C, or Fortran,
+and is part of the compiled Octave binary.
+
+ at item Loadable Function
+ at cindex loadable function
+The function described is written in a language like C++, C, or Fortran.
+On systems that support dynamic linking of user-supplied functions, it
+may be automatically linked while Octave is running, but only if it is
+needed.  @xref{Dynamically Linked Functions}.
+
+ at item Mapping Function
+ at cindex mapping function
+The function described works element-by-element for matrix and vector
+arguments.
+ at end table
+
+ at node A Sample Command Description
+ at subsubsection A Sample Command Description
+ at cindex command descriptions
+
+Command descriptions have a format similar to function descriptions,
+except that the word `Function' is replaced by `Command'.  Commands are
+functions that may be called without surrounding their arguments in
+parentheses.  For example, here is the description for Octave's
+ at code{cd} command:
+
+ at deffn {Command} cd dir
+ at deffnx {Command} chdir dir
+Change the current working directory to @var{dir}.  For example,
+ at kbd{cd ~/octave} changes the current working directory to
+ at file{~/octave}.  If the directory does not exist, an error message is
+printed and the working directory is not changed.
+ at end deffn
+
+ at node A Sample Variable Description
+ at subsubsection A Sample Variable Description
+ at cindex variable descriptions
+
+A @dfn{variable} is a name that can hold a value.  Although any variable
+can be set by the user, @dfn{built-in variables} typically exist
+specifically so that users can change them to alter the way Octave
+behaves (built-in variables are also sometimes called @dfn{user
+options}).  Ordinary variables and built-in variables are described
+using a format like that for functions except that there are no
+arguments.
+
+Here is a description of the imaginary variable
+ at code{do_what_i_mean_not_what_i_say}.
+
+ at defvr {Built-in Variable} do_what_i_mean_not_what_i_say
+If the value of this variable is nonzero, Octave will do what you
+actually wanted, even if you have typed a completely different and
+meaningless list of commands.
+ at end defvr
+
+Other variable descriptions have the same format, but `Built-in
+Variable' is replaced by `Variable', for ordinary variables, or
+`Constant' for symbolic constants whose values cannot be changed.
diff --git a/doc/interpreter/intro.txi b/doc/interpreter/intro.txi
new file mode 100644
index 0000000..f0b073d
--- /dev/null
+++ b/doc/interpreter/intro.txi
@@ -0,0 +1,667 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Introduction
+ at chapter A Brief Introduction to Octave
+ at cindex introduction
+
+GNU Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient interactive command line 
+interface for solving linear and nonlinear problems numerically, and 
+for performing other numerical experiments.  It may also be used as a 
+batch-oriented language for data processing.
+
+GNU Octave is freely redistributable software.  You may redistribute 
+it and/or modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation.  The GPL is included in 
+this manual in @ref{Copying}.
+
+This manual provides comprehensive documentation on how to install, 
+run, use, and extend GNU Octave.  Additional chapters describe how 
+to report bugs and help contribute code.
+
+This document corresponds to Octave version @value{VERSION}.
+
+ at menu
+* Running Octave::              
+* Simple Examples::             
+* Conventions::                 
+ at end menu
+
+ at node Running Octave
+ at section Running Octave
+
+On most systems, Octave is started with the shell command 
+ at samp{octave}.  Octave displays an initial message and then a prompt
+indicating it is ready to accept input.  You can begin typing Octave
+commands immediately afterward.
+
+If you get into trouble, you can usually interrupt Octave by typing
+ at kbd{Control-C} (written @kbd{C-c} for short).  @kbd{C-c} gets
+its name from the fact that you type it by holding down @key{CTRL} and
+then pressing @key{c}.  Doing this will normally return you to Octave's
+prompt.
+
+ at cindex exiting octave
+ at cindex quitting octave
+To exit Octave, type @kbd{quit}, or @kbd{exit} at the Octave prompt.
+
+On systems that support job control, you can suspend Octave by sending
+it a @code{SIGTSTP} signal, usually by typing @kbd{C-z}.
+
+ at node Simple Examples
+ at section Simple Examples
+
+The following chapters describe all of Octave's features in detail, but
+before doing that, it might be helpful to give a sampling of some of its
+capabilities.
+
+If you are new to Octave, I recommend that you try these examples to
+begin learning Octave by using it.  Lines marked with @samp{octave:13>}
+are lines you type, ending each with a carriage return.  Octave will
+respond with an answer, or by displaying a graph.
+
+ at subsection Elementary Calculations
+
+Octave can easily be used for basic numerical calculations.  Octave 
+knows about arithmetic operations (+,-,*,/), exponentiation (^), 
+natural logarithms/exponents (log, exp), and the trigonometric 
+functions (sin, cos, @dots{}).  Moreover, Octave calculations work 
+on real or imaginary numbers (i,j).  In addition, some mathematical 
+constants such as the base of the natural logarithm (e) and the ratio 
+of a circle's circumference to its diameter (pi) are pre-defined.
+
+ at noindent
+For example, to verify Euler's Identity,
+ at tex
+$$e^{\imath\pi} = -1$$
+ at end tex
+ at ifnottex
+ at display
+
+ i*pi
+e     = -1
+ at end display
+ at end ifnottex
+
+ at noindent
+type the following which will evaluate to @code{-1} within the
+tolerance of the calculation. 
+
+ at example
+octave:1> exp(i*pi)
+ at end example
+
+ at subsection Creating a Matrix
+
+Vectors and matrices are the basic building blocks for numerical analysis.  
+To create a new matrix and store it in a variable so that you can
+refer to it later, type the command
+
+ at example
+octave:1> A = [ 1, 1, 2; 3, 5, 8; 13, 21, 34 ]
+ at end example
+
+ at noindent
+Octave will respond by printing the matrix in neatly aligned columns.  
+Octave uses a comma or space to separate entries in a row, and a 
+semicolon or carriage return to separate one row from the next.  
+Ending a command with a semicolon tells Octave not to print the result
+of the command.  For example,
+
+ at example
+octave:2> B = rand (3, 2);
+ at end example
+
+ at noindent
+will create a 3 row, 2 column matrix with each element set to a random
+value between zero and one.
+
+To display the value of a variable, simply type the name of the
+variable at the prompt.  For example, to display the value stored in the 
+matrix @code{B}, type the command
+
+ at example
+octave:3> B
+ at end example
+
+ at subsection Matrix Arithmetic
+
+Octave has a convenient operator notation for performing matrix
+arithmetic.  For example, to multiply the matrix @code{A} by a scalar
+value, type the command
+
+ at example
+octave:4> 2 * A
+ at end example
+
+ at noindent
+To multiply the two matrices @code{A} and @code{B}, type the command
+
+ at example
+octave:5> A * B
+ at end example
+
+ at noindent
+and to form the matrix product
+ at tex
+$@code{A}^T at code{A}$,
+ at end tex
+ at ifnottex
+ at code{transpose (A) * A},
+ at end ifnottex
+type the command
+
+ at example
+octave:6> A' * A
+ at end example
+
+ at subsection Solving Systems of Linear Equations
+
+Systems of linear equations are ubiquitous in numerical analysis.
+To solve the set of linear equations @code{A at var{x} = b},
+use the left division operator, @samp{\}:
+
+ at example
+ at var{x} = A \ b
+ at end example
+
+ at noindent
+This is conceptually equivalent to
+ at tex
+$@code{A}^{-1}@code{b}$,
+ at end tex
+ at ifnottex
+ at code{inv (a) * b},
+ at end ifnottex
+but avoids computing the inverse of a matrix directly.
+
+If the coefficient matrix is singular, Octave will print a warning
+message and compute a minimum norm solution.
+
+A simple example comes from chemistry and the need to obtain balanced 
+chemical equations.  Consider the burning of hydrogen and oxygen to 
+produce water.
+
+ at tex
+$$ {\rm H_{2}} + {\rm O_{2}} \rightarrow {\rm H_{2}O} $$
+ at end tex
+ at ifnottex
+ at example
+H2 + O2 --> H2O
+ at end example
+ at end ifnottex
+
+ at noindent
+The equation above is not accurate.  The Law of Conservation of Mass requires 
+that the number of molecules of each type balance on the left- and right-hand 
+sides of the equation.  Writing the variable overall reaction with 
+individual equations for hydrogen and oxygen one finds:
+
+ at tex
+\vbox{
+$$ x_{1}{\rm H_{2}} + x_{2}{\rm O_{2}} \rightarrow {\rm H_{2}O} $$
+$$ {\rm H:}\quad 2x_{1} + 0x_{2} \rightarrow 2 $$
+$$ {\rm O:}\quad 0x_{1} + 2x_{2} \rightarrow 1 $$
+}
+ at end tex
+ at ifnottex
+ at example
+ at group
+x1*H2 + x2*O2 --> H2O
+H: 2*x1 + 0*x2 --> 2
+O: 0*x1 + 2*x2 --> 1
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+The solution in Octave is found in just three steps.
+
+ at example
+ at group
+octave:1> A = [ 2, 0; 0, 2 ];
+octave:2> b = [ 2; 1 ];
+octave:3> x = A \ b
+ at end group
+ at end example
+
+ at subsection Integrating Differential Equations
+
+Octave has built-in functions for solving nonlinear differential
+equations of the form
+ at tex
+$$
+ {dx \over dt} = f(x,t), \qquad x(t=t_0) = x_0
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+dx
+-- = f (x, t)
+dt
+ at end group
+ at end example
+
+ at noindent
+with the initial condition
+
+ at example
+x(t = t0) = x0
+ at end example
+ at end ifnottex
+
+ at noindent
+For Octave to integrate equations of this form, you must first provide a
+definition of the function
+ at tex
+$f (x, t)$.
+ at end tex
+ at ifnottex
+ at code{f(x,t)}.
+ at end ifnottex
+This is straightforward, and may be accomplished by entering the
+function body directly on the command line.  For example, the following
+commands define the right-hand side function for an interesting pair of
+nonlinear differential equations.  Note that while you are entering a
+function, Octave responds with a different prompt, to indicate that it
+is waiting for you to complete your input.
+
+ at example
+ at group
+octave:1> function xdot = f (x, t) 
+>
+>  r = 0.25;
+>  k = 1.4;
+>  a = 1.5;
+>  b = 0.16;
+>  c = 0.9;
+>  d = 0.8;
+>
+>  xdot(1) = r*x(1)*(1 - x(1)/k) - a*x(1)*x(2)/(1 + b*x(1));
+>  xdot(2) = c*a*x(1)*x(2)/(1 + b*x(1)) - d*x(2);
+>
+> endfunction
+ at end group
+ at end example
+
+ at noindent
+Given the initial condition
+
+ at example
+octave:2> x0 = [1; 2];
+ at end example
+
+ at noindent
+and the set of output times as a column vector (note that the first
+output time corresponds to the initial condition given above)
+
+ at example
+octave:3> t = linspace (0, 50, 200)';
+ at end example
+
+ at noindent
+it is easy to integrate the set of differential equations:
+
+ at example
+octave:4> x = lsode ("f", x0, t);
+ at end example
+
+ at noindent
+The function @code{lsode} uses the Livermore Solver for Ordinary
+Differential Equations, described in A. C. Hindmarsh, @cite{ODEPACK, a
+Systematized Collection of ODE Solvers}, in: Scientific Computing, R. S.
+Stepleman et al. (Eds.), North-Holland, Amsterdam, 1983, pages 55--64.
+
+ at subsection Producing Graphical Output
+
+To display the solution of the previous example graphically, use the
+command
+
+ at example
+octave:1> plot (t, x)
+ at end example
+
+ at noindent
+If you are using a graphical user interface, Octave will automatically create
+a separate window to display the plot.
+
+To save a plot once it has been displayed on the screen, use the print
+command.  For example,
+
+ at example
+print -deps foo.eps
+ at end example
+
+ at noindent
+will create a file called @file{foo.eps} that contains a rendering of
+the current plot in Encapsulated PostScript format.  The command
+
+ at example
+help print
+ at end example
+
+ at noindent
+explains more options for the @code{print} command and provides a list
+of additional output file formats.
+
+ at subsection Editing What You Have Typed
+
+At the Octave prompt, you can recall, edit, and reissue previous
+commands using Emacs- or vi-style editing commands.  The default
+keybindings use Emacs-style commands.  For example, to recall the
+previous command, press @kbd{Control-p} (written @kbd{C-p} for
+short).  Doing this will normally bring back the previous line of input.
+ at kbd{C-n} will bring up the next line of input, @kbd{C-b} will move
+the cursor backward on the line, @kbd{C-f} will move the cursor forward
+on the line, etc.
+
+A complete description of the command line editing capability is given
+in this manual in @ref{Command Line Editing}.
+
+ at subsection Help and Documentation
+
+Octave has an extensive help facility.  The same documentation that is
+available in printed form is also available from the Octave prompt,
+because both forms of the documentation are created from the same input
+file.
+
+In order to get good help you first need to know the name of the command
+that you want to use.  This name of the function may not always be
+obvious, but a good place to start is to just type @code{help}.
+This will show you all the operators, reserved words, functions,
+built-in variables, and function files.  An alternative is to search the
+documentation using the @code{lookfor} function.  This function is
+described in @ref{Getting Help}.
+
+Once you know the name of the function you wish to use, you can get more
+help on the function by simply including the name as an argument to help.
+For example,
+
+ at example
+help plot
+ at end example
+
+ at noindent
+will display the help text for the @code{plot} function.
+
+Octave sends output that is too long to fit on one screen through a
+pager like @code{less} or @code{more}.  Type a @key{RET} to advance one
+line, a @key{SPC} to advance one page, and @key{q} to exit the pager.
+
+The part of Octave's help facility that allows you to read the complete
+text of the printed manual from within Octave normally uses a separate
+program called Info.  When you invoke Info you will be put into a menu
+driven program that contains the entire Octave manual.  Help for using
+Info is provided in this manual in @ref{Getting Help}.
+
+ at node Conventions
+ at section Conventions
+
+This section explains the notational conventions that are used in this
+manual.  You may want to skip this section and refer back to it later.
+
+ at menu
+* Fonts::                       
+* Evaluation Notation::         
+* Printing Notation::           
+* Error Messages::              
+* Format of Descriptions::      
+ at end menu
+
+ at node Fonts
+ at subsection Fonts
+ at cindex documentation fonts
+
+Examples of Octave code appear in this font or form: @code{svd (a)}.
+Names that represent variables or function arguments appear
+in this font or form: @var{first-number}.  Commands that you type at the
+shell prompt appear in this font or form: @samp{octave --no-init-file}.  
+Commands that you type at the Octave prompt sometimes appear in this font 
+or form: @kbd{foo --bar --baz}.  Specific keys on your keyboard appear 
+in this font or form: @key{ANY}.
+
+ at node Evaluation Notation
+ at subsection Evaluation Notation
+ at cindex evaluation notation
+ at cindex documentation notation
+
+In the examples in this manual, results from expressions that you
+evaluate are indicated with @samp{@result{}}.  For example,
+
+ at example
+ at group
+sqrt (2)
+     @result{} 1.4142
+ at end group
+ at end example
+
+ at noindent
+You can read this as ``@code{sqrt (2)} evaluates to 1.4142''.
+
+In some cases, matrix values that are returned by expressions are
+displayed like this
+
+ at example
+ at group
+[1, 2; 3, 4] == [1, 3; 2, 4]
+     @result{} [ 1, 0; 0, 1 ]
+ at end group
+ at end example
+
+ at noindent
+and in other cases, they are displayed like this
+
+ at example
+ at group
+eye (3)
+     @result{}  1  0  0
+         0  1  0
+         0  0  1
+ at end group
+ at end example
+
+ at noindent
+in order to clearly show the structure of the result.
+
+Sometimes to help describe one expression, another expression is
+shown that produces identical results.  The exact equivalence of
+expressions is indicated with @samp{@equiv{}}.  For example,
+
+ at example
+ at group
+rot90 ([1, 2; 3, 4], -1)
+ at equiv{}
+rot90 ([1, 2; 3, 4], 3)
+ at equiv{}
+rot90 ([1, 2; 3, 4], 7)
+ at end group
+ at end example
+
+ at node Printing Notation
+ at subsection Printing Notation
+ at cindex printing notation
+
+Many of the examples in this manual print text when they are
+evaluated.  In this manual the printed text resulting from an example 
+is indicated by @samp{@print{}}.  The value that is returned by 
+evaluating the expression is displayed with @samp{@result{}} 
+(@code{1} in the next example) and follows on a separate line.
+
+ at example
+ at group
+printf ("foo %s\n", "bar")
+     @print{} foo bar
+     @result{} 1
+ at end group
+ at end example
+
+ at node Error Messages
+ at subsection Error Messages
+ at cindex error message notation
+
+Some examples signal errors.  This normally displays an error message
+on your terminal.  Error messages are shown on a line beginning with
+ at code{error:}.
+
+ at example
+ at group
+fieldnames ([1, 2; 3, 4])
+error: fieldnames: wrong type argument `matrix'
+ at end group
+ at end example
+
+ at node Format of Descriptions
+ at subsection Format of Descriptions
+ at cindex description format
+
+Functions, commands, and variables are described in this manual in a 
+uniform format.  The first line of a description contains the name of
+the item followed by its arguments, if any.
+ at ifinfo
+The category---function, variable, or whatever---appears at the
+beginning of the line.
+ at end ifinfo
+ at iftex
+The category---function, variable, or whatever---is printed next to the
+right margin.
+ at end iftex
+The description follows on succeeding lines, sometimes with examples.
+
+ at menu
+* A Sample Function Description::  
+* A Sample Command Description::  
+* A Sample Variable Description::  
+ at end menu
+
+ at node A Sample Function Description
+ at subsubsection A Sample Function Description
+ at cindex function descriptions
+
+In a function description, the name of the function being described
+appears first.  It is followed on the same line by a list of parameters.
+The names used for the parameters are also used in the body of the
+description.
+
+Here is a description of an imaginary function @code{foo}:
+
+ at deftypefn {Function} {} foo (@var{x}, @var{y}, @dots{})
+The function @code{foo} subtracts @var{x} from @var{y}, then adds the
+remaining arguments to the result.  If @var{y} is not supplied, then the
+number 19 is used by default.
+
+ at example
+ at group
+foo (1, [3, 5], 3, 9)
+     @result{} [ 14, 16 ]
+foo (5)
+     @result{} 14
+ at end group
+ at end example
+
+More generally,
+
+ at example
+ at group
+foo (@var{w}, @var{x}, @var{y}, @dots{})
+ at equiv{}
+ at var{x} - @var{w} + @var{y} + @dots{}
+ at end group
+ at end example
+ at end deftypefn
+
+Any parameter whose name contains the name of a type (e.g.,
+ at var{integer} or @var{matrix}) is expected to be of that
+type.  Parameters named @var{object} may be of any type.  Parameters
+with other sorts of names (e.g., @var{new_file}) are discussed
+specifically in the description of the function.  In some sections,
+features common to parameters of several functions are described at the
+beginning.
+
+Functions in Octave may be defined in several different ways.  The
+category name for functions may include another name that indicates the
+way that the function is defined.  These additional tags include
+
+ at table @asis
+ at item Function File
+ at cindex function file
+The function described is defined using Octave commands stored in a text
+file.  @xref{Function Files}.
+
+ at item Built-in Function
+ at cindex built-in function
+The function described is written in a language like C++, C, or Fortran,
+and is part of the compiled Octave binary.
+
+ at item Loadable Function
+ at cindex loadable function
+The function described is written in a language like C++, C, or Fortran.
+On systems that support dynamic linking of user-supplied functions, it
+may be automatically linked while Octave is running, but only if it is
+needed.  @xref{Dynamically Linked Functions}.
+
+ at item Mapping Function
+ at cindex mapping function
+The function described works element-by-element for matrix and vector
+arguments.
+ at end table
+
+ at node A Sample Command Description
+ at subsubsection A Sample Command Description
+ at cindex command descriptions
+
+Command descriptions have a format similar to function descriptions,
+except that the word `Function' is replaced by `Command'.  Commands are
+functions that may be called without surrounding their arguments in
+parentheses.  For example, here is the description for Octave's
+ at code{cd} command:
+
+ at deffn {Command} cd dir
+ at deffnx {Command} chdir dir
+Change the current working directory to @var{dir}.  For example,
+ at kbd{cd ~/octave} changes the current working directory to
+ at file{~/octave}.  If the directory does not exist, an error message is
+printed and the working directory is not changed.
+ at end deffn
+
+ at node A Sample Variable Description
+ at subsubsection A Sample Variable Description
+ at cindex variable descriptions
+
+A @dfn{variable} is a name that can hold a value.  Although any variable
+can be set by the user, @dfn{built-in variables} typically exist
+specifically so that users can change them to alter the way Octave
+behaves (built-in variables are also sometimes called @dfn{user
+options}).  Ordinary variables and built-in variables are described
+using a format like that for functions except that there are no
+arguments.
+
+Here is a description of the imaginary variable
+ at code{do_what_i_mean_not_what_i_say}.
+
+ at defvr {Built-in Variable} do_what_i_mean_not_what_i_say
+If the value of this variable is nonzero, Octave will do what you
+actually wanted, even if you have typed a completely different and
+meaningless list of commands.
+ at end defvr
+
+Other variable descriptions have the same format, but `Built-in
+Variable' is replaced by `Variable', for ordinary variables, or
+`Constant' for symbolic constants whose values cannot be changed.
diff --git a/doc/interpreter/io.texi b/doc/interpreter/io.texi
new file mode 100644
index 0000000..88bab28
--- /dev/null
+++ b/doc/interpreter/io.texi
@@ -0,0 +1,2433 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Input and Output
+ at chapter Input and Output
+
+Octave supports several ways of reading and writing data to or from the
+prompt or a file.  The simplest functions for data Input and Output
+(I/O) are easy to use, but only provides limited control of how
+data is processed.  For more control, a set of functions modelled
+after the C standard library are also provided by Octave.
+
+ at menu
+* Basic Input and Output::      
+* C-Style I/O Functions::       
+ at end menu
+
+ at node Basic Input and Output
+ at section Basic Input and Output
+
+ at c We could use a two-line introduction here...
+
+ at menu
+* Terminal Output::             
+* Terminal Input::              
+* Simple File I/O::             
+* Rational Approximations::
+ at end menu
+
+ at node Terminal Output
+ at subsection Terminal Output
+
+Since Octave normally prints the value of an expression as soon as it
+has been evaluated, the simplest of all I/O functions is a simple
+expression.  For example, the following expression will display the
+value of @samp{pi}
+
+ at example
+ at group
+pi
+     @print{} pi = 3.1416
+ at end group
+ at end example
+
+This works well as long as it is acceptable to have the name of the
+variable (or @samp{ans}) printed along with the value.  To print the
+value of a variable without printing its name, use the function
+ at code{disp}.
+
+The @code{format} command offers some control over the way Octave prints
+values with @code{disp} and through the normal echoing mechanism.
+
+ at c pr-output.cc
+ at anchor{doc-disp}
+ at deftypefn {Built-in Function} {} disp (@var{x})
+Display the value of @var{x}.  For example,
+
+ at example
+ at group
+disp ("The value of pi is:"), disp (pi)
+
+     @print{} the value of pi is:
+     @print{} 3.1416
+ at end group
+ at end example
+
+ at noindent
+Note that the output from @code{disp} always ends with a newline.
+
+If an output value is requested, @code{disp} prints nothing and
+returns the formatted output in a string.
+ at seealso{@ref{doc-fdisp,,fdisp}}
+ at end deftypefn
+
+
+ at c pr-output.cc
+ at anchor{doc-format}
+ at deffn  {Command} format
+ at deffnx {Command} format options
+Reset or specify the format of the output produced by @code{disp} and
+Octave's normal echoing mechanism.  This command only affects the display
+of numbers but not how they are stored or computed.  To change the internal
+representation from the default double use one of the conversion functions
+such as @code{single}, @code{uint8}, @code{int64}, etc.
+
+By default, Octave displays 5 significant digits in a human readable form
+(option @samp{short} paired with @samp{loose} format for matrices).
+If @code{format} is invoked without any options, this default format
+is restored.
+
+Valid formats for floating point numbers are listed in the following
+table.
+
+ at table @code
+ at item short
+Fixed point format with 5 significant figures in a field that is a maximum
+of 10 characters wide.  (default).
+
+If Octave is unable to format a matrix so that columns line up on the
+decimal point and all numbers fit within the maximum field width then
+it switches to an exponential @samp{e} format.
+
+ at item long
+Fixed point format with 15 significant figures in a field that is a maximum
+of 20 characters wide.
+
+As with the @samp{short} format, Octave will switch to an exponential
+ at samp{e} format if it is unable to format a matrix properly using the
+current format.
+
+ at item  short e
+ at itemx long e
+Exponential format.  The number to be represented is split between a mantissa
+and an exponent (power of 10).  The mantissa has 5 significant digits in the
+short format and 15 digits in the long format.
+For example, with the @samp{short e} format, @code{pi} is displayed as
+ at code{3.1416e+00}.
+
+ at item  short E
+ at itemx long E
+Identical to @samp{short e} or @samp{long e} but displays an uppercase
+ at samp{E} to indicate the exponent.
+For example, with the @samp{long E} format, @code{pi} is displayed as
+ at code{3.14159265358979E+00}.
+
+ at item  short g
+ at itemx long g
+Optimally choose between fixed point and exponential format based on
+the magnitude of the number.
+For example, with the @samp{short g} format,
+ at code{pi .^ [2; 4; 8; 16; 32]} is displayed as
+
+ at example
+ at group
+ans =
+
+      9.8696
+      97.409
+      9488.5
+  9.0032e+07
+  8.1058e+15
+ at end group
+ at end example
+
+ at item long G
+ at itemx short G
+Identical to @samp{short g} or @samp{long g} but displays an uppercase
+ at samp{E} to indicate the exponent.
+
+ at item free
+ at itemx none
+Print output in free format, without trying to line up columns of
+matrices on the decimal point.  This also causes complex numbers to be
+formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead
+of like this @samp{0.60419 + 0.60709i}.
+ at end table
+
+The following formats affect all numeric output (floating point and
+integer types).
+
+ at table @code
+ at item  +
+ at itemx + @var{chars}
+ at itemx plus
+ at itemx plus @var{chars}
+Print a @samp{+} symbol for nonzero matrix elements and a space for zero
+matrix elements.  This format can be very useful for examining the
+structure of a large sparse matrix.
+
+The optional argument @var{chars} specifies a list of 3 characters to use
+for printing values greater than zero, less than zero and equal to zero.
+For example, with the @samp{+ "+-."} format, @code{[1, 0, -1; -1, 0, 1]}
+is displayed as
+
+ at example
+ at group
+ans =
+
++.-
+-.+
+ at end group
+ at end example
+
+ at item bank
+Print in a fixed format with two digits to the right of the decimal
+point.
+
+ at item native-hex
+Print the hexadecimal representation of numbers as they are stored in
+memory.  For example, on a workstation which stores 8 byte real values
+in IEEE format with the least significant byte first, the value of
+ at code{pi} when printed in @code{native-hex} format is @code{400921fb54442d18}.
+
+ at item hex
+The same as @code{native-hex}, but always print the most significant
+byte first.
+ at item native-bit
+Print the bit representation of numbers as stored in memory.
+For example, the value of @code{pi} is
+
+ at example
+ at group
+01000000000010010010000111111011
+01010100010001000010110100011000
+ at end group
+ at end example
+
+(shown here in two 32 bit sections for typesetting purposes) when
+printed in native-bit format on a workstation which stores 8 byte real values
+in IEEE format with the least significant byte first.
+ at item bit
+The same as @code{native-bit}, but always print the most significant
+bits first.
+
+ at item rat
+Print a rational approximation, i.e., values are approximated
+as the ratio of small integers.
+For example, with the @samp{rat} format,
+ at code{pi} is displayed as @code{355/113}.
+ at end table
+
+The following two options affect the display of all matrices.
+
+ at table @code
+ at item compact
+Remove extra blank space around column number labels producing more compact
+output with more data per page.
+ at item loose
+Insert blank lines above and below column number labels to produce a more
+readable output with less data per page.  (default).
+ at end table
+ at end deffn
+
+
+ at menu
+* Paging Screen Output::
+ at end menu
+
+ at node Paging Screen Output
+ at subsubsection Paging Screen Output
+
+When running interactively, Octave normally sends any output intended
+for your terminal that is more than one screen long to a paging program,
+such as @code{less} or @code{more}.  This avoids the problem of having a
+large volume of output stream by before you can read it.  With
+ at code{less} (and some versions of @code{more}) you can also scan forward
+and backward, and search for specific items.
+
+Normally, no output is displayed by the pager until just before Octave
+is ready to print the top level prompt, or read from the standard input
+(for example, by using the @code{fscanf} or @code{scanf} functions).
+This means that there may be some delay before any output appears on
+your screen if you have asked Octave to perform a significant amount of
+work with a single command statement.  The function @code{fflush} may be
+used to force output to be sent to the pager (or any other stream)
+immediately.
+
+You can select the program to run as the pager using the @code{PAGER}
+function, and you can turn paging off by using the function
+ at code{more}.
+
+ at c pager.cc
+ at anchor{doc-more}
+ at deffn {Command} more
+ at deffnx {Command} more on
+ at deffnx {Command} more off
+Turn output pagination on or off.  Without an argument, @code{more}
+toggles the current state.
+The current state can be determined via @code{page_screen_output}.
+ at end deffn
+
+
+ at c pager.cc
+ at anchor{doc-PAGER}
+ at deftypefn {Built-in Function} {@var{val} =} PAGER ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PAGER (@var{new_val})
+Query or set the internal variable that specifies the program to use
+to display terminal output on your system.  The default value is
+normally @code{"less"}, @code{"more"}, or
+ at code{"pg"}, depending on what programs are installed on your system.
+ at xref{Installation}.
+ at seealso{@ref{doc-more,,more}, @ref{doc-page_screen_output,,page_screen_output}, @ref{doc-page_output_immediately,,page_output_immediately}, @ref{doc-PAGER_FLAGS,,PAGER_FLAGS}}
+ at end deftypefn
+
+
+ at c pager.cc
+ at anchor{doc-PAGER_FLAGS}
+ at deftypefn {Built-in Function} {@var{val} =} PAGER_FLAGS ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PAGER_FLAGS (@var{new_val})
+Query or set the internal variable that specifies the options to pass
+to the pager.
+ at seealso{@ref{doc-PAGER,,PAGER}}
+ at end deftypefn
+
+
+ at c pager.cc
+ at anchor{doc-page_screen_output}
+ at deftypefn {Built-in Function} {@var{val} =} page_screen_output ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} page_screen_output (@var{new_val})
+Query or set the internal variable that controls whether output intended
+for the terminal window that is longer than one page is sent through a
+pager.  This allows you to view one screenful at a time.  Some pagers
+(such as @code{less}---see @ref{Installation}) are also capable of moving
+backward on the output.
+ at end deftypefn
+
+
+ at c pager.cc
+ at anchor{doc-page_output_immediately}
+ at deftypefn {Built-in Function} {@var{val} =} page_output_immediately ()
+ at deftypefnx {Built-in Function} {@var{val} =} page_output_immediately (@var{new_val})
+Query or set the internal variable that controls whether Octave sends
+output to the pager as soon as it is available.  Otherwise, Octave
+buffers its output and waits until just before the prompt is printed to
+flush it to the pager.
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fflush}
+ at deftypefn {Built-in Function} {} fflush (@var{fid})
+Flush output to @var{fid}.  This is useful for ensuring that all
+pending output makes it to the screen before some other event occurs.
+For example, it is always a good idea to flush the standard output
+stream before calling @code{input}.
+
+ at code{fflush} returns 0 on success and an OS dependent error value
+(@minus{}1 on unix) on error.
+ at seealso{@ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at c FIXME -- maybe this would be a good place to describe the
+ at c following message:
+ at c
+ at c warning: connection to external pager (pid = 9334) lost --
+ at c warning: pending computations and output may be lost
+ at c warning: broken pipe
+
+ at node Terminal Input
+ at subsection Terminal Input
+
+Octave has three functions that make it easy to prompt users for
+input.  The @code{input} and @code{menu} functions are normally
+used for managing an interactive dialog with a user, and the
+ at code{keyboard} function is normally used for doing simple debugging.
+
+ at c input.cc
+ at anchor{doc-input}
+ at deftypefn {Built-in Function} {} input (@var{prompt})
+ at deftypefnx {Built-in Function} {} input (@var{prompt}, "s")
+Print a prompt and wait for user input.  For example,
+
+ at example
+input ("Pick a number, any number! ")
+ at end example
+
+ at noindent
+prints the prompt
+
+ at example
+Pick a number, any number!
+ at end example
+
+ at noindent
+and waits for the user to enter a value.  The string entered by the user
+is evaluated as an expression, so it may be a literal constant, a
+variable name, or any other valid expression.
+
+Currently, @code{input} only returns one value, regardless of the number
+of values produced by the evaluation of the expression.
+
+If you are only interested in getting a literal string value, you can
+call @code{input} with the character string @code{"s"} as the second
+argument.  This tells Octave to return the string entered by the user
+directly, without evaluating it first.
+
+Because there may be output waiting to be displayed by the pager, it is
+a good idea to always call @code{fflush (stdout)} before calling
+ at code{input}.  This will ensure that all pending output is written to
+the screen before your prompt.  @xref{Input and Output}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/menu.m
+ at anchor{doc-menu}
+ at deftypefn {Function File} {} menu (@var{title}, @var{opt1}, @dots{})
+Print a title string followed by a series of options.  Each option will
+be printed along with a number.  The return value is the number of the
+option selected by the user.  This function is useful for interactive
+programs.  There is no limit to the number of options that may be passed
+in, but it may be confusing to present more than will fit easily on one
+screen.
+ at seealso{@ref{doc-disp,,disp}, @ref{doc-printf,,printf}, @ref{doc-input,,input}}
+ at end deftypefn
+
+
+ at c input.cc
+ at anchor{doc-yes_or_no}
+ at deftypefn {Built-in Function} {} yes_or_no (@var{prompt})
+Ask the user a yes-or-no question.  Return 1 if the answer is yes.
+Takes one argument, which is the string to display to ask the
+question.  It should end in a space; @samp{yes-or-no-p} adds
+ at samp{(yes or no) } to it.  The user must confirm the answer with
+RET and can edit it until it has been confirmed.
+ at end deftypefn
+
+
+For @code{input}, the normal command line history and editing functions
+are available at the prompt.
+
+Octave also has a function that makes it possible to get a single
+character from the keyboard without requiring the user to type a
+carriage return.
+
+ at c sysdep.cc
+ at anchor{doc-kbhit}
+ at deftypefn {Built-in Function} {} kbhit ()
+Read a single keystroke from the keyboard.  If called with one
+argument, don't wait for a keypress.  For example,
+
+ at example
+x = kbhit ();
+ at end example
+
+ at noindent
+will set @var{x} to the next character typed at the keyboard as soon as
+it is typed.
+
+ at example
+x = kbhit (1);
+ at end example
+
+ at noindent
+identical to the above example, but don't wait for a keypress,
+returning the empty string if no key is available.
+ at end deftypefn
+
+
+ at node Simple File I/O
+ at subsection Simple File I/O
+
+ at cindex saving data
+ at cindex loading data
+The @code{save} and @code{load} commands allow data to be written to and
+read from disk files in various formats.  The default format of files
+written by the @code{save} command can be controlled using the functions
+ at code{default_save_options} and @code{save_precision}.
+
+As an example the following code creates a 3-by-3 matrix and saves it
+to the file @samp{myfile.mat}.
+
+ at example
+ at group
+A = [ 1:3; 4:6; 7:9 ];
+save myfile.mat A
+ at end group
+ at end example
+
+Once one or more variables have been saved to a file, they can be
+read into memory using the @code{load} command.
+
+ at example
+ at group
+load myfile.mat
+A
+     @print{} A =
+     @print{} 
+     @print{}    1   2   3
+     @print{}    4   5   6
+     @print{}    7   8   9
+ at end group
+ at end example
+
+ at c load-save.cc
+ at anchor{doc-save}
+ at deffn  {Command} save file
+ at deffnx {Command} save options file
+ at deffnx {Command} save options file @var{v1} @var{v2} @dots{}
+ at deffnx {Command} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}
+Save the named variables @var{v1}, @var{v2}, @dots{}, in the file
+ at var{file}.  The special filename @samp{-} may be used to write
+output to the terminal.  If no variable names are listed, Octave saves
+all the variables in the current scope.  Otherwise, full variable names or
+pattern syntax can be used to specify the variables to save.
+If the @code{-struct} modifier is used, fields @var{f1} @var{f2} @dots{}
+of the scalar structure @var{STRUCT} are saved as if they were variables
+with corresponding names.
+Valid options for the @code{save} command are listed in the following table.
+Options that modify the output format override the format specified by 
+ at code{default_save_options}.
+
+If save is invoked using the functional form
+
+ at example
+save ("-option1", @dots{}, "file", "v1", @dots{})
+ at end example
+
+ at noindent
+then the @var{options}, @var{file}, and variable name arguments
+(@var{v1}, @dots{}) must be specified as character strings.
+
+ at table @code
+ at item -ascii
+Save a single matrix in a text file without header or any other information.
+
+ at item -binary
+Save the data in Octave's binary data format.
+
+ at item -float-binary
+Save the data in Octave's binary data format but only using single
+precision.  Only use this format if you know that all the
+values to be saved can be represented in single precision.
+
+ at item -hdf5
+Save the data in HDF5 format.
+(HDF5 is a free, portable binary format developed by the National
+Center for Supercomputing Applications at the University of Illinois.)
+
+ at item -float-hdf5
+Save the data in HDF5 format but only using single precision.
+Only use this format if you know that all the
+values to be saved can be represented in single precision.
+
+ at item -V7
+ at itemx -v7
+ at itemx -7
+ at itemx -mat7-binary
+Save the data in @sc{matlab}'s v7 binary data format.
+
+ at item -V6
+ at itemx -v6
+ at itemx -6
+ at itemx -mat
+ at itemx -mat-binary
+Save the data in @sc{matlab}'s v6 binary data format.
+
+ at item -V4
+ at itemx -v4
+ at itemx -4
+ at itemx -mat4-binary
+Save the data in the binary format written by @sc{matlab} version 4.
+
+ at item -text
+Save the data in Octave's text data format.  (default).
+
+ at item -zip
+ at itemx -z
+Use the gzip algorithm to compress the file.  This works equally on files that
+are compressed with gzip outside of octave, and gzip can equally be used to
+convert the files for backward compatibility.
+ at end table
+
+The list of variables to save may use wildcard patterns containing
+the following special characters:
+ at table @code
+ at item ?
+Match any single character.
+
+ at item *
+Match zero or more characters.
+
+ at item [ @var{list} ]
+Match the list of characters specified by @var{list}.  If the first
+character is @code{!} or @code{^}, match all characters except those
+specified by @var{list}.  For example, the pattern @code{[a-zA-Z]} will
+match all lower and upper case alphabetic characters.  
+
+Wildcards may also be used in the field name specifications when using
+the @code{-struct} modifier (but not in the struct name itself).
+
+ at end table
+
+Except when using the @sc{matlab} binary data file format or the
+ at samp{-ascii} format, saving global
+variables also saves the global status of the variable.  If the variable
+is restored at a later time using @samp{load}, it will be restored as a
+global variable.
+
+The command
+
+ at example
+save -binary data a b*
+ at end example
+
+ at noindent
+saves the variable @samp{a} and all variables beginning with @samp{b} to
+the file @file{data} in Octave's binary format.
+ at seealso{@ref{doc-load,,load}, @ref{doc-default_save_options,,default_save_options}, @ref{doc-dlmread,,dlmread}, @ref{doc-csvread,,csvread}, @ref{doc-fread,,fread}}
+ at end deffn
+
+
+ at c load-save.cc
+ at anchor{doc-load}
+ at deffn  {Command} load file
+ at deffnx {Command} load options file
+ at deffnx {Command} load options file v1 v2 @dots{}
+ at deffnx {Command} S = load("options", "file", "v1", "v2", @dots{})
+Load the named variables @var{v1}, @var{v2}, @dots{}, from the file
+ at var{file}.  If no variables are specified then all variables found in the
+file will be loaded.  As with @code{save}, the list of variables to extract
+can be full names or use a pattern syntax.  The format of the file is
+automatically detected but may be overridden by supplying the appropriate
+option.
+
+If load is invoked using the functional form
+
+ at example
+load ("-option1", @dots{}, "file", "v1", @dots{})
+ at end example
+
+ at noindent
+then the @var{options}, @var{file}, and variable name arguments
+(@var{v1}, @dots{}) must be specified as character strings.
+
+If a variable that is not marked as global is loaded from a file when a
+global symbol with the same name already exists, it is loaded in the
+global symbol table.  Also, if a variable is marked as global in a file
+and a local symbol exists, the local symbol is moved to the global
+symbol table and given the value from the file.
+
+If invoked with a single output argument, Octave returns data instead
+of inserting variables in the symbol table.  If the data file contains
+only numbers (TAB- or space-delimited columns), a matrix of values is
+returned.  Otherwise, @code{load} returns a structure with members
+ corresponding to the names of the variables in the file.
+
+The @code{load} command can read data stored in Octave's text and
+binary formats, and @sc{matlab}'s binary format.  If compiled with zlib
+support, it can also load gzip-compressed files.  It will automatically
+detect the type of file and do conversion from different floating point
+formats (currently only IEEE big and little endian, though other formats
+may be added in the future).
+
+Valid options for @code{load} are listed in the following table.
+
+ at table @code
+ at item -force
+This option is accepted for backward compatibility but is ignored.
+Octave now overwrites variables currently in memory with
+those of the same name found in the file.
+
+ at item -ascii
+Force Octave to assume the file contains columns of numbers in text format
+without any header or other information.  Data in the file will be loaded
+as a single numeric matrix with the name of the variable derived from the
+name of the file.
+
+ at item -binary
+Force Octave to assume the file is in Octave's binary format.
+
+ at item -hdf5
+Force Octave to assume the file is in HDF5 format.
+(HDF5 is a free, portable binary format developed by the National
+Center for Supercomputing Applications at the University of Illinois.)
+Note that Octave can read HDF5 files not created by itself, but may
+skip some datasets in formats that it cannot support.
+
+ at item -import
+This option is accepted for backward compatibility but is ignored.
+Octave can now support multi-dimensional HDF data and automatically
+modifies variable names if they are invalid Octave identifiers.
+
+ at item -mat
+ at itemx -mat-binary
+ at itemx -6
+ at itemx -v6
+ at itemx -7
+ at itemx -v7
+Force Octave to assume the file is in @sc{matlab}'s version 6 or 7 binary
+format.
+
+ at item  -mat4-binary
+ at itemx -4
+ at itemx -v4
+ at itemx -V4
+Force Octave to assume the file is in the binary format written by
+ at sc{matlab} version 4.
+
+ at item -text
+Force Octave to assume the file is in Octave's text format.
+ at end table
+ at seealso{@ref{doc-save,,save}, @ref{doc-dlmwrite,,dlmwrite}, @ref{doc-csvwrite,,csvwrite}, @ref{doc-fwrite,,fwrite}}
+ at end deffn
+
+
+There are three functions that modify the behavior of @code{save}.
+
+ at c load-save.cc
+ at anchor{doc-default_save_options}
+ at deftypefn  {Built-in Function} {@var{val} =} default_save_options ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} default_save_options (@var{new_val})
+Query or set the internal variable that specifies the default options
+for the @code{save} command, and defines the default format.
+Typical values include @code{"-ascii"}, @code{"-text -zip"}.
+The default value is @code{-text}.
+ at seealso{@ref{doc-save,,save}}
+ at end deftypefn
+
+
+ at c ls-oct-ascii.cc
+ at anchor{doc-save_precision}
+ at deftypefn {Built-in Function} {@var{val} =} save_precision ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} save_precision (@var{new_val})
+Query or set the internal variable that specifies the number of
+digits to keep when saving data in text format.
+ at end deftypefn
+
+
+ at c load-save.cc
+ at anchor{doc-save_header_format_string}
+ at deftypefn  {Built-in Function} {@var{val} =} save_header_format_string ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} save_header_format_string (@var{new_val})
+Query or set the internal variable that specifies the format
+string used for the comment line written at the beginning of
+text-format data files saved by Octave.  The format string is
+passed to @code{strftime} and should begin with the character
+ at samp{#} and contain no newline characters.  If the value of
+ at code{save_header_format_string} is the empty string,
+the header comment is omitted from text-format data files.  The
+default value is
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>"
+ at end smallexample
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-save,,save}}
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-native_float_format}
+ at deftypefn {Built-in Function} {} native_float_format ()
+Return the native floating point format as a string
+ at end deftypefn
+
+
+It is possible to write data to a file in a similar way to the
+ at code{disp} function for writing data to the screen.  The @code{fdisp}
+works just like @code{disp} except its first argument is a file pointer
+as created by @code{fopen}.  As an example, the following code writes
+to data @samp{myfile.txt}.
+
+ at example
+ at group
+fid = fopen ("myfile.txt", "w");
+fdisp (fid, "3/8 is ");
+fdisp (fid, 3/8);
+fclose (fid);
+ at end group
+ at end example
+
+ at noindent
+ at xref{Opening and Closing Files}, for details on how to use @code{fopen}
+and @code{fclose}.
+
+ at c pr-output.cc
+ at anchor{doc-fdisp}
+ at deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})
+Display the value of @var{x} on the stream @var{fid}.  For example,
+
+ at example
+ at group
+fdisp (stdout, "The value of pi is:"), fdisp (stdout, pi)
+
+     @print{} the value of pi is:
+     @print{} 3.1416
+ at end group
+ at end example
+
+ at noindent
+Note that the output from @code{fdisp} always ends with a newline.
+ at seealso{@ref{doc-disp,,disp}}
+ at end deftypefn
+
+
+Octave can also read and write matrices text files such as comma
+separated lists.
+
+ at c ./io/dlmwrite.m
+ at anchor{doc-dlmwrite}
+ at deftypefn {Function File} {} dlmwrite (@var{file}, @var{a})
+ at deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, @var{delim}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, @var{key}, @var{val} @dots{})
+ at deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, "-append", @dots{})
+Write the matrix @var{a} to the named file using delimiters.
+
+The parameter @var{delim} specifies the delimiter to use to separate
+values on a row.
+
+The value of @var{r} specifies the number of delimiter-only lines to
+add to the start of the file.
+
+The value of @var{c} specifies the number of delimiters to prepend to
+each line of data.
+
+If the argument @code{"-append"} is given, append to the end of the
+ at var{file}.
+
+In addition, the following keyword value pairs may appear at the end
+of the argument list:
+ at table @code
+ at item "append"
+Either @samp{"on"} or @samp{"off"}.  See @samp{"-append"} above.
+
+ at item "delimiter"
+See @var{delim} above.
+
+ at item "newline"
+The character(s) to use to separate each row.  Three special cases
+exist for this option.  @samp{"unix"} is changed into '\n',
+ at samp{"pc"} is changed into '\r\n', and @samp{"mac"} is changed
+into '\r'.  Other values for this option are kept as is.
+
+ at item "roffset"
+See @var{r} above.
+
+ at item "coffset"
+See @var{c} above.
+
+ at item "precision"
+The precision to use when writing the file.  It can either be a
+format string (as used by fprintf) or a number of significant digits.
+ at end table
+
+ at example
+dlmwrite ("file.csv", reshape (1:16, 4, 4));
+ at end example
+
+ at example
+dlmwrite ("file.tex", a, "delimiter", "&", "newline", "\\n")
+ at end example
+
+ at seealso{@ref{doc-dlmread,,dlmread}, @ref{doc-csvread,,csvread}, @ref{doc-csvwrite,,csvwrite}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dlmread.cc
+ at anchor{doc-dlmread}
+ at deftypefn {Loadable Function} {@var{data} =} dlmread (@var{file})
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep})
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{r0}, @var{c0})
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{range})
+Read the matrix @var{data} from a text file.  If not defined the separator
+between fields is determined from the file itself.  Otherwise the
+separation character is defined by @var{sep}.
+
+Given two scalar arguments @var{r0} and @var{c0}, these define the starting
+row and column of the data to be read.  These values are indexed from zero,
+such that the first row corresponds to an index of zero.
+
+The @var{range} parameter must be a 4 element vector containing the upper
+left and lower right corner @code{[@var{R0}, at var{C0}, at var{R1}, at var{C1}]} or
+a spreadsheet style range such as 'A2..Q15'.  The lowest index value is zero.
+ at end deftypefn
+
+
+ at c ./io/csvwrite.m
+ at anchor{doc-csvwrite}
+ at deftypefn {Function File} {@var{x} =} csvwrite (@var{filename}, @var{x})
+Write the matrix @var{x} to a file.
+
+This function is equivalent to
+ at example
+dlmwrite (@var{filename}, @var{x}, ",", @dots{})
+ at end example
+
+ at seealso{@ref{doc-dlmread,,dlmread}, @ref{doc-dlmwrite,,dlmwrite}, @ref{doc-csvread,,csvread}}
+ at end deftypefn
+
+
+ at c ./io/csvread.m
+ at anchor{doc-csvread}
+ at deftypefn {Function File} {@var{x} =} csvread (@var{filename})
+Read the matrix @var{x} from a file.
+
+This function is equivalent to
+ at example
+dlmread (@var{filename}, "," , @dots{})
+ at end example
+
+ at seealso{@ref{doc-dlmread,,dlmread}, @ref{doc-dlmwrite,,dlmwrite}, @ref{doc-csvwrite,,csvwrite}}
+ at end deftypefn
+
+
+ at menu
+* Saving Data on Unexpected Exits::
+ at end menu
+
+ at node Saving Data on Unexpected Exits
+ at subsubsection Saving Data on Unexpected Exits
+
+If Octave for some reason exits unexpectedly it will by default save the
+variables available in the workspace to a file in the current directory.
+By default this file is named @samp{octave-core} and can be loaded
+into memory with the @code{load} command.  While the default behavior
+most often is reasonable it can be changed through the following
+functions.
+
+ at c load-save.cc
+ at anchor{doc-crash_dumps_octave_core}
+ at deftypefn {Built-in Function} {@var{val} =} crash_dumps_octave_core ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})
+Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it
+crashes or receives a hangup, terminate or similar signal.
+ at seealso{@ref{doc-octave_core_file_limit,,octave_core_file_limit}, @ref{doc-octave_core_file_name,,octave_core_file_name}, @ref{doc-octave_core_file_options,,octave_core_file_options}}
+ at end deftypefn
+
+
+ at c sighandlers.cc
+ at anchor{doc-sighup_dumps_octave_core}
+ at deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})
+Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it receives
+a hangup signal.
+ at end deftypefn
+
+
+ at c sighandlers.cc
+ at anchor{doc-sigterm_dumps_octave_core}
+ at deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})
+Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it receives
+a terminate signal.
+ at end deftypefn
+
+
+ at c load-save.cc
+ at anchor{doc-octave_core_file_options}
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_options ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_options (@var{new_val})
+Query or set the internal variable that specifies the options used for
+saving the workspace data if Octave aborts.  The value of
+ at code{octave_core_file_options} should follow the same format as the
+options for the @code{save} function.  The default value is Octave's binary
+format.
+ at seealso{@ref{doc-crash_dumps_octave_core,,crash_dumps_octave_core}, @ref{doc-octave_core_file_name,,octave_core_file_name}, @ref{doc-octave_core_file_limit,,octave_core_file_limit}}
+ at end deftypefn
+
+
+ at c load-save.cc
+ at anchor{doc-octave_core_file_limit}
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_limit ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_limit (@var{new_val})
+Query or set the internal variable that specifies the maximum amount
+of memory (in kilobytes) of the top-level workspace that Octave will
+attempt to save when writing data to the crash dump file (the name of
+the file is specified by @var{octave_core_file_name}).  If
+ at var{octave_core_file_options} flags specify a binary format,
+then @var{octave_core_file_limit} will be approximately the maximum
+size of the file.  If a text file format is used, then the file could
+be much larger than the limit.  The default value is -1 (unlimited)
+ at seealso{@ref{doc-crash_dumps_octave_core,,crash_dumps_octave_core}, @ref{doc-octave_core_file_name,,octave_core_file_name}, @ref{doc-octave_core_file_options,,octave_core_file_options}}
+ at end deftypefn
+
+
+ at c load-save.cc
+ at anchor{doc-octave_core_file_name}
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_name ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_name (@var{new_val})
+Query or set the internal variable that specifies the name of the file
+used for saving data from the top-level workspace if Octave aborts.
+The default value is @code{"octave-core"}
+ at seealso{@ref{doc-crash_dumps_octave_core,,crash_dumps_octave_core}, @ref{doc-octave_core_file_name,,octave_core_file_name}, @ref{doc-octave_core_file_options,,octave_core_file_options}}
+ at end deftypefn
+
+
+ at node Rational Approximations
+ at subsection Rational Approximations
+
+ at c ./general/rat.m
+ at anchor{doc-rat}
+ at deftypefn {Function File} {@var{s} =} rat (@var{x}, @var{tol})
+ at deftypefnx {Function File} {[@var{n}, @var{d}] =} rat (@var{x}, @var{tol})
+
+Find a rational approximation to @var{x} within the tolerance defined
+by @var{tol} using a continued fraction expansion.  For example,
+
+ at example
+ at group
+rat(pi) = 3 + 1/(7 + 1/16) = 355/113
+rat(e) = 3 + 1/(-4 + 1/(2 + 1/(5 + 1/(-2 + 1/(-7))))) 
+       = 1457/536
+ at end group
+ at end example
+
+Called with two arguments returns the numerator and denominator separately
+as two matrices.
+ at end deftypefn
+ at seealso{@ref{doc-rats,,rats}}
+
+
+ at c pr-output.cc
+ at anchor{doc-rats}
+ at deftypefn {Built-in Function} {} rats (@var{x}, @var{len})
+Convert @var{x} into a rational approximation represented as a string.
+You can convert the string back into a matrix as follows:
+
+ at example
+ at group
+   r = rats(hilb(4));
+   x = str2num(r)
+ at end group
+ at end example
+
+The optional second argument defines the maximum length of the string
+representing the elements of @var{x}.  By default @var{len} is 9.
+ at seealso{@ref{doc-format,,format}, @ref{doc-rat,,rat}}
+ at end deftypefn
+
+
+ at node C-Style I/O Functions
+ at section C-Style I/O Functions
+
+Octave's C-style input and output functions provide most of the
+functionality of the C programming language's standard I/O library.  The
+argument lists for some of the input functions are slightly different,
+however, because Octave has no way of passing arguments by reference.
+
+In the following, @var{file} refers to a file name and @code{fid} refers
+to an integer file number, as returned by @code{fopen}.
+
+There are three files that are always available.  Although these files
+can be accessed using their corresponding numeric file ids, you should
+always use the symbolic names given in the table below, since it will
+make your programs easier to understand.
+
+ at c file-io.cc
+ at anchor{doc-stdin}
+ at deftypefn {Built-in Function} {} stdin ()
+Return the numeric value corresponding to the standard input stream.
+When Octave is used interactively, this is filtered through the command
+line editing functions.
+ at seealso{@ref{doc-stdout,,stdout}, @ref{doc-stderr,,stderr}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-stdout}
+ at deftypefn {Built-in Function} {} stdout ()
+Return the numeric value corresponding to the standard output stream.
+Data written to the standard output is normally filtered through the pager.
+ at seealso{@ref{doc-stdin,,stdin}, @ref{doc-stderr,,stderr}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-stderr}
+ at deftypefn {Built-in Function} {} stderr ()
+Return the numeric value corresponding to the standard error stream.
+Even if paging is turned on, the standard error is not sent to the
+pager.  It is useful for error messages and prompts.
+ at seealso{@ref{doc-stdin,,stdin}, @ref{doc-stdout,,stdout}}
+ at end deftypefn
+
+
+ at menu
+* Opening and Closing Files::   
+* Simple Output::               
+* Line-Oriented Input::         
+* Formatted Output::            
+* Output Conversion for Matrices::  
+* Output Conversion Syntax::    
+* Table of Output Conversions::  
+* Integer Conversions::         
+* Floating-Point Conversions::
+* Other Output Conversions::    
+* Formatted Input::             
+* Input Conversion Syntax::     
+* Table of Input Conversions::  
+* Numeric Input Conversions::   
+* String Input Conversions::    
+* Binary I/O::                  
+* Temporary Files::             
+* EOF and Errors::              
+* File Positioning::            
+ at end menu
+
+ at node Opening and Closing Files
+ at subsection Opening and Closing Files
+
+When reading data from a file it must be opened for reading first, and
+likewise when writing to a file.  The @code{fopen} function returns a
+pointer to an open file that is ready to be read or written.  Once all
+data has been read from or written to the opened file it should be closed.
+The @code{fclose} function does this.  The following code illustrates
+the basic pattern for writing to a file, but a very similar pattern is
+used when reading a file.
+
+ at example
+ at group
+filename = "myfile.txt";
+fid = fopen (filename, "w");
+# Do the actual I/O here at dots{}
+fclose (fid);
+ at end group
+ at end example
+
+ at c file-io.cc
+ at anchor{doc-fopen}
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})
+ at deftypefnx {Built-in Function} {@var{fid_list} =} fopen ("all")
+ at deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})
+The first form of the @code{fopen} function opens the named file with
+the specified mode (read-write, read-only, etc.) and architecture
+interpretation (IEEE big endian, IEEE little endian, etc.), and returns
+an integer value that may be used to refer to the file later.  If an
+error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the
+corresponding system error message.  The @var{mode} is a one or two
+character string that specifies whether the file is to be opened for
+reading, writing, or both.
+
+The second form of the @code{fopen} function returns a vector of file ids
+corresponding to all the currently open files, excluding the
+ at code{stdin}, @code{stdout}, and @code{stderr} streams.
+
+The third form of the @code{fopen} function returns information about the
+open file given its file id.
+
+For example,
+
+ at example
+myfile = fopen ("splat.dat", "r", "ieee-le");
+ at end example
+
+ at noindent
+opens the file @file{splat.dat} for reading.  If necessary, binary
+numeric values will be read assuming they are stored in IEEE format with
+the least significant bit first, and then converted to the native
+representation.
+
+Opening a file that is already open simply opens it again and returns a
+separate file id.  It is not an error to open a file several times,
+though writing to the same file through several different file ids may
+produce unexpected results.
+
+The possible values @samp{mode} may have are
+
+ at table @asis
+ at item @samp{r}
+Open a file for reading.
+
+ at item @samp{w}
+Open a file for writing.  The previous contents are discarded.
+
+ at item @samp{a}
+Open or create a file for writing at the end of the file.
+
+ at item @samp{r+}
+Open an existing file for reading and writing.
+
+ at item @samp{w+}
+Open a file for reading or writing.  The previous contents are
+discarded.
+
+ at item @samp{a+}
+Open or create a file for reading or writing at the end of the
+file.
+ at end table
+
+Append a "t" to the mode string to open the file in text mode or a
+"b" to open in binary mode.  On Windows and Macintosh systems, text
+mode reading and writing automatically converts linefeeds to the
+appropriate line end character for the system (carriage-return linefeed
+on Windows, carriage-return on Macintosh).  The default if no mode is
+specified is binary mode.
+
+Additionally, you may append a "z" to the mode string to open a
+gzipped file for reading or writing.  For this to be successful, you
+must also open the file in binary mode.
+
+The parameter @var{arch} is a string specifying the default data format
+for the file.  Valid values for @var{arch} are:
+
+ at table @asis
+ at samp{native}
+The format of the current machine (this is the default).
+
+ at samp{ieee-be}
+IEEE big endian format.
+
+ at samp{ieee-le}
+IEEE little endian format.
+
+ at samp{vaxd}
+VAX D floating format.
+
+ at samp{vaxg}
+VAX G floating format.
+
+ at samp{cray}
+Cray floating format.
+ at end table
+
+ at noindent
+however, conversions are currently only supported for @samp{native}
+ at samp{ieee-be}, and @samp{ieee-le} formats.
+ at seealso{@ref{doc-fclose,,fclose}, @ref{doc-fgets,,fgets}, @ref{doc-fputs,,fputs}, @ref{doc-fread,,fread}, @ref{doc-fseek,,fseek}, @ref{doc-ferror,,ferror}, @ref{doc-fprintf,,fprintf}, @ref{doc-fscanf,,fscanf}, @ref{doc-ftell,,ftell}, @ref{doc-fwrite,,fwrite}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fclose}
+ at deftypefn {Built-in Function} {} fclose (@var{fid})
+Closes the specified file.  If successful, @code{fclose} returns 0,
+otherwise, it returns -1.
+ at seealso{@ref{doc-fopen,,fopen}, @ref{doc-fseek,,fseek}, @ref{doc-ftell,,ftell}}
+ at end deftypefn
+
+
+ at node Simple Output
+ at subsection Simple Output
+
+Once a file has been opened for writing a string can be written to the
+file using the @code{fputs} function.  The following example shows
+how to write the string @samp{Free Software is needed for Free Science}
+to the file @samp{free.txt}.
+
+ at example
+ at group
+filename = "free.txt";
+fid = fopen (filename, "w");
+fputs (fid, "Free Software is needed for Free Science");
+fclose (fid);
+ at end group
+ at end example
+
+ at c file-io.cc
+ at anchor{doc-fputs}
+ at deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})
+Write a string to a file with no formatting.
+
+Return a non-negative number on success and EOF on error.
+ at seealso{@ref{doc-scanf,,scanf}, @ref{doc-sscanf,,sscanf}, @ref{doc-fread,,fread}, @ref{doc-fprintf,,fprintf}, @ref{doc-fgets,,fgets}, @ref{doc-fscanf,,fscanf}}
+ at end deftypefn
+
+
+A function much similar to @code{fputs} is available for writing data
+to the screen.  The @code{puts} function works just like @code{fputs}
+except it doesn't take a file pointer as its input.
+
+ at c file-io.cc
+ at anchor{doc-puts}
+ at deftypefn {Built-in Function} {} puts (@var{string})
+Write a string to the standard output with no formatting.
+
+Return a non-negative number on success and EOF on error.
+ at end deftypefn
+
+
+ at node Line-Oriented Input
+ at subsection Line-Oriented Input
+
+To read from a file it must be opened for reading using @code{fopen}.
+Then a line can be read from the file using @code{fgetl} as the following
+code illustrates
+
+ at example
+ at group
+fid = fopen ("free.txt");
+txt = fgetl (fid)
+     @print{} Free Software is needed for Free Science
+fclose (fid);
+ at end group
+ at end example
+
+ at noindent
+This of course assumes that the file @samp{free.txt} exists and contains
+the line @samp{Free Software is needed for Free Science}.
+
+ at c file-io.cc
+ at anchor{doc-fgetl}
+ at deftypefn {Built-in Function} {} fgetl (@var{fid}, @var{len})
+Read characters from a file, stopping after a newline, or EOF,
+or @var{len} characters have been read.  The characters read, excluding
+the possible trailing newline, are returned as a string.
+
+If @var{len} is omitted, @code{fgetl} reads until the next newline
+character.
+
+If there are no more characters to read, @code{fgetl} returns @minus{}1.
+ at seealso{@ref{doc-fread,,fread}, @ref{doc-fscanf,,fscanf}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fgets}
+ at deftypefn {Built-in Function} {} fgets (@var{fid}, @var{len})
+Read characters from a file, stopping after a newline, or EOF,
+or @var{len} characters have been read.  The characters read, including
+the possible trailing newline, are returned as a string.
+
+If @var{len} is omitted, @code{fgets} reads until the next newline
+character.
+
+If there are no more characters to read, @code{fgets} returns @minus{}1.
+ at seealso{@ref{doc-fputs,,fputs}, @ref{doc-fopen,,fopen}, @ref{doc-fread,,fread}, @ref{doc-fscanf,,fscanf}}
+ at end deftypefn
+
+
+ at node Formatted Output
+ at subsection Formatted Output
+
+This section describes how to call @code{printf} and related functions.
+
+The following functions are available for formatted output.  They are
+modelled after the C language functions of the same name, but they
+interpret the format template differently in order to improve the
+performance of printing vector and matrix values.
+
+ at c file-io.cc
+ at anchor{doc-printf}
+ at deftypefn {Built-in Function} {} printf (@var{template}, @dots{})
+Print optional arguments under the control of the template string
+ at var{template} to the stream @code{stdout} and return the number of
+characters printed.
+ at ifclear OCTAVE_MANUAL
+
+See the Formatted Output section of the GNU Octave manual for a
+complete description of the syntax of the template string.
+ at end ifclear
+ at seealso{@ref{doc-fprintf,,fprintf}, @ref{doc-sprintf,,sprintf}, @ref{doc-scanf,,scanf}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fprintf}
+ at deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})
+This function is just like @code{printf}, except that the output is
+written to the stream @var{fid} instead of @code{stdout}.
+If @var{fid} is omitted, the output is written to @code{stdout}.
+ at seealso{@ref{doc-printf,,printf}, @ref{doc-sprintf,,sprintf}, @ref{doc-fread,,fread}, @ref{doc-fscanf,,fscanf}, @ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-sprintf}
+ at deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})
+This is like @code{printf}, except that the output is returned as a
+string.  Unlike the C library function, which requires you to provide a
+suitably sized string as an argument, Octave's @code{sprintf} function
+returns the string, automatically sized to hold all of the items
+converted.
+ at seealso{@ref{doc-printf,,printf}, @ref{doc-fprintf,,fprintf}, @ref{doc-sscanf,,sscanf}}
+ at end deftypefn
+
+
+The @code{printf} function can be used to print any number of arguments.
+The template string argument you supply in a call provides
+information not only about the number of additional arguments, but also
+about their types and what style should be used for printing them.
+
+Ordinary characters in the template string are simply written to the
+output stream as-is, while @dfn{conversion specifications} introduced by
+a @samp{%} character in the template cause subsequent arguments to be
+formatted and written to the output stream.  For example,
+ at cindex conversion specifications (@code{printf})
+
+ at example
+ at group
+pct = 37;
+filename = "foo.txt";
+printf ("Processed %d%% of `%s'.\nPlease be patient.\n",
+        pct, filename);
+ at end group
+ at end example
+
+ at noindent
+produces output like
+
+ at example
+ at group
+Processed 37% of `foo.txt'.
+Please be patient.
+ at end group
+ at end example
+
+This example shows the use of the @samp{%d} conversion to specify that a
+scalar argument should be printed in decimal notation, the @samp{%s}
+conversion to specify printing of a string argument, and the @samp{%%}
+conversion to print a literal @samp{%} character.
+
+There are also conversions for printing an integer argument as an
+unsigned value in octal, decimal, or hexadecimal radix (@samp{%o},
+ at samp{%u}, or @samp{%x}, respectively); or as a character value
+(@samp{%c}).
+
+Floating-point numbers can be printed in normal, fixed-point notation
+using the @samp{%f} conversion or in exponential notation using the
+ at samp{%e} conversion.  The @samp{%g} conversion uses either @samp{%e}
+or @samp{%f} format, depending on what is more appropriate for the
+magnitude of the particular number.
+
+You can control formatting more precisely by writing @dfn{modifiers}
+between the @samp{%} and the character that indicates which conversion
+to apply.  These slightly alter the ordinary behavior of the conversion.
+For example, most conversion specifications permit you to specify a
+minimum field width and a flag indicating whether you want the result
+left- or right-justified within the field.
+
+The specific flags and modifiers that are permitted and their
+interpretation vary depending on the particular conversion.  They're all
+described in more detail in the following sections.
+
+ at node Output Conversion for Matrices
+ at subsection Output Conversion for Matrices
+
+When given a matrix value, Octave's formatted output functions cycle
+through the format template until all the values in the matrix have been
+printed.  For example,
+
+ at example
+ at group
+printf ("%4.2f %10.2e %8.4g\n", hilb (3));
+
+     @print{} 1.00   5.00e-01   0.3333
+     @print{} 0.50   3.33e-01     0.25
+     @print{} 0.33   2.50e-01      0.2
+ at end group
+ at end example
+
+If more than one value is to be printed in a single call, the output
+functions do not return to the beginning of the format template when
+moving on from one value to the next.  This can lead to confusing output
+if the number of elements in the matrices are not exact multiples of the
+number of conversions in the format template.  For example,
+
+ at example
+ at group
+printf ("%4.2f %10.2e %8.4g\n", [1, 2], [3, 4]);
+
+     @print{} 1.00   2.00e+00        3
+     @print{} 4.00
+ at end group
+ at end example
+
+If this is not what you want, use a series of calls instead of just one.
+
+ at node Output Conversion Syntax
+ at subsection Output Conversion Syntax
+
+This section provides details about the precise syntax of conversion
+specifications that can appear in a @code{printf} template
+string.
+
+Characters in the template string that are not part of a
+conversion specification are printed as-is to the output stream.
+
+The conversion specifications in a @code{printf} template string have
+the general form:
+
+ at example
+% @var{flags} @var{width} @r{[} . @var{precision} @r{]} @var{type} @var{conversion}
+ at end example
+
+For example, in the conversion specifier @samp{%-10.8ld}, the @samp{-}
+is a flag, @samp{10} specifies the field width, the precision is
+ at samp{8}, the letter @samp{l} is a type modifier, and @samp{d} specifies
+the conversion style.  (This particular type specifier says to print a
+numeric argument in decimal notation, with a minimum of 8 digits
+left-justified in a field at least 10 characters wide.)
+
+In more detail, output conversion specifications consist of an
+initial @samp{%} character followed in sequence by:
+
+ at itemize @bullet
+ at item 
+Zero or more @dfn{flag characters} that modify the normal behavior of
+the conversion specification.
+ at cindex flag character (@code{printf})
+
+ at item 
+An optional decimal integer specifying the @dfn{minimum field width}.
+If the normal conversion produces fewer characters than this, the field
+is padded with spaces to the specified width.  This is a @emph{minimum}
+value; if the normal conversion produces more characters than this, the
+field is @emph{not} truncated.  Normally, the output is right-justified
+within the field.
+ at cindex minimum field width (@code{printf})
+
+You can also specify a field width of @samp{*}.  This means that the
+next argument in the argument list (before the actual value to be
+printed) is used as the field width.  The value is rounded to the
+nearest integer.  If the value is negative, this means to set the
+ at samp{-} flag (see below) and to use the absolute value as the field
+width.
+
+ at item 
+An optional @dfn{precision} to specify the number of digits to be
+written for the numeric conversions.  If the precision is specified, it
+consists of a period (@samp{.}) followed optionally by a decimal integer
+(which defaults to zero if omitted).
+ at cindex precision (@code{printf})
+
+You can also specify a precision of @samp{*}.  This means that the next
+argument in the argument list (before the actual value to be printed) is
+used as the precision.  The value must be an integer, and is ignored
+if it is negative.
+
+ at item
+An optional @dfn{type modifier character}.  This character is ignored by
+Octave's @code{printf} function, but is recognized to provide
+compatibility with the C language @code{printf}.
+
+ at item
+A character that specifies the conversion to be applied.
+ at end itemize
+
+The exact options that are permitted and how they are interpreted vary 
+between the different conversion specifiers.  See the descriptions of the
+individual conversions for information about the particular options that
+they use.
+
+ at node Table of Output Conversions
+ at subsection Table of Output Conversions
+ at cindex output conversions, for @code{printf}
+
+Here is a table summarizing what all the different conversions do:
+
+ at table @asis
+ at item @samp{%d}, @samp{%i}
+Print an integer as a signed decimal number.  @xref{Integer
+Conversions}, for details.  @samp{%d} and @samp{%i} are synonymous for
+output, but are different when used with @code{scanf} for input
+(@pxref{Table of Input Conversions}).
+
+ at item @samp{%o}
+Print an integer as an unsigned octal number.  @xref{Integer
+Conversions}, for details.
+
+ at item @samp{%u}
+Print an integer as an unsigned decimal number.  @xref{Integer
+Conversions}, for details.
+
+ at item @samp{%x}, @samp{%X}
+Print an integer as an unsigned hexadecimal number.  @samp{%x} uses
+lower-case letters and @samp{%X} uses upper-case.  @xref{Integer
+Conversions}, for details.
+
+ at item @samp{%f}
+Print a floating-point number in normal (fixed-point) notation.
+ at xref{Floating-Point Conversions}, for details.
+
+ at item @samp{%e}, @samp{%E}
+Print a floating-point number in exponential notation.  @samp{%e} uses
+lower-case letters and @samp{%E} uses upper-case.  @xref{Floating-Point
+Conversions}, for details.
+
+ at item @samp{%g}, @samp{%G}
+Print a floating-point number in either normal (fixed-point) or
+exponential notation, whichever is more appropriate for its magnitude.
+ at samp{%g} uses lower-case letters and @samp{%G} uses upper-case.
+ at xref{Floating-Point Conversions}, for details.
+
+ at item @samp{%c}
+Print a single character.  @xref{Other Output Conversions}.
+
+ at item @samp{%s}
+Print a string.  @xref{Other Output Conversions}.
+
+ at item @samp{%%}
+Print a literal @samp{%} character.  @xref{Other Output Conversions}.
+ at end table
+
+If the syntax of a conversion specification is invalid, unpredictable
+things will happen, so don't do this.  If there aren't enough function
+arguments provided to supply values for all the conversion
+specifications in the template string, or if the arguments are not of
+the correct types, the results are unpredictable.  If you supply more
+arguments than conversion specifications, the extra argument values are
+simply ignored; this is sometimes useful.
+
+ at node Integer Conversions
+ at subsection Integer Conversions
+
+This section describes the options for the @samp{%d}, @samp{%i},
+ at samp{%o}, @samp{%u}, @samp{%x}, and @samp{%X} conversion
+specifications.  These conversions print integers in various formats.
+
+The @samp{%d} and @samp{%i} conversion specifications both print an
+numeric argument as a signed decimal number; while @samp{%o},
+ at samp{%u}, and @samp{%x} print the argument as an unsigned octal,
+decimal, or hexadecimal number (respectively).  The @samp{%X} conversion
+specification is just like @samp{%x} except that it uses the characters
+ at samp{ABCDEF} as digits instead of @samp{abcdef}.
+
+The following flags are meaningful:
+
+ at table @asis
+ at item @samp{-}
+Left-justify the result in the field (instead of the normal
+right-justification).
+
+ at item @samp{+}
+For the signed @samp{%d} and @samp{%i} conversions, print a
+plus sign if the value is positive.
+
+ at item @samp{ }
+For the signed @samp{%d} and @samp{%i} conversions, if the result
+doesn't start with a plus or minus sign, prefix it with a space
+character instead.  Since the @samp{+} flag ensures that the result
+includes a sign, this flag is ignored if you supply both of them.
+
+ at item @samp{#}
+For the @samp{%o} conversion, this forces the leading digit to be
+ at samp{0}, as if by increasing the precision.  For @samp{%x} or
+ at samp{%X}, this prefixes a leading @samp{0x} or @samp{0X} (respectively)
+to the result.  This doesn't do anything useful for the @samp{%d},
+ at samp{%i}, or @samp{%u} conversions.
+
+ at item @samp{0}
+Pad the field with zeros instead of spaces.  The zeros are placed after
+any indication of sign or base.  This flag is ignored if the @samp{-}
+flag is also specified, or if a precision is specified.
+ at end table
+
+If a precision is supplied, it specifies the minimum number of digits to
+appear; leading zeros are produced if necessary.  If you don't specify a
+precision, the number is printed with as many digits as it needs.  If
+you convert a value of zero with an explicit precision of zero, then no
+characters at all are produced.
+
+ at node Floating-Point Conversions
+ at subsection Floating-Point Conversions
+
+This section discusses the conversion specifications for floating-point
+numbers: the @samp{%f}, @samp{%e}, @samp{%E}, @samp{%g}, and @samp{%G}
+conversions.
+
+The @samp{%f} conversion prints its argument in fixed-point notation,
+producing output of the form
+ at w{[@code{-}]@var{ddd}@code{.}@var{ddd}},
+where the number of digits following the decimal point is controlled
+by the precision you specify.
+
+The @samp{%e} conversion prints its argument in exponential notation,
+producing output of the form
+ at w{[@code{-}]@var{d}@code{.}@var{ddd}@code{e}[@code{+}|@code{-}]@var{dd}}.
+Again, the number of digits following the decimal point is controlled by
+the precision.  The exponent always contains at least two digits.  The
+ at samp{%E} conversion is similar but the exponent is marked with the letter
+ at samp{E} instead of @samp{e}.
+
+The @samp{%g} and @samp{%G} conversions print the argument in the style
+of @samp{%e} or @samp{%E} (respectively) if the exponent would be less
+than -4 or greater than or equal to the precision; otherwise they use the
+ at samp{%f} style.  Trailing zeros are removed from the fractional portion
+of the result and a decimal-point character appears only if it is
+followed by a digit.
+
+The following flags can be used to modify the behavior:
+
+ at c Not @samp so we can have ` ' as an item.
+ at table @asis
+ at item @samp{-}
+Left-justify the result in the field.  Normally the result is
+right-justified.
+
+ at item @samp{+}
+Always include a plus or minus sign in the result.
+
+ at item @samp{ }
+If the result doesn't start with a plus or minus sign, prefix it with a
+space instead.  Since the @samp{+} flag ensures that the result includes
+a sign, this flag is ignored if you supply both of them.
+
+ at item @samp{#}
+Specifies that the result should always include a decimal point, even
+if no digits follow it.  For the @samp{%g} and @samp{%G} conversions,
+this also forces trailing zeros after the decimal point to be left
+in place where they would otherwise be removed.
+
+ at item @samp{0}
+Pad the field with zeros instead of spaces; the zeros are placed
+after any sign.  This flag is ignored if the @samp{-} flag is also
+specified.
+ at end table
+
+The precision specifies how many digits follow the decimal-point
+character for the @samp{%f}, @samp{%e}, and @samp{%E} conversions.  For
+these conversions, the default precision is @code{6}.  If the precision
+is explicitly @code{0}, this suppresses the decimal point character
+entirely.  For the @samp{%g} and @samp{%G} conversions, the precision
+specifies how many significant digits to print.  Significant digits are
+the first digit before the decimal point, and all the digits after it.
+If the precision is @code{0} or not specified for @samp{%g} or
+ at samp{%G}, it is treated like a value of @code{1}.  If the value being
+printed cannot be expressed precisely in the specified number of digits,
+the value is rounded to the nearest number that fits.
+
+ at node Other Output Conversions
+ at subsection Other Output Conversions
+
+This section describes miscellaneous conversions for @code{printf}.
+
+The @samp{%c} conversion prints a single character.  The @samp{-} 
+flag can be used to specify left-justification in the field, but no
+other flags are defined, and no precision or type modifier can be given.
+For example:
+
+ at example
+printf ("%c%c%c%c%c", "h", "e", "l", "l", "o");
+ at end example
+
+ at noindent
+prints @samp{hello}.
+
+The @samp{%s} conversion prints a string.  The corresponding argument
+must be a string.  A precision can be specified to indicate the maximum
+number of characters to write; otherwise characters in the string up to
+but not including the terminating null character are written to the
+output stream.  The @samp{-} flag can be used to specify
+left-justification in the field, but no other flags or type modifiers
+are defined for this conversion.  For example:
+
+ at example
+printf ("%3s%-6s", "no", "where");
+ at end example
+
+ at noindent
+prints @samp{ nowhere } (note the leading and trailing spaces).
+
+ at node Formatted Input
+ at subsection Formatted Input
+
+Octave provides the @code{scanf}, @code{fscanf}, and @code{sscanf}
+functions to read formatted input.  There are two forms of each of these
+functions.  One can be used to extract vectors of data from a file, and
+the other is more `C-like'.
+
+ at c file-io.cc
+ at anchor{doc-fscanf}
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{size})
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} fscanf (@var{fid}, @var{template}, "C")
+In the first form, read from @var{fid} according to @var{template},
+returning the result in the matrix @var{val}.
+
+The optional argument @var{size} specifies the amount of data to read
+and may be one of
+
+ at table @code
+ at item Inf
+Read as much as possible, returning a column vector.
+
+ at item @var{nr}
+Read up to @var{nr} elements, returning a column vector.
+
+ at item [@var{nr}, Inf]
+Read as much as possible, returning a matrix with @var{nr} rows.  If the
+number of elements read is not an exact multiple of @var{nr}, the last
+column is padded with zeros.
+
+ at item [@var{nr}, @var{nc}]
+Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with
+ at var{nr} rows.  If the number of elements read is not an exact multiple
+of @var{nr}, the last column is padded with zeros.
+ at end table
+
+ at noindent
+If @var{size} is omitted, a value of @code{Inf} is assumed.
+
+A string is returned if @var{template} specifies only character
+conversions.
+
+The number of items successfully read is returned in @var{count}.
+
+In the second form, read from @var{fid} according to @var{template},
+with each conversion specifier in @var{template} corresponding to a
+single scalar return value.  This form is more `C-like', and also
+compatible with previous versions of Octave.  The number of successful
+conversions is returned in @var{count}
+ at ifclear OCTAVE_MANUAL
+
+See the Formatted Input section of the GNU Octave manual for a
+complete description of the syntax of the template string.
+ at end ifclear
+ at seealso{@ref{doc-scanf,,scanf}, @ref{doc-sscanf,,sscanf}, @ref{doc-fread,,fread}, @ref{doc-fprintf,,fprintf}, @ref{doc-fgets,,fgets}, @ref{doc-fputs,,fputs}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-scanf}
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} scanf (@var{template}, @var{size})
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] =} scanf (@var{template}, "C")
+This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.
+
+It is currently not useful to call @code{scanf} in interactive
+programs.
+ at seealso{@ref{doc-fscanf,,fscanf}, @ref{doc-sscanf,,sscanf}, @ref{doc-printf,,printf}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-sscanf}
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{size})
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} sscanf (@var{string}, @var{template}, "C")
+This is like @code{fscanf}, except that the characters are taken from the
+string @var{string} instead of from a stream.  Reaching the end of the
+string is treated as an end-of-file condition.
+ at seealso{@ref{doc-fscanf,,fscanf}, @ref{doc-scanf,,scanf}, @ref{doc-sprintf,,sprintf}}
+ at end deftypefn
+
+
+Calls to @code{scanf} are superficially similar to calls to
+ at code{printf} in that arbitrary arguments are read under the control of
+a template string.  While the syntax of the conversion specifications in
+the template is very similar to that for @code{printf}, the
+interpretation of the template is oriented more towards free-format
+input and simple pattern matching, rather than fixed-field formatting.
+For example, most @code{scanf} conversions skip over any amount of
+``white space'' (including spaces, tabs, and newlines) in the input
+file, and there is no concept of precision for the numeric input
+conversions as there is for the corresponding output conversions.
+Ordinarily, non-whitespace characters in the template are expected to
+match characters in the input stream exactly.
+ at cindex conversion specifications (@code{scanf})
+
+When a @dfn{matching failure} occurs, @code{scanf} returns immediately,
+leaving the first non-matching character as the next character to be
+read from the stream, and @code{scanf} returns all the items that were
+successfully converted.
+ at cindex matching failure, in @code{scanf}
+
+The formatted input functions are not used as frequently as the
+formatted output functions.  Partly, this is because it takes some care
+to use them properly.  Another reason is that it is difficult to recover
+from a matching error.
+
+ at node Input Conversion Syntax
+ at subsection Input Conversion Syntax
+
+A @code{scanf} template string is a string that contains ordinary
+multibyte characters interspersed with conversion specifications that
+start with @samp{%}.
+
+Any whitespace character in the template causes any number of whitespace
+characters in the input stream to be read and discarded.  The whitespace
+characters that are matched need not be exactly the same whitespace
+characters that appear in the template string.  For example, write
+ at samp{ , } in the template to recognize a comma with optional whitespace
+before and after.
+
+Other characters in the template string that are not part of conversion
+specifications must match characters in the input stream exactly; if
+this is not the case, a matching failure occurs.
+
+The conversion specifications in a @code{scanf} template string
+have the general form:
+
+ at example
+% @var{flags} @var{width} @var{type} @var{conversion}
+ at end example
+
+In more detail, an input conversion specification consists of an initial
+ at samp{%} character followed in sequence by:
+
+ at itemize @bullet
+ at item
+An optional @dfn{flag character} @samp{*}, which says to ignore the text
+read for this specification.  When @code{scanf} finds a conversion
+specification that uses this flag, it reads input as directed by the
+rest of the conversion specification, but it discards this input, does
+not return any value, and does not increment the count of
+successful assignments.
+ at cindex flag character (@code{scanf})
+
+ at item
+An optional decimal integer that specifies the @dfn{maximum field
+width}.  Reading of characters from the input stream stops either when
+this maximum is reached or when a non-matching character is found,
+whichever happens first.  Most conversions discard initial whitespace
+characters, and these discarded characters don't count towards the
+maximum field width.  Conversions that do not discard initial whitespace
+are explicitly documented.
+ at cindex maximum field width (@code{scanf})
+
+ at item
+An optional type modifier character.  This character is ignored by
+Octave's @code{scanf} function, but is recognized to provide
+compatibility with the C language @code{scanf}.
+
+ at item
+A character that specifies the conversion to be applied.
+ at end itemize
+
+The exact options that are permitted and how they are interpreted vary 
+between the different conversion specifiers.  See the descriptions of the
+individual conversions for information about the particular options that
+they allow.
+
+ at node Table of Input Conversions
+ at subsection Table of Input Conversions
+ at cindex input conversions, for @code{scanf}
+
+Here is a table that summarizes the various conversion specifications:
+
+ at table @asis
+ at item @samp{%d}
+Matches an optionally signed integer written in decimal.  @xref{Numeric
+Input Conversions}.
+
+ at item @samp{%i}
+Matches an optionally signed integer in any of the formats that the C
+language defines for specifying an integer constant.  @xref{Numeric
+Input Conversions}.
+
+ at item @samp{%o}
+Matches an unsigned integer written in octal radix.
+ at xref{Numeric Input Conversions}.
+
+ at item @samp{%u}
+Matches an unsigned integer written in decimal radix.
+ at xref{Numeric Input Conversions}.
+
+ at item @samp{%x}, @samp{%X}
+Matches an unsigned integer written in hexadecimal radix.
+ at xref{Numeric Input Conversions}.
+
+ at item @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, @samp{%G}
+Matches an optionally signed floating-point number.  @xref{Numeric Input
+Conversions}.
+
+ at item @samp{%s}
+Matches a string containing only non-whitespace characters.
+ at xref{String Input Conversions}.
+
+ at item @samp{%c}
+Matches a string of one or more characters; the number of characters
+read is controlled by the maximum field width given for the conversion.
+ at xref{String Input Conversions}.
+
+ at item @samp{%%}
+This matches a literal @samp{%} character in the input stream.  No
+corresponding argument is used.
+ at end table
+
+If the syntax of a conversion specification is invalid, the behavior is
+undefined.  If there aren't enough function arguments provided to supply
+addresses for all the conversion specifications in the template strings
+that perform assignments, or if the arguments are not of the correct
+types, the behavior is also undefined.  On the other hand, extra
+arguments are simply ignored.
+
+ at node Numeric Input Conversions
+ at subsection Numeric Input Conversions
+
+This section describes the @code{scanf} conversions for reading numeric
+values.
+
+The @samp{%d} conversion matches an optionally signed integer in decimal
+radix.
+
+The @samp{%i} conversion matches an optionally signed integer in any of
+the formats that the C language defines for specifying an integer
+constant.
+
+For example, any of the strings @samp{10}, @samp{0xa}, or @samp{012}
+could be read in as integers under the @samp{%i} conversion.  Each of
+these specifies a number with decimal value @code{10}.
+
+The @samp{%o}, @samp{%u}, and @samp{%x} conversions match unsigned
+integers in octal, decimal, and hexadecimal radices, respectively.
+
+The @samp{%X} conversion is identical to the @samp{%x} conversion.  They
+both permit either uppercase or lowercase letters to be used as digits.
+
+Unlike the C language @code{scanf}, Octave ignores the @samp{h},
+ at samp{l}, and @samp{L} modifiers.
+
+ at node String Input Conversions
+ at subsection String Input Conversions
+
+This section describes the @code{scanf} input conversions for reading
+string and character values: @samp{%s} and @samp{%c}.  
+
+The @samp{%c} conversion is the simplest: it matches a fixed number of
+characters, always.  The maximum field with says how many characters to
+read; if you don't specify the maximum, the default is 1.  This
+conversion does not skip over initial whitespace characters.  It reads
+precisely the next @var{n} characters, and fails if it cannot get that
+many.
+
+The @samp{%s} conversion matches a string of non-whitespace characters.
+It skips and discards initial whitespace, but stops when it encounters
+more whitespace after having read something.
+
+For example, reading the input:
+
+ at example
+ hello, world
+ at end example
+
+ at noindent
+with the conversion @samp{%10c} produces @code{" hello, wo"}, but
+reading the same input with the conversion @samp{%10s} produces
+ at code{"hello,"}.
+
+ at node Binary I/O
+ at subsection Binary I/O
+
+Octave can read and write binary data using the functions @code{fread}
+and @code{fwrite}, which are patterned after the standard C functions
+with the same names.  They are able to automatically swap the byte order
+of integer data and convert among the supported floating point formats
+as the data are read.
+
+ at c file-io.cc
+ at anchor{doc-fread}
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})
+Read binary data of type @var{precision} from the specified file ID
+ at var{fid}.
+
+The optional argument @var{size} specifies the amount of data to read
+and may be one of
+
+ at table @code
+ at item Inf
+Read as much as possible, returning a column vector.
+
+ at item @var{nr}
+Read up to @var{nr} elements, returning a column vector.
+
+ at item [@var{nr}, Inf]
+Read as much as possible, returning a matrix with @var{nr} rows.  If the
+number of elements read is not an exact multiple of @var{nr}, the last
+column is padded with zeros.
+
+ at item [@var{nr}, @var{nc}]
+Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with
+ at var{nr} rows.  If the number of elements read is not an exact multiple
+of @var{nr}, the last column is padded with zeros.
+ at end table
+
+ at noindent
+If @var{size} is omitted, a value of @code{Inf} is assumed.
+
+The optional argument @var{precision} is a string specifying the type of
+data to read and may be one of
+
+ at table @code
+ at item "schar"
+ at itemx "signed char"
+Signed character.
+
+ at item "uchar"
+ at itemx "unsigned char"
+Unsigned character.
+
+ at item "int8"
+ at itemx "integer*1"
+
+8-bit signed integer.
+
+ at item "int16"
+ at itemx "integer*2"
+16-bit signed integer.
+
+ at item "int32"
+ at itemx "integer*4"
+32-bit signed integer.
+
+ at item "int64"
+ at itemx "integer*8"
+64-bit signed integer.
+
+ at item "uint8"
+8-bit unsigned integer.
+
+ at item "uint16"
+16-bit unsigned integer.
+
+ at item "uint32"
+32-bit unsigned integer.
+
+ at item "uint64"
+64-bit unsigned integer.
+
+ at item "single"
+ at itemx "float32"
+ at itemx "real*4"
+32-bit floating point number.
+
+ at item "double"
+ at itemx "float64"
+ at itemx "real*8"
+64-bit floating point number.
+
+ at item "char"
+ at itemx "char*1"
+Single character.
+
+ at item "short"
+Short integer (size is platform dependent).
+
+ at item "int"
+Integer (size is platform dependent).
+
+ at item "long"
+Long integer (size is platform dependent).
+
+ at item "ushort"
+ at itemx "unsigned short"
+Unsigned short integer (size is platform dependent).
+
+ at item "uint"
+ at itemx "unsigned int"
+Unsigned integer (size is platform dependent).
+
+ at item "ulong"
+ at itemx "unsigned long"
+Unsigned long integer (size is platform dependent).
+
+ at item "float"
+Single precision floating point number (size is platform dependent).
+ at end table
+
+ at noindent
+The default precision is @code{"uchar"}.
+
+The @var{precision} argument may also specify an optional repeat
+count.  For example, @samp{32*single} causes @code{fread} to read
+a block of 32 single precision floating point numbers.  Reading in
+blocks is useful in combination with the @var{skip} argument.
+
+The @var{precision} argument may also specify a type conversion.
+For example, @samp{int16=>int32} causes @code{fread} to read 16-bit
+integer values and return an array of 32-bit integer values.  By
+default, @code{fread} returns a double precision array.  The special
+form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.
+
+The conversion and repeat counts may be combined.  For example, the
+specification @samp{32*single=>single} causes @code{fread} to read
+blocks of single precision floating point values and return an array
+of single precision values instead of the default array of double
+precision values.
+
+The optional argument @var{skip} specifies the number of bytes to skip
+after each element (or block of elements) is read.  If it is not
+specified, a value of 0 is assumed.  If the final block read is not
+complete, the final skip is omitted.  For example,
+
+ at example
+fread (f, 10, "3*single=>single", 8)
+ at end example
+
+ at noindent
+will omit the final 8-byte skip because the last read will not be
+a complete block of 3 values.
+
+The optional argument @var{arch} is a string specifying the data format
+for the file.  Valid values are
+
+ at table @code
+ at item "native"
+The format of the current machine.
+
+ at item "ieee-be"
+IEEE big endian.
+
+ at item "ieee-le"
+IEEE little endian.
+
+ at item "vaxd"
+VAX D floating format.
+
+ at item "vaxg"
+VAX G floating format.
+
+ at item "cray"
+Cray floating format.
+ at end table
+
+ at noindent
+Conversions are currently only supported for @code{"ieee-be"} and
+ at code{"ieee-le"} formats.
+
+The data read from the file is returned in @var{val}, and the number of
+values read is returned in @code{count}
+ at seealso{@ref{doc-fwrite,,fwrite}, @ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fwrite}
+ at deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})
+Write data in binary form of type @var{precision} to the specified file
+ID @var{fid}, returning the number of values successfully written to the
+file.
+
+The argument @var{data} is a matrix of values that are to be written to
+the file.  The values are extracted in column-major order.
+
+The remaining arguments @var{precision}, @var{skip}, and @var{arch} are
+optional, and are interpreted as described for @code{fread}.
+
+The behavior of @code{fwrite} is undefined if the values in @var{data}
+are too large to fit in the specified precision.
+ at seealso{@ref{doc-fread,,fread}, @ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at node Temporary Files
+ at subsection Temporary Files
+
+Sometimes one needs to write data to a file that is only temporary.
+This is most commonly used when an external program launched from
+within Octave needs to access data.  When Octave exits all temporary
+files will be deleted, so this step need not be executed manually.
+
+ at c file-io.cc
+ at anchor{doc-mkstemp}
+ at deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})
+Return the file ID corresponding to a new temporary file with a unique
+name created from @var{template}.  The last six characters of @var{template}
+must be @code{XXXXXX} and these are replaced with a string that makes the
+filename unique.  The file is then created with mode read/write and
+permissions that are system dependent (on GNU/Linux systems, the permissions
+will be 0600 for versions of glibc 2.0.7 and later).  The file is opened
+with the @w{@code{O_EXCL}} flag.
+
+If the optional argument @var{delete} is supplied and is true,
+the file will be deleted automatically when Octave exits, or when
+the function @code{purge_tmp_files} is called.
+
+If successful, @var{fid} is a valid file ID, @var{name} is the name of
+the file, and @var{msg} is an empty string.  Otherwise, @var{fid}
+is -1, @var{name} is empty, and @var{msg} contains a system-dependent
+error message.
+ at seealso{@ref{doc-tmpfile,,tmpfile}, @ref{doc-tmpnam,,tmpnam}, @ref{doc-P_tmpdir,,P_tmpdir}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-tmpfile}
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()
+Return the file ID corresponding to a new temporary file with a unique
+name.  The file is opened in binary read/write (@code{"w+b"}) mode.
+The file will be deleted automatically when it is closed or when Octave
+exits.
+
+If successful, @var{fid} is a valid file ID and @var{msg} is an empty
+string.  Otherwise, @var{fid} is -1 and @var{msg} contains a
+system-dependent error message.
+ at seealso{@ref{doc-tmpnam,,tmpnam}, @ref{doc-mkstemp,,mkstemp}, @ref{doc-P_tmpdir,,P_tmpdir}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-tmpnam}
+ at deftypefn {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})
+Return a unique temporary file name as a string.
+
+If @var{prefix} is omitted, a value of @code{"oct-"} is used.
+If @var{dir} is also omitted, the default directory for temporary files
+is used.  If @var{dir} is provided, it must exist, otherwise the default
+directory for temporary files is used.  Since the named file is not
+opened, by @code{tmpnam}, it is possible (though relatively unlikely)
+that it will not be available by the time your program attempts to open it.
+ at seealso{@ref{doc-tmpfile,,tmpfile}, @ref{doc-mkstemp,,mkstemp}, @ref{doc-P_tmpdir,,P_tmpdir}}
+ at end deftypefn
+
+
+
+
+ at node EOF and Errors, File Positioning, Temporary Files, C-Style I/O Functions
+ at subsection End of File and Errors
+
+Once a file has been opened its status can be acquired.  As an example
+the @code{feof} functions determines if the end of the file has been
+reached.  This can be very useful when reading small parts of a file
+at a time.  The following example shows how to read one line at a time
+from a file until the end has been reached.
+
+ at example
+ at group
+filename = "myfile.txt";
+fid = fopen (filename, "r");
+while (! feof (fid) )
+  text_line = fgetl (fid);
+endwhile
+fclose (fid);
+ at end group
+ at end example
+
+ at noindent
+Note that in some situations it is more efficient to read the entire
+contents of a file and then process it, than it is to read it line by
+line.  This has the potential advantage of removing the loop in the
+above code.
+
+ at c file-io.cc
+ at anchor{doc-feof}
+ at deftypefn {Built-in Function} {} feof (@var{fid})
+Return 1 if an end-of-file condition has been encountered for a given
+file and 0 otherwise.  Note that it will only return 1 if the end of the
+file has already been encountered, not if the next read operation will
+result in an end-of-file condition.
+ at seealso{@ref{doc-fread,,fread}, @ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-ferror}
+ at deftypefn {Built-in Function} {} ferror (@var{fid})
+Return 1 if an error condition has been encountered for a given file
+and 0 otherwise.  Note that it will only return 1 if an error has
+already been encountered, not if the next operation will result in an
+error condition.
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fclear}
+ at deftypefn {Built-in Function} {} fclear (@var{fid})
+Clear the stream state for the specified file.
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-freport}
+ at deftypefn {Built-in Function} {} freport ()
+Print a list of which files have been opened, and whether they are open
+for reading, writing, or both.  For example,
+
+ at example
+ at group
+freport ()
+
+     @print{}  number  mode  name
+     @print{} 
+     @print{}       0     r  stdin
+     @print{}       1     w  stdout
+     @print{}       2     w  stderr
+     @print{}       3     r  myfile
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at node File Positioning
+ at subsection File Positioning
+
+Three functions are available for setting and determining the position of
+the file pointer for a given file.
+
+ at c file-io.cc
+ at anchor{doc-ftell}
+ at deftypefn {Built-in Function} {} ftell (@var{fid})
+Return the position of the file pointer as the number of characters
+from the beginning of the file @var{fid}.
+ at seealso{@ref{doc-fseek,,fseek}, @ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-fseek}
+ at deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})
+Set the file pointer to any location within the file @var{fid}.
+
+The pointer is positioned @var{offset} characters from the @var{origin},
+which may be one of the predefined variables @w{@code{SEEK_CUR}} (current
+position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of
+file) or strings "cof", "bof" or "eof".  If @var{origin} is omitted,
+ at w{@code{SEEK_SET}} is assumed.  The offset must be zero, or a value returned
+by @code{ftell} (in which case @var{origin} must be @w{@code{SEEK_SET}}).
+
+Return 0 on success and -1 on error.
+ at seealso{@ref{doc-ftell,,ftell}, @ref{doc-fopen,,fopen}, @ref{doc-fclose,,fclose}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-SEEK_SET}
+ at deftypefn {Built-in Function} {} SEEK_SET ()
+ at deftypefnx {Built-in Function} {} SEEK_CUR ()
+ at deftypefnx {Built-in Function} {} SEEK_END ()
+Return the value required to request that @code{fseek} perform
+one of the following actions:
+ at table @code
+ at item SEEK_SET
+Position file relative to the beginning.
+
+ at item SEEK_CUR
+Position file relative to the current position.
+
+ at item SEEK_END
+Position file relative to the end.
+ at end table
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-frewind}
+ at deftypefn {Built-in Function} {} frewind (@var{fid})
+Move the file pointer to the beginning of the file @var{fid}, returning
+0 for success, and -1 if an error was encountered.  It is equivalent to
+ at code{fseek (@var{fid}, 0, SEEK_SET)}.
+ at end deftypefn
+
+
+The following example stores the current file position in the variable
+ at code{marker}, moves the pointer to the beginning of the file, reads
+four characters, and then returns to the original position.
+
+ at example
+ at group
+marker = ftell (myfile);
+frewind (myfile);
+fourch = fgets (myfile, 4);
+fseek (myfile, marker, SEEK_SET);
+ at end group
+ at end example
+
diff --git a/doc/interpreter/io.txi b/doc/interpreter/io.txi
new file mode 100644
index 0000000..59578d4
--- /dev/null
+++ b/doc/interpreter/io.txi
@@ -0,0 +1,1060 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Input and Output
+ at chapter Input and Output
+
+Octave supports several ways of reading and writing data to or from the
+prompt or a file.  The simplest functions for data Input and Output
+(I/O) are easy to use, but only provides limited control of how
+data is processed.  For more control, a set of functions modelled
+after the C standard library are also provided by Octave.
+
+ at menu
+* Basic Input and Output::      
+* C-Style I/O Functions::       
+ at end menu
+
+ at node Basic Input and Output
+ at section Basic Input and Output
+
+ at c We could use a two-line introduction here...
+
+ at menu
+* Terminal Output::             
+* Terminal Input::              
+* Simple File I/O::             
+* Rational Approximations::
+ at end menu
+
+ at node Terminal Output
+ at subsection Terminal Output
+
+Since Octave normally prints the value of an expression as soon as it
+has been evaluated, the simplest of all I/O functions is a simple
+expression.  For example, the following expression will display the
+value of @samp{pi}
+
+ at example
+ at group
+pi
+     @print{} pi = 3.1416
+ at end group
+ at end example
+
+This works well as long as it is acceptable to have the name of the
+variable (or @samp{ans}) printed along with the value.  To print the
+value of a variable without printing its name, use the function
+ at code{disp}.
+
+The @code{format} command offers some control over the way Octave prints
+values with @code{disp} and through the normal echoing mechanism.
+
+ at DOCSTRING(disp)
+
+ at DOCSTRING(format)
+
+ at menu
+* Paging Screen Output::
+ at end menu
+
+ at node Paging Screen Output
+ at subsubsection Paging Screen Output
+
+When running interactively, Octave normally sends any output intended
+for your terminal that is more than one screen long to a paging program,
+such as @code{less} or @code{more}.  This avoids the problem of having a
+large volume of output stream by before you can read it.  With
+ at code{less} (and some versions of @code{more}) you can also scan forward
+and backward, and search for specific items.
+
+Normally, no output is displayed by the pager until just before Octave
+is ready to print the top level prompt, or read from the standard input
+(for example, by using the @code{fscanf} or @code{scanf} functions).
+This means that there may be some delay before any output appears on
+your screen if you have asked Octave to perform a significant amount of
+work with a single command statement.  The function @code{fflush} may be
+used to force output to be sent to the pager (or any other stream)
+immediately.
+
+You can select the program to run as the pager using the @code{PAGER}
+function, and you can turn paging off by using the function
+ at code{more}.
+
+ at DOCSTRING(more)
+
+ at DOCSTRING(PAGER)
+
+ at DOCSTRING(PAGER_FLAGS)
+
+ at DOCSTRING(page_screen_output)
+
+ at DOCSTRING(page_output_immediately)
+
+ at DOCSTRING(fflush)
+
+ at c FIXME -- maybe this would be a good place to describe the
+ at c following message:
+ at c
+ at c warning: connection to external pager (pid = 9334) lost --
+ at c warning: pending computations and output may be lost
+ at c warning: broken pipe
+
+ at node Terminal Input
+ at subsection Terminal Input
+
+Octave has three functions that make it easy to prompt users for
+input.  The @code{input} and @code{menu} functions are normally
+used for managing an interactive dialog with a user, and the
+ at code{keyboard} function is normally used for doing simple debugging.
+
+ at DOCSTRING(input)
+
+ at DOCSTRING(menu)
+
+ at DOCSTRING(yes_or_no)
+
+For @code{input}, the normal command line history and editing functions
+are available at the prompt.
+
+Octave also has a function that makes it possible to get a single
+character from the keyboard without requiring the user to type a
+carriage return.
+
+ at DOCSTRING(kbhit)
+
+ at node Simple File I/O
+ at subsection Simple File I/O
+
+ at cindex saving data
+ at cindex loading data
+The @code{save} and @code{load} commands allow data to be written to and
+read from disk files in various formats.  The default format of files
+written by the @code{save} command can be controlled using the functions
+ at code{default_save_options} and @code{save_precision}.
+
+As an example the following code creates a 3-by-3 matrix and saves it
+to the file @samp{myfile.mat}.
+
+ at example
+ at group
+A = [ 1:3; 4:6; 7:9 ];
+save myfile.mat A
+ at end group
+ at end example
+
+Once one or more variables have been saved to a file, they can be
+read into memory using the @code{load} command.
+
+ at example
+ at group
+load myfile.mat
+A
+     @print{} A =
+     @print{} 
+     @print{}    1   2   3
+     @print{}    4   5   6
+     @print{}    7   8   9
+ at end group
+ at end example
+
+ at DOCSTRING(save)
+
+ at DOCSTRING(load)
+
+There are three functions that modify the behavior of @code{save}.
+
+ at DOCSTRING(default_save_options)
+
+ at DOCSTRING(save_precision)
+
+ at DOCSTRING(save_header_format_string)
+
+ at DOCSTRING(native_float_format)
+
+It is possible to write data to a file in a similar way to the
+ at code{disp} function for writing data to the screen.  The @code{fdisp}
+works just like @code{disp} except its first argument is a file pointer
+as created by @code{fopen}.  As an example, the following code writes
+to data @samp{myfile.txt}.
+
+ at example
+ at group
+fid = fopen ("myfile.txt", "w");
+fdisp (fid, "3/8 is ");
+fdisp (fid, 3/8);
+fclose (fid);
+ at end group
+ at end example
+
+ at noindent
+ at xref{Opening and Closing Files}, for details on how to use @code{fopen}
+and @code{fclose}.
+
+ at DOCSTRING(fdisp)
+
+Octave can also read and write matrices text files such as comma
+separated lists.
+
+ at DOCSTRING(dlmwrite)
+
+ at DOCSTRING(dlmread)
+
+ at DOCSTRING(csvwrite)
+
+ at DOCSTRING(csvread)
+
+ at menu
+* Saving Data on Unexpected Exits::
+ at end menu
+
+ at node Saving Data on Unexpected Exits
+ at subsubsection Saving Data on Unexpected Exits
+
+If Octave for some reason exits unexpectedly it will by default save the
+variables available in the workspace to a file in the current directory.
+By default this file is named @samp{octave-core} and can be loaded
+into memory with the @code{load} command.  While the default behavior
+most often is reasonable it can be changed through the following
+functions.
+
+ at DOCSTRING(crash_dumps_octave_core)
+
+ at DOCSTRING(sighup_dumps_octave_core)
+
+ at DOCSTRING(sigterm_dumps_octave_core)
+
+ at DOCSTRING(octave_core_file_options)
+
+ at DOCSTRING(octave_core_file_limit)
+
+ at DOCSTRING(octave_core_file_name)
+
+ at node Rational Approximations
+ at subsection Rational Approximations
+
+ at DOCSTRING(rat)
+
+ at DOCSTRING(rats)
+
+ at node C-Style I/O Functions
+ at section C-Style I/O Functions
+
+Octave's C-style input and output functions provide most of the
+functionality of the C programming language's standard I/O library.  The
+argument lists for some of the input functions are slightly different,
+however, because Octave has no way of passing arguments by reference.
+
+In the following, @var{file} refers to a file name and @code{fid} refers
+to an integer file number, as returned by @code{fopen}.
+
+There are three files that are always available.  Although these files
+can be accessed using their corresponding numeric file ids, you should
+always use the symbolic names given in the table below, since it will
+make your programs easier to understand.
+
+ at DOCSTRING(stdin)
+
+ at DOCSTRING(stdout)
+
+ at DOCSTRING(stderr)
+
+ at menu
+* Opening and Closing Files::   
+* Simple Output::               
+* Line-Oriented Input::         
+* Formatted Output::            
+* Output Conversion for Matrices::  
+* Output Conversion Syntax::    
+* Table of Output Conversions::  
+* Integer Conversions::         
+* Floating-Point Conversions::
+* Other Output Conversions::    
+* Formatted Input::             
+* Input Conversion Syntax::     
+* Table of Input Conversions::  
+* Numeric Input Conversions::   
+* String Input Conversions::    
+* Binary I/O::                  
+* Temporary Files::             
+* EOF and Errors::              
+* File Positioning::            
+ at end menu
+
+ at node Opening and Closing Files
+ at subsection Opening and Closing Files
+
+When reading data from a file it must be opened for reading first, and
+likewise when writing to a file.  The @code{fopen} function returns a
+pointer to an open file that is ready to be read or written.  Once all
+data has been read from or written to the opened file it should be closed.
+The @code{fclose} function does this.  The following code illustrates
+the basic pattern for writing to a file, but a very similar pattern is
+used when reading a file.
+
+ at example
+ at group
+filename = "myfile.txt";
+fid = fopen (filename, "w");
+# Do the actual I/O here at dots{}
+fclose (fid);
+ at end group
+ at end example
+
+ at DOCSTRING(fopen)
+
+ at DOCSTRING(fclose)
+
+ at node Simple Output
+ at subsection Simple Output
+
+Once a file has been opened for writing a string can be written to the
+file using the @code{fputs} function.  The following example shows
+how to write the string @samp{Free Software is needed for Free Science}
+to the file @samp{free.txt}.
+
+ at example
+ at group
+filename = "free.txt";
+fid = fopen (filename, "w");
+fputs (fid, "Free Software is needed for Free Science");
+fclose (fid);
+ at end group
+ at end example
+
+ at DOCSTRING(fputs)
+
+A function much similar to @code{fputs} is available for writing data
+to the screen.  The @code{puts} function works just like @code{fputs}
+except it doesn't take a file pointer as its input.
+
+ at DOCSTRING(puts)
+
+ at node Line-Oriented Input
+ at subsection Line-Oriented Input
+
+To read from a file it must be opened for reading using @code{fopen}.
+Then a line can be read from the file using @code{fgetl} as the following
+code illustrates
+
+ at example
+ at group
+fid = fopen ("free.txt");
+txt = fgetl (fid)
+     @print{} Free Software is needed for Free Science
+fclose (fid);
+ at end group
+ at end example
+
+ at noindent
+This of course assumes that the file @samp{free.txt} exists and contains
+the line @samp{Free Software is needed for Free Science}.
+
+ at DOCSTRING(fgetl)
+
+ at DOCSTRING(fgets)
+
+ at node Formatted Output
+ at subsection Formatted Output
+
+This section describes how to call @code{printf} and related functions.
+
+The following functions are available for formatted output.  They are
+modelled after the C language functions of the same name, but they
+interpret the format template differently in order to improve the
+performance of printing vector and matrix values.
+
+ at DOCSTRING(printf)
+
+ at DOCSTRING(fprintf)
+
+ at DOCSTRING(sprintf)
+
+The @code{printf} function can be used to print any number of arguments.
+The template string argument you supply in a call provides
+information not only about the number of additional arguments, but also
+about their types and what style should be used for printing them.
+
+Ordinary characters in the template string are simply written to the
+output stream as-is, while @dfn{conversion specifications} introduced by
+a @samp{%} character in the template cause subsequent arguments to be
+formatted and written to the output stream.  For example,
+ at cindex conversion specifications (@code{printf})
+
+ at example
+ at group
+pct = 37;
+filename = "foo.txt";
+printf ("Processed %d%% of `%s'.\nPlease be patient.\n",
+        pct, filename);
+ at end group
+ at end example
+
+ at noindent
+produces output like
+
+ at example
+ at group
+Processed 37% of `foo.txt'.
+Please be patient.
+ at end group
+ at end example
+
+This example shows the use of the @samp{%d} conversion to specify that a
+scalar argument should be printed in decimal notation, the @samp{%s}
+conversion to specify printing of a string argument, and the @samp{%%}
+conversion to print a literal @samp{%} character.
+
+There are also conversions for printing an integer argument as an
+unsigned value in octal, decimal, or hexadecimal radix (@samp{%o},
+ at samp{%u}, or @samp{%x}, respectively); or as a character value
+(@samp{%c}).
+
+Floating-point numbers can be printed in normal, fixed-point notation
+using the @samp{%f} conversion or in exponential notation using the
+ at samp{%e} conversion.  The @samp{%g} conversion uses either @samp{%e}
+or @samp{%f} format, depending on what is more appropriate for the
+magnitude of the particular number.
+
+You can control formatting more precisely by writing @dfn{modifiers}
+between the @samp{%} and the character that indicates which conversion
+to apply.  These slightly alter the ordinary behavior of the conversion.
+For example, most conversion specifications permit you to specify a
+minimum field width and a flag indicating whether you want the result
+left- or right-justified within the field.
+
+The specific flags and modifiers that are permitted and their
+interpretation vary depending on the particular conversion.  They're all
+described in more detail in the following sections.
+
+ at node Output Conversion for Matrices
+ at subsection Output Conversion for Matrices
+
+When given a matrix value, Octave's formatted output functions cycle
+through the format template until all the values in the matrix have been
+printed.  For example,
+
+ at example
+ at group
+printf ("%4.2f %10.2e %8.4g\n", hilb (3));
+
+     @print{} 1.00   5.00e-01   0.3333
+     @print{} 0.50   3.33e-01     0.25
+     @print{} 0.33   2.50e-01      0.2
+ at end group
+ at end example
+
+If more than one value is to be printed in a single call, the output
+functions do not return to the beginning of the format template when
+moving on from one value to the next.  This can lead to confusing output
+if the number of elements in the matrices are not exact multiples of the
+number of conversions in the format template.  For example,
+
+ at example
+ at group
+printf ("%4.2f %10.2e %8.4g\n", [1, 2], [3, 4]);
+
+     @print{} 1.00   2.00e+00        3
+     @print{} 4.00
+ at end group
+ at end example
+
+If this is not what you want, use a series of calls instead of just one.
+
+ at node Output Conversion Syntax
+ at subsection Output Conversion Syntax
+
+This section provides details about the precise syntax of conversion
+specifications that can appear in a @code{printf} template
+string.
+
+Characters in the template string that are not part of a
+conversion specification are printed as-is to the output stream.
+
+The conversion specifications in a @code{printf} template string have
+the general form:
+
+ at example
+% @var{flags} @var{width} @r{[} . @var{precision} @r{]} @var{type} @var{conversion}
+ at end example
+
+For example, in the conversion specifier @samp{%-10.8ld}, the @samp{-}
+is a flag, @samp{10} specifies the field width, the precision is
+ at samp{8}, the letter @samp{l} is a type modifier, and @samp{d} specifies
+the conversion style.  (This particular type specifier says to print a
+numeric argument in decimal notation, with a minimum of 8 digits
+left-justified in a field at least 10 characters wide.)
+
+In more detail, output conversion specifications consist of an
+initial @samp{%} character followed in sequence by:
+
+ at itemize @bullet
+ at item 
+Zero or more @dfn{flag characters} that modify the normal behavior of
+the conversion specification.
+ at cindex flag character (@code{printf})
+
+ at item 
+An optional decimal integer specifying the @dfn{minimum field width}.
+If the normal conversion produces fewer characters than this, the field
+is padded with spaces to the specified width.  This is a @emph{minimum}
+value; if the normal conversion produces more characters than this, the
+field is @emph{not} truncated.  Normally, the output is right-justified
+within the field.
+ at cindex minimum field width (@code{printf})
+
+You can also specify a field width of @samp{*}.  This means that the
+next argument in the argument list (before the actual value to be
+printed) is used as the field width.  The value is rounded to the
+nearest integer.  If the value is negative, this means to set the
+ at samp{-} flag (see below) and to use the absolute value as the field
+width.
+
+ at item 
+An optional @dfn{precision} to specify the number of digits to be
+written for the numeric conversions.  If the precision is specified, it
+consists of a period (@samp{.}) followed optionally by a decimal integer
+(which defaults to zero if omitted).
+ at cindex precision (@code{printf})
+
+You can also specify a precision of @samp{*}.  This means that the next
+argument in the argument list (before the actual value to be printed) is
+used as the precision.  The value must be an integer, and is ignored
+if it is negative.
+
+ at item
+An optional @dfn{type modifier character}.  This character is ignored by
+Octave's @code{printf} function, but is recognized to provide
+compatibility with the C language @code{printf}.
+
+ at item
+A character that specifies the conversion to be applied.
+ at end itemize
+
+The exact options that are permitted and how they are interpreted vary 
+between the different conversion specifiers.  See the descriptions of the
+individual conversions for information about the particular options that
+they use.
+
+ at node Table of Output Conversions
+ at subsection Table of Output Conversions
+ at cindex output conversions, for @code{printf}
+
+Here is a table summarizing what all the different conversions do:
+
+ at table @asis
+ at item @samp{%d}, @samp{%i}
+Print an integer as a signed decimal number.  @xref{Integer
+Conversions}, for details.  @samp{%d} and @samp{%i} are synonymous for
+output, but are different when used with @code{scanf} for input
+(@pxref{Table of Input Conversions}).
+
+ at item @samp{%o}
+Print an integer as an unsigned octal number.  @xref{Integer
+Conversions}, for details.
+
+ at item @samp{%u}
+Print an integer as an unsigned decimal number.  @xref{Integer
+Conversions}, for details.
+
+ at item @samp{%x}, @samp{%X}
+Print an integer as an unsigned hexadecimal number.  @samp{%x} uses
+lower-case letters and @samp{%X} uses upper-case.  @xref{Integer
+Conversions}, for details.
+
+ at item @samp{%f}
+Print a floating-point number in normal (fixed-point) notation.
+ at xref{Floating-Point Conversions}, for details.
+
+ at item @samp{%e}, @samp{%E}
+Print a floating-point number in exponential notation.  @samp{%e} uses
+lower-case letters and @samp{%E} uses upper-case.  @xref{Floating-Point
+Conversions}, for details.
+
+ at item @samp{%g}, @samp{%G}
+Print a floating-point number in either normal (fixed-point) or
+exponential notation, whichever is more appropriate for its magnitude.
+ at samp{%g} uses lower-case letters and @samp{%G} uses upper-case.
+ at xref{Floating-Point Conversions}, for details.
+
+ at item @samp{%c}
+Print a single character.  @xref{Other Output Conversions}.
+
+ at item @samp{%s}
+Print a string.  @xref{Other Output Conversions}.
+
+ at item @samp{%%}
+Print a literal @samp{%} character.  @xref{Other Output Conversions}.
+ at end table
+
+If the syntax of a conversion specification is invalid, unpredictable
+things will happen, so don't do this.  If there aren't enough function
+arguments provided to supply values for all the conversion
+specifications in the template string, or if the arguments are not of
+the correct types, the results are unpredictable.  If you supply more
+arguments than conversion specifications, the extra argument values are
+simply ignored; this is sometimes useful.
+
+ at node Integer Conversions
+ at subsection Integer Conversions
+
+This section describes the options for the @samp{%d}, @samp{%i},
+ at samp{%o}, @samp{%u}, @samp{%x}, and @samp{%X} conversion
+specifications.  These conversions print integers in various formats.
+
+The @samp{%d} and @samp{%i} conversion specifications both print an
+numeric argument as a signed decimal number; while @samp{%o},
+ at samp{%u}, and @samp{%x} print the argument as an unsigned octal,
+decimal, or hexadecimal number (respectively).  The @samp{%X} conversion
+specification is just like @samp{%x} except that it uses the characters
+ at samp{ABCDEF} as digits instead of @samp{abcdef}.
+
+The following flags are meaningful:
+
+ at table @asis
+ at item @samp{-}
+Left-justify the result in the field (instead of the normal
+right-justification).
+
+ at item @samp{+}
+For the signed @samp{%d} and @samp{%i} conversions, print a
+plus sign if the value is positive.
+
+ at item @samp{ }
+For the signed @samp{%d} and @samp{%i} conversions, if the result
+doesn't start with a plus or minus sign, prefix it with a space
+character instead.  Since the @samp{+} flag ensures that the result
+includes a sign, this flag is ignored if you supply both of them.
+
+ at item @samp{#}
+For the @samp{%o} conversion, this forces the leading digit to be
+ at samp{0}, as if by increasing the precision.  For @samp{%x} or
+ at samp{%X}, this prefixes a leading @samp{0x} or @samp{0X} (respectively)
+to the result.  This doesn't do anything useful for the @samp{%d},
+ at samp{%i}, or @samp{%u} conversions.
+
+ at item @samp{0}
+Pad the field with zeros instead of spaces.  The zeros are placed after
+any indication of sign or base.  This flag is ignored if the @samp{-}
+flag is also specified, or if a precision is specified.
+ at end table
+
+If a precision is supplied, it specifies the minimum number of digits to
+appear; leading zeros are produced if necessary.  If you don't specify a
+precision, the number is printed with as many digits as it needs.  If
+you convert a value of zero with an explicit precision of zero, then no
+characters at all are produced.
+
+ at node Floating-Point Conversions
+ at subsection Floating-Point Conversions
+
+This section discusses the conversion specifications for floating-point
+numbers: the @samp{%f}, @samp{%e}, @samp{%E}, @samp{%g}, and @samp{%G}
+conversions.
+
+The @samp{%f} conversion prints its argument in fixed-point notation,
+producing output of the form
+ at w{[@code{-}]@var{ddd}@code{.}@var{ddd}},
+where the number of digits following the decimal point is controlled
+by the precision you specify.
+
+The @samp{%e} conversion prints its argument in exponential notation,
+producing output of the form
+ at w{[@code{-}]@var{d}@code{.}@var{ddd}@code{e}[@code{+}|@code{-}]@var{dd}}.
+Again, the number of digits following the decimal point is controlled by
+the precision.  The exponent always contains at least two digits.  The
+ at samp{%E} conversion is similar but the exponent is marked with the letter
+ at samp{E} instead of @samp{e}.
+
+The @samp{%g} and @samp{%G} conversions print the argument in the style
+of @samp{%e} or @samp{%E} (respectively) if the exponent would be less
+than -4 or greater than or equal to the precision; otherwise they use the
+ at samp{%f} style.  Trailing zeros are removed from the fractional portion
+of the result and a decimal-point character appears only if it is
+followed by a digit.
+
+The following flags can be used to modify the behavior:
+
+ at c Not @samp so we can have ` ' as an item.
+ at table @asis
+ at item @samp{-}
+Left-justify the result in the field.  Normally the result is
+right-justified.
+
+ at item @samp{+}
+Always include a plus or minus sign in the result.
+
+ at item @samp{ }
+If the result doesn't start with a plus or minus sign, prefix it with a
+space instead.  Since the @samp{+} flag ensures that the result includes
+a sign, this flag is ignored if you supply both of them.
+
+ at item @samp{#}
+Specifies that the result should always include a decimal point, even
+if no digits follow it.  For the @samp{%g} and @samp{%G} conversions,
+this also forces trailing zeros after the decimal point to be left
+in place where they would otherwise be removed.
+
+ at item @samp{0}
+Pad the field with zeros instead of spaces; the zeros are placed
+after any sign.  This flag is ignored if the @samp{-} flag is also
+specified.
+ at end table
+
+The precision specifies how many digits follow the decimal-point
+character for the @samp{%f}, @samp{%e}, and @samp{%E} conversions.  For
+these conversions, the default precision is @code{6}.  If the precision
+is explicitly @code{0}, this suppresses the decimal point character
+entirely.  For the @samp{%g} and @samp{%G} conversions, the precision
+specifies how many significant digits to print.  Significant digits are
+the first digit before the decimal point, and all the digits after it.
+If the precision is @code{0} or not specified for @samp{%g} or
+ at samp{%G}, it is treated like a value of @code{1}.  If the value being
+printed cannot be expressed precisely in the specified number of digits,
+the value is rounded to the nearest number that fits.
+
+ at node Other Output Conversions
+ at subsection Other Output Conversions
+
+This section describes miscellaneous conversions for @code{printf}.
+
+The @samp{%c} conversion prints a single character.  The @samp{-} 
+flag can be used to specify left-justification in the field, but no
+other flags are defined, and no precision or type modifier can be given.
+For example:
+
+ at example
+printf ("%c%c%c%c%c", "h", "e", "l", "l", "o");
+ at end example
+
+ at noindent
+prints @samp{hello}.
+
+The @samp{%s} conversion prints a string.  The corresponding argument
+must be a string.  A precision can be specified to indicate the maximum
+number of characters to write; otherwise characters in the string up to
+but not including the terminating null character are written to the
+output stream.  The @samp{-} flag can be used to specify
+left-justification in the field, but no other flags or type modifiers
+are defined for this conversion.  For example:
+
+ at example
+printf ("%3s%-6s", "no", "where");
+ at end example
+
+ at noindent
+prints @samp{ nowhere } (note the leading and trailing spaces).
+
+ at node Formatted Input
+ at subsection Formatted Input
+
+Octave provides the @code{scanf}, @code{fscanf}, and @code{sscanf}
+functions to read formatted input.  There are two forms of each of these
+functions.  One can be used to extract vectors of data from a file, and
+the other is more `C-like'.
+
+ at DOCSTRING(fscanf)
+
+ at DOCSTRING(scanf)
+
+ at DOCSTRING(sscanf)
+
+Calls to @code{scanf} are superficially similar to calls to
+ at code{printf} in that arbitrary arguments are read under the control of
+a template string.  While the syntax of the conversion specifications in
+the template is very similar to that for @code{printf}, the
+interpretation of the template is oriented more towards free-format
+input and simple pattern matching, rather than fixed-field formatting.
+For example, most @code{scanf} conversions skip over any amount of
+``white space'' (including spaces, tabs, and newlines) in the input
+file, and there is no concept of precision for the numeric input
+conversions as there is for the corresponding output conversions.
+Ordinarily, non-whitespace characters in the template are expected to
+match characters in the input stream exactly.
+ at cindex conversion specifications (@code{scanf})
+
+When a @dfn{matching failure} occurs, @code{scanf} returns immediately,
+leaving the first non-matching character as the next character to be
+read from the stream, and @code{scanf} returns all the items that were
+successfully converted.
+ at cindex matching failure, in @code{scanf}
+
+The formatted input functions are not used as frequently as the
+formatted output functions.  Partly, this is because it takes some care
+to use them properly.  Another reason is that it is difficult to recover
+from a matching error.
+
+ at node Input Conversion Syntax
+ at subsection Input Conversion Syntax
+
+A @code{scanf} template string is a string that contains ordinary
+multibyte characters interspersed with conversion specifications that
+start with @samp{%}.
+
+Any whitespace character in the template causes any number of whitespace
+characters in the input stream to be read and discarded.  The whitespace
+characters that are matched need not be exactly the same whitespace
+characters that appear in the template string.  For example, write
+ at samp{ , } in the template to recognize a comma with optional whitespace
+before and after.
+
+Other characters in the template string that are not part of conversion
+specifications must match characters in the input stream exactly; if
+this is not the case, a matching failure occurs.
+
+The conversion specifications in a @code{scanf} template string
+have the general form:
+
+ at example
+% @var{flags} @var{width} @var{type} @var{conversion}
+ at end example
+
+In more detail, an input conversion specification consists of an initial
+ at samp{%} character followed in sequence by:
+
+ at itemize @bullet
+ at item
+An optional @dfn{flag character} @samp{*}, which says to ignore the text
+read for this specification.  When @code{scanf} finds a conversion
+specification that uses this flag, it reads input as directed by the
+rest of the conversion specification, but it discards this input, does
+not return any value, and does not increment the count of
+successful assignments.
+ at cindex flag character (@code{scanf})
+
+ at item
+An optional decimal integer that specifies the @dfn{maximum field
+width}.  Reading of characters from the input stream stops either when
+this maximum is reached or when a non-matching character is found,
+whichever happens first.  Most conversions discard initial whitespace
+characters, and these discarded characters don't count towards the
+maximum field width.  Conversions that do not discard initial whitespace
+are explicitly documented.
+ at cindex maximum field width (@code{scanf})
+
+ at item
+An optional type modifier character.  This character is ignored by
+Octave's @code{scanf} function, but is recognized to provide
+compatibility with the C language @code{scanf}.
+
+ at item
+A character that specifies the conversion to be applied.
+ at end itemize
+
+The exact options that are permitted and how they are interpreted vary 
+between the different conversion specifiers.  See the descriptions of the
+individual conversions for information about the particular options that
+they allow.
+
+ at node Table of Input Conversions
+ at subsection Table of Input Conversions
+ at cindex input conversions, for @code{scanf}
+
+Here is a table that summarizes the various conversion specifications:
+
+ at table @asis
+ at item @samp{%d}
+Matches an optionally signed integer written in decimal.  @xref{Numeric
+Input Conversions}.
+
+ at item @samp{%i}
+Matches an optionally signed integer in any of the formats that the C
+language defines for specifying an integer constant.  @xref{Numeric
+Input Conversions}.
+
+ at item @samp{%o}
+Matches an unsigned integer written in octal radix.
+ at xref{Numeric Input Conversions}.
+
+ at item @samp{%u}
+Matches an unsigned integer written in decimal radix.
+ at xref{Numeric Input Conversions}.
+
+ at item @samp{%x}, @samp{%X}
+Matches an unsigned integer written in hexadecimal radix.
+ at xref{Numeric Input Conversions}.
+
+ at item @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, @samp{%G}
+Matches an optionally signed floating-point number.  @xref{Numeric Input
+Conversions}.
+
+ at item @samp{%s}
+Matches a string containing only non-whitespace characters.
+ at xref{String Input Conversions}.
+
+ at item @samp{%c}
+Matches a string of one or more characters; the number of characters
+read is controlled by the maximum field width given for the conversion.
+ at xref{String Input Conversions}.
+
+ at item @samp{%%}
+This matches a literal @samp{%} character in the input stream.  No
+corresponding argument is used.
+ at end table
+
+If the syntax of a conversion specification is invalid, the behavior is
+undefined.  If there aren't enough function arguments provided to supply
+addresses for all the conversion specifications in the template strings
+that perform assignments, or if the arguments are not of the correct
+types, the behavior is also undefined.  On the other hand, extra
+arguments are simply ignored.
+
+ at node Numeric Input Conversions
+ at subsection Numeric Input Conversions
+
+This section describes the @code{scanf} conversions for reading numeric
+values.
+
+The @samp{%d} conversion matches an optionally signed integer in decimal
+radix.
+
+The @samp{%i} conversion matches an optionally signed integer in any of
+the formats that the C language defines for specifying an integer
+constant.
+
+For example, any of the strings @samp{10}, @samp{0xa}, or @samp{012}
+could be read in as integers under the @samp{%i} conversion.  Each of
+these specifies a number with decimal value @code{10}.
+
+The @samp{%o}, @samp{%u}, and @samp{%x} conversions match unsigned
+integers in octal, decimal, and hexadecimal radices, respectively.
+
+The @samp{%X} conversion is identical to the @samp{%x} conversion.  They
+both permit either uppercase or lowercase letters to be used as digits.
+
+Unlike the C language @code{scanf}, Octave ignores the @samp{h},
+ at samp{l}, and @samp{L} modifiers.
+
+ at node String Input Conversions
+ at subsection String Input Conversions
+
+This section describes the @code{scanf} input conversions for reading
+string and character values: @samp{%s} and @samp{%c}.  
+
+The @samp{%c} conversion is the simplest: it matches a fixed number of
+characters, always.  The maximum field with says how many characters to
+read; if you don't specify the maximum, the default is 1.  This
+conversion does not skip over initial whitespace characters.  It reads
+precisely the next @var{n} characters, and fails if it cannot get that
+many.
+
+The @samp{%s} conversion matches a string of non-whitespace characters.
+It skips and discards initial whitespace, but stops when it encounters
+more whitespace after having read something.
+
+For example, reading the input:
+
+ at example
+ hello, world
+ at end example
+
+ at noindent
+with the conversion @samp{%10c} produces @code{" hello, wo"}, but
+reading the same input with the conversion @samp{%10s} produces
+ at code{"hello,"}.
+
+ at node Binary I/O
+ at subsection Binary I/O
+
+Octave can read and write binary data using the functions @code{fread}
+and @code{fwrite}, which are patterned after the standard C functions
+with the same names.  They are able to automatically swap the byte order
+of integer data and convert among the supported floating point formats
+as the data are read.
+
+ at DOCSTRING(fread)
+
+ at DOCSTRING(fwrite)
+
+ at node Temporary Files
+ at subsection Temporary Files
+
+Sometimes one needs to write data to a file that is only temporary.
+This is most commonly used when an external program launched from
+within Octave needs to access data.  When Octave exits all temporary
+files will be deleted, so this step need not be executed manually.
+
+ at DOCSTRING(mkstemp)
+
+ at DOCSTRING(tmpfile)
+
+ at DOCSTRING(tmpnam)
+
+ at DOCSTRING(octave_tmp_file_name)
+
+ at node EOF and Errors, File Positioning, Temporary Files, C-Style I/O Functions
+ at subsection End of File and Errors
+
+Once a file has been opened its status can be acquired.  As an example
+the @code{feof} functions determines if the end of the file has been
+reached.  This can be very useful when reading small parts of a file
+at a time.  The following example shows how to read one line at a time
+from a file until the end has been reached.
+
+ at example
+ at group
+filename = "myfile.txt";
+fid = fopen (filename, "r");
+while (! feof (fid) )
+  text_line = fgetl (fid);
+endwhile
+fclose (fid);
+ at end group
+ at end example
+
+ at noindent
+Note that in some situations it is more efficient to read the entire
+contents of a file and then process it, than it is to read it line by
+line.  This has the potential advantage of removing the loop in the
+above code.
+
+ at DOCSTRING(feof)
+
+ at DOCSTRING(ferror)
+
+ at DOCSTRING(fclear)
+
+ at DOCSTRING(freport)
+
+ at node File Positioning
+ at subsection File Positioning
+
+Three functions are available for setting and determining the position of
+the file pointer for a given file.
+
+ at DOCSTRING(ftell)
+
+ at DOCSTRING(fseek)
+
+ at DOCSTRING(SEEK_SET)
+
+ at DOCSTRING(frewind)
+
+The following example stores the current file position in the variable
+ at code{marker}, moves the pointer to the beginning of the file, reads
+four characters, and then returns to the original position.
+
+ at example
+ at group
+marker = ftell (myfile);
+frewind (myfile);
+fourch = fgets (myfile, 4);
+fseek (myfile, marker, SEEK_SET);
+ at end group
+ at end example
+
diff --git a/doc/interpreter/linalg.texi b/doc/interpreter/linalg.texi
new file mode 100644
index 0000000..ca4aab4
--- /dev/null
+++ b/doc/interpreter/linalg.texi
@@ -0,0 +1,1660 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Linear Algebra
+ at chapter Linear Algebra
+
+This chapter documents the linear algebra functions of Octave.
+Reference material for many of these functions may be found in
+Golub and Van Loan, @cite{Matrix Computations, 2nd Ed.}, Johns Hopkins,
+1989, and in the @cite{@sc{lapack} Users' Guide}, SIAM, 1992.
+
+ at menu
+* Techniques used for Linear Algebra::
+* Basic Matrix Functions::      
+* Matrix Factorizations::       
+* Functions of a Matrix::       
+* Specialized Solvers::
+ at end menu
+
+ at node Techniques used for Linear Algebra
+ at section Techniques used for Linear Algebra
+
+Octave includes a polymorphic solver, that selects an appropriate
+matrix factorization depending on the properties of the matrix itself. 
+Generally, the cost of determining the matrix type is small relative to 
+the cost of factorizing the matrix itself, but in any case the matrix 
+type is cached once it is calculated, so that it is not re-determined 
+each time it is used in a linear equation.
+
+The selection tree for how the linear equation is solve or a matrix
+inverse is form is given by
+
+ at enumerate 1
+ at item If the matrix is upper or lower triangular sparse a forward or
+backward substitution using the @sc{lapack} xTRTRS function, and goto 4.
+
+ at c Permuted triangular matrices currently disabled in the code
+ at c
+ at c @item If the matrix is a upper triangular matrix with column permutations
+ at c or lower triangular matrix with row permutations, perform a forward or
+ at c backward substitution, and goto 5.
+
+ at item If the matrix is square, hermitian with a real positive diagonal,
+attempt Cholesky factorization using the @sc{lapack} xPOTRF function.
+
+ at item If the Cholesky factorization failed or the matrix is not
+hermitian with a real positive diagonal, and the matrix is square, factorize 
+using the @sc{lapack} xGETRF function.
+
+ at item If the matrix is not square, or any of the previous solvers flags
+a singular or near singular matrix, find a least squares solution using
+the @sc{lapack} xGELSD function.
+ at end enumerate
+
+The user can force the type of the matrix with the @code{matrix_type}
+function.  This overcomes the cost of discovering the type of the matrix.
+However, it should be noted that identifying the type of the matrix incorrectly
+will lead to unpredictable results, and so @code{matrix_type} should be
+used with care.
+
+It should be noted that the test for whether a matrix is a candidate for
+Cholesky factorization, performed above and by the @code{matrix_type}
+function, does not give a certainty that the matrix is
+Hermitian.  However, the attempt to factorize the matrix will quickly
+flag a non-Hermitian matrix.
+
+ at node Basic Matrix Functions
+ at section Basic Matrix Functions
+
+ at c ./DLD-FUNCTIONS/balance.cc
+ at anchor{doc-balance}
+ at deftypefn {Loadable Function} {@var{aa} =} balance (@var{a}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{dd}, @var{aa}] =} balance (@var{a}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{d}, @var{p}, @var{aa}] =} balance (@var{a}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{cc}, @var{dd}, @var{aa}, @var{bb}] =} balance (@var{a}, @var{b}, @var{opt})
+
+Compute @code{aa = dd \ a * dd} in which @code{aa} is a matrix whose
+row and column norms are roughly equal in magnitude, and
+ at code{dd} = @code{p * d}, in which @code{p} is a permutation
+matrix and @code{d} is a diagonal matrix of powers of two.  This allows
+the equilibration to be computed without roundoff.  Results of
+eigenvalue calculation are typically improved by balancing first.
+
+If two output values are requested, @code{balance} returns 
+the diagonal @code{d} and the permutation @code{p} separately as vectors.  
+In this case, @code{dd = eye(n)(:,p) * diag (d)}, where @code{n} is the matrix 
+size.  
+
+If four output values are requested, compute @code{aa = cc*a*dd} and
+ at code{bb = cc*b*dd)}, in which @code{aa} and @code{bb} have non-zero
+elements of approximately the same magnitude and @code{cc} and @code{dd}
+are permuted diagonal matrices as in @code{dd} for the algebraic
+eigenvalue problem.
+
+The eigenvalue balancing option @code{opt} may be one of:
+
+ at table @asis
+ at item @code{"noperm"}, @code{"S"}
+Scale only; do not permute.
+
+ at item @code{"noscal"}, @code{"P"}
+Permute only; do not scale.
+ at end table
+
+Algebraic eigenvalue balancing uses standard @sc{lapack} routines.
+
+Generalized eigenvalue problem balancing uses Ward's algorithm
+(SIAM Journal on Scientific and Statistical Computing, 1981).
+ at end deftypefn
+
+
+ at c ./linear-algebra/cond.m
+ at anchor{doc-cond}
+ at deftypefn {Function File} {} cond (@var{a}, at var{p})
+Compute the @var{p}-norm condition number of a matrix.  @code{cond (@var{a})} is
+defined as @code{norm (@var{a}, @var{p}) * norm (inv (@var{a}), @var{p})}.
+By default @code{@var{p}=2} is used which implies a (relatively slow)
+singular value decomposition.  Other possible selections are 
+ at code{@var{p}= 1, Inf, inf, 'Inf', 'fro'} which are generally faster.
+ at seealso{@ref{doc-condest,,condest}, @ref{doc-rcond,,rcond}, @ref{doc-norm,,norm}, @ref{doc-svd,,svd}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/det.cc
+ at anchor{doc-det}
+ at deftypefn {Loadable Function} {[@var{d}, @var{rcond}] =} det (@var{a})
+Compute the determinant of @var{a} using @sc{lapack} for full and UMFPACK
+for sparse matrices.  Return an estimate of the reciprocal condition number
+if requested.
+ at end deftypefn
+
+
+ at c ./deprecated/dmult.m
+ at anchor{doc-dmult}
+ at deftypefn {Function File} {} dmult (@var{a}, @var{b})
+This function has been deprecated.  Use the direct syntax @code{diag(A)*B}
+which is more readable and now also more efficient.
+ at end deftypefn
+
+
+ at c ./linear-algebra/dot.m
+ at anchor{doc-dot}
+ at deftypefn {Function File} {} dot (@var{x}, @var{y}, @var{dim})
+Computes the dot product of two vectors.  If @var{x} and @var{y}
+are matrices, calculate the dot-product along the first 
+non-singleton dimension.  If the optional argument @var{dim} is
+given, calculate the dot-product along this dimension.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/eig.cc
+ at anchor{doc-eig}
+ at deftypefn  {Loadable Function} {@var{lambda} =} eig (@var{a})
+ at deftypefnx {Loadable Function} {@var{lambda} =} eig (@var{a}, @var{b})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{lambda}] =} eig (@var{a})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{lambda}] =} eig (@var{a}, @var{b})
+The eigenvalues (and eigenvectors) of a matrix are computed in a several
+step process which begins with a Hessenberg decomposition, followed by a
+Schur decomposition, from which the eigenvalues are apparent.  The
+eigenvectors, when desired, are computed by further manipulations of the
+Schur decomposition.
+
+The eigenvalues returned by @code{eig} are not ordered.
+ at seealso{@ref{doc-eigs,,eigs}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/givens.cc
+ at anchor{doc-givens}
+ at deftypefn {Loadable Function} {@var{g} =} givens (@var{x}, @var{y})
+ at deftypefnx {Loadable Function} {[@var{c}, @var{s}] =} givens (@var{x}, @var{y})
+ at iftex
+ at tex
+Return a $2\times 2$ orthogonal matrix
+$$
+ G = \left[\matrix{c & s\cr -s'& c\cr}\right]
+$$
+such that
+$$
+ G \left[\matrix{x\cr y}\right] = \left[\matrix{\ast\cr 0}\right]
+$$
+with $x$ and $y$ scalars.
+ at end tex
+ at end iftex
+ at ifnottex
+Return a 2 by 2 orthogonal matrix
+ at code{@var{g} = [@var{c} @var{s}; - at var{s}' @var{c}]} such that
+ at code{@var{g} [@var{x}; @var{y}] = [*; 0]} with @var{x} and @var{y} scalars.
+ at end ifnottex
+
+For example,
+
+ at example
+ at group
+givens (1, 1)
+     @result{}   0.70711   0.70711
+         -0.70711   0.70711
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./linear-algebra/planerot.m
+ at anchor{doc-planerot}
+ at deftypefn {Function File} {[@var{g}, @var{y}] =} planerot (@var{x})
+Given a two-element column vector, returns the
+ at tex
+$2 \times 2$ orthogonal matrix
+ at end tex
+ at ifnottex
+2 by 2 orthogonal matrix
+ at end ifnottex
+ at var{G} such that
+ at code{@var{y} = @var{g} * @var{x}} and @code{@var{y}(2) = 0}.
+ at seealso{@ref{doc-givens,,givens}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/inv.cc
+ at anchor{doc-inv}
+ at deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inv (@var{a})
+ at deftypefnx {Loadable Function} {[@var{x}, @var{rcond}] =} inverse (@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.
+
+If called with a sparse matrix, then in general @var{x} will be a full
+matrix, and so if possible forming the inverse of a sparse matrix should
+be avoided.  It is significantly more accurate and faster to do
+ at code{@var{y} = @var{a} \ @var{b}}, rather than
+ at code{@var{y} = inv (@var{a}) * @var{b}}.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/matrix_type.cc
+ at anchor{doc-matrix_type}
+ at deftypefn {Loadable Function} {@var{type} =} matrix_type (@var{a})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, @var{type})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'upper', @var{perm})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'lower', @var{perm})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'banded', @var{nl}, @var{nu})
+Identify the matrix type or mark a matrix as a particular type.  This allows rapid
+for solutions of linear equations involving @var{a} to be performed.  Called with a
+single argument, @code{matrix_type} returns the type of the matrix and caches it for
+future use.  Called with more than one argument, @code{matrix_type} allows the type
+of the matrix to be defined.
+
+The possible matrix types depend on whether the matrix is full or sparse, and can be
+one of the following
+
+ at table @asis
+ at item 'unknown'
+Remove any previously cached matrix type, and mark type as unknown
+
+ at item 'full'
+Mark the matrix as full.
+
+ at item 'positive definite'
+Probable full positive definite matrix.
+
+ at item 'diagonal'
+Diagonal Matrix.  (Sparse matrices only)
+
+ at item 'permuted diagonal'
+Permuted Diagonal matrix.  The permutation does not need to be specifically
+indicated, as the structure of the matrix explicitly gives this.  (Sparse matrices
+only)
+
+ at item 'upper'
+Upper triangular.  If the optional third argument @var{perm} is given, the matrix is
+assumed to be a permuted upper triangular with the permutations defined by the
+vector @var{perm}.
+
+ at item 'lower'
+Lower triangular.  If the optional third argument @var{perm} is given, the matrix is
+assumed to be a permuted lower triangular with the permutations defined by the
+vector @var{perm}.
+
+ at item 'banded'
+ at itemx 'banded positive definite'
+Banded matrix with the band size of @var{nl} below the diagonal and @var{nu} above
+it.  If @var{nl} and @var{nu} are 1, then the matrix is tridiagonal and treated
+with specialized code.  In addition the matrix can be marked as probably a
+positive definite (Sparse matrices only)
+
+ at item 'singular'
+The matrix is assumed to be singular and will be treated with a minimum norm solution
+
+ at end table
+
+Note that the matrix type will be discovered automatically on the first attempt to
+solve a linear equation involving @var{a}.  Therefore @code{matrix_type} is only
+useful to give Octave hints of the matrix type.  Incorrectly defining the
+matrix type will result in incorrect results from solutions of linear equations,
+and so it is entirely the responsibility of the user to correctly identify the
+matrix type.
+
+Also the test for positive definiteness is a low-cost test for a hermitian
+matrix with a real positive diagonal.  This does not guarantee that the matrix
+is positive definite, but only that it is a probable candidate.  When such a
+matrix is factorized, a Cholesky factorization is first attempted, and if
+that fails the matrix is then treated with an LU factorization.  Once the
+matrix has been factorized, @code{matrix_type} will return the correct
+classification of the matrix.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-norm}
+ at deftypefn {Built-in Function} {} norm (@var{a}, @var{p}, @var{opt})
+Compute the p-norm of the matrix @var{a}.  If the second argument is
+missing, @code{p = 2} is assumed.
+
+If @var{a} is a matrix (or sparse matrix):
+
+ at table @asis
+ at item @var{p} = @code{1}
+1-norm, the largest column sum of the absolute values of @var{a}.
+
+ at item @var{p} = @code{2}
+Largest singular value of @var{a}.
+
+ at item @var{p} = @code{Inf} or @code{"inf"}
+ at cindex infinity norm
+Infinity norm, the largest row sum of the absolute values of @var{a}.
+
+ at item @var{p} = @code{"fro"}
+ at cindex Frobenius norm
+Frobenius norm of @var{a}, @code{sqrt (sum (diag (@var{a}' * @var{a})))}.
+
+ at item other @var{p}, @code{@var{p} > 1}
+ at cindex general p-norm 
+maximum @code{norm (A*x, p)} such that @code{norm (x, p) == 1}
+ at end table
+
+If @var{a} is a vector or a scalar:
+
+ at table @asis
+ at item @var{p} = @code{Inf} or @code{"inf"}
+ at code{max (abs (@var{a}))}.
+
+ at item @var{p} = @code{-Inf}
+ at code{min (abs (@var{a}))}.
+
+ at item @var{p} = @code{"fro"}
+Frobenius norm of @var{a}, @code{sqrt (sumsq (abs (a)))}.
+
+ at item @var{p} = 0
+Hamming norm - the number of nonzero elements.
+
+ at item other @var{p}, @code{@var{p} > 1}
+p-norm of @var{a}, @code{(sum (abs (@var{a}) .^ @var{p})) ^ (1/@var{p})}.
+
+ at item other @var{p} @code{@var{p} < 1}
+the p-pseudonorm defined as above.
+ at end table
+
+If @code{"rows"} is given as @var{opt}, the norms of all rows of the matrix @var{a} are
+returned as a column vector.  Similarly, if @code{"columns"} or @code{"cols"} is passed
+column norms are computed.
+ at seealso{@ref{doc-cond,,cond}, @ref{doc-svd,,svd}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/null.m
+ at anchor{doc-null}
+ at deftypefn {Function File} {} null (@var{a}, @var{tol})
+Return an orthonormal basis of the null space of @var{a}.
+
+The dimension of the null space is taken as the number of singular
+values of @var{a} not greater than @var{tol}.  If the argument @var{tol}
+is missing, it is computed as
+
+ at example
+max (size (@var{a})) * max (svd (@var{a})) * eps
+ at end example
+ at end deftypefn
+
+
+ at c ./linear-algebra/orth.m
+ at anchor{doc-orth}
+ at deftypefn {Function File} {} orth (@var{a}, @var{tol})
+Return an orthonormal basis of the range space of @var{a}.
+
+The dimension of the range space is taken as the number of singular
+values of @var{a} greater than @var{tol}.  If the argument @var{tol} is
+missing, it is computed as
+
+ at example
+max (size (@var{a})) * max (svd (@var{a})) * eps
+ at end example
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/pinv.cc
+ at anchor{doc-pinv}
+ at deftypefn {Loadable Function} {} pinv (@var{x}, @var{tol})
+Return the pseudoinverse of @var{x}.  Singular values less than
+ at var{tol} are ignored.  
+
+If the second argument is omitted, it is assumed that
+
+ at example
+tol = max (size (@var{x})) * sigma_max (@var{x}) * eps,
+ at end example
+
+ at noindent
+where @code{sigma_max (@var{x})} is the maximal singular value of @var{x}.
+ at end deftypefn
+
+
+ at c ./linear-algebra/rank.m
+ at anchor{doc-rank}
+ at deftypefn {Function File} {} rank (@var{a}, @var{tol})
+Compute the rank of @var{a}, using the singular value decomposition.
+The rank is taken to be the number of singular values of @var{a} that
+are greater than the specified tolerance @var{tol}.  If the second
+argument is omitted, it is taken to be
+
+ at example
+tol = max (size (@var{a})) * sigma(1) * eps;
+ at end example
+
+ at noindent
+where @code{eps} is machine precision and @code{sigma(1)} is the largest
+singular value of @var{a}.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/rcond.cc
+ at anchor{doc-rcond}
+ at deftypefn {Loadable Function} {@var{c} =} rcond (@var{a})
+Compute the 1-norm estimate of the reciprocal condition as returned
+by @sc{lapack}.  If the matrix is well-conditioned then @var{c} will be near
+1 and if the matrix is poorly conditioned it will be close to zero.
+
+The matrix @var{a} must not be sparse.  If the matrix is sparse then
+ at code{condest (@var{a})} or @code{rcond (full (@var{a}))} should be used
+instead.
+ at seealso{@ref{doc-inv,,inv}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/trace.m
+ at anchor{doc-trace}
+ at deftypefn {Function File} {} trace (@var{a})
+Compute the trace of @var{a}, @code{sum (diag (@var{a}))}.
+ at end deftypefn
+
+
+ at c ./linear-algebra/rref.m
+ at anchor{doc-rref}
+ at deftypefn {Function File} {[@var{r}, @var{k}] =} rref (@var{a}, @var{tol})
+
+Returns the reduced row echelon form of @var{a}.  @var{tol} defaults
+to @code{eps * max (size (@var{a})) * norm (@var{a}, inf)}.
+
+Called with two return arguments, @var{k} returns the vector of
+"bound variables", which are those columns on which elimination 
+has been performed.
+
+ at end deftypefn
+
+
+ at node Matrix Factorizations
+ at section Matrix Factorizations
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-chol}
+ at deftypefn {Loadable Function} {@var{r} =} chol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}] =} chol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} chol (@var{s})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} chol (@var{s}, 'vector')
+ at deftypefnx {Loadable Function} {[@var{l}, @dots{}] =} chol (@dots{}, 'lower')
+ at cindex Cholesky factorization
+Compute the Cholesky factor, @var{r}, of the symmetric positive definite
+matrix @var{a}, where
+ at iftex
+ at tex
+$ R^T R = A $.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{r}' * @var{r} = @var{a}.
+ at end example
+ at end ifnottex
+
+Called with one output argument @code{chol} fails if @var{a} or @var{s} is
+not positive definite.  With two or more output arguments @var{p} flags
+whether the matrix was positive definite and @code{chol} does not fail.  A
+zero value indicated that the matrix was positive definite and the @var{r}
+gives the factorization, and @var{p} will have a positive value otherwise.
+
+If called with 3 outputs then a sparsity preserving row/column permutation
+is applied to @var{a} prior to the factorization.  That is @var{r}
+is the factorization of @code{@var{a}(@var{q}, at var{q})} such that
+ at iftex
+ at tex
+$ R^T R = Q^T A Q$.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{r}' * @var{r} = @var{q}' * @var{a} * @var{q}.
+ at end example
+ at end ifnottex
+
+The sparsity preserving permutation is generally returned as a matrix.
+However, given the flag 'vector', @var{q} will be returned as a vector
+such that
+ at iftex
+ at tex
+$ R^T R = A (Q, Q)$.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{r}' * @var{r} = a (@var{q}, @var{q}).
+ at end example
+ at end ifnottex
+
+Called with either a sparse or full matrix and using the 'lower' flag,
+ at code{chol} returns the lower triangular factorization such that
+ at iftex
+ at tex
+$ L L^T = A $.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{l} * @var{l}' = @var{a}.
+ at end example
+ at end ifnottex
+
+In general the lower triangular factorization is significantly faster for
+sparse matrices.
+ at seealso{@ref{doc-cholinv,,cholinv}, @ref{doc-chol2inv,,chol2inv}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-cholinv}
+ at deftypefn {Loadable Function} {} cholinv (@var{a})
+Use the Cholesky factorization to compute the inverse of the
+symmetric positive definite matrix @var{a}.
+ at seealso{@ref{doc-chol,,chol}, @ref{doc-chol2inv,,chol2inv}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-chol2inv}
+ at deftypefn {Loadable Function} {} chol2inv (@var{u})
+Invert a symmetric, positive definite square matrix from its Cholesky
+decomposition, @var{u}.  Note that @var{u} should be an upper-triangular
+matrix with positive diagonal elements.  @code{chol2inv (@var{u})}
+provides @code{inv (@var{u}'*@var{u})} but it is much faster than
+using @code{inv}.
+ at seealso{@ref{doc-chol,,chol}, @ref{doc-cholinv,,cholinv}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-cholupdate}
+ at deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholupdate (@var{R}, @var{u}, @var{op})
+Update or downdate a Cholesky factorization.  Given an upper triangular
+matrix @var{R} and a column vector @var{u}, attempt to determine another
+upper triangular matrix @var{R1} such that
+ at itemize @bullet
+ at item
+ at var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'
+if @var{op} is "+"
+ at item
+ at var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'
+if @var{op} is "-"
+ at end itemize
+
+If @var{op} is "-", @var{info} is set to
+ at itemize
+ at item 0 if the downdate was successful,
+ at item 1 if @var{R}'*@var{R} - @var{u}*@var{u}' is not positive definite,
+ at item 2 if @var{R} is singular.
+ at end itemize
+
+If @var{info} is not present, an error message is printed in cases 1 and 2.
+ at seealso{@ref{doc-chol,,chol}, @ref{doc-qrupdate,,qrupdate}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-cholinsert}
+ at deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholinsert (@var{R}, @var{j}, @var{u})
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,
+return the Cholesky at tie{}factorization of
+ at var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and
+ at w{p = [1:j-1,j+1:n+1]}.  @w{u(j)} should be positive.
+On return, @var{info} is set to
+ at itemize
+ at item 0 if the insertion was successful,
+ at item 1 if @var{A1} is not positive definite,
+ at item 2 if @var{R} is singular.
+ at end itemize
+
+If @var{info} is not present, an error message is printed in cases 1 and 2.
+ at seealso{@ref{doc-chol,,chol}, @ref{doc-cholupdate,,cholupdate}, @ref{doc-choldelete,,choldelete}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-choldelete}
+ at deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,
+return the Cholesky at tie{}factorization of @w{A(p,p)}, where @w{p = [1:j-1,j+1:n+1]}.
+ at seealso{@ref{doc-chol,,chol}, @ref{doc-cholupdate,,cholupdate}, @ref{doc-cholinsert,,cholinsert}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/chol.cc
+ at anchor{doc-cholshift}
+ at deftypefn {Loadable Function} {@var{R1} =} cholshift (@var{R}, @var{i}, @var{j})
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,
+return the Cholesky at tie{}factorization of
+ at w{@var{A}(p,p)}, where @w{p} is the permutation @*
+ at code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*
+ or @*
+ at code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*
+
+ at seealso{@ref{doc-chol,,chol}, @ref{doc-cholinsert,,cholinsert}, @ref{doc-choldelete,,choldelete}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/hess.cc
+ at anchor{doc-hess}
+ at deftypefn {Loadable Function} {@var{h} =} hess (@var{a})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{h}] =} hess (@var{a})
+ at cindex Hessenberg decomposition
+Compute the Hessenberg decomposition of the matrix @var{a}.
+
+The Hessenberg decomposition is usually used as the first step in an
+eigenvalue computation, but has other applications as well (see Golub,
+Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).  The
+Hessenberg decomposition is
+ at iftex
+ at tex
+$$
+A = PHP^T
+$$
+where $P$ is a square unitary matrix ($P^HP = I$), and $H$
+is upper Hessenberg ($H_{i,j} = 0, \forall i \ge j+1$).
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{p * h * p' = a} where @code{p} is a square unitary matrix
+(@code{p' * p = I}, using complex-conjugate transposition) and @code{h}
+is upper Hessenberg (@code{i >= j+1 => h (i, j) = 0}).
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/lu.cc
+ at anchor{doc-lu}
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}] =} lu (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} lu (@var{s})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}] =} lu (@var{s})
+ at deftypefnx {Loadable Function} {[@dots{}] =} lu (@var{s}, @var{thres})
+ at deftypefnx {Loadable Function} {@var{y} =} lu (@dots{})
+ at deftypefnx {Loadable Function} {[@dots{}] =} lu (@dots{}, 'vector')
+ at cindex LU decomposition
+Compute the LU decomposition of @var{a}.  If @var{a} is full subroutines from
+ at sc{lapack} are used and if @var{a} is sparse then UMFPACK is used.  The
+result is returned in a permuted form, according to the optional return
+value @var{p}.  For example, given the matrix @code{a = [1, 2; 3, 4]},
+
+ at example
+[l, u, p] = lu (a)
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+l =
+
+  1.00000  0.00000
+  0.33333  1.00000
+
+u =
+
+  3.00000  4.00000
+  0.00000  0.66667
+
+p =
+
+  0  1
+  1  0
+ at end group
+ at end example
+
+The matrix is not required to be square.
+
+Called with two or three output arguments and a spare input matrix,
+then @dfn{lu} does not attempt to perform sparsity preserving column
+permutations.  Called with a fourth output argument, the sparsity
+preserving column transformation @var{Q} is returned, such that
+ at code{@var{p} * @var{a} * @var{q} = @var{l} * @var{u}}.
+
+Called with a fifth output argument and a sparse input matrix, then
+ at dfn{lu} attempts to use a scaling factor @var{r} on the input matrix
+such that @code{@var{p} * (@var{r} \ @var{a}) * @var{q} = @var{l} * @var{u}}.
+This typically leads to a sparser and more stable factorization.
+
+An additional input argument @var{thres}, that defines the pivoting
+threshold can be given.  @var{thres} can be a scalar, in which case
+it defines UMFPACK pivoting tolerance for both symmetric and unsymmetric
+cases.  If @var{thres} is a two element vector, then the first element
+defines the pivoting tolerance for the unsymmetric UMFPACK pivoting
+strategy and the second the symmetric strategy.  By default, the values
+defined by @code{spparms} are used and are by default @code{[0.1, 0.001]}.
+
+Given the string argument 'vector', @dfn{lu} returns the values of @var{p}
+ at var{q} as vector values, such that for full matrix, @code{@var{a}
+(@var{p},:) = @var{l} * @var{u}}, and @code{@var{r}(@var{p},:) * @var{a}
+(:, @var{q}) = @var{l} * @var{u}}.
+
+With two output arguments, returns the permuted forms of the upper and
+lower triangular matrices, such that @code{@var{a} = @var{l} * @var{u}}.
+With one output argument @var{y}, then the matrix returned by the @sc{lapack}
+routines is returned.  If the input matrix is sparse then the matrix @var{l}
+is embedded into @var{u} to give a return value similar to the full case.
+For both full and sparse matrices, @dfn{lu} looses the permutation
+information.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/qr.cc
+ at anchor{doc-qr}
+ at deftypefn {Loadable Function} {[@var{q}, @var{r}, @var{p}] =} qr (@var{a})
+ at deftypefnx {Loadable Function} {[@var{q}, @var{r}, @var{p}] =} qr (@var{a}, '0')
+ at cindex QR factorization
+Compute the QR factorization of @var{a}, using standard @sc{lapack}
+subroutines.  For example, given the matrix @code{a = [1, 2; 3, 4]},
+
+ at example
+[q, r] = qr (a)
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+q =
+
+  -0.31623  -0.94868
+  -0.94868   0.31623
+
+r =
+
+  -3.16228  -4.42719
+   0.00000  -0.63246
+ at end group
+ at end example
+
+The @code{qr} factorization has applications in the solution of least
+squares problems
+ at iftex
+ at tex
+$$
+\min_x \left\Vert A x - b \right\Vert_2
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at code{min norm(A x - b)}
+ at end example
+
+ at end ifnottex
+for overdetermined systems of equations (i.e.,
+ at iftex
+ at tex
+$A$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}
+ at end ifnottex
+ is a tall, thin matrix).  The QR factorization is
+ at iftex
+ at tex
+$QR = A$ where $Q$ is an orthogonal matrix and $R$ is upper triangular.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{q * r = a} where @code{q} is an orthogonal matrix and @code{r} is
+upper triangular.
+ at end ifnottex
+
+If given a second argument of '0', @code{qr} returns an economy-sized
+QR factorization, omitting zero rows of @var{R} and the corresponding
+columns of @var{Q}.
+
+If the matrix @var{a} is full, the permuted QR factorization
+ at code{[@var{q}, @var{r}, @var{p}] = qr (@var{a})} forms the QR factorization
+such that the diagonal entries of @code{r} are decreasing in magnitude
+order.  For example,given the matrix @code{a = [1, 2; 3, 4]},
+
+ at example
+[q, r, p] = qr(a)
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+q = 
+
+  -0.44721  -0.89443
+  -0.89443   0.44721
+
+r =
+
+  -4.47214  -3.13050
+   0.00000   0.44721
+
+p =
+
+   0  1
+   1  0
+ at end group
+ at end example
+
+The permuted @code{qr} factorization @code{[q, r, p] = qr (a)}
+factorization allows the construction of an orthogonal basis of
+ at code{span (a)}.
+
+If the matrix @var{a} is sparse, then compute the sparse QR factorization
+of @var{a}, using @sc{CSparse}.  As the matrix @var{Q} is in general a full
+matrix, this function returns the @var{Q}-less factorization @var{r} of
+ at var{a}, such that @code{@var{r} = chol (@var{a}' * @var{a})}.
+
+If the final argument is the scalar @code{0} and the number of rows is
+larger than the number of columns, then an economy factorization is
+returned.  That is @var{r} will have only @code{size (@var{a},1)} rows.
+
+If an additional matrix @var{b} is supplied, then @code{qr} returns
+ at var{c}, where @code{@var{c} = @var{q}' * @var{b}}.  This allows the
+least squares approximation of @code{@var{a} \ @var{b}} to be calculated
+as
+
+ at example
+ at group
+[@var{c}, at var{r}] = spqr (@var{a}, at var{b})
+ at var{x} = @var{r} \ @var{c}
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/qr.cc
+ at anchor{doc-qrupdate}
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrupdate (@var{Q}, @var{R}, @var{u}, @var{v})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization
+of @w{@var{A} + @var{u}*@var{v}'}, where @var{u} and @var{v} are
+column vectors (rank-1 update) or matrices with equal number of columns
+(rank-k update).  Notice that the latter case is done as a sequence of rank-1 updates;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+The QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+ at seealso{@ref{doc-qr,,qr}, @ref{doc-qrinsert,,qrinsert}, @ref{doc-qrdelete,,qrdelete}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/qr.cc
+ at anchor{doc-qrinsert}
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrinsert (@var{Q}, @var{R}, @var{j}, @var{x}, @var{orient})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization of
+ at w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be
+inserted into @var{A} (if @var{orient} is @code{"col"}), or the
+QR at tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}
+is a row vector to be inserted into @var{A} (if @var{orient} is
+ at code{"row"}).
+
+The default value of @var{orient} is @code{"col"}.
+If @var{orient} is @code{"col"},
+ at var{u} may be a matrix and @var{j} an index vector
+resulting in the QR at tie{}factorization of a matrix @var{B} such that
+ at w{B(:, at var{j})} gives @var{u} and @w{B(:, at var{j}) = []} gives @var{A}.
+Notice that the latter case is done as a sequence of k insertions;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+If @var{orient} is @code{"col"},
+the QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+If @var{orient} is @code{"row"}, full factorization is needed.
+ at seealso{@ref{doc-qr,,qr}, @ref{doc-qrupdate,,qrupdate}, @ref{doc-qrdelete,,qrdelete}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/qr.cc
+ at anchor{doc-qrdelete}
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrdelete (@var{Q}, @var{R}, @var{j}, @var{orient})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization of
+ at w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted
+(if @var{orient} is "col"), or the QR at tie{}factorization of
+ at w{[A(1:j-1,:);A(:,j+1:n)]}, i.e., @var{A} with one row deleted (if
+ at var{orient} is "row").
+
+The default value of @var{orient} is "col".
+
+If @var{orient} is @code{"col"},
+ at var{j} may be an index vector
+resulting in the QR at tie{}factorization of a matrix @var{B} such that
+ at w{A(:, at var{j}) = []} gives @var{B}.
+Notice that the latter case is done as a sequence of k deletions;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+If @var{orient} is @code{"col"},
+the QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+If @var{orient} is @code{"row"}, full factorization is needed.
+ at seealso{@ref{doc-qr,,qr}, @ref{doc-qrinsert,,qrinsert}, @ref{doc-qrupdate,,qrupdate}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/qr.cc
+ at anchor{doc-qrshift}
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrshift (@var{Q}, @var{R}, @var{i}, @var{j})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization
+of @w{@var{A}(:,p)}, where @w{p} is the permutation @*
+ at code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*
+ or @*
+ at code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*
+
+ at seealso{@ref{doc-qr,,qr}, @ref{doc-qrinsert,,qrinsert}, @ref{doc-qrdelete,,qrdelete}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/qz.cc
+ at anchor{doc-qz}
+ at deftypefn {Loadable Function} {@var{lambda} =} qz (@var{a}, @var{b})
+Generalized eigenvalue problem @math{A x = s B x},
+ at var{QZ} decomposition.  There are three ways to call this function:
+ at enumerate
+ at item @code{lambda = qz(A,B)}
+
+Computes the generalized eigenvalues
+ at iftex
+ at tex
+$\lambda$
+ at end tex
+ at end iftex
+ at ifnottex
+ at var{lambda}
+ at end ifnottex
+of @math{(A - s B)}.
+ at item @code{[AA, BB, Q, Z, V, W, lambda] = qz (A, B)}
+
+Computes qz decomposition, generalized eigenvectors, and 
+generalized eigenvalues of @math{(A - sB)}
+ at iftex
+ at tex
+$$ AV = BV{ \rm diag }(\lambda) $$
+$$ W^T A = { \rm diag }(\lambda)W^T B $$
+$$ AA = Q^T AZ, BB = Q^T BZ $$
+ at end tex
+ at end iftex
+ at ifnottex
+ at example
+ at group
+
+    A*V = B*V*diag(lambda)
+    W'*A = diag(lambda)*W'*B
+    AA = Q'*A*Z, BB = Q'*B*Z
+
+ at end group
+ at end example
+ at end ifnottex
+with @var{Q} and @var{Z} orthogonal (unitary)= @var{I}
+
+ at item @code{[AA,BB,Z@{, lambda@}] = qz(A,B,opt)}
+
+As in form [2], but allows ordering of generalized eigenpairs
+for (e.g.) solution of discrete time algebraic Riccati equations.
+Form 3 is not available for complex matrices, and does not compute
+the generalized eigenvectors @var{V}, @var{W}, nor the orthogonal matrix @var{Q}.
+ at table @var
+ at item opt
+for ordering eigenvalues of the GEP pencil.  The leading block
+of the revised pencil contains all eigenvalues that satisfy:
+ at table @code
+ at item "N"
+= unordered (default) 
+
+ at item "S"
+= small: leading block has all |lambda| <=1 
+
+ at item "B"
+= big: leading block has all |lambda| >= 1 
+
+ at item "-"
+= negative real part: leading block has all eigenvalues
+in the open left half-plane
+
+ at item "+"
+= non-negative real part: leading block has all eigenvalues
+in the closed right half-plane
+ at end table
+ at end table
+ at end enumerate
+
+Note: qz performs permutation balancing, but not scaling (see balance).
+Order of output arguments was selected for compatibility with @sc{matlab}
+
+ at seealso{@ref{doc-balance,,balance}, @ref{doc-eig,,eig}, @ref{doc-schur,,schur}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/qzhess.m
+ at anchor{doc-qzhess}
+ at deftypefn {Function File} {[@var{aa}, @var{bb}, @var{q}, @var{z}] =} qzhess (@var{a}, @var{b})
+Compute the Hessenberg-triangular decomposition of the matrix pencil
+ at code{(@var{a}, @var{b})}, returning
+ at code{@var{aa} = @var{q} * @var{a} * @var{z}},
+ at code{@var{bb} = @var{q} * @var{b} * @var{z}}, with @var{q} and @var{z}
+orthogonal.  For example,
+
+ at example
+ at group
+[aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
+     @result{} aa = [ -3.02244, -4.41741;  0.92998,  0.69749 ]
+     @result{} bb = [ -8.60233, -9.99730;  0.00000, -0.23250 ]
+     @result{}  q = [ -0.58124, -0.81373; -0.81373,  0.58124 ]
+     @result{}  z = [ 1, 0; 0, 1 ]
+ at end group
+ at end example
+
+The Hessenberg-triangular decomposition is the first step in
+Moler and Stewart's QZ decomposition algorithm.
+
+Algorithm taken from Golub and Van Loan, @cite{Matrix Computations, 2nd
+edition}.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/schur.cc
+ at anchor{doc-schur}
+ at deftypefn {Loadable Function} {@var{s} =} schur (@var{a})
+ at deftypefnx {Loadable Function} {[@var{u}, @var{s}] =} schur (@var{a}, @var{opt})
+ at cindex Schur decomposition
+The Schur decomposition is used to compute eigenvalues of a
+square matrix, and has applications in the solution of algebraic
+Riccati equations in control (see @code{are} and @code{dare}).
+ at code{schur} always returns
+ at iftex
+ at tex
+$S = U^T A U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s = u' * a * u}
+ at end ifnottex
+where
+ at iftex
+ at tex
+$U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{u}
+ at end ifnottex
+ is a unitary matrix
+ at iftex
+ at tex
+($U^T U$ is identity)
+ at end tex
+ at end iftex
+ at ifnottex
+(@code{u'* u} is identity)
+ at end ifnottex
+and
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+is upper triangular.  The eigenvalues of
+ at iftex
+ at tex
+$A$ (and $S$)
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a} (and @code{s})
+ at end ifnottex
+are the diagonal elements of
+ at iftex
+ at tex
+$S$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}.
+ at end ifnottex
+If the matrix
+ at iftex
+ at tex
+$A$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}
+ at end ifnottex
+is real, then the real Schur decomposition is computed, in which the
+matrix
+ at iftex
+ at tex
+$U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{u}
+ at end ifnottex
+is orthogonal and
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+is block upper triangular
+with blocks of size at most
+ at iftex
+ at tex
+$2\times 2$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{2 x 2}
+ at end ifnottex
+along the diagonal.  The diagonal elements of
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+(or the eigenvalues of the
+ at iftex
+ at tex
+$2\times 2$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{2 x 2}
+ at end ifnottex
+blocks, when
+appropriate) are the eigenvalues of
+ at iftex
+ at tex
+$A$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}
+ at end ifnottex
+and
+ at iftex
+ at tex
+$S$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}.
+ at end ifnottex
+
+The eigenvalues are optionally ordered along the diagonal according to
+the value of @code{opt}.  @code{opt = "a"} indicates that all
+eigenvalues with negative real parts should be moved to the leading
+block of
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+(used in @code{are}), @code{opt = "d"} indicates that all eigenvalues
+with magnitude less than one should be moved to the leading block of
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+(used in @code{dare}), and @code{opt = "u"}, the default, indicates that
+no ordering of eigenvalues should occur.  The leading
+ at iftex
+ at tex
+$k$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{k}
+ at end ifnottex
+columns of
+ at iftex
+ at tex
+$U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{u}
+ at end ifnottex
+always span the
+ at iftex
+ at tex
+$A$-invariant
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}-invariant
+ at end ifnottex
+subspace corresponding to the
+ at iftex
+ at tex
+$k$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{k}
+ at end ifnottex
+leading eigenvalues of
+ at iftex
+ at tex
+$S$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}.
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./linear-algebra/subspace.m
+ at anchor{doc-subspace}
+ at deftypefn {Function File} {@var{angle} =} subspace (@var{a}, @var{B})
+Determine the largest principal angle between two subspaces
+spanned by columns of matrices @var{a} and @var{b}.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/svd.cc
+ at anchor{doc-svd}
+ at deftypefn {Loadable Function} {@var{s} =} svd (@var{a})
+ at deftypefnx {Loadable Function} {[@var{u}, @var{s}, @var{v}] =} svd (@var{a})
+ at cindex singular value decomposition
+Compute the singular value decomposition of @var{a}
+ at iftex
+ at tex
+$$
+ A = U S V^H
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+A = U*S*V'
+ at end example
+ at end ifnottex
+
+The function @code{svd} normally returns the vector of singular values.
+If asked for three return values, it computes
+ at iftex
+ at tex
+$U$, $S$, and $V$.
+ at end tex
+ at end iftex
+ at ifnottex
+U, S, and V.
+ at end ifnottex
+For example,
+
+ at example
+svd (hilb (3))
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+ans =
+
+  1.4083189
+  0.1223271
+  0.0026873
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+[u, s, v] = svd (hilb (3))
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+u =
+
+  -0.82704   0.54745   0.12766
+  -0.45986  -0.52829  -0.71375
+  -0.32330  -0.64901   0.68867
+
+s =
+
+  1.40832  0.00000  0.00000
+  0.00000  0.12233  0.00000
+  0.00000  0.00000  0.00269
+
+v =
+
+  -0.82704   0.54745   0.12766
+  -0.45986  -0.52829  -0.71375
+  -0.32330  -0.64901   0.68867
+ at end group
+ at end example
+
+If given a second argument, @code{svd} returns an economy-sized
+decomposition, eliminating the unnecessary rows or columns of @var{u} or
+ at var{v}.
+ at end deftypefn
+
+
+ at c FIXME -- should there be a new section here?
+
+ at c ./linear-algebra/housh.m
+ at anchor{doc-housh}
+ at deftypefn {Function File} {[@var{housv}, @var{beta}, @var{zer}] =} housh (@var{x}, @var{j}, @var{z})
+Compute Householder reflection vector @var{housv} to reflect @var{x}
+to be the j-th column of identity, i.e.,
+
+ at example
+ at group
+(I - beta*housv*housv')x =  norm(x)*e(j) if x(1) < 0,
+(I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0
+ at end group
+ at end example
+
+ at noindent
+Inputs
+
+ at table @var
+ at item x
+vector
+ at item j
+index into vector
+ at item z
+threshold for zero  (usually should be the number 0)
+ at end table
+
+ at noindent
+Outputs (see Golub and Van Loan):
+
+ at table @var
+ at item beta
+If beta = 0, then no reflection need be applied (zer set to 0)
+ at item housv
+householder vector
+ at end table
+ at end deftypefn
+
+
+ at c ./linear-algebra/krylov.m
+ at anchor{doc-krylov}
+ at deftypefn {Function File} {[@var{u}, @var{h}, @var{nu}] =} krylov (@var{a}, @var{v}, @var{k}, @var{eps1}, @var{pflg})
+Construct an orthogonal basis @var{u} of block Krylov subspace
+
+ at example
+[v a*v a^2*v @dots{} a^(k+1)*v]
+ at end example
+
+ at noindent
+Using Householder reflections to guard against loss of orthogonality.
+
+If @var{v} is a vector, then @var{h} contains the Hessenberg matrix
+such that @code{a*u == u*h+rk*ek'}, in which @code{rk =
+a*u(:,k)-u*h(:,k)}, and @code{ek'} is the vector
+ at code{[0, 0, @dots{}, 1]} of length @code{k}.  Otherwise, @var{h} is
+meaningless.
+
+If @var{v} is a vector and @var{k} is greater than
+ at code{length(A)-1}, then @var{h} contains the Hessenberg matrix such
+that @code{a*u == u*h}.
+
+The value of @var{nu} is the dimension of the span of the krylov
+subspace (based on @var{eps1}).
+
+If @var{b} is a vector and @var{k} is greater than @var{m-1}, then
+ at var{h} contains the Hessenberg decomposition of @var{a}.
+
+The optional parameter @var{eps1} is the threshold for zero.  The
+default value is 1e-12.
+
+If the optional parameter @var{pflg} is nonzero, row pivoting is used
+to improve numerical behavior.  The default value is 0.
+
+Reference: Hodel and Misra, "Partial Pivoting in the Computation of
+Krylov Subspaces", to be submitted to Linear Algebra and its
+Applications
+ at end deftypefn
+
+
+ at node Functions of a Matrix
+ at section Functions of a Matrix
+
+ at c ./linear-algebra/expm.m
+ at anchor{doc-expm}
+ at deftypefn {Function File} {} expm (@var{a})
+Return the exponential of a matrix, defined as the infinite Taylor
+series
+ at tex
+$$
+ \exp (A) = I + A + {A^2 \over 2!} + {A^3 \over 3!} + \cdots
+$$
+ at end tex
+ at ifnottex
+
+ at example
+expm(a) = I + a + a^2/2! + a^3/3! + @dots{}
+ at end example
+
+ at end ifnottex
+The Taylor series is @emph{not} the way to compute the matrix
+exponential; see Moler and Van Loan, @cite{Nineteen Dubious Ways to
+Compute the Exponential of a Matrix}, SIAM Review, 1978.  This routine
+uses Ward's diagonal
+ at tex
+Pad\'e
+ at end tex
+ at ifnottex
+Pade'
+ at end ifnottex
+approximation method with three step preconditioning (SIAM Journal on
+Numerical Analysis, 1977).  Diagonal
+ at tex
+Pad\'e
+ at end tex
+ at ifnottex
+Pade'
+ at end ifnottex
+ approximations are rational polynomials of matrices
+ at tex
+$D_q(a)^{-1}N_q(a)$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     -1
+D (a)   N (a)
+ at end group
+ at end example
+
+ at end ifnottex
+ whose Taylor series matches the first
+ at tex
+$2 q + 1 $
+ at end tex
+ at ifnottex
+ at code{2q+1}
+ at end ifnottex
+terms of the Taylor series above; direct evaluation of the Taylor series
+(with the same preconditioning steps) may be desirable in lieu of the
+ at tex
+Pad\'e
+ at end tex
+ at ifnottex
+Pade'
+ at end ifnottex
+approximation when
+ at tex
+$D_q(a)$
+ at end tex
+ at ifnottex
+ at code{Dq(a)}
+ at end ifnottex
+is ill-conditioned.
+ at end deftypefn
+
+
+ at c ./linear-algebra/logm.m
+ at anchor{doc-logm}
+ at deftypefn {Function File} {} logm (@var{a})
+Compute the matrix logarithm of the square matrix @var{a}.  Note that
+this is currently implemented in terms of an eigenvalue expansion and
+needs to be improved to be more robust.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/sqrtm.cc
+ at anchor{doc-sqrtm}
+ at deftypefn {Loadable Function} {[@var{result}, @var{error_estimate}] =} sqrtm (@var{a})
+Compute the matrix square root of the square matrix @var{a}.
+
+Ref: Nicholas J. Higham.  A new sqrtm for @sc{matlab}.  Numerical Analysis
+Report No. 336, Manchester Centre for Computational Mathematics,
+Manchester, England, January 1999.
+ at seealso{@ref{doc-expm,,expm}, @ref{doc-logm,,logm}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/kron.cc
+ at anchor{doc-kron}
+ at deftypefn {Loadable Function} {} kron (@var{a}, @var{b})
+Form the kronecker product of two matrices, defined block by block as
+
+ at example
+x = [a(i, j) b]
+ at end example
+
+For example,
+
+ at example
+ at group
+kron (1:4, ones (3, 1))
+      @result{}  1  2  3  4
+          1  2  3  4
+          1  2  3  4
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/syl.cc
+ at anchor{doc-syl}
+ at deftypefn {Loadable Function} {@var{x} =} syl (@var{a}, @var{b}, @var{c})
+Solve the Sylvester equation
+ at iftex
+ at tex
+$$
+ A X + X B + C = 0
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+A X + X B + C = 0
+ at end example
+ at end ifnottex
+using standard @sc{lapack} subroutines.  For example,
+
+ at example
+ at group
+syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
+     @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at node Specialized Solvers
+ at section Specialized Solvers
+
+ at c ./sparse/bicgstab.m
+ at anchor{doc-bicgstab}
+ at deftypefn {Function File} {} bicgstab (@var{A}, @var{b})
+ at deftypefnx {Function File} {} bicgstab (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+This procedure attempts to solve a system of linear equations A*x = b for x.
+The @var{A} must be square, symmetric and positive definite real matrix N*N.
+The @var{b} must be a one column vector with a length of N.
+The @var{tol} specifies the tolerance of the method, the default value is 1e-6.
+The @var{maxit} specifies the maximum number of iterations, the default value is min(20,N).
+The @var{M1} specifies a preconditioner, can also be a function handler which returns M\X.
+The @var{M2} combined with @var{M1} defines preconditioner as preconditioner=M1*M2.
+The @var{x0} is the initial guess, the default value is zeros(N,1).
+
+The value @var{x} is a computed result of this procedure.
+The value @var{flag} can be 0 when we reach tolerance in @var{maxit} iterations, 1 when
+we don't reach tolerance in @var{maxit} iterations and 3 when the procedure stagnates.
+The value @var{relres} is a relative residual - norm(b-A*x)/norm(b).
+The value @var{iter} is an iteration number in which x was computed.
+The value @var{resvec} is a vector of @var{relres} for each iteration.
+
+ at end deftypefn
+
+
+ at c ./sparse/cgs.m
+ at anchor{doc-cgs}
+ at deftypefn {Function File} {} cgs (@var{A}, @var{b})
+ at deftypefnx {Function File} {} cgs (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+This procedure attempts to solve a system of linear equations A*x = b for x.
+The @var{A} must be square, symmetric and positive definite real matrix N*N.
+The @var{b} must be a one column vector with a length of N.
+The @var{tol} specifies the tolerance of the method, default value is 1e-6.
+The @var{maxit} specifies the maximum number of iteration, default value is MIN(20,N).
+The @var{M1} specifies a preconditioner, can also be a function handler which returns M\X.
+The @var{M2} combined with @var{M1} defines preconditioner as preconditioner=M1*M2.
+The @var{x0} is initial guess, default value is zeros(N,1).
+
+ at end deftypefn
+
diff --git a/doc/interpreter/linalg.txi b/doc/interpreter/linalg.txi
new file mode 100644
index 0000000..8ec6f96
--- /dev/null
+++ b/doc/interpreter/linalg.txi
@@ -0,0 +1,186 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Linear Algebra
+ at chapter Linear Algebra
+
+This chapter documents the linear algebra functions of Octave.
+Reference material for many of these functions may be found in
+Golub and Van Loan, @cite{Matrix Computations, 2nd Ed.}, Johns Hopkins,
+1989, and in the @cite{@sc{lapack} Users' Guide}, SIAM, 1992.
+
+ at menu
+* Techniques used for Linear Algebra::
+* Basic Matrix Functions::      
+* Matrix Factorizations::       
+* Functions of a Matrix::       
+* Specialized Solvers::
+ at end menu
+
+ at node Techniques used for Linear Algebra
+ at section Techniques used for Linear Algebra
+
+Octave includes a polymorphic solver, that selects an appropriate
+matrix factorization depending on the properties of the matrix itself. 
+Generally, the cost of determining the matrix type is small relative to 
+the cost of factorizing the matrix itself, but in any case the matrix 
+type is cached once it is calculated, so that it is not re-determined 
+each time it is used in a linear equation.
+
+The selection tree for how the linear equation is solve or a matrix
+inverse is form is given by
+
+ at enumerate 1
+ at item If the matrix is upper or lower triangular sparse a forward or
+backward substitution using the @sc{lapack} xTRTRS function, and goto 4.
+
+ at c Permuted triangular matrices currently disabled in the code
+ at c
+ at c @item If the matrix is a upper triangular matrix with column permutations
+ at c or lower triangular matrix with row permutations, perform a forward or
+ at c backward substitution, and goto 5.
+
+ at item If the matrix is square, hermitian with a real positive diagonal,
+attempt Cholesky factorization using the @sc{lapack} xPOTRF function.
+
+ at item If the Cholesky factorization failed or the matrix is not
+hermitian with a real positive diagonal, and the matrix is square, factorize 
+using the @sc{lapack} xGETRF function.
+
+ at item If the matrix is not square, or any of the previous solvers flags
+a singular or near singular matrix, find a least squares solution using
+the @sc{lapack} xGELSD function.
+ at end enumerate
+
+The user can force the type of the matrix with the @code{matrix_type}
+function.  This overcomes the cost of discovering the type of the matrix.
+However, it should be noted that identifying the type of the matrix incorrectly
+will lead to unpredictable results, and so @code{matrix_type} should be
+used with care.
+
+It should be noted that the test for whether a matrix is a candidate for
+Cholesky factorization, performed above and by the @code{matrix_type}
+function, does not give a certainty that the matrix is
+Hermitian.  However, the attempt to factorize the matrix will quickly
+flag a non-Hermitian matrix.
+
+ at node Basic Matrix Functions
+ at section Basic Matrix Functions
+
+ at DOCSTRING(balance)
+
+ at DOCSTRING(cond)
+
+ at DOCSTRING(det)
+
+ at DOCSTRING(dmult)
+
+ at DOCSTRING(dot)
+
+ at DOCSTRING(eig)
+
+ at DOCSTRING(givens)
+
+ at DOCSTRING(planerot)
+
+ at DOCSTRING(inv)
+
+ at DOCSTRING(matrix_type)
+
+ at DOCSTRING(norm)
+
+ at DOCSTRING(null)
+
+ at DOCSTRING(orth)
+
+ at DOCSTRING(pinv)
+
+ at DOCSTRING(rank)
+
+ at DOCSTRING(rcond)
+
+ at DOCSTRING(trace)
+
+ at DOCSTRING(rref)
+
+ at node Matrix Factorizations
+ at section Matrix Factorizations
+
+ at DOCSTRING(chol)
+
+ at DOCSTRING(cholinv)
+
+ at DOCSTRING(chol2inv)
+
+ at DOCSTRING(cholupdate)
+
+ at DOCSTRING(cholinsert)
+
+ at DOCSTRING(choldelete)
+
+ at DOCSTRING(cholshift)
+
+ at DOCSTRING(hess)
+
+ at DOCSTRING(lu)
+
+ at DOCSTRING(qr)
+
+ at DOCSTRING(qrupdate)
+
+ at DOCSTRING(qrinsert)
+
+ at DOCSTRING(qrdelete)
+
+ at DOCSTRING(qrshift)
+
+ at DOCSTRING(qz)
+
+ at DOCSTRING(qzhess)
+
+ at DOCSTRING(schur)
+
+ at DOCSTRING(subspace)
+
+ at DOCSTRING(svd)
+
+ at c FIXME -- should there be a new section here?
+
+ at DOCSTRING(housh)
+
+ at DOCSTRING(krylov)
+
+ at node Functions of a Matrix
+ at section Functions of a Matrix
+
+ at DOCSTRING(expm)
+
+ at DOCSTRING(logm)
+
+ at DOCSTRING(sqrtm)
+
+ at DOCSTRING(kron)
+
+ at DOCSTRING(syl)
+
+ at node Specialized Solvers
+ at section Specialized Solvers
+
+ at DOCSTRING(bicgstab)
+
+ at DOCSTRING(cgs)
diff --git a/doc/interpreter/matrix.texi b/doc/interpreter/matrix.texi
new file mode 100644
index 0000000..ef7c6a4
--- /dev/null
+++ b/doc/interpreter/matrix.texi
@@ -0,0 +1,1723 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Matrix Manipulation
+ at chapter Matrix Manipulation
+
+There are a number of functions available for checking to see if the
+elements of a matrix meet some condition, and for rearranging the
+elements of a matrix.  For example, Octave can easily tell you if all
+the elements of a matrix are finite, or are less than some specified
+value.  Octave can also rotate the elements, extract the upper- or
+lower-triangular parts, or sort the columns of a matrix.
+
+ at menu
+* Finding Elements and Checking Conditions::  
+* Rearranging Matrices::        
+* Applying a Function to an Array::
+* Special Utility Matrices::    
+* Famous Matrices::             
+ at end menu
+
+ at node Finding Elements and Checking Conditions
+ at section Finding Elements and Checking Conditions
+
+The functions @code{any} and @code{all} are useful for determining
+whether any or all of the elements of a matrix satisfy some condition.
+The @code{find} function is also useful in determining which elements of
+a matrix meet a specified condition.
+
+ at c data.cc
+ at anchor{doc-any}
+ at deftypefn {Built-in Function} {} any (@var{x}, @var{dim})
+For a vector argument, return 1 if any element of the vector is
+nonzero.
+
+For a matrix argument, return a row vector of ones and
+zeros with each element indicating whether any of the elements of the
+corresponding column of the matrix are nonzero.  For example,
+
+ at example
+ at group
+any (eye (2, 4))
+     @result{} [ 1, 1, 0, 0 ]
+ at end group
+ at end example
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.  For example,
+
+ at example
+ at group
+any (eye (2, 4), 2)
+     @result{} [ 1; 1 ]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-all}
+ at deftypefn {Built-in Function} {} all (@var{x}, @var{dim})
+The function @code{all} behaves like the function @code{any}, except
+that it returns true only if all the elements of a vector, or all the
+elements along dimension @var{dim} of a matrix, are nonzero.
+ at end deftypefn
+
+
+Since the comparison operators (@pxref{Comparison Ops}) return matrices
+of ones and zeros, it is easy to test a matrix for many things, not just
+whether the elements are nonzero.  For example, 
+
+ at example
+ at group
+all (all (rand (5) < 0.9))
+     @result{} 0
+ at end group
+ at end example
+
+ at noindent
+tests a random 5 by 5 matrix to see if all of its elements are less
+than 0.9.
+
+Note that in conditional contexts (like the test clause of @code{if} and
+ at code{while} statements) Octave treats the test as if you had typed
+ at code{all (all (condition))}.
+
+ at c ./miscellaneous/xor.m
+ at anchor{doc-xor}
+ at deftypefn {Mapping Function} {} xor (@var{x}, @var{y})
+Return the `exclusive or' of the entries of @var{x} and @var{y}.
+For boolean expressions @var{x} and @var{y},
+ at code{xor (@var{x}, @var{y})} is true if and only if @var{x} or @var{y}
+is true, but not if both @var{x} and @var{y} are true.
+ at end deftypefn
+
+
+ at c ./general/is_duplicate_entry.m
+ at anchor{doc-is_duplicate_entry}
+ at deftypefn {Function File} {} is_duplicate_entry (@var{x})
+Return non-zero if any entries in @var{x} are duplicates of one
+another.
+ at end deftypefn
+
+
+ at c ./general/diff.m
+ at anchor{doc-diff}
+ at deftypefn {Function File} {} diff (@var{x}, @var{k}, @var{dim})
+If @var{x} is a vector of length @var{n}, @code{diff (@var{x})} is the
+vector of first differences
+ at tex
+ $x_2 - x_1, \ldots{}, x_n - x_{n-1}$.
+ at end tex
+ at ifnottex
+ at var{x}(2) - @var{x}(1), @dots{}, @var{x}(n) - @var{x}(n-1).
+ at end ifnottex
+
+If @var{x} is a matrix, @code{diff (@var{x})} is the matrix of column
+differences along the first non-singleton dimension.
+
+The second argument is optional.  If supplied, @code{diff (@var{x},
+ at var{k})}, where @var{k} is a non-negative integer, returns the
+ at var{k}-th differences.  It is possible that @var{k} is larger than
+then first non-singleton dimension of the matrix.  In this case,
+ at code{diff} continues to take the differences along the next
+non-singleton dimension.
+
+The dimension along which to take the difference can be explicitly
+stated with the optional variable @var{dim}.  In this case the 
+ at var{k}-th order differences are calculated along this dimension.
+In the case where @var{k} exceeds @code{size (@var{x}, @var{dim})}
+then an empty matrix is returned.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isinf}
+ at deftypefn {Mapping Function} {} isinf (@var{x})
+Return 1 for elements of @var{x} that are infinite and zero
+otherwise.  For example,
+
+ at example
+ at group
+isinf ([13, Inf, NA, NaN])
+     @result{} [ 0, 1, 0, 0 ]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isnan}
+ at deftypefn {Mapping Function} {} isnan (@var{x})
+Return 1 for elements of @var{x} that are NaN values and zero
+otherwise.  NA values are also considered NaN values.  For example,
+
+ at example
+ at group
+isnan ([13, Inf, NA, NaN])
+     @result{} [ 0, 0, 1, 1 ]
+ at end group
+ at end example
+ at seealso{@ref{doc-isna,,isna}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-finite}
+ at deftypefn {Mapping Function} {} finite (@var{x})
+Return 1 for elements of @var{x} that are finite values and zero
+otherwise.  For example,
+
+ at example
+ at group
+finite ([13, Inf, NA, NaN])
+     @result{} [ 1, 0, 0, 0 ]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/find.cc
+ at anchor{doc-find}
+ at deftypefn {Loadable Function} {} find (@var{x})
+ at deftypefnx {Loadable Function} {} find (@var{x}, @var{n})
+ at deftypefnx {Loadable Function} {} find (@var{x}, @var{n}, @var{direction})
+Return a vector of indices of nonzero elements of a matrix, as a row if
+ at var{x} is a row or as a column otherwise.  To obtain a single index for
+each matrix element, Octave pretends that the columns of a matrix form one
+long vector (like Fortran arrays are stored).  For example,
+
+ at example
+ at group
+find (eye (2))
+     @result{} [ 1; 4 ]
+ at end group
+ at end example
+
+If two outputs are requested, @code{find} returns the row and column
+indices of nonzero elements of a matrix.  For example,
+
+ at example
+ at group
+[i, j] = find (2 * eye (2))
+     @result{} i = [ 1; 2 ]
+     @result{} j = [ 1; 2 ]
+ at end group
+ at end example
+
+If three outputs are requested, @code{find} also returns a vector
+containing the nonzero values.  For example,
+
+ at example
+ at group
+[i, j, v] = find (3 * eye (2))
+     @result{} i = [ 1; 2 ]
+     @result{} j = [ 1; 2 ]
+     @result{} v = [ 3; 3 ]
+ at end group
+ at end example
+
+If two inputs are given, @var{n} indicates the maximum number of
+elements to find from the beginning of the matrix or vector.
+
+If three inputs are given, @var{direction} should be one of "first" or
+"last", requesting only the first or last @var{n} indices, respectively.
+However, the indices are always returned in ascending order.
+
+Note that this function is particularly useful for sparse matrices, as
+it extracts the non-zero elements as vectors, which can then be used to
+create the original matrix.  For example,
+
+ at example
+ at group
+sz = size(a);
+[i, j, v] = find (a);
+b = sparse(i, j, v, sz(1), sz(2));
+ at end group
+ at end example
+ at seealso{@ref{doc-sparse,,sparse}}
+ at end deftypefn
+
+        
+ at c ./general/common_size.m
+ at anchor{doc-common_size}
+ at deftypefn {Function File} {[@var{err}, @var{y1}, @dots{}] =} common_size (@var{x1}, @dots{})
+Determine if all input arguments are either scalar or of common
+size.  If so, @var{err} is zero, and @var{yi} is a matrix of the
+common size with all entries equal to @var{xi} if this is a scalar or
+ at var{xi} otherwise.  If the inputs cannot be brought to a common size,
+errorcode is 1, and @var{yi} is @var{xi}.  For example,
+
+ at example
+ at group
+[errorcode, a, b] = common_size ([1 2; 3 4], 5)
+     @result{} errorcode = 0
+     @result{} a = [ 1, 2; 3, 4 ]
+     @result{} b = [ 5, 5; 5, 5 ]
+ at end group
+ at end example
+
+ at noindent
+This is useful for implementing functions where arguments can either
+be scalars or of common size.
+ at end deftypefn
+
+
+ at node Rearranging Matrices
+ at section Rearranging Matrices
+
+ at c ./general/fliplr.m
+ at anchor{doc-fliplr}
+ at deftypefn {Function File} {} fliplr (@var{x})
+Return a copy of @var{x} with the order of the columns reversed.  For
+example,
+
+ at example
+ at group
+fliplr ([1, 2; 3, 4])
+     @result{}  2  1
+         4  3
+ at end group
+ at end example
+
+Note that @code{fliplr} only work with 2-D arrays.  To flip N-d arrays
+use @code{flipdim} instead.
+ at seealso{@ref{doc-flipud,,flipud}, @ref{doc-flipdim,,flipdim}, @ref{doc-rot90,,rot90}, @ref{doc-rotdim,,rotdim}}
+ at end deftypefn
+
+
+ at c ./general/flipud.m
+ at anchor{doc-flipud}
+ at deftypefn {Function File} {} flipud (@var{x})
+Return a copy of @var{x} with the order of the rows reversed.  For
+example,
+
+ at example
+ at group
+flipud ([1, 2; 3, 4])
+     @result{}  3  4
+         1  2
+ at end group
+ at end example
+
+Due to the difficulty of defining which axis about which to flip the 
+matrix @code{flipud} only work with 2-d arrays.  To flip N-d arrays
+use @code{flipdim} instead.
+ at seealso{@ref{doc-fliplr,,fliplr}, @ref{doc-flipdim,,flipdim}, @ref{doc-rot90,,rot90}, @ref{doc-rotdim,,rotdim}}
+ at end deftypefn
+
+
+ at c ./general/flipdim.m
+ at anchor{doc-flipdim}
+ at deftypefn {Function File} {} flipdim (@var{x}, @var{dim})
+Return a copy of @var{x} flipped about the dimension @var{dim}.
+For example
+
+ at example
+ at group
+flipdim ([1, 2; 3, 4], 2)
+     @result{}  2  1
+         4  3
+ at end group
+ at end example
+ at seealso{@ref{doc-fliplr,,fliplr}, @ref{doc-flipud,,flipud}, @ref{doc-rot90,,rot90}, @ref{doc-rotdim,,rotdim}}
+ at end deftypefn
+
+
+ at c ./general/rot90.m
+ at anchor{doc-rot90}
+ at deftypefn {Function File} {} rot90 (@var{x}, @var{n})
+Return a copy of @var{x} with the elements rotated counterclockwise in
+90-degree increments.  The second argument is optional, and specifies
+how many 90-degree rotations are to be applied (the default value is 1).
+Negative values of @var{n} rotate the matrix in a clockwise direction.
+For example,
+
+ at example
+ at group
+rot90 ([1, 2; 3, 4], -1)
+     @result{}  3  1
+         4  2
+ at end group
+ at end example
+
+ at noindent
+rotates the given matrix clockwise by 90 degrees.  The following are all
+equivalent statements:
+
+ at example
+ at group
+rot90 ([1, 2; 3, 4], -1)
+rot90 ([1, 2; 3, 4], 3)
+rot90 ([1, 2; 3, 4], 7)
+ at end group
+ at end example
+
+Due to the difficulty of defining an axis about which to rotate the 
+matrix @code{rot90} only work with 2-D arrays.  To rotate N-d arrays
+use @code{rotdim} instead.
+ at seealso{@ref{doc-rotdim,,rotdim}, @ref{doc-flipud,,flipud}, @ref{doc-fliplr,,fliplr}, @ref{doc-flipdim,,flipdim}}
+ at end deftypefn
+
+
+ at c ./general/rotdim.m
+ at anchor{doc-rotdim}
+ at deftypefn {Function File} {} rotdim (@var{x}, @var{n}, @var{plane})
+Return a copy of @var{x} with the elements rotated counterclockwise in
+90-degree increments.  The second argument is optional, and specifies
+how many 90-degree rotations are to be applied (the default value is 1).
+The third argument is also optional and defines the plane of the
+rotation.  As such @var{plane} is a two element vector containing two
+different valid dimensions of the matrix.  If @var{plane} is not given
+Then the first two non-singleton dimensions are used.
+
+Negative values of @var{n} rotate the matrix in a clockwise direction.
+For example,
+
+ at example
+ at group
+rotdim ([1, 2; 3, 4], -1, [1, 2])
+     @result{}  3  1
+         4  2
+ at end group
+ at end example
+
+ at noindent
+rotates the given matrix clockwise by 90 degrees.  The following are all
+equivalent statements:
+
+ at example
+ at group
+rotdim ([1, 2; 3, 4], -1, [1, 2])
+rotdim ([1, 2; 3, 4], 3, [1, 2])
+rotdim ([1, 2; 3, 4], 7, [1, 2])
+ at end group
+ at end example
+ at seealso{@ref{doc-rot90,,rot90}, @ref{doc-flipud,,flipud}, @ref{doc-fliplr,,fliplr}, @ref{doc-flipdim,,flipdim}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-cat}
+ at deftypefn {Built-in Function} {} cat (@var{dim}, @var{array1}, @var{array2}, @dots{}, @var{arrayN})
+Return the concatenation of N-d array objects, @var{array1},
+ at var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.
+
+ at example
+ at group
+A = ones (2, 2);
+B = zeros (2, 2);
+cat (2, A, B)
+ at result{} ans =
+
+     1 1 0 0
+     1 1 0 0
+ at end group
+ at end example
+
+Alternatively, we can concatenate @var{A} and @var{B} along the
+second dimension the following way:
+
+ at example
+ at group
+[A, B].
+ at end group
+ at end example
+
+ at var{dim} can be larger than the dimensions of the N-d array objects
+and the result will thus have @var{dim} dimensions as the
+following example shows:
+ at example
+ at group
+cat (4, ones(2, 2), zeros (2, 2))
+ at result{} ans =
+
+   ans(:,:,1,1) =
+
+     1 1
+     1 1
+
+   ans(:,:,1,2) =
+     0 0
+     0 0
+ at end group
+ at end example
+ at seealso{@ref{doc-horzcat,,horzcat}, @ref{doc-vertcat,,vertcat}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-horzcat}
+ at deftypefn {Built-in Function} {} horzcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})
+Return the horizontal concatenation of N-d array objects, @var{array1},
+ at var{array2}, @dots{}, @var{arrayN} along dimension 2.
+ at seealso{@ref{doc-cat,,cat}, @ref{doc-vertcat,,vertcat}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-vertcat}
+ at deftypefn {Built-in Function} {} vertcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})
+Return the vertical concatenation of N-d array objects, @var{array1},
+ at var{array2}, @dots{}, @var{arrayN} along dimension 1.
+ at seealso{@ref{doc-cat,,cat}, @ref{doc-horzcat,,horzcat}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-permute}
+ at deftypefn {Built-in Function} {} permute (@var{a}, @var{perm})
+Return the generalized transpose for an N-d array object @var{a}.
+The permutation vector @var{perm} must contain the elements
+ at code{1:ndims(a)} (in any order, but each element must appear just once).
+ at seealso{@ref{doc-ipermute,,ipermute}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-ipermute}
+ at deftypefn {Built-in Function} {} ipermute (@var{a}, @var{iperm})
+The inverse of the @code{permute} function.  The expression
+
+ at example
+ipermute (permute (a, perm), perm)
+ at end example
+returns the original array @var{a}.
+ at seealso{@ref{doc-permute,,permute}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-reshape}
+ at deftypefn {Built-in Function} {} reshape (@var{a}, @var{m}, @var{n}, @dots{})
+ at deftypefnx {Built-in Function} {} reshape (@var{a}, @var{size})
+Return a matrix with the given dimensions whose elements are taken
+from the matrix @var{a}.  The elements of the matrix are accessed in
+column-major order (like Fortran arrays are stored).
+
+For example,
+
+ at example
+ at group
+reshape ([1, 2, 3, 4], 2, 2)
+     @result{}  1  3
+         2  4
+ at end group
+ at end example
+
+ at noindent
+Note that the total number of elements in the original
+matrix must match the total number of elements in the new matrix.
+
+A single dimension of the return matrix can be unknown and is flagged
+by an empty argument.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-resize}
+ at deftypefn {Built-in Function} {} resize (@var{x}, @var{m})
+ at deftypefnx {Built-in Function} {} resize (@var{x}, @var{m}, @var{n})
+ at deftypefnx {Built-in Function} {} resize (@var{x}, @var{m}, @var{n}, @dots{})
+Resize @var{x} cutting off elements as necessary.
+
+In the result, element with certain indices is equal to the corresponding
+element of @var{x} if the indices are within the bounds of @var{x};
+otherwise, the element is set to zero.
+
+In other words, the statement
+
+ at example
+  y = resize (x, dv);
+ at end example
+
+ at noindent
+is equivalent to the following code:
+
+ at example
+ at group
+  y = zeros (dv, class (x));
+  sz = min (dv, size (x));
+  for i = 1:length (sz), idx@{i@} = 1:sz(i); endfor
+  y(idx@{:@}) = x(idx@{:@});
+ at end group
+ at end example
+
+ at noindent
+but is performed more efficiently.
+
+If only @var{m} is supplied and it is a scalar, the dimension of the
+result is @var{m}-by- at var{m}.  If @var{m} is a vector, then the
+dimensions of the result are given by the elements of @var{m}.
+If both @var{m} and @var{n} are scalars, then the dimensions of
+the result are @var{m}-by- at var{n}.
+
+An object can be resized to more dimensions than it has;
+in such case the missing dimensions are assumed to be 1.
+Resizing an object to fewer dimensions is not possible.
+ at seealso{@ref{doc-reshape,,reshape}, @ref{doc-postpad,,postpad}}
+ at end deftypefn
+
+
+ at c ./general/circshift.m
+ at anchor{doc-circshift}
+ at deftypefn {Function File} {@var{y} =} circshift (@var{x}, @var{n})
+Circularly shifts the values of the array @var{x}.  @var{n} must be
+a vector of integers no longer than the number of dimensions in 
+ at var{x}.  The values of @var{n} can be either positive or negative,
+which determines the direction in which the values or @var{x} are
+shifted.  If an element of @var{n} is zero, then the corresponding
+dimension of @var{x} will not be shifted.  For example
+
+ at example
+ at group
+x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+circshift (x, 1)
+ at result{}  7, 8, 9
+    1, 2, 3
+    4, 5, 6
+circshift (x, -2)
+ at result{}  7, 8, 9
+    1, 2, 3
+    4, 5, 6
+circshift (x, [0,1])
+ at result{}  3, 1, 2
+    6, 4, 5
+    9, 7, 8
+ at end group
+ at end example
+ at seealso {permute, ipermute, shiftdim}
+ at end deftypefn
+
+
+ at c ./general/shiftdim.m
+ at anchor{doc-shiftdim}
+ at deftypefn {Function File} {@var{y} =} shiftdim (@var{x}, @var{n})
+ at deftypefnx {Function File} {[@var{y}, @var{ns}] =} shiftdim (@var{x})
+Shifts the dimension of @var{x} by @var{n}, where @var{n} must be
+an integer scalar.  When @var{n} is positive, the dimensions of
+ at var{x} are shifted to the left, with the leading dimensions
+circulated to the end.  If @var{n} is negative, then the dimensions
+of @var{x} are shifted to the right, with @var{n} leading singleton
+dimensions added.
+
+Called with a single argument, @code{shiftdim}, removes the leading
+singleton dimensions, returning the number of dimensions removed
+in the second output argument @var{ns}.
+
+For example 
+
+ at example
+ at group
+x = ones (1, 2, 3);
+size (shiftdim (x, -1))
+     @result{} [1, 1, 2, 3]
+size (shiftdim (x, 1))
+     @result{} [2, 3]
+[b, ns] = shiftdim (x);
+     @result{} b =  [1, 1, 1; 1, 1, 1]
+     @result{} ns = 1
+ at end group
+ at end example
+ at seealso {reshape, permute, ipermute, circshift, squeeze}
+ at end deftypefn
+
+
+ at c ./general/shift.m
+ at anchor{doc-shift}
+ at deftypefn {Function File} {} shift (@var{x}, @var{b})
+ at deftypefnx {Function File} {} shift (@var{x}, @var{b}, @var{dim})
+If @var{x} is a vector, perform a circular shift of length @var{b} of
+the elements of @var{x}.
+
+If @var{x} is a matrix, do the same for each column of @var{x}.
+If the optional @var{dim} argument is given, operate along this 
+dimension
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-sort}
+ at deftypefn {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{mode})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim}, @var{mode})
+Return a copy of @var{x} with the elements arranged in increasing
+order.  For matrices, @code{sort} orders the elements in each column.
+
+For example,
+
+ at example
+ at group
+sort ([1, 2; 2, 3; 3, 1])
+     @result{}  1  1
+         2  2
+         3  3
+ at end group
+ at end example
+
+The @code{sort} function may also be used to produce a matrix
+containing the original row indices of the elements in the sorted
+matrix.  For example,
+
+ at example
+ at group
+[s, i] = sort ([1, 2; 2, 3; 3, 1])
+     @result{} s = 1  1
+            2  2
+            3  3
+     @result{} i = 1  3
+            2  1
+            3  2
+ at end group
+ at end example
+
+If the optional argument @var{dim} is given, then the matrix is sorted
+along the dimension defined by @var{dim}.  The optional argument @code{mode}
+defines the order in which the values will be sorted.  Valid values of
+ at code{mode} are `ascend' or `descend'.
+
+For equal elements, the indices are such that the equal elements are listed
+in the order that appeared in the original list.
+
+The @code{sort} function may also be used to sort strings and cell arrays
+of strings, in which case the dictionary order of the strings is used.
+
+The algorithm used in @code{sort} is optimized for the sorting of partially
+ordered lists.
+ at end deftypefn
+
+
+ at c ./general/sortrows.m
+ at anchor{doc-sortrows}
+ at deftypefn {Function File} {} sortrows (@var{a}, @var{c})
+Sort the rows of the matrix @var{a} according to the order of the
+columns specified in @var{c}.  If @var{c} is omitted, a
+lexicographical sort is used.  By default ascending order is used 
+however if elements of @var{c} are negative then the corresponding  
+column is sorted in descending order.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-issorted}
+ at deftypefn {Built-in Function} {} issorted (@var{a}, @var{rows})
+Returns true if the array is sorted, ascending or descending.
+NaNs are treated as by @code{sort}.  If @var{rows} is supplied and
+has the value "rows", checks whether the array is sorted by rows
+as if output by @code{sortrows} (with no options).
+
+This function does not yet support sparse matrices.
+ at seealso{@ref{doc-sortrows,,sortrows}, @ref{doc-sort,,sort}}
+ at end deftypefn
+
+
+
+Since the @code{sort} function does not allow sort keys to be specified,
+it can't be used to order the rows of a matrix according to the values
+of the elements in various columns at footnote{For example, to first sort
+based on the values in column 1, and then, for any values that are
+repeated in column 1, sort based on the values found in column 2, etc.}
+in a single call.  Using the second output, however, it is possible to
+sort all rows based on the values in a given column.  Here's an example
+that sorts the rows of a matrix based on the values in the second
+column.
+
+ at example
+ at group
+a = [1, 2; 2, 3; 3, 1];
+[s, i] = sort (a (:, 2));
+a (i, :)
+     @result{}  3  1
+         1  2
+         2  3
+ at end group
+ at end example
+
+ at anchor{doc-triu}
+ at c ./general/tril.m
+ at anchor{doc-tril}
+ at deftypefn {Function File} {} tril (@var{a}, @var{k})
+ at deftypefnx {Function File} {} triu (@var{a}, @var{k})
+Return a new matrix formed by extracting the lower (@code{tril})
+or upper (@code{triu}) triangular part of the matrix @var{a}, and
+setting all other elements to zero.  The second argument is optional,
+and specifies how many diagonals above or below the main diagonal should
+also be set to zero.
+
+The default value of @var{k} is zero, so that @code{triu} and
+ at code{tril} normally include the main diagonal as part of the result
+matrix.
+
+If the value of @var{k} is negative, additional elements above (for
+ at code{tril}) or below (for @code{triu}) the main diagonal are also
+selected.
+
+The absolute value of @var{k} must not be greater than the number of
+sub- or super-diagonals.
+
+For example,
+
+ at example
+ at group
+tril (ones (3), -1)
+     @result{}  0  0  0
+         1  0  0
+         1  1  0
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+tril (ones (3), 1)
+     @result{}  1  1  0
+         1  1  1
+         1  1  1
+ at end group
+ at end example
+ at seealso{@ref{doc-triu,,triu}, @ref{doc-diag,,diag}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/vec.m
+ at anchor{doc-vec}
+ at deftypefn {Function File} {} vec (@var{x})
+Return the vector obtained by stacking the columns of the matrix @var{x}
+one above the other.
+ at end deftypefn
+
+
+ at c ./linear-algebra/vech.m
+ at anchor{doc-vech}
+ at deftypefn {Function File} {} vech (@var{x})
+Return the vector obtained by eliminating all supradiagonal elements of
+the square matrix @var{x} and stacking the result one column above the
+other.
+ at end deftypefn
+
+
+ at anchor{doc-postpad}
+ at c ./general/prepad.m
+ at anchor{doc-prepad}
+ at deftypefn {Function File} {} prepad (@var{x}, @var{l}, @var{c})
+ at deftypefnx {Function File} {} prepad (@var{x}, @var{l}, @var{c}, @var{dim})
+Prepend (append) the scalar value @var{c} to the vector @var{x}
+until it is of length @var{l}.  If the third argument is not
+supplied, a value of 0 is used.
+
+If @code{length (@var{x}) > @var{l}}, elements from the beginning (end) of
+ at var{x} are removed until a vector of length @var{l} is obtained.
+
+If @var{x} is a matrix, elements are prepended or removed from each row.
+
+If the optional @var{dim} argument is given, then operate along this
+dimension.
+ at seealso{@ref{doc-postpad,,postpad}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-diag}
+ at deftypefn {Built-in Function} {} diag (@var{v}, @var{k})
+Return a diagonal matrix with 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
+ at var{-k}-th sub-diagonal.  The default value of @var{k} is 0, and the
+vector is placed on the main diagonal.  For example,
+
+ at example
+ at group
+diag ([1, 2, 3], 1)
+     @result{}  0  1  0  0
+         0  0  2  0
+         0  0  0  3
+         0  0  0  0
+ at end group
+ at end example
+
+ at noindent
+Given a matrix argument, instead of a vector, @code{diag} extracts the
+ at var{k}-th diagonal of the matrix.
+ at end deftypefn
+
+
+ at c ./general/blkdiag.m
+ at anchor{doc-blkdiag}
+ at deftypefn {Function File} {} blkdiag (@var{a}, @var{b}, @var{c}, @dots{})
+Build a block diagonal matrix from @var{a}, @var{b}, @var{c}, @dots{}.
+All the arguments must be numeric and are two-dimensional matrices or
+scalars.
+ at seealso{@ref{doc-diag,,diag}, @ref{doc-horzcat,,horzcat}, @ref{doc-vertcat,,vertcat}}
+ at end deftypefn
+
+
+ at node Applying a Function to an Array
+ at section Applying a Function to an Array
+
+ at c ./general/arrayfun.m
+ at anchor{doc-arrayfun}
+ at deftypefn  {Function File} {} arrayfun (@var{func}, @var{a})
+ at deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{a})
+ at deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{a}, @var{b}, @dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @dots{}] =} arrayfun (@var{func}, @var{a}, @dots{})
+ at deftypefnx {Function File} {} arrayfun (@dots{}, "UniformOutput", @var{val})
+ at deftypefnx {Function File} {} arrayfun (@dots{}, "ErrorHandler", @var{errfunc})
+
+Execute a function on each element of an array.  This is useful for
+functions that do not accept array arguments.  If the function does
+accept array arguments it is better to call the function directly.
+
+The first input argument @var{func} can be a string, a function
+handle, an inline function or an anonymous function.  The input
+argument @var{a} can be a logic array, a numeric array, a string
+array, a structure array or a cell array.  By a call of the function
+ at command{arrayfun} all elements of @var{a} are passed on to the named
+function @var{func} individually.
+
+The named function can also take more than two input arguments, with
+the input arguments given as third input argument @var{b}, fourth
+input argument @var{c}, @dots{}  If given more than one array input
+argument then all input arguments must have the same sizes, for
+example
+
+ at example
+ at group
+arrayfun (@@atan2, [1, 0], [0, 1])
+ at result{} ans = [1.5708   0.0000]
+ at end group
+ at end example
+
+If the parameter @var{val} after a further string input argument
+"UniformOutput" is set @code{true} (the default), then the named
+function @var{func} must return a single element which then will be
+concatenated into the return value and is of type matrix.  Otherwise,
+if that parameter is set to @code{false}, then the outputs are
+concatenated in a cell array.  For example
+
+ at example
+ at group
+arrayfun (@@(x,y) x:y, "abc", "def", "UniformOutput", false)
+ at result{} ans =
+@{
+  [1,1] = abcd
+  [1,2] = bcde
+  [1,3] = cdef
+@}
+ at end group
+ at end example
+
+If more than one output arguments are given then the named function
+must return the number of return values that also are expected, for
+example
+
+ at example
+ at group
+[A, B, C] = arrayfun (@@find, [10; 0], "UniformOutput", false)
+ at result{}
+A =
+@{
+  [1,1] =  1
+  [2,1] = [](0x0)
+@}
+B =
+@{
+  [1,1] =  1
+  [2,1] = [](0x0)
+@}
+C =
+@{
+  [1,1] =  10
+  [2,1] = [](0x0)
+@}
+ at end group
+ at end example
+
+If the parameter @var{errfunc} after a further string input argument
+"ErrorHandler" is another string, a function handle, an inline
+function or an anonymous function, then @var{errfunc} defines a
+function to call in the case that @var{func} generates an error.
+The definition of the function must be of the form
+
+ at example
+function [@dots{}] = errfunc (@var{s}, @dots{})
+ at end example
+
+where there is an additional input argument to @var{errfunc}
+relative to @var{func}, given by @var{s}.  This is a structure with
+the elements "identifier", "message" and "index", giving
+respectively the error identifier, the error message and the index of
+the array elements that caused the error.  The size of the output
+argument of @var{errfunc} must have the same size as the output
+argument of @var{func}, otherwise a real error is thrown.  For
+example
+
+ at example
+ at group
+function y = ferr (s, x), y = "MyString"; endfunction
+arrayfun (@@str2num, [1234], \
+          "UniformOutput", false, "ErrorHandler", @@ferr)
+ at result{} ans =
+@{
+ [1,1] = MyString
+@}
+ at end group
+ at end example
+
+ at seealso{@ref{doc-cellfun,,cellfun}, @ref{doc-spfun,,spfun}, @ref{doc-structfun,,structfun}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/bsxfun.cc
+ at anchor{doc-bsxfun}
+ at deftypefn {Loadable Function} {} bsxfun (@var{f}, @var{a}, @var{b})
+Applies a binary function @var{f} element-wise to two matrix arguments
+ at var{a} and @var{b}.  The function @var{f} must be capable of accepting
+two column vector arguments of equal length, or one column vector
+argument and a scalar.
+
+The dimensions of @var{a} and @var{b} must be equal or singleton.  The
+singleton dimensions of the matrices will be expanded to the same
+dimensionality as the other matrix.
+
+ at seealso{@ref{doc-arrayfun,,arrayfun}, @ref{doc-cellfun,,cellfun}}
+ at end deftypefn
+
+
+ at node Special Utility Matrices
+ at section Special Utility Matrices
+
+ at c data.cc
+ at anchor{doc-eye}
+ at deftypefn {Built-in Function} {} eye (@var{x})
+ at deftypefnx {Built-in Function} {} eye (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} eye (@dots{}, @var{class})
+Return an identity matrix.  If invoked with a single scalar argument,
+ at code{eye} returns a square matrix with the dimension specified.  If you
+supply two scalar arguments, @code{eye} takes them to be the number of
+rows and columns.  If given a vector with two elements, @code{eye} uses
+the values of the elements as the number of rows and columns,
+respectively.  For example,
+
+ at example
+ at group
+eye (3)
+     @result{}  1  0  0
+         0  1  0
+         0  0  1
+ at end group
+ at end example
+
+The following expressions all produce the same result:
+
+ at example
+ at group
+eye (2)
+ at equiv{}
+eye (2, 2)
+ at equiv{}
+eye (size ([1, 2; 3, 4])
+ at end group
+ at end example
+
+The optional argument @var{class}, allows @code{eye} to return an array of
+the specified type, like
+
+ at example
+val = zeros (n,m, "uint8")
+ at end example
+
+Calling @code{eye} with no arguments is equivalent to calling it
+with an argument of 1.  This odd definition is for compatibility
+with @sc{matlab}.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-ones}
+ at deftypefn {Built-in Function} {} ones (@var{x})
+ at deftypefnx {Built-in Function} {} ones (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} ones (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} ones (@dots{}, @var{class})
+Return a matrix or N-dimensional array whose elements are all 1.
+The arguments are handled the same as the arguments for @code{eye}.
+
+If you need to create a matrix whose values are all the same, you should
+use an expression like
+
+ at example
+val_matrix = val * ones (n, m)
+ at end example
+
+The optional argument @var{class}, allows @code{ones} to return an array of
+the specified type, for example
+
+ at example
+val = ones (n,m, "uint8")
+ at end example
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-zeros}
+ at deftypefn {Built-in Function} {} zeros (@var{x})
+ at deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} zeros (@dots{}, @var{class})
+Return a matrix or N-dimensional array whose elements are all 0.
+The arguments are handled the same as the arguments for @code{eye}.
+
+The optional argument @var{class}, allows @code{zeros} to return an array of
+the specified type, for example
+
+ at example
+val = zeros (n,m, "uint8")
+ at end example
+ at end deftypefn
+
+
+ at c ./general/repmat.m
+ at anchor{doc-repmat}
+ at deftypefn {Function File} {} repmat (@var{A}, @var{m}, @var{n})
+ at deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n}])
+ at deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n} @var{p} @dots{}])
+Form a block matrix of size @var{m} by @var{n}, with a copy of matrix
+ at var{A} as each element.  If @var{n} is not specified, form an 
+ at var{m} by @var{m} block matrix.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/rand.cc
+ at anchor{doc-rand}
+ at deftypefn {Loadable Function} {} rand (@var{x})
+ at deftypefnx {Loadable Function} {} rand (@var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} rand ("state", @var{x})
+ at deftypefnx {Loadable Function} {} rand ("seed", @var{x})
+Return a matrix with random elements uniformly distributed on the
+interval (0, 1).  The arguments are handled the same as the arguments
+for @code{eye}.
+
+You can query the state of the random number generator using the
+form
+
+ at example
+v = rand ("state")
+ at end example
+
+This returns a column vector @var{v} of length 625.  Later, you can
+restore the random number generator to the state @var{v}
+using the form
+
+ at example
+rand ("state", v)
+ at end example
+
+ at noindent
+You may also initialize the state vector from an arbitrary vector of
+length <= 625 for @var{v}.  This new state will be a hash based on the
+value of @var{v}, not @var{v} itself.
+
+By default, the generator is initialized from @code{/dev/urandom} if it is
+available, otherwise from cpu time, wall clock time and the current
+fraction of a second.
+
+To compute the pseudo-random sequence, @code{rand} uses the Mersenne
+Twister with a period of @math{2^{19937}-1} (See M. Matsumoto and T. Nishimura,
+ at cite{Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator}, ACM Trans. on
+Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998,
+ at url{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html}).
+Do @strong{not} use for cryptography without securely hashing
+several returned values together, otherwise the generator state
+can be learned after reading 624 consecutive values.
+
+Older versions of Octave used a different random number generator.
+The new generator is used by default
+as it is significantly faster than the old generator, and produces
+random numbers with a significantly longer cycle time.  However, in
+some circumstances it might be desirable to obtain the same random
+sequences as used by the old generators.  To do this the keyword
+"seed" is used to specify that the old generators should be use,
+as in
+
+ at example
+rand ("seed", val)
+ at end example
+
+which sets the seed of the generator to @var{val}.  The seed of the
+generator can be queried with
+
+ at example
+s = rand ("seed")
+ at end example
+
+However, it should be noted that querying the seed will not cause
+ at code{rand} to use the old generators, only setting the seed will.
+To cause @code{rand} to once again use the new generators, the
+keyword "state" should be used to reset the state of the @code{rand}.
+ at seealso{@ref{doc-randn,,randn}, @ref{doc-rande,,rande}, @ref{doc-randg,,randg}, @ref{doc-randp,,randp}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/rand.cc
+ at anchor{doc-randn}
+ at deftypefn {Loadable Function} {} randn (@var{x})
+ at deftypefnx {Loadable Function} {} randn (@var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} randn ("state", @var{x})
+ at deftypefnx {Loadable Function} {} randn ("seed", @var{x})
+Return a matrix with normally distributed pseudo-random
+elements having zero mean and variance one.  The arguments are
+handled the same as the arguments for @code{rand}.
+
+By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique'' to
+transform from a uniform to a normal distribution.  (G. Marsaglia and
+W.W. Tsang, @cite{Ziggurat method for generating random variables},
+J. Statistical Software, vol 5, 2000,
+ at url{http://www.jstatsoft.org/v05/i08/})
+
+ at seealso{@ref{doc-rand,,rand}, @ref{doc-rande,,rande}, @ref{doc-randg,,randg}, @ref{doc-randp,,randp}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/rand.cc
+ at anchor{doc-rande}
+ at deftypefn {Loadable Function} {} rande (@var{x})
+ at deftypefnx {Loadable Function} {} rande (@var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} rande ("state", @var{x})
+ at deftypefnx {Loadable Function} {} rande ("seed", @var{x})
+Return a matrix with exponentially distributed random elements.  The
+arguments are handled the same as the arguments for @code{rand}.
+
+By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique'' to
+transform from a uniform to a exponential distribution.  (G. Marsaglia and
+W.W. Tsang, @cite{Ziggurat method for generating random variables},
+J. Statistical Software, vol 5, 2000,
+ at url{http://www.jstatsoft.org/v05/i08/})
+ at seealso{@ref{doc-rand,,rand}, @ref{doc-randn,,randn}, @ref{doc-randg,,randg}, @ref{doc-randp,,randp}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/rand.cc
+ at anchor{doc-randp}
+ at deftypefn {Loadable Function} {} randp (@var{l}, @var{x})
+ at deftypefnx {Loadable Function} {} randp (@var{l}, @var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} randp ("state", @var{x})
+ at deftypefnx {Loadable Function} {} randp ("seed", @var{x})
+Return a matrix with Poisson distributed random elements with mean value parameter given by the first argument, @var{l}.  The arguments
+are handled the same as the arguments for @code{rand}, except for the
+argument @var{l}.
+
+Five different algorithms are used depending on the range of @var{l}
+and whether or not @var{l} is a scalar or a matrix.
+
+ at table @asis
+ at item For scalar @var{l} <= 12, use direct method.
+Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.
+ at item For scalar @var{l} > 12, use rejection method.[1]
+Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.
+ at item For matrix @var{l} <= 10, use inversion method.[2]
+Stadlober E., et al., WinRand source code, available via FTP.
+ at item For matrix @var{l} > 10, use patchwork rejection method.
+Stadlober E., et al., WinRand source code, available via FTP, or
+H. Zechner, 'Efficient sampling from continuous and discrete
+unimodal distributions', Doctoral Dissertation, 156pp., Technical
+University Graz, Austria, 1994.
+ at item For @var{l} > 1e8, use normal approximation.
+L. Montanet, et al., 'Review of Particle Properties', Physical Review
+D 50 p1284, 1994
+ at end table
+ at seealso{@ref{doc-rand,,rand}, @ref{doc-randn,,randn}, @ref{doc-rande,,rande}, @ref{doc-randg,,randg}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/rand.cc
+ at anchor{doc-randg}
+ at deftypefn {Loadable Function} {} randg (@var{a}, @var{x})
+ at deftypefnx {Loadable Function} {} randg (@var{a}, @var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} randg ("state", @var{x})
+ at deftypefnx {Loadable Function} {} randg ("seed", @var{x})
+Return a matrix with @code{gamma(@var{a},1)} distributed random elements.
+The arguments are handled the same as the arguments for @code{rand},
+except for the argument @var{a}.
+
+This can be used to generate many distributions:
+
+ at table @asis
+ at item @code{gamma (a, b)} for @code{a > -1}, @code{b > 0}
+ at example
+r = b * randg (a)
+ at end example
+ at item @code{beta (a, b)} for @code{a > -1}, @code{b > -1}
+ at example
+ at group
+r1 = randg (a, 1)
+r = r1 / (r1 + randg (b, 1))
+ at end group
+ at end example
+ at item @code{Erlang (a, n)}
+ at example
+r = a * randg (n)
+ at end example
+ at item @code{chisq (df)} for @code{df > 0}
+ at example
+r = 2 * randg (df / 2)
+ at end example
+ at item @code{t(df)} for @code{0 < df < inf} (use randn if df is infinite)
+ at example
+r = randn () / sqrt (2 * randg (df / 2) / df)
+ at end example
+ at item @code{F (n1, n2)} for @code{0 < n1}, @code{0 < n2}
+ at example
+ at group
+## r1 equals 1 if n1 is infinite
+r1 = 2 * randg (n1 / 2) / n1
+## r2 equals 1 if n2 is infinite
+r2 = 2 * randg (n2 / 2) / n2
+r = r1 / r2
+
+ at end group
+ at end example
+ at item negative @code{binomial (n, p)} for @code{n > 0}, @code{0 < p <= 1}
+ at example
+r = randp ((1 - p) / p * randg (n))
+ at end example
+ at item non-central @code{chisq (df, L)}, for @code{df >= 0} and @code{L > 0}
+(use chisq if @code{L = 0})
+ at example
+ at group
+r = randp (L / 2)
+r(r > 0) = 2 * randg (r(r > 0))
+r(df > 0) += 2 * randg (df(df > 0)/2)
+ at end group
+ at end example
+ at item @code{Dirichlet (a1, @dots{} ak)}
+ at example
+ at group
+r = (randg (a1), @dots{}, randg (ak))
+r = r / sum (r)
+ at end group
+ at end example
+ at end table
+ at seealso{@ref{doc-rand,,rand}, @ref{doc-randn,,randn}, @ref{doc-rande,,rande}, @ref{doc-randp,,randp}}
+ at end deftypefn
+
+
+The generators operate in the new or old style together, it is not
+possible to mix the two.  Initializing any generator with
+ at code{"state"} or @code{"seed"} causes the others to switch to the
+same style for future calls.
+
+The state of each generator is independent and calls to different
+generators can be interleaved without affecting the final result.  For
+example,
+
+ at example
+ at group
+rand ("state", [11, 22, 33]);
+randn ("state", [44, 55, 66]);
+u = rand (100, 1);
+n = randn (100, 1);
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+rand ("state", [11, 22, 33]);
+randn ("state", [44, 55, 66]);
+u = zeros (100, 1);
+n = zeros (100, 1);
+for i = 1:100
+  u(i) = rand ();
+  n(i) = randn ();
+end
+ at end group
+ at end example
+
+ at noindent
+produce equivalent results.  When the generators are initialized in
+the old style with @code{"seed"} only @code{rand} and @code{randn} are
+independent, because the old @code{rande}, @code{randg} and
+ at code{randp} generators make calls to @code{rand} and @code{randn}.
+
+The generators are initialized with random states at start-up, so
+that the sequences of random numbers are not the same each time you run
+Octave. at footnote{The old versions of @code{rand} and @code{randn}
+obtain their initial seeds from the system clock.} If you really do
+need to reproduce a sequence of numbers exactly, you can set the state
+or seed to a specific value.
+
+If invoked without arguments, @code{rand} and @code{randn} return a
+single element of a random sequence.
+
+The original @code{rand} and @code{randn} functions use Fortran code from
+ at sc{Ranlib}, a library of fortran routines for random number generation,
+compiled by Barry W. Brown and James Lovato of the Department of
+Biomathematics at The University of Texas, M.D. Anderson Cancer Center,
+Houston, TX 77030.
+
+ at c ./general/randperm.m
+ at anchor{doc-randperm}
+ at deftypefn {Function File} {} randperm (@var{n})
+Return a row vector containing a random permutation of the
+integers from 1 to @var{n}.
+ at end deftypefn
+
+
+The functions @code{linspace} and @code{logspace} make it very easy to
+create vectors with evenly or logarithmically spaced elements.
+ at xref{Ranges}.
+
+ at c data.cc
+ at anchor{doc-linspace}
+ at deftypefn {Built-in Function} {} linspace (@var{base}, @var{limit}, @var{n})
+Return a row vector with @var{n} linearly spaced elements between
+ at var{base} and @var{limit}.  If the number of elements is greater than one,
+then the @var{base} and @var{limit} are always included in
+the range.  If @var{base} is greater than @var{limit}, the elements are
+stored in decreasing order.  If the number of points is not specified, a
+value of 100 is used.
+
+The @code{linspace} function always returns a row vector.
+
+For compatibility with @sc{matlab}, return the second argument if
+fewer than two values are requested.
+ at end deftypefn
+
+
+ at c ./general/logspace.m
+ at anchor{doc-logspace}
+ at deftypefn {Function File} {} logspace (@var{base}, @var{limit}, @var{n})
+Similar to @code{linspace} except that the values are logarithmically
+spaced from
+ at tex
+$10^{base}$ to $10^{limit}$.
+ at end tex
+ at ifnottex
+10^base to 10^limit.
+ at end ifnottex
+
+If @var{limit} is equal to
+ at tex
+$\pi$,
+ at end tex
+ at ifnottex
+pi,
+ at end ifnottex
+the points are between
+ at tex
+$10^{base}$ and $\pi$,
+ at end tex
+ at ifnottex
+10^base and pi,
+ at end ifnottex
+ at emph{not}
+ at tex
+$10^{base}$ and $10^{\pi}$,
+ at end tex
+ at ifnottex
+10^base and 10^pi,
+ at end ifnottex
+in order to be compatible with the corresponding @sc{matlab}
+function.
+
+Also for compatibility, return the second argument if fewer than two
+values are requested.
+ at seealso{@ref{doc-linspace,,linspace}}
+ at end deftypefn
+
+
+ at node Famous Matrices
+ at section Famous Matrices
+
+The following functions return famous matrix forms.
+
+ at c ./special-matrix/hadamard.m
+ at anchor{doc-hadamard}
+ at deftypefn {Function File} {} hadamard (@var{n})
+Construct a Hadamard matrix @var{Hn} of size @var{n}-by- at var{n}.  The 
+size @var{n} must be of the form @code{2 ^ @var{k} * @var{p}} in which
+ at var{p} is one of 1, 12, 20 or 28.  The returned matrix is normalized,
+meaning @code{Hn(:,1) == 1} and @code{H(1,:) == 1}.
+
+Some of the properties of Hadamard matrices are:
+
+ at itemize @bullet
+ at item
+ at code{kron (@var{Hm}, @var{Hn})} is a Hadamard matrix of size 
+ at var{m}-by- at var{n}.
+ at item
+ at code{Hn * Hn' == @var{n} * eye (@var{n})}.
+ at item
+The rows of @var{Hn} are orthogonal.
+ at item
+ at code{det (@var{A}) <= abs(det (@var{Hn}))} for all @var{A} with
+ at code{abs (@var{A} (@var{i}, @var{j})) <= 1}.
+ at item
+Multiply any row or column by -1 and still have a Hadamard matrix.
+ at end itemize
+
+ at end deftypefn
+
+
+ at c ./special-matrix/hankel.m
+ at anchor{doc-hankel}
+ at deftypefn {Function File} {} hankel (@var{c}, @var{r})
+Return the Hankel matrix constructed given the first column @var{c}, and
+(optionally) the last row @var{r}.  If the last element of @var{c} is
+not the same as the first element of @var{r}, the last element of
+ at var{c} is used.  If the second argument is omitted, it is assumed to
+be a vector of zeros with the same size as @var{c}.
+
+A Hankel matrix formed from an m-vector @var{c}, and an n-vector
+ at var{r}, has the elements
+ at tex
+$$
+H (i, j) = \cases{c_{i+j-1},&$i+j-1\le m$;\cr r_{i+j-m},&otherwise.\cr}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+H(i,j) = c(i+j-1),  i+j-1 <= m;
+H(i,j) = r(i+j-m),  otherwise
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}}
+ at end deftypefn
+
+
+ at c ./special-matrix/hilb.m
+ at anchor{doc-hilb}
+ at deftypefn {Function File} {} hilb (@var{n})
+Return the Hilbert matrix of order @var{n}.  The
+ at tex
+$i,\,j$
+ at end tex
+ at ifnottex
+i, j
+ at end ifnottex
+element of a Hilbert matrix is defined as
+ at tex
+$$
+H (i, j) = {1 \over (i + j - 1)}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+H (i, j) = 1 / (i + j - 1)
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}}
+ at end deftypefn
+
+
+ at c ./special-matrix/invhilb.m
+ at anchor{doc-invhilb}
+ at deftypefn {Function File} {} invhilb (@var{n})
+Return the inverse of a Hilbert matrix of order @var{n}.  This can be 
+computed exactly using
+ at tex
+$$\eqalign{
+  A_{ij} &= -1^{i+j} (i+j-1)
+             \left( \matrix{n+i-1 \cr n-j } \right)
+             \left( \matrix{n+j-1 \cr n-i } \right)
+             \left( \matrix{i+j-2 \cr i-2 } \right)^2 \cr
+         &= { p(i)p(j) \over (i+j-1) }
+}$$
+where
+$$
+  p(k) = -1^k \left( \matrix{ k+n-1 \cr k-1 } \right)
+              \left( \matrix{ n \cr k } \right)
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+
+            (i+j)         /n+i-1\  /n+j-1\   /i+j-2\ 2
+ A(i,j) = -1      (i+j-1)(       )(       ) (       )
+                          \ n-j /  \ n-i /   \ i-2 /
+
+        = p(i) p(j) / (i+j-1)
+
+ at end group
+ at end example
+where
+ at example
+ at group
+             k  /k+n-1\   /n\
+    p(k) = -1  (       ) (   )
+                \ k-1 /   \k/
+ at end group
+ at end example
+ at end ifnottex
+
+The validity of this formula can easily be checked by expanding 
+the binomial coefficients in both formulas as factorials.  It can 
+be derived more directly via the theory of Cauchy matrices: 
+see J. W. Demmel, Applied Numerical Linear Algebra, page 92.
+
+Compare this with the numerical calculation of @code{inverse (hilb (n))},
+which suffers from the ill-conditioning of the Hilbert matrix, and the
+finite precision of your computer's floating point arithmetic.
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-toeplitz,,toeplitz}}
+ at end deftypefn
+
+
+ at c ./special-matrix/magic.m
+ at anchor{doc-magic}
+ at deftypefn {Function File} {} magic (@var{n})
+
+Create an @var{n}-by- at var{n} magic square.  Note that @code{magic
+(@var{2})} is undefined since there is no 2-by-2 magic square.
+
+ at end deftypefn
+
+
+ at c ./special-matrix/pascal.m
+ at anchor{doc-pascal}
+ at deftypefn {Function File} {} pascal (@var{n}, @var{t})
+
+Return the Pascal matrix of order @var{n} if @code{@var{t} = 0}.
+ at var{t} defaults to 0. Return lower triangular Cholesky factor of 
+the Pascal matrix if @code{@var{t} = 1}.  This matrix is its own
+inverse, that is @code{pascal (@var{n}, 1) ^ 2 == eye (@var{n})}.
+If @code{@var{t} = -1}, return its absolute value.  This is the
+standard pascal triangle as a lower-triangular matrix.
+If @code{@var{t} = 2}, return a transposed and permuted version of
+ at code{pascal (@var{n}, 1)}, which is the cube-root of the identity
+matrix.  That is @code{pascal (@var{n}, 2) ^ 3 == eye (@var{n})}.
+
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}, @ref{doc-hadamard,,hadamard}, @ref{doc-wilkinson,,wilkinson}, @ref{doc-compan,,compan}, @ref{doc-rosser,,rosser}}
+ at end deftypefn
+
+
+ at c ./special-matrix/rosser.m
+ at anchor{doc-rosser}
+ at deftypefn {Function File} {} rosser ()
+
+Returns the Rosser matrix.  This is a difficult test case used to test
+eigenvalue algorithms.
+
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}, @ref{doc-hadamard,,hadamard}, @ref{doc-wilkinson,,wilkinson}, @ref{doc-compan,,compan}, @ref{doc-pascal,,pascal}}
+ at end deftypefn
+
+
+ at c ./special-matrix/sylvester_matrix.m
+ at anchor{doc-sylvester_matrix}
+ at deftypefn {Function File} {} sylvester_matrix (@var{k})
+Return the Sylvester matrix of order
+ at tex
+$n = 2^k$.
+ at end tex
+ at ifnottex
+n = 2^k.
+ at end ifnottex
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}}
+ at end deftypefn
+
+
+ at c ./special-matrix/toeplitz.m
+ at anchor{doc-toeplitz}
+ at deftypefn {Function File} {} toeplitz (@var{c}, @var{r})
+Return the Toeplitz matrix constructed given the first column @var{c},
+and (optionally) the first row @var{r}.  If the first element of @var{c}
+is not the same as the first element of @var{r}, the first element of
+ at var{c} is used.  If the second argument is omitted, the first row is
+taken to be the same as the first column.
+
+A square Toeplitz matrix has the form:
+ at tex
+$$
+\left[\matrix{c_0    & r_1     & r_2      & \cdots & r_n\cr
+              c_1    & c_0     & r_1      & \cdots & r_{n-1}\cr
+              c_2    & c_1     & c_0      & \cdots & r_{n-2}\cr
+              \vdots & \vdots  & \vdots   & \ddots & \vdots\cr
+              c_n    & c_{n-1} & c_{n-2} & \ldots & c_0}\right]
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+c(0)  r(1)   r(2)  @dots{}  r(n)
+c(1)  c(0)   r(1)  @dots{} r(n-1)
+c(2)  c(1)   c(0)  @dots{} r(n-2)
+ .     ,      ,   .      .
+ .     ,      ,     .    .
+ .     ,      ,       .  .
+c(n) c(n-1) c(n-2) @dots{}  c(0)
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}}
+ at end deftypefn
+
+
+ at c ./special-matrix/vander.m
+ at anchor{doc-vander}
+ at deftypefn {Function File} {} vander (@var{c}, @var{n})
+Return the Vandermonde matrix whose next to last column is @var{c}.
+If @var{n} is specified, it determines the number of columns;
+otherwise, @var{n} is taken to be equal to the length of @var{c}.
+
+A Vandermonde matrix has the form:
+ at tex
+$$
+\left[\matrix{c_1^{n-1}  & \cdots & c_1^2  & c_1    & 1      \cr
+              c_2^{n-1}  & \cdots & c_2^2  & c_2    & 1      \cr
+              \vdots     & \ddots & \vdots & \vdots & \vdots \cr
+              c_n^{n-1}  & \cdots & c_n^2  & c_n    & 1      }\right]
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+c(1)^(n-1) @dots{} c(1)^2  c(1)  1
+c(2)^(n-1) @dots{} c(2)^2  c(2)  1
+    .     .      .      .    .
+    .       .    .      .    .
+    .         .  .      .    .
+c(n)^(n-1) @dots{} c(n)^2  c(n)  1
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}}
+ at end deftypefn
+
+
+ at c ./special-matrix/wilkinson.m
+ at anchor{doc-wilkinson}
+ at deftypefn {Function File} {} wilkinson (@var{n})
+
+Return the Wilkinson matrix of order @var{n}.
+
+ at seealso{@ref{doc-hankel,,hankel}, @ref{doc-vander,,vander}, @ref{doc-sylvester_matrix,,sylvester_matrix}, @ref{doc-hilb,,hilb}, @ref{doc-invhilb,,invhilb}, @ref{doc-toeplitz,,toeplitz}, @ref{doc-hadamard,,hadamard}, @ref{doc-rosser,,rosser}, @ref{doc-compan,,compan}, @ref{doc-pascal,,pascal}}
+ at end deftypefn
+
diff --git a/doc/interpreter/matrix.txi b/doc/interpreter/matrix.txi
new file mode 100644
index 0000000..4c5b86a
--- /dev/null
+++ b/doc/interpreter/matrix.txi
@@ -0,0 +1,277 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Matrix Manipulation
+ at chapter Matrix Manipulation
+
+There are a number of functions available for checking to see if the
+elements of a matrix meet some condition, and for rearranging the
+elements of a matrix.  For example, Octave can easily tell you if all
+the elements of a matrix are finite, or are less than some specified
+value.  Octave can also rotate the elements, extract the upper- or
+lower-triangular parts, or sort the columns of a matrix.
+
+ at menu
+* Finding Elements and Checking Conditions::  
+* Rearranging Matrices::        
+* Applying a Function to an Array::
+* Special Utility Matrices::    
+* Famous Matrices::             
+ at end menu
+
+ at node Finding Elements and Checking Conditions
+ at section Finding Elements and Checking Conditions
+
+The functions @code{any} and @code{all} are useful for determining
+whether any or all of the elements of a matrix satisfy some condition.
+The @code{find} function is also useful in determining which elements of
+a matrix meet a specified condition.
+
+ at DOCSTRING(any)
+
+ at DOCSTRING(all)
+
+Since the comparison operators (@pxref{Comparison Ops}) return matrices
+of ones and zeros, it is easy to test a matrix for many things, not just
+whether the elements are nonzero.  For example, 
+
+ at example
+ at group
+all (all (rand (5) < 0.9))
+     @result{} 0
+ at end group
+ at end example
+
+ at noindent
+tests a random 5 by 5 matrix to see if all of its elements are less
+than 0.9.
+
+Note that in conditional contexts (like the test clause of @code{if} and
+ at code{while} statements) Octave treats the test as if you had typed
+ at code{all (all (condition))}.
+
+ at DOCSTRING(xor)
+
+ at DOCSTRING(is_duplicate_entry)
+
+ at DOCSTRING(diff)
+
+ at DOCSTRING(isinf)
+
+ at DOCSTRING(isnan)
+
+ at DOCSTRING(finite)
+
+ at DOCSTRING(find)
+        
+ at DOCSTRING(common_size)
+
+ at node Rearranging Matrices
+ at section Rearranging Matrices
+
+ at DOCSTRING(fliplr)
+
+ at DOCSTRING(flipud)
+
+ at DOCSTRING(flipdim)
+
+ at DOCSTRING(rot90)
+
+ at DOCSTRING(rotdim)
+
+ at DOCSTRING(cat)
+
+ at DOCSTRING(horzcat)
+
+ at DOCSTRING(vertcat)
+
+ at DOCSTRING(permute)
+
+ at DOCSTRING(ipermute)
+
+ at DOCSTRING(reshape)
+
+ at DOCSTRING(resize)
+
+ at DOCSTRING(circshift)
+
+ at DOCSTRING(shiftdim)
+
+ at DOCSTRING(shift)
+
+ at DOCSTRING(sort)
+
+ at DOCSTRING(sortrows)
+
+ at DOCSTRING(issorted)
+
+Since the @code{sort} function does not allow sort keys to be specified,
+it can't be used to order the rows of a matrix according to the values
+of the elements in various columns at footnote{For example, to first sort
+based on the values in column 1, and then, for any values that are
+repeated in column 1, sort based on the values found in column 2, etc.}
+in a single call.  Using the second output, however, it is possible to
+sort all rows based on the values in a given column.  Here's an example
+that sorts the rows of a matrix based on the values in the second
+column.
+
+ at example
+ at group
+a = [1, 2; 2, 3; 3, 1];
+[s, i] = sort (a (:, 2));
+a (i, :)
+     @result{}  3  1
+         1  2
+         2  3
+ at end group
+ at end example
+
+ at anchor{doc-triu}
+ at DOCSTRING(tril)
+
+ at DOCSTRING(vec)
+
+ at DOCSTRING(vech)
+
+ at anchor{doc-postpad}
+ at DOCSTRING(prepad)
+
+ at DOCSTRING(diag)
+
+ at DOCSTRING(blkdiag)
+
+ at node Applying a Function to an Array
+ at section Applying a Function to an Array
+
+ at DOCSTRING(arrayfun)
+
+ at DOCSTRING(bsxfun)
+
+ at node Special Utility Matrices
+ at section Special Utility Matrices
+
+ at DOCSTRING(eye)
+
+ at DOCSTRING(ones)
+
+ at DOCSTRING(zeros)
+
+ at DOCSTRING(repmat)
+
+ at DOCSTRING(rand)
+
+ at DOCSTRING(randn)
+
+ at DOCSTRING(rande)
+
+ at DOCSTRING(randp)
+
+ at DOCSTRING(randg)
+
+The generators operate in the new or old style together, it is not
+possible to mix the two.  Initializing any generator with
+ at code{"state"} or @code{"seed"} causes the others to switch to the
+same style for future calls.
+
+The state of each generator is independent and calls to different
+generators can be interleaved without affecting the final result.  For
+example,
+
+ at example
+ at group
+rand ("state", [11, 22, 33]);
+randn ("state", [44, 55, 66]);
+u = rand (100, 1);
+n = randn (100, 1);
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+rand ("state", [11, 22, 33]);
+randn ("state", [44, 55, 66]);
+u = zeros (100, 1);
+n = zeros (100, 1);
+for i = 1:100
+  u(i) = rand ();
+  n(i) = randn ();
+end
+ at end group
+ at end example
+
+ at noindent
+produce equivalent results.  When the generators are initialized in
+the old style with @code{"seed"} only @code{rand} and @code{randn} are
+independent, because the old @code{rande}, @code{randg} and
+ at code{randp} generators make calls to @code{rand} and @code{randn}.
+
+The generators are initialized with random states at start-up, so
+that the sequences of random numbers are not the same each time you run
+Octave. at footnote{The old versions of @code{rand} and @code{randn}
+obtain their initial seeds from the system clock.} If you really do
+need to reproduce a sequence of numbers exactly, you can set the state
+or seed to a specific value.
+
+If invoked without arguments, @code{rand} and @code{randn} return a
+single element of a random sequence.
+
+The original @code{rand} and @code{randn} functions use Fortran code from
+ at sc{Ranlib}, a library of fortran routines for random number generation,
+compiled by Barry W. Brown and James Lovato of the Department of
+Biomathematics at The University of Texas, M.D. Anderson Cancer Center,
+Houston, TX 77030.
+
+ at DOCSTRING(randperm)
+
+The functions @code{linspace} and @code{logspace} make it very easy to
+create vectors with evenly or logarithmically spaced elements.
+ at xref{Ranges}.
+
+ at DOCSTRING(linspace)
+
+ at DOCSTRING(logspace)
+
+ at node Famous Matrices
+ at section Famous Matrices
+
+The following functions return famous matrix forms.
+
+ at DOCSTRING(hadamard)
+
+ at DOCSTRING(hankel)
+
+ at DOCSTRING(hilb)
+
+ at DOCSTRING(invhilb)
+
+ at DOCSTRING(magic)
+
+ at DOCSTRING(pascal)
+
+ at DOCSTRING(rosser)
+
+ at DOCSTRING(sylvester_matrix)
+
+ at DOCSTRING(toeplitz)
+
+ at DOCSTRING(vander)
+
+ at DOCSTRING(wilkinson)
diff --git a/doc/interpreter/mesh.eps b/doc/interpreter/mesh.eps
new file mode 100644
index 0000000..f332b22
--- /dev/null
+++ b/doc/interpreter/mesh.eps
@@ -0,0 +1,8583 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: mesh.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:56 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (mesh.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:56 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1.000 UP
+1.000 UL
+LT0
+.2804 g 3275 2788 M
+-48 7 V
+stroke
+LT0
+.2787 g 3297 2799 M
+-70 -4 V
+stroke
+LT0
+.2788 g 3165 2787 M
+62 8 V
+stroke
+LT0
+.2802 g 4125 2799 M
+-21 2 V
+stroke
+LT0
+.2819 g 4173 2786 M
+-48 13 V
+stroke
+LT0
+.2784 g 4236 2788 M
+-111 11 V
+stroke
+LT0
+.2806 g 4105 2796 M
+20 3 V
+stroke
+LT0
+.2797 g 4284 2779 M
+-48 9 V
+stroke
+LT0
+.2739 g 4346 2772 M
+-110 16 V
+stroke
+LT0
+.2803 g 4173 2786 M
+63 2 V
+stroke
+LT0
+.2767 g 3102 2775 M
+-48 -4 V
+stroke
+LT0
+.2757 g 3165 2787 M
+-111 -16 V
+stroke
+LT0
+.2725 g 2992 2764 M
+62 7 V
+stroke
+LT0
+.2837 g 3275 2788 M
+20 4 V
+stroke
+LT0
+.2819 g 3213 2770 M
+-48 17 V
+stroke
+LT0
+.2819 g 3102 2775 M
+63 12 V
+stroke
+LT0
+.2827 g 3291 2777 M
+-16 11 V
+stroke
+LT0
+.2834 g 3213 2770 M
+62 18 V
+stroke
+LT0
+.2792 g 3040 2761 M
+-48 3 V
+stroke
+LT0
+.2758 g 2929 2753 M
+63 11 V
+stroke
+LT0
+.283 g 4221 2762 M
+-48 24 V
+stroke
+LT0
+.2818 g 4115 2763 M
+58 23 V
+stroke
+LT0
+.2832 g 4332 2761 M
+-48 18 V
+stroke
+LT0
+.2824 g 4221 2762 M
+63 17 V
+stroke
+LT0
+.2728 g 4541 2740 M
+-36 6 V
+stroke
+LT0
+.2766 g 4442 2754 M
+63 -8 V
+stroke
+LT0
+.2745 g 4394 2766 M
+111 -20 V
+stroke
+LT0
+.2806 g 4442 2754 M
+-48 12 V
+stroke
+LT0
+.2812 g 4332 2761 M
+62 5 V
+stroke
+LT0
+.2817 g 3150 2750 M
+-48 25 V
+stroke
+LT0
+.2834 g 3040 2761 M
+62 14 V
+stroke
+LT0
+.274 g 4159 2722 M
+-42 35 V
+stroke
+LT0
+.2763 g 3261 2724 M
+-48 46 V
+stroke
+LT0
+.2817 g 3150 2750 M
+63 20 V
+stroke
+LT0
+.2706 g 3261 2724 M
+17 8 V
+stroke
+LT0
+.2805 g 2977 2745 M
+-48 8 V
+stroke
+LT0
+.278 g 2867 2740 M
+62 13 V
+stroke
+LT0
+.2791 g 4269 2730 M
+-48 32 V
+stroke
+LT0
+.2759 g 4159 2722 M
+62 40 V
+stroke
+LT0
+.2806 g 3088 2728 M
+-48 33 V
+stroke
+LT0
+.2838 g 2977 2745 M
+63 16 V
+stroke
+LT0
+.1976 g 4192 2529 M
+-5 -9 V
+stroke
+LT0
+.2666 g 3271 2708 M
+-10 16 V
+stroke
+LT0
+.2658 g 3198 2693 M
+63 31 V
+stroke
+LT0
+.2827 g 4380 2736 M
+-48 25 V
+stroke
+LT0
+.2799 g 4269 2730 M
+63 31 V
+stroke
+LT0
+.1521 g 3169 2415 M
+8 -20 V
+stroke
+LT0
+.2625 g 4207 2673 M
+-48 49 V
+stroke
+LT0
+.2649 g 4134 2697 M
+25 25 V
+stroke
+LT0
+.2712 g 3198 2693 M
+-48 57 V
+stroke
+LT0
+.2789 g 3088 2728 M
+62 22 V
+stroke
+LT0
+.1666 g 4240 2462 M
+-23 -41 V
+stroke
+LT0
+.2833 g 4490 2735 M
+-48 19 V
+stroke
+LT0
+.2821 g 4380 2736 M
+62 18 V
+stroke
+LT0
+.2788 g 4601 2725 M
+-48 12 V
+stroke
+LT0
+.2806 g 4490 2735 M
+60 2 V
+stroke
+LT0
+.2034 g 3184 2570 M
+27 -64 V
+stroke
+LT0
+.1582 g 3169 2415 M
+18 11 V
+stroke
+LT0
+.1365 g 4288 2397 M
+-41 -74 V
+stroke
+LT0
+.2812 g 2915 2729 M
+-48 11 V
+stroke
+LT0
+.2793 g 2804 2726 M
+63 14 V
+stroke
+LT0
+.2031 g 4192 2529 M
+-14 20 V
+stroke
+LT0
+.243 g 4207 2673 M
+-49 -60 V
+stroke
+LT0
+.2464 g 3198 2693 M
+45 -80 V
+stroke
+LT0
+.2222 g 3184 2570 M
+56 34 V
+stroke
+LT0
+.1272 g 3107 2382 M
+36 -95 V
+stroke
+LT0
+.0892 g 3092 2229 M
+35 15 V
+stroke
+LT0
+.2582 g 3136 2663 M
+62 30 V
+stroke
+LT0
+.2712 g 4317 2690 M
+-48 40 V
+stroke
+LT0
+.2657 g 4207 2673 M
+62 57 V
+stroke
+LT0
+.0802 g 3092 2229 M
+15 -36 V
+stroke
+LT0
+.2467 g 4255 2619 M
+-48 54 V
+stroke
+LT0
+.1875 g 4240 2462 M
+-48 67 V
+stroke
+LT0
+.2188 g 4255 2619 M
+-63 -90 V
+stroke
+LT0
+.0616 g 4322 2170 M
+-13 -20 V
+stroke
+LT0
+.0713 g 4322 2170 M
+-33 36 V
+stroke
+LT0
+.1097 g 4336 2337 M
+-57 -105 V
+stroke
+LT0
+.1817 g 3121 2535 M
+48 -120 V
+stroke
+LT0
+.152 g 3107 2382 M
+62 33 V
+stroke
+LT0
+.279 g 3025 2706 M
+-48 39 V
+stroke
+LT0
+.2837 g 2915 2729 M
+62 16 V
+stroke
+LT0
+.2659 g 3136 2663 M
+-48 65 V
+stroke
+LT0
+.2757 g 3025 2706 M
+63 22 V
+stroke
+LT0
+.2356 g 3136 2663 M
+48 -93 V
+stroke
+LT0
+.2119 g 3121 2535 M
+63 35 V
+stroke
+LT0
+.1642 g 4288 2397 M
+-48 65 V
+stroke
+LT0
+.1975 g 4303 2563 M
+-63 -101 V
+stroke
+LT0
+.279 g 4428 2705 M
+-48 31 V
+stroke
+LT0
+.2739 g 4317 2690 M
+63 46 V
+stroke
+LT0
+.2511 g 3073 2634 M
+63 29 V
+stroke
+LT0
+.1148 g 3044 2355 M
+48 -126 V
+stroke
+LT0
+.0868 g 3030 2209 M
+62 20 V
+stroke
+LT0
+.2289 g 4303 2563 M
+-48 56 V
+stroke
+LT0
+.2522 g 4317 2690 M
+-62 -71 V
+stroke
+LT0
+.2815 g 2852 2713 M
+-48 13 V
+stroke
+LT0
+.2799 g 2742 2711 M
+62 15 V
+stroke
+LT0
+.1428 g 4336 2337 M
+-48 60 V
+stroke
+LT0
+.177 g 4351 2507 M
+-63 -110 V
+stroke
+LT0
+.0596 g 4370 2125 M
+-48 45 V
+stroke
+LT0
+.0908 g 4384 2283 M
+-62 -113 V
+stroke
+LT0
+.1735 g 3059 2504 M
+48 -122 V
+stroke
+LT0
+.1447 g 3044 2355 M
+63 27 V
+stroke
+LT0
+.2604 g 4365 2646 M
+-48 44 V
+stroke
+LT0
+.2834 g 4538 2713 M
+-48 22 V
+stroke
+LT0
+.2802 g 4428 2705 M
+62 30 V
+stroke
+LT0
+.2725 g 4759 2687 M
+-48 13 V
+stroke
+LT0
+.2767 g 4649 2708 M
+62 -8 V
+stroke
+LT0
+.2757 g 4601 2725 M
+110 -25 V
+stroke
+LT0
+.0641 g 3030 2209 M
+44 -103 V
+stroke
+LT0
+.0397 g 3015 2084 M
+55 11 V
+stroke
+LT0
+.2274 g 3073 2634 M
+48 -99 V
+stroke
+LT0
+.2033 g 3059 2504 M
+62 31 V
+stroke
+LT0
+.2819 g 4649 2708 M
+-48 17 V
+stroke
+LT0
+.2819 g 4538 2713 M
+63 12 V
+stroke
+LT0
+.044 g 4370 2125 M
+-33 -45 V
+stroke
+LT0
+.2609 g 3073 2634 M
+-48 72 V
+stroke
+LT0
+.2728 g 2963 2685 M
+62 21 V
+stroke
+LT0
+.2775 g 2963 2685 M
+-48 44 V
+stroke
+LT0
+.2834 g 2852 2713 M
+63 16 V
+stroke
+LT0
+.2103 g 4351 2507 M
+-48 56 V
+stroke
+LT0
+.237 g 4365 2646 M
+-62 -83 V
+stroke
+LT0
+.1243 g 4384 2283 M
+-48 54 V
+stroke
+LT0
+.1583 g 4399 2452 M
+-63 -115 V
+stroke
+LT0
+.2451 g 3011 2608 M
+62 26 V
+stroke
+LT0
+.273 g 4476 2671 M
+-48 34 V
+stroke
+LT0
+.2654 g 4365 2646 M
+63 59 V
+stroke
+LT0
+.113 g 2982 2336 M
+48 -127 V
+stroke
+LT0
+.0868 g 2967 2197 M
+63 12 V
+stroke
+LT0
+.0494 g 4418 2088 M
+-48 37 V
+stroke
+LT0
+.0781 g 4432 2237 M
+-62 -112 V
+stroke
+LT0
+.1685 g 2996 2479 M
+48 -124 V
+stroke
+LT0
+.1411 g 2982 2336 M
+62 19 V
+stroke
+LT0
+.2479 g 4413 2600 M
+-48 46 V
+stroke
+LT0
+.2211 g 3011 2608 M
+48 -104 V
+stroke
+LT0
+.1973 g 2996 2479 M
+63 25 V
+stroke
+LT0
+.1924 g 4399 2452 M
+-48 55 V
+stroke
+LT0
+.2213 g 4413 2600 M
+-62 -93 V
+stroke
+LT0
+.2815 g 2790 2696 M
+-48 15 V
+stroke
+LT0
+.2799 g 2679 2695 M
+63 16 V
+stroke
+LT0
+.1093 g 4432 2237 M
+-48 46 V
+stroke
+LT0
+.1423 g 4447 2402 M
+-63 -119 V
+stroke
+LT0
+.0311 g 3015 2084 M
+28 -48 V
+stroke
+LT0
+.064 g 2967 2197 M
+48 -113 V
+stroke
+LT0
+.0111 g 3000 1992 M
+24 3 V
+stroke
+LT0
+.0428 g 2952 2078 M
+63 6 V
+stroke
+LT0
+.257 g 3011 2608 M
+-48 77 V
+stroke
+LT0
+.2705 g 2900 2665 M
+63 20 V
+stroke
+LT0
+.2817 g 4586 2688 M
+-48 25 V
+stroke
+LT0
+.2763 g 4476 2671 M
+62 42 V
+stroke
+LT0
+.2409 g 2948 2586 M
+63 22 V
+stroke
+LT0
+.0095 g 4403 1981 M
+-24 13 V
+stroke
+LT0
+.0312 g 4418 2088 M
+-52 -67 V
+stroke
+LT0
+.2764 g 2900 2665 M
+-48 48 V
+stroke
+LT0
+.2831 g 2790 2696 M
+62 17 V
+stroke
+LT0
+.1763 g 4447 2402 M
+-48 50 V
+stroke
+LT0
+.2062 g 4461 2556 M
+-62 -104 V
+stroke
+LT0
+.2758 g 4807 2672 M
+-48 15 V
+stroke
+LT0
+.2792 g 4697 2689 M
+62 -2 V
+stroke
+LT0
+.235 g 4461 2556 M
+-48 44 V
+stroke
+LT0
+.2555 g 4476 2671 M
+-63 -71 V
+stroke
+LT0
+.2834 g 4697 2689 M
+-48 19 V
+stroke
+LT0
+.2817 g 4586 2688 M
+63 20 V
+stroke
+LT0
+.2171 g 2948 2586 M
+48 -107 V
+stroke
+LT0
+.1942 g 2934 2461 M
+62 18 V
+stroke
+LT0
+.1668 g 2934 2461 M
+48 -125 V
+stroke
+LT0
+.1411 g 2919 2324 M
+63 12 V
+stroke
+LT0
+.0428 g 4466 2058 M
+-48 30 V
+stroke
+LT0
+.0693 g 4480 2198 M
+-62 -110 V
+stroke
+LT0
+.2658 g 4524 2636 M
+-48 35 V
+stroke
+LT0
+.098 g 4480 2198 M
+-48 39 V
+stroke
+LT0
+.1296 g 4495 2358 M
+-63 -121 V
+stroke
+LT0
+.1148 g 2919 2324 M
+48 -127 V
+stroke
+LT0
+.0905 g 2904 2192 M
+63 5 V
+stroke
+LT0
+.2815 g 2727 2681 M
+-48 14 V
+stroke
+LT0
+.2793 g 2617 2677 M
+62 18 V
+stroke
+LT0
+.2544 g 2948 2586 M
+-48 79 V
+stroke
+LT0
+.2693 g 2838 2648 M
+62 17 V
+stroke
+LT0
+.2387 g 2886 2569 M
+62 17 V
+stroke
+LT0
+.1626 g 4495 2358 M
+-48 44 V
+stroke
+LT0
+.1928 g 4509 2512 M
+-62 -110 V
+stroke
+LT0
+.0098 g 3016 1978 M
+-16 14 V
+stroke
+LT0
+.0284 g 2952 2078 M
+48 -86 V
+stroke
+LT0
+.0143 g 2938 1986 M
+62 6 V
+stroke
+LT0
+.2227 g 4509 2512 M
+-48 44 V
+stroke
+LT0
+.2453 g 4524 2636 M
+-63 -80 V
+stroke
+LT0
+.276 g 2838 2648 M
+-48 48 V
+stroke
+LT0
+.2831 g 2727 2681 M
+63 15 V
+stroke
+LT0
+.0693 g 2904 2192 M
+48 -114 V
+stroke
+LT0
+.0494 g 2890 2078 M
+62 0 V
+stroke
+LT0
+.2789 g 4634 2661 M
+-48 27 V
+stroke
+LT0
+.2712 g 4524 2636 M
+62 52 V
+stroke
+LT0
+.0084 g 4451 1959 M
+-48 22 V
+stroke
+LT0
+.0246 g 4466 2058 M
+-63 -77 V
+stroke
+LT0
+.0079 g 4390 1974 M
+13 7 V
+stroke
+LT0
+.2158 g 2886 2569 M
+48 -108 V
+stroke
+LT0
+.1942 g 2871 2448 M
+63 13 V
+stroke
+LT0
+.0905 g 4528 2167 M
+-48 31 V
+stroke
+LT0
+.1204 g 4543 2320 M
+-63 -122 V
+stroke
+LT0
+.2582 g 4572 2600 M
+-48 36 V
+stroke
+LT0
+.1685 g 2871 2448 M
+48 -124 V
+stroke
+LT0
+.1447 g 2856 2319 M
+63 5 V
+stroke
+LT0
+.0396 g 4514 2035 M
+-48 23 V
+stroke
+LT0
+.064 g 4528 2167 M
+-62 -109 V
+stroke
+LT0
+.2812 g 2665 2666 M
+-48 11 V
+stroke
+LT0
+.278 g 2554 2658 M
+63 19 V
+stroke
+LT0
+.2838 g 4745 2669 M
+-48 20 V
+stroke
+LT0
+.2806 g 4634 2661 M
+63 28 V
+stroke
+LT0
+.278 g 4855 2654 M
+-48 18 V
+stroke
+LT0
+.2805 g 4745 2669 M
+62 3 V
+stroke
+LT0
+.152 g 4543 2320 M
+-48 38 V
+stroke
+LT0
+.1817 g 4557 2472 M
+-62 -114 V
+stroke
+LT0
+.1204 g 2856 2319 M
+48 -127 V
+stroke
+LT0
+.098 g 2842 2195 M
+62 -3 V
+stroke
+LT0
+.2536 g 2886 2569 M
+-48 79 V
+stroke
+LT0
+.2693 g 2775 2634 M
+63 14 V
+stroke
+LT0
+.2387 g 2823 2555 M
+63 14 V
+stroke
+LT0
+.2119 g 4557 2472 M
+-48 40 V
+stroke
+LT0
+.2356 g 4572 2600 M
+-63 -88 V
+stroke
+LT0
+.2764 g 2775 2634 M
+-48 47 V
+stroke
+LT0
+.2834 g 2665 2666 M
+62 15 V
+stroke
+LT0
+.0087 g 2986 1933 M
+-48 53 V
+stroke
+LT0
+.0352 g 2890 2078 M
+48 -92 V
+stroke
+LT0
+.0214 g 2875 1988 M
+63 -2 V
+stroke
+LT0
+.2171 g 2823 2555 M
+48 -107 V
+stroke
+LT0
+.1973 g 2808 2441 M
+63 7 V
+stroke
+LT0
+.2757 g 4682 2634 M
+-48 27 V
+stroke
+LT0
+.2659 g 4572 2600 M
+62 61 V
+stroke
+LT0
+.0781 g 2842 2195 M
+48 -117 V
+stroke
+LT0
+.0596 g 2827 2086 M
+63 -8 V
+stroke
+LT0
+.2511 g 4620 2568 M
+-48 32 V
+stroke
+LT0
+.0868 g 4576 2142 M
+-48 25 V
+stroke
+LT0
+.1148 g 4591 2288 M
+-63 -121 V
+stroke
+LT0
+.0084 g 4499 1940 M
+-48 19 V
+stroke
+LT0
+.0234 g 4514 2035 M
+-63 -76 V
+stroke
+LT0
+.0056 g 4410 1939 M
+41 20 V
+stroke
+LT0
+.2805 g 2602 2651 M
+-48 7 V
+stroke
+LT0
+.2758 g 2491 2637 M
+63 21 V
+stroke
+LT0
+.1447 g 4591 2288 M
+-48 32 V
+stroke
+LT0
+.1735 g 4605 2437 M
+-62 -117 V
+stroke
+LT0
+.1735 g 2808 2441 M
+48 -122 V
+stroke
+LT0
+.152 g 2794 2321 M
+62 -2 V
+stroke
+LT0
+.0396 g 4562 2017 M
+-48 18 V
+stroke
+LT0
+.0623 g 4576 2142 M
+-62 -107 V
+stroke
+LT0
+.2033 g 4605 2437 M
+-48 35 V
+stroke
+LT0
+.2274 g 4620 2568 M
+-63 -96 V
+stroke
+LT0
+.2544 g 2823 2555 M
+-48 79 V
+stroke
+LT0
+.2705 g 2712 2622 M
+63 12 V
+stroke
+LT0
+.0017 g 2923 1923 M
+63 10 V
+stroke
+LT0
+.2409 g 2760 2546 M
+63 9 V
+stroke
+LT0
+.2837 g 4793 2648 M
+-48 21 V
+stroke
+LT0
+.279 g 4682 2634 M
+63 35 V
+stroke
+LT0
+.2793 g 4903 2635 M
+-48 19 V
+stroke
+LT0
+.2812 g 4793 2648 M
+62 6 V
+stroke
+LT0
+.2775 g 2712 2622 M
+-47 44 V
+stroke
+LT0
+.2837 g 2602 2651 M
+63 15 V
+stroke
+LT0
+.1296 g 2794 2321 M
+48 -126 V
+stroke
+LT0
+.1093 g 2779 2205 M
+63 -10 V
+stroke
+LT0
+.2792 g 2539 2635 M
+-48 2 V
+stroke
+LT0
+.2725 g 2429 2614 M
+62 23 V
+stroke
+LT0
+.2451 g 4668 2537 M
+-48 31 V
+stroke
+LT0
+.2609 g 4682 2634 M
+-62 -66 V
+stroke
+LT0
+.2211 g 2760 2546 M
+48 -105 V
+stroke
+LT0
+.2033 g 2746 2440 M
+62 1 V
+stroke
+LT0
+.2728 g 4730 2608 M
+-48 26 V
+stroke
+LT0
+.0144 g 2923 1923 M
+-48 65 V
+stroke
+LT0
+.0457 g 2827 2086 M
+48 -98 V
+stroke
+LT0
+.0323 g 2813 1997 M
+62 -9 V
+stroke
+LT0
+.0868 g 4624 2125 M
+-48 17 V
+stroke
+LT0
+.113 g 4639 2264 M
+-63 -122 V
+stroke
+LT0
+.1411 g 4639 2264 M
+-48 24 V
+stroke
+LT0
+.1685 g 4653 2408 M
+-62 -120 V
+stroke
+LT0
+.1973 g 4653 2408 M
+-48 29 V
+stroke
+LT0
+.2211 g 4668 2537 M
+-63 -100 V
+stroke
+LT0
+.0102 g 4547 1925 M
+-48 15 V
+stroke
+LT0
+.0246 g 4562 2017 M
+-63 -77 V
+stroke
+LT0
+.0046 g 4437 1908 M
+62 32 V
+stroke
+LT0
+.257 g 2760 2546 M
+-48 76 V
+stroke
+LT0
+.2728 g 2650 2611 M
+62 11 V
+stroke
+LT0
+.0908 g 2779 2205 M
+48 -119 V
+stroke
+LT0
+.0739 g 2765 2103 M
+62 -17 V
+stroke
+LT0
+.0031 g 2963 1906 M
+-40 17 V
+stroke
+LT0
+.0064 g 2861 1920 M
+62 3 V
+stroke
+LT0
+.2451 g 2698 2540 M
+62 6 V
+stroke
+LT0
+.1817 g 2746 2440 M
+48 -119 V
+stroke
+LT0
+.1626 g 2731 2329 M
+63 -8 V
+stroke
+LT0
+.279 g 2650 2611 M
+-48 40 V
+stroke
+LT0
+.2838 g 2539 2635 M
+63 16 V
+stroke
+LT0
+.0428 g 4610 2006 M
+-48 11 V
+stroke
+LT0
+.064 g 4624 2125 M
+-62 -108 V
+stroke
+LT0
+.2834 g 4841 2626 M
+-48 22 V
+stroke
+LT0
+.2775 g 4730 2608 M
+63 40 V
+stroke
+LT0
+.2767 g 2477 2617 M
+-48 -3 V
+stroke
+LT0
+.2677 g 2366 2587 M
+63 27 V
+stroke
+LT0
+.2799 g 4951 2615 M
+-48 20 V
+stroke
+LT0
+.2815 g 4841 2626 M
+62 9 V
+stroke
+LT0
+.0003 g 4478 1889 M
+-41 19 V
+stroke
+LT0
+.0015 g 4430 1910 M
+7 -2 V
+stroke
+LT0
+.0012 g 4430 1911 M
+7 -3 V
+stroke
+LT0
+.2409 g 4716 2510 M
+-48 27 V
+stroke
+LT0
+.257 g 4730 2608 M
+-62 -71 V
+stroke
+LT0
+.1423 g 2731 2329 M
+48 -124 V
+stroke
+LT0
+.1243 g 2717 2222 M
+62 -17 V
+stroke
+LT0
+.2705 g 4778 2584 M
+-48 24 V
+stroke
+LT0
+.2274 g 2698 2540 M
+48 -100 V
+stroke
+LT0
+.2119 g 2683 2443 M
+63 -3 V
+stroke
+LT0
+.1942 g 4701 2384 M
+-48 24 V
+stroke
+LT0
+.2171 g 4716 2510 M
+-63 -102 V
+stroke
+LT0
+.1411 g 4687 2247 M
+-48 17 V
+stroke
+LT0
+.1668 g 4701 2384 M
+-62 -120 V
+stroke
+LT0
+.2609 g 2698 2540 M
+-48 71 V
+stroke
+LT0
+.2757 g 2587 2602 M
+63 9 V
+stroke
+LT0
+.2728 g 2414 2597 M
+-48 -10 V
+stroke
+LT0
+.261 g 2304 2557 M
+62 30 V
+stroke
+LT0
+.0905 g 4672 2116 M
+-48 9 V
+stroke
+LT0
+.1148 g 4687 2247 M
+-63 -122 V
+stroke
+LT0
+.2806 g 2587 2602 M
+-48 33 V
+stroke
+LT0
+.2834 g 2477 2617 M
+62 18 V
+stroke
+LT0
+.0243 g 2861 1920 M
+-48 77 V
+stroke
+LT0
+.0605 g 2765 2103 M
+48 -106 V
+stroke
+LT0
+.0479 g 2750 2017 M
+63 -20 V
+stroke
+LT0
+.2511 g 2635 2537 M
+63 3 V
+stroke
+LT0
+.0069 g 2889 1897 M
+-28 23 V
+stroke
+LT0
+.0157 g 2798 1928 M
+63 -8 V
+stroke
+LT0
+.014 g 4590 1916 M
+-43 9 V
+stroke
+LT0
+.0284 g 4610 2006 M
+-63 -81 V
+stroke
+LT0
+.0069 g 4496 1893 M
+51 32 V
+stroke
+LT0
+.2831 g 4889 2606 M
+-48 20 V
+stroke
+LT0
+.2764 g 4778 2584 M
+63 42 V
+stroke
+LT0
+.1928 g 2683 2443 M
+48 -114 V
+stroke
+LT0
+.1763 g 2669 2342 M
+62 -13 V
+stroke
+LT0
+.1074 g 2717 2222 M
+48 -119 V
+stroke
+LT0
+.0924 g 2702 2127 M
+63 -24 V
+stroke
+LT0
+.0494 g 4658 2002 M
+-48 4 V
+stroke
+LT0
+.0693 g 4672 2116 M
+-62 -110 V
+stroke
+LT0
+.267 g 2352 2575 M
+-48 -18 V
+stroke
+LT0
+.2555 g 2285 2546 M
+17 10 V
+stroke
+LT0
+.2528 g 2268 2537 M
+15 8 V
+stroke
+LT0
+.2799 g 4999 2594 M
+-48 21 V
+stroke
+LT0
+.2815 g 4889 2606 M
+62 9 V
+stroke
+LT0
+.2387 g 4764 2487 M
+-48 23 V
+stroke
+LT0
+.2544 g 4778 2584 M
+-62 -74 V
+stroke
+LT0
+.0066 g 4443 1897 M
+32 -8 V
+stroke
+LT0
+.2693 g 4826 2563 M
+-48 21 V
+stroke
+LT0
+.2817 g 2525 2592 M
+-48 25 V
+stroke
+LT0
+.2821 g 2424 2601 M
+53 16 V
+stroke
+LT0
+.0104 g 2970 1909 M
+-44 -20 V
+stroke
+LT0
+.1942 g 4749 2366 M
+-48 18 V
+stroke
+LT0
+.2158 g 4764 2487 M
+-63 -103 V
+stroke
+LT0
+.2659 g 2635 2537 M
+-48 65 V
+stroke
+LT0
+.2789 g 2525 2592 M
+62 10 V
+stroke
+LT0
+.2356 g 2635 2537 M
+48 -94 V
+stroke
+LT0
+.2227 g 2621 2450 M
+62 -7 V
+stroke
+LT0
+.1447 g 4735 2237 M
+-48 10 V
+stroke
+LT0
+.1685 g 4749 2366 M
+-62 -119 V
+stroke
+LT0
+.1583 g 2669 2342 M
+48 -120 V
+stroke
+LT0
+.1428 g 2654 2246 M
+63 -24 V
+stroke
+LT0
+.2582 g 2573 2536 M
+62 1 V
+stroke
+LT0
+.098 g 4720 2114 M
+-48 2 V
+stroke
+LT0
+.1204 g 4735 2237 M
+-63 -121 V
+stroke
+LT0
+.02 g 2807 1917 M
+-9 11 V
+stroke
+LT0
+.0394 g 2750 2017 M
+48 -89 V
+stroke
+LT0
+.0311 g 2736 1948 M
+62 -20 V
+stroke
+LT0
+.0359 g 4658 2002 M
+-61 -85 V
+stroke
+LT0
+.2831 g 4937 2585 M
+-48 21 V
+stroke
+LT0
+.276 g 4826 2563 M
+63 43 V
+stroke
+LT0
+.0798 g 2702 2127 M
+48 -110 V
+stroke
+LT0
+.0686 g 2688 2047 M
+62 -30 V
+stroke
+LT0
+.2819 g 2462 2582 M
+-47 15 V
+stroke
+LT0
+.2788 g 2352 2575 M
+62 22 V
+stroke
+LT0
+.2387 g 4812 2469 M
+-48 18 V
+stroke
+LT0
+.2536 g 4826 2563 M
+-62 -76 V
+stroke
+LT0
+.2793 g 5047 2573 M
+-48 21 V
+stroke
+LT0
+.2815 g 4937 2585 M
+62 9 V
+stroke
+LT0
+.2062 g 2621 2450 M
+48 -108 V
+stroke
+LT0
+.1924 g 2606 2360 M
+63 -18 V
+stroke
+LT0
+.2693 g 4874 2544 M
+-48 19 V
+stroke
+LT0
+.2712 g 2573 2536 M
+-48 56 V
+stroke
+LT0
+.2817 g 2462 2582 M
+63 10 V
+stroke
+LT0
+.0596 g 4706 2005 M
+-48 -3 V
+stroke
+LT0
+.0781 g 4720 2114 M
+-62 -112 V
+stroke
+LT0
+.1278 g 2654 2246 M
+48 -119 V
+stroke
+LT0
+.1149 g 2640 2159 M
+62 -32 V
+stroke
+LT0
+.1973 g 4797 2355 M
+-48 11 V
+stroke
+LT0
+.2171 g 4812 2469 M
+-63 -103 V
+stroke
+LT0
+.2453 g 2573 2536 M
+48 -86 V
+stroke
+LT0
+.235 g 2558 2460 M
+63 -10 V
+stroke
+LT0
+.2658 g 2510 2535 M
+63 1 V
+stroke
+LT0
+.2804 g 2400 2568 M
+-48 7 V
+stroke
+LT0
+.2737 g 2289 2547 M
+63 28 V
+stroke
+LT0
+.152 g 4783 2234 M
+-48 3 V
+stroke
+LT0
+.1735 g 4797 2355 M
+-62 -118 V
+stroke
+LT0
+.183 g 1976 2325 M
+-48 -36 V
+stroke
+LT0
+.1594 g 1866 2238 M
+62 51 V
+stroke
+LT0
+.2834 g 4985 2566 M
+-48 19 V
+stroke
+LT0
+.2764 g 4874 2544 M
+63 41 V
+stroke
+LT0
+.177 g 2606 2360 M
+48 -114 V
+stroke
+LT0
+.1642 g 2592 2274 M
+62 -28 V
+stroke
+LT0
+.278 g 5095 2549 M
+-48 24 V
+stroke
+LT0
+.2812 g 4985 2566 M
+62 7 V
+stroke
+LT0
+.1637 g 1914 2269 M
+-48 -31 V
+stroke
+LT0
+.142 g 1803 2190 M
+63 48 V
+stroke
+LT0
+.1093 g 4768 2119 M
+-48 -5 V
+stroke
+LT0
+.1296 g 4783 2234 M
+-63 -120 V
+stroke
+LT0
+.2409 g 4860 2455 M
+-48 14 V
+stroke
+LT0
+.2544 g 4874 2544 M
+-62 -75 V
+stroke
+LT0
+.2763 g 2510 2535 M
+-48 47 V
+stroke
+LT0
+.2834 g 2400 2568 M
+62 14 V
+stroke
+LT0
+.0509 g 4706 2005 M
+-47 -69 V
+stroke
+LT0
+.0381 g 2744 1936 M
+-8 12 V
+stroke
+LT0
+.0603 g 2688 2047 M
+48 -99 V
+stroke
+LT0
+.0531 g 2673 1982 M
+63 -34 V
+stroke
+LT0
+.0288 g 2970 1909 M
+-29 -23 V
+stroke
+LT0
+.2766 g 2337 2550 M
+-48 -3 V
+stroke
+LT0
+.266 g 2227 2513 M
+62 34 V
+stroke
+LT0
+.2705 g 4922 2527 M
+-48 17 V
+stroke
+LT0
+.1453 g 1851 2214 M
+-48 -24 V
+stroke
+LT0
+.1268 g 1741 2147 M
+62 43 V
+stroke
+LT0
+.1037 g 2640 2159 M
+48 -112 V
+stroke
+LT0
+.0943 g 2625 2086 M
+63 -39 V
+stroke
+LT0
+.2213 g 2558 2460 M
+48 -100 V
+stroke
+LT0
+.2103 g 2544 2381 M
+62 -21 V
+stroke
+LT0
+.2033 g 4845 2349 M
+-48 6 V
+stroke
+LT0
+.2211 g 4860 2455 M
+-63 -100 V
+stroke
+LT0
+.1289 g 1789 2161 M
+-48 -14 V
+stroke
+LT0
+.1147 g 1678 2111 M
+63 36 V
+stroke
+LT0
+.0739 g 4754 2016 M
+-48 -11 V
+stroke
+LT0
+.0908 g 4768 2119 M
+-62 -114 V
+stroke
+LT0
+.2555 g 2558 2460 M
+-48 75 V
+stroke
+LT0
+.273 g 2448 2533 M
+62 2 V
+stroke
+LT0
+.27 g 2275 2526 M
+-48 -13 V
+stroke
+LT0
+.2554 g 2164 2474 M
+63 39 V
+stroke
+LT0
+.2479 g 2496 2469 M
+62 -9 V
+stroke
+LT0
+.2802 g 2448 2533 M
+-48 35 V
+stroke
+LT0
+.2833 g 2337 2550 M
+63 18 V
+stroke
+LT0
+.2837 g 5033 2546 M
+-48 20 V
+stroke
+LT0
+.2775 g 4922 2527 M
+63 39 V
+stroke
+LT0
+.1514 g 2592 2274 M
+48 -115 V
+stroke
+LT0
+.1409 g 2577 2197 M
+63 -38 V
+stroke
+LT0
+.2758 g 5143 2523 M
+-48 26 V
+stroke
+LT0
+.2805 g 5033 2546 M
+62 3 V
+stroke
+LT0
+.0312 g 4437 1901 M
+20 -16 V
+stroke
+LT0
+.1626 g 4831 2238 M
+-48 -4 V
+stroke
+LT0
+.1817 g 4845 2349 M
+-62 -115 V
+stroke
+LT0
+.1159 g 1726 2115 M
+-48 -4 V
+stroke
+LT0
+.1069 g 1616 2084 M
+62 27 V
+stroke
+LT0
+.2602 g 2212 2495 M
+-48 -21 V
+stroke
+LT0
+.242 g 2102 2429 M
+62 45 V
+stroke
+LT0
+.2451 g 4908 2444 M
+-48 11 V
+stroke
+LT0
+.257 g 4922 2527 M
+-62 -72 V
+stroke
+LT0
+.2728 g 4970 2511 M
+-48 16 V
+stroke
+LT0
+.2471 g 2150 2457 M
+-48 -28 V
+stroke
+LT0
+.2254 g 2039 2379 M
+60 48 V
+stroke
+LT0
+.1243 g 4816 2131 M
+-48 -12 V
+stroke
+LT0
+.1423 g 4831 2238 M
+-63 -119 V
+stroke
+LT0
+.1975 g 2544 2381 M
+48 -107 V
+stroke
+LT0
+.1875 g 2529 2305 M
+63 -31 V
+stroke
+LT0
+.0685 g 4754 2016 M
+-40 -63 V
+stroke
+LT0
+.2308 g 2087 2412 M
+-48 -33 V
+stroke
+LT0
+.2058 g 1976 2325 M
+53 46 V
+stroke
+LT0
+.2821 g 2385 2527 M
+-48 23 V
+stroke
+LT0
+.2806 g 2275 2526 M
+62 24 V
+stroke
+LT0
+.1074 g 1664 2076 M
+-48 8 V
+stroke
+LT0
+.1041 g 1553 2068 M
+63 16 V
+stroke
+LT0
+.2654 g 2496 2469 M
+-48 64 V
+stroke
+LT0
+.279 g 2385 2527 M
+63 6 V
+stroke
+LT0
+.06 g 2673 1982 M
+16 -29 V
+stroke
+LT0
+.087 g 2625 2086 M
+48 -104 V
+stroke
+LT0
+.0814 g 2611 2027 M
+62 -45 V
+stroke
+LT0
+.2119 g 2024 2361 M
+-48 -36 V
+stroke
+LT0
+.1873 g 1914 2269 M
+62 56 V
+stroke
+LT0
+.2119 g 4893 2348 M
+-48 1 V
+stroke
+LT0
+.2274 g 4908 2444 M
+-63 -95 V
+stroke
+LT0
+.237 g 2496 2469 M
+48 -88 V
+stroke
+LT0
+.2289 g 2481 2401 M
+63 -20 V
+stroke
+LT0
+.0525 g 2998 1949 M
+-34 -50 V
+stroke
+LT0
+.2725 g 5191 2495 M
+-48 28 V
+stroke
+LT0
+.2792 g 5081 2526 M
+62 -3 V
+stroke
+LT0
+.1912 g 1962 2304 M
+-48 -35 V
+stroke
+LT0
+.1669 g 1851 2214 M
+63 55 V
+stroke
+LT0
+.2838 g 5081 2526 M
+-48 20 V
+stroke
+LT0
+.279 g 4970 2511 M
+63 35 V
+stroke
+LT0
+.2604 g 2433 2477 M
+63 -8 V
+stroke
+LT0
+.1699 g 1899 2245 M
+-48 -31 V
+stroke
+LT0
+.1474 g 1789 2161 M
+62 53 V
+stroke
+LT0
+.0466 g 2970 1905 M
+-21 -20 V
+stroke
+LT0
+.1315 g 2577 2197 M
+48 -111 V
+stroke
+LT0
+.1243 g 2563 2132 M
+62 -46 V
+stroke
+LT0
+.0924 g 4802 2036 M
+-48 -20 V
+stroke
+LT0
+.1074 g 4816 2131 M
+-62 -115 V
+stroke
+LT0
+.1494 g 1837 2185 M
+-48 -24 V
+stroke
+LT0
+.1301 g 1726 2115 M
+63 46 V
+stroke
+LT0
+.2812 g 2323 2516 M
+-48 10 V
+stroke
+LT0
+.2752 g 2219 2499 M
+56 27 V
+stroke
+LT0
+.2511 g 4956 2437 M
+-48 7 V
+stroke
+LT0
+.2609 g 4970 2511 M
+-62 -67 V
+stroke
+LT0
+.1763 g 4879 2247 M
+-48 -9 V
+stroke
+LT0
+.1928 g 4893 2348 M
+-62 -110 V
+stroke
+LT0
+.2757 g 5018 2497 M
+-48 14 V
+stroke
+LT0
+.1042 g 1601 2048 M
+-48 20 V
+stroke
+LT0
+.1067 g 1491 2063 M
+62 5 V
+stroke
+LT0
+.1312 g 1774 2129 M
+-48 -14 V
+stroke
+LT0
+.1164 g 1664 2076 M
+62 39 V
+stroke
+LT0
+.0624 g 4397 1959 M
+29 -43 V
+stroke
+LT0
+.1771 g 2529 2305 M
+48 -108 V
+stroke
+LT0
+.1692 g 2515 2238 M
+62 -41 V
+stroke
+LT0
+.2739 g 2433 2477 M
+-48 50 V
+stroke
+LT0
+.2827 g 2323 2516 M
+62 11 V
+stroke
+LT0
+.2677 g 5239 2463 M
+-48 32 V
+stroke
+LT0
+.2767 g 5129 2503 M
+62 -8 V
+stroke
+LT0
+.2769 g 2260 2497 M
+-47 -2 V
+stroke
+LT0
+.2653 g 2150 2457 M
+62 38 V
+stroke
+LT0
+.1168 g 1712 2080 M
+-48 -4 V
+stroke
+LT0
+.1075 g 1601 2048 M
+63 28 V
+stroke
+LT0
+.2834 g 5129 2503 M
+-48 23 V
+stroke
+LT0
+.2806 g 5018 2497 M
+63 29 V
+stroke
+LT0
+.2188 g 2481 2401 M
+48 -96 V
+stroke
+LT0
+.2115 g 2467 2336 M
+62 -31 V
+stroke
+LT0
+.1428 g 4864 2150 M
+-48 -19 V
+stroke
+LT0
+.1583 g 4879 2247 M
+-63 -116 V
+stroke
+LT0
+.0586 g 4409 1937 M
+42 -53 V
+stroke
+LT0
+.2522 g 2481 2401 M
+-48 76 V
+stroke
+LT0
+.2712 g 2371 2480 M
+62 -3 V
+stroke
+LT0
+.2227 g 4941 2350 M
+-48 -2 V
+stroke
+LT0
+.2356 g 4956 2437 M
+-63 -89 V
+stroke
+LT0
+.0882 g 4802 2036 M
+-40 -67 V
+stroke
+LT0
+.2682 g 2198 2470 M
+-48 -13 V
+stroke
+LT0
+.2521 g 2087 2412 M
+63 45 V
+stroke
+LT0
+.2467 g 2419 2419 M
+62 -18 V
+stroke
+LT0
+.0855 g 2611 2027 M
+29 -57 V
+stroke
+LT0
+.1067 g 1539 2032 M
+-48 31 V
+stroke
+LT0
+.1075 g 1649 2040 M
+-48 8 V
+stroke
+LT0
+.1042 g 1539 2032 M
+62 16 V
+stroke
+LT0
+.2799 g 2371 2480 M
+-48 36 V
+stroke
+LT0
+.2832 g 2260 2497 M
+63 19 V
+stroke
+LT0
+.2555 g 2135 2434 M
+-48 -22 V
+stroke
+LT0
+.2354 g 2024 2361 M
+63 51 V
+stroke
+LT0
+.2789 g 5066 2483 M
+-48 14 V
+stroke
+LT0
+.2659 g 4956 2437 M
+62 60 V
+stroke
+LT0
+.1186 g 2563 2132 M
+48 -105 V
+stroke
+LT0
+.1149 g 2548 2081 M
+63 -54 V
+stroke
+LT0
+.2582 g 5004 2431 M
+-48 6 V
+stroke
+LT0
+.261 g 5287 2428 M
+-48 35 V
+stroke
+LT0
+.2728 g 5177 2479 M
+62 -16 V
+stroke
+LT0
+.2388 g 2072 2389 M
+-48 -28 V
+stroke
+LT0
+.2158 g 1962 2304 M
+62 57 V
+stroke
+LT0
+.0789 g 3026 1993 M
+-70 -109 V
+stroke
+LT0
+.2188 g 2010 2336 M
+-48 -32 V
+stroke
+LT0
+.1942 g 1899 2245 M
+63 59 V
+stroke
+LT0
+.1149 g 4850 2063 M
+-48 -27 V
+stroke
+LT0
+.1278 g 4864 2150 M
+-62 -114 V
+stroke
+LT0
+.1965 g 1947 2277 M
+-48 -32 V
+stroke
+LT0
+.1719 g 1837 2185 M
+62 60 V
+stroke
+LT0
+.1924 g 4927 2260 M
+-48 -13 V
+stroke
+LT0
+.2062 g 4941 2350 M
+-62 -103 V
+stroke
+LT0
+.0611 g 2976 1889 M
+-6 -6 V
+stroke
+LT0
+.162 g 2515 2238 M
+48 -106 V
+stroke
+LT0
+.157 g 2500 2182 M
+63 -50 V
+stroke
+LT0
+.1734 g 1885 2214 M
+-48 -29 V
+stroke
+LT0
+.1505 g 1774 2129 M
+63 56 V
+stroke
+LT0
+.2819 g 5177 2479 M
+-48 24 V
+stroke
+LT0
+.2817 g 5066 2483 M
+63 20 V
+stroke
+LT0
+.1512 g 1822 2152 M
+-48 -23 V
+stroke
+LT0
+.1316 g 1712 2080 M
+62 49 V
+stroke
+LT0
+.1148 g 3062 2076 M
+-48 -101 V
+stroke
+LT0
+.2824 g 2308 2476 M
+-48 21 V
+stroke
+LT0
+.2797 g 2198 2470 M
+62 27 V
+stroke
+LT0
+.2657 g 2419 2419 M
+-48 61 V
+stroke
+LT0
+.2791 g 2308 2476 M
+63 4 V
+stroke
+LT0
+.1041 g 1587 2012 M
+-48 20 V
+stroke
+LT0
+.1316 g 1760 2093 M
+-48 -13 V
+stroke
+LT0
+.1168 g 1649 2040 M
+63 40 V
+stroke
+LT0
+.2037 g 2467 2336 M
+48 -98 V
+stroke
+LT0
+.1983 g 2452 2279 M
+63 -41 V
+stroke
+LT0
+.2523 g 5335 2388 M
+-48 40 V
+stroke
+LT0
+.267 g 5225 2450 M
+62 -22 V
+stroke
+LT0
+.235 g 4989 2354 M
+-48 -4 V
+stroke
+LT0
+.2453 g 5004 2431 M
+-63 -81 V
+stroke
+LT0
+.2394 g 2419 2419 M
+48 -83 V
+stroke
+LT0
+.2346 g 2404 2364 M
+63 -28 V
+stroke
+LT0
+.2625 g 2356 2431 M
+63 -12 V
+stroke
+LT0
+.2817 g 5114 2467 M
+-48 16 V
+stroke
+LT0
+.2712 g 5004 2431 M
+62 52 V
+stroke
+LT0
+.1164 g 1697 2042 M
+-48 -2 V
+stroke
+LT0
+.1074 g 1587 2012 M
+62 28 V
+stroke
+LT0
+.1642 g 4912 2173 M
+-48 -23 V
+stroke
+LT0
+.177 g 4927 2260 M
+-63 -110 V
+stroke
+LT0
+.2803 g 2246 2464 M
+-48 6 V
+stroke
+LT0
+.2716 g 2135 2434 M
+63 36 V
+stroke
+LT0
+.2658 g 5052 2425 M
+-48 6 V
+stroke
+LT0
+.2788 g 5225 2450 M
+-48 29 V
+stroke
+LT0
+.2819 g 5114 2467 M
+63 12 V
+stroke
+LT0
+.0931 g 4805 1986 M
+-1 -2 V
+stroke
+LT0
+.1104 g 4850 2063 M
+-45 -76 V
+stroke
+LT0
+.1003 g 4341 2069 M
+96 -187 V
+stroke
+LT0
+.1377 g 4332 2092 M
+21 -46 V
+stroke
+LT0
+.2413 g 5383 2344 M
+-48 44 V
+stroke
+LT0
+.2589 g 5273 2417 M
+62 -29 V
+stroke
+LT0
+.0855 g 4378 1972 M
+59 -90 V
+stroke
+LT0
+.2759 g 2356 2431 M
+-48 45 V
+stroke
+LT0
+.283 g 2246 2464 M
+62 12 V
+stroke
+LT0
+.1137 g 2548 2081 M
+46 -94 V
+stroke
+LT0
+.1146 g 2534 2045 M
+57 -57 V
+stroke
+LT0
+.2732 g 2183 2440 M
+-48 -6 V
+stroke
+LT0
+.2589 g 2072 2389 M
+63 45 V
+stroke
+LT0
+.1069 g 1635 2002 M
+-48 10 V
+stroke
+LT0
+.2103 g 4975 2275 M
+-48 -15 V
+stroke
+LT0
+.2213 g 4989 2354 M
+-62 -94 V
+stroke
+LT0
+.0613 g 2976 1889 M
+-5 -7 V
+stroke
+LT0
+.1533 g 2500 2182 M
+48 -101 V
+stroke
+LT0
+.1516 g 2486 2139 M
+62 -58 V
+stroke
+LT0
+.261 g 2120 2406 M
+-48 -17 V
+stroke
+LT0
+.2419 g 2010 2336 M
+62 53 V
+stroke
+LT0
+.1409 g 4898 2096 M
+-48 -33 V
+stroke
+LT0
+.1514 g 4912 2173 M
+-62 -110 V
+stroke
+LT0
+.2438 g 2058 2361 M
+-48 -25 V
+stroke
+LT0
+.2212 g 1947 2277 M
+63 59 V
+stroke
+LT0
+.2281 g 5431 2295 M
+-48 49 V
+stroke
+LT0
+.2483 g 5321 2379 M
+62 -35 V
+stroke
+LT0
+.2834 g 5162 2448 M
+-48 19 V
+stroke
+LT0
+.2763 g 5052 2425 M
+62 42 V
+stroke
+LT0
+.2226 g 1995 2306 M
+-48 -29 V
+stroke
+LT0
+.198 g 1885 2214 M
+62 63 V
+stroke
+LT0
+.1988 g 1933 2243 M
+-48 -29 V
+stroke
+LT0
+.1741 g 1822 2152 M
+63 62 V
+stroke
+LT0
+.1933 g 2452 2279 M
+48 -97 V
+stroke
+LT0
+.1904 g 2438 2231 M
+62 -49 V
+stroke
+LT0
+.1741 g 1870 2178 M
+-48 -26 V
+stroke
+LT0
+.1512 g 1760 2093 M
+62 59 V
+stroke
+LT0
+.2737 g 5273 2417 M
+-48 33 V
+stroke
+LT0
+.2804 g 5162 2448 M
+63 2 V
+stroke
+LT0
+.2577 g 2404 2364 M
+-48 67 V
+stroke
+LT0
+.2746 g 2294 2435 M
+62 -4 V
+stroke
+LT0
+.1505 g 1808 2113 M
+-48 -20 V
+stroke
+LT0
+.1312 g 1697 2042 M
+63 51 V
+stroke
+LT0
+.0854 g 3024 1957 M
+-48 -68 V
+stroke
+LT0
+.1229 g 3086 2119 M
+2976 1889 L
+stroke
+LT0
+.2479 g 5037 2359 M
+-48 -5 V
+stroke
+LT0
+.2555 g 5052 2425 M
+-63 -71 V
+stroke
+LT0
+.2292 g 2404 2364 M
+48 -85 V
+stroke
+LT0
+.226 g 2390 2315 M
+62 -36 V
+stroke
+LT0
+.2817 g 2294 2435 M
+-48 29 V
+stroke
+LT0
+.2819 g 2183 2440 M
+63 24 V
+stroke
+LT0
+.1301 g 1745 2052 M
+-48 -10 V
+stroke
+LT0
+.1159 g 1635 2002 M
+62 40 V
+stroke
+LT0
+.255 g 2342 2384 M
+62 -20 V
+stroke
+LT0
+.273 g 5100 2418 M
+-48 7 V
+stroke
+LT0
+.2127 g 5479 2243 M
+-48 52 V
+stroke
+LT0
+.2352 g 5369 2335 M
+62 -40 V
+stroke
+LT0
+.1875 g 4960 2200 M
+-48 -27 V
+stroke
+LT0
+.1975 g 4975 2275 M
+-63 -102 V
+stroke
+LT0
+.1147 g 1683 2001 M
+-48 1 V
+stroke
+LT0
+.266 g 5321 2379 M
+-48 38 V
+stroke
+LT0
+.2766 g 5210 2425 M
+63 -8 V
+stroke
+LT0
+.2819 g 2231 2427 M
+-48 13 V
+stroke
+LT0
+.2753 g 2120 2406 M
+63 34 V
+stroke
+LT0
+.1957 g 5527 2187 M
+-48 56 V
+stroke
+LT0
+.2195 g 5417 2285 M
+62 -42 V
+stroke
+LT0
+.2833 g 5210 2425 M
+-48 23 V
+stroke
+LT0
+.2802 g 5100 2418 M
+62 30 V
+stroke
+LT0
+.1306 g 4883 2032 M
+-29 -25 V
+stroke
+LT0
+.1337 g 4898 2096 M
+-57 -96 V
+stroke
+LT0
+.2719 g 2342 2384 M
+-48 51 V
+stroke
+LT0
+.2817 g 2231 2427 M
+63 8 V
+stroke
+LT0
+.1924 g 3136 2266 M
+-85 -221 V
+stroke
+LT0
+.2289 g 5023 2291 M
+-48 -16 V
+stroke
+LT0
+.237 g 5037 2359 M
+-62 -84 V
+stroke
+LT0
+.1247 g 2534 2045 M
+21 -41 V
+stroke
+LT0
+.1397 g 2519 2023 M
+1 -1 V
+stroke
+LT0
+.276 g 2168 2407 M
+-48 -1 V
+stroke
+LT0
+.2629 g 2058 2361 M
+62 45 V
+stroke
+LT0
+.1776 g 5575 2131 M
+-48 56 V
+stroke
+LT0
+.2019 g 5465 2231 M
+62 -44 V
+stroke
+LT0
+.0885 g 4378 1972 M
+42 -94 V
+stroke
+LT0
+.0947 g 4364 1955 M
+52 -77 V
+stroke
+LT0
+.1516 g 2486 2139 M
+48 -94 V
+stroke
+LT0
+.1533 g 2471 2109 M
+63 -64 V
+stroke
+LT0
+.2554 g 5369 2335 M
+-48 44 V
+stroke
+LT0
+.27 g 5258 2397 M
+63 -18 V
+stroke
+LT0
+.279 g 5148 2407 M
+-48 11 V
+stroke
+LT0
+.2654 g 5037 2359 M
+63 59 V
+stroke
+LT0
+.0905 g 3024 1957 M
+-38 -78 V
+stroke
+LT0
+.2604 g 5085 2362 M
+-48 -3 V
+stroke
+LT0
+.2517 g 2390 2315 M
+-48 69 V
+stroke
+LT0
+.2708 g 2279 2394 M
+63 -10 V
+stroke
+LT0
+.2638 g 2106 2373 M
+-48 -12 V
+stroke
+LT0
+.2453 g 1995 2306 M
+63 55 V
+stroke
+LT0
+.1887 g 2438 2231 M
+48 -92 V
+stroke
+LT0
+.1887 g 2423 2195 M
+63 -56 V
+stroke
+LT0
+.1719 g 1856 2136 M
+-48 -23 V
+stroke
+LT0
+.1734 g 1870 2178 M
+-62 -65 V
+stroke
+LT0
+.1494 g 1745 2052 M
+63 61 V
+stroke
+LT0
+.1692 g 4946 2133 M
+-48 -37 V
+stroke
+LT0
+.1771 g 4960 2200 M
+-62 -104 V
+stroke
+LT0
+.198 g 1918 2204 M
+-48 -26 V
+stroke
+LT0
+.1988 g 1933 2243 M
+-63 -65 V
+stroke
+LT0
+.1474 g 1793 2068 M
+-48 -16 V
+stroke
+LT0
+.1289 g 1683 2001 M
+62 51 V
+stroke
+LT0
+.2459 g 2043 2327 M
+-48 -21 V
+stroke
+LT0
+.2234 g 1933 2243 M
+62 63 V
+stroke
+LT0
+.2234 g 1981 2269 M
+-48 -26 V
+stroke
+LT0
+.1594 g 5623 2075 M
+-48 56 V
+stroke
+LT0
+.183 g 5513 2172 M
+62 -41 V
+stroke
+LT0
+.2231 g 2390 2315 M
+48 -84 V
+stroke
+LT0
+.222 g 2375 2274 M
+63 -43 V
+stroke
+LT0
+.2502 g 2327 2342 M
+63 -27 V
+stroke
+LT0
+.1455 g 4316 2103 M
+62 -131 V
+stroke
+LT0
+.1794 g 4268 2256 M
+110 -284 V
+stroke
+LT0
+.2806 g 5258 2397 M
+-48 28 V
+stroke
+LT0
+.2821 g 5148 2407 M
+62 18 V
+stroke
+LT0
+.1268 g 1731 2008 M
+-48 -7 V
+stroke
+LT0
+.2806 g 2279 2394 M
+-48 33 V
+stroke
+LT0
+.2827 g 2168 2407 M
+63 20 V
+stroke
+LT0
+.242 g 5417 2285 M
+-48 50 V
+stroke
+LT0
+.2602 g 5306 2361 M
+63 -26 V
+stroke
+LT0
+.142 g 5671 2022 M
+-48 53 V
+stroke
+LT0
+.1637 g 5561 2111 M
+62 -36 V
+stroke
+LT0
+.2115 g 5008 2226 M
+-48 -26 V
+stroke
+LT0
+.2188 g 5023 2291 M
+-63 -91 V
+stroke
+LT0
+.2341 g 4249 2319 M
+55 -155 V
+stroke
+LT0
+.1368 g 4883 2032 M
+-10 -16 V
+stroke
+LT0
+.1326 g 3072 2032 M
+-48 -75 V
+stroke
+LT0
+.1455 g 3086 2119 M
+-62 -162 V
+stroke
+LT0
+.2258 g 5465 2231 M
+-48 54 V
+stroke
+LT0
+.2471 g 5354 2319 M
+63 -34 V
+stroke
+LT0
+.2827 g 5196 2391 M
+-48 16 V
+stroke
+LT0
+.2739 g 5085 2362 M
+63 45 V
+stroke
+LT0
+.2825 g 2216 2390 M
+-48 17 V
+stroke
+LT0
+.2769 g 2106 2373 M
+62 34 V
+stroke
+LT0
+.1268 g 5719 1974 M
+-48 48 V
+stroke
+LT0
+.1453 g 5609 2051 M
+62 -29 V
+stroke
+LT0
+.2693 g 2327 2342 M
+-48 52 V
+stroke
+LT0
+.2804 g 2216 2390 M
+63 4 V
+stroke
+LT0
+.2748 g 5306 2361 M
+-48 36 V
+stroke
+LT0
+.2812 g 5196 2391 M
+62 6 V
+stroke
+LT0
+.2467 g 5071 2304 M
+-48 -13 V
+stroke
+LT0
+.2522 g 5085 2362 M
+-62 -71 V
+stroke
+LT0
+.2712 g 5133 2360 M
+-48 2 V
+stroke
+LT0
+.157 g 4931 2077 M
+-48 -45 V
+stroke
+LT0
+.162 g 4946 2133 M
+-63 -101 V
+stroke
+LT0
+.2073 g 5513 2172 M
+-48 59 V
+stroke
+LT0
+.2308 g 5402 2269 M
+63 -38 V
+stroke
+LT0
+.2771 g 2154 2371 M
+-48 2 V
+stroke
+LT0
+.2645 g 2043 2327 M
+63 46 V
+stroke
+LT0
+.1005 g 4364 1955 M
+30 -81 V
+stroke
+LT0
+.0992 g 4349 1899 M
+24 -28 V
+stroke
+LT0
+.1147 g 5767 1934 M
+-48 40 V
+stroke
+LT0
+.1289 g 5657 1994 M
+62 -20 V
+stroke
+LT0
+.2491 g 2375 2274 M
+-48 68 V
+stroke
+LT0
+.2688 g 2264 2356 M
+63 -14 V
+stroke
+LT0
+.1669 g 1841 2088 M
+-48 -20 V
+stroke
+LT0
+.1699 g 1856 2136 M
+-63 -68 V
+stroke
+LT0
+.1453 g 1731 2008 M
+62 60 V
+stroke
+LT0
+.142 g 1779 2020 M
+-48 -12 V
+stroke
+LT0
+.1942 g 1904 2159 M
+-48 -23 V
+stroke
+LT0
+.1965 g 1918 2204 M
+-62 -68 V
+stroke
+LT0
+.2645 g 2091 2337 M
+-48 -10 V
+stroke
+LT0
+.2459 g 1981 2269 M
+62 58 V
+stroke
+LT0
+.14 g 2519 2023 M
+0 -1 V
+stroke
+LT0
+.157 g 2471 2109 M
+48 -86 V
+stroke
+LT0
+.162 g 2456 2093 M
+63 -70 V
+stroke
+LT0
+.1873 g 5561 2111 M
+-48 61 V
+stroke
+LT0
+.2119 g 5450 2212 M
+63 -40 V
+stroke
+LT0
+.2212 g 1966 2227 M
+-48 -23 V
+stroke
+LT0
+.2226 g 1981 2269 M
+-63 -65 V
+stroke
+LT0
+.222 g 2423 2195 M
+-48 79 V
+stroke
+LT0
+.2491 g 2312 2305 M
+63 -31 V
+stroke
+LT0
+.1904 g 2423 2195 M
+48 -86 V
+stroke
+LT0
+.1933 g 2408 2170 M
+63 -61 V
+stroke
+LT0
+.0987 g 3057 1910 M
+-43 -37 V
+stroke
+LT0
+.1204 g 3072 2032 M
+-61 -159 V
+stroke
+LT0
+.2453 g 2029 2288 M
+-48 -19 V
+stroke
+LT0
+.2231 g 2360 2242 M
+63 -47 V
+stroke
+LT0
+.2653 g 5354 2319 M
+-48 42 V
+stroke
+LT0
+.2767 g 5244 2368 M
+62 -7 V
+stroke
+LT0
+.1983 g 4994 2169 M
+-48 -36 V
+stroke
+LT0
+.2037 g 5008 2226 M
+-62 -93 V
+stroke
+LT0
+.2832 g 5244 2368 M
+-48 23 V
+stroke
+LT0
+.2799 g 5133 2360 M
+63 31 V
+stroke
+LT0
+.28 g 2264 2356 M
+-48 34 V
+stroke
+LT0
+.2827 g 2154 2371 M
+62 19 V
+stroke
+LT0
+.1669 g 5609 2051 M
+-48 60 V
+stroke
+LT0
+.1912 g 5498 2151 M
+63 -40 V
+stroke
+LT0
+.1069 g 5815 1902 M
+-48 32 V
+stroke
+LT0
+.1159 g 5705 1942 M
+62 -8 V
+stroke
+LT0
+.1505 g 4316 2103 M
+48 -148 V
+stroke
+LT0
+.1505 g 4301 2067 M
+63 -112 V
+stroke
+LT0
+.2346 g 5056 2249 M
+-48 -23 V
+stroke
+LT0
+.2394 g 5071 2304 M
+-63 -78 V
+stroke
+LT0
+.1474 g 5657 1994 M
+-48 57 V
+stroke
+LT0
+.1699 g 5546 2087 M
+63 -36 V
+stroke
+LT0
+.1034 g 3057 1910 M
+-18 -42 V
+stroke
+LT0
+.217 g 3134 2231 M
+-48 -112 V
+stroke
+LT0
+.2687 g 3197 2449 M
+3086 2119 L
+stroke
+LT0
+.2521 g 5402 2269 M
+-48 50 V
+stroke
+LT0
+.2682 g 5292 2336 M
+62 -17 V
+stroke
+LT0
+.2791 g 5181 2352 M
+-48 8 V
+stroke
+LT0
+.2657 g 5071 2304 M
+62 56 V
+stroke
+LT0
+.2625 g 5119 2311 M
+-48 -7 V
+stroke
+LT0
+.2827 g 2202 2354 M
+-48 17 V
+stroke
+LT0
+.2771 g 2091 2337 M
+63 34 V
+stroke
+LT0
+.2688 g 2312 2305 M
+-48 51 V
+stroke
+LT0
+.28 g 2202 2354 M
+62 2 V
+stroke
+LT0
+.1013 g 4349 1899 M
+11 -30 V
+stroke
+LT0
+.1636 g 4931 2077 M
+-31 -48 V
+stroke
+LT0
+.1301 g 5705 1942 M
+-48 52 V
+stroke
+LT0
+.1494 g 5594 2023 M
+63 -29 V
+stroke
+LT0
+.2797 g 5292 2336 M
+-48 32 V
+stroke
+LT0
+.2824 g 5181 2352 M
+63 16 V
+stroke
+LT0
+.2354 g 5450 2212 M
+-48 57 V
+stroke
+LT0
+.2555 g 5340 2296 M
+62 -27 V
+stroke
+LT0
+.1041 g 5863 1882 M
+-48 20 V
+stroke
+LT0
+.1074 g 5753 1899 M
+62 3 V
+stroke
+LT1
+.0214 g 2807 1659 M
+-48 38 V
+stroke
+LT1
+.0351 g 2730 1726 M
+29 -29 V
+stroke
+LT1
+.0503 g 2713 1743 M
+15 -16 V
+stroke
+LT0
+.1594 g 1827 2034 M
+-48 -14 V
+stroke
+LT0
+.1637 g 1841 2088 M
+-62 -68 V
+stroke
+LT0
+.2769 g 2139 2334 M
+-48 3 V
+stroke
+LT0
+.2638 g 2029 2288 M
+62 49 V
+stroke
+LT0
+.1873 g 1889 2107 M
+-48 -19 V
+stroke
+LT0
+.1912 g 1904 2159 M
+-63 -71 V
+stroke
+LT0
+.217 g 4268 2256 M
+48 -153 V
+stroke
+LT0
+.2255 g 4253 2253 M
+63 -150 V
+stroke
+LT0
+.2502 g 2360 2242 M
+-48 63 V
+stroke
+LT0
+.2693 g 2250 2321 M
+62 -16 V
+stroke
+LT0
+.1164 g 5753 1899 M
+-48 43 V
+stroke
+LT0
+.1312 g 5642 1962 M
+63 -20 V
+stroke
+LT0
+.1904 g 4979 2121 M
+-48 -44 V
+stroke
+LT0
+.1933 g 4994 2169 M
+-63 -92 V
+stroke
+LT0
+.2158 g 1952 2179 M
+-48 -20 V
+stroke
+LT0
+.2188 g 1966 2227 M
+-62 -68 V
+stroke
+LT0
+.2158 g 5498 2151 M
+-48 61 V
+stroke
+LT0
+.2388 g 5388 2246 M
+62 -34 V
+stroke
+LT0
+.1807 g 3120 2103 M
+-48 -71 V
+stroke
+LT0
+.2041 g 3134 2231 M
+-62 -199 V
+stroke
+LT0
+.2629 g 2077 2297 M
+-48 -9 V
+stroke
+LT0
+.2438 g 1966 2227 M
+63 61 V
+stroke
+LT0
+.2419 g 2014 2244 M
+-48 -17 V
+stroke
+LT0
+.226 g 2408 2170 M
+-48 72 V
+stroke
+LT0
+.2517 g 2298 2275 M
+62 -33 V
+stroke
+LT0
+.1455 g 4301 2067 M
+48 -168 V
+stroke
+LT0
+.1326 g 4287 1980 M
+62 -81 V
+stroke
+LT0
+.283 g 5229 2334 M
+-48 18 V
+stroke
+LT0
+.2759 g 5119 2311 M
+62 41 V
+stroke
+LT0
+.1942 g 5546 2087 M
+-48 64 V
+stroke
+LT0
+.2188 g 5436 2188 M
+62 -37 V
+stroke
+LT0
+.1983 g 2456 2093 M
+-48 77 V
+stroke
+LT0
+.2292 g 2346 2218 M
+62 -48 V
+stroke
+LT0
+.1262 g 3105 1941 M
+-48 -31 V
+stroke
+LT0
+.1585 g 3120 2103 M
+-63 -193 V
+stroke
+LT0
+.2804 g 2250 2321 M
+-48 33 V
+stroke
+LT0
+.2825 g 2139 2334 M
+63 20 V
+stroke
+LT0
+.2716 g 5340 2296 M
+-48 40 V
+stroke
+LT0
+.2803 g 5229 2334 M
+63 2 V
+stroke
+LT1
+.0143 g 2855 1628 M
+-48 31 V
+stroke
+LT1
+.0352 g 2744 1715 M
+63 -56 V
+stroke
+LT0
+.226 g 5042 2200 M
+-48 -31 V
+stroke
+LT0
+.2292 g 5056 2249 M
+-62 -80 V
+stroke
+LT0
+.1728 g 2493 2034 M
+-37 59 V
+stroke
+LT0
+.2037 g 2394 2154 M
+62 -61 V
+stroke
+LT0
+.185 g 2442 2087 M
+40 -47 V
+stroke
+LT0
+.1214 g 3105 1941 M
+-29 -78 V
+stroke
+LT1
+.0603 g 4714 1774 M
+-48 -57 V
+stroke
+LT1
+.0531 g 4729 1782 M
+-63 -65 V
+stroke
+LT1
+.0311 g 4604 1665 M
+62 52 V
+stroke
+LT0
+.1075 g 5801 1866 M
+-48 33 V
+stroke
+LT0
+.1168 g 5690 1908 M
+63 -9 V
+stroke
+LT1
+.087 g 4777 1845 M
+-48 -63 V
+stroke
+LT1
+.0777 g 4777 1841 M
+-48 -59 V
+stroke
+LT0
+.1067 g 5911 1872 M
+-48 10 V
+stroke
+LT0
+.1042 g 5801 1866 M
+62 16 V
+stroke
+LT0
+.1719 g 5594 2023 M
+-48 64 V
+stroke
+LT0
+.1965 g 5484 2124 M
+62 -37 V
+stroke
+LT0
+.2746 g 5167 2310 M
+-48 1 V
+stroke
+LT0
+.2577 g 5056 2249 M
+63 62 V
+stroke
+LT0
+.255 g 5104 2264 M
+-48 -15 V
+stroke
+LT1
+.0394 g 4652 1713 M
+-48 -48 V
+stroke
+LT1
+.017 g 4556 1635 M
+45 28 V
+stroke
+LT1
+.1186 g 4839 1923 M
+-48 -64 V
+stroke
+LT1
+.0924 g 2648 1812 M
+-48 60 V
+stroke
+LT1
+.1234 g 2549 1940 M
+51 -68 V
+stroke
+LT0
+.1505 g 5642 1962 M
+-48 61 V
+stroke
+LT0
+.1734 g 5532 2056 M
+62 -33 V
+stroke
+LT0
+.3759 g 3259 2666 M
+-95 -315 V
+stroke
+LT0
+.3026 g 4205 2442 M
+63 -186 V
+stroke
+LT0
+.3421 g 4157 2616 M
+111 -360 V
+stroke
+LT0
+.2589 g 5388 2246 M
+-48 50 V
+stroke
+LT0
+.2732 g 5277 2306 M
+63 -10 V
+stroke
+LT0
+.2827 g 2187 2318 M
+-48 16 V
+stroke
+LT0
+.276 g 2077 2297 M
+62 37 V
+stroke
+LT1
+.0243 g 4589 1661 M
+-48 -36 V
+stroke
+LT1
+.0088 g 4524 1617 M
+17 8 V
+stroke
+LT0
+.1309 g 4287 1980 M
+33 -117 V
+stroke
+LT0
+.1124 g 4272 1857 M
+2 -2 V
+stroke
+LT0
+.2708 g 2298 2275 M
+-48 46 V
+stroke
+LT0
+.2806 g 2187 2318 M
+63 3 V
+stroke
+LT1
+.0739 g 2696 1759 M
+-48 53 V
+stroke
+LT1
+.1074 g 2586 1895 M
+62 -83 V
+stroke
+LT1
+.0102 g 2903 1602 M
+-48 26 V
+stroke
+LT1
+.0284 g 2792 1678 M
+63 -50 V
+stroke
+LT0
+.1316 g 5690 1908 M
+-48 54 V
+stroke
+LT0
+.1512 g 5580 1989 M
+62 -27 V
+stroke
+LT0
+.1776 g 1875 2050 M
+-48 -16 V
+stroke
+LT0
+.183 g 1889 2107 M
+-62 -73 V
+stroke
+LT0
+.2819 g 5277 2306 M
+-48 28 V
+stroke
+LT0
+.2817 g 5167 2310 M
+62 24 V
+stroke
+LT0
+.1042 g 5849 1845 M
+-48 21 V
+stroke
+LT0
+.1075 g 5738 1863 M
+63 3 V
+stroke
+LT0
+.2073 g 1937 2124 M
+-48 -17 V
+stroke
+LT0
+.2119 g 1952 2179 M
+-63 -72 V
+stroke
+LT0
+.2753 g 2125 2295 M
+-48 2 V
+stroke
+LT0
+.261 g 2014 2244 M
+63 53 V
+stroke
+LT0
+.2419 g 5436 2188 M
+-48 58 V
+stroke
+LT0
+.261 g 5325 2267 M
+63 -21 V
+stroke
+LT0
+.1925 g 4964 2085 M
+-37 -41 V
+stroke
+LT0
+.1904 g 4979 2121 M
+-57 -79 V
+stroke
+LT0
+.2255 g 4253 2253 M
+48 -186 V
+stroke
+LT0
+.217 g 4239 2183 M
+62 -116 V
+stroke
+LT0
+.2354 g 2000 2194 M
+-48 -15 V
+stroke
+LT0
+.2388 g 2014 2244 M
+-62 -65 V
+stroke
+LT0
+.2589 g 2062 2253 M
+-48 -9 V
+stroke
+LT1
+.061 g 2733 1725 M
+-37 34 V
+stroke
+LT1
+.0908 g 2634 1841 M
+62 -82 V
+stroke
+LT0
+.1168 g 5738 1863 M
+-48 45 V
+stroke
+LT0
+.1316 g 5628 1925 M
+62 -17 V
+stroke
+LT0
+.255 g 2346 2218 M
+-48 57 V
+stroke
+LT0
+.2719 g 2235 2289 M
+63 -14 V
+stroke
+LT0
+.1067 g 5849 1845 M
+62 27 V
+stroke
+LT0
+.1126 g 4272 1857 M
+1 -2 V
+stroke
+LT0
+.1343 g 3153 1955 M
+-34 -98 V
+stroke
+LT0
+.2212 g 5484 2124 M
+-48 64 V
+stroke
+LT0
+.2438 g 5373 2217 M
+63 -29 V
+stroke
+LT0
+.2817 g 5215 2298 M
+-48 12 V
+stroke
+LT0
+.2719 g 5104 2264 M
+63 46 V
+stroke
+LT0
+.222 g 5027 2159 M
+-48 -38 V
+stroke
+LT0
+.2231 g 5042 2200 M
+-63 -79 V
+stroke
+LT1
+.0084 g 2951 1580 M
+-48 22 V
+stroke
+LT1
+.0246 g 2840 1648 M
+63 -46 V
+stroke
+LT0
+.2817 g 2235 2289 M
+-48 29 V
+stroke
+LT0
+.2819 g 2125 2295 M
+62 23 V
+stroke
+LT0
+.2346 g 2394 2154 M
+-48 64 V
+stroke
+LT0
+.2577 g 2283 2249 M
+63 -31 V
+stroke
+LT0
+.2824 g 3182 2334 M
+-48 -103 V
+stroke
+LT0
+.3026 g 3197 2449 M
+-63 -218 V
+stroke
+LT0
+.1484 g 3153 1955 M
+-48 -14 V
+stroke
+LT0
+.1911 g 3168 2158 M
+-63 -217 V
+stroke
+LT0
+.2753 g 5325 2267 M
+-48 39 V
+stroke
+LT0
+.2819 g 5215 2298 M
+62 8 V
+stroke
+LT0
+.2502 g 5090 2222 M
+-48 -22 V
+stroke
+LT0
+.2517 g 5104 2264 M
+-62 -64 V
+stroke
+LT0
+.198 g 5532 2056 M
+-48 68 V
+stroke
+LT0
+.2226 g 5421 2157 M
+63 -33 V
+stroke
+LT0
+.2708 g 5152 2269 M
+-48 -5 V
+stroke
+LT1
+.0494 g 2792 1678 M
+-48 37 V
+stroke
+LT1
+.0793 g 2682 1795 M
+59 -77 V
+stroke
+LT0
+.1074 g 5786 1830 M
+-48 33 V
+stroke
+LT0
+.1164 g 5676 1870 M
+62 -7 V
+stroke
+LT0
+.1041 g 5786 1830 M
+63 15 V
+stroke
+LT0
+.2115 g 2442 2087 M
+-48 67 V
+stroke
+LT0
+.2394 g 2331 2201 M
+63 -47 V
+stroke
+LT0
+.2234 g 3168 2158 M
+-48 -55 V
+stroke
+LT0
+.259 g 3182 2334 M
+-62 -231 V
+stroke
+LT0
+.1741 g 5580 1989 M
+-48 67 V
+stroke
+LT0
+.1988 g 5469 2090 M
+63 -34 V
+stroke
+LT0
+.2041 g 4239 2183 M
+48 -203 V
+stroke
+LT0
+.1807 g 4224 2056 M
+63 -76 V
+stroke
+LT0
+.1941 g 2464 2056 M
+-22 31 V
+stroke
+LT0
+.187 g 2469 2048 M
+-5 7 V
+stroke
+LT0
+.2188 g 2379 2146 M
+63 -59 V
+stroke
+LT0
+.1512 g 5628 1925 M
+-48 64 V
+stroke
+LT0
+.1741 g 5517 2020 M
+63 -31 V
+stroke
+LT0
+.2819 g 2173 2282 M
+-48 13 V
+stroke
+LT0
+.2732 g 2062 2253 M
+63 42 V
+stroke
+LT1
+.105 g 4762 1845 M
+-45 -67 V
+stroke
+LT1
+.0966 g 4777 1845 M
+-53 -60 V
+stroke
+LT1
+.0686 g 4652 1713 M
+62 61 V
+stroke
+LT1
+.0798 g 4700 1781 M
+-48 -68 V
+stroke
+LT1
+.0479 g 4589 1661 M
+63 52 V
+stroke
+LT0
+.1957 g 1923 2064 M
+-48 -14 V
+stroke
+LT0
+.2019 g 1937 2124 M
+-62 -74 V
+stroke
+LT0
+.1585 g 4224 2056 M
+48 -199 V
+stroke
+LT0
+.1262 g 4210 1893 M
+62 -36 V
+stroke
+LT0
+.2629 g 5373 2217 M
+-48 50 V
+stroke
+LT0
+.276 g 5263 2273 M
+62 -6 V
+stroke
+LT1
+.1315 g 4825 1915 M
+-48 -70 V
+stroke
+LT1
+.1243 g 4839 1923 M
+-62 -78 V
+stroke
+LT0
+.2746 g 2283 2249 M
+-48 40 V
+stroke
+LT0
+.2817 g 2173 2282 M
+62 7 V
+stroke
+LT0
+.1407 g 3201 1947 M
+-33 -98 V
+stroke
+LT0
+.1312 g 5676 1870 M
+-48 55 V
+stroke
+LT0
+.1505 g 5565 1950 M
+63 -25 V
+stroke
+LT1
+.0605 g 4637 1725 M
+-48 -64 V
+stroke
+LT1
+.0323 g 4527 1620 M
+62 41 V
+stroke
+LT1
+.0428 g 2840 1648 M
+-48 30 V
+stroke
+LT1
+.0693 g 2730 1756 M
+62 -78 V
+stroke
+LT0
+.2258 g 1985 2138 M
+-48 -14 V
+stroke
+LT0
+.2308 g 2000 2194 M
+-63 -70 V
+stroke
+LT0
+.1293 g 4210 1893 M
+12 -45 V
+stroke
+LT1
+.0084 g 2999 1561 M
+-48 19 V
+stroke
+LT1
+.0234 g 2888 1624 M
+63 -44 V
+stroke
+LT0
+.2827 g 5263 2273 M
+-48 25 V
+stroke
+LT0
+.2806 g 5152 2269 M
+63 29 V
+stroke
+LT0
+.2716 g 2110 2252 M
+-48 1 V
+stroke
+LT0
+.2555 g 2000 2194 M
+62 59 V
+stroke
+LT0
+.1069 g 5724 1825 M
+62 5 V
+stroke
+LT1
+.1427 g 4845 1930 M
+-6 -7 V
+stroke
+LT1
+.1422 g 4846 1930 M
+-7 -7 V
+stroke
+LT0
+.2521 g 2048 2203 M
+-48 -9 V
+stroke
+LT0
+.3111 g 4205 2442 M
+48 -189 V
+stroke
+LT0
+.3111 g 4191 2406 M
+62 -153 V
+stroke
+LT1
+.0457 g 4575 1678 M
+-48 -58 V
+stroke
+LT1
+.0214 g 4464 1587 M
+63 33 V
+stroke
+LT0
+.2453 g 5421 2157 M
+-48 60 V
+stroke
+LT0
+.2638 g 5311 2234 M
+62 -17 V
+stroke
+LT0
+.1159 g 5724 1825 M
+-48 45 V
+stroke
+LT0
+.1301 g 5613 1885 M
+63 -15 V
+stroke
+LT0
+.2004 g 4964 2085 M
+-24 -32 V
+stroke
+LT1
+.1243 g 2634 1841 M
+-48 54 V
+stroke
+LT1
+.1458 g 2554 1938 M
+32 -43 V
+stroke
+LT0
+.2804 g 5200 2261 M
+-48 8 V
+stroke
+LT0
+.2693 g 5090 2222 M
+62 47 V
+stroke
+LT0
+.2625 g 2331 2201 M
+-48 48 V
+stroke
+LT0
+.2759 g 2221 2258 M
+62 -9 V
+stroke
+LT0
+.2236 g 5012 2127 M
+-46 -41 V
+stroke
+LT0
+.2222 g 5027 2159 M
+-62 -73 V
+stroke
+LT0
+.1603 g 3201 1947 M
+-48 8 V
+stroke
+LT0
+.2126 g 3216 2187 M
+-63 -232 V
+stroke
+LT0
+.2234 g 5469 2090 M
+-48 67 V
+stroke
+LT0
+.2459 g 5359 2183 M
+62 -26 V
+stroke
+LT0
+.1406 g 3249 1914 M
+-25 -72 V
+stroke
+LT1
+.0352 g 4512 1638 M
+-48 -51 V
+stroke
+LT1
+.0143 g 4402 1561 M
+62 26 V
+stroke
+LT1
+.0396 g 2888 1624 M
+-48 24 V
+stroke
+LT1
+.064 g 2778 1724 M
+62 -76 V
+stroke
+LT0
+.283 g 2221 2258 M
+-48 24 V
+stroke
+LT0
+.2803 g 2110 2252 M
+63 30 V
+stroke
+LT0
+.2688 g 5138 2231 M
+-48 -9 V
+stroke
+LT0
+.2491 g 5027 2159 M
+63 63 V
+stroke
+LT0
+.2491 g 5075 2186 M
+-48 -27 V
+stroke
+LT0
+.2769 g 5311 2234 M
+-48 39 V
+stroke
+LT0
+.2825 g 5200 2261 M
+63 12 V
+stroke
+LT1
+.1093 g 2682 1795 M
+-48 46 V
+stroke
+LT1
+.1423 g 2571 1929 M
+63 -88 V
+stroke
+LT0
+.1988 g 5517 2020 M
+-48 70 V
+stroke
+LT0
+.2234 g 5407 2121 M
+62 -31 V
+stroke
+LT0
+.1147 g 5661 1829 M
+63 -4 V
+stroke
+LT1
+.0097 g 3031 1551 M
+-32 10 V
+stroke
+LT1
+.0246 g 2936 1607 M
+63 -46 V
+stroke
+LT0
+.1407 g 4147 1912 M
+19 -73 V
+stroke
+LT0
+.2467 g 2379 2146 M
+-48 55 V
+stroke
+LT0
+.2657 g 2269 2225 M
+62 -24 V
+stroke
+LT0
+.1734 g 5565 1950 M
+-48 70 V
+stroke
+LT0
+.198 g 5455 2051 M
+62 -31 V
+stroke
+LT0
+.2797 g 2158 2243 M
+-48 9 V
+stroke
+LT0
+.2682 g 2048 2203 M
+62 49 V
+stroke
+LT0
+.1494 g 5613 1885 M
+-48 65 V
+stroke
+LT0
+.1719 g 5503 1978 M
+62 -28 V
+stroke
+LT0
+.2127 g 1971 2075 M
+-48 -11 V
+stroke
+LT0
+.2195 g 1985 2138 M
+-62 -74 V
+stroke
+LT1
+.0284 g 4450 1606 M
+-48 -45 V
+stroke
+LT1
+.0102 g 4339 1540 M
+63 21 V
+stroke
+LT0
+.3026 g 4191 2406 M
+48 -223 V
+stroke
+LT0
+.2824 g 4176 2291 M
+63 -108 V
+stroke
+LT0
+.1911 g 4162 2115 M
+48 -222 V
+stroke
+LT0
+.1484 g 4147 1912 M
+63 -19 V
+stroke
+LT0
+.1345 g 3297 1859 M
+-8 -22 V
+stroke
+LT1
+.098 g 2730 1756 M
+-48 39 V
+stroke
+LT1
+.1296 g 2619 1884 M
+63 -89 V
+stroke
+LT0
+.242 g 2033 2147 M
+-48 -9 V
+stroke
+LT0
+.2471 g 2048 2203 M
+-63 -65 V
+stroke
+LT0
+.2653 g 2096 2204 M
+-48 -1 V
+stroke
+LT0
+.2289 g 2427 2090 M
+-48 56 V
+stroke
+LT0
+.2522 g 2317 2186 M
+62 -40 V
+stroke
+LT0
+.3938 g 3245 2583 M
+-48 -134 V
+stroke
+LT0
+.4062 g 3259 2666 M
+-62 -217 V
+stroke
+LT0
+.2553 g 3216 2187 M
+-48 -29 V
+stroke
+LT0
+.3038 g 3230 2413 M
+-62 -255 V
+stroke
+LT0
+.1289 g 5661 1829 M
+-48 56 V
+stroke
+LT0
+.1474 g 5551 1906 M
+62 -21 V
+stroke
+LT0
+.2645 g 5359 2183 M
+-48 51 V
+stroke
+LT0
+.2771 g 5248 2237 M
+63 -3 V
+stroke
+LT0
+.259 g 4176 2291 M
+48 -235 V
+stroke
+LT0
+.2234 g 4162 2115 M
+62 -59 V
+stroke
+LT1
+.0396 g 2936 1607 M
+-48 17 V
+stroke
+LT1
+.0623 g 2826 1700 M
+62 -76 V
+stroke
+LT0
+.2791 g 2269 2225 M
+-48 33 V
+stroke
+LT0
+.2824 g 2158 2243 M
+63 15 V
+stroke
+LT0
+.2827 g 5248 2237 M
+-48 24 V
+stroke
+LT0
+.28 g 5138 2231 M
+62 30 V
+stroke
+LT0
+.1603 g 3249 1914 M
+-48 33 V
+stroke
+LT0
+.2201 g 3264 2184 M
+-63 -237 V
+stroke
+LT0
+.3938 g 4157 2616 M
+48 -174 V
+stroke
+LT0
+.4062 g 4143 2628 M
+62 -186 V
+stroke
+LT0
+.1467 g 4084 1908 M
+19 -73 V
+stroke
+LT0
+.2151 g 2450 2063 M
+-23 27 V
+stroke
+LT0
+.2329 g 2379 2130 M
+48 -40 V
+stroke
+LT1
+.0246 g 4387 1581 M
+-48 -41 V
+stroke
+LT1
+.0084 g 4276 1522 M
+63 18 V
+stroke
+LT0
+.1268 g 5599 1840 M
+62 -11 V
+stroke
+LT0
+.3394 g 3230 2413 M
+-48 -79 V
+stroke
+LT0
+.3736 g 3245 2583 M
+-63 -249 V
+stroke
+LT1
+.0386 g 2984 1595 M
+25 -19 V
+stroke
+LT0
+.2459 g 5407 2121 M
+-48 62 V
+stroke
+LT0
+.2645 g 5296 2198 M
+63 -15 V
+stroke
+LT1
+.1278 g 4748 1859 M
+-48 -78 V
+stroke
+LT1
+.1149 g 4762 1845 M
+-62 -64 V
+stroke
+LT1
+.0924 g 4637 1725 M
+63 56 V
+stroke
+LT1
+.1514 g 4810 1919 M
+-48 -74 V
+stroke
+LT1
+.1409 g 4825 1915 M
+-63 -70 V
+stroke
+LT1
+.0905 g 2778 1724 M
+-48 32 V
+stroke
+LT1
+.1204 g 2667 1846 M
+63 -90 V
+stroke
+LT1
+.1592 g 4835 1928 M
+-10 -13 V
+stroke
+LT1
+.1074 g 4685 1804 M
+-48 -79 V
+stroke
+LT1
+.0739 g 4575 1678 M
+62 47 V
+stroke
+LT0
+.28 g 5186 2225 M
+-48 6 V
+stroke
+LT0
+.2688 g 5075 2186 M
+63 45 V
+stroke
+LT0
+.2226 g 5455 2051 M
+-48 70 V
+stroke
+LT0
+.2453 g 5344 2144 M
+63 -23 V
+stroke
+LT0
+.2832 g 2206 2225 M
+-48 18 V
+stroke
+LT0
+.2767 g 2096 2204 M
+62 39 V
+stroke
+LT1
+.0908 g 4623 1755 M
+-48 -77 V
+stroke
+LT1
+.0596 g 4512 1638 M
+63 40 V
+stroke
+LT0
+.2712 g 2317 2186 M
+-48 39 V
+stroke
+LT0
+.2799 g 2206 2225 M
+63 0 V
+stroke
+LT0
+.2693 g 5123 2197 M
+-48 -11 V
+stroke
+LT0
+.2502 g 5012 2127 M
+63 59 V
+stroke
+LT0
+.2211 g 4981 2093 M
+-22 -24 V
+stroke
+LT0
+.2332 g 5012 2127 M
+-28 -31 V
+stroke
+LT0
+.1456 g 4022 1880 M
+13 -51 V
+stroke
+LT0
+.1484 g 3297 1859 M
+-48 55 V
+stroke
+LT0
+.2126 g 3312 2146 M
+-63 -232 V
+stroke
+LT0
+.2517 g 5060 2155 M
+-48 -28 V
+stroke
+LT0
+.1965 g 5503 1978 M
+-48 73 V
+stroke
+LT0
+.2212 g 5392 2079 M
+63 -28 V
+stroke
+LT0
+.2771 g 5296 2198 M
+-48 39 V
+stroke
+LT0
+.2827 g 5186 2225 M
+62 12 V
+stroke
+LT0
+.2126 g 4099 2149 M
+48 -237 V
+stroke
+LT0
+.1603 g 4084 1908 M
+63 4 V
+stroke
+LT1
+.0234 g 4324 1562 M
+-48 -40 V
+stroke
+LT1
+.0084 g 4214 1508 M
+62 14 V
+stroke
+LT1
+.0428 g 2984 1595 M
+-48 12 V
+stroke
+LT1
+.064 g 2874 1683 M
+62 -76 V
+stroke
+LT0
+.1699 g 5551 1906 M
+-48 72 V
+stroke
+LT0
+.1942 g 5440 2005 M
+63 -27 V
+stroke
+LT0
+.2281 g 2019 2083 M
+-48 -8 V
+stroke
+LT0
+.2352 g 2033 2147 M
+-62 -72 V
+stroke
+LT0
+.2748 g 2144 2199 M
+-48 5 V
+stroke
+LT0
+.2602 g 2033 2147 M
+63 57 V
+stroke
+LT1
+.0781 g 4560 1713 M
+-48 -75 V
+stroke
+LT1
+.0494 g 4450 1606 M
+62 32 V
+stroke
+LT0
+.1453 g 5599 1840 M
+-48 66 V
+stroke
+LT0
+.1669 g 5488 1930 M
+63 -24 V
+stroke
+LT0
+.2554 g 2081 2149 M
+-48 -2 V
+stroke
+LT1
+.0868 g 2826 1700 M
+-48 24 V
+stroke
+LT1
+.1148 g 2715 1815 M
+63 -91 V
+stroke
+LT0
+.1383 g 3959 1830 M
+2 -6 V
+stroke
+LT0
+.1351 g 3313 1835 M
+-16 24 V
+stroke
+LT0
+.1911 g 3360 2076 M
+-63 -217 V
+stroke
+LT0
+.2604 g 2365 2142 M
+-48 44 V
+stroke
+LT0
+.2739 g 2254 2200 M
+63 -14 V
+stroke
+LT0
+.169 g 3408 1980 M
+-49 -149 V
+stroke
+LT0
+.1473 g 3456 1868 M
+-17 -43 V
+stroke
+LT0
+.142 g 5536 1857 M
+63 -17 V
+stroke
+LT0
+.2723 g 3264 2184 M
+-48 3 V
+stroke
+LT0
+.333 g 3278 2457 M
+-62 -270 V
+stroke
+LT1
+.1626 g 2619 1884 M
+-48 45 V
+stroke
+LT0
+.2638 g 5344 2144 M
+-48 54 V
+stroke
+LT0
+.2769 g 5234 2200 M
+62 -2 V
+stroke
+LT0
+.4927 g 4095 2832 M
+62 -216 V
+stroke
+LT1
+.0693 g 4498 1679 M
+-48 -73 V
+stroke
+LT1
+.0428 g 4387 1581 M
+63 25 V
+stroke
+LT0
+.2825 g 5234 2200 M
+-48 25 V
+stroke
+LT0
+.2804 g 5123 2197 M
+63 28 V
+stroke
+LT0
+.2827 g 2254 2200 M
+-48 25 V
+stroke
+LT0
+.2812 g 2144 2199 M
+62 26 V
+stroke
+LT1
+.0246 g 4262 1549 M
+-48 -41 V
+stroke
+LT1
+.0102 g 4151 1498 M
+63 10 V
+stroke
+LT0
+.4062 g 4143 2628 M
+48 -222 V
+stroke
+LT0
+.3938 g 4128 2545 M
+63 -139 V
+stroke
+LT0
+.3038 g 4114 2374 M
+48 -259 V
+stroke
+LT0
+.2553 g 4099 2149 M
+63 -34 V
+stroke
+LT0
+.2201 g 4036 2150 M
+48 -242 V
+stroke
+LT0
+.1603 g 4022 1880 M
+62 28 V
+stroke
+LT1
+.0087 g 4089 1492 M
+-48 -11 V
+stroke
+LT1
+.006 g 4151 1498 M
+-110 -17 V
+stroke
+LT1
+.0017 g 3978 1470 M
+63 11 V
+stroke
+LT0
+.2479 g 2413 2096 M
+-48 46 V
+stroke
+LT0
+.2654 g 2302 2169 M
+63 -27 V
+stroke
+LT0
+.2438 g 5392 2079 M
+-48 65 V
+stroke
+LT0
+.2629 g 5282 2158 M
+62 -14 V
+stroke
+LT1
+.0459 g 2993 1595 M
+-9 0 V
+stroke
+LT1
+.066 g 2930 1663 M
+54 -68 V
+stroke
+LT1
+.0868 g 2874 1683 M
+-48 17 V
+stroke
+LT1
+.113 g 2763 1791 M
+63 -91 V
+stroke
+LT1
+.152 g 2667 1846 M
+-48 38 V
+stroke
+LT1
+.1666 g 2594 1917 M
+25 -33 V
+stroke
+LT1
+.064 g 4435 1653 M
+-48 -72 V
+stroke
+LT1
+.0396 g 4324 1562 M
+63 19 V
+stroke
+LT0
+.505 g 3307 2829 M
+-48 -163 V
+stroke
+LT0
+.5584 g 3370 3053 M
+3259 2666 L
+stroke
+LT0
+.2806 g 5171 2189 M
+-48 8 V
+stroke
+LT0
+.2708 g 5060 2155 M
+63 42 V
+stroke
+LT0
+.2188 g 5440 2005 M
+-48 74 V
+stroke
+LT0
+.2419 g 5330 2100 M
+62 -21 V
+stroke
+LT0
+.2806 g 2192 2186 M
+-48 13 V
+stroke
+LT0
+.27 g 2081 2149 M
+63 50 V
+stroke
+LT0
+.3736 g 4128 2545 M
+48 -254 V
+stroke
+LT0
+.3394 g 4114 2374 M
+62 -83 V
+stroke
+LT0
+.1491 g 3786 1853 M
+11 -36 V
+stroke
+LT0
+.2126 g 3974 2117 M
+48 -237 V
+stroke
+LT0
+.1484 g 3959 1830 M
+63 50 V
+stroke
+LT0
+.1912 g 5488 1930 M
+-48 75 V
+stroke
+LT0
+.2158 g 5378 2030 M
+62 -25 V
+stroke
+LT0
+.1615 g 3566 1913 M
+-36 -93 V
+stroke
+LT0
+.1478 g 3456 1868 M
+18 -45 V
+stroke
+LT0
+.2413 g 2067 2086 M
+-48 -3 V
+stroke
+LT0
+.2483 g 2081 2149 M
+-62 -66 V
+stroke
+LT0
+.266 g 2129 2147 M
+-48 2 V
+stroke
+LT0
+.1637 g 5536 1857 M
+-48 73 V
+stroke
+LT0
+.1873 g 5426 1954 M
+62 -24 V
+stroke
+LT0
+.1383 g 3959 1830 M
+-5 -6 V
+stroke
+LT0
+.172 g 3849 1961 M
+34 -140 V
+stroke
+LT1
+.0284 g 4199 1543 M
+-48 -45 V
+stroke
+LT1
+.0143 g 4089 1492 M
+62 6 V
+stroke
+LT0
+.2523 g 2365 2126 M
+48 -30 V
+stroke
+LT0
+.2719 g 5108 2165 M
+-48 -10 V
+stroke
+LT0
+.255 g 4998 2103 M
+62 52 V
+stroke
+LT0
+.276 g 5282 2158 M
+-48 42 V
+stroke
+LT0
+.2827 g 5171 2189 M
+63 11 V
+stroke
+LT0
+.1911 g 3911 2052 M
+48 -222 V
+stroke
+LT0
+.279 g 2302 2169 M
+-48 31 V
+stroke
+LT0
+.2821 g 2192 2186 M
+62 14 V
+stroke
+LT0
+.1594 g 5474 1876 M
+62 -19 V
+stroke
+LT0
+.2577 g 5046 2129 M
+-48 -26 V
+stroke
+LT0
+.2414 g 4976 2083 M
+20 18 V
+stroke
+LT0
+.2349 g 4962 2070 M
+11 9 V
+stroke
+LT0
+.2323 g 4959 2066 M
+3 3 V
+stroke
+LT0
+.2723 g 3312 2146 M
+-48 38 V
+stroke
+LT0
+.3432 g 3326 2459 M
+-62 -275 V
+stroke
+LT0
+.3815 g 3278 2457 M
+-48 -44 V
+stroke
+LT0
+.4309 g 3293 2685 M
+-63 -272 V
+stroke
+LT1
+.0144 g 4026 1494 M
+-48 -24 V
+stroke
+LT1
+.0064 g 3916 1467 M
+62 3 V
+stroke
+LT1
+.1766 g 4810 1919 M
+6 5 V
+stroke
+LT1
+.1447 g 2715 1815 M
+-48 31 V
+stroke
+LT1
+.1636 g 2629 1899 M
+38 -53 V
+stroke
+LT1
+.1772 g 4814 1924 M
+-4 -5 V
+stroke
+LT1
+.1642 g 4748 1859 M
+62 60 V
+stroke
+LT1
+.0623 g 4372 1633 M
+-48 -71 V
+stroke
+LT1
+.0396 g 4262 1549 M
+62 13 V
+stroke
+LT1
+.1722 g 4786 1918 M
+-38 -59 V
+stroke
+LT1
+.1428 g 4685 1804 M
+63 55 V
+stroke
+LT0
+.1493 g 3786 1853 M
+-20 -36 V
+stroke
+LT0
+.1625 g 3677 1909 M
+25 -92 V
+stroke
+LT0
+.1623 g 3677 1909 M
+-40 -91 V
+stroke
+LT0
+.1621 g 3566 1913 M
+31 -95 V
+stroke
+LT0
+.2041 g 3518 2067 M
+-62 -199 V
+stroke
+LT0
+.1807 g 3408 1980 M
+48 -112 V
+stroke
+LT1
+.1583 g 4733 1883 M
+-48 -79 V
+stroke
+LT1
+.1243 g 4623 1755 M
+62 49 V
+stroke
+LT1
+.0904 g 2920 1674 M
+-46 9 V
+stroke
+LT1
+.1148 g 2811 1774 M
+63 -91 V
+stroke
+LT0
+.4651 g 3293 2685 M
+-48 -102 V
+stroke
+LT0
+.4927 g 3307 2829 M
+-62 -246 V
+stroke
+LT0
+.261 g 5330 2100 M
+-48 58 V
+stroke
+LT0
+.2753 g 5219 2161 M
+63 -3 V
+stroke
+LT1
+.1423 g 4671 1838 M
+-48 -83 V
+stroke
+LT1
+.1093 g 4560 1713 M
+63 42 V
+stroke
+LT1
+.0073 g 3916 1467 M
+-74 -6 V
+stroke
+LT0
+.333 g 4051 2424 M
+48 -275 V
+stroke
+LT0
+.2723 g 4036 2150 M
+63 -1 V
+stroke
+LT0
+.2833 g 2240 2168 M
+-48 18 V
+stroke
+LT0
+.2766 g 2129 2147 M
+63 39 V
+stroke
+LT0
+.2819 g 5219 2161 M
+-48 28 V
+stroke
+LT0
+.2819 g 5116 2167 M
+55 22 V
+stroke
+LT0
+.273 g 2350 2135 M
+-48 34 V
+stroke
+LT0
+.2802 g 2240 2168 M
+62 1 V
+stroke
+LT0
+.259 g 3470 2210 M
+-62 -230 V
+stroke
+LT0
+.2234 g 3360 2076 M
+48 -96 V
+stroke
+LT1
+.0352 g 4137 1543 M
+-48 -51 V
+stroke
+LT1
+.0214 g 4026 1494 M
+63 -2 V
+stroke
+LT0
+.2553 g 3360 2076 M
+-48 70 V
+stroke
+LT0
+.333 g 3374 2416 M
+-62 -270 V
+stroke
+LT1
+.1296 g 4608 1798 M
+-48 -85 V
+stroke
+LT1
+.098 g 4498 1679 M
+62 34 V
+stroke
+LT0
+.2388 g 5378 2030 M
+-48 70 V
+stroke
+LT0
+.2589 g 5267 2114 M
+63 -14 V
+stroke
+LT1
+.1411 g 2763 1791 M
+-48 24 V
+stroke
+LT1
+.1597 g 2673 1873 M
+42 -58 V
+stroke
+LT0
+.1807 g 3849 1961 M
+-63 -108 V
+stroke
+LT0
+.2041 g 3738 2057 M
+48 -204 V
+stroke
+LT1
+.064 g 4310 1621 M
+-48 -72 V
+stroke
+LT1
+.0428 g 4199 1543 M
+63 6 V
+stroke
+LT0
+.3038 g 3422 2330 M
+-62 -254 V
+stroke
+LT0
+.2737 g 2177 2138 M
+-48 9 V
+stroke
+LT0
+.2589 g 2067 2086 M
+62 61 V
+stroke
+LT1
+.0243 g 3964 1504 M
+-48 -37 V
+stroke
+LT1
+.0153 g 3858 1474 M
+58 -7 V
+stroke
+LT0
+.2523 g 2115 2084 M
+-48 2 V
+stroke
+LT0
+.2119 g 5426 1954 M
+-48 76 V
+stroke
+LT0
+.2354 g 5315 2050 M
+63 -20 V
+stroke
+LT0
+.183 g 5474 1876 M
+-48 78 V
+stroke
+LT0
+.2073 g 5363 1976 M
+63 -22 V
+stroke
+LT0
+.1776 g 5411 1896 M
+63 -20 V
+stroke
+LT0
+.2255 g 3629 2095 M
+-63 -182 V
+stroke
+LT0
+.217 g 3518 2067 M
+48 -154 V
+stroke
+LT0
+.2817 g 5156 2152 M
+-46 12 V
+stroke
+LT0
+.2746 g 5046 2129 M
+62 36 V
+stroke
+LT1
+.1204 g 4546 1765 M
+-48 -86 V
+stroke
+LT1
+.0905 g 4435 1653 M
+63 26 V
+stroke
+LT0
+.505 g 4095 2832 M
+48 -204 V
+stroke
+LT0
+.505 g 4080 2796 M
+63 -168 V
+stroke
+LT0
+.2658 g 2398 2100 M
+-48 35 V
+stroke
+LT0
+.2763 g 2288 2145 M
+62 -10 V
+stroke
+LT0
+.217 g 3738 2057 M
+-61 -148 V
+stroke
+LT0
+.2255 g 3629 2095 M
+48 -186 V
+stroke
+LT0
+.2732 g 5267 2114 M
+-48 47 V
+stroke
+LT0
+.2819 g 5156 2152 M
+63 9 V
+stroke
+LT0
+.3432 g 3988 2430 M
+48 -280 V
+stroke
+LT0
+.2723 g 3974 2117 M
+62 33 V
+stroke
+LT0
+.2234 g 3911 2052 M
+-62 -91 V
+stroke
+LT0
+.259 g 3801 2196 M
+48 -235 V
+stroke
+LT0
+.2834 g 2288 2145 M
+-48 23 V
+stroke
+LT0
+.2804 g 2177 2138 M
+63 30 V
+stroke
+LT0
+.2759 g 5094 2133 M
+-48 -4 V
+stroke
+LT0
+.2625 g 4983 2086 M
+63 43 V
+stroke
+LT1
+.0457 g 4074 1551 M
+-48 -57 V
+stroke
+LT1
+.0323 g 3964 1504 M
+62 -10 V
+stroke
+LT1
+.1411 g 2811 1774 M
+-48 17 V
+stroke
+LT1
+.1542 g 2730 1837 M
+33 -46 V
+stroke
+LT1
+.0693 g 4247 1616 M
+-48 -73 V
+stroke
+LT1
+.0494 g 4137 1543 M
+62 0 V
+stroke
+LT1
+.1148 g 4483 1738 M
+-48 -85 V
+stroke
+LT1
+.0868 g 4372 1633 M
+63 20 V
+stroke
+LT0
+.4309 g 4066 2652 M
+48 -278 V
+stroke
+LT0
+.3815 g 4051 2424 M
+63 -50 V
+stroke
+LT0
+.2657 g 5031 2106 M
+-48 -20 V
+stroke
+LT0
+.252 g 4963 2070 M
+16 12 V
+stroke
+LT0
+.2477 g 4949 2058 M
+13 11 V
+stroke
+LT0
+.4039 g 3326 2459 M
+-48 -2 V
+stroke
+LT0
+.468 g 3341 2745 M
+-63 -288 V
+stroke
+LT0
+.2553 g 3974 2117 M
+-63 -65 V
+stroke
+LT0
+.3038 g 3863 2311 M
+48 -259 V
+stroke
+LT0
+.2555 g 5315 2050 M
+-48 64 V
+stroke
+LT0
+.2716 g 5204 2118 M
+63 -4 V
+stroke
+LT0
+.333 g 3926 2392 M
+48 -275 V
+stroke
+LT0
+.2582 g 2446 2064 M
+-48 36 V
+stroke
+LT0
+.2712 g 2336 2120 M
+62 -20 V
+stroke
+LT0
+.2788 g 2225 2126 M
+-48 12 V
+stroke
+LT0
+.267 g 2115 2084 M
+62 54 V
+stroke
+LT0
+.4927 g 4080 2796 M
+48 -251 V
+stroke
+LT0
+.4651 g 4066 2652 M
+62 -107 V
+stroke
+LT0
+.261 g 2163 2079 M
+-48 5 V
+stroke
+LT0
+.2308 g 5363 1976 M
+-48 74 V
+stroke
+LT0
+.2521 g 5252 2064 M
+63 -14 V
+stroke
+LT0
+.2803 g 5204 2118 M
+-48 34 V
+stroke
+LT0
+.283 g 5094 2133 M
+62 19 V
+stroke
+LT0
+.3026 g 3581 2284 M
+-63 -217 V
+stroke
+LT0
+.2824 g 3470 2210 M
+48 -143 V
+stroke
+LT0
+.2019 g 5411 1896 M
+-48 80 V
+stroke
+LT0
+.2258 g 5300 1994 M
+63 -18 V
+stroke
+LT0
+.1957 g 5348 1915 M
+63 -19 V
+stroke
+LT1
+.113 g 4420 1719 M
+-48 -86 V
+stroke
+LT1
+.0868 g 4310 1621 M
+62 12 V
+stroke
+LT1
+.1896 g 4733 1883 M
+42 33 V
+stroke
+LT0
+.2817 g 2336 2120 M
+-48 25 V
+stroke
+LT0
+.2819 g 2225 2126 M
+63 19 V
+stroke
+LT1
+.1932 g 4753 1911 M
+-20 -28 V
+stroke
+LT1
+.1763 g 4671 1838 M
+62 45 V
+stroke
+LT1
+.0781 g 4185 1619 M
+-48 -76 V
+stroke
+LT1
+.0596 g 4074 1551 M
+63 -8 V
+stroke
+LT0
+.2824 g 3801 2196 M
+-63 -139 V
+stroke
+LT0
+.3026 g 3691 2280 M
+47 -223 V
+stroke
+LT1
+.0605 g 4012 1567 M
+-48 -63 V
+stroke
+LT1
+.0463 g 3913 1520 M
+51 -16 V
+stroke
+LT0
+.2521 g 2480 2041 M
+-34 23 V
+stroke
+LT0
+.2649 g 2389 2091 M
+57 -27 V
+stroke
+LT0
+.2824 g 5142 2113 M
+-48 20 V
+stroke
+LT0
+.2791 g 5031 2106 M
+63 27 V
+stroke
+LT1
+.1897 g 4712 1902 M
+-41 -64 V
+stroke
+LT1
+.1626 g 4608 1798 M
+63 40 V
+stroke
+LT0
+.3111 g 3691 2280 M
+-62 -185 V
+stroke
+LT0
+.3111 g 3581 2284 M
+48 -189 V
+stroke
+LT0
+.2682 g 5252 2064 M
+-48 54 V
+stroke
+LT0
+.2797 g 5142 2113 M
+62 5 V
+stroke
+LT0
+.5894 g 4047 2999 M
+48 -167 V
+stroke
+LT0
+.6053 g 4032 3025 M
+63 -193 V
+stroke
+LT0
+.2819 g 2273 2109 M
+-48 17 V
+stroke
+LT0
+.2728 g 2163 2079 M
+62 47 V
+stroke
+LT0
+.5894 g 3355 2955 M
+-48 -126 V
+stroke
+LT0
+.6053 g 3370 3053 M
+-63 -224 V
+stroke
+LT0
+.3736 g 3533 2459 M
+-63 -249 V
+stroke
+LT0
+.3394 g 3422 2330 M
+48 -120 V
+stroke
+LT1
+.1148 g 4358 1706 M
+-48 -85 V
+stroke
+LT1
+.0905 g 4247 1616 M
+63 5 V
+stroke
+LT0
+.5173 g 3341 2745 M
+-48 -60 V
+stroke
+LT0
+.5618 g 3355 2955 M
+-62 -270 V
+stroke
+LT0
+.4039 g 3374 2416 M
+-48 43 V
+stroke
+LT0
+.4808 g 3389 2752 M
+-63 -293 V
+stroke
+LT1
+.1817 g 4656 1876 M
+-48 -78 V
+stroke
+LT1
+.152 g 4546 1765 M
+62 33 V
+stroke
+LT0
+.2789 g 2384 2093 M
+-48 27 V
+stroke
+LT0
+.2817 g 2273 2109 M
+63 11 V
+stroke
+LT0
+.2677 g 2211 2069 M
+-48 10 V
+stroke
+LT0
+.2471 g 5300 1994 M
+-48 70 V
+stroke
+LT0
+.2653 g 5190 2070 M
+62 -6 V
+stroke
+LT0
+.2799 g 5079 2100 M
+-48 6 V
+stroke
+LT0
+.2712 g 4969 2071 M
+62 35 V
+stroke
+LT0
+.468 g 4003 2716 M
+48 -292 V
+stroke
+LT0
+.4039 g 3988 2430 M
+63 -6 V
+stroke
+LT0
+.2195 g 5348 1915 M
+-48 79 V
+stroke
+LT0
+.242 g 5238 2008 M
+62 -14 V
+stroke
+LT0
+.2127 g 5286 1931 M
+62 -16 V
+stroke
+LT1
+.1735 g 4594 1846 M
+-48 -81 V
+stroke
+LT1
+.1447 g 4483 1738 M
+63 27 V
+stroke
+LT1
+.0908 g 4122 1629 M
+-48 -78 V
+stroke
+LT1
+.0739 g 4012 1567 M
+62 -16 V
+stroke
+LT0
+.4309 g 3485 2603 M
+-63 -273 V
+stroke
+LT0
+.3815 g 3374 2416 M
+48 -86 V
+stroke
+LT0
+.468 g 3437 2703 M
+-63 -287 V
+stroke
+LT0
+.3394 g 3863 2311 M
+-62 -115 V
+stroke
+LT0
+.3736 g 3753 2450 M
+48 -254 V
+stroke
+LT0
+.2767 g 5190 2070 M
+-48 43 V
+stroke
+LT0
+.2832 g 5079 2100 M
+63 13 V
+stroke
+LT0
+.2739 g 5017 2080 M
+-48 -9 V
+stroke
+LT0
+.2616 g 4919 2040 M
+50 31 V
+stroke
+LT1
+.1204 g 4295 1701 M
+-48 -85 V
+stroke
+LT1
+.098 g 4185 1619 M
+62 -3 V
+stroke
+LT0
+.2834 g 2321 2090 M
+-48 19 V
+stroke
+LT0
+.2767 g 2211 2069 M
+62 40 V
+stroke
+LT0
+.2757 g 2432 2066 M
+-48 27 V
+stroke
+LT0
+.2806 g 2321 2090 M
+63 3 V
+stroke
+LT1
+.1685 g 4531 1821 M
+-48 -83 V
+stroke
+LT1
+.1411 g 4420 1719 M
+63 19 V
+stroke
+LT0
+.7027 g 3984 3211 M
+44 -148 V
+stroke
+LT0
+.2602 g 5238 2008 M
+-48 62 V
+stroke
+LT0
+.2748 g 5127 2069 M
+63 1 V
+stroke
+LT0
+.2725 g 2259 2056 M
+-48 13 V
+stroke
+LT0
+.4808 g 3940 2728 M
+48 -298 V
+stroke
+LT0
+.4039 g 3926 2392 M
+62 38 V
+stroke
+LT0
+.4062 g 3643 2503 M
+-62 -219 V
+stroke
+LT0
+.3938 g 3533 2459 M
+48 -175 V
+stroke
+LT0
+.2812 g 5127 2069 M
+-48 31 V
+stroke
+LT0
+.2827 g 5017 2080 M
+62 20 V
+stroke
+LT0
+.3815 g 3926 2392 M
+-63 -81 V
+stroke
+LT0
+.4309 g 3815 2588 M
+48 -277 V
+stroke
+LT0
+.6053 g 4032 3025 M
+48 -229 V
+stroke
+LT0
+.5894 g 4018 2926 M
+62 -130 V
+stroke
+LT0
+.5618 g 4018 2926 M
+48 -274 V
+stroke
+LT0
+.5173 g 4003 2716 M
+63 -64 V
+stroke
+LT0
+.2352 g 5286 1931 M
+-48 77 V
+stroke
+LT0
+.2554 g 5175 2015 M
+63 -7 V
+stroke
+LT0
+.3938 g 3753 2450 M
+-62 -170 V
+stroke
+LT0
+.4062 g 3643 2503 M
+48 -223 V
+stroke
+LT0
+.2281 g 5223 1944 M
+63 -13 V
+stroke
+LT0
+.468 g 3878 2684 M
+48 -292 V
+stroke
+LT1
+.1668 g 4468 1802 M
+-48 -83 V
+stroke
+LT1
+.1411 g 4358 1706 M
+62 13 V
+stroke
+LT1
+.1001 g 4046 1623 M
+-34 -56 V
+stroke
+LT1
+.0864 g 3985 1578 M
+27 -11 V
+stroke
+LT0
+.279 g 2369 2070 M
+63 -4 V
+stroke
+LT1
+.1296 g 4233 1703 M
+-48 -84 V
+stroke
+LT1
+.1093 g 4122 1629 M
+63 -10 V
+stroke
+LT0
+.2838 g 2369 2070 M
+-48 20 V
+stroke
+LT0
+.2792 g 2259 2056 M
+62 34 V
+stroke
+LT0
+.2821 g 5065 2062 M
+-48 18 V
+stroke
+LT0
+.279 g 4954 2054 M
+63 26 V
+stroke
+LT1
+.21 g 4656 1876 M
+38 21 V
+stroke
+LT0
+.5449 g 3389 2752 M
+-48 -7 V
+stroke
+LT0
+.6064 g 3403 3028 M
+-62 -283 V
+stroke
+LT0
+.27 g 5175 2015 M
+-48 54 V
+stroke
+LT0
+.2806 g 5065 2062 M
+62 7 V
+stroke
+LT0
+.2758 g 2307 2041 M
+-48 15 V
+stroke
+LT0
+.701 g 3418 3198 M
+-48 -145 V
+stroke
+LT0
+.7472 g 3480 3394 M
+3370 3053 L
+stroke
+LT1
+.2121 g 4668 1891 M
+-12 -15 V
+stroke
+LT1
+.2033 g 4594 1846 M
+62 30 V
+stroke
+LT1
+.1685 g 4406 1789 M
+-48 -83 V
+stroke
+LT1
+.1447 g 4295 1701 M
+63 5 V
+stroke
+LT0
+.2483 g 5223 1944 M
+-48 71 V
+stroke
+LT0
+.266 g 5113 2017 M
+62 -2 V
+stroke
+LT0
+.2802 g 5002 2048 M
+-48 6 V
+stroke
+LT0
+.273 g 4892 2025 M
+62 29 V
+stroke
+LT0
+.2705 g 2528 2017 M
+-48 24 V
+stroke
+LT0
+.2775 g 2417 2049 M
+63 -8 V
+stroke
+LT0
+.2413 g 5161 1952 M
+62 -8 V
+stroke
+LT0
+.4927 g 3595 2706 M
+-62 -247 V
+stroke
+LT0
+.4651 g 3485 2603 M
+48 -144 V
+stroke
+LT0
+.2837 g 2417 2049 M
+-48 21 V
+stroke
+LT0
+.2805 g 2307 2041 M
+62 29 V
+stroke
+LT1
+.1392 g 4164 1701 M
+-42 -72 V
+stroke
+LT1
+.1226 g 4073 1642 M
+49 -13 V
+stroke
+LT1
+.2105 g 4618 1878 M
+-24 -32 V
+stroke
+LT1
+.1973 g 4531 1821 M
+63 25 V
+stroke
+LT0
+.2766 g 5113 2017 M
+-48 45 V
+stroke
+LT0
+.2833 g 5002 2048 M
+63 14 V
+stroke
+LT0
+.6509 g 3403 3028 M
+-48 -73 V
+stroke
+LT0
+.6851 g 3418 3198 M
+-63 -243 V
+stroke
+LT0
+.2763 g 4940 2031 M
+-48 -6 V
+stroke
+LT0
+.2658 g 4829 1994 M
+63 31 V
+stroke
+LT0
+.4651 g 3815 2588 M
+-62 -138 V
+stroke
+LT0
+.4927 g 3705 2701 M
+48 -251 V
+stroke
+LT0
+.278 g 2355 2024 M
+-48 17 V
+stroke
+LT1
+.1735 g 4343 1783 M
+-48 -82 V
+stroke
+LT1
+.152 g 4233 1703 M
+62 -2 V
+stroke
+LT0
+.6064 g 3955 3005 M
+48 -289 V
+stroke
+LT0
+.5449 g 3940 2728 M
+63 -12 V
+stroke
+LT0
+.5449 g 3437 2703 M
+-48 49 V
+stroke
+LT0
+.6218 g 3451 3040 M
+-62 -288 V
+stroke
+LT0
+.2693 g 2576 1995 M
+-48 22 V
+stroke
+LT0
+.2764 g 2465 2027 M
+63 -10 V
+stroke
+LT1
+.2089 g 4561 1862 M
+-30 -41 V
+stroke
+LT1
+.1942 g 4468 1802 M
+63 19 V
+stroke
+LT0
+.2589 g 5161 1952 M
+-48 65 V
+stroke
+LT0
+.2737 g 5050 2014 M
+63 3 V
+stroke
+LT0
+.701 g 3984 3211 M
+48 -186 V
+stroke
+LT0
+.701 g 3970 3174 M
+62 -149 V
+stroke
+LT0
+.2834 g 2465 2027 M
+-48 22 V
+stroke
+LT0
+.2812 g 2355 2024 M
+62 25 V
+stroke
+LT0
+.5618 g 3547 2873 M
+-62 -270 V
+stroke
+LT0
+.5173 g 3437 2703 M
+48 -100 V
+stroke
+LT0
+.505 g 3705 2701 M
+-62 -198 V
+stroke
+LT0
+.505 g 3595 2706 M
+48 -203 V
+stroke
+LT0
+.2804 g 5050 2014 M
+-48 34 V
+stroke
+LT0
+.2835 g 4946 2032 M
+56 16 V
+stroke
+LT0
+.2523 g 5098 1955 M
+63 -3 V
+stroke
+LT0
+.6064 g 3499 2987 M
+-62 -284 V
+stroke
+LT1
+.2074 g 4498 1844 M
+-30 -42 V
+stroke
+LT1
+.1942 g 4406 1789 M
+62 13 V
+stroke
+LT0
+.2793 g 2403 2005 M
+-48 19 V
+stroke
+LT0
+.5173 g 3878 2684 M
+-63 -96 V
+stroke
+LT0
+.5618 g 3767 2863 M
+48 -275 V
+stroke
+LT1
+.173 g 4264 1754 M
+-31 -51 V
+stroke
+LT1
+.1616 g 4180 1710 M
+53 -7 V
+stroke
+LT0
+.6851 g 3970 3174 M
+48 -248 V
+stroke
+LT0
+.6509 g 3955 3005 M
+63 -79 V
+stroke
+LT0
+.2693 g 2624 1975 M
+-48 20 V
+stroke
+LT0
+.276 g 2513 2006 M
+63 -11 V
+stroke
+LT0
+.2819 g 4988 2006 M
+-48 24 V
+stroke
+LT0
+.2817 g 4877 2010 M
+63 21 V
+stroke
+LT0
+.267 g 5098 1955 M
+-48 59 V
+stroke
+LT0
+.2788 g 4988 2006 M
+62 8 V
+stroke
+LT0
+.6218 g 3892 3021 M
+48 -293 V
+stroke
+LT0
+.5449 g 3878 2684 M
+62 44 V
+stroke
+LT0
+.2831 g 2513 2006 M
+-48 21 V
+stroke
+LT0
+.2815 g 2403 2005 M
+62 22 V
+stroke
+LT0
+.261 g 5036 1954 M
+62 1 V
+stroke
+LT0
+.6064 g 3830 2973 M
+48 -289 V
+stroke
+LT1
+.2057 g 4429 1821 M
+-23 -32 V
+stroke
+LT1
+.1973 g 4343 1783 M
+63 6 V
+stroke
+LT0
+.2817 g 4925 1994 M
+-48 16 V
+stroke
+LT0
+.2799 g 2451 1985 M
+-48 20 V
+stroke
+LT0
+.7895 g 3922 3375 M
+62 -164 V
+stroke
+LT0
+.8191 g 3874 3511 M
+110 -300 V
+stroke
+LT0
+.2728 g 5036 1954 M
+-48 52 V
+stroke
+LT0
+.2819 g 4925 1994 M
+63 12 V
+stroke
+LT0
+.2705 g 2672 1958 M
+-48 17 V
+stroke
+LT0
+.2764 g 2561 1986 M
+63 -11 V
+stroke
+LT0
+.6834 g 3451 3040 M
+-48 -12 V
+stroke
+LT0
+.7364 g 3466 3284 M
+-63 -256 V
+stroke
+LT0
+.6053 g 3658 2930 M
+-63 -224 V
+stroke
+LT0
+.5894 g 3547 2873 M
+48 -167 V
+stroke
+LT0
+.2831 g 2561 1986 M
+-48 20 V
+stroke
+LT0
+.2815 g 2451 1985 M
+62 21 V
+stroke
+LT0
+.2806 g 4863 1980 M
+-48 8 V
+stroke
+LT0
+.2757 g 4752 1966 M
+63 22 V
+stroke
+LT0
+.5894 g 3767 2863 M
+-62 -162 V
+stroke
+LT0
+.6053 g 3658 2930 M
+47 -229 V
+stroke
+LT0
+.2677 g 4973 1949 M
+63 5 V
+stroke
+LT0
+.7706 g 3466 3284 M
+-48 -86 V
+stroke
+LT0
+.7895 g 3480 3394 M
+-62 -196 V
+stroke
+LT1
+.203 g 4351 1793 M
+-8 -10 V
+stroke
+LT1
+.2006 g 4326 1782 M
+17 1 V
+stroke
+LT0
+.2767 g 4973 1949 M
+-48 45 V
+stroke
+LT0
+.2834 g 4863 1980 M
+62 14 V
+stroke
+LT0
+.2799 g 2499 1964 M
+-48 21 V
+stroke
+LT0
+.279 g 4800 1964 M
+-48 2 V
+stroke
+LT0
+.2728 g 4690 1945 M
+62 21 V
+stroke
+LT0
+.2728 g 2720 1943 M
+-48 15 V
+stroke
+LT0
+.2775 g 2609 1966 M
+63 -8 V
+stroke
+LT0
+.2834 g 2609 1966 M
+-48 20 V
+stroke
+LT0
+.2815 g 2499 1964 M
+62 22 V
+stroke
+LT0
+.7364 g 3907 3265 M
+48 -260 V
+stroke
+LT0
+.6834 g 3892 3021 M
+63 -16 V
+stroke
+LT0
+.2725 g 4911 1941 M
+62 8 V
+stroke
+LT0
+.6851 g 3610 3116 M
+-63 -243 V
+stroke
+LT0
+.6509 g 3499 2987 M
+48 -114 V
+stroke
+LT0
+.2792 g 4911 1941 M
+-48 39 V
+stroke
+LT0
+.2838 g 4800 1964 M
+63 16 V
+stroke
+LT0
+.6834 g 3499 2987 M
+-48 53 V
+stroke
+LT0
+.7541 g 3514 3300 M
+-63 -260 V
+stroke
+LT0
+.7895 g 3922 3375 M
+48 -201 V
+stroke
+LT0
+.7706 g 3907 3265 M
+63 -91 V
+stroke
+LT0
+.2775 g 4737 1948 M
+-47 -3 V
+stroke
+LT0
+.2705 g 4627 1926 M
+63 19 V
+stroke
+LT0
+.2793 g 2547 1941 M
+-48 23 V
+stroke
+LT0
+.6509 g 3830 2973 M
+-63 -110 V
+stroke
+LT0
+.6851 g 3719 3111 M
+48 -248 V
+stroke
+LT0
+.7364 g 3562 3243 M
+-63 -256 V
+stroke
+LT0
+.2757 g 2768 1929 M
+-48 14 V
+stroke
+LT0
+.279 g 2657 1946 M
+63 -3 V
+stroke
+LT0
+.2837 g 2657 1946 M
+-48 20 V
+stroke
+LT0
+.2812 g 2547 1941 M
+62 25 V
+stroke
+LT0
+.2758 g 4848 1931 M
+63 10 V
+stroke
+LT0
+.2805 g 4848 1931 M
+-48 33 V
+stroke
+LT0
+.2837 g 4737 1948 M
+63 16 V
+stroke
+LT0
+.2764 g 4675 1932 M
+-48 -6 V
+stroke
+LT0
+.2693 g 4564 1909 M
+63 17 V
+stroke
+LT0
+.7541 g 3844 3286 M
+48 -265 V
+stroke
+LT0
+.6834 g 3830 2973 M
+62 48 V
+stroke
+LT0
+.8652 g 3528 3489 M
+-48 -95 V
+stroke
+LT0
+.7364 g 3782 3233 M
+48 -260 V
+stroke
+LT0
+.701 g 3719 3111 M
+-61 -181 V
+stroke
+LT0
+.701 g 3610 3116 M
+48 -186 V
+stroke
+LT0
+.278 g 2595 1917 M
+-48 24 V
+stroke
+LT0
+.2812 g 4785 1918 M
+-48 30 V
+stroke
+LT0
+.2834 g 4675 1932 M
+62 16 V
+stroke
+LT0
+.278 g 4785 1918 M
+63 13 V
+stroke
+LT0
+.276 g 4612 1915 M
+-48 -6 V
+stroke
+LT0
+.2693 g 4502 1894 M
+62 15 V
+stroke
+LT0
+.8072 g 3514 3300 M
+-48 -16 V
+stroke
+LT0
+.8463 g 3528 3489 M
+-62 -205 V
+stroke
+LT0
+.2838 g 2705 1926 M
+-48 20 V
+stroke
+LT0
+.2805 g 2595 1917 M
+62 29 V
+stroke
+LT0
+.2789 g 2816 1914 M
+-48 15 V
+stroke
+LT0
+.2806 g 2705 1926 M
+63 3 V
+stroke
+LT0
+.8652 g 3874 3511 M
+48 -136 V
+stroke
+LT0
+.8652 g 3859 3475 M
+63 -100 V
+stroke
+LT0
+.2758 g 2643 1892 M
+-48 25 V
+stroke
+LT0
+.2815 g 4723 1904 M
+-48 28 V
+stroke
+LT0
+.2831 g 4612 1915 M
+63 17 V
+stroke
+LT0
+.2793 g 4723 1904 M
+62 14 V
+stroke
+LT0
+.2764 g 4550 1900 M
+-48 -6 V
+stroke
+LT0
+.2705 g 4439 1882 M
+63 12 V
+stroke
+LT0
+.8463 g 3859 3475 M
+48 -210 V
+stroke
+LT0
+.8072 g 3844 3286 M
+63 -21 V
+stroke
+LT0
+.2834 g 2753 1903 M
+-48 23 V
+stroke
+LT0
+.2792 g 2643 1892 M
+62 34 V
+stroke
+LT0
+.2753 g 2816 1914 M
+106 -25 V
+stroke
+LT0
+.2817 g 2864 1898 M
+-48 16 V
+stroke
+LT0
+.2817 g 2753 1903 M
+63 11 V
+stroke
+LT0
+.9258 g 3811 3617 M
+63 -106 V
+stroke
+LT0
+.7895 g 3672 3312 M
+-62 -196 V
+stroke
+LT0
+.7706 g 3562 3243 M
+48 -127 V
+stroke
+LT0
+.2815 g 4660 1889 M
+-48 26 V
+stroke
+LT0
+.2831 g 4550 1900 M
+62 15 V
+stroke
+LT0
+.2725 g 2691 1863 M
+-48 29 V
+stroke
+LT0
+.7706 g 3782 3233 M
+-63 -122 V
+stroke
+LT0
+.7895 g 3672 3312 M
+47 -201 V
+stroke
+LT0
+.2799 g 4660 1889 M
+63 15 V
+stroke
+LT0
+.2775 g 4487 1885 M
+-48 -3 V
+stroke
+LT0
+.2728 g 4377 1871 M
+62 11 V
+stroke
+LT0
+.8072 g 3562 3243 M
+-48 57 V
+stroke
+LT0
+.8658 g 3576 3508 M
+-62 -208 V
+stroke
+LT0
+.2819 g 2801 1879 M
+-48 24 V
+stroke
+LT0
+.2767 g 2691 1863 M
+62 40 V
+stroke
+LT0
+.8463 g 3624 3448 M
+-62 -205 V
+stroke
+LT0
+.2815 g 4598 1873 M
+-48 27 V
+stroke
+LT0
+.2834 g 4487 1885 M
+63 15 V
+stroke
+LT0
+.2834 g 2912 1880 M
+-48 18 V
+stroke
+LT0
+.2797 g 2974 1881 M
+-110 17 V
+stroke
+LT0
+.2819 g 2801 1879 M
+63 19 V
+stroke
+LT0
+.279 g 3022 1870 M
+-48 11 V
+stroke
+LT0
+.2802 g 2912 1880 M
+62 1 V
+stroke
+LT0
+.8658 g 3796 3499 M
+48 -213 V
+stroke
+LT0
+.8072 g 3782 3233 M
+62 53 V
+stroke
+LT0
+.9049 g 3576 3508 M
+-48 -19 V
+stroke
+LT0
+.9258 g 3591 3626 M
+-63 -137 V
+stroke
+LT0
+.2799 g 4598 1873 M
+62 16 V
+stroke
+LT0
+.2677 g 2739 1832 M
+-48 31 V
+stroke
+LT0
+.279 g 4425 1870 M
+-48 1 V
+stroke
+LT0
+.2757 g 4314 1862 M
+63 9 V
+stroke
+LT0
+.8463 g 3734 3443 M
+48 -210 V
+stroke
+LT0
+.2788 g 2849 1850 M
+-48 29 V
+stroke
+LT0
+.2728 g 2739 1832 M
+62 47 V
+stroke
+LT0
+.2812 g 4535 1855 M
+-48 30 V
+stroke
+LT0
+.2837 g 4425 1870 M
+62 15 V
+stroke
+LT0
+.9258 g 3811 3617 M
+48 -142 V
+stroke
+LT0
+.9049 g 3796 3499 M
+63 -24 V
+stroke
+LT0
+.2793 g 4535 1855 M
+63 18 V
+stroke
+LT0
+.261 g 2787 1796 M
+-48 36 V
+stroke
+LT0
+.2833 g 2960 1857 M
+-48 23 V
+stroke
+LT0
+.2804 g 2849 1850 M
+63 30 V
+stroke
+LT0
+.2806 g 4362 1854 M
+-48 8 V
+stroke
+LT0
+.9891 g 3701 3706 M
+-47 -22 V
+stroke
+LT0
+.9676 g 3591 3626 M
+63 58 V
+stroke
+LT0
+.2827 g 3070 1854 M
+-48 16 V
+stroke
+LT0
+.2788 g 3133 1855 M
+-111 15 V
+stroke
+LT0
+.2821 g 2960 1857 M
+62 13 V
+stroke
+LT0
+.8652 g 3734 3443 M
+-62 -131 V
+stroke
+LT0
+.8652 g 3624 3448 M
+48 -136 V
+stroke
+LT0
+.2791 g 3181 1846 M
+-48 9 V
+stroke
+LT0
+.2799 g 3070 1854 M
+63 1 V
+stroke
+LT0
+.9676 g 3639 3647 M
+-48 -21 V
+stroke
+LT0
+.2763 g 4252 1852 M
+-85 -13 V
+stroke
+LT0
+.9676 g 3811 3617 M
+-48 62 V
+stroke
+LT0
+.9891 g 3701 3706 M
+62 -27 V
+stroke
+LT0
+.2805 g 4473 1836 M
+-48 34 V
+stroke
+LT0
+.2838 g 4362 1854 M
+63 16 V
+stroke
+LT0
+.2737 g 2897 1817 M
+-48 33 V
+stroke
+LT0
+.267 g 2787 1796 M
+62 54 V
+stroke
+LT0
+.278 g 4473 1836 M
+62 19 V
+stroke
+LT0
+.2523 g 2834 1756 M
+-47 40 V
+stroke
+LT0
+.9049 g 3624 3448 M
+-48 60 V
+stroke
+LT0
+.9467 g 3639 3647 M
+-63 -139 V
+stroke
+LT0
+.9676 g 3748 3643 M
+63 -26 V
+stroke
+LT0
+.2817 g 4300 1836 M
+-48 16 V
+stroke
+LT0
+.2817 g 4189 1841 M
+63 11 V
+stroke
+LT0
+.2806 g 3008 1828 M
+-48 29 V
+stroke
+LT0
+.2766 g 2897 1817 M
+63 40 V
+stroke
+LT0
+.9258 g 3687 3585 M
+-63 -137 V
+stroke
+LT0
+.9467 g 3748 3643 M
+48 -144 V
+stroke
+LT0
+.9049 g 3734 3443 M
+62 56 V
+stroke
+LT0
+.2832 g 3118 1831 M
+-48 23 V
+stroke
+LT0
+.2812 g 3008 1828 M
+62 26 V
+stroke
+LT0
+.2792 g 4410 1815 M
+-48 39 V
+stroke
+LT0
+.2834 g 4300 1836 M
+62 18 V
+stroke
+LT0
+.2758 g 4410 1815 M
+63 21 V
+stroke
+LT0
+.9258 g 3687 3585 M
+47 -142 V
+stroke
+LT0
+.2802 g 4127 1827 M
+-48 6 V
+stroke
+LT0
+.2797 g 4189 1841 M
+-110 -8 V
+stroke
+LT0
+.279 g 4016 1827 M
+63 6 V
+stroke
+LT0
+.266 g 2945 1779 M
+-48 38 V
+stroke
+LT0
+.2589 g 2834 1756 M
+63 61 V
+stroke
+LT0
+.2413 g 2882 1712 M
+-48 44 V
+stroke
+LT0
+.283 g 3229 1829 M
+-48 17 V
+stroke
+LT0
+.2809 g 3291 1836 M
+-110 10 V
+stroke
+LT0
+.2824 g 3118 1831 M
+63 15 V
+stroke
+LT0
+.2817 g 3339 1824 M
+-48 12 V
+stroke
+LT0
+.2784 g 3402 1827 M
+-111 9 V
+stroke
+LT0
+.2817 g 3229 1829 M
+62 7 V
+stroke
+LT0
+.2804 g 3450 1819 M
+-48 8 V
+stroke
+LT0
+.2769 g 3512 1821 M
+-110 6 V
+stroke
+LT0
+.2806 g 3339 1824 M
+63 3 V
+stroke
+LT0
+.2819 g 4237 1816 M
+-48 25 V
+stroke
+LT0
+.2834 g 4127 1827 M
+62 14 V
+stroke
+LT0
+.2748 g 3056 1793 M
+-48 35 V
+stroke
+LT0
+.27 g 2945 1779 M
+63 49 V
+stroke
+LT0
+.9891 g 3748 3643 M
+-47 63 V
+stroke
+LT0
+.9891 g 3639 3647 M
+62 59 V
+stroke
+LT0
+.2799 g 3953 1816 M
+-48 5 V
+stroke
+LT0
+.2788 g 4016 1827 M
+-111 -6 V
+stroke
+LT0
+.2791 g 3843 1818 M
+62 3 V
+stroke
+LT0
+.9676 g 3687 3585 M
+-48 62 V
+stroke
+LT0
+.28 g 3560 1814 M
+-48 7 V
+stroke
+LT0
+.2769 g 3623 1818 M
+-111 3 V
+stroke
+LT0
+.28 g 3450 1819 M
+62 2 V
+stroke
+LT0
+.2725 g 4348 1791 M
+62 24 V
+stroke
+LT0
+.2767 g 4348 1791 M
+-48 45 V
+stroke
+LT0
+.2819 g 4237 1816 M
+63 20 V
+stroke
+LT0
+.2281 g 2930 1663 M
+-48 49 V
+stroke
+LT0
+.2483 g 2945 1779 M
+-63 -67 V
+stroke
+LT0
+.2554 g 2993 1735 M
+-48 44 V
+stroke
+LT0
+.9676 g 3687 3585 M
+61 58 V
+stroke
+LT0
+.2806 g 3671 1810 M
+-48 8 V
+stroke
+LT0
+.2784 g 3732 1817 M
+-109 1 V
+stroke
+LT0
+.2804 g 3560 1814 M
+63 4 V
+stroke
+LT0
+.2797 g 3166 1799 M
+-48 32 V
+stroke
+LT0
+.2767 g 3056 1793 M
+62 38 V
+stroke
+LT0
+.2821 g 4064 1809 M
+-48 18 V
+stroke
+LT0
+.2827 g 3953 1816 M
+63 11 V
+stroke
+LT0
+.2819 g 3277 1801 M
+-48 28 V
+stroke
+LT0
+.2803 g 3166 1799 M
+63 30 V
+stroke
+LT0
+.2817 g 3780 1805 M
+-48 12 V
+stroke
+LT0
+.2809 g 3843 1818 M
+-111 -1 V
+stroke
+LT0
+.2817 g 3671 1810 M
+61 7 V
+stroke
+LT0
+.2127 g 2978 1611 M
+-48 52 V
+stroke
+LT0
+.2352 g 2993 1735 M
+-63 -72 V
+stroke
+LT0
+.2804 g 4175 1793 M
+-48 34 V
+stroke
+LT0
+.2833 g 4064 1809 M
+63 18 V
+stroke
+LT0
+.2653 g 3104 1750 M
+-48 43 V
+stroke
+LT0
+.2602 g 2993 1735 M
+63 58 V
+stroke
+LT0
+.2677 g 4285 1765 M
+63 26 V
+stroke
+LT0
+.242 g 3041 1685 M
+-48 50 V
+stroke
+LT0
+.2728 g 4285 1765 M
+-48 51 V
+stroke
+LT0
+.2788 g 4175 1793 M
+62 23 V
+stroke
+LT0
+.2827 g 3387 1799 M
+-48 25 V
+stroke
+LT0
+.2819 g 3277 1801 M
+62 23 V
+stroke
+LT0
+.2824 g 3891 1798 M
+-48 20 V
+stroke
+LT0
+.283 g 3780 1805 M
+63 13 V
+stroke
+LT0
+.2827 g 3498 1795 M
+-48 24 V
+stroke
+LT0
+.2825 g 3387 1799 M
+63 20 V
+stroke
+LT0
+.2716 g 3214 1759 M
+-48 40 V
+stroke
+LT0
+.2682 g 3104 1750 M
+62 49 V
+stroke
+LT0
+.1957 g 3026 1556 M
+-48 55 V
+stroke
+LT0
+.2195 g 3041 1685 M
+-63 -74 V
+stroke
+LT0
+.2812 g 4001 1785 M
+-48 31 V
+stroke
+LT0
+.2832 g 3891 1798 M
+62 18 V
+stroke
+LT0
+.2825 g 3608 1789 M
+-48 25 V
+stroke
+LT0
+.2827 g 3498 1795 M
+62 19 V
+stroke
+LT0
+.261 g 4223 1734 M
+62 31 V
+stroke
+LT0
+.2258 g 3089 1630 M
+-48 55 V
+stroke
+LT0
+.2471 g 3104 1750 M
+-63 -65 V
+stroke
+LT0
+.2521 g 3152 1700 M
+-48 50 V
+stroke
+LT0
+.2766 g 4112 1765 M
+-48 44 V
+stroke
+LT0
+.2806 g 4001 1785 M
+63 24 V
+stroke
+LT0
+.267 g 4223 1734 M
+-48 59 V
+stroke
+LT0
+.2737 g 4112 1765 M
+63 28 V
+stroke
+LT0
+.2753 g 3325 1762 M
+-48 39 V
+stroke
+LT0
+.2732 g 3214 1759 M
+63 42 V
+stroke
+LT0
+.2819 g 3718 1782 M
+-47 28 V
+stroke
+LT0
+.2827 g 3608 1789 M
+63 21 V
+stroke
+LT0
+.1776 g 3074 1499 M
+-48 57 V
+stroke
+LT0
+.2019 g 3089 1630 M
+-63 -74 V
+stroke
+LT0
+.2769 g 3435 1761 M
+-48 38 V
+stroke
+LT0
+.276 g 3325 1762 M
+62 37 V
+stroke
+LT0
+.2803 g 3828 1771 M
+-48 34 V
+stroke
+LT0
+.2819 g 3718 1782 M
+62 23 V
+stroke
+LT0
+.2073 g 3137 1572 M
+-48 58 V
+stroke
+LT0
+.2308 g 3152 1700 M
+-63 -70 V
+stroke
+LT0
+.2589 g 3262 1709 M
+-48 50 V
+stroke
+LT0
+.2555 g 3152 1700 M
+62 59 V
+stroke
+LT0
+.2523 g 4160 1699 M
+63 35 V
+stroke
+LT0
+.2354 g 3200 1644 M
+-48 56 V
+stroke
+LT0
+.2767 g 3939 1755 M
+-48 43 V
+stroke
+LT0
+.2797 g 3828 1771 M
+63 27 V
+stroke
+LT0
+.2771 g 3546 1756 M
+-48 39 V
+stroke
+LT0
+.2771 g 3435 1761 M
+63 34 V
+stroke
+LT0
+.1594 g 3122 1443 M
+-48 56 V
+stroke
+LT0
+.183 g 3137 1572 M
+-63 -73 V
+stroke
+LT0
+.2589 g 4160 1699 M
+-48 66 V
+stroke
+LT0
+.266 g 4049 1731 M
+63 34 V
+stroke
+LT0
+.27 g 4049 1731 M
+-48 54 V
+stroke
+LT0
+.2748 g 3939 1755 M
+62 30 V
+stroke
+LT0
+.1873 g 3185 1511 M
+-48 61 V
+stroke
+LT0
+.2119 g 3200 1644 M
+-63 -72 V
+stroke
+LT0
+.2629 g 3373 1712 M
+-48 50 V
+stroke
+LT0
+.261 g 3262 1709 M
+63 53 V
+stroke
+LT0
+.276 g 3656 1747 M
+-48 42 V
+stroke
+LT0
+.2769 g 3546 1756 M
+62 33 V
+stroke
+LT0
+.2413 g 4097 1659 M
+63 40 V
+stroke
+LT0
+.2158 g 3248 1582 M
+-48 62 V
+stroke
+LT0
+.2388 g 3262 1709 M
+-62 -65 V
+stroke
+LT0
+.2419 g 3310 1651 M
+-48 58 V
+stroke
+LT0
+.2732 g 3766 1735 M
+-48 47 V
+stroke
+LT0
+.2753 g 3656 1747 M
+62 35 V
+stroke
+LT0
+.142 g 3170 1390 M
+-48 53 V
+stroke
+LT0
+.1637 g 3185 1511 M
+-63 -68 V
+stroke
+LT0
+.2645 g 3483 1709 M
+-48 52 V
+stroke
+LT0
+.2638 g 3373 1712 M
+62 49 V
+stroke
+LT0
+.2483 g 4097 1659 M
+-48 72 V
+stroke
+LT0
+.2554 g 3987 1692 M
+62 39 V
+stroke
+LT0
+.1669 g 3233 1451 M
+-48 60 V
+stroke
+LT0
+.1912 g 3248 1582 M
+-63 -71 V
+stroke
+LT0
+.2682 g 3876 1717 M
+-48 54 V
+stroke
+LT0
+.2716 g 3766 1735 M
+62 36 V
+stroke
+LT0
+.2602 g 3987 1692 M
+-48 63 V
+stroke
+LT0
+.2653 g 3876 1717 M
+63 38 V
+stroke
+LT0
+.1942 g 3296 1518 M
+-48 64 V
+stroke
+LT0
+.2188 g 3310 1651 M
+-62 -69 V
+stroke
+LT0
+.2281 g 4035 1616 M
+62 43 V
+stroke
+LT0
+.2453 g 3421 1652 M
+-48 60 V
+stroke
+LT0
+.2438 g 3310 1651 M
+63 61 V
+stroke
+LT0
+.2638 g 3594 1702 M
+-48 54 V
+stroke
+LT0
+.2645 g 3483 1709 M
+63 47 V
+stroke
+LT0
+.2212 g 3358 1587 M
+-48 64 V
+stroke
+LT0
+.261 g 3703 1690 M
+-47 57 V
+stroke
+LT0
+.2629 g 3594 1702 M
+62 45 V
+stroke
+LT0
+.1474 g 3281 1394 M
+-48 57 V
+stroke
+LT0
+.1699 g 3296 1518 M
+-63 -67 V
+stroke
+LT0
+.1453 g 3170 1390 M
+63 61 V
+stroke
+LT0
+.2352 g 4035 1616 M
+-48 76 V
+stroke
+LT0
+.242 g 3924 1647 M
+63 45 V
+stroke
+LT0
+.1268 g 3218 1342 M
+-48 48 V
+stroke
+LT0
+.1719 g 3344 1454 M
+-48 64 V
+stroke
+LT0
+.1965 g 3358 1587 M
+-62 -69 V
+stroke
+LT0
+.2459 g 3531 1647 M
+-48 62 V
+stroke
+LT0
+.2459 g 3421 1652 M
+62 57 V
+stroke
+LT0
+.2555 g 3814 1671 M
+-48 64 V
+stroke
+LT0
+.2589 g 3703 1690 M
+63 45 V
+stroke
+LT0
+.2471 g 3924 1647 M
+-48 70 V
+stroke
+LT0
+.2521 g 3814 1671 M
+62 46 V
+stroke
+LT0
+.2127 g 3972 1568 M
+63 48 V
+stroke
+LT0
+.198 g 3406 1519 M
+-48 68 V
+stroke
+LT0
+.2226 g 3421 1652 M
+-63 -65 V
+stroke
+LT0
+.2234 g 3469 1585 M
+-48 67 V
+stroke
+LT0
+.2438 g 3642 1636 M
+-48 66 V
+stroke
+LT0
+.2453 g 3531 1647 M
+63 55 V
+stroke
+LT0
+.2195 g 3972 1568 M
+-48 79 V
+stroke
+LT0
+.2258 g 3862 1597 M
+62 50 V
+stroke
+LT0
+.1505 g 3392 1393 M
+-48 61 V
+stroke
+LT0
+.1734 g 3406 1519 M
+-62 -65 V
+stroke
+LT0
+.1494 g 3281 1394 M
+63 60 V
+stroke
+LT0
+.1957 g 3910 1517 M
+62 51 V
+stroke
+LT0
+.2388 g 3751 1620 M
+-48 70 V
+stroke
+LT0
+.2419 g 3642 1636 M
+61 54 V
+stroke
+LT0
+.1741 g 3454 1452 M
+-48 67 V
+stroke
+LT0
+.1988 g 3469 1585 M
+-63 -66 V
+stroke
+LT0
+.1301 g 3329 1342 M
+-48 52 V
+stroke
+LT0
+.1289 g 3218 1342 M
+63 52 V
+stroke
+LT0
+.2308 g 3862 1597 M
+-48 74 V
+stroke
+LT0
+.2354 g 3751 1620 M
+63 51 V
+stroke
+LT0
+.2226 g 3579 1577 M
+-48 70 V
+stroke
+LT0
+.2234 g 3469 1585 M
+62 62 V
+stroke
+LT0
+.1988 g 3517 1514 M
+-48 71 V
+stroke
+LT0
+.2019 g 3910 1517 M
+-48 80 V
+stroke
+LT0
+.2073 g 3799 1543 M
+63 54 V
+stroke
+LT0
+.2188 g 3690 1563 M
+-48 73 V
+stroke
+LT0
+.2212 g 3579 1577 M
+63 59 V
+stroke
+LT0
+.1776 g 3847 1466 M
+63 51 V
+stroke
+LT0
+.2119 g 3799 1543 M
+-48 77 V
+stroke
+LT0
+.2158 g 3690 1563 M
+61 57 V
+stroke
+LT0
+.1147 g 3266 1302 M
+-48 40 V
+stroke
+LT0
+.1965 g 3627 1504 M
+-48 73 V
+stroke
+LT0
+.198 g 3517 1514 M
+62 63 V
+stroke
+LT0
+.1734 g 3565 1445 M
+-48 69 V
+stroke
+LT0
+.1741 g 3454 1452 M
+63 62 V
+stroke
+LT0
+.1512 g 3502 1389 M
+-48 63 V
+stroke
+LT0
+.1512 g 3392 1393 M
+62 59 V
+stroke
+LT0
+.183 g 3847 1466 M
+-48 77 V
+stroke
+LT0
+.1873 g 3737 1487 M
+62 56 V
+stroke
+LT0
+.1912 g 3737 1487 M
+-47 76 V
+stroke
+LT0
+.1942 g 3627 1504 M
+63 59 V
+stroke
+LT0
+.1316 g 3440 1339 M
+-48 54 V
+stroke
+LT0
+.1312 g 3329 1342 M
+63 51 V
+stroke
+LT0
+.1699 g 3675 1432 M
+-48 72 V
+stroke
+LT0
+.1719 g 3565 1445 M
+62 59 V
+stroke
+LT0
+.1594 g 3785 1415 M
+62 51 V
+stroke
+LT0
+.1637 g 3785 1415 M
+-48 72 V
+stroke
+LT0
+.1669 g 3675 1432 M
+62 55 V
+stroke
+LT0
+.1494 g 3613 1379 M
+-48 66 V
+stroke
+LT0
+.1505 g 3502 1389 M
+63 56 V
+stroke
+LT0
+.1164 g 3377 1299 M
+-48 43 V
+stroke
+LT0
+.1159 g 3266 1302 M
+63 40 V
+stroke
+LT0
+.1453 g 3722 1366 M
+-47 66 V
+stroke
+LT0
+.1474 g 3613 1379 M
+62 53 V
+stroke
+LT0
+.1312 g 3550 1333 M
+-48 56 V
+stroke
+LT0
+.1316 g 3440 1339 M
+62 50 V
+stroke
+LT0
+.142 g 3722 1366 M
+63 49 V
+stroke
+LT0
+.1289 g 3661 1323 M
+-48 56 V
+stroke
+LT0
+.1301 g 3550 1333 M
+63 46 V
+stroke
+LT0
+.1168 g 3488 1294 M
+-48 45 V
+stroke
+LT0
+.1168 g 3377 1299 M
+63 40 V
+stroke
+LT0
+.1268 g 3661 1323 M
+61 43 V
+stroke
+LT0
+.1069 g 3314 1271 M
+-48 31 V
+stroke
+LT0
+.1159 g 3598 1288 M
+-48 45 V
+stroke
+LT0
+.1164 g 3488 1294 M
+62 39 V
+stroke
+LT0
+.1147 g 3598 1288 M
+63 35 V
+stroke
+LT0
+.1075 g 3425 1266 M
+-48 33 V
+stroke
+LT0
+.1074 g 3314 1271 M
+63 28 V
+stroke
+LT0
+.1074 g 3536 1261 M
+-48 33 V
+stroke
+LT0
+.1075 g 3425 1266 M
+63 28 V
+stroke
+LT0
+.1069 g 3536 1261 M
+62 27 V
+stroke
+LT0
+.1041 g 3362 1250 M
+-48 21 V
+stroke
+LT0
+.1042 g 3473 1245 M
+-48 21 V
+stroke
+LT0
+.1042 g 3362 1250 M
+63 16 V
+stroke
+LT0
+.1041 g 3473 1245 M
+63 16 V
+stroke
+LT0
+.1067 g 3410 1240 M
+-48 10 V
+stroke
+LT0
+.1067 g 3410 1240 M
+63 5 V
+% Begin plot #1
+stroke
+LT0
+.1784 g % End plot #1
+0.500 UL
+LTb
+3338 551 M
+3126 790 V
+3338 551 M
+938 1580 L
+149 38 R
+1397 352 V
+938 1580 M
+148 37 V
+6464 1341 M
+5034 1954 L
+938 3825 M
+0 -2245 V
+4064 4615 M
+0 -1676 V
+2400 647 R
+0 -2245 V
+938 3825 M
+3126 790 V
+6464 3586 M
+4064 4615 L
+3338 551 M
+-82 35 V
+stroke
+0.00 0.00 0.00 C 3415 495 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-10)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1020 1545 M
+-82 35 V
+4119 748 M
+-82 35 V
+stroke
+0.00 0.00 0.00 C 4196 693 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-5)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1801 1742 M
+-81 35 V
+4900 946 M
+-81 35 V
+stroke
+0.00 0.00 0.00 C 4978 890 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5682 1143 M
+-81 35 V
+stroke
+0.00 0.00 0.00 C 5760 1088 M
+[ [(Helvetica) 120.0 0.0 true true 0 (5)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 1341 M
+-82 35 V
+stroke
+0.00 0.00 0.00 C 6542 1285 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+3338 551 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 3271 523 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6394 1323 M
+70 18 V
+2738 808 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 2671 780 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5794 1580 M
+70 18 V
+2138 1065 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 2071 1037 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5194 1837 M
+70 18 V
+1538 1323 M
+70 17 V
+stroke
+0.00 0.00 0.00 C 1471 1295 M
+[ [(Helvetica) 120.0 0.0 true true 0 (5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+938 1580 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 871 1552 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1026 1580 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 1580 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 1341 M
+88 0 V
+1026 1901 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 1901 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 1661 M
+88 0 V
+1026 2222 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 2222 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 1982 M
+88 0 V
+1026 2543 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 2543 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 2303 M
+88 0 V
+1026 2863 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 2863 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 2623 M
+88 0 V
+1026 3184 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 3184 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 2944 M
+88 0 V
+1026 3505 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 3505 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 3265 M
+88 0 V
+1026 3825 M
+-88 0 V
+stroke
+0.00 0.00 0.00 C 812 3825 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6376 3586 M
+88 0 V
+1.000 UP
+stroke
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/mesh.pdf b/doc/interpreter/mesh.pdf
new file mode 100644
index 0000000..1e48517
Binary files /dev/null and b/doc/interpreter/mesh.pdf differ
diff --git a/doc/interpreter/mesh.png b/doc/interpreter/mesh.png
new file mode 100644
index 0000000..3dd304e
Binary files /dev/null and b/doc/interpreter/mesh.png differ
diff --git a/doc/interpreter/mesh.txt b/doc/interpreter/mesh.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/mesh.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/mk_doc_cache.m b/doc/interpreter/mk_doc_cache.m
new file mode 100644
index 0000000..d79b6b2
--- /dev/null
+++ b/doc/interpreter/mk_doc_cache.m
@@ -0,0 +1,141 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+args = argv ();
+
+if (nargin < 2)
+  error ("usage: mk_doc_cache OUTPUT-FILE DOCSTRINGS-FILE ...");
+endif
+
+output_file = args{1};
+docstrings_files = args(2:end);
+
+doc_delim = char (31);
+
+function str = skip_newline (str)
+  n = numel (str);
+  j = 1;
+  while (j <= n)
+    c = str(j);
+    if (c == "\r" || c == "\n")
+      j++;
+    else
+      break;
+    endif
+  endwhile
+  str = str(j:end);
+endfunction
+
+## Read the contents of all the DOCSTRINGS files into TEXT.
+
+text = "";
+nfiles = numel (docstrings_files);
+text = cell (1, nfiles+1);
+for i = 1:nfiles
+  file = docstrings_files{i};
+  fid = fopen (file, "r");
+  if (fid < 0)
+    error ("unable to open %s for reading", file);
+  else
+    tmp = fread (fid, Inf, "*char")';
+    delim_idx = find (tmp == doc_delim, 1);
+    text{i} = tmp(delim_idx:end);
+  endif
+endfor
+text = [text{:}, doc_delim];
+
+text = regexprep (text, "@seealso *{([^}]*)}", "See also: $1.");
+text = regexprep (text, "-\\*- texinfo -\\*-[ \t]*[\r\n]*", "");
+
+[fid, name, msg] = mkstemp ("octave_doc_XXXXXX", true);
+
+if (fid < 0)
+  error ("%s: %s\n", name, msg);
+endif
+
+fwrite (fid, text, "char");
+
+fclose (fid);
+
+cmd = sprintf ("%s --no-headers --no-warn --force --no-validate --fill-column=1024 %s",
+               makeinfo_program (), name);
+
+[status, formatted_text] = system (cmd);
+
+## Did we get the help text?
+if (status != 0)
+  error ("makeinfo failed with exit status %d!", status);
+endif
+
+if (isempty (formatted_text))
+  error ("makeinfo produced no output!");
+endif
+
+delim_idx = find (formatted_text == doc_delim);
+n = numel (delim_idx);
+
+cache = cell (3, n);
+k = 1;
+
+for i = 2:n
+
+  block = formatted_text(delim_idx(i-1)+1:delim_idx(i)-1);
+
+  [symbol, doc] = strtok (block, "\r\n");
+
+  doc = skip_newline (doc);
+
+  ## Skip functions that start with __ as these shouldn't be
+  ## searched by lookfor.
+  if (numel (symbol) > 2 && regexp (symbol, "^__.+__$"))
+    continue;
+  endif
+
+  if (isempty (doc))
+    continue;
+  endif
+
+  [s, e] = regexp (doc, "^ -- [^\r\n]*[\r\n]", "lineanchors");
+
+  if (isempty (s))
+    continue;
+  endif
+
+  start_of_first_sentence = e(end);
+
+  tmp = doc(start_of_first_sentence:end);
+
+  end_of_first_sentence = regexp (tmp, '(\.|[\r\n][\r\n])');
+
+  if (isempty (end_of_first_sentence))
+    end_of_first_sentence = numel (tmp);
+  else
+    end_of_first_sentence = end_of_first_sentence(1);
+  endif
+
+  first_sentence = tmp(1:end_of_first_sentence);
+  first_sentence = regexprep (first_sentence, "([\r\n]|  *)", " ");
+  first_sentence = regexprep (first_sentence, "^ *", "");
+
+  cache{1,k} = symbol;
+  cache{2,k} = doc;
+  cache{3,k} = first_sentence;
+  k++;
+endfor
+
+cache(:,k:end) = [];
+
+save ("-text", output_file, "cache");
diff --git a/doc/interpreter/mkcontrib.awk b/doc/interpreter/mkcontrib.awk
new file mode 100644
index 0000000..c4192c3
--- /dev/null
+++ b/doc/interpreter/mkcontrib.awk
@@ -0,0 +1,12 @@
+{ x[NR] = $0; } END {
+  print "@multitable @columnfractions .33 .33 .33";
+  rem = NR % 3;
+  n = NR - rem;
+  for (i = 1; i <= n; i += 3)
+    printf ("@item %s @tab %s @tab %s\n", x[i], x[i+1], x[i+2]);
+  if (rem == 1)
+    printf ("@item %s\n", x[NR]);
+  else if (rem == 2)
+    printf ("@item %s @tab %s\n", x[NR-1], x[NR]);
+  print "@end multitable";
+}
diff --git a/doc/interpreter/mkoctfile.1 b/doc/interpreter/mkoctfile.1
new file mode 100644
index 0000000..26d2924
--- /dev/null
+++ b/doc/interpreter/mkoctfile.1
@@ -0,0 +1,118 @@
+.\" Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+.\"               Dirk Eddelbuettel
+.\"
+.\" This file is part of Octave.
+.\"
+.\" Octave is free software; you can redistribute it and/or modify it
+.\" under the terms of the GNU General Public License as published by the
+.\" Free Software Foundation; either version 3 of the License, or (at
+.\" your option) any later version.
+.\"
+.\" Octave is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+.\" for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with Octave; see the file COPYING.  If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.\" This page was contributed by Dirk Eddelbuettel <edd at debian.org>
+.\"
+.TH MKOCTFILE 1 "1 November 2002" "GNU Octave"
+.SH NAME
+mkoctfile \- Compile dynamic-load modules for GNU Octave
+.SH SYNOPSIS
+.BR mkoctfile\  [\-IDIR]\ [\-DDEF]\ [\-lLIB]\ [\-LDIR]\ [\-M|\-\-depend]\ 
+[\-c]\ [\-o FILE|\-\-output FILE]\ [\-p VAR|\-\-print VAR]\ [\-s|\-\-strip]\ 
+[\-v|\-\-verbose]\ [\-h|\-?|\-\-help]\ \fIfile\fP .\|.\|.  
+.SH DESCRIPTION
+.PP
+\fImkoctfile\fP is used to compile source C, C++ or Fortran source code in
+dynamically loadable 
+.I .oct
+file for 
+.BR octave (1).
+.SH OPTIONS
+\fImkoctfile\fP accepts the following options:
+.TP 8
+.B \-IDIR
+Add include directory DIR to compile commands.
+.TP 8
+.B \-DDEF
+Add definition DEF to compiler call.
+.TP 8
+.B \-lLIB
+Add library LIB to link command.
+.TP 8
+.B \-LDIR
+Add library directory DIR to link command.
+.TP 8
+.B \-M|\-\-depend
+Generate dependency files (.d) for C and C++ source files.
+.TP 8
+.B \-c
+Compile but do not link.
+.TP 8
+.B \-o FILE|\-\-output FILE
+Output file name; default extension is .oct (or .mex if \-\-mex is
+specified) unless linking a stand-alone executable.
+.TP
+.B \-p VAR|\-\-print VAR
+Print configuration variable VAR.  Recognized variables are:
+.RS
+    ALL_CFLAGS                FFTW_LIBS     
+    ALL_CXXFLAGS              FLIBS       
+    ALL_FFLAGS                FPICFLAG      
+    ALL_LDFLAGS               INCFLAGS      
+    BLAS_LIBS                 LDFLAGS             
+    CC                        LD_CXX              
+    CFLAGS                    LD_STATIC_FLAG
+    CPICFLAG                  LFLAGS              
+    CPPFLAGS                  LIBCRUFT      
+    CXX                       LIBOCTAVE     
+    CXXFLAGS                  LIBOCTINTERP  
+    CXXPICFLAG                LIBREADLINE   
+    DEPEND_EXTRA_SED_PATTERN  LIBS        
+    DEPEND_FLAGS              OCTAVE_LIBS   
+    DL_LD                     RDYNAMIC_FLAG 
+    DL_LDFLAGS                RLD_FLAG      
+    F2C                       SED         
+    F2CFLAGS                  XTRA_CFLAGS   
+    F77                       XTRA_CXXFLAGS 
+    FFLAGS
+.RE
+.TP 8
+.B \-\-link-stand-alone
+Link a stand-alone executable file.
+.TP 8
+.B \-\-mex
+Assume we are creating a MEX file.  Set the default output extension
+to .mex.
+.TP 8
+.B \-s|--strip
+Strip the output file.
+.TP 8
+.B \-v|--verbose
+Echo commands as they are executed.
+.TP 8
+.B file
+Compile or link file. Recognised file types are 
+.RS
+    .c    C source
+    .cc   C++ source
+    .C    C++ source
+    .cpp  C++ source
+    .f    Fortran source
+    .F    Fortran source
+    .o    object file
+    .a    library file
+.SH SEE ALSO
+.BR octave (1).
+.RE
+.SH AUTHOR
+John W. Eaton <jwe at octave.org>
+
+This manual page was contributed by Dirk Eddelbuettel
+<edd at debian.org> for the Debian GNU/Linux distribution but 
+may be used by others.
diff --git a/doc/interpreter/munge-texi.cc b/doc/interpreter/munge-texi.cc
new file mode 100644
index 0000000..23024ab
--- /dev/null
+++ b/doc/interpreter/munge-texi.cc
@@ -0,0 +1,334 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2003, 2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if defined (__DECCXX)
+#define __USE_STD_IOSTREAM
+#endif
+
+#include <cctype>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <map>
+
+#include <cstdlib>
+#include <cstring>
+
+static const char doc_delim = '';
+
+static std::map<std::string, std::string> help_text;
+
+static void
+fatal (const std::string& msg)
+{
+  std::cerr << msg << "\n";
+  exit (1);
+}
+
+static void
+usage (void)
+{
+  std::cerr << "usage: munge-texi -d DOCSTRING-FILE file ...\n";
+  exit (1);
+}
+
+static std::string
+extract_symbol_name (std::istream& is)
+{
+  std::string symbol_name;
+
+  int c;
+  while ((c = is.get ()) != EOF && c != '\n')
+    symbol_name += (char) c;
+
+  return symbol_name;
+}
+
+static std::string
+extract_docstring (std::istream& is)
+{
+  std::string doc;
+
+  int c;
+  while ((c = is.get ()) != EOF && c != doc_delim)
+    {
+      // Expand @seealso commands to Texinfo references.
+      if (c == '@')
+        {
+          char buf[16];
+          int i = 0;
+          buf[i++] = (char) c;
+          
+          if ((   buf[i++] = (char) is.get ()) == 's'  
+              && (buf[i++] = (char) is.get ()) == 'e'
+              && (buf[i++] = (char) is.get ()) == 'e'
+              && (buf[i++] = (char) is.get ()) == 'a'
+              && (buf[i++] = (char) is.get ()) == 'l'
+              && (buf[i++] = (char) is.get ()) == 's'
+              && (buf[i++] = (char) is.get ()) == 'o'
+              && (buf[i++] = (char) is.get ()) == '{')
+            {
+              doc += "@seealso{";
+              
+              bool first = true;
+              
+              // process @seealso parameters
+              while ((c = is.get ()) != EOF
+                     && c != doc_delim
+                     && c != '}') 
+                {
+                  // ignore whitespace and delimiters
+                  while (   c == ' ' 
+                         || c == '\t'
+                         || c == '\r'
+                         || c == '\n'
+                         || c == ',')
+                    {
+                      c = is.get ();
+                    }
+                    
+                  // test for end of @seealso
+                  if (c == '}') 
+                    break;
+                  
+                  // get function name
+	          std::string function_name;
+                  do 
+                    function_name += (char) c;
+                  while ((c = is.get ()) != EOF
+                          && c != doc_delim
+                          && c != ' '
+                          && c != '\t'
+                          && c != '\r'
+                          && c != '\n'
+                          && c != ','
+                          && c != '}');
+                  if (first)
+                    first = false;
+                  else
+                    doc += ", ";
+
+                  doc += "@ref{doc-" + function_name + ",,"
+		    + function_name + "}";
+
+                  // test for end of @seealso
+                  if (c == '}') 
+                    break;
+                }
+              if (c == '}')
+                doc += (char) c;
+            }
+          else
+            {
+              for (int j = 0; j < i; j++)
+                doc += buf[j];
+            }
+        }
+      else
+        doc += (char) c;
+    }
+  return doc;
+}
+
+static void
+skip_comments (std::ifstream& is)
+{
+  int c;
+
+  bool in_comment = false;
+
+  while ((c = is.get ()) != EOF)
+    {
+      if (c == '#')
+	in_comment = true;
+      else if (c == '\n')
+	in_comment = false;
+      else if (! (in_comment || ::isspace (c)))
+	{
+	  is.putback (c);
+	  break;
+	}
+    }
+}
+
+static void
+process_doc_file (const std::string& fname)
+{
+  std::ifstream infile (fname.c_str ());
+
+  if (infile)
+    {
+      skip_comments (infile);
+
+      if (infile.get () != doc_delim)
+	fatal ("invalid doc file format");
+
+      std::string symbol_name;
+
+      do
+	{
+	  symbol_name = extract_symbol_name (infile);
+
+	  if (! symbol_name.empty ())
+	    {
+	      std::string doc_string = extract_docstring (infile);
+
+	      if (help_text.find (symbol_name) != help_text.end ())
+		std::cerr << "ignoring duplicate entry for "
+			  << symbol_name << "\n";
+	      else
+		help_text[symbol_name] = doc_string;
+	    }
+	}
+      while (! symbol_name.empty ());
+    }
+  else
+    fatal ("unable to open docfile");
+}
+
+static void
+process_texi_input_file (std::istream& is, std::ostream& os)
+{
+  os << "@c DO NOT EDIT!  Generated automatically by munge-texi.\n\n";
+
+  bool bol = true;
+
+  int c;
+  while ((c = is.get ()) != EOF)
+    {
+      if (bol)
+	{
+	  if (c == '@')
+	    {
+	      std::string symbol_name;
+
+	      char buf[16];
+	      int i = 0;
+	      buf[i++] = (char) c;
+
+	      if ((   buf[i++] = (char) is.get ()) == 'D'
+		  && (buf[i++] = (char) is.get ()) == 'O'
+		  && (buf[i++] = (char) is.get ()) == 'C'
+		  && (buf[i++] = (char) is.get ()) == 'S'
+		  && (buf[i++] = (char) is.get ()) == 'T'
+		  && (buf[i++] = (char) is.get ()) == 'R'
+		  && (buf[i++] = (char) is.get ()) == 'I'
+		  && (buf[i++] = (char) is.get ()) == 'N'
+		  && (buf[i++] = (char) is.get ()) == 'G'
+		  && (buf[i++] = (char) is.get ()) == '(')
+		{
+		  while ((c = is.get ()) != EOF && c != ')')
+		    symbol_name += (char) c;
+
+		  if (is.eof ())
+		    fatal ("end of file while reading @DOCSTRING command");
+		  else
+		    {
+		      std::string doc_string = help_text[symbol_name];
+
+		      size_t len = doc_string.length ();
+
+		      int j = 0;
+
+		      // If there is a leading comment with the file
+		      // name, copy it to the output.
+		      if (len > 1
+			  && doc_string[j] == '@'
+			  && doc_string[j+1] == 'c')
+			{
+			  j = 2;
+			  while (doc_string[j++] != '\n')
+			    /* find eol */;
+
+			  os << doc_string.substr (0, j);
+			}
+
+		      while (doc_string[j] == ' ')
+			j++;
+
+		      if (doc_string.substr (j, 15) == "-*- texinfo -*-")
+			{
+			  j += 15;
+
+			  while (isspace (doc_string[j]))
+			    j++;
+
+			  // Make `see also' references in functions
+			  // possible using @anchor{TAG} (new with
+			  // Texinfo 4.0).
+
+			  os << "@anchor{doc-" << symbol_name << "}\n";
+
+			  os << doc_string.substr (j);
+			}
+		      else
+			os << doc_string;
+		    }
+		}
+	      else
+		{
+		  buf[i] = '\0';
+		  os << buf;
+
+		  if (buf[i - 1] == '\n')
+		    bol = true;
+		}
+	    }
+	  else
+	    os.put ((char) c);
+	}
+      else
+	{
+	  if (c == '\n')
+	    bol = true;
+
+	  os.put ((char) (c));
+	}
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  while (*++argv)
+    {
+      if (! strcmp (*argv, "-d"))
+	{
+	  if (*++argv)
+	    process_doc_file (*argv);
+	  else
+	    usage ();
+	}
+      else
+	break;
+    }
+
+  process_texi_input_file (std::cin, std::cout);
+
+  return 0;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/doc/interpreter/nonlin.texi b/doc/interpreter/nonlin.texi
new file mode 100644
index 0000000..83d0a95
--- /dev/null
+++ b/doc/interpreter/nonlin.texi
@@ -0,0 +1,287 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Nonlinear Equations
+ at chapter Nonlinear Equations
+ at cindex nonlinear equations
+ at cindex equations, nonlinear
+
+Octave can solve sets of nonlinear equations of the form
+ at tex
+$$
+ f (x) = 0
+$$
+ at end tex
+ at ifnottex
+
+ at example
+F (x) = 0
+ at end example
+ at end ifnottex
+
+ at noindent
+using the function @code{fsolve}, which is based on the @sc{Minpack}
+subroutine @code{hybrd}.  This is an iterative technique so a starting
+point will have to be provided.  This also has the consequence that
+convergence is not guaranteed even if a solution exists.
+
+ at c ./optimization/fsolve.m
+ at anchor{doc-fsolve}
+ at deftypefn  {Function File} {} fsolve (@var{fcn}, @var{x0}, @var{options})
+ at deftypefnx {Function File} {[@var{x}, @var{fvec}, @var{info}, @var{output}, @var{fjac}]} = fsolve (@var{fcn}, @dots{})
+Solve a system of nonlinear equations defined by the function @var{fcn}.
+ at var{fcn} should accepts a vector (array) defining the unknown variables,
+and return a vector of left-hand sides of the equations.  Right-hand sides
+are defined to be zeros.
+In other words, this function attempts to determine a vector @var{x} such 
+that @code{@var{fcn} (@var{x})} gives (approximately) all zeros.
+ at var{x0} determines a starting guess.  The shape of @var{x0} is preserved
+in all calls to @var{fcn}, but otherwise it is treated as a column vector.
+ at var{options} is a structure specifying additional options.
+Currently, @code{fsolve} recognizes these options:
+ at code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
+ at code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"}, 
+ at code{"Jacobian"}, @code{"Updating"} and @code{"ComplexEqn"}.
+
+If @code{"Jacobian"} is @code{"on"}, it specifies that @var{fcn},
+called with 2 output arguments, also returns the Jacobian matrix
+of right-hand sides at the requested point.  @code{"TolX"} specifies
+the termination tolerance in the unknown variables, while 
+ at code{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
+for both @code{"TolX"} and @code{"TolFun"}.
+If @code{"Updating"} is "on", the function will attempt to use Broyden
+updates to update the Jacobian, in order to reduce the amount of jacobian
+calculations.
+If your user function always calculates the Jacobian (regardless of number
+of output arguments), this option provides no advantage and should be set to
+false.
+
+ at code{"ComplexEqn"} is @code{"on"}, @code{fsolve} will attempt to solve
+complex equations in complex variables, assuming that the equations possess a
+complex derivative (i.e., are holomorphic).  If this is not what you want, 
+should unpack the real and imaginary parts of the system to get a real
+system.
+
+For description of the other options, see @code{optimset}.
+
+On return, @var{fval} contains the value of the function @var{fcn}
+evaluated at @var{x}, and @var{info} may be one of the following values:
+
+ at table @asis
+ at item 1
+Converged to a solution point.  Relative residual error is less than specified
+by TolFun.
+ at item 2
+Last relative step size was less that TolX.
+ at item 3
+Last relative decrease in residual was less than TolF. 
+ at item 0
+Iteration limit exceeded.
+ at item -3
+The trust region radius became excessively small. 
+ at end table
+
+Note: If you only have a single nonlinear equation of one variable, using 
+ at code{fzero} is usually a much better idea.
+ at seealso{@ref{doc-fzero,,fzero}, @ref{doc-optimset,,optimset}}
+
+Note about user-supplied jacobians:
+As an inherent property of the algorithm, jacobian is always requested for a
+solution vector whose residual vector is already known, and it is the last
+accepted successful step.  Often this will be one of the last two calls, but
+not always.  If the savings by reusing intermediate results from residual
+calculation in jacobian calculation are significant, the best strategy is to
+employ OutputFcn: After a vector is evaluated for residuals, if OutputFcn is
+called with that vector, then the intermediate results should be saved for
+future jacobian evaluation, and should be kept until a jacobian evaluation
+is requested or until outputfcn is called with a different vector, in which
+case they should be dropped in favor of this most recent vector.  A short
+example how this can be achieved follows:
+
+ at example
+function [fvec, fjac] = user_func (x, optimvalues, state)
+persistent sav = [], sav0 = [];
+if (nargin == 1)
+  ## evaluation call
+  if (nargout == 1)
+    sav0.x = x; # mark saved vector
+    ## calculate fvec, save results to sav0.
+  elseif (nargout == 2)
+    ## calculate fjac using sav.
+  endif
+else
+  ## outputfcn call.
+  if (all (x == sav0.x))
+    sav = sav0;
+  endif
+  ## maybe output iteration status, etc.
+endif
+endfunction
+
+ @dots{}.
+
+fsolve (@@user_func, x0, optimset ("OutputFcn", @@user_func, @dots{}))
+ at end example
+
+ at end deftypefn
+
+
+Here is a complete example.  To solve the set of equations
+ at tex
+$$
+ \eqalign{-2x^2 + 3xy + 4\sin(y) - 6 &= 0\cr
+           3x^2 - 2xy^2 + 3\cos(x) + 4 &= 0}
+$$
+ at end tex
+ at ifinfo
+
+ at example
+ at group
+-2x^2 + 3xy   + 4 sin(y) = 6
+ 3x^2 - 2xy^2 + 3 cos(x) = -4
+ at end group
+ at end example
+ at end ifinfo
+
+ at noindent
+you first need to write a function to compute the value of the given
+function.  For example:
+
+ at example
+ at group
+function y = f (x)
+  y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
+  y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
+endfunction
+ at end group
+ at end example
+
+Then, call @code{fsolve} with a specified initial condition to find the
+roots of the system of equations.  For example, given the function
+ at code{f} defined above,
+
+ at example
+[x, fval, info] = fsolve (@@f, [1; 2])
+ at end example
+
+ at noindent
+results in the solution
+
+ at example
+ at group
+x =
+
+  0.57983
+  2.54621
+
+fval =
+
+  -5.7184e-10
+   5.5460e-10
+
+info = 1
+ at end group
+ at end example
+
+ at noindent
+A value of @code{info = 1} indicates that the solution has converged.
+
+The function @code{perror} may be used to print English messages
+corresponding to the numeric error codes.  For example,
+
+ at example
+ at group
+perror ("fsolve", 1)
+     @print{} solution converged to requested tolerance
+ at end group
+ at end example
+
+When no Jacobian is supplied (as in the example above) it is approximated
+numerically.  This requires more function evaluations, and hence is
+less efficient.  In the example above we could compute the Jacobian 
+analytically as
+
+ at iftex
+ at tex
+$$
+\left[\matrix{ {\partial f_1 \over \partial x_1} &
+               {\partial f_1 \over \partial x_2} \cr
+               {\partial f_2 \over \partial x_1} &
+               {\partial f_2 \over \partial x_2} \cr}\right] =
+\left[\matrix{ 3 x_2 - 4 x_1                  &
+               4 \cos(x_2) + 3 x_1            \cr
+               -2 x_2^2 - 3 \sin(x_1) + 6 x_1 &
+               -4 x_1 x_2                     \cr }\right]
+$$
+ at end tex
+and compute it with the following Octave function
+ at end iftex
+
+ at example
+ at group
+function J = jacobian(x)
+  J(1,1) =  3*x(2) - 4*x(1);
+  J(1,2) =  4*cos(x(2)) + 3*x(1);
+  J(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
+  J(2,2) = -4*x(1)*x(2);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+The Jacobian can then be used with the following call to @code{fsolve}:
+
+ at example
+[x, fval, info] = fsolve (@{@@f, @@jacobian@}, [1; 2]);
+ at end example
+
+ at noindent
+which gives the same solution as before.
+
+ at c ./optimization/fzero.m
+ at anchor{doc-fzero}
+ at deftypefn {Function File} {[@var{x}, @var{fval}, @var{info}, @var{output}] =} fzero (@var{fun}, @var{x0}, @var{options})
+Find a zero point of a univariate function.  @var{fun} should be a function
+handle or name.  @var{x0} specifies a starting point.  @var{options} is a
+structure specifying additional options.  Currently, @code{fzero}
+recognizes these options: @code{"FunValCheck"}, @code{"OutputFcn"},
+ at code{"TolX"}, @code{"MaxIter"}, @code{"MaxFunEvals"}. 
+For description of these options, see @ref{doc-optimset,,optimset}.
+
+On exit, the function returns @var{x}, the approximate zero point
+and @var{fval}, the function value thereof.
+ at var{info} is an exit flag that can have these values:
+ at itemize
+ at item 1
+The algorithm converged to a solution.
+ at item 0
+Maximum number of iterations or function evaluations has been exhausted.
+ at item -1
+The algorithm has been terminated from user output function.
+ at item -2 
+A general unexpected error.
+ at item -3
+A non-real value encountered.
+ at item -4
+A NaN value encountered.
+ at end itemize
+ at seealso{@ref{doc-optimset,,optimset}, @ref{doc-fsolve,,fsolve}} 
+ at end deftypefn
+
diff --git a/doc/interpreter/nonlin.txi b/doc/interpreter/nonlin.txi
new file mode 100644
index 0000000..610370c
--- /dev/null
+++ b/doc/interpreter/nonlin.txi
@@ -0,0 +1,157 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Nonlinear Equations
+ at chapter Nonlinear Equations
+ at cindex nonlinear equations
+ at cindex equations, nonlinear
+
+Octave can solve sets of nonlinear equations of the form
+ at tex
+$$
+ f (x) = 0
+$$
+ at end tex
+ at ifnottex
+
+ at example
+F (x) = 0
+ at end example
+ at end ifnottex
+
+ at noindent
+using the function @code{fsolve}, which is based on the @sc{Minpack}
+subroutine @code{hybrd}.  This is an iterative technique so a starting
+point will have to be provided.  This also has the consequence that
+convergence is not guaranteed even if a solution exists.
+
+ at DOCSTRING(fsolve)
+
+Here is a complete example.  To solve the set of equations
+ at tex
+$$
+ \eqalign{-2x^2 + 3xy + 4\sin(y) - 6 &= 0\cr
+           3x^2 - 2xy^2 + 3\cos(x) + 4 &= 0}
+$$
+ at end tex
+ at ifinfo
+
+ at example
+ at group
+-2x^2 + 3xy   + 4 sin(y) = 6
+ 3x^2 - 2xy^2 + 3 cos(x) = -4
+ at end group
+ at end example
+ at end ifinfo
+
+ at noindent
+you first need to write a function to compute the value of the given
+function.  For example:
+
+ at example
+ at group
+function y = f (x)
+  y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
+  y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
+endfunction
+ at end group
+ at end example
+
+Then, call @code{fsolve} with a specified initial condition to find the
+roots of the system of equations.  For example, given the function
+ at code{f} defined above,
+
+ at example
+[x, fval, info] = fsolve (@@f, [1; 2])
+ at end example
+
+ at noindent
+results in the solution
+
+ at example
+ at group
+x =
+
+  0.57983
+  2.54621
+
+fval =
+
+  -5.7184e-10
+   5.5460e-10
+
+info = 1
+ at end group
+ at end example
+
+ at noindent
+A value of @code{info = 1} indicates that the solution has converged.
+
+The function @code{perror} may be used to print English messages
+corresponding to the numeric error codes.  For example,
+
+ at example
+ at group
+perror ("fsolve", 1)
+     @print{} solution converged to requested tolerance
+ at end group
+ at end example
+
+When no Jacobian is supplied (as in the example above) it is approximated
+numerically.  This requires more function evaluations, and hence is
+less efficient.  In the example above we could compute the Jacobian 
+analytically as
+
+ at iftex
+ at tex
+$$
+\left[\matrix{ {\partial f_1 \over \partial x_1} &
+               {\partial f_1 \over \partial x_2} \cr
+               {\partial f_2 \over \partial x_1} &
+               {\partial f_2 \over \partial x_2} \cr}\right] =
+\left[\matrix{ 3 x_2 - 4 x_1                  &
+               4 \cos(x_2) + 3 x_1            \cr
+               -2 x_2^2 - 3 \sin(x_1) + 6 x_1 &
+               -4 x_1 x_2                     \cr }\right]
+$$
+ at end tex
+and compute it with the following Octave function
+ at end iftex
+
+ at example
+ at group
+function J = jacobian(x)
+  J(1,1) =  3*x(2) - 4*x(1);
+  J(1,2) =  4*cos(x(2)) + 3*x(1);
+  J(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
+  J(2,2) = -4*x(1)*x(2);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+The Jacobian can then be used with the following call to @code{fsolve}:
+
+ at example
+[x, fval, info] = fsolve (@{@@f, @@jacobian@}, [1; 2]);
+ at end example
+
+ at noindent
+which gives the same solution as before.
+
+ at DOCSTRING(fzero)
diff --git a/doc/interpreter/numbers.texi b/doc/interpreter/numbers.texi
new file mode 100644
index 0000000..9d90309
--- /dev/null
+++ b/doc/interpreter/numbers.texi
@@ -0,0 +1,1357 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Numeric Data Types
+ at chapter Numeric Data Types
+ at cindex numeric constant
+ at cindex numeric value
+
+A @dfn{numeric constant} may be a scalar, a vector, or a matrix, and it
+may contain complex values.
+
+The simplest form of a numeric constant, a scalar, is a single number
+that can be an integer, a decimal fraction, a number in scientific
+(exponential) notation, or a complex number.  Note that by default numeric
+constants are represented within Octave in double-precision floating
+point format (complex constants are stored as pairs of double-precision
+floating point values).  It is however possible to represent real
+integers as described in @ref{Integer Data Types}.  Here are some
+examples of real-valued numeric constants, which all have the same
+value:
+
+ at example
+ at group
+105
+1.05e+2
+1050e-1
+ at end group
+ at end example
+
+To specify complex constants, you can write an expression of the form
+
+ at example
+ at group
+3 + 4i
+3.0 + 4.0i
+0.3e1 + 40e-1i
+ at end group
+ at end example
+
+ at noindent
+all of which are equivalent.  The letter @samp{i} in the previous example
+stands for the pure imaginary constant, defined as
+ at tex
+  $\sqrt{-1}$.
+ at end tex
+ at ifnottex
+  @code{sqrt (-1)}.
+ at end ifnottex
+
+For Octave to recognize a value as the imaginary part of a complex
+constant, a space must not appear between the number and the @samp{i}.
+If it does, Octave will print an error message, like this:
+
+ at example
+ at group
+octave:13> 3 + 4 i
+
+parse error:
+
+  syntax error
+
+>>> 3 + 4 i
+          ^
+ at end group
+ at end example
+
+ at noindent
+You may also use @samp{j}, @samp{I}, or @samp{J} in place of the
+ at samp{i} above.  All four forms are equivalent.
+
+ at c ov-re-mat.cc
+ at anchor{doc-double}
+ at deftypefn {Built-in Function} {} double (@var{x})
+Convert @var{x} to double precision type.
+ at seealso{@ref{doc-single,,single}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-complex}
+ at deftypefn  {Built-in Function} {} complex (@var{x})
+ at deftypefnx {Built-in Function} {} complex (@var{re}, @var{im})
+Return a complex result from real arguments.  With 1 real argument @var{x},
+return the complex result @code{@var{x} + 0i}.  With 2 real arguments,
+return the complex result @code{@var{re} + @var{im}}.  @code{complex} can
+often be more convenient than expressions such as @code{a + i*b}.
+For example:
+
+ at example
+complex ([1, 2], [3, 4])
+ at result{}
+   1 + 3i   2 + 4i
+ at end example
+ at seealso{@ref{doc-real,,real}, @ref{doc-imag,,imag}, @ref{doc-iscomplex,,iscomplex}}
+ at end deftypefn
+
+
+ at menu
+* Matrices::
+* Ranges::
+* Single Precision Data Types::
+* Integer Data Types::
+* Bit Manipulations::
+* Logical Values:: 
+* Promotion and Demotion of Data Types::
+* Predicates for Numeric Objects::  
+ at end menu
+
+ at node Matrices
+ at section Matrices
+ at cindex matrices
+
+ at opindex [
+ at opindex ]
+ at opindex ;
+ at opindex ,
+
+It is easy to define a matrix of values in Octave.  The size of the
+matrix is determined automatically, so it is not necessary to explicitly
+state the dimensions.  The expression
+
+ at example
+a = [1, 2; 3, 4]
+ at end example
+
+ at noindent
+results in the matrix
+ at tex
+$$ a = \left[ \matrix{ 1 & 2 \cr 3 & 4 } \right] $$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+
+        /      \
+        | 1  2 |
+  a  =  |      |
+        | 3  4 |
+        \      /
+
+ at end group
+ at end example
+ at end ifnottex
+
+Elements of a matrix may be arbitrary expressions, provided that the
+dimensions all make sense when combining the various pieces.  For
+example, given the above matrix, the expression
+
+ at example
+[ a, a ]
+ at end example
+
+ at noindent
+produces the matrix
+
+ at example
+ at group
+ans =
+
+  1  2  1  2
+  3  4  3  4
+ at end group
+ at end example
+
+ at noindent
+but the expression
+
+ at example
+[ a, 1 ]
+ at end example
+
+ at noindent
+produces the error
+
+ at example
+error: number of rows must match (1 != 2) near line 13, column 6
+ at end example
+
+ at noindent
+(assuming that this expression was entered as the first thing on line
+13, of course).
+
+Inside the square brackets that delimit a matrix expression, Octave
+looks at the surrounding context to determine whether spaces and newline
+characters should be converted into element and row separators, or
+simply ignored, so an expression like
+
+ at example
+ at group
+a = [ 1 2
+      3 4 ]
+ at end group
+ at end example
+
+ at noindent
+will work.  However, some possible sources of confusion remain.  For
+example, in the expression
+
+ at example
+[ 1 - 1 ]
+ at end example
+
+ at noindent
+the @samp{-} is treated as a binary operator and the result is the
+scalar 0, but in the expression
+
+ at example
+[ 1 -1 ]
+ at end example
+
+ at noindent
+the @samp{-} is treated as a unary operator and the result is the
+vector @code{[ 1, -1 ]}.  Similarly, the expression
+
+ at example
+[ sin (pi) ]
+ at end example
+
+ at noindent
+will be parsed as
+
+ at example
+[ sin, (pi) ]
+ at end example
+
+ at noindent
+and will result in an error since the @code{sin} function will be
+called with no arguments.  To get around this, you must omit the space
+between @code{sin} and the opening parenthesis, or enclose the
+expression in a set of parentheses:
+
+ at example
+[ (sin (pi)) ]
+ at end example
+
+Whitespace surrounding the single quote character (@samp{'}, used as a
+transpose operator and for delimiting character strings) can also cause
+confusion.  Given @code{a = 1}, the expression
+
+ at example
+[ 1 a' ]
+ at end example
+
+ at noindent
+results in the single quote character being treated as a
+transpose operator and the result is the vector @code{[ 1, 1 ]}, but the
+expression
+
+ at example
+[ 1 a ' ]
+ at end example
+
+ at noindent
+produces the error message
+
+ at example
+ at group
+parse error:
+
+  syntax error
+
+>>> [ 1 a ' ]
+              ^
+ at end group
+ at end example
+
+ at noindent
+because not doing so would cause trouble when parsing the valid expression
+
+ at example
+[ a 'foo' ]
+ at end example
+
+For clarity, it is probably best to always use commas and semicolons to
+separate matrix elements and rows.
+
+When you type a matrix or the name of a variable whose value is a
+matrix, Octave responds by printing the matrix in with neatly aligned
+rows and columns.  If the rows of the matrix are too large to fit on the
+screen, Octave splits the matrix and displays a header before each
+section to indicate which columns are being displayed.  You can use the
+following variables to control the format of the output.
+
+ at c pr-output.cc
+ at anchor{doc-output_max_field_width}
+ at deftypefn {Built-in Function} {@var{val} =} output_max_field_width ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} output_max_field_width (@var{new_val})
+Query or set the internal variable that specifies the maximum width
+of a numeric output field.
+ at seealso{@ref{doc-format,,format}, @ref{doc-output_precision,,output_precision}}
+ at end deftypefn
+
+
+ at c pr-output.cc
+ at anchor{doc-output_precision}
+ at deftypefn {Built-in Function} {@var{val} =} output_precision ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} output_precision (@var{new_val})
+Query or set the internal variable that specifies the minimum number of
+significant figures to display for numeric output.
+ at seealso{@ref{doc-format,,format}, @ref{doc-output_max_field_width,,output_max_field_width}}
+ at end deftypefn
+
+
+It is possible to achieve a wide range of output styles by using
+different values of @code{output_precision} and
+ at code{output_max_field_width}.  Reasonable combinations can be set using
+the @code{format} function.  @xref{Basic Input and Output}.
+
+ at c pr-output.cc
+ at anchor{doc-split_long_rows}
+ at deftypefn {Built-in Function} {@var{val} =} split_long_rows ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} split_long_rows (@var{new_val})
+Query or set the internal variable that controls whether rows of a matrix
+may be split when displayed to a terminal window.  If the rows are split,
+Octave will display the matrix in a series of smaller pieces, each of
+which can fit within the limits of your terminal width and each set of
+rows is labeled so that you can easily see which columns are currently
+being displayed.  For example:
+
+ at example
+ at group
+octave:13> rand (2,10)
+ans =
+
+ Columns 1 through 6:
+
+  0.75883  0.93290  0.40064  0.43818  0.94958  0.16467
+  0.75697  0.51942  0.40031  0.61784  0.92309  0.40201
+
+ Columns 7 through 10:
+
+  0.90174  0.11854  0.72313  0.73326
+  0.44672  0.94303  0.56564  0.82150
+ at end group
+ at end example
+ at end deftypefn
+
+
+Octave automatically switches to scientific notation when values become
+very large or very small.  This guarantees that you will see several
+significant figures for every value in a matrix.  If you would prefer to
+see all values in a matrix printed in a fixed point format, you can set
+the built-in variable @code{fixed_point_format} to a nonzero value.  But
+doing so is not recommended, because it can produce output that can
+easily be misinterpreted.
+
+ at c pr-output.cc
+ at anchor{doc-fixed_point_format}
+ at deftypefn {Built-in Function} {@var{val} =} fixed_point_format ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} fixed_point_format (@var{new_val})
+Query or set the internal variable that controls whether Octave will
+use a scaled format to print matrix values such that the largest
+element may be written with a single leading digit with the scaling
+factor is printed on the first line of output.  For example,
+
+ at example
+ at group
+octave:1> logspace (1, 7, 5)'
+ans =
+
+  1.0e+07  *
+
+  0.00000
+  0.00003
+  0.00100
+  0.03162
+  1.00000
+ at end group
+ at end example
+
+ at noindent
+Notice that first value appears to be zero when it is actually 1.  For
+this reason, you should be careful when setting
+ at code{fixed_point_format} to a nonzero value.
+ at end deftypefn
+
+
+ at menu
+* Empty Matrices::              
+ at end menu
+
+ at node Empty Matrices
+ at subsection Empty Matrices
+
+A matrix may have one or both dimensions zero, and operations on empty
+matrices are handled as described by Carl de Boor in @cite{An Empty
+Exercise}, SIGNUM, Volume 25, pages 2-6, 1990 and C. N. Nett and W. M.
+Haddad, in @cite{A System-Theoretic Appropriate Realization of the Empty
+Matrix Concept}, IEEE Transactions on Automatic Control, Volume 38,
+Number 5, May 1993.
+ at tex
+Briefly, given a scalar $s$, an $m\times n$ matrix $M_{m\times n}$,
+and an $m\times n$ empty matrix $[\,]_{m\times n}$ (with either one or
+both dimensions equal to zero), the following are true:
+$$
+\eqalign{%
+s \cdot [\,]_{m\times n} = [\,]_{m\times n} \cdot s &= [\,]_{m\times n}\cr
+[\,]_{m\times n} + [\,]_{m\times n} &= [\,]_{m\times n}\cr
+[\,]_{0\times m} \cdot M_{m\times n} &= [\,]_{0\times n}\cr
+M_{m\times n} \cdot [\,]_{n\times 0} &= [\,]_{m\times 0}\cr
+[\,]_{m\times 0} \cdot [\,]_{0\times n} &=  0_{m\times n}}
+$$
+ at end tex
+ at ifnottex
+Briefly, given a scalar @var{s}, an @var{m} by
+ at var{n} matrix @code{M(mxn)}, and an @var{m} by @var{n} empty matrix
+ at code{[](mxn)} (with either one or both dimensions equal to zero), the
+following are true:
+
+ at example
+ at group
+s * [](mxn) = [](mxn) * s = [](mxn)
+
+    [](mxn) + [](mxn) = [](mxn)
+
+    [](0xm) *  M(mxn) = [](0xn)
+
+     M(mxn) * [](nx0) = [](mx0)
+
+    [](mx0) * [](0xn) =  0(mxn)
+ at end group
+ at end example
+ at end ifnottex
+
+By default, dimensions of the empty matrix are printed along with the
+empty matrix symbol, @samp{[]}.  The built-in variable
+ at code{print_empty_dimensions} controls this behavior.
+
+ at c pr-output.cc
+ at anchor{doc-print_empty_dimensions}
+ at deftypefn {Built-in Function} {@var{val} =} print_empty_dimensions ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} print_empty_dimensions (@var{new_val})
+Query or set the internal variable that controls whether the
+dimensions of empty matrices are printed along with the empty matrix
+symbol, @samp{[]}.  For example, the expression
+
+ at example
+zeros (3, 0)
+ at end example
+
+ at noindent
+will print
+
+ at example
+ans = [](3x0)
+ at end example
+ at end deftypefn
+
+
+Empty matrices may also be used in assignment statements as a convenient
+way to delete rows or columns of matrices.
+ at xref{Assignment Ops, ,Assignment Expressions}.
+
+When Octave parses a matrix expression, it examines the elements of the
+list to determine whether they are all constants.  If they are, it
+replaces the list with a single matrix constant.
+
+ at node Ranges
+ at section Ranges
+ at cindex range expressions
+ at cindex expression, range
+
+ at opindex colon
+
+A @dfn{range} is a convenient way to write a row vector with evenly
+spaced elements.  A range expression is defined by the value of the first
+element in the range, an optional value for the increment between
+elements, and a maximum value which the elements of the range will not
+exceed.  The base, increment, and limit are separated by colons (the
+ at samp{:} character) and may contain any arithmetic expressions and
+function calls.  If the increment is omitted, it is assumed to be 1.
+For example, the range
+
+ at example
+1 : 5
+ at end example
+
+ at noindent
+defines the set of values @samp{[ 1, 2, 3, 4, 5 ]}, and the range
+
+ at example
+1 : 3 : 5
+ at end example
+
+ at noindent
+defines the set of values @samp{[ 1, 4 ]}.
+
+Although a range constant specifies a row vector, Octave does @emph{not}
+convert range constants to vectors unless it is necessary to do so.
+This allows you to write a constant like @samp{1 : 10000} without using
+80,000 bytes of storage on a typical 32-bit workstation.
+
+Note that the upper (or lower, if the increment is negative) bound on
+the range is not always included in the set of values, and that ranges
+defined by floating point values can produce surprising results because
+Octave uses floating point arithmetic to compute the values in the
+range.  If it is important to include the endpoints of a range and the
+number of elements is known, you should use the @code{linspace} function
+instead (@pxref{Special Utility Matrices}).
+
+When adding a scalar to a range, subtracting a scalar from it (or subtracting a
+range from a scalar) and multiplying by scalar, Octave will attempt to avoid
+unpacking the range and keep the result as a range, too, if it can determine
+that it is safe to do so.  For instance, doing
+
+ at example
+a = 2*(1:1e7) - 1;
+ at end example
+
+will produce the same result as @samp{1:2:2e7-1}, but without ever forming a
+vector with ten million elements.
+
+Using zero as an increment in the colon notation, as @samp{1:0:1} is not
+allowed, because a division by zero would occur in determining the number of
+range elements.  However, ranges with zero increment (i.e., all elements equal)
+are useful, especially in indexing, and Octave allows them to be constructed
+using the built-in function @dfn{ones}.  Note that because a range must be a row
+vector, @samp{ones (1, 10)} produces a range, while @samp{ones (10, 1)} does not.
+
+When Octave parses a range expression, it examines the elements of the
+expression to determine whether they are all constants.  If they are, it
+replaces the range expression with a single range constant.
+
+ at node Single Precision Data Types
+ at section Single Precision Data Types
+
+Octave includes support for single precision data types, and most of the
+functions in Octave accept single precision values and return single
+precision answers.  A single precision variable is created with the
+ at code{single} function.
+
+ at c ov-flt-re-mat.cc
+ at anchor{doc-single}
+ at deftypefn {Built-in Function} {} single (@var{x})
+Convert @var{x} to single precision type.
+ at seealso{@ref{doc-double,,double}}
+ at end deftypefn
+
+
+for example
+
+ at example
+ at group
+sngl = single (rand (2, 2))
+     @result{} sngl = 
+        0.37569   0.92982
+        0.11962   0.50876
+class (sngl)
+    @result{} single
+ at end group
+ at end example
+
+Many functions can also return single precision values directly.  For
+example
+
+ at example
+ at group
+ones (2, 2, "single")
+zeros (2, 2, "single")
+eye (2, 2,  "single")
+rand (2, 2, "single")
+NaN (2, 2, "single")
+NA (2, 2, "single")
+Inf (2, 2, "single")
+ at end group
+ at end example
+
+ at noindent
+will all return single precision matrices.
+
+ at node Integer Data Types
+ at section Integer Data Types
+
+Octave supports integer matrices as an alternative to using double
+precision.  It is possible to use both signed and unsigned integers
+represented by 8, 16, 32, or 64 bits.  It should be noted that most
+computations require floating point data, meaning that integers will
+often change type when involved in numeric computations.  For this
+reason integers are most often used to store data, and not for
+calculations.
+
+In general most integer matrices are created by casting
+existing matrices to integers.  The following example shows how to cast
+a matrix into 32 bit integers.
+
+ at example
+ at group
+float = rand (2, 2)
+     @result{} float = 0.37569   0.92982
+                0.11962   0.50876
+integer = int32 (float)
+     @result{} integer = 0  1
+                  0  1
+ at end group
+ at end example
+
+ at noindent
+As can be seen, floating point values are rounded to the nearest integer
+when converted.
+
+ at c data.cc
+ at anchor{doc-isinteger}
+ at deftypefn {Built-in Function} {} isinteger (@var{x})
+Return true if @var{x} is an integer object (int8, uint8, int16, etc.).
+Note that @code{isinteger (14)} is false because numeric constants in
+Octave are double precision floating point values.
+ at seealso{@ref{doc-isreal,,isreal}, @ref{doc-isnumeric,,isnumeric}, @ref{doc-class,,class}, @ref{doc-isa,,isa}}
+ at end deftypefn
+
+
+ at c ov-int8.cc
+ at anchor{doc-int8}
+ at deftypefn {Built-in Function} {} int8 (@var{x})
+Convert @var{x} to 8-bit integer type.
+ at end deftypefn
+
+
+ at c ov-uint8.cc
+ at anchor{doc-uint8}
+ at deftypefn {Built-in Function} {} uint8 (@var{x})
+Convert @var{x} to unsigned 8-bit integer type.
+ at end deftypefn
+
+
+ at c ov-int16.cc
+ at anchor{doc-int16}
+ at deftypefn {Built-in Function} {} int16 (@var{x})
+Convert @var{x} to 16-bit integer type.
+ at end deftypefn
+
+
+ at c ov-uint16.cc
+ at anchor{doc-uint16}
+ at deftypefn {Built-in Function} {} uint16 (@var{x})
+Convert @var{x} to unsigned 16-bit integer type.
+ at end deftypefn
+
+
+ at c ov-int32.cc
+ at anchor{doc-int32}
+ at deftypefn {Built-in Function} {} int32 (@var{x})
+Convert @var{x} to 32-bit integer type.
+ at end deftypefn
+
+
+ at c ov-uint32.cc
+ at anchor{doc-uint32}
+ at deftypefn {Built-in Function} {} uint32 (@var{x})
+Convert @var{x} to unsigned 32-bit integer type.
+ at end deftypefn
+
+
+ at c ov-int64.cc
+ at anchor{doc-int64}
+ at deftypefn {Built-in Function} {} int64 (@var{x})
+Convert @var{x} to 64-bit integer type.
+ at end deftypefn
+
+
+ at c ov-uint64.cc
+ at anchor{doc-uint64}
+ at deftypefn {Built-in Function} {} uint64 (@var{x})
+Convert @var{x} to unsigned 64-bit integer type.
+ at end deftypefn
+
+
+ at c bitfcns.cc
+ at anchor{doc-intmax}
+ at deftypefn {Built-in Function} {} intmax (@var{type})
+Return the largest integer that can be represented in an integer type.
+The variable @var{type} can be
+
+ at table @code
+ at item int8
+signed 8-bit integer.
+ at item int16
+signed 16-bit integer.
+ at item int32
+signed 32-bit integer.
+ at item int64
+signed 64-bit integer.
+ at item uint8
+unsigned 8-bit integer.
+ at item uint16
+unsigned 16-bit integer.
+ at item uint32
+unsigned 32-bit integer.
+ at item uint64
+unsigned 64-bit integer.
+ at end table
+
+The default for @var{type} is @code{uint32}.
+ at seealso{@ref{doc-intmin,,intmin}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+ at c bitfcns.cc
+ at anchor{doc-intmin}
+ at deftypefn {Built-in Function} {} intmin (@var{type})
+Return the smallest integer that can be represented in an integer type.
+The variable @var{type} can be
+
+ at table @code
+ at item int8
+signed 8-bit integer.
+ at item int16
+signed 16-bit integer.
+ at item int32
+signed 32-bit integer.
+ at item int64
+signed 64-bit integer.
+ at item uint8
+unsigned 8-bit integer.
+ at item uint16
+unsigned 16-bit integer.
+ at item uint32
+unsigned 32-bit integer.
+ at item uint64
+unsigned 64-bit integer.
+ at end table
+
+The default for @var{type} is @code{uint32}.
+ at seealso{@ref{doc-intmax,,intmax}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/intwarning.m
+ at anchor{doc-intwarning}
+ at deftypefn {Function File} {} intwarning (@var{action})
+ at deftypefnx {Function File} {} intwarning (@var{s})
+ at deftypefnx {Function File} {@var{s} =} intwarning (@dots{})
+Control the state of the warning for integer conversions and math
+operations.
+
+ at table @asis
+ at item "query"
+The state of the Octave integer conversion and math warnings is
+queried.  If there is no output argument, then the state is printed.
+Otherwise it is returned in a structure with the fields "identifier"
+and "state".
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+ at group
+intwarning ("query")
+The state of warning "Octave:int-convert-nan" is "off"
+The state of warning "Octave:int-convert-non-int-val" is "off"
+The state of warning "Octave:int-convert-overflow" is "off"
+The state of warning "Octave:int-math-overflow" is "off"
+ at end group
+ at end smallexample 
+
+ at item "on"
+Turn integer conversion and math warnings "on".  If there is no output
+argument, then nothing is printed.  Otherwise the original state of
+the state of the integer conversion and math warnings is returned in
+a structure array.
+
+ at item "off"
+Turn integer conversion and math warnings "on".  If there is no output
+argument, then nothing is printed.  Otherwise the original state of
+the state of the integer conversion and math warnings is returned in
+a structure array.
+ at end table
+
+The original state of the integer warnings can be restored by passing
+the structure array returned by @code{intwarning} to a later call to
+ at code{intwarning}.  For example
+
+ at example
+ at group
+s = intwarning ("off");
+ at dots{}
+intwarning (s);
+ at end group
+ at end example
+ at seealso{@ref{doc-warning,,warning}}
+ at end deftypefn
+
+
+ at menu
+* Integer Arithmetic::
+ at end menu
+
+ at node Integer Arithmetic
+ at subsection Integer Arithmetic
+
+While many numerical computations can't be carried out in integers,
+Octave does support basic operations like addition and multiplication
+on integers.  The operators @code{+}, @code{-}, @code{.*}, and @code{./}
+work on integers of the same type.  So, it is possible to add two 32 bit
+integers, but not to add a 32 bit integer and a 16 bit integer.
+
+The arithmetic operations on integers are performed by casting the
+integer values to double precision values, performing the operation, and
+then re-casting the values back to the original integer type.  As the
+double precision type of Octave is only capable of representing integers
+with up to 53 bits of precision, it is not possible to perform
+arithmetic with 64 bit integer types.
+
+When doing integer arithmetic one should consider the possibility of
+underflow and overflow.  This happens when the result of the computation
+can't be represented using the chosen integer type.  As an example it is
+not possible to represent the result of @math{10 - 20} when using
+unsigned integers.  Octave makes sure that the result of integer
+computations is the integer that is closest to the true result.  So, the
+result of @math{10 - 20} when using unsigned integers is zero.
+
+When doing integer division Octave will round the result to the nearest
+integer.  This is different from most programming languages, where the
+result is often floored to the nearest integer.  So, the result of
+ at code{int32(5)./int32(8)} is @code{1}.
+
+ at c ./general/idivide.m
+ at anchor{doc-idivide}
+ at deftypefn {Function File} {} idivide (@var{x}, @var{y}, @var{op})
+Integer division with different round rules.  The standard behavior of
+the an integer division such as @code{@var{a} ./ @var{b}} is to round
+the result to the nearest integer.  This is not always the desired
+behavior and @code{idivide} permits integer element-by-element
+division to be performed with different treatment for the fractional
+part of the division as determined by the @var{op} flag.  @var{op} is
+a string with one of the values: 
+
+ at table @asis
+ at item "fix"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+towards zero.
+ at item "round"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+towards the nearest integer.
+ at item "floor"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+downwards.
+ at item "ceil"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+upwards.
+ at end table
+
+ at noindent
+If @var{op} is not given it is assumed that it is @code{"fix"}.
+An example demonstrating these rounding rules is
+
+ at example
+ at group
+idivide (int8 ([-3, 3]), int8 (4), "fix")
+ at result{} int8 ([0, 0])
+idivide (int8 ([-3, 3]), int8 (4), "round")
+ at result{} int8 ([-1, 1])
+idivide (int8 ([-3, 3]), int8 (4), "ceil")
+ at result{} int8 ([0, 1])
+idivide (int8 ([-3, 3]), int8 (4), "floor")
+ at result{} int8 ([-1, 0])
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ldivide,,ldivide}, @ref{doc-rdivide,,rdivide}}
+ at end deftypefn
+
+
+ at node Bit Manipulations
+ at section Bit Manipulations
+
+Octave provides a number of functions for the manipulation of numeric
+values on a bit by bit basis.  The basic functions to set and obtain the
+values of individual bits are @code{bitset} and @code{bitget}.
+
+ at c ./general/bitset.m
+ at anchor{doc-bitset}
+ at deftypefn {Function File} {@var{x} =} bitset (@var{a}, @var{n})
+ at deftypefnx {Function File} {@var{x} =} bitset (@var{a}, @var{n}, @var{v})
+Set or reset bit(s) @var{n} of unsigned integers in @var{a}.
+ at var{v} = 0 resets and @var{v} = 1 sets the bits.
+The lowest significant bit is: @var{n} = 1
+
+ at example
+ at group
+dec2bin (bitset (10, 1))
+ at result{} 1011
+ at end group
+ at end example
+ at seealso{@ref{doc-bitand,,bitand}, @ref{doc-bitor,,bitor}, @ref{doc-bitxor,,bitxor}, @ref{doc-bitget,,bitget}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitshift,,bitshift}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+ at c ./general/bitget.m
+ at anchor{doc-bitget}
+ at deftypefn {Function File} {@var{X} =} bitget (@var{a}, at var{n})
+Return the status of bit(s) @var{n} of unsigned integers in @var{a}
+the lowest significant bit is @var{n} = 1.
+
+ at example
+ at group
+bitget (100, 8:-1:1)
+ at result{} 0  1  1  0  0  1  0  0 
+ at end group
+ at end example
+ at seealso{@ref{doc-bitand,,bitand}, @ref{doc-bitor,,bitor}, @ref{doc-bitxor,,bitxor}, @ref{doc-bitset,,bitset}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitshift,,bitshift}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+The arguments to all of Octave's bitwise operations can be scalar or
+arrays, except for @code{bitcmp}, whose @var{k} argument must a
+scalar.  In the case where more than one argument is an array, then all
+arguments must have the same shape, and the bitwise operator is applied
+to each of the elements of the argument individually.  If at least one
+argument is a scalar and one an array, then the scalar argument is
+duplicated.  Therefore
+
+ at example
+bitget (100, 8:-1:1)
+ at end example
+
+is the same as
+
+ at example
+bitget (100 * ones (1, 8), 8:-1:1)
+ at end example
+
+It should be noted that all values passed to the bit manipulation
+functions of Octave are treated as integers.  Therefore, even though the
+example for @code{bitset} above passes the floating point value
+ at code{10}, it is treated as the bits @code{[1, 0, 1, 0]} rather than the
+bits of the native floating point format representation of @code{10}.
+
+As the maximum value that can be represented by a number is important
+for bit manipulation, particularly when forming masks, Octave supplies
+the function @code{bitmax}.
+
+ at c bitfcns.cc
+ at anchor{doc-bitmax}
+ at deftypefn {Built-in Function} {} bitmax ()
+Return the largest integer that can be represented as a floating point
+value.  On IEEE-754 compatible systems, @code{bitmax} is @code{2^53 - 1}.
+ at end deftypefn
+
+
+This is the double precision version of the functions @code{intmax},
+previously discussed.
+
+Octave also includes the basic bitwise 'and', 'or' and 'exclusive or'
+operators.
+
+ at c bitfcns.cc
+ at anchor{doc-bitand}
+ at deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})
+Return the bitwise AND of non-negative integers.
+ at var{x}, @var{y} must be in the range [0,bitmax]
+ at seealso{@ref{doc-bitor,,bitor}, @ref{doc-bitxor,,bitxor}, @ref{doc-bitset,,bitset}, @ref{doc-bitget,,bitget}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitshift,,bitshift}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+ at c bitfcns.cc
+ at anchor{doc-bitor}
+ at deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})
+Return the bitwise OR of non-negative integers.
+ at var{x}, @var{y} must be in the range [0,bitmax]
+ at seealso{@ref{doc-bitor,,bitor}, @ref{doc-bitxor,,bitxor}, @ref{doc-bitset,,bitset}, @ref{doc-bitget,,bitget}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitshift,,bitshift}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+ at c bitfcns.cc
+ at anchor{doc-bitxor}
+ at deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})
+Return the bitwise XOR of non-negative integers.
+ at var{x}, @var{y} must be in the range [0,bitmax]
+ at seealso{@ref{doc-bitand,,bitand}, @ref{doc-bitor,,bitor}, @ref{doc-bitset,,bitset}, @ref{doc-bitget,,bitget}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitshift,,bitshift}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+The bitwise 'not' operator is a unary operator that performs a logical
+negation of each of the bits of the value.  For this to make sense, the
+mask against which the value is negated must be defined.  Octave's
+bitwise 'not' operator is @code{bitcmp}.
+
+ at c ./general/bitcmp.m
+ at anchor{doc-bitcmp}
+ at deftypefn {Function File} {} bitcmp (@var{a}, @var{k})
+Return the @var{k}-bit complement of integers in @var{a}.  If
+ at var{k} is omitted @code{k = log2 (bitmax) + 1} is assumed.
+
+ at example
+ at group
+bitcmp(7,4)
+ at result{} 8
+dec2bin(11)
+ at result{} 1011
+dec2bin(bitcmp(11, 6))
+ at result{} 110100
+ at end group
+ at end example
+ at seealso{@ref{doc-bitand,,bitand}, @ref{doc-bitor,,bitor}, @ref{doc-bitxor,,bitxor}, @ref{doc-bitset,,bitset}, @ref{doc-bitget,,bitget}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitshift,,bitshift}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+Octave also includes the ability to left-shift and right-shift values bitwise.
+
+ at c bitfcns.cc
+ at anchor{doc-bitshift}
+ at deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})
+ at deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})
+Return a @var{k} bit shift of @var{n}-digit unsigned
+integers in @var{a}.  A positive @var{k} leads to a left shift.
+A negative value to a right shift.  If @var{n} is omitted it defaults
+to log2(bitmax)+1.
+ at var{n} must be in the range [1,log2(bitmax)+1] usually [1,33]
+
+ at example
+ at group
+bitshift (eye (3), 1)
+ at result{}
+ at group
+2 0 0
+0 2 0
+0 0 2
+ at end group
+
+bitshift (10, [-2, -1, 0, 1, 2])
+ at result{} 2   5  10  20  40
+ at c FIXME -- restore this example when third arg is allowed to be an array.
+ at c 
+ at c 
+ at c bitshift ([1, 10], 2, [3,4])
+ at c @result{} 4  8
+ at end group
+ at end example
+ at seealso{@ref{doc-bitand,,bitand}, @ref{doc-bitor,,bitor}, @ref{doc-bitxor,,bitxor}, @ref{doc-bitset,,bitset}, @ref{doc-bitget,,bitget}, @ref{doc-bitcmp,,bitcmp}, @ref{doc-bitmax,,bitmax}}
+ at end deftypefn
+
+
+Bits that are shifted out of either end of the value are lost.  Octave
+also uses arithmetic shifts, where the sign bit of the value is kept
+during a right shift.  For example
+
+ at example
+ at group
+bitshift (-10, -1)
+ at result{} -5
+bitshift (int8 (-1), -1)
+ at result{} -1
+ at end group
+ at end example
+
+Note that @code{bitshift (int8 (-1), -1)} is @code{-1} since the bit
+representation of @code{-1} in the @code{int8} data type is @code{[1, 1,
+1, 1, 1, 1, 1, 1]}.
+
+ at node Logical Values
+ at section Logical Values
+
+Octave has built-in support for logical values, i.e., variables that
+are either @code{true} or @code{false}.  When comparing two variables,
+the result will be a logical value whose value depends on whether or
+not the comparison is true.
+
+The basic logical operations are @code{&}, @code{|}, and @code{!},
+which correspond to ``Logical And'', ``Logical Or'', and ``Logical
+Negation''.  These operations all follow the usual rules of logic.
+
+It is also possible to use logical values as part of standard numerical
+calculations.  In this case @code{true} is converted to @code{1}, and
+ at code{false} to 0, both represented using double precision floating
+point numbers.  So, the result of @code{true*22 - false/6} is @code{22}.
+
+Logical values can also be used to index matrices and cell arrays.
+When indexing with a logical array the result will be a vector containing
+the values corresponding to @code{true} parts of the logical array.
+The following example illustrates this.
+
+ at example
+ at group
+data = [ 1, 2; 3, 4 ];
+idx = (data <= 2);
+data(idx)
+     @result{} ans = [ 1; 2 ]
+ at end group
+ at end example
+
+ at noindent
+Instead of creating the @code{idx} array it is possible to replace
+ at code{data(idx)} with @code{data( data <= 2 )} in the above code.
+
+Logical values can also be constructed by
+casting numeric objects to logical values, or by using the @code{true}
+or @code{false} functions.
+
+ at c ./general/logical.m
+ at anchor{doc-logical}
+ at deftypefn {Function File} {} logical (@var{arg})
+Convert @var{arg} to a logical value.  For example,
+
+ at example
+logical ([-1, 0, 1])
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+[-1, 0, 1] != 0
+ at end example
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-true}
+ at deftypefn {Built-in Function} {} true (@var{x})
+ at deftypefnx {Built-in Function} {} true (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} true (@var{n}, @var{m}, @var{k}, @dots{})
+Return a matrix or N-dimensional array whose elements are all logical 1.
+The arguments are handled the same as the arguments for @code{eye}.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-false}
+ at deftypefn {Built-in Function} {} false (@var{x})
+ at deftypefnx {Built-in Function} {} false (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} false (@var{n}, @var{m}, @var{k}, @dots{})
+Return a matrix or N-dimensional array whose elements are all logical 0.
+The arguments are handled the same as the arguments for @code{eye}.
+ at end deftypefn
+
+
+ at node Promotion and Demotion of Data Types
+ at section Promotion and Demotion of Data Types
+
+Many operators and functions can work with mixed data types.  For example
+
+ at example
+ at group
+uint8 (1) + 1
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+where the above operator works with an 8-bit integer and a double precision
+value and returns an 8-bit integer value.  Note that the type is demoted
+to an 8-bit integer, rather than promoted to a double precision value as
+might be expected.  The reason is that if Octave promoted values in
+expressions like the above with all numerical constants would need to be
+explicitly cast to the appropriate data type like
+
+ at example
+ at group
+uint8 (1) + uint8 (1)
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+which becomes difficult for the user to apply uniformly and might allow
+hard to find bugs to be introduced.  The same applies to single precision
+values where a mixed operation such as
+
+ at example
+ at group
+single (1) + 1
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+returns a single precision value.  The mixed operations that are valid
+and their returned data types are
+
+ at multitable @columnfractions .2 .3 .3 .2
+ at item @tab Mixed Operation @tab Result @tab 
+ at item @tab double OP single @tab single @tab
+ at item @tab double OP integer @tab integer @tab
+ at item @tab double OP char @tab double @tab
+ at item @tab double OP logical @tab double @tab
+ at item @tab single OP integer @tab integer @tab
+ at item @tab single OP char @tab single @tab
+ at item @tab single OP logical @tab single @tab
+ at end multitable
+
+The same logic applies to functions with mixed arguments such as
+
+ at example
+ at group
+min (single (1), 0)
+   @result{} 0
+ at end group
+ at end example
+
+ at noindent
+where the returned value is single precision.
+
+In the case of mixed type indexed assignments, the type is not
+changed.  For example
+
+ at example
+ at group
+x = ones (2, 2);
+x (1, 1) = single (2)
+    @result{} x = 2   1
+           1   1
+ at end group
+ at end example
+
+ at noindent
+where @code{x} remains of the double precision type. 
+
+ at node Predicates for Numeric Objects
+ at section Predicates for Numeric Objects
+
+Since the type of a variable may change during the execution of a
+program, it can be necessary to do type checking at run-time.  Doing this
+also allows you to change the behavior of a function depending on the
+type of the input.  As an example, this naive implementation of @code{abs}
+returns the absolute value of the input if it is a real number, and the
+length of the input if it is a complex number.
+
+ at example
+ at group
+function a = abs (x)
+  if (isreal (x))
+    a = sign (x) .* x;
+  elseif (iscomplex (x))
+    a = sqrt (real(x).^2 + imag(x).^2);
+  endif
+endfunction
+ at end group
+ at end example
+
+The following functions are available for determining the type of a
+variable.
+
+ at c data.cc
+ at anchor{doc-isnumeric}
+ at deftypefn {Built-in Function} {} isnumeric (@var{x})
+Return nonzero if @var{x} is a numeric object.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-isreal}
+ at deftypefn {Built-in Function} {} isreal (@var{x})
+Return true if @var{x} is a real-valued numeric object.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-isfloat}
+ at deftypefn {Built-in Function} {} isfloat (@var{x})
+Return true if @var{x} is a floating-point numeric object.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-iscomplex}
+ at deftypefn {Built-in Function} {} iscomplex (@var{x})
+Return true if @var{x} is a complex-valued numeric object.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-ismatrix}
+ at deftypefn {Built-in Function} {} ismatrix (@var{a})
+Return 1 if @var{a} is a matrix.  Otherwise, return 0.
+ at end deftypefn
+
+
+ at c ./general/isvector.m
+ at anchor{doc-isvector}
+ at deftypefn {Function File} {} isvector (@var{a})
+Return 1 if @var{a} is a vector.  Otherwise, return 0.
+ at seealso{@ref{doc-size,,size}, @ref{doc-rows,,rows}, @ref{doc-columns,,columns}, @ref{doc-length,,length}, @ref{doc-isscalar,,isscalar}, @ref{doc-ismatrix,,ismatrix}}
+ at end deftypefn
+
+
+ at c ./general/isscalar.m
+ at anchor{doc-isscalar}
+ at deftypefn {Function File} {} isscalar (@var{a})
+Return 1 if @var{a} is a scalar.  Otherwise, return 0.
+ at seealso{@ref{doc-size,,size}, @ref{doc-rows,,rows}, @ref{doc-columns,,columns}, @ref{doc-length,,length}, @ref{doc-isscalar,,isscalar}, @ref{doc-ismatrix,,ismatrix}}
+ at end deftypefn
+
+
+ at c ./general/issquare.m
+ at anchor{doc-issquare}
+ at deftypefn {Function File} {} issquare (@var{x})
+If @var{x} is a square matrix, then return the dimension of @var{x}.
+Otherwise, return 0.
+ at seealso{@ref{doc-size,,size}, @ref{doc-rows,,rows}, @ref{doc-columns,,columns}, @ref{doc-length,,length}, @ref{doc-ismatrix,,ismatrix}, @ref{doc-isscalar,,isscalar}, @ref{doc-isvector,,isvector}}
+ at end deftypefn
+
+
+ at c ./general/issymmetric.m
+ at anchor{doc-issymmetric}
+ at deftypefn {Function File} {} issymmetric (@var{x}, @var{tol})
+If @var{x} is symmetric within the tolerance specified by @var{tol},
+then return the dimension of @var{x}.  Otherwise, return 0.  If
+ at var{tol} is omitted, use a tolerance equal to the machine precision.
+Matrix @var{x} is considered symmetric if
+ at code{norm (@var{x} - @var{x}.', inf) / norm (@var{x}, inf) < @var{tol}}.
+ at seealso{@ref{doc-size,,size}, @ref{doc-rows,,rows}, @ref{doc-columns,,columns}, @ref{doc-length,,length}, @ref{doc-ismatrix,,ismatrix}, @ref{doc-isscalar,,isscalar}, @ref{doc-issquare,,issquare}, @ref{doc-isvector,,isvector}}
+ at end deftypefn
+
+
+ at c ./general/isdefinite.m
+ at anchor{doc-isdefinite}
+ at deftypefn {Function File} {} isdefinite (@var{x}, @var{tol})
+Return 1 if @var{x} is symmetric positive definite within the
+tolerance specified by @var{tol} or 0 if @var{x} is symmetric
+positive semidefinite.  Otherwise, return -1.  If @var{tol}
+is omitted, use a tolerance equal to 100 times the machine precision.
+ at seealso{@ref{doc-issymmetric,,issymmetric}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-islogical}
+ at deftypefn {Built-in Function} {} islogical (@var{x})
+Return true if @var{x} is a logical object.
+ at end deftypefn
+
+
+ at c ./specfun/isprime.m
+ at anchor{doc-isprime}
+ at deftypefn {Function File} {} isprime (@var{n})
+
+Return true if @var{n} is a prime number, false otherwise.
+
+Something like the following is much faster if you need to test a lot
+of small numbers:
+
+ at example
+   @var{t} = ismember (@var{n}, primes (max (@var{n} (:))));
+ at end example
+
+If max(n) is very large, then you should be using special purpose 
+factorization code.
+
+ at seealso{@ref{doc-primes,,primes}, @ref{doc-factor,,factor}, @ref{doc-gcd,,gcd}, @ref{doc-lcm,,lcm}}
+ at end deftypefn
+
diff --git a/doc/interpreter/numbers.txi b/doc/interpreter/numbers.txi
new file mode 100644
index 0000000..47b537d
--- /dev/null
+++ b/doc/interpreter/numbers.txi
@@ -0,0 +1,809 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Numeric Data Types
+ at chapter Numeric Data Types
+ at cindex numeric constant
+ at cindex numeric value
+
+A @dfn{numeric constant} may be a scalar, a vector, or a matrix, and it
+may contain complex values.
+
+The simplest form of a numeric constant, a scalar, is a single number
+that can be an integer, a decimal fraction, a number in scientific
+(exponential) notation, or a complex number.  Note that by default numeric
+constants are represented within Octave in double-precision floating
+point format (complex constants are stored as pairs of double-precision
+floating point values).  It is however possible to represent real
+integers as described in @ref{Integer Data Types}.  Here are some
+examples of real-valued numeric constants, which all have the same
+value:
+
+ at example
+ at group
+105
+1.05e+2
+1050e-1
+ at end group
+ at end example
+
+To specify complex constants, you can write an expression of the form
+
+ at example
+ at group
+3 + 4i
+3.0 + 4.0i
+0.3e1 + 40e-1i
+ at end group
+ at end example
+
+ at noindent
+all of which are equivalent.  The letter @samp{i} in the previous example
+stands for the pure imaginary constant, defined as
+ at tex
+  $\sqrt{-1}$.
+ at end tex
+ at ifnottex
+  @code{sqrt (-1)}.
+ at end ifnottex
+
+For Octave to recognize a value as the imaginary part of a complex
+constant, a space must not appear between the number and the @samp{i}.
+If it does, Octave will print an error message, like this:
+
+ at example
+ at group
+octave:13> 3 + 4 i
+
+parse error:
+
+  syntax error
+
+>>> 3 + 4 i
+          ^
+ at end group
+ at end example
+
+ at noindent
+You may also use @samp{j}, @samp{I}, or @samp{J} in place of the
+ at samp{i} above.  All four forms are equivalent.
+
+ at DOCSTRING(double)
+
+ at DOCSTRING(complex)
+
+ at menu
+* Matrices::
+* Ranges::
+* Single Precision Data Types::
+* Integer Data Types::
+* Bit Manipulations::
+* Logical Values:: 
+* Promotion and Demotion of Data Types::
+* Predicates for Numeric Objects::  
+ at end menu
+
+ at node Matrices
+ at section Matrices
+ at cindex matrices
+
+ at opindex [
+ at opindex ]
+ at opindex ;
+ at opindex ,
+
+It is easy to define a matrix of values in Octave.  The size of the
+matrix is determined automatically, so it is not necessary to explicitly
+state the dimensions.  The expression
+
+ at example
+a = [1, 2; 3, 4]
+ at end example
+
+ at noindent
+results in the matrix
+ at tex
+$$ a = \left[ \matrix{ 1 & 2 \cr 3 & 4 } \right] $$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+
+        /      \
+        | 1  2 |
+  a  =  |      |
+        | 3  4 |
+        \      /
+
+ at end group
+ at end example
+ at end ifnottex
+
+Elements of a matrix may be arbitrary expressions, provided that the
+dimensions all make sense when combining the various pieces.  For
+example, given the above matrix, the expression
+
+ at example
+[ a, a ]
+ at end example
+
+ at noindent
+produces the matrix
+
+ at example
+ at group
+ans =
+
+  1  2  1  2
+  3  4  3  4
+ at end group
+ at end example
+
+ at noindent
+but the expression
+
+ at example
+[ a, 1 ]
+ at end example
+
+ at noindent
+produces the error
+
+ at example
+error: number of rows must match (1 != 2) near line 13, column 6
+ at end example
+
+ at noindent
+(assuming that this expression was entered as the first thing on line
+13, of course).
+
+Inside the square brackets that delimit a matrix expression, Octave
+looks at the surrounding context to determine whether spaces and newline
+characters should be converted into element and row separators, or
+simply ignored, so an expression like
+
+ at example
+ at group
+a = [ 1 2
+      3 4 ]
+ at end group
+ at end example
+
+ at noindent
+will work.  However, some possible sources of confusion remain.  For
+example, in the expression
+
+ at example
+[ 1 - 1 ]
+ at end example
+
+ at noindent
+the @samp{-} is treated as a binary operator and the result is the
+scalar 0, but in the expression
+
+ at example
+[ 1 -1 ]
+ at end example
+
+ at noindent
+the @samp{-} is treated as a unary operator and the result is the
+vector @code{[ 1, -1 ]}.  Similarly, the expression
+
+ at example
+[ sin (pi) ]
+ at end example
+
+ at noindent
+will be parsed as
+
+ at example
+[ sin, (pi) ]
+ at end example
+
+ at noindent
+and will result in an error since the @code{sin} function will be
+called with no arguments.  To get around this, you must omit the space
+between @code{sin} and the opening parenthesis, or enclose the
+expression in a set of parentheses:
+
+ at example
+[ (sin (pi)) ]
+ at end example
+
+Whitespace surrounding the single quote character (@samp{'}, used as a
+transpose operator and for delimiting character strings) can also cause
+confusion.  Given @code{a = 1}, the expression
+
+ at example
+[ 1 a' ]
+ at end example
+
+ at noindent
+results in the single quote character being treated as a
+transpose operator and the result is the vector @code{[ 1, 1 ]}, but the
+expression
+
+ at example
+[ 1 a ' ]
+ at end example
+
+ at noindent
+produces the error message
+
+ at example
+ at group
+parse error:
+
+  syntax error
+
+>>> [ 1 a ' ]
+              ^
+ at end group
+ at end example
+
+ at noindent
+because not doing so would cause trouble when parsing the valid expression
+
+ at example
+[ a 'foo' ]
+ at end example
+
+For clarity, it is probably best to always use commas and semicolons to
+separate matrix elements and rows.
+
+When you type a matrix or the name of a variable whose value is a
+matrix, Octave responds by printing the matrix in with neatly aligned
+rows and columns.  If the rows of the matrix are too large to fit on the
+screen, Octave splits the matrix and displays a header before each
+section to indicate which columns are being displayed.  You can use the
+following variables to control the format of the output.
+
+ at DOCSTRING(output_max_field_width)
+
+ at DOCSTRING(output_precision)
+
+It is possible to achieve a wide range of output styles by using
+different values of @code{output_precision} and
+ at code{output_max_field_width}.  Reasonable combinations can be set using
+the @code{format} function.  @xref{Basic Input and Output}.
+
+ at DOCSTRING(split_long_rows)
+
+Octave automatically switches to scientific notation when values become
+very large or very small.  This guarantees that you will see several
+significant figures for every value in a matrix.  If you would prefer to
+see all values in a matrix printed in a fixed point format, you can set
+the built-in variable @code{fixed_point_format} to a nonzero value.  But
+doing so is not recommended, because it can produce output that can
+easily be misinterpreted.
+
+ at DOCSTRING(fixed_point_format)
+
+ at menu
+* Empty Matrices::              
+ at end menu
+
+ at node Empty Matrices
+ at subsection Empty Matrices
+
+A matrix may have one or both dimensions zero, and operations on empty
+matrices are handled as described by Carl de Boor in @cite{An Empty
+Exercise}, SIGNUM, Volume 25, pages 2-6, 1990 and C. N. Nett and W. M.
+Haddad, in @cite{A System-Theoretic Appropriate Realization of the Empty
+Matrix Concept}, IEEE Transactions on Automatic Control, Volume 38,
+Number 5, May 1993.
+ at tex
+Briefly, given a scalar $s$, an $m\times n$ matrix $M_{m\times n}$,
+and an $m\times n$ empty matrix $[\,]_{m\times n}$ (with either one or
+both dimensions equal to zero), the following are true:
+$$
+\eqalign{%
+s \cdot [\,]_{m\times n} = [\,]_{m\times n} \cdot s &= [\,]_{m\times n}\cr
+[\,]_{m\times n} + [\,]_{m\times n} &= [\,]_{m\times n}\cr
+[\,]_{0\times m} \cdot M_{m\times n} &= [\,]_{0\times n}\cr
+M_{m\times n} \cdot [\,]_{n\times 0} &= [\,]_{m\times 0}\cr
+[\,]_{m\times 0} \cdot [\,]_{0\times n} &=  0_{m\times n}}
+$$
+ at end tex
+ at ifnottex
+Briefly, given a scalar @var{s}, an @var{m} by
+ at var{n} matrix @code{M(mxn)}, and an @var{m} by @var{n} empty matrix
+ at code{[](mxn)} (with either one or both dimensions equal to zero), the
+following are true:
+
+ at example
+ at group
+s * [](mxn) = [](mxn) * s = [](mxn)
+
+    [](mxn) + [](mxn) = [](mxn)
+
+    [](0xm) *  M(mxn) = [](0xn)
+
+     M(mxn) * [](nx0) = [](mx0)
+
+    [](mx0) * [](0xn) =  0(mxn)
+ at end group
+ at end example
+ at end ifnottex
+
+By default, dimensions of the empty matrix are printed along with the
+empty matrix symbol, @samp{[]}.  The built-in variable
+ at code{print_empty_dimensions} controls this behavior.
+
+ at DOCSTRING(print_empty_dimensions)
+
+Empty matrices may also be used in assignment statements as a convenient
+way to delete rows or columns of matrices.
+ at xref{Assignment Ops, ,Assignment Expressions}.
+
+When Octave parses a matrix expression, it examines the elements of the
+list to determine whether they are all constants.  If they are, it
+replaces the list with a single matrix constant.
+
+ at node Ranges
+ at section Ranges
+ at cindex range expressions
+ at cindex expression, range
+
+ at opindex colon
+
+A @dfn{range} is a convenient way to write a row vector with evenly
+spaced elements.  A range expression is defined by the value of the first
+element in the range, an optional value for the increment between
+elements, and a maximum value which the elements of the range will not
+exceed.  The base, increment, and limit are separated by colons (the
+ at samp{:} character) and may contain any arithmetic expressions and
+function calls.  If the increment is omitted, it is assumed to be 1.
+For example, the range
+
+ at example
+1 : 5
+ at end example
+
+ at noindent
+defines the set of values @samp{[ 1, 2, 3, 4, 5 ]}, and the range
+
+ at example
+1 : 3 : 5
+ at end example
+
+ at noindent
+defines the set of values @samp{[ 1, 4 ]}.
+
+Although a range constant specifies a row vector, Octave does @emph{not}
+convert range constants to vectors unless it is necessary to do so.
+This allows you to write a constant like @samp{1 : 10000} without using
+80,000 bytes of storage on a typical 32-bit workstation.
+
+Note that the upper (or lower, if the increment is negative) bound on
+the range is not always included in the set of values, and that ranges
+defined by floating point values can produce surprising results because
+Octave uses floating point arithmetic to compute the values in the
+range.  If it is important to include the endpoints of a range and the
+number of elements is known, you should use the @code{linspace} function
+instead (@pxref{Special Utility Matrices}).
+
+When adding a scalar to a range, subtracting a scalar from it (or subtracting a
+range from a scalar) and multiplying by scalar, Octave will attempt to avoid
+unpacking the range and keep the result as a range, too, if it can determine
+that it is safe to do so.  For instance, doing
+
+ at example
+a = 2*(1:1e7) - 1;
+ at end example
+
+will produce the same result as @samp{1:2:2e7-1}, but without ever forming a
+vector with ten million elements.
+
+Using zero as an increment in the colon notation, as @samp{1:0:1} is not
+allowed, because a division by zero would occur in determining the number of
+range elements.  However, ranges with zero increment (i.e., all elements equal)
+are useful, especially in indexing, and Octave allows them to be constructed
+using the built-in function @dfn{ones}.  Note that because a range must be a row
+vector, @samp{ones (1, 10)} produces a range, while @samp{ones (10, 1)} does not.
+
+When Octave parses a range expression, it examines the elements of the
+expression to determine whether they are all constants.  If they are, it
+replaces the range expression with a single range constant.
+
+ at node Single Precision Data Types
+ at section Single Precision Data Types
+
+Octave includes support for single precision data types, and most of the
+functions in Octave accept single precision values and return single
+precision answers.  A single precision variable is created with the
+ at code{single} function.
+
+ at DOCSTRING(single)
+
+for example
+
+ at example
+ at group
+sngl = single (rand (2, 2))
+     @result{} sngl = 
+        0.37569   0.92982
+        0.11962   0.50876
+class (sngl)
+    @result{} single
+ at end group
+ at end example
+
+Many functions can also return single precision values directly.  For
+example
+
+ at example
+ at group
+ones (2, 2, "single")
+zeros (2, 2, "single")
+eye (2, 2,  "single")
+rand (2, 2, "single")
+NaN (2, 2, "single")
+NA (2, 2, "single")
+Inf (2, 2, "single")
+ at end group
+ at end example
+
+ at noindent
+will all return single precision matrices.
+
+ at node Integer Data Types
+ at section Integer Data Types
+
+Octave supports integer matrices as an alternative to using double
+precision.  It is possible to use both signed and unsigned integers
+represented by 8, 16, 32, or 64 bits.  It should be noted that most
+computations require floating point data, meaning that integers will
+often change type when involved in numeric computations.  For this
+reason integers are most often used to store data, and not for
+calculations.
+
+In general most integer matrices are created by casting
+existing matrices to integers.  The following example shows how to cast
+a matrix into 32 bit integers.
+
+ at example
+ at group
+float = rand (2, 2)
+     @result{} float = 0.37569   0.92982
+                0.11962   0.50876
+integer = int32 (float)
+     @result{} integer = 0  1
+                  0  1
+ at end group
+ at end example
+
+ at noindent
+As can be seen, floating point values are rounded to the nearest integer
+when converted.
+
+ at DOCSTRING(isinteger)
+
+ at DOCSTRING(int8)
+
+ at DOCSTRING(uint8)
+
+ at DOCSTRING(int16)
+
+ at DOCSTRING(uint16)
+
+ at DOCSTRING(int32)
+
+ at DOCSTRING(uint32)
+
+ at DOCSTRING(int64)
+
+ at DOCSTRING(uint64)
+
+ at DOCSTRING(intmax)
+
+ at DOCSTRING(intmin)
+
+ at DOCSTRING(intwarning)
+
+ at menu
+* Integer Arithmetic::
+ at end menu
+
+ at node Integer Arithmetic
+ at subsection Integer Arithmetic
+
+While many numerical computations can't be carried out in integers,
+Octave does support basic operations like addition and multiplication
+on integers.  The operators @code{+}, @code{-}, @code{.*}, and @code{./}
+work on integers of the same type.  So, it is possible to add two 32 bit
+integers, but not to add a 32 bit integer and a 16 bit integer.
+
+The arithmetic operations on integers are performed by casting the
+integer values to double precision values, performing the operation, and
+then re-casting the values back to the original integer type.  As the
+double precision type of Octave is only capable of representing integers
+with up to 53 bits of precision, it is not possible to perform
+arithmetic with 64 bit integer types.
+
+When doing integer arithmetic one should consider the possibility of
+underflow and overflow.  This happens when the result of the computation
+can't be represented using the chosen integer type.  As an example it is
+not possible to represent the result of @math{10 - 20} when using
+unsigned integers.  Octave makes sure that the result of integer
+computations is the integer that is closest to the true result.  So, the
+result of @math{10 - 20} when using unsigned integers is zero.
+
+When doing integer division Octave will round the result to the nearest
+integer.  This is different from most programming languages, where the
+result is often floored to the nearest integer.  So, the result of
+ at code{int32(5)./int32(8)} is @code{1}.
+
+ at DOCSTRING(idivide)
+
+ at node Bit Manipulations
+ at section Bit Manipulations
+
+Octave provides a number of functions for the manipulation of numeric
+values on a bit by bit basis.  The basic functions to set and obtain the
+values of individual bits are @code{bitset} and @code{bitget}.
+
+ at DOCSTRING(bitset)
+
+ at DOCSTRING(bitget)
+
+The arguments to all of Octave's bitwise operations can be scalar or
+arrays, except for @code{bitcmp}, whose @var{k} argument must a
+scalar.  In the case where more than one argument is an array, then all
+arguments must have the same shape, and the bitwise operator is applied
+to each of the elements of the argument individually.  If at least one
+argument is a scalar and one an array, then the scalar argument is
+duplicated.  Therefore
+
+ at example
+bitget (100, 8:-1:1)
+ at end example
+
+is the same as
+
+ at example
+bitget (100 * ones (1, 8), 8:-1:1)
+ at end example
+
+It should be noted that all values passed to the bit manipulation
+functions of Octave are treated as integers.  Therefore, even though the
+example for @code{bitset} above passes the floating point value
+ at code{10}, it is treated as the bits @code{[1, 0, 1, 0]} rather than the
+bits of the native floating point format representation of @code{10}.
+
+As the maximum value that can be represented by a number is important
+for bit manipulation, particularly when forming masks, Octave supplies
+the function @code{bitmax}.
+
+ at DOCSTRING(bitmax)
+
+This is the double precision version of the functions @code{intmax},
+previously discussed.
+
+Octave also includes the basic bitwise 'and', 'or' and 'exclusive or'
+operators.
+
+ at DOCSTRING(bitand)
+
+ at DOCSTRING(bitor)
+
+ at DOCSTRING(bitxor)
+
+The bitwise 'not' operator is a unary operator that performs a logical
+negation of each of the bits of the value.  For this to make sense, the
+mask against which the value is negated must be defined.  Octave's
+bitwise 'not' operator is @code{bitcmp}.
+
+ at DOCSTRING(bitcmp)
+
+Octave also includes the ability to left-shift and right-shift values bitwise.
+
+ at DOCSTRING(bitshift)
+
+Bits that are shifted out of either end of the value are lost.  Octave
+also uses arithmetic shifts, where the sign bit of the value is kept
+during a right shift.  For example
+
+ at example
+ at group
+bitshift (-10, -1)
+ at result{} -5
+bitshift (int8 (-1), -1)
+ at result{} -1
+ at end group
+ at end example
+
+Note that @code{bitshift (int8 (-1), -1)} is @code{-1} since the bit
+representation of @code{-1} in the @code{int8} data type is @code{[1, 1,
+1, 1, 1, 1, 1, 1]}.
+
+ at node Logical Values
+ at section Logical Values
+
+Octave has built-in support for logical values, i.e., variables that
+are either @code{true} or @code{false}.  When comparing two variables,
+the result will be a logical value whose value depends on whether or
+not the comparison is true.
+
+The basic logical operations are @code{&}, @code{|}, and @code{!},
+which correspond to ``Logical And'', ``Logical Or'', and ``Logical
+Negation''.  These operations all follow the usual rules of logic.
+
+It is also possible to use logical values as part of standard numerical
+calculations.  In this case @code{true} is converted to @code{1}, and
+ at code{false} to 0, both represented using double precision floating
+point numbers.  So, the result of @code{true*22 - false/6} is @code{22}.
+
+Logical values can also be used to index matrices and cell arrays.
+When indexing with a logical array the result will be a vector containing
+the values corresponding to @code{true} parts of the logical array.
+The following example illustrates this.
+
+ at example
+ at group
+data = [ 1, 2; 3, 4 ];
+idx = (data <= 2);
+data(idx)
+     @result{} ans = [ 1; 2 ]
+ at end group
+ at end example
+
+ at noindent
+Instead of creating the @code{idx} array it is possible to replace
+ at code{data(idx)} with @code{data( data <= 2 )} in the above code.
+
+Logical values can also be constructed by
+casting numeric objects to logical values, or by using the @code{true}
+or @code{false} functions.
+
+ at DOCSTRING(logical)
+
+ at DOCSTRING(true)
+
+ at DOCSTRING(false)
+
+ at node Promotion and Demotion of Data Types
+ at section Promotion and Demotion of Data Types
+
+Many operators and functions can work with mixed data types.  For example
+
+ at example
+ at group
+uint8 (1) + 1
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+where the above operator works with an 8-bit integer and a double precision
+value and returns an 8-bit integer value.  Note that the type is demoted
+to an 8-bit integer, rather than promoted to a double precision value as
+might be expected.  The reason is that if Octave promoted values in
+expressions like the above with all numerical constants would need to be
+explicitly cast to the appropriate data type like
+
+ at example
+ at group
+uint8 (1) + uint8 (1)
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+which becomes difficult for the user to apply uniformly and might allow
+hard to find bugs to be introduced.  The same applies to single precision
+values where a mixed operation such as
+
+ at example
+ at group
+single (1) + 1
+    @result{} 2
+ at end group
+ at end example
+
+ at noindent
+returns a single precision value.  The mixed operations that are valid
+and their returned data types are
+
+ at multitable @columnfractions .2 .3 .3 .2
+ at item @tab Mixed Operation @tab Result @tab 
+ at item @tab double OP single @tab single @tab
+ at item @tab double OP integer @tab integer @tab
+ at item @tab double OP char @tab double @tab
+ at item @tab double OP logical @tab double @tab
+ at item @tab single OP integer @tab integer @tab
+ at item @tab single OP char @tab single @tab
+ at item @tab single OP logical @tab single @tab
+ at end multitable
+
+The same logic applies to functions with mixed arguments such as
+
+ at example
+ at group
+min (single (1), 0)
+   @result{} 0
+ at end group
+ at end example
+
+ at noindent
+where the returned value is single precision.
+
+In the case of mixed type indexed assignments, the type is not
+changed.  For example
+
+ at example
+ at group
+x = ones (2, 2);
+x (1, 1) = single (2)
+    @result{} x = 2   1
+           1   1
+ at end group
+ at end example
+
+ at noindent
+where @code{x} remains of the double precision type. 
+
+ at node Predicates for Numeric Objects
+ at section Predicates for Numeric Objects
+
+Since the type of a variable may change during the execution of a
+program, it can be necessary to do type checking at run-time.  Doing this
+also allows you to change the behavior of a function depending on the
+type of the input.  As an example, this naive implementation of @code{abs}
+returns the absolute value of the input if it is a real number, and the
+length of the input if it is a complex number.
+
+ at example
+ at group
+function a = abs (x)
+  if (isreal (x))
+    a = sign (x) .* x;
+  elseif (iscomplex (x))
+    a = sqrt (real(x).^2 + imag(x).^2);
+  endif
+endfunction
+ at end group
+ at end example
+
+The following functions are available for determining the type of a
+variable.
+
+ at DOCSTRING(isnumeric)
+
+ at DOCSTRING(isreal)
+
+ at DOCSTRING(isfloat)
+
+ at DOCSTRING(iscomplex)
+
+ at DOCSTRING(ismatrix)
+
+ at DOCSTRING(isvector)
+
+ at DOCSTRING(isscalar)
+
+ at DOCSTRING(issquare)
+
+ at DOCSTRING(issymmetric)
+
+ at DOCSTRING(isdefinite)
+
+ at DOCSTRING(islogical)
+
+ at DOCSTRING(isprime)
diff --git a/doc/interpreter/octave-a4.pdf b/doc/interpreter/octave-a4.pdf
new file mode 100644
index 0000000..c9baf83
Binary files /dev/null and b/doc/interpreter/octave-a4.pdf differ
diff --git a/doc/interpreter/octave-bug.1 b/doc/interpreter/octave-bug.1
new file mode 100644
index 0000000..18e0161
--- /dev/null
+++ b/doc/interpreter/octave-bug.1
@@ -0,0 +1,68 @@
+.\" Copyright (C) 2000, 2004, 2005, 2007, 2008 Dirk Eddelbuettel
+.\"
+.\" This file is part of Octave.
+.\"
+.\" Octave is free software; you can redistribute it and/or modify it
+.\" under the terms of the GNU General Public License as published by the
+.\" Free Software Foundation; either version 3 of the License, or (at
+.\" your option) any later version.
+.\"
+.\" Octave is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+.\" for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with Octave; see the file COPYING.  If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.\" This page was contributed by Dirk Eddelbuettel <edd at debian.org>
+.\" 
+.TH octave-bug 1 "6 March 2000" GNU
+.SH NAME
+octave-bug \- report a bug in GNU Octave
+.SH SYNOPSIS
+.B octave-bug
+.RB [\| \-s
+.IR subject \|]
+.SH DESCRIPTION
+.B octave-bug
+is a shell script to help the user compose and mail bug reports
+concerning Octave in a standard format.  
+.B octave-bug
+is typically invoked by the Octave command
+.B bug_report
+which is intended to be called interactively from within Octave. This
+provides the best way to submit a bug report for Octave. It creates a
+template bug report file and starts an editor on that file.  The bug report
+will be sent to the bug-octave mailing list once the editing has been
+completed (this assumes of course that your system can use email). However,
+the user could also call \fBoctave-bug\fR outside of Octave.
+.PP
+Please read the `Bugs' chapter in the Octave manual to find out how to submit
+a bug report that will enable the Octave maintainers to fix the problem.  If
+you are unable to use the bug_report command, send your message to the
+bug-octave mailing list, bug at octave.org.
+.SH OPTIONS
+.TP
+.BI -s\  subject
+Specify a subject line for the bug report.  Spaces in the subject must
+be quoted.
+.SH ENVIRONMENT VARIABLES
+.B 
+octave-bug 
+uses the environment variables
+.BR USER, 
+.BR EDITOR, 
+and 
+.B PAGER 
+which can be used for customization.
+.SH VERSION
+This document was last revised for Octave version 2.0.16.
+.SH SEE ALSO
+.BR octave (1),
+.BR bashbug (1)     
+.SH AUTHOR
+.nf
+John W. Eaton
+<jwe at octave.org>
diff --git a/doc/interpreter/octave-config.1 b/doc/interpreter/octave-config.1
new file mode 100644
index 0000000..fb9e583
--- /dev/null
+++ b/doc/interpreter/octave-config.1
@@ -0,0 +1,80 @@
+.\" Copyright (C) 2003, 2004, 2005, 2006, 2007 Dirk Eddelbuettel
+.\"
+.\" This file is part of Octave.
+.\"
+.\" Octave is free software; you can redistribute it and/or modify it
+.\" under the terms of the GNU General Public License as published by the
+.\" Free Software Foundation; either version 3 of the License, or (at
+.\" your option) any later version.
+.\"
+.\" Octave is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+.\" for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with Octave; see the file COPYING.  If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.\" This page was contributed by Dirk Eddelbuettel <edd at debian.org>.
+.\" 
+.TH OCTAVE-CONFIG 1 "19 February 2003" "GNU Octave"
+.SH NAME
+octave-config - GNU Octave component and library information retrieval
+.SH SYNOPSIS
+.B octave-config
+.RI [ options ]
+.SH DESCRIPTION
+.PP
+.B octave-config
+is a tool to obtain directory information for 
+.I .oct
+and 
+.I .m
+files for
+.BR octave (1).
+.SH OPTIONS
+.B octave-config
+accepts the following options:
+.TP 8
+.B \--m-site-dir
+Display the main directory for local, or site-specific, .m script files.
+.TP 8
+.B \--oct-site-dir
+Display the main directory for local, or site-specific, .oct dynamic-link libraries.
+.TP 8
+.B \-p|\-\-print VAR
+Print the default value of the Octave configuration variable VAR.
+Recognized variables are:
+.RS
+    CANONICAL_HOST_TYPE    LOCALFCNFILEDIR    
+    DEFAULT_PAGER          LOCALFCNFILEPATH
+    ARCHLIBDIR             LOCALOCTFILEDIR
+    BINDIR                 LOCALOCTFILEPATH
+    DATADIR                LOCALSTARTUPFILEDIR
+    EXEC_PREFIX            LOCALVERARCHLIBDIR
+    FCNFILEDIR             LOCALVERFCNFILEDIR
+    FCNFILEPATH            LOCALVEROCTFILEDIR
+    IMAGEDIR               MAN1DIR
+    IMAGE_PATH             MAN1EXT
+    INCLUDEDIR             MANDIR
+    INFODIR                OCTFILEDIR
+    INFOFILE               OCTINCLUDEDIR
+    LIBDIR                 OCTLIBDIR
+    LIBEXECDIR             PREFIX
+    LIBEXECDIR             STARTUPFILEDIR
+    LOCALARCHLIBDIR        VERSION
+.RE
+.TP 8
+.B \-v|\-\-version
+Display the version number of 
+.BR octave (1).
+.TP 8
+.B \-h|-?|--help
+Display a help page about
+.B octave-config
+.SH AUTHOR
+John W. Eaton <jwe at octave.org>
+
+This manual page was contributed by Dirk Eddelbuettel <edd at debian.org> 
+for the Debian GNU/Linux distribution but may be used by others.
diff --git a/doc/interpreter/octave.1 b/doc/interpreter/octave.1
new file mode 100644
index 0000000..626f634
--- /dev/null
+++ b/doc/interpreter/octave.1
@@ -0,0 +1,74 @@
+.\" Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+.\"
+.\" This file is part of Octave.
+.\"
+.\" Octave is free software; you can redistribute it and/or modify it
+.\" under the terms of the GNU General Public License as published by the
+.\" Free Software Foundation; either version 3 of the License, or (at
+.\" your option) any later version.
+.\"
+.\" Octave is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+.\" for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with Octave; see the file COPYING.  If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.TH Octave 1 "Jan 8 1996"
+.SH NAME
+octave \- A high-level interactive language for numerical computations.
+.SH SYNOPSIS
+.nf
+octave [options]
+.fi
+.SH OPTIONS
+The complete set of command-line options for octave is available by
+running the command
+.nf
+
+    octave \-\-help
+
+.fi
+.SH DESCRIPTION
+Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient command line interface for
+solving linear and nonlinear problems numerically.
+.SH DOCUMENTATION
+The primary documentation for Octave is written using Texinfo, the GNU
+documentation system, which allows the same source files to be used to
+produce on-line and printed versions of the manual.
+.PP
+You can read the on-line copy of the Octave documentation by issuing
+the command
+.nf
+
+    octave:13> help \-i
+
+.fi
+while running Octave interactively, by using the GNU Emacs info mode,
+or by running standalone programs like info or xinfo.
+.SH BUGS
+The best way to submit a bug report for Octave is to use the command
+.nf
+
+     octave:13> bug_report
+
+.fi
+while running Octave interactively.  This will create a template bug
+report file and start an editor on that file.  Your 
+message will be sent to the bug-octave mailing list
+once you are finished editing the template.
+.PP
+If you are unable to use the bug_report command, send your message
+to the
+.B bug at octave.org
+mailing list by some other means.  Please read the `Bugs' chapter in
+the Octave manual to find out how to submit a bug report that will
+enable the Octave maintainers to fix the problem.
+.SH AUTHOR
+.nf
+John W. Eaton
+<jwe at octave.org>
+.fi
diff --git a/doc/interpreter/octave.info b/doc/interpreter/octave.info
new file mode 100644
index 0000000..b0bc8c1
--- /dev/null
+++ b/doc/interpreter/octave.info
@@ -0,0 +1,1708 @@
+This is octave.info, produced by makeinfo version 4.11 from ./octave.texi.
+
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, 2007
+John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+Indirect:
+octave.info-1: 838
+octave.info-2: 299722
+octave.info-3: 599578
+octave.info-4: 900838
+octave.info-5: 1203709
+octave.info-6: 1497821
+
+Tag Table:
+(Indirect)
+Node: Top838
+Node: Preface14135
+Node: Acknowledgements16517
+Node: How You Can Contribute to Octave23903
+Node: Distribution24933
+Node: Introduction26040
+Node: Running Octave27064
+Node: Simple Examples27866
+Node: Conventions36090
+Node: Fonts36462
+Node: Evaluation Notation36999
+Node: Printing Notation37992
+Node: Error Messages38517
+Node: Format of Descriptions38914
+Node: A Sample Function Description39518
+Node: A Sample Command Description41662
+Node: A Sample Variable Description42482
+Node: Getting Started43599
+Node: Invoking Octave from the Command Line44129
+Node: Command Line Options45018
+Ref: doc-argv49923
+Ref: doc-program_name50450
+Ref: doc-program_invocation_name50662
+Node: Startup Files51540
+Node: Quitting Octave53727
+Ref: doc-quit53902
+Ref: doc-atexit54175
+Node: Getting Help55174
+Ref: doc-help55800
+Ref: doc-doc56382
+Ref: doc-lookfor56923
+Ref: doc-news58275
+Ref: doc-info58351
+Ref: doc-warranty58443
+Ref: doc-info_file58696
+Ref: doc-info_program59319
+Ref: doc-makeinfo_program60078
+Ref: doc-doc_cache_file60519
+Ref: doc-suppress_verbose_help_message61354
+Node: Command Line Editing61697
+Node: Cursor Motion63562
+Ref: doc-clc64932
+Node: Killing and Yanking65078
+Node: Commands For Text66781
+Node: Commands For Completion68172
+Ref: doc-completion_append_char68671
+Ref: doc-completion_matches68964
+Node: Commands For History69315
+Ref: doc-history71044
+Ref: doc-edit_history71944
+Ref: doc-run_history73310
+Ref: doc-saving_history73649
+Ref: doc-history_file74075
+Ref: doc-history_size74597
+Ref: doc-history_timestamp_format_string75099
+Ref: doc-EDITOR75722
+Node: Customizing readline76165
+Ref: doc-read_readline_init_file76760
+Ref: doc-re_read_readline_init_file77046
+Node: Customizing the Prompt77255
+Ref: doc-PS178491
+Ref: doc-PS279188
+Ref: doc-PS479718
+Node: Diary and Echo Commands80173
+Ref: doc-diary80523
+Ref: doc-echo81185
+Ref: doc-echo_executing_commands81787
+Node: Errors82440
+Node: Executable Octave Programs85029
+Ref: Executable Octave Programs-Footnote-188494
+Node: Comments88628
+Node: Single Line Comments89204
+Node: Block Comments89852
+Node: Comments and the Help System90481
+Node: Data Types91779
+Ref: doc-typeinfo92570
+Node: Built-in Data Types92857
+Ref: doc-class93532
+Ref: doc-isa93872
+Ref: doc-cast93963
+Ref: doc-typecast94292
+Ref: doc-swapbytes94850
+Node: Numeric Objects95262
+Node: Missing Data96141
+Ref: doc-NA96580
+Ref: doc-isna97521
+Node: String Objects97766
+Node: Data Structure Objects98249
+Node: Cell Array Objects98713
+Node: User-defined Data Types99007
+Node: Object Sizes99466
+Ref: doc-ndims99925
+Ref: doc-columns100137
+Ref: doc-rows100431
+Ref: doc-numel100725
+Ref: doc-length100853
+Ref: doc-size101089
+Ref: doc-isempty101861
+Ref: doc-isnull102036
+Ref: doc-sizeof102549
+Ref: doc-size_equal102624
+Ref: doc-squeeze102906
+Node: Numeric Data Types103139
+Ref: doc-double104622
+Ref: doc-complex104743
+Node: Matrices105481
+Ref: doc-output_max_field_width108405
+Ref: doc-output_precision108727
+Ref: doc-split_long_rows109312
+Ref: doc-fixed_point_format110641
+Node: Empty Matrices111429
+Ref: doc-print_empty_dimensions112428
+Node: Ranges113163
+Node: Single Precision Data Types115743
+Ref: doc-single116162
+Node: Integer Data Types116765
+Ref: doc-isinteger117806
+Ref: doc-int8118167
+Ref: doc-uint8118239
+Ref: doc-int16118321
+Ref: doc-uint16118395
+Ref: doc-int32118479
+Ref: doc-uint32118553
+Ref: doc-int64118637
+Ref: doc-uint64118711
+Ref: doc-intmax118795
+Ref: doc-intmin119427
+Ref: doc-intwarning120060
+Node: Integer Arithmetic121751
+Ref: doc-idivide123307
+Node: Bit Manipulations124683
+Ref: doc-bitset125047
+Ref: doc-bitget125527
+Ref: doc-bitmax126962
+Ref: doc-bitand127322
+Ref: doc-bitor127670
+Ref: doc-bitxor128016
+Ref: doc-bitcmp128613
+Ref: doc-bitshift129214
+Node: Logical Values130326
+Ref: doc-logical131777
+Ref: doc-true131945
+Ref: doc-false132211
+Node: Promotion and Demotion of Data Types132480
+Node: Predicates for Numeric Objects134492
+Ref: doc-isnumeric135358
+Ref: doc-isreal135443
+Ref: doc-isfloat135534
+Ref: doc-iscomplex135629
+Ref: doc-ismatrix135726
+Ref: doc-isvector135818
+Ref: doc-isscalar136092
+Ref: doc-issquare136366
+Ref: doc-issymmetric136709
+Ref: doc-isdefinite137288
+Ref: doc-islogical137632
+Ref: doc-isprime137714
+Node: Strings138170
+Node: Escape Sequences in string constants139236
+Node: Character Arrays140912
+Ref: doc-ischar141910
+Ref: doc-string_fill_char142720
+Node: Creating Strings143421
+Ref: doc-blanks143890
+Node: Concatenating Strings144366
+Ref: doc-char147334
+Ref: doc-strvcat148532
+Ref: doc-strcat149756
+Ref: doc-cstrcat150581
+Node: Conversion of Numerical Data to Strings151062
+Ref: doc-mat2str151811
+Ref: doc-num2str152944
+Ref: doc-int2str154386
+Node: Comparing Strings155161
+Ref: doc-strcmp155903
+Ref: doc-strncmp156676
+Ref: doc-strcmpi157612
+Ref: doc-strncmpi158424
+Ref: doc-validatestring159266
+Node: Manipulating Strings160203
+Ref: doc-deblank160958
+Ref: doc-strtrim161200
+Ref: doc-strtrunc161612
+Ref: doc-findstr161895
+Ref: doc-strchr162580
+Ref: doc-index163016
+Ref: doc-rindex163652
+Ref: doc-strfind164050
+Ref: doc-strmatch165090
+Ref: doc-strtok165956
+Ref: doc-strsplit166581
+Ref: doc-strrep166938
+Ref: doc-substr167312
+Ref: doc-regexp167828
+Ref: doc-regexpi171951
+Ref: doc-regexprep172299
+Ref: doc-regexptranslate173619
+Node: String Conversions174503
+Ref: doc-bin2dec174905
+Ref: doc-dec2bin175399
+Ref: doc-dec2hex176022
+Ref: doc-hex2dec176615
+Ref: doc-dec2base177155
+Ref: doc-base2dec177949
+Ref: doc-num2hex178722
+Ref: doc-hex2num179258
+Ref: doc-str2double179777
+Ref: doc-strjust181834
+Ref: doc-str2num182335
+Ref: doc-toascii182927
+Ref: doc-tolower183139
+Ref: doc-toupper183525
+Ref: doc-do_string_escapes183913
+Ref: doc-undo_string_escapes184031
+Node: Character Class Functions184801
+Ref: doc-isalnum185361
+Ref: doc-isalpha185500
+Ref: doc-isascii185668
+Ref: doc-iscntrl185786
+Ref: doc-isdigit185860
+Ref: doc-isgraph185950
+Ref: doc-isletter186056
+Ref: doc-islower186189
+Ref: doc-isprint186283
+Ref: doc-ispunct186391
+Ref: doc-isspace186469
+Ref: doc-isupper186618
+Ref: doc-isxdigit186692
+Ref: doc-isstrprop186787
+Node: Data Containers188446
+Node: Data Structures189035
+Node: Basic Usage and Examples189504
+Ref: doc-struct_levels_to_print191601
+Node: Structure Arrays193270
+Node: Creating Structures195962
+Ref: doc-struct197504
+Ref: doc-isstruct198134
+Node: Manipulating Structures198241
+Ref: doc-rmfield198523
+Ref: doc-setfield198813
+Ref: doc-orderfields199402
+Ref: doc-fieldnames200033
+Ref: doc-isfield200248
+Ref: doc-getfield200471
+Ref: doc-substruct201071
+Node: Processing Data in Structures201273
+Ref: doc-structfun201712
+Ref: doc-struct2cell203689
+Node: Cell Arrays204047
+Node: Basic Usage of Cell Arrays204661
+Ref: doc-celldisp206212
+Ref: doc-iscell206643
+Node: Creating Cell Arrays206751
+Ref: doc-cell208373
+Ref: doc-num2cell209015
+Ref: doc-mat2cell209319
+Node: Indexing Cell Arrays210346
+Node: Cell Arrays of Strings213341
+Ref: doc-cellstr214399
+Ref: doc-iscellstr215517
+Ref: doc-cellidx215643
+Node: Processing Data in Cell Arrays216268
+Ref: doc-cellfun216805
+Ref: doc-cell2mat220098
+Ref: doc-cell2struct220437
+Node: Comma Separated Lists220966
+Ref: Comma Separated Lists-Footnote-1222505
+Node: Comma Separated Lists Generated from Cell Arrays222592
+Node: Comma Separated Lists Generated from Structure Arrays224752
+Node: Variables225450
+Ref: doc-ans227301
+Ref: doc-isvarname227533
+Ref: doc-genvarname227625
+Ref: doc-namelengthmax229816
+Node: Global Variables230340
+Ref: doc-isglobal232064
+Node: Persistent Variables232254
+Ref: doc-persistent232424
+Node: Status of Variables235785
+Ref: doc-who236326
+Ref: doc-whos237484
+Ref: doc-whos_line_format238974
+Ref: doc-exist241023
+Ref: doc-clear242665
+Ref: doc-type245030
+Ref: doc-which245454
+Ref: doc-what245679
+Node: Expressions246041
+Node: Index Expressions246900
+Ref: doc-sub2ind250873
+Ref: doc-ind2sub251368
+Node: Calling Functions251812
+Node: Call by Value254325
+Node: Recursion256337
+Ref: doc-max_recursion_depth257276
+Ref: Recursion-Footnote-1257629
+Ref: Recursion-Footnote-2258018
+Node: Arithmetic Ops258179
+Node: Comparison Ops261464
+Ref: doc-isequal262612
+Ref: doc-isequalwithequalnans262777
+Node: Boolean Expressions262951
+Node: Element-by-element Boolean Operators263200
+Node: Short-circuit Boolean Operators265665
+Node: Assignment Ops268586
+Node: Increment Ops273376
+Node: Operator Precedence274997
+Node: Evaluation277053
+Ref: doc-eval277491
+Node: Calling a Function by its Name278324
+Ref: doc-feval280032
+Ref: doc-run280835
+Node: Evaluation in a Different Context281214
+Ref: doc-evalin283612
+Ref: doc-assignin283799
+Node: Statements283957
+Node: The `if' Statement285480
+Node: The `switch' Statement289012
+Node: Notes for the C programmer291835
+Node: The `while' Statement292938
+Node: The `do-until' Statement295146
+Node: The `for' Statement296560
+Node: Looping Over Structure Elements299722
+Node: The `break' Statement300993
+Node: The `continue' Statement302512
+Node: The `unwind_protect' Statement303806
+Node: The `try' Statement305221
+Node: Continuation Lines306257
+Node: Functions and Scripts307942
+Node: Defining Functions308659
+Ref: doc-nargin313843
+Ref: doc-inputname314398
+Ref: doc-silent_functions314491
+Node: Multiple Return Values314886
+Ref: doc-nargout317235
+Ref: doc-nargchk317941
+Ref: doc-nargoutchk318545
+Ref: doc-varargin319164
+Ref: doc-varargout319164
+Node: Variable-length Argument Lists319164
+Ref: doc-parseparams321303
+Node: Variable-length Return Lists321991
+Ref: doc-deal323160
+Node: Returning From a Function323664
+Node: Default Arguments325252
+Node: Function Files326541
+Ref: doc-edit329149
+Ref: doc-mfilename333959
+Ref: doc-ignore_function_time_stamp334418
+Ref: Function Files-Footnote-1335485
+Node: Manipulating the load path335551
+Ref: doc-addpath336366
+Ref: doc-genpath336941
+Ref: doc-rmpath337048
+Ref: doc-savepath337345
+Ref: doc-path337791
+Ref: doc-pathdef338489
+Ref: doc-pathsep339009
+Ref: doc-rehash339262
+Ref: doc-file_in_loadpath339351
+Ref: doc-restoredefaultpath340079
+Ref: doc-command_line_path340413
+Ref: doc-find_dir_in_path340729
+Node: Subfunctions341060
+Node: Private Functions341856
+Node: Overloading and Autoloading342939
+Ref: doc-dispatch343824
+Ref: doc-builtin344325
+Ref: doc-autoload345291
+Node: Function Locking346323
+Ref: doc-mlock348259
+Ref: doc-munlock348482
+Ref: doc-mislocked348730
+Node: Function Precedence349012
+Node: Script Files350489
+Ref: doc-source354299
+Node: Function Handles Inline Functions and Anonymous Functions354508
+Node: Function Handles355093
+Ref: doc-functions356016
+Ref: doc-func2str356151
+Ref: doc-str2func356306
+Node: Anonymous Functions356419
+Node: Inline Functions357506
+Ref: doc-inline357951
+Ref: doc-argnames358917
+Ref: doc-formula359183
+Ref: doc-vectorize359464
+Ref: doc-symvar359640
+Node: Commands359982
+Ref: doc-mark_as_command361206
+Ref: doc-unmark_command361343
+Ref: doc-iscommand361479
+Ref: doc-mark_as_rawcommand361610
+Ref: doc-unmark_rawcommand361750
+Ref: doc-israwcommand361889
+Node: Organization of Functions362023
+Node: Errors and Warnings364139
+Node: Handling Errors364744
+Node: Raising Errors365476
+Ref: doc-error366095
+Ref: doc-print_usage369276
+Ref: doc-usage369574
+Ref: doc-beep370426
+Ref: doc-beep_on_error370633
+Node: Catching Errors370885
+Ref: doc-lasterror372030
+Ref: doc-lasterr373518
+Ref: doc-rethrow374403
+Ref: doc-errno374848
+Ref: doc-errno_list375200
+Node: Handling Warnings375309
+Node: Issuing Warnings375888
+Ref: doc-warning377136
+Ref: doc-lastwarn378384
+Node: Enabling and Disabling Warnings378632
+Ref: doc-warning_ids379588
+Node: Debugging386956
+Node: Entering Debug Mode387635
+Ref: doc-debug_on_interrupt388126
+Ref: doc-debug_on_warning388542
+Ref: doc-debug_on_error388788
+Node: Leaving Debug Mode389153
+Ref: doc-dbcont389379
+Ref: doc-dbquit389631
+Node: Breakpoints389900
+Ref: doc-dbstop390115
+Ref: doc-dbstatus391302
+Ref: doc-dbclear391769
+Ref: doc-keyboard393150
+Node: Debug Mode394085
+Ref: doc-dbwhere394448
+Ref: doc-dbtype394626
+Ref: doc-isdebugmode394899
+Ref: doc-dbstep395220
+Node: Call Stack395800
+Ref: doc-dbstack395908
+Ref: doc-dbup396179
+Ref: doc-dbdown396363
+Node: Input and Output396553
+Node: Basic Input and Output397077
+Node: Terminal Output397336
+Ref: doc-disp398074
+Ref: doc-format398487
+Node: Paging Screen Output403750
+Ref: doc-more404894
+Ref: doc-PAGER405124
+Ref: doc-PAGER_FLAGS405682
+Ref: doc-page_screen_output405918
+Ref: doc-page_output_immediately406365
+Ref: doc-fflush406737
+Node: Terminal Input407187
+Ref: doc-input407598
+Ref: doc-menu408723
+Ref: doc-yes_or_no409259
+Ref: doc-kbhit409875
+Node: Simple File I/O410299
+Ref: doc-save411124
+Ref: doc-load414997
+Ref: doc-default_save_options418761
+Ref: doc-save_precision419147
+Ref: doc-save_header_format_string419375
+Ref: doc-native_float_format420118
+Ref: doc-fdisp420699
+Ref: doc-dlmwrite421127
+Ref: doc-dlmread422769
+Ref: doc-csvwrite423591
+Ref: doc-csvread423862
+Node: Saving Data on Unexpected Exits424175
+Ref: doc-crash_dumps_octave_core424691
+Ref: doc-sighup_dumps_octave_core425230
+Ref: doc-sigterm_dumps_octave_core425529
+Ref: doc-octave_core_file_options425833
+Ref: doc-octave_core_file_limit426463
+Ref: doc-octave_core_file_name427352
+Node: Rational Approximations427875
+Ref: doc-rat428044
+Ref: doc-rats428533
+Node: C-Style I/O Functions428965
+Ref: doc-stdin429778
+Ref: doc-stdout430063
+Ref: doc-stderr430328
+Node: Opening and Closing Files431132
+Ref: doc-fopen431867
+Ref: doc-fclose435351
+Node: Simple Output435583
+Ref: doc-fputs436128
+Ref: doc-puts436648
+Node: Line-Oriented Input436814
+Ref: doc-fgetl437396
+Ref: doc-fgets437847
+Node: Formatted Output438351
+Ref: doc-printf438866
+Ref: doc-fprintf439175
+Ref: doc-sprintf439591
+Node: Output Conversion for Matrices442106
+Node: Output Conversion Syntax443196
+Node: Table of Output Conversions446164
+Node: Integer Conversions448348
+Node: Floating-Point Conversions450404
+Node: Other Output Conversions453240
+Node: Formatted Input454349
+Ref: doc-fscanf454762
+Ref: doc-scanf456373
+Ref: doc-sscanf456743
+Node: Input Conversion Syntax458434
+Node: Table of Input Conversions460924
+Node: Numeric Input Conversions462763
+Node: String Input Conversions463803
+Node: Binary I/O464834
+Ref: doc-fread465296
+Ref: doc-fwrite469749
+Node: Temporary Files470451
+Ref: doc-mkstemp470886
+Ref: doc-tmpfile471928
+Ref: doc-tmpnam472471
+Node: EOF and Errors473105
+Ref: doc-feof473986
+Ref: doc-ferror474389
+Ref: doc-fclear474669
+Ref: doc-freport474759
+Node: File Positioning475160
+Ref: doc-ftell475418
+Ref: doc-fseek475666
+Ref: doc-SEEK_SET476322
+Ref: doc-frewind476730
+Node: Plotting477275
+Node: Plotting Basics477453
+Node: Two-Dimensional Plots478000
+Ref: fig:plot478439
+Ref: doc-plot478626
+Ref: doc-plotyy483217
+Ref: doc-semilogx484634
+Ref: doc-semilogy484946
+Ref: doc-loglog485258
+Ref: fig:hist485810
+Ref: doc-bar485979
+Ref: doc-barh487449
+Ref: doc-hist488607
+Ref: doc-stairs489521
+Ref: doc-stem490476
+Ref: doc-stem3492016
+Ref: doc-scatter492651
+Ref: doc-scatter3494162
+Ref: doc-plotmatrix495664
+Ref: doc-pareto497071
+Ref: doc-rose498528
+Ref: doc-contour499650
+Ref: doc-contourf500730
+Ref: doc-contourc502166
+Ref: doc-contour3503262
+Ref: fig:errorbar504810
+Ref: doc-errorbar504987
+Ref: doc-semilogxerr507246
+Ref: doc-semilogyerr507817
+Ref: doc-loglogerr508388
+Ref: fig:polar509221
+Ref: doc-polar509392
+Ref: doc-pie509617
+Ref: doc-quiver510385
+Ref: doc-quiver3511787
+Ref: doc-compass513310
+Ref: doc-feather514170
+Ref: doc-pcolor515013
+Ref: doc-area516321
+Ref: doc-comet517230
+Ref: doc-axis517986
+Ref: doc-caxis520477
+Ref: doc-ylim521299
+Ref: doc-zlim521299
+Ref: doc-xlim521299
+Node: Two-dimensional Function Plotting522239
+Ref: doc-fplot522934
+Ref: doc-ezplot523808
+Ref: doc-ezcontour525302
+Ref: doc-ezcontourf526431
+Ref: doc-ezpolar527571
+Node: Three-Dimensional Plotting528450
+Ref: fig:mesh529147
+Ref: fig:plot3529742
+Ref: doc-mesh530011
+Ref: doc-meshc530447
+Ref: doc-meshz530918
+Ref: doc-hidden531385
+Ref: doc-surf531771
+Ref: doc-surfc532197
+Ref: doc-surfl532671
+Ref: doc-surfnorm534220
+Ref: doc-diffuse535399
+Ref: doc-specular535802
+Ref: doc-meshgrid536392
+Ref: doc-ndgrid537061
+Ref: doc-plot3537629
+Ref: doc-view539319
+Ref: doc-slice539500
+Ref: doc-ribbon541373
+Ref: doc-shading541861
+Node: Three-dimensional Function Plotting542462
+Ref: doc-ezplot3542694
+Ref: doc-ezmesh543685
+Ref: doc-ezmeshc545344
+Ref: doc-ezsurf546803
+Ref: doc-ezsurfc548465
+Node: Three-dimensional Geometric Shapes549927
+Ref: doc-cylinder550157
+Ref: doc-sphere550993
+Ref: doc-ellipsoid551502
+Node: Plot Annotations551920
+Ref: doc-title552552
+Ref: doc-legend552688
+Ref: doc-text554136
+Ref: doc-ylabel554588
+Ref: doc-zlabel554588
+Ref: doc-xlabel554588
+Ref: doc-clabel555145
+Ref: doc-box556777
+Ref: doc-grid557045
+Ref: doc-colorbar557660
+Node: Multiple Plots on One Page558606
+Ref: doc-subplot559482
+Node: Multiple Plot Windows560260
+Ref: doc-figure560756
+Node: Printing Plots561078
+Ref: doc-print561440
+Ref: doc-orient566291
+Node: Interacting with plots566660
+Ref: doc-ginput567019
+Ref: doc-waitforbuttonpress567313
+Ref: doc-gtext567554
+Node: Test Plotting Functions568007
+Ref: doc-sombrero568362
+Ref: doc-peaks568709
+Node: Advanced Plotting569655
+Node: Graphics Objects569981
+Ref: doc-ishandle571025
+Ref: doc-ishghandle571127
+Ref: doc-isfigure571227
+Ref: doc-gcf571574
+Ref: doc-gca572162
+Ref: doc-get574042
+Ref: doc-set574305
+Ref: doc-ancestor574442
+Ref: doc-allchild575072
+Ref: doc-axes575744
+Ref: doc-line575904
+Ref: doc-patch576305
+Ref: doc-fill577069
+Ref: doc-surface577351
+Ref: doc-drawnow578383
+Ref: doc-refresh579021
+Ref: doc-newplot579837
+Ref: doc-hold580018
+Ref: doc-ishold580887
+Ref: doc-clf581379
+Ref: doc-cla581938
+Ref: doc-shg582379
+Ref: doc-delete582562
+Ref: doc-close582860
+Ref: doc-closereq583179
+Node: Graphics Object Properties583367
+Node: Root Figure Properties583786
+Node: Figure Properties584034
+Node: Axes Properties584724
+Node: Line Properties588722
+Node: Text Properties589551
+Ref: tab:extended592577
+Node: Image Properties595407
+Node: Patch Properties596035
+Node: Surface Properties596662
+Node: Searching Properties597191
+Ref: doc-findobj597362
+Ref: doc-findall599038
+Node: Managing Default Properties599578
+Node: Colors602077
+Node: Line Styles602436
+Node: Marker Styles602939
+Node: Callbacks603718
+Ref: doc-gcbo605627
+Ref: doc-gcbf606217
+Node: Object Groups606704
+Ref: doc-hggroup607160
+Ref: doc-addproperty608083
+Ref: doc-addlistener610954
+Ref: doc-dellistener612100
+Ref: doc-linkprop613716
+Node: Data sources in object groups616151
+Ref: doc-refreshdata616554
+Ref: doc-linkdata617480
+Node: Area series617480
+Node: Bar series618353
+Node: Contour groups620183
+Node: Error bar series622824
+Node: Line series623783
+Node: Quiver group624534
+Node: Scatter group626124
+Node: Stair group627195
+Node: Stem Series628018
+Node: Surface group629471
+Node: Graphics backends630370
+Ref: doc-backend630514
+Ref: doc-available_backends630963
+Node: Interaction with gnuplot631107
+Ref: doc-gnuplot_binary631258
+Node: Matrix Manipulation631496
+Node: Finding Elements and Checking Conditions632202
+Ref: doc-any632655
+Ref: doc-all633191
+Ref: doc-xor633912
+Ref: doc-is_duplicate_entry634135
+Ref: doc-diff634251
+Ref: doc-isinf635150
+Ref: doc-isnan635343
+Ref: doc-finite635621
+Ref: doc-find635822
+Ref: doc-common_size637460
+Node: Rearranging Matrices638108
+Ref: doc-fliplr638326
+Ref: doc-flipud638749
+Ref: doc-flipdim639240
+Ref: doc-rot90639558
+Ref: doc-rotdim640499
+Ref: doc-cat641584
+Ref: doc-horzcat642446
+Ref: doc-vertcat642690
+Ref: doc-permute642932
+Ref: doc-ipermute643222
+Ref: doc-reshape643454
+Ref: doc-resize644084
+Ref: doc-circshift645293
+Ref: doc-shiftdim646085
+Ref: doc-shift647005
+Ref: doc-sort647296
+Ref: doc-sortrows648760
+Ref: doc-issorted649091
+Ref: doc-triu650042
+Ref: doc-tril650042
+Ref: doc-vec651098
+Ref: doc-vech651225
+Ref: doc-postpad651414
+Ref: doc-prepad651414
+Ref: doc-diag651975
+Ref: doc-blkdiag652602
+Ref: Rearranging Matrices-Footnote-1652927
+Node: Applying a Function to an Array653100
+Ref: doc-arrayfun653324
+Ref: doc-bsxfun656839
+Node: Special Utility Matrices657367
+Ref: doc-eye657572
+Ref: doc-ones658626
+Ref: doc-zeros659214
+Ref: doc-repmat659659
+Ref: doc-rand659919
+Ref: doc-randn662491
+Ref: doc-rande663251
+Ref: doc-randp663975
+Ref: doc-randg665478
+Ref: doc-randperm668696
+Ref: doc-linspace668966
+Ref: doc-logspace669535
+Ref: Special Utility Matrices-Footnote-1670047
+Node: Famous Matrices670144
+Ref: doc-hadamard670344
+Ref: doc-hankel670979
+Ref: doc-hilb671687
+Ref: doc-invhilb672039
+Ref: doc-magic673209
+Ref: doc-pascal673357
+Ref: doc-rosser674245
+Ref: doc-sylvester_matrix674710
+Ref: doc-toeplitz674963
+Ref: doc-vander675812
+Ref: doc-wilkinson676503
+Node: Arithmetic676907
+Node: Exponents and Logarithms677611
+Ref: doc-exp677770
+Ref: doc-expm1677951
+Ref: doc-log678090
+Ref: doc-log1p678405
+Ref: doc-log10678593
+Ref: doc-log2678799
+Ref: doc-nextpow2679207
+Ref: doc-nthroot679440
+Ref: doc-pow2679677
+Ref: doc-reallog679927
+Ref: doc-realpow680200
+Ref: doc-realsqrt680496
+Ref: doc-sqrt680765
+Node: Complex Arithmetic681020
+Ref: doc-abs681304
+Ref: doc-arg681469
+Ref: doc-conj681688
+Ref: doc-cplxpair681855
+Ref: doc-imag682815
+Ref: doc-real682964
+Node: Trigonometry683091
+Ref: doc-sin683754
+Ref: doc-cos683931
+Ref: doc-tan684110
+Ref: doc-sec684290
+Ref: doc-csc684469
+Ref: doc-cot684650
+Ref: doc-asin684832
+Ref: doc-acos684991
+Ref: doc-atan685152
+Ref: doc-asec685314
+Ref: doc-acsc685475
+Ref: doc-acot685638
+Ref: doc-sinh685802
+Ref: doc-cosh685982
+Ref: doc-tanh686164
+Ref: doc-sech686343
+Ref: doc-csch686475
+Ref: doc-coth686609
+Ref: doc-asinh686744
+Ref: doc-acosh686882
+Ref: doc-atanh687022
+Ref: doc-asech687163
+Ref: doc-acsch687302
+Ref: doc-acoth687443
+Ref: doc-atan2687585
+Ref: doc-sind688072
+Ref: doc-cosd688281
+Ref: doc-tand688497
+Ref: doc-secd688770
+Ref: doc-cscd688920
+Ref: doc-cotd689072
+Ref: doc-asind689225
+Ref: doc-acosd689382
+Ref: doc-atand689541
+Ref: doc-asecd689701
+Ref: doc-acscd689860
+Ref: doc-acotd690021
+Node: Sums and Products690183
+Ref: doc-sum690341
+Ref: doc-prod691040
+Ref: doc-cumsum691393
+Ref: doc-cumprod692030
+Ref: doc-sumsq692470
+Ref: doc-accumarray692981
+Node: Utility Functions694466
+Ref: doc-ceil694629
+Ref: doc-cross694991
+Ref: doc-del2695462
+Ref: doc-factor696684
+Ref: doc-factorial697075
+Ref: doc-fix697461
+Ref: doc-floor697826
+Ref: doc-fmod698193
+Ref: doc-gcd698486
+Ref: doc-gradient699422
+Ref: doc-hypot701332
+Ref: doc-lcm701593
+Ref: doc-list_primes701972
+Ref: doc-max702228
+Ref: doc-min703318
+Ref: doc-cummax704398
+Ref: doc-cummin705209
+Ref: doc-mod706022
+Ref: doc-primes706572
+Ref: doc-rem707046
+Ref: doc-round707390
+Ref: doc-roundb707679
+Ref: doc-sign707951
+Node: Special Functions708197
+Ref: doc-airy708369
+Ref: doc-besselj709488
+Ref: doc-beta711637
+Ref: doc-betainc711785
+Ref: doc-betaln712274
+Ref: doc-bincoeff712526
+Ref: doc-commutation_matrix713061
+Ref: doc-duplication_matrix713448
+Ref: doc-erf713780
+Ref: doc-erfc714105
+Ref: doc-erfinv714265
+Ref: doc-gamma714409
+Ref: doc-gammainc714699
+Ref: doc-legendre715453
+Ref: doc-gammaln717757
+Ref: doc-lgamma717757
+Node: Coordinate Transformations717961
+Ref: doc-cart2pol718156
+Ref: doc-pol2cart718602
+Ref: doc-cart2sph719052
+Ref: doc-sph2cart719482
+Node: Mathematical Constants719912
+Ref: doc-e720073
+Ref: doc-pi720891
+Ref: doc-I721744
+Ref: doc-Inf722674
+Ref: doc-NaN723772
+Ref: doc-eps725067
+Ref: doc-realmax726157
+Ref: doc-realmin727304
+Node: Linear Algebra728432
+Node: Techniques used for Linear Algebra728968
+Node: Basic Matrix Functions730911
+Ref: doc-balance731114
+Ref: doc-cond732591
+Ref: doc-det733055
+Ref: doc-dmult733268
+Ref: doc-dot733434
+Ref: doc-eig733712
+Ref: doc-givens734318
+Ref: doc-planerot734641
+Ref: doc-inv734849
+Ref: doc-matrix_type735426
+Ref: doc-norm738557
+Ref: doc-null739821
+Ref: doc-orth740129
+Ref: doc-pinv740435
+Ref: doc-rank740738
+Ref: doc-rcond741165
+Ref: doc-trace741592
+Ref: doc-rref741670
+Node: Matrix Factorizations741982
+Ref: doc-chol742170
+Ref: doc-cholinv743640
+Ref: doc-chol2inv743856
+Ref: doc-cholupdate744235
+Ref: doc-cholinsert744883
+Ref: doc-choldelete745569
+Ref: doc-cholshift745948
+Ref: doc-hess746437
+Ref: doc-lu747016
+Ref: doc-qr749535
+Ref: doc-qrupdate751736
+Ref: doc-qrinsert752459
+Ref: doc-qrdelete753603
+Ref: doc-qrshift754663
+Ref: doc-qz755106
+Ref: doc-qzhess757030
+Ref: doc-schur757768
+Ref: doc-subspace759217
+Ref: doc-svd759371
+Ref: doc-housh760418
+Ref: doc-krylov761017
+Node: Functions of a Matrix762203
+Ref: doc-expm762388
+Ref: doc-logm763272
+Ref: doc-sqrtm763491
+Ref: doc-kron763860
+Ref: doc-syl764151
+Node: Specialized Solvers764432
+Ref: doc-bicgstab764583
+Ref: doc-cgs765752
+Node: Nonlinear Equations766460
+Ref: doc-fsolve766956
+Ref: doc-fzero772800
+Node: Diagonal and Permutation Matrices773856
+Node: Basic Usage774420
+Node: Creating Diagonal Matrices775655
+Node: Creating Permutation Matrices776763
+Node: Explicit and Implicit Conversions778525
+Node: Matrix Algebra779795
+Node: Expressions Involving Diagonal Matrices780422
+Node: Expressions Involving Permutation Matrices783665
+Node: Function Support785786
+Node: Diagonal Matrix Functions786422
+Node: Permutation Matrix Functions787109
+Node: Example Codes787877
+Node: Zeros Treatment789135
+Node: Sparse Matrices792268
+Node: Basics792694
+Node: Storage of Sparse Matrices793993
+Ref: Storage of Sparse Matrices-Footnote-1798190
+Node: Creating Sparse Matrices798338
+Ref: doc-spdiags800270
+Ref: doc-speye801339
+Ref: doc-spfun801834
+Ref: doc-spmax802077
+Ref: doc-spmin802221
+Ref: doc-spones802365
+Ref: doc-sprand802515
+Ref: doc-sprandn803098
+Ref: doc-sprandsym803702
+Ref: doc-full806434
+Ref: doc-spalloc806613
+Ref: doc-sparse807376
+Ref: doc-spconvert808845
+Node: Information809585
+Ref: doc-issparse810653
+Ref: doc-nnz810764
+Ref: doc-nonzeros810900
+Ref: doc-nzmax811003
+Ref: doc-spstats811470
+Ref: fig:spmatrix813563
+Ref: doc-spy815521
+Ref: doc-etree815952
+Ref: doc-etreeplot816525
+Ref: doc-gplot816863
+Ref: doc-treeplot817518
+Ref: doc-treelayout817949
+Node: Operators and Functions818414
+Node: Sparse Functions818720
+Node: Return Types of Operators and Functions820627
+Ref: doc-sparse_auto_mutate823109
+Node: Mathematical Considerations823734
+Ref: fig:simplematrix826888
+Ref: fig:simplechol828659
+Ref: fig:simplecholperm829450
+Ref: doc-amd830615
+Ref: doc-ccolamd831930
+Ref: doc-colamd835847
+Ref: doc-colperm839451
+Ref: doc-csymamd839768
+Ref: doc-dmperm842554
+Ref: doc-symamd843348
+Ref: doc-symrcm846809
+Node: Sparse Linear Algebra847847
+Ref: doc-normest852054
+Ref: doc-onenormest852507
+Ref: doc-condest853921
+Ref: doc-spparms855622
+Ref: doc-sprank858018
+Ref: doc-symbfact858466
+Ref: doc-spaugment859811
+Ref: doc-eigs861330
+Ref: doc-svds867207
+Ref: Sparse Linear Algebra-Footnote-1869349
+Node: Iterative Techniques869488
+Ref: doc-pcg870011
+Ref: doc-pcr876188
+Ref: doc-luinc880895
+Node: Real Life Example883349
+Node: Numerical Integration888779
+Node: Functions of One Variable889212
+Ref: doc-quad890035
+Ref: doc-quad_options891478
+Ref: doc-quadl893580
+Ref: doc-quadgk894691
+Ref: doc-quadv898643
+Ref: doc-trapz899891
+Ref: doc-cumtrapz900331
+Node: Orthogonal Collocation900838
+Ref: doc-colloc901015
+Node: Functions of Multiple Variables902027
+Ref: doc-dblquad903546
+Ref: doc-triplequad904317
+Node: Differential Equations906022
+Node: Ordinary Differential Equations906453
+Ref: doc-lsode906792
+Ref: doc-lsode_options909538
+Node: Differential-Algebraic Equations912630
+Ref: doc-daspk913058
+Ref: doc-daspk_options915648
+Ref: doc-dassl922145
+Ref: doc-dassl_options924813
+Ref: doc-dasrt927272
+Ref: doc-dasrt_options931490
+Node: Optimization933463
+Node: Linear Programming933935
+Ref: doc-glpk934317
+Node: Quadratic Programming946892
+Ref: doc-qp947253
+Node: Nonlinear Programming948355
+Ref: doc-sqp948644
+Node: Linear Least Squares952777
+Ref: doc-ols953337
+Ref: doc-gls954117
+Ref: doc-lsqnonneg954719
+Ref: doc-optimset955999
+Ref: doc-optimget956222
+Node: Statistics956522
+Node: Descriptive Statistics957511
+Ref: doc-mean957747
+Ref: doc-median958448
+Ref: doc-quantile958987
+Ref: doc-prctile961708
+Ref: doc-meansq962467
+Ref: doc-std962795
+Ref: doc-var963653
+Ref: doc-mode964242
+Ref: doc-cov964767
+Ref: doc-cor965082
+Ref: doc-corrcoef965579
+Ref: doc-kurtosis965968
+Ref: doc-skewness966330
+Ref: doc-statistics966678
+Ref: doc-moment967008
+Node: Basic Statistical Functions967551
+Ref: doc-mahalanobis967810
+Ref: doc-center968062
+Ref: doc-studentize968320
+Ref: doc-nchoosek968607
+Ref: doc-histc969434
+Ref: doc-perms970544
+Ref: doc-values970903
+Ref: doc-table971103
+Ref: doc-spearman971360
+Ref: doc-run_count971986
+Ref: doc-ranks972231
+Ref: doc-range972431
+Ref: doc-probit972753
+Ref: doc-logit972895
+Ref: doc-cloglog973026
+Ref: doc-kendall973165
+Ref: doc-iqr974056
+Ref: doc-cut974388
+Node: Statistical Plots974935
+Ref: doc-qqplot975402
+Ref: doc-ppplot976342
+Node: Tests977206
+Ref: doc-anova978784
+Ref: doc-bartlett_test979794
+Ref: doc-chisquare_test_homogeneity980283
+Ref: doc-chisquare_test_independence980902
+Ref: doc-cor_test981361
+Ref: doc-f_test_regression982766
+Ref: doc-hotelling_test983280
+Ref: doc-hotelling_test_2983848
+Ref: doc-kolmogorov_smirnov_test984532
+Ref: doc-kolmogorov_smirnov_test_2985901
+Ref: doc-kruskal_wallis_test987073
+Ref: doc-manova988208
+Ref: doc-mcnemar_test988855
+Ref: doc-prop_test_2989407
+Ref: doc-run_test990275
+Ref: doc-sign_test990610
+Ref: doc-t_test991568
+Ref: doc-t_test_2992420
+Ref: doc-t_test_regression993306
+Ref: doc-u_test994163
+Ref: doc-var_test995057
+Ref: doc-welch_test995945
+Ref: doc-wilcoxon_test996845
+Ref: doc-z_test997801
+Ref: doc-z_test_2998652
+Node: Models999536
+Ref: doc-logistic_regression999650
+Node: Distributions1001332
+Ref: doc-betacdf1003920
+Ref: doc-betainv1004099
+Ref: doc-betapdf1004274
+Ref: doc-binocdf1004417
+Ref: doc-binoinv1004564
+Ref: doc-binopdf1004716
+Ref: doc-cauchy_cdf1004894
+Ref: doc-cauchy_inv1005172
+Ref: doc-cauchy_pdf1005445
+Ref: doc-chi2cdf1005723
+Ref: doc-chi2inv1005910
+Ref: doc-chi2pdf1006087
+Ref: doc-discrete_cdf1006271
+Ref: doc-discrete_inv1006499
+Ref: doc-discrete_pdf1006717
+Ref: doc-empirical_cdf1006941
+Ref: doc-empirical_inv1007152
+Ref: doc-empirical_pdf1007358
+Ref: doc-expcdf1007565
+Ref: doc-expinv1007802
+Ref: doc-exppdf1007976
+Ref: doc-fcdf1008146
+Ref: doc-finv1008319
+Ref: doc-fpdf1008488
+Ref: doc-gamcdf1008664
+Ref: doc-gaminv1009035
+Ref: doc-gampdf1009398
+Ref: doc-geocdf1009759
+Ref: doc-geoinv1009896
+Ref: doc-geopdf1010038
+Ref: doc-hygecdf1010206
+Ref: doc-hygeinv1010676
+Ref: doc-hygepdf1010935
+Ref: doc-kolmogorov_smirnov_cdf1011347
+Ref: doc-laplace_cdf1011715
+Ref: doc-laplace_inv1011870
+Ref: doc-laplace_pdf1012020
+Ref: doc-logistic_cdf1012171
+Ref: doc-logistic_inv1012295
+Ref: doc-logistic_pdf1012449
+Ref: doc-logncdf1012573
+Ref: doc-logninv1012955
+Ref: doc-lognpdf1013330
+Ref: doc-nbincdf1013708
+Ref: doc-nbininv1014011
+Ref: doc-nbinpdf1014319
+Ref: doc-normcdf1014658
+Ref: doc-norminv1014895
+Ref: doc-normpdf1015127
+Ref: doc-poisscdf1015360
+Ref: doc-poissinv1015547
+Ref: doc-poisspdf1015726
+Ref: doc-tcdf1015904
+Ref: doc-tinv1016114
+Ref: doc-tpdf1016426
+Ref: doc-unidcdf1016608
+Ref: doc-unidinv1016830
+Ref: doc-unidpdf1017050
+Ref: doc-unifcdf1017268
+Ref: doc-unifinv1017449
+Ref: doc-unifpdf1017650
+Ref: doc-wblcdf1017821
+Ref: doc-wblinv1018083
+Ref: doc-wblpdf1018272
+Node: Random Number Generation1018576
+Ref: doc-betarnd1020050
+Ref: doc-binornd1020400
+Ref: doc-cauchy_rnd1020756
+Ref: doc-chi2rnd1021147
+Ref: doc-discrete_rnd1021478
+Ref: doc-empirical_rnd1021917
+Ref: doc-exprnd1022301
+Ref: doc-frnd1022674
+Ref: doc-gamrnd1023078
+Ref: doc-geornd1023616
+Ref: doc-hygernd1023963
+Ref: doc-laplace_rnd1024454
+Ref: doc-logistic_rnd1024661
+Ref: doc-lognrnd1024870
+Ref: doc-nbinrnd1025290
+Ref: doc-normrnd1025702
+Ref: doc-poissrnd1026078
+Ref: doc-trnd1026363
+Ref: doc-unidrnd1026722
+Ref: doc-unifrnd1027201
+Ref: doc-wblrnd1027541
+Ref: doc-wienrnd1027954
+Node: Sets1028409
+Ref: doc-unique1028706
+Node: Set Operations1029732
+Ref: doc-ismember1030241
+Ref: doc-union1031502
+Ref: doc-intersect1032261
+Ref: doc-complement1032740
+Ref: doc-setdiff1033024
+Ref: doc-setxor1033670
+Node: Polynomial Manipulations1034219
+Node: Evaluating Polynomials1034775
+Ref: doc-polyval1035683
+Ref: doc-polyvalm1036703
+Node: Finding Roots1037295
+Ref: doc-roots1037667
+Ref: doc-compan1038156
+Ref: doc-mpoles1039247
+Node: Products of Polynomials1040302
+Ref: doc-conv1040501
+Ref: doc-convn1040994
+Ref: doc-deconv1041723
+Ref: doc-conv21042272
+Ref: doc-polygcd1042856
+Ref: doc-residue1043821
+Node: Derivatives and Integrals1046359
+Ref: doc-polyderiv1046955
+Ref: doc-polyder1047695
+Ref: doc-polyinteg1047831
+Ref: doc-polyint1048374
+Node: Polynomial Interpolation1048926
+Ref: doc-polyfit1049634
+Ref: doc-ppval1051364
+Ref: doc-mkpp1051705
+Ref: doc-unmkpp1052574
+Node: Miscellaneous Functions1053524
+Ref: doc-poly1053700
+Ref: doc-polyout1054588
+Ref: doc-polyreduce1055137
+Node: Interpolation1055596
+Node: One-dimensional Interpolation1055814
+Ref: doc-interp11056221
+Ref: doc-interp1q1059578
+Ref: doc-interpft1060520
+Ref: doc-spline1061992
+Ref: doc-lookup1063575
+Node: Multi-dimensional Interpolation1065060
+Ref: doc-interp21065446
+Ref: doc-interp31067319
+Ref: doc-interpn1069146
+Ref: doc-bicubic1072068
+Node: Geometry1072442
+Ref: Geometry-Footnote-11072941
+Node: Delaunay Triangulation1073127
+Ref: doc-delaunay1073847
+Ref: doc-delaunay31075196
+Ref: doc-delaunayn1075749
+Node: Plotting the Triangulation1077426
+Ref: doc-triplot1077743
+Ref: doc-trimesh1078255
+Node: Identifying points in Triangulation1079121
+Ref: doc-tsearch1081394
+Ref: doc-tsearchn1081731
+Ref: doc-dsearch1082960
+Ref: doc-dsearchn1083312
+Node: Voronoi Diagrams1084251
+Ref: doc-voronoi1084897
+Ref: doc-voronoin1085865
+Ref: doc-polyarea1086958
+Ref: doc-rectint1087895
+Ref: doc-inpolygon1088371
+Node: Convex Hull1089001
+Ref: doc-convhull1089387
+Ref: doc-convhulln1089876
+Node: Interpolation on Scattered Data1090786
+Ref: doc-griddata1091462
+Ref: doc-griddata31092001
+Ref: doc-griddatan1092453
+Node: Signal Processing1093179
+Ref: doc-detrend1093532
+Ref: doc-fft1093900
+Ref: doc-fftw1095462
+Ref: doc-ifft1098569
+Ref: doc-fft21099546
+Ref: doc-ifft21100001
+Ref: doc-fftn1100466
+Ref: doc-ifftn1100982
+Ref: doc-fftconv1101517
+Ref: doc-fftfilt1101964
+Ref: doc-filter1102276
+Ref: doc-filter21103852
+Ref: doc-freqz1104428
+Ref: doc-freqz_plot1105671
+Ref: doc-sinc1105770
+Ref: doc-unwrap1105831
+Ref: doc-arch_fit1106191
+Ref: doc-arch_rnd1107083
+Ref: doc-arch_test1107462
+Ref: doc-arma_rnd1108429
+Ref: doc-autocor1109009
+Ref: doc-autocov1109239
+Ref: doc-autoreg_matrix1109466
+Ref: doc-bartlett1109821
+Ref: doc-blackman1110073
+Ref: doc-diffpara1110307
+Ref: doc-durbinlevinson1111043
+Ref: doc-fftshift1111446
+Ref: doc-ifftshift1112114
+Ref: doc-fractdiff1112326
+Ref: doc-hamming1112478
+Ref: doc-hanning1112709
+Ref: doc-hurst1112938
+Ref: doc-pchip1113130
+Ref: doc-periodogram1114330
+Ref: doc-rectangle_lw1114446
+Ref: doc-rectangle_sw1114572
+Ref: doc-sinetone1114703
+Ref: doc-sinewave1114997
+Ref: doc-spectral_adf1115200
+Ref: doc-spectral_xdf1115590
+Ref: doc-spencer1115966
+Ref: doc-stft1116079
+Ref: doc-synthesis1117066
+Ref: doc-triangle_lw1117331
+Ref: doc-triangle_sw1117455
+Ref: doc-yulewalker1117584
+Node: Image Processing1117822
+Node: Loading and Saving Images1118647
+Ref: doc-imread1119328
+Ref: doc-imwrite1119863
+Ref: doc-IMAGE_PATH1120557
+Ref: doc-imfinfo1121033
+Node: Displaying Images1123373
+Ref: doc-imshow1124002
+Ref: doc-image1125203
+Ref: doc-imagesc1125989
+Ref: doc-image_viewer1126762
+Node: Representing Images1128597
+Ref: doc-gray2ind1129894
+Ref: doc-ind2gray1130122
+Ref: doc-rgb2ind1130456
+Ref: doc-ind2rgb1130684
+Ref: doc-colormap1131183
+Ref: doc-brighten1131803
+Ref: doc-autumn1132530
+Ref: doc-bone1132804
+Ref: doc-cool1133086
+Ref: doc-copper1133344
+Ref: doc-flag1133618
+Ref: doc-gray1133900
+Ref: doc-hot1134130
+Ref: doc-hsv1134429
+Ref: doc-jet1134933
+Ref: doc-ocean1135241
+Ref: doc-pink1135413
+Ref: doc-prism1135698
+Ref: doc-rainbow1136002
+Ref: doc-spring1136302
+Ref: doc-summer1136565
+Ref: doc-white1136826
+Ref: doc-winter1137087
+Ref: doc-contrast1137346
+Ref: doc-gmap401138005
+Ref: doc-spinmap1138638
+Node: Plotting on top of Images1138990
+Node: Color Conversion1140061
+Ref: doc-rgb2hsv1140295
+Ref: doc-hsv2rgb1140800
+Ref: doc-rgb2ntsc1140966
+Ref: doc-ntsc2rgb1141103
+Node: Audio Processing1141240
+Ref: doc-lin2mu1142526
+Ref: doc-mu2lin1143068
+Ref: doc-loadaudio1143563
+Ref: doc-saveaudio1144218
+Ref: doc-playaudio1145155
+Ref: doc-record1145516
+Ref: doc-setaudio1146004
+Ref: doc-wavread1146113
+Ref: doc-wavwrite1146923
+Node: Object Oriented Programming1147351
+Node: Creating a Class1148213
+Ref: doc-isobject1151831
+Ref: doc-methods1151990
+Ref: doc-ismethod1152283
+Node: Manipulating Classes1152507
+Ref: doc-display1153116
+Ref: doc-saveobj1157058
+Ref: doc-loadobj1157986
+Node: Indexing Objects1158521
+Ref: doc-subsref1159146
+Ref: doc-subsasgn1161449
+Ref: doc-subsindex1163347
+Ref: doc-colon1164336
+Node: Overloading Objects1164680
+Node: Function Overloading1164961
+Node: Operator Overloading1166561
+Ref: tab:overload_ops1166753
+Ref: doc-rdivide1166753
+Ref: doc-plus1166753
+Ref: doc-minus1166753
+Ref: doc-uminus1166753
+Ref: doc-uplus1166753
+Ref: doc-times1166753
+Ref: doc-mtimes1166753
+Ref: doc-mrdivide1166753
+Ref: doc-ldivide1166753
+Ref: doc-mldivide1166753
+Ref: doc-power1166753
+Ref: doc-mpower1166753
+Ref: doc-lt1166753
+Ref: doc-le1166753
+Ref: doc-gt1166753
+Ref: doc-ge1166753
+Ref: doc-eq1166753
+Ref: doc-ne1166753
+Ref: doc-and1166753
+Ref: doc-or1166753
+Ref: doc-not1166753
+Ref: doc-ctranspose1166753
+Ref: doc-transpose1166753
+Node: Precedence of Objects1170390
+Ref: doc-superiorto1170936
+Ref: doc-inferiorto1171254
+Node: Inheritance and Aggregation1173060
+Node: System Utilities1180130
+Node: Timing Utilities1180948
+Ref: doc-time1181918
+Ref: doc-now1182621
+Ref: doc-ctime1183135
+Ref: doc-gmtime1183493
+Ref: doc-localtime1184457
+Ref: doc-mktime1185423
+Ref: doc-asctime1186049
+Ref: doc-strftime1186351
+Ref: doc-strptime1189556
+Ref: doc-clock1190548
+Ref: doc-date1190880
+Ref: doc-etime1191043
+Ref: doc-cputime1191517
+Ref: doc-is_leap_year1192208
+Ref: doc-toc1192460
+Ref: doc-tic1192460
+Ref: doc-pause1193880
+Ref: doc-sleep1194322
+Ref: doc-usleep1194443
+Ref: doc-datenum1194749
+Ref: doc-datestr1196356
+Ref: doc-datevec1200561
+Ref: doc-addtodate1201423
+Ref: doc-calendar1201684
+Ref: doc-weekday1202301
+Ref: doc-eomday1202831
+Ref: doc-datetick1203032
+Node: Filesystem Utilities1203709
+Ref: doc-rename1204067
+Ref: doc-link1204360
+Ref: doc-symlink1204672
+Ref: doc-readlink1205002
+Ref: doc-unlink1205389
+Ref: doc-readdir1205614
+Ref: doc-mkdir1206016
+Ref: doc-rmdir1206450
+Ref: doc-confirm_recursive_rmdir1207047
+Ref: doc-mkfifo1207322
+Ref: doc-umask1207583
+Ref: doc-lstat1207904
+Ref: doc-stat1207904
+Ref: doc-fstat1210397
+Ref: doc-fileattrib1210561
+Ref: doc-isdir1211799
+Ref: doc-glob1211868
+Ref: doc-fnmatch1212381
+Ref: doc-file_in_path1212696
+Ref: doc-tilde_expand1213558
+Ref: doc-canonicalize_file_name1214251
+Ref: doc-movefile1214381
+Ref: doc-copyfile1214866
+Ref: doc-fileparts1215473
+Ref: doc-filesep1215671
+Ref: doc-filemarker1216182
+Ref: doc-fullfile1216865
+Ref: doc-tempdir1217050
+Ref: doc-tempname1217155
+Ref: doc-P_tmpdir1217243
+Ref: doc-is_absolute_filename1217416
+Ref: doc-is_rooted_relative_filename1217519
+Ref: doc-make_absolute_filename1217635
+Node: File Archiving Utilities1217760
+Ref: doc-bunzip21217956
+Ref: doc-gzip1218346
+Ref: doc-gunzip1218911
+Ref: doc-tar1219402
+Ref: doc-untar1219923
+Ref: doc-zip1220286
+Ref: doc-unzip1220690
+Ref: doc-pack1221053
+Ref: doc-unpack1221186
+Ref: doc-bzip21221901
+Node: Networking Utilities1222445
+Ref: doc-urlread1222637
+Ref: doc-urlwrite1223892
+Node: Controlling Subprocesses1225295
+Ref: doc-system1225956
+Ref: doc-unix1227350
+Ref: doc-dos1227895
+Ref: doc-perl1228467
+Ref: doc-popen1228797
+Ref: doc-pclose1229686
+Ref: doc-popen21229835
+Ref: doc-EXEC_PATH1231123
+Ref: doc-fork1232072
+Ref: doc-exec1232757
+Ref: doc-pipe1233260
+Ref: doc-dup21233581
+Ref: doc-waitpid1233833
+Ref: doc-WCONTINUE1235553
+Ref: doc-WCOREDUMP1235908
+Ref: doc-WEXITSTATUS1236582
+Ref: doc-WIFCONTINUED1237086
+Ref: doc-WIFSIGNALED1237549
+Ref: doc-WIFSTOPPED1238003
+Ref: doc-WIFEXITED1238589
+Ref: doc-WNOHANG1239030
+Ref: doc-WSTOPSIG1239377
+Ref: doc-WTERMSIG1239912
+Ref: doc-WUNTRACED1240460
+Ref: doc-fcntl1240830
+Ref: doc-kill1242166
+Ref: doc-SIG1242749
+Node: Process ID Information1242865
+Ref: doc-getpgrp1243072
+Ref: doc-getpid1243171
+Ref: doc-getppid1243262
+Ref: doc-geteuid1243353
+Ref: doc-getuid1243453
+Ref: doc-getegid1243546
+Ref: doc-getgid1243647
+Node: Environment Variables1243741
+Ref: doc-getenv1243935
+Ref: doc-putenv1244127
+Node: Current Working Directory1244277
+Ref: doc-cd1244484
+Ref: doc-ls1244971
+Ref: doc-ls_command1245573
+Ref: doc-dir1245834
+Ref: doc-pwd1246848
+Node: Password Database Functions1246979
+Ref: doc-getpwent1247639
+Ref: doc-getpwuid1247860
+Ref: doc-getpwnam1248092
+Ref: doc-setpwent1248330
+Ref: doc-endpwent1248448
+Node: Group Database Functions1248519
+Ref: doc-getgrent1249075
+Ref: doc-getgrgid1249265
+Ref: doc-getgrnam1249474
+Ref: doc-setgrent1249688
+Ref: doc-endgrent1249798
+Node: System Information1249866
+Ref: doc-computer1250047
+Ref: doc-uname1250732
+Ref: doc-ispc1251284
+Ref: doc-isunix1251453
+Ref: doc-ismac1251627
+Ref: doc-isieee1251796
+Ref: doc-OCTAVE_HOME1251939
+Ref: doc-OCTAVE_VERSION1252048
+Ref: doc-license1252146
+Ref: doc-version1253295
+Ref: doc-ver1253448
+Ref: doc-octave_config_info1254294
+Ref: doc-getrusage1254540
+Node: Hashing Functions1256007
+Ref: doc-md5sum1256968
+Node: Packages1257200
+Node: Installing and Removing Packages1258021
+Ref: doc-pkg1260488
+Node: Using Packages1267019
+Node: Administrating Packages1267633
+Node: Creating Packages1269114
+Ref: doc-PKG_ADD1270227
+Node: The DESCRIPTION File1272979
+Node: The INDEX file1276971
+Node: PKG_ADD and PKG_DEL directives1279244
+Node: Dynamically Linked Functions1280371
+Node: Oct-Files1282406
+Node: Getting Started with Oct-Files1283032
+Ref: doc-mkoctfile1283341
+Node: Matrices and Arrays in Oct-Files1288888
+Node: Character Strings in Oct-Files1295720
+Node: Cell Arrays in Oct-Files1298171
+Node: Structures in Oct-Files1299472
+Node: Sparse Matrices in Oct-Files1301907
+Node: Array and Sparse Differences1303353
+Node: Creating Sparse Matrices in Oct-Files1306411
+Node: Using Sparse Matrices in Oct-Files1313344
+Node: Accessing Global Variables in Oct-Files1314291
+Node: Calling Octave Functions from Oct-Files1315843
+Node: Calling External Code from Oct-Files1319015
+Node: Allocating Local Memory in Oct-Files1323265
+Node: Input Parameter Checking in Oct-Files1323940
+Node: Exception and Error Handling in Oct-Files1326629
+Node: Documentation and Test of Oct-Files1330061
+Node: Mex-Files1332304
+Node: Getting Started with Mex-Files1333447
+Ref: doc-mex1333929
+Ref: doc-mexext1334155
+Node: Working with Matrices and Arrays in Mex-Files1337342
+Node: Character Strings in Mex-Files1341107
+Node: Cell Arrays with Mex-Files1342842
+Node: Structures with Mex-Files1344372
+Node: Sparse Matrices with Mex-Files1348033
+Node: Calling Other Functions in Mex-Files1353218
+Node: Standalone Programs1354546
+Node: Test and Demo Functions1357340
+Node: Test Functions1357741
+Ref: doc-test1357886
+Ref: doc-assert1366395
+Ref: doc-fail1367827
+Node: Demonstration Functions1368560
+Ref: doc-demo1368723
+Ref: doc-rundemos1370784
+Ref: doc-example1370826
+Ref: doc-speed1371336
+Node: Tips and Standards1376388
+Node: Style Tips1377065
+Node: Coding Tips1378816
+Node: Comment Tips1384428
+Node: Function Headers1385594
+Node: Documentation Tips1389990
+Node: Contributing Guidelines1399176
+Node: How to Contribute1399546
+Node: General Guidelines1402791
+Node: Octave Sources (m-files)1405206
+Node: C++ Sources1406705
+Node: Other Sources1409569
+Node: Trouble1411230
+Node: Actual Bugs1411963
+Node: Reporting Bugs1412785
+Ref: doc-bug_report1413931
+Node: Bug Criteria1414360
+Node: Bug Lists1415585
+Node: Bug Reporting1416371
+Node: Sending Patches1421836
+Node: Service1424661
+Node: Installation1425380
+Node: Installation Problems1434879
+Node: Emacs Octave Support1441991
+Node: Installing EOS1443216
+Node: Using Octave Mode1443951
+Node: Running Octave From Within Emacs1454833
+Node: Using the Emacs Info Reader for Octave1459099
+Node: Copying1460245
+Node: Concept Index1497821
+Node: Function Index1536883
+Node: Operator Index1672473
+
+End Tag Table
diff --git a/doc/interpreter/octave.info-1 b/doc/interpreter/octave.info-1
new file mode 100644
index 0000000..1eb5157
--- /dev/null
+++ b/doc/interpreter/octave.info-1
@@ -0,0 +1,8835 @@
+This is octave.info, produced by makeinfo version 4.11 from ./octave.texi.
+
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, 2007
+John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+File: octave.info,  Node: Top,  Next: Preface,  Up: (dir)
+
+GNU Octave
+**********
+
+This manual documents how to run, install and port GNU Octave, as well
+as its new features and incompatibilities, and how to report bugs.  It
+corresponds to GNU Octave version 3.2.4.
+
+* Menu:
+
+* Preface::
+* Introduction::                A brief introduction to Octave.
+* Getting Started::
+* Data Types::
+* Numeric Data Types::
+* Strings::
+* Data Containers::
+* Variables::
+* Expressions::
+* Evaluation::
+* Statements::                  Looping and program flow control.
+* Functions and Scripts::
+* Errors and Warnings::
+* Debugging::
+* Input and Output::
+* Plotting::
+* Matrix Manipulation::
+* Arithmetic::
+* Linear Algebra::
+* Nonlinear Equations::
+* Diagonal and Permutation Matrices::
+* Sparse Matrices::
+* Numerical Integration::
+* Differential Equations::
+* Optimization::
+* Statistics::
+* Sets::
+* Polynomial Manipulations::
+* Interpolation::
+* Geometry::
+* Signal Processing::
+* Image Processing::
+* Audio Processing::
+* Object Oriented Programming::
+* System Utilities::
+* Packages::
+* Dynamically Linked Functions::
+* Test and Demo Functions::
+* Tips and Standards::
+* Contributing Guidelines::
+* Trouble::                     If you have trouble installing Octave.
+* Installation::                How to configure, compile and install Octave.
+* Emacs Octave Support::
+* Copying::                     The GNU General Public License.
+* Concept Index::               An item for each concept.
+* Function Index::              An item for each documented function.
+* Operator Index::              An item for each documented operator.
+
+ --- The Detailed Node Listing ---
+
+Preface
+
+* Acknowledgements::
+* How You Can Contribute to Octave::
+* Distribution::
+
+Introduction
+
+* Running Octave::
+* Simple Examples::
+* Conventions::
+
+Conventions
+
+* Fonts::
+* Evaluation Notation::
+* Printing Notation::
+* Error Messages::
+* Format of Descriptions::
+
+Format of Descriptions
+
+* A Sample Function Description::
+* A Sample Command Description::
+* A Sample Variable Description::
+
+Getting Started
+
+* Invoking Octave from the Command Line::
+* Quitting Octave::
+* Getting Help::
+* Command Line Editing::
+* Errors::
+* Executable Octave Programs::
+* Comments::
+
+Invoking Octave from the Command Line
+
+* Command Line Options::
+* Startup Files::
+
+Command Line Editing
+
+* Cursor Motion::
+* Killing and Yanking::
+* Commands For Text::
+* Commands For Completion::
+* Commands For History::
+* Customizing readline::
+* Customizing the Prompt::
+* Diary and Echo Commands::
+
+Comments
+
+* Single Line Comments::
+* Block Comments::
+* Comments and the Help System::
+
+Data Types
+
+* Built-in Data Types::
+* User-defined Data Types::
+* Object Sizes::
+
+Built-in Data Types
+
+* Numeric Objects::
+* Missing Data::
+* String Objects::
+* Data Structure Objects::
+* Cell Array Objects::
+
+Numeric Data Types
+
+* Matrices::
+* Ranges::
+* Single Precision Data Types::
+* Integer Data Types::
+* Bit Manipulations::
+* Logical Values::
+* Promotion and Demotion of Data Types::
+* Predicates for Numeric Objects::
+
+Matrices
+
+* Empty Matrices::
+
+Integer Data Types
+
+* Integer Arithmetic::
+
+Strings
+
+* Escape Sequences in string constants::
+* Character Arrays::
+* Creating Strings::
+* Comparing Strings::
+* Manipulating Strings::
+* String Conversions::
+* Character Class Functions::
+
+Creating Strings
+
+* Concatenating Strings::
+* Conversion of Numerical Data to Strings::
+
+Data Containers
+
+* Data Structures::
+* Cell Arrays::
+* Comma Separated Lists::
+
+Data Structures
+
+* Structure Arrays::
+* Creating Structures::
+* Manipulating Structures::
+* Processing Data in Structures::
+
+Cell Arrays
+
+* Creating Cell Arrays::
+* Indexing Cell Arrays::
+* Cell Arrays of Strings::
+* Processing Data in Cell Arrays::
+
+Variables
+
+* Global Variables::
+* Persistent Variables::
+* Status of Variables::
+
+Expressions
+
+* Index Expressions::
+* Calling Functions::
+* Arithmetic Ops::
+* Comparison Ops::
+* Boolean Expressions::
+* Assignment Ops::
+* Increment Ops::
+* Operator Precedence::
+
+Calling Functions
+
+* Call by Value::
+* Recursion::
+
+Boolean Expressions
+
+* Element-by-element Boolean Operators::
+* Short-circuit Boolean Operators::
+
+Evaluation
+
+* Calling a Function by its Name::
+* Evaluation in a Different Context::
+
+Statements
+
+* The `if' Statement::
+* The `switch' Statement::
+* The `while' Statement::
+* The `do-until' Statement::
+* The `for' Statement::
+* The `break' Statement::
+* The `continue' Statement::
+* The `unwind_protect' Statement::
+* The `try' Statement::
+* Continuation Lines::
+
+The `switch' Statement
+
+* Notes for the C programmer::
+
+The `for' Statement
+
+* Looping Over Structure Elements::
+
+Functions and Scripts
+
+* Defining Functions::
+* Multiple Return Values::
+* Variable-length Argument Lists::
+* Variable-length Return Lists::
+* Returning From a Function::
+* Default Arguments::
+* Function Files::
+* Script Files::
+* Function Handles Inline Functions and Anonymous Functions::
+* Commands::
+* Organization of Functions::
+
+Function Files
+
+* Manipulating the load path::
+* Subfunctions::
+* Private Functions::
+* Overloading and Autoloading::
+* Function Locking::
+* Function Precedence::
+
+Function Handles Inline Functions and Anonymous Functions
+
+* Function Handles::
+* Anonymous Functions::
+* Inline Functions::
+
+Errors and Warnings
+
+* Handling Errors::
+* Handling Warnings::
+
+Handling Errors
+
+* Raising Errors::
+* Catching Errors::
+
+Handling Warnings
+
+* Issuing Warnings::
+* Enabling and Disabling Warnings::
+
+Debugging
+
+* Entering Debug Mode::
+* Leaving Debug Mode::
+* Breakpoints::
+* Debug Mode::
+* Call Stack::
+
+Input and Output
+
+* Basic Input and Output::
+* C-Style I/O Functions::
+
+Basic Input and Output
+
+* Terminal Output::
+* Terminal Input::
+* Simple File I/O::
+* Rational Approximations::
+
+Terminal Output
+
+* Paging Screen Output::
+
+Simple File I/O
+
+* Saving Data on Unexpected Exits::
+
+C-Style I/O Functions
+
+* Opening and Closing Files::
+* Simple Output::
+* Line-Oriented Input::
+* Formatted Output::
+* Output Conversion for Matrices::
+* Output Conversion Syntax::
+* Table of Output Conversions::
+* Integer Conversions::
+* Floating-Point Conversions::
+* Other Output Conversions::
+* Formatted Input::
+* Input Conversion Syntax::
+* Table of Input Conversions::
+* Numeric Input Conversions::
+* String Input Conversions::
+* Binary I/O::
+* Temporary Files::
+* EOF and Errors::
+* File Positioning::
+
+Plotting
+
+* Plotting Basics::
+* Advanced Plotting::
+
+Plotting Basics
+
+* Two-Dimensional Plots::
+* Three-Dimensional Plotting::
+* Plot Annotations::
+* Multiple Plots on One Page::
+* Multiple Plot Windows::
+* Printing Plots::
+* Interacting with plots::
+* Test Plotting Functions::
+
+Two-Dimensional Plots
+
+* Two-dimensional Function Plotting::
+
+Three-Dimensional Plotting
+
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
+
+Advanced Plotting
+
+* Graphics Objects::
+* Graphics Object Properties::
+* Managing Default Properties::
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
+* Object Groups::
+* Graphics backends::
+
+Graphics Object Properties
+
+* Root Figure Properties::
+* Figure Properties::
+* Axes Properties::
+* Line Properties::
+* Text Properties::
+* Image Properties::
+* Patch Properties::
+* Surface Properties::
+* Searching Properties::
+
+Object Groups
+
+* Data sources in object groups::
+* Area series::
+* Bar series::
+* Contour groups::
+* Error bar series::
+* Line series::
+* Quiver group::
+* Scatter group::
+* Stair group::
+* Stem Series::
+* Surface group::
+
+Graphics backends
+
+* Interaction with gnuplot::
+
+Matrix Manipulation
+
+* Finding Elements and Checking Conditions::
+* Rearranging Matrices::
+* Applying a Function to an Array::
+* Special Utility Matrices::
+* Famous Matrices::
+
+Arithmetic
+
+* Exponents and Logarithms::
+* Complex Arithmetic::
+* Trigonometry::
+* Sums and Products::
+* Utility Functions::
+* Special Functions::
+* Coordinate Transformations::
+* Mathematical Constants::
+
+Linear Algebra
+
+* Techniques used for Linear Algebra::
+* Basic Matrix Functions::
+* Matrix Factorizations::
+* Functions of a Matrix::
+* Specialized Solvers::
+
+Diagonal and Permutation Matrices
+
+* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Function Support::     Functions That Are Aware of These Matrices
+* Example Codes::        Some Examples of Usage
+* Zeros Treatment::      The Differences in Treatment of Zero Elements
+
+Basic Usage
+
+* Creating Diagonal Matrices::
+* Creating Permutation Matrices::
+* Explicit and Implicit Conversions::
+
+Matrix Algebra
+
+* Expressions Involving Diagonal Matrices::
+* Expressions Involving Permutation Matrices::
+
+Function Support
+
+* Diagonal Matrix Functions::
+* Permutation Matrix Functions::
+
+Sparse Matrices
+
+* Basics::                      Creation and Manipulation of Sparse Matrices
+* Sparse Linear Algebra::       Linear Algebra on Sparse Matrices
+* Iterative Techniques::        Iterative Techniques
+* Real Life Example::           Using Sparse Matrices
+
+Basics
+
+* Storage of Sparse Matrices::
+* Creating Sparse Matrices::
+* Information::
+* Operators and Functions::
+
+Operators and Functions
+
+* Sparse Functions::
+* Return Types of Operators and Functions::
+* Mathematical Considerations::
+
+Numerical Integration
+
+* Functions of One Variable::
+* Functions of Multiple Variables::
+* Orthogonal Collocation::
+
+Differential Equations
+
+* Ordinary Differential Equations::
+* Differential-Algebraic Equations::
+
+Optimization
+
+* Linear Programming::
+* Quadratic Programming::
+* Nonlinear Programming::
+* Linear Least Squares::
+
+Statistics
+
+* Descriptive Statistics::
+* Basic Statistical Functions::
+* Statistical Plots::
+* Tests::
+* Models::
+* Distributions::
+* Random Number Generation::
+
+Sets
+
+* Set Operations::
+
+Polynomial Manipulations
+
+* Evaluating Polynomials::
+* Finding Roots::
+* Products of Polynomials::
+* Derivatives and Integrals::
+* Polynomial Interpolation::
+* Miscellaneous Functions::
+
+Interpolation
+
+* One-dimensional Interpolation::
+* Multi-dimensional Interpolation::
+
+Geometry
+
+* Delaunay Triangulation::
+* Voronoi Diagrams::
+* Convex Hull::
+* Interpolation on Scattered Data::
+
+Delaunay Triangulation
+
+* Plotting the Triangulation::
+* Identifying points in Triangulation::
+
+Image Processing
+
+* Loading and Saving Images::
+* Displaying Images::
+* Representing Images::
+* Plotting on top of Images::
+* Color Conversion::
+
+Object Oriented Programming
+
+* Creating a Class::
+* Manipulating Classes::
+* Indexing Objects::
+* Overloading Objects::
+
+Overloading Objects
+
+* Function Overloading::
+* Operator Overloading::
+* Precedence of Objects::
+
+System Utilities
+
+* Timing Utilities::
+* Filesystem Utilities::
+* File Archiving Utilities::
+* Networking Utilities::
+* Controlling Subprocesses::
+* Process ID Information::
+* Environment Variables::
+* Current Working Directory::
+* Password Database Functions::
+* Group Database Functions::
+* System Information::
+* Hashing Functions::
+
+Packages
+
+* Installing and Removing Packages::
+* Using Packages::
+* Administrating Packages::
+* Creating Packages::
+
+Creating Packages
+
+* The DESCRIPTION File::
+* The INDEX file::
+* PKG_ADD and PKG_DEL directives::
+
+Dynamically Linked Functions
+
+* Oct-Files::
+* Mex-Files::
+* Standalone Programs::
+
+Oct-Files
+
+* Getting Started with Oct-Files::
+* Matrices and Arrays in Oct-Files::
+* Character Strings in Oct-Files::
+* Cell Arrays in Oct-Files::
+* Structures in Oct-Files::
+* Sparse Matrices in Oct-Files::
+* Accessing Global Variables in Oct-Files::
+* Calling Octave Functions from Oct-Files::
+* Calling External Code from Oct-Files::
+* Allocating Local Memory in Oct-Files::
+* Input Parameter Checking in Oct-Files::
+* Exception and Error Handling in Oct-Files::
+* Documentation and Test of Oct-Files::
+
+Sparse Matrices in Oct-Files
+
+* Array and Sparse Differences::
+* Creating Sparse Matrices in Oct-Files::
+* Using Sparse Matrices in Oct-Files::
+
+Mex-Files
+
+* Getting Started with Mex-Files::
+* Working with Matrices and Arrays in Mex-Files::
+* Character Strings in Mex-Files::
+* Cell Arrays with Mex-Files::
+* Structures with Mex-Files::
+* Sparse Matrices with Mex-Files::
+* Calling Other Functions in Mex-Files::
+
+Test and Demo Functions
+
+* Test Functions::
+* Demonstration Functions::
+
+Tips and Standards
+
+* Style Tips::                  Writing clean and robust programs.
+* Coding Tips::                 Making code run faster.
+* Comment Tips::                Conventions for writing comments.
+* Function Headers::            Standard headers for functions.
+* Documentation Tips::          Writing readable documentation strings.
+
+Contributing Guidelines
+
+* How to Contribute::
+* General Guidelines::
+* Octave Sources (m-files)::
+* C++ Sources::
+* Other Sources::
+
+Trouble
+
+* Actual Bugs::                 Bugs we will fix later.
+* Reporting Bugs::
+* Bug Criteria::
+* Bug Lists::
+* Bug Reporting::
+* Sending Patches::
+* Service::
+
+Reporting Bugs
+
+* Bug Criteria::
+* Where: Bug Lists.             Where to send your bug report.
+* Reporting: Bug Reporting.     How to report a bug effectively.
+* Patches: Sending Patches.     How to send a patch for Octave.
+
+Installation
+
+* Installation Problems::
+
+Emacs Octave Support
+
+* Installing EOS::
+* Using Octave Mode::
+* Running Octave From Within Emacs::
+* Using the Emacs Info Reader for Octave::
+
+
+File: octave.info,  Node: Preface,  Next: Introduction,  Prev: Top,  Up: Top
+
+Preface
+*******
+
+Octave was originally intended to be companion software for an
+undergraduate-level textbook on chemical reactor design being written by
+James B. Rawlings of the University of Wisconsin-Madison and John G.
+Ekerdt of the University of Texas.
+
+   Clearly, Octave is now much more than just another `courseware'
+package with limited utility beyond the classroom.  Although our
+initial goals were somewhat vague, we knew that we wanted to create
+something that would enable students to solve realistic problems, and
+that they could use for many things other than chemical reactor design
+problems.
+
+   There are those who would say that we should be teaching the students
+Fortran instead, because that is the computer language of engineering,
+but every time we have tried that, the students have spent far too much
+time trying to figure out why their Fortran code crashes and not enough
+time learning about chemical engineering.  With Octave, most students
+pick up the basics quickly, and are using it confidently in just a few
+hours.
+
+   Although it was originally intended to be used to teach reactor
+design, it has been used in several other undergraduate and graduate
+courses in the Chemical Engineering Department at the University of
+Texas, and the math department at the University of Texas has been using
+it for teaching differential equations and linear algebra as well.  If
+you find it useful, please let us know.  We are always interested to
+find out how Octave is being used in other places.
+
+   Virtually everyone thinks that the name Octave has something to do
+with music, but it is actually the name of a former professor of mine
+who wrote a famous textbook on chemical reaction engineering, and who
+was also well known for his ability to do quick `back of the envelope'
+calculations.  We hope that this software will make it possible for many
+people to do more ambitious computations just as easily.
+
+   Everyone is encouraged to share this software with others under the
+terms of the GNU General Public License (*note Copying::).  You are
+also encouraged to help make Octave more useful by writing and
+contributing additional functions for it, and by reporting any problems
+you may have.
+
+* Menu:
+
+* Acknowledgements::
+* How You Can Contribute to Octave::
+* Distribution::
+
+
+File: octave.info,  Node: Acknowledgements,  Next: How You Can Contribute to Octave,  Up: Preface
+
+Acknowledgements
+================
+
+Many people have already contributed to Octave's development.  The
+following people have helped code parts of Octave or aided in various
+other ways (listed alphabetically).
+
+Ben Abbott               Andy Adler               Joel Andersson
+Muthiah Annamalai        Shai Ayal                Roger Banks
+Ben Barrowes             Alexander Barth          David Bateman
+Heinz Bauschke           Karl Berry               David Billinghurst
+Don Bindner              Jakub Bogusz             Moritz Borgmann
+Richard Bovey            Marcus Brinkmann         Remy Bruno
+Marco Caliari            Daniel Calvelo           John C. Campbell
+Jean-Francois Cardoso    Joao Cardoso             Larrie Carr
+David Castelow           Vincent Cautaerts        Clinton Chee
+Albert Chin-A-Young      Carsten Clark            J. D. Cole
+Martin Costabel          Michael Creel            Jeff Cunningham
+Martin Dalecki           Jorge Barros de Abreu    Carlo de Falco
+Thomas D. Dean           Philippe Defert          Bill Denney
+David M. Doolin          Pascal A. Dupuis         John W. Eaton
+Dirk Eddelbuettel        Paul Eggert              Stephen Eglen
+Peter Ekberg             Rolf Fabian              Stephen Fegan
+Ramon Garcia Fernandez   Torsten Finke            Jose Daniel Munoz Frias
+Castor Fu                Eduardo Gallestey        Walter Gautschi
+Klaus Gebhardt           Driss Ghaddab            Nicolo Giorgetti
+Michael Goffioul         Glenn Golden             Tomislav Goles
+Keith Goodman            Brian Gough              Steffen Groot
+Etienne Grossmann        Peter Gustafson          Kai Habel
+William P. Y.            Jaroslav Hajek           Benjamin Hall
+Hadisoeseno                                       
+Kim Hansen               Soren Hauberg            Dave Hawthorne
+Daniel Heiserer          Martin Helm              Stefan Hepp
+Yozo Hida                Ryan Hinton              Roman Hodek
+A. Scottedward Hodel     Richard Allan Holcombe   Tom Holroyd
+David Hoover             Kurt Hornik              Christopher Hulbert
+Cyril Humbert            Teemu Ikonen             Alan W. Irwin
+Geoff Jacobsen           Mats Jansson             Cai Jianming
+Steven G. Johnson        Heikki Junes             Atsushi Kajita
+Jarkko Kaleva            Mohamed Kamoun           Lute Kamstra
+Thomas Kasper            Joel Keay                Mumit Khan
+Paul Kienzle             Aaron A. King            Arno J. Klaassen
+Geoffrey Knauth          Heine Kolltveit          Ken Kouno
+Oyvind Kristiansen       Piotr Krzyzanowski       Volker Kuhlmann
+Tetsuro Kurita           Miroslaw Kwasniak        Rafael Laboissiere
+Kai Labusch              Claude Lacoursiere       Walter Landry
+Bill Lash                Dirk Laurie              Maurice LeBrun
+Friedrich Leisch         Timo Lindfors            Benjamin Lindner
+Ross Lippert             David Livings            Erik de Castro Lopo
+Massimo Lorenzin         Emil Lucretiu            Hoxide Ma
+James Macnicol           Jens-Uwe Mager           Ricardo Marranita
+Orestes Mas              Makoto Matsumoto         Tatsuro Matsuoka
+Laurent Mazet            G. D. McBain             Alexander Mamonov
+Christoph Mayer          Thorsten Meyer           Petr Mikulik
+Stefan Monnier           Antoine Moreau           Kai P. Mueller
+Victor Munoz             Carmen Navarrete         Todd Neal
+Al Niessner              Rick Niles               Takuji Nishimura
+Kai Noda                 Eric Norum               Krzesimir Nowak
+Michael O'Brien          Peter O'Gorman           Thorsten Ohl
+Arno Onken               Luis F. Ortiz            Scott Pakin
+Gabriele Pannocchia      Sylvain Pelissier        Per Persson
+Primozz Peterlin         Jim Peterson             Danilo Piazzalunga
+Nicholas Piper           Robert Platt             Hans Ekkehard Plesser
+Tom Poage                Orion Poplawski          Ondrej Popp
+Jef Poskanzer            Francesco Potorti        James B. Rawlings
+Eric S. Raymond          Balint Reczey            Michael Reifenberger
+Jason Riedy              Petter Risholm           Matthew W. Roberts
+Andrew Ross              Mark van Rossum          Kevin Ruland
+Ryan Rusaw               Olli Saarela             Toni Saarela
+Juhani Saastamoinen      Radek Salac              Ben Sapp
+Aleksej Saushev          Alois Schloegl           Michel D. Schmid
+Julian Schnidder         Nicol N. Schraudolph     Sebastian Schubert
+Ludwig Schwardt          Thomas L. Scofield       Daniel J. Sebald
+Dmitri A. Sergatskov     Baylis Shanks            Joseph P. Skudlarek
+John Smith               Julius Smith             Shan G. Smith
+Joerg Specht             Quentin H. Spencer       Christoph Spiel
+Richard Stallman         Russell Standish         Doug Stewart
+Jonathan Stickel         Thomas Stuart            Ivan Sutoris
+John Swensen             Ariel Tankus             Georg Thimm
+Duncan Temple Lang       Kris Thielemans          Olaf Till
+Thomas Treichl           Frederick Umminger       Utkarsh Upadhyay
+Stefan van der Walt      Peter Van Wieren         James R. Van Zandt
+Gregory Vanuxem          Ivana Varekova           Thomas Walter
+Olaf Weber               Thomas Weber             Rik Wehbring
+Bob Weigel               Andreas Weingessel       Michael Weitzel
+Fook Fah Yap             Michael Zeising          Federico Zenith
+Alex Zvoleff                                      
+
+   Special thanks to the following people and organizations for
+supporting the development of Octave:
+
+   * The United States Department of Energy, through grant number
+     DE-FG02-04ER25635.
+
+   * Ashok Krishnamurthy, David Hudak, Juan Carlos Chaves, and Stanley
+     C. Ahalt of the Ohio Supercomputer Center.
+
+   * The National Science Foundation, through grant numbers CTS-0105360,
+     CTS-9708497, CTS-9311420, CTS-8957123, and CNS-0540147.
+
+   * The industrial members of the Texas-Wisconsin Modeling and Control
+     Consortium (TWMCC (http://www.che.utexas.edu/twmcc)).
+
+   * The Paul A. Elfers Endowed Chair in Chemical Engineering at the
+     University of Wisconsin-Madison.
+
+   * Digital Equipment Corporation, for an equipment grant as part of
+     their External Research Program.
+
+   * Sun Microsystems, Inc., for an Academic Equipment grant.
+
+   * International Business Machines, Inc., for providing equipment as
+     part of a grant to the University of Texas College of Engineering.
+
+   * Texaco Chemical Company, for providing funding to continue the
+     development of this software.
+
+   * The University of Texas College of Engineering, for providing a
+     Challenge for Excellence Research Supplement, and for providing an
+     Academic Development Funds grant.
+
+   * The State of Texas, for providing funding through the Texas
+     Advanced Technology Program under Grant No. 003658-078.
+
+   * Noel Bell, Senior Engineer, Texaco Chemical Company, Austin Texas.
+
+   * John A. Turner, Group Leader, Continuum Dynamics (CCS-2), Los
+     Alamos National Laboratory, for registering the `octave.org'
+     domain name.
+
+   * James B. Rawlings, Professor, University of Wisconsin-Madison,
+     Department of Chemical and Biological Engineering.
+
+   * Richard Stallman, for writing GNU.
+
+   This project would not have been possible without the GNU software
+used in and to produce Octave.
+
+
+File: octave.info,  Node: How You Can Contribute to Octave,  Next: Distribution,  Prev: Acknowledgements,  Up: Preface
+
+How You Can Contribute to Octave
+================================
+
+There are a number of ways that you can contribute to help make Octave a
+better system.  Perhaps the most important way to contribute is to write
+high-quality code for solving new problems, and to make your code freely
+available for others to use.  *Note Contributing Guidelines::, for
+detailed information on contributing new code.
+
+   If you find Octave useful, consider providing additional funding to
+continue its development.  Even a modest amount of additional funding
+could make a significant difference in the amount of time that is
+available for development and support.
+
+   If you cannot provide funding or contribute code, you can still help
+make Octave better and more reliable by reporting any bugs you find and
+by offering suggestions for ways to improve Octave.  *Note Trouble::,
+for tips on how to write useful bug reports.
+
+
+File: octave.info,  Node: Distribution,  Prev: How You Can Contribute to Octave,  Up: Preface
+
+Distribution
+============
+
+Octave is "free" software.  This means that everyone is free to use it
+and free to redistribute it on certain conditions.  Octave is not,
+however, in the public domain.  It is copyrighted and there are
+restrictions on its distribution, but the restrictions are designed to
+ensure that others will have the same freedom to use and redistribute
+Octave that you have.  The precise conditions can be found in the GNU
+General Public License that comes with Octave and that also appears in
+*note Copying::.
+
+   Octave is available on CD-ROM, with various collections of other free
+software, from the Free Software Foundation.  Ordering a copy of Octave
+from the Free Software Foundation helps to fund the development of more
+free software.  For more information, write to
+
+     Free Software Foundation
+     51 Franklin Street, Fifth Floor
+     Boston, MA 02110-1301-1307
+     USA
+
+   Octave can also be downloaded from `http://www.octave.org', where
+additional information is available.
+
+
+File: octave.info,  Node: Introduction,  Next: Getting Started,  Prev: Preface,  Up: Top
+
+1 A Brief Introduction to Octave
+********************************
+
+GNU Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient interactive command line
+interface for solving linear and nonlinear problems numerically, and
+for performing other numerical experiments.  It may also be used as a
+batch-oriented language for data processing.
+
+   GNU Octave is freely redistributable software.  You may redistribute
+it and/or modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation.  The GPL is included in
+this manual in *note Copying::.
+
+   This manual provides comprehensive documentation on how to install,
+run, use, and extend GNU Octave.  Additional chapters describe how to
+report bugs and help contribute code.
+
+   This document corresponds to Octave version 3.2.4.
+
+* Menu:
+
+* Running Octave::
+* Simple Examples::
+* Conventions::
+
+
+File: octave.info,  Node: Running Octave,  Next: Simple Examples,  Up: Introduction
+
+1.1 Running Octave
+==================
+
+On most systems, Octave is started with the shell command `octave'.
+Octave displays an initial message and then a prompt indicating it is
+ready to accept input.  You can begin typing Octave commands
+immediately afterward.
+
+   If you get into trouble, you can usually interrupt Octave by typing
+`Control-C' (written `C-c' for short).  `C-c' gets its name from the
+fact that you type it by holding down <CTRL> and then pressing <c>.
+Doing this will normally return you to Octave's prompt.
+
+   To exit Octave, type `quit', or `exit' at the Octave prompt.
+
+   On systems that support job control, you can suspend Octave by
+sending it a `SIGTSTP' signal, usually by typing `C-z'.
+
+
+File: octave.info,  Node: Simple Examples,  Next: Conventions,  Prev: Running Octave,  Up: Introduction
+
+1.2 Simple Examples
+===================
+
+The following chapters describe all of Octave's features in detail, but
+before doing that, it might be helpful to give a sampling of some of its
+capabilities.
+
+   If you are new to Octave, I recommend that you try these examples to
+begin learning Octave by using it.  Lines marked with `octave:13>' are
+lines you type, ending each with a carriage return.  Octave will
+respond with an answer, or by displaying a graph.
+
+1.2.1 Elementary Calculations
+-----------------------------
+
+Octave can easily be used for basic numerical calculations.  Octave
+knows about arithmetic operations (+,-,*,/), exponentiation (^),
+natural logarithms/exponents (log, exp), and the trigonometric
+functions (sin, cos, ...).  Moreover, Octave calculations work on real
+or imaginary numbers (i,j).  In addition, some mathematical constants
+such as the base of the natural logarithm (e) and the ratio of a
+circle's circumference to its diameter (pi) are pre-defined.
+
+For example, to verify Euler's Identity,
+
+      i*pi
+     e     = -1
+
+type the following which will evaluate to `-1' within the tolerance of
+the calculation.
+
+     octave:1> exp(i*pi)
+
+1.2.2 Creating a Matrix
+-----------------------
+
+Vectors and matrices are the basic building blocks for numerical
+analysis.  To create a new matrix and store it in a variable so that
+you can refer to it later, type the command
+
+     octave:1> A = [ 1, 1, 2; 3, 5, 8; 13, 21, 34 ]
+
+Octave will respond by printing the matrix in neatly aligned columns.
+Octave uses a comma or space to separate entries in a row, and a
+semicolon or carriage return to separate one row from the next.  Ending
+a command with a semicolon tells Octave not to print the result of the
+command.  For example,
+
+     octave:2> B = rand (3, 2);
+
+will create a 3 row, 2 column matrix with each element set to a random
+value between zero and one.
+
+   To display the value of a variable, simply type the name of the
+variable at the prompt.  For example, to display the value stored in the
+matrix `B', type the command
+
+     octave:3> B
+
+1.2.3 Matrix Arithmetic
+-----------------------
+
+Octave has a convenient operator notation for performing matrix
+arithmetic.  For example, to multiply the matrix `A' by a scalar value,
+type the command
+
+     octave:4> 2 * A
+
+To multiply the two matrices `A' and `B', type the command
+
+     octave:5> A * B
+
+and to form the matrix product `transpose (A) * A', type the command
+
+     octave:6> A' * A
+
+1.2.4 Solving Systems of Linear Equations
+-----------------------------------------
+
+Systems of linear equations are ubiquitous in numerical analysis.  To
+solve the set of linear equations `AX = b', use the left division
+operator, `\':
+
+     X = A \ b
+
+This is conceptually equivalent to `inv (a) * b', but avoids computing
+the inverse of a matrix directly.
+
+   If the coefficient matrix is singular, Octave will print a warning
+message and compute a minimum norm solution.
+
+   A simple example comes from chemistry and the need to obtain balanced
+chemical equations.  Consider the burning of hydrogen and oxygen to
+produce water.
+
+     H2 + O2 --> H2O
+
+The equation above is not accurate.  The Law of Conservation of Mass
+requires that the number of molecules of each type balance on the left-
+and right-hand sides of the equation.  Writing the variable overall
+reaction with individual equations for hydrogen and oxygen one finds:
+
+     x1*H2 + x2*O2 --> H2O
+     H: 2*x1 + 0*x2 --> 2
+     O: 0*x1 + 2*x2 --> 1
+
+The solution in Octave is found in just three steps.
+
+     octave:1> A = [ 2, 0; 0, 2 ];
+     octave:2> b = [ 2; 1 ];
+     octave:3> x = A \ b
+
+1.2.5 Integrating Differential Equations
+----------------------------------------
+
+Octave has built-in functions for solving nonlinear differential
+equations of the form
+
+     dx
+     -- = f (x, t)
+     dt
+
+with the initial condition
+
+     x(t = t0) = x0
+
+For Octave to integrate equations of this form, you must first provide a
+definition of the function `f(x,t)'.  This is straightforward, and may
+be accomplished by entering the function body directly on the command
+line.  For example, the following commands define the right-hand side
+function for an interesting pair of nonlinear differential equations.
+Note that while you are entering a function, Octave responds with a
+different prompt, to indicate that it is waiting for you to complete
+your input.
+
+     octave:1> function xdot = f (x, t)
+     >
+     >  r = 0.25;
+     >  k = 1.4;
+     >  a = 1.5;
+     >  b = 0.16;
+     >  c = 0.9;
+     >  d = 0.8;
+     >
+     >  xdot(1) = r*x(1)*(1 - x(1)/k) - a*x(1)*x(2)/(1 + b*x(1));
+     >  xdot(2) = c*a*x(1)*x(2)/(1 + b*x(1)) - d*x(2);
+     >
+     > endfunction
+
+Given the initial condition
+
+     octave:2> x0 = [1; 2];
+
+and the set of output times as a column vector (note that the first
+output time corresponds to the initial condition given above)
+
+     octave:3> t = linspace (0, 50, 200)';
+
+it is easy to integrate the set of differential equations:
+
+     octave:4> x = lsode ("f", x0, t);
+
+The function `lsode' uses the Livermore Solver for Ordinary
+Differential Equations, described in A. C. Hindmarsh, `ODEPACK, a
+Systematized Collection of ODE Solvers', in: Scientific Computing, R. S.
+Stepleman et al. (Eds.), North-Holland, Amsterdam, 1983, pages 55-64.
+
+1.2.6 Producing Graphical Output
+--------------------------------
+
+To display the solution of the previous example graphically, use the
+command
+
+     octave:1> plot (t, x)
+
+If you are using a graphical user interface, Octave will automatically
+create a separate window to display the plot.
+
+   To save a plot once it has been displayed on the screen, use the
+print command.  For example,
+
+     print -deps foo.eps
+
+will create a file called `foo.eps' that contains a rendering of the
+current plot in Encapsulated PostScript format.  The command
+
+     help print
+
+explains more options for the `print' command and provides a list of
+additional output file formats.
+
+1.2.7 Editing What You Have Typed
+---------------------------------
+
+At the Octave prompt, you can recall, edit, and reissue previous
+commands using Emacs- or vi-style editing commands.  The default
+keybindings use Emacs-style commands.  For example, to recall the
+previous command, press `Control-p' (written `C-p' for short).  Doing
+this will normally bring back the previous line of input.  `C-n' will
+bring up the next line of input, `C-b' will move the cursor backward on
+the line, `C-f' will move the cursor forward on the line, etc.
+
+   A complete description of the command line editing capability is
+given in this manual in *note Command Line Editing::.
+
+1.2.8 Help and Documentation
+----------------------------
+
+Octave has an extensive help facility.  The same documentation that is
+available in printed form is also available from the Octave prompt,
+because both forms of the documentation are created from the same input
+file.
+
+   In order to get good help you first need to know the name of the
+command that you want to use.  This name of the function may not always
+be obvious, but a good place to start is to just type `help'.  This
+will show you all the operators, reserved words, functions, built-in
+variables, and function files.  An alternative is to search the
+documentation using the `lookfor' function.  This function is described
+in *note Getting Help::.
+
+   Once you know the name of the function you wish to use, you can get
+more help on the function by simply including the name as an argument
+to help.  For example,
+
+     help plot
+
+will display the help text for the `plot' function.
+
+   Octave sends output that is too long to fit on one screen through a
+pager like `less' or `more'.  Type a <RET> to advance one line, a <SPC>
+to advance one page, and <q> to exit the pager.
+
+   The part of Octave's help facility that allows you to read the
+complete text of the printed manual from within Octave normally uses a
+separate program called Info.  When you invoke Info you will be put
+into a menu driven program that contains the entire Octave manual.
+Help for using Info is provided in this manual in *note Getting Help::.
+
+
+File: octave.info,  Node: Conventions,  Prev: Simple Examples,  Up: Introduction
+
+1.3 Conventions
+===============
+
+This section explains the notational conventions that are used in this
+manual.  You may want to skip this section and refer back to it later.
+
+* Menu:
+
+* Fonts::
+* Evaluation Notation::
+* Printing Notation::
+* Error Messages::
+* Format of Descriptions::
+
+
+File: octave.info,  Node: Fonts,  Next: Evaluation Notation,  Up: Conventions
+
+1.3.1 Fonts
+-----------
+
+Examples of Octave code appear in this font or form: `svd (a)'.  Names
+that represent variables or function arguments appear in this font or
+form: FIRST-NUMBER.  Commands that you type at the shell prompt appear
+in this font or form: `octave --no-init-file'.  Commands that you type
+at the Octave prompt sometimes appear in this font or form: `foo --bar
+--baz'.  Specific keys on your keyboard appear in this font or form:
+<ANY>.
+
+
+File: octave.info,  Node: Evaluation Notation,  Next: Printing Notation,  Prev: Fonts,  Up: Conventions
+
+1.3.2 Evaluation Notation
+-------------------------
+
+In the examples in this manual, results from expressions that you
+evaluate are indicated with `=>'.  For example,
+
+     sqrt (2)
+          => 1.4142
+
+You can read this as "`sqrt (2)' evaluates to 1.4142".
+
+   In some cases, matrix values that are returned by expressions are
+displayed like this
+
+     [1, 2; 3, 4] == [1, 3; 2, 4]
+          => [ 1, 0; 0, 1 ]
+
+and in other cases, they are displayed like this
+
+     eye (3)
+          =>  1  0  0
+              0  1  0
+              0  0  1
+
+in order to clearly show the structure of the result.
+
+   Sometimes to help describe one expression, another expression is
+shown that produces identical results.  The exact equivalence of
+expressions is indicated with `=='.  For example,
+
+     rot90 ([1, 2; 3, 4], -1)
+     ==
+     rot90 ([1, 2; 3, 4], 3)
+     ==
+     rot90 ([1, 2; 3, 4], 7)
+
+
+File: octave.info,  Node: Printing Notation,  Next: Error Messages,  Prev: Evaluation Notation,  Up: Conventions
+
+1.3.3 Printing Notation
+-----------------------
+
+Many of the examples in this manual print text when they are evaluated.
+In this manual the printed text resulting from an example is indicated
+by `-|'.  The value that is returned by evaluating the expression is
+displayed with `=>' (`1' in the next example) and follows on a separate
+line.
+
+     printf ("foo %s\n", "bar")
+          -| foo bar
+          => 1
+
+
+File: octave.info,  Node: Error Messages,  Next: Format of Descriptions,  Prev: Printing Notation,  Up: Conventions
+
+1.3.4 Error Messages
+--------------------
+
+Some examples signal errors.  This normally displays an error message
+on your terminal.  Error messages are shown on a line beginning with
+`error:'.
+
+     fieldnames ([1, 2; 3, 4])
+     error: fieldnames: wrong type argument `matrix'
+
+
+File: octave.info,  Node: Format of Descriptions,  Prev: Error Messages,  Up: Conventions
+
+1.3.5 Format of Descriptions
+----------------------------
+
+Functions, commands, and variables are described in this manual in a
+uniform format.  The first line of a description contains the name of
+the item followed by its arguments, if any.  The category--function,
+variable, or whatever--appears at the beginning of the line.  The
+description follows on succeeding lines, sometimes with examples.
+
+* Menu:
+
+* A Sample Function Description::
+* A Sample Command Description::
+* A Sample Variable Description::
+
+
+File: octave.info,  Node: A Sample Function Description,  Next: A Sample Command Description,  Up: Format of Descriptions
+
+1.3.5.1 A Sample Function Description
+.....................................
+
+In a function description, the name of the function being described
+appears first.  It is followed on the same line by a list of parameters.
+The names used for the parameters are also used in the body of the
+description.
+
+   Here is a description of an imaginary function `foo':
+
+ -- Function:  foo (X, Y, ...)
+     The function `foo' subtracts X from Y, then adds the remaining
+     arguments to the result.  If Y is not supplied, then the number 19
+     is used by default.
+
+          foo (1, [3, 5], 3, 9)
+               => [ 14, 16 ]
+          foo (5)
+               => 14
+
+     More generally,
+
+          foo (W, X, Y, ...)
+          ==
+          X - W + Y + ...
+
+   Any parameter whose name contains the name of a type (e.g., INTEGER
+or MATRIX) is expected to be of that type.  Parameters named OBJECT may
+be of any type.  Parameters with other sorts of names (e.g., NEW_FILE)
+are discussed specifically in the description of the function.  In some
+sections, features common to parameters of several functions are
+described at the beginning.
+
+   Functions in Octave may be defined in several different ways.  The
+category name for functions may include another name that indicates the
+way that the function is defined.  These additional tags include
+
+Function File
+     The function described is defined using Octave commands stored in
+     a text file.  *Note Function Files::.
+
+Built-in Function
+     The function described is written in a language like C++, C, or
+     Fortran, and is part of the compiled Octave binary.
+
+Loadable Function
+     The function described is written in a language like C++, C, or
+     Fortran.  On systems that support dynamic linking of user-supplied
+     functions, it may be automatically linked while Octave is running,
+     but only if it is needed.  *Note Dynamically Linked Functions::.
+
+Mapping Function
+     The function described works element-by-element for matrix and
+     vector arguments.
+
+
+File: octave.info,  Node: A Sample Command Description,  Next: A Sample Variable Description,  Prev: A Sample Function Description,  Up: Format of Descriptions
+
+1.3.5.2 A Sample Command Description
+....................................
+
+Command descriptions have a format similar to function descriptions,
+except that the word `Function' is replaced by `Command'.  Commands are
+functions that may be called without surrounding their arguments in
+parentheses.  For example, here is the description for Octave's `cd'
+command:
+
+ -- Command: cd dir
+ -- Command: chdir dir
+     Change the current working directory to DIR.  For example, `cd
+     ~/octave' changes the current working directory to `~/octave'.  If
+     the directory does not exist, an error message is printed and the
+     working directory is not changed.
+
+
+File: octave.info,  Node: A Sample Variable Description,  Prev: A Sample Command Description,  Up: Format of Descriptions
+
+1.3.5.3 A Sample Variable Description
+.....................................
+
+A "variable" is a name that can hold a value.  Although any variable
+can be set by the user, "built-in variables" typically exist
+specifically so that users can change them to alter the way Octave
+behaves (built-in variables are also sometimes called "user options").
+Ordinary variables and built-in variables are described using a format
+like that for functions except that there are no arguments.
+
+   Here is a description of the imaginary variable
+`do_what_i_mean_not_what_i_say'.
+
+ -- Built-in Variable: do_what_i_mean_not_what_i_say
+     If the value of this variable is nonzero, Octave will do what you
+     actually wanted, even if you have typed a completely different and
+     meaningless list of commands.
+
+   Other variable descriptions have the same format, but `Built-in
+Variable' is replaced by `Variable', for ordinary variables, or
+`Constant' for symbolic constants whose values cannot be changed.
+
+
+File: octave.info,  Node: Getting Started,  Next: Data Types,  Prev: Introduction,  Up: Top
+
+2 Getting Started
+*****************
+
+This chapter explains some of Octave's basic features, including how to
+start an Octave session, get help at the command prompt, edit the
+command line, and write Octave programs that can be executed as commands
+from your shell.
+
+* Menu:
+
+* Invoking Octave from the Command Line::
+* Quitting Octave::
+* Getting Help::
+* Command Line Editing::
+* Errors::
+* Executable Octave Programs::
+* Comments::
+
+
+File: octave.info,  Node: Invoking Octave from the Command Line,  Next: Quitting Octave,  Up: Getting Started
+
+2.1 Invoking Octave from the Command Line
+=========================================
+
+Normally, Octave is used interactively by running the program `octave'
+without any arguments.  Once started, Octave reads commands from the
+terminal until you tell it to exit.
+
+   You can also specify the name of a file on the command line, and
+Octave will read and execute the commands from the named file and then
+exit when it is finished.
+
+   You can further control how Octave starts by using the command-line
+options described in the next section, and Octave itself can remind you
+of the options available.  Type `octave --help' to display all
+available options and briefly describe their use (`octave -h' is a
+shorter equivalent).
+
+* Menu:
+
+* Command Line Options::
+* Startup Files::
+
+
+File: octave.info,  Node: Command Line Options,  Next: Startup Files,  Up: Invoking Octave from the Command Line
+
+2.1.1 Command Line Options
+--------------------------
+
+Here is a complete list of the command line options that Octave accepts.
+
+`--debug'
+`-d'
+     Enter parser debugging mode.  Using this option will cause Octave's
+     parser to print a lot of information about the commands it reads,
+     and is probably only useful if you are actually trying to debug
+     the parser.
+
+`--doc-cache-file FILENAME'
+     Specify the name of the doc cache file to use.  The value of
+     FILENAME specified on the command line will override any value of
+     `OCTAVE_DOC_CACHE_FILE' found in the environment, but not any
+     commands in the system or user startup files that use the
+     `doc_cache_file' function.
+
+`--echo-commands'
+`-x'
+     Echo commands as they are executed.
+
+`--eval CODE'
+     Evaluate CODE and exit when finished unless `--persist' is also
+     specified.
+
+`--exec-path PATH'
+     Specify the path to search for programs to run.  The value of PATH
+     specified on the command line will override any value of
+     `OCTAVE_EXEC_PATH' found in the environment, but not any commands
+     in the system or user startup files that set the built-in variable
+     `EXEC_PATH'.
+
+`--help'
+`-h'
+`-?'
+     Print short help message and exit.
+
+`--image-path PATH'
+     Add path to the head of the search path for images.  The value of
+     PATH specified on the command line will override any value of
+     `OCTAVE_IMAGE_PATH' found in the environment, but not any commands
+     in the system or user startup files that set the built-in variable
+     `IMAGE_PATH'.
+
+`--info-file FILENAME'
+     Specify the name of the info file to use.  The value of FILENAME
+     specified on the command line will override any value of
+     `OCTAVE_INFO_FILE' found in the environment, but not any commands
+     in the system or user startup files that use the `info_file'
+     function.
+
+`--info-program PROGRAM'
+     Specify the name of the info program to use.  The value of PROGRAM
+     specified on the command line will override any value of
+     `OCTAVE_INFO_PROGRAM' found in the environment, but not any
+     commands in the system or user startup files that use the
+     `info_program' function.
+
+`--interactive'
+`-i'
+     Force interactive behavior.  This can be useful for running Octave
+     via a remote shell command or inside an Emacs shell buffer.  For
+     another way to run Octave within Emacs, see *note Emacs Octave
+     Support::.
+
+`--line-editing'
+     Force readline use for command-line editing.
+
+`--no-history'
+`-H'
+     Disable recording of command-line history.
+
+`--no-init-file'
+     Don't read the initialization files `~/.octaverc' and `.octaverc'.
+
+`--no-init-path'
+     Don't initialize the search path for function files to include
+     default locations.
+
+`--no-line-editing'
+     Disable command-line editing.
+
+`--no-site-file'
+     Don't read the site-wide `octaverc' initialization files.
+
+`--norc'
+`-f'
+     Don't read any of the system or user initialization files at
+     startup.  This is equivalent to using both of the options
+     `--no-init-file' and `--no-site-file'.
+
+`--path PATH'
+`-p PATH'
+     Add path to the head of the search path for function files.  The
+     value of PATH specified on the command line will override any value
+     of `OCTAVE_PATH' found in the environment, but not any commands in
+     the system or user startup files that set the internal load path
+     through one of the path functions.
+
+`--persist'
+     Go to interactive mode after `--eval' or reading from a file named
+     on the command line.
+
+`--silent'
+`--quiet'
+`-q'
+     Don't print the usual greeting and version message at startup.
+
+`--traditional'
+`--braindead'
+     For compatibility with MATLAB, set initial values for user
+     preferences to the following values
+
+          PS1                     = ">> "
+          PS2                     = ""
+          beep_on_error           = true
+          confirm_recursive_rmdir = false
+          crash_dumps_octave_core = false
+          default_save_options    = "-mat-binary"
+          fixed_point_format      = true
+          history_timestamp_format_string
+                                  = "%%-- %D %I:%M %p --%%"
+          page_screen_output      = false
+          print_empty_dimensions  = false
+
+     and disable the following warnings
+          Octave:fopen-file-in-path
+          Octave:function-name-clash
+          Octave:load-file-in-path
+
+`--verbose'
+`-V'
+     Turn on verbose output.
+
+`--version'
+`-v'
+     Print the program version number and exit.
+
+`FILE'
+     Execute commands from FILE.  Exit when done unless `--persist' is
+     also specified.
+
+   Octave also includes several functions which return information
+about the command line, including the number of arguments and all of the
+options.
+
+ -- Built-in Function:  argv ()
+     Return the command line arguments passed to Octave.  For example,
+     if you invoked Octave using the command
+
+          octave --no-line-editing --silent
+
+     `argv' would return a cell array of strings with the elements
+     `--no-line-editing' and `--silent'.
+
+     If you write an executable Octave script, `argv' will return the
+     list of arguments passed to the script.  *Note Executable Octave
+     Programs::, for an example of how to create an executable Octave
+     script.
+
+ -- Built-in Function:  program_name ()
+     Return the last component of the value returned by
+     `program_invocation_name'.
+
+     *See also:* *note program_invocation_name:
+     doc-program_invocation_name.
+
+ -- Built-in Function: program_invocation_name ()
+     Return the name that was typed at the shell prompt to run Octave.
+
+     If executing a script from the command line (e.g., `octave foo.m')
+     or using an executable Octave script, the program name is set to
+     the name of the script.  *Note Executable Octave Programs::, for
+     an example of how to create an executable Octave script.
+
+     *See also:* *note program_name: doc-program_name.
+
+   Here is an example of using these functions to reproduce the command
+line which invoked Octave.
+
+     printf ("%s", program_name ());
+     arg_list = argv ();
+     for i = 1:nargin
+       printf (" %s", arg_list{i});
+     endfor
+     printf ("\n");
+
+*Note Indexing Cell Arrays::, for an explanation of how to retrieve
+objects from cell arrays, and *note Defining Functions::, for
+information about the variable `nargin'.
+
+
+File: octave.info,  Node: Startup Files,  Prev: Command Line Options,  Up: Invoking Octave from the Command Line
+
+2.1.2 Startup Files
+-------------------
+
+When Octave starts, it looks for commands to execute from the files in
+the following list.  These files may contain any valid Octave commands,
+including function definitions.
+
+`OCTAVE-HOME/share/octave/site/m/startup/octaverc'
+     where OCTAVE-HOME is the directory in which Octave is installed
+     (the default is `/usr/local').  This file is provided so that
+     changes to the default Octave environment can be made globally for
+     all users at your site for all versions of Octave you have
+     installed.  Care should be taken when making changes to this file
+     since all users of Octave at your site will be affected.  The
+     default file may be overridden by the environment variable
+     `OCTAVE_SITE_INITFILE'.
+
+`OCTAVE-HOME/share/octave/VERSION/m/startup/octaverc'
+     where OCTAVE-HOME is the directory in which Octave is installed
+     (the default is `/usr/local'), and VERSION is the version number
+     of Octave.  This file is provided so that changes to the default
+     Octave environment can be made globally for all users of a
+     particular version of Octave.  Care should be taken when making
+     changes to this file since all users of Octave at your site will be
+     affected.  The default file may be overridden by the environment
+     variable `OCTAVE_VERSION_INITFILE'.
+
+`~/.octaverc'
+     This file is used to make personal changes to the default Octave
+     environment.
+
+`.octaverc'
+     This file can be used to make changes to the default Octave
+     environment for a particular project.  Octave searches for this
+     file in the current directory after it reads `~/.octaverc'.  Any
+     use of the `cd' command in the `~/.octaverc' file will affect the
+     directory where Octave searches for `.octaverc'.
+
+     If you start Octave in your home directory, commands from the file
+     `~/.octaverc' will only be executed once.
+
+   A message will be displayed as each of the startup files is read if
+you invoke Octave with the `--verbose' option but without the
+`--silent' option.
+
+
+File: octave.info,  Node: Quitting Octave,  Next: Getting Help,  Prev: Invoking Octave from the Command Line,  Up: Getting Started
+
+2.2 Quitting Octave
+===================
+
+ -- Built-in Function:  exit (STATUS)
+ -- Built-in Function:  quit (STATUS)
+     Exit the current Octave session.  If the optional integer value
+     STATUS is supplied, pass that value to the operating system as the
+     Octave's exit status.  The default value is zero.
+
+ -- Built-in Function:  atexit (FCN)
+ -- Built-in Function:  atexit (FCN, FLAG)
+     Register a function to be called when Octave exits.  For example,
+
+          function last_words ()
+            disp ("Bye bye");
+          endfunction
+          atexit ("last_words");
+
+     will print the message "Bye bye" when Octave exits.
+
+     The additional argument FLAG will register or unregister FCN from
+     the list of functions to be called when Octave exits.  If FLAG is
+     true, the function is registered, and if FLAG is false, it is
+     unregistered.  For example, after registering the function
+     `last_words' above,
+
+          atexit ("last_words", false);
+
+     will remove the function from the list and Octave will not call
+     `last_words' when it exits.
+
+     Note that `atexit' only removes the first occurrence of a function
+     from the list, so if a function was placed in the list multiple
+     times with `atexit', it must also be removed from the list
+     multiple times.
+
+
+File: octave.info,  Node: Getting Help,  Next: Command Line Editing,  Prev: Quitting Octave,  Up: Getting Started
+
+2.3 Commands for Getting Help
+=============================
+
+The entire text of this manual is available from the Octave prompt via
+the command `doc'.  In addition, the documentation for individual
+user-written functions and variables is also available via the `help'
+command.  This section describes the commands used for reading the
+manual and the documentation strings for user-supplied functions and
+variables.  *Note Function Files::, for more information about how to
+document the functions you write.
+
+ -- Command: help NAME
+     Display the help text for NAME.  If invoked without any arguments,
+     `help' prints a list of all the available operators and functions.
+
+     For example, the command `help help' prints a short message
+     describing the `help' command.
+
+     The help command can give you information about operators, but not
+     the comma and semicolons that are used as command separators.  To
+     get help for those, you must type `help comma' or `help semicolon'.
+
+     *See also:* *note doc: doc-doc, *note lookfor: doc-lookfor, *note
+     which: doc-which.
+
+ -- Command: doc FUNCTION_NAME
+     Display documentation for the function FUNCTION_NAME directly from
+     an on-line version of the printed manual, using the GNU Info
+     browser.  If invoked without any arguments, the manual is shown
+     from the beginning.
+
+     For example, the command `doc rand' starts the GNU Info browser at
+     the `rand' node in the on-line version of the manual.
+
+     Once the GNU Info browser is running, help for using it is
+     available using the command `C-h'.
+
+     *See also:* *note help: doc-help.
+
+ -- Command: lookfor STR
+ -- Command: lookfor -all STR
+ -- Function: [FUNC, HELPSTRING] = lookfor (STR)
+ -- Function: [FUNC, HELPSTRING] = lookfor ('-all', STR)
+     Search for the string STR in all functions found in the current
+     function search path.  By default, `lookfor' searches for STR in
+     the first sentence of the help string of each function found.  The
+     entire help text of each function can be searched if the '-all'
+     argument is supplied.  All searches are case insensitive.
+
+     Called with no output arguments, `lookfor' prints the list of
+     matching functions to the terminal.  Otherwise, the output
+     arguments FUNC and HELPSTRING define the matching functions and the
+     first sentence of each of their help strings.
+
+     The ability of `lookfor' to correctly identify the first sentence
+     of the help text is dependent on the format of the function's
+     help.  All Octave core functions are correctly formatted, but the
+     same can not be guaranteed for external packages and user-supplied
+     functions.  Therefore, the use of the '-all' argument may be
+     necessary to find related functions that are not a part of Octave.
+
+     *See also:* *note help: doc-help, *note doc: doc-doc, *note which:
+     doc-which.
+
+   To see what is new in the current release of Octave, use the `news'
+function.
+
+ -- Function File:  news ()
+     Display the current NEWS file for Octave.
+
+ -- Function File:  info ()
+     Display contact information for the GNU Octave community.
+
+ -- Built-in Function:  warranty ()
+     Describe the conditions for copying and distributing Octave.
+
+   The following functions can be used to change which programs are used
+for displaying the documentation, and where the documentation can be
+found.
+
+ -- Built-in Function: VAL = info_file ()
+ -- Built-in Function: OLD_VAL = info_file (NEW_VAL)
+     Query or set the internal variable that specifies the name of the
+     Octave info file.  The default value is
+     `OCTAVE-HOME/info/octave.info', in which OCTAVE-HOME is the root
+     directory of the Octave installation.  The default value may be
+     overridden by the environment variable `OCTAVE_INFO_FILE', or the
+     command line argument `--info-file NAME'.
+
+     *See also:* *note info_program: doc-info_program, *note doc:
+     doc-doc, *note help: doc-help, *note makeinfo_program:
+     doc-makeinfo_program.
+
+ -- Built-in Function: VAL = info_program ()
+ -- Built-in Function: OLD_VAL = info_program (NEW_VAL)
+     Query or set the internal variable that specifies the name of the
+     info program to run.  The default value is
+     `OCTAVE-HOME/libexec/octave/VERSION/exec/ARCH/info' in which
+     OCTAVE-HOME is the root directory of the Octave installation,
+     VERSION is the Octave version number, and ARCH is the system type
+     (for example, `i686-pc-linux-gnu').  The default value may be
+     overridden by the environment variable `OCTAVE_INFO_PROGRAM', or
+     the command line argument `--info-program NAME'.
+
+     *See also:* *note info_file: doc-info_file, *note doc: doc-doc,
+     *note help: doc-help, *note makeinfo_program: doc-makeinfo_program.
+
+ -- Built-in Function: VAL = makeinfo_program ()
+ -- Built-in Function: OLD_VAL = makeinfo_program (NEW_VAL)
+     Query or set the internal variable that specifies the name of the
+     program that Octave runs to format help text containing Texinfo
+     markup commands.  The default value is `makeinfo'.
+
+     *See also:* *note info_file: doc-info_file, *note info_program:
+     doc-info_program, *note doc: doc-doc, *note help: doc-help.
+
+ -- Built-in Function: VAL = doc_cache_file ()
+ -- Built-in Function: OLD_VAL = doc_cache_file (NEW_VAL)
+     Query or set the internal variable that specifies the name of the
+     Octave documentation cache file.  A cache file significantly
+     improves the performance of the `lookfor' command.  The default
+     value is `OCTAVE-HOME/share/octave/VERSION/etc/doc-cache', in
+     which OCTAVE-HOME is the root directory of the Octave installation,
+     and VERSION is the Octave version number.  The default value may
+     be overridden by the environment variable `OCTAVE_DOC_CACHE_FILE',
+     or the command line argument `--doc-cache-file NAME'.
+
+     *See also:* *note lookfor: doc-lookfor, *note info_program:
+     doc-info_program, *note doc: doc-doc, *note help: doc-help, *note
+     makeinfo_program: doc-makeinfo_program.
+
+ -- Built-in Function: VAL = suppress_verbose_help_message ()
+ -- Built-in Function: OLD_VAL = suppress_verbose_help_message (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will add additional help information to the end of the output from
+     the `help' command and usage messages for built-in commands.
+
+
+File: octave.info,  Node: Command Line Editing,  Next: Errors,  Prev: Getting Help,  Up: Getting Started
+
+2.4 Command Line Editing
+========================
+
+Octave uses the GNU Readline library to provide an extensive set of
+command-line editing and history features.  Only the most common
+features are described in this manual.  In addition, all of the editing
+functions can be bound to different key strokes at the user's
+discretion.  This manual assumes no changes from the default Emacs
+bindings.  See the GNU Readline Library manual for more information on
+customizing Readline and for a complete feature list.
+
+   To insert printing characters (letters, digits, symbols, etc.),
+simply type the character.  Octave will insert the character at the
+cursor and advance the cursor forward.
+
+   Many of the command-line editing functions operate using control
+characters.  For example, the character `Control-a' moves the cursor to
+the beginning of the line.  To type `C-a', hold down <CTRL> and then
+press <a>.  In the following sections, control characters such as
+`Control-a' are written as `C-a'.
+
+   Another set of command-line editing functions use Meta characters.
+To type `M-u', hold down the <META> key and press <u>.  Depending on
+the keyboard, the <META> key may be labeled <ALT> or even <WINDOWS>.
+If your terminal does not have a <META> key, you can still type Meta
+characters using two-character sequences starting with `ESC'.  Thus, to
+enter `M-u', you would type <ESC> <u>.  The `ESC' character sequences
+are also allowed on terminals with real Meta keys.  In the following
+sections, Meta characters such as `Meta-u' are written as `M-u'.
+
+* Menu:
+
+* Cursor Motion::
+* Killing and Yanking::
+* Commands For Text::
+* Commands For Completion::
+* Commands For History::
+* Customizing readline::
+* Customizing the Prompt::
+* Diary and Echo Commands::
+
+
+File: octave.info,  Node: Cursor Motion,  Next: Killing and Yanking,  Up: Command Line Editing
+
+2.4.1 Cursor Motion
+-------------------
+
+The following commands allow you to position the cursor.
+
+`C-b'
+     Move back one character.
+
+`C-f'
+     Move forward one character.
+
+`<DEL>'
+     Delete the character to the left of the cursor.
+
+`C-d'
+     Delete the character underneath the cursor.
+
+`M-f'
+     Move forward a word.
+
+`M-b'
+     Move backward a word.
+
+`C-a'
+     Move to the start of the line.
+
+`C-e'
+     Move to the end of the line.
+
+`C-l'
+     Clear the screen, reprinting the current line at the top.
+
+`C-_'
+`C-/'
+     Undo the last action.  You can undo all the way back to an empty
+     line.
+
+`M-r'
+     Undo all changes made to this line.  This is like typing the `undo'
+     command enough times to get back to the beginning.
+
+   The above table describes the most basic possible keystrokes that
+you need in order to do editing of the input line.  On most terminals,
+you can also use the left and right arrow keys in place of `C-f' and
+`C-b' to move forward and backward.
+
+   Notice how `C-f' moves forward a character, while `M-f' moves
+forward a word.  It is a loose convention that control keystrokes
+operate on characters while meta keystrokes operate on words.
+
+   The function `clc' will allow you to clear the screen from within
+Octave programs.
+
+ -- Built-in Function:  clc ()
+ -- Built-in Function:  home ()
+     Clear the terminal screen and move the cursor to the upper left
+     corner.
+
+
+File: octave.info,  Node: Killing and Yanking,  Next: Commands For Text,  Prev: Cursor Motion,  Up: Command Line Editing
+
+2.4.2 Killing and Yanking
+-------------------------
+
+"Killing" text means to delete the text from the line, but to save it
+away for later use, usually by "yanking" it back into the line.  If the
+description for a command says that it `kills' text, then you can be
+sure that you can get the text back in a different (or the same) place
+later.
+
+   Here is the list of commands for killing text.
+
+`C-k'
+     Kill the text from the current cursor position to the end of the
+     line.
+
+`M-d'
+     Kill from the cursor to the end of the current word, or if between
+     words, to the end of the next word.
+
+`M-<DEL>'
+     Kill from the cursor to the start of the previous word, or if
+     between words, to the start of the previous word.
+
+`C-w'
+     Kill from the cursor to the previous whitespace.  This is
+     different than `M-<DEL>' because the word boundaries differ.
+
+   And, here is how to "yank" the text back into the line.  Yanking
+means to copy the most-recently-killed text from the kill buffer.
+
+`C-y'
+     Yank the most recently killed text back into the buffer at the
+     cursor.
+
+`M-y'
+     Rotate the kill-ring, and yank the new top.  You can only do this
+     if the prior command is `C-y' or `M-y'.
+
+   When you use a kill command, the text is saved in a "kill-ring".
+Any number of consecutive kills save all of the killed text together, so
+that when you yank it back, you get it in one clean sweep.  The kill
+ring is not line specific; the text that you killed on a previously
+typed line is available to be yanked back later, when you are typing
+another line.
+
+
+File: octave.info,  Node: Commands For Text,  Next: Commands For Completion,  Prev: Killing and Yanking,  Up: Command Line Editing
+
+2.4.3 Commands For Changing Text
+--------------------------------
+
+The following commands can be used for entering characters that would
+otherwise have a special meaning (e.g., <TAB>, `C-q', etc.), or for
+quickly correcting typing mistakes.
+
+`C-q'
+`C-v'
+     Add the next character that you type to the line verbatim.  This is
+     how to insert things like `C-q' for example.
+
+`M-<TAB>'
+     Insert a tab character.
+
+`C-t'
+     Drag the character before the cursor forward over the character at
+     the cursor, also moving the cursor forward.  If the cursor is at
+     the end of the line, then transpose the two characters before it.
+
+`M-t'
+     Drag the word behind the cursor past the word in front of the
+     cursor moving the cursor over that word as well.
+
+`M-u'
+     Uppercase the characters following the cursor to the end of the
+     current (or following) word, moving the cursor to the end of the
+     word.
+
+`M-l'
+     Lowercase the characters following the cursor to the end of the
+     current (or following) word, moving the cursor to the end of the
+     word.
+
+`M-c'
+     Uppercase the character following the cursor (or the beginning of
+     the next word if the cursor is between words), moving the cursor
+     to the end of the word.
+
+
+File: octave.info,  Node: Commands For Completion,  Next: Commands For History,  Prev: Commands For Text,  Up: Command Line Editing
+
+2.4.4 Letting Readline Type For You
+-----------------------------------
+
+The following commands allow Octave to complete command and variable
+names for you.
+
+`<TAB>'
+     Attempt to do completion on the text before the cursor.  Octave can
+     complete the names of commands and variables.
+
+`M-?'
+     List the possible completions of the text before the cursor.
+
+ -- Built-in Function: VAL = completion_append_char ()
+ -- Built-in Function: OLD_VAL = completion_append_char (NEW_VAL)
+     Query or set the internal character variable that is appended to
+     successful command-line completion attempts.  The default value is
+     `" "' (a single space).
+
+ -- Built-in Function:  completion_matches (HINT)
+     Generate possible completions given HINT.
+
+     This function is provided for the benefit of programs like Emacs
+     which might be controlling Octave and handling user input.  The
+     current command number is not incremented when this function is
+     called.  This is a feature, not a bug.
+
+
+File: octave.info,  Node: Commands For History,  Next: Customizing readline,  Prev: Commands For Completion,  Up: Command Line Editing
+
+2.4.5 Commands For Manipulating The History
+-------------------------------------------
+
+Octave normally keeps track of the commands you type so that you can
+recall previous commands to edit or execute them again.  When you exit
+Octave, the most recent commands you have typed, up to the number
+specified by the variable `history_size', are saved in a file.  When
+Octave starts, it loads an initial list of commands from the file named
+by the variable `history_file'.
+
+   Here are the commands for simple browsing and searching the history
+list.
+
+`<LFD>'
+`<RET>'
+     Accept the current line regardless of where the cursor is.  If the
+     line is non-empty, add it to the history list.  If the line was a
+     history line, then restore the history line to its original state.
+
+`C-p'
+     Move `up' through the history list.
+
+`C-n'
+     Move `down' through the history list.
+
+`M-<'
+     Move to the first line in the history.
+
+`M->'
+     Move to the end of the input history, i.e., the line you are
+     entering!
+
+`C-r'
+     Search backward starting at the current line and moving `up'
+     through the history as necessary.  This is an incremental search.
+
+`C-s'
+     Search forward starting at the current line and moving `down'
+     through the history as necessary.
+
+   On most terminals, you can also use the up and down arrow keys in
+place of `C-p' and `C-n' to move through the history list.
+
+   In addition to the keyboard commands for moving through the history
+list, Octave provides three functions for viewing, editing, and
+re-running chunks of commands from the history list.
+
+ -- Command: history options
+     If invoked with no arguments, `history' displays a list of commands
+     that you have executed.  Valid options are:
+
+    `-w FILE'
+          Write the current history to the file FILE.  If the name is
+          omitted, use the default history file (normally
+          `~/.octave_hist').
+
+    `-r FILE'
+          Read the file FILE, replacing the current history list with
+          its contents.  If the name is omitted, use the default
+          history file (normally `~/.octave_hist').
+
+    `N'
+          Display only the most recent N lines of history.
+
+    `-q'
+          Don't number the displayed lines of history.  This is useful
+          for cutting and pasting commands using the X Window System.
+
+     For example, to display the five most recent commands that you have
+     typed without displaying line numbers, use the command `history -q
+     5'.
+
+ -- Command: edit_history [FIRST] [LAST]
+     If invoked with no arguments, `edit_history' allows you to edit the
+     history list using the editor named by the variable `EDITOR'.  The
+     commands to be edited are first copied to a temporary file.  When
+     you exit the editor, Octave executes the commands that remain in
+     the file.  It is often more convenient to use `edit_history' to
+     define functions rather than attempting to enter them directly on
+     the command line.  By default, the block of commands is executed
+     as soon as you exit the editor.  To avoid executing any commands,
+     simply delete all the lines from the buffer before exiting the
+     editor.
+
+     The `edit_history' command takes two optional arguments specifying
+     the history numbers of first and last commands to edit.  For
+     example, the command
+
+          edit_history 13
+
+     extracts all the commands from the 13th through the last in the
+     history list.  The command
+
+          edit_history 13 169
+
+     only extracts commands 13 through 169.  Specifying a larger number
+     for the first command than the last command reverses the list of
+     commands before placing them in the buffer to be edited.  If both
+     arguments are omitted, the previous command in the history list is
+     used.
+
+     *See also:* *note run_history: doc-run_history.
+
+ -- Command: run_history [FIRST] [LAST]
+     Similar to `edit_history', except that the editor is not invoked,
+     and the commands are simply executed as they appear in the history
+     list.
+
+     *See also:* *note edit_history: doc-edit_history.
+
+Octave also allows you customize the details of when, where, and how
+history is saved.
+
+ -- Built-in Function: VAL = saving_history ()
+ -- Built-in Function: OLD_VAL = saving_history (NEW_VAL)
+     Query or set the internal variable that controls whether commands
+     entered on the command line are saved in the history file.
+
+     *See also:* *note history_file: doc-history_file, *note
+     history_size: doc-history_size, *note
+     history_timestamp_format_string:
+     doc-history_timestamp_format_string.
+
+ -- Built-in Function: VAL = history_file ()
+ -- Built-in Function: OLD_VAL = history_file (NEW_VAL)
+     Query or set the internal variable that specifies the name of the
+     file used to store command history.  The default value is
+     `~/.octave_hist', but may be overridden by the environment
+     variable `OCTAVE_HISTFILE'.
+
+     *See also:* *note history_size: doc-history_size, *note
+     saving_history: doc-saving_history, *note
+     history_timestamp_format_string:
+     doc-history_timestamp_format_string.
+
+ -- Built-in Function: VAL = history_size ()
+ -- Built-in Function: OLD_VAL = history_size (NEW_VAL)
+     Query or set the internal variable that specifies how many entries
+     to store in the history file.  The default value is `1024', but
+     may be overridden by the environment variable `OCTAVE_HISTSIZE'.
+
+     *See also:* *note history_file: doc-history_file, *note
+     history_timestamp_format_string:
+     doc-history_timestamp_format_string, *note saving_history:
+     doc-saving_history.
+
+ -- Built-in Function: VAL = history_timestamp_format_string ()
+ -- Built-in Function: OLD_VAL = history_timestamp_format_string
+          (NEW_VAL)
+     Query or set the internal variable that specifies the format string
+     for the comment line that is written to the history file when
+     Octave exits.  The format string is passed to `strftime'.  The
+     default value is
+
+          "# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER at HOST>"
+
+     *See also:* *note strftime: doc-strftime, *note history_file:
+     doc-history_file, *note history_size: doc-history_size, *note
+     saving_history: doc-saving_history.
+
+ -- Built-in Function: VAL = EDITOR ()
+ -- Built-in Function: OLD_VAL = EDITOR (NEW_VAL)
+     Query or set the internal variable that specifies the editor to
+     use with the `edit_history' command.  The default value is taken
+     from the environment variable `EDITOR' when Octave starts.  If the
+     environment variable is not initialized, `EDITOR' will be set to
+     `"emacs"'.
+
+     *See also:* *note edit_history: doc-edit_history.
+
+
+File: octave.info,  Node: Customizing readline,  Next: Customizing the Prompt,  Prev: Commands For History,  Up: Command Line Editing
+
+2.4.6 Customizing `readline'
+----------------------------
+
+Octave uses the GNU Readline library for command-line editing and
+history features.  Readline is very flexible and can be modified through
+a configuration file of commands (See the GNU Readline library for the
+exact command syntax).  The default configuration file is normally
+`~/.inputrc'.
+
+   Octave provides two commands for initializing Readline and thereby
+changing the command line behavior.
+
+ -- Built-in Function:  read_readline_init_file (FILE)
+     Read the readline library initialization file FILE.  If FILE is
+     omitted, read the default initialization file (normally
+     `~/.inputrc').
+
+     *Note Readline Init File: (readline)Readline Init File, for
+     details.
+
+ -- Built-in Function:  re_read_readline_init_file ()
+     Re-read the last readline library initialization file that was
+     read.  *Note Readline Init File: (readline)Readline Init File, for
+     details.
+
+
+File: octave.info,  Node: Customizing the Prompt,  Next: Diary and Echo Commands,  Prev: Customizing readline,  Up: Command Line Editing
+
+2.4.7 Customizing the Prompt
+----------------------------
+
+The following variables are available for customizing the appearance of
+the command-line prompts.  Octave allows the prompt to be customized by
+inserting a number of backslash-escaped special characters that are
+decoded as follows:
+
+`\t'
+     The time.
+
+`\d'
+     The date.
+
+`\n'
+     Begins a new line by printing the equivalent of a carriage return
+     followed by a line feed.
+
+`\s'
+     The name of the program (usually just `octave').
+
+`\w'
+     The current working directory.
+
+`\W'
+     The basename of the current working directory.
+
+`\u'
+     The username of the current user.
+
+`\h'
+     The hostname, up to the first `.'.
+
+`\H'
+     The hostname.
+
+`\#'
+     The command number of this command, counting from when Octave
+     starts.
+
+`\!'
+     The history number of this command.  This differs from `\#' by the
+     number of commands in the history list when Octave starts.
+
+`\$'
+     If the effective UID is 0, a `#', otherwise a `$'.
+
+`\nnn'
+     The character whose character code in octal is NNN.
+
+`\\'
+     A backslash.
+
+ -- Built-in Function: VAL = PS1 ()
+ -- Built-in Function: OLD_VAL = PS1 (NEW_VAL)
+     Query or set the primary prompt string.  When executing
+     interactively, Octave displays the primary prompt when it is ready
+     to read a command.
+
+     The default value of the primary prompt string is `"\s:\#> "'.  To
+     change it, use a command like
+
+          octave:13> PS1 ("\\u@\\H> ")
+
+     which will result in the prompt `boris at kremvax> ' for the user
+     `boris' logged in on the host `kremvax.kgb.su'.  Note that two
+     backslashes are required to enter a backslash into a double-quoted
+     character string.  *Note Strings::.
+
+     *See also:* *note PS2: doc-PS2, *note PS4: doc-PS4.
+
+ -- Built-in Function: VAL = PS2 ()
+ -- Built-in Function: OLD_VAL = PS2 (NEW_VAL)
+     Query or set the secondary prompt string.  The secondary prompt is
+     printed when Octave is expecting additional input to complete a
+     command.  For example, if you are typing a `for' loop that spans
+     several lines, Octave will print the secondary prompt at the
+     beginning of each line after the first.  The default value of the
+     secondary prompt string is `"> "'.
+
+     *See also:* *note PS1: doc-PS1, *note PS4: doc-PS4.
+
+ -- Built-in Function: VAL = PS4 ()
+ -- Built-in Function: OLD_VAL = PS4 (NEW_VAL)
+     Query or set the character string used to prefix output produced
+     when echoing commands is enabled.  The default value is `"+ "'.
+     *Note Diary and Echo Commands::, for a description of echoing
+     commands.
+
+     *See also:* *note echo: doc-echo, *note echo_executing_commands:
+     doc-echo_executing_commands, *note PS1: doc-PS1, *note PS2:
+     doc-PS2.
+
+
+File: octave.info,  Node: Diary and Echo Commands,  Prev: Customizing the Prompt,  Up: Command Line Editing
+
+2.4.8 Diary and Echo Commands
+-----------------------------
+
+Octave's diary feature allows you to keep a log of all or part of an
+interactive session by recording the input you type and the output that
+Octave produces in a separate file.
+
+ -- Command: diary options
+     Record a list of all commands _and_ the output they produce, mixed
+     together just as you see them on your terminal.  Valid options are:
+
+    `on'
+          Start recording your session in a file called `diary' in your
+          current working directory.
+
+    `off'
+          Stop recording your session in the diary file.
+
+    `FILE'
+          Record your session in the file named FILE.
+
+     With no arguments, `diary' toggles the current diary state.
+
+   Sometimes it is useful to see the commands in a function or script as
+they are being evaluated.  This can be especially helpful for debugging
+some kinds of problems.
+
+ -- Command: echo options
+     Control whether commands are displayed as they are executed.  Valid
+     options are:
+
+    `on'
+          Enable echoing of commands as they are executed in script
+          files.
+
+    `off'
+          Disable echoing of commands as they are executed in script
+          files.
+
+    `on all'
+          Enable echoing of commands as they are executed in script
+          files and functions.
+
+    `off all'
+          Disable echoing of commands as they are executed in script
+          files and functions.
+
+     With no arguments, `echo' toggles the current echo state.
+
+ -- Built-in Function: VAL = echo_executing_commands ()
+ -- Built-in Function: OLD_VAL = echo_executing_commands (NEW_VAL)
+     Query or set the internal variable that controls the echo state.
+     It may be the sum of the following values:
+
+    1
+          Echo commands read from script files.
+
+    2
+          Echo commands from functions.
+
+    4
+          Echo commands read from command line.
+
+     More than one state can be active at once.  For example, a value
+     of 3 is equivalent to the command `echo on all'.
+
+     The value of `echo_executing_commands' may be set by the `echo'
+     command or the command line option `--echo-commands'.
+
+
+File: octave.info,  Node: Errors,  Next: Executable Octave Programs,  Prev: Command Line Editing,  Up: Getting Started
+
+2.5 How Octave Reports Errors
+=============================
+
+Octave reports two kinds of errors for invalid programs.
+
+   A "parse error" occurs if Octave cannot understand something you
+have typed.  For example, if you misspell a keyword,
+
+     octave:13> function y = f (x) y = x***2; endfunction
+
+Octave will respond immediately with a message like this:
+
+     parse error:
+
+       syntax error
+
+     >>> function y = f (x) y = x***2; endfunction
+                                   ^
+
+For most parse errors, Octave uses a caret (`^') to mark the point on
+the line where it was unable to make sense of your input.  In this
+case, Octave generated an error message because the keyword for
+exponentiation (`**') was misspelled.  It marked the error at the third
+`*' because the code leading up to this was correct but the final `*'
+was not understood.
+
+   Another class of error message occurs at evaluation time.  These
+errors are called "run-time errors", or sometimes "evaluation errors",
+because they occur when your program is being "run", or "evaluated".
+For example, if after correcting the mistake in the previous function
+definition, you type
+
+     octave:13> f ()
+
+Octave will respond with
+
+     error: `x' undefined near line 1 column 24
+     error: called from:
+     error:   f at line 1, column 22
+
+This error message has several parts, and gives quite a bit of
+information to help you locate the source of the error.  The messages
+are generated from the point of the innermost error, and provide a
+traceback of enclosing expressions and function calls.
+
+   In the example above, the first line indicates that a variable named
+`x' was found to be undefined near line 1 and column 24 of some
+function or expression.  For errors occurring within functions, lines
+are counted from the beginning of the file containing the function
+definition.  For errors occurring outside of an enclosing function, the
+line number indicates the input line number, which is usually displayed
+in the primary prompt string.
+
+   The second and third lines of the error message indicate that the
+error occurred within the function `f'.  If the function `f' had been
+called from within another function, for example, `g', the list of
+errors would have ended with one more line:
+
+     error:   g at line 1, column 17
+
+   These lists of function calls make it fairly easy to trace the path
+your program took before the error occurred, and to correct the error
+before trying again.
+
+
+File: octave.info,  Node: Executable Octave Programs,  Next: Comments,  Prev: Errors,  Up: Getting Started
+
+2.6 Executable Octave Programs
+==============================
+
+Once you have learned Octave, you may want to write self-contained
+Octave scripts, using the `#!' script mechanism.  You can do this on
+GNU systems and on many Unix systems (1).
+
+   Self-contained Octave scripts are useful when you want to write a
+program which users can invoke without knowing that the program is
+written in the Octave language.  Octave scripts are also used for batch
+processing of data files.  Once an algorithm has been developed and
+tested in the interactive portion of Octave, it can be committed to an
+executable script and used again and again on new data files.
+
+   As a trivial example of an executable Octave script, you might
+create a text file named `hello', containing the following lines:
+
+     #! OCTAVE-INTERPRETER-NAME -qf
+     # a sample Octave program
+     printf ("Hello, world!\n");
+
+(where OCTAVE-INTERPRETER-NAME should be replaced with the full path
+and name of your Octave binary).  Note that this will only work if `#!'
+appears at the very beginning of the file.  After making the file
+executable (with the `chmod' command on Unix systems), you can simply
+type:
+
+     hello
+
+at the shell, and the system will arrange to run Octave as if you had
+typed:
+
+     octave hello
+
+   The line beginning with `#!' lists the full path and filename of an
+interpreter to be run, and an optional initial command line argument to
+pass to that interpreter.  The operating system then runs the
+interpreter with the given argument and the full argument list of the
+executed program.  The first argument in the list is the full file name
+of the Octave executable.  The rest of the argument list will either be
+options to Octave, or data files, or both.  The `-qf' options are
+usually specified in stand-alone Octave programs to prevent them from
+printing the normal startup message, and to keep them from behaving
+differently depending on the contents of a particular user's
+`~/.octaverc' file.  *Note Invoking Octave from the Command Line::.
+
+   Note that some operating systems may place a limit on the number of
+characters that are recognized after `#!'.  Also, the arguments
+appearing in a `#!' line are parsed differently by various
+shells/systems.  The majority of them group all the arguments together
+in one string and pass it to the interpreter as a single argument.  In
+this case, the following script:
+
+     #! OCTAVE-INTERPRETER-NAME -q -f # comment
+
+is equivalent to typing at the command line:
+
+     octave "-q -f # comment"
+
+which will produce an error message.  Unfortunately, it is not possible
+for Octave to determine whether it has been called from the command
+line or from a `#!' script, so some care is needed when using the `#!'
+mechanism.
+
+   Note that when Octave is started from an executable script, the
+built-in function `argv' returns a cell array containing the command
+line arguments passed to the executable Octave script, not the arguments
+passed to the Octave interpreter on the `#!' line of the script.  For
+example, the following program will reproduce the command line that was
+used to execute the script, not `-qf'.
+
+     #! /bin/octave -qf
+     printf ("%s", program_name ());
+     arg_list = argv ();
+     for i = 1:nargin
+       printf (" %s", arg_list{i});
+     endfor
+     printf ("\n");
+
+   ---------- Footnotes ----------
+
+   (1) The `#!' mechanism works on Unix systems derived from Berkeley
+Unix, System V Release 4, and some System V Release 3 systems.
+
+
+File: octave.info,  Node: Comments,  Prev: Executable Octave Programs,  Up: Getting Started
+
+2.7 Comments in Octave Programs
+===============================
+
+A "comment" is some text that is included in a program for the sake of
+human readers, and which is NOT an executable part of the program.
+Comments can explain what the program does, and how it works.  Nearly
+all programming languages have provisions for comments, because
+programs are typically hard to understand without them.
+
+* Menu:
+
+* Single Line Comments::
+* Block Comments::
+* Comments and the Help System::
+
+
+File: octave.info,  Node: Single Line Comments,  Next: Block Comments,  Up: Comments
+
+2.7.1 Single Line Comments
+--------------------------
+
+In the Octave language, a comment starts with either the sharp sign
+character, `#', or the percent symbol `%' and continues to the end of
+the line.  Any text following the sharp sign or percent symbol is
+ignored by the Octave interpreter and not executed.  The following
+example shows whole line and partial line comments.
+     function countdown
+       # Count down for main rocket engines
+       disp(3);
+       disp(2);
+       disp(1);
+       disp("Blast Off!");  # Rocket leaves pad
+     endfunction
+
+
+File: octave.info,  Node: Block Comments,  Next: Comments and the Help System,  Prev: Single Line Comments,  Up: Comments
+
+2.7.2 Block Comments
+--------------------
+
+Entire blocks of code can be commented by enclosing the code between
+matching `#{' and `#}' or `%{' and `%}' markers.  For example,
+     function quick_countdown
+       # Count down for main rocket engines
+       disp(3);
+      #{
+       disp(2);
+       disp(1);
+      #}
+       disp("Blast Off!");  # Rocket leaves pad
+     endfunction
+
+will produce a very quick countdown from '3' to 'Blast Off' as the
+lines "`disp(2);'" and "`disp(1);'" won't be executed.
+
+
+File: octave.info,  Node: Comments and the Help System,  Prev: Block Comments,  Up: Comments
+
+2.7.3 Comments and the Help System
+----------------------------------
+
+The `help' command (*note Getting Help::) is able to find the first
+block of comments in a function and return those as a documentation
+string.  This means that the same commands used to get help on built-in
+functions are available for properly formatted user-defined functions.
+For example, after defining the function `f' below,
+     function xdot = f (x, t)
+
+     # usage: f (x, t)
+     #
+     # This function defines the right-hand
+     # side functions for a set of nonlinear
+     # differential equations.
+
+       r = 0.25;
+       ...
+     endfunction
+
+   the command `help f' produces the output
+
+      usage: f (x, t)
+
+      This function defines the right-hand
+      side functions for a set of nonlinear
+      differential equations.
+
+   Although it is possible to put comment lines into keyboard-composed,
+throw-away Octave programs, it usually isn't very useful because the
+purpose of a comment is to help you or another person understand the
+program at a later time.
+
+   The `help' parser currently only recognizes single line comments
+(*note Single Line Comments::) and not block comments for the initial
+help text.
+
+
+File: octave.info,  Node: Data Types,  Next: Numeric Data Types,  Prev: Getting Started,  Up: Top
+
+3 Data Types
+************
+
+All versions of Octave include a number of built-in data types,
+including real and complex scalars and matrices, character strings, a
+data structure type, and an array that can contain all data types.
+
+   It is also possible to define new specialized data types by writing a
+small amount of C++ code.  On some systems, new data types can be loaded
+dynamically while Octave is running, so it is not necessary to recompile
+all of Octave just to add a new type.  *Note Dynamically Linked
+Functions::, for more information about Octave's dynamic linking
+capabilities.  *note User-defined Data Types:: describes what you must
+do to define a new data type for Octave.
+
+ -- Built-in Function:  typeinfo (EXPR)
+     Return the type of the expression EXPR, as a string.  If EXPR is
+     omitted, return an array of strings containing all the currently
+     installed data types.
+
+* Menu:
+
+* Built-in Data Types::
+* User-defined Data Types::
+* Object Sizes::
+
+
+File: octave.info,  Node: Built-in Data Types,  Next: User-defined Data Types,  Up: Data Types
+
+3.1 Built-in Data Types
+=======================
+
+The standard built-in data types are real and complex scalars and
+matrices, ranges, character strings, a data structure type, and cell
+arrays.  Additional built-in data types may be added in future versions.
+If you need a specialized data type that is not currently provided as a
+built-in type, you are encouraged to write your own user-defined data
+type and contribute it for distribution in a future release of Octave.
+
+   The data type of a variable can be determined and changed through the
+use of the following functions.
+
+ -- Built-in Function:  class (EXPR)
+ -- Built-in Function:  class (S, ID)
+ -- Built-in Function:  class (S, ID, P, ...)
+     Return the class of the expression EXPR or create a class with
+     fields from structure S and name (string) ID.  Additional
+     arguments name a list of parent classes from which the new class is
+     derived.
+
+ -- Function File:  isa (X, CLASS)
+     Return true if X is a value from the class CLASS.
+
+ -- Function File:  cast (VAL, TYPE)
+     Convert VAL to data type TYPE.
+
+     *See also:* *note int8: doc-int8, *note uint8: doc-uint8, *note
+     int16: doc-int16, *note uint16: doc-uint16, *note int32:
+     doc-int32, *note uint32: doc-uint32, *note int64: doc-int64, *note
+     uint64: doc-uint64, *note double: doc-double.
+
+ -- Loadable Function:  typecast (X, TYPE)
+     Convert from one datatype to another without changing the
+     underlying data.  The argument TYPE defines the type of the return
+     argument and must be one of 'uint8', 'uint16', 'uint32', 'uint64',
+     'int8', 'int16', 'int32', 'int64', 'single' or 'double'.
+
+     An example of the use of typecast on a little-endian machine is
+
+          X = uint16 ([1, 65535]);
+          typecast (X, 'uint8')
+          => [   0,   1, 255, 255]
+
+     *See also:* *note cast: doc-cast, *note swapbytes: doc-swapbytes.
+
+ -- Function File:  swapbytes (X)
+     Swaps the byte order on values, converting from little endian to
+     big endian and vice versa.  For example
+
+          swapbytes (uint16 (1:4))
+          => [   256   512   768  1024]
+
+     *See also:* *note typecast: doc-typecast, *note cast: doc-cast.
+
+* Menu:
+
+* Numeric Objects::
+* Missing Data::
+* String Objects::
+* Data Structure Objects::
+* Cell Array Objects::
+
+
+File: octave.info,  Node: Numeric Objects,  Next: Missing Data,  Up: Built-in Data Types
+
+3.1.1 Numeric Objects
+---------------------
+
+Octave's built-in numeric objects include real, complex, and integer
+scalars and matrices.  All built-in floating point numeric data is
+currently stored as double precision numbers.  On systems that use the
+IEEE floating point format, values in the range of approximately
+2.2251e-308 to 1.7977e+308  can be stored, and the relative precision
+is approximately  2.2204e-16.  The exact values are given by the
+variables `realmin', `realmax', and `eps', respectively.
+
+   Matrix objects can be of any size, and can be dynamically reshaped
+and resized.  It is easy to extract individual rows, columns, or
+submatrices using a variety of powerful indexing features.  *Note Index
+Expressions::.
+
+   *Note Numeric Data Types::, for more information.
+
+
+File: octave.info,  Node: Missing Data,  Next: String Objects,  Prev: Numeric Objects,  Up: Built-in Data Types
+
+3.1.2 Missing Data
+------------------
+
+It is possible to represent missing data explicitly in Octave using
+`NA' (short for "Not Available").  Missing data can only be represented
+when data is represented as floating point numbers.  In this case
+missing data is represented as a special case of the representation of
+`NaN'.
+
+ -- Built-in Function:  NA
+ -- Built-in Function:  NA (N)
+ -- Built-in Function:  NA (N, M)
+ -- Built-in Function:  NA (N, M, K, ...)
+ -- Built-in Function:  NA (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are
+     all equal to the special constant used to designate missing values.
+
+     Note that NA always compares not equal to NA (NA != NA).  To find
+     NA values, use the `isna' function.
+
+     When called with no arguments, return a scalar with the value `NA'.
+     When called with a single argument, return a square matrix with
+     the dimension specified.  When called with more than one scalar
+     argument the first two arguments are taken as the number of rows
+     and columns and any further arguments specify additional matrix
+     dimensions.  The optional argument CLASS specifies the return type
+     and may be either "double" or "single".
+
+     *See also:* *note isna: doc-isna.
+
+ -- Mapping Function:  isna (X)
+     Return 1 for elements of X that are NA (missing) values and zero
+     otherwise.  For example,
+
+          isna ([13, Inf, NA, NaN])
+               => [ 0, 0, 1, 0 ]
+
+     *See also:* *note isnan: doc-isnan.
+
+
+File: octave.info,  Node: String Objects,  Next: Data Structure Objects,  Prev: Missing Data,  Up: Built-in Data Types
+
+3.1.3 String Objects
+--------------------
+
+A character string in Octave consists of a sequence of characters
+enclosed in either double-quote or single-quote marks.  Internally,
+Octave currently stores strings as matrices of characters.  All the
+indexing operations that work for matrix objects also work for strings.
+
+   *Note Strings::, for more information.
+
+
+File: octave.info,  Node: Data Structure Objects,  Next: Cell Array Objects,  Prev: String Objects,  Up: Built-in Data Types
+
+3.1.4 Data Structure Objects
+----------------------------
+
+Octave's data structure type can help you to organize related objects of
+different types.  The current implementation uses an associative array
+with indices limited to strings, but the syntax is more like C-style
+structures.
+
+   *Note Data Structures::, for more information.
+
+
+File: octave.info,  Node: Cell Array Objects,  Prev: Data Structure Objects,  Up: Built-in Data Types
+
+3.1.5 Cell Array Objects
+------------------------
+
+A Cell Array in Octave is general array that can hold any number of
+different data types.
+
+   *Note Cell Arrays::, for more information.
+
+
+File: octave.info,  Node: User-defined Data Types,  Next: Object Sizes,  Prev: Built-in Data Types,  Up: Data Types
+
+3.2 User-defined Data Types
+===========================
+
+Someday I hope to expand this to include a complete description of
+Octave's mechanism for managing user-defined data types.  Until this
+feature is documented here, you will have to make do by reading the code
+in the `ov.h', `ops.h', and related files from Octave's `src' directory.
+
+
+File: octave.info,  Node: Object Sizes,  Prev: User-defined Data Types,  Up: Data Types
+
+3.3 Object Sizes
+================
+
+The following functions allow you to determine the size of a variable or
+expression.  These functions are defined for all objects.  They return
+-1 when the operation doesn't make sense.  For example, Octave's data
+structure type doesn't have rows or columns, so the `rows' and
+`columns' functions return -1 for structure arguments.
+
+ -- Built-in Function:  ndims (A)
+     Returns the number of dimensions of array A.  For any array, the
+     result will always be larger than or equal to 2.  Trailing
+     singleton dimensions are not counted.
+
+ -- Built-in Function:  columns (A)
+     Return the number of columns of A.
+
+     *See also:* *note size: doc-size, *note numel: doc-numel, *note
+     rows: doc-rows, *note length: doc-length, *note isscalar:
+     doc-isscalar, *note isvector: doc-isvector, *note ismatrix:
+     doc-ismatrix.
+
+ -- Built-in Function:  rows (A)
+     Return the number of rows of A.
+
+     *See also:* *note size: doc-size, *note numel: doc-numel, *note
+     columns: doc-columns, *note length: doc-length, *note isscalar:
+     doc-isscalar, *note isvector: doc-isvector, *note ismatrix:
+     doc-ismatrix.
+
+ -- Built-in Function:  numel (A)
+     Returns the number of elements in the object A.
+
+     *See also:* *note size: doc-size.
+
+ -- Built-in Function:  length (A)
+     Return the `length' of the object A.  For matrix objects, the
+     length is the number of rows or columns, whichever is greater (this
+     odd definition is used for compatibility with MATLAB).
+
+ -- Built-in Function:  size (A, N)
+     Return the number rows and columns of A.
+
+     With one input argument and one output argument, the result is
+     returned in a row vector.  If there are multiple output arguments,
+     the number of rows is assigned to the first, and the number of
+     columns to the second, etc.  For example,
+
+          size ([1, 2; 3, 4; 5, 6])
+               => [ 3, 2 ]
+
+          [nr, nc] = size ([1, 2; 3, 4; 5, 6])
+               => nr = 3
+               => nc = 2
+
+     If given a second argument, `size' will return the size of the
+     corresponding dimension.  For example
+
+          size ([1, 2; 3, 4; 5, 6], 2)
+               => 2
+
+     returns the number of columns in the given matrix.
+
+     *See also:* *note numel: doc-numel.
+
+ -- Built-in Function:  isempty (A)
+     Return 1 if A is an empty matrix (either the number of rows, or
+     the number of columns, or both are zero).  Otherwise, return 0.
+
+ -- Built-in Function:  isnull (X)
+     Return 1 if X is a special null matrix, string or single quoted
+     string.  Indexed assignment with such a value as right-hand side
+     should delete array elements.  This function should be used when
+     overloading indexed assignment for user-defined classes instead of
+     `isempty', to distinguish the cases:
+    `A(I) = []'
+          This should delete elements if `I' is nonempty.
+
+    `X = []; A(I) = X'
+          This should give an error if `I' is nonempty.
+
+ -- Built-in Function:  sizeof (VAL)
+     Return the size of VAL in bytes
+
+ -- Built-in Function:  size_equal (A, B, ...)
+     Return true if the dimensions of all arguments agree.  Trailing
+     singleton dimensions are ignored.  Called with a single argument,
+     size_equal returns true.
+
+     *See also:* *note size: doc-size, *note numel: doc-numel.
+
+ -- Built-in Function:  squeeze (X)
+     Remove singleton dimensions from X and return the result.  Note
+     that for compatibility with MATLAB, all objects have a minimum of
+     two dimensions and row vectors are left unchanged.
+
+
+File: octave.info,  Node: Numeric Data Types,  Next: Strings,  Prev: Data Types,  Up: Top
+
+4 Numeric Data Types
+********************
+
+A "numeric constant" may be a scalar, a vector, or a matrix, and it may
+contain complex values.
+
+   The simplest form of a numeric constant, a scalar, is a single number
+that can be an integer, a decimal fraction, a number in scientific
+(exponential) notation, or a complex number.  Note that by default
+numeric constants are represented within Octave in double-precision
+floating point format (complex constants are stored as pairs of
+double-precision floating point values).  It is however possible to
+represent real integers as described in *note Integer Data Types::.
+Here are some examples of real-valued numeric constants, which all have
+the same value:
+
+     105
+     1.05e+2
+     1050e-1
+
+   To specify complex constants, you can write an expression of the form
+
+     3 + 4i
+     3.0 + 4.0i
+     0.3e1 + 40e-1i
+
+all of which are equivalent.  The letter `i' in the previous example
+stands for the pure imaginary constant, defined as   `sqrt (-1)'.
+
+   For Octave to recognize a value as the imaginary part of a complex
+constant, a space must not appear between the number and the `i'.  If
+it does, Octave will print an error message, like this:
+
+     octave:13> 3 + 4 i
+
+     parse error:
+
+       syntax error
+
+     >>> 3 + 4 i
+               ^
+
+You may also use `j', `I', or `J' in place of the `i' above.  All four
+forms are equivalent.
+
+ -- Built-in Function:  double (X)
+     Convert X to double precision type.
+
+     *See also:* *note single: doc-single.
+
+ -- Built-in Function:  complex (X)
+ -- Built-in Function:  complex (RE, IM)
+     Return a complex result from real arguments.  With 1 real argument
+     X, return the complex result `X + 0i'.  With 2 real arguments,
+     return the complex result `RE + IM'.  `complex' can often be more
+     convenient than expressions such as `a + i*b'.  For example:
+
+          complex ([1, 2], [3, 4])
+          =>
+             1 + 3i   2 + 4i
+
+     *See also:* *note real: doc-real, *note imag: doc-imag, *note
+     iscomplex: doc-iscomplex.
+
+* Menu:
+
+* Matrices::
+* Ranges::
+* Single Precision Data Types::
+* Integer Data Types::
+* Bit Manipulations::
+* Logical Values::
+* Promotion and Demotion of Data Types::
+* Predicates for Numeric Objects::
+
+
+File: octave.info,  Node: Matrices,  Next: Ranges,  Up: Numeric Data Types
+
+4.1 Matrices
+============
+
+It is easy to define a matrix of values in Octave.  The size of the
+matrix is determined automatically, so it is not necessary to explicitly
+state the dimensions.  The expression
+
+     a = [1, 2; 3, 4]
+
+results in the matrix
+
+
+             /      \
+             | 1  2 |
+       a  =  |      |
+             | 3  4 |
+             \      /
+
+   Elements of a matrix may be arbitrary expressions, provided that the
+dimensions all make sense when combining the various pieces.  For
+example, given the above matrix, the expression
+
+     [ a, a ]
+
+produces the matrix
+
+     ans =
+
+       1  2  1  2
+       3  4  3  4
+
+but the expression
+
+     [ a, 1 ]
+
+produces the error
+
+     error: number of rows must match (1 != 2) near line 13, column 6
+
+(assuming that this expression was entered as the first thing on line
+13, of course).
+
+   Inside the square brackets that delimit a matrix expression, Octave
+looks at the surrounding context to determine whether spaces and newline
+characters should be converted into element and row separators, or
+simply ignored, so an expression like
+
+     a = [ 1 2
+           3 4 ]
+
+will work.  However, some possible sources of confusion remain.  For
+example, in the expression
+
+     [ 1 - 1 ]
+
+the `-' is treated as a binary operator and the result is the scalar 0,
+but in the expression
+
+     [ 1 -1 ]
+
+the `-' is treated as a unary operator and the result is the vector `[
+1, -1 ]'.  Similarly, the expression
+
+     [ sin (pi) ]
+
+will be parsed as
+
+     [ sin, (pi) ]
+
+and will result in an error since the `sin' function will be called
+with no arguments.  To get around this, you must omit the space between
+`sin' and the opening parenthesis, or enclose the expression in a set
+of parentheses:
+
+     [ (sin (pi)) ]
+
+   Whitespace surrounding the single quote character (`'', used as a
+transpose operator and for delimiting character strings) can also cause
+confusion.  Given `a = 1', the expression
+
+     [ 1 a' ]
+
+results in the single quote character being treated as a transpose
+operator and the result is the vector `[ 1, 1 ]', but the expression
+
+     [ 1 a ' ]
+
+produces the error message
+
+     parse error:
+
+       syntax error
+
+     >>> [ 1 a ' ]
+                   ^
+
+because not doing so would cause trouble when parsing the valid
+expression
+
+     [ a 'foo' ]
+
+   For clarity, it is probably best to always use commas and semicolons
+to separate matrix elements and rows.
+
+   When you type a matrix or the name of a variable whose value is a
+matrix, Octave responds by printing the matrix in with neatly aligned
+rows and columns.  If the rows of the matrix are too large to fit on the
+screen, Octave splits the matrix and displays a header before each
+section to indicate which columns are being displayed.  You can use the
+following variables to control the format of the output.
+
+ -- Built-in Function: VAL = output_max_field_width ()
+ -- Built-in Function: OLD_VAL = output_max_field_width (NEW_VAL)
+     Query or set the internal variable that specifies the maximum width
+     of a numeric output field.
+
+     *See also:* *note format: doc-format, *note output_precision:
+     doc-output_precision.
+
+ -- Built-in Function: VAL = output_precision ()
+ -- Built-in Function: OLD_VAL = output_precision (NEW_VAL)
+     Query or set the internal variable that specifies the minimum
+     number of significant figures to display for numeric output.
+
+     *See also:* *note format: doc-format, *note
+     output_max_field_width: doc-output_max_field_width.
+
+   It is possible to achieve a wide range of output styles by using
+different values of `output_precision' and `output_max_field_width'.
+Reasonable combinations can be set using the `format' function.  *Note
+Basic Input and Output::.
+
+ -- Built-in Function: VAL = split_long_rows ()
+ -- Built-in Function: OLD_VAL = split_long_rows (NEW_VAL)
+     Query or set the internal variable that controls whether rows of a
+     matrix may be split when displayed to a terminal window.  If the
+     rows are split, Octave will display the matrix in a series of
+     smaller pieces, each of which can fit within the limits of your
+     terminal width and each set of rows is labeled so that you can
+     easily see which columns are currently being displayed.  For
+     example:
+
+          octave:13> rand (2,10)
+          ans =
+
+           Columns 1 through 6:
+
+            0.75883  0.93290  0.40064  0.43818  0.94958  0.16467
+            0.75697  0.51942  0.40031  0.61784  0.92309  0.40201
+
+           Columns 7 through 10:
+
+            0.90174  0.11854  0.72313  0.73326
+            0.44672  0.94303  0.56564  0.82150
+
+   Octave automatically switches to scientific notation when values
+become very large or very small.  This guarantees that you will see
+several significant figures for every value in a matrix.  If you would
+prefer to see all values in a matrix printed in a fixed point format,
+you can set the built-in variable `fixed_point_format' to a nonzero
+value.  But doing so is not recommended, because it can produce output
+that can easily be misinterpreted.
+
+ -- Built-in Function: VAL = fixed_point_format ()
+ -- Built-in Function: OLD_VAL = fixed_point_format (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will use a scaled format to print matrix values such that the
+     largest element may be written with a single leading digit with
+     the scaling factor is printed on the first line of output.  For
+     example,
+
+          octave:1> logspace (1, 7, 5)'
+          ans =
+
+            1.0e+07  *
+
+            0.00000
+            0.00003
+            0.00100
+            0.03162
+            1.00000
+
+     Notice that first value appears to be zero when it is actually 1.
+     For this reason, you should be careful when setting
+     `fixed_point_format' to a nonzero value.
+
+* Menu:
+
+* Empty Matrices::
+
+
+File: octave.info,  Node: Empty Matrices,  Up: Matrices
+
+4.1.1 Empty Matrices
+--------------------
+
+A matrix may have one or both dimensions zero, and operations on empty
+matrices are handled as described by Carl de Boor in `An Empty
+Exercise', SIGNUM, Volume 25, pages 2-6, 1990 and C. N. Nett and W. M.
+Haddad, in `A System-Theoretic Appropriate Realization of the Empty
+Matrix Concept', IEEE Transactions on Automatic Control, Volume 38,
+Number 5, May 1993.  Briefly, given a scalar S, an M by N matrix
+`M(mxn)', and an M by N empty matrix `[](mxn)' (with either one or both
+dimensions equal to zero), the following are true:
+
+     s * [](mxn) = [](mxn) * s = [](mxn)
+
+         [](mxn) + [](mxn) = [](mxn)
+
+         [](0xm) *  M(mxn) = [](0xn)
+
+          M(mxn) * [](nx0) = [](mx0)
+
+         [](mx0) * [](0xn) =  0(mxn)
+
+   By default, dimensions of the empty matrix are printed along with the
+empty matrix symbol, `[]'.  The built-in variable
+`print_empty_dimensions' controls this behavior.
+
+ -- Built-in Function: VAL = print_empty_dimensions ()
+ -- Built-in Function: OLD_VAL = print_empty_dimensions (NEW_VAL)
+     Query or set the internal variable that controls whether the
+     dimensions of empty matrices are printed along with the empty
+     matrix symbol, `[]'.  For example, the expression
+
+          zeros (3, 0)
+
+     will print
+
+          ans = [](3x0)
+
+   Empty matrices may also be used in assignment statements as a
+convenient way to delete rows or columns of matrices.  *Note Assignment
+Expressions: Assignment Ops.
+
+   When Octave parses a matrix expression, it examines the elements of
+the list to determine whether they are all constants.  If they are, it
+replaces the list with a single matrix constant.
+
+
+File: octave.info,  Node: Ranges,  Next: Single Precision Data Types,  Prev: Matrices,  Up: Numeric Data Types
+
+4.2 Ranges
+==========
+
+A "range" is a convenient way to write a row vector with evenly spaced
+elements.  A range expression is defined by the value of the first
+element in the range, an optional value for the increment between
+elements, and a maximum value which the elements of the range will not
+exceed.  The base, increment, and limit are separated by colons (the
+`:' character) and may contain any arithmetic expressions and function
+calls.  If the increment is omitted, it is assumed to be 1.  For
+example, the range
+
+     1 : 5
+
+defines the set of values `[ 1, 2, 3, 4, 5 ]', and the range
+
+     1 : 3 : 5
+
+defines the set of values `[ 1, 4 ]'.
+
+   Although a range constant specifies a row vector, Octave does _not_
+convert range constants to vectors unless it is necessary to do so.
+This allows you to write a constant like `1 : 10000' without using
+80,000 bytes of storage on a typical 32-bit workstation.
+
+   Note that the upper (or lower, if the increment is negative) bound on
+the range is not always included in the set of values, and that ranges
+defined by floating point values can produce surprising results because
+Octave uses floating point arithmetic to compute the values in the
+range.  If it is important to include the endpoints of a range and the
+number of elements is known, you should use the `linspace' function
+instead (*note Special Utility Matrices::).
+
+   When adding a scalar to a range, subtracting a scalar from it (or
+subtracting a range from a scalar) and multiplying by scalar, Octave
+will attempt to avoid unpacking the range and keep the result as a
+range, too, if it can determine that it is safe to do so.  For
+instance, doing
+
+     a = 2*(1:1e7) - 1;
+
+   will produce the same result as `1:2:2e7-1', but without ever
+forming a vector with ten million elements.
+
+   Using zero as an increment in the colon notation, as `1:0:1' is not
+allowed, because a division by zero would occur in determining the
+number of range elements.  However, ranges with zero increment (i.e.,
+all elements equal) are useful, especially in indexing, and Octave
+allows them to be constructed using the built-in function "ones".  Note
+that because a range must be a row vector, `ones (1, 10)' produces a
+range, while `ones (10, 1)' does not.
+
+   When Octave parses a range expression, it examines the elements of
+the expression to determine whether they are all constants.  If they
+are, it replaces the range expression with a single range constant.
+
+
+File: octave.info,  Node: Single Precision Data Types,  Next: Integer Data Types,  Prev: Ranges,  Up: Numeric Data Types
+
+4.3 Single Precision Data Types
+===============================
+
+Octave includes support for single precision data types, and most of the
+functions in Octave accept single precision values and return single
+precision answers.  A single precision variable is created with the
+`single' function.
+
+ -- Built-in Function:  single (X)
+     Convert X to single precision type.
+
+     *See also:* *note double: doc-double.
+
+   for example
+
+     sngl = single (rand (2, 2))
+          => sngl =
+             0.37569   0.92982
+             0.11962   0.50876
+     class (sngl)
+         => single
+
+   Many functions can also return single precision values directly.  For
+example
+
+     ones (2, 2, "single")
+     zeros (2, 2, "single")
+     eye (2, 2,  "single")
+     rand (2, 2, "single")
+     NaN (2, 2, "single")
+     NA (2, 2, "single")
+     Inf (2, 2, "single")
+
+will all return single precision matrices.
+
+
+File: octave.info,  Node: Integer Data Types,  Next: Bit Manipulations,  Prev: Single Precision Data Types,  Up: Numeric Data Types
+
+4.4 Integer Data Types
+======================
+
+Octave supports integer matrices as an alternative to using double
+precision.  It is possible to use both signed and unsigned integers
+represented by 8, 16, 32, or 64 bits.  It should be noted that most
+computations require floating point data, meaning that integers will
+often change type when involved in numeric computations.  For this
+reason integers are most often used to store data, and not for
+calculations.
+
+   In general most integer matrices are created by casting existing
+matrices to integers.  The following example shows how to cast a matrix
+into 32 bit integers.
+
+     float = rand (2, 2)
+          => float = 0.37569   0.92982
+                     0.11962   0.50876
+     integer = int32 (float)
+          => integer = 0  1
+                       0  1
+
+As can be seen, floating point values are rounded to the nearest integer
+when converted.
+
+ -- Built-in Function:  isinteger (X)
+     Return true if X is an integer object (int8, uint8, int16, etc.).
+     Note that `isinteger (14)' is false because numeric constants in
+     Octave are double precision floating point values.
+
+     *See also:* *note isreal: doc-isreal, *note isnumeric:
+     doc-isnumeric, *note class: doc-class, *note isa: doc-isa.
+
+ -- Built-in Function:  int8 (X)
+     Convert X to 8-bit integer type.
+
+ -- Built-in Function:  uint8 (X)
+     Convert X to unsigned 8-bit integer type.
+
+ -- Built-in Function:  int16 (X)
+     Convert X to 16-bit integer type.
+
+ -- Built-in Function:  uint16 (X)
+     Convert X to unsigned 16-bit integer type.
+
+ -- Built-in Function:  int32 (X)
+     Convert X to 32-bit integer type.
+
+ -- Built-in Function:  uint32 (X)
+     Convert X to unsigned 32-bit integer type.
+
+ -- Built-in Function:  int64 (X)
+     Convert X to 64-bit integer type.
+
+ -- Built-in Function:  uint64 (X)
+     Convert X to unsigned 64-bit integer type.
+
+ -- Built-in Function:  intmax (TYPE)
+     Return the largest integer that can be represented in an integer
+     type.  The variable TYPE can be
+
+    `int8'
+          signed 8-bit integer.
+
+    `int16'
+          signed 16-bit integer.
+
+    `int32'
+          signed 32-bit integer.
+
+    `int64'
+          signed 64-bit integer.
+
+    `uint8'
+          unsigned 8-bit integer.
+
+    `uint16'
+          unsigned 16-bit integer.
+
+    `uint32'
+          unsigned 32-bit integer.
+
+    `uint64'
+          unsigned 64-bit integer.
+
+     The default for TYPE is `uint32'.
+
+     *See also:* *note intmin: doc-intmin, *note bitmax: doc-bitmax.
+
+ -- Built-in Function:  intmin (TYPE)
+     Return the smallest integer that can be represented in an integer
+     type.  The variable TYPE can be
+
+    `int8'
+          signed 8-bit integer.
+
+    `int16'
+          signed 16-bit integer.
+
+    `int32'
+          signed 32-bit integer.
+
+    `int64'
+          signed 64-bit integer.
+
+    `uint8'
+          unsigned 8-bit integer.
+
+    `uint16'
+          unsigned 16-bit integer.
+
+    `uint32'
+          unsigned 32-bit integer.
+
+    `uint64'
+          unsigned 64-bit integer.
+
+     The default for TYPE is `uint32'.
+
+     *See also:* *note intmax: doc-intmax, *note bitmax: doc-bitmax.
+
+ -- Function File:  intwarning (ACTION)
+ -- Function File:  intwarning (S)
+ -- Function File: S = intwarning (...)
+     Control the state of the warning for integer conversions and math
+     operations.
+
+    "query"
+          The state of the Octave integer conversion and math warnings
+          is queried.  If there is no output argument, then the state
+          is printed.  Otherwise it is returned in a structure with the
+          fields "identifier" and "state".
+
+               intwarning ("query")
+               The state of warning "Octave:int-convert-nan" is "off"
+               The state of warning "Octave:int-convert-non-int-val" is "off"
+               The state of warning "Octave:int-convert-overflow" is "off"
+               The state of warning "Octave:int-math-overflow" is "off"
+
+    "on"
+          Turn integer conversion and math warnings "on".  If there is
+          no output argument, then nothing is printed.  Otherwise the
+          original state of the state of the integer conversion and
+          math warnings is returned in a structure array.
+
+    "off"
+          Turn integer conversion and math warnings "on".  If there is
+          no output argument, then nothing is printed.  Otherwise the
+          original state of the state of the integer conversion and
+          math warnings is returned in a structure array.
+
+     The original state of the integer warnings can be restored by
+     passing the structure array returned by `intwarning' to a later
+     call to `intwarning'.  For example
+
+          s = intwarning ("off");
+          ...
+          intwarning (s);
+
+     *See also:* *note warning: doc-warning.
+
+* Menu:
+
+* Integer Arithmetic::
+
+
+File: octave.info,  Node: Integer Arithmetic,  Up: Integer Data Types
+
+4.4.1 Integer Arithmetic
+------------------------
+
+While many numerical computations can't be carried out in integers,
+Octave does support basic operations like addition and multiplication
+on integers.  The operators `+', `-', `.*', and `./' work on integers
+of the same type.  So, it is possible to add two 32 bit integers, but
+not to add a 32 bit integer and a 16 bit integer.
+
+   The arithmetic operations on integers are performed by casting the
+integer values to double precision values, performing the operation, and
+then re-casting the values back to the original integer type.  As the
+double precision type of Octave is only capable of representing integers
+with up to 53 bits of precision, it is not possible to perform
+arithmetic with 64 bit integer types.
+
+   When doing integer arithmetic one should consider the possibility of
+underflow and overflow.  This happens when the result of the computation
+can't be represented using the chosen integer type.  As an example it is
+not possible to represent the result of 10 - 20 when using unsigned
+integers.  Octave makes sure that the result of integer computations is
+the integer that is closest to the true result.  So, the result of 10 -
+20 when using unsigned integers is zero.
+
+   When doing integer division Octave will round the result to the
+nearest integer.  This is different from most programming languages,
+where the result is often floored to the nearest integer.  So, the
+result of `int32(5)./int32(8)' is `1'.
+
+ -- Function File:  idivide (X, Y, OP)
+     Integer division with different round rules.  The standard
+     behavior of the an integer division such as `A ./ B' is to round
+     the result to the nearest integer.  This is not always the desired
+     behavior and `idivide' permits integer element-by-element division
+     to be performed with different treatment for the fractional part
+     of the division as determined by the OP flag.  OP is a string with
+     one of the values:
+
+    "fix"
+          Calculate `A ./ B' with the fractional part rounded towards
+          zero.
+
+    "round"
+          Calculate `A ./ B' with the fractional part rounded towards
+          the nearest integer.
+
+    "floor"
+          Calculate `A ./ B' with the fractional part rounded downwards.
+
+    "ceil"
+          Calculate `A ./ B' with the fractional part rounded upwards.
+
+     If OP is not given it is assumed that it is `"fix"'.  An example
+     demonstrating these rounding rules is
+
+          idivide (int8 ([-3, 3]), int8 (4), "fix")
+          => int8 ([0, 0])
+          idivide (int8 ([-3, 3]), int8 (4), "round")
+          => int8 ([-1, 1])
+          idivide (int8 ([-3, 3]), int8 (4), "ceil")
+          => int8 ([0, 1])
+          idivide (int8 ([-3, 3]), int8 (4), "floor")
+          => int8 ([-1, 0])
+
+     *See also:* *note ldivide: doc-ldivide, *note rdivide: doc-rdivide.
+
+
+File: octave.info,  Node: Bit Manipulations,  Next: Logical Values,  Prev: Integer Data Types,  Up: Numeric Data Types
+
+4.5 Bit Manipulations
+=====================
+
+Octave provides a number of functions for the manipulation of numeric
+values on a bit by bit basis.  The basic functions to set and obtain the
+values of individual bits are `bitset' and `bitget'.
+
+ -- Function File: X = bitset (A, N)
+ -- Function File: X = bitset (A, N, V)
+     Set or reset bit(s) N of unsigned integers in A.  V = 0 resets and
+     V = 1 sets the bits.  The lowest significant bit is: N = 1
+
+          dec2bin (bitset (10, 1))
+          => 1011
+
+     *See also:* *note bitand: doc-bitand, *note bitor: doc-bitor,
+     *note bitxor: doc-bitxor, *note bitget: doc-bitget, *note bitcmp:
+     doc-bitcmp, *note bitshift: doc-bitshift, *note bitmax: doc-bitmax.
+
+ -- Function File: X = bitget (A,N)
+     Return the status of bit(s) N of unsigned integers in A the lowest
+     significant bit is N = 1.
+
+          bitget (100, 8:-1:1)
+          => 0  1  1  0  0  1  0  0
+
+     *See also:* *note bitand: doc-bitand, *note bitor: doc-bitor,
+     *note bitxor: doc-bitxor, *note bitset: doc-bitset, *note bitcmp:
+     doc-bitcmp, *note bitshift: doc-bitshift, *note bitmax: doc-bitmax.
+
+   The arguments to all of Octave's bitwise operations can be scalar or
+arrays, except for `bitcmp', whose K argument must a scalar.  In the
+case where more than one argument is an array, then all arguments must
+have the same shape, and the bitwise operator is applied to each of the
+elements of the argument individually.  If at least one argument is a
+scalar and one an array, then the scalar argument is duplicated.
+Therefore
+
+     bitget (100, 8:-1:1)
+
+   is the same as
+
+     bitget (100 * ones (1, 8), 8:-1:1)
+
+   It should be noted that all values passed to the bit manipulation
+functions of Octave are treated as integers.  Therefore, even though the
+example for `bitset' above passes the floating point value `10', it is
+treated as the bits `[1, 0, 1, 0]' rather than the bits of the native
+floating point format representation of `10'.
+
+   As the maximum value that can be represented by a number is important
+for bit manipulation, particularly when forming masks, Octave supplies
+the function `bitmax'.
+
+ -- Built-in Function:  bitmax ()
+     Return the largest integer that can be represented as a floating
+     point value.  On IEEE-754 compatible systems, `bitmax' is `2^53 -
+     1'.
+
+   This is the double precision version of the functions `intmax',
+previously discussed.
+
+   Octave also includes the basic bitwise 'and', 'or' and 'exclusive or'
+operators.
+
+ -- Built-in Function:  bitand (X, Y)
+     Return the bitwise AND of non-negative integers.  X, Y must be in
+     the range [0,bitmax]
+
+     *See also:* *note bitor: doc-bitor, *note bitxor: doc-bitxor,
+     *note bitset: doc-bitset, *note bitget: doc-bitget, *note bitcmp:
+     doc-bitcmp, *note bitshift: doc-bitshift, *note bitmax: doc-bitmax.
+
+ -- Built-in Function:  bitor (X, Y)
+     Return the bitwise OR of non-negative integers.  X, Y must be in
+     the range [0,bitmax]
+
+     *See also:* *note bitor: doc-bitor, *note bitxor: doc-bitxor,
+     *note bitset: doc-bitset, *note bitget: doc-bitget, *note bitcmp:
+     doc-bitcmp, *note bitshift: doc-bitshift, *note bitmax: doc-bitmax.
+
+ -- Built-in Function:  bitxor (X, Y)
+     Return the bitwise XOR of non-negative integers.  X, Y must be in
+     the range [0,bitmax]
+
+     *See also:* *note bitand: doc-bitand, *note bitor: doc-bitor,
+     *note bitset: doc-bitset, *note bitget: doc-bitget, *note bitcmp:
+     doc-bitcmp, *note bitshift: doc-bitshift, *note bitmax: doc-bitmax.
+
+   The bitwise 'not' operator is a unary operator that performs a
+logical negation of each of the bits of the value.  For this to make
+sense, the mask against which the value is negated must be defined.
+Octave's bitwise 'not' operator is `bitcmp'.
+
+ -- Function File:  bitcmp (A, K)
+     Return the K-bit complement of integers in A.  If K is omitted `k
+     = log2 (bitmax) + 1' is assumed.
+
+          bitcmp(7,4)
+          => 8
+          dec2bin(11)
+          => 1011
+          dec2bin(bitcmp(11, 6))
+          => 110100
+
+     *See also:* *note bitand: doc-bitand, *note bitor: doc-bitor,
+     *note bitxor: doc-bitxor, *note bitset: doc-bitset, *note bitget:
+     doc-bitget, *note bitcmp: doc-bitcmp, *note bitshift:
+     doc-bitshift, *note bitmax: doc-bitmax.
+
+   Octave also includes the ability to left-shift and right-shift
+values bitwise.
+
+ -- Built-in Function:  bitshift (A, K)
+ -- Built-in Function:  bitshift (A, K, N)
+     Return a K bit shift of N-digit unsigned integers in A.  A
+     positive K leads to a left shift.  A negative value to a right
+     shift.  If N is omitted it defaults to log2(bitmax)+1.  N must be
+     in the range [1,log2(bitmax)+1] usually [1,33]
+
+          bitshift (eye (3), 1)
+          =>
+          2 0 0
+          0 2 0
+          0 0 2
+
+          bitshift (10, [-2, -1, 0, 1, 2])
+          => 2   5  10  20  40
+
+     *See also:* *note bitand: doc-bitand, *note bitor: doc-bitor,
+     *note bitxor: doc-bitxor, *note bitset: doc-bitset, *note bitget:
+     doc-bitget, *note bitcmp: doc-bitcmp, *note bitmax: doc-bitmax.
+
+   Bits that are shifted out of either end of the value are lost.
+Octave also uses arithmetic shifts, where the sign bit of the value is
+kept during a right shift.  For example
+
+     bitshift (-10, -1)
+     => -5
+     bitshift (int8 (-1), -1)
+     => -1
+
+   Note that `bitshift (int8 (-1), -1)' is `-1' since the bit
+representation of `-1' in the `int8' data type is `[1, 1, 1, 1, 1, 1,
+1, 1]'.
+
+
+File: octave.info,  Node: Logical Values,  Next: Promotion and Demotion of Data Types,  Prev: Bit Manipulations,  Up: Numeric Data Types
+
+4.6 Logical Values
+==================
+
+Octave has built-in support for logical values, i.e., variables that
+are either `true' or `false'.  When comparing two variables, the result
+will be a logical value whose value depends on whether or not the
+comparison is true.
+
+   The basic logical operations are `&', `|', and `!', which correspond
+to "Logical And", "Logical Or", and "Logical Negation".  These
+operations all follow the usual rules of logic.
+
+   It is also possible to use logical values as part of standard
+numerical calculations.  In this case `true' is converted to `1', and
+`false' to 0, both represented using double precision floating point
+numbers.  So, the result of `true*22 - false/6' is `22'.
+
+   Logical values can also be used to index matrices and cell arrays.
+When indexing with a logical array the result will be a vector
+containing the values corresponding to `true' parts of the logical
+array.  The following example illustrates this.
+
+     data = [ 1, 2; 3, 4 ];
+     idx = (data <= 2);
+     data(idx)
+          => ans = [ 1; 2 ]
+
+Instead of creating the `idx' array it is possible to replace
+`data(idx)' with `data( data <= 2 )' in the above code.
+
+   Logical values can also be constructed by casting numeric objects to
+logical values, or by using the `true' or `false' functions.
+
+ -- Function File:  logical (ARG)
+     Convert ARG to a logical value.  For example,
+
+          logical ([-1, 0, 1])
+
+     is equivalent to
+
+          [-1, 0, 1] != 0
+
+ -- Built-in Function:  true (X)
+ -- Built-in Function:  true (N, M)
+ -- Built-in Function:  true (N, M, K, ...)
+     Return a matrix or N-dimensional array whose elements are all
+     logical 1.  The arguments are handled the same as the arguments
+     for `eye'.
+
+ -- Built-in Function:  false (X)
+ -- Built-in Function:  false (N, M)
+ -- Built-in Function:  false (N, M, K, ...)
+     Return a matrix or N-dimensional array whose elements are all
+     logical 0.  The arguments are handled the same as the arguments
+     for `eye'.
+
+
+File: octave.info,  Node: Promotion and Demotion of Data Types,  Next: Predicates for Numeric Objects,  Prev: Logical Values,  Up: Numeric Data Types
+
+4.7 Promotion and Demotion of Data Types
+========================================
+
+Many operators and functions can work with mixed data types.  For
+example
+
+     uint8 (1) + 1
+         => 2
+
+where the above operator works with an 8-bit integer and a double
+precision value and returns an 8-bit integer value.  Note that the type
+is demoted to an 8-bit integer, rather than promoted to a double
+precision value as might be expected.  The reason is that if Octave
+promoted values in expressions like the above with all numerical
+constants would need to be explicitly cast to the appropriate data type
+like
+
+     uint8 (1) + uint8 (1)
+         => 2
+
+which becomes difficult for the user to apply uniformly and might allow
+hard to find bugs to be introduced.  The same applies to single
+precision values where a mixed operation such as
+
+     single (1) + 1
+         => 2
+
+returns a single precision value.  The mixed operations that are valid
+and their returned data types are
+
+               Mixed Operation        Result                 
+               double OP single       single                 
+               double OP integer      integer                
+               double OP char         double                 
+               double OP logical      double                 
+               single OP integer      integer                
+               single OP char         single                 
+               single OP logical      single                 
+
+   The same logic applies to functions with mixed arguments such as
+
+     min (single (1), 0)
+        => 0
+
+where the returned value is single precision.
+
+   In the case of mixed type indexed assignments, the type is not
+changed.  For example
+
+     x = ones (2, 2);
+     x (1, 1) = single (2)
+         => x = 2   1
+                1   1
+
+where `x' remains of the double precision type.
+
+
+File: octave.info,  Node: Predicates for Numeric Objects,  Prev: Promotion and Demotion of Data Types,  Up: Numeric Data Types
+
+4.8 Predicates for Numeric Objects
+==================================
+
+Since the type of a variable may change during the execution of a
+program, it can be necessary to do type checking at run-time.  Doing
+this also allows you to change the behavior of a function depending on
+the type of the input.  As an example, this naive implementation of
+`abs' returns the absolute value of the input if it is a real number,
+and the length of the input if it is a complex number.
+
+     function a = abs (x)
+       if (isreal (x))
+         a = sign (x) .* x;
+       elseif (iscomplex (x))
+         a = sqrt (real(x).^2 + imag(x).^2);
+       endif
+     endfunction
+
+   The following functions are available for determining the type of a
+variable.
+
+ -- Built-in Function:  isnumeric (X)
+     Return nonzero if X is a numeric object.
+
+ -- Built-in Function:  isreal (X)
+     Return true if X is a real-valued numeric object.
+
+ -- Built-in Function:  isfloat (X)
+     Return true if X is a floating-point numeric object.
+
+ -- Built-in Function:  iscomplex (X)
+     Return true if X is a complex-valued numeric object.
+
+ -- Built-in Function:  ismatrix (A)
+     Return 1 if A is a matrix.  Otherwise, return 0.
+
+ -- Function File:  isvector (A)
+     Return 1 if A is a vector.  Otherwise, return 0.
+
+     *See also:* *note size: doc-size, *note rows: doc-rows, *note
+     columns: doc-columns, *note length: doc-length, *note isscalar:
+     doc-isscalar, *note ismatrix: doc-ismatrix.
+
+ -- Function File:  isscalar (A)
+     Return 1 if A is a scalar.  Otherwise, return 0.
+
+     *See also:* *note size: doc-size, *note rows: doc-rows, *note
+     columns: doc-columns, *note length: doc-length, *note isscalar:
+     doc-isscalar, *note ismatrix: doc-ismatrix.
+
+ -- Function File:  issquare (X)
+     If X is a square matrix, then return the dimension of X.
+     Otherwise, return 0.
+
+     *See also:* *note size: doc-size, *note rows: doc-rows, *note
+     columns: doc-columns, *note length: doc-length, *note ismatrix:
+     doc-ismatrix, *note isscalar: doc-isscalar, *note isvector:
+     doc-isvector.
+
+ -- Function File:  issymmetric (X, TOL)
+     If X is symmetric within the tolerance specified by TOL, then
+     return the dimension of X.  Otherwise, return 0.  If TOL is
+     omitted, use a tolerance equal to the machine precision.  Matrix X
+     is considered symmetric if `norm (X - X.', inf) / norm (X, inf) <
+     TOL'.
+
+     *See also:* *note size: doc-size, *note rows: doc-rows, *note
+     columns: doc-columns, *note length: doc-length, *note ismatrix:
+     doc-ismatrix, *note isscalar: doc-isscalar, *note issquare:
+     doc-issquare, *note isvector: doc-isvector.
+
+ -- Function File:  isdefinite (X, TOL)
+     Return 1 if X is symmetric positive definite within the tolerance
+     specified by TOL or 0 if X is symmetric positive semidefinite.
+     Otherwise, return -1.  If TOL is omitted, use a tolerance equal to
+     100 times the machine precision.
+
+     *See also:* *note issymmetric: doc-issymmetric.
+
+ -- Built-in Function:  islogical (X)
+     Return true if X is a logical object.
+
+ -- Function File:  isprime (N)
+     Return true if N is a prime number, false otherwise.
+
+     Something like the following is much faster if you need to test a
+     lot of small numbers:
+
+             T = ismember (N, primes (max (N (:))));
+
+     If max(n) is very large, then you should be using special purpose
+     factorization code.
+
+     *See also:* *note primes: doc-primes, *note factor: doc-factor,
+     *note gcd: doc-gcd, *note lcm: doc-lcm.
+
+
+File: octave.info,  Node: Strings,  Next: Data Containers,  Prev: Numeric Data Types,  Up: Top
+
+5 Strings
+*********
+
+A "string constant" consists of a sequence of characters enclosed in
+either double-quote or single-quote marks.  For example, both of the
+following expressions
+
+     "parrot"
+     'parrot'
+
+represent the string whose contents are `parrot'.  Strings in Octave
+can be of any length.
+
+   Since the single-quote mark is also used for the transpose operator
+(*note Arithmetic Ops::) but double-quote marks have no other purpose
+in Octave, it is best to use double-quote marks to denote strings.
+
+   Strings can be concatenated using the notation for defining
+matrices.  For example, the expression
+
+     [ "foo" , "bar" , "baz" ]
+
+produces the string whose contents are `foobarbaz'.  *Note Numeric Data
+Types::, for more information about creating matrices.
+
+* Menu:
+
+* Escape Sequences in string constants::
+* Character Arrays::
+* Creating Strings::
+* Comparing Strings::
+* Manipulating Strings::
+* String Conversions::
+* Character Class Functions::
+
+
+File: octave.info,  Node: Escape Sequences in string constants,  Next: Character Arrays,  Up: Strings
+
+5.1 Escape Sequences in string constants
+========================================
+
+In double-quoted strings, the backslash character is used to introduce
+"escape sequences" that represent other characters.  For example, `\n'
+embeds a newline character in a double-quoted string and `\"' embeds a
+double quote character.  In single-quoted strings, backslash is not a
+special character.  Here is an example showing the difference:
+
+     toascii ("\n")
+         => 10
+     toascii ('\n')
+         => [ 92 110 ]
+
+   Here is a table of all the escape sequences used in Octave (within
+double quoted strings).  They are the same as those used in the C
+programming language.
+
+`\\'
+     Represents a literal backslash, `\'.
+
+`\"'
+     Represents a literal double-quote character, `"'.
+
+`\''
+     Represents a literal single-quote character, `''.
+
+`\0'
+     Represents the "nul" character, control-@, ASCII code 0.
+
+`\a'
+     Represents the "alert" character, control-g, ASCII code 7.
+
+`\b'
+     Represents a backspace, control-h, ASCII code 8.
+
+`\f'
+     Represents a formfeed, control-l, ASCII code 12.
+
+`\n'
+     Represents a newline, control-j, ASCII code 10.
+
+`\r'
+     Represents a carriage return, control-m, ASCII code 13.
+
+`\t'
+     Represents a horizontal tab, control-i, ASCII code 9.
+
+`\v'
+     Represents a vertical tab, control-k, ASCII code 11.
+
+
+   In a single-quoted string there is only one escape sequence: you may
+insert a single quote character using two single quote characters in
+succession.  For example,
+
+     'I can''t escape'
+         => I can't escape
+
+
+File: octave.info,  Node: Character Arrays,  Next: Creating Strings,  Prev: Escape Sequences in string constants,  Up: Strings
+
+5.2 Character Arrays
+====================
+
+The string representation used by Octave is an array of characters, so
+internally the string "dddddddddd" is actually a row vector of length 10
+containing the value 100 in all places (100 is the ASCII code of "d").
+This lends itself to the obvious generalization to character matrices.
+Using a matrix of characters, it is possible to represent a collection
+of same-length strings in one variable.  The convention used in Octave
+is that each row in a character matrix is a separate string, but
+letting each column represent a string is equally possible.
+
+   The easiest way to create a character matrix is to put several
+strings together into a matrix.
+
+     collection = [ "String #1"; "String #2" ];
+
+This creates a 2-by-9 character matrix.
+
+   The function `ischar' can be used to test if an object is a character
+matrix.
+
+ -- Built-in Function:  ischar (A)
+     Return 1 if A is a character array.  Otherwise, return 0.
+
+   To test if an object is a string (i.e., a character vector and not a
+character matrix) you can use the `ischar' function in combination with
+the `isvector' function as in the following example:
+
+     ischar(collection)
+          => ans = 1
+
+     ischar(collection) && isvector(collection)
+          => ans = 0
+
+     ischar("my string") && isvector("my string")
+          => ans = 1
+
+   One relevant question is, what happens when a character matrix is
+created from strings of different length.  The answer is that Octave
+puts blank characters at the end of strings shorter than the longest
+string.  It is possible to use a different character than the blank
+character using the `string_fill_char' function.
+
+ -- Built-in Function: VAL = string_fill_char ()
+ -- Built-in Function: OLD_VAL = string_fill_char (NEW_VAL)
+     Query or set the internal variable used to pad all rows of a
+     character matrix to the same length.  It must be a single
+     character.  The default value is `" "' (a single space).  For
+     example,
+
+          string_fill_char ("X");
+          [ "these"; "are"; "strings" ]
+               => "theseXX"
+                  "areXXXX"
+                  "strings"
+
+   This shows a problem with character matrices.  It simply isn't
+possible to represent strings of different lengths.  The solution is to
+use a cell array of strings, which is described in *note Cell Arrays of
+Strings::.
+
+
+File: octave.info,  Node: Creating Strings,  Next: Comparing Strings,  Prev: Character Arrays,  Up: Strings
+
+5.3 Creating Strings
+====================
+
+The easiest way to create a string is, as illustrated in the
+introduction, to enclose a text in double-quotes or single-quotes.  It
+is however possible to create a string without actually writing a text.
+The function `blanks' creates a string of a given length consisting
+only of blank characters (ASCII code 32).
+
+ -- Function File:  blanks (N)
+     Return a string of N blanks, for example:
+
+          blanks(10);
+          whos ans;
+               =>
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     ans         1x10                        10  char
+
+     *See also:* *note repmat: doc-repmat.
+
+* Menu:
+
+* Concatenating Strings::
+* Conversion of Numerical Data to Strings::
+
+
+File: octave.info,  Node: Concatenating Strings,  Next: Conversion of Numerical Data to Strings,  Up: Creating Strings
+
+5.3.1 Concatenating Strings
+---------------------------
+
+It has been shown above that strings can be concatenated using matrix
+notation (*note Strings::, *note Character Arrays::).  Apart from that,
+there are several functions to concatenate string objects: `char',
+`strvcat', `strcat' and `cstrcat'.  In addition, the general purpose
+concatenation functions can be used: see *note cat: doc-cat, *note
+horzcat: doc-horzcat. and *note vertcat: doc-vertcat.
+
+   * All string concatenation functions except `cstrcat' convert
+     numerical input into character data by taking the corresponding
+     ASCII character for each element, as in the following example:
+
+          char([98, 97, 110, 97, 110, 97])
+               => ans =
+                 banana
+
+   * `char' and `strvcat' concatenate vertically, while `strcat' and
+     `cstrcat' concatenate horizontally.  For example:
+
+          char("an apple", "two pears")
+               => ans =
+                 an apple
+                 two pears
+
+          strcat("oc", "tave", " is", " good", " for you")
+               => ans =
+                 octave is good for you
+
+   * `char' generates an empty row in the output for each empty string
+     in the input.  `strvcat', on the other hand, eliminates empty
+     strings.
+
+          char("orange", "green", "", "red")
+               => ans =
+                 orange
+                 green
+
+                 red
+
+          strvcat("orange", "green", "", "red")
+               => ans =
+                 orange
+                 green
+                 red
+
+   * All string concatenation functions except `cstrcat' also accept
+     cell array data (*note Cell Arrays::).  `char' and `strvcat'
+     convert cell arrays into character arrays, while `strcat'
+     concatenates within the cells of the cell arrays:
+
+          char({"red", "green", "", "blue"})
+               => ans =
+                 red
+                 green
+
+                 blue
+
+          strcat({"abc"; "ghi"}, {"def"; "jkl"})
+               => ans =
+                 {
+                   [1,1] = abcdef
+                   [2,1] = ghijkl
+                 }
+
+   * `strcat' removes trailing white space in the arguments (except
+     within cell arrays), while `cstrcat' leaves white space untouched.
+     Both kinds of behavior can be useful as can be seen in the
+     examples:
+
+          strcat(["dir1";"directory2"], ["/";"/"], ["file1";"file2"])
+               => ans =
+                 dir1/file1
+                 directory2/file2
+
+          cstrcat(["thirteen apples"; "a banana"], [" 5$";" 1$"])
+               => ans =
+                 thirteen apples 5$
+                 a banana        1$
+
+     Note that in the above example for `cstrcat', the white space
+     originates from the internal representation of the strings in a
+     string array (*note Character Arrays::).
+
+ -- Built-in Function:  char (X)
+ -- Built-in Function:  char (X, ...)
+ -- Built-in Function:  char (S1, S2, ...)
+ -- Built-in Function:  char (CELL_ARRAY)
+     Create a string array from one or more numeric matrices, character
+     matrices, or cell arrays.  Arguments are concatenated vertically.
+     The returned values are padded with blanks as needed to make each
+     row of the string array have the same length.  Empty input strings
+     are significant and will concatenated in the output.
+
+     For numerical input, each element is converted to the
+     corresponding ASCII character.  A range error results if an input
+     is outside the ASCII range (0-255).
+
+     For cell arrays, each element is concatenated separately.  Cell
+     arrays converted through `char' can mostly be converted back with
+     `cellstr'.  For example,
+
+          char ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
+               => ["abc    "
+                   "       "
+                   "98     "
+                   "99     "
+                   "d      "
+                   "str1   "
+                   "half   "]
+
+     *See also:* *note strvcat: doc-strvcat, *note cellstr: doc-cellstr.
+
+ -- Built-in Function:  strvcat (X)
+ -- Built-in Function:  strvcat (X, ...)
+ -- Built-in Function:  strvcat (S1, S2, ...)
+ -- Built-in Function:  strvcat (CELL_ARRAY)
+     Create a character array from one or more numeric matrices,
+     character matrices, or cell arrays.  Arguments are concatenated
+     vertically.  The returned values are padded with blanks as needed
+     to make each row of the string array have the same length.  Unlike
+     `char', empty strings are removed and will not appear in the
+     output.
+
+     For numerical input, each element is converted to the
+     corresponding ASCII character.  A range error results if an input
+     is outside the ASCII range (0-255).
+
+     For cell arrays, each element is concatenated separately.  Cell
+     arrays converted through `strvcat' can mostly be converted back
+     with `cellstr'.  For example,
+
+          strvcat ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
+               => ["abc    "
+                   "98     "
+                   "99     "
+                   "d      "
+                   "str1   "
+                   "half   "]
+
+     *See also:* *note char: doc-char, *note strcat: doc-strcat, *note
+     cstrcat: doc-cstrcat.
+
+ -- Function File:  strcat (S1, S2, ...)
+     Return a string containing all the arguments concatenated
+     horizontally.  If the arguments are cells strings,  `strcat'
+     returns a cell string with the individual cells concatenated.  For
+     numerical input, each element is converted to the corresponding
+     ASCII character.  Trailing white space is eliminated.  For example,
+
+          s = [ "ab"; "cde" ];
+          strcat (s, s, s)
+               => ans =
+                  "ab ab ab "
+                  "cdecdecde"
+
+          s = { "ab"; "cde" };
+          strcat (s, s, s)
+               => ans =
+                  {
+                    [1,1] = ababab
+                    [2,1] = cdecdecde
+                  }
+
+     *See also:* *note cstrcat: doc-cstrcat, *note char: doc-char,
+     *note strvcat: doc-strvcat.
+
+ -- Function File:  cstrcat (S1, S2, ...)
+     Return a string containing all the arguments concatenated
+     horizontally.  Trailing white space is preserved.  For example,
+
+          cstrcat ("ab   ", "cd")
+               => "ab   cd"
+
+          s = [ "ab"; "cde" ];
+          cstrcat (s, s, s)
+               => ans =
+                  "ab ab ab "
+                  "cdecdecde"
+
+     *See also:* *note strcat: doc-strcat, *note char: doc-char, *note
+     strvcat: doc-strvcat.
+
+
+File: octave.info,  Node: Conversion of Numerical Data to Strings,  Prev: Concatenating Strings,  Up: Creating Strings
+
+5.3.2 Conversion of Numerical Data to Strings
+---------------------------------------------
+
+Apart from the string concatenation functions (*note Concatenating
+Strings::) which cast numerical data to the corresponding ASCII
+characters, there are several functions that format numerical data as
+strings.  `mat2str' and `num2str' convert real or complex matrices,
+while `int2str' converts integer matrices.  `int2str' takes the real
+part of complex values and round fractional values to integer.  A more
+flexible way to format numerical data as strings is the `sprintf'
+function (*note Formatted Output::, *note doc-sprintf::).
+
+ -- Function File: S = mat2str (X, N)
+ -- Function File: S = mat2str (..., 'class')
+     Format real/complex numerical matrices as strings.  This function
+     returns values that are suitable for the use of the `eval'
+     function.
+
+     The precision of the values is given by N.  If N is a scalar then
+     both real and imaginary parts of the matrix are printed to the
+     same precision.  Otherwise `N (1)' defines the precision of the
+     real part and `N (2)' defines the precision of the imaginary part.
+     The default for N is 17.
+
+     If the argument 'class' is given, then the class of X is included
+     in the string in such a way that the eval will result in the
+     construction of a matrix of the same class.
+
+          mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
+               => "[-0.3333+0.14i;0.3333-0.14i]"
+
+          mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
+               => "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]"
+
+          mat2str (int16([1 -1]), 'class')
+               => "int16([1,-1])"
+
+     *See also:* *note sprintf: doc-sprintf, *note num2str:
+     doc-num2str, *note int2str: doc-int2str.
+
+ -- Function File:  num2str (X)
+ -- Function File:  num2str (X, PRECISION)
+ -- Function File:  num2str (X, FORMAT)
+     Convert a number (or array) to a string (or a character array).
+     The optional second argument may either give the number of
+     significant digits (PRECISION) to be used in the output or a format
+     template string (FORMAT) as in `sprintf' (*note Formatted
+     Output::).  `num2str' can also handle complex numbers.  For
+     example:
+
+          num2str (123.456)
+               => "123.46"
+
+          num2str (123.456, 4)
+               => "123.5"
+
+          s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
+               => s =
+                  1.0  1.3
+                  3.0  3.6
+          whos s
+               =>
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     s           2x8                         16  char
+
+          num2str (1.234 + 27.3i)
+               => "1.234+27.3i"
+
+     The `num2str' function is not very flexible.  For better control
+     over the results, use `sprintf' (*note Formatted Output::).  Note
+     that for complex X, the format string may only contain one output
+     conversion specification and nothing else.  Otherwise, you will
+     get unpredictable results.
+
+     *See also:* *note sprintf: doc-sprintf, *note int2str:
+     doc-int2str, *note mat2str: doc-mat2str.
+
+ -- Function File:  int2str (N)
+     Convert an integer (or array of integers) to a string (or a
+     character array).
+
+
+          int2str (123)
+               => "123"
+
+          s = int2str ([1, 2, 3; 4, 5, 6])
+               => s =
+                  1  2  3
+                  4  5  6
+
+          whos s
+               => s =
+                Attr Name        Size                     Bytes  Class
+                ==== ====        ====                     =====  =====
+                     s           2x7                         14  char
+
+     This function is not very flexible.  For better control over the
+     results, use `sprintf' (*note Formatted Output::).
+
+     *See also:* *note sprintf: doc-sprintf, *note num2str:
+     doc-num2str, *note mat2str: doc-mat2str.
+
+
+File: octave.info,  Node: Comparing Strings,  Next: Manipulating Strings,  Prev: Creating Strings,  Up: Strings
+
+5.4 Comparing Strings
+=====================
+
+Since a string is a character array, comparisons between strings work
+element by element as the following example shows:
+
+     GNU = "GNU's Not UNIX";
+     spaces = (GNU == " ")
+          => spaces =
+            0   0   0   0   0   1   0   0   0   1   0   0   0   0
+
+To determine if two strings are identical it is necessary to use the
+`strcmp' function.  It compares complete strings and is case sensitive.
+`strncmp' compares only the first `N' characters (with `N' given as a
+parameter).  `strcmpi' and `strncmpi' are the corresponding functions
+for case-insensitive comparison.
+
+ -- Built-in Function:  strcmp (S1, S2)
+     Return 1 if the character strings S1 and S2 are the same, and 0
+     otherwise.
+
+     If either S1 or S2 is a cell array of strings, then an array of
+     the same size is returned, containing the values described above
+     for every member of the cell array.  The other argument may also
+     be a cell array of strings (of the same size or with only one
+     element), char matrix or character string.
+
+     *Caution:* For compatibility with MATLAB, Octave's strcmp function
+     returns 1 if the character strings are equal, and 0 otherwise.
+     This is just the opposite of the corresponding C library function.
+
+     *See also:* *note strcmpi: doc-strcmpi, *note strncmp:
+     doc-strncmp, *note strncmpi: doc-strncmpi.
+
+ -- Built-in Function:  strncmp (S1, S2, N)
+     Return 1 if the first N characters of strings S1 and S2 are the
+     same, and 0 otherwise.
+
+          strncmp ("abce", "abcd", 3)
+               => 1
+
+     If either S1 or S2 is a cell array of strings, then an array of
+     the same size is returned, containing the values described above
+     for every member of the cell array.  The other argument may also
+     be a cell array of strings (of the same size or with only one
+     element), char matrix or character string.
+
+          strncmp ("abce", {"abcd", "bca", "abc"}, 3)
+               => [1, 0, 1]
+
+     *Caution:* For compatibility with MATLAB, Octave's strncmp
+     function returns 1 if the character strings are equal, and 0
+     otherwise.  This is just the opposite of the corresponding C
+     library function.
+
+     *See also:* *note strncmpi: doc-strncmpi, *note strcmp:
+     doc-strcmp, *note strcmpi: doc-strcmpi.
+
+ -- Function File:  strcmpi (S1, S2)
+     Ignoring case, return 1 if the character strings (or character
+     arrays) S1 and S2 are the same, and 0 otherwise.
+
+     If either S1 or S2 is a cell array of strings, then an array of
+     the same size is returned, containing the values described above
+     for every member of the cell array.  The other argument may also
+     be a cell array of strings (of the same size or with only one
+     element), char matrix or character string.
+
+     *Caution:* For compatibility with MATLAB, Octave's strcmpi
+     function returns 1 if the character strings are equal, and 0
+     otherwise.  This is just the opposite of the corresponding C
+     library function.
+
+     *See also:* *note strcmp: doc-strcmp, *note strncmp: doc-strncmp,
+     *note strncmpi: doc-strncmpi.
+
+ -- Function File:  strncmpi (S1, S2, N)
+     Ignoring case, return 1 if the first N characters of character
+     strings (or character arrays) S1 and S2 are the same, and 0
+     otherwise.
+
+     If either S1 or S2 is a cell array of strings, then an array of
+     the same size is returned, containing the values described above
+     for every member of the cell array.  The other argument may also
+     be a cell array of strings (of the same size or with only one
+     element), char matrix or character string.
+
+     *Caution:* For compatibility with MATLAB, Octave's strncmpi
+     function returns 1 if the character strings are equal, and 0
+     otherwise.  This is just the opposite of the corresponding C
+     library function.
+
+     *See also:* *note strcmp: doc-strcmp, *note strcmpi: doc-strcmpi,
+     *note strncmp: doc-strncmp.
+
+ -- Function File: VALIDSTR = validatestring (STR, STRARRAY)
+ -- Function File: VALIDSTR = validatestring (STR, STRARRAY, FUNCNAME)
+ -- Function File: VALIDSTR = validatestring (STR, STRARRAY, FUNCNAME,
+          VARNAME)
+ -- Function File: VALIDSTR = validatestring (..., POSITION)
+     Verify that STR is a string or substring of an element of STRARRAY.
+
+     STR is a character string to be tested, and STRARRAY is a cellstr
+     of valid values.  VALIDSTR will be the validated form of STR where
+     validation is defined as STR being a member or substring of
+     VALIDSTR.  If STR is a substring of VALIDSTR and there are
+     multiple matches, the shortest match will be returned if all
+     matches are substrings of each other, and an error will be raised
+     if the matches are not substrings of each other.
+
+     All comparisons are case insensitive.
+
+     *See also:* *note strcmp: doc-strcmp, *note strcmpi: doc-strcmpi.
+
+
+File: octave.info,  Node: Manipulating Strings,  Next: String Conversions,  Prev: Comparing Strings,  Up: Strings
+
+5.5 Manipulating Strings
+========================
+
+Octave supports a wide range of functions for manipulating strings.
+Since a string is just a matrix, simple manipulations can be
+accomplished using standard operators.  The following example shows how
+to replace all blank characters with underscores.
+
+     quote = ...
+       "First things first, but not necessarily in that order";
+     quote( quote == " " ) = "_"
+     => quote =
+         First_things_first,_but_not_necessarily_in_that_order
+
+   For more complex manipulations, such as searching, replacing, and
+general regular expressions, the following functions come with Octave.
+
+ -- Function File:  deblank (S)
+     Remove trailing blanks and nulls from S.  If S is a matrix,
+     DEBLANK trims each row to the length of longest string.  If S is a
+     cell array, operate recursively on each element of the cell array.
+
+ -- Function File:  strtrim (S)
+     Remove leading and trailing blanks and nulls from S.  If S is a
+     matrix, STRTRIM trims each row to the length of longest string.
+     If S is a cell array, operate recursively on each element of the
+     cell array.  For example:
+
+          strtrim ("    abc  ")
+               => "abc"
+
+          strtrim ([" abc   "; "   def   "])
+               => ["abc  "; "  def"]
+
+ -- Function File:  strtrunc (S, N)
+     Truncate the character string S to length N.  If S is a char
+     matrix, then the number of columns is adjusted.
+
+     If S is a cell array of strings, then the operation is performed
+     on its members and the new cell array is returned.
+
+ -- Function File:  findstr (S, T, OVERLAP)
+     Return the vector of all positions in the longer of the two strings
+     S and T where an occurrence of the shorter of the two starts.  If
+     the optional argument OVERLAP is nonzero, the returned vector can
+     include overlapping positions (this is the default).  For example,
+
+          findstr ("ababab", "a")
+               => [1, 3, 5]
+          findstr ("abababa", "aba", 0)
+               => [1, 5]
+
+     *See also:* *note strfind: doc-strfind, *note strmatch:
+     doc-strmatch, *note strcmp: doc-strcmp, *note strncmp:
+     doc-strncmp, *note strcmpi: doc-strcmpi, *note strncmpi:
+     doc-strncmpi, *note find: doc-find.
+
+ -- Function File: IDX = strchr (STR, CHARS)
+ -- Function File: IDX = strchr (STR, CHARS, N)
+ -- Function File: IDX = strchr (STR, CHARS, N, DIRECTION)
+     Search for the string STR for occurrences of characters from the
+     set CHARS.  The return value, as well as the N and DIRECTION
+     arguments behave identically as in `find'.
+
+     This will be faster than using regexp in most cases.
+
+     *See also:* *note find: doc-find.
+
+ -- Function File:  index (S, T)
+ -- Function File:  index (S, T, DIRECTION)
+     Return the position of the first occurrence of the string T in the
+     string S, or 0 if no occurrence is found.  For example,
+
+          index ("Teststring", "t")
+               => 4
+
+     If DIRECTION is `"first"', return the first element found.  If
+     DIRECTION is `"last"', return the last element found.  The
+     `rindex' function is equivalent to `index' with DIRECTION set to
+     `"last"'.
+
+     *Caution:*  This function does not work for arrays of character
+     strings.
+
+     *See also:* *note find: doc-find, *note rindex: doc-rindex.
+
+ -- Function File:  rindex (S, T)
+     Return the position of the last occurrence of the character string
+     T in the character string S, or 0 if no occurrence is found.  For
+     example,
+
+          rindex ("Teststring", "t")
+               => 6
+
+     *Caution:*  This function does not work for arrays of character
+     strings.
+
+     *See also:* *note find: doc-find, *note index: doc-index.
+
+ -- Function File: IDX = strfind (STR, PATTERN)
+ -- Function File: IDX = strfind (CELLSTR, PATTERN)
+     Search for PATTERN in the string STR and return the starting index
+     of every such occurrence in the vector IDX.  If there is no such
+     occurrence, or if PATTERN is longer than STR, then IDX is the
+     empty array `[]'.
+
+     If the cell array of strings CELLSTR is specified instead of the
+     string STR, then IDX is a cell array of vectors, as specified
+     above.  Examples:
+
+          strfind ("abababa", "aba")
+               => [1, 3, 5]
+
+          strfind ({"abababa", "bebebe", "ab"}, "aba")
+               => ans =
+                  {
+                    [1,1] =
+
+                       1   3   5
+
+                    [1,2] = [](1x0)
+                    [1,3] = [](1x0)
+                  }
+
+     *See also:* *note findstr: doc-findstr, *note strmatch:
+     doc-strmatch, *note strcmp: doc-strcmp, *note strncmp:
+     doc-strncmp, *note strcmpi: doc-strcmpi, *note strncmpi:
+     doc-strncmpi, *note find: doc-find.
+
+ -- Function File:  strmatch (S, A, "exact")
+     Return indices of entries of A that match the string S.  The
+     second argument A may be a string matrix or a cell array of
+     strings.  If the third argument `"exact"' is not given, then S
+     only needs to match A up to the length of S.  Nul characters match
+     blanks.  Results are returned as a column vector.  For example:
+
+          strmatch ("apple", "apple juice")
+               => 1
+
+          strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
+               => [1; 2]
+
+          strmatch ("apple", {"apple pie"; "apple juice"; "tomato"})
+               => [1; 2]
+
+     *See also:* *note strfind: doc-strfind, *note findstr:
+     doc-findstr, *note strcmp: doc-strcmp, *note strncmp: doc-strncmp,
+     *note strcmpi: doc-strcmpi, *note strncmpi: doc-strncmpi, *note
+     find: doc-find.
+
+ -- Function File: [TOK, REM] = strtok (STR, DELIM)
+     Find all characters up to but not including the first character
+     which is in the string delim.  If REM is requested, it contains the
+     remainder of the string, starting at the first delimiter.  Leading
+     delimiters are ignored.  If DELIM is not specified, space is
+     assumed.  For example:
+
+          strtok ("this is the life")
+               => "this"
+
+          [tok, rem] = strtok ("14*27+31", "+-*/")
+               =>
+                  tok = 14
+                  rem = *27+31
+
+     *See also:* *note index: doc-index, *note strsplit: doc-strsplit.
+
+ -- Function File: [S] = strsplit (P, SEP, STRIP_EMPTY)
+     Split a single string using one or more delimiters and return a
+     cell array of strings.  Consecutive delimiters and delimiters at
+     boundaries result in empty strings, unless STRIP_EMPTY is true.
+     The default value of STRIP_EMPTY is false.
+
+     *See also:* *note strtok: doc-strtok.
+
+ -- Function File:  strrep (S, X, Y)
+     Replace all occurrences of the substring X of the string S with
+     the string Y and return the result.  For example,
+
+          strrep ("This is a test string", "is", "&%$")
+               => "Th&%$ &%$ a test string"
+
+     *See also:* *note regexprep: doc-regexprep, *note strfind:
+     doc-strfind, *note findstr: doc-findstr.
+
+ -- Function File:  substr (S, OFFSET, LEN)
+     Return the substring of S which starts at character number OFFSET
+     and is LEN characters long.
+
+     If OFFSET is negative, extraction starts that far from the end of
+     the string.  If LEN is omitted, the substring extends to the end
+     of S.
+
+     For example,
+
+          substr ("This is a test string", 6, 9)
+               => "is a test"
+
+     This function is patterned after AWK.  You can get the same result
+     by `S(OFFSET : (OFFSET + LEN - 1))'.
+
+ -- Loadable Function: [S, E, TE, M, T, NM] = regexp (STR, PAT)
+ -- Loadable Function: [...] = regexp (STR, PAT, OPTS, ...)
+     Regular expression string matching.  Matches PAT in STR and
+     returns the position and matching substrings or empty values if
+     there are none.
+
+     The matched pattern PAT can include any of the standard regex
+     operators, including:
+
+    `.'
+          Match any character
+
+    `* + ? {}'
+          Repetition operators, representing
+         `*'
+               Match zero or more times
+
+         `+'
+               Match one or more times
+
+         `?'
+               Match zero or one times
+
+         `{}'
+               Match range operator, which is of the form `{N}' to
+               match exactly N times, `{M,}' to match M or more times,
+               `{M,N}' to match between M and N times.
+
+    `[...] [^...]'
+          List operators, where for example `[ab]c' matches `ac' and
+          `bc'
+
+    `()'
+          Grouping operator
+
+    `|'
+          Alternation operator.  Match one of a choice of regular
+          expressions.  The alternatives must be delimited by the
+          grouping operator `()' above
+
+    `^ $'
+          Anchoring operator.  `^' matches the start of the string STR
+          and `$' the end
+
+     In addition the following escaped characters have special meaning.
+     It should be noted that it is recommended to quote PAT in single
+     quotes rather than double quotes, to avoid the escape sequences
+     being interpreted by Octave before being passed to `regexp'.
+
+    `\b'
+          Match a word boundary
+
+    `\B'
+          Match within a word
+
+    `\w'
+          Matches any word character
+
+    `\W'
+          Matches any non word character
+
+    `\<'
+          Matches the beginning of a word
+
+    `\>'
+          Matches the end of a word
+
+    `\s'
+          Matches any whitespace character
+
+    `\S'
+          Matches any non whitespace character
+
+    `\d'
+          Matches any digit
+
+    `\D'
+          Matches any non-digit
+
+     The outputs of `regexp' by default are in the order as given below
+
+    S
+          The start indices of each of the matching substrings
+
+    E
+          The end indices of each matching substring
+
+    TE
+          The extents of each of the matched token surrounded by
+          `(...)' in PAT.
+
+    M
+          A cell array of the text of each match.
+
+    T
+          A cell array of the text of each token matched.
+
+    NM
+          A structure containing the text of each matched named token,
+          with the name being used as the fieldname.  A named token is
+          denoted as `(?<name>...)'
+
+     Particular output arguments or the order of the output arguments
+     can be selected by additional OPTS arguments.  These are strings
+     and the correspondence between the output arguments and the
+     optional argument are
+
+                   'start'              S                    
+                   'end'                E                    
+                   'tokenExtents'       TE                   
+                   'match'              M                    
+                   'tokens'             T                    
+                   'names'              NM                   
+
+     A further optional argument is 'once', that limits the number of
+     returned matches to the first match.  Additional arguments are
+
+    matchcase
+          Make the matching case sensitive.
+
+    ignorecase
+          Make the matching case insensitive.
+
+    stringanchors
+          Match the anchor characters at the beginning and end of the
+          string.
+
+    lineanchors
+          Match the anchor characters at the beginning and end of the
+          line.
+
+    dotall
+          The character `.' matches the newline character.
+
+    dotexceptnewline
+          The character `.' matches all but the newline character.
+
+    freespacing
+          The pattern can include arbitrary whitespace and comments
+          starting with `#'.
+
+    literalspacing
+          The pattern is taken literally.
+
+     *See also:* *note regexpi: doc-regexpi, *note regexprep:
+     doc-regexprep.
+
+ -- Loadable Function: [S, E, TE, M, T, NM] = regexpi (STR, PAT)
+ -- Loadable Function: [...] = regexpi (STR, PAT, OPTS, ...)
+     Case insensitive regular expression string matching.  Matches PAT
+     in STR and returns the position and matching substrings or empty
+     values if there are none.  *Note regexp: doc-regexp, for more
+     details
+
+ -- Loadable Function: STRING = regexprep (STRING, PAT, REPSTR, OPTIONS)
+     Replace matches of PAT in  STRING with REPSTR.
+
+     The replacement can contain `$i', which substitutes for the ith
+     set of parentheses in the match string.  E.g.,
+
+             regexprep("Bill Dunn",'(\w+) (\w+)','$2, $1')
+     returns "Dunn, Bill"
+
+     OPTIONS may be zero or more of
+    `once'
+          Replace only the first occurrence of PAT in the result.
+
+    `warnings'
+          This option is present for compatibility but is ignored.
+
+    `ignorecase or matchcase'
+          Ignore case for the pattern matching (see `regexpi').
+          Alternatively, use (?i) or (?-i) in the pattern.
+
+    `lineanchors and stringanchors'
+          Whether characters ^ and $ match the beginning and ending of
+          lines.  Alternatively, use (?m) or (?-m) in the pattern.
+
+    `dotexceptnewline and dotall'
+          Whether . matches newlines in the string.  Alternatively, use
+          (?s) or (?-s) in the pattern.
+
+    `freespacing or literalspacing'
+          Whether whitespace and # comments can be used to make the
+          regular expression more readable.  Alternatively, use (?x) or
+          (?-x) in the pattern.
+
+
+     *See also:* *note regexp: doc-regexp, *note regexpi: doc-regexpi,
+     *note strrep: doc-strrep.
+
+ -- Function File:  regexptranslate (OP, S)
+     Translate a string for use in a regular expression.  This might
+     include either wildcard replacement or special character escaping.
+     The behavior can be controlled by the OP that can have the values
+
+    "wildcard"
+          The wildcard characters `.', `*' and `?' are replaced with
+          wildcards that are appropriate for a regular expression.  For
+          example:
+               regexptranslate ("wildcard", "*.m")
+                    => ".*\.m"
+
+    "escape"
+          The characters `$.?[]', that have special meaning for regular
+          expressions are escaped so that they are treated literally.
+          For example:
+               regexptranslate ("escape", "12.5")
+                    => "12\.5"
+
+     *See also:* *note regexp: doc-regexp, *note regexpi: doc-regexpi,
+     *note regexprep: doc-regexprep.
+
+
+File: octave.info,  Node: String Conversions,  Next: Character Class Functions,  Prev: Manipulating Strings,  Up: Strings
+
+5.6 String Conversions
+======================
+
+Octave supports various kinds of conversions between strings and
+numbers.  As an example, it is possible to convert a string containing
+a hexadecimal number to a floating point number.
+
+     hex2dec ("FF")
+          => ans = 255
+
+ -- Function File:  bin2dec (S)
+     Return the decimal number corresponding to the binary number stored
+     in the string S.  For example,
+
+          bin2dec ("1110")
+               => 14
+
+     If S is a string matrix, returns a column vector of converted
+     numbers, one per row of S.  Invalid rows evaluate to NaN.
+
+     *See also:* *note dec2hex: doc-dec2hex, *note base2dec:
+     doc-base2dec, *note dec2base: doc-dec2base, *note hex2dec:
+     doc-hex2dec, *note dec2bin: doc-dec2bin.
+
+ -- Function File:  dec2bin (N, LEN)
+     Return a binary number corresponding to the non-negative decimal
+     number N, as a string of ones and zeros.  For example,
+
+          dec2bin (14)
+               => "1110"
+
+     If N is a vector, returns a string matrix, one row per value,
+     padded with leading zeros to the width of the largest value.
+
+     The optional second argument, LEN, specifies the minimum number of
+     digits in the result.
+
+     *See also:* *note bin2dec: doc-bin2dec, *note dec2base:
+     doc-dec2base, *note base2dec: doc-base2dec, *note hex2dec:
+     doc-hex2dec, *note dec2hex: doc-dec2hex.
+
+ -- Function File:  dec2hex (N, LEN)
+     Return the hexadecimal string corresponding to the non-negative
+     integer N.  For example,
+
+          dec2hex (2748)
+               => "ABC"
+
+     If N is a vector, returns a string matrix, one row per value,
+     padded with leading zeros to the width of the largest value.
+
+     The optional second argument, LEN, specifies the minimum number of
+     digits in the result.
+
+     *See also:* *note hex2dec: doc-hex2dec, *note dec2base:
+     doc-dec2base, *note base2dec: doc-base2dec, *note bin2dec:
+     doc-bin2dec, *note dec2bin: doc-dec2bin.
+
+ -- Function File:  hex2dec (S)
+     Return the integer corresponding to the hexadecimal number stored
+     in the string S.  For example,
+
+          hex2dec ("12B")
+               => 299
+          hex2dec ("12b")
+               => 299
+
+     If S is a string matrix, returns a column vector of converted
+     numbers, one per row of S.  Invalid rows evaluate to NaN.
+
+     *See also:* *note dec2hex: doc-dec2hex, *note base2dec:
+     doc-base2dec, *note dec2base: doc-dec2base, *note bin2dec:
+     doc-bin2dec, *note dec2bin: doc-dec2bin.
+
+ -- Function File:  dec2base (N, B, LEN)
+     Return a string of symbols in base B corresponding to the
+     non-negative integer N.
+
+          dec2base (123, 3)
+               => "11120"
+
+     If N is a vector, return a string matrix with one row per value,
+     padded with leading zeros to the width of the largest value.
+
+     If B is a string then the characters of B are used as the symbols
+     for the digits of N.  Space (' ') may not be used as a symbol.
+
+          dec2base (123, "aei")
+               => "eeeia"
+
+     The optional third argument, LEN, specifies the minimum number of
+     digits in the result.
+
+     *See also:* *note base2dec: doc-base2dec, *note dec2bin:
+     doc-dec2bin, *note bin2dec: doc-bin2dec, *note hex2dec:
+     doc-hex2dec, *note dec2hex: doc-dec2hex.
+
+ -- Function File:  base2dec (S, B)
+     Convert S from a string of digits of base B into an integer.
+
+          base2dec ("11120", 3)
+               => 123
+
+     If S is a matrix, returns a column vector with one value per row
+     of S.  If a row contains invalid symbols then the corresponding
+     value will be NaN.  Rows are right-justified before converting so
+     that trailing spaces are ignored.
+
+     If B is a string, the characters of B are used as the symbols for
+     the digits of S.  Space (' ') may not be used as a symbol.
+
+          base2dec ("yyyzx", "xyz")
+               => 123
+
+     *See also:* *note dec2base: doc-dec2base, *note dec2bin:
+     doc-dec2bin, *note bin2dec: doc-bin2dec, *note hex2dec:
+     doc-hex2dec, *note dec2hex: doc-dec2hex.
+
+ -- Loadable Function: S = num2hex (N)
+     Typecast a double precision number or vector to a 16 character
+     hexadecimal string of the IEEE 754 representation of the number.
+     For example
+
+          num2hex ([-1, 1, e, Inf, NaN, NA]);
+          => "bff0000000000000
+              3ff0000000000000
+              4005bf0a8b145769
+              7ff0000000000000
+              fff8000000000000
+              7ff00000000007a2"
+
+     *See also:* *note hex2num: doc-hex2num, *note hex2dec:
+     doc-hex2dec, *note dec2hex: doc-dec2hex.
+
+ -- Loadable Function: N = hex2num (S)
+     Typecast the 16 character hexadecimal character matrix to an IEEE
+     754 double precision number.  If fewer than 16 characters are
+     given the strings are right padded with '0' characters.
+
+     Given a string matrix, `hex2num' treats each row as a separate
+     number.
+
+          hex2num (["4005bf0a8b145769";"4024000000000000"])
+          => [2.7183; 10.000]
+
+     *See also:* *note num2hex: doc-num2hex, *note hex2dec:
+     doc-hex2dec, *note dec2hex: doc-dec2hex.
+
+ -- Function File: [NUM, STATUS, STRARRAY] = str2double (STR, CDELIM,
+          RDELIM, DDELIM)
+     Convert strings into numeric values.
+
+     `str2double' can replace `str2num', but avoids the use of `eval'
+     on unknown data.
+
+     STR can be the form `[+-]d[.]dd[[eE][+-]ddd]' in which `d' can be
+     any of digit from 0 to 9, and `[]' indicate optional elements.
+
+     NUM is the corresponding numeric value.  If the conversion fails,
+     status is -1 and NUM is NaN.
+
+     STATUS is 0 if the conversion was successful and -1 otherwise.
+
+     STRARRAY is a cell array of strings.
+
+     Elements which are not defined or not valid return NaN and the
+     STATUS becomes -1.
+
+     If STR is a character array or a cell array of strings, then NUM
+     and STATUS return matrices of appropriate size.
+
+     STR can also contain multiple elements separated by row and column
+     delimiters (CDELIM and RDELIM).
+
+     The parameters CDELIM, RDELIM, and DDELIM are optional column,
+     row, and decimal delimiters.
+
+     The default row-delimiters are newline, carriage return and
+     semicolon (ASCII 10, 13 and 59).  The default column-delimiters
+     are tab, space and comma (ASCII 9, 32, and 44).  The default
+     decimal delimiter is `.' (ASCII 46).
+
+     CDELIM, RDELIM, and DDELIM must contain only nul, newline,
+     carriage return, semicolon, colon, slash, tab, space, comma, or
+     `()[]{}' (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40, 41, 44,
+     47, 58, 59, 91, 93, 123, 124, 125).
+
+     Examples:
+
+          str2double ("-.1e-5")
+          => -1.0000e-006
+
+          str2double (".314e1, 44.44e-1, .7; -1e+1")
+          =>
+             3.1400    4.4440    0.7000
+           -10.0000       NaN       NaN
+
+          line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+          [x, status] = str2double (line)
+          => x =
+              200   300   NaN  -Inf   NaN   NaN   999   NaN   NaN
+          => status =
+                0     0     0     0    -1    -1     0    -1     0
+
+     *See also:* *note str2num: doc-str2num.
+
+ -- Function File:  strjust (S, ["left"|"right"|"center"])
+     Shift the non-blank text of S to the left, right or center of the
+     string.  If S is a string array, justify each string in the array.
+     Null characters are replaced by blanks.  If no justification is
+     specified, then all rows are right-justified.  For example:
+
+          strjust (["a"; "ab"; "abc"; "abcd"])
+               => ans =
+                     a
+                    ab
+                   abc
+                  abcd
+
+ -- Function File:  str2num (S)
+     Convert the string (or character array) S to a number (or an
+     array).  Examples:
+
+          str2num("3.141596")
+               => 3.141596
+
+          str2num(["1, 2, 3"; "4, 5, 6"]);
+               => ans =
+                  1  2  3
+                  4  5  6
+
+     *Caution:* As `str2num' uses the `eval' function to do the
+     conversion, `str2num' will execute any code contained in the
+     string S.  Use `str2double' instead if you want to avoid the use
+     of `eval'.
+
+     *See also:* *note str2double: doc-str2double, *note eval: doc-eval.
+
+ -- Mapping Function:  toascii (S)
+     Return ASCII representation of S in a matrix.  For example,
+
+          toascii ("ASCII")
+               => [ 65, 83, 67, 73, 73 ]
+
+
+     *See also:* *note char: doc-char.
+
+ -- Mapping Function:  tolower (S)
+ -- Mapping Function:  lower (S)
+     Return a copy of the string or cell string S, with each upper-case
+     character replaced by the corresponding lower-case one;
+     non-alphabetic characters are left unchanged.  For example,
+
+          tolower ("MiXeD cAsE 123")
+               => "mixed case 123"
+
+     *See also:* *note toupper: doc-toupper.
+
+ -- Built-in Function:  toupper (S)
+ -- Built-in Function:  upper (S)
+     Return a copy of the string or cell string S, with each lower-case
+     character replaced by the corresponding upper-case one;
+     non-alphabetic characters are left unchanged.  For example,
+
+          toupper ("MiXeD cAsE 123")
+               => "MIXED CASE 123"
+
+     *See also:* *note tolower: doc-tolower.
+
+ -- Built-in Function:  do_string_escapes (STRING)
+     Convert special characters in STRING to their escaped forms.
+
+ -- Built-in Function:  undo_string_escapes (S)
+     Converts special characters in strings back to their escaped
+     forms.  For example, the expression
+
+          bell = "\a";
+
+     assigns the value of the alert character (control-g, ASCII code 7)
+     to the string variable `bell'.  If this string is printed, the
+     system will ring the terminal bell (if it is possible).  This is
+     normally the desired outcome.  However, sometimes it is useful to
+     be able to print the original representation of the string, with
+     the special characters replaced by their escape sequences.  For
+     example,
+
+          octave:13> undo_string_escapes (bell)
+          ans = \a
+
+     replaces the unprintable alert character with its printable
+     representation.
+
+
+File: octave.info,  Node: Character Class Functions,  Prev: String Conversions,  Up: Strings
+
+5.7 Character Class Functions
+=============================
+
+Octave also provides the following character class test functions
+patterned after the functions in the standard C library.  They all
+operate on string arrays and return matrices of zeros and ones.
+Elements that are nonzero indicate that the condition was true for the
+corresponding character in the string array.  For example,
+
+     isalpha ("!Q at WERT^Y&")
+          => [ 0, 1, 0, 1, 1, 1, 1, 0, 1, 0 ]
+
+ -- Mapping Function:  isalnum (S)
+     Return 1 for characters that are letters or digits (`isalpha (S)'
+     or `isdigit (S)' is true).
+
+ -- Mapping Function:  isalpha (S)
+ -- Mapping Function:  isletter (S)
+     Return true for characters that are letters (`isupper (S)' or
+     `islower (S)' is true).
+
+ -- Mapping Function:  isascii (S)
+     Return 1 for characters that are ASCII (in the range 0 to 127
+     decimal).
+
+ -- Mapping Function:  iscntrl (S)
+     Return 1 for control characters.
+
+ -- Mapping Function:  isdigit (S)
+     Return 1 for characters that are decimal digits.
+
+ -- Mapping Function:  isgraph (S)
+     Return 1 for printable characters (but not the space character).
+
+ -- Function File:  isletter (S)
+     Returns true if S is a letter, false otherwise.
+
+     *See also:* *note isalpha: doc-isalpha.
+
+ -- Mapping Function:  islower (S)
+     Return 1 for characters that are lower case letters.
+
+ -- Mapping Function:  isprint (S)
+     Return 1 for printable characters (including the space character).
+
+ -- Mapping Function:  ispunct (S)
+     Return 1 for punctuation characters.
+
+ -- Mapping Function:  isspace (S)
+     Return 1 for whitespace characters (space, formfeed, newline,
+     carriage return, tab, and vertical tab).
+
+ -- Mapping Function:  isupper (S)
+     Return 1 for upper case letters.
+
+ -- Mapping Function:  isxdigit (S)
+     Return 1 for characters that are hexadecimal digits.
+
+ -- Function File:  isstrprop (STR, PRED)
+     Test character string properties.  For example,
+
+          isstrprop ("abc123", "alpha")
+          => [1, 1, 1, 0, 0, 0]
+
+     If STR is a cell array, `isstrpop' is applied recursively to each
+     element of the cell array.
+
+     Numeric arrays are converted to character strings.
+
+     The second argument PRED may be one of
+
+    `"alpha"'
+          True for characters that are alphabetic
+
+    `"alnum"'
+    `"alphanum"'
+          True for characters that are alphabetic or digits.
+
+    `"ascii"'
+          True for characters that are in the range of ASCII encoding.
+
+    `"cntrl"'
+          True for control characters.
+
+    `"digit"'
+          True for decimal digits.
+
+    `"graph"'
+    `"graphic"'
+          True for printing characters except space.
+
+    `"lower"'
+          True for lower-case letters.
+
+    `"print"'
+          True for printing characters including space.
+
+    `"punct"'
+          True for printing characters except space or letter or digit.
+
+    `"space"'
+    `"wspace"'
+          True for whitespace characters (space, formfeed, newline,
+          carriage return, tab, vertical tab).
+
+    `"upper"'
+          True for upper-case letters.
+
+    `"xdigit"'
+          True for hexadecimal digits.
+
+     *See also:* *note isalnum: doc-isalnum, *note isalpha:
+     doc-isalpha, *note isascii: doc-isascii, *note iscntrl:
+     doc-iscntrl, *note isdigit: doc-isdigit, *note isgraph:
+     doc-isgraph, *note islower: doc-islower, *note isprint:
+     doc-isprint, *note ispunct: doc-ispunct, *note isspace:
+     doc-isspace, *note isupper: doc-isupper, *note isxdigit:
+     doc-isxdigit.
+
+
+File: octave.info,  Node: Data Containers,  Next: Variables,  Prev: Strings,  Up: Top
+
+6 Data Containers
+*****************
+
+Octave includes support for two different mechanisms to contain
+arbitrary data types in the same variable.  Structures, which are
+C-like, and are indexed with named fields, and cell arrays, where each
+element of the array can have a different data type and or shape.
+Multiple input arguments and return values of functions are organized as
+another data container, the comma separated list.
+
+* Menu:
+
+* Data Structures::
+* Cell Arrays::
+* Comma Separated Lists::
+
+
+File: octave.info,  Node: Data Structures,  Next: Cell Arrays,  Up: Data Containers
+
+6.1 Data Structures
+===================
+
+Octave includes support for organizing data in structures.  The current
+implementation uses an associative array with indices limited to
+strings, but the syntax is more like C-style structures.
+
+* Menu:
+
+* Basic Usage and Examples::
+* Structure Arrays::
+* Creating Structures::
+* Manipulating Structures::
+* Processing Data in Structures::
+
+
+File: octave.info,  Node: Basic Usage and Examples,  Next: Structure Arrays,  Up: Data Structures
+
+6.1.1 Basic Usage and Examples
+------------------------------
+
+Here are some examples of using data structures in Octave.
+
+   Elements of structures can be of any value type.  For example, the
+three expressions
+
+     x.a = 1;
+     x.b = [1, 2; 3, 4];
+     x.c = "string";
+
+create a structure with three elements.  To print the value of the
+structure, you can type its name, just as for any other variable:
+
+     x
+          => x =
+             {
+               a = 1
+               b =
+
+                 1  2
+                 3  4
+
+               c = string
+             }
+
+Note that Octave may print the elements in any order.
+
+   Structures may be copied just like any other variable:
+
+     y = x
+          => y =
+             {
+               a = 1
+               b =
+
+                 1  2
+                 3  4
+
+               c = string
+             }
+
+   Since structures are themselves values, structure elements may
+reference other structures.  The following statements change the value
+of the element `b' of the structure `x' to be a data structure
+containing the single element `d', which has a value of 3.
+
+     x.b.d = 3;
+     x.b
+          => ans =
+             {
+               d = 3
+             }
+
+     x
+          => x =
+             {
+               a = 1
+               b =
+               {
+                 d = 3
+               }
+
+               c = string
+             }
+
+   Note that when Octave prints the value of a structure that contains
+other structures, only a few levels are displayed.  For example,
+
+     a.b.c.d.e = 1;
+     a
+          => a =
+             {
+               b =
+               {
+                 c =
+                 {
+                   1x1 struct array containing the fields:
+
+                   d: 1x1 struct
+                 }
+               }
+             }
+
+This prevents long and confusing output from large deeply nested
+structures. The number of levels to print for nested structures can be
+set with the function `struct_levels_to_print':
+
+ -- Built-in Function: VAL = struct_levels_to_print ()
+ -- Built-in Function: OLD_VAL = struct_levels_to_print (NEW_VAL)
+     Query or set the internal variable that specifies the number of
+     structure levels to display.
+
+   Functions can return structures.  For example, the following function
+separates the real and complex parts of a matrix and stores them in two
+elements of the same structure variable.
+
+     function y = f (x)
+       y.re = real (x);
+       y.im = imag (x);
+     endfunction
+
+   When called with a complex-valued argument, `f' returns the data
+structure containing the real and imaginary parts of the original
+function argument.
+
+     f (rand (2) + rand (2) * I)
+          => ans =
+             {
+               im =
+
+                 0.26475  0.14828
+                 0.18436  0.83669
+
+               re =
+
+                 0.040239  0.242160
+                 0.238081  0.402523
+
+             }
+
+   Function return lists can include structure elements, and they may be
+indexed like any other variable.  For example,
+
+     [ x.u, x.s(2:3,2:3), x.v ] = svd ([1, 2; 3, 4]);
+     x
+          => x =
+             {
+               u =
+
+                 -0.40455  -0.91451
+                 -0.91451   0.40455
+
+               s =
+
+                  0.00000   0.00000   0.00000
+                  0.00000   5.46499   0.00000
+                  0.00000   0.00000   0.36597
+
+               v =
+
+                 -0.57605   0.81742
+                 -0.81742  -0.57605
+
+             }
+
+   It is also possible to cycle through all the elements of a structure
+in a loop, using a special form of the `for' statement (*note Looping
+Over Structure Elements::).
+
+
+File: octave.info,  Node: Structure Arrays,  Next: Creating Structures,  Prev: Basic Usage and Examples,  Up: Data Structures
+
+6.1.2 Structure Arrays
+----------------------
+
+A structure array is a particular instance of a structure, where each of
+the fields of the structure is represented by a cell array.  Each of
+these cell arrays has the same dimensions. Conceptually, a structure
+array can also be seen as an array of structures with identical fields.
+An example of the creation of a structure array is
+
+     x(1).a = "string1";
+     x(2).a = "string2";
+     x(1).b = 1;
+     x(2).b = 2;
+
+which creates a 2-by-1 structure array with two fields.  Another way to
+create a structure array is with the `struct' function (*note Creating
+Structures::).  As previously, to print the value of the structure
+array, you can type its name:
+
+     x
+          => x =
+             {
+               1x2 struct array containing the fields:
+
+                 a
+                 b
+             }
+
+   Individual elements of the structure array can be returned by
+indexing the variable like `X(1)', which returns a structure with two
+fields:
+
+     x(1)
+          => ans =
+             {
+               a = string1
+               b =  1
+             }
+
+   Furthermore, the structure array can return a comma separated list of
+field values (*note Comma Separated Lists::), if indexed by one of its
+own field names.  For example
+
+     x.a
+          =>
+             ans = string1
+             ans = string2
+
+   Here is another example, using this comma separated list on the
+left-hand side of an assignment:
+
+     [x.a] = deal("new string1", "new string2");
+      x(1).a
+          => ans = new string1
+      x(2).a
+          => ans = new string2
+
+   Just as for numerical arrays, it is possible to use vectors as
+indices (*note Index Expressions::):
+
+     x(3:4) = x(1:2);
+     [x([1,3]).a] = deal("other string1", "other string2");
+     x.a
+          =>
+             ans = other string1
+             ans = new string2
+             ans = other string2
+             ans = new string2
+
+   The function `size' will return the size of the structure.  For the
+example above
+
+     size(x)
+          => ans =
+
+               1   4
+
+   Elements can be deleted from a structure array in a similar manner
+to a numerical array, by assigning the elements to an empty matrix.  For
+example
+
+     in = struct ("call1", {x, Inf, "last"},
+                  "call2", {x, Inf, "first"})
+          => in =
+             {
+               1x3 struct array containing the fields:
+
+                 call1
+                 call2
+             }
+
+     in(1) = [];
+     in.call1
+          =>
+            ans = Inf
+            ans = last
+
+
+File: octave.info,  Node: Creating Structures,  Next: Manipulating Structures,  Prev: Structure Arrays,  Up: Data Structures
+
+6.1.3 Creating Structures
+-------------------------
+
+As well as indexing a structure with ".", Octave can create a structure
+with the `struct' command.  `struct' takes pairs of arguments, where
+the first argument in the pair is the fieldname to include in the
+structure and the second is a scalar or cell array, representing the
+values to include in the structure or structure array.  For example
+
+     struct ("field1", 1, "field2", 2)
+     => ans =
+           {
+             field1 =  1
+             field2 =  2
+           }
+
+   If the values passed to `struct' are a mix of scalar and cell
+arrays, then the scalar arguments are expanded to create a structure
+array with a consistent dimension.  For example
+
+     s = struct ("field1", {1, "one"}, "field2", {2, "two"},
+             "field3", 3);
+     s.field1
+          =>
+             ans =  1
+             ans = one
+
+     s.field2
+          =>
+             ans =  2
+             ans = two
+
+     s.field3
+          =>
+             ans =  3
+             ans =  3
+
+   If you want to create a struct which contains a cell array as an
+individual field, you have to put it into another cell array like in
+the following example:
+
+     struct ("field1", {{1, "one"}}, "field2", 2)
+          => ans =
+             {
+               field1 =
+
+             {
+               [1,1] =  1
+               [1,2] = one
+             }
+
+               field2 =  2
+             }
+
+ -- Built-in Function:  struct ("field", VALUE, "field", VALUE, ...)
+     Create a structure and initialize its value.
+
+     If the values are cell arrays, create a structure array and
+     initialize its values.  The dimensions of each cell array of
+     values must match.  Singleton cells and non-cell values are
+     repeated so that they fill the entire array.  If the cells are
+     empty, create an empty structure array with the specified field
+     names.
+
+     If the argument is an object, return the underlying struct.
+
+   The function `isstruct' can be used to test if an object is a
+structure or a structure array.
+
+ -- Built-in Function:  isstruct (EXPR)
+     Return 1 if the value of the expression EXPR is a structure.
+
+
+File: octave.info,  Node: Manipulating Structures,  Next: Processing Data in Structures,  Prev: Creating Structures,  Up: Data Structures
+
+6.1.4 Manipulating Structures
+-----------------------------
+
+Other functions that can manipulate the fields of a structure are given
+below.
+
+ -- Built-in Function:  rmfield (S, F)
+     Remove field F from the structure S.  If F is a cell array of
+     character strings or a character array, remove the named fields.
+
+     *See also:* *note cellstr: doc-cellstr, *note iscellstr:
+     doc-iscellstr, *note setfield: doc-setfield.
+
+ -- Function File: [K1, ..., V1] = setfield (S, K1, V1, ...)
+     Set field members in a structure.
+
+          oo(1,1).f0 = 1;
+          oo = setfield (oo, {1,2}, "fd", {3}, "b", 6);
+          oo(1,2).fd(3).b == 6
+          => ans = 1
+
+     Note that this function could be written
+
+          i1 = {1,2}; i2 = "fd"; i3 = {3}; i4 = "b";
+          oo(i1{:}).(i2)(i3{:}).(i4) == 6;
+
+     *See also:* *note getfield: doc-getfield, *note rmfield:
+     doc-rmfield, *note isfield: doc-isfield, *note isstruct:
+     doc-isstruct, *note fieldnames: doc-fieldnames, *note struct:
+     doc-struct.
+
+ -- Function File: [T, P] = orderfields (S1, S2)
+     Return a struct with fields arranged alphabetically or as specified
+     by S2 and a corresponding permutation vector.
+
+     Given one struct, arrange field names in S1 alphabetically.
+
+     Given two structs, arrange field names in S1 as they appear in S2.
+     The second argument may also specify the order in a permutation
+     vector or a cell array of strings.
+
+     *See also:* *note getfield: doc-getfield, *note rmfield:
+     doc-rmfield, *note isfield: doc-isfield, *note isstruct:
+     doc-isstruct, *note fieldnames: doc-fieldnames, *note struct:
+     doc-struct.
+
+ -- Built-in Function:  fieldnames (STRUCT)
+     Return a cell array of strings naming the elements of the structure
+     STRUCT.  It is an error to call `fieldnames' with an argument that
+     is not a structure.
+
+ -- Built-in Function:  isfield (EXPR, NAME)
+     Return true if the expression EXPR is a structure and it includes
+     an element named NAME.  The first argument must be a structure and
+     the second must be a string.
+
+ -- Function File: [V1, ...] = getfield (S, KEY, ...)
+     Extract fields from a structure.  For example
+
+          ss(1,2).fd(3).b = 5;
+          getfield (ss, {1,2}, "fd", {3}, "b")
+          => ans = 5
+
+     Note that the function call in the previous example is equivalent
+     to the expression
+
+          i1 = {1,2}; i2 = "fd"; i3 = {3}; i4= "b";
+          ss(i1{:}).(i2)(i3{:}).(i4)
+
+     *See also:* *note setfield: doc-setfield, *note rmfield:
+     doc-rmfield, *note isfield: doc-isfield, *note isstruct:
+     doc-isstruct, *note fieldnames: doc-fieldnames, *note struct:
+     doc-struct.
+
+ -- Function File:  substruct (TYPE, SUBS, ...)
+     Create a subscript structure for use with `subsref' or `subsasgn'.
+
+     *See also:* *note subsref: doc-subsref, *note subsasgn:
+     doc-subsasgn.
+
+
+File: octave.info,  Node: Processing Data in Structures,  Prev: Manipulating Structures,  Up: Data Structures
+
+6.1.5 Processing Data in Structures
+-----------------------------------
+
+The simplest way to process data in a structure is within a `for' loop
+(*note Looping Over Structure Elements::).  A similar effect can be
+achieved with the `structfun' function, where a user defined function
+is applied to each field of the structure.
+
+ -- Function File:  structfun (FUNC, S)
+ -- Function File: [A, B] = structfun (...)
+ -- Function File:  structfun (..., "ErrorHandler", ERRFUNC)
+ -- Function File:  structfun (..., "UniformOutput", VAL)
+     Evaluate the function named NAME on the fields of the structure S.
+     The fields of S are passed to the function FUNC individually.
+
+     `structfun' accepts an arbitrary function FUNC in the form of an
+     inline function, function handle, or the name of a function (in a
+     character string).  In the case of a character string argument, the
+     function must accept a single argument named X, and it must return
+     a string value.  If the function returns more than one argument,
+     they are returned as separate output variables.
+
+     If the parameter "UniformOutput" is set to true (the default),
+     then the function must return a single element which will be
+     concatenated into the return value.  If "UniformOutput" is false,
+     the outputs placed in a structure with the same fieldnames as the
+     input structure.
+
+          s.name1 = "John Smith";
+          s.name2 = "Jill Jones";
+          structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
+                     "UniformOutput", false)
+
+     Given the parameter "ErrorHandler", then ERRFUNC defines a
+     function to call in case FUNC generates an error.  The form of the
+     function is
+
+          function [...] = errfunc (SE, ...)
+
+     where there is an additional input argument to ERRFUNC relative to
+     FUNC, given by SE.  This is a structure with the elements
+     "identifier", "message" and "index", giving respectively the error
+     identifier, the error message, and the index into the input
+     arguments of the element that caused the error.
+
+     *See also:* *note cellfun: doc-cellfun, *note arrayfun:
+     doc-arrayfun.
+
+   Alternatively, to process the data in a structure, the structure
+might be converted to another type of container before being treated.
+
+ -- Built-in Function:  struct2cell (S)
+     Create a new cell array from the objects stored in the struct
+     object.  If F is the number of fields in the structure, the
+     resulting cell array will have a dimension vector corresponding to
+     `[F size(S)]'.
+
+     *See also:* *note cell2struct: doc-cell2struct, *note fieldnames:
+     doc-fieldnames.
+
+
+File: octave.info,  Node: Cell Arrays,  Next: Comma Separated Lists,  Prev: Data Structures,  Up: Data Containers
+
+6.2 Cell Arrays
+===============
+
+It can be both necessary and convenient to store several variables of
+different size or type in one variable.  A cell array is a container
+class able to do just that.  In general cell arrays work just like
+N-dimensional arrays with the exception of the use of `{' and `}' as
+allocation and indexing operators.
+
+* Menu:
+
+* Basic Usage of Cell Arrays::
+* Creating Cell Arrays::
+* Indexing Cell Arrays::
+* Cell Arrays of Strings::
+* Processing Data in Cell Arrays::
+
+
+File: octave.info,  Node: Basic Usage of Cell Arrays,  Next: Creating Cell Arrays,  Up: Cell Arrays
+
+6.2.1 Basic Usage of Cell Arrays
+--------------------------------
+
+As an example, the following code creates a cell array containing a
+string and a 2-by-2 random matrix
+
+     c = {"a string", rand(2, 2)};
+
+To access the elements of a cell array, it can be indexed with the {
+and } operators.  Thus, the variable created in the previous example
+can be indexed like this:
+
+     c{1}
+          => ans = a string
+
+As with numerical arrays several elements of a cell array can be
+extracted by indexing with a vector of indexes
+
+     c{1:2}
+          => ans =
+
+               (,
+                 [1] = a string
+                 [2] =
+
+                    0.593993   0.627732
+                    0.377037   0.033643
+
+               ,)
+
+   The indexing operators can also be used to insert or overwrite
+elements of a cell array.  The following code inserts the scalar 3 on
+the third place of the previously created cell array
+
+     c{3} = 3
+          => c =
+
+              {
+                [1,1] = a string
+                [1,2] =
+
+                   0.593993   0.627732
+                   0.377037   0.033643
+
+                [1,3] =  3
+              }
+
+   Details on indexing cell arrays are explained in *note Indexing Cell
+Arrays::.
+
+   In general nested cell arrays are displayed hierarchically as in the
+previous example.  In some circumstances it makes sense to reference
+them by their index, and this can be performed by the `celldisp'
+function.
+
+ -- Function File:  celldisp (C, NAME)
+     Recursively display the contents of a cell array.  By default the
+     values are displayed with the name of the variable C.  However,
+     this name can be replaced with the variable NAME.
+
+     *See also:* *note disp: doc-disp.
+
+   To test if an object is a cell array, use the `iscell' function. For
+example:
+
+     iscell(c)
+          => ans = 1
+
+     iscell(3)
+          => ans = 0
+
+ -- Built-in Function:  iscell (X)
+     Return true if X is a cell array object.  Otherwise, return false.
+
+
+File: octave.info,  Node: Creating Cell Arrays,  Next: Indexing Cell Arrays,  Prev: Basic Usage of Cell Arrays,  Up: Cell Arrays
+
+6.2.2 Creating Cell Array
+-------------------------
+
+The introductory example (*note Basic Usage of Cell Arrays::) showed
+how to create a cell array containing currently available variables.
+In many situations, however, it is useful to create a cell array and
+then fill it with data.
+
+   The `cell' function returns a cell array of a given size, containing
+empty matrices.  This function is similar to the `zeros' function for
+creating new numerical arrays.  The following example creates a 2-by-2
+cell array containing empty matrices
+
+     c = cell(2,2)
+          => c =
+
+              {
+                [1,1] = [](0x0)
+                [2,1] = [](0x0)
+                [1,2] = [](0x0)
+                [2,2] = [](0x0)
+              }
+
+   Just like numerical arrays, cell arrays can be multidimensional.  The
+`cell' function accepts any number of positive integers to describe the
+size of the returned cell array.  It is also possible to set the size
+of the cell array through a vector of positive integers.  In the
+following example two cell arrays of equal size are created, and the
+size of the first one is displayed
+
+     c1 = cell(3, 4, 5);
+     c2 = cell( [3, 4, 5] );
+     size(c1)
+          => ans =
+              3   4   5
+
+As can be seen, the *note `size': doc-size. function also works for
+cell arrays.  As do other functions describing the size of an object,
+such as *note `length': doc-length, *note `numel': doc-numel, *note
+`rows': doc-rows, and *note `columns': doc-columns.
+
+ -- Built-in Function:  cell (X)
+ -- Built-in Function:  cell (N, M)
+     Create a new cell array object.  If invoked with a single scalar
+     argument, `cell' returns a square cell array with the dimension
+     specified.  If you supply two scalar arguments, `cell' takes them
+     to be the number of rows and columns.  If given a vector with two
+     elements, `cell' uses the values of the elements as the number of
+     rows and columns, respectively.
+
+   As an alternative to creating empty cell arrays, and then filling
+them, it is possible to convert numerical arrays into cell arrays using
+the `num2cell' and `mat2cell' functions.
+
+ -- Loadable Function: C = num2cell (M)
+ -- Loadable Function: C = num2cell (M, DIM)
+     Convert the matrix M to a cell array.  If DIM is defined, the
+     value C is of dimension 1 in this dimension and the elements of M
+     are placed in slices in C.
+
+     *See also:* *note mat2cell: doc-mat2cell.
+
+ -- Loadable Function: B = mat2cell (A, M, N)
+ -- Loadable Function: B = mat2cell (A, D1, D2, ...)
+ -- Loadable Function: B = mat2cell (A, R)
+     Convert the matrix A to a cell array.  If A is 2-D, then it is
+     required that `sum (M) == size (A, 1)' and `sum (N) == size (A,
+     2)'.  Similarly, if A is a multi-dimensional and the number of
+     dimensional arguments is equal to the dimensions of A, then it is
+     required that `sum (DI) == size (A, i)'.
+
+     Given a single dimensional argument R, the other dimensional
+     arguments are assumed to equal `size (A,I)'.
+
+     An example of the use of mat2cell is
+
+          mat2cell (reshape(1:16,4,4),[3,1],[3,1])
+          => {
+            [1,1] =
+
+               1   5   9
+               2   6  10
+               3   7  11
+
+            [2,1] =
+
+               4   8  12
+
+            [1,2] =
+
+              13
+              14
+              15
+
+            [2,2] = 16
+          }
+
+     *See also:* *note num2cell: doc-num2cell, *note cell2mat:
+     doc-cell2mat.
+
+
+File: octave.info,  Node: Indexing Cell Arrays,  Next: Cell Arrays of Strings,  Prev: Creating Cell Arrays,  Up: Cell Arrays
+
+6.2.3 Indexing Cell Arrays
+--------------------------
+
+As shown in *note Basic Usage of Cell Arrays:: elements can be
+extracted from cell arrays using the `{' and `}' operators.  If you
+want to extract or access subarrays which are still cell arrays, you
+need to use the `(' and `)' operators. The following example
+illustrates the difference:
+
+     c = {"1", "2", "3"; "a", "b", "c"; "4", "5", "6"};
+     c{2,3}
+          => ans = c
+
+     c(2,3)
+          => ans =
+             {
+               [1,1] = c
+             }
+
+So with `{}' you access elements of a cell array, while with `()' you
+access a sub array of a cell array.
+
+   Using the `(' and `)' operators, indexing works for cell arrays like
+for multidimensional arrays.  As an example, all the rows of the first
+and third column of a cell array can be set to `0' with the following
+command:
+
+     c(:, [1, 3]) = {0}
+          =>  =
+             {
+               [1,1] = 0
+               [2,1] = 0
+               [3,1] = 0
+               [1,2] = 2
+               [2,2] =  10
+               [3,2] =  20
+               [1,3] = 0
+               [2,3] = 0
+               [3,3] = 0
+             }
+
+   Note, that the above can also be achieved like this:
+
+     c(:, [1, 3]) = 0;
+
+Here, the scalar `0' is automatically promoted to cell array `{0}' and
+then assigned to the subarray of `c'.
+
+   To give another example for indexing cell arrays with `()', you can
+exchange the first and the second row of a cell array as in the
+following command:
+
+     c = {1, 2, 3; 4, 5, 6};
+     c([1, 2], :) = c([2, 1], :)
+          => =
+             {
+               [1,1] =  4
+               [2,1] =  1
+               [1,2] =  5
+               [2,2] =  2
+               [1,3] =  6
+               [2,3] =  3
+             }
+
+   Accessing multiple elements of a cell array with the `{' and `}'
+operators will result in a comma-separated list of all the requested
+elements (*note Comma Separated Lists::). Using the `{' and `}'
+operators the first two rows in the above example can be swapped back
+like this:
+
+     [c{[1,2], :}] = deal(c{[2, 1], :})
+          => =
+             {
+               [1,1] =  1
+               [2,1] =  4
+               [1,2] =  2
+               [2,2] =  5
+               [1,3] =  3
+               [2,3] =  6
+             }
+
+   As for struct arrays and numerical arrays, the empty matrix `[]' can
+be used to delete elements from a cell array:
+
+     x = {"1", "2"; "3", "4"};
+     x(1, :) = []
+          => x =
+             {
+               [1,1] = 3
+               [1,2] = 4
+             }
+
+   The following example shows how to just remove the contents of cell
+array elements but not delete the space for them:
+
+     x = {"1", "2"; "3", "4"};
+     x{1, :} = []
+     => x =
+           {
+             [1,1] = [](0x0)
+             [2,1] = 3
+             [1,2] = [](0x0)
+             [2,2] = 4
+           }
+
+
+File: octave.info,  Node: Cell Arrays of Strings,  Next: Processing Data in Cell Arrays,  Prev: Indexing Cell Arrays,  Up: Cell Arrays
+
+6.2.4 Cell Arrays of Strings
+----------------------------
+
+One common use of cell arrays is to store multiple strings in the same
+variable.  It is also possible to store multiple strings in a character
+matrix by letting each row be a string.  This, however, introduces the
+problem that all strings must be of equal length.  Therefore, it is
+recommended to use cell arrays to store multiple strings.  For cases,
+where the character matrix representation is required for an operation,
+there are several functions that convert a cell array of strings to a
+character array and back.  `char' and `strvcat' convert cell arrays to
+a character array (*note Concatenating Strings::), while the function
+`cellstr' converts a character array to a cell array of strings:
+
+     a = ["hello"; "world"];
+     c = cellstr (a)
+          => c =
+              {
+                [1,1] = hello
+                [2,1] = world
+              }
+
+ -- Built-in Function:  cellstr (STRING)
+     Create a new cell array object from the elements of the string
+     array STRING.
+
+   One further advantage of using cell arrays to store multiple strings
+is that most functions for string manipulations included with Octave
+support this representation.  As an example, it is possible to compare
+one string with many others using the `strcmp' function.  If one of the
+arguments to this function is a string and the other is a cell array of
+strings, each element of the cell array will be compared to the string
+argument:
+
+     c = {"hello", "world"};
+     strcmp ("hello", c)
+          => ans =
+             1   0
+
+The following string functions support cell arrays of strings: `char',
+`strvcat', `strcat' (*note Concatenating Strings::), `strcmp',
+`strncmp', `strcmpi', `strncmpi' (*note Comparing Strings::),
+`str2double', `deblank', `strtrim', `strtrunc', `strfind', `strmatch',
+, `regexp', `regexpi' (*note Manipulating Strings::) and `str2double'
+(*note String Conversions::).
+
+   The function `iscellstr' can be used to test if an object is a cell
+array of strings.
+
+ -- Built-in Function:  iscellstr (CELL)
+     Return true if every element of the cell array CELL is a character
+     string
+
+ -- Function File: [IDXVEC, ERRMSG] = cellidx (LISTVAR, STRLIST)
+     Return indices of string entries in LISTVAR that match strings in
+     STRLIST.
+
+     Both LISTVAR and STRLIST may be passed as strings or string
+     matrices.  If they are passed as string matrices, each entry is
+     processed by `deblank' prior to searching for the entries.
+
+     The first output is the vector of indices in LISTVAR.
+
+     If STRLIST contains a string not in LISTVAR, then an error message
+     is returned in ERRMSG.  If only one output argument is requested,
+     then CELLIDX prints ERRMSG to the screen and exits with an error.
+
+
+File: octave.info,  Node: Processing Data in Cell Arrays,  Prev: Cell Arrays of Strings,  Up: Cell Arrays
+
+6.2.5 Processing Data in Cell Arrays
+------------------------------------
+
+Data that is stored in a cell array can be processed in several ways
+depending on the actual data.  The simplest way to process that data is
+to iterate through it using one or more `for' loops.  The same idea can
+be implemented more easily through the use of the `cellfun' function
+that calls a user-specified function on all elements of a cell array.
+
+ -- Loadable Function:  cellfun (NAME, C)
+ -- Loadable Function:  cellfun ("size", C, K)
+ -- Loadable Function:  cellfun ("isclass", C, CLASS)
+ -- Loadable Function:  cellfun (FUNC, C)
+ -- Loadable Function:  cellfun (FUNC, C, D)
+ -- Loadable Function: [A, B] = cellfun (...)
+ -- Loadable Function:  cellfun (..., 'ErrorHandler', ERRFUNC)
+ -- Loadable Function:  cellfun (..., 'UniformOutput', VAL)
+     Evaluate the function named NAME on the elements of the cell array
+     C.  Elements in C are passed on to the named function
+     individually.  The function NAME can be one of the functions
+
+    `isempty'
+          Return 1 for empty elements.
+
+    `islogical'
+          Return 1 for logical elements.
+
+    `isreal'
+          Return 1 for real elements.
+
+    `length'
+          Return a vector of the lengths of cell elements.
+
+    `ndims'
+          Return the number of dimensions of each element.
+
+    `prodofsize'
+          Return the product of dimensions of each element.
+
+    `size'
+          Return the size along the K-th dimension.
+
+    `isclass'
+          Return 1 for elements of CLASS.
+
+     Additionally, `cellfun' accepts an arbitrary function FUNC in the
+     form of an inline function, function handle, or the name of a
+     function (in a character string).  In the case of a character
+     string argument, the function must accept a single argument named
+     X, and it must return a string value.  The function can take one
+     or more arguments, with the inputs args given by C, D, etc.
+     Equally the function can return one or more output arguments.  For
+     example
+
+          cellfun (@atan2, {1, 0}, {0, 1})
+          =>ans = [1.57080   0.00000]
+
+     Note that the default output argument is an array of the same size
+     as the input arguments.
+
+     If the parameter 'UniformOutput' is set to true (the default),
+     then the function must return a single element which will be
+     concatenated into the return value.  If 'UniformOutput' is false,
+     the outputs are concatenated in a cell array.  For example
+
+          cellfun ("tolower(x)", {"Foo", "Bar", "FooBar"},
+                   "UniformOutput",false)
+          => ans = {"foo", "bar", "foobar"}
+
+     Given the parameter 'ErrorHandler', then ERRFUNC defines a
+     function to call in case FUNC generates an error.  The form of the
+     function is
+
+          function [...] = errfunc (S, ...)
+
+     where there is an additional input argument to ERRFUNC relative to
+     FUNC, given by S.  This is a structure with the elements
+     'identifier', 'message' and 'index', giving respectively the error
+     identifier, the error message, and the index into the input
+     arguments of the element that caused the error.  For example
+
+          function y = foo (s, x), y = NaN; endfunction
+          cellfun (@factorial, {-1,2},'ErrorHandler', at foo)
+          => ans = [NaN 2]
+
+     *See also:* *note isempty: doc-isempty, *note islogical:
+     doc-islogical, *note isreal: doc-isreal, *note length: doc-length,
+     *note ndims: doc-ndims, *note numel: doc-numel, *note size:
+     doc-size.
+
+   An alternative is to convert the data to a different container, such
+as a matrix or a data structure.  Depending on the data this is possible
+using the `cell2mat' and `cell2struct' functions.
+
+ -- Function File: M = cell2mat (C)
+     Convert the cell array C into a matrix by concatenating all
+     elements of C into a hyperrectangle.  Elements of C must be
+     numeric, logical or char, and `cat' must be able to concatenate
+     them together.
+
+     *See also:* *note mat2cell: doc-mat2cell, *note num2cell:
+     doc-num2cell.
+
+ -- Built-in Function:  cell2struct (CELL, FIELDS, DIM)
+     Convert CELL to a structure.  The number of fields in FIELDS must
+     match the number of elements in CELL along dimension DIM, that is
+     `numel (FIELDS) == size (CELL, DIM)'.
+
+          A = cell2struct ({'Peter', 'Hannah', 'Robert';
+                             185, 170, 168},
+                           {'Name','Height'}, 1);
+          A(1)
+          => ans =
+                {
+                  Height = 185
+                  Name   = Peter
+                }
+
+
+File: octave.info,  Node: Comma Separated Lists,  Prev: Cell Arrays,  Up: Data Containers
+
+6.3 Comma Separated Lists
+=========================
+
+Comma separated lists (1) are the basic argument type to all Octave
+functions - both for input and return arguments.  In the example
+
+     max (A, B)
+
+`A, B' is a comma separated list.  Comma separated lists can appear on
+both the right and left hand side of an assignment.  For example
+
+     x = [1 0 1 0 0 1 1; 0 0 0 0 0 0 7];
+     [I, J] = find (X, 2, "last");
+
+Here, `X, 2, "last"' is a comma separated list constituting the input
+arguments of `find'.  `find' returns a comma separated list of output
+arguments which is assigned element by element to the comma separated
+list `I, J'.
+
+   Another example of where comma separated lists are used is in the
+creation of a new array with `[]' (*note Matrices::) or the creation of
+a cell array with `{}' (*note Basic Usage of Cell Arrays::). In the
+expressions
+
+     a = [1, 2, 3, 4];
+     c = {4, 5, 6, 7};
+
+both `1, 2, 3, 4' and `4, 5, 6, 7' are comma separated lists.
+
+   Comma separated lists cannot be directly manipulated by the user.
+However, both structure arrays and cell arrays can be converted into
+comma separated lists, and thus used in place of explicitly written
+comma separated lists.  This feature is useful in many ways, as will be
+shown in the following subsections.
+
+* Menu:
+
+* Comma Separated Lists Generated from Cell Arrays::
+* Comma Separated Lists Generated from Structure Arrays::
+
+   ---------- Footnotes ----------
+
+   (1) Comma-separated lists are also sometimes informally referred to
+as "cs-lists".
+
+
+File: octave.info,  Node: Comma Separated Lists Generated from Cell Arrays,  Next: Comma Separated Lists Generated from Structure Arrays,  Up: Comma Separated Lists
+
+6.3.1 Comma Separated Lists Generated from Cell Arrays
+------------------------------------------------------
+
+As has been mentioned above (*note Indexing Cell Arrays::), elements of
+a cell array can be extracted into a comma separated list with the `{'
+and `}' operators. By surrounding this list with `[' and `]', it can be
+concatenated into an array. For example:
+
+     a = {1, [2, 3], 4, 5, 6};
+     b = [a{1:4}]
+          => b =
+              1   2   3   4
+
+   Similarly, it is possible to create a new cell array containing cell
+elements selected with `{}'.  By surrounding the list with `{' and `}'
+a new cell array will be created, as the following example illustrates:
+
+     a = {1, rand(2, 2), "three"};
+     b = { a{ [1, 3] } }
+          => b =
+              {
+                [1,1] =  1
+                [1,2] = three
+              }
+
+   Furthermore, cell elements (accessed by `{}') can be passed directly
+to a function.  The list of elements from the cell array will be passed
+as an argument list to a given function as if it is called with the
+elements as individual arguments.  The two calls to `printf' in the
+following example are identical but the latter is simpler and can
+handle cell arrays of an arbitrary size:
+
+     c = {"GNU", "Octave", "is", "Free", "Software"};
+     printf ("%s ", c{1}, c{2}, c{3}, c{4}, c{5});
+          -| GNU Octave is Free Software
+     printf ("%s ", c{:});
+          -| GNU Octave is Free Software
+
+   If used on the left-hand side of an assignment, a comma separated
+list generated with `{}' can be assigned to.  An example is
+
+     in{1} = [10, 20, 30, 40, 50, 60, 70, 80, 90];
+     in{2} = inf;
+     in{3} = "last";
+     in{4} = "first";
+     out = cell (4, 1);
+     [out{1:3}] = find (in{1 : 3});
+     [out{4:6}] = find (in{[1, 2, 4]})
+          => out =
+             {
+               [1,1] = 1
+               [2,1] = 9
+               [3,1] = 90
+               [4,1] = 1
+               [3,1] = 1
+               [4,1] = 10
+             }
+
+
+File: octave.info,  Node: Comma Separated Lists Generated from Structure Arrays,  Prev: Comma Separated Lists Generated from Cell Arrays,  Up: Comma Separated Lists
+
+6.3.2 Comma Separated Lists Generated from Structure Arrays
+-----------------------------------------------------------
+
+Structure arrays can equally be used to create comma separated lists.
+This is done by addressing one of the fields of a structure array.  For
+example
+
+     x = ceil (randn (10, 1));
+     in = struct ("call1", {x, 3, "last"},
+                  "call2", {x, inf, "first"});
+     out = struct ("call1", cell (2, 1), "call2", cell (2, 1));
+     [out.call1] = find (in.call1);
+     [out.call2] = find (in.call2);
+
+
+File: octave.info,  Node: Variables,  Next: Expressions,  Prev: Data Containers,  Up: Top
+
+7 Variables
+***********
+
+Variables let you give names to values and refer to them later.  You
+have already seen variables in many of the examples.  The name of a
+variable must be a sequence of letters, digits and underscores, but it
+may not begin with a digit.  Octave does not enforce a limit on the
+length of variable names, but it is seldom useful to have variables
+with names longer than about 30 characters.  The following are all
+valid variable names
+
+     x
+     x15
+     __foo_bar_baz__
+     fucnrdthsucngtagdjb
+
+However, names like `__foo_bar_baz__' that begin and end with two
+underscores are understood to be reserved for internal use by Octave.
+You should not use them in code you write, except to access Octave's
+documented internal variables and built-in symbolic constants.
+
+   Case is significant in variable names.  The symbols `a' and `A' are
+distinct variables.
+
+   A variable name is a valid expression by itself.  It represents the
+variable's current value.  Variables are given new values with
+"assignment operators" and "increment operators".  *Note Assignment
+Expressions: Assignment Ops.
+
+   There is one built-in variable with a special meaning.  The `ans'
+variable always contains the result of the last computation, where the
+output wasn't assigned to any variable.  The code `a = cos (pi)' will
+assign the value -1 to the variable `a', but will not change the value
+of `ans'.  However, the code `cos (pi)' will set the value of `ans' to
+-1.
+
+   Variables in Octave do not have fixed types, so it is possible to
+first store a numeric value in a variable and then to later use the
+same name to hold a string value in the same program.  Variables may
+not be used before they have been given a value.  Doing so results in
+an error.
+
+ -- Automatic Variable: ans
+     The most recently computed result that was not explicitly assigned
+     to a variable.  For example, after the expression
+
+          3^2 + 4^2
+
+     is evaluated, the value returned by `ans' is 25.
+
+ -- Built-in Function:  isvarname (NAME)
+     Return true if NAME is a valid variable name
+
+ -- Function File: VARNAME = genvarname (STR)
+ -- Function File: VARNAME = genvarname (STR, EXCLUSIONS)
+     Create unique variable(s) from STR.  If EXCLUSIONS is given, then
+     the variable(s) will be unique to each other and to EXCLUSIONS
+     (EXCLUSIONS may be either a string or a cellstr).
+
+     If STR is a cellstr, then a unique variable is created for each
+     cell in STR.
+
+          x = 3.141;
+          genvarname ("x", who ())
+          => x1
+
+     If WANTED is a cell array, genvarname will make sure the returned
+     strings are distinct:
+
+          genvarname ({"foo", "foo"})
+          =>
+          {
+            [1,1] = foo
+            [1,2] = foo1
+          }
+
+     Note that the result is a char array/cell array of strings, not the
+     variables themselves.  To define a variable, `eval()' can be used.
+     The following trivial example sets `x' to `42'.
+
+          name = genvarname ("x");
+          eval([name " = 42"]);
+          => x =  42
+
+     Also, this can be useful for creating unique struct field names.
+
+          x = struct ();
+          for i = 1:3
+            x.(genvarname ("a", fieldnames (x))) = i;
+          endfor
+          =>
+          x =
+          {
+            a =  1
+            a1 =  2
+            a2 =  3
+          }
+
+     Since variable names may only contain letters, digits and
+     underscores, genvarname replaces any sequence of disallowed
+     characters with an underscore.  Also, variables may not begin with
+     a digit; in this case an underscore is added before the variable
+     name.
+
+     Variable names beginning and ending with two underscores "__" are
+     valid but they are used internally by octave and should generally
+     be avoided, therefore genvarname will not generate such names.
+
+     genvarname will also make sure that returned names do not clash
+     with keywords such as "for" and "if".  A number will be appended
+     if necessary.  Note, however, that this does *not* include
+     function names, such as "sin".  Such names should be included in
+     AVOID if necessary.
+
+     *See also:* *note isvarname: doc-isvarname, *note exist:
+     doc-exist, *note tmpnam: doc-tmpnam, *note eval: doc-eval.
+
+ -- Function File:  namelengthmax ()
+     Returns the MATLAB compatible maximum variable name length.
+     Octave is capable of storing strings up to `2 ^ 31 - 1' in length.
+     However for MATLAB compatibility all variable, function and
+     structure field names should be shorter than the length supplied by
+     `namelengthmax'.  In particular variables stored to a MATLAB file
+     format will have their names truncated to this length.
+
+* Menu:
+
+* Global Variables::
+* Persistent Variables::
+* Status of Variables::
+
+
+File: octave.info,  Node: Global Variables,  Next: Persistent Variables,  Up: Variables
+
+7.1 Global Variables
+====================
+
+A variable that has been declared "global" may be accessed from within
+a function body without having to pass it as a formal parameter.
+
+   A variable may be declared global using a `global' declaration
+statement.  The following statements are all global declarations.
+
+     global a
+     global a b
+     global c = 2
+     global d = 3 e f = 5
+
+   A global variable may only be initialized once in a `global'
+statement.  For example, after executing the following code
+
+     global gvar = 1
+     global gvar = 2
+
+the value of the global variable `gvar' is 1, not 2.  Issuing a `clear
+gvar' command does not change the above behavior, but `clear all' does.
+
+   It is necessary declare a variable as global within a function body
+in order to access it.  For example,
+
+     global x
+     function f ()
+       x = 1;
+     endfunction
+     f ()
+
+does _not_ set the value of the global variable `x' to 1.  In order to
+change the value of the global variable `x', you must also declare it
+to be global within the function body, like this
+
+     function f ()
+       global x;
+       x = 1;
+     endfunction
+
+   Passing a global variable in a function parameter list will make a
+local copy and not modify the global value.  For example, given the
+function
+
+     function f (x)
+       x = 0
+     endfunction
+
+and the definition of `x' as a global variable at the top level,
+
+     global x = 13
+
+the expression
+
+     f (x)
+
+will display the value of `x' from inside the function as 0, but the
+value of `x' at the top level remains unchanged, because the function
+works with a _copy_ of its argument.
+
+ -- Built-in Function:  isglobal (NAME)
+     Return 1 if NAME is globally visible.  Otherwise, return 0.  For
+     example,
+
+          global x
+          isglobal ("x")
+               => 1
+
+
+File: octave.info,  Node: Persistent Variables,  Next: Status of Variables,  Prev: Global Variables,  Up: Variables
+
+7.2 Persistent Variables
+========================
+
+A variable that has been declared "persistent" within a function will
+retain its contents in memory between subsequent calls to the same
+function.  The difference between persistent variables and global
+variables is that persistent variables are local in scope to a
+particular function and are not visible elsewhere.
+
+   The following example uses a persistent variable to create a function
+that prints the number of times it has been called.
+
+     function count_calls ()
+       persistent calls = 0;
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+
+     for i = 1:3
+       count_calls ();
+     endfor
+
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+     -| 'count_calls' has been called 3 times
+
+   As the example shows, a variable may be declared persistent using a
+`persistent' declaration statement.  The following statements are all
+persistent declarations.
+
+     persistent a
+     persistent a b
+     persistent c = 2
+     persistent d = 3 e f = 5
+
+   The behavior of persistent variables is equivalent to the behavior of
+static variables in C.  The command `static' in Octave is also
+recognized and is equivalent to `persistent'.
+
+   Like global variables, a persistent variable may only be initialized
+once.  For example, after executing the following code
+
+     persistent pvar = 1
+     persistent pvar = 2
+
+the value of the persistent variable `pvar' is 1, not 2.
+
+   If a persistent variable is declared but not initialized to a
+specific value, it will contain an empty matrix.  So, it is also
+possible to initialize a persistent variable by checking whether it is
+empty, as the following example illustrates.
+
+     function count_calls ()
+       persistent calls;
+       if (isempty (calls))
+         calls = 0;
+       endif
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+
+This implementation behaves in exactly the same way as the previous
+implementation of `count_calls'.
+
+   The value of a persistent variable is kept in memory until it is
+explicitly cleared.  Assuming that the implementation of `count_calls'
+is saved on disk, we get the following behavior.
+
+     for i = 1:2
+       count_calls ();
+     endfor
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+
+     clear
+     for i = 1:2
+       count_calls();
+     endfor
+     -| 'count_calls' has been called 3 times
+     -| 'count_calls' has been called 4 times
+
+     clear all
+     for i = 1:2
+       count_calls();
+     endfor
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+
+     clear count_calls
+     for i = 1:2
+       count_calls();
+     endfor
+     -| 'count_calls' has been called 1 times
+     -| 'count_calls' has been called 2 times
+
+That is, the persistent variable is only removed from memory when the
+function containing the variable is removed.  Note that if the function
+definition is typed directly into the Octave prompt, the persistent
+variable will be cleared by a simple `clear' command as the entire
+function definition will be removed from memory.  If you do not want a
+persistent variable to be removed from memory even if the function is
+cleared, you should use the `mlock' function as described in *Note
+Function Locking::.
+
+
+File: octave.info,  Node: Status of Variables,  Prev: Persistent Variables,  Up: Variables
+
+7.3 Status of Variables
+=======================
+
+When creating simple one-shot programs it can be very convenient to see
+which variables are available at the prompt.  The function `who' and
+its siblings `whos' and `whos_line_format' will show different
+information about what is in memory, as the following shows.
+
+     str = "A random string";
+     who -variables
+          -| *** local user variables:
+          -|
+          -| __nargin__  str
+
+ -- Command: who
+ -- Command: who pattern ...
+ -- Command: who option pattern ...
+ -- Command: C = who("pattern", ...)
+     List currently defined variables matching the given patterns.
+     Valid pattern syntax is the same as described for the `clear'
+     command.  If no patterns are supplied, all variables are listed.
+     By default, only variables visible in the local scope are
+     displayed.
+
+     The following are valid options but may not be combined.
+
+    `global'
+          List variables in the global scope rather than the current
+          scope.
+
+    `-regexp'
+          The patterns are considered to be regular expressions when
+          matching the variables to display.  The same pattern syntax
+          accepted by the `regexp' function is used.
+
+    `-file'
+          The next argument is treated as a filename.  All variables
+          found within the specified file are listed.  No patterns are
+          accepted when reading variables from a file.
+
+     If called as a function, return a cell array of defined variable
+     names matching the given patterns.
+
+     *See also:* *note whos: doc-whos, *note regexp: doc-regexp.
+
+ -- Command: whos
+ -- Command: whos pattern ...
+ -- Command: whos option pattern ...
+ -- Command: S = whos("pattern", ...)
+     Provide detailed information on currently defined variables
+     matching the given patterns.  Options and pattern syntax are the
+     same as for the `who' command.  Extended information about each
+     variable is summarized in a table with the following default
+     entries.
+
+    Attr
+          Attributes of the listed variable.  Possible attributes are:
+         blank
+               Variable in local scope
+
+         `g'
+               Variable with global scope
+
+         `p'
+               Persistent variable
+
+    Name
+          The name of the variable.
+
+    Size
+          The logical size of the variable.  A scalar is 1x1, a vector
+          is 1xN or Nx1, a 2-D matrix is MxN.
+
+    Bytes
+          The amount of memory currently used to store the variable.
+
+    Class
+          The class of the variable.  Examples include double, single,
+          char, uint16, cell, and struct.
+
+     The table can be customized to display more or less information
+     through the function `whos_line_format'.
+
+     If `whos' is called as a function, return a struct array of defined
+     variable names matching the given patterns.  Fields in the
+     structure describing each variable are: name, size, bytes, class,
+     global, sparse, complex, nesting, persistent.
+
+     *See also:* *note who: doc-who, *note whos_line_format:
+     doc-whos_line_format.
+
+ -- Built-in Function: VAL = whos_line_format ()
+ -- Built-in Function: OLD_VAL = whos_line_format (NEW_VAL)
+     Query or set the format string used by the command `whos'.
+
+     A full format string is:
+
+          %[modifier]<command>[:width[:left-min[:balance]]];
+
+     The following command sequences are available:
+
+    `%a'
+          Prints attributes of variables (g=global, p=persistent,
+          f=formal parameter, a=automatic variable).
+
+    `%b'
+          Prints number of bytes occupied by variables.
+
+    `%c'
+          Prints class names of variables.
+
+    `%e'
+          Prints elements held by variables.
+
+    `%n'
+          Prints variable names.
+
+    `%s'
+          Prints dimensions of variables.
+
+    `%t'
+          Prints type names of variables.
+
+     Every command may also have an alignment modifier:
+
+    `l'
+          Left alignment.
+
+    `r'
+          Right alignment (default).
+
+    `c'
+          Column-aligned (only applicable to command %s).
+
+     The `width' parameter is a positive integer specifying the minimum
+     number of columns used for printing.  No maximum is needed as the
+     field will auto-expand as required.
+
+     The parameters `left-min' and `balance' are only available when the
+     column-aligned modifier is used with the command `%s'.  `balance'
+     specifies the column number within the field width which will be
+     aligned between entries.  Numbering starts from 0 which indicates
+     the leftmost column.  `left-min' specifies the minimum field width
+     to the left of the specified balance column.
+
+     The default format is `"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;
+     %lc:-1;\n"'.
+
+     *See also:* *note whos: doc-whos.
+
+   Instead of displaying which variables are in memory, it is possible
+to determine if a given variable is available.  That way it is possible
+to alter the behavior of a program depending on the existence of a
+variable.  The following example illustrates this.
+
+     if (! exist ("meaning", "var"))
+       disp ("The program has no 'meaning'");
+     endif
+
+ -- Built-in Function:  exist (NAME, TYPE)
+     Return 1 if the name exists as a variable, 2 if the name is an
+     absolute file name, an ordinary file in Octave's `path', or (after
+     appending `.m') a function file in Octave's `path', 3 if the name
+     is a `.oct' or `.mex' file in Octave's `path', 5 if the name is a
+     built-in function, 7 if the name is a directory, or 103 if the
+     name is a function not associated with a file (entered on the
+     command line).
+
+     Otherwise, return 0.
+
+     This function also returns 2 if a regular file called NAME exists
+     in Octave's search path.  If you want information about other
+     types of files, you should use some combination of the functions
+     `file_in_path' and `stat' instead.
+
+     If the optional argument TYPE is supplied, check only for symbols
+     of the specified type.  Valid types are
+
+    `"var"'
+          Check only for variables.
+
+    `"builtin"'
+          Check only for built-in functions.
+
+    `"file"'
+          Check only for files.
+
+    `"dir"'
+          Check only for directories.
+
+   Usually Octave will manage the memory, but sometimes it can be
+practical to remove variables from memory manually.  This is usually
+needed when working with large variables that fill a substantial part
+of the memory.  On a computer that uses the IEEE floating point format,
+the following program allocates a matrix that requires around 128 MB
+memory.
+
+     large_matrix = zeros (4000, 4000);
+
+Since having this variable in memory might slow down other computations,
+it can be necessary to remove it manually from memory.  The `clear'
+function allows this.
+
+ -- Command: clear [options] pattern ...
+     Delete the names matching the given patterns from the symbol
+     table.  The pattern may contain the following special characters:
+
+    `?'
+          Match any single character.
+
+    `*'
+          Match zero or more characters.
+
+    `[ LIST ]'
+          Match the list of characters specified by LIST.  If the first
+          character is `!' or `^', match all characters except those
+          specified by LIST.  For example, the pattern `[a-zA-Z]' will
+          match all lower and upper case alphabetic characters.
+
+     For example, the command
+
+          clear foo b*r
+
+     clears the name `foo' and all names that begin with the letter `b'
+     and end with the letter `r'.
+
+     If `clear' is called without any arguments, all user-defined
+     variables (local and global) are cleared from the symbol table.  If
+     `clear' is called with at least one argument, only the visible
+     names matching the arguments are cleared.  For example, suppose
+     you have defined a function `foo', and then hidden it by
+     performing the assignment `foo = 2'.  Executing the command `clear
+     foo' once will clear the variable definition and restore the
+     definition of `foo' as a function.  Executing `clear foo' a second
+     time will clear the function definition.
+
+     The following options are available in both long and short form
+    `-all, -a'
+          Clears all local and global user-defined variables and all
+          functions from the symbol table.
+
+    `-exclusive, -x'
+          Clears the variables that don't match the following pattern.
+
+    `-functions, -f'
+          Clears the function names and the built-in symbols names.
+
+    `-global, -g'
+          Clears the global symbol names.
+
+    `-variables, -v'
+          Clears the local variable names.
+
+    `-classes, -c'
+          Clears the class structure table and clears all objects.
+
+    `-regexp, -r'
+          The arguments are treated as regular expressions as any
+          variables that match will be cleared.
+     With the exception of `exclusive', all long options can be used
+     without the dash as well.
+
+   Information about a function or variable such as its location in the
+file system can also be acquired from within Octave.  This is usually
+only useful during development of programs, and not within a program.
+
+ -- Command: type options name ...
+     Display the definition of each NAME that refers to a function.
+
+     Normally also displays whether each NAME is user-defined or
+     built-in; the `-q' option suppresses this behavior.
+
+     If an output argument is requested nothing is displayed.  Instead,
+     a cell array of strings is returned, where each element
+     corresponds to the definition of each requested function.
+
+ -- Command: which name ...
+     Display the type of each NAME.  If NAME is defined from a function
+     file, the full name of the file is also displayed.
+
+     *See also:* *note help: doc-help, *note lookfor: doc-lookfor.
+
+ -- Command:  what
+ -- Command:  what DIR
+ -- Function File: w = what (DIR)
+     List the Octave specific files in a directory.  If the variable DIR
+     is given then check that directory rather than the current
+     directory.  If a return argument is requested, the files found are
+     returned in the structure W.
+
+     *See also:* *note which: doc-which.
+
+
+File: octave.info,  Node: Expressions,  Next: Evaluation,  Prev: Variables,  Up: Top
+
+8 Expressions
+*************
+
+Expressions are the basic building block of statements in Octave.  An
+expression evaluates to a value, which you can print, test, store in a
+variable, pass to a function, or assign a new value to a variable with
+an assignment operator.
+
+   An expression can serve as a statement on its own.  Most other kinds
+of statements contain one or more expressions which specify data to be
+operated on.  As in other languages, expressions in Octave include
+variables, array references, constants, and function calls, as well as
+combinations of these with various operators.
+
+* Menu:
+
+* Index Expressions::
+* Calling Functions::
+* Arithmetic Ops::
+* Comparison Ops::
+* Boolean Expressions::
+* Assignment Ops::
+* Increment Ops::
+* Operator Precedence::
+
+
+File: octave.info,  Node: Index Expressions,  Next: Calling Functions,  Up: Expressions
+
+8.1 Index Expressions
+=====================
+
+An "index expression" allows you to reference or extract selected
+elements of a matrix or vector.
+
+   Indices may be scalars, vectors, ranges, or the special operator
+`:', which may be used to select entire rows or columns.
+
+   Vectors are indexed using a single index expression.  Matrices may be
+indexed using one or two indices.  When using a single index
+expression, the elements of the matrix are taken in column-first order;
+the dimensions of the output match those of the index expression.  For
+example,
+     a (2)       # a scalar
+     a (1:2)     # a row vector
+     a ([1; 2])  # a column vector
+
+   As a special case, when a colon is used as a single index, the output
+is a column vector containing all the elements of the vector or matrix.
+For example
+     a (:)       # a column vector
+
+   Given the matrix
+
+     a = [1, 2; 3, 4]
+
+all of the following expressions are equivalent
+
+     a (1, [1, 2])
+     a (1, 1:2)
+     a (1, :)
+
+and select the first row of the matrix.
+
+   In general, an array with `n' dimensions can be indexed using `m'
+indices.  If `n == m', each index corresponds to its respective
+dimension.  The set of index tuples determining the result is formed by
+the Cartesian product of the index vectors (or ranges or scalars).  If
+`n < m', then the array is padded by trailing singleton dimensions.  If
+`n > m', the last `n-m+1' dimensions are folded into a single dimension
+with extent equal to product of extents of the original dimensions.
+
+   Indexing a scalar with a vector of ones can be used to create a
+vector the same size as the index vector, with each element equal to
+the value of the original scalar.  For example, the following statements
+
+     a = 13;
+     a (ones (1, 4))
+
+produce a vector whose four elements are all equal to 13.
+
+   Similarly, indexing a scalar with two vectors of ones can be used to
+create a matrix.  For example the following statements
+
+     a = 13;
+     a (ones (1, 2), ones (1, 3))
+
+create a 2 by 3 matrix with all elements equal to 13.
+
+   The last example could also be written as
+
+     13 (ones (2, 3))
+
+   It should be, noted that `ones (1, n)' (a row vector of ones)
+results in a range (with zero increment), and is therefore more
+efficient when used in index expression than other forms of "ones".  In
+particular, when `r' is a row vector, the expressions
+
+       r(ones (1, n), :)
+
+       r(ones (n, 1), :)
+
+   will produce identical results, but the first one will be
+significantly faster, at least for `r' and `n' large enough.  The
+reason is that in the first case the index is kept in a compressed
+form, which allows Octave to choose a more efficient algorithm to
+handle the expression.
+
+   In general, for an user unaware of these subtleties, it is best to
+use the function "repmat" for spreading arrays into bigger ones.
+
+   It is also possible to create a matrix with different values.  The
+following example creates a 10 dimensional row vector a containing the
+values a(i) = sqrt(i).
+
+     for i = 1:10
+       a(i) = sqrt (i);
+     endfor
+
+Note that it is quite inefficient to create a vector using a loop like
+the one shown in the example above.  In this particular case, it would
+have been much more efficient to use the expression
+
+     a = sqrt (1:10);
+
+thus avoiding the loop entirely.  In cases where a loop is still
+required, or a number of values must be combined to form a larger
+matrix, it is generally much faster to set the size of the matrix first,
+and then insert elements using indexing commands.  For example, given a
+matrix `a',
+
+     [nr, nc] = size (a);
+     x = zeros (nr, n * nc);
+     for i = 1:n
+       x(:,(i-1)*nc+1:i*nc) = a;
+     endfor
+
+is considerably faster than
+
+     x = a;
+     for i = 1:n-1
+       x = [x, a];
+     endfor
+
+particularly for large matrices because Octave does not have to
+repeatedly resize the result.
+
+ -- Function File: IND = sub2ind (DIMS, I, J)
+ -- Function File: IND = sub2ind (DIMS, S1, S2, ..., SN)
+     Convert subscripts into a linear index.
+
+     The following example shows how to convert the two-dimensional
+     index `(2,3)' of a 3-by-3 matrix to a linear index.  The matrix is
+     linearly indexed moving from one column to next, filling up all
+     rows in each column.
+
+          linear_index = sub2ind ([3, 3], 2, 3)
+          => 8
+
+     *See also:* *note ind2sub: doc-ind2sub.
+
+ -- Function File: [S1, S2, ..., SN] = ind2sub (DIMS, IND)
+     Convert a linear index into subscripts.
+
+     The following example shows how to convert the linear index `8' in
+     a 3-by-3 matrix into a subscript.  The matrix is linearly indexed
+     moving from one column to next, filling up all rows in each column.
+          [r, c] = ind2sub ([3, 3], 8)
+          => r =  2
+          c =  3
+
+     *See also:* *note sub2ind: doc-sub2ind.
+
+
+File: octave.info,  Node: Calling Functions,  Next: Arithmetic Ops,  Prev: Index Expressions,  Up: Expressions
+
+8.2 Calling Functions
+=====================
+
+A "function" is a name for a particular calculation.  Because it has a
+name, you can ask for it by name at any point in the program.  For
+example, the function `sqrt' computes the square root of a number.
+
+   A fixed set of functions are "built-in", which means they are
+available in every Octave program.  The `sqrt' function is one of
+these.  In addition, you can define your own functions.  *Note
+Functions and Scripts::, for information about how to do this.
+
+   The way to use a function is with a "function call" expression,
+which consists of the function name followed by a list of "arguments"
+in parentheses.  The arguments are expressions which give the raw
+materials for the calculation that the function will do.  When there is
+more than one argument, they are separated by commas.  If there are no
+arguments, you can omit the parentheses, but it is a good idea to
+include them anyway, to clearly indicate that a function call was
+intended.  Here are some examples:
+
+     sqrt (x^2 + y^2)      # One argument
+     ones (n, m)           # Two arguments
+     rand ()               # No arguments
+
+   Each function expects a particular number of arguments.  For
+example, the `sqrt' function must be called with a single argument, the
+number to take the square root of:
+
+     sqrt (ARGUMENT)
+
+   Some of the built-in functions take a variable number of arguments,
+depending on the particular usage, and their behavior is different
+depending on the number of arguments supplied.
+
+   Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it.  In this
+example, the value of `sqrt (ARGUMENT)' is the square root of the
+argument.  A function can also have side effects, such as assigning the
+values of certain variables or doing input or output operations.
+
+   Unlike most languages, functions in Octave may return multiple
+values.  For example, the following statement
+
+     [u, s, v] = svd (a)
+
+computes the singular value decomposition of the matrix `a' and assigns
+the three result matrices to `u', `s', and `v'.
+
+   The left side of a multiple assignment expression is itself a list of
+expressions, and is allowed to be a list of variable names or index
+expressions.  See also *note Index Expressions::, and *note Assignment
+Ops::.
+
+* Menu:
+
+* Call by Value::
+* Recursion::
+
+
+File: octave.info,  Node: Call by Value,  Next: Recursion,  Up: Calling Functions
+
+8.2.1 Call by Value
+-------------------
+
+In Octave, unlike Fortran, function arguments are passed by value, which
+means that each argument in a function call is evaluated and assigned to
+a temporary location in memory before being passed to the function.
+There is currently no way to specify that a function parameter should be
+passed by reference instead of by value.  This means that it is
+impossible to directly alter the value of a function parameter in the
+calling function.  It can only change the local copy within the function
+body.  For example, the function
+
+     function f (x, n)
+       while (n-- > 0)
+         disp (x);
+       endwhile
+     endfunction
+
+displays the value of the first argument N times.  In this function,
+the variable N is used as a temporary variable without having to worry
+that its value might also change in the calling function.  Call by
+value is also useful because it is always possible to pass constants
+for any function parameter without first having to determine that the
+function will not attempt to modify the parameter.
+
+   The caller may use a variable as the expression for the argument, but
+the called function does not know this: it only knows what value the
+argument had.  For example, given a function called as
+
+     foo = "bar";
+     fcn (foo)
+
+you should not think of the argument as being "the variable `foo'."
+Instead, think of the argument as the string value, `"bar"'.
+
+   Even though Octave uses pass-by-value semantics for function
+arguments, values are not copied unnecessarily.  For example,
+
+     x = rand (1000);
+     f (x);
+
+does not actually force two 1000 by 1000 element matrices to exist
+_unless_ the function `f' modifies the value of its argument.  Then
+Octave must create a copy to avoid changing the value outside the scope
+of the function `f', or attempting (and probably failing!) to modify
+the value of a constant or the value of a temporary result.
+
+
+File: octave.info,  Node: Recursion,  Prev: Call by Value,  Up: Calling Functions
+
+8.2.2 Recursion
+---------------
+
+With some restrictions(1), recursive function calls are allowed.  A
+"recursive function" is one which calls itself, either directly or
+indirectly.  For example, here is an inefficient(2) way to compute the
+factorial of a given integer:
+
+     function retval = fact (n)
+       if (n > 0)
+         retval = n * fact (n-1);
+       else
+         retval = 1;
+       endif
+     endfunction
+
+   This function is recursive because it calls itself directly.  It
+eventually terminates because each time it calls itself, it uses an
+argument that is one less than was used for the previous call.  Once the
+argument is no longer greater than zero, it does not call itself, and
+the recursion ends.
+
+   The built-in variable `max_recursion_depth' specifies a limit to the
+recursion depth and prevents Octave from recursing infinitely.
+
+ -- Built-in Function: VAL = max_recursion_depth ()
+ -- Built-in Function: OLD_VAL = max_recursion_depth (NEW_VAL)
+     Query or set the internal limit on the number of times a function
+     may be called recursively.  If the limit is exceeded, an error
+     message is printed and control returns to the top level.
+
+   ---------- Footnotes ----------
+
+   (1) Some of Octave's functions are implemented in terms of functions
+that cannot be called recursively.  For example, the ODE solver `lsode'
+is ultimately implemented in a Fortran subroutine that cannot be called
+recursively, so `lsode' should not be called either directly or
+indirectly from within the user-supplied function that `lsode'
+requires.  Doing so will result in an error.
+
+   (2) It would be much better to use `prod (1:n)', or `gamma (n+1)'
+instead, after first checking to ensure that the value `n' is actually a
+positive integer.
+
+
+File: octave.info,  Node: Arithmetic Ops,  Next: Comparison Ops,  Prev: Calling Functions,  Up: Expressions
+
+8.3 Arithmetic Operators
+========================
+
+The following arithmetic operators are available, and work on scalars
+and matrices.
+
+`X + Y'
+     Addition.  If both operands are matrices, the number of rows and
+     columns must both agree.  If one operand is a scalar, its value is
+     added to all the elements of the other operand.
+
+`X .+ Y'
+     Element by element addition.  This operator is equivalent to `+'.
+
+`X - Y'
+     Subtraction.  If both operands are matrices, the number of rows and
+     columns of both must agree.
+
+`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 system is not square, or if the coefficient matrix is
+     singular, a minimum norm solution is computed.
+
+`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 system is not square, or if the coefficient matrix is
+     singular, a minimum norm solution is computed.
+
+`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.  If X is a scalar and Y is a
+     square matrix, the result is computed using an eigenvalue
+     expansion.  If X is a square matrix, the result is computed by
+     repeated multiplication if Y is an integer, and by an eigenvalue
+     expansion if Y is not an integer.  An error results if both X and
+     Y are matrices.
+
+     The implementation of this operator needs to be improved.
+
+`X .^ Y'
+
+`X .** Y'
+     Element by element power operator.  If both operands are matrices,
+     the number of rows and columns must both agree.
+
+`-X'
+     Negation.
+
+`+X'
+     Unary plus.  This operator has no effect on the operand.
+
+`X''
+     Complex conjugate transpose.  For real arguments, this operator is
+     the same as the transpose operator.  For complex arguments, this
+     operator is equivalent to the expression
+
+          conj (x.')
+
+`X.''
+     Transpose.
+
+   Note that because Octave's element by element operators begin with a
+`.', there is a possible ambiguity for statements like
+
+     1./m
+
+because the period could be interpreted either as part of the constant
+or as part of the operator.  To resolve this conflict, Octave treats the
+expression as if you had typed
+
+     (1) ./ m
+
+and not
+
+     (1.) / m
+
+Although this is inconsistent with the normal behavior of Octave's
+lexer, which usually prefers to break the input into tokens by
+preferring the longest possible match at any given point, it is more
+useful in this case.
+
+
+File: octave.info,  Node: Comparison Ops,  Next: Boolean Expressions,  Prev: Arithmetic Ops,  Up: Expressions
+
+8.4 Comparison Operators
+========================
+
+"Comparison operators" compare numeric values for relationships such as
+equality.  They are written using _relational operators_.
+
+   All of Octave's comparison operators return a value of 1 if the
+comparison is true, or 0 if it is false.  For matrix values, they all
+work on an element-by-element basis.  For example,
+
+     [1, 2; 3, 4] == [1, 3; 2, 4]
+          =>  1  0
+              0  1
+
+   If one operand is a scalar and the other is a matrix, the scalar is
+compared to each element of the matrix in turn, and the result is the
+same size as the matrix.
+
+`X < Y'
+     True if X is less than Y.
+
+`X <= Y'
+     True if X is less than or equal to Y.
+
+`X == Y'
+     True if X is equal to Y.
+
+`X >= Y'
+     True if X is greater than or equal to Y.
+
+`X > Y'
+     True if X is greater than Y.
+
+`X != Y'
+`X ~= Y'
+     True if X is not equal to Y.
+
+   String comparisons may also be performed with the `strcmp' function,
+not with the comparison operators listed above.  *Note Strings::.
+
+ -- Function File:  isequal (X1, X2, ...)
+     Return true if all of X1, X2, ... are equal.
+
+     *See also:* *note isequalwithequalnans: doc-isequalwithequalnans.
+
+ -- Function File:  isequalwithequalnans (X1, X2, ...)
+     Assuming NaN == NaN, return true if all of X1, X2, ...  are equal.
+
+     *See also:* *note isequal: doc-isequal.
+
+
+File: octave.info,  Node: Boolean Expressions,  Next: Assignment Ops,  Prev: Comparison Ops,  Up: Expressions
+
+8.5 Boolean Expressions
+=======================
+
+* Menu:
+
+* Element-by-element Boolean Operators::
+* Short-circuit Boolean Operators::
+
+
+File: octave.info,  Node: Element-by-element Boolean Operators,  Next: Short-circuit Boolean Operators,  Up: Boolean Expressions
+
+8.5.1 Element-by-element Boolean Operators
+------------------------------------------
+
+An "element-by-element boolean expression" is a combination of
+comparison expressions using the boolean operators "or" (`|'), "and"
+(`&'), and "not" (`!'), along with parentheses to control nesting.  The
+truth of the boolean expression is computed by combining the truth
+values of the corresponding elements of the component expressions.  A
+value is considered to be false if it is zero, and true otherwise.
+
+   Element-by-element boolean expressions can be used wherever
+comparison expressions can be used.  They can be used in `if' and
+`while' statements.  However, a matrix value used as the condition in an
+`if' or `while' statement is only true if _all_ of its elements are
+nonzero.
+
+   Like comparison operations, each element of an element-by-element
+boolean expression also has a numeric value (1 if true, 0 if false) that
+comes into play if the result of the boolean expression is stored in a
+variable, or used in arithmetic.
+
+   Here are descriptions of the three element-by-element boolean
+operators.
+
+`BOOLEAN1 & BOOLEAN2'
+     Elements of the result are true if both corresponding elements of
+     BOOLEAN1 and BOOLEAN2 are true.
+
+`BOOLEAN1 | BOOLEAN2'
+     Elements of the result are true if either of the corresponding
+     elements of BOOLEAN1 or BOOLEAN2 is true.
+
+`! BOOLEAN'
+`~ BOOLEAN'
+     Each element of the result is true if the corresponding element of
+     BOOLEAN is false.
+
+   For matrix operands, these operators work on an element-by-element
+basis.  For example, the expression
+
+     [1, 0; 0, 1] & [1, 0; 2, 3]
+
+returns a two by two identity matrix.
+
+   For the binary operators, the dimensions of the operands must
+conform if both are matrices.  If one of the operands is a scalar and
+the other a matrix, the operator is applied to the scalar and each
+element of the matrix.
+
+   For the binary element-by-element boolean operators, both
+subexpressions BOOLEAN1 and BOOLEAN2 are evaluated before computing the
+result.  This can make a difference when the expressions have side
+effects.  For example, in the expression
+
+     a & b++
+
+the value of the variable B is incremented even if the variable A is
+zero.
+
+   This behavior is necessary for the boolean operators to work as
+described for matrix-valued operands.
+
+
+File: octave.info,  Node: Short-circuit Boolean Operators,  Prev: Element-by-element Boolean Operators,  Up: Boolean Expressions
+
+8.5.2 Short-circuit Boolean Operators
+-------------------------------------
+
+Combined with the implicit conversion to scalar values in `if' and
+`while' conditions, Octave's element-by-element boolean operators are
+often sufficient for performing most logical operations.  However, it
+is sometimes desirable to stop evaluating a boolean expression as soon
+as the overall truth value can be determined.  Octave's "short-circuit"
+boolean operators work this way.
+
+`BOOLEAN1 && BOOLEAN2'
+     The expression BOOLEAN1 is evaluated and converted to a scalar
+     using the equivalent of the operation `all (BOOLEAN1(:))'.  If it
+     is false, the result of the overall expression is 0.  If it is
+     true, the expression BOOLEAN2 is evaluated and converted to a
+     scalar using the equivalent of the operation `all (BOOLEAN1(:))'.
+     If it is true, the result of the overall expression is 1.
+     Otherwise, the result of the overall expression is 0.
+
+     *Warning:* there is one exception to the rule of evaluating `all
+     (BOOLEAN1(:))', which is when `boolean1' is the empty matrix.  The
+     truth value of an empty matrix is always `false' so `[] && true'
+     evaluates to `false' even though `all ([])' is `true'.
+
+`BOOLEAN1 || BOOLEAN2'
+     The expression BOOLEAN1 is evaluated and converted to a scalar
+     using the equivalent of the operation `all (BOOLEAN1(:))'.  If it
+     is true, the result of the overall expression is 1.  If it is
+     false, the expression BOOLEAN2 is evaluated and converted to a
+     scalar using the equivalent of the operation `all (BOOLEAN1(:))'.
+     If it is true, the result of the overall expression is 1.
+     Otherwise, the result of the overall expression is 0.
+
+     *Warning:* the truth value of an empty matrix is always `false',
+     see the previous list item for details.
+
+   The fact that both operands may not be evaluated before determining
+the overall truth value of the expression can be important.  For
+example, in the expression
+
+     a && b++
+
+the value of the variable B is only incremented if the variable A is
+nonzero.
+
+   This can be used to write somewhat more concise code.  For example,
+it is possible write
+
+     function f (a, b, c)
+       if (nargin > 2 && ischar (c))
+         ...
+
+instead of having to use two `if' statements to avoid attempting to
+evaluate an argument that doesn't exist.  For example, without the
+short-circuit feature, it would be necessary to write
+
+     function f (a, b, c)
+       if (nargin > 2)
+         if (ischar (c))
+           ...
+
+Writing
+
+     function f (a, b, c)
+       if (nargin > 2 & ischar (c))
+         ...
+
+would result in an error if `f' were called with one or two arguments
+because Octave would be forced to try to evaluate both of the operands
+for the operator `&'.
+
+
+File: octave.info,  Node: Assignment Ops,  Next: Increment Ops,  Prev: Boolean Expressions,  Up: Expressions
+
+8.6 Assignment Expressions
+==========================
+
+An "assignment" is an expression that stores a new value into a
+variable.  For example, the following expression assigns the value 1 to
+the variable `z':
+
+     z = 1
+
+After this expression is executed, the variable `z' has the value 1.
+Whatever old value `z' had before the assignment is forgotten.  The `='
+sign is called an "assignment operator".
+
+   Assignments can store string values also.  For example, the following
+expression would store the value `"this food is good"' in the variable
+`message':
+
+     thing = "food"
+     predicate = "good"
+     message = [ "this " , thing , " is " , predicate ]
+
+(This also illustrates concatenation of strings.)
+
+   Most operators (addition, concatenation, and so on) have no effect
+except to compute a value.  If you ignore the value, you might as well
+not use the operator.  An assignment operator is different.  It does
+produce a value, but even if you ignore the value, the assignment still
+makes itself felt through the alteration of the variable.  We call this
+a "side effect".
+
+   The left-hand operand of an assignment need not be a variable (*note
+Variables::).  It can also be an element of a matrix (*note Index
+Expressions::) or a list of return values (*note Calling Functions::).
+These are all called "lvalues", which means they can appear on the
+left-hand side of an assignment operator.  The right-hand operand may
+be any expression.  It produces the new value which the assignment
+stores in the specified variable, matrix element, or list of return
+values.
+
+   It is important to note that variables do _not_ have permanent types.
+The type of a variable is simply the type of whatever value it happens
+to hold at the moment.  In the following program fragment, the variable
+`foo' has a numeric value at first, and a string value later on:
+
+     octave:13> foo = 1
+     foo = 1
+     octave:13> foo = "bar"
+     foo = bar
+
+When the second assignment gives `foo' a string value, the fact that it
+previously had a numeric value is forgotten.
+
+   Assignment of a scalar to an indexed matrix sets all of the elements
+that are referenced by the indices to the scalar value.  For example, if
+`a' is a matrix with at least two columns,
+
+     a(:, 2) = 5
+
+sets all the elements in the second column of `a' to 5.
+
+   Assigning an empty matrix `[]' works in most cases to allow you to
+delete rows or columns of matrices and vectors.  *Note Empty Matrices::.
+For example, given a 4 by 5 matrix A, the assignment
+
+     A (3, :) = []
+
+deletes the third row of A, and the assignment
+
+     A (:, 1:2:5) = []
+
+deletes the first, third, and fifth columns.
+
+   An assignment is an expression, so it has a value.  Thus, `z = 1' as
+an expression has the value 1.  One consequence of this is that you can
+write multiple assignments together:
+
+     x = y = z = 0
+
+stores the value 0 in all three variables.  It does this because the
+value of `z = 0', which is 0, is stored into `y', and then the value of
+`y = z = 0', which is 0, is stored into `x'.
+
+   This is also true of assignments to lists of values, so the
+following is a valid expression
+
+     [a, b, c] = [u, s, v] = svd (a)
+
+that is exactly equivalent to
+
+     [u, s, v] = svd (a)
+     a = u
+     b = s
+     c = v
+
+   In expressions like this, the number of values in each part of the
+expression need not match.  For example, the expression
+
+     [a, b] = [u, s, v] = svd (a)
+
+is equivalent to
+
+     [u, s, v] = svd (a)
+     a = u
+     b = s
+
+The number of values on the left side of the expression can, however,
+not exceed the number of values on the right side.  For example, the
+following will produce an error.
+
+     [a, b, c, d] = [u, s, v] = svd (a);
+     -| error: element number 4 undefined in return list
+
+   A very common programming pattern is to increment an existing
+variable with a given value, like this
+
+     a = a + 2;
+
+This can be written in a clearer and more condensed form using the `+='
+operator
+
+     a += 2;
+
+Similar operators also exist for subtraction (`-='), multiplication
+(`*='), and division (`/=').  An expression of the form
+
+     EXPR1 OP= EXPR2
+
+is evaluated as
+
+     EXPR1 = (EXPR1) OP (EXPR2)
+
+where OP can be either `+', `-', `*', or `/'.  So, the expression
+
+     a *= b+1
+
+is evaluated as
+
+     a = a * (b+1)
+
+and _not_
+
+     a = a * b + 1
+
+   You can use an assignment anywhere an expression is called for.  For
+example, it is valid to write `x != (y = 1)' to set `y' to 1 and then
+test whether `x' equals 1.  But this style tends to make programs hard
+to read.  Except in a one-shot program, you should rewrite it to get
+rid of such nesting of assignments.  This is never very hard.
+
+
+File: octave.info,  Node: Increment Ops,  Next: Operator Precedence,  Prev: Assignment Ops,  Up: Expressions
+
+8.7 Increment Operators
+=======================
+
+_Increment operators_ increase or decrease the value of a variable by
+1.  The operator to increment a variable is written as `++'.  It may be
+used to increment a variable either before or after taking its value.
+
+   For example, to pre-increment the variable X, you would write `++X'.
+This would add one to X and then return the new value of X as the
+result of the expression.  It is exactly the same as the expression `X
+= X + 1'.
+
+   To post-increment a variable X, you would write `X++'.  This adds
+one to the variable X, but returns the value that X had prior to
+incrementing it.  For example, if X is equal to 2, the result of the
+expression `X++' is 2, and the new value of X is 3.
+
+   For matrix and vector arguments, the increment and decrement
+operators work on each element of the operand.
+
+   Here is a list of all the increment and decrement expressions.
+
+`++X'
+     This expression increments the variable X.  The value of the
+     expression is the _new_ value of X.  It is equivalent to the
+     expression `X = X + 1'.
+
+`--X'
+     This expression decrements the variable X.  The value of the
+     expression is the _new_ value of X.  It is equivalent to the
+     expression `X = X - 1'.
+
+`X++'
+     This expression causes the variable X to be incremented.  The
+     value of the expression is the _old_ value of X.
+
+`X--'
+     This expression causes the variable X to be decremented.  The
+     value of the expression is the _old_ value of X.
+
+
+File: octave.info,  Node: Operator Precedence,  Prev: Increment Ops,  Up: Expressions
+
+8.8 Operator Precedence
+=======================
+
+"Operator precedence" determines how operators are grouped, when
+different operators appear close by in one expression.  For example,
+`*' has higher precedence than `+'.  Thus, the expression `a + b * c'
+means to multiply `b' and `c', and then add `a' to the product (i.e.,
+`a + (b * c)').
+
+   You can overrule the precedence of the operators by using
+parentheses.  You can think of the precedence rules as saying where the
+parentheses are assumed if you do not write parentheses yourself.  In
+fact, it is wise to use parentheses whenever you have an unusual
+combination of operators, because other people who read the program may
+not remember what the precedence is in this case.  You might forget as
+well, and then you too could make a mistake.  Explicit parentheses will
+help prevent any such mistake.
+
+   When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment and exponentiation
+operators, which group in the opposite order.  Thus, the expression `a
+- b + c' groups as `(a - b) + c', but the expression `a = b = c' groups
+as `a = (b = c)'.
+
+   The precedence of prefix unary operators is important when another
+operator follows the operand.  For example, `-x^2' means `-(x^2)',
+because `-' has lower precedence than `^'.
+
+   Here is a table of the operators in Octave, in order of increasing
+precedence.
+
+`statement separators'
+     `;', `,'.
+
+`assignment'
+     `=', `+=', `-=', `*=',`/='.  This operator groups right to left.
+
+`logical "or" and "and"'
+     `||', `&&'.
+
+`element-wise "or" and "and"'
+     `|', `&'.
+
+`relational'
+     `<', `<=', `==', `>=', `>', `!=', `~='.
+
+`colon'
+     `:'.
+
+`add, subtract'
+     `+', `-'.
+
+`multiply, divide'
+     `*', `/', `\', `.\', `.*', `./'.
+
+`transpose'
+     `'', `.''
+
+`unary plus, minus, increment, decrement, and ``not'''
+     `+', `-', `++', `--', `!', `~'.
+
+`exponentiation'
+     `^', `**', `.^', `.**'.
+
+
+File: octave.info,  Node: Evaluation,  Next: Statements,  Prev: Expressions,  Up: Top
+
+9 Evaluation
+************
+
+Normally, you evaluate expressions simply by typing them at the Octave
+prompt, or by asking Octave to interpret commands that you have saved in
+a file.
+
+   Sometimes, you may find it necessary to evaluate an expression that
+has been computed and stored in a string, which is exactly what the
+`eval' function lets you do.
+
+ -- Built-in Function:  eval (TRY, CATCH)
+     Parse the string TRY and evaluate it as if it were an Octave
+     program.  If that fails, evaluate the optional string CATCH.  The
+     string TRY is evaluated in the current context, so any results
+     remain available after `eval' returns.
+
+     The following example makes the variable A with the approximate
+     value 3.1416 available.
+
+          eval("a = acos(-1);");
+
+     If an error occurs during the evaluation of TRY the CATCH string
+     is evaluated, as the following example shows:
+
+          eval ('error ("This is a bad example");',
+                'printf ("This error occurred:\n%s\n", lasterr ());');
+               -| This error occurred:
+                  This is a bad example
+
+* Menu:
+
+* Calling a Function by its Name::
+* Evaluation in a Different Context::
+
+
+File: octave.info,  Node: Calling a Function by its Name,  Next: Evaluation in a Different Context,  Up: Evaluation
+
+9.1 Calling a Function by its Name
+==================================
+
+The `feval' function allows you to call a function from a string
+containing its name.  This is useful when writing a function that needs
+to call user-supplied functions.  The `feval' function takes the name
+of the function to call as its first argument, and the remaining
+arguments are given to the function.
+
+   The following example is a simple-minded function using `feval' that
+finds the root of a user-supplied function of one variable using
+Newton's method.
+
+     function result = newtroot (fname, x)
+
+     # usage: newtroot (fname, x)
+     #
+     #   fname : a string naming a function f(x).
+     #   x     : initial guess
+
+       delta = tol = sqrt (eps);
+       maxit = 200;
+       fx = feval (fname, x);
+       for i = 1:maxit
+         if (abs (fx) < tol)
+           result = x;
+           return;
+         else
+           fx_new = feval (fname, x + delta);
+           deriv = (fx_new - fx) / delta;
+           x = x - fx / deriv;
+           fx = fx_new;
+         endif
+       endfor
+
+       result = x;
+
+     endfunction
+
+   Note that this is only meant to be an example of calling
+user-supplied functions and should not be taken too seriously.  In
+addition to using a more robust algorithm, any serious code would check
+the number and type of all the arguments, ensure that the supplied
+function really was a function, etc.  *Note Predicates for Numeric
+Objects::, for example, for a list of predicates for numeric objects,
+and see *note Status of Variables::, for a description of the `exist'
+function.
+
+ -- Built-in Function:  feval (NAME, ...)
+     Evaluate the function named NAME.  Any arguments after the first
+     are passed on to the named function.  For example,
+
+          feval ("acos", -1)
+               => 3.1416
+
+     calls the function `acos' with the argument `-1'.
+
+     The function `feval' is necessary in order to be able to write
+     functions that call user-supplied functions, because Octave does
+     not have a way to declare a pointer to a function (like C) or to
+     declare a special kind of variable that can be used to hold the
+     name of a function (like `EXTERNAL' in Fortran).  Instead, you
+     must refer to functions by name, and use `feval' to call them.
+
+   A similar function `run' exists for calling user script files, that
+are not necessarily on the user path
+
+ -- Function File:  run (F)
+ -- Command:  run F
+     Run scripts in the current workspace that are not necessarily on
+     the path.  If F is the script to run, including its path, then
+     `run' change the directory to the directory where F is found.
+     `run' then executes the script, and returns to the original
+     directory.
+
+     *See also:* *note system: doc-system.
+
+
+File: octave.info,  Node: Evaluation in a Different Context,  Prev: Calling a Function by its Name,  Up: Evaluation
+
+9.2 Evaluation in a Different Context
+=====================================
+
+Before you evaluate an expression you need to substitute the values of
+the variables used in the expression.  These are stored in the symbol
+table.  Whenever the interpreter starts a new function it saves the
+current symbol table and creates a new one, initializing it with the
+list of function parameters and a couple of predefined variables such
+as `nargin'.  Expressions inside the function use the new symbol table.
+
+   Sometimes you want to write a function so that when you call it, it
+modifies variables in your own context.  This allows you to use a
+pass-by-name style of function, which is similar to using a pointer in
+programming languages such as C.
+
+   Consider how you might write `save' and `load' as m-files.  For
+example,
+
+     function create_data
+       x = linspace (0, 10, 10);
+       y = sin (x);
+       save mydata x y
+     endfunction
+
+   With `evalin', you could write `save' as follows:
+
+     function save (file, name1, name2)
+       f = open_save_file (file);
+       save_var(f, name1, evalin ("caller", name1));
+       save_var(f, name2, evalin ("caller", name2));
+     endfunction
+
+Here, `caller' is the `create_data' function and `name1' is the string
+`"x"', which evaluates simply as the value of `x'.
+
+   You later want to load the values back from `mydata' in a different
+context:
+
+     function process_data
+       load mydata
+       ... do work ...
+     endfunction
+
+With `assignin', you could write `load' as follows:
+
+     function load (file)
+       f = open_load_file (file);
+       [name, val] = load_var (f);
+       assignin ("caller", name, val);
+       [name, val] = load_var (f);
+       assignin ("caller", name, val);
+     endfunction
+
+Here, `caller' is the `process_data' function.
+
+   You can set and use variables at the command prompt using the
+context `base' rather than `caller'.
+
+   These functions are rarely used in practice.  One example is the
+`fail (`code', `pattern')' function which evaluates `code' in the
+caller's context and checks that the error message it produces matches
+the given pattern.  Other examples such as `save' and `load' are
+written in C++ where all Octave variables are in the `caller' context
+and `evalin' is not needed.
+
+ -- Built-in Function:  evalin (CONTEXT, TRY, CATCH)
+     Like `eval', except that the expressions are evaluated in the
+     context CONTEXT, which may be either `"caller"' or `"base"'.
+
+ -- Built-in Function:  assignin (CONTEXT, VARNAME, VALUE)
+     Assign VALUE to VARNAME in context CONTEXT, which may be either
+     `"base"' or `"caller"'.
+
+
+File: octave.info,  Node: Statements,  Next: Functions and Scripts,  Prev: Evaluation,  Up: Top
+
+10 Statements
+*************
+
+Statements may be a simple constant expression or a complicated list of
+nested loops and conditional statements.
+
+   "Control statements" such as `if', `while', and so on control the
+flow of execution in Octave programs.  All the control statements start
+with special keywords such as `if' and `while', to distinguish them
+from simple expressions.  Many control statements contain other
+statements; for example, the `if' statement contains another statement
+which may or may not be executed.
+
+   Each control statement has a corresponding "end" statement that
+marks the end of the control statement.  For example, the keyword
+`endif' marks the end of an `if' statement, and `endwhile' marks the
+end of a `while' statement.  You can use the keyword `end' anywhere a
+more specific end keyword is expected, but using the more specific
+keywords is preferred because if you use them, Octave is able to
+provide better diagnostics for mismatched or missing end tokens.
+
+   The list of statements contained between keywords like `if' or
+`while' and the corresponding end statement is called the "body" of a
+control statement.
+
+* Menu:
+
+* The `if' Statement::
+* The `switch' Statement::
+* The `while' Statement::
+* The `do-until' Statement::
+* The `for' Statement::
+* The `break' Statement::
+* The `continue' Statement::
+* The `unwind_protect' Statement::
+* The `try' Statement::
+* Continuation Lines::
+
+
+File: octave.info,  Node: The `if' Statement,  Next: The `switch' Statement,  Up: Statements
+
+10.1 The `if' Statement
+=======================
+
+The `if' statement is Octave's decision-making statement.  There are
+three basic forms of an `if' statement.  In its simplest form, it looks
+like this:
+
+     if (CONDITION)
+       THEN-BODY
+     endif
+
+CONDITION is an expression that controls what the rest of the statement
+will do.  The THEN-BODY is executed only if CONDITION is true.
+
+   The condition in an `if' statement is considered true if its value
+is non-zero, and false if its value is zero.  If the value of the
+conditional expression in an `if' statement is a vector or a matrix, it
+is considered true only if it is non-empty and _all_ of the elements
+are non-zero.
+
+   The second form of an if statement looks like this:
+
+     if (CONDITION)
+       THEN-BODY
+     else
+       ELSE-BODY
+     endif
+
+If CONDITION is true, THEN-BODY is executed; otherwise, ELSE-BODY is
+executed.
+
+   Here is an example:
+
+     if (rem (x, 2) == 0)
+       printf ("x is even\n");
+     else
+       printf ("x is odd\n");
+     endif
+
+   In this example, if the expression `rem (x, 2) == 0' is true (that
+is, the value of `x' is divisible by 2), then the first `printf'
+statement is evaluated, otherwise the second `printf' statement is
+evaluated.
+
+   The third and most general form of the `if' statement allows
+multiple decisions to be combined in a single statement.  It looks like
+this:
+
+     if (CONDITION)
+       THEN-BODY
+     elseif (CONDITION)
+       ELSEIF-BODY
+     else
+       ELSE-BODY
+     endif
+
+Any number of `elseif' clauses may appear.  Each condition is tested in
+turn, and if one is found to be true, its corresponding BODY is
+executed.  If none of the conditions are true and the `else' clause is
+present, its body is executed.  Only one `else' clause may appear, and
+it must be the last part of the statement.
+
+   In the following example, if the first condition is true (that is,
+the value of `x' is divisible by 2), then the first `printf' statement
+is executed.  If it is false, then the second condition is tested, and
+if it is true (that is, the value of `x' is divisible by 3), then the
+second `printf' statement is executed.  Otherwise, the third `printf'
+statement is performed.
+
+     if (rem (x, 2) == 0)
+       printf ("x is even\n");
+     elseif (rem (x, 3) == 0)
+       printf ("x is odd and divisible by 3\n");
+     else
+       printf ("x is odd\n");
+     endif
+
+   Note that the `elseif' keyword must not be spelled `else if', as is
+allowed in Fortran.  If it is, the space between the `else' and `if'
+will tell Octave to treat this as a new `if' statement within another
+`if' statement's `else' clause.  For example, if you write
+
+     if (C1)
+       BODY-1
+     else if (C2)
+       BODY-2
+     endif
+
+Octave will expect additional input to complete the first `if'
+statement.  If you are using Octave interactively, it will continue to
+prompt you for additional input.  If Octave is reading this input from a
+file, it may complain about missing or mismatched `end' statements, or,
+if you have not used the more specific `end' statements (`endif',
+`endfor', etc.), it may simply produce incorrect results, without
+producing any warning messages.
+
+   It is much easier to see the error if we rewrite the statements above
+like this,
+
+     if (C1)
+       BODY-1
+     else
+       if (C2)
+         BODY-2
+       endif
+
+using the indentation to show how Octave groups the statements.  *Note
+Functions and Scripts::.
+
+
+File: octave.info,  Node: The `switch' Statement,  Next: The `while' Statement,  Prev: The `if' Statement,  Up: Statements
+
+10.2 The `switch' Statement
+===========================
+
+It is very common to take different actions depending on the value of
+one variable.  This is possible using the `if' statement in the
+following way
+
+     if (X == 1)
+       do_something ();
+     elseif (X == 2)
+       do_something_else ();
+     else
+       do_something_completely_different ();
+     endif
+
+This kind of code can however be very cumbersome to both write and
+maintain.  To overcome this problem Octave supports the `switch'
+statement.  Using this statement, the above example becomes
+
+     switch (X)
+       case 1
+         do_something ();
+       case 2
+         do_something_else ();
+       otherwise
+         do_something_completely_different ();
+     endswitch
+
+This code makes the repetitive structure of the problem more explicit,
+making the code easier to read, and hence maintain.  Also, if the
+variable `X' should change its name, only one line would need changing
+compared to one line per case when `if' statements are used.
+
+   The general form of the `switch' statement is
+
+     switch EXPRESSION
+       case LABEL
+         COMMAND_LIST
+       case LABEL
+         COMMAND_LIST
+       ...
+
+       otherwise
+         COMMAND_LIST
+     endswitch
+
+where LABEL can be any expression.  However, duplicate LABEL values are
+not detected, and only the COMMAND_LIST corresponding to the first
+match will be executed.  For the `switch' statement to be meaningful at
+least one `case LABEL COMMAND_LIST' clause must be present, while the
+`otherwise COMMAND_LIST' clause is optional.
+
+   If LABEL is a cell array the corresponding COMMAND_LIST is executed
+if _any_ of the elements of the cell array match EXPRESSION.  As an
+example, the following program will print `Variable is either 6 or 7'.
+
+     A = 7;
+     switch A
+       case { 6, 7 }
+         printf ("variable is either 6 or 7\n");
+       otherwise
+         printf ("variable is neither 6 nor 7\n");
+     endswitch
+
+   As with all other specific `end' keywords, `endswitch' may be
+replaced by `end', but you can get better diagnostics if you use the
+specific forms.
+
+   One advantage of using the `switch' statement compared to using `if'
+statements is that the LABELs can be strings.  If an `if' statement is
+used it is _not_ possible to write
+
+     if (X == "a string") # This is NOT valid
+
+since a character-to-character comparison between `X' and the string
+will be made instead of evaluating if the strings are equal.  This
+special-case is handled by the `switch' statement, and it is possible
+to write programs that look like this
+
+     switch (X)
+       case "a string"
+         do_something
+       ...
+     endswitch
+
+* Menu:
+
+* Notes for the C programmer::
+
+
+File: octave.info,  Node: Notes for the C programmer,  Up: The `switch' Statement
+
+10.2.1 Notes for the C programmer
+---------------------------------
+
+The `switch' statement is also available in the widely used C
+programming language.  There are, however, some differences between the
+statement in Octave and C
+
+   * Cases are exclusive, so they don't `fall through' as do the cases
+     in the `switch' statement of the C language.
+
+   * The COMMAND_LIST elements are not optional.  Making the list
+     optional would have meant requiring a separator between the label
+     and the command list.  Otherwise, things like
+
+          switch (foo)
+            case (1) -2
+            ...
+
+     would produce surprising results, as would
+
+          switch (foo)
+            case (1)
+            case (2)
+              doit ();
+            ...
+
+     particularly for C programmers.  If `doit()' should be executed if
+     FOO is either `1' or `2', the above code should be written with a
+     cell array like this
+
+          switch (foo)
+            case { 1, 2 }
+              doit ();
+            ...
+
+
+File: octave.info,  Node: The `while' Statement,  Next: The `do-until' Statement,  Prev: The `switch' Statement,  Up: Statements
+
+10.3 The `while' Statement
+==========================
+
+In programming, a "loop" means a part of a program that is (or at least
+can be) executed two or more times in succession.
+
+   The `while' statement is the simplest looping statement in Octave.
+It repeatedly executes a statement as long as a condition is true.  As
+with the condition in an `if' statement, the condition in a `while'
+statement is considered true if its value is non-zero, and false if its
+value is zero.  If the value of the conditional expression in a `while'
+statement is a vector or a matrix, it is considered true only if it is
+non-empty and _all_ of the elements are non-zero.
+
+   Octave's `while' statement looks like this:
+
+     while (CONDITION)
+       BODY
+     endwhile
+
+Here BODY is a statement or list of statements that we call the "body"
+of the loop, and CONDITION is an expression that controls how long the
+loop keeps running.
+
+   The first thing the `while' statement does is test CONDITION.  If
+CONDITION is true, it executes the statement BODY.  After BODY has been
+executed, CONDITION is tested again, and if it is still true, BODY is
+executed again.  This process repeats until CONDITION is no longer
+true.  If CONDITION is initially false, the body of the loop is never
+executed.
+
+   This example creates a variable `fib' that contains the first ten
+elements of the Fibonacci sequence.
+
+     fib = ones (1, 10);
+     i = 3;
+     while (i <= 10)
+       fib (i) = fib (i-1) + fib (i-2);
+       i++;
+     endwhile
+
+Here the body of the loop contains two statements.
+
+   The loop works like this: first, the value of `i' is set to 3.
+Then, the `while' tests whether `i' is less than or equal to 10.  This
+is the case when `i' equals 3, so the value of the `i'-th element of
+`fib' is set to the sum of the previous two values in the sequence.
+Then the `i++' increments the value of `i' and the loop repeats.  The
+loop terminates when `i' reaches 11.
+
+   A newline is not required between the condition and the body; but
+using one makes the program clearer unless the body is very simple.
+
+
+File: octave.info,  Node: The `do-until' Statement,  Next: The `for' Statement,  Prev: The `while' Statement,  Up: Statements
+
+10.4 The `do-until' Statement
+=============================
+
+The `do-until' statement is similar to the `while' statement, except
+that it repeatedly executes a statement until a condition becomes true,
+and the test of the condition is at the end of the loop, so the body of
+the loop is always executed at least once.  As with the condition in an
+`if' statement, the condition in a `do-until' statement is considered
+true if its value is non-zero, and false if its value is zero.  If the
+value of the conditional expression in a `do-until' statement is a
+vector or a matrix, it is considered true only if it is non-empty and
+_all_ of the elements are non-zero.
+
+   Octave's `do-until' statement looks like this:
+
+     do
+       BODY
+     until (CONDITION)
+
+Here BODY is a statement or list of statements that we call the "body"
+of the loop, and CONDITION is an expression that controls how long the
+loop keeps running.
+
+   This example creates a variable `fib' that contains the first ten
+elements of the Fibonacci sequence.
+
+     fib = ones (1, 10);
+     i = 2;
+     do
+       i++;
+       fib (i) = fib (i-1) + fib (i-2);
+     until (i == 10)
+
+   A newline is not required between the `do' keyword and the body; but
+using one makes the program clearer unless the body is very simple.
+
+
+File: octave.info,  Node: The `for' Statement,  Next: The `break' Statement,  Prev: The `do-until' Statement,  Up: Statements
+
+10.5 The `for' Statement
+========================
+
+The `for' statement makes it more convenient to count iterations of a
+loop.  The general form of the `for' statement looks like this:
+
+     for VAR = EXPRESSION
+       BODY
+     endfor
+
+where BODY stands for any statement or list of statements, EXPRESSION
+is any valid expression, and VAR may take several forms.  Usually it is
+a simple variable name or an indexed variable.  If the value of
+EXPRESSION is a structure, VAR may also be a vector with two elements.
+*Note Looping Over Structure Elements::, below.
+
+   The assignment expression in the `for' statement works a bit
+differently than Octave's normal assignment statement.  Instead of
+assigning the complete result of the expression, it assigns each column
+of the expression to VAR in turn.  If EXPRESSION is a range, a row
+vector, or a scalar, the value of VAR will be a scalar each time the
+loop body is executed.  If VAR is a column vector or a matrix, VAR will
+be a column vector each time the loop body is executed.
+
+   The following example shows another way to create a vector containing
+the first ten elements of the Fibonacci sequence, this time using the
+`for' statement:
+
+     fib = ones (1, 10);
+     for i = 3:10
+       fib (i) = fib (i-1) + fib (i-2);
+     endfor
+
+This code works by first evaluating the expression `3:10', to produce a
+range of values from 3 to 10 inclusive.  Then the variable `i' is
+assigned the first element of the range and the body of the loop is
+executed once.  When the end of the loop body is reached, the next
+value in the range is assigned to the variable `i', and the loop body
+is executed again.  This process continues until there are no more
+elements to assign.
+
+   Within Octave is it also possible to iterate over matrices or cell
+arrays using the `for' statement.  For example consider
+
+     disp("Loop over a matrix")
+     for i = [1,3;2,4]
+       i
+     endfor
+     disp("Loop over a cell array")
+     for i = {1,"two";"three",4}
+       i
+     endfor
+
+In this case the variable `i' takes on the value of the columns of the
+matrix or cell matrix.  So the first loop iterates twice, producing two
+column vectors `[1;2]', followed by `[3;4]', and likewise for the loop
+over the cell array.  This can be extended to loops over
+multidimensional arrays.  For example
+
+     a = [1,3;2,4]; b = cat(3, a, 2*a);
+     for i = c
+       i
+     endfor
+
+In the above case, the multidimensional matrix C is reshaped to a
+two-dimensional matrix as `reshape (c, rows(c), prod(size(c)(2:end)))'
+and then the same behavior as a loop over a two dimensional matrix is
+produced.
+
+   Although it is possible to rewrite all `for' loops as `while' loops,
+the Octave language has both statements because often a `for' loop is
+both less work to type and more natural to think of.  Counting the
+number of iterations is very common in loops and it can be easier to
+think of this counting as part of looping rather than as something to
+do inside the loop.
+
+* Menu:
+
+* Looping Over Structure Elements::
+
diff --git a/doc/interpreter/octave.info-2 b/doc/interpreter/octave.info-2
new file mode 100644
index 0000000..71d9d26
--- /dev/null
+++ b/doc/interpreter/octave.info-2
@@ -0,0 +1,8168 @@
+This is octave.info, produced by makeinfo version 4.11 from ./octave.texi.
+
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, 2007
+John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+File: octave.info,  Node: Looping Over Structure Elements,  Up: The `for' Statement
+
+10.5.1 Looping Over Structure Elements
+--------------------------------------
+
+A special form of the `for' statement allows you to loop over all the
+elements of a structure:
+
+     for [ VAL, KEY ] = EXPRESSION
+       BODY
+     endfor
+
+In this form of the `for' statement, the value of EXPRESSION must be a
+structure.  If it is, KEY and VAL are set to the name of the element
+and the corresponding value in turn, until there are no more elements.
+For example,
+
+     x.a = 1
+     x.b = [1, 2; 3, 4]
+     x.c = "string"
+     for [val, key] = x
+       key
+       val
+     endfor
+
+          -| key = a
+          -| val = 1
+          -| key = b
+          -| val =
+          -|
+          -|   1  2
+          -|   3  4
+          -|
+          -| key = c
+          -| val = string
+
+   The elements are not accessed in any particular order.  If you need
+to cycle through the list in a particular way, you will have to use the
+function `fieldnames' and sort the list yourself.
+
+   The KEY variable may also be omitted.  If it is, the brackets are
+also optional.  This is useful for cycling through the values of all the
+structure elements when the names of the elements do not need to be
+known.
+
+
+File: octave.info,  Node: The `break' Statement,  Next: The `continue' Statement,  Prev: The `for' Statement,  Up: Statements
+
+10.6 The `break' Statement
+==========================
+
+The `break' statement jumps out of the innermost `for' or `while' loop
+that encloses it.  The `break' statement may only be used within the
+body of a loop.  The following example finds the smallest divisor of a
+given integer, and also identifies prime numbers:
+
+     num = 103;
+     div = 2;
+     while (div*div <= num)
+       if (rem (num, div) == 0)
+         break;
+       endif
+       div++;
+     endwhile
+     if (rem (num, div) == 0)
+       printf ("Smallest divisor of %d is %d\n", num, div)
+     else
+       printf ("%d is prime\n", num);
+     endif
+
+   When the remainder is zero in the first `while' statement, Octave
+immediately "breaks out" of the loop.  This means that Octave proceeds
+immediately to the statement following the loop and continues
+processing.  (This is very different from the `exit' statement which
+stops the entire Octave program.)
+
+   Here is another program equivalent to the previous one.  It
+illustrates how the CONDITION of a `while' statement could just as well
+be replaced with a `break' inside an `if':
+
+     num = 103;
+     div = 2;
+     while (1)
+       if (rem (num, div) == 0)
+         printf ("Smallest divisor of %d is %d\n", num, div);
+         break;
+       endif
+       div++;
+       if (div*div > num)
+         printf ("%d is prime\n", num);
+         break;
+       endif
+     endwhile
+
+
+File: octave.info,  Node: The `continue' Statement,  Next: The `unwind_protect' Statement,  Prev: The `break' Statement,  Up: Statements
+
+10.7 The `continue' Statement
+=============================
+
+The `continue' statement, like `break', is used only inside `for' or
+`while' loops.  It skips over the rest of the loop body, causing the
+next cycle around the loop to begin immediately.  Contrast this with
+`break', which jumps out of the loop altogether.  Here is an example:
+
+     # print elements of a vector of random
+     # integers that are even.
+
+     # first, create a row vector of 10 random
+     # integers with values between 0 and 100:
+
+     vec = round (rand (1, 10) * 100);
+
+     # print what we're interested in:
+
+     for x = vec
+       if (rem (x, 2) != 0)
+         continue;
+       endif
+       printf ("%d\n", x);
+     endfor
+
+   If one of the elements of VEC is an odd number, this example skips
+the print statement for that element, and continues back to the first
+statement in the loop.
+
+   This is not a practical example of the `continue' statement, but it
+should give you a clear understanding of how it works.  Normally, one
+would probably write the loop like this:
+
+     for x = vec
+       if (rem (x, 2) == 0)
+         printf ("%d\n", x);
+       endif
+     endfor
+
+
+File: octave.info,  Node: The `unwind_protect' Statement,  Next: The `try' Statement,  Prev: The `continue' Statement,  Up: Statements
+
+10.8 The `unwind_protect' Statement
+===================================
+
+Octave supports a limited form of exception handling modelled after the
+unwind-protect form of Lisp.
+
+   The general form of an `unwind_protect' block looks like this:
+
+     unwind_protect
+       BODY
+     unwind_protect_cleanup
+       CLEANUP
+     end_unwind_protect
+
+where BODY and CLEANUP are both optional and may contain any Octave
+expressions or commands.  The statements in CLEANUP are guaranteed to
+be executed regardless of how control exits BODY.
+
+   This is useful to protect temporary changes to global variables from
+possible errors.  For example, the following code will always restore
+the original value of the global variable `frobnosticate' even if an
+error occurs in the first part of the `unwind_protect' block.
+
+     save_frobnosticate = frobnosticate;
+     unwind_protect
+       frobnosticate = true;
+       ...
+     unwind_protect_cleanup
+       frobnosticate = save_frobnosticate;
+     end_unwind_protect
+
+Without `unwind_protect', the value of FROBNOSTICATE would not be
+restored if an error occurs while evaluating the first part of the
+`unwind_protect' block because evaluation would stop at the point of
+the error and the statement to restore the value would not be executed.
+
+
+File: octave.info,  Node: The `try' Statement,  Next: Continuation Lines,  Prev: The `unwind_protect' Statement,  Up: Statements
+
+10.9 The `try' Statement
+========================
+
+In addition to unwind_protect, Octave supports another limited form of
+exception handling.
+
+   The general form of a `try' block looks like this:
+
+     try
+       BODY
+     catch
+       CLEANUP
+     end_try_catch
+
+where BODY and CLEANUP are both optional and may contain any Octave
+expressions or commands.  The statements in CLEANUP are only executed
+if an error occurs in BODY.
+
+   No warnings or error messages are printed while BODY is executing.
+If an error does occur during the execution of BODY, CLEANUP can use
+the function `lasterr' to access the text of the message that would
+have been printed.  This is the same as `eval (TRY, CATCH)' but it is
+more efficient since the commands do not need to be parsed each time
+the TRY and CATCH statements are evaluated.  *Note Errors and
+Warnings::, for more information about the `lasterr' function.
+
+
+File: octave.info,  Node: Continuation Lines,  Prev: The `try' Statement,  Up: Statements
+
+10.10 Continuation Lines
+========================
+
+In the Octave language, most statements end with a newline character and
+you must tell Octave to ignore the newline character in order to
+continue a statement from one line to the next.  Lines that end with the
+characters `...' or `\' are joined with the following line before they
+are divided into tokens by Octave's parser.  For example, the lines
+
+     x = long_variable_name ...
+         + longer_variable_name \
+         - 42
+
+form a single statement.  The backslash character on the second line
+above is interpreted as a continuation character, _not_ as a division
+operator.
+
+   For continuation lines that do not occur inside string constants,
+whitespace and comments may appear between the continuation marker and
+the newline character.  For example, the statement
+
+     x = long_variable_name ...     # comment one
+         + longer_variable_name \   # comment two
+         - 42                       # last comment
+
+is equivalent to the one shown above.  Inside string constants, the
+continuation marker must appear at the end of the line just before the
+newline character.
+
+   Input that occurs inside parentheses can be continued to the next
+line without having to use a continuation marker.  For example, it is
+possible to write statements like
+
+     if (fine_dining_destination == on_a_boat
+         || fine_dining_destination == on_a_train)
+       seuss (i, will, not, eat, them, sam, i, am, i,
+              will, not, eat, green, eggs, and, ham);
+     endif
+
+without having to add to the clutter with continuation markers.
+
+
+File: octave.info,  Node: Functions and Scripts,  Next: Errors and Warnings,  Prev: Statements,  Up: Top
+
+11 Functions and Scripts
+************************
+
+Complicated Octave programs can often be simplified by defining
+functions.  Functions can be defined directly on the command line during
+interactive Octave sessions, or in external files, and can be called
+just like built-in functions.
+
+* Menu:
+
+* Defining Functions::
+* Multiple Return Values::
+* Variable-length Argument Lists::
+* Variable-length Return Lists::
+* Returning From a Function::
+* Default Arguments::
+* Function Files::
+* Script Files::
+* Function Handles Inline Functions and Anonymous Functions::
+* Commands::
+* Organization of Functions::
+
+
+File: octave.info,  Node: Defining Functions,  Next: Multiple Return Values,  Up: Functions and Scripts
+
+11.1 Defining Functions
+=======================
+
+In its simplest form, the definition of a function named NAME looks
+like this:
+
+     function NAME
+       BODY
+     endfunction
+
+A valid function name is like a valid variable name: a sequence of
+letters, digits and underscores, not starting with a digit.  Functions
+share the same pool of names as variables.
+
+   The function BODY consists of Octave statements.  It is the most
+important part of the definition, because it says what the function
+should actually _do_.
+
+   For example, here is a function that, when executed, will ring the
+bell on your terminal (assuming that it is possible to do so):
+
+     function wakeup
+       printf ("\a");
+     endfunction
+
+   The `printf' statement (*note Input and Output::) simply tells
+Octave to print the string `"\a"'.  The special character `\a' stands
+for the alert character (ASCII 7).  *Note Strings::.
+
+   Once this function is defined, you can ask Octave to evaluate it by
+typing the name of the function.
+
+   Normally, you will want to pass some information to the functions you
+define.  The syntax for passing parameters to a function in Octave is
+
+     function NAME (ARG-LIST)
+       BODY
+     endfunction
+
+where ARG-LIST is a comma-separated list of the function's arguments.
+When the function is called, the argument names are used to hold the
+argument values given in the call.  The list of arguments may be empty,
+in which case this form is equivalent to the one shown above.
+
+   To print a message along with ringing the bell, you might modify the
+`wakeup' to look like this:
+
+     function wakeup (message)
+       printf ("\a%s\n", message);
+     endfunction
+
+   Calling this function using a statement like this
+
+     wakeup ("Rise and shine!");
+
+will cause Octave to ring your terminal's bell and print the message
+`Rise and shine!', followed by a newline character (the `\n' in the
+first argument to the `printf' statement).
+
+   In most cases, you will also want to get some information back from
+the functions you define.  Here is the syntax for writing a function
+that returns a single value:
+
+     function RET-VAR = NAME (ARG-LIST)
+       BODY
+     endfunction
+
+The symbol RET-VAR is the name of the variable that will hold the value
+to be returned by the function.  This variable must be defined before
+the end of the function body in order for the function to return a
+value.
+
+   Variables used in the body of a function are local to the function.
+Variables named in ARG-LIST and RET-VAR are also local to the function.
+*Note Global Variables::, for information about how to access global
+variables inside a function.
+
+   For example, here is a function that computes the average of the
+elements of a vector:
+
+     function retval = avg (v)
+       retval = sum (v) / length (v);
+     endfunction
+
+   If we had written `avg' like this instead,
+
+     function retval = avg (v)
+       if (isvector (v))
+         retval = sum (v) / length (v);
+       endif
+     endfunction
+
+and then called the function with a matrix instead of a vector as the
+argument, Octave would have printed an error message like this:
+
+     error: value on right hand side of assignment is undefined
+
+because the body of the `if' statement was never executed, and `retval'
+was never defined.  To prevent obscure errors like this, it is a good
+idea to always make sure that the return variables will always have
+values, and to produce meaningful error messages when problems are
+encountered.  For example, `avg' could have been written like this:
+
+     function retval = avg (v)
+       retval = 0;
+       if (isvector (v))
+         retval = sum (v) / length (v);
+       else
+         error ("avg: expecting vector argument");
+       endif
+     endfunction
+
+   There is still one additional problem with this function.  What if
+it is called without an argument?  Without additional error checking,
+Octave will probably print an error message that won't really help you
+track down the source of the error.  To allow you to catch errors like
+this, Octave provides each function with an automatic variable called
+`nargin'.  Each time a function is called, `nargin' is automatically
+initialized to the number of arguments that have actually been passed
+to the function.  For example, we might rewrite the `avg' function like
+this:
+
+     function retval = avg (v)
+       retval = 0;
+       if (nargin != 1)
+         usage ("avg (vector)");
+       endif
+       if (isvector (v))
+         retval = sum (v) / length (v);
+       else
+         error ("avg: expecting vector argument");
+       endif
+     endfunction
+
+   Although Octave does not automatically report an error if you call a
+function with more arguments than expected, doing so probably indicates
+that something is wrong.  Octave also does not automatically report an
+error if a function is called with too few arguments, but any attempt to
+use a variable that has not been given a value will result in an error.
+To avoid such problems and to provide useful messages, we check for both
+possibilities and issue our own error message.
+
+ -- Built-in Function:  nargin ()
+ -- Built-in Function:  nargin (FCN_NAME)
+     Within a function, return the number of arguments passed to the
+     function.  At the top level, return the number of command line
+     arguments passed to Octave.  If called with the optional argument
+     FCN_NAME, return the maximum number of arguments the named
+     function can accept, or -1 if the function accepts a variable
+     number of arguments.
+
+     *See also:* *note nargout: doc-nargout, *note varargin:
+     doc-varargin, *note varargout: doc-varargout.
+
+ -- Function File:  inputname (N)
+     Return the text defining N-th input to the function.
+
+ -- Built-in Function: VAL = silent_functions ()
+ -- Built-in Function: OLD_VAL = silent_functions (NEW_VAL)
+     Query or set the internal variable that controls whether internal
+     output from a function is suppressed.  If this option is disabled,
+     Octave will display the results produced by evaluating expressions
+     within a function body that are not terminated with a semicolon.
+
+
+File: octave.info,  Node: Multiple Return Values,  Next: Variable-length Argument Lists,  Prev: Defining Functions,  Up: Functions and Scripts
+
+11.2 Multiple Return Values
+===========================
+
+Unlike many other computer languages, Octave allows you to define
+functions that return more than one value.  The syntax for defining
+functions that return multiple values is
+
+     function [RET-LIST] = NAME (ARG-LIST)
+       BODY
+     endfunction
+
+where NAME, ARG-LIST, and BODY have the same meaning as before, and
+RET-LIST is a comma-separated list of variable names that will hold the
+values returned from the function.  The list of return values must have
+at least one element.  If RET-LIST has only one element, this form of
+the `function' statement is equivalent to the form described in the
+previous section.
+
+   Here is an example of a function that returns two values, the maximum
+element of a vector and the index of its first occurrence in the vector.
+
+     function [max, idx] = vmax (v)
+       idx = 1;
+       max = v (idx);
+       for i = 2:length (v)
+         if (v (i) > max)
+           max = v (i);
+           idx = i;
+         endif
+       endfor
+     endfunction
+
+   In this particular case, the two values could have been returned as
+elements of a single array, but that is not always possible or
+convenient.  The values to be returned may not have compatible
+dimensions, and it is often desirable to give the individual return
+values distinct names.
+
+   In addition to setting `nargin' each time a function is called,
+Octave also automatically initializes `nargout' to the number of values
+that are expected to be returned.  This allows you to write functions
+that behave differently depending on the number of values that the user
+of the function has requested.  The implicit assignment to the built-in
+variable `ans' does not figure in the count of output arguments, so the
+value of `nargout' may be zero.
+
+   The `svd' and `lu' functions are examples of built-in functions that
+behave differently depending on the value of `nargout'.
+
+   It is possible to write functions that only set some return values.
+For example, calling the function
+
+     function [x, y, z] = f ()
+       x = 1;
+       z = 2;
+     endfunction
+
+as
+
+     [a, b, c] = f ()
+
+produces:
+
+     a = 1
+
+     b = [](0x0)
+
+     c = 2
+
+along with a warning.
+
+ -- Built-in Function:  nargout ()
+ -- Built-in Function:  nargout (FCN_NAME)
+     Within a function, return the number of values the caller expects
+     to receive.  If called with the optional argument FCN_NAME, return
+     the maximum number of values the named function can produce, or -1
+     if the function can produce a variable number of values.
+
+     For example,
+
+          f ()
+
+     will cause `nargout' to return 0 inside the function `f' and
+
+          [s, t] = f ()
+
+     will cause `nargout' to return 2 inside the function `f'.
+
+     At the top level, `nargout' is undefined.
+
+     *See also:* *note nargin: doc-nargin, *note varargin:
+     doc-varargin, *note varargout: doc-varargout.
+
+ -- Function File: MSGSTR = nargchk (MINARGS, MAXARGS, NARGS)
+ -- Function File: MSGSTR = nargchk (MINARGS, MAXARGS, NARGS, "string")
+ -- Function File: MSGSTRUCT = nargchk (MINARGS, MAXARGS, NARGS,
+          "struct")
+     Return an appropriate error message string (or structure) if the
+     number of inputs requested is invalid.
+
+     This is useful for checking to see that the number of input
+     arguments supplied to a function is within an acceptable range.
+
+     *See also:* *note nargoutchk: doc-nargoutchk, *note error:
+     doc-error, *note nargin: doc-nargin, *note nargout: doc-nargout.
+
+ -- Function File: MSGSTR = nargoutchk (MINARGS, MAXARGS, NARGS)
+ -- Function File: MSGSTR = nargoutchk (MINARGS, MAXARGS, NARGS,
+          "string")
+ -- Function File: MSGSTRUCT = nargoutchk (MINARGS, MAXARGS, NARGS,
+          "struct")
+     Return an appropriate error message string (or structure) if the
+     number of outputs requested is invalid.
+
+     This is useful for checking to see that the number of output
+     arguments supplied to a function is within an acceptable range.
+
+     *See also:* *note nargchk: doc-nargchk, *note error: doc-error,
+     *note nargout: doc-nargout, *note nargin: doc-nargin.
+
+
+File: octave.info,  Node: Variable-length Argument Lists,  Next: Variable-length Return Lists,  Prev: Multiple Return Values,  Up: Functions and Scripts
+
+11.3 Variable-length Argument Lists
+===================================
+
+Sometimes the number of input arguments is not known when the function
+is defined.  As an example think of a function that returns the smallest
+of all its input arguments.  For example,
+
+     a = smallest (1, 2, 3);
+     b = smallest (1, 2, 3, 4);
+
+In this example both `a' and `b' would be 1.  One way to write the
+`smallest' function is
+
+     function val = smallest (arg1, arg2, arg3, arg4, arg5)
+       BODY
+     endfunction
+
+and then use the value of `nargin' to determine which of the input
+arguments should be considered.  The problem with this approach is that
+it can only handle a limited number of input arguments.
+
+   If the special parameter name `varargin' appears at the end of a
+function parameter list it indicates that the function takes a variable
+number of input arguments.  Using `varargin' the function looks like
+this
+
+     function val = smallest (varargin)
+       BODY
+     endfunction
+
+In the function body the input arguments can be accessed through the
+variable `varargin'.  This variable is a cell array containing all the
+input arguments.  *Note Cell Arrays::, for details on working with cell
+arrays.  The `smallest' function can now be defined like this
+
+     function val = smallest (varargin)
+       val = min ([varargin{:}]);
+     endfunction
+
+This implementation handles any number of input arguments, but it's also
+a very simple solution to the problem.
+
+   A slightly more complex example of `varargin' is a function
+`print_arguments' that prints all input arguments.  Such a function can
+be defined like this
+
+     function print_arguments (varargin)
+       for i = 1:length (varargin)
+         printf ("Input argument %d: ", i);
+         disp (varargin{i});
+       endfor
+     endfunction
+
+This function produces output like this
+
+     print_arguments (1, "two", 3);
+          -| Input argument 1:  1
+          -| Input argument 2: two
+          -| Input argument 3:  3
+
+ -- Function File: [REG, PROP] = parseparams (PARAMS)
+     Return in REG the cell elements of PARAM up to the first string
+     element and in PROP all remaining elements beginning with the
+     first string element.  For example
+
+          [reg, prop] = parseparams ({1, 2, "linewidth", 10})
+          reg =
+          {
+            [1,1] = 1
+            [1,2] = 2
+          }
+          prop =
+          {
+            [1,1] = linewidth
+            [1,2] = 10
+          }
+
+     The parseparams function may be used to separate 'regular'
+     arguments and additional arguments given as property/value pairs of
+     the VARARGIN cell array.
+
+     *See also:* *note varargin: doc-varargin.
+
+
+File: octave.info,  Node: Variable-length Return Lists,  Next: Returning From a Function,  Prev: Variable-length Argument Lists,  Up: Functions and Scripts
+
+11.4 Variable-length Return Lists
+=================================
+
+It is possible to return a variable number of output arguments from a
+function using a syntax that's similar to the one used with the special
+`varargin' parameter name.  To let a function return a variable number
+of output arguments the special output parameter name `varargout' is
+used.  As with `varargin', `varargout' is a cell array that will
+contain the requested output arguments.
+
+   As an example the following function sets the first output argument
+to 1, the second to 2, and so on.
+
+     function varargout = one_to_n ()
+       for i = 1:nargout
+         varargout{i} = i;
+       endfor
+     endfunction
+
+When called this function returns values like this
+
+     [a, b, c] = one_to_n ()
+          => a =  1
+          => b =  2
+          => c =  3
+
+   If `varargin' (`varargout') does not appear as the last element of
+the input (output) parameter list, then it is not special, and is
+handled the same as any other parameter name.
+
+ -- Function File: [R1, R2, ..., RN] = deal (A)
+ -- Function File: [R1, R2, ..., RN] = deal (A1, A2, ..., AN)
+     Copy the input parameters into the corresponding output parameters.
+     If only one input parameter is supplied, its value is copied to
+     each of the outputs.
+
+     For example,
+
+          [a, b, c] = deal (x, y, z);
+
+     is equivalent to
+
+          a = x;
+          b = y;
+          c = z;
+
+     and
+
+          [a, b, c] = deal (x);
+
+     is equivalent to
+
+          a = b = c = x;
+
+
+File: octave.info,  Node: Returning From a Function,  Next: Default Arguments,  Prev: Variable-length Return Lists,  Up: Functions and Scripts
+
+11.5 Returning From a Function
+==============================
+
+The body of a user-defined function can contain a `return' statement.
+This statement returns control to the rest of the Octave program.  It
+looks like this:
+
+     return
+
+   Unlike the `return' statement in C, Octave's `return' statement
+cannot be used to return a value from a function.  Instead, you must
+assign values to the list of return variables that are part of the
+`function' statement.  The `return' statement simply makes it easier to
+exit a function from a deeply nested loop or conditional statement.
+
+   Here is an example of a function that checks to see if any elements
+of a vector are nonzero.
+
+     function retval = any_nonzero (v)
+       retval = 0;
+       for i = 1:length (v)
+         if (v (i) != 0)
+           retval = 1;
+           return;
+         endif
+       endfor
+       printf ("no nonzero elements found\n");
+     endfunction
+
+   Note that this function could not have been written using the
+`break' statement to exit the loop once a nonzero value is found
+without adding extra logic to avoid printing the message if the vector
+does contain a nonzero element.
+
+ -- Keyword: return
+     When Octave encounters the keyword `return' inside a function or
+     script, it returns control to the caller immediately.  At the top
+     level, the return statement is ignored.  A `return' statement is
+     assumed at the end of every function definition.
+
+
+File: octave.info,  Node: Default Arguments,  Next: Function Files,  Prev: Returning From a Function,  Up: Functions and Scripts
+
+11.6 Default Arguments
+======================
+
+Since Octave supports variable number of input arguments, it is very
+useful to assign default values to some input arguments.  When an input
+argument is declared in the argument list it is possible to assign a
+default value to the argument like this
+
+     function NAME (ARG1 = VAL1, ...)
+       BODY
+     endfunction
+
+If no value is assigned to ARG1 by the user, it will have the value
+VAL1.
+
+   As an example, the following function implements a variant of the
+classic "Hello, World" program.
+     function hello (who = "World")
+       printf ("Hello, %s!\n", who);
+     endfunction
+
+When called without an input argument the function prints the following
+     hello ();
+          -| Hello, World!
+
+and when it's called with an input argument it prints the following
+     hello ("Beautiful World of Free Software");
+          -| Hello, Beautiful World of Free Software!
+
+   Sometimes it is useful to explicitly tell Octave to use the default
+value of an input argument.  This can be done writing a `:' as the value
+of the input argument when calling the function.
+     hello (:);
+          -| Hello, World!
+
+
+File: octave.info,  Node: Function Files,  Next: Script Files,  Prev: Default Arguments,  Up: Functions and Scripts
+
+11.7 Function Files
+===================
+
+Except for simple one-shot programs, it is not practical to have to
+define all the functions you need each time you need them.  Instead, you
+will normally want to save them in a file so that you can easily edit
+them, and save them for use at a later time.
+
+   Octave does not require you to load function definitions from files
+before using them.  You simply need to put the function definitions in a
+place where Octave can find them.
+
+   When Octave encounters an identifier that is undefined, it first
+looks for variables or functions that are already compiled and currently
+listed in its symbol table.  If it fails to find a definition there, it
+searches a list of directories (the "path") for files ending in `.m'
+that have the same base name as the undefined identifier.(1)  Once
+Octave finds a file with a name that matches, the contents of the file
+are read.  If it defines a _single_ function, it is compiled and
+executed.  *Note Script Files::, for more information about how you can
+define more than one function in a single file.
+
+   When Octave defines a function from a function file, it saves the
+full name of the file it read and the time stamp on the file.  If the
+time stamp on the file changes, Octave may reload the file.  When
+Octave is running interactively, time stamp checking normally happens
+at most once each time Octave prints the prompt.  Searching for new
+function definitions also occurs if the current working directory
+changes.
+
+   Checking the time stamp allows you to edit the definition of a
+function while Octave is running, and automatically use the new function
+definition without having to restart your Octave session.
+
+   To avoid degrading performance unnecessarily by checking the time
+stamps on functions that are not likely to change, Octave assumes that
+function files in the directory tree
+`OCTAVE-HOME/share/octave/VERSION/m' will not change, so it doesn't
+have to check their time stamps every time the functions defined in
+those files are used.  This is normally a very good assumption and
+provides a significant improvement in performance for the function
+files that are distributed with Octave.
+
+   If you know that your own function files will not change while you
+are running Octave, you can improve performance by calling
+`ignore_function_time_stamp ("all")', so that Octave will ignore the
+time stamps for all function files.  Passing `"system"' to this
+function resets the default behavior.
+
+ -- Command: edit NAME
+ -- Command: edit FIELD VALUE
+ -- Command: VALUE = edit get FIELD
+     Edit the named function, or change editor settings.
+
+     If `edit' is called with the name of a file or function as its
+     argument it will be opened in a text editor.
+
+        * If the function NAME is available in a file on your path and
+          that file is modifiable, then it will be edited in place.  If
+          it is a system function, then it will first be copied to the
+          directory `HOME' (see further down) and then edited.  If no
+          file is found, then the m-file variant, ending with ".m",
+          will be considered.  If still no file is found, then variants
+          with a leading "@" and then with both a leading "@" and
+          trailing ".m" will be considered.
+
+        * If NAME is the name of a function defined in the interpreter
+          but not in an m-file, then an m-file will be created in `HOME'
+          to contain that function along with its current definition.
+
+        * If `name.cc' is specified, then it will search for `name.cc'
+          in the path and try to modify it, otherwise it will create a
+          new `.cc' file in `HOME'.  If NAME happens to be an m-file or
+          interpreter defined function, then the text of that function
+          will be inserted into the .cc file as a comment.
+
+        * If NAME.EXT is on your path then it will be edited, otherwise
+          the editor will be started with `HOME/name.ext' as the
+          filename.  If `name.ext' is not modifiable, it will be copied
+          to `HOME' before editing.
+
+          *WARNING!* You may need to clear name before the new
+          definition is available.  If you are editing a .cc file, you
+          will need to mkoctfile `name.cc' before the definition will
+          be available.
+
+     If `edit' is called with FIELD and VALUE variables, the value of
+     the control field FIELD will be VALUE.  If an output argument is
+     requested and the first argument is `get' then `edit' will return
+     the value of the control field FIELD.  If the control field does
+     not exist, edit will return a structure containing all fields and
+     values.  Thus, `edit get all' returns a complete control structure.
+     The following control fields are used:
+
+    `editor'
+          This is the editor to use to modify the functions.  By
+          default it uses Octave's `EDITOR' built-in function, which
+          comes from `getenv("EDITOR")' and defaults to `emacs'.  Use
+          `%s' In place of the function name.  For example,
+         `[EDITOR, " %s"]'
+               Use the editor which Octave uses for `bug_report'.
+
+         `"xedit %s &"'
+               pop up simple X11 editor in a separate window
+
+         `"gnudoit -q \"(find-file \\\"%s\\\")\""'
+               Send it to current Emacs; must have `(gnuserv-start)' in
+               `.emacs'.
+
+          See also field 'mode', which controls how the editor is run
+          by Octave.
+
+          On Cygwin, you will need to convert the Cygwin path to a
+          Windows path if you are using a native Windows editor.  For
+          example
+               '"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+
+    `home'
+          This is the location of user local m-files.  Be be sure it is
+          in your path.  The default is `~/octave'.
+
+    `author'
+          This is the name to put after the "## Author:" field of new
+          functions.  By default it guesses from the `gecos' field of
+          password database.
+
+    `email'
+          This is the e-mail address to list after the name in the
+          author field.  By default it guesses `<$LOGNAME@$HOSTNAME>',
+          and if `$HOSTNAME' is not defined it uses `uname -n'.  You
+          probably want to override this.  Be sure to use `<user at host>'
+          as your format.
+
+    `license'
+
+         `gpl'
+               GNU General Public License (default).
+
+         `bsd'
+               BSD-style license without advertising clause.
+
+         `pd'
+               Public domain.
+
+         `"text"'
+               Your own default copyright and license.
+
+          Unless you specify `pd', edit will prepend the copyright
+          statement with "Copyright (C) yyyy Function Author".
+
+    `mode'
+          This value determines whether the editor should be started in
+          async mode (editor is started in the background and Octave
+          continues) or sync mode (Octave waits until the editor
+          exits).  Set it to "async" to start the editor in async mode.
+          The default is "sync" (see also "system").
+
+    `editinplace'
+          Determines whether files should be edited in place, without
+          regard to whether they are modifiable or not.  The default is
+          `false'.
+
+ -- Built-in Function:  mfilename ()
+ -- Built-in Function:  mfilename (`"fullpath"')
+ -- Built-in Function:  mfilename (`"fullpathext"')
+     Return the name of the currently executing file.  At the top-level,
+     return the empty string.  Given the argument `"fullpath"', include
+     the directory part of the file name, but not the extension.  Given
+     the argument `"fullpathext"', include the directory part of the
+     file name and the extension.
+
+ -- Built-in Function: VAL = ignore_function_time_stamp ()
+ -- Built-in Function: OLD_VAL = ignore_function_time_stamp (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     checks the time stamp on files each time it looks up functions
+     defined in function files.  If the internal variable is set to
+     `"system"', Octave will not automatically recompile function files
+     in subdirectories of `OCTAVE-HOME/lib/VERSION' if they have
+     changed since they were last compiled, but will recompile other
+     function files in the search path if they change.  If set to
+     `"all"', Octave will not recompile any function files unless their
+     definitions are removed with `clear'.  If set to "none", Octave
+     will always check time stamps on files to determine whether
+     functions defined in function files need to recompiled.
+
+* Menu:
+
+* Manipulating the load path::
+* Subfunctions::
+* Private Functions::
+* Overloading and Autoloading::
+* Function Locking::
+* Function Precedence::
+
+   ---------- Footnotes ----------
+
+   (1) The `.m' suffix was chosen for compatibility with MATLAB.
+
+
+File: octave.info,  Node: Manipulating the load path,  Next: Subfunctions,  Up: Function Files
+
+11.7.1 Manipulating the load path
+---------------------------------
+
+When a function is called, Octave searches a list of directories for a
+file that contains the function declaration.  This list of directories
+is known as the load path.  By default the load path contains a list of
+directories distributed with Octave plus the current working directory.
+To see your current load path call the `path' function without any
+input or output arguments.
+
+   It is possible to add or remove directories to or from the load path
+using `addpath' and `rmpath'.  As an example, the following code adds
+`~/Octave' to the load path.
+
+     addpath("~/Octave")
+
+After this the directory `~/Octave' will be searched for functions.
+
+ -- Built-in Function:  addpath (DIR1, ...)
+ -- Built-in Function:  addpath (DIR1, ..., OPTION)
+     Add DIR1, ... to the current function search path.  If OPTION is
+     `"-begin"' or 0 (the default), prepend the directory name to the
+     current path.  If OPTION is `"-end"' or 1, append the directory
+     name to the current path.  Directories added to the path must
+     exist.
+
+     *See also:* *note path: doc-path, *note rmpath: doc-rmpath, *note
+     genpath: doc-genpath, *note pathdef: doc-pathdef, *note savepath:
+     doc-savepath, *note pathsep: doc-pathsep.
+
+ -- Built-in Function:  genpath (DIR)
+     Return a path constructed from DIR and all its subdirectories.
+
+ -- Built-in Function:  rmpath (DIR1, ...)
+     Remove DIR1, ... from the current function search path.
+
+     *See also:* *note path: doc-path, *note addpath: doc-addpath,
+     *note genpath: doc-genpath, *note pathdef: doc-pathdef, *note
+     savepath: doc-savepath, *note pathsep: doc-pathsep.
+
+ -- Function File:  savepath (FILE)
+     Save the portion of the current function search path, that is not
+     set during Octave's initialization process, to FILE.  If FILE is
+     omitted, `~/.octaverc' is used.  If successful, `savepath' returns
+     0.
+
+     *See also:* *note path: doc-path, *note addpath: doc-addpath,
+     *note rmpath: doc-rmpath, *note genpath: doc-genpath, *note
+     pathdef: doc-pathdef, *note pathsep: doc-pathsep.
+
+ -- Built-in Function:  path (...)
+     Modify or display Octave's load path.
+
+     If NARGIN and NARGOUT are zero, display the elements of Octave's
+     load path in an easy to read format.
+
+     If NARGIN is zero and nargout is greater than zero, return the
+     current load path.
+
+     If NARGIN is greater than zero, concatenate the arguments,
+     separating them with `pathsep()'.  Set the internal search path to
+     the result and return it.
+
+     No checks are made for duplicate elements.
+
+     *See also:* *note addpath: doc-addpath, *note rmpath: doc-rmpath,
+     *note genpath: doc-genpath, *note pathdef: doc-pathdef, *note
+     savepath: doc-savepath, *note pathsep: doc-pathsep.
+
+ -- Function File: VAL = pathdef ()
+     Return the default path for Octave.  The path information is
+     extracted from one of three sources.  In order of preference,
+     those are;
+
+       1. `~/.octaverc'
+
+       2. `<octave-home>/.../<version>/m/startup/octaverc'
+
+       3. Octave's path prior to changes by any octaverc.
+
+     *See also:* *note path: doc-path, *note addpath: doc-addpath,
+     *note rmpath: doc-rmpath, *note genpath: doc-genpath, *note
+     savepath: doc-savepath, *note pathsep: doc-pathsep.
+
+ -- Built-in Function: VAL = pathsep ()
+ -- Built-in Function: OLD_VAL = pathsep (NEW_VAL)
+     Query or set the character used to separate directories in a path.
+
+     *See also:* *note filesep: doc-filesep, *note dir: doc-dir, *note
+     ls: doc-ls.
+
+ -- Built-in Function:  rehash ()
+     Reinitialize Octave's load path directory cache.
+
+ -- Built-in Function:  file_in_loadpath (FILE)
+ -- Built-in Function:  file_in_loadpath (FILE, "all")
+     Return the absolute name of FILE if it can be found in the list of
+     directories specified by `path'.  If no file is found, return an
+     empty matrix.
+
+     If the first argument is a cell array of strings, search each
+     directory of the loadpath for element of the cell array and return
+     the first that matches.
+
+     If the second optional argument `"all"' is supplied, return a cell
+     array containing the list of all files that have the same name in
+     the path.  If no files are found, return an empty cell array.
+
+     *See also:* *note file_in_path: doc-file_in_path, *note path:
+     doc-path.
+
+ -- Built-in Function:  restoredefaultpath (...)
+     Restore Octave's path to it's initial state at startup.
+
+     *See also:* *note path: doc-path, *note addpath: doc-addpath,
+     *note rmpath: doc-rmpath, *note genpath: doc-genpath, *note
+     pathdef: doc-pathdef, *note savepath: doc-savepath, *note pathsep:
+     doc-pathsep.
+
+ -- Built-in Function:  command_line_path (...)
+     Return the command line path variable.
+
+     *See also:* *note path: doc-path, *note addpath: doc-addpath,
+     *note rmpath: doc-rmpath, *note genpath: doc-genpath, *note
+     pathdef: doc-pathdef, *note savepath: doc-savepath, *note pathsep:
+     doc-pathsep.
+
+ -- Built-in Function:  find_dir_in_path (DIR)
+     Return the full name of the path element matching DIR.  The match
+     is performed at the end of each path element.  For example, if DIR
+     is `"foo/bar"', it matches the path element `"/some/dir/foo/bar"',
+     but not `"/some/dir/foo/bar/baz"' or `"/some/dir/allfoo/bar"'.
+
+
+File: octave.info,  Node: Subfunctions,  Next: Private Functions,  Prev: Manipulating the load path,  Up: Function Files
+
+11.7.2 Subfunctions
+-------------------
+
+A function file may contain secondary functions called "subfunctions".
+These secondary functions are only visible to the other functions in
+the same function file.  For example, a file `f.m' containing
+
+     function f ()
+       printf ("in f, calling g\n");
+       g ()
+     endfunction
+     function g ()
+       printf ("in g, calling h\n");
+       h ()
+     endfunction
+     function h ()
+       printf ("in h\n")
+     endfunction
+
+defines a main function `f' and two subfunctions.  The subfunctions `g'
+and `h' may only be called from the main function `f' or from the other
+subfunctions, but not from outside the file `f.m'.
+
+
+File: octave.info,  Node: Private Functions,  Next: Overloading and Autoloading,  Prev: Subfunctions,  Up: Function Files
+
+11.7.3 Private Functions
+------------------------
+
+In many cases one function needs to access one or more helper
+functions.  If the helper function is limited to the scope of a single
+function, then subfunctions as discussed above might be used.  However,
+if a single helper function is used by more than one function, then
+this is no longer possible.  In this case the helper functions might be
+placed in a subdirectory, called "private", of the directory in which
+the functions needing access to this helper function are found.
+
+   As a simple example, consider a function `func1', that calls a helper
+function `func2' to do much of the work.  For example
+
+     function y = func1 (x)
+       y = func2 (x);
+     endfunction
+
+Then if the path to `func1' is `<directory>/func1.m', and if `func2' is
+found in the directory `<directory>/private/func2.m', then `func2' is
+only available for use of the functions, like `func1', that are found
+in `<directory>'.
+
+
+File: octave.info,  Node: Overloading and Autoloading,  Next: Function Locking,  Prev: Private Functions,  Up: Function Files
+
+11.7.4 Overloading and Autoloading
+----------------------------------
+
+The `dispatch' function can be used to alias one function name to
+another.  It can be used to alias all calls to a particular function
+name to another function, or the alias can be limited to only a
+particular variable type.  Consider the example
+
+     function y = spsin (x)
+       printf ("Calling spsin\n");
+       fflush(stdout);
+       y = spfun ("sin", x);
+     endfunction
+
+     dispatch ("sin", "spsin", "sparse matrix");
+     y0 = sin(eye(3));
+     y1 = sin(speye(3));
+
+which aliases the user-defined function `spsin' to `sin', but only for
+real sparse matrices.  Note that the builtin `sin' already correctly
+treats sparse matrices and so this example is only illustrative.
+
+ -- Loadable Function:  dispatch (F, R, TYPE)
+     Replace the function F with a dispatch so that function R is
+     called when F is called with the first argument of the named TYPE.
+     If the type is ANY then call R if no other type matches.  The
+     original function F is accessible using `builtin (F, ...)'.
+
+     If R is omitted, clear dispatch function associated with TYPE.
+
+     If both R and TYPE are omitted, list dispatch functions for F.
+
+     *See also:* *note builtin: doc-builtin.
+
+ -- Loadable Function: [...] builtin (F, ...)
+     Call the base function F even if F is overloaded to some other
+     function for the given type signature.
+
+     *See also:* *note dispatch: doc-dispatch.
+
+   A single dynamically linked file might define several functions.
+However, as Octave searches for functions based on the functions
+filename, Octave needs a manner in which to find each of the functions
+in the dynamically linked file.  On operating systems that support
+symbolic links, it is possible to create a symbolic link to the
+original file for each of the functions which it contains.
+
+   However, there is at least one well known operating system that
+doesn't support symbolic links.  Making copies of the original file for
+each of the functions is undesirable as it increases the amount of disk
+space used by Octave.  Instead Octave supplies the `autoload' function,
+that permits the user to define in which file a certain function will
+be found.
+
+ -- Built-in Function:  autoload (FUNCTION, FILE)
+     Define FUNCTION to autoload from FILE.
+
+     The second argument, FILE, should be an absolute file name or a
+     file name in the same directory as the function or script from
+     which the autoload command was run.  FILE should not depend on the
+     Octave load path.
+
+     Normally, calls to `autoload' appear in PKG_ADD script files that
+     are evaluated when a directory is added to the Octave's load path.
+     To avoid having to hardcode directory names in FILE, if FILE is in
+     the same directory as the PKG_ADD script then
+
+          autoload ("foo", "bar.oct");
+
+     will load the function `foo' from the file `bar.oct'.  The above
+     when `bar.oct' is not in the same directory or uses like
+
+          autoload ("foo", file_in_loadpath ("bar.oct"))
+
+     are strongly discouraged, as their behavior might be unpredictable.
+
+     With no arguments, return a structure containing the current
+     autoload map.
+
+     *See also:* *note PKG_ADD: doc-PKG_ADD.
+
+
+File: octave.info,  Node: Function Locking,  Next: Function Precedence,  Prev: Overloading and Autoloading,  Up: Function Files
+
+11.7.5 Function Locking
+-----------------------
+
+It is sometime desirable to lock a function into memory with the
+`mlock' function.  This is typically used for dynamically linked
+functions in Oct-files or mex-files that contain some initialization,
+and it is desirable that calling `clear' does not remove this
+initialization.
+
+   As an example,
+
+     mlock ("my_function");
+
+prevents `my_function' from being removed from memory, even if `clear'
+is called.  It is possible to determine if a function is locked into
+memory with the `mislocked', and to unlock a function with `munlock',
+which the following illustrates.
+
+     mlock ("my_function");
+     mislocked ("my_function")
+     => ans = 1
+     munlock ("my_function");
+     mislocked ("my_function")
+     => ans = 0
+
+   A common use of `mlock' is to prevent persistent variables from
+being removed from memory, as the following example shows:
+
+     function count_calls()
+       persistent calls = 0;
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+     mlock ("count_calls");
+
+     count_calls ();
+     -| 'count_calls' has been called 1 times
+
+     clear count_calls
+     count_calls ();
+     -| 'count_calls' has been called 2 times
+
+It is, however, often inconvenient to lock a function from the prompt,
+so it is also possible to lock a function from within its body.  This
+is simply done by calling `mlock' from within the function.
+
+     function count_calls ()
+       mlock ();
+       persistent calls = 0;
+       printf ("'count_calls' has been called %d times\n",
+               ++calls);
+     endfunction
+
+   `mlock' might equally be used to prevent changes to a function from
+having effect in Octave, though a similar effect can be had with the
+`ignore_function_time_stamp' function.
+
+ -- Built-in Function:  mlock ()
+     Lock the current function into memory so that it can't be cleared.
+
+     *See also:* *note munlock: doc-munlock, *note mislocked:
+     doc-mislocked, *note persistent: doc-persistent.
+
+ -- Built-in Function:  munlock (FCN)
+     Unlock the named function.  If no function is named then unlock
+     the current function.
+
+     *See also:* *note mlock: doc-mlock, *note mislocked:
+     doc-mislocked, *note persistent: doc-persistent.
+
+ -- Built-in Function:  mislocked (FCN)
+     Return true if the named function is locked.  If no function is
+     named then return true if the current function is locked.
+
+     *See also:* *note mlock: doc-mlock, *note munlock: doc-munlock,
+     *note persistent: doc-persistent.
+
+
+File: octave.info,  Node: Function Precedence,  Prev: Function Locking,  Up: Function Files
+
+11.7.6 Function Precedence
+--------------------------
+
+Given the numerous different ways that Octave can define a function, it
+is possible and even likely that multiple versions of a function, might
+be defined within a particular scope.  The precedence of which function
+will be used within a particular scope is given by
+
+  1. Subfunction A subfunction with the required function name in the
+     given scope.
+
+  2. Private function A function defined within a private directory of
+     the directory which contains the current function.
+
+  3. Class constructor A function that constuctors a user class as
+     defined in chapter *note Object Oriented Programming::.
+
+  4. Class method An overloaded function of a class as in chapter *note
+     Object Oriented Programming::.
+
+  5. Legacy Dispatch An overloaded function as defined by *Note
+     doc-dispatch::.
+
+  6. Command-line Function A function that has been defined on the
+     command-line.
+
+  7. Autoload function A function that is marked as autoloaded with
+     *Note doc-autoload::.
+
+  8. A Function on the Path A function that can be found on the users
+     load-path.  There can also be Oct-file, mex-file or m-file
+     versions of this function and the precedence between these
+     versions are in that order.
+
+  9. Built-in function A function that is builtin to Octave itself such
+     as `numel', `size', etc.
+
+
+File: octave.info,  Node: Script Files,  Next: Function Handles Inline Functions and Anonymous Functions,  Prev: Function Files,  Up: Functions and Scripts
+
+11.8 Script Files
+=================
+
+A script file is a file containing (almost) any sequence of Octave
+commands.  It is read and evaluated just as if you had typed each
+command at the Octave prompt, and provides a convenient way to perform a
+sequence of commands that do not logically belong inside a function.
+
+   Unlike a function file, a script file must _not_ begin with the
+keyword `function'.  If it does, Octave will assume that it is a
+function file, and that it defines a single function that should be
+evaluated as soon as it is defined.
+
+   A script file also differs from a function file in that the variables
+named in a script file are not local variables, but are in the same
+scope as the other variables that are visible on the command line.
+
+   Even though a script file may not begin with the `function' keyword,
+it is possible to define more than one function in a single script file
+and load (but not execute) all of them at once.  To do this, the first
+token in the file (ignoring comments and other white space) must be
+something other than `function'.  If you have no other statements to
+evaluate, you can use a statement that has no effect, like this:
+
+     # Prevent Octave from thinking that this
+     # is a function file:
+
+     1;
+
+     # Define function one:
+
+     function one ()
+       ...
+
+   To have Octave read and compile these functions into an internal
+form, you need to make sure that the file is in Octave's load path
+(accessible through the `path' function), then simply type the base
+name of the file that contains the commands.  (Octave uses the same
+rules to search for script files as it does to search for function
+files.)
+
+   If the first token in a file (ignoring comments) is `function',
+Octave will compile the function and try to execute it, printing a
+message warning about any non-whitespace characters that appear after
+the function definition.
+
+   Note that Octave does not try to look up the definition of any
+identifier until it needs to evaluate it.  This means that Octave will
+compile the following statements if they appear in a script file, or
+are typed at the command line,
+
+     # not a function file:
+     1;
+     function foo ()
+       do_something ();
+     endfunction
+     function do_something ()
+       do_something_else ();
+     endfunction
+
+even though the function `do_something' is not defined before it is
+referenced in the function `foo'.  This is not an error because Octave
+does not need to resolve all symbols that are referenced by a function
+until the function is actually evaluated.
+
+   Since Octave doesn't look for definitions until they are needed, the
+following code will always print `bar = 3' whether it is typed directly
+on the command line, read from a script file, or is part of a function
+body, even if there is a function or script file called `bar.m' in
+Octave's path.
+
+     eval ("bar = 3");
+     bar
+
+   Code like this appearing within a function body could fool Octave if
+definitions were resolved as the function was being compiled.  It would
+be virtually impossible to make Octave clever enough to evaluate this
+code in a consistent fashion.  The parser would have to be able to
+perform the call to `eval' at compile time, and that would be
+impossible unless all the references in the string to be evaluated could
+also be resolved, and requiring that would be too restrictive (the
+string might come from user input, or depend on things that are not
+known until the function is evaluated).
+
+   Although Octave normally executes commands from script files that
+have the name `FILE.m', you can use the function `source' to execute
+commands from any file.
+
+ -- Built-in Function:  source (FILE)
+     Parse and execute the contents of FILE.  This is equivalent to
+     executing commands from a script file, but without requiring the
+     file to be named `FILE.m'.
+
+
+File: octave.info,  Node: Function Handles Inline Functions and Anonymous Functions,  Next: Commands,  Prev: Script Files,  Up: Functions and Scripts
+
+11.9 Function Handles, Inline Functions, and Anonymous Functions
+================================================================
+
+It can be very convenient store a function in a variable so that it can
+be passed to a different function.  For example, a function that
+performs numerical minimization needs access to the function that
+should be minimized.
+
+* Menu:
+
+* Function Handles::
+* Anonymous Functions::
+* Inline Functions::
+
+
+File: octave.info,  Node: Function Handles,  Next: Anonymous Functions,  Up: Function Handles Inline Functions and Anonymous Functions
+
+11.9.1 Function Handles
+-----------------------
+
+A function handle is a pointer to another function and is defined with
+the syntax
+
+     @FUNCTION-NAME
+
+For example
+
+     f = @sin;
+
+Creates a function handle called `f' that refers to the function `sin'.
+
+   Function handles are used to call other functions indirectly, or to
+pass a function as an argument to another function like `quad' or
+`fsolve'.  For example
+
+     f = @sin;
+     quad (f, 0, pi)
+         => 2
+
+   You may use `feval' to call a function using function handle, or
+simply write the name of the function handle followed by an argument
+list.  If there are no arguments, you must use an empty argument list
+`()'.  For example
+
+     f = @sin;
+     feval (f, pi/4)
+         => 0.70711
+     f (pi/4)
+         => 0.70711
+
+ -- Built-in Function:  functions (FCN_HANDLE)
+     Return a struct containing information about the function handle
+     FCN_HANDLE.
+
+ -- Built-in Function:  func2str (FCN_HANDLE)
+     Return a string containing the name of the function referenced by
+     the function handle FCN_HANDLE.
+
+ -- Built-in Function:  str2func (FCN_NAME)
+     Return a function handle constructed from the string FCN_NAME.
+
+
+File: octave.info,  Node: Anonymous Functions,  Next: Inline Functions,  Prev: Function Handles,  Up: Function Handles Inline Functions and Anonymous Functions
+
+11.9.2 Anonymous Functions
+--------------------------
+
+Anonymous functions are defined using the syntax
+
+     @(ARGUMENT-LIST) EXPRESSION
+
+Any variables that are not found in the argument list are inherited from
+the enclosing scope.  Anonymous functions are useful for creating simple
+unnamed functions from expressions or for wrapping calls to other
+functions to adapt them for use by functions like `quad'.  For example,
+
+     f = @(x) x.^2;
+     quad (f, 0, 10)
+         => 333.33
+
+creates a simple unnamed function from the expression `x.^2' and passes
+it to `quad',
+
+     quad (@(x) sin (x), 0, pi)
+         => 2
+
+wraps another function, and
+
+     a = 1;
+     b = 2;
+     quad (@(x) betainc (x, a, b), 0, 0.4)
+         => 0.13867
+
+adapts a function with several parameters to the form required by
+`quad'.  In this example, the values of A and B that are passed to
+`betainc' are inherited from the current environment.
+
+
+File: octave.info,  Node: Inline Functions,  Prev: Anonymous Functions,  Up: Function Handles Inline Functions and Anonymous Functions
+
+11.9.3 Inline Functions
+-----------------------
+
+An inline function is created from a string containing the function
+body using the `inline' function.  The following code defines the
+function f(x) = x^2 + 2.
+
+     f = inline("x^2 + 2");
+
+After this it is possible to evaluate f at any x by writing `f(x)'.
+
+ -- Built-in Function:  inline (STR)
+ -- Built-in Function:  inline (STR, ARG1, ...)
+ -- Built-in Function:  inline (STR, N)
+     Create an inline function from the character string STR.  If
+     called with a single argument, the arguments of the generated
+     function are extracted from the function itself.  The generated
+     function arguments will then be in alphabetical order.  It should
+     be noted that i, and j are ignored as arguments due to the
+     ambiguity between their use as a variable or their use as an
+     inbuilt constant.  All arguments followed by a parenthesis are
+     considered to be functions.
+
+     If the second and subsequent arguments are character strings, they
+     are the names of the arguments of the function.
+
+     If the second argument is an integer N, the arguments are `"x"',
+     `"P1"', ..., `"PN"'.
+
+     *See also:* *note argnames: doc-argnames, *note formula:
+     doc-formula, *note vectorize: doc-vectorize.
+
+ -- Built-in Function:  argnames (FUN)
+     Return a cell array of character strings containing the names of
+     the arguments of the inline function FUN.
+
+     *See also:* *note inline: doc-inline, *note formula: doc-formula,
+     *note vectorize: doc-vectorize.
+
+ -- Built-in Function:  formula (FUN)
+     Return a character string representing the inline function FUN.
+     Note that `char (FUN)' is equivalent to `formula (FUN)'.
+
+     *See also:* *note argnames: doc-argnames, *note inline:
+     doc-inline, *note vectorize: doc-vectorize.
+
+ -- Built-in Function:  vectorize (FUN)
+     Create a vectorized version of the inline function FUN by
+     replacing all occurrences of `*', `/', etc., with `.*', `./', etc.
+
+ -- Function File:  symvar (S)
+     Identifies the argument names in the function defined by a string.
+     Common constant names such as `pi', `NaN', `Inf', `eps', `i' or
+     `j' are ignored.  The arguments that are found are returned in a
+     cell array of strings.  If no variables are found then the
+     returned cell array is empty.
+
+
+File: octave.info,  Node: Commands,  Next: Organization of Functions,  Prev: Function Handles Inline Functions and Anonymous Functions,  Up: Functions and Scripts
+
+11.10 Commands
+==============
+
+Commands are a special class of functions that only accept string input
+arguments.  A command can be called as an ordinary function, but it can
+also be called without the parentheses like the following example shows
+
+     my_command hello world
+
+which is the same as
+
+     my_command("hello", "world")
+
+   The general form of a command call is
+
+     NAME ARG1 ARG2 ...
+
+which translates directly to
+
+     NAME ("ARG1", "ARG2", ...)
+
+   A function can be used as a command if it accepts string input
+arguments.  To do this, the function must be marked as a command, which
+can be done with the `mark_as_command' command like this
+
+     mark_as_command name
+
+where `name' is the function to be marked as a command.
+
+   One difficulty of commands occurs when one of the string input
+arguments are stored in a variable.  Since Octave can't tell the
+difference between a variable name, and an ordinary string, it is not
+possible to pass a variable as input to a command.  In such a situation
+a command must be called as a function.
+
+ -- Built-in Function:  mark_as_command (NAME)
+     This function is obsolete and will be removed from a future
+     version of Octave.
+
+ -- Built-in Function:  unmark_command (NAME)
+     This function is obsolete and will be removed from a future
+     version of Octave.
+
+ -- Built-in Function:  iscommand (NAME)
+     This function is obsolete and will be removed from a future
+     version of Octave.
+
+ -- Built-in Function:  mark_as_rawcommand (NAME)
+     This function is obsolete and will be removed from a future
+     version of Octave.
+
+ -- Built-in Function:  unmark_rawcommand (NAME)
+     This function is obsolete and will be removed from a future
+     version of Octave.
+
+ -- Built-in Function:  israwcommand (NAME)
+     This function is obsolete and will be removed from a future
+     version of Octave.
+
+
+File: octave.info,  Node: Organization of Functions,  Prev: Commands,  Up: Functions and Scripts
+
+11.11 Organization of Functions Distributed with Octave
+=======================================================
+
+Many of Octave's standard functions are distributed as function files.
+They are loosely organized by topic, in subdirectories of
+`OCTAVE-HOME/lib/octave/VERSION/m', to make it easier to find them.
+
+   The following is a list of all the function file subdirectories, and
+the types of functions you will find there.
+
+`audio'
+     Functions for playing and recording sounds.
+
+`control'
+     Functions for design and simulation of automatic control systems.
+
+`elfun'
+     Elementary functions.
+
+`finance'
+     Functions for computing interest payments, investment values, and
+     rates of return.
+
+`general'
+     Miscellaneous matrix manipulations, like `flipud', `rot90', and
+     `triu', as well as other basic functions, like `ismatrix',
+     `nargchk', etc.
+
+`image'
+     Image processing tools.  These functions require the X Window
+     System.
+
+`io'
+     Input-output functions.
+
+`linear-algebra'
+     Functions for linear algebra.
+
+`miscellaneous'
+     Functions that don't really belong anywhere else.
+
+`optimization'
+     Minimization of functions.
+
+`path'
+     Functions to manage the directory path Octave uses to find
+     functions.
+
+`pkg'
+     Install external packages of functions in Octave.
+
+`plot'
+     Functions for displaying and printing two- and three-dimensional
+     graphs.
+
+`polynomial'
+     Functions for manipulating polynomials.
+
+`set'
+     Functions for creating and manipulating sets of unique values.
+
+`signal'
+     Functions for signal processing applications.
+
+`sparse'
+     Functions for handling sparse matrices.
+
+`specfun'
+     Special functions.
+
+`special-matrix'
+     Functions that create special matrix forms.
+
+`startup'
+     Octave's system-wide startup file.
+
+`statistics'
+     Statistical functions.
+
+`strings'
+     Miscellaneous string-handling functions.
+
+`testfun'
+     Perform unit tests on other functions.
+
+`time'
+     Functions related to time keeping.
+
+
+File: octave.info,  Node: Errors and Warnings,  Next: Debugging,  Prev: Functions and Scripts,  Up: Top
+
+12 Errors and Warnings
+**********************
+
+Octave includes several functions for printing error and warning
+messages.  When you write functions that need to take special action
+when they encounter abnormal conditions, you should print the error
+messages using the functions described in this chapter.
+
+   Since many of Octave's functions use these functions, it is also
+useful to understand them, so that errors and warnings can be handled.
+
+* Menu:
+
+* Handling Errors::
+* Handling Warnings::
+
+
+File: octave.info,  Node: Handling Errors,  Next: Handling Warnings,  Up: Errors and Warnings
+
+12.1 Handling Errors
+====================
+
+An error is something that occurs when a program is in a state where it
+doesn't make sense to continue.  An example is when a function is
+called with too few input arguments.  In this situation the function
+should abort with an error message informing the user of the lacking
+input arguments.
+
+   Since an error can occur during the evaluation of a program, it is
+very convenient to be able to detect that an error occurred, so that
+the error can be fixed.  This is possible with the `try' statement
+described in *note The `try' Statement::.
+
+* Menu:
+
+* Raising Errors::
+* Catching Errors::
+
+
+File: octave.info,  Node: Raising Errors,  Next: Catching Errors,  Up: Handling Errors
+
+12.1.1 Raising Errors
+---------------------
+
+The most common use of errors is for checking input arguments to
+functions.  The following example calls the `error' function if the
+function `f' is called without any input arguments.
+
+     function f (arg1)
+       if (nargin == 0)
+         error("not enough input arguments");
+       endif
+     endfunction
+
+   When the `error' function is called, it prints the given message and
+returns to the Octave prompt.  This means that no code following a call
+to `error' will be executed.
+
+ -- Built-in Function:  error (TEMPLATE, ...)
+ -- Built-in Function:  error (ID, TEMPLATE, ...)
+     Format the optional arguments under the control of the template
+     string TEMPLATE using the same rules as the `printf' family of
+     functions (*note Formatted Output::) and print the resulting
+     message on the `stderr' stream.  The message is prefixed by the
+     character string `error: '.
+
+     Calling `error' also sets Octave's internal error state such that
+     control will return to the top level without evaluating any more
+     commands.  This is useful for aborting from functions or scripts.
+
+     If the error message does not end with a new line character,
+     Octave will print a traceback of all the function calls leading to
+     the error.  For example, given the following function definitions:
+
+          function f () g (); end
+          function g () h (); end
+          function h () nargin == 1 || error ("nargin != 1"); end
+
+     calling the function `f' will result in a list of messages that
+     can help you to quickly locate the exact location of the error:
+
+          f ()
+          error: nargin != 1
+          error: called from:
+          error:   error at line -1, column -1
+          error:   h at line 1, column 27
+          error:   g at line 1, column 15
+          error:   f at line 1, column 15
+
+     If the error message ends in a new line character, Octave will
+     print the message but will not display any traceback messages as
+     it returns control to the top level.  For example, modifying the
+     error message in the previous example to end in a new line causes
+     Octave to only print a single message:
+
+          function h () nargin == 1 || error ("nargin != 1\n"); end
+          f ()
+          error: nargin != 1
+
+   Since it is common to use errors when there is something wrong with
+the input to a function, Octave supports functions to simplify such
+code.  When the `print_usage' function is called, it reads the help text
+of the function calling `print_usage', and presents a useful error.  If
+the help text is written in Texinfo it is possible to present an error
+message that only contains the function prototypes as described by the
+`@deftypefn' parts of the help text.  When the help text isn't written
+in Texinfo, the error message contains the entire help message.
+
+   Consider the following function.
+     ## -*- texinfo -*-
+     ## @deftypefn {Function File} f (@var{arg1})
+     ## Function help text goes here...
+     ## @end deftypefn
+     function f (arg1)
+       if (nargin == 0)
+         print_usage ();
+       endif
+     endfunction
+
+When it is called with no input arguments it produces the following
+error.
+
+     f ()
+
+     -|  error: Invalid call to f.  Correct usage is:
+     -|
+     -|   -- Function File: f (ARG1)
+     -|
+     -|
+     -|  Additional help for built-in functions and operators is
+     -|  available in the on-line version of the manual.  Use the command
+     -|  `doc <topic>' to search the manual index.
+     -|
+     -|  Help and information about Octave is also available on the WWW
+     -|  at http://www.octave.org and via the help at octave.org
+     -|  mailing list.
+
+ -- Function File:  print_usage ()
+ -- Function File:  print_usage (NAME)
+     Print the usage message for a function.  When called with no input
+     arguments the `print_usage' function displays the usage message of
+     the currently executing function.
+
+     *See also:* *note help: doc-help.
+
+ -- Built-in Function:  usage (MSG)
+     Print the message MSG, prefixed by the string `usage: ', and set
+     Octave's internal error state such that control will return to the
+     top level without evaluating any more commands.  This is useful for
+     aborting from functions.
+
+     After `usage' is evaluated, Octave will print a traceback of all
+     the function calls leading to the usage message.
+
+     You should use this function for reporting problems errors that
+     result from an improper call to a function, such as calling a
+     function with an incorrect number of arguments, or with arguments
+     of the wrong type.  For example, most functions distributed with
+     Octave begin with code like this
+
+          if (nargin != 2)
+            usage ("foo (a, b)");
+          endif
+
+     to check for the proper number of arguments.
+
+ -- Function File:  beep ()
+     Produce a beep from the speaker (or visual bell).
+
+     *See also:* *note puts: doc-puts, *note fputs: doc-fputs, *note
+     printf: doc-printf, *note fprintf: doc-fprintf.
+
+ -- Built-in Function: VAL = beep_on_error ()
+ -- Built-in Function: OLD_VAL = beep_on_error (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will try to ring the terminal bell before printing an error
+     message.
+
+
+File: octave.info,  Node: Catching Errors,  Prev: Raising Errors,  Up: Handling Errors
+
+12.1.2 Catching Errors
+----------------------
+
+When an error occurs, it can be detected and handled using the `try'
+statement as described in *note The `try' Statement::.  As an example,
+the following piece of code counts the number of errors that occurs
+during a `for' loop.
+
+     number_of_errors = 0;
+     for n = 1:100
+       try
+         ...
+       catch
+         number_of_errors++;
+       end_try_catch
+     endfor
+
+   The above example treats all errors the same.  In many situations it
+can however be necessary to discriminate between errors, and take
+different actions depending on the error.  The `lasterror' function
+returns a structure containing information about the last error that
+occurred.  As an example, the code above could be changed to count the
+number of errors related to the `*' operator.
+
+     number_of_errors = 0;
+     for n = 1:100
+       try
+         ...
+       catch
+         msg = lasterror.message;
+         if (strfind (msg, "operator *"))
+           number_of_errors++;
+         endif
+       end_try_catch
+     endfor
+
+ -- Built-in Function: ERR = lasterror (ERR)
+ -- Built-in Function:  lasterror ('reset')
+     Returns or sets the last error message.  Called without any
+     arguments returns a structure containing the last error message,
+     as well as other information related to this error.  The elements
+     of this structure are:
+
+    'message'
+          The text of the last error message
+
+    'identifier'
+          The message identifier of this error message
+
+    'stack'
+          A structure containing information on where the message
+          occurred.  This might be an empty structure if this in the
+          case where this information cannot be obtained.  The fields
+          of this structure are:
+
+         'file'
+               The name of the file where the error occurred
+
+         'name'
+               The name of function in which the error occurred
+
+         'line'
+               The line number at which the error occurred
+
+         'column'
+               An optional field with the column number at which the
+               error occurred
+
+     The ERR structure may also be passed to `lasterror' to set the
+     information about the last error.  The only constraint on ERR in
+     that case is that it is a scalar structure.  Any fields of ERR
+     that match the above are set to the value passed in ERR, while
+     other fields are set to their default values.
+
+     If `lasterror' is called with the argument 'reset', all values take
+     their default values.
+
+ -- Built-in Function: [MSG, MSGID] = lasterr (MSG, MSGID)
+     Without any arguments, return the last error message.  With one
+     argument, set the last error message to MSG.  With two arguments,
+     also set the last message identifier.
+
+   When an error has been handled it is possible to raise it again.
+This can be useful when an error needs to be detected, but the program
+should still abort.  This is possible using the `rethrow' function.  The
+previous example can now be changed to count the number of errors
+related to the `*' operator, but still abort if another kind of error
+occurs.
+
+     number_of_errors = 0;
+     for n = 1:100
+       try
+         ...
+       catch
+         msg = lasterror.message;
+         if (strfind (msg, "operator *"))
+           number_of_errors++;
+         else
+           rethrow (lasterror);
+         endif
+       end_try_catch
+     endfor
+
+ -- Built-in Function:  rethrow (ERR)
+     Reissues a previous error as defined by ERR.  ERR is a structure
+     that must contain at least the 'message' and 'identifier' fields.
+     ERR can also contain a field 'stack' that gives information on the
+     assumed location of the error.  Typically ERR is returned from
+     `lasterror'.
+
+     *See also:* *note lasterror: doc-lasterror, *note lasterr:
+     doc-lasterr, *note error: doc-error.
+
+ -- Built-in Function: ERR = errno ()
+ -- Built-in Function: ERR = errno (VAL)
+ -- Built-in Function: ERR = errno (NAME)
+     Return the current value of the system-dependent variable errno,
+     set its value to VAL and return the previous value, or return the
+     named error code given NAME as a character string, or -1 if NAME
+     is not found.
+
+ -- Built-in Function:  errno_list ()
+     Return a structure containing the system-dependent errno values.
+
+
+File: octave.info,  Node: Handling Warnings,  Prev: Handling Errors,  Up: Errors and Warnings
+
+12.2 Handling Warnings
+======================
+
+Like an error, a warning is issued when something unexpected happens.
+Unlike an error, a warning doesn't abort the currently running program.
+A simple example of a warning is when a number is divided by zero.  In
+this case Octave will issue a warning and assign the value `Inf' to the
+result.
+
+     a = 1/0
+          -| warning: division by zero
+          => a = Inf
+
+* Menu:
+
+* Issuing Warnings::
+* Enabling and Disabling Warnings::
+
+
+File: octave.info,  Node: Issuing Warnings,  Next: Enabling and Disabling Warnings,  Up: Handling Warnings
+
+12.2.1 Issuing Warnings
+-----------------------
+
+It is possible to issue warnings from any code using the `warning'
+function.  In its most simple form, the `warning' function takes a
+string describing the warning as its input argument.  As an example,
+the following code controls if the variable `a' is non-negative, and if
+not issues a warning and sets `a' to zero.
+
+     a = -1;
+     if (a < 0)
+       warning ("'a' must be non-negative.  Setting 'a' to zero.");
+       a = 0;
+     endif
+          -| 'a' must be non-negative.  Setting 'a' to zero.
+
+   Since warnings aren't fatal to a running program, it is not possible
+to catch a warning using the `try' statement or something similar.  It
+is however possible to access the last warning as a string using the
+`lastwarn' function.
+
+   It is also possible to assign an identification string to a warning.
+If a warning has such an ID the user can enable and disable this warning
+as will be described in the next section.  To assign an ID to a warning,
+simply call `warning' with two string arguments, where the first is the
+identification string, and the second is the actual warning.
+
+ -- Built-in Function:  warning (TEMPLATE, ...)
+ -- Built-in Function:  warning (ID, TEMPLATE, ...)
+     Format the optional arguments under the control of the template
+     string TEMPLATE using the same rules as the `printf' family of
+     functions (*note Formatted Output::) and print the resulting
+     message on the `stderr' stream.  The message is prefixed by the
+     character string `warning: '.  You should use this function when
+     you want to notify the user of an unusual condition, but only when
+     it makes sense for your program to go on.
+
+     The optional message identifier allows users to enable or disable
+     warnings tagged by ID.  The special identifier `"all"' may be used
+     to set the state of all warnings.
+
+ -- Built-in Function:  warning ("on", ID)
+ -- Built-in Function:  warning ("off", ID)
+ -- Built-in Function:  warning ("error", ID)
+ -- Built-in Function:  warning ("query", ID)
+     Set or query the state of a particular warning using the identifier
+     ID.  If the identifier is omitted, a value of `"all"' is assumed.
+     If you set the state of a warning to `"error"', the warning named
+     by ID is handled as if it were an error instead.
+
+     *See also:* *note warning_ids: doc-warning_ids.
+
+ -- Built-in Function: [MSG, MSGID] = lastwarn (MSG, MSGID)
+     Without any arguments, return the last warning message.  With one
+     argument, set the last warning message to MSG.  With two arguments,
+     also set the last message identifier.
+
+
+File: octave.info,  Node: Enabling and Disabling Warnings,  Prev: Issuing Warnings,  Up: Handling Warnings
+
+12.2.2 Enabling and Disabling Warnings
+--------------------------------------
+
+The `warning' function also allows you to control which warnings are
+actually printed to the screen.  If the `warning' function is called
+with a string argument that is either `"on"' or `"off"' all warnings
+will be enabled or disabled.
+
+   It is also possible to enable and disable individual warnings through
+their string identifications.  The following code will issue a warning
+
+     warning ("non-negative-variable",
+              "'a' must be non-negative.  Setting 'a' to zero.");
+
+while the following won't issue a warning
+
+     warning ("off", "non-negative-variable");
+     warning ("non-negative-variable",
+              "'a' must be non-negative.  Setting 'a' to zero.");
+
+   The functions distributed with Octave can issue one of the following
+warnings.
+
+`Octave:array-to-scalar'
+     If the `Octave:array-to-scalar' warning is enabled, Octave will
+     warn when an implicit conversion from an array to a scalar value is
+     attempted.  By default, the `Octave:array-to-scalar' warning is
+     disabled.
+
+`Octave:array-to-vector'
+     If the `Octave:array-to-vector' warning is enabled, Octave will
+     warn when an implicit conversion from an array to a vector value is
+     attempted.  By default, the `Octave:array-to-vector' warning is
+     disabled.
+
+`Octave:assign-as-truth-value'
+     If the `Octave:assign-as-truth-value' warning is enabled, a
+     warning is issued for statements like
+
+          if (s = t)
+            ...
+
+     since such statements are not common, and it is likely that the
+     intent was to write
+
+          if (s == t)
+            ...
+
+     instead.
+
+     There are times when it is useful to write code that contains
+     assignments within the condition of a `while' or `if' statement.
+     For example, statements like
+
+          while (c = getc())
+            ...
+
+     are common in C programming.
+
+     It is possible to avoid all warnings about such statements by
+     disabling the `Octave:assign-as-truth-value' warning, but that may
+     also let real errors like
+
+          if (x = 1)  # intended to test (x == 1)!
+            ...
+
+     slip by.
+
+     In such cases, it is possible suppress errors for specific
+     statements by writing them with an extra set of parentheses.  For
+     example, writing the previous example as
+
+          while ((c = getc()))
+            ...
+
+     will prevent the warning from being printed for this statement,
+     while allowing Octave to warn about other assignments used in
+     conditional contexts.
+
+     By default, the `Octave:assign-as-truth-value' warning is enabled.
+
+`Octave:associativity-change'
+     If the `Octave:associativity-change' warning is enabled, Octave
+     will warn about possible changes in the meaning of some code due
+     to changes in associativity for some operators.  Associativity
+     changes have typically been made for MATLAB compatibility.  By
+     default, the `Octave:associativity-change' warning is enabled.
+
+`Octave:divide-by-zero'
+     If the `Octave:divide-by-zero' warning is enabled, a warning is
+     issued when Octave encounters a division by zero.  By default, the
+     `Octave:divide-by-zero' warning is enabled.
+
+`Octave:empty-list-elements'
+     If the `Octave:empty-list-elements' warning is enabled, a warning
+     is issued when an empty matrix is found in a matrix list.  For
+     example,
+
+          a = [1, [], 3, [], 5]
+
+     By default, the `Octave:empty-list-elements' warning is enabled.
+
+`Octave:fortran-indexing'
+     If the `Octave:fortran-indexing' warning is enabled, a warning is
+     printed for expressions which select elements of a two-dimensional
+     matrix using a single index.  By default, the
+     `Octave:fortran-indexing' warning is disabled.
+
+`Octave:function-name-clash'
+     If the `Octave:function-name-clash' warning is enabled, a warning
+     is issued when Octave finds that the name of a function defined in
+     a function file differs from the name of the file.  (If the names
+     disagree, the name declared inside the file is ignored.)  By
+     default, the `Octave:function-name-clash' warning is enabled.
+
+`Octave:future-time-stamp'
+     If the `Octave:future-time-stamp' warning is enabled, Octave will
+     print a warning if it finds a function file with a time stamp that
+     is in the future.  By default, the `Octave:future-time-stamp'
+     warning is enabled.
+
+`Octave:imag-to-real'
+     If the `Octave:imag-to-real' warning is enabled, a warning is
+     printed for implicit conversions of complex numbers to real
+     numbers.  By default, the `Octave:imag-to-real' warning is
+     disabled.
+
+`Octave:matlab-incompatible'
+     Print warnings for Octave language features that may cause
+     compatibility problems with MATLAB.
+
+`Octave:missing-semicolon'
+     If the `Octave:missing-semicolon' warning is enabled, Octave will
+     warn when statements in function definitions don't end in
+     semicolons.  By default the `Octave:missing-semicolon' warning is
+     disabled.
+
+`Octave:neg-dim-as-zero'
+     If the `Octave:neg-dim-as-zero' warning is enabled, print a warning
+     for expressions like
+
+          eye (-1)
+
+     By default, the `Octave:neg-dim-as-zero' warning is disabled.
+
+`Octave:num-to-str'
+     If the `Octave:num-to-str' warning is enable, a warning is printed
+     for implicit conversions of numbers to their ASCII character
+     equivalents when strings are constructed using a mixture of
+     strings and numbers in matrix notation.  For example,
+
+          [ "f", 111, 111 ]
+               => "foo"
+     elicits a warning if the `Octave:num-to-str' warning is enabled.
+     By default, the `Octave:num-to-str' warning is enabled.
+
+`Octave:precedence-change'
+     If the `Octave:precedence-change' warning is enabled, Octave will
+     warn about possible changes in the meaning of some code due to
+     changes in precedence for some operators.  Precedence changes have
+     typically been made for MATLAB compatibility.  By default, the
+     `Octave:precedence-change' warning is enabled.
+
+`Octave:reload-forces-clear'
+     If several functions have been loaded from the same file, Octave
+     must clear all the functions before any one of them can be
+     reloaded.  If the `Octave:reload-forces-clear' warning is enabled,
+     Octave will warn you when this happens, and print a list of the
+     additional functions that it is forced to clear.  By default, the
+     `Octave:reload-forces-clear' warning is enabled.
+
+`Octave:resize-on-range-error'
+     If the `Octave:resize-on-range-error' warning is enabled, print a
+     warning when a matrix is resized by an indexed assignment with
+     indices outside the current bounds.  By default, the
+     `Octave:resize-on-range-error' warning is disabled.
+
+`Octave:separator-insert'
+     Print warning if commas or semicolons might be inserted
+     automatically in literal matrices.
+
+`Octave:single-quote-string'
+     Print warning if a single quote character is used to introduce a
+     string constant.
+
+`Octave:str-to-num'
+     If the `Octave:str-to-num' warning is enabled, a warning is printed
+     for implicit conversions of strings to their numeric ASCII
+     equivalents.  For example,
+          "abc" + 0
+               => 97 98 99
+     elicits a warning if the `Octave:str-to-num' warning is enabled.
+     By default, the `Octave:str-to-num' warning is disabled.
+
+`Octave:string-concat'
+     If the `Octave:string-concat' warning is enabled, print a warning
+     when concatenating a mixture of double and single quoted strings.
+     By default, the `Octave:string-concat' warning is disabled.
+
+`Octave:undefined-return-values'
+     If the `Octave:undefined-return-values' warning is disabled, print
+     a warning if a function does not define all the values in the
+     return list which are expected.  By default, the
+     `Octave:undefined-return-values' warning is enabled.
+
+`Octave:variable-switch-label'
+     If the `Octave:variable-switch-label' warning is enabled, Octave
+     will print a warning if a switch label is not a constant or
+     constant expression.  By default, the
+     `Octave:variable-switch-label' warning is disabled.
+
+
+File: octave.info,  Node: Debugging,  Next: Input and Output,  Prev: Errors and Warnings,  Up: Top
+
+13 Debugging
+************
+
+Octave includes a built-in debugger to aid in the development of
+scripts.  This can be used to interrupt the execution of an Octave
+script at a certain point, or when certain conditions are met.  Once
+execution has stopped, and debug mode is entered, the symbol table at
+the point where execution has stopped can be examined and modified to
+check for errors.
+
+   The normal command-line editing and history functions are available
+in debug mode.
+
+* Menu:
+
+* Entering Debug Mode::
+* Leaving Debug Mode::
+* Breakpoints::
+* Debug Mode::
+* Call Stack::
+
+
+File: octave.info,  Node: Entering Debug Mode,  Next: Leaving Debug Mode,  Up: Debugging
+
+13.1 Entering Debug Mode
+========================
+
+There are two basic means of interrupting the execution of an Octave
+script.  These are breakpoints *note Breakpoints::, discussed in the
+next section and interruption based on some condition.
+
+   Octave supports three means to stop execution based on the values
+set in the functions `debug_on_interrupt', `debug_on_warning' and
+`debug_on_error'.
+
+ -- Built-in Function: VAL = debug_on_interrupt ()
+ -- Built-in Function: OLD_VAL = debug_on_interrupt (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will try to enter debugging mode when it receives an interrupt
+     signal (typically generated with `C-c').  If a second interrupt
+     signal is received before reaching the debugging mode, a normal
+     interrupt will occur.
+
+ -- Built-in Function: VAL = debug_on_warning ()
+ -- Built-in Function: OLD_VAL = debug_on_warning (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will try to enter the debugger when a warning is encountered.
+
+ -- Built-in Function: VAL = debug_on_error ()
+ -- Built-in Function: OLD_VAL = debug_on_error (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will try to enter the debugger when an error is encountered.  This
+     will also inhibit printing of the normal traceback message (you
+     will only see the top-level error message).
+
+
+File: octave.info,  Node: Leaving Debug Mode,  Next: Breakpoints,  Prev: Entering Debug Mode,  Up: Debugging
+
+13.2 Leavinging Debug Mode
+==========================
+
+To leave the debug mode, use either `dbcont' or `return'.
+
+ -- Command:  dbcont ()
+     In debugging mode, quit debugging mode and continue execution.
+
+     *See also:* *note dbstep: doc-dbstep, *note dbstep: doc-dbstep.
+
+   To quit debug mode and return directly to the prompt `dbquit' should
+be used instead
+
+ -- Command:  dbquit ()
+     In debugging mode, quit debugging mode and return to the top level.
+
+     *See also:* *note dbstep: doc-dbstep, *note dbcont: doc-dbcont.
+
+   Finally, typing `exit' or `quit' at the debug prompt will result in
+Octave terminating normally.
+
+
+File: octave.info,  Node: Breakpoints,  Next: Debug Mode,  Prev: Leaving Debug Mode,  Up: Debugging
+
+13.3 Breakpoints
+================
+
+Breakpoints can be set in any Octave function, using the `dbstop'
+function.
+
+ -- Loadable Function: RLINE = dbstop (FUNC, LINE, ...)
+     Set a breakpoint in a function
+    `func'
+          String representing the function name.  When already in debug
+          mode this should be left out and only the line should be
+          given.
+
+    `line'
+          Line number you would like the breakpoint to be set on.
+          Multiple lines might be given as separate arguments or as a
+          vector.
+
+     The rline returned is the real line that the breakpoint was set at.
+
+     *See also:* *note dbclear: doc-dbclear, *note dbstatus:
+     doc-dbstatus, *note dbstep: doc-dbstep.
+
+Note that breakpoints cannot be set in built-in functions (e.g., `sin',
+etc.) or dynamically loaded function (i.e., oct-files).  To set a
+breakpoint immediately on entering a function, the breakpoint should be
+set to line 1. The leading comment block will be ignored and the
+breakpoint will be set to the first executable statement in the
+function.  For example
+
+     dbstop ("asind", 1)
+     => 27
+
+Note that the return value of `27' means that the breakpoint was
+effectively set to line 27.  The status of breakpoints in a function can
+be queried with the `dbstatus' function.
+
+ -- Loadable Function: lst = dbstatus (FUNC)
+     Return a vector containing the lines on which a function has
+     breakpoints set.
+    `func'
+          String representing the function name.  When already in debug
+          mode this should be left out.
+
+     *See also:* *note dbclear: doc-dbclear, *note dbwhere: doc-dbwhere.
+
+Taking the above as an example, `dbstatus ("asind")' should return 27.
+The breakpoints can then be cleared with the `dbclear' function
+
+ -- Loadable Function:  dbclear (FUNC, LINE, ...)
+     Delete a breakpoint in a function
+    `func'
+          String representing the function name.  When already in debug
+          mode this should be left out and only the line should be
+          given.
+
+    `line'
+          Line number where you would like to remove the breakpoint.
+          Multiple lines might be given as separate arguments or as a
+          vector.
+     No checking is done to make sure that the line you requested is
+     really a breakpoint.  If you get the wrong line nothing will
+     happen.
+
+     *See also:* *note dbstop: doc-dbstop, *note dbstatus:
+     doc-dbstatus, *note dbwhere: doc-dbwhere.
+
+These functions can be used to clear all the breakpoints in a function.
+For example,
+
+     dbclear ("asind", dbstatus ("asind"));
+
+   A breakpoint can be set in a subfunction.  For example if a file
+contains the functions
+
+     function y = func1 (x)
+       y = func2 (x);
+     endfunction
+     function y = func2 (x)
+       y = x + 1;
+     endfunction
+
+then a breakpoint can be set at the start of the subfunction directly
+with
+
+     dbstop (["func1", filemarker(), "func2"])
+     => 5
+
+   Note that `filemarker' returns a character that marks the
+subfunctions from the file containing them.
+
+   Another simple way of setting a breakpoint in an Octave script is the
+use of the `keyboard' function.
+
+ -- Built-in Function:  keyboard ()
+ -- Built-in Function:  keyboard (PROMPT)
+     This function is normally used for simple debugging.  When the
+     `keyboard' function is executed, Octave prints a prompt and waits
+     for user input.  The input strings are then evaluated and the
+     results are printed.  This makes it possible to examine the values
+     of variables within a function, and to assign new values if
+     necessary.  To leave the prompt and return to normal execution
+     type `return' or `dbcont'.  The `keyboard' function does not
+     return an exit status.
+
+     If `keyboard' is invoked without arguments, a default prompt of
+     `debug> ' is used.
+
+     *See also:* *note dbcont: doc-dbcont, *note dbquit: doc-dbquit.
+
+The `keyboard' function is typically placed in a script at the point
+where the user desires that the execution is stopped.  It automatically
+sets the running script into the debug mode.
+
+
+File: octave.info,  Node: Debug Mode,  Next: Call Stack,  Prev: Breakpoints,  Up: Debugging
+
+13.4 Debug Mode
+===============
+
+There are two additional support functions that allow the user to
+interrogate where in the execution of a script Octave entered the debug
+mode and to print the code in the script surrounding the point where
+Octave entered debug mode.
+
+ -- Loadable Function:  dbwhere ()
+     Show where we are in the code
+
+     *See also:* *note dbclear: doc-dbclear, *note dbstatus:
+     doc-dbstatus, *note dbstop: doc-dbstop.
+
+ -- Loadable Function:  dbtype ()
+     List script file with line numbers.
+
+     *See also:* *note dbclear: doc-dbclear, *note dbstatus:
+     doc-dbstatus, *note dbstop: doc-dbstop.
+
+   You may also use `isdebugmode' to determine whether the debugger is
+currently active.
+
+ -- Command:  isdebugmode ()
+     Return true if debug mode is on, otherwise false.
+
+     *See also:* *note dbstack: doc-dbstack, *note dbclear:
+     doc-dbclear, *note dbstop: doc-dbstop, *note dbstatus:
+     doc-dbstatus.
+
+   Debug mode also allows single line stepping through a function using
+the commands `dbstep'.
+
+ -- Command:  dbstep N
+ -- Command:  dbstep in
+ -- Command:  dbstep out
+     In debugging mode, execute the next N lines of code.  If N is
+     omitted execute the next line of code.  If the next line of code
+     is itself defined in terms of an m-file remain in the existing
+     function.
+
+     Using `dbstep in' will cause execution of the next line to step
+     into any m-files defined on the next line.  Using `dbstep out'
+     with cause execution to continue until the current function
+     returns.
+
+     *See also:* *note dbcont: doc-dbcont, *note dbquit: doc-dbquit.
+
+
+File: octave.info,  Node: Call Stack,  Prev: Debug Mode,  Up: Debugging
+
+13.5 Call Stack
+===============
+
+ -- Loadable Function: [STACK, IDX] dbstack (N)
+     Print or return current stack information.  With optional argument
+     N, omit the N innermost stack frames.
+
+     *See also:* *note dbclear: doc-dbclear, *note dbstatus:
+     doc-dbstatus, *note dbstop: doc-dbstop.
+
+ -- Loadable Function:  dbup (N)
+     In debugging mode, move up the execution stack N frames.  If N is
+     omitted, move up one frame.
+
+     *See also:* *note dbstack: doc-dbstack.
+
+ -- Loadable Function:  dbdown (N)
+     In debugging mode, move down the execution stack N frames.  If N
+     is omitted, move down one frame.
+
+     *See also:* *note dbstack: doc-dbstack.
+
+
+File: octave.info,  Node: Input and Output,  Next: Plotting,  Prev: Debugging,  Up: Top
+
+14 Input and Output
+*******************
+
+Octave supports several ways of reading and writing data to or from the
+prompt or a file.  The simplest functions for data Input and Output
+(I/O) are easy to use, but only provides limited control of how data is
+processed.  For more control, a set of functions modelled after the C
+standard library are also provided by Octave.
+
+* Menu:
+
+* Basic Input and Output::
+* C-Style I/O Functions::
+
+
+File: octave.info,  Node: Basic Input and Output,  Next: C-Style I/O Functions,  Up: Input and Output
+
+14.1 Basic Input and Output
+===========================
+
+* Menu:
+
+* Terminal Output::
+* Terminal Input::
+* Simple File I/O::
+* Rational Approximations::
+
+
+File: octave.info,  Node: Terminal Output,  Next: Terminal Input,  Up: Basic Input and Output
+
+14.1.1 Terminal Output
+----------------------
+
+Since Octave normally prints the value of an expression as soon as it
+has been evaluated, the simplest of all I/O functions is a simple
+expression.  For example, the following expression will display the
+value of `pi'
+
+     pi
+          -| pi = 3.1416
+
+   This works well as long as it is acceptable to have the name of the
+variable (or `ans') printed along with the value.  To print the value
+of a variable without printing its name, use the function `disp'.
+
+   The `format' command offers some control over the way Octave prints
+values with `disp' and through the normal echoing mechanism.
+
+ -- Built-in Function:  disp (X)
+     Display the value of X.  For example,
+
+          disp ("The value of pi is:"), disp (pi)
+
+               -| the value of pi is:
+               -| 3.1416
+
+     Note that the output from `disp' always ends with a newline.
+
+     If an output value is requested, `disp' prints nothing and returns
+     the formatted output in a string.
+
+     *See also:* *note fdisp: doc-fdisp.
+
+ -- Command: format
+ -- Command: format options
+     Reset or specify the format of the output produced by `disp' and
+     Octave's normal echoing mechanism.  This command only affects the
+     display of numbers but not how they are stored or computed.  To
+     change the internal representation from the default double use one
+     of the conversion functions such as `single', `uint8', `int64',
+     etc.
+
+     By default, Octave displays 5 significant digits in a human
+     readable form (option `short' paired with `loose' format for
+     matrices).  If `format' is invoked without any options, this
+     default format is restored.
+
+     Valid formats for floating point numbers are listed in the
+     following table.
+
+    `short'
+          Fixed point format with 5 significant figures in a field that
+          is a maximum of 10 characters wide.  (default).
+
+          If Octave is unable to format a matrix so that columns line
+          up on the decimal point and all numbers fit within the
+          maximum field width then it switches to an exponential `e'
+          format.
+
+    `long'
+          Fixed point format with 15 significant figures in a field
+          that is a maximum of 20 characters wide.
+
+          As with the `short' format, Octave will switch to an
+          exponential `e' format if it is unable to format a matrix
+          properly using the current format.
+
+    `short e'
+    `long e'
+          Exponential format.  The number to be represented is split
+          between a mantissa and an exponent (power of 10).  The
+          mantissa has 5 significant digits in the short format and 15
+          digits in the long format.  For example, with the `short e'
+          format, `pi' is displayed as `3.1416e+00'.
+
+    `short E'
+    `long E'
+          Identical to `short e' or `long e' but displays an uppercase
+          `E' to indicate the exponent.  For example, with the `long E'
+          format, `pi' is displayed as `3.14159265358979E+00'.
+
+    `short g'
+    `long g'
+          Optimally choose between fixed point and exponential format
+          based on the magnitude of the number.  For example, with the
+          `short g' format, `pi .^ [2; 4; 8; 16; 32]' is displayed as
+
+               ans =
+
+                     9.8696
+                     97.409
+                     9488.5
+                 9.0032e+07
+                 8.1058e+15
+
+    `long G'
+    `short G'
+          Identical to `short g' or `long g' but displays an uppercase
+          `E' to indicate the exponent.
+
+    `free'
+    `none'
+          Print output in free format, without trying to line up
+          columns of matrices on the decimal point.  This also causes
+          complex numbers to be formatted as numeric pairs like this
+          `(0.60419, 0.60709)' instead of like this `0.60419 +
+          0.60709i'.
+
+     The following formats affect all numeric output (floating point and
+     integer types).
+
+    `+'
+    `+ CHARS'
+    `plus'
+    `plus CHARS'
+          Print a `+' symbol for nonzero matrix elements and a space
+          for zero matrix elements.  This format can be very useful for
+          examining the structure of a large sparse matrix.
+
+          The optional argument CHARS specifies a list of 3 characters
+          to use for printing values greater than zero, less than zero
+          and equal to zero.  For example, with the `+ "+-."' format,
+          `[1, 0, -1; -1, 0, 1]' is displayed as
+
+               ans =
+
+               +.-
+               -.+
+
+    `bank'
+          Print in a fixed format with two digits to the right of the
+          decimal point.
+
+    `native-hex'
+          Print the hexadecimal representation of numbers as they are
+          stored in memory.  For example, on a workstation which stores
+          8 byte real values in IEEE format with the least significant
+          byte first, the value of `pi' when printed in `native-hex'
+          format is `400921fb54442d18'.
+
+    `hex'
+          The same as `native-hex', but always print the most
+          significant byte first.
+
+    `native-bit'
+          Print the bit representation of numbers as stored in memory.
+          For example, the value of `pi' is
+
+               01000000000010010010000111111011
+               01010100010001000010110100011000
+
+          (shown here in two 32 bit sections for typesetting purposes)
+          when printed in native-bit format on a workstation which
+          stores 8 byte real values in IEEE format with the least
+          significant byte first.
+
+    `bit'
+          The same as `native-bit', but always print the most
+          significant bits first.
+
+    `rat'
+          Print a rational approximation, i.e., values are approximated
+          as the ratio of small integers.  For example, with the `rat'
+          format, `pi' is displayed as `355/113'.
+
+     The following two options affect the display of all matrices.
+
+    `compact'
+          Remove extra blank space around column number labels
+          producing more compact output with more data per page.
+
+    `loose'
+          Insert blank lines above and below column number labels to
+          produce a more readable output with less data per page.
+          (default).
+
+* Menu:
+
+* Paging Screen Output::
+
+
+File: octave.info,  Node: Paging Screen Output,  Up: Terminal Output
+
+14.1.1.1 Paging Screen Output
+.............................
+
+When running interactively, Octave normally sends any output intended
+for your terminal that is more than one screen long to a paging program,
+such as `less' or `more'.  This avoids the problem of having a large
+volume of output stream by before you can read it.  With `less' (and
+some versions of `more') you can also scan forward and backward, and
+search for specific items.
+
+   Normally, no output is displayed by the pager until just before
+Octave is ready to print the top level prompt, or read from the
+standard input (for example, by using the `fscanf' or `scanf'
+functions).  This means that there may be some delay before any output
+appears on your screen if you have asked Octave to perform a
+significant amount of work with a single command statement.  The
+function `fflush' may be used to force output to be sent to the pager
+(or any other stream) immediately.
+
+   You can select the program to run as the pager using the `PAGER'
+function, and you can turn paging off by using the function `more'.
+
+ -- Command: more
+ -- Command: more on
+ -- Command: more off
+     Turn output pagination on or off.  Without an argument, `more'
+     toggles the current state.  The current state can be determined
+     via `page_screen_output'.
+
+ -- Built-in Function: VAL = PAGER ()
+ -- Built-in Function: OLD_VAL = PAGER (NEW_VAL)
+     Query or set the internal variable that specifies the program to
+     use to display terminal output on your system.  The default value
+     is normally `"less"', `"more"', or `"pg"', depending on what
+     programs are installed on your system.  *Note Installation::.
+
+     *See also:* *note more: doc-more, *note page_screen_output:
+     doc-page_screen_output, *note page_output_immediately:
+     doc-page_output_immediately, *note PAGER_FLAGS: doc-PAGER_FLAGS.
+
+ -- Built-in Function: VAL = PAGER_FLAGS ()
+ -- Built-in Function: OLD_VAL = PAGER_FLAGS (NEW_VAL)
+     Query or set the internal variable that specifies the options to
+     pass to the pager.
+
+     *See also:* *note PAGER: doc-PAGER.
+
+ -- Built-in Function: VAL = page_screen_output ()
+ -- Built-in Function: OLD_VAL = page_screen_output (NEW_VAL)
+     Query or set the internal variable that controls whether output
+     intended for the terminal window that is longer than one page is
+     sent through a pager.  This allows you to view one screenful at a
+     time.  Some pagers (such as `less'--see *note Installation::) are
+     also capable of moving backward on the output.
+
+ -- Built-in Function: VAL = page_output_immediately ()
+ -- Built-in Function: VAL = page_output_immediately (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     sends output to the pager as soon as it is available.  Otherwise,
+     Octave buffers its output and waits until just before the prompt
+     is printed to flush it to the pager.
+
+ -- Built-in Function:  fflush (FID)
+     Flush output to FID.  This is useful for ensuring that all pending
+     output makes it to the screen before some other event occurs.  For
+     example, it is always a good idea to flush the standard output
+     stream before calling `input'.
+
+     `fflush' returns 0 on success and an OS dependent error value (-1
+     on unix) on error.
+
+     *See also:* *note fopen: doc-fopen, *note fclose: doc-fclose.
+
+
+File: octave.info,  Node: Terminal Input,  Next: Simple File I/O,  Prev: Terminal Output,  Up: Basic Input and Output
+
+14.1.2 Terminal Input
+---------------------
+
+Octave has three functions that make it easy to prompt users for input.
+The `input' and `menu' functions are normally used for managing an
+interactive dialog with a user, and the `keyboard' function is normally
+used for doing simple debugging.
+
+ -- Built-in Function:  input (PROMPT)
+ -- Built-in Function:  input (PROMPT, "s")
+     Print a prompt and wait for user input.  For example,
+
+          input ("Pick a number, any number! ")
+
+     prints the prompt
+
+          Pick a number, any number!
+
+     and waits for the user to enter a value.  The string entered by
+     the user is evaluated as an expression, so it may be a literal
+     constant, a variable name, or any other valid expression.
+
+     Currently, `input' only returns one value, regardless of the number
+     of values produced by the evaluation of the expression.
+
+     If you are only interested in getting a literal string value, you
+     can call `input' with the character string `"s"' as the second
+     argument.  This tells Octave to return the string entered by the
+     user directly, without evaluating it first.
+
+     Because there may be output waiting to be displayed by the pager,
+     it is a good idea to always call `fflush (stdout)' before calling
+     `input'.  This will ensure that all pending output is written to
+     the screen before your prompt.  *Note Input and Output::.
+
+ -- Function File:  menu (TITLE, OPT1, ...)
+     Print a title string followed by a series of options.  Each option
+     will be printed along with a number.  The return value is the
+     number of the option selected by the user.  This function is
+     useful for interactive programs.  There is no limit to the number
+     of options that may be passed in, but it may be confusing to
+     present more than will fit easily on one screen.
+
+     *See also:* *note disp: doc-disp, *note printf: doc-printf, *note
+     input: doc-input.
+
+ -- Built-in Function:  yes_or_no (PROMPT)
+     Ask the user a yes-or-no question.  Return 1 if the answer is yes.
+     Takes one argument, which is the string to display to ask the
+     question.  It should end in a space; `yes-or-no-p' adds `(yes or
+     no) ' to it.  The user must confirm the answer with RET and can
+     edit it until it has been confirmed.
+
+   For `input', the normal command line history and editing functions
+are available at the prompt.
+
+   Octave also has a function that makes it possible to get a single
+character from the keyboard without requiring the user to type a
+carriage return.
+
+ -- Built-in Function:  kbhit ()
+     Read a single keystroke from the keyboard.  If called with one
+     argument, don't wait for a keypress.  For example,
+
+          x = kbhit ();
+
+     will set X to the next character typed at the keyboard as soon as
+     it is typed.
+
+          x = kbhit (1);
+
+     identical to the above example, but don't wait for a keypress,
+     returning the empty string if no key is available.
+
+
+File: octave.info,  Node: Simple File I/O,  Next: Rational Approximations,  Prev: Terminal Input,  Up: Basic Input and Output
+
+14.1.3 Simple File I/O
+----------------------
+
+The `save' and `load' commands allow data to be written to and read
+from disk files in various formats.  The default format of files
+written by the `save' command can be controlled using the functions
+`default_save_options' and `save_precision'.
+
+   As an example the following code creates a 3-by-3 matrix and saves it
+to the file `myfile.mat'.
+
+     A = [ 1:3; 4:6; 7:9 ];
+     save myfile.mat A
+
+   Once one or more variables have been saved to a file, they can be
+read into memory using the `load' command.
+
+     load myfile.mat
+     A
+          -| A =
+          -|
+          -|    1   2   3
+          -|    4   5   6
+          -|    7   8   9
+
+ -- Command: save file
+ -- Command: save options file
+ -- Command: save options file V1 V2 ...
+ -- Command: save options file -struct STRUCT F1 F2 ...
+     Save the named variables V1, V2, ..., in the file FILE.  The
+     special filename `-' may be used to write output to the terminal.
+     If no variable names are listed, Octave saves all the variables in
+     the current scope.  Otherwise, full variable names or pattern
+     syntax can be used to specify the variables to save.  If the
+     `-struct' modifier is used, fields F1 F2 ...  of the scalar
+     structure STRUCT are saved as if they were variables with
+     corresponding names.  Valid options for the `save' command are
+     listed in the following table.  Options that modify the output
+     format override the format specified by `default_save_options'.
+
+     If save is invoked using the functional form
+
+          save ("-option1", ..., "file", "v1", ...)
+
+     then the OPTIONS, FILE, and variable name arguments (V1, ...) must
+     be specified as character strings.
+
+    `-ascii'
+          Save a single matrix in a text file without header or any
+          other information.
+
+    `-binary'
+          Save the data in Octave's binary data format.
+
+    `-float-binary'
+          Save the data in Octave's binary data format but only using
+          single precision.  Only use this format if you know that all
+          the values to be saved can be represented in single precision.
+
+    `-hdf5'
+          Save the data in HDF5 format.  (HDF5 is a free, portable
+          binary format developed by the National Center for
+          Supercomputing Applications at the University of Illinois.)
+
+    `-float-hdf5'
+          Save the data in HDF5 format but only using single precision.
+          Only use this format if you know that all the values to be
+          saved can be represented in single precision.
+
+    `-V7'
+    `-v7'
+    `-7'
+    `-mat7-binary'
+          Save the data in MATLAB's v7 binary data format.
+
+    `-V6'
+    `-v6'
+    `-6'
+    `-mat'
+    `-mat-binary'
+          Save the data in MATLAB's v6 binary data format.
+
+    `-V4'
+    `-v4'
+    `-4'
+    `-mat4-binary'
+          Save the data in the binary format written by MATLAB version
+          4.
+
+    `-text'
+          Save the data in Octave's text data format.  (default).
+
+    `-zip'
+    `-z'
+          Use the gzip algorithm to compress the file.  This works
+          equally on files that are compressed with gzip outside of
+          octave, and gzip can equally be used to convert the files for
+          backward compatibility.
+
+     The list of variables to save may use wildcard patterns containing
+     the following special characters:
+    `?'
+          Match any single character.
+
+    `*'
+          Match zero or more characters.
+
+    `[ LIST ]'
+          Match the list of characters specified by LIST.  If the first
+          character is `!' or `^', match all characters except those
+          specified by LIST.  For example, the pattern `[a-zA-Z]' will
+          match all lower and upper case alphabetic characters.
+
+          Wildcards may also be used in the field name specifications
+          when using the `-struct' modifier (but not in the struct name
+          itself).
+
+
+     Except when using the MATLAB binary data file format or the
+     `-ascii' format, saving global variables also saves the global
+     status of the variable.  If the variable is restored at a later
+     time using `load', it will be restored as a global variable.
+
+     The command
+
+          save -binary data a b*
+
+     saves the variable `a' and all variables beginning with `b' to the
+     file `data' in Octave's binary format.
+
+     *See also:* *note load: doc-load, *note default_save_options:
+     doc-default_save_options, *note dlmread: doc-dlmread, *note
+     csvread: doc-csvread, *note fread: doc-fread.
+
+ -- Command: load file
+ -- Command: load options file
+ -- Command: load options file v1 v2 ...
+ -- Command: S = load("options", "file", "v1", "v2", ...)
+     Load the named variables V1, V2, ..., from the file FILE.  If no
+     variables are specified then all variables found in the file will
+     be loaded.  As with `save', the list of variables to extract can
+     be full names or use a pattern syntax.  The format of the file is
+     automatically detected but may be overridden by supplying the
+     appropriate option.
+
+     If load is invoked using the functional form
+
+          load ("-option1", ..., "file", "v1", ...)
+
+     then the OPTIONS, FILE, and variable name arguments (V1, ...) must
+     be specified as character strings.
+
+     If a variable that is not marked as global is loaded from a file
+     when a global symbol with the same name already exists, it is
+     loaded in the global symbol table.  Also, if a variable is marked
+     as global in a file and a local symbol exists, the local symbol is
+     moved to the global symbol table and given the value from the file.
+
+     If invoked with a single output argument, Octave returns data
+     instead of inserting variables in the symbol table.  If the data
+     file contains only numbers (TAB- or space-delimited columns), a
+     matrix of values is returned.  Otherwise, `load' returns a
+     structure with members  corresponding to the names of the
+     variables in the file.
+
+     The `load' command can read data stored in Octave's text and
+     binary formats, and MATLAB's binary format.  If compiled with zlib
+     support, it can also load gzip-compressed files.  It will
+     automatically detect the type of file and do conversion from
+     different floating point formats (currently only IEEE big and
+     little endian, though other formats may be added in the future).
+
+     Valid options for `load' are listed in the following table.
+
+    `-force'
+          This option is accepted for backward compatibility but is
+          ignored.  Octave now overwrites variables currently in memory
+          with those of the same name found in the file.
+
+    `-ascii'
+          Force Octave to assume the file contains columns of numbers
+          in text format without any header or other information.  Data
+          in the file will be loaded as a single numeric matrix with
+          the name of the variable derived from the name of the file.
+
+    `-binary'
+          Force Octave to assume the file is in Octave's binary format.
+
+    `-hdf5'
+          Force Octave to assume the file is in HDF5 format.  (HDF5 is
+          a free, portable binary format developed by the National
+          Center for Supercomputing Applications at the University of
+          Illinois.)  Note that Octave can read HDF5 files not created
+          by itself, but may skip some datasets in formats that it
+          cannot support.
+
+    `-import'
+          This option is accepted for backward compatibility but is
+          ignored.  Octave can now support multi-dimensional HDF data
+          and automatically modifies variable names if they are invalid
+          Octave identifiers.
+
+    `-mat'
+    `-mat-binary'
+    `-6'
+    `-v6'
+    `-7'
+    `-v7'
+          Force Octave to assume the file is in MATLAB's version 6 or 7
+          binary format.
+
+    `-mat4-binary'
+    `-4'
+    `-v4'
+    `-V4'
+          Force Octave to assume the file is in the binary format
+          written by MATLAB version 4.
+
+    `-text'
+          Force Octave to assume the file is in Octave's text format.
+
+     *See also:* *note save: doc-save, *note dlmwrite: doc-dlmwrite,
+     *note csvwrite: doc-csvwrite, *note fwrite: doc-fwrite.
+
+   There are three functions that modify the behavior of `save'.
+
+ -- Built-in Function: VAL = default_save_options ()
+ -- Built-in Function: OLD_VAL = default_save_options (NEW_VAL)
+     Query or set the internal variable that specifies the default
+     options for the `save' command, and defines the default format.
+     Typical values include `"-ascii"', `"-text -zip"'.  The default
+     value is `-text'.
+
+     *See also:* *note save: doc-save.
+
+ -- Built-in Function: VAL = save_precision ()
+ -- Built-in Function: OLD_VAL = save_precision (NEW_VAL)
+     Query or set the internal variable that specifies the number of
+     digits to keep when saving data in text format.
+
+ -- Built-in Function: VAL = save_header_format_string ()
+ -- Built-in Function: OLD_VAL = save_header_format_string (NEW_VAL)
+     Query or set the internal variable that specifies the format
+     string used for the comment line written at the beginning of
+     text-format data files saved by Octave.  The format string is
+     passed to `strftime' and should begin with the character `#' and
+     contain no newline characters.  If the value of
+     `save_header_format_string' is the empty string, the header
+     comment is omitted from text-format data files.  The default value
+     is
+
+          "# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER at HOST>"
+
+     *See also:* *note strftime: doc-strftime, *note save: doc-save.
+
+ -- Built-in Function:  native_float_format ()
+     Return the native floating point format as a string
+
+   It is possible to write data to a file in a similar way to the
+`disp' function for writing data to the screen.  The `fdisp' works just
+like `disp' except its first argument is a file pointer as created by
+`fopen'.  As an example, the following code writes to data `myfile.txt'.
+
+     fid = fopen ("myfile.txt", "w");
+     fdisp (fid, "3/8 is ");
+     fdisp (fid, 3/8);
+     fclose (fid);
+
+*Note Opening and Closing Files::, for details on how to use `fopen'
+and `fclose'.
+
+ -- Built-in Function:  fdisp (FID, X)
+     Display the value of X on the stream FID.  For example,
+
+          fdisp (stdout, "The value of pi is:"), fdisp (stdout, pi)
+
+               -| the value of pi is:
+               -| 3.1416
+
+     Note that the output from `fdisp' always ends with a newline.
+
+     *See also:* *note disp: doc-disp.
+
+   Octave can also read and write matrices text files such as comma
+separated lists.
+
+ -- Function File:  dlmwrite (FILE, A)
+ -- Function File:  dlmwrite (FILE, A, DELIM, R, C)
+ -- Function File:  dlmwrite (FILE, A, KEY, VAL ...)
+ -- Function File:  dlmwrite (FILE, A, "-append", ...)
+     Write the matrix A to the named file using delimiters.
+
+     The parameter DELIM specifies the delimiter to use to separate
+     values on a row.
+
+     The value of R specifies the number of delimiter-only lines to add
+     to the start of the file.
+
+     The value of C specifies the number of delimiters to prepend to
+     each line of data.
+
+     If the argument `"-append"' is given, append to the end of the
+     FILE.
+
+     In addition, the following keyword value pairs may appear at the
+     end of the argument list:
+    `"append"'
+          Either `"on"' or `"off"'.  See `"-append"' above.
+
+    `"delimiter"'
+          See DELIM above.
+
+    `"newline"'
+          The character(s) to use to separate each row.  Three special
+          cases exist for this option.  `"unix"' is changed into '\n',
+          `"pc"' is changed into '\r\n', and `"mac"' is changed into
+          '\r'.  Other values for this option are kept as is.
+
+    `"roffset"'
+          See R above.
+
+    `"coffset"'
+          See C above.
+
+    `"precision"'
+          The precision to use when writing the file.  It can either be
+          a format string (as used by fprintf) or a number of
+          significant digits.
+
+          dlmwrite ("file.csv", reshape (1:16, 4, 4));
+
+          dlmwrite ("file.tex", a, "delimiter", "&", "newline", "\\n")
+
+     *See also:* *note dlmread: doc-dlmread, *note csvread:
+     doc-csvread, *note csvwrite: doc-csvwrite.
+
+ -- Loadable Function: DATA = dlmread (FILE)
+ -- Loadable Function: DATA = dlmread (FILE, SEP)
+ -- Loadable Function: DATA = dlmread (FILE, SEP, R0, C0)
+ -- Loadable Function: DATA = dlmread (FILE, SEP, RANGE)
+     Read the matrix DATA from a text file.  If not defined the
+     separator between fields is determined from the file itself.
+     Otherwise the separation character is defined by SEP.
+
+     Given two scalar arguments R0 and C0, these define the starting
+     row and column of the data to be read.  These values are indexed
+     from zero, such that the first row corresponds to an index of zero.
+
+     The RANGE parameter must be a 4 element vector containing the upper
+     left and lower right corner `[R0,C0,R1,C1]' or a spreadsheet style
+     range such as 'A2..Q15'.  The lowest index value is zero.
+
+ -- Function File: X = csvwrite (FILENAME, X)
+     Write the matrix X to a file.
+
+     This function is equivalent to
+          dlmwrite (FILENAME, X, ",", ...)
+
+     *See also:* *note dlmread: doc-dlmread, *note dlmwrite:
+     doc-dlmwrite, *note csvread: doc-csvread.
+
+ -- Function File: X = csvread (FILENAME)
+     Read the matrix X from a file.
+
+     This function is equivalent to
+          dlmread (FILENAME, "," , ...)
+
+     *See also:* *note dlmread: doc-dlmread, *note dlmwrite:
+     doc-dlmwrite, *note csvwrite: doc-csvwrite.
+
+* Menu:
+
+* Saving Data on Unexpected Exits::
+
+
+File: octave.info,  Node: Saving Data on Unexpected Exits,  Up: Simple File I/O
+
+14.1.3.1 Saving Data on Unexpected Exits
+........................................
+
+If Octave for some reason exits unexpectedly it will by default save the
+variables available in the workspace to a file in the current directory.
+By default this file is named `octave-core' and can be loaded into
+memory with the `load' command.  While the default behavior most often
+is reasonable it can be changed through the following functions.
+
+ -- Built-in Function: VAL = crash_dumps_octave_core ()
+ -- Built-in Function: OLD_VAL = crash_dumps_octave_core (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     tries to save all current variables to the file "octave-core" if it
+     crashes or receives a hangup, terminate or similar signal.
+
+     *See also:* *note octave_core_file_limit:
+     doc-octave_core_file_limit, *note octave_core_file_name:
+     doc-octave_core_file_name, *note octave_core_file_options:
+     doc-octave_core_file_options.
+
+ -- Built-in Function: VAL = sighup_dumps_octave_core ()
+ -- Built-in Function: OLD_VAL = sighup_dumps_octave_core (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     tries to save all current variables to the file "octave-core" if
+     it receives a hangup signal.
+
+ -- Built-in Function: VAL = sigterm_dumps_octave_core ()
+ -- Built-in Function: OLD_VAL = sigterm_dumps_octave_core (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     tries to save all current variables to the file "octave-core" if
+     it receives a terminate signal.
+
+ -- Built-in Function: VAL = octave_core_file_options ()
+ -- Built-in Function: OLD_VAL = octave_core_file_options (NEW_VAL)
+     Query or set the internal variable that specifies the options used
+     for saving the workspace data if Octave aborts.  The value of
+     `octave_core_file_options' should follow the same format as the
+     options for the `save' function.  The default value is Octave's
+     binary format.
+
+     *See also:* *note crash_dumps_octave_core:
+     doc-crash_dumps_octave_core, *note octave_core_file_name:
+     doc-octave_core_file_name, *note octave_core_file_limit:
+     doc-octave_core_file_limit.
+
+ -- Built-in Function: VAL = octave_core_file_limit ()
+ -- Built-in Function: OLD_VAL = octave_core_file_limit (NEW_VAL)
+     Query or set the internal variable that specifies the maximum
+     amount of memory (in kilobytes) of the top-level workspace that
+     Octave will attempt to save when writing data to the crash dump
+     file (the name of the file is specified by OCTAVE_CORE_FILE_NAME).
+     If OCTAVE_CORE_FILE_OPTIONS flags specify a binary format, then
+     OCTAVE_CORE_FILE_LIMIT will be approximately the maximum size of
+     the file.  If a text file format is used, then the file could be
+     much larger than the limit.  The default value is -1 (unlimited)
+
+     *See also:* *note crash_dumps_octave_core:
+     doc-crash_dumps_octave_core, *note octave_core_file_name:
+     doc-octave_core_file_name, *note octave_core_file_options:
+     doc-octave_core_file_options.
+
+ -- Built-in Function: VAL = octave_core_file_name ()
+ -- Built-in Function: OLD_VAL = octave_core_file_name (NEW_VAL)
+     Query or set the internal variable that specifies the name of the
+     file used for saving data from the top-level workspace if Octave
+     aborts.  The default value is `"octave-core"'
+
+     *See also:* *note crash_dumps_octave_core:
+     doc-crash_dumps_octave_core, *note octave_core_file_name:
+     doc-octave_core_file_name, *note octave_core_file_options:
+     doc-octave_core_file_options.
+
+
+File: octave.info,  Node: Rational Approximations,  Prev: Simple File I/O,  Up: Basic Input and Output
+
+14.1.4 Rational Approximations
+------------------------------
+
+ -- Function File: S = rat (X, TOL)
+ -- Function File: [N, D] = rat (X, TOL)
+     Find a rational approximation to X within the tolerance defined by
+     TOL using a continued fraction expansion.  For example,
+
+          rat(pi) = 3 + 1/(7 + 1/16) = 355/113
+          rat(e) = 3 + 1/(-4 + 1/(2 + 1/(5 + 1/(-2 + 1/(-7)))))
+                 = 1457/536
+
+     Called with two arguments returns the numerator and denominator
+     separately as two matrices.
+
+*See also:* *note rats: doc-rats.
+
+ -- Built-in Function:  rats (X, LEN)
+     Convert X into a rational approximation represented as a string.
+     You can convert the string back into a matrix as follows:
+
+             r = rats(hilb(4));
+             x = str2num(r)
+
+     The optional second argument defines the maximum length of the
+     string representing the elements of X.  By default LEN is 9.
+
+     *See also:* *note format: doc-format, *note rat: doc-rat.
+
+
+File: octave.info,  Node: C-Style I/O Functions,  Prev: Basic Input and Output,  Up: Input and Output
+
+14.2 C-Style I/O Functions
+==========================
+
+Octave's C-style input and output functions provide most of the
+functionality of the C programming language's standard I/O library.  The
+argument lists for some of the input functions are slightly different,
+however, because Octave has no way of passing arguments by reference.
+
+   In the following, FILE refers to a file name and `fid' refers to an
+integer file number, as returned by `fopen'.
+
+   There are three files that are always available.  Although these
+files can be accessed using their corresponding numeric file ids, you
+should always use the symbolic names given in the table below, since it
+will make your programs easier to understand.
+
+ -- Built-in Function:  stdin ()
+     Return the numeric value corresponding to the standard input
+     stream.  When Octave is used interactively, this is filtered
+     through the command line editing functions.
+
+     *See also:* *note stdout: doc-stdout, *note stderr: doc-stderr.
+
+ -- Built-in Function:  stdout ()
+     Return the numeric value corresponding to the standard output
+     stream.  Data written to the standard output is normally filtered
+     through the pager.
+
+     *See also:* *note stdin: doc-stdin, *note stderr: doc-stderr.
+
+ -- Built-in Function:  stderr ()
+     Return the numeric value corresponding to the standard error
+     stream.  Even if paging is turned on, the standard error is not
+     sent to the pager.  It is useful for error messages and prompts.
+
+     *See also:* *note stdin: doc-stdin, *note stdout: doc-stdout.
+
+* Menu:
+
+* Opening and Closing Files::
+* Simple Output::
+* Line-Oriented Input::
+* Formatted Output::
+* Output Conversion for Matrices::
+* Output Conversion Syntax::
+* Table of Output Conversions::
+* Integer Conversions::
+* Floating-Point Conversions::
+* Other Output Conversions::
+* Formatted Input::
+* Input Conversion Syntax::
+* Table of Input Conversions::
+* Numeric Input Conversions::
+* String Input Conversions::
+* Binary I/O::
+* Temporary Files::
+* EOF and Errors::
+* File Positioning::
+
+
+File: octave.info,  Node: Opening and Closing Files,  Next: Simple Output,  Up: C-Style I/O Functions
+
+14.2.1 Opening and Closing Files
+--------------------------------
+
+When reading data from a file it must be opened for reading first, and
+likewise when writing to a file.  The `fopen' function returns a
+pointer to an open file that is ready to be read or written.  Once all
+data has been read from or written to the opened file it should be
+closed.  The `fclose' function does this.  The following code
+illustrates the basic pattern for writing to a file, but a very similar
+pattern is used when reading a file.
+
+     filename = "myfile.txt";
+     fid = fopen (filename, "w");
+     # Do the actual I/O here...
+     fclose (fid);
+
+ -- Built-in Function: [FID, MSG] = fopen (NAME, MODE, ARCH)
+ -- Built-in Function: FID_LIST = fopen ("all")
+ -- Built-in Function: [FILE, MODE, ARCH] = fopen (FID)
+     The first form of the `fopen' function opens the named file with
+     the specified mode (read-write, read-only, etc.) and architecture
+     interpretation (IEEE big endian, IEEE little endian, etc.), and
+     returns an integer value that may be used to refer to the file
+     later.  If an error occurs, FID is set to -1 and MSG contains the
+     corresponding system error message.  The MODE is a one or two
+     character string that specifies whether the file is to be opened
+     for reading, writing, or both.
+
+     The second form of the `fopen' function returns a vector of file
+     ids corresponding to all the currently open files, excluding the
+     `stdin', `stdout', and `stderr' streams.
+
+     The third form of the `fopen' function returns information about
+     the open file given its file id.
+
+     For example,
+
+          myfile = fopen ("splat.dat", "r", "ieee-le");
+
+     opens the file `splat.dat' for reading.  If necessary, binary
+     numeric values will be read assuming they are stored in IEEE
+     format with the least significant bit first, and then converted to
+     the native representation.
+
+     Opening a file that is already open simply opens it again and
+     returns a separate file id.  It is not an error to open a file
+     several times, though writing to the same file through several
+     different file ids may produce unexpected results.
+
+     The possible values `mode' may have are
+
+    `r'
+          Open a file for reading.
+
+    `w'
+          Open a file for writing.  The previous contents are discarded.
+
+    `a'
+          Open or create a file for writing at the end of the file.
+
+    `r+'
+          Open an existing file for reading and writing.
+
+    `w+'
+          Open a file for reading or writing.  The previous contents are
+          discarded.
+
+    `a+'
+          Open or create a file for reading or writing at the end of the
+          file.
+
+     Append a "t" to the mode string to open the file in text mode or a
+     "b" to open in binary mode.  On Windows and Macintosh systems, text
+     mode reading and writing automatically converts linefeeds to the
+     appropriate line end character for the system (carriage-return
+     linefeed on Windows, carriage-return on Macintosh).  The default
+     if no mode is specified is binary mode.
+
+     Additionally, you may append a "z" to the mode string to open a
+     gzipped file for reading or writing.  For this to be successful,
+     you must also open the file in binary mode.
+
+     The parameter ARCH is a string specifying the default data format
+     for the file.  Valid values for ARCH are:
+
+          `native' The format of the current machine (this is the
+          default).
+
+          `ieee-be' IEEE big endian format.
+
+          `ieee-le' IEEE little endian format.
+
+          `vaxd' VAX D floating format.
+
+          `vaxg' VAX G floating format.
+
+          `cray' Cray floating format.
+
+     however, conversions are currently only supported for `native'
+     `ieee-be', and `ieee-le' formats.
+
+     *See also:* *note fclose: doc-fclose, *note fgets: doc-fgets,
+     *note fputs: doc-fputs, *note fread: doc-fread, *note fseek:
+     doc-fseek, *note ferror: doc-ferror, *note fprintf: doc-fprintf,
+     *note fscanf: doc-fscanf, *note ftell: doc-ftell, *note fwrite:
+     doc-fwrite.
+
+ -- Built-in Function:  fclose (FID)
+     Closes the specified file.  If successful, `fclose' returns 0,
+     otherwise, it returns -1.
+
+     *See also:* *note fopen: doc-fopen, *note fseek: doc-fseek, *note
+     ftell: doc-ftell.
+
+
+File: octave.info,  Node: Simple Output,  Next: Line-Oriented Input,  Prev: Opening and Closing Files,  Up: C-Style I/O Functions
+
+14.2.2 Simple Output
+--------------------
+
+Once a file has been opened for writing a string can be written to the
+file using the `fputs' function.  The following example shows how to
+write the string `Free Software is needed for Free Science' to the file
+`free.txt'.
+
+     filename = "free.txt";
+     fid = fopen (filename, "w");
+     fputs (fid, "Free Software is needed for Free Science");
+     fclose (fid);
+
+ -- Built-in Function:  fputs (FID, STRING)
+     Write a string to a file with no formatting.
+
+     Return a non-negative number on success and EOF on error.
+
+     *See also:* *note scanf: doc-scanf, *note sscanf: doc-sscanf,
+     *note fread: doc-fread, *note fprintf: doc-fprintf, *note fgets:
+     doc-fgets, *note fscanf: doc-fscanf.
+
+   A function much similar to `fputs' is available for writing data to
+the screen.  The `puts' function works just like `fputs' except it
+doesn't take a file pointer as its input.
+
+ -- Built-in Function:  puts (STRING)
+     Write a string to the standard output with no formatting.
+
+     Return a non-negative number on success and EOF on error.
+
+
+File: octave.info,  Node: Line-Oriented Input,  Next: Formatted Output,  Prev: Simple Output,  Up: C-Style I/O Functions
+
+14.2.3 Line-Oriented Input
+--------------------------
+
+To read from a file it must be opened for reading using `fopen'.  Then
+a line can be read from the file using `fgetl' as the following code
+illustrates
+
+     fid = fopen ("free.txt");
+     txt = fgetl (fid)
+          -| Free Software is needed for Free Science
+     fclose (fid);
+
+This of course assumes that the file `free.txt' exists and contains the
+line `Free Software is needed for Free Science'.
+
+ -- Built-in Function:  fgetl (FID, LEN)
+     Read characters from a file, stopping after a newline, or EOF, or
+     LEN characters have been read.  The characters read, excluding the
+     possible trailing newline, are returned as a string.
+
+     If LEN is omitted, `fgetl' reads until the next newline character.
+
+     If there are no more characters to read, `fgetl' returns -1.
+
+     *See also:* *note fread: doc-fread, *note fscanf: doc-fscanf.
+
+ -- Built-in Function:  fgets (FID, LEN)
+     Read characters from a file, stopping after a newline, or EOF, or
+     LEN characters have been read.  The characters read, including the
+     possible trailing newline, are returned as a string.
+
+     If LEN is omitted, `fgets' reads until the next newline character.
+
+     If there are no more characters to read, `fgets' returns -1.
+
+     *See also:* *note fputs: doc-fputs, *note fopen: doc-fopen, *note
+     fread: doc-fread, *note fscanf: doc-fscanf.
+
+
+File: octave.info,  Node: Formatted Output,  Next: Output Conversion for Matrices,  Prev: Line-Oriented Input,  Up: C-Style I/O Functions
+
+14.2.4 Formatted Output
+-----------------------
+
+This section describes how to call `printf' and related functions.
+
+   The following functions are available for formatted output.  They are
+modelled after the C language functions of the same name, but they
+interpret the format template differently in order to improve the
+performance of printing vector and matrix values.
+
+ -- Built-in Function:  printf (TEMPLATE, ...)
+     Print optional arguments under the control of the template string
+     TEMPLATE to the stream `stdout' and return the number of
+     characters printed.
+
+     *See also:* *note fprintf: doc-fprintf, *note sprintf:
+     doc-sprintf, *note scanf: doc-scanf.
+
+ -- Built-in Function:  fprintf (FID, TEMPLATE, ...)
+     This function is just like `printf', except that the output is
+     written to the stream FID instead of `stdout'.  If FID is omitted,
+     the output is written to `stdout'.
+
+     *See also:* *note printf: doc-printf, *note sprintf: doc-sprintf,
+     *note fread: doc-fread, *note fscanf: doc-fscanf, *note fopen:
+     doc-fopen, *note fclose: doc-fclose.
+
+ -- Built-in Function:  sprintf (TEMPLATE, ...)
+     This is like `printf', except that the output is returned as a
+     string.  Unlike the C library function, which requires you to
+     provide a suitably sized string as an argument, Octave's `sprintf'
+     function returns the string, automatically sized to hold all of
+     the items converted.
+
+     *See also:* *note printf: doc-printf, *note fprintf: doc-fprintf,
+     *note sscanf: doc-sscanf.
+
+   The `printf' function can be used to print any number of arguments.
+The template string argument you supply in a call provides information
+not only about the number of additional arguments, but also about their
+types and what style should be used for printing them.
+
+   Ordinary characters in the template string are simply written to the
+output stream as-is, while "conversion specifications" introduced by a
+`%' character in the template cause subsequent arguments to be
+formatted and written to the output stream.  For example, 
+
+     pct = 37;
+     filename = "foo.txt";
+     printf ("Processed %d%% of `%s'.\nPlease be patient.\n",
+             pct, filename);
+
+produces output like
+
+     Processed 37% of `foo.txt'.
+     Please be patient.
+
+   This example shows the use of the `%d' conversion to specify that a
+scalar argument should be printed in decimal notation, the `%s'
+conversion to specify printing of a string argument, and the `%%'
+conversion to print a literal `%' character.
+
+   There are also conversions for printing an integer argument as an
+unsigned value in octal, decimal, or hexadecimal radix (`%o', `%u', or
+`%x', respectively); or as a character value (`%c').
+
+   Floating-point numbers can be printed in normal, fixed-point notation
+using the `%f' conversion or in exponential notation using the `%e'
+conversion.  The `%g' conversion uses either `%e' or `%f' format,
+depending on what is more appropriate for the magnitude of the
+particular number.
+
+   You can control formatting more precisely by writing "modifiers"
+between the `%' and the character that indicates which conversion to
+apply.  These slightly alter the ordinary behavior of the conversion.
+For example, most conversion specifications permit you to specify a
+minimum field width and a flag indicating whether you want the result
+left- or right-justified within the field.
+
+   The specific flags and modifiers that are permitted and their
+interpretation vary depending on the particular conversion.  They're all
+described in more detail in the following sections.
+
+
+File: octave.info,  Node: Output Conversion for Matrices,  Next: Output Conversion Syntax,  Prev: Formatted Output,  Up: C-Style I/O Functions
+
+14.2.5 Output Conversion for Matrices
+-------------------------------------
+
+When given a matrix value, Octave's formatted output functions cycle
+through the format template until all the values in the matrix have been
+printed.  For example,
+
+     printf ("%4.2f %10.2e %8.4g\n", hilb (3));
+
+          -| 1.00   5.00e-01   0.3333
+          -| 0.50   3.33e-01     0.25
+          -| 0.33   2.50e-01      0.2
+
+   If more than one value is to be printed in a single call, the output
+functions do not return to the beginning of the format template when
+moving on from one value to the next.  This can lead to confusing output
+if the number of elements in the matrices are not exact multiples of the
+number of conversions in the format template.  For example,
+
+     printf ("%4.2f %10.2e %8.4g\n", [1, 2], [3, 4]);
+
+          -| 1.00   2.00e+00        3
+          -| 4.00
+
+   If this is not what you want, use a series of calls instead of just
+one.
+
+
+File: octave.info,  Node: Output Conversion Syntax,  Next: Table of Output Conversions,  Prev: Output Conversion for Matrices,  Up: C-Style I/O Functions
+
+14.2.6 Output Conversion Syntax
+-------------------------------
+
+This section provides details about the precise syntax of conversion
+specifications that can appear in a `printf' template string.
+
+   Characters in the template string that are not part of a conversion
+specification are printed as-is to the output stream.
+
+   The conversion specifications in a `printf' template string have the
+general form:
+
+     % FLAGS WIDTH [ . PRECISION ] TYPE CONVERSION
+
+   For example, in the conversion specifier `%-10.8ld', the `-' is a
+flag, `10' specifies the field width, the precision is `8', the letter
+`l' is a type modifier, and `d' specifies the conversion style.  (This
+particular type specifier says to print a numeric argument in decimal
+notation, with a minimum of 8 digits left-justified in a field at least
+10 characters wide.)
+
+   In more detail, output conversion specifications consist of an
+initial `%' character followed in sequence by:
+
+   * Zero or more "flag characters" that modify the normal behavior of
+     the conversion specification.  
+
+   * An optional decimal integer specifying the "minimum field width".
+     If the normal conversion produces fewer characters than this, the
+     field is padded with spaces to the specified width.  This is a
+     _minimum_ value; if the normal conversion produces more characters
+     than this, the field is _not_ truncated.  Normally, the output is
+     right-justified within the field.  
+
+     You can also specify a field width of `*'.  This means that the
+     next argument in the argument list (before the actual value to be
+     printed) is used as the field width.  The value is rounded to the
+     nearest integer.  If the value is negative, this means to set the
+     `-' flag (see below) and to use the absolute value as the field
+     width.
+
+   * An optional "precision" to specify the number of digits to be
+     written for the numeric conversions.  If the precision is
+     specified, it consists of a period (`.') followed optionally by a
+     decimal integer (which defaults to zero if omitted).  
+
+     You can also specify a precision of `*'.  This means that the next
+     argument in the argument list (before the actual value to be
+     printed) is used as the precision.  The value must be an integer,
+     and is ignored if it is negative.
+
+   * An optional "type modifier character".  This character is ignored
+     by Octave's `printf' function, but is recognized to provide
+     compatibility with the C language `printf'.
+
+   * A character that specifies the conversion to be applied.
+
+   The exact options that are permitted and how they are interpreted
+vary between the different conversion specifiers.  See the descriptions
+of the individual conversions for information about the particular
+options that they use.
+
+
+File: octave.info,  Node: Table of Output Conversions,  Next: Integer Conversions,  Prev: Output Conversion Syntax,  Up: C-Style I/O Functions
+
+14.2.7 Table of Output Conversions
+----------------------------------
+
+Here is a table summarizing what all the different conversions do:
+
+`%d', `%i'
+     Print an integer as a signed decimal number.  *Note Integer
+     Conversions::, for details.  `%d' and `%i' are synonymous for
+     output, but are different when used with `scanf' for input (*note
+     Table of Input Conversions::).
+
+`%o'
+     Print an integer as an unsigned octal number.  *Note Integer
+     Conversions::, for details.
+
+`%u'
+     Print an integer as an unsigned decimal number.  *Note Integer
+     Conversions::, for details.
+
+`%x', `%X'
+     Print an integer as an unsigned hexadecimal number.  `%x' uses
+     lower-case letters and `%X' uses upper-case.  *Note Integer
+     Conversions::, for details.
+
+`%f'
+     Print a floating-point number in normal (fixed-point) notation.
+     *Note Floating-Point Conversions::, for details.
+
+`%e', `%E'
+     Print a floating-point number in exponential notation.  `%e' uses
+     lower-case letters and `%E' uses upper-case.  *Note Floating-Point
+     Conversions::, for details.
+
+`%g', `%G'
+     Print a floating-point number in either normal (fixed-point) or
+     exponential notation, whichever is more appropriate for its
+     magnitude.  `%g' uses lower-case letters and `%G' uses upper-case.
+     *Note Floating-Point Conversions::, for details.
+
+`%c'
+     Print a single character.  *Note Other Output Conversions::.
+
+`%s'
+     Print a string.  *Note Other Output Conversions::.
+
+`%%'
+     Print a literal `%' character.  *Note Other Output Conversions::.
+
+   If the syntax of a conversion specification is invalid, unpredictable
+things will happen, so don't do this.  If there aren't enough function
+arguments provided to supply values for all the conversion
+specifications in the template string, or if the arguments are not of
+the correct types, the results are unpredictable.  If you supply more
+arguments than conversion specifications, the extra argument values are
+simply ignored; this is sometimes useful.
+
+
+File: octave.info,  Node: Integer Conversions,  Next: Floating-Point Conversions,  Prev: Table of Output Conversions,  Up: C-Style I/O Functions
+
+14.2.8 Integer Conversions
+--------------------------
+
+This section describes the options for the `%d', `%i', `%o', `%u',
+`%x', and `%X' conversion specifications.  These conversions print
+integers in various formats.
+
+   The `%d' and `%i' conversion specifications both print an numeric
+argument as a signed decimal number; while `%o', `%u', and `%x' print
+the argument as an unsigned octal, decimal, or hexadecimal number
+(respectively).  The `%X' conversion specification is just like `%x'
+except that it uses the characters `ABCDEF' as digits instead of
+`abcdef'.
+
+   The following flags are meaningful:
+
+`-'
+     Left-justify the result in the field (instead of the normal
+     right-justification).
+
+`+'
+     For the signed `%d' and `%i' conversions, print a plus sign if the
+     value is positive.
+
+` '
+     For the signed `%d' and `%i' conversions, if the result doesn't
+     start with a plus or minus sign, prefix it with a space character
+     instead.  Since the `+' flag ensures that the result includes a
+     sign, this flag is ignored if you supply both of them.
+
+`#'
+     For the `%o' conversion, this forces the leading digit to be `0',
+     as if by increasing the precision.  For `%x' or `%X', this
+     prefixes a leading `0x' or `0X' (respectively) to the result.
+     This doesn't do anything useful for the `%d', `%i', or `%u'
+     conversions.
+
+`0'
+     Pad the field with zeros instead of spaces.  The zeros are placed
+     after any indication of sign or base.  This flag is ignored if the
+     `-' flag is also specified, or if a precision is specified.
+
+   If a precision is supplied, it specifies the minimum number of
+digits to appear; leading zeros are produced if necessary.  If you
+don't specify a precision, the number is printed with as many digits as
+it needs.  If you convert a value of zero with an explicit precision of
+zero, then no characters at all are produced.
+
+
+File: octave.info,  Node: Floating-Point Conversions,  Next: Other Output Conversions,  Prev: Integer Conversions,  Up: C-Style I/O Functions
+
+14.2.9 Floating-Point Conversions
+---------------------------------
+
+This section discusses the conversion specifications for floating-point
+numbers: the `%f', `%e', `%E', `%g', and `%G' conversions.
+
+   The `%f' conversion prints its argument in fixed-point notation,
+producing output of the form [`-']DDD`.'DDD, where the number of digits
+following the decimal point is controlled by the precision you specify.
+
+   The `%e' conversion prints its argument in exponential notation,
+producing output of the form [`-']D`.'DDD`e'[`+'|`-']DD.  Again, the
+number of digits following the decimal point is controlled by the
+precision.  The exponent always contains at least two digits.  The `%E'
+conversion is similar but the exponent is marked with the letter `E'
+instead of `e'.
+
+   The `%g' and `%G' conversions print the argument in the style of
+`%e' or `%E' (respectively) if the exponent would be less than -4 or
+greater than or equal to the precision; otherwise they use the `%f'
+style.  Trailing zeros are removed from the fractional portion of the
+result and a decimal-point character appears only if it is followed by
+a digit.
+
+   The following flags can be used to modify the behavior:
+
+`-'
+     Left-justify the result in the field.  Normally the result is
+     right-justified.
+
+`+'
+     Always include a plus or minus sign in the result.
+
+` '
+     If the result doesn't start with a plus or minus sign, prefix it
+     with a space instead.  Since the `+' flag ensures that the result
+     includes a sign, this flag is ignored if you supply both of them.
+
+`#'
+     Specifies that the result should always include a decimal point,
+     even if no digits follow it.  For the `%g' and `%G' conversions,
+     this also forces trailing zeros after the decimal point to be left
+     in place where they would otherwise be removed.
+
+`0'
+     Pad the field with zeros instead of spaces; the zeros are placed
+     after any sign.  This flag is ignored if the `-' flag is also
+     specified.
+
+   The precision specifies how many digits follow the decimal-point
+character for the `%f', `%e', and `%E' conversions.  For these
+conversions, the default precision is `6'.  If the precision is
+explicitly `0', this suppresses the decimal point character entirely.
+For the `%g' and `%G' conversions, the precision specifies how many
+significant digits to print.  Significant digits are the first digit
+before the decimal point, and all the digits after it.  If the
+precision is `0' or not specified for `%g' or `%G', it is treated like
+a value of `1'.  If the value being printed cannot be expressed
+precisely in the specified number of digits, the value is rounded to
+the nearest number that fits.
+
+
+File: octave.info,  Node: Other Output Conversions,  Next: Formatted Input,  Prev: Floating-Point Conversions,  Up: C-Style I/O Functions
+
+14.2.10 Other Output Conversions
+--------------------------------
+
+This section describes miscellaneous conversions for `printf'.
+
+   The `%c' conversion prints a single character.  The `-' flag can be
+used to specify left-justification in the field, but no other flags are
+defined, and no precision or type modifier can be given.  For example:
+
+     printf ("%c%c%c%c%c", "h", "e", "l", "l", "o");
+
+prints `hello'.
+
+   The `%s' conversion prints a string.  The corresponding argument
+must be a string.  A precision can be specified to indicate the maximum
+number of characters to write; otherwise characters in the string up to
+but not including the terminating null character are written to the
+output stream.  The `-' flag can be used to specify left-justification
+in the field, but no other flags or type modifiers are defined for this
+conversion.  For example:
+
+     printf ("%3s%-6s", "no", "where");
+
+prints ` nowhere ' (note the leading and trailing spaces).
+
+
+File: octave.info,  Node: Formatted Input,  Next: Input Conversion Syntax,  Prev: Other Output Conversions,  Up: C-Style I/O Functions
+
+14.2.11 Formatted Input
+-----------------------
+
+Octave provides the `scanf', `fscanf', and `sscanf' functions to read
+formatted input.  There are two forms of each of these functions.  One
+can be used to extract vectors of data from a file, and the other is
+more `C-like'.
+
+ -- Built-in Function: [VAL, COUNT] = fscanf (FID, TEMPLATE, SIZE)
+ -- Built-in Function: [V1, V2, ..., COUNT] = fscanf (FID, TEMPLATE,
+          "C")
+     In the first form, read from FID according to TEMPLATE, returning
+     the result in the matrix VAL.
+
+     The optional argument SIZE specifies the amount of data to read
+     and may be one of
+
+    `Inf'
+          Read as much as possible, returning a column vector.
+
+    `NR'
+          Read up to NR elements, returning a column vector.
+
+    `[NR, Inf]'
+          Read as much as possible, returning a matrix with NR rows.
+          If the number of elements read is not an exact multiple of
+          NR, the last column is padded with zeros.
+
+    `[NR, NC]'
+          Read up to `NR * NC' elements, returning a matrix with NR
+          rows.  If the number of elements read is not an exact multiple
+          of NR, the last column is padded with zeros.
+
+     If SIZE is omitted, a value of `Inf' is assumed.
+
+     A string is returned if TEMPLATE specifies only character
+     conversions.
+
+     The number of items successfully read is returned in COUNT.
+
+     In the second form, read from FID according to TEMPLATE, with each
+     conversion specifier in TEMPLATE corresponding to a single scalar
+     return value.  This form is more `C-like', and also compatible
+     with previous versions of Octave.  The number of successful
+     conversions is returned in COUNT
+
+     *See also:* *note scanf: doc-scanf, *note sscanf: doc-sscanf,
+     *note fread: doc-fread, *note fprintf: doc-fprintf, *note fgets:
+     doc-fgets, *note fputs: doc-fputs.
+
+ -- Built-in Function: [VAL, COUNT] = scanf (TEMPLATE, SIZE)
+ -- Built-in Function: [V1, V2, ..., COUNT]] = scanf (TEMPLATE, "C")
+     This is equivalent to calling `fscanf' with FID = `stdin'.
+
+     It is currently not useful to call `scanf' in interactive programs.
+
+     *See also:* *note fscanf: doc-fscanf, *note sscanf: doc-sscanf,
+     *note printf: doc-printf.
+
+ -- Built-in Function: [VAL, COUNT] = sscanf (STRING, TEMPLATE, SIZE)
+ -- Built-in Function: [V1, V2, ..., COUNT] = sscanf (STRING, TEMPLATE,
+          "C")
+     This is like `fscanf', except that the characters are taken from
+     the string STRING instead of from a stream.  Reaching the end of
+     the string is treated as an end-of-file condition.
+
+     *See also:* *note fscanf: doc-fscanf, *note scanf: doc-scanf,
+     *note sprintf: doc-sprintf.
+
+   Calls to `scanf' are superficially similar to calls to `printf' in
+that arbitrary arguments are read under the control of a template
+string.  While the syntax of the conversion specifications in the
+template is very similar to that for `printf', the interpretation of
+the template is oriented more towards free-format input and simple
+pattern matching, rather than fixed-field formatting.  For example,
+most `scanf' conversions skip over any amount of "white space"
+(including spaces, tabs, and newlines) in the input file, and there is
+no concept of precision for the numeric input conversions as there is
+for the corresponding output conversions.  Ordinarily, non-whitespace
+characters in the template are expected to match characters in the
+input stream exactly.  
+
+   When a "matching failure" occurs, `scanf' returns immediately,
+leaving the first non-matching character as the next character to be
+read from the stream, and `scanf' returns all the items that were
+successfully converted.  
+
+   The formatted input functions are not used as frequently as the
+formatted output functions.  Partly, this is because it takes some care
+to use them properly.  Another reason is that it is difficult to recover
+from a matching error.
+
+
+File: octave.info,  Node: Input Conversion Syntax,  Next: Table of Input Conversions,  Prev: Formatted Input,  Up: C-Style I/O Functions
+
+14.2.12 Input Conversion Syntax
+-------------------------------
+
+A `scanf' template string is a string that contains ordinary multibyte
+characters interspersed with conversion specifications that start with
+`%'.
+
+   Any whitespace character in the template causes any number of
+whitespace characters in the input stream to be read and discarded.
+The whitespace characters that are matched need not be exactly the same
+whitespace characters that appear in the template string.  For example,
+write ` , ' in the template to recognize a comma with optional
+whitespace before and after.
+
+   Other characters in the template string that are not part of
+conversion specifications must match characters in the input stream
+exactly; if this is not the case, a matching failure occurs.
+
+   The conversion specifications in a `scanf' template string have the
+general form:
+
+     % FLAGS WIDTH TYPE CONVERSION
+
+   In more detail, an input conversion specification consists of an
+initial `%' character followed in sequence by:
+
+   * An optional "flag character" `*', which says to ignore the text
+     read for this specification.  When `scanf' finds a conversion
+     specification that uses this flag, it reads input as directed by
+     the rest of the conversion specification, but it discards this
+     input, does not return any value, and does not increment the count
+     of successful assignments.  
+
+   * An optional decimal integer that specifies the "maximum field
+     width".  Reading of characters from the input stream stops either
+     when this maximum is reached or when a non-matching character is
+     found, whichever happens first.  Most conversions discard initial
+     whitespace characters, and these discarded characters don't count
+     towards the maximum field width.  Conversions that do not discard
+     initial whitespace are explicitly documented.  
+
+   * An optional type modifier character.  This character is ignored by
+     Octave's `scanf' function, but is recognized to provide
+     compatibility with the C language `scanf'.
+
+   * A character that specifies the conversion to be applied.
+
+   The exact options that are permitted and how they are interpreted
+vary between the different conversion specifiers.  See the descriptions
+of the individual conversions for information about the particular
+options that they allow.
+
+
+File: octave.info,  Node: Table of Input Conversions,  Next: Numeric Input Conversions,  Prev: Input Conversion Syntax,  Up: C-Style I/O Functions
+
+14.2.13 Table of Input Conversions
+----------------------------------
+
+Here is a table that summarizes the various conversion specifications:
+
+`%d'
+     Matches an optionally signed integer written in decimal.  *Note
+     Numeric Input Conversions::.
+
+`%i'
+     Matches an optionally signed integer in any of the formats that
+     the C language defines for specifying an integer constant.  *Note
+     Numeric Input Conversions::.
+
+`%o'
+     Matches an unsigned integer written in octal radix.  *Note Numeric
+     Input Conversions::.
+
+`%u'
+     Matches an unsigned integer written in decimal radix.  *Note
+     Numeric Input Conversions::.
+
+`%x', `%X'
+     Matches an unsigned integer written in hexadecimal radix.  *Note
+     Numeric Input Conversions::.
+
+`%e', `%f', `%g', `%E', `%G'
+     Matches an optionally signed floating-point number.  *Note Numeric
+     Input Conversions::.
+
+`%s'
+     Matches a string containing only non-whitespace characters.  *Note
+     String Input Conversions::.
+
+`%c'
+     Matches a string of one or more characters; the number of
+     characters read is controlled by the maximum field width given for
+     the conversion.  *Note String Input Conversions::.
+
+`%%'
+     This matches a literal `%' character in the input stream.  No
+     corresponding argument is used.
+
+   If the syntax of a conversion specification is invalid, the behavior
+is undefined.  If there aren't enough function arguments provided to
+supply addresses for all the conversion specifications in the template
+strings that perform assignments, or if the arguments are not of the
+correct types, the behavior is also undefined.  On the other hand, extra
+arguments are simply ignored.
+
+
+File: octave.info,  Node: Numeric Input Conversions,  Next: String Input Conversions,  Prev: Table of Input Conversions,  Up: C-Style I/O Functions
+
+14.2.14 Numeric Input Conversions
+---------------------------------
+
+This section describes the `scanf' conversions for reading numeric
+values.
+
+   The `%d' conversion matches an optionally signed integer in decimal
+radix.
+
+   The `%i' conversion matches an optionally signed integer in any of
+the formats that the C language defines for specifying an integer
+constant.
+
+   For example, any of the strings `10', `0xa', or `012' could be read
+in as integers under the `%i' conversion.  Each of these specifies a
+number with decimal value `10'.
+
+   The `%o', `%u', and `%x' conversions match unsigned integers in
+octal, decimal, and hexadecimal radices, respectively.
+
+   The `%X' conversion is identical to the `%x' conversion.  They both
+permit either uppercase or lowercase letters to be used as digits.
+
+   Unlike the C language `scanf', Octave ignores the `h', `l', and `L'
+modifiers.
+
+
+File: octave.info,  Node: String Input Conversions,  Next: Binary I/O,  Prev: Numeric Input Conversions,  Up: C-Style I/O Functions
+
+14.2.15 String Input Conversions
+--------------------------------
+
+This section describes the `scanf' input conversions for reading string
+and character values: `%s' and `%c'.
+
+   The `%c' conversion is the simplest: it matches a fixed number of
+characters, always.  The maximum field with says how many characters to
+read; if you don't specify the maximum, the default is 1.  This
+conversion does not skip over initial whitespace characters.  It reads
+precisely the next N characters, and fails if it cannot get that many.
+
+   The `%s' conversion matches a string of non-whitespace characters.
+It skips and discards initial whitespace, but stops when it encounters
+more whitespace after having read something.
+
+   For example, reading the input:
+
+      hello, world
+
+with the conversion `%10c' produces `" hello, wo"', but reading the
+same input with the conversion `%10s' produces `"hello,"'.
+
+
+File: octave.info,  Node: Binary I/O,  Next: Temporary Files,  Prev: String Input Conversions,  Up: C-Style I/O Functions
+
+14.2.16 Binary I/O
+------------------
+
+Octave can read and write binary data using the functions `fread' and
+`fwrite', which are patterned after the standard C functions with the
+same names.  They are able to automatically swap the byte order of
+integer data and convert among the supported floating point formats as
+the data are read.
+
+ -- Built-in Function: [VAL, COUNT] = fread (FID, SIZE, PRECISION,
+          SKIP, ARCH)
+     Read binary data of type PRECISION from the specified file ID FID.
+
+     The optional argument SIZE specifies the amount of data to read
+     and may be one of
+
+    `Inf'
+          Read as much as possible, returning a column vector.
+
+    `NR'
+          Read up to NR elements, returning a column vector.
+
+    `[NR, Inf]'
+          Read as much as possible, returning a matrix with NR rows.
+          If the number of elements read is not an exact multiple of
+          NR, the last column is padded with zeros.
+
+    `[NR, NC]'
+          Read up to `NR * NC' elements, returning a matrix with NR
+          rows.  If the number of elements read is not an exact multiple
+          of NR, the last column is padded with zeros.
+
+     If SIZE is omitted, a value of `Inf' is assumed.
+
+     The optional argument PRECISION is a string specifying the type of
+     data to read and may be one of
+
+    `"schar"'
+    `"signed char"'
+          Signed character.
+
+    `"uchar"'
+    `"unsigned char"'
+          Unsigned character.
+
+    `"int8"'
+    `"integer*1"'
+          8-bit signed integer.
+
+    `"int16"'
+    `"integer*2"'
+          16-bit signed integer.
+
+    `"int32"'
+    `"integer*4"'
+          32-bit signed integer.
+
+    `"int64"'
+    `"integer*8"'
+          64-bit signed integer.
+
+    `"uint8"'
+          8-bit unsigned integer.
+
+    `"uint16"'
+          16-bit unsigned integer.
+
+    `"uint32"'
+          32-bit unsigned integer.
+
+    `"uint64"'
+          64-bit unsigned integer.
+
+    `"single"'
+    `"float32"'
+    `"real*4"'
+          32-bit floating point number.
+
+    `"double"'
+    `"float64"'
+    `"real*8"'
+          64-bit floating point number.
+
+    `"char"'
+    `"char*1"'
+          Single character.
+
+    `"short"'
+          Short integer (size is platform dependent).
+
+    `"int"'
+          Integer (size is platform dependent).
+
+    `"long"'
+          Long integer (size is platform dependent).
+
+    `"ushort"'
+    `"unsigned short"'
+          Unsigned short integer (size is platform dependent).
+
+    `"uint"'
+    `"unsigned int"'
+          Unsigned integer (size is platform dependent).
+
+    `"ulong"'
+    `"unsigned long"'
+          Unsigned long integer (size is platform dependent).
+
+    `"float"'
+          Single precision floating point number (size is platform
+          dependent).
+
+     The default precision is `"uchar"'.
+
+     The PRECISION argument may also specify an optional repeat count.
+     For example, `32*single' causes `fread' to read a block of 32
+     single precision floating point numbers.  Reading in blocks is
+     useful in combination with the SKIP argument.
+
+     The PRECISION argument may also specify a type conversion.  For
+     example, `int16=>int32' causes `fread' to read 16-bit integer
+     values and return an array of 32-bit integer values.  By default,
+     `fread' returns a double precision array.  The special form
+     `*TYPE' is shorthand for `TYPE=>TYPE'.
+
+     The conversion and repeat counts may be combined.  For example, the
+     specification `32*single=>single' causes `fread' to read blocks of
+     single precision floating point values and return an array of
+     single precision values instead of the default array of double
+     precision values.
+
+     The optional argument SKIP specifies the number of bytes to skip
+     after each element (or block of elements) is read.  If it is not
+     specified, a value of 0 is assumed.  If the final block read is not
+     complete, the final skip is omitted.  For example,
+
+          fread (f, 10, "3*single=>single", 8)
+
+     will omit the final 8-byte skip because the last read will not be
+     a complete block of 3 values.
+
+     The optional argument ARCH is a string specifying the data format
+     for the file.  Valid values are
+
+    `"native"'
+          The format of the current machine.
+
+    `"ieee-be"'
+          IEEE big endian.
+
+    `"ieee-le"'
+          IEEE little endian.
+
+    `"vaxd"'
+          VAX D floating format.
+
+    `"vaxg"'
+          VAX G floating format.
+
+    `"cray"'
+          Cray floating format.
+
+     Conversions are currently only supported for `"ieee-be"' and
+     `"ieee-le"' formats.
+
+     The data read from the file is returned in VAL, and the number of
+     values read is returned in `count'
+
+     *See also:* *note fwrite: doc-fwrite, *note fopen: doc-fopen,
+     *note fclose: doc-fclose.
+
+ -- Built-in Function: COUNT = fwrite (FID, DATA, PRECISION, SKIP, ARCH)
+     Write data in binary form of type PRECISION to the specified file
+     ID FID, returning the number of values successfully written to the
+     file.
+
+     The argument DATA is a matrix of values that are to be written to
+     the file.  The values are extracted in column-major order.
+
+     The remaining arguments PRECISION, SKIP, and ARCH are optional,
+     and are interpreted as described for `fread'.
+
+     The behavior of `fwrite' is undefined if the values in DATA are
+     too large to fit in the specified precision.
+
+     *See also:* *note fread: doc-fread, *note fopen: doc-fopen, *note
+     fclose: doc-fclose.
+
+
+File: octave.info,  Node: Temporary Files,  Next: EOF and Errors,  Prev: Binary I/O,  Up: C-Style I/O Functions
+
+14.2.17 Temporary Files
+-----------------------
+
+Sometimes one needs to write data to a file that is only temporary.
+This is most commonly used when an external program launched from
+within Octave needs to access data.  When Octave exits all temporary
+files will be deleted, so this step need not be executed manually.
+
+ -- Built-in Function: [FID, NAME, MSG] = mkstemp (TEMPLATE, DELETE)
+     Return the file ID corresponding to a new temporary file with a
+     unique name created from TEMPLATE.  The last six characters of
+     TEMPLATE must be `XXXXXX' and these are replaced with a string
+     that makes the filename unique.  The file is then created with
+     mode read/write and permissions that are system dependent (on
+     GNU/Linux systems, the permissions will be 0600 for versions of
+     glibc 2.0.7 and later).  The file is opened with the `O_EXCL' flag.
+
+     If the optional argument DELETE is supplied and is true, the file
+     will be deleted automatically when Octave exits, or when the
+     function `purge_tmp_files' is called.
+
+     If successful, FID is a valid file ID, NAME is the name of the
+     file, and MSG is an empty string.  Otherwise, FID is -1, NAME is
+     empty, and MSG contains a system-dependent error message.
+
+     *See also:* *note tmpfile: doc-tmpfile, *note tmpnam: doc-tmpnam,
+     *note P_tmpdir: doc-P_tmpdir.
+
+ -- Built-in Function: [FID, MSG] = tmpfile ()
+     Return the file ID corresponding to a new temporary file with a
+     unique name.  The file is opened in binary read/write (`"w+b"')
+     mode.  The file will be deleted automatically when it is closed or
+     when Octave exits.
+
+     If successful, FID is a valid file ID and MSG is an empty string.
+     Otherwise, FID is -1 and MSG contains a system-dependent error
+     message.
+
+     *See also:* *note tmpnam: doc-tmpnam, *note mkstemp: doc-mkstemp,
+     *note P_tmpdir: doc-P_tmpdir.
+
+ -- Built-in Function:  tmpnam (DIR, PREFIX)
+     Return a unique temporary file name as a string.
+
+     If PREFIX is omitted, a value of `"oct-"' is used.  If DIR is also
+     omitted, the default directory for temporary files is used.  If
+     DIR is provided, it must exist, otherwise the default directory
+     for temporary files is used.  Since the named file is not opened,
+     by `tmpnam', it is possible (though relatively unlikely) that it
+     will not be available by the time your program attempts to open it.
+
+     *See also:* *note tmpfile: doc-tmpfile, *note mkstemp:
+     doc-mkstemp, *note P_tmpdir: doc-P_tmpdir.
+
+
+File: octave.info,  Node: EOF and Errors,  Next: File Positioning,  Prev: Temporary Files,  Up: C-Style I/O Functions
+
+14.2.18 End of File and Errors
+------------------------------
+
+Once a file has been opened its status can be acquired.  As an example
+the `feof' functions determines if the end of the file has been
+reached.  This can be very useful when reading small parts of a file at
+a time.  The following example shows how to read one line at a time
+from a file until the end has been reached.
+
+     filename = "myfile.txt";
+     fid = fopen (filename, "r");
+     while (! feof (fid) )
+       text_line = fgetl (fid);
+     endwhile
+     fclose (fid);
+
+Note that in some situations it is more efficient to read the entire
+contents of a file and then process it, than it is to read it line by
+line.  This has the potential advantage of removing the loop in the
+above code.
+
+ -- Built-in Function:  feof (FID)
+     Return 1 if an end-of-file condition has been encountered for a
+     given file and 0 otherwise.  Note that it will only return 1 if
+     the end of the file has already been encountered, not if the next
+     read operation will result in an end-of-file condition.
+
+     *See also:* *note fread: doc-fread, *note fopen: doc-fopen, *note
+     fclose: doc-fclose.
+
+ -- Built-in Function:  ferror (FID)
+     Return 1 if an error condition has been encountered for a given
+     file and 0 otherwise.  Note that it will only return 1 if an error
+     has already been encountered, not if the next operation will
+     result in an error condition.
+
+ -- Built-in Function:  fclear (FID)
+     Clear the stream state for the specified file.
+
+ -- Built-in Function:  freport ()
+     Print a list of which files have been opened, and whether they are
+     open for reading, writing, or both.  For example,
+
+          freport ()
+
+               -|  number  mode  name
+               -|
+               -|       0     r  stdin
+               -|       1     w  stdout
+               -|       2     w  stderr
+               -|       3     r  myfile
+
+
+File: octave.info,  Node: File Positioning,  Prev: EOF and Errors,  Up: C-Style I/O Functions
+
+14.2.19 File Positioning
+------------------------
+
+Three functions are available for setting and determining the position
+of the file pointer for a given file.
+
+ -- Built-in Function:  ftell (FID)
+     Return the position of the file pointer as the number of characters
+     from the beginning of the file FID.
+
+     *See also:* *note fseek: doc-fseek, *note fopen: doc-fopen, *note
+     fclose: doc-fclose.
+
+ -- Built-in Function:  fseek (FID, OFFSET, ORIGIN)
+     Set the file pointer to any location within the file FID.
+
+     The pointer is positioned OFFSET characters from the ORIGIN, which
+     may be one of the predefined variables `SEEK_CUR' (current
+     position), `SEEK_SET' (beginning), or `SEEK_END' (end of file) or
+     strings "cof", "bof" or "eof".  If ORIGIN is omitted, `SEEK_SET'
+     is assumed.  The offset must be zero, or a value returned by
+     `ftell' (in which case ORIGIN must be `SEEK_SET').
+
+     Return 0 on success and -1 on error.
+
+     *See also:* *note ftell: doc-ftell, *note fopen: doc-fopen, *note
+     fclose: doc-fclose.
+
+ -- Built-in Function:  SEEK_SET ()
+ -- Built-in Function:  SEEK_CUR ()
+ -- Built-in Function:  SEEK_END ()
+     Return the value required to request that `fseek' perform one of
+     the following actions:
+    `SEEK_SET'
+          Position file relative to the beginning.
+
+    `SEEK_CUR'
+          Position file relative to the current position.
+
+    `SEEK_END'
+          Position file relative to the end.
+
+ -- Built-in Function:  frewind (FID)
+     Move the file pointer to the beginning of the file FID, returning
+     0 for success, and -1 if an error was encountered.  It is
+     equivalent to `fseek (FID, 0, SEEK_SET)'.
+
+   The following example stores the current file position in the
+variable `marker', moves the pointer to the beginning of the file, reads
+four characters, and then returns to the original position.
+
+     marker = ftell (myfile);
+     frewind (myfile);
+     fourch = fgets (myfile, 4);
+     fseek (myfile, marker, SEEK_SET);
+
+
+File: octave.info,  Node: Plotting,  Next: Matrix Manipulation,  Prev: Input and Output,  Up: Top
+
+15 Plotting
+***********
+
+* Menu:
+
+* Plotting Basics::
+* Advanced Plotting::
+
+
+File: octave.info,  Node: Plotting Basics,  Next: Advanced Plotting,  Up: Plotting
+
+15.1 Plotting Basics
+====================
+
+Octave makes it easy to create many different types of two- and
+three-dimensional plots using a few high-level functions.
+
+   If you need finer control over graphics, see *note Advanced
+Plotting::.
+
+* Menu:
+
+* Two-Dimensional Plots::
+* Three-Dimensional Plotting::
+* Plot Annotations::
+* Multiple Plots on One Page::
+* Multiple Plot Windows::
+* Printing Plots::
+* Interacting with plots::
+* Test Plotting Functions::
+
+
+File: octave.info,  Node: Two-Dimensional Plots,  Next: Three-Dimensional Plotting,  Up: Plotting Basics
+
+15.1.1 Two-Dimensional Plots
+----------------------------
+
+The `plot' function allows you to create simple x-y plots with linear
+axes.  For example,
+
+     x = -10:0.1:10;
+     plot (x, sin (x));
+
+displays a sine wave shown in *note fig:plot::.  On most systems, this
+command will open a separate plot window to display the graph.
+
+ [image src="plot.png" text="
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
+" ]
+Figure 15.1: Simple Two-Dimensional Plot.
+
+ -- Function File:  plot (Y)
+ -- Function File:  plot (X, Y)
+ -- Function File:  plot (X, Y, PROPERTY, VALUE, ...)
+ -- Function File:  plot (X, Y, FMT)
+ -- Function File:  plot (H, ...)
+     Produces two-dimensional plots.  Many different combinations of
+     arguments are possible.  The simplest form is
+
+          plot (Y)
+
+     where the argument is taken as the set of Y coordinates and the X
+     coordinates are taken to be the indices of the elements, starting
+     with 1.
+
+     To save a plot, in one of several image formats such as PostScript
+     or PNG, use the `print' command.
+
+     If more than one argument is given, they are interpreted as
+
+          plot (Y, PROPERTY, VALUE, ...)
+
+     or
+
+          plot (X, Y, PROPERTY, VALUE, ...)
+
+     or
+
+          plot (X, Y, FMT, ...)
+
+     and so on.  Any number of argument sets may appear.  The X and Y
+     values are interpreted as follows:
+
+        * If a single data argument is supplied, it is taken as the set
+          of Y coordinates and the X coordinates are taken to be the
+          indices of the elements, starting with 1.
+
+        * If the X is a vector and Y is a matrix, then the columns (or
+          rows) of Y are plotted versus X.  (using whichever
+          combination matches, with columns tried first.)
+
+        * If the X is a matrix and Y is a vector, Y is plotted versus
+          the columns (or rows) of X.  (using whichever combination
+          matches, with columns tried first.)
+
+        * If both arguments are vectors, the elements of Y are plotted
+          versus the elements of X.
+
+        * If both arguments are matrices, the columns of Y are plotted
+          versus the columns of X.  In this case, both matrices must
+          have the same number of rows and columns and no attempt is
+          made to transpose the arguments to make the number of rows
+          match.
+
+          If both arguments are scalars, a single point is plotted.
+
+     Multiple property-value pairs may be specified, but they must
+     appear in pairs.  These arguments are applied to the lines drawn by
+     `plot'.
+
+     If the FMT argument is supplied, it is interpreted as follows.  If
+     FMT is missing, the default gnuplot line style is assumed.
+
+    `-'
+          Set lines plot style (default).
+
+    `.'
+          Set dots plot style.
+
+    `N'
+          Interpreted as the plot color if N is an integer in the range
+          1 to 6.
+
+    `NM'
+          If NM is a two digit integer and M is an integer in the range
+          1 to 6, M is interpreted as the point style.  This is only
+          valid in combination with the `@' or `-@' specifiers.
+
+    `C'
+          If C is one of `"k"' (black), `"r"' (red), `"g"' (green),
+          `"b"' (blue), `"m"' (magenta), `"c"' (cyan), or `"w"'
+          (white), it is interpreted as the line plot color.
+
+    `";title;"'
+          Here `"title"' is the label for the key.
+
+    `+'
+    `*'
+    `o'
+    `x'
+    `^'
+          Used in combination with the points or linespoints styles,
+          set the point style.
+
+     The FMT argument may also be used to assign key titles.  To do so,
+     include the desired title between semi-colons after the formatting
+     sequence described above, e.g., "+3;Key Title;" Note that the last
+     semi-colon is required and will generate an error if it is left
+     out.
+
+     Here are some plot examples:
+
+          plot (x, y, "@12", x, y2, x, y3, "4", x, y4, "+")
+
+     This command will plot `y' with points of type 2 (displayed as
+     `+') and color 1 (red), `y2' with lines, `y3' with lines of color
+     4 (magenta) and `y4' with points displayed as `+'.
+
+          plot (b, "*", "markersize", 3)
+
+     This command will plot the data in the variable `b', with points
+     displayed as `*' with a marker size of 3.
+
+          t = 0:0.1:6.3;
+          plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+
+     This will plot the cosine and sine functions and label them
+     accordingly in the key.
+
+     If the first argument is an axis handle, then plot into these axes,
+     rather than the current axis handle returned by `gca'.
+
+     *See also:* *note semilogx: doc-semilogx, *note semilogy:
+     doc-semilogy, *note loglog: doc-loglog, *note polar: doc-polar,
+     *note mesh: doc-mesh, *note contour: doc-contour, *note bar:
+     doc-bar, *note stairs: doc-stairs, *note errorbar: doc-errorbar,
+     *note xlabel: doc-xlabel, *note ylabel: doc-ylabel, *note title:
+     doc-title, *note print: doc-print.
+
+   The `plotyy' function may be used to create a plot with two
+independent y axes.
+
+ -- Function File:  plotyy (X1, Y1, X2, Y2)
+ -- Function File:  plotyy (..., FUN)
+ -- Function File:  plotyy (..., FUN1, FUN2)
+ -- Function File:  plotyy (H, ...)
+ -- Function File: [AX, H1, H2] = plotyy (...)
+     Plots two sets of data with independent y-axes.  The arguments X1
+     and Y1 define the arguments for the first plot and X1 and Y2 for
+     the second.
+
+     By default the arguments are evaluated with `feval (@plot, X, Y)'.
+     However the type of plot can be modified with the FUN argument, in
+     which case the plots are generated by `feval (FUN, X, Y)'.  FUN
+     can be a function handle, an inline function or a string of a
+     function name.
+
+     The function to use for each of the plots can be independently
+     defined with FUN1 and FUN2.
+
+     If given, H defines the principal axis in which to plot the X1 and
+     Y1 data.  The return value AX is a two element vector with the
+     axis handles of the two plots.  H1 and H2 are handles to the
+     objects generated by the plot commands.
+
+          x = 0:0.1:2*pi;
+          y1 = sin (x);
+          y2 = exp (x - 1);
+          ax = plotyy (x, y1, x - 1, y2, @plot, @semilogy);
+          xlabel ("X");
+          ylabel (ax(1), "Axis 1");
+          ylabel (ax(2), "Axis 2");
+
+   The functions `semilogx', `semilogy', and `loglog' are similar to
+the `plot' function, but produce plots in which one or both of the axes
+use log scales.
+
+ -- Function File:  semilogx (ARGS)
+     Produce a two-dimensional plot using a log scale for the X axis.
+     See the description of `plot' for a description of the arguments
+     that `semilogx' will accept.
+
+     *See also:* *note plot: doc-plot, *note semilogy: doc-semilogy,
+     *note loglog: doc-loglog.
+
+ -- Function File:  semilogy (ARGS)
+     Produce a two-dimensional plot using a log scale for the Y axis.
+     See the description of `plot' for a description of the arguments
+     that `semilogy' will accept.
+
+     *See also:* *note plot: doc-plot, *note semilogx: doc-semilogx,
+     *note loglog: doc-loglog.
+
+ -- Function File:  loglog (ARGS)
+     Produce a two-dimensional plot using log scales for both axes.  See
+     the description of `plot' for a description of the arguments that
+     `loglog' will accept.
+
+     *See also:* *note plot: doc-plot, *note semilogx: doc-semilogx,
+     *note semilogy: doc-semilogy.
+
+   The functions `bar', `barh', `stairs', and `stem' are useful for
+displaying discrete data.  For example,
+
+     hist (randn (10000, 1), 30);
+
+produces the histogram of 10,000 normally distributed random numbers
+shown in *note fig:hist::.
+
+ [image src="hist.png" text="
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
+" ]
+Figure 15.2: Histogram.
+
+ -- Function File:  bar (X, Y)
+ -- Function File:  bar (Y)
+ -- Function File:  bar (X, Y, W)
+ -- Function File:  bar (X, Y, W, STYLE)
+ -- Function File: H = bar (..., PROP, VAL)
+ -- Function File:  bar (H, ...)
+     Produce a bar graph from two vectors of x-y data.
+
+     If only one argument is given, it is taken as a vector of y-values
+     and the x coordinates are taken to be the indices of the elements.
+
+     The default width of 0.8 for the bars can be changed using W.
+
+     If Y is a matrix, then each column of Y is taken to be a separate
+     bar graph plotted on the same graph.  By default the columns are
+     plotted side-by-side.  This behavior can be changed by the STYLE
+     argument, which can take the values `"grouped"' (the default), or
+     `"stacked"'.
+
+     The optional return value H provides a handle to the "bar series"
+     object with one handle per column of the variable Y.  This series
+     allows common elements of the group of bar series objects to be
+     changed in a single bar series and the same properties are changed
+     in the other "bar series".  For example
+
+          h = bar (rand (5, 10));
+          set (h(1), "basevalue", 0.5);
+
+     changes the position on the base of all of the bar series.
+
+     The optional input handle H allows an axis handle to be passed.
+     Properties of the patch graphics object can be changed using PROP,
+     VAL pairs.
+
+     *See also:* *note barh: doc-barh, *note plot: doc-plot.
+
+ -- Function File:  barh (X, Y)
+ -- Function File:  barh (Y)
+ -- Function File:  barh (X, Y, W)
+ -- Function File:  barh (X, Y, W, STYLE)
+ -- Function File: H = barh (..., PROP, VAL)
+ -- Function File:  barh (H, ...)
+     Produce a horizontal bar graph from two vectors of x-y data.
+
+     If only one argument is given, it is taken as a vector of y-values
+     and the x coordinates are taken to be the indices of the elements.
+
+     The default width of 0.8 for the bars can be changed using W.
+
+     If Y is a matrix, then each column of Y is taken to be a separate
+     bar graph plotted on the same graph.  By default the columns are
+     plotted side-by-side.  This behavior can be changed by the STYLE
+     argument, which can take the values `"grouped"' (the default), or
+     `"stacked"'.
+
+     The optional return value H provides a handle to the bar series
+     object.  See `bar' for a description of the use of the bar series.
+
+     The optional input handle H allows an axis handle to be passed.
+     Properties of the patch graphics object can be changed using PROP,
+     VAL pairs.
+
+     *See also:* *note bar: doc-bar, *note plot: doc-plot.
+
+ -- Function File:  hist (Y, X, NORM)
+     Produce histogram counts or plots.
+
+     With one vector input argument, plot a histogram of the values with
+     10 bins.  The range of the histogram bins is determined by the
+     range of the data.  With one matrix input argument, plot a
+     histogram where each bin contains a bar per input column.
+
+     Given a second scalar argument, use that as the number of bins.
+
+     Given a second vector argument, use that as the centers of the
+     bins, with the width of the bins determined from the adjacent
+     values in the vector.
+
+     If third argument is provided, the histogram is normalized such
+     that the sum of the bars is equal to NORM.
+
+     Extreme values are lumped in the first and last bins.
+
+     With two output arguments, produce the values NN and XX such that
+     `bar (XX, NN)' will plot the histogram.
+
+     *See also:* *note bar: doc-bar.
+
+ -- Function File:  stairs (X, Y)
+ -- Function File:  stairs (..., STYLE)
+ -- Function File:  stairs (..., PROP, VAL)
+ -- Function File:  stairs (H, ...)
+ -- Function File: H = stairs (...)
+     Produce a stairstep plot.  The arguments may be vectors or
+     matrices.
+
+     If only one argument is given, it is taken as a vector of y-values
+     and the x coordinates are taken to be the indices of the elements.
+
+     If two output arguments are specified, the data are generated but
+     not plotted.  For example,
+
+          stairs (x, y);
+
+     and
+
+          [xs, ys] = stairs (x, y);
+          plot (xs, ys);
+
+     are equivalent.
+
+     *See also:* *note plot: doc-plot, *note semilogx: doc-semilogx,
+     *note semilogy: doc-semilogy, *note loglog: doc-loglog, *note
+     polar: doc-polar, *note mesh: doc-mesh, *note contour:
+     doc-contour, *note bar: doc-bar, *note xlabel: doc-xlabel, *note
+     ylabel: doc-ylabel, *note title: doc-title.
+
+ -- Function File: H = stem (X, Y, LINESPEC)
+ -- Function File: H = stem (..., "filled")
+     Plot a stem graph from two vectors of x-y data.  If only one
+     argument is given, it is taken as the y-values and the x
+     coordinates are taken from the indices of the elements.
+
+     If Y is a matrix, then each column of the matrix is plotted as a
+     separate stem graph.  In this case X can either be a vector, the
+     same length as the number of rows in Y, or it can be a matrix of
+     the same size as Y.
+
+     The default color is `"r"' (red).  The default line style is `"-"'
+     and the default marker is `"o"'.  The line style can be altered by
+     the `linespec' argument in the same manner as the `plot' command.
+     For example
+
+          x = 1:10;
+          y = ones (1, length (x))*2.*x;
+          stem (x, y, "b");
+
+     plots 10 stems with heights from 2 to 20 in blue;
+
+     The return value of `stem' is a vector if "stem series" graphics
+     handles, with one handle per column of the variable Y.  This
+     handle regroups the elements of the stem graph together as the
+     children of the "stem series" handle, allowing them to be altered
+     together.  For example
+
+          x = [0 : 10].';
+          y = [sin(x), cos(x)]
+          h = stem (x, y);
+          set (h(2), "color", "g");
+          set (h(1), "basevalue", -1)
+
+     changes the color of the second "stem series"  and moves the base
+     line of the first.
+
+     *See also:* *note bar: doc-bar, *note barh: doc-barh, *note plot:
+     doc-plot.
+
+ -- Function File: H = stem3 (X, Y, Z, LINESPEC)
+     Plot a three-dimensional stem graph and return the handles of the
+     line and marker objects used to draw the stems as "stem series"
+     object.  The default color is `"r"' (red).  The default line style
+     is `"-"' and the default marker is `"o"'.
+
+     For example,
+          theta = 0:0.2:6;
+          stem3 (cos (theta), sin (theta), theta)
+
+     plots 31 stems with heights from 0 to 6 lying on a circle.  Color
+     definitions with rgb-triples are not valid!
+
+     *See also:* *note bar: doc-bar, *note barh: doc-barh, *note stem:
+     doc-stem, *note plot: doc-plot.
+
+ -- Function File:  scatter (X, Y, S, C)
+ -- Function File:  scatter (..., 'filled')
+ -- Function File:  scatter (..., STYLE)
+ -- Function File:  scatter (..., PROP, VAL)
+ -- Function File:  scatter (H, ...)
+ -- Function File: H = scatter (...)
+     Plot a scatter plot of the data.  A marker is plotted at each point
+     defined by the points in the vectors X and Y.  The size of the
+     markers used is determined by the S, which can be a scalar, a
+     vector of the same length of X and Y.  If S is not given or is an
+     empty matrix, then the default value of 8 points is used.
+
+     The color of the markers is determined by C, which can be a string
+     defining a fixed color, a 3 element vector giving the red, green
+     and blue components of the color, a vector of the same length as X
+     that gives a scaled index into the current colormap, or a N-by-3
+     matrix defining the colors of each of the markers individually.
+
+     The marker to use can be changed with the STYLE argument, that is a
+     string defining a marker in the same manner as the `plot' command.
+     If the argument 'filled' is given then the markers as filled.  All
+     additional arguments are passed to the underlying patch command.
+
+     The optional return value H provides a handle to the patch object
+
+          x = randn (100, 1);
+          y = randn (100, 1);
+          scatter (x, y, [], sqrt(x.^2 + y.^2));
+
+     *See also:* *note plot: doc-plot, *note patch: doc-patch, *note
+     scatter3: doc-scatter3.
+
+ -- Function File:  scatter3 (X, Y, Z, S, C)
+ -- Function File:  scatter3 (..., 'filled')
+ -- Function File:  scatter3 (..., STYLE)
+ -- Function File:  scatter3 (..., PROP, VAL)
+ -- Function File:  scatter3 (H, ...)
+ -- Function File: H = scatter3 (...)
+     Plot a scatter plot of the data in 3D.  A marker is plotted at
+     each point defined by the points in the vectors X, Y and Z.  The
+     size of the markers used is determined by S, which can be a scalar
+     or a vector of the same length of X, Y and Z.  If S is not given
+     or is an empty matrix, then the default value of 8 points is used.
+
+     The color of the markers is determined by C, which can be a string
+     defining a fixed color, a 3 element vector giving the red, green
+     and blue components of the color, a vector of the same length as X
+     that gives a scaled index into the current colormap, or a N-by-3
+     matrix defining the colors of each of the markers individually.
+
+     The marker to use can be changed with the STYLE argument, that is a
+     string defining a marker in the same manner as the `plot' command.
+     If the argument 'filled' is given then the markers as filled.  All
+     additional arguments are passed to the underlying patch command.
+
+     The optional return value H provides a handle to the patch object
+
+          [x, y, z] = peaks (20);
+          scatter3 (x(:), y(:), z(:), [], z(:));
+
+     *See also:* *note plot: doc-plot, *note patch: doc-patch, *note
+     scatter: doc-scatter.
+
+ -- Function File:  plotmatrix (X, Y)
+ -- Function File:  plotmatrix (X)
+ -- Function File:  plotmatrix (..., STYLE)
+ -- Function File:  plotmatrix (H, ...)
+ -- Function File: [H, AX, BIGAX, P, PAX] = plotmatrix (...)
+     Scatter plot of the columns of one matrix against another.  Given
+     the arguments X and Y, that have a matching number of rows,
+     `plotmatrix' plots a set of axes corresponding to
+
+          plot (X (:, i), Y (:, j)
+
+     Given a single argument X, then this is equivalent to
+
+          plotmatrix (X, X)
+
+     except that the diagonal of the set of axes will be replaced with
+     the histogram `hist (X (:, i))'.
+
+     The marker to use can be changed with the STYLE argument, that is a
+     string defining a marker in the same manner as the `plot' command.
+     If a leading axes handle H is passed to `plotmatrix', then this
+     axis will be used for the plot.
+
+     The optional return value H provides handles to the individual
+     graphics objects in the scatter plots, whereas AX returns the
+     handles to the scatter plot axis objects.  BIGAX is a hidden axis
+     object that surrounds the other axes, such that the commands
+     `xlabel', `title', etc., will be associated with this hidden axis.
+     Finally P returns the graphics objects associated with the
+     histogram and PAX the corresponding axes objects.
+
+          plotmatrix (randn (100, 3), 'g+')
+
+
+ -- Function File:  pareto (X)
+ -- Function File:  pareto (X, Y)
+ -- Function File:  pareto (H, ...)
+ -- Function File: H = pareto (...)
+     Draw a Pareto chart, also called ABC chart.  A Pareto chart is a
+     bar graph used to arrange information in such a way that
+     priorities for process improvement can be established.  It
+     organizes and displays information to show the relative importance
+     of data.  The chart is similar to the histogram or bar chart,
+     except that the bars are arranged in decreasing order from left to
+     right along the abscissa.
+
+     The fundamental idea (Pareto principle) behind the use of Pareto
+     diagrams is that the majority of an effect is due to a small
+     subset of the causes, so for quality improvement the first few (as
+     presented on the diagram) contributing causes to a problem usually
+     account for the majority of the result.  Thus, targeting these
+     "major causes" for elimination results in the most cost-effective
+     improvement scheme.
+
+     The data are passed as X and the abscissa as Y.  If Y is absent,
+     then the abscissa are assumed to be `1 : length (X)'.  Y can be a
+     string array, a cell array of strings or a numerical vector.
+
+     An example of the use of `pareto' is
+
+          Cheese = {"Cheddar", "Swiss", "Camembert", ...
+                    "Munster", "Stilton", "Blue"};
+          Sold = [105, 30, 70, 10, 15, 20];
+          pareto(Sold, Cheese);
+
+ -- Function File:  rose (TH, R)
+ -- Function File:  rose (H, ...)
+ -- Function File: H = rose (...)
+ -- Function File: [R, TH] = rose (...)
+     Plot an angular histogram.  With one vector argument TH, plots the
+     histogram with 20 angular bins.  If TH is a matrix, then each
+     column of TH produces a separate histogram.
+
+     If R is given and is a scalar, then the histogram is produced with
+     R bins.  If R is a vector, then the center of each bin are defined
+     by the values of R.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+     If two output arguments are requested, then rather than plotting
+     the histogram, the polar vectors necessary to plot the histogram
+     are returned.
+
+          [r, t] = rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)]);
+          polar (r, t);
+
+     *See also:* *note plot: doc-plot, *note compass: doc-compass,
+     *note polar: doc-polar, *note hist: doc-hist.
+
+   The `contour', `contourf' and `contourc' functions produce
+two-dimensional contour plots from three-dimensional data.
+
+ -- Function File:  contour (Z)
+ -- Function File:  contour (Z, VN)
+ -- Function File:  contour (X, Y, Z)
+ -- Function File:  contour (X, Y, Z, VN)
+ -- Function File:  contour (..., STYLE)
+ -- Function File:  contour (H, ...)
+ -- Function File: [C, H] = contour (...)
+     Plot level curves (contour lines) of the matrix Z, using the
+     contour matrix C computed by `contourc' from the same arguments;
+     see the latter for their interpretation.  The set of contour
+     levels, C, is only returned if requested.  For example:
+
+          x = 0:2;
+          y = x;
+          z = x' * y;
+          contour (x, y, z, 2:3)
+
+     The style to use for the plot can be defined with a line style
+     STYLE in a similar manner to the line styles used with the `plot'
+     command.  Any markers defined by STYLE are ignored.
+
+     The optional input and output argument H allows an axis handle to
+     be passed to `contour' and the handles to the contour objects to be
+     returned.
+
+     *See also:* *note contourc: doc-contourc, *note patch: doc-patch,
+     *note plot: doc-plot.
+
+ -- Function File: [C, H] = contourf (X, Y, Z, LVL)
+ -- Function File: [C, H] = contourf (X, Y, Z, N)
+ -- Function File: [C, H] = contourf (X, Y, Z)
+ -- Function File: [C, H] = contourf (Z, N)
+ -- Function File: [C, H] = contourf (Z, LVL)
+ -- Function File: [C, H] = contourf (Z)
+ -- Function File: [C, H] = contourf (AX, ...)
+ -- Function File: [C, H] = contourf (..., "PROPERTY", VAL)
+     Compute and plot filled contours of the matrix Z.  Parameters X, Y
+     and N or LVL are optional.
+
+     The return value C is a 2xn matrix containing the contour lines as
+     described in the help to the contourc function.
+
+     The return value H is handle-vector to the patch objects creating
+     the filled contours.
+
+     If X and Y are omitted they are taken as the row/column index of
+     Z.  N is a scalar denoting the number of lines to compute.
+     Alternatively LVL is a vector containing the contour levels.  If
+     only one value (e.g., lvl0) is wanted, set LVL to [lvl0, lvl0].
+     If both N or LVL are omitted a default value of 10 contour level
+     is assumed.
+
+     If provided, the filled contours are added to the axes object AX
+     instead of the current axis.
+
+     The following example plots filled contours of the `peaks'
+     function.
+          [x, y, z] = peaks (50);
+          contourf (x, y, z, -7:9)
+
+     *See also:* *note contour: doc-contour, *note contourc:
+     doc-contourc, *note patch: doc-patch.
+
+ -- Function File: [C, LEV] = contourc (X, Y, Z, VN)
+     Compute isolines (contour lines) of the matrix Z.  Parameters X, Y
+     and VN are optional.
+
+     The return value LEV is a vector of the contour levels.  The
+     return value C is a 2 by N matrix containing the contour lines in
+     the following format
+
+          C = [lev1, x1, x2, ..., levn, x1, x2, ...
+               len1, y1, y2, ..., lenn, y1, y2, ...]
+
+     in which contour line N has a level (height) of LEVN and length of
+     LENN.
+
+     If X and Y are omitted they are taken as the row/column index of
+     Z.  VN is either a scalar denoting the number of lines to compute
+     or a vector containing the values of the lines.  If only one value
+     is wanted, set `VN = [val, val]'; If VN is omitted it defaults to
+     10.
+
+     For example,
+          x = 0:2;
+          y = x;
+          z = x' * y;
+          contourc (x, y, z, 2:3)
+               =>   2.0000   2.0000   1.0000   3.0000   1.5000   2.0000
+               2.0000   1.0000   2.0000   2.0000   2.0000   1.5000
+
+     *See also:* *note contour: doc-contour.
+
+ -- Function File:  contour3 (Z)
+ -- Function File:  contour3 (Z, VN)
+ -- Function File:  contour3 (X, Y, Z)
+ -- Function File:  contour3 (X, Y, Z, VN)
+ -- Function File:  contour3 (..., STYLE)
+ -- Function File:  contour3 (H, ...)
+ -- Function File: [C, H] = contour3 (...)
+     Plot level curves (contour lines) of the matrix Z, using the
+     contour matrix C computed by `contourc' from the same arguments;
+     see the latter for their interpretation.  The contours are plotted
+     at the Z level corresponding to their contour.  The set of contour
+     levels, C, is only returned if requested.  For example:
+
+          contour3 (peaks (19));
+          hold on
+          surface (peaks (19), "facecolor", "none", "EdgeColor", "black")
+          colormap hot
+
+     The style to use for the plot can be defined with a line style
+     STYLE in a similar manner to the line styles used with the `plot'
+     command.  Any markers defined by STYLE are ignored.
+
+     The optional input and output argument H allows an axis handle to
+     be passed to `contour' and the handles to the contour objects to be
+     returned.
+
+     *See also:* *note contourc: doc-contourc, *note patch: doc-patch,
+     *note plot: doc-plot.
+
+   The `errorbar', `semilogxerr', `semilogyerr', and `loglogerr'
+functions produce plots with error bar markers.  For example,
+
+     x = 0:0.1:10;
+     y = sin (x);
+     yp =  0.1 .* randn (size (x));
+     ym = -0.1 .* randn (size (x));
+     errorbar (x, sin (x), ym, yp);
+
+produces the figure shown in *note fig:errorbar::.
+
+ [image src="errorbar.png" text="
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
+" ]
+Figure 15.3: Errorbar plot.
+
+ -- Function File:  errorbar (ARGS)
+     This function produces two-dimensional plots with errorbars.  Many
+     different combinations of arguments are possible.  The simplest
+     form is
+
+          errorbar (Y, EY)
+
+     where the first argument is taken as the set of Y coordinates and
+     the second argument EY is taken as the errors of the Y values.  X
+     coordinates are taken to be the indices of the elements, starting
+     with 1.
+
+     If more than two arguments are given, they are interpreted as
+
+          errorbar (X, Y, ..., FMT, ...)
+
+     where after X and Y there can be up to four error parameters such
+     as EY, EX, LY, UY, etc., depending on the plot type.  Any number
+     of argument sets may appear, as long as they are separated with a
+     format string FMT.
+
+     If Y is a matrix, X and error parameters must also be matrices
+     having same dimensions.  The columns of Y are plotted versus the
+     corresponding columns of X and errorbars are drawn from the
+     corresponding columns of error parameters.
+
+     If FMT is missing, yerrorbars ("~") plot style is assumed.
+
+     If the FMT argument is supplied, it is interpreted as in normal
+     plots.  In addition the following plot styles are supported by
+     errorbar:
+
+    `~'
+          Set yerrorbars plot style (default).
+
+    `>'
+          Set xerrorbars plot style.
+
+    `~>'
+          Set xyerrorbars plot style.
+
+    `#'
+          Set boxes plot style.
+
+    `#~'
+          Set boxerrorbars plot style.
+
+    `#~>'
+          Set boxxyerrorbars plot style.
+
+     Examples:
+
+          errorbar (X, Y, EX, ">")
+
+     produces an xerrorbar plot of Y versus X with X errorbars drawn
+     from X-EX to X+EX.
+
+          errorbar (X, Y1, EY, "~",
+                    X, Y2, LY, UY)
+
+     produces yerrorbar plots with Y1 and Y2 versus X.  Errorbars for
+     Y1 are drawn from Y1-EY to Y1+EY, errorbars for Y2 from Y2-LY to
+     Y2+UY.
+
+          errorbar (X, Y, LX, UX,
+                    LY, UY, "~>")
+
+     produces an xyerrorbar plot of Y versus X in which X errorbars are
+     drawn from X-LX to X+UX and Y errorbars from Y-LY to Y+UY.
+
+     *See also:* *note semilogxerr: doc-semilogxerr, *note semilogyerr:
+     doc-semilogyerr, *note loglogerr: doc-loglogerr.
+
+ -- Function File:  semilogxerr (ARGS)
+     Produce two-dimensional plots on a semilogarithm axis with
+     errorbars.  Many different combinations of arguments are possible.
+     The most used form is
+
+          semilogxerr (X, Y, EY, FMT)
+
+     which produces a semi-logarithm plot of Y versus X with errors in
+     the Y-scale defined by EY and the plot format defined by FMT.  See
+     errorbar for available formats and additional information.
+
+     *See also:* *note errorbar: doc-errorbar, *note loglogerr:
+     doc-loglogerr, *note semilogyerr: doc-semilogyerr.
+
+ -- Function File:  semilogyerr (ARGS)
+     Produce two-dimensional plots on a semilogarithm axis with
+     errorbars.  Many different combinations of arguments are possible.
+     The most used form is
+
+          semilogyerr (X, Y, EY, FMT)
+
+     which produces a semi-logarithm plot of Y versus X with errors in
+     the Y-scale defined by EY and the plot format defined by FMT.  See
+     errorbar for available formats and additional information.
+
+     *See also:* *note errorbar: doc-errorbar, *note loglogerr:
+     doc-loglogerr, *note semilogxerr: doc-semilogxerr.
+
+ -- Function File:  loglogerr (ARGS)
+     Produce two-dimensional plots on double logarithm axis with
+     errorbars.  Many different combinations of arguments are possible.
+     The most used form is
+
+          loglogerr (X, Y, EY, FMT)
+
+     which produces a double logarithm plot of Y versus X with errors
+     in the Y-scale defined by EY and the plot format defined by FMT.
+     See errorbar for available formats and additional information.
+
+     *See also:* *note errorbar: doc-errorbar, *note semilogxerr:
+     doc-semilogxerr, *note semilogyerr: doc-semilogyerr.
+
+   Finally, the `polar' function allows you to easily plot data in
+polar coordinates.  However, the display coordinates remain rectangular
+and linear.  For example,
+
+     polar (0:0.1:10*pi, 0:0.1:10*pi);
+
+produces the spiral plot shown in *note fig:polar::.
+
+ [image src="polar.png" text="
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
+" ]
+Figure 15.4: Polar plot.
+
+ -- Function File:  polar (THETA, RHO, FMT)
+     Make a two-dimensional plot given the polar coordinates THETA and
+     RHO.
+
+     The optional third argument specifies the line type.
+
+     *See also:* *note plot: doc-plot.
+
+ -- Function File:  pie (Y)
+ -- Function File:  pie (Y, EXPLODE)
+ -- Function File:  pie (..., LABELS)
+ -- Function File:  pie (H, ...);
+ -- Function File: H = pie (...);
+     Produce a pie chart.
+
+     Called with a single vector argument, produces a pie chart of the
+     elements in X, with the size of the slice determined by percentage
+     size of the values of X.
+
+     The variable EXPLODE is a vector of the same length as X that if
+     non zero 'explodes' the slice from the pie chart.
+
+     If given LABELS is a cell array of strings of the same length as
+     X, giving the labels of each of the slices of the pie chart.
+
+     The optional return value H provides a handle to the patch object.
+
+     *See also:* *note bar: doc-bar, *note stem: doc-stem.
+
+ -- Function File:  quiver (U, V)
+ -- Function File:  quiver (X, Y, U, V)
+ -- Function File:  quiver (..., S)
+ -- Function File:  quiver (..., STYLE)
+ -- Function File:  quiver (..., 'filled')
+ -- Function File:  quiver (H, ...)
+ -- Function File: H = quiver (...)
+     Plot the `(U, V)' components of a vector field in an `(X, Y)'
+     meshgrid.  If the grid is uniform, you can specify X and Y as
+     vectors.
+
+     If X and Y are undefined they are assumed to be `(1:M, 1:N)' where
+     `[M, N] = size(U)'.
+
+     The variable S is a scalar defining a scaling factor to use for
+     the arrows of the field relative to the mesh spacing.  A value of 0
+     disables all scaling.  The default value is 1.
+
+     The style to use for the plot can be defined with a line style
+     STYLE in a similar manner to the line styles used with the `plot'
+     command.  If a marker is specified then markers at the grid points
+     of the vectors are printed rather than arrows.  If the argument
+     'filled' is given then the markers as filled.
+
+     The optional return value H provides a quiver group that regroups
+     the components of the quiver plot (body, arrow and marker), and
+     allows them to be changed together
+
+          [x, y] = meshgrid (1:2:20);
+          h = quiver (x, y, sin (2*pi*x/10), sin (2*pi*y/10));
+          set (h, "maxheadsize", 0.33);
+
+     *See also:* *note plot: doc-plot.
+
+ -- Function File:  quiver3 (U, V, W)
+ -- Function File:  quiver3 (X, Y, Z, U, V, W)
+ -- Function File:  quiver3 (..., S)
+ -- Function File:  quiver3 (..., STYLE)
+ -- Function File:  quiver3 (..., 'filled')
+ -- Function File:  quiver3 (H, ...)
+ -- Function File: H = quiver3 (...)
+     Plot the `(U, V, W)' components of a vector field in an `(X, Y),
+     Z' meshgrid.  If the grid is uniform, you can specify X, Y Z as
+     vectors.
+
+     If X, Y and Z are undefined they are assumed to be `(1:M, 1:N,
+     1:P)' where `[M, N] = size(U)' and `P = max (size (W))'.
+
+     The variable S is a scalar defining a scaling factor to use for
+     the arrows of the field relative to the mesh spacing.  A value of 0
+     disables all scaling.  The default value is 1.
+
+     The style to use for the plot can be defined with a line style
+     STYLE in a similar manner to the line styles used with the `plot'
+     command.  If a marker is specified then markers at the grid points
+     of the vectors are printed rather than arrows.  If the argument
+     'filled' is given then the markers as filled.
+
+     The optional return value H provides a quiver group that regroups
+     the components of the quiver plot (body, arrow and marker), and
+     allows them to be changed together
+
+          [x, y, z] = peaks (25);
+          surf (x, y, z);
+          hold on;
+          [u, v, w] = surfnorm (x, y, z / 10);
+          h = quiver3 (x, y, z, u, v, w);
+          set (h, "maxheadsize", 0.33);
+
+     *See also:* *note plot: doc-plot.
+
+ -- Function File:  compass (U, V)
+ -- Function File:  compass (Z)
+ -- Function File:  compass (..., STYLE)
+ -- Function File:  compass (H, ...)
+ -- Function File: H = compass (...)
+     Plot the `(U, V)' components of a vector field emanating from the
+     origin of a polar plot.  If a single complex argument Z is given,
+     then `U = real (Z)' and `V = imag (Z)'.
+
+     The style to use for the plot can be defined with a line style
+     STYLE in a similar manner to the line styles used with the `plot'
+     command.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+          compass (eig (a))
+
+     *See also:* *note plot: doc-plot, *note polar: doc-polar, *note
+     quiver: doc-quiver, *note feather: doc-feather.
+
+ -- Function File:  feather (U, V)
+ -- Function File:  feather (Z)
+ -- Function File:  feather (..., STYLE)
+ -- Function File:  feather (H, ...)
+ -- Function File: H = feather (...)
+     Plot the `(U, V)' components of a vector field emanating from
+     equidistant points on the x-axis.  If a single complex argument Z
+     is given, then `U = real (Z)' and `V = imag (Z)'.
+
+     The style to use for the plot can be defined with a line style
+     STYLE in a similar manner to the line styles used with the `plot'
+     command.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          phi = [0 : 15 : 360] * pi / 180;
+          feather (sin (phi), cos (phi))
+
+     *See also:* *note plot: doc-plot, *note quiver: doc-quiver, *note
+     compass: doc-compass.
+
+ -- Function File:  pcolor (X, Y, C)
+ -- Function File:  pcolor (C)
+     Density plot for given matrices X, and Y from `meshgrid' and a
+     matrix C corresponding to the X and Y coordinates of the mesh's
+     vertices.  If X and Y are vectors, then a typical vertex is (X(j),
+     Y(i), C(i,j)).  Thus, columns of C correspond to different X
+     values and rows of C correspond to different Y values.
+
+     The `colormap' is scaled to the extents of C.  Limits may be
+     placed on the color axis by the command `caxis', or by setting the
+     `clim' property of the parent axis.
+
+     The face color of each cell of the mesh is determined by
+     interpolating the values of C for the cell's vertices.  Contrast
+     this with `imagesc' which renders one cell for each element of C.
+
+     `shading' modifies an attribute determining the manner by which the
+     face color of each cell is interpolated from the values of C, and
+     the visibility of the cells' edges.  By default the attribute is
+     "faceted", which renders a single color for each cell's face with
+     the edge visible.
+
+     H is the handle to the surface object.
+
+     *See also:* *note caxis: doc-caxis, *note contour: doc-contour,
+     *note meshgrid: doc-meshgrid, *note imagesc: doc-imagesc, *note
+     shading: doc-shading.
+
+ -- Function File:  area (X, Y)
+ -- Function File:  area (X, Y, LVL)
+ -- Function File:  area (..., PROP, VAL, ...)
+ -- Function File:  area (Y, ...)
+ -- Function File:  area (H, ...)
+ -- Function File: H = area (...)
+     Area plot of cumulative sum of the columns of Y.  This shows the
+     contributions of a value to a sum, and is functionally similar to
+     `plot (X, cumsum (Y, 2))', except that the area under the curve is
+     shaded.
+
+     If the X argument is omitted it is assumed to be given by `1 :
+     rows (Y)'.  A value LVL can be defined that determines where the
+     base level of the shading under the curve should be defined.
+
+     Additional arguments to the `area' function are passed to the
+     `patch'.  The optional return value H provides a handle to area
+     series object representing the patches of the areas.
+
+     *See also:* *note plot: doc-plot, *note patch: doc-patch.
+
+ -- Function File:  comet (Y)
+ -- Function File:  comet (X, Y)
+ -- Function File:  comet (X, Y, P)
+ -- Function File:  comet (AX, ...)
+     Produce a simple comet style animation along the trajectory
+     provided by the input coordinate vectors (X, Y), where X will
+     default to the indices of Y.
+
+     The speed of the comet may be controlled by P, which represents the
+     time which passes as the animation passes from one point to the
+     next.  The default for P is 0.1 seconds.
+
+     If AX is specified the animation is produced in that axis rather
+     than the `gca'.
+
+   The axis function may be used to change the axis limits of an
+existing plot and various other axis properties, such as the aspect
+ratio and the appearance of tic marks.
+
+ -- Function File:  axis (LIMITS)
+     Set axis limits for plots.
+
+     The argument LIMITS should be a 2, 4, or 6 element vector.  The
+     first and second elements specify the lower and upper limits for
+     the x axis.  The third and fourth specify the limits for the
+     y-axis, and the fifth and sixth specify the limits for the z-axis.
+
+     Without any arguments, `axis' turns autoscaling on.
+
+     With one output argument, `x = axis' returns the current axes
+
+     The vector argument specifying limits is optional, and additional
+     string arguments may be used to specify various axis properties.
+     For example,
+
+          axis ([1, 2, 3, 4], "square");
+
+     forces a square aspect ratio, and
+
+          axis ("labely", "tic");
+
+     turns tic marks on for all axes and tic mark labels on for the
+     y-axis only.
+
+     The following options control the aspect ratio of the axes.
+
+    `"square"'
+          Force a square aspect ratio.
+
+    `"equal"'
+          Force x distance to equal y-distance.
+
+    `"normal"'
+          Restore the balance.
+
+     The following options control the way axis limits are interpreted.
+
+    `"auto"'
+          Set the specified axes to have nice limits around the data or
+          all if no axes are specified.
+
+    `"manual"'
+          Fix the current axes limits.
+
+    `"tight"'
+          Fix axes to the limits of the data.
+
+     The option `"image"' is equivalent to `"tight"' and `"equal"'.
+
+     The following options affect the appearance of tic marks.
+
+    `"on"'
+          Turn tic marks and labels on for all axes.
+
+    `"off"'
+          Turn tic marks off for all axes.
+
+    `"tic[xyz]"'
+          Turn tic marks on for all axes, or turn them on for the
+          specified axes and off for the remainder.
+
+    `"label[xyz]"'
+          Turn tic labels on for all axes, or turn them on for the
+          specified axes and off for the remainder.
+
+    `"nolabel"'
+          Turn tic labels off for all axes.
+     Note, if there are no tic marks for an axis, there can be no
+     labels.
+
+     The following options affect the direction of increasing values on
+     the axes.
+
+    `"ij"'
+          Reverse y-axis, so lower values are nearer the top.
+
+    `"xy"'
+          Restore y-axis, so higher values are nearer the top.
+
+     If an axes handle is passed as the first argument, then operate on
+     this axes rather than the current axes.
+
+   Similarly the axis limits of the colormap can be changed with the
+caxis function.
+
+ -- Function File:  caxis (LIMITS)
+ -- Function File:  caxis (H, ...)
+     Set color axis limits for plots.
+
+     The argument LIMITS should be a 2 element vector specifying the
+     lower and upper limits to assign to the first and last value in the
+     colormap.  Values outside this range are clamped to the first and
+     last colormap entries.
+
+     If LIMITS is 'auto', then automatic colormap scaling is applied,
+     whereas if LIMITS is 'manual' the colormap scaling is set to
+     manual.
+
+     Called without any arguments to current color axis limits are
+     returned.
+
+     If an axes handle is passed as the first argument, then operate on
+     this axes rather than the current axes.
+
+   The `xlim', `ylim', and `zlim' functions may be used to get or set
+individual axis limits.  Each has the same form.
+
+ -- Function File: XL = xlim ()
+ -- Function File:  xlim (XL)
+ -- Function File: M = xlim ('mode')
+ -- Function File:  xlim (M)
+ -- Function File:  xlim (H, ...)
+     Get or set the limits of the x-axis of the current plot.  Called
+     without arguments `xlim' returns the x-axis limits of the current
+     plot.  If passed a two element vector XL, the limits of the x-axis
+     are set to this value.
+
+     The current mode for calculation of the x-axis can be returned
+     with a call `xlim ('mode')', and can be either 'auto' or 'manual'.
+     The current plotting mode can be set by passing either 'auto' or
+     'manual' as the argument.
+
+     If passed an handle as the first argument, then operate on this
+     handle rather than the current axes handle.
+
+     *See also:* *note ylim: doc-ylim, *note zlim: doc-zlim, *note set:
+     doc-set, *note get: doc-get, *note gca: doc-gca.
+
+* Menu:
+
+* Two-dimensional Function Plotting::
+
+
+File: octave.info,  Node: Two-dimensional Function Plotting,  Up: Two-Dimensional Plots
+
+15.1.1.1 Two-dimensional Function Plotting
+..........................................
+
+Octave can plot a function from a function handle inline function or
+string defining the function without the user needing to explicitly
+create the data to be plotted.  The function `fplot' also generates
+two-dimensional plots with linear axes using a function name and limits
+for the range of the x-coordinate instead of the x and y data.  For
+example,
+
+     fplot (@sin, [-10, 10], 201);
+
+produces a plot that is equivalent to the one above, but also includes a
+legend displaying the name of the plotted function.
+
+ -- Function File:  fplot (FN, LIMITS)
+ -- Function File:  fplot (FN, LIMITS, TOL)
+ -- Function File:  fplot (FN, LIMITS, N)
+ -- Function File:  fplot (..., FMT)
+     Plot a function FN, within the defined limits.  FN an be either a
+     string, a function handle or an inline function.  The limits of
+     the plot are given by LIMITS of the form `[XLO, XHI]' or `[XLO,
+     XHI, YLO, YHI]'.  TOL is the default tolerance to use for the
+     plot, and if TOL is an integer it is assumed that it defines the
+     number points to use in the plot.  The FMT argument is passed to
+     the plot command.
+
+             fplot ("cos", [0, 2*pi])
+             fplot ("[cos(x), sin(x)]", [0, 2*pi])
+
+     *See also:* *note plot: doc-plot.
+
+   Other functions that can create two-dimensional plots directly from a
+function include `ezplot', `ezcontour', `ezcontourf' and `ezpolar'.
+
+ -- Function File:  ezplot (F)
+ -- Function File:  ezplot (FX, FY)
+ -- Function File:  ezplot (..., DOM)
+ -- Function File:  ezplot (..., N)
+ -- Function File:  ezplot (H, ...)
+ -- Function File: H = ezplot (...)
+     Plots in two-dimensions the curve defined by F.  The function F
+     may be a string, inline function or function handle and can have
+     either one or two variables.  If F has one variable, then the
+     function is plotted over the domain `-2*pi < X < 2*pi' with 500
+     points.
+
+     If F has two variables then `F(X,Y) = 0' is calculated over the
+     meshed domain `-2*pi < X | Y < 2*pi' with 60 by 60 in the mesh.
+     For example
+
+          ezplot (@(X, Y) X .^ 2 - Y .^ 2 - 1)
+
+     If two functions are passed as strings, inline functions or
+     function handles, then the parametric function
+
+          X = FX (T)
+          Y = FY (T)
+
+     is plotted over the domain `-2*pi < T < 2*pi' with 500 points.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of X, Y and T.  If it is a four element vector, then
+     the minimum and maximum values of X and T are determined by the
+     first two elements and the minimum and maximum of Y by the second
+     pair of elements.
+
+     N is a scalar defining the number of points to use in plotting the
+     function.
+
+     The optional return value H provides a list of handles to the the
+     line objects plotted.
+
+     *See also:* *note plot: doc-plot, *note ezplot3: doc-ezplot3.
+
+ -- Function File:  ezcontour (F)
+ -- Function File:  ezcontour (..., DOM)
+ -- Function File:  ezcontour (..., N)
+ -- Function File:  ezcontour (H, ...)
+ -- Function File: H = ezcontour (...)
+     Plots the contour lines of a function.  F is a string, inline
+     function or function handle with two arguments defining the
+     function.  By default the plot is over the domain `-2*pi < X <
+     2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both X and Y.  If DOM is a four element vector,
+     then the minimum and maximum value of X and Y are specify
+     separately.
+
+     N is a scalar defining the number of points to use in each
+     dimension.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezcontour (f, [-3, 3]);
+
+     *See also:* *note ezplot: doc-ezplot, *note ezcontourf:
+     doc-ezcontourf, *note ezsurfc: doc-ezsurfc, *note ezmeshc:
+     doc-ezmeshc.
+
+ -- Function File:  ezcontourf (F)
+ -- Function File:  ezcontourf (..., DOM)
+ -- Function File:  ezcontourf (..., N)
+ -- Function File:  ezcontourf (H, ...)
+ -- Function File: H = ezcontourf (...)
+     Plots the filled contour lines of a function.  F is a string,
+     inline function or function handle with two arguments defining the
+     function.  By default the plot is over the domain `-2*pi < X <
+     2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both X and Y.  If DOM is a four element vector,
+     then the minimum and maximum value of X and Y are specify
+     separately.
+
+     N is a scalar defining the number of points to use in each
+     dimension.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezcontourf (f, [-3, 3]);
+
+     *See also:* *note ezplot: doc-ezplot, *note ezcontour:
+     doc-ezcontour, *note ezsurfc: doc-ezsurfc, *note ezmeshc:
+     doc-ezmeshc.
+
+ -- Function File:  ezpolar (F)
+ -- Function File:  ezpolar (..., DOM)
+ -- Function File:  ezpolar (..., N)
+ -- Function File:  ezpolar (H, ...)
+ -- Function File: H = ezpolar (...)
+     Plots in polar plot defined by a function.  The function F is
+     either a string, inline function or function handle with one
+     arguments defining the function.  By default the plot is over the
+     domain `0 < X < 2*pi' with 60 points.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both T.  N is a scalar defining the number of
+     points to use.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          ezpolar (@(t) 1 + sin (t));
+
+     *See also:* *note polar: doc-polar, *note ezplot: doc-ezplot,
+     *note ezsurf: doc-ezsurf, *note ezmesh: doc-ezmesh.
+
+
+File: octave.info,  Node: Three-Dimensional Plotting,  Next: Plot Annotations,  Prev: Two-Dimensional Plots,  Up: Plotting Basics
+
+15.1.2 Three-Dimensional Plotting
+---------------------------------
+
+The function `mesh' produces mesh surface plots.  For example,
+
+     tx = ty = linspace (-8, 8, 41)';
+     [xx, yy] = meshgrid (tx, ty);
+     r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+     tz = sin (r) ./ r;
+     mesh (tx, ty, tz);
+
+produces the familiar "sombrero" plot shown in *note fig:mesh::.  Note
+the use of the function `meshgrid' to create matrices of X and Y
+coordinates to use for plotting the Z data.  The `ndgrid' function is
+similar to `meshgrid', but works for N-dimensional matrices.
+
+ [image src="mesh.png" text="
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
+" ]
+Figure 15.5: Mesh plot.
+
+   The `meshc' function is similar to `mesh', but also produces a plot
+of contours for the surface.
+
+   The `plot3' function displays arbitrary three-dimensional data,
+without requiring it to form a surface.  For example
+
+     t = 0:0.1:10*pi;
+     r = linspace (0, 1, numel (t));
+     z = linspace (0, 1, numel (t));
+     plot3 (r.*sin(t), r.*cos(t), z);
+
+displays the spiral in three dimensions shown in *note fig:plot3::.
+
+ [image src="plot3.png" text="
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
+" ]
+Figure 15.6: Three dimensional spiral.
+
+   Finally, the `view' function changes the viewpoint for
+three-dimensional plots.
+
+ -- Function File:  mesh (X, Y, Z)
+     Plot a mesh given matrices X, and Y from `meshgrid' and a matrix Z
+     corresponding to the X and Y coordinates of the mesh.  If X and Y
+     are vectors, then a typical vertex is (X(j), Y(i), Z(i,j)).  Thus,
+     columns of Z correspond to different X values and rows of Z
+     correspond to different Y values.
+
+     *See also:* *note meshgrid: doc-meshgrid, *note contour:
+     doc-contour.
+
+ -- Function File:  meshc (X, Y, Z)
+     Plot a mesh and contour given matrices X, and Y from `meshgrid'
+     and a matrix Z corresponding to the X and Y coordinates of the
+     mesh.  If X and Y are vectors, then a typical vertex is (X(j),
+     Y(i), Z(i,j)).  Thus, columns of Z correspond to different X
+     values and rows of Z correspond to different Y values.
+
+     *See also:* *note meshgrid: doc-meshgrid, *note mesh: doc-mesh,
+     *note contour: doc-contour.
+
+ -- Function File:  meshz (X, Y, Z)
+     Plot a curtain mesh given matrices X, and Y from `meshgrid' and a
+     matrix Z corresponding to the X and Y coordinates of the mesh.  If
+     X and Y are vectors, then a typical vertex is (X(j), Y(i),
+     Z(i,j)).  Thus, columns of Z correspond to different X values and
+     rows of Z correspond to different Y values.
+
+     *See also:* *note meshgrid: doc-meshgrid, *note mesh: doc-mesh,
+     *note contour: doc-contour.
+
+ -- Function File:  hidden (MODE)
+ -- Function File:  hidden ()
+     Manipulation the mesh hidden line removal.  Called with no argument
+     the hidden line removal is toggled.  The argument MODE can be
+     either 'on' or 'off' and the set of the hidden line removal is set
+     accordingly.
+
+     *See also:* *note mesh: doc-mesh, *note meshc: doc-meshc, *note
+     surf: doc-surf.
+
+ -- Function File:  surf (X, Y, Z)
+     Plot a surface given matrices X, and Y from `meshgrid' and a
+     matrix Z corresponding to the X and Y coordinates of the mesh.  If
+     X and Y are vectors, then a typical vertex is (X(j), Y(i),
+     Z(i,j)).  Thus, columns of Z correspond to different X values and
+     rows of Z correspond to different Y values.
+
+     *See also:* *note mesh: doc-mesh, *note surface: doc-surface.
+
+ -- Function File:  surfc (X, Y, Z)
+     Plot a surface and contour given matrices X, and Y from `meshgrid'
+     and a matrix Z corresponding to the X and Y coordinates of the
+     mesh.  If X and Y are vectors, then a typical vertex is (X(j),
+     Y(i), Z(i,j)).  Thus, columns of Z correspond to different X
+     values and rows of Z correspond to different Y values.
+
+     *See also:* *note meshgrid: doc-meshgrid, *note surf: doc-surf,
+     *note contour: doc-contour.
+
+ -- Function File:  surfl (X, Y, Z)
+ -- Function File:  surfl (Z)
+ -- Function File:  surfl (X, Y, Z, L)
+ -- Function File:  surfl (X, Y, Z, L, P)
+ -- Function File:  surfl (...,"light")
+     Plot a lighted surface given matrices X, and Y from `meshgrid' and
+     a matrix Z corresponding to the X and Y coordinates of the mesh.
+     If X and Y are vectors, then a typical vertex is (X(j), Y(i),
+     Z(i,j)).  Thus, columns of Z correspond to different X values and
+     rows of Z correspond to different Y values.
+
+     The light direction can be specified using L.  It can be given as
+     2-element vector [azimuth, elevation] in degrees or as 3-element
+     vector [lx, ly, lz].  The default value is rotated 45°
+     counter-clockwise from the current view.
+
+     The material properties of the surface can specified using a
+     4-element vector P = [AM D SP EXP] which defaults to P = [0.55 0.6
+     0.4 10].
+    `"AM" strength of ambient light'
+
+    `"D" strength of diffuse reflection'
+
+    `"SP" strength of specular reflection'
+
+    `"EXP" specular exponent'
+
+     The default lighting mode "cdata", changes the cdata property to
+     give the impression of a lighted surface.  Please note: the
+     alternative "light" mode, which creates a light object to
+     illuminate the surface is not implemented (yet).
+
+     Example:
+
+          colormap(bone);
+          surfl(peaks);
+          shading interp;
+
+     *See also:* *note surf: doc-surf, *note diffuse: doc-diffuse,
+     *note specular: doc-specular, *note surface: doc-surface.
+
+ -- Function File:  surfnorm (X, Y, Z)
+ -- Function File:  surfnorm (Z)
+ -- Function File: [NX, NY, NZ] = surfnorm (...)
+ -- Function File:  surfnorm (H, ...)
+     Find the vectors normal to a meshgridded surface.  The meshed
+     gridded surface is defined by X, Y, and Z.  If X and Y are not
+     defined, then it is assumed that they are given by
+
+          [X, Y] = meshgrid (1:size(Z, 1),
+                               1:size(Z, 2));
+
+     If no return arguments are requested, a surface plot with the
+     normal vectors to the surface is plotted.  Otherwise the
+     components of the normal vectors at the mesh gridded points are
+     returned in NX, NY, and NZ.
+
+     The normal vectors are calculated by taking the cross product of
+     the diagonals of each of the quadrilaterals in the meshgrid to
+     find the normal vectors of the centers of these quadrilaterals.
+     The four nearest normal vectors to the meshgrid points are then
+     averaged to obtain the normal to the surface at the meshgridded
+     points.
+
+     An example of the use of `surfnorm' is
+
+          surfnorm (peaks (25));
+
+     *See also:* *note surf: doc-surf, *note quiver3: doc-quiver3.
+
+ -- Function File:  diffuse (SX, SY, SZ, L)
+     Calculate diffuse reflection strength of a surface defined by the
+     normal vector elements SX, SY, SZ.  The light vector can be
+     specified using parameter L.  It can be given as 2-element vector
+     [azimuth, elevation] in degrees or as 3-element vector [lx, ly,
+     lz].
+
+     *See also:* *note specular: doc-specular, *note surfl: doc-surfl.
+
+ -- Function File:  specular (SX, SY, SZ, L, V)
+ -- Function File:  specular (SX, SY, SZ, L, V, SE)
+     Calculate specular reflection strength of a surface defined by the
+     normal vector elements SX, SY, SZ using Phong's approximation.
+     The light and view vectors can be specified using parameter L and
+     V respectively.  Both can be given as 2-element vectors [azimuth,
+     elevation] in degrees or as 3-element vector [x, y, z].  An
+     optional 6th argument describes the specular exponent (spread) SE.
+
+     *See also:* *note surfl: doc-surfl, *note diffuse: doc-diffuse.
+
+ -- Function File: [XX, YY, ZZ] = meshgrid (X, Y, Z)
+ -- Function File: [XX, YY] = meshgrid (X, Y)
+ -- Function File: [XX, YY] = meshgrid (X)
+     Given vectors of X and Y and Z coordinates, and returning 3
+     arguments, return three-dimensional arrays corresponding to the X,
+     Y, and Z coordinates of a mesh.  When returning only 2 arguments,
+     return matrices corresponding to the X and Y coordinates of a
+     mesh.  The rows of XX are copies of X, and the columns of YY are
+     copies of Y.  If Y is omitted, then it is assumed to be the same
+     as X, and Z is assumed the same as Y.
+
+     *See also:* *note mesh: doc-mesh, *note contour: doc-contour.
+
+ -- Function File: [Y1, Y2, ...,  Yn] = ndgrid (X1, X2, ..., Xn)
+ -- Function File: [Y1, Y2, ...,  Yn] = ndgrid (X)
+     Given n vectors X1, ... Xn, `ndgrid' returns n arrays of dimension
+     n. The elements of the i-th output argument contains the elements
+     of the vector Xi repeated over all dimensions different from the
+     i-th dimension.  Calling ndgrid with only one input argument X is
+     equivalent of calling ndgrid with all n input arguments equal to X:
+
+     [Y1, Y2, ...,  Yn] = ndgrid (X, ..., X)
+
+     *See also:* *note meshgrid: doc-meshgrid.
+
+ -- Function File:  plot3 (ARGS)
+     Produce three-dimensional plots.  Many different combinations of
+     arguments are possible.  The simplest form is
+
+          plot3 (X, Y, Z)
+
+     in which the arguments are taken to be the vertices of the points
+     to be plotted in three dimensions.  If all arguments are vectors
+     of the same length, then a single continuous line is drawn.  If
+     all arguments are matrices, then each column of the matrices is
+     treated as a separate line.  No attempt is made to transpose the
+     arguments to make the number of rows match.
+
+     If only two arguments are given, as
+
+          plot3 (X, C)
+
+     the real and imaginary parts of the second argument are used as
+     the Y and Z coordinates, respectively.
+
+     If only one argument is given, as
+
+          plot3 (C)
+
+     the real and imaginary parts of the argument are used as the Y and
+     Z values, and they are plotted versus their index.
+
+     Arguments may also be given in groups of three as
+
+          plot3 (X1, Y1, Z1, X2, Y2, Z2, ...)
+
+     in which each set of three arguments is treated as a separate line
+     or set of lines in three dimensions.
+
+     To plot multiple one- or two-argument groups, separate each group
+     with an empty format string, as
+
+          plot3 (X1, C1, "", C2, "", ...)
+
+     An example of the use of `plot3' is
+
+             z = [0:0.05:5];
+             plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+             plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
+
+     *See also:* *note plot: doc-plot, *note xlabel: doc-xlabel, *note
+     ylabel: doc-ylabel, *note zlabel: doc-zlabel, *note title:
+     doc-title, *note print: doc-print.
+
+ -- Function File:  view (AZIMUTH, ELEVATION)
+ -- Function File:  view (DIMS)
+ -- Function File: [AZIMUTH, ELEVATION] = view ()
+     Set or get the viewpoint for the current axes.
+
+ -- Function File:  slice (X, Y, Z, V, SX, SY, SZ)
+ -- Function File:  slice (X, Y, Z, V, XI, YI, ZI)
+ -- Function File:  slice (V, SX, SY, SZ)
+ -- Function File:  slice (V, XI, YI, ZI)
+ -- Function File: H = slice (...)
+ -- Function File: H = slice (..., METHOD)
+     Plot slices of 3D data/scalar fields.  Each element of the
+     3-dimensional array V represents a scalar value at a location
+     given by the parameters X, Y, and Z.  The parameters X, X, and Z
+     are either 3-dimensional arrays of the same size as the array V in
+     the "meshgrid" format or vectors.  The parameters XI, etc. respect
+     a similar format to X, etc., and they represent the points at
+     which the array VI is interpolated using interp3.  The vectors SX,
+     SY, and SZ contain points of orthogonal slices of the respective
+     axes.
+
+     If X, Y, Z are omitted, they are assumed to be `x = 1:size (V,
+     2)', `y = 1:size (V, 1)' and `z = 1:size (V, 3)'.
+
+     METHOD is one of:
+
+    `"nearest"'
+          Return the nearest neighbor.
+
+    `"linear"'
+          Linear interpolation from nearest neighbors.
+
+    `"cubic"'
+          Cubic interpolation from four nearest neighbors (not
+          implemented yet).
+
+    `"spline"'
+          Cubic spline interpolation--smooth first and second
+          derivatives throughout the curve.
+
+     The default method is `"linear"'.  The optional return value H is
+     a vector of handles to the surface graphic objects.
+
+     Examples:
+          [x, y, z] = meshgrid (linspace (-8, 8, 32));
+          v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+          slice (x, y, z, v, [], 0, []);
+          [xi, yi] = meshgrid (linspace (-7, 7));
+          zi = xi + yi;
+          slice (x, y, z, v, xi, yi, zi);
+
+     *See also:* *note interp3: doc-interp3, *note surface:
+     doc-surface, *note pcolor: doc-pcolor.
+
+ -- Function File:  ribbon (X, Y, WIDTH)
+ -- Function File:  ribbon (Y)
+ -- Function File: H = ribbon (...)
+     Plot a ribbon plot for the columns of Y vs.  X.  The optional
+     parameter WIDTH specifies the width of a single ribbon (default is
+     0.75).  If X is omitted, a vector containing the row numbers is
+     assumed (1:rows(Y)).  If requested, return a vector H of the
+     handles to the surface objects.
+
+     *See also:* *note gca: doc-gca, *note colorbar: doc-colorbar.
+
+ -- Function File:  shading (TYPE)
+ -- Function File:  shading (AX, ...)
+     Set the shading of surface or patch graphic objects.  Valid
+     arguments for TYPE are
+
+    `"flat"'
+          Single colored patches with invisible edges.
+
+    `"faceted"'
+          Single colored patches with visible edges.
+
+    `"interp"'
+          Color between patch vertices are interpolated and the patch
+          edges are invisible.
+
+     If AX is given the shading is applied to axis AX instead of the
+     current axis.
+
+* Menu:
+
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
+
+
+File: octave.info,  Node: Three-dimensional Function Plotting,  Next: Three-dimensional Geometric Shapes,  Up: Three-Dimensional Plotting
+
+15.1.2.1 Three-dimensional Function Plotting
+............................................
+
+ -- Function File:  ezplot3 (FX, FY, FZ)
+ -- Function File:  ezplot3 (..., DOM)
+ -- Function File:  ezplot3 (..., N)
+ -- Function File:  ezplot3 (H, ...)
+ -- Function File: H = ezplot3 (...)
+     Plots in three-dimensions the curve defined parametrically.  FX,
+     FY, and FZ are strings, inline functions or function handles with
+     one arguments defining the function.  By default the plot is over
+     the domain `-2*pi < X < 2*pi' with 60 points.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of T.  N is a scalar defining the number of points
+     to use.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          fx = @(t) cos (t);
+          fy = @(t) sin (t);
+          fz = @(t) t;
+          ezplot3 (fx, fy, fz, [0, 10*pi], 100);
+
+     *See also:* *note plot3: doc-plot3, *note ezplot: doc-ezplot,
+     *note ezsurf: doc-ezsurf, *note ezmesh: doc-ezmesh.
+
+ -- Function File:  ezmesh (F)
+ -- Function File:  ezmesh (FX, FY, FZ)
+ -- Function File:  ezmesh (..., DOM)
+ -- Function File:  ezmesh (..., N)
+ -- Function File:  ezmesh (..., 'circ')
+ -- Function File:  ezmesh (H, ...)
+ -- Function File: H = ezmesh (...)
+     Plots the mesh defined by a function.  F is a string, inline
+     function or function handle with two arguments defining the
+     function.  By default the plot is over the domain `-2*pi < X <
+     2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both X and Y.  If DOM is a four element vector,
+     then the minimum and maximum value of X and Y are specify
+     separately.
+
+     N is a scalar defining the number of points to use in each
+     dimension.
+
+     If three functions are passed, then plot the parametrically defined
+     function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over
+     a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezmesh (f, [-3, 3]);
+
+     An example of a parametrically defined function is
+
+          fx = @(s,t) cos (s) .* cos(t);
+          fy = @(s,t) sin (s) .* cos(t);
+          fz = @(s,t) sin(t);
+          ezmesh (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+
+     *See also:* *note ezplot: doc-ezplot, *note ezsurf: doc-ezsurf,
+     *note ezsurfc: doc-ezsurfc, *note ezmeshc: doc-ezmeshc.
+
+ -- Function File:  ezmeshc (F)
+ -- Function File:  ezmeshc (FX, FY, FZ)
+ -- Function File:  ezmeshc (..., DOM)
+ -- Function File:  ezmeshc (..., N)
+ -- Function File:  ezmeshc (..., 'circ')
+ -- Function File:  ezmeshc (H, ...)
+ -- Function File: H = ezmeshc (...)
+     Plots the mesh and contour lines defined by a function.  F is a
+     string, inline function or function handle with two arguments
+     defining the function.  By default the plot is over the domain
+     `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each
+     dimension.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both X and Y.  If DOM is a four element vector,
+     then the minimum and maximum value of X and Y are specify
+     separately.
+
+     N is a scalar defining the number of points to use in each
+     dimension.
+
+     If three functions are passed, then plot the parametrically defined
+     function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over
+     a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezmeshc (f, [-3, 3]);
+
+     *See also:* *note ezplot: doc-ezplot, *note ezsurfc: doc-ezsurfc,
+     *note ezsurf: doc-ezsurf, *note ezmesh: doc-ezmesh.
+
+ -- Function File:  ezsurf (F)
+ -- Function File:  ezsurf (FX, FY, FZ)
+ -- Function File:  ezsurf (..., DOM)
+ -- Function File:  ezsurf (..., N)
+ -- Function File:  ezsurf (..., 'circ')
+ -- Function File:  ezsurf (H, ...)
+ -- Function File: H = ezsurf (...)
+     Plots the surface defined by a function.  F is a string, inline
+     function or function handle with two arguments defining the
+     function.  By default the plot is over the domain `-2*pi < X <
+     2*pi' and `-2*pi < Y < 2*pi' with 60 points in each dimension.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both X and Y.  If DOM is a four element vector,
+     then the minimum and maximum value of X and Y are specify
+     separately.
+
+     N is a scalar defining the number of points to use in each
+     dimension.
+
+     If three functions are passed, then plot the parametrically defined
+     function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over
+     a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezsurf (f, [-3, 3]);
+
+     An example of a parametrically defined function is
+
+          fx = @(s,t) cos (s) .* cos(t);
+          fy = @(s,t) sin (s) .* cos(t);
+          fz = @(s,t) sin(t);
+          ezsurf (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+
+     *See also:* *note ezplot: doc-ezplot, *note ezmesh: doc-ezmesh,
+     *note ezsurfc: doc-ezsurfc, *note ezmeshc: doc-ezmeshc.
+
+ -- Function File:  ezsurfc (F)
+ -- Function File:  ezsurfc (FX, FY, FZ)
+ -- Function File:  ezsurfc (..., DOM)
+ -- Function File:  ezsurfc (..., N)
+ -- Function File:  ezsurfc (..., 'circ')
+ -- Function File:  ezsurfc (H, ...)
+ -- Function File: H = ezsurfc (...)
+     Plots the surface and contour lines defined by a function.  F is a
+     string, inline function or function handle with two arguments
+     defining the function.  By default the plot is over the domain
+     `-2*pi < X < 2*pi' and `-2*pi < Y < 2*pi' with 60 points in each
+     dimension.
+
+     If DOM is a two element vector, it represents the minimum and
+     maximum value of both X and Y.  If DOM is a four element vector,
+     then the minimum and maximum value of X and Y are specify
+     separately.
+
+     N is a scalar defining the number of points to use in each
+     dimension.
+
+     If three functions are passed, then plot the parametrically defined
+     function `[FX (S, T), FY (S, T), FZ (S, T)]'.
+
+     If the argument 'circ' is given, then the function is plotted over
+     a disk centered on the middle of the domain DOM.
+
+     The optional return value H provides a list of handles to the the
+     parts of the vector field (body, arrow and marker).
+
+          f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+          ezsurfc (f, [-3, 3]);
+
+     *See also:* *note ezplot: doc-ezplot, *note ezmeshc: doc-ezmeshc,
+     *note ezsurf: doc-ezsurf, *note ezmesh: doc-ezmesh.
+
+
+File: octave.info,  Node: Three-dimensional Geometric Shapes,  Prev: Three-dimensional Function Plotting,  Up: Three-Dimensional Plotting
+
+15.1.2.2 Three-dimensional Geometric Shapes
+...........................................
+
+ -- Function File:  cylinder
+ -- Function File:  cylinder (R)
+ -- Function File:  cylinder (R, N)
+ -- Function File: [X, Y, Z] = cylinder (...)
+ -- Function File:  cylinder (AX, ...)
+     Generates three matrices in `meshgrid' format, such that `surf (X,
+     Y, Z)' generates a unit cylinder.  The matrices are of size
+     `N+1'-by-`N+1'.  R is a vector containing the radius along the
+     z-axis.  If N or R are omitted then default values of 20 or [1 1]
+     are assumed.
+
+     Called with no return arguments, `cylinder' calls directly `surf
+     (X, Y, Z)'.  If an axes handle AX is passed as the first argument,
+     the surface is plotted to this set of axes.
+
+     Examples:
+          disp ("plotting a cone")
+          [x, y, z] = cylinder (10:-1:0,50);
+          surf (x, y, z);
+
+     *See also:* *note sphere: doc-sphere.
+
+ -- Function File: [X, Y, Z] = sphere (N)
+ -- Function File:  sphere (H, ...)
+     Generates three matrices in `meshgrid' format, such that `surf (X,
+     Y, Z)' generates a unit sphere.  The matrices of `N+1'-by-`N+1'.
+     If N is omitted then a default value of 20 is assumed.
+
+     Called with no return arguments, `sphere' call directly `surf (X,
+     Y, Z)'.  If an axes handle is passed as the first argument, the
+     surface is plotted to this set of axes.
+
+     *See also:* *note peaks: doc-peaks.
+
+ -- Function File: [X, Y, Z] = ellipsoid (XC,YC, ZC, XR, YR, ZR, N)
+ -- Function File:  ellipsoid (H, ...)
+     Generate three matrices in `meshgrid' format that define an
+     ellipsoid.  Called with no return arguments, `ellipsoid' calls
+     directly `surf (X, Y, Z)'.  If an axes handle is passed as the
+     first argument, the surface is plotted to this set of axes.
+
+     *See also:* *note sphere: doc-sphere.
+
+
+File: octave.info,  Node: Plot Annotations,  Next: Multiple Plots on One Page,  Prev: Three-Dimensional Plotting,  Up: Plotting Basics
+
+15.1.3 Plot Annotations
+-----------------------
+
+You can add titles, axis labels, legends, and arbitrary text to an
+existing plot.  For example,
+
+     x = -10:0.1:10;
+     plot (x, sin (x));
+     title ("sin(x) for x = -10:0.1:10");
+     xlabel ("x");
+     ylabel ("sin (x)");
+     text (pi, 0.7, "arbitrary text");
+     legend ("sin (x)");
+
+   The functions `grid' and `box' may also be used to add grid and
+border lines to the plot.  By default, the grid is off and the border
+lines are on.
+
+ -- Function File:  title (TITLE)
+ -- Function File:  title (TITLE, P1, V1, ...)
+     Create a title object and return a handle to it.
+
+ -- Function File:  legend (ST1, ST2, ...)
+ -- Function File:  legend (ST1, ST2, ..., "location", POS)
+ -- Function File:  legend (MATSTR)
+ -- Function File:  legend (MATSTR, "location", POS)
+ -- Function File:  legend (CELL)
+ -- Function File:  legend (CELL, "location", POS)
+ -- Function File:  legend ('FUNC')
+     Display a legend for the current axes using the specified strings
+     as labels.  Legend entries may be specified as individual character
+     string arguments, a character array, or a cell array of character
+     strings.  Legend works on line graphs, bar graphs, etc.  A plot
+     must exist before legend is called.
+
+     The optional parameter POS specifies the location of the legend as
+     follows:
+
+          north      center top
+          south      center bottom
+          east       right center
+          west       left center
+          northeast  right top (default)
+          northwest  left top
+          southeast  right bottom
+          southwest  left bottom
+
+          outside    can be appended to any location string
+
+     Some specific functions are directly available using FUNC:
+
+    "show"
+          Show legends from the plot
+
+    "hide"
+    "off"
+          Hide legends from the plot
+
+    "boxon"
+          Draw a box around legends
+
+    "boxoff"
+          Withdraw the box around legends
+
+    "left"
+          Text is to the left of the keys
+
+    "right"
+          Text is to the right of the keys
+
+ -- Function File: H = text (X, Y, LABEL)
+ -- Function File: H = text (X, Y, Z, LABEL)
+ -- Function File: H = text (X, Y, LABEL, P1, V1, ...)
+ -- Function File: H = text (X, Y, Z, LABEL, P1, V1, ...)
+     Create a text object with text LABEL at position X, Y, Z on the
+     current axes.  Property-value pairs following LABEL may be used to
+     specify the appearance of the text.
+
+   See *note Text Properties:: for the properties that you can set.
+
+ -- Function File:  xlabel (STRING)
+ -- Function File:  ylabel (STRING)
+ -- Function File:  zlabel (STRING)
+ -- Function File:  xlabel (H, STRING)
+     Specify x, y, and z axis labels for the current figure.  If H is
+     specified then label the axis defined by H.
+
+     *See also:* *note plot: doc-plot, *note semilogx: doc-semilogx,
+     *note semilogy: doc-semilogy, *note loglog: doc-loglog, *note
+     polar: doc-polar, *note mesh: doc-mesh, *note contour:
+     doc-contour, *note bar: doc-bar, *note stairs: doc-stairs, *note
+     title: doc-title.
+
+ -- Function File:  clabel (C, H)
+ -- Function File:  clabel (C, H, V)
+ -- Function File:  clabel (C, H, "manual")
+ -- Function File:  clabel (C)
+ -- Function File:  clabel (C, H)
+ -- Function File:  clabel (..., PROP, VAL, ...)
+ -- Function File: H = clabel (...)
+     Adds labels to the contours of a contour plot.  The contour plot
+     is specified by the contour matrix C and optionally the
+     contourgroup object H that are returned by `contour', `contourf'
+     and `contour3'.  The contour labels are rotated and placed in the
+     contour itself.
+
+     By default, all contours are labelled.  However, the contours to
+     label can be specified by the vector V.  If the "manual" argument
+     is given then the contours to label can be selected with the mouse.
+
+     Additional property/value pairs that are valid properties of text
+     objects can be given and are passed to the underlying text
+     objects.  Additionally, the property "LabelSpacing" is available
+     allowing the spacing between labels on a contour (in points) to be
+     specified.  The default is 144 points, or 2 inches.
+
+     The returned value H is the set of text object that represent the
+     contour labels.  The "userdata" property of the text objects
+     contains the numerical value of the contour label.
+
+     An example of the use of `clabel' is
+
+          [c, h] = contour (peaks(), -4 : 6);
+          clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+
+     *See also:* *note contour: doc-contour, *note contourf:
+     doc-contourf, *note contour3: doc-contour3, *note meshc:
+     doc-meshc, *note surfc: doc-surfc, *note text: doc-text.
+
+ -- Function File:  box (ARG)
+ -- Function File:  box (H, ...)
+     Control the display of a border around the plot.  The argument may
+     be either `"on"' or `"off"'.  If it is omitted, the current box
+     state is toggled.
+
+     *See also:* *note grid: doc-grid.
+
+ -- Function File:  grid (ARG)
+ -- Function File:  grid ("minor", ARG2)
+ -- Function File:  grid (HAX, ...)
+     Force the display of a grid on the plot.  The argument may be
+     either `"on"', or `"off"'.  If it is omitted, the current grid
+     state is toggled.
+
+     If ARG is `"minor"' then the minor grid is toggled.  When using a
+     minor grid a second argument ARG2 is allowed, which can be either
+     `"on"' or `"off"' to explicitly set the state of the minor grid.
+
+     If the first argument is an axis handle, HAX, operate on the
+     specified axis object.
+
+     *See also:* *note plot: doc-plot.
+
+ -- Function File:  colorbar (S)
+ -- Function File:  colorbar ("peer", H, ...)
+     Adds a colorbar to the current axes.  Valid values for S are
+
+    "EastOutside"
+          Place the colorbar outside the plot to the right.  This is
+          the default.
+
+    "East"
+          Place the colorbar inside the plot to the right.
+
+    "WestOutside"
+          Place the colorbar outside the plot to the left.
+
+    "West"
+          Place the colorbar inside the plot to the left.
+
+    "NorthOutside"
+          Place the colorbar above the plot.
+
+    "North"
+          Place the colorbar at the top of the plot.
+
+    "SouthOutside"
+          Place the colorbar under the plot.
+
+    "South"
+          Place the colorbar at the bottom of the plot.
+
+    "Off", "None"
+          Remove any existing colorbar from the plot.
+
+     If the argument "peer" is given, then the following argument is
+     treated as the axes handle on which to add the colorbar.
+
+
+File: octave.info,  Node: Multiple Plots on One Page,  Next: Multiple Plot Windows,  Prev: Plot Annotations,  Up: Plotting Basics
+
+15.1.4 Multiple Plots on One Page
+---------------------------------
+
+Octave can display more than one plot in a single figure.  The simplest
+way to do this is to use the `subplot' function to divide the plot area
+into a series of subplot windows that are indexed by an integer.  For
+example,
+
+     subplot (2, 1, 1)
+     fplot (@sin, [-10, 10]);
+     subplot (2, 1, 2)
+     fplot (@cos, [-10, 10]);
+
+creates a figure with two separate axes, one displaying a sine wave and
+the other a cosine wave.  The first call to subplot divides the figure
+into two plotting areas (two rows and one column) and makes the first
+plot area active.  The grid of plot areas created by `subplot' is
+numbered in column-major order (top to bottom, left to right).
+
+ -- Function File:  subplot (ROWS, COLS, INDEX)
+ -- Function File:  subplot (RCN)
+     Set up a plot grid with COLS by ROWS subwindows and plot in
+     location given by INDEX.
+
+     If only one argument is supplied, then it must be a three digit
+     value specifying the location in digits 1 (rows) and 2 (columns)
+     and the plot index in digit 3.
+
+     The plot index runs row-wise.  First all the columns in a row are
+     filled and then the next row is filled.
+
+     For example, a plot with 2 by 3 grid will have plot indices
+     running as follows:
+
+               +-----+-----+-----+
+               |  1  |  2  |  3  |
+               +-----+-----+-----+
+               |  4  |  5  |  6  |
+               +-----+-----+-----+
+
+     *See also:* *note plot: doc-plot.
+
+
+File: octave.info,  Node: Multiple Plot Windows,  Next: Printing Plots,  Prev: Multiple Plots on One Page,  Up: Plotting Basics
+
+15.1.5 Multiple Plot Windows
+----------------------------
+
+You can open multiple plot windows using the `figure' function.  For
+example
+
+     figure (1);
+     fplot (@sin, [-10, 10]);
+     figure (2);
+     fplot (@cos, [-10, 10]);
+
+creates two figures, with the first displaying a sine wave and the
+second a cosine wave.  Figure numbers must be positive integers.
+
+ -- Function File:  figure (N)
+ -- Function File:  figure (N, PROPERTY, VALUE, ...)
+     Set the current plot window to plot window N.  If no arguments are
+     specified, the next available window number is chosen.
+
+     Multiple property-value pairs may be specified for the figure, but
+     they must appear in pairs.
+
+
+File: octave.info,  Node: Printing Plots,  Next: Interacting with plots,  Prev: Multiple Plot Windows,  Up: Plotting Basics
+
+15.1.6 Printing Plots
+---------------------
+
+The `print' command allows you to save plots in a variety of formats.
+For example,
+
+     print -deps foo.eps
+
+writes the current figure to an encapsulated PostScript file called
+`foo.eps'.
+
+ -- Function File:  print ()
+ -- Function File:  print (OPTIONS)
+ -- Function File:  print (FILENAME, OPTIONS)
+ -- Function File:  print (H, FILENAME, OPTIONS)
+     Print a graph, or save it to a file
+
+     FILENAME defines the file name of the output file.  If no filename
+     is specified, the output is sent to the printer.
+
+     H specifies the figure handle.  If no handle is specified the
+     handle for the current figure is used.
+
+     OPTIONS:
+    `-PPRINTER'
+          Set the PRINTER name to which the graph is sent if no
+          FILENAME is specified.
+
+    `-GGHOSTSCRIPT_COMMAND'
+          Specify the command for calling Ghostscript.  For Unix and
+          Windows, the defaults are 'gs' and 'gswin32c', respectively.
+
+    `-color'
+    `-mono'
+          Monochrome or color lines.
+
+    `-solid'
+    `-dashed'
+          Solid or dashed lines.
+
+    `-portrait'
+    `-landscape'
+          Specify the orientation of the plot for printed output.
+
+    `-dDEVICE'
+          Output device, where DEVICE is one of:
+         `ps'
+         `ps2'
+         `psc'
+         `psc2'
+               Postscript (level 1 and 2, mono and color)
+
+         `eps'
+         `eps2'
+         `epsc'
+         `epsc2'
+               Encapsulated postscript (level 1 and 2, mono and color)
+
+         `tex'
+         `epslatex'
+         `epslatexstandalone'
+         `pstex'
+         `pslatex'
+               Generate a LaTeX (or TeX) file for labels, and eps/ps for
+               graphics.  The file produced by `epslatexstandalone' can
+               be processed directly by LaTeX.  The other formats are
+               intended to be included in a LaTeX (or TeX) document.
+               The `tex' device is the same as the `epslatex' device.
+
+         `ill'
+         `aifm'
+               Adobe Illustrator
+
+         `cdr'
+         `corel'
+               CorelDraw
+
+         `dxf'
+               AutoCAD
+
+         `emf'
+         `meta'
+               Microsoft Enhanced Metafile
+
+         `fig'
+               XFig.  If this format is selected the additional options
+               `-textspecial' or `-textnormal' can be used to control
+                whether the special flag should be set for the text in
+                 the figure (default is `-textnormal').
+
+         `hpgl'
+               HP plotter language
+
+         `mf'
+               Metafont
+
+         `png'
+               Portable network graphics
+
+         `jpg'
+         `jpeg'
+               JPEG image
+
+         `gif'
+               GIF image
+
+         `pbm'
+               PBMplus
+
+         `svg'
+               Scalable vector graphics
+
+         `pdf'
+               Portable document format
+
+          If the device is omitted, it is inferred from the file
+          extension, or if there is no filename it is sent to the
+          printer as postscript.
+
+    `-dGS_DEVICE'
+          Additional devices are supported by Ghostscript.  Some
+          examples are;
+
+         `ljet2p'
+               HP LaserJet IIP
+
+         `ljet3'
+               HP LaserJet III
+
+         `deskjet'
+               HP DeskJet and DeskJet Plus
+
+         `cdj550'
+               HP DeskJet 550C
+
+         `paintjet'
+               HP PointJet
+
+         `pcx24b'
+               24-bit color PCX file format
+
+         `ppm'
+               Portable Pixel Map file format
+
+          For a complete list, type `system ("gs -h")' to see what
+          formats and devices are available.
+
+          When the ghostscript is sent to a printer the size is
+          determined by the figure's "papersize" property.  When the
+          ghostscript output is sent to a file the size is determined
+          by the figure's "paperposition" property.
+
+    `-rNUM'
+          Resolution of bitmaps in pixels per inch.  For both metafiles
+          and SVG the default is the screen resolution, for other it is
+          150 dpi.  To specify screen resolution, use "-r0".
+
+    `-tight'
+          Forces a tight bounding box for eps-files.  Since the
+          ghostscript devices are conversion of an eps-file, this
+          option works the those devices as well.
+
+    `-SXSIZE,YSIZE'
+          Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG.  If
+          using the command form of the print function, you must quote
+          the XSIZE,YSIZE option.  For example, by writing
+          `"-S640,480"'.  The size defaults to that specified by the
+          figure's paperposition property.
+
+    `-FFONTNAME'
+    `-FFONTNAME:SIZE'
+    `-F:SIZE'
+          FONTNAME set the postscript font (for use with postscript,
+          aifm, corel and fig).  By default, 'Helvetica' is set for
+          PS/Aifm, and 'SwitzerlandLight' for Corel.  It can also be
+          'Times-Roman'.  SIZE is given in points.  FONTNAME is ignored
+          for the fig device.
+
+     The filename and options can be given in any order.
+
+ -- Function File:  orient (ORIENTATION)
+     Set the default print orientation.  Valid values for ORIENTATION
+     include `"landscape"', `"portrait"', and `"tall"'.
+
+     The `"tall"' option sets the orientation to portait and fills the
+     page with the plot, while leaving a 0.25in border.
+
+     If called with no arguments, return the default print orientation.
+
+
+File: octave.info,  Node: Interacting with plots,  Next: Test Plotting Functions,  Prev: Printing Plots,  Up: Plotting Basics
+
+15.1.7 Interacting with plots
+-----------------------------
+
+The user can select points on a plot with the `ginput' function or
+selection the position at which to place text on the plot with the
+`gtext' function using the mouse.
+
+ -- Function File: [X, Y, BUTTONS] = ginput (N)
+     Return which mouse buttons were pressed and keys were hit on the
+     current figure.  If N is defined, then wait for N mouse clicks
+     before returning.  If N is not defined, then `ginput' will loop
+     until the return key is pressed.
+
+ -- Function File: B = waitforbuttonpress ()
+     Wait for button or mouse press.over a figure window.  The value of
+     B returns 0 if a mouse button was pressed or 1 is a key was
+     pressed.
+
+     *See also:* *note ginput: doc-ginput.
+
+ -- Function File:  gtext (S)
+ -- Function File:  gtext ({S1; S2; ...})
+ -- Function File:  gtext (..., PROP, VAL)
+     Place text on the current figure using the mouse.  The text is
+     defined by the string S.  If S is a cell array, each element of
+     the cell array is written to a separate line.  Additional
+     arguments are passed to the underlying text object as properties.
+
+     *See also:* *note ginput: doc-ginput, *note text: doc-text.
+
+
+File: octave.info,  Node: Test Plotting Functions,  Prev: Interacting with plots,  Up: Plotting Basics
+
+15.1.8 Test Plotting Functions
+------------------------------
+
+The functions `sombrero' and `peaks' provide a way to check that
+plotting is working.  Typing either `sombrero' or `peaks' at the Octave
+prompt should display a three-dimensional plot.
+
+ -- Function File:  sombrero (N)
+     Produce the familiar three-dimensional sombrero plot using N grid
+     lines.  If N is omitted, a value of 41 is assumed.
+
+     The function plotted is
+
+          z = sin (sqrt (x^2 + y^2)) / (sqrt (x^2 + y^2))
+
+     *See also:* *note surf: doc-surf, *note meshgrid: doc-meshgrid,
+     *note mesh: doc-mesh.
+
+ -- Function File:  peaks ()
+ -- Function File:  peaks (N)
+ -- Function File:  peaks (X, Y)
+ -- Function File: Z = peaks (...)
+ -- Function File: [X, Y, Z] = peaks (...)
+     Generate a function with lots of local maxima and minima.  The
+     function has the form
+
+
+     f(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) ...
+              - 10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) ...
+              - 1/3*exp(-(x+1)^2 - y^2)
+
+     Called without a return argument, `peaks' plots the surface of the
+     above function using `mesh'.  If N is a scalar, the `peaks'
+     returns the values of the above function on a N-by-N mesh over the
+     range `[-3,3]'.  The default value for N is 49.
+
+     If N is a vector, then it represents the X and Y values of the
+     grid on which to calculate the above function.  The X and Y values
+     can be specified separately.
+
+     *See also:* *note surf: doc-surf, *note mesh: doc-mesh, *note
+     meshgrid: doc-meshgrid.
+
+
+File: octave.info,  Node: Advanced Plotting,  Prev: Plotting Basics,  Up: Plotting
+
+15.2 Advanced Plotting
+======================
+
+* Menu:
+
+* Graphics Objects::
+* Graphics Object Properties::
+* Managing Default Properties::
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
+* Object Groups::
+* Graphics backends::
+
+
+File: octave.info,  Node: Graphics Objects,  Next: Graphics Object Properties,  Up: Advanced Plotting
+
+15.2.1 Graphics Objects
+-----------------------
+
+Plots in Octave are constructed from the following "graphics objects".
+Each graphics object has a set of properties that define its appearance
+and may also contain links to other graphics objects.  Graphics objects
+are only referenced by a numeric index, or "handle".
+
+root figure
+     The parent of all figure objects.  The index for the root figure is
+     defined to be 0.
+
+figure
+     A figure window.
+
+axes
+     A set of axes.  This object is a child of a figure object and may
+     be a parent of line, text, image, patch, or surface objects.
+
+line
+     A line in two or three dimensions.
+
+text
+     Text annotations.
+
+image
+     A bitmap image.
+
+patch
+     A filled polygon, currently limited to two dimensions.
+
+surface
+     A three-dimensional surface.
+
+   To determine whether a variable is a graphics object index or a
+figure index, use the functions `ishandle' and `isfigure'.
+
+ -- Built-in Function:  ishandle (H)
+     Return true if H is a graphics handle and false otherwise.
+
+ -- Function File:  ishghandle (H)
+     Return true if H is a graphics handle and false otherwise.
+
+ -- Function File:  isfigure (H)
+     Return true if H is a graphics handle that contains a figure
+     object and false otherwise.
+
+   The function `gcf' returns an index to the current figure object, or
+creates one if none exists.  Similarly, `gca' returns the current axes
+object, or creates one (and its parent figure object) if none exists.
+
+ -- Function File:  gcf ()
+     Return the current figure handle.  If a figure does not exist,
+     create one and return its handle.  The handle may then be used to
+     examine or set properties of the figure.  For example,
+
+          fplot (@sin, [-10, 10]);
+          fig = gcf ();
+          set (fig, "visible", "off");
+
+     plots a sine wave, finds the handle of the current figure, and then
+     makes that figure invisible.  Setting the visible property of the
+     figure to `"on"' will cause it to be displayed again.
+
+     *See also:* *note get: doc-get, *note set: doc-set.
+
+ -- Function File:  gca ()
+     Return a handle to the current axis object.  If no axis object
+     exists, create one and return its handle.  The handle may then be
+     used to examine or set properties of the axes.  For example,
+
+          ax = gca ();
+          set (ax, "position", [0.5, 0.5, 0.5, 0.5]);
+
+     creates an empty axes object, then changes its location and size in
+     the figure window.
+
+     *See also:* *note get: doc-get, *note set: doc-set.
+
+   The `get' and `set' functions may be used to examine and set
+properties for graphics objects.  For example,
+
+     get (0)
+         => ans =
+            {
+              type = root
+              currentfigure = [](0x0)
+              children = [](0x0)
+              visible = on
+     			...
+            }
+
+returns a structure containing all the properties of the root figure.
+As with all functions in Octave, the structure is returned by value, so
+modifying it will not modify the internal root figure plot object.  To
+do that, you must use the `set' function.  Also, note that in this
+case, the `currentfigure' property is empty, which indicates that there
+is no current figure window.
+
+   The `get' function may also be used to find the value of a single
+property.  For example,
+
+     get (gca (), "xlim")
+         => [ 0 1 ]
+
+returns the range of the x-axis for the current axes object in the
+current figure.
+
+   To set graphics object properties, use the set function.  For
+example,
+
+     set (gca (), "xlim", [-10, 10]);
+
+sets the range of the x-axis for the current axes object in the current
+figure to `[-10, 10]'.  Additionally, calling set with a graphics
+object index as the only argument returns a structure containing the
+default values for all the properties for the given object type.  For
+example,
+
+     set (gca ())
+
+returns a structure containing the default property values for axes
+objects.
+
+ -- Built-in Function:  get (H, P)
+     Return the named property P from the graphics handle H.  If P is
+     omitted, return the complete property list for H.  If H is a
+     vector, return a cell array including the property values or lists
+     respectively.
+
+ -- Built-in Function:  set (H, P, V, ...)
+     Set the named property value or vector P to the value V for the
+     graphics handle H.
+
+ -- Function File: PARENT = ancestor (H, TYPE)
+ -- Function File: PARENT = ancestor (H, TYPE, 'toplevel')
+     Return the first ancestor of handle object H whose type matches
+     TYPE, where TYPE is a character string.  If TYPE is a cell array
+     of strings, return the first parent whose type matches any of the
+     given type strings.
+
+     If the handle object H is of type TYPE, return H.
+
+     If `"toplevel"' is given as a 3rd argument, return the highest
+     parent in the object hierarchy that matches the condition, instead
+     of the first (nearest) one.
+
+     *See also:* *note get: doc-get, *note set: doc-set.
+
+ -- Function File: H = allchild (HANDLES)
+     Find all children, including hidden children, of a graphics object.
+
+     This function is similar to `get (h, "children")', but also
+     returns includes hidden objects.  If HANDLES is a scalar, H will
+     be a vector.  Otherwise, H will be a cell matrix of the same size
+     as HANDLES and each cell will contain a vector of handles.
+
+     *See also:* *note get: doc-get, *note set: doc-set, *note findall:
+     doc-findall, *note findobj: doc-findobj.
+
+   You can create axes, line, and patch objects directly using the
+`axes', `line', and `patch' functions.  These objects become children
+of the current axes object.
+
+ -- Function File:  axes ()
+ -- Function File:  axes (PROPERTY, VALUE, ...)
+ -- Function File:  axes (H)
+     Create an axes object and return a handle to it.
+
+ -- Function File:  line ()
+ -- Function File:  line (X, Y)
+ -- Function File:  line (X, Y, Z)
+ -- Function File:  line (X, Y, Z, PROPERTY, VALUE, ...)
+     Create line object from X and Y and insert in current axes object.
+     Return a handle (or vector of handles) to the line objects created.
+
+     Multiple property-value pairs may be specified for the line, but
+     they must appear in pairs.
+
+ -- Function File:  patch ()
+ -- Function File:  patch (X, Y, C)
+ -- Function File:  patch (X, Y, Z, C)
+ -- Function File:  patch (FV)
+ -- Function File:  patch ('Faces', F, 'Vertices', V, ...)
+ -- Function File:  patch (..., PROP, VAL)
+ -- Function File:  patch (H, ...)
+ -- Function File: H = patch (...)
+     Create patch object from X and Y with color C and insert in the
+     current axes object.  Return handle to patch object.
+
+     For a uniform colored patch, C can be given as an RGB vector,
+     scalar value referring to the current colormap, or string value
+     (for example, "r" or "red").
+
+     If passed a structure FV contain the fields "vertices", "faces"
+     and optionally "facevertexcdata", create the patch based on these
+     properties.
+
+ -- Function File:  fill (X, Y, C)
+ -- Function File:  fill (X1, Y1, C1, X2, Y2, C2)
+ -- Function File:  fill (..., PROP, VAL)
+ -- Function File:  fill (H, ...)
+ -- Function File: H = fill (...)
+     Create one or more filled patch objects, returning a patch object
+     for each.
+
+ -- Function File:  surface (X, Y, Z, C)
+ -- Function File:  surface (X, Y, Z)
+ -- Function File:  surface (Z, C)
+ -- Function File:  surface (Z)
+ -- Function File:  surface (..., PROP, VAL)
+ -- Function File:  surface (H, ...)
+ -- Function File: H = surface (...)
+     Plot a surface graphic object given matrices X, and Y from
+     `meshgrid' and a matrix Z corresponding to the X and Y coordinates
+     of the surface.  If X and Y are vectors, then a typical vertex is
+     (X(j), Y(i), Z(i,j)).  Thus, columns of Z correspond to different
+     X values and rows of Z correspond to different Y values.  If X and
+     Y are missing, they are constructed from size of the matrix Z.
+
+     Any additional properties passed are assigned to the surface.
+
+     *See also:* *note surf: doc-surf, *note mesh: doc-mesh, *note
+     patch: doc-patch, *note line: doc-line.
+
+   By default, Octave refreshes the plot window when a prompt is
+printed, or when waiting for input.  To force an update at other times,
+call the `drawnow' function.
+
+ -- Built-in Function:  drawnow ()
+ -- Built-in Function:  drawnow ("expose")
+ -- Built-in Function:  drawnow (TERM, FILE, MONO, DEBUG_FILE)
+     Update figure windows and their children.  The event queue is
+     flushed and any callbacks generated are executed.  With the
+     optional argument `"expose"', only graphic objects are updated and
+     no other events or callbacks are processed.  The third calling
+     form of `drawnow' is for debugging and is undocumented.
+
+   Only figures that are modified will be updated.  The `refresh'
+function can also be used to force an update of the current figure,
+even if it is not modified.
+
+ -- Function File:  refresh ()
+ -- Function File:  refresh (H)
+     Refresh a figure, forcing it to be redrawn.  Called without an
+     argument the current figure is redrawn, otherwise the figure
+     pointed to by H is redrawn.
+
+     *See also:* *note drawnow: doc-drawnow.
+
+   Normally, high-level plot functions like `plot' or `mesh' call
+`newplot' to initialize the state of the current axes so that the next
+plot is drawn in a blank window with default property settings.  To
+have two plots superimposed over one another, use the `hold' function.
+For example,
+
+     hold on;
+     x = -10:0.1:10;
+     plot (x, sin (x));
+     plot (x, cos (x));
+     hold off;
+
+displays sine and cosine waves on the same axes.  If the hold state is
+off, consecutive plotting commands like this will only display the last
+plot.
+
+ -- Function File:  newplot ()
+     Prepare graphics engine to produce a new plot.  This function
+     should be called at the beginning of all high-level plotting
+     functions.
+
+ -- Function File:  hold
+ -- Function File:  hold STATE
+ -- Function File:  hold (HAX, ...)
+     Toggle or set the 'hold' state of the plotting engine which
+     determines whether new graphic objects are added to the plot or
+     replace the existing objects.
+
+    `hold on'
+          Retain plot data and settings so that subsequent plot
+          commands are displayed on a single graph.
+
+    `hold off'
+          Clear plot and restore default graphics settings before each
+          new plot command.  (default).
+
+    `hold'
+          Toggle the current 'hold' state.
+
+     When given the additional argument HAX, the hold state is modified
+     only for the given axis handle.
+
+     To query the current 'hold' state use the `ishold' function.
+
+     *See also:* *note ishold: doc-ishold, *note cla: doc-cla, *note
+     newplot: doc-newplot, *note clf: doc-clf.
+
+ -- Function File:  ishold
+     Return true if the next line will be added to the current plot, or
+     false if the plot device will be cleared before drawing the next
+     line.
+
+   To clear the current figure, call the `clf' function.  To clear the
+current axis, call the `cla' function.  To bring the current figure to
+the top of the window stack, call the `shg' function.  To delete a
+graphics object, call `delete' on its index.  To close the figure
+window, call the `close' function.
+
+ -- Function File:  clf ()
+ -- Function File:  clf ("reset")
+ -- Function File:  clf (HFIG)
+ -- Function File:  clf (HFIG, "reset")
+     Clear the current figure window.  `clf' operates by deleting child
+     graphics objects with visible handles (`HandleVisibility' = on).
+     If HFIG is specified operate on it instead of the current figure.
+     If the optional argument `"reset"' is specified, all objects
+     including those with hidden handles are deleted.
+
+     *See also:* *note cla: doc-cla, *note close: doc-close, *note
+     delete: doc-delete.
+
+ -- Function File:  cla ()
+ -- Function File:  cla ("reset")
+ -- Function File:  cla (HAX)
+ -- Function File:  cla (HAX, "reset")
+     Delete the children of the current axes with visible handles.  If
+     HAX is specified and is an axes object handle, operate on it
+     instead of the current axes.  If the optional argument `"reset"'
+     is specified, also delete the children with hidden handles.
+
+     *See also:* *note clf: doc-clf.
+
+ -- Function File:  shg
+     Show the graph window.  Currently, this is the same as executing
+     `drawnow'.
+
+     *See also:* *note drawnow: doc-drawnow, *note figure: doc-figure.
+
+ -- Function File:  delete (FILE)
+ -- Function File:  delete (HANDLE)
+     Delete the named file or graphics handle.
+
+     Deleting graphics objects is the proper way to remove features
+     from a plot without clearing the entire figure.
+
+     *See also:* *note clf: doc-clf, *note cla: doc-cla.
+
+ -- Command:  close
+ -- Command:  close (N)
+ -- Command:  close all
+ -- Command:  close all hidden
+     Close figure window(s) by calling the function specified by the
+     `"closerequestfcn"' property for each figure.  By default, the
+     function `closereq' is used.
+
+     *See also:* *note closereq: doc-closereq.
+
+ -- Function File:  closereq ()
+     Close the current figure and delete all graphics objects associated
+     with it.
+
+     *See also:* *note close: doc-close, *note delete: doc-delete.
+
+
+File: octave.info,  Node: Graphics Object Properties,  Next: Managing Default Properties,  Prev: Graphics Objects,  Up: Advanced Plotting
+
+15.2.2 Graphics Object Properties
+---------------------------------
+
+* Menu:
+
+* Root Figure Properties::
+* Figure Properties::
+* Axes Properties::
+* Line Properties::
+* Text Properties::
+* Image Properties::
+* Patch Properties::
+* Surface Properties::
+* Searching Properties::
+
+
+File: octave.info,  Node: Root Figure Properties,  Next: Figure Properties,  Up: Graphics Object Properties
+
+15.2.2.1 Root Figure Properties
+...............................
+
+`currentfigure'
+     Index to graphics object for the current figure.
+
+
+
+File: octave.info,  Node: Figure Properties,  Next: Axes Properties,  Prev: Root Figure Properties,  Up: Graphics Object Properties
+
+15.2.2.2 Figure Properties
+..........................
+
+`nextplot'
+     May be one of
+    `"new"'
+
+    `"add"'
+
+    `"replace"'
+
+    `"replacechildren"'
+
+`closerequestfcn'
+     Handle of function to call when a figure is closed.
+
+`currentaxes'
+     Index to graphics object of current axes.
+
+`colormap'
+     An N-by-3 matrix containing the color map for the current axes.
+
+`visible'
+     Either `"on"' or `"off"' to toggle display of the figure.
+
+`paperorientation'
+     Indicates the orientation for printing.  Either `"landscape"' or
+     `"portrait"'.
+
+
+File: octave.info,  Node: Axes Properties,  Next: Line Properties,  Prev: Figure Properties,  Up: Graphics Object Properties
+
+15.2.2.3 Axes Properties
+........................
+
+`position'
+     A vector specifying the position of the plot, excluding titles,
+     axes and legend.  The four elements of the vector are the
+     coordinates of the lower left corner and width and height of the
+     plot, in units normalized to the width and height of the plot
+     window.  For example, `[0.2, 0.3, 0.4, 0.5]' sets the lower left
+     corner of the axes at (0.2, 0.3) and the width and height to be
+     0.4 and 0.5 respectively.  See also the `outerposition' property.
+
+`title'
+     Index of text object for the axes title.
+
+`box'
+     Either `"on"' or `"off"' to toggle display of the box around the
+     axes.
+
+`key'
+     Either `"on"' or `"off"' to toggle display of the legend.  Note
+     that this property is not compatible with MATLAB and may be
+     removed in a future version of Octave.
+
+`keybox'
+     Either `"on"' or `"off"' to toggle display of a box around the
+     legend.  Note that this property is not compatible with MATLAB and
+     may be removed in a future version of Octave.
+
+`keypos'
+     An integer from 1 to 4 specifying the position of the legend.  1
+     indicates upper right corner, 2 indicates upper left, 3 indicates
+     lower left, and 4 indicates lower right.  Note that this property
+     is not compatible with MATLAB and may be removed in a future
+     version of Octave.
+
+`dataaspectratio'
+     A two-element vector specifying the relative height and width of
+     the data displayed in the axes.  Setting `dataaspectratio' to `1,
+     2]' causes the length of one unit as displayed on the y-axis to be
+     the same as the length of 2 units on the x-axis.  Setting
+     `dataaspectratio' also forces the `dataaspectratiomode' property
+     to be set to `"manual"'.
+
+`dataaspectratiomode'
+     Either `"manual"' or `"auto"'.
+
+`xlim'
+`ylim'
+`zlim'
+`clim'
+     Two-element vectors defining the limits for the x, y, and z axes
+     and the Setting one of these properties also forces the
+     corresponding mode property to be set to `"manual"'.
+
+`xlimmode'
+`ylimmode'
+`zlimmode'
+`climmode'
+     Either `"manual"' or `"auto"'.
+
+`xlabel'
+`ylabel'
+`zlabel'
+     Indices to text objects for the axes labels.
+
+`xgrid'
+`ygrid'
+`zgrid'
+     Either `"on"' or `"off"' to toggle display of grid lines.
+
+`xminorgrid'
+`yminorgrid'
+`zminorgrid'
+     Either `"on"' or `"off"' to toggle display of minor grid lines.
+
+`xtick'
+`ytick'
+`ztick'
+     Setting one of these properties also forces the corresponding mode
+     property to be set to `"manual"'.
+
+`xtickmode'
+`ytickmode'
+`ztickmode'
+     Either `"manual"' or `"auto"'.
+
+`xticklabel'
+`yticklabel'
+`zticklabel'
+     Setting one of these properties also forces the corresponding mode
+     property to be set to `"manual"'.
+
+`xticklabelmode'
+`yticklabelmode'
+`zticklabelmode'
+     Either `"manual"' or `"auto"'.
+
+`xscale'
+`yscale'
+`zscale'
+     Either `"linear"' or `"log"'.
+
+`xdir'
+`ydir'
+`zdir'
+     Either `"forward"' or `"reverse"'.
+
+`xaxislocation'
+`yaxislocation'
+     Either `"top"' or `"bottom"' for the x-axis and `"left"' or
+     `"right"' for the y-axis.
+
+`view'
+     A three element vector specifying the view point for
+     three-dimensional plots.
+
+`visible'
+     Either `"on"' or `"off"' to toggle display of the axes.
+
+`nextplot'
+     May be one of
+    `"new"'
+
+    `"add"'
+
+    `"replace"'
+
+    `"replacechildren"'
+
+`outerposition'
+     A vector specifying the position of the plot, including titles,
+     axes and legend.  The four elements of the vector are the
+     coordinates of the lower left corner and width and height of the
+     plot, in units normalized to the width and height of the plot
+     window.  For example, `[0.2, 0.3, 0.4, 0.5]' sets the lower left
+     corner of the axes at (0.2, 0.3) and the width and height to be
+     0.4 and 0.5 respectively.  See also the `position' property.
+
+
+File: octave.info,  Node: Line Properties,  Next: Text Properties,  Prev: Axes Properties,  Up: Graphics Object Properties
+
+15.2.2.4 Line Properties
+........................
+
+`xdata'
+`ydata'
+`zdata'
+`ldata'
+`udata'
+`xldata'
+`xudata'
+     The data to be plotted.  The `ldata' and `udata' elements are for
+     errorbars in the y direction, and the `xldata' and `xudata'
+     elements are for errorbars in the x direction.
+
+`color'
+     The RGB color of the line, or a color name.  *Note Colors::.
+
+`linestyle'
+`linewidth'
+     *Note Line Styles::.
+
+`marker'
+
+`markeredgecolor'
+
+`markerfacecolor'
+
+`markersize'
+     *Note Marker Styles::.
+
+`keylabel'
+     The text of the legend entry corresponding to this line.  Note
+     that this property is not compatible with MATLAB and may be
+     removed in a future version of Octave.
+
+
+File: octave.info,  Node: Text Properties,  Next: Image Properties,  Prev: Line Properties,  Up: Graphics Object Properties
+
+15.2.2.5 Text Properties
+........................
+
+`string'
+     The character string contained by the text object.
+
+`units'
+     May be `"normalized"' or `"graph"'.
+
+`position'
+     The coordinates of the text object.
+
+`rotation'
+     The angle of rotation for the displayed text, measured in degrees.
+
+`horizontalalignment'
+     May be `"left"', `"center"', or `"right"'.
+
+`color'
+     The color of the text.  *Note Colors::.
+
+`fontname'
+     The font used for the text.
+
+`fontsize'
+     The size of the font, in points to use.
+
+`fontangle'
+     Flag whether the font is italic or normal.  Valid values are
+     'normal', 'italic' and 'oblique'.
+
+`fontweight'
+     Flag whether the font is bold, etc.  Valid values are 'normal',
+     'bold', 'demi' or 'light'.
+
+`interpreter'
+     Determines how the text is rendered.  Valid values are 'none',
+     'tex' or 'latex'.
+
+   All text objects, including titles, labels, legends, and text,
+include the property 'interpreter', this property determines the manner
+in which special control sequences in the text are rendered.  If the
+interpreter is set to 'none', then no rendering occurs.  At this point
+the 'latex' option is not implemented and so the 'latex' interpreter
+also does not interpret the text.
+
+   The 'tex' option implements a subset of TEX functionality in the
+rendering of the text.  This allows the insertion of special characters
+such as Greek or mathematical symbols within the text.  The special
+characters are also inserted with a code starting with the back-slash
+(\) character, as in the table *note tab:extended::.
+
+   In addition, the formatting of the text can be changed within the
+string with the codes
+
+               \bf            Bold font                                   
+               \it            Italic font                                 
+               \sl            Oblique Font                                
+               \rm            Normal font                                 
+
+   These are be used in conjunction with the { and } characters to limit
+the change in the font to part of the string.  For example
+
+     xlabel ('{\bf H} = a {\bf V}')
+
+   where the character 'a' will not appear in a bold font.  Note that to
+avoid having Octave interpret the backslash characters in the strings,
+the strings should be in single quotes.
+
+   It is also possible to change the fontname and size within the text
+
+        \fontname{FONTNAME}           Specify the font to use                     
+        \fontsize{SIZE}               Specify the size of the font to use         
+
+   Finally, the superscript and subscripting can be controlled with the
+'^' and '_' characters.  If the '^' or '_' is followed by a { character,
+then all of the block surrounded by the { } pair is super- or
+sub-scripted.  Without the { } pair, only the character immediately
+following the '^' or '_' is super- or sub-scripted.
+
+          \forall            \exists            \ni                
+          \cong              \Delta             \Phi               
+          \Gamma             \vartheta          \Lambda            
+          \Pi                \Theta             \Sigma             
+          \varsigma          \Omega             \Xi                
+          \Psi               \perp              \alpha             
+          \beta              \chi               \delta             
+          \epsilon           \phi               \gamma             
+          \eta               \iota              \varphi            
+          \kappa             \lambda            \mu                
+          \nu                \o                 \pi                
+          \theta             \rho               \sigma             
+          \tau               \upsilon           \varpi             
+          \omega             \xi                \psi               
+          \zeta              \sim               \Upsilon           
+          \prime             \leq               \infty             
+          \clubsuit          \diamondsuit       \heartsuit         
+          \spadesuit         \leftrightarrow    \leftarrow         
+          \uparrow           \rightarrow        \downarrow         
+          \circ              \pm                \geq               
+          \times             \propto            \partial           
+          \bullet            \div               \neq               
+          \equiv             \approx            \ldots             
+          \mid               \aleph             \Im                
+          \Re                \wp                \otimes            
+          \oplus             \oslash            \cap               
+          \cup               \supset            \supseteq          
+          \subset            \subseteq          \in                
+          \notin             \angle             \bigrightriangledown
+          \langle            \rangle            \nabla             
+          \prod              \surd              \cdot              
+          \neg               \wedge             \vee               
+          \Leftrightarrow    \Leftarrow         \Uparrow           
+          \Rightarrow        \Downarrow         \diamond           
+          \copyright         \lfloor            \lceil             
+          \rfloor            \rceil             \int               
+
+Table 15.1: Available special characters in TEX mode
+
+   A complete example showing the capabilities of the extended text is
+
+     x = 0:0.01:3;
+     plot(x,erf(x));
+     hold on;
+     plot(x,x,"r");
+     axis([0, 3, 0, 1]);
+     text(0.65, 0.6175, strcat('\leftarrow x = {2/\surd\pi',
+     ' {\fontsize{16}\int_{\fontsize{8}0}^{\fontsize{8}x}}',
+     ' e^{-t^2} dt} = 0.6175'))
+
+
+File: octave.info,  Node: Image Properties,  Next: Patch Properties,  Prev: Text Properties,  Up: Graphics Object Properties
+
+15.2.2.6 Image Properties
+.........................
+
+`cdata'
+     The data for the image.  Each pixel of the image corresponds to an
+     element of `cdata'.  The value of an element of `cdata' specifies
+     the row-index into the colormap of the axes object containing the
+     image.  The color value found in the color map for the given index
+     determines the color of the pixel.
+
+`xdata'
+`ydata'
+     Two-element vectors specifying the range of the x- and y-
+     coordinates for the image.
+
+
+File: octave.info,  Node: Patch Properties,  Next: Surface Properties,  Prev: Image Properties,  Up: Graphics Object Properties
+
+15.2.2.7 Patch Properties
+.........................
+
+`cdata'
+`xdata'
+`ydata'
+`zdata'
+     Data defining the patch object.
+
+`facecolor'
+     The fill color of the patch.  *Note Colors::.
+
+`facealpha'
+     A number in the range [0, 1] indicating the transparency of the
+     patch.
+
+`edgecolor'
+     The color of the line defining the patch.  *Note Colors::.
+
+`linestyle'
+`linewidth'
+     *Note Line Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+`markersize'
+     *Note Marker Styles::.
+
+
+File: octave.info,  Node: Surface Properties,  Next: Searching Properties,  Prev: Patch Properties,  Up: Graphics Object Properties
+
+15.2.2.8 Surface Properties
+...........................
+
+`xdata'
+`ydata'
+`zdata'
+     The data determining the surface.  The `xdata' and `ydata'
+     elements are vectors and `zdata' must be a matrix.
+
+`keylabel'
+     The text of the legend entry corresponding to this surface.  Note
+     that this property is not compatible with MATLAB and may be
+     removed in a future version of Octave.
+
+
+File: octave.info,  Node: Searching Properties,  Prev: Surface Properties,  Up: Graphics Object Properties
+
+15.2.2.9 Searching Properties
+.............................
+
+ -- Function File: H = findobj ()
+ -- Function File: H = findobj (PROP_NAME, PROP_VALUE)
+ -- Function File: H = findobj ('-property', PROP_NAME)
+ -- Function File: H = findobj ('-regexp', PROP_NAME, PATTERN)
+ -- Function File: H = findobj ('flat', ...)
+ -- Function File: H = findobj (H, ...)
+ -- Function File: H = findobj (H, '-depth', D, ...)
+     Find object with specified property values.  The simplest form is
+
+          findobj (PROP_NAME, PROP_VALUE)
+
+     which returns all of the handles to the objects with the name
+     PROP_NAME and the name PROP_VALUE.  The search can be limited to a
+     particular object or set of objects and their descendants by
+     passing a handle or set of handles H as the first argument to
+     `findobj'.
+
+     The depth of hierarchy of objects to which to search to can be
+     limited with the '-depth' argument.  To limit the number depth of
+     the hierarchy to search to D generations of children, and example
+     is
+
+          findobj (H, '-depth', D, PROP_NAME, PROP_VALUE)
+
+     Specifying a depth D of 0, limits the search to the set of object
+     passed in H.  A depth D of 0 is equivalent to the '-flat' argument.
+
+     A specified logical operator may be applied to the pairs of
+     PROP_NAME and PROP_VALUE.  The supported logical operators are
+     '-and', '-or', '-xor', '-not'.
+
+     The objects may also be matched by comparing a regular expression
+     to the property values, where property values that match `regexp
+     (PROP_VALUE, PATTERN)' are returned.  Finally, objects may be
+     matched by property name only, using the '-property' option.
+
+     *See also:* *note get: doc-get, *note set: doc-set.
+
+ -- Function File: H = findall ()
+ -- Function File: H = findall (PROP_NAME, PROP_VALUE)
+ -- Function File: H = findall (H, ...)
+ -- Function File: H = findall (H, "-depth", D, ...)
+     Find object with specified property values including hidden
+     handles.
+
+     This function performs the same function as `findobj', but it
+     includes hidden objects in its search.  For full documentation, see
+     `findobj'.
+
+     *See also:* *note get: doc-get, *note set: doc-set, *note findobj:
+     doc-findobj, *note allchild: doc-allchild.
+
diff --git a/doc/interpreter/octave.info-3 b/doc/interpreter/octave.info-3
new file mode 100644
index 0000000..b259b29
--- /dev/null
+++ b/doc/interpreter/octave.info-3
@@ -0,0 +1,7878 @@
+This is octave.info, produced by makeinfo version 4.11 from ./octave.texi.
+
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, 2007
+John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+File: octave.info,  Node: Managing Default Properties,  Next: Colors,  Prev: Graphics Object Properties,  Up: Advanced Plotting
+
+15.2.3 Managing Default Properties
+----------------------------------
+
+Object properties have two classes of default values, "factory
+defaults" (the initial values) and "user-defined defaults", which may
+override the factory defaults.
+
+   Although default values may be set for any object, they are set in
+parent objects and apply to child objects.  For example,
+
+     set (0, "defaultlinecolor", "green");
+
+sets the default line color for all objects.  The rule for constructing
+the property name to set a default value is
+
+     default + OBJECT-TYPE + PROPERTY-NAME
+
+   This rule can lead to some strange looking names, for example
+`defaultlinelinewidth"' specifies the default `linewidth' property for
+`line' objects.
+
+   The example above used the root figure object, 0, so the default
+property value will apply to all line objects.  However, default values
+are hierarchical, so defaults set in a figure objects override those
+set in the root figure object.  Likewise, defaults set in axes objects
+override those set in figure or root figure objects.  For example,
+
+     subplot (2, 1, 1);
+     set (0, "defaultlinecolor", "red");
+     set (1, "defaultlinecolor", "green");
+     set (gca (), "defaultlinecolor", "blue");
+     line (1:10, rand (1, 10));
+     subplot (2, 1, 2);
+     line (1:10, rand (1, 10));
+     figure (2)
+     line (1:10, rand (1, 10));
+
+produces two figures.  The line in first subplot window of the first
+figure is blue because it inherits its color from its parent axes
+object.  The line in the second subplot window of the first figure is
+green because it inherits its color from its parent figure object.  The
+line in the second figure window is red because it inherits its color
+from the global root figure parent object.
+
+   To remove a user-defined default setting, set the default property to
+the value `"remove"'.  For example,
+
+     set (gca (), "defaultlinecolor", "remove");
+
+removes the user-defined default line color setting from the current
+axes object.
+
+   Getting the `"default"' property of an object returns a list of
+user-defined defaults set for the object.  For example,
+
+     get (gca (), "default");
+
+returns a list of user-defined default values for the current axes
+object.
+
+   Factory default values are stored in the root figure object.  The
+command
+
+     get (0, "factory");
+
+returns a list of factory defaults.
+
+
+File: octave.info,  Node: Colors,  Next: Line Styles,  Prev: Managing Default Properties,  Up: Advanced Plotting
+
+15.2.4 Colors
+-------------
+
+Colors may be specified as RGB triplets with values ranging from zero to
+one, or by name.  Recognized color names include `"blue"', `"black"',
+`"cyan"', `"green"', `"magenta"', `"red"', `"white"', and `"yellow"'.
+
+
+File: octave.info,  Node: Line Styles,  Next: Marker Styles,  Prev: Colors,  Up: Advanced Plotting
+
+15.2.5 Line Styles
+------------------
+
+Line styles are specified by the following properties:
+
+`linestyle'
+     May be one of
+    `"-"'
+          Solid lines.
+
+    `"--"'
+          Dashed lines.
+
+    `":"'
+          Points.
+
+    `"-."'
+          A dash-dot line.
+
+`linewidth'
+     A number specifying the width of the line.  The default is 1.  A
+     value of 2 is twice as wide as the default, etc.
+
+
+File: octave.info,  Node: Marker Styles,  Next: Callbacks,  Prev: Line Styles,  Up: Advanced Plotting
+
+15.2.6 Marker Styles
+--------------------
+
+Marker styles are specified by the following properties:
+`marker'
+     A character indicating a plot marker to be place at each data
+     point, or `"none"', meaning no markers should be displayed.
+
+`markeredgecolor'
+     The color of the edge around the marker, or `"auto"', meaning that
+     the edge color is the same as the face color.  *Note Colors::.
+
+`markerfacecolor'
+     The color of the marker, or `"none"' to indicate that the marker
+     should not be filled.  *Note Colors::.
+
+`markersize'
+     A number specifying the size of the marker.  The default is 1.  A
+     value of 2 is twice as large as the default, etc.
+
+
+File: octave.info,  Node: Callbacks,  Next: Object Groups,  Prev: Marker Styles,  Up: Advanced Plotting
+
+15.2.7 Callbacks
+----------------
+
+Callback functions can be associated with graphics objects and triggered
+after certain events occur.  The basic structure of all callback
+function is
+
+     function mycallback (src, data)
+     ...
+     endfunction
+
+   where `src' gives a handle to the source of the callback, and `code'
+gives some event specific data.  This can then be associated with an
+object either at the objects creation or later with the `set' function.
+For example
+
+     plot (x, "DeleteFcn", @(s, e) disp("Window Deleted"))
+
+where at the moment that the plot is deleted, the message "Window
+Deleted" will be displayed.
+
+   Additional user arguments can be passed to callback functions, and
+will be passed after the 2 default arguments.  For example
+
+     plot (x, "DeleteFcn", {@mycallback, "1"})
+     ...
+     function mycallback (src, data, a1)
+       fprintf ("Closing plot %d\n", a1);
+     endfunction
+
+   The basic callback functions that are available for all graphics
+objects are
+
+   * CreateFcn This is the callback that is called at the moment of the
+     objects creation.  It is not called if the object is altered in
+     any way, and so it only makes sense to define this callback in the
+     function call that defines the object.  Callbacks that are added
+     to `CreateFcn' later with the `set' function will never be
+     executed.
+
+   * DeleteFcn This is the callback that is called at the moment an
+     object is deleted.
+
+   * ButtonDownFcn This is the callback that is called if a mouse
+     button is pressed while the pointer is over this object.  Note,
+     that the gnuplot interface does not respect this callback.
+
+   The object and figure that the event occurred in that resulted in the
+callback being called can be found with the `gcbo' and `gcbf' functions.
+
+ -- Function File: H = gcbo ()
+ -- Function File: [H, FIG] = gcbo ()
+     Return a handle to the object whose callback is currently
+     executing.  If no callback is executing, this function returns the
+     empty matrix.  This handle is obtained from the root object
+     property "CallbackObject".
+
+     Additionally return the handle of the figure containing the object
+     whose callback is currently executing.  If no callback is
+     executing, the second output is also set to the empty matrix.
+
+     *See also:* *note gcf: doc-gcf, *note gca: doc-gca, *note gcbf:
+     doc-gcbf.
+
+ -- Function File: FIG = gcbf ()
+     Return a handle to the figure containing the object whose callback
+     is currently executing.  If no callback is executing, this function
+     returns the empty matrix.  The handle returned by this function is
+     the same as the second output argument of gcbo.
+
+     *See also:* *note gcf: doc-gcf, *note gca: doc-gca, *note gcbo:
+     doc-gcbo.
+
+   Callbacks can equally be added to properties with the `addlistener'
+function described below.
+
+
+File: octave.info,  Node: Object Groups,  Next: Graphics backends,  Prev: Callbacks,  Up: Advanced Plotting
+
+15.2.8 Object Groups
+--------------------
+
+A number of Octave high level plot functions return groups of other
+graphics objects or they return graphics objects that are have their
+properties linked in such a way that changes to one of the properties
+results in changes in the others.  A graphic object that groups other
+objects is an `hggroup'
+
+ -- Function File:  hggroup ()
+ -- Function File:  hggroup (H)
+ -- Function File:  hggroup (..., PROPERTY, VALUE, ...)
+     Create group object with parent H.  If no parent is specified, the
+     group is created in the current axes.  Return the handle of the
+     group object created.
+
+     Multiple property-value pairs may be specified for the group, but
+     they must appear in pairs.
+
+   For example a simple use of a `hggroup' might be
+
+     x = 0:0.1:10;
+     hg = hggroup ();
+     plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+     hold on
+     plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+     set (hg, "visible", "off");
+
+which groups the two plots into a single object and controls their
+visibility directly.  The default properties of an `hggroup' are the
+same as the set of common properties for the other graphics objects.
+Additional properties can be added with the `addproperty' function.
+
+ -- Built-in Function:  addproperty (NAME, H, TYPE, [ARG, ...])
+     Create a new property named NAME in graphics object H.  TYPE
+     determines the type of the property to create.  ARGS usually
+     contains the default value of the property, but additional
+     arguments might be given, depending on the type of the property.
+
+     The supported property types are:
+
+    `string'
+          A string property.  ARG contains the default string value.
+
+    `any'
+          An un-typed property.  This kind of property can hold any
+          octave value.  ARGS contains the default value.
+
+    `radio'
+          A string property with a limited set of accepted values.  The
+          first argument must be a string with all accepted values
+          separated by a vertical bar ('|').  The default value can be
+          marked by enclosing it with a '{' '}' pair.  The default
+          value may also be given as an optional second string argument.
+
+    `boolean'
+          A boolean property.  This property type is equivalent to a
+          radio property with "on|off" as accepted values.  ARG contains
+          the default property value.
+
+    `double'
+          A scalar double property.  ARG contains the default value.
+
+    `handle'
+          A handle property.  This kind of property holds the handle of
+          a graphics object.  ARG contains the default handle value.
+          When no default value is given, the property is initialized to
+          the empty matrix.
+
+    `data'
+          A data (matrix) property.  ARG contains the default data
+          value.  When no default value is given, the data is
+          initialized to the empty matrix.
+
+    `color'
+          A color property.  ARG contains the default color value.
+          When no default color is given, the property is set to black.
+          An optional second string argument may be given to specify an
+          additional set of accepted string values (like a radio
+          property).
+
+     TYPE may also be the concatenation of a core object type and a
+     valid property name for that object type.  The property created
+     then has the same characteristics as the referenced property (type,
+     possible values, hidden state...).  This allows to clone an
+     existing property into the graphics object H.
+
+     Examples:
+
+          addproperty ("my_property", gcf, "string", "a string value");
+          addproperty ("my_radio", gcf, "radio", "val_1|val_2|{val_3}");
+          addproperty ("my_style", gcf, "linelinestyle", "--");
+
+
+   Once a property in added to an `hggroup', it is not linked to any
+other property of either the children of the group, or any other
+graphics object.  Add so to control the way in which this newly added
+property is used, the `addlistener' function is used to define a
+callback function that is executed when the property is altered.
+
+ -- Built-in Function:  addlistener (H, PROP, FCN)
+     Register FCN as listener for the property PROP of the graphics
+     object H.  Property listeners are executed (in order of
+     registration) when the property is set.  The new value is already
+     available when the listeners are executed.
+
+     PROP must be a string naming a valid property in H.
+
+     FCN can be a function handle, a string or a cell array whose first
+     element is a function handle.  If FCN is a function handle, the
+     corresponding function should accept at least 2 arguments, that
+     will be set to the object handle and the empty matrix
+     respectively.  If FCN is a string, it must be any valid octave
+     expression.  If FCN is a cell array, the first element must be a
+     function handle with the same signature as described above.  The
+     next elements of the cell array are passed as additional arguments
+     to the function.
+
+     Example:
+
+          function my_listener (h, dummy, p1)
+            fprintf ("my_listener called with p1=%s\n", p1);
+          endfunction
+
+          addlistener (gcf, "position", {@my_listener, "my string"})
+
+
+ -- Built-in Function:  dellistener (H, PROP, FCN)
+     Remove the registration of FCN as a listener for the property PROP
+     of the graphics object H.  The function FCN must be the same
+     variable (not just the same value), as was passed to the original
+     call to `addlistener'.
+
+     If FCN is not defined then all listener functions of PROP are
+     removed.
+
+     Example:
+
+          function my_listener (h, dummy, p1)
+            fprintf ("my_listener called with p1=%s\n", p1);
+          endfunction
+
+          c = {@my_listener, "my string"};
+          addlistener (gcf, "position", c);
+          dellistener (gcf, "position", c);
+
+
+   An example of the use of these two functions might be
+
+     x = 0:0.1:10;
+     hg = hggroup ();
+     h = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+     addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+     addlistener (hg, "linestyle", @update_props);
+     hold on
+     plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+
+     function update_props (h, d)
+       set (get (h, "children"), "linestyle", get (h, "linestyle"));
+     endfunction
+
+that adds a `linestyle' property to the `hggroup' and propagating any
+changes its value to the children of the group.  The `linkprop'
+function can be used to simplify the above to be
+
+     x = 0:0.1:10;
+     hg = hggroup ();
+     h1 = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+     addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+     hold on
+     h2 = plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+     hlink = linkprop ([hg, h1, h2], "color");
+
+ -- Function File: HLINK = linkprop (H, PROP)
+     Links graphics object properties, such that a change in one is
+     propagated to the others.  The properties to link are given as a
+     string of cell string array by PROP and the objects containing
+     these properties by the handle array H.
+
+     An example of the use of linkprops is
+
+          x = 0:0.1:10;
+          subplot (1, 2, 1);
+          h1 = plot (x, sin (x));
+          subplot (1, 2, 2);
+          h2 = plot (x, cos (x));
+          hlink = linkprop ([h1, h2], {"color","linestyle"});
+          set (h1, "color", "green");
+          set (h2, "linestyle", "--");
+
+
+   These capabilities are used in a number of basic graphics objects.
+The `hggroup' objects created by the functions of Octave contain one or
+more graphics object and are used to:
+
+   * group together multiple graphics objects,
+
+   * create linked properties between different graphics objects, and
+
+   * to hide the nominal user data, from the actual data of the objects.
+
+For example the `stem' function creates a stem series where each
+`hggroup' of the stem series contains two line objects representing the
+body and head of the stem.  The `ydata' property of the `hggroup' of
+the stem series represents the head of the stem, whereas the body of
+the stem is between the baseline and this value.  For example
+
+     h = stem (1:4)
+     get (h, "xdata")
+     => [  1   2   3   4]'
+     get (get (h, "children")(1), "xdata")
+     => [  1   1 NaN   2   2 NaN   3   3 NaN   4   4 NaN]'
+
+shows the difference between the `xdata' of the `hggroup' of a stem
+series object and the underlying line.
+
+   The basic properties of such group objects is that they consist of
+one or more linked `hggroup', and that changes in certain properties of
+these groups are propagated to other members of the group.  Whereas,
+certain properties of the members of the group only apply to the current
+member.
+
+   In addition the members of the group can also be linked to other
+graphics objects through callback functions.  For example the baseline
+of the `bar' or `stem' functions is a line object, whose length and
+position are automatically adjusted, based on changes to the
+corresponding hggroup elements.
+
+* Menu:
+
+* Data sources in object groups::
+* Area series::
+* Bar series::
+* Contour groups::
+* Error bar series::
+* Line series::
+* Quiver group::
+* Scatter group::
+* Stair group::
+* Stem Series::
+* Surface group::
+
+
+File: octave.info,  Node: Data sources in object groups,  Next: Area series,  Up: Object Groups
+
+15.2.8.1 Data sources in object groups
+......................................
+
+All of the group objects contain data source parameters.  There are
+string parameters that contain an expression that is evaluated to update
+the relevant data property of the group when the `refreshdata' function
+is called.
+
+ -- Function File:  refreshdata ()
+ -- Function File:  refreshdata (H)
+ -- Function File:  refreshdata (H, WORKSPACE)
+     Evaluate any `datasource' properties of the current figure and
+     update the plot if the corresponding data has changed.  If called
+     with one or more arguments H is a scalar or array of figure
+     handles to refresh.  The optional second argument WORKSPACE can
+     take the following values.
+
+    `"base"'
+          Evaluate the datasource properties in the base workspace.
+          (default).
+
+    `"caller"'
+          Evaluate the datasource properties in the workspace of the
+          function that called `refreshdata'.
+
+     An example of the use of `refreshdata' is:
+
+          x = 0:0.1:10;
+          y = sin (x);
+          plot (x, y, "ydatasource", "y");
+          for i = 1 : 100
+            pause(0.1)
+            y = sin (x + 0.1 * i);
+            refreshdata();
+          endfor
+
+
+File: octave.info,  Node: Area series,  Next: Bar series,  Prev: Data sources in object groups,  Up: Object Groups
+
+15.2.8.2 Area series
+....................
+
+Area series objects are created by the `area' function.  Each of the
+`hggroup' elements contains a single patch object.  The properties of
+the area series are
+
+`basevalue'
+     The value where the base of the area plot is drawn.
+
+`linewidth'
+`linestyle'
+     The line width and style of the edge of the patch objects making
+     up the areas.  *Note Line Styles::.
+
+`edgecolor'
+`facecolor'
+     The line and fill color of the patch objects making up the areas.
+     *Note Colors::.
+
+`xdata'
+`ydata'
+     The x and y coordinates of the original columns of the data passed
+     to `area' prior to the cumulative summation used in the `area'
+     function.
+
+`xdatasource'
+`ydatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Bar series,  Next: Contour groups,  Prev: Area series,  Up: Object Groups
+
+15.2.8.3 Bar series
+...................
+
+Bar series objects are created by the `bar' or `barh' functions.  Each
+`hggroup' element contains a single patch object.  The properties of
+the bar series are
+
+`showbaseline'
+`baseline'
+`basevalue'
+     The property `showbaseline' flags whether the baseline of the bar
+     series is displayed (default is "on").  The handle of the graphics
+     object representing the baseline is given by the `baseline'
+     property and the y-value of the baseline by the `basevalue'
+     property.
+
+     Changes to any of these property are propagated to the other
+     members of the bar series and to the baseline itself.  Equally
+     changes in the properties of the base line itself are propagated
+     to the members of the corresponding bar series.
+
+`barwidth'
+`barlayout'
+`horizontal'
+     The property `barwidth' is the width of the bar corresponding to
+     the WIDTH variable passed to `bar' or BARH.  Whether the bar
+     series is "grouped" or "stacked" is determined by the `barlayout'
+     property and whether the bars are horizontal or vertical by the
+     `horizontal' property.
+
+     Changes to any of these property are propagated to the other
+     members of the bar series.
+
+`linewidth'
+`linestyle'
+     The line width and style of the edge of the patch objects making
+     up the bars.  *Note Line Styles::.
+
+`edgecolor'
+`facecolor'
+     The line and fill color of the patch objects making up the bars.
+     *Note Colors::.
+
+`xdata'
+     The nominal x positions of the bars.  Changes in this property and
+     propagated to the other members of the bar series.
+
+`ydata'
+     The y value of the bars in the `hggroup'.
+
+`xdatasource'
+`ydatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Contour groups,  Next: Error bar series,  Prev: Bar series,  Up: Object Groups
+
+15.2.8.4 Contour groups
+.......................
+
+Contour group objects are created by the `contour', `contourf' and
+`contour3' functions.  The are equally one of the handles returned by
+the `surfc' and `meshc' functions.  The properties of the contour group
+are
+
+`contourmatrix'
+     A read only property that contains the data return by `contourc'
+     used to create the contours of the plot.
+
+`fill'
+     A radio property that can have the values "on" or "off" that flags
+     whether the contours to plot are to be filled.
+
+`zlevelmode'
+`zlevel'
+     The radio property `zlevelmode' can have the values "none", "auto"
+     or "manual".  When its value is "none" there is no z component to
+     the plotted contours.  When its value is "auto" the z value of the
+     plotted contours is at the same value as the contour itself.  If
+     the value is "manual", then the z value at which to plot the
+     contour is determined by the `zlevel' property.
+
+`levellistmode'
+`levellist'
+`levelstepmode'
+`levelstep'
+     If `levellistmode' is "manual", then the levels at which to plot
+     the contours is determined by `levellist'.  If `levellistmode' is
+     set to "auto", then the distance between contours is determined by
+     `levelstep'.  If both `levellistmode' and `levelstepmode' are set
+     to "auto", then there are assumed to be 10 equal spaced contours.
+
+`textlistmode'
+`textlist'
+`textstepmode'
+`textstep'
+     If `textlistmode' is "manual", then the labelled contours is
+     determined by `textlist'.  If `textlistmode' is set to "auto",
+     then the distance between labelled contours is determined by
+     `textstep'.  If both `textlistmode' and `textstepmode' are set to
+     "auto", then there are assumed to be 10 equal spaced labelled
+     contours.
+
+`showtext'
+     Flag whether the contour labels are shown or not.
+
+`labelspacing'
+     The distance between labels on a single contour in points.
+
+`linewidth'
+
+`linestyle'
+
+`linecolor'
+     The properties of the contour lines.  The properties `linewidth'
+     and `linestyle' are similar to the corresponding properties for
+     lines.  The property `linecolor' is a color property (*note
+     Colors::), that can also have the values of "none" or "auto".  If
+     `linecolor' is "none", then no contour line is drawn.  If
+     `linecolor' is "auto" then the line color is determined by the
+     colormap.
+
+`xdata'
+`ydata'
+`zdata'
+     The original x, y, and z data of the contour lines.
+
+`xdatasource'
+`ydatasource'
+`zdatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Error bar series,  Next: Line series,  Prev: Contour groups,  Up: Object Groups
+
+15.2.8.5 Error bar series
+.........................
+
+Error bar series are created by the `errorbar' function.  Each
+`hggroup' element contains two line objects representing the data and
+the errorbars separately.  The properties of the error bar series are
+
+`color'
+     The RGB color or color name of the line objects of the error bars.
+     *Note Colors::.
+
+`linewidth'
+`linestyle'
+     The line width and style of the line objects of the error bars.
+     *Note Line Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+`markersize'
+     The line and fill color of the markers on the error bars.  *Note
+     Colors::.
+
+`xdata'
+`ydata'
+`ldata'
+`udata'
+`xldata'
+`xudata'
+     The original x, y, l, u, xl, xu data of the error bars.
+
+`xdatasource'
+`ydatasource'
+`ldatasource'
+`udatasource'
+`xldatasource'
+`xudatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Line series,  Next: Quiver group,  Prev: Error bar series,  Up: Object Groups
+
+15.2.8.6 Line series
+....................
+
+Line series objects are created by the `plot'  and `plot3' functions
+and are of the type `line'.  The properties of the line series with the
+ability to add data sources.
+
+`color'
+     The RGB color or color name of the line objects.  *Note Colors::.
+
+`linewidth'
+`linestyle'
+     The line width and style of the line objects.  *Note Line Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+`markersize'
+     The line and fill color of the markers.  *Note Colors::.
+
+`xdata'
+`ydata'
+`zdata'
+     The original x, y and z data.
+
+`xdatasource'
+`ydatasource'
+`zdatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Quiver group,  Next: Scatter group,  Prev: Line series,  Up: Object Groups
+
+15.2.8.7 Quiver group
+.....................
+
+Quiver series objects are created by the `quiver' or `quiver3'
+functions.  Each `hggroup' element of the series contains three line
+objects as children representing the body and head of the arrow,
+together with a marker as the point of original of the arrows.  The
+properties of the quiver series are
+
+`autoscale'
+`autoscalefactor'
+     Flag whether the length of the arrows is scaled or defined
+     directly from the U, V and W data.  If the arrow length is flagged
+     as being scaled by the `autoscale' property, then the length of the
+     autoscaled arrow is controlled by the `autoscalefactor'.
+
+`maxheadsize'
+     This property controls the size of the head of the arrows in the
+     quiver series.  The default value is 0.2.
+
+`showarrowhead'
+     Flag whether the arrow heads are displayed in the quiver plot.
+
+`color'
+     The RGB color or color name of the line objects of the quiver.
+     *Note Colors::.
+
+`linewidth'
+`linestyle'
+     The line width and style of the line objects of the quiver.  *Note
+     Line Styles::.
+
+`marker'
+`markerfacecolor'
+`markersize'
+     The line and fill color of the marker objects at the original of
+     the arrows.  *Note Colors::.
+
+`xdata'
+`ydata'
+`zdata'
+     The origins of the values of the vector field.
+
+`udata'
+`vdata'
+`wdata'
+     The values of the vector field to plot.
+
+`xdatasource'
+`ydatasource'
+`zdatasource'
+`udatasource'
+`vdatasource'
+`wdatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Scatter group,  Next: Stair group,  Prev: Quiver group,  Up: Object Groups
+
+15.2.8.8 Scatter group
+......................
+
+Scatter series objects are created by the `scatter' or `scatter3'
+functions.  A single hggroup element contains as many children as there
+are points in the scatter plot, with each child representing one of the
+points.  The properties of the stem series are
+
+`linewidth'
+     The line width of the line objects of the points.  *Note Line
+     Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+     The line and fill color of the markers of the points.  *Note
+     Colors::.
+
+`xdata'
+`ydata'
+`zdata'
+     The original x, y and z data of the stems.
+
+`cdata'
+     The color data for the points of the plot.  Each point can have a
+     separate color, or a unique color can be specified.
+
+`sizedata'
+     The size data for the points of the plot.  Each point can its own
+     size or a unique size can be specified.
+
+`xdatasource'
+`ydatasource'
+`zdatasource'
+`cdatasource'
+`sizedatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Stair group,  Next: Stem Series,  Prev: Scatter group,  Up: Object Groups
+
+15.2.8.9 Stair group
+....................
+
+Stair series objects are created by the `stair' function.  Each
+`hggroup' element of the series contains a single line object as a
+child representing the stair.  The properties of the stair series are
+
+`color'
+     The RGB color or color name of the line objects of the stairs.
+     *Note Colors::.
+
+`linewidth'
+`linestyle'
+     The line width and style of the line objects of the stairs.  *Note
+     Line Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+`markersize'
+     The line and fill color of the markers on the stairs.  *Note
+     Colors::.
+
+`xdata'
+`ydata'
+     The original x and y data of the stairs.
+
+`xdatasource'
+`ydatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Stem Series,  Next: Surface group,  Prev: Stair group,  Up: Object Groups
+
+15.2.8.10 Stem Series
+.....................
+
+Stem series objects are created by the `stem' or `stem3' functions.
+Each `hggroup' element contains a single line object as a child
+representing the stems.  The properties of the stem series are
+
+`showbaseline'
+`baseline'
+`basevalue'
+     The property `showbaseline' flags whether the baseline of the stem
+     series is displayed (default is "on").  The handle of the graphics
+     object representing the baseline is given by the `baseline'
+     property and the y-value (or z-value for `stem3') of the baseline
+     by the `basevalue' property.
+
+     Changes to any of these property are propagated to the other
+     members of the stem series and to the baseline itself.  Equally
+     changes in the properties of the base line itself are propagated
+     to the members of the corresponding stem series.
+
+`color'
+     The RGB color or color name of the line objects of the stems.
+     *Note Colors::.
+
+`linewidth'
+`linestyle'
+     The line width and style of the line objects of the stems.  *Note
+     Line Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+`markersize'
+     The line and fill color of the markers on the stems.  *Note
+     Colors::.
+
+`xdata'
+`ydata'
+`zdata'
+     The original x, y and z data of the stems.
+
+`xdatasource'
+`ydatasource'
+`zdatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Surface group,  Prev: Stem Series,  Up: Object Groups
+
+15.2.8.11 Surface group
+.......................
+
+Surface group objects are created by the `surf' or `mesh' functions,
+but are equally one of the handles returned by the `surfc' or `meshc'
+functions.  The surface group is of the type `surface'.
+
+   The properties of the surface group are
+
+`edgecolor'
+
+`facecolor'
+     The RGB color or color name of the edges or faces of the surface.
+     *Note Colors::.
+
+`linewidth'
+`linestyle'
+     The line width and style of the lines on the surface.  *Note Line
+     Styles::.
+
+`marker'
+`markeredgecolor'
+`markerfacecolor'
+`markersize'
+     The line and fill color of the markers on the surface.  *Note
+     Colors::.
+
+`xdata'
+`ydata'
+`zdata'
+
+`cdata'
+     The original x, y, z and c data.
+
+`xdatasource'
+`ydatasource'
+`zdatasource'
+`cdatasource'
+     Data source variables.
+
+
+File: octave.info,  Node: Graphics backends,  Prev: Object Groups,  Up: Advanced Plotting
+
+15.2.9 Graphics backends
+------------------------
+
+ -- Function File:  backend (NAME)
+ -- Function File:  backend (HLIST, NAME)
+     Change the default graphics backend to NAME.  If the backend is
+     not already loaded, it is first initialized (initialization is done
+     through the execution of `__init_NAME__').
+
+     When called with a list of figure handles, HLIST, the backend is
+     changed only for the listed figures.
+
+     *See also:* *note available_backends: doc-available_backends.
+
+ -- Built-in Function:  available_backends ()
+     Return a cell array of registered graphics backends.
+
+* Menu:
+
+* Interaction with gnuplot::
+
+
+File: octave.info,  Node: Interaction with gnuplot,  Up: Graphics backends
+
+15.2.9.1 Interaction with `gnuplot'
+...................................
+
+ -- Loadable Function: VAL = gnuplot_binary ()
+ -- Loadable Function: OLD_VAL = gnuplot_binary (NEW_VAL)
+     Query or set the name of the program invoked by the plot command.
+     The default value `\"gnuplot\"'.  *Note Installation::.
+
+
+File: octave.info,  Node: Matrix Manipulation,  Next: Arithmetic,  Prev: Plotting,  Up: Top
+
+16 Matrix Manipulation
+**********************
+
+There are a number of functions available for checking to see if the
+elements of a matrix meet some condition, and for rearranging the
+elements of a matrix.  For example, Octave can easily tell you if all
+the elements of a matrix are finite, or are less than some specified
+value.  Octave can also rotate the elements, extract the upper- or
+lower-triangular parts, or sort the columns of a matrix.
+
+* Menu:
+
+* Finding Elements and Checking Conditions::
+* Rearranging Matrices::
+* Applying a Function to an Array::
+* Special Utility Matrices::
+* Famous Matrices::
+
+
+File: octave.info,  Node: Finding Elements and Checking Conditions,  Next: Rearranging Matrices,  Up: Matrix Manipulation
+
+16.1 Finding Elements and Checking Conditions
+=============================================
+
+The functions `any' and `all' are useful for determining whether any or
+all of the elements of a matrix satisfy some condition.  The `find'
+function is also useful in determining which elements of a matrix meet
+a specified condition.
+
+ -- Built-in Function:  any (X, DIM)
+     For a vector argument, return 1 if any element of the vector is
+     nonzero.
+
+     For a matrix argument, return a row vector of ones and zeros with
+     each element indicating whether any of the elements of the
+     corresponding column of the matrix are nonzero.  For example,
+
+          any (eye (2, 4))
+               => [ 1, 1, 0, 0 ]
+
+     If the optional argument DIM is supplied, work along dimension
+     DIM.  For example,
+
+          any (eye (2, 4), 2)
+               => [ 1; 1 ]
+
+ -- Built-in Function:  all (X, DIM)
+     The function `all' behaves like the function `any', except that it
+     returns true only if all the elements of a vector, or all the
+     elements along dimension DIM of a matrix, are nonzero.
+
+   Since the comparison operators (*note Comparison Ops::) return
+matrices of ones and zeros, it is easy to test a matrix for many
+things, not just whether the elements are nonzero.  For example,
+
+     all (all (rand (5) < 0.9))
+          => 0
+
+tests a random 5 by 5 matrix to see if all of its elements are less
+than 0.9.
+
+   Note that in conditional contexts (like the test clause of `if' and
+`while' statements) Octave treats the test as if you had typed `all
+(all (condition))'.
+
+ -- Mapping Function:  xor (X, Y)
+     Return the `exclusive or' of the entries of X and Y.  For boolean
+     expressions X and Y, `xor (X, Y)' is true if and only if X or Y is
+     true, but not if both X and Y are true.
+
+ -- Function File:  is_duplicate_entry (X)
+     Return non-zero if any entries in X are duplicates of one another.
+
+ -- Function File:  diff (X, K, DIM)
+     If X is a vector of length N, `diff (X)' is the vector of first
+     differences X(2) - X(1), ..., X(n) - X(n-1).
+
+     If X is a matrix, `diff (X)' is the matrix of column differences
+     along the first non-singleton dimension.
+
+     The second argument is optional.  If supplied, `diff (X, K)',
+     where K is a non-negative integer, returns the K-th differences.
+     It is possible that K is larger than then first non-singleton
+     dimension of the matrix.  In this case, `diff' continues to take
+     the differences along the next non-singleton dimension.
+
+     The dimension along which to take the difference can be explicitly
+     stated with the optional variable DIM.  In this case the K-th
+     order differences are calculated along this dimension.  In the
+     case where K exceeds `size (X, DIM)' then an empty matrix is
+     returned.
+
+ -- Mapping Function:  isinf (X)
+     Return 1 for elements of X that are infinite and zero otherwise.
+     For example,
+
+          isinf ([13, Inf, NA, NaN])
+               => [ 0, 1, 0, 0 ]
+
+ -- Mapping Function:  isnan (X)
+     Return 1 for elements of X that are NaN values and zero otherwise.
+     NA values are also considered NaN values.  For example,
+
+          isnan ([13, Inf, NA, NaN])
+               => [ 0, 0, 1, 1 ]
+
+     *See also:* *note isna: doc-isna.
+
+ -- Mapping Function:  finite (X)
+     Return 1 for elements of X that are finite values and zero
+     otherwise.  For example,
+
+          finite ([13, Inf, NA, NaN])
+               => [ 1, 0, 0, 0 ]
+
+ -- Loadable Function:  find (X)
+ -- Loadable Function:  find (X, N)
+ -- Loadable Function:  find (X, N, DIRECTION)
+     Return a vector of indices of nonzero elements of a matrix, as a
+     row if X is a row or as a column otherwise.  To obtain a single
+     index for each matrix element, Octave pretends that the columns of
+     a matrix form one long vector (like Fortran arrays are stored).
+     For example,
+
+          find (eye (2))
+               => [ 1; 4 ]
+
+     If two outputs are requested, `find' returns the row and column
+     indices of nonzero elements of a matrix.  For example,
+
+          [i, j] = find (2 * eye (2))
+               => i = [ 1; 2 ]
+               => j = [ 1; 2 ]
+
+     If three outputs are requested, `find' also returns a vector
+     containing the nonzero values.  For example,
+
+          [i, j, v] = find (3 * eye (2))
+               => i = [ 1; 2 ]
+               => j = [ 1; 2 ]
+               => v = [ 3; 3 ]
+
+     If two inputs are given, N indicates the maximum number of
+     elements to find from the beginning of the matrix or vector.
+
+     If three inputs are given, DIRECTION should be one of "first" or
+     "last", requesting only the first or last N indices, respectively.
+     However, the indices are always returned in ascending order.
+
+     Note that this function is particularly useful for sparse
+     matrices, as it extracts the non-zero elements as vectors, which
+     can then be used to create the original matrix.  For example,
+
+          sz = size(a);
+          [i, j, v] = find (a);
+          b = sparse(i, j, v, sz(1), sz(2));
+
+     *See also:* *note sparse: doc-sparse.
+
+ -- Function File: [ERR, Y1, ...] = common_size (X1, ...)
+     Determine if all input arguments are either scalar or of common
+     size.  If so, ERR is zero, and YI is a matrix of the common size
+     with all entries equal to XI if this is a scalar or XI otherwise.
+     If the inputs cannot be brought to a common size, errorcode is 1,
+     and YI is XI.  For example,
+
+          [errorcode, a, b] = common_size ([1 2; 3 4], 5)
+               => errorcode = 0
+               => a = [ 1, 2; 3, 4 ]
+               => b = [ 5, 5; 5, 5 ]
+
+     This is useful for implementing functions where arguments can
+     either be scalars or of common size.
+
+
+File: octave.info,  Node: Rearranging Matrices,  Next: Applying a Function to an Array,  Prev: Finding Elements and Checking Conditions,  Up: Matrix Manipulation
+
+16.2 Rearranging Matrices
+=========================
+
+ -- Function File:  fliplr (X)
+     Return a copy of X with the order of the columns reversed.  For
+     example,
+
+          fliplr ([1, 2; 3, 4])
+               =>  2  1
+                   4  3
+
+     Note that `fliplr' only work with 2-D arrays.  To flip N-d arrays
+     use `flipdim' instead.
+
+     *See also:* *note flipud: doc-flipud, *note flipdim: doc-flipdim,
+     *note rot90: doc-rot90, *note rotdim: doc-rotdim.
+
+ -- Function File:  flipud (X)
+     Return a copy of X with the order of the rows reversed.  For
+     example,
+
+          flipud ([1, 2; 3, 4])
+               =>  3  4
+                   1  2
+
+     Due to the difficulty of defining which axis about which to flip
+     the matrix `flipud' only work with 2-d arrays.  To flip N-d arrays
+     use `flipdim' instead.
+
+     *See also:* *note fliplr: doc-fliplr, *note flipdim: doc-flipdim,
+     *note rot90: doc-rot90, *note rotdim: doc-rotdim.
+
+ -- Function File:  flipdim (X, DIM)
+     Return a copy of X flipped about the dimension DIM.  For example
+
+          flipdim ([1, 2; 3, 4], 2)
+               =>  2  1
+                   4  3
+
+     *See also:* *note fliplr: doc-fliplr, *note flipud: doc-flipud,
+     *note rot90: doc-rot90, *note rotdim: doc-rotdim.
+
+ -- Function File:  rot90 (X, N)
+     Return a copy of X with the elements rotated counterclockwise in
+     90-degree increments.  The second argument is optional, and
+     specifies how many 90-degree rotations are to be applied (the
+     default value is 1).  Negative values of N rotate the matrix in a
+     clockwise direction.  For example,
+
+          rot90 ([1, 2; 3, 4], -1)
+               =>  3  1
+                   4  2
+
+     rotates the given matrix clockwise by 90 degrees.  The following
+     are all equivalent statements:
+
+          rot90 ([1, 2; 3, 4], -1)
+          rot90 ([1, 2; 3, 4], 3)
+          rot90 ([1, 2; 3, 4], 7)
+
+     Due to the difficulty of defining an axis about which to rotate the
+     matrix `rot90' only work with 2-D arrays.  To rotate N-d arrays
+     use `rotdim' instead.
+
+     *See also:* *note rotdim: doc-rotdim, *note flipud: doc-flipud,
+     *note fliplr: doc-fliplr, *note flipdim: doc-flipdim.
+
+ -- Function File:  rotdim (X, N, PLANE)
+     Return a copy of X with the elements rotated counterclockwise in
+     90-degree increments.  The second argument is optional, and
+     specifies how many 90-degree rotations are to be applied (the
+     default value is 1).  The third argument is also optional and
+     defines the plane of the rotation.  As such PLANE is a two element
+     vector containing two different valid dimensions of the matrix.
+     If PLANE is not given Then the first two non-singleton dimensions
+     are used.
+
+     Negative values of N rotate the matrix in a clockwise direction.
+     For example,
+
+          rotdim ([1, 2; 3, 4], -1, [1, 2])
+               =>  3  1
+                   4  2
+
+     rotates the given matrix clockwise by 90 degrees.  The following
+     are all equivalent statements:
+
+          rotdim ([1, 2; 3, 4], -1, [1, 2])
+          rotdim ([1, 2; 3, 4], 3, [1, 2])
+          rotdim ([1, 2; 3, 4], 7, [1, 2])
+
+     *See also:* *note rot90: doc-rot90, *note flipud: doc-flipud,
+     *note fliplr: doc-fliplr, *note flipdim: doc-flipdim.
+
+ -- Built-in Function:  cat (DIM, ARRAY1, ARRAY2, ..., ARRAYN)
+     Return the concatenation of N-d array objects, ARRAY1, ARRAY2,
+     ..., ARRAYN along dimension DIM.
+
+          A = ones (2, 2);
+          B = zeros (2, 2);
+          cat (2, A, B)
+          => ans =
+
+               1 1 0 0
+               1 1 0 0
+
+     Alternatively, we can concatenate A and B along the second
+     dimension the following way:
+
+          [A, B].
+
+     DIM can be larger than the dimensions of the N-d array objects and
+     the result will thus have DIM dimensions as the following example
+     shows:
+          cat (4, ones(2, 2), zeros (2, 2))
+          => ans =
+
+             ans(:,:,1,1) =
+
+               1 1
+               1 1
+
+             ans(:,:,1,2) =
+               0 0
+               0 0
+
+     *See also:* *note horzcat: doc-horzcat, *note vertcat: doc-vertcat.
+
+ -- Built-in Function:  horzcat (ARRAY1, ARRAY2, ..., ARRAYN)
+     Return the horizontal concatenation of N-d array objects, ARRAY1,
+     ARRAY2, ..., ARRAYN along dimension 2.
+
+     *See also:* *note cat: doc-cat, *note vertcat: doc-vertcat.
+
+ -- Built-in Function:  vertcat (ARRAY1, ARRAY2, ..., ARRAYN)
+     Return the vertical concatenation of N-d array objects, ARRAY1,
+     ARRAY2, ..., ARRAYN along dimension 1.
+
+     *See also:* *note cat: doc-cat, *note horzcat: doc-horzcat.
+
+ -- Built-in Function:  permute (A, PERM)
+     Return the generalized transpose for an N-d array object A.  The
+     permutation vector PERM must contain the elements `1:ndims(a)' (in
+     any order, but each element must appear just once).
+
+     *See also:* *note ipermute: doc-ipermute.
+
+ -- Built-in Function:  ipermute (A, IPERM)
+     The inverse of the `permute' function.  The expression
+
+          ipermute (permute (a, perm), perm)
+     returns the original array A.
+
+     *See also:* *note permute: doc-permute.
+
+ -- Built-in Function:  reshape (A, M, N, ...)
+ -- Built-in Function:  reshape (A, SIZE)
+     Return a matrix with the given dimensions whose elements are taken
+     from the matrix A.  The elements of the matrix are accessed in
+     column-major order (like Fortran arrays are stored).
+
+     For example,
+
+          reshape ([1, 2, 3, 4], 2, 2)
+               =>  1  3
+                   2  4
+
+     Note that the total number of elements in the original matrix must
+     match the total number of elements in the new matrix.
+
+     A single dimension of the return matrix can be unknown and is
+     flagged by an empty argument.
+
+ -- Built-in Function:  resize (X, M)
+ -- Built-in Function:  resize (X, M, N)
+ -- Built-in Function:  resize (X, M, N, ...)
+     Resize X cutting off elements as necessary.
+
+     In the result, element with certain indices is equal to the
+     corresponding element of X if the indices are within the bounds of
+     X; otherwise, the element is set to zero.
+
+     In other words, the statement
+
+            y = resize (x, dv);
+
+     is equivalent to the following code:
+
+            y = zeros (dv, class (x));
+            sz = min (dv, size (x));
+            for i = 1:length (sz), idx{i} = 1:sz(i); endfor
+            y(idx{:}) = x(idx{:});
+
+     but is performed more efficiently.
+
+     If only M is supplied and it is a scalar, the dimension of the
+     result is M-by-M.  If M is a vector, then the dimensions of the
+     result are given by the elements of M.  If both M and N are
+     scalars, then the dimensions of the result are M-by-N.
+
+     An object can be resized to more dimensions than it has; in such
+     case the missing dimensions are assumed to be 1.  Resizing an
+     object to fewer dimensions is not possible.
+
+     *See also:* *note reshape: doc-reshape, *note postpad: doc-postpad.
+
+ -- Function File: Y = circshift (X, N)
+     Circularly shifts the values of the array X.  N must be a vector
+     of integers no longer than the number of dimensions in X.  The
+     values of N can be either positive or negative, which determines
+     the direction in which the values or X are shifted.  If an element
+     of N is zero, then the corresponding dimension of X will not be
+     shifted.  For example
+
+          x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+          circshift (x, 1)
+          =>  7, 8, 9
+              1, 2, 3
+              4, 5, 6
+          circshift (x, -2)
+          =>  7, 8, 9
+              1, 2, 3
+              4, 5, 6
+          circshift (x, [0,1])
+          =>  3, 1, 2
+              6, 4, 5
+              9, 7, 8
+
+     *See also:* permute, ipermute, shiftdim.
+
+ -- Function File: Y = shiftdim (X, N)
+ -- Function File: [Y, NS] = shiftdim (X)
+     Shifts the dimension of X by N, where N must be an integer scalar.
+     When N is positive, the dimensions of X are shifted to the left,
+     with the leading dimensions circulated to the end.  If N is
+     negative, then the dimensions of X are shifted to the right, with
+     N leading singleton dimensions added.
+
+     Called with a single argument, `shiftdim', removes the leading
+     singleton dimensions, returning the number of dimensions removed
+     in the second output argument NS.
+
+     For example
+
+          x = ones (1, 2, 3);
+          size (shiftdim (x, -1))
+               => [1, 1, 2, 3]
+          size (shiftdim (x, 1))
+               => [2, 3]
+          [b, ns] = shiftdim (x);
+               => b =  [1, 1, 1; 1, 1, 1]
+               => ns = 1
+
+     *See also:* reshape, permute, ipermute, circshift, squeeze.
+
+ -- Function File:  shift (X, B)
+ -- Function File:  shift (X, B, DIM)
+     If X is a vector, perform a circular shift of length B of the
+     elements of X.
+
+     If X is a matrix, do the same for each column of X.  If the
+     optional DIM argument is given, operate along this dimension
+
+ -- Loadable Function: [S, I] = sort (X)
+ -- Loadable Function: [S, I] = sort (X, DIM)
+ -- Loadable Function: [S, I] = sort (X, MODE)
+ -- Loadable Function: [S, I] = sort (X, DIM, MODE)
+     Return a copy of X with the elements arranged in increasing order.
+     For matrices, `sort' orders the elements in each column.
+
+     For example,
+
+          sort ([1, 2; 2, 3; 3, 1])
+               =>  1  1
+                   2  2
+                   3  3
+
+     The `sort' function may also be used to produce a matrix
+     containing the original row indices of the elements in the sorted
+     matrix.  For example,
+
+          [s, i] = sort ([1, 2; 2, 3; 3, 1])
+               => s = 1  1
+                      2  2
+                      3  3
+               => i = 1  3
+                      2  1
+                      3  2
+
+     If the optional argument DIM is given, then the matrix is sorted
+     along the dimension defined by DIM.  The optional argument `mode'
+     defines the order in which the values will be sorted.  Valid
+     values of `mode' are `ascend' or `descend'.
+
+     For equal elements, the indices are such that the equal elements
+     are listed in the order that appeared in the original list.
+
+     The `sort' function may also be used to sort strings and cell
+     arrays of strings, in which case the dictionary order of the
+     strings is used.
+
+     The algorithm used in `sort' is optimized for the sorting of
+     partially ordered lists.
+
+ -- Function File:  sortrows (A, C)
+     Sort the rows of the matrix A according to the order of the
+     columns specified in C.  If C is omitted, a lexicographical sort
+     is used.  By default ascending order is used however if elements
+     of C are negative then the corresponding column is sorted in
+     descending order.
+
+ -- Built-in Function:  issorted (A, ROWS)
+     Returns true if the array is sorted, ascending or descending.
+     NaNs are treated as by `sort'.  If ROWS is supplied and has the
+     value "rows", checks whether the array is sorted by rows as if
+     output by `sortrows' (with no options).
+
+     This function does not yet support sparse matrices.
+
+     *See also:* *note sortrows: doc-sortrows, *note sort: doc-sort.
+
+   Since the `sort' function does not allow sort keys to be specified,
+it can't be used to order the rows of a matrix according to the values
+of the elements in various columns(1) in a single call.  Using the
+second output, however, it is possible to sort all rows based on the
+values in a given column.  Here's an example that sorts the rows of a
+matrix based on the values in the second column.
+
+     a = [1, 2; 2, 3; 3, 1];
+     [s, i] = sort (a (:, 2));
+     a (i, :)
+          =>  3  1
+              1  2
+              2  3
+
+ -- Function File:  tril (A, K)
+ -- Function File:  triu (A, K)
+     Return a new matrix formed by extracting the lower (`tril') or
+     upper (`triu') triangular part of the matrix A, and setting all
+     other elements to zero.  The second argument is optional, and
+     specifies how many diagonals above or below the main diagonal
+     should also be set to zero.
+
+     The default value of K is zero, so that `triu' and `tril' normally
+     include the main diagonal as part of the result matrix.
+
+     If the value of K is negative, additional elements above (for
+     `tril') or below (for `triu') the main diagonal are also selected.
+
+     The absolute value of K must not be greater than the number of
+     sub- or super-diagonals.
+
+     For example,
+
+          tril (ones (3), -1)
+               =>  0  0  0
+                   1  0  0
+                   1  1  0
+
+     and
+
+          tril (ones (3), 1)
+               =>  1  1  0
+                   1  1  1
+                   1  1  1
+
+     *See also:* *note triu: doc-triu, *note diag: doc-diag.
+
+ -- Function File:  vec (X)
+     Return the vector obtained by stacking the columns of the matrix X
+     one above the other.
+
+ -- Function File:  vech (X)
+     Return the vector obtained by eliminating all supradiagonal
+     elements of the square matrix X and stacking the result one column
+     above the other.
+
+ -- Function File:  prepad (X, L, C)
+ -- Function File:  prepad (X, L, C, DIM)
+     Prepend (append) the scalar value C to the vector X until it is of
+     length L.  If the third argument is not supplied, a value of 0 is
+     used.
+
+     If `length (X) > L', elements from the beginning (end) of X are
+     removed until a vector of length L is obtained.
+
+     If X is a matrix, elements are prepended or removed from each row.
+
+     If the optional DIM argument is given, then operate along this
+     dimension.
+
+     *See also:* *note postpad: doc-postpad.
+
+ -- Built-in Function:  diag (V, K)
+     Return a diagonal matrix with 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 ([1, 2, 3], 1)
+               =>  0  1  0  0
+                   0  0  2  0
+                   0  0  0  3
+                   0  0  0  0
+
+     Given a matrix argument, instead of a vector, `diag' extracts the
+     K-th diagonal of the matrix.
+
+ -- Function File:  blkdiag (A, B, C, ...)
+     Build a block diagonal matrix from A, B, C, ....  All the
+     arguments must be numeric and are two-dimensional matrices or
+     scalars.
+
+     *See also:* *note diag: doc-diag, *note horzcat: doc-horzcat,
+     *note vertcat: doc-vertcat.
+
+   ---------- Footnotes ----------
+
+   (1) For example, to first sort based on the values in column 1, and
+then, for any values that are repeated in column 1, sort based on the
+values found in column 2, etc.
+
+
+File: octave.info,  Node: Applying a Function to an Array,  Next: Special Utility Matrices,  Prev: Rearranging Matrices,  Up: Matrix Manipulation
+
+16.3 Applying a Function to an Array
+====================================
+
+ -- Function File:  arrayfun (FUNC, A)
+ -- Function File: X = arrayfun (FUNC, A)
+ -- Function File: X = arrayfun (FUNC, A, B, ...)
+ -- Function File: [X, Y, ...] = arrayfun (FUNC, A, ...)
+ -- Function File:  arrayfun (..., "UniformOutput", VAL)
+ -- Function File:  arrayfun (..., "ErrorHandler", ERRFUNC)
+     Execute a function on each element of an array.  This is useful for
+     functions that do not accept array arguments.  If the function does
+     accept array arguments it is better to call the function directly.
+
+     The first input argument FUNC can be a string, a function handle,
+     an inline function or an anonymous function.  The input argument A
+     can be a logic array, a numeric array, a string array, a structure
+     array or a cell array.  By a call of the function `arrayfun' all
+     elements of A are passed on to the named function FUNC
+     individually.
+
+     The named function can also take more than two input arguments,
+     with the input arguments given as third input argument B, fourth
+     input argument C, ...  If given more than one array input argument
+     then all input arguments must have the same sizes, for example
+
+          arrayfun (@atan2, [1, 0], [0, 1])
+          => ans = [1.5708   0.0000]
+
+     If the parameter VAL after a further string input argument
+     "UniformOutput" is set `true' (the default), then the named
+     function FUNC must return a single element which then will be
+     concatenated into the return value and is of type matrix.
+     Otherwise, if that parameter is set to `false', then the outputs
+     are concatenated in a cell array.  For example
+
+          arrayfun (@(x,y) x:y, "abc", "def", "UniformOutput", false)
+          => ans =
+          {
+            [1,1] = abcd
+            [1,2] = bcde
+            [1,3] = cdef
+          }
+
+     If more than one output arguments are given then the named function
+     must return the number of return values that also are expected, for
+     example
+
+          [A, B, C] = arrayfun (@find, [10; 0], "UniformOutput", false)
+          =>
+          A =
+          {
+            [1,1] =  1
+            [2,1] = [](0x0)
+          }
+          B =
+          {
+            [1,1] =  1
+            [2,1] = [](0x0)
+          }
+          C =
+          {
+            [1,1] =  10
+            [2,1] = [](0x0)
+          }
+
+     If the parameter ERRFUNC after a further string input argument
+     "ErrorHandler" is another string, a function handle, an inline
+     function or an anonymous function, then ERRFUNC defines a function
+     to call in the case that FUNC generates an error.  The definition
+     of the function must be of the form
+
+          function [...] = errfunc (S, ...)
+
+     where there is an additional input argument to ERRFUNC relative to
+     FUNC, given by S.  This is a structure with the elements
+     "identifier", "message" and "index", giving respectively the error
+     identifier, the error message and the index of the array elements
+     that caused the error.  The size of the output argument of ERRFUNC
+     must have the same size as the output argument of FUNC, otherwise
+     a real error is thrown.  For example
+
+          function y = ferr (s, x), y = "MyString"; endfunction
+          arrayfun (@str2num, [1234], \
+                    "UniformOutput", false, "ErrorHandler", @ferr)
+          => ans =
+          {
+           [1,1] = MyString
+          }
+
+     *See also:* *note cellfun: doc-cellfun, *note spfun: doc-spfun,
+     *note structfun: doc-structfun.
+
+ -- Loadable Function:  bsxfun (F, A, B)
+     Applies a binary function F element-wise to two matrix arguments A
+     and B.  The function F must be capable of accepting two column
+     vector arguments of equal length, or one column vector argument
+     and a scalar.
+
+     The dimensions of A and B must be equal or singleton.  The
+     singleton dimensions of the matrices will be expanded to the same
+     dimensionality as the other matrix.
+
+     *See also:* *note arrayfun: doc-arrayfun, *note cellfun:
+     doc-cellfun.
+
+
+File: octave.info,  Node: Special Utility Matrices,  Next: Famous Matrices,  Prev: Applying a Function to an Array,  Up: Matrix Manipulation
+
+16.4 Special Utility Matrices
+=============================
+
+ -- Built-in Function:  eye (X)
+ -- Built-in Function:  eye (N, M)
+ -- Built-in Function:  eye (..., CLASS)
+     Return an identity matrix.  If invoked with a single scalar
+     argument, `eye' returns a square matrix with the dimension
+     specified.  If you supply two scalar arguments, `eye' takes them
+     to be the number of rows and columns.  If given a vector with two
+     elements, `eye' uses the values of the elements as the number of
+     rows and columns, respectively.  For example,
+
+          eye (3)
+               =>  1  0  0
+                   0  1  0
+                   0  0  1
+
+     The following expressions all produce the same result:
+
+          eye (2)
+          ==
+          eye (2, 2)
+          ==
+          eye (size ([1, 2; 3, 4])
+
+     The optional argument CLASS, allows `eye' to return an array of
+     the specified type, like
+
+          val = zeros (n,m, "uint8")
+
+     Calling `eye' with no arguments is equivalent to calling it with
+     an argument of 1.  This odd definition is for compatibility with
+     MATLAB.
+
+ -- Built-in Function:  ones (X)
+ -- Built-in Function:  ones (N, M)
+ -- Built-in Function:  ones (N, M, K, ...)
+ -- Built-in Function:  ones (..., CLASS)
+     Return a matrix or N-dimensional array whose elements are all 1.
+     The arguments are handled the same as the arguments for `eye'.
+
+     If you need to create a matrix whose values are all the same, you
+     should use an expression like
+
+          val_matrix = val * ones (n, m)
+
+     The optional argument CLASS, allows `ones' to return an array of
+     the specified type, for example
+
+          val = ones (n,m, "uint8")
+
+ -- Built-in Function:  zeros (X)
+ -- Built-in Function:  zeros (N, M)
+ -- Built-in Function:  zeros (N, M, K, ...)
+ -- Built-in Function:  zeros (..., CLASS)
+     Return a matrix or N-dimensional array whose elements are all 0.
+     The arguments are handled the same as the arguments for `eye'.
+
+     The optional argument CLASS, allows `zeros' to return an array of
+     the specified type, for example
+
+          val = zeros (n,m, "uint8")
+
+ -- Function File:  repmat (A, M, N)
+ -- Function File:  repmat (A, [M N])
+ -- Function File:  repmat (A, [M N P ...])
+     Form a block matrix of size M by N, with a copy of matrix A as
+     each element.  If N is not specified, form an M by M block matrix.
+
+ -- Loadable Function:  rand (X)
+ -- Loadable Function:  rand (N, M)
+ -- Loadable Function:  rand ("state", X)
+ -- Loadable Function:  rand ("seed", X)
+     Return a matrix with random elements uniformly distributed on the
+     interval (0, 1).  The arguments are handled the same as the
+     arguments for `eye'.
+
+     You can query the state of the random number generator using the
+     form
+
+          v = rand ("state")
+
+     This returns a column vector V of length 625.  Later, you can
+     restore the random number generator to the state V using the form
+
+          rand ("state", v)
+
+     You may also initialize the state vector from an arbitrary vector
+     of length <= 625 for V.  This new state will be a hash based on the
+     value of V, not V itself.
+
+     By default, the generator is initialized from `/dev/urandom' if it
+     is available, otherwise from cpu time, wall clock time and the
+     current fraction of a second.
+
+     To compute the pseudo-random sequence, `rand' uses the Mersenne
+     Twister with a period of 2^19937-1 (See M. Matsumoto and T.
+     Nishimura, `Mersenne Twister: A 623-dimensionally equidistributed
+     uniform pseudorandom number generator', ACM Trans. on Modeling and
+     Computer Simulation Vol. 8, No. 1, January pp.3-30 1998,
+     `http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html').  Do
+     *not* use for cryptography without securely hashing several
+     returned values together, otherwise the generator state can be
+     learned after reading 624 consecutive values.
+
+     Older versions of Octave used a different random number generator.
+     The new generator is used by default as it is significantly faster
+     than the old generator, and produces random numbers with a
+     significantly longer cycle time.  However, in some circumstances
+     it might be desirable to obtain the same random sequences as used
+     by the old generators.  To do this the keyword "seed" is used to
+     specify that the old generators should be use, as in
+
+          rand ("seed", val)
+
+     which sets the seed of the generator to VAL.  The seed of the
+     generator can be queried with
+
+          s = rand ("seed")
+
+     However, it should be noted that querying the seed will not cause
+     `rand' to use the old generators, only setting the seed will.  To
+     cause `rand' to once again use the new generators, the keyword
+     "state" should be used to reset the state of the `rand'.
+
+     *See also:* *note randn: doc-randn, *note rande: doc-rande, *note
+     randg: doc-randg, *note randp: doc-randp.
+
+ -- Loadable Function:  randn (X)
+ -- Loadable Function:  randn (N, M)
+ -- Loadable Function:  randn ("state", X)
+ -- Loadable Function:  randn ("seed", X)
+     Return a matrix with normally distributed pseudo-random elements
+     having zero mean and variance one.  The arguments are handled the
+     same as the arguments for `rand'.
+
+     By default, `randn' uses the Marsaglia and Tsang "Ziggurat
+     technique" to transform from a uniform to a normal distribution.
+     (G. Marsaglia and W.W. Tsang, `Ziggurat method for generating
+     random variables', J. Statistical Software, vol 5, 2000,
+     `http://www.jstatsoft.org/v05/i08/')
+
+     *See also:* *note rand: doc-rand, *note rande: doc-rande, *note
+     randg: doc-randg, *note randp: doc-randp.
+
+ -- Loadable Function:  rande (X)
+ -- Loadable Function:  rande (N, M)
+ -- Loadable Function:  rande ("state", X)
+ -- Loadable Function:  rande ("seed", X)
+     Return a matrix with exponentially distributed random elements.
+     The arguments are handled the same as the arguments for `rand'.
+
+     By default, `randn' uses the Marsaglia and Tsang "Ziggurat
+     technique" to transform from a uniform to a exponential
+     distribution.  (G. Marsaglia and W.W. Tsang, `Ziggurat method for
+     generating random variables', J. Statistical Software, vol 5, 2000,
+     `http://www.jstatsoft.org/v05/i08/')
+
+     *See also:* *note rand: doc-rand, *note randn: doc-randn, *note
+     randg: doc-randg, *note randp: doc-randp.
+
+ -- Loadable Function:  randp (L, X)
+ -- Loadable Function:  randp (L, N, M)
+ -- Loadable Function:  randp ("state", X)
+ -- Loadable Function:  randp ("seed", X)
+     Return a matrix with Poisson distributed random elements with mean
+     value parameter given by the first argument, L.  The arguments are
+     handled the same as the arguments for `rand', except for the
+     argument L.
+
+     Five different algorithms are used depending on the range of L and
+     whether or not L is a scalar or a matrix.
+
+    For scalar L <= 12, use direct method.
+          Press, et al., 'Numerical Recipes in C', Cambridge University
+          Press, 1992.
+
+    For scalar L > 12, use rejection method.[1]
+          Press, et al., 'Numerical Recipes in C', Cambridge University
+          Press, 1992.
+
+    For matrix L <= 10, use inversion method.[2]
+          Stadlober E., et al., WinRand source code, available via FTP.
+
+    For matrix L > 10, use patchwork rejection method.
+          Stadlober E., et al., WinRand source code, available via FTP,
+          or H. Zechner, 'Efficient sampling from continuous and
+          discrete unimodal distributions', Doctoral Dissertation,
+          156pp., Technical University Graz, Austria, 1994.
+
+    For L > 1e8, use normal approximation.
+          L. Montanet, et al., 'Review of Particle Properties',
+          Physical Review D 50 p1284, 1994
+
+     *See also:* *note rand: doc-rand, *note randn: doc-randn, *note
+     rande: doc-rande, *note randg: doc-randg.
+
+ -- Loadable Function:  randg (A, X)
+ -- Loadable Function:  randg (A, N, M)
+ -- Loadable Function:  randg ("state", X)
+ -- Loadable Function:  randg ("seed", X)
+     Return a matrix with `gamma(A,1)' distributed random elements.
+     The arguments are handled the same as the arguments for `rand',
+     except for the argument A.
+
+     This can be used to generate many distributions:
+
+    `gamma (a, b)' for `a > -1', `b > 0'
+               r = b * randg (a)
+
+    `beta (a, b)' for `a > -1', `b > -1'
+               r1 = randg (a, 1)
+               r = r1 / (r1 + randg (b, 1))
+
+    `Erlang (a, n)'
+               r = a * randg (n)
+
+    `chisq (df)' for `df > 0'
+               r = 2 * randg (df / 2)
+
+    `t(df)' for `0 < df < inf' (use randn if df is infinite)
+               r = randn () / sqrt (2 * randg (df / 2) / df)
+
+    `F (n1, n2)' for `0 < n1', `0 < n2'
+               ## r1 equals 1 if n1 is infinite
+               r1 = 2 * randg (n1 / 2) / n1
+               ## r2 equals 1 if n2 is infinite
+               r2 = 2 * randg (n2 / 2) / n2
+               r = r1 / r2
+
+    negative `binomial (n, p)' for `n > 0', `0 < p <= 1'
+               r = randp ((1 - p) / p * randg (n))
+
+    non-central `chisq (df, L)', for `df >= 0' and `L > 0'
+          (use chisq if `L = 0')
+               r = randp (L / 2)
+               r(r > 0) = 2 * randg (r(r > 0))
+               r(df > 0) += 2 * randg (df(df > 0)/2)
+
+    `Dirichlet (a1, ... ak)'
+               r = (randg (a1), ..., randg (ak))
+               r = r / sum (r)
+
+     *See also:* *note rand: doc-rand, *note randn: doc-randn, *note
+     rande: doc-rande, *note randp: doc-randp.
+
+   The generators operate in the new or old style together, it is not
+possible to mix the two.  Initializing any generator with `"state"' or
+`"seed"' causes the others to switch to the same style for future calls.
+
+   The state of each generator is independent and calls to different
+generators can be interleaved without affecting the final result.  For
+example,
+
+     rand ("state", [11, 22, 33]);
+     randn ("state", [44, 55, 66]);
+     u = rand (100, 1);
+     n = randn (100, 1);
+
+and
+
+     rand ("state", [11, 22, 33]);
+     randn ("state", [44, 55, 66]);
+     u = zeros (100, 1);
+     n = zeros (100, 1);
+     for i = 1:100
+       u(i) = rand ();
+       n(i) = randn ();
+     end
+
+produce equivalent results.  When the generators are initialized in the
+old style with `"seed"' only `rand' and `randn' are independent,
+because the old `rande', `randg' and `randp' generators make calls to
+`rand' and `randn'.
+
+   The generators are initialized with random states at start-up, so
+that the sequences of random numbers are not the same each time you run
+Octave.(1) If you really do need to reproduce a sequence of numbers
+exactly, you can set the state or seed to a specific value.
+
+   If invoked without arguments, `rand' and `randn' return a single
+element of a random sequence.
+
+   The original `rand' and `randn' functions use Fortran code from
+RANLIB, a library of fortran routines for random number generation,
+compiled by Barry W. Brown and James Lovato of the Department of
+Biomathematics at The University of Texas, M.D. Anderson Cancer Center,
+Houston, TX 77030.
+
+ -- Function File:  randperm (N)
+     Return a row vector containing a random permutation of the
+     integers from 1 to N.
+
+   The functions `linspace' and `logspace' make it very easy to create
+vectors with evenly or logarithmically spaced elements.  *Note Ranges::.
+
+ -- Built-in Function:  linspace (BASE, LIMIT, N)
+     Return a row vector with N linearly spaced elements between BASE
+     and LIMIT.  If the number of elements is greater than one, then
+     the BASE and LIMIT are always included in the range.  If BASE is
+     greater than LIMIT, the elements are stored in decreasing order.
+     If the number of points is not specified, a value of 100 is used.
+
+     The `linspace' function always returns a row vector.
+
+     For compatibility with MATLAB, return the second argument if fewer
+     than two values are requested.
+
+ -- Function File:  logspace (BASE, LIMIT, N)
+     Similar to `linspace' except that the values are logarithmically
+     spaced from 10^base to 10^limit.
+
+     If LIMIT is equal to pi, the points are between 10^base and pi,
+     _not_ 10^base and 10^pi, in order to be compatible with the
+     corresponding MATLAB function.
+
+     Also for compatibility, return the second argument if fewer than
+     two values are requested.
+
+     *See also:* *note linspace: doc-linspace.
+
+   ---------- Footnotes ----------
+
+   (1) The old versions of `rand' and `randn' obtain their initial
+seeds from the system clock.
+
+
+File: octave.info,  Node: Famous Matrices,  Prev: Special Utility Matrices,  Up: Matrix Manipulation
+
+16.5 Famous Matrices
+====================
+
+The following functions return famous matrix forms.
+
+ -- Function File:  hadamard (N)
+     Construct a Hadamard matrix HN of size N-by-N.  The size N must be
+     of the form `2 ^ K * P' in which P is one of 1, 12, 20 or 28.  The
+     returned matrix is normalized, meaning `Hn(:,1) == 1' and `H(1,:)
+     == 1'.
+
+     Some of the properties of Hadamard matrices are:
+
+        * `kron (HM, HN)' is a Hadamard matrix of size M-by-N.
+
+        * `Hn * Hn' == N * eye (N)'.
+
+        * The rows of HN are orthogonal.
+
+        * `det (A) <= abs(det (HN))' for all A with `abs (A (I, J)) <=
+          1'.
+
+        * Multiply any row or column by -1 and still have a Hadamard
+          matrix.
+
+
+ -- Function File:  hankel (C, R)
+     Return the Hankel matrix constructed given the first column C, and
+     (optionally) the last row R.  If the last element of C is not the
+     same as the first element of R, the last element of C is used.  If
+     the second argument is omitted, it is assumed to be a vector of
+     zeros with the same size as C.
+
+     A Hankel matrix formed from an m-vector C, and an n-vector R, has
+     the elements
+
+          H(i,j) = c(i+j-1),  i+j-1 <= m;
+          H(i,j) = r(i+j-m),  otherwise
+
+     *See also:* *note vander: doc-vander, *note sylvester_matrix:
+     doc-sylvester_matrix, *note hilb: doc-hilb, *note invhilb:
+     doc-invhilb, *note toeplitz: doc-toeplitz.
+
+ -- Function File:  hilb (N)
+     Return the Hilbert matrix of order N.  The i, j element of a
+     Hilbert matrix is defined as
+
+          H (i, j) = 1 / (i + j - 1)
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note sylvester_matrix: doc-sylvester_matrix, *note invhilb:
+     doc-invhilb, *note toeplitz: doc-toeplitz.
+
+ -- Function File:  invhilb (N)
+     Return the inverse of a Hilbert matrix of order N.  This can be
+     computed exactly using
+
+                      (i+j)         /n+i-1\  /n+j-1\   /i+j-2\ 2
+           A(i,j) = -1      (i+j-1)(       )(       ) (       )
+                                    \ n-j /  \ n-i /   \ i-2 /
+
+                  = p(i) p(j) / (i+j-1)
+     where
+                       k  /k+n-1\   /n\
+              p(k) = -1  (       ) (   )
+                          \ k-1 /   \k/
+
+     The validity of this formula can easily be checked by expanding
+     the binomial coefficients in both formulas as factorials.  It can
+     be derived more directly via the theory of Cauchy matrices: see J.
+     W. Demmel, Applied Numerical Linear Algebra, page 92.
+
+     Compare this with the numerical calculation of `inverse (hilb
+     (n))', which suffers from the ill-conditioning of the Hilbert
+     matrix, and the finite precision of your computer's floating point
+     arithmetic.
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note sylvester_matrix: doc-sylvester_matrix, *note hilb:
+     doc-hilb, *note toeplitz: doc-toeplitz.
+
+ -- Function File:  magic (N)
+     Create an N-by-N magic square.  Note that `magic (2)' is undefined
+     since there is no 2-by-2 magic square.
+
+
+ -- Function File:  pascal (N, T)
+     Return the Pascal matrix of order N if `T = 0'.  T defaults to 0.
+     Return lower triangular Cholesky factor of the Pascal matrix if `T
+     = 1'.  This matrix is its own inverse, that is `pascal (N, 1) ^ 2
+     == eye (N)'.  If `T = -1', return its absolute value.  This is the
+     standard pascal triangle as a lower-triangular matrix.  If `T =
+     2', return a transposed and permuted version of `pascal (N, 1)',
+     which is the cube-root of the identity matrix.  That is `pascal
+     (N, 2) ^ 3 == eye (N)'.
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note sylvester_matrix: doc-sylvester_matrix, *note hilb:
+     doc-hilb, *note invhilb: doc-invhilb, *note toeplitz:
+     doc-toeplitz, *note hadamard: doc-hadamard, *note wilkinson:
+     doc-wilkinson, *note compan: doc-compan, *note rosser: doc-rosser.
+
+ -- Function File:  rosser ()
+     Returns the Rosser matrix.  This is a difficult test case used to
+     test eigenvalue algorithms.
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note sylvester_matrix: doc-sylvester_matrix, *note hilb:
+     doc-hilb, *note invhilb: doc-invhilb, *note toeplitz:
+     doc-toeplitz, *note hadamard: doc-hadamard, *note wilkinson:
+     doc-wilkinson, *note compan: doc-compan, *note pascal: doc-pascal.
+
+ -- Function File:  sylvester_matrix (K)
+     Return the Sylvester matrix of order n = 2^k.
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note hilb: doc-hilb, *note invhilb: doc-invhilb, *note toeplitz:
+     doc-toeplitz.
+
+ -- Function File:  toeplitz (C, R)
+     Return the Toeplitz matrix constructed given the first column C,
+     and (optionally) the first row R.  If the first element of C is
+     not the same as the first element of R, the first element of C is
+     used.  If the second argument is omitted, the first row is taken
+     to be the same as the first column.
+
+     A square Toeplitz matrix has the form:
+
+          c(0)  r(1)   r(2)  ...  r(n)
+          c(1)  c(0)   r(1)  ... r(n-1)
+          c(2)  c(1)   c(0)  ... r(n-2)
+           .     ,      ,   .      .
+           .     ,      ,     .    .
+           .     ,      ,       .  .
+          c(n) c(n-1) c(n-2) ...  c(0)
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note sylvester_matrix: doc-sylvester_matrix, *note hilb:
+     doc-hilb, *note invhilb: doc-invhilb.
+
+ -- Function File:  vander (C, N)
+     Return the Vandermonde matrix whose next to last column is C.  If
+     N is specified, it determines the number of columns; otherwise, N
+     is taken to be equal to the length of C.
+
+     A Vandermonde matrix has the form:
+
+          c(1)^(n-1) ... c(1)^2  c(1)  1
+          c(2)^(n-1) ... c(2)^2  c(2)  1
+              .     .      .      .    .
+              .       .    .      .    .
+              .         .  .      .    .
+          c(n)^(n-1) ... c(n)^2  c(n)  1
+
+     *See also:* *note hankel: doc-hankel, *note sylvester_matrix:
+     doc-sylvester_matrix, *note hilb: doc-hilb, *note invhilb:
+     doc-invhilb, *note toeplitz: doc-toeplitz.
+
+ -- Function File:  wilkinson (N)
+     Return the Wilkinson matrix of order N.
+
+     *See also:* *note hankel: doc-hankel, *note vander: doc-vander,
+     *note sylvester_matrix: doc-sylvester_matrix, *note hilb:
+     doc-hilb, *note invhilb: doc-invhilb, *note toeplitz:
+     doc-toeplitz, *note hadamard: doc-hadamard, *note rosser:
+     doc-rosser, *note compan: doc-compan, *note pascal: doc-pascal.
+
+
+File: octave.info,  Node: Arithmetic,  Next: Linear Algebra,  Prev: Matrix Manipulation,  Up: Top
+
+17 Arithmetic
+*************
+
+Unless otherwise noted, all of the functions described in this chapter
+will work for real and complex scalar, vector, or matrix arguments.
+Functions described as "mapping functions" apply the given operation
+individually to each element when given a matrix argument.  For example,
+
+     sin ([1, 2; 3, 4])
+          =>  0.84147   0.90930
+              0.14112  -0.75680
+
+* Menu:
+
+* Exponents and Logarithms::
+* Complex Arithmetic::
+* Trigonometry::
+* Sums and Products::
+* Utility Functions::
+* Special Functions::
+* Coordinate Transformations::
+* Mathematical Constants::
+
+
+File: octave.info,  Node: Exponents and Logarithms,  Next: Complex Arithmetic,  Up: Arithmetic
+
+17.1 Exponents and Logarithms
+=============================
+
+ -- Mapping Function:  exp (X)
+     Compute `e^x' for each element of X.  To compute the matrix
+     exponential, see *note Linear Algebra::.
+
+     *See also:* *note log: doc-log.
+
+ -- Mapping Function:  expm1 (X)
+     Compute `exp (X) - 1' accurately in the neighborhood of zero.
+
+     *See also:* *note exp: doc-exp.
+
+ -- Mapping Function:  log (X)
+     Compute the natural logarithm, `ln (X)', for each element of X.
+     To compute the matrix logarithm, see *note Linear Algebra::.
+
+     *See also:* *note exp: doc-exp, *note log1p: doc-log1p, *note
+     log2: doc-log2, *note log10: doc-log10, *note logspace:
+     doc-logspace.
+
+ -- Mapping Function:  log1p (X)
+     Compute `log (1 + X)' accurately in the neighborhood of zero.
+
+     *See also:* *note log: doc-log, *note exp: doc-exp, *note expm1:
+     doc-expm1.
+
+ -- Mapping Function:  log10 (X)
+     Compute the base-10 logarithm of each element of X.
+
+     *See also:* *note log: doc-log, *note log2: doc-log2, *note
+     logspace: doc-logspace, *note exp: doc-exp.
+
+ -- Mapping Function:  log2 (X)
+ -- Mapping Function: [F, E] = log2 (X)
+     Compute the base-2 logarithm of each element of X.
+
+     If called with two output arguments, split X into binary mantissa
+     and exponent so that `1/2 <= abs(f) < 1' and E is an integer.  If
+     `x = 0', `f = e = 0'.
+
+     *See also:* *note pow2: doc-pow2, *note log: doc-log, *note log10:
+     doc-log10, *note exp: doc-exp.
+
+ -- Function File:  nextpow2 (X)
+     If X is a scalar, return the first integer N such that 2^n >= abs
+     (x).
+
+     If X is a vector, return `nextpow2 (length (X))'.
+
+     *See also:* *note pow2: doc-pow2, *note log2: doc-log2.
+
+ -- Function File:  nthroot (X, N)
+     Compute the n-th root of X, returning real results for real
+     components of X.  For example
+
+          nthroot (-1, 3)
+          => -1
+          (-1) ^ (1 / 3)
+          => 0.50000 - 0.86603i
+
+
+ -- Mapping Function:  pow2 (X)
+ -- Mapping Function:  pow2 (F, E)
+     With one argument, computes 2 .^ x for each element of X.
+
+     With two arguments, returns f .* (2 .^ e).
+
+     *See also:* *note log2: doc-log2, *note nextpow2: doc-nextpow2.
+
+ -- Function File:  reallog (X)
+     Return the real-valued natural logarithm of each element of X.
+     Report an error if any element results in a complex return value.
+
+     *See also:* *note log: doc-log, *note realpow: doc-realpow, *note
+     realsqrt: doc-realsqrt.
+
+ -- Function File:  realpow (X, Y)
+     Compute the real-valued, element-by-element power operator.  This
+     is equivalent to `X .^ Y', except that `realpow' reports an error
+     if any return value is complex.
+
+     *See also:* *note reallog: doc-reallog, *note realsqrt:
+     doc-realsqrt.
+
+ -- Function File:  realsqrt (X)
+     Return the real-valued square root of each element of X.  Report an
+     error if any element results in a complex return value.
+
+     *See also:* *note sqrt: doc-sqrt, *note realpow: doc-realpow,
+     *note reallog: doc-reallog.
+
+ -- Mapping Function:  sqrt (X)
+     Compute the square root of each element of X.  If X is negative, a
+     complex result is returned.  To compute the matrix square root, see
+     *note Linear Algebra::.
+
+     *See also:* *note realsqrt: doc-realsqrt.
+
+
+File: octave.info,  Node: Complex Arithmetic,  Next: Trigonometry,  Prev: Exponents and Logarithms,  Up: Arithmetic
+
+17.2 Complex Arithmetic
+=======================
+
+In the descriptions of the following functions, Z is the complex number
+X + IY, where I is defined as `sqrt (-1)'.
+
+ -- Mapping Function:  abs (Z)
+     Compute the magnitude of Z, defined as |Z| = `sqrt (x^2 + y^2)'.
+
+     For example,
+
+          abs (3 + 4i)
+               => 5
+
+ -- Mapping Function:  arg (Z)
+ -- Mapping Function:  angle (Z)
+     Compute the argument of Z, defined as, THETA = `atan2 (Y, X)', in
+     radians.
+
+     For example,
+
+          arg (3 + 4i)
+               => 0.92730
+
+ -- Mapping Function:  conj (Z)
+     Return the complex conjugate of Z, defined as `conj (Z)' = X - IY.
+
+     *See also:* *note real: doc-real, *note imag: doc-imag.
+
+ -- Function File:  cplxpair (Z)
+ -- Function File:  cplxpair (Z, TOL)
+ -- Function File:  cplxpair (Z, TOL, DIM)
+     Sort the numbers Z into complex conjugate pairs ordered by
+     increasing real part.  Place the negative imaginary complex number
+     first within each pair.  Place all the real numbers (those with
+     `abs (imag (Z) / Z) < TOL)') after the complex pairs.
+
+     If TOL is unspecified the default value is 100*`eps'.
+
+     By default the complex pairs are sorted along the first
+     non-singleton dimension of Z.  If DIM is specified, then the
+     complex pairs are sorted along this dimension.
+
+     Signal an error if some complex numbers could not be paired.
+     Signal an error if all complex numbers are not exact conjugates
+     (to within TOL).  Note that there is no defined order for pairs
+     with identical real parts but differing imaginary parts.
+
+          cplxpair (exp(2i*pi*[0:4]'/5)) == exp(2i*pi*[3; 2; 4; 1; 0]/5)
+
+ -- Mapping Function:  imag (Z)
+     Return the imaginary part of Z as a real number.
+
+     *See also:* *note real: doc-real, *note conj: doc-conj.
+
+ -- Mapping Function:  real (Z)
+     Return the real part of Z.
+
+     *See also:* *note imag: doc-imag, *note conj: doc-conj.
+
+
+File: octave.info,  Node: Trigonometry,  Next: Sums and Products,  Prev: Complex Arithmetic,  Up: Arithmetic
+
+17.3 Trigonometry
+=================
+
+Octave provides the following trigonometric functions where angles are
+specified in radians.  To convert from degrees to radians multiply by
+`pi/180' (e.g., `sin (30 * pi/180)' returns the sine of 30 degrees).  As
+an alternative, Octave provides a number of trigonometric functions
+which work directly on an argument specified in degrees.  These
+functions are named after the base trigonometric function with a `d'
+suffix.  For example, `sin' expects an angle in radians while `sind'
+expects an angle in degrees.
+
+ -- Mapping Function:  sin (X)
+     Compute the sine for each element of X in radians.
+
+     *See also:* *note asin: doc-asin, *note sind: doc-sind, *note
+     sinh: doc-sinh.
+
+ -- Mapping Function:  cos (X)
+     Compute the cosine for each element of X in radians.
+
+     *See also:* *note acos: doc-acos, *note cosd: doc-cosd, *note
+     cosh: doc-cosh.
+
+ -- Mapping Function:  tan (Z)
+     Compute the tangent for each element of X in radians.
+
+     *See also:* *note atan: doc-atan, *note tand: doc-tand, *note
+     tanh: doc-tanh.
+
+ -- Mapping Function:  sec (X)
+     Compute the secant for each element of X in radians.
+
+     *See also:* *note asec: doc-asec, *note secd: doc-secd, *note
+     sech: doc-sech.
+
+ -- Mapping Function:  csc (X)
+     Compute the cosecant for each element of X in radians.
+
+     *See also:* *note acsc: doc-acsc, *note cscd: doc-cscd, *note
+     csch: doc-csch.
+
+ -- Mapping Function:  cot (X)
+     Compute the cotangent for each element of X in radians.
+
+     *See also:* *note acot: doc-acot, *note cotd: doc-cotd, *note
+     coth: doc-coth.
+
+ -- Mapping Function:  asin (X)
+     Compute the inverse sine in radians for each element of X.
+
+     *See also:* *note sin: doc-sin, *note asind: doc-asind.
+
+ -- Mapping Function:  acos (X)
+     Compute the inverse cosine in radians for each element of X.
+
+     *See also:* *note cos: doc-cos, *note acosd: doc-acosd.
+
+ -- Mapping Function:  atan (X)
+     Compute the inverse tangent in radians for each element of X.
+
+     *See also:* *note tan: doc-tan, *note atand: doc-atand.
+
+ -- Mapping Function:  asec (X)
+     Compute the inverse secant in radians for each element of X.
+
+     *See also:* *note sec: doc-sec, *note asecd: doc-asecd.
+
+ -- Mapping Function:  acsc (X)
+     Compute the inverse cosecant in radians for each element of X.
+
+     *See also:* *note csc: doc-csc, *note acscd: doc-acscd.
+
+ -- Mapping Function:  acot (X)
+     Compute the inverse cotangent in radians for each element of X.
+
+     *See also:* *note cot: doc-cot, *note acotd: doc-acotd.
+
+ -- Mapping Function:  sinh (X)
+     Compute the hyperbolic sine for each element of X.
+
+     *See also:* *note asinh: doc-asinh, *note cosh: doc-cosh, *note
+     tanh: doc-tanh.
+
+ -- Mapping Function:  cosh (X)
+     Compute the hyperbolic cosine for each element of X.
+
+     *See also:* *note acosh: doc-acosh, *note sinh: doc-sinh, *note
+     tanh: doc-tanh.
+
+ -- Mapping Function:  tanh (X)
+     Compute hyperbolic tangent for each element of X.
+
+     *See also:* *note atanh: doc-atanh, *note sinh: doc-sinh, *note
+     cosh: doc-cosh.
+
+ -- Mapping Function:  sech (X)
+     Compute the hyperbolic secant of each element of X.
+
+     *See also:* *note asech: doc-asech.
+
+ -- Mapping Function:  csch (X)
+     Compute the hyperbolic cosecant of each element of X.
+
+     *See also:* *note acsch: doc-acsch.
+
+ -- Mapping Function:  coth (X)
+     Compute the hyperbolic cotangent of each element of X.
+
+     *See also:* *note acoth: doc-acoth.
+
+ -- Mapping Function:  asinh (X)
+     Compute the inverse hyperbolic sine for each element of X.
+
+     *See also:* *note sinh: doc-sinh.
+
+ -- Mapping Function:  acosh (X)
+     Compute the inverse hyperbolic cosine for each element of X.
+
+     *See also:* *note cosh: doc-cosh.
+
+ -- Mapping Function:  atanh (X)
+     Compute the inverse hyperbolic tangent for each element of X.
+
+     *See also:* *note tanh: doc-tanh.
+
+ -- Mapping Function:  asech (X)
+     Compute the inverse hyperbolic secant of each element of X.
+
+     *See also:* *note sech: doc-sech.
+
+ -- Mapping Function:  acsch (X)
+     Compute the inverse hyperbolic cosecant of each element of X.
+
+     *See also:* *note csch: doc-csch.
+
+ -- Mapping Function:  acoth (X)
+     Compute the inverse hyperbolic cotangent of each element of X.
+
+     *See also:* *note coth: doc-coth.
+
+ -- Mapping Function:  atan2 (Y, X)
+     Compute atan (Y / X) for corresponding elements of Y and X.
+     Signal an error if Y and X do not match in size and orientation.
+
+   Octave provides the following trigonometric functions where angles
+are specified in degrees.  These functions produce true zeros at the
+appropriate intervals rather than the small roundoff error that occurs
+when using radians.  For example:
+     cosd (90)
+          => 0
+     cos (pi/2)
+          => 6.1230e-17
+
+ -- Function File:  sind (X)
+     Compute the sine for each element of X in degrees.  Returns zero
+     for elements where `X/180' is an integer.
+
+     *See also:* *note asind: doc-asind, *note sin: doc-sin.
+
+ -- Function File:  cosd (X)
+     Compute the cosine for each element of X in degrees.  Returns zero
+     for elements where `(X-90)/180' is an integer.
+
+     *See also:* *note acosd: doc-acosd, *note cos: doc-cos.
+
+ -- Function File:  tand (X)
+     Compute the tangent for each element of X in degrees.  Returns zero
+     for elements where `X/180' is an integer and `Inf' for elements
+     where `(X-90)/180' is an integer.
+
+     *See also:* *note atand: doc-atand, *note tan: doc-tan.
+
+ -- Function File:  secd (X)
+     Compute the secant for each element of X in degrees.
+
+     *See also:* *note asecd: doc-asecd, *note sec: doc-sec.
+
+ -- Function File:  cscd (X)
+     Compute the cosecant for each element of X in degrees.
+
+     *See also:* *note acscd: doc-acscd, *note csc: doc-csc.
+
+ -- Function File:  cotd (X)
+     Compute the cotangent for each element of X in degrees.
+
+     *See also:* *note acotd: doc-acotd, *note cot: doc-cot.
+
+ -- Function File:  asind (X)
+     Compute the inverse sine in degrees for each element of X.
+
+     *See also:* *note sind: doc-sind, *note asin: doc-asin.
+
+ -- Function File:  acosd (X)
+     Compute the inverse cosine in degrees for each element of X.
+
+     *See also:* *note cosd: doc-cosd, *note acos: doc-acos.
+
+ -- Function File:  atand (X)
+     Compute the inverse tangent in degrees for each element of X.
+
+     *See also:* *note tand: doc-tand, *note atan: doc-atan.
+
+ -- Function File:  asecd (X)
+     Compute the inverse secant in degrees for each element of X.
+
+     *See also:* *note secd: doc-secd, *note asec: doc-asec.
+
+ -- Function File:  acscd (X)
+     Compute the inverse cosecant in degrees for each element of X.
+
+     *See also:* *note cscd: doc-cscd, *note acsc: doc-acsc.
+
+ -- Function File:  acotd (X)
+     Compute the inverse cotangent in degrees for each element of X.
+
+     *See also:* *note cotd: doc-cotd, *note acot: doc-acot.
+
+
+File: octave.info,  Node: Sums and Products,  Next: Utility Functions,  Prev: Trigonometry,  Up: Arithmetic
+
+17.4 Sums and Products
+======================
+
+ -- Built-in Function:  sum (X)
+ -- Built-in Function:  sum (X, DIM)
+ -- Built-in Function:  sum (..., 'native')
+     Sum of elements along dimension DIM.  If DIM is omitted, it
+     defaults to 1 (column-wise sum).
+
+     As a special case, if X is a vector and DIM is omitted, return the
+     sum of the elements.
+
+     If the optional argument 'native' is given, then the sum is
+     performed in the same type as the original argument, rather than
+     in the default double type.  For example
+
+          sum ([true, true])
+            => 2
+          sum ([true, true], 'native')
+            => true
+
+     *See also:* *note cumsum: doc-cumsum, *note sumsq: doc-sumsq,
+     *note prod: doc-prod.
+
+ -- Built-in Function:  prod (X)
+ -- Built-in Function:  prod (X, DIM)
+     Product of elements along dimension DIM.  If DIM is omitted, it
+     defaults to 1 (column-wise products).
+
+     As a special case, if X is a vector and DIM is omitted, return the
+     product of the elements.
+
+     *See also:* *note cumprod: doc-cumprod, *note sum: doc-sum.
+
+ -- Built-in Function:  cumsum (X)
+ -- Built-in Function:  cumsum (X, DIM)
+ -- Built-in Function:  cumsum (..., 'native')
+     Cumulative sum of elements along dimension DIM.  If DIM is
+     omitted, it defaults to 1 (column-wise cumulative sums).
+
+     As a special case, if X is a vector and DIM is omitted, return the
+     cumulative sum of the elements as a vector with the same
+     orientation as X.
+
+     The "native" argument implies the summation is performed in native
+     type.   See `sum' for a complete description and example of the
+     use of "native".
+
+     *See also:* *note sum: doc-sum, *note cumprod: doc-cumprod.
+
+ -- Built-in Function:  cumprod (X)
+ -- Built-in Function:  cumprod (X, DIM)
+     Cumulative product of elements along dimension DIM.  If DIM is
+     omitted, it defaults to 1 (column-wise cumulative products).
+
+     As a special case, if X is a vector and DIM is omitted, return the
+     cumulative product of the elements as a vector with the same
+     orientation as X.
+
+     *See also:* *note prod: doc-prod, *note cumsum: doc-cumsum.
+
+ -- Built-in Function:  sumsq (X)
+ -- Built-in Function:  sumsq (X, DIM)
+     Sum of squares of elements along dimension DIM.  If DIM is
+     omitted, it defaults to 1 (column-wise sum of squares).
+
+     As a special case, if X is a vector and DIM is omitted, return the
+     sum of squares of the elements.
+
+     This function is conceptually equivalent to computing
+          sum (x .* conj (x), dim)
+     but it uses less memory and avoids calling `conj' if X is real.
+
+     *See also:* *note sum: doc-sum.
+
+ -- Function File:  accumarray (SUBS, VALS, SZ, FUNC, FILLVAL, ISSPARSE)
+ -- Function File:  accumarray (CSUBS, VALS, ...)
+     Create an array by accumulating the elements of a vector into the
+     positions defined by their subscripts.  The subscripts are defined
+     by the rows of the matrix SUBS and the values by VALS.  Each row
+     of SUBS corresponds to one of the values in VALS.
+
+     The size of the matrix will be determined by the subscripts
+     themselves.  However, if SZ is defined it determines the matrix
+     size.  The length of SZ must correspond to the number of columns
+     in SUBS.
+
+     The default action of `accumarray' is to sum the elements with the
+     same subscripts.  This behavior can be modified by defining the
+     FUNC function.  This should be a function or function handle that
+     accepts a column vector and returns a scalar.  The result of the
+     function should not depend on the order of the subscripts.
+
+     The elements of the returned array that have no subscripts
+     associated with them are set to zero.  Defining FILLVAL to some
+     other value allows these values to be defined.
+
+     By default `accumarray' returns a full matrix.  If ISSPARSE is
+     logically true, then a sparse matrix is returned instead.
+
+     An example of the use of `accumarray' is:
+
+          accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+          => ans(:,:,1) = [101, 0, 0; 0, 0, 0]
+             ans(:,:,2) = [0, 0, 0; 206, 0, 208]
+
+
+File: octave.info,  Node: Utility Functions,  Next: Special Functions,  Prev: Sums and Products,  Up: Arithmetic
+
+17.5 Utility Functions
+======================
+
+ -- Mapping Function:  ceil (X)
+     Return the smallest integer not less than X.  This is equivalent to
+     rounding towards positive infinity.  If X is complex, return `ceil
+     (real (X)) + ceil (imag (X)) * I'.
+          ceil ([-2.7, 2.7])
+             =>  -2   3
+
+     *See also:* *note floor: doc-floor, *note round: doc-round, *note
+     fix: doc-fix.
+
+ -- Function File:  cross (X, Y)
+ -- Function File:  cross (X, Y, DIM)
+     Compute the vector cross product of two 3-dimensional vectors X
+     and Y.
+
+          cross ([1,1,0], [0,1,1])
+               => [ 1; -1; 1 ]
+
+     If X and Y are matrices, the cross product is applied along the
+     first dimension with 3 elements.  The optional argument DIM forces
+     the cross product to be calculated along the specified dimension.
+
+     *See also:* *note dot: doc-dot.
+
+ -- Function File: D = del2 (M)
+ -- Function File: D = del2 (M, H)
+ -- Function File: D = del2 (M, DX, DY, ...)
+     Calculate the discrete Laplace operator.  For a 2-dimensional
+     matrix M this is defined as
+
+                1    / d^2            d^2         \
+          D  = --- * | ---  M(x,y) +  ---  M(x,y) |
+                4    \ dx^2           dy^2        /
+
+     For N-dimensional arrays the sum in parentheses is expanded to
+     include second derivatives over the additional higher dimensions.
+
+     The spacing between evaluation points may be defined by H, which
+     is a scalar defining the equidistant spacing in all dimensions.
+     Alternatively, the spacing in each dimension may be defined
+     separately by DX, DY, etc.  A scalar spacing argument defines
+     equidistant spacing, whereas a vector argument can be used to
+     specify variable spacing.  The length of the spacing vectors must
+     match the respective dimension of M.  The default spacing value is
+     1.
+
+     At least 3 data points are needed for each dimension.  Boundary
+     points are calculated from the linear extrapolation of interior
+     points.
+
+     *See also:* *note gradient: doc-gradient, *note diff: doc-diff.
+
+ -- Function File: P = factor (Q)
+ -- Function File: [P, N] = factor (Q)
+     Return prime factorization of Q.  That is, `prod (P) == Q' and
+     every element of P is a prime number.  If `Q == 1', returns 1.
+
+     With two output arguments, return the unique primes P and their
+     multiplicities.  That is, `prod (P .^ N) == Q'.
+
+     *See also:* *note gcd: doc-gcd, *note lcm: doc-lcm.
+
+ -- Function File:  factorial (N)
+     Return the factorial of N where N is a positive integer.  If N is
+     a scalar, this is equivalent to `prod (1:N)'.  For vector or
+     matrix arguments, return the factorial of each element in the
+     array.  For non-integers see the generalized factorial function
+     `gamma'.
+
+     *See also:* *note prod: doc-prod, *note gamma: doc-gamma.
+
+ -- Mapping Function:  fix (X)
+     Truncate fractional portion of X and return the integer portion.
+     This is equivalent to rounding towards zero.  If X is complex,
+     return `fix (real (X)) + fix (imag (X)) * I'.
+          fix ([-2.7, 2.7])
+             => -2   2
+
+     *See also:* *note ceil: doc-ceil, *note floor: doc-floor, *note
+     round: doc-round.
+
+ -- Mapping Function:  floor (X)
+     Return the largest integer not greater than X.  This is equivalent
+     to rounding towards negative infinity.  If X is complex, return
+     `floor (real (X)) + floor (imag (X)) * I'.
+          floor ([-2.7, 2.7])
+               => -3   2
+
+     *See also:* *note ceil: doc-ceil, *note round: doc-round, *note
+     fix: doc-fix.
+
+ -- Mapping Function:  fmod (X, Y)
+     Compute the floating point remainder of dividing X by Y using the
+     C library function `fmod'.  The result has the same sign as X.  If
+     Y is zero, the result is implementation-dependent.
+
+     *See also:* *note mod: doc-mod, *note rem: doc-rem.
+
+ -- Loadable Function: G = gcd (A)
+ -- Loadable Function: G = gcd (A1, A2, ...)
+ -- Loadable Function: [G, V1, ...] = gcd (A1, A2, ...)
+     Compute the greatest common divisor of the elements of A.  If more
+     than one argument is given all arguments must be the same size or
+     scalar.    In this case the greatest common divisor is calculated
+     for each element individually.  All elements must be integers.
+     For example,
+
+          gcd ([15, 20])
+              =>  5
+
+     and
+
+          gcd ([15, 9], [20, 18])
+              =>  5  9
+
+     Optional return arguments V1, etc., contain integer vectors such
+     that,
+
+          G = V1 .* A1 + V2 .* A2 + ...
+
+     For backward compatibility with previous versions of this
+     function, when all arguments are scalar, a single return argument
+     V1 containing all of the values of V1, ... is acceptable.
+
+     *See also:* *note lcm: doc-lcm, *note factor: doc-factor.
+
+ -- Function File: DX = gradient (M)
+ -- Function File: [DX, DY, DZ, ...] = gradient (M)
+ -- Function File: [...] = gradient (M, S)
+ -- Function File: [...] = gradient (M, X, Y, Z, ...)
+ -- Function File: [...] = gradient (F, X0)
+ -- Function File: [...] = gradient (F, X0, S)
+ -- Function File: [...] = gradient (F, X0, X, Y, ...)
+     Calculate the gradient of sampled data or a function.  If M is a
+     vector, calculate the one-dimensional gradient of M.  If M is a
+     matrix the gradient is calculated for each dimension.
+
+     `[DX, DY] = gradient (M)' calculates the one dimensional gradient
+     for X and Y direction if M is a matrix.  Additional return
+     arguments can be use for multi-dimensional matrices.
+
+     A constant spacing between two points can be provided by the S
+     parameter.  If S is a scalar, it is assumed to be the spacing for
+     all dimensions.  Otherwise, separate values of the spacing can be
+     supplied by the X, ... arguments.  Scalar values specify an
+     equidistant spacing.  Vector values for the X, ... arguments
+     specify the coordinate for that dimension.  The length must match
+     their respective dimension of M.
+
+     At boundary points a linear extrapolation is applied.  Interior
+     points are calculated with the first approximation of the
+     numerical gradient
+
+          y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).
+
+     If the first argument F is a function handle, the gradient of the
+     function at the points in X0 is approximated using central
+     difference.  For example, `gradient (@cos, 0)' approximates the
+     gradient of the cosine function in the point x0 = 0.  As with
+     sampled data, the spacing values between the points from which the
+     gradient is estimated can be set via the S or DX, DY, ...
+     arguments.  By default a spacing of 1 is used.
+
+     *See also:* *note diff: doc-diff, *note del2: doc-del2.
+
+ -- Built-in Function:  hypot (X, Y)
+     Compute the element-by-element square root of the sum of the
+     squares of X and Y.  This is equivalent to `sqrt (X.^2 + Y.^2)',
+     but calculated in a manner that avoids overflows for large values
+     of X or Y.
+
+ -- Mapping Function:  lcm (X)
+ -- Mapping Function:  lcm (X, ...)
+     Compute the least common multiple of the elements of X, or of the
+     list of all arguments.  For example,
+
+          lcm (a1, ..., ak)
+
+     is the same as
+
+          lcm ([a1, ..., ak]).
+
+     All elements must be the same size or scalar.
+
+     *See also:* *note factor: doc-factor, *note gcd: doc-gcd.
+
+ -- Function File:  list_primes (N)
+     List the first N primes.  If N is unspecified, the first 25 primes
+     are listed.
+
+     The algorithm used is from page 218 of the TeXbook.
+
+     *See also:* *note primes: doc-primes, *note isprime: doc-isprime.
+
+ -- Loadable Function:  max (X)
+ -- Loadable Function:  max (X, Y)
+ -- Loadable Function:  max (X, Y, DIM)
+ -- Loadable Function: [W, IW] = max (X)
+     For a vector argument, return the maximum value.  For a matrix
+     argument, return the maximum value from each column, as a row
+     vector, or over the dimension DIM if defined.  For two matrices
+     (or a matrix and scalar), return the pair-wise maximum.  Thus,
+
+          max (max (X))
+
+     returns the largest element of the matrix X, and
+
+          max (2:5, pi)
+              =>  3.1416  3.1416  4.0000  5.0000
+     compares each element of the range `2:5' with `pi', and returns a
+     row vector of the maximum values.
+
+     For complex arguments, the magnitude of the elements are used for
+     comparison.
+
+     If called with one input and two output arguments, `max' also
+     returns the first index of the maximum value(s).  Thus,
+
+          [x, ix] = max ([1, 3, 5, 2, 5])
+              =>  x = 5
+                  ix = 3
+
+     *See also:* *note min: doc-min, *note cummax: doc-cummax, *note
+     cummin: doc-cummin.
+
+ -- Loadable Function:  min (X)
+ -- Loadable Function:  min (X, Y)
+ -- Loadable Function:  min (X, Y, DIM)
+ -- Loadable Function: [W, IW] = min (X)
+     For a vector argument, return the minimum value.  For a matrix
+     argument, return the minimum value from each column, as a row
+     vector, or over the dimension DIM if defined.  For two matrices
+     (or a matrix and scalar), return the pair-wise minimum.  Thus,
+
+          min (min (X))
+
+     returns the smallest element of X, and
+
+          min (2:5, pi)
+              =>  2.0000  3.0000  3.1416  3.1416
+     compares each element of the range `2:5' with `pi', and returns a
+     row vector of the minimum values.
+
+     For complex arguments, the magnitude of the elements are used for
+     comparison.
+
+     If called with one input and two output arguments, `min' also
+     returns the first index of the minimum value(s).  Thus,
+
+          [x, ix] = min ([1, 3, 0, 2, 0])
+              =>  x = 0
+                  ix = 3
+
+     *See also:* *note max: doc-max, *note cummin: doc-cummin, *note
+     cummax: doc-cummax.
+
+ -- Loadable Function:  cummax (X)
+ -- Loadable Function:  cummax (X, DIM)
+ -- Loadable Function: [W, IW] = cummax (X)
+     Return the cumulative maximum values along dimension DIM.  If DIM
+     is unspecified it defaults to column-wise operation.  For example,
+
+          cummax ([1 3 2 6 4 5])
+              =>  1  3  3  6  6  6
+
+     The call
+          [w, iw] = cummax (x, dim)
+
+     is equivalent to the following code:
+          w = iw = zeros (size (x));
+          idxw = idxx = repmat ({':'}, 1, ndims (x));
+          for i = 1:size (x, dim)
+            idxw{dim} = i; idxx{dim} = 1:i;
+            [w(idxw{:}), iw(idxw{:})] = max(x(idxx{:}), [], dim);
+          endfor
+
+     but computed in a much faster manner.
+
+     *See also:* *note cummin: doc-cummin, *note max: doc-max, *note
+     min: doc-min.
+
+ -- Loadable Function:  cummin (X)
+ -- Loadable Function:  cummin (X, DIM)
+ -- Loadable Function: [W, IW] = cummin (X)
+     Return the cumulative minimum values along dimension DIM.  If DIM
+     is unspecified it defaults to column-wise operation.  For example,
+
+          cummin ([5 4 6 2 3 1])
+              =>  5  4  4  2  2  1
+
+     The call
+            [w, iw] = cummin (x, dim)
+
+     is equivalent to the following code:
+          w = iw = zeros (size (x));
+          idxw = idxx = repmat ({':'}, 1, ndims (x));
+          for i = 1:size (x, dim)
+            idxw{dim} = i; idxx{dim} = 1:i;
+            [w(idxw{:}), iw(idxw{:})] = min(x(idxx{:}), [], dim);
+          endfor
+
+     but computed in a much faster manner.
+
+     *See also:* *note cummax: doc-cummax, *note min: doc-min, *note
+     max: doc-max.
+
+ -- Mapping Function:  mod (X, Y)
+     Compute the modulo of X and Y.  Conceptually this is given by
+
+          x - y .* floor (x ./ y)
+
+     and is written such that the correct modulus is returned for
+     integer types.  This function handles negative values correctly.
+     That is, `mod (-1, 3)' is 2, not -1, as `rem (-1, 3)' returns.
+     `mod (X, 0)' returns X.
+
+     An error results if the dimensions of the arguments do not agree,
+     or if either of the arguments is complex.
+
+     *See also:* *note rem: doc-rem, *note fmod: doc-fmod.
+
+ -- Function File:  primes (N)
+     Return all primes up to N.
+
+     The algorithm used is the Sieve of Erastothenes.
+
+     Note that if you need a specific number of primes you can use the
+     fact the distance from one prime to the next is, on average,
+     proportional to the logarithm of the prime.  Integrating, one finds
+     that there are about k primes less than k*log(5*k).
+
+     *See also:* *note list_primes: doc-list_primes, *note isprime:
+     doc-isprime.
+
+ -- Mapping Function:  rem (X, Y)
+     Return the remainder of the division `X / Y', computed using the
+     expression
+
+          x - y .* fix (x ./ y)
+
+     An error message is printed if the dimensions of the arguments do
+     not agree, or if either of the arguments is complex.
+
+     *See also:* *note mod: doc-mod, *note fmod: doc-fmod.
+
+ -- Mapping Function:  round (X)
+     Return the integer nearest to X.  If X is complex, return `round
+     (real (X)) + round (imag (X)) * I'.
+          round ([-2.7, 2.7])
+               => -3   3
+
+     *See also:* *note ceil: doc-ceil, *note floor: doc-floor, *note
+     fix: doc-fix.
+
+ -- Mapping Function:  roundb (X)
+     Return the integer nearest to X.  If there are two nearest
+     integers, return the even one (banker's rounding).  If X is
+     complex, return `roundb (real (X)) + roundb (imag (X)) * I'.
+
+     *See also:* *note round: doc-round.
+
+ -- Mapping Function:  sign (X)
+     Compute the "signum" function, which is defined as
+
+                     -1, x < 0;
+          sign (x) =  0, x = 0;
+                      1, x > 0.
+
+     For complex arguments, `sign' returns `x ./ abs (X)'.
+
+
+File: octave.info,  Node: Special Functions,  Next: Coordinate Transformations,  Prev: Utility Functions,  Up: Arithmetic
+
+17.6 Special Functions
+======================
+
+ -- Loadable Function: [A, IERR] = airy (K, Z, OPT)
+     Compute Airy functions of the first and second kind, and their
+     derivatives.
+
+           K   Function   Scale factor (if 'opt' is supplied)
+          ---  --------   ---------------------------------------
+           0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))
+           1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))
+           2   Bi (Z)     exp (-abs (real ((2/3) * Z *sqrt (Z))))
+           3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z *sqrt (Z))))
+
+     The function call `airy (Z)' is equivalent to `airy (0, Z)'.
+
+     The result is the same size as Z.
+
+     If requested, IERR contains the following status information and
+     is the same size as the result.
+
+       0. Normal return.
+
+       1. Input error, return `NaN'.
+
+       2. Overflow, return `Inf'.
+
+       3. Loss of significance by argument reduction results in less
+          than half  of machine accuracy.
+
+       4. Complete loss of significance by argument reduction, return
+          `NaN'.
+
+       5. Error--no computation, algorithm termination condition not
+          met, return `NaN'.
+
+ -- Loadable Function: [J, IERR] = besselj (ALPHA, X, OPT)
+ -- Loadable Function: [Y, IERR] = bessely (ALPHA, X, OPT)
+ -- Loadable Function: [I, IERR] = besseli (ALPHA, X, OPT)
+ -- Loadable Function: [K, IERR] = besselk (ALPHA, X, OPT)
+ -- Loadable Function: [H, IERR] = besselh (ALPHA, K, X, OPT)
+     Compute Bessel or Hankel functions of various kinds:
+
+    `besselj'
+          Bessel functions of the first kind.  If the argument OPT is
+          supplied, the result is multiplied by `exp(-abs(imag(x)))'.
+
+    `bessely'
+          Bessel functions of the second kind.  If the argument OPT is
+          supplied, the result is multiplied by `exp(-abs(imag(x)))'.
+
+    `besseli'
+          Modified Bessel functions of the first kind.  If the argument
+          OPT is supplied, the result is multiplied by
+          `exp(-abs(real(x)))'.
+
+    `besselk'
+          Modified Bessel functions of the second kind.  If the
+          argument OPT is supplied, the result is multiplied by
+          `exp(x)'.
+
+    `besselh'
+          Compute Hankel functions of the first (K = 1) or second (K =
+          2) kind.  If the argument OPT is supplied, the result is
+          multiplied by `exp (-I*X)' for K = 1 or `exp (I*X)' for K = 2.
+
+     If ALPHA is a scalar, the result is the same size as X.  If X is a
+     scalar, the result is the same size as ALPHA.  If ALPHA is a row
+     vector and X is a column vector, the result is a matrix with
+     `length (X)' rows and `length (ALPHA)' columns.  Otherwise, ALPHA
+     and X must conform and the result will be the same size.
+
+     The value of ALPHA must be real.  The value of X may be complex.
+
+     If requested, IERR contains the following status information and
+     is the same size as the result.
+
+       0. Normal return.
+
+       1. Input error, return `NaN'.
+
+       2. Overflow, return `Inf'.
+
+       3. Loss of significance by argument reduction results in less
+          than half of machine accuracy.
+
+       4. Complete loss of significance by argument reduction, return
+          `NaN'.
+
+       5. Error--no computation, algorithm termination condition not
+          met, return `NaN'.
+
+ -- Mapping Function:  beta (A, B)
+     For real inputs, return the Beta function,
+
+          beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
+
+ -- Mapping Function:  betainc (X, A, B)
+     Return the incomplete Beta function,
+
+                                                x
+                                               /
+          betainc (x, a, b) = beta (a, b)^(-1) | t^(a-1) (1-t)^(b-1) dt.
+                                               /
+                                            t=0
+
+     If x has more than one component, both A and B must be scalars.
+     If X is a scalar, A and B must be of compatible dimensions.
+
+ -- Mapping Function:  betaln (A, B)
+     Return the log of the Beta function,
+
+          betaln (a, b) = gammaln (a) + gammaln (b) - gammaln (a + b)
+
+     *See also:* *note beta: doc-beta, *note betainc: doc-betainc,
+     *note gammaln: doc-gammaln.
+
+ -- Mapping Function:  bincoeff (N, K)
+     Return the binomial coefficient of N and K, defined as
+
+           /   \
+           | n |    n (n-1) (n-2) ... (n-k+1)
+           |   |  = -------------------------
+           | k |               k!
+           \   /
+
+     For example,
+
+          bincoeff (5, 2)
+               => 10
+
+     In most cases, the `nchoosek' function is faster for small scalar
+     integer arguments.  It also warns about loss of precision for big
+     arguments.
+
+     *See also:* *note nchoosek: doc-nchoosek.
+
+ -- Function File:  commutation_matrix (M, N)
+     Return the commutation matrix  K(m,n)  which is the unique M*N by
+     M*N  matrix such that K(m,n) * vec(A) = vec(A')  for all m by n
+     matrices A.
+
+     If only one argument M is given, K(m,m)  is returned.
+
+     See Magnus and Neudecker (1988), Matrix differential calculus with
+     applications in statistics and econometrics.
+
+ -- Function File:  duplication_matrix (N)
+     Return the duplication matrix Dn  which is the unique n^2 by
+     n*(n+1)/2  matrix such that Dn vech (A) = vec (A)  for all
+     symmetric n by n  matrices A.
+
+     See Magnus and Neudecker (1988), Matrix differential calculus with
+     applications in statistics and econometrics.
+
+ -- Mapping Function:  erf (Z)
+     Computes the error function,
+
+                                   z
+                                  /
+          erf (z) = (2/sqrt (pi)) | e^(-t^2) dt
+                                  /
+                               t=0
+
+     *See also:* *note erfc: doc-erfc, *note erfinv: doc-erfinv.
+
+ -- Mapping Function:  erfc (Z)
+     Computes the complementary error function, `1 - erf (Z)'.
+
+     *See also:* *note erf: doc-erf, *note erfinv: doc-erfinv.
+
+ -- Mapping Function:  erfinv (Z)
+     Computes the inverse of the error function.
+
+     *See also:* *note erf: doc-erf, *note erfc: doc-erfc.
+
+ -- Mapping Function:  gamma (Z)
+     Computes the Gamma function,
+
+                      infinity
+                      /
+          gamma (z) = | t^(z-1) exp (-t) dt.
+                      /
+                   t=0
+
+     *See also:* *note gammainc: doc-gammainc, *note lgamma: doc-lgamma.
+
+ -- Mapping Function:  gammainc (X, A)
+     Compute the normalized incomplete gamma function,
+
+                                          x
+                                1        /
+          gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
+                            gamma (a)    /
+                                      t=0
+
+     with the limiting value of 1 as X approaches infinity.  The
+     standard notation is P(a,x), e.g., Abramowitz and Stegun (6.5.1).
+
+     If A is scalar, then `gammainc (X, A)' is returned for each
+     element of X and vice versa.
+
+     If neither X nor A is scalar, the sizes of X and A must agree, and
+     GAMMAINC is applied element-by-element.
+
+     *See also:* *note gamma: doc-gamma, *note lgamma: doc-lgamma.
+
+ -- Function File: L = legendre (N, X)
+ -- Function File: L = legendre (N, X, NORMALIZATION)
+     Compute the Legendre function of degree N and order M = 0 ... N.
+     The optional argument, NORMALIZATION, may be one of `"unnorm"',
+     `"sch"', or `"norm"'.  The default is `"unnorm"'.  The value of N
+     must be a non-negative scalar integer.
+
+     If the optional argument NORMALIZATION is missing or is
+     `"unnorm"', compute the Legendre function of degree N and order M
+     and return all values for M = 0 ... N.  The return value has one
+     dimension more than X.
+
+     The Legendre Function of degree N and order M:
+
+           m        m       2  m/2   d^m
+          P(x) = (-1) * (1-x  )    * ----  P (x)
+           n                         dx^m   n
+
+     with Legendre polynomial of degree N:
+
+                    1     d^n   2    n
+          P (x) = ------ [----(x - 1)  ]
+           n      2^n n!  dx^n
+
+     `legendre (3, [-1.0, -0.9, -0.8])' returns the matrix:
+
+           x  |   -1.0   |   -0.9   |  -0.8
+          ------------------------------------
+          m=0 | -1.00000 | -0.47250 | -0.08000
+          m=1 |  0.00000 | -1.99420 | -1.98000
+          m=2 |  0.00000 | -2.56500 | -4.32000
+          m=3 |  0.00000 | -1.24229 | -3.24000
+
+     If the optional argument `normalization' is `"sch"', compute the
+     Schmidt semi-normalized associated Legendre function.  The Schmidt
+     semi-normalized associated Legendre function is related to the
+     unnormalized Legendre functions by the following:
+
+     For Legendre functions of degree n and order 0:
+
+            0       0
+          SP (x) = P (x)
+            n       n
+
+     For Legendre functions of degree n and order m:
+
+            m       m          m    2(n-m)! 0.5
+          SP (x) = P (x) * (-1)  * [-------]
+            n       n               (n+m)!
+
+     If the optional argument NORMALIZATION is `"norm"', compute the
+     fully normalized associated Legendre function.  The fully
+     normalized associated Legendre function is related to the
+     unnormalized Legendre functions by the following:
+
+     For Legendre functions of degree N and order M
+
+            m       m          m    (n+0.5)(n-m)! 0.5
+          NP (x) = P (x) * (-1)  * [-------------]
+            n       n                   (n+m)!
+
+ -- Mapping Function:  lgamma (X)
+ -- Mapping Function:  gammaln (X)
+     Return the natural logarithm of the gamma function of X.
+
+     *See also:* *note gamma: doc-gamma, *note gammainc: doc-gammainc.
+
+
+File: octave.info,  Node: Coordinate Transformations,  Next: Mathematical Constants,  Prev: Special Functions,  Up: Arithmetic
+
+17.7 Coordinate Transformations
+===============================
+
+ -- Function File: [THETA, R] = cart2pol (X, Y)
+ -- Function File: [THETA, R, Z] = cart2pol (X, Y, Z)
+     Transform Cartesian to polar or cylindrical coordinates.  X, Y
+     (and Z) must be the same shape, or scalar.  THETA describes the
+     angle relative to the positive x-axis.  R is the distance to the
+     z-axis (0, 0, z).
+
+     *See also:* *note pol2cart: doc-pol2cart, *note cart2sph:
+     doc-cart2sph, *note sph2cart: doc-sph2cart.
+
+ -- Function File: [X, Y] = pol2cart (THETA, R)
+ -- Function File: [X, Y, Z] = pol2cart (THETA, R, Z)
+     Transform polar or cylindrical to Cartesian coordinates.  THETA, R
+     (and Z) must be the same shape, or scalar.  THETA describes the
+     angle relative to the positive x-axis.  R is the distance to the
+     z-axis (0, 0, z).
+
+     *See also:* *note cart2pol: doc-cart2pol, *note cart2sph:
+     doc-cart2sph, *note sph2cart: doc-sph2cart.
+
+ -- Function File: [THETA, PHI, R] = cart2sph (X, Y, Z)
+     Transform Cartesian to spherical coordinates.  X, Y and Z must be
+     the same shape, or scalar.  THETA describes the angle relative to
+     the positive x-axis.  PHI is the angle relative to the xy-plane.
+     R is the distance to the origin (0, 0, 0).
+
+     *See also:* *note pol2cart: doc-pol2cart, *note cart2pol:
+     doc-cart2pol, *note sph2cart: doc-sph2cart.
+
+ -- Function File: [X, Y, Z] = sph2cart (THETA, PHI, R)
+     Transform spherical to Cartesian coordinates.  X, Y and Z must be
+     the same shape, or scalar.  THETA describes the angle relative to
+     the positive x-axis.  PHI is the angle relative to the xy-plane.
+     R is the distance to the origin (0, 0, 0).
+
+     *See also:* *note pol2cart: doc-pol2cart, *note cart2pol:
+     doc-cart2pol, *note cart2sph: doc-cart2sph.
+
+
+File: octave.info,  Node: Mathematical Constants,  Prev: Coordinate Transformations,  Up: Arithmetic
+
+17.8 Mathematical Constants
+===========================
+
+ -- Built-in Function:  e
+ -- Built-in Function:  e (N)
+ -- Built-in Function:  e (N, M)
+ -- Built-in Function:  e (N, M, K, ...)
+ -- Built-in Function:  e (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are
+     all equal to the base of natural logarithms.  The constant `e'
+     satisfies the equation `log' (e) = 1.
+
+     When called with no arguments, return a scalar with the value e.
+     When called with a single argument, return a square matrix with
+     the dimension specified.  When called with more than one scalar
+     argument the first two arguments are taken as the number of rows
+     and columns and any further arguments specify additional matrix
+     dimensions.  The optional argument CLASS specifies the return type
+     and may be either "double" or "single".
+
+ -- Built-in Function:  pi
+ -- Built-in Function:  pi (N)
+ -- Built-in Function:  pi (N, M)
+ -- Built-in Function:  pi (N, M, K, ...)
+ -- Built-in Function:  pi (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are
+     all equal to the ratio of the circumference of a circle to its
+     diameter.  Internally, `pi' is computed as `4.0 * atan (1.0)'.
+
+     When called with no arguments, return a scalar with the value of
+     pi.  When called with a single argument, return a square matrix
+     with the dimension specified.  When called with more than one
+     scalar argument the first two arguments are taken as the number of
+     rows and columns and any further arguments specify additional
+     matrix dimensions.  The optional argument CLASS specifies the
+     return type and may be either "double" or "single".
+
+ -- Built-in Function:  I
+ -- Built-in Function:  I (N)
+ -- Built-in Function:  I (N, M)
+ -- Built-in Function:  I (N, M, K, ...)
+ -- Built-in Function:  I (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are
+     all equal to the pure imaginary unit, defined as `sqrt (-1)'.   I,
+     and its equivalents i, J, and j, are functions so any of the names
+     may be reused for other purposes (such as i for a counter
+     variable).
+
+     When called with no arguments, return a scalar with the value i.
+     When called with a single argument, return a square matrix with
+     the dimension specified.  When called with more than one scalar
+     argument the first two arguments are taken as the number of rows
+     and columns and any further arguments specify additional matrix
+     dimensions.  The optional argument CLASS specifies the return type
+     and may be either "double" or "single".
+
+ -- Built-in Function:  Inf
+ -- Built-in Function:  Inf (N)
+ -- Built-in Function:  Inf (N, M)
+ -- Built-in Function:  Inf (N, M, K, ...)
+ -- Built-in Function:  Inf (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are
+     all equal to the IEEE representation for positive infinity.
+
+     Infinity is produced when results are too large to be represented
+     using the the IEEE floating point format for numbers.  Two common
+     examples which produce infinity are division by zero and overflow.
+          [1/0 e^800]
+          =>
+          Inf   Inf
+
+     When called with no arguments, return a scalar with the value
+     `Inf'.  When called with a single argument, return a square matrix
+     with the dimension specified.  When called with more than one
+     scalar argument the first two arguments are taken as the number of
+     rows and columns and any further arguments specify additional
+     matrix dimensions.  The optional argument CLASS specifies the
+     return type and may be either "double" or "single".
+
+     *See also:* *note isinf: doc-isinf.
+
+ -- Built-in Function:  NaN
+ -- Built-in Function:  NaN (N)
+ -- Built-in Function:  NaN (N, M)
+ -- Built-in Function:  NaN (N, M, K, ...)
+ -- Built-in Function:  NaN (..., CLASS)
+     Return a scalar, matrix, or N-dimensional array whose elements are
+     all equal to the IEEE symbol NaN (Not a Number).  NaN is the
+     result of operations which do not produce a well defined numerical
+     result.  Common operations which produce a NaN are arithmetic with
+     infinity (Inf - Inf), zero divided by zero (0/0), and any
+     operation involving another NaN value (5 + NaN).
+
+     Note that NaN always compares not equal to NaN (NaN != NaN).  This
+     behavior is specified by the IEEE standard for floating point
+     arithmetic.  To find NaN values, use the `isnan' function.
+
+     When called with no arguments, return a scalar with the value
+     `NaN'.  When called with a single argument, return a square matrix
+     with the dimension specified.  When called with more than one
+     scalar argument the first two arguments are taken as the number of
+     rows and columns and any further arguments specify additional
+     matrix dimensions.  The optional argument CLASS specifies the
+     return type and may be either "double" or "single".
+
+     *See also:* *note isnan: doc-isnan.
+
+ -- Built-in Function:  eps
+ -- Built-in Function:  eps (X)
+ -- Built-in Function:  eps (N, M)
+ -- Built-in Function:  eps (N, M, K, ...)
+ -- Built-in Function:  eps (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are
+     all eps, the machine precision.  More precisely, `eps' is the
+     relative spacing between any two adjacent numbers in the machine's
+     floating point system.  This number is obviously system dependent.
+     On machines that support IEEE floating point arithmetic, `eps' is
+     approximately 2.2204e-16 for double precision and 1.1921e-07 for
+     single precision.
+
+     When called with no arguments, return a scalar with the value
+     `eps(1.0)'.  Given a single argument X, return the distance
+     between X and the next largest value.  When called with more than
+     one argument the first two arguments are taken as the number of
+     rows and columns and any further arguments specify additional
+     matrix dimensions.  The optional argument CLASS specifies the
+     return type and may be either "double" or "single".
+
+ -- Built-in Function:  realmax
+ -- Built-in Function:  realmax (N)
+ -- Built-in Function:  realmax (N, M)
+ -- Built-in Function:  realmax (N, M, K, ...)
+ -- Built-in Function:  realmax (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are
+     all equal to the largest floating point number that is
+     representable.  The actual value is system dependent.  On machines
+     that support IEEE floating point arithmetic, `realmax' is
+     approximately 1.7977e+308 for double precision and 3.4028e+38 for
+     single precision.
+
+     When called with no arguments, return a scalar with the value
+     `realmax("double")'.  When called with a single argument, return a
+     square matrix with the dimension specified.  When called with more
+     than one scalar argument the first two arguments are taken as the
+     number of rows and columns and any further arguments specify
+     additional matrix dimensions.  The optional argument CLASS
+     specifies the return type and may be either "double" or "single".
+
+     *See also:* *note realmin: doc-realmin, *note intmax: doc-intmax,
+     *note bitmax: doc-bitmax.
+
+ -- Built-in Function:  realmin
+ -- Built-in Function:  realmin (N)
+ -- Built-in Function:  realmin (N, M)
+ -- Built-in Function:  realmin (N, M, K, ...)
+ -- Built-in Function:  realmin (..., CLASS)
+     Return a scalar, matrix or N-dimensional array whose elements are
+     all equal to the smallest normalized floating point number that is
+     representable.  The actual value is system dependent.  On machines
+     that support IEEE floating point arithmetic, `realmin' is
+     approximately 2.2251e-308 for double precision and 1.1755e-38 for
+     single precision.
+
+     When called with no arguments, return a scalar with the value
+     `realmin("double")'.  When called with a single argument, return a
+     square matrix with the dimension specified.  When called with more
+     than one scalar argument the first two arguments are taken as the
+     number of rows and columns and any further arguments specify
+     additional matrix dimensions.  The optional argument CLASS
+     specifies the return type and may be either "double" or "single".
+
+     *See also:* *note realmax: doc-realmax, *note intmin: doc-intmin.
+
+
+File: octave.info,  Node: Linear Algebra,  Next: Nonlinear Equations,  Prev: Arithmetic,  Up: Top
+
+18 Linear Algebra
+*****************
+
+This chapter documents the linear algebra functions of Octave.
+Reference material for many of these functions may be found in Golub
+and Van Loan, `Matrix Computations, 2nd Ed.', Johns Hopkins, 1989, and
+in the `LAPACK Users' Guide', SIAM, 1992.
+
+* Menu:
+
+* Techniques used for Linear Algebra::
+* Basic Matrix Functions::
+* Matrix Factorizations::
+* Functions of a Matrix::
+* Specialized Solvers::
+
+
+File: octave.info,  Node: Techniques used for Linear Algebra,  Next: Basic Matrix Functions,  Up: Linear Algebra
+
+18.1 Techniques used for Linear Algebra
+=======================================
+
+Octave includes a polymorphic solver, that selects an appropriate
+matrix factorization depending on the properties of the matrix itself.
+Generally, the cost of determining the matrix type is small relative to
+the cost of factorizing the matrix itself, but in any case the matrix
+type is cached once it is calculated, so that it is not re-determined
+each time it is used in a linear equation.
+
+   The selection tree for how the linear equation is solve or a matrix
+inverse is form is given by
+
+  1. If the matrix is upper or lower triangular sparse a forward or
+     backward substitution using the LAPACK xTRTRS function, and goto 4.
+
+  2. If the matrix is square, hermitian with a real positive diagonal,
+     attempt Cholesky factorization using the LAPACK xPOTRF function.
+
+  3. If the Cholesky factorization failed or the matrix is not
+     hermitian with a real positive diagonal, and the matrix is square,
+     factorize using the LAPACK xGETRF function.
+
+  4. If the matrix is not square, or any of the previous solvers flags
+     a singular or near singular matrix, find a least squares solution
+     using the LAPACK xGELSD function.
+
+   The user can force the type of the matrix with the `matrix_type'
+function.  This overcomes the cost of discovering the type of the
+matrix.  However, it should be noted that identifying the type of the
+matrix incorrectly will lead to unpredictable results, and so
+`matrix_type' should be used with care.
+
+   It should be noted that the test for whether a matrix is a candidate
+for Cholesky factorization, performed above and by the `matrix_type'
+function, does not give a certainty that the matrix is Hermitian.
+However, the attempt to factorize the matrix will quickly flag a
+non-Hermitian matrix.
+
+
+File: octave.info,  Node: Basic Matrix Functions,  Next: Matrix Factorizations,  Prev: Techniques used for Linear Algebra,  Up: Linear Algebra
+
+18.2 Basic Matrix Functions
+===========================
+
+ -- Loadable Function: AA = balance (A, OPT)
+ -- Loadable Function: [DD, AA] = balance (A, OPT)
+ -- Loadable Function: [D, P, AA] = balance (A, OPT)
+ -- Loadable Function: [CC, DD, AA, BB] = balance (A, B, OPT)
+     Compute `aa = dd \ a * dd' in which `aa' is a matrix whose row and
+     column norms are roughly equal in magnitude, and `dd' = `p * d',
+     in which `p' is a permutation matrix and `d' is a diagonal matrix
+     of powers of two.  This allows the equilibration to be computed
+     without roundoff.  Results of eigenvalue calculation are typically
+     improved by balancing first.
+
+     If two output values are requested, `balance' returns the diagonal
+     `d' and the permutation `p' separately as vectors.  In this case,
+     `dd = eye(n)(:,p) * diag (d)', where `n' is the matrix size.
+
+     If four output values are requested, compute `aa = cc*a*dd' and
+     `bb = cc*b*dd)', in which `aa' and `bb' have non-zero elements of
+     approximately the same magnitude and `cc' and `dd' are permuted
+     diagonal matrices as in `dd' for the algebraic eigenvalue problem.
+
+     The eigenvalue balancing option `opt' may be one of:
+
+    `"noperm"', `"S"'
+          Scale only; do not permute.
+
+    `"noscal"', `"P"'
+          Permute only; do not scale.
+
+     Algebraic eigenvalue balancing uses standard LAPACK routines.
+
+     Generalized eigenvalue problem balancing uses Ward's algorithm
+     (SIAM Journal on Scientific and Statistical Computing, 1981).
+
+ -- Function File:  cond (A,P)
+     Compute the P-norm condition number of a matrix.  `cond (A)' is
+     defined as `norm (A, P) * norm (inv (A), P)'.  By default `P=2' is
+     used which implies a (relatively slow) singular value
+     decomposition.  Other possible selections are `P= 1, Inf, inf,
+     'Inf', 'fro'' which are generally faster.
+
+     *See also:* *note condest: doc-condest, *note rcond: doc-rcond,
+     *note norm: doc-norm, *note svd: doc-svd.
+
+ -- Loadable Function: [D, RCOND] = det (A)
+     Compute the determinant of A using LAPACK for full and UMFPACK for
+     sparse matrices.  Return an estimate of the reciprocal condition
+     number if requested.
+
+ -- Function File:  dmult (A, B)
+     This function has been deprecated.  Use the direct syntax
+     `diag(A)*B' which is more readable and now also more efficient.
+
+ -- Function File:  dot (X, Y, DIM)
+     Computes the dot product of two vectors.  If X and Y are matrices,
+     calculate the dot-product along the first non-singleton dimension.
+     If the optional argument DIM is given, calculate the dot-product
+     along this dimension.
+
+ -- Loadable Function: LAMBDA = eig (A)
+ -- Loadable Function: LAMBDA = eig (A, B)
+ -- Loadable Function: [V, LAMBDA] = eig (A)
+ -- Loadable Function: [V, LAMBDA] = eig (A, B)
+     The eigenvalues (and eigenvectors) of a matrix are computed in a
+     several step process which begins with a Hessenberg decomposition,
+     followed by a Schur decomposition, from which the eigenvalues are
+     apparent.  The eigenvectors, when desired, are computed by further
+     manipulations of the Schur decomposition.
+
+     The eigenvalues returned by `eig' are not ordered.
+
+     *See also:* *note eigs: doc-eigs.
+
+ -- Loadable Function: G = givens (X, Y)
+ -- Loadable Function: [C, S] = givens (X, Y)
+     Return a 2 by 2 orthogonal matrix `G = [C S; -S' C]' such that `G
+     [X; Y] = [*; 0]' with X and Y scalars.
+
+     For example,
+
+          givens (1, 1)
+               =>   0.70711   0.70711
+                   -0.70711   0.70711
+
+ -- Function File: [G, Y] = planerot (X)
+     Given a two-element column vector, returns the 2 by 2 orthogonal
+     matrix G such that `Y = G * X' and `Y(2) = 0'.
+
+     *See also:* *note givens: doc-givens.
+
+ -- Loadable Function: [X, RCOND] = inv (A)
+ -- Loadable Function: [X, RCOND] = inverse (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.
+
+     If called with a sparse matrix, then in general X will be a full
+     matrix, and so if possible forming the inverse of a sparse matrix
+     should be avoided.  It is significantly more accurate and faster
+     to do `Y = A \ B', rather than `Y = inv (A) * B'.
+
+ -- Loadable Function: TYPE = matrix_type (A)
+ -- Loadable Function: A = matrix_type (A, TYPE)
+ -- Loadable Function: A = matrix_type (A, 'upper', PERM)
+ -- Loadable Function: A = matrix_type (A, 'lower', PERM)
+ -- Loadable Function: A = matrix_type (A, 'banded', NL, NU)
+     Identify the matrix type or mark a matrix as a particular type.
+     This allows rapid for solutions of linear equations involving A to
+     be performed.  Called with a single argument, `matrix_type'
+     returns the type of the matrix and caches it for future use.
+     Called with more than one argument, `matrix_type' allows the type
+     of the matrix to be defined.
+
+     The possible matrix types depend on whether the matrix is full or
+     sparse, and can be one of the following
+
+    'unknown'
+          Remove any previously cached matrix type, and mark type as
+          unknown
+
+    'full'
+          Mark the matrix as full.
+
+    'positive definite'
+          Probable full positive definite matrix.
+
+    'diagonal'
+          Diagonal Matrix.  (Sparse matrices only)
+
+    'permuted diagonal'
+          Permuted Diagonal matrix.  The permutation does not need to
+          be specifically indicated, as the structure of the matrix
+          explicitly gives this.  (Sparse matrices only)
+
+    'upper'
+          Upper triangular.  If the optional third argument PERM is
+          given, the matrix is assumed to be a permuted upper
+          triangular with the permutations defined by the vector PERM.
+
+    'lower'
+          Lower triangular.  If the optional third argument PERM is
+          given, the matrix is assumed to be a permuted lower
+          triangular with the permutations defined by the vector PERM.
+
+    'banded'
+    'banded positive definite'
+          Banded matrix with the band size of NL below the diagonal and
+          NU above it.  If NL and NU are 1, then the matrix is
+          tridiagonal and treated with specialized code.  In addition
+          the matrix can be marked as probably a positive definite
+          (Sparse matrices only)
+
+    'singular'
+          The matrix is assumed to be singular and will be treated with
+          a minimum norm solution
+
+
+     Note that the matrix type will be discovered automatically on the
+     first attempt to solve a linear equation involving A.  Therefore
+     `matrix_type' is only useful to give Octave hints of the matrix
+     type.  Incorrectly defining the matrix type will result in
+     incorrect results from solutions of linear equations, and so it is
+     entirely the responsibility of the user to correctly identify the
+     matrix type.
+
+     Also the test for positive definiteness is a low-cost test for a
+     hermitian matrix with a real positive diagonal.  This does not
+     guarantee that the matrix is positive definite, but only that it
+     is a probable candidate.  When such a matrix is factorized, a
+     Cholesky factorization is first attempted, and if that fails the
+     matrix is then treated with an LU factorization.  Once the matrix
+     has been factorized, `matrix_type' will return the correct
+     classification of the matrix.
+
+ -- Built-in Function:  norm (A, P, OPT)
+     Compute the p-norm of the matrix A.  If the second argument is
+     missing, `p = 2' is assumed.
+
+     If A is a matrix (or sparse matrix):
+
+    P = `1'
+          1-norm, the largest column sum of the absolute values of A.
+
+    P = `2'
+          Largest singular value of A.
+
+    P = `Inf' or `"inf"'
+          Infinity norm, the largest row sum of the absolute values of
+          A.
+
+    P = `"fro"'
+          Frobenius norm of A, `sqrt (sum (diag (A' * A)))'.
+
+    other P, `P > 1'
+          maximum `norm (A*x, p)' such that `norm (x, p) == 1'
+
+     If A is a vector or a scalar:
+
+    P = `Inf' or `"inf"'
+          `max (abs (A))'.
+
+    P = `-Inf'
+          `min (abs (A))'.
+
+    P = `"fro"'
+          Frobenius norm of A, `sqrt (sumsq (abs (a)))'.
+
+    P = 0
+          Hamming norm - the number of nonzero elements.
+
+    other P, `P > 1'
+          p-norm of A, `(sum (abs (A) .^ P)) ^ (1/P)'.
+
+    other P `P < 1'
+          the p-pseudonorm defined as above.
+
+     If `"rows"' is given as OPT, the norms of all rows of the matrix A
+     are returned as a column vector.  Similarly, if `"columns"' or
+     `"cols"' is passed column norms are computed.
+
+     *See also:* *note cond: doc-cond, *note svd: doc-svd.
+
+ -- Function File:  null (A, TOL)
+     Return an orthonormal basis of the null space of A.
+
+     The dimension of the null space is taken as the number of singular
+     values of A not greater than TOL.  If the argument TOL is missing,
+     it is computed as
+
+          max (size (A)) * max (svd (A)) * eps
+
+ -- Function File:  orth (A, TOL)
+     Return an orthonormal basis of the range space of A.
+
+     The dimension of the range space is taken as the number of singular
+     values of A greater than TOL.  If the argument TOL is missing, it
+     is computed as
+
+          max (size (A)) * max (svd (A)) * eps
+
+ -- Loadable Function:  pinv (X, TOL)
+     Return the pseudoinverse of X.  Singular values less than TOL are
+     ignored.
+
+     If the second argument is omitted, it is assumed that
+
+          tol = max (size (X)) * sigma_max (X) * eps,
+
+     where `sigma_max (X)' is the maximal singular value of X.
+
+ -- Function File:  rank (A, TOL)
+     Compute the rank of A, using the singular value decomposition.
+     The rank is taken to be the number of singular values of A that
+     are greater than the specified tolerance TOL.  If the second
+     argument is omitted, it is taken to be
+
+          tol = max (size (A)) * sigma(1) * eps;
+
+     where `eps' is machine precision and `sigma(1)' is the largest
+     singular value of A.
+
+ -- Loadable Function: C = rcond (A)
+     Compute the 1-norm estimate of the reciprocal condition as returned
+     by LAPACK.  If the matrix is well-conditioned then C will be near
+     1 and if the matrix is poorly conditioned it will be close to zero.
+
+     The matrix A must not be sparse.  If the matrix is sparse then
+     `condest (A)' or `rcond (full (A))' should be used instead.
+
+     *See also:* *note inv: doc-inv.
+
+ -- Function File:  trace (A)
+     Compute the trace of A, `sum (diag (A))'.
+
+ -- Function File: [R, K] = rref (A, TOL)
+     Returns the reduced row echelon form of A.  TOL defaults to `eps *
+     max (size (A)) * norm (A, inf)'.
+
+     Called with two return arguments, K returns the vector of "bound
+     variables", which are those columns on which elimination has been
+     performed.
+
+
+
+File: octave.info,  Node: Matrix Factorizations,  Next: Functions of a Matrix,  Prev: Basic Matrix Functions,  Up: Linear Algebra
+
+18.3 Matrix Factorizations
+==========================
+
+ -- Loadable Function: R = chol (A)
+ -- Loadable Function: [R, P] = chol (A)
+ -- Loadable Function: [R, P, Q] = chol (S)
+ -- Loadable Function: [R, P, Q] = chol (S, 'vector')
+ -- Loadable Function: [L, ...] = chol (..., 'lower')
+     Compute the Cholesky factor, R, of the symmetric positive definite
+     matrix A, where
+
+          R' * R = A.
+
+     Called with one output argument `chol' fails if A or S is not
+     positive definite.  With two or more output arguments P flags
+     whether the matrix was positive definite and `chol' does not fail.
+     A zero value indicated that the matrix was positive definite and
+     the R gives the factorization, and P will have a positive value
+     otherwise.
+
+     If called with 3 outputs then a sparsity preserving row/column
+     permutation is applied to A prior to the factorization.  That is R
+     is the factorization of `A(Q,Q)' such that
+
+          R' * R = Q' * A * Q.
+
+     The sparsity preserving permutation is generally returned as a
+     matrix.  However, given the flag 'vector', Q will be returned as a
+     vector such that
+
+          R' * R = a (Q, Q).
+
+     Called with either a sparse or full matrix and using the 'lower'
+     flag, `chol' returns the lower triangular factorization such that
+
+          L * L' = A.
+
+     In general the lower triangular factorization is significantly
+     faster for sparse matrices.
+
+     *See also:* *note cholinv: doc-cholinv, *note chol2inv:
+     doc-chol2inv.
+
+ -- Loadable Function:  cholinv (A)
+     Use the Cholesky factorization to compute the inverse of the
+     symmetric positive definite matrix A.
+
+     *See also:* *note chol: doc-chol, *note chol2inv: doc-chol2inv.
+
+ -- Loadable Function:  chol2inv (U)
+     Invert a symmetric, positive definite square matrix from its
+     Cholesky decomposition, U.  Note that U should be an
+     upper-triangular matrix with positive diagonal elements.
+     `chol2inv (U)' provides `inv (U'*U)' but it is much faster than
+     using `inv'.
+
+     *See also:* *note chol: doc-chol, *note cholinv: doc-cholinv.
+
+ -- Loadable Function: [R1, INFO] = cholupdate (R, U, OP)
+     Update or downdate a Cholesky factorization.  Given an upper
+     triangular matrix R and a column vector U, attempt to determine
+     another upper triangular matrix R1 such that
+        * R1'*R1 = R'*R + U*U' if OP is "+"
+
+        * R1'*R1 = R'*R - U*U' if OP is "-"
+
+     If OP is "-", INFO is set to
+        * 0 if the downdate was successful,
+
+        * 1 if R'*R - U*U' is not positive definite,
+
+        * 2 if R is singular.
+
+     If INFO is not present, an error message is printed in cases 1 and
+     2.
+
+     *See also:* *note chol: doc-chol, *note qrupdate: doc-qrupdate.
+
+ -- Loadable Function: [R1, INFO] = cholinsert (R, J, U)
+     Given a Cholesky factorization of a real symmetric or complex
+     hermitian positive definite matrix A = R'*R, R upper triangular,
+     return the Cholesky factorization of A1, where A1(p,p) = A,
+     A1(:,j) = A1(j,:)' = u and p = [1:j-1,j+1:n+1].  u(j) should be
+     positive.  On return, INFO is set to
+        * 0 if the insertion was successful,
+
+        * 1 if A1 is not positive definite,
+
+        * 2 if R is singular.
+
+     If INFO is not present, an error message is printed in cases 1 and
+     2.
+
+     *See also:* *note chol: doc-chol, *note cholupdate:
+     doc-cholupdate, *note choldelete: doc-choldelete.
+
+ -- Loadable Function: R1 = choldelete (R, J)
+     Given a Cholesky factorization of a real symmetric or complex
+     hermitian positive definite matrix A = R'*R, R upper triangular,
+     return the Cholesky factorization of A(p,p), where
+     p = [1:j-1,j+1:n+1].
+
+     *See also:* *note chol: doc-chol, *note cholupdate:
+     doc-cholupdate, *note cholinsert: doc-cholinsert.
+
+ -- Loadable Function: R1 = cholshift (R, I, J)
+     Given a Cholesky factorization of a real symmetric or complex
+     hermitian positive definite matrix A = R'*R, R upper triangular,
+     return the Cholesky factorization of A(p,p), where p is the
+     permutation
+     `p = [1:i-1, shift(i:j, 1), j+1:n]' if I < J
+     or
+     `p = [1:j-1, shift(j:i,-1), i+1:n]' if J < I.
+     *See also:* *note chol: doc-chol, *note cholinsert:
+     doc-cholinsert, *note choldelete: doc-choldelete.
+
+ -- Loadable Function: H = hess (A)
+ -- Loadable Function: [P, H] = hess (A)
+     Compute the Hessenberg decomposition of the matrix A.
+
+     The Hessenberg decomposition is usually used as the first step in
+     an eigenvalue computation, but has other applications as well (see
+     Golub, Nash, and Van Loan, IEEE Transactions on Automatic Control,
+     1979).  The Hessenberg decomposition is `p * h * p' = a' where `p'
+     is a square unitary matrix (`p' * p = I', using complex-conjugate
+     transposition) and `h' is upper Hessenberg (`i >= j+1 => h (i, j)
+     = 0').
+
+ -- Loadable Function: [L, U, P] = lu (A)
+ -- Loadable Function: [L, U, P, Q] = lu (S)
+ -- Loadable Function: [L, U, P, Q, R] = lu (S)
+ -- Loadable Function: [...] = lu (S, THRES)
+ -- Loadable Function: Y = lu (...)
+ -- Loadable Function: [...] = lu (..., 'vector')
+     Compute the LU decomposition of A.  If A is full subroutines from
+     LAPACK are used and if A is sparse then UMFPACK is used.  The
+     result is returned in a permuted form, according to the optional
+     return value P.  For example, given the matrix `a = [1, 2; 3, 4]',
+
+          [l, u, p] = lu (a)
+
+     returns
+
+          l =
+
+            1.00000  0.00000
+            0.33333  1.00000
+
+          u =
+
+            3.00000  4.00000
+            0.00000  0.66667
+
+          p =
+
+            0  1
+            1  0
+
+     The matrix is not required to be square.
+
+     Called with two or three output arguments and a spare input matrix,
+     then "lu" does not attempt to perform sparsity preserving column
+     permutations.  Called with a fourth output argument, the sparsity
+     preserving column transformation Q is returned, such that `P * A *
+     Q = L * U'.
+
+     Called with a fifth output argument and a sparse input matrix, then
+     "lu" attempts to use a scaling factor R on the input matrix such
+     that `P * (R \ A) * Q = L * U'.  This typically leads to a sparser
+     and more stable factorization.
+
+     An additional input argument THRES, that defines the pivoting
+     threshold can be given.  THRES can be a scalar, in which case it
+     defines UMFPACK pivoting tolerance for both symmetric and
+     unsymmetric cases.  If THRES is a two element vector, then the
+     first element defines the pivoting tolerance for the unsymmetric
+     UMFPACK pivoting strategy and the second the symmetric strategy.
+     By default, the values defined by `spparms' are used and are by
+     default `[0.1, 0.001]'.
+
+     Given the string argument 'vector', "lu" returns the values of P Q
+     as vector values, such that for full matrix, `A (P,:) = L * U',
+     and `R(P,:) * A (:, Q) = L * U'.
+
+     With two output arguments, returns the permuted forms of the upper
+     and lower triangular matrices, such that `A = L * U'.  With one
+     output argument Y, then the matrix returned by the LAPACK routines
+     is returned.  If the input matrix is sparse then the matrix L is
+     embedded into U to give a return value similar to the full case.
+     For both full and sparse matrices, "lu" looses the permutation
+     information.
+
+ -- Loadable Function: [Q, R, P] = qr (A)
+ -- Loadable Function: [Q, R, P] = qr (A, '0')
+     Compute the QR factorization of A, using standard LAPACK
+     subroutines.  For example, given the matrix `a = [1, 2; 3, 4]',
+
+          [q, r] = qr (a)
+
+     returns
+
+          q =
+
+            -0.31623  -0.94868
+            -0.94868   0.31623
+
+          r =
+
+            -3.16228  -4.42719
+             0.00000  -0.63246
+
+     The `qr' factorization has applications in the solution of least
+     squares problems
+
+          `min norm(A x - b)'
+
+     for overdetermined systems of equations (i.e., `a'  is a tall,
+     thin matrix).  The QR factorization is `q * r = a' where `q' is an
+     orthogonal matrix and `r' is upper triangular.
+
+     If given a second argument of '0', `qr' returns an economy-sized
+     QR factorization, omitting zero rows of R and the corresponding
+     columns of Q.
+
+     If the matrix A is full, the permuted QR factorization `[Q, R, P]
+     = qr (A)' forms the QR factorization such that the diagonal
+     entries of `r' are decreasing in magnitude order.  For
+     example,given the matrix `a = [1, 2; 3, 4]',
+
+          [q, r, p] = qr(a)
+
+     returns
+
+          q =
+
+            -0.44721  -0.89443
+            -0.89443   0.44721
+
+          r =
+
+            -4.47214  -3.13050
+             0.00000   0.44721
+
+          p =
+
+             0  1
+             1  0
+
+     The permuted `qr' factorization `[q, r, p] = qr (a)' factorization
+     allows the construction of an orthogonal basis of `span (a)'.
+
+     If the matrix A is sparse, then compute the sparse QR factorization
+     of A, using CSPARSE.  As the matrix Q is in general a full matrix,
+     this function returns the Q-less factorization R of A, such that
+     `R = chol (A' * A)'.
+
+     If the final argument is the scalar `0' and the number of rows is
+     larger than the number of columns, then an economy factorization is
+     returned.  That is R will have only `size (A,1)' rows.
+
+     If an additional matrix B is supplied, then `qr' returns C, where
+     `C = Q' * B'.  This allows the least squares approximation of `A \
+     B' to be calculated as
+
+          [C,R] = spqr (A,B)
+          X = R \ C
+
+ -- Loadable Function: [Q1, R1] = qrupdate (Q, R, U, V)
+     Given a QR factorization of a real or complex matrix A = Q*R,
+     Q unitary and R upper trapezoidal, return the QR factorization of
+     A + U*V', where U and V are column vectors (rank-1 update) or
+     matrices with equal number of columns (rank-k update).  Notice
+     that the latter case is done as a sequence of rank-1 updates;
+     thus, for k large enough, it will be both faster and more accurate
+     to recompute the factorization from scratch.
+
+     The QR factorization supplied may be either full (Q is square) or
+     economized (R is square).
+
+     *See also:* *note qr: doc-qr, *note qrinsert: doc-qrinsert, *note
+     qrdelete: doc-qrdelete.
+
+ -- Loadable Function: [Q1, R1] = qrinsert (Q, R, J, X, ORIENT)
+     Given a QR factorization of a real or complex matrix A = Q*R,
+     Q unitary and R upper trapezoidal, return the QR factorization of
+     [A(:,1:j-1) x A(:,j:n)], where U is a column vector to be inserted
+     into A (if ORIENT is `"col"'), or the QR factorization of
+     [A(1:j-1,:);x;A(:,j:n)], where X is a row vector to be inserted
+     into A (if ORIENT is `"row"').
+
+     The default value of ORIENT is `"col"'.  If ORIENT is `"col"', U
+     may be a matrix and J an index vector resulting in the
+     QR factorization of a matrix B such that B(:,J) gives U and
+     B(:,J) = [] gives A.  Notice that the latter case is done as a
+     sequence of k insertions; thus, for k large enough, it will be
+     both faster and more accurate to recompute the factorization from
+     scratch.
+
+     If ORIENT is `"col"', the QR factorization supplied may be either
+     full (Q is square) or economized (R is square).
+
+     If ORIENT is `"row"', full factorization is needed.
+
+     *See also:* *note qr: doc-qr, *note qrupdate: doc-qrupdate, *note
+     qrdelete: doc-qrdelete.
+
+ -- Loadable Function: [Q1, R1] = qrdelete (Q, R, J, ORIENT)
+     Given a QR factorization of a real or complex matrix A = Q*R,
+     Q unitary and R upper trapezoidal, return the QR factorization of
+     [A(:,1:j-1) A(:,j+1:n)], i.e., A with one column deleted (if
+     ORIENT is "col"), or the QR factorization of
+     [A(1:j-1,:);A(:,j+1:n)], i.e., A with one row deleted (if ORIENT
+     is "row").
+
+     The default value of ORIENT is "col".
+
+     If ORIENT is `"col"', J may be an index vector resulting in the
+     QR factorization of a matrix B such that A(:,J) = [] gives B.
+     Notice that the latter case is done as a sequence of k deletions;
+     thus, for k large enough, it will be both faster and more accurate
+     to recompute the factorization from scratch.
+
+     If ORIENT is `"col"', the QR factorization supplied may be either
+     full (Q is square) or economized (R is square).
+
+     If ORIENT is `"row"', full factorization is needed.
+
+     *See also:* *note qr: doc-qr, *note qrinsert: doc-qrinsert, *note
+     qrupdate: doc-qrupdate.
+
+ -- Loadable Function: [Q1, R1] = qrshift (Q, R, I, J)
+     Given a QR factorization of a real or complex matrix A = Q*R,
+     Q unitary and R upper trapezoidal, return the QR factorization of
+     A(:,p), where p is the permutation
+     `p = [1:i-1, shift(i:j, 1), j+1:n]' if I < J
+     or
+     `p = [1:j-1, shift(j:i,-1), i+1:n]' if J < I.
+     *See also:* *note qr: doc-qr, *note qrinsert: doc-qrinsert, *note
+     qrdelete: doc-qrdelete.
+
+ -- Loadable Function: LAMBDA = qz (A, B)
+     Generalized eigenvalue problem A x = s B x, QZ decomposition.
+     There are three ways to call this function:
+       1. `lambda = qz(A,B)'
+
+          Computes the generalized eigenvalues LAMBDA of (A - s B).
+
+       2. `[AA, BB, Q, Z, V, W, lambda] = qz (A, B)'
+
+          Computes qz decomposition, generalized eigenvectors, and
+          generalized eigenvalues of (A - sB)
+
+                   A*V = B*V*diag(lambda)
+                   W'*A = diag(lambda)*W'*B
+                   AA = Q'*A*Z, BB = Q'*B*Z
+          with Q and Z orthogonal (unitary)= I
+
+       3. `[AA,BB,Z{, lambda}] = qz(A,B,opt)'
+
+          As in form [2], but allows ordering of generalized eigenpairs
+          for (e.g.) solution of discrete time algebraic Riccati
+          equations.  Form 3 is not available for complex matrices, and
+          does not compute the generalized eigenvectors V, W, nor the
+          orthogonal matrix Q.
+         OPT
+               for ordering eigenvalues of the GEP pencil.  The leading
+               block of the revised pencil contains all eigenvalues
+               that satisfy:
+              `"N"'
+                    = unordered (default)
+
+              `"S"'
+                    = small: leading block has all |lambda| <=1
+
+              `"B"'
+                    = big: leading block has all |lambda| >= 1
+
+              `"-"'
+                    = negative real part: leading block has all
+                    eigenvalues in the open left half-plane
+
+              `"+"'
+                    = non-negative real part: leading block has all
+                    eigenvalues in the closed right half-plane
+
+     Note: qz performs permutation balancing, but not scaling (see
+     balance).  Order of output arguments was selected for
+     compatibility with MATLAB
+
+     *See also:* *note balance: doc-balance, *note eig: doc-eig, *note
+     schur: doc-schur.
+
+ -- Function File: [AA, BB, Q, Z] = qzhess (A, B)
+     Compute the Hessenberg-triangular decomposition of the matrix
+     pencil `(A, B)', returning `AA = Q * A * Z', `BB = Q * B * Z',
+     with Q and Z orthogonal.  For example,
+
+          [aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
+               => aa = [ -3.02244, -4.41741;  0.92998,  0.69749 ]
+               => bb = [ -8.60233, -9.99730;  0.00000, -0.23250 ]
+               =>  q = [ -0.58124, -0.81373; -0.81373,  0.58124 ]
+               =>  z = [ 1, 0; 0, 1 ]
+
+     The Hessenberg-triangular decomposition is the first step in Moler
+     and Stewart's QZ decomposition algorithm.
+
+     Algorithm taken from Golub and Van Loan, `Matrix Computations, 2nd
+     edition'.
+
+ -- Loadable Function: S = schur (A)
+ -- Loadable Function: [U, S] = schur (A, OPT)
+     The Schur decomposition is used to compute eigenvalues of a square
+     matrix, and has applications in the solution of algebraic Riccati
+     equations in control (see `are' and `dare').  `schur' always
+     returns `s = u' * a * u' where `u'  is a unitary matrix (`u'* u'
+     is identity) and `s' is upper triangular.  The eigenvalues of `a'
+     (and `s') are the diagonal elements of `s'.  If the matrix `a' is
+     real, then the real Schur decomposition is computed, in which the
+     matrix `u' is orthogonal and `s' is block upper triangular with
+     blocks of size at most `2 x 2' along the diagonal.  The diagonal
+     elements of `s' (or the eigenvalues of the `2 x 2' blocks, when
+     appropriate) are the eigenvalues of `a' and `s'.
+
+     The eigenvalues are optionally ordered along the diagonal
+     according to the value of `opt'.  `opt = "a"' indicates that all
+     eigenvalues with negative real parts should be moved to the leading
+     block of `s' (used in `are'), `opt = "d"' indicates that all
+     eigenvalues with magnitude less than one should be moved to the
+     leading block of `s' (used in `dare'), and `opt = "u"', the
+     default, indicates that no ordering of eigenvalues should occur.
+     The leading `k' columns of `u' always span the `a'-invariant
+     subspace corresponding to the `k' leading eigenvalues of `s'.
+
+ -- Function File: ANGLE = subspace (A, B)
+     Determine the largest principal angle between two subspaces
+     spanned by columns of matrices A and B.
+
+ -- Loadable Function: S = svd (A)
+ -- Loadable Function: [U, S, V] = svd (A)
+     Compute the singular value decomposition of A
+
+          A = U*S*V'
+
+     The function `svd' normally returns the vector of singular values.
+     If asked for three return values, it computes U, S, and V.  For
+     example,
+
+          svd (hilb (3))
+
+     returns
+
+          ans =
+
+            1.4083189
+            0.1223271
+            0.0026873
+
+     and
+
+          [u, s, v] = svd (hilb (3))
+
+     returns
+
+          u =
+
+            -0.82704   0.54745   0.12766
+            -0.45986  -0.52829  -0.71375
+            -0.32330  -0.64901   0.68867
+
+          s =
+
+            1.40832  0.00000  0.00000
+            0.00000  0.12233  0.00000
+            0.00000  0.00000  0.00269
+
+          v =
+
+            -0.82704   0.54745   0.12766
+            -0.45986  -0.52829  -0.71375
+            -0.32330  -0.64901   0.68867
+
+     If given a second argument, `svd' returns an economy-sized
+     decomposition, eliminating the unnecessary rows or columns of U or
+     V.
+
+ -- Function File: [HOUSV, BETA, ZER] = housh (X, J, Z)
+     Compute Householder reflection vector HOUSV to reflect X to be the
+     j-th column of identity, i.e.,
+
+          (I - beta*housv*housv')x =  norm(x)*e(j) if x(1) < 0,
+          (I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0
+
+     Inputs
+
+    X
+          vector
+
+    J
+          index into vector
+
+    Z
+          threshold for zero  (usually should be the number 0)
+
+     Outputs (see Golub and Van Loan):
+
+    BETA
+          If beta = 0, then no reflection need be applied (zer set to 0)
+
+    HOUSV
+          householder vector
+
+ -- Function File: [U, H, NU] = krylov (A, V, K, EPS1, PFLG)
+     Construct an orthogonal basis U of block Krylov subspace
+
+          [v a*v a^2*v ... a^(k+1)*v]
+
+     Using Householder reflections to guard against loss of
+     orthogonality.
+
+     If V is a vector, then H contains the Hessenberg matrix such that
+     `a*u == u*h+rk*ek'', in which `rk = a*u(:,k)-u*h(:,k)', and `ek''
+     is the vector `[0, 0, ..., 1]' of length `k'.  Otherwise, H is
+     meaningless.
+
+     If V is a vector and K is greater than `length(A)-1', then H
+     contains the Hessenberg matrix such that `a*u == u*h'.
+
+     The value of NU is the dimension of the span of the krylov
+     subspace (based on EPS1).
+
+     If B is a vector and K is greater than M-1, then H contains the
+     Hessenberg decomposition of A.
+
+     The optional parameter EPS1 is the threshold for zero.  The
+     default value is 1e-12.
+
+     If the optional parameter PFLG is nonzero, row pivoting is used to
+     improve numerical behavior.  The default value is 0.
+
+     Reference: Hodel and Misra, "Partial Pivoting in the Computation of
+     Krylov Subspaces", to be submitted to Linear Algebra and its
+     Applications
+
+
+File: octave.info,  Node: Functions of a Matrix,  Next: Specialized Solvers,  Prev: Matrix Factorizations,  Up: Linear Algebra
+
+18.4 Functions of a Matrix
+==========================
+
+ -- Function File:  expm (A)
+     Return the exponential of a matrix, defined as the infinite Taylor
+     series
+
+          expm(a) = I + a + a^2/2! + a^3/3! + ...
+
+     The Taylor series is _not_ the way to compute the matrix
+     exponential; see Moler and Van Loan, `Nineteen Dubious Ways to
+     Compute the Exponential of a Matrix', SIAM Review, 1978.  This
+     routine uses Ward's diagonal Pade' approximation method with three
+     step preconditioning (SIAM Journal on Numerical Analysis, 1977).
+     Diagonal Pade'  approximations are rational polynomials of matrices
+
+               -1
+          D (a)   N (a)
+
+     whose Taylor series matches the first `2q+1' terms of the Taylor
+     series above; direct evaluation of the Taylor series (with the
+     same preconditioning steps) may be desirable in lieu of the Pade'
+     approximation when `Dq(a)' is ill-conditioned.
+
+ -- Function File:  logm (A)
+     Compute the matrix logarithm of the square matrix A.  Note that
+     this is currently implemented in terms of an eigenvalue expansion
+     and needs to be improved to be more robust.
+
+ -- Loadable Function: [RESULT, ERROR_ESTIMATE] = sqrtm (A)
+     Compute the matrix square root of the square matrix A.
+
+     Ref: Nicholas J. Higham.  A new sqrtm for MATLAB.  Numerical
+     Analysis Report No. 336, Manchester Centre for Computational
+     Mathematics, Manchester, England, January 1999.
+
+     *See also:* *note expm: doc-expm, *note logm: doc-logm.
+
+ -- Loadable Function:  kron (A, B)
+     Form the kronecker product of two matrices, defined block by block
+     as
+
+          x = [a(i, j) b]
+
+     For example,
+
+          kron (1:4, ones (3, 1))
+                =>  1  2  3  4
+                    1  2  3  4
+                    1  2  3  4
+
+ -- Loadable Function: X = syl (A, B, C)
+     Solve the Sylvester equation
+
+          A X + X B + C = 0
+     using standard LAPACK subroutines.  For example,
+
+          syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
+               => [ -0.50000, -0.66667; -0.66667, -0.50000 ]
+
+
+File: octave.info,  Node: Specialized Solvers,  Prev: Functions of a Matrix,  Up: Linear Algebra
+
+18.5 Specialized Solvers
+========================
+
+ -- Function File:  bicgstab (A, B)
+ -- Function File:  bicgstab (A, B, TOL, MAXIT, M1, M2, X0)
+     This procedure attempts to solve a system of linear equations A*x
+     = b for x.  The A must be square, symmetric and positive definite
+     real matrix N*N.  The B must be a one column vector with a length
+     of N.  The TOL specifies the tolerance of the method, the default
+     value is 1e-6.  The MAXIT specifies the maximum number of
+     iterations, the default value is min(20,N).  The M1 specifies a
+     preconditioner, can also be a function handler which returns M\X.
+     The M2 combined with M1 defines preconditioner as
+     preconditioner=M1*M2.  The X0 is the initial guess, the default
+     value is zeros(N,1).
+
+     The value X is a computed result of this procedure.  The value
+     FLAG can be 0 when we reach tolerance in MAXIT iterations, 1 when
+     we don't reach tolerance in MAXIT iterations and 3 when the
+     procedure stagnates.  The value RELRES is a relative residual -
+     norm(b-A*x)/norm(b).  The value ITER is an iteration number in
+     which x was computed.  The value RESVEC is a vector of RELRES for
+     each iteration.
+
+
+ -- Function File:  cgs (A, B)
+ -- Function File:  cgs (A, B, TOL, MAXIT, M1, M2, X0)
+     This procedure attempts to solve a system of linear equations A*x
+     = b for x.  The A must be square, symmetric and positive definite
+     real matrix N*N.  The B must be a one column vector with a length
+     of N.  The TOL specifies the tolerance of the method, default
+     value is 1e-6.  The MAXIT specifies the maximum number of
+     iteration, default value is MIN(20,N).  The M1 specifies a
+     preconditioner, can also be a function handler which returns M\X.
+     The M2 combined with M1 defines preconditioner as
+     preconditioner=M1*M2.  The X0 is initial guess, default value is
+     zeros(N,1).
+
+
+
+File: octave.info,  Node: Nonlinear Equations,  Next: Diagonal and Permutation Matrices,  Prev: Linear Algebra,  Up: Top
+
+19 Nonlinear Equations
+**********************
+
+Octave can solve sets of nonlinear equations of the form
+
+     F (x) = 0
+
+using the function `fsolve', which is based on the MINPACK subroutine
+`hybrd'.  This is an iterative technique so a starting point will have
+to be provided.  This also has the consequence that convergence is not
+guaranteed even if a solution exists.
+
+ -- Function File:  fsolve (FCN, X0, OPTIONS)
+ -- Function File: [X, FVEC, INFO, OUTPUT, FJAC] = fsolve (FCN, ...)
+     Solve a system of nonlinear equations defined by the function FCN.
+     FCN should accepts a vector (array) defining the unknown variables,
+     and return a vector of left-hand sides of the equations.
+     Right-hand sides are defined to be zeros.  In other words, this
+     function attempts to determine a vector X such that `FCN (X)'
+     gives (approximately) all zeros.  X0 determines a starting guess.
+     The shape of X0 is preserved in all calls to FCN, but otherwise it
+     is treated as a column vector.  OPTIONS is a structure specifying
+     additional options.  Currently, `fsolve' recognizes these options:
+     `"FunValCheck"', `"OutputFcn"', `"TolX"', `"TolFun"', `"MaxIter"',
+     `"MaxFunEvals"', `"Jacobian"', `"Updating"' and `"ComplexEqn"'.
+
+     If `"Jacobian"' is `"on"', it specifies that FCN, called with 2
+     output arguments, also returns the Jacobian matrix of right-hand
+     sides at the requested point.  `"TolX"' specifies the termination
+     tolerance in the unknown variables, while `"TolFun"' is a
+     tolerance for equations.  Default is `1e-7' for both `"TolX"' and
+     `"TolFun"'.  If `"Updating"' is "on", the function will attempt to
+     use Broyden updates to update the Jacobian, in order to reduce the
+     amount of jacobian calculations.  If your user function always
+     calculates the Jacobian (regardless of number of output
+     arguments), this option provides no advantage and should be set to
+     false.
+
+     `"ComplexEqn"' is `"on"', `fsolve' will attempt to solve complex
+     equations in complex variables, assuming that the equations
+     possess a complex derivative (i.e., are holomorphic).  If this is
+     not what you want, should unpack the real and imaginary parts of
+     the system to get a real system.
+
+     For description of the other options, see `optimset'.
+
+     On return, FVAL contains the value of the function FCN evaluated
+     at X, and INFO may be one of the following values:
+
+    1
+          Converged to a solution point.  Relative residual error is
+          less than specified by TolFun.
+
+    2
+          Last relative step size was less that TolX.
+
+    3
+          Last relative decrease in residual was less than TolF.
+
+    0
+          Iteration limit exceeded.
+
+    -3
+          The trust region radius became excessively small.
+
+     Note: If you only have a single nonlinear equation of one
+     variable, using `fzero' is usually a much better idea.
+
+     *See also:* *note fzero: doc-fzero, *note optimset: doc-optimset.
+
+     Note about user-supplied jacobians: As an inherent property of the
+     algorithm, jacobian is always requested for a solution vector
+     whose residual vector is already known, and it is the last
+     accepted successful step.  Often this will be one of the last two
+     calls, but not always.  If the savings by reusing intermediate
+     results from residual calculation in jacobian calculation are
+     significant, the best strategy is to employ OutputFcn: After a
+     vector is evaluated for residuals, if OutputFcn is called with
+     that vector, then the intermediate results should be saved for
+     future jacobian evaluation, and should be kept until a jacobian
+     evaluation is requested or until outputfcn is called with a
+     different vector, in which case they should be dropped in favor of
+     this most recent vector.  A short example how this can be achieved
+     follows:
+
+          function [fvec, fjac] = user_func (x, optimvalues, state)
+          persistent sav = [], sav0 = [];
+          if (nargin == 1)
+            ## evaluation call
+            if (nargout == 1)
+              sav0.x = x; # mark saved vector
+              ## calculate fvec, save results to sav0.
+            elseif (nargout == 2)
+              ## calculate fjac using sav.
+            endif
+          else
+            ## outputfcn call.
+            if (all (x == sav0.x))
+              sav = sav0;
+            endif
+            ## maybe output iteration status, etc.
+          endif
+          endfunction
+
+           ....
+
+          fsolve (@user_func, x0, optimset ("OutputFcn", @user_func, ...))
+
+
+   Here is a complete example.  To solve the set of equations
+
+     -2x^2 + 3xy   + 4 sin(y) = 6
+      3x^2 - 2xy^2 + 3 cos(x) = -4
+
+you first need to write a function to compute the value of the given
+function.  For example:
+
+     function y = f (x)
+       y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
+       y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
+     endfunction
+
+   Then, call `fsolve' with a specified initial condition to find the
+roots of the system of equations.  For example, given the function `f'
+defined above,
+
+     [x, fval, info] = fsolve (@f, [1; 2])
+
+results in the solution
+
+     x =
+
+       0.57983
+       2.54621
+
+     fval =
+
+       -5.7184e-10
+        5.5460e-10
+
+     info = 1
+
+A value of `info = 1' indicates that the solution has converged.
+
+   The function `perror' may be used to print English messages
+corresponding to the numeric error codes.  For example,
+
+     perror ("fsolve", 1)
+          -| solution converged to requested tolerance
+
+   When no Jacobian is supplied (as in the example above) it is
+approximated numerically.  This requires more function evaluations, and
+hence is less efficient.  In the example above we could compute the
+Jacobian analytically as
+
+     function J = jacobian(x)
+       J(1,1) =  3*x(2) - 4*x(1);
+       J(1,2) =  4*cos(x(2)) + 3*x(1);
+       J(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
+       J(2,2) = -4*x(1)*x(2);
+     endfunction
+
+The Jacobian can then be used with the following call to `fsolve':
+
+     [x, fval, info] = fsolve ({@f, @jacobian}, [1; 2]);
+
+which gives the same solution as before.
+
+ -- Function File: [X, FVAL, INFO, OUTPUT] = fzero (FUN, X0, OPTIONS)
+     Find a zero point of a univariate function.  FUN should be a
+     function handle or name.  X0 specifies a starting point.  OPTIONS
+     is a structure specifying additional options.  Currently, `fzero'
+     recognizes these options: `"FunValCheck"', `"OutputFcn"',
+     `"TolX"', `"MaxIter"', `"MaxFunEvals"'.  For description of these
+     options, see *note optimset: doc-optimset.
+
+     On exit, the function returns X, the approximate zero point and
+     FVAL, the function value thereof.  INFO is an exit flag that can
+     have these values:
+        * 1 The algorithm converged to a solution.
+
+        * 0 Maximum number of iterations or function evaluations has
+          been exhausted.
+
+        * -1 The algorithm has been terminated from user output
+          function.
+
+        * -2 A general unexpected error.
+
+        * -3 A non-real value encountered.
+
+        * -4 A NaN value encountered.
+
+     *See also:* *note optimset: doc-optimset, *note fsolve: doc-fsolve.
+
+
+File: octave.info,  Node: Diagonal and Permutation Matrices,  Next: Sparse Matrices,  Prev: Nonlinear Equations,  Up: Top
+
+20 Diagonal and Permutation Matrices
+************************************
+
+* Menu:
+
+* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Function Support::     Functions That Are Aware of These Matrices
+* Example Codes::        Some Examples of Usage
+* Zeros Treatment::      The Differences in Treatment of Zero Elements
+
+
+File: octave.info,  Node: Basic Usage,  Next: Matrix Algebra,  Up: Diagonal and Permutation Matrices
+
+20.1 Creating and Manipulating Diagonal and Permutation Matrices
+================================================================
+
+A diagonal matrix is defined as a matrix that has zero entries outside
+the main diagonal; that is, `D(i,j) == 0' if `i != j'.  Most often,
+square diagonal matrices are considered; however, the definition can
+equally be applied to nonsquare matrices, in which case we usually
+speak of a rectangular diagonal matrix.
+
+   A permutation matrix is defined as a square matrix that has a single
+element equal to unity in each row and each column; all other elements
+are zero.  That is, there exists a permutation (vector) `p' such that
+`P(i,j) == 1' if `j == p(i)' and `P(i,j) == 0' otherwise.
+
+   Octave provides special treatment of real and complex rectangular
+diagonal matrices, as well as permutation matrices.  They are stored as
+special objects, using efficient storage and algorithms, facilitating
+writing both readable and efficient matrix algebra expressions in the
+Octave language.
+
+* Menu:
+
+* Creating Diagonal Matrices::
+* Creating Permutation Matrices::
+* Explicit and Implicit Conversions::
+
+
+File: octave.info,  Node: Creating Diagonal Matrices,  Next: Creating Permutation Matrices,  Up: Basic Usage
+
+20.1.1 Creating Diagonal Matrices
+---------------------------------
+
+The most common and easiest way to create a diagonal matrix is using
+the built-in function "diag".  The expression `diag (v)', with V a
+vector, will create a square diagonal matrix with elements on the main
+diagonal given by the elements of V, and size equal to the length of V.
+`diag (v, m, n)' can be used to construct a rectangular diagonal matrix.
+The result of these expressions will be a special diagonal matrix
+object, rather than a general matrix object.
+
+   Diagonal matrix with unit elements can be created using "eye".  Some
+other built-in functions can also return diagonal matrices.  Examples
+include "balance" or "inv".
+
+   Example:
+       diag (1:4)
+     =>
+     Diagonal Matrix
+
+        1   0   0   0
+        0   2   0   0
+        0   0   3   0
+        0   0   0   4
+
+       diag(1:3,5,3)
+
+     =>
+     Diagonal Matrix
+
+        1   0   0
+        0   2   0
+        0   0   3
+        0   0   0
+        0   0   0
+
+
+File: octave.info,  Node: Creating Permutation Matrices,  Next: Explicit and Implicit Conversions,  Prev: Creating Diagonal Matrices,  Up: Basic Usage
+
+20.1.2 Creating Permutation Matrices
+------------------------------------
+
+For creating permutation matrices, Octave does not introduce a new
+function, but rather overrides an existing syntax: permutation matrices
+can be conveniently created by indexing an identity matrix by
+permutation vectors.  That is, if Q is a permutation vector of length
+N, the expression
+       P = eye (n) (:, q);
+   will create a permutation matrix - a special matrix object.
+     eye (n) (q, :)
+   will also work (and create a row permutation matrix), as well as
+     eye (n) (q1, q2).
+
+   For example:
+       eye (4) ([1,3,2,4],:)
+     =>
+     Permutation Matrix
+
+        1   0   0   0
+        0   0   1   0
+        0   1   0   0
+        0   0   0   1
+
+       eye (4) (:,[1,3,2,4])
+     =>
+     Permutation Matrix
+
+        1   0   0   0
+        0   0   1   0
+        0   1   0   0
+        0   0   0   1
+
+   Mathematically, an identity matrix is both diagonal and permutation
+matrix.  In Octave, `eye (n)' returns a diagonal matrix, because a
+matrix can only have one class.  You can convert this diagonal matrix
+to a permutation matrix by indexing it by an identity permutation, as
+shown below.  This is a special property of the identity matrix;
+indexing other diagonal matrices generally produces a full matrix.
+
+       eye (3)
+     =>
+     Diagonal Matrix
+
+        1   0   0
+        0   1   0
+        0   0   1
+
+       eye(3)(1:3,:)
+     =>
+     Permutation Matrix
+
+        1   0   0
+        0   1   0
+        0   0   1
+
+   Some other built-in functions can also return permutation matrices.
+Examples include "inv" or "lu".
+
+
+File: octave.info,  Node: Explicit and Implicit Conversions,  Prev: Creating Permutation Matrices,  Up: Basic Usage
+
+20.1.3 Explicit and Implicit Conversions
+----------------------------------------
+
+The diagonal and permutation matrices are special objects in their own
+right.  A number of operations and built-in functions are defined for
+these matrices to use special, more efficient code than would be used
+for a full matrix in the same place.  Examples are given in further
+sections.
+
+   To facilitate smooth mixing with full matrices, backward
+compatibility, and compatibility with MATLAB, the diagonal and
+permutation matrices should allow any operation that works on full
+matrices, and will either treat it specially, or implicitly convert
+themselves to full matrices.
+
+   Instances include matrix indexing, except for extracting a single
+element or a leading submatrix, indexed assignment, or applying most
+mapper functions, such as "exp".
+
+   An explicit conversion to a full matrix can be requested using the
+built-in function "full".  It should also be noted that the diagonal
+and permutation matrix objects will cache the result of the conversion
+after it is first requested (explicitly or implicitly), so that
+subsequent conversions will be very cheap.
+
+
+File: octave.info,  Node: Matrix Algebra,  Next: Function Support,  Prev: Basic Usage,  Up: Diagonal and Permutation Matrices
+
+20.2 Linear Algebra with Diagonal and Permutation Matrices
+==========================================================
+
+As has been already said, diagonal and permutation matrices make it
+possible to use efficient algorithms while preserving natural linear
+algebra syntax.  This section describes in detail the operations that
+are treated specially when performed on these special matrix objects.
+
+* Menu:
+
+* Expressions Involving Diagonal Matrices::
+* Expressions Involving Permutation Matrices::
+
+
+File: octave.info,  Node: Expressions Involving Diagonal Matrices,  Next: Expressions Involving Permutation Matrices,  Up: Matrix Algebra
+
+20.2.1 Expressions Involving Diagonal Matrices
+----------------------------------------------
+
+Assume D is a diagonal matrix.  If M is a full matrix, then `D*M' will
+scale the rows of M.  That means, if `S = D*M', then for each pair of
+indices i,j it holds
+     S(i,j) = D(i,i) * M(i,j).
+   Similarly, `M*D' will do a column scaling.
+
+   The matrix D may also be rectangular, m-by-n where `m != n'.  If `m
+< n', then the expression `D*M' is equivalent to
+     D(:,1:m) * M(1:m,:),
+   i.e., trailing `n-m' rows of M are ignored.  If `m > n', then `D*M'
+is equivalent to
+     [D(1:n,n) * M; zeros(m-n, columns (M))],
+   i.e., null rows are appended to the result.  The situation for
+right-multiplication `M*D' is analogous.
+
+   The expressions `D \ M' and `M / D' perform inverse scaling.  They
+are equivalent to solving a diagonal (or rectangular diagonal) in a
+least-squares minimum-norm sense.  In exact arithmetics, this is
+equivalent to multiplying by a pseudoinverse.  The pseudoinverse of a
+rectangular diagonal matrix is again a rectangular diagonal matrix with
+swapped dimensions, where each nonzero diagonal element is replaced by
+its reciprocal.  The matrix division algorithms do, in fact, use
+division rather than multiplication by reciprocals for better numerical
+accuracy; otherwise, they honor the above definition.  Note that a
+diagonal matrix is never truncated due to ill-conditioning; otherwise,
+it would not be much useful for scaling.  This is typically consistent
+with linear algebra needs.  A full matrix that only happens to be
+diagonal (an is thus not a special object) is of course treated
+normally.
+
+   Multiplication and division by diagonal matrices works efficiently
+also when combined with sparse matrices, i.e., `D*S', where D is a
+diagonal matrix and S is a sparse matrix scales the rows of the sparse
+matrix and returns a sparse matrix.  The expressions `S*D', `D\S',
+`S/D' work analogically.
+
+   If D1 and D2 are both diagonal matrices, then the expressions
+     D1 + D2
+     D1 - D2
+     D1 * D2
+     D1 / D2
+     D1 \ D2
+again produce diagonal matrices, provided that normal dimension
+matching rules are obeyed.  The relations used are same as described
+above.
+
+   Also, a diagonal matrix D can be multiplied or divided by a scalar,
+or raised to a scalar power if it is square, producing diagonal matrix
+result in all cases.
+
+   A diagonal matrix can also be transposed or conjugate-transposed,
+giving the expected result.  Extracting a leading submatrix of a
+diagonal matrix, i.e., `D(1:m,1:n)', will produce a diagonal matrix,
+other indexing expressions will implicitly convert to full matrix.
+
+   Adding a diagonal matrix to a full matrix only operates on the
+diagonal elements.  Thus,
+     A = A + eps * eye (n)
+   is an efficient method of augmenting the diagonal of a matrix.
+Subtraction works analogically.
+
+   When involved in expressions with other element-by-element
+operators, `.*', `./', `.\' or `.^', an implicit conversion to full
+matrix will take place.  This is not always strictly necessary but
+chosen to facilitate better consistency with MATLAB.
+
+
+File: octave.info,  Node: Expressions Involving Permutation Matrices,  Prev: Expressions Involving Diagonal Matrices,  Up: Matrix Algebra
+
+20.2.2 Expressions Involving Permutation Matrices
+-------------------------------------------------
+
+If P is a permutation matrix and M a matrix, the expression `P*M' will
+permute the rows of M.  Similarly, `M*P' will yield a column
+permutation.  Matrix division `P\M' and `M/P' can be used to do inverse
+permutation.
+
+   The previously described syntax for creating permutation matrices
+can actually help an user to understand the connection between a
+permutation matrix and a permuting vector.  Namely, the following
+holds, where `I = eye (n)' is an identity matrix:
+       I(p,:) * M = (I*M) (p,:) = M(p,:)
+   Similarly,
+       M * I(:,p) = (M*I) (:,p) = M(:,p)
+
+   The expressions `I(p,:)' and `I(:,p)' are permutation matrices.
+
+   A permutation matrix can be transposed (or conjugate-transposed,
+which is the same, because a permutation matrix is never complex),
+inverting the permutation, or equivalently, turning a row-permutation
+matrix into a column-permutation one.  For permutation matrices,
+transpose is equivalent to inversion, thus `P\M' is equivalent to
+`P'*M'.  Transpose of a permutation matrix (or inverse) is a
+constant-time operation, flipping only a flag internally, and thus the
+choice between the two above equivalent expressions for inverse
+permuting is completely up to the user's taste.
+
+   Multiplication and division by permutation matrices works
+efficiently also when combined with sparse matrices, i.e., `P*S', where
+P is a permutation matrix and S is a sparse matrix permutes the rows of
+the sparse matrix and returns a sparse matrix.  The expressions `S*P',
+`P\S', `S/P' work analogically.
+
+   Two permutation matrices can be multiplied or divided (if their
+sizes match), performing a composition of permutations.  Also a
+permutation matrix can be indexed by a permutation vector (or two
+vectors), giving again a permutation matrix.  Any other operations do
+not generally yield a permutation matrix and will thus trigger the
+implicit conversion.
+
+
+File: octave.info,  Node: Function Support,  Next: Example Codes,  Prev: Matrix Algebra,  Up: Diagonal and Permutation Matrices
+
+20.3 Functions That Are Aware of These Matrices
+===============================================
+
+This section lists the built-in functions that are aware of diagonal and
+permutation matrices on input, or can return them as output.  Passed to
+other functions, these matrices will in general trigger an implicit
+conversion.  (Of course, user-defined dynamically linked functions may
+also work with diagonal or permutation matrices).
+
+* Menu:
+
+* Diagonal Matrix Functions::
+* Permutation Matrix Functions::
+
+
+File: octave.info,  Node: Diagonal Matrix Functions,  Next: Permutation Matrix Functions,  Up: Function Support
+
+20.3.1 Diagonal Matrix Functions
+--------------------------------
+
+"inv" and "pinv" can be applied to a diagonal matrix, yielding again a
+diagonal matrix.  "det" will use an efficient straightforward
+calculation when given a diagonal matrix, as well as "cond".  The
+following mapper functions can be applied to a diagonal matrix without
+converting it to a full one: "abs", "real", "imag", "conj", "sqrt".  A
+diagonal matrix can also be returned from the "balance" and "svd"
+functions.  The "sparse" function will convert a diagonal matrix
+efficiently to a sparse matrix.
+
+
+File: octave.info,  Node: Permutation Matrix Functions,  Prev: Diagonal Matrix Functions,  Up: Function Support
+
+20.3.2 Permutation Matrix Functions
+-----------------------------------
+
+"inv" and "pinv" will invert a permutation matrix, preserving its
+specialness.  "det" can be applied to a permutation matrix, efficiently
+calculating the sign of the permutation (which is equal to the
+determinant).
+
+   A permutation matrix can also be returned from the built-in functions
+"lu" and "qr", if a pivoted factorization is requested.
+
+   The "sparse" function will convert a permutation matrix efficiently
+to a sparse matrix.  The "find" function will also work efficiently
+with a permutation matrix, making it possible to conveniently obtain
+the permutation indices.
+
+
+File: octave.info,  Node: Example Codes,  Next: Zeros Treatment,  Prev: Function Support,  Up: Diagonal and Permutation Matrices
+
+20.4 Some Examples of Usage
+===========================
+
+The following can be used to solve a linear system `A*x = b' using the
+pivoted LU factorization:
+       [L, U, P] = lu (A); ## now L*U = P*A
+       x = U \ L \ P*b;
+
+This is how you normalize columns of a matrix X to unit norm:
+       s = norm (X, "columns");
+       X = diag (s) \ X;
+
+The following expression is a way to efficiently calculate the sign of a
+permutation, given by a permutation vector P.  It will also work in
+earlier versions of Octave, but slowly.
+       det (eye (length (p))(p, :))
+
+Finally, here's how you solve a linear system `A*x = b' with Tikhonov
+regularization (ridge regression) using SVD (a skeleton only):
+       m = rows (A); n = columns (A);
+       [U, S, V] = svd (A);
+       ## determine the regularization factor alpha
+       ## alpha = ...
+       ## transform to orthogonal basis
+       b = U'*b;
+       ## Use the standard formula, replacing A with S.
+       ## S is diagonal, so the following will be very fast and accurate.
+       x = (S'*S + alpha^2 * eye (n)) \ (S' * b);
+       ## transform to solution basis
+       x = V*x;
+
+
+File: octave.info,  Node: Zeros Treatment,  Prev: Example Codes,  Up: Diagonal and Permutation Matrices
+
+20.5 The Differences in Treatment of Zero Elements
+==================================================
+
+Making diagonal and permutation matrices special matrix objects in
+their own right and the consequent usage of smarter algorithms for
+certain operations implies, as a side effect, small differences in
+treating zeros.  The contents of this section applies also to sparse
+matrices, discussed in the following chapter.
+
+   The IEEE standard defines the result of the expressions `0*Inf' and
+`0*NaN' as `NaN', as it has been generally agreed that this is the best
+compromise.  Numerical software dealing with structured and sparse
+matrices (including Octave) however, almost always makes a distinction
+between a "numerical zero" and an "assumed zero".  A "numerical zero"
+is a zero value occurring in a place where any floating-point value
+could occur.  It is normally stored somewhere in memory as an explicit
+value.  An "assumed zero", on the contrary, is a zero matrix element
+implied by the matrix structure (diagonal, triangular) or a sparsity
+pattern; its value is usually not stored explicitly anywhere, but is
+implied by the underlying data structure.
+
+   The primary distinction is that an assumed zero, when multiplied by
+any number, or divided by any nonzero number, yields *always* a zero,
+even when, e.g., multiplied by `Inf' or divided by `NaN'.  The reason
+for this behavior is that the numerical multiplication is not actually
+performed anywhere by the underlying algorithm; the result is just
+assumed to be zero.  Equivalently, one can say that the part of the
+computation involving assumed zeros is performed symbolically, not
+numerically.
+
+   This behavior not only facilitates the most straightforward and
+efficient implementation of algorithms, but also preserves certain
+useful invariants, like:
+   * scalar * diagonal matrix is a diagonal matrix
+
+   * sparse matrix / scalar preserves the sparsity pattern
+
+   * permutation matrix * matrix is equivalent to permuting rows
+   all of these natural mathematical truths would be invalidated by
+treating assumed zeros as numerical ones.
+
+   Note that certain competing software does not strictly follow this
+principle and converts assumed zeros to numerical zeros in certain
+cases, while not doing so in other cases.  As of today, there are no
+intentions to mimic such behavior in Octave.
+
+   Examples of effects of assumed zeros vs. numerical zeros:
+     Inf * eye (3)
+     =>
+        Inf     0     0
+          0   Inf     0
+          0     0   Inf
+
+     Inf * speye (3)
+     =>
+     Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%])
+
+       (1, 1) -> Inf
+       (2, 2) -> Inf
+       (3, 3) -> Inf
+
+     Inf * full (eye (3))
+     =>
+        Inf   NaN   NaN
+        NaN   Inf   NaN
+        NaN   NaN   Inf
+
+     diag(1:3) * [NaN; 1; 1]
+     =>
+        NaN
+          2
+          3
+
+     sparse(1:3,1:3,1:3) * [NaN; 1; 1]
+     =>
+        NaN
+          2
+          3
+     [1,0,0;0,2,0;0,0,3] * [NaN; 1; 1]
+     =>
+        NaN
+        NaN
+        NaN
+
+
+File: octave.info,  Node: Sparse Matrices,  Next: Numerical Integration,  Prev: Diagonal and Permutation Matrices,  Up: Top
+
+21 Sparse Matrices
+******************
+
+* Menu:
+
+* Basics::                      Creation and Manipulation of Sparse Matrices
+* Sparse Linear Algebra::       Linear Algebra on Sparse Matrices
+* Iterative Techniques::        Iterative Techniques
+* Real Life Example::           Using Sparse Matrices
+
+
+File: octave.info,  Node: Basics,  Next: Sparse Linear Algebra,  Up: Sparse Matrices
+
+21.1 The Creation and Manipulation of Sparse Matrices
+=====================================================
+
+The size of mathematical problems that can be treated at any particular
+time is generally limited by the available computing resources.  Both,
+the speed of the computer and its available memory place limitation on
+the problem size.
+
+   There are many classes of mathematical problems which give rise to
+matrices, where a large number of the elements are zero.  In this case
+it makes sense to have a special matrix type to handle this class of
+problems where only the non-zero elements of the matrix are stored.
+Not only does this reduce the amount of memory to store the matrix, but
+it also means that operations on this type of matrix can take advantage
+of the a-priori knowledge of the positions of the non-zero elements to
+accelerate their calculations.
+
+   A matrix type that stores only the non-zero elements is generally
+called sparse.  It is the purpose of this document to discuss the
+basics of the storage and creation of sparse matrices and the
+fundamental operations on them.
+
+* Menu:
+
+* Storage of Sparse Matrices::
+* Creating Sparse Matrices::
+* Information::
+* Operators and Functions::
+
+
+File: octave.info,  Node: Storage of Sparse Matrices,  Next: Creating Sparse Matrices,  Up: Basics
+
+21.1.1 Storage of Sparse Matrices
+---------------------------------
+
+It is not strictly speaking necessary for the user to understand how
+sparse matrices are stored.  However, such an understanding will help
+to get an understanding of the size of sparse matrices.  Understanding
+the storage technique is also necessary for those users wishing to
+create their own oct-files.
+
+   There are many different means of storing sparse matrix data.  What
+all of the methods have in common is that they attempt to reduce the
+complexity and storage given a-priori knowledge of the particular class
+of problems that will be solved.  A good summary of the available
+techniques for storing sparse matrix is given by Saad (1).  With full
+matrices, knowledge of the point of an element of the matrix within the
+matrix is implied by its position in the computers memory.  However,
+this is not the case for sparse matrices, and so the positions of the
+non-zero elements of the matrix must equally be stored.
+
+   An obvious way to do this is by storing the elements of the matrix as
+triplets, with two elements being their position in the array (rows and
+column) and the third being the data itself.  This is conceptually easy
+to grasp, but requires more storage than is strictly needed.
+
+   The storage technique used within Octave is the compressed column
+format.  In this format the position of each element in a row and the
+data are stored as previously.  However, if we assume that all elements
+in the same column are stored adjacent in the computers memory, then we
+only need to store information on the number of non-zero elements in
+each column, rather than their positions.  Thus assuming that the
+matrix has more non-zero elements than there are columns in the matrix,
+we win in terms of the amount of memory used.
+
+   In fact, the column index contains one more element than the number
+of columns, with the first element always being zero.  The advantage of
+this is a simplification in the code, in that there is no special case
+for the first or last columns.  A short example, demonstrating this in
+C is.
+
+       for (j = 0; j < nc; j++)
+         for (i = cidx (j); i < cidx(j+1); i++)
+            printf ("non-zero element (%i,%i) is %d\n",
+     	   ridx(i), j, data(i));
+
+   A clear understanding might be had by considering an example of how
+the above applies to an example matrix.  Consider the matrix
+
+         1   2   0  0
+         0   0   0  3
+         0   0   0  4
+
+   The non-zero elements of this matrix are
+
+        (1, 1)  => 1
+        (1, 2)  => 2
+        (2, 4)  => 3
+        (3, 4)  => 4
+
+   This will be stored as three vectors CIDX, RIDX and DATA,
+representing the column indexing, row indexing and data respectively.
+The contents of these three vectors for the above matrix will be
+
+       CIDX = [0, 1, 2, 2, 4]
+       RIDX = [0, 0, 1, 2]
+       DATA = [1, 2, 3, 4]
+
+   Note that this is the representation of these elements with the
+first row and column assumed to start at zero, while in Octave itself
+the row and column indexing starts at one.  Thus the number of elements
+in the I-th column is given by `CIDX (I + 1) - CIDX (I)'.
+
+   Although Octave uses a compressed column format, it should be noted
+that compressed row formats are equally possible.  However, in the
+context of mixed operations between mixed sparse and dense matrices, it
+makes sense that the elements of the sparse matrices are in the same
+order as the dense matrices.  Octave stores dense matrices in column
+major ordering, and so sparse matrices are equally stored in this
+manner.
+
+   A further constraint on the sparse matrix storage used by Octave is
+that all elements in the rows are stored in increasing order of their
+row index, which makes certain operations faster.  However, it imposes
+the need to sort the elements on the creation of sparse matrices.
+Having disordered elements is potentially an advantage in that it makes
+operations such as concatenating two sparse matrices together easier
+and faster, however it adds complexity and speed problems elsewhere.
+
+   ---------- Footnotes ----------
+
+   (1) Youcef Saad "SPARSKIT: A basic toolkit for sparse matrix
+computation", 1994,
+`http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps'
+
+
+File: octave.info,  Node: Creating Sparse Matrices,  Next: Information,  Prev: Storage of Sparse Matrices,  Up: Basics
+
+21.1.2 Creating Sparse Matrices
+-------------------------------
+
+There are several means to create sparse matrix.
+
+Returned from a function
+     There are many functions that directly return sparse matrices.
+     These include "speye", "sprand", "diag", etc.
+
+Constructed from matrices or vectors
+     The function "sparse" allows a sparse matrix to be constructed from
+     three vectors representing the row, column and data.
+     Alternatively, the function "spconvert" uses a three column matrix
+     format to allow easy importation of data from elsewhere.
+
+Created and then filled
+     The function "sparse" or "spalloc" can be used to create an empty
+     matrix that is then filled by the user
+
+From a user binary program
+     The user can directly create the sparse matrix within an oct-file.
+
+   There are several basic functions to return specific sparse
+matrices.  For example the sparse identity matrix, is a matrix that is
+often needed.  It therefore has its own function to create it as `speye
+(N)' or `speye (R, C)', which creates an N-by-N or R-by-C sparse
+identity matrix.
+
+   Another typical sparse matrix that is often needed is a random
+distribution of random elements.  The functions "sprand" and "sprandn"
+perform this for uniform and normal random distributions of elements.
+They have exactly the same calling convention, where `sprand (R, C, D)',
+creates an R-by-C sparse matrix with a density of filled elements of D.
+
+   Other functions of interest that directly create sparse matrices, are
+"diag" or its generalization "spdiags", that can take the definition of
+the diagonals of the matrix and create the sparse matrix that
+corresponds to this.  For example
+
+     s = diag (sparse(randn(1,n)), -1);
+
+   creates a sparse (N+1)-by-(N+1) sparse matrix with a single diagonal
+defined.
+
+ -- Function File: [B, C] = spdiags (A)
+ -- Function File: B = spdiags (A, C)
+ -- Function File: B = spdiags (V, C, A)
+ -- Function File: B = spdiags (V, C, M, N)
+     A generalization of the function `diag'.  Called with a single
+     input argument, the non-zero diagonals C of A are extracted.  With
+     two arguments the diagonals to extract are given by the vector C.
+
+     The other two forms of `spdiags' modify the input matrix by
+     replacing the diagonals.  They use the columns of V to replace the
+     columns represented by the vector C.  If the sparse matrix A is
+     defined then the diagonals of this matrix are replaced.  Otherwise
+     a matrix of M by N is created with the diagonals given by V.
+
+     Negative values of C represent diagonals below the main diagonal,
+     and positive values of C diagonals above the main diagonal.
+
+     For example
+
+          spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
+          =>    5 10  0  0
+                1  6 11  0
+                0  2  7 12
+                0  0  3  8
+                0  0  0  4
+
+
+ -- Function File: Y = speye (M)
+ -- Function File: Y = speye (M, N)
+ -- Function File: Y = speye (SZ)
+     Returns a sparse identity matrix.  This is significantly more
+     efficient than `sparse (eye (M))' as the full matrix is not
+     constructed.
+
+     Called with a single argument a square matrix of size M by M is
+     created.  Otherwise a matrix of M by N is created.  If called with
+     a single vector argument, this argument is taken to be the size of
+     the matrix to create.
+
+ -- Function File: Y = spfun (F,X)
+     Compute `f(X)' for the non-zero values of X.  This results in a
+     sparse matrix with the same structure as X.  The function F can be
+     passed as a string, a function handle or an inline function.
+
+ -- Mapping Function:  spmax (X, Y, DIM)
+ -- Mapping Function: [W, IW] = spmax (X)
+     This function has been deprecated.  Use `max' instead.
+
+ -- Mapping Function:  spmin (X, Y, DIM)
+ -- Mapping Function: [W, IW] = spmin (X)
+     This function has been deprecated.  Use `min' instead.
+
+ -- Function File: Y = spones (X)
+     Replace the non-zero entries of X with ones.  This creates a
+     sparse matrix with the same structure as X.
+
+ -- Function File:  sprand (M, N, D)
+ -- Function File:  sprand (S)
+     Generate a random sparse matrix.  The size of the matrix will be M
+     by N, with a density of values given by D.  D should be between 0
+     and 1. Values will be uniformly distributed between 0 and 1.
+
+     Note: sometimes the actual density may be a bit smaller than D.
+     This is unlikely to happen for large really sparse matrices.
+
+     If called with a single matrix argument, a random sparse matrix is
+     generated wherever the matrix S is non-zero.
+
+     *See also:* *note sprandn: doc-sprandn.
+
+ -- Function File:  sprandn (M, N, D)
+ -- Function File:  sprandn (S)
+     Generate a random sparse matrix.  The size of the matrix will be M
+     by N, with a density of values given by D.  D should be between 0
+     and 1. Values will be normally distributed with mean of zero and
+     variance 1.
+
+     Note: sometimes the actual density may be a bit smaller than D.
+     This is unlikely to happen for large really sparse matrices.
+
+     If called with a single matrix argument, a random sparse matrix is
+     generated wherever the matrix S is non-zero.
+
+     *See also:* *note sprand: doc-sprand.
+
+ -- Function File:  sprandsym (N, D)
+ -- Function File:  sprandsym (S)
+     Generate a symmetric random sparse matrix.  The size of the matrix
+     will be N by N, with a density of values given by D.  D should be
+     between 0 and 1. Values will be normally distributed with mean of
+     zero and variance 1.
+
+     Note: sometimes the actual density may be a bit smaller than D.
+     This is unlikely to happen for large really sparse matrices.
+
+     If called with a single matrix argument, a random sparse matrix is
+     generated wherever the matrix S is non-zero in its lower
+     triangular part.
+
+     *See also:* *note sprand: doc-sprand, *note sprandn: doc-sprandn.
+
+   The recommended way for the user to create a sparse matrix, is to
+create two vectors containing the row and column index of the data and
+a third vector of the same size containing the data to be stored.  For
+example
+
+       ri = ci = d = [];
+       for j = 1:c
+         ri = [ri; randperm(r)(1:n)'];
+         ci = [ci; j*ones(n,1)];
+         d = [d; rand(n,1)];
+       endfor
+       s = sparse (ri, ci, d, r, c);
+
+   creates an R-by-C sparse matrix with a random distribution of N (<R)
+elements per column.  The elements of the vectors do not need to be
+sorted in any particular order as Octave will sort them prior to
+storing the data.  However, pre-sorting the data will make the creation
+of the sparse matrix faster.
+
+   The function "spconvert" takes a three or four column real matrix.
+The first two columns represent the row and column index respectively
+and the third and four columns, the real and imaginary parts of the
+sparse matrix.  The matrix can contain zero elements and the elements
+can be sorted in any order.  Adding zero elements is a convenient way
+to define the size of the sparse matrix.  For example
+
+     s = spconvert ([1 2 3 4; 1 3 4 4; 1 2 3 0]')
+     => Compressed Column Sparse (rows=4, cols=4, nnz=3)
+           (1 , 1) -> 1
+           (2 , 3) -> 2
+           (3 , 4) -> 3
+
+   An example of creating and filling a matrix might be
+
+     k = 5;
+     nz = r * k;
+     s = spalloc (r, c, nz)
+     for j = 1:c
+       idx = randperm (r);
+       s (:, j) = [zeros(r - k, 1); ...
+             rand(k, 1)] (idx);
+     endfor
+
+   It should be noted, that due to the way that the Octave assignment
+functions are written that the assignment will reallocate the memory
+used by the sparse matrix at each iteration of the above loop.
+Therefore the "spalloc" function ignores the NZ argument and does not
+preassign the memory for the matrix.  Therefore, it is vitally
+important that code using to above structure should be vectorized as
+much as possible to minimize the number of assignments and reduce the
+number of memory allocations.
+
+ -- Loadable Function: FM = full (SM)
+     returns a full storage matrix from a sparse, diagonal, permutation
+     matrix or a range.
+
+     *See also:* *note sparse: doc-sparse.
+
+ -- Function File: S = spalloc (R, C, NZ)
+     Returns an empty sparse matrix of size R-by-C.  As Octave resizes
+     sparse matrices at the first opportunity, so that no additional
+     space is needed, the argument NZ is ignored.  This function is
+     provided only for compatibility reasons.
+
+     It should be noted that this means that code like
+
+          k = 5;
+          nz = r * k;
+          s = spalloc (r, c, nz)
+          for j = 1:c
+            idx = randperm (r);
+            s (:, j) = [zeros(r - k, 1); rand(k, 1)] (idx);
+          endfor
+
+     will reallocate memory at each step.  It is therefore vitally
+     important that code like this is vectorized as much as possible.
+
+     *See also:* *note sparse: doc-sparse, *note nzmax: doc-nzmax.
+
+ -- Loadable Function: S = sparse (A)
+ -- Loadable Function: S = sparse (I, J, SV, M, N, NZMAX)
+ -- Loadable Function: S = sparse (I, J, SV)
+ -- Loadable Function: S = sparse (I, J, S, M, N, "unique")
+ -- Loadable Function: S = sparse (M, N)
+     Create a sparse matrix from the full matrix or row, column, value
+     triplets.  If A is a full matrix, convert it to a sparse matrix
+     representation, removing all zero values in the process.
+
+     Given the integer index vectors I and J, a 1-by-`nnz' vector of
+     real of complex values SV, overall dimensions M and N of the
+     sparse matrix.  The argument `nzmax' is ignored but accepted for
+     compatibility with MATLAB.  If M or N are not specified their
+     values are derived from the maximum index in the vectors I and J
+     as given by `M = max (I)', `N = max (J)'.
+
+     *Note*: if multiple values are specified with the same I, J
+     indices, the corresponding values in S will be added.
+
+     The following are all equivalent:
+
+          s = sparse (i, j, s, m, n)
+          s = sparse (i, j, s, m, n, "summation")
+          s = sparse (i, j, s, m, n, "sum")
+
+     Given the option "unique". if more than two values are specified
+     for the same I, J indices, the last specified value will be used.
+
+     `sparse(M, N)' is equivalent to `sparse ([], [], [], M, N, 0)'
+
+     If any of SV, I or J are scalars, they are expanded to have a
+     common size.
+
+     *See also:* *note full: doc-full.
+
+ -- Function File: X = spconvert (M)
+     This function converts for a simple sparse matrix format easily
+     produced by other programs into Octave's internal sparse format.
+     The input X is either a 3 or 4 column real matrix, containing the
+     row, column, real and imaginary parts of the elements of the
+     sparse matrix.  An element with a zero real and imaginary part can
+     be used to force a particular matrix size.
+
+   The above problem of memory reallocation can be avoided in
+oct-files.  However, the construction of a sparse matrix from an
+oct-file is more complex than can be discussed here, and you are
+referred to chapter *note Dynamically Linked Functions::, to have a
+full description of the techniques involved.
+
+
+File: octave.info,  Node: Information,  Next: Operators and Functions,  Prev: Creating Sparse Matrices,  Up: Basics
+
+21.1.3 Finding out Information about Sparse Matrices
+----------------------------------------------------
+
+There are a number of functions that allow information concerning
+sparse matrices to be obtained.  The most basic of these is "issparse"
+that identifies whether a particular Octave object is in fact a sparse
+matrix.
+
+   Another very basic function is "nnz" that returns the number of
+non-zero entries there are in a sparse matrix, while the function
+"nzmax" returns the amount of storage allocated to the sparse matrix.
+Note that Octave tends to crop unused memory at the first opportunity
+for sparse objects.  There are some cases of user created sparse
+objects where the value returned by "nzmax" will not be the same as
+"nnz", but in general they will give the same result.  The function
+"spstats" returns some basic statistics on the columns of a sparse
+matrix including the number of elements, the mean and the variance of
+each column.
+
+ -- Loadable Function:  issparse (EXPR)
+     Return 1 if the value of the expression EXPR is a sparse matrix.
+
+ -- Built-in Function: SCALAR = nnz (A)
+     Returns the number of non zero elements in A.
+
+     *See also:* *note sparse: doc-sparse.
+
+ -- Function File:  nonzeros (S)
+     Returns a vector of the non-zero values of the sparse matrix S.
+
+ -- Built-in Function: SCALAR = nzmax (SM)
+     Return the amount of storage allocated to the sparse matrix SM.
+     Note that Octave tends to crop unused memory at the first
+     opportunity for sparse objects.  There are some cases of user
+     created sparse objects where the value returned by "nzmax" will
+     not be the same as "nnz", but in general they will give the same
+     result.
+
+     *See also:* *note sparse: doc-sparse, *note spalloc: doc-spalloc.
+
+ -- Function File: [COUNT, MEAN, VAR] = spstats (S)
+ -- Function File: [COUNT, MEAN, VAR] = spstats (S, J)
+     Return the stats for the non-zero elements of the sparse matrix S.
+     COUNT is the number of non-zeros in each column, MEAN is the mean
+     of the non-zeros in each column, and VAR is the variance of the
+     non-zeros in each column.
+
+     Called with two input arguments, if S is the data and J is the bin
+     number for the data, compute the stats for each bin.  In this
+     case, bins can contain data values of zero, whereas with `spstats
+     (S)' the zeros may disappear.
+
+   When solving linear equations involving sparse matrices Octave
+determines the means to solve the equation based on the type of the
+matrix as discussed in *note Sparse Linear Algebra::.  Octave probes the
+matrix type when the div (/) or ldiv (\) operator is first used with
+the matrix and then caches the type.  However the "matrix_type"
+function can be used to determine the type of the sparse matrix prior
+to use of the div or ldiv operators.  For example
+
+     a = tril (sprandn(1024, 1024, 0.02), -1) ...
+         + speye(1024);
+     matrix_type (a);
+     ans = Lower
+
+   show that Octave correctly determines the matrix type for lower
+triangular matrices.  "matrix_type" can also be used to force the type
+of a matrix to be a particular type.  For example
+
+     a = matrix_type (tril (sprandn (1024, ...
+        1024, 0.02), -1) + speye(1024), 'Lower');
+
+   This allows the cost of determining the matrix type to be avoided.
+However, incorrectly defining the matrix type will result in incorrect
+results from solutions of linear equations, and so it is entirely the
+responsibility of the user to correctly identify the matrix type
+
+   There are several graphical means of finding out information about
+sparse matrices.  The first is the "spy" command, which displays the
+structure of the non-zero elements of the matrix.  *Note
+fig:spmatrix::, for an example of the use of "spy".  More advanced
+graphical information can be obtained with the "treeplot", "etreeplot"
+and "gplot" commands.
+
+ [image src="spmatrix.png" text="
+            |  * *
+            |  * * * *
+            |    * *   * *
+            |    *   *     * *
+          5 -      *   *       * *
+            |      *     *         * *
+            |        *     *           * *
+            |        *       *             *
+            |          *       *
+         10 -          *         *
+            |            *         *
+            |            *           *
+            |              *           *
+            |              *             *
+         15 -                *             *
+            |----------|---------|---------|
+                       5        10        15" ]
+Figure 21.1: Structure of simple sparse matrix.
+
+   One use of sparse matrices is in graph theory, where the
+interconnections between nodes are represented as an adjacency matrix.
+That is, if the i-th node in a graph is connected to the j-th node.
+Then the ij-th node (and in the case of undirected graphs the ji-th
+node) of the sparse adjacency matrix is non-zero.  If each node is then
+associated with a set of coordinates, then the "gplot" command can be
+used to graphically display the interconnections between nodes.
+
+   As a trivial example of the use of "gplot", consider the example
+
+     A = sparse([2,6,1,3,2,4,3,5,4,6,1,5],
+         [1,1,2,2,3,3,4,4,5,5,6,6],1,6,6);
+     xy = [0,4,8,6,4,2;5,0,5,7,5,7]';
+     gplot(A,xy)
+
+   which creates an adjacency matrix `A' where node 1 is connected to
+nodes 2 and 6, node 2 with nodes 1 and 3, etc.  The coordinates of the
+nodes are given in the n-by-2 matrix `xy'.
+
+   The dependencies between the nodes of a Cholesky factorization can be
+calculated in linear time without explicitly needing to calculate the
+Cholesky factorization by the `etree' command.  This command returns
+the elimination tree of the matrix and can be displayed graphically by
+the command `treeplot(etree(A))' if `A' is symmetric or
+`treeplot(etree(A+A'))' otherwise.
+
+ -- Function File:  spy (X)
+ -- Function File:  spy (..., MARKERSIZE)
+ -- Function File:  spy (..., LINE_SPEC)
+     Plot the sparsity pattern of the sparse matrix X.  If the argument
+     MARKERSIZE is given as an scalar value, it is used to determine the
+     point size in the plot.  If the string LINE_SPEC is given it is
+     passed to `plot' and determines the appearance of the plot.
+
+     *See also:* *note plot: doc-plot.
+
+ -- Loadable Function: P = etree (S)
+ -- Loadable Function: P = etree (S, TYP)
+ -- Loadable Function: [P, Q] = etree (S, TYP)
+     Returns the elimination tree for the matrix S.  By default S is
+     assumed to be symmetric and the symmetric elimination tree is
+     returned.  The argument TYP controls whether a symmetric or column
+     elimination tree is returned.  Valid values of TYP are 'sym' or
+     'col', for symmetric or column elimination tree respectively
+
+     Called with a second argument, "etree" also returns the postorder
+     permutations on the tree.
+
+ -- Function File:  etreeplot (TREE)
+ -- Function File:  etreeplot (TREE, NODE_STYLE, EDGE_STYLE)
+     Plot the elimination tree of the matrix S or `S+S''  if S in
+     non-symmetric.  The optional parameters LINE_STYLE and EDGE_STYLE
+     define the output style.
+
+     *See also:* *note treeplot: doc-treeplot, *note gplot: doc-gplot.
+
+ -- Function File:  gplot (A, XY)
+ -- Function File:  gplot (A, XY, LINE_STYLE)
+ -- Function File: [X, Y] = gplot (A, XY)
+     Plot a graph defined by A and XY in the graph theory sense.  A is
+     the adjacency matrix of the array to be plotted and XY is an
+     N-by-2 matrix containing the coordinates of the nodes of the graph.
+
+     The optional parameter LINE_STYLE defines the output style for the
+     plot.  Called with no output arguments the graph is plotted
+     directly.  Otherwise, return the coordinates of the plot in X and
+     Y.
+
+     *See also:* *note treeplot: doc-treeplot, *note etreeplot:
+     doc-etreeplot, *note spy: doc-spy.
+
+ -- Function File:  treeplot (TREE)
+ -- Function File:  treeplot (TREE, LINE_STYLE, EDGE_STYLE)
+     Produces a graph of tree or forest.  The first argument is vector
+     of predecessors, optional parameters LINE_STYLE and EDGE_STYLE
+     define the output style.  The complexity of the algorithm is O(n)
+     in terms of is time and memory requirements.
+
+     *See also:* *note etreeplot: doc-etreeplot, *note gplot: doc-gplot.
+
+ -- Function File:  treelayout (TREE)
+ -- Function File:  treelayout (TREE, PERMUTATION)
+     treelayout lays out a tree or a forest.  The first argument TREE
+     is a vector of predecessors, optional parameter PERMUTATION is an
+     optional postorder permutation.  The complexity of the algorithm
+     is O(n) in terms of time and memory requirements.
+
+     *See also:* *note etreeplot: doc-etreeplot, *note gplot:
+     doc-gplot, *note treeplot: doc-treeplot.
+
+
+File: octave.info,  Node: Operators and Functions,  Prev: Information,  Up: Basics
+
+21.1.4 Basic Operators and Functions on Sparse Matrices
+-------------------------------------------------------
+
+* Menu:
+
+* Sparse Functions::
+* Return Types of Operators and Functions::
+* Mathematical Considerations::
+
+
+File: octave.info,  Node: Sparse Functions,  Next: Return Types of Operators and Functions,  Up: Operators and Functions
+
+21.1.4.1 Sparse Functions
+.........................
+
+An important consideration in the use of the sparse functions of Octave
+is that many of the internal functions of Octave, such as "diag",
+cannot accept sparse matrices as an input.  The sparse implementation
+in Octave therefore uses the "dispatch" function to overload the normal
+Octave functions with equivalent functions that work with sparse
+matrices.  However, at any time the sparse matrix specific version of
+the function can be used by explicitly calling its function name.
+
+   The table below lists all of the sparse functions of Octave.  Note
+that the names of the specific sparse forms of the functions are
+typically the same as the general versions with a "sp" prefix.  In the
+table below, and the rest of this article the specific sparse versions
+of the functions are used.
+
+Generate sparse matrices:
+     "spalloc", "spdiags", "speye", "sprand",   "sprandn", "sprandsym"
+
+Sparse matrix conversion:
+     "full", "sparse", "spconvert"
+
+Manipulate sparse matrices
+     "issparse", "nnz", "nonzeros", "nzmax",   "spfun", "spones", "spy"
+
+Graph Theory:
+     "etree", "etreeplot", "gplot",   "treeplot"
+
+Sparse matrix reordering:
+     "amd", "ccolamd", "colamd", "colperm", "csymamd",   "dmperm",
+     "symamd", "randperm", "symrcm"
+
+Linear algebra:
+     "condest", "eigs", "matrix_type", "normest", "sprank",
+     "spaugment", "svds"
+
+Iterative techniques:
+     "luinc", "pcg", "pcr"
+
+Miscellaneous:
+     "spparms", "symbfact", "spstats"
+
+   In addition all of the standard Octave mapper functions (i.e., basic
+math functions that take a single argument) such as "abs", etc.  can
+accept sparse matrices.  The reader is referred to the documentation
+supplied with these functions within Octave itself for further details.
+
+
+File: octave.info,  Node: Return Types of Operators and Functions,  Next: Mathematical Considerations,  Prev: Sparse Functions,  Up: Operators and Functions
+
+21.1.4.2 The Return Types of Operators and Functions
+....................................................
+
+The two basic reasons to use sparse matrices are to reduce the memory
+usage and to not have to do calculations on zero elements.  The two are
+closely related in that the computation time on a sparse matrix operator
+or function is roughly linear with the number of non-zero elements.
+
+   Therefore, there is a certain density of non-zero elements of a
+matrix where it no longer makes sense to store it as a sparse matrix,
+but rather as a full matrix.  For this reason operators and functions
+that have a high probability of returning a full matrix will always
+return one.  For example adding a scalar constant to a sparse matrix
+will almost always make it a full matrix, and so the example
+
+     speye(3) + 0
+     =>   1  0  0
+       0  1  0
+       0  0  1
+
+   returns a full matrix as can be seen.
+
+   Additionally, if `sparse_auto_mutate' is true, all sparse functions
+test the amount of memory occupied by the sparse matrix to see if the
+amount of storage used is larger than the amount used by the full
+equivalent.  Therefore `speye (2) * 1' will return a full matrix as the
+memory used is smaller for the full version than the sparse version.
+
+   As all of the mixed operators and functions between full and sparse
+matrices exist, in general this does not cause any problems.  However,
+one area where it does cause a problem is where a sparse matrix is
+promoted to a full matrix, where subsequent operations would resparsify
+the matrix.  Such cases are rare, but can be artificially created, for
+example `(fliplr(speye(3)) + speye(3)) - speye(3)' gives a full matrix
+when it should give a sparse one.  In general, where such cases occur,
+they impose only a small memory penalty.
+
+   There is however one known case where this behavior of Octave's
+sparse matrices will cause a problem.  That is in the handling of the
+"diag" function.  Whether "diag" returns a sparse or full matrix
+depending on the type of its input arguments.  So
+
+      a = diag (sparse([1,2,3]), -1);
+
+   should return a sparse matrix.  To ensure this actually happens, the
+"sparse" function, and other functions based on it like "speye", always
+returns a sparse matrix, even if the memory used will be larger than
+its full representation.
+
+ -- Built-in Function: VAL = sparse_auto_mutate ()
+ -- Built-in Function: OLD_VAL = sparse_auto_mutate (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will automatically mutate sparse matrices to real matrices to save
+     memory.  For example,
+
+          s = speye(3);
+          sparse_auto_mutate (false)
+          s (:, 1) = 1;
+          typeinfo (s)
+          => sparse matrix
+          sparse_auto_mutate (true)
+          s (1, :) = 1;
+          typeinfo (s)
+          => matrix
+
+   Note that the `sparse_auto_mutate' option is incompatible with
+MATLAB, and so it is off by default.
+
+
+File: octave.info,  Node: Mathematical Considerations,  Prev: Return Types of Operators and Functions,  Up: Operators and Functions
+
+21.1.4.3 Mathematical Considerations
+....................................
+
+The attempt has been made to make sparse matrices behave in exactly the
+same manner as there full counterparts.  However, there are certain
+differences and especially differences with other products sparse
+implementations.
+
+   Firstly, the "./" and ".^" operators must be used with care.
+Consider what the examples
+
+       s = speye (4);
+       a1 = s .^ 2;
+       a2 = s .^ s;
+       a3 = s .^ -2;
+       a4 = s ./ 2;
+       a5 = 2 ./ s;
+       a6 = s ./ s;
+
+   will give.  The first example of S raised to the power of 2 causes
+no problems.  However S raised element-wise to itself involves a large
+number of terms `0 .^ 0' which is 1. There `S .^ S' is a full matrix.
+
+   Likewise `S .^ -2' involves terms like `0 .^ -2' which is infinity,
+and so `S .^ -2' is equally a full matrix.
+
+   For the "./" operator `S ./ 2' has no problems, but `2 ./ S'
+involves a large number of infinity terms as well and is equally a full
+matrix.  The case of `S ./ S' involves terms like `0 ./ 0' which is a
+`NaN' and so this is equally a full matrix with the zero elements of S
+filled with `NaN' values.
+
+   The above behavior is consistent with full matrices, but is not
+consistent with sparse implementations in other products.
+
+   A particular problem of sparse matrices comes about due to the fact
+that as the zeros are not stored, the sign-bit of these zeros is
+equally not stored.  In certain cases the sign-bit of zero is
+important.  For example
+
+      a = 0 ./ [-1, 1; 1, -1];
+      b = 1 ./ a
+      => -Inf            Inf
+          Inf           -Inf
+      c = 1 ./ sparse (a)
+      =>  Inf            Inf
+          Inf            Inf
+
+   To correct this behavior would mean that zero elements with a
+negative sign-bit would need to be stored in the matrix to ensure that
+their sign-bit was respected.  This is not done at this time, for
+reasons of efficiency, and so the user is warned that calculations
+where the sign-bit of zero is important must not be done using sparse
+matrices.
+
+   In general any function or operator used on a sparse matrix will
+result in a sparse matrix with the same or a larger number of non-zero
+elements than the original matrix.  This is particularly true for the
+important case of sparse matrix factorizations.  The usual way to
+address this is to reorder the matrix, such that its factorization is
+sparser than the factorization of the original matrix.  That is the
+factorization of `L * U = P * S * Q' has sparser terms `L' and `U' than
+the equivalent factorization `L * U = S'.
+
+   Several functions are available to reorder depending on the type of
+the matrix to be factorized.  If the matrix is symmetric
+positive-definite, then "symamd" or "csymamd" should be used.  Otherwise
+"amd", "colamd" or "ccolamd" should be used.  For completeness the
+reordering functions "colperm" and "randperm" are also available.
+
+   *Note fig:simplematrix::, for an example of the structure of a simple
+positive definite matrix.
+
+ [image src="spmatrix.png" text="
+            |  * *
+            |  * * * *
+            |    * *   * *
+            |    *   *     * *
+          5 -      *   *       * *
+            |      *     *         * *
+            |        *     *           * *
+            |        *       *             *
+            |          *       *
+         10 -          *         *
+            |            *         *
+            |            *           *
+            |              *           *
+            |              *             *
+         15 -                *             *
+            |----------|---------|---------|
+                       5        10        15" ]
+Figure 21.2: Structure of simple sparse matrix.
+
+   The standard Cholesky factorization of this matrix can be obtained
+by the same command that would be used for a full matrix.  This can be
+visualized with the command `r = chol(A); spy(r);'.  *Note
+fig:simplechol::.  The original matrix had 43 non-zero terms, while
+this Cholesky factorization has 71, with only half of the symmetric
+matrix being stored.  This is a significant level of fill in, and
+although not an issue for such a small test case, can represents a
+large overhead in working with other sparse matrices.
+
+   The appropriate sparsity preserving permutation of the original
+matrix is given by "symamd" and the factorization using this reordering
+can be visualized using the command `q = symamd(A); r = chol(A(q,q));
+spy(r)'.  This gives 29 non-zero terms which is a significant
+improvement.
+
+   The Cholesky factorization itself can be used to determine the
+appropriate sparsity preserving reordering of the matrix during the
+factorization, In that case this might be obtained with three return
+arguments as r`[r, p, q] = chol(A); spy(r)'.
+
+ [image src="spchol.png" text="
+            |  * *
+            |    * * *
+            |      * * * *
+            |        * * * * *
+          5 -          * * * * * *
+            |            * * * * * * *
+            |              * * * * * * * *
+            |                * * * * * * * *
+            |                  * * * * * * *
+         10 -                    * * * * * *
+            |                      * * * * *
+            |                        * * * *
+            |                          * * *
+            |                            * *
+         15 -                              *
+            |----------|---------|---------|
+                       5        10        15" ]
+Figure 21.3: Structure of the un-permuted Cholesky factorization of the
+above matrix.
+
+ [image src="spcholperm.png" text="
+            |  * *
+            |    *       *
+            |      *   *
+            |        * *
+          5 -          * *
+            |            *                 *
+            |              *   *
+            |                * *
+            |                  *       *
+         10 -                    *   *
+            |                      * *
+            |                        * *
+            |                          *   *
+            |                            * *
+         15 -                              *
+            |----------|---------|---------|
+                       5        10        15" ]
+Figure 21.4: Structure of the permuted Cholesky factorization of the
+above matrix.
+
+   In the case of an asymmetric matrix, the appropriate sparsity
+preserving permutation is "colamd" and the factorization using this
+reordering can be visualized using the command `q = colamd(A); [l, u,
+p] = lu(A(:,q)); spy(l+u)'.
+
+   Finally, Octave implicitly reorders the matrix when using the div (/)
+and ldiv (\) operators, and so no the user does not need to explicitly
+reorder the matrix to maximize performance.
+
+ -- Loadable Function: P = amd (S)
+ -- Loadable Function: P = amd (S, OPTS)
+     Returns the approximate minimum degree permutation of a matrix.
+     This permutation such that the Cholesky factorization of `S (P,
+     P)' tends to be sparser than the Cholesky factorization of S
+     itself.  `amd' is typically faster than `symamd' but serves a
+     similar purpose.
+
+     The optional parameter OPTS is a structure that controls the
+     behavior of `amd'.  The fields of these structure are
+
+    opts.dense
+          Determines what `amd' considers to be a dense row or column
+          of the input matrix.  Rows or columns with more than `max(16,
+          (dense * sqrt (N)' entries, where N is the order of the
+          matrix S, are ignored by `amd' during the calculation of the
+          permutation The value of dense must be a positive scalar and
+          its default value is 10.0
+
+    opts.aggressive
+          If this value is a non zero scalar, then `amd' performs
+          aggressive absorption.  The default is not to perform
+          aggressive absorption.
+
+     The author of the code itself is Timothy A. Davis
+     (davis at cise.ufl.edu), University of Florida (see
+     `http://www.cise.ufl.edu/research/sparse/amd').
+
+     *See also:* *note symamd: doc-symamd, *note colamd: doc-colamd.
+
+ -- Loadable Function: P = ccolamd (S)
+ -- Loadable Function: P = ccolamd (S, KNOBS)
+ -- Loadable Function: P = ccolamd (S, KNOBS, CMEMBER)
+ -- Loadable Function: [P, STATS] = ccolamd (...)
+     Constrained column approximate minimum degree permutation.  `P =
+     ccolamd (S)' returns the column approximate minimum degree
+     permutation vector for the sparse matrix S.  For a non-symmetric
+     matrix S, `S (:, P)' tends to have sparser LU factors than S.
+     `chol (S (:, P)' * S (:, P))' also tends to be sparser than `chol
+     (S' * S)'.  `P = ccolamd (S, 1)' optimizes the ordering for `lu (S
+     (:, P))'.  The ordering is followed by a column elimination tree
+     post-ordering.
+
+     KNOBS is an optional one- to five-element input vector, with a
+     default value of `[0 10 10 1 0]' if not present or empty.  Entries
+     not present are set to their defaults.
+
+    `KNOBS(1)'
+          if nonzero, the ordering is optimized for `lu (S (:, p))'.
+          It will be a poor ordering for `chol (S (:, P)' * S (:, P))'.
+          This is the most important knob for ccolamd.
+
+    `KNOB(2)'
+          if S is m-by-n, rows with more than `max (16, KNOBS (2) *
+          sqrt (n))' entries are ignored.
+
+    `KNOB(3)'
+          columns with more than `max (16, KNOBS (3) * sqrt (min (M,
+          N)))' entries are ignored and ordered last in the output
+          permutation (subject to the cmember constraints).
+
+    `KNOB(4)'
+          if nonzero, aggressive absorption is performed.
+
+    `KNOB(5)'
+          if nonzero, statistics and knobs are printed.
+
+
+     CMEMBER is an optional vector of length n.  It defines the
+     constraints on the column ordering.  If `CMEMBER (j) = C', then
+     column J is in constraint set C (C must be in the range 1 to N).
+     In the output permutation P, all columns in set 1 appear first,
+     followed by all columns in set 2, and so on.  `CMEMBER =
+     ones(1,n)' if not present or empty.  `ccolamd (S, [], 1 : N)'
+     returns `1 : N'
+
+     `P = ccolamd (S)' is about the same as `P = colamd (S)'.  KNOBS
+     and its default values differ.  `colamd' always does aggressive
+     absorption, and it finds an ordering suitable for both `lu (S (:,
+     P))' and `chol (S (:, P)' * S (:, P))'; it cannot optimize its
+     ordering for `lu (S (:, P))' to the extent that `ccolamd (S, 1)'
+     can.
+
+     STATS is an optional 20-element output vector that provides data
+     about the ordering and the validity of the input matrix S.
+     Ordering statistics are in `STATS (1 : 3)'.  `STATS (1)' and
+     `STATS (2)' are the number of dense or empty rows and columns
+     ignored by CCOLAMD and `STATS (3)' is the number of garbage
+     collections performed on the internal data structure used by
+     CCOLAMD (roughly of size `2.2 * nnz (S) + 4 * M + 7 * N' integers).
+
+     `STATS (4 : 7)' provide information if CCOLAMD was able to
+     continue.  The matrix is OK if `STATS (4)' is zero, or 1 if
+     invalid.  `STATS (5)' is the rightmost column index that is
+     unsorted or contains duplicate entries, or zero if no such column
+     exists.  `STATS (6)' is the last seen duplicate or out-of-order row
+     index in the column index given by `STATS (5)', or zero if no such
+     row index exists.  `STATS (7)' is the number of duplicate or
+     out-of-order row indices.  `STATS (8 : 20)' is always zero in the
+     current version of CCOLAMD (reserved for future use).
+
+     The authors of the code itself are S. Larimore, T. Davis (Uni of
+     Florida) and S. Rajamanickam in collaboration with J. Bilbert and
+     E. Ng.  Supported by the National Science Foundation (DMS-9504974,
+     DMS-9803599, CCR-0203270), and a grant from Sandia National Lab.
+     See `http://www.cise.ufl.edu/research/sparse' for ccolamd,
+     csymamd, amd, colamd, symamd, and other related orderings.
+
+     *See also:* *note colamd: doc-colamd, *note csymamd: doc-csymamd.
+
+ -- Loadable Function: P = colamd (S)
+ -- Loadable Function: P = colamd (S, KNOBS)
+ -- Loadable Function: [P, STATS] = colamd (S)
+ -- Loadable Function: [P, STATS] = colamd (S, KNOBS)
+     Column approximate minimum degree permutation.  `P = colamd (S)'
+     returns the column approximate minimum degree permutation vector
+     for the sparse matrix S.  For a non-symmetric matrix S, `S (:,P)'
+     tends to have sparser LU factors than S.  The Cholesky
+     factorization of `S (:,P)' * S (:,P)' also tends to be sparser
+     than that of `S' * S'.
+
+     KNOBS is an optional one- to three-element input vector.  If S is
+     m-by-n, then rows with more than `max(16,KNOBS(1)*sqrt(n))' entries
+     are ignored.  Columns with more than
+     `max(16,knobs(2)*sqrt(min(m,n)))' entries are removed prior to
+     ordering, and ordered last in the output permutation P.  Only
+     completely dense rows or columns are removed if `KNOBS (1)' and
+     `KNOBS (2)' are < 0, respectively.  If `KNOBS (3)' is nonzero,
+     STATS and KNOBS are printed.  The default is `KNOBS = [10 10 0]'.
+     Note that KNOBS differs from earlier versions of colamd
+
+     STATS is an optional 20-element output vector that provides data
+     about the ordering and the validity of the input matrix S.
+     Ordering statistics are in `STATS (1:3)'.  `STATS (1)' and `STATS
+     (2)' are the number of dense or empty rows and columns ignored by
+     COLAMD and `STATS (3)' is the number of garbage collections
+     performed on the internal data structure used by COLAMD (roughly
+     of size `2.2 * nnz(S) + 4 * M + 7 * N' integers).
+
+     Octave built-in functions are intended to generate valid sparse
+     matrices, with no duplicate entries, with ascending row indices of
+     the nonzeros in each column, with a non-negative number of entries
+     in each column (!)  and so on.  If a matrix is invalid, then
+     COLAMD may or may not be able to continue.  If there are duplicate
+     entries (a row index appears two or more times in the same column)
+     or if the row indices in a column are out of order, then COLAMD
+     can correct these errors by ignoring the duplicate entries and
+     sorting each column of its internal copy of the matrix S (the
+     input matrix S is not repaired, however).  If a matrix is invalid
+     in other ways then COLAMD cannot continue, an error message is
+     printed, and no output arguments (P or STATS) are returned.
+     COLAMD is thus a simple way to check a sparse matrix to see if it's
+     valid.
+
+     `STATS (4:7)' provide information if COLAMD was able to continue.
+     The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS
+     (5)' is the rightmost column index that is unsorted or contains
+     duplicate entries, or zero if no such column exists.  `STATS (6)'
+     is the last seen duplicate or out-of-order row index in the column
+     index given by `STATS (5)', or zero if no such row index exists.
+     `STATS (7)' is the number of duplicate or out-of-order row
+     indices.  `STATS (8:20)' is always zero in the current version of
+     COLAMD (reserved for future use).
+
+     The ordering is followed by a column elimination tree
+     post-ordering.
+
+     The authors of the code itself are Stefan I. Larimore and Timothy
+     A.  Davis (davis at cise.ufl.edu), University of Florida.  The
+     algorithm was developed in collaboration with John Gilbert, Xerox
+     PARC, and Esmond Ng, Oak Ridge National Laboratory.  (see
+     `http://www.cise.ufl.edu/research/sparse/colamd')
+
+     *See also:* *note colperm: doc-colperm, *note symamd: doc-symamd.
+
+ -- Function File: P = colperm (S)
+     Returns the column permutations such that the columns of `S (:,
+     P)' are ordered in terms of increase number of non-zero elements.
+     If S is symmetric, then P is chosen such that `S (P, P)' orders
+     the rows and columns with increasing number of non zeros elements.
+
+ -- Loadable Function: P = csymamd (S)
+ -- Loadable Function: P = csymamd (S, KNOBS)
+ -- Loadable Function: P = csymamd (S, KNOBS, CMEMBER)
+ -- Loadable Function: [P, STATS] = csymamd (...)
+     For a symmetric positive definite matrix S, returns the permutation
+     vector P such that `S(P,P)' tends to have a sparser Cholesky
+     factor than S.  Sometimes `csymamd' works well for symmetric
+     indefinite matrices too.  The matrix S is assumed to be symmetric;
+     only the strictly lower triangular part is referenced.  S must be
+     square.  The ordering is followed by an elimination tree
+     post-ordering.
+
+     KNOBS is an optional one- to three-element input vector, with a
+     default value of `[10 1 0]' if present or empty.  Entries not
+     present are set to their defaults.
+
+    `KNOBS(1)'
+          If S is n-by-n, then rows and columns with more than
+          `max(16,KNOBS(1)*sqrt(n))' entries are ignored, and ordered
+          last in the output permutation (subject to the cmember
+          constraints).
+
+    `KNOBS(2)'
+          If nonzero, aggressive absorption is performed.
+
+    `KNOBS(3)'
+          If nonzero, statistics and knobs are printed.
+
+
+     CMEMBER is an optional vector of length n. It defines the
+     constraints on the ordering.  If `CMEMBER(j) = S', then row/column
+     j is in constraint set C (C must be in the range 1 to n).  In the
+     output permutation P, rows/columns in set 1 appear first, followed
+     by all rows/columns in set 2, and so on.  `CMEMBER = ones(1,n)' if
+     not present or empty.  `csymamd(S,[],1:n)' returns `1:n'.
+
+     `P = csymamd(S)' is about the same as `P = symamd(S)'.  KNOBS and
+     its default values differ.
+
+     `STATS (4:7)' provide information if CCOLAMD was able to continue.
+     The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS
+     (5)' is the rightmost column index that is unsorted or contains
+     duplicate entries, or zero if no such column exists.  `STATS (6)'
+     is the last seen duplicate or out-of-order row index in the column
+     index given by `STATS (5)', or zero if no such row index exists.
+     `STATS (7)' is the number of duplicate or out-of-order row
+     indices.  `STATS (8:20)' is always zero in the current version of
+     CCOLAMD (reserved for future use).
+
+     The authors of the code itself are S. Larimore, T. Davis (Uni of
+     Florida) and S. Rajamanickam in collaboration with J. Bilbert and
+     E. Ng.  Supported by the National Science Foundation (DMS-9504974,
+     DMS-9803599, CCR-0203270), and a grant from Sandia National Lab.
+     See `http://www.cise.ufl.edu/research/sparse' for ccolamd,
+     csymamd, amd, colamd, symamd, and other related orderings.
+
+     *See also:* *note symamd: doc-symamd, *note ccolamd: doc-ccolamd.
+
+ -- Loadable Function: P = dmperm (S)
+ -- Loadable Function: [P, Q, R, S] = dmperm (S)
+     Perform a Dulmage-Mendelsohn permutation on the sparse matrix S.
+     With a single output argument "dmperm" performs the row
+     permutations P such that `S (P,:)' has no zero elements on the
+     diagonal.
+
+     Called with two or more output arguments, returns the row and
+     column permutations, such that `S (P, Q)' is in block triangular
+     form.  The values of R and S define the boundaries of the blocks.
+     If S is square then `R == S'.
+
+     The method used is described in: A. Pothen & C.-J. Fan. Computing
+     the block triangular form of a sparse matrix. ACM Trans. Math.
+     Software, 16(4):303-324, 1990.
+
+     *See also:* *note colamd: doc-colamd, *note ccolamd: doc-ccolamd.
+
+ -- Loadable Function: P = symamd (S)
+ -- Loadable Function: P = symamd (S, KNOBS)
+ -- Loadable Function: [P, STATS] = symamd (S)
+ -- Loadable Function: [P, STATS] = symamd (S, KNOBS)
+     For a symmetric positive definite matrix S, returns the permutation
+     vector p such that `S (P, P)' tends to have a sparser Cholesky
+     factor than S.  Sometimes SYMAMD works well for symmetric
+     indefinite matrices too.  The matrix S is assumed to be symmetric;
+     only the strictly lower triangular part is referenced.  S must be
+     square.
+
+     KNOBS is an optional one- to two-element input vector.  If S is
+     n-by-n, then rows and columns with more than
+     `max(16,KNOBS(1)*sqrt(n))' entries are removed prior to ordering,
+     and ordered last in the output permutation P.  No rows/columns are
+     removed if `KNOBS(1) < 0'.  If `KNOBS (2)' is nonzero, `stats' and
+     KNOBS are printed.  The default is `KNOBS = [10 0]'.  Note that
+     KNOBS differs from earlier versions of symamd.
+
+     STATS is an optional 20-element output vector that provides data
+     about the ordering and the validity of the input matrix S.
+     Ordering statistics are in `STATS (1:3)'.  `STATS (1) = STATS (2)'
+     is the number of dense or empty rows and columns ignored by SYMAMD
+     and `STATS (3)' is the number of garbage collections performed on
+     the internal data structure used by SYMAMD (roughly of size `8.4 *
+     nnz (tril (S, -1)) + 9 * N' integers).
+
+     Octave built-in functions are intended to generate valid sparse
+     matrices, with no duplicate entries, with ascending row indices of
+     the nonzeros in each column, with a non-negative number of entries
+     in each column (!)  and so on.  If a matrix is invalid, then
+     SYMAMD may or may not be able to continue.  If there are duplicate
+     entries (a row index appears two or more times in the same column)
+     or if the row indices in a column are out of order, then SYMAMD
+     can correct these errors by ignoring the duplicate entries and
+     sorting each column of its internal copy of the matrix S (the
+     input matrix S is not repaired, however).  If a matrix is invalid
+     in other ways then SYMAMD cannot continue, an error message is
+     printed, and no output arguments (P or STATS) are returned.
+     SYMAMD is thus a simple way to check a sparse matrix to see if
+     it's valid.
+
+     `STATS (4:7)' provide information if SYMAMD was able to continue.
+     The matrix is OK if `STATS (4)' is zero, or 1 if invalid.  `STATS
+     (5)' is the rightmost column index that is unsorted or contains
+     duplicate entries, or zero if no such column exists.  `STATS (6)'
+     is the last seen duplicate or out-of-order row index in the column
+     index given by `STATS (5)', or zero if no such row index exists.
+     `STATS (7)' is the number of duplicate or out-of-order row
+     indices.  `STATS (8:20)' is always zero in the current version of
+     SYMAMD (reserved for future use).
+
+     The ordering is followed by a column elimination tree
+     post-ordering.
+
+     The authors of the code itself are Stefan I. Larimore and Timothy
+     A.  Davis (davis at cise.ufl.edu), University of Florida.  The
+     algorithm was developed in collaboration with John Gilbert, Xerox
+     PARC, and Esmond Ng, Oak Ridge National Laboratory.  (see
+     `http://www.cise.ufl.edu/research/sparse/colamd')
+
+     *See also:* *note colperm: doc-colperm, *note colamd: doc-colamd.
+
+ -- Loadable Function: P = symrcm (S)
+     Symmetric reverse Cuthill-McKee permutation of S.  Return a
+     permutation vector P such that `S (P, P)' tends to have its
+     diagonal elements closer to the diagonal than S.  This is a good
+     preordering for LU or Cholesky factorization of matrices that come
+     from 'long, skinny' problems.  It works for both symmetric and
+     asymmetric S.
+
+     The algorithm represents a heuristic approach to the NP-complete
+     bandwidth minimization problem.  The implementation is based in the
+     descriptions found in
+
+     E. Cuthill, J. McKee: Reducing the Bandwidth of Sparse Symmetric
+     Matrices. Proceedings of the 24th ACM National Conference, 157-172
+     1969, Brandon Press, New Jersey.
+
+     Alan George, Joseph W. H. Liu: Computer Solution of Large Sparse
+     Positive Definite Systems, Prentice Hall Series in Computational
+     Mathematics, ISBN 0-13-165274-5, 1981.
+
+     *See also:* *note colperm: doc-colperm, *note colamd: doc-colamd,
+     *note symamd: doc-symamd.
+
+
+File: octave.info,  Node: Sparse Linear Algebra,  Next: Iterative Techniques,  Prev: Basics,  Up: Sparse Matrices
+
+21.2 Linear Algebra on Sparse Matrices
+======================================
+
+Octave includes a polymorphic solver for sparse matrices, where the
+exact solver used to factorize the matrix, depends on the properties of
+the sparse matrix itself.  Generally, the cost of determining the
+matrix type is small relative to the cost of factorizing the matrix
+itself, but in any case the matrix type is cached once it is
+calculated, so that it is not re-determined each time it is used in a
+linear equation.
+
+   The selection tree for how the linear equation is solve is
+
+  1. If the matrix is diagonal, solve directly and goto 8
+
+  2. If the matrix is a permuted diagonal, solve directly taking into
+     account the permutations.  Goto 8
+
+  3. If the matrix is square, banded and if the band density is less
+     than that given by `spparms ("bandden")' continue, else goto 4.
+
+       a. If the matrix is tridiagonal and the right-hand side is not
+          sparse continue, else goto 3b.
+
+            1. If the matrix is hermitian, with a positive real
+               diagonal, attempt       Cholesky factorization using
+               LAPACK xPTSV.
+
+            2. If the above failed or the matrix is not hermitian with
+               a positive       real diagonal use Gaussian elimination
+               with pivoting using       LAPACK xGTSV, and goto 8.
+
+       b. If the matrix is hermitian with a positive real diagonal,
+          attempt       Cholesky factorization using LAPACK xPBTRF.
+
+       c. if the above failed or the matrix is not hermitian with a
+          positive       real diagonal use Gaussian elimination with
+          pivoting using       LAPACK xGBTRF, and goto 8.
+
+  4. If the matrix is upper or lower triangular perform a sparse forward
+     or backward substitution, and goto 8
+
+  5. If the matrix is a upper triangular matrix with column permutations
+     or lower triangular matrix with row permutations, perform a sparse
+     forward or backward substitution, and goto 8
+
+  6. If the matrix is square, hermitian with a real positive diagonal,
+     attempt sparse Cholesky factorization using CHOLMOD.
+
+  7. If the sparse Cholesky factorization failed or the matrix is not
+     hermitian with a real positive diagonal, and the matrix is square,
+     factorize using UMFPACK.
+
+  8. If the matrix is not square, or any of the previous solvers flags
+     a singular or near singular matrix, find a minimum norm solution
+     using CXSPARSE(1).
+
+   The band density is defined as the number of non-zero values in the
+matrix divided by the number of non-zero values in the matrix.  The
+banded matrix solvers can be entirely disabled by using "spparms" to
+set `bandden' to 1 (i.e., `spparms ("bandden", 1)').
+
+   The QR solver factorizes the problem with a Dulmage-Mendelsohn, to
+separate the problem into blocks that can be treated as over-determined,
+multiple well determined blocks, and a final over-determined block.  For
+matrices with blocks of strongly connected nodes this is a big win as
+LU decomposition can be used for many blocks.  It also significantly
+improves the chance of finding a solution to over-determined problems
+rather than just returning a vector of "NaN"'s.
+
+   All of the solvers above, can calculate an estimate of the condition
+number.  This can be used to detect numerical stability problems in the
+solution and force a minimum norm solution to be used.  However, for
+narrow banded, triangular or diagonal matrices, the cost of calculating
+the condition number is significant, and can in fact exceed the cost of
+factoring the matrix.  Therefore the condition number is not calculated
+in these cases, and Octave relies on simpler techniques to detect
+singular matrices or the underlying LAPACK code in the case of banded
+matrices.
+
+   The user can force the type of the matrix with the `matrix_type'
+function.  This overcomes the cost of discovering the type of the
+matrix.  However, it should be noted that identifying the type of the
+matrix incorrectly will lead to unpredictable results, and so
+`matrix_type' should be used with care.
+
+ -- Function File: [N, C] = normest (A, TOL)
+     Estimate the 2-norm of the matrix A using a power series analysis.
+     This is typically used for large matrices, where the cost of
+     calculating the `norm (A)' is prohibitive and an approximation to
+     the 2-norm is acceptable.
+
+     TOL is the tolerance to which the 2-norm is calculated.  By default
+     TOL is 1e-6.  C returns the number of iterations needed for
+     `normest' to converge.
+
+ -- Function File: [EST, V, W, ITER] = onenormest (A, T)
+ -- Function File: [EST, V, W, ITER] = onenormest (APPLY, APPLY_T, N, T)
+     Apply Higham and Tisseur's randomized block 1-norm estimator to
+     matrix A using T test vectors.  If T exceeds 5, then only 5 test
+     vectors are used.
+
+     If the matrix is not explicit, e.g., when estimating the norm of
+     `inv (A)' given an LU factorization, `onenormest' applies A and
+     its conjugate transpose through a pair of functions APPLY and
+     APPLY_T, respectively, to a dense matrix of size N by T.  The
+     implicit version requires an explicit dimension N.
+
+     Returns the norm estimate EST, two vectors V and W related by norm
+     `(W, 1) = EST * norm (V, 1)', and the number of iterations ITER.
+     The number of iterations is limited to 10 and is at least 2.
+
+     References:
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+          for Matrix 1-Norm Estimation, with an Application to 1-Norm
+          Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+          `http://dx.doi.org/10.1137/S0895479899356080'
+
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+          for Matrix 1-Norm Estimation, with an Application to 1-Norm
+          Pseudospectra." `http://citeseer.ist.psu.edu/223007.html'
+
+     *See also:* *note condest: doc-condest, *note norm: doc-norm,
+     *note cond: doc-cond.
+
+ -- Function File: [EST, V] = condest (A, T)
+ -- Function File: [EST, V] = condest (A, SOLVE, SOLVE_T, T)
+ -- Function File: [EST, V] = condest (APPLY, APPLY_T, SOLVE, SOLVE_T,
+          N, T)
+     Estimate the 1-norm condition number of a matrix A using T test
+     vectors using a randomized 1-norm estimator.  If T exceeds 5, then
+     only 5 test vectors are used.
+
+     If the matrix is not explicit, e.g., when estimating the condition
+     number of A given an LU factorization, `condest' uses the
+     following functions:
+
+    APPLY
+          `A*x' for a matrix `x' of size N by T.
+
+    APPLY_T
+          `A'*x' for a matrix `x' of size N by T.
+
+    SOLVE
+          `A \ b' for a matrix `b' of size N by T.
+
+    SOLVE_T
+          `A' \ b' for a matrix `b' of size N by T.
+
+     The implicit version requires an explicit dimension N.
+
+     `condest' uses a randomized algorithm to approximate the 1-norms.
+
+     `condest' returns the 1-norm condition estimate EST and a vector V
+     satisfying `norm (A*v, 1) == norm (A, 1) * norm (V, 1) / EST'.
+     When EST is large, V is an approximate null vector.
+
+     References:
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+          for Matrix 1-Norm Estimation, with an Application to 1-Norm
+          Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+          `http://dx.doi.org/10.1137/S0895479899356080'
+
+        * Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+          for Matrix 1-Norm Estimation, with an Application to 1-Norm
+          Pseudospectra." `http://citeseer.ist.psu.edu/223007.html'
+
+     *See also:* *note cond: doc-cond, *note norm: doc-norm, *note
+     onenormest: doc-onenormest.
+
+ -- Loadable Function:   spparms ()
+ -- Loadable Function: VALS = spparms ()
+ -- Loadable Function: [KEYS, VALS] = spparms ()
+ -- Loadable Function: VAL = spparms (KEY)
+ -- Loadable Function:   spparms (VALS)
+ -- Loadable Function:   spparms ('defaults')
+ -- Loadable Function:   spparms ('tight')
+ -- Loadable Function:   spparms (KEY, VAL)
+     Sets or displays the parameters used by the sparse solvers and
+     factorization functions.  The first four calls above get
+     information about the current settings, while the others change
+     the current settings.  The parameters are stored as pairs of keys
+     and values, where the values are all floats and the keys are one
+     of the following strings:
+
+    `spumoni'
+          Printing level of debugging information of the solvers
+          (default 0)
+
+    `ths_rel'
+          Included for compatibility.  Not used.  (default 1)
+
+    `ths_abs'
+          Included for compatibility.  Not used.  (default 1)
+
+    `exact_d'
+          Included for compatibility.  Not used.  (default 0)
+
+    `supernd'
+          Included for compatibility.  Not used.  (default 3)
+
+    `rreduce'
+          Included for compatibility.  Not used.  (default 3)
+
+    `wh_frac'
+          Included for compatibility.  Not used.  (default 0.5)
+
+    `autommd'
+          Flag whether the LU/QR and the '\' and '/' operators will
+          automatically use the sparsity preserving mmd functions
+          (default 1)
+
+    `autoamd'
+          Flag whether the LU and the '\' and '/' operators will
+          automatically use the sparsity preserving amd functions
+          (default 1)
+
+    `piv_tol'
+          The pivot tolerance of the UMFPACK solvers (default 0.1)
+
+    `sym_tol'
+          The pivot tolerance of the UMFPACK symmetric solvers (default
+          0.001)
+
+    `bandden'
+          The density of non-zero elements in a banded matrix before it
+          is treated by the LAPACK banded solvers (default 0.5)
+
+    `umfpack'
+          Flag whether the UMFPACK or mmd solvers are used for the LU,
+          '\' and '/' operations (default 1)
+
+     The value of individual keys can be set with `spparms (KEY, VAL)'.
+     The default values can be restored with the special keyword
+     'defaults'.  The special keyword 'tight' can be used to set the
+     mmd solvers to attempt for a sparser solution at the potential
+     cost of longer running time.
+
+ -- Loadable Function: P = sprank (S)
+     Calculates the structural rank of a sparse matrix S.  Note that
+     only the structure of the matrix is used in this calculation based
+     on a Dulmage-Mendelsohn permutation to block triangular form.  As
+     such the numerical rank of the matrix S is bounded by `sprank (S)
+     >= rank (S)'.  Ignoring floating point errors `sprank (S) == rank
+     (S)'.
+
+     *See also:* *note dmperm: doc-dmperm.
+
+ -- Loadable Function: [COUNT, H, PARENT, POST, R] = symbfact (S, TYP,
+          MODE)
+     Performs a symbolic factorization analysis on the sparse matrix S.
+     Where
+
+    S
+          S is a complex or real sparse matrix.
+
+    TYP
+          Is the type of the factorization and can be one of
+
+         `sym'
+               Factorize S.  This is the default.
+
+         `col'
+               Factorize `S' * S'.
+
+         `row'
+               Factorize `S * S''.
+
+         `lo'
+               Factorize `S''
+
+    MODE
+          The default is to return the Cholesky factorization for R,
+          and if MODE is 'L', the conjugate transpose of the Cholesky
+          factorization is returned.  The conjugate transpose version
+          is faster and uses less memory, but returns the same values
+          for COUNT, H, PARENT and POST outputs.
+
+     The output variables are
+
+    COUNT
+          The row counts of the Cholesky factorization as determined by
+          TYP.
+
+    H
+          The height of the elimination tree.
+
+    PARENT
+          The elimination tree itself.
+
+    POST
+          A sparse boolean matrix whose structure is that of the
+          Cholesky factorization as determined by TYP.
+
+   For non square matrices, the user can also utilize the `spaugment'
+function to find a least squares solution to a linear equation.
+
+ -- Function File: S = spaugment (A, C)
+     Creates the augmented matrix of A.  This is given by
+
+          [C * eye(M, M),A; A', zeros(N,
+          N)]
+
+     This is related to the least squares solution of `A \\ B', by
+
+          S * [ R / C; x] = [B, zeros(N,
+          columns(B)]
+
+     where R is the residual error
+
+          R = B - A * X
+
+     As the matrix S is symmetric indefinite it can be factorized with
+     `lu', and the minimum norm solution can therefore be found without
+     the need for a `qr' factorization.  As the residual error will be
+     `zeros (M, M)' for under determined problems, and example can be
+
+          m = 11; n = 10; mn = max(m ,n);
+          a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],
+                       [-1, 0, 1], m, n);
+          x0 = a \ ones (m,1);
+          s = spaugment (a);
+          [L, U, P, Q] = lu (s);
+          x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+          x1 = x1(end - n + 1 : end);
+
+     To find the solution of an overdetermined problem needs an estimate
+     of the residual error R and so it is more complex to formulate a
+     minimum norm solution using the `spaugment' function.
+
+     In general the left division operator is more stable and faster
+     than using the `spaugment' function.
+
+   Finally, the function `eigs' can be used to calculate a limited
+number of eigenvalues and eigenvectors based on a selection criteria
+and likewise for `svds' which calculates a limited number of singular
+values and vectors.
+
+ -- Loadable Function: D = eigs (A)
+ -- Loadable Function: D = eigs (A, K)
+ -- Loadable Function: D = eigs (A, K, SIGMA)
+ -- Loadable Function: D = eigs (A, K, SIGMA,OPTS)
+ -- Loadable Function: D = eigs (A, B)
+ -- Loadable Function: D = eigs (A, B, K)
+ -- Loadable Function: D = eigs (A, B, K, SIGMA)
+ -- Loadable Function: D = eigs (A, B, K, SIGMA, OPTS)
+ -- Loadable Function: D = eigs (AF, N)
+ -- Loadable Function: D = eigs (AF, N, B)
+ -- Loadable Function: D = eigs (AF, N, K)
+ -- Loadable Function: D = eigs (AF, N, B, K)
+ -- Loadable Function: D = eigs (AF, N, K, SIGMA)
+ -- Loadable Function: D = eigs (AF, N, B, K, SIGMA)
+ -- Loadable Function: D = eigs (AF, N, K, SIGMA, OPTS)
+ -- Loadable Function: D = eigs (AF, N, B, K, SIGMA, OPTS)
+ -- Loadable Function: [V, D] = eigs (A, ...)
+ -- Loadable Function: [V, D] = eigs (AF, N, ...)
+ -- Loadable Function: [V, D, FLAG] = eigs (A, ...)
+ -- Loadable Function: [V, D, FLAG] = eigs (AF, N, ...)
+     Calculate a limited number of eigenvalues and eigenvectors of A,
+     based on a selection criteria.  The number eigenvalues and
+     eigenvectors to calculate is given by K whose default value is 6.
+
+     By default `eigs' solve the equation `A * v = lambda * v' , where
+     `lambda' is a scalar representing one of the eigenvalues, and `v'
+     is the corresponding eigenvector.  If given the positive definite
+     matrix B then `eigs' solves the general eigenvalue equation `A * v
+     = lambda * B * v' .
+
+     The argument SIGMA determines which eigenvalues are returned.
+     SIGMA can be either a scalar or a string.  When SIGMA is a scalar,
+     the K eigenvalues closest to SIGMA are returned.  If SIGMA is a
+     string, it must have one of the values
+
+    'lm'
+          Largest magnitude (default).
+
+    'sm'
+          Smallest magnitude.
+
+    'la'
+          Largest Algebraic (valid only for real symmetric problems).
+
+    'sa'
+          Smallest Algebraic (valid only for real symmetric problems).
+
+    'be'
+          Both ends, with one more from the high-end if K is odd (valid
+          only for real symmetric problems).
+
+    'lr'
+          Largest real part (valid only for complex or unsymmetric
+          problems).
+
+    'sr'
+          Smallest real part (valid only for complex or unsymmetric
+          problems).
+
+    'li'
+          Largest imaginary part (valid only for complex or unsymmetric
+          problems).
+
+    'si'
+          Smallest imaginary part (valid only for complex or
+          unsymmetric problems).
+
+     If OPTS is given, it is a structure defining some of the options
+     that `eigs' should use.  The fields of the structure OPTS are
+
+    `issym'
+          If AF is given, then flags whether the function AF defines a
+          symmetric problem.  It is ignored if A is given.  The default
+          is false.
+
+    `isreal'
+          If AF is given, then flags whether the function AF defines a
+          real problem.  It is ignored if A is given.  The default is
+          true.
+
+    `tol'
+          Defines the required convergence tolerance, given as `tol *
+          norm (A)'.  The default is `eps'.
+
+    `maxit'
+          The maximum number of iterations.  The default is 300.
+
+    `p'
+          The number of Lanzcos basis vectors to use.  More vectors
+          will result in faster convergence, but a larger amount of
+          memory.  The optimal value of 'p' is problem dependent and
+          should be in the range K to N.  The default value is `2 * K'.
+
+    `v0'
+          The starting vector for the computation.  The default is to
+          have ARPACK randomly generate a starting vector.
+
+    `disp'
+          The level of diagnostic printout.  If `disp' is 0 then there
+          is no printout.  The default value is 1.
+
+    `cholB'
+          Flag if `chol (B)' is passed rather than B.  The default is
+          false.
+
+    `permB'
+          The permutation vector of the Cholesky factorization of B if
+          `cholB' is true.  That is `chol ( B (permB, permB))'.  The
+          default is `1:N'.
+
+
+     It is also possible to represent A by a function denoted AF.  AF
+     must be followed by a scalar argument N defining the length of the
+     vector argument accepted by AF.  AF can be passed either as an
+     inline function, function handle or as a string.  In the case where
+     AF is passed as a string, the name of the string defines the
+     function to use.
+
+     AF is a function of the form `function y = af (x), y = ...;
+     endfunction', where the required return value of AF is determined
+     by the value of SIGMA, and are
+
+    `A * x'
+          If SIGMA is not given or is a string other than 'sm'.
+
+    `A \ x'
+          If SIGMA is 'sm'.
+
+    `(A - sigma * I) \ x'
+          for standard eigenvalue problem, where `I' is the identity
+          matrix of the same size as `A'.  If SIGMA is zero, this
+          reduces the `A \ x'.
+
+    `(A - sigma * B) \ x'
+          for the general eigenvalue problem.
+
+     The return arguments of `eigs' depends on the number of return
+     arguments.  With a single return argument, a vector D of length K
+     is returned, represent the K eigenvalues that have been found.
+     With two return arguments, V is a N-by-K matrix whose columns are
+     the K eigenvectors corresponding to the returned eigenvalues.  The
+     eigenvalues themselves are then returned in D in the form of a
+     N-by-K matrix, where the elements on the diagonal are the
+     eigenvalues.
+
+     Given a third return argument FLAG, `eigs' also returns the status
+     of the convergence.  If FLAG is 0, then all eigenvalues have
+     converged, otherwise not.
+
+     This function is based on the ARPACK package, written by R Lehoucq,
+     K Maschhoff, D Sorensen and C Yang.  For more information see
+     `http://www.caam.rice.edu/software/ARPACK/'.
+
+
+*See also:* *note eig: doc-eig, *note svds: doc-svds.
+
+ -- Function File: S = svds (A)
+ -- Function File: S = svds (A, K)
+ -- Function File: S = svds (A, K, SIGMA)
+ -- Function File: S = svds (A, K, SIGMA, OPTS)
+ -- Function File: [U, S, V, FLAG] = svds (...)
+     Find a few singular values of the matrix A.  The singular values
+     are calculated using
+
+          [M, N] = size(A)
+          S = eigs([sparse(M, M), A; ...
+                          A', sparse(N, N)])
+
+     The eigenvalues returned by `eigs' correspond to the singular
+     values of A.  The number of singular values to calculate is given
+     by K, whose default value is 6.
+
+     The argument SIGMA can be used to specify which singular values to
+     find.  SIGMA can be either the string 'L', the default, in which
+     case the largest singular values of A are found.  Otherwise SIGMA
+     should be a real scalar, in which case the singular values closest
+     to SIGMA are found.  Note that for relatively small values of
+     SIGMA, there is the chance that the requested number of singular
+     values are not returned.  In that case SIGMA should be increased.
+
+     If OPTS is given, then it is a structure that defines options that
+     `svds' will pass to EIGS.  The possible fields of this structure
+     are therefore determined by `eigs'.  By default three fields of
+     this structure are set by `svds'.
+
+    `tol'
+          The required convergence tolerance for the singular values.
+          `eigs' is passed TOL divided by `sqrt(2)'.  The default value
+          is 1e-10.
+
+    `maxit'
+          The maximum number of iterations.  The default is 300.
+
+    `disp'
+          The level of diagnostic printout.  If `disp' is 0 then there
+          is no printout.  The default value is 0.
+
+     If more than one output argument is given, then `svds' also
+     calculates the left and right singular vectors of A.  FLAG is used
+     to signal the convergence of `svds'.  If `svds' converges to the
+     desired tolerance, then FLAG given by
+
+          norm (A * V - U * S, 1) <= ...
+                  TOL * norm (A, 1)
+
+     will be zero.
+
+*See also:* *note eigs: doc-eigs.
+
+   ---------- Footnotes ----------
+
+   (1) The CHOLMOD, UMFPACK and CXSPARSE packages were written by Tim
+Davis and are available at http://www.cise.ufl.edu/research/sparse/
+
+
+File: octave.info,  Node: Iterative Techniques,  Next: Real Life Example,  Prev: Sparse Linear Algebra,  Up: Sparse Matrices
+
+21.3 Iterative Techniques applied to sparse matrices
+====================================================
+
+The left division `\' and right division `/' operators, discussed in
+the previous section, use direct solvers to resolve a linear equation
+of the form `X = A \ B' or `X = B / A'.  Octave equally includes a
+number of functions to solve sparse linear equations using iterative
+techniques.
+
+ -- Function File: X = pcg (A, B, TOL, MAXIT, M1, M2, X0, ...)
+ -- Function File: [X, FLAG, RELRES, ITER, RESVEC, EIGEST] = pcg (...)
+     Solves the linear system of equations `A * X = B' by means of the
+     Preconditioned Conjugate Gradient iterative method.  The input
+     arguments are
+
+        * A can be either a square (preferably sparse) matrix or a
+          function handle, inline function or string containing the name
+          of a function which computes `A * X'.  In principle A should
+          be symmetric and positive definite; if `pcg' finds A to not
+          be positive definite, you will get a warning message and the
+          FLAG output parameter will be set.
+
+        * B is the right hand side vector.
+
+        * TOL is the required relative tolerance for the residual error,
+          `B - A * X'.  The iteration stops if `norm (B - A * X) <= TOL
+          * norm (B - A * X0)'.  If TOL is empty or is omitted, the
+          function sets `TOL = 1e-6' by default.
+
+        * MAXIT is the maximum allowable number of iterations; if `[]'
+          is supplied for `maxit', or `pcg' has less arguments, a
+          default value equal to 20 is used.
+
+        * M = M1 * M2 is the (left) preconditioning matrix, so that the
+          iteration is (theoretically) equivalent to solving by `pcg'
+          `P * X = M \ B', with `P = M \ A'.  Note that a proper choice
+          of the preconditioner may dramatically improve the overall
+          performance of the method.  Instead of matrices M1 and M2,
+          the user may pass two functions which return the results of
+          applying the inverse of M1 and M2 to a vector (usually this
+          is the preferred way of using the preconditioner).  If `[]'
+          is supplied for M1, or M1 is omitted, no preconditioning is
+          applied.  If M2 is omitted, M = M1 will be used as
+          preconditioner.
+
+        * X0 is the initial guess.  If X0 is empty or omitted, the
+          function sets X0 to a zero vector by default.
+
+     The arguments which follow X0 are treated as parameters, and
+     passed in a proper way to any of the functions (A or M) which are
+     passed to `pcg'.  See the examples below for further details.  The
+     output arguments are
+
+        * X is the computed approximation to the solution of `A * X =
+          B'.
+
+        * FLAG reports on the convergence.  `FLAG = 0' means the
+          solution converged and the tolerance criterion given by TOL
+          is satisfied.  `FLAG = 1' means that the MAXIT limit for the
+          iteration count was reached.  `FLAG = 3' reports that the
+          (preconditioned) matrix was found not positive definite.
+
+        * RELRES is the ratio of the final residual to its initial
+          value, measured in the Euclidean norm.
+
+        * ITER is the actual number of iterations performed.
+
+        * RESVEC describes the convergence history of the method.
+          `RESVEC (i,1)' is the Euclidean norm of the residual, and
+          `RESVEC (i,2)' is the preconditioned residual norm, after the
+          (I-1)-th iteration, `I = 1, 2, ..., ITER+1'.  The
+          preconditioned residual norm is defined as `norm (R) ^ 2 = R'
+          * (M \ R)' where `R = B - A * X', see also the description of
+          M.  If EIGEST is not required, only `RESVEC (:,1)' is
+          returned.
+
+        * EIGEST returns the estimate for the smallest `EIGEST (1)' and
+          largest `EIGEST (2)' eigenvalues of the preconditioned matrix
+          `P = M \ A'.  In particular, if no preconditioning is used,
+          the estimates for the extreme eigenvalues of A are returned.
+          `EIGEST (1)' is an overestimate and `EIGEST (2)' is an
+          underestimate, so that `EIGEST (2) / EIGEST (1)' is a lower
+          bound for `cond (P, 2)', which nevertheless in the limit
+          should theoretically be equal to the actual value of the
+          condition number.  The method which computes EIGEST works
+          only for symmetric positive definite A and M, and the user is
+          responsible for verifying this assumption.
+
+     Let us consider a trivial problem with a diagonal matrix (we
+     exploit the sparsity of A)
+
+          	n = 10;
+          	a = diag (sparse (1:n));
+          	b = rand (n, 1);
+               [l, u, p, q] = luinc (a, 1.e-3);
+
+     EXAMPLE 1: Simplest use of `pcg'
+
+            x = pcg(A,b)
+
+     EXAMPLE 2: `pcg' with a function which computes `A * X'
+
+            function y = apply_a (x)
+              y = [1:N]'.*x;
+            endfunction
+
+            x = pcg ("apply_a", b)
+
+     EXAMPLE 3: `pcg' with a preconditioner: L * U
+
+          x = pcg (a, b, 1.e-6, 500, l*u);
+
+     EXAMPLE 4: `pcg' with a preconditioner: L * U.  Faster than
+     EXAMPLE 3 since lower and upper triangular matrices are easier to
+     invert
+
+          x = pcg (a, b, 1.e-6, 500, l, u);
+
+     EXAMPLE 5: Preconditioned iteration, with full diagnostics.  The
+     preconditioner (quite strange, because even the original matrix A
+     is trivial) is defined as a function
+
+            function y = apply_m (x)
+              k = floor (length (x) - 2);
+              y = x;
+              y(1:k) = x(1:k)./[1:k]';
+            endfunction
+
+            [x, flag, relres, iter, resvec, eigest] = ...
+                               pcg (a, b, [], [], "apply_m");
+            semilogy (1:iter+1, resvec);
+
+     EXAMPLE 6: Finally, a preconditioner which depends on a parameter
+     K.
+
+            function y = apply_M (x, varargin)
+            K = varargin{1};
+            y = x;
+            y(1:K) = x(1:K)./[1:K]';
+            endfunction
+
+            [x, flag, relres, iter, resvec, eigest] = ...
+                 pcg (A, b, [], [], "apply_m", [], [], 3)
+
+     REFERENCES
+
+     	[1] C.T.Kelley, 'Iterative methods for linear and nonlinear
+     equations', 	SIAM, 1995 (the base PCG algorithm)
+
+     	[2] Y.Saad, 'Iterative methods for sparse linear systems', PWS
+     1996 	(condition number estimate from PCG) Revised version of
+     this book is 	available online at
+     http://www-users.cs.umn.edu/~saad/books.html
+
+     *See also:* *note sparse: doc-sparse, *note pcr: doc-pcr.
+
+ -- Function File: X = pcr (A, B, TOL, MAXIT, M, X0, ...)
+ -- Function File: [X, FLAG, RELRES, ITER, RESVEC] = pcr (...)
+     Solves the linear system of equations `A * X = B' by means of the
+     Preconditioned Conjugate Residuals iterative method.  The input
+     arguments are
+
+        * A can be either a square (preferably sparse) matrix or a
+          function handle, inline function or string containing the name
+          of a function which computes `A * X'.  In principle A should
+          be symmetric and non-singular; if `pcr' finds A to be
+          numerically singular, you will get a warning message and the
+          FLAG output parameter will be set.
+
+        * B is the right hand side vector.
+
+        * TOL is the required relative tolerance for the residual error,
+          `B - A * X'.  The iteration stops if `norm (B - A * X) <= TOL
+          * norm (B - A * X0)'.  If TOL is empty or is omitted, the
+          function sets `TOL = 1e-6' by default.
+
+        * MAXIT is the maximum allowable number of iterations; if `[]'
+          is supplied for `maxit', or `pcr' has less arguments, a
+          default value equal to 20 is used.
+
+        * M is the (left) preconditioning matrix, so that the iteration
+          is (theoretically) equivalent to solving by `pcr' `P * X = M
+          \ B', with `P = M \ A'.  Note that a proper choice of the
+          preconditioner may dramatically improve the overall
+          performance of the method.  Instead of matrix M, the user may
+          pass a function which returns the results of applying the
+          inverse of M to a vector (usually this is the preferred way
+          of using the preconditioner).  If `[]' is supplied for M, or
+          M is omitted, no preconditioning is applied.
+
+        * X0 is the initial guess.  If X0 is empty or omitted, the
+          function sets X0 to a zero vector by default.
+
+     The arguments which follow X0 are treated as parameters, and
+     passed in a proper way to any of the functions (A or M) which are
+     passed to `pcr'.  See the examples below for further details.  The
+     output arguments are
+
+        * X is the computed approximation to the solution of `A * X =
+          B'.
+
+        * FLAG reports on the convergence.  `FLAG = 0' means the
+          solution converged and the tolerance criterion given by TOL
+          is satisfied.  `FLAG = 1' means that the MAXIT limit for the
+          iteration count was reached.  `FLAG = 3' reports t `pcr'
+          breakdown, see [1] for details.
+
+        * RELRES is the ratio of the final residual to its initial
+          value, measured in the Euclidean norm.
+
+        * ITER is the actual number of iterations performed.
+
+        * RESVEC describes the convergence history of the method, so
+          that `RESVEC (i)' contains the Euclidean norms of the
+          residual after the (I-1)-th iteration, `I = 1,2, ..., ITER+1'.
+
+     Let us consider a trivial problem with a diagonal matrix (we
+     exploit the sparsity of A)
+
+          	n = 10;
+          	a = sparse (diag (1:n));
+          	b = rand (N, 1);
+
+     EXAMPLE 1: Simplest use of `pcr'
+
+            x = pcr(A, b)
+
+     EXAMPLE 2: `pcr' with a function which computes `A * X'.
+
+            function y = apply_a (x)
+              y = [1:10]'.*x;
+            endfunction
+
+            x = pcr ("apply_a", b)
+
+     EXAMPLE 3:  Preconditioned iteration, with full diagnostics.  The
+     preconditioner (quite strange, because even the original matrix A
+     is trivial) is defined as a function
+
+            function y = apply_m (x)
+              k = floor (length(x)-2);
+              y = x;
+              y(1:k) = x(1:k)./[1:k]';
+            endfunction
+
+            [x, flag, relres, iter, resvec] = ...
+                               pcr (a, b, [], [], "apply_m")
+            semilogy([1:iter+1], resvec);
+
+     EXAMPLE 4: Finally, a preconditioner which depends on a parameter
+     K.
+
+            function y = apply_m (x, varargin)
+              k = varargin{1};
+              y = x; y(1:k) = x(1:k)./[1:k]';
+            endfunction
+
+            [x, flag, relres, iter, resvec] = ...
+                               pcr (a, b, [], [], "apply_m"', [], 3)
+
+     REFERENCES
+
+     	[1] W. Hackbusch, "Iterative Solution of Large Sparse Systems of
+     	Equations", section 9.5.4; Springer, 1994
+
+     *See also:* *note sparse: doc-sparse, *note pcg: doc-pcg.
+
+   The speed with which an iterative solver converges to a solution can
+be accelerated with the use of a pre-conditioning matrix M.  In this
+case the linear equation `M^-1 * X = M^-1 * A \ B' is solved instead.
+Typical pre-conditioning matrices are partial factorizations of the
+original matrix.
+
+ -- Loadable Function: [L, U, P, Q] = luinc (A, '0')
+ -- Loadable Function: [L, U, P, Q] = luinc (A, DROPTOL)
+ -- Loadable Function: [L, U, P, Q] = luinc (A, OPTS)
+     Produce the incomplete LU factorization of the sparse matrix A.
+     Two types of incomplete factorization are possible, and the type
+     is determined by the second argument to "luinc".
+
+     Called with a second argument of '0', the zero-level incomplete LU
+     factorization is produced.  This creates a factorization of A
+     where the position of the non-zero arguments correspond to the same
+     positions as in the matrix A.
+
+     Alternatively, the fill-in of the incomplete LU factorization can
+     be controlled through the variable DROPTOL or the structure OPTS.
+     The UMFPACK multifrontal factorization code by Tim A.  Davis is
+     used for the incomplete LU factorization, (availability
+     `http://www.cise.ufl.edu/research/sparse/umfpack/')
+
+     DROPTOL determines the values below which the values in the LU
+     factorization are dropped and replaced by zero.  It must be a
+     positive scalar, and any values in the factorization whose
+     absolute value are less than this value are dropped, expect if
+     leaving them increase the sparsity of the matrix.  Setting DROPTOL
+     to zero results in a complete LU factorization which is the
+     default.
+
+     OPTS is a structure containing one or more of the fields
+
+    `droptol'
+          The drop tolerance as above.  If OPTS only contains `droptol'
+          then this is equivalent to using the variable DROPTOL.
+
+    `milu'
+          A logical variable flagging whether to use the modified
+          incomplete LU factorization.  In the case that `milu' is
+          true, the dropped values are subtracted from the diagonal of
+          the matrix U of the factorization.  The default is `false'.
+
+    `udiag'
+          A logical variable that flags whether zero elements on the
+          diagonal of U should be replaced with DROPTOL to attempt to
+          avoid singular factors.  The default is `false'.
+
+    `thresh'
+          Defines the pivot threshold in the interval [0,1].  Values
+          outside that range are ignored.
+
+     All other fields in OPTS are ignored.  The outputs from "luinc"
+     are the same as for "lu".
+
+     Given the string argument 'vector', "luinc" returns the values of P
+     Q as vector values.
+
+     *See also:* *note sparse: doc-sparse, *note lu: doc-lu.
+
+
+File: octave.info,  Node: Real Life Example,  Prev: Iterative Techniques,  Up: Sparse Matrices
+
+21.4 Real Life Example of the use of Sparse Matrices
+====================================================
+
+A common application for sparse matrices is in the solution of Finite
+Element Models.  Finite element models allow numerical solution of
+partial differential equations that do not have closed form solutions,
+typically because of the complex shape of the domain.
+
+   In order to motivate this application, we consider the boundary value
+Laplace equation.  This system can model scalar potential fields, such
+as heat or electrical potential.  Given a medium Omega with boundary
+dOmega . At all points on the dOmega the boundary conditions are known,
+and we wish to calculate the potential in Omega . Boundary conditions
+may specify the potential (Dirichlet boundary condition), its normal
+derivative across the boundary (Neumann boundary condition), or a
+weighted sum of the potential and its derivative (Cauchy boundary
+condition).
+
+   In a thermal model, we want to calculate the temperature in Omega
+and know the boundary temperature (Dirichlet condition) or heat flux
+(from which we can calculate the Neumann condition by dividing by the
+thermal conductivity at the boundary).  Similarly, in an electrical
+model, we want to calculate the voltage in Omega and know the boundary
+voltage (Dirichlet) or current (Neumann condition after diving by the
+electrical conductivity).  In an electrical model, it is common for
+much of the boundary to be electrically isolated; this is a Neumann
+boundary condition with the current equal to zero.
+
+   The simplest finite element models will divide Omega into simplexes
+(triangles in 2D, pyramids in 3D).
+
+   The following example creates a simple rectangular 2D electrically
+conductive medium with 10 V and 20 V imposed on opposite sides
+(Dirichlet boundary conditions).  All other edges are electrically
+isolated.
+
+        node_y= [1;1.2;1.5;1.8;2]*ones(1,11);
+        node_x= ones(5,1)*[1,1.05,1.1,1.2, ...
+                  1.3,1.5,1.7,1.8,1.9,1.95,2];
+        nodes= [node_x(:), node_y(:)];
+
+        [h,w]= size(node_x);
+        elems= [];
+        for idx= 1:w-1
+          widx= (idx-1)*h;
+          elems= [elems; ...
+            widx+[(1:h-1);(2:h);h+(1:h-1)]'; ...
+            widx+[(2:h);h+(2:h);h+(1:h-1)]' ];
+        endfor
+
+        E= size(elems,1); # No. of simplices
+        N= size(nodes,1); # No. of vertices
+        D= size(elems,2); # dimensions+1
+
+   This creates a N-by-2 matrix `nodes' and a E-by-3 matrix `elems'
+with values, which define finite element triangles:
+
+       nodes(1:7,:)'
+         1.00 1.00 1.00 1.00 1.00 1.05 1.05 ...
+         1.00 1.20 1.50 1.80 2.00 1.00 1.20 ...
+
+       elems(1:7,:)'
+         1    2    3    4    2    3    4 ...
+         2    3    4    5    7    8    9 ...
+         6    7    8    9    6    7    8 ...
+
+   Using a first order FEM, we approximate the electrical conductivity
+distribution in Omega as constant on each simplex (represented by the
+vector `conductivity').  Based on the finite element geometry, we first
+calculate a system (or stiffness) matrix for each simplex (represented
+as 3-by-3 elements on the diagonal of the element-wise system matrix
+`SE'.  Based on `SE' and a N-by-DE connectivity matrix `C',
+representing the connections between simplices and vertices, the global
+connectivity matrix `S' is calculated.
+
+       # Element conductivity
+       conductivity= [1*ones(1,16), ...
+              2*ones(1,48), 1*ones(1,16)];
+
+       # Connectivity matrix
+       C = sparse ((1:D*E), reshape (elems', ...
+              D*E, 1), 1, D*E, N);
+
+       # Calculate system matrix
+       Siidx = floor ([0:D*E-1]'/D) * D * ...
+              ones(1,D) + ones(D*E,1)*(1:D) ;
+       Sjidx = [1:D*E]'*ones(1,D);
+       Sdata = zeros(D*E,D);
+       dfact = factorial(D-1);
+       for j=1:E
+          a = inv([ones(D,1), ...
+              nodes(elems(j,:), :)]);
+          const = conductivity(j) * 2 / ...
+              dfact / abs(det(a));
+          Sdata(D*(j-1)+(1:D),:) = const * ...
+              a(2:D,:)' * a(2:D,:);
+       endfor
+       # Element-wise system matrix
+       SE= sparse(Siidx,Sjidx,Sdata);
+       # Global system matrix
+       S= C'* SE *C;
+
+   The system matrix acts like the conductivity `S' in Ohm's law `S * V
+= I'.  Based on the Dirichlet and Neumann boundary conditions, we are
+able to solve for the voltages at each vertex `V'.
+
+       # Dirichlet boundary conditions
+       D_nodes=[1:5, 51:55];
+       D_value=[10*ones(1,5), 20*ones(1,5)];
+
+       V= zeros(N,1);
+       V(D_nodes) = D_value;
+       idx = 1:N; # vertices without Dirichlet
+                  # boundary condns
+       idx(D_nodes) = [];
+
+       # Neumann boundary conditions.  Note that
+       # N_value must be normalized by the
+       # boundary length and element conductivity
+       N_nodes=[];
+       N_value=[];
+
+       Q = zeros(N,1);
+       Q(N_nodes) = N_value;
+
+       V(idx) = S(idx,idx) \ ( Q(idx) - ...
+                 S(idx,D_nodes) * V(D_nodes));
+
+   Finally, in order to display the solution, we show each solved
+voltage value in the z-axis for each simplex vertex.
+
+       elemx = elems(:,[1,2,3,1])';
+       xelems = reshape (nodes(elemx, 1), 4, E);
+       yelems = reshape (nodes(elemx, 2), 4, E);
+       velems = reshape (V(elemx), 4, E);
+       plot3 (xelems,yelems,velems,'k');
+       print ('grid.eps');
+
+
+File: octave.info,  Node: Numerical Integration,  Next: Differential Equations,  Prev: Sparse Matrices,  Up: Top
+
+22 Numerical Integration
+************************
+
+Octave comes with several built-in functions for computing the integral
+of a function numerically.  These functions all solve 1-dimensional
+integration problems.
+
+* Menu:
+
+* Functions of One Variable::
+* Functions of Multiple Variables::
+* Orthogonal Collocation::
+
+
+File: octave.info,  Node: Functions of One Variable,  Next: Functions of Multiple Variables,  Up: Numerical Integration
+
+22.1 Functions of One Variable
+==============================
+
+Octave supports three different algorithms for computing the integral
+of a function f over the interval from a to b.  These are
+
+`quad'
+     Numerical integration based on Gaussian quadrature.
+
+`quadl'
+     Numerical integration using an adaptive Lobatto rule.
+
+`quadgk'
+     Numerical integration using an adaptive Gauss-Konrod rule.
+
+`quadv'
+     Numerical integration using an adaptive vectorized Simpson's rule.
+
+`trapz'
+     Numerical integration using the trapezoidal method.
+
+Besides these functions Octave also allows you to perform cumulative
+numerical integration using the trapezoidal method through the
+`cumtrapz' function.
+
+ -- Loadable Function: [V, IER, NFUN, ERR] = quad (F, A, B, TOL, SING)
+     Integrate a nonlinear function of one variable using Quadpack.
+     The first argument is the name of the function, the function
+     handle or the inline function to call to compute the value of the
+     integrand.  It must have the form
+
+          y = f (x)
+
+     where Y and X are scalars.
+
+     The second and third arguments are limits of integration.  Either
+     or both may be infinite.
+
+     The optional argument TOL is a vector that specifies the desired
+     accuracy of the result.  The first element of the vector is the
+     desired absolute tolerance, and the second element is the desired
+     relative tolerance.  To choose a relative test only, set the
+     absolute tolerance to zero.  To choose an absolute test only, set
+     the relative tolerance to zero.
+
+     The optional argument SING is a vector of values at which the
+     integrand is known to be singular.
+
+     The result of the integration is returned in V and IER contains an
+     integer error code (0 indicates a successful integration).  The
+     value of NFUN indicates how many function evaluations were
+     required, and ERR contains an estimate of the error in the
+     solution.
+
+     You can use the function `quad_options' to set optional parameters
+     for `quad'.
+
+     It should be noted that since `quad' is written in Fortran it
+     cannot be called recursively.
+
+ -- Loadable Function:  quad_options (OPT, VAL)
+     When called with two arguments, this function allows you set
+     options parameters for the function `quad'.  Given one argument,
+     `quad_options' returns the value of the corresponding option.  If
+     no arguments are supplied, the names of all the available options
+     and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance; may be zero for pure relative error test.
+
+    `"relative tolerance"'
+          Nonnegative relative tolerance.  If the absolute tolerance is
+          zero, the relative tolerance must be greater than or equal to
+          `max (50*eps, 0.5e-28)'.
+
+    `"single precision absolute tolerance"'
+          Absolute tolerance for single precision; may be zero for pure
+          relative error test.
+
+    `"single precision relative tolerance"'
+          Nonnegative relative tolerance for single precision.  If the
+          absolute tolerance is zero, the relative tolerance must be
+          greater than or equal to `max (50*eps, 0.5e-28)'.
+
+   Here is an example of using `quad' to integrate the function
+
+       F(X) = X * sin (1/X) * sqrt (abs (1 - X))
+
+from X = 0 to X = 3.
+
+   This is a fairly difficult integration (plot the function over the
+range of integration to see why).
+
+   The first step is to define the function:
+
+     function y = f (x)
+       y = x .* sin (1 ./ x) .* sqrt (abs (1 - x));
+     endfunction
+
+   Note the use of the `dot' forms of the operators.  This is not
+necessary for the call to `quad', but it makes it much easier to
+generate a set of points for plotting (because it makes it possible to
+call the function with a vector argument to produce a vector result).
+
+   Then we simply call quad:
+
+     [v, ier, nfun, err] = quad ("f", 0, 3)
+          => 1.9819
+          => 1
+          => 5061
+          => 1.1522e-07
+
+   Although `quad' returns a nonzero value for IER, the result is
+reasonably accurate (to see why, examine what happens to the result if
+you move the lower bound to 0.1, then 0.01, then 0.001, etc.).
+
+ -- Function File: Q = quadl (F, A, B)
+ -- Function File: Q = quadl (F, A, B, TOL)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE, P1, P2, ...)
+     Numerically evaluate integral using adaptive Lobatto rule.  `quadl
+     (F, A, B)' approximates the integral of `F(X)' to machine
+     precision.  F is either a function handle, inline function or
+     string containing the name of the function to evaluate.  The
+     function F must return a vector of output values if given a vector
+     of input values.
+
+     If defined, TOL defines the relative tolerance to which to which
+     to integrate `F(X)'.  While if TRACE is defined, displays the left
+     end point of the current interval, the interval length, and the
+     partial integral.
+
+     Additional arguments P1, etc., are passed directly to F.  To use
+     default values for TOL and TRACE, one may pass empty matrices.
+
+     Reference: W. Gander and W. Gautschi, 'Adaptive Quadrature -
+     Revisited', BIT Vol. 40, No. 1, March 2000, pp. 84-101.
+     `http://www.inf.ethz.ch/personal/gander/'
+
+
+ -- Function File:  quadgk (F, A, B, ABSTOL, TRACE)
+ -- Function File:  quadgk (F, A, B, PROP, VAL, ...)
+ -- Function File: [Q, ERR] = quadgk (...)
+     Numerically evaluate integral using adaptive Gauss-Konrod
+     quadrature.  The formulation is based on a proposal by L.F.
+     Shampine, `"Vectorized adaptive quadrature in MATLAB", Journal of
+     Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2,
+     Feb 2008' where all function evaluations at an iteration are
+     calculated with a single call to F.  Therefore the function F must
+     be of the form `F (X)' and accept vector values of X and return a
+     vector of the same length representing the function evaluations at
+     the given values of X.  The function F can be defined in terms of
+     a function handle, inline function or string.
+
+     The bounds of the quadrature `[A, B]' can be finite or infinite
+     and contain weak end singularities.  Variable transformation will
+     be used to treat infinite intervals and weaken the singularities.
+     For example
+
+          quadgk(@(x) 1 ./ (sqrt (x) .* (x + 1)), 0, Inf)
+
+     Note that the formulation of the integrand uses the
+     element-by-element operator `./' and all user functions to
+     `quadgk' should do the same.
+
+     The absolute tolerance can be passed as a fourth argument in a
+     manner compatible with `quadv'.  Equally the user can request that
+     information on the convergence can be printed is the fifth argument
+     is logically true.
+
+     Alternatively, certain properties of `quadgk' can be passed as
+     pairs `PROP, VAL'.  Valid properties are
+
+    `AbsTol'
+          Defines the absolute error tolerance for the quadrature.  The
+          default absolute tolerance is 1e-10.
+
+    `RelTol'
+          Defines the relative error tolerance for the quadrature.  The
+          default relative tolerance is 1e-5.
+
+    `MaxIntervalCount'
+          `quadgk' initially subdivides the interval on which to perform
+          the quadrature into 10 intervals.  Sub-intervals that have an
+          unacceptable error are sub-divided and re-evaluated.  If the
+          number of sub-intervals exceeds at any point 650
+          sub-intervals then a poor convergence is signaled and the
+          current estimate of the integral is returned.  The property
+          'MaxIntervalCount' can be used to alter the number of
+          sub-intervals that can exist before exiting.
+
+    `WayPoints'
+          If there exists discontinuities in the first derivative of the
+          function to integrate, then these can be flagged with the
+          `"WayPoints"' property.  This forces the ends of a
+          sub-interval to fall on the breakpoints of the function and
+          can result in significantly improved estimation of the error
+          in the integral, faster computation or both.  For example,
+
+               quadgk (@(x) abs (1 - x .^ 2), 0, 2, 'Waypoints', 1)
+
+          signals the breakpoint in the integrand at `X = 1'.
+
+    `Trace'
+          If logically true, then `quadgk' prints information on the
+          convergence of the quadrature at each iteration.
+
+     If any of A, B or WAYPOINTS is complex, then the quadrature is
+     treated as a contour integral along a piecewise continuous path
+     defined by the above.  In this case the integral is assumed to
+     have no edge singularities.  For example
+
+          quadgk (@(z) log (z), 1+1i, 1+1i, "WayPoints",
+                  [1-1i, -1,-1i, -1+1i])
+
+     integrates `log (z)' along the square defined by `[1+1i,  1-1i,
+     -1-1i, -1+1i]'
+
+     If two output arguments are requested, then ERR returns the
+     approximate bounds on the error in the integral `abs (Q - I)',
+     where I is the exact value of the integral.
+
+     *See also:* *note triplequad: doc-triplequad, *note dblquad:
+     doc-dblquad, *note quad: doc-quad, *note quadl: doc-quadl, *note
+     quadv: doc-quadv, *note trapz: doc-trapz.
+
+ -- Function File: Q = quadv (F, A, B)
+ -- Function File: Q = quadl (F, A, B, TOL)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE)
+ -- Function File: Q = quadl (F, A, B, TOL, TRACE, P1, P2, ...)
+ -- Function File: [Q, FCNT] = quadl (...)
+     Numerically evaluate integral using adaptive Simpson's rule.
+     `quadv (F, A, B)' approximates the integral of `F(X)' to the
+     default absolute tolerance of `1e-6'.  F is either a function
+     handle, inline function or string containing the name of the
+     function to evaluate.  The function F must accept a string, and
+     can return a vector representing the approximation to N different
+     sub-functions.
+
+     If defined, TOL defines the absolute tolerance to which to which
+     to integrate each sub-interval of `F(X)'.  While if TRACE is
+     defined, displays the left end point of the current interval, the
+     interval length, and the partial integral.
+
+     Additional arguments P1, etc., are passed directly to F.  To use
+     default values for TOL and TRACE, one may pass empty matrices.
+
+     *See also:* *note triplequad: doc-triplequad, *note dblquad:
+     doc-dblquad, *note quad: doc-quad, *note quadl: doc-quadl, *note
+     quadgk: doc-quadgk, *note trapz: doc-trapz.
+
+ -- Function File: Z = trapz (Y)
+ -- Function File: Z = trapz (X, Y)
+ -- Function File: Z = trapz (..., DIM)
+     Numerical integration using trapezoidal method.  `trapz (Y)'
+     computes the integral of the Y along the first non-singleton
+     dimension.  If the argument X is omitted a equally spaced vector
+     is assumed.  `trapz (X, Y)' evaluates the integral with respect to
+     X.
+
+     *See also:* *note cumtrapz: doc-cumtrapz.
+
+ -- Function File: Z = cumtrapz (Y)
+ -- Function File: Z = cumtrapz (X, Y)
+ -- Function File: Z = cumtrapz (..., DIM)
+     Cumulative numerical integration using trapezoidal method.
+     `cumtrapz (Y)' computes the cumulative integral of the Y along the
+     first non-singleton dimension.  If the argument X is omitted a
+     equally spaced vector is assumed.  `cumtrapz (X, Y)' evaluates the
+     cumulative integral with respect to X.
+
+     *See also:* *note trapz: doc-trapz, *note cumsum: doc-cumsum.
+
diff --git a/doc/interpreter/octave.info-4 b/doc/interpreter/octave.info-4
new file mode 100644
index 0000000..2b136f3
--- /dev/null
+++ b/doc/interpreter/octave.info-4
@@ -0,0 +1,7937 @@
+This is octave.info, produced by makeinfo version 4.11 from ./octave.texi.
+
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, 2007
+John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+File: octave.info,  Node: Orthogonal Collocation,  Prev: Functions of Multiple Variables,  Up: Numerical Integration
+
+22.2 Orthogonal Collocation
+===========================
+
+ -- Loadable Function: [R, AMAT, BMAT, Q] = colloc (N, "left", "right")
+     Compute derivative and integral weight matrices for orthogonal
+     collocation using the subroutines given in J. Villadsen and M. L.
+     Michelsen, `Solution of Differential Equation Models by Polynomial
+     Approximation'.
+
+   Here is an example of using `colloc' to generate weight matrices for
+solving the second order differential equation U' - ALPHA * U" = 0 with
+the boundary conditions U(0) = 0 and U(1) = 1.
+
+   First, we can generate the weight matrices for N points (including
+the endpoints of the interval), and incorporate the boundary conditions
+in the right hand side (for a specific value of ALPHA).
+
+     n = 7;
+     alpha = 0.1;
+     [r, a, b] = colloc (n-2, "left", "right");
+     at = a(2:n-1,2:n-1);
+     bt = b(2:n-1,2:n-1);
+     rhs = alpha * b(2:n-1,n) - a(2:n-1,n);
+
+   Then the solution at the roots R is
+
+     u = [ 0; (at - alpha * bt) \ rhs; 1]
+          => [ 0.00; 0.004; 0.01 0.00; 0.12; 0.62; 1.00 ]
+
+
+File: octave.info,  Node: Functions of Multiple Variables,  Next: Orthogonal Collocation,  Prev: Functions of One Variable,  Up: Numerical Integration
+
+22.3 Functions of Multiple Variables
+====================================
+
+Octave does not have built-in functions for computing the integral of
+functions of multiple variables directly.  It is however possible to
+compute the integral of a function of multiple variables using the
+functions for one-dimensional integrals.
+
+   To illustrate how the integration can be performed, we will integrate
+the function
+     f(x, y) = sin(pi*x*y)*sqrt(x*y)
+   for x and y between 0 and 1.
+
+   The first approach creates a function that integrates f with respect
+to x, and then integrates that function with respect to y.  Since
+`quad' is written in Fortran it cannot be called recursively.  This
+means that `quad' cannot integrate a function that calls `quad', and
+hence cannot be used to perform the double integration.  It is however
+possible with `quadl', which is what the following code does.
+
+     function I = g(y)
+       I = ones(1, length(y));
+       for i = 1:length(y)
+         f = @(x) sin(pi.*x.*y(i)).*sqrt(x.*y(i));
+         I(i) = quadl(f, 0, 1);
+       endfor
+     endfunction
+
+     I = quadl("g", 0, 1)
+           => 0.30022
+
+   The above process can be simplified with the `dblquad' and
+`triplequad' functions for integrals over two and three variables.  For
+example
+
+     I =  dblquad (@(x, y) sin(pi.*x.*y).*sqrt(x.*y), 0, 1, 0, 1)
+           => 0.30022
+
+ -- Function File:  dblquad (F, XA, XB, YA, YB, TOL, QUADF, ...)
+     Numerically evaluate a double integral.  The function over with to
+     integrate is defined by `F', and the interval for the integration
+     is defined by `[XA, XB, YA, YB]'.  The function F must accept a
+     vector X and a scalar Y, and return a vector of the same length as
+     X.
+
+     If defined, TOL defines the absolute tolerance to which to which
+     to integrate each sub-integral.
+
+     Additional arguments, are passed directly to F.  To use the default
+     value for TOL one may pass an empty matrix.
+
+     *See also:* *note triplequad: doc-triplequad, *note quad:
+     doc-quad, *note quadv: doc-quadv, *note quadl: doc-quadl, *note
+     quadgk: doc-quadgk, *note trapz: doc-trapz.
+
+ -- Function File:  triplequad (F, XA, XB, YA, YB, ZA, ZB, TOL, QUADF,
+          ...)
+     Numerically evaluate a triple integral.  The function over which to
+     integrate is defined by `F', and the interval for the integration
+     is defined by `[XA, XB, YA, YB, ZA, ZB]'.  The function F must
+     accept a vector X and a scalar Y, and return a vector of the same
+     length as X.
+
+     If defined, TOL defines the absolute tolerance to which to which
+     to integrate each sub-integral.
+
+     Additional arguments, are passed directly to F.  To use the default
+     value for TOL one may pass an empty matrix.
+
+     *See also:* *note dblquad: doc-dblquad, *note quad: doc-quad,
+     *note quadv: doc-quadv, *note quadl: doc-quadl, *note quadgk:
+     doc-quadgk, *note trapz: doc-trapz.
+
+   The above mentioned approach works but is fairly slow, and that
+problem increases exponentially with the dimensionality the problem.
+Another possible solution is to use Orthogonal Collocation as described
+in the previous section.  The integral of a function f(x,y) for x and y
+between 0 and 1 can be approximated using n points by the sum over
+`i=1:n' and `j=1:n' of `q(i)*q(j)*f(r(i),r(j))', where q and r is as
+returned by `colloc(n)'.  The generalization to more than two variables
+is straight forward.  The following code computes the studied integral
+using n=7 points.
+
+     f = @(x,y) sin(pi*x*y').*sqrt(x*y');
+     n = 7;
+     [t, A, B, q] = colloc(n);
+     I = q'*f(t,t)*q;
+           => 0.30022
+
+It should be noted that the number of points determines the quality of
+the approximation.  If the integration needs to be performed between a
+and b instead of 0 and 1, a change of variables is needed.
+
+
+File: octave.info,  Node: Differential Equations,  Next: Optimization,  Prev: Numerical Integration,  Up: Top
+
+23 Differential Equations
+*************************
+
+Octave has built-in functions for solving ordinary differential
+equations, and differential-algebraic equations.  All solvers are based
+on reliable ODE routines written in Fortran.
+
+* Menu:
+
+* Ordinary Differential Equations::
+* Differential-Algebraic Equations::
+
+
+File: octave.info,  Node: Ordinary Differential Equations,  Next: Differential-Algebraic Equations,  Up: Differential Equations
+
+23.1 Ordinary Differential Equations
+====================================
+
+The function `lsode' can be used to solve ODEs of the form
+
+     dx
+     -- = f (x, t)
+     dt
+
+using Hindmarsh's ODE solver LSODE.
+
+ -- Loadable Function: [X, ISTATE, MSG] = lsode (FCN, X_0, T, T_CRIT)
+     Solve the set of differential equations
+
+          dx
+          -- = f(x, t)
+          dt
+
+     with
+
+          x(t_0) = x_0
+
+     The solution is returned in the matrix X, with each row
+     corresponding to an element of the vector T.  The first element of
+     T should be t_0 and should correspond to the initial state of the
+     system X_0, so that the first row of the output is X_0.
+
+     The first argument, FCN, is a string, inline, or function handle
+     that names the function f to call to compute the vector of right
+     hand sides for the set of equations.  The function must have the
+     form
+
+          XDOT = f (X, T)
+
+     in which XDOT and X are vectors and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array
+     of strings, inline functions, or function handles, the first
+     element names the function f described above, and the second
+     element names a function to compute the Jacobian of f.  The
+     Jacobian function must have the form
+
+          JAC = j (X, T)
+
+     in which JAC is the matrix of partial derivatives
+
+                       | df_1  df_1       df_1 |
+                       | ----  ----  ...  ---- |
+                       | dx_1  dx_2       dx_N |
+                       |                       |
+                       | df_2  df_2       df_2 |
+                       | ----  ----  ...  ---- |
+                df_i   | dx_1  dx_2       dx_N |
+          jac = ---- = |                       |
+                dx_j   |  .    .     .    .    |
+                       |  .    .      .   .    |
+                       |  .    .       .  .    |
+                       |                       |
+                       | df_N  df_N       df_N |
+                       | ----  ----  ...  ---- |
+                       | dx_1  dx_2       dx_N |
+
+     The second and third arguments specify the initial state of the
+     system, x_0, and the initial value of the independent variable t_0.
+
+     The fourth argument is optional, and may be used to specify a set
+     of times that the ODE solver should not integrate past.  It is
+     useful for avoiding difficulties with singularities and points
+     where there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be 2
+     (consistent with the Fortran version of LSODE).
+
+     If the computation is not successful, ISTATE will be something
+     other than 2 and MSG will contain additional information.
+
+     You can use the function `lsode_options' to set optional
+     parameters for `lsode'.
+
+     *See also:* *note daspk: doc-daspk, *note dassl: doc-dassl, *note
+     dasrt: doc-dasrt.
+
+ -- Loadable Function:  lsode_options (OPT, VAL)
+     When called with two arguments, this function allows you set
+     options parameters for the function `lsode'.  Given one argument,
+     `lsode_options' returns the value of the corresponding option.  If
+     no arguments are supplied, the names of all the available options
+     and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector.
+
+    `"relative tolerance"'
+          Relative tolerance parameter.  Unlike the absolute tolerance,
+          this parameter may only be a scalar.
+
+          The local error test applied at each integration step is
+
+                 abs (local error in x(i)) <= ...
+                     rtol * abs (y(i)) + atol(i)
+
+    `"integration method"'
+          A string specifying the method of integration to use to solve
+          the ODE system.  Valid values are
+
+         "adams"
+         "non-stiff"
+               No Jacobian used (even if it is available).
+
+         "bdf"
+
+         "stiff"
+               Use stiff backward differentiation formula (BDF) method.
+               If a function to compute the Jacobian is not supplied,
+               `lsode' will compute a finite difference approximation
+               of the Jacobian matrix.
+
+    `"initial step size"'
+          The step size to be attempted on the first step (default is
+          determined automatically).
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  If using
+          the Adams method, this option must be between 1 and 12.
+          Otherwise, it must be between 1 and 5, inclusive.
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very
+          large regions  (default is not specified).
+
+    `"minimum step size"'
+          The minimum absolute step size allowed (default is 0).
+
+    `"step limit"'
+          Maximum number of steps allowed (default is 100000).
+
+   Here is an example of solving a set of three differential equations
+using `lsode'.  Given the function
+
+     function xdot = f (x, t)
+
+       xdot = zeros (3,1);
+
+       xdot(1) = 77.27 * (x(2) - x(1)*x(2) + x(1) \
+                 - 8.375e-06*x(1)^2);
+       xdot(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
+       xdot(3) = 0.161*(x(1) - x(3));
+
+     endfunction
+
+and the initial condition `x0 = [ 4; 1.1; 4 ]', the set of equations
+can be integrated using the command
+
+     t = linspace (0, 500, 1000);
+
+     y = lsode ("f", x0, t);
+
+   If you try this, you will see that the value of the result changes
+dramatically between T = 0 and 5, and again around T = 305.  A more
+efficient set of output points might be
+
+     t = [0, logspace (-1, log10(303), 150), \
+             logspace (log10(304), log10(500), 150)];
+
+   See Alan C. Hindmarsh, `ODEPACK, A Systematized Collection of ODE
+Solvers', in Scientific Computing, R. S. Stepleman, editor, (1983) for
+more information about the inner workings of `lsode'.
+
+
+File: octave.info,  Node: Differential-Algebraic Equations,  Prev: Ordinary Differential Equations,  Up: Differential Equations
+
+23.2 Differential-Algebraic Equations
+=====================================
+
+The function `daspk' can be used to solve DAEs of the form
+
+     0 = f (x-dot, x, t),    x(t=0) = x_0, x-dot(t=0) = x-dot_0
+
+where x-dot is the derivative of x.  The equation is solved using
+Petzold's DAE solver DASPK.
+
+ -- Loadable Function: [X, XDOT, ISTATE, MSG] = daspk (FCN, X_0,
+          XDOT_0, T, T_CRIT)
+     Solve the set of differential-algebraic equations
+
+          0 = f (x, xdot, t)
+
+     with
+
+          x(t_0) = x_0, xdot(t_0) = xdot_0
+
+     The solution is returned in the matrices X and XDOT, with each row
+     in the result matrices corresponding to one of the elements in the
+     vector T.  The first element of T should be t_0 and correspond to
+     the initial state of the system X_0 and its derivative XDOT_0, so
+     that the first row of the output X is X_0 and the first row of the
+     output XDOT is XDOT_0.
+
+     The first argument, FCN, is a string, inline, or function handle
+     that names the function f to call to compute the vector of
+     residuals for the set of equations.  It must have the form
+
+          RES = f (X, XDOT, T)
+
+     in which X, XDOT, and RES are vectors, and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array
+     of strings, inline functions, or function handles, the first
+     element names the function f described above, and the second
+     element names a function to compute the modified Jacobian
+
+                df       df
+          jac = -- + c ------
+                dx     d xdot
+
+     The modified Jacobian function must have the form
+
+
+          JAC = j (X, XDOT, T, C)
+
+     The second and third arguments to `daspk' specify the initial
+     condition of the states and their derivatives, and the fourth
+     argument specifies a vector of output times at which the solution
+     is desired, including the time corresponding to the initial
+     condition.
+
+     The set of initial states and derivatives are not strictly
+     required to be consistent.  If they are not consistent, you must
+     use the `daspk_options' function to provide additional information
+     so that `daspk' can compute a consistent starting point.
+
+     The fifth argument is optional, and may be used to specify a set of
+     times that the DAE solver should not integrate past.  It is useful
+     for avoiding difficulties with singularities and points where
+     there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be
+     greater than zero (consistent with the Fortran version of DASPK).
+
+     If the computation is not successful, the value of ISTATE will be
+     less than zero and MSG will contain additional information.
+
+     You can use the function `daspk_options' to set optional
+     parameters for `daspk'.
+
+     *See also:* *note dassl: doc-dassl.
+
+ -- Loadable Function:  daspk_options (OPT, VAL)
+     When called with two arguments, this function allows you set
+     options parameters for the function `daspk'.  Given one argument,
+     `daspk_options' returns the value of the corresponding option.  If
+     no arguments are supplied, the names of all the available options
+     and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector, and
+          the relative tolerance must also be a vector of the same
+          length.
+
+    `"relative tolerance"'
+          Relative tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector, and
+          the absolute tolerance must also be a vector of the same
+          length.
+
+          The local error test applied at each integration step is
+
+                 abs (local error in x(i))
+                      <= rtol(i) * abs (Y(i)) + atol(i)
+
+    `"compute consistent initial condition"'
+          Denoting the differential variables in the state vector by
+          `Y_d' and the algebraic variables by `Y_a', `ddaspk' can solve
+          one of two initialization problems:
+
+            1. Given Y_d, calculate Y_a and Y'_d
+
+            2. Given Y', calculate Y.
+
+          In either case, initial values for the given components are
+          input, and initial guesses for the unknown components must
+          also be provided as input.  Set this option to 1 to solve the
+          first problem, or 2 to solve the second (the default is 0, so
+          you must provide a set of initial conditions that are
+          consistent).
+
+          If this option is set to a nonzero value, you must also set
+          the `"algebraic variables"' option to declare which variables
+          in the problem are algebraic.
+
+    `"use initial condition heuristics"'
+          Set to a nonzero value to use the initial condition
+          heuristics options described below.
+
+    `"initial condition heuristics"'
+          A vector of the following parameters that can be used to
+          control the initial condition calculation.
+
+         `MXNIT'
+               Maximum number of Newton iterations (default is 5).
+
+         `MXNJ'
+               Maximum number of Jacobian evaluations (default is 6).
+
+         `MXNH'
+               Maximum number of values of the artificial stepsize
+               parameter to be tried if the `"compute consistent
+               initial condition"' option has been set to 1 (default is
+               5).
+
+               Note that the maximum total number of Newton iterations
+               allowed is `MXNIT*MXNJ*MXNH' if the `"compute consistent
+               initial condition"' option has been set to 1 and
+               `MXNIT*MXNJ' if it is set to 2.
+
+         `LSOFF'
+               Set to a nonzero value to disable the linesearch
+               algorithm (default is 0).
+
+         `STPTOL'
+               Minimum scaled step in linesearch algorithm (default is
+               eps^(2/3)).
+
+         `EPINIT'
+               Swing factor in the Newton iteration convergence test.
+               The test is applied to the residual vector,
+               premultiplied by the approximate Jacobian.  For
+               convergence, the weighted RMS norm of this vector
+               (scaled by the error weights) must be less than
+               `EPINIT*EPCON', where `EPCON' = 0.33 is the analogous
+               test constant used in the time steps.  The default is
+               `EPINIT' = 0.01.
+
+    `"print initial condition info"'
+          Set this option to a nonzero value to display detailed
+          information about the initial condition calculation (default
+          is 0).
+
+    `"exclude algebraic variables from error test"'
+          Set to a nonzero value to exclude algebraic variables from
+          the error test.  You must also set the `"algebraic
+          variables"' option to declare which variables in the problem
+          are algebraic (default is 0).
+
+    `"algebraic variables"'
+          A vector of the same length as the state vector.  A nonzero
+          element indicates that the corresponding element of the state
+          vector is an algebraic variable (i.e., its derivative does
+          not appear explicitly in the equation set.
+
+          This option is required by the `compute consistent initial
+          condition"' and `"exclude algebraic variables from error
+          test"' options.
+
+    `"enforce inequality constraints"'
+          Set to one of the following values to enforce the inequality
+          constraints specified by the `"inequality constraint types"'
+          option (default is 0).
+
+            1. To have constraint checking only in the initial
+               condition calculation.
+
+            2. To enforce constraint checking during the integration.
+
+            3. To enforce both options 1 and 2.
+
+    `"inequality constraint types"'
+          A vector of the same length as the state specifying the type
+          of inequality constraint.  Each element of the vector
+          corresponds to an element of the state and should be assigned
+          one of the following codes
+
+         -2
+               Less than zero.
+
+         -1
+               Less than or equal to zero.
+
+         0
+               Not constrained.
+
+         1
+               Greater than or equal to zero.
+
+         2
+               Greater than zero.
+
+          This option only has an effect if the `"enforce inequality
+          constraints"' option is nonzero.
+
+    `"initial step size"'
+          Differential-algebraic problems may occasionally suffer from
+          severe scaling difficulties on the first step.  If you know a
+          great deal about the scaling of your problem, you can help to
+          alleviate this problem by specifying an initial stepsize
+          (default is computed automatically).
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  This
+          option must be between 1 and 5, inclusive (default is 5).
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very
+          large regions (default is not specified).
+
+   Octave also includes DASSL, an earlier version of DASPK, and DASRT,
+which can be used to solve DAEs with constraints (stopping conditions).
+
+ -- Loadable Function: [X, XDOT, ISTATE, MSG] = dassl (FCN, X_0,
+          XDOT_0, T, T_CRIT)
+     Solve the set of differential-algebraic equations
+
+          0 = f (x, xdot, t)
+
+     with
+
+          x(t_0) = x_0, xdot(t_0) = xdot_0
+
+     The solution is returned in the matrices X and XDOT, with each row
+     in the result matrices corresponding to one of the elements in the
+     vector T.  The first element of T should be t_0 and correspond to
+     the initial state of the system X_0 and its derivative XDOT_0, so
+     that the first row of the output X is X_0 and the first row of the
+     output XDOT is XDOT_0.
+
+     The first argument, FCN, is a string, inline, or function handle
+     that names the function f to call to compute the vector of
+     residuals for the set of equations.  It must have the form
+
+          RES = f (X, XDOT, T)
+
+     in which X, XDOT, and RES are vectors, and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array
+     of strings, inline functions, or function handles, the first
+     element names the function f described above, and the second
+     element names a function to compute the modified Jacobian
+
+                df       df
+          jac = -- + c ------
+                dx     d xdot
+
+     The modified Jacobian function must have the form
+
+
+          JAC = j (X, XDOT, T, C)
+
+     The second and third arguments to `dassl' specify the initial
+     condition of the states and their derivatives, and the fourth
+     argument specifies a vector of output times at which the solution
+     is desired, including the time corresponding to the initial
+     condition.
+
+     The set of initial states and derivatives are not strictly
+     required to be consistent.  In practice, however, DASSL is not
+     very good at determining a consistent set for you, so it is best
+     if you ensure that the initial values result in the function
+     evaluating to zero.
+
+     The fifth argument is optional, and may be used to specify a set of
+     times that the DAE solver should not integrate past.  It is useful
+     for avoiding difficulties with singularities and points where
+     there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be
+     greater than zero (consistent with the Fortran version of DASSL).
+
+     If the computation is not successful, the value of ISTATE will be
+     less than zero and MSG will contain additional information.
+
+     You can use the function `dassl_options' to set optional
+     parameters for `dassl'.
+
+     *See also:* *note daspk: doc-daspk, *note dasrt: doc-dasrt, *note
+     lsode: doc-lsode.
+
+ -- Loadable Function:  dassl_options (OPT, VAL)
+     When called with two arguments, this function allows you set
+     options parameters for the function `dassl'.  Given one argument,
+     `dassl_options' returns the value of the corresponding option.  If
+     no arguments are supplied, the names of all the available options
+     and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector, and
+          the relative tolerance must also be a vector of the same
+          length.
+
+    `"relative tolerance"'
+          Relative tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector, and
+          the absolute tolerance must also be a vector of the same
+          length.
+
+          The local error test applied at each integration step is
+
+                 abs (local error in x(i))
+                      <= rtol(i) * abs (Y(i)) + atol(i)
+
+    `"compute consistent initial condition"'
+          If nonzero, `dassl' will attempt to compute a consistent set
+          of initial conditions.  This is generally not reliable, so it
+          is best to provide a consistent set and leave this option set
+          to zero.
+
+    `"enforce nonnegativity constraints"'
+          If you know that the solutions to your equations will always
+          be nonnegative, it may help to set this parameter to a nonzero
+          value.  However, it is probably best to try leaving this
+          option set to zero first, and only setting it to a nonzero
+          value if that doesn't work very well.
+
+    `"initial step size"'
+          Differential-algebraic problems may occasionally suffer from
+          severe scaling difficulties on the first step.  If you know a
+          great deal about the scaling of your problem, you can help to
+          alleviate this problem by specifying an initial stepsize.
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  This
+          option must be between 1 and 5, inclusive.
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very
+          large regions  (default is not specified).
+
+    `"step limit"'
+          Maximum number of integration steps to attempt on a single
+          call to the underlying Fortran code.
+
+ -- Loadable Function: [X, XDOT, T_OUT, ISTAT, MSG] = dasrt (FCN [, G],
+          X_0, XDOT_0, T [, T_CRIT])
+     Solve the set of differential-algebraic equations
+
+          0 = f (x, xdot, t)
+
+     with
+
+          x(t_0) = x_0, xdot(t_0) = xdot_0
+
+     with functional stopping criteria (root solving).
+
+     The solution is returned in the matrices X and XDOT, with each row
+     in the result matrices corresponding to one of the elements in the
+     vector T_OUT.  The first element of T should be t_0 and correspond
+     to the initial state of the system X_0 and its derivative XDOT_0,
+     so that the first row of the output X is X_0 and the first row of
+     the output XDOT is XDOT_0.
+
+     The vector T provides an upper limit on the length of the
+     integration.  If the stopping condition is met, the vector T_OUT
+     will be shorter than T, and the final element of T_OUT will be the
+     point at which the stopping condition was met, and may not
+     correspond to any element of the vector T.
+
+     The first argument, FCN, is a string, inline, or function handle
+     that names the function f to call to compute the vector of
+     residuals for the set of equations.  It must have the form
+
+          RES = f (X, XDOT, T)
+
+     in which X, XDOT, and RES are vectors, and T is a scalar.
+
+     If FCN is a two-element string array or a two-element cell array
+     of strings, inline functions, or function handles, the first
+     element names the function f described above, and the second
+     element names a function to compute the modified Jacobian
+
+                df       df
+          jac = -- + c ------
+                dx     d xdot
+
+     The modified Jacobian function must have the form
+
+
+          JAC = j (X, XDOT, T, C)
+
+     The optional second argument names a function that defines the
+     constraint functions whose roots are desired during the
+     integration.  This function must have the form
+
+          G_OUT = g (X, T)
+
+     and return a vector of the constraint function values.  If the
+     value of any of the constraint functions changes sign, DASRT will
+     attempt to stop the integration at the point of the sign change.
+
+     If the name of the constraint function is omitted, `dasrt' solves
+     the same problem as `daspk' or `dassl'.
+
+     Note that because of numerical errors in the constraint functions
+     due to roundoff and integration error, DASRT may return false
+     roots, or return the same root at two or more nearly equal values
+     of T.  If such false roots are suspected, the user should consider
+     smaller error tolerances or higher precision in the evaluation of
+     the constraint functions.
+
+     If a root of some constraint function defines the end of the
+     problem, the input to DASRT should nevertheless allow integration
+     to a point slightly past that root, so that DASRT can locate the
+     root by interpolation.
+
+     The third and fourth arguments to `dasrt' specify the initial
+     condition of the states and their derivatives, and the fourth
+     argument specifies a vector of output times at which the solution
+     is desired, including the time corresponding to the initial
+     condition.
+
+     The set of initial states and derivatives are not strictly
+     required to be consistent.  In practice, however, DASSL is not
+     very good at determining a consistent set for you, so it is best
+     if you ensure that the initial values result in the function
+     evaluating to zero.
+
+     The sixth argument is optional, and may be used to specify a set of
+     times that the DAE solver should not integrate past.  It is useful
+     for avoiding difficulties with singularities and points where
+     there is a discontinuity in the derivative.
+
+     After a successful computation, the value of ISTATE will be
+     greater than zero (consistent with the Fortran version of DASSL).
+
+     If the computation is not successful, the value of ISTATE will be
+     less than zero and MSG will contain additional information.
+
+     You can use the function `dasrt_options' to set optional
+     parameters for `dasrt'.
+
+     *See also:* *note daspk: doc-daspk, *note dasrt: doc-dasrt, *note
+     lsode: doc-lsode.
+
+ -- Loadable Function:  dasrt_options (OPT, VAL)
+     When called with two arguments, this function allows you set
+     options parameters for the function `dasrt'.  Given one argument,
+     `dasrt_options' returns the value of the corresponding option.  If
+     no arguments are supplied, the names of all the available options
+     and their current values are displayed.
+
+     Options include
+
+    `"absolute tolerance"'
+          Absolute tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector, and
+          the relative tolerance must also be a vector of the same
+          length.
+
+    `"relative tolerance"'
+          Relative tolerance.  May be either vector or scalar.  If a
+          vector, it must match the dimension of the state vector, and
+          the absolute tolerance must also be a vector of the same
+          length.
+
+          The local error test applied at each integration step is
+                 abs (local error in x(i)) <= ...
+                     rtol(i) * abs (Y(i)) + atol(i)
+
+    `"initial step size"'
+          Differential-algebraic problems may occasionally suffer from
+          severe scaling difficulties on the first step.  If you know a
+          great deal about the scaling of your problem, you can help to
+          alleviate this problem by specifying an initial stepsize.
+
+    `"maximum order"'
+          Restrict the maximum order of the solution method.  This
+          option must be between 1 and 5, inclusive.
+
+    `"maximum step size"'
+          Setting the maximum stepsize will avoid passing over very
+          large regions.
+
+    `"step limit"'
+          Maximum number of integration steps to attempt on a single
+          call to the underlying Fortran code.
+
+   See K. E. Brenan, et al., `Numerical Solution of Initial-Value
+Problems in Differential-Algebraic Equations', North-Holland (1989) for
+more information about the implementation of DASSL.
+
+
+File: octave.info,  Node: Optimization,  Next: Statistics,  Prev: Differential Equations,  Up: Top
+
+24 Optimization
+***************
+
+Octave comes with support for solving various kinds of optimization
+problems.  Specifically Octave can solve problems in Linear Programming,
+Quadratic Programming, Nonlinear Programming, and Linear Least Squares
+Minimization.
+
+* Menu:
+
+* Linear Programming::
+* Quadratic Programming::
+* Nonlinear Programming::
+* Linear Least Squares::
+
+
+File: octave.info,  Node: Linear Programming,  Next: Quadratic Programming,  Up: Optimization
+
+24.1 Linear Programming
+=======================
+
+Octave can solve Linear Programming problems using the `glpk' function.
+That is, Octave can solve
+
+     min C'*x
+   subject to the linear constraints A*x = b where x >= 0.
+
+The `glpk' function also supports variations of this problem.
+
+ -- Function File: [XOPT, FMIN, STATUS, EXTRA] = glpk (C, A, B, LB, UB,
+          CTYPE, VARTYPE, SENSE, PARAM)
+     Solve a linear program using the GNU GLPK library.  Given three
+     arguments, `glpk' solves the following standard LP:
+
+          min C'*x
+
+     subject to
+
+          A*x  = b
+            x >= 0
+
+     but may also solve problems of the form
+
+          [ min | max ] C'*x
+
+     subject to
+
+          A*x [ "=" | "<=" | ">=" ] b
+            x >= LB
+            x <= UB
+
+     Input arguments:
+
+    C
+          A column array containing the objective function coefficients.
+
+    A
+          A matrix containing the constraints coefficients.
+
+    B
+          A column array containing the right-hand side value for each
+          constraint in the constraint matrix.
+
+    LB
+          An array containing the lower bound on each of the variables.
+          If LB is not supplied, the default lower bound for the
+          variables is zero.
+
+    UB
+          An array containing the upper bound on each of the variables.
+          If UB is not supplied, the default upper bound is assumed to
+          be infinite.
+
+    CTYPE
+          An array of characters containing the sense of each
+          constraint in the constraint matrix.  Each element of the
+          array may be one of the following values
+         `"F"'
+               A free (unbounded) constraint (the constraint is
+               ignored).
+
+         `"U"'
+               An inequality constraint with an upper bound (`A(i,:)*x
+               <= b(i)').
+
+         `"S"'
+               An equality constraint (`A(i,:)*x = b(i)').
+
+         `"L"'
+               An inequality with a lower bound (`A(i,:)*x >= b(i)').
+
+         `"D"'
+               An inequality constraint with both upper and lower bounds
+               (`A(i,:)*x >= -b(i)' _and_ (`A(i,:)*x <= b(i)').
+
+    VARTYPE
+          A column array containing the types of the variables.
+         `"C"'
+               A continuous variable.
+
+         `"I"'
+               An integer variable.
+
+    SENSE
+          If SENSE is 1, the problem is a minimization.  If SENSE is
+          -1, the problem is a maximization.  The default value is 1.
+
+    PARAM
+          A structure containing the following parameters used to
+          define the behavior of solver.  Missing elements in the
+          structure take on default values, so you only need to set the
+          elements that you wish to change from the default.
+
+          Integer parameters:
+
+         `msglev (`LPX_K_MSGLEV', default: 1)'
+               Level of messages output by solver routines:
+              0
+                    No output.
+
+              1
+                    Error messages only.
+
+              2
+                    Normal output .
+
+              3
+                    Full output (includes informational messages).
+
+         `scale (`LPX_K_SCALE', default: 1)'
+               Scaling option:
+              0
+                    No scaling.
+
+              1
+                    Equilibration scaling.
+
+              2
+                    Geometric mean scaling, then equilibration scaling.
+
+         `dual	 (`LPX_K_DUAL', default: 0)'
+               Dual simplex option:
+              0
+                    Do not use the dual simplex.
+
+              1
+                    If initial basic solution is dual feasible, use the
+                    dual simplex.
+
+         `price	 (`LPX_K_PRICE', default: 1)'
+               Pricing option (for both primal and dual simplex):
+              0
+                    Textbook pricing.
+
+              1
+                    Steepest edge pricing.
+
+         `round	 (`LPX_K_ROUND', default: 0)'
+               Solution rounding option:
+              0
+                    Report all primal and dual values "as is".
+
+              1
+                    Replace tiny primal and dual values by exact zero.
+
+         `itlim	 (`LPX_K_ITLIM', default: -1)'
+               Simplex iterations limit.  If this value is positive, it
+               is decreased by one each time when one simplex iteration
+               has been performed, and reaching zero value signals the
+               solver to stop the search.  Negative value means no
+               iterations limit.
+
+         `itcnt (`LPX_K_OUTFRQ', default: 200)'
+               Output frequency, in iterations.  This parameter
+               specifies how frequently the solver sends information
+               about the solution to the standard output.
+
+         `branch (`LPX_K_BRANCH', default: 2)'
+               Branching heuristic option (for MIP only):
+              0
+                    Branch on the first variable.
+
+              1
+                    Branch on the last variable.
+
+              2
+                    Branch using a heuristic by Driebeck and Tomlin.
+
+         `btrack (`LPX_K_BTRACK', default: 2)'
+               Backtracking heuristic option (for MIP only):
+              0
+                    Depth first search.
+
+              1
+                    Breadth first search.
+
+              2
+                    Backtrack using the best projection heuristic.
+
+         `presol (`LPX_K_PRESOL', default: 1)'
+               If this flag is set, the routine lpx_simplex solves the
+               problem using the built-in LP presolver.  Otherwise the
+               LP presolver is not used.
+
+         `lpsolver (default: 1)'
+               Select which solver to use.  If the problem is a MIP
+               problem this flag will be ignored.
+              1
+                    Revised simplex method.
+
+              2
+                    Interior point method.
+
+         `save (default: 0)'
+               If this parameter is nonzero, save a copy of the problem
+               in CPLEX LP format to the file `"outpb.lp"'.  There is
+               currently no way to change the name of the output file.
+
+          Real parameters:
+
+         `relax (`LPX_K_RELAX', default: 0.07)'
+               Relaxation parameter used in the ratio test.  If it is
+               zero, the textbook ratio test is used.  If it is
+               non-zero (should be positive), Harris' two-pass ratio
+               test is used.  In the latter case on the first pass of
+               the ratio test basic variables (in the case of primal
+               simplex) or reduced costs of non-basic variables (in the
+               case of dual simplex) are allowed to slightly violate
+               their bounds, but not more than `relax*tolbnd' or
+               `relax*toldj (thus, `relax' is a percentage of `tolbnd'
+               or `toldj''.
+
+         `tolbnd (`LPX_K_TOLBND', default: 10e-7)'
+               Relative tolerance used to check if the current basic
+               solution is primal feasible.  It is not recommended that
+               you change this parameter unless you have a detailed
+               understanding of its purpose.
+
+         `toldj (`LPX_K_TOLDJ', default: 10e-7)'
+               Absolute tolerance used to check if the current basic
+               solution is dual feasible.  It is not recommended that
+               you change this parameter unless you have a detailed
+               understanding of its purpose.
+
+         `tolpiv (`LPX_K_TOLPIV', default: 10e-9)'
+               Relative tolerance used to choose eligible pivotal
+               elements of the simplex table.  It is not recommended
+               that you change this parameter unless you have a
+               detailed understanding of its purpose.
+
+         `objll (`LPX_K_OBJLL', default: -DBL_MAX)'
+               Lower limit of the objective function.  If on the phase
+               II the objective function reaches this limit and
+               continues decreasing, the solver stops the search.  This
+               parameter is used in the dual simplex method only.
+
+         `objul (`LPX_K_OBJUL', default: +DBL_MAX)'
+               Upper limit of the objective function.  If on the phase
+               II the objective function reaches this limit and
+               continues increasing, the solver stops the search.  This
+               parameter is used in the dual simplex only.
+
+         `tmlim (`LPX_K_TMLIM', default: -1.0)'
+               Searching time limit, in seconds.  If this value is
+               positive, it is decreased each time when one simplex
+               iteration has been performed by the amount of time spent
+               for the iteration, and reaching zero value signals the
+               solver to stop the search.  Negative value means no time
+               limit.
+
+         `outdly (`LPX_K_OUTDLY', default: 0.0)'
+               Output delay, in seconds.  This parameter specifies how
+               long the solver should delay sending information about
+               the solution to the standard output.  Non-positive value
+               means no delay.
+
+         `tolint (`LPX_K_TOLINT', default: 10e-5)'
+               Relative tolerance used to check if the current basic
+               solution is integer feasible.  It is not recommended
+               that you change this parameter unless you have a
+               detailed understanding of its purpose.
+
+         `tolobj (`LPX_K_TOLOBJ', default: 10e-7)'
+               Relative tolerance used to check if the value of the
+               objective function is not better than in the best known
+               integer feasible solution.  It is not recommended that
+               you change this parameter unless you have a detailed
+               understanding of its purpose.
+
+     Output values:
+
+    XOPT
+          The optimizer (the value of the decision variables at the
+          optimum).
+
+    FOPT
+          The optimum value of the objective function.
+
+    STATUS
+          Status of the optimization.
+
+          Simplex Method:
+         180 (`LPX_OPT')
+               Solution is optimal.
+
+         181 (`LPX_FEAS')
+               Solution is feasible.
+
+         182 (`LPX_INFEAS')
+               Solution is infeasible.
+
+         183 (`LPX_NOFEAS')
+               Problem has no feasible solution.
+
+         184 (`LPX_UNBND')
+               Problem has no unbounded solution.
+
+         185 (`LPX_UNDEF')
+               Solution status is undefined.
+          Interior Point Method:
+         150 (`LPX_T_UNDEF')
+               The interior point method is undefined.
+
+         151 (`LPX_T_OPT')
+               The interior point method is optimal.
+          Mixed Integer Method:
+         170 (`LPX_I_UNDEF')
+               The status is undefined.
+
+         171 (`LPX_I_OPT')
+               The solution is integer optimal.
+
+         172 (`LPX_I_FEAS')
+               Solution integer feasible but its optimality has not
+               been proven
+
+         173 (`LPX_I_NOFEAS')
+               No integer feasible solution.
+          If an error occurs, STATUS will contain one of the following
+          codes:
+
+         204 (`LPX_E_FAULT')
+               Unable to start the search.
+
+         205 (`LPX_E_OBJLL')
+               Objective function lower limit reached.
+
+         206 (`LPX_E_OBJUL')
+               Objective function upper limit reached.
+
+         207 (`LPX_E_ITLIM')
+               Iterations limit exhausted.
+
+         208 (`LPX_E_TMLIM')
+               Time limit exhausted.
+
+         209 (`LPX_E_NOFEAS')
+               No feasible solution.
+
+         210 (`LPX_E_INSTAB')
+               Numerical instability.
+
+         211 (`LPX_E_SING')
+               Problems with basis matrix.
+
+         212 (`LPX_E_NOCONV')
+               No convergence (interior).
+
+         213 (`LPX_E_NOPFS')
+               No primal feasible solution (LP presolver).
+
+         214 (`LPX_E_NODFS')
+               No dual feasible solution (LP presolver).
+
+    EXTRA
+          A data structure containing the following fields:
+         `lambda'
+               Dual variables.
+
+         `redcosts'
+               Reduced Costs.
+
+         `time'
+               Time (in seconds) used for solving LP/MIP problem.
+
+         `mem'
+               Memory (in bytes) used for solving LP/MIP problem (this
+               is not available if the version of GLPK is 4.15 or
+               later).
+
+     Example:
+
+          c = [10, 6, 4]';
+          a = [ 1, 1, 1;
+               10, 4, 5;
+                2, 2, 6];
+          b = [100, 600, 300]';
+          lb = [0, 0, 0]';
+          ub = [];
+          ctype = "UUU";
+          vartype = "CCC";
+          s = -1;
+
+          param.msglev = 1;
+          param.itlim = 100;
+
+          [xmin, fmin, status, extra] = ...
+             glpk (c, a, b, lb, ub, ctype, vartype, s, param);
+
+
+File: octave.info,  Node: Quadratic Programming,  Next: Nonlinear Programming,  Prev: Linear Programming,  Up: Optimization
+
+24.2 Quadratic Programming
+==========================
+
+Octave can also solve Quadratic Programming problems, this is
+     min 0.5 x'*H*x + x'*q
+   subject to
+          A*x = b
+          lb <= x <= ub
+          A_lb <= A_in*x <= A_ub
+
+ -- Function File: [X, OBJ, INFO, LAMBDA] = qp (X0, H, Q, A, B, LB, UB,
+          A_LB, A_IN, A_UB)
+     Solve the quadratic program
+
+               min 0.5 x'*H*x + x'*q
+                x
+
+     subject to
+
+               A*x = b
+               lb <= x <= ub
+               A_lb <= A_in*x <= A_ub
+
+     using a null-space active-set method.
+
+     Any bound (A, B, LB, UB, A_LB, A_UB) may be set to the empty
+     matrix (`[]') if not present.  If the initial guess is feasible
+     the algorithm is faster.
+
+     The value INFO is a structure with the following fields:
+    `solveiter'
+          The number of iterations required to find the solution.
+
+    `info'
+          An integer indicating the status of the solution, as follows:
+         0
+               The problem is feasible and convex.  Global solution
+               found.
+
+         1
+               The problem is not convex.  Local solution found.
+
+         2
+               The problem is not convex and unbounded.
+
+         3
+               Maximum number of iterations reached.
+
+         6
+               The problem is infeasible.
+
+
+File: octave.info,  Node: Nonlinear Programming,  Next: Linear Least Squares,  Prev: Quadratic Programming,  Up: Optimization
+
+24.3 Nonlinear Programming
+==========================
+
+Octave can also perform general nonlinear minimization using a
+successive quadratic programming solver.
+
+ -- Function File: [X, OBJ, INFO, ITER, NF, LAMBDA] = sqp (X, PHI, G,
+          H, LB, UB, MAXITER, TOLERANCE)
+     Solve the nonlinear program
+
+               min phi (x)
+                x
+
+     subject to
+
+               g(x)  = 0
+               h(x) >= 0
+               lb <= x <= ub
+
+     using a successive quadratic programming method.
+
+     The first argument is the initial guess for the vector X.
+
+     The second argument is a function handle pointing to the objective
+     function.  The objective function must be of the form
+
+               y = phi (x)
+
+     in which X is a vector and Y is a scalar.
+
+     The second argument may also be a 2- or 3-element cell array of
+     function handles.  The first element should point to the objective
+     function, the second should point to a function that computes the
+     gradient of the objective function, and the third should point to a
+     function to compute the hessian of the objective function.  If the
+     gradient function is not supplied, the gradient is computed by
+     finite differences.  If the hessian function is not supplied, a
+     BFGS update formula is used to approximate the hessian.
+
+     If supplied, the gradient function must be of the form
+
+          g = gradient (x)
+
+     in which X is a vector and G is a vector.
+
+     If supplied, the hessian function must be of the form
+
+          h = hessian (x)
+
+     in which X is a vector and H is a matrix.
+
+     The third and fourth arguments are function handles pointing to
+     functions that compute the equality constraints and the inequality
+     constraints, respectively.
+
+     If your problem does not have equality (or inequality) constraints,
+     you may pass an empty matrix for CEF (or CIF).
+
+     If supplied, the equality and inequality constraint functions must
+     be of the form
+
+          r = f (x)
+
+     in which X is a vector and R is a vector.
+
+     The third and fourth arguments may also be 2-element cell arrays of
+     function handles.  The first element should point to the constraint
+     function and the second should point to a function that computes
+     the gradient of the constraint function:
+
+                          [ d f(x)   d f(x)        d f(x) ]
+              transpose ( [ ------   -----   ...   ------ ] )
+                          [  dx_1     dx_2          dx_N  ]
+
+     The fifth and sixth arguments are vectors containing lower and
+     upper bounds on X.  These must be consistent with equality and
+     inequality constraints G and H.  If the bounds are not specified,
+     or are empty, they are set to -REALMAX and REALMAX by default.
+
+     The seventh argument is max. number of iterations.  If not
+     specified, the default value is 100.
+
+     The eighth argument is tolerance for stopping criteria.  If not
+     specified, the default value is EPS.
+
+     Here is an example of calling `sqp':
+
+          function r = g (x)
+            r = [ sumsq(x)-10;
+                  x(2)*x(3)-5*x(4)*x(5);
+                  x(1)^3+x(2)^3+1 ];
+          endfunction
+
+          function obj = phi (x)
+            obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+          endfunction
+
+          x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+
+          [x, obj, info, iter, nf, lambda] = sqp (x0, @phi, @g, [])
+
+          x =
+
+            -1.71714
+             1.59571
+             1.82725
+            -0.76364
+            -0.76364
+
+          obj = 0.053950
+          info = 101
+          iter = 8
+          nf = 10
+          lambda =
+
+            -0.0401627
+             0.0379578
+            -0.0052227
+
+     The value returned in INFO may be one of the following:
+    101
+          The algorithm terminated because the norm of the last step
+          was less than `tol * norm (x))' (the value of tol is
+          currently fixed at `sqrt (eps)'--edit `sqp.m' to modify this
+          value.
+
+    102
+          The BFGS update failed.
+
+    103
+          The maximum number of iterations was reached (the maximum
+          number of allowed iterations is currently fixed at 100--edit
+          `sqp.m' to increase this value).
+
+     *See also:* *note qp: doc-qp.
+
+
+File: octave.info,  Node: Linear Least Squares,  Prev: Nonlinear Programming,  Up: Optimization
+
+24.4 Linear Least Squares
+=========================
+
+Octave also supports linear least squares minimization.  That is,
+Octave can find the parameter b such that the model y = x*b fits data
+(x,y) as well as possible, assuming zero-mean Gaussian noise.  If the
+noise is assumed to be isotropic the problem can be solved using the
+`\' or `/' operators, or the `ols' function.  In the general case where
+the noise is assumed to be anisotropic the `gls' is needed.
+
+ -- Function File: [BETA, SIGMA, R] = ols (Y, X)
+     Ordinary least squares estimation for the multivariate model y = x
+     b + e with mean (e) = 0 and cov (vec (e)) = kron (s, I).   where y
+     is a t by p matrix, x is a t by k matrix, b is a k by p matrix, and
+     e is a t by p matrix.
+
+     Each row of Y and X is an observation and each column a variable.
+
+     The return values BETA, SIGMA, and R are defined as follows.
+
+    BETA
+          The OLS estimator for B, `BETA = pinv (X) * Y', where `pinv
+          (X)' denotes the pseudoinverse of X.
+
+    SIGMA
+          The OLS estimator for the matrix S,
+
+               SIGMA = (Y-X*BETA)'
+                 * (Y-X*BETA)
+                 / (T-rank(X))
+
+    R
+          The matrix of OLS residuals, `R = Y - X * BETA'.
+
+ -- Function File: [BETA, V, R] = gls (Y, X, O)
+     Generalized least squares estimation for the multivariate model y
+     = x b + e with mean (e) = 0 and cov (vec (e)) = (s^2) o,  where y
+     is a t by p matrix, x is a t by k matrix, b is a k by p matrix, e
+     is a t by p matrix, and o is a t p by t p matrix.
+
+     Each row of Y and X is an observation and each column a variable.
+     The return values BETA, V, and R are defined as follows.
+
+    BETA
+          The GLS estimator for b.
+
+    V
+          The GLS estimator for s^2.
+
+    R
+          The matrix of GLS residuals, r = y - x beta.
+
+ -- Function File: X = lsqnonneg (C, D)
+ -- Function File: X = lsqnonneg (C, D, X0)
+ -- Function File: [X, RESNORM] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL, EXITFLAG] = lsqnonneg (...)
+ -- Function File: [X, RESNORM, RESIDUAL, EXITFLAG, OUTPUT] = lsqnonneg
+          (...)
+ -- Function File: [X, RESNORM, RESIDUAL, EXITFLAG, OUTPUT, LAMBDA] =
+lsqnonneg (...)
+     Minimize `norm (C*X-d)' subject to `X >= 0'.  C and D must be
+     real.  X0 is an optional initial guess for X.
+
+     Outputs:
+        * resnorm
+
+          The squared 2-norm of the residual: norm(C*X-D)^2
+
+        * residual
+
+          The residual: D-C*X
+
+        * exitflag
+
+          An indicator of convergence.  0 indicates that the iteration
+          count was exceeded, and therefore convergence was not
+          reached; >0 indicates that the algorithm converged.  (The
+          algorithm is stable and will converge given enough
+          iterations.)
+
+        * output
+
+          A structure with two fields:
+             * "algorithm": The algorithm used ("nnls")
+
+             * "iterations": The number of iterations taken.
+
+        * lambda
+
+          Not implemented.
+
+     *See also:* *note optimset: doc-optimset.
+
+ -- Function File:  optimset ()
+ -- Function File:  optimset (PAR, VAL, ...)
+ -- Function File:  optimset (OLD, PAR, VAL, ...)
+ -- Function File:  optimset (OLD, NEW)
+     Create options struct for optimization functions.
+
+ -- Function File:  optimget (OPTIONS, PARNAME)
+ -- Function File:  optimget (OPTIONS, PARNAME, DEFAULT)
+     Return a specific option from a structure created by `optimset'.
+     If PARNAME is not a field of the OPTIONS structure, return DEFAULT
+     if supplied, otherwise return an empty matrix.
+
+
+File: octave.info,  Node: Statistics,  Next: Sets,  Prev: Optimization,  Up: Top
+
+25 Statistics
+*************
+
+Octave has support for various statistical methods.  This includes
+basic descriptive statistics, statistical tests, random number
+generation, and much more.
+
+   The functions that analyze data all assume that multidimensional data
+is arranged in a matrix where each row is an observation, and each
+column is a variable.  So, the matrix defined by
+
+     a = [ 0.9, 0.7;
+           0.1, 0.1;
+           0.5, 0.4 ];
+
+contains three observations from a two-dimensional distribution.  While
+this is the default data arrangement, most functions support different
+arrangements.
+
+   It should be noted that the statistics functions don't test for data
+containing NaN, NA, or Inf.  Such values need to be handled explicitly.
+
+* Menu:
+
+* Descriptive Statistics::
+* Basic Statistical Functions::
+* Statistical Plots::
+* Tests::
+* Models::
+* Distributions::
+* Random Number Generation::
+
+
+File: octave.info,  Node: Descriptive Statistics,  Next: Basic Statistical Functions,  Up: Statistics
+
+25.1 Descriptive Statistics
+===========================
+
+Octave can compute various statistics such as the moments of a data set.
+
+ -- Function File:  mean (X, DIM, OPT)
+     If X is a vector, compute the mean of the elements of X
+
+          mean (x) = SUM_i x(i) / N
+     If X is a matrix, compute the mean for each column and return them
+     in a row vector.
+
+     With the optional argument OPT, the kind of mean computed can be
+     selected.  The following options are recognized:
+
+    `"a"'
+          Compute the (ordinary) arithmetic mean.  This is the default.
+
+    `"g"'
+          Compute the geometric mean.
+
+    `"h"'
+          Compute the harmonic mean.
+
+     If the optional argument DIM is supplied, work along dimension DIM.
+
+     Both DIM and OPT are optional.  If both are supplied, either may
+     appear first.
+
+ -- Function File:  median (X, DIM)
+     If X is a vector, compute the median value of the elements of X.
+     If the elements of X are sorted, the median is defined as
+
+                      x(ceil(N/2)),             N odd
+          median(x) =
+                      (x(N/2) + x((N/2)+1))/2,  N even
+     If X is a matrix, compute the median value for each column and
+     return them in a row vector.  If the optional DIM argument is
+     given, operate along this dimension.
+
+     *See also:* *note std: doc-std, *note mean: doc-mean.
+
+ -- Function File: Q = quantile (X, P)
+ -- Function File: Q = quantile (X, P, DIM)
+ -- Function File: Q = quantile (X, P, DIM, METHOD)
+     For a sample, X, calculate the quantiles, Q, corresponding to the
+     cumulative probability values in P.  All non-numeric values (NaNs)
+     of X are ignored.
+
+     If X is a matrix, compute the quantiles for each column and return
+     them in a matrix, such that the i-th row of Q contains the P(i)th
+     quantiles of each column of X.
+
+     The optional argument DIM determines the dimension along which the
+     percentiles are calculated.  If DIM is omitted, and X is a vector
+     or matrix, it defaults to 1 (column wise quantiles).  In the
+     instance that X is a N-d array, DIM defaults to the first
+     dimension whose size greater than unity.
+
+     The methods available to calculate sample quantiles are the nine
+     methods used by R (http://www.r-project.org/).  The default value
+     is METHOD = 5.
+
+     Discontinuous sample quantile methods 1, 2, and 3
+
+       1. Method 1: Inverse of empirical distribution function.
+
+       2. Method 2: Similar to method 1 but with averaging at
+          discontinuities.
+
+       3. Method 3: SAS definition: nearest even order statistic.
+
+     Continuous sample quantile methods 4 through 9, where p(k) is the
+     linear interpolation function respecting each methods'
+     representative cdf.
+
+       4. Method 4: p(k) = k / n. That is, linear interpolation of the
+          empirical cdf.
+
+       5. Method 5: p(k) = (k - 0.5) / n. That is a piecewise linear
+          function where the knots are the values midway through the
+          steps of the empirical cdf.
+
+       6. Method 6: p(k) = k / (n + 1).
+
+       7. Method 7: p(k) = (k - 1) / (n - 1).
+
+       8. Method 8: p(k) = (k - 1/3) / (n + 1/3).  The resulting
+          quantile estimates are approximately median-unbiased
+          regardless of the distribution of X.
+
+       9. Method 9: p(k) = (k - 3/8) / (n + 1/4).  The resulting
+          quantile estimates are approximately unbiased for the
+          expected order statistics if X is normally distributed.
+
+     Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R
+     (versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS
+     use method 6.  MATLAB uses method 5.
+
+     References:
+
+        * Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New
+          S Language.  Wadsworth & Brooks/Cole.
+
+        * Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in
+          statistical packages, American Statistician, 50, 361-365.
+
+        * R: A Language and Environment for Statistical Computing;
+          `http://cran.r-project.org/doc/manuals/fullrefman.pdf'.
+
+ -- Function File: Y = prctile (X, P)
+ -- Function File: Q = prctile (X, P, DIM)
+     For a sample X, compute the quantiles, Y, corresponding to the
+     cumulative probability values, P, in percent.  All non-numeric
+     values (NaNs) of X are ignored.
+
+     If X is a matrix, compute the percentiles for each column and
+     return them in a matrix, such that the i-th row of Y contains the
+     P(i)th percentiles of each column of X.
+
+     The optional argument DIM determines the dimension along which the
+     percentiles are calculated.  If DIM is omitted, and X is a vector
+     or matrix, it defaults to 1 (column wise quantiles).  In the
+     instance that X is a N-d array, DIM defaults to the first
+     dimension whose size greater than unity.
+
+
+ -- Function File:  meansq (X)
+ -- Function File:  meansq (X, DIM)
+     For vector arguments, return the mean square of the values.  For
+     matrix arguments, return a row vector containing the mean square
+     of each column.  With the optional DIM argument, returns the mean
+     squared of the values along this dimension.
+
+ -- Function File:  std (X)
+ -- Function File:  std (X, OPT)
+ -- Function File:  std (X, OPT, DIM)
+     If X is a vector, compute the standard deviation of the elements
+     of X.
+
+          std (x) = sqrt (sumsq (x - mean (x)) / (n - 1))
+     If X is a matrix, compute the standard deviation for each column
+     and return them in a row vector.
+
+     The argument OPT determines the type of normalization to use.
+     Valid values are
+
+    0:
+          normalizes with N-1, provides the square root of best
+          unbiased estimator of   the variance [default]
+
+    1:
+          normalizes with N, this provides the square root of the
+          second moment around   the mean
+
+     The third argument DIM determines the dimension along which the
+     standard deviation is calculated.
+
+     *See also:* *note mean: doc-mean, *note median: doc-median.
+
+ -- Function File:  var (X)
+     For vector arguments, return the (real) variance of the values.
+     For matrix arguments, return a row vector containing the variance
+     for each column.
+
+     The argument OPT determines the type of normalization to use.
+     Valid values are
+
+    0:
+          Normalizes with N-1, provides the best unbiased estimator of
+          the variance [default].
+
+    1:
+          Normalizes with N, this provides the second moment around the
+          mean.
+
+     The third argument DIM determines the dimension along which the
+     variance is calculated.
+
+ -- Function File: [M, F, C] = mode (X, DIM)
+     Count the most frequently appearing value.  `mode' counts the
+     frequency along the first non-singleton dimension and if two or
+     more values have the same frequency returns the smallest of the
+     two in M.  The dimension along which to count can be specified by
+     the DIM parameter.
+
+     The variable F counts the frequency of each of the most frequently
+     occurring elements.  The cell array C contains all of the elements
+     with the maximum frequency .
+
+ -- Function File:  cov (X, Y)
+     Compute covariance.
+
+     If each row of X and Y is an observation and each column is a
+     variable, the (I, J)-th entry of `cov (X, Y)' is the covariance
+     between the I-th variable in X and the J-th variable in Y.  If
+     called with one argument, compute `cov (X, X)'.
+
+ -- Function File:  cor (X, Y)
+     Compute correlation.
+
+     The (I, J)-th entry of `cor (X, Y)' is the correlation between the
+     I-th variable in X and the J-th variable in Y.
+
+          corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+
+     For matrices, each row is an observation and each column a
+     variable; vectors are always observations and may be row or column
+     vectors.
+
+     `cor (X)' is equivalent to `cor (X, X)'.
+
+     Note that the `corrcoef' function does the same as `cor'.
+
+ -- Function File:  corrcoef (X, Y)
+     Compute correlation.
+
+     If each row of X and Y is an observation and each column is a
+     variable, the (I, J)-th entry of `corrcoef (X, Y)' is the
+     correlation between the I-th variable in X and the J-th variable
+     in Y.
+
+          corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+
+     If called with one argument, compute `corrcoef (X, X)'.
+
+ -- Function File:  kurtosis (X, DIM)
+     If X is a vector of length N, return the kurtosis
+
+          kurtosis (x) = N^(-1) std(x)^(-4) sum ((x - mean(x)).^4) - 3
+
+     of X.  If X is a matrix, return the kurtosis over the first
+     non-singleton dimension.  The optional argument DIM can be given
+     to force the kurtosis to be given over that dimension.
+
+ -- Function File:  skewness (X, DIM)
+     If X is a vector of length n, return the skewness
+
+          skewness (x) = N^(-1) std(x)^(-3) sum ((x - mean(x)).^3)
+
+     of X.  If X is a matrix, return the skewness along the first
+     non-singleton dimension of the matrix.  If the optional DIM
+     argument is given, operate along this dimension.
+
+ -- Function File:  statistics (X)
+     If X is a matrix, return a matrix with the minimum, first
+     quartile, median, third quartile, maximum, mean, standard
+     deviation, skewness and kurtosis of the columns of X as its
+     columns.
+
+     If X is a vector, calculate the statistics along the non-singleton
+     dimension.
+
+ -- Function File:  moment (X, P, OPT, DIM)
+     If X is a vector, compute the P-th moment of X.
+
+     If X is a matrix, return the row vector containing the P-th moment
+     of each column.
+
+     With the optional string opt, the kind of moment to be computed can
+     be specified.  If opt contains `"c"' or `"a"', central and/or
+     absolute moments are returned.  For example,
+
+          moment (x, 3, "ac")
+
+     computes the third central absolute moment of X.
+
+     If the optional argument DIM is supplied, work along dimension DIM.
+
+
+File: octave.info,  Node: Basic Statistical Functions,  Next: Statistical Plots,  Prev: Descriptive Statistics,  Up: Statistics
+
+25.2 Basic Statistical Functions
+================================
+
+Octave also supports various helpful statistical functions.
+
+ -- Function File:  mahalanobis (X, Y)
+     Return the Mahalanobis' D-square distance between the multivariate
+     samples X and Y, which must have the same number of components
+     (columns), but may have a different number of observations (rows).
+
+ -- Function File:  center (X)
+ -- Function File:  center (X, DIM)
+     If X is a vector, subtract its mean.  If X is a matrix, do the
+     above for each column.  If the optional argument DIM is given,
+     perform the above operation along this dimension
+
+ -- Function File:  studentize (X, DIM)
+     If X is a vector, subtract its mean and divide by its standard
+     deviation.
+
+     If X is a matrix, do the above along the first non-singleton
+     dimension.  If the optional argument DIM is given then operate
+     along this dimension.
+
+ -- Function File: C = nchoosek (N, K)
+     Compute the binomial coefficient or all combinations of N.  If N
+     is a scalar then, calculate the binomial coefficient of N and K,
+     defined as
+
+           /   \
+           | n |    n (n-1) (n-2) ... (n-k+1)       n!
+           |   |  = ------------------------- =  ---------
+           | k |               k!                k! (n-k)!
+           \   /
+
+     If N is a vector generate all combinations of the elements of N,
+     taken K at a time, one row per combination.  The resulting C has
+     size `[nchoosek (length (N), K), K]'.
+
+     `nchoosek' works only for non-negative integer arguments; use
+     `bincoeff' for non-integer scalar arguments and for using vector
+     arguments to compute many coefficients at once.
+
+     *See also:* *note bincoeff: doc-bincoeff.
+
+ -- Function File: N = histc (Y, EDGES)
+ -- Function File: N = histc (Y, EDGES, DIM)
+ -- Function File: [N, IDX] = histc (...)
+     Produce histogram counts.
+
+     When Y is a vector, the function counts the number of elements of
+     Y that fall in the histogram bins defined by EDGES.  This must be
+     a vector of monotonically non-decreasing values that define the
+     edges of the histogram bins.  So, `N (k)' contains the number of
+     elements in Y for which `EDGES (k) <= Y < EDGES (k+1)'.  The final
+     element of N contains the number of elements of Y that was equal
+     to the last element of EDGES.
+
+     When Y is a N-dimensional array, the same operation as above is
+     repeated along dimension DIM.  If this argument is given, the
+     operation is performed along the first non-singleton dimension.
+
+     If a second output argument is requested an index matrix is also
+     returned.  The IDX matrix has same size as Y.  Each element of IDX
+     contains the index of the histogram bin in which the corresponding
+     element of Y was counted.
+
+     *See also:* *note hist: doc-hist.
+
+ -- Function File:  perms (V)
+     Generate all permutations of V, one row per permutation.  The
+     result has size `factorial (N) * N', where N is the length of V.
+
+     As an example, `perms([1, 2, 3])' returns the matrix
+            1   2   3
+            2   1   3
+            1   3   2
+            2   3   1
+            3   1   2
+            3   2   1
+
+ -- Function File:  values (X)
+     Return the different values in a column vector, arranged in
+     ascending order.
+
+     As an example, `values([1, 2, 3, 1])' returns the vector `[1, 2,
+     3]'.
+
+ -- Function File: [T, L_X] = table (X)
+ -- Function File: [T, L_X, L_Y] = table (X, Y)
+     Create a contingency table T from data vectors.  The L vectors are
+     the corresponding levels.
+
+     Currently, only 1- and 2-dimensional tables are supported.
+
+ -- Function File:  spearman (X, Y)
+     Compute Spearman's rank correlation coefficient RHO for each of
+     the variables specified by the input arguments.
+
+     For matrices, each row is an observation and each column a
+     variable; vectors are always observations and may be row or column
+     vectors.
+
+     `spearman (X)' is equivalent to `spearman (X, X)'.
+
+     For two data vectors X and Y, Spearman's RHO is the correlation of
+     the ranks of X and Y.
+
+     If X and Y are drawn from independent distributions, RHO has zero
+     mean and variance `1 / (n - 1)', and is asymptotically normally
+     distributed.
+
+ -- Function File:  run_count (X, N)
+     Count the upward runs along the first non-singleton dimension of X
+     of length 1, 2, ..., N-1 and greater than or equal to N.  If the
+     optional argument DIM is given operate along this dimension
+
+ -- Function File:  ranks (X, DIM)
+     Return the ranks of X along the first non-singleton dimension
+     adjust for ties.  If the optional argument DIM is given, operate
+     along this dimension.
+
+ -- Function File:  range (X)
+ -- Function File:  range (X, DIM)
+     If X is a vector, return the range, i.e., the difference between
+     the maximum and the minimum, of the input data.
+
+     If X is a matrix, do the above for each column of X.
+
+     If the optional argument DIM is supplied, work along dimension DIM.
+
+ -- Function File:  probit (P)
+     For each component of P, return the probit (the quantile of the
+     standard normal distribution) of P.
+
+ -- Function File:  logit (P)
+     For each component of P, return the logit of P defined as
+          logit(P) = log (P / (1-P))
+
+ -- Function File:  cloglog (X)
+     Return the complementary log-log function of X, defined as
+
+          cloglog(x) = - log (- log (X))
+
+ -- Function File:  kendall (X, Y)
+     Compute Kendall's TAU for each of the variables specified by the
+     input arguments.
+
+     For matrices, each row is an observation and each column a
+     variable; vectors are always observations and may be row or column
+     vectors.
+
+     `kendall (X)' is equivalent to `kendall (X, X)'.
+
+     For two data vectors X, Y of common length N, Kendall's TAU is the
+     correlation of the signs of all rank differences of X and Y;
+     i.e., if both X and Y have distinct entries, then
+
+                   1
+          tau = -------   SUM sign (q(i) - q(j)) * sign (r(i) - r(j))
+                n (n-1)   i,j
+
+     in which the Q(I) and R(I)  are the ranks of X and Y, respectively.
+
+     If X and Y are drawn from independent distributions, Kendall's TAU
+     is asymptotically normal with mean 0 and variance `(2 * (2N+5)) /
+     (9 * N * (N-1))'.
+
+ -- Function File:  iqr (X, DIM)
+     If X is a vector, return the interquartile range, i.e., the
+     difference between the upper and lower quartile, of the input data.
+
+     If X is a matrix, do the above for first non-singleton dimension
+     of X.  If the option DIM argument is given, then operate along
+     this dimension.
+
+ -- Function File:  cut (X, BREAKS)
+     Create categorical data out of numerical or continuous data by
+     cutting into intervals.
+
+     If BREAKS is a scalar, the data is cut into that many equal-width
+     intervals.  If BREAKS is a vector of break points, the category
+     has `length (BREAKS) - 1' groups.
+
+     The returned value is a vector of the same size as X telling which
+     group each point in X belongs to.  Groups are labelled from 1 to
+     the number of groups; points outside the range of BREAKS are
+     labelled by `NaN'.
+
+
+File: octave.info,  Node: Statistical Plots,  Next: Tests,  Prev: Basic Statistical Functions,  Up: Statistics
+
+25.3 Statistical Plots
+======================
+
+Octave can create Quantile Plots (QQ-Plots), and Probability Plots
+(PP-Plots).  These are simple graphical tests for determining if a data
+set comes from a certain distribution.
+
+   Note that Octave can also show histograms of data using the `hist'
+function as described in *note Two-Dimensional Plots::.
+
+ -- Function File: [Q, S] = qqplot (X, DIST, PARAMS)
+     Perform a QQ-plot (quantile plot).
+
+     If F is the CDF of the distribution DIST with parameters PARAMS
+     and G its inverse, and X a sample vector of length N, the QQ-plot
+     graphs ordinate S(I) = I-th largest element of x versus abscissa
+     Q(If) = G((I - 0.5)/N).
+
+     If the sample comes from F except for a transformation of location
+     and scale, the pairs will approximately follow a straight line.
+
+     The default for DIST is the standard normal distribution.  The
+     optional argument PARAMS contains a list of parameters of DIST.
+     For example, for a quantile plot of the uniform distribution on
+     [2,4] and X, use
+
+          qqplot (x, "uniform", 2, 4)
+
+     DIST can be any string for which a function DIST_INV that
+     calculates the inverse CDF of distribution DIST exists.
+
+     If no output arguments are given, the data are plotted directly.
+
+ -- Function File: [P, Y] = ppplot (X, DIST, PARAMS)
+     Perform a PP-plot (probability plot).
+
+     If F is the CDF of the distribution DIST with parameters PARAMS
+     and X a sample vector of length N, the PP-plot graphs ordinate
+     Y(I) = F (I-th largest element of X) versus abscissa P(I) = (I -
+     0.5)/N.  If the sample comes from F, the pairs will approximately
+     follow a straight line.
+
+     The default for DIST is the standard normal distribution.  The
+     optional argument PARAMS contains a list of parameters of DIST.
+     For example, for a probability plot of the uniform distribution on
+     [2,4] and X, use
+
+          ppplot (x, "uniform", 2, 4)
+
+     DIST can be any string for which a function DIST_CDF that
+     calculates the CDF of distribution DIST exists.
+
+     If no output arguments are given, the data are plotted directly.
+
+
+File: octave.info,  Node: Tests,  Next: Models,  Prev: Statistical Plots,  Up: Statistics
+
+25.4 Tests
+==========
+
+Octave can perform several different statistical tests.  The following
+table summarizes the available tests.
+
+*Hypothesis*                  *Test Functions*
+Equal mean values             `anova', `hotelling_test2',
+                              `t_test_2',        `welch_test',
+                              `wilcoxon_test', `z_test_2'
+Equal medians                 `kruskal_wallis_test', `sign_test'
+Equal variances               `bartlett_test', `manova',
+                              `var_test'
+Equal distributions           `chisquare_test_homogeneity',
+                              `kolmogorov_smirnov_test_2',
+                              `u_test'
+Equal marginal frequencies    `mcnemar_test'
+Equal success probabilities   `prop_test_2'
+Independent observations      `chisquare_test_independence',
+                              `run_test'
+Uncorrelated observations     `cor_test'
+Given mean value              `hotelling_test', `t_test', `z_test'
+Observations from given       `kolmogorov_smirnov_test'
+distribution                  
+Regression                    `f_test_regression',
+                              `t_test_regression'
+
+   The tests return a p-value that describes the outcome of the test.
+Assuming that the test hypothesis is true, the p-value is the
+probability of obtaining a worse result than the observed one.  So
+large p-values corresponds to a successful test.  Usually a test
+hypothesis is accepted if the p-value exceeds 0.05.
+
+ -- Function File: [PVAL, F, DF_B, DF_W] = anova (Y, G)
+     Perform a one-way analysis of variance (ANOVA).  The goal is to
+     test whether the population means of data taken from K different
+     groups are all equal.
+
+     Data may be given in a single vector Y with groups specified by a
+     corresponding vector of group labels G (e.g., numbers from 1 to
+     K).  This is the general form which does not impose any
+     restriction on the number of data in each group or the group
+     labels.
+
+     If Y is a matrix and G is omitted, each column of Y is treated as
+     a group.  This form is only appropriate for balanced ANOVA in
+     which the numbers of samples from each group are all equal.
+
+     Under the null of constant means, the statistic F follows an F
+     distribution with DF_B and DF_W degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at F) is
+     returned in PVAL.
+
+     If no output argument is given, the standard one-way ANOVA table is
+     printed.
+
+ -- Function File: [PVAL, CHISQ, DF] = bartlett_test (X1, ...)
+     Perform a Bartlett test for the homogeneity of variances in the
+     data vectors X1, X2, ..., XK, where K > 1.
+
+     Under the null of equal variances, the test statistic CHISQ
+     approximately follows a chi-square distribution with DF degrees of
+     freedom.
+
+     The p-value (1 minus the CDF of this distribution at CHISQ) is
+     returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, CHISQ, DF] = chisquare_test_homogeneity (X,
+          Y, C)
+     Given two samples X and Y, perform a chisquare test for
+     homogeneity of the null hypothesis that X and Y come from the same
+     distribution, based on the partition induced by the (strictly
+     increasing) entries of C.
+
+     For large samples, the test statistic CHISQ approximately follows a
+     chisquare distribution with DF = `length (C)' degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at CHISQ) is
+     returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, CHISQ, DF] = chisquare_test_independence (X)
+     Perform a chi-square test for independence based on the contingency
+     table X.  Under the null hypothesis of independence, CHISQ
+     approximately has a chi-square distribution with DF degrees of
+     freedom.
+
+     The p-value (1 minus the CDF of this distribution at chisq) of the
+     test is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File:  cor_test (X, Y, ALT, METHOD)
+     Test whether two samples X and Y come from uncorrelated
+     populations.
+
+     The optional argument string ALT describes the alternative
+     hypothesis, and can be `"!="' or `"<>"' (non-zero), `">"' (greater
+     than 0), or `"<"' (less than 0).  The default is the two-sided
+     case.
+
+     The optional argument string METHOD specifies on which correlation
+     coefficient the test should be based.  If METHOD is `"pearson"'
+     (default), the (usual) Pearson's product moment correlation
+     coefficient is used.  In this case, the data should come from a
+     bivariate normal distribution.  Otherwise, the other two methods
+     offer nonparametric alternatives.  If METHOD is `"kendall"', then
+     Kendall's rank correlation tau is used.  If METHOD is
+     `"spearman"', then Spearman's rank correlation rho is used.  Only
+     the first character is necessary.
+
+     The output is a structure with the following elements:
+
+    PVAL
+          The p-value of the test.
+
+    STAT
+          The value of the test statistic.
+
+    DIST
+          The distribution of the test statistic.
+
+    PARAMS
+          The parameters of the null distribution of the test statistic.
+
+    ALTERNATIVE
+          The alternative hypothesis.
+
+    METHOD
+          The method used for testing.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, F, DF_NUM, DF_DEN] = f_test_regression (Y, X,
+          RR, R)
+     Perform an F test for the null hypothesis rr * b = r in a classical
+     normal regression model y = X * b + e.
+
+     Under the null, the test statistic F follows an F distribution
+     with DF_NUM and DF_DEN degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at F) is
+     returned in PVAL.
+
+     If not given explicitly, R = 0.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, TSQ] = hotelling_test (X, M)
+     For a sample X from a multivariate normal distribution with unknown
+     mean and covariance matrix, test the null hypothesis that `mean
+     (X) == M'.
+
+     Hotelling's T^2 is returned in TSQ.  Under the null, (n-p) T^2 /
+     (p(n-1)) has an F distribution with p and n-p degrees of freedom,
+     where n and p are the numbers of samples and variables,
+     respectively.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, TSQ] = hotelling_test_2 (X, Y)
+     For two samples X from multivariate normal distributions with the
+     same number of variables (columns), unknown means and unknown
+     equal covariance matrices, test the null hypothesis `mean (X) ==
+     mean (Y)'.
+
+     Hotelling's two-sample T^2 is returned in TSQ.  Under the null,
+
+          (n_x+n_y-p-1) T^2 / (p(n_x+n_y-2))
+
+     has an F distribution with p and n_x+n_y-p-1 degrees of freedom,
+     where n_x and n_y are the sample sizes and p is the number of
+     variables.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, KS] = kolmogorov_smirnov_test (X, DIST,
+          PARAMS, ALT)
+     Perform a Kolmogorov-Smirnov test of the null hypothesis that the
+     sample X comes from the (continuous) distribution dist.  I.e., if
+     F and G are the CDFs corresponding to the sample and dist,
+     respectively, then the null is that F == G.
+
+     The optional argument PARAMS contains a list of parameters of
+     DIST.  For example, to test whether a sample X comes from a
+     uniform distribution on [2,4], use
+
+          kolmogorov_smirnov_test(x, "uniform", 2, 4)
+
+     DIST can be any string for which a function DIST_CDF that
+     calculates the CDF of distribution DIST exists.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative F != G.  In this case, the test
+     statistic KS follows a two-sided Kolmogorov-Smirnov distribution.
+     If ALT is `">"', the one-sided alternative F > G is considered.
+     Similarly for `"<"', the one-sided alternative F > G is
+     considered.  In this case, the test statistic KS has a one-sided
+     Kolmogorov-Smirnov distribution.  The default is the two-sided
+     case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, KS, D] = kolmogorov_smirnov_test_2 (X, Y, ALT)
+     Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis
+     that the samples X and Y come from the same (continuous)
+     distribution.  I.e., if F and G are the CDFs corresponding to the
+     X and Y samples, respectively, then the null is that F == G.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative F != G.  In this case, the test
+     statistic KS follows a two-sided Kolmogorov-Smirnov distribution.
+     If ALT is `">"', the one-sided alternative F > G is considered.
+     Similarly for `"<"', the one-sided alternative F < G is
+     considered.  In this case, the test statistic KS has a one-sided
+     Kolmogorov-Smirnov distribution.  The default is the two-sided
+     case.
+
+     The p-value of the test is returned in PVAL.
+
+     The third returned value, D, is the test statistic, the maximum
+     vertical distance between the two cumulative distribution
+     functions.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, K, DF] = kruskal_wallis_test (X1, ...)
+     Perform a Kruskal-Wallis one-factor "analysis of variance".
+
+     Suppose a variable is observed for K > 1 different groups, and let
+     X1, ..., XK be the corresponding data vectors.
+
+     Under the null hypothesis that the ranks in the pooled sample are
+     not affected by the group memberships, the test statistic K is
+     approximately chi-square with DF = K - 1 degrees of freedom.
+
+     If the data contains ties (some value appears more than once) K is
+     divided by
+
+     1 - SUM_TIES / (N^3 - N)
+
+     where SUM_TIES is the sum of T^2 - T over each group of ties where
+     T is the number of ties in the group and N is the total number of
+     values in the input data.  For more info on this adjustment see
+     "Use of Ranks in One-Criterion Variance Analysis" in Journal of
+     the American Statistical Association, Vol. 47, No. 260 (Dec 1952)
+     by William H. Kruskal and W. Allen Wallis.
+
+     The p-value (1 minus the CDF of this distribution at K) is
+     returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File:  manova (Y, G)
+     Perform a one-way multivariate analysis of variance (MANOVA).  The
+     goal is to test whether the p-dimensional population means of data
+     taken from K different groups are all equal.  All data are assumed
+     drawn independently from p-dimensional normal distributions with
+     the same covariance matrix.
+
+     The data matrix is given by Y.  As usual, rows are observations
+     and columns are variables.  The vector G specifies the
+     corresponding group labels (e.g., numbers from 1 to K).
+
+     The LR test statistic (Wilks' Lambda) and approximate p-values are
+     computed and displayed.
+
+ -- Function File: [PVAL, CHISQ, DF] = mcnemar_test (X)
+     For a square contingency table X of data cross-classified on the
+     row and column variables, McNemar's test can be used for testing
+     the null hypothesis of symmetry of the classification
+     probabilities.
+
+     Under the null, CHISQ is approximately distributed as chisquare
+     with DF degrees of freedom.
+
+     The p-value (1 minus the CDF of this distribution at CHISQ) is
+     returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, Z] = prop_test_2 (X1, N1, X2, N2, ALT)
+     If X1 and N1 are the counts of successes and trials in one sample,
+     and X2 and N2 those in a second one, test the null hypothesis that
+     the success probabilities P1 and P2 are the same.  Under the null,
+     the test statistic Z approximately follows a standard normal
+     distribution.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative P1 != P2.  If ALT is `">"', the
+     one-sided alternative P1 > P2 is used.  Similarly for `"<"', the
+     one-sided alternative P1 < P2 is used.  The default is the
+     two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, CHISQ] = run_test (X)
+     Perform a chi-square test with 6 degrees of freedom based on the
+     upward runs in the columns of X.  Can be used to test whether X
+     contains independent data.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File: [PVAL, B, N] = sign_test (X, Y, ALT)
+     For two matched-pair samples X and Y, perform a sign test of the
+     null hypothesis PROB (X > Y) == PROB (X < Y) == 1/2.  Under the
+     null, the test statistic B roughly follows a binomial distribution
+     with parameters `N = sum (X != Y)' and P = 1/2.
+
+     With the optional argument `alt', the alternative of interest can
+     be selected.  If ALT is `"!="' or `"<>"', the null hypothesis is
+     tested against the two-sided alternative PROB (X < Y) != 1/2.  If
+     ALT is `">"', the one-sided alternative PROB (X > Y) > 1/2 ("x is
+     stochastically greater than y") is considered.  Similarly for
+     `"<"', the one-sided alternative PROB (X > Y) < 1/2 ("x is
+     stochastically less than y") is considered.  The default is the
+     two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, T, DF] = t_test (X, M, ALT)
+     For a sample X from a normal distribution with unknown mean and
+     variance, perform a t-test of the null hypothesis `mean (X) == M'.
+     Under the null, the test statistic T follows a Student
+     distribution with `DF = length (X) - 1' degrees of freedom.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `mean (X) != M'.  If ALT is
+     `">"', the one-sided alternative `mean (X) > M' is considered.
+     Similarly for "<", the one-sided alternative `mean (X) < M' is
+     considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, T, DF] = t_test_2 (X, Y, ALT)
+     For two samples x and y from normal distributions with unknown
+     means and unknown equal variances, perform a two-sample t-test of
+     the null hypothesis of equal means.  Under the null, the test
+     statistic T follows a Student distribution with DF degrees of
+     freedom.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `mean (X) != mean (Y)'.  If ALT
+     is `">"', the one-sided alternative `mean (X) > mean (Y)' is used.
+     Similarly for `"<"', the one-sided alternative `mean (X) < mean
+     (Y)' is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, T, DF] = t_test_regression (Y, X, RR, R, ALT)
+     Perform an t test for the null hypothesis `RR * B = R' in a
+     classical normal regression model `Y = X * B + E'.  Under the
+     null, the test statistic T follows a T distribution with DF
+     degrees of freedom.
+
+     If R is omitted, a value of 0 is assumed.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `RR * B != R'.  If ALT is `">"',
+     the one-sided alternative `RR * B > R' is used.  Similarly for
+     "<", the one-sided alternative `RR * B < R' is used.  The default
+     is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, Z] = u_test (X, Y, ALT)
+     For two samples X and Y, perform a Mann-Whitney U-test of the null
+     hypothesis PROB (X > Y) == 1/2 == PROB (X < Y).  Under the null,
+     the test statistic Z approximately follows a standard normal
+     distribution.  Note that this test is equivalent to the Wilcoxon
+     rank-sum test.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative PROB (X > Y) != 1/2.  If ALT is
+     `">"', the one-sided alternative PROB (X > Y) > 1/2 is considered.
+     Similarly for `"<"', the one-sided alternative PROB (X > Y) < 1/2
+     is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, F, DF_NUM, DF_DEN] = var_test (X, Y, ALT)
+     For two samples X and Y from normal distributions with unknown
+     means and unknown variances, perform an F-test of the null
+     hypothesis of equal variances.  Under the null, the test statistic
+     F follows an F-distribution with DF_NUM and DF_DEN degrees of
+     freedom.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `var (X) != var (Y)'.  If ALT is
+     `">"', the one-sided alternative `var (X) > var (Y)' is used.
+     Similarly for "<", the one-sided alternative `var (X) > var (Y)'
+     is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, T, DF] = welch_test (X, Y, ALT)
+     For two samples X and Y from normal distributions with unknown
+     means and unknown and not necessarily equal variances, perform a
+     Welch test of the null hypothesis of equal means.  Under the null,
+     the test statistic T approximately follows a Student distribution
+     with DF degrees of freedom.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `mean (X) != M'.  If ALT is
+     `">"', the one-sided alternative mean(x) > M is considered.
+     Similarly for `"<"', the one-sided alternative mean(x) < M is
+     considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, Z] = wilcoxon_test (X, Y, ALT)
+     For two matched-pair sample vectors X and Y, perform a Wilcoxon
+     signed-rank test of the null hypothesis PROB (X > Y) == 1/2.
+     Under the null, the test statistic Z approximately follows a
+     standard normal distribution when N > 25.
+
+     *Warning*: This function assumes a normal distribution for Z and
+     thus is invalid for N <= 25.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative PROB (X > Y) != 1/2.  If alt is
+     `">"', the one-sided alternative PROB (X > Y) > 1/2 is considered.
+     Similarly for `"<"', the one-sided alternative PROB (X > Y) < 1/2
+     is considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed.
+
+ -- Function File: [PVAL, Z] = z_test (X, M, V, ALT)
+     Perform a Z-test of the null hypothesis `mean (X) == M' for a
+     sample X from a normal distribution with unknown mean and known
+     variance V.  Under the null, the test statistic Z follows a
+     standard normal distribution.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `mean (X) != M'.  If ALT is
+     `">"', the one-sided alternative `mean (X) > M' is considered.
+     Similarly for `"<"', the one-sided alternative `mean (X) < M' is
+     considered.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed along with some information.
+
+ -- Function File: [PVAL, Z] = z_test_2 (X, Y, V_X, V_Y, ALT)
+     For two samples X and Y from normal distributions with unknown
+     means and known variances V_X and V_Y, perform a Z-test of the
+     hypothesis of equal means.  Under the null, the test statistic Z
+     follows a standard normal distribution.
+
+     With the optional argument string ALT, the alternative of interest
+     can be selected.  If ALT is `"!="' or `"<>"', the null is tested
+     against the two-sided alternative `mean (X) != mean (Y)'.  If alt
+     is `">"', the one-sided alternative `mean (X) > mean (Y)' is used.
+     Similarly for `"<"', the one-sided alternative `mean (X) < mean
+     (Y)' is used.  The default is the two-sided case.
+
+     The p-value of the test is returned in PVAL.
+
+     If no output argument is given, the p-value of the test is
+     displayed along with some information.
+
+
+File: octave.info,  Node: Models,  Next: Distributions,  Prev: Tests,  Up: Statistics
+
+25.5 Models
+===========
+
+ -- Function File: [THETA, BETA, DEV, DL, D2L, P] = logistic_regression
+          (Y, X, PRINT, THETA, BETA)
+     Perform ordinal logistic regression.
+
+     Suppose Y takes values in K ordered categories, and let `gamma_i
+     (X)' be the cumulative probability that Y falls in one of the
+     first I categories given the covariate X.  Then
+
+          [theta, beta] = logistic_regression (y, x)
+
+     fits the model
+
+          logit (gamma_i (x)) = theta_i - beta' * x,   i = 1 ... k-1
+
+     The number of ordinal categories, K, is taken to be the number of
+     distinct values of `round (Y)'.  If K equals 2, Y is binary and
+     the model is ordinary logistic regression.  The matrix X is
+     assumed to have full column rank.
+
+     Given Y only, `theta = logistic_regression (y)' fits the model
+     with baseline logit odds only.
+
+     The full form is
+
+          [theta, beta, dev, dl, d2l, gamma]
+             = logistic_regression (y, x, print, theta, beta)
+
+     in which all output arguments and all input arguments except Y are
+     optional.
+
+     Setting PRINT to 1 requests summary information about the fitted
+     model to be displayed.  Setting PRINT to 2 requests information
+     about convergence at each iteration.  Other values request no
+     information to be displayed.  The input arguments THETA and BETA
+     give initial estimates for THETA and BETA.
+
+     The returned value DEV holds minus twice the log-likelihood.
+
+     The returned values DL and D2L are the vector of first and the
+     matrix of second derivatives of the log-likelihood with respect to
+     THETA and BETA.
+
+     P holds estimates for the conditional distribution of Y given X.
+
+
+File: octave.info,  Node: Distributions,  Next: Random Number Generation,  Prev: Models,  Up: Statistics
+
+25.6 Distributions
+==================
+
+Octave has functions for computing the Probability Density Function
+(PDF), the Cumulative Distribution function (CDF), and the quantile
+(the inverse of the CDF) of a large number of distributions.
+
+   The following table summarizes the supported distributions (in
+alphabetical order).
+
+*Distribution*         *PDF*             *CDF*             *Quantile*
+Beta Distribution      `betapdf'         `betacdf'         `betainv'
+Binomial Distribution  `binopdf'         `binocdf'         `binoinv'
+Cauchy Distribution    `cauchy_pdf'      `cauchy_cdf'      `cauchy_inv'
+Chi-Square             `chi2pdf'         `chi2cdf'         `chi2inv'
+Distribution                                               
+Univariate Discrete    `discrete_pdf'    `discrete_cdf'    `discrete_inv'
+Distribution                                               
+Empirical Distribution `empirical_pdf'   `empirical_cdf'   `empirical_inv'
+Exponential            `exppdf'          `expcdf'          `expinv'
+Distribution                                               
+F Distribution         `fpdf'            `fcdf'            `finv'
+Gamma Distribution     `gampdf'          `gamcdf'          `gaminv'
+Geometric Distribution `geopdf'          `geocdf'          `geoinv'
+Hypergeometric         `hygepdf'         `hygecdf'         `hygeinv'
+Distribution                                               
+Kolmogorov Smirnov     _Not Available_   `kolmogorov_smirnov_cdf'_Not Available_
+Distribution                                               
+Laplace Distribution   `laplace_pdf'     `laplace_cdf'     `laplace_inv'
+Logistic Distribution  `logistic_pdf'    `logistic_cdf'    `logistic_inv'
+Log-Normal             `lognpdf'         `logncdf'         `logninv'
+Distribution                                               
+Pascal Distribution    `nbinpdf'         `nbincdf'         `nbininv'
+Univariate Normal      `normpdf'         `normcdf'         `norminv'
+Distribution                                               
+Poisson Distribution   `poisspdf'        `poisscdf'        `poissinv'
+t (Student)            `tpdf'            `tcdf'            `tinv'
+Distribution                                               
+Univariate Discrete    `unidpdf'         `unidcdf'         `unidinv'
+Distribution                                               
+Uniform Distribution   `unifpdf'         `unifcdf'         `unifinv'
+Weibull Distribution   `wblpdf'          `wblcdf'          `wblinv'
+
+ -- Function File:  betacdf (X, A, B)
+     For each element of X, returns the CDF at X of the beta
+     distribution with parameters A and B, i.e., PROB (beta (A, B) <=
+     X).
+
+ -- Function File:  betainv (X, A, B)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the Beta distribution with parameters A and B.
+
+ -- Function File:  betapdf (X, A, B)
+     For each element of X, returns the PDF at X of the beta
+     distribution with parameters A and B.
+
+ -- Function File:  binocdf (X, N, P)
+     For each element of X, compute the CDF at X of the binomial
+     distribution with parameters N and P.
+
+ -- Function File:  binoinv (X, N, P)
+     For each element of X, compute the quantile at X of the binomial
+     distribution with parameters N and P.
+
+ -- Function File:  binopdf (X, N, P)
+     For each element of X, compute the probability density function
+     (PDF) at X of the binomial distribution with parameters N and P.
+
+ -- Function File:  cauchy_cdf (X, LAMBDA, SIGMA)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the Cauchy distribution with location
+     parameter LAMBDA and scale parameter SIGMA.  Default values are
+     LAMBDA = 0, SIGMA = 1.
+
+ -- Function File:  cauchy_inv (X, LAMBDA, SIGMA)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the Cauchy distribution with location parameter
+     LAMBDA and scale parameter SIGMA.  Default values are LAMBDA = 0,
+     SIGMA = 1.
+
+ -- Function File:  cauchy_pdf (X, LAMBDA, SIGMA)
+     For each element of X, compute the probability density function
+     (PDF) at X of the Cauchy distribution with location parameter
+     LAMBDA and scale parameter SIGMA > 0.  Default values are LAMBDA =
+     0, SIGMA = 1.
+
+ -- Function File:  chi2cdf (X, N)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the chisquare distribution with N degrees
+     of freedom.
+
+ -- Function File:  chi2inv (X, N)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the chisquare distribution with N degrees of freedom.
+
+ -- Function File:  chisquare_pdf (X, N)
+     For each element of X, compute the probability density function
+     (PDF) at X of the chisquare distribution with N degrees of freedom.
+
+ -- Function File:  discrete_cdf (X, V, P)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of a univariate discrete distribution which
+     assumes the values in V with probabilities P.
+
+ -- Function File:  discrete_inv (X, V, P)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the univariate distribution which assumes the values
+     in V with probabilities P.
+
+ -- Function File:  discrete_pdf (X, V, P)
+     For each element of X, compute the probability density function
+     (PDF) at X of a univariate discrete distribution which assumes the
+     values in V with probabilities P.
+
+ -- Function File:  empirical_cdf (X, DATA)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the empirical distribution obtained from
+     the univariate sample DATA.
+
+ -- Function File:  empirical_inv (X, DATA)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the empirical distribution obtained from the
+     univariate sample DATA.
+
+ -- Function File:  empirical_pdf (X, DATA)
+     For each element of X, compute the probability density function
+     (PDF) at X of the empirical distribution obtained from the
+     univariate sample DATA.
+
+ -- Function File:  expcdf (X, LAMBDA)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the exponential distribution with mean
+     LAMBDA.
+
+     The arguments can be of common size or scalar.
+
+ -- Function File:  expinv (X, LAMBDA)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the exponential distribution with mean LAMBDA.
+
+ -- Function File:  exppdf (X, LAMBDA)
+     For each element of X, compute the probability density function
+     (PDF) of the exponential distribution with mean LAMBDA.
+
+ -- Function File:  fcdf (X, M, N)
+     For each element of X, compute the CDF at X of the F distribution
+     with M and N degrees of freedom, i.e., PROB (F (M, N) <= X).
+
+ -- Function File:  finv (X, M, N)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the F distribution with parameters M and N.
+
+ -- Function File:  fpdf (X, M, N)
+     For each element of X, compute the probability density function
+     (PDF) at X of the F distribution with M and N degrees of freedom.
+
+ -- Function File:  gamcdf (X, A, B)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the Gamma distribution with parameters A
+     and B.
+
+     *See also:* *note gamma: doc-gamma, *note gammaln: doc-gammaln,
+     *note gammainc: doc-gammainc, *note gampdf: doc-gampdf, *note
+     gaminv: doc-gaminv, *note gamrnd: doc-gamrnd.
+
+ -- Function File:  gaminv (X, A, B)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the Gamma distribution with parameters A and B.
+
+     *See also:* *note gamma: doc-gamma, *note gammaln: doc-gammaln,
+     *note gammainc: doc-gammainc, *note gampdf: doc-gampdf, *note
+     gamcdf: doc-gamcdf, *note gamrnd: doc-gamrnd.
+
+ -- Function File:  gampdf (X, A, B)
+     For each element of X, return the probability density function
+     (PDF) at X of the Gamma distribution with parameters A and B.
+
+     *See also:* *note gamma: doc-gamma, *note gammaln: doc-gammaln,
+     *note gammainc: doc-gammainc, *note gamcdf: doc-gamcdf, *note
+     gaminv: doc-gaminv, *note gamrnd: doc-gamrnd.
+
+ -- Function File:  geocdf (X, P)
+     For each element of X, compute the CDF at X of the geometric
+     distribution with parameter P.
+
+ -- Function File:  geoinv (X, P)
+     For each element of X, compute the quantile at X of the geometric
+     distribution with parameter P.
+
+ -- Function File:  geopdf (X, P)
+     For each element of X, compute the probability density function
+     (PDF) at X of the geometric distribution with parameter P.
+
+ -- Function File:  hygecdf (X, T, M, N)
+     Compute the cumulative distribution function (CDF) at X of the
+     hypergeometric distribution with parameters T, M, and N.  This is
+     the probability of obtaining not more than X marked items when
+     randomly drawing a sample of size N without replacement from a
+     population of total size T containing M marked items.
+
+     The parameters T, M, and N must positive integers with M and N not
+     greater than T.
+
+ -- Function File:  hygeinv (X, T, M, N)
+     For each element of X, compute the quantile at X of the
+     hypergeometric distribution with parameters T, M, and N.
+
+     The parameters T, M, and N must positive integers with M and N not
+     greater than T.
+
+ -- Function File:  hygepdf (X, T, M, N)
+     Compute the probability density function (PDF) at X of the
+     hypergeometric distribution with parameters T, M, and N.  This is
+     the probability of obtaining X marked items when randomly drawing
+     a sample of size N without replacement from a population of total
+     size T containing M marked items.
+
+     The arguments must be of common size or scalar.
+
+ -- Function File:  kolmogorov_smirnov_cdf (X, TOL)
+     Return the CDF at X of the Kolmogorov-Smirnov distribution,
+                   Inf
+          Q(x) =   SUM    (-1)^k exp(-2 k^2 x^2)
+                 k = -Inf
+
+     for X > 0.
+
+     The optional parameter TOL specifies the precision up to which the
+     series should be evaluated;  the default is TOL = `eps'.
+
+ -- Function File:  laplace_cdf (X)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the Laplace distribution.
+
+ -- Function File:  laplace_inv (X)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the Laplace distribution.
+
+ -- Function File:  laplace_pdf (X)
+     For each element of X, compute the probability density function
+     (PDF) at X of the Laplace distribution.
+
+ -- Function File:  logistic_cdf (X)
+     For each component of X, compute the CDF at X of the logistic
+     distribution.
+
+ -- Function File:  logistic_inv (X)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the logistic distribution.
+
+ -- Function File:  logistic_pdf (X)
+     For each component of X, compute the PDF at X of the logistic
+     distribution.
+
+ -- Function File:  logncdf (X, MU, SIGMA)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the lognormal distribution with parameters
+     MU and SIGMA.  If a random variable follows this distribution, its
+     logarithm is normally distributed with mean MU and standard
+     deviation SIGMA.
+
+     Default values are MU = 1, SIGMA = 1.
+
+ -- Function File:  logninv (X, MU, SIGMA)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the lognormal distribution with parameters MU and
+     SIGMA.  If a random variable follows this distribution, its
+     logarithm is normally distributed with mean `log (MU)' and
+     variance SIGMA.
+
+     Default values are MU = 1, SIGMA = 1.
+
+ -- Function File:  lognpdf (X, MU, SIGMA)
+     For each element of X, compute the probability density function
+     (PDF) at X of the lognormal distribution with parameters MU and
+     SIGMA.  If a random variable follows this distribution, its
+     logarithm is normally distributed with mean MU and standard
+     deviation SIGMA.
+
+     Default values are MU = 1, SIGMA = 1.
+
+ -- Function File:  nbincdf (X, N, P)
+     For each element of X, compute the CDF at x of the Pascal
+     (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success
+     probability P before the N-th success follows this distribution.
+
+ -- Function File:  nbininv (X, N, P)
+     For each element of X, compute the quantile at X of the Pascal
+     (negative binomial) distribution with parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success
+     probability P before the N-th success follows this distribution.
+
+ -- Function File:  nbinpdf (X, N, P)
+     For each element of X, compute the probability density function
+     (PDF) at X of the Pascal (negative binomial) distribution with
+     parameters N and P.
+
+     The number of failures in a Bernoulli experiment with success
+     probability P before the N-th success follows this distribution.
+
+ -- Function File:  normcdf (X, M, S)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the normal distribution with mean M and
+     standard deviation S.
+
+     Default values are M = 0, S = 1.
+
+ -- Function File:  norminv (X, M, S)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the normal distribution with mean M and standard
+     deviation S.
+
+     Default values are M = 0, S = 1.
+
+ -- Function File:  normpdf (X, M, S)
+     For each element of X, compute the probability density function
+     (PDF) at X of the normal distribution with mean M and standard
+     deviation S.
+
+     Default values are M = 0, S = 1.
+
+ -- Function File:  poisscdf (X, LAMBDA)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the Poisson distribution with parameter
+     lambda.
+
+ -- Function File:  poissinv (X, LAMBDA)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the Poisson distribution with parameter LAMBDA.
+
+ -- Function File:  poisspdf (X, LAMBDA)
+     For each element of X, compute the probability density function
+     (PDF) at X of the poisson distribution with parameter LAMBDA.
+
+ -- Function File:  tcdf (X, N)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of the t (Student) distribution with N degrees
+     of freedom, i.e., PROB (t(N) <= X).
+
+ -- Function File:  tinv (X, N)
+     For each probability value X, compute the inverse of the
+     cumulative distribution function (CDF) of the t (Student)
+     distribution with degrees of freedom N.  This function is
+     analogous to looking in a table for the t-value of a single-tailed
+     distribution.
+
+ -- Function File:  tpdf (X, N)
+     For each element of X, compute the probability density function
+     (PDF) at X of the T (Student) distribution with N degrees of
+     freedom.
+
+ -- Function File:  unidcdf (X, V)
+     For each element of X, compute the cumulative distribution
+     function (CDF) at X of a univariate discrete distribution which
+     assumes the values in V with equal probability.
+
+ -- Function File:  unidinv (X, V)
+     For each component of X, compute the quantile (the inverse of the
+     CDF) at X of the univariate discrete distribution which assumes the
+     values in V with equal probability
+
+ -- Function File:  unidpdf (X, V)
+     For each element of X, compute the probability density function
+     (PDF) at X of a univariate discrete distribution which assumes the
+     values in V with equal probability.
+
+ -- Function File:  unifcdf (X, A, B)
+     Return the CDF at X of the uniform distribution on [A, B], i.e.,
+     PROB (uniform (A, B) <= x).
+
+     Default values are A = 0, B = 1.
+
+ -- Function File:  unifinv (X, A, B)
+     For each element of X, compute the quantile (the inverse of the
+     CDF) at X of the uniform distribution on [A, B].
+
+     Default values are A = 0, B = 1.
+
+ -- Function File:  unifpdf (X, A, B)
+     For each element of X, compute the PDF at X of the uniform
+     distribution on [A, B].
+
+     Default values are A = 0, B = 1.
+
+ -- Function File:  wblcdf (X, SCALE, SHAPE)
+     Compute the cumulative distribution function (CDF) at X of the
+     Weibull distribution with shape parameter SCALE and scale
+     parameter SHAPE, which is
+
+          1 - exp(-(x/shape)^scale)
+     for X >= 0.
+
+ -- Function File:  wblinv (X, SCALE, SHAPE)
+     Compute the quantile (the inverse of the CDF) at X of the Weibull
+     distribution with shape parameter SCALE and scale parameter SHAPE.
+
+ -- Function File:  wblpdf (X, SCALE, SHAPE)
+     Compute the probability density function (PDF) at X of the Weibull
+     distribution with shape parameter SCALE and scale parameter SHAPE
+     which is given by
+
+             scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+
+     for X > 0.
+
+
+File: octave.info,  Node: Random Number Generation,  Prev: Distributions,  Up: Statistics
+
+25.7 Random Number Generation
+=============================
+
+Octave can generate random numbers from a large number of distributions.
+The random number generators are based on the random number generators
+described in *note Special Utility Matrices::.
+
+   The following table summarizes the available random number generators
+(in alphabetical order).
+
+*Distribution*                *Function*
+Beta Distribution             `betarnd'
+Binomial Distribution         `binornd'
+Cauchy Distribution           `cauchy_rnd'
+Chi-Square Distribution       `chi2rnd'
+Univariate Discrete           `discrete_rnd'
+Distribution                  
+Empirical Distribution        `empirical_rnd'
+Exponential Distribution      `exprnd'
+F Distribution                `frnd'
+Gamma Distribution            `gamrnd'
+Geometric Distribution        `geornd'
+Hypergeometric Distribution   `hygernd'
+Laplace Distribution          `laplace_rnd'
+Logistic Distribution         `logistic_rnd'
+Log-Normal Distribution       `lognrnd'
+Pascal Distribution           `nbinrnd'
+Univariate Normal             `normrnd'
+Distribution                  
+Poisson Distribution          `poissrnd'
+t (Student) Distribution      `trnd'
+Univariate Discrete           `unidrnd'
+Distribution                  
+Uniform Distribution          `unifrnd'
+Weibull Distribution          `wblrnd'
+Wiener Process                `wienrnd'
+
+ -- Function File:  betarnd (A, B, R, C)
+ -- Function File:  betarnd (A, B, SZ)
+     Return an R by C or `size (SZ)' matrix of random samples from the
+     Beta distribution with parameters A and B.  Both A and B must be
+     scalar or of size R  by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of A and B.
+
+ -- Function File:  binornd (N, P, R, C)
+ -- Function File:  binornd (N, P, SZ)
+     Return an R by C  or a `size (SZ)' matrix of random samples from
+     the binomial distribution with parameters N and P.  Both N and P
+     must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of N and P.
+
+ -- Function File:  cauchy_rnd (LAMBDA, SIGMA, R, C)
+ -- Function File:  cauchy_rnd (LAMBDA, SIGMA, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from
+     the Cauchy distribution with parameters LAMBDA and SIGMA which
+     must both be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of LAMBDA and SIGMA.
+
+ -- Function File:  chi2rnd (N, R, C)
+ -- Function File:  chi2rnd (N, SZ)
+     Return an R by C  or a `size (SZ)' matrix of random samples from
+     the chisquare distribution with N degrees of freedom.  N must be a
+     scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the size
+     of N.
+
+ -- Function File:  discrete_rnd (N, V, P)
+ -- Function File:  discrete_rnd (V, P, R, C)
+ -- Function File:  discrete_rnd (V, P, SZ)
+     Generate a row vector containing a random sample of size N from
+     the univariate distribution which assumes the values in V with
+     probabilities P.  N must be a scalar.
+
+     If R and C are given create a matrix with R rows and C columns.
+     Or if SZ is a vector, create a matrix of size SZ.
+
+ -- Function File:  empirical_rnd (N, DATA)
+ -- Function File:  empirical_rnd (DATA, R, C)
+ -- Function File:  empirical_rnd (DATA, SZ)
+     Generate a bootstrap sample of size N from the empirical
+     distribution obtained from the univariate sample DATA.
+
+     If R and C are given create a matrix with R rows and C columns.
+     Or if SZ is a vector, create a matrix of size SZ.
+
+ -- Function File:  exprnd (LAMBDA, R, C)
+ -- Function File:  exprnd (LAMBDA, SZ)
+     Return an R by C matrix of random samples from the exponential
+     distribution with mean LAMBDA, which must be a scalar or of size R
+     by C.  Or if SZ is a vector, create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the size
+     of LAMBDA.
+
+ -- Function File:  frnd (M, N, R, C)
+ -- Function File:  frnd (M, N, SZ)
+     Return an R by C matrix of random samples from the F distribution
+     with M and N degrees of freedom.  Both M and N must be scalar or
+     of size R by C.  If SZ is a vector the random samples are in a
+     matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of M and N.
+
+ -- Function File:  gamrnd (A, B, R, C)
+ -- Function File:  gamrnd (A, B, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from
+     the Gamma distribution with parameters A and B.  Both A and B must
+     be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of A and B.
+
+     *See also:* *note gamma: doc-gamma, *note gammaln: doc-gammaln,
+     *note gammainc: doc-gammainc, *note gampdf: doc-gampdf, *note
+     gamcdf: doc-gamcdf, *note gaminv: doc-gaminv.
+
+ -- Function File:  geornd (P, R, C)
+ -- Function File:  geornd (P, SZ)
+     Return an R by C matrix of random samples from the geometric
+     distribution with parameter P, which must be a scalar or of size R
+     by C.
+
+     If R and C are given create a matrix with R rows and C columns.
+     Or if SZ is a vector, create a matrix of size SZ.
+
+ -- Function File:  hygernd (T, M, N, R, C)
+ -- Function File:  hygernd (T, M, N, SZ)
+ -- Function File:  hygernd (T, M, N)
+     Return an R by C matrix of random samples from the hypergeometric
+     distribution with parameters T, M, and N.
+
+     The parameters T, M, and N must positive integers with M and N not
+     greater than T.
+
+     The parameter SZ must be scalar or a vector of matrix dimensions.
+     If SZ is scalar, then a SZ by SZ matrix of random samples is
+     generated.
+
+ -- Function File:  laplace_rnd (R, C)
+ -- Function File:  laplace_rnd (SZ);
+     Return an R by C matrix of random numbers from the Laplace
+     distribution.  Or if SZ is a vector, create a matrix of SZ.
+
+ -- Function File:  logistic_rnd (R, C)
+ -- Function File:  logistic_rnd (SZ)
+     Return an R by C matrix of random numbers from the logistic
+     distribution.  Or if SZ is a vector, create a matrix of SZ.
+
+ -- Function File:  lognrnd (MU, SIGMA, R, C)
+ -- Function File:  lognrnd (MU, SIGMA, SZ)
+     Return an R by C matrix of random samples from the lognormal
+     distribution with parameters MU and SIGMA.  Both MU and SIGMA must
+     be scalar or of size R by C.  Or if SZ is a vector, create a
+     matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of MU and SIGMA.
+
+ -- Function File:  nbinrnd (N, P, R, C)
+ -- Function File:  nbinrnd (N, P, SZ)
+     Return an R by C matrix of random samples from the Pascal
+     (negative binomial) distribution with parameters N and P.  Both N
+     and P must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of N and P.  Or if SZ is a vector, create a matrix of
+     size SZ.
+
+ -- Function File:  normrnd (M, S, R, C)
+ -- Function File:  normrnd (M, S, SZ)
+     Return an R by C  or `size (SZ)' matrix of random samples from the
+     normal distribution with parameters mean M and standard deviation
+     S.  Both M and S must be scalar or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of M and S.
+
+ -- Function File:  poissrnd (LAMBDA, R, C)
+     Return an R by C matrix of random samples from the Poisson
+     distribution with parameter LAMBDA, which must be a scalar or of
+     size R by C.
+
+     If R and C are omitted, the size of the result matrix is the size
+     of LAMBDA.
+
+ -- Function File:  trnd (N, R, C)
+ -- Function File:  trnd (N, SZ)
+     Return an R by C matrix of random samples from the t (Student)
+     distribution with N degrees of freedom.  N must be a scalar or of
+     size R by C.  Or if SZ is a vector create a matrix of size SZ.
+
+     If R and C are omitted, the size of the result matrix is the size
+     of N.
+
+ -- Function File:  unidrnd (MX);
+ -- Function File:  unidrnd (MX, V);
+ -- Function File:  unidrnd (MX, M, N, ...);
+     Return random values from discrete uniform distribution, with
+     maximum value(s) given by the integer MX, which may be a scalar or
+     multidimensional array.
+
+     If MX is a scalar, the size of the result is specified by the
+     vector V, or by the optional arguments M, N, ....  Otherwise, the
+     size of the result is the same as the size of MX.
+
+ -- Function File:  unifrnd (A, B, R, C)
+ -- Function File:  unifrnd (A, B, SZ)
+     Return an R by C or a `size (SZ)' matrix of random samples from
+     the uniform distribution on [A, B].  Both A and B must be scalar
+     or of size R by C.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of A and B.
+
+ -- Function File:  wblrnd (SCALE, SHAPE, R, C)
+ -- Function File:  wblrnd (SCALE, SHAPE, SZ)
+     Return an R by C matrix of random samples from the Weibull
+     distribution with parameters SCALE and SHAPE which must be scalar
+     or of size R by C.  Or if SZ is a vector return a matrix of size
+     SZ.
+
+     If R and C are omitted, the size of the result matrix is the
+     common size of ALPHA and SIGMA.
+
+ -- Function File:  wienrnd (T, D, N)
+     Return a simulated realization of the D-dimensional Wiener Process
+     on the interval [0, T].  If D is omitted, D = 1 is used.  The
+     first column of the return matrix contains time, the remaining
+     columns contain the Wiener process.
+
+     The optional parameter N gives the number of summands used for
+     simulating the process over an interval of length 1.  If N is
+     omitted, N = 1000 is used.
+
+
+File: octave.info,  Node: Sets,  Next: Polynomial Manipulations,  Prev: Statistics,  Up: Top
+
+26 Sets
+*******
+
+Octave has a limited number of functions for managing sets of data,
+where a set is defined as a collection of unique elements.  In Octave a
+set is represented as a vector of numbers.
+
+ -- Function File:  unique (X)
+ -- Function File:  unique (X, "rows")
+ -- Function File:  unique (..., "first")
+ -- Function File:  unique (..., "last")
+ -- Function File: [Y, I, J] = unique (...)
+     Return the unique elements of X, sorted in ascending order.  If X
+     is a row vector, return a row vector, but if X is a column vector
+     or a matrix return a column vector.
+
+     If the optional argument `"rows"' is supplied, return the unique
+     rows of X, sorted in ascending order.
+
+     If requested, return index vectors I and J such that `x(i)==y' and
+     `y(j)==x'.
+
+     Additionally, one of `"first"' or `"last"' may be given as an
+     argument.  If `"last"' is specified, return the highest possible
+     indices in I, otherwise, if `"first"' is specified, return the
+     lowest.  The default is `"last"'.
+
+     *See also:* *note union: doc-union, *note intersect:
+     doc-intersect, *note setdiff: doc-setdiff, *note setxor:
+     doc-setxor, *note ismember: doc-ismember.
+
+* Menu:
+
+* Set Operations::
+
+
+File: octave.info,  Node: Set Operations,  Up: Sets
+
+26.1 Set Operations
+===================
+
+Octave supports the basic set operations.  That is, Octave can compute
+the union, intersection, complement, and difference of two sets.
+Octave also supports the _Exclusive Or_ set operation, and membership
+determination.  The functions for set operations all work in pretty
+much the same way.  As an example, assume that `x' and `y' contains two
+sets, then
+
+     union(x, y)
+
+computes the union of the two sets.
+
+ -- Function File: [TF = ismember (A, S)
+ -- Function File: [TF, S_IDX] = ismember (A, S)
+ -- Function File: [TF, S_IDX] = ismember (A, S, "rows")
+     Return a matrix TF with the same shape as A which has a 1 if
+     `A(i,j)' is in S and 0 if it is not.  If a second output argument
+     is requested, the index into S of each of the matching elements is
+     also returned.
+
+          a = [3, 10, 1];
+          s = [0:9];
+          [tf, s_idx] = ismember (a, s);
+               => tf = [1, 0, 1]
+               => s_idx = [4, 0, 2]
+
+     The inputs, A and S, may also be cell arrays.
+
+          a = {'abc'};
+          s = {'abc', 'def'};
+          [tf, s_idx] = ismember (a, s);
+               => tf = [1, 0]
+               => s_idx = [1, 0]
+
+     With the optional third argument `"rows"', and matrices A and S
+     with the same number of columns, compare rows in A with the rows
+     in S.
+
+          a = [1:3; 5:7; 4:6];
+          s = [0:2; 1:3; 2:4; 3:5; 4:6];
+          [tf, s_idx] = ismember(a, s, 'rows');
+               => tf = logical ([1; 0; 1])
+               => s_idx = [2; 0; 5];
+
+     *See also:* *note unique: doc-unique, *note union: doc-union,
+     *note intersect: doc-intersect, *note setxor: doc-setxor, *note
+     setdiff: doc-setdiff.
+
+ -- Function File:  union (A, B)
+ -- Function File:  union (A, B, "rows")
+     Return the set of elements that are in either of the sets A and B.
+     For example,
+
+          union ([1, 2, 4], [2, 3, 5])
+               => [1, 2, 3, 4, 5]
+
+     If the optional third input argument is the string "rows" each row
+     of the matrices A and B will be considered an element of sets.
+     For example,
+          union([1, 2; 2, 3], [1, 2; 3, 4], "rows")
+               =>  1   2
+              2   3
+              3   4
+
+ -- Function File: [C, IA, IB] = union (A, B)
+     Return index vectors IA and IB such that `a == c(ia)' and `b ==
+     c(ib)'.
+
+     *See also:* *note intersect: doc-intersect, *note complement:
+     doc-complement, *note unique: doc-unique.
+
+ -- Function File:  intersect (A, B)
+ -- Function File: [C, IA, IB] = intersect (A, B)
+     Return the elements in both A and B, sorted in ascending order.
+     If A and B are both column vectors return a column vector,
+     otherwise return a row vector.
+
+     Return index vectors IA and IB such that `a(ia)==c' and `b(ib)==c'.
+
+
+*See also:* *note unique: doc-unique, *note union: doc-union, *note
+setxor: doc-setxor, *note setdiff: doc-setdiff, *note ismember:
+doc-ismember.
+
+ -- Function File:  complement (X, Y)
+     Return the elements of set Y that are not in set X.  For example,
+
+          complement ([ 1, 2, 3 ], [ 2, 3, 5 ])
+               => 5
+
+     *See also:* *note union: doc-union, *note intersect:
+     doc-intersect, *note unique: doc-unique.
+
+ -- Function File:  setdiff (A, B)
+ -- Function File:  setdiff (A, B, "rows")
+ -- Function File: [C, I] = setdiff (A, B)
+     Return the elements in A that are not in B, sorted in ascending
+     order.  If A and B are both column vectors return a column vector,
+     otherwise return a row vector.
+
+     Given the optional third argument `"rows"', return the rows in A
+     that are not in B, sorted in ascending order by rows.
+
+     If requested, return I such that `c = a(i)'.
+
+     *See also:* *note unique: doc-unique, *note union: doc-union,
+     *note intersect: doc-intersect, *note setxor: doc-setxor, *note
+     ismember: doc-ismember.
+
+ -- Function File:  setxor (A, B)
+ -- Function File:  setxor (A, B, 'rows')
+     Return the elements exclusive to A or B, sorted in ascending
+     order.  If A and B are both column vectors return a column vector,
+     otherwise return a row vector.
+
+ -- Function File: [C, IA, IB] = setxor (A, B)
+     Return index vectors IA and IB such that `a == c(ia)' and `b ==
+     c(ib)'.
+
+     *See also:* *note unique: doc-unique, *note union: doc-union,
+     *note intersect: doc-intersect, *note setdiff: doc-setdiff, *note
+     ismember: doc-ismember.
+
+
+File: octave.info,  Node: Polynomial Manipulations,  Next: Interpolation,  Prev: Sets,  Up: Top
+
+27 Polynomial Manipulations
+***************************
+
+In Octave, a polynomial is represented by its coefficients (arranged in
+descending order).  For example, a vector C of length N+1 corresponds
+to the following polynomial of order  N
+
+     p(x) = C(1) x^N + ... + C(N) x + C(N+1).
+
+* Menu:
+
+* Evaluating Polynomials::
+* Finding Roots::
+* Products of Polynomials::
+* Derivatives and Integrals::
+* Polynomial Interpolation::
+* Miscellaneous Functions::
+
+
+File: octave.info,  Node: Evaluating Polynomials,  Next: Finding Roots,  Up: Polynomial Manipulations
+
+27.1 Evaluating Polynomials
+===========================
+
+The value of a polynomial represented by the vector C can be evaluated
+at the point X very easily, as the following example shows:
+
+     N = length(c)-1;
+     val = dot( x.^(N:-1:0), c );
+
+While the above example shows how easy it is to compute the value of a
+polynomial, it isn't the most stable algorithm.  With larger polynomials
+you should use more elegant algorithms, such as Horner's Method, which
+is exactly what the Octave function `polyval' does.
+
+   In the case where X is a square matrix, the polynomial given by C is
+still well-defined.  As when X is a scalar the obvious implementation
+is easily expressed in Octave, but also in this case more elegant
+algorithms perform better.  The `polyvalm' function provides such an
+algorithm.
+
+ -- Function File: Y = polyval (P, X)
+ -- Function File: Y = polyval (P, X, [], MU)
+     Evaluate the polynomial at of the specified values for X.  When MU
+     is present evaluate the polynomial for (X-MU(1))/MU(2).  If X is a
+     vector or matrix, the polynomial is evaluated for each of the
+     elements of X.
+
+ -- Function File: [Y, DY] = polyval (P, X, S)
+ -- Function File: [Y, DY] = polyval (P, X, S, MU)
+     In addition to evaluating the polynomial, the second output
+     represents the prediction interval, Y +/- DY, which contains at
+     least 50% of the future predictions.  To calculate the prediction
+     interval, the structured variable S, originating form `polyfit',
+     must be present.
+
+     *See also:* *note polyfit: doc-polyfit, *note polyvalm:
+     doc-polyvalm, *note poly: doc-poly, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note residue:
+     doc-residue, *note filter: doc-filter, *note polyderiv:
+     doc-polyderiv, *note polyinteg: doc-polyinteg.
+
+ -- Function File:  polyvalm (C, X)
+     Evaluate a polynomial in the matrix sense.
+
+     `polyvalm (C, X)' will evaluate the polynomial in the matrix
+     sense, i.e., matrix multiplication is used instead of element by
+     element multiplication as is used in polyval.
+
+     The argument X must be a square matrix.
+
+     *See also:* *note polyval: doc-polyval, *note poly: doc-poly,
+     *note roots: doc-roots, *note conv: doc-conv, *note deconv:
+     doc-deconv, *note residue: doc-residue, *note filter: doc-filter,
+     *note polyderiv: doc-polyderiv, *note polyinteg: doc-polyinteg.
+
+
+File: octave.info,  Node: Finding Roots,  Next: Products of Polynomials,  Prev: Evaluating Polynomials,  Up: Polynomial Manipulations
+
+27.2 Finding Roots
+==================
+
+Octave can find the roots of a given polynomial.  This is done by
+computing the companion matrix of the polynomial (see the `compan'
+function for a definition), and then finding its eigenvalues.
+
+ -- Function File:  roots (V)
+     For a vector V with N components, return the roots of the
+     polynomial
+
+          v(1) * z^(N-1) + ... + v(N-1) * z + v(N)
+
+     As an example, the following code finds the roots of the quadratic
+     polynomial
+          p(x) = x^2 - 5.
+
+          c = [1, 0, -5];
+          roots(c)
+          =>  2.2361
+          => -2.2361
+     Note that the true result is +/- sqrt(5) which is roughly +/-
+     2.2361.
+
+     *See also:* *note compan: doc-compan.
+
+ -- Function File:  compan (C)
+     Compute the companion matrix corresponding to polynomial
+     coefficient vector C.
+
+     The companion matrix is
+
+               _                                                        _
+              |  -c(2)/c(1)   -c(3)/c(1)  ...  -c(N)/c(1)  -c(N+1)/c(1)  |
+              |       1            0      ...       0             0      |
+              |       0            1      ...       0             0      |
+          A = |       .            .   .            .             .      |
+              |       .            .       .        .             .      |
+              |       .            .           .    .             .      |
+              |_      0            0      ...       1             0     _|
+
+     The eigenvalues of the companion matrix are equal to the roots of
+     the polynomial.
+
+     *See also:* *note poly: doc-poly, *note roots: doc-roots, *note
+     residue: doc-residue, *note conv: doc-conv, *note deconv:
+     doc-deconv, *note polyval: doc-polyval, *note polyderiv:
+     doc-polyderiv, *note polyinteg: doc-polyinteg.
+
+ -- Function File: [MULTP, INDX] = mpoles (P)
+ -- Function File: [MULTP, INDX] = mpoles (P, TOL)
+ -- Function File: [MULTP, INDX] = mpoles (P, TOL, REORDER)
+     Identify unique poles in P and associates their multiplicity,
+     ordering them from largest to smallest.
+
+     If the relative difference of the poles is less than TOL, then
+     they are considered to be multiples.  The default value for TOL is
+     0.001.
+
+     If the optional parameter REORDER is zero, poles are not sorted.
+
+     The value MULTP is a vector specifying the multiplicity of the
+     poles.  MULTP(:) refers to multiplicity of P(INDX(:)).
+
+     For example,
+
+          p = [2 3 1 1 2];
+          [m, n] = mpoles(p);
+            => m = [1; 1; 2; 1; 2]
+            => n = [2; 5; 1; 4; 3]
+            => p(n) = [3, 2, 2, 1, 1]
+
+     *See also:* *note poly: doc-poly, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note polyval:
+     doc-polyval, *note polyderiv: doc-polyderiv, *note polyinteg:
+     doc-polyinteg, *note residue: doc-residue.
+
+
+File: octave.info,  Node: Products of Polynomials,  Next: Derivatives and Integrals,  Prev: Finding Roots,  Up: Polynomial Manipulations
+
+27.3 Products of Polynomials
+============================
+
+ -- Function File:  conv (A, B)
+     Convolve two 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:* *note deconv: doc-deconv, *note poly: doc-poly, *note
+     roots: doc-roots, *note residue: doc-residue, *note polyval:
+     doc-polyval, *note polyderiv: doc-polyderiv, *note polyinteg:
+     doc-polyinteg.
+
+ -- Function File: C = convn (A, B, SHAPE)
+     N-dimensional convolution of matrices A and B.
+
+     The size of the output is determined by the SHAPE argument.  This
+     can be any of the following character strings:
+
+    "full"
+          The full convolution result is returned.  The size out of the
+          output is `size (A) + size (B)-1'.  This is the default
+          behavior.
+
+    "same"
+          The central part of the convolution result is returned.  The
+          size out of the output is the same as A.
+
+    "valid"
+          The valid part of the convolution is returned.  The size of
+          the result is `max (size (A) - size (B)+1, 0)'.
+
+     *See also:* *note conv: doc-conv, *note conv2: doc-conv2.
+
+ -- Function File:  deconv (Y, A)
+     Deconvolve two 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:* *note conv: doc-conv, *note poly: doc-poly, *note
+     roots: doc-roots, *note residue: doc-residue, *note polyval:
+     doc-polyval, *note polyderiv: doc-polyderiv, *note polyinteg:
+     doc-polyinteg.
+
+ -- Loadable Function: y = conv2 (A, B, SHAPE)
+ -- Loadable Function: y = conv2 (V1, V2, M, SHAPE)
+     Returns 2D convolution of A and B where the size of C is given by
+
+    SHAPE= 'full'
+          returns full 2-D convolution
+
+    SHAPE= 'same'
+          same size as a. 'central' part of convolution
+
+    SHAPE= 'valid'
+          only parts which do not include zero-padded edges
+
+     By default SHAPE is 'full'.  When the third argument is a matrix
+     returns the convolution of the matrix M by the vector V1 in the
+     column direction and by vector V2 in the row direction
+
+ -- Function File: Q = polygcd (B, A, TOL)
+     Find greatest common divisor of two polynomials.  This is
+     equivalent to the polynomial found by multiplying together all the
+     common roots.  Together with deconv, you can reduce a ratio of two
+     polynomials.  Tolerance defaults to
+          sqrt(eps).
+      Note that this is an unstable algorithm, so don't try it on large
+     polynomials.
+
+     Example
+          polygcd (poly(1:8), poly(3:12)) - poly(3:8)
+          => [ 0, 0, 0, 0, 0, 0, 0 ]
+          deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))) ...
+            - poly(1:2)
+          => [ 0, 0, 0 ]
+
+     *See also:* *note poly: doc-poly, *note polyinteg: doc-polyinteg,
+     *note polyderiv: doc-polyderiv, *note polyreduce: doc-polyreduce,
+     *note roots: doc-roots, *note conv: doc-conv, *note deconv:
+     doc-deconv, *note residue: doc-residue, *note filter: doc-filter,
+     *note polyval: doc-polyval, *note polyvalm: doc-polyvalm.
+
+ -- Function File: [R, P, K, E] = residue (B, A)
+     Compute the partial fraction expansion for the quotient of the
+     polynomials, B and A.
+
+           B(s)    M       r(m)         N
+           ---- = SUM -------------  + SUM k(i)*s^(N-i)
+           A(s)   m=1 (s-p(m))^e(m)    i=1
+
+     where M is the number of poles (the length of the R, P, and E),
+     the K vector is a polynomial of order N-1 representing the direct
+     contribution, and the E vector specifies the multiplicity of the
+     m-th residue's pole.
+
+     For example,
+
+          b = [1, 1, 1];
+          a = [1, -5, 8, -4];
+          [r, p, k, e] = residue (b, a);
+               => r = [-2; 7; 3]
+               => p = [2; 2; 1]
+               => k = [](0x0)
+               => e = [1; 2; 1]
+
+     which represents the following partial fraction expansion
+
+                  s^2 + s + 1       -2        7        3
+             ------------------- = ----- + ------- + -----
+             s^3 - 5s^2 + 8s - 4   (s-2)   (s-2)^2   (s-1)
+
+ -- Function File: [B, A] = residue (R, P, K)
+ -- Function File: [B, A] = residue (R, P, K, E)
+     Compute the reconstituted quotient of polynomials, B(s)/A(s), from
+     the partial fraction expansion; represented by the residues,
+     poles, and a direct polynomial specified by R, P and K, and the
+     pole multiplicity E.
+
+     If the multiplicity, E, is not explicitly specified the
+     multiplicity is determined by the script mpoles.m.
+
+     For example,
+
+          r = [-2; 7; 3];
+          p = [2; 2; 1];
+          k = [1, 0];
+          [b, a] = residue (r, p, k);
+               => b = [1, -5, 9, -3, 1]
+               => a = [1, -5, 8, -4]
+
+          where mpoles.m is used to determine e = [1; 2; 1]
+
+     Alternatively the multiplicity may be defined explicitly, for
+     example,
+
+          r = [7; 3; -2];
+          p = [2; 1; 2];
+          k = [1, 0];
+          e = [2; 1; 1];
+          [b, a] = residue (r, p, k, e);
+               => b = [1, -5, 9, -3, 1]
+               => a = [1, -5, 8, -4]
+
+     which represents the following partial fraction expansion
+
+              -2        7        3         s^4 - 5s^3 + 9s^2 - 3s + 1
+             ----- + ------- + ----- + s = --------------------------
+             (s-2)   (s-2)^2   (s-1)          s^3 - 5s^2 + 8s - 4
+
+     *See also:* *note poly: doc-poly, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note mpoles:
+     doc-mpoles, *note polyval: doc-polyval, *note polyderiv:
+     doc-polyderiv, *note polyinteg: doc-polyinteg.
+
+
+File: octave.info,  Node: Derivatives and Integrals,  Next: Polynomial Interpolation,  Prev: Products of Polynomials,  Up: Polynomial Manipulations
+
+27.4 Derivatives and Integrals
+==============================
+
+Octave comes with functions for computing the derivative and the
+integral of a polynomial.  The functions `polyderiv' and `polyint' both
+return new polynomials describing the result.  As an example we'll
+compute the definite integral of p(x) = x^2 + 1 from 0 to 3.
+
+     c = [1, 0, 1];
+     integral = polyint(c);
+     area = polyval(integral, 3) - polyval(integral, 0)
+     => 12
+
+ -- Function File:  polyderiv (C)
+ -- Function File: [Q] = polyderiv (B, A)
+ -- Function File: [Q, R] = polyderiv (B, A)
+     Return the coefficients of the derivative of the polynomial whose
+     coefficients are given by vector C.  If a pair of polynomials is
+     given B and A, the derivative of the product is returned in Q, or
+     the quotient numerator in Q and the quotient denominator in R.
+
+     *See also:* *note poly: doc-poly, *note polyinteg: doc-polyinteg,
+     *note polyreduce: doc-polyreduce, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note residue:
+     doc-residue, *note filter: doc-filter, *note polygcd: doc-polygcd,
+     *note polyval: doc-polyval, *note polyvalm: doc-polyvalm.
+
+ -- Function File:  polyder (C)
+ -- Function File: [Q] = polyder (B, A)
+ -- Function File: [Q, R] = polyder (B, A)
+     See polyderiv.
+
+ -- Function File:  polyinteg (C)
+     Return the coefficients of the integral of the polynomial whose
+     coefficients are represented by the vector C.
+
+     The constant of integration is set to zero.
+
+     *See also:* *note polyint: doc-polyint, *note poly: doc-poly,
+     *note polyderiv: doc-polyderiv, *note polyreduce: doc-polyreduce,
+     *note roots: doc-roots, *note conv: doc-conv, *note deconv:
+     doc-deconv, *note residue: doc-residue, *note filter: doc-filter,
+     *note polyval: doc-polyval, *note polyvalm: doc-polyvalm.
+
+ -- Function File:  polyint (C, K)
+     Return the coefficients of the integral of the polynomial whose
+     coefficients are represented by the vector C.  The variable K is
+     the constant of integration, which by default is set to zero.
+
+     *See also:* *note poly: doc-poly, *note polyderiv: doc-polyderiv,
+     *note polyreduce: doc-polyreduce, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note residue:
+     doc-residue, *note filter: doc-filter, *note polyval: doc-polyval,
+     *note polyvalm: doc-polyvalm.
+
+
+File: octave.info,  Node: Polynomial Interpolation,  Next: Miscellaneous Functions,  Prev: Derivatives and Integrals,  Up: Polynomial Manipulations
+
+27.5 Polynomial Interpolation
+=============================
+
+Octave comes with good support for various kinds of interpolation, most
+of which are described in *note Interpolation::.  One simple alternative
+to the functions described in the aforementioned chapter, is to fit a
+single polynomial to some given data points.  To avoid a highly
+fluctuating polynomial, one most often wants to fit a low-order
+polynomial to data.  This usually means that it is necessary to fit the
+polynomial in a least-squares sense, which is what the `polyfit'
+function does.
+
+ -- Function File: [P, S, MU] = polyfit (X, Y, N)
+     Return the coefficients of a polynomial P(X) of degree N that
+     minimizes the least-squares-error of the fit.
+
+     The polynomial coefficients are returned in a row vector.
+
+     The second output is a structure containing the following fields:
+
+    `R'
+          Triangular factor R from the QR decomposition.
+
+    `X'
+          The Vandermonde matrix used to compute the polynomial
+          coefficients.
+
+    `df'
+          The degrees of freedom.
+
+    `normr'
+          The norm of the residuals.
+
+    `yf'
+          The values of the polynomial for each value of X.
+
+     The second output may be used by `polyval' to calculate the
+     statistical error limits of the predicted values.
+
+     When the third output, MU, is present the coefficients, P, are
+     associated with a polynomial in XHAT = (X-MU(1))/MU(2).  Where
+     MU(1) = mean (X), and MU(2) = std (X).  This linear transformation
+     of X improves the numerical stability of the fit.
+
+     *See also:* *note polyval: doc-polyval, *note residue: doc-residue.
+
+   In situations where a single polynomial isn't good enough, a solution
+is to use several polynomials pieced together.  The function `mkpp'
+creates a piece-wise polynomial, `ppval' evaluates the function created
+by `mkpp', and `unmkpp' returns detailed information about the function.
+
+   The following example shows how to combine two linear functions and a
+quadratic into one function.  Each of these functions is expressed on
+adjoined intervals.
+
+     x = [-2, -1, 1, 2];
+     p = [ 0,  1, 0;
+           1, -2, 1;
+           0, -1, 1 ];
+     pp = mkpp(x, p);
+     xi = linspace(-2, 2, 50);
+     yi = ppval(pp, xi);
+     plot(xi, yi);
+
+ -- Function File: YI = ppval (PP, XI)
+     Evaluate piece-wise polynomial PP at the points XI.  If `PP.d' is
+     a scalar greater than 1, or an array, then the returned value YI
+     will be an array that is `d1, d1, ..., dk, length (XI)]'.
+
+     *See also:* *note mkpp: doc-mkpp, *note unmkpp: doc-unmkpp, *note
+     spline: doc-spline.
+
+ -- Function File: PP = mkpp (X, P)
+ -- Function File: PP = mkpp (X, P, D)
+     Construct a piece-wise polynomial structure from sample points X
+     and coefficients P.  The i-th row of P, `P (I,:)', contains the
+     coefficients for the polynomial over the I-th interval, ordered
+     from highest to lowest.  There must be one row for each interval
+     in X, so `rows (P) == length (X) - 1'.
+
+     You can concatenate multiple polynomials of the same order over the
+     same set of intervals using `P = [ P1; P2; ...; PD ]'.  In this
+     case, `rows (P) == D * (length (X) - 1)'.
+
+     D specifies the shape of the matrix P for all except the last
+     dimension.  If D is not specified it will be computed as `round
+     (rows (P) / (length (X) - 1))' instead.
+
+     *See also:* *note unmkpp: doc-unmkpp, *note ppval: doc-ppval,
+     *note spline: doc-spline.
+
+ -- Function File: [X, P, N, K, D] = unmkpp (PP)
+     Extract the components of a piece-wise polynomial structure PP.
+     These are as follows:
+
+    X
+          Sample points.
+
+    P
+          Polynomial coefficients for points in sample interval.  `P
+          (I, :)' contains the coefficients for the polynomial over
+          interval I ordered from highest to lowest.  If `D > 1', `P
+          (R, I, :)' contains the coefficients for the r-th polynomial
+          defined on interval I.  However, this is stored as a 2-D
+          array such that `C = reshape (P (:, J), N, D)' gives `C (I,
+          R)' is the j-th coefficient of the r-th polynomial over the
+          i-th interval.
+
+    N
+          Number of polynomial pieces.
+
+    K
+          Order of the polynomial plus 1.
+
+    D
+          Number of polynomials defined for each interval.
+
+     *See also:* *note mkpp: doc-mkpp, *note ppval: doc-ppval, *note
+     spline: doc-spline.
+
+
+File: octave.info,  Node: Miscellaneous Functions,  Prev: Polynomial Interpolation,  Up: Polynomial Manipulations
+
+27.6 Miscellaneous Functions
+============================
+
+ -- Function File:  poly (A)
+     If A is a square N-by-N matrix, `poly (A)' is the row vector of
+     the coefficients of `det (z * eye (N) - a)', the characteristic
+     polynomial of A.  As an example we can use this to find the
+     eigenvalues of A as the roots of `poly (A)'.
+          roots(poly(eye(3)))
+          => 1.00000 + 0.00000i
+          => 1.00000 - 0.00000i
+          => 1.00000 + 0.00000i
+     In real-life examples you should, however, use the `eig' function
+     for computing eigenvalues.
+
+     If X is a vector, `poly (X)' is a vector of coefficients of the
+     polynomial whose roots are the elements of X.  That is, of C is a
+     polynomial, then the elements of `D = roots (poly (C))' are
+     contained in C.  The vectors C and D are, however, not equal due
+     to sorting and numerical errors.
+
+     *See also:* *note eig: doc-eig, *note roots: doc-roots.
+
+ -- Function File:  polyout (C, X)
+     Write formatted polynomial
+             c(x) = c(1) * x^n + ... + c(n) x + c(n+1)
+      and return it as a string or write it to the screen (if NARGOUT
+     is zero).  X defaults to the string `"s"'.
+
+     *See also:* *note polyval: doc-polyval, *note polyvalm:
+     doc-polyvalm, *note poly: doc-poly, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note residue:
+     doc-residue, *note filter: doc-filter, *note polyderiv:
+     doc-polyderiv, *note polyinteg: doc-polyinteg.
+
+ -- Function File:  polyreduce (C)
+     Reduces a polynomial coefficient vector to a minimum number of
+     terms by stripping off any leading zeros.
+
+     *See also:* *note poly: doc-poly, *note roots: doc-roots, *note
+     conv: doc-conv, *note deconv: doc-deconv, *note residue:
+     doc-residue, *note filter: doc-filter, *note polyval: doc-polyval,
+     *note polyvalm: doc-polyvalm, *note polyderiv: doc-polyderiv,
+     *note polyinteg: doc-polyinteg.
+
+
+File: octave.info,  Node: Interpolation,  Next: Geometry,  Prev: Polynomial Manipulations,  Up: Top
+
+28 Interpolation
+****************
+
+* Menu:
+
+* One-dimensional Interpolation::
+* Multi-dimensional Interpolation::
+
+
+File: octave.info,  Node: One-dimensional Interpolation,  Next: Multi-dimensional Interpolation,  Up: Interpolation
+
+28.1 One-dimensional Interpolation
+==================================
+
+Octave supports several methods for one-dimensional interpolation, most
+of which are described in this section.  *note Polynomial
+Interpolation:: and *note Interpolation on Scattered Data:: describe
+further methods.
+
+ -- Function File: YI = interp1 (X, Y, XI)
+ -- Function File: YI = interp1 (..., METHOD)
+ -- Function File: YI = interp1 (..., EXTRAP)
+ -- Function File: PP = interp1 (..., 'pp')
+     One-dimensional interpolation.  Interpolate Y, defined at the
+     points X, at the points XI.  The sample points X must be strictly
+     monotonic.  If Y is an array, treat the columns of Y separately.
+
+     Method is one of:
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors
+
+    'pchip'
+          Piece-wise cubic hermite interpolating polynomial
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives
+          throughout the curve
+
+     Appending '*' to the start of the above method forces `interp1' to
+     assume that X is uniformly spaced, and only `X (1)' and `X (2)'
+     are referenced.  This is usually faster, and is never slower.  The
+     default method is 'linear'.
+
+     If EXTRAP is the string 'extrap', then extrapolate values beyond
+     the endpoints.  If EXTRAP is a number, replace values beyond the
+     endpoints with that number.  If EXTRAP is missing, assume NA.
+
+     If the string argument 'pp' is specified, then XI should not be
+     supplied and `interp1' returns the piece-wise polynomial that can
+     later be used with `ppval' to evaluate the interpolation.  There
+     is an equivalence, such that `ppval (interp1 (X, Y, METHOD, 'pp'),
+     XI) == interp1 (X, Y, XI, METHOD, 'extrap')'.
+
+     An example of the use of `interp1' is
+
+          xf = [0:0.05:10];
+          yf = sin (2*pi*xf/5);
+          xp = [0:10];
+          yp = sin (2*pi*xp/5);
+          lin = interp1 (xp, yp, xf);
+          spl = interp1 (xp, yp, xf, "spline");
+          cub = interp1 (xp, yp, xf, "cubic");
+          near = interp1 (xp, yp, xf, "nearest");
+          plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
+                xf, cub, "c", xf, near, "m", xp, yp, "r*");
+          legend ("original", "linear", "spline", "cubic", "nearest")
+
+     *See also:* *note interpft: doc-interpft.
+
+   There are some important differences between the various
+interpolation methods.  The 'spline' method enforces that both the
+first and second derivatives of the interpolated values have a
+continuous derivative, whereas the other methods do not.  This means
+that the results of the 'spline' method are generally smoother.  If the
+function to be interpolated is in fact smooth, then 'spline' will give
+excellent results.  However, if the function to be evaluated is in some
+manner discontinuous, then 'pchip' interpolation might give better
+results.
+
+   This can be demonstrated by the code
+
+     t = -2:2;
+     dt = 1;
+     ti =-2:0.025:2;
+     dti = 0.025;
+     y = sign(t);
+     ys = interp1(t,y,ti,'spline');
+     yp = interp1(t,y,ti,'pchip');
+     ddys = diff(diff(ys)./dti)./dti;
+     ddyp = diff(diff(yp)./dti)./dti;
+     figure(1);
+     plot (ti, ys,'r-', ti, yp,'g-');
+     legend('spline','pchip',4);
+     figure(2);
+     plot (ti, ddys,'r+', ti, ddyp,'g*');
+     legend('spline','pchip');
+
+   A simplified version of `interp1' that performs only linear
+interpolation is available in `interp1q'.  This argument is slightly
+faster than `interp1' as to performs little error checking.
+
+ -- Function File: YI = interp1q (X, Y, XI)
+     One-dimensional linear interpolation without error checking.
+     Interpolates Y, defined at the points X, at the points XI.  The
+     sample points X must be a strictly monotonically increasing column
+     vector.  If Y is an array, treat the columns of Y separately.  If
+     Y is a vector, it must be a column vector of the same length as X.
+
+     Values of XI beyond the endpoints of the interpolation result in
+     NA being returned.
+
+     Note that the error checking is only a significant portion of the
+     execution time of this `interp1' if the size of the input arguments
+     is relatively small.  Therefore, the benefit of using `interp1q'
+     is relatively small.
+
+     *See also:* *note interp1: doc-interp1.
+
+   Fourier interpolation, is a resampling technique where a signal is
+converted to the frequency domain, padded with zeros and then
+reconverted to the time domain.
+
+ -- Function File:  interpft (X, N)
+ -- Function File:  interpft (X, N, DIM)
+     Fourier interpolation.  If X is a vector, then X is resampled with
+     N points.  The data in X is assumed to be equispaced.  If X is an
+     array, then operate along each column of the array separately.  If
+     DIM is specified, then interpolate along the dimension DIM.
+
+     `interpft' assumes that the interpolated function is periodic, and
+     so assumptions are made about the end points of the interpolation.
+
+     *See also:* *note interp1: doc-interp1.
+
+   There are two significant limitations on Fourier interpolation.
+Firstly, the function signal is assumed to be periodic, and so
+non-periodic signals will be poorly represented at the edges.
+Secondly, both the signal and its interpolation are required to be
+sampled at equispaced points.  An example of the use of `interpft' is
+
+     t = 0 : 0.3 : pi; dt = t(2)-t(1);
+     n = length (t); k = 100;
+     ti = t(1) + [0 : k-1]*dt*n/k;
+     y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+     yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
+     plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ...
+           ti, interpft (y, k), 'c', t, y, 'r+');
+     legend ('sin(4t+0.3)cos(3t-0.1','spline','interpft','data');
+
+which demonstrates the poor behavior of Fourier interpolation for
+non-periodic functions.
+
+   In additional the support function `spline' and `lookup' that
+underlie the `interp1' function can be called directly.
+
+ -- Function File: PP = spline (X, Y)
+ -- Function File: YI = spline (X, Y, XI)
+     Return the cubic spline interpolant of Y at points X.  If called
+     with two arguments, `spline' returns the piece-wise polynomial PP
+     that may later be used with `ppval' to evaluate the polynomial at
+     specific points.  If called with a third input argument, `spline'
+     evaluates the spline at the points XI.  There is an equivalence
+     between `ppval (spline (X, Y), XI)' and `spline (X, Y, XI)'.
+
+     The variable X must be a vector of length N, and Y can be either a
+     vector or array.  In the case where Y is a vector, it can have a
+     length of either N or `N + 2'.  If the length of Y is N, then the
+     'not-a-knot' end condition is used.  If the length of Y is `N + 2',
+     then the first and last values of the vector Y are the values of
+     the first derivative of the cubic spline at the end-points.
+
+     If Y is an array, then the size of Y must have the form `[S1, S2,
+     ..., SK, N]' or `[S1, S2, ..., SK, N + 2]'.  The array is then
+     reshaped internally to a matrix where the leading dimension is
+     given by `S1 * S2 * ... * SK' and each row of this matrix is then
+     treated separately.  Note that this is exactly the opposite
+     treatment than `interp1' and is done for compatibility.
+
+     *See also:* *note ppval: doc-ppval, *note mkpp: doc-mkpp, *note
+     unmkpp: doc-unmkpp.
+
+   The `lookup' function is used by other interpolation functions to
+identify the points of the original data that are closest to the
+current point of interest.
+
+ -- Loadable Function: IDX = lookup (TABLE, Y, OPT)
+     Lookup values in a sorted table.  Usually used as a prelude to
+     interpolation.
+
+     If table is strictly increasing and `idx = lookup (table, y)', then
+     `table(idx(i)) <= y(i) < table(idx(i+1))' for all `y(i)' within
+     the table.  If `y(i) < table (1)' then `idx(i)' is 0. If `y(i) >=
+     table(end)' then `idx(i)' is `table(n)'.
+
+     If the table is strictly decreasing, then the tests are reversed.
+     There are no guarantees for tables which are non-monotonic or are
+     not strictly monotonic.
+
+     The algorithm used by lookup is standard binary search, with
+     optimizations to speed up the case of partially ordered arrays
+     (dense downsampling).  In particular, looking up a single entry is
+     of logarithmic complexity (unless a conversion occurs due to
+     non-numeric or unequal types).
+
+     TABLE and Y can also be cell arrays of strings (or Y can be a
+     single string).  In this case, string lookup is performed using
+     lexicographical comparison.
+
+     If OPTS is specified, it shall be a string with letters indicating
+     additional options.  For numeric lookup, 'l' in OPTS indicates that
+     the leftmost subinterval shall be extended to infinity (i.e., all
+     indices at least 1), and 'r' indicates that the rightmost
+     subinterval shall be extended to infinity (i.e., all indices at
+     most n-1).
+
+     For string lookup, 'i' indicates case-insensitive comparison.
+
+
+File: octave.info,  Node: Multi-dimensional Interpolation,  Prev: One-dimensional Interpolation,  Up: Interpolation
+
+28.2 Multi-dimensional Interpolation
+====================================
+
+There are three multi-dimensional interpolation functions in Octave,
+with similar capabilities.  Methods using Delaunay tessellation are
+described in *note Interpolation on Scattered Data::.
+
+ -- Function File: ZI = interp2 (X, Y, Z, XI, YI)
+ -- Function File: ZI = interp2 (Z, XI, YI)
+ -- Function File: ZI = interp2 (Z, N)
+ -- Function File: ZI = interp2 (..., METHOD)
+ -- Function File: ZI = interp2 (..., METHOD, EXTRAPVAL)
+     Two-dimensional interpolation.  X, Y and Z describe a surface
+     function.  If X and Y are vectors their length must correspondent
+     to the size of Z.  X and Y must be monotonic.  If they are
+     matrices they must have the `meshgrid' format.
+
+    `interp2 (X, Y, Z, XI, YI, ...)'
+          Returns a matrix corresponding to the points described by the
+          matrices XI, YI.
+
+          If the last argument is a string, the interpolation method can
+          be specified.  The method can be 'linear', 'nearest' or
+          'cubic'.  If it is omitted 'linear' interpolation is assumed.
+
+    `interp2 (Z, XI, YI)'
+          Assumes `X = 1:rows (Z)' and `Y = 1:columns (Z)'
+
+    `interp2 (Z, N)'
+          Interleaves the matrix Z n-times.  If N is omitted a value of
+          `N = 1' is assumed.
+
+     The variable METHOD defines the method to use for the
+     interpolation.  It can take one of the following values
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors.
+
+    'pchip'
+          Piece-wise cubic hermite interpolating polynomial (not
+          implemented yet).
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors.
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives
+          throughout the curve.
+
+     If a scalar value EXTRAPVAL is defined as the final value, then
+     values outside the mesh as set to this value.  Note that in this
+     case METHOD must be defined as well.  If EXTRAPVAL is not defined
+     then NA is assumed.
+
+     *See also:* *note interp1: doc-interp1.
+
+ -- Function File: VI = interp3 (X, Y,Z, V, XI, YI, ZI)
+ -- Function File: VI = interp3 (V, XI, YI, ZI)
+ -- Function File: VI = interp3 (V, M)
+ -- Function File: VI = interp3 (V)
+ -- Function File: VI = interp3 (..., METHOD)
+ -- Function File: VI = interp3 (..., METHOD, EXTRAPVAL)
+     Perform 3-dimensional interpolation.  Each element of the
+     3-dimensional array V represents a value at a location given by
+     the parameters X, Y, and Z.  The parameters X, X, and Z are either
+     3-dimensional arrays of the same size as the array V in the
+     'meshgrid' format or vectors.  The parameters XI, etc.  respect a
+     similar format to X, etc., and they represent the points at which
+     the array VI is interpolated.
+
+     If X, Y, Z are omitted, they are assumed to be `x = 1 : size (V,
+     2)', `y = 1 : size (V, 1)' and `z = 1 : size (V, 3)'.  If M is
+     specified, then the interpolation adds a point half way between
+     each of the interpolation points.  This process is performed M
+     times.  If only V is specified, then M is assumed to be `1'.
+
+     Method is one of:
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors.
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors (not
+          implemented yet).
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives
+          throughout the curve.
+
+     The default method is 'linear'.
+
+     If EXTRAP is the string 'extrap', then extrapolate values beyond
+     the endpoints.  If EXTRAP is a number, replace values beyond the
+     endpoints with that number.  If EXTRAP is missing, assume NA.
+
+     *See also:* *note interp1: doc-interp1, *note interp2:
+     doc-interp2, *note spline: doc-spline, *note meshgrid:
+     doc-meshgrid.
+
+ -- Function File: VI = interpn (X1, X2, ..., V, Y1, Y2, ...)
+ -- Function File: VI = interpn (V, Y1, Y2, ...)
+ -- Function File: VI = interpn (V, M)
+ -- Function File: VI = interpn (V)
+ -- Function File: VI = interpn (..., METHOD)
+ -- Function File: VI = interpn (..., METHOD, EXTRAPVAL)
+     Perform N-dimensional interpolation, where N is at least two.
+     Each element of the N-dimensional array V represents a value at a
+     location given by the parameters X1, X2, ..., XN.  The parameters
+     X1, X2, ..., XN are either N-dimensional arrays of the same size
+     as the array V in the 'ndgrid' format or vectors.  The parameters
+     Y1, etc. respect a similar format to X1, etc., and they represent
+     the points at which the array VI is interpolated.
+
+     If X1, ..., XN are omitted, they are assumed to be `x1 = 1 : size
+     (V, 1)', etc.  If M is specified, then the interpolation adds a
+     point half way between each of the interpolation points.  This
+     process is performed M times.  If only V is specified, then M is
+     assumed to be `1'.
+
+     Method is one of:
+
+    'nearest'
+          Return the nearest neighbor.
+
+    'linear'
+          Linear interpolation from nearest neighbors.
+
+    'cubic'
+          Cubic interpolation from four nearest neighbors (not
+          implemented yet).
+
+    'spline'
+          Cubic spline interpolation-smooth first and second derivatives
+          throughout the curve.
+
+     The default method is 'linear'.
+
+     If EXTRAPVAL is the scalar value, use it to replace the values
+     beyond the endpoints with that number.  If EXTRAPVAL is missing,
+     assume NA.
+
+     *See also:* *note interp1: doc-interp1, *note interp2:
+     doc-interp2, *note spline: doc-spline, *note ndgrid: doc-ndgrid.
+
+   A significant difference between `interpn' and the other two
+multidimensional interpolation functions is the fashion in which the
+dimensions are treated.  For `interp2' and `interp3', the 'y' axis is
+considered to be the columns of the matrix, whereas the 'x' axis
+corresponds to the rows of the array.  As Octave indexes arrays in
+column major order, the first dimension of any array is the columns, and
+so `interpn' effectively reverses the 'x' and 'y' dimensions.  Consider
+the example
+
+     x = y = z = -1:1;
+     f = @(x,y,z) x.^2 - y - z.^2;
+     [xx, yy, zz] = meshgrid (x, y, z);
+     v = f (xx,yy,zz);
+     xi = yi = zi = -1:0.1:1;
+     [xxi, yyi, zzi] = meshgrid (xi, yi, zi);
+     vi = interp3(x, y, z, v, xxi, yyi, zzi, 'spline');
+     [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+     vi2 = interpn(x, y, z, v, xxi, yyi, zzi, 'spline');
+     mesh (zi, yi, squeeze (vi2(1,:,:)));
+
+where `vi' and `vi2' are identical.  The reversal of the dimensions is
+treated in the `meshgrid' and `ndgrid' functions respectively.
+
+   In additional the support function `bicubic' that underlies the
+cubic interpolation of `interp2' function can be called directly.
+
+ -- Function File: ZI = bicubic (X, Y, Z, XI, YI, EXTRAPVAL)
+     Return a matrix ZI corresponding to the bicubic interpolations at
+     XI and YI of the data supplied as X, Y and Z.  Points outside the
+     grid are set to EXTRAPVAL.
+
+     See `http://wiki.woodpecker.org.cn/moin/Octave/Bicubic' for
+     further information.
+
+     *See also:* *note interp2: doc-interp2.
+
+
+File: octave.info,  Node: Geometry,  Next: Signal Processing,  Prev: Interpolation,  Up: Top
+
+29 Geometry
+***********
+
+Much of the geometry code in Octave is based on the Qhull library(1).
+Some of the documentation for Qhull, particularly for the options that
+can be passed to `delaunay', `voronoi' and `convhull', etc., is
+relevant to Octave users.
+
+* Menu:
+
+* Delaunay Triangulation::
+* Voronoi Diagrams::
+* Convex Hull::
+* Interpolation on Scattered Data::
+
+   ---------- Footnotes ----------
+
+   (1) Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull
+algorithm for convex hulls," ACM Trans. on Mathematical Software,
+22(4):469-483, Dec 1996, `http://www.qhull.org'
+
+
+File: octave.info,  Node: Delaunay Triangulation,  Next: Voronoi Diagrams,  Up: Geometry
+
+29.1 Delaunay Triangulation
+===========================
+
+The Delaunay triangulation is constructed from a set of circum-circles.
+These circum-circles are chosen so that there are at least three of the
+points in the set to triangulation on the circumference of the
+circum-circle.  None of the points in the set of points falls within
+any of the circum-circles.
+
+   In general there are only three points on the circumference of any
+circum-circle.  However, in some cases, and in particular for the case
+of a regular grid, 4 or more points can be on a single circum-circle.
+In this case the Delaunay triangulation is not unique.
+
+ -- Function File: TRI = delaunay (X, Y)
+ -- Function File: TRI = delaunay (X, Y, OPT)
+     The return matrix of size [n, 3] contains a set triangles which are
+     described by the indices to the data point x and y vector.  The
+     triangulation satisfies the Delaunay circum-circle criterion.  No
+     other data point is in the circum-circle of the defining triangle.
+
+     A third optional argument, which must be a string, contains extra
+     options passed to the underlying qhull command.  See the
+     documentation for the Qhull library for details.
+
+          x = rand (1, 10);
+          y = rand (size (x));
+          T = delaunay (x, y);
+          X = [x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1))];
+          Y = [y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1))];
+          axis ([0,1,0,1]);
+          plot (X, Y, "b", x, y, "r*");
+
+     *See also:* *note voronoi: doc-voronoi, *note delaunay3:
+     doc-delaunay3, *note delaunayn: doc-delaunayn.
+
+   The 3- and N-dimensional extension of the Delaunay triangulation are
+given by `delaunay3' and `delaunayn' respectively.  `delaunay3' returns
+a set of tetrahedra that satisfy the Delaunay circum-circle criteria.
+Similarly, `delaunayn' returns the N-dimensional simplex satisfying the
+Delaunay circum-circle criteria.  The N-dimensional extension of a
+triangulation is called a tessellation.
+
+ -- Function File: T = delaunay3 (X, Y, Z)
+ -- Function File: T = delaunay3 (X, Y, Z, OPT)
+     A matrix of size [n, 4] is returned.  Each row contains a set of
+     tetrahedron which are described by the indices to the data point
+     vectors (x,y,z).
+
+     A fourth optional argument, which must be a string or cell array
+     of strings, contains extra options passed to the underlying qhull
+     command.  See the documentation for the Qhull library for details.
+
+     *See also:* *note delaunay: doc-delaunay, *note delaunayn:
+     doc-delaunayn.
+
+ -- Function File: T = delaunayn (P)
+ -- Function File: T = delaunayn (P, OPT)
+     Form the Delaunay triangulation for a set of points.  The Delaunay
+     triangulation is a tessellation of the convex hull of the points
+     such that no n-sphere defined by the n-triangles contains any
+     other points from the set.  The input matrix P of size `[n, dim]'
+     contains N points in a space of dimension dim.  The return matrix
+     T has the size `[m, dim+1]'.  It contains for each row a set of
+     indices to the points, which describes a simplex of dimension dim.
+     For example, a 2d simplex is a triangle and 3d simplex is a
+     tetrahedron.
+
+     Extra options for the underlying Qhull command can be specified by
+     the second argument.  This argument is a cell array of strings.
+     The default options depend on the dimension of the input:
+
+        * 2D and 3D: OPT = `{"Qt", "Qbb", "Qc"}'
+
+        * 4D and higher: OPT = `{"Qt", "Qbb", "Qc", "Qz"}'
+
+     If OPT is [], then the default arguments are used.  If OPT is
+     `{""}', then none of the default arguments are used by Qhull.  See
+     the Qhull documentation for the available options.
+
+     All options can also be specified as single string, for example
+     `"Qt Qbb Qc Qz"'.
+
+
+   An example of a Delaunay triangulation of a set of points is
+
+     rand ("state", 2);
+     x = rand (10, 1);
+     y = rand (10, 1);
+     T = delaunay (x, y);
+     X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
+     Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+     axis ([0, 1, 0, 1]);
+     plot(X, Y, "b", x, y, "r*");
+
+* Menu:
+
+* Plotting the Triangulation::
+* Identifying points in Triangulation::
+
+
+File: octave.info,  Node: Plotting the Triangulation,  Next: Identifying points in Triangulation,  Up: Delaunay Triangulation
+
+29.1.1 Plotting the Triangulation
+---------------------------------
+
+Octave has the functions `triplot' and `trimesh' to plot the Delaunay
+triangulation of a 2-dimensional set of points.
+
+ -- Function File:  triplot (TRI, X, Y)
+ -- Function File:  triplot (TRI, X, Y, LINESPEC)
+ -- Function File: H = triplot (...)
+     Plot a triangular mesh in 2D.  The variable TRI is the triangular
+     meshing of the points `(X, Y)' which is returned from `delaunay'.
+     If given, the LINESPEC determines the properties to use for the
+     lines.  The output argument H is the graphic handle to the plot.
+
+     *See also:* *note plot: doc-plot, *note trimesh: doc-trimesh,
+     *note delaunay: doc-delaunay.
+
+ -- Function File:  trimesh (TRI, X, Y, Z)
+ -- Function File: H = trimesh (...)
+     Plot a triangular mesh in 3D.  The variable TRI is the triangular
+     meshing of the points `(X, Y)' which is returned from `delaunay'.
+     The variable Z is value at the point `(X, Y)'.  The output
+     argument H is the graphic handle to the plot.
+
+     *See also:* *note triplot: doc-triplot, *note delaunay3:
+     doc-delaunay3.
+
+   The difference between `triplot' and `trimesh' is that the former
+only plots the 2-dimensional triangulation itself, whereas the second
+plots the value of some function `f (X, Y)'.  An example of the use of
+the `triplot' function is
+
+     rand ("state", 2)
+     x = rand (20, 1);
+     y = rand (20, 1);
+     tri = delaunay (x, y);
+     triplot (tri, x, y);
+
+   that plot the Delaunay triangulation of a set of random points in
+2-dimensions.
+
+
+File: octave.info,  Node: Identifying points in Triangulation,  Prev: Plotting the Triangulation,  Up: Delaunay Triangulation
+
+29.1.2 Identifying points in Triangulation
+------------------------------------------
+
+It is often necessary to identify whether a particular point in the
+N-dimensional space is within the Delaunay tessellation of a set of
+points in this N-dimensional space, and if so which N-simplex contains
+the point and which point in the tessellation is closest to the desired
+point.  The functions `tsearch' and `dsearch' perform this function in
+a triangulation, and `tsearchn' and `dsearchn' in an N-dimensional
+tessellation.
+
+   To identify whether a particular point represented by a vector P
+falls within one of the simplices of an N-simplex, we can write the
+Cartesian coordinates of the point in a parametric form with respect to
+the N-simplex.  This parametric form is called the Barycentric
+Coordinates of the point.  If the points defining the N-simplex are
+given by `N + 1' vectors T(I,:), then the Barycentric coordinates
+defining the point P are given by
+
+     P = sum (BETA(1:N+1) * T(1:N+1),:)
+
+where there are `N + 1' values `BETA(I)' that together as a vector
+represent the Barycentric coordinates of the point P.  To ensure a
+unique solution for the values of `BETA(I)' an additional criteria of
+
+     sum (BETA(1:N+1)) == 1
+
+is imposed, and we can therefore write the above as
+
+     P - T(end, :) = BETA(1:end-1) * (T(1:end-1, :)
+           - ones(N, 1) * T(end, :)
+
+Solving for BETA we can then write
+
+     BETA(1:end-1) = (P - T(end, :)) / (T(1:end-1, :)
+           - ones(N, 1) * T(end, :))
+     BETA(end) = sum(BETA(1:end-1))
+
+which gives the formula for the conversion of the Cartesian coordinates
+of the point P to the Barycentric coordinates BETA.  An important
+property of the Barycentric coordinates is that for all points in the
+N-simplex
+
+     0 <= BETA(I) <= 1
+
+Therefore, the test in `tsearch' and `tsearchn' essentially only needs
+to express each point in terms of the Barycentric coordinates of each
+of the simplices of the N-simplex and test the values of BETA.  This is
+exactly the implementation used in `tsearchn'.  `tsearch' is optimized
+for 2-dimensions and the Barycentric coordinates are not explicitly
+formed.
+
+ -- Loadable Function: IDX = tsearch (X, Y, T, XI, YI)
+     Searches for the enclosing Delaunay convex hull.  For `T =
+     delaunay (X, Y)', finds the index in T containing the points `(XI,
+     YI)'.  For points outside the convex hull, IDX is NaN.
+
+     *See also:* *note delaunay: doc-delaunay, *note delaunayn:
+     doc-delaunayn.
+
+ -- Function File: [IDX, P] = tsearchn (X, T, XI)
+     Searches for the enclosing Delaunay convex hull.  For `T =
+     delaunayn (X)', finds the index in T containing the points XI.
+     For points outside the convex hull, IDX is NaN.  If requested
+     `tsearchn' also returns the Barycentric coordinates P of the
+     enclosing triangles.
+
+     *See also:* *note delaunay: doc-delaunay, *note delaunayn:
+     doc-delaunayn.
+
+   An example of the use of `tsearch' can be seen with the simple
+triangulation
+
+     X = [-1; -1; 1; 1];
+     Y = [-1; 1; -1; 1];
+     TRI = [1, 2, 3; 2, 3, 1];
+
+consisting of two triangles defined by TRI.  We can then identify which
+triangle a point falls in like
+
+     tsearch (X, Y, TRI, -0.5, -0.5)
+     => 1
+     tsearch (X, Y, TRI, 0.5, 0.5)
+     => 2
+
+and we can confirm that a point doesn't lie within one of the triangles
+like
+
+     tsearch (X, Y, TRI, 2, 2)
+     => NaN
+
+   The `dsearch' and `dsearchn' find the closest point in a
+tessellation to the desired point.  The desired point does not
+necessarily have to be in the tessellation, and even if it the returned
+point of the tessellation does not have to be one of the vertexes of the
+N-simplex within which the desired point is found.
+
+ -- Function File: IDX = dsearch (X, Y, TRI, XI, YI)
+ -- Function File: IDX = dsearch (X, Y, TRI, XI, YI, S)
+     Returns the index IDX or the closest point in `X, Y' to the
+     elements `[XI(:), YI(:)]'.  The variable S is accepted but ignored
+     for compatibility.
+
+     *See also:* *note dsearchn: doc-dsearchn, *note tsearch:
+     doc-tsearch.
+
+ -- Function File: IDX = dsearchn (X, TRI, XI)
+ -- Function File: IDX = dsearchn (X, TRI, XI, OUTVAL)
+ -- Function File: IDX = dsearchn (X, XI)
+ -- Function File: [IDX, D] = dsearchn (...)
+     Returns the index IDX or the closest point in X to the elements
+     XI.  If OUTVAL is supplied, then the values of XI that are not
+     contained within one of the simplicies TRI are set to OUTVAL.
+     Generally, TRI is returned from `delaunayn (X)'.
+
+     *See also:* *note dsearch: doc-dsearch, *note tsearch: doc-tsearch.
+
+   An example of the use of `dsearch', using the above values of X, Y
+and TRI is
+
+     dsearch (X, Y, TRI, -2, -2)
+     => 1
+
+   If you wish the points that are outside the tessellation to be
+flagged, then `dsearchn' can be used as
+
+     dsearchn ([X, Y], TRI, [-2, -2], NaN)
+     => NaN
+     dsearchn ([X, Y], TRI, [-0.5, -0.5], NaN)
+     => 1
+
+where the point outside the tessellation are then flagged with `NaN'.
+
+
+File: octave.info,  Node: Voronoi Diagrams,  Next: Convex Hull,  Prev: Delaunay Triangulation,  Up: Geometry
+
+29.2 Voronoi Diagrams
+=====================
+
+A Voronoi diagram or Voronoi tessellation of a set of points S in an
+N-dimensional space, is the tessellation of the N-dimensional space
+such that all points in `V(P)', a partitions of the tessellation where
+P is a member of S, are closer to P than any other point in S.  The
+Voronoi diagram is related to the Delaunay triangulation of a set of
+points, in that the vertexes of the Voronoi tessellation are the
+centers of the circum-circles of the simplicies of the Delaunay
+tessellation.
+
+ -- Function File:  voronoi (X, Y)
+ -- Function File:  voronoi (X, Y, "plotstyle")
+ -- Function File:  voronoi (X, Y, "plotstyle", OPTIONS)
+ -- Function File: [VX, VY] = voronoi (...)
+     plots voronoi diagram of points `(X, Y)'.  The voronoi facets with
+     points at infinity are not drawn.  [VX, VY] = voronoi(...) returns
+     the vertices instead of plotting the diagram. plot (VX, VY) shows
+     the voronoi diagram.
+
+     A fourth optional argument, which must be a string, contains extra
+     options passed to the underlying qhull command.  See the
+     documentation for the Qhull library for details.
+
+            x = rand (10, 1);
+            y = rand (size (x));
+            h = convhull (x, y);
+            [vx, vy] = voronoi (x, y);
+            plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g")
+            legend ("", "points", "hull");
+
+     *See also:* *note voronoin: doc-voronoin, *note delaunay:
+     doc-delaunay, *note convhull: doc-convhull.
+
+ -- Function File: [C, F] = voronoin (PTS)
+ -- Function File: [C, F] = voronoin (PTS, OPTIONS)
+     computes n- dimensional voronoi facets.  The input matrix PTS of
+     size [n, dim] contains n points of dimension dim.  C contains the
+     points of the voronoi facets.  The list F contains for each facet
+     the indices of the voronoi points.
+
+     A second optional argument, which must be a string, contains extra
+     options passed to the underlying qhull command.  See the
+     documentation for the Qhull library for details.
+
+     *See also:* *note voronoin: doc-voronoin, *note delaunay:
+     doc-delaunay, *note convhull: doc-convhull.
+
+   An example of the use of `voronoi' is
+
+     rand("state",9);
+     x = rand(10,1);
+     y = rand(10,1);
+     tri = delaunay (x, y);
+     [vx, vy] = voronoi (x, y, tri);
+     triplot (tri, x, y, "b");
+     hold on;
+     plot (vx, vy, "r");
+
+   Additional information about the size of the facets of a Voronoi
+diagram, and which points of a set of points is in a polygon can be had
+with the `polyarea' and `inpolygon' functions respectively.
+
+ -- Function File:  polyarea (X, Y)
+ -- Function File:  polyarea (X, Y, DIM)
+     Determines area of a polygon by triangle method.  The variables X
+     and Y define the vertex pairs, and must therefore have the same
+     shape.  They can be either vectors or arrays.  If they are arrays
+     then the columns of X and Y are treated separately and an area
+     returned for each.
+
+     If the optional DIM argument is given, then `polyarea' works along
+     this dimension of the arrays X and Y.
+
+
+   An example of the use of `polyarea' might be
+
+     rand ("state", 2);
+     x = rand (10, 1);
+     y = rand (10, 1);
+     [c, f] = voronoin ([x, y]);
+     af = zeros (size(f));
+     for i = 1 : length (f)
+       af(i) = polyarea (c (f {i, :}, 1), c (f {i, :}, 2));
+     endfor
+
+   Facets of the Voronoi diagram with a vertex at infinity have infinity
+area.  A simplified version of `polyarea' for rectangles is available
+with `rectint'
+
+ -- Function File: AREA = rectint (A, B)
+     Compute the area of intersection of rectangles in A and rectangles
+     in B.  Rectangles are defined as [x y width height] where x and y
+     are the minimum values of the two orthogonal dimensions.
+
+     If A or B are matrices, then the output, AREA, is a matrix where
+     the i-th row corresponds to the i-th row of a and the j-th column
+     corresponds to the j-th row of b.
+
+     *See also:* *note polyarea: doc-polyarea.
+
+ -- Function File: [IN, ON] = inpolygon (X, Y, XV, XY)
+     For a polygon defined by `(XV, YV)' points, determine if the
+     points `(X, Y)' are inside or outside the polygon.  The variables
+     X, Y, must have the same dimension.  The optional output ON gives
+     the points that are on the polygon.
+
+
+   An example of the use of `inpolygon' might be
+
+     randn ("state", 2);
+     x = randn (100, 1);
+     y = randn (100, 1);
+     vx = cos (pi * [-1 : 0.1: 1]);
+     vy = sin (pi * [-1 : 0.1 : 1]);
+     in = inpolygon (x, y, vx, vy);
+     plot(vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo");
+     axis ([-2, 2, -2, 2]);
+
+
+File: octave.info,  Node: Convex Hull,  Next: Interpolation on Scattered Data,  Prev: Voronoi Diagrams,  Up: Geometry
+
+29.3 Convex Hull
+================
+
+The convex hull of a set of points is the minimum convex envelope
+containing all of the points.  Octave has the functions `convhull' and
+`convhulln' to calculate the convex hull of 2-dimensional and
+N-dimensional sets of points.
+
+ -- Function File: H = convhull (X, Y)
+ -- Function File: H = convhull (X, Y, OPT)
+     Returns the index vector to the points of the enclosing convex
+     hull.  The data points are defined by the x and y vectors.
+
+     A third optional argument, which must be a string, contains extra
+     options passed to the underlying qhull command.  See the
+     documentation for the Qhull library for details.
+
+     *See also:* *note delaunay: doc-delaunay, *note convhulln:
+     doc-convhulln.
+
+ -- Loadable Function: H = convhulln (P)
+ -- Loadable Function: H = convhulln (P, OPT)
+ -- Loadable Function: [H, V] = convhulln (...)
+     Return an index vector to the points of the enclosing convex hull.
+     The input matrix of size [n, dim] contains n points of dimension
+     dim.
+
+     If a second optional argument is given, it must be a string or
+     cell array of strings containing options for the underlying qhull
+     command.  (See the Qhull documentation for the available options.)
+     The default options are "s Qci Tcv".  If the second output V is
+     requested the volume of the convex hull is calculated.
+
+     *See also:* *note convhull: doc-convhull, *note delaunayn:
+     doc-delaunayn.
+
+   An example of the use of `convhull' is
+
+     x = -3:0.05:3;
+     y = abs (sin (x));
+     k = convhull (x, y);
+     plot (x(k), y(k), "r-", x, y, "b+");
+     axis ([-3.05, 3.05, -0.05, 1.05]);
+
+
+File: octave.info,  Node: Interpolation on Scattered Data,  Prev: Convex Hull,  Up: Geometry
+
+29.4 Interpolation on Scattered Data
+====================================
+
+An important use of the Delaunay tessellation is that it can be used to
+interpolate from scattered data to an arbitrary set of points.  To do
+this the N-simplex of the known set of points is calculated with
+`delaunay', `delaunay3' or `delaunayn'.  Then the simplicies in to
+which the desired points are found are identified.  Finally the
+vertices of the simplicies are used to interpolate to the desired
+points.  The functions that perform this interpolation are `griddata',
+`griddata3' and `griddatan'.
+
+ -- Function File: ZI = griddata (X, Y, Z, XI, YI, METHOD)
+ -- Function File: [XI, YI, ZI] = griddata (X, Y, Z, XI, YI, METHOD)
+     Generate a regular mesh from irregular data using interpolation.
+     The function is defined by `Z = f (X, Y)'.  The interpolation
+     points are all `(XI, YI)'.  If XI, YI are vectors then they are
+     made into a 2D mesh.
+
+     The interpolation method can be `"nearest"', `"cubic"' or
+     `"linear"'.  If method is omitted it defaults to `"linear"'.
+
+     *See also:* *note delaunay: doc-delaunay.
+
+ -- Function File: VI = griddata3 (X, Y, Z, V XI, YI, ZI, METHOD,
+          OPTIONS)
+     Generate a regular mesh from irregular data using interpolation.
+     The function is defined by `Y = f (X,Y,Z)'.  The interpolation
+     points are all XI.
+
+     The interpolation method can be `"nearest"' or `"linear"'.  If
+     method is omitted it defaults to `"linear"'.
+
+     *See also:* *note griddata: doc-griddata, *note delaunayn:
+     doc-delaunayn.
+
+ -- Function File: YI = griddatan (X, Y, XI, METHOD, OPTIONS)
+     Generate a regular mesh from irregular data using interpolation.
+     The function is defined by `Y = f (X)'.  The interpolation points
+     are all XI.
+
+     The interpolation method can be `"nearest"' or `"linear"'.  If
+     method is omitted it defaults to `"linear"'.
+
+     *See also:* *note griddata: doc-griddata, *note delaunayn:
+     doc-delaunayn.
+
+   An example of the use of the `griddata' function is
+
+     rand("state",1);
+     x=2*rand(1000,1)-1;
+     y=2*rand(size(x))-1;
+     z=sin(2*(x.^2+y.^2));
+     [xx,yy]=meshgrid(linspace(-1,1,32));
+     griddata(x,y,z,xx,yy);
+
+that interpolates from a random scattering of points, to a uniform grid.
+
+
+File: octave.info,  Node: Signal Processing,  Next: Image Processing,  Prev: Geometry,  Up: Top
+
+30 Signal Processing
+********************
+
+This chapter describes the signal processing and fast Fourier transform
+functions available in Octave.  Fast Fourier transforms are computed
+with the FFTW or FFTPACK libraries depending on how Octave is built.
+
+ -- Function File:  detrend (X, P)
+     If X is a vector, `detrend (X, P)' removes the best fit of a
+     polynomial of order P from the data X.
+
+     If X is a matrix, `detrend (X, P)' does the same for each column
+     in X.
+
+     The second argument is optional.  If it is not specified, a value
+     of 1 is assumed.  This corresponds to removing a linear trend.
+
+ -- Loadable Function:  fft (A, N, DIM)
+     Compute the FFT of A using subroutines from FFTW.  The FFT is
+     calculated along the first non-singleton dimension of the array.
+     Thus if A is a matrix, `fft (A)' computes the FFT for each column
+     of A.
+
+     If called with two arguments, N is expected to be an integer
+     specifying the number of elements of A to use, or an empty matrix
+     to specify that its value should be ignored.  If N is larger than
+     the dimension along which the FFT is calculated, then A is resized
+     and padded with zeros.  Otherwise, if N is smaller than the
+     dimension along which the FFT is calculated, then A is truncated.
+
+     If called with three arguments, DIM is an integer specifying the
+     dimension of the matrix along which the FFT is performed
+
+     *See also:* *note ifft: doc-ifft, *note fft2: doc-fft2, *note
+     fftn: doc-fftn, *note fftw: doc-fftw.
+
+   Octave uses the FFTW libraries to perform FFT computations.  When
+Octave starts up and initializes the FFTW libraries, they read a system
+wide file (on a Unix system, it is typically `/etc/fftw/wisdom') that
+contains information useful to speed up FFT computations.  This
+information is called the _wisdom_.  The system-wide file allows wisdom
+to be shared between all applications using the FFTW libraries.
+
+   Use the `fftw' function to generate and save wisdom.  Using the
+utilities provided together with the FFTW libraries (`fftw-wisdom' on
+Unix systems), you can even add wisdom generated by Octave to the
+system-wide wisdom file.
+
+ -- Loadable Function: METHOD = fftw ('planner')
+ -- Loadable Function:  fftw ('planner', METHOD)
+ -- Loadable Function: WISDOM = fftw ('dwisdom')
+ -- Loadable Function: WISDOM = fftw ('dwisdom', WISDOM)
+     Manage FFTW wisdom data.  Wisdom data can be used to significantly
+     accelerate the calculation of the FFTs but implies an initial cost
+     in its calculation.  When the FFTW libraries are initialized, they
+     read a system wide wisdom file (typically in `/etc/fftw/wisdom'),
+     allowing wisdom to be shared between applications other than
+     Octave.  Alternatively, the `fftw' function can be used to import
+     wisdom.  For example
+
+          WISDOM = fftw ('dwisdom')
+
+     will save the existing wisdom used by Octave to the string WISDOM.
+     This string can then be saved to a file and restored using the
+     `save' and `load' commands respectively.  This existing wisdom can
+     be reimported as follows
+
+          fftw ('dwisdom', WISDOM)
+
+     If WISDOM is an empty matrix, then the wisdom used is cleared.
+
+     During the calculation of Fourier transforms further wisdom is
+     generated.  The fashion in which this wisdom is generated is
+     equally controlled by the `fftw' function.  There are five
+     different manners in which the wisdom can be treated, these being
+
+    'estimate'
+          This specifies that no run-time measurement of the optimal
+          means of calculating a particular is performed, and a simple
+          heuristic is used to pick a (probably sub-optimal) plan.  The
+          advantage of this method is that there is little or no
+          overhead in the generation of the plan, which is appropriate
+          for a Fourier transform that will be calculated once.
+
+    'measure'
+          In this case a range of algorithms to perform the transform
+          is considered and the best is selected based on their
+          execution time.
+
+    'patient'
+          This is like 'measure', but a wider range of algorithms is
+          considered.
+
+    'exhaustive'
+          This is like 'measure', but all possible algorithms that may
+          be used to treat the transform are considered.
+
+    'hybrid'
+          As run-time measurement of the algorithm can be expensive,
+          this is a compromise where 'measure' is used for transforms
+          up to the size of 8192 and beyond that the 'estimate' method
+          is used.
+
+     The default method is 'estimate', and the method currently being
+     used can be probed with
+
+          METHOD = fftw ('planner')
+
+     and the method used can be set using
+
+          fftw ('planner', METHOD)
+
+     Note that calculated wisdom will be lost when restarting Octave.
+     However, the wisdom data can be reloaded if it is saved to a file
+     as described above.  Saved wisdom files should not be used on
+     different platforms since they will not be efficient and the point
+     of calculating the wisdom is lost.
+
+     *See also:* *note fft: doc-fft, *note ifft: doc-ifft, *note fft2:
+     doc-fft2, *note ifft2: doc-ifft2, *note fftn: doc-fftn, *note
+     ifftn: doc-ifftn.
+
+ -- Loadable Function:  ifft (A, N, DIM)
+     Compute the inverse FFT of A using subroutines from FFTW.  The
+     inverse FFT is calculated along the first non-singleton dimension
+     of the array.  Thus if A is a matrix, `fft (A)' computes the
+     inverse FFT for each column of A.
+
+     If called with two arguments, N is expected to be an integer
+     specifying the number of elements of A to use, or an empty matrix
+     to specify that its value should be ignored.  If N is larger than
+     the dimension along which the inverse FFT is calculated, then A is
+     resized and padded with zeros.  Otherwise, ifN is smaller than the
+     dimension along which the inverse FFT is calculated, then A is
+     truncated.
+
+     If called with three arguments, DIM is an integer specifying the
+     dimension of the matrix along which the inverse FFT is performed
+
+     *See also:* *note fft: doc-fft, *note ifft2: doc-ifft2, *note
+     ifftn: doc-ifftn, *note fftw: doc-fftw.
+
+ -- Loadable Function:  fft2 (A, N, M)
+     Compute the two-dimensional FFT of A using subroutines from FFTW.
+     The optional arguments N and M may be used specify the number of
+     rows and columns of A to use.  If either of these is larger than
+     the size of A, A is resized and padded with zeros.
+
+     If A is a multi-dimensional matrix, each two-dimensional sub-matrix
+     of A is treated separately
+
+     *See also:* ifft2, fft, fftn, fftw.
+
+ -- Loadable Function:  fft2 (A, N, M)
+     Compute the inverse two-dimensional FFT of A using subroutines from
+     FFTW.  The optional arguments N and M may be used specify the
+     number of rows and columns of A to use.  If either of these is
+     larger than the size of A, A is resized and padded with zeros.
+
+     If A is a multi-dimensional matrix, each two-dimensional sub-matrix
+     of A is treated separately
+
+     *See also:* fft2, ifft, ifftn, fftw.
+
+ -- Loadable Function:  fftn (A, SIZE)
+     Compute the N-dimensional FFT of A using subroutines from FFTW.
+     The optional vector argument SIZE may be used specify the
+     dimensions of the array to be used.  If an element of SIZE is
+     smaller than the corresponding dimension, then the dimension is
+     truncated prior to performing the FFT.  Otherwise if an element of
+     SIZE is larger than the corresponding dimension A is resized and
+     padded with zeros.
+
+     *See also:* ifftn, fft, fft2, fftw.
+
+ -- Loadable Function:  ifftn (A, SIZE)
+     Compute the inverse N-dimensional FFT of A using subroutines from
+     FFTW.  The optional vector argument SIZE may be used specify the
+     dimensions of the array to be used.  If an element of SIZE is
+     smaller than the corresponding dimension, then the dimension is
+     truncated prior to performing the inverse FFT.  Otherwise if an
+     element of SIZE is larger than the corresponding dimension A is
+     resized and padded with zeros.
+
+     *See also:* fftn, ifft, ifft2, fftw.
+
+ -- Function File:  fftconv (A, B, N)
+     Return the convolution of the vectors A and B, as a vector with
+     length equal to the `length (a) + length (b) - 1'.  If A and B are
+     the coefficient vectors of two polynomials, the returned value is
+     the coefficient vector of the product polynomial.
+
+     The computation uses the FFT by calling the function `fftfilt'.  If
+     the optional argument N is specified, an N-point FFT is used.
+
+ -- Function File:  fftfilt (B, X, N)
+     With two arguments, `fftfilt' filters X with the FIR filter B
+     using the FFT.
+
+     Given the optional third argument, N, `fftfilt' uses the
+     overlap-add method to filter X with B using an N-point FFT.
+
+     If X is a matrix, filter each column of the matrix.
+
+ -- Loadable Function: y = filter (B, A, X)
+ -- Loadable Function: [Y, SF] = filter (B, A, X, SI)
+ -- Loadable Function: [Y, SF] = filter (B, A, X, [], DIM)
+ -- Loadable Function: [Y, SF] = filter (B, A, X, SI, DIM)
+     Return the solution to the following linear, time-invariant
+     difference equation:
+
+             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.  over the first
+     non-singleton dimension of X or over DIM if supplied.  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.
+
+     In terms of the z-transform, y is the result of passing the
+     discrete- time signal x through a system characterized by the
+     following rational system function:
+
+                       M
+                      SUM d(k+1) z^(-k)
+                      k=0
+            H(z) = ----------------------
+                         N
+                    1 + SUM c(k+1) z^(-k)
+                        k=1
+
+ -- Function File: Y = filter2 (B, X)
+ -- Function File: Y = filter2 (B, X, SHAPE)
+     Apply the 2-D FIR filter B to X.  If the argument SHAPE is
+     specified, return an array of the desired shape.  Possible values
+     are:
+
+    'full'
+          pad X with zeros on all sides before filtering.
+
+    'same'
+          unpadded X (default)
+
+    'valid'
+          trim X after filtering so edge effects are no included.
+
+     Note this is just a variation on convolution, with the parameters
+     reversed and B rotated 180 degrees.
+
+     *See also:* *note conv2: doc-conv2.
+
+ -- Function File: [H, W] = freqz (B, A, N, "whole")
+     Return the complex frequency response H of the rational IIR filter
+     whose numerator and denominator coefficients are B and A,
+     respectively.  The response is evaluated at N angular frequencies
+     between 0 and  2*pi.
+
+     The output value W is a vector of the frequencies.
+
+     If the fourth argument is omitted, the response is evaluated at
+     frequencies between 0 and  pi.
+
+     If N is omitted, a value of 512 is assumed.
+
+     If A is omitted, the denominator is assumed to be 1 (this
+     corresponds to a simple FIR filter).
+
+     For fastest computation, N should factor into a small number of
+     small primes.
+
+ -- Function File: H = freqz (B, A, W)
+     Evaluate the response at the specific frequencies in the vector W.
+     The values for W are measured in radians.
+
+ -- Function File: [...] = freqz (..., FS)
+     Return frequencies in Hz instead of radians assuming a sampling
+     rate FS.  If you are evaluating the response at specific
+     frequencies W, those frequencies should be requested in Hz rather
+     than radians.
+
+ -- Function File:  freqz (...)
+     Plot the pass band, stop band and phase response of H rather than
+     returning them.
+
+ -- Function File:  freqz_plot (W, H)
+     Plot the pass band, stop band and phase response of H.
+
+ -- Function File:  sinc (X)
+     Return  sin(pi*x)/(pi*x).
+
+ -- Function File: B = unwrap (A, TOL, DIM)
+     Unwrap radian phases by adding multiples of 2*pi as appropriate to
+     remove jumps greater than TOL.  TOL defaults to pi.
+
+     Unwrap will unwrap along the first non-singleton dimension of A,
+     unless the optional argument DIM is given, in which case the data
+     will be unwrapped along this dimension
+
+ -- Function File: [A, B] = arch_fit (Y, X, P, ITER, GAMMA, A0, B0)
+     Fit an ARCH regression model to the time series Y using the
+     scoring algorithm in Engle's original ARCH paper.  The model is
+
+          y(t) = b(1) * x(t,1) + ... + b(k) * x(t,k) + e(t),
+          h(t) = a(1) + a(2) * e(t-1)^2 + ... + a(p+1) * e(t-p)^2
+
+     in which e(t) is N(0, h(t)), given a time-series vector Y up to
+     time t-1 and a matrix of (ordinary) regressors X up to t.  The
+     order of the regression of the residual variance is specified by P.
+
+     If invoked as `arch_fit (Y, K, P)' with a positive integer K, fit
+     an ARCH(K, P) process, i.e., do the above with the t-th row of X
+     given by
+
+          [1, y(t-1), ..., y(t-k)]
+
+     Optionally, one can specify the number of iterations ITER, the
+     updating factor GAMMA, and initial values a0 and b0 for the
+     scoring algorithm.
+
+ -- Function File:  arch_rnd (A, B, T)
+     Simulate an ARCH sequence of length T with AR coefficients B and
+     CH coefficients A.  I.e., the result y(t) follows the model
+
+          y(t) = b(1) + b(2) * y(t-1) + ... + b(lb) * y(t-lb+1) + e(t),
+
+     where e(t), given Y up to time t-1, is N(0, h(t)), with
+
+          h(t) = a(1) + a(2) * e(t-1)^2 + ... + a(la) * e(t-la+1)^2
+
+ -- Function File: [PVAL, LM] = arch_test (Y, X, P)
+     For a linear regression model
+
+          y = x * b + e
+
+     perform a Lagrange Multiplier (LM) test of the null hypothesis of
+     no conditional heteroscedascity against the alternative of CH(P).
+
+     I.e., the model is
+
+          y(t) = b(1) * x(t,1) + ... + b(k) * x(t,k) + e(t),
+
+     given Y up to t-1 and X up to t, e(t) is N(0, h(t)) with
+
+          h(t) = v + a(1) * e(t-1)^2 + ... + a(p) * e(t-p)^2,
+
+     and the null is a(1) == ... == a(p) == 0.
+
+     If the second argument is a scalar integer, k, perform the same
+     test in a linear autoregression model of order k, i.e., with
+
+          [1, y(t-1), ..., y(t-K)]
+
+     as the t-th row of X.
+
+     Under the null, LM approximately has a chisquare distribution with
+     P degrees of freedom and PVAL is the p-value (1 minus the CDF of
+     this distribution at LM) of the test.
+
+     If no output argument is given, the p-value is displayed.
+
+ -- Function File:  arma_rnd (A, B, V, T, N)
+     Return a simulation of the ARMA model
+
+          x(n) = a(1) * x(n-1) + ... + a(k) * x(n-k)
+               + e(n) + b(1) * e(n-1) + ... + b(l) * e(n-l)
+
+     in which K is the length of vector A, L is the length of vector B
+     and E is Gaussian white noise with variance V.  The function
+     returns a vector of length T.
+
+     The optional parameter N gives the number of dummy X(I) used for
+     initialization, i.e., a sequence of length T+N is generated and
+     X(N+1:T+N) is returned.  If N is omitted, N = 100 is used.
+
+ -- Function File:  autocor (X, H)
+     Return the autocorrelations from lag 0 to H of vector X.  If H is
+     omitted, all autocorrelations are computed.  If X is a matrix, the
+     autocorrelations of each column are computed.
+
+ -- Function File:  autocov (X, H)
+     Return the autocovariances from lag 0 to H of vector X.  If H is
+     omitted, all autocovariances are computed.  If X is a matrix, the
+     autocovariances of each column are computed.
+
+ -- Function File:  autoreg_matrix (Y, K)
+     Given a time series (vector) Y, return a matrix with ones in the
+     first column and the first K lagged values of Y in the other
+     columns.  I.e., for T > K, `[1, Y(T-1), ..., Y(T-K)]' is the t-th
+     row of the result.  The resulting matrix may be used as a
+     regressor matrix in autoregressions.
+
+ -- Function File:  bartlett (M)
+     Return the filter coefficients of a Bartlett (triangular) window of
+     length M.
+
+     For a definition of the Bartlett window, see e.g., A. V. Oppenheim
+     & R. W. Schafer, `Discrete-Time Signal Processing'.
+
+ -- Function File:  blackman (M)
+     Return the filter coefficients of a Blackman window of length M.
+
+     For a definition of the Blackman window, see e.g., A. V. Oppenheim
+     & R. W. Schafer, `Discrete-Time Signal Processing'.
+
+ -- Function File: [D, DD] = diffpara (X, A, B)
+     Return the estimator D for the differencing parameter of an
+     integrated time series.
+
+     The frequencies from [2*pi*a/t, 2*pi*b/T] are used for the
+     estimation.  If B is omitted, the interval [2*pi/T, 2*pi*a/T] is
+     used.  If both B and A are omitted then a = 0.5 * sqrt (T) and b =
+     1.5 * sqrt (T) is used, where T is the sample size.  If X is a
+     matrix, the differencing parameter of each column is estimated.
+
+     The estimators for all frequencies in the intervals described
+     above is returned in DD.  The value of D is simply the mean of DD.
+
+     Reference: Brockwell, Peter J. & Davis, Richard A. Time Series:
+     Theory and Methods Springer 1987.
+
+ -- Function File:  durbinlevinson (C, OLDPHI, OLDV)
+     Perform one step of the Durbin-Levinson algorithm.
+
+     The vector C specifies the autocovariances `[gamma_0, ...,
+     gamma_t]' from lag 0 to T, OLDPHI specifies the coefficients based
+     on C(T-1) and OLDV specifies the corresponding error.
+
+     If OLDPHI and OLDV are omitted, all steps from 1 to T of the
+     algorithm are performed.
+
+ -- Function File:  fftshift (V)
+ -- Function File:  fftshift (V, DIM)
+     Perform a shift of the vector V, for use with the `fft' and `ifft'
+     functions, in order the move the frequency 0 to the center of the
+     vector or matrix.
+
+     If V is a vector of N elements corresponding to N time samples
+     spaced of Dt each, then `fftshift (fft (V))' corresponds to
+     frequencies
+
+          f = ((1:N) - ceil(N/2)) / N / Dt
+
+     If V is a matrix, the same holds for rows and columns.  If V is an
+     array, then the same holds along each dimension.
+
+     The optional DIM argument can be used to limit the dimension along
+     which the permutation occurs.
+
+ -- Function File:  ifftshift (V)
+ -- Function File:  ifftshift (V, DIM)
+     Undo the action of the `fftshift' function.  For even length V,
+     `fftshift' is its own inverse, but odd lengths differ slightly.
+
+ -- Function File:  fractdiff (X, D)
+     Compute the fractional differences (1-L)^d x where L denotes the
+     lag-operator and d is greater than -1.
+
+ -- Function File:  hamming (M)
+     Return the filter coefficients of a Hamming window of length M.
+
+     For a definition of the Hamming window, see e.g., A. V. Oppenheim &
+     R. W. Schafer, `Discrete-Time Signal Processing'.
+
+ -- Function File:  hanning (M)
+     Return the filter coefficients of a Hanning window of length M.
+
+     For a definition of this window type, see e.g., A. V. Oppenheim &
+     R. W. Schafer, `Discrete-Time Signal Processing'.
+
+ -- Function File:  hurst (X)
+     Estimate the Hurst parameter of sample X via the rescaled range
+     statistic.  If X is a matrix, the parameter is estimated for every
+     single column.
+
+ -- Function File: PP = pchip (X, Y)
+ -- Function File: YI = pchip (X, Y, XI)
+     Piecewise Cubic Hermite interpolating polynomial.  Called with two
+     arguments, the piece-wise polynomial PP is returned, that may
+     later be used with `ppval' to evaluate the polynomial at specific
+     points.
+
+     The variable X must be a strictly monotonic vector (either
+     increasing or decreasing).  While Y can be either a vector or
+     array.  In the case where Y is a vector, it must have a length of
+     N.  If Y is an array, then the size of Y must have the form `[S1,
+     S2, ..., SK, N]' The array is then reshaped internally to a matrix
+     where the leading dimension is given by `S1 * S2 * ... * SK' and
+     each row in this matrix is then treated separately.  Note that this
+     is exactly the opposite treatment than `interp1' and is done for
+     compatibility.
+
+     Called with a third input argument, `pchip' evaluates the
+     piece-wise polynomial at the points XI.  There is an equivalence
+     between `ppval (pchip (X, Y), XI)' and `pchip (X, Y, XI)'.
+
+     *See also:* *note spline: doc-spline, *note ppval: doc-ppval,
+     *note mkpp: doc-mkpp, *note unmkpp: doc-unmkpp.
+
+ -- Function File:  periodogram (X)
+     For a data matrix X from a sample of size N, return the
+     periodogram.
+
+ -- Function File:  rectangle_lw (N, B)
+     Rectangular lag window.  Subfunction used for spectral density
+     estimation.
+
+ -- Function File:  rectangle_sw (N, B)
+     Rectangular spectral window.  Subfunction used for spectral density
+     estimation.
+
+ -- Function File:  sinetone (FREQ, RATE, SEC, AMPL)
+     Return a sinetone of frequency FREQ with length of SEC seconds at
+     sampling rate RATE and with amplitude AMPL.  The arguments FREQ
+     and AMPL may be vectors of common size.
+
+     Defaults are RATE = 8000, SEC = 1 and AMPL = 64.
+
+ -- Function File:  sinewave (M, N, D)
+     Return an M-element vector with I-th element given by `sin (2 * pi
+     * (I+D-1) / N)'.
+
+     The default value for D is 0 and the default value for N is M.
+
+ -- Function File:  spectral_adf (C, WIN, B)
+     Return the spectral density estimator given a vector of
+     autocovariances C, window name WIN, and bandwidth, B.
+
+     The window name, e.g., `"triangle"' or `"rectangle"' is used to
+     search for a function called `WIN_sw'.
+
+     If WIN is omitted, the triangle window is used.  If B is omitted,
+     `1 / sqrt (length (X))' is used.
+
+ -- Function File:  spectral_xdf (X, WIN, B)
+     Return the spectral density estimator given a data vector X,
+     window name WIN, and bandwidth, B.
+
+     The window name, e.g., `"triangle"' or `"rectangle"' is used to
+     search for a function called `WIN_sw'.
+
+     If WIN is omitted, the triangle window is used.  If B is omitted,
+     `1 / sqrt (length (X))' is used.
+
+ -- Function File:  spencer (X)
+     Return Spencer's 15 point moving average of every single column of
+     X.
+
+ -- Function File: [Y, C] = stft (X, WIN_SIZE, INC, NUM_COEF, W_TYPE)
+     Compute the short-time Fourier transform of the vector X with
+     NUM_COEF coefficients by applying a window of WIN_SIZE data points
+     and an increment of INC points.
+
+     Before computing the Fourier transform, one of the following
+     windows is applied:
+
+    hanning
+          w_type = 1
+
+    hamming
+          w_type = 2
+
+    rectangle
+          w_type = 3
+
+     The window names can be passed as strings or by the W_TYPE number.
+
+     If not all arguments are specified, the following defaults are
+     used: WIN_SIZE = 80, INC = 24, NUM_COEF = 64, and W_TYPE = 1.
+
+     `Y = stft (X, ...)' returns the absolute values of the Fourier
+     coefficients according to the NUM_COEF positive frequencies.
+
+     `[Y, C] = stft (`x', ...)' returns the entire STFT-matrix Y and a
+     3-element vector C containing the window size, increment, and
+     window type, which is needed by the synthesis function.
+
+ -- Function File:  synthesis (Y, C)
+     Compute a signal from its short-time Fourier transform Y and a
+     3-element vector C specifying window size, increment, and window
+     type.
+
+     The values Y and C can be derived by
+
+          [Y, C] = stft (X , ...)
+
+ -- Function File:  triangle_lw (N, B)
+     Triangular lag window.  Subfunction used for spectral density
+     estimation.
+
+ -- Function File:  triangle_sw (N, B)
+     Triangular spectral window.  Subfunction used for spectral density
+     estimation.
+
+ -- Function File: [A, V] = yulewalker (C)
+     Fit an AR (p)-model with Yule-Walker estimates given a vector C of
+     autocovariances `[gamma_0, ..., gamma_p]'.
+
+     Returns the AR coefficients, A, and the variance of white noise, V.
+
+
+File: octave.info,  Node: Image Processing,  Next: Audio Processing,  Prev: Signal Processing,  Up: Top
+
+31 Image Processing
+*******************
+
+Since an image basically is a matrix Octave is a very powerful
+environment for processing and analyzing images.  To illustrate how
+easy it is to do image processing in Octave, the following example will
+load an image, smooth it by a 5-by-5 averaging filter, and compute the
+gradient of the smoothed image.
+
+     I = imread ("myimage.jpg");
+     S = conv2 (I, ones (5, 5) / 25, "same");
+     [Dx, Dy] = gradient (S);
+
+In this example `S' contains the smoothed image, and `Dx' and `Dy'
+contains the partial spatial derivatives of the image.
+
+* Menu:
+
+* Loading and Saving Images::
+* Displaying Images::
+* Representing Images::
+* Plotting on top of Images::
+* Color Conversion::
+
+
+File: octave.info,  Node: Loading and Saving Images,  Next: Displaying Images,  Up: Image Processing
+
+31.1 Loading and Saving Images
+==============================
+
+The first step in most image processing tasks is to load an image into
+Octave.  This is done using the `imread' function, which uses the
+`GraphicsMagick' library for reading.  This means a vast number of image
+formats is supported.  The `imwrite' function is the corresponding
+function for writing images to the disk.
+
+   In summary, most image processing code will follow the structure of
+this code
+
+     I = imread ("my_input_image.img");
+     J = process_my_image (I);
+     imwrite ("my_output_image.img", J);
+
+ -- Function File: [IMG, MAP, ALPHA] = imread (FILENAME)
+     Read images from various file formats.
+
+     The size and numeric class of the output depends on the format of
+     the image.  A color image is returned as an MxNx3 matrix.
+     Grey-level and black-and-white images are of size MxN.  The color
+     depth of the image determines the numeric class of the output:
+     "uint8" or "uint16" for grey and color, and "logical" for black
+     and white.
+
+     *See also:* *note imwrite: doc-imwrite, *note imfinfo: doc-imfinfo.
+
+ -- Function File:  imwrite (IMG, FILENAME, FMT, P1, V1, ...)
+ -- Function File:  imwrite (IMG, MAP, FILENAME, FMT, P1, V1, ...)
+     Write images in various file formats.
+
+     If FMT is missing, the file extension (if any) of FILENAME is used
+     to determine the format.
+
+     The parameter-value pairs (P1, V1, ...) are optional.  Currently
+     the following options are supported for JPEG images
+
+    `Quality'
+          Sets the quality of the compression.  The corresponding value
+          should be an integer between 0 and 100, with larger values
+          meaning higher visual quality and less compression.
+
+     *See also:* *note imread: doc-imread, *note imfinfo: doc-imfinfo.
+
+ -- Built-in Function: VAL = IMAGE_PATH ()
+ -- Built-in Function: OLD_VAL = IMAGE_PATH (NEW_VAL)
+     Query or set the internal variable that specifies a colon separated
+     list of directories in which to search for image files.
+
+   It is possible to get information about an image file on disk,
+without actually reading it into Octave.  This is done using the
+`imfinfo' function which provides read access to many of the parameters
+stored in the header of the image file.
+
+ -- Function File: INFO = imfinfo (FILENAME)
+ -- Function File: INFO = imfinfo (URL)
+     Read image information from a file.
+
+     `imfinfo' returns a structure containing information about the
+     image stored in the file FILENAME.  The output structure contains
+     the following fields.
+
+    `Filename'
+          The full name of the image file.
+
+    `FileSize'
+          Number of bytes of the image on disk
+
+    `FileModDate'
+          Date of last modification to the file.
+
+    `Height'
+          Image height in pixels.
+
+    `Width'
+          Image Width in pixels.
+
+    `BitDepth'
+          Number of bits per channel per pixel.
+
+    `Format'
+          Image format (e.g., `"jpeg"').
+
+    `LongFormat'
+          Long form image format description.
+
+    `XResolution'
+          X resolution of the image.
+
+    `YResolution'
+          Y resolution of the image.
+
+    `TotalColors'
+          Number of unique colors in the image.
+
+    `TileName'
+          Tile name.
+
+    `AnimationDelay'
+          Time in 1/100ths of a second (0 to 65535) which must expire
+          before displaying the next image in an animated sequence.
+
+    `AnimationIterations'
+          Number of iterations to loop an animation (e.g., Netscape
+          loop extension) for.
+
+    `ByteOrder'
+          Endian option for formats that support it.  Is either
+          `"little-endian"', `"big-endian"', or `"undefined"'.
+
+    `Gamma'
+          Gamma level of the image.  The same color image displayed on
+          two different workstations may look different due to
+          differences in the display monitor.
+
+    `Matte'
+          `true' if the image has transparency.
+
+    `ModulusDepth'
+          Image modulus depth (minimum number of bits required to
+          support red/green/blue components without loss of accuracy).
+
+    `Quality'
+          JPEG/MIFF/PNG compression level.
+
+    `QuantizeColors'
+          Preferred number of colors in the image.
+
+    `ResolutionUnits'
+          Units of image resolution.  Is either `"pixels per inch"',
+          `"pixels per centimeter"', or `"undefined"'.
+
+    `ColorType'
+          Image type.  Is either `"grayscale"', `"indexed"',
+          `"truecolor"', or `"undefined"'.
+
+    `View'
+          FlashPix viewing parameters.
+
+     *See also:* *note imread: doc-imread, *note imwrite: doc-imwrite.
+
+
+File: octave.info,  Node: Displaying Images,  Next: Representing Images,  Prev: Loading and Saving Images,  Up: Image Processing
+
+31.2 Displaying Images
+======================
+
+A natural part of image processing is visualization of an image.  The
+most basic function for this is the `imshow' function that shows the
+image given in the first input argument.  This function uses an
+external program to show the image.  If gnuplot 4.2 or later is
+available it will be used to display the image, otherwise the
+`display', `xv', or `xloadimage' program is used.  The actual program
+can be selected with the `image_viewer' function.
+
+ -- Function File:  imshow (IM)
+ -- Function File:  imshow (IM, LIMITS)
+ -- Function File:  imshow (IM, MAP)
+ -- Function File:  imshow (RGB, ...)
+ -- Function File:  imshow (FILENAME)
+ -- Function File:  imshow (..., STRING_PARAM1, VALUE1, ...)
+     Display the image IM, where IM can be a 2-dimensional (gray-scale
+     image) or a 3-dimensional (RGB image) matrix.
+
+     If LIMITS is a 2-element vector `[LOW, HIGH]', the image is shown
+     using a display range between LOW and HIGH.  If an empty matrix is
+     passed for LIMITS, the display range is computed as the range
+     between the minimal and the maximal value in the image.
+
+     If MAP is a valid color map, the image will be shown as an indexed
+     image using the supplied color map.
+
+     If a file name is given instead of an image, the file will be read
+     and shown.
+
+     If given, the parameter STRING_PARAM1 has value VALUE1.
+     STRING_PARAM1 can be any of the following:
+    `"displayrange"'
+          VALUE1 is the display range as described above.
+
+     *See also:* *note image: doc-image, *note imagesc: doc-imagesc,
+     *note colormap: doc-colormap, *note gray2ind: doc-gray2ind, *note
+     rgb2ind: doc-rgb2ind.
+
+ -- Function File:  image (IMG)
+ -- Function File:  image (X, Y, IMG)
+     Display a matrix as a color image.  The elements of X are indices
+     into the current colormap, and the colormap will be scaled so that
+     the extremes of X are mapped to the extremes of the colormap.
+
+     It first tries to use `gnuplot', then `display' from
+     `ImageMagick', then `xv', and then `xloadimage'.  The actual
+     program used can be changed using the `image_viewer' function.
+
+     The axis values corresponding to the matrix elements are specified
+     in X and Y.  If you're not using gnuplot 4.2 or later, these
+     variables are ignored.
+
+     *See also:* *note imshow: doc-imshow, *note imagesc: doc-imagesc,
+     *note colormap: doc-colormap, *note image_viewer: doc-image_viewer.
+
+ -- Function File:  imagesc (A)
+ -- Function File:  imagesc (X, Y, A)
+ -- Function File:  imagesc (..., LIMITS)
+ -- Function File:  imagesc (H, ...)
+ -- Function File: H = imagesc (...)
+     Display a scaled version of the matrix A as a color image.  The
+     colormap is scaled so that the entries of the matrix occupy the
+     entire colormap.  If LIMITS = [LO, HI] are given, then that range
+     is set to the 'clim' of the current axes.
+
+     The axis values corresponding to the matrix elements are specified
+     in X and Y, either as pairs giving the minimum and maximum values
+     for the respective axes, or as values for each row and column of
+     the matrix A.
+
+     *See also:* *note image: doc-image, *note imshow: doc-imshow,
+     *note caxis: doc-caxis.
+
+ -- Function File: [FCN, DEFAULT_ZOOM] = image_viewer (FCN,
+          DEFAULT_ZOOM)
+     Change the program or function used for viewing images and return
+     the previous values.
+
+     When the `image' or `imshow' function is called it will launch an
+     external program to display the image.  The default behavior is to
+     use gnuplot if the installed version supports image viewing, and
+     otherwise try the programs `display', `xv', and `xloadimage'.
+     Using this function it is possible to change that behavior.
+
+     When called with one input argument images will be displayed by
+     saving the image to a file and the system command COMMAND will be
+     called to view the image.  The COMMAND must be a string containing
+     `%s' and possibly `%f'.  The `%s' will be replaced by the filename
+     of the image, and the `%f' will (if present) be replaced by the
+     zoom factor given to the `image' function.  For example,
+          image_viewer ("eog %s");
+     changes the image viewer to the `eog' program.
+
+     With two input arguments, images will be displayed by calling the
+     function FUNCTION_HANDLE.  For example,
+          image_viewer (data, @my_image_viewer);
+     sets the image viewer function to `my_image_viewer'.  The image
+     viewer function is called with
+          my_image_viewer (X, Y, IM, ZOOM, DATA)
+     where X and Y are the axis of the image, IM is the image variable,
+     and DATA is extra user-supplied data to be passed to the viewer
+     function.
+
+     With three input arguments it is possible to change the zooming.
+     Some programs (like `xloadimage') require the zoom factor to be
+     between 0 and 100, and not 0 and 1 like Octave assumes.  This is
+     solved by setting the third argument to 100.
+
+     *See also:* *note image: doc-image, *note imshow: doc-imshow.
+
+
+File: octave.info,  Node: Representing Images,  Next: Plotting on top of Images,  Prev: Displaying Images,  Up: Image Processing
+
+31.3 Representing Images
+========================
+
+In general Octave supports four different kinds of images, gray-scale
+images, RGB images, binary images, and indexed images.  A gray-scale
+image is represented with an M-by-N matrix in which each element
+corresponds to the intensity of a pixel.  An RGB image is represented
+with an M-by-N-by-3 array where each 3-vector corresponds to the red,
+green, and blue intensities of each pixel.
+
+   The actual meaning of the value of a pixel in a gray-scale or RGB
+image depends on the class of the matrix.  If the matrix is of class
+`double' pixel intensities are between 0 and 1, if it is of class
+`uint8' intensities are between 0 and 255, and if it is of class
+`uint16' intensities are between 0 and 65535.
+
+   A binary image is an M-by-N matrix of class `logical'.  A pixel in a
+binary image is black if it is `false' and white if it is `true'.
+
+   An indexed image consists of an M-by-N matrix of integers and a
+C-by-3 color map.  Each integer corresponds to an index in the color
+map, and each row in the color map corresponds to an RGB color.  The
+color map must be of class `double' with values between 0 and 1.
+
+ -- Function File: [IMG, MAP] = gray2ind (I, N)
+     Convert a gray scale intensity image to an Octave indexed image.
+     The indexed image will consist of N different intensity values.
+     If not given N will default to 64.
+
+ -- Function File:  ind2gray (X, MAP)
+     Convert an Octave indexed image to a gray scale intensity image.
+     If MAP is omitted, the current colormap is used to determine the
+     intensities.
+
+     *See also:* *note gray2ind: doc-gray2ind, *note rgb2ntsc:
+     doc-rgb2ntsc, *note image: doc-image, *note colormap: doc-colormap.
+
+ -- Function File: [X, MAP] = rgb2ind (RGB)
+ -- Function File: [X, MAP] = rgb2ind (R, G, B)
+     Convert an RGB image to an Octave indexed image.
+
+     *See also:* *note ind2rgb: doc-ind2rgb, *note rgb2ntsc:
+     doc-rgb2ntsc.
+
+ -- Function File: RGB = ind2rgb (X, MAP)
+ -- Function File: [R, G, B] = ind2rgb (X, MAP)
+     Convert an indexed image to red, green, and blue color components.
+     If the colormap doesn't contain enough colors, pad it with the
+     last color in the map.  If MAP is omitted, the current colormap is
+     used for the conversion.
+
+     *See also:* *note rgb2ind: doc-rgb2ind, *note image: doc-image,
+     *note imshow: doc-imshow, *note ind2gray: doc-ind2gray, *note
+     gray2ind: doc-gray2ind.
+
+ -- Function File:  colormap (MAP)
+ -- Function File:  colormap ("default")
+     Set the current colormap.
+
+     `colormap (MAP)' sets the current colormap to MAP.  The color map
+     should be an N row by 3 column matrix.  The columns contain red,
+     green, and blue intensities respectively.  All entries should be
+     between 0 and 1 inclusive.  The new colormap is returned.
+
+     `colormap ("default")' restores the default colormap (the `jet'
+     map with 64 entries).  The default colormap is returned.
+
+     With no arguments, `colormap' returns the current color map.
+
+     *See also:* *note jet: doc-jet.
+
+ -- Function File: MAP_OUT = brighten (MAP, BETA)
+ -- Function File: MAP_OUT = brighten (H, BETA)
+ -- Function File: MAP_OUT = brighten (BETA)
+     Darkens or brightens the given colormap.  If the MAP argument is
+     omitted, the function is applied to the current colormap.  The
+     first argument can also be a valid graphics handle H, in which case
+     `brighten' is applied to the colormap associated with this handle.
+
+     Should the resulting colormap MAP_OUT not be assigned, it will be
+     written to the current colormap.
+
+     The argument BETA should be a scalar between -1 and 1, where a
+     negative value darkens and a positive value brightens the colormap.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  autumn (N)
+     Create color colormap.  This colormap is red through orange to
+     yellow.  The argument N should be a scalar.  If it is omitted, the
+     length of the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  bone (N)
+     Create color colormap.  This colormap is a gray colormap with a
+     light blue tone.  The argument N should be a scalar.  If it is
+     omitted, the length of the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  cool (N)
+     Create color colormap.  The colormap is cyan to magenta.  The
+     argument N should be a scalar.  If it is omitted, the length of
+     the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  copper (N)
+     Create color colormap.  This colormap is black to a light copper
+     tone.  The argument N should be a scalar.  If it is omitted, the
+     length of the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  flag (N)
+     Create color colormap.  This colormap cycles through red, white,
+     blue and black.  The argument N should be a scalar.  If it is
+     omitted, the length of the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  gray (N)
+     Return a gray colormap with N entries corresponding to values from
+     0 to N-1.  The argument N should be a scalar.  If it is omitted,
+     the length of the current colormap or 64 is assumed.
+
+ -- Function File:  hot (N)
+     Create color colormap.  This colormap is black through dark red,
+     red, orange, yellow to white.  The argument N should be a scalar.
+     If it is omitted, the length of the current colormap or 64 is
+     assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  hsv (N)
+     Create color colormap.  This colormap is red through yellow, green,
+     cyan, blue, magenta to red.  It is obtained by linearly varying the
+     hue through all possible values while keeping constant maximum
+     saturation and value and is equivalent to `hsv2rgb
+     ([linspace(0,1,N)', ones(N,2)])'.
+
+     The argument N should be a scalar.  If it is omitted, the length
+     of the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  jet (N)
+     Create color colormap.  This colormap is dark blue through blue,
+     cyan, green, yellow, red to dark red.  The argument N should be a
+     scalar.  If it is omitted, the length of the current colormap or
+     64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  ocean (N)
+     Create color colormap.  The argument N should be a scalar.  If it
+     is omitted, the length of the current colormap or 64 is assumed.
+
+ -- Function File:  pink (N)
+     Create color colormap.  This colormap gives a sepia tone on black
+     and white images.  The argument N should be a scalar.  If it is
+     omitted, the length of the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  prism (N)
+     Create color colormap.  This colormap cycles trough red, orange,
+     yellow, green, blue and violet.  The argument N should be a
+     scalar.  If it is omitted, the length of the current colormap or
+     64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  rainbow (N)
+     Create color colormap.  This colormap is red through orange,
+     yellow, green, blue to violet.  The argument N should be a scalar.
+     If it is omitted, the length of the current colormap or 64 is
+     assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  spring (N)
+     Create color colormap.  This colormap is magenta to yellow.  The
+     argument N should be a scalar.  If it is omitted, the length of
+     the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  summer (N)
+     Create color colormap.  This colormap is green to yellow.  The
+     argument N should be a scalar.  If it is omitted, the length of
+     the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  white (N)
+     Create color colormap.  This colormap is completely white.  The
+     argument N should be a scalar.  If it is omitted, the length of
+     the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  winter (N)
+     Create color colormap.  This colormap is blue to green.  The
+     argument N should be a scalar.  If it is omitted, the length of
+     the current colormap or 64 is assumed.
+
+     *See also:* *note colormap: doc-colormap.
+
+ -- Function File:  contrast (X, N)
+     Return a gray colormap that maximizes the contrast in an image.
+     The returned colormap will have N rows.  If N is not defined then
+     the size of the current colormap is used instead.
+
+     *See also:* *note colormap: doc-colormap.
+
+   An additional colormap is `gmap40'.  This code map contains only
+colors with integer values of the red, green and blue components.  This
+is a workaround for a limitation of gnuplot 4.0, that does not allow
+the color of line or patch objects to be set, and so `gmap40' is useful
+for gnuplot 4.0 users, and in particular in conjunction with the BAR,
+BARH or CONTOUR functions.
+
+ -- Function File:  gmap40 (N)
+     Create a color colormap.  The colormap is red, green, blue, yellow,
+     magenta and cyan.  These are the colors that are allowed with patch
+     objects using gnuplot 4.0, and so this colormap function is
+     specially designed for users of gnuplot 4.0.  The argument N
+     should be a scalar.  If it is omitted, a length of 6 is assumed.
+     Larger values of N result in a repetition of the above colors
+
+     *See also:* *note colormap: doc-colormap.
+
+   You may use the `spinmap' function to cycle through the colors in
+the current colormap, displaying the changes for the current figure.
+
+ -- Function File:  spinmap (T, INC)
+     Cycle the colormap for T seconds with an increment of INC.  Both
+     parameters are optional.  The default cycle time is 5 seconds and
+     the default increment is 2.
+
+     A higher value of INC causes a faster cycle through the colormap.
+
+     *See also:* *note gca: doc-gca, *note colorbar: doc-colorbar.
+
+
+File: octave.info,  Node: Plotting on top of Images,  Next: Color Conversion,  Prev: Representing Images,  Up: Image Processing
+
+31.4 Plotting on top of Images
+==============================
+
+If gnuplot is being used to display images it is possible to plot on
+top of images.  Since an image is a matrix it is indexed by row and
+column values.  The plotting system is, however, based on the
+traditional (x, y) system.  To minimize the difference between the two
+systems Octave places the origin of the coordinate system in the point
+corresponding to the pixel at (1, 1).  So, to plot points given by row
+and column values on top of an image, one should simply call `plot'
+with the column values as the first argument and the row values as the
+second.  As an example the following code generates an image with
+random intensities between 0 and 1, and shows the image with red
+circles over pixels with an intensity above 0.99.
+
+     I = rand (100, 100);
+     [row, col] = find (I > 0.99);
+     hold ("on");
+     imshow (I);
+     plot (col, row, "ro");
+     hold ("off");
+
+
+File: octave.info,  Node: Color Conversion,  Prev: Plotting on top of Images,  Up: Image Processing
+
+31.5 Color Conversion
+=====================
+
+Octave supports conversion from the RGB color system to NTSC and HSV
+and vice versa.
+
+ -- Function File: HSV_MAP = rgb2hsv (RGB_MAP)
+     Transform a colormap or image from the rgb space to the hsv space.
+
+     A color n the RGB space consists of the red, green and blue
+     intensities.
+
+     In the HSV space each color is represented by their hue, saturation
+     and value (brightness).  Value gives the amount of light in the
+     color.  Hue describes the dominant wavelength.  Saturation is the
+     amount of Hue mixed into the color.
+
+     *See also:* *note hsv2rgb: doc-hsv2rgb.
+
+ -- Function File: RGB_MAP = hsv2rgb (HSV_MAP)
+     Transform a colormap or image from the hsv space to the rgb space.
+
+     *See also:* *note rgb2hsv: doc-rgb2hsv.
+
+ -- Function File:  rgb2ntsc (RGB)
+     Transform a colormap or image from RGB to NTSC.
+
+     *See also:* *note ntsc2rgb: doc-ntsc2rgb.
+
+ -- Function File:  ntsc2rgb (YIQ)
+     Transform a colormap or image from NTSC to RGB.
+
+     *See also:* *note rgb2ntsc: doc-rgb2ntsc.
+
+
+File: octave.info,  Node: Audio Processing,  Next: Object Oriented Programming,  Prev: Image Processing,  Up: Top
+
+32 Audio Processing
+*******************
+
+Octave provides a few functions for dealing with audio data.  An audio
+`sample' is a single output value from an A/D converter, i.e., a small
+integer number (usually 8 or 16 bits), and audio data is just a series
+of such samples.  It can be characterized by three parameters:  the
+sampling rate (measured in samples per second or Hz, e.g., 8000 or
+44100), the number of bits per sample (e.g., 8 or 16), and the number of
+channels (1 for mono, 2 for stereo, etc.).
+
+   There are many different formats for representing such data.
+Currently, only the two most popular, _linear encoding_ and _mu-law
+encoding_, are supported by Octave.  There is an excellent FAQ on audio
+formats by Guido van Rossum <guido at cwi.nl> which can be found at any
+FAQ ftp site, in particular in the directory
+`/pub/usenet/news.answers/audio-fmts' of the archive site
+`rtfm.mit.edu'.
+
+   Octave simply treats audio data as vectors of samples (non-mono data
+are not supported yet).  It is assumed that audio files using linear
+encoding have one of the extensions `lin' or `raw', and that files
+holding data in mu-law encoding end in `au', `mu', or `snd'.
+
+ -- Function File:  lin2mu (X, N)
+     Converts audio data from linear to mu-law.  Mu-law values use 8-bit
+     unsigned integers.  Linear values use N-bit signed integers or
+     floating point values in the range -1<=X<=1 if N is 0.  If N is
+     not specified it defaults to 0, 8 or 16 depending on the range
+     values in X.
+
+     *See also:* *note mu2lin: doc-mu2lin, *note loadaudio:
+     doc-loadaudio, *note saveaudio: doc-saveaudio, *note playaudio:
+     doc-playaudio, *note setaudio: doc-setaudio, *note record:
+     doc-record.
+
+ -- Function File:  mu2lin (X, BPS)
+     Converts audio data from linear to mu-law.  Mu-law values are 8-bit
+     unsigned integers.  Linear values use N-bit signed integers or
+     floating point values in the range -1<=y<=1 if N is 0.  If N is
+     not specified it defaults to 8.
+
+     *See also:* *note lin2mu: doc-lin2mu, *note loadaudio:
+     doc-loadaudio, *note saveaudio: doc-saveaudio, *note playaudio:
+     doc-playaudio, *note setaudio: doc-setaudio, *note record:
+     doc-record.
+
+ -- Function File:  loadaudio (NAME, EXT, BPS)
+     Loads audio data from the file `NAME.EXT' into the vector X.
+
+     The extension EXT determines how the data in the audio file is
+     interpreted;  the extensions `lin' (default) and `raw' correspond
+     to linear, the extensions `au', `mu', or `snd' to mu-law encoding.
+
+     The argument BPS can be either 8 (default) or 16, and specifies
+     the number of bits per sample used in the audio file.
+
+     *See also:* *note lin2mu: doc-lin2mu, *note mu2lin: doc-mu2lin,
+     *note saveaudio: doc-saveaudio, *note playaudio: doc-playaudio,
+     *note setaudio: doc-setaudio, *note record: doc-record.
+
+ -- Function File:  saveaudio (NAME, X, EXT, BPS)
+     Saves a vector X of audio data to the file `NAME.EXT'.  The
+     optional parameters EXT and BPS determine the encoding and the
+     number of bits per sample used in the audio file (see
+     `loadaudio');  defaults are `lin' and 8, respectively.
+
+     *See also:* *note lin2mu: doc-lin2mu, *note mu2lin: doc-mu2lin,
+     *note loadaudio: doc-loadaudio, *note playaudio: doc-playaudio,
+     *note setaudio: doc-setaudio, *note record: doc-record.
+
+   The following functions for audio I/O require special A/D hardware
+and operating system support.  It is assumed that audio data in linear
+encoding can be played and recorded by reading from and writing to
+`/dev/dsp', and that similarly `/dev/audio' is used for mu-law
+encoding.  These file names are system-dependent.  Improvements so that
+these functions will work without modification on a wide variety of
+hardware are welcome.
+
+ -- Function File:  playaudio (NAME, EXT)
+ -- Function File:  playaudio (X)
+     Plays the audio file `NAME.EXT' or the audio data stored in the
+     vector X.
+
+     *See also:* *note lin2mu: doc-lin2mu, *note mu2lin: doc-mu2lin,
+     *note loadaudio: doc-loadaudio, *note saveaudio: doc-saveaudio,
+     *note setaudio: doc-setaudio, *note record: doc-record.
+
+ -- Function File:  record (SEC, SAMPLING_RATE)
+     Records SEC seconds of audio input into the vector X.  The default
+     value for SAMPLING_RATE is 8000 samples per second, or 8kHz.  The
+     program waits until the user types <RET> and then immediately
+     starts to record.
+
+     *See also:* *note lin2mu: doc-lin2mu, *note mu2lin: doc-mu2lin,
+     *note loadaudio: doc-loadaudio, *note saveaudio: doc-saveaudio,
+     *note playaudio: doc-playaudio, *note setaudio: doc-setaudio.
+
+ -- Function File:  setaudio ([W_TYPE [, VALUE]])
+     Execute the shell command `mixer [W_TYPE [, VALUE]]'
+
+ -- Function File: Y = wavread (FILENAME)
+     Load the RIFF/WAVE sound file FILENAME, and return the samples in
+     vector Y.  If the file contains multichannel data, then Y is a
+     matrix with the channels represented as columns.
+
+ -- Function File: [Y, FS, BITS] = wavread (FILENAME)
+     Additionally return the sample rate (FS) in Hz and the number of
+     bits per sample (BITS).
+
+ -- Function File: [...] = wavread (FILENAME, N)
+     Read only the first N samples from each channel.
+
+ -- Function File: [...] = wavread (FILENAME,[N1 N2])
+     Read only samples N1 through N2 from each channel.
+
+ -- Function File: [SAMPLES, CHANNELS] = wavread (FILENAME, "size")
+     Return the number of samples (N) and channels (CH) instead of the
+     audio data.
+
+     *See also:* *note wavwrite: doc-wavwrite.
+
+ -- Function File:  wavwrite (Y, FILENAME)
+ -- Function File:  wavwrite (Y, FS, FILENAME)
+ -- Function File:  wavwrite (Y, FS, BITS, FILENAME)
+     Write Y to the canonical RIFF/WAVE sound file FILENAME with sample
+     rate FS and bits per sample BITS.  The default sample rate is 8000
+     Hz with 16-bits per sample.  Each column of the data represents a
+     separate channel.
+
+     *See also:* *note wavread: doc-wavread.
+
+
+File: octave.info,  Node: Object Oriented Programming,  Next: System Utilities,  Prev: Audio Processing,  Up: Top
+
+33 Object Oriented Programming
+******************************
+
+Octave includes the capability to include user classes, including the
+features of operator and function overloading.  Equally a user class
+can be used to encapsulate certain properties of the class so that they
+cannot be altered accidentally and can be set up to address the issue
+of class precedence in mixed class operations.
+
+   This chapter discussions the means of constructing a user class with
+the example of a polynomial class, how to query and set the properties
+of this class, together with the means to overload operators and
+functions.
+
+* Menu:
+
+* Creating a Class::
+* Manipulating Classes::
+* Indexing Objects::
+* Overloading Objects::
+* Inheritance and Aggregation::
+
+
+File: octave.info,  Node: Creating a Class,  Next: Manipulating Classes,  Up: Object Oriented Programming
+
+33.1 Creating a Class
+=====================
+
+We use in the following text a polynomial class to demonstrate the use
+of object oriented programming within Octave.  This class was chosen as
+it is simple, and so doesn't distract unnecessarily from the discussion
+of the programming features of Octave.  However, even still a small
+understand of the polynomial class itself is necessary to fully grasp
+the techniques described.
+
+   The polynomial class is used to represent polynomials of the form
+
+     a0 + a1 * x + a2 * x^2 + ... + an * x^n
+
+where a0, a1, etc. are real scalars.  Thus the polynomial can be
+represented by a vector
+
+     a = [a0, a1, a2, ..., an];
+
+   We therefore now have sufficient information about the requirements
+of the class constructor for our polynomial class to write it.  All
+object oriented classes in Octave, must be contained with a directory
+taking the name of the class, prepended with the @ symbol.  For
+example, with our polynomial class, we would place the methods defining
+the class in the @polynomial directory.
+
+   The constructor of the class, must have the name of the class itself
+and so in our example the constructor with have the name
+`@polynomial/polynomial.m'.  Also ideally when the constructor is
+called with no arguments to should return a value object.  So for
+example our polynomial might look like
+
+     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} polynomial ()
+     ## @deftypefnx {Function File} {} polynomial (@var{a})
+     ## Creates a polynomial object representing the polynomial
+     ##
+     ## @example
+     ## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+     ## @end example
+     ##
+     ## from a vector of coefficients [a0 a1 a2 ... an].
+     ## @end deftypefn
+
+     function p = polynomial (a)
+       if (nargin == 0)
+         p.poly = [0];
+         p = class (p, "polynomial");
+       elseif (nargin == 1)
+         if (strcmp (class (a), "polynomial"))
+           p = a;
+         elseif (isvector (a) && isreal (a))
+           p.poly = a(:).';
+           p = class (p, "polynomial");
+         else
+           error ("polynomial: expecting real vector");
+         endif
+       else
+         print_usage ();
+       endif
+     endfunction
+
+   Note that the return value of the constructor must be the output of
+the `class' function called with the first argument being a structure
+and the second argument being the class name.  An example of the call
+to this constructor function is then
+
+     p = polynomial ([1, 0, 1]);
+
+   Note that methods of a class can be documented.  The help for the
+constructor itself can be obtained with the constructor name, that is
+for the polynomial constructor `help polynomial' will return the help
+string.  Also the help can be obtained by restricting the search for
+the help to a particular class, for example `help
+ at polynomial/polynomial'.  This second method is the only means of
+getting help for the overloaded methods and functions of the class.
+
+   The same is true for other Octave functions that take a function name
+as an argument.  For example `type @polynomial/display' will print the
+code of the display method of the polynomial class to the screen, and
+`dbstop @polynomial/display' will set a breakpoint at the first
+executable line of the display method of the polynomial class.
+
+   To check where a variable is a user class, the `isobject' and `isa'
+functions can be used. for example
+
+     p = polynomial ([1, 0, 1]);
+     isobject (p)
+     => 1
+     isa (p, "polynomial")
+     => 1
+
+ -- Built-in Function:  isobject (X)
+     Return true if X is a class object.
+
+The available methods of a class can be displayed with the `methods'
+function.
+
+ -- Built-in Function:  methods (X)
+ -- Built-in Function:  methods ("classname")
+     Return a cell array containing the names of the methods for the
+     object X or the named class.
+
+To inquire whether a particular method is available to a user class, the
+`ismethod' function can be used.
+
+ -- Built-in Function:  ismethod (X, METHOD)
+     Return true if X is a class object and the string METHOD is a
+     method of this class.
+
+For example
+
+     p = polynomial ([1, 0, 1]);
+     ismethod (p, "roots")
+     => 1
+
+
+File: octave.info,  Node: Manipulating Classes,  Next: Indexing Objects,  Prev: Creating a Class,  Up: Object Oriented Programming
+
+33.2 Manipulating Classes
+=========================
+
+There are a number of basic classes methods that can be defined to allow
+the contents of the classes to be queried and set.  The most basic of
+these is the `display' method.  The `display' method is used by Octave
+when displaying a class on the screen, due to an expression that is not
+terminated with a semicolon.  If this method is not defined, then
+Octave will printed nothing when displaying the contents of a class.
+
+ -- Function File:  display (A)
+     Display the contents of an object.  If A is an object of the class
+     "myclass", then `display' is called in a case like
+
+          myclass (...)
+
+     where Octave is required to display the contents of a variable of
+     the type "myclass".
+
+     *See also:* *note class: doc-class, *note subsref: doc-subsref,
+     *note subsasgn: doc-subsasgn.
+
+An example of a display method for the polynomial class might be
+
+     function display (p)
+       a = p.poly;
+       first = true;
+       fprintf("%s =", inputname(1));
+       for i = 1 : length (a);
+         if (a(i) != 0)
+           if (first)
+             first = false;
+           elseif (a(i) > 0)
+             fprintf (" +");
+           endif
+           if (a(i) < 0)
+             fprintf (" -");
+           endif
+           if (i == 1)
+             fprintf (" %g", abs (a(i)));
+           elseif (abs(a(i)) != 1)
+             fprintf (" %g *", abs (a(i)));
+           endif
+           if (i > 1)
+             fprintf (" X");
+           endif
+           if (i > 2)
+             fprintf (" ^ %d", i - 1);
+           endif
+         endif
+       endfor
+       if (first)
+         fprintf(" 0");
+       endif
+       fprintf("\n");
+     endfunction
+
+Note that in the display method, it makes sense to start the method
+with the line `fprintf("%s =", inputname(1))' to be consistent with the
+rest of Octave and print the variable name to be displayed when
+displaying the class.
+
+   To be consistent with the Octave graphic handle classes, a class
+should also define the `get' and `set' methods.  The `get' method
+should accept one or two arguments, and given one argument of the
+appropriate class it should return a structure with all of the
+properties of the class.  For example
+
+     function s = get (p, f)
+       if (nargin == 1)
+         s.poly = p.poly;
+       elseif (nargin == 2)
+         if (ischar (f))
+           switch (f)
+             case "poly"
+               s = p.poly;
+             otherwise
+               error ("get: invalid property %s", f);
+           endswitch
+         else
+           error ("get: expecting the property to be a string");
+         endif
+       else
+         print_usage ();
+       endif
+     endfunction
+
+Similarly, the `set' method should taken as its first argument an
+object to modify, and then take property/value pairs to be modified.
+
+     function s = set (p, varargin)
+       s = p;
+       if (length (varargin) < 2 || rem (length (varargin), 2) != 0)
+         error ("set: expecting property/value pairs");
+       endif
+       while (length (varargin) > 1)
+         prop = varargin{1};
+         val = varargin{2};
+         varargin(1:2) = [];
+         if (ischar (prop) && strcmp (prop, "poly"))
+           if (isvector (val) && isreal (val))
+             s.poly = val(:).';
+           else
+             error ("set: expecting the value to be a real vector");
+           endif
+         else
+           error ("set: invalid property of polynomial class");
+         endif
+       endwhile
+     endfunction
+
+Note that as Octave does not implement pass by reference, than the
+modified object is the return value of the `set' method and it must be
+called like
+
+     p = set (p, "a", [1, 0, 0, 0, 1]);
+
+Also the `set' method makes use of the `subsasgn' method of the class,
+and this method must be defined.  The `subsasgn' method is discussed in
+the next section.
+
+   Finally, user classes can be considered as a special type of a
+structure, and so they can be saved to a file in the same manner as a
+structure.  For example
+
+     p = polynomial ([1, 0, 1]);
+     save userclass.mat p
+     clear p
+     load userclass.mat
+
+All of the file formats supported by `save' and `load' are supported.
+In certain circumstances, a user class might either contain a field
+that it makes no sense to save or a field that needs to be initialized
+before it is saved.  This can be done with the `saveobj' method of the
+class
+
+ -- Function File: B = saveobj (A)
+     Method of a class to manipulate an object prior to saving it to a
+     file.  The function `saveobj' is called when the object A is saved
+     using the `save' function.  An example of the use of `saveobj'
+     might be to remove fields of the object that don't make sense to
+     be saved or it might be used to ensure that certain fields of the
+     object are initialized before the object is saved.  For example
+
+          function b = saveobj (a)
+            b = a;
+            if (isempty (b.field))
+               b.field = initfield(b);
+            endif
+          endfunction
+
+     *See also:* *note loadobj: doc-loadobj, *note class: doc-class.
+
+`saveobj' is called just prior to saving the class to a file.  Likely,
+the `loadobj' method is called just after a class is loaded from a
+file, and can be used to ensure that any removed fields are reinserted
+into the user object.
+
+ -- Function File: B = loadobj (A)
+     Method of a class to manipulate an object after loading it from a
+     file.  The function `loadobj' is called when the object A is loaded
+     using the `load' function.  An example of the use of `saveobj'
+     might be to add fields to an object that don't make sense to be
+     saved.  For example
+
+          function b = loadobj (a)
+            b = a;
+            b.addmissingfield = addfield (b);
+          endfunction
+
+     *See also:* *note saveobj: doc-saveobj, *note class: doc-class.
+
+
+File: octave.info,  Node: Indexing Objects,  Next: Overloading Objects,  Prev: Manipulating Classes,  Up: Object Oriented Programming
+
+33.3 Indexing Objects
+=====================
+
+Objects can be indexed with parentheses, either like `A (IDX)' or like
+`A {IDX}', or even like `A (IDX).FIELD'.  However, it is up to the user
+to decide what this indexing actually means.  In the case of our
+polynomial class `P (N)' might mean either the coefficient of the N-th
+power of the polynomial, or it might be the evaluation of the
+polynomial at N.  The meaning of this subscripted referencing is
+determined by the `subsref' method.
+
+ -- Built-in Function:  subsref (VAL, IDX)
+     Perform the subscripted element selection operation according to
+     the subscript specified by IDX.
+
+     The subscript IDX is expected to be a structure array with fields
+     `type' and `subs'.  Valid values for `type' are `"()"', `"{}"',
+     and `"."'.  The `subs' field may be either `":"' or a cell array
+     of index values.
+
+     The following example shows how to extract the two first columns of
+     a matrix
+
+          val = magic(3)
+               => val = [ 8   1   6
+                          3   5   7
+                          4   9   2 ]
+          idx.type = "()";
+          idx.subs = {":", 1:2};
+          subsref(val, idx)
+               => [ 8   1
+                    3   5
+                    4   9 ]
+
+     Note that this is the same as writing `val(:,1:2)'.
+
+     *See also:* *note subsasgn: doc-subsasgn, *note substruct:
+     doc-substruct.
+
+   For example we might decide that indexing with "()" evaluates the
+polynomial and indexing with "{}" returns the N-th coefficient (of N-th
+power).  In this case the `subsref' method of our polynomial class
+might look like
+
+     function b = subsref (a, s)
+       if (isempty (s))
+         error ("polynomial: missing index");
+       endif
+       switch (s(1).type)
+         case "()"
+           ind = s(1).subs;
+           if (numel (ind) != 1)
+             error ("polynomial: need exactly one index");
+           else
+             b = polyval (fliplr (a.poly), ind{1});
+           endif
+         case "{}"
+           ind = s(1).subs;
+           if (numel (ind) != 1)
+             error ("polynomial: need exactly one index");
+           else
+             if (isnumeric (ind{1}))
+               b = a.poly(ind{1}+1);
+             else
+               b = a.poly(ind{1});
+             endif
+           endif
+         case "."
+           fld = s.subs;
+           if (strcmp (fld, "poly"))
+             b = a.poly;
+           else
+             error ("@polynomial/subsref: invalid property \"%s\"", fld);
+           endif
+         otherwise
+           error ("invalid subscript type");
+       endswitch
+       if (numel (s) > 1)
+         b = subsref (b, s(2:end));
+       endif
+     endfunction
+
+   The equivalent functionality for subscripted assignments uses the
+`subsasgn' method.
+
+ -- Built-in Function:  subsasgn (VAL, IDX, RHS)
+     Perform the subscripted assignment operation according to the
+     subscript specified by IDX.
+
+     The subscript IDX is expected to be a structure array with fields
+     `type' and `subs'.  Valid values for `type' are `"()"', `"{}"',
+     and `"."'.  The `subs' field may be either `":"' or a cell array
+     of index values.
+
+     The following example shows how to set the two first columns of a
+     3-by-3 matrix to zero.
+
+          val = magic(3);
+          idx.type = "()";
+          idx.subs = {":", 1:2};
+          subsasgn (val, idx, 0)
+               => [ 0   0   6
+                    0   0   7
+                    0   0   2 ]
+
+     Note that this is the same as writing `val(:,1:2) = 0'.
+
+     *See also:* *note subsref: doc-subsref, *note substruct:
+     doc-substruct.
+
+   Note that the `subsref' and `subsasgn' methods always receive the
+whole index chain, while they usually handle only the first element.
+It is the responsibility of these methods to handle the rest of the
+chain (if needed), usually by forwarding it again to `subsref' or
+`subsasgn'.
+
+   If you wish to use the `end' keyword in subscripted expressions of
+an object, then the user needs to define the `end' method for the class.
+
+   For example the `end' method for our polynomial class might look like
+
+     function r = end (obj, index_pos, num_indices)
+
+       if (num_indices != 1)
+         error ("polynomial object may only have one index")
+       endif
+
+       r = length (obj.poly) - 1;
+
+     endfunction
+
+which is a fairly generic `end' method that has a behavior similar to
+the `end' keyword for Octave Array classes.  It can then be used for
+example like
+
+     p = polynomial([1,2,3,4]);
+     p(end-1)
+     => 3
+
+   Objects can also be used as the index in a subscripted expression
+themselves and this is controlled with the `subsindex' function.
+
+ -- Function File: IDX = subsindex (A)
+     Convert an object to an index vector.  When A is a class object
+     defined with a class constructor, then `subsindex' is the
+     overloading method that allows the conversion of this class object
+     to a valid indexing vector.  It is important to note that
+     `subsindex' must return a zero-based real integer vector of the
+     class "double".  For example, if the class constructor
+
+          function b = myclass (a)
+           b = myclass (struct ("a", a), "myclass");
+          endfunction
+
+     then the `subsindex' function
+
+          function idx = subsindex (a)
+           idx = double (a.a) - 1.0;
+          endfunction
+
+     can then be used as follows
+
+          a = myclass (1:4);
+          b = 1:10;
+          b(a)
+          => 1  2  3  4
+
+     *See also:* *note class: doc-class, *note subsref: doc-subsref,
+     *note subsasgn: doc-subsasgn.
+
+   Finally, objects can equally be used like ranges, using the `colon'
+method
+
+ -- Function File: R = colon (A, B)
+ -- Function File: R = colon (A, B, C)
+     Method of a class to construct a range with the `:' operator.  For
+     example.
+
+          a = myclass (...)
+          b = myclass (...)
+          c = a : b
+
+     *See also:* *note class: doc-class, *note subsref: doc-subsref,
+     *note subsasgn: doc-subsasgn.
+
+
+File: octave.info,  Node: Overloading Objects,  Next: Inheritance and Aggregation,  Prev: Indexing Objects,  Up: Object Oriented Programming
+
+33.4 Overloading Objects
+========================
+
+* Menu:
+
+* Function Overloading::
+* Operator Overloading::
+* Precedence of Objects::
+
+
+File: octave.info,  Node: Function Overloading,  Next: Operator Overloading,  Up: Overloading Objects
+
+33.4.1 Function Overloading
+---------------------------
+
+Any Octave function can be overloaded, and allows a object specific
+version of this function to be called as needed.  A pertinent example
+for our polynomial class might be to overload the `polyval' function
+like
+
+     function [y, dy] = polyval (p, varargin)
+       if (nargout == 2)
+         [y, dy] = polyval (fliplr(p.poly), varargin{:});
+       else
+         y = polyval (fliplr(p.poly), varargin{:});
+       endif
+     endfunction
+
+   This function just hands off the work to the normal Octave `polyval'
+function.  Another interesting example for an overloaded function for
+our polynomial class is the `plot' function.
+
+     function h = plot(p, varargin)
+       n = 128;
+       rmax = max (abs (roots (p.poly)));
+       x = [0 : (n - 1)] / (n - 1) * 2.2 * rmax - 1.1 * rmax;
+       if (nargout > 0)
+         h = plot(x, p(x), varargin{:});
+       else
+         plot(x, p(x), varargin{:});
+       endif
+     endfunction
+
+which allows polynomials to be plotted in the domain near the region of
+the roots of the polynomial.
+
+   Functions that are of particular interest to be overloaded are the
+class conversion functions such as `double'.  Overloading these
+functions allows the `cast' function to work with the user class and
+can aid in the use of methods of other classes with the user class.  An
+example `double' function for our polynomial class might look like.
+
+     function b = double (a)
+       b = a.poly;
+     endfunction
+
+
+File: octave.info,  Node: Operator Overloading,  Next: Precedence of Objects,  Prev: Function Overloading,  Up: Overloading Objects
+
+33.4.2 Operator Overloading
+---------------------------
+
+        Operation      Method         Description                   
+        a + b          plus (a, b)    Binary addition               
+        a - b$         minus (a, b)   Binary subtraction operator   
+        + a$           uplus (a)      Unary addition operator       
+        - a$           uminus (a)     Unary subtraction operator    
+        a .* b$        times (a, b)   Element-wise multiplication   
+                                      operator                      
+        a * b$         mtimes (a, b)  Matrix multiplication         
+                                      operator                      
+        a ./ b$        rdivide (a,    Element-wise right division   
+                       b)             operator                      
+        a / b$         mrdivide (a,   Matrix right division         
+                       b)             operator                      
+        a .\ b$        ldivide (a,    Element-wise left division    
+                       b)             operator                      
+        a \ b$         mldivide (a,   Matrix left division          
+                       b)             operator                      
+        a .^ b$        ldivide (a,    Element-wise power operator   
+                       b)                                           
+        a ^ b$         mldivide (a,   Matrix power operator         
+                       b)                                           
+        a < b$         lt (a, b)      Less than operator            
+        a <= b$        le (a, b)      Less than or equal to         
+                                      operator                      
+        a > b$         gt (a, b)      Greater than operator         
+        a >= b$        ge (a, b)      Greater than or equal to      
+                                      operator                      
+        a == b$        eq (a, b)      Equal to operator             
+        a != b$        ne (a, b)      Not equal to operator         
+        a \& b$        and (a, b)     Logical and operator          
+        a | b$         or (a, b)      Logical or operator           
+        ! b$           not (a)        Logical not operator          
+        a'$            ctranspose     Complex conjugate transpose   
+                       (a)            operator                      
+        a.'$           transpose (a)  Transpose operator            
+        a : b$         colon (a, b)   Two element range operator    
+        a : b : c$     colon (a, b,   Three element range operator  
+                       c)                                           
+        [a, b]$        horzcat (a,    Horizontal concatenation      
+                       b)             operator                      
+        [a; b]$        vertcat (a,    Vertical concatenation        
+                       b)             operator                      
+        a(s_1,         subsref (a,    Subscripted reference         
+        \ldots, s_n)$  s)                                           
+        a(s_1,         subsasgn (a,   Subscripted assignment        
+        \ldots, s_n)   s, b)                                        
+        = b$                                                        
+        b (a)$         subsindex (a)  Convert to zero-based index   
+        "display"      display (a)    Commandline display function  
+
+Table 33.1: Available overloaded operators and their corresponding
+class method
+
+   An example `mtimes' method for our polynomial class might look like
+
+     function y = mtimes (a, b)
+       y = polynomial (conv (double(a),double(b)));
+     endfunction
+
+
+File: octave.info,  Node: Precedence of Objects,  Prev: Operator Overloading,  Up: Overloading Objects
+
+33.4.3 Precedence of Objects
+----------------------------
+
+Many functions and operators take two or more arguments and so the case
+can easily arise that these functions are called with objects of
+different classes.  It is therefore necessary to determine the
+precedence of which method of which class to call when there are mixed
+objects given to a function or operator.  To do this the `superiorto'
+and `inferiorto' functions can be used
+
+ -- Built-in Function:  superiorto (CLASS_NAME, ...)
+     When called from a class constructor, mark the object currently
+     constructed as having a higher precedence than CLASS_NAME.  More
+     that one such class can be specified in a single call.  This
+     function may only be called from a class constructor.
+
+ -- Built-in Function:  inferiorto (CLASS_NAME, ...)
+     When called from a class constructor, mark the object currently
+     constructed as having a lower precedence than CLASS_NAME.  More
+     that one such class can be specified in a single call.  This
+     function may only be called from a class constructor.
+
+   For example with our polynomial class consider the case
+
+     2 * polynomial ([1, 0, 1]);
+
+That mixes an object of the class "double" with an object of the class
+"polynomial".  In this case we like to ensure that the return type of
+the above is of the type "polynomial" and so we use the `superiorto'
+function in the class constructor.  In particular our polynomial class
+constructor would be modified to be
+
+     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} polynomial ()
+     ## @deftypefnx {Function File} {} polynomial (@var{a})
+     ## Creates a polynomial object representing the polynomial
+     ##
+     ## @example
+     ## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+     ## @end example
+     ##
+     ## from a vector of coefficients [a0 a1 a2 ... an].
+     ## @end deftypefn
+
+     function p = polynomial (a)
+       if (nargin == 0)
+         p.poly = [0];
+         p = class (p, "polynomial");
+       elseif (nargin == 1)
+         if (strcmp (class (a), "polynomial"))
+           p = a;
+         elseif (isvector (a) && isreal (a))
+           p.poly = a(:).';
+           p = class (p, "polynomial");
+         else
+           error ("polynomial: expecting real vector");
+         endif
+       else
+         print_usage ();
+       endif
+       superiorto ("double");
+     endfunction
+
+   Note that user classes always have higher precedence than built-in
+Octave types.  So in fact marking our polynomial class higher than the
+"double" class is in fact not necessary.
+
+
+File: octave.info,  Node: Inheritance and Aggregation,  Prev: Overloading Objects,  Up: Object Oriented Programming
+
+33.5 Inheritance and Aggregation
+================================
+
+Using classes to build new classes is supported by octave through the
+use of both inheritance and aggregation.
+
+   Class inheritance is provided by octave using the `class' function
+in the class constructor.  As in the case of the polynomial class, the
+octave programmer will create a struct that contains the data fields
+required by the class, and then call the class function to indicate
+that an object is to be created from the struct.  Creating a child of
+an existing object is done by creating an object of the parent class
+and providing that object as the third argument of the class function.
+
+   This is easily demonstrated by example.  Suppose the programmer needs
+an FIR filter, i.e. a filter with a numerator polynomial but a unity
+denominator polynomial.  In traditional octave programming, this would
+be performed as follows.
+
+     octave:1> x = [some data vector];
+     octave:2> n = [some coefficient vector];
+     octave:3> y = filter (n, 1, x);
+
+   The equivalent class could be implemented in a class directory
+ at FIRfilter that is on the octave path.  The constructor is a file
+FIRfilter.m in the class directory.
+
+     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} FIRfilter ()
+     ## @deftypefnx {Function File} {} FIRfilter (@var{p})
+     ## Creates an FIR filter with polynomial @var{p} as
+     ## coefficient vector.
+     ##
+     ## @end deftypefn
+
+     function f = FIRfilter (p)
+
+       f.polynomial = [];
+       if (nargin == 0)
+         p = @polynomial ([1]);
+       elseif (nargin == 1)
+         if (!isa (p, "polynomial"))
+           error ("FIRfilter: expecting polynomial as input argument");
+         endif
+       else
+         print_usage ();
+       endif
+       f = class (f, "FIRfilter", p);
+     endfunction
+
+   As before, the leading comments provide command-line documentation
+for the class constructor.  This constructor is very similar to the
+polynomial class constructor, except that we pass a polynomial object
+as the third argument to the class function, telling octave that the
+FIRfilter class will be derived from the polynomial class.  Our FIR
+filter does not have any data fields, but we must provide a struct to
+the `class' function.  The `class' function will add an element named
+polynomial to the object struct, so we simply add a dummy element named
+polynomial as the first line of the constructor.  This dummy element
+will be overwritten by the class function.
+
+   Note further that all our examples provide for the case in which no
+arguments are supplied.  This is important since octave will call the
+constructor with no arguments when loading ojects from save files to
+determine the inheritance structure.
+
+   A class may be a child of more than one class (see the documentation
+for the `class' function), and inheritance may be nested.  There is no
+limitation to the number of parents or the level of nesting other than
+memory or other physical issues.
+
+   As before, we need a `display' method.  A simple example might be
+
+     function display (f)
+
+       display(f.polynomial);
+
+     endfunction
+
+   Note that we have used the polynomial field of the struct to display
+the filter coefficients.
+
+   Once we have the class constructor and display method, we may create
+an object by calling the class constructor.  We may also check the
+class type and examine the underlying structure.
+
+     octave:1> f=FIRfilter(polynomial([1 1 1]/3))
+     f.polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+     octave:2> class(f)
+     ans = FIRfilter
+     octave:3> isa(f,"FIRfilter")
+     ans =  1
+     octave:4> isa(f,"polynomial")
+     ans =  1
+     octave:5> struct(f)
+     ans =
+     {
+     polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+     }
+
+   We only need to define a method to actually process data with our
+filter and our class is usable.  It is also useful to provide a means
+of changing the data stored in the class.  Since the fields in the
+underlying struct are private by default, we could provide a mechanism
+to access the fields.  The `subsref' method may be used for both.
+
+     function out = subsref (f, x)
+       switch x.type
+         case "()"
+           n = f.polynomial;
+           out = filter(n.poly, 1, x.subs{1});
+         case "."
+           fld = x.subs;
+           if (strcmp (fld, "polynomial"))
+             out = f.polynomial;
+           else
+             error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+           endif
+         otherwise
+           error ("@FIRfilter/subsref: invalid subscript type for FIR filter");
+       endswitch
+     endfunction
+
+   The "()" case allows us to filter data using the polynomial provided
+to the constructor.
+
+     octave:2> f=FIRfilter(polynomial([1 1 1]/3));
+     octave:3> x=ones(5,1);
+     octave:4> y=f(x)
+     y =
+
+        0.33333
+        0.66667
+        1.00000
+        1.00000
+        1.00000
+
+   The "." case allows us to view the contents of the polynomial field.
+
+     octave:1> f=FIRfilter(polynomial([1 1 1]/3));
+     octave:2> f.polynomial
+     ans = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+
+   In order to change the contents of the object, we need to define a
+`subsasgn' method.  For example, we may make the polynomial field
+publicly writeable.
+
+     function out = subsasgn (f, index, val)
+       switch (index.type)
+         case "."
+           fld = index.subs;
+           if (strcmp (fld, "polynomial"))
+             out = f;
+             out.polynomial = val;
+           else
+             error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+           endif
+         otherwise
+           error ("FIRfilter/subsagn: Invalid index type")
+       endswitch
+     endfunction
+
+   So that
+
+     octave:6> f=FIRfilter();
+     octave:7> f.polynomial = polynomial([1 2 3]);
+     f.polynomial = 1 + 2 * X + 3 * X ^ 2
+
+   Defining the FIRfilter class as a child of the polynomial class
+implies that and FIRfilter object may be used any place that a
+polynomial may be used.  This is not a normal use of a filter, so that
+aggregation may be a more sensible design approach.  In this case, the
+polynomial is simply a field in the class structure.  A class
+constructor for this case might be
+
+     ## -*- texinfo -*-
+     ## @deftypefn {Function File} {} FIRfilter ()
+     ## @deftypefnx {Function File} {} FIRfilter (@var{p})
+     ## Creates an FIR filter with polynomial @var{p} as
+     ## coefficient vector.
+     ##
+     ## @end deftypefn
+
+     function f = FIRfilter (p)
+
+       if (nargin == 0)
+         f.polynomial = @polynomial ([1]);
+       elseif (nargin == 1)
+         if (isa (p, "polynomial"))
+           f.polynomial = p;
+         else
+           error ("FIRfilter: expecting polynomial as input argument");
+         endif
+       else
+         print_usage ();
+       endif
+       f = class (f, "FIRfilter");
+     endfunction
+
+   For our example, the remaining class methods remain unchanged.
+
+
+File: octave.info,  Node: System Utilities,  Next: Packages,  Prev: Object Oriented Programming,  Up: Top
+
+34 System Utilities
+*******************
+
+This chapter describes the functions that are available to allow you to
+get information about what is happening outside of Octave, while it is
+still running, and use this information in your program.  For example,
+you can get information about environment variables, the current time,
+and even start other programs from the Octave prompt.
+
+* Menu:
+
+* Timing Utilities::
+* Filesystem Utilities::
+* File Archiving Utilities::
+* Networking Utilities::
+* Controlling Subprocesses::
+* Process ID Information::
+* Environment Variables::
+* Current Working Directory::
+* Password Database Functions::
+* Group Database Functions::
+* System Information::
+* Hashing Functions::
+
+
+File: octave.info,  Node: Timing Utilities,  Next: Filesystem Utilities,  Up: System Utilities
+
+34.1 Timing Utilities
+=====================
+
+Octave's core set of functions for manipulating time values are
+patterned after the corresponding functions from the standard C library.
+Several of these functions use a data structure for time that includes
+the following elements:
+
+`usec'
+     Microseconds after the second (0-999999).
+
+`sec'
+     Seconds after the minute (0-61).  This number can be 61 to account
+     for leap seconds.
+
+`min'
+     Minutes after the hour (0-59).
+
+`hour'
+     Hours since midnight (0-23).
+
+`mday'
+     Day of the month (1-31).
+
+`mon'
+     Months since January (0-11).
+
+`year'
+     Years since 1900.
+
+`wday'
+     Days since Sunday (0-6).
+
+`yday'
+     Days since January 1 (0-365).
+
+`isdst'
+     Daylight Savings Time flag.
+
+`zone'
+     Time zone.
+
+In the descriptions of the following functions, this structure is
+referred to as a TM_STRUCT.
+
+ -- Loadable Function:  time ()
+     Return the current time as the number of seconds since the epoch.
+     The epoch is referenced to 00:00:00 CUT (Coordinated Universal
+     Time) 1 Jan 1970.  For example, on Monday February 17, 1997 at
+     07:15:06 CUT, the value returned by `time' was 856163706.
+
+     *See also:* *note strftime: doc-strftime, *note strptime:
+     doc-strptime, *note localtime: doc-localtime, *note gmtime:
+     doc-gmtime, *note mktime: doc-mktime, *note now: doc-now, *note
+     date: doc-date, *note clock: doc-clock, *note datenum:
+     doc-datenum, *note datestr: doc-datestr, *note datevec:
+     doc-datevec, *note calendar: doc-calendar, *note weekday:
+     doc-weekday.
+
+ -- Function File: t = now ()
+     Returns the current local time as the number of days since Jan 1,
+     0000.  By this reckoning, Jan 1, 1970 is day number 719529.
+
+     The integral part, `floor (now)' corresponds to 00:00:00 today.
+
+     The fractional part, `rem (now, 1)' corresponds to the current
+     time on Jan 1, 0000.
+
+     The returned value is also called a "serial date number" (see
+     `datenum').
+
+     *See also:* *note clock: doc-clock, *note date: doc-date, *note
+     datenum: doc-datenum.
+
+ -- Function File:  ctime (T)
+     Convert a value returned from `time' (or any other non-negative
+     integer), to the local time and return a string of the same form as
+     `asctime'.  The function `ctime (time)' is equivalent to `asctime
+     (localtime (time))'.  For example,
+
+          ctime (time ())
+               => "Mon Feb 17 01:15:06 1997\n"
+
+ -- Loadable Function:  gmtime (T)
+     Given a value returned from time (or any non-negative integer),
+     return a time structure corresponding to CUT.  For example,
+
+          gmtime (time ())
+               => {
+                     usec = 0
+                     year = 97
+                     mon = 1
+                     mday = 17
+                     sec = 6
+                     zone = CST
+                     min = 15
+                     wday = 1
+                     hour = 7
+                     isdst = 0
+                     yday = 47
+                   }
+
+     *See also:* *note strftime: doc-strftime, *note strptime:
+     doc-strptime, *note localtime: doc-localtime, *note mktime:
+     doc-mktime, *note time: doc-time, *note now: doc-now, *note date:
+     doc-date, *note clock: doc-clock, *note datenum: doc-datenum,
+     *note datestr: doc-datestr, *note datevec: doc-datevec, *note
+     calendar: doc-calendar, *note weekday: doc-weekday.
+
+ -- Loadable Function:  localtime (T)
+     Given a value returned from time (or any non-negative integer),
+     return a time structure corresponding to the local time zone.
+
+          localtime (time ())
+               => {
+                     usec = 0
+                     year = 97
+                     mon = 1
+                     mday = 17
+                     sec = 6
+                     zone = CST
+                     min = 15
+                     wday = 1
+                     hour = 1
+                     isdst = 0
+                     yday = 47
+                   }
+
+     *See also:* *note strftime: doc-strftime, *note strptime:
+     doc-strptime, *note gmtime: doc-gmtime, *note mktime: doc-mktime,
+     *note time: doc-time, *note now: doc-now, *note date: doc-date,
+     *note clock: doc-clock, *note datenum: doc-datenum, *note datestr:
+     doc-datestr, *note datevec: doc-datevec, *note calendar:
+     doc-calendar, *note weekday: doc-weekday.
+
+ -- Loadable Function:  mktime (TM_STRUCT)
+     Convert a time structure corresponding to the local time to the
+     number of seconds since the epoch.  For example,
+
+          mktime (localtime (time ()))
+               => 856163706
+
+     *See also:* *note strftime: doc-strftime, *note strptime:
+     doc-strptime, *note localtime: doc-localtime, *note gmtime:
+     doc-gmtime, *note time: doc-time, *note now: doc-now, *note date:
+     doc-date, *note clock: doc-clock, *note datenum: doc-datenum,
+     *note datestr: doc-datestr, *note datevec: doc-datevec, *note
+     calendar: doc-calendar, *note weekday: doc-weekday.
+
+ -- Function File:  asctime (TM_STRUCT)
+     Convert a time structure to a string using the following five-field
+     format: Thu Mar 28 08:40:14 1996.  For example,
+
+          asctime (localtime (time ()))
+               => "Mon Feb 17 01:15:06 1997\n"
+
+     This is equivalent to `ctime (time ())'.
+
+ -- Loadable Function:  strftime (FMT, TM_STRUCT)
+     Format the time structure TM_STRUCT in a flexible way using the
+     format string FMT that contains `%' substitutions similar to those
+     in `printf'.  Except where noted, substituted fields have a fixed
+     size; numeric fields are padded if necessary.  Padding is with
+     zeros by default; for fields that display a single number, padding
+     can be changed or inhibited by following the `%' with one of the
+     modifiers described below.  Unknown field specifiers are copied as
+     normal characters.  All other characters are copied to the output
+     without change.  For example,
+
+          strftime ("%r (%Z) %A %e %B %Y", localtime (time ()))
+               => "01:15:06 AM (CST) Monday 17 February 1997"
+
+     Octave's `strftime' function supports a superset of the ANSI C
+     field specifiers.
+
+     Literal character fields:
+
+    `%'
+          % character.
+
+    `n'
+          Newline character.
+
+    `t'
+          Tab character.
+
+     Numeric modifiers (a nonstandard extension):
+
+    `- (dash)'
+          Do not pad the field.
+
+    `_ (underscore)'
+          Pad the field with spaces.
+
+     Time fields:
+
+    `%H'
+          Hour (00-23).
+
+    `%I'
+          Hour (01-12).
+
+    `%k'
+          Hour (0-23).
+
+    `%l'
+          Hour (1-12).
+
+    `%M'
+          Minute (00-59).
+
+    `%p'
+          Locale's AM or PM.
+
+    `%r'
+          Time, 12-hour (hh:mm:ss [AP]M).
+
+    `%R'
+          Time, 24-hour (hh:mm).
+
+    `%s'
+          Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard
+          extension).
+
+    `%S'
+          Second (00-61).
+
+    `%T'
+          Time, 24-hour (hh:mm:ss).
+
+    `%X'
+          Locale's time representation (%H:%M:%S).
+
+    `%Z'
+          Time zone (EDT), or nothing if no time zone is determinable.
+
+     Date fields:
+
+    `%a'
+          Locale's abbreviated weekday name (Sun-Sat).
+
+    `%A'
+          Locale's full weekday name, variable length (Sunday-Saturday).
+
+    `%b'
+          Locale's abbreviated month name (Jan-Dec).
+
+    `%B'
+          Locale's full month name, variable length (January-December).
+
+    `%c'
+          Locale's date and time (Sat Nov 04 12:02:33 EST 1989).
+
+    `%C'
+          Century (00-99).
+
+    `%d'
+          Day of month (01-31).
+
+    `%e'
+          Day of month ( 1-31).
+
+    `%D'
+          Date (mm/dd/yy).
+
+    `%h'
+          Same as %b.
+
+    `%j'
+          Day of year (001-366).
+
+    `%m'
+          Month (01-12).
+
+    `%U'
+          Week number of year with Sunday as first day of week (00-53).
+
+    `%w'
+          Day of week (0-6).
+
+    `%W'
+          Week number of year with Monday as first day of week (00-53).
+
+    `%x'
+          Locale's date representation (mm/dd/yy).
+
+    `%y'
+          Last two digits of year (00-99).
+
+    `%Y'
+          Year (1970-).
+
+     *See also:* *note strptime: doc-strptime, *note localtime:
+     doc-localtime, *note gmtime: doc-gmtime, *note mktime: doc-mktime,
+     *note time: doc-time, *note now: doc-now, *note date: doc-date,
+     *note clock: doc-clock, *note datenum: doc-datenum, *note datestr:
+     doc-datestr, *note datevec: doc-datevec, *note calendar:
+     doc-calendar, *note weekday: doc-weekday.
+
+ -- Loadable Function: [TM_STRUCT, NCHARS] = strptime (STR, FMT)
+     Convert the string STR to the time structure TM_STRUCT under the
+     control of the format string FMT.
+
+     If FMT fails to match, NCHARS is 0; otherwise it is set to the
+     position of last matched character plus 1. Always check for this
+     unless you're absolutely sure the date string will be parsed
+     correctly.
+
+     *See also:* *note strftime: doc-strftime, *note localtime:
+     doc-localtime, *note gmtime: doc-gmtime, *note mktime: doc-mktime,
+     *note time: doc-time, *note now: doc-now, *note date: doc-date,
+     *note clock: doc-clock, *note datenum: doc-datenum, *note datestr:
+     doc-datestr, *note datevec: doc-datevec, *note calendar:
+     doc-calendar, *note weekday: doc-weekday.
+
+   Most of the remaining functions described in this section are not
+patterned after the standard C library.  Some are available for
+compatibility with MATLAB and others are provided because they are
+useful.
+
+ -- Function File:  clock ()
+     Return a vector containing the current year, month (1-12), day
+     (1-31), hour (0-23), minute (0-59) and second (0-61).  For example,
+
+          clock ()
+               => [ 1993, 8, 20, 4, 56, 1 ]
+
+     The function clock is more accurate on systems that have the
+     `gettimeofday' function.
+
+ -- Function File:  date ()
+     Return the date as a character string in the form DD-MMM-YY.  For
+     example,
+
+          date ()
+               => "20-Aug-93"
+
+ -- Function File:  etime (T1, T2)
+     Return the difference (in seconds) between two time values
+     returned from `clock'.  For example:
+
+          t0 = clock ();
+           many computations later...
+          elapsed_time = etime (clock (), t0);
+
+     will set the variable `elapsed_time' to the number of seconds since
+     the variable `t0' was set.
+
+     *See also:* *note tic: doc-tic, *note toc: doc-toc, *note clock:
+     doc-clock, *note cputime: doc-cputime.
+
+ -- Built-in Function: [TOTAL, USER, SYSTEM] = cputime ();
+     Return the CPU time used by your Octave session.  The first output
+     is the total time spent executing your process and is equal to the
+     sum of second and third outputs, which are the number of CPU
+     seconds spent executing in user mode and the number of CPU seconds
+     spent executing in system mode, respectively.  If your system does
+     not have a way to report CPU time usage, `cputime' returns 0 for
+     each of its output values.  Note that because Octave used some CPU
+     time to start, it is reasonable to check to see if `cputime' works
+     by checking to see if the total CPU time used is nonzero.
+
+ -- Function File:  is_leap_year (YEAR)
+     Return 1 if the given year is a leap year and 0 otherwise.  If no
+     arguments are provided, `is_leap_year' will use the current year.
+     For example,
+
+          is_leap_year (2000)
+               => 1
+
+ -- Built-in Function:  tic ()
+ -- Built-in Function:  toc ()
+     Set or check a wall-clock timer.  Calling `tic' without an output
+     argument sets the timer.  Subsequent calls to `toc' return the
+     number of seconds since the timer was set.  For example,
+
+          tic ();
+          # many computations later...
+          elapsed_time = toc ();
+
+     will set the variable `elapsed_time' to the number of seconds since
+     the most recent call to the function `tic'.
+
+     If called with one output argument then this function returns a
+     scalar of type `uint64' and the wall-clock timer is not started.
+
+          t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6
+               => 5
+
+     Nested timing with `tic' and `toc' is not supported.  Therefore
+     `toc' will always return the elapsed time from the most recent
+     call to `tic'.
+
+     If you are more interested in the CPU time that your process used,
+     you should use the `cputime' function instead.  The `tic' and
+     `toc' functions report the actual wall clock time that elapsed
+     between the calls.  This may include time spent processing other
+     jobs or doing nothing at all.  For example,
+
+          tic (); sleep (5); toc ()
+               => 5
+          t = cputime (); sleep (5); cputime () - t
+               => 0
+
+     (This example also illustrates that the CPU timer may have a fairly
+     coarse resolution.)
+
+ -- Built-in Function:  pause (SECONDS)
+     Suspend the execution of the program.  If invoked without any
+     arguments, Octave waits until you type a character.  With a
+     numeric argument, it pauses for the given number of seconds.  For
+     example, the following statement prints a message and then waits 5
+     seconds before clearing the screen.
+
+          fprintf (stderr, "wait please...\n");
+          pause (5);
+          clc;
+
+ -- Built-in Function:  sleep (SECONDS)
+     Suspend the execution of the program for the given number of
+     seconds.
+
+ -- Built-in Function:  usleep (MICROSECONDS)
+     Suspend the execution of the program for the given number of
+     microseconds.  On systems where it is not possible to sleep for
+     periods of time less than one second, `usleep' will pause the
+     execution for `round (MICROSECONDS / 1e6)' seconds.
+
+ -- Function File:  datenum (YEAR, MONTH, DAY)
+ -- Function File:  datenum (YEAR, MONTH, DAY, HOUR)
+ -- Function File:  datenum (YEAR, MONTH, DAY, HOUR, MINUTE)
+ -- Function File:  datenum (YEAR, MONTH, DAY, HOUR, MINUTE, SECOND)
+ -- Function File:  datenum (`"date"')
+ -- Function File:  datenum (`"date"', P)
+     Returns the specified local time as a day number, with Jan 1, 0000
+     being day 1.  By this reckoning, Jan 1, 1970 is day number 719529.
+     The fractional portion, P, corresponds to the portion of the
+     specified day.
+
+     Notes:
+
+        * Years can be negative and/or fractional.
+
+        * Months below 1 are considered to be January.
+
+        * Days of the month start at 1.
+
+        * Days beyond the end of the month go into subsequent months.
+
+        * Days before the beginning of the month go to the previous
+          month.
+
+        * Days can be fractional.
+
+     *Warning:* this function does not attempt to handle Julian
+     calendars so dates before Octave 15, 1582 are wrong by as much as
+     eleven days.  Also be aware that only Roman Catholic countries
+     adopted the calendar in 1582.  It took until 1924 for it to be
+     adopted everywhere.  See the Wikipedia entry on the Gregorian
+     calendar for more details.
+
+     *Warning:* leap seconds are ignored.  A table of leap seconds is
+     available on the Wikipedia entry for leap seconds.
+
+     *See also:* *note date: doc-date, *note clock: doc-clock, *note
+     now: doc-now, *note datestr: doc-datestr, *note datevec:
+     doc-datevec, *note calendar: doc-calendar, *note weekday:
+     doc-weekday.
+
+ -- Function File: STR = datestr (DATE, [F, [P]])
+     Format the given date/time according to the format `f' and return
+     the result in STR.  DATE is a serial date number (see `datenum')
+     or a date vector (see `datevec').  The value of DATE may also be a
+     string or cell array of strings.
+
+     F can be an integer which corresponds to one of the codes in the
+     table below, or a date format string.
+
+     P is the year at the start of the century in which two-digit years
+     are to be interpreted in.  If not specified, it defaults to the
+     current year minus 50.
+
+     For example, the date 730736.65149 (2000-09-07 15:38:09.0934)
+     would be formatted as follows:
+
+     Code    Format                         Example
+     --------------------------------------------------------------- 
+     0       dd-mmm-yyyy HH:MM:SS           07-Sep-2000 15:38:09
+     1       dd-mmm-yyyy                    07-Sep-2000
+     2       mm/dd/yy                       09/07/00
+     3       mmm                            Sep
+     4       m                              S
+     5       mm                             09
+     6       mm/dd                          09/07
+     7       dd                             07
+     8       ddd                            Thu
+     9       d                              T
+     10      yyyy                           2000
+     11      yy                             00
+     12      mmmyy                          Sep00
+     13      HH:MM:SS                       15:38:09
+     14      HH:MM:SS PM                    03:38:09 PM
+     15      HH:MM                          15:38
+     16      HH:MM PM                       03:38 PM
+     17      QQ-YY                          Q3-00
+     18      QQ                             Q3
+     19      dd/mm                          13/03
+     20      dd/mm/yy                       13/03/95
+     21      mmm.dd.yyyy HH:MM:SS           Mar.03.1962 13:53:06
+     22      mmm.dd.yyyy                    Mar.03.1962
+     23      mm/dd/yyyy                     03/13/1962
+     24      dd/mm/yyyy                     12/03/1962
+     25      yy/mm/dd                       95/03/13
+     26      yyyy/mm/dd                     1995/03/13
+     27      QQ-YYYY                        Q4-2132
+     28      mmmyyyy                        Mar2047
+     29      yyyymmdd                       20470313
+     30      yyyymmddTHHMMSS                20470313T132603
+     31      yyyy-mm-dd HH:MM:SS            1047-03-13 13:26:03
+
+     If F is a format string, the following symbols are recognized:
+
+     Symbol  Meaning                                         Example
+     ---------------------------------------------------------------------- 
+     yyyy    Full year                                       2005
+     yy      Two-digit year                                  2005
+     mmmm    Full month name                                 December
+     mmm     Abbreviated month name                          Dec
+     mm      Numeric month number (padded with zeros)        01, 08, 12
+     m       First letter of month name (capitalized)        D
+     dddd    Full weekday name                               Sunday
+     ddd     Abbreviated weekday name                        Sun
+     dd      Numeric day of month (padded with zeros)        11
+     d       First letter of weekday name (capitalized)      S
+     HH      Hour of day, padded with zeros if PM is set     09:00
+             and not padded with zeros otherwise             9:00 AM
+     MM      Minute of hour (padded with zeros)              10:05
+     SS      Second of minute (padded with zeros)            10:05:03
+     PM      Use 12-hour time format                         11:30 PM
+
+     If F is not specified or is `-1', then use 0, 1 or 16, depending
+     on whether the date portion or the time portion of DATE is empty.
+
+     If P is nor specified, it defaults to the current year minus 50.
+
+     If a matrix or cell array of dates is given, a vector of date
+     strings is returned.
+
+     *See also:* *note datenum: doc-datenum, *note datevec:
+     doc-datevec, *note date: doc-date, *note clock: doc-clock, *note
+     now: doc-now, *note datetick: doc-datetick.
+
+ -- Function File: V = datevec (DATE)
+ -- Function File: V = datevec (DATE, F)
+ -- Function File: V = datevec (DATE, P)
+ -- Function File: V = datevec (DATE, F, P)
+ -- Function File: [Y, M, D, H, MI, S] = datevec (...)
+     Convert a serial date number (see `datenum') or date string (see
+     `datestr') into a date vector.
+
+     A date vector is a row vector with six members, representing the
+     year, month, day, hour, minute, and seconds respectively.
+
+     F is the format string used to interpret date strings (see
+     `datestr').
+
+     P is the year at the start of the century in which two-digit years
+     are to be interpreted in.  If not specified, it defaults to the
+     current year minus 50.
+
+     *See also:* *note datenum: doc-datenum, *note datestr:
+     doc-datestr, *note date: doc-date, *note clock: doc-clock, *note
+     now: doc-now.
+
+ -- Function File: D = addtodate (D, Q, F)
+     Add Q amount of time (with units F) to the datenum, D.
+
+     F must be one of "year", "month", "day", "hour", "minute", or
+     "second".
+
+     *See also:* *note datenum: doc-datenum, *note datevec: doc-datevec.
+
+ -- Function File:  calendar (...)
+ -- Function File: C = calendar ()
+ -- Function File: C = calendar (D)
+ -- Function File: C = calendar (Y, M)
+     If called with no arguments, return the current monthly calendar in
+     a 6x7 matrix.
+
+     If D is specified, return the calendar for the month containing
+     the day D, which must be a serial date number or a date string.
+
+     If Y and M are specified, return the calendar for year Y and month
+     M.
+
+     If no output arguments are specified, print the calendar on the
+     screen instead of returning a matrix.
+
+     *See also:* *note datenum: doc-datenum.
+
+ -- Function File: [N, S] = weekday (D, [FORM])
+     Return the day of week as a number in N and a string in S, for
+     example `[1, "Sun"]', `[2, "Mon"]', ..., or `[7, "Sat"]'.
+
+     D is a serial date number or a date string.
+
+     If the string FORM is given and is `"long"', S will contain the
+     full name of the weekday; otherwise (or if FORM is `"short"'), S
+     will contain the abbreviated name of the weekday.
+
+     *See also:* *note datenum: doc-datenum, *note datevec:
+     doc-datevec, *note eomday: doc-eomday.
+
+ -- Function File: E = eomday (Y, M)
+     Return the last day of the month M for the year Y.
+
+     *See also:* *note datenum: doc-datenum, *note datevec:
+     doc-datevec, *note weekday: doc-weekday.
+
+ -- Function File:  datetick (FORM)
+ -- Function File:  datetick (AXIS, FORM)
+ -- Function File:  datetick (..., "keeplimits")
+ -- Function File:  datetick (..., "keepticks")
+ -- Function File:  datetick (...ax, ...)
+     Adds date formatted tick labels to an axis.  The axis the apply the
+     ticks to is determined by AXIS that can take the values "x", "y"
+     or "z".  The default value is "x".  The formatting of the labels is
+     determined by the variable FORM, that can either be a string in
+     the format needed by `dateform', or a positive integer that can be
+     accepted by `datestr'.
+
+     *See also:* *note datenum: doc-datenum, *note datestr: doc-datestr.
+
diff --git a/doc/interpreter/octave.info-5 b/doc/interpreter/octave.info-5
new file mode 100644
index 0000000..b89782d
--- /dev/null
+++ b/doc/interpreter/octave.info-5
@@ -0,0 +1,7544 @@
+This is octave.info, produced by makeinfo version 4.11 from ./octave.texi.
+
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, 2007
+John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+File: octave.info,  Node: Filesystem Utilities,  Next: File Archiving Utilities,  Prev: Timing Utilities,  Up: System Utilities
+
+34.2 Filesystem Utilities
+=========================
+
+Octave includes the following functions for renaming and deleting files,
+creating, deleting, and reading directories, and for getting information
+about the status of files.
+
+ -- Built-in Function: [ERR, MSG] = rename (OLD, NEW)
+     Change the name of file OLD to NEW.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+     *See also:* *note ls: doc-ls, *note dir: doc-dir.
+
+ -- Built-in Function: [ERR, MSG] = link (OLD, NEW)
+     Create a new link (also known as a hard link) to an existing file.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+     *See also:* *note symlink: doc-symlink.
+
+ -- Built-in Function: [ERR, MSG] = symlink (OLD, NEW)
+     Create a symbolic link NEW which contains the string OLD.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+     *See also:* *note link: doc-link, *note readlink: doc-readlink.
+
+ -- Built-in Function: [RESULT, ERR, MSG] = readlink (SYMLINK)
+     Read the value of the symbolic link SYMLINK.
+
+     If successful, RESULT contains the contents of the symbolic link
+     SYMLINK, ERR is 0 and MSG is an empty string.  Otherwise, ERR is
+     nonzero and MSG contains a system-dependent error message.
+
+     *See also:* *note link: doc-link, *note symlink: doc-symlink.
+
+ -- Built-in Function: [ERR, MSG] = unlink (FILE)
+     Delete the file named FILE.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+ -- Built-in Function: [FILES, ERR, MSG] = readdir (DIR)
+     Return names of the files in the directory DIR as a cell array of
+     strings.  If an error occurs, return an empty cell array in FILES.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+     *See also:* *note dir: doc-dir, *note glob: doc-glob.
+
+ -- Built-in Function: [STATUS, MSG, MSGID] = mkdir (DIR)
+ -- Built-in Function: [STATUS, MSG, MSGID] = mkdir (PARENT, DIR)
+     Create a directory named DIR in the directory PARENT.
+
+     If successful, STATUS is 1, with MSG and MSGID empty character
+     strings.  Otherwise, STATUS is 0, MSG contains a system-dependent
+     error message, and MSGID contains a unique message identifier.
+
+     *See also:* *note rmdir: doc-rmdir.
+
+ -- Built-in Function: [STATUS, MSG, MSGID] = rmdir (DIR)
+ -- Built-in Function: [STATUS, MSG, MSGID] = rmdir (DIR, `"s"')
+     Remove the directory named DIR.
+
+     If successful, STATUS is 1, with MSG and MSGID empty character
+     strings.  Otherwise, STATUS is 0, MSG contains a system-dependent
+     error message, and MSGID contains a unique message identifier.
+
+     If the optional second parameter is supplied with value `"s"',
+     recursively remove all subdirectories as well.
+
+     *See also:* *note mkdir: doc-mkdir, *note confirm_recursive_rmdir:
+     doc-confirm_recursive_rmdir.
+
+ -- Built-in Function: VAL = confirm_recursive_rmdir ()
+ -- Built-in Function: OLD_VAL = confirm_recursive_rmdir (NEW_VAL)
+     Query or set the internal variable that controls whether Octave
+     will ask for confirmation before recursively removing a directory
+     tree.
+
+ -- Built-in Function: [ERR, MSG] = mkfifo (NAME, MODE)
+     Create a FIFO special file named NAME with file mode MODE
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+ -- Built-in Function:  umask (MASK)
+     Set the permission mask for file creation.  The parameter MASK is
+     an integer, interpreted as an octal number.  If successful,
+     returns the previous value of the mask (as an integer to be
+     interpreted as an octal number); otherwise an error message is
+     printed.
+
+ -- Built-in Function: [INFO, ERR, MSG] = stat (FILE)
+ -- Built-in Function: [INFO, ERR, MSG] = lstat (FILE)
+     Return a structure S containing the following information about
+     FILE.
+
+    `dev'
+          ID of device containing a directory entry for this file.
+
+    `ino'
+          File number of the file.
+
+    `mode'
+          File mode, as an integer.  Use the functions `S_ISREG',
+          `S_ISDIR', `S_ISCHR', `S_ISBLK', `S_ISFIFO', `S_ISLNK', or
+          `S_ISSOCK' to extract information from this value.
+
+    `modestr'
+          File mode, as a string of ten letters or dashes as would be
+          returned by `ls -l'.
+
+    `nlink'
+          Number of links.
+
+    `uid'
+          User ID of file's owner.
+
+    `gid'
+          Group ID of file's group.
+
+    `rdev'
+          ID of device for block or character special files.
+
+    `size'
+          Size in bytes.
+
+    `atime'
+          Time of last access in the same form as time values returned
+          from `time'.  *Note Timing Utilities::.
+
+    `mtime'
+          Time of last modification in the same form as time values
+          returned from `time'.  *Note Timing Utilities::.
+
+    `ctime'
+          Time of last file status change in the same form as time
+          values returned from `time'.  *Note Timing Utilities::.
+
+    `blksize'
+          Size of blocks in the file.
+
+    `blocks'
+          Number of blocks allocated for file.
+
+     If the call is successful ERR is 0 and MSG is an empty string.  If
+     the file does not exist, or some other error occurs, S is an empty
+     matrix, ERR is -1, and MSG contains the corresponding system error
+     message.
+
+     If FILE is a symbolic link, `stat' will return information about
+     the actual file that is referenced by the link.  Use `lstat' if
+     you want information about the symbolic link itself.
+
+     For example,
+
+          [s, err, msg] = stat ("/vmlinuz")
+                => s =
+                  {
+                    atime = 855399756
+                    rdev = 0
+                    ctime = 847219094
+                    uid = 0
+                    size = 389218
+                    blksize = 4096
+                    mtime = 847219094
+                    gid = 6
+                    nlink = 1
+                    blocks = 768
+                    mode = -rw-r--r--
+                    modestr = -rw-r--r--
+                    ino = 9316
+                    dev = 2049
+                  }
+               => err = 0
+               => msg =
+
+ -- Built-in Function: [INFO, ERR, MSG] = fstat (FID)
+     Return information about the open file FID.  See `stat' for a
+     description of the contents of INFO.
+
+ -- Function File: [STATUS, MSG, MSGID] = fileattrib (FILE)
+     Return information about FILE.
+
+     If successful, STATUS is 1, with RESULT containing a structure
+     with the following fields:
+
+    `Name'
+          Full name of FILE.
+
+    `archive'
+          True if FILE is an archive (Windows).
+
+    `system'
+          True if FILE is a system file (Windows).
+
+    `hidden'
+          True if FILE is a hidden file (Windows).
+
+    `directory'
+          True if FILE is a directory.
+
+    `UserRead'
+    `GroupRead'
+    `OtherRead'
+          True if the user (group; other users) has read permission for
+          FILE.
+
+    `UserWrite'
+    `GroupWrite'
+    `OtherWrite'
+          True if the user (group; other users) has write permission for
+          FILE.
+
+    `UserExecute'
+    `GroupExecute'
+    `OtherExecute'
+          True if the user (group; other users) has execute permission
+          for FILE.
+     If an attribute does not apply (i.e., archive on a Unix system)
+     then the field is set to NaN.
+
+     With no input arguments, return information about the current
+     directory.
+
+     If FILE contains globbing characters, return information about all
+     the matching files.
+
+     *See also:* *note glob: doc-glob.
+
+ -- Function File:  isdir (F)
+     Return true if F is a directory.
+
+ -- Built-in Function:  glob (PATTERN)
+     Given an array of strings (as a char array or a cell array) in
+     PATTERN, return a cell array of file names that match any of them,
+     or an empty cell array if no patterns match.  Tilde expansion is
+     performed on each of the patterns before looking for matching file
+     names.  For example,
+
+          glob ("/vm*")
+               => "/vmlinuz"
+
+     *See also:* *note dir: doc-dir, *note ls: doc-ls, *note stat:
+     doc-stat, *note readdir: doc-readdir.
+
+ -- Built-in Function:  fnmatch (PATTERN, STRING)
+     Return 1 or zero for each element of STRING that matches any of
+     the elements of the string array PATTERN, using the rules of
+     filename pattern matching.  For example,
+
+          fnmatch ("a*b", {"ab"; "axyzb"; "xyzab"})
+               => [ 1; 1; 0 ]
+
+ -- Built-in Function:  file_in_path (PATH, FILE)
+ -- Built-in Function:  file_in_path (PATH, FILE, "all")
+     Return the absolute name of FILE if it can be found in PATH.  The
+     value of PATH should be a colon-separated list of directories in
+     the format described for `path'.  If no file is found, return an
+     empty matrix.  For example,
+
+          file_in_path (EXEC_PATH, "sh")
+               => "/bin/sh"
+
+     If the second argument is a cell array of strings, search each
+     directory of the path for element of the cell array and return the
+     first that matches.
+
+     If the third optional argument `"all"' is supplied, return a cell
+     array containing the list of all files that have the same name in
+     the path.  If no files are found, return an empty cell array.
+
+     *See also:* *note file_in_loadpath: doc-file_in_loadpath.
+
+ -- Built-in Function:  tilde_expand (STRING)
+     Performs tilde expansion on STRING.  If STRING begins with a tilde
+     character, (`~'), all of the characters preceding the first slash
+     (or all characters, if there is no slash) are treated as a
+     possible user name, and the tilde and the following characters up
+     to the slash are replaced by the home directory of the named user.
+     If the tilde is followed immediately by a slash, the tilde is
+     replaced by the home directory of the user running Octave.  For
+     example,
+
+          tilde_expand ("~joeuser/bin")
+               => "/home/joeuser/bin"
+          tilde_expand ("~/bin")
+               => "/home/jwe/bin"
+
+ -- Built-in Function: [CNAME, STATUS, MSG] canonicalize_file_name
+          (NAME)
+     Return the canonical name of file NAME.
+
+ -- Function File: [STATUS, MSG, MSGID] = movefile (F1, F2)
+     Move the file F1 to the new name F2.  The name F1 may contain
+     globbing patterns.  If F1 expands to multiple file names, F2 must
+     be a directory.
+
+     If successful, STATUS is 1, with MSG and MSGID empty\n\ character
+     strings.  Otherwise, STATUS is 0, MSG contains a\n\
+     system-dependent error message, and MSGID contains a unique\n\
+     message identifier.\n\
+
+     *See also:* *note glob: doc-glob.
+
+ -- Function File: [STATUS, MSG, MSGID] = copyfile (F1, F2, FORCE)
+     Copy the file F1 to the new name F2.  The name F1 may contain
+     globbing patterns.  If F1 expands to multiple file names, F2 must
+     be a directory.  If FORCE is given and equals the string "f" the
+     copy operation will be forced.
+
+     If successful, STATUS is 1, with MSG and MSGID empty\n\ character
+     strings.  Otherwise, STATUS is 0, MSG contains a\n\
+     system-dependent error message, and MSGID contains a unique\n\
+     message identifier.\n\
+
+     *See also:* *note glob: doc-glob, *note movefile: doc-movefile.
+
+ -- Function File: [DIR, NAME, EXT, VER] = fileparts (FILENAME)
+     Return the directory, name, extension, and version components of
+     FILENAME.
+
+     *See also:* *note fullfile: doc-fullfile.
+
+ -- Built-in Function:  filesep ()
+ -- Built-in Function:  filesep ('all')
+     Return the system-dependent character used to separate directory
+     names.
+
+     If 'all' is given, the function return all valid file separators in
+     the form of a string.  The list of file separators is
+     system-dependent.  It is / (forward slash) under UNIX or Mac OS X,
+     / and \ (forward and backward slashes) under Windows.
+
+     *See also:* *note pathsep: doc-pathsep, *note dir: doc-dir, *note
+     ls: doc-ls.
+
+ -- Built-in Function:  filemarker ()
+     Returns or sets the character used to separate filename from the
+     the subfunction names contained within the file.  This can be used
+     in a generic manner to interact with subfunctions.  For example
+
+          help (["myfunc", filemarker, "mysubfunc"])
+
+     returns the help string associated with the sub-function
+     `mysubfunc' of the function `myfunc'.  Another use of `filemarker'
+     is when debugging it allows easier placement of breakpoints within
+     sub-functions.  For example
+
+          dbstop (["myfunc", filemarker, "mysubfunc"])
+
+     will set a breakpoint at the first line of the subfunction
+     `mysubfunc'.
+
+ -- Function File: FILENAME = fullfile (DIR1, DIR2, ..., FILE)
+     Return a complete filename constructed from the given components.
+
+     *See also:* *note fileparts: doc-fileparts.
+
+ -- Function File: DIR = tempdir ()
+     Return the name of the system's directory for temporary files.
+
+ -- Function File: filename = tempname ()
+     This function is an alias for `tmpnam'.
+
+ -- Built-in Function:  P_tmpdir ()
+     Return the default name of the directory for temporary files on
+     this system.  The name of this directory is system dependent.
+
+ -- Built-in Function:  is_absolute_filename (FILE)
+     Return true if FILE is an absolute filename.
+
+ -- Built-in Function:  is_rooted_relative_filename (FILE)
+     Return true if FILE is a rooted-relative filename.
+
+ -- Built-in Function:  make_absolute_filename (FILE)
+     Return the full name of FILE, relative to the current directory.
+
+
+File: octave.info,  Node: File Archiving Utilities,  Next: Networking Utilities,  Prev: Filesystem Utilities,  Up: System Utilities
+
+34.3 File Archiving Utilities
+=============================
+
+ -- Function File:  bunzip2 (BZFILE, DIR)
+     Unpack the bzip2 archive BZFILE to the directory DIR.  If DIR is
+     not specified, it defaults to the current directory.
+
+     *See also:* *note unpack: doc-unpack, *note bzip2: doc-bzip2,
+     *note tar: doc-tar, *note untar: doc-untar, *note gzip: doc-gzip,
+     *note gunzip: doc-gunzip, *note zip: doc-zip, *note unzip:
+     doc-unzip.
+
+ -- Function File: ENTRIES = gzip (FILES)
+ -- Function File: ENTRIES = gzip (FILES, OUTDIR)
+     Compress the list of files and/or directories specified in FILES.
+     Each file is compressed separately and a new file with a '.gz'
+     extension is created.  The original files are not touched.
+     Existing compressed files are silently overwritten.  If OUTDIR is
+     defined the compressed versions of the files are placed in this
+     directory.
+
+     *See also:* *note gunzip: doc-gunzip, *note bzip2: doc-bzip2,
+     *note zip: doc-zip, *note tar: doc-tar.
+
+ -- Function File:  gunzip (GZFILE, DIR)
+     Unpack the gzip archive GZFILE to the directory DIR.  If DIR is
+     not specified, it defaults to the current directory.  If the
+     GZFILE is a directory, all files in the directory will be
+     recursively gunzipped.
+
+     *See also:* *note unpack: doc-unpack, *note bunzip2: doc-bunzip2,
+     *note tar: doc-tar, *note untar: doc-untar, *note gzip: doc-gzip,
+     *note gunzip: doc-gunzip, *note zip: doc-zip, *note unzip:
+     doc-unzip.
+
+ -- Function File: ENTRIES = tar (TARFILE, FILES, ROOT)
+     Pack FILES FILES into the TAR archive TARFILE.  The list of files
+     must be a string or a cell array of strings.
+
+     The optional argument ROOT changes the relative path of FILES from
+     the current directory.
+
+     If an output argument is requested the entries in the archive are
+     returned in a cell array.
+
+     *See also:* *note untar: doc-untar, *note gzip: doc-gzip, *note
+     gunzip: doc-gunzip, *note zip: doc-zip, *note unzip: doc-unzip.
+
+ -- Function File:  untar (TARFILE, DIR)
+     Unpack the TAR archive TARFILE to the directory DIR.  If DIR is
+     not specified, it defaults to the current directory.
+
+     *See also:* *note unpack: doc-unpack, *note bunzip2: doc-bunzip2,
+     *note tar: doc-tar, *note gzip: doc-gzip, *note gunzip:
+     doc-gunzip, *note zip: doc-zip, *note unzip: doc-unzip.
+
+ -- Function File: ENTRIES = zip (ZIPFILE, FILES)
+ -- Function File: ENTRIES = zip (ZIPFILE, FILES, ROOTDIR)
+     Compress the list of files and/or directories specified in FILES
+     into the archive ZIPFILES in the same directory.  If ROOTDIR is
+     defined the FILES is located relative to ROOTDIR rather than the
+     current directory
+
+     *See also:* *note unzip: doc-unzip, *note tar: doc-tar.
+
+ -- Function File:  unzip (ZIPFILE, DIR)
+     Unpack the ZIP archive ZIPFILE to the directory DIR.  If DIR is
+     not specified, it defaults to the current directory.
+
+     *See also:* *note unpack: doc-unpack, *note bunzip2: doc-bunzip2,
+     *note tar: doc-tar, *note untar: doc-untar, *note gzip: doc-gzip,
+     *note gunzip: doc-gunzip, *note zip: doc-zip.
+
+ -- Function File:  pack ()
+     This function is provided for compatibility with MATLAB, but it
+     doesn't actually do anything.
+
+ -- Function File: FILES = unpack (FILE, DIR)
+ -- Function File: FILES = unpack (FILE, DIR, FILETYPE)
+     Unpack the archive FILE based on its extension to the directory
+     DIR.  If FILE is a cellstr, then all files will be handled
+     individually.  If DIR is not specified, it defaults to the current
+     directory.  It returns a list of FILES unpacked.  If a directory
+     is in the file list, then the FILETYPE to unpack must also be
+     specified.
+
+     The FILES includes the entire path to the output files.
+
+     *See also:* *note bunzip2: doc-bunzip2, *note tar: doc-tar, *note
+     untar: doc-untar, *note gzip: doc-gzip, *note gunzip: doc-gunzip,
+     *note zip: doc-zip, *note unzip: doc-unzip.
+
+ -- Function File: ENTRIES = bzip2 (FILES)
+ -- Function File: ENTRIES = bzip2 (FILES, OUTDIR)
+     Compress the list of files specified in FILES.  Each file is
+     compressed separately and a new file with a '.bz2' extension is
+     created.  The original files are not touched.  Existing compressed
+     files are silently overwritten.If OUTDIR is defined the compressed
+     versions of the files are placed in this directory.
+
+     *See also:* *note bunzip2: doc-bunzip2, *note gzip: doc-gzip,
+     *note zip: doc-zip, *note tar: doc-tar.
+
+
+File: octave.info,  Node: Networking Utilities,  Next: Controlling Subprocesses,  Prev: File Archiving Utilities,  Up: System Utilities
+
+34.4 Networking Utilities
+=========================
+
+ -- Loadable Function: S = urlread (URL)
+ -- Loadable Function: [S, SUCCESS] = urlread (URL)
+ -- Loadable Function: [S, SUCCESS, MESSAGE] = urlread (URL)
+ -- Loadable Function: [...] = urlread (URL, METHOD, PARAM)
+     Download a remote file specified by its URL and return its content
+     in string S.  For example,
+
+          s = urlread ("ftp://ftp.octave.org/pub/octave/README");
+
+     The variable SUCCESS is 1 if the download was successful,
+     otherwise it is 0 in which case MESSAGE contains an error message.
+     If no output argument is specified and if an error occurs, then
+     the error is signaled through Octave's error handling mechanism.
+
+     This function uses libcurl.  Curl supports, among others, the HTTP,
+     FTP and FILE protocols.  Username and password may be specified in
+     the URL.  For example,
+
+          s = urlread ("http://user:password@example.com/file.txt");
+
+     GET and POST requests can be specified by METHOD and PARAM.  The
+     parameter METHOD is either `get' or `post' and PARAM is a cell
+     array of parameter and value pairs.  For example,
+
+          s = urlread ("http://www.google.com/search", "get",
+                       {"query", "octave"});
+
+     *See also:* *note urlwrite: doc-urlwrite.
+
+ -- Loadable Function:  urlwrite (URL, LOCALFILE)
+ -- Loadable Function: F = urlwrite (URL, LOCALFILE)
+ -- Loadable Function: [F, SUCCESS] = urlwrite (URL, LOCALFILE)
+ -- Loadable Function: [F, SUCCESS, MESSAGE] = urlwrite (URL, LOCALFILE)
+     Download a remote file specified by its URL and save it as
+     LOCALFILE.  For example,
+
+          urlwrite ("ftp://ftp.octave.org/pub/octave/README",
+                    "README.txt");
+
+     The full path of the downloaded file is returned in F.  The
+     variable SUCCESS is 1 if the download was successful, otherwise it
+     is 0 in which case MESSAGE contains an error message.  If no
+     output argument is specified and if an error occurs, then the
+     error is signaled through Octave's error handling mechanism.
+
+     This function uses libcurl.  Curl supports, among others, the HTTP,
+     FTP and FILE protocols.  Username and password may be specified in
+     the URL, for example:
+
+          urlwrite ("http://username:password@example.com/file.txt",
+                    "file.txt");
+
+     GET and POST requests can be specified by METHOD and PARAM.  The
+     parameter METHOD is either `get' or `post' and PARAM is a cell
+     array of parameter and value pairs.  For example:
+
+          urlwrite ("http://www.google.com/search", "search.html",
+                    "get", {"query", "octave"});
+
+     *See also:* *note urlread: doc-urlread.
+
+
+File: octave.info,  Node: Controlling Subprocesses,  Next: Process ID Information,  Prev: Networking Utilities,  Up: System Utilities
+
+34.5 Controlling Subprocesses
+=============================
+
+Octave includes some high-level commands like `system' and `popen' for
+starting subprocesses.  If you want to run another program to perform
+some task and then look at its output, you will probably want to use
+these functions.
+
+   Octave also provides several very low-level Unix-like functions which
+can also be used for starting subprocesses, but you should probably only
+use them if you can't find any way to do what you need with the
+higher-level functions.
+
+ -- Built-in Function:  system (STRING, RETURN_OUTPUT, TYPE)
+     Execute a shell command specified by STRING.  The second argument
+     is optional.  If TYPE is `"async"', the process is started in the
+     background and the process id of the child process is returned
+     immediately.  Otherwise, the process is started, and Octave waits
+     until it exits.  If the TYPE argument is omitted, a value of
+     `"sync"' is assumed.
+
+     If two input arguments are given (the actual value of
+     RETURN_OUTPUT is irrelevant) and the subprocess is started
+     synchronously, or if SYSTEM is called with one input argument and
+     one or more output arguments, the output from the command is
+     returned.  Otherwise, if the subprocess is executed synchronously,
+     its output is sent to the standard output.  To send the output of
+     a command executed with SYSTEM through the pager, use a command
+     like
+
+          disp (system (cmd, 1));
+
+     or
+
+          printf ("%s\n", system (cmd, 1));
+
+     The `system' function can return two values.  The first is the
+     exit status of the command and the second is any output from the
+     command that was written to the standard output stream.  For
+     example,
+
+          [status, output] = system ("echo foo; exit 2");
+
+     will set the variable `output' to the string `foo', and the
+     variable `status' to the integer `2'.
+
+ -- Function File: [STATUS, TEXT] unix (COMMAND)
+ -- Function File: [STATUS, TEXT] unix (COMMAND, "-echo")
+     Execute a system command if running under a Unix-like operating
+     system, otherwise do nothing.  Return the exit status of the
+     program in STATUS and any output sent to the standard output in
+     TEXT.  If the optional second argument `"-echo"' is given, then
+     also send the output from the command to the standard output.
+
+     *See also:* *note isunix: doc-isunix, *note ispc: doc-ispc, *note
+     system: doc-system.
+
+ -- Function File: [STATUS, TEXT] = dos (COMMAND)
+ -- Function File: [STATUS, TEXT] = dos (COMMAND, "-echo")
+     Execute a system command if running under a Windows-like operating
+     system, otherwise do nothing.  Return the exit status of the
+     program in STATUS and any output sent to the standard output in
+     TEXT.  If the optional second argument `"-echo"' is given, then
+     also send the output from the command to the standard output.
+
+     *See also:* *note unix: doc-unix, *note isunix: doc-isunix, *note
+     ispc: doc-ispc, *note system: doc-system.
+
+ -- Function File: [OUTPUT, STATUS] = perl (SCRIPTFILE)
+ -- Function File: [OUTPUT, STATUS] = perl (SCRIPTFILE, ARGUMENT1,
+          ARGUMENT2, ...)
+     Invoke perl script SCRIPTFILE with possibly a list of command line
+     arguments.  Returns output in OUTPUT and status in STATUS.
+
+     *See also:* *note system: doc-system.
+
+ -- Built-in Function: FID = popen (COMMAND, MODE)
+     Start a process and create a pipe.  The name of the command to run
+     is given by COMMAND.  The file identifier corresponding to the
+     input or output stream of the process is returned in FID.  The
+     argument MODE may be
+
+    `"r"'
+          The pipe will be connected to the standard output of the
+          process, and open for reading.
+
+    `"w"'
+          The pipe will be connected to the standard input of the
+          process, and open for writing.
+
+     For example,
+
+          fid = popen ("ls -ltr / | tail -3", "r");
+          while (ischar (s = fgets (fid)))
+            fputs (stdout, s);
+          endwhile
+               -| drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc
+               -| drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib
+               -| drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp
+
+ -- Built-in Function:  pclose (FID)
+     Close a file identifier that was opened by `popen'.  You may also
+     use `fclose' for the same purpose.
+
+ -- Built-in Function: [IN, OUT, PID] = popen2 (COMMAND, ARGS)
+     Start a subprocess with two-way communication.  The name of the
+     process is given by COMMAND, and ARGS is an array of strings
+     containing options for the command.  The file identifiers for the
+     input and output streams of the subprocess are returned in IN and
+     OUT.  If execution of the command is successful, PID contains the
+     process ID of the subprocess.  Otherwise, PID is -1.
+
+     For example,
+
+          [in, out, pid] = popen2 ("sort", "-r");
+          fputs (in, "these\nare\nsome\nstrings\n");
+          fclose (in);
+          EAGAIN = errno ("EAGAIN");
+          done = false;
+          do
+            s = fgets (out);
+            if (ischar (s))
+              fputs (stdout, s);
+            elseif (errno () == EAGAIN)
+              sleep (0.1);
+              fclear (out);
+            else
+              done = true;
+            endif
+          until (done)
+          fclose (out);
+          waitpid (pid);
+               -| these
+               -| strings
+               -| some
+               -| are
+
+     Note that `popen2', unlike `popen', will not "reap" the child
+     process.  If you don't use `waitpid' to check the child's exit
+     status, it will linger until Octave exits.
+
+ -- Built-in Function: VAL = EXEC_PATH ()
+ -- Built-in Function: OLD_VAL = EXEC_PATH (NEW_VAL)
+     Query or set the internal variable that specifies a colon separated
+     list of directories to search when executing external programs.
+     Its initial value is taken from the environment variable
+     `OCTAVE_EXEC_PATH' (if it exists) or `PATH', but that value can be
+     overridden by the command line argument `--exec-path PATH'.  At
+     startup, an additional set of directories (including the shell
+     PATH) is appended to the path specified in the environment or on
+     the command line.  If you use the `EXEC_PATH' function to modify
+     the path, you should take care to preserve these additional
+     directories.
+
+   In most cases, the following functions simply decode their arguments
+and make the corresponding Unix system calls.  For a complete example
+of how they can be used, look at the definition of the function
+`popen2'.
+
+ -- Built-in Function: [PID, MSG] = fork ()
+     Create a copy of the current process.
+
+     Fork can return one of the following values:
+
+    > 0
+          You are in the parent process.  The value returned from
+          `fork' is the process id of the child process.  You should
+          probably arrange to wait for any child processes to exit.
+
+    0
+          You are in the child process.  You can call `exec' to start
+          another process.  If that fails, you should probably call
+          `exit'.
+
+    < 0
+          The call to `fork' failed for some reason.  You must take
+          evasive action.  A system dependent error message will be
+          waiting in MSG.
+
+ -- Built-in Function: [ERR, MSG] = exec (FILE, ARGS)
+     Replace current process with a new process.  Calling `exec' without
+     first calling `fork' will terminate your current Octave process and
+     replace it with the program named by FILE.  For example,
+
+          exec ("ls" "-l")
+
+     will run `ls' and return you to your shell prompt.
+
+     If successful, `exec' does not return.  If `exec' does return, ERR
+     will be nonzero, and MSG will contain a system-dependent error
+     message.
+
+ -- Built-in Function: [READ_FD, WRITE_FD, ERR, MSG] = pipe ()
+     Create a pipe and return the reading and writing ends of the pipe
+     into READ_FD and WRITE_FD respectively.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+ -- Built-in Function: [FID, MSG] = dup2 (OLD, NEW)
+     Duplicate a file descriptor.
+
+     If successful, FID is greater than zero and contains the new file
+     ID.  Otherwise, FID is negative and MSG contains a
+     system-dependent error message.
+
+ -- Built-in Function: [PID, STATUS, MSG] = waitpid (PID, OPTIONS)
+     Wait for process PID to terminate.  The PID argument can be:
+
+    -1
+          Wait for any child process.
+
+    0
+          Wait for any child process whose process group ID is equal to
+          that of the Octave interpreter process.
+
+    > 0
+          Wait for termination of the child process with ID PID.
+
+     The OPTIONS argument can be a bitwise OR of zero or more of the
+     following constants:
+
+    `0'
+          Wait until signal is received or a child process exits (this
+          is the default if the OPTIONS argument is missing).
+
+    `WNOHANG'
+          Do not hang if status is not immediately available.
+
+    `WUNTRACED'
+          Report the status of any child processes that are stopped,
+          and whose status has not yet been reported since they stopped.
+
+    `WCONTINUE'
+          Return if a stopped child has been resumed by delivery of
+          `SIGCONT'.  This value may not be meaningful on all systems.
+
+     If the returned value of PID is greater than 0, it is the process
+     ID of the child process that exited.  If an error occurs, PID will
+     be less than zero and MSG will contain a system-dependent error
+     message.  The value of STATUS contains additional system-dependent
+     information about the subprocess that exited.
+
+     *See also:* *note WCONTINUE: doc-WCONTINUE, *note WCOREDUMP:
+     doc-WCOREDUMP, *note WEXITSTATUS: doc-WEXITSTATUS, *note
+     WIFCONTINUED: doc-WIFCONTINUED, *note WIFSIGNALED:
+     doc-WIFSIGNALED, *note WIFSTOPPED: doc-WIFSTOPPED, *note WNOHANG:
+     doc-WNOHANG, *note WSTOPSIG: doc-WSTOPSIG, *note WTERMSIG:
+     doc-WTERMSIG, *note WUNTRACED: doc-WUNTRACED.
+
+ -- Built-in Function: WCONINTUE ()
+     Return the numerical value of the option argument that may be
+     passed to `waitpid' to indicate that it should also return if a
+     stopped child has been resumed by delivery of a `SIGCONT' signal.
+
+     *See also:* *note waitpid: doc-waitpid, *note WNOHANG:
+     doc-WNOHANG, *note WUNTRACED: doc-WUNTRACED.
+
+ -- Built-in Function:  WCOREDUMP (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child
+     produced a core dump.  This function should only be employed if
+     `WIFSIGNALED' returned true.  The macro used to implement this
+     function is not specified in POSIX.1-2001 and is not available on
+     some Unix implementations (e.g., AIX, SunOS).
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WEXITSTATUS: doc-WEXITSTATUS, *note
+     WIFSIGNALED: doc-WIFSIGNALED, *note WTERMSIG: doc-WTERMSIG, *note
+     WIFSTOPPED: doc-WIFSTOPPED, *note WSTOPSIG: doc-WSTOPSIG, *note
+     WIFCONTINUED: doc-WIFCONTINUED.
+
+ -- Built-in Function:  WEXITSTATUS (STATUS)
+     Given STATUS from a call to `waitpid', return the exit status of
+     the child.  This function should only be employed if `WIFEXITED'
+     returned true.
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WIFSIGNALED: doc-WIFSIGNALED, *note WTERMSIG:
+     doc-WTERMSIG, *note WCOREDUMP: doc-WCOREDUMP, *note WIFSTOPPED:
+     doc-WIFSTOPPED, *note WSTOPSIG: doc-WSTOPSIG, *note WIFCONTINUED:
+     doc-WIFCONTINUED.
+
+ -- Built-in Function:  WIFCONTINUED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child
+     process was resumed by delivery of `SIGCONT'.
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WEXITSTATUS: doc-WEXITSTATUS, *note
+     WIFSIGNALED: doc-WIFSIGNALED, *note WTERMSIG: doc-WTERMSIG, *note
+     WCOREDUMP: doc-WCOREDUMP, *note WIFSTOPPED: doc-WIFSTOPPED, *note
+     WSTOPSIG: doc-WSTOPSIG.
+
+ -- Built-in Function:  WIFSIGNALED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child
+     process was terminated by a signal.
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WEXITSTATUS: doc-WEXITSTATUS, *note WTERMSIG:
+     doc-WTERMSIG, *note WCOREDUMP: doc-WCOREDUMP, *note WIFSTOPPED:
+     doc-WIFSTOPPED, *note WSTOPSIG: doc-WSTOPSIG, *note WIFCONTINUED:
+     doc-WIFCONTINUED.
+
+ -- Built-in Function:  WIFSTOPPED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child
+     process was stopped by delivery of a signal; this is only possible
+     if the call was done using `WUNTRACED' or when the child is being
+     traced (see ptrace(2)).
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WEXITSTATUS: doc-WEXITSTATUS, *note
+     WIFSIGNALED: doc-WIFSIGNALED, *note WTERMSIG: doc-WTERMSIG, *note
+     WCOREDUMP: doc-WCOREDUMP, *note WSTOPSIG: doc-WSTOPSIG, *note
+     WIFCONTINUED: doc-WIFCONTINUED.
+
+ -- Built-in Function:  WIFEXITED (STATUS)
+     Given STATUS from a call to `waitpid', return true if the child
+     terminated normally.
+
+     *See also:* *note waitpid: doc-waitpid, *note WEXITSTATUS:
+     doc-WEXITSTATUS, *note WIFSIGNALED: doc-WIFSIGNALED, *note
+     WTERMSIG: doc-WTERMSIG, *note WCOREDUMP: doc-WCOREDUMP, *note
+     WIFSTOPPED: doc-WIFSTOPPED, *note WSTOPSIG: doc-WSTOPSIG, *note
+     WIFCONTINUED: doc-WIFCONTINUED.
+
+ -- Built-in Function:  WNOHANG ()
+     Return the numerical value of the option argument that may be
+     passed to `waitpid' to indicate that it should return its status
+     immediately instead of waiting for a process to exit.
+
+     *See also:* *note waitpid: doc-waitpid, *note WUNTRACED:
+     doc-WUNTRACED, *note WCONTINUE: doc-WCONTINUE.
+
+ -- Built-in Function:  WSTOPSIG (STATUS)
+     Given STATUS from a call to `waitpid', return the number of the
+     signal which caused the child to stop.  This function should only
+     be employed if `WIFSTOPPED' returned true.
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WEXITSTATUS: doc-WEXITSTATUS, *note
+     WIFSIGNALED: doc-WIFSIGNALED, *note WTERMSIG: doc-WTERMSIG, *note
+     WCOREDUMP: doc-WCOREDUMP, *note WIFSTOPPED: doc-WIFSTOPPED, *note
+     WIFCONTINUED: doc-WIFCONTINUED.
+
+ -- Built-in Function:  WTERMSIG (STATUS)
+     Given STATUS from a call to `waitpid', return the number of the
+     signal that caused the child process to terminate.  This function
+     should only be employed if `WIFSIGNALED' returned true.
+
+     *See also:* *note waitpid: doc-waitpid, *note WIFEXITED:
+     doc-WIFEXITED, *note WEXITSTATUS: doc-WEXITSTATUS, *note
+     WIFSIGNALED: doc-WIFSIGNALED, *note WCOREDUMP: doc-WCOREDUMP,
+     *note WIFSTOPPED: doc-WIFSTOPPED, *note WSTOPSIG: doc-WSTOPSIG,
+     *note WIFCONTINUED: doc-WIFCONTINUED.
+
+ -- Built-in Function:  WUNTRACED ()
+     Return the numerical value of the option argument that may be
+     passed to `waitpid' to indicate that it should also return if the
+     child process has stopped but is not traced via the `ptrace'
+     system call
+
+     *See also:* *note waitpid: doc-waitpid, *note WNOHANG:
+     doc-WNOHANG, *note WCONTINUE: doc-WCONTINUE.
+
+ -- Built-in Function: [ERR, MSG] = fcntl (FID, REQUEST, ARG)
+     Change the properties of the open file FID.  The following values
+     may be passed as REQUEST:
+
+    `F_DUPFD'
+          Return a duplicate file descriptor.
+
+    `F_GETFD'
+          Return the file descriptor flags for FID.
+
+    `F_SETFD'
+          Set the file descriptor flags for FID.
+
+    `F_GETFL'
+          Return the file status flags for FID.  The following codes
+          may be returned (some of the flags may be undefined on some
+          systems).
+
+         `O_RDONLY'
+               Open for reading only.
+
+         `O_WRONLY'
+               Open for writing only.
+
+         `O_RDWR'
+               Open for reading and writing.
+
+         `O_APPEND'
+               Append on each write.
+
+         `O_CREAT'
+               Create the file if it does not exist.
+
+         `O_NONBLOCK'
+               Nonblocking mode.
+
+         `O_SYNC'
+               Wait for writes to complete.
+
+         `O_ASYNC'
+               Asynchronous I/O.
+
+    `F_SETFL'
+          Set the file status flags for FID to the value specified by
+          ARG.  The only flags that can be changed are `O_APPEND' and
+          `O_NONBLOCK'.
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+ -- Built-in Function: [ERR, MSG] = kill (PID, SIG)
+     Send signal SIG to process PID.
+
+     If PID is positive, then signal SIG is sent to PID.
+
+     If PID is 0, then signal SIG is sent to every process in the
+     process group of the current process.
+
+     If PID is -1, then signal SIG is sent to every process except
+     process 1.
+
+     If PID is less than -1, then signal SIG is sent to every process
+     in the process group -PID.
+
+     If SIG is 0, then no signal is sent, but error checking is still
+     performed.
+
+     Return 0 if successful, otherwise return -1.
+
+ -- Built-in Function:  SIG ()
+     Return a structure containing Unix signal names and their defined
+     values.
+
+
+File: octave.info,  Node: Process ID Information,  Next: Environment Variables,  Prev: Controlling Subprocesses,  Up: System Utilities
+
+34.6 Process, Group, and User IDs
+=================================
+
+ -- Built-in Function: pgid = getpgrp ()
+     Return the process group id of the current process.
+
+ -- Built-in Function: pid = getpid ()
+     Return the process id of the current process.
+
+ -- Built-in Function: pid = getppid ()
+     Return the process id of the parent process.
+
+ -- Built-in Function: euid = geteuid ()
+     Return the effective user id of the current process.
+
+ -- Built-in Function: uid = getuid ()
+     Return the real user id of the current process.
+
+ -- Built-in Function: egid = getegid ()
+     Return the effective group id of the current process.
+
+ -- Built-in Function: gid = getgid ()
+     Return the real group id of the current process.
+
+
+File: octave.info,  Node: Environment Variables,  Next: Current Working Directory,  Prev: Process ID Information,  Up: System Utilities
+
+34.7 Environment Variables
+==========================
+
+ -- Built-in Function:  getenv (VAR)
+     Return the value of the environment variable VAR.  For example,
+
+          getenv ("PATH")
+
+     returns a string containing the value of your path.
+
+ -- Built-in Function:  putenv (VAR, VALUE)
+ -- Built-in Function:  setenv (VAR, VALUE)
+     Set the value of the environment variable VAR to VALUE.
+
+
+File: octave.info,  Node: Current Working Directory,  Next: Password Database Functions,  Prev: Environment Variables,  Up: System Utilities
+
+34.8 Current Working Directory
+==============================
+
+ -- Command: cd dir
+ -- Command: chdir dir
+     Change the current working directory to DIR.  If DIR is omitted,
+     the current directory is changed to the user's home directory.
+     For example,
+
+          cd ~/octave
+
+     Changes the current working directory to `~/octave'.  If the
+     directory does not exist, an error message is printed and the
+     working directory is not changed.
+
+     *See also:* *note mkdir: doc-mkdir, *note rmdir: doc-rmdir, *note
+     dir: doc-dir.
+
+ -- Command: ls options
+     List directory contents.  For example,
+
+          ls -l
+               -| total 12
+               -| -rw-r--r--   1 jwe  users  4488 Aug 19 04:02 foo.m
+               -| -rw-r--r--   1 jwe  users  1315 Aug 17 23:14 bar.m
+
+     The `dir' and `ls' commands are implemented by calling your
+     system's directory listing command, so the available options may
+     vary from system to system.
+
+     *See also:* *note dir: doc-dir, *note stat: doc-stat, *note
+     readdir: doc-readdir, *note glob: doc-glob, *note filesep:
+     doc-filesep, *note ls_command: doc-ls_command.
+
+ -- Function File: [OLD_CMD = ls_command (CMD)
+     Set or return the shell command used by Octave's `ls' command.
+     The value of CMD must be a character string.  With no arguments,
+     simply return the previous value.
+
+     *See also:* *note ls: doc-ls.
+
+ -- Function File:  dir (DIRECTORY)
+ -- Function File: [LIST] = dir (DIRECTORY)
+     Display file listing for directory DIRECTORY.  If a return value
+     is requested, return a structure array with the fields
+
+          name
+          bytes
+          date
+          isdir
+          statinfo
+
+     in which `statinfo' is the structure returned from `stat'.
+
+     If DIRECTORY is not a directory, return information about the
+     named FILENAME.  DIRECTORY may be a list of directories specified
+     either by name or with wildcard characters (like * and ?)  which
+     will be expanded with glob.
+
+     Note that for symbolic links, `dir' returns information about the
+     file that a symbolic link points to instead of the link itself.
+     However, if the link points to a nonexistent file, `dir' returns
+     information about the link.
+
+     *See also:* *note ls: doc-ls, *note stat: doc-stat, *note lstat:
+     doc-lstat, *note readdir: doc-readdir, *note glob: doc-glob, *note
+     filesep: doc-filesep.
+
+ -- Built-in Function:  pwd ()
+     Return the current working directory.
+
+     *See also:* *note dir: doc-dir, *note ls: doc-ls.
+
+
+File: octave.info,  Node: Password Database Functions,  Next: Group Database Functions,  Prev: Current Working Directory,  Up: System Utilities
+
+34.9 Password Database Functions
+================================
+
+Octave's password database functions return information in a structure
+with the following fields.
+
+`name'
+     The user name.
+
+`passwd'
+     The encrypted password, if available.
+
+`uid'
+     The numeric user id.
+
+`gid'
+     The numeric group id.
+
+`gecos'
+     The GECOS field.
+
+`dir'
+     The home directory.
+
+`shell'
+     The initial shell.
+
+   In the descriptions of the following functions, this data structure
+is referred to as a PW_STRUCT.
+
+ -- Loadable Function: PW_STRUCT = getpwent ()
+     Return a structure containing an entry from the password database,
+     opening it if necessary.  Once the end of the data has been
+     reached, `getpwent' returns 0.
+
+ -- Loadable Function: PW_STRUCT = getpwuid (UID).
+     Return a structure containing the first entry from the password
+     database with the user ID UID.  If the user ID does not exist in
+     the database, `getpwuid' returns 0.
+
+ -- Loadable Function: PW_STRUCT = getpwnam (NAME)
+     Return a structure containing the first entry from the password
+     database with the user name NAME.  If the user name does not exist
+     in the database, `getpwname' returns 0.
+
+ -- Loadable Function:  setpwent ()
+     Return the internal pointer to the beginning of the password
+     database.
+
+ -- Loadable Function:  endpwent ()
+     Close the password database.
+
+
+File: octave.info,  Node: Group Database Functions,  Next: System Information,  Prev: Password Database Functions,  Up: System Utilities
+
+34.10 Group Database Functions
+==============================
+
+Octave's group database functions return information in a structure
+with the following fields.
+
+`name'
+     The user name.
+
+`passwd'
+     The encrypted password, if available.
+
+`gid'
+     The numeric group id.
+
+`mem'
+     The members of the group.
+
+   In the descriptions of the following functions, this data structure
+is referred to as a GRP_STRUCT.
+
+ -- Loadable Function: GRP_STRUCT = getgrent ()
+     Return an entry from the group database, opening it if necessary.
+     Once the end of the data has been reached, `getgrent' returns 0.
+
+ -- Loadable Function: GRP_STRUCT = getgrgid (GID).
+     Return the first entry from the group database with the group ID
+     GID.  If the group ID does not exist in the database, `getgrgid'
+     returns 0.
+
+ -- Loadable Function: GRP_STRUCT = getgrnam (NAME)
+     Return the first entry from the group database with the group name
+     NAME.  If the group name does not exist in the database,
+     `getgrnam' returns 0.
+
+ -- Loadable Function:  setgrent ()
+     Return the internal pointer to the beginning of the group database.
+
+ -- Loadable Function:  endgrent ()
+     Close the group database.
+
+
+File: octave.info,  Node: System Information,  Next: Hashing Functions,  Prev: Group Database Functions,  Up: System Utilities
+
+34.11 System Information
+========================
+
+ -- Function File: [C, MAXSIZE, ENDIAN] = computer ()
+     Print or return a string of the form CPU-VENDOR-OS that identifies
+     the kind of computer Octave is running on.  If invoked with an
+     output argument, the value is returned instead of printed.  For
+     example,
+
+          computer ()
+               -| i586-pc-linux-gnu
+
+          x = computer ()
+               => x = "i586-pc-linux-gnu"
+
+     If two output arguments are requested, also return the maximum
+     number of elements for an array.
+
+     If three output arguments are requested, also return the byte order
+     of the current system as a character (`"B"' for big-endian or
+     `"L"' for little-endian).
+
+ -- Built-in Function: [UTS, ERR, MSG] = uname ()
+     Return system information in the structure.  For example,
+
+          uname ()
+               => {
+                     sysname = x86_64
+                     nodename = segfault
+                     release = 2.6.15-1-amd64-k8-smp
+                     version = Linux
+                     machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006
+                   }
+
+     If successful, ERR is 0 and MSG is an empty string.  Otherwise,
+     ERR is nonzero and MSG contains a system-dependent error message.
+
+ -- Function File:  ispc ()
+     Return 1 if Octave is running on a Windows system and 0 otherwise.
+
+     *See also:* *note ismac: doc-ismac, *note isunix: doc-isunix.
+
+ -- Function File:  isunix ()
+     Return 1 if Octave is running on a Unix-like system and 0
+     otherwise.
+
+     *See also:* *note ismac: doc-ismac, *note ispc: doc-ispc.
+
+ -- Function File:  ismac ()
+     Return 1 if Octave is running on a Mac OS X system and 0 otherwise.
+
+     *See also:* *note ispc: doc-ispc, *note isunix: doc-isunix.
+
+ -- Built-in Function:  isieee ()
+     Return 1 if your computer claims to conform to the IEEE standard
+     for floating point calculations.
+
+ -- Built-in Function:  OCTAVE_HOME ()
+     Return the name of the top-level Octave installation directory.
+
+ -- Built-in Function:  OCTAVE_VERSION ()
+     Return the version number of Octave, as a string.
+
+ -- Function File:  license
+     Display the license of Octave.
+
+ -- Function File:  license ("inuse")
+     Display a list of packages currently being used.
+
+ -- Function File: RETVAL = license ("inuse")
+     Return a structure containing the fields `feature' and `user'.
+
+ -- Function File: RETVAL = license ("test", FEATURE)
+     Return 1 if a license exists for the product identified by the
+     string FEATURE and 0 otherwise.  The argument FEATURE is case
+     insensitive and only the first 27 characters are checked.
+
+ -- Function File:  license ("test", FEATURE, TOGGLE)
+     Enable or disable license testing for FEATURE, depending on
+     TOGGLE, which may be one of:
+
+    `"enable"'
+          Future tests for the specified license of FEATURE are
+          conducted as usual.
+
+    `"disable"'
+          Future tests for the specified license of FEATURE return 0.
+
+ -- Function File: RETVAL = license ("checkout", FEATURE)
+     Check out a license for FEATURE, returning 1 on success and 0 on
+     failure.
+
+     This function is provided for compatibility with MATLAB.
+
+     *See also:* *note ver: doc-ver, *note version: doc-version.
+
+ -- Function File:  version ()
+     Return Octave's version number as a string.  This is also the
+     value of the built-in variable `OCTAVE_VERSION'.
+
+ -- Function File:  ver ()
+     Display a header containing the current Octave version number,
+     license string and operating system, followed by the installed
+     package names, versions, and installation directories.
+
+ -- Function File: v = ver ()
+     Return a vector of structures, respecting Octave and each
+     installed package.  The structure includes the following fields.
+
+    `Name'
+          Package name.
+
+    `Version'
+          Version of the package.
+
+    `Revision'
+          Revision of the package.
+
+    `Date'
+          Date respecting the version/revision.
+
+ -- Function File: v = ver (`"Octave"')
+     Return version information for Octave only..
+
+ -- Function File: v = ver (PKG)
+     Return version information for the specified package PKG.
+
+     *See also:* *note license: doc-license, *note version: doc-version.
+
+ -- Built-in Function:  octave_config_info (OPTION)
+     Return a structure containing configuration and installation
+     information for Octave.
+
+     if OPTION is a string, return the configuration information for the
+     specified option.
+
+
+ -- Loadable Function:  getrusage ()
+     Return a structure containing a number of statistics about the
+     current Octave process.  Not all fields are available on all
+     systems.  If it is not possible to get CPU time statistics, the
+     CPU time slots are set to zero.  Other missing data are replaced
+     by NaN.  Here is a list of all the possible fields that can be
+     present in the structure returned by `getrusage':
+
+    `idrss'
+          Unshared data size.
+
+    `inblock'
+          Number of block input operations.
+
+    `isrss'
+          Unshared stack size.
+
+    `ixrss'
+          Shared memory size.
+
+    `majflt'
+          Number of major page faults.
+
+    `maxrss'
+          Maximum data size.
+
+    `minflt'
+          Number of minor page faults.
+
+    `msgrcv'
+          Number of messages received.
+
+    `msgsnd'
+          Number of messages sent.
+
+    `nivcsw'
+          Number of involuntary context switches.
+
+    `nsignals'
+          Number of signals received.
+
+    `nswap'
+          Number of swaps.
+
+    `nvcsw'
+          Number of voluntary context switches.
+
+    `oublock'
+          Number of block output operations.
+
+    `stime'
+          A structure containing the system CPU time used.  The
+          structure has the elements `sec' (seconds) `usec'
+          (microseconds).
+
+    `utime'
+          A structure containing the user CPU time used.  The structure
+          has the elements `sec' (seconds) `usec' (microseconds).
+
+
+File: octave.info,  Node: Hashing Functions,  Prev: System Information,  Up: System Utilities
+
+34.12 Hashing Functions
+=======================
+
+It is often necessary to find if two strings or files are identical.
+This might be done by comparing them character by character and looking
+for differences.  However, this can be slow, and so comparing a hash of
+the string or file can be a rapid way of finding if the files differ.
+
+   Another use of the hashing function is to check for file integrity.
+The user can check the hash of the file against a known value and find
+if the file they have is the same as the one that the original hash was
+produced with.
+
+   Octave supplies the `md5sum' function to perform MD5 hashes on
+strings and files.  An example of the use of `md5sum' function might be
+
+     if exist (file, "file")
+       hash = md5sum (file);
+     else
+       # Treat the variable "file" as a string
+       hash = md5sum (file, true);
+     endif
+
+ -- Loadable Function:  md5sum (FILE)
+ -- Loadable Function:  md5sum (STR, OPT)
+     Calculates the MD5 sum of the file FILE.  If the second parameter
+     OPT exists and is true, then calculate the MD5 sum of the string
+     STR.
+
+
+File: octave.info,  Node: Packages,  Next: Dynamically Linked Functions,  Prev: System Utilities,  Up: Top
+
+35 Packages
+***********
+
+Since Octave is Free Software users are encouraged to share their
+programs amongst each other.  To aid this sharing Octave supports the
+installation of extra packages.  The `Octave-Forge' project is a
+community-maintained set of packages that can be downloaded and
+installed in Octave.  At the time of writing the `Octave-Forge' project
+can be found on-line at `http://octave.sourceforge.net', but since the
+Internet is an ever-changing place this may not be true at the time of
+reading.  Therefore it is recommended to see the Octave website for an
+updated reference.
+
+* Menu:
+
+* Installing and Removing Packages::
+* Using Packages::
+* Administrating Packages::
+* Creating Packages::
+
+
+File: octave.info,  Node: Installing and Removing Packages,  Next: Using Packages,  Up: Packages
+
+35.1 Installing and Removing Packages
+=====================================
+
+Assuming a package is available in the file `image-1.0.0.tar.gz' it can
+be installed from the Octave prompt with the command
+
+     pkg install image-1.0.0.tar.gz
+
+If the package is installed successfully nothing will be printed on the
+prompt, but if an error occurred during installation it will be
+reported.  It is possible to install several packages at once by
+writing several package files after the `pkg install' command.  If a
+different version of the package is already installed it will be
+removed prior to installing the new package.  This makes it easy to
+upgrade and downgrade the version of a package, but makes it impossible
+to have several versions of the same package installed at once.
+
+   To see which packages are installed type
+
+     pkg list
+     -| Package Name  | Version | Installation directory
+     -| --------------+---------+-----------------------
+     -|        image *|   1.0.0 | /home/jwe/octave/image-1.0.0
+
+In this case only version 1.0.0 of the `image' package is installed.
+The '*' character next to the package name shows that the image package
+is loaded and ready for use.
+
+   It is possible to remove a package from the system using the `pkg
+uninstall' command like this
+
+     pkg uninstall image
+
+If the package is removed successfully nothing will be printed in the
+prompt, but if an error occurred it will be reported.  It should be
+noted that the package file used for installation is not needed for
+removal, and that only the package name as reported by `pkg list'
+should be used when removing a package.  It is possible to remove
+several packages at once by writing several package names after the
+`pkg uninstall' command.
+
+   To minimize the amount of code duplication between packages it is
+possible that one package depends on another one.  If a package depends
+on another, it will check if that package is installed during
+installation.  If it is not, an error will be reported and the package
+will not be installed.  This behavior can be disabled by passing the
+`-nodeps' flag to the `pkg install' command
+
+     pkg install -nodeps my_package_with_dependencies.tar.gz
+
+Since the installed package expects its dependencies to be installed it
+may not function correctly.  Because of this it is not recommended to
+disable dependency checking.
+
+ -- Command: pkg COMMAND PKG_NAME
+ -- Command: pkg COMMAND OPTION PKG_NAME
+     This command interacts with the package manager.  Different
+     actions will be taken depending on the value of COMMAND.
+
+    `install'
+          Install named packages.  For example,
+               pkg install image-1.0.0.tar.gz
+          installs the package found in the file `image-1.0.0.tar.gz'.
+
+          The OPTION variable can contain options that affect the manner
+          in which a package is installed.  These options can be one or
+          more of
+
+         `-nodeps'
+               The package manager will disable the dependency
+               checking.  That way it is possible to install a package
+               even if it depends on another package that's not
+               installed on the system.  *Use this option with care.*
+
+         `-noauto'
+               The package manager will not automatically load the
+               installed package when starting Octave, even if the
+               package requests that it is.
+
+         `-auto'
+               The package manager will automatically load the
+               installed package when starting Octave, even if the
+               package requests that it isn't.
+
+         `-local'
+               A local installation is forced, even if the user has
+               system privileges.
+
+         `-global'
+               A global installation is forced, even if the user
+               doesn't normally have system privileges
+
+         `-verbose'
+               The package manager will print the output of all of the
+               commands that are performed.
+
+    `uninstall'
+          Uninstall named packages.  For example,
+               pkg uninstall image
+          removes the `image' package from the system.  If another
+          installed package depends on the `image' package an error
+          will be issued.  The package can be uninstalled anyway by
+          using the `-nodeps' option.
+
+    `load'
+          Add named packages to the path.  After loading a package it is
+          possible to use the functions provided by the package.  For
+          example,
+               pkg load image
+          adds the `image' package to the path.  It is possible to load
+          all installed packages at once with the command
+               pkg load all
+
+    `unload'
+          Removes named packages from the path.  After unloading a
+          package it is no longer possible to use the functions
+          provided by the package.  This command behaves like the
+          `load' command.
+
+    `list'
+          Show a list of the currently installed packages.  By
+          requesting one or two output argument it is possible to get a
+          list of the currently installed packages.  For example,
+               installed_packages = pkg list;
+          returns a cell array containing a structure for each
+          installed package.  The command
+               [USER_PACKAGES, SYSTEM_PACKAGES] = pkg list
+          splits the list of installed packages into those who are
+          installed by the current user, and those installed by the
+          system administrator.
+
+    `describe'
+          Show a short description of the named installed packages,
+          with the option '-verbose' also list functions provided by
+          the package, e.g.:
+                pkg describe -verbose all
+          will describe all installed packages and the functions they
+          provide.  If one output is requested a cell of structure
+          containing the description and list of functions of each
+          package is returned as output rather than printed on screen:
+                desc = pkg ("describe", "secs1d", "image")
+          If any of the requested packages is not installed, pkg
+          returns an error, unless a second output is requested:
+                [ desc, flag] = pkg ("describe", "secs1d", "image")
+          FLAG will take one of the values "Not installed", "Loaded" or
+          "Not loaded" for each of the named packages.
+
+    `prefix'
+          Set the installation prefix directory.  For example,
+               pkg prefix ~/my_octave_packages
+          sets the installation prefix to `~/my_octave_packages'.
+          Packages will be installed in this directory.
+
+          It is possible to get the current installation prefix by
+          requesting an output argument.  For example,
+               p = pkg prefix
+
+          The location in which to install the architecture dependent
+          files can be independent specified with an addition argument.
+          For example
+
+               pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
+
+    `local_list'
+          Set the file in which to look for information on the locally
+          installed packages.  Locally installed packages are those
+          that are typically available only to the current user.  For
+          example
+               pkg local_list ~/.octave_packages
+          It is possible to get the current value of local_list with
+          the following
+               pkg local_list
+
+    `global_list'
+          Set the file in which to look for, for information on the
+          globally installed packages.  Globally installed packages are
+          those that are typically available to all users.  For example
+               pkg global_list /usr/share/octave/octave_packages
+          It is possible to get the current value of global_list with
+          the following
+               pkg global_list
+
+    `rebuild'
+          Rebuilds the package database from the installed directories.
+          This can be used in cases where for some reason the package
+          database is corrupted.  It can also take the `-auto' and
+          `-noauto' options to allow the autoloading state of a package
+          to be changed.  For example
+
+               pkg rebuild -noauto image
+
+          will remove the autoloading status of the image package.
+
+    `build'
+          Builds a binary form of a package or packages.  The binary
+          file produced will itself be an Octave package that can be
+          installed normally with `pkg'.  The form of the command to
+          build a binary package is
+
+               pkg build builddir image-1.0.0.tar.gz ...
+
+          where `builddir' is the name of a directory where the
+          temporary installation will be produced and the binary
+          packages will be found.  The options `-verbose' and `-nodeps'
+          are respected, while the other options are ignored.
+
+
+File: octave.info,  Node: Using Packages,  Next: Administrating Packages,  Prev: Installing and Removing Packages,  Up: Packages
+
+35.2 Using Packages
+===================
+
+By default installed packages are available from the Octave prompt, but
+it is possible to control this using the `pkg load' and `pkg unload'
+commands.  The functions from a package can be removed from the Octave
+path by typing
+
+     pkg unload package_name
+
+where `package_name' is the name of the package to be removed from the
+path.
+
+   In much the same way a package can be added to the Octave path by
+typing
+
+     pkg load package_name
+
+
+File: octave.info,  Node: Administrating Packages,  Next: Creating Packages,  Prev: Using Packages,  Up: Packages
+
+35.3 Administrating Packages
+============================
+
+On UNIX-like systems it is possible to make both per-user and
+system-wide installations of a package.  If the user performing the
+installation is `root' the packages will be installed in a system-wide
+directory that defaults to `OCTAVE_HOME/share/octave/packages/'.  If
+the user is not `root' the default installation directory is
+`~/octave/'.  Packages will be installed in a subdirectory of the
+installation directory that will be named after the package.  It is
+possible to change the installation directory by using the `pkg prefix'
+command
+
+     pkg prefix new_installation_directory
+
+The current installation directory can be retrieved by typing
+
+     current_installation_directory = pkg prefix
+
+   To function properly the package manager needs to keep some
+information about the installed packages.  For per-user packages this
+information is by default stored in the file `~/.octave_packages' and
+for system-wide installations it is stored in
+`OCTAVE_HOME/share/octave/octave_packages'.  The path to the per-user
+file can be changed with the `pkg local_list' command
+
+     pkg local_list /path/to/new_file
+
+For system-wide installations this can be changed in the same way using
+the `pkg global_list' command.  If these commands are called without a
+new path, the current path will be returned.
+
+
+File: octave.info,  Node: Creating Packages,  Prev: Administrating Packages,  Up: Packages
+
+35.4 Creating Packages
+======================
+
+Internally a package is simply a gzipped tar file that contains a top
+level directory of any given name.  This directory will in the
+following be referred to as `package' and may contain the following
+files
+
+
+`package/DESCRIPTION'
+     This is a required file containing information about the package.
+     *Note The DESCRIPTION File::, for details on this file.
+
+`package/COPYING'
+     This is a required file containing the license of the package.  No
+     restrictions is made on the license in general.  If however the
+     package contains dynamically linked functions the license must be
+     compatible with the GNU General Public License.
+
+`package/INDEX'
+     This is an optional file describing the functions provided by the
+     package.  If this file is not given then one with be created
+     automatically from the functions in the package and the
+     `Categories' keyword in the `DESCRIPTION' file.  *Note The INDEX
+     file::, for details on this file.
+
+`package/PKG_ADD'
+     An optional file that includes commands that are run when the
+     package is added to the users path.  Note that `PKG_ADD'
+     directives in the source code of the package will also be added to
+     this file by the Octave package manager.  Note that symbolic links
+     are to be avoided in packages, as symbolic links do not exist on
+     some file systems, and so a typical use for this file is the
+     replacement of the symbolic link
+
+          ln -s foo.oct bar.oct
+
+     with an autoload directive like
+
+          autoload ('bar', which ('foo'));
+
+     *Note PKG_ADD and PKG_DEL directives::, for details on `PKG_ADD'
+     directives.
+
+`package/PKG_DEL'
+     An optional file that includes commands that are run when the
+     package is removed from the users path.  Note that `PKG_DEL'
+     directives in the source code of the package will also be added to
+     this file by the Octave package manager.  *Note PKG_ADD and
+     PKG_DEL directives::, for details on `PKG_DEL' directives.
+
+`package/pre_install.m'
+     This is an optional script that is run prior to the installation
+     of a package.
+
+`package/post_install.m'
+     This is an optional script that is run after the installation of a
+     package.
+
+`package/on_uninstall.m'
+     This is an optional script that is run prior to the removal of a
+     package.
+
+   Besides the above mentioned files, a package can also contain on or
+more of the following directories
+
+
+`package/inst'
+     An optional directory containing any files that are directly
+     installed by the package.  Typically this will include any
+     `m'-files.
+
+`package/src'
+     An optional directory containing code that must be built prior to
+     the packages installation.  The Octave package manager will execute
+     `./configure' in this directory if this script exists, and will
+     then call `make' if a file `Makefile' exists in this directory.
+     `make install' will however not be called.  If a file called
+     `FILES' exists all files listed there will be copied to the `inst'
+     directory, so they also will be installed.  If the `FILES' file
+     doesn't exist, `src/*.m' and `src/*.oct' will be copied to the
+     `inst' directory.
+
+`package/doc'
+     An optional directory containing documentation for the package.
+     The files in this directory will be directly installed in a
+     sub-directory of the installed package for future reference.
+
+`package/bin'
+     An optional directory containing files that will be added to the
+     Octave `EXEC_PATH' when the package is loaded.  This might contain
+     external scripts, etc., called by functions within the package.
+
+* Menu:
+
+* The DESCRIPTION File::
+* The INDEX file::
+* PKG_ADD and PKG_DEL directives::
+
+
+File: octave.info,  Node: The DESCRIPTION File,  Next: The INDEX file,  Up: Creating Packages
+
+35.4.1 The DESCRIPTION File
+---------------------------
+
+The `DESCRIPTION' file contains various information about the package,
+such as its name, author, and version.  This file has a very simple
+format
+
+
+   * Lines starting with `#' are comments.
+
+   * Lines starting with a blank character are continuations from the
+     previous line.
+
+   * Everything else is of the form `NameOfOption: ValueOfOption'.
+
+The following is a simple example of a `DESCRIPTION' file
+
+     Name: The name of my package
+     Version: 1.0.0
+     Date: 2007-18-04
+     Author: The name (and possibly email) of the package author.
+     Maintainer: The name (and possibly email) of the current
+      package maintainer.
+     Title: The title of the package
+     Description: A short description of the package.  If this
+      description gets too long for one line it can continue
+      on the next by adding a space to the beginning of the
+      following lines.
+     License: GPL version 3 or later
+
+   The package manager currently recognizes the following keywords
+
+
+`Name'
+     Name of the package.
+
+`Version'
+     Version of the package.
+
+`Date'
+     Date of last update.
+
+`Author'
+     Original author of the package.
+
+`Maintainer'
+     Maintainer of the package.
+
+`Title'
+     A one line description of the package.
+
+`Description'
+     A one paragraph description of the package.
+
+`Categories'
+     Optional keyword describing the package (if no `INDEX' file is
+     given this is mandatory).
+
+`Problems'
+     Optional list of known problems.
+
+`Url'
+     Optional list of homepages related to the package.
+
+`Autoload'
+     Optional field that sets the default loading behavior for the
+     package.  If set to `yes', `true' or `on', then Octave will
+     automatically load the package when starting.  Otherwise the
+     package must be manually loaded with the pkg load command.  This
+     default behavior can be overridden when the package is installed.
+
+`Depends'
+     A list of other Octave packages that this package depends on.
+     This can include dependencies on particular versions, with a format
+
+          Depends: package (>= 1.0.0)
+
+     Possible operators are `<', `<=', `==', `>=' or `>'.  If the part
+     of the dependency in `()' is missing, any version of the package
+     is acceptable.  Multiple dependencies can be defined either as a
+     comma separated list or on separate `Depends' lines.
+
+`License'
+     An optional short description of the used license (e.g., GPL
+     version 3 or newer).  This is optional since the file `COPYING' is
+     mandatory.
+
+`SystemRequirements'
+     These are the external install dependencies of the package and are
+     not checked by the package manager.  This is here as a hint to the
+     distribution packager.  They follow the same conventions as the
+     `Depends' keyword.
+
+`BuildRequires'
+     These are the external build dependencies of the package and are
+     not checked by the package manager.  This is here as a hint to the
+     distribution packager.  They follow the same conventions as the
+     `Depends' keyword.  Note that in general, packaging systems such
+     as `rpm' or `deb' and autoprobe the install dependencies from the
+     build dependencies, and therefore the often a `BuildRequires'
+     dependency removes the need for a `SystemRequirements' dependency.
+
+
+The developer is free to add additional arguments to the `DESCRIPTION'
+file for their own purposes.  One further detail to aid the packager is
+that the `SystemRequirements' and `BuildRequires' keywords can have a
+distribution dependent section, and the automatic build process will
+use these.  An example of the format of this is
+
+     BuildRequires: libtermcap-devel [Mandriva] libtermcap2-devel
+
+where the first package name will be used as a default and if the RPMs
+are built on a Mandriva distribution, then the second package name will
+be used instead.
+
+
+File: octave.info,  Node: The INDEX file,  Next: PKG_ADD and PKG_DEL directives,  Prev: The DESCRIPTION File,  Up: Creating Packages
+
+35.4.2 The INDEX file
+---------------------
+
+The optional `INDEX' file provides a categorical view of the functions
+in the package.  This file has a very simple format
+
+
+   * Lines beginning with `#' are comments.
+
+   * The first non-comment line should look like this
+
+          toolbox >> Toolbox name
+
+   * Lines beginning with an alphabetical character indicates a new
+     category of functions.
+
+   * Lines starting with a white space character indicate that the
+     function names on the line belong to the last mentioned category.
+
+The format can be summarized with the following example
+
+     # A comment
+     toolbox >> Toolbox name
+     Category Name 1
+      function1 function2 function3
+      function4
+     Category Name 2
+      function2 function5
+
+   If you wish to refer to a function that users might expect to find
+in your package but is not there, providing a work around or pointing
+out that the function is available elsewhere, you can use:
+
+     fn = workaround description
+
+This workaround description will not appear when listing functions in
+the package with `pkg describe' but they will be published in the html
+documentation online.  Workaround descriptions can use any html markup,
+but keep in mind that it will be enclosed in a bold-italic environment.
+For the special case of:
+
+     fn = use <code>alternate expression</code>
+
+the bold-italic is automatically suppressed.  You will need to use
+`<code>' even in references:
+
+     fn = use <a href="someothersite.html"><code>fn</code></a>
+
+Sometimes functions are only partially compatible, in which case you
+can list the non-compatible cases separately.  To refer to another
+function in the package, use `<f>fn</f>'.  For example,
+
+     eig (a, b) = use <f>qz</f>
+
+Since sites may have many missing functions, you can define a macro
+rather than typing the same link over and again.
+
+     $id = expansion
+
+defines the macro id.  You can use `$id' anywhere in the description
+and it will be expanded.  For example,
+
+     $TSA = see <a href="link_to_spctools">SPC Tools</a>
+     arcov = $TSA <code>armcv</code>
+
+id is any string of letters, numbers and `_'.
+
+
+File: octave.info,  Node: PKG_ADD and PKG_DEL directives,  Prev: The INDEX file,  Up: Creating Packages
+
+35.4.3 PKG_ADD and PKG_DEL directives
+-------------------------------------
+
+If the package contains files called `PKG_ADD' or `PKG_DEL' the
+commands in these files will be executed when the package is added or
+removed from the users path.  In some situations such files are a bit
+cumbersome to maintain, so the package manager supports automatic
+creation of such files.  If a source file in the package contains a
+`PKG_ADD' or `PKG_DEL' directive they will be added to either the
+`PKG_ADD' or `PKG_DEL' files.
+
+   In `m'-files a `PKG_ADD' directive looks like this
+
+     ## PKG_ADD: some_octave_command
+
+Such lines should be added before the `function' keyword.  In C++ files
+a `PKG_ADD' directive looks like this
+
+     // PKG_ADD: some_octave_command
+
+In both cases `some_octave_command' should be replaced by the command
+that should be placed in the `PKG_ADD' file.  `PKG_DEL' directives work
+in the same way, except the `PKG_ADD' keyword is replaced with
+`PKG_DEL' and the commands get added to the `PKG_DEL' file.
+
+
+File: octave.info,  Node: Dynamically Linked Functions,  Next: Test and Demo Functions,  Prev: Packages,  Up: Top
+
+Appendix A Dynamically Linked Functions
+***************************************
+
+Octave has the possibility of including compiled code as dynamically
+linked extensions and then using these extensions as if they were part
+of Octave itself.  Octave can call C++ code through its native oct-file
+interface or C code through its mex interface.  It can also indirectly
+call functions written in any other language through a simple wrapper.
+The reasons to write code in a compiled language might be either to
+link to an existing piece of code and allow it to be used within
+Octave, or to allow improved performance for key pieces of code.
+
+   Before going further, you should first determine if you really need
+to use dynamically linked functions at all.  Before proceeding with
+writing any dynamically linked function to improve performance you
+should address ask yourself
+
+   * Can I get the same functionality using the Octave scripting
+     language only?
+
+   * Is it thoroughly optimized Octave code?  Vectorization of Octave
+     code, doesn't just make it concise, it generally significantly
+     improves its performance.  Above all, if loops must be used, make
+     sure that the allocation of space for variables takes place
+     outside the loops using an assignment to a matrix of the right
+     size, or zeros.
+
+   * Does it make as much use as possible of existing built-in library
+     routines?  These are highly optimized and many do not carry the
+     overhead of being interpreted.
+
+   * Does writing a dynamically linked function represent useful
+     investment of your time, relative to staying in Octave?
+
+   Also, as oct- and mex-files are dynamically linked to Octave, they
+introduce the possibility of Octave crashing due to errors in the user
+code.  For example a segmentation violation in the user's code will
+cause Octave to abort.
+
+* Menu:
+
+* Oct-Files::
+* Mex-Files::
+* Standalone Programs::
+
+
+File: octave.info,  Node: Oct-Files,  Next: Mex-Files,  Up: Dynamically Linked Functions
+
+A.1 Oct-Files
+=============
+
+* Menu:
+
+* Getting Started with Oct-Files::
+* Matrices and Arrays in Oct-Files::
+* Character Strings in Oct-Files::
+* Cell Arrays in Oct-Files::
+* Structures in Oct-Files::
+* Sparse Matrices in Oct-Files::
+* Accessing Global Variables in Oct-Files::
+* Calling Octave Functions from Oct-Files::
+* Calling External Code from Oct-Files::
+* Allocating Local Memory in Oct-Files::
+* Input Parameter Checking in Oct-Files::
+* Exception and Error Handling in Oct-Files::
+* Documentation and Test of Oct-Files::
+
+
+File: octave.info,  Node: Getting Started with Oct-Files,  Next: Matrices and Arrays in Oct-Files,  Up: Oct-Files
+
+A.1.1 Getting Started with Oct-Files
+------------------------------------
+
+The basic command to build oct-files is `mkoctfile' and it can be call
+from within octave or from the command line.
+
+ -- Function File:  mkoctfile [-options] file ...
+     The `mkoctfile' function compiles source code written in C, C++,
+     or Fortran.  Depending on the options used with `mkoctfile', the
+     compiled code can be called within Octave or can be used as a
+     stand-alone application.
+
+     `mkoctfile' can be called from the shell prompt or from the Octave
+     prompt.
+
+     `mkoctfile' accepts the following options, all of which are
+     optional except for the file name of the code you wish to compile:
+
+    `-I DIR'
+          Add the include directory DIR to compile commands.
+
+    `-D DEF'
+          Add the definition DEF to the compiler call.
+
+    `-l LIB'
+          Add the library LIB to the link command.
+
+    `-L DIR'
+          Add the library directory DIR to the link command.
+
+    `-M'
+    `--depend'
+          Generate dependency files (.d) for C and C++ source files.
+
+    `-c'
+          Compile but do not link.
+
+    `-g'
+          Enable debugging options for compilers.
+
+    `-o FILE'
+    `--output FILE'
+          Output file name.  Default extension is .oct (or .mex if -mex
+          is specified) unless linking a stand-alone executable.
+
+    `-p VAR'
+    `--print VAR'
+          Print the configuration variable VAR.  Recognized variables
+          are:
+
+                  ALL_CFLAGS                FFTW_LIBS
+                  ALL_CXXFLAGS              FLIBS
+                  ALL_FFLAGS                FPICFLAG
+                  ALL_LDFLAGS               INCFLAGS
+                  BLAS_LIBS                 LDFLAGS
+                  CC                        LD_CXX
+                  CFLAGS                    LD_STATIC_FLAG
+                  CPICFLAG                  LFLAGS
+                  CPPFLAGS                  LIBCRUFT
+                  CXX                       LIBOCTAVE
+                  CXXFLAGS                  LIBOCTINTERP
+                  CXXPICFLAG                LIBREADLINE
+                  DEPEND_EXTRA_SED_PATTERN  LIBS
+                  DEPEND_FLAGS              OCTAVE_LIBS
+                  DL_LD                     RDYNAMIC_FLAG
+                  DL_LDFLAGS                RLD_FLAG
+                  F2C                       SED
+                  F2CFLAGS                  XTRA_CFLAGS
+                  F77                       XTRA_CXXFLAGS
+                  FFLAGS
+
+    `--link-stand-alone'
+          Link a stand-alone executable file.
+
+    `--mex'
+          Assume we are creating a MEX file.  Set the default output
+          extension to ".mex".
+
+    `-s'
+    `--strip'
+          Strip the output file.
+
+    `-v'
+    `--verbose'
+          Echo commands as they are executed.
+
+    `file'
+          The file to compile or link.  Recognized file types are
+
+                                 .c    C source
+                                 .cc   C++ source
+                                 .C    C++ source
+                                 .cpp  C++ source
+                                 .f    Fortran source
+                                 .F    Fortran source
+                                 .o    object file
+
+
+   Consider the short example
+
+     #include <octave/oct.h>
+
+     DEFUN_DLD (helloworld, args, nargout,
+       "Hello World Help String")
+     {
+       int nargin = args.length ();
+       octave_stdout << "Hello World has " << nargin
+             << " input arguments and "
+             << nargout << " output arguments.\n";
+       return octave_value_list ();
+     }
+
+   This example although short introduces the basics of writing a C++
+function that can be dynamically linked to Octave.  The easiest way to
+make available most of the definitions that might be necessary for an
+oct-file in Octave is to use the `#include <octave/oct.h>' header.
+
+   The macro that defines the entry point into the dynamically loaded
+function is `DEFUN_DLD'.  This macro takes four arguments, these being
+
+  1. The function name as it will be seen in Octave,
+
+  2. The list of arguments to the function of type `octave_value_list',
+
+  3. The number of output arguments, which can and often is omitted if
+     not used, and
+
+  4. The string that will be seen as the help text of the function.
+
+   The return type of functions defined with `DEFUN_DLD' is always
+`octave_value_list'.
+
+   There are a couple of important considerations in the choice of
+function name.  Firstly, it must be a valid Octave function name and so
+must be a sequence of letters, digits and underscores, not starting
+with a digit.  Secondly, as Octave uses the function name to define the
+filename it attempts to find the function in, the function name in the
+`DEFUN_DLD' macro must match the filename of the oct-file.  Therefore,
+the above function should be in a file `helloworld.cc', and it should be
+compiled to an oct-file using the command
+
+     mkoctfile helloworld.cc
+
+   This will create a file called `helloworld.oct', that is the compiled
+version of the function.  It should be noted that it is perfectly
+acceptable to have more than one `DEFUN_DLD' function in a source file.
+However, there must either be a symbolic link to the oct-file for each
+of the functions defined in the source code with the `DEFUN_DLD' macro
+or the autoload (*note Function Files::) function should be used.
+
+   The rest of this function then shows how to find the number of input
+arguments, how to print through the octave pager, and return from the
+function.  After compiling this function as above, an example of its use
+is
+
+     helloworld (1, 2, 3)
+     -| Hello World has 3 input arguments and 0 output arguments.
+
+
+File: octave.info,  Node: Matrices and Arrays in Oct-Files,  Next: Character Strings in Oct-Files,  Prev: Getting Started with Oct-Files,  Up: Oct-Files
+
+A.1.2 Matrices and Arrays in Oct-Files
+--------------------------------------
+
+Octave supports a number of different array and matrix classes, the
+majority of which are based on the Array class.  The exception is the
+sparse matrix types discussed separately below.  There are three basic
+matrix types
+
+`Matrix'
+     A double precision matrix class defined in dMatrix.h,
+
+`ComplexMatrix'
+     A complex matrix class defined in CMatrix.h, and
+
+`BoolMatrix'
+     A boolean matrix class defined in boolMatrix.h.
+
+   These are the basic two-dimensional matrix types of octave.  In
+additional there are a number of multi-dimensional array types, these
+being
+
+`NDArray'
+     A double precision array class defined in `dNDArray.h'
+
+`ComplexNDarray'
+     A complex array class defined in `CNDArray.h'
+
+`boolNDArray'
+     A boolean array class defined in `boolNDArray.h'
+
+`int8NDArray'
+`int16NDArray'
+`int32NDArray'
+`int64NDArray'
+     8, 16, 32 and 64-bit signed array classes defined in
+     `int8NDArray.h', `int16NDArray.h', etc.
+
+`uint8NDArray'
+`uint16NDArray'
+`uint32NDArray'
+`uint64NDArray'
+     8, 16, 32 and 64-bit unsigned array classes defined in
+     `uint8NDArray.h', `uint16NDArray.h', etc.
+
+   There are several basic means of constructing matrices of
+multi-dimensional arrays.  Considering the `Matrix' type as an example
+
+   * We can create an empty matrix or array with the empty constructor.
+     For example
+
+          Matrix a;
+
+     This can be used on all matrix and array types
+
+   * Define the dimensions of the matrix or array with a dim_vector.
+     For example
+
+          dim_vector dv (2);
+          dv(0) = 2; dv(1) = 2;
+          Matrix a (dv);
+
+     This can be used on all matrix and array types
+
+   * Define the number of rows and columns in the matrix.  For example
+
+          Matrix a (2, 2)
+
+     However, this constructor can only be used with the matrix types.
+
+   These types all share a number of basic methods and operators, a
+selection of which include
+
+ -- Method: T& operator () (octave_idx_type)
+ -- Method: T& elem (octave_idx_type)
+     The `()' operator or `elem' method allow the values of the matrix
+     or array to be read or set.  These can take a single argument,
+     which is of type `octave_idx_type', that is the index into the
+     matrix or array.  Additionally, the matrix type allows two
+     argument versions of the `()' operator and elem method, giving the
+     row and column index of the value to obtain or set.
+
+   Note that these functions do significant error checking and so in
+some circumstances the user might prefer to access the data of the
+array or matrix directly through the fortran_vec method discussed below.
+
+ -- Method: octave_idx_type nelem (void) const
+     The total number of elements in the matrix or array.
+
+ -- Method: size_t byte_size (void) const
+     The number of bytes used to store the matrix or array.
+
+ -- Method: dim_vector dims (void) const
+     The dimensions of the matrix or array in value of type dim_vector.
+
+ -- Method: void resize (const dim_vector&)
+     A method taking either an argument of type `dim_vector', or in the
+     case of a matrix two arguments of type `octave_idx_type' defining
+     the number of rows and columns in the matrix.
+
+ -- Method: T* fortran_vec (void)
+     This method returns a pointer to the underlying data of the matrix
+     or a array so that it can be manipulated directly, either within
+     Octave or by an external library.
+
+   Operators such an `+', `-', or `*' can be used on the majority of
+the above types.  In addition there are a number of methods that are of
+interest only for matrices such as `transpose', `hermitian', `solve',
+etc.
+
+   The typical way to extract a matrix or array from the input
+arguments of `DEFUN_DLD' function is as follows
+
+     #include <octave/oct.h>
+
+     DEFUN_DLD (addtwomatrices, args, , "Add A to B")
+     {
+       int nargin = args.length ();
+       if (nargin != 2)
+         print_usage ();
+       else
+         {
+           NDArray A = args(0).array_value ();
+           NDArray B = args(1).array_value ();
+           if (! error_state)
+             return octave_value (A + B);
+         }
+       return octave_value_list ();
+     }
+
+   To avoid segmentation faults causing Octave to abort, this function
+explicitly checks that there are sufficient arguments available before
+accessing these arguments.  It then obtains two multi-dimensional arrays
+of type `NDArray' and adds these together.  Note that the array_value
+method is called without using the `is_matrix_type' type, and instead
+the error_state is checked before returning `A + B'.  The reason to
+prefer this is that the arguments might be a type that is not an
+`NDArray', but it would make sense to convert it to one.  The
+`array_value' method allows this conversion to be performed
+transparently if possible, and sets `error_state' if it is not.
+
+   `A + B', operating on two `NDArray''s returns an `NDArray', which is
+cast to an `octave_value' on the return from the function.  An example
+of the use of this demonstration function is
+
+     addtwomatrices (ones (2, 2), ones (2, 2))
+           =>  2  2
+               2  2
+
+   A list of the basic `Matrix' and `Array' types, the methods to
+extract these from an `octave_value' and the associated header is
+listed below.
+
+`RowVector'            `row_vector_value'            `dRowVector.h'
+`ComplexRowVector'     `complex_row_vector_value'    `CRowVector.h'
+`ColumnVector'         `column_vector_value'         `dColVector.h'
+`ComplexColumnVector'  `complex_column_vector_value' `CColVector.h'
+`Matrix'               `matrix_value'                `dMatrix.h'
+`ComplexMatrix'        `complex_matrix_value'        `CMatrix.h'
+`boolMatrix'           `bool_matrix_value'           `boolMatrix.h'
+`charMatrix'           `char_matrix_value'           `chMatrix.h'
+`NDArray'              `array_value'                 `dNDArray.h'
+`ComplexNDArray'       `complex_array_value'         `CNDArray.h'
+`boolNDArray'          `bool_array_value'            `boolNDArray.h'
+`charNDArray'          `char_array_value'            `charNDArray.h'
+`int8NDArray'          `int8_array_value'            `int8NDArray.h'
+`int16NDArray'         `int16_array_value'           `int16NDArray.h'
+`int32NDArray'         `int32_array_value'           `int32NDArray.h'
+`int64NDArray'         `int64_array_value'           `int64NDArray.h'
+`uint8NDArray'         `uint8_array_value'           `uint8NDArray.h'
+`uint16NDArray'        `uint16_array_value'          `uint16NDArray.h'
+`uint32NDArray'        `uint32_array_value'          `uint32NDArray.h'
+`uint64NDArray'        `uint64_array_value'          `uint64NDArray.h'
+
+
+File: octave.info,  Node: Character Strings in Oct-Files,  Next: Cell Arrays in Oct-Files,  Prev: Matrices and Arrays in Oct-Files,  Up: Oct-Files
+
+A.1.3 Character Strings in Oct-Files
+------------------------------------
+
+In Octave a character string is just a special `Array' class.  Consider
+the example
+
+     #include <octave/oct.h>
+
+     DEFUN_DLD (stringdemo, args, , "String Demo")
+     {
+       int nargin = args.length();
+       octave_value_list retval;
+
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           charMatrix ch = args(0).char_matrix_value ();
+
+           if (! error_state)
+             {
+               if (args(0).is_sq_string ())
+                 retval(1) = octave_value (ch, true);
+               else
+                 retval(1) = octave_value (ch, true, '\'');
+
+               octave_idx_type nr = ch.rows();
+               for (octave_idx_type i = 0; i < nr / 2; i++)
+                 {
+                   std::string tmp = ch.row_as_string (i);
+                   ch.insert (ch.row_as_string(nr-i-1).c_str(),
+     			 i, 0);
+                   ch.insert (tmp.c_str(), nr-i-1, 0);
+                 }
+               retval(0) = octave_value (ch, true);
+             }
+         }
+       return retval;
+     }
+
+   An example of the use of this function is
+
+     s0 = ["First String"; "Second String"];
+     [s1,s2] = stringdemo (s0)
+     => s1 = Second String
+             First String
+
+     => s2 = First String
+             Second String
+
+     typeinfo (s2)
+     => sq_string
+     typeinfo (s1)
+     => string
+
+   One additional complication of strings in Octave is the difference
+between single quoted and double quoted strings.  To find out if an
+`octave_value' contains a single or double quoted string an example is
+
+         if (args(0).is_sq_string ())
+           octave_stdout <<
+             "First argument is a singularly quoted string\n";
+         else if (args(0).is_dq_string ())
+           octave_stdout <<
+             "First argument is a doubly quoted string\n";
+
+   Note however, that both types of strings are represented by the
+`charNDArray' type, and so when assigning to an `octave_value', the
+type of string should be specified.  For example
+
+     octave_value_list retval;
+     charNDArray c;
+     ...
+     // Create single quoted string
+     retval(1) = octave_value (ch, true, '\'');
+
+     // Create a double quoted string
+     retval(0) = octave_value (ch, true);
+
+
+File: octave.info,  Node: Cell Arrays in Oct-Files,  Next: Structures in Oct-Files,  Prev: Character Strings in Oct-Files,  Up: Oct-Files
+
+A.1.4 Cell Arrays in Oct-Files
+------------------------------
+
+Octave's cell type is equally accessible within oct-files.  A cell
+array is just an array of `octave_value's, and so each element of the
+cell array can then be treated just like any other `octave_value'.  A
+simple example is
+
+     #include <octave/oct.h>
+     #include <octave/Cell.h>
+
+     DEFUN_DLD (celldemo, args, , "Cell Demo")
+     {
+       octave_value_list retval;
+       int nargin = args.length ();
+
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           Cell c = args (0).cell_value ();
+           if (! error_state)
+             for (octave_idx_type i = 0; i < c.nelem (); i++)
+               retval(i) = c.elem (i);
+         }
+
+       return retval;
+     }
+
+   Note that cell arrays are used less often in standard oct-files and
+so the `Cell.h' header file must be explicitly included.  The rest of
+this example extracts the `octave_value's one by one from the cell
+array and returns be as individual return arguments.  For example
+consider
+
+     [b1, b2, b3] = celldemo ({1, [1, 2], "test"})
+     =>
+     b1 =  1
+     b2 =
+
+        1   2
+
+     b3 = test
+
+
+File: octave.info,  Node: Structures in Oct-Files,  Next: Sparse Matrices in Oct-Files,  Prev: Cell Arrays in Oct-Files,  Up: Oct-Files
+
+A.1.5 Structures in Oct-Files
+-----------------------------
+
+A structure in Octave is map between a number of fields represented and
+their values.  The Standard Template Library `map' class is used, with
+the pair consisting of a `std::string' and an octave `Cell' variable.
+
+   A simple example demonstrating the use of structures within
+oct-files is
+
+     #include <octave/oct.h>
+     #include <octave/ov-struct.h>
+
+     DEFUN_DLD (structdemo, args, , "Struct demo.")
+     {
+       int nargin = args.length ();
+       octave_value retval;
+
+       if (nargin != 2)
+         print_usage ();
+       else
+         {
+           Octave_map arg0 = args(0).map_value ();
+           std::string arg1 = args(1).string_value ();
+
+           if (! error_state && arg0.contains (arg1))
+             {
+               // The following two lines might be written as
+               //    octave_value tmp;
+               //    for (Octave_map::iterator p0 =
+     	  //        arg0.begin();
+               //        p0 != arg0.end(); p0++ )
+               //      if (arg0.key (p0) == arg1)
+               //        {
+               //          tmp = arg0.contents (p0) (0);
+               //          break;
+               //        }
+               // though using seek is more concise.
+               Octave_map::const_iterator p1 = arg0.seek (arg1);
+               octave_value tmp =  arg0.contents(p1)(0);
+               Octave_map st;
+               st.assign ("selected", tmp);
+               retval = octave_value (st);
+             }
+         }
+       return retval;
+     }
+
+   An example of its use is
+
+     x.a = 1; x.b = "test"; x.c = [1, 2];
+     structdemo (x, "b")
+     => selected = test
+
+   The commented code above demonstrates how to iterate over all of the
+fields of the structure, where as the following code demonstrates
+finding a particular field in a more concise manner.
+
+   As can be seen the `contents' method of the `Octave_map' class
+returns a `Cell' which allows structure arrays to be represented.
+Therefore, to obtain the underlying `octave_value' we write
+
+     octave_value tmp = arg0.contents (p1) (0);
+
+   where the trailing (0) is the () operator on the `Cell' object.  We
+can equally iterate of the elements of the Cell array to address the
+elements of the structure array.
+
+
+File: octave.info,  Node: Sparse Matrices in Oct-Files,  Next: Accessing Global Variables in Oct-Files,  Prev: Structures in Oct-Files,  Up: Oct-Files
+
+A.1.6 Sparse Matrices in Oct-Files
+----------------------------------
+
+There are three classes of sparse objects that are of interest to the
+user.
+
+`SparseMatrix'
+     A double precision sparse matrix class
+
+`SparseComplexMatrix'
+     A complex sparse matrix class
+
+`SparseBoolMatrix'
+     A boolean sparse matrix class
+
+   All of these classes inherit from the `Sparse<T>' template class,
+and so all have similar capabilities and usage.  The `Sparse<T>' class
+was based on Octave `Array<T>' class, and so users familiar with
+Octave's `Array' classes will be comfortable with the use of the sparse
+classes.
+
+   The sparse classes will not be entirely described in this section,
+due to their similarity with the existing `Array' classes.  However,
+there are a few differences due the different nature of sparse objects,
+and these will be described.  Firstly, although it is fundamentally
+possible to have N-dimensional sparse objects, the Octave sparse
+classes do not allow them at this time.  So all operations of the
+sparse classes must be 2-dimensional.  This means that in fact
+`SparseMatrix' is similar to Octave's `Matrix' class rather than its
+`NDArray' class.
+
+* Menu:
+
+* Array and Sparse Differences::
+* Creating Sparse Matrices in Oct-Files::
+* Using Sparse Matrices in Oct-Files::
+
+
+File: octave.info,  Node: Array and Sparse Differences,  Next: Creating Sparse Matrices in Oct-Files,  Up: Sparse Matrices in Oct-Files
+
+A.1.6.1 The Differences between the Array and Sparse Classes
+............................................................
+
+The number of elements in a sparse matrix is considered to be the number
+of non-zero elements rather than the product of the dimensions.
+Therefore
+
+     SparseMatrix sm;
+     ...
+     int nel = sm.nelem ();
+
+   returns the number of non-zero elements.  If the user really
+requires the number of elements in the matrix, including the non-zero
+elements, they should use `numel' rather than `nelem'.  Note that for
+very large matrices, where the product of the two dimensions is larger
+than the representation of an unsigned int, then `numel' can overflow.
+An example is `speye(1e6)' which will create a matrix with a million
+rows and columns, but only a million non-zero elements.  Therefore the
+number of rows by the number of columns in this case is more than two
+hundred times the maximum value that can be represented by an unsigned
+int.  The use of `numel' should therefore be avoided useless it is known
+it won't overflow.
+
+   Extreme care must be take with the elem method and the "()" operator,
+which perform basically the same function.  The reason is that if a
+sparse object is non-const, then Octave will assume that a request for
+a zero element in a sparse matrix is in fact a request to create this
+element so it can be filled.  Therefore a piece of code like
+
+     SparseMatrix sm;
+     ...
+     for (int j = 0; j < nc; j++)
+       for (int i = 0; i < nr; i++)
+         std::cerr << " (" << i << "," << j << "): " << sm(i,j)
+                   << std::endl;
+
+   is a great way of turning the sparse matrix into a dense one, and a
+very slow way at that since it reallocates the sparse object at each
+zero element in the matrix.
+
+   An easy way of preventing the above from happening is to create a
+temporary constant version of the sparse matrix.  Note that only the
+container for the sparse matrix will be copied, while the actual
+representation of the data will be shared between the two versions of
+the sparse matrix.  So this is not a costly operation.  For example,
+the above would become
+
+     SparseMatrix sm;
+     ...
+     const SparseMatrix tmp (sm);
+     for (int j = 0; j < nc; j++)
+       for (int i = 0; i < nr; i++)
+         std::cerr << " (" << i << "," << j << "): " << tmp(i,j)
+                   << std::endl;
+
+   Finally, as the sparse types aren't just represented as a contiguous
+block of memory, the `fortran_vec' method of the `Array<T>' is not
+available.  It is however replaced by three separate methods `ridx',
+`cidx' and `data', that access the raw compressed column format that
+the Octave sparse matrices are stored in.  Additionally, these methods
+can be used in a manner similar to `elem', to allow the matrix to be
+accessed or filled.  However, in that case it is up to the user to
+respect the sparse matrix compressed column format discussed previous.
+
+
+File: octave.info,  Node: Creating Sparse Matrices in Oct-Files,  Next: Using Sparse Matrices in Oct-Files,  Prev: Array and Sparse Differences,  Up: Sparse Matrices in Oct-Files
+
+A.1.6.2 Creating Sparse Matrices in Oct-Files
+.............................................
+
+You have several alternatives for creating a sparse matrix.  You can
+first create the data as three vectors representing the row and column
+indexes and the data, and from those create the matrix.  Or
+alternatively, you can create a sparse matrix with the appropriate
+amount of space and then fill in the values.  Both techniques have their
+advantages and disadvantages.
+
+   Here is an example of how to create a small sparse matrix with the
+first technique
+
+     int nz = 4, nr = 3, nc = 4;
+
+     ColumnVector ridx (nz);
+     ColumnVector cidx (nz);
+     ColumnVector data (nz);
+
+     ridx(0) = 0; ridx(1) = 0; ridx(2) = 1; ridx(3) = 2;
+     cidx(0) = 0; cidx(1) = 1; cidx(2) = 3; cidx(3) = 3;
+     data(0) = 1; data(1) = 2; data(2) = 3; data(3) = 4;
+
+     SparseMatrix sm (data, ridx, cidx, nr, nc);
+
+which creates the matrix given in section *note Storage of Sparse
+Matrices::.  Note that the compressed matrix format is not used at the
+time of the creation of the matrix itself, however it is used
+internally.
+
+   As previously mentioned, the values of the sparse matrix are stored
+in increasing column-major ordering.  Although the data passed by the
+user does not need to respect this requirement, the pre-sorting the
+data significantly speeds up the creation of the sparse matrix.
+
+   The disadvantage of this technique of creating a sparse matrix is
+that there is a brief time where two copies of the data exists.
+Therefore for extremely memory constrained problems this might not be
+the right technique to create the sparse matrix.
+
+   The alternative is to first create the sparse matrix with the desired
+number of non-zero elements and then later fill those elements in.  The
+easiest way to do this is
+
+     int nz = 4, nr = 3, nc = 4;
+     SparseMatrix sm (nr, nc, nz);
+     sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+
+   That creates the same matrix as previously.  Again, although it is
+not strictly necessary, it is significantly faster if the sparse matrix
+is created in this manner that the elements are added in column-major
+ordering.  The reason for this is that if the elements are inserted at
+the end of the current list of known elements then no element in the
+matrix needs to be moved to allow the new element to be inserted.  Only
+the column indexes need to be updated.
+
+   There are a few further points to note about this technique of
+creating a sparse matrix.  Firstly, it is possible to create a sparse
+matrix with fewer elements than are actually inserted in the matrix.
+Therefore
+
+     int nz = 4, nr = 3, nc = 4;
+     SparseMatrix sm (nr, nc, 0);
+     sm(0,0) = 1; sm(0,1) = 2; sm(1,3) = 3; sm(2,3) = 4;
+
+is perfectly valid.  However it is a very bad idea.  The reason is that
+as each new element is added to the sparse matrix the space allocated
+to it is increased by reallocating the memory.  This is an expensive
+operation, that will significantly slow this means of creating a sparse
+matrix.  Furthermore, it is possible to create a sparse matrix with too
+much storage, so having NZ above equaling 6 is also valid.  The
+disadvantage is that the matrix occupies more memory than strictly
+needed.
+
+   It is not always easy to know the number of non-zero elements prior
+to filling a matrix.  For this reason the additional storage for the
+sparse matrix can be removed after its creation with the
+"maybe_compress" function.  Furthermore, the maybe_compress can
+deallocate the unused storage, but it can equally remove zero elements
+from the matrix.  The removal of zero elements from the matrix is
+controlled by setting the argument of the "maybe_compress" function to
+be `true'.  However, the cost of removing the zeros is high because it
+implies resorting the elements.  Therefore, if possible it is better is
+the user doesn't add the zeros in the first place.  An example of the
+use of "maybe_compress" is
+
+       int nz = 6, nr = 3, nc = 4;
+
+       SparseMatrix sm1 (nr, nc, nz);
+       sm1(0,0) = 1; sm1(0,1) = 2; sm1(1,3) = 3; sm1(2,3) = 4;
+       sm1.maybe_compress ();  // No zero elements were added
+
+       SparseMatrix sm2 (nr, nc, nz);
+       sm2(0,0) = 1; sm2(0,1) = 2; sm(0,2) = 0; sm(1,2) = 0;
+       sm1(1,3) = 3; sm1(2,3) = 4;
+       sm2.maybe_compress (true);  // Zero elements were added
+
+   The use of the "maybe_compress" function should be avoided if
+possible, as it will slow the creation of the matrices.
+
+   A third means of creating a sparse matrix is to work directly with
+the data in compressed row format.  An example of this technique might
+be
+
+     octave_value arg;
+     ...
+     int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+     SparseMatrix sm (nr, nc, nz);
+     Matrix m = arg.matrix_value ();
+
+     int ii = 0;
+     sm.cidx (0) = 0;
+     for (int j = 1; j < nc; j++)
+       {
+         for (int i = 0; i < nr; i++)
+           {
+             double tmp = foo (m(i,j));
+             if (tmp != 0.)
+               {
+                 sm.data(ii) = tmp;
+                 sm.ridx(ii) = i;
+                 ii++;
+               }
+           }
+         sm.cidx(j+1) = ii;
+      }
+     sm.maybe_compress ();  // If don't know a-priori
+                            // the final no of nz.
+
+which is probably the most efficient means of creating the sparse
+matrix.
+
+   Finally, it might sometimes arise that the amount of storage
+initially created is insufficient to completely store the sparse
+matrix.  Therefore, the method `change_capacity' exists to reallocate
+the sparse memory.  The above example would then be modified as
+
+     octave_value arg;
+     ...
+     int nz = 6, nr = 3, nc = 4;   // Assume we know the max no nz
+     SparseMatrix sm (nr, nc, nz);
+     Matrix m = arg.matrix_value ();
+
+     int ii = 0;
+     sm.cidx (0) = 0;
+     for (int j = 1; j < nc; j++)
+       {
+         for (int i = 0; i < nr; i++)
+           {
+             double tmp = foo (m(i,j));
+             if (tmp != 0.)
+               {
+                 if (ii == nz)
+                   {
+                     nz += 2;   // Add 2 more elements
+                     sm.change_capacity (nz);
+                   }
+                 sm.data(ii) = tmp;
+                 sm.ridx(ii) = i;
+                 ii++;
+               }
+           }
+         sm.cidx(j+1) = ii;
+      }
+     sm.maybe_mutate ();  // If don't know a-priori
+                          // the final no of nz.
+
+   Note that both increasing and decreasing the number of non-zero
+elements in a sparse matrix is expensive, as it involves memory
+reallocation.  Also as parts of the matrix, though not its entirety,
+exist as the old and new copy at the same time, additional memory is
+needed.  Therefore if possible this should be avoided.
+
+
+File: octave.info,  Node: Using Sparse Matrices in Oct-Files,  Prev: Creating Sparse Matrices in Oct-Files,  Up: Sparse Matrices in Oct-Files
+
+A.1.6.3 Using Sparse Matrices in Oct-Files
+..........................................
+
+Most of the same operators and functions on sparse matrices that are
+available from the Octave are equally available with oct-files.  The
+basic means of extracting a sparse matrix from an `octave_value' and
+returning them as an `octave_value', can be seen in the following
+example
+
+     octave_value_list retval;
+
+     SparseMatrix sm = args(0).sparse_matrix_value ();
+     SparseComplexMatrix scm =
+         args(1).sparse_complex_matrix_value ();
+     SparseBoolMatrix sbm = args(2).sparse_bool_matrix_value ();
+     ...
+     retval(2) = sbm;
+     retval(1) = scm;
+     retval(0) = sm;
+
+   The conversion to an octave-value is handled by the sparse
+`octave_value' constructors, and so no special care is needed.
+
+
+File: octave.info,  Node: Accessing Global Variables in Oct-Files,  Next: Calling Octave Functions from Oct-Files,  Prev: Sparse Matrices in Oct-Files,  Up: Oct-Files
+
+A.1.7 Accessing Global Variables in Oct-Files
+---------------------------------------------
+
+Global variables allow variables in the global scope to be accessed.
+Global variables can easily be accessed with oct-files using the
+support functions `get_global_value' and `set_global_value'.
+`get_global_value' takes two arguments, the first is a string
+representing the variable name to obtain.  The second argument is a
+boolean argument specifying what to do in the case that no global
+variable of the desired name is found.  An example of the use of these
+two functions is
+
+     #include <octave/oct.h>
+
+     DEFUN_DLD (globaldemo, args, , "Global demo.")
+     {
+       int nargin = args.length ();
+       octave_value retval;
+
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           std::string s = args(0).string_value ();
+           if (! error_state)
+             {
+               octave_value tmp = get_global_value (s, true);
+               if (tmp.is_defined ())
+                 retval = tmp;
+               else
+                 retval = "Global variable not found";
+
+               set_global_value ("a", 42.0);
+             }
+         }
+       return retval;
+     }
+
+   An example of its use is
+
+     global a b
+     b = 10;
+     globaldemo ("b")
+     => 10
+     globaldemo ("c")
+     => "Global variable not found"
+     num2str (a)
+     => 42
+
+
+File: octave.info,  Node: Calling Octave Functions from Oct-Files,  Next: Calling External Code from Oct-Files,  Prev: Accessing Global Variables in Oct-Files,  Up: Oct-Files
+
+A.1.8 Calling Octave Functions from Oct-Files
+---------------------------------------------
+
+There is often a need to be able to call another octave function from
+within an oct-file, and there are many examples of such within octave
+itself.  For example the `quad' function is an oct-file that calculates
+the definite integral by quadrature over a user supplied function.
+
+   There are also many ways in which a function might be passed.  It
+might be passed as one of
+
+  1. Function Handle
+
+  2. Anonymous Function Handle
+
+  3. Inline Function
+
+  4. String
+
+   The example below demonstrates an example that accepts all four
+means of passing a function to an oct-file.
+
+     #include <octave/oct.h>
+     #include <octave/parse.h>
+
+     DEFUN_DLD (funcdemo, args, nargout, "Function Demo")
+     {
+       int nargin = args.length();
+       octave_value_list retval;
+
+       if (nargin < 2)
+         print_usage ();
+       else
+         {
+           octave_value_list newargs;
+           for (octave_idx_type i = nargin - 1; i > 0; i--)
+             newargs (i - 1) = args(i);
+           if (args(0).is_function_handle ()
+               || args(0).is_inline_function ())
+             {
+               octave_function *fcn = args(0).function_value ();
+               if (! error_state)
+                 retval = feval (fcn, newargs, nargout);
+             }
+           else if (args(0).is_string ())
+             {
+               std::string fcn = args (0).string_value ();
+               if (! error_state)
+                 retval = feval (fcn, newargs, nargout);
+             }
+           else
+             error ("funcdemo: expected string,",
+     	       " inline or function handle");
+         }
+       return retval;
+     }
+
+   The first argument to this demonstration is the user supplied
+function and the following arguments are all passed to the user
+function.
+
+     funcdemo (@sin,1)
+     => 0.84147
+     funcdemo (@(x) sin(x), 1)
+     => 0.84147
+     funcdemo (inline ("sin(x)"), 1)
+     => 0.84147
+     funcdemo ("sin",1)
+     => 0.84147
+     funcdemo (@atan2, 1, 1)
+     => 0.78540
+
+   When the user function is passed as a string, the treatment of the
+function is different.  In some cases it is necessary to always have the
+user supplied function as an `octave_function' object.  In that case
+the string argument can be used to create a temporary function like
+
+     std::octave fcn_name = unique_symbol_name ("__fcn__");
+     std::string fname = "function y = ";
+     fname.append (fcn_name);
+     fname.append ("(x) y = ");
+     fcn = extract_function (args(0), "funcdemo", fcn_name,
+                             fname, "; endfunction");
+     ...
+     if (fcn_name.length ())
+       clear_function (fcn_name);
+
+   There are two important things to know in this case.  The number of
+input arguments to the user function is fixed, and in the above is a
+single argument, and secondly to avoid leaving the temporary function
+in the Octave symbol table it should be cleared after use.
+
+
+File: octave.info,  Node: Calling External Code from Oct-Files,  Next: Allocating Local Memory in Oct-Files,  Prev: Calling Octave Functions from Oct-Files,  Up: Oct-Files
+
+A.1.9 Calling External Code from Oct-Files
+------------------------------------------
+
+Linking external C code to Octave is relatively simple, as the C
+functions can easily be called directly from C++.  One possible issue is
+the declarations of the external C functions might need to be explicitly
+defined as C functions to the compiler.  If the declarations of the
+external C functions are in the header `foo.h', then the manner in
+which to ensure that the C++ compiler treats these declarations as C
+code is
+
+     #ifdef __cplusplus
+     extern "C"
+     {
+     #endif
+     #include "foo.h"
+     #ifdef __cplusplus
+     }  /* end extern "C" */
+     #endif
+
+   Calling Fortran code however can pose some difficulties.  This is
+due to differences in the manner in compilers treat the linking of
+Fortran code with C or C++ code.  Octave supplies a number of macros
+that allow consistent behavior across a number of compilers.
+
+   The underlying Fortran code should use the `XSTOPX' function to
+replace the Fortran `STOP' function.  `XSTOPX' uses the Octave
+exception handler to treat failing cases in the fortran code
+explicitly.  Note that Octave supplies its own replacement BLAS
+`XERBLA' function, which uses `XSTOPX'.
+
+   If the underlying code calls `XSTOPX', then the `F77_XFCN' macro
+should be used to call the underlying fortran function.  The Fortran
+exception state can then be checked with the global variable
+`f77_exception_encountered'.  If `XSTOPX' will not be called, then the
+`F77_FCN' macro should be used instead to call the Fortran code.
+
+   There is no harm in using `F77_XFCN' in all cases, except that for
+Fortran code that is short running and executes a large number of times,
+there is potentially an overhead in doing so.  However, if `F77_FCN' is
+used with code that calls `XSTOP', Octave can generate a segmentation
+fault.
+
+   An example of the inclusion of a Fortran function in an oct-file is
+given in the following example, where the C++ wrapper is
+
+     #include <octave/oct.h>
+     #include <octave/f77-fcn.h>
+
+     extern "C"
+     {
+       F77_RET_T
+       F77_FUNC (fortsub, FORTSUB)
+             (const int&, double*, F77_CHAR_ARG_DECL
+              F77_CHAR_ARG_LEN_DECL);
+     }
+
+     DEFUN_DLD (fortdemo , args , , "Fortran Demo.")
+     {
+       octave_value_list retval;
+       int nargin = args.length();
+       if (nargin != 1)
+         print_usage ();
+       else
+         {
+           NDArray a = args(0).array_value ();
+           if (! error_state)
+             {
+               double *av = a.fortran_vec ();
+               octave_idx_type na = a.nelem ();
+               OCTAVE_LOCAL_BUFFER (char, ctmp, 128);
+
+               F77_XFCN (fortsub, FORTSUB, (na, av, ctmp
+                         F77_CHAR_ARG_LEN (128)));
+
+     	  retval(1) = std::string (ctmp);
+     	  retval(0) = a;
+             }
+         }
+       return retval;
+     }
+
+and the fortran function is
+
+           subroutine fortsub (n, a, s)
+           implicit none
+           character*(*) s
+           real*8 a(*)
+           integer*4 i, n, ioerr
+           do i = 1, n
+             if (a(i) .eq. 0d0) then
+               call xstopx ('fortsub: divide by zero')
+             else
+               a(i) = 1d0 / a(i)
+             endif
+           enddo
+           write (unit = s, fmt = '(a,i3,a,a)', iostat = ioerr)
+          $       'There are ', n,
+          $       ' values in the input vector', char(0)
+           if (ioerr .ne. 0) then
+             call xstopx ('fortsub: error writing string')
+           endif
+           return
+           end
+
+   This example demonstrates most of the features needed to link to an
+external Fortran function, including passing arrays and strings, as well
+as exception handling.  An example of the behavior of this function is
+
+     [b, s] = fortdemo (1:3)
+     =>
+       b = 1.00000   0.50000   0.33333
+       s = There are   3 values in the input vector
+     [b, s] = fortdemo(0:3)
+     error: fortsub:divide by zero
+     error: exception encountered in Fortran subroutine fortsub_
+     error: fortdemo: error in fortran
+
+
+File: octave.info,  Node: Allocating Local Memory in Oct-Files,  Next: Input Parameter Checking in Oct-Files,  Prev: Calling External Code from Oct-Files,  Up: Oct-Files
+
+A.1.10 Allocating Local Memory in Oct-Files
+-------------------------------------------
+
+Allocating memory within an oct-file might seem easy as the C++
+new/delete operators can be used.  However, in that case care must be
+taken to avoid memory leaks.  The preferred manner in which to allocate
+memory for use locally is to use the `OCTAVE_LOCAL_BUFFER' macro.  An
+example of its use is
+
+     OCTAVE_LOCAL_BUFFER (double, tmp, len)
+
+   that returns a pointer `tmp' of type `double *' of length `len'.
+
+
+File: octave.info,  Node: Input Parameter Checking in Oct-Files,  Next: Exception and Error Handling in Oct-Files,  Prev: Allocating Local Memory in Oct-Files,  Up: Oct-Files
+
+A.1.11 Input Parameter Checking in Oct-Files
+--------------------------------------------
+
+As oct-files are compiled functions they have the possibility of causing
+Octave to abort abnormally.  It is therefore important that each and
+every function has the minimum of parameter checking needed to ensure
+that Octave behaves well.
+
+   The minimum requirement, as previously discussed, is to check the
+number of input arguments before using them to avoid referencing a non
+existent argument.  However, it some case this might not be sufficient
+as the underlying code imposes further constraints.  For example an
+external function call might be undefined if the input arguments are not
+integers, or if one of the arguments is zero.  Therefore, oct-files
+often need additional input parameter checking.
+
+   There are several functions within Octave that might be useful for
+the purposes of parameter checking.  These include the methods of the
+octave_value class like `is_real_matrix', etc., but equally include
+more specialized functions.  Some of the more common ones are
+demonstrated in the following example
+
+     #include <octave/oct.h>
+
+     DEFUN_DLD (paramdemo, args, nargout,
+     	   "Parameter Check Demo.")
+     {
+       int nargin = args.length ();
+       octave_value retval;
+
+       if (nargin != 1)
+         print_usage();
+       else if (nargout != 0)
+         error ("paramdemo: function has no output arguments");
+       else
+         {
+           NDArray m = args(0).array_value();
+           double min_val = -10.0;
+           double max_val = 10.0;
+           octave_stdout << "Properties of input array:\n";
+           if (m.any_element_is_negative ())
+             octave_stdout << "  includes negative values\n";
+           if (m.any_element_is_inf_or_nan())
+             octave_stdout << "  includes Inf or NaN values\n";
+           if (m.any_element_not_one_or_zero())
+             octave_stdout <<
+     	  "  includes other values than 1 and 0\n";
+           if (m.all_elements_are_int_or_inf_or_nan())
+             octave_stdout <<
+     	  "  includes only int, Inf or NaN values\n";
+           if (m.all_integers (min_val, max_val))
+             octave_stdout <<
+     	  "  includes only integers in [-10,10]\n";
+         }
+       return retval;
+     }
+
+and an example of its use is
+
+     paramdemo ([1, 2, NaN, Inf])
+     => Properties of input array:
+           includes Inf or NaN values
+           includes other values than 1 and 0
+           includes only int, Inf or NaN values
+
+
+File: octave.info,  Node: Exception and Error Handling in Oct-Files,  Next: Documentation and Test of Oct-Files,  Prev: Input Parameter Checking in Oct-Files,  Up: Oct-Files
+
+A.1.12 Exception and Error Handling in Oct-Files
+------------------------------------------------
+
+Another important feature of Octave is its ability to react to the user
+typing `Control-C' even during calculations.  This ability is based on
+the C++ exception handler, where memory allocated by the C++ new/delete
+methods are automatically released when the exception is treated.  When
+writing an oct-file, to allow Octave to treat the user typing
+`Control-C', the `OCTAVE_QUIT' macro is supplied.  For example
+
+     for (octave_idx_type i = 0; i < a.nelem (); i++)
+       {
+         OCTAVE_QUIT;
+         b.elem(i) = 2. * a.elem(i);
+       }
+
+   The presence of the `OCTAVE_QUIT' macro in the inner loop allows
+Octave to treat the user request with the `Control-C'.  Without this
+macro, the user must either wait for the function to return before the
+interrupt is processed, or press `Control-C' three times to force
+Octave to exit.
+
+   The `OCTAVE_QUIT' macro does impose a very small speed penalty, and
+so for loops that are known to be small it might not make sense to
+include `OCTAVE_QUIT'.
+
+   When creating an oct-file that uses an external libraries, the
+function might spend a significant portion of its time in the external
+library.  It is not generally possible to use the `OCTAVE_QUIT' macro in
+this case.  The alternative in this case is
+
+     BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+     ...  some code that calls a "foreign" function ...
+     END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+   The disadvantage of this is that if the foreign code allocates any
+memory internally, then this memory might be lost during an interrupt,
+without being deallocated.  Therefore, ideally Octave itself should
+allocate any memory that is needed by the foreign code, with either the
+fortran_vec method or the `OCTAVE_LOCAL_BUFFER' macro.
+
+   The Octave unwind_protect mechanism (*note The `unwind_protect'
+Statement::) can also be used in oct-files.  In conjunction with the
+exception handling of Octave, it is important to enforce that certain
+code is run to allow variables, etc. to be restored even if an
+exception occurs.  An example of the use of this mechanism is
+
+     #include <octave/oct.h>
+     #include <octave/unwind-prot.h>
+
+     void
+     err_hand (const char *fmt, ...)
+     {
+       // Do nothing!!
+     }
+
+     DEFUN_DLD (unwinddemo, args, nargout, "Unwind Demo")
+     {
+       int nargin = args.length();
+       octave_value retval;
+       if (nargin < 2)
+         print_usage ();
+       else
+         {
+           NDArray a = args(0).array_value ();
+           NDArray b = args(1).array_value ();
+
+           if (! error_state)
+             {
+               unwind_protect::begin_frame ("Funwinddemo");
+               unwind_protect_ptr
+     	    (current_liboctave_warning_handler);
+               set_liboctave_warning_handler(err_hand);
+               retval = octave_value (quotient (a, b));
+               unwind_protect::run_frame ("Funwinddemo");
+             }
+         }
+       return retval;
+     }
+
+   As can be seen in the example
+
+     unwinddemo (1, 0)
+     => Inf
+     1 / 0
+     => warning: division by zero
+        Inf
+
+   The division by zero (and in fact all warnings) is disabled in the
+`unwinddemo' function.
+
+
+File: octave.info,  Node: Documentation and Test of Oct-Files,  Prev: Exception and Error Handling in Oct-Files,  Up: Oct-Files
+
+A.1.13 Documentation and Test of Oct-Files
+------------------------------------------
+
+The documentation of an oct-file is the fourth string parameter of the
+`DEFUN_DLD' macro.  This string can be formatted in the same manner as
+the help strings for user functions (*note Documentation Tips::),
+however there are some issue that are particular to the formatting of
+help strings within oct-files.
+
+   The major issue is that the help string will typically be longer
+than a single line of text, and so the formatting of long help strings
+need to be taken into account.  There are several manners in which to
+treat this issue, but the most common is illustrated in the following
+example
+
+     DEFUN_DLD (do_what_i_want, args, nargout,
+       "-*- texinfo -*-\n\
+     @deftypefn {Function File} {} do_what_i_say (@var{n})\n\
+     A function that does what the user actually wants rather\n\
+     than what they requested.\n\
+     @end deftypefn")
+     {
+     ...
+     }
+
+where, as can be seen, end line of text within the help string is
+terminated by `\n\' which is an embedded new-line in the string
+together with a C++ string continuation character.  Note that the final
+`\' must be the last character on the line.
+
+   Octave also includes the ability to embed the test and demonstration
+code for a function within the code itself (*note Test and Demo
+Functions::).  This can be used from within oct-files (or in fact any
+file) with certain provisos.  Firstly, the test and demo functions of
+Octave look for a `%!' as the first characters on a new-line to
+identify test and demonstration code.  This is equally a requirement for
+oct-files.  Furthermore the test and demonstration code must be included
+in a comment block of the compiled code to avoid it being interpreted by
+the compiler.  Finally, the Octave test and demonstration code must have
+access to the source code of the oct-file and not just the compiled code
+as the tests are stripped from the compiled code.  An example in an
+oct-file might be
+
+     /*
+
+     %!error (sin())
+     %!error (sin(1,1))
+     %!assert (sin([1,2]),[sin(1),sin(2)])
+
+     */
+
+
+File: octave.info,  Node: Mex-Files,  Next: Standalone Programs,  Prev: Oct-Files,  Up: Dynamically Linked Functions
+
+A.2 Mex-Files
+=============
+
+Octave includes an interface to allow legacy mex-files to be compiled
+and used with Octave.  This interface can also be used to share code
+between Octave and non Octave users.  However, as mex-files expose the
+internal API of an alternative product to Octave, and the internal
+structure of Octave is different to this product, a mex-file can never
+have the same performance in Octave as the equivalent oct-file.  In
+particular to support the manner in which mex-files access the variables
+passed to mex functions, there are a significant number of additional
+copies of memory when calling or returning from a mex function.  For
+this reason, new code should be written using the oct-file interface
+discussed above if possible.
+
+* Menu:
+
+* Getting Started with Mex-Files::
+* Working with Matrices and Arrays in Mex-Files::
+* Character Strings in Mex-Files::
+* Cell Arrays with Mex-Files::
+* Structures with Mex-Files::
+* Sparse Matrices with Mex-Files::
+* Calling Other Functions in Mex-Files::
+
+
+File: octave.info,  Node: Getting Started with Mex-Files,  Next: Working with Matrices and Arrays in Mex-Files,  Up: Mex-Files
+
+A.2.1 Getting Started with Mex-Files
+------------------------------------
+
+The basic command to build a mex-file is either `mkoctfile --mex' or
+`mex'.  The first can either be used from within Octave or from the
+command line.  However, to avoid issues with the installation of other
+products, the use of the command `mex' is limited to within Octave.
+
+ -- Function File:  mex [options] file ...
+     Compile source code written in C, C++, or Fortran, to a MEX file.
+     This is equivalent to `mkoctfile --mex [options] file'.
+
+     *See also:* *note mkoctfile: doc-mkoctfile.
+
+ -- Function File:  mexext ()
+     Return the filename extension used for MEX files.
+
+   One important difference between the use of mex with other products
+and with Octave is that the header file "matrix.h" is implicitly
+included through the inclusion of "mex.h".  This is to avoid a conflict
+with the Octave file "Matrix.h" with operating systems and compilers
+that don't distinguish between filenames in upper and lower case
+
+   Consider the short example
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs,
+     	     const mxArray *prhs[])
+     {
+       mxArray *v = mxCreateDoubleMatrix (1, 1, mxREAL);
+       double *data = mxGetPr (v);
+       *data = 1.23456789;
+       plhs[0] = v;
+     }
+
+   This simple example demonstrates the basics of writing a mex-file.
+The entry point into the mex-file is defined by `mexFunction'.  Note
+that the function name is not explicitly included in the `mexFunction'
+and so there can only be a single `mexFunction' entry point per-file.
+Also the name of the function is determined by the name of the mex-file
+itself.  Therefore if the above function is in the file
+`firstmexdemo.c', it can be compiled with
+
+     mkoctfile --mex firstmexdemo.c
+
+which creates a file `firstmexdemo.mex'.  The function can then be run
+from Octave as
+
+     firstmexdemo()
+     => 1.2346
+
+   It should be noted that the mex-file contains no help string for the
+functions it contains.  To document mex-files, there should exist an
+m-file in the same directory as the mex-file itself.  Taking the above
+as an example, we would therefore have a file `firstmexdemo.m' that
+might contain the text
+
+     %FIRSTMEXDEMO Simple test of the functionality of a mex-file.
+
+   In this case, the function that will be executed within Octave will
+be given by the mex-file, while the help string will come from the
+m-file.  This can also be useful to allow a sample implementation of the
+mex-file within the Octave language itself for testing purposes.
+
+   Although we cannot have multiple entry points into a single mex-file,
+we can use the `mexFunctionName' function to determine what name the
+mex-file was called with.  This can be used to alter the behavior of
+the mex-file based on the function name.  For example if
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs,
+     	     const mxArray *prhs[])
+     {
+       const char *nm;
+       nm = mexFunctionName ();
+       mexPrintf ("You called function: %s\n", nm);
+       if (strcmp (nm, "myfunc") == 0)
+         mexPrintf ("This is the principal function\n", nm);
+       return;
+     }
+
+is in file `myfunc.c', and it is compiled with
+
+     mkoctfile --mex myfunc.c
+     ln -s myfunc.mex myfunc2.mex
+
+   Then as can be seen by
+
+     myfunc()
+     => You called function: myfunc
+         This is the principal function
+     myfunc2()
+     => You called function: myfunc2
+
+the behavior of the mex-file can be altered depending on the functions
+name.
+
+   Allow the user should only include `mex.h' in their code, Octave
+declares additional functions, typedefs, etc., available to the user to
+write mex-files in the headers `mexproto.h' and `mxarray.h'.
+
+
+File: octave.info,  Node: Working with Matrices and Arrays in Mex-Files,  Next: Character Strings in Mex-Files,  Prev: Getting Started with Mex-Files,  Up: Mex-Files
+
+A.2.2 Working with Matrices and Arrays in Mex-Files
+---------------------------------------------------
+
+The basic mex type of all variables is `mxArray'.  All variables, such
+as matrices, cell arrays or structures are all stored in this basic
+type, and this type serves basically the same purpose as the
+octave_value class in oct-files.  That is it acts as a container for the
+more specialized types.
+
+   The `mxArray' structure contains at a minimum, the variable it
+represents name, its dimensions, its type and whether the variable is
+real or complex.  It can however contain a number of additional fields
+depending on the type of the `mxArray'.  There are a number of
+functions to create `mxArray' structures, including
+`mxCreateCellArray', `mxCreateSparse' and the generic
+`mxCreateNumericArray'.
+
+   The basic functions to access the data contained in an array is
+`mxGetPr'.  As the mex interface assumes that the real and imaginary
+parts of a complex array are stored separately, there is an equivalent
+function `mxGetPi' that get the imaginary part.  Both of these
+functions are for use only with double precision matrices.  There also
+exists the generic function `mxGetData' and `mxGetImagData' that
+perform the same operation on all matrix types.  For example
+
+     mxArray *m;
+     mwSize *dims;
+     UINT32_T *pr;
+
+     dims = (mwSize *) mxMalloc (2 * sizeof(mwSize));
+     dims[0] = 2;
+     dims[1] = 2;
+     m = mxCreateNumericArray (2, dims, mxUINT32_CLASS, mxREAL);
+     pr =  = (UINT32_T *) mxGetData (m);
+
+   There are also the functions `mxSetPr', etc., that perform the
+inverse, and set the data of an Array to use the block of memory pointed
+to by the argument of `mxSetPr'.
+
+   Note the type `mwSize' used above, and `mwIndex' are defined as the
+native precision of the indexing in Octave on the platform on which the
+mex-file is built.  This allows both 32- and 64-bit platforms to
+support mex-files.  `mwSize' is used to define array dimension and
+maximum number or elements, while `mwIndex' is used to define indexing
+into arrays.
+
+   An example that demonstration how to work with arbitrary real or
+complex double precision arrays is given by the file `mypow2.c' as given
+below.
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs,
+     	     const mxArray* prhs[])
+     {
+       mwIndex i;
+       mwSize n;
+       double *vri, *vro;
+
+       if (nrhs != 1 || ! mxIsNumeric (prhs[0]))
+         mexErrMsgTxt ("expects matrix");
+
+       n = mxGetNumberOfElements (prhs[0]);
+       plhs[0] = (mxArray *) mxCreateNumericArray
+         (mxGetNumberOfDimensions (prhs[0]),
+          mxGetDimensions (prhs[0]), mxGetClassID (prhs[0]),
+          mxIsComplex (prhs[0]));
+       vri = mxGetPr (prhs[0]);
+       vro = mxGetPr (plhs[0]);
+
+       if (mxIsComplex (prhs[0]))
+         {
+           double *vii, *vio;
+           vii = mxGetPi (prhs[0]);
+           vio = mxGetPi (plhs[0]);
+
+           for (i = 0; i < n; i++)
+     	{
+     	  vro [i] = vri [i] * vri [i] - vii [i] * vii [i];
+     	  vio [i] = 2 * vri [i] * vii [i];
+     	}
+         }
+       else
+         {
+           for (i = 0; i < n; i++)
+     	vro [i] = vri [i] * vri [i];
+         }
+     }
+
+with an example of its use
+
+     b = randn(4,1) + 1i * randn(4,1);
+     all(b.^2 == mypow2(b))
+     => 1
+
+   The example above uses the functions `mxGetDimensions',
+`mxGetNumberOfElements', and `mxGetNumberOfDimensions' to work with the
+dimensions of multi-dimensional arrays.  The functions `mxGetM', and
+`mxGetN' are also available to find the number of rows and columns in a
+matrix.
+
+
+File: octave.info,  Node: Character Strings in Mex-Files,  Next: Cell Arrays with Mex-Files,  Prev: Working with Matrices and Arrays in Mex-Files,  Up: Mex-Files
+
+A.2.3 Character Strings in Mex-Files
+------------------------------------
+
+As mex-files do not make the distinction between single and double
+quoted strings within Octave, there is perhaps less complexity in the
+use of strings and character matrices in mex-files.  An example of their
+use, that parallels the demo in `stringdemo.cc', is given in the file
+`mystring.c', as seen below.
+
+     #include <string.h>
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs,
+     	     const mxArray *prhs[])
+     {
+       mwIndex i, j;
+       mwSize m, n;
+       mxChar *pi, *po;
+
+       if (nrhs != 1 || ! mxIsChar (prhs[0]) ||
+           mxGetNumberOfDimensions (prhs[0]) > 2)
+         mexErrMsgTxt ("expecting char matrix");
+
+       m = mxGetM (prhs[0]);
+       n = mxGetN (prhs[0]);
+       pi = mxGetChars (prhs[0]);
+       plhs[0] = mxCreateNumericMatrix (m, n, mxCHAR_CLASS,
+     				   mxREAL);
+       po = mxGetChars (plhs[0]);
+
+       for (j = 0; j < n; j++)
+         for (i = 0; i < m; i++)
+           po [j*m + m - 1 - i] = pi [j*m + i];
+     }
+
+An example of its expected output is
+
+     mystring(["First String"; "Second String"])
+     => s1 = Second String
+             First String
+
+   Other functions in the mex interface for handling character strings
+are `mxCreateString', `mxArrayToString', and
+`mxCreateCharMatrixFromStrings'.  In a mex-file, a character string is
+considered to be a vector rather than a matrix.  This is perhaps an
+arbitrary distinction as the data in the mxArray for the matrix is
+consecutive in any case.
+
+
+File: octave.info,  Node: Cell Arrays with Mex-Files,  Next: Structures with Mex-Files,  Prev: Character Strings in Mex-Files,  Up: Mex-Files
+
+A.2.4 Cell Arrays with Mex-Files
+--------------------------------
+
+We can perform exactly the same operations in Cell arrays in mex-files
+as we can in oct-files.  An example that reduplicates the functional of
+the `celldemo.cc' oct-file in a mex-file is given by `mycell.c' as below
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs,
+     	     const mxArray* prhs[])
+     {
+       mwSize n;
+       mwIndex i;
+
+       if (nrhs != 1 || ! mxIsCell (prhs[0]))
+         mexErrMsgTxt ("expects cell");
+
+       n = mxGetNumberOfElements (prhs[0]);
+       n = (n > nlhs ? nlhs : n);
+
+       for (i = 0; i < n; i++)
+         plhs[i] = mxDuplicateArray (mxGetCell (prhs[0], i));
+     }
+
+which as can be seen below has exactly the same behavior as the oct-file
+version.
+
+     [b1, b2, b3] = mycell ({1, [1, 2], "test"})
+     =>
+     b1 =  1
+     b2 =
+
+        1   2
+
+     b3 = test
+
+   Note in the example the use of the `mxDuplicateArray' function.  This
+is needed as the `mxArray' pointer returned by `mxGetCell' might be
+deallocated.  The inverse function to `mxGetCell' is `mcSetCell' and is
+defined as
+
+     void mxSetCell (mxArray *ptr, int idx, mxArray *val);
+
+   Finally, to create a cell array or matrix, the appropriate functions
+are
+
+     mxArray *mxCreateCellArray (int ndims, const int *dims);
+     mxArray *mxCreateCellMatrix (int m, int n);
+
+
+File: octave.info,  Node: Structures with Mex-Files,  Next: Sparse Matrices with Mex-Files,  Prev: Cell Arrays with Mex-Files,  Up: Mex-Files
+
+A.2.5 Structures with Mex-Files
+-------------------------------
+
+The basic function to create a structure in a mex-file is
+`mxCreateStructMatrix', which creates a structure array with a two
+dimensional matrix, or `mxCreateStructArray'.
+
+     mxArray *mxCreateStructArray (int ndims, int *dims,
+                                   int num_keys,
+                                   const char **keys);
+     mxArray *mxCreateStructMatrix (int rows, int cols,
+                                    int num_keys,
+                                    const char **keys);
+
+   Accessing the fields of the structure can then be performed with the
+`mxGetField' and `mxSetField' or alternatively with the
+`mxGetFieldByNumber' and `mxSetFieldByNumber' functions.
+
+     mxArray *mxGetField (const mxArray *ptr, mwIndex index,
+                          const char *key);
+     mxArray *mxGetFieldByNumber (const mxArray *ptr,
+                                  mwIndex index, int key_num);
+     void mxSetField (mxArray *ptr, mwIndex index,
+                      const char *key, mxArray *val);
+     void mxSetFieldByNumber (mxArray *ptr, mwIndex index,
+                              int key_num, mxArray *val);
+
+   A difference between the oct-file interface to structures and the
+mex-file version is that the functions to operate on structures in
+mex-files directly include an `index' over the elements of the arrays
+of elements per `field'.  Whereas the oct-file structure includes a
+Cell Array per field of the structure.
+
+   An example that demonstrates the use of structures in mex-file can be
+found in the file `mystruct.c', as seen below
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs,
+     	     const mxArray* prhs[])
+     {
+       int i;
+       mwIndex j;
+       mxArray *v;
+       const char *keys[] = { "this", "that" };
+
+       if (nrhs != 1 || ! mxIsStruct (prhs[0]))
+         mexErrMsgTxt ("expects struct");
+
+       for (i = 0; i < mxGetNumberOfFields (prhs[0]); i++)
+         for (j = 0; j < mxGetNumberOfElements (prhs[0]); j++)
+           {
+             mexPrintf ("field %s(%d) = ",
+                        mxGetFieldNameByNumber (prhs[0], i), j);
+             v = mxGetFieldByNumber (prhs[0], j, i);
+             mexCallMATLAB (0, 0, 1, &v, "disp");
+           }
+
+       v = mxCreateStructMatrix (2, 2, 2, keys);
+
+       mxSetFieldByNumber (v, 0, 0, mxCreateString ("this1"));
+       mxSetFieldByNumber (v, 0, 1, mxCreateString ("that1"));
+       mxSetFieldByNumber (v, 1, 0, mxCreateString ("this2"));
+       mxSetFieldByNumber (v, 1, 1, mxCreateString ("that2"));
+       mxSetFieldByNumber (v, 2, 0, mxCreateString ("this3"));
+       mxSetFieldByNumber (v, 2, 1, mxCreateString ("that3"));
+       mxSetFieldByNumber (v, 3, 0, mxCreateString ("this4"));
+       mxSetFieldByNumber (v, 3, 1, mxCreateString ("that4"));
+
+       if (nlhs)
+         plhs[0] = v;
+     }
+
+   An example of the behavior of this function within Octave is then
+
+     a(1).f1 = "f11"; a(1).f2 = "f12";
+     a(2).f1 = "f21"; a(2).f2 = "f22";
+     b = mystruct(a)
+     => field f1(0) = f11
+         field f1(1) = f21
+         field f2(0) = f12
+         field f2(1) = f22
+         b =
+         {
+           this =
+
+           (,
+             [1] = this1
+             [2] = this2
+             [3] = this3
+             [4] = this4
+           ,)
+
+           that =
+
+           (,
+             [1] = that1
+             [2] = that2
+             [3] = that3
+             [4] = that4
+           ,)
+
+         }
+
+
+File: octave.info,  Node: Sparse Matrices with Mex-Files,  Next: Calling Other Functions in Mex-Files,  Prev: Structures with Mex-Files,  Up: Mex-Files
+
+A.2.6 Sparse Matrices with Mex-Files
+------------------------------------
+
+The Octave format for sparse matrices is identical to the mex format in
+that it is a compressed column sparse format.  Also in both, sparse
+matrices are required to be two-dimensional.  The only difference is
+that the real and imaginary parts of the matrix are stored separately.
+
+   The mex-file interface, as well as using `mxGetM', `mxGetN',
+`mxSetM', `mxSetN', `mxGetPr', `mxGetPi', `mxSetPr' and `mxSetPi', the
+mex-file interface supplies the functions
+
+     mwIndex *mxGetIr (const mxArray *ptr);
+     mwIndex *mxGetJc (const mxArray *ptr);
+     mwSize mxGetNzmax (const mxArray *ptr);
+
+     void mxSetIr (mxArray *ptr, mwIndex *ir);
+     void mxSetJc (mxArray *ptr, mwIndex *jc);
+     void mxSetNzmax (mxArray *ptr, mwSize nzmax);
+
+`mxGetNzmax' gets the maximum number of elements that can be stored in
+the sparse matrix.  This is not necessarily the number of non-zero
+elements in the sparse matrix.  `mxGetJc' returns an array with one
+additional value than the number of columns in the sparse matrix.  The
+difference between consecutive values of the array returned by
+`mxGetJc' define the number of non-zero elements in each column of the
+sparse matrix.  Therefore
+
+     mwSize nz, n;
+     mwIndex *Jc;
+     mxArray *m;
+     ...
+     n = mxGetN (m);
+     Jc = mxGetJc (m);
+     nz = Jc[n];
+
+returns the actual number of non-zero elements stored in the matrix in
+`nz'.  As the arrays returned by `mxGetPr' and `mxGetPi' only contain
+the non-zero values of the matrix, we also need a pointer to the rows
+of the non-zero elements, and this is given by `mxGetIr'.  A complete
+example of the use of sparse matrices in mex-files is given by the file
+`mysparse.c' as seen below
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray *plhs[], int nrhs,
+     	     const mxArray *prhs[])
+     {
+       mwSize n, m, nz;
+       mxArray *v;
+       mwIndex i;
+       double *pr, *pi;
+       double *pr2, *pi2;
+       mwIndex *ir, *jc;
+       mwIndex *ir2, *jc2;
+
+       if (nrhs != 1 || ! mxIsSparse (prhs[0]))
+         mexErrMsgTxt ("expects sparse matrix");
+
+       m = mxGetM (prhs [0]);
+       n = mxGetN (prhs [0]);
+       nz = mxGetNzmax (prhs [0]);
+
+       if (mxIsComplex (prhs[0]))
+         {
+           mexPrintf ("Matrix is %d-by-%d complex",
+     		 " sparse matrix", m, n);
+           mexPrintf (" with %d elements\n", nz);
+
+           pr = mxGetPr (prhs[0]);
+           pi = mxGetPi (prhs[0]);
+           ir = mxGetIr (prhs[0]);
+           jc = mxGetJc (prhs[0]);
+
+           i = n;
+           while (jc[i] == jc[i-1] && i != 0) i--;
+           mexPrintf ("last non-zero element (%d, %d) =",
+     		 ir[nz-1]+ 1, i);
+           mexPrintf (" (%g, %g)\n", pr[nz-1], pi[nz-1]);
+
+           v = mxCreateSparse (m, n, nz, mxCOMPLEX);
+           pr2 = mxGetPr (v);
+           pi2 = mxGetPi (v);
+           ir2 = mxGetIr (v);
+           jc2 = mxGetJc (v);
+
+           for (i = 0; i < nz; i++)
+             {
+               pr2[i] = 2 * pr[i];
+               pi2[i] = 2 * pi[i];
+               ir2[i] = ir[i];
+             }
+           for (i = 0; i < n + 1; i++)
+             jc2[i] = jc[i];
+
+           if (nlhs > 0)
+             plhs[0] = v;
+         }
+       else if (mxIsLogical (prhs[0]))
+         {
+           bool *pbr, *pbr2;
+           mexPrintf ("Matrix is %d-by-%d logical",
+     		 " sparse matrix", m, n);
+           mexPrintf (" with %d elements\n", nz);
+
+           pbr = mxGetLogicals (prhs[0]);
+           ir = mxGetIr (prhs[0]);
+           jc = mxGetJc (prhs[0]);
+
+           i = n;
+           while (jc[i] == jc[i-1] && i != 0) i--;
+           mexPrintf ("last non-zero element (%d, %d) = %d\n",
+                      ir[nz-1]+ 1, i, pbr[nz-1]);
+
+           v = mxCreateSparseLogicalMatrix (m, n, nz);
+           pbr2 = mxGetLogicals (v);
+           ir2 = mxGetIr (v);
+           jc2 = mxGetJc (v);
+
+           for (i = 0; i < nz; i++)
+             {
+               pbr2[i] = pbr[i];
+               ir2[i] = ir[i];
+             }
+           for (i = 0; i < n + 1; i++)
+             jc2[i] = jc[i];
+
+           if (nlhs > 0)
+             plhs[0] = v;
+         }
+       else
+         {
+           mexPrintf ("Matrix is %d-by-%d real",
+     		 " sparse matrix", m, n);
+           mexPrintf (" with %d elements\n", nz);
+
+           pr = mxGetPr (prhs[0]);
+           ir = mxGetIr (prhs[0]);
+           jc = mxGetJc (prhs[0]);
+
+           i = n;
+           while (jc[i] == jc[i-1] && i != 0) i--;
+           mexPrintf ("last non-zero element (%d, %d) = %g\n",
+                     ir[nz-1]+ 1, i, pr[nz-1]);
+
+           v = mxCreateSparse (m, n, nz, mxREAL);
+           pr2 = mxGetPr (v);
+           ir2 = mxGetIr (v);
+           jc2 = mxGetJc (v);
+
+           for (i = 0; i < nz; i++)
+             {
+               pr2[i] = 2 * pr[i];
+               ir2[i] = ir[i];
+             }
+           for (i = 0; i < n + 1; i++)
+             jc2[i] = jc[i];
+
+           if (nlhs > 0)
+             plhs[0] = v;
+         }
+     }
+
+
+File: octave.info,  Node: Calling Other Functions in Mex-Files,  Prev: Sparse Matrices with Mex-Files,  Up: Mex-Files
+
+A.2.7 Calling Other Functions in Mex-Files
+------------------------------------------
+
+It is also possible call other Octave functions from within a mex-file
+using `mexCallMATLAB'.  An example of the use of `mexCallMATLAB' can be
+see in the example below
+
+     #include "mex.h"
+
+     void
+     mexFunction (int nlhs, mxArray* plhs[], int nrhs,
+     	     const mxArray* prhs[])
+     {
+       char *str;
+
+       mexPrintf ("Hello, World!\n");
+
+       mexPrintf ("I have %d inputs and %d outputs\n", nrhs,
+     	     nlhs);
+
+       if (nrhs < 1 || ! mxIsString (prhs[0]))
+         mexErrMsgTxt ("function name expected");
+
+       str = mxArrayToString (prhs[0]);
+
+       mexPrintf ("I'm going to call the function %s\n", str);
+
+       mexCallMATLAB (nlhs, plhs, nrhs-1, prhs+1, str);
+
+       mxFree (str);
+     }
+
+   If this code is in the file `myfeval.c', and is compiled to
+`myfeval.mex', then an example of its use is
+
+     myfeval("sin", 1)
+     a = myfeval("sin", 1)
+     => Hello, World!
+         I have 2 inputs and 1 outputs
+         I'm going to call the interpreter function sin
+         a =  0.84147
+
+   Note that it is not possible to use function handles or inline
+functions within a mex-file.
+
+
+File: octave.info,  Node: Standalone Programs,  Prev: Mex-Files,  Up: Dynamically Linked Functions
+
+A.3 Standalone Programs
+=======================
+
+The libraries Octave itself uses, can be utilized in standalone
+applications.  These applications then have access, for example, to the
+array and matrix classes as well as to all the Octave algorithms.  The
+following C++ program, uses class Matrix from liboctave.a or
+liboctave.so.
+
+     #include <iostream>
+     #include <octave/oct.h>
+
+     int
+     main (void)
+     {
+       std::cout << "Hello Octave world!\n";
+       int n = 2;
+       Matrix a_matrix = Matrix (n, n);
+       for (octave_idx_type i = 0; i < n; i++)
+         {
+           for (octave_idx_type j = 0; j < n; j++)
+             {
+               a_matrix (i, j) = (i + 1) * 10 + (j + 1);
+             }
+         }
+       std::cout << a_matrix;
+       return 0;
+     }
+
+mkoctfile can then be used to build a standalone application with a
+command like
+
+     $ mkoctfile --link-stand-alone standalone.cc -o standalone
+     $ ./standalone
+     Hello Octave world!
+       11 12
+       21 22
+     $
+
+   Note that the application `hello' will be dynamically linked against
+the octave libraries and any octave support libraries.  The above
+allows the Octave math libraries to be used by an application.  It does
+not however allow the script files, oct-files or builtin functions of
+Octave to be used by the application.  To do that the Octave interpreter
+needs to be initialized first.  An example of how to do this can then be
+seen in the code
+
+     #include <iostream>
+     #include <octave/oct.h>
+     #include <octave/octave.h>
+     #include <octave/parse.h>
+
+     int
+     main (void)
+     {
+       string_vector argv (2);
+       argv(0) = "embedded";
+       argv(1) = "-q";
+
+       octave_main (2, argv.c_str_vec(), 1);
+
+       octave_idx_type n = 2;
+       Matrix a_matrix = Matrix (1, 2);
+
+       std::cout << "GCD of [";
+       for (octave_idx_type i = 0; i < n; i++)
+         {
+           a_matrix (i) = 5 * (i + 1);
+           if (i != 0)
+     	std::cout << ", " << 5 * (i + 2);
+           else
+     	std::cout << 5 * (i + 2);
+         }
+       std::cout << "] is ";
+
+       octave_value_list in = octave_value (a_matrix);
+       octave_value_list out = feval ("gcd", in, 1);
+
+       if (!error_state && out.length () > 0)
+         {
+           a_matrix = out(0).matrix_value ();
+           if (a_matrix.numel () == 1)
+     	std::cout << a_matrix(0) << "\n";
+           else
+     	std::cout << "invalid\n";
+         }
+       else
+         std::cout << "invalid\n";
+
+       return 0;
+     }
+
+which is compiled and run as before as a standalone application with
+
+     $ mkoctfile --link-stand-alone embedded.cc -o embedded
+     $ ./embedded
+     GCD of [10, 15] is 5
+     $
+
+
+File: octave.info,  Node: Test and Demo Functions,  Next: Tips and Standards,  Prev: Dynamically Linked Functions,  Up: Top
+
+Appendix B Test and Demo Functions
+**********************************
+
+Octave includes a number of functions to allow the integration of
+testing and demonstration code in the source code of the functions
+themselves.
+
+* Menu:
+
+* Test Functions::
+* Demonstration Functions::
+
+
+File: octave.info,  Node: Test Functions,  Next: Demonstration Functions,  Up: Test and Demo Functions
+
+B.1 Test Functions
+==================
+
+ -- Function File:  test NAME
+ -- Function File:  test NAME quiet|normal|verbose
+ -- Function File:  test ('NAME', 'quiet|normal|verbose', FID)
+ -- Function File:  test ([], 'explain', FID)
+ -- Function File: SUCCESS = test (...)
+ -- Function File: [N, MAX] = test (...)
+ -- Function File: [CODE, IDX] = test ('NAME','grabdemo')
+     Perform tests from the first file in the loadpath matching NAME.
+     `test' can be called as a command or as a function.  Called with a
+     single argument NAME, the tests are run interactively and stop
+     after the first error is encountered.
+
+     With a second argument the tests which are performed and the
+     amount of output is selected.
+
+    'quiet'
+          Don't report all the tests as they happen, just the errors.
+
+    'normal'
+          Report all tests as they happen, but don't do tests which
+          require user interaction.
+
+    'verbose'
+          Do tests which require user interaction.
+
+     The argument FID can be used to allow batch processing.  Errors
+     can be written to the already open file defined by FID, and
+     hopefully when Octave crashes this file will tell you what was
+     happening when it did.  You can use `stdout' if you want to see
+     the results as they happen.  You can also give a file name rather
+     than an FID, in which case the contents of the file will be
+     replaced with the log from the current test.
+
+     Called with a single output argument SUCCESS, `test' returns true
+     if all of the tests were successful.  Called with two output
+     arguments N and MAX, the number of successful tests and the total
+     number of tests in the file NAME are returned.
+
+     If the second argument is the string 'grabdemo', the contents of
+     the demo blocks are extracted but not executed.  Code for all code
+     blocks is concatenated and returned as CODE with IDX being a
+     vector of positions of the ends of the demo blocks.
+
+     If the second argument is 'explain', then NAME is ignored and an
+     explanation of the line markers used is written to the file FID.
+
+     *See also:* *note error: doc-error, *note assert: doc-assert,
+     *note fail: doc-fail, *note demo: doc-demo, *note example:
+     doc-example.
+
+   `test' scans the named script file looking for lines which start
+with `%!'.  The prefix is stripped off and the rest of the line is
+processed through the Octave interpreter.  If the code generates an
+error, then the test is said to fail.
+
+   Since `eval()' will stop at the first error it encounters, you must
+divide your tests up into blocks, with anything in a separate block
+evaluated separately.  Blocks are introduced by the keyword `test'
+immediately following the `%!'.  For example,
+
+        %!test error ("this test fails!");
+        %!test "test doesn't fail. it doesn't generate an error";
+
+   When a test fails, you will see something like:
+
+          ***** test error ('this test fails!')
+        !!!!! test failed
+        this test fails!
+
+   Generally, to test if something works, you want to assert that it
+produces a correct value.  A real test might look something like
+
+        %!test
+        %! A = [1, 2, 3; 4, 5, 6]; B = [1; 2];
+        %! expect = [ A ; 2*A ];
+        %! get = kron (B, A);
+        %! if (any(size(expect) != size(get)))
+        %!    error ("wrong size: expected %d,%d but got %d,%d",
+        %!           size(expect), size(get));
+        %! elseif (any(any(expect!=get)))
+        %!    error ("didn't get what was expected.");
+        %! endif
+
+   To make the process easier, use the `assert' function.  For example,
+with `assert' the previous test is reduced to:
+
+        %!test
+        %! A = [1, 2, 3; 4, 5, 6]; B = [1; 2];
+        %! assert (kron (B, A), [ A; 2*A ]);
+
+   `assert' can accept a tolerance so that you can compare results
+absolutely or relatively.  For example, the following all succeed:
+
+        %!test assert (1+eps, 1, 2*eps)          # absolute error
+        %!test assert (100+100*eps, 100, -2*eps) # relative error
+
+   You can also do the comparison yourself, but still have assert
+generate the error:
+
+        %!test assert (isempty([]))
+        %!test assert ([ 1,2; 3,4 ] > 0)
+
+   Because `assert' is so frequently used alone in a test block, there
+is a shorthand form:
+
+        %!assert (...)
+
+   which is equivalent to:
+
+        %!test assert (...)
+
+   Sometimes during development there is a test that should work but is
+known to fail.  You still want to leave the test in because when the
+final code is ready the test should pass, but you may not be able to
+fix it immediately.  To avoid unnecessary bug reports for these known
+failures, mark the block with `xtest' rather than `test':
+
+        %!xtest assert (1==0)
+        %!xtest fail ('success=1','error'))
+
+   Another use of `xtest' is for statistical tests which should pass
+most of the time but are known to fail occasionally.
+
+   Each block is evaluated in its own function environment, which means
+that variables defined in one block are not automatically shared with
+other blocks.  If you do want to share variables, then you must declare
+them as `shared' before you use them.  For example, the following
+declares the variable A, gives it an initial value (default is empty),
+then uses it in several subsequent tests.
+
+        %!shared A
+        %! A = [1, 2, 3; 4, 5, 6];
+        %!assert (kron ([1; 2], A), [ A; 2*A ]);
+        %!assert (kron ([1, 2], A), [ A, 2*A ]);
+        %!assert (kron ([1,2; 3,4], A), [ A,2*A; 3*A,4*A ]);
+
+   You can share several variables at the same time:
+
+        %!shared A, B
+
+   You can also share test functions:
+
+        %!function A = fn(B)
+        %!  A = 2*B;
+        %!assert (A(2),4);
+
+   Note that all previous variables and values are lost when a new
+shared block is declared.
+
+   Error and warning blocks are like test blocks, but they only succeed
+if the code generates an error.  You can check the text of the error is
+correct using an optional regular expression `<pattern>'.  For example:
+
+        %!error <passes!> error('this test passes!');
+
+   If the code doesn't generate an error, the test fails.  For example,
+
+        %!error "this is an error because it succeeds.";
+
+   produces
+
+        ***** error "this is an error because it succeeds.";
+        !!!!! test failed: no error
+
+   It is important to automate the tests as much as possible, however
+some tests require user interaction.  These can be isolated into demo
+blocks, which if you are in batch mode, are only run when called with
+`demo' or `verbose'.  The code is displayed before it is executed.  For
+example,
+
+        %!demo
+        %! T=[0:0.01:2*pi]; X=sin(T);
+        %! plot(T,X);
+        %! you should now see a sine wave in your figure window
+
+   produces
+
+        > T=[0:0.01:2*pi]; X=sin(T);
+        > plot(T,X);
+        > you should now see a sine wave in your figure window
+        Press <enter> to continue:
+
+   Note that demo blocks cannot use any shared variables.  This is so
+that they can be executed by themselves, ignoring all other tests.
+
+   If you want to temporarily disable a test block, put `#' in place of
+the block type.  This creates a comment block which is echoed in the
+log file, but is not executed.  For example:
+
+        %!#demo
+        %! T=[0:0.01:2*pi]; X=sin(T);
+        %! plot(T,X);
+        %! you should now see a sine wave in your figure window
+
+   Block type summary:
+
+`%!test'
+     check that entire block is correct
+
+`%!error'
+     check for correct error message
+
+`%!warning'
+     check for correct warning message
+
+`%!demo'
+     demo only executes in interactive mode
+
+`%!#'
+     comment: ignore everything within the block
+
+`%!shared x,y,z'
+     declares variables for use in multiple tests
+
+`%!function'
+     defines a function value for a shared variable
+
+`%!assert (x, y, tol)'
+     shorthand for %!test assert (x, y, tol)
+
+   You can also create test scripts for builtins and your own C++
+functions.  Just put a file of the function name on your path without
+any extension and it will be picked up by the test procedure.  You can
+even embed tests directly in your C++ code:
+
+        #if 0
+        %!test disp('this is a test')
+        #endif
+
+   or
+
+        /*
+        %!test disp('this is a test')
+        */
+
+   but then the code will have to be on the load path and the user will
+have to remember to type test('name.cc').  Conversely, you can separate
+the tests from normal Octave script files by putting them in plain
+files with no extension rather than in script files.
+
+ -- Function File:  assert (COND)
+ -- Function File:  assert (COND, ERRMSG, ...)
+ -- Function File:  assert (COND, MSG_ID, ERRMSG, ...)
+ -- Function File:  assert (OBSERVED,EXPECTED)
+ -- Function File:  assert (OBSERVED,EXPECTED,TOL)
+     Produces an error if the condition is not met.  `assert' can be
+     called in three different ways.
+
+    `assert (COND)'
+    `assert (COND, ERRMSG, ...)'
+    `assert (COND, MSG_ID, ERRMSG, ...)'
+          Called with a single argument COND, `assert' produces an
+          error if COND is zero.  If called with a single argument a
+          generic error message.  With more than one argument, the
+          additional arguments are passed to the `error' function.
+
+    `assert (OBSERVED, EXPECTED)'
+          Produce an error if observed is not the same as expected.
+          Note that observed and expected can be strings, scalars,
+          vectors, matrices, lists or structures.
+
+    `assert(OBSERVED, EXPECTED, TOL)'
+          Accept a tolerance when comparing numbers.  If TOL is
+          positive use it as an absolute tolerance, will produce an
+          error if `abs(OBSERVED - EXPECTED) > abs(TOL)'.  If TOL is
+          negative use it as a relative tolerance, will produce an
+          error if `abs(OBSERVED - EXPECTED) > abs(TOL * EXPECTED)'.
+          If EXPECTED is zero TOL will always be used as an absolute
+          tolerance.
+
+     *See also:* *note test: doc-test.
+
+ -- Function File:  fail (CODE,PATTERN)
+ -- Function File:  fail (CODE,'warning',PATTERN)
+     Return true if CODE fails with an error message matching PATTERN,
+     otherwise produce an error.  Note that CODE is a string and if
+     CODE runs successfully, the error produced is:
+
+                    expected error but got none
+
+     If the code fails with a different error, the message produced is:
+
+                    expected <pattern>
+                    but got <text of actual error>
+
+     The angle brackets are not part of the output.
+
+     Called with three arguments, the behavior is similar to
+     `fail(CODE, PATTERN)', but produces an error if no warning is
+     given during code execution or if the code fails.
+
+
+
+File: octave.info,  Node: Demonstration Functions,  Prev: Test Functions,  Up: Test and Demo Functions
+
+B.2 Demonstration Functions
+===========================
+
+ -- Function File:  demo ('NAME',N)
+     Runs any examples associated with the function 'NAME'.  Examples
+     are stored in the script file, or in a file with the same name but
+     no extension somewhere on your path.  To keep them separate from
+     the usual script code, all lines are prefixed by `%!'.  Each
+     example is introduced by the keyword 'demo' flush left to the
+     prefix, with no intervening spaces.  The remainder of the example
+     can contain arbitrary Octave code.  For example:
+
+             %!demo
+             %! t=0:0.01:2*pi; x = sin(t);
+             %! plot(t,x)
+             %! %-------------------------------------------------
+             %! % the figure window shows one cycle of a sine wave
+
+     Note that the code is displayed before it is executed, so a simple
+     comment at the end suffices.  It is generally not necessary to use
+     disp or printf within the demo.
+
+     Demos are run in a function environment with no access to external
+     variables.  This means that all demos in your function must use
+     separate initialization code.  Alternatively, you can combine your
+     demos into one huge demo, with the code:
+
+             %! input("Press <enter> to continue: ","s");
+
+     between the sections, but this is discouraged.  Other techniques
+     include using multiple plots by saying figure between each, or
+     using subplot to put multiple plots in the same window.
+
+     Also, since demo evaluates inside a function context, you cannot
+     define new functions inside a demo.  Instead you will have to use
+     `eval(example('function',n))' to see them.  Because eval only
+     evaluates one line, or one statement if the statement crosses
+     multiple lines, you must wrap your demo in "if 1 <demo stuff>
+     endif" with the 'if' on the same line as 'demo'.  For example,
+
+            %!demo if 1
+            %!  function y=f(x)
+            %!    y=x;
+            %!  endfunction
+            %!  f(3)
+            %! endif
+
+     *See also:* *note test: doc-test, *note example: doc-example.
+
+ -- Function File:  rundemos (DIRECTORY)
+
+ -- Function File:  example ('NAME',N)
+ -- Function File: [X, IDX] = example ('NAME',N)
+     Display the code for example N associated with the function
+     'NAME', but do not run it.  If N is not given, all examples are
+     displayed.
+
+     Called with output arguments, the examples are returned in the
+     form of a string X, with IDX indicating the ending position of the
+     various examples.
+
+     See `demo' for a complete explanation.
+
+     *See also:* *note demo: doc-demo, *note test: doc-test.
+
+ -- Function File:  speed (F, INIT, MAX_N, F2, TOL)
+ -- Function File: [ORDER, N, T_F, T_F2] = speed (...)
+     Determine the execution time of an expression for various N.  The
+     N are log-spaced from 1 to MAX_N.  For each N, an initialization
+     expression is computed to create whatever data are needed for the
+     test.  If a second expression is given, the execution times of the
+     two expressions will be compared.  Called without output arguments
+     the results are presented graphically.
+
+    `F'
+          The expression to evaluate.
+
+    `MAX_N'
+          The maximum test length to run.  Default value is 100.
+          Alternatively, use `[min_n,max_n]' or for complete control,
+          `[n1,n2,...,nk]'.
+
+    `INIT'
+          Initialization expression for function argument values.  Use K
+          for the test number and N for the size of the test.  This
+          should compute values for all variables listed in args.  Note
+          that init will be evaluated first for k = 0, so things which
+          are constant throughout the test can be computed then.  The
+          default value is `X = randn (N, 1);'.
+
+    `F2'
+          An alternative expression to evaluate, so the speed of the two
+          can be compared.  Default is `[]'.
+
+    `TOL'
+          If TOL is `Inf', then no comparison will be made between the
+          results of expression F and expression F2.  Otherwise,
+          expression F should produce a value V and expression F2
+          should produce a value V2, and these shall be compared using
+          `assert(V,V2,TOL)'.  If TOL is positive, the tolerance is
+          assumed to be absolute.  If TOL is negative, the tolerance is
+          assumed to be relative.  The default is `eps'.
+
+    `ORDER'
+          The time complexity of the expression `O(a n^p)'.  This is a
+          structure with fields `a' and `p'.
+
+    `N'
+          The values N for which the expression was calculated and the
+          execution time was greater than zero.
+
+    `T_F'
+          The nonzero execution times recorded for the expression F in
+          seconds.
+
+    `T_F2'
+          The nonzero execution times recorded for the expression F2 in
+          seconds.  If it is needed, the mean time ratio is just
+          `mean(T_f./T_f2)'.
+
+
+     The slope of the execution time graph shows the approximate power
+     of the asymptotic running time `O(n^p)'.  This power is plotted
+     for the region over which it is approximated (the latter half of
+     the graph).  The estimated power is not very accurate, but should
+     be sufficient to determine the general order of your algorithm.
+     It should indicate if for example your implementation is
+     unexpectedly `O(n^2)' rather than `O(n)' because it extends a
+     vector each time through the loop rather than preallocating one
+     which is big enough.  For example, in the current version of
+     Octave, the following is not the expected `O(n)':
+
+          speed ("for i = 1:n, y{i} = x(i); end", "", [1000,10000])
+
+     but it is if you preallocate the cell array `y':
+
+          speed ("for i = 1:n, y{i} = x(i); end", ...
+                 "x = rand (n, 1); y = cell (size (x));", [1000, 10000])
+
+     An attempt is made to approximate the cost of the individual
+     operations, but it is wildly inaccurate.  You can improve the
+     stability somewhat by doing more work for each `n'.  For example:
+
+          speed ("airy(x)", "x = rand (n, 10)", [10000, 100000])
+
+     When comparing a new and original expression, the line on the
+     speedup ratio graph should be larger than 1 if the new expression
+     is faster.  Better algorithms have a shallow slope.  Generally,
+     vectorizing an algorithm will not change the slope of the execution
+     time graph, but it will shift it relative to the original.  For
+     example:
+
+          speed ("v = sum (x)", "", [10000, 100000], ...
+                 "v = 0; for i = 1:length (x), v += x(i); end")
+
+     A more complex example, if you had an original version of `xcorr'
+     using for loops and another version using an FFT, you could
+     compare the run speed for various lags as follows, or for a fixed
+     lag with varying vector lengths as follows:
+
+          speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100,
+                 "v2 = xcorr_orig (x, n)", -100*eps)
+          speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100,
+                 "v2 = xcorr_orig (x, n)", -100*eps)
+
+     Assuming one of the two versions is in XCORR_ORIG, this would
+     compare their speed and their output values.  Note that the FFT
+     version is not exact, so we specify an acceptable tolerance on the
+     comparison `100*eps', and the errors should be computed
+     relatively, as `abs((X - Y)./Y)' rather than absolutely as `abs(X
+     - Y)'.
+
+     Type `example('speed')' to see some real examples.  Note for
+     obscure reasons, you can't run examples 1 and 2 directly using
+     `demo('speed')'.  Instead use, `eval(example('speed',1))' and
+     `eval(example('speed',2))'.
+
+
+File: octave.info,  Node: Tips and Standards,  Next: Contributing Guidelines,  Prev: Test and Demo Functions,  Up: Top
+
+Appendix C Tips and Standards
+*****************************
+
+This chapter describes no additional features of Octave.  Instead it
+gives advice on making effective use of the features described in the
+previous chapters.
+
+* Menu:
+
+* Style Tips::                  Writing clean and robust programs.
+* Coding Tips::                 Making code run faster.
+* Comment Tips::                Conventions for writing comments.
+* Function Headers::            Standard headers for functions.
+* Documentation Tips::          Writing readable documentation strings.
+
+
+File: octave.info,  Node: Style Tips,  Next: Coding Tips,  Up: Tips and Standards
+
+C.1 Writing Clean Octave Programs
+=================================
+
+Here are some tips for avoiding common errors in writing Octave code
+intended for widespread use:
+
+   * Since all global variables share the same name space, and all
+     functions share another name space, you should choose a short word
+     to distinguish your program from other Octave programs.  Then take
+     care to begin the names of all global variables, constants, and
+     functions with the chosen prefix.  This helps avoid name conflicts.
+
+     If you write a function that you think ought to be added to Octave
+     under a certain name, such as `fiddle_matrix', don't call it by
+     that name in your program.  Call it `mylib_fiddle_matrix' in your
+     program, and send mail to <maintainers at octave.org> suggesting that
+     it be added to Octave.  If and when it is, the name can be changed
+     easily enough.
+
+     If one prefix is insufficient, your package may use two or three
+     alternative common prefixes, so long as they make sense.
+
+     Separate the prefix from the rest of the symbol name with an
+     underscore `_'.  This will be consistent with Octave itself and
+     with most Octave programs.
+
+   * When you encounter an error condition, call the function `error'
+     (or `usage').  The `error' and `usage' functions do not return.
+     *Note Errors::.
+
+   * Please put a copyright notice on the file if you give copies to
+     anyone.  Use the same lines that appear at the top of the function
+     files distributed with Octave.  If you have not signed papers to
+     assign the copyright to anyone else, then place your name in the
+     copyright notice.
+
+
+File: octave.info,  Node: Coding Tips,  Next: Comment Tips,  Prev: Style Tips,  Up: Tips and Standards
+
+C.2 Tips for Making Code Run Faster.
+====================================
+
+Here are some ways of improving the execution speed of Octave programs.
+
+   * Vectorize loops. For instance, rather than
+          for i = 1:n-1
+            a(i) = b(i+1) - b(i);
+          endfor
+
+     write
+
+          a = b(2:n) - b(1:n-1);
+
+     This is especially important for loops with "cheap" bodies. Often
+     it suffices to vectorize just the innermost loop to get acceptable
+     performance. A general rule of thumb is that the "order" of the
+     vectorized body should be greater or equal to the "order" of the
+     enclosing loop.
+
+   * Use built-in and library functions if possible. Built-in and
+     compiled functions are very fast.  Even with a m-file library
+     function, chances are good that it is already optimized, or will be
+     optimized more in a future release.
+
+   * Avoid computing costly intermediate results multiple times. Octave
+     currently does not eliminate common subexpressions.
+
+   * Be aware of lazy copies (copy-on-write). When a copy of an object
+     is created, the data is not immediately copied, but rather shared.
+     The actual copying is postponed until the copied data needs to be
+     modified. For example:
+
+          a = zeros (1000); # create a 1000x1000 matrix
+          b = a; # no copying done here
+          b(1) = 1; # copying done here
+
+     Lazy copying applies to whole Octave objects such as matrices,
+     cells, struct, and also individual cell or struct elements (not
+     array elements).
+
+     Additionally, index expressions also use lazy copying when Octave
+     can determine that the indexed portion is contiguous in memory.
+     For example:
+
+          a = zeros (1000); # create a 1000x1000 matrix
+          b = a(:,10:100); # no copying done here
+          b = a(10:100,:); # copying done here
+
+     This applies to arrays (matrices), cell arrays, and structs
+     indexed using ().  Index expressions generating cs-lists can also
+     benefit of shallow copying in some cases. In particular, when A is
+     a struct array, expressions like `{a.x}, {a(:,2).x}' will use lazy
+     copying, so that data can be shared between a struct array and a
+     cell array.
+
+     Most indexing expressions do not live longer than their `parent'
+     objects.  In rare cases, however, a lazily copied slice outlasts
+     its parent, in which case it becomes orphaned, still occupying
+     unnecessarily more memory than needed.  To provide a remedy
+     working in most real cases, Octave checks for orphaned lazy slices
+     at certain situations, when a value is stored into a "permanent"
+     location, such as a named variable or cell or struct element, and
+     possibly economizes them. For example
+
+          a = zeros (1000); # create a 1000x1000 matrix
+          b = a(:,10:100); # lazy slice
+          a = []; # the original a array is still allocated
+          c{1} = b; # b is reallocated at this point
+
+   * Avoid deep recursion. Function calls to m-file functions carry a
+     relatively significant overhead, so rewriting a recursion as a
+     loop often helps. Also, note that the maximum level of recursion is
+     limited.
+
+   * Avoid resizing matrices unnecessarily. When building a single
+     result matrix from a series of calculations, set the size of the
+     result matrix first, then insert values into it.  Write
+
+          result = zeros (big_n, big_m)
+          for i = over:and_over
+            r1 = ...
+            r2 = ...
+            result (r1, r2) = new_value ();
+          endfor
+
+     instead of
+
+          result = [];
+          for i = ever:and_ever
+            result = [ result, new_value() ];
+          endfor
+
+     Sometimes the number of items can't be computed in advance, and
+     stack-like operations are needed. When elements are being
+     repeatedly inserted at/removed from the end of an array, Octave
+     detects it as stack usage and attempts to use a smarter memory
+     management strategy preallocating the array in bigger chunks.
+     Likewise works for cell and struct arrays.
+
+          a = [];
+          while (condition)
+            ...
+            a(end+1) = value; # "push" operation
+            ...
+            a(end) = []; # "pop" operation
+            ...
+          endwhile
+
+   * Use `cellfun' intelligently. The `cellfun' function is a useful
+     tool for avoiding loops. *Note Processing Data in Cell Arrays::.
+     `cellfun' is often use with anonymous function handles; however,
+     calling an anonymous function involves an overhead quite
+     comparable to the overhead of an m-file function. Passing a handle
+     to a built-in function is faster, because the interpreter is not
+     involved in the internal loop. For example:
+
+          a = {...}
+          v = cellfun (@(x) det(x), a); # compute determinants
+          v = cellfun (@det, a); # faster
+
+   * Avoid calling `eval' or `feval' excessively, because they require
+     Octave to parse input or look up the name of a function in the
+     symbol table.
+
+     If you are using `eval' as an exception handling mechanism and not
+     because you need to execute some arbitrary text, use the `try'
+     statement instead.  *Note The `try' Statement::.
+
+   * If you are calling lots of functions but none of them will need to
+     change during your run, set the variable
+     `ignore_function_time_stamp' to `"all"' so that Octave doesn't
+     waste a lot of time checking to see if you have updated your
+     function files.
+
+
+File: octave.info,  Node: Comment Tips,  Next: Function Headers,  Prev: Coding Tips,  Up: Tips and Standards
+
+C.3 Tips on Writing Comments
+============================
+
+Here are the conventions to follow when writing comments.
+
+`#'
+     Comments that start with a single sharp-sign, `#', should all be
+     aligned to the same column on the right of the source code.  Such
+     comments usually explain how the code on the same line does its
+     job.  In the Emacs mode for Octave, the `M-;'
+     (`indent-for-comment') command automatically inserts such a `#' in
+     the right place, or aligns such a comment if it is already present.
+
+`##'
+     Comments that start with a double sharp-sign, `##', should be
+     aligned to the same level of indentation as the code.  Such
+     comments usually describe the purpose of the following lines or
+     the state of the program at that point.
+
+The indentation commands of the Octave mode in Emacs, such as `M-;'
+(`indent-for-comment') and `TAB' (`octave-indent-line') automatically
+indent comments according to these conventions, depending on the number
+of semicolons.  *Note Manipulating Comments: (emacs)Comments.
+
+
+File: octave.info,  Node: Function Headers,  Next: Documentation Tips,  Prev: Comment Tips,  Up: Tips and Standards
+
+C.4 Conventional Headers for Octave Functions
+=============================================
+
+Octave has conventions for using special comments in function files to
+give information such as who wrote them.  This section explains these
+conventions.
+
+   The top of the file should contain a copyright notice, followed by a
+block of comments that can be used as the help text for the function.
+Here is an example:
+
+     ## Copyright (C) 1996, 1997, 2007 John W. Eaton
+     ##
+     ## This file is part of Octave.
+     ##
+     ## Octave is free software; you can redistribute it and/or
+     ## modify it under the terms of the GNU General Public
+     ## License as published by the Free Software Foundation;
+     ## either version 3 of the License, or (at your option) any
+     ## later version.
+     ##
+     ## Octave is distributed in the hope that it will be useful,
+     ## but WITHOUT ANY WARRANTY; without even the implied
+     ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     ## PURPOSE.  See the GNU General Public License for more
+     ## details.
+     ##
+     ## You should have received a copy of the GNU General Public
+     ## License along with Octave; see the file COPYING.  If not,
+     ## see <http://www.gnu.org/licenses/>.
+
+     ## usage: [IN, OUT, PID] = popen2 (COMMAND, ARGS)
+     ##
+     ## Start a subprocess with two-way communication.  COMMAND
+     ## specifies the name of the command to start.  ARGS is an
+     ## array of strings containing options for COMMAND.  IN and
+     ## OUT are the file ids of the input and streams for the
+     ## subprocess, and PID is the process id of the subprocess,
+     ## or -1 if COMMAND could not be executed.
+     ##
+     ## Example:
+     ##
+     ##  [in, out, pid] = popen2 ("sort", "-nr");
+     ##  fputs (in, "these\nare\nsome\nstrings\n");
+     ##  fclose (in);
+     ##  while (ischar (s = fgets (out)))
+     ##    fputs (stdout, s);
+     ##  endwhile
+     ##  fclose (out);
+
+   Octave uses the first block of comments in a function file that do
+not appear to be a copyright notice as the help text for the file.  For
+Octave to recognize the first comment block as a copyright notice, it
+must start with the word `Copyright' after stripping the leading
+comment characters.
+
+   After the copyright notice and help text come several "header
+comment" lines, each beginning with `## HEADER-NAME:'.  For example,
+
+     ## Author: jwe
+     ## Keywords: subprocesses input-output
+     ## Maintainer: jwe
+
+   Here is a table of the conventional possibilities for HEADER-NAME:
+
+`Author'
+     This line states the name and net address of at least the principal
+     author of the library.
+
+          ## Author: John W. Eaton <jwe at octave.org>
+
+`Maintainer'
+     This line should contain a single name/address as in the Author
+     line, or an address only, or the string `jwe'.  If there is no
+     maintainer line, the person(s) in the Author field are presumed to
+     be the maintainers.  The example above is mildly bogus because the
+     maintainer line is redundant.
+
+     The idea behind the `Author' and `Maintainer' lines is to make
+     possible a function to "send mail to the maintainer" without
+     having to mine the name out by hand.
+
+     Be sure to surround the network address with `<...>' if you
+     include the person's full name as well as the network address.
+
+`Created'
+     This optional line gives the original creation date of the file.
+     For historical interest only.
+
+`Version'
+     If you wish to record version numbers for the individual Octave
+     program, put them in this line.
+
+`Adapted-By'
+     In this header line, place the name of the person who adapted the
+     library for installation (to make it fit the style conventions, for
+     example).
+
+`Keywords'
+     This line lists keywords.  Eventually, it will be used by an
+     apropos command to allow people will find your package when
+     they're looking for things by topic area.  To separate the
+     keywords, you can use spaces, commas, or both.
+
+   Just about every Octave function ought to have the `Author' and
+`Keywords' header comment lines.  Use the others if they are
+appropriate.  You can also put in header lines with other header
+names--they have no standard meanings, so they can't do any harm.
+
+
+File: octave.info,  Node: Documentation Tips,  Prev: Function Headers,  Up: Tips and Standards
+
+C.5 Tips for Documentation Strings
+==================================
+
+As noted above, documentation is typically in a commented header block
+on an Octave function following the copyright statement.  The help
+string shown above is an unformatted string and will be displayed as is
+by Octave.  Here are some tips for the writing of documentation strings.
+
+   * Every command, function, or variable intended for users to know
+     about should have a documentation string.
+
+   * An internal variable or subroutine of an Octave program might as
+     well have a documentation string.
+
+   * The first line of the documentation string should consist of one
+     or two complete sentences that stand on their own as a summary.
+
+     The documentation string can have additional lines that expand on
+     the details of how to use the function or variable.  The
+     additional lines should also be made up of complete sentences.
+
+   * For consistency, phrase the verb in the first sentence of a
+     documentation string as an infinitive with "to" omitted.  For
+     instance, use "Return the frob of A and B." in preference to
+     "Returns the frob of A and B."  Usually it looks good to do
+     likewise for the rest of the first paragraph.  Subsequent
+     paragraphs usually look better if they have proper subjects.
+
+   * Write documentation strings in the active voice, not the passive,
+     and in the present tense, not the future.  For instance, use
+     "Return a list containing A and B." instead of "A list containing
+     A and B will be returned."
+
+   * Avoid using the word "cause" (or its equivalents) unnecessarily.
+     Instead of, "Cause Octave to display text in boldface," write just
+     "Display text in boldface."
+
+   * Do not start or end a documentation string with whitespace.
+
+   * Format the documentation string so that it fits in an Emacs window
+     on an 80-column screen.  It is a good idea for most lines to be no
+     wider than 60 characters.
+
+     However, rather than simply filling the entire documentation
+     string, you can make it much more readable by choosing line breaks
+     with care.  Use blank lines between topics if the documentation
+     string is long.
+
+   * *Do not* indent subsequent lines of a documentation string so that
+     the text is lined up in the source code with the text of the first
+     line.  This looks nice in the source code, but looks bizarre when
+     users view the documentation.  Remember that the indentation
+     before the starting double-quote is not part of the string!
+
+   * The documentation string for a variable that is a yes-or-no flag
+     should start with words such as "Nonzero means...", to make it
+     clear that all nonzero values are equivalent and indicate
+     explicitly what zero and nonzero mean.
+
+   * When a function's documentation string mentions the value of an
+     argument of the function, use the argument name in capital letters
+     as if it were a name for that value.  Thus, the documentation
+     string of the operator `/' refers to its second argument as
+     `DIVISOR', because the actual argument name is `divisor'.
+
+     Also use all caps for meta-syntactic variables, such as when you
+     show the decomposition of a list or vector into subunits, some of
+     which may vary.
+
+   Octave also allows extensive formatting of the help string of
+functions using Texinfo.  The effect on the online documentation is
+relatively small, but makes the help string of functions conform to the
+help of Octave's own functions.  However, the effect on the appearance
+of printed or online documentation will be greatly improved.
+
+   The fundamental building block of Texinfo documentation strings is
+the Texinfo-macro `@deftypefn', which takes three arguments: The class
+the function is in, its output arguments, and the function's signature.
+Typical classes for functions include `Function File' for standard
+Octave functions, and `Loadable Function' for dynamically linked
+functions.  A skeletal Texinfo documentation string therefore looks
+like this
+
+     -*- texinfo -*-
+     @deftypefn{Function File} {@var{ret} =} fn (...)
+     @cindex index term
+     Help text in Texinfo format.  Code samples should be marked
+     like @code{sample of code} and variables should be marked
+     as @var{variable}.
+     @seealso{fn2}
+     @end deftypefn
+
+   This help string must be commented in user functions, or in the help
+string of the `DEFUN_DLD' macro for dynamically loadable functions.
+The important aspects of the documentation string are
+
+-*- texinfo -*-
+     This string signals Octave that the following text is in Texinfo
+     format, and should be the first part of any help string in Texinfo
+     format.
+
+ at deftypefn{class} ... @end deftypefn
+     The entire help string should be enclosed within the block defined
+     by deftypefn.
+
+ at cindex index term
+     This generates an index entry, and can be useful when the function
+     is included as part of a larger piece of documentation.  It is
+     ignored within Octave's help viewer.  Only one index term may
+     appear per line but multiple @cindex lines are valid if the
+     function should be filed under different terms.
+
+ at var{variable}
+     All variables should be marked with this macro.  The markup of
+     variables is then changed appropriately for display.
+
+ at code{sample of code}
+     All samples of code should be marked with this macro for the same
+     reasons as the @var macro.
+
+ at seealso{function2}
+     This is a comma separated list of function names that allows cross
+     referencing from one function documentation string to another.
+
+   Texinfo format has been designed to generate output for online
+viewing with text terminals as well as generating high-quality printed
+output.  To these ends, Texinfo has commands which control the
+diversion of parts of the document into a particular output processor.
+Three formats are of importance: info, html and TeX.  These are
+selected with
+
+     @ifinfo
+     Text area for info only
+     @end ifinfo
+
+     @ifhtml
+     Text area for HTML only
+     @end ifhtml
+
+     @tex
+     Text area for TeX only
+     @end tex
+
+   Note that often TeX output can be used in html documents and so often
+the `@ifhtml' blocks are unnecessary.  If no specific output processor
+is chosen, by default, the text goes into all output processors.  It is
+usual to have the above blocks in pairs to allow the same information
+to be conveyed in all output formats, but with a different markup.
+Currently, most Octave documentation only makes a distinction between
+TeX and all other formats.  Therefore, the following construct is seen
+repeatedly.
+
+     @tex
+     text for TeX only
+     @end tex
+     @ifnottex
+     text for info, HTML, plaintext
+     @end ifnottex
+
+   Another important feature of Texinfo that is often used in Octave
+help strings is the `@example' environment.  An example of its use is
+
+     @example
+     @group
+     @code{2 * 2}
+     @result{} 4
+     @end group
+     @end example
+
+   which produces
+
+     `2 * 2'
+     => 4
+
+   The `@group' block prevents the example from being split across a
+page boundary, while the `@result{}' macro produces a right arrow
+signifying the result of a command.  If your example is larger than 20
+lines it is better NOT to use grouping so that a reasonable page
+boundary can be calculated.
+
+   In many cases a function has multiple ways in which it can be called,
+and the `@deftypefnx' macro can be used to give alternatives.  For
+example
+
+     -*- texinfo -*-
+     @deftypefn{Function File} {@var{a} =} fn (@var{x}, ...)
+     @deftypefnx{Function File} {@var{a} =} fn (@var{y}, ...)
+     Help text in Texinfo format.
+     @end deftypefn
+
+   Many complete examples of Texinfo documentation can be taken from the
+help strings for the Octave functions themselves.  A relatively complete
+example of which is the `nchoosek' function.  The Texinfo documentation
+string for `nchoosek' is
+
+     -*- texinfo -*-
+     @deftypefn {Function File} {} nchoosek (@var{n}, @var{k})
+
+     Compute the binomial coefficient or all combinations of
+     @var{n}.  If @var{n} is a scalar then, calculate the
+     binomial coefficient of @var{n} and @var{k}, defined as
+
+     @tex
+     $$
+      {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+     $$
+     @end tex
+     @ifnottex
+
+     @example
+     @group
+      /   \
+      | n |    n (n-1) (n-2) ... (n-k+1)
+      |   |  = -------------------------
+      | k |               k!
+      \   /
+     @end group
+     @end example
+     @end ifnottex
+
+     If @var{n} is a vector, this generates all combinations
+     of the elements of @var{n}, taken @var{k} at a time,
+     one row per combination.  The resulting @var{c} has size
+     @code{[nchoosek (length (@var{n}), at var{k}), @var{k}]}.
+
+     @code{nchoosek} works only for non-negative integer arguments; use
+     @code{bincoeff} for non-integer scalar arguments and for using vector
+     arguments to compute many coefficients at once.
+
+     @seealso{bincoeff}
+     @end deftypefn
+
+   which demonstrates most of the concepts discussed above.
+
+
+File: octave.info,  Node: Contributing Guidelines,  Next: Trouble,  Prev: Tips and Standards,  Up: Top
+
+Appendix D Contributing Guidelines
+**********************************
+
+This chapter is dedicated to those who wish to contribute code to
+Octave.
+
+* Menu:
+
+* How to Contribute::
+* General Guidelines::
+* Octave Sources (m-files)::
+* C++ Sources::
+* Other Sources::
+
+
+File: octave.info,  Node: How to Contribute,  Next: General Guidelines,  Up: Contributing Guidelines
+
+D.1 How to Contribute
+=====================
+
+The mailing list for Octave development discussion and sending
+contributions is <maintainers at octave.org>.  This concerns the
+development of Octave core, i.e., code that goes to Octave directly.
+You may consider developing and publishing a package instead; a great
+place for this is the allied Octave-Forge project
+(`http://octave.sf.net').  Note that the Octave project is inherently
+more conservative and follows narrower rules.
+
+   The preferable form of contribution is creating a Mercurial
+changeset and sending it via e-mail to the octave-maintainers mailing
+list.  Mercurial is the source code management system currently used to
+develop Octave.  Other forms of contributions (e.g., simple diff
+patches) are also acceptable, but they slow down the review process.
+If you want to make more contributions, you should really get familiar
+with Mercurial.  A good place to start is
+`http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial'.  There you
+will also find help how to install Mercurial.
+
+   A simple contribution sequence could look like this:
+     hg clone http://www.octave.org/hg/octave
+                                  # make a local copy of the octave
+                                  # source repository
+     cd octave
+     # change some sources...
+     hg commit -m "make Octave the coolest software ever"
+                                  # commit the changeset into your
+                                  # local repository
+     hg export -o ../cool.diff tip
+                                  # export the changeset to a diff
+                                  # file
+     # send ../cool.diff via email
+
+   You may want to get familiar with Mercurial queues to manage your
+changesets.  Here is a slightly less simple example using Mercurial
+queues, where you work on two unrelated changesets in parallel and
+update one of the changesets after discussion in the maintainers
+mailing list:
+     hg qnew nasty_bug            # create a new patch
+     # change sources...
+     hg qref                      # save the changes into the patch
+     # change even more...
+     hg qref -m "solution to nasty bug!"
+                                  # save again with commit message
+     hg export -o ../nasty.diff tip
+                                  # export the patch
+     # send ../nasty.diff via email
+     hg qpop                      # undo the application of the patch
+                                  # and remove the changes from the
+                                  # source tree
+     hg qnew doc_improvements     # create an unrelated patch
+     # change doc sources...
+     hg qref -m "could not find myfav.m in the doc"
+                                  # save the changes into the patch
+     hg export -o ../doc.diff tip
+                                  # export the second patch
+     # send ../doc.diff tip via email
+     hg qpop
+     # discussion in the maintainers mailing list ...
+     hg qpush nasty_bug           # apply the patch again
+     # change sources yet again ...
+     hg qref
+     hg export -o ../nasty2.diff tip
+     # send ../nasty2.diff via email
+
+
+File: octave.info,  Node: General Guidelines,  Next: Octave Sources (m-files),  Prev: How to Contribute,  Up: Contributing Guidelines
+
+D.2 General Guidelines
+======================
+
+All Octave's sources are distributed under the General Public License
+(GPL).  Currently, Octave uses GPL version 3.  For details about this
+license, see `http://www.gnu.org/licenses/gpl.html'.  Therefore,
+whenever you create a new source file, it should have the following
+comment header (use appropriate year, name and comment marks):
+
+     ## Copyright (C) 1996, 1997, 2007 John W. Eaton <jwe at octave.org>
+     ##
+     ## This file is part of Octave.
+     ##
+     ## Octave is free software; you can redistribute it and/or
+     ## modify it under the terms of the GNU General Public
+     ## License as published by the Free Software Foundation;
+     ## either version 3 of the License, or (at your option) any
+     ## later version.
+     ##
+     ## Octave is distributed in the hope that it will be useful,
+     ## but WITHOUT ANY WARRANTY; without even the implied
+     ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     ## PURPOSE.  See the GNU General Public License for more
+     ## details.
+     ##
+     ## You should have received a copy of the GNU General Public
+     ## License along with Octave; see the file COPYING.  If not,
+     ## see <http://www.gnu.org/licenses/>.
+
+   Always include ChangeLog entries in changesets.  After making your
+source changes, record and briefly describe the changes in the nearest
+ChangeLog file upwards in the directory tree.  Use the previous entries
+as a template.  Your entry should contain your name and email, and the
+path to the modified source file relative to the parent directory of
+the ChangeLog file.  If there are more functions in the file, you
+should also include the name of the modified function (in parentheses
+after file path).  Example:
+
+     2008-04-02  David Bateman  <dbateman at free.fr>
+
+             * graphics.cc (void gnuplot_backend::close_figure (const
+             octave_value&) const): Allow for an input and output stream.
+
+The ChangeLog entries should describe what is changed, not why.  Any
+explanation of why a change is needed should appear as comments in the
+code, particularly if there is something that might not be obvious to
+someone reading it later.
+
+   The preferred comment mark for places that may need further
+attention is FIXME.
+
+
+File: octave.info,  Node: Octave Sources (m-files),  Next: C++ Sources,  Prev: General Guidelines,  Up: Contributing Guidelines
+
+D.3 Octave Sources (m-files)
+============================
+
+Don't use tabs.  Tabs cause trouble.  If you are used to them, set up
+your editor so that it converts tabs to spaces.  Indent the bodies of
+the statement blocks.  Recommended indent is 2 spaces.  When calling
+functions, put spaces after commas and before the calling parentheses,
+like this:
+
+       x = max (sin (y+3), 2);
+
+An exception are matrix and vector constructors:
+
+       [sin(x), cos(x)]
+
+Here, putting spaces after `sin', `cos' would result in a parse error.
+In indexing expression, do not put a space after the identifier (this
+differentiates indexing and function calls nicely).  The space after
+comma is not necessary if index expressions are simple, i.e., you may
+write
+       A(:,i,j)
+
+but
+
+       A([1:i-1;i+1:n], XI(:,2:n-1))
+
+   Use lowercase names if possible.  Uppercase is acceptable for
+variable names consisting of 1-2 letters.  Do not use mixed case names.
+Function names must be lowercase.  Function names are global, so choose
+them wisely.
+
+   Always use a specific end-of-block statement (like `endif',
+`endswitch') rather than generic `end'.  Enclose the `if', `while',
+`until' and `switch' conditions in parentheses, like in C:
+
+     if (isvector (a))
+       s = sum(a);
+     endif
+
+Do not do this, however, with `for':
+
+     for i = 1:n
+       b(i) = sum (a(:,i));
+     endfor
+
+
+File: octave.info,  Node: C++ Sources,  Next: Other Sources,  Prev: Octave Sources (m-files),  Up: Contributing Guidelines
+
+D.4 C++ Sources
+===============
+
+Don't use tabs.  Tabs cause trouble.  If you are used to them, set up
+your editor so that it converts tabs to spaces.  Format function
+headers like this:
+
+     static bool
+     matches_patterns (const string_vector& patterns, int pat_idx,
+     		  int num_pat, const std::string& name)
+
+The function name should start in column 1, and multi-line argument
+lists should be aligned on the first char after the open parenthesis.
+You should put a space after the left open parenthesis and after
+commas, for both function definitions and function calls.
+
+   Recommended indent is 2 spaces.  When indenting, indent the
+statement after control structures (like `if', `while', etc.). If there
+is a compound statement, indent both the curly braces and the body of
+the statement (so that the body gets indented by two indents).  Example:
+
+     if (have_args)
+       {
+         idx.push_back (first_args);
+         have_args = false;
+       }
+     else
+       idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
+
+If you have nested `if' statements, use extra braces for extra
+clarification.
+
+   Split long expressions in such a way that a continuation line starts
+with an operator rather than identifier.  If the split occurs inside
+braces, continuation should be aligned with the first char after the
+innermost braces enclosing the split.  Example:
+
+     SVD::type type = ((nargout == 0 || nargout == 1)
+                       ? SVD::sigma_only
+                       : (nargin == 2) ? SVD::economy : SVD::std);
+
+Consider putting extra braces around a multiline expression to make it
+more readable, even if they are not necessary.  Also, do not hesitate
+to put extra braces anywhere if it improves clarity.
+
+   Try declaring variables just before they're needed.  Use local
+variables of blocks - it helps optimization.  Don't write multi-line
+variable declaration with a single type specification and multiple
+variables.  If the variables don't fit on single line, repeat the type
+specification.  Example:
+
+     octave_value retval;
+
+     octave_idx_type nr = b.rows ();
+     octave_idx_type nc = b.cols ();
+
+     double d1, d2;
+
+   Use lowercase names if possible.  Uppercase is acceptable for
+variable names consisting of 1-2 letters.  Do not use mixed case names.
+
+   Try to use Octave's types and classes if possible.  Otherwise, try
+to use C++ standard library.  Use of STL containers and algorithms is
+encouraged.  Use templates wisely to reduce code duplication.  Avoid
+comma expressions, labels and gotos, and explicit typecasts.  If you
+need to typecast, use the modern C++ casting operators.  In functions,
+try to reduce the number of `return' statements - use nested `if'
+statements if possible.
+
+
+File: octave.info,  Node: Other Sources,  Prev: C++ Sources,  Up: Contributing Guidelines
+
+D.5 Other Sources
+=================
+
+Apart from C++ and Octave language (m-files), Octave's sources include
+files written in C, Fortran, M4, perl, unix shell, AWK, texinfo and
+TeX.  There are not many rules to follow when using these other
+languages; some of them are summarized below.  In any case, the golden
+rule is: if you modify a source file, try to follow any conventions you
+can detect in the file or other similar files.
+
+   For C you should obviously follow all C++ rules that can apply.
+
+   If you happen to modify a Fortran file, you should stay within
+Fortran 77 with common extensions like `END DO'.  Currently, we want
+all sources to be compilable with the f2c and g77 compilers, without
+special flags if possible.  This usually means that non-legacy
+compilers also accept the sources.
+
+   The M4 macro language is mainly used for autoconf configuration
+files.  You should follow normal M4 rules when contributing to these
+files.  Some M4 files come from external source, namely the Autoconf
+archive `http://autoconf-archive.cryp.to'.
+
+   If you give a code example in the documentation written in texinfo
+with the `@example' environment, you should be aware that the text
+within such an environment will not be wrapped.  It is recommended that
+you keep the lines short enough to fit on pages in the generated pdf or
+ps documents.  Here is a ruler (in an `@example' environment) for
+finding the appropriate line width:
+
+              1         2         3         4         5         6
+     123456789012345678901234567890123456789012345678901234567890
+
+
+File: octave.info,  Node: Trouble,  Next: Installation,  Prev: Contributing Guidelines,  Up: Top
+
+Appendix E Known Causes of Trouble
+**********************************
+
+   This section describes known problems that affect users of Octave.
+Most of these are not Octave bugs per se--if they were, we would fix
+them.  But the result for a user may be like the result of a bug.
+
+   Some of these problems are due to bugs in other software, some are
+missing features that are too much work to add, and some are places
+where people's opinions differ as to what is best.
+
+* Menu:
+
+* Actual Bugs::                 Bugs we will fix later.
+* Reporting Bugs::
+* Bug Criteria::
+* Bug Lists::
+* Bug Reporting::
+* Sending Patches::
+* Service::
+
+
+File: octave.info,  Node: Actual Bugs,  Next: Reporting Bugs,  Up: Trouble
+
+E.1 Actual Bugs We Haven't Fixed Yet
+====================================
+
+   * Output that comes directly from Fortran functions is not sent
+     through the pager and may appear out of sequence with other output
+     that is sent through the pager.  One way to avoid this is to force
+     pending output to be flushed before calling a function that will
+     produce output from within Fortran functions.  To do this, use the
+     command
+
+          fflush (stdout)
+
+     Another possible workaround is to use the command
+
+          page_screen_output (false);
+
+     to turn the pager off.
+
+   A list of ideas for future enhancements is distributed with Octave.
+See the file `PROJECTS' in the top level directory in the source
+distribution.
+
+
+File: octave.info,  Node: Reporting Bugs,  Next: Bug Criteria,  Prev: Actual Bugs,  Up: Trouble
+
+E.2 Reporting Bugs
+==================
+
+Your bug reports play an essential role in making Octave reliable.
+
+   When you encounter a problem, the first thing to do is to see if it
+is already known.  *Note Trouble::.  If it isn't known, then you should
+report the problem.
+
+   Reporting a bug may help you by bringing a solution to your problem,
+or it may not.  In any case, the principal function of a bug report is
+to help the entire community by making the next version of Octave work
+better.  Bug reports are your contribution to the maintenance of Octave.
+
+   In order for a bug report to serve its purpose, you must include the
+information that makes it possible to fix the bug.
+
+   If you have Octave working at all, the easiest way to prepare a
+complete bug report is to use the Octave function `bug_report'.  When
+you execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+ -- Function File:  bug_report ()
+     Have Octave create a bug report template file, invoke your favorite
+     editor, and submit the report to the bug-octave mailing list when
+     you are finished editing.
+
+* Menu:
+
+* Bug Criteria::
+* Where: Bug Lists.             Where to send your bug report.
+* Reporting: Bug Reporting.     How to report a bug effectively.
+* Patches: Sending Patches.     How to send a patch for Octave.
+
+
+File: octave.info,  Node: Bug Criteria,  Next: Bug Lists,  Prev: Reporting Bugs,  Up: Trouble
+
+E.3 Have You Found a Bug?
+=========================
+
+If you are not sure whether you have found a bug, here are some
+guidelines:
+
+   * If Octave gets a fatal signal, for any input whatever, that is a
+     bug.  Reliable interpreters never crash.
+
+   * If Octave produces incorrect results, for any input whatever, that
+     is a bug.
+
+   * Some output may appear to be incorrect when it is in fact due to a
+     program whose behavior is undefined, which happened by chance to
+     give the desired results on another system.  For example, the
+     range operator may produce different results because of
+     differences in the way floating point arithmetic is handled on
+     various systems.
+
+   * If Octave produces an error message for valid input, that is a bug.
+
+   * If Octave does not produce an error message for invalid input,
+     that is a bug.  However, you should note that your idea of
+     "invalid input" might be my idea of "an extension" or "support for
+     traditional practice".
+
+   * If you are an experienced user of programs like Octave, your
+     suggestions for improvement are welcome in any case.
+
+
+File: octave.info,  Node: Bug Lists,  Next: Bug Reporting,  Prev: Bug Criteria,  Up: Trouble
+
+E.4 Where to Report Bugs
+========================
+
+If you have Octave working at all, the easiest way to prepare a complete
+bug report is to use the Octave function `bug_report'.  When you
+execute this function, Octave will prompt you for a subject and then
+invoke the editor on a file that already contains all the configuration
+information.  When you exit the editor, Octave will mail the bug report
+for you.
+
+   If for some reason you cannot use Octave's `bug_report' function,
+send bug reports for Octave to <bug at octave.org>.
+
+   *Do not send bug reports to `help-octave'*.  Most users of Octave do
+not want to receive bug reports.  Those that do have asked to be on the
+mailing list.
+
+
+File: octave.info,  Node: Bug Reporting,  Next: Sending Patches,  Prev: Bug Lists,  Up: Trouble
+
+E.5 How to Report Bugs
+======================
+
+Send bug reports for Octave to one of the addresses listed in *note Bug
+Lists::.
+
+   The fundamental principle of reporting bugs usefully is this:
+*report all the facts*.  If you are not sure whether to state a fact or
+leave it out, state it!
+
+   Often people omit facts because they think they know what causes the
+problem and they conclude that some details don't matter.  Thus, you
+might assume that the name of the variable you use in an example does
+not matter.  Well, probably it doesn't, but one cannot be sure.
+Perhaps the bug is a stray memory reference which happens to fetch from
+the location where that name is stored in memory; perhaps, if the name
+were different, the contents of that location would fool the
+interpreter into doing the right thing despite the bug.  Play it safe
+and give a specific, complete example.
+
+   Keep in mind that the purpose of a bug report is to enable someone to
+fix the bug if it is not known.  Always write your bug reports on the
+assumption that the bug is not known.
+
+   Sometimes people give a few sketchy facts and ask, "Does this ring a
+bell?"  This cannot help us fix a bug.  It is better to send a complete
+bug report to begin with.
+
+   Try to make your bug report self-contained.  If we have to ask you
+for more information, it is best if you include all the previous
+information in your response, as well as the information that was
+missing.
+
+   To enable someone to investigate the bug, you should include all
+these things:
+
+   * The version of Octave.  You can get this by noting the version
+     number that is printed when Octave starts, or running it with the
+     `-v' option.
+
+   * A complete input file that will reproduce the bug.
+
+     A single statement may not be enough of an example--the bug might
+     depend on other details that are missing from the single statement
+     where the error finally occurs.
+
+   * The command arguments you gave Octave to execute that example and
+     observe the bug.  To guarantee you won't omit something important,
+     list all the options.
+
+     If we were to try to guess the arguments, we would probably guess
+     wrong and then we would not encounter the bug.
+
+   * The type of machine you are using, and the operating system name
+     and version number.
+
+   * The command-line arguments you gave to the `configure' command when
+     you installed the interpreter.
+
+   * A complete list of any modifications you have made to the
+     interpreter source.
+
+     Be precise about these changes--show a context diff for them.
+
+   * Details of any other deviations from the standard procedure for
+     installing Octave.
+
+   * A description of what behavior you observe that you believe is
+     incorrect.  For example, "The interpreter gets a fatal signal,"
+     or, "The output produced at line 208 is incorrect."
+
+     Of course, if the bug is that the interpreter gets a fatal signal,
+     then one can't miss it.  But if the bug is incorrect output, we
+     might not notice unless it is glaringly wrong.
+
+     Even if the problem you experience is a fatal signal, you should
+     still say so explicitly.  Suppose something strange is going on,
+     such as, your copy of the interpreter is out of synch, or you have
+     encountered a bug in the C library on your system.  Your copy
+     might crash and the copy here would not.  If you said to expect a
+     crash, then when the interpreter here fails to crash, we would
+     know that the bug was not happening.  If you don't say to expect a
+     crash, then we would not know whether the bug was happening.  We
+     would not be able to draw any conclusion from our observations.
+
+     Often the observed symptom is incorrect output when your program
+     is run.  Unfortunately, this is not enough information unless the
+     program is short and simple.  It is very helpful if you can
+     include an explanation of the expected output, and why the actual
+     output is incorrect.
+
+   * If you wish to suggest changes to the Octave source, send them as
+     context diffs.  If you even discuss something in the Octave source,
+     refer to it by context, not by line number, because the line
+     numbers in the development sources probably won't match those in
+     your sources.
+
+   Here are some things that are not necessary:
+
+   * A description of the envelope of the bug.
+
+     Often people who encounter a bug spend a lot of time investigating
+     which changes to the input file will make the bug go away and
+     which changes will not affect it.  Such information is usually not
+     necessary to enable us to fix bugs in Octave, but if you can find
+     a simpler example to report _instead_ of the original one, that is
+     a convenience.  Errors in the output will be easier to spot,
+     running under the debugger will take less time, etc.  Most Octave
+     bugs involve just one function, so the most straightforward way to
+     simplify an example is to delete all the function definitions
+     except the one in which the bug occurs.
+
+     However, simplification is not vital; if you don't want to do
+     this, report the bug anyway and send the entire test case you used.
+
+   * A patch for the bug.  Patches can be helpful, but if you find a
+     bug, you should report it, even if you cannot send a fix for the
+     problem.
+
+
+File: octave.info,  Node: Sending Patches,  Next: Service,  Prev: Bug Reporting,  Up: Trouble
+
+E.6 Sending Patches for Octave
+==============================
+
+If you would like to write bug fixes or improvements for Octave, that is
+very helpful.  When you send your changes, please follow these
+guidelines to avoid causing extra work for us in studying the patches.
+
+   If you don't follow these guidelines, your information might still be
+useful, but using it will take extra work.  Maintaining Octave is a lot
+of work in the best of circumstances, and we can't keep up unless you do
+your best to help.
+
+   * Send an explanation with your changes of what problem they fix or
+     what improvement they bring about.  For a bug fix, just include a
+     copy of the bug report, and explain why the change fixes the bug.
+
+   * Always include a proper bug report for the problem you think you
+     have fixed.  We need to convince ourselves that the change is
+     right before installing it.  Even if it is right, we might have
+     trouble judging it if we don't have a way to reproduce the problem.
+
+   * Include all the comments that are appropriate to help people
+     reading the source in the future understand why this change was
+     needed.
+
+   * Don't mix together changes made for different reasons.  Send them
+     _individually_.
+
+     If you make two changes for separate reasons, then we might not
+     want to install them both.  We might want to install just one.
+
+   * Use `diff -c' to make your diffs.  Diffs without context are hard
+     for us to install reliably.  More than that, they make it hard for
+     us to study the diffs to decide whether we want to install them.
+     Unidiff format is better than contextless diffs, but not as easy
+     to read as `-c' format.
+
+     If you have GNU diff, use `diff -cp', which shows the name of the
+     function that each change occurs in.
+
+   * Write the change log entries for your changes.
+
+     Read the `ChangeLog' file to see what sorts of information to put
+     in, and to learn the style that we use.  The purpose of the change
+     log is to show people where to find what was changed.  So you need
+     to be specific about what functions you changed; in large
+     functions, it's often helpful to indicate where within the
+     function the change was made.
+
+     On the other hand, once you have shown people where to find the
+     change, you need not explain its purpose.  Thus, if you add a new
+     function, all you need to say about it is that it is new.  If you
+     feel that the purpose needs explaining, it probably does--but the
+     explanation will be much more useful if you put it in comments in
+     the code.
+
+     If you would like your name to appear in the header line for who
+     made the change, send us the header line.
+
+
+File: octave.info,  Node: Service,  Prev: Sending Patches,  Up: Trouble
+
+E.7 How To Get Help with Octave
+===============================
+
+The mailing list <help at octave.org> exists for the discussion of matters
+related to using and installing Octave.  If would like to join the
+discussion, please send a short note to <help*-request*@octave.org>.
+
+   *Please do not* send requests to be added or removed from the
+mailing list, or other administrative trivia to the list itself.
+
+   If you think you have found a bug in the installation procedure,
+however, you should send a complete bug report for the problem to
+<bug at octave.org>.  *Note Bug Reporting::, for information that will
+help you to submit a useful report.
+
+
+File: octave.info,  Node: Installation,  Next: Emacs Octave Support,  Prev: Trouble,  Up: Top
+
+Appendix F Installing Octave
+****************************
+
+   Here is the procedure for installing Octave from scratch on a Unix
+system.
+
+   * Run the shell script `configure'.  This will determine the features
+     your system has (or doesn't have) and create a file named
+     `Makefile' from each of the files named `Makefile.in'.
+
+     Here is a summary of the configure options that are most
+     frequently used when building Octave:
+
+    `--prefix=PREFIX'
+          Install Octave in subdirectories below PREFIX.  The default
+          value of PREFIX is `/usr/local'.
+
+    `--srcdir=DIR'
+          Look for Octave sources in the directory DIR.
+
+    `--enable-bounds-check'
+          Enable bounds checking for indexing operators in the internal
+          array classes.  This option is primarily used for debugging
+          Octave.  Building Octave with this option has a negative
+          impact on performance and is not recommended for general use.
+
+    `--enable-64'
+          This is an *experimental* option to enable Octave to use
+          64-bit integers for array dimensions and indexing on 64-bit
+          platforms.  You probably don't want to use this option unless
+          you know what you are doing.
+
+          If you use `--enable-64', you must ensure that your Fortran
+          compiler generates code with 8 byte signed `INTEGER' values,
+          and that your BLAS and LAPACK libraries are compiled to use 8
+          byte signed integers for array dimensions and indexing.
+
+    `--enable-shared'
+          Create shared libraries (this is the default).  If you are
+          planning to use the dynamic loading features, you will
+          probably want to use this option.  It will make your `.oct'
+          files much smaller and on some systems it may be necessary to
+          build shared libraries in order to use dynamically linked
+          functions.
+
+          You may also want to build a shared version of `libstdc++',
+          if your system doesn't already have one.
+
+    `--enable-dl'
+          Use `dlopen' and friends to make Octave capable of dynamically
+          linking externally compiled functions (this is the default if
+          `--enable-shared' is specified).  This option only works on
+          systems that actually have these functions.  If you plan on
+          using this feature, you should probably also use
+          `--enable-shared' to reduce the size of your `.oct' files.
+
+    `--without-blas'
+          Compile and use the generic BLAS and LAPACK versions included
+          with Octave.  By default, configure first looks for BLAS and
+          LAPACK matrix libraries on your system, including optimized
+          BLAS implementations such as the free ATLAS 3.0, as well as
+          vendor-tuned libraries.  (The use of an optimized BLAS will
+          generally result in several-times faster matrix operations.)
+          Only use this option if your system has BLAS/LAPACK libraries
+          that cause problems for some reason.  You can also use
+          `--with-blas=lib' to specify a particular BLAS library  that
+          configure doesn't check for automatically.
+
+    `--without-ccolamd'
+          Don't use CCOLAMD, disable some sparse matrix functionality.
+
+    `--without-colamd'
+          Don't use COLAMD, disable some sparse matrix functionality.
+
+    `--without-curl'
+          Don't use the cURL, disable the `urlread' and `urlwrite'
+          functions.
+
+    `--without-cxsparse'
+          Don't use CXSPARSE, disable some sparse matrix functionality.
+
+    `--without-umfpack'
+          Don't use UMFPACK, disable some sparse matrix functionality.
+
+    `--without-fftw'
+          Use the included FFTPACK library instead of the FFTW library.
+
+    `--without-glpk'
+          Don't use the GLPK library for linear programming.
+
+    `--without-hdf5'
+          Don't use the HDF5 library for reading and writing HDF5 files.
+
+    `--without-zlib'
+          Don't use the zlib library, disable data file compression and
+          support for recent MAT file formats.
+
+    `--without-lapack'
+          Compile and use the generic BLAS and LAPACK versions included
+          with Octave.  By default, configure first looks for BLAS and
+          LAPACK matrix libraries on your system, including optimized
+          BLAS implementations such as the free ATLAS 3.0, as well as
+          vendor-tuned libraries.  (The use of an optimized BLAS will
+          generally result in several-times faster matrix operations.)
+          Only use this option if your system has BLAS/LAPACK libraries
+          that cause problems for some reason.  You can also use
+          `--with-blas=lib' to specify a particular BLAS library  that
+          configure doesn't check for automatically.
+
+    `--without-framework-carbon'
+          Don't use framework Carbon headers, libraries and specific
+          source code for compilation even if the configure test
+          succeeds (the default value is `--with-framework-carbon').
+          This is a platform specific configure option for Mac systems.
+
+    `--without-framework-opengl'
+          Don't use framework OpenGL headers, libraries and specific
+          source code for compilation even if the configure test
+          succeeds.  If this option is given then OpenGL headers and
+          libraries in standard system locations are tested (the
+          default value is `--with-framework-opengl').  This is a
+          platform specific configure option for Mac systems.
+
+    `--help'
+          Print a summary of the options recognized by the configure
+          script.
+
+     See the file `INSTALL' for more general information about the
+     command line options used by configure.  That file also contains
+     instructions for compiling in a directory other than where the
+     source is located.
+
+   * Run make.
+
+     You will need a recent version of GNU Make.  Modifying Octave's
+     makefiles to work with other make programs is probably not worth
+     your time.  We recommend you get and compile GNU Make instead.
+
+     For plotting, you will need to have gnuplot installed on your
+     system.  Gnuplot is a command-driven interactive function plotting
+     program.  Gnuplot is copyrighted, but freely distributable.  The
+     `gnu' in gnuplot is a coincidence--it is not related to the GNU
+     project or the FSF in any but the most peripheral sense.
+
+     To compile Octave, you will need a recent version of GNU Make.
+     You will also need a recent version of `g++' or other ANSI C++
+     compiler.  You will also need a Fortran 77 compiler or `f2c'.  If
+     you use `f2c', you will need a script like `fort77' that works
+     like a normal Fortran compiler by combining `f2c' with your C
+     compiler in a single script.
+
+     If you plan to modify the parser you will also need GNU `bison' and
+     `flex'.  If you modify the documentation, you will need GNU
+     Texinfo, along with the patch for the `makeinfo' program that is
+     distributed with Octave.
+
+     GNU Make, `gcc', and `libstdc++', `gnuplot', `bison', `flex', and
+     Texinfo are all available from many anonymous ftp archives.  The
+     primary site is `ftp.gnu.org', but it is often very busy.  A list
+     of sites that mirror the software on `ftp.gnu.org' is available by
+     anonymous ftp from `ftp://ftp.gnu.org/pub/gnu/GNUinfo/FTP'.
+
+     You will need about 1 gigabyte of disk storage to work with when
+     building Octave from source (considerably less if you don't
+     compile with debugging symbols).  To do that, use the command
+
+          make CFLAGS=-O CXXFLAGS=-O LDFLAGS=
+
+     instead of just `make'.
+
+   * If you encounter errors while compiling Octave, first check the
+     list of known problems below to see if there is a workaround or
+     solution for your problem.  If not, see *note Trouble::, for
+     information about how to report bugs.
+
+   * Once you have successfully compiled Octave, run `make install'.
+
+     This will install a copy of Octave, its libraries, and its
+     documentation in the destination directory.  As distributed,
+     Octave is installed in the following directories.  In the table
+     below, PREFIX defaults to `/usr/local', VERSION stands for the
+     current version number of the interpreter, and ARCH is the type of
+     computer on which Octave is installed (for example,
+     `i586-unknown-gnu').
+
+    `PREFIX/bin'
+          Octave and other binaries that people will want to run
+          directly.
+
+    `PREFIX/lib'
+          Libraries like libcruft.a and liboctave.a.
+
+    `PREFIX/share'
+          Architecture-independent data files.
+
+    `PREFIX/include/octave'
+          Include files distributed with Octave.
+
+    `PREFIX/man/man1'
+          Unix-style man pages describing Octave.
+
+    `PREFIX/info'
+          Info files describing Octave.
+
+    `PREFIX/share/octave/VERSION/m'
+          Function files distributed with Octave.  This includes the
+          Octave version, so that multiple versions of Octave may be
+          installed at the same time.
+
+    `PREFIX/lib/octave/VERSION/exec/ARCH'
+          Executables to be run by Octave rather than the user.
+
+    `PREFIX/lib/octave/VERSION/oct/ARCH'
+          Object files that will be dynamically loaded.
+
+    `PREFIX/share/octave/VERSION/imagelib'
+          Image files that are distributed with Octave.
+
+* Menu:
+
+* Installation Problems::
+
+
+File: octave.info,  Node: Installation Problems,  Up: Installation
+
+F.1 Installation Problems
+=========================
+
+This section contains a list of problems (and some apparent problems
+that don't really mean anything is wrong) that may show up during
+installation of Octave.
+
+   * On some SCO systems, `info' fails to compile if `HAVE_TERMIOS_H'
+     is defined in `config.h'.  Simply removing the definition from
+     `info/config.h' should allow it to compile.
+
+   * If `configure' finds `dlopen', `dlsym', `dlclose', and `dlerror',
+     but not the header file `dlfcn.h', you need to find the source for
+     the header file and install it in the directory `usr/include'.
+     This is reportedly a problem with Slackware 3.1.  For Linux/GNU
+     systems, the source for `dlfcn.h' is in the `ldso' package.
+
+   * Building `.oct' files doesn't work.
+
+     You should probably have a shared version of `libstdc++'.  A patch
+     is needed to build shared versions of version 2.7.2 of `libstdc++'
+     on the HP-PA architecture.  You can find the patch at
+     `ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix'.
+
+   * On some alpha systems there may be a problem with the `libdxml'
+     library, resulting in floating point errors and/or segmentation
+     faults in the linear algebra routines called by Octave.  If you
+     encounter such problems, then you should modify the configure
+     script so that `SPECIAL_MATH_LIB' is not set to `-ldxml'.
+
+   * On FreeBSD systems Octave may hang while initializing some internal
+     constants.  The fix appears to be to use
+
+          options      GPL_MATH_EMULATE
+
+     rather than
+
+          options      MATH_EMULATE
+
+     in the kernel configuration files (typically found in the directory
+     `/sys/i386/conf'.  After making this change, you'll need to rebuild
+     the kernel, install it, and reboot.
+
+   * If you encounter errors like
+
+          passing `void (*)()' as argument 2 of
+            `octave_set_signal_handler(int, void (*)(int))'
+
+     or
+
+          warning: ANSI C++ prohibits conversion from `(int)'
+                   to `(...)'
+
+     while compiling `sighandlers.cc', you may need to edit some files
+     in the `gcc' include subdirectory to add proper prototypes for
+     functions there.  For example, Ultrix 4.2 needs proper
+     declarations for the `signal' function and the `SIG_IGN' macro in
+     the file `signal.h'.
+
+     On some systems the `SIG_IGN' macro is defined to be something like
+     this:
+
+          #define  SIG_IGN  (void (*)())1
+
+     when it should really be something like:
+
+          #define  SIG_IGN  (void (*)(int))1
+
+     to match the prototype declaration for the `signal' function.  This
+     change should also be made for the `SIG_DFL' and `SIG_ERR'
+     symbols.  It may be necessary to change the definitions in
+     `sys/signal.h' as well.
+
+     The `gcc' `fixincludes' and `fixproto' scripts should probably fix
+     these problems when `gcc' installs its modified set of header
+     files, but I don't think that's been done yet.
+
+     *You should not change the files in `/usr/include'*.  You can find
+     the `gcc' include directory tree by running the command
+
+          gcc -print-libgcc-file-name
+
+     The directory of `gcc' include files normally begins in the same
+     directory that contains the file `libgcc.a'.
+
+   * Some of the Fortran subroutines may fail to compile with older
+     versions of the Sun Fortran compiler.  If you get errors like
+
+          zgemm.f:
+          	zgemm:
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 245: warning: unexpected parent of complex
+            expression subtree
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 304: warning: unexpected parent of complex
+            expression subtree
+          warning: unexpected parent of complex expression subtree
+          zgemm.f, line 327: warning: unexpected parent of complex
+            expression subtree
+          pcc_binval: missing IR_CONV in complex op
+          make[2]: *** [zgemm.o] Error 1
+
+     when compiling the Fortran subroutines in the `libcruft'
+     subdirectory, you should either upgrade your compiler or try
+     compiling with optimization turned off.
+
+   * On NeXT systems, if you get errors like this:
+
+          /usr/tmp/cc007458.s:unknown:Undefined local
+                symbol LBB7656
+          /usr/tmp/cc007458.s:unknown:Undefined local
+                symbol LBE7656
+
+     when compiling `Array.cc' and `Matrix.cc', try recompiling these
+     files without `-g'.
+
+   * Some people have reported that calls to shell_cmd and the pager do
+     not work on SunOS systems.  This is apparently due to having
+     `G_HAVE_SYS_WAIT' defined to be 0 instead of 1 when compiling
+     `libg++'.
+
+   * On NeXT systems, linking to `libsys_s.a' may fail to resolve the
+     following functions
+
+          _tcgetattr
+          _tcsetattr
+          _tcflow
+
+     which are part of `libposix.a'.  Unfortunately, linking Octave with
+     `-posix' results in the following undefined symbols.
+
+          .destructors_used
+          .constructors_used
+          _objc_msgSend
+          _NXGetDefaultValue
+          _NXRegisterDefaults
+          .objc_class_name_NXStringTable
+          .objc_class_name_NXBundle
+
+     One kluge around this problem is to extract `termios.o' from
+     `libposix.a', put it in Octave's `src' directory, and add it to
+     the list of files to link together in the makefile.  Suggestions
+     for better ways to solve this problem are welcome!
+
+   * If Octave crashes immediately with a floating point exception, it
+     is likely that it is failing to initialize the IEEE floating point
+     values for infinity and NaN.
+
+     If your system actually does support IEEE arithmetic, you should
+     be able to fix this problem by modifying the function
+     `octave_ieee_init' in the file `lo-ieee.cc' to correctly
+     initialize Octave's internal infinity and NaN variables.
+
+     If your system does not support IEEE arithmetic but Octave's
+     configure script incorrectly determined that it does, you can work
+     around the problem by editing the file `config.h' to not define
+     `HAVE_ISINF', `HAVE_FINITE', and `HAVE_ISNAN'.
+
+     In any case, please report this as a bug since it might be
+     possible to modify Octave's configuration script to automatically
+     determine the proper thing to do.
+
+   * If Octave is unable to find a header file because it is installed
+     in a location that is not normally searched by the compiler, you
+     can add the directory to the include search path by specifying
+     (for example) `CPPFLAGS=-I/some/nonstandard/directory' as an
+     argument to `configure'.  Other variables that can be specified
+     this way are `CFLAGS', `CXXFLAGS', `FFLAGS', and `LDFLAGS'.
+     Passing them as options to the configure script also records them
+     in the `config.status' file.  By default, `CPPFLAGS' and `LDFLAGS'
+     are empty, `CFLAGS' and `CXXFLAGS' are set to `"-g -O"' and
+     `FFLAGS' is set to `"-O"'.
+
+
+
+File: octave.info,  Node: Emacs Octave Support,  Next: Copying,  Prev: Installation,  Up: Top
+
+Appendix G Emacs Octave Support
+*******************************
+
+The development of Octave code can greatly be facilitated using Emacs
+with Octave mode, a major mode for editing Octave files which can e.g.
+automatically indent the code, do some of the typing (with Abbrev mode)
+and show keywords, comments, strings, etc. in different faces (with
+Font-lock mode on devices that support it).
+
+   It is also possible to run Octave from within Emacs, either by
+directly entering commands at the prompt in a buffer in Inferior Octave
+mode, or by interacting with Octave from within a file with Octave
+code.  This is useful in particular for debugging Octave code.
+
+   Finally, you can convince Octave to use the Emacs info reader for
+`help -i'.
+
+   All functionality is provided by the Emacs Lisp package EOS (for
+"Emacs Octave Support").  This chapter describes how to set up and use
+this package.
+
+   Please contact <Kurt.Hornik at wu-wien.ac.at> if you have any questions
+or suggestions on using EOS.
+
+* Menu:
+
+* Installing EOS::
+* Using Octave Mode::
+* Running Octave From Within Emacs::
+* Using the Emacs Info Reader for Octave::
+
+
+File: octave.info,  Node: Installing EOS,  Next: Using Octave Mode,  Up: Emacs Octave Support
+
+G.1 Installing EOS
+==================
+
+The Emacs package EOS consists of the three files `octave-mod.el',
+`octave-inf.el', and `octave-hlp.el'.  These files, or better yet their
+byte-compiled versions, should be somewhere in your Emacs load-path.
+
+   If you have GNU Emacs with a version number at least as high as
+19.35, you are all set up, because EOS is respectively will be part of
+GNU Emacs as of version 19.35.
+
+   Otherwise, copy the three files from the `emacs' subdirectory of the
+Octave distribution to a place where Emacs can find them (this depends
+on how your Emacs was installed).  Byte-compile them for speed if you
+want.
+
+
+File: octave.info,  Node: Using Octave Mode,  Next: Running Octave From Within Emacs,  Prev: Installing EOS,  Up: Emacs Octave Support
+
+G.2 Using Octave Mode
+=====================
+
+If you are lucky, your sysadmins have already arranged everything so
+that Emacs automatically goes into Octave mode whenever you visit an
+Octave code file as characterized by its extension `.m'.  If not,
+proceed as follows.
+
+  1. To begin using Octave mode for all `.m' files you visit, add the
+     following lines to a file loaded by Emacs at startup time,
+     typically your `~/.emacs' file:
+
+          (autoload 'octave-mode "octave-mod" nil t)
+          (setq auto-mode-alist
+                (cons '("\\.m$" . octave-mode) auto-mode-alist))
+
+  2. Finally, to turn on the abbrevs, auto-fill and font-lock features
+     automatically, also add the following lines to one of the Emacs
+     startup files:
+          (add-hook 'octave-mode-hook
+                    (lambda ()
+                      (abbrev-mode 1)
+                      (auto-fill-mode 1)
+                      (if (eq window-system 'x)
+                          (font-lock-mode 1))))
+     See the Emacs manual for more information about how to customize
+     Font-lock mode.
+
+   In Octave mode, the following special Emacs commands can be used in
+addition to the standard Emacs commands.
+
+`C-h m'
+     Describe the features of Octave mode.
+
+`LFD'
+     Reindent the current Octave line, insert a newline and indent the
+     new line (`octave-reindent-then-newline-and-indent').  An abbrev
+     before point is expanded if `abbrev-mode' is non-`nil'.
+
+`TAB'
+     Indents current Octave line based on its contents and on previous
+     lines (`indent-according-to-mode').
+
+`;'
+     Insert an "electric" semicolon (`octave-electric-semi').  If
+     `octave-auto-indent' is non-`nil', reindent the current line.  If
+     `octave-auto-newline' is non-`nil', automagically insert a newline
+     and indent the new line.
+
+``'
+     Start entering an abbreviation (`octave-abbrev-start').  If Abbrev
+     mode is turned on, typing ``C-h' or ``?' lists all abbrevs.  Any
+     other key combination is executed normally.  Note that all Octave
+     abbrevs start with a grave accent.
+
+`M-LFD'
+     Break line at point and insert continuation marker and alignment
+     (`octave-split-line').
+
+`M-TAB'
+     Perform completion on Octave symbol preceding point, comparing that
+     symbol against Octave's reserved words and built-in variables
+     (`octave-complete-symbol').
+
+`M-C-a'
+     Move backward to the beginning of a function
+     (`octave-beginning-of-defun').  With prefix argument N, do it that
+     many times if N is positive;  otherwise, move forward to the N-th
+     following beginning of a function.
+
+`M-C-e'
+     Move forward to the end of a function (`octave-end-of-defun').
+     With prefix argument N, do it that many times if N is positive;
+     otherwise, move back to the N-th preceding end of a function.
+
+`M-C-h'
+     Puts point at beginning and mark at the end of the current Octave
+     function, i.e., the one containing point or following point
+     (`octave-mark-defun').
+
+`M-C-q'
+     Properly indents the Octave function which contains point
+     (`octave-indent-defun').
+
+`M-;'
+     If there is no comment already on this line, create a code-level
+     comment (started by two comment characters) if the line is empty,
+     or an in-line comment (started by one comment character) otherwise
+     (`octave-indent-for-comment').  Point is left after the start of
+     the comment which is properly aligned.
+
+`C-c ;'
+     Puts the comment character `#' (more precisely, the string value of
+     `octave-comment-start') at the beginning of every line in the
+     region (`octave-comment-region').  With just `C-u' prefix
+     argument, uncomment each line in the region.  A numeric prefix
+     argument N means use N comment characters.
+
+`C-c :'
+     Uncomments every line in the region (`octave-uncomment-region').
+
+`C-c C-p'
+     Move one line of Octave code backward, skipping empty and comment
+     lines (`octave-previous-code-line').  With numeric prefix argument
+     N, move that many code lines backward (forward if N is negative).
+
+`C-c C-n'
+     Move one line of Octave code forward, skipping empty and comment
+     lines (`octave-next-code-line').  With numeric prefix argument N,
+     move that many code lines forward (backward if N is negative).
+
+`C-c C-a'
+     Move to the `real' beginning of the current line
+     (`octave-beginning-of-line').  If point is in an empty or comment
+     line, simply go to its beginning;  otherwise, move backwards to the
+     beginning of the first code line which is not inside a continuation
+     statement, i.e., which does not follow a code line ending in `...'
+     or `\', or is inside an open parenthesis list.
+
+`C-c C-e'
+     Move to the `real' end of the current line (`octave-end-of-line').
+     If point is in a code line, move forward to the end of the first
+     Octave code line which does not end in `...' or `\' or is inside an
+     open parenthesis list.  Otherwise, simply go to the end of the
+     current line.
+
+`C-c M-C-n'
+     Move forward across one balanced begin-end block of Octave code
+     (`octave-forward-block').  With numeric prefix argument N, move
+     forward across N such blocks (backward if N is negative).
+
+`C-c M-C-p'
+     Move back across one balanced begin-end block of Octave code
+     (`octave-backward-block').  With numeric prefix argument N, move
+     backward across N such blocks (forward if N is negative).
+
+`C-c M-C-d'
+     Move forward down one begin-end block level of Octave code
+     (`octave-down-block').  With numeric prefix argument, do it that
+     many times;  a negative argument means move backward, but still go
+     down one level.
+
+`C-c M-C-u'
+     Move backward out of one begin-end block level of Octave code
+     (`octave-backward-up-block').  With numeric prefix argument, do it
+     that many times; a negative argument means move forward, but still
+     to a less deep spot.
+
+`C-c M-C-h'
+     Put point at the beginning of this block, mark at the end
+     (`octave-mark-block').  The block marked is the one that contains
+     point or follows point.
+
+`C-c ]'
+     Close the current block on a separate line (`octave-close-block').
+     An error is signaled if no block to close is found.
+
+`C-c f'
+     Insert a function skeleton, prompting for the function's name,
+     arguments and return values which have to be entered without
+     parentheses (`octave-insert-defun').
+
+`C-c C-h'
+     Search the function, operator and variable indices of all info
+     files with documentation for Octave for entries (`octave-help').
+     If used interactively, the entry is prompted for with completion.
+     If multiple matches are found, one can cycle through them using
+     the standard `,' (`Info-index-next') command of the Info reader.
+
+     The variable `octave-help-files' is a list of files to search
+     through and defaults to `'("octave")'.  If there is also an Octave
+     Local Guide with corresponding info file, say, `octave-LG', you can
+     have `octave-help' search both files by
+          (setq octave-help-files '("octave" "octave-LG"))
+     in one of your Emacs startup files.
+
+
+   A common problem is that the <RET> key does _not_ indent the line to
+where the new text should go after inserting the newline.  This is
+because the standard Emacs convention is that <RET> (aka `C-m') just
+adds a newline, whereas <LFD> (aka `C-j') adds a newline and indents
+it.  This is particularly inconvenient for users with keyboards which
+do not have a special <LFD> key at all;  in such cases, it is typically
+more convenient to use <RET> as the <LFD> key (rather than typing
+`C-j').
+
+   You can make <RET> do this by adding
+     (define-key octave-mode-map "\C-m"
+       'octave-reindent-then-newline-and-indent)
+   to one of your Emacs startup files.  Another, more generally
+applicable solution is
+     (defun RET-behaves-as-LFD ()
+       (let ((x (key-binding "\C-j")))
+         (local-set-key "\C-m" x)))
+     (add-hook 'octave-mode-hook 'RET-behaves-as-LFD)
+   (this works for all modes by adding to the startup hooks, without
+having to know the particular binding of <RET> in that mode!).  Similar
+considerations apply for using <M-RET> as <M-LFD>.  As Barry A. Warsaw
+<bwarsaw at cnri.reston.va.us> says in the documentation for his
+`cc-mode', "This is a very common question.  `:-)' If you want this to
+be the default behavior, don't lobby me, lobby RMS!"
+
+   The following variables can be used to customize Octave mode.
+
+`octave-auto-indent'
+     Non-`nil' means auto-indent the current line after a semicolon or
+     space.  Default is `nil'.
+
+`octave-auto-newline'
+     Non-`nil' means auto-insert a newline and indent after semicolons
+     are typed.  The default value is `nil'.
+
+`octave-blink-matching-block'
+     Non-`nil' means show matching begin of block when inserting a
+     space, newline or `;' after an else or end keyword.  Default is
+     `t'.  This is an extremely useful feature for automatically
+     verifying that the keywords match--if they don't, an error message
+     is displayed.
+
+`octave-block-offset'
+     Extra indentation applied to statements in block structures.
+     Default is 2.
+
+`octave-continuation-offset'
+     Extra indentation applied to Octave continuation lines.  Default
+     is 4.
+
+`octave-continuation-string'
+     String used for Octave continuation lines.  Normally `\'.
+
+`octave-mode-startup-message'
+     If `t' (default), a startup message is displayed when Octave mode
+     is called.
+
+
+   If Font Lock mode is enabled, Octave mode will display
+   * strings in `font-lock-string-face'
+
+   * comments in `font-lock-comment-face'
+
+   * the Octave reserved words (such as all block keywords) and the text
+     functions (such as `cd' or `who') which are also reserved using
+     `font-lock-keyword-face'
+
+   * the built-in operators (`&&', `==', ...) using
+     `font-lock-reference-face'
+
+   * and the function names in function declarations in
+     `font-lock-function-name-face'.
+
+   There is also rudimentary support for Imenu (currently, function
+names can be indexed).
+
+   You can generate TAGS files for Emacs from Octave `.m' files using
+the shell script `octave-tags' that is installed alongside your copy of
+Octave.
+
+   Customization of Octave mode can be performed by modification of the
+variable `octave-mode-hook'.  If the value of this variable is
+non-`nil', turning on Octave mode calls its value.
+
+   If you discover a problem with Octave mode, you can conveniently
+send a bug report using `C-c C-b' (`octave-submit-bug-report').  This
+automatically sets up a mail buffer with version information already
+added.  You just need to add a description of the problem, including a
+reproducible test case and send the message.
+
+
+File: octave.info,  Node: Running Octave From Within Emacs,  Next: Using the Emacs Info Reader for Octave,  Prev: Using Octave Mode,  Up: Emacs Octave Support
+
+G.3 Running Octave From Within Emacs
+====================================
+
+The package `octave' provides commands for running an inferior Octave
+process in a special Emacs buffer.  Use
+     M-x run-octave
+   to directly start an inferior Octave process.  If Emacs does not know
+about this command, add the line
+     (autoload 'run-octave "octave-inf" nil t)
+   to your `.emacs' file.
+
+   This will start Octave in a special buffer the name of which is
+specified by the variable `inferior-octave-buffer' and defaults to
+`"*Inferior Octave*"'.  From within this buffer, you can interact with
+the inferior Octave process `as usual', i.e., by entering Octave
+commands at the prompt.  The buffer is in Inferior Octave mode, which
+is derived from the standard Comint mode, a major mode for interacting
+with an inferior interpreter.  See the documentation for `comint-mode'
+for more details, and use `C-h b' to find out about available special
+keybindings.
+
+   You can also communicate with an inferior Octave process from within
+files with Octave code (i.e., buffers in Octave mode), using the
+following commands.
+
+`C-c i l'
+     Send the current line to the inferior Octave process
+     (`octave-send-line').  With positive prefix argument N, send that
+     many lines.  If `octave-send-line-auto-forward' is non-`nil', go
+     to the next unsent code line.
+
+`C-c i b'
+     Send the current block to the inferior Octave process
+     (`octave-send-block').
+
+`C-c i f'
+     Send the current function to the inferior Octave process
+     (`octave-send-defun').
+
+`C-c i r'
+     Send the region to the inferior Octave process
+     (`octave-send-region').
+
+`C-c i s'
+     Make sure that `inferior-octave-buffer' is displayed
+     (`octave-show-process-buffer').
+
+`C-c i h'
+     Delete all windows that display the inferior Octave buffer
+     (`octave-hide-process-buffer').
+
+`C-c i k'
+     Kill the inferior Octave process and its buffer
+     (`octave-kill-process').
+
+   The effect of the commands which send code to the Octave process can
+be customized by the following variables.
+`octave-send-echo-input'
+     Non-`nil' means echo input sent to the inferior Octave process.
+     Default is `t'.
+
+`octave-send-show-buffer'
+     Non-`nil' means display the buffer running the Octave process after
+     sending a command (but without selecting it).  Default is `t'.
+
+   If you send code and there is no inferior Octave process yet, it
+will be started automatically.
+
+   The startup of the inferior Octave process is highly customizable.
+The variable `inferior-octave-startup-args' can be used for specifying
+command lines arguments to be passed to Octave on startup as a list of
+strings.  For example, to suppress the startup message and use
+`traditional' mode, set this to `'("-q" "--traditional")'.  You can
+also specify a startup file of Octave commands to be loaded on startup;
+note that these commands will not produce any visible output in the
+process buffer.  Which file to use is controlled by the variable
+`inferior-octave-startup-file'.  If this is `nil', the file
+`~/.emacs-octave' is used if it exists.
+
+   And finally, `inferior-octave-mode-hook' is run after starting the
+process and putting its buffer into Inferior Octave mode.  Hence, if you
+like the up and down arrow keys to behave in the interaction buffer as
+in the shell, and you want this buffer to use nice colors, add
+     (add-hook 'inferior-octave-mode-hook
+               (lambda ()
+                 (turn-on-font-lock)
+                 (define-key inferior-octave-mode-map [up]
+                   'comint-previous-input)
+                 (define-key inferior-octave-mode-map [down]
+                   'comint-next-input)))
+   to your `.emacs' file.  You could also swap the roles of `C-a'
+(`beginning-of-line') and `C-c C-a' (`comint-bol') using this hook.
+
+     *Note* that if you set your Octave prompts to something different
+     from the defaults, make sure that `inferior-octave-prompt' matches
+     them.  Otherwise, _nothing_ will work, because Emacs will not know
+     when Octave is waiting for input, or done sending output.
+
+
+File: octave.info,  Node: Using the Emacs Info Reader for Octave,  Prev: Running Octave From Within Emacs,  Up: Emacs Octave Support
+
+G.4 Using the Emacs Info Reader for Octave
+==========================================
+
+You may also use the Emacs Info reader with Octave's `doc' function.
+For this, the package `gnuserv' needs to be installed.
+
+   If `gnuserv' is installed, add the lines
+     (autoload 'octave-help "octave-hlp" nil t)
+     (require 'gnuserv)
+     (gnuserv-start)
+   to your `.emacs' file.
+
+   You can use either `plain' Emacs Info or the function `octave-help'
+as your Octave info reader (for `help -i').  In the former case, use
+`info_program ("info-emacs-info")'.  The latter is perhaps more
+attractive because it allows to look up keys in the indices of
+_several_ info files related to Octave (provided that the Emacs
+variable `octave-help-files' is set correctly).  In this case, use
+`info_program ("info-emacs-octave-help")'.
+
+   If you use Octave from within Emacs, it is best to add these
+settings to your `~/.emacs-octave' startup file (or the file pointed to
+by the Emacs variable `inferior-octave-startup-file').
+
+
+File: octave.info,  Node: Copying,  Next: Concept Index,  Prev: Emacs Octave Support,  Up: Top
+
+Appendix H GNU GENERAL PUBLIC LICENSE
+*************************************
+
+                        Version 3, 29 June 2007
+
+     Copyright (C) 2007 Free Software Foundation, Inc. `http://fsf.org/'
+
+     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.
+
+     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
+     Copyright (C) YEAR NAME OF AUTHOR
+
+     This program is free software: you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation, either version 3 of the License, or (at
+     your option) any later version.
+
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see `http://www.gnu.org/licenses/'.
+
+   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:
+
+     PROGRAM Copyright (C) YEAR NAME OF AUTHOR
+     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 `http://www.gnu.org/licenses/'.
+
+   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 `http://www.gnu.org/philosophy/why-not-lgpl.html'.
+
diff --git a/doc/interpreter/octave.info-6 b/doc/interpreter/octave.info-6
new file mode 100644
index 0000000..023b7f6
Binary files /dev/null and b/doc/interpreter/octave.info-6 differ
diff --git a/doc/interpreter/octave.pdf b/doc/interpreter/octave.pdf
new file mode 100644
index 0000000..fbb1511
Binary files /dev/null and b/doc/interpreter/octave.pdf differ
diff --git a/doc/interpreter/octave.texi b/doc/interpreter/octave.texi
new file mode 100644
index 0000000..b4b381a
--- /dev/null
+++ b/doc/interpreter/octave.texi
@@ -0,0 +1,875 @@
+% Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006,
+%               2007, 2008, 2009 John W. Eaton
+%
+% This file is part of Octave.
+%
+% Octave is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 3 of the License, or (at
+% your option) any later version.
+% 
+% Octave is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+% 
+% You should have received a copy of the GNU General Public License
+% along with Octave; see the file COPYING.  If not, see
+% <http://www.gnu.org/licenses/>.
+
+\input texinfo
+ at setfilename octave.info
+
+ at c The following macro is used for the on-line help system, but we don't
+ at c want lots of `See also: foo, bar, and baz' strings cluttering the
+ at c printed manual (that information should be in the supporting text for
+ at c each group of functions and variables).
+
+ at macro seealso {args}
+ at iftex
+ at vskip 2pt
+ at end iftex
+ at ifnottex
+ at c Texinfo @sp should work but in practice produces ugly results for HTML.
+ at c A simple blank line produces the correct behavior. 
+ at c @sp 1
+
+ at end ifnottex
+ at noindent
+ at strong{See also:} \args\.
+ at end macro
+
+ at ifinfo
+ at format
+START-INFO-DIR-ENTRY
+* Octave: (octave).	Interactive language for numerical computations.
+END-INFO-DIR-ENTRY
+ at end format
+ at end ifinfo
+
+ at c Settings for printing on 8-1/2 by 11 inch paper:
+ at c -----------------------------------------------
+
+ at setchapternewpage odd
+
+ at c Settings for small book format:
+ at c ------------------------------
+
+ at ignore
+ at smallbook
+ at setchapternewpage odd
+ at finalout
+ at iftex
+ at cropmarks
+ at end iftex
+ at end ignore
+
+ at defindex op
+
+ at c Things like the Octave version number are defined in conf.texi.
+ at c This file doesn't include a chapter, so it must not be included
+ at c if you want to run the Emacs function texinfo-multiple-files-update.
+
+ at include conf.texi
+
+ at settitle GNU Octave
+
+ at ifnottex
+
+Copyright @copyright{} 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006,
+2007 John W. Eaton.
+
+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.
+
+ at ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+ at end ignore
+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 above conditions for
+modified versions.
+ at end ifnottex
+
+ at titlepage
+ at title GNU Octave
+ at subtitle A high-level interactive language for numerical computations
+ at subtitle Edition 3 for Octave version @value{VERSION}
+ at subtitle July 2007
+ at author John W. Eaton
+ at author David Bateman
+ at author S at o{}ren Hauberg
+ at page
+ at vskip 0pt plus 1filll
+Copyright @copyright{} 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006,
+2007 John W. Eaton.
+
+This is the third edition of the Octave documentation, and is consistent
+with version @value{VERSION} of Octave.
+
+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.
+
+Portions of this document have been adapted from the @code{gawk},
+ at code{readline}, @code{gcc}, and C library manuals, published by the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301--1307, USA.
+ at end titlepage
+
+ at contents
+
+ at ifnottex
+ at node Top
+ at top
+
+This manual documents how to run, install and port GNU Octave, as well
+as its new features and incompatibilities, and how to report bugs.
+It corresponds to GNU Octave version @value{VERSION}.
+ at end ifnottex
+
+ at c ------------------------------------------------------------------------
+
+ at menu
+* Preface::                     
+* Introduction::                A brief introduction to Octave.
+* Getting Started::             
+* Data Types::                  
+* Numeric Data Types::          
+* Strings::                     
+* Data Containers::             
+* Variables::                   
+* Expressions::                 
+* Evaluation::                  
+* Statements::                  Looping and program flow control.
+* Functions and Scripts::       
+* Errors and Warnings::              
+* Debugging::
+* Input and Output::            
+* Plotting::                    
+* Matrix Manipulation::         
+* Arithmetic::                  
+* Linear Algebra::              
+* Nonlinear Equations::         
+* Diagonal and Permutation Matrices::
+* Sparse Matrices::
+* Numerical Integration::                  
+* Differential Equations::      
+* Optimization::                
+* Statistics::                  
+* Sets::                        
+* Polynomial Manipulations::    
+* Interpolation::
+* Geometry::
+* Signal Processing::           
+* Image Processing::            
+* Audio Processing::            
+* Object Oriented Programming::            
+* System Utilities::            
+* Packages:: 
+* Dynamically Linked Functions::
+* Test and Demo Functions::
+* Tips and Standards::                        
+* Contributing Guidelines::
+* Trouble::                     If you have trouble installing Octave.
+* Installation::                How to configure, compile and install Octave.
+* Emacs Octave Support::                       
+ at c * Grammar::                     
+* Copying::                     The GNU General Public License.
+* Concept Index::               An item for each concept.
+* Function Index::              An item for each documented function.
+* Operator Index::              An item for each documented operator.
+
+ at detailmenu
+ --- The Detailed Node Listing ---
+
+Preface
+
+* Acknowledgements::            
+* How You Can Contribute to Octave::  
+* Distribution::                
+
+Introduction
+
+* Running Octave::              
+* Simple Examples::             
+* Conventions::                 
+
+Conventions
+
+* Fonts::                       
+* Evaluation Notation::         
+* Printing Notation::           
+* Error Messages::              
+* Format of Descriptions::      
+
+Format of Descriptions
+
+* A Sample Function Description::  
+* A Sample Command Description::  
+* A Sample Variable Description::  
+
+Getting Started
+
+* Invoking Octave from the Command Line::             
+* Quitting Octave::             
+* Getting Help::                
+* Command Line Editing::        
+* Errors::                      
+* Executable Octave Programs::  
+* Comments::                    
+
+Invoking Octave from the Command Line
+
+* Command Line Options::        
+* Startup Files::               
+
+Command Line Editing
+
+* Cursor Motion::               
+* Killing and Yanking::         
+* Commands For Text::           
+* Commands For Completion::     
+* Commands For History::        
+* Customizing readline::        
+* Customizing the Prompt::      
+* Diary and Echo Commands::     
+
+Comments
+
+* Single Line Comments::
+* Block Comments::
+* Comments and the Help System::                    
+
+Data Types
+
+* Built-in Data Types::         
+* User-defined Data Types::     
+* Object Sizes::                
+
+Built-in Data Types
+
+* Numeric Objects::             
+* Missing Data::                
+* String Objects::              
+* Data Structure Objects::      
+* Cell Array Objects::          
+
+Numeric Data Types
+
+* Matrices::
+* Ranges::
+* Single Precision Data Types::
+* Integer Data Types::
+* Bit Manipulations::
+* Logical Values:: 
+* Promotion and Demotion of Data Types::
+* Predicates for Numeric Objects::  
+
+Matrices
+
+* Empty Matrices::              
+
+Integer Data Types
+
+* Integer Arithmetic::
+
+Strings
+
+* Escape Sequences in string constants::
+* Character Arrays::
+* Creating Strings:: 
+* Comparing Strings::           
+* Manipulating Strings::     
+* String Conversions::          
+* Character Class Functions::   
+
+Creating Strings
+
+* Concatenating Strings:: 
+* Conversion of Numerical Data to Strings::
+
+Data Containers
+
+* Data Structures::
+* Cell Arrays::
+* Comma Separated Lists::
+
+Data Structures
+
+* Structure Arrays::
+* Creating Structures::
+* Manipulating Structures::
+* Processing Data in Structures::
+
+Cell Arrays
+
+* Creating Cell Arrays::                 
+* Indexing Cell Arrays::
+* Cell Arrays of Strings::
+* Processing Data in Cell Arrays::
+
+Variables
+
+* Global Variables::            
+* Persistent Variables::        
+* Status of Variables::         
+
+Expressions
+
+* Index Expressions::           
+* Calling Functions::           
+* Arithmetic Ops::              
+* Comparison Ops::              
+* Boolean Expressions::         
+* Assignment Ops::              
+* Increment Ops::               
+* Operator Precedence::         
+
+Calling Functions
+
+* Call by Value::               
+* Recursion::                   
+
+Boolean Expressions
+
+* Element-by-element Boolean Operators::  
+* Short-circuit Boolean Operators::  
+
+Evaluation
+
+* Calling a Function by its Name::
+* Evaluation in a Different Context::
+
+Statements
+
+* The @code{if} Statement::            
+* The @code{switch} Statement::        
+* The @code{while} Statement::         
+* The @code{do-until} Statement::      
+* The @code{for} Statement::           
+* The @code{break} Statement::         
+* The @code{continue} Statement::      
+* The @code{unwind_protect} Statement::  
+* The @code{try} Statement::           
+* Continuation Lines::          
+
+The @code{switch} Statement
+
+* Notes for the C programmer::  
+
+The @code{for} Statement
+
+* Looping Over Structure Elements::  
+
+Functions and Scripts
+
+* Defining Functions::          
+* Multiple Return Values::      
+* Variable-length Argument Lists::  
+* Variable-length Return Lists::  
+* Returning From a Function::   
+* Default Arguments::   
+* Function Files::              
+* Script Files::                
+* Function Handles Inline Functions and Anonymous Functions::
+* Commands::
+* Organization of Functions::   
+
+Function Files
+
+* Manipulating the load path::
+* Subfunctions::
+* Private Functions::
+* Overloading and Autoloading::
+* Function Locking::
+* Function Precedence::
+
+Function Handles Inline Functions and Anonymous Functions
+
+* Function Handles::
+* Anonymous Functions::
+* Inline Functions::
+
+Errors and Warnings
+
+* Handling Errors::
+* Handling Warnings::
+
+Handling Errors
+
+* Raising Errors::
+* Catching Errors::
+
+Handling Warnings
+
+* Issuing Warnings::
+* Enabling and Disabling Warnings::
+
+Debugging
+
+* Entering Debug Mode::
+* Leaving Debug Mode::
+* Breakpoints::
+* Debug Mode::
+* Call Stack::
+
+Input and Output
+
+* Basic Input and Output::      
+* C-Style I/O Functions::       
+
+Basic Input and Output
+
+* Terminal Output::             
+* Terminal Input::              
+* Simple File I/O::             
+* Rational Approximations::
+
+Terminal Output
+
+* Paging Screen Output::
+
+Simple File I/O
+
+* Saving Data on Unexpected Exits::
+
+C-Style I/O Functions
+
+* Opening and Closing Files::   
+* Simple Output::               
+* Line-Oriented Input::         
+* Formatted Output::            
+* Output Conversion for Matrices::  
+* Output Conversion Syntax::    
+* Table of Output Conversions::  
+* Integer Conversions::         
+* Floating-Point Conversions::
+* Other Output Conversions::    
+* Formatted Input::             
+* Input Conversion Syntax::     
+* Table of Input Conversions::  
+* Numeric Input Conversions::   
+* String Input Conversions::    
+* Binary I/O::                  
+* Temporary Files::             
+* EOF and Errors::              
+* File Positioning::            
+
+Plotting
+
+* Plotting Basics::
+* Advanced Plotting::
+
+Plotting Basics
+
+* Two-Dimensional Plots::       
+* Three-Dimensional Plotting::  
+* Plot Annotations::            
+* Multiple Plots on One Page::  
+* Multiple Plot Windows::       
+* Printing Plots::              
+* Interacting with plots::
+* Test Plotting Functions::     
+
+Two-Dimensional Plots
+
+* Two-dimensional Function Plotting::
+
+Three-Dimensional Plotting
+
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
+
+Advanced Plotting
+
+* Graphics Objects::
+* Graphics Object Properties::  
+* Managing Default Properties::  
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
+* Object Groups::
+* Graphics backends::
+
+Graphics Object Properties
+
+* Root Figure Properties::      
+* Figure Properties::           
+* Axes Properties::             
+* Line Properties::             
+* Text Properties::             
+* Image Properties::            
+* Patch Properties::            
+* Surface Properties::          
+* Searching Properties::
+
+Object Groups
+
+* Data sources in object groups::
+* Area series::
+* Bar series::
+* Contour groups::
+* Error bar series::
+* Line series::
+* Quiver group::
+* Scatter group::
+* Stair group::
+* Stem Series::
+* Surface group::
+
+Graphics backends
+
+* Interaction with gnuplot::
+
+Matrix Manipulation
+
+* Finding Elements and Checking Conditions::  
+* Rearranging Matrices::        
+* Applying a Function to an Array::
+* Special Utility Matrices::    
+* Famous Matrices::             
+
+Arithmetic
+
+* Exponents and Logarithms::
+* Complex Arithmetic::          
+* Trigonometry::                
+* Sums and Products::           
+* Utility Functions::           
+* Special Functions::           
+* Coordinate Transformations::
+* Mathematical Constants::      
+
+Linear Algebra
+
+* Techniques used for Linear Algebra::
+* Basic Matrix Functions::      
+* Matrix Factorizations::       
+* Functions of a Matrix::       
+* Specialized Solvers::
+
+Diagonal and Permutation Matrices
+
+* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Function Support::     Functions That Are Aware of These Matrices
+* Example Codes::        Some Examples of Usage
+* Zeros Treatment::      The Differences in Treatment of Zero Elements
+
+Basic Usage
+
+* Creating Diagonal Matrices::
+* Creating Permutation Matrices::
+* Explicit and Implicit Conversions::
+
+Matrix Algebra
+
+* Expressions Involving Diagonal Matrices::
+* Expressions Involving Permutation Matrices::
+
+Function Support
+
+* Diagonal Matrix Functions::
+* Permutation Matrix Functions::
+
+Sparse Matrices
+
+* Basics::                      Creation and Manipulation of Sparse Matrices
+* Sparse Linear Algebra::       Linear Algebra on Sparse Matrices
+* Iterative Techniques::        Iterative Techniques
+* Real Life Example::           Using Sparse Matrices
+
+Basics
+
+* Storage of Sparse Matrices::
+* Creating Sparse Matrices::
+* Information::
+* Operators and Functions::
+
+Operators and Functions
+
+* Sparse Functions::            
+* Return Types of Operators and Functions::  
+* Mathematical Considerations::  
+
+Numerical Integration
+
+* Functions of One Variable:: 
+* Functions of Multiple Variables:: 
+* Orthogonal Collocation::      
+
+Differential Equations
+
+* Ordinary Differential Equations::  
+* Differential-Algebraic Equations::  
+
+Optimization
+
+* Linear Programming::       
+* Quadratic Programming::       
+* Nonlinear Programming::       
+* Linear Least Squares::        
+
+Statistics
+
+* Descriptive Statistics::
+* Basic Statistical Functions:: 
+* Statistical Plots:: 
+* Tests::                       
+* Models::                      
+* Distributions::     
+* Random Number Generation::          
+
+Sets
+
+* Set Operations::
+
+Polynomial Manipulations
+
+* Evaluating Polynomials::
+* Finding Roots::
+* Products of Polynomials::
+* Derivatives and Integrals::
+* Polynomial Interpolation::
+* Miscellaneous Functions::
+
+Interpolation
+
+* One-dimensional Interpolation::
+* Multi-dimensional Interpolation::
+
+Geometry
+
+* Delaunay Triangulation::
+* Voronoi Diagrams::
+* Convex Hull::
+* Interpolation on Scattered Data::
+
+Delaunay Triangulation
+
+* Plotting the Triangulation::
+* Identifying points in Triangulation::
+
+Image Processing
+
+* Loading and Saving Images::   
+* Displaying Images::           
+* Representing Images::         
+* Plotting on top of Images::   
+* Color Conversion::            
+
+Object Oriented Programming
+
+* Creating a Class::
+* Manipulating Classes::
+* Indexing Objects::
+* Overloading Objects::
+
+Overloading Objects
+
+* Function Overloading::
+* Operator Overloading::
+* Precedence of Objects::
+
+System Utilities
+
+* Timing Utilities::            
+* Filesystem Utilities::        
+* File Archiving Utilities::
+* Networking Utilities::
+* Controlling Subprocesses::    
+* Process ID Information::      
+* Environment Variables::       
+* Current Working Directory::   
+* Password Database Functions::  
+* Group Database Functions::    
+* System Information::          
+* Hashing Functions::
+
+Packages
+
+* Installing and Removing Packages::  
+* Using Packages::              
+* Administrating Packages::     
+* Creating Packages::           
+
+Creating Packages
+
+* The DESCRIPTION File::        
+* The INDEX file::              
+* PKG_ADD and PKG_DEL directives::  
+
+Dynamically Linked Functions
+
+* Oct-Files::                   
+* Mex-Files::                   
+* Standalone Programs::         
+
+Oct-Files
+
+* Getting Started with Oct-Files::  
+* Matrices and Arrays in Oct-Files::  
+* Character Strings in Oct-Files::  
+* Cell Arrays in Oct-Files::    
+* Structures in Oct-Files::  
+* Sparse Matrices in Oct-Files::  
+* Accessing Global Variables in Oct-Files::  
+* Calling Octave Functions from Oct-Files::  
+* Calling External Code from Oct-Files::  
+* Allocating Local Memory in Oct-Files::  
+* Input Parameter Checking in Oct-Files::  
+* Exception and Error Handling in Oct-Files::  
+* Documentation and Test of Oct-Files::  
+
+Sparse Matrices in Oct-Files
+
+* Array and Sparse Differences::  
+* Creating Sparse Matrices in Oct-Files::  
+* Using Sparse Matrices in Oct-Files::  
+
+Mex-Files
+
+* Getting Started with Mex-Files::  
+* Working with Matrices and Arrays in Mex-Files::  
+* Character Strings in Mex-Files::  
+* Cell Arrays with Mex-Files::  
+* Structures with Mex-Files::  
+* Sparse Matrices with Mex-Files::  
+* Calling Other Functions in Mex-Files::  
+
+Test and Demo Functions
+
+* Test Functions::
+* Demonstration Functions::
+
+Tips and Standards
+
+* Style Tips::                  Writing clean and robust programs.
+* Coding Tips::                 Making code run faster.
+* Comment Tips::                Conventions for writing comments.
+* Function Headers::            Standard headers for functions.
+* Documentation Tips::          Writing readable documentation strings.
+
+Contributing Guidelines
+
+* How to Contribute::
+* General Guidelines::
+* Octave Sources (m-files)::
+* C++ Sources::
+* Other Sources::	
+
+Trouble
+
+* Actual Bugs::                 Bugs we will fix later.
+* Reporting Bugs::              
+* Bug Criteria::                
+* Bug Lists::                   
+* Bug Reporting::               
+* Sending Patches::             
+* Service::                     
+
+Reporting Bugs
+
+* Bug Criteria::                
+* Where: Bug Lists.             Where to send your bug report.
+* Reporting: Bug Reporting.     How to report a bug effectively.
+* Patches: Sending Patches.     How to send a patch for Octave.
+
+Installation
+
+* Installation Problems::       
+
+Emacs Octave Support
+
+* Installing EOS::              
+* Using Octave Mode::           
+* Running Octave From Within Emacs::  
+* Using the Emacs Info Reader for Octave::  
+ at end detailmenu
+ at end menu
+
+ at c ------------------------------------------------------------------------
+
+ at include preface.texi
+ at include intro.texi
+ at include basics.texi
+ at include data.texi
+ at include numbers.texi
+ at include strings.texi
+ at include container.texi
+ at include var.texi
+ at include expr.texi
+ at include eval.texi
+ at include stmt.texi
+ at include func.texi
+ at include errors.texi
+ at include debug.texi
+ at include io.texi
+ at include plot.texi
+ at include matrix.texi
+ at include arith.texi
+ at include linalg.texi
+ at include nonlin.texi
+ at include diagperm.texi
+ at include sparse.texi
+ at include quad.texi
+ at include diffeq.texi
+ at include optim.texi
+ at include stats.texi
+ at include set.texi
+ at include poly.texi
+ at include interp.texi
+ at include geometry.texi
+ at include signal.texi
+ at include image.texi
+ at include audio.texi
+ at include oop.texi
+ at include system.texi
+ at include package.texi
+
+ at c maybe add again later, if anyone every writes any really interesting
+ at c fun stuff for Octave.
+ at c
+ at c @include amuse.texi
+
+ at c ------------------------------------------------------------------------
+ at c Appendices start here. 
+
+ at include dynamic.texi
+ at include testfun.texi
+ at include tips.texi
+ at include contrib.texi
+ at include bugs.texi
+ at include install.texi
+ at include emacs.texi
+ at c @include grammar.texi
+ at include gpl.texi
+
+ at c ------------------------------------------------------------------------
+ at c Indices start here. 
+
+ at include cp-idx.texi
+ at c @include vr-idx.texi
+ at include fn-idx.texi
+ at include op-idx.texi
+
+ at bye
diff --git a/doc/interpreter/oop.texi b/doc/interpreter/oop.texi
new file mode 100644
index 0000000..6f0ba42
--- /dev/null
+++ b/doc/interpreter/oop.texi
@@ -0,0 +1,840 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2008, 2009 David Bateman
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c FIXME
+ at c For now can't include "@" character in the path name, and so name
+ at c the example directory without the "@"!!
+
+ at macro classfile{class, file}
+ at example
+ at group
+ at verbatiminclude @value{abs_top_srcdir}/examples/\class\/\file\
+ at end group
+ at end example
+ at end macro
+
+ at macro polynomialfile{file}
+ at classfile{@@polynomial,\file\}
+ at end macro
+
+ at node Object Oriented Programming
+ at chapter Object Oriented Programming
+
+Octave includes the capability to include user classes, including the
+features of operator and function overloading.  Equally a user class
+can be used to encapsulate certain properties of the class so that
+they cannot be altered accidentally and can be set up to address the
+issue of class precedence in mixed class operations.
+
+This chapter discussions the means of constructing a user class with
+the example of a polynomial class, how to query and set the properties
+of this class, together with the means to overload operators and
+functions.
+
+ at menu
+* Creating a Class::
+* Manipulating Classes::
+* Indexing Objects::
+* Overloading Objects::
+* Inheritance and Aggregation::
+ at end menu
+
+ at node Creating a Class
+ at section Creating a Class
+
+We use in the following text a polynomial class to demonstrate the use
+of object oriented programming within Octave.  This class was chosen as
+it is simple, and so doesn't distract unnecessarily from the
+discussion of the programming features of Octave.  However, even still
+a small understand of the polynomial class itself is necessary to
+fully grasp the techniques described.
+
+The polynomial class is used to represent polynomials of the form
+
+ at example
+ at group
+ at tex
+$a_0 + a_1 x + a_2 x^2 + \ldots a_n x^n$
+ at end tex
+ at ifnottex
+a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+ at end ifnottex
+ at end group
+ at end example
+
+ at noindent
+where
+ at tex
+$a_0$, $a_1$, etc. are elements of $\Re$.
+ at end tex
+ at ifnottex
+a0, a1, etc. are real scalars.
+ at end ifnottex
+Thus the polynomial can be represented by a vector
+
+ at example
+a = [a0, a1, a2, @dots{}, an];
+ at end example
+
+We therefore now have sufficient information about the requirements of
+the class constructor for our polynomial class to write it.  All object
+oriented classes in Octave, must be contained with a directory taking
+the name of the class, prepended with the @@ symbol.  For example, with
+our polynomial class, we would place the methods defining the class in
+the @@polynomial directory.
+
+The constructor of the class, must have the name of the class itself
+and so in our example the constructor with have the name
+ at file{@@polynomial/polynomial.m}.  Also ideally when the constructor is
+called with no arguments to should return a value object.  So for example
+our polynomial might look like
+
+ at polynomialfile{polynomial.m}
+
+Note that the return value of the constructor must be the output of
+the @code{class} function called with the first argument being a
+structure and the second argument being the class name.  An example of
+the call to this constructor function is then
+
+ at example
+p = polynomial ([1, 0, 1]);
+ at end example
+
+Note that methods of a class can be documented.  The help for the
+constructor itself can be obtained with the constructor name, that is
+for the polynomial constructor @code{help polynomial} will return the
+help string.  Also the help can be obtained by restricting the search
+for the help to a particular class, for example @code{help
+@@polynomial/polynomial}.  This second method is the only means of
+getting help for the overloaded methods and functions of the class.
+
+The same is true for other Octave functions that take a function name
+as an argument.  For example @code{type @@polynomial/display} will
+print the code of the display method of the polynomial class to the
+screen, and @code{dbstop @@polynomial/display} will set a breakpoint
+at the first executable line of the display method of the polynomial
+class.
+
+To check where a variable is a user class, the @code{isobject} and
+ at code{isa} functions can be used. for example
+
+ at example
+ at group
+p = polynomial ([1, 0, 1]);
+isobject (p)
+ at result{} 1
+isa (p, "polynomial")
+ at result{} 1
+ at end group
+ at end example
+
+ at c ov-class.cc
+ at anchor{doc-isobject}
+ at deftypefn {Built-in Function} {} isobject (@var{x})
+Return true if @var{x} is a class object.
+ at end deftypefn
+
+
+ at noindent
+The available methods of a class can be displayed with the
+ at code{methods} function.
+
+ at c ov-class.cc
+ at anchor{doc-methods}
+ at deftypefn {Built-in Function} {} methods (@var{x})
+ at deftypefnx {Built-in Function} {} methods ("classname")
+Return a cell array containing the names of the methods for the
+object @var{x} or the named class.
+ at end deftypefn
+
+
+ at noindent
+To inquire whether a particular method is available to a user class, the
+ at code{ismethod} function can be used.
+
+ at c ov-class.cc
+ at anchor{doc-ismethod}
+ at deftypefn {Built-in Function} {} ismethod (@var{x}, @var{method})
+Return true if @var{x} is a class object and the string @var{method}
+is a method of this class.
+ at end deftypefn
+
+
+ at noindent
+For example
+
+ at example
+ at group
+p = polynomial ([1, 0, 1]);
+ismethod (p, "roots")
+ at result{} 1
+ at end group
+ at end example
+
+ at node Manipulating Classes
+ at section Manipulating Classes
+
+There are a number of basic classes methods that can be defined to allow
+the contents of the classes to be queried and set.  The most basic of
+these is the @code{display} method.  The @code{display} method is used
+by Octave when displaying a class on the screen, due to an expression
+that is not terminated with a semicolon.  If this method is not defined,
+then Octave will printed nothing when displaying the contents of a class.
+
+ at c ./general/display.m
+ at anchor{doc-display}
+ at deftypefn {Function File} {} display (@var{a})
+Display the contents of an object.  If @var{a} is an object of the
+class "myclass", then @code{display} is called in a case like
+
+ at example
+myclass (@dots{})
+ at end example
+
+ at noindent
+where Octave is required to display the contents of a variable of the
+type "myclass".
+
+ at seealso{@ref{doc-class,,class}, @ref{doc-subsref,,subsref}, @ref{doc-subsasgn,,subsasgn}}
+ at end deftypefn
+
+
+ at noindent
+An example of a display method for the polynomial class might be
+
+ at polynomialfile{display.m}
+
+ at noindent
+Note that in the display method, it makes sense to start the method
+with the line @code{fprintf("%s =", inputname(1))} to be consistent
+with the rest of Octave and print the variable name to be displayed
+when displaying the class. 
+
+To be consistent with the Octave graphic handle classes, a class
+should also define the @code{get} and @code{set} methods.  The
+ at code{get} method should accept one or two arguments, and given one
+argument of the appropriate class it should return a structure with
+all of the properties of the class.  For example
+
+ at polynomialfile{get.m}
+
+ at noindent
+Similarly, the @code{set} method should taken as its first argument an
+object to modify, and then take property/value pairs to be modified. 
+
+ at polynomialfile{set.m}
+
+ at noindent
+Note that as Octave does not implement pass by reference, than the
+modified object is the return value of the @code{set} method and it
+must be called like
+
+ at example
+p = set (p, "a", [1, 0, 0, 0, 1]);
+ at end example
+
+ at noindent
+Also the @code{set} method makes use of the @code{subsasgn} method of
+the class, and this method must be defined.  The @code{subsasgn} method
+is discussed in the next section.
+
+Finally, user classes can be considered as a special type of a
+structure, and so they can be saved to a file in the same manner as a
+structure.  For example
+
+ at example
+ at group
+p = polynomial ([1, 0, 1]);
+save userclass.mat p
+clear p
+load userclass.mat
+ at end group
+ at end example
+
+ at noindent
+All of the file formats supported by @code{save} and @code{load} are
+supported.  In certain circumstances, a user class might either contain
+a field that it makes no sense to save or a field that needs to be
+initialized before it is saved.  This can be done with the
+ at code{saveobj} method of the class
+
+ at c ./general/saveobj.m
+ at anchor{doc-saveobj}
+ at deftypefn {Function File} {@var{b} =} saveobj (@var{a})
+Method of a class to manipulate an object prior to saving it to a file. 
+The function @code{saveobj} is called when the object @var{a} is saved 
+using the @code{save} function.  An example of the use of @code{saveobj}
+might be to remove fields of the object that don't make sense to be saved
+or it might be used to ensure that certain fields of the object are
+initialized before the object is saved.  For example
+
+ at example
+ at group
+function b = saveobj (a)
+  b = a;
+  if (isempty (b.field))
+     b.field = initfield(b);
+  endif
+endfunction
+ at end group
+ at end example
+
+ at seealso{@ref{doc-loadobj,,loadobj}, @ref{doc-class,,class}}
+ at end deftypefn
+
+
+ at noindent
+ at code{saveobj} is called just prior to saving the class to a
+file.  Likely, the @code{loadobj} method is called just after a class
+is loaded from a file, and can be used to ensure that any removed
+fields are reinserted into the user object.
+
+ at c ./general/loadobj.m
+ at anchor{doc-loadobj}
+ at deftypefn {Function File} {@var{b} =} loadobj (@var{a})
+Method of a class to manipulate an object after loading it from a file. 
+The function @code{loadobj} is called when the object @var{a} is loaded 
+using the @code{load} function.  An example of the use of @code{saveobj}
+might be to add fields to an object that don't make sense to be saved.
+For example
+
+ at example
+ at group
+function b = loadobj (a)
+  b = a;
+  b.addmissingfield = addfield (b);
+endfunction
+ at end group
+ at end example
+
+ at seealso{@ref{doc-saveobj,,saveobj}, @ref{doc-class,,class}}
+ at end deftypefn
+
+
+ at node Indexing Objects
+ at section Indexing Objects
+
+Objects can be indexed with parentheses, either like 
+ at code{@var{a} (@var{idx})} or like @code{@var{a} @{@var{idx}@}}, or even
+like @code{@var{a} (@var{idx}). at var{field}}.  However, it is up to the user
+to decide what this indexing actually means.  In the case of our polynomial
+class @code{@var{p} (@var{n})} might mean either the coefficient of the 
+ at var{n}-th power of the polynomial, or it might be the evaluation of the 
+polynomial at @var{n}.  The meaning of this subscripted referencing is 
+determined by the @code{subsref} method.
+
+ at c ov.cc
+ at anchor{doc-subsref}
+ at deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})
+Perform the subscripted element selection operation according to
+the subscript specified by @var{idx}.
+
+The subscript @var{idx} is expected to be a structure array with
+fields @samp{type} and @samp{subs}.  Valid values for @samp{type}
+are @samp{"()"}, @samp{"@{@}"}, and @samp{"."}.
+The @samp{subs} field may be either @samp{":"} or a cell array
+of index values.
+
+The following example shows how to extract the two first columns of
+a matrix
+
+ at example
+ at group
+val = magic(3)
+     @result{} val = [ 8   1   6
+                3   5   7
+                4   9   2 ]
+idx.type = "()";
+idx.subs = @{":", 1:2@};
+subsref(val, idx)
+     @result{} [ 8   1 
+          3   5 
+          4   9 ]
+ at end group
+ at end example
+
+ at noindent
+Note that this is the same as writing @code{val(:,1:2)}.
+ at seealso{@ref{doc-subsasgn,,subsasgn}, @ref{doc-substruct,,substruct}}
+ at end deftypefn
+
+
+For example we might decide that indexing with "()" evaluates the
+polynomial and indexing with "@{@}" returns the @var{n}-th coefficient (of @var{n}-th power).
+In this case the @code{subsref} method of our polynomial class might look like
+
+ at polynomialfile{subsref.m}
+
+The equivalent functionality for subscripted assignments uses the 
+ at code{subsasgn} method.
+
+ at c ov.cc
+ at anchor{doc-subsasgn}
+ at deftypefn {Built-in Function} {} subsasgn (@var{val}, @var{idx}, @var{rhs})
+Perform the subscripted assignment operation according to
+the subscript specified by @var{idx}.
+
+The subscript @var{idx} is expected to be a structure array with
+fields @samp{type} and @samp{subs}.  Valid values for @samp{type}
+are @samp{"()"}, @samp{"@{@}"}, and @samp{"."}.
+The @samp{subs} field may be either @samp{":"} or a cell array
+of index values.
+
+The following example shows how to set the two first columns of a
+3-by-3 matrix to zero.
+
+ at example
+ at group
+val = magic(3);
+idx.type = "()";
+idx.subs = @{":", 1:2@};
+subsasgn (val, idx, 0)
+     @result{} [ 0   0   6
+          0   0   7
+          0   0   2 ]
+ at end group
+ at end example
+
+Note that this is the same as writing @code{val(:,1:2) = 0}.
+ at seealso{@ref{doc-subsref,,subsref}, @ref{doc-substruct,,substruct}}
+ at end deftypefn
+
+
+Note that the @code{subsref} and @code{subsasgn} methods always receive the
+whole index chain, while they usually handle only the first element.  It is the
+responsibility of these methods to handle the rest of the chain (if needed),
+usually by forwarding it again to @code{subsref} or @code{subsasgn}.
+
+If you wish to use the @code{end} keyword in subscripted expressions
+of an object, then the user needs to define the @code{end} method for 
+the class.
+
+
+
+For example the @code{end} method for our polynomial class might look like
+
+ at polynomialfile{end.m}
+
+ at noindent
+which is a fairly generic @code{end} method that has a behavior similar to
+the @code{end} keyword for Octave Array classes.  It can then be used for
+example like
+
+ at example
+ at group
+p = polynomial([1,2,3,4]);
+p(end-1)
+ at result{} 3
+ at end group
+ at end example
+
+Objects can also be used as the index in a subscripted expression themselves
+and this is controlled with the @code{subsindex} function.
+
+ at c ./general/subsindex.m
+ at anchor{doc-subsindex}
+ at deftypefn {Function File} {@var{idx} =} subsindex (@var{a})
+Convert an object to an index vector.  When @var{a} is a class object 
+defined with a class constructor, then @code{subsindex} is the
+overloading method that allows the conversion of this class object to
+a valid indexing vector.  It is important to note that
+ at code{subsindex} must return a zero-based real integer vector of the
+class "double".  For example, if the class constructor
+
+ at example
+ at group
+function b = myclass (a)
+ b = myclass (struct ("a", a), "myclass");
+endfunction
+ at end group
+ at end example
+
+ at noindent
+then the @code{subsindex} function
+
+ at example
+ at group
+function idx = subsindex (a)
+ idx = double (a.a) - 1.0;
+endfunction
+ at end group
+ at end example
+
+ at noindent
+can then be used as follows
+
+ at example
+ at group
+a = myclass (1:4);
+b = 1:10;
+b(a)
+ at result{} 1  2  3  4
+ at end group
+ at end example
+
+ at seealso{@ref{doc-class,,class}, @ref{doc-subsref,,subsref}, @ref{doc-subsasgn,,subsasgn}}
+ at end deftypefn
+
+
+Finally, objects can equally be used like ranges, using the @code{colon}
+method
+
+ at c ./general/colon.m
+ at anchor{doc-colon}
+ at deftypefn {Function File} {@var{r} =} colon (@var{a}, @var{b})
+ at deftypefnx {Function File} {@var{r} =} colon (@var{a}, @var{b}, @var{c})
+Method of a class to construct a range with the @code{:} operator.  For
+example.
+
+ at example
+ at group
+a = myclass (@dots{})
+b = myclass (@dots{})
+c = a : b
+ at end group
+ at end example
+
+ at seealso{@ref{doc-class,,class}, @ref{doc-subsref,,subsref}, @ref{doc-subsasgn,,subsasgn}}
+ at end deftypefn
+
+
+ at node Overloading Objects
+ at section Overloading Objects
+
+ at menu
+* Function Overloading::
+* Operator Overloading::
+* Precedence of Objects::
+ at end menu
+
+ at node Function Overloading
+ at subsection Function Overloading
+
+Any Octave function can be overloaded, and allows a object specific
+version of this function to be called as needed.  A pertinent example
+for our polynomial class might be to overload the @code{polyval} function
+like
+
+ at polynomialfile{polyval.m}
+
+This function just hands off the work to the normal Octave @code{polyval}
+function.  Another interesting example for an overloaded function for our
+polynomial class is the @code{plot} function.
+
+ at polynomialfile{plot.m}
+
+ at noindent
+which allows polynomials to be plotted in the domain near the region
+of the roots of the polynomial.
+
+Functions that are of particular interest to be overloaded are the class
+conversion functions such as @code{double}.  Overloading these functions 
+allows the @code{cast} function to work with the user class and can aid 
+in the use of methods of other classes with the user class.  An example
+ at code{double} function for our polynomial class might look like.
+
+ at polynomialfile{double.m}
+
+ at node Operator Overloading
+ at subsection Operator Overloading
+
+ at float Table,tab:overload_ops
+
+ at anchor{doc-rdivide} @anchor{doc-plus} @anchor{doc-minus} @anchor{doc-uminus}
+ at anchor{doc-uplus} @anchor{doc-times} @anchor{doc-mtimes} @anchor{doc-mrdivide}
+ at anchor{doc-ldivide} @anchor{doc-mldivide} @anchor{doc-power}
+ at anchor{doc-mpower} @anchor{doc-lt} @anchor{doc-le} @anchor{doc-gt}
+ at anchor{doc-ge} @anchor{doc-eq} @anchor{doc-ne} @anchor{doc-and}
+ at anchor{doc-or} @anchor{doc-not} @anchor{doc-ctranspose} @anchor{doc-transpose}
+
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & \vrule # & # \hfil & # \vrule 
+width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& Operation && Method && Description &\cr
+\noalign{\hrule}
+& $a + b$ && plus (a, b) && Binary addition operator&\cr
+& $a - b$ && minus (a, b) && Binary subtraction operator&\cr
+& $+ a$ && uplus (a) && Unary addition operator&\cr
+& $- a$ && uminus (a) && Unary subtraction operator&\cr
+& $a .* b$ && times (a, b) && Element-wise multiplication operator&\cr
+& $a * b$ && mtimes (a, b) && Matrix multiplication operator&\cr
+& $a ./ b$ && rdivide (a, b) && Element-wise right division operator&\cr
+& $a / b$ && mrdivide (a, b) && Matrix right division operator&\cr
+& $a .\backslash b$ && ldivide (a, b) && Element-wise left division operator&\cr
+& $a \backslash b$ && mldivide (a, b) && Matrix left division operator&\cr
+& $a .\hat b$ && power (a, b) && Element-wise power operator&\cr
+& $a \hat b$ && mpower (a, b) && Matrix power operator&\cr
+& $a < b$ && lt (a, b) && Less than operator&\cr
+& $a <= b$ && le (a, b) && Less than or equal to operator&\cr
+& $a > b$ && gt (a, b) && Greater than operator&\cr
+& $a >= b$ && ge (a, b) && Greater than or equal to operator&\cr
+& $a == b$ && eq (a, b) && Equal to operator&\cr
+& $a != b$ && ne (a, b) && Not equal to operator&\cr
+& $a \& b$ && and (a, b) && Logical and operator&\cr
+& $a | b$ && or (a, b) && Logical or operator&\cr
+& $! b$ && not (a) && Logical not operator&\cr
+& $a'$ && ctranspose (a) && Complex conjugate transpose operator &\cr
+& $a.'$ && transpose (a) && Transpose operator &\cr
+& $a : b$ && colon (a, b) && Two element range operator &\cr
+& $a : b : c$ && colon (a, b, c) && Three element range operator &\cr
+& $[a, b]$ && horzcat (a, b) && Horizontal concatenation operator &\cr
+& $[a; b]$ && vertcat (a, b) && Vertical concatenation operator &\cr
+& $a(s_1, \ldots, s_n)$ && subsref (a, s) && Subscripted reference &\cr
+& $a(s_1, \ldots, s_n) = b$ && subsasgn (a, s, b) && Subscripted assignment &\cr
+& $b (a)$ && subsindex (a) && Convert to zero-based index &\cr
+& {\it display} && display (a) && Commandline display function &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .1 .20 .20 .40 .1
+ at item @tab Operation @tab Method @tab Description @tab
+ at item @tab a + b @tab plus (a, b) @tab Binary addition @tab
+ at item @tab a - b$ @tab minus (a, b) @tab Binary subtraction operator @tab
+ at item @tab + a$ @tab uplus (a) @tab Unary addition operator @tab
+ at item @tab - a$ @tab uminus (a) @tab Unary subtraction operator @tab
+ at item @tab a .* b$ @tab times (a, b) @tab Element-wise multiplication operator @tab
+ at item @tab a * b$ @tab mtimes (a, b) @tab Matrix multiplication operator @tab
+ at item @tab a ./ b$ @tab rdivide (a, b) @tab Element-wise right division operator @tab
+ at item @tab a / b$ @tab mrdivide (a, b) @tab Matrix right division operator @tab
+ at item @tab a .\ b$ @tab ldivide (a, b) @tab Element-wise left division operator @tab
+ at item @tab a \ b$ @tab mldivide (a, b) @tab Matrix left division operator @tab
+ at item @tab a .^ b$ @tab ldivide (a, b) @tab Element-wise power operator @tab
+ at item @tab a ^ b$ @tab mldivide (a, b) @tab Matrix power operator @tab
+ at item @tab a < b$ @tab lt (a, b) @tab Less than operator @tab
+ at item @tab a <= b$ @tab le (a, b) @tab Less than or equal to operator @tab
+ at item @tab a > b$ @tab gt (a, b) @tab Greater than operator @tab
+ at item @tab a >= b$ @tab ge (a, b) @tab Greater than or equal to operator @tab
+ at item @tab a == b$ @tab eq (a, b) @tab Equal to operator @tab
+ at item @tab a != b$ @tab ne (a, b) @tab Not equal to operator @tab
+ at item @tab a \& b$ @tab and (a, b) @tab Logical and operator @tab
+ at item @tab a | b$ @tab or (a, b) @tab Logical or operator @tab
+ at item @tab ! b$ @tab not (a) @tab Logical not operator @tab
+ at item @tab a'$ @tab ctranspose (a) @tab Complex conjugate transpose operator @tab
+ at item @tab a.'$ @tab transpose (a) @tab Transpose operator @tab
+ at item @tab a : b$ @tab colon (a, b) @tab Two element range operator @tab
+ at item @tab a : b : c$ @tab colon (a, b, c) @tab Three element range operator @tab
+ at item @tab [a, b]$ @tab horzcat (a, b) @tab Horizontal concatenation operator @tab
+ at item @tab [a; b]$ @tab vertcat (a, b) @tab Vertical concatenation operator @tab
+ at item @tab a(s_1, \ldots, s_n)$ @tab subsref (a, s) @tab Subscripted reference @tab
+ at item @tab a(s_1, \ldots, s_n) = b$ @tab subsasgn (a, s, b) @tab Subscripted assignment @tab
+ at item @tab b (a)$ @tab subsindex (a) @tab Convert to zero-based index @tab
+ at item @tab  @dfn{display} @tab display (a) @tab Commandline display function @tab
+ at end multitable
+ at end ifnottex
+ at caption{Available overloaded operators and their corresponding class method}
+ at end float
+
+An example @code{mtimes} method for our polynomial class might look like
+
+ at polynomialfile{mtimes.m}
+
+ at node Precedence of Objects
+ at subsection Precedence of Objects
+
+Many functions and operators take two or more arguments and so the
+case can easily arise that these functions are called with objects of
+different classes.  It is therefore necessary to determine the precedence
+of which method of which class to call when there are mixed objects given
+to a function or operator.  To do this the @code{superiorto} and
+ at code{inferiorto} functions can be used
+
+ at c ov-class.cc
+ at anchor{doc-superiorto}
+ at deftypefn {Built-in Function} {} superiorto (@var{class_name}, @dots{})
+When called from a class constructor, mark the object currently
+constructed as having a higher precedence than @var{class_name}.
+More that one such class can be specified in a single call.
+This function may only be called from a class constructor.
+ at end deftypefn
+
+
+ at c ov-class.cc
+ at anchor{doc-inferiorto}
+ at deftypefn {Built-in Function} {} inferiorto (@var{class_name}, @dots{})
+When called from a class constructor, mark the object currently
+constructed as having a lower precedence than @var{class_name}.
+More that one such class can be specified in a single call.
+This function may only be called from a class constructor.
+ at end deftypefn
+
+
+For example with our polynomial class consider the case
+
+ at example
+2 * polynomial ([1, 0, 1]);
+ at end example
+
+ at noindent
+That mixes an object of the class "double" with an object of the class
+"polynomial".  In this case we like to ensure that the return type of
+the above is of the type "polynomial" and so we use the
+ at code{superiorto} function in the class constructor.  In particular our
+polynomial class constructor would be modified to be
+
+ at polynomialfile{polynomial_superiorto.m}
+
+Note that user classes always have higher precedence than built-in
+Octave types.  So in fact marking our polynomial class higher than the 
+"double" class is in fact not necessary.
+
+
+ at node Inheritance and Aggregation
+ at section Inheritance and Aggregation
+
+Using classes to build new classes is supported by octave through the
+use of both inheritance and aggregation.
+
+Class inheritance is provided by octave using the @code{class}
+function in the class constructor.  As in the case of the polynomial
+class, the octave programmer will create a struct that contains the
+data fields required by the class, and then call the class function to
+indicate that an object is to be created from the struct.  Creating a
+child of an existing object is done by creating an object of the
+parent class and providing that object as the third argument of the
+class function.
+
+This is easily demonstrated by example.  Suppose the programmer needs
+an FIR filter, i.e. a filter with a numerator polynomial but a unity
+denominator polynomial.  In traditional octave programming, this would
+be performed as follows.
+
+ at example
+octave:1> x = [some data vector];
+octave:2> n = [some coefficient vector];
+octave:3> y = filter (n, 1, x);
+ at end example
+
+The equivalent class could be implemented in a class directory
+@@FIRfilter that is on the octave path.  The constructor is a file
+FIRfilter.m in the class directory.
+
+ at classfile{@@FIRfilter,FIRfilter.m}
+
+As before, the leading comments provide command-line documentation for
+the class constructor.  This constructor is very similar to the
+polynomial class constructor, except that we pass a polynomial object
+as the third argument to the class function, telling octave that the
+FIRfilter class will be derived from the polynomial class.  Our FIR
+filter does not have any data fields, but we must provide a struct to
+the @code{class} function.  The @code{class} function will add an
+element named polynomial to the object struct, so we simply add a
+dummy element named polynomial as the first line of the constructor.
+This dummy element will be overwritten by the class function.
+
+Note further that all our examples provide for the case in which no
+arguments are supplied.  This is important since octave will call the
+constructor with no arguments when loading ojects from save files to
+determine the inheritance structure.
+
+A class may be a child of more than one class (see the documentation
+for the @code{class} function), and inheritance may be nested.  There
+is no limitation to the number of parents or the level of nesting
+other than memory or other physical issues.
+
+As before, we need a @code{display} method.  A simple example might be
+
+ at classfile{@@FIRfilter,display.m}
+
+Note that we have used the polynomial field of the struct to display
+the filter coefficients.
+
+Once we have the class constructor and display method, we may create
+an object by calling the class constructor.  We may also check the
+class type and examine the underlying structure.
+
+ at example
+octave:1> f=FIRfilter(polynomial([1 1 1]/3))
+f.polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+octave:2> class(f)
+ans = FIRfilter
+octave:3> isa(f,"FIRfilter")
+ans =  1
+octave:4> isa(f,"polynomial")
+ans =  1
+octave:5> struct(f)
+ans = 
+@{
+polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+@}
+ at end example
+
+We only need to define a method to actually process data with our
+filter and our class is usable.  It is also useful to provide a means
+of changing the data stored in the class.  Since the fields in the
+underlying struct are private by default, we could provide a mechanism
+to access the fields.  The @code{subsref} method may be used for both.
+
+ at classfile{@@FIRfilter,subsref.m}
+
+The "()" case allows us to filter data using the polynomial provided
+to the constructor.
+
+ at example
+octave:2> f=FIRfilter(polynomial([1 1 1]/3));
+octave:3> x=ones(5,1);
+octave:4> y=f(x)
+y =
+
+   0.33333
+   0.66667
+   1.00000
+   1.00000
+   1.00000
+ at end example
+
+The "." case allows us to view the contents of the polynomial field.
+
+ at example
+octave:1> f=FIRfilter(polynomial([1 1 1]/3));
+octave:2> f.polynomial
+ans = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+ at end example
+
+In order to change the contents of the object, we need to define a
+ at code{subsasgn} method.  For example, we may make the polynomial field
+publicly writeable.
+
+ at classfile{@@FIRfilter,subsasgn.m}
+
+So that
+
+ at example
+octave:6> f=FIRfilter();
+octave:7> f.polynomial = polynomial([1 2 3]);
+f.polynomial = 1 + 2 * X + 3 * X ^ 2
+ at end example
+
+
+Defining the FIRfilter class as a child of the polynomial class
+implies that and FIRfilter object may be used any place that a
+polynomial may be used.  This is not a normal use of a filter, so that
+aggregation may be a more sensible design approach.  In this case, the
+polynomial is simply a field in the class structure.  A class
+constructor for this case might be
+
+ at classfile{@@FIRfilter,FIRfilter_aggregation.m}
+
+For our example, the remaining class methods remain unchanged.
diff --git a/doc/interpreter/oop.txi b/doc/interpreter/oop.txi
new file mode 100644
index 0000000..05b2e12
--- /dev/null
+++ b/doc/interpreter/oop.txi
@@ -0,0 +1,621 @@
+ at c Copyright (C) 2008, 2009 David Bateman
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at c FIXME
+ at c For now can't include "@" character in the path name, and so name
+ at c the example directory without the "@"!!
+
+ at macro classfile{class, file}
+ at example
+ at group
+ at verbatiminclude @value{abs_top_srcdir}/examples/\class\/\file\
+ at end group
+ at end example
+ at end macro
+
+ at macro polynomialfile{file}
+ at classfile{@@polynomial,\file\}
+ at end macro
+
+ at node Object Oriented Programming
+ at chapter Object Oriented Programming
+
+Octave includes the capability to include user classes, including the
+features of operator and function overloading.  Equally a user class
+can be used to encapsulate certain properties of the class so that
+they cannot be altered accidentally and can be set up to address the
+issue of class precedence in mixed class operations.
+
+This chapter discussions the means of constructing a user class with
+the example of a polynomial class, how to query and set the properties
+of this class, together with the means to overload operators and
+functions.
+
+ at menu
+* Creating a Class::
+* Manipulating Classes::
+* Indexing Objects::
+* Overloading Objects::
+* Inheritance and Aggregation::
+ at end menu
+
+ at node Creating a Class
+ at section Creating a Class
+
+We use in the following text a polynomial class to demonstrate the use
+of object oriented programming within Octave.  This class was chosen as
+it is simple, and so doesn't distract unnecessarily from the
+discussion of the programming features of Octave.  However, even still
+a small understand of the polynomial class itself is necessary to
+fully grasp the techniques described.
+
+The polynomial class is used to represent polynomials of the form
+
+ at example
+ at group
+ at tex
+$a_0 + a_1 x + a_2 x^2 + \ldots a_n x^n$
+ at end tex
+ at ifnottex
+a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+ at end ifnottex
+ at end group
+ at end example
+
+ at noindent
+where
+ at tex
+$a_0$, $a_1$, etc. are elements of $\Re$.
+ at end tex
+ at ifnottex
+a0, a1, etc. are real scalars.
+ at end ifnottex
+Thus the polynomial can be represented by a vector
+
+ at example
+a = [a0, a1, a2, @dots{}, an];
+ at end example
+
+We therefore now have sufficient information about the requirements of
+the class constructor for our polynomial class to write it.  All object
+oriented classes in Octave, must be contained with a directory taking
+the name of the class, prepended with the @@ symbol.  For example, with
+our polynomial class, we would place the methods defining the class in
+the @@polynomial directory.
+
+The constructor of the class, must have the name of the class itself
+and so in our example the constructor with have the name
+ at file{@@polynomial/polynomial.m}.  Also ideally when the constructor is
+called with no arguments to should return a value object.  So for example
+our polynomial might look like
+
+ at polynomialfile{polynomial.m}
+
+Note that the return value of the constructor must be the output of
+the @code{class} function called with the first argument being a
+structure and the second argument being the class name.  An example of
+the call to this constructor function is then
+
+ at example
+p = polynomial ([1, 0, 1]);
+ at end example
+
+Note that methods of a class can be documented.  The help for the
+constructor itself can be obtained with the constructor name, that is
+for the polynomial constructor @code{help polynomial} will return the
+help string.  Also the help can be obtained by restricting the search
+for the help to a particular class, for example @code{help
+@@polynomial/polynomial}.  This second method is the only means of
+getting help for the overloaded methods and functions of the class.
+
+The same is true for other Octave functions that take a function name
+as an argument.  For example @code{type @@polynomial/display} will
+print the code of the display method of the polynomial class to the
+screen, and @code{dbstop @@polynomial/display} will set a breakpoint
+at the first executable line of the display method of the polynomial
+class.
+
+To check where a variable is a user class, the @code{isobject} and
+ at code{isa} functions can be used. for example
+
+ at example
+ at group
+p = polynomial ([1, 0, 1]);
+isobject (p)
+ at result{} 1
+isa (p, "polynomial")
+ at result{} 1
+ at end group
+ at end example
+
+ at DOCSTRING(isobject)
+
+ at noindent
+The available methods of a class can be displayed with the
+ at code{methods} function.
+
+ at DOCSTRING(methods)
+
+ at noindent
+To inquire whether a particular method is available to a user class, the
+ at code{ismethod} function can be used.
+
+ at DOCSTRING(ismethod)
+
+ at noindent
+For example
+
+ at example
+ at group
+p = polynomial ([1, 0, 1]);
+ismethod (p, "roots")
+ at result{} 1
+ at end group
+ at end example
+
+ at node Manipulating Classes
+ at section Manipulating Classes
+
+There are a number of basic classes methods that can be defined to allow
+the contents of the classes to be queried and set.  The most basic of
+these is the @code{display} method.  The @code{display} method is used
+by Octave when displaying a class on the screen, due to an expression
+that is not terminated with a semicolon.  If this method is not defined,
+then Octave will printed nothing when displaying the contents of a class.
+
+ at DOCSTRING(display)
+
+ at noindent
+An example of a display method for the polynomial class might be
+
+ at polynomialfile{display.m}
+
+ at noindent
+Note that in the display method, it makes sense to start the method
+with the line @code{fprintf("%s =", inputname(1))} to be consistent
+with the rest of Octave and print the variable name to be displayed
+when displaying the class. 
+
+To be consistent with the Octave graphic handle classes, a class
+should also define the @code{get} and @code{set} methods.  The
+ at code{get} method should accept one or two arguments, and given one
+argument of the appropriate class it should return a structure with
+all of the properties of the class.  For example
+
+ at polynomialfile{get.m}
+
+ at noindent
+Similarly, the @code{set} method should taken as its first argument an
+object to modify, and then take property/value pairs to be modified. 
+
+ at polynomialfile{set.m}
+
+ at noindent
+Note that as Octave does not implement pass by reference, than the
+modified object is the return value of the @code{set} method and it
+must be called like
+
+ at example
+p = set (p, "a", [1, 0, 0, 0, 1]);
+ at end example
+
+ at noindent
+Also the @code{set} method makes use of the @code{subsasgn} method of
+the class, and this method must be defined.  The @code{subsasgn} method
+is discussed in the next section.
+
+Finally, user classes can be considered as a special type of a
+structure, and so they can be saved to a file in the same manner as a
+structure.  For example
+
+ at example
+ at group
+p = polynomial ([1, 0, 1]);
+save userclass.mat p
+clear p
+load userclass.mat
+ at end group
+ at end example
+
+ at noindent
+All of the file formats supported by @code{save} and @code{load} are
+supported.  In certain circumstances, a user class might either contain
+a field that it makes no sense to save or a field that needs to be
+initialized before it is saved.  This can be done with the
+ at code{saveobj} method of the class
+
+ at DOCSTRING(saveobj)
+
+ at noindent
+ at code{saveobj} is called just prior to saving the class to a
+file.  Likely, the @code{loadobj} method is called just after a class
+is loaded from a file, and can be used to ensure that any removed
+fields are reinserted into the user object.
+
+ at DOCSTRING(loadobj)
+
+ at node Indexing Objects
+ at section Indexing Objects
+
+Objects can be indexed with parentheses, either like 
+ at code{@var{a} (@var{idx})} or like @code{@var{a} @{@var{idx}@}}, or even
+like @code{@var{a} (@var{idx}). at var{field}}.  However, it is up to the user
+to decide what this indexing actually means.  In the case of our polynomial
+class @code{@var{p} (@var{n})} might mean either the coefficient of the 
+ at var{n}-th power of the polynomial, or it might be the evaluation of the 
+polynomial at @var{n}.  The meaning of this subscripted referencing is 
+determined by the @code{subsref} method.
+
+ at DOCSTRING(subsref)
+
+For example we might decide that indexing with "()" evaluates the
+polynomial and indexing with "@{@}" returns the @var{n}-th coefficient (of @var{n}-th power).
+In this case the @code{subsref} method of our polynomial class might look like
+
+ at polynomialfile{subsref.m}
+
+The equivalent functionality for subscripted assignments uses the 
+ at code{subsasgn} method.
+
+ at DOCSTRING(subsasgn)
+
+Note that the @code{subsref} and @code{subsasgn} methods always receive the
+whole index chain, while they usually handle only the first element.  It is the
+responsibility of these methods to handle the rest of the chain (if needed),
+usually by forwarding it again to @code{subsref} or @code{subsasgn}.
+
+If you wish to use the @code{end} keyword in subscripted expressions
+of an object, then the user needs to define the @code{end} method for 
+the class.
+
+ at DOCSTRING(end)
+
+For example the @code{end} method for our polynomial class might look like
+
+ at polynomialfile{end.m}
+
+ at noindent
+which is a fairly generic @code{end} method that has a behavior similar to
+the @code{end} keyword for Octave Array classes.  It can then be used for
+example like
+
+ at example
+ at group
+p = polynomial([1,2,3,4]);
+p(end-1)
+ at result{} 3
+ at end group
+ at end example
+
+Objects can also be used as the index in a subscripted expression themselves
+and this is controlled with the @code{subsindex} function.
+
+ at DOCSTRING(subsindex)
+
+Finally, objects can equally be used like ranges, using the @code{colon}
+method
+
+ at DOCSTRING(colon)
+
+ at node Overloading Objects
+ at section Overloading Objects
+
+ at menu
+* Function Overloading::
+* Operator Overloading::
+* Precedence of Objects::
+ at end menu
+
+ at node Function Overloading
+ at subsection Function Overloading
+
+Any Octave function can be overloaded, and allows a object specific
+version of this function to be called as needed.  A pertinent example
+for our polynomial class might be to overload the @code{polyval} function
+like
+
+ at polynomialfile{polyval.m}
+
+This function just hands off the work to the normal Octave @code{polyval}
+function.  Another interesting example for an overloaded function for our
+polynomial class is the @code{plot} function.
+
+ at polynomialfile{plot.m}
+
+ at noindent
+which allows polynomials to be plotted in the domain near the region
+of the roots of the polynomial.
+
+Functions that are of particular interest to be overloaded are the class
+conversion functions such as @code{double}.  Overloading these functions 
+allows the @code{cast} function to work with the user class and can aid 
+in the use of methods of other classes with the user class.  An example
+ at code{double} function for our polynomial class might look like.
+
+ at polynomialfile{double.m}
+
+ at node Operator Overloading
+ at subsection Operator Overloading
+
+ at float Table,tab:overload_ops
+
+ at anchor{doc-rdivide} @anchor{doc-plus} @anchor{doc-minus} @anchor{doc-uminus}
+ at anchor{doc-uplus} @anchor{doc-times} @anchor{doc-mtimes} @anchor{doc-mrdivide}
+ at anchor{doc-ldivide} @anchor{doc-mldivide} @anchor{doc-power}
+ at anchor{doc-mpower} @anchor{doc-lt} @anchor{doc-le} @anchor{doc-gt}
+ at anchor{doc-ge} @anchor{doc-eq} @anchor{doc-ne} @anchor{doc-and}
+ at anchor{doc-or} @anchor{doc-not} @anchor{doc-ctranspose} @anchor{doc-transpose}
+
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & \vrule # & # \hfil & # \vrule 
+width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& Operation && Method && Description &\cr
+\noalign{\hrule}
+& $a + b$ && plus (a, b) && Binary addition operator&\cr
+& $a - b$ && minus (a, b) && Binary subtraction operator&\cr
+& $+ a$ && uplus (a) && Unary addition operator&\cr
+& $- a$ && uminus (a) && Unary subtraction operator&\cr
+& $a .* b$ && times (a, b) && Element-wise multiplication operator&\cr
+& $a * b$ && mtimes (a, b) && Matrix multiplication operator&\cr
+& $a ./ b$ && rdivide (a, b) && Element-wise right division operator&\cr
+& $a / b$ && mrdivide (a, b) && Matrix right division operator&\cr
+& $a .\backslash b$ && ldivide (a, b) && Element-wise left division operator&\cr
+& $a \backslash b$ && mldivide (a, b) && Matrix left division operator&\cr
+& $a .\hat b$ && power (a, b) && Element-wise power operator&\cr
+& $a \hat b$ && mpower (a, b) && Matrix power operator&\cr
+& $a < b$ && lt (a, b) && Less than operator&\cr
+& $a <= b$ && le (a, b) && Less than or equal to operator&\cr
+& $a > b$ && gt (a, b) && Greater than operator&\cr
+& $a >= b$ && ge (a, b) && Greater than or equal to operator&\cr
+& $a == b$ && eq (a, b) && Equal to operator&\cr
+& $a != b$ && ne (a, b) && Not equal to operator&\cr
+& $a \& b$ && and (a, b) && Logical and operator&\cr
+& $a | b$ && or (a, b) && Logical or operator&\cr
+& $! b$ && not (a) && Logical not operator&\cr
+& $a'$ && ctranspose (a) && Complex conjugate transpose operator &\cr
+& $a.'$ && transpose (a) && Transpose operator &\cr
+& $a : b$ && colon (a, b) && Two element range operator &\cr
+& $a : b : c$ && colon (a, b, c) && Three element range operator &\cr
+& $[a, b]$ && horzcat (a, b) && Horizontal concatenation operator &\cr
+& $[a; b]$ && vertcat (a, b) && Vertical concatenation operator &\cr
+& $a(s_1, \ldots, s_n)$ && subsref (a, s) && Subscripted reference &\cr
+& $a(s_1, \ldots, s_n) = b$ && subsasgn (a, s, b) && Subscripted assignment &\cr
+& $b (a)$ && subsindex (a) && Convert to zero-based index &\cr
+& {\it display} && display (a) && Commandline display function &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .1 .20 .20 .40 .1
+ at item @tab Operation @tab Method @tab Description @tab
+ at item @tab a + b @tab plus (a, b) @tab Binary addition @tab
+ at item @tab a - b$ @tab minus (a, b) @tab Binary subtraction operator @tab
+ at item @tab + a$ @tab uplus (a) @tab Unary addition operator @tab
+ at item @tab - a$ @tab uminus (a) @tab Unary subtraction operator @tab
+ at item @tab a .* b$ @tab times (a, b) @tab Element-wise multiplication operator @tab
+ at item @tab a * b$ @tab mtimes (a, b) @tab Matrix multiplication operator @tab
+ at item @tab a ./ b$ @tab rdivide (a, b) @tab Element-wise right division operator @tab
+ at item @tab a / b$ @tab mrdivide (a, b) @tab Matrix right division operator @tab
+ at item @tab a .\ b$ @tab ldivide (a, b) @tab Element-wise left division operator @tab
+ at item @tab a \ b$ @tab mldivide (a, b) @tab Matrix left division operator @tab
+ at item @tab a .^ b$ @tab ldivide (a, b) @tab Element-wise power operator @tab
+ at item @tab a ^ b$ @tab mldivide (a, b) @tab Matrix power operator @tab
+ at item @tab a < b$ @tab lt (a, b) @tab Less than operator @tab
+ at item @tab a <= b$ @tab le (a, b) @tab Less than or equal to operator @tab
+ at item @tab a > b$ @tab gt (a, b) @tab Greater than operator @tab
+ at item @tab a >= b$ @tab ge (a, b) @tab Greater than or equal to operator @tab
+ at item @tab a == b$ @tab eq (a, b) @tab Equal to operator @tab
+ at item @tab a != b$ @tab ne (a, b) @tab Not equal to operator @tab
+ at item @tab a \& b$ @tab and (a, b) @tab Logical and operator @tab
+ at item @tab a | b$ @tab or (a, b) @tab Logical or operator @tab
+ at item @tab ! b$ @tab not (a) @tab Logical not operator @tab
+ at item @tab a'$ @tab ctranspose (a) @tab Complex conjugate transpose operator @tab
+ at item @tab a.'$ @tab transpose (a) @tab Transpose operator @tab
+ at item @tab a : b$ @tab colon (a, b) @tab Two element range operator @tab
+ at item @tab a : b : c$ @tab colon (a, b, c) @tab Three element range operator @tab
+ at item @tab [a, b]$ @tab horzcat (a, b) @tab Horizontal concatenation operator @tab
+ at item @tab [a; b]$ @tab vertcat (a, b) @tab Vertical concatenation operator @tab
+ at item @tab a(s_1, \ldots, s_n)$ @tab subsref (a, s) @tab Subscripted reference @tab
+ at item @tab a(s_1, \ldots, s_n) = b$ @tab subsasgn (a, s, b) @tab Subscripted assignment @tab
+ at item @tab b (a)$ @tab subsindex (a) @tab Convert to zero-based index @tab
+ at item @tab  @dfn{display} @tab display (a) @tab Commandline display function @tab
+ at end multitable
+ at end ifnottex
+ at caption{Available overloaded operators and their corresponding class method}
+ at end float
+
+An example @code{mtimes} method for our polynomial class might look like
+
+ at polynomialfile{mtimes.m}
+
+ at node Precedence of Objects
+ at subsection Precedence of Objects
+
+Many functions and operators take two or more arguments and so the
+case can easily arise that these functions are called with objects of
+different classes.  It is therefore necessary to determine the precedence
+of which method of which class to call when there are mixed objects given
+to a function or operator.  To do this the @code{superiorto} and
+ at code{inferiorto} functions can be used
+
+ at DOCSTRING(superiorto)
+
+ at DOCSTRING(inferiorto)
+
+For example with our polynomial class consider the case
+
+ at example
+2 * polynomial ([1, 0, 1]);
+ at end example
+
+ at noindent
+That mixes an object of the class "double" with an object of the class
+"polynomial".  In this case we like to ensure that the return type of
+the above is of the type "polynomial" and so we use the
+ at code{superiorto} function in the class constructor.  In particular our
+polynomial class constructor would be modified to be
+
+ at polynomialfile{polynomial_superiorto.m}
+
+Note that user classes always have higher precedence than built-in
+Octave types.  So in fact marking our polynomial class higher than the 
+"double" class is in fact not necessary.
+
+
+ at node Inheritance and Aggregation
+ at section Inheritance and Aggregation
+
+Using classes to build new classes is supported by octave through the
+use of both inheritance and aggregation.
+
+Class inheritance is provided by octave using the @code{class}
+function in the class constructor.  As in the case of the polynomial
+class, the octave programmer will create a struct that contains the
+data fields required by the class, and then call the class function to
+indicate that an object is to be created from the struct.  Creating a
+child of an existing object is done by creating an object of the
+parent class and providing that object as the third argument of the
+class function.
+
+This is easily demonstrated by example.  Suppose the programmer needs
+an FIR filter, i.e. a filter with a numerator polynomial but a unity
+denominator polynomial.  In traditional octave programming, this would
+be performed as follows.
+
+ at example
+octave:1> x = [some data vector];
+octave:2> n = [some coefficient vector];
+octave:3> y = filter (n, 1, x);
+ at end example
+
+The equivalent class could be implemented in a class directory
+@@FIRfilter that is on the octave path.  The constructor is a file
+FIRfilter.m in the class directory.
+
+ at classfile{@@FIRfilter,FIRfilter.m}
+
+As before, the leading comments provide command-line documentation for
+the class constructor.  This constructor is very similar to the
+polynomial class constructor, except that we pass a polynomial object
+as the third argument to the class function, telling octave that the
+FIRfilter class will be derived from the polynomial class.  Our FIR
+filter does not have any data fields, but we must provide a struct to
+the @code{class} function.  The @code{class} function will add an
+element named polynomial to the object struct, so we simply add a
+dummy element named polynomial as the first line of the constructor.
+This dummy element will be overwritten by the class function.
+
+Note further that all our examples provide for the case in which no
+arguments are supplied.  This is important since octave will call the
+constructor with no arguments when loading ojects from save files to
+determine the inheritance structure.
+
+A class may be a child of more than one class (see the documentation
+for the @code{class} function), and inheritance may be nested.  There
+is no limitation to the number of parents or the level of nesting
+other than memory or other physical issues.
+
+As before, we need a @code{display} method.  A simple example might be
+
+ at classfile{@@FIRfilter,display.m}
+
+Note that we have used the polynomial field of the struct to display
+the filter coefficients.
+
+Once we have the class constructor and display method, we may create
+an object by calling the class constructor.  We may also check the
+class type and examine the underlying structure.
+
+ at example
+octave:1> f=FIRfilter(polynomial([1 1 1]/3))
+f.polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+octave:2> class(f)
+ans = FIRfilter
+octave:3> isa(f,"FIRfilter")
+ans =  1
+octave:4> isa(f,"polynomial")
+ans =  1
+octave:5> struct(f)
+ans = 
+@{
+polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+@}
+ at end example
+
+We only need to define a method to actually process data with our
+filter and our class is usable.  It is also useful to provide a means
+of changing the data stored in the class.  Since the fields in the
+underlying struct are private by default, we could provide a mechanism
+to access the fields.  The @code{subsref} method may be used for both.
+
+ at classfile{@@FIRfilter,subsref.m}
+
+The "()" case allows us to filter data using the polynomial provided
+to the constructor.
+
+ at example
+octave:2> f=FIRfilter(polynomial([1 1 1]/3));
+octave:3> x=ones(5,1);
+octave:4> y=f(x)
+y =
+
+   0.33333
+   0.66667
+   1.00000
+   1.00000
+   1.00000
+ at end example
+
+The "." case allows us to view the contents of the polynomial field.
+
+ at example
+octave:1> f=FIRfilter(polynomial([1 1 1]/3));
+octave:2> f.polynomial
+ans = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+ at end example
+
+In order to change the contents of the object, we need to define a
+ at code{subsasgn} method.  For example, we may make the polynomial field
+publicly writeable.
+
+ at classfile{@@FIRfilter,subsasgn.m}
+
+So that
+
+ at example
+octave:6> f=FIRfilter();
+octave:7> f.polynomial = polynomial([1 2 3]);
+f.polynomial = 1 + 2 * X + 3 * X ^ 2
+ at end example
+
+
+Defining the FIRfilter class as a child of the polynomial class
+implies that and FIRfilter object may be used any place that a
+polynomial may be used.  This is not a normal use of a filter, so that
+aggregation may be a more sensible design approach.  In this case, the
+polynomial is simply a field in the class structure.  A class
+constructor for this case might be
+
+ at classfile{@@FIRfilter,FIRfilter_aggregation.m}
+
+For our example, the remaining class methods remain unchanged.
diff --git a/doc/interpreter/op-idx.texi b/doc/interpreter/op-idx.texi
new file mode 100644
index 0000000..0f1e389
--- /dev/null
+++ b/doc/interpreter/op-idx.texi
@@ -0,0 +1,24 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Operator Index
+ at unnumbered Operator Index
+
+ at printindex op
diff --git a/doc/interpreter/op-idx.txi b/doc/interpreter/op-idx.txi
new file mode 100644
index 0000000..49154dd
--- /dev/null
+++ b/doc/interpreter/op-idx.txi
@@ -0,0 +1,22 @@
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Operator Index
+ at unnumbered Operator Index
+
+ at printindex op
diff --git a/doc/interpreter/optim.texi b/doc/interpreter/optim.texi
new file mode 100644
index 0000000..22acf52
--- /dev/null
+++ b/doc/interpreter/optim.texi
@@ -0,0 +1,930 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Optimization
+ at chapter Optimization
+
+Octave comes with support for solving various kinds of optimization
+problems.  Specifically Octave can solve problems in Linear Programming,
+Quadratic Programming, Nonlinear Programming, and Linear Least Squares
+Minimization.
+
+ at menu
+* Linear Programming::       
+* Quadratic Programming::       
+* Nonlinear Programming::       
+* Linear Least Squares::        
+ at end menu
+
+ at c @cindex linear programming
+ at cindex quadratic programming
+ at cindex nonlinear programming
+ at cindex optimization
+ at cindex LP
+ at cindex QP
+ at cindex NLP
+
+ at node Linear Programming
+ at section Linear Programming
+
+Octave can solve Linear Programming problems using the @code{glpk}
+function.  That is, Octave can solve
+
+ at tex
+$$
+  \min_x c^T x
+$$
+ at end tex
+ at ifnottex
+ at example
+min C'*x
+ at end example
+ at end ifnottex
+subject to the linear constraints
+ at tex
+$Ax = b$ where $x \geq 0$.
+ at end tex
+ at ifnottex
+ at math{A*x = b} where @math{x >= 0}.
+ at end ifnottex
+
+ at noindent
+The @code{glpk} function also supports variations of this problem.
+
+ at c ./optimization/glpk.m
+ at anchor{doc-glpk}
+ at deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{status}, @var{extra}] =} glpk (@var{c}, @var{a}, @var{b}, @var{lb}, @var{ub}, @var{ctype}, @var{vartype}, @var{sense}, @var{param})
+Solve a linear program using the GNU GLPK library.  Given three
+arguments, @code{glpk} solves the following standard LP:
+
+ at tex
+$$
+  \min_x C^T x
+$$
+ at end tex
+ at ifnottex
+ at example
+min C'*x
+ at end example
+ at end ifnottex
+
+subject to
+
+ at tex
+$$
+  Ax = b \qquad x \geq 0
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+A*x  = b
+  x >= 0
+ at end group
+ at end example
+ at end ifnottex
+
+but may also solve problems of the form
+
+ at tex
+$$
+  [ \min_x | \max_x ] C^T x
+$$
+ at end tex
+ at ifnottex
+ at example
+[ min | max ] C'*x
+ at end example
+ at end ifnottex
+
+subject to
+
+ at tex
+$$
+ Ax [ = | \leq | \geq ] b \qquad LB \leq x \leq UB
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+A*x [ "=" | "<=" | ">=" ] b
+  x >= LB
+  x <= UB
+ at end group
+ at end example
+ at end ifnottex
+
+Input arguments:
+
+ at table @var
+ at item c
+A column array containing the objective function coefficients.
+
+ at item a
+A matrix containing the constraints coefficients.
+
+ at item b
+A column array containing the right-hand side value for each constraint
+in the constraint matrix.
+
+ at item lb
+An array containing the lower bound on each of the variables.  If
+ at var{lb} is not supplied, the default lower bound for the variables is
+zero.
+
+ at item ub
+An array containing the upper bound on each of the variables.  If
+ at var{ub} is not supplied, the default upper bound is assumed to be
+infinite.
+
+ at item ctype
+An array of characters containing the sense of each constraint in the
+constraint matrix.  Each element of the array may be one of the
+following values
+ at table @code
+ at item "F"
+A free (unbounded) constraint (the constraint is ignored).
+ at item "U"
+An inequality constraint with an upper bound (@code{A(i,:)*x <= b(i)}).
+ at item "S"
+An equality constraint (@code{A(i,:)*x = b(i)}).
+ at item "L"
+An inequality with a lower bound (@code{A(i,:)*x >= b(i)}).
+ at item "D"
+An inequality constraint with both upper and lower bounds
+(@code{A(i,:)*x >= -b(i)} @emph{and} (@code{A(i,:)*x <= b(i)}).
+ at end table
+
+ at item vartype
+A column array containing the types of the variables.
+ at table @code
+ at item "C"
+A continuous variable.
+ at item "I"
+An integer variable.
+ at end table
+
+ at item sense
+If @var{sense} is 1, the problem is a minimization.  If @var{sense} is
+-1, the problem is a maximization.  The default value is 1.
+
+ at item param
+A structure containing the following parameters used to define the
+behavior of solver.  Missing elements in the structure take on default
+values, so you only need to set the elements that you wish to change
+from the default.
+
+Integer parameters:
+
+ at table @code
+ at item msglev (@code{LPX_K_MSGLEV}, default: 1)
+Level of messages output by solver routines:
+ at table @asis
+ at item 0
+No output.
+ at item 1
+Error messages only.
+ at item 2
+Normal output .
+ at item 3
+Full output (includes informational messages).
+ at end table
+
+ at item scale (@code{LPX_K_SCALE}, default: 1)
+Scaling option: 
+ at table @asis
+ at item 0
+No scaling.
+ at item 1
+Equilibration scaling.
+ at item 2
+Geometric mean scaling, then equilibration scaling.
+ at end table
+
+ at item dual	 (@code{LPX_K_DUAL}, default: 0)
+Dual simplex option:
+ at table @asis
+ at item 0
+Do not use the dual simplex.
+ at item 1
+If initial basic solution is dual feasible, use the dual simplex.
+ at end table
+
+ at item price	 (@code{LPX_K_PRICE}, default: 1)
+Pricing option (for both primal and dual simplex):
+ at table @asis
+ at item 0
+Textbook pricing.
+ at item 1
+Steepest edge pricing.
+ at end table
+  
+ at item round	 (@code{LPX_K_ROUND}, default: 0)
+Solution rounding option:
+ at table @asis
+ at item 0
+Report all primal and dual values "as is".
+ at item 1
+Replace tiny primal and dual values by exact zero.
+ at end table
+
+ at item itlim	 (@code{LPX_K_ITLIM}, default: -1)
+Simplex iterations limit.  If this value is positive, it is decreased by
+one each time when one simplex iteration has been performed, and
+reaching zero value signals the solver to stop the search.  Negative
+value means no iterations limit.
+
+ at item itcnt (@code{LPX_K_OUTFRQ}, default: 200)
+Output frequency, in iterations.  This parameter specifies how
+frequently the solver sends information about the solution to the
+standard output.
+
+ at item branch (@code{LPX_K_BRANCH}, default: 2)
+Branching heuristic option (for MIP only):
+ at table @asis
+ at item 0
+Branch on the first variable.
+ at item 1
+Branch on the last variable.
+ at item 2
+Branch using a heuristic by Driebeck and Tomlin.
+ at end table
+
+ at item btrack (@code{LPX_K_BTRACK}, default: 2)
+Backtracking heuristic option (for MIP only):
+ at table @asis
+ at item 0
+Depth first search.
+ at item 1
+Breadth first search.
+ at item 2
+Backtrack using the best projection heuristic.
+ at end table        
+
+ at item presol (@code{LPX_K_PRESOL}, default: 1)
+If this flag is set, the routine lpx_simplex solves the problem using
+the built-in LP presolver.  Otherwise the LP presolver is not used.
+
+ at item lpsolver (default: 1)
+Select which solver to use.  If the problem is a MIP problem this flag
+will be ignored.
+ at table @asis
+ at item 1
+Revised simplex method.
+ at item 2
+Interior point method.
+ at end table
+ at item save (default: 0)
+If this parameter is nonzero, save a copy of the problem in
+CPLEX LP format to the file @file{"outpb.lp"}.  There is currently no
+way to change the name of the output file.
+ at end table
+
+Real parameters:
+
+ at table @code
+ at item relax (@code{LPX_K_RELAX}, default: 0.07)
+Relaxation parameter used in the ratio test.  If it is zero, the textbook
+ratio test is used.  If it is non-zero (should be positive), Harris'
+two-pass ratio test is used.  In the latter case on the first pass of the
+ratio test basic variables (in the case of primal simplex) or reduced
+costs of non-basic variables (in the case of dual simplex) are allowed
+to slightly violate their bounds, but not more than
+ at code{relax*tolbnd} or @code{relax*toldj (thus, @code{relax} is a
+percentage of @code{tolbnd} or @code{toldj}}.
+
+ at item tolbnd (@code{LPX_K_TOLBND}, default: 10e-7)
+Relative tolerance used to check if the current basic solution is primal
+feasible.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+ at item toldj (@code{LPX_K_TOLDJ}, default: 10e-7)
+Absolute tolerance used to check if the current basic solution is dual
+feasible.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+ at item tolpiv (@code{LPX_K_TOLPIV}, default: 10e-9)
+Relative tolerance used to choose eligible pivotal elements of the
+simplex table.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+ at item objll (@code{LPX_K_OBJLL}, default: -DBL_MAX)
+Lower limit of the objective function.  If on the phase II the objective
+function reaches this limit and continues decreasing, the solver stops
+the search.  This parameter is used in the dual simplex method only.
+
+ at item objul (@code{LPX_K_OBJUL}, default: +DBL_MAX)
+Upper limit of the objective function.  If on the phase II the objective
+function reaches this limit and continues increasing, the solver stops
+the search.  This parameter is used in the dual simplex only.
+
+ at item tmlim (@code{LPX_K_TMLIM}, default: -1.0)
+Searching time limit, in seconds.  If this value is positive, it is
+decreased each time when one simplex iteration has been performed by the
+amount of time spent for the iteration, and reaching zero value signals
+the solver to stop the search.  Negative value means no time limit.
+
+ at item outdly (@code{LPX_K_OUTDLY}, default: 0.0)
+Output delay, in seconds.  This parameter specifies how long the solver
+should delay sending information about the solution to the standard
+output.  Non-positive value means no delay.
+
+ at item tolint (@code{LPX_K_TOLINT}, default: 10e-5)
+Relative tolerance used to check if the current basic solution is integer
+feasible.  It is not recommended that you change this parameter unless
+you have a detailed understanding of its purpose.
+
+ at item tolobj (@code{LPX_K_TOLOBJ}, default: 10e-7)
+Relative tolerance used to check if the value of the objective function
+is not better than in the best known integer feasible solution.  It is
+not recommended that you change this parameter unless you have a
+detailed understanding of its purpose.
+ at end table
+ at end table
+
+Output values:
+
+ at table @var
+ at item xopt
+The optimizer (the value of the decision variables at the optimum).
+ at item fopt
+The optimum value of the objective function.
+ at item status
+Status of the optimization.
+
+Simplex Method:
+ at table @asis
+ at item 180 (@code{LPX_OPT})
+Solution is optimal.
+ at item 181 (@code{LPX_FEAS})
+Solution is feasible.
+ at item 182 (@code{LPX_INFEAS})
+Solution is infeasible.
+ at item 183 (@code{LPX_NOFEAS})
+Problem has no feasible solution.
+ at item 184 (@code{LPX_UNBND})
+Problem has no unbounded solution.
+ at item 185 (@code{LPX_UNDEF})
+Solution status is undefined.
+ at end table
+Interior Point Method:
+ at table @asis
+ at item 150 (@code{LPX_T_UNDEF})
+The interior point method is undefined.
+ at item 151 (@code{LPX_T_OPT})
+The interior point method is optimal.
+ at end table
+Mixed Integer Method:
+ at table @asis
+ at item 170 (@code{LPX_I_UNDEF})
+The status is undefined.
+ at item 171 (@code{LPX_I_OPT})
+The solution is integer optimal.
+ at item 172 (@code{LPX_I_FEAS})
+Solution integer feasible but its optimality has not been proven
+ at item 173 (@code{LPX_I_NOFEAS})
+No integer feasible solution.
+ at end table
+ at noindent
+If an error occurs, @var{status} will contain one of the following
+codes:
+
+ at table @asis
+ at item 204 (@code{LPX_E_FAULT})
+Unable to start the search.
+ at item 205 (@code{LPX_E_OBJLL})
+Objective function lower limit reached.
+ at item 206 (@code{LPX_E_OBJUL})
+Objective function upper limit reached.
+ at item 207 (@code{LPX_E_ITLIM})
+Iterations limit exhausted.
+ at item 208 (@code{LPX_E_TMLIM})
+Time limit exhausted.
+ at item 209 (@code{LPX_E_NOFEAS})
+No feasible solution.
+ at item 210 (@code{LPX_E_INSTAB})
+Numerical instability.
+ at item 211 (@code{LPX_E_SING})
+Problems with basis matrix.
+ at item 212 (@code{LPX_E_NOCONV})
+No convergence (interior).
+ at item 213 (@code{LPX_E_NOPFS})
+No primal feasible solution (LP presolver).
+ at item 214 (@code{LPX_E_NODFS})
+No dual feasible solution (LP presolver).
+ at end table
+ at item extra
+A data structure containing the following fields:
+ at table @code
+ at item lambda
+Dual variables.
+ at item redcosts
+Reduced Costs.
+ at item time
+Time (in seconds) used for solving LP/MIP problem.
+ at item mem
+Memory (in bytes) used for solving LP/MIP problem (this is not 
+available if the version of GLPK is 4.15 or later).
+ at end table
+ at end table
+
+Example:
+
+ at example
+ at group
+c = [10, 6, 4]';
+a = [ 1, 1, 1;
+     10, 4, 5;
+      2, 2, 6];
+b = [100, 600, 300]';
+lb = [0, 0, 0]';
+ub = [];
+ctype = "UUU";
+vartype = "CCC";
+s = -1;
+
+param.msglev = 1;
+param.itlim = 100;
+
+[xmin, fmin, status, extra] = @dots{}
+   glpk (c, a, b, lb, ub, ctype, vartype, s, param);
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at node Quadratic Programming
+ at section Quadratic Programming
+
+Octave can also solve Quadratic Programming problems, this is
+ at tex
+$$
+ \min_x {1 \over 2} x^T H x + x^T q
+$$
+ at end tex
+ at ifnottex
+ at example
+min 0.5 x'*H*x + x'*q
+ at end example
+ at end ifnottex
+subject to
+ at tex
+$$
+ Ax = b \qquad lb \leq x \leq ub \qquad A_{lb} \leq A_{in} \leq A_{ub}
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+     A*x = b
+     lb <= x <= ub
+     A_lb <= A_in*x <= A_ub
+ at end group
+ at end example
+ at end ifnottex
+
+ at c ./optimization/qp.m
+ at anchor{doc-qp}
+ at deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb}, @var{A_in}, @var{A_ub})
+Solve the quadratic program
+ at tex
+$$
+ \min_x {1 \over 2} x^T H x + x^T q
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     min 0.5 x'*H*x + x'*q
+      x
+ at end group
+ at end example
+
+ at end ifnottex
+subject to
+ at tex
+$$
+ Ax = b \qquad lb \leq x \leq ub \qquad A_{lb} \leq A_{in} \leq A_{ub}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     A*x = b
+     lb <= x <= ub
+     A_lb <= A_in*x <= A_ub
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+using a null-space active-set method.
+
+Any bound (@var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb},
+ at var{A_ub}) may be set to the empty matrix (@code{[]}) if not
+present.  If the initial guess is feasible the algorithm is faster.
+
+The value @var{info} is a structure with the following fields:
+ at table @code
+ at item solveiter
+The number of iterations required to find the solution.
+ at item info
+An integer indicating the status of the solution, as follows:
+ at table @asis
+ at item 0
+The problem is feasible and convex.  Global solution found.
+ at item 1
+The problem is not convex.  Local solution found.
+ at item 2
+The problem is not convex and unbounded.
+ at item 3
+Maximum number of iterations reached.
+ at item 6
+The problem is infeasible.
+ at end table
+ at end table
+ at end deftypefn
+
+
+ at node Nonlinear Programming
+ at section Nonlinear Programming
+
+Octave can also perform general nonlinear minimization using a
+successive quadratic programming solver.
+
+ at c ./optimization/sqp.m
+ at anchor{doc-sqp}
+ at deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{iter}, @var{nf}, @var{lambda}] =} sqp (@var{x}, @var{phi}, @var{g}, @var{h}, @var{lb}, @var{ub}, @var{maxiter}, @var{tolerance})
+Solve the nonlinear program
+ at tex
+$$
+\min_x \phi (x)
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     min phi (x)
+      x
+ at end group
+ at end example
+
+ at end ifnottex
+subject to
+ at tex
+$$
+ g(x) = 0 \qquad h(x) \geq 0 \qquad lb \leq x \leq ub
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     g(x)  = 0
+     h(x) >= 0
+     lb <= x <= ub
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+using a successive quadratic programming method.
+
+The first argument is the initial guess for the vector @var{x}.
+
+The second argument is a function handle pointing to the objective
+function.  The objective function must be of the form
+
+ at example
+     y = phi (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{y} is a scalar.
+
+The second argument may also be a 2- or 3-element cell array of
+function handles.  The first element should point to the objective
+function, the second should point to a function that computes the
+gradient of the objective function, and the third should point to a
+function to compute the hessian of the objective function.  If the
+gradient function is not supplied, the gradient is computed by finite
+differences.  If the hessian function is not supplied, a BFGS update
+formula is used to approximate the hessian.
+
+If supplied, the gradient function must be of the form
+
+ at example
+g = gradient (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{g} is a vector.
+
+If supplied, the hessian function must be of the form
+
+ at example
+h = hessian (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{h} is a matrix.
+
+The third and fourth arguments are function handles pointing to
+functions that compute the equality constraints and the inequality
+constraints, respectively.
+
+If your problem does not have equality (or inequality) constraints,
+you may pass an empty matrix for @var{cef} (or @var{cif}).
+
+If supplied, the equality and inequality constraint functions must be
+of the form
+
+ at example
+r = f (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{r} is a vector.
+
+The third and fourth arguments may also be 2-element cell arrays of
+function handles.  The first element should point to the constraint
+function and the second should point to a function that computes the
+gradient of the constraint function:
+
+ at tex
+$$
+ \Bigg( {\partial f(x) \over \partial x_1}, 
+        {\partial f(x) \over \partial x_2}, \ldots,
+        {\partial f(x) \over \partial x_N} \Bigg)^T
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+                [ d f(x)   d f(x)        d f(x) ]
+    transpose ( [ ------   -----   ...   ------ ] )
+                [  dx_1     dx_2          dx_N  ]
+ at end group
+ at end example
+ at end ifnottex
+
+The fifth and sixth arguments are vectors containing lower and upper bounds
+on @var{x}.  These must be consistent with equality and inequality
+constraints @var{g} and @var{h}.  If the bounds are not specified, or are
+empty, they are set to - at var{realmax} and @var{realmax} by default.
+
+The seventh argument is max. number of iterations.  If not specified,
+the default value is 100.
+
+The eighth argument is tolerance for stopping criteria.  If not specified,
+the default value is @var{eps}.
+
+Here is an example of calling @code{sqp}:
+
+ at example
+function r = g (x)
+  r = [ sumsq(x)-10;
+        x(2)*x(3)-5*x(4)*x(5); 
+        x(1)^3+x(2)^3+1 ];
+endfunction
+
+function obj = phi (x)
+  obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+endfunction
+
+x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+
+[x, obj, info, iter, nf, lambda] = sqp (x0, @@phi, @@g, [])
+
+x =
+    
+  -1.71714
+   1.59571
+   1.82725
+  -0.76364
+  -0.76364
+     
+obj = 0.053950
+info = 101
+iter = 8
+nf = 10
+lambda =
+    
+  -0.0401627
+   0.0379578
+  -0.0052227
+ at end example
+
+The value returned in @var{info} may be one of the following:
+ at table @asis
+ at item 101
+The algorithm terminated because the norm of the last step was less
+than @code{tol * norm (x))} (the value of tol is currently fixed at
+ at code{sqrt (eps)}---edit @file{sqp.m} to modify this value.
+ at item 102
+The BFGS update failed.
+ at item 103
+The maximum number of iterations was reached (the maximum number of
+allowed iterations is currently fixed at 100---edit @file{sqp.m} to
+increase this value).
+ at end table
+ at seealso{@ref{doc-qp,,qp}}
+ at end deftypefn
+
+
+ at node Linear Least Squares
+ at section Linear Least Squares
+
+Octave also supports linear least squares minimization.  That is,
+Octave can find the parameter @math{b} such that the model
+ at tex
+$y = xb$
+ at end tex
+ at ifnottex
+ at math{y = x*b}
+ at end ifnottex
+fits data @math{(x,y)} as well as possible, assuming zero-mean
+Gaussian noise.  If the noise is assumed to be isotropic the problem
+can be solved using the @samp{\} or @samp{/} operators, or the @code{ols}
+function.  In the general case where the noise is assumed to be anisotropic
+the @code{gls} is needed.
+
+ at c ./statistics/base/ols.m
+ at anchor{doc-ols}
+ at deftypefn {Function File} {[@var{beta}, @var{sigma}, @var{r}] =} ols (@var{y}, @var{x})
+Ordinary least squares estimation for the multivariate model
+ at tex
+$y = x b + e$
+with
+$\bar{e} = 0$, and cov(vec($e$)) = kron ($s, I$)
+ at end tex
+ at ifnottex
+ at math{y = x b + e} with
+ at math{mean (e) = 0} and @math{cov (vec (e)) = kron (s, I)}.
+ at end ifnottex
+ where
+ at tex
+$y$ is a $t \times p$ matrix, $x$ is a $t \times k$ matrix,
+$b$ is a $k \times p$ matrix, and $e$ is a $t \times p$ matrix.
+ at end tex
+ at ifnottex
+ at math{y} is a @math{t} by @math{p} matrix, @math{x} is a @math{t} by
+ at math{k} matrix, @math{b} is a @math{k} by @math{p} matrix, and
+ at math{e} is a @math{t} by @math{p} matrix.
+ at end ifnottex
+
+Each row of @var{y} and @var{x} is an observation and each column a
+variable.
+
+The return values @var{beta}, @var{sigma}, and @var{r} are defined as
+follows.
+
+ at table @var
+ at item beta
+The OLS estimator for @var{b}, @code{@var{beta} = pinv (@var{x}) *
+ at var{y}}, where @code{pinv (@var{x})} denotes the pseudoinverse of
+ at var{x}.
+
+ at item sigma
+The OLS estimator for the matrix @var{s},
+
+ at example
+ at group
+ at var{sigma} = (@var{y}- at var{x}*@var{beta})'
+  * (@var{y}- at var{x}*@var{beta})
+  / (@var{t}-rank(@var{x}))
+ at end group
+ at end example
+
+ at item r
+The matrix of OLS residuals, @code{@var{r} = @var{y} - @var{x} *
+ at var{beta}}.
+ at end table
+ at end deftypefn
+
+
+ at c ./statistics/base/gls.m
+ at anchor{doc-gls}
+ at deftypefn {Function File} {[@var{beta}, @var{v}, @var{r}] =} gls (@var{y}, @var{x}, @var{o})
+Generalized least squares estimation for the multivariate model
+ at tex
+$y = x b + e$
+with $\bar{e} = 0$ and cov(vec($e$)) = $(s^2)o$,
+ at end tex
+ at ifnottex
+ at math{y = x b + e} with @math{mean (e) = 0} and
+ at math{cov (vec (e)) = (s^2) o},
+ at end ifnottex
+ where
+ at tex
+$y$ is a $t \times p$ matrix, $x$ is a $t \times k$ matrix, $b$ is a $k
+\times p$ matrix, $e$ is a $t \times p$ matrix, and $o$ is a $tp \times
+tp$ matrix.
+ at end tex
+ at ifnottex
+ at math{y} is a @math{t} by @math{p} matrix, @math{x} is a @math{t} by
+ at math{k} matrix, @math{b} is a @math{k} by @math{p} matrix, @math{e}
+is a @math{t} by @math{p} matrix, and @math{o} is a @math{t p} by
+ at math{t p} matrix.
+ at end ifnottex
+
+ at noindent
+Each row of @var{y} and @var{x} is an observation and each column a
+variable.  The return values @var{beta}, @var{v}, and @var{r} are
+defined as follows.
+
+ at table @var
+ at item beta
+The GLS estimator for @math{b}.
+
+ at item v
+The GLS estimator for @math{s^2}.
+
+ at item r
+The matrix of GLS residuals, @math{r = y - x beta}.
+ at end table
+ at end deftypefn
+
+
+ at c ./optimization/lsqnonneg.m
+ at anchor{doc-lsqnonneg}
+ at deftypefn {Function File} {@var{x} =} lsqnonneg (@var{c}, @var{d})
+ at deftypefnx {Function File} {@var{x} =} lsqnonneg (@var{c}, @var{d}, @var{x0})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}, @var{output}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}, @var{output}, @var{lambda}] =} lsqnonneg (@dots{})
+Minimize @code{norm (@var{c}*@var{x}-d)} subject to @code{@var{x} >=
+0}.  @var{c} and @var{d} must be real.  @var{x0} is an optional
+initial guess for @var{x}.
+
+Outputs:
+ at itemize @bullet
+ at item resnorm
+
+The squared 2-norm of the residual: norm(@var{c}*@var{x}- at var{d})^2
+ at item residual
+
+The residual: @var{d}- at var{c}*@var{x}
+ at item exitflag
+
+An indicator of convergence.  0 indicates that the iteration count
+was exceeded, and therefore convergence was not reached; >0 indicates
+that the algorithm converged.  (The algorithm is stable and will
+converge given enough iterations.)
+ at item output
+
+A structure with two fields:
+ at itemize @bullet
+ at item "algorithm": The algorithm used ("nnls")
+ at item "iterations": The number of iterations taken.
+ at end itemize
+ at item lambda
+
+Not implemented.
+ at end itemize
+ at seealso{@ref{doc-optimset,,optimset}}
+ at end deftypefn
+
+
+ at c ./optimization/optimset.m
+ at anchor{doc-optimset}
+ at deftypefn {Function File} {} optimset ()
+ at deftypefnx {Function File} {} optimset (@var{par}, @var{val}, @dots{})
+ at deftypefnx {Function File} {} optimset (@var{old}, @var{par}, @var{val}, @dots{})
+ at deftypefnx {Function File} {} optimset (@var{old}, @var{new})
+Create options struct for optimization functions.
+ at end deftypefn
+
+
+ at c ./optimization/optimget.m
+ at anchor{doc-optimget}
+ at deftypefn {Function File} {} optimget (@var{options}, @var{parname})
+ at deftypefnx {Function File} {} optimget (@var{options}, @var{parname}, @var{default})
+Return a specific option from a structure created by 
+ at code{optimset}.  If @var{parname} is not a field of the @var{options}
+structure, return @var{default} if supplied, otherwise return an 
+empty matrix.
+ at end deftypefn
+
diff --git a/doc/interpreter/optim.txi b/doc/interpreter/optim.txi
new file mode 100644
index 0000000..9b27942
--- /dev/null
+++ b/doc/interpreter/optim.txi
@@ -0,0 +1,136 @@
+ at c Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Optimization
+ at chapter Optimization
+
+Octave comes with support for solving various kinds of optimization
+problems.  Specifically Octave can solve problems in Linear Programming,
+Quadratic Programming, Nonlinear Programming, and Linear Least Squares
+Minimization.
+
+ at menu
+* Linear Programming::       
+* Quadratic Programming::       
+* Nonlinear Programming::       
+* Linear Least Squares::        
+ at end menu
+
+ at c @cindex linear programming
+ at cindex quadratic programming
+ at cindex nonlinear programming
+ at cindex optimization
+ at cindex LP
+ at cindex QP
+ at cindex NLP
+
+ at node Linear Programming
+ at section Linear Programming
+
+Octave can solve Linear Programming problems using the @code{glpk}
+function.  That is, Octave can solve
+
+ at tex
+$$
+  \min_x c^T x
+$$
+ at end tex
+ at ifnottex
+ at example
+min C'*x
+ at end example
+ at end ifnottex
+subject to the linear constraints
+ at tex
+$Ax = b$ where $x \geq 0$.
+ at end tex
+ at ifnottex
+ at math{A*x = b} where @math{x >= 0}.
+ at end ifnottex
+
+ at noindent
+The @code{glpk} function also supports variations of this problem.
+
+ at DOCSTRING(glpk)
+
+ at node Quadratic Programming
+ at section Quadratic Programming
+
+Octave can also solve Quadratic Programming problems, this is
+ at tex
+$$
+ \min_x {1 \over 2} x^T H x + x^T q
+$$
+ at end tex
+ at ifnottex
+ at example
+min 0.5 x'*H*x + x'*q
+ at end example
+ at end ifnottex
+subject to
+ at tex
+$$
+ Ax = b \qquad lb \leq x \leq ub \qquad A_{lb} \leq A_{in} \leq A_{ub}
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+     A*x = b
+     lb <= x <= ub
+     A_lb <= A_in*x <= A_ub
+ at end group
+ at end example
+ at end ifnottex
+
+ at DOCSTRING(qp)
+
+ at node Nonlinear Programming
+ at section Nonlinear Programming
+
+Octave can also perform general nonlinear minimization using a
+successive quadratic programming solver.
+
+ at DOCSTRING(sqp)
+
+ at node Linear Least Squares
+ at section Linear Least Squares
+
+Octave also supports linear least squares minimization.  That is,
+Octave can find the parameter @math{b} such that the model
+ at tex
+$y = xb$
+ at end tex
+ at ifnottex
+ at math{y = x*b}
+ at end ifnottex
+fits data @math{(x,y)} as well as possible, assuming zero-mean
+Gaussian noise.  If the noise is assumed to be isotropic the problem
+can be solved using the @samp{\} or @samp{/} operators, or the @code{ols}
+function.  In the general case where the noise is assumed to be anisotropic
+the @code{gls} is needed.
+
+ at DOCSTRING(ols)
+
+ at DOCSTRING(gls)
+
+ at DOCSTRING(lsqnonneg)
+
+ at DOCSTRING(optimset)
+
+ at DOCSTRING(optimget)
diff --git a/doc/interpreter/package.texi b/doc/interpreter/package.texi
new file mode 100644
index 0000000..23265fc
--- /dev/null
+++ b/doc/interpreter/package.texi
@@ -0,0 +1,730 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2007, 2008, 2009 S�ren Hauberg
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Packages
+ at chapter Packages
+
+Since Octave is Free Software users are encouraged to share their
+programs amongst each other.  To aid this sharing Octave supports the
+installation of extra packages.  The `Octave-Forge' project is a
+community-maintained set of packages that can be downloaded and
+installed in Octave.  At the time of writing the `Octave-Forge' project
+can be found on-line at @uref{http://octave.sourceforge.net}, but
+since the Internet is an ever-changing place this may not be true at
+the time of reading.  Therefore it is recommended to see the Octave
+website for an updated reference.
+
+ at menu
+* Installing and Removing Packages::  
+* Using Packages::              
+* Administrating Packages::     
+* Creating Packages::           
+ at end menu
+
+ at findex pkg
+ at node Installing and Removing Packages
+ at section Installing and Removing Packages
+
+Assuming a package is available in the file @file{image-1.0.0.tar.gz}
+it can be installed from the Octave prompt with the command
+
+ at example
+pkg install image-1.0.0.tar.gz
+ at end example
+
+ at noindent
+If the package is installed successfully nothing will be printed on
+the prompt, but if an error occurred during installation it will be
+reported.  It is possible to install several packages at once by
+writing several package files after the @code{pkg install} command.
+If a different version of the package is already installed it will
+be removed prior to installing the new package.  This makes it easy to
+upgrade and downgrade the version of a package, but makes it
+impossible to have several versions of the same package installed at
+once.
+
+To see which packages are installed type
+
+ at example
+ at group
+pkg list
+ at print{} Package Name  | Version | Installation directory
+ at print{} --------------+---------+-----------------------
+ at print{}        image *|   1.0.0 | /home/jwe/octave/image-1.0.0
+ at end group
+ at end example
+
+ at noindent
+In this case only version 1.0.0 of the @code{image} package is
+installed.  The '*' character next to the package name shows that the
+image package is loaded and ready for use.
+
+It is possible to remove a package from the system using the
+ at code{pkg uninstall} command like this
+
+ at example
+pkg uninstall image
+ at end example
+
+ at noindent
+If the package is removed successfully nothing will be printed in the
+prompt, but if an error occurred it will be reported.  It should be
+noted that the package file used for installation is not needed for
+removal, and that only the package name as reported by @code{pkg list}
+should be used when removing a package.  It is possible to remove
+several packages at once by writing several package names after the
+ at code{pkg uninstall} command.
+
+To minimize the amount of code duplication between packages it is
+possible that one package depends on another one.  If a package
+depends on another, it will check if that package is installed
+during installation.  If it is not, an error will be reported and
+the package will not be installed.  This behavior can be disabled
+by passing the @code{-nodeps} flag to the @code{pkg install}
+command
+
+ at example
+pkg install -nodeps my_package_with_dependencies.tar.gz
+ at end example
+
+ at noindent
+Since the installed package expects its dependencies to be installed
+it may not function correctly.  Because of this it is not recommended
+to disable dependency checking.
+
+ at c ./pkg/pkg.m
+ at anchor{doc-pkg}
+ at deftypefn  {Command} pkg @var{command} @var{pkg_name}
+ at deftypefnx {Command} pkg @var{command} @var{option} @var{pkg_name}
+This command interacts with the package manager.  Different actions will
+be taken depending on the value of @var{command}.
+
+ at table @samp
+ at item install
+Install named packages.  For example,
+ at example
+pkg install image-1.0.0.tar.gz
+ at end example
+ at noindent
+installs the package found in the file @file{image-1.0.0.tar.gz}.
+
+The @var{option} variable can contain options that affect the manner
+in which a package is installed.  These options can be one or more of
+
+ at table @code
+ at item -nodeps
+The package manager will disable the dependency checking.  That way it 
+is possible to install a package even if it depends on another package 
+that's not installed on the system.  @strong{Use this option with care.}
+
+ at item -noauto
+The package manager will not automatically load the installed package 
+when starting Octave, even if the package requests that it is.
+
+ at item -auto
+The package manager will automatically load the installed package when 
+starting Octave, even if the package requests that it isn't.
+
+ at item -local
+A local installation is forced, even if the user has system privileges.
+
+ at item -global
+A global installation is forced, even if the user doesn't normally have
+system privileges
+
+ at item -verbose
+The package manager will print the output of all of the commands that are 
+performed.
+ at end table
+
+ at item uninstall
+Uninstall named packages.  For example,
+ at example
+pkg uninstall image
+ at end example
+ at noindent
+removes the @code{image} package from the system.  If another installed
+package depends on the @code{image} package an error will be issued.
+The package can be uninstalled anyway by using the @code{-nodeps} option.
+ at item load
+Add named packages to the path.  After loading a package it is
+possible to use the functions provided by the package.  For example,
+ at example
+pkg load image
+ at end example
+ at noindent
+adds the @code{image} package to the path.  It is possible to load all
+installed packages at once with the command
+ at example
+pkg load all
+ at end example
+ at item unload
+Removes named packages from the path.  After unloading a package it is
+no longer possible to use the functions provided by the package.
+This command behaves like the @code{load} command.
+ at item list
+Show a list of the currently installed packages.  By requesting one or two
+output argument it is possible to get a list of the currently installed
+packages.  For example,
+ at example
+installed_packages = pkg list;
+ at end example
+ at noindent
+returns a cell array containing a structure for each installed package.
+The command
+ at example
+[@var{user_packages}, @var{system_packages}] = pkg list
+ at end example
+ at noindent
+splits the list of installed packages into those who are installed by
+the current user, and those installed by the system administrator.
+ at item describe
+Show a short description of the named installed packages, with the option
+'-verbose' also list functions provided by the package, e.g.:
+ at example
+ pkg describe -verbose all
+ at end example
+ at noindent
+will describe all installed packages and the functions they provide.
+If one output is requested a cell of structure containing the
+description and list of functions of each package is returned as
+output rather than printed on screen:
+ at example
+ desc = pkg ("describe", "secs1d", "image")
+ at end example
+ at noindent
+If any of the requested packages is not installed, pkg returns an
+error, unless a second output is requested:
+ at example
+ [ desc, flag] = pkg ("describe", "secs1d", "image")
+ at end example
+ at noindent
+ at var{flag} will take one of the values "Not installed", "Loaded" or
+"Not loaded" for each of the named packages.
+ at item prefix
+Set the installation prefix directory.  For example,
+ at example
+pkg prefix ~/my_octave_packages
+ at end example
+ at noindent
+sets the installation prefix to @file{~/my_octave_packages}.
+Packages will be installed in this directory.
+
+It is possible to get the current installation prefix by requesting an
+output argument.  For example,
+ at example
+p = pkg prefix
+ at end example
+
+The location in which to install the architecture dependent files can be
+independent specified with an addition argument.  For example
+
+ at example
+pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
+ at end example
+ at item local_list
+Set the file in which to look for information on the locally
+installed packages.  Locally installed packages are those that are
+typically available only to the current user.  For example
+ at example
+pkg local_list ~/.octave_packages
+ at end example
+It is possible to get the current value of local_list with the following
+ at example
+pkg local_list
+ at end example
+ at item global_list
+Set the file in which to look for, for information on the globally
+installed packages.  Globally installed packages are those that are
+typically available to all users.  For example
+ at example
+pkg global_list /usr/share/octave/octave_packages
+ at end example
+It is possible to get the current value of global_list with the following
+ at example
+pkg global_list
+ at end example
+ at item rebuild
+Rebuilds the package database from the installed directories.  This can 
+be used in cases where for some reason the package database is corrupted.
+It can also take the @code{-auto} and @code{-noauto} options to allow the
+autoloading state of a package to be changed.  For example
+
+ at example
+pkg rebuild -noauto image
+ at end example
+
+will remove the autoloading status of the image package.
+ at item build
+Builds a binary form of a package or packages.  The binary file produced
+will itself be an Octave package that can be installed normally with
+ at code{pkg}.  The form of the command to build a binary package is
+
+ at example
+pkg build builddir image-1.0.0.tar.gz @dots{}
+ at end example
+
+ at noindent
+where @code{builddir} is the name of a directory where the temporary
+installation will be produced and the binary packages will be found.
+The options @code{-verbose} and @code{-nodeps} are respected, while 
+the other options are ignored.
+ at end table
+ at end deftypefn
+
+
+ at node Using Packages
+ at section Using Packages
+
+By default installed packages are available from the Octave prompt,
+but it is possible to control this using the @code{pkg load} and 
+ at code{pkg unload} commands.  The functions from a package can be 
+removed from the Octave path by typing
+
+ at example
+pkg unload package_name
+ at end example
+
+ at noindent
+where @code{package_name} is the name of the package to be removed
+from the path.
+
+In much the same way a package can be added to the Octave path by
+typing
+
+ at example
+pkg load package_name
+ at end example
+
+ at node Administrating Packages
+ at section Administrating Packages
+
+On UNIX-like systems it is possible to make both per-user and
+system-wide installations of a package.  If the user performing the
+installation is @code{root} the packages will be installed in a
+system-wide directory that defaults to 
+ at file{OCTAVE_HOME/share/octave/packages/}.  If the user is not 
+ at code{root} the default installation directory is
+ at file{~/octave/}.  Packages will be installed in a subdirectory of the
+installation directory that will be named after the package.  It is
+possible to change the installation directory by using the
+ at code{pkg prefix} command
+
+ at example
+pkg prefix new_installation_directory
+ at end example
+
+ at noindent
+The current installation directory can be retrieved by typing
+
+ at example
+current_installation_directory = pkg prefix
+ at end example
+
+To function properly the package manager needs to keep some
+information about the installed packages.  For per-user packages this
+information is by default stored in the file @file{~/.octave_packages}
+and for system-wide installations it is stored in
+ at file{OCTAVE_HOME/share/octave/octave_packages}.  The path to the
+per-user file can be changed with the @code{pkg local_list} command
+
+ at example
+pkg local_list /path/to/new_file
+ at end example
+
+ at noindent
+For system-wide installations this can be changed in the same way
+using the @code{pkg global_list} command.  If these commands are
+called without a new path, the current path will be returned.
+
+ at node Creating Packages
+ at section Creating Packages
+
+Internally a package is simply a gzipped tar file that contains a
+top level directory of any given name.  This directory will in the
+following be referred to as @code{package} and may contain the
+following files
+
+ at noindent
+ at table @code
+ at item package/DESCRIPTION
+This is a required file containing information about the package.
+ at xref{The DESCRIPTION File}, for details on this file.
+
+ at item package/COPYING
+This is a required file containing the license of the package.  No
+restrictions is made on the license in general.  If however the
+package contains dynamically linked functions the license must be
+compatible with the GNU General Public License.
+
+ at item package/INDEX
+This is an optional file describing the functions provided by the
+package.  If this file is not given then one with be created
+automatically from the functions in the package and the
+ at code{Categories} keyword in the @code{DESCRIPTION} file.
+ at xref{The INDEX file}, for details on this file.
+
+ at anchor{doc-PKG_ADD}
+ at item package/PKG_ADD
+An optional file that includes commands that are run when the package
+is added to the users path.  Note that @w{@code{PKG_ADD}} directives in the
+source code of the package will also be added to this file by the
+Octave package manager.  Note that symbolic links are to be avoided in
+packages, as symbolic links do not exist on some file systems, and so
+a typical use for this file is the replacement of the symbolic link
+
+ at example
+ln -s foo.oct bar.oct
+ at end example
+
+ at noindent
+with an autoload directive like
+
+ at example
+autoload ('bar', which ('foo'));
+ at end example
+
+ at noindent
+ at xref{PKG_ADD and PKG_DEL directives}, for details on @w{@code{PKG_ADD}}
+directives.
+
+ at item package/PKG_DEL
+An optional file that includes commands that are run when the package
+is removed from the users path.  Note that @w{@code{PKG_DEL}} directives in
+the source code of the package will also be added to this file by the
+Octave package manager. 
+ at xref{PKG_ADD and PKG_DEL directives}, for details on @w{@code{PKG_DEL}}
+directives.
+
+ at item package/pre_install.m
+This is an optional script that is run prior to the installation of a
+package. 
+
+ at item package/post_install.m
+This is an optional script that is run after the installation of a
+package. 
+
+ at item package/on_uninstall.m
+This is an optional script that is run prior to the removal of a
+package. 
+ at end table
+
+Besides the above mentioned files, a package can also contain on or
+more of the following directories
+
+ at noindent
+ at table @code
+ at item package/inst
+An optional directory containing any files that are directly installed
+by the package.  Typically this will include any @code{m}-files. 
+
+ at item package/src
+An optional directory containing code that must be built prior to the
+packages installation.  The Octave package manager will execute
+ at file{./configure} in this directory if this script exists, and will
+then call @code{make} if a file @file{Makefile} exists in this
+directory.  @code{make install} will however not be called.  If a file
+called @code{FILES} exists all files listed there will be copied to the
+ at code{inst} directory, so they also will be installed.  If the
+ at code{FILES} file doesn't exist, @file{src/*.m} and @file{src/*.oct}
+will be copied to the @code{inst} directory.
+
+ at item package/doc
+An optional directory containing documentation for the package.  The
+files in this directory will be directly installed in a sub-directory
+of the installed package for future reference.
+
+ at item package/bin
+An optional directory containing files that will be added to the
+Octave @w{@code{EXEC_PATH}} when the package is loaded.  This might contain
+external scripts, etc., called by functions within the package.
+ at end table
+
+ at menu
+* The DESCRIPTION File::        
+* The INDEX file::              
+* PKG_ADD and PKG_DEL directives::  
+ at end menu
+
+ at node The DESCRIPTION File
+ at subsection The DESCRIPTION File
+
+The @code{DESCRIPTION} file contains various information about the
+package, such as its name, author, and version.  This file has a very
+simple format
+
+ at noindent
+ at itemize
+ at item
+Lines starting with @samp{#} are comments.
+
+ at item
+Lines starting with a blank character are continuations from the 
+previous line.
+
+ at item
+Everything else is of the form @code{NameOfOption: ValueOfOption}.
+ at end itemize
+
+ at noindent
+The following is a simple example of a @code{DESCRIPTION} file
+
+ at example
+ at group
+Name: The name of my package
+Version: 1.0.0
+Date: 2007-18-04
+Author: The name (and possibly email) of the package author.
+Maintainer: The name (and possibly email) of the current
+ package maintainer.
+Title: The title of the package
+Description: A short description of the package.  If this
+ description gets too long for one line it can continue
+ on the next by adding a space to the beginning of the
+ following lines.
+License: GPL version 3 or later
+ at end group
+ at end example
+
+The package manager currently recognizes the following keywords
+
+ at noindent
+ at table @code
+ at item Name
+Name of the package.
+
+ at item Version
+Version of the package.
+
+ at item Date
+Date of last update.
+
+ at item Author
+Original author of the package.
+
+ at item Maintainer
+Maintainer of the package.
+
+ at item Title
+A one line description of the package.
+
+ at item Description
+A one paragraph description of the package.
+
+ at item Categories
+Optional keyword describing the package (if no @code{INDEX} file is
+given this is mandatory).
+
+ at item Problems
+Optional list of known problems.
+
+ at item Url
+Optional list of homepages related to the package.
+
+ at item Autoload
+Optional field that sets the default loading behavior for the package.
+If set to @code{yes}, @code{true} or @code{on}, then Octave will
+automatically load the package when starting.  Otherwise the package
+must be manually loaded with the pkg load command.  This default
+behavior can be overridden when the package is installed.
+
+ at item Depends
+A list of other Octave packages that this package depends on.  This can
+include dependencies on particular versions, with a format
+
+ at example
+Depends: package (>= 1.0.0)
+ at end example
+
+ at noindent
+Possible operators are @code{<}, @code{<=}, @code{==}, @code{>=} or
+ at code{>}.  If the part of the dependency in @code{()} is missing, any
+version of the package is acceptable.  Multiple dependencies can be
+defined either as a comma separated list or on separate @code{Depends}
+lines.
+
+ at item License
+An optional short description of the used license (e.g., GPL version 3
+or newer).  This is optional since the file @code{COPYING} is mandatory.
+
+ at item SystemRequirements
+These are the external install dependencies of the package and are not
+checked by the package manager.  This is here as a hint to the
+distribution packager.  They follow the same conventions as the
+ at code{Depends} keyword.
+
+ at item BuildRequires
+These are the external build dependencies of the package and are not
+checked by the package manager.  This is here as a hint to the
+distribution packager.  They follow the same conventions as the 
+ at code{Depends} keyword.  Note that in general, packaging systems such
+as @code{rpm} or @code{deb} and autoprobe the install dependencies
+from the build dependencies, and therefore the often a
+ at code{BuildRequires} dependency removes the need for a
+ at code{SystemRequirements} dependency.
+
+ at end table
+
+ at noindent
+The developer is free to add additional arguments to the 
+ at code{DESCRIPTION} file for their own purposes.  One further detail to
+aid the packager is that the @code{SystemRequirements} and
+ at code{BuildRequires} keywords can have a distribution dependent section,
+and the automatic build process will use these.  An example of the
+format of this is
+
+ at example
+BuildRequires: libtermcap-devel [Mandriva] libtermcap2-devel
+ at end example
+
+ at noindent
+where the first package name will be used as a default and if the
+RPMs are built on a Mandriva distribution, then the second package
+name will be used instead. 
+
+ at node The INDEX file
+ at subsection The INDEX file
+
+The optional @code{INDEX} file provides a categorical view of the
+functions in the package.  This file has a very simple format
+
+ at noindent
+ at itemize
+ at item Lines beginning with @samp{#} are comments.
+
+ at item The first non-comment line should look like this
+
+ at example
+toolbox >> Toolbox name
+ at end example
+
+ at item Lines beginning with an alphabetical character indicates a new
+category of functions.
+
+ at item Lines starting with a white space character indicate that the
+function names on the line belong to the last mentioned category.
+ at end itemize
+
+ at noindent
+The format can be summarized with the following example
+
+ at example
+ at group
+# A comment
+toolbox >> Toolbox name
+Category Name 1
+ function1 function2 function3
+ function4
+Category Name 2
+ function2 function5
+ at end group
+ at end example
+
+If you wish to refer to a function that users might expect
+to find in your package but is not there, providing a work around or 
+pointing out that the function is available elsewhere, you can use:
+
+ at example
+fn = workaround description
+ at end example
+
+ at noindent
+This workaround description will not appear when listing functions in the 
+package with @code{pkg describe} but they will be published
+in the html documentation online.
+Workaround descriptions can use any html markup, but
+keep in mind that it will be enclosed in a bold-italic environment.  
+For the special case of:
+
+ at example
+fn = use <code>alternate expression</code>
+ at end example
+
+ at noindent
+the bold-italic is automatically suppressed.  You will need
+to use @code{<code>} even in references:
+
+ at example
+fn = use <a href="someothersite.html"><code>fn</code></a>
+ at end example
+
+ at noindent
+Sometimes functions are only partially compatible, in which
+case you can list the non-compatible cases separately.  To
+refer to another function in the package, use @code{<f>fn</f>}.
+For example,
+
+ at example
+eig (a, b) = use <f>qz</f>
+ at end example
+
+ at noindent
+Since sites may have many missing functions, you can define
+a macro rather than typing the same link over and again.
+
+ at example
+$id = expansion
+ at end example
+
+ at noindent
+defines the macro id.  You can use @code{$id} anywhere in the
+description and it will be expanded.  For example,
+
+ at example
+ at group
+$TSA = see <a href="link_to_spctools">SPC Tools</a>
+arcov = $TSA <code>armcv</code>
+ at end group
+ at end example
+
+ at noindent
+id is any string of letters, numbers and @code{_}.
+
+ at node PKG_ADD and PKG_DEL directives
+ at subsection PKG_ADD and PKG_DEL directives
+
+If the package contains files called @w{@code{PKG_ADD}} or @w{@code{PKG_DEL}}
+the commands in these files will be executed when the package is
+added or removed from the users path.  In some situations such files
+are a bit cumbersome to maintain, so the package manager supports
+automatic creation of such files.  If a source file in the package
+contains a @w{@code{PKG_ADD}} or @w{@code{PKG_DEL}} directive they will be
+added to either the @w{@code{PKG_ADD}} or @w{@code{PKG_DEL}} files.
+
+In @code{m}-files a @w{@code{PKG_ADD}} directive looks like this
+
+ at example
+## PKG_ADD: some_octave_command
+ at end example
+
+ at noindent
+Such lines should be added before the @code{function} keyword.
+In C++ files a @w{@code{PKG_ADD}} directive looks like this
+
+ at example
+// PKG_ADD: some_octave_command
+ at end example
+
+ at noindent
+In both cases @code{some_octave_command} should be replaced by the
+command that should be placed in the @w{@code{PKG_ADD}} file.
+ at w{@code{PKG_DEL}} directives work in the same way, except the @w{@code{PKG_ADD}}
+keyword is replaced with @w{@code{PKG_DEL}} and the commands get added
+to the @w{@code{PKG_DEL}} file.
diff --git a/doc/interpreter/package.txi b/doc/interpreter/package.txi
new file mode 100644
index 0000000..dc70c8b
--- /dev/null
+++ b/doc/interpreter/package.txi
@@ -0,0 +1,549 @@
+ at c Copyright (C) 2007, 2008, 2009 S�ren Hauberg
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Packages
+ at chapter Packages
+
+Since Octave is Free Software users are encouraged to share their
+programs amongst each other.  To aid this sharing Octave supports the
+installation of extra packages.  The `Octave-Forge' project is a
+community-maintained set of packages that can be downloaded and
+installed in Octave.  At the time of writing the `Octave-Forge' project
+can be found on-line at @uref{http://octave.sourceforge.net}, but
+since the Internet is an ever-changing place this may not be true at
+the time of reading.  Therefore it is recommended to see the Octave
+website for an updated reference.
+
+ at menu
+* Installing and Removing Packages::  
+* Using Packages::              
+* Administrating Packages::     
+* Creating Packages::           
+ at end menu
+
+ at findex pkg
+ at node Installing and Removing Packages
+ at section Installing and Removing Packages
+
+Assuming a package is available in the file @file{image-1.0.0.tar.gz}
+it can be installed from the Octave prompt with the command
+
+ at example
+pkg install image-1.0.0.tar.gz
+ at end example
+
+ at noindent
+If the package is installed successfully nothing will be printed on
+the prompt, but if an error occurred during installation it will be
+reported.  It is possible to install several packages at once by
+writing several package files after the @code{pkg install} command.
+If a different version of the package is already installed it will
+be removed prior to installing the new package.  This makes it easy to
+upgrade and downgrade the version of a package, but makes it
+impossible to have several versions of the same package installed at
+once.
+
+To see which packages are installed type
+
+ at example
+ at group
+pkg list
+ at print{} Package Name  | Version | Installation directory
+ at print{} --------------+---------+-----------------------
+ at print{}        image *|   1.0.0 | /home/jwe/octave/image-1.0.0
+ at end group
+ at end example
+
+ at noindent
+In this case only version 1.0.0 of the @code{image} package is
+installed.  The '*' character next to the package name shows that the
+image package is loaded and ready for use.
+
+It is possible to remove a package from the system using the
+ at code{pkg uninstall} command like this
+
+ at example
+pkg uninstall image
+ at end example
+
+ at noindent
+If the package is removed successfully nothing will be printed in the
+prompt, but if an error occurred it will be reported.  It should be
+noted that the package file used for installation is not needed for
+removal, and that only the package name as reported by @code{pkg list}
+should be used when removing a package.  It is possible to remove
+several packages at once by writing several package names after the
+ at code{pkg uninstall} command.
+
+To minimize the amount of code duplication between packages it is
+possible that one package depends on another one.  If a package
+depends on another, it will check if that package is installed
+during installation.  If it is not, an error will be reported and
+the package will not be installed.  This behavior can be disabled
+by passing the @code{-nodeps} flag to the @code{pkg install}
+command
+
+ at example
+pkg install -nodeps my_package_with_dependencies.tar.gz
+ at end example
+
+ at noindent
+Since the installed package expects its dependencies to be installed
+it may not function correctly.  Because of this it is not recommended
+to disable dependency checking.
+
+ at DOCSTRING(pkg)
+
+ at node Using Packages
+ at section Using Packages
+
+By default installed packages are available from the Octave prompt,
+but it is possible to control this using the @code{pkg load} and 
+ at code{pkg unload} commands.  The functions from a package can be 
+removed from the Octave path by typing
+
+ at example
+pkg unload package_name
+ at end example
+
+ at noindent
+where @code{package_name} is the name of the package to be removed
+from the path.
+
+In much the same way a package can be added to the Octave path by
+typing
+
+ at example
+pkg load package_name
+ at end example
+
+ at node Administrating Packages
+ at section Administrating Packages
+
+On UNIX-like systems it is possible to make both per-user and
+system-wide installations of a package.  If the user performing the
+installation is @code{root} the packages will be installed in a
+system-wide directory that defaults to 
+ at file{OCTAVE_HOME/share/octave/packages/}.  If the user is not 
+ at code{root} the default installation directory is
+ at file{~/octave/}.  Packages will be installed in a subdirectory of the
+installation directory that will be named after the package.  It is
+possible to change the installation directory by using the
+ at code{pkg prefix} command
+
+ at example
+pkg prefix new_installation_directory
+ at end example
+
+ at noindent
+The current installation directory can be retrieved by typing
+
+ at example
+current_installation_directory = pkg prefix
+ at end example
+
+To function properly the package manager needs to keep some
+information about the installed packages.  For per-user packages this
+information is by default stored in the file @file{~/.octave_packages}
+and for system-wide installations it is stored in
+ at file{OCTAVE_HOME/share/octave/octave_packages}.  The path to the
+per-user file can be changed with the @code{pkg local_list} command
+
+ at example
+pkg local_list /path/to/new_file
+ at end example
+
+ at noindent
+For system-wide installations this can be changed in the same way
+using the @code{pkg global_list} command.  If these commands are
+called without a new path, the current path will be returned.
+
+ at node Creating Packages
+ at section Creating Packages
+
+Internally a package is simply a gzipped tar file that contains a
+top level directory of any given name.  This directory will in the
+following be referred to as @code{package} and may contain the
+following files
+
+ at noindent
+ at table @code
+ at item package/DESCRIPTION
+This is a required file containing information about the package.
+ at xref{The DESCRIPTION File}, for details on this file.
+
+ at item package/COPYING
+This is a required file containing the license of the package.  No
+restrictions is made on the license in general.  If however the
+package contains dynamically linked functions the license must be
+compatible with the GNU General Public License.
+
+ at item package/INDEX
+This is an optional file describing the functions provided by the
+package.  If this file is not given then one with be created
+automatically from the functions in the package and the
+ at code{Categories} keyword in the @code{DESCRIPTION} file.
+ at xref{The INDEX file}, for details on this file.
+
+ at anchor{doc-PKG_ADD}
+ at item package/PKG_ADD
+An optional file that includes commands that are run when the package
+is added to the users path.  Note that @w{@code{PKG_ADD}} directives in the
+source code of the package will also be added to this file by the
+Octave package manager.  Note that symbolic links are to be avoided in
+packages, as symbolic links do not exist on some file systems, and so
+a typical use for this file is the replacement of the symbolic link
+
+ at example
+ln -s foo.oct bar.oct
+ at end example
+
+ at noindent
+with an autoload directive like
+
+ at example
+autoload ('bar', which ('foo'));
+ at end example
+
+ at noindent
+ at xref{PKG_ADD and PKG_DEL directives}, for details on @w{@code{PKG_ADD}}
+directives.
+
+ at item package/PKG_DEL
+An optional file that includes commands that are run when the package
+is removed from the users path.  Note that @w{@code{PKG_DEL}} directives in
+the source code of the package will also be added to this file by the
+Octave package manager. 
+ at xref{PKG_ADD and PKG_DEL directives}, for details on @w{@code{PKG_DEL}}
+directives.
+
+ at item package/pre_install.m
+This is an optional script that is run prior to the installation of a
+package. 
+
+ at item package/post_install.m
+This is an optional script that is run after the installation of a
+package. 
+
+ at item package/on_uninstall.m
+This is an optional script that is run prior to the removal of a
+package. 
+ at end table
+
+Besides the above mentioned files, a package can also contain on or
+more of the following directories
+
+ at noindent
+ at table @code
+ at item package/inst
+An optional directory containing any files that are directly installed
+by the package.  Typically this will include any @code{m}-files. 
+
+ at item package/src
+An optional directory containing code that must be built prior to the
+packages installation.  The Octave package manager will execute
+ at file{./configure} in this directory if this script exists, and will
+then call @code{make} if a file @file{Makefile} exists in this
+directory.  @code{make install} will however not be called.  If a file
+called @code{FILES} exists all files listed there will be copied to the
+ at code{inst} directory, so they also will be installed.  If the
+ at code{FILES} file doesn't exist, @file{src/*.m} and @file{src/*.oct}
+will be copied to the @code{inst} directory.
+
+ at item package/doc
+An optional directory containing documentation for the package.  The
+files in this directory will be directly installed in a sub-directory
+of the installed package for future reference.
+
+ at item package/bin
+An optional directory containing files that will be added to the
+Octave @w{@code{EXEC_PATH}} when the package is loaded.  This might contain
+external scripts, etc., called by functions within the package.
+ at end table
+
+ at menu
+* The DESCRIPTION File::        
+* The INDEX file::              
+* PKG_ADD and PKG_DEL directives::  
+ at end menu
+
+ at node The DESCRIPTION File
+ at subsection The DESCRIPTION File
+
+The @code{DESCRIPTION} file contains various information about the
+package, such as its name, author, and version.  This file has a very
+simple format
+
+ at noindent
+ at itemize
+ at item
+Lines starting with @samp{#} are comments.
+
+ at item
+Lines starting with a blank character are continuations from the 
+previous line.
+
+ at item
+Everything else is of the form @code{NameOfOption: ValueOfOption}.
+ at end itemize
+
+ at noindent
+The following is a simple example of a @code{DESCRIPTION} file
+
+ at example
+ at group
+Name: The name of my package
+Version: 1.0.0
+Date: 2007-18-04
+Author: The name (and possibly email) of the package author.
+Maintainer: The name (and possibly email) of the current
+ package maintainer.
+Title: The title of the package
+Description: A short description of the package.  If this
+ description gets too long for one line it can continue
+ on the next by adding a space to the beginning of the
+ following lines.
+License: GPL version 3 or later
+ at end group
+ at end example
+
+The package manager currently recognizes the following keywords
+
+ at noindent
+ at table @code
+ at item Name
+Name of the package.
+
+ at item Version
+Version of the package.
+
+ at item Date
+Date of last update.
+
+ at item Author
+Original author of the package.
+
+ at item Maintainer
+Maintainer of the package.
+
+ at item Title
+A one line description of the package.
+
+ at item Description
+A one paragraph description of the package.
+
+ at item Categories
+Optional keyword describing the package (if no @code{INDEX} file is
+given this is mandatory).
+
+ at item Problems
+Optional list of known problems.
+
+ at item Url
+Optional list of homepages related to the package.
+
+ at item Autoload
+Optional field that sets the default loading behavior for the package.
+If set to @code{yes}, @code{true} or @code{on}, then Octave will
+automatically load the package when starting.  Otherwise the package
+must be manually loaded with the pkg load command.  This default
+behavior can be overridden when the package is installed.
+
+ at item Depends
+A list of other Octave packages that this package depends on.  This can
+include dependencies on particular versions, with a format
+
+ at example
+Depends: package (>= 1.0.0)
+ at end example
+
+ at noindent
+Possible operators are @code{<}, @code{<=}, @code{==}, @code{>=} or
+ at code{>}.  If the part of the dependency in @code{()} is missing, any
+version of the package is acceptable.  Multiple dependencies can be
+defined either as a comma separated list or on separate @code{Depends}
+lines.
+
+ at item License
+An optional short description of the used license (e.g., GPL version 3
+or newer).  This is optional since the file @code{COPYING} is mandatory.
+
+ at item SystemRequirements
+These are the external install dependencies of the package and are not
+checked by the package manager.  This is here as a hint to the
+distribution packager.  They follow the same conventions as the
+ at code{Depends} keyword.
+
+ at item BuildRequires
+These are the external build dependencies of the package and are not
+checked by the package manager.  This is here as a hint to the
+distribution packager.  They follow the same conventions as the 
+ at code{Depends} keyword.  Note that in general, packaging systems such
+as @code{rpm} or @code{deb} and autoprobe the install dependencies
+from the build dependencies, and therefore the often a
+ at code{BuildRequires} dependency removes the need for a
+ at code{SystemRequirements} dependency.
+
+ at end table
+
+ at noindent
+The developer is free to add additional arguments to the 
+ at code{DESCRIPTION} file for their own purposes.  One further detail to
+aid the packager is that the @code{SystemRequirements} and
+ at code{BuildRequires} keywords can have a distribution dependent section,
+and the automatic build process will use these.  An example of the
+format of this is
+
+ at example
+BuildRequires: libtermcap-devel [Mandriva] libtermcap2-devel
+ at end example
+
+ at noindent
+where the first package name will be used as a default and if the
+RPMs are built on a Mandriva distribution, then the second package
+name will be used instead. 
+
+ at node The INDEX file
+ at subsection The INDEX file
+
+The optional @code{INDEX} file provides a categorical view of the
+functions in the package.  This file has a very simple format
+
+ at noindent
+ at itemize
+ at item Lines beginning with @samp{#} are comments.
+
+ at item The first non-comment line should look like this
+
+ at example
+toolbox >> Toolbox name
+ at end example
+
+ at item Lines beginning with an alphabetical character indicates a new
+category of functions.
+
+ at item Lines starting with a white space character indicate that the
+function names on the line belong to the last mentioned category.
+ at end itemize
+
+ at noindent
+The format can be summarized with the following example
+
+ at example
+ at group
+# A comment
+toolbox >> Toolbox name
+Category Name 1
+ function1 function2 function3
+ function4
+Category Name 2
+ function2 function5
+ at end group
+ at end example
+
+If you wish to refer to a function that users might expect
+to find in your package but is not there, providing a work around or 
+pointing out that the function is available elsewhere, you can use:
+
+ at example
+fn = workaround description
+ at end example
+
+ at noindent
+This workaround description will not appear when listing functions in the 
+package with @code{pkg describe} but they will be published
+in the html documentation online.
+Workaround descriptions can use any html markup, but
+keep in mind that it will be enclosed in a bold-italic environment.  
+For the special case of:
+
+ at example
+fn = use <code>alternate expression</code>
+ at end example
+
+ at noindent
+the bold-italic is automatically suppressed.  You will need
+to use @code{<code>} even in references:
+
+ at example
+fn = use <a href="someothersite.html"><code>fn</code></a>
+ at end example
+
+ at noindent
+Sometimes functions are only partially compatible, in which
+case you can list the non-compatible cases separately.  To
+refer to another function in the package, use @code{<f>fn</f>}.
+For example,
+
+ at example
+eig (a, b) = use <f>qz</f>
+ at end example
+
+ at noindent
+Since sites may have many missing functions, you can define
+a macro rather than typing the same link over and again.
+
+ at example
+$id = expansion
+ at end example
+
+ at noindent
+defines the macro id.  You can use @code{$id} anywhere in the
+description and it will be expanded.  For example,
+
+ at example
+ at group
+$TSA = see <a href="link_to_spctools">SPC Tools</a>
+arcov = $TSA <code>armcv</code>
+ at end group
+ at end example
+
+ at noindent
+id is any string of letters, numbers and @code{_}.
+
+ at node PKG_ADD and PKG_DEL directives
+ at subsection PKG_ADD and PKG_DEL directives
+
+If the package contains files called @w{@code{PKG_ADD}} or @w{@code{PKG_DEL}}
+the commands in these files will be executed when the package is
+added or removed from the users path.  In some situations such files
+are a bit cumbersome to maintain, so the package manager supports
+automatic creation of such files.  If a source file in the package
+contains a @w{@code{PKG_ADD}} or @w{@code{PKG_DEL}} directive they will be
+added to either the @w{@code{PKG_ADD}} or @w{@code{PKG_DEL}} files.
+
+In @code{m}-files a @w{@code{PKG_ADD}} directive looks like this
+
+ at example
+## PKG_ADD: some_octave_command
+ at end example
+
+ at noindent
+Such lines should be added before the @code{function} keyword.
+In C++ files a @w{@code{PKG_ADD}} directive looks like this
+
+ at example
+// PKG_ADD: some_octave_command
+ at end example
+
+ at noindent
+In both cases @code{some_octave_command} should be replaced by the
+command that should be placed in the @w{@code{PKG_ADD}} file.
+ at w{@code{PKG_DEL}} directives work in the same way, except the @w{@code{PKG_ADD}}
+keyword is replaced with @w{@code{PKG_DEL}} and the commands get added
+to the @w{@code{PKG_DEL}} file.
diff --git a/doc/interpreter/plot.eps b/doc/interpreter/plot.eps
new file mode 100644
index 0000000..6d17ce0
--- /dev/null
+++ b/doc/interpreter/plot.eps
@@ -0,0 +1,880 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: plot.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:55 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (plot.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:55 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+913 532 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 532 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 1557 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 1557 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 2582 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 2582 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 3607 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 3607 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 4632 M
+88 0 V
+5486 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 829 4632 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+913 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 913 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2307 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 2307 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3700 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3700 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5094 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5094 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6487 532 M
+0 88 V
+0 4012 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6487 392 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 913 3697 M
+28 -177 V
+28 -187 V
+28 -194 V
+27 -200 V
+28 -203 V
+28 -205 V
+28 -204 V
+28 -202 V
+28 -197 V
+28 -191 V
+28 -182 V
+27 -172 V
+28 -160 V
+28 -147 V
+28 -131 V
+28 -115 V
+28 -97 V
+28 -79 V
+28 -60 V
+27 -40 V
+28 -20 V
+28 1 V
+28 21 V
+28 42 V
+28 61 V
+28 81 V
+27 99 V
+28 116 V
+28 133 V
+28 147 V
+28 161 V
+28 173 V
+28 183 V
+28 191 V
+27 198 V
+28 202 V
+28 205 V
+28 204 V
+28 203 V
+28 200 V
+28 193 V
+28 186 V
+27 177 V
+28 165 V
+28 152 V
+28 138 V
+28 122 V
+28 105 V
+28 87 V
+28 68 V
+27 48 V
+28 28 V
+28 8 V
+28 -13 V
+28 -33 V
+28 -53 V
+28 -73 V
+27 -91 V
+28 -110 V
+28 -126 V
+28 -141 V
+28 -156 V
+28 -168 V
+28 -179 V
+28 -188 V
+27 -195 V
+28 -201 V
+28 -203 V
+28 -205 V
+28 -204 V
+28 -201 V
+28 -197 V
+28 -189 V
+27 -181 V
+28 -170 V
+28 -158 V
+28 -144 V
+28 -128 V
+28 -113 V
+28 -94 V
+27 -76 V
+28 -56 V
+28 -37 V
+28 -16 V
+28 4 V
+28 25 V
+28 45 V
+28 64 V
+27 84 V
+28 102 V
+28 119 V
+28 135 V
+28 150 V
+28 163 V
+28 175 V
+28 185 V
+27 192 V
+28 199 V
+28 202 V
+28 205 V
+28 205 V
+28 202 V
+28 199 V
+27 192 V
+stroke 3811 3380 M
+28 185 V
+28 175 V
+28 163 V
+28 150 V
+28 135 V
+28 119 V
+28 102 V
+27 84 V
+28 64 V
+28 45 V
+28 25 V
+28 4 V
+28 -16 V
+28 -37 V
+28 -56 V
+27 -76 V
+28 -94 V
+28 -113 V
+28 -128 V
+28 -144 V
+28 -158 V
+28 -170 V
+27 -181 V
+28 -189 V
+28 -197 V
+28 -201 V
+28 -204 V
+28 -205 V
+28 -203 V
+28 -201 V
+27 -195 V
+28 -188 V
+28 -179 V
+28 -168 V
+28 -156 V
+28 -141 V
+28 -126 V
+28 -110 V
+27 -91 V
+28 -73 V
+28 -53 V
+28 -33 V
+28 -13 V
+28 8 V
+28 28 V
+28 48 V
+27 68 V
+28 87 V
+28 105 V
+28 122 V
+28 138 V
+28 152 V
+28 165 V
+27 177 V
+28 186 V
+28 193 V
+28 200 V
+28 203 V
+28 204 V
+28 205 V
+28 202 V
+27 198 V
+28 191 V
+28 183 V
+28 173 V
+28 161 V
+28 147 V
+28 133 V
+28 116 V
+27 99 V
+28 81 V
+28 61 V
+28 42 V
+28 21 V
+28 1 V
+28 -20 V
+27 -40 V
+28 -60 V
+28 -79 V
+28 -97 V
+28 -115 V
+28 -131 V
+28 -147 V
+28 -160 V
+27 -172 V
+28 -182 V
+28 -191 V
+28 -197 V
+28 -202 V
+28 -204 V
+28 -205 V
+28 -203 V
+27 -200 V
+28 -194 V
+28 -187 V
+28 -177 V
+% End plot #1
+stroke
+LTb
+913 4632 N
+913 532 L
+5574 0 V
+0 4100 V
+-5574 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/plot.pdf b/doc/interpreter/plot.pdf
new file mode 100644
index 0000000..5994841
Binary files /dev/null and b/doc/interpreter/plot.pdf differ
diff --git a/doc/interpreter/plot.png b/doc/interpreter/plot.png
new file mode 100644
index 0000000..635acdd
Binary files /dev/null and b/doc/interpreter/plot.png differ
diff --git a/doc/interpreter/plot.texi b/doc/interpreter/plot.texi
new file mode 100644
index 0000000..80223c9
--- /dev/null
+++ b/doc/interpreter/plot.texi
@@ -0,0 +1,5277 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005,
+ at c               2006, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Plotting
+ at chapter Plotting
+ at cindex plotting
+ at cindex graphics
+
+ at menu
+* Plotting Basics::
+* Advanced Plotting::
+ at end menu
+
+ at node Plotting Basics
+ at section Plotting Basics
+
+Octave makes it easy to create many different types of two- and
+three-dimensional plots using a few high-level functions.
+
+If you need finer control over graphics, see @ref{Advanced Plotting}.
+
+ at menu
+* Two-Dimensional Plots::       
+* Three-Dimensional Plotting::  
+* Plot Annotations::            
+* Multiple Plots on One Page::  
+* Multiple Plot Windows::       
+* Printing Plots::              
+* Interacting with plots::
+* Test Plotting Functions::     
+ at end menu
+
+ at node Two-Dimensional Plots
+ at subsection Two-Dimensional Plots
+
+The @code{plot} function allows you to create simple x-y plots with
+linear axes.  For example,
+
+ at example
+ at group
+x = -10:0.1:10;
+plot (x, sin (x));
+ at end group
+ at end example
+
+ at noindent
+displays a sine wave shown in @ref{fig:plot}.  On most systems, this
+command will open a separate plot window to display the graph.
+
+ at float Figure,fig:plot
+ at center @image{plot,4in}
+ at caption{Simple Two-Dimensional Plot.}
+ at end float
+
+ at c ./plot/plot.m
+ at anchor{doc-plot}
+ at deftypefn {Function File} {} plot (@var{y})
+ at deftypefnx {Function File} {} plot (@var{x}, @var{y})
+ at deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
+ at deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{fmt})
+ at deftypefnx {Function File} {} plot (@var{h}, @dots{})
+Produces two-dimensional plots.  Many different combinations of
+arguments are possible.  The simplest form is
+
+ at example
+plot (@var{y})
+ at end example
+
+ at noindent
+where the argument is taken as the set of @var{y} coordinates and the
+ at var{x} coordinates are taken to be the indices of the elements,
+starting with 1.
+
+To save a plot, in one of several image formats such as PostScript
+or PNG, use the @code{print} command.
+
+If more than one argument is given, they are interpreted as
+
+ at example
+plot (@var{y}, @var{property}, @var{value}, @dots{})
+ at end example
+
+ at noindent
+or
+
+ at example
+plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
+ at end example
+
+ at noindent
+or
+
+ at example
+plot (@var{x}, @var{y}, @var{fmt}, @dots{})
+ at end example
+
+ at noindent
+and so on.  Any number of argument sets may appear.  The @var{x} and
+ at var{y} values are interpreted as follows:
+
+ at itemize @bullet
+ at item
+If a single data argument is supplied, it is taken as the set of @var{y}
+coordinates and the @var{x} coordinates are taken to be the indices of
+the elements, starting with 1.
+
+ at item
+If the @var{x} is a vector and @var{y} is a matrix, then
+the columns (or rows) of @var{y} are plotted versus @var{x}.
+(using whichever combination matches, with columns tried first.)
+
+ at item
+If the @var{x} is a matrix and @var{y} is a vector,
+ at var{y} is plotted versus the columns (or rows) of @var{x}.
+(using whichever combination matches, with columns tried first.)
+
+ at item
+If both arguments are vectors, the elements of @var{y} are plotted versus
+the elements of @var{x}.
+
+ at item
+If both arguments are matrices, the columns of @var{y} are plotted
+versus the columns of @var{x}.  In this case, both matrices must have
+the same number of rows and columns and no attempt is made to transpose
+the arguments to make the number of rows match.
+
+If both arguments are scalars, a single point is plotted.
+ at end itemize
+
+Multiple property-value pairs may be specified, but they must appear
+in pairs.  These arguments are applied to the lines drawn by
+ at code{plot}.
+
+If the @var{fmt} argument is supplied, it is interpreted as
+follows.  If @var{fmt} is missing, the default gnuplot line style
+is assumed.
+
+ at table @samp
+ at item -
+Set lines plot style (default).
+
+ at item .
+Set dots plot style.
+
+ at item @var{n}
+Interpreted as the plot color if @var{n} is an integer in the range 1 to
+6.
+
+ at item @var{nm}
+If @var{nm} is a two digit integer and @var{m} is an integer in the
+range 1 to 6, @var{m} is interpreted as the point style.  This is only
+valid in combination with the @code{@@} or @code{-@@} specifiers.
+
+ at item @var{c}
+If @var{c} is one of @code{"k"} (black), @code{"r"} (red), @code{"g"}
+(green), @code{"b"} (blue), @code{"m"} (magenta), @code{"c"} (cyan),
+or @code{"w"} (white), it is interpreted as the line plot color.
+
+ at item ";title;"
+Here @code{"title"} is the label for the key.
+
+ at item +
+ at itemx *
+ at itemx o
+ at itemx x
+ at itemx ^
+Used in combination with the points or linespoints styles, set the point
+style.
+ at end table
+
+The @var{fmt} argument may also be used to assign key titles.
+To do so, include the desired title between semi-colons after the
+formatting sequence described above, e.g., "+3;Key Title;"
+Note that the last semi-colon is required and will generate an error if
+it is left out.
+
+Here are some plot examples:
+
+ at example
+plot (x, y, "@@12", x, y2, x, y3, "4", x, y4, "+")
+ at end example
+
+This command will plot @code{y} with points of type 2 (displayed as
+ at samp{+}) and color 1 (red), @code{y2} with lines, @code{y3} with lines of
+color 4 (magenta) and @code{y4} with points displayed as @samp{+}.
+
+ at example
+plot (b, "*", "markersize", 3)
+ at end example
+
+This command will plot the data in the variable @code{b},
+with points displayed as @samp{*} with a marker size of 3.
+
+ at example
+ at group
+t = 0:0.1:6.3;
+plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+ at end group
+ at end example
+
+This will plot the cosine and sine functions and label them accordingly
+in the key.
+
+If the first argument is an axis handle, then plot into these axes, 
+rather than the current axis handle returned by @code{gca}. 
+ at seealso{@ref{doc-semilogx,,semilogx}, @ref{doc-semilogy,,semilogy}, @ref{doc-loglog,,loglog}, @ref{doc-polar,,polar}, @ref{doc-mesh,,mesh}, @ref{doc-contour,,contour}, @ref{doc-bar,,bar}, @ref{doc-stairs,,stairs}, @ref{doc-errorbar,,errorbar}, @ref{doc-xlabel,,xlabel}, @ref{doc-ylabel,,ylabel}, @ref{doc-title,,title}, @ref{doc-print,,print}}
+ at end deftypefn
+
+
+The @code{plotyy} function may be used to create a plot with two
+independent y axes.
+
+ at c ./plot/plotyy.m
+ at anchor{doc-plotyy}
+ at deftypefn {Function File} {} plotyy (@var{x1}, @var{y1}, @var{x2}, @var{y2})
+ at deftypefnx {Function File} {} plotyy (@dots{}, @var{fun})
+ at deftypefnx {Function File} {} plotyy (@dots{}, @var{fun1}, @var{fun2})
+ at deftypefnx {Function File} {} plotyy (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{ax}, @var{h1}, @var{h2}] =} plotyy (@dots{})
+Plots two sets of data with independent y-axes.  The arguments @var{x1} and
+ at var{y1} define the arguments for the first plot and @var{x1} and @var{y2}
+for the second. 
+
+By default the arguments are evaluated with 
+ at code{feval (@@plot, @var{x}, @var{y})}.  However the type of plot can be
+modified with the @var{fun} argument, in which case the plots are
+generated by @code{feval (@var{fun}, @var{x}, @var{y})}.  @var{fun} can be 
+a function handle, an inline function or a string of a function name.
+
+The function to use for each of the plots can be independently defined 
+with @var{fun1} and @var{fun2}.
+
+If given, @var{h} defines the principal axis in which to plot the @var{x1}
+and @var{y1} data.  The return value @var{ax} is a two element vector with
+the axis handles of the two plots.  @var{h1} and @var{h2} are handles to
+the objects generated by the plot commands.
+
+ at example
+ at group
+x = 0:0.1:2*pi; 
+y1 = sin (x);
+y2 = exp (x - 1);
+ax = plotyy (x, y1, x - 1, y2, @@plot, @@semilogy);
+xlabel ("X");
+ylabel (ax(1), "Axis 1");
+ylabel (ax(2), "Axis 2");
+ at end group
+ at end example
+ at end deftypefn
+
+
+The functions @code{semilogx}, @code{semilogy}, and @code{loglog} are
+similar to the @code{plot} function, but produce plots in which one or
+both of the axes use log scales.
+
+ at c ./plot/semilogx.m
+ at anchor{doc-semilogx}
+ at deftypefn {Function File} {} semilogx (@var{args})
+Produce a two-dimensional plot using a log scale for the @var{x}
+axis.  See the description of @code{plot} for a description of the
+arguments that @code{semilogx} will accept.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-semilogy,,semilogy}, @ref{doc-loglog,,loglog}}
+ at end deftypefn
+
+
+ at c ./plot/semilogy.m
+ at anchor{doc-semilogy}
+ at deftypefn {Function File} {} semilogy (@var{args})
+Produce a two-dimensional plot using a log scale for the @var{y}
+axis.  See the description of @code{plot} for a description of the
+arguments that @code{semilogy} will accept.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-semilogx,,semilogx}, @ref{doc-loglog,,loglog}}
+ at end deftypefn
+
+
+ at c ./plot/loglog.m
+ at anchor{doc-loglog}
+ at deftypefn {Function File} {} loglog (@var{args})
+Produce a two-dimensional plot using log scales for both axes.  See
+the description of @code{plot} for a description of the arguments
+that @code{loglog} will accept.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-semilogx,,semilogx}, @ref{doc-semilogy,,semilogy}}
+ at end deftypefn
+
+
+The functions @code{bar}, @code{barh}, @code{stairs}, and @code{stem}
+are useful for displaying discrete data.  For example,
+
+ at example
+ at group
+hist (randn (10000, 1), 30);
+ at end group
+ at end example
+
+ at noindent
+produces the histogram of 10,000 normally distributed random numbers
+shown in @ref{fig:hist}.
+
+ at float Figure,fig:hist
+ at center @image{hist,4in}
+ at caption{Histogram.}
+ at end float
+
+ at c ./plot/bar.m
+ at anchor{doc-bar}
+ at deftypefn {Function File} {} bar (@var{x}, @var{y})
+ at deftypefnx {Function File} {} bar (@var{y})
+ at deftypefnx {Function File} {} bar (@var{x}, @var{y}, @var{w})
+ at deftypefnx {Function File} {} bar (@var{x}, @var{y}, @var{w}, @var{style})
+ at deftypefnx {Function File} {@var{h} =} bar (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} bar (@var{h}, @dots{})
+Produce a bar graph from two vectors of x-y data.
+
+If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+The default width of 0.8 for the bars can be changed using @var{w}. 
+
+If @var{y} is a matrix, then each column of @var{y} is taken to be a
+separate bar graph plotted on the same graph.  By default the columns
+are plotted side-by-side.  This behavior can be changed by the @var{style}
+argument, which can take the values @code{"grouped"} (the default),
+or @code{"stacked"}.
+
+The optional return value @var{h} provides a handle to the "bar series"
+object with one handle per column of the variable @var{y}.  This
+series allows common elements of the group of bar series objects to
+be changed in a single bar series and the same properties are changed
+in the other "bar series".  For example
+
+ at example
+ at group
+h = bar (rand (5, 10));
+set (h(1), "basevalue", 0.5);
+ at end group
+ at end example
+
+ at noindent
+changes the position on the base of all of the bar series.
+
+The optional input handle @var{h} allows an axis handle to be passed.
+Properties of the patch graphics object can be changed using
+ at var{prop}, @var{val} pairs.
+
+ at seealso{@ref{doc-barh,,barh}, @ref{doc-plot,,plot}} 
+ at end deftypefn
+
+
+ at c ./plot/barh.m
+ at anchor{doc-barh}
+ at deftypefn {Function File} {} barh (@var{x}, @var{y})
+ at deftypefnx {Function File} {} barh (@var{y})
+ at deftypefnx {Function File} {} barh (@var{x}, @var{y}, @var{w})
+ at deftypefnx {Function File} {} barh (@var{x}, @var{y}, @var{w}, @var{style})
+ at deftypefnx {Function File} {@var{h} =} barh (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} barh (@var{h}, @dots{})
+Produce a horizontal bar graph from two vectors of x-y data.
+
+If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+The default width of 0.8 for the bars can be changed using @var{w}. 
+
+If @var{y} is a matrix, then each column of @var{y} is taken to be a
+separate bar graph plotted on the same graph.  By default the columns
+are plotted side-by-side.  This behavior can be changed by the @var{style}
+argument, which can take the values @code{"grouped"} (the default),
+or @code{"stacked"}.
+
+The optional return value @var{h} provides a handle to the bar series
+object.  See @code{bar} for a description of the use of the bar series.
+
+The optional input handle @var{h} allows an axis handle to be passed.
+Properties of the patch graphics object can be changed using
+ at var{prop}, @var{val} pairs.
+
+ at seealso{@ref{doc-bar,,bar}, @ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/hist.m
+ at anchor{doc-hist}
+ at deftypefn {Function File} {} hist (@var{y}, @var{x}, @var{norm})
+Produce histogram counts or plots.
+
+With one vector input argument, plot a histogram of the values with
+10 bins.  The range of the histogram bins is determined by the range
+of the data.  With one matrix input argument, plot a histogram where
+each bin contains a bar per input column.
+
+Given a second scalar argument, use that as the number of bins.
+
+Given a second vector argument, use that as the centers of the bins,
+with the width of the bins determined from the adjacent values in
+the vector.
+
+If third argument is provided, the histogram is normalized such that
+the sum of the bars is equal to @var{norm}.
+
+Extreme values are lumped in the first and last bins.
+
+With two output arguments, produce the values @var{nn} and @var{xx} such
+that @code{bar (@var{xx}, @var{nn})} will plot the histogram.
+ at seealso{@ref{doc-bar,,bar}}
+ at end deftypefn
+
+
+ at c ./plot/stairs.m
+ at anchor{doc-stairs}
+ at deftypefn {Function File} {} stairs (@var{x}, @var{y})
+ at deftypefnx {Function File} {} stairs (@dots{}, @var{style})
+ at deftypefnx {Function File} {} stairs (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} stairs (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} stairs (@dots{})
+Produce a stairstep plot.  The arguments may be vectors or matrices.
+
+If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+If two output arguments are specified, the data are generated but
+not plotted.  For example,
+
+ at example
+stairs (x, y);
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+[xs, ys] = stairs (x, y);
+plot (xs, ys);
+ at end group
+ at end example
+
+ at noindent
+are equivalent.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-semilogx,,semilogx}, @ref{doc-semilogy,,semilogy}, @ref{doc-loglog,,loglog}, @ref{doc-polar,,polar}, @ref{doc-mesh,,mesh}, @ref{doc-contour,,contour}, @ref{doc-bar,,bar}, @ref{doc-xlabel,,xlabel}, @ref{doc-ylabel,,ylabel}, @ref{doc-title,,title}}
+ at end deftypefn
+
+
+ at c ./plot/stem.m
+ at anchor{doc-stem}
+ at deftypefn {Function File} {@var{h} =} stem (@var{x}, @var{y}, @var{linespec})
+ at deftypefnx {Function File} {@var{h} =} stem (@dots{}, "filled")
+Plot a stem graph from two vectors of x-y data.  If only one argument
+is given, it is taken as the y-values and the x coordinates are taken
+from the indices of the elements.
+
+If @var{y} is a matrix, then each column of the matrix is plotted as
+a separate stem graph.  In this case @var{x} can either be a vector,
+the same length as the number of rows in @var{y}, or it can be a
+matrix of the same size as @var{y}.
+
+The default color is @code{"r"} (red).  The default line style is
+ at code{"-"} and the default marker is @code{"o"}.  The line style can
+be altered by the @code{linespec} argument in the same manner as the
+ at code{plot} command.  For example
+
+ at example
+ at group
+x = 1:10;
+y = ones (1, length (x))*2.*x;
+stem (x, y, "b");
+ at end group
+ at end example
+
+ at noindent
+plots 10 stems with heights from 2 to 20 in blue;
+
+The return value of @code{stem} is a vector if "stem series" graphics
+handles, with one handle per column of the variable @var{y}.  This
+handle regroups the elements of the stem graph together as the
+children of the "stem series" handle, allowing them to be altered
+together.  For example
+
+ at example
+ at group
+x = [0 : 10].';
+y = [sin(x), cos(x)]
+h = stem (x, y);
+set (h(2), "color", "g");
+set (h(1), "basevalue", -1)
+ at end group
+ at end example
+
+ at noindent
+changes the color of the second "stem series"  and moves the base line
+of the first.
+ at seealso{@ref{doc-bar,,bar}, @ref{doc-barh,,barh}, @ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/stem3.m
+ at anchor{doc-stem3}
+ at deftypefn {Function File} {@var{h} =} stem3 (@var{x}, @var{y}, @var{z}, @var{linespec})
+Plot a three-dimensional stem graph and return the handles of the line
+and marker objects used to draw the stems as "stem series" object.
+The default color is @code{"r"} (red).  The default line style is
+ at code{"-"} and the default marker is @code{"o"}.
+
+For example,
+ at example
+ at group
+theta = 0:0.2:6; 
+stem3 (cos (theta), sin (theta), theta) 
+ at end group
+ at end example
+
+ at noindent
+plots 31 stems with heights from 0 to 6 lying on a circle.  Color 
+definitions with rgb-triples are not valid!
+ at seealso{@ref{doc-bar,,bar}, @ref{doc-barh,,barh}, @ref{doc-stem,,stem}, @ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/scatter.m
+ at anchor{doc-scatter}
+ at deftypefn {Function File} {} scatter (@var{x}, @var{y}, @var{s}, @var{c})
+ at deftypefnx {Function File} {} scatter (@dots{}, 'filled')
+ at deftypefnx {Function File} {} scatter (@dots{}, @var{style})
+ at deftypefnx {Function File} {} scatter (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} scatter (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} scatter (@dots{})
+
+Plot a scatter plot of the data.  A marker is plotted at each point 
+defined by the points in the vectors @var{x} and @var{y}.  The size of
+the markers used is determined by the @var{s}, which can be a scalar, 
+a vector of the same length of @var{x} and @var{y}.  If @var{s} is not 
+given or is an empty matrix, then the default value of 8 points is used.
+
+The color of the markers is determined by @var{c}, which can be a string
+defining a fixed color, a 3 element vector giving the red, green and blue 
+components of the color, a vector of the same length as @var{x} that gives
+a scaled index into the current colormap, or a @var{n}-by-3 matrix defining
+the colors of each of the markers individually.
+
+The marker to use can be changed with the @var{style} argument, that is a 
+string defining a marker in the same manner as the @code{plot} command. 
+If the argument 'filled' is given then the markers as filled.  All 
+additional arguments are passed to the underlying patch command.
+
+The optional return value @var{h} provides a handle to the patch object
+
+ at example
+ at group
+x = randn (100, 1);
+y = randn (100, 1);
+scatter (x, y, [], sqrt(x.^2 + y.^2));
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-patch,,patch}, @ref{doc-scatter3,,scatter3}}
+ at end deftypefn
+
+
+ at c ./plot/scatter3.m
+ at anchor{doc-scatter3}
+ at deftypefn {Function File} {} scatter3 (@var{x}, @var{y}, @var{z}, @var{s}, @var{c})
+ at deftypefnx {Function File} {} scatter3 (@dots{}, 'filled')
+ at deftypefnx {Function File} {} scatter3 (@dots{}, @var{style})
+ at deftypefnx {Function File} {} scatter3 (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} scatter3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} scatter3 (@dots{})
+
+Plot a scatter plot of the data in 3D.  A marker is plotted at each point 
+defined by the points in the vectors @var{x}, @var{y} and @var{z}.  The size
+of the markers used is determined by @var{s}, which can be a scalar or
+a vector of the same length of @var{x}, @var{y} and @var{z}.  If @var{s} is
+not given or is an empty matrix, then the default value of 8 points is used.
+
+The color of the markers is determined by @var{c}, which can be a string
+defining a fixed color, a 3 element vector giving the red, green and blue 
+components of the color, a vector of the same length as @var{x} that gives
+a scaled index into the current colormap, or a @var{n}-by-3 matrix defining
+the colors of each of the markers individually.
+
+The marker to use can be changed with the @var{style} argument, that is a 
+string defining a marker in the same manner as the @code{plot} command. 
+If the argument 'filled' is given then the markers as filled.  All 
+additional arguments are passed to the underlying patch command.
+
+The optional return value @var{h} provides a handle to the patch object
+
+ at example
+ at group
+[x, y, z] = peaks (20);
+scatter3 (x(:), y(:), z(:), [], z(:));
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-patch,,patch}, @ref{doc-scatter,,scatter}}
+ at end deftypefn
+
+
+ at c ./plot/plotmatrix.m
+ at anchor{doc-plotmatrix}
+ at deftypefn {Function File} {} plotmatrix (@var{x}, @var{y})
+ at deftypefnx {Function File} {} plotmatrix (@var{x})
+ at deftypefnx {Function File} {} plotmatrix (@dots{}, @var{style})
+ at deftypefnx {Function File} {} plotmatrix (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{h}, @var{ax}, @var{bigax}, @var{p}, @var{pax}] =} plotmatrix (@dots{})
+Scatter plot of the columns of one matrix against another.  Given the
+arguments @var{x} and @var{y}, that have a matching number of rows,
+ at code{plotmatrix} plots a set of axes corresponding to
+
+ at example
+plot (@var{x} (:, i), @var{y} (:, j)
+ at end example
+
+Given a single argument @var{x}, then this is equivalent to 
+
+ at example
+plotmatrix (@var{x}, @var{x})
+ at end example
+
+ at noindent
+except that the diagonal of the set of axes will be replaced with the
+histogram @code{hist (@var{x} (:, i))}.
+
+The marker to use can be changed with the @var{style} argument, that is a 
+string defining a marker in the same manner as the @code{plot}
+command.  If a leading axes handle @var{h} is passed to
+ at code{plotmatrix}, then this axis will be used for the plot.
+
+The optional return value @var{h} provides handles to the individual
+graphics objects in the scatter plots, whereas @var{ax} returns the
+handles to the scatter plot axis objects.  @var{bigax} is a hidden
+axis object that surrounds the other axes, such that the commands 
+ at code{xlabel}, @code{title}, etc., will be associated with this hidden
+axis.  Finally @var{p} returns the graphics objects associated with
+the histogram and @var{pax} the corresponding axes objects.
+
+ at example
+ at group
+plotmatrix (randn (100, 3), 'g+')
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+ at c ./plot/pareto.m
+ at anchor{doc-pareto}
+ at deftypefn {Function File} {} pareto (@var{x})
+ at deftypefnx {Function File} {} pareto (@var{x}, @var{y})
+ at deftypefnx {Function File} {} pareto (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} pareto (@dots{})
+Draw a Pareto chart, also called ABC chart.  A Pareto chart is a bar graph 
+used to arrange information in such a way that priorities for process 
+improvement can be established.  It organizes and displays information 
+to show the relative importance of data.  The chart is similar to the 
+histogram or bar chart, except that the bars are arranged in decreasing 
+order from left to right along the abscissa.
+
+The fundamental idea (Pareto principle) behind the use of Pareto 
+diagrams is that the majority of an effect is due to a small subset of the
+causes, so for quality improvement the first few (as presented on the 
+diagram) contributing causes to a problem usually account for the majority 
+of the result.  Thus, targeting these "major causes" for elimination 
+results in the most cost-effective improvement scheme.
+
+The data are passed as @var{x} and the abscissa as @var{y}.  If @var{y} is
+absent, then the abscissa are assumed to be @code{1 : length (@var{x})}.
+ at var{y} can be a string array, a cell array of strings or a numerical
+vector.
+
+An example of the use of @code{pareto} is
+
+ at example
+ at group
+Cheese = @{"Cheddar", "Swiss", "Camembert", ...
+          "Munster", "Stilton", "Blue"@};
+Sold = [105, 30, 70, 10, 15, 20];
+pareto(Sold, Cheese);
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./plot/rose.m
+ at anchor{doc-rose}
+ at deftypefn {Function File} {} rose (@var{th}, @var{r})
+ at deftypefnx {Function File} {} rose (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} rose (@dots{})
+ at deftypefnx {Function File} {[@var{r}, @var{th}] =} rose (@dots{})
+
+Plot an angular histogram.  With one vector argument @var{th}, plots the
+histogram with 20 angular bins.  If @var{th} is a matrix, then each column
+of @var{th} produces a separate histogram.
+
+If @var{r} is given and is a scalar, then the histogram is produced with
+ at var{r} bins.  If @var{r} is a vector, then the center of each bin are 
+defined by the values of @var{r}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+If two output arguments are requested, then rather than plotting the 
+histogram, the polar vectors necessary to plot the histogram are 
+returned.
+
+ at example
+ at group
+[r, t] = rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)]);
+polar (r, t);
+ at end group
+ at end example
+
+
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-compass,,compass}, @ref{doc-polar,,polar}, @ref{doc-hist,,hist}}
+ at end deftypefn
+
+
+The @code{contour}, @code{contourf} and @code{contourc} functions
+produce two-dimensional contour plots from three-dimensional data.
+
+ at c ./plot/contour.m
+ at anchor{doc-contour}
+ at deftypefn {Function File} {} contour (@var{z})
+ at deftypefnx {Function File} {} contour (@var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} contour (@var{x}, @var{y}, @var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour (@dots{}, @var{style})
+ at deftypefnx {Function File} {} contour (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contour (@dots{})
+Plot level curves (contour lines) of the matrix @var{z}, using the
+contour matrix @var{c} computed by @code{contourc} from the same
+arguments; see the latter for their interpretation.  The set of
+contour levels, @var{c}, is only returned if requested.  For example:
+
+ at example
+ at group
+x = 0:2;
+y = x;
+z = x' * y;
+contour (x, y, z, 2:3)
+ at end group
+ at end example
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+Any markers defined by @var{style} are ignored.
+
+The optional input and output argument @var{h} allows an axis handle to 
+be passed to @code{contour} and the handles to the contour objects to be
+returned.
+ at seealso{@ref{doc-contourc,,contourc}, @ref{doc-patch,,patch}, @ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/contourf.m
+ at anchor{doc-contourf}
+ at deftypefn {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z}, @var{lvl})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z}, @var{n})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z}, @var{n})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z}, @var{lvl})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{ax}, @dots{})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@dots{}, @var{"property"}, @var{val})
+Compute and plot filled contours of the matrix @var{z}.
+Parameters @var{x}, @var{y} and @var{n} or @var{lvl} are optional.
+
+The return value @var{c} is a 2xn matrix containing the contour lines
+as described in the help to the contourc function.
+
+The return value @var{h} is handle-vector to the patch objects creating
+the filled contours.
+
+If @var{x} and @var{y} are omitted they are taken as the row/column
+index of @var{z}.  @var{n} is a scalar denoting the number of lines
+to compute.  Alternatively @var{lvl} is a vector containing the
+contour levels.  If only one value (e.g., lvl0) is wanted, set
+ at var{lvl} to [lvl0, lvl0].  If both @var{n} or @var{lvl} are omitted
+a default value of 10 contour level is assumed.
+
+If provided, the filled contours are added to the axes object
+ at var{ax} instead of the current axis.
+
+The following example plots filled contours of the @code{peaks}
+function.
+ at example
+ at group
+[x, y, z] = peaks (50);
+contourf (x, y, z, -7:9)
+ at end group
+ at end example
+ at seealso{@ref{doc-contour,,contour}, @ref{doc-contourc,,contourc}, @ref{doc-patch,,patch}}
+ at end deftypefn
+
+
+ at c ./plot/contourc.m
+ at anchor{doc-contourc}
+ at deftypefn {Function File} {[@var{c}, @var{lev}] =}  contourc (@var{x}, @var{y}, @var{z}, @var{vn})
+Compute isolines (contour lines) of the matrix @var{z}. 
+Parameters @var{x}, @var{y} and @var{vn} are optional.
+
+The return value @var{lev} is a vector of the contour levels.
+The return value @var{c} is a 2 by @var{n} matrix containing the
+contour lines in the following format
+
+ at example
+ at group
+ at var{c} = [lev1, x1, x2, @dots{}, levn, x1, x2, @dots{} 
+     len1, y1, y2, @dots{}, lenn, y1, y2, @dots{}]
+ at end group
+ at end example
+
+ at noindent
+in which contour line @var{n} has a level (height) of @var{levn} and
+length of @var{lenn}.
+
+If @var{x} and @var{y} are omitted they are taken as the row/column 
+index of @var{z}.  @var{vn} is either a scalar denoting the number of lines 
+to compute or a vector containing the values of the lines.  If only one 
+value is wanted, set @code{@var{vn} = [val, val]};
+If @var{vn} is omitted it defaults to 10.
+
+For example,
+ at example
+ at group
+x = 0:2;
+y = x;
+z = x' * y;
+contourc (x, y, z, 2:3)
+     @result{}   2.0000   2.0000   1.0000   3.0000   1.5000   2.0000
+     2.0000   1.0000   2.0000   2.0000   2.0000   1.5000
+
+ at end group
+ at end example
+ at seealso{@ref{doc-contour,,contour}}
+ at end deftypefn
+
+
+ at c ./plot/contour3.m
+ at anchor{doc-contour3}
+ at deftypefn {Function File} {} contour3 (@var{z})
+ at deftypefnx {Function File} {} contour3 (@var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour3 (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} contour3 (@var{x}, @var{y}, @var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour3 (@dots{}, @var{style})
+ at deftypefnx {Function File} {} contour3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contour3 (@dots{})
+Plot level curves (contour lines) of the matrix @var{z}, using the
+contour matrix @var{c} computed by @code{contourc} from the same
+arguments; see the latter for their interpretation.  The contours are
+plotted at the Z level corresponding to their contour.  The set of
+contour levels, @var{c}, is only returned if requested.  For example:
+
+ at example
+ at group
+contour3 (peaks (19));
+hold on
+surface (peaks (19), "facecolor", "none", "EdgeColor", "black")
+colormap hot
+ at end group
+ at end example
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+Any markers defined by @var{style} are ignored.
+
+The optional input and output argument @var{h} allows an axis handle to 
+be passed to @code{contour} and the handles to the contour objects to be
+returned.
+ at seealso{@ref{doc-contourc,,contourc}, @ref{doc-patch,,patch}, @ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+The @code{errorbar}, @code{semilogxerr}, @code{semilogyerr}, and
+ at code{loglogerr} functions produce plots with error bar markers.  For
+example,
+
+ at example
+ at group
+x = 0:0.1:10;
+y = sin (x);
+yp =  0.1 .* randn (size (x));
+ym = -0.1 .* randn (size (x));
+errorbar (x, sin (x), ym, yp);
+ at end group
+ at end example
+
+ at noindent
+produces the figure shown in @ref{fig:errorbar}.
+
+ at float Figure,fig:errorbar
+ at center @image{errorbar,4in}
+ at caption{Errorbar plot.}
+ at end float
+
+ at c ./plot/errorbar.m
+ at anchor{doc-errorbar}
+ at deftypefn {Function File} {} errorbar (@var{args})
+This function produces two-dimensional plots with errorbars.  Many
+different combinations of arguments are possible.  The simplest form is
+
+ at example
+errorbar (@var{y}, @var{ey})
+ at end example
+
+ at noindent
+where the first argument is taken as the set of @var{y} coordinates
+and the second argument @var{ey} is taken as the errors of the
+ at var{y} values.  @var{x} coordinates are taken to be the indices
+of the elements, starting with 1.
+
+If more than two arguments are given, they are interpreted as
+
+ at example
+errorbar (@var{x}, @var{y}, @dots{}, @var{fmt}, @dots{})
+ at end example
+
+ at noindent
+where after @var{x} and @var{y} there can be up to four error
+parameters such as @var{ey}, @var{ex}, @var{ly}, @var{uy}, etc.,
+depending on the plot type.  Any number of argument sets may appear,
+as long as they are separated with a format string @var{fmt}.
+
+If @var{y} is a matrix, @var{x} and error parameters must also be matrices
+having same dimensions.  The columns of @var{y} are plotted versus the
+corresponding columns of @var{x} and errorbars are drawn from
+the corresponding columns of error parameters.
+
+If @var{fmt} is missing, yerrorbars ("~") plot style is assumed.
+
+If the @var{fmt} argument is supplied, it is interpreted as in
+normal plots.  In addition the following plot styles are supported by
+errorbar:
+
+ at table @samp
+ at item ~
+Set yerrorbars plot style (default).
+
+ at item >
+Set xerrorbars plot style.
+
+ at item ~>
+Set xyerrorbars plot style.
+
+ at item #
+Set boxes plot style.
+
+ at item #~
+Set boxerrorbars plot style.
+
+ at item #~>
+Set boxxyerrorbars plot style.
+ at end table
+
+Examples:
+
+ at example
+errorbar (@var{x}, @var{y}, @var{ex}, ">")
+ at end example
+
+produces an xerrorbar plot of @var{y} versus @var{x} with @var{x}
+errorbars drawn from @var{x}- at var{ex} to @var{x}+ at var{ex}.
+
+ at example
+ at group
+errorbar (@var{x}, @var{y1}, @var{ey}, "~",
+          @var{x}, @var{y2}, @var{ly}, @var{uy})
+ at end group
+ at end example
+
+produces yerrorbar plots with @var{y1} and @var{y2} versus @var{x}.
+Errorbars for @var{y1} are drawn from @var{y1}- at var{ey} to
+ at var{y1}+ at var{ey}, errorbars for @var{y2} from @var{y2}- at var{ly} to
+ at var{y2}+ at var{uy}.
+
+ at example
+ at group
+errorbar (@var{x}, @var{y}, @var{lx}, @var{ux},
+          @var{ly}, @var{uy}, "~>")
+ at end group
+ at end example
+
+produces an xyerrorbar plot of @var{y} versus @var{x} in which
+ at var{x} errorbars are drawn from @var{x}- at var{lx} to @var{x}+ at var{ux}
+and @var{y} errorbars from @var{y}- at var{ly} to @var{y}+ at var{uy}.
+ at seealso{@ref{doc-semilogxerr,,semilogxerr}, @ref{doc-semilogyerr,,semilogyerr}, @ref{doc-loglogerr,,loglogerr}}
+ at end deftypefn
+
+
+ at c ./plot/semilogxerr.m
+ at anchor{doc-semilogxerr}
+ at deftypefn {Function File} {} semilogxerr (@var{args})
+Produce two-dimensional plots on a semilogarithm axis with errorbars.
+Many different combinations of arguments are possible.  The most used
+form is
+
+ at example
+semilogxerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+ at end example
+
+ at noindent
+which produces a semi-logarithm plot of @var{y} versus @var{x}
+with errors in the @var{y}-scale defined by @var{ey} and the plot
+format defined by @var{fmt}.  See errorbar for available formats and 
+additional information.
+ at seealso{@ref{doc-errorbar,,errorbar}, @ref{doc-loglogerr,,loglogerr}, @ref{doc-semilogyerr,,semilogyerr}}
+ at end deftypefn
+
+
+ at c ./plot/semilogyerr.m
+ at anchor{doc-semilogyerr}
+ at deftypefn {Function File} {} semilogyerr (@var{args})
+Produce two-dimensional plots on a semilogarithm axis with errorbars.
+Many different combinations of arguments are possible.  The most used
+form is
+
+ at example
+semilogyerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+ at end example
+
+ at noindent
+which produces a semi-logarithm plot of @var{y} versus @var{x}
+with errors in the @var{y}-scale defined by @var{ey} and the plot
+format defined by @var{fmt}.  See errorbar for available formats and 
+additional information.
+ at seealso{@ref{doc-errorbar,,errorbar}, @ref{doc-loglogerr,,loglogerr}, @ref{doc-semilogxerr,,semilogxerr}}
+ at end deftypefn
+
+
+ at c ./plot/loglogerr.m
+ at anchor{doc-loglogerr}
+ at deftypefn {Function File} {} loglogerr (@var{args})
+Produce two-dimensional plots on double logarithm axis with
+errorbars.  Many different combinations of arguments are possible.
+The most used form is
+
+ at example
+loglogerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+ at end example
+
+ at noindent
+which produces a double logarithm plot of @var{y} versus @var{x} 
+with errors in the @var{y}-scale defined by @var{ey} and the plot
+format defined by @var{fmt}.  See errorbar for available formats and 
+additional information.
+ at seealso{@ref{doc-errorbar,,errorbar}, @ref{doc-semilogxerr,,semilogxerr}, @ref{doc-semilogyerr,,semilogyerr}}
+ at end deftypefn
+
+
+Finally, the @code{polar} function allows you to easily plot data in
+polar coordinates.  However, the display coordinates remain rectangular
+and linear.  For example,
+
+ at example
+polar (0:0.1:10*pi, 0:0.1:10*pi);
+ at end example
+
+ at noindent
+produces the spiral plot shown in @ref{fig:polar}.
+
+ at float Figure,fig:polar
+ at center @image{polar,4in}
+ at caption{Polar plot.}
+ at end float
+
+ at c ./plot/polar.m
+ at anchor{doc-polar}
+ at deftypefn {Function File} {} polar (@var{theta}, @var{rho}, @var{fmt})
+Make a two-dimensional plot given the polar coordinates @var{theta} and
+ at var{rho}.
+
+The optional third argument specifies the line type.
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/pie.m
+ at anchor{doc-pie}
+ at deftypefn {Function File} {} pie (@var{y})
+ at deftypefnx {Function File} {} pie (@var{y}, @var{explode})
+ at deftypefnx {Function File} {} pie (@dots{}, @var{labels})
+ at deftypefnx {Function File} {} pie (@var{h}, @dots{});
+ at deftypefnx {Function File} {@var{h} =} pie (@dots{});
+Produce a pie chart. 
+
+Called with a single vector argument, produces a pie chart of the
+elements in @var{x}, with the size of the slice determined by percentage
+size of the values of @var{x}.
+
+The variable @var{explode} is a vector of the same length as @var{x} that
+if non zero 'explodes' the slice from the pie chart.
+
+If given @var{labels} is a cell array of strings of the same length as
+ at var{x}, giving the labels of each of the slices of the pie chart. 
+
+The optional return value @var{h} provides a handle to the patch object.
+
+ at seealso{@ref{doc-bar,,bar}, @ref{doc-stem,,stem}}
+ at end deftypefn
+
+
+ at c ./plot/quiver.m
+ at anchor{doc-quiver}
+ at deftypefn {Function File} {} quiver (@var{u}, @var{v})
+ at deftypefnx {Function File} {} quiver (@var{x}, @var{y}, @var{u}, @var{v})
+ at deftypefnx {Function File} {} quiver (@dots{}, @var{s})
+ at deftypefnx {Function File} {} quiver (@dots{}, @var{style})
+ at deftypefnx {Function File} {} quiver (@dots{}, 'filled')
+ at deftypefnx {Function File} {} quiver (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} quiver (@dots{})
+
+Plot the @code{(@var{u}, @var{v})} components of a vector field in 
+an @code{(@var{x}, @var{y})} meshgrid.  If the grid is uniform, you can 
+specify @var{x} and @var{y} as vectors.
+
+If @var{x} and @var{y} are undefined they are assumed to be
+ at code{(1:@var{m}, 1:@var{n})} where @code{[@var{m}, @var{n}] = 
+size(@var{u})}.
+
+The variable @var{s} is a scalar defining a scaling factor to use for
+ the arrows of the field relative to the mesh spacing.  A value of 0 
+disables all scaling.  The default value is 1.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+If a marker is specified then markers at the grid points of the vectors are
+printed rather than arrows.  If the argument 'filled' is given then the
+markers as filled.
+
+The optional return value @var{h} provides a quiver group that
+regroups the components of the quiver plot (body, arrow and marker),
+and allows them to be changed together
+
+ at example
+ at group
+[x, y] = meshgrid (1:2:20);
+h = quiver (x, y, sin (2*pi*x/10), sin (2*pi*y/10));
+set (h, "maxheadsize", 0.33);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/quiver3.m
+ at anchor{doc-quiver3}
+ at deftypefn {Function File} {} quiver3 (@var{u}, @var{v}, @var{w})
+ at deftypefnx {Function File} {} quiver3 (@var{x}, @var{y}, @var{z}, @var{u}, @var{v}, @var{w})
+ at deftypefnx {Function File} {} quiver3 (@dots{}, @var{s})
+ at deftypefnx {Function File} {} quiver3 (@dots{}, @var{style})
+ at deftypefnx {Function File} {} quiver3 (@dots{}, 'filled')
+ at deftypefnx {Function File} {} quiver3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} quiver3 (@dots{})
+
+Plot the @code{(@var{u}, @var{v}, @var{w})} components of a vector field in 
+an @code{(@var{x}, @var{y}), @var{z}} meshgrid.  If the grid is uniform, you 
+can specify @var{x}, @var{y} @var{z} as vectors.
+
+If @var{x}, @var{y} and @var{z} are undefined they are assumed to be
+ at code{(1:@var{m}, 1:@var{n}, 1:@var{p})} where @code{[@var{m}, @var{n}] = 
+size(@var{u})} and @code{@var{p} = max (size (@var{w}))}.
+
+The variable @var{s} is a scalar defining a scaling factor to use for
+ the arrows of the field relative to the mesh spacing.  A value of 0 
+disables all scaling.  The default value is 1.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+If a marker is specified then markers at the grid points of the vectors are
+printed rather than arrows.  If the argument 'filled' is given then the
+markers as filled.
+
+The optional return value @var{h} provides a quiver group that
+regroups the components of the quiver plot (body, arrow and marker),
+and allows them to be changed together
+
+ at example
+ at group
+[x, y, z] = peaks (25);
+surf (x, y, z);
+hold on;
+[u, v, w] = surfnorm (x, y, z / 10);
+h = quiver3 (x, y, z, u, v, w);
+set (h, "maxheadsize", 0.33);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/compass.m
+ at anchor{doc-compass}
+ at deftypefn {Function File} {} compass (@var{u}, @var{v})
+ at deftypefnx {Function File} {} compass (@var{z})
+ at deftypefnx {Function File} {} compass (@dots{}, @var{style})
+ at deftypefnx {Function File} {} compass (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} compass (@dots{})
+
+Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
+from the origin of a polar plot.  If a single complex argument @var{z} is 
+given, then @code{@var{u} = real (@var{z})} and @code{@var{v} = imag 
+(@var{z})}.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+compass (eig (a))
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-polar,,polar}, @ref{doc-quiver,,quiver}, @ref{doc-feather,,feather}}
+ at end deftypefn
+
+
+ at c ./plot/feather.m
+ at anchor{doc-feather}
+ at deftypefn {Function File} {} feather (@var{u}, @var{v})
+ at deftypefnx {Function File} {} feather (@var{z})
+ at deftypefnx {Function File} {} feather (@dots{}, @var{style})
+ at deftypefnx {Function File} {} feather (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} feather (@dots{})
+
+Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
+from equidistant points on the x-axis.  If a single complex argument
+ at var{z} is given, then @code{@var{u} = real (@var{z})} and
+ at code{@var{v} = imag (@var{z})}.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+phi = [0 : 15 : 360] * pi / 180;
+feather (sin (phi), cos (phi))
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-quiver,,quiver}, @ref{doc-compass,,compass}}
+ at end deftypefn
+
+
+ at c ./plot/pcolor.m
+ at anchor{doc-pcolor}
+ at deftypefn {Function File} {} pcolor (@var{x}, @var{y}, @var{c})
+ at deftypefnx {Function File} {} pcolor (@var{c})
+Density plot for given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{c} corresponding to the @var{x} and @var{y} coordinates of
+the mesh's vertices.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{c}(i,j)).  Thus, columns of @var{c}
+correspond to different @var{x} values and rows of @var{c} correspond
+to different @var{y} values.
+
+The @code{colormap} is scaled to the extents of @var{c}.
+Limits may be placed on the color axis by the
+command @code{caxis}, or by setting the @code{clim} property of the
+parent axis.
+
+The face color of each cell of the mesh is determined by interpolating
+the values of @var{c} for the cell's vertices.  Contrast this with 
+ at code{imagesc} which renders one cell for each element of @var{c}.
+
+ at code{shading} modifies an attribute determining the manner by which the
+face color of each cell is interpolated from the values of @var{c},
+and the visibility of the cells' edges.  By default the attribute is
+"faceted", which renders a single color for each cell's face with the edge
+visible.
+
+ at var{h} is the handle to the surface object.
+
+ at seealso{@ref{doc-caxis,,caxis}, @ref{doc-contour,,contour}, @ref{doc-meshgrid,,meshgrid}, @ref{doc-imagesc,,imagesc}, @ref{doc-shading,,shading}}
+ at end deftypefn
+
+
+ at c ./plot/area.m
+ at anchor{doc-area}
+ at deftypefn {Function File} {} area (@var{x}, @var{y})
+ at deftypefnx {Function File} {} area (@var{x}, @var{y}, @var{lvl})
+ at deftypefnx {Function File} {} area (@dots{}, @var{prop}, @var{val}, @dots{})
+ at deftypefnx {Function File} {} area (@var{y}, @dots{})
+ at deftypefnx {Function File} {} area (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} area (@dots{})
+Area plot of cumulative sum of the columns of @var{y}.  This shows the
+contributions of a value to a sum, and is functionally similar to 
+ at code{plot (@var{x}, cumsum (@var{y}, 2))}, except that the area under 
+the curve is shaded.
+
+If the @var{x} argument is omitted it is assumed to be given by
+ at code{1 : rows (@var{y})}.  A value @var{lvl} can be defined that determines
+where the base level of the shading under the curve should be defined.
+
+Additional arguments to the @code{area} function are passed to the 
+ at code{patch}.  The optional return value @var{h} provides a handle to 
+area series object representing the patches of the areas.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-patch,,patch}}
+ at end deftypefn
+
+
+ at c ./plot/comet.m
+ at anchor{doc-comet}
+ at deftypefn {Function File} {} comet (@var{y})
+ at deftypefnx {Function File} {} comet (@var{x}, @var{y})
+ at deftypefnx {Function File} {} comet (@var{x}, @var{y}, @var{p})
+ at deftypefnx {Function File} {} comet (@var{ax}, @dots{})
+Produce a simple comet style animation along the trajectory provided by 
+the input coordinate vectors (@var{x}, @var{y}), where @var{x} will default
+to the indices of @var{y}.
+
+The speed of the comet may be controlled by @var{p}, which represents the
+time which passes as the animation passes from one point to the next.  The
+default for @var{p} is 0.1 seconds.
+
+If @var{ax} is specified the animation is produced in that axis rather than
+the @code{gca}.
+ at end deftypefn
+
+
+The axis function may be used to change the axis limits of an existing
+plot and various other axis properties, such as the aspect ratio and the
+appearance of tic marks.
+
+ at c ./plot/axis.m
+ at anchor{doc-axis}
+ at deftypefn {Function File} {} axis (@var{limits})
+Set axis limits for plots.
+
+The argument @var{limits} should be a 2, 4, or 6 element vector.  The
+first and second elements specify the lower and upper limits for the x
+axis.  The third and fourth specify the limits for the y-axis, and the
+fifth and sixth specify the limits for the z-axis.
+
+Without any arguments, @code{axis} turns autoscaling on.  
+
+With one output argument, @code{x = axis} returns the current axes 
+
+The vector argument specifying limits is optional, and additional
+string arguments may be used to specify various axis properties.  For
+example,
+
+ at example
+axis ([1, 2, 3, 4], "square");
+ at end example
+
+ at noindent
+forces a square aspect ratio, and
+
+ at example
+axis ("labely", "tic");
+ at end example
+
+ at noindent
+turns tic marks on for all axes and tic mark labels on for the y-axis
+only.
+
+ at noindent
+The following options control the aspect ratio of the axes.
+
+ at table @code
+ at item "square"
+Force a square aspect ratio.
+ at item "equal"
+Force x distance to equal y-distance.
+ at item "normal"
+Restore the balance.
+ at end table
+
+ at noindent
+The following options control the way axis limits are interpreted.
+
+ at table @code
+ at item "auto" 
+Set the specified axes to have nice limits around the data
+or all if no axes are specified.
+ at item "manual" 
+Fix the current axes limits.
+ at item "tight"
+Fix axes to the limits of the data.
+ at end table
+
+ at noindent
+The option @code{"image"} is equivalent to @code{"tight"} and
+ at code{"equal"}.
+
+ at noindent
+The following options affect the appearance of tic marks.
+
+ at table @code
+ at item "on" 
+Turn tic marks and labels on for all axes.
+ at item "off"
+Turn tic marks off for all axes.
+ at item "tic[xyz]"
+Turn tic marks on for all axes, or turn them on for the
+specified axes and off for the remainder.
+ at item "label[xyz]"
+Turn tic labels on for all axes, or turn them on for the 
+specified axes and off for the remainder.
+ at item "nolabel"
+Turn tic labels off for all axes.
+ at end table
+Note, if there are no tic marks for an axis, there can be no labels.
+
+ at noindent
+The following options affect the direction of increasing values on
+the axes.
+
+ at table @code
+ at item "ij"
+Reverse y-axis, so lower values are nearer the top.
+ at item "xy" 
+Restore y-axis, so higher values are nearer the top. 
+ at end table
+
+If an axes handle is passed as the first argument, then operate on
+this axes rather than the current axes.
+ at end deftypefn
+
+
+Similarly the axis limits of the colormap can be changed with the caxis
+function.
+
+ at c ./plot/caxis.m
+ at anchor{doc-caxis}
+ at deftypefn {Function File} {} caxis (@var{limits})
+ at deftypefnx {Function File} {} caxis (@var{h}, @dots{})
+Set color axis limits for plots.
+
+The argument @var{limits} should be a 2 element vector specifying the 
+lower and upper limits to assign to the first and last value in the
+colormap.  Values outside this range are clamped to the first and last
+colormap entries. 
+
+If @var{limits} is 'auto', then automatic colormap scaling is applied,
+whereas if @var{limits} is 'manual' the colormap scaling is set to manual.
+
+Called without any arguments to current color axis limits are returned.
+
+If an axes handle is passed as the first argument, then operate on
+this axes rather than the current axes.
+ at end deftypefn
+
+
+The @code{xlim}, @code{ylim}, and @code{zlim} functions may be used to
+get or set individual axis limits.  Each has the same form.
+
+ at anchor{doc-ylim}
+ at anchor{doc-zlim}
+ at c ./plot/xlim.m
+ at anchor{doc-xlim}
+ at deftypefn {Function File} {@var{xl} =} xlim ()
+ at deftypefnx {Function File} {} xlim (@var{xl})
+ at deftypefnx {Function File} {@var{m} =} xlim ('mode')
+ at deftypefnx {Function File} {} xlim (@var{m})
+ at deftypefnx {Function File} {} xlim (@var{h}, @dots{})
+Get or set the limits of the x-axis of the current plot.  Called without
+arguments @code{xlim} returns the x-axis limits of the current plot.
+If passed a two element vector @var{xl}, the limits of the x-axis are set
+to this value.
+
+The current mode for calculation of the x-axis can be returned with a
+call @code{xlim ('mode')}, and can be either 'auto' or 'manual'.  The 
+current plotting mode can be set by passing either 'auto' or 'manual' 
+as the argument.
+
+If passed an handle as the first argument, then operate on this handle
+rather than the current axes handle.
+ at seealso{@ref{doc-ylim,,ylim}, @ref{doc-zlim,,zlim}, @ref{doc-set,,set}, @ref{doc-get,,get}, @ref{doc-gca,,gca}}
+ at end deftypefn
+
+
+ at menu
+* Two-dimensional Function Plotting::
+ at end menu
+
+ at node Two-dimensional Function Plotting
+ at subsubsection Two-dimensional Function Plotting
+
+Octave can plot a function from a function handle inline function or
+string defining the function without the user needing to explicitly
+create the data to be plotted.  The function @code{fplot} also generates
+two-dimensional plots with linear axes using a function name and limits
+for the range of the x-coordinate instead of the x and y data.  For
+example,
+
+ at example
+ at group
+fplot (@@sin, [-10, 10], 201);
+ at end group
+ at end example
+
+ at noindent
+produces a plot that is equivalent to the one above, but also includes a
+legend displaying the name of the plotted function.
+
+ at c ./plot/fplot.m
+ at anchor{doc-fplot}
+ at deftypefn {Function File} {} fplot (@var{fn}, @var{limits})
+ at deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{tol})
+ at deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{n})
+ at deftypefnx {Function File} {} fplot (@dots{}, @var{fmt})
+Plot a function @var{fn}, within the defined limits.  @var{fn}
+an be either a string, a function handle or an inline function.
+The limits of the plot are given by @var{limits} of the form
+ at code{[@var{xlo}, @var{xhi}]} or @code{[@var{xlo}, @var{xhi},
+ at var{ylo}, @var{yhi}]}.  @var{tol} is the default tolerance to use for the
+plot, and if @var{tol} is an integer it is assumed that it defines the 
+number points to use in the plot.  The @var{fmt} argument is passed
+to the plot command.
+
+ at example
+ at group
+   fplot ("cos", [0, 2*pi])
+   fplot ("[cos(x), sin(x)]", [0, 2*pi])
+ at end group
+ at end example
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+Other functions that can create two-dimensional plots directly from a
+function include @code{ezplot}, @code{ezcontour}, @code{ezcontourf} and
+ at code{ezpolar}.
+
+ at c ./plot/ezplot.m
+ at anchor{doc-ezplot}
+ at deftypefn {Function File} {} ezplot (@var{f})
+ at deftypefnx {Function File} {} ezplot (@var{fx}, @var{fy})
+ at deftypefnx {Function File} {} ezplot (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezplot (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezplot (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezplot (@dots{})
+
+Plots in two-dimensions the curve defined by @var{f}.  The function
+ at var{f} may be a string, inline function or function handle and can
+have either one or two variables.  If @var{f} has one variable, then 
+the function is plotted over the domain @code{-2*pi < @var{x} < 2*pi}  
+with 500 points. 
+
+If @var{f} has two variables then @code{@var{f}(@var{x}, at var{y}) = 0}
+is calculated over the meshed domain @code{-2*pi < @var{x} | @var{y}
+< 2*pi} with 60 by 60 in the mesh.  For example
+
+ at example
+ezplot (@@(@var{x}, @var{y}) @var{x} .^ 2 - @var{y} .^ 2 - 1)
+ at end example
+
+If two functions are passed as strings, inline functions or function
+handles, then the parametric function
+
+ at example
+ at group
+ at var{x} = @var{fx} (@var{t})
+ at var{y} = @var{fy} (@var{t})
+ at end group
+ at end example
+
+is plotted over the domain @code{-2*pi < @var{t} < 2*pi} with 500
+points. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of @var{x}, @var{y} and @var{t}.  If it is a four element
+vector, then the minimum and maximum values of @var{x} and @var{t}
+are determined by the first two elements and the minimum and maximum
+of @var{y} by the second pair of elements.
+
+ at var{n} is a scalar defining the number of points to use in plotting
+the function.
+
+The optional return value @var{h} provides a list of handles to the 
+the line objects plotted.
+
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-ezplot3,,ezplot3}}
+ at end deftypefn
+
+
+ at c ./plot/ezcontour.m
+ at anchor{doc-ezcontour}
+ at deftypefn {Function File} {} ezcontour (@var{f})
+ at deftypefnx {Function File} {} ezcontour (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezcontour (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezcontour (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezcontour (@dots{})
+
+Plots the contour lines of a function.  @var{f} is a string, inline function
+or function handle with two arguments defining the function.  By default the
+plot is over the domain @code{-2*pi < @var{x} < 2*pi} and @code{-2*pi < 
+ at var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezcontour (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ezplot,,ezplot}, @ref{doc-ezcontourf,,ezcontourf}, @ref{doc-ezsurfc,,ezsurfc}, @ref{doc-ezmeshc,,ezmeshc}}
+ at end deftypefn
+
+
+ at c ./plot/ezcontourf.m
+ at anchor{doc-ezcontourf}
+ at deftypefn {Function File} {} ezcontourf (@var{f})
+ at deftypefnx {Function File} {} ezcontourf (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezcontourf (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezcontourf (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezcontourf (@dots{})
+
+Plots the filled contour lines of a function.  @var{f} is a string, inline 
+function or function handle with two arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and 
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezcontourf (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ezplot,,ezplot}, @ref{doc-ezcontour,,ezcontour}, @ref{doc-ezsurfc,,ezsurfc}, @ref{doc-ezmeshc,,ezmeshc}}
+ at end deftypefn
+
+
+ at c ./plot/ezpolar.m
+ at anchor{doc-ezpolar}
+ at deftypefn {Function File} {} ezpolar (@var{f})
+ at deftypefnx {Function File} {} ezpolar (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezpolar (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezpolar (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezpolar (@dots{})
+
+Plots in polar plot defined by a function.  The function @var{f} is either
+a string, inline function or function handle with one arguments defining 
+the function.  By default the plot is over the domain @code{0 < @var{x} < 
+2*pi} with 60 points. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{t}.  @var{n} is a scalar defining the number of points to 
+use.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ezpolar (@@(t) 1 + sin (t));
+ at end example
+
+ at seealso{@ref{doc-polar,,polar}, @ref{doc-ezplot,,ezplot}, @ref{doc-ezsurf,,ezsurf}, @ref{doc-ezmesh,,ezmesh}}
+ at end deftypefn
+
+
+ at node Three-Dimensional Plotting
+ at subsection Three-Dimensional Plotting
+
+The function @code{mesh} produces mesh surface plots.  For example,
+
+ at example
+ at group
+tx = ty = linspace (-8, 8, 41)';
+[xx, yy] = meshgrid (tx, ty);
+r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+tz = sin (r) ./ r;
+mesh (tx, ty, tz);
+ at end group
+ at end example
+
+ at noindent
+produces the familiar ``sombrero'' plot shown in @ref{fig:mesh}.  Note
+the use of the function @code{meshgrid} to create matrices of X and Y
+coordinates to use for plotting the Z data.  The @code{ndgrid} function
+is similar to @code{meshgrid}, but works for N-dimensional matrices.
+
+ at float Figure,fig:mesh
+ at center @image{mesh,4in}
+ at caption{Mesh plot.}
+ at end float
+
+The @code{meshc} function is similar to @code{mesh}, but also produces a
+plot of contours for the surface.
+
+The @code{plot3} function displays arbitrary three-dimensional data,
+without requiring it to form a surface.  For example
+
+ at example
+ at group
+t = 0:0.1:10*pi;
+r = linspace (0, 1, numel (t));
+z = linspace (0, 1, numel (t));
+plot3 (r.*sin(t), r.*cos(t), z);
+ at end group
+ at end example
+
+ at noindent
+displays the spiral in three dimensions shown in @ref{fig:plot3}.
+
+ at float Figure,fig:plot3
+ at center @image{plot3,4in}
+ at caption{Three dimensional spiral.}
+ at end float
+
+Finally, the @code{view} function changes the viewpoint for
+three-dimensional plots.
+
+ at c ./plot/mesh.m
+ at anchor{doc-mesh}
+ at deftypefn {Function File} {} mesh (@var{x}, @var{y}, @var{z})
+Plot a mesh given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+correspond to different @var{x} values and rows of @var{z} correspond
+to different @var{y} values.
+ at seealso{@ref{doc-meshgrid,,meshgrid}, @ref{doc-contour,,contour}}
+ at end deftypefn
+
+
+ at c ./plot/meshc.m
+ at anchor{doc-meshc}
+ at deftypefn {Function File} {} meshc (@var{x}, @var{y}, @var{z})
+Plot a mesh and contour given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.
+ at seealso{@ref{doc-meshgrid,,meshgrid}, @ref{doc-mesh,,mesh}, @ref{doc-contour,,contour}}
+ at end deftypefn
+
+
+ at c ./plot/meshz.m
+ at anchor{doc-meshz}
+ at deftypefn {Function File} {} meshz (@var{x}, @var{y}, @var{z})
+Plot a curtain mesh given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.
+ at seealso{@ref{doc-meshgrid,,meshgrid}, @ref{doc-mesh,,mesh}, @ref{doc-contour,,contour}}
+ at end deftypefn
+
+
+ at c ./plot/hidden.m
+ at anchor{doc-hidden}
+ at deftypefn {Function File} {} hidden (@var{mode})
+ at deftypefnx {Function File} {} hidden ()
+Manipulation the mesh hidden line removal.  Called with no argument
+the hidden line removal is toggled.  The argument @var{mode} can be either
+'on' or 'off' and the set of the hidden line removal is set accordingly.
+ at seealso{@ref{doc-mesh,,mesh}, @ref{doc-meshc,,meshc}, @ref{doc-surf,,surf}}
+ at end deftypefn
+
+
+ at c ./plot/surf.m
+ at anchor{doc-surf}
+ at deftypefn {Function File} {} surf (@var{x}, @var{y}, @var{z})
+Plot a surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+correspond to different @var{x} values and rows of @var{z} correspond
+to different @var{y} values.
+ at seealso{@ref{doc-mesh,,mesh}, @ref{doc-surface,,surface}}
+ at end deftypefn
+
+
+ at c ./plot/surfc.m
+ at anchor{doc-surfc}
+ at deftypefn {Function File} {} surfc (@var{x}, @var{y}, @var{z})
+Plot a surface and contour given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.
+ at seealso{@ref{doc-meshgrid,,meshgrid}, @ref{doc-surf,,surf}, @ref{doc-contour,,contour}}
+ at end deftypefn
+
+
+ at c ./plot/surfl.m
+ at anchor{doc-surfl}
+ at deftypefn {Function File} {} surfl (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} surfl (@var{z})
+ at deftypefnx {Function File} {} surfl (@var{x}, @var{y}, @var{z}, @var{L})
+ at deftypefnx {Function File} {} surfl (@var{x}, @var{y}, @var{z}, @var{L}, @var{P})
+ at deftypefnx {Function File} {} surfl (@dots{},"light")
+Plot a lighted surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+correspond to different @var{x} values and rows of @var{z} correspond
+to different @var{y} values.
+
+The light direction can be specified using @var{L}.  It can be
+given as 2-element vector [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz].
+The default value is rotated 45° counter-clockwise from the current view.
+
+The material properties of the surface can specified using a 4-element vector
+ at var{P} = [@var{AM} @var{D} @var{SP} @var{exp}] which defaults to
+ at var{p} = [0.55 0.6 0.4 10]. 
+ at table @code
+ at item "AM" strength of ambient light
+ at item "D" strength of diffuse reflection
+ at item "SP" strength of specular reflection
+ at item "EXP" specular exponent
+ at end table
+
+The default lighting mode "cdata", changes the cdata property to give the impression
+of a lighted surface.  Please note: the alternative "light" mode, which creates a light
+object to illuminate the surface is not implemented (yet).
+
+Example:
+
+ at example
+ at group
+colormap(bone);
+surfl(peaks);
+shading interp;
+ at end group
+ at end example
+ at seealso{@ref{doc-surf,,surf}, @ref{doc-diffuse,,diffuse}, @ref{doc-specular,,specular}, @ref{doc-surface,,surface}}
+ at end deftypefn
+
+
+ at c ./plot/surfnorm.m
+ at anchor{doc-surfnorm}
+ at deftypefn {Function File} {} surfnorm (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} surfnorm (@var{z})
+ at deftypefnx {Function File} {[@var{nx}, @var{ny}, @var{nz}] =} surfnorm (@dots{})
+ at deftypefnx {Function File} {} surfnorm (@var{h}, @dots{})
+Find the vectors normal to a meshgridded surface.  The meshed gridded 
+surface is defined by @var{x}, @var{y}, and @var{z}.  If @var{x} and 
+ at var{y} are not defined, then it is assumed that they are given by
+
+ at example
+ at group
+[@var{x}, @var{y}] = meshgrid (1:size(@var{z}, 1), 
+                     1:size(@var{z}, 2));
+ at end group
+ at end example
+
+If no return arguments are requested, a surface plot with the normal 
+vectors to the surface is plotted.  Otherwise the components of the normal
+vectors at the mesh gridded points are returned in @var{nx}, @var{ny},
+and @var{nz}.
+
+The normal vectors are calculated by taking the cross product of the 
+diagonals of each of the quadrilaterals in the meshgrid to find the 
+normal vectors of the centers of these quadrilaterals.  The four nearest
+normal vectors to the meshgrid points are then averaged to obtain the 
+normal to the surface at the meshgridded points.
+
+An example of the use of @code{surfnorm} is
+
+ at example
+surfnorm (peaks (25));
+ at end example
+ at seealso{@ref{doc-surf,,surf}, @ref{doc-quiver3,,quiver3}}
+ at end deftypefn
+
+
+ at c ./plot/diffuse.m
+ at anchor{doc-diffuse}
+ at deftypefn {Function File} {} diffuse (@var{sx}, @var{sy}, @var{sz}, @var{l})
+Calculate diffuse reflection strength of a surface defined by the normal
+vector elements @var{sx}, @var{sy}, @var{sz}. 
+The light vector can be specified using parameter @var{L}.  It can be
+given as 2-element vector [azimuth, elevation] in degrees or as 3-element
+vector [lx, ly, lz]. 
+ at seealso{@ref{doc-specular,,specular}, @ref{doc-surfl,,surfl}}
+ at end deftypefn
+
+
+ at c ./plot/specular.m
+ at anchor{doc-specular}
+ at deftypefn {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{l}, @var{v})
+ at deftypefnx {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{l}, @var{v}, @var{se})
+Calculate specular reflection strength of a surface defined by the normal
+vector elements @var{sx}, @var{sy}, @var{sz} using Phong's approximation. 
+The light and view vectors can be specified using parameter @var{L} and @var{V} respectively.
+Both can be given as 2-element vectors [azimuth, elevation] in degrees or as 3-element
+vector [x, y, z].  An optional 6th argument describes the specular exponent (spread) @var{se}.
+ at seealso{@ref{doc-surfl,,surfl}, @ref{doc-diffuse,,diffuse}}
+ at end deftypefn
+
+
+ at c ./plot/meshgrid.m
+ at anchor{doc-meshgrid}
+ at deftypefn {Function File} {[@var{xx}, @var{yy}, @var{zz}] =} meshgrid (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {[@var{xx}, @var{yy}] =} meshgrid (@var{x}, @var{y})
+ at deftypefnx {Function File} {[@var{xx}, @var{yy}] =} meshgrid (@var{x})
+Given vectors of @var{x} and @var{y} and @var{z} coordinates, and
+returning 3 arguments, return three-dimensional arrays corresponding
+to the @var{x}, @var{y}, and @var{z} coordinates of a mesh.  When
+returning only 2 arguments, return matrices corresponding to the
+ at var{x} and @var{y} coordinates of a mesh.  The rows of @var{xx} are
+copies of @var{x}, and the columns of @var{yy} are copies of @var{y}.
+If @var{y} is omitted, then it is assumed to be the same as @var{x},
+and @var{z} is assumed the same as @var{y}.
+ at seealso{@ref{doc-mesh,,mesh}, @ref{doc-contour,,contour}}
+ at end deftypefn
+
+
+ at c ./plot/ndgrid.m
+ at anchor{doc-ndgrid}
+ at deftypefn {Function File} {[@var{y1}, @var{y2}, @dots{},  @var{y}n] =} ndgrid (@var{x1}, @var{x2}, @dots{}, @var{x}n)
+ at deftypefnx {Function File} {[@var{y1}, @var{y2}, @dots{},  @var{y}n] =} ndgrid (@var{x})
+Given n vectors @var{x1}, @dots{} @var{x}n, @code{ndgrid} returns
+n arrays of dimension n. The elements of the i-th output argument
+contains the elements of the vector @var{x}i repeated over all
+dimensions different from the i-th dimension.  Calling ndgrid with
+only one input argument @var{x} is equivalent of calling ndgrid with
+all n input arguments equal to @var{x}:
+
+[@var{y1}, @var{y2}, @dots{},  @var{y}n] = ndgrid (@var{x}, @dots{}, @var{x})
+ at seealso{@ref{doc-meshgrid,,meshgrid}}
+ at end deftypefn
+
+
+ at c ./plot/plot3.m
+ at anchor{doc-plot3}
+ at deftypefn {Function File} {} plot3 (@var{args})
+Produce three-dimensional plots.  Many different combinations of
+arguments are possible.  The simplest form is
+
+ at example
+plot3 (@var{x}, @var{y}, @var{z})
+ at end example
+
+ at noindent
+in which the arguments are taken to be the vertices of the points to
+be plotted in three dimensions.  If all arguments are vectors of the
+same length, then a single continuous line is drawn.  If all arguments
+are matrices, then each column of the matrices is treated as a
+separate line.  No attempt is made to transpose the arguments to make
+the number of rows match.
+
+If only two arguments are given, as
+
+ at example
+plot3 (@var{x}, @var{c})
+ at end example
+
+ at noindent
+the real and imaginary parts of the second argument are used
+as the @var{y} and @var{z} coordinates, respectively.
+
+If only one argument is given, as
+
+ at example
+plot3 (@var{c})
+ at end example
+
+ at noindent
+the real and imaginary parts of the argument are used as the @var{y}
+and @var{z} values, and they are plotted versus their index.
+
+Arguments may also be given in groups of three as
+
+ at example
+plot3 (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2}, @dots{})
+ at end example
+
+ at noindent
+in which each set of three arguments is treated as a separate line or
+set of lines in three dimensions.
+
+To plot multiple one- or two-argument groups, separate each group
+with an empty format string, as
+
+ at example
+plot3 (@var{x1}, @var{c1}, "", @var{c2}, "", @dots{})
+ at end example
+
+An example of the use of @code{plot3} is
+
+ at example
+ at group
+   z = [0:0.05:5];
+   plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+   plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
+ at end group
+ at end example
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-xlabel,,xlabel}, @ref{doc-ylabel,,ylabel}, @ref{doc-zlabel,,zlabel}, @ref{doc-title,,title}, @ref{doc-print,,print}}
+ at end deftypefn
+
+
+ at c ./plot/view.m
+ at anchor{doc-view}
+ at deftypefn {Function File} {} view (@var{azimuth}, @var{elevation})
+ at deftypefnx {Function File} {} view (@var{dims})
+ at deftypefnx {Function File} {[@var{azimuth}, @var{elevation}] =} view ()
+Set or get the viewpoint for the current axes.
+ at end deftypefn
+
+
+ at c ./plot/slice.m
+ at anchor{doc-slice}
+ at deftypefn {Function File} {} slice (@var{x}, @var{y}, @var{z}, @var{v}, @var{sx}, @var{sy}, @var{sz})
+ at deftypefnx {Function File} {} slice (@var{x}, @var{y}, @var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {} slice (@var{v}, @var{sx}, @var{sy}, @var{sz})
+ at deftypefnx {Function File} {} slice (@var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {@var{h} =} slice (@dots{})
+ at deftypefnx {Function File} {@var{h} =} slice (@dots{}, @var{method})
+Plot slices of 3D data/scalar fields.  Each element of the 3-dimensional 
+array @var{v} represents a scalar value at a location given by the
+parameters @var{x}, @var{y}, and @var{z}.  The parameters @var{x},
+ at var{x}, and @var{z} are either 3-dimensional arrays of the same size
+as the array @var{v} in the "meshgrid" format or vectors.  The
+parameters @var{xi}, etc. respect a similar format to @var{x}, etc.,
+and they represent the points at which the array @var{vi} is
+interpolated using interp3.  The vectors @var{sx}, @var{sy}, and
+ at var{sz} contain points of orthogonal slices of the respective axes.
+
+If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be 
+ at code{x = 1:size (@var{v}, 2)}, @code{y = 1:size (@var{v}, 1)} and
+ at code{z = 1:size (@var{v}, 3)}. 
+
+ at var{Method} is one of:
+
+ at table @code
+ at item "nearest"
+Return the nearest neighbor.
+ at item "linear"
+Linear interpolation from nearest neighbors.
+ at item "cubic"
+Cubic interpolation from four nearest neighbors (not implemented yet).
+ at item "spline"
+Cubic spline interpolation---smooth first and second derivatives
+throughout the curve.
+ at end table
+
+The default method is @code{"linear"}.
+The optional return value @var{h} is a vector of handles to the
+surface graphic objects.
+
+Examples:
+ at example
+ at group
+[x, y, z] = meshgrid (linspace (-8, 8, 32));
+v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+slice (x, y, z, v, [], 0, []);
+[xi, yi] = meshgrid (linspace (-7, 7));
+zi = xi + yi;
+slice (x, y, z, v, xi, yi, zi);
+ at end group
+ at end example
+ at seealso{@ref{doc-interp3,,interp3}, @ref{doc-surface,,surface}, @ref{doc-pcolor,,pcolor}}
+ at end deftypefn
+
+
+ at c ./plot/ribbon.m
+ at anchor{doc-ribbon}
+ at deftypefn  {Function File} {} ribbon (@var{x}, @var{y}, @var{width})
+ at deftypefnx {Function File} {} ribbon (@var{y})
+ at deftypefnx {Function File} {@var{h} =} ribbon (@dots{})
+Plot a ribbon plot for the columns of @var{y} vs.  @var{x}.  The
+optional parameter @var{width} specifies the width of a single ribbon
+(default is 0.75).  If @var{x} is omitted, a vector containing the
+row numbers is assumed (1:rows(Y)).  If requested, return a vector
+ at var{h} of the handles to the surface objects.
+ at seealso{@ref{doc-gca,,gca}, @ref{doc-colorbar,,colorbar}}
+ at end deftypefn
+
+
+ at c ./plot/shading.m
+ at anchor{doc-shading}
+ at deftypefn {Function File} {} shading (@var{type})
+ at deftypefnx {Function File} {} shading (@var{ax}, @dots{})
+Set the shading of surface or patch graphic objects.  Valid arguments
+for @var{type} are
+
+ at table @code
+ at item "flat"
+Single colored patches with invisible edges.
+
+ at item "faceted"
+Single colored patches with visible edges.
+
+ at item "interp"
+Color between patch vertices are interpolated and the patch edges are
+invisible.
+ at end table
+
+If @var{ax} is given the shading is applied to axis @var{ax} instead
+of the current axis.
+ at end deftypefn
+
+
+ at menu
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
+ at end menu
+
+ at node Three-dimensional Function Plotting
+ at subsubsection Three-dimensional Function Plotting
+
+ at c ./plot/ezplot3.m
+ at anchor{doc-ezplot3}
+ at deftypefn {Function File} {} ezplot3 (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezplot3 (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezplot3 (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezplot3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezplot3 (@dots{})
+
+Plots in three-dimensions the curve defined parametrically. 
+ at var{fx}, @var{fy}, and @var{fz} are strings, inline functions
+or function handles with one arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi}  
+with 60 points. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of @var{t}.  @var{n} is a scalar defining the number of points to use.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+fx = @@(t) cos (t);
+fy = @@(t) sin (t);
+fz = @@(t) t;
+ezplot3 (fx, fy, fz, [0, 10*pi], 100);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-plot3,,plot3}, @ref{doc-ezplot,,ezplot}, @ref{doc-ezsurf,,ezsurf}, @ref{doc-ezmesh,,ezmesh}}
+ at end deftypefn
+
+
+ at c ./plot/ezmesh.m
+ at anchor{doc-ezmesh}
+ at deftypefn {Function File} {} ezmesh (@var{f})
+ at deftypefnx {Function File} {} ezmesh (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezmesh (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezmesh (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezmesh (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezmesh (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezmesh (@dots{})
+
+Plots the mesh defined by a function.  @var{f} is a string, inline
+function or function handle with two arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezmesh (f, [-3, 3]);
+ at end group
+ at end example
+
+An example of a parametrically defined function is
+
+ at example
+ at group
+fx = @@(s,t) cos (s) .* cos(t);
+fy = @@(s,t) sin (s) .* cos(t);
+fz = @@(s,t) sin(t);
+ezmesh (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ezplot,,ezplot}, @ref{doc-ezsurf,,ezsurf}, @ref{doc-ezsurfc,,ezsurfc}, @ref{doc-ezmeshc,,ezmeshc}}
+ at end deftypefn
+
+
+ at c ./plot/ezmeshc.m
+ at anchor{doc-ezmeshc}
+ at deftypefn {Function File} {} ezmeshc (@var{f})
+ at deftypefnx {Function File} {} ezmeshc (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezmeshc (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezmeshc (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezmeshc (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezmeshc (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezmeshc (@dots{})
+
+Plots the mesh and contour lines defined by a function.  @var{f} is a string,
+inline function or function handle with two arguments defining the function.
+By default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezmeshc (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ezplot,,ezplot}, @ref{doc-ezsurfc,,ezsurfc}, @ref{doc-ezsurf,,ezsurf}, @ref{doc-ezmesh,,ezmesh}}
+ at end deftypefn
+
+
+ at c ./plot/ezsurf.m
+ at anchor{doc-ezsurf}
+ at deftypefn {Function File} {} ezsurf (@var{f})
+ at deftypefnx {Function File} {} ezsurf (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezsurf (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezsurf (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezsurf (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezsurf (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezsurf (@dots{})
+
+Plots the surface defined by a function.  @var{f} is a string, inline
+function or function handle with two arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezsurf (f, [-3, 3]);
+ at end group
+ at end example
+
+An example of a parametrically defined function is
+
+ at example
+ at group
+fx = @@(s,t) cos (s) .* cos(t);
+fy = @@(s,t) sin (s) .* cos(t);
+fz = @@(s,t) sin(t);
+ezsurf (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ezplot,,ezplot}, @ref{doc-ezmesh,,ezmesh}, @ref{doc-ezsurfc,,ezsurfc}, @ref{doc-ezmeshc,,ezmeshc}}
+ at end deftypefn
+
+
+ at c ./plot/ezsurfc.m
+ at anchor{doc-ezsurfc}
+ at deftypefn {Function File} {} ezsurfc (@var{f})
+ at deftypefnx {Function File} {} ezsurfc (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezsurfc (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezsurfc (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezsurfc (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezsurfc (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezsurfc (@dots{})
+
+Plots the surface and contour lines defined by a function.  @var{f} is a
+string, inline function or function handle with two arguments defining the
+function.  By default the plot is over the domain @code{-2*pi < @var{x} <
+2*pi} and @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezsurfc (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-ezplot,,ezplot}, @ref{doc-ezmeshc,,ezmeshc}, @ref{doc-ezsurf,,ezsurf}, @ref{doc-ezmesh,,ezmesh}}
+ at end deftypefn
+
+
+ at node Three-dimensional Geometric Shapes
+ at subsubsection Three-dimensional Geometric Shapes
+
+ at c ./plot/cylinder.m
+ at anchor{doc-cylinder}
+ at deftypefn {Function File} {} cylinder
+ at deftypefnx {Function File} {} cylinder (@var{r})
+ at deftypefnx {Function File} {} cylinder (@var{r}, @var{n})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} cylinder (@dots{})
+ at deftypefnx {Function File} {} cylinder (@var{ax}, @dots{})
+Generates three matrices in @code{meshgrid} format, such that
+ at code{surf (@var{x}, @var{y}, @var{z})} generates a unit cylinder.
+The matrices are of size @code{@var{n}+1}-by- at code{@var{n}+1}. 
+ at var{r} is a vector containing the radius along the z-axis.
+If @var{n} or @var{r} are omitted then default values of 20 or [1 1]
+are assumed.
+
+Called with no return arguments, @code{cylinder} calls directly
+ at code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle @var{ax}
+is passed as the first argument, the surface is plotted to this set
+of axes.
+
+Examples:
+ at example
+ at group
+disp ("plotting a cone")
+[x, y, z] = cylinder (10:-1:0,50);
+surf (x, y, z);
+ at end group
+ at end example
+ at seealso{@ref{doc-sphere,,sphere}}
+ at end deftypefn
+
+
+ at c ./plot/sphere.m
+ at anchor{doc-sphere}
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sphere (@var{n})
+ at deftypefnx {Function File} {} sphere (@var{h}, @dots{})
+Generates three matrices in @code{meshgrid} format, such that 
+ at code{surf (@var{x}, @var{y}, @var{z})} generates a unit sphere. 
+The matrices of @code{@var{n}+1}-by- at code{@var{n}+1}.  If @var{n} is 
+omitted then a default value of 20 is assumed.
+
+Called with no return arguments, @code{sphere} call directly 
+ at code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle is passed
+as the first argument, the surface is plotted to this set of axes.
+ at seealso{@ref{doc-peaks,,peaks}}
+ at end deftypefn
+
+
+ at c ./plot/ellipsoid.m
+ at anchor{doc-ellipsoid}
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} ellipsoid (@var{xc}, at var{yc}, @var{zc}, @var{xr}, @var{yr}, @var{zr}, @var{n})
+ at deftypefnx {Function File} {} ellipsoid (@var{h}, @dots{})
+Generate three matrices in @code{meshgrid} format that define an
+ellipsoid.  Called with no return arguments, @code{ellipsoid} calls
+directly @code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle
+is passed as the first argument, the surface is plotted to this
+set of axes.
+ at seealso{@ref{doc-sphere,,sphere}}
+ at end deftypefn
+
+
+ at node Plot Annotations
+ at subsection Plot Annotations
+
+You can add titles, axis labels, legends, and arbitrary text to an
+existing plot.  For example,
+
+ at example
+ at group
+x = -10:0.1:10;
+plot (x, sin (x));
+title ("sin(x) for x = -10:0.1:10");
+xlabel ("x");
+ylabel ("sin (x)");
+text (pi, 0.7, "arbitrary text");
+legend ("sin (x)");
+ at end group
+ at end example
+
+The functions @code{grid} and @code{box} may also be used to add grid
+and border lines to the plot.  By default, the grid is off and the
+border lines are on.
+
+ at c ./plot/title.m
+ at anchor{doc-title}
+ at deftypefn {Function File} {} title (@var{title})
+ at deftypefnx {Function File} {} title (@var{title}, @var{p1}, @var{v1}, @dots{})
+Create a title object and return a handle to it.
+ at end deftypefn
+
+
+ at c ./plot/legend.m
+ at anchor{doc-legend}
+ at deftypefn {Function File} {} legend (@var{st1}, @var{st2}, @dots{})
+ at deftypefnx {Function File} {} legend (@var{st1}, @var{st2}, @dots{}, "location", @var{pos})
+ at deftypefnx {Function File} {} legend (@var{matstr})
+ at deftypefnx {Function File} {} legend (@var{matstr}, "location", @var{pos})
+ at deftypefnx {Function File} {} legend (@var{cell})
+ at deftypefnx {Function File} {} legend (@var{cell}, "location", @var{pos})
+ at deftypefnx {Function File} {} legend ('@var{func}')
+
+Display a legend for the current axes using the specified strings
+as labels.  Legend entries may be specified as individual character
+string arguments, a character array, or a cell array of character
+strings.  Legend works on line graphs, bar graphs, etc.  A plot must
+exist before legend is called.
+
+The optional parameter @var{pos} specifies the location of the legend
+as follows:
+
+ at multitable @columnfractions 0.06 0.14 0.80
+ at item @tab north @tab
+  center top
+ at item @tab south @tab
+  center bottom
+ at item @tab east @tab
+  right center
+ at item @tab west @tab
+  left center
+ at item @tab northeast @tab
+  right top (default)
+ at item @tab northwest @tab
+  left top
+ at item @tab southeast @tab
+  right bottom
+ at item @tab southwest @tab
+  left bottom
+ at item 
+ at item @tab outside @tab
+  can be appended to any location string
+ at end multitable
+
+Some specific functions are directly available using @var{func}:
+
+ at table @asis
+ at item "show"
+  Show legends from the plot
+ at item "hide"
+ at itemx "off"
+  Hide legends from the plot
+ at item "boxon"
+  Draw a box around legends
+ at item "boxoff"
+  Withdraw the box around legends
+ at item "left"
+  Text is to the left of the keys
+ at item "right"
+  Text is to the right of the keys
+ at end table
+ at end deftypefn
+
+
+ at c ./plot/text.m
+ at anchor{doc-text}
+ at deftypefn {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{label})
+ at deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{z}, @var{label})
+ at deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{label}, @var{p1}, @var{v1}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{z}, @var{label}, @var{p1}, @var{v1}, @dots{})
+Create a text object with text @var{label} at position @var{x},
+ at var{y}, @var{z} on the current axes.  Property-value pairs following
+ at var{label} may be used to specify the appearance of the text.
+ at end deftypefn
+
+
+See @ref{Text Properties} for the properties that you can set.
+
+ at anchor{doc-ylabel}
+ at anchor{doc-zlabel}
+ at c ./plot/xlabel.m
+ at anchor{doc-xlabel}
+ at deftypefn {Function File} {} xlabel (@var{string})
+ at deftypefnx {Function File} {} ylabel (@var{string})
+ at deftypefnx {Function File} {} zlabel (@var{string})
+ at deftypefnx {Function File} {} xlabel (@var{h}, @var{string})
+Specify x, y, and z axis labels for the current figure.  If @var{h} is
+specified then label the axis defined by @var{h}.
+ at seealso{@ref{doc-plot,,plot}, @ref{doc-semilogx,,semilogx}, @ref{doc-semilogy,,semilogy}, @ref{doc-loglog,,loglog}, @ref{doc-polar,,polar}, @ref{doc-mesh,,mesh}, @ref{doc-contour,,contour}, @ref{doc-bar,,bar}, @ref{doc-stairs,,stairs}, @ref{doc-title,,title}}
+ at end deftypefn
+
+
+ at c ./plot/clabel.m
+ at anchor{doc-clabel}
+ at deftypefn {Function File} {} clabel (@var{c}, @var{h})
+ at deftypefnx {Function File} {} clabel (@var{c}, @var{h}, @var{v})
+ at deftypefnx {Function File} {} clabel (@var{c}, @var{h}, "manual")
+ at deftypefnx {Function File} {} clabel (@var{c})
+ at deftypefnx {Function File} {} clabel (@var{c}, @var{h})
+ at deftypefnx {Function File} {} clabel (@dots{}, @var{prop}, @var{val}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} clabel (@dots{})
+Adds labels to the contours of a contour plot.  The contour plot is specified
+by the contour matrix @var{c} and optionally the contourgroup object @var{h}
+that are returned by @code{contour}, @code{contourf} and @code{contour3}.
+The contour labels are rotated and placed in the contour itself.
+
+By default, all contours are labelled.  However, the contours to label can be
+specified by the vector @var{v}.  If the "manual" argument is given then
+the contours to label can be selected with the mouse.
+
+Additional property/value pairs that are valid properties of text objects
+can be given and are passed to the underlying text objects.  Additionally,
+the property "LabelSpacing" is available allowing the spacing between labels
+on a contour (in points) to be specified.  The default is 144 points, or 2
+inches.
+
+The returned value @var{h} is the set of text object that represent the
+contour labels.  The "userdata" property of the text objects contains the
+numerical value of the contour label.
+
+An example of the use of @code{clabel} is
+
+ at example
+ at group
+[c, h] = contour (peaks(), -4 : 6);
+clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+ at end group
+ at end example
+
+ at seealso{@ref{doc-contour,,contour}, @ref{doc-contourf,,contourf}, @ref{doc-contour3,,contour3}, @ref{doc-meshc,,meshc}, @ref{doc-surfc,,surfc}, @ref{doc-text,,text}}
+ at end deftypefn
+
+
+ at c ./plot/box.m
+ at anchor{doc-box}
+ at deftypefn {Function File} {} box (@var{arg})
+ at deftypefnx {Function File} {} box (@var{h}, @dots{})
+Control the display of a border around the plot.
+The argument may be either @code{"on"} or @code{"off"}.  If it is
+omitted, the current box state is toggled.
+ at seealso{@ref{doc-grid,,grid}}
+ at end deftypefn
+
+
+ at c ./plot/grid.m
+ at anchor{doc-grid}
+ at deftypefn {Function File} {} grid (@var{arg})
+ at deftypefnx {Function File} {} grid ("minor", @var{arg2})
+ at deftypefnx {Function File} {} grid (@var{hax}, @dots{})
+Force the display of a grid on the plot.
+The argument may be either @code{"on"}, or @code{"off"}.
+If it is omitted, the current grid state is toggled.
+
+If @var{arg} is @code{"minor"} then the minor grid is toggled.  When
+using a minor grid a second argument @var{arg2} is allowed, which can
+be either @code{"on"} or @code{"off"} to explicitly set the state of
+the minor grid.
+
+If the first argument is an axis handle, @var{hax}, operate on the
+specified axis object.
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./plot/colorbar.m
+ at anchor{doc-colorbar}
+ at deftypefn {Function File} {} colorbar (@var{s})
+ at deftypefnx {Function File} {} colorbar ("peer", @var{h}, @dots{})
+Adds a colorbar to the current axes.  Valid values for @var{s} are
+
+ at table @asis
+ at item "EastOutside"
+Place the colorbar outside the plot to the right.  This is the default.
+ at item "East"
+Place the colorbar inside the plot to the right.
+ at item "WestOutside"
+Place the colorbar outside the plot to the left.
+ at item "West"
+Place the colorbar inside the plot to the left.
+ at item "NorthOutside"
+Place the colorbar above the plot.
+ at item "North"
+Place the colorbar at the top of the plot.
+ at item "SouthOutside"
+Place the colorbar under the plot.
+ at item "South"
+Place the colorbar at the bottom of the plot.
+ at item "Off", "None"
+Remove any existing colorbar from the plot.
+ at end table
+
+If the argument "peer" is given, then the following argument is treated
+as the axes handle on which to add the colorbar.
+ at end deftypefn
+
+
+ at node Multiple Plots on One Page
+ at subsection Multiple Plots on One Page
+
+Octave can display more than one plot in a single figure.  The simplest
+way to do this is to use the @code{subplot} function to divide the plot
+area into a series of subplot windows that are indexed by an integer.
+For example,
+
+ at example
+ at group
+subplot (2, 1, 1)
+fplot (@@sin, [-10, 10]);
+subplot (2, 1, 2)
+fplot (@@cos, [-10, 10]);
+ at end group
+ at end example
+
+ at noindent
+creates a figure with two separate axes, one displaying a sine wave and
+the other a cosine wave.  The first call to subplot divides the figure
+into two plotting areas (two rows and one column) and makes the first plot
+area active.  The grid of plot areas created by @code{subplot} is
+numbered in column-major order (top to bottom, left to right).
+
+ at c ./plot/subplot.m
+ at anchor{doc-subplot}
+ at deftypefn {Function File} {} subplot (@var{rows}, @var{cols}, @var{index})
+ at deftypefnx {Function File} {} subplot (@var{rcn})
+Set up a plot grid with @var{cols} by @var{rows} subwindows and plot
+in location given by @var{index}.
+
+If only one argument is supplied, then it must be a three digit value
+specifying the location in digits 1 (rows) and 2 (columns) and the plot
+index in digit 3.
+
+The plot index runs row-wise.  First all the columns in a row are filled
+and then the next row is filled.
+
+For example, a plot with 2 by 3 grid will have plot indices running as
+follows:
+ at tex
+\vskip 10pt
+\hfil\vbox{\offinterlineskip\hrule
+\halign{\vrule#&&\qquad\hfil#\hfil\qquad\vrule\cr
+height13pt&1&2&3\cr height12pt&&&\cr\noalign{\hrule}
+height13pt&4&5&6\cr height12pt&&&\cr\noalign{\hrule}}}
+\hfil
+\vskip 10pt
+ at end tex
+ at ifnottex
+ at display
+ at example
+ at group
+
++-----+-----+-----+
+|  1  |  2  |  3  |
++-----+-----+-----+
+|  4  |  5  |  6  |
++-----+-----+-----+
+ at end group
+ at end example
+ at end display
+ at end ifnottex
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at node Multiple Plot Windows
+ at subsection Multiple Plot Windows
+
+You can open multiple plot windows using the @code{figure} function.
+For example
+
+ at example
+ at group
+figure (1);
+fplot (@@sin, [-10, 10]);
+figure (2);
+fplot (@@cos, [-10, 10]);
+ at end group
+ at end example
+
+ at noindent
+creates two figures, with the first displaying a sine wave and
+the second a cosine wave.  Figure numbers must be positive integers.
+
+ at c ./plot/figure.m
+ at anchor{doc-figure}
+ at deftypefn {Function File} {} figure (@var{n})
+ at deftypefnx {Function File} {} figure (@var{n}, @var{property}, @var{value}, @dots{})
+Set the current plot window to plot window @var{n}.  If no arguments are
+specified, the next available window number is chosen.
+
+Multiple property-value pairs may be specified for the figure, but they
+must appear in pairs.
+ at end deftypefn
+
+
+ at node Printing Plots
+ at subsection Printing Plots
+
+The @code{print} command allows you to save plots in a variety of
+formats.  For example,
+
+ at example
+print -deps foo.eps
+ at end example
+
+ at noindent
+writes the current figure to an encapsulated PostScript file called
+ at file{foo.eps}.
+
+ at c ./plot/print.m
+ at anchor{doc-print}
+ at deftypefn {Function File} {} print ()
+ at deftypefnx {Function File} {} print (@var{options})
+ at deftypefnx {Function File} {} print (@var{filename}, @var{options})
+ at deftypefnx {Function File} {} print (@var{h}, @var{filename}, @var{options})
+Print a graph, or save it to a file
+
+ at var{filename} defines the file name of the output file.  If no
+filename is specified, the output is sent to the printer.
+
+ at var{h} specifies the figure handle.  If no handle is specified
+the handle for the current figure is used.
+
+ at var{options}:
+ at table @code
+ at item -P at var{printer}
+  Set the @var{printer} name to which the graph is sent if no
+ at var{filename} is specified.
+ at item -G at var{ghostscript_command}
+  Specify the command for calling Ghostscript.  For Unix and Windows,
+the defaults are 'gs' and 'gswin32c', respectively.
+ at item -color
+ at itemx -mono
+  Monochrome or color lines.
+ at item -solid
+ at itemx -dashed
+  Solid or dashed lines.
+ at item -portrait
+ at itemx -landscape
+  Specify the orientation of the plot for printed output.
+ at item -d at var{device}
+  Output device, where @var{device} is one of:
+ at table @code
+ at item ps
+ at itemx ps2
+ at itemx psc
+ at itemx psc2
+    Postscript (level 1 and 2, mono and color)
+ at item eps
+ at itemx eps2
+ at itemx epsc
+ at itemx epsc2
+    Encapsulated postscript (level 1 and 2, mono and color)
+ at item tex
+ at itemx epslatex
+ at itemx epslatexstandalone
+ at itemx pstex
+ at itemx pslatex
+    Generate a @LaTeX{} (or @TeX{}) file for labels, and eps/ps for
+graphics.  The file produced by @code{epslatexstandalone} can be
+processed directly by @LaTeX{}.  The other formats are intended to
+be included in a @LaTeX{} (or @TeX{}) document.  The @code{tex} device
+is the same as the @code{epslatex} device.
+ at item ill
+ at itemx aifm
+    Adobe Illustrator
+ at item cdr
+ at itemx corel
+    CorelDraw
+ at item dxf
+    AutoCAD
+ at item emf
+ at itemx meta
+    Microsoft Enhanced Metafile
+ at item fig
+    XFig.  If this format is selected the additional options
+ at code{-textspecial} or @code{-textnormal} can be used to control
+    whether the special flag should be set for the text in
+    the figure (default is @code{-textnormal}). 
+ at item hpgl
+    HP plotter language
+ at item mf
+    Metafont
+ at item png
+    Portable network graphics
+ at item jpg
+ at itemx jpeg
+    JPEG image
+ at item gif
+    GIF image
+ at item pbm
+    PBMplus
+ at item svg
+    Scalable vector graphics
+ at item pdf
+    Portable document format
+ at end table
+
+  If the device is omitted, it is inferred from the file extension,
+or if there is no filename it is sent to the printer as postscript.
+
+ at item -d at var{gs_device}
+  Additional devices are supported by Ghostscript.
+Some examples are;
+
+ at table @code
+ at item ljet2p 
+    HP LaserJet IIP
+ at item ljet3 
+    HP LaserJet III
+ at item deskjet
+    HP DeskJet and DeskJet Plus
+ at item cdj550
+    HP DeskJet 550C
+ at item paintjet
+    HP PointJet
+ at item pcx24b
+    24-bit color PCX file format
+ at item ppm
+    Portable Pixel Map file format
+ at end table
+
+  For a complete list, type `system ("gs -h")' to see what formats
+and devices are available.
+
+  When the ghostscript is sent to a printer the size is determined
+by the figure's "papersize" property.  When the ghostscript output 
+is sent to a file the size is determined by the figure's
+"paperposition" property.
+
+ at itemx -r at var{NUM}
+  Resolution of bitmaps in pixels per inch.  For both metafiles and 
+SVG the default is the screen resolution, for other it is 150 dpi.
+To specify screen resolution, use "-r0".
+
+ at item -tight
+  Forces a tight bounding box for eps-files.  Since the ghostscript
+devices are conversion of an eps-file, this option works the those
+devices as well.
+
+ at itemx -S at var{xsize}, at var{ysize}
+  Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG.  If
+using the command form of the print function, you must quote the
+ at var{xsize}, at var{ysize} option.  For example, by writing
+ at w{@code{"-S640,480"}}.  The size defaults to that specified by the
+figure's paperposition property.
+
+ at item -F at var{fontname}
+ at itemx -F at var{fontname}:@var{size}
+ at itemx -F:@var{size}
+ at var{fontname} set the postscript font (for use with postscript,
+aifm, corel and fig).  By default, 'Helvetica' is set for PS/Aifm,
+and 'SwitzerlandLight' for Corel.  It can also be 'Times-Roman'.
+ at var{size} is given in points.  @var{fontname} is ignored for the
+fig device.
+ at end table
+
+The filename and options can be given in any order.
+ at end deftypefn
+
+
+ at c ./plot/orient.m
+ at anchor{doc-orient}
+ at deftypefn {Function File} {} orient (@var{orientation})
+Set the default print orientation.  Valid values for
+ at var{orientation} include @code{"landscape"}, @code{"portrait"}, 
+and @code{"tall"}.
+
+The @code{"tall"} option sets the orientation to portait and fills
+the page with the plot, while leaving a 0.25in border.
+
+If called with no arguments, return the default print orientation.
+ at end deftypefn
+
+
+ at node Interacting with plots
+ at subsection Interacting with plots
+
+The user can select points on a plot with the @code{ginput} function or
+selection the position at which to place text on the plot with the
+ at code{gtext} function using the mouse.
+
+ at c ./plot/ginput.m
+ at anchor{doc-ginput}
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} ginput (@var{n})
+Return which mouse buttons were pressed and keys were hit on the current
+figure.  If @var{n} is defined, then wait for @var{n} mouse clicks
+before returning.  If @var{n} is not defined, then @code{ginput} will
+loop until the return key is pressed.
+ at end deftypefn
+
+
+ at c ./plot/waitforbuttonpress.m
+ at anchor{doc-waitforbuttonpress}
+ at deftypefn {Function File} {@var{b} =} waitforbuttonpress ()
+Wait for button or mouse press.over a figure window.  The value of
+ at var{b} returns 0 if a mouse button was pressed or 1 is a key was
+pressed.
+ at seealso{@ref{doc-ginput,,ginput}}
+ at end deftypefn
+
+
+ at c ./plot/gtext.m
+ at anchor{doc-gtext}
+ at deftypefn  {Function File} {} gtext (@var{s})
+ at deftypefnx {Function File} {} gtext (@{@var{s1}; @var{s2}; @dots{}@})
+ at deftypefnx {Function File} {} gtext (@dots{}, @var{prop}, @var{val})
+Place text on the current figure using the mouse.  The text is defined
+by the string @var{s}.  If @var{s} is a cell array, each element of the cell
+array is written to a separate line.  Additional arguments are passed to
+the underlying text object as properties.
+ at seealso{@ref{doc-ginput,,ginput}, @ref{doc-text,,text}}
+ at end deftypefn
+
+
+ at node Test Plotting Functions
+ at subsection Test Plotting Functions
+
+The functions @code{sombrero} and @code{peaks} provide a way to check
+that plotting is working.  Typing either @code{sombrero} or @code{peaks}
+at the Octave prompt should display a three-dimensional plot.
+
+ at c ./plot/sombrero.m
+ at anchor{doc-sombrero}
+ at deftypefn {Function File} {} sombrero (@var{n})
+Produce the familiar three-dimensional sombrero plot using @var{n}
+grid lines.  If @var{n} is omitted, a value of 41 is assumed.
+
+The function plotted is
+
+ at example
+z = sin (sqrt (x^2 + y^2)) / (sqrt (x^2 + y^2))
+ at end example
+ at seealso{@ref{doc-surf,,surf}, @ref{doc-meshgrid,,meshgrid}, @ref{doc-mesh,,mesh}}
+ at end deftypefn
+
+
+ at c ./plot/peaks.m
+ at anchor{doc-peaks}
+ at deftypefn {Function File} {} peaks ()
+ at deftypefnx {Function File} {} peaks (@var{n})
+ at deftypefnx {Function File} {} peaks (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{z} =} peaks (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} peaks (@dots{})
+Generate a function with lots of local maxima and minima.  The function
+has the form
+
+ at tex
+$f(x,y) = 3 (1 - x) ^ 2 e ^ {\left(-x^2 - (y+1)^2\right)} - 10 \left({x \over 5} - x^3 - y^5)\right) - {1 \over 3} e^{\left(-(x+1)^2 - y^2\right)}$
+ at end tex
+ at ifnottex
+ at verbatim
+f(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) ...
+         - 10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) ...
+         - 1/3*exp(-(x+1)^2 - y^2)
+ at end verbatim
+ at end ifnottex
+
+Called without a return argument, @code{peaks} plots the surface of the 
+above function using @code{mesh}.  If @var{n} is a scalar, the @code{peaks}
+returns the values of the above function on a @var{n}-by- at var{n} mesh over
+the range @code{[-3,3]}.  The default value for @var{n} is 49.
+
+If @var{n} is a vector, then it represents the @var{x} and @var{y} values
+of the grid on which to calculate the above function.  The @var{x} and 
+ at var{y} values can be specified separately.
+ at seealso{@ref{doc-surf,,surf}, @ref{doc-mesh,,mesh}, @ref{doc-meshgrid,,meshgrid}}
+ at end deftypefn
+
+
+ at node Advanced Plotting
+ at section Advanced Plotting
+
+ at menu
+* Graphics Objects::
+* Graphics Object Properties::  
+* Managing Default Properties::  
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
+* Object Groups::
+* Graphics backends::
+ at end menu
+
+ at node Graphics Objects
+ at subsection Graphics Objects
+
+Plots in Octave are constructed from the following @dfn{graphics
+objects}.  Each graphics object has a set of properties that define its
+appearance and may also contain links to other graphics objects.
+Graphics objects are only referenced by a numeric index, or @dfn{handle}.
+
+ at table @asis
+ at item root figure
+ at cindex root figure graphics object
+ at cindex graphics object, root figure
+The parent of all figure objects.  The index for the root figure is
+defined to be 0.
+
+ at item figure
+ at cindex figure graphics object
+ at cindex graphics object, figure
+A figure window.
+
+ at item axes
+ at cindex axes graphics object
+ at cindex graphics object, axes
+A set of axes.  This object is a child of a figure object and may be a
+parent of line, text, image, patch, or surface objects.
+
+ at item line
+ at cindex line graphics object
+ at cindex graphics object, line
+A line in two or three dimensions.
+
+ at item text
+ at cindex text graphics object
+ at cindex graphics object, text
+Text annotations.
+
+ at item image
+ at cindex image graphics object
+ at cindex graphics object, image
+A bitmap image.
+
+ at item patch
+ at cindex patch graphics object
+ at cindex graphics object, patch
+A filled polygon, currently limited to two dimensions.
+
+ at item surface
+ at cindex surface graphics object
+ at cindex graphics object, surface 
+A three-dimensional surface.
+ at end table
+
+To determine whether a variable is a graphics object index or a figure
+index, use the functions @code{ishandle} and @code{isfigure}.
+
+ at c graphics.cc
+ at anchor{doc-ishandle}
+ at deftypefn {Built-in Function} {} ishandle (@var{h})
+Return true if @var{h} is a graphics handle and false otherwise.
+ at end deftypefn
+
+
+ at c ./plot/ishghandle.m
+ at anchor{doc-ishghandle}
+ at deftypefn {Function File} {} ishghandle (@var{h})
+Return true if @var{h} is a graphics handle and false otherwise.
+ at end deftypefn
+
+
+ at c ./plot/isfigure.m
+ at anchor{doc-isfigure}
+ at deftypefn {Function File} {} isfigure (@var{h})
+Return true if @var{h} is a graphics handle that contains a figure
+object and false otherwise.
+ at end deftypefn
+
+
+The function @code{gcf} returns an index to the current figure object,
+or creates one if none exists.  Similarly, @code{gca} returns the
+current axes object, or creates one (and its parent figure object) if
+none exists.
+
+ at c ./plot/gcf.m
+ at anchor{doc-gcf}
+ at deftypefn {Function File} {} gcf ()
+Return the current figure handle.  If a figure does not exist, create
+one and return its handle.  The handle may then be used to examine or
+set properties of the figure.  For example,
+
+ at example
+ at group
+fplot (@@sin, [-10, 10]);
+fig = gcf ();
+set (fig, "visible", "off");
+ at end group
+ at end example
+
+ at noindent
+plots a sine wave, finds the handle of the current figure, and then
+makes that figure invisible.  Setting the visible property of the
+figure to @code{"on"} will cause it to be displayed again.
+ at seealso{@ref{doc-get,,get}, @ref{doc-set,,set}}
+ at end deftypefn
+
+
+ at c ./plot/gca.m
+ at anchor{doc-gca}
+ at deftypefn {Function File} {} gca ()
+Return a handle to the current axis object.  If no axis object
+exists, create one and return its handle.  The handle may then be
+used to examine or set properties of the axes.  For example,
+
+ at example
+ at group
+ax = gca ();
+set (ax, "position", [0.5, 0.5, 0.5, 0.5]);
+ at end group
+ at end example
+
+ at noindent
+creates an empty axes object, then changes its location and size in
+the figure window.
+ at seealso{@ref{doc-get,,get}, @ref{doc-set,,set}}
+ at end deftypefn
+
+
+The @code{get} and @code{set} functions may be used to examine and set
+properties for graphics objects.  For example,
+
+ at example
+ at group
+get (0)
+    @result{} ans =
+       @{
+         type = root
+         currentfigure = [](0x0)
+         children = [](0x0)
+         visible = on
+			@dots{}
+       @}
+ at end group
+ at end example
+
+ at noindent
+returns a structure containing all the properties of the root figure.
+As with all functions in Octave, the structure is returned by value, so
+modifying it will not modify the internal root figure plot object.  To
+do that, you must use the @code{set} function.  Also, note that in this
+case, the @code{currentfigure} property is empty, which indicates that
+there is no current figure window.
+
+The @code{get} function may also be used to find the value of a single
+property.  For example,
+
+ at example
+ at group
+get (gca (), "xlim")
+    @result{} [ 0 1 ]
+ at end group
+ at end example
+
+ at noindent
+returns the range of the x-axis for the current axes object in the
+current figure.
+
+To set graphics object properties, use the set function.  For example,
+
+ at example
+set (gca (), "xlim", [-10, 10]);
+ at end example
+
+ at noindent
+sets the range of the x-axis for the current axes object in the current
+figure to @samp{[-10, 10]}.  Additionally, calling set with a graphics
+object index as the only argument returns a structure containing the
+default values for all the properties for the given object type.  For
+example,
+
+ at example
+set (gca ())
+ at end example
+
+ at noindent
+returns a structure containing the default property values for axes
+objects.
+
+ at c graphics.cc
+ at anchor{doc-get}
+ at deftypefn {Built-in Function} {} get (@var{h}, @var{p})
+Return the named property @var{p} from the graphics handle @var{h}.
+If @var{p} is omitted, return the complete property list for @var{h}.
+If @var{h} is a vector, return a cell array including the property
+values or lists respectively.
+ at end deftypefn
+
+
+ at c graphics.cc
+ at anchor{doc-set}
+ at deftypefn {Built-in Function} {} set (@var{h}, @var{p}, @var{v}, @dots{})
+Set the named property value or vector @var{p} to the value @var{v}
+for the graphics handle @var{h}.
+ at end deftypefn
+
+
+ at c ./plot/ancestor.m
+ at anchor{doc-ancestor}
+ at deftypefn {Function File} {@var{parent} =} ancestor (@var{h}, @var{type})
+ at deftypefnx {Function File} {@var{parent} =} ancestor (@var{h}, @var{type}, 'toplevel')
+Return the first ancestor of handle object @var{h} whose type matches
+ at var{type}, where @var{type} is a character string.  If @var{type} is a
+cell array of strings, return the first parent whose type matches
+any of the given type strings.
+
+If the handle object @var{h} is of type @var{type}, return @var{h}.
+
+If @code{"toplevel"} is given as a 3rd argument, return the highest
+parent in the object hierarchy that matches the condition, instead
+of the first (nearest) one.
+ at seealso{@ref{doc-get,,get}, @ref{doc-set,,set}}
+ at end deftypefn
+
+
+ at c ./plot/allchild.m
+ at anchor{doc-allchild}
+ at deftypefn {Function File} {@var{h} =} allchild (@var{handles})
+Find all children, including hidden children, of a graphics object.
+
+This function is similar to @code{get (h, "children")}, but also
+returns includes hidden objects.  If @var{handles} is a scalar,
+ at var{h} will be a vector.  Otherwise, @var{h} will be a cell matrix
+of the same size as @var{handles} and each cell will contain a
+vector of handles.
+ at seealso{@ref{doc-get,,get}, @ref{doc-set,,set}, @ref{doc-findall,,findall}, @ref{doc-findobj,,findobj}}
+ at end deftypefn
+
+
+You can create axes, line, and patch objects directly using the
+ at code{axes}, @code{line}, and @code{patch} functions.  These objects
+become children of the current axes object.
+
+ at c ./plot/axes.m
+ at anchor{doc-axes}
+ at deftypefn {Function File} {} axes ()
+ at deftypefnx {Function File} {} axes (@var{property}, @var{value}, @dots{})
+ at deftypefnx {Function File} {} axes (@var{h})
+Create an axes object and return a handle to it.
+ at end deftypefn
+
+
+ at c ./plot/line.m
+ at anchor{doc-line}
+ at deftypefn {Function File} {} line ()
+ at deftypefnx {Function File} {} line (@var{x}, @var{y})
+ at deftypefnx {Function File} {} line (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} line (@var{x}, @var{y}, @var{z}, @var{property}, @var{value}, @dots{})
+Create line object from @var{x} and @var{y} and insert in current
+axes object.  Return a handle (or vector of handles) to the line
+objects created.
+
+Multiple property-value pairs may be specified for the line, but they
+must appear in pairs.
+ at end deftypefn
+
+
+ at c ./plot/patch.m
+ at anchor{doc-patch}
+ at deftypefn {Function File} {} patch ()
+ at deftypefnx {Function File} {} patch (@var{x}, @var{y}, @var{c})
+ at deftypefnx {Function File} {} patch (@var{x}, @var{y}, @var{z}, @var{c})
+ at deftypefnx {Function File} {} patch (@var{fv})
+ at deftypefnx {Function File} {} patch ('Faces', @var{f}, 'Vertices', @var{v}, @dots{})
+ at deftypefnx {Function File} {} patch (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} patch (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} patch (@dots{})
+Create patch object from @var{x} and @var{y} with color @var{c} and
+insert in the current axes object.  Return handle to patch object.
+
+For a uniform colored patch, @var{c} can be given as an RGB vector,
+scalar value referring to the current colormap, or string value (for
+example, "r" or "red").
+
+If passed a structure @var{fv} contain the fields "vertices", "faces"
+and optionally "facevertexcdata", create the patch based on these 
+properties.
+ at end deftypefn
+
+
+ at c ./plot/fill.m
+ at anchor{doc-fill}
+ at deftypefn {Function File} {} fill (@var{x}, @var{y}, @var{c})
+ at deftypefnx {Function File} {} fill (@var{x1}, @var{y1}, @var{c1}, @var{x2}, @var{y2}, @var{c2})
+ at deftypefnx {Function File} {} fill (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} fill (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} fill (@dots{})
+Create one or more filled patch objects, returning a patch object for each.
+ at end deftypefn
+
+
+ at c ./plot/surface.m
+ at anchor{doc-surface}
+ at deftypefn {Function File} {} surface (@var{x}, @var{y}, @var{z}, @var{c})
+ at deftypefnx {Function File} {} surface (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} surface (@var{z}, @var{c})
+ at deftypefnx {Function File} {} surface (@var{z})
+ at deftypefnx {Function File} {} surface (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} surface (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} surface (@dots{})
+Plot a surface graphic object given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the surface.  If @var{x} and @var{y} are vectors,
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.  If @var{x} and @var{y}
+are missing, they are constructed from size of the matrix @var{z}.
+
+Any additional properties passed are assigned to the surface.
+ at seealso{@ref{doc-surf,,surf}, @ref{doc-mesh,,mesh}, @ref{doc-patch,,patch}, @ref{doc-line,,line}}
+ at end deftypefn
+
+
+By default, Octave refreshes the plot window when a prompt is printed,
+or when waiting for input.  To force an update at other times, call the
+ at code{drawnow} function.
+
+ at c graphics.cc
+ at anchor{doc-drawnow}
+ at deftypefn  {Built-in Function} {} drawnow ()
+ at deftypefnx {Built-in Function} {} drawnow ("expose")
+ at deftypefnx {Built-in Function} {} drawnow (@var{term}, @var{file}, @var{mono}, @var{debug_file})
+Update figure windows and their children.  The event queue is flushed and
+any callbacks generated are executed.  With the optional argument
+ at code{"expose"}, only graphic objects are updated and no other events or
+callbacks are processed.
+The third calling form of @code{drawnow} is for debugging and is
+undocumented.
+ at end deftypefn
+
+
+Only figures that are modified will be updated.  The @code{refresh}
+function can also be used to force an update of the current figure, even if
+it is not modified.
+
+ at c ./plot/refresh.m
+ at anchor{doc-refresh}
+ at deftypefn {Function File} {} refresh ()
+ at deftypefnx {Function File} {} refresh (@var{h})
+Refresh a figure, forcing it to be redrawn.  Called without an
+argument the current figure is redrawn, otherwise the figure pointed
+to by @var{h} is redrawn.
+ at seealso{@ref{doc-drawnow,,drawnow}}
+ at end deftypefn
+
+
+Normally, high-level plot functions like @code{plot} or @code{mesh} call
+ at code{newplot} to initialize the state of the current axes so that the
+next plot is drawn in a blank window with default property settings.  To
+have two plots superimposed over one another, use the @code{hold}
+function.  For example,
+
+ at example
+ at group
+hold on;
+x = -10:0.1:10;
+plot (x, sin (x));
+plot (x, cos (x));
+hold off;
+ at end group
+ at end example
+
+ at noindent
+displays sine and cosine waves on the same axes.  If the hold state is
+off, consecutive plotting commands like this will only display the last
+plot.
+
+ at c ./plot/newplot.m
+ at anchor{doc-newplot}
+ at deftypefn {Function File} {} newplot ()
+Prepare graphics engine to produce a new plot.  This function should
+be called at the beginning of all high-level plotting functions.
+ at end deftypefn
+
+
+ at c ./plot/hold.m
+ at anchor{doc-hold}
+ at deftypefn  {Function File} {} hold
+ at deftypefnx {Function File} {} hold @var{state}
+ at deftypefnx {Function File} {} hold (@var{hax}, @dots{})
+Toggle or set the 'hold' state of the plotting engine which determines
+whether new graphic objects are added to the plot or replace the existing
+objects.  
+
+ at table @code
+ at item hold on
+Retain plot data and settings so that subsequent plot commands are displayed
+on a single graph.
+
+ at item hold off
+Clear plot and restore default graphics settings before each new plot
+command.  (default).
+
+ at item hold
+Toggle the current 'hold' state.
+ at end table
+
+When given the additional argument @var{hax}, the hold state is modified
+only for the given axis handle.
+
+To query the current 'hold' state use the @code{ishold} function.
+ at seealso{@ref{doc-ishold,,ishold}, @ref{doc-cla,,cla}, @ref{doc-newplot,,newplot}, @ref{doc-clf,,clf}}
+ at end deftypefn
+
+
+ at c ./plot/ishold.m
+ at anchor{doc-ishold}
+ at deftypefn {Function File} {} ishold
+Return true if the next line will be added to the current plot, or
+false if the plot device will be cleared before drawing the next line.
+ at end deftypefn
+
+
+To clear the current figure, call the @code{clf} function.  To clear the
+current axis, call the @code{cla} function.  To bring the current figure
+to the top of the window stack, call the @code{shg} function.  To delete
+a graphics object, call @code{delete} on its index.  To close the
+figure window, call the @code{close} function.
+
+ at c ./plot/clf.m
+ at anchor{doc-clf}
+ at deftypefn  {Function File} {} clf ()
+ at deftypefnx {Function File} {} clf ("reset")
+ at deftypefnx {Function File} {} clf (@var{hfig})
+ at deftypefnx {Function File} {} clf (@var{hfig}, "reset")
+Clear the current figure window.  @code{clf} operates by deleting child
+graphics objects with visible handles (@code{HandleVisibility} = on).
+If @var{hfig} is specified operate on it instead of the current figure.
+If the optional argument @code{"reset"} is specified, all objects including
+those with hidden handles are deleted.
+ at seealso{@ref{doc-cla,,cla}, @ref{doc-close,,close}, @ref{doc-delete,,delete}}
+ at end deftypefn
+
+
+ at c ./plot/cla.m
+ at anchor{doc-cla}
+ at deftypefn {Function File} {} cla ()
+ at deftypefnx {Function File} {} cla ("reset")
+ at deftypefnx {Function File} {} cla (@var{hax})
+ at deftypefnx {Function File} {} cla (@var{hax}, "reset")
+Delete the children of the current axes with visible handles.
+If @var{hax} is specified and is an axes object handle, operate on it
+instead of the current axes.  If the optional argument @code{"reset"}
+is specified, also delete the children with hidden handles.
+ at seealso{@ref{doc-clf,,clf}}
+ at end deftypefn
+
+
+ at c ./plot/shg.m
+ at anchor{doc-shg}
+ at deftypefn {Function File} {} shg
+Show the graph window.  Currently, this is the same as executing
+ at code{drawnow}.
+ at seealso{@ref{doc-drawnow,,drawnow}, @ref{doc-figure,,figure}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/delete.m
+ at anchor{doc-delete}
+ at deftypefn  {Function File} {} delete (@var{file})
+ at deftypefnx {Function File} {} delete (@var{handle})
+Delete the named file or graphics handle.
+
+Deleting graphics objects is the proper way to remove
+features from a plot without clearing the entire figure.
+ at seealso{@ref{doc-clf,,clf}, @ref{doc-cla,,cla}}
+ at end deftypefn
+
+
+ at c ./plot/close.m
+ at anchor{doc-close}
+ at deftypefn {Command} {} close
+ at deftypefnx {Command} {} close (@var{n})
+ at deftypefnx {Command} {} close all
+ at deftypefnx {Command} {} close all hidden
+Close figure window(s) by calling the function specified by the
+ at code{"closerequestfcn"} property for each figure.  By default, the
+function @code{closereq} is used.
+ at seealso{@ref{doc-closereq,,closereq}}
+ at end deftypefn
+
+
+ at c ./plot/closereq.m
+ at anchor{doc-closereq}
+ at deftypefn {Function File} {} closereq ()
+Close the current figure and delete all graphics objects associated
+with it.
+ at seealso{@ref{doc-close,,close}, @ref{doc-delete,,delete}}
+ at end deftypefn
+
+
+ at node Graphics Object Properties
+ at subsection Graphics Object Properties
+ at cindex graphics object properties
+
+ at menu
+* Root Figure Properties::      
+* Figure Properties::           
+* Axes Properties::             
+* Line Properties::             
+* Text Properties::             
+* Image Properties::            
+* Patch Properties::            
+* Surface Properties::          
+* Searching Properties::
+ at end menu
+
+ at node Root Figure Properties
+ at subsubsection Root Figure Properties
+
+ at table @code
+ at item currentfigure
+Index to graphics object for the current figure.
+
+ at c FIXME -- does this work?
+ at c @item visible
+ at c Either @code{"on"} or @code{"off"} to toggle display of figures.
+ at end table
+
+ at node Figure Properties
+ at subsubsection Figure Properties
+ at cindex figure properties
+
+ at table @code
+ at item nextplot
+May be one of
+ at table @code
+ at item "new"
+ at item "add"
+ at item "replace"
+ at item "replacechildren"
+ at end table
+
+ at item closerequestfcn
+Handle of function to call when a figure is closed.
+
+ at item currentaxes
+Index to graphics object of current axes.
+
+ at item colormap
+An N-by-3 matrix containing the color map for the current axes.
+
+ at item visible
+Either @code{"on"} or @code{"off"} to toggle display of the figure.
+
+ at item paperorientation
+Indicates the orientation for printing.  Either @code{"landscape"} or
+ at code{"portrait"}.
+ at end table
+
+ at node Axes Properties
+ at subsubsection Axes Properties
+ at cindex axes properties
+
+ at table @code
+ at item position
+A vector specifying the position of the plot, excluding titles, axes and
+legend.  The four elements of the vector are the coordinates of the
+lower left corner and width and height of the plot, in units normalized
+to the width and height of the plot window.  For example, @code{[0.2,
+0.3, 0.4, 0.5]} sets the lower left corner of the axes at @math{(0.2,
+0.3)} and the width and height to be 0.4 and 0.5 respectively.  See also
+the @code{outerposition} property.
+
+ at item title
+Index of text object for the axes title.
+
+ at item box
+Either @code{"on"} or @code{"off"} to toggle display of the box around
+the axes.
+
+ at item key
+Either @code{"on"} or @code{"off"} to toggle display of the legend.
+Note that this property is not compatible with @sc{matlab} and may be
+removed in a future version of Octave.
+
+ at item keybox
+Either @code{"on"} or @code{"off"} to toggle display of a box around the
+legend.  Note that this property is not compatible with @sc{matlab} and
+may be removed in a future version of Octave.
+
+ at item keypos
+An integer from 1 to 4 specifying the position of the legend.  1
+indicates upper right corner, 2 indicates upper left, 3 indicates lower
+left, and 4 indicates lower right.  Note that this property is not
+compatible with @sc{matlab} and may be removed in a future version of
+Octave.
+
+ at item dataaspectratio
+A two-element vector specifying the relative height and width of the
+data displayed in the axes.  Setting @code{dataaspectratio} to @samp{1,
+2]} causes the length of one unit as displayed on the y-axis to be the
+same as the length of 2 units on the x-axis.  Setting
+ at code{dataaspectratio} also forces the @code{dataaspectratiomode}
+property to be set to @code{"manual"}.
+
+ at item dataaspectratiomode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xlim
+ at itemx ylim
+ at itemx zlim
+ at itemx clim
+Two-element vectors defining the limits for the x, y, and z axes and the 
+Setting one of these properties also forces the corresponding mode
+property to be set to @code{"manual"}.
+
+ at item xlimmode
+ at itemx ylimmode
+ at itemx zlimmode
+ at itemx climmode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xlabel
+ at itemx ylabel
+ at itemx zlabel
+Indices to text objects for the axes labels.
+
+ at item xgrid
+ at itemx ygrid
+ at itemx zgrid
+Either @code{"on"} or @code{"off"} to toggle display of grid lines.
+
+ at item xminorgrid
+ at itemx yminorgrid
+ at itemx zminorgrid
+Either @code{"on"} or @code{"off"} to toggle display of minor grid lines.
+
+ at item xtick
+ at itemx ytick
+ at itemx ztick
+Setting one of these properties also forces the corresponding mode
+property to be set to @code{"manual"}.
+
+ at item xtickmode
+ at itemx ytickmode
+ at itemx ztickmode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xticklabel
+ at itemx yticklabel
+ at itemx zticklabel
+Setting one of these properties also forces the corresponding mode
+property to be set to @code{"manual"}.
+
+ at item xticklabelmode
+ at itemx yticklabelmode
+ at itemx zticklabelmode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xscale
+ at itemx yscale
+ at itemx zscale
+Either @code{"linear"} or @code{"log"}.
+
+ at item xdir
+ at itemx ydir
+ at itemx zdir
+Either @code{"forward"} or @code{"reverse"}.
+
+ at item xaxislocation
+ at itemx yaxislocation
+Either @code{"top"} or @code{"bottom"} for the x-axis and @code{"left"}
+or @code{"right"} for the y-axis.
+
+ at item view
+A three element vector specifying the view point for three-dimensional plots.
+
+ at item visible
+Either @code{"on"} or @code{"off"} to toggle display of the axes.
+
+ at item nextplot
+May be one of
+ at table @code
+ at item "new"
+ at item "add"
+ at item "replace"
+ at item "replacechildren"
+ at end table
+
+ at item outerposition
+A vector specifying the position of the plot, including titles, axes and
+legend.  The four elements of the vector are the coordinates of the
+lower left corner and width and height of the plot, in units normalized
+to the width and height of the plot window.  For example, @code{[0.2,
+0.3, 0.4, 0.5]} sets the lower left corner of the axes at @math{(0.2,
+0.3)} and the width and height to be 0.4 and 0.5 respectively.  See also
+the @code{position} property.
+ at end table
+
+ at node Line Properties
+ at subsubsection Line Properties
+ at cindex line properties
+
+ at table @code
+ at itemx xdata
+ at itemx ydata
+ at itemx zdata
+ at itemx ldata
+ at itemx udata
+ at itemx xldata
+ at itemx xudata
+The data to be plotted.  The @code{ldata} and @code{udata} elements are
+for errorbars in the y direction, and the @code{xldata} and @code{xudata}
+elements are for errorbars in the x direction.
+
+ at item color
+The RGB color of the line, or a color name.  @xref{Colors}.
+
+ at item linestyle
+ at itemx linewidth
+ at xref{Line Styles}.
+
+ at item marker
+ at item markeredgecolor
+ at item markerfacecolor
+ at item markersize
+ at xref{Marker Styles}.
+
+ at item keylabel
+The text of the legend entry corresponding to this line.  Note that this
+property is not compatible with @sc{matlab} and may be removed in a
+future version of Octave.
+ at end table
+
+ at node Text Properties
+ at subsubsection Text Properties
+ at cindex text properties
+
+ at table @code
+ at item string
+The character string contained by the text object.
+
+ at item units
+May be @code{"normalized"} or @code{"graph"}.
+
+ at item position
+The coordinates of the text object.
+
+ at item rotation
+The angle of rotation for the displayed text, measured in degrees.
+
+ at item horizontalalignment
+May be @code{"left"}, @code{"center"}, or @code{"right"}.
+
+ at item color
+The color of the text.  @xref{Colors}.
+
+ at item fontname
+The font used for the text.
+
+ at item fontsize
+The size of the font, in points to use.
+
+ at item fontangle
+Flag whether the font is italic or normal.  Valid values are 'normal',
+'italic' and 'oblique'.
+
+ at item fontweight
+Flag whether the font is bold, etc.  Valid values are 'normal', 'bold',
+'demi' or 'light'.
+
+ at item interpreter
+Determines how the text is rendered.  Valid values are 'none', 'tex' or
+'latex'.
+ at end table
+
+All text objects, including titles, labels, legends, and text, include
+the property 'interpreter', this property determines the manner in which
+special control sequences in the text are rendered.  If the interpreter
+is set to 'none', then no rendering occurs.  At this point the 'latex'
+option is not implemented and so the 'latex' interpreter also does not
+interpret the text.
+
+The 'tex' option implements a subset of @sc{TeX} functionality in the
+rendering of the text.  This allows the insertion of special characters
+such as Greek or mathematical symbols within the text.  The special
+characters are also inserted with a code starting with the back-slash
+(\) character, as in the table @ref{tab:extended}. 
+
+In addition, the formatting of the text can be changed within the string
+with the codes 
+
+ at multitable @columnfractions .2 .2 .6 .2
+ at item @tab \bf @tab Bold font @tab
+ at item @tab \it @tab Italic font @tab
+ at item @tab \sl @tab Oblique Font @tab
+ at item @tab \rm @tab Normal font @tab
+ at end multitable
+
+These are be used in conjunction with the @{ and @} characters to limit
+the change in the font to part of the string.  For example
+
+ at example
+xlabel ('@{\bf H@} = a @{\bf V@}')
+ at end example
+
+where the character 'a' will not appear in a bold font.  Note that to
+avoid having Octave interpret the backslash characters in the strings,
+the strings should be in single quotes.
+
+It is also possible to change the fontname and size within the text 
+
+ at multitable @columnfractions .1 .4 .6 .1
+ at item @tab \fontname@{@var{fontname}@} @tab Specify the font to use @tab
+ at item @tab \fontsize@{@var{size}@} @tab Specify the size of the font to
+use @tab
+ at end multitable
+
+Finally, the superscript and subscripting can be controlled with the '^'
+and '_' characters.  If the '^' or '_' is followed by a @{ character,
+then all of the block surrounded by the @{ @} pair is super- or
+sub-scripted.  Without the @{ @} pair, only the character immediately
+following the '^' or '_' is super- or sub-scripted.
+
+ at float Table,tab:extended
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & # \vrule &
+# \hfil & \vrule # & # \hfil & # \vrule &
+# \hfil & \vrule # & # \hfil & # \vrule 
+width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& Code && Sym && Code && Sym && Code && Sym &\cr
+\noalign{\hrule}
+& $\backslash$forall    && $\forall$ 
+&& $\backslash$exists   && $\exists$ 
+&& $\backslash$ni       && $\ni$       &\cr
+& $\backslash$cong      && $\cong$ 
+&& $\backslash$Delta    && $\Delta$ 
+&& $\backslash$Phi      && $\Phi$      &\cr
+& $\backslash$Gamma     && $\Gamma$ 
+&& $\backslash$vartheta && $\vartheta$ 
+&& $\backslash$Lambda   && $\Lambda$   &\cr
+& $\backslash$Pi        && $\Pi$ 
+&& $\backslash$Theta    && $\Theta$ 
+&& $\backslash$Sigma    && $\Sigma$    &\cr
+& $\backslash$varsigma  && $\varsigma$ 
+&& $\backslash$Omega    && $\Omega$ 
+&& $\backslash$Xi       && $\Xi$       &\cr
+& $\backslash$Psi       && $\Psi$ 
+&& $\backslash$perp     && $\perp$ 
+&& $\backslash$alpha    && $\alpha$    &\cr
+& $\backslash$beta      && $\beta$ 
+&& $\backslash$chi      && $\chi$ 
+&& $\backslash$delta    && $\delta$    &\cr
+& $\backslash$epsilon   && $\epsilon$ 
+&& $\backslash$phi      && $\phi$ 
+&& $\backslash$gamma    && $\gamma$    &\cr
+& $\backslash$eta       && $\eta$ 
+&& $\backslash$iota     && $\iota$ 
+&& $\backslash$varphi   && $\varphi$   &\cr
+& $\backslash$kappa     && $\kappa$ 
+&& $\backslash$lambda   && $\lambda$ 
+&& $\backslash$mu       && $\mu$       &\cr
+& $\backslash$nu        && $\nu$ 
+&& $\backslash$o        && $\o$ 
+&& $\backslash$pi       && $\pi$       &\cr
+& $\backslash$theta     && $\theta$ 
+&& $\backslash$rho      && $\rho$ 
+&& $\backslash$sigma    && $\sigma$    &\cr
+& $\backslash$tau       && $\tau$
+&& $\backslash$upsilon  && $\upsilon$ 
+&& $\backslash$varpi    && $\varpi$    &\cr
+& $\backslash$omega     && $\omega$ 
+&& $\backslash$xi       && $\xi$ 
+&& $\backslash$psi      && $\psi$      &\cr
+& $\backslash$zeta      && $\zeta$ 
+&& $\backslash$sim      && $\sim$ 
+&& $\backslash$Upsilon  && $\Upsilon$  &\cr
+& $\backslash$prime     && $\prime$ 
+&& $\backslash$leq      && $\leq$ 
+&& $\backslash$infty    && $\infty$    &\cr
+& $\backslash$clubsuit  && $\clubsuit$ 
+&& $\backslash$diamondsuit    && $\diamondsuit$ 
+&& $\backslash$heartsuit      && $\heartsuit$     &\cr
+& $\backslash$spadesuit       && $\spadesuit$ 
+&& $\backslash$leftrightarrow && $\leftrightarrow$ 
+&& $\backslash$leftarrow      && $\leftarrow$     &\cr
+& $\backslash$uparrow         && $\uparrow$ 
+&& $\backslash$rightarrow     && $\rightarrow$ 
+&& $\backslash$downarrow      && $\downarrow$     &\cr
+& $\backslash$circ      && $\circ$ 
+&& $\backslash$pm       && $\pm$ 
+&& $\backslash$geq      && $\geq$      &\cr
+& $\backslash$times     && $\times$ 
+&& $\backslash$propto   && $\propto$ 
+&& $\backslash$partial  && $\partial$  &\cr
+& $\backslash$bullet    && $\bullet$
+&& $\backslash$div      && $\div$ 
+&& $\backslash$neq      && $\neq$      &\cr
+& $\backslash$equiv     && $\equiv$ 
+&& $\backslash$approx   && $\approx$ 
+&& $\backslash$ldots    && $\ldots$ &\cr
+& $\backslash$mid       && $\mid$ 
+&& $\backslash$aleph    && $\aleph$ 
+&& $\backslash$Im       && $\Im$ &\cr
+& $\backslash$Re        && $\Re$ 
+&& $\backslash$wp       && $\wp$ 
+&& $\backslash$otimes   && $\otimes$ &\cr
+& $\backslash$oplus     && $\oplus$ 
+&& $\backslash$oslash   && $\oslash$ 
+&& $\backslash$cap      && $\cap$ &\cr
+& $\backslash$cup       && $\cup$ 
+&& $\backslash$supset   && $\supset$ 
+&& $\backslash$supseteq && $\supseteq$ &\cr
+& $\backslash$subset    && $\subset$ 
+&& $\backslash$subseteq && $\subseteq$ 
+&& $\backslash$in       && $\in$ &\cr
+& $\backslash$notin     && $\notin$
+&& $\backslash$angle    && $\angle$
+&& $\backslash$bigtriangledown && $\bigtriangledown$ &\cr
+& $\backslash$langle    && $\langle$ 
+&& $\backslash$rangle   && $\rangle$ 
+&& $\backslash$nabla    && $\nabla$    &\cr
+& $\backslash$prod      && $\prod$
+&& $\backslash$surd     && $\surd$ 
+&& $\backslash$cdot     && $\cdot$     &\cr
+& $\backslash$neg       && $\neg$ 
+&& $\backslash$wedge    && $\wedge$ 
+&& $\backslash$vee      && $\vee$      &\cr
+& $\backslash$Leftrightarrow && $\Leftrightarrow$
+&& $\backslash$Leftarrow     && $\Leftarrow$
+&& $\backslash$Uparrow       && $\Uparrow$           &\cr
+& $\backslash$Rightarrow     && $\Rightarrow$
+&& $\backslash$Downarrow     && $\Downarrow$
+&& $\backslash$diamond  && $\diamond$  &\cr
+& $\backslash$copyright && $\copyright$ 
+&& $\backslash$rfloor   && $\rfloor$ 
+&& $\backslash$lceil    && $\lceil$    &\cr
+& $\backslash$lfloor    && $\lfloor$ 
+&& $\backslash$rceil    && $\rceil$ 
+&& $\backslash$int      && $\int$      &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .125 .25 .25 .25 .125
+ at item @tab  \forall     @tab  \exists     @tab  \ni      @tab
+ at item @tab  \cong       @tab  \Delta      @tab  \Phi     @tab
+ at item @tab  \Gamma      @tab  \vartheta   @tab  \Lambda  @tab
+ at item @tab  \Pi         @tab  \Theta      @tab  \Sigma   @tab
+ at item @tab  \varsigma   @tab  \Omega      @tab  \Xi      @tab
+ at item @tab  \Psi        @tab  \perp       @tab  \alpha   @tab
+ at item @tab  \beta       @tab  \chi        @tab  \delta   @tab  
+ at item @tab  \epsilon    @tab  \phi        @tab  \gamma   @tab
+ at item @tab  \eta        @tab  \iota       @tab  \varphi  @tab
+ at item @tab  \kappa      @tab  \lambda     @tab  \mu      @tab 
+ at item @tab  \nu         @tab  \o          @tab  \pi      @tab
+ at item @tab  \theta      @tab  \rho        @tab  \sigma   @tab 
+ at item @tab  \tau        @tab  \upsilon    @tab  \varpi   @tab
+ at item @tab  \omega      @tab  \xi         @tab  \psi     @tab 
+ at item @tab  \zeta       @tab  \sim        @tab  \Upsilon @tab
+ at item @tab  \prime      @tab  \leq        @tab  \infty   @tab
+ at item @tab  \clubsuit   @tab  \diamondsuit    @tab  \heartsuit  @tab
+ at item @tab  \spadesuit  @tab  \leftrightarrow @tab  \leftarrow  @tab 
+ at item @tab  \uparrow    @tab  \rightarrow @tab  \downarrow @tab 
+ at item @tab  \circ       @tab \pm          @tab  \geq     @tab 
+ at item @tab  \times      @tab  \propto     @tab  \partial @tab
+ at item @tab  \bullet     @tab \div         @tab  \neq     @tab 
+ at item @tab  \equiv      @tab  \approx     @tab  \ldots   @tab 
+ at item @tab  \mid        @tab  \aleph      @tab  \Im      @tab 
+ at item @tab  \Re         @tab \wp          @tab  \otimes  @tab
+ at item @tab  \oplus      @tab \oslash      @tab  \cap     @tab 
+ at item @tab  \cup        @tab   \supset    @tab  \supseteq @tab 
+ at item @tab  \subset     @tab \subseteq    @tab  \in      @tab 
+ at item @tab  \notin      @tab \angle       @tab  \bigrightriangledown @tab
+ at item @tab  \langle     @tab  \rangle     @tab  \nabla   @tab
+ at item @tab  \prod       @tab \surd        @tab  \cdot    @tab 
+ at item @tab  \neg        @tab  \wedge      @tab \vee      @tab 
+ at item @tab  \Leftrightarrow @tab \Leftarrow @tab \Uparrow @tab
+ at item @tab  \Rightarrow @tab \Downarrow   @tab \diamond  @tab
+ at item @tab  \copyright  @tab  \lfloor     @tab  \lceil   @tab 
+ at item @tab  \rfloor     @tab  \rceil      @tab  \int     @tab 
+ at end multitable
+ at end ifnottex
+ at caption{Available special characters in @sc{TeX} mode}
+ at end float
+
+A complete example showing the capabilities of the extended text is
+
+ at example
+ at group
+x = 0:0.01:3;
+plot(x,erf(x));
+hold on;
+plot(x,x,"r");
+axis([0, 3, 0, 1]);
+text(0.65, 0.6175, strcat('\leftarrow x = @{2/\surd\pi',
+' @{\fontsize@{16@}\int_@{\fontsize@{8@}0@}^@{\fontsize@{8@}x@}@}',
+' e^@{-t^2@} dt@} = 0.6175'))
+ at end group
+ at end example
+
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:extendedtext}
+
+ at float Figure,fig:extendedtext
+ at center @image{extended,4in}
+ at caption{Example of inclusion of text with the @sc{TeX} interpreter}
+ at end float
+ at end ifnotinfo
+
+ at node Image Properties
+ at subsubsection Image Properties
+ at cindex image properties
+
+ at table @code
+ at item cdata
+The data for the image.  Each pixel of the image corresponds to an
+element of @code{cdata}.  The value of an element of @code{cdata}
+specifies the row-index into the colormap of the axes object containing
+the image.  The color value found in the color map for the given index
+determines the color of the pixel.
+
+ at item xdata
+ at itemx ydata
+Two-element vectors specifying the range of the x- and y- coordinates for
+the image.
+ at end table
+
+ at node Patch Properties
+ at subsubsection Patch Properties
+ at cindex patch properties
+
+ at table @code
+ at item cdata
+ at itemx xdata
+ at itemx ydata
+ at itemx zdata
+Data defining the patch object.
+
+ at item facecolor
+The fill color of the patch.  @xref{Colors}.
+
+ at item facealpha
+A number in the range [0, 1] indicating the transparency of the patch.
+
+ at item edgecolor
+The color of the line defining the patch.  @xref{Colors}.
+
+ at item linestyle
+ at itemx linewidth
+ at xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+ at xref{Marker Styles}.
+ at end table
+
+ at node Surface Properties
+ at subsubsection Surface Properties
+ at cindex surface properties
+
+ at table @code
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The data determining the surface.  The @code{xdata} and @code{ydata}
+elements are vectors and @code{zdata} must be a matrix.
+
+ at item keylabel
+The text of the legend entry corresponding to this surface.  Note that
+this property is not compatible with @sc{matlab} and may be removed in a
+future version of Octave.
+ at end table
+
+ at node Searching Properties
+ at subsubsection Searching Properties
+
+ at c ./plot/findobj.m
+ at anchor{doc-findobj}
+ at deftypefn {Function File} {@var{h} =} findobj ()
+ at deftypefnx {Function File} {@var{h} =} findobj (@var{prop_name}, @var{prop_value})
+ at deftypefnx {Function File} {@var{h} =} findobj ('-property', @var{prop_name})
+ at deftypefnx {Function File} {@var{h} =} findobj ('-regexp', @var{prop_name}, @var{pattern})
+ at deftypefnx {Function File} {@var{h} =} findobj ('flat', @dots{})
+ at deftypefnx {Function File} {@var{h} =} findobj (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} findobj (@var{h}, '-depth', @var{d}, @dots{})
+Find object with specified property values.  The simplest form is
+
+ at example
+findobj (@var{prop_name}, @var{prop_Value})
+ at end example
+
+ at noindent
+which returns all of the handles to the objects with the name 
+ at var{prop_name} and the name @var{prop_Value}.  The search can be limited
+to a particular object or set of objects and their descendants by 
+passing a handle or set of handles @var{h} as the first argument to 
+ at code{findobj}.
+
+The depth of hierarchy of objects to which to search to can be limited
+with the '-depth' argument.  To limit the number depth of the hierarchy
+to search to @var{d} generations of children, and example is
+
+ at example
+findobj (@var{h}, '-depth', @var{d}, @var{prop_Name}, @var{prop_Value})
+ at end example
+
+Specifying a depth @var{d} of 0, limits the search to the set of object
+passed in @var{h}.  A depth @var{d} of 0 is equivalent to the '-flat'
+argument. 
+
+A specified logical operator may be applied to the pairs of @var{prop_Name}
+and @var{prop_Value}.  The supported logical operators are '-and', '-or', 
+'-xor', '-not'.
+
+The objects may also be matched by comparing a regular expression to the 
+property values, where property values that match @code{regexp 
+(@var{prop_Value}, @var{pattern})} are returned.  Finally, objects may be 
+matched by property name only, using the '-property' option.
+ at seealso{@ref{doc-get,,get}, @ref{doc-set,,set}}
+ at end deftypefn
+
+
+ at c ./plot/findall.m
+ at anchor{doc-findall}
+ at deftypefn {Function File} {@var{h} =} findall ()
+ at deftypefnx {Function File} {@var{h} =} findall (@var{prop_name}, @var{prop_value})
+ at deftypefnx {Function File} {@var{h} =} findall (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} findall (@var{h}, "-depth", @var{d}, @dots{})
+Find object with specified property values including hidden handles.
+
+This function performs the same function as @code{findobj}, but it
+includes hidden objects in its search.  For full documentation, see
+ at code{findobj}.
+ at seealso{@ref{doc-get,,get}, @ref{doc-set,,set}, @ref{doc-findobj,,findobj}, @ref{doc-allchild,,allchild}}
+ at end deftypefn
+
+
+
+ at node Managing Default Properties
+ at subsection Managing Default Properties
+ at cindex default graphics properties
+ at cindex graphics properties, default
+
+Object properties have two classes of default values, @dfn{factory
+defaults} (the initial values) and @dfn{user-defined defaults}, which
+may override the factory defaults.
+
+Although default values may be set for any object, they are set in
+parent objects and apply to child objects.  For example,
+
+ at example
+set (0, "defaultlinecolor", "green");
+ at end example
+
+ at noindent
+sets the default line color for all objects.  The rule for constructing
+the property name to set a default value is
+
+ at example
+default + @var{object-type} + @var{property-name}
+ at end example
+
+This rule can lead to some strange looking names, for example
+ at code{defaultlinelinewidth"} specifies the default @code{linewidth}
+property for @code{line} objects.
+
+The example above used the root figure object, 0, so the default
+property value will apply to all line objects.  However, default values
+are hierarchical, so defaults set in a figure objects override those
+set in the root figure object.  Likewise, defaults set in axes objects
+override those set in figure or root figure objects.  For example,
+
+ at example
+ at group
+subplot (2, 1, 1);
+set (0, "defaultlinecolor", "red");
+set (1, "defaultlinecolor", "green");
+set (gca (), "defaultlinecolor", "blue");
+line (1:10, rand (1, 10));
+subplot (2, 1, 2);
+line (1:10, rand (1, 10));
+figure (2)
+line (1:10, rand (1, 10));
+ at end group
+ at end example
+
+ at noindent
+produces two figures.  The line in first subplot window of the first
+figure is blue because it inherits its color from its parent axes
+object.  The line in the second subplot window of the first figure is
+green because it inherits its color from its parent figure object.  The
+line in the second figure window is red because it inherits its color
+from the global root figure parent object.
+
+To remove a user-defined default setting, set the default property to
+the value @code{"remove"}.  For example,
+
+ at example
+set (gca (), "defaultlinecolor", "remove");
+ at end example
+
+ at noindent
+removes the user-defined default line color setting from the current axes
+object.
+
+Getting the @code{"default"} property of an object returns a list of
+user-defined defaults set for the object.  For example,
+
+ at example
+get (gca (), "default");
+ at end example
+
+ at noindent
+returns a list of user-defined default values for the current axes
+object.
+
+Factory default values are stored in the root figure object.  The
+command
+
+ at example
+get (0, "factory");
+ at end example
+
+ at noindent
+returns a list of factory defaults.
+
+ at node Colors
+ at subsection Colors
+ at cindex graphics colors
+ at cindex colors, graphics
+
+Colors may be specified as RGB triplets with values ranging from zero to
+one, or by name.  Recognized color names include @code{"blue"},
+ at code{"black"}, @code{"cyan"}, @code{"green"}, @code{"magenta"},
+ at code{"red"}, @code{"white"}, and @code{"yellow"}.
+
+ at node Line Styles
+ at subsection Line Styles
+ at cindex line styles, graphics
+ at cindex graphics line styles
+
+Line styles are specified by the following properties:
+
+ at table @code
+ at item linestyle
+May be one of
+ at table @code
+ at item "-"
+Solid lines.
+ at item "--"
+Dashed lines.
+ at item ":"
+Points.
+ at item "-."
+A dash-dot line.
+ at end table
+
+ at item linewidth
+A number specifying the width of the line.  The default is 1.  A value
+of 2 is twice as wide as the default, etc.
+ at end table
+
+ at node Marker Styles
+ at subsection Marker Styles
+ at cindex graphics marker styles
+ at cindex marker styles, graphics
+
+Marker styles are specified by the following properties:
+ at table @code
+ at item marker
+A character indicating a plot marker to be place at each data point, or
+ at code{"none"}, meaning no markers should be displayed.
+
+ at itemx markeredgecolor
+The color of the edge around the marker, or @code{"auto"}, meaning that
+the edge color is the same as the face color.  @xref{Colors}.
+
+ at itemx markerfacecolor
+The color of the marker, or @code{"none"} to indicate that the marker
+should not be filled.  @xref{Colors}.
+
+ at itemx markersize
+A number specifying the size of the marker.  The default is 1.  A value
+of 2 is twice as large as the default, etc.
+ at end table
+
+ at node Callbacks
+ at subsection Callbacks
+ at cindex callbacks
+
+Callback functions can be associated with graphics objects and triggered
+after certain events occur.  The basic structure of all callback function
+is 
+
+ at example
+ at group
+function mycallback (src, data)
+ at dots{}
+endfunction
+ at end group
+ at end example
+
+where @code{src} gives a handle to the source of the callback, and
+ at code{code} gives some event specific data.  This can then be associated
+with an object either at the objects creation or later with the
+ at code{set} function.  For example
+
+ at example
+plot (x, "DeleteFcn", @@(s, e) disp("Window Deleted"))
+ at end example
+
+ at noindent
+where at the moment that the plot is deleted, the message "Window
+Deleted" will be displayed.
+
+Additional user arguments can be passed to callback functions, and will
+be passed after the 2 default arguments.  For example
+
+ at example
+ at group
+plot (x, "DeleteFcn", @{@@mycallback, "1"@})
+ at dots{}
+function mycallback (src, data, a1)
+  fprintf ("Closing plot %d\n", a1);
+endfunction
+ at end group
+ at end example
+
+The basic callback functions that are available for all graphics objects
+are
+
+ at itemize @bullet
+ at item CreateFcn
+This is the callback that is called at the moment of the objects
+creation.  It is not called if the object is altered in any way, and so
+it only makes sense to define this callback in the function call that
+defines the object.  Callbacks that are added to @code{CreateFcn} later with
+the @code{set} function will never be executed.
+
+ at item DeleteFcn
+This is the callback that is called at the moment an object is deleted.
+
+ at item ButtonDownFcn
+This is the callback that is called if a mouse button is pressed while
+the pointer is over this object.  Note, that the gnuplot interface does
+not respect this callback.
+ at end itemize
+
+The object and figure that the event occurred in that resulted in the
+callback being called can be found with the @code{gcbo} and @code{gcbf}
+functions.
+
+ at c ./plot/gcbo.m
+ at anchor{doc-gcbo}
+ at deftypefn {Function File} {@var{h} =} gcbo ()
+ at deftypefnx {Function File} {[@var{h}, @var{fig}] =} gcbo ()
+Return a handle to the object whose callback is currently
+executing.  If no callback is executing, this function returns the
+empty matrix.  This handle is obtained from the root object property
+"CallbackObject".
+
+Additionally return the handle of the figure containing the
+object whose callback is currently executing.  If no callback is
+executing, the second output is also set to the empty matrix.
+
+ at seealso{@ref{doc-gcf,,gcf}, @ref{doc-gca,,gca}, @ref{doc-gcbf,,gcbf}}
+ at end deftypefn
+
+
+ at c ./plot/gcbf.m
+ at anchor{doc-gcbf}
+ at deftypefn {Function File} {@var{fig} =} gcbf ()
+Return a handle to the figure containing the object whose callback
+is currently executing.  If no callback is executing, this function
+returns the empty matrix.  The handle returned by this function is
+the same as the second output argument of gcbo.
+
+ at seealso{@ref{doc-gcf,,gcf}, @ref{doc-gca,,gca}, @ref{doc-gcbo,,gcbo}}
+ at end deftypefn
+
+
+Callbacks can equally be added to properties with the @code{addlistener}
+function described below.
+
+ at node Object Groups
+ at subsection Object Groups
+ at cindex object groups
+
+A number of Octave high level plot functions return groups of other
+graphics objects or they return graphics objects that are have their
+properties linked in such a way that changes to one of the properties
+results in changes in the others.  A graphic object that groups other
+objects is an @code{hggroup}
+
+ at c ./plot/hggroup.m
+ at anchor{doc-hggroup}
+ at deftypefn {Function File} {} hggroup ()
+ at deftypefnx {Function File} {} hggroup (@var{h})
+ at deftypefnx {Function File} {} hggroup (@dots{}, @var{property}, @var{value}, @dots{})
+Create group object with parent @var{h}.  If no parent is specified,
+the group is created in the current axes.  Return the handle of the
+group object created.
+
+Multiple property-value pairs may be specified for the group, but they
+must appear in pairs.
+ at end deftypefn
+
+
+For example a simple use of a @code{hggroup} might be
+
+ at example
+ at group
+x = 0:0.1:10;
+hg = hggroup ();
+plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+hold on
+plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+set (hg, "visible", "off");
+ at end group
+ at end example
+
+ at noindent
+which groups the two plots into a single object and controls their
+visibility directly.  The default properties of an @code{hggroup} are
+the same as the set of common properties for the other graphics
+objects.  Additional properties can be added with the @code{addproperty}
+function. 
+
+ at c graphics.cc
+ at anchor{doc-addproperty}
+ at deftypefn {Built-in Function} {} addproperty (@var{name}, @var{h}, @var{type}, [@var{arg}, @dots{}])
+Create a new property named @var{name} in graphics object @var{h}.
+ at var{type} determines the type of the property to create.  @var{args}
+usually contains the default value of the property, but additional
+arguments might be given, depending on the type of the property.
+
+The supported property types are:
+
+ at table @code
+ at item string
+A string property.  @var{arg} contains the default string value.
+ at item any
+An un-typed property.  This kind of property can hold any octave
+value.  @var{args} contains the default value.
+ at item radio
+A string property with a limited set of accepted values.  The first
+argument must be a string with all accepted values separated by
+a vertical bar ('|').  The default value can be marked by enclosing
+it with a '@{' '@}' pair.  The default value may also be given as
+an optional second string argument.
+ at item boolean
+A boolean property.  This property type is equivalent to a radio
+property with "on|off" as accepted values.  @var{arg} contains
+the default property value.
+ at item double
+A scalar double property.  @var{arg} contains the default value.
+ at item handle
+A handle property.  This kind of property holds the handle of a
+graphics object.  @var{arg} contains the default handle value.
+When no default value is given, the property is initialized to
+the empty matrix.
+ at item data
+A data (matrix) property.  @var{arg} contains the default data
+value.  When no default value is given, the data is initialized to
+the empty matrix.
+ at item color
+A color property.  @var{arg} contains the default color value.
+When no default color is given, the property is set to black.
+An optional second string argument may be given to specify an
+additional set of accepted string values (like a radio property).
+ at end table
+
+ at var{type} may also be the concatenation of a core object type and
+a valid property name for that object type.  The property created
+then has the same characteristics as the referenced property (type,
+possible values, hidden state at dots{}).  This allows to clone an existing
+property into the graphics object @var{h}.
+
+Examples:
+
+ at example
+ at group
+addproperty ("my_property", gcf, "string", "a string value");
+addproperty ("my_radio", gcf, "radio", "val_1|val_2|@{val_3@}");
+addproperty ("my_style", gcf, "linelinestyle", "--");
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+Once a property in added to an @code{hggroup}, it is not linked to any
+other property of either the children of the group, or any other
+graphics object.  Add so to control the way in which this newly added
+property is used, the @code{addlistener} function is used to define a
+callback function that is executed when the property is altered.
+
+ at c graphics.cc
+ at anchor{doc-addlistener}
+ at deftypefn {Built-in Function} {} addlistener (@var{h}, @var{prop}, @var{fcn})
+Register @var{fcn} as listener for the property @var{prop} of the graphics
+object @var{h}.  Property listeners are executed (in order of registration)
+when the property is set.  The new value is already available when the
+listeners are executed.
+
+ at var{prop} must be a string naming a valid property in @var{h}.
+
+ at var{fcn} can be a function handle, a string or a cell array whose first
+element is a function handle.  If @var{fcn} is a function handle, the
+corresponding function should accept at least 2 arguments, that will be
+set to the object handle and the empty matrix respectively.  If @var{fcn}
+is a string, it must be any valid octave expression.  If @var{fcn} is a cell
+array, the first element must be a function handle with the same signature
+as described above.  The next elements of the cell array are passed
+as additional arguments to the function.
+
+Example:
+
+ at example
+ at group
+function my_listener (h, dummy, p1)
+  fprintf ("my_listener called with p1=%s\n", p1);
+endfunction
+
+addlistener (gcf, "position", @{@@my_listener, "my string"@})
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+ at c graphics.cc
+ at anchor{doc-dellistener}
+ at deftypefn {Built-in Function} {} dellistener (@var{h}, @var{prop}, @var{fcn})
+Remove the registration of @var{fcn} as a listener for the property
+ at var{prop} of the graphics object @var{h}.  The function @var{fcn} must
+be the same variable (not just the same value), as was passed to the
+original call to @code{addlistener}.
+
+If @var{fcn} is not defined then all listener functions of @var{prop}
+are removed.
+
+Example:
+
+ at example
+ at group
+function my_listener (h, dummy, p1)
+  fprintf ("my_listener called with p1=%s\n", p1);
+endfunction
+
+c = @{@@my_listener, "my string"@};
+addlistener (gcf, "position", c);
+dellistener (gcf, "position", c);
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+An example of the use of these two functions might be
+
+ at example
+ at group
+x = 0:0.1:10;
+hg = hggroup ();
+h = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+addlistener (hg, "linestyle", @@update_props);
+hold on
+plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+
+function update_props (h, d)
+  set (get (h, "children"), "linestyle", get (h, "linestyle"));
+endfunction
+ at end group
+ at end example
+
+ at noindent
+that adds a @code{linestyle} property to the @code{hggroup} and
+propagating any changes its value to the children of the group.  The
+ at code{linkprop} function can be used to simplify the above to be
+
+ at example
+ at group
+x = 0:0.1:10;
+hg = hggroup ();
+h1 = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+hold on
+h2 = plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+hlink = linkprop ([hg, h1, h2], "color"); 
+ at end group
+ at end example
+
+ at c ./plot/linkprop.m
+ at anchor{doc-linkprop}
+ at deftypefn {Function File} {@var{hlink} =} linkprop (@var{h}, @var{prop})
+Links graphics object properties, such that a change in one is
+propagated to the others.  The properties to link are given as a
+string of cell string array by @var{prop} and the objects containing
+these properties by the handle array @var{h}.
+
+An example of the use of linkprops is
+
+ at example
+ at group
+x = 0:0.1:10;
+subplot (1, 2, 1);
+h1 = plot (x, sin (x));
+subplot (1, 2, 2);
+h2 = plot (x, cos (x));
+hlink = linkprop ([h1, h2], @{"color","linestyle"@});
+set (h1, "color", "green");
+set (h2, "linestyle", "--");
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+These capabilities are used in a number of basic graphics objects. 
+The @code{hggroup} objects created by the functions of Octave contain
+one or more graphics object and are used to:
+
+ at itemize @bullet
+ at item group together multiple graphics objects,
+ at item create linked properties between different graphics objects, and
+ at item to hide the nominal user data, from the actual data of the objects.
+ at end itemize
+
+ at noindent
+For example the @code{stem} function creates a stem series where each
+ at code{hggroup} of the stem series contains two line objects representing
+the body and head of the stem.  The @code{ydata} property of the
+ at code{hggroup} of the stem series represents the head of the stem,
+whereas the body of the stem is between the baseline and this value.  For
+example
+
+ at example
+ at group
+h = stem (1:4)
+get (h, "xdata")
+ at result{} [  1   2   3   4]'
+get (get (h, "children")(1), "xdata")
+ at result{} [  1   1 NaN   2   2 NaN   3   3 NaN   4   4 NaN]'
+ at end group
+ at end example
+
+ at noindent
+shows the difference between the @code{xdata} of the @code{hggroup}
+of a stem series object and the underlying line.
+
+The basic properties of such group objects is that they consist of one 
+or more linked @code{hggroup}, and that changes in certain properties of
+these groups are propagated to other members of the group.  Whereas,
+certain properties of the members of the group only apply to the current
+member.
+
+In addition the members of the group can also be linked to other
+graphics objects through callback functions.  For example the baseline of
+the @code{bar} or @code{stem} functions is a line object, whose length
+and position are automatically adjusted, based on changes to the
+corresponding hggroup elements.
+
+ at menu
+* Data sources in object groups::
+* Area series::
+* Bar series::
+* Contour groups::
+* Error bar series::
+* Line series::
+* Quiver group::
+* Scatter group::
+* Stair group::
+* Stem Series::
+* Surface group::
+ at end menu
+
+ at node Data sources in object groups
+ at subsubsection Data sources in object groups
+ at cindex data sources in object groups
+
+All of the group objects contain data source parameters.  There are
+string parameters that contain an expression that is evaluated to update
+the relevant data property of the group when the @code{refreshdata}
+function is called. 
+
+ at c ./plot/refreshdata.m
+ at anchor{doc-refreshdata}
+ at deftypefn  {Function File} {} refreshdata ()
+ at deftypefnx {Function File} {} refreshdata (@var{h})
+ at deftypefnx {Function File} {} refreshdata (@var{h}, @var{workspace})
+Evaluate any @samp{datasource} properties of the current figure and update
+the plot if the corresponding data has changed.  If called with one or more
+arguments @var{h} is a scalar or array of figure handles to refresh.  The
+optional second argument @var{workspace} can take the following values.
+
+ at table @code
+ at item "base"
+Evaluate the datasource properties in the base workspace.  (default).
+ at item "caller"
+Evaluate the datasource properties in the workspace of the function
+that called @code{refreshdata}.
+ at end table
+
+An example of the use of @code{refreshdata} is:
+
+ at example
+ at group
+x = 0:0.1:10;
+y = sin (x);
+plot (x, y, "ydatasource", "y");
+for i = 1 : 100
+  pause(0.1)
+  y = sin (x + 0.1 * i);
+  refreshdata();
+endfor
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at anchor{doc-linkdata}
+ at c add the description of the linkdata function here when it is written
+ at c remove the explicit anchor when you add the corresponding @DOCSTRING
+ at c command
+
+ at node Area series
+ at subsubsection Area series
+ at cindex series objects
+ at cindex area series
+
+Area series objects are created by the @code{area} function.  Each of the
+ at code{hggroup} elements contains a single patch object.  The properties
+of the area series are
+
+ at table @code
+ at item basevalue
+The value where the base of the area plot is drawn.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the edge of the patch objects making up the
+areas.  @xref{Line Styles}.
+
+ at item edgecolor
+ at itemx facecolor
+The line and fill color of the patch objects making up the areas.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+The x and y coordinates of the original columns of the data passed to
+ at code{area} prior to the cumulative summation used in the @code{area}
+function. 
+
+ at item xdatasource
+ at itemx ydatasource
+Data source variables.
+ at end table
+
+ at node Bar series
+ at subsubsection Bar series
+ at cindex series objects
+ at cindex bar series
+
+Bar series objects are created by the @code{bar} or @code{barh}
+functions.  Each @code{hggroup} element contains a single patch object. 
+The properties of the bar series are
+
+ at table @code
+ at item showbaseline
+ at itemx baseline
+ at itemx basevalue
+The property @code{showbaseline} flags whether the baseline of the bar
+series is displayed (default is "on").  The handle of the graphics object
+representing the baseline is given by the @code{baseline} property and
+the y-value of the baseline by the @code{basevalue} property. 
+
+Changes to any of these property are propagated to the other members of
+the bar series and to the baseline itself.  Equally changes in the
+properties of the base line itself are propagated to the members of the
+corresponding bar series.
+
+ at item barwidth
+ at itemx barlayout
+ at itemx horizontal
+The property @code{barwidth} is the width of the bar corresponding to
+the @var{width} variable passed to @code{bar} or @var{barh}.  Whether the
+bar series is "grouped" or "stacked" is determined by the
+ at code{barlayout} property and whether the bars are horizontal or
+vertical by the @code{horizontal} property.
+
+Changes to any of these property are propagated to the other members of
+the bar series.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the edge of the patch objects making up the
+bars.  @xref{Line Styles}.
+
+ at item edgecolor
+ at itemx facecolor
+The line and fill color of the patch objects making up the bars.  @xref{Colors}.
+
+ at item xdata
+The nominal x positions of the bars.  Changes in this property and
+propagated to the other members of the bar series. 
+
+ at item ydata
+The y value of the bars in the @code{hggroup}.
+
+ at item xdatasource
+ at itemx ydatasource
+Data source variables.
+ at end table
+
+ at node Contour groups
+ at subsubsection Contour groups
+ at cindex series objects
+ at cindex contour series
+
+Contour group objects are created by the @code{contour}, @code{contourf}
+and @code{contour3} functions.  The are equally one of the handles returned
+by the @code{surfc} and @code{meshc} functions.  The properties of the contour
+group are
+
+ at table @code
+ at item contourmatrix
+A read only property that contains the data return by @code{contourc} used to
+create the contours of the plot.
+
+ at item fill
+A radio property that can have the values "on" or "off" that flags whether the
+contours to plot are to be filled.
+
+ at item zlevelmode
+ at itemx zlevel
+The radio property @code{zlevelmode} can have the values "none", "auto" or 
+"manual".  When its value is "none" there is no z component to the plotted
+contours.  When its value is "auto" the z value of the plotted contours is 
+at the same value as the contour itself.  If the value is "manual", then the
+z value at which to plot the contour is determined by the @code{zlevel}
+property.
+
+ at item levellistmode
+ at itemx levellist
+ at itemx levelstepmode
+ at itemx levelstep
+If @code{levellistmode} is "manual", then the levels at which to plot the 
+contours is determined by @code{levellist}.  If @code{levellistmode} is
+set to "auto", then the distance between contours is determined by 
+ at code{levelstep}.  If both @code{levellistmode} and @code{levelstepmode}
+are set to "auto", then there are assumed to be 10 equal spaced contours.
+
+ at item textlistmode
+ at itemx textlist
+ at itemx textstepmode
+ at itemx textstep
+If @code{textlistmode} is "manual", then the labelled contours 
+is determined by @code{textlist}.  If @code{textlistmode} is set to 
+"auto", then the distance between labelled contours is determined by 
+ at code{textstep}.  If both @code{textlistmode} and @code{textstepmode}
+are set to "auto", then there are assumed to be 10 equal spaced 
+labelled contours.
+
+ at item showtext
+Flag whether the contour labels are shown or not.
+
+ at item labelspacing
+The distance between labels on a single contour in points.
+
+ at item linewidth
+ at item linestyle
+ at item linecolor
+The properties of the contour lines.  The properties @code{linewidth} and
+ at code{linestyle} are similar to the corresponding properties for lines.  The
+property @code{linecolor} is a color property (@pxref{Colors}), that can also
+have the values of "none" or "auto".  If @code{linecolor} is "none", then no
+contour line is drawn.  If @code{linecolor} is "auto" then the line color is
+determined by the colormap.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y, and z data of the contour lines.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+Data source variables.
+ at end table
+
+ at node Error bar series
+ at subsubsection Error bar series
+ at cindex series objects
+ at cindex error bar series
+
+Error bar series are created by the @code{errorbar} function.  Each 
+ at code{hggroup} element contains two line objects representing the data and
+the errorbars separately.  The properties of the error bar series are
+
+ at table @code
+ at item color
+The RGB color or color name of the line objects of the error bars.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the error bars.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the error bars.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx ldata
+ at itemx udata
+ at itemx xldata
+ at itemx xudata
+The original x, y, l, u, xl, xu data of the error bars.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx ldatasource
+ at itemx udatasource
+ at itemx xldatasource
+ at itemx xudatasource
+Data source variables.
+ at end table
+
+ at node Line series
+ at subsubsection Line series
+ at cindex series objects
+ at cindex line series
+
+Line series objects are created by the @code{plot}  and @code{plot3}
+functions and are of the type @code{line}.  The properties of the
+line series with the ability to add data sources.
+
+ at table @code
+ at item color
+The RGB color or color name of the line objects.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y and z data.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+Data source variables.
+ at end table
+
+ at node Quiver group
+ at subsubsection Quiver group
+ at cindex group objects
+ at cindex quiver group
+
+Quiver series objects are created by the @code{quiver} or @code{quiver3}
+functions.  Each @code{hggroup} element of the series contains three line
+objects as children representing the body and head of the arrow,
+together with a marker as the point of original of the arrows.  The 
+properties of the quiver series are
+
+ at table @code
+ at item autoscale
+ at itemx autoscalefactor
+Flag whether the length of the arrows is scaled or defined directly from
+the @var{u}, @var{v} and @var{w} data.  If the arrow length is flagged
+as being scaled by the @code{autoscale} property, then the length of the
+autoscaled arrow is controlled by the @code{autoscalefactor}. 
+
+ at item maxheadsize
+This property controls the size of the head of the arrows in the quiver
+series.  The default value is 0.2.
+
+ at item showarrowhead
+Flag whether the arrow heads are displayed in the quiver plot.
+
+ at item color
+The RGB color or color name of the line objects of the quiver.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the quiver.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the marker objects at the original of the
+arrows.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The origins of the values of the vector field.
+
+ at item udata
+ at itemx vdata
+ at itemx wdata
+The values of the vector field to plot.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+ at itemx udatasource
+ at itemx vdatasource
+ at itemx wdatasource
+Data source variables.
+ at end table
+
+ at node Scatter group
+ at subsubsection Scatter group
+ at cindex group objects
+ at cindex scatter group
+
+Scatter series objects are created by the @code{scatter} or @code{scatter3}
+functions.  A single hggroup element contains as many children as there are
+points in the scatter plot, with each child representing one of the points.
+The properties of the stem series are
+
+ at table @code
+ at item linewidth
+The line width of the line objects of the points.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+The line and fill color of the markers of the points.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y and z data of the stems.
+
+ at item cdata
+The color data for the points of the plot.  Each point can have a separate
+color, or a unique color can be specified.
+
+ at item sizedata
+The size data for the points of the plot.  Each point can its own size or a 
+unique size can be specified.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+ at itemx cdatasource
+ at itemx sizedatasource
+Data source variables.
+ at end table
+
+ at node Stair group
+ at subsubsection Stair group
+ at cindex group objects
+ at cindex stair group
+
+Stair series objects are created by the @code{stair} function.  Each
+ at code{hggroup} element of the series contains a single line object as a
+child representing the stair.  The properties of the stair series are
+
+ at table @code
+ at item color
+The RGB color or color name of the line objects of the stairs.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the stairs.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the stairs.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+The original x and y data of the stairs.
+
+ at item xdatasource
+ at itemx ydatasource
+Data source variables.
+ at end table
+
+ at node Stem Series
+ at subsubsection Stem Series
+ at cindex series objects
+ at cindex stem series
+
+Stem series objects are created by the @code{stem} or @code{stem3}
+functions.  Each @code{hggroup} element contains a single line object
+as a child representing the stems.  The properties of the stem series
+are
+
+ at table @code
+ at item showbaseline
+ at itemx baseline
+ at itemx basevalue
+The property @code{showbaseline} flags whether the baseline of the
+stem series is displayed (default is "on").  The handle of the graphics
+object representing the baseline is given by the @code{baseline}
+property and the y-value (or z-value for @code{stem3}) of the baseline
+by the @code{basevalue} property.
+
+Changes to any of these property are propagated to the other members of
+the stem series and to the baseline itself.  Equally changes in the
+properties of the base line itself are propagated to the members of the
+corresponding stem series.
+
+ at item color
+The RGB color or color name of the line objects of the stems.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the stems.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the stems.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y and z data of the stems.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+Data source variables.
+ at end table
+
+ at node Surface group
+ at subsubsection Surface group
+ at cindex group objects
+ at cindex surface group
+
+Surface group objects are created by the @code{surf} or @code{mesh}
+functions, but are equally one of the handles returned by the @code{surfc}
+or @code{meshc} functions.  The surface group is of the type @code{surface}.
+
+The properties of the surface group are
+
+ at table @code
+ at item edgecolor
+ at item facecolor
+The RGB color or color name of the edges or faces of the surface.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the lines on the surface.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the surface.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+ at item cdata
+The original x, y, z and c data.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+ at itemx cdatasource
+Data source variables.
+ at end table
+
+ at node Graphics backends
+ at subsection Graphics backends
+ at cindex graphics backends
+ at cindex backends, graphics
+
+ at c ./plot/backend.m
+ at anchor{doc-backend}
+ at deftypefn  {Function File} {} backend (@var{name})
+ at deftypefnx {Function File} {} backend (@var{hlist}, @var{name})
+Change the default graphics backend to @var{name}.  If the backend is
+not already loaded, it is first initialized (initialization is done
+through the execution of @code{__init_ at var{name}__}).
+
+When called with a list of figure handles, @var{hlist}, the backend is
+changed only for the listed figures.
+ at seealso{@ref{doc-available_backends,,available_backends}}
+ at end deftypefn
+
+
+ at c graphics.cc
+ at anchor{doc-available_backends}
+ at deftypefn {Built-in Function} {} available_backends ()
+Return a cell array of registered graphics backends.
+ at end deftypefn
+
+
+ at menu
+* Interaction with gnuplot::
+ at end menu
+
+ at node Interaction with gnuplot
+ at subsubsection Interaction with @code{gnuplot}
+ at cindex gnuplot interaction
+
+ at c ./plot/gnuplot_binary.m
+ at anchor{doc-gnuplot_binary}
+ at deftypefn {Loadable Function} {@var{val} =} gnuplot_binary ()
+ at deftypefnx {Loadable Function} {@var{old_val} =} gnuplot_binary (@var{new_val})
+Query or set the name of the program invoked by the plot command.
+The default value @code{\"gnuplot\"}.  @xref{Installation}.
+ at end deftypefn
+
diff --git a/doc/interpreter/plot.txi b/doc/interpreter/plot.txi
new file mode 100644
index 0000000..ac5da13
--- /dev/null
+++ b/doc/interpreter/plot.txi
@@ -0,0 +1,2167 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005,
+ at c               2006, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Plotting
+ at chapter Plotting
+ at cindex plotting
+ at cindex graphics
+
+ at menu
+* Plotting Basics::
+* Advanced Plotting::
+ at end menu
+
+ at node Plotting Basics
+ at section Plotting Basics
+
+Octave makes it easy to create many different types of two- and
+three-dimensional plots using a few high-level functions.
+
+If you need finer control over graphics, see @ref{Advanced Plotting}.
+
+ at menu
+* Two-Dimensional Plots::       
+* Three-Dimensional Plotting::  
+* Plot Annotations::            
+* Multiple Plots on One Page::  
+* Multiple Plot Windows::       
+* Printing Plots::              
+* Interacting with plots::
+* Test Plotting Functions::     
+ at end menu
+
+ at node Two-Dimensional Plots
+ at subsection Two-Dimensional Plots
+
+The @code{plot} function allows you to create simple x-y plots with
+linear axes.  For example,
+
+ at example
+ at group
+x = -10:0.1:10;
+plot (x, sin (x));
+ at end group
+ at end example
+
+ at noindent
+displays a sine wave shown in @ref{fig:plot}.  On most systems, this
+command will open a separate plot window to display the graph.
+
+ at float Figure,fig:plot
+ at center @image{plot,4in}
+ at caption{Simple Two-Dimensional Plot.}
+ at end float
+
+ at DOCSTRING(plot)
+
+The @code{plotyy} function may be used to create a plot with two
+independent y axes.
+
+ at DOCSTRING(plotyy)
+
+The functions @code{semilogx}, @code{semilogy}, and @code{loglog} are
+similar to the @code{plot} function, but produce plots in which one or
+both of the axes use log scales.
+
+ at DOCSTRING(semilogx)
+
+ at DOCSTRING(semilogy)
+
+ at DOCSTRING(loglog)
+
+The functions @code{bar}, @code{barh}, @code{stairs}, and @code{stem}
+are useful for displaying discrete data.  For example,
+
+ at example
+ at group
+hist (randn (10000, 1), 30);
+ at end group
+ at end example
+
+ at noindent
+produces the histogram of 10,000 normally distributed random numbers
+shown in @ref{fig:hist}.
+
+ at float Figure,fig:hist
+ at center @image{hist,4in}
+ at caption{Histogram.}
+ at end float
+
+ at DOCSTRING(bar)
+
+ at DOCSTRING(barh)
+
+ at DOCSTRING(hist)
+
+ at DOCSTRING(stairs)
+
+ at DOCSTRING(stem)
+
+ at DOCSTRING(stem3)
+
+ at DOCSTRING(scatter)
+
+ at DOCSTRING(scatter3)
+
+ at DOCSTRING(plotmatrix)
+
+ at DOCSTRING(pareto)
+
+ at DOCSTRING(rose)
+
+The @code{contour}, @code{contourf} and @code{contourc} functions
+produce two-dimensional contour plots from three-dimensional data.
+
+ at DOCSTRING(contour)
+
+ at DOCSTRING(contourf)
+
+ at DOCSTRING(contourc)
+
+ at DOCSTRING(contour3)
+
+The @code{errorbar}, @code{semilogxerr}, @code{semilogyerr}, and
+ at code{loglogerr} functions produce plots with error bar markers.  For
+example,
+
+ at example
+ at group
+x = 0:0.1:10;
+y = sin (x);
+yp =  0.1 .* randn (size (x));
+ym = -0.1 .* randn (size (x));
+errorbar (x, sin (x), ym, yp);
+ at end group
+ at end example
+
+ at noindent
+produces the figure shown in @ref{fig:errorbar}.
+
+ at float Figure,fig:errorbar
+ at center @image{errorbar,4in}
+ at caption{Errorbar plot.}
+ at end float
+
+ at DOCSTRING(errorbar)
+
+ at DOCSTRING(semilogxerr)
+
+ at DOCSTRING(semilogyerr)
+
+ at DOCSTRING(loglogerr)
+
+Finally, the @code{polar} function allows you to easily plot data in
+polar coordinates.  However, the display coordinates remain rectangular
+and linear.  For example,
+
+ at example
+polar (0:0.1:10*pi, 0:0.1:10*pi);
+ at end example
+
+ at noindent
+produces the spiral plot shown in @ref{fig:polar}.
+
+ at float Figure,fig:polar
+ at center @image{polar,4in}
+ at caption{Polar plot.}
+ at end float
+
+ at DOCSTRING(polar)
+
+ at DOCSTRING(pie)
+
+ at DOCSTRING(quiver)
+
+ at DOCSTRING(quiver3)
+
+ at DOCSTRING(compass)
+
+ at DOCSTRING(feather)
+
+ at DOCSTRING(pcolor)
+
+ at DOCSTRING(area)
+
+ at DOCSTRING(comet)
+
+The axis function may be used to change the axis limits of an existing
+plot and various other axis properties, such as the aspect ratio and the
+appearance of tic marks.
+
+ at DOCSTRING(axis)
+
+Similarly the axis limits of the colormap can be changed with the caxis
+function.
+
+ at DOCSTRING(caxis)
+
+The @code{xlim}, @code{ylim}, and @code{zlim} functions may be used to
+get or set individual axis limits.  Each has the same form.
+
+ at anchor{doc-ylim}
+ at anchor{doc-zlim}
+ at DOCSTRING(xlim)
+
+ at menu
+* Two-dimensional Function Plotting::
+ at end menu
+
+ at node Two-dimensional Function Plotting
+ at subsubsection Two-dimensional Function Plotting
+
+Octave can plot a function from a function handle inline function or
+string defining the function without the user needing to explicitly
+create the data to be plotted.  The function @code{fplot} also generates
+two-dimensional plots with linear axes using a function name and limits
+for the range of the x-coordinate instead of the x and y data.  For
+example,
+
+ at example
+ at group
+fplot (@@sin, [-10, 10], 201);
+ at end group
+ at end example
+
+ at noindent
+produces a plot that is equivalent to the one above, but also includes a
+legend displaying the name of the plotted function.
+
+ at DOCSTRING(fplot)
+
+Other functions that can create two-dimensional plots directly from a
+function include @code{ezplot}, @code{ezcontour}, @code{ezcontourf} and
+ at code{ezpolar}.
+
+ at DOCSTRING(ezplot)
+
+ at DOCSTRING(ezcontour)
+
+ at DOCSTRING(ezcontourf)
+
+ at DOCSTRING(ezpolar)
+
+ at node Three-Dimensional Plotting
+ at subsection Three-Dimensional Plotting
+
+The function @code{mesh} produces mesh surface plots.  For example,
+
+ at example
+ at group
+tx = ty = linspace (-8, 8, 41)';
+[xx, yy] = meshgrid (tx, ty);
+r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+tz = sin (r) ./ r;
+mesh (tx, ty, tz);
+ at end group
+ at end example
+
+ at noindent
+produces the familiar ``sombrero'' plot shown in @ref{fig:mesh}.  Note
+the use of the function @code{meshgrid} to create matrices of X and Y
+coordinates to use for plotting the Z data.  The @code{ndgrid} function
+is similar to @code{meshgrid}, but works for N-dimensional matrices.
+
+ at float Figure,fig:mesh
+ at center @image{mesh,4in}
+ at caption{Mesh plot.}
+ at end float
+
+The @code{meshc} function is similar to @code{mesh}, but also produces a
+plot of contours for the surface.
+
+The @code{plot3} function displays arbitrary three-dimensional data,
+without requiring it to form a surface.  For example
+
+ at example
+ at group
+t = 0:0.1:10*pi;
+r = linspace (0, 1, numel (t));
+z = linspace (0, 1, numel (t));
+plot3 (r.*sin(t), r.*cos(t), z);
+ at end group
+ at end example
+
+ at noindent
+displays the spiral in three dimensions shown in @ref{fig:plot3}.
+
+ at float Figure,fig:plot3
+ at center @image{plot3,4in}
+ at caption{Three dimensional spiral.}
+ at end float
+
+Finally, the @code{view} function changes the viewpoint for
+three-dimensional plots.
+
+ at DOCSTRING(mesh)
+
+ at DOCSTRING(meshc)
+
+ at DOCSTRING(meshz)
+
+ at DOCSTRING(hidden)
+
+ at DOCSTRING(surf)
+
+ at DOCSTRING(surfc)
+
+ at DOCSTRING(surfl)
+
+ at DOCSTRING(surfnorm)
+
+ at DOCSTRING(diffuse)
+
+ at DOCSTRING(specular)
+
+ at DOCSTRING(meshgrid)
+
+ at DOCSTRING(ndgrid)
+
+ at DOCSTRING(plot3)
+
+ at DOCSTRING(view)
+
+ at DOCSTRING(slice)
+
+ at DOCSTRING(ribbon)
+
+ at DOCSTRING(shading)
+
+ at menu
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
+ at end menu
+
+ at node Three-dimensional Function Plotting
+ at subsubsection Three-dimensional Function Plotting
+
+ at DOCSTRING(ezplot3)
+
+ at DOCSTRING(ezmesh)
+
+ at DOCSTRING(ezmeshc)
+
+ at DOCSTRING(ezsurf)
+
+ at DOCSTRING(ezsurfc)
+
+ at node Three-dimensional Geometric Shapes
+ at subsubsection Three-dimensional Geometric Shapes
+
+ at DOCSTRING(cylinder)
+
+ at DOCSTRING(sphere)
+
+ at DOCSTRING(ellipsoid)
+
+ at node Plot Annotations
+ at subsection Plot Annotations
+
+You can add titles, axis labels, legends, and arbitrary text to an
+existing plot.  For example,
+
+ at example
+ at group
+x = -10:0.1:10;
+plot (x, sin (x));
+title ("sin(x) for x = -10:0.1:10");
+xlabel ("x");
+ylabel ("sin (x)");
+text (pi, 0.7, "arbitrary text");
+legend ("sin (x)");
+ at end group
+ at end example
+
+The functions @code{grid} and @code{box} may also be used to add grid
+and border lines to the plot.  By default, the grid is off and the
+border lines are on.
+
+ at DOCSTRING(title)
+
+ at DOCSTRING(legend)
+
+ at DOCSTRING(text)
+
+See @ref{Text Properties} for the properties that you can set.
+
+ at anchor{doc-ylabel}
+ at anchor{doc-zlabel}
+ at DOCSTRING(xlabel)
+
+ at DOCSTRING(clabel)
+
+ at DOCSTRING(box)
+
+ at DOCSTRING(grid)
+
+ at DOCSTRING(colorbar)
+
+ at node Multiple Plots on One Page
+ at subsection Multiple Plots on One Page
+
+Octave can display more than one plot in a single figure.  The simplest
+way to do this is to use the @code{subplot} function to divide the plot
+area into a series of subplot windows that are indexed by an integer.
+For example,
+
+ at example
+ at group
+subplot (2, 1, 1)
+fplot (@@sin, [-10, 10]);
+subplot (2, 1, 2)
+fplot (@@cos, [-10, 10]);
+ at end group
+ at end example
+
+ at noindent
+creates a figure with two separate axes, one displaying a sine wave and
+the other a cosine wave.  The first call to subplot divides the figure
+into two plotting areas (two rows and one column) and makes the first plot
+area active.  The grid of plot areas created by @code{subplot} is
+numbered in column-major order (top to bottom, left to right).
+
+ at DOCSTRING(subplot)
+
+ at node Multiple Plot Windows
+ at subsection Multiple Plot Windows
+
+You can open multiple plot windows using the @code{figure} function.
+For example
+
+ at example
+ at group
+figure (1);
+fplot (@@sin, [-10, 10]);
+figure (2);
+fplot (@@cos, [-10, 10]);
+ at end group
+ at end example
+
+ at noindent
+creates two figures, with the first displaying a sine wave and
+the second a cosine wave.  Figure numbers must be positive integers.
+
+ at DOCSTRING(figure)
+
+ at node Printing Plots
+ at subsection Printing Plots
+
+The @code{print} command allows you to save plots in a variety of
+formats.  For example,
+
+ at example
+print -deps foo.eps
+ at end example
+
+ at noindent
+writes the current figure to an encapsulated PostScript file called
+ at file{foo.eps}.
+
+ at DOCSTRING(print)
+
+ at DOCSTRING(orient)
+
+ at node Interacting with plots
+ at subsection Interacting with plots
+
+The user can select points on a plot with the @code{ginput} function or
+selection the position at which to place text on the plot with the
+ at code{gtext} function using the mouse.
+
+ at DOCSTRING(ginput)
+
+ at DOCSTRING(waitforbuttonpress)
+
+ at DOCSTRING(gtext)
+
+ at node Test Plotting Functions
+ at subsection Test Plotting Functions
+
+The functions @code{sombrero} and @code{peaks} provide a way to check
+that plotting is working.  Typing either @code{sombrero} or @code{peaks}
+at the Octave prompt should display a three-dimensional plot.
+
+ at DOCSTRING(sombrero)
+
+ at DOCSTRING(peaks)
+
+ at node Advanced Plotting
+ at section Advanced Plotting
+
+ at menu
+* Graphics Objects::
+* Graphics Object Properties::  
+* Managing Default Properties::  
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
+* Object Groups::
+* Graphics backends::
+ at end menu
+
+ at node Graphics Objects
+ at subsection Graphics Objects
+
+Plots in Octave are constructed from the following @dfn{graphics
+objects}.  Each graphics object has a set of properties that define its
+appearance and may also contain links to other graphics objects.
+Graphics objects are only referenced by a numeric index, or @dfn{handle}.
+
+ at table @asis
+ at item root figure
+ at cindex root figure graphics object
+ at cindex graphics object, root figure
+The parent of all figure objects.  The index for the root figure is
+defined to be 0.
+
+ at item figure
+ at cindex figure graphics object
+ at cindex graphics object, figure
+A figure window.
+
+ at item axes
+ at cindex axes graphics object
+ at cindex graphics object, axes
+A set of axes.  This object is a child of a figure object and may be a
+parent of line, text, image, patch, or surface objects.
+
+ at item line
+ at cindex line graphics object
+ at cindex graphics object, line
+A line in two or three dimensions.
+
+ at item text
+ at cindex text graphics object
+ at cindex graphics object, text
+Text annotations.
+
+ at item image
+ at cindex image graphics object
+ at cindex graphics object, image
+A bitmap image.
+
+ at item patch
+ at cindex patch graphics object
+ at cindex graphics object, patch
+A filled polygon, currently limited to two dimensions.
+
+ at item surface
+ at cindex surface graphics object
+ at cindex graphics object, surface 
+A three-dimensional surface.
+ at end table
+
+To determine whether a variable is a graphics object index or a figure
+index, use the functions @code{ishandle} and @code{isfigure}.
+
+ at DOCSTRING(ishandle)
+
+ at DOCSTRING(ishghandle)
+
+ at DOCSTRING(isfigure)
+
+The function @code{gcf} returns an index to the current figure object,
+or creates one if none exists.  Similarly, @code{gca} returns the
+current axes object, or creates one (and its parent figure object) if
+none exists.
+
+ at DOCSTRING(gcf)
+
+ at DOCSTRING(gca)
+
+The @code{get} and @code{set} functions may be used to examine and set
+properties for graphics objects.  For example,
+
+ at example
+ at group
+get (0)
+    @result{} ans =
+       @{
+         type = root
+         currentfigure = [](0x0)
+         children = [](0x0)
+         visible = on
+			@dots{}
+       @}
+ at end group
+ at end example
+
+ at noindent
+returns a structure containing all the properties of the root figure.
+As with all functions in Octave, the structure is returned by value, so
+modifying it will not modify the internal root figure plot object.  To
+do that, you must use the @code{set} function.  Also, note that in this
+case, the @code{currentfigure} property is empty, which indicates that
+there is no current figure window.
+
+The @code{get} function may also be used to find the value of a single
+property.  For example,
+
+ at example
+ at group
+get (gca (), "xlim")
+    @result{} [ 0 1 ]
+ at end group
+ at end example
+
+ at noindent
+returns the range of the x-axis for the current axes object in the
+current figure.
+
+To set graphics object properties, use the set function.  For example,
+
+ at example
+set (gca (), "xlim", [-10, 10]);
+ at end example
+
+ at noindent
+sets the range of the x-axis for the current axes object in the current
+figure to @samp{[-10, 10]}.  Additionally, calling set with a graphics
+object index as the only argument returns a structure containing the
+default values for all the properties for the given object type.  For
+example,
+
+ at example
+set (gca ())
+ at end example
+
+ at noindent
+returns a structure containing the default property values for axes
+objects.
+
+ at DOCSTRING(get)
+
+ at DOCSTRING(set)
+
+ at DOCSTRING(ancestor)
+
+ at DOCSTRING(allchild)
+
+You can create axes, line, and patch objects directly using the
+ at code{axes}, @code{line}, and @code{patch} functions.  These objects
+become children of the current axes object.
+
+ at DOCSTRING(axes)
+
+ at DOCSTRING(line)
+
+ at DOCSTRING(patch)
+
+ at DOCSTRING(fill)
+
+ at DOCSTRING(surface)
+
+By default, Octave refreshes the plot window when a prompt is printed,
+or when waiting for input.  To force an update at other times, call the
+ at code{drawnow} function.
+
+ at DOCSTRING(drawnow)
+
+Only figures that are modified will be updated.  The @code{refresh}
+function can also be used to force an update of the current figure, even if
+it is not modified.
+
+ at DOCSTRING(refresh)
+
+Normally, high-level plot functions like @code{plot} or @code{mesh} call
+ at code{newplot} to initialize the state of the current axes so that the
+next plot is drawn in a blank window with default property settings.  To
+have two plots superimposed over one another, use the @code{hold}
+function.  For example,
+
+ at example
+ at group
+hold on;
+x = -10:0.1:10;
+plot (x, sin (x));
+plot (x, cos (x));
+hold off;
+ at end group
+ at end example
+
+ at noindent
+displays sine and cosine waves on the same axes.  If the hold state is
+off, consecutive plotting commands like this will only display the last
+plot.
+
+ at DOCSTRING(newplot)
+
+ at DOCSTRING(hold)
+
+ at DOCSTRING(ishold)
+
+To clear the current figure, call the @code{clf} function.  To clear the
+current axis, call the @code{cla} function.  To bring the current figure
+to the top of the window stack, call the @code{shg} function.  To delete
+a graphics object, call @code{delete} on its index.  To close the
+figure window, call the @code{close} function.
+
+ at DOCSTRING(clf)
+
+ at DOCSTRING(cla)
+
+ at DOCSTRING(shg)
+
+ at DOCSTRING(delete)
+
+ at DOCSTRING(close)
+
+ at DOCSTRING(closereq)
+
+ at node Graphics Object Properties
+ at subsection Graphics Object Properties
+ at cindex graphics object properties
+
+ at menu
+* Root Figure Properties::      
+* Figure Properties::           
+* Axes Properties::             
+* Line Properties::             
+* Text Properties::             
+* Image Properties::            
+* Patch Properties::            
+* Surface Properties::          
+* Searching Properties::
+ at end menu
+
+ at node Root Figure Properties
+ at subsubsection Root Figure Properties
+
+ at table @code
+ at item currentfigure
+Index to graphics object for the current figure.
+
+ at c FIXME -- does this work?
+ at c @item visible
+ at c Either @code{"on"} or @code{"off"} to toggle display of figures.
+ at end table
+
+ at node Figure Properties
+ at subsubsection Figure Properties
+ at cindex figure properties
+
+ at table @code
+ at item nextplot
+May be one of
+ at table @code
+ at item "new"
+ at item "add"
+ at item "replace"
+ at item "replacechildren"
+ at end table
+
+ at item closerequestfcn
+Handle of function to call when a figure is closed.
+
+ at item currentaxes
+Index to graphics object of current axes.
+
+ at item colormap
+An N-by-3 matrix containing the color map for the current axes.
+
+ at item visible
+Either @code{"on"} or @code{"off"} to toggle display of the figure.
+
+ at item paperorientation
+Indicates the orientation for printing.  Either @code{"landscape"} or
+ at code{"portrait"}.
+ at end table
+
+ at node Axes Properties
+ at subsubsection Axes Properties
+ at cindex axes properties
+
+ at table @code
+ at item position
+A vector specifying the position of the plot, excluding titles, axes and
+legend.  The four elements of the vector are the coordinates of the
+lower left corner and width and height of the plot, in units normalized
+to the width and height of the plot window.  For example, @code{[0.2,
+0.3, 0.4, 0.5]} sets the lower left corner of the axes at @math{(0.2,
+0.3)} and the width and height to be 0.4 and 0.5 respectively.  See also
+the @code{outerposition} property.
+
+ at item title
+Index of text object for the axes title.
+
+ at item box
+Either @code{"on"} or @code{"off"} to toggle display of the box around
+the axes.
+
+ at item key
+Either @code{"on"} or @code{"off"} to toggle display of the legend.
+Note that this property is not compatible with @sc{matlab} and may be
+removed in a future version of Octave.
+
+ at item keybox
+Either @code{"on"} or @code{"off"} to toggle display of a box around the
+legend.  Note that this property is not compatible with @sc{matlab} and
+may be removed in a future version of Octave.
+
+ at item keypos
+An integer from 1 to 4 specifying the position of the legend.  1
+indicates upper right corner, 2 indicates upper left, 3 indicates lower
+left, and 4 indicates lower right.  Note that this property is not
+compatible with @sc{matlab} and may be removed in a future version of
+Octave.
+
+ at item dataaspectratio
+A two-element vector specifying the relative height and width of the
+data displayed in the axes.  Setting @code{dataaspectratio} to @samp{1,
+2]} causes the length of one unit as displayed on the y-axis to be the
+same as the length of 2 units on the x-axis.  Setting
+ at code{dataaspectratio} also forces the @code{dataaspectratiomode}
+property to be set to @code{"manual"}.
+
+ at item dataaspectratiomode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xlim
+ at itemx ylim
+ at itemx zlim
+ at itemx clim
+Two-element vectors defining the limits for the x, y, and z axes and the 
+Setting one of these properties also forces the corresponding mode
+property to be set to @code{"manual"}.
+
+ at item xlimmode
+ at itemx ylimmode
+ at itemx zlimmode
+ at itemx climmode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xlabel
+ at itemx ylabel
+ at itemx zlabel
+Indices to text objects for the axes labels.
+
+ at item xgrid
+ at itemx ygrid
+ at itemx zgrid
+Either @code{"on"} or @code{"off"} to toggle display of grid lines.
+
+ at item xminorgrid
+ at itemx yminorgrid
+ at itemx zminorgrid
+Either @code{"on"} or @code{"off"} to toggle display of minor grid lines.
+
+ at item xtick
+ at itemx ytick
+ at itemx ztick
+Setting one of these properties also forces the corresponding mode
+property to be set to @code{"manual"}.
+
+ at item xtickmode
+ at itemx ytickmode
+ at itemx ztickmode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xticklabel
+ at itemx yticklabel
+ at itemx zticklabel
+Setting one of these properties also forces the corresponding mode
+property to be set to @code{"manual"}.
+
+ at item xticklabelmode
+ at itemx yticklabelmode
+ at itemx zticklabelmode
+Either @code{"manual"} or @code{"auto"}.
+
+ at item xscale
+ at itemx yscale
+ at itemx zscale
+Either @code{"linear"} or @code{"log"}.
+
+ at item xdir
+ at itemx ydir
+ at itemx zdir
+Either @code{"forward"} or @code{"reverse"}.
+
+ at item xaxislocation
+ at itemx yaxislocation
+Either @code{"top"} or @code{"bottom"} for the x-axis and @code{"left"}
+or @code{"right"} for the y-axis.
+
+ at item view
+A three element vector specifying the view point for three-dimensional plots.
+
+ at item visible
+Either @code{"on"} or @code{"off"} to toggle display of the axes.
+
+ at item nextplot
+May be one of
+ at table @code
+ at item "new"
+ at item "add"
+ at item "replace"
+ at item "replacechildren"
+ at end table
+
+ at item outerposition
+A vector specifying the position of the plot, including titles, axes and
+legend.  The four elements of the vector are the coordinates of the
+lower left corner and width and height of the plot, in units normalized
+to the width and height of the plot window.  For example, @code{[0.2,
+0.3, 0.4, 0.5]} sets the lower left corner of the axes at @math{(0.2,
+0.3)} and the width and height to be 0.4 and 0.5 respectively.  See also
+the @code{position} property.
+ at end table
+
+ at node Line Properties
+ at subsubsection Line Properties
+ at cindex line properties
+
+ at table @code
+ at itemx xdata
+ at itemx ydata
+ at itemx zdata
+ at itemx ldata
+ at itemx udata
+ at itemx xldata
+ at itemx xudata
+The data to be plotted.  The @code{ldata} and @code{udata} elements are
+for errorbars in the y direction, and the @code{xldata} and @code{xudata}
+elements are for errorbars in the x direction.
+
+ at item color
+The RGB color of the line, or a color name.  @xref{Colors}.
+
+ at item linestyle
+ at itemx linewidth
+ at xref{Line Styles}.
+
+ at item marker
+ at item markeredgecolor
+ at item markerfacecolor
+ at item markersize
+ at xref{Marker Styles}.
+
+ at item keylabel
+The text of the legend entry corresponding to this line.  Note that this
+property is not compatible with @sc{matlab} and may be removed in a
+future version of Octave.
+ at end table
+
+ at node Text Properties
+ at subsubsection Text Properties
+ at cindex text properties
+
+ at table @code
+ at item string
+The character string contained by the text object.
+
+ at item units
+May be @code{"normalized"} or @code{"graph"}.
+
+ at item position
+The coordinates of the text object.
+
+ at item rotation
+The angle of rotation for the displayed text, measured in degrees.
+
+ at item horizontalalignment
+May be @code{"left"}, @code{"center"}, or @code{"right"}.
+
+ at item color
+The color of the text.  @xref{Colors}.
+
+ at item fontname
+The font used for the text.
+
+ at item fontsize
+The size of the font, in points to use.
+
+ at item fontangle
+Flag whether the font is italic or normal.  Valid values are 'normal',
+'italic' and 'oblique'.
+
+ at item fontweight
+Flag whether the font is bold, etc.  Valid values are 'normal', 'bold',
+'demi' or 'light'.
+
+ at item interpreter
+Determines how the text is rendered.  Valid values are 'none', 'tex' or
+'latex'.
+ at end table
+
+All text objects, including titles, labels, legends, and text, include
+the property 'interpreter', this property determines the manner in which
+special control sequences in the text are rendered.  If the interpreter
+is set to 'none', then no rendering occurs.  At this point the 'latex'
+option is not implemented and so the 'latex' interpreter also does not
+interpret the text.
+
+The 'tex' option implements a subset of @sc{TeX} functionality in the
+rendering of the text.  This allows the insertion of special characters
+such as Greek or mathematical symbols within the text.  The special
+characters are also inserted with a code starting with the back-slash
+(\) character, as in the table @ref{tab:extended}. 
+
+In addition, the formatting of the text can be changed within the string
+with the codes 
+
+ at multitable @columnfractions .2 .2 .6 .2
+ at item @tab \bf @tab Bold font @tab
+ at item @tab \it @tab Italic font @tab
+ at item @tab \sl @tab Oblique Font @tab
+ at item @tab \rm @tab Normal font @tab
+ at end multitable
+
+These are be used in conjunction with the @{ and @} characters to limit
+the change in the font to part of the string.  For example
+
+ at example
+xlabel ('@{\bf H@} = a @{\bf V@}')
+ at end example
+
+where the character 'a' will not appear in a bold font.  Note that to
+avoid having Octave interpret the backslash characters in the strings,
+the strings should be in single quotes.
+
+It is also possible to change the fontname and size within the text 
+
+ at multitable @columnfractions .1 .4 .6 .1
+ at item @tab \fontname@{@var{fontname}@} @tab Specify the font to use @tab
+ at item @tab \fontsize@{@var{size}@} @tab Specify the size of the font to
+use @tab
+ at end multitable
+
+Finally, the superscript and subscripting can be controlled with the '^'
+and '_' characters.  If the '^' or '_' is followed by a @{ character,
+then all of the block surrounded by the @{ @} pair is super- or
+sub-scripted.  Without the @{ @} pair, only the character immediately
+following the '^' or '_' is super- or sub-scripted.
+
+ at float Table,tab:extended
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & # \vrule &
+# \hfil & \vrule # & # \hfil & # \vrule &
+# \hfil & \vrule # & # \hfil & # \vrule 
+width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& Code && Sym && Code && Sym && Code && Sym &\cr
+\noalign{\hrule}
+& $\backslash$forall    && $\forall$ 
+&& $\backslash$exists   && $\exists$ 
+&& $\backslash$ni       && $\ni$       &\cr
+& $\backslash$cong      && $\cong$ 
+&& $\backslash$Delta    && $\Delta$ 
+&& $\backslash$Phi      && $\Phi$      &\cr
+& $\backslash$Gamma     && $\Gamma$ 
+&& $\backslash$vartheta && $\vartheta$ 
+&& $\backslash$Lambda   && $\Lambda$   &\cr
+& $\backslash$Pi        && $\Pi$ 
+&& $\backslash$Theta    && $\Theta$ 
+&& $\backslash$Sigma    && $\Sigma$    &\cr
+& $\backslash$varsigma  && $\varsigma$ 
+&& $\backslash$Omega    && $\Omega$ 
+&& $\backslash$Xi       && $\Xi$       &\cr
+& $\backslash$Psi       && $\Psi$ 
+&& $\backslash$perp     && $\perp$ 
+&& $\backslash$alpha    && $\alpha$    &\cr
+& $\backslash$beta      && $\beta$ 
+&& $\backslash$chi      && $\chi$ 
+&& $\backslash$delta    && $\delta$    &\cr
+& $\backslash$epsilon   && $\epsilon$ 
+&& $\backslash$phi      && $\phi$ 
+&& $\backslash$gamma    && $\gamma$    &\cr
+& $\backslash$eta       && $\eta$ 
+&& $\backslash$iota     && $\iota$ 
+&& $\backslash$varphi   && $\varphi$   &\cr
+& $\backslash$kappa     && $\kappa$ 
+&& $\backslash$lambda   && $\lambda$ 
+&& $\backslash$mu       && $\mu$       &\cr
+& $\backslash$nu        && $\nu$ 
+&& $\backslash$o        && $\o$ 
+&& $\backslash$pi       && $\pi$       &\cr
+& $\backslash$theta     && $\theta$ 
+&& $\backslash$rho      && $\rho$ 
+&& $\backslash$sigma    && $\sigma$    &\cr
+& $\backslash$tau       && $\tau$
+&& $\backslash$upsilon  && $\upsilon$ 
+&& $\backslash$varpi    && $\varpi$    &\cr
+& $\backslash$omega     && $\omega$ 
+&& $\backslash$xi       && $\xi$ 
+&& $\backslash$psi      && $\psi$      &\cr
+& $\backslash$zeta      && $\zeta$ 
+&& $\backslash$sim      && $\sim$ 
+&& $\backslash$Upsilon  && $\Upsilon$  &\cr
+& $\backslash$prime     && $\prime$ 
+&& $\backslash$leq      && $\leq$ 
+&& $\backslash$infty    && $\infty$    &\cr
+& $\backslash$clubsuit  && $\clubsuit$ 
+&& $\backslash$diamondsuit    && $\diamondsuit$ 
+&& $\backslash$heartsuit      && $\heartsuit$     &\cr
+& $\backslash$spadesuit       && $\spadesuit$ 
+&& $\backslash$leftrightarrow && $\leftrightarrow$ 
+&& $\backslash$leftarrow      && $\leftarrow$     &\cr
+& $\backslash$uparrow         && $\uparrow$ 
+&& $\backslash$rightarrow     && $\rightarrow$ 
+&& $\backslash$downarrow      && $\downarrow$     &\cr
+& $\backslash$circ      && $\circ$ 
+&& $\backslash$pm       && $\pm$ 
+&& $\backslash$geq      && $\geq$      &\cr
+& $\backslash$times     && $\times$ 
+&& $\backslash$propto   && $\propto$ 
+&& $\backslash$partial  && $\partial$  &\cr
+& $\backslash$bullet    && $\bullet$
+&& $\backslash$div      && $\div$ 
+&& $\backslash$neq      && $\neq$      &\cr
+& $\backslash$equiv     && $\equiv$ 
+&& $\backslash$approx   && $\approx$ 
+&& $\backslash$ldots    && $\ldots$ &\cr
+& $\backslash$mid       && $\mid$ 
+&& $\backslash$aleph    && $\aleph$ 
+&& $\backslash$Im       && $\Im$ &\cr
+& $\backslash$Re        && $\Re$ 
+&& $\backslash$wp       && $\wp$ 
+&& $\backslash$otimes   && $\otimes$ &\cr
+& $\backslash$oplus     && $\oplus$ 
+&& $\backslash$oslash   && $\oslash$ 
+&& $\backslash$cap      && $\cap$ &\cr
+& $\backslash$cup       && $\cup$ 
+&& $\backslash$supset   && $\supset$ 
+&& $\backslash$supseteq && $\supseteq$ &\cr
+& $\backslash$subset    && $\subset$ 
+&& $\backslash$subseteq && $\subseteq$ 
+&& $\backslash$in       && $\in$ &\cr
+& $\backslash$notin     && $\notin$
+&& $\backslash$angle    && $\angle$
+&& $\backslash$bigtriangledown && $\bigtriangledown$ &\cr
+& $\backslash$langle    && $\langle$ 
+&& $\backslash$rangle   && $\rangle$ 
+&& $\backslash$nabla    && $\nabla$    &\cr
+& $\backslash$prod      && $\prod$
+&& $\backslash$surd     && $\surd$ 
+&& $\backslash$cdot     && $\cdot$     &\cr
+& $\backslash$neg       && $\neg$ 
+&& $\backslash$wedge    && $\wedge$ 
+&& $\backslash$vee      && $\vee$      &\cr
+& $\backslash$Leftrightarrow && $\Leftrightarrow$
+&& $\backslash$Leftarrow     && $\Leftarrow$
+&& $\backslash$Uparrow       && $\Uparrow$           &\cr
+& $\backslash$Rightarrow     && $\Rightarrow$
+&& $\backslash$Downarrow     && $\Downarrow$
+&& $\backslash$diamond  && $\diamond$  &\cr
+& $\backslash$copyright && $\copyright$ 
+&& $\backslash$rfloor   && $\rfloor$ 
+&& $\backslash$lceil    && $\lceil$    &\cr
+& $\backslash$lfloor    && $\lfloor$ 
+&& $\backslash$rceil    && $\rceil$ 
+&& $\backslash$int      && $\int$      &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .125 .25 .25 .25 .125
+ at item @tab  \forall     @tab  \exists     @tab  \ni      @tab
+ at item @tab  \cong       @tab  \Delta      @tab  \Phi     @tab
+ at item @tab  \Gamma      @tab  \vartheta   @tab  \Lambda  @tab
+ at item @tab  \Pi         @tab  \Theta      @tab  \Sigma   @tab
+ at item @tab  \varsigma   @tab  \Omega      @tab  \Xi      @tab
+ at item @tab  \Psi        @tab  \perp       @tab  \alpha   @tab
+ at item @tab  \beta       @tab  \chi        @tab  \delta   @tab  
+ at item @tab  \epsilon    @tab  \phi        @tab  \gamma   @tab
+ at item @tab  \eta        @tab  \iota       @tab  \varphi  @tab
+ at item @tab  \kappa      @tab  \lambda     @tab  \mu      @tab 
+ at item @tab  \nu         @tab  \o          @tab  \pi      @tab
+ at item @tab  \theta      @tab  \rho        @tab  \sigma   @tab 
+ at item @tab  \tau        @tab  \upsilon    @tab  \varpi   @tab
+ at item @tab  \omega      @tab  \xi         @tab  \psi     @tab 
+ at item @tab  \zeta       @tab  \sim        @tab  \Upsilon @tab
+ at item @tab  \prime      @tab  \leq        @tab  \infty   @tab
+ at item @tab  \clubsuit   @tab  \diamondsuit    @tab  \heartsuit  @tab
+ at item @tab  \spadesuit  @tab  \leftrightarrow @tab  \leftarrow  @tab 
+ at item @tab  \uparrow    @tab  \rightarrow @tab  \downarrow @tab 
+ at item @tab  \circ       @tab \pm          @tab  \geq     @tab 
+ at item @tab  \times      @tab  \propto     @tab  \partial @tab
+ at item @tab  \bullet     @tab \div         @tab  \neq     @tab 
+ at item @tab  \equiv      @tab  \approx     @tab  \ldots   @tab 
+ at item @tab  \mid        @tab  \aleph      @tab  \Im      @tab 
+ at item @tab  \Re         @tab \wp          @tab  \otimes  @tab
+ at item @tab  \oplus      @tab \oslash      @tab  \cap     @tab 
+ at item @tab  \cup        @tab   \supset    @tab  \supseteq @tab 
+ at item @tab  \subset     @tab \subseteq    @tab  \in      @tab 
+ at item @tab  \notin      @tab \angle       @tab  \bigrightriangledown @tab
+ at item @tab  \langle     @tab  \rangle     @tab  \nabla   @tab
+ at item @tab  \prod       @tab \surd        @tab  \cdot    @tab 
+ at item @tab  \neg        @tab  \wedge      @tab \vee      @tab 
+ at item @tab  \Leftrightarrow @tab \Leftarrow @tab \Uparrow @tab
+ at item @tab  \Rightarrow @tab \Downarrow   @tab \diamond  @tab
+ at item @tab  \copyright  @tab  \lfloor     @tab  \lceil   @tab 
+ at item @tab  \rfloor     @tab  \rceil      @tab  \int     @tab 
+ at end multitable
+ at end ifnottex
+ at caption{Available special characters in @sc{TeX} mode}
+ at end float
+
+A complete example showing the capabilities of the extended text is
+
+ at example
+ at group
+x = 0:0.01:3;
+plot(x,erf(x));
+hold on;
+plot(x,x,"r");
+axis([0, 3, 0, 1]);
+text(0.65, 0.6175, strcat('\leftarrow x = @{2/\surd\pi',
+' @{\fontsize@{16@}\int_@{\fontsize@{8@}0@}^@{\fontsize@{8@}x@}@}',
+' e^@{-t^2@} dt@} = 0.6175'))
+ at end group
+ at end example
+
+ at ifnotinfo
+ at noindent
+The result of which can be seen in @ref{fig:extendedtext}
+
+ at float Figure,fig:extendedtext
+ at center @image{extended,4in}
+ at caption{Example of inclusion of text with the @sc{TeX} interpreter}
+ at end float
+ at end ifnotinfo
+
+ at node Image Properties
+ at subsubsection Image Properties
+ at cindex image properties
+
+ at table @code
+ at item cdata
+The data for the image.  Each pixel of the image corresponds to an
+element of @code{cdata}.  The value of an element of @code{cdata}
+specifies the row-index into the colormap of the axes object containing
+the image.  The color value found in the color map for the given index
+determines the color of the pixel.
+
+ at item xdata
+ at itemx ydata
+Two-element vectors specifying the range of the x- and y- coordinates for
+the image.
+ at end table
+
+ at node Patch Properties
+ at subsubsection Patch Properties
+ at cindex patch properties
+
+ at table @code
+ at item cdata
+ at itemx xdata
+ at itemx ydata
+ at itemx zdata
+Data defining the patch object.
+
+ at item facecolor
+The fill color of the patch.  @xref{Colors}.
+
+ at item facealpha
+A number in the range [0, 1] indicating the transparency of the patch.
+
+ at item edgecolor
+The color of the line defining the patch.  @xref{Colors}.
+
+ at item linestyle
+ at itemx linewidth
+ at xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+ at xref{Marker Styles}.
+ at end table
+
+ at node Surface Properties
+ at subsubsection Surface Properties
+ at cindex surface properties
+
+ at table @code
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The data determining the surface.  The @code{xdata} and @code{ydata}
+elements are vectors and @code{zdata} must be a matrix.
+
+ at item keylabel
+The text of the legend entry corresponding to this surface.  Note that
+this property is not compatible with @sc{matlab} and may be removed in a
+future version of Octave.
+ at end table
+
+ at node Searching Properties
+ at subsubsection Searching Properties
+
+ at DOCSTRING(findobj)
+
+ at DOCSTRING(findall)
+
+
+ at node Managing Default Properties
+ at subsection Managing Default Properties
+ at cindex default graphics properties
+ at cindex graphics properties, default
+
+Object properties have two classes of default values, @dfn{factory
+defaults} (the initial values) and @dfn{user-defined defaults}, which
+may override the factory defaults.
+
+Although default values may be set for any object, they are set in
+parent objects and apply to child objects.  For example,
+
+ at example
+set (0, "defaultlinecolor", "green");
+ at end example
+
+ at noindent
+sets the default line color for all objects.  The rule for constructing
+the property name to set a default value is
+
+ at example
+default + @var{object-type} + @var{property-name}
+ at end example
+
+This rule can lead to some strange looking names, for example
+ at code{defaultlinelinewidth"} specifies the default @code{linewidth}
+property for @code{line} objects.
+
+The example above used the root figure object, 0, so the default
+property value will apply to all line objects.  However, default values
+are hierarchical, so defaults set in a figure objects override those
+set in the root figure object.  Likewise, defaults set in axes objects
+override those set in figure or root figure objects.  For example,
+
+ at example
+ at group
+subplot (2, 1, 1);
+set (0, "defaultlinecolor", "red");
+set (1, "defaultlinecolor", "green");
+set (gca (), "defaultlinecolor", "blue");
+line (1:10, rand (1, 10));
+subplot (2, 1, 2);
+line (1:10, rand (1, 10));
+figure (2)
+line (1:10, rand (1, 10));
+ at end group
+ at end example
+
+ at noindent
+produces two figures.  The line in first subplot window of the first
+figure is blue because it inherits its color from its parent axes
+object.  The line in the second subplot window of the first figure is
+green because it inherits its color from its parent figure object.  The
+line in the second figure window is red because it inherits its color
+from the global root figure parent object.
+
+To remove a user-defined default setting, set the default property to
+the value @code{"remove"}.  For example,
+
+ at example
+set (gca (), "defaultlinecolor", "remove");
+ at end example
+
+ at noindent
+removes the user-defined default line color setting from the current axes
+object.
+
+Getting the @code{"default"} property of an object returns a list of
+user-defined defaults set for the object.  For example,
+
+ at example
+get (gca (), "default");
+ at end example
+
+ at noindent
+returns a list of user-defined default values for the current axes
+object.
+
+Factory default values are stored in the root figure object.  The
+command
+
+ at example
+get (0, "factory");
+ at end example
+
+ at noindent
+returns a list of factory defaults.
+
+ at node Colors
+ at subsection Colors
+ at cindex graphics colors
+ at cindex colors, graphics
+
+Colors may be specified as RGB triplets with values ranging from zero to
+one, or by name.  Recognized color names include @code{"blue"},
+ at code{"black"}, @code{"cyan"}, @code{"green"}, @code{"magenta"},
+ at code{"red"}, @code{"white"}, and @code{"yellow"}.
+
+ at node Line Styles
+ at subsection Line Styles
+ at cindex line styles, graphics
+ at cindex graphics line styles
+
+Line styles are specified by the following properties:
+
+ at table @code
+ at item linestyle
+May be one of
+ at table @code
+ at item "-"
+Solid lines.
+ at item "--"
+Dashed lines.
+ at item ":"
+Points.
+ at item "-."
+A dash-dot line.
+ at end table
+
+ at item linewidth
+A number specifying the width of the line.  The default is 1.  A value
+of 2 is twice as wide as the default, etc.
+ at end table
+
+ at node Marker Styles
+ at subsection Marker Styles
+ at cindex graphics marker styles
+ at cindex marker styles, graphics
+
+Marker styles are specified by the following properties:
+ at table @code
+ at item marker
+A character indicating a plot marker to be place at each data point, or
+ at code{"none"}, meaning no markers should be displayed.
+
+ at itemx markeredgecolor
+The color of the edge around the marker, or @code{"auto"}, meaning that
+the edge color is the same as the face color.  @xref{Colors}.
+
+ at itemx markerfacecolor
+The color of the marker, or @code{"none"} to indicate that the marker
+should not be filled.  @xref{Colors}.
+
+ at itemx markersize
+A number specifying the size of the marker.  The default is 1.  A value
+of 2 is twice as large as the default, etc.
+ at end table
+
+ at node Callbacks
+ at subsection Callbacks
+ at cindex callbacks
+
+Callback functions can be associated with graphics objects and triggered
+after certain events occur.  The basic structure of all callback function
+is 
+
+ at example
+ at group
+function mycallback (src, data)
+ at dots{}
+endfunction
+ at end group
+ at end example
+
+where @code{src} gives a handle to the source of the callback, and
+ at code{code} gives some event specific data.  This can then be associated
+with an object either at the objects creation or later with the
+ at code{set} function.  For example
+
+ at example
+plot (x, "DeleteFcn", @@(s, e) disp("Window Deleted"))
+ at end example
+
+ at noindent
+where at the moment that the plot is deleted, the message "Window
+Deleted" will be displayed.
+
+Additional user arguments can be passed to callback functions, and will
+be passed after the 2 default arguments.  For example
+
+ at example
+ at group
+plot (x, "DeleteFcn", @{@@mycallback, "1"@})
+ at dots{}
+function mycallback (src, data, a1)
+  fprintf ("Closing plot %d\n", a1);
+endfunction
+ at end group
+ at end example
+
+The basic callback functions that are available for all graphics objects
+are
+
+ at itemize @bullet
+ at item CreateFcn
+This is the callback that is called at the moment of the objects
+creation.  It is not called if the object is altered in any way, and so
+it only makes sense to define this callback in the function call that
+defines the object.  Callbacks that are added to @code{CreateFcn} later with
+the @code{set} function will never be executed.
+
+ at item DeleteFcn
+This is the callback that is called at the moment an object is deleted.
+
+ at item ButtonDownFcn
+This is the callback that is called if a mouse button is pressed while
+the pointer is over this object.  Note, that the gnuplot interface does
+not respect this callback.
+ at end itemize
+
+The object and figure that the event occurred in that resulted in the
+callback being called can be found with the @code{gcbo} and @code{gcbf}
+functions.
+
+ at DOCSTRING(gcbo)
+
+ at DOCSTRING(gcbf)
+
+Callbacks can equally be added to properties with the @code{addlistener}
+function described below.
+
+ at node Object Groups
+ at subsection Object Groups
+ at cindex object groups
+
+A number of Octave high level plot functions return groups of other
+graphics objects or they return graphics objects that are have their
+properties linked in such a way that changes to one of the properties
+results in changes in the others.  A graphic object that groups other
+objects is an @code{hggroup}
+
+ at DOCSTRING(hggroup)
+
+For example a simple use of a @code{hggroup} might be
+
+ at example
+ at group
+x = 0:0.1:10;
+hg = hggroup ();
+plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+hold on
+plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+set (hg, "visible", "off");
+ at end group
+ at end example
+
+ at noindent
+which groups the two plots into a single object and controls their
+visibility directly.  The default properties of an @code{hggroup} are
+the same as the set of common properties for the other graphics
+objects.  Additional properties can be added with the @code{addproperty}
+function. 
+
+ at DOCSTRING(addproperty)
+
+Once a property in added to an @code{hggroup}, it is not linked to any
+other property of either the children of the group, or any other
+graphics object.  Add so to control the way in which this newly added
+property is used, the @code{addlistener} function is used to define a
+callback function that is executed when the property is altered.
+
+ at DOCSTRING(addlistener)
+
+ at DOCSTRING(dellistener)
+
+An example of the use of these two functions might be
+
+ at example
+ at group
+x = 0:0.1:10;
+hg = hggroup ();
+h = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+addlistener (hg, "linestyle", @@update_props);
+hold on
+plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+
+function update_props (h, d)
+  set (get (h, "children"), "linestyle", get (h, "linestyle"));
+endfunction
+ at end group
+ at end example
+
+ at noindent
+that adds a @code{linestyle} property to the @code{hggroup} and
+propagating any changes its value to the children of the group.  The
+ at code{linkprop} function can be used to simplify the above to be
+
+ at example
+ at group
+x = 0:0.1:10;
+hg = hggroup ();
+h1 = plot (x, sin (x), "color", [1, 0, 0], "parent", hg);
+addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle"));
+hold on
+h2 = plot (x, cos (x), "color", [0, 1, 0], "parent", hg);
+hlink = linkprop ([hg, h1, h2], "color"); 
+ at end group
+ at end example
+
+ at DOCSTRING(linkprop)
+
+These capabilities are used in a number of basic graphics objects. 
+The @code{hggroup} objects created by the functions of Octave contain
+one or more graphics object and are used to:
+
+ at itemize @bullet
+ at item group together multiple graphics objects,
+ at item create linked properties between different graphics objects, and
+ at item to hide the nominal user data, from the actual data of the objects.
+ at end itemize
+
+ at noindent
+For example the @code{stem} function creates a stem series where each
+ at code{hggroup} of the stem series contains two line objects representing
+the body and head of the stem.  The @code{ydata} property of the
+ at code{hggroup} of the stem series represents the head of the stem,
+whereas the body of the stem is between the baseline and this value.  For
+example
+
+ at example
+ at group
+h = stem (1:4)
+get (h, "xdata")
+ at result{} [  1   2   3   4]'
+get (get (h, "children")(1), "xdata")
+ at result{} [  1   1 NaN   2   2 NaN   3   3 NaN   4   4 NaN]'
+ at end group
+ at end example
+
+ at noindent
+shows the difference between the @code{xdata} of the @code{hggroup}
+of a stem series object and the underlying line.
+
+The basic properties of such group objects is that they consist of one 
+or more linked @code{hggroup}, and that changes in certain properties of
+these groups are propagated to other members of the group.  Whereas,
+certain properties of the members of the group only apply to the current
+member.
+
+In addition the members of the group can also be linked to other
+graphics objects through callback functions.  For example the baseline of
+the @code{bar} or @code{stem} functions is a line object, whose length
+and position are automatically adjusted, based on changes to the
+corresponding hggroup elements.
+
+ at menu
+* Data sources in object groups::
+* Area series::
+* Bar series::
+* Contour groups::
+* Error bar series::
+* Line series::
+* Quiver group::
+* Scatter group::
+* Stair group::
+* Stem Series::
+* Surface group::
+ at end menu
+
+ at node Data sources in object groups
+ at subsubsection Data sources in object groups
+ at cindex data sources in object groups
+
+All of the group objects contain data source parameters.  There are
+string parameters that contain an expression that is evaluated to update
+the relevant data property of the group when the @code{refreshdata}
+function is called. 
+
+ at DOCSTRING(refreshdata)
+
+ at anchor{doc-linkdata}
+ at c add the description of the linkdata function here when it is written
+ at c remove the explicit anchor when you add the corresponding @DOCSTRING
+ at c command
+
+ at node Area series
+ at subsubsection Area series
+ at cindex series objects
+ at cindex area series
+
+Area series objects are created by the @code{area} function.  Each of the
+ at code{hggroup} elements contains a single patch object.  The properties
+of the area series are
+
+ at table @code
+ at item basevalue
+The value where the base of the area plot is drawn.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the edge of the patch objects making up the
+areas.  @xref{Line Styles}.
+
+ at item edgecolor
+ at itemx facecolor
+The line and fill color of the patch objects making up the areas.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+The x and y coordinates of the original columns of the data passed to
+ at code{area} prior to the cumulative summation used in the @code{area}
+function. 
+
+ at item xdatasource
+ at itemx ydatasource
+Data source variables.
+ at end table
+
+ at node Bar series
+ at subsubsection Bar series
+ at cindex series objects
+ at cindex bar series
+
+Bar series objects are created by the @code{bar} or @code{barh}
+functions.  Each @code{hggroup} element contains a single patch object. 
+The properties of the bar series are
+
+ at table @code
+ at item showbaseline
+ at itemx baseline
+ at itemx basevalue
+The property @code{showbaseline} flags whether the baseline of the bar
+series is displayed (default is "on").  The handle of the graphics object
+representing the baseline is given by the @code{baseline} property and
+the y-value of the baseline by the @code{basevalue} property. 
+
+Changes to any of these property are propagated to the other members of
+the bar series and to the baseline itself.  Equally changes in the
+properties of the base line itself are propagated to the members of the
+corresponding bar series.
+
+ at item barwidth
+ at itemx barlayout
+ at itemx horizontal
+The property @code{barwidth} is the width of the bar corresponding to
+the @var{width} variable passed to @code{bar} or @var{barh}.  Whether the
+bar series is "grouped" or "stacked" is determined by the
+ at code{barlayout} property and whether the bars are horizontal or
+vertical by the @code{horizontal} property.
+
+Changes to any of these property are propagated to the other members of
+the bar series.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the edge of the patch objects making up the
+bars.  @xref{Line Styles}.
+
+ at item edgecolor
+ at itemx facecolor
+The line and fill color of the patch objects making up the bars.  @xref{Colors}.
+
+ at item xdata
+The nominal x positions of the bars.  Changes in this property and
+propagated to the other members of the bar series. 
+
+ at item ydata
+The y value of the bars in the @code{hggroup}.
+
+ at item xdatasource
+ at itemx ydatasource
+Data source variables.
+ at end table
+
+ at node Contour groups
+ at subsubsection Contour groups
+ at cindex series objects
+ at cindex contour series
+
+Contour group objects are created by the @code{contour}, @code{contourf}
+and @code{contour3} functions.  The are equally one of the handles returned
+by the @code{surfc} and @code{meshc} functions.  The properties of the contour
+group are
+
+ at table @code
+ at item contourmatrix
+A read only property that contains the data return by @code{contourc} used to
+create the contours of the plot.
+
+ at item fill
+A radio property that can have the values "on" or "off" that flags whether the
+contours to plot are to be filled.
+
+ at item zlevelmode
+ at itemx zlevel
+The radio property @code{zlevelmode} can have the values "none", "auto" or 
+"manual".  When its value is "none" there is no z component to the plotted
+contours.  When its value is "auto" the z value of the plotted contours is 
+at the same value as the contour itself.  If the value is "manual", then the
+z value at which to plot the contour is determined by the @code{zlevel}
+property.
+
+ at item levellistmode
+ at itemx levellist
+ at itemx levelstepmode
+ at itemx levelstep
+If @code{levellistmode} is "manual", then the levels at which to plot the 
+contours is determined by @code{levellist}.  If @code{levellistmode} is
+set to "auto", then the distance between contours is determined by 
+ at code{levelstep}.  If both @code{levellistmode} and @code{levelstepmode}
+are set to "auto", then there are assumed to be 10 equal spaced contours.
+
+ at item textlistmode
+ at itemx textlist
+ at itemx textstepmode
+ at itemx textstep
+If @code{textlistmode} is "manual", then the labelled contours 
+is determined by @code{textlist}.  If @code{textlistmode} is set to 
+"auto", then the distance between labelled contours is determined by 
+ at code{textstep}.  If both @code{textlistmode} and @code{textstepmode}
+are set to "auto", then there are assumed to be 10 equal spaced 
+labelled contours.
+
+ at item showtext
+Flag whether the contour labels are shown or not.
+
+ at item labelspacing
+The distance between labels on a single contour in points.
+
+ at item linewidth
+ at item linestyle
+ at item linecolor
+The properties of the contour lines.  The properties @code{linewidth} and
+ at code{linestyle} are similar to the corresponding properties for lines.  The
+property @code{linecolor} is a color property (@pxref{Colors}), that can also
+have the values of "none" or "auto".  If @code{linecolor} is "none", then no
+contour line is drawn.  If @code{linecolor} is "auto" then the line color is
+determined by the colormap.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y, and z data of the contour lines.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+Data source variables.
+ at end table
+
+ at node Error bar series
+ at subsubsection Error bar series
+ at cindex series objects
+ at cindex error bar series
+
+Error bar series are created by the @code{errorbar} function.  Each 
+ at code{hggroup} element contains two line objects representing the data and
+the errorbars separately.  The properties of the error bar series are
+
+ at table @code
+ at item color
+The RGB color or color name of the line objects of the error bars.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the error bars.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the error bars.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx ldata
+ at itemx udata
+ at itemx xldata
+ at itemx xudata
+The original x, y, l, u, xl, xu data of the error bars.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx ldatasource
+ at itemx udatasource
+ at itemx xldatasource
+ at itemx xudatasource
+Data source variables.
+ at end table
+
+ at node Line series
+ at subsubsection Line series
+ at cindex series objects
+ at cindex line series
+
+Line series objects are created by the @code{plot}  and @code{plot3}
+functions and are of the type @code{line}.  The properties of the
+line series with the ability to add data sources.
+
+ at table @code
+ at item color
+The RGB color or color name of the line objects.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y and z data.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+Data source variables.
+ at end table
+
+ at node Quiver group
+ at subsubsection Quiver group
+ at cindex group objects
+ at cindex quiver group
+
+Quiver series objects are created by the @code{quiver} or @code{quiver3}
+functions.  Each @code{hggroup} element of the series contains three line
+objects as children representing the body and head of the arrow,
+together with a marker as the point of original of the arrows.  The 
+properties of the quiver series are
+
+ at table @code
+ at item autoscale
+ at itemx autoscalefactor
+Flag whether the length of the arrows is scaled or defined directly from
+the @var{u}, @var{v} and @var{w} data.  If the arrow length is flagged
+as being scaled by the @code{autoscale} property, then the length of the
+autoscaled arrow is controlled by the @code{autoscalefactor}. 
+
+ at item maxheadsize
+This property controls the size of the head of the arrows in the quiver
+series.  The default value is 0.2.
+
+ at item showarrowhead
+Flag whether the arrow heads are displayed in the quiver plot.
+
+ at item color
+The RGB color or color name of the line objects of the quiver.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the quiver.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the marker objects at the original of the
+arrows.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The origins of the values of the vector field.
+
+ at item udata
+ at itemx vdata
+ at itemx wdata
+The values of the vector field to plot.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+ at itemx udatasource
+ at itemx vdatasource
+ at itemx wdatasource
+Data source variables.
+ at end table
+
+ at node Scatter group
+ at subsubsection Scatter group
+ at cindex group objects
+ at cindex scatter group
+
+Scatter series objects are created by the @code{scatter} or @code{scatter3}
+functions.  A single hggroup element contains as many children as there are
+points in the scatter plot, with each child representing one of the points.
+The properties of the stem series are
+
+ at table @code
+ at item linewidth
+The line width of the line objects of the points.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+The line and fill color of the markers of the points.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y and z data of the stems.
+
+ at item cdata
+The color data for the points of the plot.  Each point can have a separate
+color, or a unique color can be specified.
+
+ at item sizedata
+The size data for the points of the plot.  Each point can its own size or a 
+unique size can be specified.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+ at itemx cdatasource
+ at itemx sizedatasource
+Data source variables.
+ at end table
+
+ at node Stair group
+ at subsubsection Stair group
+ at cindex group objects
+ at cindex stair group
+
+Stair series objects are created by the @code{stair} function.  Each
+ at code{hggroup} element of the series contains a single line object as a
+child representing the stair.  The properties of the stair series are
+
+ at table @code
+ at item color
+The RGB color or color name of the line objects of the stairs.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the stairs.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the stairs.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+The original x and y data of the stairs.
+
+ at item xdatasource
+ at itemx ydatasource
+Data source variables.
+ at end table
+
+ at node Stem Series
+ at subsubsection Stem Series
+ at cindex series objects
+ at cindex stem series
+
+Stem series objects are created by the @code{stem} or @code{stem3}
+functions.  Each @code{hggroup} element contains a single line object
+as a child representing the stems.  The properties of the stem series
+are
+
+ at table @code
+ at item showbaseline
+ at itemx baseline
+ at itemx basevalue
+The property @code{showbaseline} flags whether the baseline of the
+stem series is displayed (default is "on").  The handle of the graphics
+object representing the baseline is given by the @code{baseline}
+property and the y-value (or z-value for @code{stem3}) of the baseline
+by the @code{basevalue} property.
+
+Changes to any of these property are propagated to the other members of
+the stem series and to the baseline itself.  Equally changes in the
+properties of the base line itself are propagated to the members of the
+corresponding stem series.
+
+ at item color
+The RGB color or color name of the line objects of the stems.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the line objects of the stems.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the stems.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+The original x, y and z data of the stems.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+Data source variables.
+ at end table
+
+ at node Surface group
+ at subsubsection Surface group
+ at cindex group objects
+ at cindex surface group
+
+Surface group objects are created by the @code{surf} or @code{mesh}
+functions, but are equally one of the handles returned by the @code{surfc}
+or @code{meshc} functions.  The surface group is of the type @code{surface}.
+
+The properties of the surface group are
+
+ at table @code
+ at item edgecolor
+ at item facecolor
+The RGB color or color name of the edges or faces of the surface.  @xref{Colors}.
+
+ at item linewidth
+ at itemx linestyle
+The line width and style of the lines on the surface.  @xref{Line Styles}.
+
+ at item marker
+ at itemx markeredgecolor
+ at itemx markerfacecolor
+ at itemx markersize
+The line and fill color of the markers on the surface.  @xref{Colors}.
+
+ at item xdata
+ at itemx ydata
+ at itemx zdata
+ at item cdata
+The original x, y, z and c data.
+
+ at item xdatasource
+ at itemx ydatasource
+ at itemx zdatasource
+ at itemx cdatasource
+Data source variables.
+ at end table
+
+ at node Graphics backends
+ at subsection Graphics backends
+ at cindex graphics backends
+ at cindex backends, graphics
+
+ at DOCSTRING(backend)
+
+ at DOCSTRING(available_backends)
+
+ at menu
+* Interaction with gnuplot::
+ at end menu
+
+ at node Interaction with gnuplot
+ at subsubsection Interaction with @code{gnuplot}
+ at cindex gnuplot interaction
+
+ at DOCSTRING(gnuplot_binary)
diff --git a/doc/interpreter/plot.txt b/doc/interpreter/plot.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/plot.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/plot3.eps b/doc/interpreter/plot3.eps
new file mode 100644
index 0000000..ad8bc82
--- /dev/null
+++ b/doc/interpreter/plot3.eps
@@ -0,0 +1,1957 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: plot3.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:56 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (plot3.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:56 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+0.500 UL
+LTb
+1.000 UP
+0.500 UL
+LT0
+0.00 0.00 1.00 C 3698 1469 M
+3 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3696 1478 M
+2 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3695 1488 M
+1 -10 V
+stroke
+LT0
+0.00 0.00 1.00 C 3695 1497 M
+0 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3697 1506 M
+-2 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3699 1516 M
+-2 -10 V
+stroke
+LT0
+0.00 0.00 1.00 C 3702 1525 M
+-3 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3708 1534 M
+-6 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3714 1543 M
+-6 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3722 1551 M
+-8 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3730 1559 M
+-8 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3740 1567 M
+-10 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3750 1575 M
+-10 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3760 1582 M
+-10 -7 V
+stroke
+LT0
+0.00 0.00 1.00 C 3771 1588 M
+-11 -6 V
+stroke
+LT0
+0.00 0.00 1.00 C 3782 1594 M
+-11 -6 V
+stroke
+LT0
+0.00 0.00 1.00 C 3793 1599 M
+-11 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3643 2086 M
+42 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 3728 2105 M
+-43 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3773 2113 M
+-45 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3803 1604 M
+-10 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3602 2074 M
+41 12 V
+stroke
+LT0
+0.00 0.00 1.00 C 3818 2119 M
+-45 -6 V
+stroke
+LT0
+0.00 0.00 1.00 C 3564 2061 M
+38 13 V
+stroke
+LT0
+0.00 0.00 1.00 C 3814 1609 M
+-11 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3863 2124 M
+-45 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3529 2047 M
+35 14 V
+stroke
+LT0
+0.00 0.00 1.00 C 3823 1613 M
+-9 -4 V
+stroke
+LT0
+0.00 0.00 1.00 C 3908 2126 M
+-45 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3496 2032 M
+33 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 3831 1616 M
+-8 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3466 2016 M
+30 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 3951 2128 M
+-43 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3602 2665 M
+82 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 3766 2685 M
+-82 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3850 2690 M
+-84 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3523 2651 M
+79 14 V
+stroke
+LT0
+0.00 0.00 1.00 C 3839 1619 M
+-8 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3440 1999 M
+26 17 V
+stroke
+LT0
+0.00 0.00 1.00 C 3934 2693 M
+-84 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3994 2128 M
+-43 0 V
+stroke
+LT0
+0.00 0.00 1.00 C 3446 2635 M
+77 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 3844 1621 M
+-5 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3417 1981 M
+23 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 4016 2693 M
+-82 0 V
+stroke
+LT0
+0.00 0.00 1.00 C 3373 2616 M
+73 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 4034 2126 M
+-40 2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3849 1623 M
+-5 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3398 1963 M
+19 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 3575 3246 M
+122 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 3818 3264 M
+-121 -7 V
+stroke
+LT0
+0.00 0.00 1.00 C 4097 2690 M
+-81 3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3305 2595 M
+68 21 V
+stroke
+LT0
+0.00 0.00 1.00 C 3456 3230 M
+119 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 3941 3268 M
+-123 -4 V
+stroke
+LT0
+0.00 0.00 1.00 C 3852 1625 M
+-3 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 4072 2123 M
+-38 3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3383 1944 M
+15 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 3341 3211 M
+115 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 4063 3267 M
+-122 1 V
+stroke
+LT0
+0.00 0.00 1.00 C 3852 1627 M
+0 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3241 2573 M
+64 22 V
+stroke
+LT0
+0.00 0.00 1.00 C 4175 2685 M
+-78 5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3371 1925 M
+12 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 3230 3188 M
+111 23 V
+stroke
+LT0
+0.00 0.00 1.00 C 4182 3262 M
+-119 5 V
+stroke
+LT0
+0.00 0.00 1.00 C 4107 2119 M
+-35 4 V
+stroke
+LT0
+0.00 0.00 1.00 C 3851 1628 M
+1 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 3561 3827 M
+160 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 3883 3844 M
+-162 -6 V
+stroke
+LT0
+0.00 0.00 1.00 C 3402 3810 M
+159 17 V
+stroke
+LT0
+0.00 0.00 1.00 C 4045 3844 M
+-162 0 V
+stroke
+LT0
+0.00 0.00 1.00 C 3363 1907 M
+8 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 3184 2548 M
+57 25 V
+stroke
+LT0
+0.00 0.00 1.00 C 3848 1629 M
+3 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 4249 2677 M
+-74 8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3248 3789 M
+154 21 V
+stroke
+LT0
+0.00 0.00 1.00 C 3125 3162 M
+105 26 V
+stroke
+LT0
+0.00 0.00 1.00 C 4139 2113 M
+-32 6 V
+stroke
+LT0
+0.00 0.00 1.00 C 4205 3839 M
+-160 5 V
+stroke
+LT0
+0.00 0.00 1.00 C 4298 3253 M
+-116 9 V
+stroke
+LT0
+0.00 0.00 1.00 C 3359 1888 M
+4 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 3843 1630 M
+5 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 3099 3762 M
+149 27 V
+stroke
+LT0
+0.00 0.00 1.00 C 3132 2522 M
+52 26 V
+stroke
+LT0
+0.00 0.00 1.00 C 3835 1632 M
+8 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3359 1869 M
+0 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 4318 2667 M
+-69 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 3028 3133 M
+97 29 V
+stroke
+LT0
+0.00 0.00 1.00 C 4360 3829 M
+-155 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 4167 2106 M
+-28 7 V
+stroke
+LT0
+0.00 0.00 1.00 C 4409 3241 M
+-111 12 V
+stroke
+LT0
+0.00 0.00 1.00 C 3825 1633 M
+10 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 3363 1850 M
+-4 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 2958 3731 M
+141 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 3087 2494 M
+45 28 V
+stroke
+LT0
+0.00 0.00 1.00 C 3813 1635 M
+12 -2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3370 1832 M
+-7 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 4191 2098 M
+-24 8 V
+stroke
+LT0
+0.00 0.00 1.00 C 4382 2654 M
+-64 13 V
+stroke
+LT0
+0.00 0.00 1.00 C 4510 3814 M
+-150 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 2938 3100 M
+90 33 V
+stroke
+LT0
+0.00 0.00 1.00 C 3799 1636 M
+14 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 3380 1814 M
+-10 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 4513 3225 M
+-104 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 3783 1639 M
+16 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3049 2465 M
+38 29 V
+stroke
+LT0
+0.00 0.00 1.00 C 2825 3695 M
+133 36 V
+stroke
+LT0
+0.00 0.00 1.00 C 3393 1797 M
+-13 17 V
+stroke
+LT0
+0.00 0.00 1.00 C 4210 2090 M
+-19 8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3765 1642 M
+18 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3409 1781 M
+-16 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 4440 2639 M
+-58 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 2856 3065 M
+82 35 V
+stroke
+LT0
+0.00 0.00 1.00 C 3745 1645 M
+20 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 4654 3794 M
+-144 20 V
+stroke
+LT0
+0.00 0.00 1.00 C 3427 1765 M
+-18 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 3723 1649 M
+22 -4 V
+stroke
+LT0
+0.00 0.00 1.00 C 3018 2435 M
+31 30 V
+stroke
+LT0
+0.00 0.00 1.00 C 4611 3205 M
+-98 20 V
+stroke
+LT0
+0.00 0.00 1.00 C 3447 1750 M
+-20 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 4225 2080 M
+-15 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 3701 1654 M
+22 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3470 1736 M
+-23 14 V
+stroke
+LT0
+0.00 0.00 1.00 C 2702 3656 M
+123 39 V
+stroke
+LT0
+0.00 0.00 1.00 C 3676 1659 M
+25 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3494 1723 M
+-24 13 V
+stroke
+LT0
+0.00 0.00 1.00 C 3651 1666 M
+25 -7 V
+stroke
+LT0
+0.00 0.00 1.00 C 4492 2622 M
+-52 17 V
+stroke
+LT0
+0.00 0.00 1.00 C 3519 1711 M
+-25 12 V
+stroke
+LT0
+0.00 0.00 1.00 C 3624 1673 M
+27 -7 V
+stroke
+LT0
+0.00 0.00 1.00 C 2784 3028 M
+72 37 V
+stroke
+LT0
+0.00 0.00 1.00 C 3545 1700 M
+-26 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 3598 1681 M
+26 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3571 1690 M
+-26 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 2994 2404 M
+24 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 3571 1690 M
+27 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 4234 2070 M
+-9 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 4788 3769 M
+-134 25 V
+stroke
+LT0
+0.00 0.00 1.00 C 4700 3182 M
+-89 23 V
+stroke
+LT0
+0.00 0.00 1.00 C 2590 3612 M
+112 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 4238 2059 M
+-4 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 2978 2372 M
+16 32 V
+stroke
+LT0
+0.00 0.00 1.00 C 4536 2603 M
+-44 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 2722 2988 M
+62 40 V
+stroke
+LT0
+0.00 0.00 1.00 C 4913 3740 M
+-125 29 V
+stroke
+LT0
+0.00 0.00 1.00 C 4237 2048 M
+1 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 2969 2341 M
+9 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 4780 3156 M
+-80 26 V
+stroke
+LT0
+0.00 0.00 1.00 C 4572 2583 M
+-36 20 V
+stroke
+LT0
+0.00 0.00 1.00 C 2490 3565 M
+100 47 V
+stroke
+LT0
+0.00 0.00 1.00 C 2670 2947 M
+52 41 V
+stroke
+LT0
+0.00 0.00 1.00 C 2333 4162 M
+144 52 V
+stroke
+LT0
+0.00 0.00 1.00 C 4230 2038 M
+7 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 2968 2309 M
+1 32 V
+stroke
+LT0
+0.00 0.00 1.00 C 5027 3707 M
+-114 33 V
+stroke
+LT0
+0.00 0.00 1.00 C 4851 3128 M
+-71 28 V
+stroke
+LT0
+0.00 0.00 1.00 C 4600 2562 M
+-28 21 V
+stroke
+LT0
+0.00 0.00 1.00 C 4217 2027 M
+13 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 2974 2278 M
+-6 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 2629 2904 M
+41 43 V
+stroke
+LT0
+0.00 0.00 1.00 C 2402 3516 M
+88 49 V
+stroke
+LT0
+0.00 0.00 1.00 C 4199 2016 M
+18 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 2204 4107 M
+129 55 V
+stroke
+LT0
+0.00 0.00 1.00 C 2988 2248 M
+-14 30 V
+stroke
+LT0
+0.00 0.00 1.00 C 4619 2540 M
+-19 22 V
+stroke
+LT0
+0.00 0.00 1.00 C 4910 3097 M
+-59 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 5128 3670 M
+-101 37 V
+stroke
+LT0
+0.00 0.00 1.00 C 2599 2860 M
+30 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 4175 2007 M
+24 9 V
+stroke
+LT0
+0.00 0.00 1.00 C 2329 3464 M
+73 52 V
+stroke
+LT0
+0.00 0.00 1.00 C 3008 2218 M
+-20 30 V
+stroke
+LT0
+0.00 0.00 1.00 C 4145 1997 M
+30 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 4629 2517 M
+-10 23 V
+stroke
+LT0
+0.00 0.00 1.00 C 2091 4047 M
+113 60 V
+stroke
+LT0
+0.00 0.00 1.00 C 3035 2189 M
+-27 29 V
+stroke
+LT0
+0.00 0.00 1.00 C 2581 2816 M
+18 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 4957 3064 M
+-47 33 V
+stroke
+LT0
+0.00 0.00 1.00 C 4111 1989 M
+34 8 V
+stroke
+LT0
+0.00 0.00 1.00 C 5215 3629 M
+-87 41 V
+stroke
+LT0
+0.00 0.00 1.00 C 3068 2161 M
+-33 28 V
+stroke
+LT0
+0.00 0.00 1.00 C 2270 3409 M
+59 55 V
+stroke
+LT0
+0.00 0.00 1.00 C 4630 2493 M
+-1 24 V
+stroke
+LT0
+0.00 0.00 1.00 C 4071 1982 M
+40 7 V
+stroke
+LT0
+0.00 0.00 1.00 C 3108 2135 M
+-40 26 V
+stroke
+LT0
+0.00 0.00 1.00 C 2574 2772 M
+7 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 4027 1976 M
+44 6 V
+stroke
+LT0
+0.00 0.00 1.00 C 1994 3984 M
+97 63 V
+stroke
+LT0
+0.00 0.00 1.00 C 4992 3030 M
+-35 34 V
+stroke
+LT0
+0.00 0.00 1.00 C 3152 2110 M
+-44 25 V
+stroke
+LT0
+0.00 0.00 1.00 C 4622 2469 M
+8 24 V
+stroke
+LT0
+0.00 0.00 1.00 C 3978 1971 M
+49 5 V
+stroke
+LT0
+0.00 0.00 1.00 C 5288 3586 M
+-73 43 V
+stroke
+LT0
+0.00 0.00 1.00 C 2225 3354 M
+45 55 V
+stroke
+LT0
+0.00 0.00 1.00 C 3201 2087 M
+-49 23 V
+stroke
+LT0
+0.00 0.00 1.00 C 2579 2728 M
+-5 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 3926 1968 M
+52 3 V
+stroke
+LT0
+0.00 0.00 1.00 C 3254 2065 M
+-53 22 V
+stroke
+LT0
+0.00 0.00 1.00 C 3870 1967 M
+56 1 V
+stroke
+LT0
+0.00 0.00 1.00 C 4604 2446 M
+18 23 V
+stroke
+LT0
+0.00 0.00 1.00 C 5015 2994 M
+-23 36 V
+stroke
+LT0
+0.00 0.00 1.00 C 3311 2046 M
+-57 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 3811 1967 M
+59 0 V
+stroke
+LT0
+0.00 0.00 1.00 C 1915 3919 M
+79 65 V
+stroke
+LT0
+0.00 0.00 1.00 C 3370 2029 M
+-59 17 V
+stroke
+LT0
+0.00 0.00 1.00 C 3750 1970 M
+61 -3 V
+stroke
+LT0
+0.00 0.00 1.00 C 2594 2684 M
+-15 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 3432 2014 M
+-62 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 2196 3297 M
+29 57 V
+stroke
+LT0
+0.00 0.00 1.00 C 3688 1974 M
+62 -4 V
+stroke
+LT0
+0.00 0.00 1.00 C 3496 2000 M
+-64 14 V
+stroke
+LT0
+0.00 0.00 1.00 C 5345 3541 M
+-57 45 V
+stroke
+LT0
+0.00 0.00 1.00 C 3624 1981 M
+64 -7 V
+stroke
+LT0
+0.00 0.00 1.00 C 3560 1990 M
+-64 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 3560 1990 M
+64 -9 V
+stroke
+LT0
+0.00 0.00 1.00 C 4576 2423 M
+28 23 V
+stroke
+LT0
+0.00 0.00 1.00 C 5025 2958 M
+-10 36 V
+stroke
+LT0
+0.00 0.00 1.00 C 2621 2641 M
+-27 43 V
+stroke
+LT0
+0.00 0.00 1.00 C 4539 2401 M
+37 22 V
+stroke
+LT0
+0.00 0.00 1.00 C 1855 3851 M
+60 68 V
+stroke
+LT0
+0.00 0.00 1.00 C 2181 3240 M
+15 57 V
+stroke
+LT0
+0.00 0.00 1.00 C 5387 3494 M
+-42 47 V
+stroke
+LT0
+0.00 0.00 1.00 C 2658 2600 M
+-37 41 V
+stroke
+LT0
+0.00 0.00 1.00 C 5021 2921 M
+4 37 V
+stroke
+LT0
+0.00 0.00 1.00 C 4494 2380 M
+45 21 V
+stroke
+LT0
+0.00 0.00 1.00 C 2183 3182 M
+-2 58 V
+stroke
+LT0
+0.00 0.00 1.00 C 2705 2561 M
+-47 39 V
+stroke
+LT0
+0.00 0.00 1.00 C 1813 3782 M
+42 69 V
+stroke
+LT0
+0.00 0.00 1.00 C 4439 2361 M
+55 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 5004 2885 M
+17 36 V
+stroke
+LT0
+0.00 0.00 1.00 C 5411 3445 M
+-24 49 V
+stroke
+LT0
+0.00 0.00 1.00 C 2761 2522 M
+-56 39 V
+stroke
+LT0
+0.00 0.00 1.00 C 4377 2343 M
+62 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 2199 3126 M
+-16 56 V
+stroke
+LT0
+0.00 0.00 1.00 C 2826 2487 M
+-65 35 V
+stroke
+LT0
+0.00 0.00 1.00 C 4307 2328 M
+70 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 1790 3712 M
+23 70 V
+stroke
+LT0
+0.00 0.00 1.00 C 4973 2849 M
+31 36 V
+stroke
+LT0
+0.00 0.00 1.00 C 5419 3396 M
+-8 49 V
+stroke
+LT0
+0.00 0.00 1.00 C 2899 2453 M
+-73 34 V
+stroke
+LT0
+0.00 0.00 1.00 C 4229 2315 M
+78 13 V
+stroke
+LT0
+0.00 0.00 1.00 C 2230 3070 M
+-31 56 V
+stroke
+LT0
+0.00 0.00 1.00 C 2980 2422 M
+-81 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 4930 2814 M
+43 35 V
+stroke
+LT0
+0.00 0.00 1.00 C 4146 2304 M
+83 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 1787 3642 M
+3 70 V
+stroke
+LT0
+0.00 0.00 1.00 C 3066 2394 M
+-86 28 V
+stroke
+LT0
+0.00 0.00 1.00 C 4057 2296 M
+89 8 V
+stroke
+LT0
+0.00 0.00 1.00 C 5409 3346 M
+10 50 V
+stroke
+LT0
+0.00 0.00 1.00 C 2276 3016 M
+-46 54 V
+stroke
+LT0
+0.00 0.00 1.00 C 3158 2370 M
+-92 24 V
+stroke
+LT0
+0.00 0.00 1.00 C 3963 2291 M
+94 5 V
+stroke
+LT0
+0.00 0.00 1.00 C 4874 2781 M
+56 33 V
+stroke
+LT0
+0.00 0.00 1.00 C 3255 2348 M
+-97 22 V
+stroke
+LT0
+0.00 0.00 1.00 C 3865 2289 M
+98 2 V
+stroke
+LT0
+0.00 0.00 1.00 C 3354 2330 M
+-99 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 3764 2290 M
+101 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 2335 2963 M
+-59 53 V
+stroke
+LT0
+0.00 0.00 1.00 C 3456 2315 M
+-102 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 3663 2295 M
+101 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 1803 3572 M
+-16 70 V
+stroke
+LT0
+0.00 0.00 1.00 C 3559 2303 M
+-103 12 V
+stroke
+LT0
+0.00 0.00 1.00 C 3559 2303 M
+104 -8 V
+stroke
+LT0
+0.00 0.00 1.00 C 5383 3297 M
+26 49 V
+stroke
+LT0
+0.00 0.00 1.00 C 4805 2749 M
+69 32 V
+stroke
+LT0
+0.00 0.00 1.00 C 2408 2913 M
+-73 50 V
+stroke
+LT0
+0.00 0.00 1.00 C 4725 2720 M
+80 29 V
+stroke
+LT0
+0.00 0.00 1.00 C 1837 3503 M
+-34 69 V
+stroke
+LT0
+0.00 0.00 1.00 C 5339 3249 M
+44 48 V
+stroke
+LT0
+0.00 0.00 1.00 C 2493 2866 M
+-85 47 V
+stroke
+LT0
+0.00 0.00 1.00 C 4633 2694 M
+92 26 V
+stroke
+LT0
+0.00 0.00 1.00 C 2589 2822 M
+-96 44 V
+stroke
+LT0
+0.00 0.00 1.00 C 1890 3436 M
+-53 67 V
+stroke
+LT0
+0.00 0.00 1.00 C 5278 3203 M
+61 46 V
+stroke
+LT0
+0.00 0.00 1.00 C 4531 2670 M
+102 24 V
+stroke
+LT0
+0.00 0.00 1.00 C 2696 2781 M
+-107 41 V
+stroke
+LT0
+0.00 0.00 1.00 C 4420 2650 M
+111 20 V
+stroke
+LT0
+0.00 0.00 1.00 C 1961 3371 M
+-71 65 V
+stroke
+LT0
+0.00 0.00 1.00 C 5201 3158 M
+77 45 V
+stroke
+LT0
+0.00 0.00 1.00 C 2811 2744 M
+-115 37 V
+stroke
+LT0
+0.00 0.00 1.00 C 4301 2634 M
+119 16 V
+stroke
+LT0
+0.00 0.00 1.00 C 2935 2712 M
+-124 32 V
+stroke
+LT0
+0.00 0.00 1.00 C 4175 2621 M
+126 13 V
+stroke
+LT0
+0.00 0.00 1.00 C 2049 3309 M
+-88 62 V
+stroke
+LT0
+0.00 0.00 1.00 C 3065 2683 M
+-130 29 V
+stroke
+LT0
+0.00 0.00 1.00 C 5108 3116 M
+93 42 V
+stroke
+LT0
+0.00 0.00 1.00 C 4042 2613 M
+133 8 V
+stroke
+LT0
+0.00 0.00 1.00 C 3201 2659 M
+-136 24 V
+stroke
+LT0
+0.00 0.00 1.00 C 3905 2609 M
+137 4 V
+stroke
+LT0
+0.00 0.00 1.00 C 3340 2640 M
+-139 19 V
+stroke
+LT0
+0.00 0.00 1.00 C 3765 2610 M
+140 -1 V
+stroke
+LT0
+0.00 0.00 1.00 C 3481 2625 M
+-141 15 V
+stroke
+LT0
+0.00 0.00 1.00 C 3624 2615 M
+141 -5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3624 2615 M
+-143 10 V
+stroke
+LT0
+0.00 0.00 1.00 C 2152 3250 M
+-103 59 V
+stroke
+LT0
+0.00 0.00 1.00 C 5001 3077 M
+107 39 V
+stroke
+LT0
+0.00 0.00 1.00 C 2270 3195 M
+-118 55 V
+stroke
+LT0
+0.00 0.00 1.00 C 4879 3042 M
+122 35 V
+stroke
+LT0
+0.00 0.00 1.00 C 4745 3011 M
+134 31 V
+stroke
+LT0
+0.00 0.00 1.00 C 2402 3144 M
+-132 51 V
+stroke
+LT0
+0.00 0.00 1.00 C 4600 2985 M
+145 26 V
+stroke
+LT0
+0.00 0.00 1.00 C 2546 3098 M
+-144 46 V
+stroke
+LT0
+0.00 0.00 1.00 C 4444 2963 M
+156 22 V
+stroke
+LT0
+0.00 0.00 1.00 C 2700 3057 M
+-154 41 V
+stroke
+LT0
+0.00 0.00 1.00 C 4280 2946 M
+164 17 V
+stroke
+LT0
+0.00 0.00 1.00 C 2864 3022 M
+-164 35 V
+stroke
+LT0
+0.00 0.00 1.00 C 4109 2935 M
+171 11 V
+stroke
+LT0
+0.00 0.00 1.00 C 3034 2992 M
+-170 30 V
+stroke
+LT0
+0.00 0.00 1.00 C 3933 2930 M
+176 5 V
+stroke
+LT0
+0.00 0.00 1.00 C 3211 2967 M
+-177 25 V
+stroke
+LT0
+0.00 0.00 1.00 C 3753 2930 M
+180 0 V
+stroke
+LT0
+0.00 0.00 1.00 C 3390 2949 M
+-179 18 V
+stroke
+LT0
+0.00 0.00 1.00 C 3572 2937 M
+181 -7 V
+stroke
+LT0
+0.00 0.00 1.00 C 3572 2937 M
+-182 12 V
+% Begin plot #1
+stroke
+LT0
+0.00 0.00 1.00 C % End plot #1
+0.500 UL
+LTb
+6464 1341 M
+3338 551 L
+938 1580 M
+3338 551 L
+938 1580 M
+3126 790 V
+6464 1341 M
+4064 2370 L
+938 1580 M
+0 2245 V
+4064 2370 M
+0 2245 V
+6464 1341 M
+0 2245 V
+3338 551 M
+0 2245 V
+938 3825 M
+3126 790 V
+6464 3586 M
+4064 4615 L
+938 3825 M
+3338 2796 L
+3126 790 R
+3338 2796 L
+0 -2245 R
+-82 35 V
+stroke
+0.00 0.00 0.00 C 3415 495 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+938 1580 M
+82 -35 V
+4119 748 M
+-82 35 V
+stroke
+0.00 0.00 0.00 C 4196 693 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1720 1777 M
+81 -35 V
+4900 946 M
+-81 35 V
+stroke
+0.00 0.00 0.00 C 4978 890 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+2502 1975 M
+81 -35 V
+5682 1143 M
+-81 35 V
+stroke
+0.00 0.00 0.00 C 5760 1088 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+3283 2172 M
+82 -35 V
+6464 1341 M
+-82 35 V
+stroke
+0.00 0.00 0.00 C 6542 1285 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MLshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+4064 2370 M
+82 -35 V
+3338 551 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 3271 523 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 1341 M
+-70 -18 V
+2738 808 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 2671 780 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5864 1598 M
+-70 -18 V
+2138 1065 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 2071 1037 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+5264 1855 M
+-70 -18 V
+1538 1323 M
+70 17 V
+stroke
+0.00 0.00 0.00 C 1471 1295 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.5)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+4664 2112 M
+-70 -17 V
+938 1580 M
+70 18 V
+stroke
+0.00 0.00 0.00 C 871 1552 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+4064 2370 M
+-70 -18 V
+938 1580 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 812 1580 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 1341 M
+-88 0 V
+938 2029 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 812 2029 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 1790 M
+-88 0 V
+938 2479 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 812 2479 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 2239 M
+-88 0 V
+938 2927 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 812 2927 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 2687 M
+-88 0 V
+938 3376 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 812 3376 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 3137 M
+-88 0 V
+938 3825 M
+88 0 V
+stroke
+0.00 0.00 0.00 C 812 3825 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+6464 3586 M
+-88 0 V
+1.000 UP
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/plot3.pdf b/doc/interpreter/plot3.pdf
new file mode 100644
index 0000000..3fe97ab
Binary files /dev/null and b/doc/interpreter/plot3.pdf differ
diff --git a/doc/interpreter/plot3.png b/doc/interpreter/plot3.png
new file mode 100644
index 0000000..cf09c14
Binary files /dev/null and b/doc/interpreter/plot3.png differ
diff --git a/doc/interpreter/plot3.txt b/doc/interpreter/plot3.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/plot3.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/plotimages.m b/doc/interpreter/plotimages.m
new file mode 100644
index 0000000..e445100
--- /dev/null
+++ b/doc/interpreter/plotimages.m
@@ -0,0 +1,97 @@
+## Copyright (C) 2007, 2008, 2009 John W. Eaton and David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+function plotimages (nm, typ)
+  set_print_size ();
+  hide_output ();
+
+  if (strcmp (typ, "png"))
+    set (0, "defaulttextfontname", "*");
+  endif
+  if (strcmp(typ , "txt"))
+    image_as_txt(nm);
+  elseif (strcmp (nm, "plot"))
+    x = -10:0.1:10;
+    plot (x, sin (x));
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "hist"))
+	 rand ("state", 2);
+    hist (randn (10000, 1), 30);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "errorbar"))
+	 rand ("state", 2);
+    x = 0:0.1:10;
+    y = sin (x);
+    yl = 0.1 .* rand (size (x));
+    yu = 0.1 .* rand (size (x));
+    errorbar (x, sin (x), yl, yu);
+	 axis ([0, 10, -1.1, 1.1]);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "polar"))
+    polar (0:0.1:10*pi, 0:0.1:10*pi);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "mesh"))
+    tx = ty = linspace (-8, 8, 41)';
+    [xx, yy] = meshgrid (tx, ty);
+    r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+    tz = sin (r) ./ r;
+    mesh (tx, ty, tz);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "plot3"))
+    t = 0:0.1:10*pi;
+    r = linspace (0, 1, numel (t));
+    z = linspace (0, 1, numel (t));
+    plot3 (r.*sin(t), r.*cos(t), z);
+    print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))    
+  elseif (strcmp (nm, "extended"))
+    x = 0:0.01:3;
+    plot(x,erf(x));
+    hold on;
+    plot(x,x,"r");
+    axis([0, 3, 0, 1]);
+    text(0.65, 0.6175, cstrcat('\leftarrow x = {2/\surd\pi {\fontsize{16}',
+      '\int_{\fontsize{8}0}^{\fontsize{8}x}} e^{-t^2} dt} = 0.6175'))
+    print (cstrcat (nm, ".", typ), cstrcat ("-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", "<custom>");
+  set (0, "defaultfigurepapersize", image_size + 2*border);
+  set (0, "defaultfigurepaperposition", [border, border, image_size]);
+endfunction
+
+function hide_output ()
+  f = figure (1);
+  set (f, "visible", "off");
+endfunction
+
+## generate something for the texinfo @image command to process
+function image_as_txt(nm)
+  fid = fopen (sprintf ("%s.txt", nm), "wt");
+  fputs (fid, "\n");
+  fputs (fid, "+---------------------------------+\n");
+  fputs (fid, "| Image unavailable in text mode. |\n");
+  fputs (fid, "+---------------------------------+\n");
+  fclose (fid);
+endfunction
diff --git a/doc/interpreter/polar.eps b/doc/interpreter/polar.eps
new file mode 100644
index 0000000..9d9448e
--- /dev/null
+++ b/doc/interpreter/polar.eps
@@ -0,0 +1,1042 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: polar.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon Jun  8 07:38:55 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 409 301
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (polar.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon Jun  8 07:38:55 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 409 50 lineto 409 301 lineto 50 301 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+3715 643 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 643 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-30)]
+] -40.0 MRshow
+0.500 UL
+LTb
+3715 1294 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 1294 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-20)]
+] -40.0 MRshow
+0.500 UL
+LTb
+3715 1946 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 1946 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-10)]
+] -40.0 MRshow
+0.500 UL
+LTb
+3715 2597 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 2597 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+3715 3248 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 3248 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MRshow
+0.500 UL
+LTb
+3715 3900 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 3900 M
+[ [(Helvetica) 120.0 0.0 true true 0 (20)]
+] -40.0 MRshow
+0.500 UL
+LTb
+3715 4551 M
+-88 0 V
+88 0 R
+88 0 V
+stroke
+0.00 0.00 0.00 C 3631 4551 M
+[ [(Helvetica) 120.0 0.0 true true 0 (30)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1619 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 1619 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-30)]
+] -40.0 MCshow
+0.500 UL
+LTb
+2318 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 2318 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-20)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3016 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 3016 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (-10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3715 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 3715 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+4414 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 4414 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (10)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5112 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 5112 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (20)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5811 2597 M
+0 -88 V
+0 88 R
+0 88 V
+stroke
+0.00 0.00 0.00 C 5811 2368 M
+[ [(Helvetica) 120.0 0.0 true true 0 (30)]
+] -40.0 MCshow
+0.500 UL
+LTb
+1.000 UL
+LTa
+1521 2597 M
+4388 0 V
+3715 552 M
+0 4090 V
+stroke
+0.500 UL
+LTb
+1521 4642 N
+0 -4090 V
+4388 0 V
+0 4090 V
+-4388 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 3715 2597 M
+7 1 V
+7 2 V
+6 3 V
+6 4 V
+5 6 V
+4 6 V
+2 7 V
+2 8 V
+0 9 V
+-1 9 V
+-3 9 V
+-5 9 V
+-6 9 V
+-7 8 V
+-10 7 V
+-10 7 V
+-12 6 V
+-14 4 V
+-14 3 V
+-15 1 V
+-16 0 V
+-16 -2 V
+-17 -4 V
+-17 -6 V
+-16 -9 V
+-16 -10 V
+-15 -12 V
+-13 -14 V
+-13 -16 V
+-11 -17 V
+-8 -20 V
+-7 -20 V
+-5 -22 V
+-2 -23 V
+1 -23 V
+3 -24 V
+7 -24 V
+9 -23 V
+12 -24 V
+15 -22 V
+18 -21 V
+21 -20 V
+24 -19 V
+26 -16 V
+28 -13 V
+30 -12 V
+32 -8 V
+33 -5 V
+35 -3 V
+35 2 V
+36 4 V
+35 9 V
+35 12 V
+34 15 V
+33 19 V
+31 23 V
+29 26 V
+27 29 V
+23 31 V
+21 35 V
+16 37 V
+13 38 V
+8 41 V
+4 42 V
+0 42 V
+-6 43 V
+-10 43 V
+-15 42 V
+-20 41 V
+-24 40 V
+-29 37 V
+-34 35 V
+-38 32 V
+-41 29 V
+-45 25 V
+-49 21 V
+-50 17 V
+-54 11 V
+-54 7 V
+-56 1 V
+-57 -3 V
+-56 -10 V
+-56 -14 V
+-55 -20 V
+-53 -26 V
+-50 -31 V
+-47 -35 V
+-44 -41 V
+-39 -45 V
+-35 -48 V
+-30 -53 V
+-24 -55 V
+-18 -59 V
+-12 -60 V
+-5 -61 V
+1 -63 V
+9 -63 V
+15 -62 V
+22 -61 V
+29 -59 V
+35 -57 V
+42 -54 V
+48 -50 V
+53 -46 V
+stroke 3307 2036 M
+59 -41 V
+64 -35 V
+67 -30 V
+71 -23 V
+74 -17 V
+76 -9 V
+78 -3 V
+78 5 V
+78 12 V
+76 19 V
+75 27 V
+73 34 V
+68 41 V
+65 48 V
+60 54 V
+54 60 V
+47 65 V
+41 69 V
+33 74 V
+25 77 V
+17 80 V
+9 82 V
+-1 82 V
+-9 83 V
+-18 82 V
+-28 81 V
+-36 78 V
+-45 75 V
+-53 71 V
+-61 66 V
+-68 61 V
+-75 54 V
+-81 47 V
+-86 40 V
+-91 32 V
+-94 23 V
+-97 15 V
+-99 5 V
+-100 -4 V
+-99 -13 V
+-99 -23 V
+-95 -32 V
+-93 -41 V
+-88 -50 V
+-83 -59 V
+-77 -66 V
+-70 -73 V
+-62 -80 V
+-53 -87 V
+-44 -91 V
+-35 -96 V
+-24 -99 V
+-13 -101 V
+-2 -103 V
+8 -103 V
+20 -102 V
+31 -101 V
+42 -97 V
+53 -94 V
+63 -90 V
+72 -83 V
+82 -76 V
+90 -69 V
+97 -61 V
+104 -52 V
+110 -41 V
+115 -32 V
+117 -21 V
+121 -9 V
+121 1 V
+121 13 V
+120 24 V
+118 36 V
+113 47 V
+109 57 V
+102 68 V
+96 77 V
+87 86 V
+77 94 V
+68 102 V
+56 108 V
+45 114 V
+33 118 V
+20 120 V
+7 123 V
+-6 123 V
+-20 123 V
+-33 121 V
+-46 118 V
+-59 114 V
+-71 108 V
+-82 102 V
+-94 93 V
+-104 85 V
+-113 75 V
+-121 65 V
+-128 53 V
+-133 42 V
+-139 29 V
+-141 15 V
+-143 3 V
+-143 -11 V
+-142 -24 V
+-140 -38 V
+stroke 3176 3855 M
+-135 -50 V
+-130 -64 V
+-123 -75 V
+-114 -87 V
+-106 -98 V
+-95 -107 V
+-83 -117 V
+-70 -124 V
+-57 -130 V
+-43 -136 V
+-29 -140 V
+-13 -143 V
+2 -143 V
+18 -144 V
+33 -141 V
+48 -139 V
+63 -134 V
+78 -128 V
+91 -120 V
+104 -112 V
+117 -102 V
+127 -92 V
+137 -79 V
+145 -66 V
+152 -53 V
+158 -38 V
+162 -24 V
+165 -8 V
+165 7 V
+164 23 V
+162 38 V
+157 53 V
+152 67 V
+144 82 V
+135 95 V
+125 108 V
+113 119 V
+101 130 V
+86 139 V
+71 147 V
+55 154 V
+38 159 V
+22 161 V
+4 164 V
+-14 164 V
+-31 163 V
+-49 159 V
+-66 155 V
+-83 148 V
+-98 141 V
+-113 131 V
+-128 120 V
+-140 109 V
+-152 95 V
+-161 80 V
+-171 66 V
+-177 49 V
+-182 33 V
+-185 16 V
+-187 -2 V
+-187 -19 V
+-184 -36 V
+-180 -54 V
+-174 -70 V
+-166 -87 V
+2487 3966 L
+2341 3849 L
+2209 3719 L
+2090 3577 L
+1987 3424 L
+-86 -163 V
+-69 -170 V
+-51 -177 V
+-31 -181 V
+-12 -183 V
+8 -185 V
+28 -183 V
+48 -181 V
+67 -176 V
+85 -169 V
+104 -161 V
+121 -151 V
+137 -140 V
+152 -127 V
+2653 965 L
+177 -96 V
+188 -80 V
+195 -62 V
+202 -44 V
+206 -25 V
+209 -5 V
+208 14 V
+207 33 V
+203 53 V
+197 71 V
+189 90 V
+179 108 V
+167 123 V
+153 140 V
+139 153 V
+121 166 V
+103 177 V
+84 187 V
+64 194 V
+43 199 V
+22 203 V
+% End plot #1
+stroke
+LTb
+1521 4642 N
+0 -4090 V
+4388 0 V
+0 4090 V
+-4388 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/polar.pdf b/doc/interpreter/polar.pdf
new file mode 100644
index 0000000..9b93826
Binary files /dev/null and b/doc/interpreter/polar.pdf differ
diff --git a/doc/interpreter/polar.png b/doc/interpreter/polar.png
new file mode 100644
index 0000000..339d5c0
Binary files /dev/null and b/doc/interpreter/polar.png differ
diff --git a/doc/interpreter/polar.txt b/doc/interpreter/polar.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/polar.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/poly.texi b/doc/interpreter/poly.texi
new file mode 100644
index 0000000..b55afc4
--- /dev/null
+++ b/doc/interpreter/poly.texi
@@ -0,0 +1,728 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Polynomial Manipulations
+ at chapter Polynomial Manipulations
+
+In Octave, a polynomial is represented by its coefficients (arranged
+in descending order).  For example, a vector @var{c} of length
+ at math{N+1} corresponds to the following polynomial of order
+ at tex
+ $N$
+$$
+ p (x) = c_1 x^N + \ldots + c_N x + c_{N+1}.
+$$
+ at end tex
+ at ifinfo
+ @var{N}
+
+ at example
+p(x) = @var{c}(1) x^@var{N} + @dots{} + @var{c}(@var{N}) x + @var{c}(@var{N}+1).
+ at end example
+ at end ifinfo
+
+ at menu
+* Evaluating Polynomials::
+* Finding Roots::
+* Products of Polynomials::
+* Derivatives and Integrals::
+* Polynomial Interpolation::
+* Miscellaneous Functions::
+ at end menu
+
+ at node Evaluating Polynomials
+ at section Evaluating Polynomials
+
+The value of a polynomial represented by the vector @var{c} can be evaluated
+at the point @var{x} very easily, as the following example shows:
+
+ at example
+ at group
+N = length(c)-1;
+val = dot( x.^(N:-1:0), c );
+ at end group
+ at end example
+
+ at noindent
+While the above example shows how easy it is to compute the value of a
+polynomial, it isn't the most stable algorithm.  With larger polynomials
+you should use more elegant algorithms, such as Horner's Method, which
+is exactly what the Octave function @code{polyval} does.
+
+In the case where @var{x} is a square matrix, the polynomial given by
+ at var{c} is still well-defined.  As when @var{x} is a scalar the obvious
+implementation is easily expressed in Octave, but also in this case
+more elegant algorithms perform better.  The @code{polyvalm} function
+provides such an algorithm.
+
+ at c ./polynomial/polyval.m
+ at anchor{doc-polyval}
+ at deftypefn {Function File} {@var{y} =} polyval (@var{p}, @var{x})
+ at deftypefnx {Function File} {@var{y} =} polyval (@var{p}, @var{x}, [], @var{mu})
+Evaluate the polynomial at of the specified values for @var{x}.  When @var{mu}
+is present evaluate the polynomial for (@var{x}- at var{mu}(1))/@var{mu}(2).
+If @var{x} is a vector or matrix, the polynomial is evaluated for each of
+the elements of @var{x}.
+ at deftypefnx {Function File} {[@var{y}, @var{dy}] =} polyval (@var{p}, @var{x}, @var{s})
+ at deftypefnx {Function File} {[@var{y}, @var{dy}] =} polyval (@var{p}, @var{x}, @var{s}, @var{mu})
+In addition to evaluating the polynomial, the second output 
+represents the prediction interval, @var{y} +/- @var{dy}, which
+contains at least 50% of the future predictions.  To calculate the
+prediction interval, the structured variable @var{s}, originating
+form `polyfit', must be present.
+ at seealso{@ref{doc-polyfit,,polyfit}, @ref{doc-polyvalm,,polyvalm}, @ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at c ./polynomial/polyvalm.m
+ at anchor{doc-polyvalm}
+ at deftypefn {Function File} {} polyvalm (@var{c}, @var{x})
+Evaluate a polynomial in the matrix sense.
+
+ at code{polyvalm (@var{c}, @var{x})} will evaluate the polynomial in the
+matrix sense, i.e., matrix multiplication is used instead of element by
+element multiplication as is used in polyval.
+
+The argument @var{x} must be a square matrix.
+ at seealso{@ref{doc-polyval,,polyval}, @ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at node Finding Roots
+ at section Finding Roots
+
+Octave can find the roots of a given polynomial.  This is done by computing
+the companion matrix of the polynomial (see the @code{compan} function
+for a definition), and then finding its eigenvalues.
+
+ at c ./polynomial/roots.m
+ at anchor{doc-roots}
+ at deftypefn {Function File} {} roots (@var{v})
+
+For a vector @var{v} with @math{N} components, return
+the roots of the polynomial
+ at tex
+$$
+v_1 z^{N-1} + \cdots + v_{N-1} z + v_N.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+v(1) * z^(N-1) + @dots{} + v(N-1) * z + v(N)
+ at end example
+ at end ifnottex
+
+As an example, the following code finds the roots of the quadratic
+polynomial
+ at tex
+$$ p(x) = x^2 - 5. $$
+ at end tex
+ at ifnottex
+ at example
+p(x) = x^2 - 5.
+ at end example
+ at end ifnottex
+ at example
+ at group
+c = [1, 0, -5];
+roots(c)
+ at result{}  2.2361
+ at result{} -2.2361
+ at end group
+ at end example
+Note that the true result is
+ at tex
+$\pm \sqrt{5}$
+ at end tex
+ at ifnottex
+ at math{+/- sqrt(5)}
+ at end ifnottex
+which is roughly
+ at tex
+$\pm 2.2361$.
+ at end tex
+ at ifnottex
+ at math{+/- 2.2361}.
+ at end ifnottex
+ at seealso{@ref{doc-compan,,compan}}
+ at end deftypefn
+
+
+ at c ./polynomial/compan.m
+ at anchor{doc-compan}
+ at deftypefn {Function File} {} compan (@var{c})
+Compute the companion matrix corresponding to polynomial coefficient
+vector @var{c}.
+
+The companion matrix is
+ at tex
+$$
+A = \left[\matrix{
+ -c_2/c_1 & -c_3/c_1 & \cdots & -c_N/c_1 & -c_{N+1}/c_1\cr
+     1    &     0    & \cdots &     0    &         0   \cr
+     0    &     1    & \cdots &     0    &         0   \cr
+  \vdots  &   \vdots & \ddots &  \vdots  &      \vdots \cr
+     0    &     0    & \cdots &     1    &         0}\right].
+$$
+ at end tex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+     _                                                        _
+    |  -c(2)/c(1)   -c(3)/c(1)  @dots{}  -c(N)/c(1)  -c(N+1)/c(1)  |
+    |       1            0      @dots{}       0             0      |
+    |       0            1      @dots{}       0             0      |
+A = |       .            .   .            .             .      |
+    |       .            .       .        .             .      |
+    |       .            .           .    .             .      |
+    |_      0            0      @dots{}       1             0     _|
+ at end smallexample
+ at end ifnottex
+
+The eigenvalues of the companion matrix are equal to the roots of the
+polynomial.
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-residue,,residue}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-polyval,,polyval}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at c ./polynomial/mpoles.m
+ at anchor{doc-mpoles}
+ at deftypefn {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p})
+ at deftypefnx {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p}, @var{tol})
+ at deftypefnx {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p}, @var{tol}, @var{reorder})
+Identify unique poles in @var{p} and associates their multiplicity,
+ordering them from largest to smallest.
+
+If the relative difference of the poles is less than @var{tol}, then
+they are considered to be multiples.  The default value for @var{tol}
+is 0.001.
+
+If the optional parameter @var{reorder} is zero, poles are not sorted.
+
+The value @var{multp} is a vector specifying the multiplicity of the
+poles.  @var{multp}(:) refers to multiplicity of @var{p}(@var{indx}(:)).
+
+For example,
+
+ at example
+ at group
+p = [2 3 1 1 2];
+[m, n] = mpoles(p);
+  @result{} m = [1; 1; 2; 1; 2]
+  @result{} n = [2; 5; 1; 4; 3]
+  @result{} p(n) = [3, 2, 2, 1, 1]
+ at end group
+ at end example
+
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-polyval,,polyval}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}, @ref{doc-residue,,residue}}
+ at end deftypefn
+
+
+ at node Products of Polynomials
+ at section Products of Polynomials
+
+ at c ./polynomial/conv.m
+ at anchor{doc-conv}
+ at deftypefn {Function File} {} conv (@var{a}, @var{b})
+Convolve two vectors.
+
+ at code{y = conv (a, b)} returns a vector of length equal to
+ at 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.
+ at seealso{@ref{doc-deconv,,deconv}, @ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-residue,,residue}, @ref{doc-polyval,,polyval}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at c ./polynomial/convn.m
+ at anchor{doc-convn}
+ at deftypefn {Function File} {@var{c} =} convn (@var{a}, @var{b}, @var{shape})
+ at math{N}-dimensional convolution of matrices @var{a} and @var{b}.
+
+The size of the output is determined by the @var{shape} argument.
+This can be any of the following character strings:
+
+ at table @asis
+ at item "full"
+The full convolution result is returned.  The size out of the output is
+ at code{size (@var{a}) + size (@var{b})-1}.  This is the default behavior.
+ at item "same"
+The central part of the convolution result is returned.  The size out of the
+output is the same as @var{a}.
+ at item "valid"
+The valid part of the convolution is returned.  The size of the result is
+ at code{max (size (@var{a}) - size (@var{b})+1, 0)}.
+ at end table
+
+ at seealso{@ref{doc-conv,,conv}, @ref{doc-conv2,,conv2}}
+ at end deftypefn
+
+
+ at c ./polynomial/deconv.m
+ at anchor{doc-deconv}
+ at deftypefn {Function File} {} deconv (@var{y}, @var{a})
+Deconvolve two vectors.
+
+ at code{[b, r] = deconv (y, a)} solves for @var{b} and @var{r} such that
+ at 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.
+ at seealso{@ref{doc-conv,,conv}, @ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-residue,,residue}, @ref{doc-polyval,,polyval}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/conv2.cc
+ at anchor{doc-conv2}
+ at deftypefn {Loadable Function} {y =} conv2 (@var{a}, @var{b}, @var{shape})
+ at deftypefnx {Loadable Function} {y =} conv2 (@var{v1}, @var{v2}, @var{M}, @var{shape})
+
+Returns 2D convolution of @var{a} and @var{b} where the size
+of @var{c} is given by
+
+ at table @asis
+ at item @var{shape}= 'full'
+returns full 2-D convolution
+ at item @var{shape}= 'same'
+same size as a. 'central' part of convolution
+ at item @var{shape}= 'valid'
+only parts which do not include zero-padded edges
+ at end table
+
+By default @var{shape} is 'full'.  When the third argument is a matrix
+returns the convolution of the matrix @var{M} by the vector @var{v1}
+in the column direction and by vector @var{v2} in the row direction
+ at end deftypefn
+
+
+ at c ./polynomial/polygcd.m
+ at anchor{doc-polygcd}
+ at deftypefn {Function File} {@var{q} =} polygcd (@var{b}, @var{a}, @var{tol})
+
+Find greatest common divisor of two polynomials.  This is equivalent
+to the polynomial found by multiplying together all the common roots.
+Together with deconv, you can reduce a ratio of two polynomials.
+Tolerance defaults to 
+ at example 
+sqrt(eps).
+ at end example
+ Note that this is an unstable
+algorithm, so don't try it on large polynomials.
+
+Example
+ at example
+ at group
+polygcd (poly(1:8), poly(3:12)) - poly(3:8)
+ at result{} [ 0, 0, 0, 0, 0, 0, 0 ]
+deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))) ...
+  - poly(1:2)
+ at result{} [ 0, 0, 0 ]
+ at end group
+ at end example
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-polyinteg,,polyinteg}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyreduce,,polyreduce}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyval,,polyval}, @ref{doc-polyvalm,,polyvalm}}
+ at end deftypefn
+
+
+ at c ./polynomial/residue.m
+ at anchor{doc-residue}
+ at deftypefn {Function File} {[@var{r}, @var{p}, @var{k}, @var{e}] =} residue (@var{b}, @var{a})
+Compute the partial fraction expansion for the quotient of the
+polynomials, @var{b} and @var{a}.
+
+ at tex
+$$
+{B(s)\over A(s)} = \sum_{m=1}^M {r_m\over (s-p_m)^e_m}
+  + \sum_{i=1}^N k_i s^{N-i}.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+ B(s)    M       r(m)         N
+ ---- = SUM -------------  + SUM k(i)*s^(N-i)
+ A(s)   m=1 (s-p(m))^e(m)    i=1
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+where @math{M} is the number of poles (the length of the @var{r},
+ at var{p}, and @var{e}), the @var{k} vector is a polynomial of order @math{N-1}
+representing the direct contribution, and the @var{e} vector specifies
+the multiplicity of the m-th residue's pole.
+
+For example,
+
+ at example
+ at group
+b = [1, 1, 1];
+a = [1, -5, 8, -4];
+[r, p, k, e] = residue (b, a);
+     @result{} r = [-2; 7; 3]
+     @result{} p = [2; 2; 1]
+     @result{} k = [](0x0)
+     @result{} e = [1; 2; 1]
+ at end group
+ at end example
+
+ at noindent
+which represents the following partial fraction expansion
+ at tex
+$$
+{s^2+s+1\over s^3-5s^2+8s-4} = {-2\over s-2} + {7\over (s-2)^2} + {3\over s-1}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+        s^2 + s + 1       -2        7        3
+   ------------------- = ----- + ------- + -----
+   s^3 - 5s^2 + 8s - 4   (s-2)   (s-2)^2   (s-1)
+ at end group
+ at end example
+
+ at end ifnottex
+
+ at deftypefnx {Function File} {[@var{b}, @var{a}] =} residue (@var{r}, @var{p}, @var{k})
+ at deftypefnx {Function File} {[@var{b}, @var{a}] =} residue (@var{r}, @var{p}, @var{k}, @var{e})
+Compute the reconstituted quotient of polynomials,
+ at var{b}(s)/@var{a}(s), from the partial fraction expansion;
+represented by the residues, poles, and a direct polynomial specified
+by @var{r}, @var{p} and @var{k}, and the pole multiplicity @var{e}.
+
+If the multiplicity, @var{e}, is not explicitly specified the multiplicity is
+determined by the script mpoles.m.
+
+For example,
+
+ at example
+ at group
+r = [-2; 7; 3];
+p = [2; 2; 1];
+k = [1, 0];
+[b, a] = residue (r, p, k);
+     @result{} b = [1, -5, 9, -3, 1]
+     @result{} a = [1, -5, 8, -4]
+
+where mpoles.m is used to determine e = [1; 2; 1]
+
+ at end group
+ at end example
+
+Alternatively the multiplicity may be defined explicitly, for example,
+
+ at example
+ at group
+r = [7; 3; -2];
+p = [2; 1; 2];
+k = [1, 0];
+e = [2; 1; 1];
+[b, a] = residue (r, p, k, e);
+     @result{} b = [1, -5, 9, -3, 1]
+     @result{} a = [1, -5, 8, -4]
+ at end group
+ at end example
+
+ at noindent
+which represents the following partial fraction expansion
+ at tex
+$$
+{-2\over s-2} + {7\over (s-2)^2} + {3\over s-1} + s = {s^4-5s^3+9s^2-3s+1\over s^3-5s^2+8s-4}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+    -2        7        3         s^4 - 5s^3 + 9s^2 - 3s + 1
+   ----- + ------- + ----- + s = --------------------------
+   (s-2)   (s-2)^2   (s-1)          s^3 - 5s^2 + 8s - 4
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-mpoles,,mpoles}, @ref{doc-polyval,,polyval}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at node Derivatives and Integrals
+ at section Derivatives and Integrals
+
+Octave comes with functions for computing the derivative and the integral
+of a polynomial.  The functions @code{polyderiv} and @code{polyint}
+both return new polynomials describing the result.  As an example we'll
+compute the definite integral of @math{p(x) = x^2 + 1} from 0 to 3.
+
+ at example
+ at group
+c = [1, 0, 1];
+integral = polyint(c);
+area = polyval(integral, 3) - polyval(integral, 0)
+ at result{} 12
+ at end group
+ at end example
+
+ at c ./polynomial/polyderiv.m
+ at anchor{doc-polyderiv}
+ at deftypefn {Function File} {} polyderiv (@var{c})
+ at deftypefnx {Function File} {[@var{q}] =} polyderiv (@var{b}, @var{a})
+ at deftypefnx {Function File} {[@var{q}, @var{r}] =} polyderiv (@var{b}, @var{a})
+Return the coefficients of the derivative of the polynomial whose
+coefficients are given by vector @var{c}.  If a pair of polynomials
+is given @var{b} and @var{a}, the derivative of the product is
+returned in @var{q}, or the quotient numerator in @var{q} and the
+quotient denominator in @var{r}.
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-polyinteg,,polyinteg}, @ref{doc-polyreduce,,polyreduce}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polygcd,,polygcd}, @ref{doc-polyval,,polyval}, @ref{doc-polyvalm,,polyvalm}}
+ at end deftypefn
+
+
+ at c ./polynomial/polyder.m
+ at anchor{doc-polyder}
+ at deftypefn {Function File} {} polyder (@var{c})
+ at deftypefnx {Function File} {[@var{q}] =} polyder (@var{b}, @var{a})
+ at deftypefnx {Function File} {[@var{q}, @var{r}] =} polyder (@var{b}, @var{a})
+See polyderiv.
+ at end deftypefn
+
+
+ at c ./deprecated/polyinteg.m
+ at anchor{doc-polyinteg}
+ at deftypefn {Function File} {} polyinteg (@var{c})
+Return the coefficients of the integral of the polynomial whose
+coefficients are represented by the vector @var{c}.
+
+The constant of integration is set to zero.
+ at seealso{@ref{doc-polyint,,polyint}, @ref{doc-poly,,poly}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyreduce,,polyreduce}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyval,,polyval}, @ref{doc-polyvalm,,polyvalm}}
+ at end deftypefn
+
+
+ at c ./polynomial/polyint.m
+ at anchor{doc-polyint}
+ at deftypefn {Function File} {} polyint (@var{c}, @var{k})
+Return the coefficients of the integral of the polynomial whose
+coefficients are represented by the vector @var{c}.  The variable
+ at var{k} is the constant of integration, which by default is set to zero.
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyreduce,,polyreduce}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyval,,polyval}, @ref{doc-polyvalm,,polyvalm}}
+ at end deftypefn
+
+
+ at node Polynomial Interpolation
+ at section Polynomial Interpolation
+
+Octave comes with good support for various kinds of interpolation,
+most of which are described in @ref{Interpolation}.  One simple alternative
+to the functions described in the aforementioned chapter, is to fit
+a single polynomial to some given data points.  To avoid a highly
+fluctuating polynomial, one most often wants to fit a low-order polynomial
+to data.  This usually means that it is necessary to fit the polynomial
+in a least-squares sense, which is what the @code{polyfit} function does.
+
+ at c ./polynomial/polyfit.m
+ at anchor{doc-polyfit}
+ at deftypefn {Function File} {[@var{p}, @var{s}, @var{mu}] =} polyfit (@var{x}, @var{y}, @var{n})
+Return the coefficients of a polynomial @var{p}(@var{x}) of degree
+ at var{n} that minimizes the least-squares-error of the fit.
+
+The polynomial coefficients are returned in a row vector.
+
+The second output is a structure containing the following fields:
+
+ at table @samp
+ at item R
+Triangular factor R from the QR decomposition.
+ at item X
+The Vandermonde matrix used to compute the polynomial coefficients.
+ at item df
+The degrees of freedom.
+ at item normr
+The norm of the residuals.
+ at item yf
+The values of the polynomial for each value of @var{x}.
+ at end table
+
+The second output may be used by @code{polyval} to calculate the 
+statistical error limits of the predicted values.
+
+When the third output, @var{mu}, is present the 
+coefficients, @var{p}, are associated with a polynomial in
+ at var{xhat} = (@var{x}- at var{mu}(1))/@var{mu}(2).
+Where @var{mu}(1) = mean (@var{x}), and @var{mu}(2) = std (@var{x}).
+This linear transformation of @var{x} improves the numerical
+stability of the fit.
+ at seealso{@ref{doc-polyval,,polyval}, @ref{doc-residue,,residue}}
+ at end deftypefn
+
+
+In situations where a single polynomial isn't good enough, a solution
+is to use several polynomials pieced together.  The function @code{mkpp}
+creates a piece-wise polynomial, @code{ppval} evaluates the function 
+created by @code{mkpp}, and @code{unmkpp} returns detailed information
+about the function.
+
+The following example shows how to combine two linear functions and a
+quadratic into one function.  Each of these functions is expressed
+on adjoined intervals.
+
+ at example
+ at group
+x = [-2, -1, 1, 2];
+p = [ 0,  1, 0;
+      1, -2, 1;
+      0, -1, 1 ];
+pp = mkpp(x, p);
+xi = linspace(-2, 2, 50);
+yi = ppval(pp, xi);
+plot(xi, yi);
+ at end group
+ at end example
+
+ at c ./polynomial/ppval.m
+ at anchor{doc-ppval}
+ at deftypefn {Function File} {@var{yi} =} ppval (@var{pp}, @var{xi})
+Evaluate piece-wise polynomial @var{pp} at the points @var{xi}.  
+If @code{@var{pp}.d} is a scalar greater than 1, or an array,
+then the returned value @var{yi} will be an array that is 
+ at code{d1, d1, @dots{}, dk, length (@var{xi})]}.
+ at seealso{@ref{doc-mkpp,,mkpp}, @ref{doc-unmkpp,,unmkpp}, @ref{doc-spline,,spline}}
+ at end deftypefn 
+
+
+ at c ./polynomial/mkpp.m
+ at anchor{doc-mkpp}
+ at deftypefn {Function File} {@var{pp} =} mkpp (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{pp} =} mkpp (@var{x}, @var{p}, @var{d})
+
+Construct a piece-wise polynomial structure from sample points
+ at var{x} and coefficients @var{p}.  The i-th row of @var{p},
+ at code{@var{p} (@var{i},:)}, contains the coefficients for the polynomial
+over the @var{i}-th interval, ordered from highest to 
+lowest.  There must be one row for each interval in @var{x}, so 
+ at code{rows (@var{p}) == length (@var{x}) - 1}.  
+
+You can concatenate multiple polynomials of the same order over the 
+same set of intervals using @code{@var{p} = [ @var{p1}; @var{p2}; 
+ at dots{}; @var{pd} ]}.  In this case, @code{rows (@var{p}) == @var{d} 
+* (length (@var{x}) - 1)}.
+
+ at var{d} specifies the shape of the matrix @var{p} for all except the
+last dimension.  If @var{d} is not specified it will be computed as
+ at code{round (rows (@var{p}) / (length (@var{x}) - 1))} instead.
+
+ at seealso{@ref{doc-unmkpp,,unmkpp}, @ref{doc-ppval,,ppval}, @ref{doc-spline,,spline}}
+ at end deftypefn
+
+
+ at c ./polynomial/unmkpp.m
+ at anchor{doc-unmkpp}
+ at deftypefn {Function File} {[@var{x}, @var{p}, @var{n}, @var{k}, @var{d}] =} unmkpp (@var{pp})
+
+Extract the components of a piece-wise polynomial structure @var{pp}.
+These are as follows:
+
+ at table @asis
+ at item @var{x}
+Sample points.
+ at item @var{p}
+Polynomial coefficients for points in sample interval.  @code{@var{p}
+(@var{i}, :)} contains the coefficients for the polynomial over
+interval @var{i} ordered from highest to lowest.  If @code{@var{d} >
+1}, @code{@var{p} (@var{r}, @var{i}, :)} contains the coefficients for 
+the r-th polynomial defined on interval @var{i}.  However, this is 
+stored as a 2-D array such that @code{@var{c} = reshape (@var{p} (:,
+ at var{j}), @var{n}, @var{d})} gives @code{@var{c} (@var{i},  @var{r})}
+is the j-th coefficient of the r-th polynomial over the i-th interval.
+ at item @var{n}
+Number of polynomial pieces.
+ at item @var{k}
+Order of the polynomial plus 1.
+ at item @var{d}
+Number of polynomials defined for each interval.
+ at end table
+
+ at seealso{@ref{doc-mkpp,,mkpp}, @ref{doc-ppval,,ppval}, @ref{doc-spline,,spline}}
+ at end deftypefn
+
+
+ at node Miscellaneous Functions
+ at section Miscellaneous Functions
+
+ at c ./polynomial/poly.m
+ at anchor{doc-poly}
+ at deftypefn {Function File} {} poly (@var{a})
+If @var{a} is a square @math{N}-by- at math{N} matrix, @code{poly (@var{a})}
+is the row vector of the coefficients of @code{det (z * eye (N) - a)},
+the characteristic polynomial of @var{a}.  As an example we can use
+this to find the eigenvalues of @var{a} as the roots of @code{poly (@var{a})}.
+ at example
+ at group
+roots(poly(eye(3)))
+ at result{} 1.00000 + 0.00000i
+ at result{} 1.00000 - 0.00000i
+ at result{} 1.00000 + 0.00000i
+ at end group
+ at end example
+In real-life examples you should, however, use the @code{eig} function
+for computing eigenvalues.
+
+If @var{x} is a vector, @code{poly (@var{x})} is a vector of coefficients
+of the polynomial whose roots are the elements of @var{x}.  That is,
+of @var{c} is a polynomial, then the elements of 
+ at code{@var{d} = roots (poly (@var{c}))} are contained in @var{c}.
+The vectors @var{c} and @var{d} are, however, not equal due to sorting
+and numerical errors.
+ at seealso{@ref{doc-eig,,eig}, @ref{doc-roots,,roots}}
+ at end deftypefn
+
+
+ at c ./polynomial/polyout.m
+ at anchor{doc-polyout}
+ at deftypefn {Function File} {} polyout (@var{c}, @var{x})
+Write formatted polynomial
+ at tex
+$$ c(x) = c_1 x^n + \ldots + c_n x + c_{n+1} $$
+ at end tex
+ at ifnottex
+ at example
+   c(x) = c(1) * x^n + @dots{} + c(n) x + c(n+1)
+ at end example
+ at end ifnottex
+ and return it as a string or write it to the screen (if
+ at var{nargout} is zero).
+ at var{x} defaults to the string @code{"s"}.
+ at seealso{@ref{doc-polyval,,polyval}, @ref{doc-polyvalm,,polyvalm}, @ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+ at c ./polynomial/polyreduce.m
+ at anchor{doc-polyreduce}
+ at deftypefn {Function File} {} polyreduce (@var{c})
+Reduces a polynomial coefficient vector to a minimum number of terms by
+stripping off any leading zeros.
+ at seealso{@ref{doc-poly,,poly}, @ref{doc-roots,,roots}, @ref{doc-conv,,conv}, @ref{doc-deconv,,deconv}, @ref{doc-residue,,residue}, @ref{doc-filter,,filter}, @ref{doc-polyval,,polyval}, @ref{doc-polyvalm,,polyvalm}, @ref{doc-polyderiv,,polyderiv}, @ref{doc-polyinteg,,polyinteg}}
+ at end deftypefn
+
+
+
+
+
diff --git a/doc/interpreter/poly.txi b/doc/interpreter/poly.txi
new file mode 100644
index 0000000..4f30e30
--- /dev/null
+++ b/doc/interpreter/poly.txi
@@ -0,0 +1,183 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Polynomial Manipulations
+ at chapter Polynomial Manipulations
+
+In Octave, a polynomial is represented by its coefficients (arranged
+in descending order).  For example, a vector @var{c} of length
+ at math{N+1} corresponds to the following polynomial of order
+ at tex
+ $N$
+$$
+ p (x) = c_1 x^N + \ldots + c_N x + c_{N+1}.
+$$
+ at end tex
+ at ifinfo
+ @var{N}
+
+ at example
+p(x) = @var{c}(1) x^@var{N} + @dots{} + @var{c}(@var{N}) x + @var{c}(@var{N}+1).
+ at end example
+ at end ifinfo
+
+ at menu
+* Evaluating Polynomials::
+* Finding Roots::
+* Products of Polynomials::
+* Derivatives and Integrals::
+* Polynomial Interpolation::
+* Miscellaneous Functions::
+ at end menu
+
+ at node Evaluating Polynomials
+ at section Evaluating Polynomials
+
+The value of a polynomial represented by the vector @var{c} can be evaluated
+at the point @var{x} very easily, as the following example shows:
+
+ at example
+ at group
+N = length(c)-1;
+val = dot( x.^(N:-1:0), c );
+ at end group
+ at end example
+
+ at noindent
+While the above example shows how easy it is to compute the value of a
+polynomial, it isn't the most stable algorithm.  With larger polynomials
+you should use more elegant algorithms, such as Horner's Method, which
+is exactly what the Octave function @code{polyval} does.
+
+In the case where @var{x} is a square matrix, the polynomial given by
+ at var{c} is still well-defined.  As when @var{x} is a scalar the obvious
+implementation is easily expressed in Octave, but also in this case
+more elegant algorithms perform better.  The @code{polyvalm} function
+provides such an algorithm.
+
+ at DOCSTRING(polyval)
+
+ at DOCSTRING(polyvalm)
+
+ at node Finding Roots
+ at section Finding Roots
+
+Octave can find the roots of a given polynomial.  This is done by computing
+the companion matrix of the polynomial (see the @code{compan} function
+for a definition), and then finding its eigenvalues.
+
+ at DOCSTRING(roots)
+
+ at DOCSTRING(compan)
+
+ at DOCSTRING(mpoles)
+
+ at node Products of Polynomials
+ at section Products of Polynomials
+
+ at DOCSTRING(conv)
+
+ at DOCSTRING(convn)
+
+ at DOCSTRING(deconv)
+
+ at DOCSTRING(conv2)
+
+ at DOCSTRING(polygcd)
+
+ at DOCSTRING(residue)
+
+ at node Derivatives and Integrals
+ at section Derivatives and Integrals
+
+Octave comes with functions for computing the derivative and the integral
+of a polynomial.  The functions @code{polyderiv} and @code{polyint}
+both return new polynomials describing the result.  As an example we'll
+compute the definite integral of @math{p(x) = x^2 + 1} from 0 to 3.
+
+ at example
+ at group
+c = [1, 0, 1];
+integral = polyint(c);
+area = polyval(integral, 3) - polyval(integral, 0)
+ at result{} 12
+ at end group
+ at end example
+
+ at DOCSTRING(polyderiv)
+
+ at DOCSTRING(polyder)
+
+ at DOCSTRING(polyinteg)
+
+ at DOCSTRING(polyint)
+
+ at node Polynomial Interpolation
+ at section Polynomial Interpolation
+
+Octave comes with good support for various kinds of interpolation,
+most of which are described in @ref{Interpolation}.  One simple alternative
+to the functions described in the aforementioned chapter, is to fit
+a single polynomial to some given data points.  To avoid a highly
+fluctuating polynomial, one most often wants to fit a low-order polynomial
+to data.  This usually means that it is necessary to fit the polynomial
+in a least-squares sense, which is what the @code{polyfit} function does.
+
+ at DOCSTRING(polyfit)
+
+In situations where a single polynomial isn't good enough, a solution
+is to use several polynomials pieced together.  The function @code{mkpp}
+creates a piece-wise polynomial, @code{ppval} evaluates the function 
+created by @code{mkpp}, and @code{unmkpp} returns detailed information
+about the function.
+
+The following example shows how to combine two linear functions and a
+quadratic into one function.  Each of these functions is expressed
+on adjoined intervals.
+
+ at example
+ at group
+x = [-2, -1, 1, 2];
+p = [ 0,  1, 0;
+      1, -2, 1;
+      0, -1, 1 ];
+pp = mkpp(x, p);
+xi = linspace(-2, 2, 50);
+yi = ppval(pp, xi);
+plot(xi, yi);
+ at end group
+ at end example
+
+ at DOCSTRING(ppval)
+
+ at DOCSTRING(mkpp)
+
+ at DOCSTRING(unmkpp)
+
+ at node Miscellaneous Functions
+ at section Miscellaneous Functions
+
+ at DOCSTRING(poly)
+
+ at DOCSTRING(polyout)
+
+ at DOCSTRING(polyreduce)
+
+
+
+
diff --git a/doc/interpreter/preface.texi b/doc/interpreter/preface.texi
new file mode 100644
index 0000000..f747bdb
--- /dev/null
+++ b/doc/interpreter/preface.texi
@@ -0,0 +1,196 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
+ at c               2005, 2006, 2007, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Preface
+ at unnumbered Preface
+ at cindex contributors
+ at cindex history
+
+Octave was originally intended to be companion software for an
+undergraduate-level textbook on chemical reactor design being written by
+James B. Rawlings of the University of Wisconsin-Madison and John
+G. Ekerdt of the University of Texas.
+
+Clearly, Octave is now much more than just another `courseware' package
+with limited utility beyond the classroom.  Although our initial goals
+were somewhat vague, we knew that we wanted to create something that
+would enable students to solve realistic problems, and that they could
+use for many things other than chemical reactor design problems.
+
+There are those who would say that we should be teaching the students
+Fortran instead, because that is the computer language of engineering,
+but every time we have tried that, the students have spent far too much
+time trying to figure out why their Fortran code crashes and not enough
+time learning about chemical engineering.  With Octave, most students
+pick up the basics quickly, and are using it confidently in just a few
+hours.
+
+Although it was originally intended to be used to teach reactor design,
+it has been used in several other undergraduate and graduate
+courses in the Chemical Engineering Department at the University of
+Texas, and the math department at the University of Texas has been using
+it for teaching differential equations and linear algebra as well.  If
+you find it useful, please let us know.  We are always interested to
+find out how Octave is being used in other places.
+
+Virtually everyone thinks that the name Octave has something to do with
+music, but it is actually the name of a former professor of mine who
+wrote a famous textbook on chemical reaction engineering, and who was
+also well known for his ability to do quick `back of the envelope'
+calculations.  We hope that this software will make it possible for many
+people to do more ambitious computations just as easily.
+
+Everyone is encouraged to share this software with others under the
+terms of the GNU General Public License (@pxref{Copying}).  You are 
+also encouraged to help make Octave more useful by writing and 
+contributing additional functions for it, and by reporting any problems
+you may have.
+
+ at menu
+* Acknowledgements::            
+* How You Can Contribute to Octave::  
+* Distribution::                
+ at end menu
+
+ at node Acknowledgements
+ at unnumberedsec Acknowledgements
+ at cindex acknowledgements
+
+Many people have already contributed to Octave's development.  The
+following people have helped code parts of Octave or aided in
+various other ways (listed alphabetically).
+
+ at include contributors.texi
+
+Special thanks to the following people and organizations for
+supporting the development of Octave:
+
+ at itemize @bullet
+ at item
+The United States Department of Energy, through grant number
+DE-FG02-04ER25635.
+
+ at item
+Ashok Krishnamurthy, David Hudak, Juan Carlos Chaves, and Stanley
+C. Ahalt of the Ohio Supercomputer Center.
+
+ at item
+The National Science Foundation, through grant numbers CTS-0105360,
+CTS-9708497, CTS-9311420, CTS-8957123, and CNS-0540147.
+
+ at item
+The industrial members of the Texas-Wisconsin Modeling and Control
+Consortium (@uref{http://www.che.utexas.edu/twmcc, TWMCC}).
+
+ at item
+The Paul A. Elfers Endowed Chair in Chemical Engineering at the
+University of Wisconsin-Madison.
+
+ at item
+Digital Equipment Corporation, for an equipment grant as part of their
+External Research Program.
+
+ at item
+Sun Microsystems, Inc., for an Academic Equipment grant.
+
+ at item
+International Business Machines, Inc., for providing equipment as part
+of a grant to the University of Texas College of Engineering.
+
+ at item
+Texaco Chemical Company, for providing funding to continue the
+development of this software.
+
+ at item
+The University of Texas College of Engineering, for providing a
+Challenge for Excellence Research Supplement, and for providing an
+Academic Development Funds grant.
+
+ at item
+The State of Texas, for providing funding through the Texas
+Advanced Technology Program under Grant No. 003658-078.
+
+ at item
+Noel Bell, Senior Engineer, Texaco Chemical Company, Austin Texas.
+
+ at item
+John A. Turner, Group Leader, Continuum Dynamics (CCS-2), Los Alamos
+National Laboratory, for registering the @url{octave.org} domain name.
+
+ at item
+James B. Rawlings, Professor, University of Wisconsin-Madison,
+Department of Chemical and Biological Engineering.
+
+ at item
+Richard Stallman, for writing GNU.
+ at end itemize
+
+This project would not have been possible without the GNU software used
+in and to produce Octave.
+
+ at node How You Can Contribute to Octave
+ at unnumberedsec How You Can Contribute to Octave
+ at cindex contributing to Octave
+ at cindex funding Octave development
+
+There are a number of ways that you can contribute to help make Octave a
+better system.  Perhaps the most important way to contribute is to write
+high-quality code for solving new problems, and to make your code freely
+available for others to use.  @xref{Contributing Guidelines}, for detailed 
+information on contributing new code.
+
+If you find Octave useful, consider providing additional funding to
+continue its development.  Even a modest amount of additional funding
+could make a significant difference in the amount of time that is
+available for development and support.
+
+If you cannot provide funding or contribute code, you can still help
+make Octave better and more reliable by reporting any bugs you find and
+by offering suggestions for ways to improve Octave.  @xref{Trouble}, for
+tips on how to write useful bug reports.
+
+ at node Distribution
+ at unnumberedsec Distribution
+ at cindex distribution of Octave
+
+Octave is @dfn{free} software.  This means that everyone is free to
+use it and free to redistribute it on certain conditions.  Octave 
+is not, however, in the public domain.  It is copyrighted and there are
+restrictions on its distribution, but the restrictions are designed to 
+ensure that others will have the same freedom to use and redistribute 
+Octave that you have.  The precise conditions can be found in the 
+GNU General Public License that comes with Octave and that also appears 
+in @ref{Copying}.
+
+Octave is available on CD-ROM, with various collections of other free
+software, from the Free Software Foundation.  Ordering a copy of
+Octave from the Free Software Foundation helps to fund the development
+of more free software.  For more information, write to
+
+ at quotation
+Free Software Foundation@*
+51 Franklin Street, Fifth Floor@*
+Boston, MA 02110-1301--1307@*
+USA
+ at end quotation
+
+Octave can also be downloaded from @url{http://www.octave.org}, where
+additional information is available.
diff --git a/doc/interpreter/preface.txi b/doc/interpreter/preface.txi
new file mode 100644
index 0000000..4e09d4d
--- /dev/null
+++ b/doc/interpreter/preface.txi
@@ -0,0 +1,194 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
+ at c               2005, 2006, 2007, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Preface
+ at unnumbered Preface
+ at cindex contributors
+ at cindex history
+
+Octave was originally intended to be companion software for an
+undergraduate-level textbook on chemical reactor design being written by
+James B. Rawlings of the University of Wisconsin-Madison and John
+G. Ekerdt of the University of Texas.
+
+Clearly, Octave is now much more than just another `courseware' package
+with limited utility beyond the classroom.  Although our initial goals
+were somewhat vague, we knew that we wanted to create something that
+would enable students to solve realistic problems, and that they could
+use for many things other than chemical reactor design problems.
+
+There are those who would say that we should be teaching the students
+Fortran instead, because that is the computer language of engineering,
+but every time we have tried that, the students have spent far too much
+time trying to figure out why their Fortran code crashes and not enough
+time learning about chemical engineering.  With Octave, most students
+pick up the basics quickly, and are using it confidently in just a few
+hours.
+
+Although it was originally intended to be used to teach reactor design,
+it has been used in several other undergraduate and graduate
+courses in the Chemical Engineering Department at the University of
+Texas, and the math department at the University of Texas has been using
+it for teaching differential equations and linear algebra as well.  If
+you find it useful, please let us know.  We are always interested to
+find out how Octave is being used in other places.
+
+Virtually everyone thinks that the name Octave has something to do with
+music, but it is actually the name of a former professor of mine who
+wrote a famous textbook on chemical reaction engineering, and who was
+also well known for his ability to do quick `back of the envelope'
+calculations.  We hope that this software will make it possible for many
+people to do more ambitious computations just as easily.
+
+Everyone is encouraged to share this software with others under the
+terms of the GNU General Public License (@pxref{Copying}).  You are 
+also encouraged to help make Octave more useful by writing and 
+contributing additional functions for it, and by reporting any problems
+you may have.
+
+ at menu
+* Acknowledgements::            
+* How You Can Contribute to Octave::  
+* Distribution::                
+ at end menu
+
+ at node Acknowledgements
+ at unnumberedsec Acknowledgements
+ at cindex acknowledgements
+
+Many people have already contributed to Octave's development.  The
+following people have helped code parts of Octave or aided in
+various other ways (listed alphabetically).
+
+ at include contributors.texi
+
+Special thanks to the following people and organizations for
+supporting the development of Octave:
+
+ at itemize @bullet
+ at item
+The United States Department of Energy, through grant number
+DE-FG02-04ER25635.
+
+ at item
+Ashok Krishnamurthy, David Hudak, Juan Carlos Chaves, and Stanley
+C. Ahalt of the Ohio Supercomputer Center.
+
+ at item
+The National Science Foundation, through grant numbers CTS-0105360,
+CTS-9708497, CTS-9311420, CTS-8957123, and CNS-0540147.
+
+ at item
+The industrial members of the Texas-Wisconsin Modeling and Control
+Consortium (@uref{http://www.che.utexas.edu/twmcc, TWMCC}).
+
+ at item
+The Paul A. Elfers Endowed Chair in Chemical Engineering at the
+University of Wisconsin-Madison.
+
+ at item
+Digital Equipment Corporation, for an equipment grant as part of their
+External Research Program.
+
+ at item
+Sun Microsystems, Inc., for an Academic Equipment grant.
+
+ at item
+International Business Machines, Inc., for providing equipment as part
+of a grant to the University of Texas College of Engineering.
+
+ at item
+Texaco Chemical Company, for providing funding to continue the
+development of this software.
+
+ at item
+The University of Texas College of Engineering, for providing a
+Challenge for Excellence Research Supplement, and for providing an
+Academic Development Funds grant.
+
+ at item
+The State of Texas, for providing funding through the Texas
+Advanced Technology Program under Grant No. 003658-078.
+
+ at item
+Noel Bell, Senior Engineer, Texaco Chemical Company, Austin Texas.
+
+ at item
+John A. Turner, Group Leader, Continuum Dynamics (CCS-2), Los Alamos
+National Laboratory, for registering the @url{octave.org} domain name.
+
+ at item
+James B. Rawlings, Professor, University of Wisconsin-Madison,
+Department of Chemical and Biological Engineering.
+
+ at item
+Richard Stallman, for writing GNU.
+ at end itemize
+
+This project would not have been possible without the GNU software used
+in and to produce Octave.
+
+ at node How You Can Contribute to Octave
+ at unnumberedsec How You Can Contribute to Octave
+ at cindex contributing to Octave
+ at cindex funding Octave development
+
+There are a number of ways that you can contribute to help make Octave a
+better system.  Perhaps the most important way to contribute is to write
+high-quality code for solving new problems, and to make your code freely
+available for others to use.  @xref{Contributing Guidelines}, for detailed 
+information on contributing new code.
+
+If you find Octave useful, consider providing additional funding to
+continue its development.  Even a modest amount of additional funding
+could make a significant difference in the amount of time that is
+available for development and support.
+
+If you cannot provide funding or contribute code, you can still help
+make Octave better and more reliable by reporting any bugs you find and
+by offering suggestions for ways to improve Octave.  @xref{Trouble}, for
+tips on how to write useful bug reports.
+
+ at node Distribution
+ at unnumberedsec Distribution
+ at cindex distribution of Octave
+
+Octave is @dfn{free} software.  This means that everyone is free to
+use it and free to redistribute it on certain conditions.  Octave 
+is not, however, in the public domain.  It is copyrighted and there are
+restrictions on its distribution, but the restrictions are designed to 
+ensure that others will have the same freedom to use and redistribute 
+Octave that you have.  The precise conditions can be found in the 
+GNU General Public License that comes with Octave and that also appears 
+in @ref{Copying}.
+
+Octave is available on CD-ROM, with various collections of other free
+software, from the Free Software Foundation.  Ordering a copy of
+Octave from the Free Software Foundation helps to fund the development
+of more free software.  For more information, write to
+
+ at quotation
+Free Software Foundation@*
+51 Franklin Street, Fifth Floor@*
+Boston, MA 02110-1301--1307@*
+USA
+ at end quotation
+
+Octave can also be downloaded from @url{http://www.octave.org}, where
+additional information is available.
diff --git a/doc/interpreter/quad.texi b/doc/interpreter/quad.texi
new file mode 100644
index 0000000..d7ba70d
--- /dev/null
+++ b/doc/interpreter/quad.texi
@@ -0,0 +1,563 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Numerical Integration
+ at chapter Numerical Integration
+
+Octave comes with several built-in functions for computing the integral
+of a function numerically.  These functions all solve 1-dimensional
+integration problems.
+
+ at menu
+* Functions of One Variable:: 
+* Functions of Multiple Variables:: 
+* Orthogonal Collocation::      
+ at end menu
+
+ at node Functions of One Variable
+ at section Functions of One Variable
+
+Octave supports three different algorithms for computing the integral
+ at tex
+$$
+ \int_a^b f(x) d x
+$$
+ at end tex
+of a function @math{f} over the interval from @math{a} to @math{b}.
+These are
+
+ at table @code
+ at item quad
+Numerical integration based on Gaussian quadrature.
+
+ at item quadl
+Numerical integration using an adaptive Lobatto rule.
+
+ at item quadgk
+Numerical integration using an adaptive Gauss-Konrod rule.
+
+ at item quadv
+Numerical integration using an adaptive vectorized Simpson's rule.
+
+ at item trapz
+Numerical integration using the trapezoidal method.
+ at end table
+
+ at noindent
+Besides these functions Octave also allows you to perform cumulative
+numerical integration using the trapezoidal method through the
+ at code{cumtrapz} function.
+
+ at c ./DLD-FUNCTIONS/quad.cc
+ at anchor{doc-quad}
+ at deftypefn {Loadable Function} {[@var{v}, @var{ier}, @var{nfun}, @var{err}] =} quad (@var{f}, @var{a}, @var{b}, @var{tol}, @var{sing})
+Integrate a nonlinear function of one variable using Quadpack.
+The first argument is the name of the function, the function handle or
+the inline function to call to compute the value of the integrand.  It
+must have the form
+
+ at example
+y = f (x)
+ at end example
+
+ at noindent
+where @var{y} and @var{x} are scalars.
+
+The second and third arguments are limits of integration.  Either or
+both may be infinite.
+
+The optional argument @var{tol} is a vector that specifies the desired
+accuracy of the result.  The first element of the vector is the desired
+absolute tolerance, and the second element is the desired relative
+tolerance.  To choose a relative test only, set the absolute
+tolerance to zero.  To choose an absolute test only, set the relative
+tolerance to zero.  
+
+The optional argument @var{sing} is a vector of values at which the
+integrand is known to be singular.
+
+The result of the integration is returned in @var{v} and @var{ier}
+contains an integer error code (0 indicates a successful integration).
+The value of @var{nfun} indicates how many function evaluations were
+required, and @var{err} contains an estimate of the error in the
+solution.
+
+You can use the function @code{quad_options} to set optional
+parameters for @code{quad}.
+
+It should be noted that since @code{quad} is written in Fortran it
+cannot be called recursively.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/quad.cc
+ at anchor{doc-quad_options}
+ at deftypefn {Loadable Function} {} quad_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{quad}.
+Given one argument, @code{quad_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance; may be zero for pure relative error test.
+ at item "relative tolerance"
+Nonnegative relative tolerance.  If the absolute tolerance is zero,
+the relative tolerance must be greater than or equal to 
+ at code{max (50*eps, 0.5e-28)}.
+ at item "single precision absolute tolerance"
+Absolute tolerance for single precision; may be zero for pure relative 
+error test.
+ at item "single precision relative tolerance"
+Nonnegative relative tolerance for single precision.  If the absolute
+tolerance is zero, the relative tolerance must be greater than or equal to 
+ at code{max (50*eps, 0.5e-28)}.
+ at end table
+ at end deftypefn
+
+
+Here is an example of using @code{quad} to integrate the function
+ at tex
+$$
+ f(x) = x \sin (1/x) \sqrt {|1 - x|}
+$$
+from $x = 0$ to $x = 3$.
+ at end tex
+ at ifnottex
+
+ at example
+  @var{f}(@var{x}) = @var{x} * sin (1/@var{x}) * sqrt (abs (1 - @var{x}))
+ at end example
+
+ at noindent
+from @var{x} = 0 to @var{x} = 3.
+ at end ifnottex
+
+This is a fairly difficult integration (plot the function over the range
+of integration to see why).
+
+The first step is to define the function:
+
+ at example
+ at group
+function y = f (x)
+  y = x .* sin (1 ./ x) .* sqrt (abs (1 - x));
+endfunction
+ at end group
+ at end example
+
+Note the use of the `dot' forms of the operators.  This is not necessary
+for the call to @code{quad}, but it makes it much easier to generate a
+set of points for plotting (because it makes it possible to call the
+function with a vector argument to produce a vector result).
+
+Then we simply call quad:
+
+ at example
+ at group
+[v, ier, nfun, err] = quad ("f", 0, 3)
+     @result{} 1.9819
+     @result{} 1
+     @result{} 5061
+     @result{} 1.1522e-07
+ at end group
+ at end example
+
+Although @code{quad} returns a nonzero value for @var{ier}, the result
+is reasonably accurate (to see why, examine what happens to the result
+if you move the lower bound to 0.1, then 0.01, then 0.001, etc.).
+
+ at c ./general/quadl.m
+ at anchor{doc-quadl}
+ at deftypefn {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace}, @var{p1}, @var{p2}, @dots{})
+
+Numerically evaluate integral using adaptive Lobatto rule.
+ at code{quadl (@var{f}, @var{a}, @var{b})} approximates the integral of
+ at code{@var{f}(@var{x})} to machine precision.  @var{f} is either a
+function handle, inline function or string containing the name of
+the function to evaluate.  The function @var{f} must return a vector
+of output values if given a vector of input values.
+
+If defined, @var{tol} defines the relative tolerance to which to
+which to integrate @code{@var{f}(@var{x})}.  While if @var{trace} is
+defined, displays the left end point of the current interval, the 
+interval length, and the partial integral.
+
+Additional arguments @var{p1}, etc., are passed directly to @var{f}.
+To use default values for @var{tol} and @var{trace}, one may pass
+empty matrices.
+
+Reference: W. Gander and W. Gautschi, 'Adaptive Quadrature - 
+Revisited', BIT Vol. 40, No. 1, March 2000, pp. 84--101.
+ at url{http://www.inf.ethz.ch/personal/gander/}
+
+ at end deftypefn
+
+
+ at c ./general/quadgk.m
+ at anchor{doc-quadgk}
+ at deftypefn {Function File} {} quadgk (@var{f}, @var{a}, @var{b}, @var{abstol}, @var{trace})
+ at deftypefnx {Function File} {} quadgk (@var{f}, @var{a}, @var{b}, @var{prop}, @var{val}, @dots{})
+ at deftypefnx {Function File} {[@var{q}, @var{err}] =} quadgk (@dots{})
+Numerically evaluate integral using adaptive Gauss-Konrod quadrature.
+The formulation is based on a proposal by L.F. Shampine,
+ at cite{"Vectorized adaptive quadrature in @sc{matlab}", Journal of
+Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2,
+Feb 2008} where all function evaluations at an iteration are
+calculated with a single call to @var{f}.  Therefore the function
+ at var{f} must be of the form @code{@var{f} (@var{x})} and accept
+vector values of @var{x} and return a vector of the same length
+representing the function evaluations at the given values of @var{x}.
+The function @var{f} can be defined in terms of a function handle,
+inline function or string.
+
+The bounds of the quadrature @code{[@var{a}, @var{b}]} can be finite
+or infinite and contain weak end singularities.  Variable
+transformation will be used to treat infinite intervals and weaken
+the singularities.  For example
+
+ at example
+quadgk(@@(x) 1 ./ (sqrt (x) .* (x + 1)), 0, Inf)
+ at end example
+
+ at noindent
+Note that the formulation of the integrand uses the
+element-by-element operator @code{./} and all user functions to
+ at code{quadgk} should do the same.
+
+The absolute tolerance can be passed as a fourth argument in a manner
+compatible with @code{quadv}.  Equally the user can request that
+information on the convergence can be printed is the fifth argument
+is logically true.
+
+Alternatively, certain properties of @code{quadgk} can be passed as
+pairs @code{@var{prop}, @var{val}}.  Valid properties are
+
+ at table @code
+ at item AbsTol
+Defines the absolute error tolerance for the quadrature.  The default
+absolute tolerance is 1e-10.
+
+ at item RelTol
+Defines the relative error tolerance for the quadrature.  The default
+relative tolerance is 1e-5.
+
+ at item MaxIntervalCount
+ at code{quadgk} initially subdivides the interval on which to perform
+the quadrature into 10 intervals.  Sub-intervals that have an
+unacceptable error are sub-divided and re-evaluated.  If the number of
+sub-intervals exceeds at any point 650 sub-intervals then a poor
+convergence is signaled and the current estimate of the integral is
+returned.  The property 'MaxIntervalCount' can be used to alter the
+number of sub-intervals that can exist before exiting.
+
+ at item WayPoints
+If there exists discontinuities in the first derivative of the
+function to integrate, then these can be flagged with the
+ at code{"WayPoints"} property.  This forces the ends of a sub-interval
+to fall on the breakpoints of the function and can result in
+significantly improved estimation of the error in the integral, faster
+computation or both.  For example,
+
+ at example
+quadgk (@@(x) abs (1 - x .^ 2), 0, 2, 'Waypoints', 1)
+ at end example
+
+ at noindent
+signals the breakpoint in the integrand at @code{@var{x} = 1}.
+
+ at item Trace
+If logically true, then @code{quadgk} prints information on the
+convergence of the quadrature at each iteration.
+ at end table
+
+If any of @var{a}, @var{b} or @var{waypoints} is complex, then the
+quadrature is treated as a contour integral along a piecewise
+continuous path defined by the above.  In this case the integral is
+assumed to have no edge singularities.  For example
+
+ at example
+ at group
+quadgk (@@(z) log (z), 1+1i, 1+1i, "WayPoints",
+        [1-1i, -1,-1i, -1+1i])
+ at end group
+ at end example
+
+ at noindent
+integrates @code{log (z)} along the square defined by @code{[1+1i,
+ 1-1i, -1-1i, -1+1i]}
+
+If two output arguments are requested, then @var{err} returns the
+approximate bounds on the error in the integral @code{abs (@var{q} -
+ at var{i})}, where @var{i} is the exact value of the integral.
+
+ at seealso{@ref{doc-triplequad,,triplequad}, @ref{doc-dblquad,,dblquad}, @ref{doc-quad,,quad}, @ref{doc-quadl,,quadl}, @ref{doc-quadv,,quadv}, @ref{doc-trapz,,trapz}}
+ at end deftypefn
+
+
+ at c ./general/quadv.m
+ at anchor{doc-quadv}
+ at deftypefn {Function File} {@var{q} =} quadv (@var{f}, @var{a}, @var{b})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace}, @var{p1}, @var{p2}, @dots{})
+ at deftypefnx {Function File} {[@var{q}, @var{fcnt}] =} quadl (@dots{})
+
+Numerically evaluate integral using adaptive Simpson's rule.
+ at code{quadv (@var{f}, @var{a}, @var{b})} approximates the integral of
+ at code{@var{f}(@var{x})} to the default absolute tolerance of @code{1e-6}. 
+ at var{f} is either a function handle, inline function or string
+containing the name of the function to evaluate.  The function @var{f}
+must accept a string, and can return a vector representing the
+approximation to @var{n} different sub-functions.
+
+If defined, @var{tol} defines the absolute tolerance to which to
+which to integrate each sub-interval of @code{@var{f}(@var{x})}.
+While if @var{trace} is defined, displays the left end point of the
+current interval, the interval length, and the partial integral.
+
+Additional arguments @var{p1}, etc., are passed directly to @var{f}.
+To use default values for @var{tol} and @var{trace}, one may pass
+empty matrices.
+ at seealso{@ref{doc-triplequad,,triplequad}, @ref{doc-dblquad,,dblquad}, @ref{doc-quad,,quad}, @ref{doc-quadl,,quadl}, @ref{doc-quadgk,,quadgk}, @ref{doc-trapz,,trapz}}
+ at end deftypefn
+
+
+ at c ./general/trapz.m
+ at anchor{doc-trapz}
+ at deftypefn {Function File} {@var{z} =} trapz (@var{y})
+ at deftypefnx {Function File} {@var{z} =} trapz (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{z} =} trapz (@dots{}, @var{dim})
+
+Numerical integration using trapezoidal method.  @code{trapz
+(@var{y})} computes the integral of the @var{y} along the first
+non-singleton dimension.  If the argument @var{x} is omitted a 
+equally spaced vector is assumed.  @code{trapz (@var{x}, @var{y})} 
+evaluates the integral with respect to @var{x}.
+ 
+ at seealso{@ref{doc-cumtrapz,,cumtrapz}}
+ at end deftypefn
+
+
+ at c ./general/cumtrapz.m
+ at anchor{doc-cumtrapz}
+ at deftypefn {Function File} {@var{z} =} cumtrapz (@var{y})
+ at deftypefnx {Function File} {@var{z} =} cumtrapz (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{z} =} cumtrapz (@dots{}, @var{dim})
+
+Cumulative numerical integration using trapezoidal method.
+ at code{cumtrapz (@var{y})} computes the cumulative integral of the 
+ at var{y} along the first non-singleton dimension.  If the argument 
+ at var{x} is omitted a equally spaced vector is assumed.  @code{cumtrapz 
+(@var{x}, @var{y})} evaluates the cumulative integral with respect 
+to @var{x}.
+ 
+ at seealso{@ref{doc-trapz,,trapz}, @ref{doc-cumsum,,cumsum}}
+ at end deftypefn
+
+
+ at node Orthogonal Collocation
+ at section Orthogonal Collocation
+
+ at c ./DLD-FUNCTIONS/colloc.cc
+ at anchor{doc-colloc}
+ at deftypefn {Loadable Function} {[@var{r}, @var{amat}, @var{bmat}, @var{q}] =} colloc (@var{n}, "left", "right")
+Compute derivative and integral weight matrices for orthogonal
+collocation using the subroutines given in J. Villadsen and
+M. L. Michelsen, @cite{Solution of Differential Equation Models by
+Polynomial Approximation}.
+ at end deftypefn
+
+
+Here is an example of using @code{colloc} to generate weight matrices
+for solving the second order differential equation
+ at tex
+$u^\prime - \alpha u^{\prime\prime} = 0$ with the boundary conditions
+$u(0) = 0$ and $u(1) = 1$.
+ at end tex
+ at ifnottex
+ at var{u}' - @var{alpha} * @var{u}'' = 0 with the boundary conditions
+ at var{u}(0) = 0 and @var{u}(1) = 1.
+ at end ifnottex
+
+First, we can generate the weight matrices for @var{n} points (including
+the endpoints of the interval), and incorporate the boundary conditions
+in the right hand side (for a specific value of
+ at tex
+$\alpha$).
+ at end tex
+ at ifnottex
+ at var{alpha}).
+ at end ifnottex
+
+ at example
+ at group
+n = 7;
+alpha = 0.1;
+[r, a, b] = colloc (n-2, "left", "right");
+at = a(2:n-1,2:n-1);
+bt = b(2:n-1,2:n-1);
+rhs = alpha * b(2:n-1,n) - a(2:n-1,n);
+ at end group
+ at end example
+
+Then the solution at the roots @var{r} is
+
+ at example
+ at group
+u = [ 0; (at - alpha * bt) \ rhs; 1]
+     @result{} [ 0.00; 0.004; 0.01 0.00; 0.12; 0.62; 1.00 ]
+ at end group
+ at end example
+
+ at node Functions of Multiple Variables
+ at section Functions of Multiple Variables
+
+Octave does not have built-in functions for computing the integral of
+functions of multiple variables directly.  It is however possible to
+compute the integral of a function of multiple variables using the
+functions for one-dimensional integrals.
+
+To illustrate how the integration can be performed, we will integrate
+the function
+ at tex
+$$
+  f(x, y) = \sin(\pi x y)\sqrt{x y}
+$$
+ at end tex
+ at ifnottex
+ at example
+f(x, y) = sin(pi*x*y)*sqrt(x*y)
+ at end example
+ at end ifnottex
+for @math{x} and @math{y} between 0 and 1.
+
+The first approach creates a function that integrates @math{f} with
+respect to @math{x}, and then integrates that function with respect to
+ at math{y}.  Since @code{quad} is written in Fortran it cannot be called
+recursively.  This means that @code{quad} cannot integrate a function
+that calls @code{quad}, and hence cannot be used to perform the double
+integration.  It is however possible with @code{quadl}, which is what
+the following code does.
+
+ at example
+ at group
+function I = g(y)
+  I = ones(1, length(y));
+  for i = 1:length(y)
+    f = @@(x) sin(pi.*x.*y(i)).*sqrt(x.*y(i));
+    I(i) = quadl(f, 0, 1);
+  endfor
+endfunction
+
+I = quadl("g", 0, 1)
+      @result{} 0.30022
+ at end group
+ at end example
+
+The above process can be simplified with the @code{dblquad} and
+ at code{triplequad} functions for integrals over two and three
+variables.  For example
+
+ at example
+ at group
+I =  dblquad (@@(x, y) sin(pi.*x.*y).*sqrt(x.*y), 0, 1, 0, 1)
+      @result{} 0.30022
+ at end group
+ at end example
+
+ at c ./general/dblquad.m
+ at anchor{doc-dblquad}
+ at deftypefn {Function File} {} dblquad (@var{f}, @var{xa}, @var{xb}, @var{ya}, @var{yb}, @var{tol}, @var{quadf}, @dots{})
+Numerically evaluate a double integral.  The function over with to
+integrate is defined by @code{@var{f}}, and the interval for the
+integration is defined by @code{[@var{xa}, @var{xb}, @var{ya},
+ at var{yb}]}.  The function @var{f} must accept a vector @var{x} and a
+scalar @var{y}, and return a vector of the same length as @var{x}. 
+
+If defined, @var{tol} defines the absolute tolerance to which to
+which to integrate each sub-integral.
+
+Additional arguments, are passed directly to @var{f}.  To use the default
+value for @var{tol} one may pass an empty matrix.
+ at seealso{@ref{doc-triplequad,,triplequad}, @ref{doc-quad,,quad}, @ref{doc-quadv,,quadv}, @ref{doc-quadl,,quadl}, @ref{doc-quadgk,,quadgk}, @ref{doc-trapz,,trapz}}
+ at end deftypefn
+
+
+ at c ./general/triplequad.m
+ at anchor{doc-triplequad}
+ at deftypefn {Function File} {} triplequad (@var{f}, @var{xa}, @var{xb}, @var{ya}, @var{yb}, @var{za}, @var{zb}, @var{tol}, @var{quadf}, @dots{})
+Numerically evaluate a triple integral.  The function over which to
+integrate is defined by @code{@var{f}}, and the interval for the
+integration is defined by @code{[@var{xa}, @var{xb}, @var{ya},
+ at var{yb}, @var{za}, @var{zb}]}.  The function @var{f} must accept a
+vector @var{x} and a scalar @var{y}, and return a vector of the same
+length as @var{x}.
+
+If defined, @var{tol} defines the absolute tolerance to which to
+which to integrate each sub-integral.
+
+Additional arguments, are passed directly to @var{f}.  To use the default
+value for @var{tol} one may pass an empty matrix.
+ at seealso{@ref{doc-dblquad,,dblquad}, @ref{doc-quad,,quad}, @ref{doc-quadv,,quadv}, @ref{doc-quadl,,quadl}, @ref{doc-quadgk,,quadgk}, @ref{doc-trapz,,trapz}}
+ at end deftypefn
+
+
+The above mentioned approach works but is fairly slow, and that problem
+increases exponentially with the dimensionality the problem.  Another
+possible solution is to use Orthogonal Collocation as described in the
+previous section.  The integral of a function @math{f(x,y)} for
+ at math{x} and @math{y} between 0 and 1 can be approximated using @math{n}
+points by
+ at tex
+$$
+ \int_0^1 \int_0^1 f(x,y) d x d y \approx \sum_{i=1}^n \sum_{j=1}^n q_i q_j f(r_i, r_j),
+$$
+ at end tex
+ at ifnottex
+the sum over @code{i=1:n} and @code{j=1:n} of @code{q(i)*q(j)*f(r(i),r(j))},
+ at end ifnottex
+where @math{q} and @math{r} is as returned by @code{colloc(n)}.  The
+generalization to more than two variables is straight forward.  The
+following code computes the studied integral using @math{n=7} points.
+
+ at example
+ at group
+f = @@(x,y) sin(pi*x*y').*sqrt(x*y');
+n = 7;
+[t, A, B, q] = colloc(n);
+I = q'*f(t,t)*q;
+      @result{} 0.30022
+ at end group
+ at end example
+
+ at noindent
+It should be noted that the number of points determines the quality
+of the approximation.  If the integration needs to be performed between
+ at math{a} and @math{b} instead of 0 and 1, a change of variables is needed.
+
+
+
diff --git a/doc/interpreter/quad.txi b/doc/interpreter/quad.txi
new file mode 100644
index 0000000..420acef
--- /dev/null
+++ b/doc/interpreter/quad.txi
@@ -0,0 +1,271 @@
+ at c Copyright (C) 1996, 1997, 1999, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Numerical Integration
+ at chapter Numerical Integration
+
+Octave comes with several built-in functions for computing the integral
+of a function numerically.  These functions all solve 1-dimensional
+integration problems.
+
+ at menu
+* Functions of One Variable:: 
+* Functions of Multiple Variables:: 
+* Orthogonal Collocation::      
+ at end menu
+
+ at node Functions of One Variable
+ at section Functions of One Variable
+
+Octave supports three different algorithms for computing the integral
+ at tex
+$$
+ \int_a^b f(x) d x
+$$
+ at end tex
+of a function @math{f} over the interval from @math{a} to @math{b}.
+These are
+
+ at table @code
+ at item quad
+Numerical integration based on Gaussian quadrature.
+
+ at item quadl
+Numerical integration using an adaptive Lobatto rule.
+
+ at item quadgk
+Numerical integration using an adaptive Gauss-Konrod rule.
+
+ at item quadv
+Numerical integration using an adaptive vectorized Simpson's rule.
+
+ at item trapz
+Numerical integration using the trapezoidal method.
+ at end table
+
+ at noindent
+Besides these functions Octave also allows you to perform cumulative
+numerical integration using the trapezoidal method through the
+ at code{cumtrapz} function.
+
+ at DOCSTRING(quad)
+
+ at DOCSTRING(quad_options)
+
+Here is an example of using @code{quad} to integrate the function
+ at tex
+$$
+ f(x) = x \sin (1/x) \sqrt {|1 - x|}
+$$
+from $x = 0$ to $x = 3$.
+ at end tex
+ at ifnottex
+
+ at example
+  @var{f}(@var{x}) = @var{x} * sin (1/@var{x}) * sqrt (abs (1 - @var{x}))
+ at end example
+
+ at noindent
+from @var{x} = 0 to @var{x} = 3.
+ at end ifnottex
+
+This is a fairly difficult integration (plot the function over the range
+of integration to see why).
+
+The first step is to define the function:
+
+ at example
+ at group
+function y = f (x)
+  y = x .* sin (1 ./ x) .* sqrt (abs (1 - x));
+endfunction
+ at end group
+ at end example
+
+Note the use of the `dot' forms of the operators.  This is not necessary
+for the call to @code{quad}, but it makes it much easier to generate a
+set of points for plotting (because it makes it possible to call the
+function with a vector argument to produce a vector result).
+
+Then we simply call quad:
+
+ at example
+ at group
+[v, ier, nfun, err] = quad ("f", 0, 3)
+     @result{} 1.9819
+     @result{} 1
+     @result{} 5061
+     @result{} 1.1522e-07
+ at end group
+ at end example
+
+Although @code{quad} returns a nonzero value for @var{ier}, the result
+is reasonably accurate (to see why, examine what happens to the result
+if you move the lower bound to 0.1, then 0.01, then 0.001, etc.).
+
+ at DOCSTRING(quadl)
+
+ at DOCSTRING(quadgk)
+
+ at DOCSTRING(quadv)
+
+ at DOCSTRING(trapz)
+
+ at DOCSTRING(cumtrapz)
+
+ at node Orthogonal Collocation
+ at section Orthogonal Collocation
+
+ at DOCSTRING(colloc)
+
+Here is an example of using @code{colloc} to generate weight matrices
+for solving the second order differential equation
+ at tex
+$u^\prime - \alpha u^{\prime\prime} = 0$ with the boundary conditions
+$u(0) = 0$ and $u(1) = 1$.
+ at end tex
+ at ifnottex
+ at var{u}' - @var{alpha} * @var{u}'' = 0 with the boundary conditions
+ at var{u}(0) = 0 and @var{u}(1) = 1.
+ at end ifnottex
+
+First, we can generate the weight matrices for @var{n} points (including
+the endpoints of the interval), and incorporate the boundary conditions
+in the right hand side (for a specific value of
+ at tex
+$\alpha$).
+ at end tex
+ at ifnottex
+ at var{alpha}).
+ at end ifnottex
+
+ at example
+ at group
+n = 7;
+alpha = 0.1;
+[r, a, b] = colloc (n-2, "left", "right");
+at = a(2:n-1,2:n-1);
+bt = b(2:n-1,2:n-1);
+rhs = alpha * b(2:n-1,n) - a(2:n-1,n);
+ at end group
+ at end example
+
+Then the solution at the roots @var{r} is
+
+ at example
+ at group
+u = [ 0; (at - alpha * bt) \ rhs; 1]
+     @result{} [ 0.00; 0.004; 0.01 0.00; 0.12; 0.62; 1.00 ]
+ at end group
+ at end example
+
+ at node Functions of Multiple Variables
+ at section Functions of Multiple Variables
+
+Octave does not have built-in functions for computing the integral of
+functions of multiple variables directly.  It is however possible to
+compute the integral of a function of multiple variables using the
+functions for one-dimensional integrals.
+
+To illustrate how the integration can be performed, we will integrate
+the function
+ at tex
+$$
+  f(x, y) = \sin(\pi x y)\sqrt{x y}
+$$
+ at end tex
+ at ifnottex
+ at example
+f(x, y) = sin(pi*x*y)*sqrt(x*y)
+ at end example
+ at end ifnottex
+for @math{x} and @math{y} between 0 and 1.
+
+The first approach creates a function that integrates @math{f} with
+respect to @math{x}, and then integrates that function with respect to
+ at math{y}.  Since @code{quad} is written in Fortran it cannot be called
+recursively.  This means that @code{quad} cannot integrate a function
+that calls @code{quad}, and hence cannot be used to perform the double
+integration.  It is however possible with @code{quadl}, which is what
+the following code does.
+
+ at example
+ at group
+function I = g(y)
+  I = ones(1, length(y));
+  for i = 1:length(y)
+    f = @@(x) sin(pi.*x.*y(i)).*sqrt(x.*y(i));
+    I(i) = quadl(f, 0, 1);
+  endfor
+endfunction
+
+I = quadl("g", 0, 1)
+      @result{} 0.30022
+ at end group
+ at end example
+
+The above process can be simplified with the @code{dblquad} and
+ at code{triplequad} functions for integrals over two and three
+variables.  For example
+
+ at example
+ at group
+I =  dblquad (@@(x, y) sin(pi.*x.*y).*sqrt(x.*y), 0, 1, 0, 1)
+      @result{} 0.30022
+ at end group
+ at end example
+
+ at DOCSTRING(dblquad)
+
+ at DOCSTRING(triplequad)
+
+The above mentioned approach works but is fairly slow, and that problem
+increases exponentially with the dimensionality the problem.  Another
+possible solution is to use Orthogonal Collocation as described in the
+previous section.  The integral of a function @math{f(x,y)} for
+ at math{x} and @math{y} between 0 and 1 can be approximated using @math{n}
+points by
+ at tex
+$$
+ \int_0^1 \int_0^1 f(x,y) d x d y \approx \sum_{i=1}^n \sum_{j=1}^n q_i q_j f(r_i, r_j),
+$$
+ at end tex
+ at ifnottex
+the sum over @code{i=1:n} and @code{j=1:n} of @code{q(i)*q(j)*f(r(i),r(j))},
+ at end ifnottex
+where @math{q} and @math{r} is as returned by @code{colloc(n)}.  The
+generalization to more than two variables is straight forward.  The
+following code computes the studied integral using @math{n=7} points.
+
+ at example
+ at group
+f = @@(x,y) sin(pi*x*y').*sqrt(x*y');
+n = 7;
+[t, A, B, q] = colloc(n);
+I = q'*f(t,t)*q;
+      @result{} 0.30022
+ at end group
+ at end example
+
+ at noindent
+It should be noted that the number of points determines the quality
+of the approximation.  If the integration needs to be performed between
+ at math{a} and @math{b} instead of 0 and 1, a change of variables is needed.
+
+
+
diff --git a/doc/interpreter/set.texi b/doc/interpreter/set.texi
new file mode 100644
index 0000000..9257d22
--- /dev/null
+++ b/doc/interpreter/set.texi
@@ -0,0 +1,224 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Sets
+ at chapter Sets
+
+Octave has a limited number of functions for managing sets of data, where a
+set is defined as a collection of unique elements.  In Octave a set is
+represented as a vector of numbers.
+
+ at c ./set/unique.m
+ at anchor{doc-unique}
+ at deftypefn {Function File} {} unique (@var{x})
+ at deftypefnx {Function File} {} unique (@var{x}, "rows")
+ at deftypefnx {Function File} {} unique (@dots{}, "first")
+ at deftypefnx {Function File} {} unique (@dots{}, "last")
+ at deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{})
+Return the unique elements of @var{x}, sorted in ascending order.
+If @var{x} is a row vector, return a row vector, but if @var{x}
+is a column vector or a matrix return a column vector.
+
+If the optional argument @code{"rows"} is supplied, return the unique
+rows of @var{x}, sorted in ascending order.
+
+If requested, return index vectors @var{i} and @var{j} such that
+ at code{x(i)==y} and @code{y(j)==x}.
+
+Additionally, one of @code{"first"} or @code{"last"} may be given as
+an argument.  If @code{"last"} is specified, return the highest
+possible indices in @var{i}, otherwise, if @code{"first"} is
+specified, return the lowest.  The default is @code{"last"}.
+ at seealso{@ref{doc-union,,union}, @ref{doc-intersect,,intersect}, @ref{doc-setdiff,,setdiff}, @ref{doc-setxor,,setxor}, @ref{doc-ismember,,ismember}}
+ at end deftypefn
+
+
+ at menu
+* Set Operations::
+ at end menu
+
+ at node Set Operations
+ at section Set Operations
+
+Octave supports the basic set operations.  That is, Octave can compute
+the union, intersection, complement, and difference of two sets.
+Octave also supports the @emph{Exclusive Or} set operation, and
+membership determination.  The functions for set operations all work in
+pretty much the same way.  As an example, assume that @code{x} and
+ at code{y} contains two sets, then
+
+ at example
+union(x, y)
+ at end example
+
+ at noindent
+computes the union of the two sets.
+
+ at c ./set/ismember.m
+ at anchor{doc-ismember}
+ at deftypefn  {Function File} {[@var{tf} =} ismember (@var{A}, @var{S}) 
+ at deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{S}) 
+ at deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{S}, "rows")
+Return a matrix @var{tf} with the same shape as @var{A} which has a 1 if 
+ at code{A(i,j)} is in @var{S} and 0 if it is not.  If a second output argument 
+is requested, the index into @var{S} of each of the matching elements is
+also returned. 
+
+ at example
+ at group
+a = [3, 10, 1];
+s = [0:9];
+[tf, s_idx] = ismember (a, s);
+     @result{} tf = [1, 0, 1]
+     @result{} s_idx = [4, 0, 2]
+ at end group
+ at end example
+
+The inputs, @var{A} and @var{S}, may also be cell arrays.
+
+ at example
+ at group
+a = @{'abc'@};
+s = @{'abc', 'def'@};
+[tf, s_idx] = ismember (a, s);
+     @result{} tf = [1, 0]
+     @result{} s_idx = [1, 0]
+ at end group
+ at end example
+
+With the optional third argument @code{"rows"}, and matrices 
+ at var{A} and @var{S} with the same number of columns, compare rows in
+ at var{A} with the rows in @var{S}.
+
+ at example
+ at group
+a = [1:3; 5:7; 4:6];
+s = [0:2; 1:3; 2:4; 3:5; 4:6];
+[tf, s_idx] = ismember(a, s, 'rows');
+     @result{} tf = logical ([1; 0; 1])
+     @result{} s_idx = [2; 0; 5];
+ at end group
+ at end example
+
+ at seealso{@ref{doc-unique,,unique}, @ref{doc-union,,union}, @ref{doc-intersect,,intersect}, @ref{doc-setxor,,setxor}, @ref{doc-setdiff,,setdiff}}
+ at end deftypefn
+
+
+ at c ./set/union.m
+ at anchor{doc-union}
+ at deftypefn {Function File} {} union (@var{a}, @var{b})
+ at deftypefnx{Function File} {} union (@var{a}, @var{b}, "rows")
+Return the set of elements that are in either of the sets @var{a} and
+ at var{b}.  For example,
+
+ at example
+ at group
+union ([1, 2, 4], [2, 3, 5])
+     @result{} [1, 2, 3, 4, 5]
+ at end group
+ at end example
+
+If the optional third input argument is the string "rows" each row of
+the matrices @var{a} and @var{b} will be considered an element of sets.
+For example,
+ at example
+ at group
+union([1, 2; 2, 3], [1, 2; 3, 4], "rows")
+     @result{}  1   2
+    2   3
+    3   4
+ at end group
+ at end example
+
+ at deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@var{a}, @var{b})
+
+Return index vectors @var{ia} and @var{ib} such that @code{a == c(ia)} and
+ at code{b == c(ib)}.
+
+ at seealso{@ref{doc-intersect,,intersect}, @ref{doc-complement,,complement}, @ref{doc-unique,,unique}}
+ at end deftypefn
+
+
+ at c ./set/intersect.m
+ at anchor{doc-intersect}
+ at deftypefn {Function File} {} intersect (@var{a}, @var{b})
+ at deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@var{a}, @var{b})
+
+Return the elements in both @var{a} and @var{b}, sorted in ascending
+order.  If @var{a} and @var{b} are both column vectors return a column
+vector, otherwise return a row vector.
+
+Return index vectors @var{ia} and @var{ib} such that @code{a(ia)==c} and
+ at code{b(ib)==c}.
+
+ at end deftypefn
+ at seealso{@ref{doc-unique,,unique}, @ref{doc-union,,union}, @ref{doc-setxor,,setxor}, @ref{doc-setdiff,,setdiff}, @ref{doc-ismember,,ismember}}
+
+
+ at c ./set/complement.m
+ at anchor{doc-complement}
+ at deftypefn {Function File} {} complement (@var{x}, @var{y})
+Return the elements of set @var{y} that are not in set @var{x}.  For
+example,
+
+ at example
+ at group
+complement ([ 1, 2, 3 ], [ 2, 3, 5 ])
+     @result{} 5
+ at end group
+ at end example
+ at seealso{@ref{doc-union,,union}, @ref{doc-intersect,,intersect}, @ref{doc-unique,,unique}}
+ at end deftypefn
+
+
+ at c ./set/setdiff.m
+ at anchor{doc-setdiff}
+ at deftypefn {Function File} {} setdiff (@var{a}, @var{b})
+ at deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows")
+ at deftypefnx {Function File} {[@var{c}, @var{i}] =} setdiff (@var{a}, @var{b})
+Return the elements in @var{a} that are not in @var{b}, sorted in
+ascending order.  If @var{a} and @var{b} are both column vectors
+return a column vector, otherwise return a row vector.
+
+Given the optional third argument @samp{"rows"}, return the rows in
+ at var{a} that are not in @var{b}, sorted in ascending order by rows.
+
+If requested, return @var{i} such that @code{c = a(i)}.
+ at seealso{@ref{doc-unique,,unique}, @ref{doc-union,,union}, @ref{doc-intersect,,intersect}, @ref{doc-setxor,,setxor}, @ref{doc-ismember,,ismember}}
+ at end deftypefn
+
+
+ at c ./set/setxor.m
+ at anchor{doc-setxor}
+ at deftypefn {Function File} {} setxor (@var{a}, @var{b})
+ at deftypefnx {Function File} {} setxor (@var{a}, @var{b}, 'rows')
+
+Return the elements exclusive to @var{a} or @var{b}, sorted in ascending
+order.  If @var{a} and @var{b} are both column vectors return a column
+vector, otherwise return a row vector.
+
+ at deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b})
+
+Return index vectors @var{ia} and @var{ib} such that @code{a == c(ia)} and
+ at code{b == c(ib)}.
+
+ at seealso{@ref{doc-unique,,unique}, @ref{doc-union,,union}, @ref{doc-intersect,,intersect}, @ref{doc-setdiff,,setdiff}, @ref{doc-ismember,,ismember}}
+ at end deftypefn
+
diff --git a/doc/interpreter/set.txi b/doc/interpreter/set.txi
new file mode 100644
index 0000000..21e7ead
--- /dev/null
+++ b/doc/interpreter/set.txi
@@ -0,0 +1,59 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Sets
+ at chapter Sets
+
+Octave has a limited number of functions for managing sets of data, where a
+set is defined as a collection of unique elements.  In Octave a set is
+represented as a vector of numbers.
+
+ at DOCSTRING(unique)
+
+ at menu
+* Set Operations::
+ at end menu
+
+ at node Set Operations
+ at section Set Operations
+
+Octave supports the basic set operations.  That is, Octave can compute
+the union, intersection, complement, and difference of two sets.
+Octave also supports the @emph{Exclusive Or} set operation, and
+membership determination.  The functions for set operations all work in
+pretty much the same way.  As an example, assume that @code{x} and
+ at code{y} contains two sets, then
+
+ at example
+union(x, y)
+ at end example
+
+ at noindent
+computes the union of the two sets.
+
+ at DOCSTRING(ismember)
+
+ at DOCSTRING(union)
+
+ at DOCSTRING(intersect)
+
+ at DOCSTRING(complement)
+
+ at DOCSTRING(setdiff)
+
+ at DOCSTRING(setxor)
diff --git a/doc/interpreter/signal.texi b/doc/interpreter/signal.texi
new file mode 100644
index 0000000..b875cf3
--- /dev/null
+++ b/doc/interpreter/signal.texi
@@ -0,0 +1,967 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2006, 2007, 2008, 2009
+ at c               John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Signal Processing
+ at chapter Signal Processing
+
+
+This chapter describes the signal processing and fast Fourier
+transform functions available in Octave.  Fast Fourier transforms are
+computed with the @sc{fftw} or @sc{fftpack} libraries depending on how
+Octave is built.
+ 
+
+
+ at c ./signal/detrend.m
+ at anchor{doc-detrend}
+ at deftypefn {Function File} {} detrend (@var{x}, @var{p})
+If @var{x} is a vector, @code{detrend (@var{x}, @var{p})} removes the
+best fit of a polynomial of order @var{p} from the data @var{x}.
+
+If @var{x} is a matrix, @code{detrend (@var{x}, @var{p})} does the same
+for each column in @var{x}.
+
+The second argument is optional.  If it is not specified, a value of 1
+is assumed.  This corresponds to removing a linear trend.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/fft.cc
+ at anchor{doc-fft}
+ at deftypefn {Loadable Function} {} fft (@var{a}, @var{n}, @var{dim})
+Compute the FFT of @var{a} using subroutines from
+ at sc{fftw}.  The FFT is calculated along the first non-singleton dimension of the
+array.  Thus if @var{a} is a matrix, @code{fft (@var{a})} computes the
+FFT for each column of @var{a}.
+
+If called with two arguments, @var{n} is expected to be an integer
+specifying the number of elements of @var{a} to use, or an empty
+matrix to specify that its value should be ignored.  If @var{n} is
+larger than the dimension along which the FFT is calculated, then
+ at var{a} is resized and padded with zeros.  Otherwise, if @var{n} is
+smaller than the dimension along which the FFT is calculated, then
+ at var{a} is truncated.
+
+If called with three arguments, @var{dim} is an integer specifying the
+dimension of the matrix along which the FFT is performed
+ at seealso{@ref{doc-ifft,,ifft}, @ref{doc-fft2,,fft2}, @ref{doc-fftn,,fftn}, @ref{doc-fftw,,fftw}}
+ at end deftypefn
+
+
+Octave uses the @sc{fftw} libraries to perform FFT computations.  When Octave
+starts up and initializes the @sc{fftw} libraries, they read a system wide
+file (on a Unix system, it is typically @file{/etc/fftw/wisdom}) that
+contains information useful to speed up FFT computations.  This
+information is called the @emph{wisdom}.  The system-wide file allows
+wisdom to be shared between all applications using the @sc{fftw} libraries.
+
+Use the @code{fftw} function to generate and save wisdom.  Using the
+utilities provided together with the @sc{fftw} libraries
+(@command{fftw-wisdom} on Unix systems), you can even add wisdom
+generated by Octave to the system-wide wisdom file.
+
+ at c ./DLD-FUNCTIONS/fftw.cc
+ at anchor{doc-fftw}
+ at deftypefn {Loadable Function} {@var{method} =} fftw ('planner')
+ at deftypefnx {Loadable Function} {} fftw ('planner', @var{method})
+ at deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom')
+ at deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom', @var{wisdom})
+
+Manage @sc{fftw} wisdom data.  Wisdom data can be used to significantly
+accelerate the calculation of the FFTs but implies an initial cost
+in its calculation.  When the @sc{fftw} libraries are initialized, they read
+a system wide wisdom file (typically in @file{/etc/fftw/wisdom}), allowing wisdom
+to be shared between applications other than Octave.  Alternatively, the
+ at code{fftw} function can be used to import wisdom.  For example
+
+ at example
+ at var{wisdom} = fftw ('dwisdom')
+ at end example
+
+will save the existing wisdom used by Octave to the string @var{wisdom}.
+This string can then be saved to a file and restored using the @code{save}
+and @code{load} commands respectively.  This existing wisdom can be reimported
+as follows
+
+ at example
+fftw ('dwisdom', @var{wisdom})
+ at end example 
+
+If @var{wisdom} is an empty matrix, then the wisdom used is cleared.
+
+During the calculation of Fourier transforms further wisdom is generated.
+The fashion in which this wisdom is generated is equally controlled by
+the @code{fftw} function.  There are five different manners in which the
+wisdom can be treated, these being
+
+ at table @asis
+ at item 'estimate'
+This specifies that no run-time measurement of the optimal means of
+calculating a particular is performed, and a simple heuristic is used
+to pick a (probably sub-optimal) plan.  The advantage of this method is
+that there is little or no overhead in the generation of the plan, which
+is appropriate for a Fourier transform that will be calculated once.
+
+ at item 'measure'
+In this case a range of algorithms to perform the transform is considered
+and the best is selected based on their execution time.
+
+ at item 'patient'
+This is like 'measure', but a wider range of algorithms is considered.
+
+ at item 'exhaustive'
+This is like 'measure', but all possible algorithms that may be used to
+treat the transform are considered.
+
+ at item 'hybrid'
+As run-time measurement of the algorithm can be expensive, this is a
+compromise where 'measure' is used for transforms up to the size of 8192
+and beyond that the 'estimate' method is used.
+ at end table
+
+The default method is 'estimate', and the method currently being used can
+be probed with
+
+ at example
+ at var{method} = fftw ('planner')
+ at end example
+
+and the method used can be set using
+
+ at example
+fftw ('planner', @var{method})
+ at end example
+
+Note that calculated wisdom will be lost when restarting Octave.  However,
+the wisdom data can be reloaded if it is saved to a file as described
+above.  Saved wisdom files should not be used on different platforms since
+they will not be efficient and the point of calculating the wisdom is lost.
+ at seealso{@ref{doc-fft,,fft}, @ref{doc-ifft,,ifft}, @ref{doc-fft2,,fft2}, @ref{doc-ifft2,,ifft2}, @ref{doc-fftn,,fftn}, @ref{doc-ifftn,,ifftn}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/fft.cc
+ at anchor{doc-ifft}
+ at deftypefn {Loadable Function} {} ifft (@var{a}, @var{n}, @var{dim})
+Compute the inverse FFT of @var{a} using subroutines from
+ at sc{fftw}.  The inverse FFT is calculated along the first non-singleton dimension
+of the array.  Thus if @var{a} is a matrix, @code{fft (@var{a})} computes
+the inverse FFT for each column of @var{a}.
+
+If called with two arguments, @var{n} is expected to be an integer
+specifying the number of elements of @var{a} to use, or an empty
+matrix to specify that its value should be ignored.  If @var{n} is
+larger than the dimension along which the inverse FFT is calculated, then
+ at var{a} is resized and padded with zeros.  Otherwise, if at var{n} is
+smaller than the dimension along which the inverse FFT is calculated,
+then @var{a} is truncated.
+
+If called with three arguments, @var{dim} is an integer specifying the
+dimension of the matrix along which the inverse FFT is performed
+ at seealso{@ref{doc-fft,,fft}, @ref{doc-ifft2,,ifft2}, @ref{doc-ifftn,,ifftn}, @ref{doc-fftw,,fftw}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/fft2.cc
+ at anchor{doc-fft2}
+ at deftypefn {Loadable Function} {} fft2 (@var{a}, @var{n}, @var{m})
+Compute the two-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional arguments @var{n} and @var{m} may be used specify the
+number of rows and columns of @var{a} to use.  If either of these is
+larger than the size of @var{a}, @var{a} is resized and padded with
+zeros.
+
+If @var{a} is a multi-dimensional matrix, each two-dimensional sub-matrix
+of @var{a} is treated separately
+ at seealso {ifft2, fft, fftn, fftw}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/fft2.cc
+ at anchor{doc-ifft2}
+ at deftypefn {Loadable Function} {} fft2 (@var{a}, @var{n}, @var{m})
+Compute the inverse two-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional arguments @var{n} and @var{m} may be used specify the
+number of rows and columns of @var{a} to use.  If either of these is
+larger than the size of @var{a}, @var{a} is resized and padded with
+zeros.
+
+If @var{a} is a multi-dimensional matrix, each two-dimensional sub-matrix
+of @var{a} is treated separately
+ at seealso {fft2, ifft, ifftn, fftw}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/fftn.cc
+ at anchor{doc-fftn}
+ at deftypefn {Loadable Function} {} fftn (@var{a}, @var{size})
+Compute the N-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional vector argument @var{size} may be used specify the
+dimensions of the array to be used.  If an element of @var{size} is
+smaller than the corresponding dimension, then the dimension is
+truncated prior to performing the FFT.  Otherwise if an element
+of @var{size} is larger than the corresponding dimension @var{a}
+is resized and padded with zeros.
+ at seealso {ifftn, fft, fft2, fftw}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/fftn.cc
+ at anchor{doc-ifftn}
+ at deftypefn {Loadable Function} {} ifftn (@var{a}, @var{size})
+Compute the inverse N-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional vector argument @var{size} may be used specify the
+dimensions of the array to be used.  If an element of @var{size} is
+smaller than the corresponding dimension, then the dimension is
+truncated prior to performing the inverse FFT.  Otherwise if an element
+of @var{size} is larger than the corresponding dimension @var{a}
+is resized and padded with zeros.
+ at seealso {fftn, ifft, ifft2, fftw}
+ at end deftypefn
+
+
+ at c ./signal/fftconv.m
+ at anchor{doc-fftconv}
+ at deftypefn {Function File} {} fftconv (@var{a}, @var{b}, @var{n})
+Return the convolution of the vectors @var{a} and @var{b}, as a vector
+with length equal to the @code{length (a) + length (b) - 1}.  If @var{a}
+and @var{b} are the coefficient vectors of two polynomials, the returned
+value is the coefficient vector of the product polynomial.
+
+The computation uses the FFT by calling the function @code{fftfilt}.  If
+the optional argument @var{n} is specified, an N-point FFT is used.
+ at end deftypefn
+
+
+ at c ./signal/fftfilt.m
+ at anchor{doc-fftfilt}
+ at deftypefn {Function File} {} fftfilt (@var{b}, @var{x}, @var{n})
+
+With two arguments, @code{fftfilt} filters @var{x} with the FIR filter
+ at var{b} using the FFT.
+
+Given the optional third argument, @var{n}, @code{fftfilt} uses the
+overlap-add method to filter @var{x} with @var{b} using an N-point FFT.
+
+If @var{x} is a matrix, filter each column of the matrix.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/filter.cc
+ at anchor{doc-filter}
+ at deftypefn {Loadable Function} {y =} filter (@var{b}, @var{a}, @var{x})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, [], @var{dim})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}, @var{dim})
+Return the solution to the following linear, time-invariant difference
+equation:
+ at iftex
+ at 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
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+   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
+ at end smallexample
+ at end ifnottex
+
+ at noindent
+where
+ at ifnottex
+ N=length(a)-1 and M=length(b)-1.
+ at end ifnottex
+ at iftex
+ at tex
+ $a \in \Re^{N-1}$, $b \in \Re^{M-1}$, and $x \in \Re^P$.
+ at end tex
+ at end iftex
+over the first non-singleton dimension of @var{x} or over @var{dim} if
+supplied.  An equivalent form of this equation is:
+ at iftex
+ at 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
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+            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
+ at end smallexample
+ at end ifnottex
+
+ at noindent
+where
+ at ifnottex
+ c = a/a(1) and d = b/a(1).
+ at end ifnottex
+ at iftex
+ at tex
+$c = a/a_1$ and $d = b/a_1$.
+ at end tex
+ at end iftex
+
+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
+ at 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.
+
+In terms of the z-transform, y is the result of passing the discrete-
+time signal x through a system characterized by the following rational
+system function:
+ at iftex
+ at tex
+$$
+H(z) = {\displaystyle\sum_{k=0}^M d_{k+1} z^{-k}
+        \over 1 + \displaystyle\sum_{k+1}^N c_{k+1} z^{-k}}
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at group
+             M
+            SUM d(k+1) z^(-k)
+            k=0
+  H(z) = ----------------------
+               N
+          1 + SUM c(k+1) z^(-k)
+              k=1
+ at end group
+ at end example
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./signal/filter2.m
+ at anchor{doc-filter2}
+ at deftypefn {Function File} {@var{y} =} filter2 (@var{b}, @var{x})
+ at deftypefnx {Function File} {@var{y} =} filter2 (@var{b}, @var{x}, @var{shape})
+Apply the 2-D FIR filter @var{b} to @var{x}.  If the argument
+ at var{shape} is specified, return an array of the desired shape.
+Possible values are: 
+
+ at table @asis
+ at item 'full'
+pad @var{x} with zeros on all sides before filtering.
+ at item 'same'
+unpadded @var{x} (default)
+ at item 'valid'
+trim @var{x} after filtering so edge effects are no included.
+ at end table
+
+Note this is just a variation on convolution, with the parameters
+reversed and @var{b} rotated 180 degrees.
+ at seealso{@ref{doc-conv2,,conv2}}
+ at end deftypefn
+
+
+ at c ./signal/freqz.m
+ at anchor{doc-freqz}
+ at deftypefn {Function File} {[@var{h}, @var{w}] =} freqz (@var{b}, @var{a}, @var{n}, "whole")
+Return the complex frequency response @var{h} of the rational IIR filter
+whose numerator and denominator coefficients are @var{b} and @var{a},
+respectively.  The response is evaluated at @var{n} angular frequencies
+between 0 and
+ at ifnottex
+ 2*pi.
+ at end ifnottex
+ at tex
+ $2\pi$.
+ at end tex
+
+ at noindent
+The output value @var{w} is a vector of the frequencies.
+
+If the fourth argument is omitted, the response is evaluated at
+frequencies between 0 and
+ at ifnottex
+ pi.
+ at end ifnottex
+ at tex
+ $\pi$.
+ at end tex
+
+If @var{n} is omitted, a value of 512 is assumed.
+
+If @var{a} is omitted, the denominator is assumed to be 1 (this
+corresponds to a simple FIR filter).
+
+For fastest computation, @var{n} should factor into a small number of
+small primes.
+
+ at deftypefnx {Function File} {@var{h} =} freqz (@var{b}, @var{a}, @var{w})
+Evaluate the response at the specific frequencies in the vector @var{w}.
+The values for @var{w} are measured in radians.
+
+ at deftypefnx {Function File} {[@dots{}] =} freqz (@dots{}, @var{Fs})
+Return frequencies in Hz instead of radians assuming a sampling rate
+ at var{Fs}.  If you are evaluating the response at specific frequencies 
+ at var{w}, those frequencies should be requested in Hz rather than radians.
+
+ at deftypefnx {Function File} {} freqz (@dots{})
+Plot the pass band, stop band and phase response of @var{h} rather
+than returning them.
+ at end deftypefn
+
+
+ at c ./signal/freqz_plot.m
+ at anchor{doc-freqz_plot}
+ at deftypefn {Function File} {} freqz_plot (@var{w}, @var{h})
+Plot the pass band, stop band and phase response of @var{h}.
+ at end deftypefn
+
+
+ at c ./signal/sinc.m
+ at anchor{doc-sinc}
+ at deftypefn {Function File} {} sinc (@var{x})
+Return
+ at tex
+$ \sin (\pi x)/(\pi x)$.
+ at end tex
+ at ifnottex
+ sin(pi*x)/(pi*x).
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./signal/unwrap.m
+ at anchor{doc-unwrap}
+ at deftypefn {Function File} {@var{b} =} unwrap (@var{a}, @var{tol}, @var{dim})
+
+Unwrap radian phases by adding multiples of 2*pi as appropriate to
+remove jumps greater than @var{tol}.  @var{tol} defaults to pi.
+
+Unwrap will unwrap along the first non-singleton dimension of
+ at var{a}, unless the optional argument @var{dim} is given, in 
+which case the data will be unwrapped along this dimension
+ at end deftypefn
+
+
+ at c FIXME -- someone needs to organize these...
+
+ at c ./signal/arch_fit.m
+ at anchor{doc-arch_fit}
+ at deftypefn {Function File} {[@var{a}, @var{b}] =} arch_fit (@var{y}, @var{x}, @var{p}, @var{iter}, @var{gamma}, @var{a0}, @var{b0})
+Fit an ARCH regression model to the time series @var{y} using the
+scoring algorithm in Engle's original ARCH paper.  The model is
+
+ at example
+ at group
+y(t) = b(1) * x(t,1) + @dots{} + b(k) * x(t,k) + e(t),
+h(t) = a(1) + a(2) * e(t-1)^2 + @dots{} + a(p+1) * e(t-p)^2
+ at end group
+ at end example
+
+ at noindent
+in which @math{e(t)} is @math{N(0, h(t))}, given a time-series vector
+ at var{y} up to time @math{t-1} and a matrix of (ordinary) regressors
+ at var{x} up to @math{t}.  The order of the regression of the residual
+variance is specified by @var{p}.
+
+If invoked as @code{arch_fit (@var{y}, @var{k}, @var{p})} with a
+positive integer @var{k}, fit an ARCH(@var{k}, @var{p}) process,
+i.e., do the above with the @math{t}-th row of @var{x} given by
+
+ at example
+[1, y(t-1), @dots{}, y(t-k)]
+ at end example
+
+Optionally, one can specify the number of iterations @var{iter}, the
+updating factor @var{gamma}, and initial values @math{a0} and
+ at math{b0} for the scoring algorithm.
+ at end deftypefn
+
+
+ at c ./signal/arch_rnd.m
+ at anchor{doc-arch_rnd}
+ at deftypefn {Function File} {} arch_rnd (@var{a}, @var{b}, @var{t})
+Simulate an ARCH sequence of length @var{t} with AR
+coefficients @var{b} and CH coefficients @var{a}.  I.e., the result
+ at math{y(t)} follows the model
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+y(t) = b(1) + b(2) * y(t-1) + @dots{} + b(lb) * y(t-lb+1) + e(t),
+ at end smallexample
+
+ at noindent
+where @math{e(t)}, given @var{y} up to time @math{t-1}, is
+ at math{N(0, h(t))}, with
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+h(t) = a(1) + a(2) * e(t-1)^2 + @dots{} + a(la) * e(t-la+1)^2
+ at end smallexample
+ at end deftypefn
+
+
+ at c ./signal/arch_test.m
+ at anchor{doc-arch_test}
+ at deftypefn {Function File} {[@var{pval}, @var{lm}] =} arch_test (@var{y}, @var{x}, @var{p})
+For a linear regression model
+
+ at example
+y = x * b + e
+ at end example
+
+ at noindent
+perform a Lagrange Multiplier (LM) test of the null hypothesis of no
+conditional heteroscedascity against the alternative of CH(@var{p}).
+
+I.e., the model is
+
+ at example
+y(t) = b(1) * x(t,1) + @dots{} + b(k) * x(t,k) + e(t),
+ at end example
+
+ at noindent
+given @var{y} up to @math{t-1} and @var{x} up to @math{t},
+ at math{e}(t) is @math{N(0, h(t))} with
+
+ at example
+h(t) = v + a(1) * e(t-1)^2 + @dots{} + a(p) * e(t-p)^2,
+ at end example
+
+ at noindent
+and the null is @math{a(1)} == @dots{} == @math{a(p)} == 0.
+
+If the second argument is a scalar integer, @math{k}, perform the same
+test in a linear autoregression model of order @math{k}, i.e., with
+
+ at example
+[1, y(t-1), @dots{}, y(t- at var{k})]
+ at end example
+
+ at noindent
+as the @math{t}-th row of @var{x}.
+
+Under the null, LM approximately has a chisquare distribution with
+ at var{p} degrees of freedom and @var{pval} is the @math{p}-value (1
+minus the CDF of this distribution at LM) of the test.
+
+If no output argument is given, the @math{p}-value is displayed.
+ at end deftypefn
+
+
+ at c ./signal/arma_rnd.m
+ at anchor{doc-arma_rnd}
+ at deftypefn {Function File} {} arma_rnd (@var{a}, @var{b}, @var{v}, @var{t}, @var{n})
+Return a simulation of the ARMA model
+
+ at example
+ at group
+x(n) = a(1) * x(n-1) + @dots{} + a(k) * x(n-k)
+     + e(n) + b(1) * e(n-1) + @dots{} + b(l) * e(n-l)
+ at end group
+ at end example
+
+ at noindent
+in which @var{k} is the length of vector @var{a}, @var{l} is the
+length of vector @var{b} and @var{e} is Gaussian white noise with
+variance @var{v}.  The function returns a vector of length @var{t}.
+
+The optional parameter @var{n} gives the number of dummy
+ at var{x}(@var{i}) used for initialization, i.e., a sequence of length
+ at var{t}+ at var{n} is generated and @var{x}(@var{n}+1:@var{t}+ at var{n})
+is returned.  If @var{n} is omitted, @var{n} = 100 is used. 
+ at end deftypefn
+
+
+ at c ./signal/autocor.m
+ at anchor{doc-autocor}
+ at deftypefn {Function File} {} autocor (@var{x}, @var{h})
+Return the autocorrelations from lag 0 to @var{h} of vector @var{x}.
+If @var{h} is omitted, all autocorrelations are computed.
+If @var{x} is a matrix, the autocorrelations of each column are
+computed.
+ at end deftypefn
+
+
+ at c ./signal/autocov.m
+ at anchor{doc-autocov}
+ at deftypefn {Function File} {} autocov (@var{x}, @var{h})
+Return the autocovariances from lag 0 to @var{h} of vector @var{x}.
+If @var{h} is omitted, all autocovariances are computed.
+If @var{x} is a matrix, the autocovariances of each column are
+computed.
+ at end deftypefn
+
+
+ at c ./signal/autoreg_matrix.m
+ at anchor{doc-autoreg_matrix}
+ at deftypefn {Function File} {} autoreg_matrix (@var{y}, @var{k})
+Given a time series (vector) @var{y}, return a matrix with ones in the
+first column and the first @var{k} lagged values of @var{y} in the
+other columns.  I.e., for @var{t} > @var{k}, @code{[1,
+ at var{y}(@var{t}-1), @dots{}, @var{y}(@var{t}- at var{k})]} is the t-th row
+of the result.  The resulting matrix may be used as a regressor matrix
+in autoregressions.
+ at end deftypefn
+
+
+ at c ./signal/bartlett.m
+ at anchor{doc-bartlett}
+ at deftypefn {Function File} {} bartlett (@var{m})
+Return the filter coefficients of a Bartlett (triangular) window of
+length @var{m}.
+
+For a definition of the Bartlett window, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+
+
+ at c ./signal/blackman.m
+ at anchor{doc-blackman}
+ at deftypefn {Function File} {} blackman (@var{m})
+Return the filter coefficients of a Blackman window of length @var{m}.
+
+For a definition of the Blackman window, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+
+
+ at c ./signal/diffpara.m
+ at anchor{doc-diffpara}
+ at deftypefn {Function File} {[@var{d}, @var{dd}] =} diffpara (@var{x}, @var{a}, @var{b})
+Return the estimator @var{d} for the differencing parameter of an
+integrated time series.
+
+The frequencies from @math{[2*pi*a/t, 2*pi*b/T]} are used for the
+estimation.  If @var{b} is omitted, the interval
+ at math{[2*pi/T, 2*pi*a/T]} is used.  If both @var{b} and @var{a} are
+omitted then @math{a = 0.5 * sqrt (T)} and @math{b = 1.5 * sqrt (T)}
+is used, where @math{T} is the sample size.  If @var{x} is a matrix,
+the differencing parameter of each column is estimated.
+
+The estimators for all frequencies in the intervals
+described above is returned in @var{dd}.  The value of @var{d} is
+simply the mean of @var{dd}.
+
+Reference: Brockwell, Peter J. & Davis, Richard A. Time Series:
+Theory and Methods Springer 1987.
+ at end deftypefn
+
+
+ at c ./signal/durbinlevinson.m
+ at anchor{doc-durbinlevinson}
+ at deftypefn {Function File} {} durbinlevinson (@var{c}, @var{oldphi}, @var{oldv})
+Perform one step of the Durbin-Levinson algorithm.
+
+The vector @var{c} specifies the autocovariances @code{[gamma_0, @dots{},
+gamma_t]} from lag 0 to @var{t}, @var{oldphi} specifies the
+coefficients based on @var{c}(@var{t}-1) and @var{oldv} specifies the
+corresponding error.
+
+If @var{oldphi} and @var{oldv} are omitted, all steps from 1 to
+ at var{t} of the algorithm are performed.
+ at end deftypefn
+
+
+ at c ./signal/fftshift.m
+ at anchor{doc-fftshift}
+ at deftypefn {Function File} {} fftshift (@var{v})
+ at deftypefnx {Function File} {} fftshift (@var{v}, @var{dim})
+Perform a shift of the vector @var{v}, for use with the @code{fft}
+and @code{ifft} functions, in order the move the frequency 0 to the
+center of the vector or matrix.
+
+If @var{v} is a vector of @math{N} elements corresponding to @math{N}
+time samples spaced of @math{Dt} each, then @code{fftshift (fft
+(@var{v}))} corresponds to frequencies
+
+ at example
+f = ((1:N) - ceil(N/2)) / N / Dt
+ at end example
+
+If @var{v} is a matrix, the same holds for rows and columns.  If 
+ at var{v} is an array, then the same holds along each dimension.
+
+The optional @var{dim} argument can be used to limit the dimension
+along which the permutation occurs.
+ at end deftypefn
+
+
+ at c ./signal/ifftshift.m
+ at anchor{doc-ifftshift}
+ at deftypefn {Function File} {} ifftshift (@var{v})
+ at deftypefnx {Function File} {} ifftshift (@var{v}, @var{dim})
+Undo the action of the @code{fftshift} function.  For even length 
+ at var{v}, @code{fftshift} is its own inverse, but odd lengths differ 
+slightly.
+ at end deftypefn
+
+
+ at c ./signal/fractdiff.m
+ at anchor{doc-fractdiff}
+ at deftypefn {Function File} {} fractdiff (@var{x}, @var{d})
+Compute the fractional differences @math{(1-L)^d x} where @math{L}
+denotes the lag-operator and @math{d} is greater than -1.
+ at end deftypefn
+
+
+ at c ./signal/hamming.m
+ at anchor{doc-hamming}
+ at deftypefn {Function File} {} hamming (@var{m})
+Return the filter coefficients of a Hamming window of length @var{m}.
+
+For a definition of the Hamming window, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+
+
+ at c ./signal/hanning.m
+ at anchor{doc-hanning}
+ at deftypefn {Function File} {} hanning (@var{m})
+Return the filter coefficients of a Hanning window of length @var{m}.
+
+For a definition of this window type, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+
+
+ at c ./signal/hurst.m
+ at anchor{doc-hurst}
+ at deftypefn {Function File} {} hurst (@var{x})
+Estimate the Hurst parameter of sample @var{x} via the rescaled range
+statistic.  If @var{x} is a matrix, the parameter is estimated for
+every single column.
+ at end deftypefn
+
+
+ at c ./polynomial/pchip.m
+ at anchor{doc-pchip}
+ at deftypefn {Function File} {@var{pp} =} pchip (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{yi} =} pchip (@var{x}, @var{y}, @var{xi})
+
+Piecewise Cubic Hermite interpolating polynomial.  Called with two
+arguments, the piece-wise polynomial @var{pp} is returned, that may
+later be used with @code{ppval} to evaluate the polynomial at
+specific points.
+
+The variable @var{x} must be a strictly monotonic vector (either
+increasing or decreasing).  While @var{y} can be either a vector or
+array.  In the case where @var{y} is a vector, it must have a length
+of @var{n}.  If @var{y} is an array, then the size of @var{y} must
+have the form
+ at tex
+$$[s_1, s_2, \cdots, s_k, n]$$
+ at end tex
+ at ifnottex
+ at code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]}
+ at end ifnottex
+The array is then reshaped internally to a matrix where the leading
+dimension is given by 
+ at tex
+$$s_1 s_2 \cdots s_k$$
+ at end tex
+ at ifnottex
+ at code{@var{s1} * @var{s2} * @dots{} * @var{sk}}
+ at end ifnottex
+and each row in this matrix is then treated separately.  Note that this
+is exactly the opposite treatment than @code{interp1} and is done
+for compatibility.
+
+Called with a third input argument, @code{pchip} evaluates the 
+piece-wise polynomial at the points @var{xi}.  There is an equivalence
+between @code{ppval (pchip (@var{x}, @var{y}), @var{xi})} and
+ at code{pchip (@var{x}, @var{y}, @var{xi})}.
+
+ at seealso{@ref{doc-spline,,spline}, @ref{doc-ppval,,ppval}, @ref{doc-mkpp,,mkpp}, @ref{doc-unmkpp,,unmkpp}}
+ at end deftypefn
+
+
+ at c ./signal/periodogram.m
+ at anchor{doc-periodogram}
+ at deftypefn {Function File} {} periodogram (@var{x})
+For a data matrix @var{x} from a sample of size @var{n}, return the
+periodogram.
+ at end deftypefn
+
+
+ at c ./signal/rectangle_lw.m
+ at anchor{doc-rectangle_lw}
+ at deftypefn {Function File} {} rectangle_lw (@var{n}, @var{b})
+Rectangular lag window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+
+
+ at c ./signal/rectangle_sw.m
+ at anchor{doc-rectangle_sw}
+ at deftypefn {Function File} {} rectangle_sw (@var{n}, @var{b})
+Rectangular spectral window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+
+
+ at c ./signal/sinetone.m
+ at anchor{doc-sinetone}
+ at deftypefn {Function File} {} sinetone (@var{freq}, @var{rate}, @var{sec}, @var{ampl})
+Return a sinetone of frequency @var{freq} with length of @var{sec}
+seconds at sampling rate @var{rate} and with amplitude @var{ampl}.
+The arguments @var{freq} and @var{ampl} may be vectors of common size.
+
+Defaults are @var{rate} = 8000, @var{sec} = 1 and @var{ampl} = 64.
+ at end deftypefn
+
+
+ at c ./signal/sinewave.m
+ at anchor{doc-sinewave}
+ at deftypefn {Function File} {} sinewave (@var{m}, @var{n}, @var{d})
+Return an @var{m}-element vector with @var{i}-th element given by
+ at code{sin (2 * pi * (@var{i}+ at var{d}-1) / @var{n})}.
+
+The default value for @var{d} is 0 and the default value for @var{n}
+is @var{m}.
+ at end deftypefn
+
+
+ at c ./signal/spectral_adf.m
+ at anchor{doc-spectral_adf}
+ at deftypefn {Function File} {} spectral_adf (@var{c}, @var{win}, @var{b})
+Return the spectral density estimator given a vector of
+autocovariances @var{c}, window name @var{win}, and bandwidth,
+ at var{b}.
+
+The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+used to search for a function called @code{@var{win}_sw}.
+
+If @var{win} is omitted, the triangle window is used.  If @var{b} is
+omitted, @code{1 / sqrt (length (@var{x}))} is used.
+ at end deftypefn
+
+
+ at c ./signal/spectral_xdf.m
+ at anchor{doc-spectral_xdf}
+ at deftypefn {Function File} {} spectral_xdf (@var{x}, @var{win}, @var{b})
+Return the spectral density estimator given a data vector @var{x},
+window name @var{win}, and bandwidth, @var{b}.
+
+The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+used to search for a function called @code{@var{win}_sw}.
+
+If @var{win} is omitted, the triangle window is used.  If @var{b} is
+omitted, @code{1 / sqrt (length (@var{x}))} is used.
+ at end deftypefn
+
+
+ at c ./signal/spencer.m
+ at anchor{doc-spencer}
+ at deftypefn {Function File} {} spencer (@var{x})
+Return Spencer's 15 point moving average of every single column of
+ at var{x}.
+ at end deftypefn
+
+
+ at c ./signal/stft.m
+ at anchor{doc-stft}
+ at deftypefn {Function File} {[@var{y}, @var{c}] =} stft (@var{x}, @var{win_size}, @var{inc}, @var{num_coef}, @var{w_type})
+Compute the short-time Fourier transform of the vector @var{x} with
+ at var{num_coef} coefficients by applying a window of @var{win_size} data
+points and an increment of @var{inc} points.
+
+Before computing the Fourier transform, one of the following windows
+is applied:
+
+ at table @asis
+ at item hanning
+w_type = 1
+ at item hamming
+w_type = 2
+ at item rectangle
+w_type = 3
+ at end table
+
+The window names can be passed as strings or by the @var{w_type} number.
+
+If not all arguments are specified, the following defaults are used:
+ at var{win_size} = 80, @var{inc} = 24, @var{num_coef} = 64, and
+ at var{w_type} = 1.
+
+ at code{@var{y} = stft (@var{x}, @dots{})} returns the absolute values
+of the Fourier coefficients according to the @var{num_coef} positive
+frequencies.
+
+ at code{[@var{y}, @var{c}] = stft (@code{x}, @dots{})} returns the
+entire STFT-matrix @var{y} and a 3-element vector @var{c} containing
+the window size, increment, and window type, which is needed by the
+synthesis function.
+ at end deftypefn
+
+
+ at c ./signal/synthesis.m
+ at anchor{doc-synthesis}
+ at deftypefn {Function File} {} synthesis (@var{y}, @var{c})
+Compute a signal from its short-time Fourier transform @var{y} and a
+3-element vector @var{c} specifying window size, increment, and
+window type.
+
+The values @var{y} and @var{c} can be derived by
+
+ at example
+[@var{y}, @var{c}] = stft (@var{x} , @dots{})
+ at end example
+ at end deftypefn
+
+
+ at c ./signal/triangle_lw.m
+ at anchor{doc-triangle_lw}
+ at deftypefn {Function File} {} triangle_lw (@var{n}, @var{b})
+Triangular lag window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+
+
+ at c ./signal/triangle_sw.m
+ at anchor{doc-triangle_sw}
+ at deftypefn {Function File} {} triangle_sw (@var{n}, @var{b})
+Triangular spectral window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+
+
+ at c ./signal/yulewalker.m
+ at anchor{doc-yulewalker}
+ at deftypefn {Function File} {[@var{a}, @var{v}] =} yulewalker (@var{c})
+Fit an AR (p)-model with Yule-Walker estimates given a vector @var{c}
+of autocovariances @code{[gamma_0, @dots{}, gamma_p]}.
+
+Returns the AR coefficients, @var{a}, and the variance of white
+noise, @var{v}.
+ at end deftypefn
+
diff --git a/doc/interpreter/signal.txi b/doc/interpreter/signal.txi
new file mode 100644
index 0000000..0ec2b48
--- /dev/null
+++ b/doc/interpreter/signal.txi
@@ -0,0 +1,137 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2006, 2007, 2008, 2009
+ at c               John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Signal Processing
+ at chapter Signal Processing
+
+
+This chapter describes the signal processing and fast Fourier
+transform functions available in Octave.  Fast Fourier transforms are
+computed with the @sc{fftw} or @sc{fftpack} libraries depending on how
+Octave is built.
+ 
+
+
+ at DOCSTRING(detrend)
+
+ at DOCSTRING(fft)
+
+Octave uses the @sc{fftw} libraries to perform FFT computations.  When Octave
+starts up and initializes the @sc{fftw} libraries, they read a system wide
+file (on a Unix system, it is typically @file{/etc/fftw/wisdom}) that
+contains information useful to speed up FFT computations.  This
+information is called the @emph{wisdom}.  The system-wide file allows
+wisdom to be shared between all applications using the @sc{fftw} libraries.
+
+Use the @code{fftw} function to generate and save wisdom.  Using the
+utilities provided together with the @sc{fftw} libraries
+(@command{fftw-wisdom} on Unix systems), you can even add wisdom
+generated by Octave to the system-wide wisdom file.
+
+ at DOCSTRING(fftw)
+
+ at DOCSTRING(ifft)
+
+ at DOCSTRING(fft2)
+
+ at DOCSTRING(ifft2)
+
+ at DOCSTRING(fftn)
+
+ at DOCSTRING(ifftn)
+
+ at DOCSTRING(fftconv)
+
+ at DOCSTRING(fftfilt)
+
+ at DOCSTRING(filter)
+
+ at DOCSTRING(filter2)
+
+ at DOCSTRING(freqz)
+
+ at DOCSTRING(freqz_plot)
+
+ at DOCSTRING(sinc)
+
+ at DOCSTRING(unwrap)
+
+ at c FIXME -- someone needs to organize these...
+
+ at DOCSTRING(arch_fit)
+
+ at DOCSTRING(arch_rnd)
+
+ at DOCSTRING(arch_test)
+
+ at DOCSTRING(arma_rnd)
+
+ at DOCSTRING(autocor)
+
+ at DOCSTRING(autocov)
+
+ at DOCSTRING(autoreg_matrix)
+
+ at DOCSTRING(bartlett)
+
+ at DOCSTRING(blackman)
+
+ at DOCSTRING(diffpara)
+
+ at DOCSTRING(durbinlevinson)
+
+ at DOCSTRING(fftshift)
+
+ at DOCSTRING(ifftshift)
+
+ at DOCSTRING(fractdiff)
+
+ at DOCSTRING(hamming)
+
+ at DOCSTRING(hanning)
+
+ at DOCSTRING(hurst)
+
+ at DOCSTRING(pchip)
+
+ at DOCSTRING(periodogram)
+
+ at DOCSTRING(rectangle_lw)
+
+ at DOCSTRING(rectangle_sw)
+
+ at DOCSTRING(sinetone)
+
+ at DOCSTRING(sinewave)
+
+ at DOCSTRING(spectral_adf)
+
+ at DOCSTRING(spectral_xdf)
+
+ at DOCSTRING(spencer)
+
+ at DOCSTRING(stft)
+
+ at DOCSTRING(synthesis)
+
+ at DOCSTRING(triangle_lw)
+
+ at DOCSTRING(triangle_sw)
+
+ at DOCSTRING(yulewalker)
diff --git a/doc/interpreter/sparse.texi b/doc/interpreter/sparse.texi
new file mode 100644
index 0000000..df0f549
--- /dev/null
+++ b/doc/interpreter/sparse.texi
@@ -0,0 +1,2761 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at ifhtml
+ at set htmltex
+ at end ifhtml
+ at iftex
+ at set htmltex
+ at end iftex
+
+ at node Sparse Matrices 
+ at chapter Sparse Matrices
+
+ at menu
+* Basics::                      Creation and Manipulation of Sparse Matrices
+* Sparse Linear Algebra::       Linear Algebra on Sparse Matrices
+* Iterative Techniques::        Iterative Techniques
+* Real Life Example::           Using Sparse Matrices
+ at end menu
+
+ at node Basics
+ at section The Creation and Manipulation of Sparse Matrices
+
+The size of mathematical problems that can be treated at any particular
+time is generally limited by the available computing resources.  Both,
+the speed of the computer and its available memory place limitation on
+the problem size. 
+
+There are many classes of mathematical problems which give rise to
+matrices, where a large number of the elements are zero.  In this case
+it makes sense to have a special matrix type to handle this class of
+problems where only the non-zero elements of the matrix are
+stored.  Not only does this reduce the amount of memory to store the
+matrix, but it also means that operations on this type of matrix can
+take advantage of the a-priori knowledge of the positions of the
+non-zero elements to accelerate their calculations.
+
+A matrix type that stores only the non-zero elements is generally called
+sparse.  It is the purpose of this document to discuss the basics of the
+storage and creation of sparse matrices and the fundamental operations
+on them.
+
+ at menu
+* Storage of Sparse Matrices::
+* Creating Sparse Matrices::
+* Information::
+* Operators and Functions::
+ at end menu
+
+ at node Storage of Sparse Matrices
+ at subsection Storage of Sparse Matrices
+
+It is not strictly speaking necessary for the user to understand how
+sparse matrices are stored.  However, such an understanding will help
+to get an understanding of the size of sparse matrices.  Understanding
+the storage technique is also necessary for those users wishing to 
+create their own oct-files. 
+
+There are many different means of storing sparse matrix data.  What all
+of the methods have in common is that they attempt to reduce the complexity
+and storage given a-priori knowledge of the particular class of problems
+that will be solved.  A good summary of the available techniques for storing
+sparse matrix is given by Saad @footnote{Youcef Saad "SPARSKIT: A basic toolkit
+for sparse matrix computation", 1994,
+ at url{http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps}}.
+With full matrices, knowledge of the point of an element of the matrix
+within the matrix is implied by its position in the computers memory. 
+However, this is not the case for sparse matrices, and so the positions
+of the non-zero elements of the matrix must equally be stored. 
+
+An obvious way to do this is by storing the elements of the matrix as
+triplets, with two elements being their position in the array 
+(rows and column) and the third being the data itself.  This is conceptually
+easy to grasp, but requires more storage than is strictly needed.
+
+The storage technique used within Octave is the compressed column
+format.  In this format the position of each element in a row and the
+data are stored as previously.  However, if we assume that all elements
+in the same column are stored adjacent in the computers memory, then
+we only need to store information on the number of non-zero elements
+in each column, rather than their positions.  Thus assuming that the
+matrix has more non-zero elements than there are columns in the
+matrix, we win in terms of the amount of memory used.
+
+In fact, the column index contains one more element than the number of
+columns, with the first element always being zero.  The advantage of
+this is a simplification in the code, in that there is no special case
+for the first or last columns.  A short example, demonstrating this in
+C is.
+
+ at example
+ at group
+  for (j = 0; j < nc; j++)
+    for (i = cidx (j); i < cidx(j+1); i++)
+       printf ("non-zero element (%i,%i) is %d\n", 
+	   ridx(i), j, data(i));
+ at end group
+ at end example
+
+A clear understanding might be had by considering an example of how the
+above applies to an example matrix.  Consider the matrix
+
+ at example
+ at group
+    1   2   0  0
+    0   0   0  3
+    0   0   0  4
+ at end group
+ at end example
+
+The non-zero elements of this matrix are
+
+ at example
+ at group
+   (1, 1)  @result{} 1
+   (1, 2)  @result{} 2
+   (2, 4)  @result{} 3
+   (3, 4)  @result{} 4
+ at end group
+ at end example
+
+This will be stored as three vectors @var{cidx}, @var{ridx} and @var{data},
+representing the column indexing, row indexing and data respectively.  The
+contents of these three vectors for the above matrix will be
+
+ at example
+ at group
+  @var{cidx} = [0, 1, 2, 2, 4]
+  @var{ridx} = [0, 0, 1, 2]
+  @var{data} = [1, 2, 3, 4]
+ at end group
+ at end example
+
+Note that this is the representation of these elements with the first row
+and column assumed to start at zero, while in Octave itself the row and 
+column indexing starts at one.  Thus the number of elements in the 
+ at var{i}-th column is given by @code{@var{cidx} (@var{i} + 1) - 
+ at var{cidx} (@var{i})}.
+
+Although Octave uses a compressed column format, it should be noted
+that compressed row formats are equally possible.  However, in the
+context of mixed operations between mixed sparse and dense matrices,
+it makes sense that the elements of the sparse matrices are in the
+same order as the dense matrices.  Octave stores dense matrices in
+column major ordering, and so sparse matrices are equally stored in
+this manner.
+
+A further constraint on the sparse matrix storage used by Octave is that 
+all elements in the rows are stored in increasing order of their row
+index, which makes certain operations faster.  However, it imposes
+the need to sort the elements on the creation of sparse matrices.  Having
+disordered elements is potentially an advantage in that it makes operations
+such as concatenating two sparse matrices together easier and faster, however
+it adds complexity and speed problems elsewhere.
+
+ at node Creating Sparse Matrices
+ at subsection Creating Sparse Matrices
+
+There are several means to create sparse matrix.
+
+ at table @asis
+ at item Returned from a function
+There are many functions that directly return sparse matrices.  These include
+ at dfn{speye}, @dfn{sprand}, @dfn{diag}, etc.
+ at item Constructed from matrices or vectors
+The function @dfn{sparse} allows a sparse matrix to be constructed from 
+three vectors representing the row, column and data.  Alternatively, the
+function @dfn{spconvert} uses a three column matrix format to allow easy
+importation of data from elsewhere.
+ at item Created and then filled
+The function @dfn{sparse} or @dfn{spalloc} can be used to create an empty
+matrix that is then filled by the user
+ at item From a user binary program
+The user can directly create the sparse matrix within an oct-file.
+ at end table
+
+There are several basic functions to return specific sparse
+matrices.  For example the sparse identity matrix, is a matrix that is
+often needed.  It therefore has its own function to create it as
+ at code{speye (@var{n})} or @code{speye (@var{r}, @var{c})}, which
+creates an @var{n}-by- at var{n} or @var{r}-by- at var{c} sparse identity
+matrix.
+
+Another typical sparse matrix that is often needed is a random distribution
+of random elements.  The functions @dfn{sprand} and @dfn{sprandn} perform
+this for uniform and normal random distributions of elements.  They have exactly
+the same calling convention, where @code{sprand (@var{r}, @var{c}, @var{d})},
+creates an @var{r}-by- at var{c} sparse matrix with a density of filled
+elements of @var{d}.
+
+Other functions of interest that directly create sparse matrices, are
+ at dfn{diag} or its generalization @dfn{spdiags}, that can take the
+definition of the diagonals of the matrix and create the sparse matrix 
+that corresponds to this.  For example
+
+ at example
+s = diag (sparse(randn(1,n)), -1);
+ at end example
+
+creates a sparse (@var{n}+1)-by-(@var{n}+1) sparse matrix with a single
+diagonal defined.
+
+
+ at c ./sparse/spdiags.m
+ at anchor{doc-spdiags}
+ at deftypefn {Function File} {[@var{b}, @var{c}] =} spdiags (@var{a})
+ at deftypefnx {Function File} {@var{b} =} spdiags (@var{a}, @var{c})
+ at deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{a})
+ at deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{m}, @var{n})
+A generalization of the function @code{diag}.  Called with a single
+input argument, the non-zero diagonals @var{c} of @var{A} are extracted.
+With two arguments the diagonals to extract are given by the vector 
+ at var{c}.
+
+The other two forms of @code{spdiags} modify the input matrix by
+replacing the diagonals.  They use the columns of @var{v} to replace
+the columns represented by the vector @var{c}.  If the sparse matrix
+ at var{a} is defined then the diagonals of this matrix are replaced.
+Otherwise a matrix of @var{m} by @var{n} is created with the
+diagonals given by @var{v}.
+
+Negative values of @var{c} represent diagonals below the main
+diagonal, and positive values of @var{c} diagonals above the main
+diagonal.
+
+For example
+
+ at example
+ at group
+spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
+ at result{}    5 10  0  0
+      1  6 11  0
+      0  2  7 12
+      0  0  3  8
+      0  0  0  4
+ at end group
+ at end example
+
+ at end deftypefn
+
+
+ at c ./sparse/speye.m
+ at anchor{doc-speye}
+ at deftypefn {Function File} {@var{y} =} speye (@var{m})
+ at deftypefnx {Function File} {@var{y} =} speye (@var{m}, @var{n})
+ at deftypefnx {Function File} {@var{y} =} speye (@var{sz})
+Returns a sparse identity matrix.  This is significantly more
+efficient than @code{sparse (eye (@var{m}))} as the full matrix
+is not constructed.
+
+Called with a single argument a square matrix of size @var{m} by
+ at var{m} is created.  Otherwise a matrix of @var{m} by @var{n} is
+created.  If called with a single vector argument, this argument 
+is taken to be the size of the matrix to create.
+ at end deftypefn
+
+
+ at c ./sparse/spfun.m
+ at anchor{doc-spfun}
+ at deftypefn {Function File} {@var{y} =} spfun (@var{f}, at var{x})
+Compute @code{f(@var{x})} for the non-zero values of @var{x}.
+This results in a sparse matrix with the same structure as 
+ at var{x}.  The function @var{f} can be passed as a string, a
+function handle or an inline function.
+ at end deftypefn
+
+
+ at c ./deprecated/spmax.m
+ at anchor{doc-spmax}
+ at deftypefn {Mapping Function} {} spmax (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmax (@var{x})
+This function has been deprecated.  Use @code{max} instead.
+ at end deftypefn
+
+
+ at c ./deprecated/spmin.m
+ at anchor{doc-spmin}
+ at deftypefn {Mapping Function} {} spmin (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmin (@var{x})
+This function has been deprecated.  Use @code{min} instead.
+ at end deftypefn
+
+
+ at c ./sparse/spones.m
+ at anchor{doc-spones}
+ at deftypefn {Function File} {@var{y} =} spones (@var{x})
+Replace the non-zero entries of @var{x} with ones.  This creates a
+sparse matrix with the same structure as @var{x}.
+ at end deftypefn
+
+
+ at c ./sparse/sprand.m
+ at anchor{doc-sprand}
+ at deftypefn {Function File} {} sprand (@var{m}, @var{n}, @var{d})
+ at deftypefnx {Function File} {} sprand (@var{s})
+Generate a random sparse matrix.  The size of the matrix will be
+ at var{m} by @var{n}, with a density of values given by @var{d}.
+ at var{d} should be between 0 and 1. Values will be uniformly
+distributed between 0 and 1.
+
+Note: sometimes the actual density may be a bit smaller than @var{d}. 
+This is unlikely to happen for large really sparse matrices.
+
+If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix @var{S} is non-zero.
+ at seealso{@ref{doc-sprandn,,sprandn}}
+ at end deftypefn
+
+
+ at c ./sparse/sprandn.m
+ at anchor{doc-sprandn}
+ at deftypefn {Function File} {} sprandn (@var{m}, @var{n}, @var{d})
+ at deftypefnx {Function File} {} sprandn (@var{s})
+Generate a random sparse matrix.  The size of the matrix will be
+ at var{m} by @var{n}, with a density of values given by @var{d}.
+ at var{d} should be between 0 and 1. Values will be normally
+distributed with mean of zero and variance 1.
+
+Note: sometimes the actual density may be a bit smaller than @var{d}. 
+This is unlikely to happen for large really sparse matrices.
+
+If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix @var{S} is non-zero.
+ at seealso{@ref{doc-sprand,,sprand}}
+ at end deftypefn
+
+
+ at c ./sparse/sprandsym.m
+ at anchor{doc-sprandsym}
+ at deftypefn {Function File} {} sprandsym (@var{n}, @var{d})
+ at deftypefnx {Function File} {} sprandsym (@var{s})
+Generate a symmetric random sparse matrix.  The size of the matrix will be
+ at var{n} by @var{n}, with a density of values given by @var{d}.
+ at var{d} should be between 0 and 1. Values will be normally
+distributed with mean of zero and variance 1.
+
+Note: sometimes the actual density may be a bit smaller than @var{d}. 
+This is unlikely to happen for large really sparse matrices.
+
+If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix @var{S} is non-zero in its lower
+triangular part.
+ at seealso{@ref{doc-sprand,,sprand}, @ref{doc-sprandn,,sprandn}}
+ at end deftypefn
+
+
+The recommended way for the user to create a sparse matrix, is to create 
+two vectors containing the row and column index of the data and a third
+vector of the same size containing the data to be stored.  For example
+
+ at example
+ at group
+  ri = ci = d = [];
+  for j = 1:c
+    ri = [ri; randperm(r)(1:n)'];
+    ci = [ci; j*ones(n,1)];
+    d = [d; rand(n,1)];
+  endfor
+  s = sparse (ri, ci, d, r, c);
+ at end group
+ at end example
+
+creates an @var{r}-by- at var{c} sparse matrix with a random distribution
+of @var{n} (<@var{r}) elements per column.  The elements of the vectors
+do not need to be sorted in any particular order as Octave will sort
+them prior to storing the data.  However, pre-sorting the data will
+make the creation of the sparse matrix faster.
+
+The function @dfn{spconvert} takes a three or four column real matrix.
+The first two columns represent the row and column index respectively and
+the third and four columns, the real and imaginary parts of the sparse
+matrix.  The matrix can contain zero elements and the elements can be 
+sorted in any order.  Adding zero elements is a convenient way to define
+the size of the sparse matrix.  For example
+
+ at example
+ at group
+s = spconvert ([1 2 3 4; 1 3 4 4; 1 2 3 0]')
+ at result{} Compressed Column Sparse (rows=4, cols=4, nnz=3)
+      (1 , 1) -> 1
+      (2 , 3) -> 2
+      (3 , 4) -> 3
+ at end group
+ at end example
+
+An example of creating and filling a matrix might be
+
+ at example
+ at group
+k = 5;
+nz = r * k;
+s = spalloc (r, c, nz)
+for j = 1:c
+  idx = randperm (r);
+  s (:, j) = [zeros(r - k, 1); ...
+        rand(k, 1)] (idx);
+endfor
+ at end group
+ at end example
+
+It should be noted, that due to the way that the Octave
+assignment functions are written that the assignment will reallocate
+the memory used by the sparse matrix at each iteration of the above loop. 
+Therefore the @dfn{spalloc} function ignores the @var{nz} argument and 
+does not preassign the memory for the matrix.  Therefore, it is vitally
+important that code using to above structure should be vectorized
+as much as possible to minimize the number of assignments and reduce the
+number of memory allocations.
+
+ at c data.cc
+ at anchor{doc-full}
+ at deftypefn {Loadable Function} {@var{FM} =} full (@var{SM})
+ returns a full storage matrix from a sparse, diagonal, permutation matrix or a range.
+ at seealso{@ref{doc-sparse,,sparse}}
+ at end deftypefn
+
+
+ at c ./sparse/spalloc.m
+ at anchor{doc-spalloc}
+ at deftypefn {Function File} {@var{s} =} spalloc (@var{r}, @var{c}, @var{nz})
+Returns an empty sparse matrix of size @var{r}-by- at var{c}.  As Octave
+resizes sparse matrices at the first opportunity, so that no additional 
+space is needed, the argument @var{nz} is ignored.  This function is 
+provided only for compatibility reasons.
+
+It should be noted that this means that code like
+
+ at example
+ at group
+k = 5;
+nz = r * k;
+s = spalloc (r, c, nz)
+for j = 1:c
+  idx = randperm (r);
+  s (:, j) = [zeros(r - k, 1); rand(k, 1)] (idx);
+endfor
+ at end group
+ at end example
+
+will reallocate memory at each step.  It is therefore vitally important
+that code like this is vectorized as much as possible.
+ at seealso{@ref{doc-sparse,,sparse}, @ref{doc-nzmax,,nzmax}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/sparse.cc
+ at anchor{doc-sparse}
+ at deftypefn {Loadable Function} {@var{s} =} sparse (@var{a})
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, "unique")
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{m}, @var{n})
+Create a sparse matrix from the full matrix or row, column, value triplets.
+If @var{a} is a full matrix, convert it to a sparse matrix representation,
+removing all zero values in the process.
+
+Given the integer index vectors @var{i} and @var{j}, a 1-by- at code{nnz} vector
+of real of complex values @var{sv}, overall dimensions @var{m} and @var{n}
+of the sparse matrix.  The argument @code{nzmax} is ignored but accepted for
+compatibility with @sc{matlab}.  If @var{m} or @var{n} are not specified their
+values are derived from the maximum index in the vectors @var{i} and @var{j}
+as given by @code{@var{m} = max (@var{i})}, @code{@var{n} = max (@var{j})}.
+
+ at strong{Note}: if multiple values are specified with the same
+ at var{i}, @var{j} indices, the corresponding values in @var{s} will
+be added.
+
+The following are all equivalent:
+
+ at example
+ at group
+s = sparse (i, j, s, m, n)
+s = sparse (i, j, s, m, n, "summation")
+s = sparse (i, j, s, m, n, "sum")
+ at end group
+ at end example
+
+Given the option "unique". if more than two values are specified for the
+same @var{i}, @var{j} indices, the last specified value will be used.
+
+ at code{sparse(@var{m}, @var{n})} is equivalent to
+ at code{sparse ([], [], [], @var{m}, @var{n}, 0)}
+
+If any of @var{sv}, @var{i} or @var{j} are scalars, they are expanded
+to have a common size.
+ at seealso{@ref{doc-full,,full}}
+ at end deftypefn
+
+
+ at c ./sparse/spconvert.m
+ at anchor{doc-spconvert}
+ at deftypefn {Function File} {@var{x} =} spconvert (@var{m})
+This function converts for a simple sparse matrix format easily
+produced by other programs into Octave's internal sparse format.  The
+input @var{x} is either a 3 or 4 column real matrix, containing
+the row, column, real and imaginary parts of the elements of the
+sparse matrix.  An element with a zero real and imaginary part can
+be used to force a particular matrix size.
+ at end deftypefn
+
+
+The above problem of memory reallocation can be avoided in
+oct-files.  However, the construction of a sparse matrix from an oct-file
+is more complex than can be discussed here, and
+you are referred to chapter @ref{Dynamically Linked Functions}, to have
+a full description of the techniques involved.
+
+ at node Information
+ at subsection Finding out Information about Sparse Matrices
+
+There are a number of functions that allow information concerning
+sparse matrices to be obtained.  The most basic of these is
+ at dfn{issparse} that identifies whether a particular Octave object is
+in fact a sparse matrix.
+
+Another very basic function is @dfn{nnz} that returns the number of
+non-zero entries there are in a sparse matrix, while the function
+ at dfn{nzmax} returns the amount of storage allocated to the sparse
+matrix.  Note that Octave tends to crop unused memory at the first
+opportunity for sparse objects.  There are some cases of user created
+sparse objects where the value returned by @dfn{nzmax} will not be
+the same as @dfn{nnz}, but in general they will give the same
+result.  The function @dfn{spstats} returns some basic statistics on
+the columns of a sparse matrix including the number of elements, the
+mean and the variance of each column.
+
+ at c ./DLD-FUNCTIONS/sparse.cc
+ at anchor{doc-issparse}
+ at deftypefn {Loadable Function} {} issparse (@var{expr})
+Return 1 if the value of the expression @var{expr} is a sparse matrix.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-nnz}
+ at deftypefn {Built-in Function} {@var{scalar} =} nnz (@var{a})
+Returns the number of non zero elements in @var{a}.
+ at seealso{@ref{doc-sparse,,sparse}}
+ at end deftypefn
+
+
+ at c ./sparse/nonzeros.m
+ at anchor{doc-nonzeros}
+ at deftypefn {Function File} {} nonzeros (@var{s})
+Returns a vector of the non-zero values of the sparse matrix @var{s}.
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-nzmax}
+ at deftypefn {Built-in Function} {@var{scalar} =} nzmax (@var{SM})
+Return the amount of storage allocated to the sparse matrix @var{SM}.
+Note that Octave tends to crop unused memory at the first opportunity
+for sparse objects.  There are some cases of user created sparse objects
+where the value returned by @dfn{nzmax} will not be the same as @dfn{nnz},
+but in general they will give the same result.
+ at seealso{@ref{doc-sparse,,sparse}, @ref{doc-spalloc,,spalloc}}
+ at end deftypefn
+
+
+ at c ./sparse/spstats.m
+ at anchor{doc-spstats}
+ at deftypefn {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{s})
+ at deftypefnx {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{s}, @var{j})
+Return the stats for the non-zero elements of the sparse matrix @var{s}.
+ at var{count} is the number of non-zeros in each column, @var{mean}
+is the mean of the non-zeros in each column, and @var{var} is the  
+variance of the non-zeros in each column.
+
+Called with two input arguments, if @var{s} is the data and @var{j}
+is the bin number for the data, compute the stats for each bin.  In 
+this case, bins can contain data values of zero, whereas with 
+ at code{spstats (@var{s})} the zeros may disappear.
+ at end deftypefn
+
+
+When solving linear equations involving sparse matrices Octave
+determines the means to solve the equation based on the type of the
+matrix as discussed in @ref{Sparse Linear Algebra}.  Octave probes the
+matrix type when the div (/) or ldiv (\) operator is first used with
+the matrix and then caches the type.  However the @dfn{matrix_type}
+function can be used to determine the type of the sparse matrix prior
+to use of the div or ldiv operators.  For example
+
+ at example
+ at group
+a = tril (sprandn(1024, 1024, 0.02), -1) ...
+    + speye(1024); 
+matrix_type (a);
+ans = Lower
+ at end group
+ at end example
+
+show that Octave correctly determines the matrix type for lower
+triangular matrices.  @dfn{matrix_type} can also be used to force
+the type of a matrix to be a particular type.  For example
+
+ at example
+ at group
+a = matrix_type (tril (sprandn (1024, ...
+   1024, 0.02), -1) + speye(1024), 'Lower');
+ at end group
+ at end example
+
+This allows the cost of determining the matrix type to be
+avoided.  However, incorrectly defining the matrix type will result in
+incorrect results from solutions of linear equations, and so it is
+entirely the responsibility of the user to correctly identify the
+matrix type
+
+There are several graphical means of finding out information about
+sparse matrices.  The first is the @dfn{spy} command, which displays
+the structure of the non-zero elements of the
+matrix.  @xref{fig:spmatrix}, for an example of the use of
+ at dfn{spy}.  More advanced graphical information can be obtained with the
+ at dfn{treeplot}, @dfn{etreeplot} and @dfn{gplot} commands.
+
+ at float Figure,fig:spmatrix
+ at center @image{spmatrix,4in}
+ at caption{Structure of simple sparse matrix.}
+ at end float
+
+One use of sparse matrices is in graph theory, where the
+interconnections between nodes are represented as an adjacency
+matrix.  That is, if the i-th node in a graph is connected to the j-th
+node.  Then the ij-th node (and in the case of undirected graphs the
+ji-th node) of the sparse adjacency matrix is non-zero.  If each node
+is then associated with a set of coordinates, then the @dfn{gplot}
+command can be used to graphically display the interconnections
+between nodes.
+
+As a trivial example of the use of @dfn{gplot}, consider the example
+
+ at example
+ at group
+A = sparse([2,6,1,3,2,4,3,5,4,6,1,5],
+    [1,1,2,2,3,3,4,4,5,5,6,6],1,6,6);
+xy = [0,4,8,6,4,2;5,0,5,7,5,7]';
+gplot(A,xy)
+ at end group
+ at end example
+
+which creates an adjacency matrix @code{A} where node 1 is connected
+to nodes 2 and 6, node 2 with nodes 1 and 3, etc.  The coordinates of
+the nodes are given in the n-by-2 matrix @code{xy}.
+ at ifset htmltex 
+ at xref{fig:gplot}.
+
+ at float Figure,fig:gplot
+ at center @image{gplot,4in}
+ at caption{Simple use of the @dfn{gplot} command.}
+ at end float
+ at end ifset
+
+The dependencies between the nodes of a Cholesky factorization can be
+calculated in linear time without explicitly needing to calculate the
+Cholesky factorization by the @code{etree} command.  This command
+returns the elimination tree of the matrix and can be displayed
+graphically by the command @code{treeplot(etree(A))} if @code{A} is
+symmetric or @code{treeplot(etree(A+A'))} otherwise.
+
+ at c ./sparse/spy.m
+ at anchor{doc-spy}
+ at deftypefn {Function File} {} spy (@var{x})
+ at deftypefnx {Function File} {} spy (@dots{}, @var{markersize})
+ at deftypefnx {Function File} {} spy (@dots{}, @var{line_spec})
+Plot the sparsity pattern of the sparse matrix @var{x}.  If the argument
+ at var{markersize} is given as an scalar value, it is used to determine the
+point size in the plot.  If the string @var{line_spec} is given it is
+passed to @code{plot} and determines the appearance of the plot.
+ at seealso{@ref{doc-plot,,plot}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/colamd.cc
+ at anchor{doc-etree}
+ at deftypefn {Loadable Function} {@var{p} =} etree (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} etree (@var{s}, @var{typ})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{s}, @var{typ})
+
+Returns the elimination tree for the matrix @var{s}.  By default @var{s}
+is assumed to be symmetric and the symmetric elimination tree is
+returned.  The argument @var{typ} controls whether a symmetric or
+column elimination tree is returned.  Valid values of @var{typ} are
+'sym' or 'col', for symmetric or column elimination tree respectively
+
+Called with a second argument, @dfn{etree} also returns the postorder
+permutations on the tree.
+ at end deftypefn
+
+
+ at c ./sparse/etreeplot.m
+ at anchor{doc-etreeplot}
+ at deftypefn {Function File} {} etreeplot (@var{tree})
+ at deftypefnx {Function File} {} etreeplot (@var{tree}, @var{node_style}, @var{edge_style})
+Plot the elimination tree of the matrix @var{s} or
+ at code{@var{s}+ at var{s}'}  if @var{s} in non-symmetric.  The optional
+parameters @var{line_style} and @var{edge_style} define the output
+style.
+ at seealso{@ref{doc-treeplot,,treeplot}, @ref{doc-gplot,,gplot}}
+ at end deftypefn
+
+
+ at c ./sparse/gplot.m
+ at anchor{doc-gplot}
+ at deftypefn {Function File} {} gplot (@var{a}, @var{xy})
+ at deftypefnx {Function File} {} gplot (@var{a}, @var{xy}, @var{line_style})
+ at deftypefnx {Function File} {[@var{x}, @var{y}] =} gplot (@var{a}, @var{xy})
+Plot a graph defined by @var{A} and @var{xy} in the graph theory
+sense.  @var{A} is the adjacency matrix of the array to be plotted
+and @var{xy} is an @var{n}-by-2 matrix containing the coordinates of
+the nodes of the graph.
+
+The optional parameter @var{line_style} defines the output style for
+the plot.  Called with no output arguments the graph is plotted
+directly.  Otherwise, return the coordinates of the plot in @var{x}
+and @var{y}.
+ at seealso{@ref{doc-treeplot,,treeplot}, @ref{doc-etreeplot,,etreeplot}, @ref{doc-spy,,spy}}
+ at end deftypefn
+
+
+ at c ./sparse/treeplot.m
+ at anchor{doc-treeplot}
+ at deftypefn {Function File} {} treeplot (@var{tree})
+ at deftypefnx {Function File} {} treeplot (@var{tree}, @var{line_style}, @var{edge_style})
+Produces a graph of tree or forest.  The first argument is vector of
+predecessors, optional parameters @var{line_style} and @var{edge_style}
+define the output style.  The complexity of the algorithm is O(n) in
+terms of is time and memory requirements.
+ at seealso{@ref{doc-etreeplot,,etreeplot}, @ref{doc-gplot,,gplot}}
+ at end deftypefn
+
+
+ at c ./sparse/treelayout.m
+ at anchor{doc-treelayout}
+ at deftypefn {Function File} {} treelayout (@var{Tree})
+ at deftypefnx {Function File} {} treelayout (@var{Tree}, @var{permutation})
+treelayout lays out a tree or a forest.  The first argument @var{Tree} is a vector of
+predecessors, optional parameter @var{permutation} is an optional postorder permutation.
+The complexity of the algorithm is O(n) in
+terms of time and memory requirements.
+ at seealso{@ref{doc-etreeplot,,etreeplot}, @ref{doc-gplot,,gplot}, @ref{doc-treeplot,,treeplot}}
+ at end deftypefn
+
+
+ at node Operators and Functions
+ at subsection Basic Operators and Functions on Sparse Matrices
+
+ at menu
+* Sparse Functions::            
+* Return Types of Operators and Functions::  
+* Mathematical Considerations::  
+ at end menu
+
+ at node Sparse Functions
+ at subsubsection Sparse Functions
+
+An important consideration in the use of the sparse functions of
+Octave is that many of the internal functions of Octave, such as
+ at dfn{diag}, cannot accept sparse matrices as an input.  The sparse
+implementation in Octave therefore uses the @dfn{dispatch}
+function to overload the normal Octave functions with equivalent
+functions that work with sparse matrices.  However, at any time the
+sparse matrix specific version of the function can be used by
+explicitly calling its function name. 
+
+The table below lists all of the sparse functions of Octave.  Note that
+the names of the 
+specific sparse forms of the functions are typically the same as
+the general versions with a @dfn{sp} prefix.  In the table below, and the
+rest of this article the specific sparse versions of the functions are
+used.
+
+ at c Table includes in comments the missing sparse functions
+
+ at table @asis
+ at item Generate sparse matrices:
+  @dfn{spalloc}, @dfn{spdiags}, @dfn{speye}, @dfn{sprand}, 
+  @dfn{sprandn}, @dfn{sprandsym}
+
+ at item Sparse matrix conversion:
+  @dfn{full}, @dfn{sparse}, @dfn{spconvert}
+
+ at item Manipulate sparse matrices
+  @dfn{issparse}, @dfn{nnz}, @dfn{nonzeros}, @dfn{nzmax},
+  @dfn{spfun}, @dfn{spones}, @dfn{spy}
+
+ at item Graph Theory:
+  @dfn{etree}, @dfn{etreeplot}, @dfn{gplot}, 
+  @dfn{treeplot}
+ at c @dfn{treelayout}
+
+ at item Sparse matrix reordering:
+  @dfn{amd}, @dfn{ccolamd}, @dfn{colamd}, @dfn{colperm}, @dfn{csymamd},
+  @dfn{dmperm}, @dfn{symamd}, @dfn{randperm}, @dfn{symrcm}
+
+ at item Linear algebra:
+  @dfn{condest}, @dfn{eigs}, @dfn{matrix_type}, @dfn{normest}, @dfn{sprank},
+  @dfn{spaugment}, @dfn{svds}
+
+ at item Iterative techniques:
+  @dfn{luinc}, @dfn{pcg}, @dfn{pcr}
+ at c @dfn{bicg}, @dfn{bicgstab}, @dfn{cholinc}, @dfn{cgs}, @dfn{gmres}, 
+ at c @dfn{lsqr}, @dfn{minres}, @dfn{qmr}, @dfn{symmlq}
+
+ at item Miscellaneous:
+  @dfn{spparms}, @dfn{symbfact}, @dfn{spstats}
+ at end table
+
+In addition all of the standard Octave mapper functions (i.e., basic
+math functions that take a single argument) such as @dfn{abs}, etc.
+can accept sparse matrices.  The reader is referred to the documentation
+supplied with these functions within Octave itself for further
+details.
+
+ at node Return Types of Operators and Functions
+ at subsubsection The Return Types of Operators and Functions
+
+The two basic reasons to use sparse matrices are to reduce the memory 
+usage and to not have to do calculations on zero elements.  The two are
+closely related in that the computation time on a sparse matrix operator
+or function is roughly linear with the number of non-zero elements.
+
+Therefore, there is a certain density of non-zero elements of a matrix 
+where it no longer makes sense to store it as a sparse matrix, but rather
+as a full matrix.  For this reason operators and functions that have a 
+high probability of returning a full matrix will always return one.  For
+example adding a scalar constant to a sparse matrix will almost always
+make it a full matrix, and so the example
+
+ at example
+ at group
+speye(3) + 0
+ at result{}   1  0  0
+  0  1  0
+  0  0  1
+ at end group
+ at end example
+
+returns a full matrix as can be seen. 
+
+
+Additionally, if @code{sparse_auto_mutate} is true, all sparse functions
+test the amount of memory occupied by the sparse matrix to see if the
+amount of storage used is larger than the amount used by the full
+equivalent.  Therefore @code{speye (2) * 1} will return a full matrix as
+the memory used is smaller for the full version than the sparse version.
+
+As all of the mixed operators and functions between full and sparse 
+matrices exist, in general this does not cause any problems.  However,
+one area where it does cause a problem is where a sparse matrix is
+promoted to a full matrix, where subsequent operations would resparsify
+the matrix.  Such cases are rare, but can be artificially created, for
+example @code{(fliplr(speye(3)) + speye(3)) - speye(3)} gives a full
+matrix when it should give a sparse one.  In general, where such cases 
+occur, they impose only a small memory penalty.
+
+There is however one known case where this behavior of Octave's
+sparse matrices will cause a problem.  That is in the handling of the
+ at dfn{diag} function.  Whether @dfn{diag} returns a sparse or full matrix
+depending on the type of its input arguments.  So 
+
+ at example
+ a = diag (sparse([1,2,3]), -1);
+ at end example
+
+should return a sparse matrix.  To ensure this actually happens, the
+ at dfn{sparse} function, and other functions based on it like @dfn{speye}, 
+always returns a sparse matrix, even if the memory used will be larger 
+than its full representation.
+
+ at c ov-base.cc
+ at anchor{doc-sparse_auto_mutate}
+ at deftypefn {Built-in Function} {@var{val} =} sparse_auto_mutate ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} sparse_auto_mutate (@var{new_val})
+Query or set the internal variable that controls whether Octave will
+automatically mutate sparse matrices to real matrices to save memory.
+For example,
+
+ at example
+ at group
+s = speye(3);
+sparse_auto_mutate (false)
+s (:, 1) = 1;
+typeinfo (s)
+ at result{} sparse matrix
+sparse_auto_mutate (true)
+s (1, :) = 1;
+typeinfo (s)
+ at result{} matrix
+ at end group
+ at end example
+ at end deftypefn
+
+
+Note that the @code{sparse_auto_mutate} option is incompatible with
+ at sc{matlab}, and so it is off by default.
+
+ at node Mathematical Considerations
+ at subsubsection Mathematical Considerations
+
+The attempt has been made to make sparse matrices behave in exactly the
+same manner as there full counterparts.  However, there are certain differences
+and especially differences with other products sparse implementations.
+
+Firstly, the "./" and ".^" operators must be used with care.  Consider what
+the examples
+
+ at example
+ at group
+  s = speye (4);
+  a1 = s .^ 2;
+  a2 = s .^ s;
+  a3 = s .^ -2;
+  a4 = s ./ 2;
+  a5 = 2 ./ s;
+  a6 = s ./ s;
+ at end group
+ at end example
+
+will give.  The first example of @var{s} raised to the power of 2 causes
+no problems.  However @var{s} raised element-wise to itself involves a
+large number of terms @code{0 .^ 0} which is 1. There @code{@var{s} .^
+ at var{s}} is a full matrix. 
+
+Likewise @code{@var{s} .^ -2} involves terms like @code{0 .^ -2} which
+is infinity, and so @code{@var{s} .^ -2} is equally a full matrix.
+
+For the "./" operator @code{@var{s} ./ 2} has no problems, but 
+ at code{2 ./ @var{s}} involves a large number of infinity terms as well
+and is equally a full matrix.  The case of @code{@var{s} ./ @var{s}}
+involves terms like @code{0 ./ 0} which is a @code{NaN} and so this
+is equally a full matrix with the zero elements of @var{s} filled with
+ at code{NaN} values.
+
+The above behavior is consistent with full matrices, but is not 
+consistent with sparse implementations in other products.
+
+A particular problem of sparse matrices comes about due to the fact that
+as the zeros are not stored, the sign-bit of these zeros is equally not
+stored.  In certain cases the sign-bit of zero is important.  For example
+
+ at example
+ at group
+ a = 0 ./ [-1, 1; 1, -1];
+ b = 1 ./ a
+ @result{} -Inf            Inf
+     Inf           -Inf
+ c = 1 ./ sparse (a)
+ @result{}  Inf            Inf
+     Inf            Inf
+ at end group
+ at end example
+ 
+To correct this behavior would mean that zero elements with a negative
+sign-bit would need to be stored in the matrix to ensure that their 
+sign-bit was respected.  This is not done at this time, for reasons of
+efficiency, and so the user is warned that calculations where the sign-bit
+of zero is important must not be done using sparse matrices.
+
+In general any function or operator used on a sparse matrix will
+result in a sparse matrix with the same or a larger number of non-zero
+elements than the original matrix.  This is particularly true for the
+important case of sparse matrix factorizations.  The usual way to
+address this is to reorder the matrix, such that its factorization is
+sparser than the factorization of the original matrix.  That is the
+factorization of @code{L * U = P * S * Q} has sparser terms @code{L}
+and @code{U} than the equivalent factorization @code{L * U = S}.
+
+Several functions are available to reorder depending on the type of the
+matrix to be factorized.  If the matrix is symmetric positive-definite,
+then @dfn{symamd} or @dfn{csymamd} should be used.  Otherwise
+ at dfn{amd}, @dfn{colamd} or @dfn{ccolamd} should be used.  For completeness
+the reordering functions @dfn{colperm} and @dfn{randperm} are
+also available.
+
+ at xref{fig:simplematrix}, for an example of the structure of a simple 
+positive definite matrix.
+
+ at float Figure,fig:simplematrix
+ at center @image{spmatrix,4in}
+ at caption{Structure of simple sparse matrix.}
+ at end float
+
+The standard Cholesky factorization of this matrix can be
+obtained by the same command that would be used for a full
+matrix.  This can be visualized with the command 
+ at code{r = chol(A); spy(r);}.
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_COLAMD
+ at xref{fig:simplechol}.
+ at end ifset
+ at end ifset
+The original matrix had 
+ at ifinfo
+ at ifnothtml
+43
+ at end ifnothtml
+ at end ifinfo
+ at ifset htmltex
+598
+ at end ifset
+non-zero terms, while this Cholesky factorization has
+ at ifinfo
+ at ifnothtml
+71,
+ at end ifnothtml
+ at end ifinfo
+ at ifset htmltex
+10200,
+ at end ifset
+with only half of the symmetric matrix being stored.  This
+is a significant level of fill in, and although not an issue
+for such a small test case, can represents a large overhead 
+in working with other sparse matrices.
+
+The appropriate sparsity preserving permutation of the original
+matrix is given by @dfn{symamd} and the factorization using this
+reordering can be visualized using the command @code{q = symamd(A);
+r = chol(A(q,q)); spy(r)}.  This gives 
+ at ifinfo
+ at ifnothtml
+29
+ at end ifnothtml
+ at end ifinfo
+ at ifset htmltex
+399
+ at end ifset
+non-zero terms which is a significant improvement.
+
+The Cholesky factorization itself can be used to determine the
+appropriate sparsity preserving reordering of the matrix during the
+factorization, In that case this might be obtained with three return
+arguments as r at code{[r, p, q] = chol(A); spy(r)}.
+
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_COLAMD
+ at float Figure,fig:simplechol
+ at center @image{spchol,4in}
+ at caption{Structure of the un-permuted Cholesky factorization of the above matrix.}
+ at end float
+
+ at float Figure,fig:simplecholperm
+ at center @image{spcholperm,4in}
+ at caption{Structure of the permuted Cholesky factorization of the above matrix.}
+ at end float
+ at end ifset
+ at end ifset
+
+In the case of an asymmetric matrix, the appropriate sparsity
+preserving permutation is @dfn{colamd} and the factorization using
+this reordering can be visualized using the command @code{q =
+colamd(A); [l, u, p] = lu(A(:,q)); spy(l+u)}.
+
+Finally, Octave implicitly reorders the matrix when using the div (/)
+and ldiv (\) operators, and so no the user does not need to explicitly
+reorder the matrix to maximize performance.
+
+ at c ./DLD-FUNCTIONS/amd.cc
+ at anchor{doc-amd}
+ at deftypefn {Loadable Function} {@var{p} =} amd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} amd (@var{s}, @var{opts})
+
+Returns the approximate minimum degree permutation of a matrix.  This
+permutation such that the Cholesky factorization of @code{@var{s} (@var{p},
+ at var{p})} tends to be sparser than the Cholesky factorization of @var{s}
+itself.  @code{amd} is typically faster than @code{symamd} but serves a
+similar purpose.
+
+The optional parameter @var{opts} is a structure that controls the
+behavior of @code{amd}.  The fields of these structure are
+
+ at table @asis
+ at item opts.dense
+Determines what @code{amd} considers to be a dense row or column of the
+input matrix.  Rows or columns with more than @code{max(16, (dense *
+sqrt (@var{n})} entries, where @var{n} is the order of the matrix @var{s},
+are ignored by @code{amd} during the calculation of the permutation
+The value of dense must be a positive scalar and its default value is 10.0
+
+ at item opts.aggressive
+If this value is a non zero scalar, then @code{amd} performs aggressive
+absorption.  The default is not to perform aggressive absorption.
+ at end table
+
+The author of the code itself is Timothy A. Davis (davis@@cise.ufl.edu),
+University of Florida (see @url{http://www.cise.ufl.edu/research/sparse/amd}).
+ at seealso{@ref{doc-symamd,,symamd}, @ref{doc-colamd,,colamd}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/ccolamd.cc
+ at anchor{doc-ccolamd}
+ at deftypefn {Loadable Function} {@var{p} =} ccolamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{s}, @var{knobs}, @var{cmember})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} ccolamd (@dots{})
+
+Constrained column approximate minimum degree permutation.  @code{@var{p} =
+ccolamd (@var{s})} returns the column approximate minimum degree permutation
+vector for the sparse matrix @var{s}.  For a non-symmetric matrix @var{s},
+ at code{@var{s} (:, @var{p})} tends to have sparser LU factors than @var{s}.
+ at code{chol (@var{s} (:, @var{p})' * @var{s} (:, @var{p}))} also tends to be
+sparser than @code{chol (@var{s}' * @var{s})}.  @code{@var{p} = ccolamd
+(@var{s}, 1)} optimizes the ordering for @code{lu (@var{s} (:, @var{p}))}.
+The ordering is followed by a column elimination tree post-ordering.
+
+ at var{knobs} is an optional one- to five-element input vector, with a default
+value of @code{[0 10 10 1 0]} if not present or empty.  Entries not present
+are set to their defaults.
+
+ at table @code
+ at item @var{knobs}(1)
+if nonzero, the ordering is optimized for @code{lu (S (:, p))}.  It will be a
+poor ordering for @code{chol (@var{s} (:, @var{p})' * @var{s} (:,
+ at var{p}))}.  This is the most important knob for ccolamd.
+
+ at item @var{knob}(2)
+if @var{s} is m-by-n, rows with more than @code{max (16, @var{knobs} (2) *
+sqrt (n))} entries are ignored.
+
+ at item @var{knob}(3)
+columns with more than @code{max (16, @var{knobs} (3) * sqrt (min (@var{m},
+ at var{n})))} entries are ignored and ordered last in the output permutation
+(subject to the cmember constraints).
+
+ at item @var{knob}(4)
+if nonzero, aggressive absorption is performed.
+
+ at item @var{knob}(5)
+if nonzero, statistics and knobs are printed.
+
+ at end table
+
+ at var{cmember} is an optional vector of length n.  It defines the constraints
+on the column ordering.  If @code{@var{cmember} (j) = @var{c}}, then column
+ at var{j} is in constraint set @var{c} (@var{c} must be in the range 1 to
+ at var{n}).  In the output permutation @var{p}, all columns in set 1 appear
+first, followed by all columns in set 2, and so on.  @code{@var{cmember} =
+ones(1,n)} if not present or empty.  @code{ccolamd (@var{s}, [], 1 :
+ at var{n})} returns @code{1 : @var{n}}
+
+ at code{@var{p} = ccolamd (@var{s})} is about the same as @code{@var{p} =
+colamd (@var{s})}.  @var{knobs} and its default values differ.  @code{colamd}
+always does aggressive absorption, and it finds an ordering suitable for
+both @code{lu (@var{s} (:, @var{p}))} and @code{chol (@var{S} (:, @var{p})'
+* @var{s} (:, @var{p}))}; it cannot optimize its ordering for
+ at code{lu (@var{s} (:, @var{p}))} to the extent that
+ at code{ccolamd (@var{s}, 1)} can.
+
+ at var{stats} is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix @var{s}.  Ordering
+statistics are in @code{@var{stats} (1 : 3)}.  @code{@var{stats} (1)} and
+ at code{@var{stats} (2)} are the number of dense or empty rows and columns
+ignored by CCOLAMD and @code{@var{stats} (3)} is the number of garbage
+collections performed on the internal data structure used by CCOLAMD
+(roughly of size @code{2.2 * nnz (@var{s}) + 4 * @var{m} + 7 * @var{n}}
+integers).
+
+ at code{@var{stats} (4 : 7)} provide information if CCOLAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists.
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row
+index in the column index given by @code{@var{stats} (5)}, or zero if no
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate
+or out-of-order row indices.  @code{@var{stats} (8 : 20)} is always zero in
+the current version of CCOLAMD (reserved for future use).
+
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),
+and a grant from Sandia National Lab.  See
+ at url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,
+colamd, symamd, and other related orderings.
+ at seealso{@ref{doc-colamd,,colamd}, @ref{doc-csymamd,,csymamd}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/colamd.cc
+ at anchor{doc-colamd}
+ at deftypefn {Loadable Function} {@var{p} =} colamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} colamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{s})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{s}, @var{knobs})
+
+Column approximate minimum degree permutation.  @code{@var{p} = colamd
+(@var{s})} returns the column approximate minimum degree permutation
+vector for the sparse matrix @var{s}.  For a non-symmetric matrix @var{s},
+ at code{@var{s} (:, at var{p})} tends to have sparser LU factors than @var{s}.
+The Cholesky factorization of @code{@var{s} (:, at var{p})' * @var{s}
+(:, at var{p})} also tends to be sparser than that of @code{@var{s}' *
+ at var{s}}.
+
+ at var{knobs} is an optional one- to three-element input vector.  If @var{s} is
+m-by-n, then rows with more than @code{max(16, at var{knobs}(1)*sqrt(n))} entries
+are ignored.  Columns with more than @code{max(16,knobs(2)*sqrt(min(m,n)))}
+entries are removed prior to ordering, and ordered last in the output
+permutation @var{p}.  Only completely dense rows or columns are removed
+if @code{@var{knobs} (1)} and @code{@var{knobs} (2)} are < 0, respectively.
+If @code{@var{knobs} (3)} is nonzero, @var{stats} and @var{knobs} are
+printed.  The default is @code{@var{knobs} = [10 10 0]}.  Note that
+ at var{knobs} differs from earlier versions of colamd
+
+ at var{stats} is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix @var{s}.  Ordering
+statistics are in @code{@var{stats} (1:3)}.  @code{@var{stats} (1)} and
+ at code{@var{stats} (2)} are the number of dense or empty rows and columns
+ignored by COLAMD and @code{@var{stats} (3)} is the number of garbage
+collections performed on the internal data structure used by COLAMD
+(roughly of size @code{2.2 * nnz(@var{s}) + 4 * @var{m} + 7 * @var{n}}
+integers).
+
+Octave built-in functions are intended to generate valid sparse matrices,
+with no duplicate entries, with ascending row indices of the nonzeros
+in each column, with a non-negative number of entries in each column (!)
+and so on.  If a matrix is invalid, then COLAMD may or may not be able
+to continue.  If there are duplicate entries (a row index appears two or
+more times in the same column) or if the row indices in a column are out
+of order, then COLAMD can correct these errors by ignoring the duplicate
+entries and sorting each column of its internal copy of the matrix
+ at var{s} (the input matrix @var{s} is not repaired, however).  If a matrix
+is invalid in other ways then COLAMD cannot continue, an error message is
+printed, and no output arguments (@var{p} or @var{stats}) are returned.
+COLAMD is thus a simple way to check a sparse matrix to see if it's
+valid.
+
+ at code{@var{stats} (4:7)} provide information if COLAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists.
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row
+index in the column index given by @code{@var{stats} (5)}, or zero if no
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate
+or out-of-order row indices.  @code{@var{stats} (8:20)} is always zero in
+the current version of COLAMD (reserved for future use).
+
+The ordering is followed by a column elimination tree post-ordering.
+
+The authors of the code itself are Stefan I. Larimore and Timothy A.
+Davis (davis@@cise.ufl.edu), University of Florida.  The algorithm was
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+Ng, Oak Ridge National Laboratory.  (see
+ at url{http://www.cise.ufl.edu/research/sparse/colamd})
+ at seealso{@ref{doc-colperm,,colperm}, @ref{doc-symamd,,symamd}}
+ at end deftypefn
+
+
+ at c ./sparse/colperm.m
+ at anchor{doc-colperm}
+ at deftypefn {Function File} {@var{p} =} colperm (@var{s})
+Returns the column permutations such that the columns of
+ at code{@var{s} (:, @var{p})} are ordered in terms of increase number
+of non-zero elements.  If @var{s} is symmetric, then @var{p} is chosen
+such that @code{@var{s} (@var{p}, @var{p})} orders the rows and
+columns with increasing number of non zeros elements.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/ccolamd.cc
+ at anchor{doc-csymamd}
+ at deftypefn {Loadable Function} {@var{p} =} csymamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs}, @var{cmember})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})
+
+For a symmetric positive definite matrix @var{s}, returns the permutation
+vector @var{p} such that @code{@var{s}(@var{p}, at var{p})} tends to have a
+sparser Cholesky factor than @var{s}.  Sometimes @code{csymamd} works well
+for symmetric indefinite matrices too.  The matrix @var{s} is assumed to
+be symmetric; only the strictly lower triangular part is referenced.
+ at var{s} must be square.  The ordering is followed by an elimination tree
+post-ordering.
+
+ at var{knobs} is an optional one- to three-element input vector, with a
+default value of @code{[10 1 0]} if present or empty.  Entries not
+present are set to their defaults.
+
+ at table @code
+ at item @var{knobs}(1)
+If @var{s} is n-by-n, then rows and columns with more than
+ at code{max(16, at var{knobs}(1)*sqrt(n))} entries are ignored, and ordered
+last in the output permutation (subject to the cmember constraints).
+
+ at item @var{knobs}(2)
+If nonzero, aggressive absorption is performed.
+
+ at item @var{knobs}(3)
+If nonzero, statistics and knobs are printed.
+
+ at end table
+
+ at var{cmember} is an optional vector of length n. It defines the constraints
+on the ordering.  If @code{@var{cmember}(j) = @var{s}}, then row/column j is
+in constraint set @var{c} (@var{c} must be in the range 1 to n).  In the
+output permutation @var{p}, rows/columns in set 1 appear first, followed
+by all rows/columns in set 2, and so on.  @code{@var{cmember} = ones(1,n)}
+if not present or empty.  @code{csymamd(@var{s},[],1:n)} returns @code{1:n}.
+
+ at code{@var{p} = csymamd(@var{s})} is about the same as @code{@var{p} =
+symamd(@var{s})}.  @var{knobs} and its default values differ.
+
+ at code{@var{stats} (4:7)} provide information if CCOLAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists.
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row
+index in the column index given by @code{@var{stats} (5)}, or zero if no
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate
+or out-of-order row indices.  @code{@var{stats} (8:20)} is always zero in
+the current version of CCOLAMD (reserved for future use).
+
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),
+and a grant from Sandia National Lab.  See
+ at url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,
+colamd, symamd, and other related orderings.
+ at seealso{@ref{doc-symamd,,symamd}, @ref{doc-ccolamd,,ccolamd}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dmperm.cc
+ at anchor{doc-dmperm}
+ at deftypefn {Loadable Function} {@var{p} =} dmperm (@var{s})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{q}, @var{r}, @var{s}] =} dmperm (@var{s})
+
+ at cindex Dulmage-Mendelsohn decomposition
+Perform a Dulmage-Mendelsohn permutation on the sparse matrix @var{s}.
+With a single output argument @dfn{dmperm} performs the row permutations
+ at var{p} such that @code{@var{s} (@var{p},:)} has no zero elements on the
+diagonal.
+
+Called with two or more output arguments, returns the row and column
+permutations, such that @code{@var{s} (@var{p}, @var{q})} is in block
+triangular form.  The values of @var{r} and @var{s} define the boundaries
+of the blocks.  If @var{s} is square then @code{@var{r} == @var{s}}.
+
+The method used is described in: A. Pothen & C.-J. Fan. Computing the block
+triangular form of a sparse matrix. ACM Trans. Math. Software,
+16(4):303-324, 1990.
+ at seealso{@ref{doc-colamd,,colamd}, @ref{doc-ccolamd,,ccolamd}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/colamd.cc
+ at anchor{doc-symamd}
+ at deftypefn {Loadable Function} {@var{p} =} symamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} symamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{s})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{s}, @var{knobs})
+
+For a symmetric positive definite matrix @var{s}, returns the permutation
+vector p such that @code{@var{s} (@var{p}, @var{p})} tends to have a
+sparser Cholesky factor than @var{s}.  Sometimes SYMAMD works well for
+symmetric indefinite matrices too.  The matrix @var{s} is assumed to be
+symmetric; only the strictly lower triangular part is referenced.  @var{s}
+must be square.
+
+ at var{knobs} is an optional one- to two-element input vector.  If @var{s} is
+n-by-n, then rows and columns with more than
+ at code{max(16, at var{knobs}(1)*sqrt(n))} entries are removed prior to ordering,
+and ordered last in the output permutation @var{p}.  No rows/columns are
+removed if @code{@var{knobs}(1) < 0}.  If @code{@var{knobs} (2)} is nonzero,
+ at code{stats} and @var{knobs} are printed.  The default is @code{@var{knobs} 
+= [10 0]}.  Note that @var{knobs} differs from earlier versions of symamd.
+
+ at var{stats} is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix @var{s}.  Ordering
+statistics are in @code{@var{stats} (1:3)}.  @code{@var{stats} (1) =
+ at var{stats} (2)} is the number of dense or empty rows and columns
+ignored by SYMAMD and @code{@var{stats} (3)} is the number of garbage
+collections performed on the internal data structure used by SYMAMD
+(roughly of size @code{8.4 * nnz (tril (@var{s}, -1)) + 9 * @var{n}}
+integers).
+
+Octave built-in functions are intended to generate valid sparse matrices,
+with no duplicate entries, with ascending row indices of the nonzeros
+in each column, with a non-negative number of entries in each column (!)
+and so on.  If a matrix is invalid, then SYMAMD may or may not be able
+to continue.  If there are duplicate entries (a row index appears two or
+more times in the same column) or if the row indices in a column are out
+of order, then SYMAMD can correct these errors by ignoring the duplicate
+entries and sorting each column of its internal copy of the matrix S (the
+input matrix S is not repaired, however).  If a matrix is invalid in
+other ways then SYMAMD cannot continue, an error message is printed, and
+no output arguments (@var{p} or @var{stats}) are returned.  SYMAMD is
+thus a simple way to check a sparse matrix to see if it's valid.
+
+ at code{@var{stats} (4:7)} provide information if SYMAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1
+if invalid.  @code{@var{stats} (5)} is the rightmost column index that
+is unsorted or contains duplicate entries, or zero if no such column
+exists.  @code{@var{stats} (6)} is the last seen duplicate or out-of-order
+row index in the column index given by @code{@var{stats} (5)}, or zero
+if no such row index exists.  @code{@var{stats} (7)} is the number of
+duplicate or out-of-order row indices.  @code{@var{stats} (8:20)} is
+always zero in the current version of SYMAMD (reserved for future use).
+
+The ordering is followed by a column elimination tree post-ordering.
+
+
+The authors of the code itself are Stefan I. Larimore and Timothy A.
+Davis (davis@@cise.ufl.edu), University of Florida.  The algorithm was
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+Ng, Oak Ridge National Laboratory.  (see
+ at url{http://www.cise.ufl.edu/research/sparse/colamd})
+ at seealso{@ref{doc-colperm,,colperm}, @ref{doc-colamd,,colamd}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/symrcm.cc
+ at anchor{doc-symrcm}
+ at deftypefn {Loadable Function} {@var{p} =} symrcm (@var{S})
+Symmetric reverse Cuthill-McKee permutation of @var{S}.
+Return a permutation vector @var{p} such that
+ at code{@var{S} (@var{p}, @var{p})} tends to have its diagonal elements
+closer to the diagonal than @var{S}.  This is a good preordering for LU
+or Cholesky factorization of matrices that come from 'long, skinny'
+problems.  It works for both symmetric and asymmetric @var{S}.
+
+The algorithm represents a heuristic approach to the NP-complete
+bandwidth minimization problem.  The implementation is based in the
+descriptions found in
+
+E. Cuthill, J. McKee: Reducing the Bandwidth of Sparse Symmetric
+Matrices. Proceedings of the 24th ACM National Conference, 157--172
+1969, Brandon Press, New Jersey.
+
+Alan George, Joseph W. H. Liu: Computer Solution of Large Sparse
+Positive Definite Systems, Prentice Hall Series in Computational
+Mathematics, ISBN 0-13-165274-5, 1981.
+
+ at seealso{@ref{doc-colperm,,colperm}, @ref{doc-colamd,,colamd}, @ref{doc-symamd,,symamd}}
+ at end deftypefn
+
+
+ at node Sparse Linear Algebra
+ at section Linear Algebra on Sparse Matrices
+
+Octave includes a polymorphic solver for sparse matrices, where 
+the exact solver used to factorize the matrix, depends on the properties
+of the sparse matrix itself.  Generally, the cost of determining the matrix type
+is small relative to the cost of factorizing the matrix itself, but in any
+case the matrix type is cached once it is calculated, so that it is not
+re-determined each time it is used in a linear equation.
+
+The selection tree for how the linear equation is solve is
+
+ at enumerate 1
+ at item If the matrix is diagonal, solve directly and goto 8
+
+ at item If the matrix is a permuted diagonal, solve directly taking into
+account the permutations.  Goto 8
+
+ at item If the matrix is square, banded and if the band density is less
+than that given by @code{spparms ("bandden")} continue, else goto 4.
+
+ at enumerate a
+ at item If the matrix is tridiagonal and the right-hand side is not sparse 
+continue, else goto 3b.
+
+ at enumerate
+ at item If the matrix is hermitian, with a positive real diagonal, attempt
+      Cholesky factorization using @sc{lapack} xPTSV.
+
+ at item If the above failed or the matrix is not hermitian with a positive
+      real diagonal use Gaussian elimination with pivoting using 
+      @sc{lapack} xGTSV, and goto 8.
+ at end enumerate
+
+ at item If the matrix is hermitian with a positive real diagonal, attempt
+      Cholesky factorization using @sc{lapack} xPBTRF.
+
+ at item if the above failed or the matrix is not hermitian with a positive
+      real diagonal use Gaussian elimination with pivoting using 
+      @sc{lapack} xGBTRF, and goto 8.
+ at end enumerate
+
+ at item If the matrix is upper or lower triangular perform a sparse forward
+or backward substitution, and goto 8
+
+ at item If the matrix is a upper triangular matrix with column permutations
+or lower triangular matrix with row permutations, perform a sparse forward 
+or backward substitution, and goto 8
+
+ at item If the matrix is square, hermitian with a real positive diagonal, attempt
+sparse Cholesky factorization using CHOLMOD.
+
+ at item If the sparse Cholesky factorization failed or the matrix is not
+hermitian with a real positive diagonal, and the matrix is square, factorize 
+using UMFPACK.
+
+ at item If the matrix is not square, or any of the previous solvers flags
+a singular or near singular matrix, find a minimum norm solution using
+CXSPARSE at footnote{The CHOLMOD, UMFPACK and CXSPARSE packages were
+written by Tim Davis and are available at
+http://www.cise.ufl.edu/research/sparse/}.
+ at end enumerate
+
+The band density is defined as the number of non-zero values in the matrix
+divided by the number of non-zero values in the matrix.  The banded matrix
+solvers can be entirely disabled by using @dfn{spparms} to set @code{bandden}
+to 1 (i.e., @code{spparms ("bandden", 1)}).
+
+The QR solver factorizes the problem with a Dulmage-Mendelsohn, to
+separate the problem into blocks that can be treated as over-determined,
+multiple well determined blocks, and a final over-determined block.  For
+matrices with blocks of strongly connected nodes this is a big win as
+LU decomposition can be used for many blocks.  It also significantly
+improves the chance of finding a solution to over-determined problems
+rather than just returning a vector of @dfn{NaN}'s.
+
+All of the solvers above, can calculate an estimate of the condition
+number.  This can be used to detect numerical stability problems in the
+solution and force a minimum norm solution to be used.  However, for
+narrow banded, triangular or diagonal matrices, the cost of
+calculating the condition number is significant, and can in fact
+exceed the cost of factoring the matrix.  Therefore the condition
+number is not calculated in these cases, and Octave relies on simpler
+techniques to detect singular matrices or the underlying @sc{lapack} code in
+the case of banded matrices.
+
+The user can force the type of the matrix with the @code{matrix_type}
+function.  This overcomes the cost of discovering the type of the matrix.
+However, it should be noted that identifying the type of the matrix incorrectly
+will lead to unpredictable results, and so @code{matrix_type} should be
+used with care.
+
+ at c ./sparse/normest.m
+ at anchor{doc-normest}
+ at deftypefn {Function File} {[@var{n}, @var{c}] =} normest (@var{a}, @var{tol})
+Estimate the 2-norm of the matrix @var{a} using a power series
+analysis.  This is typically used for large matrices, where the cost
+of calculating the @code{norm (@var{a})} is prohibitive and an approximation
+to the 2-norm is acceptable.
+
+ at var{tol} is the tolerance to which the 2-norm is calculated.  By default
+ at var{tol} is 1e-6.  @var{c} returns the number of iterations needed for
+ at code{normest} to converge.
+ at end deftypefn
+
+
+ at c ./linear-algebra/onenormest.m
+ at anchor{doc-onenormest}
+ at deftypefn {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{a}, @var{t}) 
+ at deftypefnx {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{apply}, @var{apply_t}, @var{n}, @var{t})
+
+Apply Higham and Tisseur's randomized block 1-norm estimator to
+matrix @var{a} using @var{t} test vectors.  If @var{t} exceeds 5, then
+only 5 test vectors are used.
+
+If the matrix is not explicit, e.g., when estimating the norm of 
+ at code{inv (@var{A})} given an LU factorization, @code{onenormest} applies 
+ at var{A} and its conjugate transpose through a pair of functions 
+ at var{apply} and @var{apply_t}, respectively, to a dense matrix of size 
+ at var{n} by @var{t}.  The implicit version requires an explicit dimension 
+ at var{n}.
+
+Returns the norm estimate @var{est}, two vectors @var{v} and
+ at var{w} related by norm
+ at code{(@var{w}, 1) = @var{est} * norm (@var{v}, 1)},
+and the number of iterations @var{iter}.  The number of
+iterations is limited to 10 and is at least 2.
+
+References: 
+ at itemize
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+ at url{http://dx.doi.org/10.1137/S0895479899356080}
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." @url{http://citeseer.ist.psu.edu/223007.html}
+ at end itemize
+
+ at seealso{@ref{doc-condest,,condest}, @ref{doc-norm,,norm}, @ref{doc-cond,,cond}}
+ at end deftypefn
+
+
+ at c ./linear-algebra/condest.m
+ at anchor{doc-condest}
+ at deftypefn {Function File} {[@var{est}, @var{v}] =} condest (@var{a}, @var{t}) 
+ at deftypefnx {Function File} {[@var{est}, @var{v}] =} condest (@var{a}, @var{solve}, @var{solve_t}, @var{t})
+ at deftypefnx {Function File} {[@var{est}, @var{v}] =} condest (@var{apply}, @var{apply_t}, @var{solve}, @var{solve_t}, @var{n}, @var{t})
+
+Estimate the 1-norm condition number of a matrix @var{A}
+using @var{t} test vectors using a randomized 1-norm estimator.
+If @var{t} exceeds 5, then only 5 test vectors are used.
+
+If the matrix is not explicit, e.g., when estimating the condition 
+number of @var{a} given an LU factorization, @code{condest} uses the 
+following functions:
+
+ at table @var
+ at item apply
+ at code{A*x} for a matrix @code{x} of size @var{n} by @var{t}.
+ at item apply_t
+ at code{A'*x} for a matrix @code{x} of size @var{n} by @var{t}.
+ at item solve
+ at code{A \ b} for a matrix @code{b} of size @var{n} by @var{t}.
+ at item solve_t
+ at code{A' \ b} for a matrix @code{b} of size @var{n} by @var{t}.
+ at end table
+
+The implicit version requires an explicit dimension @var{n}.
+
+ at code{condest} uses a randomized algorithm to approximate
+the 1-norms.
+
+ at code{condest} returns the 1-norm condition estimate @var{est} and
+a vector @var{v} satisfying @code{norm (A*v, 1) == norm (A, 1) * norm
+(@var{v}, 1) / @var{est}}.  When @var{est} is large, @var{v} is an
+approximate null vector.
+
+References: 
+ at itemize
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+ at url{http://dx.doi.org/10.1137/S0895479899356080}
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." @url{http://citeseer.ist.psu.edu/223007.html}
+ at end itemize
+
+ at seealso{@ref{doc-cond,,cond}, @ref{doc-norm,,norm}, @ref{doc-onenormest,,onenormest}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/spparms.cc
+ at anchor{doc-spparms}
+ at deftypefn {Loadable Function} { } spparms ()
+ at deftypefnx {Loadable Function} {@var{vals} =} spparms ()
+ at deftypefnx {Loadable Function} {[@var{keys}, @var{vals}] =} spparms ()
+ at deftypefnx {Loadable Function} {@var{val} =} spparms (@var{key})
+ at deftypefnx {Loadable Function} { } spparms (@var{vals})
+ at deftypefnx {Loadable Function} { } spparms ('defaults')
+ at deftypefnx {Loadable Function} { } spparms ('tight')
+ at deftypefnx {Loadable Function} { } spparms (@var{key}, @var{val})
+Sets or displays the parameters used by the sparse solvers and factorization
+functions.  The first four calls above get information about the current
+settings, while the others change the current settings.  The parameters are
+stored as pairs of keys and values, where the values are all floats and the
+keys are one of the following strings:
+
+ at table @code
+ at item spumoni
+Printing level of debugging information of the solvers (default 0)
+ at item ths_rel
+Included for compatibility.  Not used.  (default 1)
+ at item ths_abs
+Included for compatibility.  Not used.  (default 1)
+ at item exact_d
+Included for compatibility.  Not used.  (default 0)
+ at item supernd
+Included for compatibility.  Not used.  (default 3)
+ at item rreduce
+Included for compatibility.  Not used.  (default 3)
+ at item wh_frac
+Included for compatibility.  Not used.  (default 0.5)
+ at item autommd
+Flag whether the LU/QR and the '\' and '/' operators will automatically
+use the sparsity preserving mmd functions (default 1)
+ at item autoamd
+Flag whether the LU and the '\' and '/' operators will automatically
+use the sparsity preserving amd functions (default 1)
+ at item piv_tol
+The pivot tolerance of the UMFPACK solvers (default 0.1)
+ at item sym_tol
+The pivot tolerance of the UMFPACK symmetric solvers (default 0.001)
+ at item bandden
+The density of non-zero elements in a banded matrix before it is treated
+by the @sc{lapack} banded solvers (default 0.5)
+ at item umfpack
+Flag whether the UMFPACK or mmd solvers are used for the LU, '\' and
+'/' operations (default 1)
+ at end table
+
+The value of individual keys can be set with @code{spparms (@var{key},
+ at var{val})}.  The default values can be restored with the special keyword
+'defaults'.  The special keyword 'tight' can be used to set the mmd solvers
+to attempt for a sparser solution at the potential cost of longer running
+time.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/dmperm.cc
+ at anchor{doc-sprank}
+ at deftypefn {Loadable Function} {@var{p} =} sprank (@var{s})
+
+ at cindex Structural Rank
+Calculates the structural rank of a sparse matrix @var{s}.  Note that
+only the structure of the matrix is used in this calculation based on
+a Dulmage-Mendelsohn permutation to block triangular form.  As such the numerical
+rank of the matrix @var{s} is bounded by @code{sprank (@var{s}) >=
+rank (@var{s})}.  Ignoring floating point errors @code{sprank (@var{s}) ==
+rank (@var{s})}.
+ at seealso{@ref{doc-dmperm,,dmperm}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/symbfact.cc
+ at anchor{doc-symbfact}
+ at deftypefn {Loadable Function} {[@var{count}, @var{h}, @var{parent}, @var{post}, @var{r}] =} symbfact (@var{s}, @var{typ}, @var{mode})
+
+Performs a symbolic factorization analysis on the sparse matrix @var{s}.
+Where
+
+ at table @asis
+ at item @var{s}
+ at var{s} is a complex or real sparse matrix.
+
+ at item @var{typ}
+Is the type of the factorization and can be one of
+
+ at table @code
+ at item sym
+Factorize @var{s}.  This is the default.
+
+ at item col
+Factorize @code{@var{s}' * @var{s}}.
+ at item row
+Factorize @code{@var{s} * @var{s}'}.
+ at item lo
+Factorize @code{@var{s}'}
+ at end table
+
+ at item @var{mode}
+The default is to return the Cholesky factorization for @var{r}, and if
+ at var{mode} is 'L', the conjugate transpose of the Cholesky factorization
+is returned.  The conjugate transpose version is faster and uses less
+memory, but returns the same values for @var{count}, @var{h}, @var{parent}
+and @var{post} outputs.
+ at end table
+
+The output variables are
+
+ at table @asis
+ at item @var{count}
+The row counts of the Cholesky factorization as determined by @var{typ}.
+
+ at item @var{h}
+The height of the elimination tree.
+
+ at item @var{parent}
+The elimination tree itself.
+
+ at item @var{post}
+A sparse boolean matrix whose structure is that of the Cholesky
+factorization as determined by @var{typ}.
+ at end table
+ at end deftypefn
+
+
+For non square matrices, the user can also utilize the @code{spaugment}
+function to find a least squares solution to a linear equation.
+
+ at c ./sparse/spaugment.m
+ at anchor{doc-spaugment}
+ at deftypefn {Function File} {@var{s} =} spaugment (@var{a}, @var{c})
+Creates the augmented matrix of @var{a}.  This is given by
+
+ at example
+ at group
+[@var{c} * eye(@var{m}, @var{m}), at var{a}; @var{a}', zeros(@var{n},
+ at var{n})]
+ at end group
+ at end example
+
+ at noindent
+This is related to the least squares solution of 
+ at code{@var{a} \\ @var{b}}, by
+
+ at example
+ at group
+ at var{s} * [ @var{r} / @var{c}; x] = [@var{b}, zeros(@var{n},
+columns(@var{b})]
+ at end group
+ at end example
+
+ at noindent
+where @var{r} is the residual error
+
+ at example
+ at var{r} = @var{b} - @var{a} * @var{x}
+ at end example
+
+As the matrix @var{s} is symmetric indefinite it can be factorized
+with @code{lu}, and the minimum norm solution can therefore be found
+without the need for a @code{qr} factorization.  As the residual
+error will be @code{zeros (@var{m}, @var{m})} for under determined
+problems, and example can be 
+
+ at example
+ at group
+m = 11; n = 10; mn = max(m ,n);
+a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],
+             [-1, 0, 1], m, n);
+x0 = a \ ones (m,1);
+s = spaugment (a);
+[L, U, P, Q] = lu (s);
+x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+x1 = x1(end - n + 1 : end);
+ at end group
+ at end example
+
+To find the solution of an overdetermined problem needs an estimate
+of the residual error @var{r} and so it is more complex to formulate
+a minimum norm solution using the @code{spaugment} function.
+
+In general the left division operator is more stable and faster than
+using the @code{spaugment} function.
+ at end deftypefn
+
+
+Finally, the function @code{eigs} can be used to calculate a limited
+number of eigenvalues and eigenvectors based on a selection criteria
+and likewise for @code{svds} which calculates a limited number of
+singular values and vectors.
+
+ at c ./DLD-FUNCTIONS/eigs.cc
+ at anchor{doc-eigs}
+ at deftypefn {Loadable Function} {@var{d}} = eigs (@var{a})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k}, @var{sigma}, at var{opts})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}]} = eigs (@var{a}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}]} = eigs (@var{af}, @var{n}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}, @var{flag}]} = eigs (@var{a}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}, @var{flag}]} = eigs (@var{af}, @var{n}, @dots{})
+Calculate a limited number of eigenvalues and eigenvectors of @var{a},
+based on a selection criteria.  The number eigenvalues and eigenvectors to
+calculate is given by @var{k} whose default value is 6.
+
+By default @code{eigs} solve the equation
+ at iftex
+ at tex
+$A \nu = \lambda \nu$
+ at end tex
+ at end iftex
+ at ifinfo
+ at code{A * v = lambda * v}
+ at end ifinfo
+, where
+ at iftex
+ at tex
+$\lambda$ is a scalar representing one of the eigenvalues, and $\nu$
+ at end tex
+ at end iftex
+ at ifinfo
+ at code{lambda} is a scalar representing one of the eigenvalues, and @code{v}
+ at end ifinfo
+is the corresponding eigenvector.  If given the positive definite matrix
+ at var{B} then @code{eigs} solves the general eigenvalue equation
+ at iftex
+ at tex
+$A \nu = \lambda B \nu$
+ at end tex
+ at end iftex
+ at ifinfo
+ at code{A * v = lambda * B * v}
+ at end ifinfo
+.
+
+The argument @var{sigma} determines which eigenvalues are returned.
+ at var{sigma} can be either a scalar or a string.  When @var{sigma} is a scalar,
+the @var{k} eigenvalues closest to @var{sigma} are returned.  If @var{sigma}
+is a string, it must have one of the values
+
+ at table @asis
+ at item 'lm'
+Largest magnitude (default).
+
+ at item 'sm'
+Smallest magnitude.
+
+ at item 'la'
+Largest Algebraic (valid only for real symmetric problems).
+
+ at item 'sa'
+Smallest Algebraic (valid only for real symmetric problems).
+
+ at item 'be'
+Both ends, with one more from the high-end if @var{k} is odd (valid only for
+real symmetric problems).
+
+ at item 'lr'
+Largest real part (valid only for complex or unsymmetric problems).
+
+ at item 'sr'
+Smallest real part (valid only for complex or unsymmetric problems).
+
+ at item 'li'
+Largest imaginary part (valid only for complex or unsymmetric problems).
+
+ at item 'si'
+Smallest imaginary part (valid only for complex or unsymmetric problems).
+ at end table
+
+If @var{opts} is given, it is a structure defining some of the options that
+ at code{eigs} should use.  The fields of the structure @var{opts} are
+
+ at table @code
+ at item issym
+If @var{af} is given, then flags whether the function @var{af} defines a
+symmetric problem.  It is ignored if @var{a} is given.  The default is false.
+
+ at item isreal
+If @var{af} is given, then flags whether the function @var{af} defines a
+real problem.  It is ignored if @var{a} is given.  The default is true.
+
+ at item tol
+Defines the required convergence tolerance, given as @code{tol * norm (A)}.
+The default is @code{eps}.
+
+ at item maxit
+The maximum number of iterations.  The default is 300.
+
+ at item p
+The number of Lanzcos basis vectors to use.  More vectors will result in
+faster convergence, but a larger amount of memory.  The optimal value of 'p'
+is problem dependent and should be in the range @var{k} to @var{n}.  The
+default value is @code{2 * @var{k}}.
+
+ at item v0
+The starting vector for the computation.  The default is to have @sc{Arpack}
+randomly generate a starting vector.
+
+ at item disp
+The level of diagnostic printout.  If @code{disp} is 0 then there is no
+printout.  The default value is 1.
+
+ at item cholB
+Flag if @code{chol (@var{b})} is passed rather than @var{b}.  The default is
+false.
+
+ at item permB
+The permutation vector of the Cholesky factorization of @var{b} if
+ at code{cholB} is true.  That is @code{chol ( @var{b} (permB, permB))}.  The
+default is @code{1:@var{n}}.
+
+ at end table
+
+It is also possible to represent @var{a} by a function denoted @var{af}.
+ at var{af} must be followed by a scalar argument @var{n} defining the length
+of the vector argument accepted by @var{af}.  @var{af} can be passed either
+as an inline function, function handle or as a string.  In the case where
+ at var{af} is passed as a string, the name of the string defines the function
+to use.
+
+ at var{af} is a function of the form @code{function y = af (x), y = @dots{};
+endfunction}, where the required return value of @var{af} is determined by
+the value of @var{sigma}, and are
+
+ at table @code
+ at item A * x
+If @var{sigma} is not given or is a string other than 'sm'.
+
+ at item A \ x
+If @var{sigma} is 'sm'.
+
+ at item (A - sigma * I) \ x
+for standard eigenvalue problem, where @code{I} is the identity matrix of
+the same size as @code{A}.  If @var{sigma} is zero, this reduces the
+ at code{A \ x}.
+
+ at item (A - sigma * B) \ x
+for the general eigenvalue problem.
+ at end table
+
+The return arguments of @code{eigs} depends on the number of return
+arguments.  With a single return argument, a vector @var{d} of length @var{k}
+is returned, represent the @var{k} eigenvalues that have been found.  With two
+return arguments, @var{v} is a @var{n}-by- at var{k} matrix whose columns are
+the @var{k} eigenvectors corresponding to the returned eigenvalues.  The
+eigenvalues themselves are then returned in @var{d} in the form of a
+ at var{n}-by- at var{k} matrix, where the elements on the diagonal are the
+eigenvalues.
+
+Given a third return argument @var{flag}, @code{eigs} also returns the status
+of the convergence.  If @var{flag} is 0, then all eigenvalues have converged,
+otherwise not.
+
+This function is based on the @sc{Arpack} package, written by R Lehoucq,
+K Maschhoff, D Sorensen and C Yang.  For more information see
+ at url{http://www.caam.rice.edu/software/ARPACK/}.
+
+ at end deftypefn
+ at seealso{@ref{doc-eig,,eig}, @ref{doc-svds,,svds}}
+
+
+ at c ./sparse/svds.m
+ at anchor{doc-svds}
+ at deftypefn {Function File} {@var{s} =} svds (@var{a})
+ at deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k})
+ at deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k}, @var{sigma})
+ at deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Function File} {[@var{u}, @var{s}, @var{v}, @var{flag}] =} svds (@dots{})
+
+Find a few singular values of the matrix @var{a}.  The singular values
+are calculated using 
+
+ at example
+ at group
+[@var{m}, @var{n}] = size(@var{a})
+ at var{s} = eigs([sparse(@var{m}, @var{m}), @var{a}; ...
+                @var{a}', sparse(@var{n}, @var{n})])
+ at end group
+ at end example
+
+The eigenvalues returned by @code{eigs} correspond to the singular
+values of @var{a}.  The number of singular values to calculate is given
+by @var{k}, whose default value is 6.
+
+The argument @var{sigma} can be used to specify which singular values
+to find.  @var{sigma} can be either the string 'L', the default, in 
+which case the largest singular values of @var{a} are found.  Otherwise
+ at var{sigma} should be a real scalar, in which case the singular values
+closest to @var{sigma} are found.  Note that for relatively small values
+of @var{sigma}, there is the chance that the requested number of singular
+values are not returned.  In that case @var{sigma} should be increased.
+
+If @var{opts} is given, then it is a structure that defines options
+that @code{svds} will pass to @var{eigs}.  The possible fields of this
+structure are therefore determined by @code{eigs}.  By default three
+fields of this structure are set by @code{svds}.
+
+ at table @code
+ at item tol
+The required convergence tolerance for the singular values.  @code{eigs}
+is passed @var{tol} divided by @code{sqrt(2)}.  The default value is 
+1e-10.
+
+ at item maxit
+The maximum number of iterations.  The default is 300.
+
+ at item disp
+The level of diagnostic printout.  If @code{disp} is 0 then there is no
+printout.  The default value is 0.
+ at end table
+
+If more than one output argument is given, then @code{svds} also
+calculates the left and right singular vectors of @var{a}.  @var{flag}
+is used to signal the convergence of @code{svds}.  If @code{svds} 
+converges to the desired tolerance, then @var{flag} given by
+
+ at example
+ at group
+norm (@var{a} * @var{v} - @var{u} * @var{s}, 1) <= ...
+        @var{tol} * norm (@var{a}, 1)
+ at end group
+ at end example
+
+will be zero.
+ at end deftypefn
+ at seealso{@ref{doc-eigs,,eigs}}
+
+
+ at node Iterative Techniques
+ at section Iterative Techniques applied to sparse matrices
+
+The left division @code{\} and right division @code{/} operators,
+discussed in the previous section, use direct solvers to resolve a
+linear equation of the form @code{@var{x} = @var{A} \ @var{b}} or
+ at code{@var{x} = @var{b} / @var{A}}.  Octave equally includes a number of
+functions to solve sparse linear equations using iterative techniques.
+
+ at c ./sparse/pcg.m
+ at anchor{doc-pcg}
+ at deftypefn {Function File} {@var{x} =} pcg (@var{a}, @var{b}, @var{tol}, @var{maxit}, @var{m1}, @var{m2}, @var{x0}, @dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}, @var{eigest}] =} pcg (@dots{})
+
+Solves the linear system of equations @code{@var{a} * @var{x} =
+ at var{b}} by means of the Preconditioned Conjugate Gradient iterative
+method.  The input arguments are
+
+ at itemize
+ at item
+ at var{a} can be either a square (preferably sparse) matrix or a
+function handle, inline function or string containing the name
+of a function which computes @code{@var{a} * @var{x}}.  In principle
+ at var{a} should be symmetric and positive definite; if @code{pcg}
+finds @var{a} to not be positive definite, you will get a warning
+message and the @var{flag} output parameter will be set.
+
+ at item
+ at var{b} is the right hand side vector.
+
+ at item
+ at var{tol} is the required relative tolerance for the residual error,
+ at code{@var{b} - @var{a} * @var{x}}.  The iteration stops if @code{norm
+(@var{b} - @var{a} * @var{x}) <= @var{tol} * norm (@var{b} - @var{a} *
+ at var{x0})}.  If @var{tol} is empty or is omitted, the function sets
+ at code{@var{tol} = 1e-6} by default.
+
+ at item
+ at var{maxit} is the maximum allowable number of iterations; if
+ at code{[]} is supplied for @code{maxit}, or @code{pcg} has less
+arguments, a default value equal to 20 is used.
+
+ at item
+ at var{m} = @var{m1} * @var{m2} is the (left) preconditioning matrix, so that the iteration is
+(theoretically) equivalent to solving by @code{pcg} @code{@var{P} *
+ at var{x} = @var{m} \ @var{b}}, with @code{@var{P} = @var{m} \ @var{a}}.
+Note that a proper choice of the preconditioner may dramatically
+improve the overall performance of the method.  Instead of matrices
+ at var{m1} and @var{m2}, the user may pass two functions which return 
+the results of applying the inverse of @var{m1} and @var{m2} to 
+a vector (usually this is the preferred way of using the preconditioner). 
+If @code{[]} is supplied for @var{m1}, or @var{m1} is omitted, no 
+preconditioning is applied.  If @var{m2} is omitted, @var{m} = @var{m1}
+will be used as preconditioner.
+
+ at item
+ at var{x0} is the initial guess.  If @var{x0} is empty or omitted, the 
+function sets @var{x0} to a zero vector by default.
+ at end itemize
+
+The arguments which follow @var{x0} are treated as parameters, and
+passed in a proper way to any of the functions (@var{a} or @var{m})
+which are passed to @code{pcg}.  See the examples below for further
+details.  The output arguments are
+
+ at itemize
+ at item
+ at var{x} is the computed approximation to the solution of
+ at code{@var{a} * @var{x} = @var{b}}.
+
+ at item
+ at var{flag} reports on the convergence.  @code{@var{flag} = 0} means
+the solution converged and the tolerance criterion given by @var{tol}
+is satisfied.  @code{@var{flag} = 1} means that the @var{maxit} limit
+for the iteration count was reached.  @code{@var{flag} = 3} reports that
+the (preconditioned) matrix was found not positive definite.
+
+ at item
+ at var{relres} is the ratio of the final residual to its initial value,
+measured in the Euclidean norm.
+
+ at item
+ at var{iter} is the actual number of iterations performed.
+
+ at item 
+ at var{resvec} describes the convergence history of the method.
+ at code{@var{resvec} (i,1)} is the Euclidean norm of the residual, and
+ at code{@var{resvec} (i,2)} is the preconditioned residual norm,
+after the (@var{i}-1)-th iteration, @code{@var{i} =
+1, 2, @dots{}, @var{iter}+1}.  The preconditioned residual norm
+is defined as
+ at code{norm (@var{r}) ^ 2 = @var{r}' * (@var{m} \ @var{r})} where
+ at code{@var{r} = @var{b} - @var{a} * @var{x}}, see also the
+description of @var{m}.  If @var{eigest} is not required, only
+ at code{@var{resvec} (:,1)} is returned.
+
+ at item
+ at var{eigest} returns the estimate for the smallest @code{@var{eigest}
+(1)} and largest @code{@var{eigest} (2)} eigenvalues of the
+preconditioned matrix @code{@var{P} = @var{m} \ @var{a}}.  In 
+particular, if no preconditioning is used, the estimates for the
+extreme eigenvalues of @var{a} are returned.  @code{@var{eigest} (1)}
+is an overestimate and @code{@var{eigest} (2)} is an underestimate, 
+so that @code{@var{eigest} (2) / @var{eigest} (1)} is a lower bound
+for @code{cond (@var{P}, 2)}, which nevertheless in the limit should
+theoretically be equal to the actual value of the condition number. 
+The method which computes @var{eigest} works only for symmetric positive
+definite @var{a} and @var{m}, and the user is responsible for
+verifying this assumption. 
+ at end itemize
+
+Let us consider a trivial problem with a diagonal matrix (we exploit the
+sparsity of A) 
+
+ at example
+ at group
+	n = 10; 
+	a = diag (sparse (1:n));
+	b = rand (n, 1);
+     [l, u, p, q] = luinc (a, 1.e-3);
+ at end group
+ at end example
+
+ at sc{Example 1:} Simplest use of @code{pcg}
+
+ at example
+  x = pcg(A,b)
+ at end example
+
+ at sc{Example 2:} @code{pcg} with a function which computes
+ at code{@var{a} * @var{x}}
+
+ at example
+ at group
+  function y = apply_a (x)
+    y = [1:N]'.*x; 
+  endfunction
+
+  x = pcg ("apply_a", b)
+ at end group
+ at end example
+
+ at sc{Example 3:} @code{pcg} with a preconditioner: @var{l} * @var{u}
+
+ at example
+x = pcg (a, b, 1.e-6, 500, l*u);
+ at end example
+
+ at sc{Example 4:} @code{pcg} with a preconditioner: @var{l} * @var{u}.
+Faster than @sc{Example 3} since lower and upper triangular matrices 
+are easier to invert
+
+ at example
+x = pcg (a, b, 1.e-6, 500, l, u);
+ at end example
+
+ at sc{Example 5:} Preconditioned iteration, with full diagnostics.  The
+preconditioner (quite strange, because even the original matrix
+ at var{a} is trivial) is defined as a function
+
+ at example
+ at group
+  function y = apply_m (x)
+    k = floor (length (x) - 2);
+    y = x;
+    y(1:k) = x(1:k)./[1:k]';
+  endfunction
+
+  [x, flag, relres, iter, resvec, eigest] = ...
+                     pcg (a, b, [], [], "apply_m");
+  semilogy (1:iter+1, resvec);
+ at end group
+ at end example
+
+ at sc{Example 6:} Finally, a preconditioner which depends on a
+parameter @var{k}.
+
+ at example
+ at group
+  function y = apply_M (x, varargin)
+  K = varargin@{1@}; 
+  y = x;
+  y(1:K) = x(1:K)./[1:K]';
+  endfunction
+
+  [x, flag, relres, iter, resvec, eigest] = ...
+       pcg (A, b, [], [], "apply_m", [], [], 3)
+ at end group
+ at end example
+
+ at sc{References}
+
+	[1] C.T.Kelley, 'Iterative methods for linear and nonlinear equations',
+	SIAM, 1995 (the base PCG algorithm) 
+	
+	[2] Y.Saad, 'Iterative methods for sparse linear systems', PWS 1996
+	(condition number estimate from PCG) Revised version of this book is
+	available online at http://www-users.cs.umn.edu/~saad/books.html
+
+
+ at seealso{@ref{doc-sparse,,sparse}, @ref{doc-pcr,,pcr}}
+ at end deftypefn
+
+
+ at c ./sparse/pcr.m
+ at anchor{doc-pcr}
+ at deftypefn {Function File} {@var{x} =} pcr (@var{a}, @var{b}, @var{tol}, @var{maxit}, @var{m}, @var{x0}, @dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} pcr (@dots{})
+
+Solves the linear system of equations @code{@var{a} * @var{x} =
+ at var{b}} by means of the Preconditioned Conjugate Residuals iterative
+method.  The input arguments are
+
+ at itemize
+ at item
+ at var{a} can be either a square (preferably sparse) matrix or a
+function handle, inline function or string containing the name
+of a function which computes @code{@var{a} * @var{x}}.  In principle
+ at var{a} should be symmetric and non-singular; if @code{pcr}
+finds @var{a} to be numerically singular, you will get a warning
+message and the @var{flag} output parameter will be set.
+
+ at item
+ at var{b} is the right hand side vector.
+
+ at item
+ at var{tol} is the required relative tolerance for the residual error,
+ at code{@var{b} - @var{a} * @var{x}}.  The iteration stops if @code{norm
+(@var{b} - @var{a} * @var{x}) <= @var{tol} * norm (@var{b} - @var{a} *
+ at var{x0})}.  If @var{tol} is empty or is omitted, the function sets
+ at code{@var{tol} = 1e-6} by default.
+
+ at item
+ at var{maxit} is the maximum allowable number of iterations; if
+ at code{[]} is supplied for @code{maxit}, or @code{pcr} has less
+arguments, a default value equal to 20 is used.
+
+ at item
+ at var{m} is the (left) preconditioning matrix, so that the iteration is
+(theoretically) equivalent to solving by @code{pcr} @code{@var{P} *
+ at var{x} = @var{m} \ @var{b}}, with @code{@var{P} = @var{m} \ @var{a}}.
+Note that a proper choice of the preconditioner may dramatically
+improve the overall performance of the method.  Instead of matrix
+ at var{m}, the user may pass a function which returns the results of 
+applying the inverse of @var{m} to a vector (usually this is the
+preferred way of using the preconditioner).  If @code{[]} is supplied
+for @var{m}, or @var{m} is omitted, no preconditioning is applied.
+
+ at item
+ at var{x0} is the initial guess.  If @var{x0} is empty or omitted, the 
+function sets @var{x0} to a zero vector by default.
+ at end itemize
+
+The arguments which follow @var{x0} are treated as parameters, and
+passed in a proper way to any of the functions (@var{a} or @var{m})
+which are passed to @code{pcr}.  See the examples below for further
+details.  The output arguments are
+
+ at itemize
+ at item
+ at var{x} is the computed approximation to the solution of
+ at code{@var{a} * @var{x} = @var{b}}.
+
+ at item
+ at var{flag} reports on the convergence.  @code{@var{flag} = 0} means
+the solution converged and the tolerance criterion given by @var{tol}
+is satisfied.  @code{@var{flag} = 1} means that the @var{maxit} limit
+for the iteration count was reached.  @code{@var{flag} = 3} reports t
+ at code{pcr} breakdown, see [1] for details.
+
+ at item
+ at var{relres} is the ratio of the final residual to its initial value,
+measured in the Euclidean norm.
+
+ at item
+ at var{iter} is the actual number of iterations performed.
+
+ at item 
+ at var{resvec} describes the convergence history of the method,
+so that @code{@var{resvec} (i)} contains the Euclidean norms of the 
+residual after the (@var{i}-1)-th iteration, @code{@var{i} =
+1,2, @dots{}, @var{iter}+1}.
+ at end itemize
+
+Let us consider a trivial problem with a diagonal matrix (we exploit the
+sparsity of A) 
+
+ at example
+ at group
+	n = 10; 
+	a = sparse (diag (1:n));
+	b = rand (N, 1);
+ at end group
+ at end example
+
+ at sc{Example 1:} Simplest use of @code{pcr}
+
+ at example
+  x = pcr(A, b)
+ at end example
+
+ at sc{Example 2:} @code{pcr} with a function which computes
+ at code{@var{a} * @var{x}}.
+
+ at example
+ at group
+  function y = apply_a (x) 
+    y = [1:10]'.*x; 
+  endfunction
+
+  x = pcr ("apply_a", b)
+ at end group
+ at end example
+
+ at sc{Example 3:}  Preconditioned iteration, with full diagnostics.  The
+preconditioner (quite strange, because even the original matrix
+ at var{a} is trivial) is defined as a function
+
+ at example
+ at group
+  function y = apply_m (x)		
+    k = floor (length(x)-2); 
+    y = x; 
+    y(1:k) = x(1:k)./[1:k]';	
+  endfunction
+
+  [x, flag, relres, iter, resvec] = ...
+                     pcr (a, b, [], [], "apply_m")
+  semilogy([1:iter+1], resvec);
+ at end group
+ at end example
+
+ at sc{Example 4:} Finally, a preconditioner which depends on a
+parameter @var{k}.
+
+ at example
+ at group
+  function y = apply_m (x, varargin)
+    k = varargin@{1@}; 
+    y = x; y(1:k) = x(1:k)./[1:k]';	 
+  endfunction
+
+  [x, flag, relres, iter, resvec] = ...
+                     pcr (a, b, [], [], "apply_m"', [], 3)
+ at end group
+ at end example
+
+ at sc{References}
+
+	[1] W. Hackbusch, "Iterative Solution of Large Sparse Systems of
+ 	Equations", section 9.5.4; Springer, 1994
+
+ at seealso{@ref{doc-sparse,,sparse}, @ref{doc-pcg,,pcg}}
+ at end deftypefn
+
+
+The speed with which an iterative solver converges to a solution can be
+accelerated with the use of a pre-conditioning matrix @var{M}.  In this
+case the linear equation @code{@var{M}^-1 * @var{x} = @var{M}^-1 *
+ at var{A} \ @var{b}} is solved instead.  Typical pre-conditioning matrices
+are partial factorizations of the original matrix.
+
+ at c ./DLD-FUNCTIONS/luinc.cc
+ at anchor{doc-luinc}
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, '0')
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, @var{droptol})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, @var{opts})
+ at cindex LU decomposition
+Produce the incomplete LU factorization of the sparse matrix @var{a}.
+Two types of incomplete factorization are possible, and the type
+is determined by the second argument to @dfn{luinc}.
+
+Called with a second argument of '0', the zero-level incomplete
+LU factorization is produced.  This creates a factorization of @var{a}
+where the position of the non-zero arguments correspond to the same
+positions as in the matrix @var{a}.
+
+Alternatively, the fill-in of the incomplete LU factorization can
+be controlled through the variable @var{droptol} or the structure
+ at var{opts}.  The UMFPACK multifrontal factorization code by Tim A.
+Davis is used for the incomplete LU factorization, (availability
+ at url{http://www.cise.ufl.edu/research/sparse/umfpack/})
+
+ at var{droptol} determines the values below which the values in the LU
+factorization are dropped and replaced by zero.  It must be a positive
+scalar, and any values in the factorization whose absolute value are
+less than this value are dropped, expect if leaving them increase the
+sparsity of the matrix.  Setting @var{droptol} to zero results in a
+complete LU factorization which is the default.
+
+ at var{opts} is a structure containing one or more of the fields
+
+ at table @code
+ at item droptol
+The drop tolerance as above.  If @var{opts} only contains @code{droptol}
+then this is equivalent to using the variable @var{droptol}.
+
+ at item milu
+A logical variable flagging whether to use the modified incomplete LU
+factorization.  In the case that @code{milu} is true, the dropped values
+are subtracted from the diagonal of the matrix U of the factorization.
+The default is @code{false}.
+
+ at item udiag
+A logical variable that flags whether zero elements on the diagonal of U
+should be replaced with @var{droptol} to attempt to avoid singular
+factors.  The default is @code{false}.
+
+ at item thresh
+Defines the pivot threshold in the interval [0,1].  Values outside that
+range are ignored.
+ at end table
+
+All other fields in @var{opts} are ignored.  The outputs from @dfn{luinc}
+are the same as for @dfn{lu}.
+
+Given the string argument 'vector', @dfn{luinc} returns the values of @var{p}
+ at var{q} as vector values.
+ at seealso{@ref{doc-sparse,,sparse}, @ref{doc-lu,,lu}}
+ at end deftypefn
+
+
+ at node Real Life Example
+ at section Real Life Example of the use of Sparse Matrices
+
+A common application for sparse matrices is in the solution of Finite
+Element Models.  Finite element models allow numerical solution of
+partial differential equations that do not have closed form solutions,
+typically because of the complex shape of the domain.
+
+In order to motivate this application, we consider the boundary value
+Laplace equation.  This system can model scalar potential fields, such
+as heat or electrical potential.  Given a medium 
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+with boundary
+ at tex
+$\partial\Omega$ 
+ at end tex
+ at ifinfo
+dOmega
+ at end ifinfo
+. At all points on the 
+ at tex
+$\partial\Omega$ 
+ at end tex
+ at ifinfo
+dOmega
+ at end ifinfo
+the boundary conditions are known, and we wish to calculate the potential in
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+. Boundary conditions may specify the potential (Dirichlet
+boundary condition), its normal derivative across the boundary
+(Neumann boundary condition), or a weighted sum of the potential and
+its derivative (Cauchy boundary condition).
+
+In a thermal model, we want to calculate the temperature in
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+and know the boundary temperature (Dirichlet condition)
+or heat flux (from which we can calculate the Neumann condition
+by dividing by the thermal conductivity at the boundary).  Similarly, 
+in an electrical model, we want to calculate the voltage in
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+and know the boundary voltage (Dirichlet) or current
+(Neumann condition after diving by the electrical conductivity).
+In an electrical model, it is common for much of the boundary
+to be electrically isolated; this is a Neumann boundary condition
+with the current equal to zero.
+
+The simplest finite element models will divide 
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+into simplexes (triangles in 2D, pyramids in 3D).
+ at ifset htmltex
+We take as an 3D example a cylindrical liquid filled tank with a small 
+non-conductive ball from the EIDORS project at footnote{EIDORS - Electrical 
+Impedance Tomography and Diffuse optical Tomography Reconstruction Software 
+ at url{http://eidors3d.sourceforge.net}}.  This is model is designed to reflect
+an application of electrical impedance tomography, where current patterns
+are applied to such a tank in order to image the internal conductivity
+distribution.  In order to describe the FEM geometry, we have a matrix of 
+vertices @code{nodes} and simplices @code{elems}.
+ at end ifset
+
+The following example creates a simple rectangular 2D electrically
+conductive medium with 10 V and 20 V imposed on opposite sides 
+(Dirichlet boundary conditions).  All other edges are electrically
+isolated.
+
+ at example
+ at group
+   node_y= [1;1.2;1.5;1.8;2]*ones(1,11);
+   node_x= ones(5,1)*[1,1.05,1.1,1.2, ...
+             1.3,1.5,1.7,1.8,1.9,1.95,2];
+   nodes= [node_x(:), node_y(:)];
+
+   [h,w]= size(node_x);
+   elems= [];
+   for idx= 1:w-1
+     widx= (idx-1)*h;
+     elems= [elems; ...
+       widx+[(1:h-1);(2:h);h+(1:h-1)]'; ...
+       widx+[(2:h);h+(2:h);h+(1:h-1)]' ]; 
+   endfor
+
+   E= size(elems,1); # No. of simplices
+   N= size(nodes,1); # No. of vertices
+   D= size(elems,2); # dimensions+1
+ at end group
+ at end example
+
+This creates a N-by-2 matrix @code{nodes} and a E-by-3 matrix
+ at code{elems} with values, which define finite element triangles:
+
+ at example
+ at group
+  nodes(1:7,:)'
+    1.00 1.00 1.00 1.00 1.00 1.05 1.05 @dots{}
+    1.00 1.20 1.50 1.80 2.00 1.00 1.20 @dots{}
+
+  elems(1:7,:)'
+    1    2    3    4    2    3    4 @dots{}
+    2    3    4    5    7    8    9 @dots{}
+    6    7    8    9    6    7    8 @dots{}
+ at end group
+ at end example
+
+Using a first order FEM, we approximate the electrical conductivity 
+distribution in 
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+as constant on each simplex (represented by the vector @code{conductivity}).
+Based on the finite element geometry, we first calculate a system (or
+stiffness) matrix for each simplex (represented as 3-by-3 elements on the
+diagonal of the element-wise system matrix @code{SE}.  Based on @code{SE} 
+and a N-by-DE connectivity matrix @code{C}, representing the connections 
+between simplices and vertices, the global connectivity matrix @code{S} is
+calculated.
+
+ at example
+  # Element conductivity
+  conductivity= [1*ones(1,16), ...
+         2*ones(1,48), 1*ones(1,16)];
+
+  # Connectivity matrix
+  C = sparse ((1:D*E), reshape (elems', ...
+         D*E, 1), 1, D*E, N);
+
+  # Calculate system matrix
+  Siidx = floor ([0:D*E-1]'/D) * D * ...
+         ones(1,D) + ones(D*E,1)*(1:D) ;
+  Sjidx = [1:D*E]'*ones(1,D);
+  Sdata = zeros(D*E,D);
+  dfact = factorial(D-1);
+  for j=1:E
+     a = inv([ones(D,1), ... 
+         nodes(elems(j,:), :)]);
+     const = conductivity(j) * 2 / ...
+         dfact / abs(det(a));
+     Sdata(D*(j-1)+(1:D),:) = const * ...
+         a(2:D,:)' * a(2:D,:);
+  endfor
+  # Element-wise system matrix
+  SE= sparse(Siidx,Sjidx,Sdata);
+  # Global system matrix
+  S= C'* SE *C;
+ at end example
+
+The system matrix acts like the conductivity 
+ at tex
+$S$ 
+ at end tex
+ at ifinfo
+ at code{S}
+ at end ifinfo
+in Ohm's law 
+ at tex
+$SV = I$. 
+ at end tex
+ at ifinfo
+ at code{S * V = I}.
+ at end ifinfo
+Based on the Dirichlet and Neumann boundary conditions, we are able to 
+solve for the voltages at each vertex @code{V}. 
+
+ at example
+  # Dirichlet boundary conditions
+  D_nodes=[1:5, 51:55]; 
+  D_value=[10*ones(1,5), 20*ones(1,5)]; 
+
+  V= zeros(N,1);
+  V(D_nodes) = D_value;
+  idx = 1:N; # vertices without Dirichlet 
+             # boundary condns
+  idx(D_nodes) = [];
+
+  # Neumann boundary conditions.  Note that
+  # N_value must be normalized by the
+  # boundary length and element conductivity
+  N_nodes=[];
+  N_value=[];
+
+  Q = zeros(N,1);
+  Q(N_nodes) = N_value;
+
+  V(idx) = S(idx,idx) \ ( Q(idx) - ...
+            S(idx,D_nodes) * V(D_nodes));
+ at end example
+
+Finally, in order to display the solution, we show each solved voltage 
+value in the z-axis for each simplex vertex.
+ at ifset htmltex
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_UMFPACK
+ at ifset HAVE_COLAMD
+ at xref{fig:femmodel}.
+ at end ifset
+ at end ifset
+ at end ifset
+ at end ifset
+
+ at example
+ at group
+  elemx = elems(:,[1,2,3,1])';
+  xelems = reshape (nodes(elemx, 1), 4, E);
+  yelems = reshape (nodes(elemx, 2), 4, E);
+  velems = reshape (V(elemx), 4, E);
+  plot3 (xelems,yelems,velems,'k'); 
+  print ('grid.eps');
+ at end group
+ at end example
+
+
+ at ifset htmltex
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_UMFPACK
+ at ifset HAVE_COLAMD
+ at float Figure,fig:femmodel
+ at center @image{grid,4in}
+ at caption{Example finite element model the showing triangular elements. 
+The height of each vertex corresponds to the solution value.}
+ at end float
+ at end ifset
+ at end ifset
+ at end ifset
+ at end ifset
diff --git a/doc/interpreter/sparse.txi b/doc/interpreter/sparse.txi
new file mode 100644
index 0000000..1cce4b8
--- /dev/null
+++ b/doc/interpreter/sparse.txi
@@ -0,0 +1,1136 @@
+ at c Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at ifhtml
+ at set htmltex
+ at end ifhtml
+ at iftex
+ at set htmltex
+ at end iftex
+
+ at node Sparse Matrices 
+ at chapter Sparse Matrices
+
+ at menu
+* Basics::                      Creation and Manipulation of Sparse Matrices
+* Sparse Linear Algebra::       Linear Algebra on Sparse Matrices
+* Iterative Techniques::        Iterative Techniques
+* Real Life Example::           Using Sparse Matrices
+ at end menu
+
+ at node Basics
+ at section The Creation and Manipulation of Sparse Matrices
+
+The size of mathematical problems that can be treated at any particular
+time is generally limited by the available computing resources.  Both,
+the speed of the computer and its available memory place limitation on
+the problem size. 
+
+There are many classes of mathematical problems which give rise to
+matrices, where a large number of the elements are zero.  In this case
+it makes sense to have a special matrix type to handle this class of
+problems where only the non-zero elements of the matrix are
+stored.  Not only does this reduce the amount of memory to store the
+matrix, but it also means that operations on this type of matrix can
+take advantage of the a-priori knowledge of the positions of the
+non-zero elements to accelerate their calculations.
+
+A matrix type that stores only the non-zero elements is generally called
+sparse.  It is the purpose of this document to discuss the basics of the
+storage and creation of sparse matrices and the fundamental operations
+on them.
+
+ at menu
+* Storage of Sparse Matrices::
+* Creating Sparse Matrices::
+* Information::
+* Operators and Functions::
+ at end menu
+
+ at node Storage of Sparse Matrices
+ at subsection Storage of Sparse Matrices
+
+It is not strictly speaking necessary for the user to understand how
+sparse matrices are stored.  However, such an understanding will help
+to get an understanding of the size of sparse matrices.  Understanding
+the storage technique is also necessary for those users wishing to 
+create their own oct-files. 
+
+There are many different means of storing sparse matrix data.  What all
+of the methods have in common is that they attempt to reduce the complexity
+and storage given a-priori knowledge of the particular class of problems
+that will be solved.  A good summary of the available techniques for storing
+sparse matrix is given by Saad @footnote{Youcef Saad "SPARSKIT: A basic toolkit
+for sparse matrix computation", 1994,
+ at url{http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps}}.
+With full matrices, knowledge of the point of an element of the matrix
+within the matrix is implied by its position in the computers memory. 
+However, this is not the case for sparse matrices, and so the positions
+of the non-zero elements of the matrix must equally be stored. 
+
+An obvious way to do this is by storing the elements of the matrix as
+triplets, with two elements being their position in the array 
+(rows and column) and the third being the data itself.  This is conceptually
+easy to grasp, but requires more storage than is strictly needed.
+
+The storage technique used within Octave is the compressed column
+format.  In this format the position of each element in a row and the
+data are stored as previously.  However, if we assume that all elements
+in the same column are stored adjacent in the computers memory, then
+we only need to store information on the number of non-zero elements
+in each column, rather than their positions.  Thus assuming that the
+matrix has more non-zero elements than there are columns in the
+matrix, we win in terms of the amount of memory used.
+
+In fact, the column index contains one more element than the number of
+columns, with the first element always being zero.  The advantage of
+this is a simplification in the code, in that there is no special case
+for the first or last columns.  A short example, demonstrating this in
+C is.
+
+ at example
+ at group
+  for (j = 0; j < nc; j++)
+    for (i = cidx (j); i < cidx(j+1); i++)
+       printf ("non-zero element (%i,%i) is %d\n", 
+	   ridx(i), j, data(i));
+ at end group
+ at end example
+
+A clear understanding might be had by considering an example of how the
+above applies to an example matrix.  Consider the matrix
+
+ at example
+ at group
+    1   2   0  0
+    0   0   0  3
+    0   0   0  4
+ at end group
+ at end example
+
+The non-zero elements of this matrix are
+
+ at example
+ at group
+   (1, 1)  @result{} 1
+   (1, 2)  @result{} 2
+   (2, 4)  @result{} 3
+   (3, 4)  @result{} 4
+ at end group
+ at end example
+
+This will be stored as three vectors @var{cidx}, @var{ridx} and @var{data},
+representing the column indexing, row indexing and data respectively.  The
+contents of these three vectors for the above matrix will be
+
+ at example
+ at group
+  @var{cidx} = [0, 1, 2, 2, 4]
+  @var{ridx} = [0, 0, 1, 2]
+  @var{data} = [1, 2, 3, 4]
+ at end group
+ at end example
+
+Note that this is the representation of these elements with the first row
+and column assumed to start at zero, while in Octave itself the row and 
+column indexing starts at one.  Thus the number of elements in the 
+ at var{i}-th column is given by @code{@var{cidx} (@var{i} + 1) - 
+ at var{cidx} (@var{i})}.
+
+Although Octave uses a compressed column format, it should be noted
+that compressed row formats are equally possible.  However, in the
+context of mixed operations between mixed sparse and dense matrices,
+it makes sense that the elements of the sparse matrices are in the
+same order as the dense matrices.  Octave stores dense matrices in
+column major ordering, and so sparse matrices are equally stored in
+this manner.
+
+A further constraint on the sparse matrix storage used by Octave is that 
+all elements in the rows are stored in increasing order of their row
+index, which makes certain operations faster.  However, it imposes
+the need to sort the elements on the creation of sparse matrices.  Having
+disordered elements is potentially an advantage in that it makes operations
+such as concatenating two sparse matrices together easier and faster, however
+it adds complexity and speed problems elsewhere.
+
+ at node Creating Sparse Matrices
+ at subsection Creating Sparse Matrices
+
+There are several means to create sparse matrix.
+
+ at table @asis
+ at item Returned from a function
+There are many functions that directly return sparse matrices.  These include
+ at dfn{speye}, @dfn{sprand}, @dfn{diag}, etc.
+ at item Constructed from matrices or vectors
+The function @dfn{sparse} allows a sparse matrix to be constructed from 
+three vectors representing the row, column and data.  Alternatively, the
+function @dfn{spconvert} uses a three column matrix format to allow easy
+importation of data from elsewhere.
+ at item Created and then filled
+The function @dfn{sparse} or @dfn{spalloc} can be used to create an empty
+matrix that is then filled by the user
+ at item From a user binary program
+The user can directly create the sparse matrix within an oct-file.
+ at end table
+
+There are several basic functions to return specific sparse
+matrices.  For example the sparse identity matrix, is a matrix that is
+often needed.  It therefore has its own function to create it as
+ at code{speye (@var{n})} or @code{speye (@var{r}, @var{c})}, which
+creates an @var{n}-by- at var{n} or @var{r}-by- at var{c} sparse identity
+matrix.
+
+Another typical sparse matrix that is often needed is a random distribution
+of random elements.  The functions @dfn{sprand} and @dfn{sprandn} perform
+this for uniform and normal random distributions of elements.  They have exactly
+the same calling convention, where @code{sprand (@var{r}, @var{c}, @var{d})},
+creates an @var{r}-by- at var{c} sparse matrix with a density of filled
+elements of @var{d}.
+
+Other functions of interest that directly create sparse matrices, are
+ at dfn{diag} or its generalization @dfn{spdiags}, that can take the
+definition of the diagonals of the matrix and create the sparse matrix 
+that corresponds to this.  For example
+
+ at example
+s = diag (sparse(randn(1,n)), -1);
+ at end example
+
+creates a sparse (@var{n}+1)-by-(@var{n}+1) sparse matrix with a single
+diagonal defined.
+
+
+ at DOCSTRING(spdiags)
+
+ at DOCSTRING(speye)
+
+ at DOCSTRING(spfun)
+
+ at DOCSTRING(spmax)
+
+ at DOCSTRING(spmin)
+
+ at DOCSTRING(spones)
+
+ at DOCSTRING(sprand)
+
+ at DOCSTRING(sprandn)
+
+ at DOCSTRING(sprandsym)
+
+The recommended way for the user to create a sparse matrix, is to create 
+two vectors containing the row and column index of the data and a third
+vector of the same size containing the data to be stored.  For example
+
+ at example
+ at group
+  ri = ci = d = [];
+  for j = 1:c
+    ri = [ri; randperm(r)(1:n)'];
+    ci = [ci; j*ones(n,1)];
+    d = [d; rand(n,1)];
+  endfor
+  s = sparse (ri, ci, d, r, c);
+ at end group
+ at end example
+
+creates an @var{r}-by- at var{c} sparse matrix with a random distribution
+of @var{n} (<@var{r}) elements per column.  The elements of the vectors
+do not need to be sorted in any particular order as Octave will sort
+them prior to storing the data.  However, pre-sorting the data will
+make the creation of the sparse matrix faster.
+
+The function @dfn{spconvert} takes a three or four column real matrix.
+The first two columns represent the row and column index respectively and
+the third and four columns, the real and imaginary parts of the sparse
+matrix.  The matrix can contain zero elements and the elements can be 
+sorted in any order.  Adding zero elements is a convenient way to define
+the size of the sparse matrix.  For example
+
+ at example
+ at group
+s = spconvert ([1 2 3 4; 1 3 4 4; 1 2 3 0]')
+ at result{} Compressed Column Sparse (rows=4, cols=4, nnz=3)
+      (1 , 1) -> 1
+      (2 , 3) -> 2
+      (3 , 4) -> 3
+ at end group
+ at end example
+
+An example of creating and filling a matrix might be
+
+ at example
+ at group
+k = 5;
+nz = r * k;
+s = spalloc (r, c, nz)
+for j = 1:c
+  idx = randperm (r);
+  s (:, j) = [zeros(r - k, 1); ...
+        rand(k, 1)] (idx);
+endfor
+ at end group
+ at end example
+
+It should be noted, that due to the way that the Octave
+assignment functions are written that the assignment will reallocate
+the memory used by the sparse matrix at each iteration of the above loop. 
+Therefore the @dfn{spalloc} function ignores the @var{nz} argument and 
+does not preassign the memory for the matrix.  Therefore, it is vitally
+important that code using to above structure should be vectorized
+as much as possible to minimize the number of assignments and reduce the
+number of memory allocations.
+
+ at DOCSTRING(full)
+
+ at DOCSTRING(spalloc)
+
+ at DOCSTRING(sparse)
+
+ at DOCSTRING(spconvert)
+
+The above problem of memory reallocation can be avoided in
+oct-files.  However, the construction of a sparse matrix from an oct-file
+is more complex than can be discussed here, and
+you are referred to chapter @ref{Dynamically Linked Functions}, to have
+a full description of the techniques involved.
+
+ at node Information
+ at subsection Finding out Information about Sparse Matrices
+
+There are a number of functions that allow information concerning
+sparse matrices to be obtained.  The most basic of these is
+ at dfn{issparse} that identifies whether a particular Octave object is
+in fact a sparse matrix.
+
+Another very basic function is @dfn{nnz} that returns the number of
+non-zero entries there are in a sparse matrix, while the function
+ at dfn{nzmax} returns the amount of storage allocated to the sparse
+matrix.  Note that Octave tends to crop unused memory at the first
+opportunity for sparse objects.  There are some cases of user created
+sparse objects where the value returned by @dfn{nzmax} will not be
+the same as @dfn{nnz}, but in general they will give the same
+result.  The function @dfn{spstats} returns some basic statistics on
+the columns of a sparse matrix including the number of elements, the
+mean and the variance of each column.
+
+ at DOCSTRING(issparse)
+
+ at DOCSTRING(nnz)
+
+ at DOCSTRING(nonzeros)
+
+ at DOCSTRING(nzmax)
+
+ at DOCSTRING(spstats)
+
+When solving linear equations involving sparse matrices Octave
+determines the means to solve the equation based on the type of the
+matrix as discussed in @ref{Sparse Linear Algebra}.  Octave probes the
+matrix type when the div (/) or ldiv (\) operator is first used with
+the matrix and then caches the type.  However the @dfn{matrix_type}
+function can be used to determine the type of the sparse matrix prior
+to use of the div or ldiv operators.  For example
+
+ at example
+ at group
+a = tril (sprandn(1024, 1024, 0.02), -1) ...
+    + speye(1024); 
+matrix_type (a);
+ans = Lower
+ at end group
+ at end example
+
+show that Octave correctly determines the matrix type for lower
+triangular matrices.  @dfn{matrix_type} can also be used to force
+the type of a matrix to be a particular type.  For example
+
+ at example
+ at group
+a = matrix_type (tril (sprandn (1024, ...
+   1024, 0.02), -1) + speye(1024), 'Lower');
+ at end group
+ at end example
+
+This allows the cost of determining the matrix type to be
+avoided.  However, incorrectly defining the matrix type will result in
+incorrect results from solutions of linear equations, and so it is
+entirely the responsibility of the user to correctly identify the
+matrix type
+
+There are several graphical means of finding out information about
+sparse matrices.  The first is the @dfn{spy} command, which displays
+the structure of the non-zero elements of the
+matrix.  @xref{fig:spmatrix}, for an example of the use of
+ at dfn{spy}.  More advanced graphical information can be obtained with the
+ at dfn{treeplot}, @dfn{etreeplot} and @dfn{gplot} commands.
+
+ at float Figure,fig:spmatrix
+ at center @image{spmatrix,4in}
+ at caption{Structure of simple sparse matrix.}
+ at end float
+
+One use of sparse matrices is in graph theory, where the
+interconnections between nodes are represented as an adjacency
+matrix.  That is, if the i-th node in a graph is connected to the j-th
+node.  Then the ij-th node (and in the case of undirected graphs the
+ji-th node) of the sparse adjacency matrix is non-zero.  If each node
+is then associated with a set of coordinates, then the @dfn{gplot}
+command can be used to graphically display the interconnections
+between nodes.
+
+As a trivial example of the use of @dfn{gplot}, consider the example
+
+ at example
+ at group
+A = sparse([2,6,1,3,2,4,3,5,4,6,1,5],
+    [1,1,2,2,3,3,4,4,5,5,6,6],1,6,6);
+xy = [0,4,8,6,4,2;5,0,5,7,5,7]';
+gplot(A,xy)
+ at end group
+ at end example
+
+which creates an adjacency matrix @code{A} where node 1 is connected
+to nodes 2 and 6, node 2 with nodes 1 and 3, etc.  The coordinates of
+the nodes are given in the n-by-2 matrix @code{xy}.
+ at ifset htmltex 
+ at xref{fig:gplot}.
+
+ at float Figure,fig:gplot
+ at center @image{gplot,4in}
+ at caption{Simple use of the @dfn{gplot} command.}
+ at end float
+ at end ifset
+
+The dependencies between the nodes of a Cholesky factorization can be
+calculated in linear time without explicitly needing to calculate the
+Cholesky factorization by the @code{etree} command.  This command
+returns the elimination tree of the matrix and can be displayed
+graphically by the command @code{treeplot(etree(A))} if @code{A} is
+symmetric or @code{treeplot(etree(A+A'))} otherwise.
+
+ at DOCSTRING(spy)
+
+ at DOCSTRING(etree)
+
+ at DOCSTRING(etreeplot)
+
+ at DOCSTRING(gplot)
+
+ at DOCSTRING(treeplot)
+
+ at DOCSTRING(treelayout)
+
+ at node Operators and Functions
+ at subsection Basic Operators and Functions on Sparse Matrices
+
+ at menu
+* Sparse Functions::            
+* Return Types of Operators and Functions::  
+* Mathematical Considerations::  
+ at end menu
+
+ at node Sparse Functions
+ at subsubsection Sparse Functions
+
+An important consideration in the use of the sparse functions of
+Octave is that many of the internal functions of Octave, such as
+ at dfn{diag}, cannot accept sparse matrices as an input.  The sparse
+implementation in Octave therefore uses the @dfn{dispatch}
+function to overload the normal Octave functions with equivalent
+functions that work with sparse matrices.  However, at any time the
+sparse matrix specific version of the function can be used by
+explicitly calling its function name. 
+
+The table below lists all of the sparse functions of Octave.  Note that
+the names of the 
+specific sparse forms of the functions are typically the same as
+the general versions with a @dfn{sp} prefix.  In the table below, and the
+rest of this article the specific sparse versions of the functions are
+used.
+
+ at c Table includes in comments the missing sparse functions
+
+ at table @asis
+ at item Generate sparse matrices:
+  @dfn{spalloc}, @dfn{spdiags}, @dfn{speye}, @dfn{sprand}, 
+  @dfn{sprandn}, @dfn{sprandsym}
+
+ at item Sparse matrix conversion:
+  @dfn{full}, @dfn{sparse}, @dfn{spconvert}
+
+ at item Manipulate sparse matrices
+  @dfn{issparse}, @dfn{nnz}, @dfn{nonzeros}, @dfn{nzmax},
+  @dfn{spfun}, @dfn{spones}, @dfn{spy}
+
+ at item Graph Theory:
+  @dfn{etree}, @dfn{etreeplot}, @dfn{gplot}, 
+  @dfn{treeplot}
+ at c @dfn{treelayout}
+
+ at item Sparse matrix reordering:
+  @dfn{amd}, @dfn{ccolamd}, @dfn{colamd}, @dfn{colperm}, @dfn{csymamd},
+  @dfn{dmperm}, @dfn{symamd}, @dfn{randperm}, @dfn{symrcm}
+
+ at item Linear algebra:
+  @dfn{condest}, @dfn{eigs}, @dfn{matrix_type}, @dfn{normest}, @dfn{sprank},
+  @dfn{spaugment}, @dfn{svds}
+
+ at item Iterative techniques:
+  @dfn{luinc}, @dfn{pcg}, @dfn{pcr}
+ at c @dfn{bicg}, @dfn{bicgstab}, @dfn{cholinc}, @dfn{cgs}, @dfn{gmres}, 
+ at c @dfn{lsqr}, @dfn{minres}, @dfn{qmr}, @dfn{symmlq}
+
+ at item Miscellaneous:
+  @dfn{spparms}, @dfn{symbfact}, @dfn{spstats}
+ at end table
+
+In addition all of the standard Octave mapper functions (i.e., basic
+math functions that take a single argument) such as @dfn{abs}, etc.
+can accept sparse matrices.  The reader is referred to the documentation
+supplied with these functions within Octave itself for further
+details.
+
+ at node Return Types of Operators and Functions
+ at subsubsection The Return Types of Operators and Functions
+
+The two basic reasons to use sparse matrices are to reduce the memory 
+usage and to not have to do calculations on zero elements.  The two are
+closely related in that the computation time on a sparse matrix operator
+or function is roughly linear with the number of non-zero elements.
+
+Therefore, there is a certain density of non-zero elements of a matrix 
+where it no longer makes sense to store it as a sparse matrix, but rather
+as a full matrix.  For this reason operators and functions that have a 
+high probability of returning a full matrix will always return one.  For
+example adding a scalar constant to a sparse matrix will almost always
+make it a full matrix, and so the example
+
+ at example
+ at group
+speye(3) + 0
+ at result{}   1  0  0
+  0  1  0
+  0  0  1
+ at end group
+ at end example
+
+returns a full matrix as can be seen. 
+
+
+Additionally, if @code{sparse_auto_mutate} is true, all sparse functions
+test the amount of memory occupied by the sparse matrix to see if the
+amount of storage used is larger than the amount used by the full
+equivalent.  Therefore @code{speye (2) * 1} will return a full matrix as
+the memory used is smaller for the full version than the sparse version.
+
+As all of the mixed operators and functions between full and sparse 
+matrices exist, in general this does not cause any problems.  However,
+one area where it does cause a problem is where a sparse matrix is
+promoted to a full matrix, where subsequent operations would resparsify
+the matrix.  Such cases are rare, but can be artificially created, for
+example @code{(fliplr(speye(3)) + speye(3)) - speye(3)} gives a full
+matrix when it should give a sparse one.  In general, where such cases 
+occur, they impose only a small memory penalty.
+
+There is however one known case where this behavior of Octave's
+sparse matrices will cause a problem.  That is in the handling of the
+ at dfn{diag} function.  Whether @dfn{diag} returns a sparse or full matrix
+depending on the type of its input arguments.  So 
+
+ at example
+ a = diag (sparse([1,2,3]), -1);
+ at end example
+
+should return a sparse matrix.  To ensure this actually happens, the
+ at dfn{sparse} function, and other functions based on it like @dfn{speye}, 
+always returns a sparse matrix, even if the memory used will be larger 
+than its full representation.
+
+ at DOCSTRING(sparse_auto_mutate)
+
+Note that the @code{sparse_auto_mutate} option is incompatible with
+ at sc{matlab}, and so it is off by default.
+
+ at node Mathematical Considerations
+ at subsubsection Mathematical Considerations
+
+The attempt has been made to make sparse matrices behave in exactly the
+same manner as there full counterparts.  However, there are certain differences
+and especially differences with other products sparse implementations.
+
+Firstly, the "./" and ".^" operators must be used with care.  Consider what
+the examples
+
+ at example
+ at group
+  s = speye (4);
+  a1 = s .^ 2;
+  a2 = s .^ s;
+  a3 = s .^ -2;
+  a4 = s ./ 2;
+  a5 = 2 ./ s;
+  a6 = s ./ s;
+ at end group
+ at end example
+
+will give.  The first example of @var{s} raised to the power of 2 causes
+no problems.  However @var{s} raised element-wise to itself involves a
+large number of terms @code{0 .^ 0} which is 1. There @code{@var{s} .^
+ at var{s}} is a full matrix. 
+
+Likewise @code{@var{s} .^ -2} involves terms like @code{0 .^ -2} which
+is infinity, and so @code{@var{s} .^ -2} is equally a full matrix.
+
+For the "./" operator @code{@var{s} ./ 2} has no problems, but 
+ at code{2 ./ @var{s}} involves a large number of infinity terms as well
+and is equally a full matrix.  The case of @code{@var{s} ./ @var{s}}
+involves terms like @code{0 ./ 0} which is a @code{NaN} and so this
+is equally a full matrix with the zero elements of @var{s} filled with
+ at code{NaN} values.
+
+The above behavior is consistent with full matrices, but is not 
+consistent with sparse implementations in other products.
+
+A particular problem of sparse matrices comes about due to the fact that
+as the zeros are not stored, the sign-bit of these zeros is equally not
+stored.  In certain cases the sign-bit of zero is important.  For example
+
+ at example
+ at group
+ a = 0 ./ [-1, 1; 1, -1];
+ b = 1 ./ a
+ @result{} -Inf            Inf
+     Inf           -Inf
+ c = 1 ./ sparse (a)
+ @result{}  Inf            Inf
+     Inf            Inf
+ at end group
+ at end example
+ 
+To correct this behavior would mean that zero elements with a negative
+sign-bit would need to be stored in the matrix to ensure that their 
+sign-bit was respected.  This is not done at this time, for reasons of
+efficiency, and so the user is warned that calculations where the sign-bit
+of zero is important must not be done using sparse matrices.
+
+In general any function or operator used on a sparse matrix will
+result in a sparse matrix with the same or a larger number of non-zero
+elements than the original matrix.  This is particularly true for the
+important case of sparse matrix factorizations.  The usual way to
+address this is to reorder the matrix, such that its factorization is
+sparser than the factorization of the original matrix.  That is the
+factorization of @code{L * U = P * S * Q} has sparser terms @code{L}
+and @code{U} than the equivalent factorization @code{L * U = S}.
+
+Several functions are available to reorder depending on the type of the
+matrix to be factorized.  If the matrix is symmetric positive-definite,
+then @dfn{symamd} or @dfn{csymamd} should be used.  Otherwise
+ at dfn{amd}, @dfn{colamd} or @dfn{ccolamd} should be used.  For completeness
+the reordering functions @dfn{colperm} and @dfn{randperm} are
+also available.
+
+ at xref{fig:simplematrix}, for an example of the structure of a simple 
+positive definite matrix.
+
+ at float Figure,fig:simplematrix
+ at center @image{spmatrix,4in}
+ at caption{Structure of simple sparse matrix.}
+ at end float
+
+The standard Cholesky factorization of this matrix can be
+obtained by the same command that would be used for a full
+matrix.  This can be visualized with the command 
+ at code{r = chol(A); spy(r);}.
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_COLAMD
+ at xref{fig:simplechol}.
+ at end ifset
+ at end ifset
+The original matrix had 
+ at ifinfo
+ at ifnothtml
+43
+ at end ifnothtml
+ at end ifinfo
+ at ifset htmltex
+598
+ at end ifset
+non-zero terms, while this Cholesky factorization has
+ at ifinfo
+ at ifnothtml
+71,
+ at end ifnothtml
+ at end ifinfo
+ at ifset htmltex
+10200,
+ at end ifset
+with only half of the symmetric matrix being stored.  This
+is a significant level of fill in, and although not an issue
+for such a small test case, can represents a large overhead 
+in working with other sparse matrices.
+
+The appropriate sparsity preserving permutation of the original
+matrix is given by @dfn{symamd} and the factorization using this
+reordering can be visualized using the command @code{q = symamd(A);
+r = chol(A(q,q)); spy(r)}.  This gives 
+ at ifinfo
+ at ifnothtml
+29
+ at end ifnothtml
+ at end ifinfo
+ at ifset htmltex
+399
+ at end ifset
+non-zero terms which is a significant improvement.
+
+The Cholesky factorization itself can be used to determine the
+appropriate sparsity preserving reordering of the matrix during the
+factorization, In that case this might be obtained with three return
+arguments as r at code{[r, p, q] = chol(A); spy(r)}.
+
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_COLAMD
+ at float Figure,fig:simplechol
+ at center @image{spchol,4in}
+ at caption{Structure of the un-permuted Cholesky factorization of the above matrix.}
+ at end float
+
+ at float Figure,fig:simplecholperm
+ at center @image{spcholperm,4in}
+ at caption{Structure of the permuted Cholesky factorization of the above matrix.}
+ at end float
+ at end ifset
+ at end ifset
+
+In the case of an asymmetric matrix, the appropriate sparsity
+preserving permutation is @dfn{colamd} and the factorization using
+this reordering can be visualized using the command @code{q =
+colamd(A); [l, u, p] = lu(A(:,q)); spy(l+u)}.
+
+Finally, Octave implicitly reorders the matrix when using the div (/)
+and ldiv (\) operators, and so no the user does not need to explicitly
+reorder the matrix to maximize performance.
+
+ at DOCSTRING(amd)
+
+ at DOCSTRING(ccolamd)
+
+ at DOCSTRING(colamd)
+
+ at DOCSTRING(colperm)
+
+ at DOCSTRING(csymamd)
+
+ at DOCSTRING(dmperm)
+
+ at DOCSTRING(symamd)
+
+ at DOCSTRING(symrcm)
+
+ at node Sparse Linear Algebra
+ at section Linear Algebra on Sparse Matrices
+
+Octave includes a polymorphic solver for sparse matrices, where 
+the exact solver used to factorize the matrix, depends on the properties
+of the sparse matrix itself.  Generally, the cost of determining the matrix type
+is small relative to the cost of factorizing the matrix itself, but in any
+case the matrix type is cached once it is calculated, so that it is not
+re-determined each time it is used in a linear equation.
+
+The selection tree for how the linear equation is solve is
+
+ at enumerate 1
+ at item If the matrix is diagonal, solve directly and goto 8
+
+ at item If the matrix is a permuted diagonal, solve directly taking into
+account the permutations.  Goto 8
+
+ at item If the matrix is square, banded and if the band density is less
+than that given by @code{spparms ("bandden")} continue, else goto 4.
+
+ at enumerate a
+ at item If the matrix is tridiagonal and the right-hand side is not sparse 
+continue, else goto 3b.
+
+ at enumerate
+ at item If the matrix is hermitian, with a positive real diagonal, attempt
+      Cholesky factorization using @sc{lapack} xPTSV.
+
+ at item If the above failed or the matrix is not hermitian with a positive
+      real diagonal use Gaussian elimination with pivoting using 
+      @sc{lapack} xGTSV, and goto 8.
+ at end enumerate
+
+ at item If the matrix is hermitian with a positive real diagonal, attempt
+      Cholesky factorization using @sc{lapack} xPBTRF.
+
+ at item if the above failed or the matrix is not hermitian with a positive
+      real diagonal use Gaussian elimination with pivoting using 
+      @sc{lapack} xGBTRF, and goto 8.
+ at end enumerate
+
+ at item If the matrix is upper or lower triangular perform a sparse forward
+or backward substitution, and goto 8
+
+ at item If the matrix is a upper triangular matrix with column permutations
+or lower triangular matrix with row permutations, perform a sparse forward 
+or backward substitution, and goto 8
+
+ at item If the matrix is square, hermitian with a real positive diagonal, attempt
+sparse Cholesky factorization using CHOLMOD.
+
+ at item If the sparse Cholesky factorization failed or the matrix is not
+hermitian with a real positive diagonal, and the matrix is square, factorize 
+using UMFPACK.
+
+ at item If the matrix is not square, or any of the previous solvers flags
+a singular or near singular matrix, find a minimum norm solution using
+CXSPARSE at footnote{The CHOLMOD, UMFPACK and CXSPARSE packages were
+written by Tim Davis and are available at
+http://www.cise.ufl.edu/research/sparse/}.
+ at end enumerate
+
+The band density is defined as the number of non-zero values in the matrix
+divided by the number of non-zero values in the matrix.  The banded matrix
+solvers can be entirely disabled by using @dfn{spparms} to set @code{bandden}
+to 1 (i.e., @code{spparms ("bandden", 1)}).
+
+The QR solver factorizes the problem with a Dulmage-Mendelsohn, to
+separate the problem into blocks that can be treated as over-determined,
+multiple well determined blocks, and a final over-determined block.  For
+matrices with blocks of strongly connected nodes this is a big win as
+LU decomposition can be used for many blocks.  It also significantly
+improves the chance of finding a solution to over-determined problems
+rather than just returning a vector of @dfn{NaN}'s.
+
+All of the solvers above, can calculate an estimate of the condition
+number.  This can be used to detect numerical stability problems in the
+solution and force a minimum norm solution to be used.  However, for
+narrow banded, triangular or diagonal matrices, the cost of
+calculating the condition number is significant, and can in fact
+exceed the cost of factoring the matrix.  Therefore the condition
+number is not calculated in these cases, and Octave relies on simpler
+techniques to detect singular matrices or the underlying @sc{lapack} code in
+the case of banded matrices.
+
+The user can force the type of the matrix with the @code{matrix_type}
+function.  This overcomes the cost of discovering the type of the matrix.
+However, it should be noted that identifying the type of the matrix incorrectly
+will lead to unpredictable results, and so @code{matrix_type} should be
+used with care.
+
+ at DOCSTRING(normest)
+
+ at DOCSTRING(onenormest)
+
+ at DOCSTRING(condest)
+
+ at DOCSTRING(spparms)
+
+ at DOCSTRING(sprank)
+
+ at DOCSTRING(symbfact)
+
+For non square matrices, the user can also utilize the @code{spaugment}
+function to find a least squares solution to a linear equation.
+
+ at DOCSTRING(spaugment)
+
+Finally, the function @code{eigs} can be used to calculate a limited
+number of eigenvalues and eigenvectors based on a selection criteria
+and likewise for @code{svds} which calculates a limited number of
+singular values and vectors.
+
+ at DOCSTRING(eigs)
+
+ at DOCSTRING(svds)
+
+ at node Iterative Techniques
+ at section Iterative Techniques applied to sparse matrices
+
+The left division @code{\} and right division @code{/} operators,
+discussed in the previous section, use direct solvers to resolve a
+linear equation of the form @code{@var{x} = @var{A} \ @var{b}} or
+ at code{@var{x} = @var{b} / @var{A}}.  Octave equally includes a number of
+functions to solve sparse linear equations using iterative techniques.
+
+ at DOCSTRING(pcg)
+
+ at DOCSTRING(pcr)
+
+The speed with which an iterative solver converges to a solution can be
+accelerated with the use of a pre-conditioning matrix @var{M}.  In this
+case the linear equation @code{@var{M}^-1 * @var{x} = @var{M}^-1 *
+ at var{A} \ @var{b}} is solved instead.  Typical pre-conditioning matrices
+are partial factorizations of the original matrix.
+
+ at DOCSTRING(luinc)
+
+ at node Real Life Example
+ at section Real Life Example of the use of Sparse Matrices
+
+A common application for sparse matrices is in the solution of Finite
+Element Models.  Finite element models allow numerical solution of
+partial differential equations that do not have closed form solutions,
+typically because of the complex shape of the domain.
+
+In order to motivate this application, we consider the boundary value
+Laplace equation.  This system can model scalar potential fields, such
+as heat or electrical potential.  Given a medium 
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+with boundary
+ at tex
+$\partial\Omega$ 
+ at end tex
+ at ifinfo
+dOmega
+ at end ifinfo
+. At all points on the 
+ at tex
+$\partial\Omega$ 
+ at end tex
+ at ifinfo
+dOmega
+ at end ifinfo
+the boundary conditions are known, and we wish to calculate the potential in
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+. Boundary conditions may specify the potential (Dirichlet
+boundary condition), its normal derivative across the boundary
+(Neumann boundary condition), or a weighted sum of the potential and
+its derivative (Cauchy boundary condition).
+
+In a thermal model, we want to calculate the temperature in
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+and know the boundary temperature (Dirichlet condition)
+or heat flux (from which we can calculate the Neumann condition
+by dividing by the thermal conductivity at the boundary).  Similarly, 
+in an electrical model, we want to calculate the voltage in
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+and know the boundary voltage (Dirichlet) or current
+(Neumann condition after diving by the electrical conductivity).
+In an electrical model, it is common for much of the boundary
+to be electrically isolated; this is a Neumann boundary condition
+with the current equal to zero.
+
+The simplest finite element models will divide 
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+into simplexes (triangles in 2D, pyramids in 3D).
+ at ifset htmltex
+We take as an 3D example a cylindrical liquid filled tank with a small 
+non-conductive ball from the EIDORS project at footnote{EIDORS - Electrical 
+Impedance Tomography and Diffuse optical Tomography Reconstruction Software 
+ at url{http://eidors3d.sourceforge.net}}.  This is model is designed to reflect
+an application of electrical impedance tomography, where current patterns
+are applied to such a tank in order to image the internal conductivity
+distribution.  In order to describe the FEM geometry, we have a matrix of 
+vertices @code{nodes} and simplices @code{elems}.
+ at end ifset
+
+The following example creates a simple rectangular 2D electrically
+conductive medium with 10 V and 20 V imposed on opposite sides 
+(Dirichlet boundary conditions).  All other edges are electrically
+isolated.
+
+ at example
+ at group
+   node_y= [1;1.2;1.5;1.8;2]*ones(1,11);
+   node_x= ones(5,1)*[1,1.05,1.1,1.2, ...
+             1.3,1.5,1.7,1.8,1.9,1.95,2];
+   nodes= [node_x(:), node_y(:)];
+
+   [h,w]= size(node_x);
+   elems= [];
+   for idx= 1:w-1
+     widx= (idx-1)*h;
+     elems= [elems; ...
+       widx+[(1:h-1);(2:h);h+(1:h-1)]'; ...
+       widx+[(2:h);h+(2:h);h+(1:h-1)]' ]; 
+   endfor
+
+   E= size(elems,1); # No. of simplices
+   N= size(nodes,1); # No. of vertices
+   D= size(elems,2); # dimensions+1
+ at end group
+ at end example
+
+This creates a N-by-2 matrix @code{nodes} and a E-by-3 matrix
+ at code{elems} with values, which define finite element triangles:
+
+ at example
+ at group
+  nodes(1:7,:)'
+    1.00 1.00 1.00 1.00 1.00 1.05 1.05 @dots{}
+    1.00 1.20 1.50 1.80 2.00 1.00 1.20 @dots{}
+
+  elems(1:7,:)'
+    1    2    3    4    2    3    4 @dots{}
+    2    3    4    5    7    8    9 @dots{}
+    6    7    8    9    6    7    8 @dots{}
+ at end group
+ at end example
+
+Using a first order FEM, we approximate the electrical conductivity 
+distribution in 
+ at tex
+$\Omega$ 
+ at end tex
+ at ifinfo
+Omega
+ at end ifinfo
+as constant on each simplex (represented by the vector @code{conductivity}).
+Based on the finite element geometry, we first calculate a system (or
+stiffness) matrix for each simplex (represented as 3-by-3 elements on the
+diagonal of the element-wise system matrix @code{SE}.  Based on @code{SE} 
+and a N-by-DE connectivity matrix @code{C}, representing the connections 
+between simplices and vertices, the global connectivity matrix @code{S} is
+calculated.
+
+ at example
+  # Element conductivity
+  conductivity= [1*ones(1,16), ...
+         2*ones(1,48), 1*ones(1,16)];
+
+  # Connectivity matrix
+  C = sparse ((1:D*E), reshape (elems', ...
+         D*E, 1), 1, D*E, N);
+
+  # Calculate system matrix
+  Siidx = floor ([0:D*E-1]'/D) * D * ...
+         ones(1,D) + ones(D*E,1)*(1:D) ;
+  Sjidx = [1:D*E]'*ones(1,D);
+  Sdata = zeros(D*E,D);
+  dfact = factorial(D-1);
+  for j=1:E
+     a = inv([ones(D,1), ... 
+         nodes(elems(j,:), :)]);
+     const = conductivity(j) * 2 / ...
+         dfact / abs(det(a));
+     Sdata(D*(j-1)+(1:D),:) = const * ...
+         a(2:D,:)' * a(2:D,:);
+  endfor
+  # Element-wise system matrix
+  SE= sparse(Siidx,Sjidx,Sdata);
+  # Global system matrix
+  S= C'* SE *C;
+ at end example
+
+The system matrix acts like the conductivity 
+ at tex
+$S$ 
+ at end tex
+ at ifinfo
+ at code{S}
+ at end ifinfo
+in Ohm's law 
+ at tex
+$SV = I$. 
+ at end tex
+ at ifinfo
+ at code{S * V = I}.
+ at end ifinfo
+Based on the Dirichlet and Neumann boundary conditions, we are able to 
+solve for the voltages at each vertex @code{V}. 
+
+ at example
+  # Dirichlet boundary conditions
+  D_nodes=[1:5, 51:55]; 
+  D_value=[10*ones(1,5), 20*ones(1,5)]; 
+
+  V= zeros(N,1);
+  V(D_nodes) = D_value;
+  idx = 1:N; # vertices without Dirichlet 
+             # boundary condns
+  idx(D_nodes) = [];
+
+  # Neumann boundary conditions.  Note that
+  # N_value must be normalized by the
+  # boundary length and element conductivity
+  N_nodes=[];
+  N_value=[];
+
+  Q = zeros(N,1);
+  Q(N_nodes) = N_value;
+
+  V(idx) = S(idx,idx) \ ( Q(idx) - ...
+            S(idx,D_nodes) * V(D_nodes));
+ at end example
+
+Finally, in order to display the solution, we show each solved voltage 
+value in the z-axis for each simplex vertex.
+ at ifset htmltex
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_UMFPACK
+ at ifset HAVE_COLAMD
+ at xref{fig:femmodel}.
+ at end ifset
+ at end ifset
+ at end ifset
+ at end ifset
+
+ at example
+ at group
+  elemx = elems(:,[1,2,3,1])';
+  xelems = reshape (nodes(elemx, 1), 4, E);
+  yelems = reshape (nodes(elemx, 2), 4, E);
+  velems = reshape (V(elemx), 4, E);
+  plot3 (xelems,yelems,velems,'k'); 
+  print ('grid.eps');
+ at end group
+ at end example
+
+
+ at ifset htmltex
+ at ifset HAVE_CHOLMOD
+ at ifset HAVE_UMFPACK
+ at ifset HAVE_COLAMD
+ at float Figure,fig:femmodel
+ at center @image{grid,4in}
+ at caption{Example finite element model the showing triangular elements. 
+The height of each vertex corresponds to the solution value.}
+ at end float
+ at end ifset
+ at end ifset
+ at end ifset
+ at end ifset
diff --git a/doc/interpreter/sparseimages.m b/doc/interpreter/sparseimages.m
new file mode 100644
index 0000000..a01abe1
--- /dev/null
+++ b/doc/interpreter/sparseimages.m
@@ -0,0 +1,274 @@
+## Copyright (C) 2006, 2007, 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+function sparseimages (nm, typ)
+  if (strcmp (typ, "png"))
+    set (0, "defaulttextfontname", "*");
+  endif
+  if (! isempty (findstr (octave_config_info ("DEFS"), "HAVE_COLAMD"))
+      && ! isempty (findstr (octave_config_info ("DEFS"), "HAVE_CHOLMOD"))
+      && ! isempty (findstr (octave_config_info ("DEFS"), "HAVE_UMFPACK")))
+    if (strcmp(typ,"txt"))
+      txtimages (nm, 15, typ);
+    else
+      if (strcmp (nm, "gplot"))
+	gplotimages ("gplot", typ);
+      elseif (strcmp (nm, "grid"))
+	femimages ("grid", typ);
+      else
+	otherimages (nm, 200, typ);
+      endif
+    endif
+  else ## There is no sparse matrix implementation available because
+       ## of missing libraries, plot sombreros instead
+    sombreroimage (nm, typ);
+  endif
+endfunction
+
+function bury_output ()
+  f = figure (1);
+  set (f, "visible", "off");
+endfunction
+
+function gplotimages (nm, typ)
+  bury_output ();
+  A = sparse ([2,6,1,3,2,4,3,5,4,6,1,5],
+	      [1,1,2,2,3,3,4,4,5,5,6,6], 1, 6, 6);
+  xy = [0,4,8,6,4,2;5,0,5,7,5,7]';
+  gplot (A, xy)
+  print (cstrcat (nm, ".", typ), cstrcat ("-d", typ))
+  bury_output ();
+endfunction
+
+function txtimages(nm,n,typ)
+  a = 10*speye(n) + sparse(1:n,ceil([1:n]/2),1,n,n) + ...
+      sparse(ceil([1:n]/2),1:n,1,n,n);
+  if (strcmp (nm, "gplot") || strcmp (nm, "grid"))
+    fid = fopen (sprintf ("%s.txt", nm), "wt");
+    fputs (fid, "\n");
+    fputs (fid, "+---------------------------------+\n");
+    fputs (fid, "| Image unavailable in text mode. |\n");
+    fputs (fid, "+---------------------------------+\n");
+    fclose (fid);
+  elseif (strcmp (nm, "spmatrix"))
+    printsparse(a,cstrcat("spmatrix.",typ));
+  else
+    if (!isempty(findstr(octave_config_info ("DEFS"),"HAVE_COLAMD")) &&
+	!isempty(findstr(octave_config_info ("DEFS"),"HAVE_CHOLMOD")))
+      if (strcmp (nm, "spchol"))
+	r1 = chol(a);
+	printsparse(r1,cstrcat("spchol.",typ));
+      elseif (strcmp (nm, "spcholperm"))
+	[r2,p2,q2]=chol(a);
+	printsparse(r2,cstrcat("spcholperm.",typ));
+      endif
+      ## printf("Text NNZ: Matrix %d, Chol %d, PermChol %d\n",nnz(a),nnz(r1),nnz(r2));
+    endif
+  endif
+endfunction
+
+function otherimages(nm,n,typ)
+  bury_output ();
+  a = 10*speye(n) + sparse(1:n,ceil([1:n]/2),1,n,n) + ...
+      sparse(ceil([1:n]/2),1:n,1,n,n);
+  if (strcmp (nm, "spmatrix"))
+    spy(a);
+    axis("ij")
+    print(cstrcat("spmatrix.",typ),cstrcat("-d",typ))
+    bury_output ();
+  else
+    if (!isempty(findstr(octave_config_info ("DEFS"),"HAVE_COLAMD")) &&
+	!isempty(findstr(octave_config_info ("DEFS"),"HAVE_CHOLMOD")))
+      if (strcmp (nm, "spchol"))
+	r1 = chol(a);
+	spy(r1);
+	axis("ij")
+	print(cstrcat("spchol.",typ),cstrcat("-d",typ))
+	bury_output ();
+      elseif (strcmp (nm, "spcholperm"))
+	[r2,p2,q2]=chol(a);
+	spy(r2);
+	axis("ij")
+	print(cstrcat("spcholperm.",typ),cstrcat("-d",typ))
+	bury_output ();
+      endif
+      ## printf("Image NNZ: Matrix %d, Chol %d, PermChol %d\n",nnz(a),nnz(r1),nnz(r2));
+    endif
+  endif
+endfunction
+
+function printsparse(a,nm)
+  fid = fopen (nm,"wt");
+  fputs (fid, "\n");
+  for i = 1:size(a,1)
+    if (rem(i,5) == 0)
+      fprintf (fid,"         %2d - ", i);
+    else
+      fprintf (fid,"            | ");
+    endif
+    for j = 1:size(a,2)
+      if (a(i,j) == 0)
+	fprintf(fid,"  ")
+      else
+	fprintf(fid," *")
+      endif
+    endfor
+    fprintf(fid,"\n")
+  endfor
+  fprintf(fid,"            |-");
+  for j=1:size(a,2)
+    if (rem(j,5)==0)
+      fprintf(fid,"-|");
+    else
+      fprintf(fid,"--");
+    endif
+  endfor
+  fprintf(fid,"\n")
+  fprintf(fid,"              ");
+  for j=1:size(a,2)
+    if (rem(j,5)==0)
+      fprintf(fid,"%2d",j);
+    else
+      fprintf(fid,"  ");
+    endif
+  endfor
+  fclose(fid);
+endfunction
+
+function femimages (nm,typ)
+  bury_output ();
+  if (!isempty(findstr(octave_config_info ("DEFS"),"HAVE_COLAMD")) &&
+      !isempty(findstr(octave_config_info ("DEFS"),"HAVE_CHOLMOD")) &&
+      !isempty(findstr(octave_config_info ("DEFS"),"HAVE_UMFPACK")))
+    ## build a rectangle
+    node_y = [1;1.2;1.5;1.8;2]*ones(1,11);
+    node_x = ones(5,1)*[1,1.05,1.1,1.2,1.3,1.5,1.7,1.8,1.9,1.95,2];
+    nodes = [node_x(:), node_y(:)];
+
+    [h,w] = size(node_x);
+    elems = [];
+    for idx = 1:w-1
+      widx = (idx-1)*h;
+      elems = [elems; widx+[(1:h-1);(2:h);h+(1:h-1)]']; 
+      elems = [elems; widx+[(2:h);h+(2:h);h+(1:h-1)]']; 
+    endfor
+
+    E = size(elems,1);  #No. of elements
+    N = size(nodes,1);  #No. of elements
+    D = size(elems,2);  #dimentions+1
+
+    ## Plot FEM Geometry
+    elemx = elems(:,[1,2,3,1])';
+    xelems = reshape( nodes(elemx, 1), 4, E);
+    yelems = reshape( nodes(elemx, 2), 4, E);
+
+    ## Set element conductivity
+    conductivity = [1*ones(1,16),2*ones(1,48),1*ones(1,16)];
+
+    ## Dirichlet boundary conditions
+    D_nodes = [1:5, 51:55]; 
+    D_value = [10*ones(1,5), 20*ones(1,5)]; 
+  
+    ## Neumann boundary conditions
+    ## Note that N_value must be normalized by the boundary
+    ##   length and element conductivity
+    N_nodes = [];
+    N_value = [];
+
+    ## Calculate connectivity matrix
+    C = sparse((1:D*E), reshape(elems',D*E,1),1, D*E, N);
+
+    ## Calculate stiffness matrix
+    Siidx = floor([0:D*E-1]'/D)*D*ones(1,D) + ones(D*E,1)*(1:D) ;
+    Sjidx = [1:D*E]'*ones(1,D);
+    Sdata = zeros(D*E,D);
+    dfact = prod(2:(D-1));
+    for j = 1:E
+      a = inv([ ones(D,1), nodes( elems(j,:), : ) ]);
+      const = conductivity(j)*2/dfact/abs(det(a));
+      Sdata(D*(j-1)+(1:D),:)= const * a(2:D,:)'*a(2:D,:);
+    endfor
+
+    ## Element-wise system matrix
+    SE = sparse(Siidx,Sjidx,Sdata);
+    ## Global system matrix
+    S = C'* SE *C;
+
+    ## Set Dirichlet boundary
+    V = zeros(N,1);
+    V(D_nodes) = D_value;
+    idx = 1:N;
+    idx(D_nodes) = [];
+
+    ## Set Neumann boundary
+    Q = zeros(N,1);
+    Q(N_nodes) = N_value; # FIXME
+
+    V(idx) = S(idx,idx)\( Q(idx) - S(idx,D_nodes)*V(D_nodes) );
+
+    velems = reshape( V(elemx), 4, E);
+
+    sz = size(xelems,2);
+
+    plot3 (xelems, yelems, velems);
+    view (10, 10);
+    print(cstrcat(nm,".",typ),cstrcat("-d",typ))
+    bury_output ();
+  endif
+endfunction
+
+## There is no sparse matrix implementation available because of missing
+## libraries, plot sombreros instead. Also plot a nice title that we are
+## sorry about that.
+function sombreroimage (nm, typ)
+  if (strcmp (typ, "txt"))
+    fid = fopen (sprintf ("%s.txt", nm), "wt");
+    fputs (fid, "\n");
+    fputs (fid, "+---------------------------------------+\n");
+    fputs (fid, "| Image unavailable because of a        |\n");
+    fputs (fid, "| missing sparse matrix implementation. |\n");
+    fputs (fid, "+---------------------------------------+\n");
+    fclose (fid);
+    return;
+  else ## if (!strcmp (typ, "txt"))
+
+    bury_output ();
+
+    x = y = linspace (-8, 8, 41)';
+    [xx, yy] = meshgrid (x, y);
+    r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+    z = sin (r) ./ r;
+    unwind_protect
+      mesh (x, y, z);
+      title ("Sorry, graphics not available because octave was\\ncompiled without the sparse matrix implementation.");
+    unwind_protect_cleanup
+      print (cstrcat (nm, ".", typ), cstrcat ("-d", typ));
+      bury_output ();
+    end_unwind_protect
+  endif
+endfunction
+
+## generate something for the texinfo @image command to process
+function image_as_txt(nm)
+  fid = fopen (sprintf ("%s.txt", nm), "wt");
+  fputs (fid, "\n");
+  fputs (fid, "+---------------------------------+\n");
+  fputs (fid, "| Image unavailable in text mode. |\n");
+  fputs (fid, "+---------------------------------+\n");
+  fclose (fid);
+endfunction
diff --git a/doc/interpreter/spchol.eps b/doc/interpreter/spchol.eps
new file mode 100644
index 0000000..dbdeb2c
--- /dev/null
+++ b/doc/interpreter/spchol.eps
@@ -0,0 +1,10879 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: spchol.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:46:56 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (spchol.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:46:56 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6212 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6212 M
+[ [(Helvetica) 120.0 0.0 true true 0 (50)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4462 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4462 M
+[ [(Helvetica) 120.0 0.0 true true 0 (100)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2713 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2713 M
+[ [(Helvetica) 120.0 0.0 true true 0 (150)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 963 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 963 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3694 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3694 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (50)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5913 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5913 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (100)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8132 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8132 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (150)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10352 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10352 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+2.000 UP
+0.500 UL
+LT0
+0.00 0.00 1.00 C 1519 7927 Star
+1564 7927 Star
+1564 7892 Star
+1608 7892 Star
+1608 7857 Star
+1653 7892 Star
+1653 7857 Star
+1653 7822 Star
+1697 7857 Star
+1697 7822 Star
+1697 7787 Star
+1741 7857 Star
+1741 7822 Star
+1741 7787 Star
+1741 7752 Star
+1786 7822 Star
+1786 7787 Star
+1786 7752 Star
+1786 7717 Star
+1830 7822 Star
+1830 7787 Star
+1830 7752 Star
+1830 7717 Star
+1830 7682 Star
+1874 7787 Star
+1874 7752 Star
+1874 7717 Star
+1874 7682 Star
+1874 7647 Star
+1919 7787 Star
+1919 7752 Star
+1919 7717 Star
+1919 7682 Star
+1919 7647 Star
+1919 7612 Star
+1963 7752 Star
+1963 7717 Star
+1963 7682 Star
+1963 7647 Star
+1963 7612 Star
+1963 7577 Star
+2008 7752 Star
+2008 7717 Star
+2008 7682 Star
+2008 7647 Star
+2008 7612 Star
+2008 7577 Star
+2008 7542 Star
+2052 7717 Star
+2052 7682 Star
+2052 7647 Star
+2052 7612 Star
+2052 7577 Star
+2052 7542 Star
+2052 7507 Star
+2096 7717 Star
+2096 7682 Star
+2096 7647 Star
+2096 7612 Star
+2096 7577 Star
+2096 7542 Star
+2096 7507 Star
+2096 7472 Star
+2141 7682 Star
+2141 7647 Star
+2141 7612 Star
+2141 7577 Star
+2141 7542 Star
+2141 7507 Star
+2141 7472 Star
+2141 7437 Star
+2185 7682 Star
+2185 7647 Star
+2185 7612 Star
+2185 7577 Star
+2185 7542 Star
+2185 7507 Star
+2185 7472 Star
+2185 7437 Star
+2185 7402 Star
+2230 7647 Star
+2230 7612 Star
+2230 7577 Star
+2230 7542 Star
+2230 7507 Star
+2230 7472 Star
+2230 7437 Star
+2230 7402 Star
+2230 7367 Star
+2274 7647 Star
+2274 7612 Star
+2274 7577 Star
+2274 7542 Star
+2274 7507 Star
+2274 7472 Star
+2274 7437 Star
+2274 7402 Star
+2274 7367 Star
+2274 7332 Star
+2318 7612 Star
+2318 7577 Star
+2318 7542 Star
+2318 7507 Star
+2318 7472 Star
+2318 7437 Star
+2318 7402 Star
+2318 7367 Star
+2318 7332 Star
+2318 7297 Star
+2363 7612 Star
+2363 7577 Star
+2363 7542 Star
+2363 7507 Star
+2363 7472 Star
+2363 7437 Star
+2363 7402 Star
+2363 7367 Star
+2363 7332 Star
+2363 7297 Star
+2363 7262 Star
+2407 7577 Star
+2407 7542 Star
+2407 7507 Star
+2407 7472 Star
+2407 7437 Star
+2407 7402 Star
+2407 7367 Star
+2407 7332 Star
+2407 7297 Star
+2407 7262 Star
+2407 7227 Star
+2451 7577 Star
+2451 7542 Star
+2451 7507 Star
+2451 7472 Star
+2451 7437 Star
+2451 7402 Star
+2451 7367 Star
+2451 7332 Star
+2451 7297 Star
+2451 7262 Star
+2451 7227 Star
+2451 7192 Star
+2496 7542 Star
+2496 7507 Star
+2496 7472 Star
+2496 7437 Star
+2496 7402 Star
+2496 7367 Star
+2496 7332 Star
+2496 7297 Star
+2496 7262 Star
+2496 7227 Star
+2496 7192 Star
+2496 7157 Star
+2540 7542 Star
+2540 7507 Star
+2540 7472 Star
+2540 7437 Star
+2540 7402 Star
+2540 7367 Star
+2540 7332 Star
+2540 7297 Star
+2540 7262 Star
+2540 7227 Star
+2540 7192 Star
+2540 7157 Star
+2540 7122 Star
+2585 7507 Star
+2585 7472 Star
+2585 7437 Star
+2585 7402 Star
+2585 7367 Star
+2585 7332 Star
+2585 7297 Star
+2585 7262 Star
+2585 7227 Star
+2585 7192 Star
+2585 7157 Star
+2585 7122 Star
+2585 7087 Star
+2629 7507 Star
+2629 7472 Star
+2629 7437 Star
+2629 7402 Star
+2629 7367 Star
+2629 7332 Star
+2629 7297 Star
+2629 7262 Star
+2629 7227 Star
+2629 7192 Star
+2629 7157 Star
+2629 7122 Star
+2629 7087 Star
+2629 7052 Star
+2673 7472 Star
+2673 7437 Star
+2673 7402 Star
+2673 7367 Star
+2673 7332 Star
+2673 7297 Star
+2673 7262 Star
+2673 7227 Star
+2673 7192 Star
+2673 7157 Star
+2673 7122 Star
+2673 7087 Star
+2673 7052 Star
+2673 7017 Star
+2718 7472 Star
+2718 7437 Star
+2718 7402 Star
+2718 7367 Star
+2718 7332 Star
+2718 7297 Star
+2718 7262 Star
+2718 7227 Star
+2718 7192 Star
+2718 7157 Star
+2718 7122 Star
+2718 7087 Star
+2718 7052 Star
+2718 7017 Star
+2718 6982 Star
+2762 7437 Star
+2762 7402 Star
+2762 7367 Star
+2762 7332 Star
+2762 7297 Star
+2762 7262 Star
+2762 7227 Star
+2762 7192 Star
+2762 7157 Star
+2762 7122 Star
+2762 7087 Star
+2762 7052 Star
+2762 7017 Star
+2762 6982 Star
+2762 6947 Star
+2806 7437 Star
+2806 7402 Star
+2806 7367 Star
+2806 7332 Star
+2806 7297 Star
+2806 7262 Star
+2806 7227 Star
+2806 7192 Star
+2806 7157 Star
+2806 7122 Star
+2806 7087 Star
+2806 7052 Star
+2806 7017 Star
+2806 6982 Star
+2806 6947 Star
+2806 6912 Star
+2851 7402 Star
+2851 7367 Star
+2851 7332 Star
+2851 7297 Star
+2851 7262 Star
+2851 7227 Star
+2851 7192 Star
+2851 7157 Star
+2851 7122 Star
+2851 7087 Star
+2851 7052 Star
+2851 7017 Star
+2851 6982 Star
+2851 6947 Star
+2851 6912 Star
+2851 6877 Star
+2895 7402 Star
+2895 7367 Star
+2895 7332 Star
+2895 7297 Star
+2895 7262 Star
+2895 7227 Star
+2895 7192 Star
+2895 7157 Star
+2895 7122 Star
+2895 7087 Star
+2895 7052 Star
+2895 7017 Star
+2895 6982 Star
+2895 6947 Star
+2895 6912 Star
+2895 6877 Star
+2895 6842 Star
+2940 7367 Star
+2940 7332 Star
+2940 7297 Star
+2940 7262 Star
+2940 7227 Star
+2940 7192 Star
+2940 7157 Star
+2940 7122 Star
+2940 7087 Star
+2940 7052 Star
+2940 7017 Star
+2940 6982 Star
+2940 6947 Star
+2940 6912 Star
+2940 6877 Star
+2940 6842 Star
+2940 6807 Star
+2984 7367 Star
+2984 7332 Star
+2984 7297 Star
+2984 7262 Star
+2984 7227 Star
+2984 7192 Star
+2984 7157 Star
+2984 7122 Star
+2984 7087 Star
+2984 7052 Star
+2984 7017 Star
+2984 6982 Star
+2984 6947 Star
+2984 6912 Star
+2984 6877 Star
+2984 6842 Star
+2984 6807 Star
+2984 6772 Star
+3028 7332 Star
+3028 7297 Star
+3028 7262 Star
+3028 7227 Star
+3028 7192 Star
+3028 7157 Star
+3028 7122 Star
+3028 7087 Star
+3028 7052 Star
+3028 7017 Star
+3028 6982 Star
+3028 6947 Star
+3028 6912 Star
+3028 6877 Star
+3028 6842 Star
+3028 6807 Star
+3028 6772 Star
+3028 6737 Star
+3073 7332 Star
+3073 7297 Star
+3073 7262 Star
+3073 7227 Star
+3073 7192 Star
+3073 7157 Star
+3073 7122 Star
+3073 7087 Star
+3073 7052 Star
+3073 7017 Star
+3073 6982 Star
+3073 6947 Star
+3073 6912 Star
+3073 6877 Star
+3073 6842 Star
+3073 6807 Star
+3073 6772 Star
+3073 6737 Star
+3073 6702 Star
+3117 7297 Star
+3117 7262 Star
+3117 7227 Star
+3117 7192 Star
+3117 7157 Star
+3117 7122 Star
+3117 7087 Star
+3117 7052 Star
+3117 7017 Star
+3117 6982 Star
+3117 6947 Star
+3117 6912 Star
+3117 6877 Star
+3117 6842 Star
+3117 6807 Star
+3117 6772 Star
+3117 6737 Star
+3117 6702 Star
+3117 6667 Star
+3162 7297 Star
+3162 7262 Star
+3162 7227 Star
+3162 7192 Star
+3162 7157 Star
+3162 7122 Star
+3162 7087 Star
+3162 7052 Star
+3162 7017 Star
+3162 6982 Star
+3162 6947 Star
+3162 6912 Star
+3162 6877 Star
+3162 6842 Star
+3162 6807 Star
+3162 6772 Star
+3162 6737 Star
+3162 6702 Star
+3162 6667 Star
+3162 6632 Star
+3206 7262 Star
+3206 7227 Star
+3206 7192 Star
+3206 7157 Star
+3206 7122 Star
+3206 7087 Star
+3206 7052 Star
+3206 7017 Star
+3206 6982 Star
+3206 6947 Star
+3206 6912 Star
+3206 6877 Star
+3206 6842 Star
+3206 6807 Star
+3206 6772 Star
+3206 6737 Star
+3206 6702 Star
+3206 6667 Star
+3206 6632 Star
+3206 6597 Star
+3250 7262 Star
+3250 7227 Star
+3250 7192 Star
+3250 7157 Star
+3250 7122 Star
+3250 7087 Star
+3250 7052 Star
+3250 7017 Star
+3250 6982 Star
+3250 6947 Star
+3250 6912 Star
+3250 6877 Star
+3250 6842 Star
+3250 6807 Star
+3250 6772 Star
+3250 6737 Star
+3250 6702 Star
+3250 6667 Star
+3250 6632 Star
+3250 6597 Star
+3250 6562 Star
+3295 7227 Star
+3295 7192 Star
+3295 7157 Star
+3295 7122 Star
+3295 7087 Star
+3295 7052 Star
+3295 7017 Star
+3295 6982 Star
+3295 6947 Star
+3295 6912 Star
+3295 6877 Star
+3295 6842 Star
+3295 6807 Star
+3295 6772 Star
+3295 6737 Star
+3295 6702 Star
+3295 6667 Star
+3295 6632 Star
+3295 6597 Star
+3295 6562 Star
+3295 6527 Star
+3339 7227 Star
+3339 7192 Star
+3339 7157 Star
+3339 7122 Star
+3339 7087 Star
+3339 7052 Star
+3339 7017 Star
+3339 6982 Star
+3339 6947 Star
+3339 6912 Star
+3339 6877 Star
+3339 6842 Star
+3339 6807 Star
+3339 6772 Star
+3339 6737 Star
+3339 6702 Star
+3339 6667 Star
+3339 6632 Star
+3339 6597 Star
+3339 6562 Star
+3339 6527 Star
+3339 6492 Star
+3383 7192 Star
+3383 7157 Star
+3383 7122 Star
+3383 7087 Star
+3383 7052 Star
+3383 7017 Star
+3383 6982 Star
+3383 6947 Star
+3383 6912 Star
+3383 6877 Star
+3383 6842 Star
+3383 6807 Star
+3383 6772 Star
+3383 6737 Star
+3383 6702 Star
+3383 6667 Star
+3383 6632 Star
+3383 6597 Star
+3383 6562 Star
+3383 6527 Star
+3383 6492 Star
+3383 6457 Star
+3428 7192 Star
+3428 7157 Star
+3428 7122 Star
+3428 7087 Star
+3428 7052 Star
+3428 7017 Star
+3428 6982 Star
+3428 6947 Star
+3428 6912 Star
+3428 6877 Star
+3428 6842 Star
+3428 6807 Star
+3428 6772 Star
+3428 6737 Star
+3428 6702 Star
+3428 6667 Star
+3428 6632 Star
+3428 6597 Star
+3428 6562 Star
+3428 6527 Star
+3428 6492 Star
+3428 6457 Star
+3428 6422 Star
+3472 7157 Star
+3472 7122 Star
+3472 7087 Star
+3472 7052 Star
+3472 7017 Star
+3472 6982 Star
+3472 6947 Star
+3472 6912 Star
+3472 6877 Star
+3472 6842 Star
+3472 6807 Star
+3472 6772 Star
+3472 6737 Star
+3472 6702 Star
+3472 6667 Star
+3472 6632 Star
+3472 6597 Star
+3472 6562 Star
+3472 6527 Star
+3472 6492 Star
+3472 6457 Star
+3472 6422 Star
+3472 6387 Star
+3517 7157 Star
+3517 7122 Star
+3517 7087 Star
+3517 7052 Star
+3517 7017 Star
+3517 6982 Star
+3517 6947 Star
+3517 6912 Star
+3517 6877 Star
+3517 6842 Star
+3517 6807 Star
+3517 6772 Star
+3517 6737 Star
+3517 6702 Star
+3517 6667 Star
+3517 6632 Star
+3517 6597 Star
+3517 6562 Star
+3517 6527 Star
+3517 6492 Star
+3517 6457 Star
+3517 6422 Star
+3517 6387 Star
+3517 6352 Star
+3561 7122 Star
+3561 7087 Star
+3561 7052 Star
+3561 7017 Star
+3561 6982 Star
+3561 6947 Star
+3561 6912 Star
+3561 6877 Star
+3561 6842 Star
+3561 6807 Star
+3561 6772 Star
+3561 6737 Star
+3561 6702 Star
+3561 6667 Star
+3561 6632 Star
+3561 6597 Star
+3561 6562 Star
+3561 6527 Star
+3561 6492 Star
+3561 6457 Star
+3561 6422 Star
+3561 6387 Star
+3561 6352 Star
+3561 6317 Star
+3605 7122 Star
+3605 7087 Star
+3605 7052 Star
+3605 7017 Star
+3605 6982 Star
+3605 6947 Star
+3605 6912 Star
+3605 6877 Star
+3605 6842 Star
+3605 6807 Star
+3605 6772 Star
+3605 6737 Star
+3605 6702 Star
+3605 6667 Star
+3605 6632 Star
+3605 6597 Star
+3605 6562 Star
+3605 6527 Star
+3605 6492 Star
+3605 6457 Star
+3605 6422 Star
+3605 6387 Star
+3605 6352 Star
+3605 6317 Star
+3605 6282 Star
+3650 7087 Star
+3650 7052 Star
+3650 7017 Star
+3650 6982 Star
+3650 6947 Star
+3650 6912 Star
+3650 6877 Star
+3650 6842 Star
+3650 6807 Star
+3650 6772 Star
+3650 6737 Star
+3650 6702 Star
+3650 6667 Star
+3650 6632 Star
+3650 6597 Star
+3650 6562 Star
+3650 6527 Star
+3650 6492 Star
+3650 6457 Star
+3650 6422 Star
+3650 6387 Star
+3650 6352 Star
+3650 6317 Star
+3650 6282 Star
+3650 6247 Star
+3694 7087 Star
+3694 7052 Star
+3694 7017 Star
+3694 6982 Star
+3694 6947 Star
+3694 6912 Star
+3694 6877 Star
+3694 6842 Star
+3694 6807 Star
+3694 6772 Star
+3694 6737 Star
+3694 6702 Star
+3694 6667 Star
+3694 6632 Star
+3694 6597 Star
+3694 6562 Star
+3694 6527 Star
+3694 6492 Star
+3694 6457 Star
+3694 6422 Star
+3694 6387 Star
+3694 6352 Star
+3694 6317 Star
+3694 6282 Star
+3694 6247 Star
+3694 6212 Star
+3739 7052 Star
+3739 7017 Star
+3739 6982 Star
+3739 6947 Star
+3739 6912 Star
+3739 6877 Star
+3739 6842 Star
+3739 6807 Star
+3739 6772 Star
+3739 6737 Star
+3739 6702 Star
+3739 6667 Star
+3739 6632 Star
+3739 6597 Star
+3739 6562 Star
+3739 6527 Star
+3739 6492 Star
+3739 6457 Star
+3739 6422 Star
+3739 6387 Star
+3739 6352 Star
+3739 6317 Star
+3739 6282 Star
+3739 6247 Star
+3739 6212 Star
+3739 6177 Star
+3783 7052 Star
+3783 7017 Star
+3783 6982 Star
+3783 6947 Star
+3783 6912 Star
+3783 6877 Star
+3783 6842 Star
+3783 6807 Star
+3783 6772 Star
+3783 6737 Star
+3783 6702 Star
+3783 6667 Star
+3783 6632 Star
+3783 6597 Star
+3783 6562 Star
+3783 6527 Star
+3783 6492 Star
+3783 6457 Star
+3783 6422 Star
+3783 6387 Star
+3783 6352 Star
+3783 6317 Star
+3783 6282 Star
+3783 6247 Star
+3783 6212 Star
+3783 6177 Star
+3783 6142 Star
+3827 7017 Star
+3827 6982 Star
+3827 6947 Star
+3827 6912 Star
+3827 6877 Star
+3827 6842 Star
+3827 6807 Star
+3827 6772 Star
+3827 6737 Star
+3827 6702 Star
+3827 6667 Star
+3827 6632 Star
+3827 6597 Star
+3827 6562 Star
+3827 6527 Star
+3827 6492 Star
+3827 6457 Star
+3827 6422 Star
+3827 6387 Star
+3827 6352 Star
+3827 6317 Star
+3827 6282 Star
+3827 6247 Star
+3827 6212 Star
+3827 6177 Star
+3827 6142 Star
+3827 6107 Star
+3872 7017 Star
+3872 6982 Star
+3872 6947 Star
+3872 6912 Star
+3872 6877 Star
+3872 6842 Star
+3872 6807 Star
+3872 6772 Star
+3872 6737 Star
+3872 6702 Star
+3872 6667 Star
+3872 6632 Star
+3872 6597 Star
+3872 6562 Star
+3872 6527 Star
+3872 6492 Star
+3872 6457 Star
+3872 6422 Star
+3872 6387 Star
+3872 6352 Star
+3872 6317 Star
+3872 6282 Star
+3872 6247 Star
+3872 6212 Star
+3872 6177 Star
+3872 6142 Star
+3872 6107 Star
+3872 6072 Star
+3916 6982 Star
+3916 6947 Star
+3916 6912 Star
+3916 6877 Star
+3916 6842 Star
+3916 6807 Star
+3916 6772 Star
+3916 6737 Star
+3916 6702 Star
+3916 6667 Star
+3916 6632 Star
+3916 6597 Star
+3916 6562 Star
+3916 6527 Star
+3916 6492 Star
+3916 6457 Star
+3916 6422 Star
+3916 6387 Star
+3916 6352 Star
+3916 6317 Star
+3916 6282 Star
+3916 6247 Star
+3916 6212 Star
+3916 6177 Star
+3916 6142 Star
+3916 6107 Star
+3916 6072 Star
+3916 6037 Star
+3960 6982 Star
+3960 6947 Star
+3960 6912 Star
+3960 6877 Star
+3960 6842 Star
+3960 6807 Star
+3960 6772 Star
+3960 6737 Star
+3960 6702 Star
+3960 6667 Star
+3960 6632 Star
+3960 6597 Star
+3960 6562 Star
+3960 6527 Star
+3960 6492 Star
+3960 6457 Star
+3960 6422 Star
+3960 6387 Star
+3960 6352 Star
+3960 6317 Star
+3960 6282 Star
+3960 6247 Star
+3960 6212 Star
+3960 6177 Star
+3960 6142 Star
+3960 6107 Star
+3960 6072 Star
+3960 6037 Star
+3960 6002 Star
+4005 6947 Star
+4005 6912 Star
+4005 6877 Star
+4005 6842 Star
+4005 6807 Star
+4005 6772 Star
+4005 6737 Star
+4005 6702 Star
+4005 6667 Star
+4005 6632 Star
+4005 6597 Star
+4005 6562 Star
+4005 6527 Star
+4005 6492 Star
+4005 6457 Star
+4005 6422 Star
+4005 6387 Star
+4005 6352 Star
+4005 6317 Star
+4005 6282 Star
+4005 6247 Star
+4005 6212 Star
+4005 6177 Star
+4005 6142 Star
+4005 6107 Star
+4005 6072 Star
+4005 6037 Star
+4005 6002 Star
+4005 5967 Star
+4049 6947 Star
+4049 6912 Star
+4049 6877 Star
+4049 6842 Star
+4049 6807 Star
+4049 6772 Star
+4049 6737 Star
+4049 6702 Star
+4049 6667 Star
+4049 6632 Star
+4049 6597 Star
+4049 6562 Star
+4049 6527 Star
+4049 6492 Star
+4049 6457 Star
+4049 6422 Star
+4049 6387 Star
+4049 6352 Star
+4049 6317 Star
+4049 6282 Star
+4049 6247 Star
+4049 6212 Star
+4049 6177 Star
+4049 6142 Star
+4049 6107 Star
+4049 6072 Star
+4049 6037 Star
+4049 6002 Star
+4049 5967 Star
+4049 5932 Star
+4094 6912 Star
+4094 6877 Star
+4094 6842 Star
+4094 6807 Star
+4094 6772 Star
+4094 6737 Star
+4094 6702 Star
+4094 6667 Star
+4094 6632 Star
+4094 6597 Star
+4094 6562 Star
+4094 6527 Star
+4094 6492 Star
+4094 6457 Star
+4094 6422 Star
+4094 6387 Star
+4094 6352 Star
+4094 6317 Star
+4094 6282 Star
+4094 6247 Star
+4094 6212 Star
+4094 6177 Star
+4094 6142 Star
+4094 6107 Star
+4094 6072 Star
+4094 6037 Star
+4094 6002 Star
+4094 5967 Star
+4094 5932 Star
+4094 5897 Star
+4138 6912 Star
+4138 6877 Star
+4138 6842 Star
+4138 6807 Star
+4138 6772 Star
+4138 6737 Star
+4138 6702 Star
+4138 6667 Star
+4138 6632 Star
+4138 6597 Star
+4138 6562 Star
+4138 6527 Star
+4138 6492 Star
+4138 6457 Star
+4138 6422 Star
+4138 6387 Star
+4138 6352 Star
+4138 6317 Star
+4138 6282 Star
+4138 6247 Star
+4138 6212 Star
+4138 6177 Star
+4138 6142 Star
+4138 6107 Star
+4138 6072 Star
+4138 6037 Star
+4138 6002 Star
+4138 5967 Star
+4138 5932 Star
+4138 5897 Star
+4138 5862 Star
+4182 6877 Star
+4182 6842 Star
+4182 6807 Star
+4182 6772 Star
+4182 6737 Star
+4182 6702 Star
+4182 6667 Star
+4182 6632 Star
+4182 6597 Star
+4182 6562 Star
+4182 6527 Star
+4182 6492 Star
+4182 6457 Star
+4182 6422 Star
+4182 6387 Star
+4182 6352 Star
+4182 6317 Star
+4182 6282 Star
+4182 6247 Star
+4182 6212 Star
+4182 6177 Star
+4182 6142 Star
+4182 6107 Star
+4182 6072 Star
+4182 6037 Star
+4182 6002 Star
+4182 5967 Star
+4182 5932 Star
+4182 5897 Star
+4182 5862 Star
+4182 5827 Star
+4227 6877 Star
+4227 6842 Star
+4227 6807 Star
+4227 6772 Star
+4227 6737 Star
+4227 6702 Star
+4227 6667 Star
+4227 6632 Star
+4227 6597 Star
+4227 6562 Star
+4227 6527 Star
+4227 6492 Star
+4227 6457 Star
+4227 6422 Star
+4227 6387 Star
+4227 6352 Star
+4227 6317 Star
+4227 6282 Star
+4227 6247 Star
+4227 6212 Star
+4227 6177 Star
+4227 6142 Star
+4227 6107 Star
+4227 6072 Star
+4227 6037 Star
+4227 6002 Star
+4227 5967 Star
+4227 5932 Star
+4227 5897 Star
+4227 5862 Star
+4227 5827 Star
+4227 5792 Star
+4271 6842 Star
+4271 6807 Star
+4271 6772 Star
+4271 6737 Star
+4271 6702 Star
+4271 6667 Star
+4271 6632 Star
+4271 6597 Star
+4271 6562 Star
+4271 6527 Star
+4271 6492 Star
+4271 6457 Star
+4271 6422 Star
+4271 6387 Star
+4271 6352 Star
+4271 6317 Star
+4271 6282 Star
+4271 6247 Star
+4271 6212 Star
+4271 6177 Star
+4271 6142 Star
+4271 6107 Star
+4271 6072 Star
+4271 6037 Star
+4271 6002 Star
+4271 5967 Star
+4271 5932 Star
+4271 5897 Star
+4271 5862 Star
+4271 5827 Star
+4271 5792 Star
+4271 5757 Star
+4316 6842 Star
+4316 6807 Star
+4316 6772 Star
+4316 6737 Star
+4316 6702 Star
+4316 6667 Star
+4316 6632 Star
+4316 6597 Star
+4316 6562 Star
+4316 6527 Star
+4316 6492 Star
+4316 6457 Star
+4316 6422 Star
+4316 6387 Star
+4316 6352 Star
+4316 6317 Star
+4316 6282 Star
+4316 6247 Star
+4316 6212 Star
+4316 6177 Star
+4316 6142 Star
+4316 6107 Star
+4316 6072 Star
+4316 6037 Star
+4316 6002 Star
+4316 5967 Star
+4316 5932 Star
+4316 5897 Star
+4316 5862 Star
+4316 5827 Star
+4316 5792 Star
+4316 5757 Star
+4316 5722 Star
+4360 6807 Star
+4360 6772 Star
+4360 6737 Star
+4360 6702 Star
+4360 6667 Star
+4360 6632 Star
+4360 6597 Star
+4360 6562 Star
+4360 6527 Star
+4360 6492 Star
+4360 6457 Star
+4360 6422 Star
+4360 6387 Star
+4360 6352 Star
+4360 6317 Star
+4360 6282 Star
+4360 6247 Star
+4360 6212 Star
+4360 6177 Star
+4360 6142 Star
+4360 6107 Star
+4360 6072 Star
+4360 6037 Star
+4360 6002 Star
+4360 5967 Star
+4360 5932 Star
+4360 5897 Star
+4360 5862 Star
+4360 5827 Star
+4360 5792 Star
+4360 5757 Star
+4360 5722 Star
+4360 5687 Star
+4404 6807 Star
+4404 6772 Star
+4404 6737 Star
+4404 6702 Star
+4404 6667 Star
+4404 6632 Star
+4404 6597 Star
+4404 6562 Star
+4404 6527 Star
+4404 6492 Star
+4404 6457 Star
+4404 6422 Star
+4404 6387 Star
+4404 6352 Star
+4404 6317 Star
+4404 6282 Star
+4404 6247 Star
+4404 6212 Star
+4404 6177 Star
+4404 6142 Star
+4404 6107 Star
+4404 6072 Star
+4404 6037 Star
+4404 6002 Star
+4404 5967 Star
+4404 5932 Star
+4404 5897 Star
+4404 5862 Star
+4404 5827 Star
+4404 5792 Star
+4404 5757 Star
+4404 5722 Star
+4404 5687 Star
+4404 5652 Star
+4449 6772 Star
+4449 6737 Star
+4449 6702 Star
+4449 6667 Star
+4449 6632 Star
+4449 6597 Star
+4449 6562 Star
+4449 6527 Star
+4449 6492 Star
+4449 6457 Star
+4449 6422 Star
+4449 6387 Star
+4449 6352 Star
+4449 6317 Star
+4449 6282 Star
+4449 6247 Star
+4449 6212 Star
+4449 6177 Star
+4449 6142 Star
+4449 6107 Star
+4449 6072 Star
+4449 6037 Star
+4449 6002 Star
+4449 5967 Star
+4449 5932 Star
+4449 5897 Star
+4449 5862 Star
+4449 5827 Star
+4449 5792 Star
+4449 5757 Star
+4449 5722 Star
+4449 5687 Star
+4449 5652 Star
+4449 5617 Star
+4493 6772 Star
+4493 6737 Star
+4493 6702 Star
+4493 6667 Star
+4493 6632 Star
+4493 6597 Star
+4493 6562 Star
+4493 6527 Star
+4493 6492 Star
+4493 6457 Star
+4493 6422 Star
+4493 6387 Star
+4493 6352 Star
+4493 6317 Star
+4493 6282 Star
+4493 6247 Star
+4493 6212 Star
+4493 6177 Star
+4493 6142 Star
+4493 6107 Star
+4493 6072 Star
+4493 6037 Star
+4493 6002 Star
+4493 5967 Star
+4493 5932 Star
+4493 5897 Star
+4493 5862 Star
+4493 5827 Star
+4493 5792 Star
+4493 5757 Star
+4493 5722 Star
+4493 5687 Star
+4493 5652 Star
+4493 5617 Star
+4493 5582 Star
+4537 6737 Star
+4537 6702 Star
+4537 6667 Star
+4537 6632 Star
+4537 6597 Star
+4537 6562 Star
+4537 6527 Star
+4537 6492 Star
+4537 6457 Star
+4537 6422 Star
+4537 6387 Star
+4537 6352 Star
+4537 6317 Star
+4537 6282 Star
+4537 6247 Star
+4537 6212 Star
+4537 6177 Star
+4537 6142 Star
+4537 6107 Star
+4537 6072 Star
+4537 6037 Star
+4537 6002 Star
+4537 5967 Star
+4537 5932 Star
+4537 5897 Star
+4537 5862 Star
+4537 5827 Star
+4537 5792 Star
+4537 5757 Star
+4537 5722 Star
+4537 5687 Star
+4537 5652 Star
+4537 5617 Star
+4537 5582 Star
+4537 5547 Star
+4582 6737 Star
+4582 6702 Star
+4582 6667 Star
+4582 6632 Star
+4582 6597 Star
+4582 6562 Star
+4582 6527 Star
+4582 6492 Star
+4582 6457 Star
+4582 6422 Star
+4582 6387 Star
+4582 6352 Star
+4582 6317 Star
+4582 6282 Star
+4582 6247 Star
+4582 6212 Star
+4582 6177 Star
+4582 6142 Star
+4582 6107 Star
+4582 6072 Star
+4582 6037 Star
+4582 6002 Star
+4582 5967 Star
+4582 5932 Star
+4582 5897 Star
+4582 5862 Star
+4582 5827 Star
+4582 5792 Star
+4582 5757 Star
+4582 5722 Star
+4582 5687 Star
+4582 5652 Star
+4582 5617 Star
+4582 5582 Star
+4582 5547 Star
+4582 5512 Star
+4626 6702 Star
+4626 6667 Star
+4626 6632 Star
+4626 6597 Star
+4626 6562 Star
+4626 6527 Star
+4626 6492 Star
+4626 6457 Star
+4626 6422 Star
+4626 6387 Star
+4626 6352 Star
+4626 6317 Star
+4626 6282 Star
+4626 6247 Star
+4626 6212 Star
+4626 6177 Star
+4626 6142 Star
+4626 6107 Star
+4626 6072 Star
+4626 6037 Star
+4626 6002 Star
+4626 5967 Star
+4626 5932 Star
+4626 5897 Star
+4626 5862 Star
+4626 5827 Star
+4626 5792 Star
+4626 5757 Star
+4626 5722 Star
+4626 5687 Star
+4626 5652 Star
+4626 5617 Star
+4626 5582 Star
+4626 5547 Star
+4626 5512 Star
+4626 5477 Star
+4671 6702 Star
+4671 6667 Star
+4671 6632 Star
+4671 6597 Star
+4671 6562 Star
+4671 6527 Star
+4671 6492 Star
+4671 6457 Star
+4671 6422 Star
+4671 6387 Star
+4671 6352 Star
+4671 6317 Star
+4671 6282 Star
+4671 6247 Star
+4671 6212 Star
+4671 6177 Star
+4671 6142 Star
+4671 6107 Star
+4671 6072 Star
+4671 6037 Star
+4671 6002 Star
+4671 5967 Star
+4671 5932 Star
+4671 5897 Star
+4671 5862 Star
+4671 5827 Star
+4671 5792 Star
+4671 5757 Star
+4671 5722 Star
+4671 5687 Star
+4671 5652 Star
+4671 5617 Star
+4671 5582 Star
+4671 5547 Star
+4671 5512 Star
+4671 5477 Star
+4671 5442 Star
+4715 6667 Star
+4715 6632 Star
+4715 6597 Star
+4715 6562 Star
+4715 6527 Star
+4715 6492 Star
+4715 6457 Star
+4715 6422 Star
+4715 6387 Star
+4715 6352 Star
+4715 6317 Star
+4715 6282 Star
+4715 6247 Star
+4715 6212 Star
+4715 6177 Star
+4715 6142 Star
+4715 6107 Star
+4715 6072 Star
+4715 6037 Star
+4715 6002 Star
+4715 5967 Star
+4715 5932 Star
+4715 5897 Star
+4715 5862 Star
+4715 5827 Star
+4715 5792 Star
+4715 5757 Star
+4715 5722 Star
+4715 5687 Star
+4715 5652 Star
+4715 5617 Star
+4715 5582 Star
+4715 5547 Star
+4715 5512 Star
+4715 5477 Star
+4715 5442 Star
+4715 5407 Star
+4759 6667 Star
+4759 6632 Star
+4759 6597 Star
+4759 6562 Star
+4759 6527 Star
+4759 6492 Star
+4759 6457 Star
+4759 6422 Star
+4759 6387 Star
+4759 6352 Star
+4759 6317 Star
+4759 6282 Star
+4759 6247 Star
+4759 6212 Star
+4759 6177 Star
+4759 6142 Star
+4759 6107 Star
+4759 6072 Star
+4759 6037 Star
+4759 6002 Star
+4759 5967 Star
+4759 5932 Star
+4759 5897 Star
+4759 5862 Star
+4759 5827 Star
+4759 5792 Star
+4759 5757 Star
+4759 5722 Star
+4759 5687 Star
+4759 5652 Star
+4759 5617 Star
+4759 5582 Star
+4759 5547 Star
+4759 5512 Star
+4759 5477 Star
+4759 5442 Star
+4759 5407 Star
+4759 5372 Star
+4804 6632 Star
+4804 6597 Star
+4804 6562 Star
+4804 6527 Star
+4804 6492 Star
+4804 6457 Star
+4804 6422 Star
+4804 6387 Star
+4804 6352 Star
+4804 6317 Star
+4804 6282 Star
+4804 6247 Star
+4804 6212 Star
+4804 6177 Star
+4804 6142 Star
+4804 6107 Star
+4804 6072 Star
+4804 6037 Star
+4804 6002 Star
+4804 5967 Star
+4804 5932 Star
+4804 5897 Star
+4804 5862 Star
+4804 5827 Star
+4804 5792 Star
+4804 5757 Star
+4804 5722 Star
+4804 5687 Star
+4804 5652 Star
+4804 5617 Star
+4804 5582 Star
+4804 5547 Star
+4804 5512 Star
+4804 5477 Star
+4804 5442 Star
+4804 5407 Star
+4804 5372 Star
+4804 5337 Star
+4848 6632 Star
+4848 6597 Star
+4848 6562 Star
+4848 6527 Star
+4848 6492 Star
+4848 6457 Star
+4848 6422 Star
+4848 6387 Star
+4848 6352 Star
+4848 6317 Star
+4848 6282 Star
+4848 6247 Star
+4848 6212 Star
+4848 6177 Star
+4848 6142 Star
+4848 6107 Star
+4848 6072 Star
+4848 6037 Star
+4848 6002 Star
+4848 5967 Star
+4848 5932 Star
+4848 5897 Star
+4848 5862 Star
+4848 5827 Star
+4848 5792 Star
+4848 5757 Star
+4848 5722 Star
+4848 5687 Star
+4848 5652 Star
+4848 5617 Star
+4848 5582 Star
+4848 5547 Star
+4848 5512 Star
+4848 5477 Star
+4848 5442 Star
+4848 5407 Star
+4848 5372 Star
+4848 5337 Star
+4848 5302 Star
+4892 6597 Star
+4892 6562 Star
+4892 6527 Star
+4892 6492 Star
+4892 6457 Star
+4892 6422 Star
+4892 6387 Star
+4892 6352 Star
+4892 6317 Star
+4892 6282 Star
+4892 6247 Star
+4892 6212 Star
+4892 6177 Star
+4892 6142 Star
+4892 6107 Star
+4892 6072 Star
+4892 6037 Star
+4892 6002 Star
+4892 5967 Star
+4892 5932 Star
+4892 5897 Star
+4892 5862 Star
+4892 5827 Star
+4892 5792 Star
+4892 5757 Star
+4892 5722 Star
+4892 5687 Star
+4892 5652 Star
+4892 5617 Star
+4892 5582 Star
+4892 5547 Star
+4892 5512 Star
+4892 5477 Star
+4892 5442 Star
+4892 5407 Star
+4892 5372 Star
+4892 5337 Star
+4892 5302 Star
+4892 5267 Star
+4937 6597 Star
+4937 6562 Star
+4937 6527 Star
+4937 6492 Star
+4937 6457 Star
+4937 6422 Star
+4937 6387 Star
+4937 6352 Star
+4937 6317 Star
+4937 6282 Star
+4937 6247 Star
+4937 6212 Star
+4937 6177 Star
+4937 6142 Star
+4937 6107 Star
+4937 6072 Star
+4937 6037 Star
+4937 6002 Star
+4937 5967 Star
+4937 5932 Star
+4937 5897 Star
+4937 5862 Star
+4937 5827 Star
+4937 5792 Star
+4937 5757 Star
+4937 5722 Star
+4937 5687 Star
+4937 5652 Star
+4937 5617 Star
+4937 5582 Star
+4937 5547 Star
+4937 5512 Star
+4937 5477 Star
+4937 5442 Star
+4937 5407 Star
+4937 5372 Star
+4937 5337 Star
+4937 5302 Star
+4937 5267 Star
+4937 5232 Star
+4981 6562 Star
+4981 6527 Star
+4981 6492 Star
+4981 6457 Star
+4981 6422 Star
+4981 6387 Star
+4981 6352 Star
+4981 6317 Star
+4981 6282 Star
+4981 6247 Star
+4981 6212 Star
+4981 6177 Star
+4981 6142 Star
+4981 6107 Star
+4981 6072 Star
+4981 6037 Star
+4981 6002 Star
+4981 5967 Star
+4981 5932 Star
+4981 5897 Star
+4981 5862 Star
+4981 5827 Star
+4981 5792 Star
+4981 5757 Star
+4981 5722 Star
+4981 5687 Star
+4981 5652 Star
+4981 5617 Star
+4981 5582 Star
+4981 5547 Star
+4981 5512 Star
+4981 5477 Star
+4981 5442 Star
+4981 5407 Star
+4981 5372 Star
+4981 5337 Star
+4981 5302 Star
+4981 5267 Star
+4981 5232 Star
+4981 5197 Star
+5026 6562 Star
+5026 6527 Star
+5026 6492 Star
+5026 6457 Star
+5026 6422 Star
+5026 6387 Star
+5026 6352 Star
+5026 6317 Star
+5026 6282 Star
+5026 6247 Star
+5026 6212 Star
+5026 6177 Star
+5026 6142 Star
+5026 6107 Star
+5026 6072 Star
+5026 6037 Star
+5026 6002 Star
+5026 5967 Star
+5026 5932 Star
+5026 5897 Star
+5026 5862 Star
+5026 5827 Star
+5026 5792 Star
+5026 5757 Star
+5026 5722 Star
+5026 5687 Star
+5026 5652 Star
+5026 5617 Star
+5026 5582 Star
+5026 5547 Star
+5026 5512 Star
+5026 5477 Star
+5026 5442 Star
+5026 5407 Star
+5026 5372 Star
+5026 5337 Star
+5026 5302 Star
+5026 5267 Star
+5026 5232 Star
+5026 5197 Star
+5026 5162 Star
+5070 6527 Star
+5070 6492 Star
+5070 6457 Star
+5070 6422 Star
+5070 6387 Star
+5070 6352 Star
+5070 6317 Star
+5070 6282 Star
+5070 6247 Star
+5070 6212 Star
+5070 6177 Star
+5070 6142 Star
+5070 6107 Star
+5070 6072 Star
+5070 6037 Star
+5070 6002 Star
+5070 5967 Star
+5070 5932 Star
+5070 5897 Star
+5070 5862 Star
+5070 5827 Star
+5070 5792 Star
+5070 5757 Star
+5070 5722 Star
+5070 5687 Star
+5070 5652 Star
+5070 5617 Star
+5070 5582 Star
+5070 5547 Star
+5070 5512 Star
+5070 5477 Star
+5070 5442 Star
+5070 5407 Star
+5070 5372 Star
+5070 5337 Star
+5070 5302 Star
+5070 5267 Star
+5070 5232 Star
+5070 5197 Star
+5070 5162 Star
+5070 5127 Star
+5114 6527 Star
+5114 6492 Star
+5114 6457 Star
+5114 6422 Star
+5114 6387 Star
+5114 6352 Star
+5114 6317 Star
+5114 6282 Star
+5114 6247 Star
+5114 6212 Star
+5114 6177 Star
+5114 6142 Star
+5114 6107 Star
+5114 6072 Star
+5114 6037 Star
+5114 6002 Star
+5114 5967 Star
+5114 5932 Star
+5114 5897 Star
+5114 5862 Star
+5114 5827 Star
+5114 5792 Star
+5114 5757 Star
+5114 5722 Star
+5114 5687 Star
+5114 5652 Star
+5114 5617 Star
+5114 5582 Star
+5114 5547 Star
+5114 5512 Star
+5114 5477 Star
+5114 5442 Star
+5114 5407 Star
+5114 5372 Star
+5114 5337 Star
+5114 5302 Star
+5114 5267 Star
+5114 5232 Star
+5114 5197 Star
+5114 5162 Star
+5114 5127 Star
+5114 5092 Star
+5159 6492 Star
+5159 6457 Star
+5159 6422 Star
+5159 6387 Star
+5159 6352 Star
+5159 6317 Star
+5159 6282 Star
+5159 6247 Star
+5159 6212 Star
+5159 6177 Star
+5159 6142 Star
+5159 6107 Star
+5159 6072 Star
+5159 6037 Star
+5159 6002 Star
+5159 5967 Star
+5159 5932 Star
+5159 5897 Star
+5159 5862 Star
+5159 5827 Star
+5159 5792 Star
+5159 5757 Star
+5159 5722 Star
+5159 5687 Star
+5159 5652 Star
+5159 5617 Star
+5159 5582 Star
+5159 5547 Star
+5159 5512 Star
+5159 5477 Star
+5159 5442 Star
+5159 5407 Star
+5159 5372 Star
+5159 5337 Star
+5159 5302 Star
+5159 5267 Star
+5159 5232 Star
+5159 5197 Star
+5159 5162 Star
+5159 5127 Star
+5159 5092 Star
+5159 5057 Star
+5203 6492 Star
+5203 6457 Star
+5203 6422 Star
+5203 6387 Star
+5203 6352 Star
+5203 6317 Star
+5203 6282 Star
+5203 6247 Star
+5203 6212 Star
+5203 6177 Star
+5203 6142 Star
+5203 6107 Star
+5203 6072 Star
+5203 6037 Star
+5203 6002 Star
+5203 5967 Star
+5203 5932 Star
+5203 5897 Star
+5203 5862 Star
+5203 5827 Star
+5203 5792 Star
+5203 5757 Star
+5203 5722 Star
+5203 5687 Star
+5203 5652 Star
+5203 5617 Star
+5203 5582 Star
+5203 5547 Star
+5203 5512 Star
+5203 5477 Star
+5203 5442 Star
+5203 5407 Star
+5203 5372 Star
+5203 5337 Star
+5203 5302 Star
+5203 5267 Star
+5203 5232 Star
+5203 5197 Star
+5203 5162 Star
+5203 5127 Star
+5203 5092 Star
+5203 5057 Star
+5203 5022 Star
+5248 6457 Star
+5248 6422 Star
+5248 6387 Star
+5248 6352 Star
+5248 6317 Star
+5248 6282 Star
+5248 6247 Star
+5248 6212 Star
+5248 6177 Star
+5248 6142 Star
+5248 6107 Star
+5248 6072 Star
+5248 6037 Star
+5248 6002 Star
+5248 5967 Star
+5248 5932 Star
+5248 5897 Star
+5248 5862 Star
+5248 5827 Star
+5248 5792 Star
+5248 5757 Star
+5248 5722 Star
+5248 5687 Star
+5248 5652 Star
+5248 5617 Star
+5248 5582 Star
+5248 5547 Star
+5248 5512 Star
+5248 5477 Star
+5248 5442 Star
+5248 5407 Star
+5248 5372 Star
+5248 5337 Star
+5248 5302 Star
+5248 5267 Star
+5248 5232 Star
+5248 5197 Star
+5248 5162 Star
+5248 5127 Star
+5248 5092 Star
+5248 5057 Star
+5248 5022 Star
+5248 4987 Star
+5292 6457 Star
+5292 6422 Star
+5292 6387 Star
+5292 6352 Star
+5292 6317 Star
+5292 6282 Star
+5292 6247 Star
+5292 6212 Star
+5292 6177 Star
+5292 6142 Star
+5292 6107 Star
+5292 6072 Star
+5292 6037 Star
+5292 6002 Star
+5292 5967 Star
+5292 5932 Star
+5292 5897 Star
+5292 5862 Star
+5292 5827 Star
+5292 5792 Star
+5292 5757 Star
+5292 5722 Star
+5292 5687 Star
+5292 5652 Star
+5292 5617 Star
+5292 5582 Star
+5292 5547 Star
+5292 5512 Star
+5292 5477 Star
+5292 5442 Star
+5292 5407 Star
+5292 5372 Star
+5292 5337 Star
+5292 5302 Star
+5292 5267 Star
+5292 5232 Star
+5292 5197 Star
+5292 5162 Star
+5292 5127 Star
+5292 5092 Star
+5292 5057 Star
+5292 5022 Star
+5292 4987 Star
+5292 4952 Star
+5336 6422 Star
+5336 6387 Star
+5336 6352 Star
+5336 6317 Star
+5336 6282 Star
+5336 6247 Star
+5336 6212 Star
+5336 6177 Star
+5336 6142 Star
+5336 6107 Star
+5336 6072 Star
+5336 6037 Star
+5336 6002 Star
+5336 5967 Star
+5336 5932 Star
+5336 5897 Star
+5336 5862 Star
+5336 5827 Star
+5336 5792 Star
+5336 5757 Star
+5336 5722 Star
+5336 5687 Star
+5336 5652 Star
+5336 5617 Star
+5336 5582 Star
+5336 5547 Star
+5336 5512 Star
+5336 5477 Star
+5336 5442 Star
+5336 5407 Star
+5336 5372 Star
+5336 5337 Star
+5336 5302 Star
+5336 5267 Star
+5336 5232 Star
+5336 5197 Star
+5336 5162 Star
+5336 5127 Star
+5336 5092 Star
+5336 5057 Star
+5336 5022 Star
+5336 4987 Star
+5336 4952 Star
+5336 4917 Star
+5381 6422 Star
+5381 6387 Star
+5381 6352 Star
+5381 6317 Star
+5381 6282 Star
+5381 6247 Star
+5381 6212 Star
+5381 6177 Star
+5381 6142 Star
+5381 6107 Star
+5381 6072 Star
+5381 6037 Star
+5381 6002 Star
+5381 5967 Star
+5381 5932 Star
+5381 5897 Star
+5381 5862 Star
+5381 5827 Star
+5381 5792 Star
+5381 5757 Star
+5381 5722 Star
+5381 5687 Star
+5381 5652 Star
+5381 5617 Star
+5381 5582 Star
+5381 5547 Star
+5381 5512 Star
+5381 5477 Star
+5381 5442 Star
+5381 5407 Star
+5381 5372 Star
+5381 5337 Star
+5381 5302 Star
+5381 5267 Star
+5381 5232 Star
+5381 5197 Star
+5381 5162 Star
+5381 5127 Star
+5381 5092 Star
+5381 5057 Star
+5381 5022 Star
+5381 4987 Star
+5381 4952 Star
+5381 4917 Star
+5381 4882 Star
+5425 6387 Star
+5425 6352 Star
+5425 6317 Star
+5425 6282 Star
+5425 6247 Star
+5425 6212 Star
+5425 6177 Star
+5425 6142 Star
+5425 6107 Star
+5425 6072 Star
+5425 6037 Star
+5425 6002 Star
+5425 5967 Star
+5425 5932 Star
+5425 5897 Star
+5425 5862 Star
+5425 5827 Star
+5425 5792 Star
+5425 5757 Star
+5425 5722 Star
+5425 5687 Star
+5425 5652 Star
+5425 5617 Star
+5425 5582 Star
+5425 5547 Star
+5425 5512 Star
+5425 5477 Star
+5425 5442 Star
+5425 5407 Star
+5425 5372 Star
+5425 5337 Star
+5425 5302 Star
+5425 5267 Star
+5425 5232 Star
+5425 5197 Star
+5425 5162 Star
+5425 5127 Star
+5425 5092 Star
+5425 5057 Star
+5425 5022 Star
+5425 4987 Star
+5425 4952 Star
+5425 4917 Star
+5425 4882 Star
+5425 4847 Star
+5469 6387 Star
+5469 6352 Star
+5469 6317 Star
+5469 6282 Star
+5469 6247 Star
+5469 6212 Star
+5469 6177 Star
+5469 6142 Star
+5469 6107 Star
+5469 6072 Star
+5469 6037 Star
+5469 6002 Star
+5469 5967 Star
+5469 5932 Star
+5469 5897 Star
+5469 5862 Star
+5469 5827 Star
+5469 5792 Star
+5469 5757 Star
+5469 5722 Star
+5469 5687 Star
+5469 5652 Star
+5469 5617 Star
+5469 5582 Star
+5469 5547 Star
+5469 5512 Star
+5469 5477 Star
+5469 5442 Star
+5469 5407 Star
+5469 5372 Star
+5469 5337 Star
+5469 5302 Star
+5469 5267 Star
+5469 5232 Star
+5469 5197 Star
+5469 5162 Star
+5469 5127 Star
+5469 5092 Star
+5469 5057 Star
+5469 5022 Star
+5469 4987 Star
+5469 4952 Star
+5469 4917 Star
+5469 4882 Star
+5469 4847 Star
+5469 4812 Star
+5514 6352 Star
+5514 6317 Star
+5514 6282 Star
+5514 6247 Star
+5514 6212 Star
+5514 6177 Star
+5514 6142 Star
+5514 6107 Star
+5514 6072 Star
+5514 6037 Star
+5514 6002 Star
+5514 5967 Star
+5514 5932 Star
+5514 5897 Star
+5514 5862 Star
+5514 5827 Star
+5514 5792 Star
+5514 5757 Star
+5514 5722 Star
+5514 5687 Star
+5514 5652 Star
+5514 5617 Star
+5514 5582 Star
+5514 5547 Star
+5514 5512 Star
+5514 5477 Star
+5514 5442 Star
+5514 5407 Star
+5514 5372 Star
+5514 5337 Star
+5514 5302 Star
+5514 5267 Star
+5514 5232 Star
+5514 5197 Star
+5514 5162 Star
+5514 5127 Star
+5514 5092 Star
+5514 5057 Star
+5514 5022 Star
+5514 4987 Star
+5514 4952 Star
+5514 4917 Star
+5514 4882 Star
+5514 4847 Star
+5514 4812 Star
+5514 4777 Star
+5558 6352 Star
+5558 6317 Star
+5558 6282 Star
+5558 6247 Star
+5558 6212 Star
+5558 6177 Star
+5558 6142 Star
+5558 6107 Star
+5558 6072 Star
+5558 6037 Star
+5558 6002 Star
+5558 5967 Star
+5558 5932 Star
+5558 5897 Star
+5558 5862 Star
+5558 5827 Star
+5558 5792 Star
+5558 5757 Star
+5558 5722 Star
+5558 5687 Star
+5558 5652 Star
+5558 5617 Star
+5558 5582 Star
+5558 5547 Star
+5558 5512 Star
+5558 5477 Star
+5558 5442 Star
+5558 5407 Star
+5558 5372 Star
+5558 5337 Star
+5558 5302 Star
+5558 5267 Star
+5558 5232 Star
+5558 5197 Star
+5558 5162 Star
+5558 5127 Star
+5558 5092 Star
+5558 5057 Star
+5558 5022 Star
+5558 4987 Star
+5558 4952 Star
+5558 4917 Star
+5558 4882 Star
+5558 4847 Star
+5558 4812 Star
+5558 4777 Star
+5558 4742 Star
+5603 6317 Star
+5603 6282 Star
+5603 6247 Star
+5603 6212 Star
+5603 6177 Star
+5603 6142 Star
+5603 6107 Star
+5603 6072 Star
+5603 6037 Star
+5603 6002 Star
+5603 5967 Star
+5603 5932 Star
+5603 5897 Star
+5603 5862 Star
+5603 5827 Star
+5603 5792 Star
+5603 5757 Star
+5603 5722 Star
+5603 5687 Star
+5603 5652 Star
+5603 5617 Star
+5603 5582 Star
+5603 5547 Star
+5603 5512 Star
+5603 5477 Star
+5603 5442 Star
+5603 5407 Star
+5603 5372 Star
+5603 5337 Star
+5603 5302 Star
+5603 5267 Star
+5603 5232 Star
+5603 5197 Star
+5603 5162 Star
+5603 5127 Star
+5603 5092 Star
+5603 5057 Star
+5603 5022 Star
+5603 4987 Star
+5603 4952 Star
+5603 4917 Star
+5603 4882 Star
+5603 4847 Star
+5603 4812 Star
+5603 4777 Star
+5603 4742 Star
+5603 4707 Star
+5647 6317 Star
+5647 6282 Star
+5647 6247 Star
+5647 6212 Star
+5647 6177 Star
+5647 6142 Star
+5647 6107 Star
+5647 6072 Star
+5647 6037 Star
+5647 6002 Star
+5647 5967 Star
+5647 5932 Star
+5647 5897 Star
+5647 5862 Star
+5647 5827 Star
+5647 5792 Star
+5647 5757 Star
+5647 5722 Star
+5647 5687 Star
+5647 5652 Star
+5647 5617 Star
+5647 5582 Star
+5647 5547 Star
+5647 5512 Star
+5647 5477 Star
+5647 5442 Star
+5647 5407 Star
+5647 5372 Star
+5647 5337 Star
+5647 5302 Star
+5647 5267 Star
+5647 5232 Star
+5647 5197 Star
+5647 5162 Star
+5647 5127 Star
+5647 5092 Star
+5647 5057 Star
+5647 5022 Star
+5647 4987 Star
+5647 4952 Star
+5647 4917 Star
+5647 4882 Star
+5647 4847 Star
+5647 4812 Star
+5647 4777 Star
+5647 4742 Star
+5647 4707 Star
+5647 4672 Star
+5691 6282 Star
+5691 6247 Star
+5691 6212 Star
+5691 6177 Star
+5691 6142 Star
+5691 6107 Star
+5691 6072 Star
+5691 6037 Star
+5691 6002 Star
+5691 5967 Star
+5691 5932 Star
+5691 5897 Star
+5691 5862 Star
+5691 5827 Star
+5691 5792 Star
+5691 5757 Star
+5691 5722 Star
+5691 5687 Star
+5691 5652 Star
+5691 5617 Star
+5691 5582 Star
+5691 5547 Star
+5691 5512 Star
+5691 5477 Star
+5691 5442 Star
+5691 5407 Star
+5691 5372 Star
+5691 5337 Star
+5691 5302 Star
+5691 5267 Star
+5691 5232 Star
+5691 5197 Star
+5691 5162 Star
+5691 5127 Star
+5691 5092 Star
+5691 5057 Star
+5691 5022 Star
+5691 4987 Star
+5691 4952 Star
+5691 4917 Star
+5691 4882 Star
+5691 4847 Star
+5691 4812 Star
+5691 4777 Star
+5691 4742 Star
+5691 4707 Star
+5691 4672 Star
+5691 4637 Star
+5736 6282 Star
+5736 6247 Star
+5736 6212 Star
+5736 6177 Star
+5736 6142 Star
+5736 6107 Star
+5736 6072 Star
+5736 6037 Star
+5736 6002 Star
+5736 5967 Star
+5736 5932 Star
+5736 5897 Star
+5736 5862 Star
+5736 5827 Star
+5736 5792 Star
+5736 5757 Star
+5736 5722 Star
+5736 5687 Star
+5736 5652 Star
+5736 5617 Star
+5736 5582 Star
+5736 5547 Star
+5736 5512 Star
+5736 5477 Star
+5736 5442 Star
+5736 5407 Star
+5736 5372 Star
+5736 5337 Star
+5736 5302 Star
+5736 5267 Star
+5736 5232 Star
+5736 5197 Star
+5736 5162 Star
+5736 5127 Star
+5736 5092 Star
+5736 5057 Star
+5736 5022 Star
+5736 4987 Star
+5736 4952 Star
+5736 4917 Star
+5736 4882 Star
+5736 4847 Star
+5736 4812 Star
+5736 4777 Star
+5736 4742 Star
+5736 4707 Star
+5736 4672 Star
+5736 4637 Star
+5736 4602 Star
+5780 6247 Star
+5780 6212 Star
+5780 6177 Star
+5780 6142 Star
+5780 6107 Star
+5780 6072 Star
+5780 6037 Star
+5780 6002 Star
+5780 5967 Star
+5780 5932 Star
+5780 5897 Star
+5780 5862 Star
+5780 5827 Star
+5780 5792 Star
+5780 5757 Star
+5780 5722 Star
+5780 5687 Star
+5780 5652 Star
+5780 5617 Star
+5780 5582 Star
+5780 5547 Star
+5780 5512 Star
+5780 5477 Star
+5780 5442 Star
+5780 5407 Star
+5780 5372 Star
+5780 5337 Star
+5780 5302 Star
+5780 5267 Star
+5780 5232 Star
+5780 5197 Star
+5780 5162 Star
+5780 5127 Star
+5780 5092 Star
+5780 5057 Star
+5780 5022 Star
+5780 4987 Star
+5780 4952 Star
+5780 4917 Star
+5780 4882 Star
+5780 4847 Star
+5780 4812 Star
+5780 4777 Star
+5780 4742 Star
+5780 4707 Star
+5780 4672 Star
+5780 4637 Star
+5780 4602 Star
+5780 4567 Star
+5825 6247 Star
+5825 6212 Star
+5825 6177 Star
+5825 6142 Star
+5825 6107 Star
+5825 6072 Star
+5825 6037 Star
+5825 6002 Star
+5825 5967 Star
+5825 5932 Star
+5825 5897 Star
+5825 5862 Star
+5825 5827 Star
+5825 5792 Star
+5825 5757 Star
+5825 5722 Star
+5825 5687 Star
+5825 5652 Star
+5825 5617 Star
+5825 5582 Star
+5825 5547 Star
+5825 5512 Star
+5825 5477 Star
+5825 5442 Star
+5825 5407 Star
+5825 5372 Star
+5825 5337 Star
+5825 5302 Star
+5825 5267 Star
+5825 5232 Star
+5825 5197 Star
+5825 5162 Star
+5825 5127 Star
+5825 5092 Star
+5825 5057 Star
+5825 5022 Star
+5825 4987 Star
+5825 4952 Star
+5825 4917 Star
+5825 4882 Star
+5825 4847 Star
+5825 4812 Star
+5825 4777 Star
+5825 4742 Star
+5825 4707 Star
+5825 4672 Star
+5825 4637 Star
+5825 4602 Star
+5825 4567 Star
+5825 4532 Star
+5869 6212 Star
+5869 6177 Star
+5869 6142 Star
+5869 6107 Star
+5869 6072 Star
+5869 6037 Star
+5869 6002 Star
+5869 5967 Star
+5869 5932 Star
+5869 5897 Star
+5869 5862 Star
+5869 5827 Star
+5869 5792 Star
+5869 5757 Star
+5869 5722 Star
+5869 5687 Star
+5869 5652 Star
+5869 5617 Star
+5869 5582 Star
+5869 5547 Star
+5869 5512 Star
+5869 5477 Star
+5869 5442 Star
+5869 5407 Star
+5869 5372 Star
+5869 5337 Star
+5869 5302 Star
+5869 5267 Star
+5869 5232 Star
+5869 5197 Star
+5869 5162 Star
+5869 5127 Star
+5869 5092 Star
+5869 5057 Star
+5869 5022 Star
+5869 4987 Star
+5869 4952 Star
+5869 4917 Star
+5869 4882 Star
+5869 4847 Star
+5869 4812 Star
+5869 4777 Star
+5869 4742 Star
+5869 4707 Star
+5869 4672 Star
+5869 4637 Star
+5869 4602 Star
+5869 4567 Star
+5869 4532 Star
+5869 4497 Star
+5913 6212 Star
+5913 6177 Star
+5913 6142 Star
+5913 6107 Star
+5913 6072 Star
+5913 6037 Star
+5913 6002 Star
+5913 5967 Star
+5913 5932 Star
+5913 5897 Star
+5913 5862 Star
+5913 5827 Star
+5913 5792 Star
+5913 5757 Star
+5913 5722 Star
+5913 5687 Star
+5913 5652 Star
+5913 5617 Star
+5913 5582 Star
+5913 5547 Star
+5913 5512 Star
+5913 5477 Star
+5913 5442 Star
+5913 5407 Star
+5913 5372 Star
+5913 5337 Star
+5913 5302 Star
+5913 5267 Star
+5913 5232 Star
+5913 5197 Star
+5913 5162 Star
+5913 5127 Star
+5913 5092 Star
+5913 5057 Star
+5913 5022 Star
+5913 4987 Star
+5913 4952 Star
+5913 4917 Star
+5913 4882 Star
+5913 4847 Star
+5913 4812 Star
+5913 4777 Star
+5913 4742 Star
+5913 4707 Star
+5913 4672 Star
+5913 4637 Star
+5913 4602 Star
+5913 4567 Star
+5913 4532 Star
+5913 4497 Star
+5913 4462 Star
+5958 6177 Star
+5958 6142 Star
+5958 6107 Star
+5958 6072 Star
+5958 6037 Star
+5958 6002 Star
+5958 5967 Star
+5958 5932 Star
+5958 5897 Star
+5958 5862 Star
+5958 5827 Star
+5958 5792 Star
+5958 5757 Star
+5958 5722 Star
+5958 5687 Star
+5958 5652 Star
+5958 5617 Star
+5958 5582 Star
+5958 5547 Star
+5958 5512 Star
+5958 5477 Star
+5958 5442 Star
+5958 5407 Star
+5958 5372 Star
+5958 5337 Star
+5958 5302 Star
+5958 5267 Star
+5958 5232 Star
+5958 5197 Star
+5958 5162 Star
+5958 5127 Star
+5958 5092 Star
+5958 5057 Star
+5958 5022 Star
+5958 4987 Star
+5958 4952 Star
+5958 4917 Star
+5958 4882 Star
+5958 4847 Star
+5958 4812 Star
+5958 4777 Star
+5958 4742 Star
+5958 4707 Star
+5958 4672 Star
+5958 4637 Star
+5958 4602 Star
+5958 4567 Star
+5958 4532 Star
+5958 4497 Star
+5958 4462 Star
+5958 4428 Star
+6002 6177 Star
+6002 6142 Star
+6002 6107 Star
+6002 6072 Star
+6002 6037 Star
+6002 6002 Star
+6002 5967 Star
+6002 5932 Star
+6002 5897 Star
+6002 5862 Star
+6002 5827 Star
+6002 5792 Star
+6002 5757 Star
+6002 5722 Star
+6002 5687 Star
+6002 5652 Star
+6002 5617 Star
+6002 5582 Star
+6002 5547 Star
+6002 5512 Star
+6002 5477 Star
+6002 5442 Star
+6002 5407 Star
+6002 5372 Star
+6002 5337 Star
+6002 5302 Star
+6002 5267 Star
+6002 5232 Star
+6002 5197 Star
+6002 5162 Star
+6002 5127 Star
+6002 5092 Star
+6002 5057 Star
+6002 5022 Star
+6002 4987 Star
+6002 4952 Star
+6002 4917 Star
+6002 4882 Star
+6002 4847 Star
+6002 4812 Star
+6002 4777 Star
+6002 4742 Star
+6002 4707 Star
+6002 4672 Star
+6002 4637 Star
+6002 4602 Star
+6002 4567 Star
+6002 4532 Star
+6002 4497 Star
+6002 4462 Star
+6002 4428 Star
+6002 4393 Star
+6046 6142 Star
+6046 6107 Star
+6046 6072 Star
+6046 6037 Star
+6046 6002 Star
+6046 5967 Star
+6046 5932 Star
+6046 5897 Star
+6046 5862 Star
+6046 5827 Star
+6046 5792 Star
+6046 5757 Star
+6046 5722 Star
+6046 5687 Star
+6046 5652 Star
+6046 5617 Star
+6046 5582 Star
+6046 5547 Star
+6046 5512 Star
+6046 5477 Star
+6046 5442 Star
+6046 5407 Star
+6046 5372 Star
+6046 5337 Star
+6046 5302 Star
+6046 5267 Star
+6046 5232 Star
+6046 5197 Star
+6046 5162 Star
+6046 5127 Star
+6046 5092 Star
+6046 5057 Star
+6046 5022 Star
+6046 4987 Star
+6046 4952 Star
+6046 4917 Star
+6046 4882 Star
+6046 4847 Star
+6046 4812 Star
+6046 4777 Star
+6046 4742 Star
+6046 4707 Star
+6046 4672 Star
+6046 4637 Star
+6046 4602 Star
+6046 4567 Star
+6046 4532 Star
+6046 4497 Star
+6046 4462 Star
+6046 4428 Star
+6046 4393 Star
+6046 4358 Star
+6091 6142 Star
+6091 6107 Star
+6091 6072 Star
+6091 6037 Star
+6091 6002 Star
+6091 5967 Star
+6091 5932 Star
+6091 5897 Star
+6091 5862 Star
+6091 5827 Star
+6091 5792 Star
+6091 5757 Star
+6091 5722 Star
+6091 5687 Star
+6091 5652 Star
+6091 5617 Star
+6091 5582 Star
+6091 5547 Star
+6091 5512 Star
+6091 5477 Star
+6091 5442 Star
+6091 5407 Star
+6091 5372 Star
+6091 5337 Star
+6091 5302 Star
+6091 5267 Star
+6091 5232 Star
+6091 5197 Star
+6091 5162 Star
+6091 5127 Star
+6091 5092 Star
+6091 5057 Star
+6091 5022 Star
+6091 4987 Star
+6091 4952 Star
+6091 4917 Star
+6091 4882 Star
+6091 4847 Star
+6091 4812 Star
+6091 4777 Star
+6091 4742 Star
+6091 4707 Star
+6091 4672 Star
+6091 4637 Star
+6091 4602 Star
+6091 4567 Star
+6091 4532 Star
+6091 4497 Star
+6091 4462 Star
+6091 4428 Star
+6091 4393 Star
+6091 4358 Star
+6091 4323 Star
+6135 6107 Star
+6135 6072 Star
+6135 6037 Star
+6135 6002 Star
+6135 5967 Star
+6135 5932 Star
+6135 5897 Star
+6135 5862 Star
+6135 5827 Star
+6135 5792 Star
+6135 5757 Star
+6135 5722 Star
+6135 5687 Star
+6135 5652 Star
+6135 5617 Star
+6135 5582 Star
+6135 5547 Star
+6135 5512 Star
+6135 5477 Star
+6135 5442 Star
+6135 5407 Star
+6135 5372 Star
+6135 5337 Star
+6135 5302 Star
+6135 5267 Star
+6135 5232 Star
+6135 5197 Star
+6135 5162 Star
+6135 5127 Star
+6135 5092 Star
+6135 5057 Star
+6135 5022 Star
+6135 4987 Star
+6135 4952 Star
+6135 4917 Star
+6135 4882 Star
+6135 4847 Star
+6135 4812 Star
+6135 4777 Star
+6135 4742 Star
+6135 4707 Star
+6135 4672 Star
+6135 4637 Star
+6135 4602 Star
+6135 4567 Star
+6135 4532 Star
+6135 4497 Star
+6135 4462 Star
+6135 4428 Star
+6135 4393 Star
+6135 4358 Star
+6135 4323 Star
+6135 4288 Star
+6180 6107 Star
+6180 6072 Star
+6180 6037 Star
+6180 6002 Star
+6180 5967 Star
+6180 5932 Star
+6180 5897 Star
+6180 5862 Star
+6180 5827 Star
+6180 5792 Star
+6180 5757 Star
+6180 5722 Star
+6180 5687 Star
+6180 5652 Star
+6180 5617 Star
+6180 5582 Star
+6180 5547 Star
+6180 5512 Star
+6180 5477 Star
+6180 5442 Star
+6180 5407 Star
+6180 5372 Star
+6180 5337 Star
+6180 5302 Star
+6180 5267 Star
+6180 5232 Star
+6180 5197 Star
+6180 5162 Star
+6180 5127 Star
+6180 5092 Star
+6180 5057 Star
+6180 5022 Star
+6180 4987 Star
+6180 4952 Star
+6180 4917 Star
+6180 4882 Star
+6180 4847 Star
+6180 4812 Star
+6180 4777 Star
+6180 4742 Star
+6180 4707 Star
+6180 4672 Star
+6180 4637 Star
+6180 4602 Star
+6180 4567 Star
+6180 4532 Star
+6180 4497 Star
+6180 4462 Star
+6180 4428 Star
+6180 4393 Star
+6180 4358 Star
+6180 4323 Star
+6180 4288 Star
+6180 4253 Star
+6224 6072 Star
+6224 6037 Star
+6224 6002 Star
+6224 5967 Star
+6224 5932 Star
+6224 5897 Star
+6224 5862 Star
+6224 5827 Star
+6224 5792 Star
+6224 5757 Star
+6224 5722 Star
+6224 5687 Star
+6224 5652 Star
+6224 5617 Star
+6224 5582 Star
+6224 5547 Star
+6224 5512 Star
+6224 5477 Star
+6224 5442 Star
+6224 5407 Star
+6224 5372 Star
+6224 5337 Star
+6224 5302 Star
+6224 5267 Star
+6224 5232 Star
+6224 5197 Star
+6224 5162 Star
+6224 5127 Star
+6224 5092 Star
+6224 5057 Star
+6224 5022 Star
+6224 4987 Star
+6224 4952 Star
+6224 4917 Star
+6224 4882 Star
+6224 4847 Star
+6224 4812 Star
+6224 4777 Star
+6224 4742 Star
+6224 4707 Star
+6224 4672 Star
+6224 4637 Star
+6224 4602 Star
+6224 4567 Star
+6224 4532 Star
+6224 4497 Star
+6224 4462 Star
+6224 4428 Star
+6224 4393 Star
+6224 4358 Star
+6224 4323 Star
+6224 4288 Star
+6224 4253 Star
+6224 4218 Star
+6268 6072 Star
+6268 6037 Star
+6268 6002 Star
+6268 5967 Star
+6268 5932 Star
+6268 5897 Star
+6268 5862 Star
+6268 5827 Star
+6268 5792 Star
+6268 5757 Star
+6268 5722 Star
+6268 5687 Star
+6268 5652 Star
+6268 5617 Star
+6268 5582 Star
+6268 5547 Star
+6268 5512 Star
+6268 5477 Star
+6268 5442 Star
+6268 5407 Star
+6268 5372 Star
+6268 5337 Star
+6268 5302 Star
+6268 5267 Star
+6268 5232 Star
+6268 5197 Star
+6268 5162 Star
+6268 5127 Star
+6268 5092 Star
+6268 5057 Star
+6268 5022 Star
+6268 4987 Star
+6268 4952 Star
+6268 4917 Star
+6268 4882 Star
+6268 4847 Star
+6268 4812 Star
+6268 4777 Star
+6268 4742 Star
+6268 4707 Star
+6268 4672 Star
+6268 4637 Star
+6268 4602 Star
+6268 4567 Star
+6268 4532 Star
+6268 4497 Star
+6268 4462 Star
+6268 4428 Star
+6268 4393 Star
+6268 4358 Star
+6268 4323 Star
+6268 4288 Star
+6268 4253 Star
+6268 4218 Star
+6268 4183 Star
+6313 6037 Star
+6313 6002 Star
+6313 5967 Star
+6313 5932 Star
+6313 5897 Star
+6313 5862 Star
+6313 5827 Star
+6313 5792 Star
+6313 5757 Star
+6313 5722 Star
+6313 5687 Star
+6313 5652 Star
+6313 5617 Star
+6313 5582 Star
+6313 5547 Star
+6313 5512 Star
+6313 5477 Star
+6313 5442 Star
+6313 5407 Star
+6313 5372 Star
+6313 5337 Star
+6313 5302 Star
+6313 5267 Star
+6313 5232 Star
+6313 5197 Star
+6313 5162 Star
+6313 5127 Star
+6313 5092 Star
+6313 5057 Star
+6313 5022 Star
+6313 4987 Star
+6313 4952 Star
+6313 4917 Star
+6313 4882 Star
+6313 4847 Star
+6313 4812 Star
+6313 4777 Star
+6313 4742 Star
+6313 4707 Star
+6313 4672 Star
+6313 4637 Star
+6313 4602 Star
+6313 4567 Star
+6313 4532 Star
+6313 4497 Star
+6313 4462 Star
+6313 4428 Star
+6313 4393 Star
+6313 4358 Star
+6313 4323 Star
+6313 4288 Star
+6313 4253 Star
+6313 4218 Star
+6313 4183 Star
+6313 4148 Star
+6357 6037 Star
+6357 6002 Star
+6357 5967 Star
+6357 5932 Star
+6357 5897 Star
+6357 5862 Star
+6357 5827 Star
+6357 5792 Star
+6357 5757 Star
+6357 5722 Star
+6357 5687 Star
+6357 5652 Star
+6357 5617 Star
+6357 5582 Star
+6357 5547 Star
+6357 5512 Star
+6357 5477 Star
+6357 5442 Star
+6357 5407 Star
+6357 5372 Star
+6357 5337 Star
+6357 5302 Star
+6357 5267 Star
+6357 5232 Star
+6357 5197 Star
+6357 5162 Star
+6357 5127 Star
+6357 5092 Star
+6357 5057 Star
+6357 5022 Star
+6357 4987 Star
+6357 4952 Star
+6357 4917 Star
+6357 4882 Star
+6357 4847 Star
+6357 4812 Star
+6357 4777 Star
+6357 4742 Star
+6357 4707 Star
+6357 4672 Star
+6357 4637 Star
+6357 4602 Star
+6357 4567 Star
+6357 4532 Star
+6357 4497 Star
+6357 4462 Star
+6357 4428 Star
+6357 4393 Star
+6357 4358 Star
+6357 4323 Star
+6357 4288 Star
+6357 4253 Star
+6357 4218 Star
+6357 4183 Star
+6357 4148 Star
+6357 4113 Star
+6402 6002 Star
+6402 5967 Star
+6402 5932 Star
+6402 5897 Star
+6402 5862 Star
+6402 5827 Star
+6402 5792 Star
+6402 5757 Star
+6402 5722 Star
+6402 5687 Star
+6402 5652 Star
+6402 5617 Star
+6402 5582 Star
+6402 5547 Star
+6402 5512 Star
+6402 5477 Star
+6402 5442 Star
+6402 5407 Star
+6402 5372 Star
+6402 5337 Star
+6402 5302 Star
+6402 5267 Star
+6402 5232 Star
+6402 5197 Star
+6402 5162 Star
+6402 5127 Star
+6402 5092 Star
+6402 5057 Star
+6402 5022 Star
+6402 4987 Star
+6402 4952 Star
+6402 4917 Star
+6402 4882 Star
+6402 4847 Star
+6402 4812 Star
+6402 4777 Star
+6402 4742 Star
+6402 4707 Star
+6402 4672 Star
+6402 4637 Star
+6402 4602 Star
+6402 4567 Star
+6402 4532 Star
+6402 4497 Star
+6402 4462 Star
+6402 4428 Star
+6402 4393 Star
+6402 4358 Star
+6402 4323 Star
+6402 4288 Star
+6402 4253 Star
+6402 4218 Star
+6402 4183 Star
+6402 4148 Star
+6402 4113 Star
+6402 4078 Star
+6446 6002 Star
+6446 5967 Star
+6446 5932 Star
+6446 5897 Star
+6446 5862 Star
+6446 5827 Star
+6446 5792 Star
+6446 5757 Star
+6446 5722 Star
+6446 5687 Star
+6446 5652 Star
+6446 5617 Star
+6446 5582 Star
+6446 5547 Star
+6446 5512 Star
+6446 5477 Star
+6446 5442 Star
+6446 5407 Star
+6446 5372 Star
+6446 5337 Star
+6446 5302 Star
+6446 5267 Star
+6446 5232 Star
+6446 5197 Star
+6446 5162 Star
+6446 5127 Star
+6446 5092 Star
+6446 5057 Star
+6446 5022 Star
+6446 4987 Star
+6446 4952 Star
+6446 4917 Star
+6446 4882 Star
+6446 4847 Star
+6446 4812 Star
+6446 4777 Star
+6446 4742 Star
+6446 4707 Star
+6446 4672 Star
+6446 4637 Star
+6446 4602 Star
+6446 4567 Star
+6446 4532 Star
+6446 4497 Star
+6446 4462 Star
+6446 4428 Star
+6446 4393 Star
+6446 4358 Star
+6446 4323 Star
+6446 4288 Star
+6446 4253 Star
+6446 4218 Star
+6446 4183 Star
+6446 4148 Star
+6446 4113 Star
+6446 4078 Star
+6446 4043 Star
+6490 5967 Star
+6490 5932 Star
+6490 5897 Star
+6490 5862 Star
+6490 5827 Star
+6490 5792 Star
+6490 5757 Star
+6490 5722 Star
+6490 5687 Star
+6490 5652 Star
+6490 5617 Star
+6490 5582 Star
+6490 5547 Star
+6490 5512 Star
+6490 5477 Star
+6490 5442 Star
+6490 5407 Star
+6490 5372 Star
+6490 5337 Star
+6490 5302 Star
+6490 5267 Star
+6490 5232 Star
+6490 5197 Star
+6490 5162 Star
+6490 5127 Star
+6490 5092 Star
+6490 5057 Star
+6490 5022 Star
+6490 4987 Star
+6490 4952 Star
+6490 4917 Star
+6490 4882 Star
+6490 4847 Star
+6490 4812 Star
+6490 4777 Star
+6490 4742 Star
+6490 4707 Star
+6490 4672 Star
+6490 4637 Star
+6490 4602 Star
+6490 4567 Star
+6490 4532 Star
+6490 4497 Star
+6490 4462 Star
+6490 4428 Star
+6490 4393 Star
+6490 4358 Star
+6490 4323 Star
+6490 4288 Star
+6490 4253 Star
+6490 4218 Star
+6490 4183 Star
+6490 4148 Star
+6490 4113 Star
+6490 4078 Star
+6490 4043 Star
+6490 4008 Star
+6535 5967 Star
+6535 5932 Star
+6535 5897 Star
+6535 5862 Star
+6535 5827 Star
+6535 5792 Star
+6535 5757 Star
+6535 5722 Star
+6535 5687 Star
+6535 5652 Star
+6535 5617 Star
+6535 5582 Star
+6535 5547 Star
+6535 5512 Star
+6535 5477 Star
+6535 5442 Star
+6535 5407 Star
+6535 5372 Star
+6535 5337 Star
+6535 5302 Star
+6535 5267 Star
+6535 5232 Star
+6535 5197 Star
+6535 5162 Star
+6535 5127 Star
+6535 5092 Star
+6535 5057 Star
+6535 5022 Star
+6535 4987 Star
+6535 4952 Star
+6535 4917 Star
+6535 4882 Star
+6535 4847 Star
+6535 4812 Star
+6535 4777 Star
+6535 4742 Star
+6535 4707 Star
+6535 4672 Star
+6535 4637 Star
+6535 4602 Star
+6535 4567 Star
+6535 4532 Star
+6535 4497 Star
+6535 4462 Star
+6535 4428 Star
+6535 4393 Star
+6535 4358 Star
+6535 4323 Star
+6535 4288 Star
+6535 4253 Star
+6535 4218 Star
+6535 4183 Star
+6535 4148 Star
+6535 4113 Star
+6535 4078 Star
+6535 4043 Star
+6535 4008 Star
+6535 3973 Star
+6579 5932 Star
+6579 5897 Star
+6579 5862 Star
+6579 5827 Star
+6579 5792 Star
+6579 5757 Star
+6579 5722 Star
+6579 5687 Star
+6579 5652 Star
+6579 5617 Star
+6579 5582 Star
+6579 5547 Star
+6579 5512 Star
+6579 5477 Star
+6579 5442 Star
+6579 5407 Star
+6579 5372 Star
+6579 5337 Star
+6579 5302 Star
+6579 5267 Star
+6579 5232 Star
+6579 5197 Star
+6579 5162 Star
+6579 5127 Star
+6579 5092 Star
+6579 5057 Star
+6579 5022 Star
+6579 4987 Star
+6579 4952 Star
+6579 4917 Star
+6579 4882 Star
+6579 4847 Star
+6579 4812 Star
+6579 4777 Star
+6579 4742 Star
+6579 4707 Star
+6579 4672 Star
+6579 4637 Star
+6579 4602 Star
+6579 4567 Star
+6579 4532 Star
+6579 4497 Star
+6579 4462 Star
+6579 4428 Star
+6579 4393 Star
+6579 4358 Star
+6579 4323 Star
+6579 4288 Star
+6579 4253 Star
+6579 4218 Star
+6579 4183 Star
+6579 4148 Star
+6579 4113 Star
+6579 4078 Star
+6579 4043 Star
+6579 4008 Star
+6579 3973 Star
+6579 3938 Star
+6623 5932 Star
+6623 5897 Star
+6623 5862 Star
+6623 5827 Star
+6623 5792 Star
+6623 5757 Star
+6623 5722 Star
+6623 5687 Star
+6623 5652 Star
+6623 5617 Star
+6623 5582 Star
+6623 5547 Star
+6623 5512 Star
+6623 5477 Star
+6623 5442 Star
+6623 5407 Star
+6623 5372 Star
+6623 5337 Star
+6623 5302 Star
+6623 5267 Star
+6623 5232 Star
+6623 5197 Star
+6623 5162 Star
+6623 5127 Star
+6623 5092 Star
+6623 5057 Star
+6623 5022 Star
+6623 4987 Star
+6623 4952 Star
+6623 4917 Star
+6623 4882 Star
+6623 4847 Star
+6623 4812 Star
+6623 4777 Star
+6623 4742 Star
+6623 4707 Star
+6623 4672 Star
+6623 4637 Star
+6623 4602 Star
+6623 4567 Star
+6623 4532 Star
+6623 4497 Star
+6623 4462 Star
+6623 4428 Star
+6623 4393 Star
+6623 4358 Star
+6623 4323 Star
+6623 4288 Star
+6623 4253 Star
+6623 4218 Star
+6623 4183 Star
+6623 4148 Star
+6623 4113 Star
+6623 4078 Star
+6623 4043 Star
+6623 4008 Star
+6623 3973 Star
+6623 3938 Star
+6623 3903 Star
+6668 5897 Star
+6668 5862 Star
+6668 5827 Star
+6668 5792 Star
+6668 5757 Star
+6668 5722 Star
+6668 5687 Star
+6668 5652 Star
+6668 5617 Star
+6668 5582 Star
+6668 5547 Star
+6668 5512 Star
+6668 5477 Star
+6668 5442 Star
+6668 5407 Star
+6668 5372 Star
+6668 5337 Star
+6668 5302 Star
+6668 5267 Star
+6668 5232 Star
+6668 5197 Star
+6668 5162 Star
+6668 5127 Star
+6668 5092 Star
+6668 5057 Star
+6668 5022 Star
+6668 4987 Star
+6668 4952 Star
+6668 4917 Star
+6668 4882 Star
+6668 4847 Star
+6668 4812 Star
+6668 4777 Star
+6668 4742 Star
+6668 4707 Star
+6668 4672 Star
+6668 4637 Star
+6668 4602 Star
+6668 4567 Star
+6668 4532 Star
+6668 4497 Star
+6668 4462 Star
+6668 4428 Star
+6668 4393 Star
+6668 4358 Star
+6668 4323 Star
+6668 4288 Star
+6668 4253 Star
+6668 4218 Star
+6668 4183 Star
+6668 4148 Star
+6668 4113 Star
+6668 4078 Star
+6668 4043 Star
+6668 4008 Star
+6668 3973 Star
+6668 3938 Star
+6668 3903 Star
+6668 3868 Star
+6712 5897 Star
+6712 5862 Star
+6712 5827 Star
+6712 5792 Star
+6712 5757 Star
+6712 5722 Star
+6712 5687 Star
+6712 5652 Star
+6712 5617 Star
+6712 5582 Star
+6712 5547 Star
+6712 5512 Star
+6712 5477 Star
+6712 5442 Star
+6712 5407 Star
+6712 5372 Star
+6712 5337 Star
+6712 5302 Star
+6712 5267 Star
+6712 5232 Star
+6712 5197 Star
+6712 5162 Star
+6712 5127 Star
+6712 5092 Star
+6712 5057 Star
+6712 5022 Star
+6712 4987 Star
+6712 4952 Star
+6712 4917 Star
+6712 4882 Star
+6712 4847 Star
+6712 4812 Star
+6712 4777 Star
+6712 4742 Star
+6712 4707 Star
+6712 4672 Star
+6712 4637 Star
+6712 4602 Star
+6712 4567 Star
+6712 4532 Star
+6712 4497 Star
+6712 4462 Star
+6712 4428 Star
+6712 4393 Star
+6712 4358 Star
+6712 4323 Star
+6712 4288 Star
+6712 4253 Star
+6712 4218 Star
+6712 4183 Star
+6712 4148 Star
+6712 4113 Star
+6712 4078 Star
+6712 4043 Star
+6712 4008 Star
+6712 3973 Star
+6712 3938 Star
+6712 3903 Star
+6712 3868 Star
+6712 3833 Star
+6757 5862 Star
+6757 5827 Star
+6757 5792 Star
+6757 5757 Star
+6757 5722 Star
+6757 5687 Star
+6757 5652 Star
+6757 5617 Star
+6757 5582 Star
+6757 5547 Star
+6757 5512 Star
+6757 5477 Star
+6757 5442 Star
+6757 5407 Star
+6757 5372 Star
+6757 5337 Star
+6757 5302 Star
+6757 5267 Star
+6757 5232 Star
+6757 5197 Star
+6757 5162 Star
+6757 5127 Star
+6757 5092 Star
+6757 5057 Star
+6757 5022 Star
+6757 4987 Star
+6757 4952 Star
+6757 4917 Star
+6757 4882 Star
+6757 4847 Star
+6757 4812 Star
+6757 4777 Star
+6757 4742 Star
+6757 4707 Star
+6757 4672 Star
+6757 4637 Star
+6757 4602 Star
+6757 4567 Star
+6757 4532 Star
+6757 4497 Star
+6757 4462 Star
+6757 4428 Star
+6757 4393 Star
+6757 4358 Star
+6757 4323 Star
+6757 4288 Star
+6757 4253 Star
+6757 4218 Star
+6757 4183 Star
+6757 4148 Star
+6757 4113 Star
+6757 4078 Star
+6757 4043 Star
+6757 4008 Star
+6757 3973 Star
+6757 3938 Star
+6757 3903 Star
+6757 3868 Star
+6757 3833 Star
+6757 3798 Star
+6801 5862 Star
+6801 5827 Star
+6801 5792 Star
+6801 5757 Star
+6801 5722 Star
+6801 5687 Star
+6801 5652 Star
+6801 5617 Star
+6801 5582 Star
+6801 5547 Star
+6801 5512 Star
+6801 5477 Star
+6801 5442 Star
+6801 5407 Star
+6801 5372 Star
+6801 5337 Star
+6801 5302 Star
+6801 5267 Star
+6801 5232 Star
+6801 5197 Star
+6801 5162 Star
+6801 5127 Star
+6801 5092 Star
+6801 5057 Star
+6801 5022 Star
+6801 4987 Star
+6801 4952 Star
+6801 4917 Star
+6801 4882 Star
+6801 4847 Star
+6801 4812 Star
+6801 4777 Star
+6801 4742 Star
+6801 4707 Star
+6801 4672 Star
+6801 4637 Star
+6801 4602 Star
+6801 4567 Star
+6801 4532 Star
+6801 4497 Star
+6801 4462 Star
+6801 4428 Star
+6801 4393 Star
+6801 4358 Star
+6801 4323 Star
+6801 4288 Star
+6801 4253 Star
+6801 4218 Star
+6801 4183 Star
+6801 4148 Star
+6801 4113 Star
+6801 4078 Star
+6801 4043 Star
+6801 4008 Star
+6801 3973 Star
+6801 3938 Star
+6801 3903 Star
+6801 3868 Star
+6801 3833 Star
+6801 3798 Star
+6801 3763 Star
+6845 5827 Star
+6845 5792 Star
+6845 5757 Star
+6845 5722 Star
+6845 5687 Star
+6845 5652 Star
+6845 5617 Star
+6845 5582 Star
+6845 5547 Star
+6845 5512 Star
+6845 5477 Star
+6845 5442 Star
+6845 5407 Star
+6845 5372 Star
+6845 5337 Star
+6845 5302 Star
+6845 5267 Star
+6845 5232 Star
+6845 5197 Star
+6845 5162 Star
+6845 5127 Star
+6845 5092 Star
+6845 5057 Star
+6845 5022 Star
+6845 4987 Star
+6845 4952 Star
+6845 4917 Star
+6845 4882 Star
+6845 4847 Star
+6845 4812 Star
+6845 4777 Star
+6845 4742 Star
+6845 4707 Star
+6845 4672 Star
+6845 4637 Star
+6845 4602 Star
+6845 4567 Star
+6845 4532 Star
+6845 4497 Star
+6845 4462 Star
+6845 4428 Star
+6845 4393 Star
+6845 4358 Star
+6845 4323 Star
+6845 4288 Star
+6845 4253 Star
+6845 4218 Star
+6845 4183 Star
+6845 4148 Star
+6845 4113 Star
+6845 4078 Star
+6845 4043 Star
+6845 4008 Star
+6845 3973 Star
+6845 3938 Star
+6845 3903 Star
+6845 3868 Star
+6845 3833 Star
+6845 3798 Star
+6845 3763 Star
+6845 3728 Star
+6890 5827 Star
+6890 5792 Star
+6890 5757 Star
+6890 5722 Star
+6890 5687 Star
+6890 5652 Star
+6890 5617 Star
+6890 5582 Star
+6890 5547 Star
+6890 5512 Star
+6890 5477 Star
+6890 5442 Star
+6890 5407 Star
+6890 5372 Star
+6890 5337 Star
+6890 5302 Star
+6890 5267 Star
+6890 5232 Star
+6890 5197 Star
+6890 5162 Star
+6890 5127 Star
+6890 5092 Star
+6890 5057 Star
+6890 5022 Star
+6890 4987 Star
+6890 4952 Star
+6890 4917 Star
+6890 4882 Star
+6890 4847 Star
+6890 4812 Star
+6890 4777 Star
+6890 4742 Star
+6890 4707 Star
+6890 4672 Star
+6890 4637 Star
+6890 4602 Star
+6890 4567 Star
+6890 4532 Star
+6890 4497 Star
+6890 4462 Star
+6890 4428 Star
+6890 4393 Star
+6890 4358 Star
+6890 4323 Star
+6890 4288 Star
+6890 4253 Star
+6890 4218 Star
+6890 4183 Star
+6890 4148 Star
+6890 4113 Star
+6890 4078 Star
+6890 4043 Star
+6890 4008 Star
+6890 3973 Star
+6890 3938 Star
+6890 3903 Star
+6890 3868 Star
+6890 3833 Star
+6890 3798 Star
+6890 3763 Star
+6890 3728 Star
+6890 3693 Star
+6934 5792 Star
+6934 5757 Star
+6934 5722 Star
+6934 5687 Star
+6934 5652 Star
+6934 5617 Star
+6934 5582 Star
+6934 5547 Star
+6934 5512 Star
+6934 5477 Star
+6934 5442 Star
+6934 5407 Star
+6934 5372 Star
+6934 5337 Star
+6934 5302 Star
+6934 5267 Star
+6934 5232 Star
+6934 5197 Star
+6934 5162 Star
+6934 5127 Star
+6934 5092 Star
+6934 5057 Star
+6934 5022 Star
+6934 4987 Star
+6934 4952 Star
+6934 4917 Star
+6934 4882 Star
+6934 4847 Star
+6934 4812 Star
+6934 4777 Star
+6934 4742 Star
+6934 4707 Star
+6934 4672 Star
+6934 4637 Star
+6934 4602 Star
+6934 4567 Star
+6934 4532 Star
+6934 4497 Star
+6934 4462 Star
+6934 4428 Star
+6934 4393 Star
+6934 4358 Star
+6934 4323 Star
+6934 4288 Star
+6934 4253 Star
+6934 4218 Star
+6934 4183 Star
+6934 4148 Star
+6934 4113 Star
+6934 4078 Star
+6934 4043 Star
+6934 4008 Star
+6934 3973 Star
+6934 3938 Star
+6934 3903 Star
+6934 3868 Star
+6934 3833 Star
+6934 3798 Star
+6934 3763 Star
+6934 3728 Star
+6934 3693 Star
+6934 3658 Star
+6979 5792 Star
+6979 5757 Star
+6979 5722 Star
+6979 5687 Star
+6979 5652 Star
+6979 5617 Star
+6979 5582 Star
+6979 5547 Star
+6979 5512 Star
+6979 5477 Star
+6979 5442 Star
+6979 5407 Star
+6979 5372 Star
+6979 5337 Star
+6979 5302 Star
+6979 5267 Star
+6979 5232 Star
+6979 5197 Star
+6979 5162 Star
+6979 5127 Star
+6979 5092 Star
+6979 5057 Star
+6979 5022 Star
+6979 4987 Star
+6979 4952 Star
+6979 4917 Star
+6979 4882 Star
+6979 4847 Star
+6979 4812 Star
+6979 4777 Star
+6979 4742 Star
+6979 4707 Star
+6979 4672 Star
+6979 4637 Star
+6979 4602 Star
+6979 4567 Star
+6979 4532 Star
+6979 4497 Star
+6979 4462 Star
+6979 4428 Star
+6979 4393 Star
+6979 4358 Star
+6979 4323 Star
+6979 4288 Star
+6979 4253 Star
+6979 4218 Star
+6979 4183 Star
+6979 4148 Star
+6979 4113 Star
+6979 4078 Star
+6979 4043 Star
+6979 4008 Star
+6979 3973 Star
+6979 3938 Star
+6979 3903 Star
+6979 3868 Star
+6979 3833 Star
+6979 3798 Star
+6979 3763 Star
+6979 3728 Star
+6979 3693 Star
+6979 3658 Star
+6979 3623 Star
+7023 5757 Star
+7023 5722 Star
+7023 5687 Star
+7023 5652 Star
+7023 5617 Star
+7023 5582 Star
+7023 5547 Star
+7023 5512 Star
+7023 5477 Star
+7023 5442 Star
+7023 5407 Star
+7023 5372 Star
+7023 5337 Star
+7023 5302 Star
+7023 5267 Star
+7023 5232 Star
+7023 5197 Star
+7023 5162 Star
+7023 5127 Star
+7023 5092 Star
+7023 5057 Star
+7023 5022 Star
+7023 4987 Star
+7023 4952 Star
+7023 4917 Star
+7023 4882 Star
+7023 4847 Star
+7023 4812 Star
+7023 4777 Star
+7023 4742 Star
+7023 4707 Star
+7023 4672 Star
+7023 4637 Star
+7023 4602 Star
+7023 4567 Star
+7023 4532 Star
+7023 4497 Star
+7023 4462 Star
+7023 4428 Star
+7023 4393 Star
+7023 4358 Star
+7023 4323 Star
+7023 4288 Star
+7023 4253 Star
+7023 4218 Star
+7023 4183 Star
+7023 4148 Star
+7023 4113 Star
+7023 4078 Star
+7023 4043 Star
+7023 4008 Star
+7023 3973 Star
+7023 3938 Star
+7023 3903 Star
+7023 3868 Star
+7023 3833 Star
+7023 3798 Star
+7023 3763 Star
+7023 3728 Star
+7023 3693 Star
+7023 3658 Star
+7023 3623 Star
+7023 3588 Star
+7067 5757 Star
+7067 5722 Star
+7067 5687 Star
+7067 5652 Star
+7067 5617 Star
+7067 5582 Star
+7067 5547 Star
+7067 5512 Star
+7067 5477 Star
+7067 5442 Star
+7067 5407 Star
+7067 5372 Star
+7067 5337 Star
+7067 5302 Star
+7067 5267 Star
+7067 5232 Star
+7067 5197 Star
+7067 5162 Star
+7067 5127 Star
+7067 5092 Star
+7067 5057 Star
+7067 5022 Star
+7067 4987 Star
+7067 4952 Star
+7067 4917 Star
+7067 4882 Star
+7067 4847 Star
+7067 4812 Star
+7067 4777 Star
+7067 4742 Star
+7067 4707 Star
+7067 4672 Star
+7067 4637 Star
+7067 4602 Star
+7067 4567 Star
+7067 4532 Star
+7067 4497 Star
+7067 4462 Star
+7067 4428 Star
+7067 4393 Star
+7067 4358 Star
+7067 4323 Star
+7067 4288 Star
+7067 4253 Star
+7067 4218 Star
+7067 4183 Star
+7067 4148 Star
+7067 4113 Star
+7067 4078 Star
+7067 4043 Star
+7067 4008 Star
+7067 3973 Star
+7067 3938 Star
+7067 3903 Star
+7067 3868 Star
+7067 3833 Star
+7067 3798 Star
+7067 3763 Star
+7067 3728 Star
+7067 3693 Star
+7067 3658 Star
+7067 3623 Star
+7067 3588 Star
+7067 3553 Star
+7112 5722 Star
+7112 5687 Star
+7112 5652 Star
+7112 5617 Star
+7112 5582 Star
+7112 5547 Star
+7112 5512 Star
+7112 5477 Star
+7112 5442 Star
+7112 5407 Star
+7112 5372 Star
+7112 5337 Star
+7112 5302 Star
+7112 5267 Star
+7112 5232 Star
+7112 5197 Star
+7112 5162 Star
+7112 5127 Star
+7112 5092 Star
+7112 5057 Star
+7112 5022 Star
+7112 4987 Star
+7112 4952 Star
+7112 4917 Star
+7112 4882 Star
+7112 4847 Star
+7112 4812 Star
+7112 4777 Star
+7112 4742 Star
+7112 4707 Star
+7112 4672 Star
+7112 4637 Star
+7112 4602 Star
+7112 4567 Star
+7112 4532 Star
+7112 4497 Star
+7112 4462 Star
+7112 4428 Star
+7112 4393 Star
+7112 4358 Star
+7112 4323 Star
+7112 4288 Star
+7112 4253 Star
+7112 4218 Star
+7112 4183 Star
+7112 4148 Star
+7112 4113 Star
+7112 4078 Star
+7112 4043 Star
+7112 4008 Star
+7112 3973 Star
+7112 3938 Star
+7112 3903 Star
+7112 3868 Star
+7112 3833 Star
+7112 3798 Star
+7112 3763 Star
+7112 3728 Star
+7112 3693 Star
+7112 3658 Star
+7112 3623 Star
+7112 3588 Star
+7112 3553 Star
+7112 3518 Star
+7156 5722 Star
+7156 5687 Star
+7156 5652 Star
+7156 5617 Star
+7156 5582 Star
+7156 5547 Star
+7156 5512 Star
+7156 5477 Star
+7156 5442 Star
+7156 5407 Star
+7156 5372 Star
+7156 5337 Star
+7156 5302 Star
+7156 5267 Star
+7156 5232 Star
+7156 5197 Star
+7156 5162 Star
+7156 5127 Star
+7156 5092 Star
+7156 5057 Star
+7156 5022 Star
+7156 4987 Star
+7156 4952 Star
+7156 4917 Star
+7156 4882 Star
+7156 4847 Star
+7156 4812 Star
+7156 4777 Star
+7156 4742 Star
+7156 4707 Star
+7156 4672 Star
+7156 4637 Star
+7156 4602 Star
+7156 4567 Star
+7156 4532 Star
+7156 4497 Star
+7156 4462 Star
+7156 4428 Star
+7156 4393 Star
+7156 4358 Star
+7156 4323 Star
+7156 4288 Star
+7156 4253 Star
+7156 4218 Star
+7156 4183 Star
+7156 4148 Star
+7156 4113 Star
+7156 4078 Star
+7156 4043 Star
+7156 4008 Star
+7156 3973 Star
+7156 3938 Star
+7156 3903 Star
+7156 3868 Star
+7156 3833 Star
+7156 3798 Star
+7156 3763 Star
+7156 3728 Star
+7156 3693 Star
+7156 3658 Star
+7156 3623 Star
+7156 3588 Star
+7156 3553 Star
+7156 3518 Star
+7156 3483 Star
+7200 5687 Star
+7200 5652 Star
+7200 5617 Star
+7200 5582 Star
+7200 5547 Star
+7200 5512 Star
+7200 5477 Star
+7200 5442 Star
+7200 5407 Star
+7200 5372 Star
+7200 5337 Star
+7200 5302 Star
+7200 5267 Star
+7200 5232 Star
+7200 5197 Star
+7200 5162 Star
+7200 5127 Star
+7200 5092 Star
+7200 5057 Star
+7200 5022 Star
+7200 4987 Star
+7200 4952 Star
+7200 4917 Star
+7200 4882 Star
+7200 4847 Star
+7200 4812 Star
+7200 4777 Star
+7200 4742 Star
+7200 4707 Star
+7200 4672 Star
+7200 4637 Star
+7200 4602 Star
+7200 4567 Star
+7200 4532 Star
+7200 4497 Star
+7200 4462 Star
+7200 4428 Star
+7200 4393 Star
+7200 4358 Star
+7200 4323 Star
+7200 4288 Star
+7200 4253 Star
+7200 4218 Star
+7200 4183 Star
+7200 4148 Star
+7200 4113 Star
+7200 4078 Star
+7200 4043 Star
+7200 4008 Star
+7200 3973 Star
+7200 3938 Star
+7200 3903 Star
+7200 3868 Star
+7200 3833 Star
+7200 3798 Star
+7200 3763 Star
+7200 3728 Star
+7200 3693 Star
+7200 3658 Star
+7200 3623 Star
+7200 3588 Star
+7200 3553 Star
+7200 3518 Star
+7200 3483 Star
+7200 3448 Star
+7245 5687 Star
+7245 5652 Star
+7245 5617 Star
+7245 5582 Star
+7245 5547 Star
+7245 5512 Star
+7245 5477 Star
+7245 5442 Star
+7245 5407 Star
+7245 5372 Star
+7245 5337 Star
+7245 5302 Star
+7245 5267 Star
+7245 5232 Star
+7245 5197 Star
+7245 5162 Star
+7245 5127 Star
+7245 5092 Star
+7245 5057 Star
+7245 5022 Star
+7245 4987 Star
+7245 4952 Star
+7245 4917 Star
+7245 4882 Star
+7245 4847 Star
+7245 4812 Star
+7245 4777 Star
+7245 4742 Star
+7245 4707 Star
+7245 4672 Star
+7245 4637 Star
+7245 4602 Star
+7245 4567 Star
+7245 4532 Star
+7245 4497 Star
+7245 4462 Star
+7245 4428 Star
+7245 4393 Star
+7245 4358 Star
+7245 4323 Star
+7245 4288 Star
+7245 4253 Star
+7245 4218 Star
+7245 4183 Star
+7245 4148 Star
+7245 4113 Star
+7245 4078 Star
+7245 4043 Star
+7245 4008 Star
+7245 3973 Star
+7245 3938 Star
+7245 3903 Star
+7245 3868 Star
+7245 3833 Star
+7245 3798 Star
+7245 3763 Star
+7245 3728 Star
+7245 3693 Star
+7245 3658 Star
+7245 3623 Star
+7245 3588 Star
+7245 3553 Star
+7245 3518 Star
+7245 3483 Star
+7245 3448 Star
+7245 3413 Star
+7289 5652 Star
+7289 5617 Star
+7289 5582 Star
+7289 5547 Star
+7289 5512 Star
+7289 5477 Star
+7289 5442 Star
+7289 5407 Star
+7289 5372 Star
+7289 5337 Star
+7289 5302 Star
+7289 5267 Star
+7289 5232 Star
+7289 5197 Star
+7289 5162 Star
+7289 5127 Star
+7289 5092 Star
+7289 5057 Star
+7289 5022 Star
+7289 4987 Star
+7289 4952 Star
+7289 4917 Star
+7289 4882 Star
+7289 4847 Star
+7289 4812 Star
+7289 4777 Star
+7289 4742 Star
+7289 4707 Star
+7289 4672 Star
+7289 4637 Star
+7289 4602 Star
+7289 4567 Star
+7289 4532 Star
+7289 4497 Star
+7289 4462 Star
+7289 4428 Star
+7289 4393 Star
+7289 4358 Star
+7289 4323 Star
+7289 4288 Star
+7289 4253 Star
+7289 4218 Star
+7289 4183 Star
+7289 4148 Star
+7289 4113 Star
+7289 4078 Star
+7289 4043 Star
+7289 4008 Star
+7289 3973 Star
+7289 3938 Star
+7289 3903 Star
+7289 3868 Star
+7289 3833 Star
+7289 3798 Star
+7289 3763 Star
+7289 3728 Star
+7289 3693 Star
+7289 3658 Star
+7289 3623 Star
+7289 3588 Star
+7289 3553 Star
+7289 3518 Star
+7289 3483 Star
+7289 3448 Star
+7289 3413 Star
+7289 3378 Star
+7334 5652 Star
+7334 5617 Star
+7334 5582 Star
+7334 5547 Star
+7334 5512 Star
+7334 5477 Star
+7334 5442 Star
+7334 5407 Star
+7334 5372 Star
+7334 5337 Star
+7334 5302 Star
+7334 5267 Star
+7334 5232 Star
+7334 5197 Star
+7334 5162 Star
+7334 5127 Star
+7334 5092 Star
+7334 5057 Star
+7334 5022 Star
+7334 4987 Star
+7334 4952 Star
+7334 4917 Star
+7334 4882 Star
+7334 4847 Star
+7334 4812 Star
+7334 4777 Star
+7334 4742 Star
+7334 4707 Star
+7334 4672 Star
+7334 4637 Star
+7334 4602 Star
+7334 4567 Star
+7334 4532 Star
+7334 4497 Star
+7334 4462 Star
+7334 4428 Star
+7334 4393 Star
+7334 4358 Star
+7334 4323 Star
+7334 4288 Star
+7334 4253 Star
+7334 4218 Star
+7334 4183 Star
+7334 4148 Star
+7334 4113 Star
+7334 4078 Star
+7334 4043 Star
+7334 4008 Star
+7334 3973 Star
+7334 3938 Star
+7334 3903 Star
+7334 3868 Star
+7334 3833 Star
+7334 3798 Star
+7334 3763 Star
+7334 3728 Star
+7334 3693 Star
+7334 3658 Star
+7334 3623 Star
+7334 3588 Star
+7334 3553 Star
+7334 3518 Star
+7334 3483 Star
+7334 3448 Star
+7334 3413 Star
+7334 3378 Star
+7334 3343 Star
+7378 5617 Star
+7378 5582 Star
+7378 5547 Star
+7378 5512 Star
+7378 5477 Star
+7378 5442 Star
+7378 5407 Star
+7378 5372 Star
+7378 5337 Star
+7378 5302 Star
+7378 5267 Star
+7378 5232 Star
+7378 5197 Star
+7378 5162 Star
+7378 5127 Star
+7378 5092 Star
+7378 5057 Star
+7378 5022 Star
+7378 4987 Star
+7378 4952 Star
+7378 4917 Star
+7378 4882 Star
+7378 4847 Star
+7378 4812 Star
+7378 4777 Star
+7378 4742 Star
+7378 4707 Star
+7378 4672 Star
+7378 4637 Star
+7378 4602 Star
+7378 4567 Star
+7378 4532 Star
+7378 4497 Star
+7378 4462 Star
+7378 4428 Star
+7378 4393 Star
+7378 4358 Star
+7378 4323 Star
+7378 4288 Star
+7378 4253 Star
+7378 4218 Star
+7378 4183 Star
+7378 4148 Star
+7378 4113 Star
+7378 4078 Star
+7378 4043 Star
+7378 4008 Star
+7378 3973 Star
+7378 3938 Star
+7378 3903 Star
+7378 3868 Star
+7378 3833 Star
+7378 3798 Star
+7378 3763 Star
+7378 3728 Star
+7378 3693 Star
+7378 3658 Star
+7378 3623 Star
+7378 3588 Star
+7378 3553 Star
+7378 3518 Star
+7378 3483 Star
+7378 3448 Star
+7378 3413 Star
+7378 3378 Star
+7378 3343 Star
+7378 3308 Star
+7422 5617 Star
+7422 5582 Star
+7422 5547 Star
+7422 5512 Star
+7422 5477 Star
+7422 5442 Star
+7422 5407 Star
+7422 5372 Star
+7422 5337 Star
+7422 5302 Star
+7422 5267 Star
+7422 5232 Star
+7422 5197 Star
+7422 5162 Star
+7422 5127 Star
+7422 5092 Star
+7422 5057 Star
+7422 5022 Star
+7422 4987 Star
+7422 4952 Star
+7422 4917 Star
+7422 4882 Star
+7422 4847 Star
+7422 4812 Star
+7422 4777 Star
+7422 4742 Star
+7422 4707 Star
+7422 4672 Star
+7422 4637 Star
+7422 4602 Star
+7422 4567 Star
+7422 4532 Star
+7422 4497 Star
+7422 4462 Star
+7422 4428 Star
+7422 4393 Star
+7422 4358 Star
+7422 4323 Star
+7422 4288 Star
+7422 4253 Star
+7422 4218 Star
+7422 4183 Star
+7422 4148 Star
+7422 4113 Star
+7422 4078 Star
+7422 4043 Star
+7422 4008 Star
+7422 3973 Star
+7422 3938 Star
+7422 3903 Star
+7422 3868 Star
+7422 3833 Star
+7422 3798 Star
+7422 3763 Star
+7422 3728 Star
+7422 3693 Star
+7422 3658 Star
+7422 3623 Star
+7422 3588 Star
+7422 3553 Star
+7422 3518 Star
+7422 3483 Star
+7422 3448 Star
+7422 3413 Star
+7422 3378 Star
+7422 3343 Star
+7422 3308 Star
+7422 3273 Star
+7467 5582 Star
+7467 5547 Star
+7467 5512 Star
+7467 5477 Star
+7467 5442 Star
+7467 5407 Star
+7467 5372 Star
+7467 5337 Star
+7467 5302 Star
+7467 5267 Star
+7467 5232 Star
+7467 5197 Star
+7467 5162 Star
+7467 5127 Star
+7467 5092 Star
+7467 5057 Star
+7467 5022 Star
+7467 4987 Star
+7467 4952 Star
+7467 4917 Star
+7467 4882 Star
+7467 4847 Star
+7467 4812 Star
+7467 4777 Star
+7467 4742 Star
+7467 4707 Star
+7467 4672 Star
+7467 4637 Star
+7467 4602 Star
+7467 4567 Star
+7467 4532 Star
+7467 4497 Star
+7467 4462 Star
+7467 4428 Star
+7467 4393 Star
+7467 4358 Star
+7467 4323 Star
+7467 4288 Star
+7467 4253 Star
+7467 4218 Star
+7467 4183 Star
+7467 4148 Star
+7467 4113 Star
+7467 4078 Star
+7467 4043 Star
+7467 4008 Star
+7467 3973 Star
+7467 3938 Star
+7467 3903 Star
+7467 3868 Star
+7467 3833 Star
+7467 3798 Star
+7467 3763 Star
+7467 3728 Star
+7467 3693 Star
+7467 3658 Star
+7467 3623 Star
+7467 3588 Star
+7467 3553 Star
+7467 3518 Star
+7467 3483 Star
+7467 3448 Star
+7467 3413 Star
+7467 3378 Star
+7467 3343 Star
+7467 3308 Star
+7467 3273 Star
+7467 3238 Star
+7511 5582 Star
+7511 5547 Star
+7511 5512 Star
+7511 5477 Star
+7511 5442 Star
+7511 5407 Star
+7511 5372 Star
+7511 5337 Star
+7511 5302 Star
+7511 5267 Star
+7511 5232 Star
+7511 5197 Star
+7511 5162 Star
+7511 5127 Star
+7511 5092 Star
+7511 5057 Star
+7511 5022 Star
+7511 4987 Star
+7511 4952 Star
+7511 4917 Star
+7511 4882 Star
+7511 4847 Star
+7511 4812 Star
+7511 4777 Star
+7511 4742 Star
+7511 4707 Star
+7511 4672 Star
+7511 4637 Star
+7511 4602 Star
+7511 4567 Star
+7511 4532 Star
+7511 4497 Star
+7511 4462 Star
+7511 4428 Star
+7511 4393 Star
+7511 4358 Star
+7511 4323 Star
+7511 4288 Star
+7511 4253 Star
+7511 4218 Star
+7511 4183 Star
+7511 4148 Star
+7511 4113 Star
+7511 4078 Star
+7511 4043 Star
+7511 4008 Star
+7511 3973 Star
+7511 3938 Star
+7511 3903 Star
+7511 3868 Star
+7511 3833 Star
+7511 3798 Star
+7511 3763 Star
+7511 3728 Star
+7511 3693 Star
+7511 3658 Star
+7511 3623 Star
+7511 3588 Star
+7511 3553 Star
+7511 3518 Star
+7511 3483 Star
+7511 3448 Star
+7511 3413 Star
+7511 3378 Star
+7511 3343 Star
+7511 3308 Star
+7511 3273 Star
+7511 3238 Star
+7511 3203 Star
+7555 5547 Star
+7555 5512 Star
+7555 5477 Star
+7555 5442 Star
+7555 5407 Star
+7555 5372 Star
+7555 5337 Star
+7555 5302 Star
+7555 5267 Star
+7555 5232 Star
+7555 5197 Star
+7555 5162 Star
+7555 5127 Star
+7555 5092 Star
+7555 5057 Star
+7555 5022 Star
+7555 4987 Star
+7555 4952 Star
+7555 4917 Star
+7555 4882 Star
+7555 4847 Star
+7555 4812 Star
+7555 4777 Star
+7555 4742 Star
+7555 4707 Star
+7555 4672 Star
+7555 4637 Star
+7555 4602 Star
+7555 4567 Star
+7555 4532 Star
+7555 4497 Star
+7555 4462 Star
+7555 4428 Star
+7555 4393 Star
+7555 4358 Star
+7555 4323 Star
+7555 4288 Star
+7555 4253 Star
+7555 4218 Star
+7555 4183 Star
+7555 4148 Star
+7555 4113 Star
+7555 4078 Star
+7555 4043 Star
+7555 4008 Star
+7555 3973 Star
+7555 3938 Star
+7555 3903 Star
+7555 3868 Star
+7555 3833 Star
+7555 3798 Star
+7555 3763 Star
+7555 3728 Star
+7555 3693 Star
+7555 3658 Star
+7555 3623 Star
+7555 3588 Star
+7555 3553 Star
+7555 3518 Star
+7555 3483 Star
+7555 3448 Star
+7555 3413 Star
+7555 3378 Star
+7555 3343 Star
+7555 3308 Star
+7555 3273 Star
+7555 3238 Star
+7555 3203 Star
+7555 3168 Star
+7600 5547 Star
+7600 5512 Star
+7600 5477 Star
+7600 5442 Star
+7600 5407 Star
+7600 5372 Star
+7600 5337 Star
+7600 5302 Star
+7600 5267 Star
+7600 5232 Star
+7600 5197 Star
+7600 5162 Star
+7600 5127 Star
+7600 5092 Star
+7600 5057 Star
+7600 5022 Star
+7600 4987 Star
+7600 4952 Star
+7600 4917 Star
+7600 4882 Star
+7600 4847 Star
+7600 4812 Star
+7600 4777 Star
+7600 4742 Star
+7600 4707 Star
+7600 4672 Star
+7600 4637 Star
+7600 4602 Star
+7600 4567 Star
+7600 4532 Star
+7600 4497 Star
+7600 4462 Star
+7600 4428 Star
+7600 4393 Star
+7600 4358 Star
+7600 4323 Star
+7600 4288 Star
+7600 4253 Star
+7600 4218 Star
+7600 4183 Star
+7600 4148 Star
+7600 4113 Star
+7600 4078 Star
+7600 4043 Star
+7600 4008 Star
+7600 3973 Star
+7600 3938 Star
+7600 3903 Star
+7600 3868 Star
+7600 3833 Star
+7600 3798 Star
+7600 3763 Star
+7600 3728 Star
+7600 3693 Star
+7600 3658 Star
+7600 3623 Star
+7600 3588 Star
+7600 3553 Star
+7600 3518 Star
+7600 3483 Star
+7600 3448 Star
+7600 3413 Star
+7600 3378 Star
+7600 3343 Star
+7600 3308 Star
+7600 3273 Star
+7600 3238 Star
+7600 3203 Star
+7600 3168 Star
+7600 3133 Star
+7644 5512 Star
+7644 5477 Star
+7644 5442 Star
+7644 5407 Star
+7644 5372 Star
+7644 5337 Star
+7644 5302 Star
+7644 5267 Star
+7644 5232 Star
+7644 5197 Star
+7644 5162 Star
+7644 5127 Star
+7644 5092 Star
+7644 5057 Star
+7644 5022 Star
+7644 4987 Star
+7644 4952 Star
+7644 4917 Star
+7644 4882 Star
+7644 4847 Star
+7644 4812 Star
+7644 4777 Star
+7644 4742 Star
+7644 4707 Star
+7644 4672 Star
+7644 4637 Star
+7644 4602 Star
+7644 4567 Star
+7644 4532 Star
+7644 4497 Star
+7644 4462 Star
+7644 4428 Star
+7644 4393 Star
+7644 4358 Star
+7644 4323 Star
+7644 4288 Star
+7644 4253 Star
+7644 4218 Star
+7644 4183 Star
+7644 4148 Star
+7644 4113 Star
+7644 4078 Star
+7644 4043 Star
+7644 4008 Star
+7644 3973 Star
+7644 3938 Star
+7644 3903 Star
+7644 3868 Star
+7644 3833 Star
+7644 3798 Star
+7644 3763 Star
+7644 3728 Star
+7644 3693 Star
+7644 3658 Star
+7644 3623 Star
+7644 3588 Star
+7644 3553 Star
+7644 3518 Star
+7644 3483 Star
+7644 3448 Star
+7644 3413 Star
+7644 3378 Star
+7644 3343 Star
+7644 3308 Star
+7644 3273 Star
+7644 3238 Star
+7644 3203 Star
+7644 3168 Star
+7644 3133 Star
+7644 3098 Star
+7689 5512 Star
+7689 5477 Star
+7689 5442 Star
+7689 5407 Star
+7689 5372 Star
+7689 5337 Star
+7689 5302 Star
+7689 5267 Star
+7689 5232 Star
+7689 5197 Star
+7689 5162 Star
+7689 5127 Star
+7689 5092 Star
+7689 5057 Star
+7689 5022 Star
+7689 4987 Star
+7689 4952 Star
+7689 4917 Star
+7689 4882 Star
+7689 4847 Star
+7689 4812 Star
+7689 4777 Star
+7689 4742 Star
+7689 4707 Star
+7689 4672 Star
+7689 4637 Star
+7689 4602 Star
+7689 4567 Star
+7689 4532 Star
+7689 4497 Star
+7689 4462 Star
+7689 4428 Star
+7689 4393 Star
+7689 4358 Star
+7689 4323 Star
+7689 4288 Star
+7689 4253 Star
+7689 4218 Star
+7689 4183 Star
+7689 4148 Star
+7689 4113 Star
+7689 4078 Star
+7689 4043 Star
+7689 4008 Star
+7689 3973 Star
+7689 3938 Star
+7689 3903 Star
+7689 3868 Star
+7689 3833 Star
+7689 3798 Star
+7689 3763 Star
+7689 3728 Star
+7689 3693 Star
+7689 3658 Star
+7689 3623 Star
+7689 3588 Star
+7689 3553 Star
+7689 3518 Star
+7689 3483 Star
+7689 3448 Star
+7689 3413 Star
+7689 3378 Star
+7689 3343 Star
+7689 3308 Star
+7689 3273 Star
+7689 3238 Star
+7689 3203 Star
+7689 3168 Star
+7689 3133 Star
+7689 3098 Star
+7689 3063 Star
+7733 5477 Star
+7733 5442 Star
+7733 5407 Star
+7733 5372 Star
+7733 5337 Star
+7733 5302 Star
+7733 5267 Star
+7733 5232 Star
+7733 5197 Star
+7733 5162 Star
+7733 5127 Star
+7733 5092 Star
+7733 5057 Star
+7733 5022 Star
+7733 4987 Star
+7733 4952 Star
+7733 4917 Star
+7733 4882 Star
+7733 4847 Star
+7733 4812 Star
+7733 4777 Star
+7733 4742 Star
+7733 4707 Star
+7733 4672 Star
+7733 4637 Star
+7733 4602 Star
+7733 4567 Star
+7733 4532 Star
+7733 4497 Star
+7733 4462 Star
+7733 4428 Star
+7733 4393 Star
+7733 4358 Star
+7733 4323 Star
+7733 4288 Star
+7733 4253 Star
+7733 4218 Star
+7733 4183 Star
+7733 4148 Star
+7733 4113 Star
+7733 4078 Star
+7733 4043 Star
+7733 4008 Star
+7733 3973 Star
+7733 3938 Star
+7733 3903 Star
+7733 3868 Star
+7733 3833 Star
+7733 3798 Star
+7733 3763 Star
+7733 3728 Star
+7733 3693 Star
+7733 3658 Star
+7733 3623 Star
+7733 3588 Star
+7733 3553 Star
+7733 3518 Star
+7733 3483 Star
+7733 3448 Star
+7733 3413 Star
+7733 3378 Star
+7733 3343 Star
+7733 3308 Star
+7733 3273 Star
+7733 3238 Star
+7733 3203 Star
+7733 3168 Star
+7733 3133 Star
+7733 3098 Star
+7733 3063 Star
+7733 3028 Star
+7777 5477 Star
+7777 5442 Star
+7777 5407 Star
+7777 5372 Star
+7777 5337 Star
+7777 5302 Star
+7777 5267 Star
+7777 5232 Star
+7777 5197 Star
+7777 5162 Star
+7777 5127 Star
+7777 5092 Star
+7777 5057 Star
+7777 5022 Star
+7777 4987 Star
+7777 4952 Star
+7777 4917 Star
+7777 4882 Star
+7777 4847 Star
+7777 4812 Star
+7777 4777 Star
+7777 4742 Star
+7777 4707 Star
+7777 4672 Star
+7777 4637 Star
+7777 4602 Star
+7777 4567 Star
+7777 4532 Star
+7777 4497 Star
+7777 4462 Star
+7777 4428 Star
+7777 4393 Star
+7777 4358 Star
+7777 4323 Star
+7777 4288 Star
+7777 4253 Star
+7777 4218 Star
+7777 4183 Star
+7777 4148 Star
+7777 4113 Star
+7777 4078 Star
+7777 4043 Star
+7777 4008 Star
+7777 3973 Star
+7777 3938 Star
+7777 3903 Star
+7777 3868 Star
+7777 3833 Star
+7777 3798 Star
+7777 3763 Star
+7777 3728 Star
+7777 3693 Star
+7777 3658 Star
+7777 3623 Star
+7777 3588 Star
+7777 3553 Star
+7777 3518 Star
+7777 3483 Star
+7777 3448 Star
+7777 3413 Star
+7777 3378 Star
+7777 3343 Star
+7777 3308 Star
+7777 3273 Star
+7777 3238 Star
+7777 3203 Star
+7777 3168 Star
+7777 3133 Star
+7777 3098 Star
+7777 3063 Star
+7777 3028 Star
+7777 2993 Star
+7822 5442 Star
+7822 5407 Star
+7822 5372 Star
+7822 5337 Star
+7822 5302 Star
+7822 5267 Star
+7822 5232 Star
+7822 5197 Star
+7822 5162 Star
+7822 5127 Star
+7822 5092 Star
+7822 5057 Star
+7822 5022 Star
+7822 4987 Star
+7822 4952 Star
+7822 4917 Star
+7822 4882 Star
+7822 4847 Star
+7822 4812 Star
+7822 4777 Star
+7822 4742 Star
+7822 4707 Star
+7822 4672 Star
+7822 4637 Star
+7822 4602 Star
+7822 4567 Star
+7822 4532 Star
+7822 4497 Star
+7822 4462 Star
+7822 4428 Star
+7822 4393 Star
+7822 4358 Star
+7822 4323 Star
+7822 4288 Star
+7822 4253 Star
+7822 4218 Star
+7822 4183 Star
+7822 4148 Star
+7822 4113 Star
+7822 4078 Star
+7822 4043 Star
+7822 4008 Star
+7822 3973 Star
+7822 3938 Star
+7822 3903 Star
+7822 3868 Star
+7822 3833 Star
+7822 3798 Star
+7822 3763 Star
+7822 3728 Star
+7822 3693 Star
+7822 3658 Star
+7822 3623 Star
+7822 3588 Star
+7822 3553 Star
+7822 3518 Star
+7822 3483 Star
+7822 3448 Star
+7822 3413 Star
+7822 3378 Star
+7822 3343 Star
+7822 3308 Star
+7822 3273 Star
+7822 3238 Star
+7822 3203 Star
+7822 3168 Star
+7822 3133 Star
+7822 3098 Star
+7822 3063 Star
+7822 3028 Star
+7822 2993 Star
+7822 2958 Star
+7866 5442 Star
+7866 5407 Star
+7866 5372 Star
+7866 5337 Star
+7866 5302 Star
+7866 5267 Star
+7866 5232 Star
+7866 5197 Star
+7866 5162 Star
+7866 5127 Star
+7866 5092 Star
+7866 5057 Star
+7866 5022 Star
+7866 4987 Star
+7866 4952 Star
+7866 4917 Star
+7866 4882 Star
+7866 4847 Star
+7866 4812 Star
+7866 4777 Star
+7866 4742 Star
+7866 4707 Star
+7866 4672 Star
+7866 4637 Star
+7866 4602 Star
+7866 4567 Star
+7866 4532 Star
+7866 4497 Star
+7866 4462 Star
+7866 4428 Star
+7866 4393 Star
+7866 4358 Star
+7866 4323 Star
+7866 4288 Star
+7866 4253 Star
+7866 4218 Star
+7866 4183 Star
+7866 4148 Star
+7866 4113 Star
+7866 4078 Star
+7866 4043 Star
+7866 4008 Star
+7866 3973 Star
+7866 3938 Star
+7866 3903 Star
+7866 3868 Star
+7866 3833 Star
+7866 3798 Star
+7866 3763 Star
+7866 3728 Star
+7866 3693 Star
+7866 3658 Star
+7866 3623 Star
+7866 3588 Star
+7866 3553 Star
+7866 3518 Star
+7866 3483 Star
+7866 3448 Star
+7866 3413 Star
+7866 3378 Star
+7866 3343 Star
+7866 3308 Star
+7866 3273 Star
+7866 3238 Star
+7866 3203 Star
+7866 3168 Star
+7866 3133 Star
+7866 3098 Star
+7866 3063 Star
+7866 3028 Star
+7866 2993 Star
+7866 2958 Star
+7866 2923 Star
+7911 5407 Star
+7911 5372 Star
+7911 5337 Star
+7911 5302 Star
+7911 5267 Star
+7911 5232 Star
+7911 5197 Star
+7911 5162 Star
+7911 5127 Star
+7911 5092 Star
+7911 5057 Star
+7911 5022 Star
+7911 4987 Star
+7911 4952 Star
+7911 4917 Star
+7911 4882 Star
+7911 4847 Star
+7911 4812 Star
+7911 4777 Star
+7911 4742 Star
+7911 4707 Star
+7911 4672 Star
+7911 4637 Star
+7911 4602 Star
+7911 4567 Star
+7911 4532 Star
+7911 4497 Star
+7911 4462 Star
+7911 4428 Star
+7911 4393 Star
+7911 4358 Star
+7911 4323 Star
+7911 4288 Star
+7911 4253 Star
+7911 4218 Star
+7911 4183 Star
+7911 4148 Star
+7911 4113 Star
+7911 4078 Star
+7911 4043 Star
+7911 4008 Star
+7911 3973 Star
+7911 3938 Star
+7911 3903 Star
+7911 3868 Star
+7911 3833 Star
+7911 3798 Star
+7911 3763 Star
+7911 3728 Star
+7911 3693 Star
+7911 3658 Star
+7911 3623 Star
+7911 3588 Star
+7911 3553 Star
+7911 3518 Star
+7911 3483 Star
+7911 3448 Star
+7911 3413 Star
+7911 3378 Star
+7911 3343 Star
+7911 3308 Star
+7911 3273 Star
+7911 3238 Star
+7911 3203 Star
+7911 3168 Star
+7911 3133 Star
+7911 3098 Star
+7911 3063 Star
+7911 3028 Star
+7911 2993 Star
+7911 2958 Star
+7911 2923 Star
+7911 2888 Star
+7955 5407 Star
+7955 5372 Star
+7955 5337 Star
+7955 5302 Star
+7955 5267 Star
+7955 5232 Star
+7955 5197 Star
+7955 5162 Star
+7955 5127 Star
+7955 5092 Star
+7955 5057 Star
+7955 5022 Star
+7955 4987 Star
+7955 4952 Star
+7955 4917 Star
+7955 4882 Star
+7955 4847 Star
+7955 4812 Star
+7955 4777 Star
+7955 4742 Star
+7955 4707 Star
+7955 4672 Star
+7955 4637 Star
+7955 4602 Star
+7955 4567 Star
+7955 4532 Star
+7955 4497 Star
+7955 4462 Star
+7955 4428 Star
+7955 4393 Star
+7955 4358 Star
+7955 4323 Star
+7955 4288 Star
+7955 4253 Star
+7955 4218 Star
+7955 4183 Star
+7955 4148 Star
+7955 4113 Star
+7955 4078 Star
+7955 4043 Star
+7955 4008 Star
+7955 3973 Star
+7955 3938 Star
+7955 3903 Star
+7955 3868 Star
+7955 3833 Star
+7955 3798 Star
+7955 3763 Star
+7955 3728 Star
+7955 3693 Star
+7955 3658 Star
+7955 3623 Star
+7955 3588 Star
+7955 3553 Star
+7955 3518 Star
+7955 3483 Star
+7955 3448 Star
+7955 3413 Star
+7955 3378 Star
+7955 3343 Star
+7955 3308 Star
+7955 3273 Star
+7955 3238 Star
+7955 3203 Star
+7955 3168 Star
+7955 3133 Star
+7955 3098 Star
+7955 3063 Star
+7955 3028 Star
+7955 2993 Star
+7955 2958 Star
+7955 2923 Star
+7955 2888 Star
+7955 2853 Star
+7999 5372 Star
+7999 5337 Star
+7999 5302 Star
+7999 5267 Star
+7999 5232 Star
+7999 5197 Star
+7999 5162 Star
+7999 5127 Star
+7999 5092 Star
+7999 5057 Star
+7999 5022 Star
+7999 4987 Star
+7999 4952 Star
+7999 4917 Star
+7999 4882 Star
+7999 4847 Star
+7999 4812 Star
+7999 4777 Star
+7999 4742 Star
+7999 4707 Star
+7999 4672 Star
+7999 4637 Star
+7999 4602 Star
+7999 4567 Star
+7999 4532 Star
+7999 4497 Star
+7999 4462 Star
+7999 4428 Star
+7999 4393 Star
+7999 4358 Star
+7999 4323 Star
+7999 4288 Star
+7999 4253 Star
+7999 4218 Star
+7999 4183 Star
+7999 4148 Star
+7999 4113 Star
+7999 4078 Star
+7999 4043 Star
+7999 4008 Star
+7999 3973 Star
+7999 3938 Star
+7999 3903 Star
+7999 3868 Star
+7999 3833 Star
+7999 3798 Star
+7999 3763 Star
+7999 3728 Star
+7999 3693 Star
+7999 3658 Star
+7999 3623 Star
+7999 3588 Star
+7999 3553 Star
+7999 3518 Star
+7999 3483 Star
+7999 3448 Star
+7999 3413 Star
+7999 3378 Star
+7999 3343 Star
+7999 3308 Star
+7999 3273 Star
+7999 3238 Star
+7999 3203 Star
+7999 3168 Star
+7999 3133 Star
+7999 3098 Star
+7999 3063 Star
+7999 3028 Star
+7999 2993 Star
+7999 2958 Star
+7999 2923 Star
+7999 2888 Star
+7999 2853 Star
+7999 2818 Star
+8044 5372 Star
+8044 5337 Star
+8044 5302 Star
+8044 5267 Star
+8044 5232 Star
+8044 5197 Star
+8044 5162 Star
+8044 5127 Star
+8044 5092 Star
+8044 5057 Star
+8044 5022 Star
+8044 4987 Star
+8044 4952 Star
+8044 4917 Star
+8044 4882 Star
+8044 4847 Star
+8044 4812 Star
+8044 4777 Star
+8044 4742 Star
+8044 4707 Star
+8044 4672 Star
+8044 4637 Star
+8044 4602 Star
+8044 4567 Star
+8044 4532 Star
+8044 4497 Star
+8044 4462 Star
+8044 4428 Star
+8044 4393 Star
+8044 4358 Star
+8044 4323 Star
+8044 4288 Star
+8044 4253 Star
+8044 4218 Star
+8044 4183 Star
+8044 4148 Star
+8044 4113 Star
+8044 4078 Star
+8044 4043 Star
+8044 4008 Star
+8044 3973 Star
+8044 3938 Star
+8044 3903 Star
+8044 3868 Star
+8044 3833 Star
+8044 3798 Star
+8044 3763 Star
+8044 3728 Star
+8044 3693 Star
+8044 3658 Star
+8044 3623 Star
+8044 3588 Star
+8044 3553 Star
+8044 3518 Star
+8044 3483 Star
+8044 3448 Star
+8044 3413 Star
+8044 3378 Star
+8044 3343 Star
+8044 3308 Star
+8044 3273 Star
+8044 3238 Star
+8044 3203 Star
+8044 3168 Star
+8044 3133 Star
+8044 3098 Star
+8044 3063 Star
+8044 3028 Star
+8044 2993 Star
+8044 2958 Star
+8044 2923 Star
+8044 2888 Star
+8044 2853 Star
+8044 2818 Star
+8044 2783 Star
+8088 5337 Star
+8088 5302 Star
+8088 5267 Star
+8088 5232 Star
+8088 5197 Star
+8088 5162 Star
+8088 5127 Star
+8088 5092 Star
+8088 5057 Star
+8088 5022 Star
+8088 4987 Star
+8088 4952 Star
+8088 4917 Star
+8088 4882 Star
+8088 4847 Star
+8088 4812 Star
+8088 4777 Star
+8088 4742 Star
+8088 4707 Star
+8088 4672 Star
+8088 4637 Star
+8088 4602 Star
+8088 4567 Star
+8088 4532 Star
+8088 4497 Star
+8088 4462 Star
+8088 4428 Star
+8088 4393 Star
+8088 4358 Star
+8088 4323 Star
+8088 4288 Star
+8088 4253 Star
+8088 4218 Star
+8088 4183 Star
+8088 4148 Star
+8088 4113 Star
+8088 4078 Star
+8088 4043 Star
+8088 4008 Star
+8088 3973 Star
+8088 3938 Star
+8088 3903 Star
+8088 3868 Star
+8088 3833 Star
+8088 3798 Star
+8088 3763 Star
+8088 3728 Star
+8088 3693 Star
+8088 3658 Star
+8088 3623 Star
+8088 3588 Star
+8088 3553 Star
+8088 3518 Star
+8088 3483 Star
+8088 3448 Star
+8088 3413 Star
+8088 3378 Star
+8088 3343 Star
+8088 3308 Star
+8088 3273 Star
+8088 3238 Star
+8088 3203 Star
+8088 3168 Star
+8088 3133 Star
+8088 3098 Star
+8088 3063 Star
+8088 3028 Star
+8088 2993 Star
+8088 2958 Star
+8088 2923 Star
+8088 2888 Star
+8088 2853 Star
+8088 2818 Star
+8088 2783 Star
+8088 2748 Star
+8132 5337 Star
+8132 5302 Star
+8132 5267 Star
+8132 5232 Star
+8132 5197 Star
+8132 5162 Star
+8132 5127 Star
+8132 5092 Star
+8132 5057 Star
+8132 5022 Star
+8132 4987 Star
+8132 4952 Star
+8132 4917 Star
+8132 4882 Star
+8132 4847 Star
+8132 4812 Star
+8132 4777 Star
+8132 4742 Star
+8132 4707 Star
+8132 4672 Star
+8132 4637 Star
+8132 4602 Star
+8132 4567 Star
+8132 4532 Star
+8132 4497 Star
+8132 4462 Star
+8132 4428 Star
+8132 4393 Star
+8132 4358 Star
+8132 4323 Star
+8132 4288 Star
+8132 4253 Star
+8132 4218 Star
+8132 4183 Star
+8132 4148 Star
+8132 4113 Star
+8132 4078 Star
+8132 4043 Star
+8132 4008 Star
+8132 3973 Star
+8132 3938 Star
+8132 3903 Star
+8132 3868 Star
+8132 3833 Star
+8132 3798 Star
+8132 3763 Star
+8132 3728 Star
+8132 3693 Star
+8132 3658 Star
+8132 3623 Star
+8132 3588 Star
+8132 3553 Star
+8132 3518 Star
+8132 3483 Star
+8132 3448 Star
+8132 3413 Star
+8132 3378 Star
+8132 3343 Star
+8132 3308 Star
+8132 3273 Star
+8132 3238 Star
+8132 3203 Star
+8132 3168 Star
+8132 3133 Star
+8132 3098 Star
+8132 3063 Star
+8132 3028 Star
+8132 2993 Star
+8132 2958 Star
+8132 2923 Star
+8132 2888 Star
+8132 2853 Star
+8132 2818 Star
+8132 2783 Star
+8132 2748 Star
+8132 2713 Star
+8177 5302 Star
+8177 5267 Star
+8177 5232 Star
+8177 5197 Star
+8177 5162 Star
+8177 5127 Star
+8177 5092 Star
+8177 5057 Star
+8177 5022 Star
+8177 4987 Star
+8177 4952 Star
+8177 4917 Star
+8177 4882 Star
+8177 4847 Star
+8177 4812 Star
+8177 4777 Star
+8177 4742 Star
+8177 4707 Star
+8177 4672 Star
+8177 4637 Star
+8177 4602 Star
+8177 4567 Star
+8177 4532 Star
+8177 4497 Star
+8177 4462 Star
+8177 4428 Star
+8177 4393 Star
+8177 4358 Star
+8177 4323 Star
+8177 4288 Star
+8177 4253 Star
+8177 4218 Star
+8177 4183 Star
+8177 4148 Star
+8177 4113 Star
+8177 4078 Star
+8177 4043 Star
+8177 4008 Star
+8177 3973 Star
+8177 3938 Star
+8177 3903 Star
+8177 3868 Star
+8177 3833 Star
+8177 3798 Star
+8177 3763 Star
+8177 3728 Star
+8177 3693 Star
+8177 3658 Star
+8177 3623 Star
+8177 3588 Star
+8177 3553 Star
+8177 3518 Star
+8177 3483 Star
+8177 3448 Star
+8177 3413 Star
+8177 3378 Star
+8177 3343 Star
+8177 3308 Star
+8177 3273 Star
+8177 3238 Star
+8177 3203 Star
+8177 3168 Star
+8177 3133 Star
+8177 3098 Star
+8177 3063 Star
+8177 3028 Star
+8177 2993 Star
+8177 2958 Star
+8177 2923 Star
+8177 2888 Star
+8177 2853 Star
+8177 2818 Star
+8177 2783 Star
+8177 2748 Star
+8177 2713 Star
+8177 2678 Star
+8221 5302 Star
+8221 5267 Star
+8221 5232 Star
+8221 5197 Star
+8221 5162 Star
+8221 5127 Star
+8221 5092 Star
+8221 5057 Star
+8221 5022 Star
+8221 4987 Star
+8221 4952 Star
+8221 4917 Star
+8221 4882 Star
+8221 4847 Star
+8221 4812 Star
+8221 4777 Star
+8221 4742 Star
+8221 4707 Star
+8221 4672 Star
+8221 4637 Star
+8221 4602 Star
+8221 4567 Star
+8221 4532 Star
+8221 4497 Star
+8221 4462 Star
+8221 4428 Star
+8221 4393 Star
+8221 4358 Star
+8221 4323 Star
+8221 4288 Star
+8221 4253 Star
+8221 4218 Star
+8221 4183 Star
+8221 4148 Star
+8221 4113 Star
+8221 4078 Star
+8221 4043 Star
+8221 4008 Star
+8221 3973 Star
+8221 3938 Star
+8221 3903 Star
+8221 3868 Star
+8221 3833 Star
+8221 3798 Star
+8221 3763 Star
+8221 3728 Star
+8221 3693 Star
+8221 3658 Star
+8221 3623 Star
+8221 3588 Star
+8221 3553 Star
+8221 3518 Star
+8221 3483 Star
+8221 3448 Star
+8221 3413 Star
+8221 3378 Star
+8221 3343 Star
+8221 3308 Star
+8221 3273 Star
+8221 3238 Star
+8221 3203 Star
+8221 3168 Star
+8221 3133 Star
+8221 3098 Star
+8221 3063 Star
+8221 3028 Star
+8221 2993 Star
+8221 2958 Star
+8221 2923 Star
+8221 2888 Star
+8221 2853 Star
+8221 2818 Star
+8221 2783 Star
+8221 2748 Star
+8221 2713 Star
+8221 2678 Star
+8221 2643 Star
+8266 5267 Star
+8266 5232 Star
+8266 5197 Star
+8266 5162 Star
+8266 5127 Star
+8266 5092 Star
+8266 5057 Star
+8266 5022 Star
+8266 4987 Star
+8266 4952 Star
+8266 4917 Star
+8266 4882 Star
+8266 4847 Star
+8266 4812 Star
+8266 4777 Star
+8266 4742 Star
+8266 4707 Star
+8266 4672 Star
+8266 4637 Star
+8266 4602 Star
+8266 4567 Star
+8266 4532 Star
+8266 4497 Star
+8266 4462 Star
+8266 4428 Star
+8266 4393 Star
+8266 4358 Star
+8266 4323 Star
+8266 4288 Star
+8266 4253 Star
+8266 4218 Star
+8266 4183 Star
+8266 4148 Star
+8266 4113 Star
+8266 4078 Star
+8266 4043 Star
+8266 4008 Star
+8266 3973 Star
+8266 3938 Star
+8266 3903 Star
+8266 3868 Star
+8266 3833 Star
+8266 3798 Star
+8266 3763 Star
+8266 3728 Star
+8266 3693 Star
+8266 3658 Star
+8266 3623 Star
+8266 3588 Star
+8266 3553 Star
+8266 3518 Star
+8266 3483 Star
+8266 3448 Star
+8266 3413 Star
+8266 3378 Star
+8266 3343 Star
+8266 3308 Star
+8266 3273 Star
+8266 3238 Star
+8266 3203 Star
+8266 3168 Star
+8266 3133 Star
+8266 3098 Star
+8266 3063 Star
+8266 3028 Star
+8266 2993 Star
+8266 2958 Star
+8266 2923 Star
+8266 2888 Star
+8266 2853 Star
+8266 2818 Star
+8266 2783 Star
+8266 2748 Star
+8266 2713 Star
+8266 2678 Star
+8266 2643 Star
+8266 2608 Star
+8310 5267 Star
+8310 5232 Star
+8310 5197 Star
+8310 5162 Star
+8310 5127 Star
+8310 5092 Star
+8310 5057 Star
+8310 5022 Star
+8310 4987 Star
+8310 4952 Star
+8310 4917 Star
+8310 4882 Star
+8310 4847 Star
+8310 4812 Star
+8310 4777 Star
+8310 4742 Star
+8310 4707 Star
+8310 4672 Star
+8310 4637 Star
+8310 4602 Star
+8310 4567 Star
+8310 4532 Star
+8310 4497 Star
+8310 4462 Star
+8310 4428 Star
+8310 4393 Star
+8310 4358 Star
+8310 4323 Star
+8310 4288 Star
+8310 4253 Star
+8310 4218 Star
+8310 4183 Star
+8310 4148 Star
+8310 4113 Star
+8310 4078 Star
+8310 4043 Star
+8310 4008 Star
+8310 3973 Star
+8310 3938 Star
+8310 3903 Star
+8310 3868 Star
+8310 3833 Star
+8310 3798 Star
+8310 3763 Star
+8310 3728 Star
+8310 3693 Star
+8310 3658 Star
+8310 3623 Star
+8310 3588 Star
+8310 3553 Star
+8310 3518 Star
+8310 3483 Star
+8310 3448 Star
+8310 3413 Star
+8310 3378 Star
+8310 3343 Star
+8310 3308 Star
+8310 3273 Star
+8310 3238 Star
+8310 3203 Star
+8310 3168 Star
+8310 3133 Star
+8310 3098 Star
+8310 3063 Star
+8310 3028 Star
+8310 2993 Star
+8310 2958 Star
+8310 2923 Star
+8310 2888 Star
+8310 2853 Star
+8310 2818 Star
+8310 2783 Star
+8310 2748 Star
+8310 2713 Star
+8310 2678 Star
+8310 2643 Star
+8310 2608 Star
+8310 2573 Star
+8354 5232 Star
+8354 5197 Star
+8354 5162 Star
+8354 5127 Star
+8354 5092 Star
+8354 5057 Star
+8354 5022 Star
+8354 4987 Star
+8354 4952 Star
+8354 4917 Star
+8354 4882 Star
+8354 4847 Star
+8354 4812 Star
+8354 4777 Star
+8354 4742 Star
+8354 4707 Star
+8354 4672 Star
+8354 4637 Star
+8354 4602 Star
+8354 4567 Star
+8354 4532 Star
+8354 4497 Star
+8354 4462 Star
+8354 4428 Star
+8354 4393 Star
+8354 4358 Star
+8354 4323 Star
+8354 4288 Star
+8354 4253 Star
+8354 4218 Star
+8354 4183 Star
+8354 4148 Star
+8354 4113 Star
+8354 4078 Star
+8354 4043 Star
+8354 4008 Star
+8354 3973 Star
+8354 3938 Star
+8354 3903 Star
+8354 3868 Star
+8354 3833 Star
+8354 3798 Star
+8354 3763 Star
+8354 3728 Star
+8354 3693 Star
+8354 3658 Star
+8354 3623 Star
+8354 3588 Star
+8354 3553 Star
+8354 3518 Star
+8354 3483 Star
+8354 3448 Star
+8354 3413 Star
+8354 3378 Star
+8354 3343 Star
+8354 3308 Star
+8354 3273 Star
+8354 3238 Star
+8354 3203 Star
+8354 3168 Star
+8354 3133 Star
+8354 3098 Star
+8354 3063 Star
+8354 3028 Star
+8354 2993 Star
+8354 2958 Star
+8354 2923 Star
+8354 2888 Star
+8354 2853 Star
+8354 2818 Star
+8354 2783 Star
+8354 2748 Star
+8354 2713 Star
+8354 2678 Star
+8354 2643 Star
+8354 2608 Star
+8354 2573 Star
+8354 2538 Star
+8399 5232 Star
+8399 5197 Star
+8399 5162 Star
+8399 5127 Star
+8399 5092 Star
+8399 5057 Star
+8399 5022 Star
+8399 4987 Star
+8399 4952 Star
+8399 4917 Star
+8399 4882 Star
+8399 4847 Star
+8399 4812 Star
+8399 4777 Star
+8399 4742 Star
+8399 4707 Star
+8399 4672 Star
+8399 4637 Star
+8399 4602 Star
+8399 4567 Star
+8399 4532 Star
+8399 4497 Star
+8399 4462 Star
+8399 4428 Star
+8399 4393 Star
+8399 4358 Star
+8399 4323 Star
+8399 4288 Star
+8399 4253 Star
+8399 4218 Star
+8399 4183 Star
+8399 4148 Star
+8399 4113 Star
+8399 4078 Star
+8399 4043 Star
+8399 4008 Star
+8399 3973 Star
+8399 3938 Star
+8399 3903 Star
+8399 3868 Star
+8399 3833 Star
+8399 3798 Star
+8399 3763 Star
+8399 3728 Star
+8399 3693 Star
+8399 3658 Star
+8399 3623 Star
+8399 3588 Star
+8399 3553 Star
+8399 3518 Star
+8399 3483 Star
+8399 3448 Star
+8399 3413 Star
+8399 3378 Star
+8399 3343 Star
+8399 3308 Star
+8399 3273 Star
+8399 3238 Star
+8399 3203 Star
+8399 3168 Star
+8399 3133 Star
+8399 3098 Star
+8399 3063 Star
+8399 3028 Star
+8399 2993 Star
+8399 2958 Star
+8399 2923 Star
+8399 2888 Star
+8399 2853 Star
+8399 2818 Star
+8399 2783 Star
+8399 2748 Star
+8399 2713 Star
+8399 2678 Star
+8399 2643 Star
+8399 2608 Star
+8399 2573 Star
+8399 2538 Star
+8399 2503 Star
+8443 5197 Star
+8443 5162 Star
+8443 5127 Star
+8443 5092 Star
+8443 5057 Star
+8443 5022 Star
+8443 4987 Star
+8443 4952 Star
+8443 4917 Star
+8443 4882 Star
+8443 4847 Star
+8443 4812 Star
+8443 4777 Star
+8443 4742 Star
+8443 4707 Star
+8443 4672 Star
+8443 4637 Star
+8443 4602 Star
+8443 4567 Star
+8443 4532 Star
+8443 4497 Star
+8443 4462 Star
+8443 4428 Star
+8443 4393 Star
+8443 4358 Star
+8443 4323 Star
+8443 4288 Star
+8443 4253 Star
+8443 4218 Star
+8443 4183 Star
+8443 4148 Star
+8443 4113 Star
+8443 4078 Star
+8443 4043 Star
+8443 4008 Star
+8443 3973 Star
+8443 3938 Star
+8443 3903 Star
+8443 3868 Star
+8443 3833 Star
+8443 3798 Star
+8443 3763 Star
+8443 3728 Star
+8443 3693 Star
+8443 3658 Star
+8443 3623 Star
+8443 3588 Star
+8443 3553 Star
+8443 3518 Star
+8443 3483 Star
+8443 3448 Star
+8443 3413 Star
+8443 3378 Star
+8443 3343 Star
+8443 3308 Star
+8443 3273 Star
+8443 3238 Star
+8443 3203 Star
+8443 3168 Star
+8443 3133 Star
+8443 3098 Star
+8443 3063 Star
+8443 3028 Star
+8443 2993 Star
+8443 2958 Star
+8443 2923 Star
+8443 2888 Star
+8443 2853 Star
+8443 2818 Star
+8443 2783 Star
+8443 2748 Star
+8443 2713 Star
+8443 2678 Star
+8443 2643 Star
+8443 2608 Star
+8443 2573 Star
+8443 2538 Star
+8443 2503 Star
+8443 2468 Star
+8488 5197 Star
+8488 5162 Star
+8488 5127 Star
+8488 5092 Star
+8488 5057 Star
+8488 5022 Star
+8488 4987 Star
+8488 4952 Star
+8488 4917 Star
+8488 4882 Star
+8488 4847 Star
+8488 4812 Star
+8488 4777 Star
+8488 4742 Star
+8488 4707 Star
+8488 4672 Star
+8488 4637 Star
+8488 4602 Star
+8488 4567 Star
+8488 4532 Star
+8488 4497 Star
+8488 4462 Star
+8488 4428 Star
+8488 4393 Star
+8488 4358 Star
+8488 4323 Star
+8488 4288 Star
+8488 4253 Star
+8488 4218 Star
+8488 4183 Star
+8488 4148 Star
+8488 4113 Star
+8488 4078 Star
+8488 4043 Star
+8488 4008 Star
+8488 3973 Star
+8488 3938 Star
+8488 3903 Star
+8488 3868 Star
+8488 3833 Star
+8488 3798 Star
+8488 3763 Star
+8488 3728 Star
+8488 3693 Star
+8488 3658 Star
+8488 3623 Star
+8488 3588 Star
+8488 3553 Star
+8488 3518 Star
+8488 3483 Star
+8488 3448 Star
+8488 3413 Star
+8488 3378 Star
+8488 3343 Star
+8488 3308 Star
+8488 3273 Star
+8488 3238 Star
+8488 3203 Star
+8488 3168 Star
+8488 3133 Star
+8488 3098 Star
+8488 3063 Star
+8488 3028 Star
+8488 2993 Star
+8488 2958 Star
+8488 2923 Star
+8488 2888 Star
+8488 2853 Star
+8488 2818 Star
+8488 2783 Star
+8488 2748 Star
+8488 2713 Star
+8488 2678 Star
+8488 2643 Star
+8488 2608 Star
+8488 2573 Star
+8488 2538 Star
+8488 2503 Star
+8488 2468 Star
+8488 2433 Star
+8532 5162 Star
+8532 5127 Star
+8532 5092 Star
+8532 5057 Star
+8532 5022 Star
+8532 4987 Star
+8532 4952 Star
+8532 4917 Star
+8532 4882 Star
+8532 4847 Star
+8532 4812 Star
+8532 4777 Star
+8532 4742 Star
+8532 4707 Star
+8532 4672 Star
+8532 4637 Star
+8532 4602 Star
+8532 4567 Star
+8532 4532 Star
+8532 4497 Star
+8532 4462 Star
+8532 4428 Star
+8532 4393 Star
+8532 4358 Star
+8532 4323 Star
+8532 4288 Star
+8532 4253 Star
+8532 4218 Star
+8532 4183 Star
+8532 4148 Star
+8532 4113 Star
+8532 4078 Star
+8532 4043 Star
+8532 4008 Star
+8532 3973 Star
+8532 3938 Star
+8532 3903 Star
+8532 3868 Star
+8532 3833 Star
+8532 3798 Star
+8532 3763 Star
+8532 3728 Star
+8532 3693 Star
+8532 3658 Star
+8532 3623 Star
+8532 3588 Star
+8532 3553 Star
+8532 3518 Star
+8532 3483 Star
+8532 3448 Star
+8532 3413 Star
+8532 3378 Star
+8532 3343 Star
+8532 3308 Star
+8532 3273 Star
+8532 3238 Star
+8532 3203 Star
+8532 3168 Star
+8532 3133 Star
+8532 3098 Star
+8532 3063 Star
+8532 3028 Star
+8532 2993 Star
+8532 2958 Star
+8532 2923 Star
+8532 2888 Star
+8532 2853 Star
+8532 2818 Star
+8532 2783 Star
+8532 2748 Star
+8532 2713 Star
+8532 2678 Star
+8532 2643 Star
+8532 2608 Star
+8532 2573 Star
+8532 2538 Star
+8532 2503 Star
+8532 2468 Star
+8532 2433 Star
+8532 2398 Star
+8576 5162 Star
+8576 5127 Star
+8576 5092 Star
+8576 5057 Star
+8576 5022 Star
+8576 4987 Star
+8576 4952 Star
+8576 4917 Star
+8576 4882 Star
+8576 4847 Star
+8576 4812 Star
+8576 4777 Star
+8576 4742 Star
+8576 4707 Star
+8576 4672 Star
+8576 4637 Star
+8576 4602 Star
+8576 4567 Star
+8576 4532 Star
+8576 4497 Star
+8576 4462 Star
+8576 4428 Star
+8576 4393 Star
+8576 4358 Star
+8576 4323 Star
+8576 4288 Star
+8576 4253 Star
+8576 4218 Star
+8576 4183 Star
+8576 4148 Star
+8576 4113 Star
+8576 4078 Star
+8576 4043 Star
+8576 4008 Star
+8576 3973 Star
+8576 3938 Star
+8576 3903 Star
+8576 3868 Star
+8576 3833 Star
+8576 3798 Star
+8576 3763 Star
+8576 3728 Star
+8576 3693 Star
+8576 3658 Star
+8576 3623 Star
+8576 3588 Star
+8576 3553 Star
+8576 3518 Star
+8576 3483 Star
+8576 3448 Star
+8576 3413 Star
+8576 3378 Star
+8576 3343 Star
+8576 3308 Star
+8576 3273 Star
+8576 3238 Star
+8576 3203 Star
+8576 3168 Star
+8576 3133 Star
+8576 3098 Star
+8576 3063 Star
+8576 3028 Star
+8576 2993 Star
+8576 2958 Star
+8576 2923 Star
+8576 2888 Star
+8576 2853 Star
+8576 2818 Star
+8576 2783 Star
+8576 2748 Star
+8576 2713 Star
+8576 2678 Star
+8576 2643 Star
+8576 2608 Star
+8576 2573 Star
+8576 2538 Star
+8576 2503 Star
+8576 2468 Star
+8576 2433 Star
+8576 2398 Star
+8576 2363 Star
+8621 5127 Star
+8621 5092 Star
+8621 5057 Star
+8621 5022 Star
+8621 4987 Star
+8621 4952 Star
+8621 4917 Star
+8621 4882 Star
+8621 4847 Star
+8621 4812 Star
+8621 4777 Star
+8621 4742 Star
+8621 4707 Star
+8621 4672 Star
+8621 4637 Star
+8621 4602 Star
+8621 4567 Star
+8621 4532 Star
+8621 4497 Star
+8621 4462 Star
+8621 4428 Star
+8621 4393 Star
+8621 4358 Star
+8621 4323 Star
+8621 4288 Star
+8621 4253 Star
+8621 4218 Star
+8621 4183 Star
+8621 4148 Star
+8621 4113 Star
+8621 4078 Star
+8621 4043 Star
+8621 4008 Star
+8621 3973 Star
+8621 3938 Star
+8621 3903 Star
+8621 3868 Star
+8621 3833 Star
+8621 3798 Star
+8621 3763 Star
+8621 3728 Star
+8621 3693 Star
+8621 3658 Star
+8621 3623 Star
+8621 3588 Star
+8621 3553 Star
+8621 3518 Star
+8621 3483 Star
+8621 3448 Star
+8621 3413 Star
+8621 3378 Star
+8621 3343 Star
+8621 3308 Star
+8621 3273 Star
+8621 3238 Star
+8621 3203 Star
+8621 3168 Star
+8621 3133 Star
+8621 3098 Star
+8621 3063 Star
+8621 3028 Star
+8621 2993 Star
+8621 2958 Star
+8621 2923 Star
+8621 2888 Star
+8621 2853 Star
+8621 2818 Star
+8621 2783 Star
+8621 2748 Star
+8621 2713 Star
+8621 2678 Star
+8621 2643 Star
+8621 2608 Star
+8621 2573 Star
+8621 2538 Star
+8621 2503 Star
+8621 2468 Star
+8621 2433 Star
+8621 2398 Star
+8621 2363 Star
+8621 2328 Star
+8665 5127 Star
+8665 5092 Star
+8665 5057 Star
+8665 5022 Star
+8665 4987 Star
+8665 4952 Star
+8665 4917 Star
+8665 4882 Star
+8665 4847 Star
+8665 4812 Star
+8665 4777 Star
+8665 4742 Star
+8665 4707 Star
+8665 4672 Star
+8665 4637 Star
+8665 4602 Star
+8665 4567 Star
+8665 4532 Star
+8665 4497 Star
+8665 4462 Star
+8665 4428 Star
+8665 4393 Star
+8665 4358 Star
+8665 4323 Star
+8665 4288 Star
+8665 4253 Star
+8665 4218 Star
+8665 4183 Star
+8665 4148 Star
+8665 4113 Star
+8665 4078 Star
+8665 4043 Star
+8665 4008 Star
+8665 3973 Star
+8665 3938 Star
+8665 3903 Star
+8665 3868 Star
+8665 3833 Star
+8665 3798 Star
+8665 3763 Star
+8665 3728 Star
+8665 3693 Star
+8665 3658 Star
+8665 3623 Star
+8665 3588 Star
+8665 3553 Star
+8665 3518 Star
+8665 3483 Star
+8665 3448 Star
+8665 3413 Star
+8665 3378 Star
+8665 3343 Star
+8665 3308 Star
+8665 3273 Star
+8665 3238 Star
+8665 3203 Star
+8665 3168 Star
+8665 3133 Star
+8665 3098 Star
+8665 3063 Star
+8665 3028 Star
+8665 2993 Star
+8665 2958 Star
+8665 2923 Star
+8665 2888 Star
+8665 2853 Star
+8665 2818 Star
+8665 2783 Star
+8665 2748 Star
+8665 2713 Star
+8665 2678 Star
+8665 2643 Star
+8665 2608 Star
+8665 2573 Star
+8665 2538 Star
+8665 2503 Star
+8665 2468 Star
+8665 2433 Star
+8665 2398 Star
+8665 2363 Star
+8665 2328 Star
+8665 2293 Star
+8709 5092 Star
+8709 5057 Star
+8709 5022 Star
+8709 4987 Star
+8709 4952 Star
+8709 4917 Star
+8709 4882 Star
+8709 4847 Star
+8709 4812 Star
+8709 4777 Star
+8709 4742 Star
+8709 4707 Star
+8709 4672 Star
+8709 4637 Star
+8709 4602 Star
+8709 4567 Star
+8709 4532 Star
+8709 4497 Star
+8709 4462 Star
+8709 4428 Star
+8709 4393 Star
+8709 4358 Star
+8709 4323 Star
+8709 4288 Star
+8709 4253 Star
+8709 4218 Star
+8709 4183 Star
+8709 4148 Star
+8709 4113 Star
+8709 4078 Star
+8709 4043 Star
+8709 4008 Star
+8709 3973 Star
+8709 3938 Star
+8709 3903 Star
+8709 3868 Star
+8709 3833 Star
+8709 3798 Star
+8709 3763 Star
+8709 3728 Star
+8709 3693 Star
+8709 3658 Star
+8709 3623 Star
+8709 3588 Star
+8709 3553 Star
+8709 3518 Star
+8709 3483 Star
+8709 3448 Star
+8709 3413 Star
+8709 3378 Star
+8709 3343 Star
+8709 3308 Star
+8709 3273 Star
+8709 3238 Star
+8709 3203 Star
+8709 3168 Star
+8709 3133 Star
+8709 3098 Star
+8709 3063 Star
+8709 3028 Star
+8709 2993 Star
+8709 2958 Star
+8709 2923 Star
+8709 2888 Star
+8709 2853 Star
+8709 2818 Star
+8709 2783 Star
+8709 2748 Star
+8709 2713 Star
+8709 2678 Star
+8709 2643 Star
+8709 2608 Star
+8709 2573 Star
+8709 2538 Star
+8709 2503 Star
+8709 2468 Star
+8709 2433 Star
+8709 2398 Star
+8709 2363 Star
+8709 2328 Star
+8709 2293 Star
+8709 2258 Star
+8754 5092 Star
+8754 5057 Star
+8754 5022 Star
+8754 4987 Star
+8754 4952 Star
+8754 4917 Star
+8754 4882 Star
+8754 4847 Star
+8754 4812 Star
+8754 4777 Star
+8754 4742 Star
+8754 4707 Star
+8754 4672 Star
+8754 4637 Star
+8754 4602 Star
+8754 4567 Star
+8754 4532 Star
+8754 4497 Star
+8754 4462 Star
+8754 4428 Star
+8754 4393 Star
+8754 4358 Star
+8754 4323 Star
+8754 4288 Star
+8754 4253 Star
+8754 4218 Star
+8754 4183 Star
+8754 4148 Star
+8754 4113 Star
+8754 4078 Star
+8754 4043 Star
+8754 4008 Star
+8754 3973 Star
+8754 3938 Star
+8754 3903 Star
+8754 3868 Star
+8754 3833 Star
+8754 3798 Star
+8754 3763 Star
+8754 3728 Star
+8754 3693 Star
+8754 3658 Star
+8754 3623 Star
+8754 3588 Star
+8754 3553 Star
+8754 3518 Star
+8754 3483 Star
+8754 3448 Star
+8754 3413 Star
+8754 3378 Star
+8754 3343 Star
+8754 3308 Star
+8754 3273 Star
+8754 3238 Star
+8754 3203 Star
+8754 3168 Star
+8754 3133 Star
+8754 3098 Star
+8754 3063 Star
+8754 3028 Star
+8754 2993 Star
+8754 2958 Star
+8754 2923 Star
+8754 2888 Star
+8754 2853 Star
+8754 2818 Star
+8754 2783 Star
+8754 2748 Star
+8754 2713 Star
+8754 2678 Star
+8754 2643 Star
+8754 2608 Star
+8754 2573 Star
+8754 2538 Star
+8754 2503 Star
+8754 2468 Star
+8754 2433 Star
+8754 2398 Star
+8754 2363 Star
+8754 2328 Star
+8754 2293 Star
+8754 2258 Star
+8754 2223 Star
+8798 5057 Star
+8798 5022 Star
+8798 4987 Star
+8798 4952 Star
+8798 4917 Star
+8798 4882 Star
+8798 4847 Star
+8798 4812 Star
+8798 4777 Star
+8798 4742 Star
+8798 4707 Star
+8798 4672 Star
+8798 4637 Star
+8798 4602 Star
+8798 4567 Star
+8798 4532 Star
+8798 4497 Star
+8798 4462 Star
+8798 4428 Star
+8798 4393 Star
+8798 4358 Star
+8798 4323 Star
+8798 4288 Star
+8798 4253 Star
+8798 4218 Star
+8798 4183 Star
+8798 4148 Star
+8798 4113 Star
+8798 4078 Star
+8798 4043 Star
+8798 4008 Star
+8798 3973 Star
+8798 3938 Star
+8798 3903 Star
+8798 3868 Star
+8798 3833 Star
+8798 3798 Star
+8798 3763 Star
+8798 3728 Star
+8798 3693 Star
+8798 3658 Star
+8798 3623 Star
+8798 3588 Star
+8798 3553 Star
+8798 3518 Star
+8798 3483 Star
+8798 3448 Star
+8798 3413 Star
+8798 3378 Star
+8798 3343 Star
+8798 3308 Star
+8798 3273 Star
+8798 3238 Star
+8798 3203 Star
+8798 3168 Star
+8798 3133 Star
+8798 3098 Star
+8798 3063 Star
+8798 3028 Star
+8798 2993 Star
+8798 2958 Star
+8798 2923 Star
+8798 2888 Star
+8798 2853 Star
+8798 2818 Star
+8798 2783 Star
+8798 2748 Star
+8798 2713 Star
+8798 2678 Star
+8798 2643 Star
+8798 2608 Star
+8798 2573 Star
+8798 2538 Star
+8798 2503 Star
+8798 2468 Star
+8798 2433 Star
+8798 2398 Star
+8798 2363 Star
+8798 2328 Star
+8798 2293 Star
+8798 2258 Star
+8798 2223 Star
+8798 2188 Star
+8843 5057 Star
+8843 5022 Star
+8843 4987 Star
+8843 4952 Star
+8843 4917 Star
+8843 4882 Star
+8843 4847 Star
+8843 4812 Star
+8843 4777 Star
+8843 4742 Star
+8843 4707 Star
+8843 4672 Star
+8843 4637 Star
+8843 4602 Star
+8843 4567 Star
+8843 4532 Star
+8843 4497 Star
+8843 4462 Star
+8843 4428 Star
+8843 4393 Star
+8843 4358 Star
+8843 4323 Star
+8843 4288 Star
+8843 4253 Star
+8843 4218 Star
+8843 4183 Star
+8843 4148 Star
+8843 4113 Star
+8843 4078 Star
+8843 4043 Star
+8843 4008 Star
+8843 3973 Star
+8843 3938 Star
+8843 3903 Star
+8843 3868 Star
+8843 3833 Star
+8843 3798 Star
+8843 3763 Star
+8843 3728 Star
+8843 3693 Star
+8843 3658 Star
+8843 3623 Star
+8843 3588 Star
+8843 3553 Star
+8843 3518 Star
+8843 3483 Star
+8843 3448 Star
+8843 3413 Star
+8843 3378 Star
+8843 3343 Star
+8843 3308 Star
+8843 3273 Star
+8843 3238 Star
+8843 3203 Star
+8843 3168 Star
+8843 3133 Star
+8843 3098 Star
+8843 3063 Star
+8843 3028 Star
+8843 2993 Star
+8843 2958 Star
+8843 2923 Star
+8843 2888 Star
+8843 2853 Star
+8843 2818 Star
+8843 2783 Star
+8843 2748 Star
+8843 2713 Star
+8843 2678 Star
+8843 2643 Star
+8843 2608 Star
+8843 2573 Star
+8843 2538 Star
+8843 2503 Star
+8843 2468 Star
+8843 2433 Star
+8843 2398 Star
+8843 2363 Star
+8843 2328 Star
+8843 2293 Star
+8843 2258 Star
+8843 2223 Star
+8843 2188 Star
+8843 2153 Star
+8887 5022 Star
+8887 4987 Star
+8887 4952 Star
+8887 4917 Star
+8887 4882 Star
+8887 4847 Star
+8887 4812 Star
+8887 4777 Star
+8887 4742 Star
+8887 4707 Star
+8887 4672 Star
+8887 4637 Star
+8887 4602 Star
+8887 4567 Star
+8887 4532 Star
+8887 4497 Star
+8887 4462 Star
+8887 4428 Star
+8887 4393 Star
+8887 4358 Star
+8887 4323 Star
+8887 4288 Star
+8887 4253 Star
+8887 4218 Star
+8887 4183 Star
+8887 4148 Star
+8887 4113 Star
+8887 4078 Star
+8887 4043 Star
+8887 4008 Star
+8887 3973 Star
+8887 3938 Star
+8887 3903 Star
+8887 3868 Star
+8887 3833 Star
+8887 3798 Star
+8887 3763 Star
+8887 3728 Star
+8887 3693 Star
+8887 3658 Star
+8887 3623 Star
+8887 3588 Star
+8887 3553 Star
+8887 3518 Star
+8887 3483 Star
+8887 3448 Star
+8887 3413 Star
+8887 3378 Star
+8887 3343 Star
+8887 3308 Star
+8887 3273 Star
+8887 3238 Star
+8887 3203 Star
+8887 3168 Star
+8887 3133 Star
+8887 3098 Star
+8887 3063 Star
+8887 3028 Star
+8887 2993 Star
+8887 2958 Star
+8887 2923 Star
+8887 2888 Star
+8887 2853 Star
+8887 2818 Star
+8887 2783 Star
+8887 2748 Star
+8887 2713 Star
+8887 2678 Star
+8887 2643 Star
+8887 2608 Star
+8887 2573 Star
+8887 2538 Star
+8887 2503 Star
+8887 2468 Star
+8887 2433 Star
+8887 2398 Star
+8887 2363 Star
+8887 2328 Star
+8887 2293 Star
+8887 2258 Star
+8887 2223 Star
+8887 2188 Star
+8887 2153 Star
+8887 2118 Star
+8931 5022 Star
+8931 4987 Star
+8931 4952 Star
+8931 4917 Star
+8931 4882 Star
+8931 4847 Star
+8931 4812 Star
+8931 4777 Star
+8931 4742 Star
+8931 4707 Star
+8931 4672 Star
+8931 4637 Star
+8931 4602 Star
+8931 4567 Star
+8931 4532 Star
+8931 4497 Star
+8931 4462 Star
+8931 4428 Star
+8931 4393 Star
+8931 4358 Star
+8931 4323 Star
+8931 4288 Star
+8931 4253 Star
+8931 4218 Star
+8931 4183 Star
+8931 4148 Star
+8931 4113 Star
+8931 4078 Star
+8931 4043 Star
+8931 4008 Star
+8931 3973 Star
+8931 3938 Star
+8931 3903 Star
+8931 3868 Star
+8931 3833 Star
+8931 3798 Star
+8931 3763 Star
+8931 3728 Star
+8931 3693 Star
+8931 3658 Star
+8931 3623 Star
+8931 3588 Star
+8931 3553 Star
+8931 3518 Star
+8931 3483 Star
+8931 3448 Star
+8931 3413 Star
+8931 3378 Star
+8931 3343 Star
+8931 3308 Star
+8931 3273 Star
+8931 3238 Star
+8931 3203 Star
+8931 3168 Star
+8931 3133 Star
+8931 3098 Star
+8931 3063 Star
+8931 3028 Star
+8931 2993 Star
+8931 2958 Star
+8931 2923 Star
+8931 2888 Star
+8931 2853 Star
+8931 2818 Star
+8931 2783 Star
+8931 2748 Star
+8931 2713 Star
+8931 2678 Star
+8931 2643 Star
+8931 2608 Star
+8931 2573 Star
+8931 2538 Star
+8931 2503 Star
+8931 2468 Star
+8931 2433 Star
+8931 2398 Star
+8931 2363 Star
+8931 2328 Star
+8931 2293 Star
+8931 2258 Star
+8931 2223 Star
+8931 2188 Star
+8931 2153 Star
+8931 2118 Star
+8931 2083 Star
+8976 4987 Star
+8976 4952 Star
+8976 4917 Star
+8976 4882 Star
+8976 4847 Star
+8976 4812 Star
+8976 4777 Star
+8976 4742 Star
+8976 4707 Star
+8976 4672 Star
+8976 4637 Star
+8976 4602 Star
+8976 4567 Star
+8976 4532 Star
+8976 4497 Star
+8976 4462 Star
+8976 4428 Star
+8976 4393 Star
+8976 4358 Star
+8976 4323 Star
+8976 4288 Star
+8976 4253 Star
+8976 4218 Star
+8976 4183 Star
+8976 4148 Star
+8976 4113 Star
+8976 4078 Star
+8976 4043 Star
+8976 4008 Star
+8976 3973 Star
+8976 3938 Star
+8976 3903 Star
+8976 3868 Star
+8976 3833 Star
+8976 3798 Star
+8976 3763 Star
+8976 3728 Star
+8976 3693 Star
+8976 3658 Star
+8976 3623 Star
+8976 3588 Star
+8976 3553 Star
+8976 3518 Star
+8976 3483 Star
+8976 3448 Star
+8976 3413 Star
+8976 3378 Star
+8976 3343 Star
+8976 3308 Star
+8976 3273 Star
+8976 3238 Star
+8976 3203 Star
+8976 3168 Star
+8976 3133 Star
+8976 3098 Star
+8976 3063 Star
+8976 3028 Star
+8976 2993 Star
+8976 2958 Star
+8976 2923 Star
+8976 2888 Star
+8976 2853 Star
+8976 2818 Star
+8976 2783 Star
+8976 2748 Star
+8976 2713 Star
+8976 2678 Star
+8976 2643 Star
+8976 2608 Star
+8976 2573 Star
+8976 2538 Star
+8976 2503 Star
+8976 2468 Star
+8976 2433 Star
+8976 2398 Star
+8976 2363 Star
+8976 2328 Star
+8976 2293 Star
+8976 2258 Star
+8976 2223 Star
+8976 2188 Star
+8976 2153 Star
+8976 2118 Star
+8976 2083 Star
+8976 2048 Star
+9020 4987 Star
+9020 4952 Star
+9020 4917 Star
+9020 4882 Star
+9020 4847 Star
+9020 4812 Star
+9020 4777 Star
+9020 4742 Star
+9020 4707 Star
+9020 4672 Star
+9020 4637 Star
+9020 4602 Star
+9020 4567 Star
+9020 4532 Star
+9020 4497 Star
+9020 4462 Star
+9020 4428 Star
+9020 4393 Star
+9020 4358 Star
+9020 4323 Star
+9020 4288 Star
+9020 4253 Star
+9020 4218 Star
+9020 4183 Star
+9020 4148 Star
+9020 4113 Star
+9020 4078 Star
+9020 4043 Star
+9020 4008 Star
+9020 3973 Star
+9020 3938 Star
+9020 3903 Star
+9020 3868 Star
+9020 3833 Star
+9020 3798 Star
+9020 3763 Star
+9020 3728 Star
+9020 3693 Star
+9020 3658 Star
+9020 3623 Star
+9020 3588 Star
+9020 3553 Star
+9020 3518 Star
+9020 3483 Star
+9020 3448 Star
+9020 3413 Star
+9020 3378 Star
+9020 3343 Star
+9020 3308 Star
+9020 3273 Star
+9020 3238 Star
+9020 3203 Star
+9020 3168 Star
+9020 3133 Star
+9020 3098 Star
+9020 3063 Star
+9020 3028 Star
+9020 2993 Star
+9020 2958 Star
+9020 2923 Star
+9020 2888 Star
+9020 2853 Star
+9020 2818 Star
+9020 2783 Star
+9020 2748 Star
+9020 2713 Star
+9020 2678 Star
+9020 2643 Star
+9020 2608 Star
+9020 2573 Star
+9020 2538 Star
+9020 2503 Star
+9020 2468 Star
+9020 2433 Star
+9020 2398 Star
+9020 2363 Star
+9020 2328 Star
+9020 2293 Star
+9020 2258 Star
+9020 2223 Star
+9020 2188 Star
+9020 2153 Star
+9020 2118 Star
+9020 2083 Star
+9020 2048 Star
+9020 2013 Star
+9065 4952 Star
+9065 4917 Star
+9065 4882 Star
+9065 4847 Star
+9065 4812 Star
+9065 4777 Star
+9065 4742 Star
+9065 4707 Star
+9065 4672 Star
+9065 4637 Star
+9065 4602 Star
+9065 4567 Star
+9065 4532 Star
+9065 4497 Star
+9065 4462 Star
+9065 4428 Star
+9065 4393 Star
+9065 4358 Star
+9065 4323 Star
+9065 4288 Star
+9065 4253 Star
+9065 4218 Star
+9065 4183 Star
+9065 4148 Star
+9065 4113 Star
+9065 4078 Star
+9065 4043 Star
+9065 4008 Star
+9065 3973 Star
+9065 3938 Star
+9065 3903 Star
+9065 3868 Star
+9065 3833 Star
+9065 3798 Star
+9065 3763 Star
+9065 3728 Star
+9065 3693 Star
+9065 3658 Star
+9065 3623 Star
+9065 3588 Star
+9065 3553 Star
+9065 3518 Star
+9065 3483 Star
+9065 3448 Star
+9065 3413 Star
+9065 3378 Star
+9065 3343 Star
+9065 3308 Star
+9065 3273 Star
+9065 3238 Star
+9065 3203 Star
+9065 3168 Star
+9065 3133 Star
+9065 3098 Star
+9065 3063 Star
+9065 3028 Star
+9065 2993 Star
+9065 2958 Star
+9065 2923 Star
+9065 2888 Star
+9065 2853 Star
+9065 2818 Star
+9065 2783 Star
+9065 2748 Star
+9065 2713 Star
+9065 2678 Star
+9065 2643 Star
+9065 2608 Star
+9065 2573 Star
+9065 2538 Star
+9065 2503 Star
+9065 2468 Star
+9065 2433 Star
+9065 2398 Star
+9065 2363 Star
+9065 2328 Star
+9065 2293 Star
+9065 2258 Star
+9065 2223 Star
+9065 2188 Star
+9065 2153 Star
+9065 2118 Star
+9065 2083 Star
+9065 2048 Star
+9065 2013 Star
+9065 1978 Star
+9109 4952 Star
+9109 4917 Star
+9109 4882 Star
+9109 4847 Star
+9109 4812 Star
+9109 4777 Star
+9109 4742 Star
+9109 4707 Star
+9109 4672 Star
+9109 4637 Star
+9109 4602 Star
+9109 4567 Star
+9109 4532 Star
+9109 4497 Star
+9109 4462 Star
+9109 4428 Star
+9109 4393 Star
+9109 4358 Star
+9109 4323 Star
+9109 4288 Star
+9109 4253 Star
+9109 4218 Star
+9109 4183 Star
+9109 4148 Star
+9109 4113 Star
+9109 4078 Star
+9109 4043 Star
+9109 4008 Star
+9109 3973 Star
+9109 3938 Star
+9109 3903 Star
+9109 3868 Star
+9109 3833 Star
+9109 3798 Star
+9109 3763 Star
+9109 3728 Star
+9109 3693 Star
+9109 3658 Star
+9109 3623 Star
+9109 3588 Star
+9109 3553 Star
+9109 3518 Star
+9109 3483 Star
+9109 3448 Star
+9109 3413 Star
+9109 3378 Star
+9109 3343 Star
+9109 3308 Star
+9109 3273 Star
+9109 3238 Star
+9109 3203 Star
+9109 3168 Star
+9109 3133 Star
+9109 3098 Star
+9109 3063 Star
+9109 3028 Star
+9109 2993 Star
+9109 2958 Star
+9109 2923 Star
+9109 2888 Star
+9109 2853 Star
+9109 2818 Star
+9109 2783 Star
+9109 2748 Star
+9109 2713 Star
+9109 2678 Star
+9109 2643 Star
+9109 2608 Star
+9109 2573 Star
+9109 2538 Star
+9109 2503 Star
+9109 2468 Star
+9109 2433 Star
+9109 2398 Star
+9109 2363 Star
+9109 2328 Star
+9109 2293 Star
+9109 2258 Star
+9109 2223 Star
+9109 2188 Star
+9109 2153 Star
+9109 2118 Star
+9109 2083 Star
+9109 2048 Star
+9109 2013 Star
+9109 1978 Star
+9109 1943 Star
+9153 4917 Star
+9153 4882 Star
+9153 4847 Star
+9153 4812 Star
+9153 4777 Star
+9153 4742 Star
+9153 4707 Star
+9153 4672 Star
+9153 4637 Star
+9153 4602 Star
+9153 4567 Star
+9153 4532 Star
+9153 4497 Star
+9153 4462 Star
+9153 4428 Star
+9153 4393 Star
+9153 4358 Star
+9153 4323 Star
+9153 4288 Star
+9153 4253 Star
+9153 4218 Star
+9153 4183 Star
+9153 4148 Star
+9153 4113 Star
+9153 4078 Star
+9153 4043 Star
+9153 4008 Star
+9153 3973 Star
+9153 3938 Star
+9153 3903 Star
+9153 3868 Star
+9153 3833 Star
+9153 3798 Star
+9153 3763 Star
+9153 3728 Star
+9153 3693 Star
+9153 3658 Star
+9153 3623 Star
+9153 3588 Star
+9153 3553 Star
+9153 3518 Star
+9153 3483 Star
+9153 3448 Star
+9153 3413 Star
+9153 3378 Star
+9153 3343 Star
+9153 3308 Star
+9153 3273 Star
+9153 3238 Star
+9153 3203 Star
+9153 3168 Star
+9153 3133 Star
+9153 3098 Star
+9153 3063 Star
+9153 3028 Star
+9153 2993 Star
+9153 2958 Star
+9153 2923 Star
+9153 2888 Star
+9153 2853 Star
+9153 2818 Star
+9153 2783 Star
+9153 2748 Star
+9153 2713 Star
+9153 2678 Star
+9153 2643 Star
+9153 2608 Star
+9153 2573 Star
+9153 2538 Star
+9153 2503 Star
+9153 2468 Star
+9153 2433 Star
+9153 2398 Star
+9153 2363 Star
+9153 2328 Star
+9153 2293 Star
+9153 2258 Star
+9153 2223 Star
+9153 2188 Star
+9153 2153 Star
+9153 2118 Star
+9153 2083 Star
+9153 2048 Star
+9153 2013 Star
+9153 1978 Star
+9153 1943 Star
+9153 1908 Star
+9198 4917 Star
+9198 4882 Star
+9198 4847 Star
+9198 4812 Star
+9198 4777 Star
+9198 4742 Star
+9198 4707 Star
+9198 4672 Star
+9198 4637 Star
+9198 4602 Star
+9198 4567 Star
+9198 4532 Star
+9198 4497 Star
+9198 4462 Star
+9198 4428 Star
+9198 4393 Star
+9198 4358 Star
+9198 4323 Star
+9198 4288 Star
+9198 4253 Star
+9198 4218 Star
+9198 4183 Star
+9198 4148 Star
+9198 4113 Star
+9198 4078 Star
+9198 4043 Star
+9198 4008 Star
+9198 3973 Star
+9198 3938 Star
+9198 3903 Star
+9198 3868 Star
+9198 3833 Star
+9198 3798 Star
+9198 3763 Star
+9198 3728 Star
+9198 3693 Star
+9198 3658 Star
+9198 3623 Star
+9198 3588 Star
+9198 3553 Star
+9198 3518 Star
+9198 3483 Star
+9198 3448 Star
+9198 3413 Star
+9198 3378 Star
+9198 3343 Star
+9198 3308 Star
+9198 3273 Star
+9198 3238 Star
+9198 3203 Star
+9198 3168 Star
+9198 3133 Star
+9198 3098 Star
+9198 3063 Star
+9198 3028 Star
+9198 2993 Star
+9198 2958 Star
+9198 2923 Star
+9198 2888 Star
+9198 2853 Star
+9198 2818 Star
+9198 2783 Star
+9198 2748 Star
+9198 2713 Star
+9198 2678 Star
+9198 2643 Star
+9198 2608 Star
+9198 2573 Star
+9198 2538 Star
+9198 2503 Star
+9198 2468 Star
+9198 2433 Star
+9198 2398 Star
+9198 2363 Star
+9198 2328 Star
+9198 2293 Star
+9198 2258 Star
+9198 2223 Star
+9198 2188 Star
+9198 2153 Star
+9198 2118 Star
+9198 2083 Star
+9198 2048 Star
+9198 2013 Star
+9198 1978 Star
+9198 1943 Star
+9198 1908 Star
+9198 1873 Star
+9242 4882 Star
+9242 4847 Star
+9242 4812 Star
+9242 4777 Star
+9242 4742 Star
+9242 4707 Star
+9242 4672 Star
+9242 4637 Star
+9242 4602 Star
+9242 4567 Star
+9242 4532 Star
+9242 4497 Star
+9242 4462 Star
+9242 4428 Star
+9242 4393 Star
+9242 4358 Star
+9242 4323 Star
+9242 4288 Star
+9242 4253 Star
+9242 4218 Star
+9242 4183 Star
+9242 4148 Star
+9242 4113 Star
+9242 4078 Star
+9242 4043 Star
+9242 4008 Star
+9242 3973 Star
+9242 3938 Star
+9242 3903 Star
+9242 3868 Star
+9242 3833 Star
+9242 3798 Star
+9242 3763 Star
+9242 3728 Star
+9242 3693 Star
+9242 3658 Star
+9242 3623 Star
+9242 3588 Star
+9242 3553 Star
+9242 3518 Star
+9242 3483 Star
+9242 3448 Star
+9242 3413 Star
+9242 3378 Star
+9242 3343 Star
+9242 3308 Star
+9242 3273 Star
+9242 3238 Star
+9242 3203 Star
+9242 3168 Star
+9242 3133 Star
+9242 3098 Star
+9242 3063 Star
+9242 3028 Star
+9242 2993 Star
+9242 2958 Star
+9242 2923 Star
+9242 2888 Star
+9242 2853 Star
+9242 2818 Star
+9242 2783 Star
+9242 2748 Star
+9242 2713 Star
+9242 2678 Star
+9242 2643 Star
+9242 2608 Star
+9242 2573 Star
+9242 2538 Star
+9242 2503 Star
+9242 2468 Star
+9242 2433 Star
+9242 2398 Star
+9242 2363 Star
+9242 2328 Star
+9242 2293 Star
+9242 2258 Star
+9242 2223 Star
+9242 2188 Star
+9242 2153 Star
+9242 2118 Star
+9242 2083 Star
+9242 2048 Star
+9242 2013 Star
+9242 1978 Star
+9242 1943 Star
+9242 1908 Star
+9242 1873 Star
+9242 1838 Star
+9286 4882 Star
+9286 4847 Star
+9286 4812 Star
+9286 4777 Star
+9286 4742 Star
+9286 4707 Star
+9286 4672 Star
+9286 4637 Star
+9286 4602 Star
+9286 4567 Star
+9286 4532 Star
+9286 4497 Star
+9286 4462 Star
+9286 4428 Star
+9286 4393 Star
+9286 4358 Star
+9286 4323 Star
+9286 4288 Star
+9286 4253 Star
+9286 4218 Star
+9286 4183 Star
+9286 4148 Star
+9286 4113 Star
+9286 4078 Star
+9286 4043 Star
+9286 4008 Star
+9286 3973 Star
+9286 3938 Star
+9286 3903 Star
+9286 3868 Star
+9286 3833 Star
+9286 3798 Star
+9286 3763 Star
+9286 3728 Star
+9286 3693 Star
+9286 3658 Star
+9286 3623 Star
+9286 3588 Star
+9286 3553 Star
+9286 3518 Star
+9286 3483 Star
+9286 3448 Star
+9286 3413 Star
+9286 3378 Star
+9286 3343 Star
+9286 3308 Star
+9286 3273 Star
+9286 3238 Star
+9286 3203 Star
+9286 3168 Star
+9286 3133 Star
+9286 3098 Star
+9286 3063 Star
+9286 3028 Star
+9286 2993 Star
+9286 2958 Star
+9286 2923 Star
+9286 2888 Star
+9286 2853 Star
+9286 2818 Star
+9286 2783 Star
+9286 2748 Star
+9286 2713 Star
+9286 2678 Star
+9286 2643 Star
+9286 2608 Star
+9286 2573 Star
+9286 2538 Star
+9286 2503 Star
+9286 2468 Star
+9286 2433 Star
+9286 2398 Star
+9286 2363 Star
+9286 2328 Star
+9286 2293 Star
+9286 2258 Star
+9286 2223 Star
+9286 2188 Star
+9286 2153 Star
+9286 2118 Star
+9286 2083 Star
+9286 2048 Star
+9286 2013 Star
+9286 1978 Star
+9286 1943 Star
+9286 1908 Star
+9286 1873 Star
+9286 1838 Star
+9286 1803 Star
+9331 4847 Star
+9331 4812 Star
+9331 4777 Star
+9331 4742 Star
+9331 4707 Star
+9331 4672 Star
+9331 4637 Star
+9331 4602 Star
+9331 4567 Star
+9331 4532 Star
+9331 4497 Star
+9331 4462 Star
+9331 4428 Star
+9331 4393 Star
+9331 4358 Star
+9331 4323 Star
+9331 4288 Star
+9331 4253 Star
+9331 4218 Star
+9331 4183 Star
+9331 4148 Star
+9331 4113 Star
+9331 4078 Star
+9331 4043 Star
+9331 4008 Star
+9331 3973 Star
+9331 3938 Star
+9331 3903 Star
+9331 3868 Star
+9331 3833 Star
+9331 3798 Star
+9331 3763 Star
+9331 3728 Star
+9331 3693 Star
+9331 3658 Star
+9331 3623 Star
+9331 3588 Star
+9331 3553 Star
+9331 3518 Star
+9331 3483 Star
+9331 3448 Star
+9331 3413 Star
+9331 3378 Star
+9331 3343 Star
+9331 3308 Star
+9331 3273 Star
+9331 3238 Star
+9331 3203 Star
+9331 3168 Star
+9331 3133 Star
+9331 3098 Star
+9331 3063 Star
+9331 3028 Star
+9331 2993 Star
+9331 2958 Star
+9331 2923 Star
+9331 2888 Star
+9331 2853 Star
+9331 2818 Star
+9331 2783 Star
+9331 2748 Star
+9331 2713 Star
+9331 2678 Star
+9331 2643 Star
+9331 2608 Star
+9331 2573 Star
+9331 2538 Star
+9331 2503 Star
+9331 2468 Star
+9331 2433 Star
+9331 2398 Star
+9331 2363 Star
+9331 2328 Star
+9331 2293 Star
+9331 2258 Star
+9331 2223 Star
+9331 2188 Star
+9331 2153 Star
+9331 2118 Star
+9331 2083 Star
+9331 2048 Star
+9331 2013 Star
+9331 1978 Star
+9331 1943 Star
+9331 1908 Star
+9331 1873 Star
+9331 1838 Star
+9331 1803 Star
+9331 1768 Star
+9375 4847 Star
+9375 4812 Star
+9375 4777 Star
+9375 4742 Star
+9375 4707 Star
+9375 4672 Star
+9375 4637 Star
+9375 4602 Star
+9375 4567 Star
+9375 4532 Star
+9375 4497 Star
+9375 4462 Star
+9375 4428 Star
+9375 4393 Star
+9375 4358 Star
+9375 4323 Star
+9375 4288 Star
+9375 4253 Star
+9375 4218 Star
+9375 4183 Star
+9375 4148 Star
+9375 4113 Star
+9375 4078 Star
+9375 4043 Star
+9375 4008 Star
+9375 3973 Star
+9375 3938 Star
+9375 3903 Star
+9375 3868 Star
+9375 3833 Star
+9375 3798 Star
+9375 3763 Star
+9375 3728 Star
+9375 3693 Star
+9375 3658 Star
+9375 3623 Star
+9375 3588 Star
+9375 3553 Star
+9375 3518 Star
+9375 3483 Star
+9375 3448 Star
+9375 3413 Star
+9375 3378 Star
+9375 3343 Star
+9375 3308 Star
+9375 3273 Star
+9375 3238 Star
+9375 3203 Star
+9375 3168 Star
+9375 3133 Star
+9375 3098 Star
+9375 3063 Star
+9375 3028 Star
+9375 2993 Star
+9375 2958 Star
+9375 2923 Star
+9375 2888 Star
+9375 2853 Star
+9375 2818 Star
+9375 2783 Star
+9375 2748 Star
+9375 2713 Star
+9375 2678 Star
+9375 2643 Star
+9375 2608 Star
+9375 2573 Star
+9375 2538 Star
+9375 2503 Star
+9375 2468 Star
+9375 2433 Star
+9375 2398 Star
+9375 2363 Star
+9375 2328 Star
+9375 2293 Star
+9375 2258 Star
+9375 2223 Star
+9375 2188 Star
+9375 2153 Star
+9375 2118 Star
+9375 2083 Star
+9375 2048 Star
+9375 2013 Star
+9375 1978 Star
+9375 1943 Star
+9375 1908 Star
+9375 1873 Star
+9375 1838 Star
+9375 1803 Star
+9375 1768 Star
+9375 1733 Star
+9420 4812 Star
+9420 4777 Star
+9420 4742 Star
+9420 4707 Star
+9420 4672 Star
+9420 4637 Star
+9420 4602 Star
+9420 4567 Star
+9420 4532 Star
+9420 4497 Star
+9420 4462 Star
+9420 4428 Star
+9420 4393 Star
+9420 4358 Star
+9420 4323 Star
+9420 4288 Star
+9420 4253 Star
+9420 4218 Star
+9420 4183 Star
+9420 4148 Star
+9420 4113 Star
+9420 4078 Star
+9420 4043 Star
+9420 4008 Star
+9420 3973 Star
+9420 3938 Star
+9420 3903 Star
+9420 3868 Star
+9420 3833 Star
+9420 3798 Star
+9420 3763 Star
+9420 3728 Star
+9420 3693 Star
+9420 3658 Star
+9420 3623 Star
+9420 3588 Star
+9420 3553 Star
+9420 3518 Star
+9420 3483 Star
+9420 3448 Star
+9420 3413 Star
+9420 3378 Star
+9420 3343 Star
+9420 3308 Star
+9420 3273 Star
+9420 3238 Star
+9420 3203 Star
+9420 3168 Star
+9420 3133 Star
+9420 3098 Star
+9420 3063 Star
+9420 3028 Star
+9420 2993 Star
+9420 2958 Star
+9420 2923 Star
+9420 2888 Star
+9420 2853 Star
+9420 2818 Star
+9420 2783 Star
+9420 2748 Star
+9420 2713 Star
+9420 2678 Star
+9420 2643 Star
+9420 2608 Star
+9420 2573 Star
+9420 2538 Star
+9420 2503 Star
+9420 2468 Star
+9420 2433 Star
+9420 2398 Star
+9420 2363 Star
+9420 2328 Star
+9420 2293 Star
+9420 2258 Star
+9420 2223 Star
+9420 2188 Star
+9420 2153 Star
+9420 2118 Star
+9420 2083 Star
+9420 2048 Star
+9420 2013 Star
+9420 1978 Star
+9420 1943 Star
+9420 1908 Star
+9420 1873 Star
+9420 1838 Star
+9420 1803 Star
+9420 1768 Star
+9420 1733 Star
+9420 1698 Star
+9464 4812 Star
+9464 4777 Star
+9464 4742 Star
+9464 4707 Star
+9464 4672 Star
+9464 4637 Star
+9464 4602 Star
+9464 4567 Star
+9464 4532 Star
+9464 4497 Star
+9464 4462 Star
+9464 4428 Star
+9464 4393 Star
+9464 4358 Star
+9464 4323 Star
+9464 4288 Star
+9464 4253 Star
+9464 4218 Star
+9464 4183 Star
+9464 4148 Star
+9464 4113 Star
+9464 4078 Star
+9464 4043 Star
+9464 4008 Star
+9464 3973 Star
+9464 3938 Star
+9464 3903 Star
+9464 3868 Star
+9464 3833 Star
+9464 3798 Star
+9464 3763 Star
+9464 3728 Star
+9464 3693 Star
+9464 3658 Star
+9464 3623 Star
+9464 3588 Star
+9464 3553 Star
+9464 3518 Star
+9464 3483 Star
+9464 3448 Star
+9464 3413 Star
+9464 3378 Star
+9464 3343 Star
+9464 3308 Star
+9464 3273 Star
+9464 3238 Star
+9464 3203 Star
+9464 3168 Star
+9464 3133 Star
+9464 3098 Star
+9464 3063 Star
+9464 3028 Star
+9464 2993 Star
+9464 2958 Star
+9464 2923 Star
+9464 2888 Star
+9464 2853 Star
+9464 2818 Star
+9464 2783 Star
+9464 2748 Star
+9464 2713 Star
+9464 2678 Star
+9464 2643 Star
+9464 2608 Star
+9464 2573 Star
+9464 2538 Star
+9464 2503 Star
+9464 2468 Star
+9464 2433 Star
+9464 2398 Star
+9464 2363 Star
+9464 2328 Star
+9464 2293 Star
+9464 2258 Star
+9464 2223 Star
+9464 2188 Star
+9464 2153 Star
+9464 2118 Star
+9464 2083 Star
+9464 2048 Star
+9464 2013 Star
+9464 1978 Star
+9464 1943 Star
+9464 1908 Star
+9464 1873 Star
+9464 1838 Star
+9464 1803 Star
+9464 1768 Star
+9464 1733 Star
+9464 1698 Star
+9464 1663 Star
+9508 4777 Star
+9508 4742 Star
+9508 4707 Star
+9508 4672 Star
+9508 4637 Star
+9508 4602 Star
+9508 4567 Star
+9508 4532 Star
+9508 4497 Star
+9508 4462 Star
+9508 4428 Star
+9508 4393 Star
+9508 4358 Star
+9508 4323 Star
+9508 4288 Star
+9508 4253 Star
+9508 4218 Star
+9508 4183 Star
+9508 4148 Star
+9508 4113 Star
+9508 4078 Star
+9508 4043 Star
+9508 4008 Star
+9508 3973 Star
+9508 3938 Star
+9508 3903 Star
+9508 3868 Star
+9508 3833 Star
+9508 3798 Star
+9508 3763 Star
+9508 3728 Star
+9508 3693 Star
+9508 3658 Star
+9508 3623 Star
+9508 3588 Star
+9508 3553 Star
+9508 3518 Star
+9508 3483 Star
+9508 3448 Star
+9508 3413 Star
+9508 3378 Star
+9508 3343 Star
+9508 3308 Star
+9508 3273 Star
+9508 3238 Star
+9508 3203 Star
+9508 3168 Star
+9508 3133 Star
+9508 3098 Star
+9508 3063 Star
+9508 3028 Star
+9508 2993 Star
+9508 2958 Star
+9508 2923 Star
+9508 2888 Star
+9508 2853 Star
+9508 2818 Star
+9508 2783 Star
+9508 2748 Star
+9508 2713 Star
+9508 2678 Star
+9508 2643 Star
+9508 2608 Star
+9508 2573 Star
+9508 2538 Star
+9508 2503 Star
+9508 2468 Star
+9508 2433 Star
+9508 2398 Star
+9508 2363 Star
+9508 2328 Star
+9508 2293 Star
+9508 2258 Star
+9508 2223 Star
+9508 2188 Star
+9508 2153 Star
+9508 2118 Star
+9508 2083 Star
+9508 2048 Star
+9508 2013 Star
+9508 1978 Star
+9508 1943 Star
+9508 1908 Star
+9508 1873 Star
+9508 1838 Star
+9508 1803 Star
+9508 1768 Star
+9508 1733 Star
+9508 1698 Star
+9508 1663 Star
+9508 1628 Star
+9553 4777 Star
+9553 4742 Star
+9553 4707 Star
+9553 4672 Star
+9553 4637 Star
+9553 4602 Star
+9553 4567 Star
+9553 4532 Star
+9553 4497 Star
+9553 4462 Star
+9553 4428 Star
+9553 4393 Star
+9553 4358 Star
+9553 4323 Star
+9553 4288 Star
+9553 4253 Star
+9553 4218 Star
+9553 4183 Star
+9553 4148 Star
+9553 4113 Star
+9553 4078 Star
+9553 4043 Star
+9553 4008 Star
+9553 3973 Star
+9553 3938 Star
+9553 3903 Star
+9553 3868 Star
+9553 3833 Star
+9553 3798 Star
+9553 3763 Star
+9553 3728 Star
+9553 3693 Star
+9553 3658 Star
+9553 3623 Star
+9553 3588 Star
+9553 3553 Star
+9553 3518 Star
+9553 3483 Star
+9553 3448 Star
+9553 3413 Star
+9553 3378 Star
+9553 3343 Star
+9553 3308 Star
+9553 3273 Star
+9553 3238 Star
+9553 3203 Star
+9553 3168 Star
+9553 3133 Star
+9553 3098 Star
+9553 3063 Star
+9553 3028 Star
+9553 2993 Star
+9553 2958 Star
+9553 2923 Star
+9553 2888 Star
+9553 2853 Star
+9553 2818 Star
+9553 2783 Star
+9553 2748 Star
+9553 2713 Star
+9553 2678 Star
+9553 2643 Star
+9553 2608 Star
+9553 2573 Star
+9553 2538 Star
+9553 2503 Star
+9553 2468 Star
+9553 2433 Star
+9553 2398 Star
+9553 2363 Star
+9553 2328 Star
+9553 2293 Star
+9553 2258 Star
+9553 2223 Star
+9553 2188 Star
+9553 2153 Star
+9553 2118 Star
+9553 2083 Star
+9553 2048 Star
+9553 2013 Star
+9553 1978 Star
+9553 1943 Star
+9553 1908 Star
+9553 1873 Star
+9553 1838 Star
+9553 1803 Star
+9553 1768 Star
+9553 1733 Star
+9553 1698 Star
+9553 1663 Star
+9553 1628 Star
+9553 1593 Star
+9597 4742 Star
+9597 4707 Star
+9597 4672 Star
+9597 4637 Star
+9597 4602 Star
+9597 4567 Star
+9597 4532 Star
+9597 4497 Star
+9597 4462 Star
+9597 4428 Star
+9597 4393 Star
+9597 4358 Star
+9597 4323 Star
+9597 4288 Star
+9597 4253 Star
+9597 4218 Star
+9597 4183 Star
+9597 4148 Star
+9597 4113 Star
+9597 4078 Star
+9597 4043 Star
+9597 4008 Star
+9597 3973 Star
+9597 3938 Star
+9597 3903 Star
+9597 3868 Star
+9597 3833 Star
+9597 3798 Star
+9597 3763 Star
+9597 3728 Star
+9597 3693 Star
+9597 3658 Star
+9597 3623 Star
+9597 3588 Star
+9597 3553 Star
+9597 3518 Star
+9597 3483 Star
+9597 3448 Star
+9597 3413 Star
+9597 3378 Star
+9597 3343 Star
+9597 3308 Star
+9597 3273 Star
+9597 3238 Star
+9597 3203 Star
+9597 3168 Star
+9597 3133 Star
+9597 3098 Star
+9597 3063 Star
+9597 3028 Star
+9597 2993 Star
+9597 2958 Star
+9597 2923 Star
+9597 2888 Star
+9597 2853 Star
+9597 2818 Star
+9597 2783 Star
+9597 2748 Star
+9597 2713 Star
+9597 2678 Star
+9597 2643 Star
+9597 2608 Star
+9597 2573 Star
+9597 2538 Star
+9597 2503 Star
+9597 2468 Star
+9597 2433 Star
+9597 2398 Star
+9597 2363 Star
+9597 2328 Star
+9597 2293 Star
+9597 2258 Star
+9597 2223 Star
+9597 2188 Star
+9597 2153 Star
+9597 2118 Star
+9597 2083 Star
+9597 2048 Star
+9597 2013 Star
+9597 1978 Star
+9597 1943 Star
+9597 1908 Star
+9597 1873 Star
+9597 1838 Star
+9597 1803 Star
+9597 1768 Star
+9597 1733 Star
+9597 1698 Star
+9597 1663 Star
+9597 1628 Star
+9597 1593 Star
+9597 1558 Star
+9641 4742 Star
+9641 4707 Star
+9641 4672 Star
+9641 4637 Star
+9641 4602 Star
+9641 4567 Star
+9641 4532 Star
+9641 4497 Star
+9641 4462 Star
+9641 4428 Star
+9641 4393 Star
+9641 4358 Star
+9641 4323 Star
+9641 4288 Star
+9641 4253 Star
+9641 4218 Star
+9641 4183 Star
+9641 4148 Star
+9641 4113 Star
+9641 4078 Star
+9641 4043 Star
+9641 4008 Star
+9641 3973 Star
+9641 3938 Star
+9641 3903 Star
+9641 3868 Star
+9641 3833 Star
+9641 3798 Star
+9641 3763 Star
+9641 3728 Star
+9641 3693 Star
+9641 3658 Star
+9641 3623 Star
+9641 3588 Star
+9641 3553 Star
+9641 3518 Star
+9641 3483 Star
+9641 3448 Star
+9641 3413 Star
+9641 3378 Star
+9641 3343 Star
+9641 3308 Star
+9641 3273 Star
+9641 3238 Star
+9641 3203 Star
+9641 3168 Star
+9641 3133 Star
+9641 3098 Star
+9641 3063 Star
+9641 3028 Star
+9641 2993 Star
+9641 2958 Star
+9641 2923 Star
+9641 2888 Star
+9641 2853 Star
+9641 2818 Star
+9641 2783 Star
+9641 2748 Star
+9641 2713 Star
+9641 2678 Star
+9641 2643 Star
+9641 2608 Star
+9641 2573 Star
+9641 2538 Star
+9641 2503 Star
+9641 2468 Star
+9641 2433 Star
+9641 2398 Star
+9641 2363 Star
+9641 2328 Star
+9641 2293 Star
+9641 2258 Star
+9641 2223 Star
+9641 2188 Star
+9641 2153 Star
+9641 2118 Star
+9641 2083 Star
+9641 2048 Star
+9641 2013 Star
+9641 1978 Star
+9641 1943 Star
+9641 1908 Star
+9641 1873 Star
+9641 1838 Star
+9641 1803 Star
+9641 1768 Star
+9641 1733 Star
+9641 1698 Star
+9641 1663 Star
+9641 1628 Star
+9641 1593 Star
+9641 1558 Star
+9641 1523 Star
+9686 4707 Star
+9686 4672 Star
+9686 4637 Star
+9686 4602 Star
+9686 4567 Star
+9686 4532 Star
+9686 4497 Star
+9686 4462 Star
+9686 4428 Star
+9686 4393 Star
+9686 4358 Star
+9686 4323 Star
+9686 4288 Star
+9686 4253 Star
+9686 4218 Star
+9686 4183 Star
+9686 4148 Star
+9686 4113 Star
+9686 4078 Star
+9686 4043 Star
+9686 4008 Star
+9686 3973 Star
+9686 3938 Star
+9686 3903 Star
+9686 3868 Star
+9686 3833 Star
+9686 3798 Star
+9686 3763 Star
+9686 3728 Star
+9686 3693 Star
+9686 3658 Star
+9686 3623 Star
+9686 3588 Star
+9686 3553 Star
+9686 3518 Star
+9686 3483 Star
+9686 3448 Star
+9686 3413 Star
+9686 3378 Star
+9686 3343 Star
+9686 3308 Star
+9686 3273 Star
+9686 3238 Star
+9686 3203 Star
+9686 3168 Star
+9686 3133 Star
+9686 3098 Star
+9686 3063 Star
+9686 3028 Star
+9686 2993 Star
+9686 2958 Star
+9686 2923 Star
+9686 2888 Star
+9686 2853 Star
+9686 2818 Star
+9686 2783 Star
+9686 2748 Star
+9686 2713 Star
+9686 2678 Star
+9686 2643 Star
+9686 2608 Star
+9686 2573 Star
+9686 2538 Star
+9686 2503 Star
+9686 2468 Star
+9686 2433 Star
+9686 2398 Star
+9686 2363 Star
+9686 2328 Star
+9686 2293 Star
+9686 2258 Star
+9686 2223 Star
+9686 2188 Star
+9686 2153 Star
+9686 2118 Star
+9686 2083 Star
+9686 2048 Star
+9686 2013 Star
+9686 1978 Star
+9686 1943 Star
+9686 1908 Star
+9686 1873 Star
+9686 1838 Star
+9686 1803 Star
+9686 1768 Star
+9686 1733 Star
+9686 1698 Star
+9686 1663 Star
+9686 1628 Star
+9686 1593 Star
+9686 1558 Star
+9686 1523 Star
+9686 1488 Star
+9730 4707 Star
+9730 4672 Star
+9730 4637 Star
+9730 4602 Star
+9730 4567 Star
+9730 4532 Star
+9730 4497 Star
+9730 4462 Star
+9730 4428 Star
+9730 4393 Star
+9730 4358 Star
+9730 4323 Star
+9730 4288 Star
+9730 4253 Star
+9730 4218 Star
+9730 4183 Star
+9730 4148 Star
+9730 4113 Star
+9730 4078 Star
+9730 4043 Star
+9730 4008 Star
+9730 3973 Star
+9730 3938 Star
+9730 3903 Star
+9730 3868 Star
+9730 3833 Star
+9730 3798 Star
+9730 3763 Star
+9730 3728 Star
+9730 3693 Star
+9730 3658 Star
+9730 3623 Star
+9730 3588 Star
+9730 3553 Star
+9730 3518 Star
+9730 3483 Star
+9730 3448 Star
+9730 3413 Star
+9730 3378 Star
+9730 3343 Star
+9730 3308 Star
+9730 3273 Star
+9730 3238 Star
+9730 3203 Star
+9730 3168 Star
+9730 3133 Star
+9730 3098 Star
+9730 3063 Star
+9730 3028 Star
+9730 2993 Star
+9730 2958 Star
+9730 2923 Star
+9730 2888 Star
+9730 2853 Star
+9730 2818 Star
+9730 2783 Star
+9730 2748 Star
+9730 2713 Star
+9730 2678 Star
+9730 2643 Star
+9730 2608 Star
+9730 2573 Star
+9730 2538 Star
+9730 2503 Star
+9730 2468 Star
+9730 2433 Star
+9730 2398 Star
+9730 2363 Star
+9730 2328 Star
+9730 2293 Star
+9730 2258 Star
+9730 2223 Star
+9730 2188 Star
+9730 2153 Star
+9730 2118 Star
+9730 2083 Star
+9730 2048 Star
+9730 2013 Star
+9730 1978 Star
+9730 1943 Star
+9730 1908 Star
+9730 1873 Star
+9730 1838 Star
+9730 1803 Star
+9730 1768 Star
+9730 1733 Star
+9730 1698 Star
+9730 1663 Star
+9730 1628 Star
+9730 1593 Star
+9730 1558 Star
+9730 1523 Star
+9730 1488 Star
+9730 1453 Star
+9775 4672 Star
+9775 4637 Star
+9775 4602 Star
+9775 4567 Star
+9775 4532 Star
+9775 4497 Star
+9775 4462 Star
+9775 4428 Star
+9775 4393 Star
+9775 4358 Star
+9775 4323 Star
+9775 4288 Star
+9775 4253 Star
+9775 4218 Star
+9775 4183 Star
+9775 4148 Star
+9775 4113 Star
+9775 4078 Star
+9775 4043 Star
+9775 4008 Star
+9775 3973 Star
+9775 3938 Star
+9775 3903 Star
+9775 3868 Star
+9775 3833 Star
+9775 3798 Star
+9775 3763 Star
+9775 3728 Star
+9775 3693 Star
+9775 3658 Star
+9775 3623 Star
+9775 3588 Star
+9775 3553 Star
+9775 3518 Star
+9775 3483 Star
+9775 3448 Star
+9775 3413 Star
+9775 3378 Star
+9775 3343 Star
+9775 3308 Star
+9775 3273 Star
+9775 3238 Star
+9775 3203 Star
+9775 3168 Star
+9775 3133 Star
+9775 3098 Star
+9775 3063 Star
+9775 3028 Star
+9775 2993 Star
+9775 2958 Star
+9775 2923 Star
+9775 2888 Star
+9775 2853 Star
+9775 2818 Star
+9775 2783 Star
+9775 2748 Star
+9775 2713 Star
+9775 2678 Star
+9775 2643 Star
+9775 2608 Star
+9775 2573 Star
+9775 2538 Star
+9775 2503 Star
+9775 2468 Star
+9775 2433 Star
+9775 2398 Star
+9775 2363 Star
+9775 2328 Star
+9775 2293 Star
+9775 2258 Star
+9775 2223 Star
+9775 2188 Star
+9775 2153 Star
+9775 2118 Star
+9775 2083 Star
+9775 2048 Star
+9775 2013 Star
+9775 1978 Star
+9775 1943 Star
+9775 1908 Star
+9775 1873 Star
+9775 1838 Star
+9775 1803 Star
+9775 1768 Star
+9775 1733 Star
+9775 1698 Star
+9775 1663 Star
+9775 1628 Star
+9775 1593 Star
+9775 1558 Star
+9775 1523 Star
+9775 1488 Star
+9775 1453 Star
+9775 1418 Star
+9819 4672 Star
+9819 4637 Star
+9819 4602 Star
+9819 4567 Star
+9819 4532 Star
+9819 4497 Star
+9819 4462 Star
+9819 4428 Star
+9819 4393 Star
+9819 4358 Star
+9819 4323 Star
+9819 4288 Star
+9819 4253 Star
+9819 4218 Star
+9819 4183 Star
+9819 4148 Star
+9819 4113 Star
+9819 4078 Star
+9819 4043 Star
+9819 4008 Star
+9819 3973 Star
+9819 3938 Star
+9819 3903 Star
+9819 3868 Star
+9819 3833 Star
+9819 3798 Star
+9819 3763 Star
+9819 3728 Star
+9819 3693 Star
+9819 3658 Star
+9819 3623 Star
+9819 3588 Star
+9819 3553 Star
+9819 3518 Star
+9819 3483 Star
+9819 3448 Star
+9819 3413 Star
+9819 3378 Star
+9819 3343 Star
+9819 3308 Star
+9819 3273 Star
+9819 3238 Star
+9819 3203 Star
+9819 3168 Star
+9819 3133 Star
+9819 3098 Star
+9819 3063 Star
+9819 3028 Star
+9819 2993 Star
+9819 2958 Star
+9819 2923 Star
+9819 2888 Star
+9819 2853 Star
+9819 2818 Star
+9819 2783 Star
+9819 2748 Star
+9819 2713 Star
+9819 2678 Star
+9819 2643 Star
+9819 2608 Star
+9819 2573 Star
+9819 2538 Star
+9819 2503 Star
+9819 2468 Star
+9819 2433 Star
+9819 2398 Star
+9819 2363 Star
+9819 2328 Star
+9819 2293 Star
+9819 2258 Star
+9819 2223 Star
+9819 2188 Star
+9819 2153 Star
+9819 2118 Star
+9819 2083 Star
+9819 2048 Star
+9819 2013 Star
+9819 1978 Star
+9819 1943 Star
+9819 1908 Star
+9819 1873 Star
+9819 1838 Star
+9819 1803 Star
+9819 1768 Star
+9819 1733 Star
+9819 1698 Star
+9819 1663 Star
+9819 1628 Star
+9819 1593 Star
+9819 1558 Star
+9819 1523 Star
+9819 1488 Star
+9819 1453 Star
+9819 1418 Star
+9819 1383 Star
+9863 4637 Star
+9863 4602 Star
+9863 4567 Star
+9863 4532 Star
+9863 4497 Star
+9863 4462 Star
+9863 4428 Star
+9863 4393 Star
+9863 4358 Star
+9863 4323 Star
+9863 4288 Star
+9863 4253 Star
+9863 4218 Star
+9863 4183 Star
+9863 4148 Star
+9863 4113 Star
+9863 4078 Star
+9863 4043 Star
+9863 4008 Star
+9863 3973 Star
+9863 3938 Star
+9863 3903 Star
+9863 3868 Star
+9863 3833 Star
+9863 3798 Star
+9863 3763 Star
+9863 3728 Star
+9863 3693 Star
+9863 3658 Star
+9863 3623 Star
+9863 3588 Star
+9863 3553 Star
+9863 3518 Star
+9863 3483 Star
+9863 3448 Star
+9863 3413 Star
+9863 3378 Star
+9863 3343 Star
+9863 3308 Star
+9863 3273 Star
+9863 3238 Star
+9863 3203 Star
+9863 3168 Star
+9863 3133 Star
+9863 3098 Star
+9863 3063 Star
+9863 3028 Star
+9863 2993 Star
+9863 2958 Star
+9863 2923 Star
+9863 2888 Star
+9863 2853 Star
+9863 2818 Star
+9863 2783 Star
+9863 2748 Star
+9863 2713 Star
+9863 2678 Star
+9863 2643 Star
+9863 2608 Star
+9863 2573 Star
+9863 2538 Star
+9863 2503 Star
+9863 2468 Star
+9863 2433 Star
+9863 2398 Star
+9863 2363 Star
+9863 2328 Star
+9863 2293 Star
+9863 2258 Star
+9863 2223 Star
+9863 2188 Star
+9863 2153 Star
+9863 2118 Star
+9863 2083 Star
+9863 2048 Star
+9863 2013 Star
+9863 1978 Star
+9863 1943 Star
+9863 1908 Star
+9863 1873 Star
+9863 1838 Star
+9863 1803 Star
+9863 1768 Star
+9863 1733 Star
+9863 1698 Star
+9863 1663 Star
+9863 1628 Star
+9863 1593 Star
+9863 1558 Star
+9863 1523 Star
+9863 1488 Star
+9863 1453 Star
+9863 1418 Star
+9863 1383 Star
+9863 1348 Star
+9908 4637 Star
+9908 4602 Star
+9908 4567 Star
+9908 4532 Star
+9908 4497 Star
+9908 4462 Star
+9908 4428 Star
+9908 4393 Star
+9908 4358 Star
+9908 4323 Star
+9908 4288 Star
+9908 4253 Star
+9908 4218 Star
+9908 4183 Star
+9908 4148 Star
+9908 4113 Star
+9908 4078 Star
+9908 4043 Star
+9908 4008 Star
+9908 3973 Star
+9908 3938 Star
+9908 3903 Star
+9908 3868 Star
+9908 3833 Star
+9908 3798 Star
+9908 3763 Star
+9908 3728 Star
+9908 3693 Star
+9908 3658 Star
+9908 3623 Star
+9908 3588 Star
+9908 3553 Star
+9908 3518 Star
+9908 3483 Star
+9908 3448 Star
+9908 3413 Star
+9908 3378 Star
+9908 3343 Star
+9908 3308 Star
+9908 3273 Star
+9908 3238 Star
+9908 3203 Star
+9908 3168 Star
+9908 3133 Star
+9908 3098 Star
+9908 3063 Star
+9908 3028 Star
+9908 2993 Star
+9908 2958 Star
+9908 2923 Star
+9908 2888 Star
+9908 2853 Star
+9908 2818 Star
+9908 2783 Star
+9908 2748 Star
+9908 2713 Star
+9908 2678 Star
+9908 2643 Star
+9908 2608 Star
+9908 2573 Star
+9908 2538 Star
+9908 2503 Star
+9908 2468 Star
+9908 2433 Star
+9908 2398 Star
+9908 2363 Star
+9908 2328 Star
+9908 2293 Star
+9908 2258 Star
+9908 2223 Star
+9908 2188 Star
+9908 2153 Star
+9908 2118 Star
+9908 2083 Star
+9908 2048 Star
+9908 2013 Star
+9908 1978 Star
+9908 1943 Star
+9908 1908 Star
+9908 1873 Star
+9908 1838 Star
+9908 1803 Star
+9908 1768 Star
+9908 1733 Star
+9908 1698 Star
+9908 1663 Star
+9908 1628 Star
+9908 1593 Star
+9908 1558 Star
+9908 1523 Star
+9908 1488 Star
+9908 1453 Star
+9908 1418 Star
+9908 1383 Star
+9908 1348 Star
+9908 1313 Star
+9952 4602 Star
+9952 4567 Star
+9952 4532 Star
+9952 4497 Star
+9952 4462 Star
+9952 4428 Star
+9952 4393 Star
+9952 4358 Star
+9952 4323 Star
+9952 4288 Star
+9952 4253 Star
+9952 4218 Star
+9952 4183 Star
+9952 4148 Star
+9952 4113 Star
+9952 4078 Star
+9952 4043 Star
+9952 4008 Star
+9952 3973 Star
+9952 3938 Star
+9952 3903 Star
+9952 3868 Star
+9952 3833 Star
+9952 3798 Star
+9952 3763 Star
+9952 3728 Star
+9952 3693 Star
+9952 3658 Star
+9952 3623 Star
+9952 3588 Star
+9952 3553 Star
+9952 3518 Star
+9952 3483 Star
+9952 3448 Star
+9952 3413 Star
+9952 3378 Star
+9952 3343 Star
+9952 3308 Star
+9952 3273 Star
+9952 3238 Star
+9952 3203 Star
+9952 3168 Star
+9952 3133 Star
+9952 3098 Star
+9952 3063 Star
+9952 3028 Star
+9952 2993 Star
+9952 2958 Star
+9952 2923 Star
+9952 2888 Star
+9952 2853 Star
+9952 2818 Star
+9952 2783 Star
+9952 2748 Star
+9952 2713 Star
+9952 2678 Star
+9952 2643 Star
+9952 2608 Star
+9952 2573 Star
+9952 2538 Star
+9952 2503 Star
+9952 2468 Star
+9952 2433 Star
+9952 2398 Star
+9952 2363 Star
+9952 2328 Star
+9952 2293 Star
+9952 2258 Star
+9952 2223 Star
+9952 2188 Star
+9952 2153 Star
+9952 2118 Star
+9952 2083 Star
+9952 2048 Star
+9952 2013 Star
+9952 1978 Star
+9952 1943 Star
+9952 1908 Star
+9952 1873 Star
+9952 1838 Star
+9952 1803 Star
+9952 1768 Star
+9952 1733 Star
+9952 1698 Star
+9952 1663 Star
+9952 1628 Star
+9952 1593 Star
+9952 1558 Star
+9952 1523 Star
+9952 1488 Star
+9952 1453 Star
+9952 1418 Star
+9952 1383 Star
+9952 1348 Star
+9952 1313 Star
+9952 1278 Star
+9997 4602 Star
+9997 4567 Star
+9997 4532 Star
+9997 4497 Star
+9997 4462 Star
+9997 4428 Star
+9997 4393 Star
+9997 4358 Star
+9997 4323 Star
+9997 4288 Star
+9997 4253 Star
+9997 4218 Star
+9997 4183 Star
+9997 4148 Star
+9997 4113 Star
+9997 4078 Star
+9997 4043 Star
+9997 4008 Star
+9997 3973 Star
+9997 3938 Star
+9997 3903 Star
+9997 3868 Star
+9997 3833 Star
+9997 3798 Star
+9997 3763 Star
+9997 3728 Star
+9997 3693 Star
+9997 3658 Star
+9997 3623 Star
+9997 3588 Star
+9997 3553 Star
+9997 3518 Star
+9997 3483 Star
+9997 3448 Star
+9997 3413 Star
+9997 3378 Star
+9997 3343 Star
+9997 3308 Star
+9997 3273 Star
+9997 3238 Star
+9997 3203 Star
+9997 3168 Star
+9997 3133 Star
+9997 3098 Star
+9997 3063 Star
+9997 3028 Star
+9997 2993 Star
+9997 2958 Star
+9997 2923 Star
+9997 2888 Star
+9997 2853 Star
+9997 2818 Star
+9997 2783 Star
+9997 2748 Star
+9997 2713 Star
+9997 2678 Star
+9997 2643 Star
+9997 2608 Star
+9997 2573 Star
+9997 2538 Star
+9997 2503 Star
+9997 2468 Star
+9997 2433 Star
+9997 2398 Star
+9997 2363 Star
+9997 2328 Star
+9997 2293 Star
+9997 2258 Star
+9997 2223 Star
+9997 2188 Star
+9997 2153 Star
+9997 2118 Star
+9997 2083 Star
+9997 2048 Star
+9997 2013 Star
+9997 1978 Star
+9997 1943 Star
+9997 1908 Star
+9997 1873 Star
+9997 1838 Star
+9997 1803 Star
+9997 1768 Star
+9997 1733 Star
+9997 1698 Star
+9997 1663 Star
+9997 1628 Star
+9997 1593 Star
+9997 1558 Star
+9997 1523 Star
+9997 1488 Star
+9997 1453 Star
+9997 1418 Star
+9997 1383 Star
+9997 1348 Star
+9997 1313 Star
+9997 1278 Star
+9997 1243 Star
+10041 4567 Star
+10041 4532 Star
+10041 4497 Star
+10041 4462 Star
+10041 4428 Star
+10041 4393 Star
+10041 4358 Star
+10041 4323 Star
+10041 4288 Star
+10041 4253 Star
+10041 4218 Star
+10041 4183 Star
+10041 4148 Star
+10041 4113 Star
+10041 4078 Star
+10041 4043 Star
+10041 4008 Star
+10041 3973 Star
+10041 3938 Star
+10041 3903 Star
+10041 3868 Star
+10041 3833 Star
+10041 3798 Star
+10041 3763 Star
+10041 3728 Star
+10041 3693 Star
+10041 3658 Star
+10041 3623 Star
+10041 3588 Star
+10041 3553 Star
+10041 3518 Star
+10041 3483 Star
+10041 3448 Star
+10041 3413 Star
+10041 3378 Star
+10041 3343 Star
+10041 3308 Star
+10041 3273 Star
+10041 3238 Star
+10041 3203 Star
+10041 3168 Star
+10041 3133 Star
+10041 3098 Star
+10041 3063 Star
+10041 3028 Star
+10041 2993 Star
+10041 2958 Star
+10041 2923 Star
+10041 2888 Star
+10041 2853 Star
+10041 2818 Star
+10041 2783 Star
+10041 2748 Star
+10041 2713 Star
+10041 2678 Star
+10041 2643 Star
+10041 2608 Star
+10041 2573 Star
+10041 2538 Star
+10041 2503 Star
+10041 2468 Star
+10041 2433 Star
+10041 2398 Star
+10041 2363 Star
+10041 2328 Star
+10041 2293 Star
+10041 2258 Star
+10041 2223 Star
+10041 2188 Star
+10041 2153 Star
+10041 2118 Star
+10041 2083 Star
+10041 2048 Star
+10041 2013 Star
+10041 1978 Star
+10041 1943 Star
+10041 1908 Star
+10041 1873 Star
+10041 1838 Star
+10041 1803 Star
+10041 1768 Star
+10041 1733 Star
+10041 1698 Star
+10041 1663 Star
+10041 1628 Star
+10041 1593 Star
+10041 1558 Star
+10041 1523 Star
+10041 1488 Star
+10041 1453 Star
+10041 1418 Star
+10041 1383 Star
+10041 1348 Star
+10041 1313 Star
+10041 1278 Star
+10041 1243 Star
+10041 1208 Star
+10085 4567 Star
+10085 4532 Star
+10085 4497 Star
+10085 4462 Star
+10085 4428 Star
+10085 4393 Star
+10085 4358 Star
+10085 4323 Star
+10085 4288 Star
+10085 4253 Star
+10085 4218 Star
+10085 4183 Star
+10085 4148 Star
+10085 4113 Star
+10085 4078 Star
+10085 4043 Star
+10085 4008 Star
+10085 3973 Star
+10085 3938 Star
+10085 3903 Star
+10085 3868 Star
+10085 3833 Star
+10085 3798 Star
+10085 3763 Star
+10085 3728 Star
+10085 3693 Star
+10085 3658 Star
+10085 3623 Star
+10085 3588 Star
+10085 3553 Star
+10085 3518 Star
+10085 3483 Star
+10085 3448 Star
+10085 3413 Star
+10085 3378 Star
+10085 3343 Star
+10085 3308 Star
+10085 3273 Star
+10085 3238 Star
+10085 3203 Star
+10085 3168 Star
+10085 3133 Star
+10085 3098 Star
+10085 3063 Star
+10085 3028 Star
+10085 2993 Star
+10085 2958 Star
+10085 2923 Star
+10085 2888 Star
+10085 2853 Star
+10085 2818 Star
+10085 2783 Star
+10085 2748 Star
+10085 2713 Star
+10085 2678 Star
+10085 2643 Star
+10085 2608 Star
+10085 2573 Star
+10085 2538 Star
+10085 2503 Star
+10085 2468 Star
+10085 2433 Star
+10085 2398 Star
+10085 2363 Star
+10085 2328 Star
+10085 2293 Star
+10085 2258 Star
+10085 2223 Star
+10085 2188 Star
+10085 2153 Star
+10085 2118 Star
+10085 2083 Star
+10085 2048 Star
+10085 2013 Star
+10085 1978 Star
+10085 1943 Star
+10085 1908 Star
+10085 1873 Star
+10085 1838 Star
+10085 1803 Star
+10085 1768 Star
+10085 1733 Star
+10085 1698 Star
+10085 1663 Star
+10085 1628 Star
+10085 1593 Star
+10085 1558 Star
+10085 1523 Star
+10085 1488 Star
+10085 1453 Star
+10085 1418 Star
+10085 1383 Star
+10085 1348 Star
+10085 1313 Star
+10085 1278 Star
+10085 1243 Star
+10085 1208 Star
+10085 1173 Star
+10130 4532 Star
+10130 4497 Star
+10130 4462 Star
+10130 4428 Star
+10130 4393 Star
+10130 4358 Star
+10130 4323 Star
+10130 4288 Star
+10130 4253 Star
+10130 4218 Star
+10130 4183 Star
+10130 4148 Star
+10130 4113 Star
+10130 4078 Star
+10130 4043 Star
+10130 4008 Star
+10130 3973 Star
+10130 3938 Star
+10130 3903 Star
+10130 3868 Star
+10130 3833 Star
+10130 3798 Star
+10130 3763 Star
+10130 3728 Star
+10130 3693 Star
+10130 3658 Star
+10130 3623 Star
+10130 3588 Star
+10130 3553 Star
+10130 3518 Star
+10130 3483 Star
+10130 3448 Star
+10130 3413 Star
+10130 3378 Star
+10130 3343 Star
+10130 3308 Star
+10130 3273 Star
+10130 3238 Star
+10130 3203 Star
+10130 3168 Star
+10130 3133 Star
+10130 3098 Star
+10130 3063 Star
+10130 3028 Star
+10130 2993 Star
+10130 2958 Star
+10130 2923 Star
+10130 2888 Star
+10130 2853 Star
+10130 2818 Star
+10130 2783 Star
+10130 2748 Star
+10130 2713 Star
+10130 2678 Star
+10130 2643 Star
+10130 2608 Star
+10130 2573 Star
+10130 2538 Star
+10130 2503 Star
+10130 2468 Star
+10130 2433 Star
+10130 2398 Star
+10130 2363 Star
+10130 2328 Star
+10130 2293 Star
+10130 2258 Star
+10130 2223 Star
+10130 2188 Star
+10130 2153 Star
+10130 2118 Star
+10130 2083 Star
+10130 2048 Star
+10130 2013 Star
+10130 1978 Star
+10130 1943 Star
+10130 1908 Star
+10130 1873 Star
+10130 1838 Star
+10130 1803 Star
+10130 1768 Star
+10130 1733 Star
+10130 1698 Star
+10130 1663 Star
+10130 1628 Star
+10130 1593 Star
+10130 1558 Star
+10130 1523 Star
+10130 1488 Star
+10130 1453 Star
+10130 1418 Star
+10130 1383 Star
+10130 1348 Star
+10130 1313 Star
+10130 1278 Star
+10130 1243 Star
+10130 1208 Star
+10130 1173 Star
+10130 1138 Star
+10174 4532 Star
+10174 4497 Star
+10174 4462 Star
+10174 4428 Star
+10174 4393 Star
+10174 4358 Star
+10174 4323 Star
+10174 4288 Star
+10174 4253 Star
+10174 4218 Star
+10174 4183 Star
+10174 4148 Star
+10174 4113 Star
+10174 4078 Star
+10174 4043 Star
+10174 4008 Star
+10174 3973 Star
+10174 3938 Star
+10174 3903 Star
+10174 3868 Star
+10174 3833 Star
+10174 3798 Star
+10174 3763 Star
+10174 3728 Star
+10174 3693 Star
+10174 3658 Star
+10174 3623 Star
+10174 3588 Star
+10174 3553 Star
+10174 3518 Star
+10174 3483 Star
+10174 3448 Star
+10174 3413 Star
+10174 3378 Star
+10174 3343 Star
+10174 3308 Star
+10174 3273 Star
+10174 3238 Star
+10174 3203 Star
+10174 3168 Star
+10174 3133 Star
+10174 3098 Star
+10174 3063 Star
+10174 3028 Star
+10174 2993 Star
+10174 2958 Star
+10174 2923 Star
+10174 2888 Star
+10174 2853 Star
+10174 2818 Star
+10174 2783 Star
+10174 2748 Star
+10174 2713 Star
+10174 2678 Star
+10174 2643 Star
+10174 2608 Star
+10174 2573 Star
+10174 2538 Star
+10174 2503 Star
+10174 2468 Star
+10174 2433 Star
+10174 2398 Star
+10174 2363 Star
+10174 2328 Star
+10174 2293 Star
+10174 2258 Star
+10174 2223 Star
+10174 2188 Star
+10174 2153 Star
+10174 2118 Star
+10174 2083 Star
+10174 2048 Star
+10174 2013 Star
+10174 1978 Star
+10174 1943 Star
+10174 1908 Star
+10174 1873 Star
+10174 1838 Star
+10174 1803 Star
+10174 1768 Star
+10174 1733 Star
+10174 1698 Star
+10174 1663 Star
+10174 1628 Star
+10174 1593 Star
+10174 1558 Star
+10174 1523 Star
+10174 1488 Star
+10174 1453 Star
+10174 1418 Star
+10174 1383 Star
+10174 1348 Star
+10174 1313 Star
+10174 1278 Star
+10174 1243 Star
+10174 1208 Star
+10174 1173 Star
+10174 1138 Star
+10174 1103 Star
+10218 4497 Star
+10218 4462 Star
+10218 4428 Star
+10218 4393 Star
+10218 4358 Star
+10218 4323 Star
+10218 4288 Star
+10218 4253 Star
+10218 4218 Star
+10218 4183 Star
+10218 4148 Star
+10218 4113 Star
+10218 4078 Star
+10218 4043 Star
+10218 4008 Star
+10218 3973 Star
+10218 3938 Star
+10218 3903 Star
+10218 3868 Star
+10218 3833 Star
+10218 3798 Star
+10218 3763 Star
+10218 3728 Star
+10218 3693 Star
+10218 3658 Star
+10218 3623 Star
+10218 3588 Star
+10218 3553 Star
+10218 3518 Star
+10218 3483 Star
+10218 3448 Star
+10218 3413 Star
+10218 3378 Star
+10218 3343 Star
+10218 3308 Star
+10218 3273 Star
+10218 3238 Star
+10218 3203 Star
+10218 3168 Star
+10218 3133 Star
+10218 3098 Star
+10218 3063 Star
+10218 3028 Star
+10218 2993 Star
+10218 2958 Star
+10218 2923 Star
+10218 2888 Star
+10218 2853 Star
+10218 2818 Star
+10218 2783 Star
+10218 2748 Star
+10218 2713 Star
+10218 2678 Star
+10218 2643 Star
+10218 2608 Star
+10218 2573 Star
+10218 2538 Star
+10218 2503 Star
+10218 2468 Star
+10218 2433 Star
+10218 2398 Star
+10218 2363 Star
+10218 2328 Star
+10218 2293 Star
+10218 2258 Star
+10218 2223 Star
+10218 2188 Star
+10218 2153 Star
+10218 2118 Star
+10218 2083 Star
+10218 2048 Star
+10218 2013 Star
+10218 1978 Star
+10218 1943 Star
+10218 1908 Star
+10218 1873 Star
+10218 1838 Star
+10218 1803 Star
+10218 1768 Star
+10218 1733 Star
+10218 1698 Star
+10218 1663 Star
+10218 1628 Star
+10218 1593 Star
+10218 1558 Star
+10218 1523 Star
+10218 1488 Star
+10218 1453 Star
+10218 1418 Star
+10218 1383 Star
+10218 1348 Star
+10218 1313 Star
+10218 1278 Star
+10218 1243 Star
+10218 1208 Star
+10218 1173 Star
+10218 1138 Star
+10218 1103 Star
+10218 1068 Star
+10263 4497 Star
+10263 4462 Star
+10263 4428 Star
+10263 4393 Star
+10263 4358 Star
+10263 4323 Star
+10263 4288 Star
+10263 4253 Star
+10263 4218 Star
+10263 4183 Star
+10263 4148 Star
+10263 4113 Star
+10263 4078 Star
+10263 4043 Star
+10263 4008 Star
+10263 3973 Star
+10263 3938 Star
+10263 3903 Star
+10263 3868 Star
+10263 3833 Star
+10263 3798 Star
+10263 3763 Star
+10263 3728 Star
+10263 3693 Star
+10263 3658 Star
+10263 3623 Star
+10263 3588 Star
+10263 3553 Star
+10263 3518 Star
+10263 3483 Star
+10263 3448 Star
+10263 3413 Star
+10263 3378 Star
+10263 3343 Star
+10263 3308 Star
+10263 3273 Star
+10263 3238 Star
+10263 3203 Star
+10263 3168 Star
+10263 3133 Star
+10263 3098 Star
+10263 3063 Star
+10263 3028 Star
+10263 2993 Star
+10263 2958 Star
+10263 2923 Star
+10263 2888 Star
+10263 2853 Star
+10263 2818 Star
+10263 2783 Star
+10263 2748 Star
+10263 2713 Star
+10263 2678 Star
+10263 2643 Star
+10263 2608 Star
+10263 2573 Star
+10263 2538 Star
+10263 2503 Star
+10263 2468 Star
+10263 2433 Star
+10263 2398 Star
+10263 2363 Star
+10263 2328 Star
+10263 2293 Star
+10263 2258 Star
+10263 2223 Star
+10263 2188 Star
+10263 2153 Star
+10263 2118 Star
+10263 2083 Star
+10263 2048 Star
+10263 2013 Star
+10263 1978 Star
+10263 1943 Star
+10263 1908 Star
+10263 1873 Star
+10263 1838 Star
+10263 1803 Star
+10263 1768 Star
+10263 1733 Star
+10263 1698 Star
+10263 1663 Star
+10263 1628 Star
+10263 1593 Star
+10263 1558 Star
+10263 1523 Star
+10263 1488 Star
+10263 1453 Star
+10263 1418 Star
+10263 1383 Star
+10263 1348 Star
+10263 1313 Star
+10263 1278 Star
+10263 1243 Star
+10263 1208 Star
+10263 1173 Star
+10263 1138 Star
+10263 1103 Star
+10263 1068 Star
+10263 1033 Star
+10307 4462 Star
+10307 4428 Star
+10307 4393 Star
+10307 4358 Star
+10307 4323 Star
+10307 4288 Star
+10307 4253 Star
+10307 4218 Star
+10307 4183 Star
+10307 4148 Star
+10307 4113 Star
+10307 4078 Star
+10307 4043 Star
+10307 4008 Star
+10307 3973 Star
+10307 3938 Star
+10307 3903 Star
+10307 3868 Star
+10307 3833 Star
+10307 3798 Star
+10307 3763 Star
+10307 3728 Star
+10307 3693 Star
+10307 3658 Star
+10307 3623 Star
+10307 3588 Star
+10307 3553 Star
+10307 3518 Star
+10307 3483 Star
+10307 3448 Star
+10307 3413 Star
+10307 3378 Star
+10307 3343 Star
+10307 3308 Star
+10307 3273 Star
+10307 3238 Star
+10307 3203 Star
+10307 3168 Star
+10307 3133 Star
+10307 3098 Star
+10307 3063 Star
+10307 3028 Star
+10307 2993 Star
+10307 2958 Star
+10307 2923 Star
+10307 2888 Star
+10307 2853 Star
+10307 2818 Star
+10307 2783 Star
+10307 2748 Star
+10307 2713 Star
+10307 2678 Star
+10307 2643 Star
+10307 2608 Star
+10307 2573 Star
+10307 2538 Star
+10307 2503 Star
+10307 2468 Star
+10307 2433 Star
+10307 2398 Star
+10307 2363 Star
+10307 2328 Star
+10307 2293 Star
+10307 2258 Star
+10307 2223 Star
+10307 2188 Star
+10307 2153 Star
+10307 2118 Star
+10307 2083 Star
+10307 2048 Star
+10307 2013 Star
+10307 1978 Star
+10307 1943 Star
+10307 1908 Star
+10307 1873 Star
+10307 1838 Star
+10307 1803 Star
+10307 1768 Star
+10307 1733 Star
+10307 1698 Star
+10307 1663 Star
+10307 1628 Star
+10307 1593 Star
+10307 1558 Star
+10307 1523 Star
+10307 1488 Star
+10307 1453 Star
+10307 1418 Star
+10307 1383 Star
+10307 1348 Star
+10307 1313 Star
+10307 1278 Star
+10307 1243 Star
+10307 1208 Star
+10307 1173 Star
+10307 1138 Star
+10307 1103 Star
+10307 1068 Star
+10307 1033 Star
+10307 998 Star
+10352 4462 Star
+10352 4428 Star
+10352 4393 Star
+10352 4358 Star
+10352 4323 Star
+10352 4288 Star
+10352 4253 Star
+10352 4218 Star
+10352 4183 Star
+10352 4148 Star
+10352 4113 Star
+10352 4078 Star
+10352 4043 Star
+10352 4008 Star
+10352 3973 Star
+10352 3938 Star
+10352 3903 Star
+10352 3868 Star
+10352 3833 Star
+10352 3798 Star
+10352 3763 Star
+10352 3728 Star
+10352 3693 Star
+10352 3658 Star
+10352 3623 Star
+10352 3588 Star
+10352 3553 Star
+10352 3518 Star
+10352 3483 Star
+10352 3448 Star
+10352 3413 Star
+10352 3378 Star
+10352 3343 Star
+10352 3308 Star
+10352 3273 Star
+10352 3238 Star
+10352 3203 Star
+10352 3168 Star
+10352 3133 Star
+10352 3098 Star
+10352 3063 Star
+10352 3028 Star
+10352 2993 Star
+10352 2958 Star
+10352 2923 Star
+10352 2888 Star
+10352 2853 Star
+10352 2818 Star
+10352 2783 Star
+10352 2748 Star
+10352 2713 Star
+10352 2678 Star
+10352 2643 Star
+10352 2608 Star
+10352 2573 Star
+10352 2538 Star
+10352 2503 Star
+10352 2468 Star
+10352 2433 Star
+10352 2398 Star
+10352 2363 Star
+10352 2328 Star
+10352 2293 Star
+10352 2258 Star
+10352 2223 Star
+10352 2188 Star
+10352 2153 Star
+10352 2118 Star
+10352 2083 Star
+10352 2048 Star
+10352 2013 Star
+10352 1978 Star
+10352 1943 Star
+10352 1908 Star
+10352 1873 Star
+10352 1838 Star
+10352 1803 Star
+10352 1768 Star
+10352 1733 Star
+10352 1698 Star
+10352 1663 Star
+10352 1628 Star
+10352 1593 Star
+10352 1558 Star
+10352 1523 Star
+10352 1488 Star
+10352 1453 Star
+10352 1418 Star
+10352 1383 Star
+10352 1348 Star
+10352 1313 Star
+10352 1278 Star
+10352 1243 Star
+10352 1208 Star
+10352 1173 Star
+10352 1138 Star
+10352 1103 Star
+10352 1068 Star
+10352 1033 Star
+10352 998 Star
+10352 963 Star
+% End plot #1
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/spchol.pdf b/doc/interpreter/spchol.pdf
new file mode 100644
index 0000000..d3eac1d
Binary files /dev/null and b/doc/interpreter/spchol.pdf differ
diff --git a/doc/interpreter/spchol.png b/doc/interpreter/spchol.png
new file mode 100644
index 0000000..016b8da
Binary files /dev/null and b/doc/interpreter/spchol.png differ
diff --git a/doc/interpreter/spchol.txt b/doc/interpreter/spchol.txt
new file mode 100644
index 0000000..5d9b563
--- /dev/null
+++ b/doc/interpreter/spchol.txt
@@ -0,0 +1,18 @@
+
+            |  * *                          
+            |    * * *                      
+            |      * * * *                  
+            |        * * * * *              
+          5 -          * * * * * *          
+            |            * * * * * * *      
+            |              * * * * * * * *  
+            |                * * * * * * * *
+            |                  * * * * * * *
+         10 -                    * * * * * *
+            |                      * * * * *
+            |                        * * * *
+            |                          * * *
+            |                            * *
+         15 -                              *
+            |----------|---------|---------|
+                       5        10        15
\ No newline at end of file
diff --git a/doc/interpreter/spcholperm.eps b/doc/interpreter/spcholperm.eps
new file mode 100644
index 0000000..6fe3ec5
--- /dev/null
+++ b/doc/interpreter/spcholperm.eps
@@ -0,0 +1,1078 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: spcholperm.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:46:57 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (spcholperm.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:46:57 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6212 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6212 M
+[ [(Helvetica) 120.0 0.0 true true 0 (50)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4462 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4462 M
+[ [(Helvetica) 120.0 0.0 true true 0 (100)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2713 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2713 M
+[ [(Helvetica) 120.0 0.0 true true 0 (150)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 963 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 963 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3694 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3694 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (50)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5913 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5913 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (100)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8132 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8132 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (150)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10352 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10352 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+2.000 UP
+0.500 UL
+LT0
+0.00 0.00 1.00 C 1519 7927 Star
+1564 7892 Star
+1608 7927 Star
+1608 7892 Star
+1608 7857 Star
+1653 7822 Star
+1697 7787 Star
+1741 7822 Star
+1741 7787 Star
+1741 7752 Star
+1786 7857 Star
+1786 7752 Star
+1786 7717 Star
+1830 7682 Star
+1874 7647 Star
+1919 7682 Star
+1919 7647 Star
+1919 7612 Star
+1963 7577 Star
+2008 7542 Star
+2052 7577 Star
+2052 7542 Star
+2052 7507 Star
+2096 7612 Star
+2096 7507 Star
+2096 7472 Star
+2141 7717 Star
+2141 7472 Star
+2141 7437 Star
+2185 7402 Star
+2230 7367 Star
+2274 7402 Star
+2274 7367 Star
+2274 7332 Star
+2318 7297 Star
+2363 7262 Star
+2407 7297 Star
+2407 7262 Star
+2407 7227 Star
+2451 7332 Star
+2451 7227 Star
+2451 7192 Star
+2496 7157 Star
+2540 7122 Star
+2585 7157 Star
+2585 7122 Star
+2585 7087 Star
+2629 7052 Star
+2673 7017 Star
+2718 7052 Star
+2718 7017 Star
+2718 6982 Star
+2762 7087 Star
+2762 6982 Star
+2762 6947 Star
+2806 7192 Star
+2806 6947 Star
+2806 6912 Star
+2851 7437 Star
+2851 6912 Star
+2851 6877 Star
+2895 6842 Star
+2940 6807 Star
+2984 6842 Star
+2984 6807 Star
+2984 6772 Star
+3028 6737 Star
+3073 6702 Star
+3117 6737 Star
+3117 6702 Star
+3117 6667 Star
+3162 6772 Star
+3162 6667 Star
+3162 6632 Star
+3206 6597 Star
+3250 6562 Star
+3295 6597 Star
+3295 6562 Star
+3295 6527 Star
+3339 6492 Star
+3383 6457 Star
+3428 6492 Star
+3428 6457 Star
+3428 6422 Star
+3472 6527 Star
+3472 6422 Star
+3472 6387 Star
+3517 6632 Star
+3517 6387 Star
+3517 6352 Star
+3561 6317 Star
+3605 6282 Star
+3650 6317 Star
+3650 6282 Star
+3650 6247 Star
+3694 6212 Star
+3739 6177 Star
+3783 6212 Star
+3783 6177 Star
+3783 6142 Star
+3827 6247 Star
+3827 6142 Star
+3827 6107 Star
+3872 6072 Star
+3916 6037 Star
+3960 6072 Star
+3960 6037 Star
+3960 6002 Star
+4005 5967 Star
+4049 5932 Star
+4094 5967 Star
+4094 5932 Star
+4094 5897 Star
+4138 6002 Star
+4138 5897 Star
+4138 5862 Star
+4182 6107 Star
+4182 5862 Star
+4182 5827 Star
+4227 6352 Star
+4227 5827 Star
+4227 5792 Star
+4271 6877 Star
+4271 5792 Star
+4271 5757 Star
+4316 5722 Star
+4360 5687 Star
+4404 5722 Star
+4404 5687 Star
+4404 5652 Star
+4449 5617 Star
+4493 5582 Star
+4537 5617 Star
+4537 5582 Star
+4537 5547 Star
+4582 5652 Star
+4582 5547 Star
+4582 5512 Star
+4626 5477 Star
+4671 5442 Star
+4715 5477 Star
+4715 5442 Star
+4715 5407 Star
+4759 5372 Star
+4804 5337 Star
+4848 5372 Star
+4848 5337 Star
+4848 5302 Star
+4892 5407 Star
+4892 5302 Star
+4892 5267 Star
+4937 5512 Star
+4937 5267 Star
+4937 5232 Star
+4981 5197 Star
+5026 5162 Star
+5070 5197 Star
+5070 5162 Star
+5070 5127 Star
+5114 5092 Star
+5159 5057 Star
+5203 5092 Star
+5203 5057 Star
+5203 5022 Star
+5248 5127 Star
+5248 5022 Star
+5248 4987 Star
+5292 4952 Star
+5336 4917 Star
+5381 4952 Star
+5381 4917 Star
+5381 4882 Star
+5425 4847 Star
+5469 4812 Star
+5514 4847 Star
+5514 4812 Star
+5514 4777 Star
+5558 4882 Star
+5558 4777 Star
+5558 4742 Star
+5603 4987 Star
+5603 4742 Star
+5603 4707 Star
+5647 5232 Star
+5647 4707 Star
+5647 4672 Star
+5691 4637 Star
+5736 4602 Star
+5780 4637 Star
+5780 4602 Star
+5780 4567 Star
+5825 4532 Star
+5869 4497 Star
+5913 4532 Star
+5913 4497 Star
+5913 4462 Star
+5958 4567 Star
+5958 4462 Star
+5958 4428 Star
+6002 4393 Star
+6046 4358 Star
+6091 4393 Star
+6091 4358 Star
+6091 4323 Star
+6135 4288 Star
+6180 4253 Star
+6224 4288 Star
+6224 4253 Star
+6224 4218 Star
+6268 4323 Star
+6268 4218 Star
+6268 4183 Star
+6313 4428 Star
+6313 4183 Star
+6313 4148 Star
+6357 4113 Star
+6402 4078 Star
+6446 4113 Star
+6446 4078 Star
+6446 4043 Star
+6490 4008 Star
+6535 3973 Star
+6579 4008 Star
+6579 3973 Star
+6579 3938 Star
+6623 4043 Star
+6623 3938 Star
+6623 3903 Star
+6668 3868 Star
+6712 3833 Star
+6757 3868 Star
+6757 3833 Star
+6757 3798 Star
+6801 3763 Star
+6845 3728 Star
+6890 3763 Star
+6890 3728 Star
+6890 3693 Star
+6934 3798 Star
+6934 3693 Star
+6934 3658 Star
+6979 3903 Star
+6979 3658 Star
+6979 3623 Star
+7023 4148 Star
+7023 3623 Star
+7023 3588 Star
+7067 4672 Star
+7067 3588 Star
+7067 3553 Star
+7112 5757 Star
+7112 3553 Star
+7112 3518 Star
+7156 3483 Star
+7200 3448 Star
+7245 3483 Star
+7245 3448 Star
+7245 3413 Star
+7289 3378 Star
+7334 3343 Star
+7378 3378 Star
+7378 3343 Star
+7378 3308 Star
+7422 3413 Star
+7422 3308 Star
+7422 3273 Star
+7467 3238 Star
+7511 3203 Star
+7555 3238 Star
+7555 3203 Star
+7555 3168 Star
+7600 3133 Star
+7644 3098 Star
+7689 3133 Star
+7689 3098 Star
+7689 3063 Star
+7733 3168 Star
+7733 3063 Star
+7733 3028 Star
+7777 3273 Star
+7777 3028 Star
+7777 2993 Star
+7822 2958 Star
+7866 2923 Star
+7911 2958 Star
+7911 2923 Star
+7911 2888 Star
+7955 2853 Star
+7999 2818 Star
+8044 2853 Star
+8044 2818 Star
+8044 2783 Star
+8088 2888 Star
+8088 2783 Star
+8088 2748 Star
+8132 2713 Star
+8177 2678 Star
+8221 2713 Star
+8221 2678 Star
+8221 2643 Star
+8266 2608 Star
+8310 2573 Star
+8354 2608 Star
+8354 2573 Star
+8354 2538 Star
+8399 2643 Star
+8399 2538 Star
+8399 2503 Star
+8443 2748 Star
+8443 2503 Star
+8443 2468 Star
+8488 2993 Star
+8488 2468 Star
+8488 2433 Star
+8532 2398 Star
+8576 2363 Star
+8621 2398 Star
+8621 2363 Star
+8621 2328 Star
+8665 2293 Star
+8709 2258 Star
+8754 2293 Star
+8754 2258 Star
+8754 2223 Star
+8798 2328 Star
+8798 2223 Star
+8798 2188 Star
+8843 2153 Star
+8887 2118 Star
+8931 2153 Star
+8931 2118 Star
+8931 2083 Star
+8976 2048 Star
+9020 2013 Star
+9065 2048 Star
+9065 2013 Star
+9065 1978 Star
+9109 2083 Star
+9109 1978 Star
+9109 1943 Star
+9153 2188 Star
+9153 1943 Star
+9153 1908 Star
+9198 1873 Star
+9242 1838 Star
+9286 1873 Star
+9286 1838 Star
+9286 1803 Star
+9331 1768 Star
+9375 1733 Star
+9420 1768 Star
+9420 1733 Star
+9420 1698 Star
+9464 1803 Star
+9464 1698 Star
+9464 1663 Star
+9508 1628 Star
+9553 1593 Star
+9597 1628 Star
+9597 1593 Star
+9597 1558 Star
+9641 1523 Star
+9686 1488 Star
+9730 1523 Star
+9730 1488 Star
+9730 1453 Star
+9775 1558 Star
+9775 1453 Star
+9775 1418 Star
+9819 1663 Star
+9819 1418 Star
+9819 1383 Star
+9863 1348 Star
+9908 1313 Star
+9952 1348 Star
+9952 1313 Star
+9952 1278 Star
+9997 1243 Star
+10041 1208 Star
+10085 1243 Star
+10085 1208 Star
+10085 1173 Star
+10130 1278 Star
+10130 1173 Star
+10130 1138 Star
+10174 1383 Star
+10174 1138 Star
+10174 1103 Star
+10218 1908 Star
+10218 1103 Star
+10218 1068 Star
+10263 2433 Star
+10263 1068 Star
+10263 1033 Star
+10307 998 Star
+10352 3518 Star
+10352 1033 Star
+10352 998 Star
+10352 963 Star
+% End plot #1
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/spcholperm.pdf b/doc/interpreter/spcholperm.pdf
new file mode 100644
index 0000000..febee63
Binary files /dev/null and b/doc/interpreter/spcholperm.pdf differ
diff --git a/doc/interpreter/spcholperm.png b/doc/interpreter/spcholperm.png
new file mode 100644
index 0000000..612a86f
Binary files /dev/null and b/doc/interpreter/spcholperm.png differ
diff --git a/doc/interpreter/spcholperm.txt b/doc/interpreter/spcholperm.txt
new file mode 100644
index 0000000..67f8500
--- /dev/null
+++ b/doc/interpreter/spcholperm.txt
@@ -0,0 +1,18 @@
+
+            |  * *                          
+            |    *       *                  
+            |      *   *                    
+            |        * *                    
+          5 -          * *                  
+            |            *                 *
+            |              *   *            
+            |                * *            
+            |                  *       *    
+         10 -                    *   *      
+            |                      * *      
+            |                        * *    
+            |                          *   *
+            |                            * *
+         15 -                              *
+            |----------|---------|---------|
+                       5        10        15
\ No newline at end of file
diff --git a/doc/interpreter/spmatrix.eps b/doc/interpreter/spmatrix.eps
new file mode 100644
index 0000000..5839631
--- /dev/null
+++ b/doc/interpreter/spmatrix.eps
@@ -0,0 +1,1277 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: spmatrix.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:46:56 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (spmatrix.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:46:56 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6212 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6212 M
+[ [(Helvetica) 120.0 0.0 true true 0 (50)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 4462 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 4462 M
+[ [(Helvetica) 120.0 0.0 true true 0 (100)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2713 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2713 M
+[ [(Helvetica) 120.0 0.0 true true 0 (150)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 963 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 963 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3694 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3694 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (50)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5913 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5913 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (100)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8132 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8132 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (150)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10352 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10352 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (200)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+2.000 UP
+0.500 UL
+LT0
+0.00 0.00 1.00 C 1519 7927 Star
+1519 7892 Star
+1564 7927 Star
+1564 7892 Star
+1564 7857 Star
+1564 7822 Star
+1608 7892 Star
+1608 7857 Star
+1608 7787 Star
+1608 7752 Star
+1653 7892 Star
+1653 7822 Star
+1653 7717 Star
+1653 7682 Star
+1697 7857 Star
+1697 7787 Star
+1697 7647 Star
+1697 7612 Star
+1741 7857 Star
+1741 7752 Star
+1741 7577 Star
+1741 7542 Star
+1786 7822 Star
+1786 7717 Star
+1786 7507 Star
+1786 7472 Star
+1830 7822 Star
+1830 7682 Star
+1830 7437 Star
+1830 7402 Star
+1874 7787 Star
+1874 7647 Star
+1874 7367 Star
+1874 7332 Star
+1919 7787 Star
+1919 7612 Star
+1919 7297 Star
+1919 7262 Star
+1963 7752 Star
+1963 7577 Star
+1963 7227 Star
+1963 7192 Star
+2008 7752 Star
+2008 7542 Star
+2008 7157 Star
+2008 7122 Star
+2052 7717 Star
+2052 7507 Star
+2052 7087 Star
+2052 7052 Star
+2096 7717 Star
+2096 7472 Star
+2096 7017 Star
+2096 6982 Star
+2141 7682 Star
+2141 7437 Star
+2141 6947 Star
+2141 6912 Star
+2185 7682 Star
+2185 7402 Star
+2185 6877 Star
+2185 6842 Star
+2230 7647 Star
+2230 7367 Star
+2230 6807 Star
+2230 6772 Star
+2274 7647 Star
+2274 7332 Star
+2274 6737 Star
+2274 6702 Star
+2318 7612 Star
+2318 7297 Star
+2318 6667 Star
+2318 6632 Star
+2363 7612 Star
+2363 7262 Star
+2363 6597 Star
+2363 6562 Star
+2407 7577 Star
+2407 7227 Star
+2407 6527 Star
+2407 6492 Star
+2451 7577 Star
+2451 7192 Star
+2451 6457 Star
+2451 6422 Star
+2496 7542 Star
+2496 7157 Star
+2496 6387 Star
+2496 6352 Star
+2540 7542 Star
+2540 7122 Star
+2540 6317 Star
+2540 6282 Star
+2585 7507 Star
+2585 7087 Star
+2585 6247 Star
+2585 6212 Star
+2629 7507 Star
+2629 7052 Star
+2629 6177 Star
+2629 6142 Star
+2673 7472 Star
+2673 7017 Star
+2673 6107 Star
+2673 6072 Star
+2718 7472 Star
+2718 6982 Star
+2718 6037 Star
+2718 6002 Star
+2762 7437 Star
+2762 6947 Star
+2762 5967 Star
+2762 5932 Star
+2806 7437 Star
+2806 6912 Star
+2806 5897 Star
+2806 5862 Star
+2851 7402 Star
+2851 6877 Star
+2851 5827 Star
+2851 5792 Star
+2895 7402 Star
+2895 6842 Star
+2895 5757 Star
+2895 5722 Star
+2940 7367 Star
+2940 6807 Star
+2940 5687 Star
+2940 5652 Star
+2984 7367 Star
+2984 6772 Star
+2984 5617 Star
+2984 5582 Star
+3028 7332 Star
+3028 6737 Star
+3028 5547 Star
+3028 5512 Star
+3073 7332 Star
+3073 6702 Star
+3073 5477 Star
+3073 5442 Star
+3117 7297 Star
+3117 6667 Star
+3117 5407 Star
+3117 5372 Star
+3162 7297 Star
+3162 6632 Star
+3162 5337 Star
+3162 5302 Star
+3206 7262 Star
+3206 6597 Star
+3206 5267 Star
+3206 5232 Star
+3250 7262 Star
+3250 6562 Star
+3250 5197 Star
+3250 5162 Star
+3295 7227 Star
+3295 6527 Star
+3295 5127 Star
+3295 5092 Star
+3339 7227 Star
+3339 6492 Star
+3339 5057 Star
+3339 5022 Star
+3383 7192 Star
+3383 6457 Star
+3383 4987 Star
+3383 4952 Star
+3428 7192 Star
+3428 6422 Star
+3428 4917 Star
+3428 4882 Star
+3472 7157 Star
+3472 6387 Star
+3472 4847 Star
+3472 4812 Star
+3517 7157 Star
+3517 6352 Star
+3517 4777 Star
+3517 4742 Star
+3561 7122 Star
+3561 6317 Star
+3561 4707 Star
+3561 4672 Star
+3605 7122 Star
+3605 6282 Star
+3605 4637 Star
+3605 4602 Star
+3650 7087 Star
+3650 6247 Star
+3650 4567 Star
+3650 4532 Star
+3694 7087 Star
+3694 6212 Star
+3694 4497 Star
+3694 4462 Star
+3739 7052 Star
+3739 6177 Star
+3739 4428 Star
+3739 4393 Star
+3783 7052 Star
+3783 6142 Star
+3783 4358 Star
+3783 4323 Star
+3827 7017 Star
+3827 6107 Star
+3827 4288 Star
+3827 4253 Star
+3872 7017 Star
+3872 6072 Star
+3872 4218 Star
+3872 4183 Star
+3916 6982 Star
+3916 6037 Star
+3916 4148 Star
+3916 4113 Star
+3960 6982 Star
+3960 6002 Star
+3960 4078 Star
+3960 4043 Star
+4005 6947 Star
+4005 5967 Star
+4005 4008 Star
+4005 3973 Star
+4049 6947 Star
+4049 5932 Star
+4049 3938 Star
+4049 3903 Star
+4094 6912 Star
+4094 5897 Star
+4094 3868 Star
+4094 3833 Star
+4138 6912 Star
+4138 5862 Star
+4138 3798 Star
+4138 3763 Star
+4182 6877 Star
+4182 5827 Star
+4182 3728 Star
+4182 3693 Star
+4227 6877 Star
+4227 5792 Star
+4227 3658 Star
+4227 3623 Star
+4271 6842 Star
+4271 5757 Star
+4271 3588 Star
+4271 3553 Star
+4316 6842 Star
+4316 5722 Star
+4316 3518 Star
+4316 3483 Star
+4360 6807 Star
+4360 5687 Star
+4360 3448 Star
+4360 3413 Star
+4404 6807 Star
+4404 5652 Star
+4404 3378 Star
+4404 3343 Star
+4449 6772 Star
+4449 5617 Star
+4449 3308 Star
+4449 3273 Star
+4493 6772 Star
+4493 5582 Star
+4493 3238 Star
+4493 3203 Star
+4537 6737 Star
+4537 5547 Star
+4537 3168 Star
+4537 3133 Star
+4582 6737 Star
+4582 5512 Star
+4582 3098 Star
+4582 3063 Star
+4626 6702 Star
+4626 5477 Star
+4626 3028 Star
+4626 2993 Star
+4671 6702 Star
+4671 5442 Star
+4671 2958 Star
+4671 2923 Star
+4715 6667 Star
+4715 5407 Star
+4715 2888 Star
+4715 2853 Star
+4759 6667 Star
+4759 5372 Star
+4759 2818 Star
+4759 2783 Star
+4804 6632 Star
+4804 5337 Star
+4804 2748 Star
+4804 2713 Star
+4848 6632 Star
+4848 5302 Star
+4848 2678 Star
+4848 2643 Star
+4892 6597 Star
+4892 5267 Star
+4892 2608 Star
+4892 2573 Star
+4937 6597 Star
+4937 5232 Star
+4937 2538 Star
+4937 2503 Star
+4981 6562 Star
+4981 5197 Star
+4981 2468 Star
+4981 2433 Star
+5026 6562 Star
+5026 5162 Star
+5026 2398 Star
+5026 2363 Star
+5070 6527 Star
+5070 5127 Star
+5070 2328 Star
+5070 2293 Star
+5114 6527 Star
+5114 5092 Star
+5114 2258 Star
+5114 2223 Star
+5159 6492 Star
+5159 5057 Star
+5159 2188 Star
+5159 2153 Star
+5203 6492 Star
+5203 5022 Star
+5203 2118 Star
+5203 2083 Star
+5248 6457 Star
+5248 4987 Star
+5248 2048 Star
+5248 2013 Star
+5292 6457 Star
+5292 4952 Star
+5292 1978 Star
+5292 1943 Star
+5336 6422 Star
+5336 4917 Star
+5336 1908 Star
+5336 1873 Star
+5381 6422 Star
+5381 4882 Star
+5381 1838 Star
+5381 1803 Star
+5425 6387 Star
+5425 4847 Star
+5425 1768 Star
+5425 1733 Star
+5469 6387 Star
+5469 4812 Star
+5469 1698 Star
+5469 1663 Star
+5514 6352 Star
+5514 4777 Star
+5514 1628 Star
+5514 1593 Star
+5558 6352 Star
+5558 4742 Star
+5558 1558 Star
+5558 1523 Star
+5603 6317 Star
+5603 4707 Star
+5603 1488 Star
+5603 1453 Star
+5647 6317 Star
+5647 4672 Star
+5647 1418 Star
+5647 1383 Star
+5691 6282 Star
+5691 4637 Star
+5691 1348 Star
+5691 1313 Star
+5736 6282 Star
+5736 4602 Star
+5736 1278 Star
+5736 1243 Star
+5780 6247 Star
+5780 4567 Star
+5780 1208 Star
+5780 1173 Star
+5825 6247 Star
+5825 4532 Star
+5825 1138 Star
+5825 1103 Star
+5869 6212 Star
+5869 4497 Star
+5869 1068 Star
+5869 1033 Star
+5913 6212 Star
+5913 4462 Star
+5913 998 Star
+5913 963 Star
+5958 6177 Star
+5958 4428 Star
+6002 6177 Star
+6002 4393 Star
+6046 6142 Star
+6046 4358 Star
+6091 6142 Star
+6091 4323 Star
+6135 6107 Star
+6135 4288 Star
+6180 6107 Star
+6180 4253 Star
+6224 6072 Star
+6224 4218 Star
+6268 6072 Star
+6268 4183 Star
+6313 6037 Star
+6313 4148 Star
+6357 6037 Star
+6357 4113 Star
+6402 6002 Star
+6402 4078 Star
+6446 6002 Star
+6446 4043 Star
+6490 5967 Star
+6490 4008 Star
+6535 5967 Star
+6535 3973 Star
+6579 5932 Star
+6579 3938 Star
+6623 5932 Star
+6623 3903 Star
+6668 5897 Star
+6668 3868 Star
+6712 5897 Star
+6712 3833 Star
+6757 5862 Star
+6757 3798 Star
+6801 5862 Star
+6801 3763 Star
+6845 5827 Star
+6845 3728 Star
+6890 5827 Star
+6890 3693 Star
+6934 5792 Star
+6934 3658 Star
+6979 5792 Star
+6979 3623 Star
+7023 5757 Star
+7023 3588 Star
+7067 5757 Star
+7067 3553 Star
+7112 5722 Star
+7112 3518 Star
+7156 5722 Star
+7156 3483 Star
+7200 5687 Star
+7200 3448 Star
+7245 5687 Star
+7245 3413 Star
+7289 5652 Star
+7289 3378 Star
+7334 5652 Star
+7334 3343 Star
+7378 5617 Star
+7378 3308 Star
+7422 5617 Star
+7422 3273 Star
+7467 5582 Star
+7467 3238 Star
+7511 5582 Star
+7511 3203 Star
+7555 5547 Star
+7555 3168 Star
+7600 5547 Star
+7600 3133 Star
+7644 5512 Star
+7644 3098 Star
+7689 5512 Star
+7689 3063 Star
+7733 5477 Star
+7733 3028 Star
+7777 5477 Star
+7777 2993 Star
+7822 5442 Star
+7822 2958 Star
+7866 5442 Star
+7866 2923 Star
+7911 5407 Star
+7911 2888 Star
+7955 5407 Star
+7955 2853 Star
+7999 5372 Star
+7999 2818 Star
+8044 5372 Star
+8044 2783 Star
+8088 5337 Star
+8088 2748 Star
+8132 5337 Star
+8132 2713 Star
+8177 5302 Star
+8177 2678 Star
+8221 5302 Star
+8221 2643 Star
+8266 5267 Star
+8266 2608 Star
+8310 5267 Star
+8310 2573 Star
+8354 5232 Star
+8354 2538 Star
+8399 5232 Star
+8399 2503 Star
+8443 5197 Star
+8443 2468 Star
+8488 5197 Star
+8488 2433 Star
+8532 5162 Star
+8532 2398 Star
+8576 5162 Star
+8576 2363 Star
+8621 5127 Star
+8621 2328 Star
+8665 5127 Star
+8665 2293 Star
+8709 5092 Star
+8709 2258 Star
+8754 5092 Star
+8754 2223 Star
+8798 5057 Star
+8798 2188 Star
+8843 5057 Star
+8843 2153 Star
+8887 5022 Star
+8887 2118 Star
+8931 5022 Star
+8931 2083 Star
+8976 4987 Star
+8976 2048 Star
+9020 4987 Star
+9020 2013 Star
+9065 4952 Star
+9065 1978 Star
+9109 4952 Star
+9109 1943 Star
+9153 4917 Star
+9153 1908 Star
+9198 4917 Star
+9198 1873 Star
+9242 4882 Star
+9242 1838 Star
+9286 4882 Star
+9286 1803 Star
+9331 4847 Star
+9331 1768 Star
+9375 4847 Star
+9375 1733 Star
+9420 4812 Star
+9420 1698 Star
+9464 4812 Star
+9464 1663 Star
+9508 4777 Star
+9508 1628 Star
+9553 4777 Star
+9553 1593 Star
+9597 4742 Star
+9597 1558 Star
+9641 4742 Star
+9641 1523 Star
+9686 4707 Star
+9686 1488 Star
+9730 4707 Star
+9730 1453 Star
+9775 4672 Star
+9775 1418 Star
+9819 4672 Star
+9819 1383 Star
+9863 4637 Star
+9863 1348 Star
+9908 4637 Star
+9908 1313 Star
+9952 4602 Star
+9952 1278 Star
+9997 4602 Star
+9997 1243 Star
+10041 4567 Star
+10041 1208 Star
+10085 4567 Star
+10085 1173 Star
+10130 4532 Star
+10130 1138 Star
+10174 4532 Star
+10174 1103 Star
+10218 4497 Star
+10218 1068 Star
+10263 4497 Star
+10263 1033 Star
+10307 4462 Star
+10307 998 Star
+10352 4462 Star
+10352 963 Star
+% End plot #1
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/spmatrix.pdf b/doc/interpreter/spmatrix.pdf
new file mode 100644
index 0000000..c49bb44
Binary files /dev/null and b/doc/interpreter/spmatrix.pdf differ
diff --git a/doc/interpreter/spmatrix.png b/doc/interpreter/spmatrix.png
new file mode 100644
index 0000000..2b7a325
Binary files /dev/null and b/doc/interpreter/spmatrix.png differ
diff --git a/doc/interpreter/spmatrix.txt b/doc/interpreter/spmatrix.txt
new file mode 100644
index 0000000..5632b8b
--- /dev/null
+++ b/doc/interpreter/spmatrix.txt
@@ -0,0 +1,18 @@
+
+            |  * *                          
+            |  * * * *                      
+            |    * *   * *                  
+            |    *   *     * *              
+          5 -      *   *       * *          
+            |      *     *         * *      
+            |        *     *           * *  
+            |        *       *             *
+            |          *       *            
+         10 -          *         *          
+            |            *         *        
+            |            *           *      
+            |              *           *    
+            |              *             *  
+         15 -                *             *
+            |----------|---------|---------|
+                       5        10        15
\ No newline at end of file
diff --git a/doc/interpreter/stats.texi b/doc/interpreter/stats.texi
new file mode 100644
index 0000000..365b6cf
--- /dev/null
+++ b/doc/interpreter/stats.texi
@@ -0,0 +1,2771 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+ at c               2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Statistics
+ at chapter Statistics
+
+Octave has support for various statistical methods.  This includes
+basic descriptive statistics, statistical tests, random number generation,
+and much more.
+
+The functions that analyze data all assume that multidimensional data
+is arranged in a matrix where each row is an observation, and each
+column is a variable.  So, the matrix defined by
+
+ at example
+ at group
+a = [ 0.9, 0.7;
+      0.1, 0.1;
+      0.5, 0.4 ];
+ at end group
+ at end example
+
+ at noindent
+contains three observations from a two-dimensional distribution.
+While this is the default data arrangement, most functions support
+different arrangements.
+
+It should be noted that the statistics functions don't test for data
+containing NaN, NA, or Inf.  Such values need to be handled explicitly.
+
+ at menu
+* Descriptive Statistics::
+* Basic Statistical Functions:: 
+* Statistical Plots:: 
+* Tests::                       
+* Models::                      
+* Distributions::     
+* Random Number Generation::          
+ at end menu
+
+ at node Descriptive Statistics
+ at section Descriptive Statistics
+
+Octave can compute various statistics such as the moments of a data set.
+
+ at c ./statistics/base/mean.m
+ at anchor{doc-mean}
+ at deftypefn {Function File} {} mean (@var{x}, @var{dim}, @var{opt})
+If @var{x} is a vector, compute the mean of the elements of @var{x}
+ at tex
+$$ {\rm mean}(x) = \bar{x} = {1\over N} \sum_{i=1}^N x_i $$
+ at end tex
+ at ifnottex
+
+ at example
+mean (x) = SUM_i x(i) / N
+ at end example
+ at end ifnottex
+If @var{x} is a matrix, compute the mean for each column and return them
+in a row vector.
+
+With the optional argument @var{opt}, the kind of mean computed can be
+selected.  The following options are recognized:
+
+ at table @code
+ at item "a"
+Compute the (ordinary) arithmetic mean.  This is the default.
+
+ at item "g"
+Compute the geometric mean.
+
+ at item "h"
+Compute the harmonic mean.
+ at end table
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.
+
+Both @var{dim} and @var{opt} are optional.  If both are supplied,
+either may appear first.
+ at end deftypefn
+
+
+ at c ./statistics/base/median.m
+ at anchor{doc-median}
+ at deftypefn {Function File} {} median (@var{x}, @var{dim})
+If @var{x} is a vector, compute the median value of the elements of
+ at var{x}.  If the elements of @var{x} are sorted, the median is defined
+as
+ at tex
+$$
+{\rm median} (x) =
+  \cases{x(\lceil N/2\rceil), & $N$ odd;\cr
+          (x(N/2)+x(N/2+1))/2, & $N$ even.}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+            x(ceil(N/2)),             N odd
+median(x) =
+            (x(N/2) + x((N/2)+1))/2,  N even
+ at end group
+ at end example
+ at end ifnottex
+If @var{x} is a matrix, compute the median value for each
+column and return them in a row vector.  If the optional @var{dim}
+argument is given, operate along this dimension.
+ at seealso{@ref{doc-std,,std}, @ref{doc-mean,,mean}}
+ at end deftypefn
+
+
+ at c ./statistics/base/quantile.m
+ at anchor{doc-quantile}
+ at deftypefn {Function File} {@var{q} =} quantile (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{q} =} quantile (@var{x}, @var{p}, @var{dim})
+ at deftypefnx {Function File} {@var{q} =} quantile (@var{x}, @var{p}, @var{dim}, @var{method})
+For a sample, @var{x}, calculate the quantiles, @var{q}, corresponding to
+the cumulative probability values in @var{p}.  All non-numeric values (NaNs) of
+ at var{x} are ignored.
+
+If @var{x} is a matrix, compute the quantiles for each column and
+return them in a matrix, such that the i-th row of @var{q} contains
+the @var{p}(i)th quantiles of each column of @var{x}.
+
+The optional argument @var{dim} determines the dimension along which 
+the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
+a vector or matrix, it defaults to 1 (column wise quantiles).  In the 
+instance that @var{x} is a N-d array, @var{dim} defaults to the first 
+dimension whose size greater than unity.
+
+The methods available to calculate sample quantiles are the nine methods
+used by R (http://www.r-project.org/).  The default value is METHOD = 5.
+
+Discontinuous sample quantile methods 1, 2, and 3
+
+ at enumerate 1
+ at item Method 1: Inverse of empirical distribution function.
+ at item Method 2: Similar to method 1 but with averaging at discontinuities.
+ at item Method 3: SAS definition: nearest even order statistic.
+ at end enumerate
+
+Continuous sample quantile methods 4 through 9, where p(k) is the linear
+interpolation function respecting each methods' representative cdf.
+
+ at enumerate 4
+ at item Method 4: p(k) = k / n. That is, linear interpolation of the empirical cdf.
+ at item Method 5: p(k) = (k - 0.5) / n. That is a piecewise linear function where 
+the knots are the values midway through the steps of the empirical cdf. 
+ at item Method 6: p(k) = k / (n + 1).
+ at item Method 7: p(k) = (k - 1) / (n - 1).
+ at item Method 8: p(k) = (k - 1/3) / (n + 1/3).  The resulting quantile estimates 
+are approximately median-unbiased regardless of the distribution of @var{x}.
+ at item Method 9: p(k) = (k - 3/8) / (n + 1/4).  The resulting quantile estimates 
+are approximately unbiased for the expected order statistics if @var{x} is 
+normally distributed.
+ at end enumerate
+
+Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R
+(versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS
+use method 6.  @sc{matlab} uses method 5.
+
+References:
+
+ at itemize @bullet
+ at item Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New
+S Language.  Wadsworth & Brooks/Cole.
+
+ at item Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in
+statistical packages, American Statistician, 50, 361--365.
+
+ at item R: A Language and Environment for Statistical Computing;
+ at url{http://cran.r-project.org/doc/manuals/fullrefman.pdf}.
+ at end itemize
+ at end deftypefn
+
+
+ at c ./statistics/base/prctile.m
+ at anchor{doc-prctile}
+ at deftypefn {Function File} {@var{y} =} prctile (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{q} =} prctile (@var{x}, @var{p}, @var{dim})
+For a sample @var{x}, compute the quantiles, @var{y}, corresponding
+to the cumulative probability values, P, in percent.  All non-numeric
+values (NaNs) of X are ignored.
+
+If @var{x} is a matrix, compute the percentiles for each column and
+return them in a matrix, such that the i-th row of @var{y} contains the 
+ at var{p}(i)th percentiles of each column of @var{x}.
+
+The optional argument @var{dim} determines the dimension along which
+the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
+a vector or matrix, it defaults to 1 (column wise quantiles).  In the 
+instance that @var{x} is a N-d array, @var{dim} defaults to the first 
+dimension whose size greater than unity.
+
+ at end deftypefn
+
+
+ at c ./statistics/base/meansq.m
+ at anchor{doc-meansq}
+ at deftypefn {Function File} {} meansq (@var{x})
+ at deftypefnx {Function File} {} meansq (@var{x}, @var{dim})
+For vector arguments, return the mean square of the values.
+For matrix arguments, return a row vector containing the mean square
+of each column.  With the optional @var{dim} argument, returns the
+mean squared of the values along this dimension.
+ at end deftypefn
+
+
+ at c ./statistics/base/std.m
+ at anchor{doc-std}
+ at deftypefn {Function File} {} std (@var{x})
+ at deftypefnx {Function File} {} std (@var{x}, @var{opt})
+ at deftypefnx {Function File} {} std (@var{x}, @var{opt}, @var{dim})
+If @var{x} is a vector, compute the standard deviation of the elements
+of @var{x}.
+ at tex
+$$
+{\rm std} (x) = \sigma (x) = \sqrt{{\sum_{i=1}^N (x_i - \bar{x})^2 \over N - 1}}
+$$
+where $\bar{x}$ is the mean value of $x$.
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+std (x) = sqrt (sumsq (x - mean (x)) / (n - 1))
+ at end group
+ at end example
+ at end ifnottex
+If @var{x} is a matrix, compute the standard deviation for
+each column and return them in a row vector.
+
+The argument @var{opt} determines the type of normalization to use.  Valid values
+are
+
+ at table @asis 
+ at item 0:
+  normalizes with @math{N-1}, provides the square root of best unbiased estimator of 
+  the variance [default]
+ at item 1:
+  normalizes with @math{N}, this provides the square root of the second moment around 
+  the mean
+ at end table
+
+The third argument @var{dim} determines the dimension along which the standard
+deviation is calculated.
+ at seealso{@ref{doc-mean,,mean}, @ref{doc-median,,median}}
+ at end deftypefn
+
+
+ at c ./statistics/base/var.m
+ at anchor{doc-var}
+ at deftypefn {Function File} {} var (@var{x})
+For vector arguments, return the (real) variance of the values.
+For matrix arguments, return a row vector containing the variance for
+each column.
+
+The argument @var{opt} determines the type of normalization to use.
+Valid values are
+
+ at table @asis 
+ at item 0:
+Normalizes with @math{N-1}, provides the best unbiased estimator of the
+variance [default].
+ at item 1:
+Normalizes with @math{N}, this provides the second moment around the mean.
+ at end table
+
+The third argument @var{dim} determines the dimension along which the 
+variance is calculated.
+ at end deftypefn
+
+
+ at c ./statistics/base/mode.m
+ at anchor{doc-mode}
+ at deftypefn {Function File} {[@var{m}, @var{f}, @var{c}] =} mode (@var{x}, @var{dim})
+Count the most frequently appearing value.  @code{mode} counts the 
+frequency along the first non-singleton dimension and if two or more
+values have the same frequency returns the smallest of the two in
+ at var{m}.  The dimension along which to count can be specified by the
+ at var{dim} parameter.
+
+The variable @var{f} counts the frequency of each of the most frequently 
+occurring elements.  The cell array @var{c} contains all of the elements
+with the maximum frequency .
+ at end deftypefn
+
+
+ at c ./statistics/base/cov.m
+ at anchor{doc-cov}
+ at deftypefn {Function File} {} cov (@var{x}, @var{y})
+Compute covariance.
+
+If each row of @var{x} and @var{y} is an observation and each column is
+a variable, the (@var{i}, @var{j})-th entry of
+ at code{cov (@var{x}, @var{y})} is the covariance between the @var{i}-th
+variable in @var{x} and the @var{j}-th variable in @var{y}.
+ at tex
+$$
+\sigma_{ij} = {1 \over N-1} \sum_{i=1}^N (x_i - \bar{x})(y_i - \bar{y})
+$$
+where $\bar{x}$ and $\bar{y}$ are the mean values of $x$ and $y$.
+ at end tex
+If called with one argument, compute @code{cov (@var{x}, @var{x})}.
+ at end deftypefn
+
+
+ at c ./statistics/base/cor.m
+ at anchor{doc-cor}
+ at deftypefn {Function File} {} cor (@var{x}, @var{y})
+Compute correlation.
+
+The (@var{i}, @var{j})-th entry of @code{cor (@var{x}, @var{y})} is
+the correlation between the @var{i}-th variable in @var{x} and the
+ at var{j}-th variable in @var{y}.
+
+ at tex
+$$
+{\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
+$$
+ at end tex
+ at ifnottex
+ at example
+corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+ at end example
+ at end ifnottex
+
+For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+ at code{cor (@var{x})} is equivalent to @code{cor (@var{x}, @var{x})}.
+
+Note that the @code{corrcoef} function does the same as @code{cor}.
+ at end deftypefn
+
+
+ at c ./statistics/base/corrcoef.m
+ at anchor{doc-corrcoef}
+ at deftypefn {Function File} {} corrcoef (@var{x}, @var{y})
+Compute correlation.
+
+If each row of @var{x} and @var{y} is an observation and each column is
+a variable, the (@var{i}, @var{j})-th entry of
+ at code{corrcoef (@var{x}, @var{y})} is the correlation between the
+ at var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}.
+
+ at tex
+$$
+{\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
+$$
+ at end tex
+ at ifnottex
+ at example
+corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+ at end example
+ at end ifnottex
+
+If called with one argument, compute @code{corrcoef (@var{x}, @var{x})}.
+ at end deftypefn
+
+
+ at c ./statistics/base/kurtosis.m
+ at anchor{doc-kurtosis}
+ at deftypefn {Function File} {} kurtosis (@var{x}, @var{dim})
+If @var{x} is a vector of length @math{N}, return the kurtosis
+ at tex
+$$
+ {\rm kurtosis} (x) = {1\over N \sigma(x)^4} \sum_{i=1}^N (x_i-\bar{x})^4 - 3
+$$
+where $\bar{x}$ is the mean value of $x$.
+ at end tex
+ at ifnottex
+
+ at example
+kurtosis (x) = N^(-1) std(x)^(-4) sum ((x - mean(x)).^4) - 3
+ at end example
+ at end ifnottex
+
+ at noindent
+of @var{x}.  If @var{x} is a matrix, return the kurtosis over the
+first non-singleton dimension.  The optional argument @var{dim}
+can be given to force the kurtosis to be given over that 
+dimension.
+ at end deftypefn
+
+
+ at c ./statistics/base/skewness.m
+ at anchor{doc-skewness}
+ at deftypefn {Function File} {} skewness (@var{x}, @var{dim})
+If @var{x} is a vector of length @math{n}, return the skewness
+ at tex
+$$
+{\rm skewness} (x) = {1\over N \sigma(x)^3} \sum_{i=1}^N (x_i-\bar{x})^3
+$$
+where $\bar{x}$ is the mean value of $x$.
+ at end tex
+ at ifnottex
+
+ at example
+skewness (x) = N^(-1) std(x)^(-3) sum ((x - mean(x)).^3)
+ at end example
+ at end ifnottex
+
+ at noindent
+of @var{x}.  If @var{x} is a matrix, return the skewness along the
+first non-singleton dimension of the matrix.  If the optional
+ at var{dim} argument is given, operate along this dimension.
+ at end deftypefn
+
+
+ at c ./statistics/base/statistics.m
+ at anchor{doc-statistics}
+ at deftypefn {Function File} {} statistics (@var{x})
+If @var{x} is a matrix, return a matrix with the minimum, first
+quartile, median, third quartile, maximum, mean, standard deviation,
+skewness and kurtosis of the columns of @var{x} as its columns.
+
+If @var{x} is a vector, calculate the statistics along the 
+non-singleton dimension.
+ at end deftypefn
+
+
+ at c ./statistics/base/moment.m
+ at anchor{doc-moment}
+ at deftypefn {Function File} {} moment (@var{x}, @var{p}, @var{opt}, @var{dim})
+If @var{x} is a vector, compute the @var{p}-th moment of @var{x}.
+
+If @var{x} is a matrix, return the row vector containing the
+ at var{p}-th moment of each column.
+
+With the optional string opt, the kind of moment to be computed can
+be specified.  If opt contains @code{"c"} or @code{"a"}, central
+and/or absolute moments are returned.  For example,
+
+ at example
+moment (x, 3, "ac")
+ at end example
+
+ at noindent
+computes the third central absolute moment of @var{x}.
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.
+ at end deftypefn
+
+
+ at node Basic Statistical Functions
+ at section Basic Statistical Functions
+
+Octave also supports various helpful statistical functions.
+
+ at c ./statistics/base/mahalanobis.m
+ at anchor{doc-mahalanobis}
+ at deftypefn {Function File} {} mahalanobis (@var{x}, @var{y})
+Return the Mahalanobis' D-square distance between the multivariate
+samples @var{x} and @var{y}, which must have the same number of
+components (columns), but may have a different number of observations
+(rows).
+ at end deftypefn
+
+
+ at c ./statistics/base/center.m
+ at anchor{doc-center}
+ at deftypefn {Function File} {} center (@var{x})
+ at deftypefnx {Function File} {} center (@var{x}, @var{dim})
+If @var{x} is a vector, subtract its mean.
+If @var{x} is a matrix, do the above for each column.
+If the optional argument @var{dim} is given, perform the above
+operation along this dimension
+ at end deftypefn
+
+
+ at c ./statistics/base/studentize.m
+ at anchor{doc-studentize}
+ at deftypefn {Function File} {} studentize (@var{x}, @var{dim})
+If @var{x} is a vector, subtract its mean and divide by its standard
+deviation.
+
+If @var{x} is a matrix, do the above along the first non-singleton
+dimension.  If the optional argument @var{dim} is given then operate
+along this dimension.
+ at end deftypefn
+
+
+ at c ./specfun/nchoosek.m
+ at anchor{doc-nchoosek}
+ at deftypefn {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
+
+Compute the binomial coefficient or all combinations of @var{n}.
+If @var{n} is a scalar then, calculate the binomial coefficient
+of @var{n} and @var{k}, defined as
+
+ at tex
+$$
+ {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+               = {n! \over k! (n-k)!}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+ /   \
+ | n |    n (n-1) (n-2) @dots{} (n-k+1)       n!
+ |   |  = ------------------------- =  ---------
+ | k |               k!                k! (n-k)!
+ \   /
+ at end group
+ at end example
+ at end ifnottex
+
+If @var{n} is a vector generate all combinations of the elements
+of @var{n}, taken @var{k} at a time, one row per combination.  The 
+resulting @var{c} has size @code{[nchoosek (length (@var{n}), 
+ at var{k}), @var{k}]}.
+
+ at code{nchoosek} works only for non-negative integer arguments; use
+ at code{bincoeff} for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+ at seealso{@ref{doc-bincoeff,,bincoeff}}
+ at end deftypefn
+
+
+ at c ./statistics/base/histc.m
+ at anchor{doc-histc}
+ at deftypefn {Function File} {@var{n} =} histc (@var{y}, @var{edges})
+ at deftypefnx {Function File} {@var{n} =} histc (@var{y}, @var{edges}, @var{dim})
+ at deftypefnx {Function File} {[@var{n}, @var{idx}] =} histc (@dots{})
+Produce histogram counts.
+
+When @var{y} is a vector, the function counts the number of elements of
+ at var{y} that fall in the histogram bins defined by @var{edges}.  This must be
+a vector of monotonically non-decreasing values that define the edges of the
+histogram bins.  So, @code{@var{n} (k)} contains the number of elements in
+ at var{y} for which @code{@var{edges} (k) <= @var{y} < @var{edges} (k+1)}.
+The final element of @var{n} contains the number of elements of @var{y}
+that was equal to the last element of @var{edges}.
+
+When @var{y} is a @math{N}-dimensional array, the same operation as above is
+repeated along dimension @var{dim}.  If this argument is given, the operation
+is performed along the first non-singleton dimension.
+
+If a second output argument is requested an index matrix is also returned.
+The @var{idx} matrix has same size as @var{y}.  Each element of @var{idx}
+contains the index of the histogram bin in which the corresponding element
+of @var{y} was counted.
+
+ at seealso{@ref{doc-hist,,hist}}
+ at end deftypefn
+
+
+ at c ./specfun/perms.m
+ at anchor{doc-perms}
+ at deftypefn {Function File} {} perms (@var{v})
+
+Generate all permutations of @var{v}, one row per permutation.  The
+result has size @code{factorial (@var{n}) * @var{n}}, where @var{n}
+is the length of @var{v}.
+
+As an example, @code{perms([1, 2, 3])} returns the matrix
+ at example
+ at group
+  1   2   3
+  2   1   3
+  1   3   2
+  2   3   1
+  3   1   2
+  3   2   1
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./statistics/base/values.m
+ at anchor{doc-values}
+ at deftypefn {Function File} {} values (@var{x})
+Return the different values in a column vector, arranged in ascending
+order.
+
+As an example, @code{values([1, 2, 3, 1])} returns the vector
+ at code{[1, 2, 3]}.
+ at end deftypefn
+
+
+ at c ./statistics/base/table.m
+ at anchor{doc-table}
+ at deftypefn {Function File} {[@var{t}, @var{l_x}] =} table (@var{x})
+ at deftypefnx {Function File} {[@var{t}, @var{l_x}, @var{l_y}] =} table (@var{x}, @var{y})
+Create a contingency table @var{t} from data vectors.  The @var{l}
+vectors are the corresponding levels.
+
+Currently, only 1- and 2-dimensional tables are supported.
+ at end deftypefn
+
+
+ at c ./statistics/base/spearman.m
+ at anchor{doc-spearman}
+ at deftypefn {Function File} {} spearman (@var{x}, @var{y})
+Compute Spearman's rank correlation coefficient @var{rho} for each of
+the variables specified by the input arguments.
+
+For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+ at code{spearman (@var{x})} is equivalent to @code{spearman (@var{x},
+ at var{x})}.
+
+For two data vectors @var{x} and @var{y}, Spearman's @var{rho} is the
+correlation of the ranks of @var{x} and @var{y}.
+
+If @var{x} and @var{y} are drawn from independent distributions,
+ at var{rho} has zero mean and variance @code{1 / (n - 1)}, and is
+asymptotically normally distributed.
+ at end deftypefn
+
+
+ at c ./statistics/base/run_count.m
+ at anchor{doc-run_count}
+ at deftypefn {Function File} {} run_count (@var{x}, @var{n})
+Count the upward runs along the first non-singleton dimension of
+ at var{x} of length 1, 2, @dots{}, @var{n}-1 and greater than or equal 
+to @var{n}.  If the optional argument @var{dim} is given operate
+along this dimension
+ at end deftypefn
+
+
+ at c ./statistics/base/ranks.m
+ at anchor{doc-ranks}
+ at deftypefn {Function File} {} ranks (@var{x}, @var{dim})
+Return the ranks of @var{x} along the first non-singleton dimension
+adjust for ties.  If the optional argument @var{dim} is
+given, operate along this dimension.
+ at end deftypefn
+
+
+ at c ./statistics/base/range.m
+ at anchor{doc-range}
+ at deftypefn {Function File} {} range (@var{x})
+ at deftypefnx {Function File} {} range (@var{x}, @var{dim})
+If @var{x} is a vector, return the range, i.e., the difference
+between the maximum and the minimum, of the input data.
+
+If @var{x} is a matrix, do the above for each column of @var{x}.
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.
+ at end deftypefn
+
+
+ at c ./statistics/base/probit.m
+ at anchor{doc-probit}
+ at deftypefn {Function File} {} probit (@var{p})
+For each component of @var{p}, return the probit (the quantile of the
+standard normal distribution) of @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/base/logit.m
+ at anchor{doc-logit}
+ at deftypefn {Function File} {} logit (@var{p})
+For each component of @var{p}, return the logit of @var{p} defined as
+ at tex
+$$
+{\rm logit}(p) = \log\Big({p \over 1-p}\Big)
+$$
+ at end tex
+ at ifnottex
+ at example
+logit(@var{p}) = log (@var{p} / (1- at var{p}))
+ at end example
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./statistics/base/cloglog.m
+ at anchor{doc-cloglog}
+ at deftypefn {Function File} {} cloglog (@var{x})
+Return the complementary log-log function of @var{x}, defined as
+
+ at tex
+$$
+{\rm cloglog}(x) = - \log (- \log (x))
+$$
+ at end tex
+ at ifnottex
+ at example
+cloglog(x) = - log (- log (@var{x}))
+ at end example
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./statistics/base/kendall.m
+ at anchor{doc-kendall}
+ at deftypefn {Function File} {} kendall (@var{x}, @var{y})
+Compute Kendall's @var{tau} for each of the variables specified by
+the input arguments.
+
+For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+ at code{kendall (@var{x})} is equivalent to @code{kendall (@var{x},
+ at var{x})}.
+
+For two data vectors @var{x}, @var{y} of common length @var{n},
+Kendall's @var{tau} is the correlation of the signs of all rank
+differences of @var{x} and @var{y};  i.e., if both @var{x} and
+ at var{y} have distinct entries, then
+
+ at tex
+$$ \tau = {1 \over n(n-1)} \sum_{i,j} {\rm sign}(q_i-q_j) {\rm sign}(r_i-r_j) $$
+ at end tex
+ at ifnottex
+ at example
+ at group
+         1    
+tau = -------   SUM sign (q(i) - q(j)) * sign (r(i) - r(j))
+      n (n-1)   i,j
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+in which the
+ at tex
+$q_i$ and $r_i$
+ at end tex
+ at ifnottex
+ at var{q}(@var{i}) and @var{r}(@var{i})
+ at end ifnottex
+ are the ranks of
+ at var{x} and @var{y}, respectively.
+
+If @var{x} and @var{y} are drawn from independent distributions,
+Kendall's @var{tau} is asymptotically normal with mean 0 and variance
+ at tex
+${2 (2n+5) \over 9n(n-1)}$.
+ at end tex
+ at ifnottex
+ at code{(2 * (2 at var{n}+5)) / (9 * @var{n} * (@var{n}-1))}.
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./statistics/base/iqr.m
+ at anchor{doc-iqr}
+ at deftypefn {Function File} {} iqr (@var{x}, @var{dim})
+If @var{x} is a vector, return the interquartile range, i.e., the
+difference between the upper and lower quartile, of the input data.
+
+If @var{x} is a matrix, do the above for first non-singleton
+dimension of @var{x}.  If the option @var{dim} argument is given,
+then operate along this dimension.
+ at end deftypefn
+
+
+ at c ./statistics/base/cut.m
+ at anchor{doc-cut}
+ at deftypefn {Function File} {} cut (@var{x}, @var{breaks})
+Create categorical data out of numerical or continuous data by
+cutting into intervals.
+
+If @var{breaks} is a scalar, the data is cut into that many
+equal-width intervals.  If @var{breaks} is a vector of break points,
+the category has @code{length (@var{breaks}) - 1} groups.
+
+The returned value is a vector of the same size as @var{x} telling
+which group each point in @var{x} belongs to.  Groups are labelled
+from 1 to the number of groups; points outside the range of
+ at var{breaks} are labelled by @code{NaN}.
+ at end deftypefn
+
+
+ at node Statistical Plots
+ at section Statistical Plots
+
+ at c Should hist be moved to here, or perhaps the qqplot and ppplot
+ at c functions should be moved to the Plotting Chapter?
+
+Octave can create Quantile Plots (QQ-Plots), and Probability Plots
+(PP-Plots).  These are simple graphical tests for determining if a
+data set comes from a certain distribution.
+
+Note that Octave can also show histograms of data
+using the @code{hist} function as described in
+ at ref{Two-Dimensional Plots}.
+
+ at c ./statistics/base/qqplot.m
+ at anchor{doc-qqplot}
+ at deftypefn {Function File} {[@var{q}, @var{s}] =} qqplot (@var{x}, @var{dist}, @var{params})
+Perform a QQ-plot (quantile plot).
+
+If F is the CDF of the distribution @var{dist} with parameters
+ at var{params} and G its inverse, and @var{x} a sample vector of length
+ at var{n}, the QQ-plot graphs ordinate @var{s}(@var{i}) = @var{i}-th
+largest element of x versus abscissa @var{q}(@var{i}f) = G((@var{i} -
+0.5)/@var{n}).
+
+If the sample comes from F except for a transformation of location
+and scale, the pairs will approximately follow a straight line.
+
+The default for @var{dist} is the standard normal distribution.  The
+optional argument @var{params} contains a list of parameters of
+ at var{dist}.  For example, for a quantile plot of the uniform
+distribution on [2,4] and @var{x}, use
+
+ at example
+qqplot (x, "uniform", 2, 4)
+ at end example
+
+ at noindent
+ at var{dist} can be any string for which a function @var{dist_inv}
+that calculates the inverse CDF of distribution @var{dist} exists.
+
+If no output arguments are given, the data are plotted directly.
+ at end deftypefn
+
+
+ at c ./statistics/base/ppplot.m
+ at anchor{doc-ppplot}
+ at deftypefn {Function File} {[@var{p}, @var{y}] =} ppplot (@var{x}, @var{dist}, @var{params})
+Perform a PP-plot (probability plot).
+
+If F is the CDF of the distribution @var{dist} with parameters
+ at var{params} and @var{x} a sample vector of length @var{n}, the
+PP-plot graphs ordinate @var{y}(@var{i}) = F (@var{i}-th largest
+element of @var{x}) versus abscissa @var{p}(@var{i}) = (@var{i} -
+0.5)/@var{n}.  If the sample comes from F, the pairs will
+approximately follow a straight line.
+
+The default for @var{dist} is the standard normal distribution.  The
+optional argument @var{params} contains a list of parameters of
+ at var{dist}.  For example, for a probability plot of the uniform
+distribution on [2,4] and @var{x}, use
+
+ at example
+ppplot (x, "uniform", 2, 4)
+ at end example
+
+ at noindent
+ at var{dist} can be any string for which a function @var{dist_cdf}
+that calculates the CDF of distribution @var{dist} exists.
+
+If no output arguments are given, the data are plotted directly.
+ at end deftypefn
+
+
+ at node Tests
+ at section Tests
+
+Octave can perform several different statistical tests.  The following
+table summarizes the available tests.
+
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & # \vrule width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& @strong{Hypothesis} && {\bf Test Functions} &\cr
+\noalign{\hrule}
+& Equal mean values && anova, hotelling\_test2, t\_test\_2, &\cr
+&                   && welch\_test, wilcoxon\_test, z\_test\_2 &\cr
+& Equal medians && kruskal\_wallis\_test, sign\_test &\cr
+& Equal variances && bartlett\_test, manova, var\_test &\cr
+& Equal distributions && chisquare\_test\_homogeneity, &\cr
+&                     && kolmogorov\_smirnov\_test\_2, u\_test &\cr
+& Equal marginal frequencies && mcnemar\_test &\cr
+& Equal success probabilities && prop\_test\_2 &\cr
+& Independent observations && chisquare\_test\_independence, &\cr
+&                          && run\_test &\cr
+& Uncorrelated observations && cor\_test &\cr
+& Given mean value && hotelling\_test, t\_test, z\_test &\cr
+& Observations from distribution && kolmogorov\_smirnov\_test &\cr
+& Regression && f\_test\_regression, t\_test\_regression &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .4 .5
+ at item @strong{Hypothesis}
+  @tab @strong{Test Functions}
+ at item Equal mean values
+  @tab @code{anova}, @code{hotelling_test2}, @code{t_test_2},
+       @code{welch_test}, @code{wilcoxon_test}, @code{z_test_2}
+ at item Equal medians
+  @tab @code{kruskal_wallis_test}, @code{sign_test}
+ at item Equal variances
+  @tab @code{bartlett_test}, @code{manova}, @code{var_test}
+ at item Equal distributions
+  @tab @code{chisquare_test_homogeneity}, @code{kolmogorov_smirnov_test_2},
+       @code{u_test}
+ at item Equal marginal frequencies
+  @tab @code{mcnemar_test}
+ at item Equal success probabilities
+  @tab @code{prop_test_2}
+ at item Independent observations
+  @tab @code{chisquare_test_independence}, @code{run_test}
+ at item Uncorrelated observations
+  @tab @code{cor_test}
+ at item Given mean value
+  @tab @code{hotelling_test}, @code{t_test}, @code{z_test}
+ at item Observations from given distribution
+  @tab @code{kolmogorov_smirnov_test}
+ at item Regression
+  @tab @code{f_test_regression}, @code{t_test_regression}
+ at end multitable
+ at end ifnottex
+
+The tests return a p-value that describes the outcome of the test.
+Assuming that the test hypothesis is true, the p-value is the probability
+of obtaining a worse result than the observed one.  So large p-values
+corresponds to a successful test.  Usually a test hypothesis is accepted
+if the p-value exceeds @math{0.05}.
+
+ at c ./statistics/tests/anova.m
+ at anchor{doc-anova}
+ at deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_b}, @var{df_w}] =} anova (@var{y}, @var{g})
+Perform a one-way analysis of variance (ANOVA).  The goal is to test
+whether the population means of data taken from @var{k} different
+groups are all equal.
+
+Data may be given in a single vector @var{y} with groups specified by
+a corresponding vector of group labels @var{g} (e.g., numbers from 1
+to @var{k}).  This is the general form which does not impose any
+restriction on the number of data in each group or the group labels.
+
+If @var{y} is a matrix and @var{g} is omitted, each column of @var{y}
+is treated as a group.  This form is only appropriate for balanced
+ANOVA in which the numbers of samples from each group are all equal.
+
+Under the null of constant means, the statistic @var{f} follows an F
+distribution with @var{df_b} and @var{df_w} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{f}) is
+returned in @var{pval}.
+
+If no output argument is given, the standard one-way ANOVA table is
+printed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/bartlett_test.m
+ at anchor{doc-bartlett_test}
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} bartlett_test (@var{x1}, @dots{}) 
+Perform a Bartlett test for the homogeneity of variances in the data
+vectors @var{x1}, @var{x2}, @dots{}, @var{xk}, where @var{k} > 1.
+
+Under the null of equal variances, the test statistic @var{chisq}
+approximately follows a chi-square distribution with @var{df} degrees of
+freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/chisquare_test_homogeneity.m
+ at anchor{doc-chisquare_test_homogeneity}
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} chisquare_test_homogeneity (@var{x}, @var{y}, @var{c})
+Given two samples @var{x} and @var{y}, perform a chisquare test for
+homogeneity of the null hypothesis that @var{x} and @var{y} come from
+the same distribution, based on the partition induced by the
+(strictly increasing) entries of @var{c}.
+
+For large samples, the test statistic @var{chisq} approximately follows a
+chisquare distribution with @var{df} = @code{length (@var{c})}
+degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/chisquare_test_independence.m
+ at anchor{doc-chisquare_test_independence}
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} chisquare_test_independence (@var{x})
+Perform a chi-square test for independence based on the contingency
+table @var{x}.  Under the null hypothesis of independence,
+ at var{chisq} approximately has a chi-square distribution with
+ at var{df} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at chisq) of the
+test is returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/cor_test.m
+ at anchor{doc-cor_test}
+ at deftypefn {Function File} {} cor_test (@var{x}, @var{y}, @var{alt}, @var{method})
+Test whether two samples @var{x} and @var{y} come from uncorrelated
+populations.
+
+The optional argument string @var{alt} describes the alternative
+hypothesis, and can be @code{"!="} or @code{"<>"} (non-zero),
+ at code{">"} (greater than 0), or @code{"<"} (less than 0).  The
+default is the two-sided case.
+
+The optional argument string @var{method} specifies on which
+correlation coefficient the test should be based.  If @var{method} is
+ at code{"pearson"} (default), the (usual) Pearson's product moment
+correlation coefficient is used.  In this case, the data should come
+from a bivariate normal distribution.  Otherwise, the other two
+methods offer nonparametric alternatives.  If @var{method} is
+ at code{"kendall"}, then Kendall's rank correlation tau is used.  If
+ at var{method} is @code{"spearman"}, then Spearman's rank correlation
+rho is used.  Only the first character is necessary.
+
+The output is a structure with the following elements:
+
+ at table @var
+ at item pval
+The p-value of the test.
+ at item stat
+The value of the test statistic.
+ at item dist
+The distribution of the test statistic.
+ at item params
+The parameters of the null distribution of the test statistic.
+ at item alternative
+The alternative hypothesis.
+ at item method
+The method used for testing.
+ at end table
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/f_test_regression.m
+ at anchor{doc-f_test_regression}
+ at deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_num}, @var{df_den}] =} f_test_regression (@var{y}, @var{x}, @var{rr}, @var{r})
+Perform an F test for the null hypothesis rr * b = r in a classical
+normal regression model y = X * b + e.
+
+Under the null, the test statistic @var{f} follows an F distribution
+with @var{df_num} and @var{df_den} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{f}) is
+returned in @var{pval}.
+
+If not given explicitly, @var{r} = 0.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/hotelling_test.m
+ at anchor{doc-hotelling_test}
+ at deftypefn {Function File} {[@var{pval}, @var{tsq}] =} hotelling_test (@var{x}, @var{m})
+For a sample @var{x} from a multivariate normal distribution with unknown
+mean and covariance matrix, test the null hypothesis that @code{mean
+(@var{x}) == @var{m}}.
+
+Hotelling's @math{T^2} is returned in @var{tsq}.  Under the null,
+ at math{(n-p) T^2 / (p(n-1))} has an F distribution with @math{p} and
+ at math{n-p} degrees of freedom, where @math{n} and @math{p} are the
+numbers of samples and variables, respectively.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/hotelling_test_2.m
+ at anchor{doc-hotelling_test_2}
+ at deftypefn {Function File} {[@var{pval}, @var{tsq}] =} hotelling_test_2 (@var{x}, @var{y})
+For two samples @var{x} from multivariate normal distributions with
+the same number of variables (columns), unknown means and unknown
+equal covariance matrices, test the null hypothesis @code{mean
+(@var{x}) == mean (@var{y})}.
+
+Hotelling's two-sample @math{T^2} is returned in @var{tsq}.  Under the null,
+
+ at tex
+$$
+{n_x+n_y-p-1) T^2 \over p(n_x+n_y-2)}
+$$
+ at end tex
+ at ifnottex
+ at example
+(n_x+n_y-p-1) T^2 / (p(n_x+n_y-2))
+ at end example
+ at end ifnottex
+
+ at noindent
+has an F distribution with @math{p} and @math{n_x+n_y-p-1} degrees of
+freedom, where @math{n_x} and @math{n_y} are the sample sizes and
+ at math{p} is the number of variables.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/kolmogorov_smirnov_test.m
+ at anchor{doc-kolmogorov_smirnov_test}
+ at deftypefn {Function File} {[@var{pval}, @var{ks}] =} kolmogorov_smirnov_test (@var{x}, @var{dist}, @var{params}, @var{alt})
+Perform a Kolmogorov-Smirnov test of the null hypothesis that the
+sample @var{x} comes from the (continuous) distribution dist.  I.e.,
+if F and G are the CDFs corresponding to the sample and dist,
+respectively, then the null is that F == G.
+
+The optional argument @var{params} contains a list of parameters of
+ at var{dist}.  For example, to test whether a sample @var{x} comes from
+a uniform distribution on [2,4], use
+
+ at example
+kolmogorov_smirnov_test(x, "uniform", 2, 4)
+ at end example
+
+ at noindent
+ at var{dist} can be any string for which a function @var{dist_cdf}
+that calculates the CDF of distribution @var{dist} exists.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative F
+!= G.  In this case, the test statistic @var{ks} follows a two-sided
+Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
+one-sided alternative F > G is considered.  Similarly for @code{"<"},
+the one-sided alternative F > G is considered.  In this case, the
+test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
+distribution.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/kolmogorov_smirnov_test_2.m
+ at anchor{doc-kolmogorov_smirnov_test_2}
+ at deftypefn {Function File} {[@var{pval}, @var{ks}, @var{d}] =} kolmogorov_smirnov_test_2 (@var{x}, @var{y}, @var{alt})
+Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis
+that the samples @var{x} and @var{y} come from the same (continuous)
+distribution.  I.e., if F and G are the CDFs corresponding to the
+ at var{x} and @var{y} samples, respectively, then the null is that F ==
+G.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative F
+!= G.  In this case, the test statistic @var{ks} follows a two-sided
+Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
+one-sided alternative F > G is considered.  Similarly for @code{"<"},
+the one-sided alternative F < G is considered.  In this case, the
+test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
+distribution.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+The third returned value, @var{d}, is the test statistic, the maximum
+vertical distance between the two cumulative distribution functions.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/kruskal_wallis_test.m
+ at anchor{doc-kruskal_wallis_test}
+ at deftypefn {Function File} {[@var{pval}, @var{k}, @var{df}] =} kruskal_wallis_test (@var{x1}, @dots{})
+Perform a Kruskal-Wallis one-factor "analysis of variance".
+
+Suppose a variable is observed for @var{k} > 1 different groups, and
+let @var{x1}, @dots{}, @var{xk} be the corresponding data vectors.
+
+Under the null hypothesis that the ranks in the pooled sample are not
+affected by the group memberships, the test statistic @var{k} is
+approximately chi-square with @var{df} = @var{k} - 1 degrees of
+freedom.
+
+If the data contains ties (some value appears more than once)
+ at var{k} is divided by
+
+1 - @var{sum_ties} / (@var{n}^3 - @var{n})
+
+where @var{sum_ties} is the sum of @var{t}^2 - @var{t} over each group
+of ties where @var{t} is the number of ties in the group and @var{n}
+is the total number of values in the input data.  For more info on
+this adjustment see "Use of Ranks in One-Criterion Variance Analysis"
+in Journal of the American Statistical Association, Vol. 47,
+No. 260 (Dec 1952) by William H. Kruskal and W. Allen Wallis.
+
+The p-value (1 minus the CDF of this distribution at @var{k}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/manova.m
+ at anchor{doc-manova}
+ at deftypefn {Function File} {} manova (@var{y}, @var{g})
+Perform a one-way multivariate analysis of variance (MANOVA).  The
+goal is to test whether the p-dimensional population means of data
+taken from @var{k} different groups are all equal.  All data are
+assumed drawn independently from p-dimensional normal distributions
+with the same covariance matrix.
+
+The data matrix is given by @var{y}.  As usual, rows are observations
+and columns are variables.  The vector @var{g} specifies the
+corresponding group labels (e.g., numbers from 1 to @var{k}).
+
+The LR test statistic (Wilks' Lambda) and approximate p-values are
+computed and displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/mcnemar_test.m
+ at anchor{doc-mcnemar_test}
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} mcnemar_test (@var{x})
+For a square contingency table @var{x} of data cross-classified on
+the row and column variables, McNemar's test can be used for testing
+the null hypothesis of symmetry of the classification probabilities.
+
+Under the null, @var{chisq} is approximately distributed as chisquare
+with @var{df} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/prop_test_2.m
+ at anchor{doc-prop_test_2}
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} prop_test_2 (@var{x1}, @var{n1}, @var{x2}, @var{n2}, @var{alt})
+If @var{x1} and @var{n1} are the counts of successes and trials in
+one sample, and @var{x2} and @var{n2} those in a second one, test the
+null hypothesis that the success probabilities @var{p1} and @var{p2}
+are the same.  Under the null, the test statistic @var{z}
+approximately follows a standard normal distribution.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at var{p1} != @var{p2}.  If @var{alt} is @code{">"}, the one-sided
+alternative @var{p1} > @var{p2} is used.  Similarly for @code{"<"},
+the one-sided alternative @var{p1} < @var{p2} is used.
+The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/run_test.m
+ at anchor{doc-run_test}
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}] =} run_test (@var{x})
+Perform a chi-square test with 6 degrees of freedom based on the
+upward runs in the columns of @var{x}.  Can be used to test whether
+ at var{x} contains independent data.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/sign_test.m
+ at anchor{doc-sign_test}
+ at deftypefn {Function File} {[@var{pval}, @var{b}, @var{n}] =} sign_test (@var{x}, @var{y}, @var{alt})
+For two matched-pair samples @var{x} and @var{y}, perform a sign test
+of the null hypothesis PROB (@var{x} > @var{y}) == PROB (@var{x} <
+ at var{y}) == 1/2.  Under the null, the test statistic @var{b} roughly
+follows a binomial distribution with parameters @code{@var{n} = sum
+(@var{x} != @var{y})} and @var{p} = 1/2.
+
+With the optional argument @code{alt}, the alternative of interest
+can be selected.  If @var{alt} is @code{"!="} or @code{"<>"}, the
+null hypothesis is tested against the two-sided alternative PROB
+(@var{x} < @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+one-sided alternative PROB (@var{x} > @var{y}) > 1/2 ("x is
+stochastically greater than y") is considered.  Similarly for
+ at code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) < 1/2
+("x is stochastically less than y") is considered.  The default is
+the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/t_test.m
+ at anchor{doc-t_test}
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test (@var{x}, @var{m}, @var{alt})
+For a sample @var{x} from a normal distribution with unknown mean and
+variance, perform a t-test of the null hypothesis @code{mean
+(@var{x}) == @var{m}}.  Under the null, the test statistic @var{t}
+follows a Student distribution with @code{@var{df} = length (@var{x})
+- 1} degrees of freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
+Similarly for @var{"<"}, the one-sided alternative @code{mean
+(@var{x}) < @var{m}} is considered.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/t_test_2.m
+ at anchor{doc-t_test_2}
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test_2 (@var{x}, @var{y}, @var{alt})
+For two samples x and y from normal distributions with unknown means
+and unknown equal variances, perform a two-sample t-test of the null
+hypothesis of equal means.  Under the null, the test statistic
+ at var{t} follows a Student distribution with @var{df} degrees of
+freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != mean (@var{y})}.  If @var{alt} is @code{">"},
+the one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is
+used.  Similarly for @code{"<"}, the one-sided alternative @code{mean
+(@var{x}) < mean (@var{y})} is used.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/t_test_regression.m
+ at anchor{doc-t_test_regression}
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test_regression (@var{y}, @var{x}, @var{rr}, @var{r}, @var{alt})
+Perform an t test for the null hypothesis @code{@var{rr} * @var{b} =
+ at var{r}} in a classical normal regression model @code{@var{y} =
+ at var{x} * @var{b} + @var{e}}.  Under the null, the test statistic @var{t}
+follows a @var{t} distribution with @var{df} degrees of freedom.
+
+If @var{r} is omitted, a value of 0 is assumed.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{@var{rr} * @var{b} != @var{r}}.  If @var{alt} is @code{">"}, the
+one-sided alternative @code{@var{rr} * @var{b} > @var{r}} is used.
+Similarly for @var{"<"}, the one-sided alternative @code{@var{rr} *
+ at var{b} < @var{r}} is used.  The default is the two-sided case. 
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/u_test.m
+ at anchor{doc-u_test}
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} u_test (@var{x}, @var{y}, @var{alt})
+For two samples @var{x} and @var{y}, perform a Mann-Whitney U-test of
+the null hypothesis PROB (@var{x} > @var{y}) == 1/2 == PROB (@var{x}
+< @var{y}).  Under the null, the test statistic @var{z} approximately
+follows a standard normal distribution.  Note that this test is
+equivalent to the Wilcoxon rank-sum test.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+PROB (@var{x} > @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+one-sided alternative PROB (@var{x} > @var{y}) > 1/2 is considered.
+Similarly for @code{"<"}, the one-sided alternative PROB (@var{x} >
+ at var{y}) < 1/2 is considered.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/var_test.m
+ at anchor{doc-var_test}
+ at deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_num}, @var{df_den}] =} var_test (@var{x}, @var{y}, @var{alt})
+For two samples @var{x} and @var{y} from normal distributions with
+unknown means and unknown variances, perform an F-test of the null
+hypothesis of equal variances.  Under the null, the test statistic
+ at var{f} follows an F-distribution with @var{df_num} and @var{df_den}
+degrees of freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{var (@var{x}) != var (@var{y})}.  If @var{alt} is @code{">"},
+the one-sided alternative @code{var (@var{x}) > var (@var{y})} is
+used.  Similarly for "<", the one-sided alternative @code{var
+(@var{x}) > var (@var{y})} is used.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/welch_test.m
+ at anchor{doc-welch_test}
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} welch_test (@var{x}, @var{y}, @var{alt})
+For two samples @var{x} and @var{y} from normal distributions with
+unknown means and unknown and not necessarily equal variances,
+perform a Welch test of the null hypothesis of equal means.
+Under the null, the test statistic @var{t} approximately follows a
+Student distribution with @var{df} degrees of freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+one-sided alternative mean(x) > @var{m} is considered.  Similarly for
+ at code{"<"}, the one-sided alternative mean(x) < @var{m} is
+considered.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/wilcoxon_test.m
+ at anchor{doc-wilcoxon_test}
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} wilcoxon_test (@var{x}, @var{y}, @var{alt})
+For two matched-pair sample vectors @var{x} and @var{y}, perform a
+Wilcoxon signed-rank test of the null hypothesis PROB (@var{x} >
+ at var{y}) == 1/2.  Under the null, the test statistic @var{z}
+approximately follows a standard normal distribution when @var{n} > 25.
+
+ at strong{Warning}: This function assumes a normal distribution for @var{z}
+and thus is invalid for @var{n} <= 25.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+PROB (@var{x} > @var{y}) != 1/2.  If alt is @code{">"}, the one-sided
+alternative PROB (@var{x} > @var{y}) > 1/2 is considered.  Similarly
+for @code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) <
+1/2 is considered.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+
+
+ at c ./statistics/tests/z_test.m
+ at anchor{doc-z_test}
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} z_test (@var{x}, @var{m}, @var{v}, @var{alt})
+Perform a Z-test of the null hypothesis @code{mean (@var{x}) ==
+ at var{m}} for a sample @var{x} from a normal distribution with unknown
+mean and known variance @var{v}.  Under the null, the test statistic
+ at var{z} follows a standard normal distribution.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
+Similarly for @code{"<"}, the one-sided alternative @code{mean
+(@var{x}) < @var{m}} is considered.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed
+along with some information.
+ at end deftypefn
+
+
+ at c ./statistics/tests/z_test_2.m
+ at anchor{doc-z_test_2}
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} z_test_2 (@var{x}, @var{y}, @var{v_x}, @var{v_y}, @var{alt})
+For two samples @var{x} and @var{y} from normal distributions with
+unknown means and known variances @var{v_x} and @var{v_y}, perform a
+Z-test of the hypothesis of equal means.  Under the null, the test
+statistic @var{z} follows a standard normal distribution.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != mean (@var{y})}.  If alt is @code{">"}, the
+one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is used.
+Similarly for @code{"<"}, the one-sided alternative @code{mean
+(@var{x}) < mean (@var{y})} is used.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed
+along with some information.
+ at end deftypefn
+
+
+ at node Models
+ at section Models
+
+ at c ./statistics/models/logistic_regression.m
+ at anchor{doc-logistic_regression}
+ at deftypefn {Function File} {[@var{theta}, @var{beta}, @var{dev}, @var{dl}, @var{d2l}, @var{p}] =} logistic_regression (@var{y}, @var{x}, @var{print}, @var{theta}, @var{beta})
+Perform ordinal logistic regression.
+
+Suppose @var{y} takes values in @var{k} ordered categories, and let
+ at code{gamma_i (@var{x})} be the cumulative probability that @var{y}
+falls in one of the first @var{i} categories given the covariate
+ at var{x}.  Then
+
+ at example
+[theta, beta] = logistic_regression (y, x)
+ at end example
+
+ at noindent
+fits the model
+
+ at example
+logit (gamma_i (x)) = theta_i - beta' * x,   i = 1 @dots{} k-1
+ at end example
+
+The number of ordinal categories, @var{k}, is taken to be the number
+of distinct values of @code{round (@var{y})}.  If @var{k} equals 2,
+ at var{y} is binary and the model is ordinary logistic regression.  The
+matrix @var{x} is assumed to have full column rank.
+
+Given @var{y} only, @code{theta = logistic_regression (y)}
+fits the model with baseline logit odds only.
+
+The full form is
+
+ at example
+ at group
+[theta, beta, dev, dl, d2l, gamma]
+   = logistic_regression (y, x, print, theta, beta)
+ at end group
+ at end example
+
+ at noindent
+in which all output arguments and all input arguments except @var{y}
+are optional.
+
+Setting @var{print} to 1 requests summary information about the fitted
+model to be displayed.  Setting @var{print} to 2 requests information
+about convergence at each iteration.  Other values request no
+information to be displayed.  The input arguments @var{theta} and
+ at var{beta} give initial estimates for @var{theta} and @var{beta}.
+
+The returned value @var{dev} holds minus twice the log-likelihood.
+
+The returned values @var{dl} and @var{d2l} are the vector of first
+and the matrix of second derivatives of the log-likelihood with
+respect to @var{theta} and @var{beta}.
+
+ at var{p} holds estimates for the conditional distribution of @var{y}
+given @var{x}.
+ at end deftypefn
+
+
+ at node Distributions
+ at section Distributions
+
+Octave has functions for computing the Probability Density Function
+(PDF), the Cumulative Distribution function (CDF), and the quantile
+(the inverse of the CDF) of a large number of distributions.
+
+The following table summarizes the supported distributions (in 
+alphabetical order).
+
+ at c Do the table explicitly in TeX if possible to get a better layout.
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & \vrule # & # \hfil & \vrule # & # \hfil &
+# \vrule width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& {\bf Distribution} && {\bf PDF}      && {\bf CDF}     && {\bf Quantile}&\cr
+\noalign{\hrule}
+&Beta         && betapdf        && betacdf       && betainv&\cr
+&Binomial     && binopdf        && binocdf       && binoinv&\cr
+&Cauchy       && cauchy\_pdf    && cauchy\_cdf   && cauchy\_inv&\cr
+&Chi-Square   && chi2pdf        && chi2cdf       && chi2inv&\cr
+&Univariate Discrete       && discrete\_pdf  && discrete\_cdf && discrete\_inv&\cr
+&Empirical    && empirical\_pdf  && empirical\_cdf && empirical\_inv&\cr
+&Exponential  && exppdf         && expcdf        && expinv&\cr
+&F            && fpdf           && fcdf          && finv&\cr
+&Gamma        && gampdf         && gamcdf        && gaminv&\cr
+&Geometric    && geopdf         && geocdf        && geoinv&\cr
+&Hypergeometric            && hygepdf      && hygecdf       && hygeinv&\cr
+&Kolmogorov Smirnov && {\it Not Available} && kolmogorov\_&& {\it Not Available}&\cr
+&             &&                && smirnov\_cdf &&&\cr
+&Laplace      && laplace\_pdf    && laplace\_cdf   && laplace\_inv&\cr
+&Logistic     && logistic\_pdf   && logistic\_cdf  && logistic\_inv&\cr
+&Log-Normal   && lognpdf        && logncdf       && logninv&\cr
+&Pascal       && nbinpdf        && nbincdf       && nbininv&\cr
+&Univariate Normal && normpdf   && normcdf       && norminv&\cr
+&Poisson      && poisspdf       && poisscdf      && poissinv&\cr
+&t (Student)  && tpdf           && tcdf          && tinv&\cr
+&Univariate Discrete && unidpdf && unidcdf       && unidinv&\cr
+&Uniform      && unifpdf        && unifcdf       && unifinv&\cr
+&Weibull      && wblpdf         && wblcdf        && wblinv&\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .31 .23 .23 .23
+ at item @strong{Distribution}
+  @tab @strong{PDF}
+  @tab @strong{CDF}
+  @tab @strong{Quantile}
+ at item Beta Distribution
+  @tab @code{betapdf}
+  @tab @code{betacdf}
+  @tab @code{betainv}
+ at item Binomial Distribution
+  @tab @code{binopdf}
+  @tab @code{binocdf}
+  @tab @code{binoinv}
+ at item Cauchy Distribution
+  @tab @code{cauchy_pdf}
+  @tab @code{cauchy_cdf}
+  @tab @code{cauchy_inv}
+ at item Chi-Square Distribution
+  @tab @code{chi2pdf}
+  @tab @code{chi2cdf}
+  @tab @code{chi2inv}
+ at item Univariate Discrete Distribution
+  @tab @code{discrete_pdf}
+  @tab @code{discrete_cdf}
+  @tab @code{discrete_inv}
+ at item Empirical Distribution
+  @tab @code{empirical_pdf}
+  @tab @code{empirical_cdf}
+  @tab @code{empirical_inv}
+ at item Exponential Distribution
+  @tab @code{exppdf}
+  @tab @code{expcdf}
+  @tab @code{expinv}
+ at item F Distribution
+  @tab @code{fpdf}
+  @tab @code{fcdf}
+  @tab @code{finv}
+ at item Gamma Distribution
+  @tab @code{gampdf}
+  @tab @code{gamcdf}
+  @tab @code{gaminv}
+ at item Geometric Distribution
+  @tab @code{geopdf}
+  @tab @code{geocdf}
+  @tab @code{geoinv}
+ at item Hypergeometric Distribution
+  @tab @code{hygepdf}
+  @tab @code{hygecdf}
+  @tab @code{hygeinv}
+ at item Kolmogorov Smirnov Distribution
+  @tab @emph{Not Available}
+  @tab @code{kolmogorov_smirnov_cdf}
+  @tab @emph{Not Available}
+ at item Laplace Distribution
+  @tab @code{laplace_pdf}
+  @tab @code{laplace_cdf}
+  @tab @code{laplace_inv}
+ at item Logistic Distribution
+  @tab @code{logistic_pdf}
+  @tab @code{logistic_cdf}
+  @tab @code{logistic_inv}
+ at item Log-Normal Distribution
+  @tab @code{lognpdf}
+  @tab @code{logncdf}
+  @tab @code{logninv}
+ at item Pascal Distribution
+  @tab @code{nbinpdf}
+  @tab @code{nbincdf}
+  @tab @code{nbininv}
+ at item Univariate Normal Distribution
+  @tab @code{normpdf}
+  @tab @code{normcdf}
+  @tab @code{norminv}
+ at item Poisson Distribution
+  @tab @code{poisspdf}
+  @tab @code{poisscdf}
+  @tab @code{poissinv}
+ at item t (Student) Distribution
+  @tab @code{tpdf}
+  @tab @code{tcdf}
+  @tab @code{tinv}
+ at item Univariate Discrete Distribution
+  @tab @code{unidpdf}
+  @tab @code{unidcdf}
+  @tab @code{unidinv}
+ at item Uniform Distribution
+  @tab @code{unifpdf}
+  @tab @code{unifcdf}
+  @tab @code{unifinv}
+ at item Weibull Distribution
+  @tab @code{wblpdf}
+  @tab @code{wblcdf}
+  @tab @code{wblinv}
+ at end multitable
+ at end ifnottex
+
+ at c ./statistics/distributions/betacdf.m
+ at anchor{doc-betacdf}
+ at deftypefn {Function File} {} betacdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, returns the CDF at @var{x} of the beta
+distribution with parameters @var{a} and @var{b}, i.e.,
+PROB (beta (@var{a}, @var{b}) <= @var{x}).
+ at end deftypefn
+
+
+ at c ./statistics/distributions/betainv.m
+ at anchor{doc-betainv}
+ at deftypefn {Function File} {} betainv (@var{x}, @var{a}, @var{b})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Beta distribution with parameters @var{a}
+and @var{b}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/betapdf.m
+ at anchor{doc-betapdf}
+ at deftypefn {Function File} {} betapdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, returns the PDF at @var{x} of the beta
+distribution with parameters @var{a} and @var{b}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/binocdf.m
+ at anchor{doc-binocdf}
+ at deftypefn {Function File} {} binocdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the CDF at @var{x} of the
+binomial distribution with parameters @var{n} and @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/binoinv.m
+ at anchor{doc-binoinv}
+ at deftypefn {Function File} {} binoinv (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+binomial distribution with parameters @var{n} and @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/binopdf.m
+ at anchor{doc-binopdf}
+ at deftypefn {Function File} {} binopdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the binomial distribution with parameters @var{n}
+and @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/cauchy_cdf.m
+ at anchor{doc-cauchy_cdf}
+ at deftypefn {Function File} {} cauchy_cdf (@var{x}, @var{lambda}, @var{sigma})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Cauchy distribution with location
+parameter @var{lambda} and scale parameter @var{sigma}.  Default
+values are @var{lambda} = 0, @var{sigma} = 1. 
+ at end deftypefn
+
+
+ at c ./statistics/distributions/cauchy_inv.m
+ at anchor{doc-cauchy_inv}
+ at deftypefn {Function File} {} cauchy_inv (@var{x}, @var{lambda}, @var{sigma})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the Cauchy distribution with location parameter
+ at var{lambda} and scale parameter @var{sigma}.  Default values are
+ at var{lambda} = 0, @var{sigma} = 1. 
+ at end deftypefn
+
+
+ at c ./statistics/distributions/cauchy_pdf.m
+ at anchor{doc-cauchy_pdf}
+ at deftypefn {Function File} {} cauchy_pdf (@var{x}, @var{lambda}, @var{sigma})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Cauchy distribution with location parameter
+ at var{lambda} and scale parameter @var{sigma} > 0.  Default values are
+ at var{lambda} = 0, @var{sigma} = 1. 
+ at end deftypefn
+
+
+ at c ./statistics/distributions/chi2cdf.m
+ at anchor{doc-chi2cdf}
+ at deftypefn {Function File} {} chi2cdf (@var{x}, @var{n})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the chisquare distribution with @var{n}
+degrees of freedom.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/chi2inv.m
+ at anchor{doc-chi2inv}
+ at deftypefn {Function File} {} chi2inv (@var{x}, @var{n})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the chisquare distribution with @var{n} degrees of
+freedom.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/chi2pdf.m
+ at anchor{doc-chi2pdf}
+ at deftypefn {Function File} {} chisquare_pdf (@var{x}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the chisquare distribution with @var{n} degrees
+of freedom.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/discrete_cdf.m
+ at anchor{doc-discrete_cdf}
+ at deftypefn {Function File} {} discrete_cdf (@var{x}, @var{v}, @var{p})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of a univariate discrete distribution which
+assumes the values in @var{v} with probabilities @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/discrete_inv.m
+ at anchor{doc-discrete_inv}
+ at deftypefn {Function File} {} discrete_inv (@var{x}, @var{v}, @var{p})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the univariate distribution which assumes the
+values in @var{v} with probabilities @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/discrete_pdf.m
+ at anchor{doc-discrete_pdf}
+ at deftypefn {Function File} {} discrete_pdf (@var{x}, @var{v}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of a univariate discrete distribution which assumes
+the values in @var{v} with probabilities @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/empirical_cdf.m
+ at anchor{doc-empirical_cdf}
+ at deftypefn {Function File} {} empirical_cdf (@var{x}, @var{data})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the empirical distribution obtained from
+the univariate sample @var{data}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/empirical_inv.m
+ at anchor{doc-empirical_inv}
+ at deftypefn {Function File} {} empirical_inv (@var{x}, @var{data})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the empirical distribution obtained from the
+univariate sample @var{data}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/empirical_pdf.m
+ at anchor{doc-empirical_pdf}
+ at deftypefn {Function File} {} empirical_pdf (@var{x}, @var{data})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the empirical distribution obtained from the
+univariate sample @var{data}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/expcdf.m
+ at anchor{doc-expcdf}
+ at deftypefn {Function File} {} expcdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the exponential distribution with
+mean @var{lambda}.
+
+The arguments can be of common size or scalar.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/expinv.m
+ at anchor{doc-expinv}
+ at deftypefn {Function File} {} expinv (@var{x}, @var{lambda})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the exponential distribution with mean
+ at var{lambda}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/exppdf.m
+ at anchor{doc-exppdf}
+ at deftypefn {Function File} {} exppdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the probability density function
+(PDF) of the exponential distribution with mean @var{lambda}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/fcdf.m
+ at anchor{doc-fcdf}
+ at deftypefn {Function File} {} fcdf (@var{x}, @var{m}, @var{n})
+For each element of @var{x}, compute the CDF at @var{x} of the F
+distribution with @var{m} and @var{n} degrees of freedom, i.e.,
+PROB (F (@var{m}, @var{n}) <= @var{x}). 
+ at end deftypefn
+
+
+ at c ./statistics/distributions/finv.m
+ at anchor{doc-finv}
+ at deftypefn {Function File} {} finv (@var{x}, @var{m}, @var{n})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the F distribution with parameters @var{m} and
+ at var{n}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/fpdf.m
+ at anchor{doc-fpdf}
+ at deftypefn {Function File} {} fpdf (@var{x}, @var{m}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the F distribution with @var{m} and @var{n}
+degrees of freedom.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/gamcdf.m
+ at anchor{doc-gamcdf}
+ at deftypefn {Function File} {} gamcdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Gamma distribution with parameters
+ at var{a} and @var{b}.
+ at seealso{@ref{doc-gamma,,gamma}, @ref{doc-gammaln,,gammaln}, @ref{doc-gammainc,,gammainc}, @ref{doc-gampdf,,gampdf}, @ref{doc-gaminv,,gaminv}, @ref{doc-gamrnd,,gamrnd}}
+ at end deftypefn
+
+
+ at c ./statistics/distributions/gaminv.m
+ at anchor{doc-gaminv}
+ at deftypefn {Function File} {} gaminv (@var{x}, @var{a}, @var{b})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Gamma distribution with parameters @var{a}
+and @var{b}.
+ at seealso{@ref{doc-gamma,,gamma}, @ref{doc-gammaln,,gammaln}, @ref{doc-gammainc,,gammainc}, @ref{doc-gampdf,,gampdf}, @ref{doc-gamcdf,,gamcdf}, @ref{doc-gamrnd,,gamrnd}}
+ at end deftypefn
+
+
+ at c ./statistics/distributions/gampdf.m
+ at anchor{doc-gampdf}
+ at deftypefn {Function File} {} gampdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, return the probability density function
+(PDF) at @var{x} of the Gamma distribution with parameters @var{a}
+and @var{b}.
+ at seealso{@ref{doc-gamma,,gamma}, @ref{doc-gammaln,,gammaln}, @ref{doc-gammainc,,gammainc}, @ref{doc-gamcdf,,gamcdf}, @ref{doc-gaminv,,gaminv}, @ref{doc-gamrnd,,gamrnd}}
+ at end deftypefn
+
+
+ at c ./statistics/distributions/geocdf.m
+ at anchor{doc-geocdf}
+ at deftypefn {Function File} {} geocdf (@var{x}, @var{p})
+For each element of @var{x}, compute the CDF at @var{x} of the
+geometric distribution with parameter @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/geoinv.m
+ at anchor{doc-geoinv}
+ at deftypefn {Function File} {} geoinv (@var{x}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+geometric distribution with parameter @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/geopdf.m
+ at anchor{doc-geopdf}
+ at deftypefn {Function File} {} geopdf (@var{x}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the geometric distribution with parameter @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/hygecdf.m
+ at anchor{doc-hygecdf}
+ at deftypefn {Function File} {} hygecdf (@var{x}, @var{t}, @var{m}, @var{n})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+hypergeometric distribution with parameters @var{t}, @var{m}, and
+ at var{n}.  This is the probability of obtaining not more than @var{x}
+marked items when randomly drawing a sample of size @var{n} without
+replacement from a population of total size @var{t} containing
+ at var{m} marked items.
+
+The parameters @var{t}, @var{m}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/hygeinv.m
+ at anchor{doc-hygeinv}
+ at deftypefn {Function File} {} hygeinv (@var{x}, @var{t}, @var{m}, @var{n})
+For each element of @var{x}, compute the quantile at @var{x} of the
+hypergeometric distribution with parameters @var{t}, @var{m}, and
+ at var{n}.
+
+The parameters @var{t}, @var{m}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/hygepdf.m
+ at anchor{doc-hygepdf}
+ at deftypefn {Function File} {} hygepdf (@var{x}, @var{t}, @var{m}, @var{n})
+Compute the probability density function (PDF) at @var{x} of the
+hypergeometric distribution with parameters @var{t}, @var{m}, and
+ at var{n}.  This is the probability of obtaining @var{x} marked items
+when randomly drawing a sample of size @var{n} without replacement
+from a population of total size @var{t} containing @var{m} marked items.
+
+The arguments must be of common size or scalar.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/kolmogorov_smirnov_cdf.m
+ at anchor{doc-kolmogorov_smirnov_cdf}
+ at deftypefn {Function File} {} kolmogorov_smirnov_cdf (@var{x}, @var{tol})
+Return the CDF at @var{x} of the Kolmogorov-Smirnov distribution,
+ at tex
+$$ Q(x) = \sum_{k=-\infty}^\infty (-1)^k \exp(-2 k^2 x^2) $$
+ at end tex
+ at ifnottex
+ at example
+ at group
+         Inf
+Q(x) =   SUM    (-1)^k exp(-2 k^2 x^2)
+       k = -Inf
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+for @var{x} > 0.
+
+The optional parameter @var{tol} specifies the precision up to which
+the series should be evaluated;  the default is @var{tol} = @code{eps}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/laplace_cdf.m
+ at anchor{doc-laplace_cdf}
+ at deftypefn {Function File} {} laplace_cdf (@var{x})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Laplace distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/laplace_inv.m
+ at anchor{doc-laplace_inv}
+ at deftypefn {Function File} {} laplace_inv (@var{x})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the Laplace distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/laplace_pdf.m
+ at anchor{doc-laplace_pdf}
+ at deftypefn {Function File} {} laplace_pdf (@var{x})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Laplace distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/logistic_cdf.m
+ at anchor{doc-logistic_cdf}
+ at deftypefn {Function File} {} logistic_cdf (@var{x})
+For each component of @var{x}, compute the CDF at @var{x} of the
+logistic distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/logistic_inv.m
+ at anchor{doc-logistic_inv}
+ at deftypefn {Function File} {} logistic_inv (@var{x})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the logistic distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/logistic_pdf.m
+ at anchor{doc-logistic_pdf}
+ at deftypefn {Function File} {} logistic_pdf (@var{x})
+For each component of @var{x}, compute the PDF at @var{x} of the
+logistic distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/logncdf.m
+ at anchor{doc-logncdf}
+ at deftypefn {Function File} {} logncdf (@var{x}, @var{mu}, @var{sigma})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the lognormal distribution with
+parameters @var{mu} and @var{sigma}.  If a random variable follows this
+distribution, its logarithm is normally distributed with mean
+ at var{mu} and standard deviation @var{sigma}.
+
+Default values are @var{mu} = 1, @var{sigma} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/logninv.m
+ at anchor{doc-logninv}
+ at deftypefn {Function File} {} logninv (@var{x}, @var{mu}, @var{sigma})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the lognormal distribution with parameters @var{mu}
+and @var{sigma}.  If a random variable follows this distribution, its
+logarithm is normally distributed with mean @code{log (@var{mu})} and
+variance @var{sigma}.
+
+Default values are @var{mu} = 1, @var{sigma} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/lognpdf.m
+ at anchor{doc-lognpdf}
+ at deftypefn {Function File} {} lognpdf (@var{x}, @var{mu}, @var{sigma})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the lognormal distribution with parameters
+ at var{mu} and @var{sigma}.  If a random variable follows this distribution,
+its logarithm is normally distributed with mean @var{mu}
+and standard deviation @var{sigma}.
+
+Default values are @var{mu} = 1, @var{sigma} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/nbincdf.m
+ at anchor{doc-nbincdf}
+ at deftypefn {Function File} {} nbincdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the CDF at x of the Pascal
+(negative binomial) distribution with parameters @var{n} and @var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/nbininv.m
+ at anchor{doc-nbininv}
+ at deftypefn {Function File} {} nbininv (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+Pascal (negative binomial) distribution with parameters @var{n} and
+ at var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/nbinpdf.m
+ at anchor{doc-nbinpdf}
+ at deftypefn {Function File} {} nbinpdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Pascal (negative binomial) distribution with
+parameters @var{n} and @var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution. 
+ at end deftypefn
+
+
+ at c ./statistics/distributions/normcdf.m
+ at anchor{doc-normcdf}
+ at deftypefn {Function File} {} normcdf (@var{x}, @var{m}, @var{s})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the normal distribution with mean
+ at var{m} and standard deviation @var{s}.
+
+Default values are @var{m} = 0, @var{s} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/norminv.m
+ at anchor{doc-norminv}
+ at deftypefn {Function File} {} norminv (@var{x}, @var{m}, @var{s})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the normal distribution with mean @var{m} and
+standard deviation @var{s}.
+
+Default values are @var{m} = 0, @var{s} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/normpdf.m
+ at anchor{doc-normpdf}
+ at deftypefn {Function File} {} normpdf (@var{x}, @var{m}, @var{s})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the normal distribution with mean @var{m} and
+standard deviation @var{s}.
+
+Default values are @var{m} = 0, @var{s} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/poisscdf.m
+ at anchor{doc-poisscdf}
+ at deftypefn {Function File} {} poisscdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Poisson distribution with parameter
+lambda.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/poissinv.m
+ at anchor{doc-poissinv}
+ at deftypefn {Function File} {} poissinv (@var{x}, @var{lambda})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Poisson distribution with parameter
+ at var{lambda}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/poisspdf.m
+ at anchor{doc-poisspdf}
+ at deftypefn {Function File} {} poisspdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the poisson distribution with parameter @var{lambda}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/tcdf.m
+ at anchor{doc-tcdf}
+ at deftypefn {Function File} {} tcdf (@var{x}, @var{n})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the t (Student) distribution with
+ at var{n} degrees of freedom, i.e., PROB (t(@var{n}) <= @var{x}).
+ at end deftypefn
+
+
+ at c ./statistics/distributions/tinv.m
+ at anchor{doc-tinv}
+ at deftypefn {Function File} {} tinv (@var{x}, @var{n})
+For each probability value @var{x}, compute the inverse of the
+cumulative distribution function (CDF) of the t (Student)
+distribution with degrees of freedom @var{n}.  This function is
+analogous to looking in a table for the t-value of a single-tailed
+distribution.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/tpdf.m
+ at anchor{doc-tpdf}
+ at deftypefn {Function File} {} tpdf (@var{x}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the @var{t} (Student) distribution with @var{n}
+degrees of freedom. 
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unidcdf.m
+ at anchor{doc-unidcdf}
+ at deftypefn {Function File} {} unidcdf (@var{x}, @var{v})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of a univariate discrete distribution which
+assumes the values in @var{v} with equal probability.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unidinv.m
+ at anchor{doc-unidinv}
+ at deftypefn {Function File} {} unidinv (@var{x}, @var{v})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the univariate discrete distribution which assumes the
+values in @var{v} with equal probability
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unidpdf.m
+ at anchor{doc-unidpdf}
+ at deftypefn {Function File} {} unidpdf (@var{x}, @var{v})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of a univariate discrete distribution which assumes
+the values in @var{v} with equal probability.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unifcdf.m
+ at anchor{doc-unifcdf}
+ at deftypefn {Function File} {} unifcdf (@var{x}, @var{a}, @var{b})
+Return the CDF at @var{x} of the uniform distribution on [@var{a},
+ at var{b}], i.e., PROB (uniform (@var{a}, @var{b}) <= x).
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unifinv.m
+ at anchor{doc-unifinv}
+ at deftypefn {Function File} {} unifinv (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the uniform distribution on [@var{a}, @var{b}].
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unifpdf.m
+ at anchor{doc-unifpdf}
+ at deftypefn {Function File} {} unifpdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the PDF at @var{x} of the uniform
+distribution on [@var{a}, @var{b}].
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/wblcdf.m
+ at anchor{doc-wblcdf}
+ at deftypefn {Function File} {} wblcdf (@var{x}, @var{scale}, @var{shape})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}, which is
+
+ at tex
+$$ 1 - \exp(-(x/shape)^{scale}) $$
+for $x\geq 0$.
+ at end tex
+ at ifnottex
+ at example
+1 - exp(-(x/shape)^scale)
+ at end example
+for @var{x} >= 0.
+ at end ifnottex
+ at end deftypefn
+
+
+ at c ./statistics/distributions/wblinv.m
+ at anchor{doc-wblinv}
+ at deftypefn {Function File} {} wblinv (@var{x}, @var{scale}, @var{shape})
+Compute the quantile (the inverse of the CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/wblpdf.m
+ at anchor{doc-wblpdf}
+ at deftypefn {Function File} {} wblpdf (@var{x}, @var{scale}, @var{shape})
+Compute the probability density function (PDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape} which is given by
+
+ at tex
+$$  scale \cdot shape^{-scale} x^{scale-1} \exp(-(x/shape)^{scale}) $$
+ at end tex
+ at ifnottex
+ at example
+   scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+ at end example
+ at end ifnottex
+
+ at noindent
+for @var{x} > 0.
+ at end deftypefn
+
+
+ at node Random Number Generation
+ at section Random Number Generation
+
+Octave can generate random numbers from a large number of distributions.
+The random number generators are based on the random number generators
+described in @ref{Special Utility Matrices}.
+ at c Should rand, randn, rande, randp, and randg be moved to here?
+
+The following table summarizes the available random number generators
+(in alphabetical order).
+
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & # \vrule width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& {\bf Distribution}                && {\bf Function} &\cr
+\noalign{\hrule}
+& Beta Distribution                 && betarnd &\cr
+& Binomial Distribution             && binornd &\cr
+& Cauchy Distribution               && cauchy\_rnd &\cr
+& Chi-Square Distribution           && chi2rnd &\cr
+& Univariate Discrete Distribution  && discrete\_rnd &\cr
+& Empirical Distribution            && empirical\_rnd &\cr
+& Exponential Distribution          && exprnd &\cr
+& F Distribution                    && frnd &\cr
+& Gamma Distribution                && gamrnd &\cr
+& Geometric Distribution            && geornd &\cr
+& Hypergeometric Distribution       && hygernd &\cr
+& Laplace Distribution              && laplace\_rnd &\cr
+& Logistic Distribution             && logistic\_rnd &\cr
+& Log-Normal Distribution           && lognrnd &\cr
+& Pascal Distribution               && nbinrnd &\cr
+& Univariate Normal Distribution    && normrnd &\cr
+& Poisson Distribution              && poissrnd &\cr
+& t (Student) Distribution          && trnd &\cr
+& Univariate Discrete Distribution  && unidrnd &\cr
+& Uniform Distribution              && unifrnd &\cr
+& Weibull Distribution              && wblrnd &\cr
+& Wiener Process                    && wienrnd &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .4 .3
+ at item @strong{Distribution}             @tab @strong{Function}
+ at item Beta Distribution                 @tab @code{betarnd}
+ at item Binomial Distribution             @tab @code{binornd}
+ at item Cauchy Distribution               @tab @code{cauchy_rnd}
+ at item Chi-Square Distribution           @tab @code{chi2rnd}
+ at item Univariate Discrete Distribution  @tab @code{discrete_rnd}
+ at item Empirical Distribution            @tab @code{empirical_rnd}
+ at item Exponential Distribution          @tab @code{exprnd}
+ at item F Distribution                    @tab @code{frnd}
+ at item Gamma Distribution                @tab @code{gamrnd}
+ at item Geometric Distribution            @tab @code{geornd}
+ at item Hypergeometric Distribution       @tab @code{hygernd}
+ at item Laplace Distribution              @tab @code{laplace_rnd}
+ at item Logistic Distribution             @tab @code{logistic_rnd}
+ at item Log-Normal Distribution           @tab @code{lognrnd}
+ at item Pascal Distribution               @tab @code{nbinrnd}
+ at item Univariate Normal Distribution    @tab @code{normrnd}
+ at item Poisson Distribution              @tab @code{poissrnd}
+ at item t (Student) Distribution          @tab @code{trnd}
+ at item Univariate Discrete Distribution  @tab @code{unidrnd}
+ at item Uniform Distribution              @tab @code{unifrnd}
+ at item Weibull Distribution              @tab @code{wblrnd}
+ at item Wiener Process                    @tab @code{wienrnd}
+ at end multitable
+ at end ifnottex
+
+ at c ./statistics/distributions/betarnd.m
+ at anchor{doc-betarnd}
+ at deftypefn {Function File} {} betarnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} betarnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+random samples from the Beta distribution with parameters @var{a} and
+ at var{b}.  Both @var{a} and @var{b} must be scalar or of size @var{r}
+ by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/binornd.m
+ at anchor{doc-binornd}
+ at deftypefn {Function File} {} binornd (@var{n}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} binornd (@var{n}, @var{p}, @var{sz})
+Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+random samples from the binomial distribution with parameters @var{n}
+and @var{p}.  Both @var{n} and @var{p} must be scalar or of size
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{n} and @var{p}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/cauchy_rnd.m
+ at anchor{doc-cauchy_rnd}
+ at deftypefn {Function File} {} cauchy_rnd (@var{lambda}, @var{sigma}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} cauchy_rnd (@var{lambda}, @var{sigma}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the Cauchy distribution with parameters @var{lambda} 
+and @var{sigma} which must both be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{lambda} and @var{sigma}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/chi2rnd.m
+ at anchor{doc-chi2rnd}
+ at deftypefn {Function File} {} chi2rnd (@var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} chi2rnd (@var{n}, @var{sz})
+Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+random samples from the chisquare distribution with @var{n} degrees 
+of freedom.  @var{n} must be a scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{n}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/discrete_rnd.m
+ at anchor{doc-discrete_rnd}
+ at deftypefn {Function File} {} discrete_rnd (@var{n}, @var{v}, @var{p})
+ at deftypefnx {Function File} {} discrete_rnd (@var{v}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} discrete_rnd (@var{v}, @var{p}, @var{sz})
+Generate a row vector containing a random sample of size @var{n} from
+the univariate distribution which assumes the values in @var{v} with
+probabilities @var{p}.  @var{n} must be a scalar.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/empirical_rnd.m
+ at anchor{doc-empirical_rnd}
+ at deftypefn {Function File} {} empirical_rnd (@var{n}, @var{data})
+ at deftypefnx {Function File} {} empirical_rnd (@var{data}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} empirical_rnd (@var{data}, @var{sz})
+Generate a bootstrap sample of size @var{n} from the empirical
+distribution obtained from the univariate sample @var{data}.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/exprnd.m
+ at anchor{doc-exprnd}
+ at deftypefn {Function File} {} exprnd (@var{lambda}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} exprnd (@var{lambda}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+exponential distribution with mean @var{lambda}, which must be a
+scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a vector, 
+create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{lambda}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/frnd.m
+ at anchor{doc-frnd}
+ at deftypefn {Function File} {} frnd (@var{m}, @var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} frnd (@var{m}, @var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the F
+distribution with @var{m} and @var{n} degrees of freedom.  Both
+ at var{m} and @var{n} must be scalar or of size @var{r} by @var{c}.
+If @var{sz} is a vector the random samples are in a matrix of 
+size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{m} and @var{n}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/gamrnd.m
+ at anchor{doc-gamrnd}
+ at deftypefn {Function File} {} gamrnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} gamrnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the Gamma distribution with parameters @var{a}
+and @var{b}.  Both @var{a} and @var{b} must be scalar or of size 
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at seealso{@ref{doc-gamma,,gamma}, @ref{doc-gammaln,,gammaln}, @ref{doc-gammainc,,gammainc}, @ref{doc-gampdf,,gampdf}, @ref{doc-gamcdf,,gamcdf}, @ref{doc-gaminv,,gaminv}}
+ at end deftypefn
+
+
+ at c ./statistics/distributions/geornd.m
+ at anchor{doc-geornd}
+ at deftypefn {Function File} {} geornd (@var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} geornd (@var{p}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+geometric distribution with parameter @var{p}, which must be a scalar
+or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/hygernd.m
+ at anchor{doc-hygernd}
+ at deftypefn {Function File} {} hygernd (@var{t}, @var{m}, @var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} hygernd (@var{t}, @var{m}, @var{n}, @var{sz})
+ at deftypefnx {Function File} {} hygernd (@var{t}, @var{m}, @var{n})
+Return an @var{r} by @var{c} matrix of random samples from the
+hypergeometric distribution with parameters @var{t}, @var{m},
+and @var{n}.
+
+The parameters @var{t}, @var{m}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+
+The parameter @var{sz} must be scalar or a vector of matrix
+dimensions.  If @var{sz} is scalar, then a @var{sz} by @var{sz}
+matrix of random samples is generated.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/laplace_rnd.m
+ at anchor{doc-laplace_rnd}
+ at deftypefn {Function File} {} laplace_rnd (@var{r}, @var{c})
+ at deftypefnx {Function File} {} laplace_rnd (@var{sz});
+Return an @var{r} by @var{c} matrix of random numbers from the
+Laplace distribution.  Or if @var{sz} is a vector, create a matrix of
+ at var{sz}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/logistic_rnd.m
+ at anchor{doc-logistic_rnd}
+ at deftypefn {Function File} {} logistic_rnd (@var{r}, @var{c})
+ at deftypefnx {Function File} {} logistic_rnd (@var{sz})
+Return an @var{r} by @var{c} matrix of random numbers from the
+logistic distribution.  Or if @var{sz} is a vector, create a matrix of
+ at var{sz}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/lognrnd.m
+ at anchor{doc-lognrnd}
+ at deftypefn {Function File} {} lognrnd (@var{mu}, @var{sigma}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} lognrnd (@var{mu}, @var{sigma}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+lognormal distribution with parameters @var{mu} and @var{sigma}.  Both
+ at var{mu} and @var{sigma} must be scalar or of size @var{r} by @var{c}.
+Or if @var{sz} is a vector, create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{mu} and @var{sigma}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/nbinrnd.m
+ at anchor{doc-nbinrnd}
+ at deftypefn {Function File} {} nbinrnd (@var{n}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} nbinrnd (@var{n}, @var{p}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the Pascal
+(negative binomial) distribution with parameters @var{n} and @var{p}.
+Both @var{n} and @var{p} must be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{n} and @var{p}.  Or if @var{sz} is a vector, 
+create a matrix of size @var{sz}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/normrnd.m
+ at anchor{doc-normrnd}
+ at deftypefn {Function File} {} normrnd (@var{m}, @var{s}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} normrnd (@var{m}, @var{s}, @var{sz})
+Return an @var{r} by @var{c}  or @code{size (@var{sz})} matrix of
+random samples from the normal distribution with parameters mean @var{m} 
+and standard deviation @var{s}.  Both @var{m} and @var{s} must be scalar 
+or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{m} and @var{s}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/poissrnd.m
+ at anchor{doc-poissrnd}
+ at deftypefn {Function File} {} poissrnd (@var{lambda}, @var{r}, @var{c})
+Return an @var{r} by @var{c} matrix of random samples from the
+Poisson distribution with parameter @var{lambda}, which must be a 
+scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{lambda}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/trnd.m
+ at anchor{doc-trnd}
+ at deftypefn {Function File} {} trnd (@var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} trnd (@var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the t
+(Student) distribution with @var{n} degrees of freedom.  @var{n} must
+be a scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a
+vector create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{n}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unidrnd.m
+ at anchor{doc-unidrnd}
+ at deftypefn {Function File} {} unidrnd (@var{mx});
+ at deftypefnx {Function File} {} unidrnd (@var{mx}, @var{v});
+ at deftypefnx {Function File} {} unidrnd (@var{mx}, @var{m}, @var{n}, @dots{});
+Return random values from discrete uniform distribution, with maximum
+value(s) given by the integer @var{mx}, which may be a scalar or
+multidimensional array.
+
+If @var{mx} is a scalar, the size of the result is specified by
+the vector @var{v}, or by the optional arguments @var{m}, @var{n},
+ at dots{}.  Otherwise, the size of the result is the same as the size
+of @var{mx}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/unifrnd.m
+ at anchor{doc-unifrnd}
+ at deftypefn {Function File} {} unifrnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} unifrnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the uniform distribution on [@var{a}, @var{b}]. 
+Both @var{a} and @var{b} must be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/wblrnd.m
+ at anchor{doc-wblrnd}
+ at deftypefn {Function File} {} wblrnd (@var{scale}, @var{shape}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} wblrnd (@var{scale}, @var{shape}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+Weibull distribution with parameters @var{scale} and @var{shape}
+which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+is a vector return a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{alpha} and @var{sigma}.
+ at end deftypefn
+
+
+ at c ./statistics/distributions/wienrnd.m
+ at anchor{doc-wienrnd}
+ at deftypefn {Function File} {} wienrnd (@var{t}, @var{d}, @var{n})
+Return a simulated realization of the @var{d}-dimensional Wiener Process
+on the interval [0, @var{t}].  If @var{d} is omitted, @var{d} = 1 is
+used.  The first column of the return matrix contains time, the
+remaining columns contain the Wiener process.
+
+The optional parameter @var{n} gives the number of summands used for
+simulating the process over an interval of length 1.  If @var{n} is
+omitted, @var{n} = 1000 is used.
+ at end deftypefn
+
+
diff --git a/doc/interpreter/stats.txi b/doc/interpreter/stats.txi
new file mode 100644
index 0000000..01c03d2
--- /dev/null
+++ b/doc/interpreter/stats.txi
@@ -0,0 +1,663 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+ at c               2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Statistics
+ at chapter Statistics
+
+Octave has support for various statistical methods.  This includes
+basic descriptive statistics, statistical tests, random number generation,
+and much more.
+
+The functions that analyze data all assume that multidimensional data
+is arranged in a matrix where each row is an observation, and each
+column is a variable.  So, the matrix defined by
+
+ at example
+ at group
+a = [ 0.9, 0.7;
+      0.1, 0.1;
+      0.5, 0.4 ];
+ at end group
+ at end example
+
+ at noindent
+contains three observations from a two-dimensional distribution.
+While this is the default data arrangement, most functions support
+different arrangements.
+
+It should be noted that the statistics functions don't test for data
+containing NaN, NA, or Inf.  Such values need to be handled explicitly.
+
+ at menu
+* Descriptive Statistics::
+* Basic Statistical Functions:: 
+* Statistical Plots:: 
+* Tests::                       
+* Models::                      
+* Distributions::     
+* Random Number Generation::          
+ at end menu
+
+ at node Descriptive Statistics
+ at section Descriptive Statistics
+
+Octave can compute various statistics such as the moments of a data set.
+
+ at DOCSTRING(mean)
+
+ at DOCSTRING(median)
+
+ at DOCSTRING(quantile)
+
+ at DOCSTRING(prctile)
+
+ at DOCSTRING(meansq)
+
+ at DOCSTRING(std)
+
+ at DOCSTRING(var)
+
+ at DOCSTRING(mode)
+
+ at DOCSTRING(cov)
+
+ at DOCSTRING(cor)
+
+ at DOCSTRING(corrcoef)
+
+ at DOCSTRING(kurtosis)
+
+ at DOCSTRING(skewness)
+
+ at DOCSTRING(statistics)
+
+ at DOCSTRING(moment)
+
+ at node Basic Statistical Functions
+ at section Basic Statistical Functions
+
+Octave also supports various helpful statistical functions.
+
+ at DOCSTRING(mahalanobis)
+
+ at DOCSTRING(center)
+
+ at DOCSTRING(studentize)
+
+ at DOCSTRING(nchoosek)
+
+ at DOCSTRING(histc)
+
+ at DOCSTRING(perms)
+
+ at DOCSTRING(values)
+
+ at DOCSTRING(table)
+
+ at DOCSTRING(spearman)
+
+ at DOCSTRING(run_count)
+
+ at DOCSTRING(ranks)
+
+ at DOCSTRING(range)
+
+ at DOCSTRING(probit)
+
+ at DOCSTRING(logit)
+
+ at DOCSTRING(cloglog)
+
+ at DOCSTRING(kendall)
+
+ at DOCSTRING(iqr)
+
+ at DOCSTRING(cut)
+
+ at node Statistical Plots
+ at section Statistical Plots
+
+ at c Should hist be moved to here, or perhaps the qqplot and ppplot
+ at c functions should be moved to the Plotting Chapter?
+
+Octave can create Quantile Plots (QQ-Plots), and Probability Plots
+(PP-Plots).  These are simple graphical tests for determining if a
+data set comes from a certain distribution.
+
+Note that Octave can also show histograms of data
+using the @code{hist} function as described in
+ at ref{Two-Dimensional Plots}.
+
+ at DOCSTRING(qqplot)
+
+ at DOCSTRING(ppplot)
+
+ at node Tests
+ at section Tests
+
+Octave can perform several different statistical tests.  The following
+table summarizes the available tests.
+
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & # \vrule width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& @strong{Hypothesis} && {\bf Test Functions} &\cr
+\noalign{\hrule}
+& Equal mean values && anova, hotelling\_test2, t\_test\_2, &\cr
+&                   && welch\_test, wilcoxon\_test, z\_test\_2 &\cr
+& Equal medians && kruskal\_wallis\_test, sign\_test &\cr
+& Equal variances && bartlett\_test, manova, var\_test &\cr
+& Equal distributions && chisquare\_test\_homogeneity, &\cr
+&                     && kolmogorov\_smirnov\_test\_2, u\_test &\cr
+& Equal marginal frequencies && mcnemar\_test &\cr
+& Equal success probabilities && prop\_test\_2 &\cr
+& Independent observations && chisquare\_test\_independence, &\cr
+&                          && run\_test &\cr
+& Uncorrelated observations && cor\_test &\cr
+& Given mean value && hotelling\_test, t\_test, z\_test &\cr
+& Observations from distribution && kolmogorov\_smirnov\_test &\cr
+& Regression && f\_test\_regression, t\_test\_regression &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .4 .5
+ at item @strong{Hypothesis}
+  @tab @strong{Test Functions}
+ at item Equal mean values
+  @tab @code{anova}, @code{hotelling_test2}, @code{t_test_2},
+       @code{welch_test}, @code{wilcoxon_test}, @code{z_test_2}
+ at item Equal medians
+  @tab @code{kruskal_wallis_test}, @code{sign_test}
+ at item Equal variances
+  @tab @code{bartlett_test}, @code{manova}, @code{var_test}
+ at item Equal distributions
+  @tab @code{chisquare_test_homogeneity}, @code{kolmogorov_smirnov_test_2},
+       @code{u_test}
+ at item Equal marginal frequencies
+  @tab @code{mcnemar_test}
+ at item Equal success probabilities
+  @tab @code{prop_test_2}
+ at item Independent observations
+  @tab @code{chisquare_test_independence}, @code{run_test}
+ at item Uncorrelated observations
+  @tab @code{cor_test}
+ at item Given mean value
+  @tab @code{hotelling_test}, @code{t_test}, @code{z_test}
+ at item Observations from given distribution
+  @tab @code{kolmogorov_smirnov_test}
+ at item Regression
+  @tab @code{f_test_regression}, @code{t_test_regression}
+ at end multitable
+ at end ifnottex
+
+The tests return a p-value that describes the outcome of the test.
+Assuming that the test hypothesis is true, the p-value is the probability
+of obtaining a worse result than the observed one.  So large p-values
+corresponds to a successful test.  Usually a test hypothesis is accepted
+if the p-value exceeds @math{0.05}.
+
+ at DOCSTRING(anova)
+
+ at DOCSTRING(bartlett_test)
+
+ at DOCSTRING(chisquare_test_homogeneity)
+
+ at DOCSTRING(chisquare_test_independence)
+
+ at DOCSTRING(cor_test)
+
+ at DOCSTRING(f_test_regression)
+
+ at DOCSTRING(hotelling_test)
+
+ at DOCSTRING(hotelling_test_2)
+
+ at DOCSTRING(kolmogorov_smirnov_test)
+
+ at DOCSTRING(kolmogorov_smirnov_test_2)
+
+ at DOCSTRING(kruskal_wallis_test)
+
+ at DOCSTRING(manova)
+
+ at DOCSTRING(mcnemar_test)
+
+ at DOCSTRING(prop_test_2)
+
+ at DOCSTRING(run_test)
+
+ at DOCSTRING(sign_test)
+
+ at DOCSTRING(t_test)
+
+ at DOCSTRING(t_test_2)
+
+ at DOCSTRING(t_test_regression)
+
+ at DOCSTRING(u_test)
+
+ at DOCSTRING(var_test)
+
+ at DOCSTRING(welch_test)
+
+ at DOCSTRING(wilcoxon_test)
+
+ at DOCSTRING(z_test)
+
+ at DOCSTRING(z_test_2)
+
+ at node Models
+ at section Models
+
+ at DOCSTRING(logistic_regression)
+
+ at node Distributions
+ at section Distributions
+
+Octave has functions for computing the Probability Density Function
+(PDF), the Cumulative Distribution function (CDF), and the quantile
+(the inverse of the CDF) of a large number of distributions.
+
+The following table summarizes the supported distributions (in 
+alphabetical order).
+
+ at c Do the table explicitly in TeX if possible to get a better layout.
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & \vrule # & # \hfil & \vrule # & # \hfil &
+# \vrule width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& {\bf Distribution} && {\bf PDF}      && {\bf CDF}     && {\bf Quantile}&\cr
+\noalign{\hrule}
+&Beta         && betapdf        && betacdf       && betainv&\cr
+&Binomial     && binopdf        && binocdf       && binoinv&\cr
+&Cauchy       && cauchy\_pdf    && cauchy\_cdf   && cauchy\_inv&\cr
+&Chi-Square   && chi2pdf        && chi2cdf       && chi2inv&\cr
+&Univariate Discrete       && discrete\_pdf  && discrete\_cdf && discrete\_inv&\cr
+&Empirical    && empirical\_pdf  && empirical\_cdf && empirical\_inv&\cr
+&Exponential  && exppdf         && expcdf        && expinv&\cr
+&F            && fpdf           && fcdf          && finv&\cr
+&Gamma        && gampdf         && gamcdf        && gaminv&\cr
+&Geometric    && geopdf         && geocdf        && geoinv&\cr
+&Hypergeometric            && hygepdf      && hygecdf       && hygeinv&\cr
+&Kolmogorov Smirnov && {\it Not Available} && kolmogorov\_&& {\it Not Available}&\cr
+&             &&                && smirnov\_cdf &&&\cr
+&Laplace      && laplace\_pdf    && laplace\_cdf   && laplace\_inv&\cr
+&Logistic     && logistic\_pdf   && logistic\_cdf  && logistic\_inv&\cr
+&Log-Normal   && lognpdf        && logncdf       && logninv&\cr
+&Pascal       && nbinpdf        && nbincdf       && nbininv&\cr
+&Univariate Normal && normpdf   && normcdf       && norminv&\cr
+&Poisson      && poisspdf       && poisscdf      && poissinv&\cr
+&t (Student)  && tpdf           && tcdf          && tinv&\cr
+&Univariate Discrete && unidpdf && unidcdf       && unidinv&\cr
+&Uniform      && unifpdf        && unifcdf       && unifinv&\cr
+&Weibull      && wblpdf         && wblcdf        && wblinv&\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .31 .23 .23 .23
+ at item @strong{Distribution}
+  @tab @strong{PDF}
+  @tab @strong{CDF}
+  @tab @strong{Quantile}
+ at item Beta Distribution
+  @tab @code{betapdf}
+  @tab @code{betacdf}
+  @tab @code{betainv}
+ at item Binomial Distribution
+  @tab @code{binopdf}
+  @tab @code{binocdf}
+  @tab @code{binoinv}
+ at item Cauchy Distribution
+  @tab @code{cauchy_pdf}
+  @tab @code{cauchy_cdf}
+  @tab @code{cauchy_inv}
+ at item Chi-Square Distribution
+  @tab @code{chi2pdf}
+  @tab @code{chi2cdf}
+  @tab @code{chi2inv}
+ at item Univariate Discrete Distribution
+  @tab @code{discrete_pdf}
+  @tab @code{discrete_cdf}
+  @tab @code{discrete_inv}
+ at item Empirical Distribution
+  @tab @code{empirical_pdf}
+  @tab @code{empirical_cdf}
+  @tab @code{empirical_inv}
+ at item Exponential Distribution
+  @tab @code{exppdf}
+  @tab @code{expcdf}
+  @tab @code{expinv}
+ at item F Distribution
+  @tab @code{fpdf}
+  @tab @code{fcdf}
+  @tab @code{finv}
+ at item Gamma Distribution
+  @tab @code{gampdf}
+  @tab @code{gamcdf}
+  @tab @code{gaminv}
+ at item Geometric Distribution
+  @tab @code{geopdf}
+  @tab @code{geocdf}
+  @tab @code{geoinv}
+ at item Hypergeometric Distribution
+  @tab @code{hygepdf}
+  @tab @code{hygecdf}
+  @tab @code{hygeinv}
+ at item Kolmogorov Smirnov Distribution
+  @tab @emph{Not Available}
+  @tab @code{kolmogorov_smirnov_cdf}
+  @tab @emph{Not Available}
+ at item Laplace Distribution
+  @tab @code{laplace_pdf}
+  @tab @code{laplace_cdf}
+  @tab @code{laplace_inv}
+ at item Logistic Distribution
+  @tab @code{logistic_pdf}
+  @tab @code{logistic_cdf}
+  @tab @code{logistic_inv}
+ at item Log-Normal Distribution
+  @tab @code{lognpdf}
+  @tab @code{logncdf}
+  @tab @code{logninv}
+ at item Pascal Distribution
+  @tab @code{nbinpdf}
+  @tab @code{nbincdf}
+  @tab @code{nbininv}
+ at item Univariate Normal Distribution
+  @tab @code{normpdf}
+  @tab @code{normcdf}
+  @tab @code{norminv}
+ at item Poisson Distribution
+  @tab @code{poisspdf}
+  @tab @code{poisscdf}
+  @tab @code{poissinv}
+ at item t (Student) Distribution
+  @tab @code{tpdf}
+  @tab @code{tcdf}
+  @tab @code{tinv}
+ at item Univariate Discrete Distribution
+  @tab @code{unidpdf}
+  @tab @code{unidcdf}
+  @tab @code{unidinv}
+ at item Uniform Distribution
+  @tab @code{unifpdf}
+  @tab @code{unifcdf}
+  @tab @code{unifinv}
+ at item Weibull Distribution
+  @tab @code{wblpdf}
+  @tab @code{wblcdf}
+  @tab @code{wblinv}
+ at end multitable
+ at end ifnottex
+
+ at DOCSTRING(betacdf)
+
+ at DOCSTRING(betainv)
+
+ at DOCSTRING(betapdf)
+
+ at DOCSTRING(binocdf)
+
+ at DOCSTRING(binoinv)
+
+ at DOCSTRING(binopdf)
+
+ at DOCSTRING(cauchy_cdf)
+
+ at DOCSTRING(cauchy_inv)
+
+ at DOCSTRING(cauchy_pdf)
+
+ at DOCSTRING(chi2cdf)
+
+ at DOCSTRING(chi2inv)
+
+ at DOCSTRING(chi2pdf)
+
+ at DOCSTRING(discrete_cdf)
+
+ at DOCSTRING(discrete_inv)
+
+ at DOCSTRING(discrete_pdf)
+
+ at DOCSTRING(empirical_cdf)
+
+ at DOCSTRING(empirical_inv)
+
+ at DOCSTRING(empirical_pdf)
+
+ at DOCSTRING(expcdf)
+
+ at DOCSTRING(expinv)
+
+ at DOCSTRING(exppdf)
+
+ at DOCSTRING(fcdf)
+
+ at DOCSTRING(finv)
+
+ at DOCSTRING(fpdf)
+
+ at DOCSTRING(gamcdf)
+
+ at DOCSTRING(gaminv)
+
+ at DOCSTRING(gampdf)
+
+ at DOCSTRING(geocdf)
+
+ at DOCSTRING(geoinv)
+
+ at DOCSTRING(geopdf)
+
+ at DOCSTRING(hygecdf)
+
+ at DOCSTRING(hygeinv)
+
+ at DOCSTRING(hygepdf)
+
+ at DOCSTRING(kolmogorov_smirnov_cdf)
+
+ at DOCSTRING(laplace_cdf)
+
+ at DOCSTRING(laplace_inv)
+
+ at DOCSTRING(laplace_pdf)
+
+ at DOCSTRING(logistic_cdf)
+
+ at DOCSTRING(logistic_inv)
+
+ at DOCSTRING(logistic_pdf)
+
+ at DOCSTRING(logncdf)
+
+ at DOCSTRING(logninv)
+
+ at DOCSTRING(lognpdf)
+
+ at DOCSTRING(nbincdf)
+
+ at DOCSTRING(nbininv)
+
+ at DOCSTRING(nbinpdf)
+
+ at DOCSTRING(normcdf)
+
+ at DOCSTRING(norminv)
+
+ at DOCSTRING(normpdf)
+
+ at DOCSTRING(poisscdf)
+
+ at DOCSTRING(poissinv)
+
+ at DOCSTRING(poisspdf)
+
+ at DOCSTRING(tcdf)
+
+ at DOCSTRING(tinv)
+
+ at DOCSTRING(tpdf)
+
+ at DOCSTRING(unidcdf)
+
+ at DOCSTRING(unidinv)
+
+ at DOCSTRING(unidpdf)
+
+ at DOCSTRING(unifcdf)
+
+ at DOCSTRING(unifinv)
+
+ at DOCSTRING(unifpdf)
+
+ at DOCSTRING(wblcdf)
+
+ at DOCSTRING(wblinv)
+
+ at DOCSTRING(wblpdf)
+
+ at node Random Number Generation
+ at section Random Number Generation
+
+Octave can generate random numbers from a large number of distributions.
+The random number generators are based on the random number generators
+described in @ref{Special Utility Matrices}.
+ at c Should rand, randn, rande, randp, and randg be moved to here?
+
+The following table summarizes the available random number generators
+(in alphabetical order).
+
+ at tex
+\vskip 6pt
+{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt 
+\halign{
+\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em &
+# \hfil & \vrule # & # \hfil & # \vrule width 0.6pt \tabskip=0pt\cr
+\noalign{\hrule height 0.6pt}
+& {\bf Distribution}                && {\bf Function} &\cr
+\noalign{\hrule}
+& Beta Distribution                 && betarnd &\cr
+& Binomial Distribution             && binornd &\cr
+& Cauchy Distribution               && cauchy\_rnd &\cr
+& Chi-Square Distribution           && chi2rnd &\cr
+& Univariate Discrete Distribution  && discrete\_rnd &\cr
+& Empirical Distribution            && empirical\_rnd &\cr
+& Exponential Distribution          && exprnd &\cr
+& F Distribution                    && frnd &\cr
+& Gamma Distribution                && gamrnd &\cr
+& Geometric Distribution            && geornd &\cr
+& Hypergeometric Distribution       && hygernd &\cr
+& Laplace Distribution              && laplace\_rnd &\cr
+& Logistic Distribution             && logistic\_rnd &\cr
+& Log-Normal Distribution           && lognrnd &\cr
+& Pascal Distribution               && nbinrnd &\cr
+& Univariate Normal Distribution    && normrnd &\cr
+& Poisson Distribution              && poissrnd &\cr
+& t (Student) Distribution          && trnd &\cr
+& Univariate Discrete Distribution  && unidrnd &\cr
+& Uniform Distribution              && unifrnd &\cr
+& Weibull Distribution              && wblrnd &\cr
+& Wiener Process                    && wienrnd &\cr
+\noalign{\hrule height 0.6pt}
+}}\hfill}}
+ at end tex
+ at ifnottex
+ at multitable @columnfractions .4 .3
+ at item @strong{Distribution}             @tab @strong{Function}
+ at item Beta Distribution                 @tab @code{betarnd}
+ at item Binomial Distribution             @tab @code{binornd}
+ at item Cauchy Distribution               @tab @code{cauchy_rnd}
+ at item Chi-Square Distribution           @tab @code{chi2rnd}
+ at item Univariate Discrete Distribution  @tab @code{discrete_rnd}
+ at item Empirical Distribution            @tab @code{empirical_rnd}
+ at item Exponential Distribution          @tab @code{exprnd}
+ at item F Distribution                    @tab @code{frnd}
+ at item Gamma Distribution                @tab @code{gamrnd}
+ at item Geometric Distribution            @tab @code{geornd}
+ at item Hypergeometric Distribution       @tab @code{hygernd}
+ at item Laplace Distribution              @tab @code{laplace_rnd}
+ at item Logistic Distribution             @tab @code{logistic_rnd}
+ at item Log-Normal Distribution           @tab @code{lognrnd}
+ at item Pascal Distribution               @tab @code{nbinrnd}
+ at item Univariate Normal Distribution    @tab @code{normrnd}
+ at item Poisson Distribution              @tab @code{poissrnd}
+ at item t (Student) Distribution          @tab @code{trnd}
+ at item Univariate Discrete Distribution  @tab @code{unidrnd}
+ at item Uniform Distribution              @tab @code{unifrnd}
+ at item Weibull Distribution              @tab @code{wblrnd}
+ at item Wiener Process                    @tab @code{wienrnd}
+ at end multitable
+ at end ifnottex
+
+ at DOCSTRING(betarnd)
+
+ at DOCSTRING(binornd)
+
+ at DOCSTRING(cauchy_rnd)
+
+ at DOCSTRING(chi2rnd)
+
+ at DOCSTRING(discrete_rnd)
+
+ at DOCSTRING(empirical_rnd)
+
+ at DOCSTRING(exprnd)
+
+ at DOCSTRING(frnd)
+
+ at DOCSTRING(gamrnd)
+
+ at DOCSTRING(geornd)
+
+ at DOCSTRING(hygernd)
+
+ at DOCSTRING(laplace_rnd)
+
+ at DOCSTRING(logistic_rnd)
+
+ at DOCSTRING(lognrnd)
+
+ at DOCSTRING(nbinrnd)
+
+ at DOCSTRING(normrnd)
+
+ at DOCSTRING(poissrnd)
+
+ at DOCSTRING(trnd)
+
+ at DOCSTRING(unidrnd)
+
+ at DOCSTRING(unifrnd)
+
+ at DOCSTRING(wblrnd)
+
+ at DOCSTRING(wienrnd)
+
diff --git a/doc/interpreter/stmp-html b/doc/interpreter/stmp-html
new file mode 100644
index 0000000..e69de29
diff --git a/doc/interpreter/stmt.texi b/doc/interpreter/stmt.texi
new file mode 100644
index 0000000..048fc14
--- /dev/null
+++ b/doc/interpreter/stmt.texi
@@ -0,0 +1,912 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2007, 2008, 2009
+ at c               John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Statements
+ at chapter Statements
+ at cindex statements
+
+Statements may be a simple constant expression or a complicated list of
+nested loops and conditional statements.
+
+ at dfn{Control statements} such as @code{if}, @code{while}, and so on
+control the flow of execution in Octave programs.  All the control
+statements start with special keywords such as @code{if} and
+ at code{while}, to distinguish them from simple expressions.
+Many control statements contain other statements; for example, the
+ at code{if} statement contains another statement which may or may not be
+executed.
+
+ at cindex @code{end} statement
+Each control statement has a corresponding @dfn{end} statement that
+marks the end of the control statement.  For example, the
+keyword @code{endif} marks the end of an @code{if} statement, and
+ at code{endwhile} marks the end of a @code{while} statement.  You can use
+the keyword @code{end} anywhere a more specific end keyword is expected,
+but using the more specific keywords is preferred because if you use
+them, Octave is able to provide better diagnostics for mismatched or
+missing end tokens.
+
+The list of statements contained between keywords like @code{if} or
+ at code{while} and the corresponding end statement is called the
+ at dfn{body} of a control statement.
+
+ at menu
+* The @code{if} Statement::            
+* The @code{switch} Statement::        
+* The @code{while} Statement::         
+* The @code{do-until} Statement::      
+* The @code{for} Statement::           
+* The @code{break} Statement::         
+* The @code{continue} Statement::      
+* The @code{unwind_protect} Statement::  
+* The @code{try} Statement::           
+* Continuation Lines::          
+ at end menu
+
+ at node The @code{if} Statement
+ at section The @code{if} Statement
+ at cindex @code{if} statement
+ at cindex @code{else} statement
+ at cindex @code{elseif} statement
+ at cindex @code{endif} statement
+
+The @code{if} statement is Octave's decision-making statement.  There
+are three basic forms of an @code{if} statement.  In its simplest form,
+it looks like this:
+
+ at example
+ at group
+if (@var{condition})
+  @var{then-body}
+endif
+ at end group
+ at end example
+
+ at noindent
+ at var{condition} is an expression that controls what the rest of the
+statement will do.  The @var{then-body} is executed only if
+ at var{condition} is true.
+
+The condition in an @code{if} statement is considered true if its value
+is non-zero, and false if its value is zero.  If the value of the
+conditional expression in an @code{if} statement is a vector or a
+matrix, it is considered true only if it is non-empty and @emph{all}
+of the elements are non-zero.
+
+The second form of an if statement looks like this:
+
+ at example
+ at group
+if (@var{condition})
+  @var{then-body}
+else
+  @var{else-body}
+endif
+ at end group
+ at end example
+
+ at noindent
+If @var{condition} is true, @var{then-body} is executed; otherwise,
+ at var{else-body} is executed.
+
+Here is an example:
+
+ at example
+ at group
+if (rem (x, 2) == 0)
+  printf ("x is even\n");
+else
+  printf ("x is odd\n");
+endif
+ at end group
+ at end example
+
+In this example, if the expression @code{rem (x, 2) == 0} is true (that
+is, the value of @code{x} is divisible by 2), then the first
+ at code{printf} statement is evaluated, otherwise the second @code{printf}
+statement is evaluated.
+
+The third and most general form of the @code{if} statement allows
+multiple decisions to be combined in a single statement.  It looks like
+this:
+
+ at example
+ at group
+if (@var{condition})
+  @var{then-body}
+elseif (@var{condition})
+  @var{elseif-body}
+else
+  @var{else-body}
+endif
+ at end group
+ at end example
+
+ at noindent
+Any number of @code{elseif} clauses may appear.  Each condition is
+tested in turn, and if one is found to be true, its corresponding
+ at var{body} is executed.  If none of the conditions are true and the
+ at code{else} clause is present, its body is executed.  Only one
+ at code{else} clause may appear, and it must be the last part of the
+statement.
+
+In the following example, if the first condition is true (that is, the
+value of @code{x} is divisible by 2), then the first @code{printf}
+statement is executed.  If it is false, then the second condition is
+tested, and if it is true (that is, the value of @code{x} is divisible
+by 3), then the second @code{printf} statement is executed.  Otherwise,
+the third @code{printf} statement is performed.
+
+ at example
+ at group
+if (rem (x, 2) == 0)
+  printf ("x is even\n");
+elseif (rem (x, 3) == 0)
+  printf ("x is odd and divisible by 3\n");
+else
+  printf ("x is odd\n");
+endif
+ at end group
+ at end example
+
+Note that the @code{elseif} keyword must not be spelled @code{else if},
+as is allowed in Fortran.  If it is, the space between the @code{else}
+and @code{if} will tell Octave to treat this as a new @code{if}
+statement within another @code{if} statement's @code{else} clause.  For
+example, if you write
+
+ at example
+ at group
+if (@var{c1})
+  @var{body-1}
+else if (@var{c2})
+  @var{body-2}
+endif
+ at end group
+ at end example
+
+ at noindent
+Octave will expect additional input to complete the first @code{if}
+statement.  If you are using Octave interactively, it will continue to
+prompt you for additional input.  If Octave is reading this input from a
+file, it may complain about missing or mismatched @code{end} statements,
+or, if you have not used the more specific @code{end} statements
+(@code{endif}, @code{endfor}, etc.), it may simply produce incorrect
+results, without producing any warning messages.
+
+It is much easier to see the error if we rewrite the statements above
+like this,
+
+ at example
+ at group
+if (@var{c1})
+  @var{body-1}
+else
+  if (@var{c2})
+    @var{body-2}
+  endif
+ at end group
+ at end example
+
+ at noindent
+using the indentation to show how Octave groups the statements.
+ at xref{Functions and Scripts}.
+
+ at node The @code{switch} Statement
+ at section The @code{switch} Statement
+ at cindex @code{switch} statement
+ at cindex @code{case} statement
+ at cindex @code{otherwise} statement
+ at cindex @code{endswitch} statement
+
+It is very common to take different actions depending on the value of
+one variable.  This is possible using the @code{if} statement in the
+following way
+
+ at example
+ at group
+if (X == 1)
+  do_something ();
+elseif (X == 2)
+  do_something_else ();
+else
+  do_something_completely_different ();
+endif
+ at end group
+ at end example
+
+ at noindent
+This kind of code can however be very cumbersome to both write and
+maintain.  To overcome this problem Octave supports the @code{switch}
+statement.  Using this statement, the above example becomes
+
+ at example
+ at group
+switch (X)
+  case 1
+    do_something ();
+  case 2
+    do_something_else ();
+  otherwise
+    do_something_completely_different ();
+endswitch
+ at end group
+ at end example
+
+ at noindent
+This code makes the repetitive structure of the problem more explicit,
+making the code easier to read, and hence maintain.  Also, if the
+variable @code{X} should change its name, only one line would need
+changing compared to one line per case when @code{if} statements are
+used.
+
+The general form of the @code{switch} statement is
+
+ at example
+ at group
+switch @var{expression}
+  case @var{label}
+    @var{command_list}
+  case @var{label}
+    @var{command_list}
+  @dots{}
+
+  otherwise
+    @var{command_list}
+endswitch
+ at end group
+ at end example
+
+ at noindent
+where @var{label} can be any expression.  However, duplicate
+ at var{label} values are not detected, and only the @var{command_list}
+corresponding to the first match will be executed.  For the
+ at code{switch} statement to be meaningful at least one
+ at code{case @var{label} @var{command_list}} clause must be present,
+while the @code{otherwise @var{command_list}} clause is optional.
+
+If @var{label} is a cell array the corresponding @var{command_list}
+is executed if @emph{any} of the elements of the cell array match
+ at var{expression}.  As an example, the following program will print
+ at samp{Variable is either 6 or 7}.
+
+ at example
+ at group
+A = 7;
+switch A
+  case @{ 6, 7 @}
+    printf ("variable is either 6 or 7\n");
+  otherwise
+    printf ("variable is neither 6 nor 7\n");
+endswitch
+ at end group
+ at end example
+
+As with all other specific @code{end} keywords, @code{endswitch} may be
+replaced by @code{end}, but you can get better diagnostics if you use
+the specific forms.
+
+ at c Strings can be matched
+
+One advantage of using the @code{switch} statement compared to using
+ at code{if} statements is that the @var{label}s can be strings.  If an
+ at code{if} statement is used it is @emph{not} possible to write
+
+ at example
+if (X == "a string") # This is NOT valid
+ at end example
+
+ at noindent
+since a character-to-character comparison between @code{X} and the
+string will be made instead of evaluating if the strings are equal.
+This special-case is handled by the @code{switch} statement, and it
+is possible to write programs that look like this
+
+ at example
+ at group
+switch (X)
+  case "a string"
+    do_something
+  @dots{}
+endswitch
+ at end group
+ at end example
+
+ at menu
+* Notes for the C programmer::  
+ at end menu
+
+ at node Notes for the C programmer
+ at subsection Notes for the C programmer
+
+The @code{switch} statement is also available in the widely used C
+programming language.  There are, however, some differences
+between the statement in Octave and C
+
+ at itemize @bullet
+ at item
+Cases are exclusive, so they don't `fall through' as do the cases
+in the @code{switch} statement of the C language.
+
+ at item
+The @var{command_list} elements are not optional.  Making the list
+optional would have meant requiring a separator between the label and
+the command list.  Otherwise, things like
+
+ at example
+ at group
+switch (foo)
+  case (1) -2
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+would produce surprising results, as would
+
+ at example
+ at group
+switch (foo)
+  case (1)
+  case (2)
+    doit ();
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+particularly for C programmers.  If @code{doit()} should be executed if
+ at var{foo} is either @code{1} or @code{2}, the above code should be
+written with a cell array like this
+
+ at example
+ at group
+switch (foo)
+  case @{ 1, 2 @}
+    doit ();
+  @dots{}
+ at end group
+ at end example
+ at end itemize
+
+ at node The @code{while} Statement
+ at section The @code{while} Statement
+ at cindex @code{while} statement
+ at cindex @code{endwhile} statement
+ at cindex loop
+ at cindex body of a loop
+
+In programming, a @dfn{loop} means a part of a program that is (or at least can
+be) executed two or more times in succession.
+
+The @code{while} statement is the simplest looping statement in Octave.
+It repeatedly executes a statement as long as a condition is true.  As
+with the condition in an @code{if} statement, the condition in a
+ at code{while} statement is considered true if its value is non-zero, and
+false if its value is zero.  If the value of the conditional expression
+in a @code{while} statement is a vector or a matrix, it is considered
+true only if it is non-empty and @emph{all} of the elements are non-zero.
+
+Octave's @code{while} statement looks like this:
+
+ at example
+ at group
+while (@var{condition})
+  @var{body}
+endwhile
+ at end group
+ at end example
+
+ at noindent
+Here @var{body} is a statement or list of statements that we call the
+ at dfn{body} of the loop, and @var{condition} is an expression that
+controls how long the loop keeps running.
+
+The first thing the @code{while} statement does is test @var{condition}.
+If @var{condition} is true, it executes the statement @var{body}.  After
+ at var{body} has been executed, @var{condition} is tested again, and if it
+is still true, @var{body} is executed again.  This process repeats until
+ at var{condition} is no longer true.  If @var{condition} is initially
+false, the body of the loop is never executed.
+
+This example creates a variable @code{fib} that contains the first ten
+elements of the Fibonacci sequence.
+
+ at example
+ at group
+fib = ones (1, 10);
+i = 3;
+while (i <= 10)
+  fib (i) = fib (i-1) + fib (i-2);
+  i++;
+endwhile
+ at end group
+ at end example
+
+ at noindent
+Here the body of the loop contains two statements.
+
+The loop works like this: first, the value of @code{i} is set to 3.
+Then, the @code{while} tests whether @code{i} is less than or equal to
+10.  This is the case when @code{i} equals 3, so the value of the
+ at code{i}-th element of @code{fib} is set to the sum of the previous two
+values in the sequence.  Then the @code{i++} increments the value of
+ at code{i} and the loop repeats.  The loop terminates when @code{i}
+reaches 11.
+
+A newline is not required between the condition and the
+body; but using one makes the program clearer unless the body is very
+simple.
+
+ at node The @code{do-until} Statement
+ at section The @code{do-until} Statement
+ at cindex @code{do-until} statement
+
+The @code{do-until} statement is similar to the @code{while} statement,
+except that it repeatedly executes a statement until a condition becomes
+true, and the test of the condition is at the end of the loop, so the
+body of the loop is always executed at least once.  As with the
+condition in an @code{if} statement, the condition in a @code{do-until}
+statement is considered true if its value is non-zero, and false if its
+value is zero.  If the value of the conditional expression in a
+ at code{do-until} statement is a vector or a matrix, it is considered 
+true only if it is non-empty and @emph{all} of the elements are non-zero.
+
+Octave's @code{do-until} statement looks like this:
+
+ at example
+ at group
+do
+  @var{body}
+until (@var{condition})
+ at end group
+ at end example
+
+ at noindent
+Here @var{body} is a statement or list of statements that we call the
+ at dfn{body} of the loop, and @var{condition} is an expression that
+controls how long the loop keeps running.
+
+This example creates a variable @code{fib} that contains the first ten
+elements of the Fibonacci sequence.
+
+ at example
+ at group
+fib = ones (1, 10);
+i = 2;
+do
+  i++;
+  fib (i) = fib (i-1) + fib (i-2);
+until (i == 10)
+ at end group
+ at end example
+
+A newline is not required between the @code{do} keyword and the
+body; but using one makes the program clearer unless the body is very
+simple.
+
+ at node The @code{for} Statement
+ at section The @code{for} Statement
+ at cindex @code{for} statement
+ at cindex @code{endfor} statement
+
+The @code{for} statement makes it more convenient to count iterations of a
+loop.  The general form of the @code{for} statement looks like this:
+
+ at example
+ at group
+for @var{var} = @var{expression}
+  @var{body}
+endfor
+ at end group
+ at end example
+
+ at noindent
+where @var{body} stands for any statement or list of statements,
+ at var{expression} is any valid expression, and @var{var} may take several
+forms.  Usually it is a simple variable name or an indexed variable.  If
+the value of @var{expression} is a structure, @var{var} may also be a
+vector with two elements.  @xref{Looping Over Structure Elements}, below.
+
+The assignment expression in the @code{for} statement works a bit
+differently than Octave's normal assignment statement.  Instead of
+assigning the complete result of the expression, it assigns each column
+of the expression to @var{var} in turn.  If @var{expression} is a range,
+a row vector, or a scalar, the value of @var{var} will be a scalar each
+time the loop body is executed.  If @var{var} is a column vector or a
+matrix, @var{var} will be a column vector each time the loop body is
+executed.
+
+The following example shows another way to create a vector containing
+the first ten elements of the Fibonacci sequence, this time using the
+ at code{for} statement:
+
+ at example
+ at group
+fib = ones (1, 10);
+for i = 3:10
+  fib (i) = fib (i-1) + fib (i-2);
+endfor
+ at end group
+ at end example
+
+ at noindent
+This code works by first evaluating the expression @code{3:10}, to
+produce a range of values from 3 to 10 inclusive.  Then the variable
+ at code{i} is assigned the first element of the range and the body of the
+loop is executed once.  When the end of the loop body is reached, the
+next value in the range is assigned to the variable @code{i}, and the
+loop body is executed again.  This process continues until there are no
+more elements to assign.
+
+Within Octave is it also possible to iterate over matrices or cell arrays
+using the @code{for} statement.  For example consider
+
+ at example
+ at group
+disp("Loop over a matrix")
+for i = [1,3;2,4]
+  i
+endfor
+disp("Loop over a cell array")
+for i = @{1,"two";"three",4@}
+  i
+endfor
+ at end group 
+ at end example
+
+ at noindent
+In this case the variable @code{i} takes on the value of the columns of
+the matrix or cell matrix.  So the first loop iterates twice, producing
+two column vectors @code{[1;2]}, followed by @code{[3;4]}, and likewise
+for the loop over the cell array.  This can be extended to loops over
+multidimensional arrays.  For example
+
+ at example
+ at group
+a = [1,3;2,4]; b = cat(3, a, 2*a);
+for i = c
+  i
+endfor
+ at end group 
+ at end example
+
+ at noindent
+In the above case, the multidimensional matrix @var{c} is reshaped to a
+two-dimensional matrix as @code{reshape (c, rows(c),
+prod(size(c)(2:end)))} and then the same behavior as a loop over a two
+dimensional matrix is produced.
+
+Although it is possible to rewrite all @code{for} loops as @code{while}
+loops, the Octave language has both statements because often a
+ at code{for} loop is both less work to type and more natural to think of.
+Counting the number of iterations is very common in loops and it can be
+easier to think of this counting as part of looping rather than as
+something to do inside the loop.
+
+ at menu
+* Looping Over Structure Elements::  
+ at end menu
+
+ at node Looping Over Structure Elements
+ at subsection Looping Over Structure Elements
+ at cindex structure elements, looping over
+ at cindex looping over structure elements
+
+A special form of the @code{for} statement allows you to loop over all
+the elements of a structure:
+
+ at example
+ at group
+for [ @var{val}, @var{key} ] = @var{expression}
+  @var{body}
+endfor
+ at end group
+ at end example
+
+ at noindent
+In this form of the @code{for} statement, the value of @var{expression}
+must be a structure.  If it is, @var{key} and @var{val} are set to the
+name of the element and the corresponding value in turn, until there are
+no more elements.  For example,
+
+ at example
+ at group
+x.a = 1
+x.b = [1, 2; 3, 4]
+x.c = "string"
+for [val, key] = x
+  key
+  val
+endfor
+
+     @print{} key = a
+     @print{} val = 1
+     @print{} key = b
+     @print{} val =
+     @print{} 
+     @print{}   1  2
+     @print{}   3  4
+     @print{} 
+     @print{} key = c
+     @print{} val = string
+ at end group
+ at end example
+
+The elements are not accessed in any particular order.  If you need to
+cycle through the list in a particular way, you will have to use the
+function @code{fieldnames} and sort the list yourself.
+
+The @var{key} variable may also be omitted.  If it is, the brackets are
+also optional.  This is useful for cycling through the values of all the
+structure elements when the names of the elements do not need to be
+known.
+
+ at node The @code{break} Statement
+ at section The @code{break} Statement
+ at cindex @code{break} statement
+
+The @code{break} statement jumps out of the innermost @code{for} or
+ at code{while} loop that encloses it.  The @code{break} statement may only
+be used within the body of a loop.  The following example finds the
+smallest divisor of a given integer, and also identifies prime numbers:
+
+ at example
+ at group
+num = 103;
+div = 2;
+while (div*div <= num)
+  if (rem (num, div) == 0)
+    break;
+  endif
+  div++;
+endwhile
+if (rem (num, div) == 0)
+  printf ("Smallest divisor of %d is %d\n", num, div)
+else
+  printf ("%d is prime\n", num);
+endif
+ at end group
+ at end example
+
+When the remainder is zero in the first @code{while} statement, Octave
+immediately @dfn{breaks out} of the loop.  This means that Octave
+proceeds immediately to the statement following the loop and continues
+processing.  (This is very different from the @code{exit} statement
+which stops the entire Octave program.)
+
+Here is another program equivalent to the previous one.  It illustrates
+how the @var{condition} of a @code{while} statement could just as well
+be replaced with a @code{break} inside an @code{if}:
+
+ at example
+ at group
+num = 103;
+div = 2;
+while (1)
+  if (rem (num, div) == 0)
+    printf ("Smallest divisor of %d is %d\n", num, div);
+    break;
+  endif
+  div++;
+  if (div*div > num)
+    printf ("%d is prime\n", num);
+    break;
+  endif
+endwhile
+ at end group
+ at end example
+
+ at node The @code{continue} Statement
+ at section The @code{continue} Statement
+ at cindex @code{continue} statement
+
+The @code{continue} statement, like @code{break}, is used only inside
+ at code{for} or @code{while} loops.  It skips over the rest of the loop
+body, causing the next cycle around the loop to begin immediately.
+Contrast this with @code{break}, which jumps out of the loop altogether.
+Here is an example:
+
+ at example
+ at group
+# print elements of a vector of random
+# integers that are even.
+
+# first, create a row vector of 10 random
+# integers with values between 0 and 100:
+
+vec = round (rand (1, 10) * 100);
+
+# print what we're interested in:
+
+for x = vec
+  if (rem (x, 2) != 0)
+    continue;
+  endif
+  printf ("%d\n", x);
+endfor
+ at end group
+ at end example
+
+If one of the elements of @var{vec} is an odd number, this example skips
+the print statement for that element, and continues back to the first
+statement in the loop.
+
+This is not a practical example of the @code{continue} statement, but it
+should give you a clear understanding of how it works.  Normally, one
+would probably write the loop like this:
+
+ at example
+ at group
+for x = vec
+  if (rem (x, 2) == 0)
+    printf ("%d\n", x);
+  endif
+endfor
+ at end group
+ at end example
+
+ at node The @code{unwind_protect} Statement
+ at section The @code{unwind_protect} Statement
+ at cindex @code{unwind_protect} statement
+ at cindex @code{unwind_protect_cleanup}
+ at cindex @code{end_unwind_protect}
+
+Octave supports a limited form of exception handling modelled after the
+unwind-protect form of Lisp.  
+
+The general form of an @code{unwind_protect} block looks like this:
+
+ at example
+ at group
+unwind_protect
+  @var{body}
+unwind_protect_cleanup
+  @var{cleanup}
+end_unwind_protect
+ at end group
+ at end example
+
+ at noindent
+where @var{body} and @var{cleanup} are both optional and may contain any
+Octave expressions or commands.  The statements in @var{cleanup} are 
+guaranteed to be executed regardless of how control exits @var{body}.
+
+This is useful to protect temporary changes to global variables from
+possible errors.  For example, the following code will always restore
+the original value of the global variable @code{frobnosticate}
+even if an error occurs in the first part of the @code{unwind_protect}
+block.
+
+ at example
+ at group
+save_frobnosticate = frobnosticate;
+unwind_protect
+  frobnosticate = true;
+  @dots{}
+unwind_protect_cleanup
+  frobnosticate = save_frobnosticate;
+end_unwind_protect
+ at end group
+ at end example
+
+ at noindent
+Without @code{unwind_protect}, the value of @var{frobnosticate}
+would not be restored if an error occurs while evaluating the first part
+of the @code{unwind_protect} block because evaluation would stop at the
+point of the error and the statement to restore the value would not be
+executed.
+
+ at node The @code{try} Statement
+ at section The @code{try} Statement
+ at cindex @code{try} statement
+ at cindex @code{catch}
+ at cindex @code{end_try_catch}
+
+In addition to unwind_protect, Octave supports another limited form of
+exception handling.
+
+The general form of a @code{try} block looks like this:
+
+ at example
+ at group
+try
+  @var{body}
+catch
+  @var{cleanup}
+end_try_catch
+ at end group
+ at end example
+
+ at noindent
+where @var{body} and @var{cleanup} are both optional and may contain any
+Octave expressions or commands.  The statements in @var{cleanup} are
+only executed if an error occurs in @var{body}.
+
+No warnings or error messages are printed while @var{body} is
+executing.  If an error does occur during the execution of @var{body},
+ at var{cleanup} can use the function @code{lasterr} to access the text
+of the message that would have been printed.  This is the same
+as @code{eval (@var{try}, @var{catch})} but it is more efficient since
+the commands do not need to be parsed each time the @var{try} and
+ at var{catch} statements are evaluated.  @xref{Errors and Warnings}, for more
+information about the @code{lasterr} function.
+
+ at cindex continuation lines
+ at cindex @code{...} continuation marker
+ at cindex @code{\} continuation marker
+
+ at node Continuation Lines
+ at section Continuation Lines
+
+In the Octave language, most statements end with a newline character and
+you must tell Octave to ignore the newline character in order to
+continue a statement from one line to the next.  Lines that end with the
+characters @code{...} or @code{\} are joined with the following line
+before they are divided into tokens by Octave's parser.  For example,
+the lines
+
+ at example
+ at group
+x = long_variable_name ...
+    + longer_variable_name \
+    - 42
+ at end group
+ at end example
+
+ at noindent
+form a single statement.  The backslash character on the second line
+above is interpreted as a continuation character, @emph{not} as a division
+operator.
+
+For continuation lines that do not occur inside string constants,
+whitespace and comments may appear between the continuation marker and
+the newline character.  For example, the statement
+
+ at example
+ at group
+x = long_variable_name ...     # comment one
+    + longer_variable_name \   # comment two
+    - 42                       # last comment
+ at end group
+ at end example
+
+ at noindent
+is equivalent to the one shown above.  Inside string constants, the
+continuation marker must appear at the end of the line just before the
+newline character.
+
+Input that occurs inside parentheses can be continued to the next line
+without having to use a continuation marker.  For example, it is
+possible to write statements like
+
+ at example
+ at group
+if (fine_dining_destination == on_a_boat
+    || fine_dining_destination == on_a_train)
+  seuss (i, will, not, eat, them, sam, i, am, i,
+         will, not, eat, green, eggs, and, ham);
+endif
+ at end group
+ at end example
+
+ at noindent
+without having to add to the clutter with continuation markers.
diff --git a/doc/interpreter/stmt.txi b/doc/interpreter/stmt.txi
new file mode 100644
index 0000000..b0d8b32
--- /dev/null
+++ b/doc/interpreter/stmt.txi
@@ -0,0 +1,910 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2007, 2008, 2009
+ at c               John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Statements
+ at chapter Statements
+ at cindex statements
+
+Statements may be a simple constant expression or a complicated list of
+nested loops and conditional statements.
+
+ at dfn{Control statements} such as @code{if}, @code{while}, and so on
+control the flow of execution in Octave programs.  All the control
+statements start with special keywords such as @code{if} and
+ at code{while}, to distinguish them from simple expressions.
+Many control statements contain other statements; for example, the
+ at code{if} statement contains another statement which may or may not be
+executed.
+
+ at cindex @code{end} statement
+Each control statement has a corresponding @dfn{end} statement that
+marks the end of the control statement.  For example, the
+keyword @code{endif} marks the end of an @code{if} statement, and
+ at code{endwhile} marks the end of a @code{while} statement.  You can use
+the keyword @code{end} anywhere a more specific end keyword is expected,
+but using the more specific keywords is preferred because if you use
+them, Octave is able to provide better diagnostics for mismatched or
+missing end tokens.
+
+The list of statements contained between keywords like @code{if} or
+ at code{while} and the corresponding end statement is called the
+ at dfn{body} of a control statement.
+
+ at menu
+* The @code{if} Statement::            
+* The @code{switch} Statement::        
+* The @code{while} Statement::         
+* The @code{do-until} Statement::      
+* The @code{for} Statement::           
+* The @code{break} Statement::         
+* The @code{continue} Statement::      
+* The @code{unwind_protect} Statement::  
+* The @code{try} Statement::           
+* Continuation Lines::          
+ at end menu
+
+ at node The @code{if} Statement
+ at section The @code{if} Statement
+ at cindex @code{if} statement
+ at cindex @code{else} statement
+ at cindex @code{elseif} statement
+ at cindex @code{endif} statement
+
+The @code{if} statement is Octave's decision-making statement.  There
+are three basic forms of an @code{if} statement.  In its simplest form,
+it looks like this:
+
+ at example
+ at group
+if (@var{condition})
+  @var{then-body}
+endif
+ at end group
+ at end example
+
+ at noindent
+ at var{condition} is an expression that controls what the rest of the
+statement will do.  The @var{then-body} is executed only if
+ at var{condition} is true.
+
+The condition in an @code{if} statement is considered true if its value
+is non-zero, and false if its value is zero.  If the value of the
+conditional expression in an @code{if} statement is a vector or a
+matrix, it is considered true only if it is non-empty and @emph{all}
+of the elements are non-zero.
+
+The second form of an if statement looks like this:
+
+ at example
+ at group
+if (@var{condition})
+  @var{then-body}
+else
+  @var{else-body}
+endif
+ at end group
+ at end example
+
+ at noindent
+If @var{condition} is true, @var{then-body} is executed; otherwise,
+ at var{else-body} is executed.
+
+Here is an example:
+
+ at example
+ at group
+if (rem (x, 2) == 0)
+  printf ("x is even\n");
+else
+  printf ("x is odd\n");
+endif
+ at end group
+ at end example
+
+In this example, if the expression @code{rem (x, 2) == 0} is true (that
+is, the value of @code{x} is divisible by 2), then the first
+ at code{printf} statement is evaluated, otherwise the second @code{printf}
+statement is evaluated.
+
+The third and most general form of the @code{if} statement allows
+multiple decisions to be combined in a single statement.  It looks like
+this:
+
+ at example
+ at group
+if (@var{condition})
+  @var{then-body}
+elseif (@var{condition})
+  @var{elseif-body}
+else
+  @var{else-body}
+endif
+ at end group
+ at end example
+
+ at noindent
+Any number of @code{elseif} clauses may appear.  Each condition is
+tested in turn, and if one is found to be true, its corresponding
+ at var{body} is executed.  If none of the conditions are true and the
+ at code{else} clause is present, its body is executed.  Only one
+ at code{else} clause may appear, and it must be the last part of the
+statement.
+
+In the following example, if the first condition is true (that is, the
+value of @code{x} is divisible by 2), then the first @code{printf}
+statement is executed.  If it is false, then the second condition is
+tested, and if it is true (that is, the value of @code{x} is divisible
+by 3), then the second @code{printf} statement is executed.  Otherwise,
+the third @code{printf} statement is performed.
+
+ at example
+ at group
+if (rem (x, 2) == 0)
+  printf ("x is even\n");
+elseif (rem (x, 3) == 0)
+  printf ("x is odd and divisible by 3\n");
+else
+  printf ("x is odd\n");
+endif
+ at end group
+ at end example
+
+Note that the @code{elseif} keyword must not be spelled @code{else if},
+as is allowed in Fortran.  If it is, the space between the @code{else}
+and @code{if} will tell Octave to treat this as a new @code{if}
+statement within another @code{if} statement's @code{else} clause.  For
+example, if you write
+
+ at example
+ at group
+if (@var{c1})
+  @var{body-1}
+else if (@var{c2})
+  @var{body-2}
+endif
+ at end group
+ at end example
+
+ at noindent
+Octave will expect additional input to complete the first @code{if}
+statement.  If you are using Octave interactively, it will continue to
+prompt you for additional input.  If Octave is reading this input from a
+file, it may complain about missing or mismatched @code{end} statements,
+or, if you have not used the more specific @code{end} statements
+(@code{endif}, @code{endfor}, etc.), it may simply produce incorrect
+results, without producing any warning messages.
+
+It is much easier to see the error if we rewrite the statements above
+like this,
+
+ at example
+ at group
+if (@var{c1})
+  @var{body-1}
+else
+  if (@var{c2})
+    @var{body-2}
+  endif
+ at end group
+ at end example
+
+ at noindent
+using the indentation to show how Octave groups the statements.
+ at xref{Functions and Scripts}.
+
+ at node The @code{switch} Statement
+ at section The @code{switch} Statement
+ at cindex @code{switch} statement
+ at cindex @code{case} statement
+ at cindex @code{otherwise} statement
+ at cindex @code{endswitch} statement
+
+It is very common to take different actions depending on the value of
+one variable.  This is possible using the @code{if} statement in the
+following way
+
+ at example
+ at group
+if (X == 1)
+  do_something ();
+elseif (X == 2)
+  do_something_else ();
+else
+  do_something_completely_different ();
+endif
+ at end group
+ at end example
+
+ at noindent
+This kind of code can however be very cumbersome to both write and
+maintain.  To overcome this problem Octave supports the @code{switch}
+statement.  Using this statement, the above example becomes
+
+ at example
+ at group
+switch (X)
+  case 1
+    do_something ();
+  case 2
+    do_something_else ();
+  otherwise
+    do_something_completely_different ();
+endswitch
+ at end group
+ at end example
+
+ at noindent
+This code makes the repetitive structure of the problem more explicit,
+making the code easier to read, and hence maintain.  Also, if the
+variable @code{X} should change its name, only one line would need
+changing compared to one line per case when @code{if} statements are
+used.
+
+The general form of the @code{switch} statement is
+
+ at example
+ at group
+switch @var{expression}
+  case @var{label}
+    @var{command_list}
+  case @var{label}
+    @var{command_list}
+  @dots{}
+
+  otherwise
+    @var{command_list}
+endswitch
+ at end group
+ at end example
+
+ at noindent
+where @var{label} can be any expression.  However, duplicate
+ at var{label} values are not detected, and only the @var{command_list}
+corresponding to the first match will be executed.  For the
+ at code{switch} statement to be meaningful at least one
+ at code{case @var{label} @var{command_list}} clause must be present,
+while the @code{otherwise @var{command_list}} clause is optional.
+
+If @var{label} is a cell array the corresponding @var{command_list}
+is executed if @emph{any} of the elements of the cell array match
+ at var{expression}.  As an example, the following program will print
+ at samp{Variable is either 6 or 7}.
+
+ at example
+ at group
+A = 7;
+switch A
+  case @{ 6, 7 @}
+    printf ("variable is either 6 or 7\n");
+  otherwise
+    printf ("variable is neither 6 nor 7\n");
+endswitch
+ at end group
+ at end example
+
+As with all other specific @code{end} keywords, @code{endswitch} may be
+replaced by @code{end}, but you can get better diagnostics if you use
+the specific forms.
+
+ at c Strings can be matched
+
+One advantage of using the @code{switch} statement compared to using
+ at code{if} statements is that the @var{label}s can be strings.  If an
+ at code{if} statement is used it is @emph{not} possible to write
+
+ at example
+if (X == "a string") # This is NOT valid
+ at end example
+
+ at noindent
+since a character-to-character comparison between @code{X} and the
+string will be made instead of evaluating if the strings are equal.
+This special-case is handled by the @code{switch} statement, and it
+is possible to write programs that look like this
+
+ at example
+ at group
+switch (X)
+  case "a string"
+    do_something
+  @dots{}
+endswitch
+ at end group
+ at end example
+
+ at menu
+* Notes for the C programmer::  
+ at end menu
+
+ at node Notes for the C programmer
+ at subsection Notes for the C programmer
+
+The @code{switch} statement is also available in the widely used C
+programming language.  There are, however, some differences
+between the statement in Octave and C
+
+ at itemize @bullet
+ at item
+Cases are exclusive, so they don't `fall through' as do the cases
+in the @code{switch} statement of the C language.
+
+ at item
+The @var{command_list} elements are not optional.  Making the list
+optional would have meant requiring a separator between the label and
+the command list.  Otherwise, things like
+
+ at example
+ at group
+switch (foo)
+  case (1) -2
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+would produce surprising results, as would
+
+ at example
+ at group
+switch (foo)
+  case (1)
+  case (2)
+    doit ();
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+particularly for C programmers.  If @code{doit()} should be executed if
+ at var{foo} is either @code{1} or @code{2}, the above code should be
+written with a cell array like this
+
+ at example
+ at group
+switch (foo)
+  case @{ 1, 2 @}
+    doit ();
+  @dots{}
+ at end group
+ at end example
+ at end itemize
+
+ at node The @code{while} Statement
+ at section The @code{while} Statement
+ at cindex @code{while} statement
+ at cindex @code{endwhile} statement
+ at cindex loop
+ at cindex body of a loop
+
+In programming, a @dfn{loop} means a part of a program that is (or at least can
+be) executed two or more times in succession.
+
+The @code{while} statement is the simplest looping statement in Octave.
+It repeatedly executes a statement as long as a condition is true.  As
+with the condition in an @code{if} statement, the condition in a
+ at code{while} statement is considered true if its value is non-zero, and
+false if its value is zero.  If the value of the conditional expression
+in a @code{while} statement is a vector or a matrix, it is considered
+true only if it is non-empty and @emph{all} of the elements are non-zero.
+
+Octave's @code{while} statement looks like this:
+
+ at example
+ at group
+while (@var{condition})
+  @var{body}
+endwhile
+ at end group
+ at end example
+
+ at noindent
+Here @var{body} is a statement or list of statements that we call the
+ at dfn{body} of the loop, and @var{condition} is an expression that
+controls how long the loop keeps running.
+
+The first thing the @code{while} statement does is test @var{condition}.
+If @var{condition} is true, it executes the statement @var{body}.  After
+ at var{body} has been executed, @var{condition} is tested again, and if it
+is still true, @var{body} is executed again.  This process repeats until
+ at var{condition} is no longer true.  If @var{condition} is initially
+false, the body of the loop is never executed.
+
+This example creates a variable @code{fib} that contains the first ten
+elements of the Fibonacci sequence.
+
+ at example
+ at group
+fib = ones (1, 10);
+i = 3;
+while (i <= 10)
+  fib (i) = fib (i-1) + fib (i-2);
+  i++;
+endwhile
+ at end group
+ at end example
+
+ at noindent
+Here the body of the loop contains two statements.
+
+The loop works like this: first, the value of @code{i} is set to 3.
+Then, the @code{while} tests whether @code{i} is less than or equal to
+10.  This is the case when @code{i} equals 3, so the value of the
+ at code{i}-th element of @code{fib} is set to the sum of the previous two
+values in the sequence.  Then the @code{i++} increments the value of
+ at code{i} and the loop repeats.  The loop terminates when @code{i}
+reaches 11.
+
+A newline is not required between the condition and the
+body; but using one makes the program clearer unless the body is very
+simple.
+
+ at node The @code{do-until} Statement
+ at section The @code{do-until} Statement
+ at cindex @code{do-until} statement
+
+The @code{do-until} statement is similar to the @code{while} statement,
+except that it repeatedly executes a statement until a condition becomes
+true, and the test of the condition is at the end of the loop, so the
+body of the loop is always executed at least once.  As with the
+condition in an @code{if} statement, the condition in a @code{do-until}
+statement is considered true if its value is non-zero, and false if its
+value is zero.  If the value of the conditional expression in a
+ at code{do-until} statement is a vector or a matrix, it is considered 
+true only if it is non-empty and @emph{all} of the elements are non-zero.
+
+Octave's @code{do-until} statement looks like this:
+
+ at example
+ at group
+do
+  @var{body}
+until (@var{condition})
+ at end group
+ at end example
+
+ at noindent
+Here @var{body} is a statement or list of statements that we call the
+ at dfn{body} of the loop, and @var{condition} is an expression that
+controls how long the loop keeps running.
+
+This example creates a variable @code{fib} that contains the first ten
+elements of the Fibonacci sequence.
+
+ at example
+ at group
+fib = ones (1, 10);
+i = 2;
+do
+  i++;
+  fib (i) = fib (i-1) + fib (i-2);
+until (i == 10)
+ at end group
+ at end example
+
+A newline is not required between the @code{do} keyword and the
+body; but using one makes the program clearer unless the body is very
+simple.
+
+ at node The @code{for} Statement
+ at section The @code{for} Statement
+ at cindex @code{for} statement
+ at cindex @code{endfor} statement
+
+The @code{for} statement makes it more convenient to count iterations of a
+loop.  The general form of the @code{for} statement looks like this:
+
+ at example
+ at group
+for @var{var} = @var{expression}
+  @var{body}
+endfor
+ at end group
+ at end example
+
+ at noindent
+where @var{body} stands for any statement or list of statements,
+ at var{expression} is any valid expression, and @var{var} may take several
+forms.  Usually it is a simple variable name or an indexed variable.  If
+the value of @var{expression} is a structure, @var{var} may also be a
+vector with two elements.  @xref{Looping Over Structure Elements}, below.
+
+The assignment expression in the @code{for} statement works a bit
+differently than Octave's normal assignment statement.  Instead of
+assigning the complete result of the expression, it assigns each column
+of the expression to @var{var} in turn.  If @var{expression} is a range,
+a row vector, or a scalar, the value of @var{var} will be a scalar each
+time the loop body is executed.  If @var{var} is a column vector or a
+matrix, @var{var} will be a column vector each time the loop body is
+executed.
+
+The following example shows another way to create a vector containing
+the first ten elements of the Fibonacci sequence, this time using the
+ at code{for} statement:
+
+ at example
+ at group
+fib = ones (1, 10);
+for i = 3:10
+  fib (i) = fib (i-1) + fib (i-2);
+endfor
+ at end group
+ at end example
+
+ at noindent
+This code works by first evaluating the expression @code{3:10}, to
+produce a range of values from 3 to 10 inclusive.  Then the variable
+ at code{i} is assigned the first element of the range and the body of the
+loop is executed once.  When the end of the loop body is reached, the
+next value in the range is assigned to the variable @code{i}, and the
+loop body is executed again.  This process continues until there are no
+more elements to assign.
+
+Within Octave is it also possible to iterate over matrices or cell arrays
+using the @code{for} statement.  For example consider
+
+ at example
+ at group
+disp("Loop over a matrix")
+for i = [1,3;2,4]
+  i
+endfor
+disp("Loop over a cell array")
+for i = @{1,"two";"three",4@}
+  i
+endfor
+ at end group 
+ at end example
+
+ at noindent
+In this case the variable @code{i} takes on the value of the columns of
+the matrix or cell matrix.  So the first loop iterates twice, producing
+two column vectors @code{[1;2]}, followed by @code{[3;4]}, and likewise
+for the loop over the cell array.  This can be extended to loops over
+multidimensional arrays.  For example
+
+ at example
+ at group
+a = [1,3;2,4]; b = cat(3, a, 2*a);
+for i = c
+  i
+endfor
+ at end group 
+ at end example
+
+ at noindent
+In the above case, the multidimensional matrix @var{c} is reshaped to a
+two-dimensional matrix as @code{reshape (c, rows(c),
+prod(size(c)(2:end)))} and then the same behavior as a loop over a two
+dimensional matrix is produced.
+
+Although it is possible to rewrite all @code{for} loops as @code{while}
+loops, the Octave language has both statements because often a
+ at code{for} loop is both less work to type and more natural to think of.
+Counting the number of iterations is very common in loops and it can be
+easier to think of this counting as part of looping rather than as
+something to do inside the loop.
+
+ at menu
+* Looping Over Structure Elements::  
+ at end menu
+
+ at node Looping Over Structure Elements
+ at subsection Looping Over Structure Elements
+ at cindex structure elements, looping over
+ at cindex looping over structure elements
+
+A special form of the @code{for} statement allows you to loop over all
+the elements of a structure:
+
+ at example
+ at group
+for [ @var{val}, @var{key} ] = @var{expression}
+  @var{body}
+endfor
+ at end group
+ at end example
+
+ at noindent
+In this form of the @code{for} statement, the value of @var{expression}
+must be a structure.  If it is, @var{key} and @var{val} are set to the
+name of the element and the corresponding value in turn, until there are
+no more elements.  For example,
+
+ at example
+ at group
+x.a = 1
+x.b = [1, 2; 3, 4]
+x.c = "string"
+for [val, key] = x
+  key
+  val
+endfor
+
+     @print{} key = a
+     @print{} val = 1
+     @print{} key = b
+     @print{} val =
+     @print{} 
+     @print{}   1  2
+     @print{}   3  4
+     @print{} 
+     @print{} key = c
+     @print{} val = string
+ at end group
+ at end example
+
+The elements are not accessed in any particular order.  If you need to
+cycle through the list in a particular way, you will have to use the
+function @code{fieldnames} and sort the list yourself.
+
+The @var{key} variable may also be omitted.  If it is, the brackets are
+also optional.  This is useful for cycling through the values of all the
+structure elements when the names of the elements do not need to be
+known.
+
+ at node The @code{break} Statement
+ at section The @code{break} Statement
+ at cindex @code{break} statement
+
+The @code{break} statement jumps out of the innermost @code{for} or
+ at code{while} loop that encloses it.  The @code{break} statement may only
+be used within the body of a loop.  The following example finds the
+smallest divisor of a given integer, and also identifies prime numbers:
+
+ at example
+ at group
+num = 103;
+div = 2;
+while (div*div <= num)
+  if (rem (num, div) == 0)
+    break;
+  endif
+  div++;
+endwhile
+if (rem (num, div) == 0)
+  printf ("Smallest divisor of %d is %d\n", num, div)
+else
+  printf ("%d is prime\n", num);
+endif
+ at end group
+ at end example
+
+When the remainder is zero in the first @code{while} statement, Octave
+immediately @dfn{breaks out} of the loop.  This means that Octave
+proceeds immediately to the statement following the loop and continues
+processing.  (This is very different from the @code{exit} statement
+which stops the entire Octave program.)
+
+Here is another program equivalent to the previous one.  It illustrates
+how the @var{condition} of a @code{while} statement could just as well
+be replaced with a @code{break} inside an @code{if}:
+
+ at example
+ at group
+num = 103;
+div = 2;
+while (1)
+  if (rem (num, div) == 0)
+    printf ("Smallest divisor of %d is %d\n", num, div);
+    break;
+  endif
+  div++;
+  if (div*div > num)
+    printf ("%d is prime\n", num);
+    break;
+  endif
+endwhile
+ at end group
+ at end example
+
+ at node The @code{continue} Statement
+ at section The @code{continue} Statement
+ at cindex @code{continue} statement
+
+The @code{continue} statement, like @code{break}, is used only inside
+ at code{for} or @code{while} loops.  It skips over the rest of the loop
+body, causing the next cycle around the loop to begin immediately.
+Contrast this with @code{break}, which jumps out of the loop altogether.
+Here is an example:
+
+ at example
+ at group
+# print elements of a vector of random
+# integers that are even.
+
+# first, create a row vector of 10 random
+# integers with values between 0 and 100:
+
+vec = round (rand (1, 10) * 100);
+
+# print what we're interested in:
+
+for x = vec
+  if (rem (x, 2) != 0)
+    continue;
+  endif
+  printf ("%d\n", x);
+endfor
+ at end group
+ at end example
+
+If one of the elements of @var{vec} is an odd number, this example skips
+the print statement for that element, and continues back to the first
+statement in the loop.
+
+This is not a practical example of the @code{continue} statement, but it
+should give you a clear understanding of how it works.  Normally, one
+would probably write the loop like this:
+
+ at example
+ at group
+for x = vec
+  if (rem (x, 2) == 0)
+    printf ("%d\n", x);
+  endif
+endfor
+ at end group
+ at end example
+
+ at node The @code{unwind_protect} Statement
+ at section The @code{unwind_protect} Statement
+ at cindex @code{unwind_protect} statement
+ at cindex @code{unwind_protect_cleanup}
+ at cindex @code{end_unwind_protect}
+
+Octave supports a limited form of exception handling modelled after the
+unwind-protect form of Lisp.  
+
+The general form of an @code{unwind_protect} block looks like this:
+
+ at example
+ at group
+unwind_protect
+  @var{body}
+unwind_protect_cleanup
+  @var{cleanup}
+end_unwind_protect
+ at end group
+ at end example
+
+ at noindent
+where @var{body} and @var{cleanup} are both optional and may contain any
+Octave expressions or commands.  The statements in @var{cleanup} are 
+guaranteed to be executed regardless of how control exits @var{body}.
+
+This is useful to protect temporary changes to global variables from
+possible errors.  For example, the following code will always restore
+the original value of the global variable @code{frobnosticate}
+even if an error occurs in the first part of the @code{unwind_protect}
+block.
+
+ at example
+ at group
+save_frobnosticate = frobnosticate;
+unwind_protect
+  frobnosticate = true;
+  @dots{}
+unwind_protect_cleanup
+  frobnosticate = save_frobnosticate;
+end_unwind_protect
+ at end group
+ at end example
+
+ at noindent
+Without @code{unwind_protect}, the value of @var{frobnosticate}
+would not be restored if an error occurs while evaluating the first part
+of the @code{unwind_protect} block because evaluation would stop at the
+point of the error and the statement to restore the value would not be
+executed.
+
+ at node The @code{try} Statement
+ at section The @code{try} Statement
+ at cindex @code{try} statement
+ at cindex @code{catch}
+ at cindex @code{end_try_catch}
+
+In addition to unwind_protect, Octave supports another limited form of
+exception handling.
+
+The general form of a @code{try} block looks like this:
+
+ at example
+ at group
+try
+  @var{body}
+catch
+  @var{cleanup}
+end_try_catch
+ at end group
+ at end example
+
+ at noindent
+where @var{body} and @var{cleanup} are both optional and may contain any
+Octave expressions or commands.  The statements in @var{cleanup} are
+only executed if an error occurs in @var{body}.
+
+No warnings or error messages are printed while @var{body} is
+executing.  If an error does occur during the execution of @var{body},
+ at var{cleanup} can use the function @code{lasterr} to access the text
+of the message that would have been printed.  This is the same
+as @code{eval (@var{try}, @var{catch})} but it is more efficient since
+the commands do not need to be parsed each time the @var{try} and
+ at var{catch} statements are evaluated.  @xref{Errors and Warnings}, for more
+information about the @code{lasterr} function.
+
+ at cindex continuation lines
+ at cindex @code{...} continuation marker
+ at cindex @code{\} continuation marker
+
+ at node Continuation Lines
+ at section Continuation Lines
+
+In the Octave language, most statements end with a newline character and
+you must tell Octave to ignore the newline character in order to
+continue a statement from one line to the next.  Lines that end with the
+characters @code{...} or @code{\} are joined with the following line
+before they are divided into tokens by Octave's parser.  For example,
+the lines
+
+ at example
+ at group
+x = long_variable_name ...
+    + longer_variable_name \
+    - 42
+ at end group
+ at end example
+
+ at noindent
+form a single statement.  The backslash character on the second line
+above is interpreted as a continuation character, @emph{not} as a division
+operator.
+
+For continuation lines that do not occur inside string constants,
+whitespace and comments may appear between the continuation marker and
+the newline character.  For example, the statement
+
+ at example
+ at group
+x = long_variable_name ...     # comment one
+    + longer_variable_name \   # comment two
+    - 42                       # last comment
+ at end group
+ at end example
+
+ at noindent
+is equivalent to the one shown above.  Inside string constants, the
+continuation marker must appear at the end of the line just before the
+newline character.
+
+Input that occurs inside parentheses can be continued to the next line
+without having to use a continuation marker.  For example, it is
+possible to write statements like
+
+ at example
+ at group
+if (fine_dining_destination == on_a_boat
+    || fine_dining_destination == on_a_train)
+  seuss (i, will, not, eat, them, sam, i, am, i,
+         will, not, eat, green, eggs, and, ham);
+endif
+ at end group
+ at end example
+
+ at noindent
+without having to add to the clutter with continuation markers.
diff --git a/doc/interpreter/strings.texi b/doc/interpreter/strings.texi
new file mode 100644
index 0000000..f845d2c
--- /dev/null
+++ b/doc/interpreter/strings.texi
@@ -0,0 +1,1856 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005,
+ at c               2006, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Strings
+ at chapter Strings
+ at cindex strings
+ at cindex character strings
+ at opindex "
+ at opindex '
+
+A @dfn{string constant} consists of a sequence of characters enclosed in
+either double-quote or single-quote marks.  For example, both of the
+following expressions
+
+ at example
+ at group
+"parrot"
+'parrot'
+ at end group
+ at end example
+
+ at noindent
+represent the string whose contents are @samp{parrot}.  Strings in
+Octave can be of any length.
+
+Since the single-quote mark is also used for the transpose operator
+(@pxref{Arithmetic Ops}) but double-quote marks have no other purpose in Octave,
+it is best to use double-quote marks to denote strings.
+
+Strings can be concatenated using the notation for defining matrices.  For
+example, the expression 
+ 
+ at example
+[ "foo" , "bar" , "baz" ]
+ at end example
+
+ at noindent
+produces the string whose contents are @samp{foobarbaz}.  @xref{Numeric Data
+Types}, for more information about creating matrices.
+
+ at menu
+* Escape Sequences in string constants::
+* Character Arrays::
+* Creating Strings:: 
+* Comparing Strings::           
+* Manipulating Strings::     
+* String Conversions::          
+* Character Class Functions::   
+ at end menu
+
+ at node Escape Sequences in string constants
+ at section Escape Sequences in string constants
+ at cindex escape sequence notation
+In double-quoted strings, the backslash character is used to introduce
+ at dfn{escape sequences} that represent other characters.  For example,
+ at samp{\n} embeds a newline character in a double-quoted string and
+ at samp{\"} embeds a double quote character.  In single-quoted strings, backslash
+is not a special character.  Here is an example showing the difference:
+
+ at example
+ at group
+toascii ("\n")
+    @result{} 10
+toascii ('\n')
+    @result{} [ 92 110 ]
+ at end group
+ at end example
+
+Here is a table of all the escape sequences used in Octave (within
+double quoted strings).  They are the same as those used in the C 
+programming language.
+
+ at table @code
+ at item \\
+Represents a literal backslash, @samp{\}.
+
+ at item \"
+Represents a literal double-quote character, @samp{"}.
+
+ at item \'
+Represents a literal single-quote character, @samp{'}.
+
+ at item \0
+Represents the ``nul'' character, control-@@, ASCII code 0.
+
+ at item \a
+Represents the ``alert'' character, control-g, ASCII code 7.
+
+ at item \b
+Represents a backspace, control-h, ASCII code 8.
+
+ at item \f
+Represents a formfeed, control-l, ASCII code 12.
+
+ at item \n
+Represents a newline, control-j, ASCII code 10.
+
+ at item \r
+Represents a carriage return, control-m, ASCII code 13.
+
+ at item \t
+Represents a horizontal tab, control-i, ASCII code 9.
+
+ at item \v
+Represents a vertical tab, control-k, ASCII code 11.
+
+ at c We don't do octal or hex this way yet.
+ at c
+ at c @item \@var{nnn}
+ at c Represents the octal value @var{nnn}, where @var{nnn} are one to three
+ at c digits between 0 and 7.  For example, the code for the ASCII ESC
+ at c (escape) character is @samp{\033}. at refill
+ at c 
+ at c @item \x at var{hh}@dots{}
+ at c Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal
+ at c digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or
+ at c @samp{a} through @samp{f}).  Like the same construct in @sc{ansi} C,
+ at c the escape 
+ at c sequence continues until the first non-hexadecimal digit is seen.  However,
+ at c using more than two hexadecimal digits produces undefined results.  (The
+ at c @samp{\x} escape sequence is not allowed in @sc{posix} @code{awk}.)@refill
+ at end table
+
+In a single-quoted string there is only one escape sequence: you may insert a
+single quote character using two single quote characters in succession.  For
+example,
+
+ at example
+ at group
+'I can''t escape'
+    @result{} I can't escape
+ at end group
+ at end example
+
+
+ at node Character Arrays
+ at section Character Arrays
+
+The string representation used by Octave is an array of characters, so
+internally the string "dddddddddd" is actually a row vector of length 10
+containing the value 100 in all places (100 is the ASCII code of "d").  This
+lends itself to the obvious generalization to character matrices.  Using a
+matrix of characters, it is possible to represent a collection of same-length
+strings in one variable.  The convention used in Octave is that each row in a
+character matrix is a separate string, but letting each column represent a
+string is equally possible.
+
+The easiest way to create a character matrix is to put several strings
+together into a matrix.
+
+ at example
+collection = [ "String #1"; "String #2" ];
+ at end example
+
+ at noindent
+This creates a 2-by-9 character matrix.
+
+The function @code{ischar} can be used to test if an object is a character
+matrix.
+
+ at c strfns.cc
+ at anchor{doc-ischar}
+ at deftypefn {Built-in Function} {} ischar (@var{a})
+Return 1 if @var{a} is a character array.  Otherwise, return 0.
+ at end deftypefn
+
+
+To test if an object is a string (i.e., a character vector and not a character
+matrix) you can use the @code{ischar} function in combination with the
+ at code{isvector} function as in the following example:
+
+ at example
+ at group
+ischar(collection)
+     @result{} ans = 1
+
+ischar(collection) && isvector(collection)
+     @result{} ans = 0
+
+ischar("my string") && isvector("my string")
+     @result{} ans = 1
+ at end group
+ at end example
+
+One relevant question is, what happens when a character matrix is
+created from strings of different length.  The answer is that Octave
+puts blank characters at the end of strings shorter than the longest
+string.  It is possible to use a different character than the
+blank character using the @code{string_fill_char} function.
+
+ at c pt-mat.cc
+ at anchor{doc-string_fill_char}
+ at deftypefn {Built-in Function} {@var{val} =} string_fill_char ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} string_fill_char (@var{new_val})
+Query or set the internal variable used to pad all rows of a character
+matrix to the same length.  It must be a single character.  The default
+value is @code{" "} (a single space).  For example,
+
+ at example
+ at group
+string_fill_char ("X");
+[ "these"; "are"; "strings" ]
+     @result{} "theseXX"
+        "areXXXX"
+        "strings"
+ at end group
+ at end example
+ at end deftypefn
+
+
+This shows a problem with character matrices.  It simply isn't possible to
+represent strings of different lengths.  The solution is to use a cell array of
+strings, which is described in @ref{Cell Arrays of Strings}.
+
+ at node Creating Strings
+ at section Creating Strings
+
+The easiest way to create a string is, as illustrated in the introduction,
+to enclose a text in double-quotes or single-quotes.  It is however
+possible to create a string without actually writing a text.  The
+function @code{blanks} creates a string of a given length consisting
+only of blank characters (ASCII code 32).
+
+ at c ./strings/blanks.m
+ at anchor{doc-blanks}
+ at deftypefn {Function File} {} blanks (@var{n})
+Return a string of @var{n} blanks, for example:
+
+ at example
+ at group
+blanks(10);
+whos ans;
+     @result{}
+      Attr Name        Size                     Bytes  Class
+      ==== ====        ====                     =====  ===== 
+           ans         1x10                        10  char
+ at end group
+ at end example
+ at seealso{@ref{doc-repmat,,repmat}}
+ at end deftypefn
+
+
+ at menu
+* Concatenating Strings:: 
+* Conversion of Numerical Data to Strings::
+ at end menu
+
+ at node Concatenating Strings
+ at subsection Concatenating Strings
+
+It has been shown above that strings can be concatenated using matrix notation
+(@pxref{Strings}, @ref{Character Arrays}).  Apart from that, there are several
+functions to concatenate string objects: @code{char},
+ at code{strvcat}, @code{strcat} and @code{cstrcat}.  In addition, the general
+purpose concatenation functions can be used: see @ref{doc-cat,,cat},
+ at ref{doc-horzcat,,horzcat} and @ref{doc-vertcat,,vertcat}.
+
+ at itemize @bullet
+ at item All string concatenation functions except @code{cstrcat}
+convert numerical input into character data by taking the corresponding ASCII
+character for each element, as in the following example:
+
+ at example
+ at group
+char([98, 97, 110, 97, 110, 97])
+     @result{} ans =
+       banana
+ at end group
+ at end example
+
+ at item
+ at code{char} and @code{strvcat}
+concatenate vertically, while @code{strcat} and @code{cstrcat} concatenate
+horizontally.  For example:
+
+ at example
+ at group
+char("an apple", "two pears")
+     @result{} ans =
+       an apple
+       two pears
+ at end group
+
+ at group
+strcat("oc", "tave", " is", " good", " for you")
+     @result{} ans =
+       octave is good for you
+ at end group
+ at end example
+
+ at item @code{char} generates an empty row in the output
+for each empty string in the input.  @code{strvcat}, on the other hand,
+eliminates empty strings.
+
+ at example
+ at group
+char("orange", "green", "", "red")
+     @result{} ans =
+       orange
+       green 
+             
+       red   
+ at end group
+
+ at group
+strvcat("orange", "green", "", "red")
+     @result{} ans =
+       orange
+       green 
+       red  
+ at end group
+ at end example
+
+ at item All string concatenation functions except @code{cstrcat} also accept cell
+array data (@pxref{Cell Arrays}).  @code{char} and
+ at code{strvcat} convert cell arrays into character arrays, while @code{strcat}
+concatenates within the cells of the cell arrays:
+
+ at example
+ at group
+char(@{"red", "green", "", "blue"@})
+     @result{} ans =
+       red  
+       green
+
+       blue 
+ at end group
+
+ at group
+strcat(@{"abc"; "ghi"@}, @{"def"; "jkl"@})
+     @result{} ans =
+       @{
+         [1,1] = abcdef
+         [2,1] = ghijkl
+       @}
+ at end group
+ at end example
+
+ at item @code{strcat} removes trailing white space in the arguments (except
+within cell arrays), while @code{cstrcat} leaves white space untouched.  Both
+kinds of behavior can be useful as can be seen in the examples:
+
+ at example
+ at group
+strcat(["dir1";"directory2"], ["/";"/"], ["file1";"file2"])
+     @result{} ans =
+       dir1/file1      
+       directory2/file2
+ at end group
+ at group
+
+cstrcat(["thirteen apples"; "a banana"], [" 5$";" 1$"])
+     @result{} ans =
+       thirteen apples 5$
+       a banana        1$
+ at end group
+ at end example
+
+Note that in the above example for @code{cstrcat}, the white space originates
+from the internal representation of the strings in a string array
+(@pxref{Character Arrays}).
+ at end itemize
+
+ at c strfns.cc
+ at anchor{doc-char}
+ at deftypefn  {Built-in Function} {} char (@var{x})
+ at deftypefnx {Built-in Function} {} char (@var{x}, @dots{})
+ at deftypefnx {Built-in Function} {} char (@var{s1}, @var{s2}, @dots{})
+ at deftypefnx {Built-in Function} {} char (@var{cell_array})
+Create a string array from one or more numeric matrices, character
+matrices, or cell arrays.  Arguments are concatenated vertically.
+The returned values are padded with blanks as needed to make each row
+of the string array have the same length.  Empty input strings are
+significant and will concatenated in the output.
+
+For numerical input, each element is converted
+to the corresponding ASCII character.  A range error results if an input
+is outside the ASCII range (0-255).
+
+For cell arrays, each element is concatenated separately.  Cell arrays converted through
+ at code{char} can mostly be converted back with @code{cellstr}.
+For example,
+
+ at example
+ at group
+char ([97, 98, 99], "", @{"98", "99", 100@}, "str1", ["ha", "lf"])
+     @result{} ["abc    "
+         "       "
+         "98     "
+         "99     "
+         "d      "
+         "str1   "
+         "half   "]
+ at end group
+ at end example
+ at seealso{@ref{doc-strvcat,,strvcat}, @ref{doc-cellstr,,cellstr}}
+ at end deftypefn
+
+
+ at c strfns.cc
+ at anchor{doc-strvcat}
+ at deftypefn  {Built-in Function} {} strvcat (@var{x})
+ at deftypefnx {Built-in Function} {} strvcat (@var{x}, @dots{})
+ at deftypefnx {Built-in Function} {} strvcat (@var{s1}, @var{s2}, @dots{})
+ at deftypefnx {Built-in Function} {} strvcat (@var{cell_array})
+Create a character array from one or more numeric matrices, character
+matrices, or cell arrays.  Arguments are concatenated vertically.
+The returned values are padded with blanks as needed to make each row
+of the string array have the same length.  Unlike @code{char}, empty
+strings are removed and will not appear in the output.
+
+For numerical input, each element is converted
+to the corresponding ASCII character.  A range error results if an input
+is outside the ASCII range (0-255).
+
+For cell arrays, each element is concatenated separately.  Cell arrays converted through
+ at code{strvcat} can mostly be converted back with @code{cellstr}.
+For example,
+
+ at example
+ at group
+strvcat ([97, 98, 99], "", @{"98", "99", 100@}, "str1", ["ha", "lf"])
+     @result{} ["abc    "
+         "98     "
+         "99     "
+         "d      "
+         "str1   "
+         "half   "]
+ at end group
+ at end example
+ at seealso{@ref{doc-char,,char}, @ref{doc-strcat,,strcat}, @ref{doc-cstrcat,,cstrcat}}
+ at end deftypefn
+
+
+ at c ./strings/strcat.m
+ at anchor{doc-strcat}
+ at deftypefn {Function File} {} strcat (@var{s1}, @var{s2}, @dots{})
+Return a string containing all the arguments concatenated
+horizontally.  If the arguments are cells strings,  @code{strcat}
+returns a cell string with the individual cells concatenated.
+For numerical input, each element is converted to the
+corresponding ASCII character.  Trailing white space is eliminated.
+For example,
+
+ at example
+ at group
+s = [ "ab"; "cde" ];
+strcat (s, s, s)
+     @result{} ans =
+        "ab ab ab "
+        "cdecdecde"
+ at end group
+ at end example
+
+ at example
+ at group
+s = @{ "ab"; "cde" @};
+strcat (s, s, s)
+     @result{} ans =
+        @{
+          [1,1] = ababab
+          [2,1] = cdecdecde
+        @}
+ at end group
+ at end example
+
+ at seealso{@ref{doc-cstrcat,,cstrcat}, @ref{doc-char,,char}, @ref{doc-strvcat,,strvcat}}
+ at end deftypefn
+
+
+ at c ./strings/cstrcat.m
+ at anchor{doc-cstrcat}
+ at deftypefn {Function File} {} cstrcat (@var{s1}, @var{s2}, @dots{})
+Return a string containing all the arguments concatenated
+horizontally.  Trailing white space is preserved.  For example,
+
+ at example
+ at group
+cstrcat ("ab   ", "cd")
+     @result{} "ab   cd"
+ at end group
+ at end example
+
+ at example
+ at group
+s = [ "ab"; "cde" ];
+cstrcat (s, s, s)
+     @result{} ans =
+        "ab ab ab "
+        "cdecdecde"
+ at end group
+ at end example
+ at seealso{@ref{doc-strcat,,strcat}, @ref{doc-char,,char}, @ref{doc-strvcat,,strvcat}}
+ at end deftypefn
+
+
+ at node Conversion of Numerical Data to Strings 
+ at subsection Conversion of Numerical Data to Strings
+Apart from the string concatenation functions (@pxref{Concatenating Strings})
+which cast numerical data to the corresponding ASCII characters, there are
+several functions that format numerical data as strings.  @code{mat2str} and
+ at code{num2str} convert real or complex matrices, while @code{int2str} converts
+integer matrices.  @code{int2str} takes the real part of complex values and
+round fractional values to integer.  A more flexible way to format numerical
+data as strings is the @code{sprintf} function (@pxref{Formatted Output},
+ at ref{doc-sprintf}).
+
+ at c ./strings/mat2str.m
+ at anchor{doc-mat2str}
+ at deftypefn {Function File} {@var{s} =} mat2str (@var{x}, @var{n})
+ at deftypefnx {Function File} {@var{s} =} mat2str (@dots{}, 'class')
+
+Format real/complex numerical matrices as strings.  This function
+returns values that are suitable for the use of the @code{eval}
+function.
+
+The precision of the values is given by @var{n}.  If @var{n} is a
+scalar then both real and imaginary parts of the matrix are printed
+to the same precision.  Otherwise @code{@var{n} (1)} defines the
+precision of the real part and @code{@var{n} (2)} defines the
+precision of the imaginary part.  The default for @var{n} is 17.
+
+If the argument 'class' is given, then the class of @var{x} is
+included in the string in such a way that the eval will result in the
+construction of a matrix of the same class.
+
+ at example
+ at group
+mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
+     @result{} "[-0.3333+0.14i;0.3333-0.14i]"
+
+mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
+     @result{} "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]"
+
+mat2str (int16([1 -1]), 'class')
+     @result{} "int16([1,-1])"
+ at end group
+ at end example
+
+ at seealso{@ref{doc-sprintf,,sprintf}, @ref{doc-num2str,,num2str}, @ref{doc-int2str,,int2str}}
+ at end deftypefn
+
+
+ at c ./general/num2str.m
+ at anchor{doc-num2str}
+ at deftypefn {Function File} {} num2str (@var{x})
+ at deftypefnx {Function File} {} num2str (@var{x}, @var{precision})
+ at deftypefnx {Function File} {} num2str (@var{x}, @var{format})
+Convert a number (or array) to a string (or a character array).  The
+optional second argument may either give the number of significant
+digits (@var{precision}) to be used in the output or a format
+template string (@var{format}) as in @code{sprintf} (@pxref{Formatted
+Output}).  @code{num2str} can also handle complex numbers.  For
+example: 
+
+ at example
+ at group
+num2str (123.456)
+     @result{} "123.46"
+
+num2str (123.456, 4)
+     @result{} "123.5"
+
+s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
+     @result{} s =
+        1.0  1.3
+        3.0  3.6
+whos s
+     @result{}
+      Attr Name        Size                     Bytes  Class
+      ==== ====        ====                     =====  ===== 
+           s           2x8                         16  char
+
+num2str (1.234 + 27.3i)
+     @result{} "1.234+27.3i"
+ at end group
+ at end example
+
+The @code{num2str} function is not very flexible.  For better control
+over the results, use @code{sprintf} (@pxref{Formatted Output}). 
+Note that for complex @var{x}, the format string may only contain one
+output conversion specification and nothing else.  Otherwise, you
+will get unpredictable results.  
+ at seealso{@ref{doc-sprintf,,sprintf}, @ref{doc-int2str,,int2str}, @ref{doc-mat2str,,mat2str}}
+ at end deftypefn
+
+
+ at c ./general/int2str.m
+ at anchor{doc-int2str}
+ at deftypefn {Function File} {} int2str (@var{n})
+Convert an integer (or array of integers) to a string (or a character
+array).
+
+ at example
+ at group
+
+int2str (123)
+     @result{} "123"
+
+s = int2str ([1, 2, 3; 4, 5, 6])
+     @result{} s = 
+        1  2  3
+        4  5  6
+
+whos s
+     @result{} s = 
+      Attr Name        Size                     Bytes  Class
+      ==== ====        ====                     =====  ===== 
+           s           2x7                         14  char
+ at end group
+ at end example
+
+This function is not very flexible.  For better control over the
+results, use @code{sprintf} (@pxref{Formatted Output}). 
+ at seealso{@ref{doc-sprintf,,sprintf}, @ref{doc-num2str,,num2str}, @ref{doc-mat2str,,mat2str}}
+ at end deftypefn
+
+
+ at node Comparing Strings
+ at section Comparing Strings
+
+Since a string is a character array, comparisons between strings work
+element by element as the following example shows:
+
+ at example
+ at group
+GNU = "GNU's Not UNIX";
+spaces = (GNU == " ")
+     @result{} spaces =
+       0   0   0   0   0   1   0   0   0   1   0   0   0   0
+ at end group
+ at end example
+
+ at noindent To determine if two strings are identical it is necessary to use the
+ at code{strcmp} function.  It compares complete strings and is case
+sensitive.  @code{strncmp} compares only the first @code{N} characters (with
+ at code{N} given as a parameter).  @code{strcmpi} and @code{strncmpi} are the
+corresponding functions for case-insensitive comparison.
+
+ at c strfns.cc
+ at anchor{doc-strcmp}
+ at deftypefn {Built-in Function} {} strcmp (@var{s1}, @var{s2})
+Return 1 if the character strings @var{s1} and @var{s2} are the same,
+and 0 otherwise.
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmp
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{@ref{doc-strcmpi,,strcmpi}, @ref{doc-strncmp,,strncmp}, @ref{doc-strncmpi,,strncmpi}}
+ at end deftypefn
+
+
+ at c strfns.cc
+ at anchor{doc-strncmp}
+ at deftypefn {Built-in Function} {} strncmp (@var{s1}, @var{s2}, @var{n})
+Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2} are the same,
+and 0 otherwise.
+
+ at example
+ at group
+strncmp ("abce", "abcd", 3)
+     @result{} 1
+ at end group
+ at end example
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at example
+ at group
+strncmp ("abce", @{"abcd", "bca", "abc"@}, 3)
+     @result{} [1, 0, 1]
+ at end group
+ at end example
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmp
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{@ref{doc-strncmpi,,strncmpi}, @ref{doc-strcmp,,strcmp}, @ref{doc-strcmpi,,strcmpi}}
+ at end deftypefn
+
+
+ at c ./strings/strcmpi.m
+ at anchor{doc-strcmpi}
+ at deftypefn {Function File} {} strcmpi (@var{s1}, @var{s2})
+Ignoring case, return 1 if the character strings (or character
+arrays) @var{s1} and @var{s2} are the same, and 0 otherwise.
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmpi
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{@ref{doc-strcmp,,strcmp}, @ref{doc-strncmp,,strncmp}, @ref{doc-strncmpi,,strncmpi}}
+ at end deftypefn
+
+
+ at c ./strings/strncmpi.m
+ at anchor{doc-strncmpi}
+ at deftypefn {Function File} {} strncmpi (@var{s1}, @var{s2}, @var{n})
+Ignoring case, return 1 if the first @var{n} characters of character
+strings (or character arrays) @var{s1} and @var{s2} are the same, and
+0 otherwise.
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmpi
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{@ref{doc-strcmp,,strcmp}, @ref{doc-strcmpi,,strcmpi}, @ref{doc-strncmp,,strncmp}}
+ at end deftypefn
+
+
+ at c ./strings/validatestring.m
+ at anchor{doc-validatestring}
+ at deftypefn {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray})
+ at deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname})
+ at deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname}, @var{varname})
+ at deftypefnx {Function File} {@var{validstr} =} validatestring (@dots{}, @var{position})
+Verify that @var{str} is a string or substring of an element of
+ at var{strarray}.
+
+ at var{str} is a character string to be tested, and @var{strarray} is a
+cellstr of valid values.  @var{validstr} will be the validated form
+of @var{str} where validation is defined as @var{str} being a member
+or substring of @var{validstr}.  If @var{str} is a substring of
+ at var{validstr} and there are multiple matches, the shortest match
+will be returned if all matches are substrings of each other, and an
+error will be raised if the matches are not substrings of each other.
+
+All comparisons are case insensitive.
+ at seealso{@ref{doc-strcmp,,strcmp}, @ref{doc-strcmpi,,strcmpi}}
+ at end deftypefn
+
+
+ at node Manipulating Strings
+ at section Manipulating Strings
+
+Octave supports a wide range of functions for manipulating strings.
+Since a string is just a matrix, simple manipulations can be accomplished
+using standard operators.  The following example shows how to replace
+all blank characters with underscores.
+
+ at example
+ at group
+quote = ...
+  "First things first, but not necessarily in that order";
+quote( quote == " " ) = "_"
+ at result{} quote = 
+    First_things_first,_but_not_necessarily_in_that_order
+ at end group
+ at end example
+
+For more complex manipulations, such as searching, replacing, and
+general regular expressions, the following functions come with Octave.
+
+ at c ./strings/deblank.m
+ at anchor{doc-deblank}
+ at deftypefn {Function File} {} deblank (@var{s})
+Remove trailing blanks and nulls from @var{s}.  If @var{s}
+is a matrix, @var{deblank} trims each row to the length of longest
+string.  If @var{s} is a cell array, operate recursively on each
+element of the cell array.
+ at end deftypefn
+
+
+ at c ./strings/strtrim.m
+ at anchor{doc-strtrim}
+ at deftypefn {Function File} {} strtrim (@var{s})
+Remove leading and trailing blanks and nulls from @var{s}.  If
+ at var{s} is a matrix, @var{strtrim} trims each row to the length of
+longest string.  If @var{s} is a cell array, operate recursively on
+each element of the cell array.  For example:
+
+ at example
+ at group
+strtrim ("    abc  ")
+     @result{} "abc"
+
+strtrim ([" abc   "; "   def   "])
+     @result{} ["abc  "; "  def"]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./strings/strtrunc.m
+ at anchor{doc-strtrunc}
+ at deftypefn {Function File} {} strtrunc (@var{s}, @var{n})
+Truncate the character string @var{s} to length @var{n}.  If @var{s}
+is a char matrix, then the number of columns is adjusted.
+
+If @var{s} is a cell array of strings, then the operation is performed
+on its members and the new cell array is returned.
+ at end deftypefn
+
+
+ at c ./strings/findstr.m
+ at anchor{doc-findstr}
+ at deftypefn {Function File} {} findstr (@var{s}, @var{t}, @var{overlap})
+Return the vector of all positions in the longer of the two strings
+ at var{s} and @var{t} where an occurrence of the shorter of the two starts.
+If the optional argument @var{overlap} is nonzero, the returned vector
+can include overlapping positions (this is the default).  For example,
+
+ at example
+ at group
+findstr ("ababab", "a")
+     @result{} [1, 3, 5]
+findstr ("abababa", "aba", 0)
+     @result{} [1, 5]
+ at end group
+ at end example
+ at seealso{@ref{doc-strfind,,strfind}, @ref{doc-strmatch,,strmatch}, @ref{doc-strcmp,,strcmp}, @ref{doc-strncmp,,strncmp}, @ref{doc-strcmpi,,strcmpi}, @ref{doc-strncmpi,,strncmpi}, @ref{doc-find,,find}}
+ at end deftypefn
+
+
+ at c ./strings/strchr.m
+ at anchor{doc-strchr}
+ at deftypefn {Function File} {@var{idx} =} strchr (@var{str}, @var{chars})
+ at deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n})
+ at deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n}, @var{direction})
+Search for the string @var{str} for occurrences of characters from the set @var{chars}.
+The return value, as well as the @var{n} and @var{direction} arguments behave
+identically as in @code{find}.
+
+This will be faster than using regexp in most cases.
+
+ at seealso{@ref{doc-find,,find}}
+ at end deftypefn
+
+
+ at c ./strings/index.m
+ at anchor{doc-index}
+ at deftypefn {Function File} {} index (@var{s}, @var{t})
+ at deftypefnx {Function File} {} index (@var{s}, @var{t}, @var{direction})
+Return the position of the first occurrence of the string @var{t} in the
+string @var{s}, or 0 if no occurrence is found.  For example,
+
+ at example
+ at group
+index ("Teststring", "t")
+     @result{} 4
+ at end group
+ at end example
+
+If @var{direction} is @samp{"first"}, return the first element found.
+If @var{direction} is @samp{"last"}, return the last element found.
+The @code{rindex} function is equivalent to @code{index} with
+ at var{direction} set to @samp{"last"}.
+
+ at strong{Caution:}  This function does not work for arrays of
+character strings.
+ at seealso{@ref{doc-find,,find}, @ref{doc-rindex,,rindex}}
+ at end deftypefn
+
+
+ at c ./strings/rindex.m
+ at anchor{doc-rindex}
+ at deftypefn {Function File} {} rindex (@var{s}, @var{t})
+Return the position of the last occurrence of the character string
+ at var{t} in the character string @var{s}, or 0 if no occurrence is
+found.  For example,
+
+ at example
+ at group
+rindex ("Teststring", "t")
+     @result{} 6
+ at end group
+ at end example
+
+ at strong{Caution:}  This function does not work for arrays of
+character strings.
+ at seealso{@ref{doc-find,,find}, @ref{doc-index,,index}}
+ at end deftypefn
+
+
+ at c ./strings/strfind.m
+ at anchor{doc-strfind}
+ at deftypefn {Function File} {@var{idx} =} strfind (@var{str}, @var{pattern})
+ at deftypefnx {Function File} {@var{idx} =} strfind (@var{cellstr}, @var{pattern})
+Search for @var{pattern} in the string @var{str} and return the
+starting index of every such occurrence in the vector @var{idx}.
+If there is no such occurrence, or if @var{pattern} is longer
+than @var{str}, then @var{idx} is the empty array @code{[]}.
+
+If the cell array of strings @var{cellstr} is specified instead of the
+string @var{str}, then @var{idx} is a cell array of vectors, as specified
+above.  Examples:
+
+ at example
+ at group
+strfind ("abababa", "aba")
+     @result{} [1, 3, 5]
+
+strfind (@{"abababa", "bebebe", "ab"@}, "aba")
+     @result{} ans =
+        @{
+          [1,1] =
+
+             1   3   5
+
+          [1,2] = [](1x0)
+          [1,3] = [](1x0)
+        @}
+ at end group
+ at end example
+ at seealso{@ref{doc-findstr,,findstr}, @ref{doc-strmatch,,strmatch}, @ref{doc-strcmp,,strcmp}, @ref{doc-strncmp,,strncmp}, @ref{doc-strcmpi,,strcmpi}, @ref{doc-strncmpi,,strncmpi}, @ref{doc-find,,find}}
+ at end deftypefn
+
+
+ at c ./strings/strmatch.m
+ at anchor{doc-strmatch}
+ at deftypefn {Function File} {} strmatch (@var{s}, @var{a}, "exact")
+Return indices of entries of @var{a} that match the string @var{s}.
+The second argument @var{a} may be a string matrix or a cell array of
+strings.  If the third argument @code{"exact"} is not given, then
+ at var{s} only needs to match @var{a} up to the length of @var{s}.  Nul
+characters match blanks.  Results are returned as a column vector. 
+For example:
+
+ at example
+ at group
+strmatch ("apple", "apple juice")
+     @result{} 1
+
+strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
+     @result{} [1; 2]
+
+strmatch ("apple", @{"apple pie"; "apple juice"; "tomato"@})
+     @result{} [1; 2]
+ at end group
+ at end example
+ at seealso{@ref{doc-strfind,,strfind}, @ref{doc-findstr,,findstr}, @ref{doc-strcmp,,strcmp}, @ref{doc-strncmp,,strncmp}, @ref{doc-strcmpi,,strcmpi}, @ref{doc-strncmpi,,strncmpi}, @ref{doc-find,,find}}
+ at end deftypefn
+
+
+ at c ./strings/strtok.m
+ at anchor{doc-strtok}
+ at deftypefn {Function File} {[@var{tok}, @var{rem}] =} strtok (@var{str}, @var{delim})
+
+Find all characters up to but not including the first character which
+is in the string delim.  If @var{rem} is requested, it contains the
+remainder of the string, starting at the first delimiter.  Leading
+delimiters are ignored.  If @var{delim} is not specified, space is
+assumed.  For example: 
+
+ at example
+ at group
+strtok ("this is the life")
+     @result{} "this"
+
+[tok, rem] = strtok ("14*27+31", "+-*/")
+     @result{}
+        tok = 14
+        rem = *27+31
+ at end group
+ at end example
+ at seealso{@ref{doc-index,,index}, @ref{doc-strsplit,,strsplit}}
+ at end deftypefn
+
+
+ at c ./strings/strsplit.m
+ at anchor{doc-strsplit}
+ at deftypefn {Function File} {[@var{s}] =} strsplit (@var{p}, @var{sep}, @var{strip_empty})
+Split a single string using one or more delimiters and return a cell
+array of strings.  Consecutive delimiters and delimiters at
+boundaries result in empty strings, unless @var{strip_empty} is true.
+The default value of @var{strip_empty} is false.
+ at seealso{@ref{doc-strtok,,strtok}}
+ at end deftypefn
+
+
+ at c ./strings/strrep.m
+ at anchor{doc-strrep}
+ at deftypefn {Function File} {} strrep (@var{s}, @var{x}, @var{y})
+Replace all occurrences of the substring @var{x} of the string @var{s}
+with the string @var{y} and return the result.  For example,
+
+ at example
+ at group
+strrep ("This is a test string", "is", "&%$")
+     @result{} "Th&%$ &%$ a test string"
+ at end group
+ at end example
+ at seealso{@ref{doc-regexprep,,regexprep}, @ref{doc-strfind,,strfind}, @ref{doc-findstr,,findstr}}
+ at end deftypefn
+
+
+ at c ./strings/substr.m
+ at anchor{doc-substr}
+ at deftypefn {Function File} {} substr (@var{s}, @var{offset}, @var{len})
+Return the substring of @var{s} which starts at character number
+ at var{offset} and is @var{len} characters long.
+
+If @var{offset} is negative, extraction starts that far from the end of
+the string.  If @var{len} is omitted, the substring extends to the end
+of S.
+
+For example,
+
+ at example
+ at group
+substr ("This is a test string", 6, 9)
+     @result{} "is a test"
+ at end group
+ at end example
+
+This function is patterned after AWK.  You can get the same result by
+ at code{@var{s}(@var{offset} : (@var{offset} + @var{len} - 1))}.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/regexp.cc
+ at anchor{doc-regexp}
+ at deftypefn {Loadable Function} {[@var{s}, @var{e}, @var{te}, @var{m}, @var{t}, @var{nm}] =} regexp (@var{str}, @var{pat})
+ at deftypefnx {Loadable Function} {[@dots{}] =} regexp (@var{str}, @var{pat}, @var{opts}, @dots{})
+
+Regular expression string matching.  Matches @var{pat} in @var{str} and
+returns the position and matching substrings or empty values if there are
+none.
+
+The matched pattern @var{pat} can include any of the standard regex
+operators, including:
+
+ at table @code
+ at item .
+Match any character
+ at item * + ? @{@}
+Repetition operators, representing
+ at table @code
+ at item *
+Match zero or more times
+ at item +
+Match one or more times
+ at item ?
+Match zero or one times
+ at item @{@}
+Match range operator, which is of the form @code{@{@var{n}@}} to match exactly
+ at var{n} times, @code{@{@var{m},@}} to match @var{m} or more times,
+ at code{@{@var{m}, at var{n}@}} to match between @var{m} and @var{n} times.
+ at end table
+ at item [@dots{}] [^@dots{}]
+List operators, where for example @code{[ab]c} matches @code{ac} and @code{bc}
+ at item ()
+Grouping operator
+ at item |
+Alternation operator.  Match one of a choice of regular expressions.  The
+alternatives must be delimited by the grouping operator @code{()} above
+ at item ^ $
+Anchoring operator.  @code{^} matches the start of the string @var{str} and
+ at code{$} the end
+ at end table
+
+In addition the following escaped characters have special meaning.  It should
+be noted that it is recommended to quote @var{pat} in single quotes rather
+than double quotes, to avoid the escape sequences being interpreted by Octave
+before being passed to @code{regexp}.
+
+ at table @code
+ at item \b
+Match a word boundary
+ at item \B
+Match within a word
+ at item \w
+Matches any word character
+ at item \W
+Matches any non word character
+ at item \<
+Matches the beginning of a word
+ at item \>
+Matches the end of a word
+ at item \s
+Matches any whitespace character
+ at item \S
+Matches any non whitespace character
+ at item \d
+Matches any digit
+ at item \D
+Matches any non-digit
+ at end table
+
+The outputs of @code{regexp} by default are in the order as given below
+
+ at table @asis
+ at item @var{s}
+The start indices of each of the matching substrings
+
+ at item @var{e}
+The end indices of each matching substring
+
+ at item @var{te}
+The extents of each of the matched token surrounded by @code{(@dots{})} in
+ at var{pat}.
+
+ at item @var{m}
+A cell array of the text of each match.
+
+ at item @var{t}
+A cell array of the text of each token matched.
+
+ at item @var{nm}
+A structure containing the text of each matched named token, with the name
+being used as the fieldname.  A named token is denoted as
+ at code{(?<name>@dots{})}
+ at end table
+
+Particular output arguments or the order of the output arguments can be
+selected by additional @var{opts} arguments.  These are strings and the
+correspondence between the output arguments and the optional argument
+are
+
+ at multitable @columnfractions 0.2 0.3 0.3 0.2
+ at item @tab 'start'        @tab @var{s}  @tab
+ at item @tab 'end'          @tab @var{e}  @tab
+ at item @tab 'tokenExtents' @tab @var{te} @tab
+ at item @tab 'match'        @tab @var{m}  @tab
+ at item @tab 'tokens'       @tab @var{t}  @tab
+ at item @tab 'names'        @tab @var{nm}  @tab
+ at end multitable
+
+A further optional argument is 'once', that limits the number of returned
+matches to the first match.  Additional arguments are
+
+ at table @asis
+ at item matchcase
+Make the matching case sensitive.
+ at item ignorecase
+Make the matching case insensitive.
+ at item stringanchors
+Match the anchor characters at the beginning and end of the string.
+ at item lineanchors
+Match the anchor characters at the beginning and end of the line.
+ at item dotall
+The character @code{.} matches the newline character.
+ at item dotexceptnewline
+The character @code{.} matches all but the newline character.
+ at item freespacing
+The pattern can include arbitrary whitespace and comments starting with
+ at code{#}.
+ at item literalspacing
+The pattern is taken literally.
+ at end table
+ at seealso{@ref{doc-regexpi,,regexpi}, @ref{doc-regexprep,,regexprep}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/regexp.cc
+ at anchor{doc-regexpi}
+ at deftypefn {Loadable Function} {[@var{s}, @var{e}, @var{te}, @var{m}, @var{t}, @var{nm}] =} regexpi (@var{str}, @var{pat})
+ at deftypefnx {Loadable Function} {[@dots{}] =} regexpi (@var{str}, @var{pat}, @var{opts}, @dots{})
+
+Case insensitive regular expression string matching.  Matches @var{pat} in
+ at var{str} and returns the position and matching substrings or empty values
+if there are none.  @xref{doc-regexp,,regexp}, for more details
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/regexp.cc
+ at anchor{doc-regexprep}
+ at deftypefn {Loadable Function}  {@var{string} =} regexprep (@var{string}, @var{pat}, @var{repstr}, @var{options})
+Replace matches of @var{pat} in  @var{string} with @var{repstr}.
+
+
+The replacement can contain @code{$i}, which substitutes
+for the ith set of parentheses in the match string.  E.g.,
+ at example
+ at group
+
+   regexprep("Bill Dunn",'(\w+) (\w+)','$2, $1')
+
+ at end group
+ at end example
+returns "Dunn, Bill"
+
+ at var{options} may be zero or more of
+ at table @samp
+
+ at item once
+Replace only the first occurrence of @var{pat} in the result.
+
+ at item warnings
+This option is present for compatibility but is ignored.
+
+ at item ignorecase or matchcase
+Ignore case for the pattern matching (see @code{regexpi}).
+Alternatively, use (?i) or (?-i) in the pattern.
+
+ at item lineanchors and stringanchors
+Whether characters ^ and $ match the beginning and ending of lines.
+Alternatively, use (?m) or (?-m) in the pattern.
+
+ at item dotexceptnewline and dotall
+Whether . matches newlines in the string.
+Alternatively, use (?s) or (?-s) in the pattern.
+
+ at item freespacing or literalspacing
+Whether whitespace and # comments can be used to make the regular expression more readable.
+Alternatively, use (?x) or (?-x) in the pattern.
+
+ at end table
+ at seealso{@ref{doc-regexp,,regexp}, @ref{doc-regexpi,,regexpi}, @ref{doc-strrep,,strrep}}
+ at end deftypefn
+
+
+ at c ./strings/regexptranslate.m
+ at anchor{doc-regexptranslate}
+ at deftypefn {Function File} {} regexptranslate (@var{op}, @var{s})
+Translate a string for use in a regular expression.  This might
+include either wildcard replacement or special character escaping.
+The behavior can be controlled by the @var{op} that can have the
+values
+
+ at table @asis
+ at item "wildcard"
+The wildcard characters @code{.}, @code{*} and @code{?} are replaced
+with wildcards that are appropriate for a regular expression. 
+For example:
+ at example
+ at group
+regexptranslate ("wildcard", "*.m")
+     @result{} ".*\.m"
+ at end group
+ at end example
+
+ at item "escape"
+The characters @code{$.?[]}, that have special meaning for regular
+expressions are escaped so that they are treated literally.  For example:
+ at example
+ at group
+regexptranslate ("escape", "12.5")
+     @result{} "12\.5"
+ at end group
+ at end example
+ at end table
+ at seealso{@ref{doc-regexp,,regexp}, @ref{doc-regexpi,,regexpi}, @ref{doc-regexprep,,regexprep}}
+ at end deftypefn
+
+
+ at node String Conversions
+ at section String Conversions
+
+Octave supports various kinds of conversions between strings and
+numbers.  As an example, it is possible to convert a string containing
+a hexadecimal number to a floating point number.
+
+ at example
+ at group
+hex2dec ("FF")
+     @result{} ans = 255
+ at end group
+ at end example
+
+ at c ./strings/bin2dec.m
+ at anchor{doc-bin2dec}
+ at deftypefn {Function File} {} bin2dec (@var{s})
+Return the decimal number corresponding to the binary number stored
+in the string @var{s}.  For example,
+
+ at example
+ at group
+bin2dec ("1110")
+     @result{} 14
+ at end group
+ at end example
+
+If @var{s} is a string matrix, returns a column vector of converted
+numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
+ at seealso{@ref{doc-dec2hex,,dec2hex}, @ref{doc-base2dec,,base2dec}, @ref{doc-dec2base,,dec2base}, @ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2bin,,dec2bin}}
+ at end deftypefn
+
+
+ at c ./strings/dec2bin.m
+ at anchor{doc-dec2bin}
+ at deftypefn {Function File} {} dec2bin (@var{n}, @var{len})
+Return a binary number corresponding to the non-negative decimal number
+ at var{n}, as a string of ones and zeros.  For example,
+
+ at example
+ at group
+dec2bin (14)
+     @result{} "1110"
+ at end group
+ at end example
+
+If @var{n} is a vector, returns a string matrix, one row per value,
+padded with leading zeros to the width of the largest value.
+
+The optional second argument, @var{len}, specifies the minimum
+number of digits in the result.
+ at seealso{@ref{doc-bin2dec,,bin2dec}, @ref{doc-dec2base,,dec2base}, @ref{doc-base2dec,,base2dec}, @ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2hex,,dec2hex}}
+ at end deftypefn
+
+
+ at c ./strings/dec2hex.m
+ at anchor{doc-dec2hex}
+ at deftypefn {Function File} {} dec2hex (@var{n}, @var{len})
+Return the hexadecimal string corresponding to the non-negative 
+integer @var{n}.  For example,
+
+ at example
+ at group
+dec2hex (2748)
+     @result{} "ABC"
+ at end group
+ at end example
+
+If @var{n} is a vector, returns a string matrix, one row per value,
+padded with leading zeros to the width of the largest value.
+
+The optional second argument, @var{len}, specifies the minimum
+number of digits in the result.
+ at seealso{@ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2base,,dec2base}, @ref{doc-base2dec,,base2dec}, @ref{doc-bin2dec,,bin2dec}, @ref{doc-dec2bin,,dec2bin}}
+ at end deftypefn
+
+
+ at c ./strings/hex2dec.m
+ at anchor{doc-hex2dec}
+ at deftypefn {Function File} {} hex2dec (@var{s})
+Return the integer corresponding to the hexadecimal number stored
+in the string @var{s}.  For example,
+
+ at example
+ at group
+hex2dec ("12B")
+     @result{} 299
+hex2dec ("12b")
+     @result{} 299
+ at end group
+ at end example
+
+If @var{s} is a string matrix, returns a column vector of converted
+numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
+ at seealso{@ref{doc-dec2hex,,dec2hex}, @ref{doc-base2dec,,base2dec}, @ref{doc-dec2base,,dec2base}, @ref{doc-bin2dec,,bin2dec}, @ref{doc-dec2bin,,dec2bin}}
+ at end deftypefn
+
+
+ at c ./strings/dec2base.m
+ at anchor{doc-dec2base}
+ at deftypefn {Function File} {} dec2base (@var{n}, @var{b}, @var{len})
+Return a string of symbols in base @var{b} corresponding to
+the non-negative integer @var{n}.
+
+ at example
+ at group
+dec2base (123, 3)
+     @result{} "11120"
+ at end group
+ at end example
+
+If @var{n} is a vector, return a string matrix with one row per value,
+padded with leading zeros to the width of the largest value.
+
+If @var{b} is a string then the characters of @var{b} are used as
+the symbols for the digits of @var{n}.  Space (' ') may not be used
+as a symbol.
+
+ at example
+ at group
+dec2base (123, "aei")
+     @result{} "eeeia"
+ at end group
+ at end example
+
+The optional third argument, @var{len}, specifies the minimum
+number of digits in the result.
+ at seealso{@ref{doc-base2dec,,base2dec}, @ref{doc-dec2bin,,dec2bin}, @ref{doc-bin2dec,,bin2dec}, @ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2hex,,dec2hex}}
+ at end deftypefn
+
+
+ at c ./strings/base2dec.m
+ at anchor{doc-base2dec}
+ at deftypefn {Function File} {} base2dec (@var{s}, @var{b})
+Convert @var{s} from a string of digits of base @var{b} into an
+integer.
+
+ at example
+ at group
+base2dec ("11120", 3)
+     @result{} 123
+ at end group
+ at end example
+
+If @var{s} is a matrix, returns a column vector with one value per
+row of @var{s}.  If a row contains invalid symbols then the
+corresponding value will be NaN.  Rows are right-justified before
+converting so that trailing spaces are ignored.
+
+If @var{b} is a string, the characters of @var{b} are used as the
+symbols for the digits of @var{s}.  Space (' ') may not be used as a
+symbol.
+
+ at example
+ at group
+base2dec ("yyyzx", "xyz")
+     @result{} 123
+ at end group
+ at end example
+ at seealso{@ref{doc-dec2base,,dec2base}, @ref{doc-dec2bin,,dec2bin}, @ref{doc-bin2dec,,bin2dec}, @ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2hex,,dec2hex}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/hex2num.cc
+ at anchor{doc-num2hex}
+ at deftypefn {Loadable Function} {@var{s} =} num2hex (@var{n})
+Typecast a double precision number or vector to a 16 character hexadecimal
+string of the IEEE 754 representation of the number.  For example
+
+ at example
+ at group
+num2hex ([-1, 1, e, Inf, NaN, NA]);
+ at result{} "bff0000000000000
+    3ff0000000000000
+    4005bf0a8b145769
+    7ff0000000000000
+    fff8000000000000
+    7ff00000000007a2"
+ at end group
+ at end example
+ at seealso{@ref{doc-hex2num,,hex2num}, @ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2hex,,dec2hex}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/hex2num.cc
+ at anchor{doc-hex2num}
+ at deftypefn {Loadable Function} {@var{n} =} hex2num (@var{s})
+Typecast the 16 character hexadecimal character matrix to an IEEE 754
+double precision number.  If fewer than 16 characters are given the
+strings are right padded with '0' characters.
+
+Given a string matrix, @code{hex2num} treats each row as a separate
+number.
+
+ at example
+ at group
+hex2num (["4005bf0a8b145769";"4024000000000000"])
+ at result{} [2.7183; 10.000]
+ at end group
+ at end example
+ at seealso{@ref{doc-num2hex,,num2hex}, @ref{doc-hex2dec,,hex2dec}, @ref{doc-dec2hex,,dec2hex}}
+ at end deftypefn
+
+
+ at c ./strings/str2double.m
+ at anchor{doc-str2double}
+ at deftypefn {Function File} {[@var{num}, @var{status}, @var{strarray}] =} str2double (@var{str}, @var{cdelim}, @var{rdelim}, @var{ddelim})
+Convert strings into numeric values.
+
+ at code{str2double} can replace @code{str2num}, but avoids the use of
+ at code{eval} on unknown data.
+
+ at var{str} can be the form @samp{[+-]d[.]dd[[eE][+-]ddd]} in which
+ at samp{d} can be any of digit from 0 to 9, and @samp{[]} indicate
+optional elements.
+
+ at var{num} is the corresponding numeric value.  If the conversion
+fails, status is -1 and @var{num} is NaN.
+
+ at var{status} is 0 if the conversion was successful and -1 otherwise.
+
+ at var{strarray} is a cell array of strings.
+
+Elements which are not defined or not valid return NaN and the
+ at var{status} becomes -1.
+
+If @var{str} is a character array or a cell array of strings, then
+ at var{num} and @var{status} return matrices of appropriate size. 
+
+ at var{str} can also contain multiple elements separated by row and
+column delimiters (@var{cdelim} and @var{rdelim}).
+
+The parameters @var{cdelim}, @var{rdelim}, and @var{ddelim} are
+optional column, row, and decimal delimiters.
+
+The default row-delimiters are newline, carriage return and semicolon
+(ASCII 10, 13 and 59).  The default column-delimiters are tab, space
+and comma (ASCII 9, 32, and 44).  The default decimal delimiter is
+ at samp{.} (ASCII 46).
+
+ at var{cdelim}, @var{rdelim}, and @var{ddelim} must contain only nul,
+newline, carriage return, semicolon, colon, slash, tab, space, comma,
+or @samp{()[]@{@}} (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40,
+41, 44, 47, 58, 59, 91, 93, 123, 124, 125).
+
+Examples:
+
+ at example
+ at group
+str2double ("-.1e-5")
+ at result{} -1.0000e-006
+
+str2double (".314e1, 44.44e-1, .7; -1e+1")
+ at result{}
+   3.1400    4.4440    0.7000
+ -10.0000       NaN       NaN
+
+line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+[x, status] = str2double (line)
+ at result{} x =
+    200   300   NaN  -Inf   NaN   NaN   999   NaN   NaN
+ at result{} status =
+      0     0     0     0    -1    -1     0    -1     0
+ at end group
+ at end example
+ at seealso{@ref{doc-str2num,,str2num}}
+ at end deftypefn
+
+
+ at c ./strings/strjust.m
+ at anchor{doc-strjust}
+ at deftypefn {Function File} {} strjust (@var{s}, ["left"|"right"|"center"])
+Shift the non-blank text of @var{s} to the left, right or center of
+the string.  If @var{s} is a string array, justify each string in the
+array.  Null characters are replaced by blanks.  If no justification
+is specified, then all rows are right-justified.  For example:
+
+ at example
+ at group
+strjust (["a"; "ab"; "abc"; "abcd"])
+     @result{} ans =
+           a
+          ab
+         abc
+        abcd
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./strings/str2num.m
+ at anchor{doc-str2num}
+ at deftypefn {Function File} {} str2num (@var{s})
+Convert the string (or character array) @var{s} to a number (or an
+array).  Examples:  
+
+ at example
+ at group
+str2num("3.141596")
+     @result{} 3.141596
+
+str2num(["1, 2, 3"; "4, 5, 6"]);
+     @result{} ans =
+        1  2  3
+        4  5  6
+ at end group
+ at end example
+
+ at strong{Caution:} As @code{str2num} uses the @code{eval} function
+to do the conversion, @code{str2num} will execute any code contained
+in the string @var{s}.  Use @code{str2double} instead if you want to
+avoid the use of @code{eval}. 
+ at seealso{@ref{doc-str2double,,str2double}, @ref{doc-eval,,eval}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-toascii}
+ at deftypefn {Mapping Function} {} toascii (@var{s})
+Return ASCII representation of @var{s} in a matrix.  For example,
+
+ at example
+ at group
+toascii ("ASCII")
+     @result{} [ 65, 83, 67, 73, 73 ]
+ at end group
+
+ at end example
+ at seealso{@ref{doc-char,,char}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-tolower}
+ at deftypefn {Mapping Function} {} tolower (@var{s})
+ at deftypefnx {Mapping Function} {} lower (@var{s})
+Return a copy of the string or cell string @var{s}, with each upper-case
+character replaced by the corresponding lower-case one; non-alphabetic
+characters are left unchanged.  For example,
+
+ at example
+ at group
+tolower ("MiXeD cAsE 123")
+     @result{} "mixed case 123"
+ at end group
+ at end example
+ at seealso{@ref{doc-toupper,,toupper}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-toupper}
+ at deftypefn {Built-in Function} {} toupper (@var{s})
+ at deftypefnx {Built-in Function} {} upper (@var{s})
+Return a copy of the string or cell string @var{s}, with each lower-case
+character replaced by the corresponding upper-case one; non-alphabetic
+characters are left unchanged.  For example,
+
+ at example
+ at group
+toupper ("MiXeD cAsE 123")
+     @result{} "MIXED CASE 123"
+ at end group
+ at end example
+ at seealso{@ref{doc-tolower,,tolower}}
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-do_string_escapes}
+ at deftypefn {Built-in Function} {} do_string_escapes (@var{string})
+Convert special characters in @var{string} to their escaped forms.
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-undo_string_escapes}
+ at deftypefn {Built-in Function} {} undo_string_escapes (@var{s})
+Converts special characters in strings back to their escaped forms.  For
+example, the expression
+
+ at example
+bell = "\a";
+ at end example
+
+ at noindent
+assigns the value of the alert character (control-g, ASCII code 7) to
+the string variable @code{bell}.  If this string is printed, the
+system will ring the terminal bell (if it is possible).  This is
+normally the desired outcome.  However, sometimes it is useful to be
+able to print the original representation of the string, with the
+special characters replaced by their escape sequences.  For example,
+
+ at example
+ at group
+octave:13> undo_string_escapes (bell)
+ans = \a
+ at end group
+ at end example
+
+ at noindent
+replaces the unprintable alert character with its printable
+representation.
+ at end deftypefn
+
+
+ at node Character Class Functions
+ at section Character Class Functions
+
+Octave also provides the following character class test functions
+patterned after the functions in the standard C library.  They all
+operate on string arrays and return matrices of zeros and ones.
+Elements that are nonzero indicate that the condition was true for the
+corresponding character in the string array.  For example,
+
+ at example
+ at group
+isalpha ("!Q@@WERT^Y&")
+     @result{} [ 0, 1, 0, 1, 1, 1, 1, 0, 1, 0 ]
+ at end group
+ at end example
+
+ at c mappers.cc
+ at anchor{doc-isalnum}
+ at deftypefn {Mapping Function} {} isalnum (@var{s})
+Return 1 for characters that are letters or digits (@code{isalpha
+(@var{s})} or @code{isdigit (@var{s})} is true).
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isalpha}
+ at deftypefn {Mapping Function} {} isalpha (@var{s})
+ at deftypefnx {Mapping Function} {} isletter (@var{s})
+Return true for characters that are letters (@code{isupper (@var{s})}
+or @code{islower (@var{s})} is true).
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isascii}
+ at deftypefn {Mapping Function} {} isascii (@var{s})
+Return 1 for characters that are ASCII (in the range 0 to 127 decimal).
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-iscntrl}
+ at deftypefn {Mapping Function} {} iscntrl (@var{s})
+Return 1 for control characters.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isdigit}
+ at deftypefn {Mapping Function} {} isdigit (@var{s})
+Return 1 for characters that are decimal digits.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isgraph}
+ at deftypefn {Mapping Function} {} isgraph (@var{s})
+Return 1 for printable characters (but not the space character).
+ at end deftypefn
+
+
+ at c ./strings/isletter.m
+ at anchor{doc-isletter}
+ at deftypefn {Function File} {} isletter (@var{s})
+Returns true if @var{s} is a letter, false otherwise.
+ at seealso{@ref{doc-isalpha,,isalpha}}
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-islower}
+ at deftypefn {Mapping Function} {} islower (@var{s})
+Return 1 for characters that are lower case letters.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isprint}
+ at deftypefn {Mapping Function} {} isprint (@var{s})
+Return 1 for printable characters (including the space character).
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-ispunct}
+ at deftypefn {Mapping Function} {} ispunct (@var{s})
+Return 1 for punctuation characters.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isspace}
+ at deftypefn {Mapping Function} {} isspace (@var{s})
+Return 1 for whitespace characters (space, formfeed, newline,
+carriage return, tab, and vertical tab).
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isupper}
+ at deftypefn {Mapping Function} {} isupper (@var{s})
+Return 1 for upper case letters.
+ at end deftypefn
+
+
+ at c mappers.cc
+ at anchor{doc-isxdigit}
+ at deftypefn {Mapping Function} {} isxdigit (@var{s})
+Return 1 for characters that are hexadecimal digits.
+ at end deftypefn
+
+
+ at c ./strings/isstrprop.m
+ at anchor{doc-isstrprop}
+ at deftypefn {Function File} {} isstrprop (@var{str}, @var{pred})
+Test character string properties.  For example,
+
+ at example
+ at group
+isstrprop ("abc123", "alpha")
+ at result{} [1, 1, 1, 0, 0, 0]
+ at end group
+ at end example
+
+If @var{str} is a cell array, @code{isstrpop} is applied recursively
+to each element of the cell array.
+
+Numeric arrays are converted to character strings.
+
+The second argument @var{pred} may be one of
+
+ at table @code
+ at item "alpha"
+True for characters that are alphabetic
+
+ at item "alnum"
+ at itemx "alphanum"
+True for characters that are alphabetic or digits.
+
+ at item "ascii"
+True for characters that are in the range of ASCII encoding.
+
+ at item "cntrl"
+True for control characters.
+
+ at item "digit"
+True for decimal digits.
+
+ at item "graph"
+ at itemx "graphic"
+True for printing characters except space.
+
+ at item "lower"
+True for lower-case letters.
+
+ at item "print"
+True for printing characters including space.
+
+ at item "punct"
+True for printing characters except space or letter or digit.
+
+ at item "space"
+ at itemx "wspace"
+True for whitespace characters (space, formfeed, newline, carriage
+return, tab, vertical tab).
+
+ at item "upper"
+True for upper-case letters.
+
+ at item "xdigit"
+True for hexadecimal digits.
+ at end table
+
+ at seealso{@ref{doc-isalnum,,isalnum}, @ref{doc-isalpha,,isalpha}, @ref{doc-isascii,,isascii}, @ref{doc-iscntrl,,iscntrl}, @ref{doc-isdigit,,isdigit}, @ref{doc-isgraph,,isgraph}, @ref{doc-islower,,islower}, @ref{doc-isprint,,isprint}, @ref{doc-ispunct,,ispunct}, @ref{doc-isspace,,isspace}, @ref{doc-isupper,,isupper}, @ref{doc-isxdigit,,isxdigit}}
+ at end deftypefn
+
diff --git a/doc/interpreter/strings.txi b/doc/interpreter/strings.txi
new file mode 100644
index 0000000..aa80d3b
--- /dev/null
+++ b/doc/interpreter/strings.txi
@@ -0,0 +1,539 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005,
+ at c               2006, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Strings
+ at chapter Strings
+ at cindex strings
+ at cindex character strings
+ at opindex "
+ at opindex '
+
+A @dfn{string constant} consists of a sequence of characters enclosed in
+either double-quote or single-quote marks.  For example, both of the
+following expressions
+
+ at example
+ at group
+"parrot"
+'parrot'
+ at end group
+ at end example
+
+ at noindent
+represent the string whose contents are @samp{parrot}.  Strings in
+Octave can be of any length.
+
+Since the single-quote mark is also used for the transpose operator
+(@pxref{Arithmetic Ops}) but double-quote marks have no other purpose in Octave,
+it is best to use double-quote marks to denote strings.
+
+Strings can be concatenated using the notation for defining matrices.  For
+example, the expression 
+ 
+ at example
+[ "foo" , "bar" , "baz" ]
+ at end example
+
+ at noindent
+produces the string whose contents are @samp{foobarbaz}.  @xref{Numeric Data
+Types}, for more information about creating matrices.
+
+ at menu
+* Escape Sequences in string constants::
+* Character Arrays::
+* Creating Strings:: 
+* Comparing Strings::           
+* Manipulating Strings::     
+* String Conversions::          
+* Character Class Functions::   
+ at end menu
+
+ at node Escape Sequences in string constants
+ at section Escape Sequences in string constants
+ at cindex escape sequence notation
+In double-quoted strings, the backslash character is used to introduce
+ at dfn{escape sequences} that represent other characters.  For example,
+ at samp{\n} embeds a newline character in a double-quoted string and
+ at samp{\"} embeds a double quote character.  In single-quoted strings, backslash
+is not a special character.  Here is an example showing the difference:
+
+ at example
+ at group
+toascii ("\n")
+    @result{} 10
+toascii ('\n')
+    @result{} [ 92 110 ]
+ at end group
+ at end example
+
+Here is a table of all the escape sequences used in Octave (within
+double quoted strings).  They are the same as those used in the C 
+programming language.
+
+ at table @code
+ at item \\
+Represents a literal backslash, @samp{\}.
+
+ at item \"
+Represents a literal double-quote character, @samp{"}.
+
+ at item \'
+Represents a literal single-quote character, @samp{'}.
+
+ at item \0
+Represents the ``nul'' character, control-@@, ASCII code 0.
+
+ at item \a
+Represents the ``alert'' character, control-g, ASCII code 7.
+
+ at item \b
+Represents a backspace, control-h, ASCII code 8.
+
+ at item \f
+Represents a formfeed, control-l, ASCII code 12.
+
+ at item \n
+Represents a newline, control-j, ASCII code 10.
+
+ at item \r
+Represents a carriage return, control-m, ASCII code 13.
+
+ at item \t
+Represents a horizontal tab, control-i, ASCII code 9.
+
+ at item \v
+Represents a vertical tab, control-k, ASCII code 11.
+
+ at c We don't do octal or hex this way yet.
+ at c
+ at c @item \@var{nnn}
+ at c Represents the octal value @var{nnn}, where @var{nnn} are one to three
+ at c digits between 0 and 7.  For example, the code for the ASCII ESC
+ at c (escape) character is @samp{\033}. at refill
+ at c 
+ at c @item \x at var{hh}@dots{}
+ at c Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal
+ at c digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or
+ at c @samp{a} through @samp{f}).  Like the same construct in @sc{ansi} C,
+ at c the escape 
+ at c sequence continues until the first non-hexadecimal digit is seen.  However,
+ at c using more than two hexadecimal digits produces undefined results.  (The
+ at c @samp{\x} escape sequence is not allowed in @sc{posix} @code{awk}.)@refill
+ at end table
+
+In a single-quoted string there is only one escape sequence: you may insert a
+single quote character using two single quote characters in succession.  For
+example,
+
+ at example
+ at group
+'I can''t escape'
+    @result{} I can't escape
+ at end group
+ at end example
+
+
+ at node Character Arrays
+ at section Character Arrays
+
+The string representation used by Octave is an array of characters, so
+internally the string "dddddddddd" is actually a row vector of length 10
+containing the value 100 in all places (100 is the ASCII code of "d").  This
+lends itself to the obvious generalization to character matrices.  Using a
+matrix of characters, it is possible to represent a collection of same-length
+strings in one variable.  The convention used in Octave is that each row in a
+character matrix is a separate string, but letting each column represent a
+string is equally possible.
+
+The easiest way to create a character matrix is to put several strings
+together into a matrix.
+
+ at example
+collection = [ "String #1"; "String #2" ];
+ at end example
+
+ at noindent
+This creates a 2-by-9 character matrix.
+
+The function @code{ischar} can be used to test if an object is a character
+matrix.
+
+ at DOCSTRING(ischar)
+
+To test if an object is a string (i.e., a character vector and not a character
+matrix) you can use the @code{ischar} function in combination with the
+ at code{isvector} function as in the following example:
+
+ at example
+ at group
+ischar(collection)
+     @result{} ans = 1
+
+ischar(collection) && isvector(collection)
+     @result{} ans = 0
+
+ischar("my string") && isvector("my string")
+     @result{} ans = 1
+ at end group
+ at end example
+
+One relevant question is, what happens when a character matrix is
+created from strings of different length.  The answer is that Octave
+puts blank characters at the end of strings shorter than the longest
+string.  It is possible to use a different character than the
+blank character using the @code{string_fill_char} function.
+
+ at DOCSTRING(string_fill_char)
+
+This shows a problem with character matrices.  It simply isn't possible to
+represent strings of different lengths.  The solution is to use a cell array of
+strings, which is described in @ref{Cell Arrays of Strings}.
+
+ at node Creating Strings
+ at section Creating Strings
+
+The easiest way to create a string is, as illustrated in the introduction,
+to enclose a text in double-quotes or single-quotes.  It is however
+possible to create a string without actually writing a text.  The
+function @code{blanks} creates a string of a given length consisting
+only of blank characters (ASCII code 32).
+
+ at DOCSTRING(blanks)
+
+ at menu
+* Concatenating Strings:: 
+* Conversion of Numerical Data to Strings::
+ at end menu
+
+ at node Concatenating Strings
+ at subsection Concatenating Strings
+
+It has been shown above that strings can be concatenated using matrix notation
+(@pxref{Strings}, @ref{Character Arrays}).  Apart from that, there are several
+functions to concatenate string objects: @code{char},
+ at code{strvcat}, @code{strcat} and @code{cstrcat}.  In addition, the general
+purpose concatenation functions can be used: see @ref{doc-cat,,cat},
+ at ref{doc-horzcat,,horzcat} and @ref{doc-vertcat,,vertcat}.
+
+ at itemize @bullet
+ at item All string concatenation functions except @code{cstrcat}
+convert numerical input into character data by taking the corresponding ASCII
+character for each element, as in the following example:
+
+ at example
+ at group
+char([98, 97, 110, 97, 110, 97])
+     @result{} ans =
+       banana
+ at end group
+ at end example
+
+ at item
+ at code{char} and @code{strvcat}
+concatenate vertically, while @code{strcat} and @code{cstrcat} concatenate
+horizontally.  For example:
+
+ at example
+ at group
+char("an apple", "two pears")
+     @result{} ans =
+       an apple
+       two pears
+ at end group
+
+ at group
+strcat("oc", "tave", " is", " good", " for you")
+     @result{} ans =
+       octave is good for you
+ at end group
+ at end example
+
+ at item @code{char} generates an empty row in the output
+for each empty string in the input.  @code{strvcat}, on the other hand,
+eliminates empty strings.
+
+ at example
+ at group
+char("orange", "green", "", "red")
+     @result{} ans =
+       orange
+       green 
+             
+       red   
+ at end group
+
+ at group
+strvcat("orange", "green", "", "red")
+     @result{} ans =
+       orange
+       green 
+       red  
+ at end group
+ at end example
+
+ at item All string concatenation functions except @code{cstrcat} also accept cell
+array data (@pxref{Cell Arrays}).  @code{char} and
+ at code{strvcat} convert cell arrays into character arrays, while @code{strcat}
+concatenates within the cells of the cell arrays:
+
+ at example
+ at group
+char(@{"red", "green", "", "blue"@})
+     @result{} ans =
+       red  
+       green
+
+       blue 
+ at end group
+
+ at group
+strcat(@{"abc"; "ghi"@}, @{"def"; "jkl"@})
+     @result{} ans =
+       @{
+         [1,1] = abcdef
+         [2,1] = ghijkl
+       @}
+ at end group
+ at end example
+
+ at item @code{strcat} removes trailing white space in the arguments (except
+within cell arrays), while @code{cstrcat} leaves white space untouched.  Both
+kinds of behavior can be useful as can be seen in the examples:
+
+ at example
+ at group
+strcat(["dir1";"directory2"], ["/";"/"], ["file1";"file2"])
+     @result{} ans =
+       dir1/file1      
+       directory2/file2
+ at end group
+ at group
+
+cstrcat(["thirteen apples"; "a banana"], [" 5$";" 1$"])
+     @result{} ans =
+       thirteen apples 5$
+       a banana        1$
+ at end group
+ at end example
+
+Note that in the above example for @code{cstrcat}, the white space originates
+from the internal representation of the strings in a string array
+(@pxref{Character Arrays}).
+ at end itemize
+
+ at DOCSTRING(char)
+
+ at DOCSTRING(strvcat)
+
+ at DOCSTRING(strcat)
+
+ at DOCSTRING(cstrcat)
+
+ at node Conversion of Numerical Data to Strings 
+ at subsection Conversion of Numerical Data to Strings
+Apart from the string concatenation functions (@pxref{Concatenating Strings})
+which cast numerical data to the corresponding ASCII characters, there are
+several functions that format numerical data as strings.  @code{mat2str} and
+ at code{num2str} convert real or complex matrices, while @code{int2str} converts
+integer matrices.  @code{int2str} takes the real part of complex values and
+round fractional values to integer.  A more flexible way to format numerical
+data as strings is the @code{sprintf} function (@pxref{Formatted Output},
+ at ref{doc-sprintf}).
+
+ at DOCSTRING(mat2str)
+
+ at DOCSTRING(num2str)
+
+ at DOCSTRING(int2str)
+
+ at node Comparing Strings
+ at section Comparing Strings
+
+Since a string is a character array, comparisons between strings work
+element by element as the following example shows:
+
+ at example
+ at group
+GNU = "GNU's Not UNIX";
+spaces = (GNU == " ")
+     @result{} spaces =
+       0   0   0   0   0   1   0   0   0   1   0   0   0   0
+ at end group
+ at end example
+
+ at noindent To determine if two strings are identical it is necessary to use the
+ at code{strcmp} function.  It compares complete strings and is case
+sensitive.  @code{strncmp} compares only the first @code{N} characters (with
+ at code{N} given as a parameter).  @code{strcmpi} and @code{strncmpi} are the
+corresponding functions for case-insensitive comparison.
+
+ at DOCSTRING(strcmp)
+
+ at DOCSTRING(strncmp)
+
+ at DOCSTRING(strcmpi)
+
+ at DOCSTRING(strncmpi)
+
+ at DOCSTRING(validatestring)
+
+ at node Manipulating Strings
+ at section Manipulating Strings
+
+Octave supports a wide range of functions for manipulating strings.
+Since a string is just a matrix, simple manipulations can be accomplished
+using standard operators.  The following example shows how to replace
+all blank characters with underscores.
+
+ at example
+ at group
+quote = ...
+  "First things first, but not necessarily in that order";
+quote( quote == " " ) = "_"
+ at result{} quote = 
+    First_things_first,_but_not_necessarily_in_that_order
+ at end group
+ at end example
+
+For more complex manipulations, such as searching, replacing, and
+general regular expressions, the following functions come with Octave.
+
+ at DOCSTRING(deblank)
+
+ at DOCSTRING(strtrim)
+
+ at DOCSTRING(strtrunc)
+
+ at DOCSTRING(findstr)
+
+ at DOCSTRING(strchr)
+
+ at DOCSTRING(index)
+
+ at DOCSTRING(rindex)
+
+ at DOCSTRING(strfind)
+
+ at DOCSTRING(strmatch)
+
+ at DOCSTRING(strtok)
+
+ at DOCSTRING(strsplit)
+
+ at DOCSTRING(strrep)
+
+ at DOCSTRING(substr)
+
+ at DOCSTRING(regexp)
+
+ at DOCSTRING(regexpi)
+
+ at DOCSTRING(regexprep)
+
+ at DOCSTRING(regexptranslate)
+
+ at node String Conversions
+ at section String Conversions
+
+Octave supports various kinds of conversions between strings and
+numbers.  As an example, it is possible to convert a string containing
+a hexadecimal number to a floating point number.
+
+ at example
+ at group
+hex2dec ("FF")
+     @result{} ans = 255
+ at end group
+ at end example
+
+ at DOCSTRING(bin2dec)
+
+ at DOCSTRING(dec2bin)
+
+ at DOCSTRING(dec2hex)
+
+ at DOCSTRING(hex2dec)
+
+ at DOCSTRING(dec2base)
+
+ at DOCSTRING(base2dec)
+
+ at DOCSTRING(num2hex)
+
+ at DOCSTRING(hex2num)
+
+ at DOCSTRING(str2double)
+
+ at DOCSTRING(strjust)
+
+ at DOCSTRING(str2num)
+
+ at DOCSTRING(toascii)
+
+ at DOCSTRING(tolower)
+
+ at DOCSTRING(toupper)
+
+ at DOCSTRING(do_string_escapes)
+
+ at DOCSTRING(undo_string_escapes)
+
+ at node Character Class Functions
+ at section Character Class Functions
+
+Octave also provides the following character class test functions
+patterned after the functions in the standard C library.  They all
+operate on string arrays and return matrices of zeros and ones.
+Elements that are nonzero indicate that the condition was true for the
+corresponding character in the string array.  For example,
+
+ at example
+ at group
+isalpha ("!Q@@WERT^Y&")
+     @result{} [ 0, 1, 0, 1, 1, 1, 1, 0, 1, 0 ]
+ at end group
+ at end example
+
+ at DOCSTRING(isalnum)
+
+ at DOCSTRING(isalpha)
+
+ at DOCSTRING(isascii)
+
+ at DOCSTRING(iscntrl)
+
+ at DOCSTRING(isdigit)
+
+ at DOCSTRING(isgraph)
+
+ at DOCSTRING(isletter)
+
+ at DOCSTRING(islower)
+
+ at DOCSTRING(isprint)
+
+ at DOCSTRING(ispunct)
+
+ at DOCSTRING(isspace)
+
+ at DOCSTRING(isupper)
+
+ at DOCSTRING(isxdigit)
+
+ at DOCSTRING(isstrprop)
diff --git a/doc/interpreter/system.texi b/doc/interpreter/system.texi
new file mode 100644
index 0000000..ab6692c
--- /dev/null
+++ b/doc/interpreter/system.texi
@@ -0,0 +1,2642 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node System Utilities
+ at chapter System Utilities
+
+This chapter describes the functions that are available to allow you to
+get information about what is happening outside of Octave, while it is
+still running, and use this information in your program.  For example,
+you can get information about environment variables, the current time,
+and even start other programs from the Octave prompt.
+
+ at menu
+* Timing Utilities::            
+* Filesystem Utilities::        
+* File Archiving Utilities::
+* Networking Utilities::
+* Controlling Subprocesses::    
+* Process ID Information::      
+* Environment Variables::       
+* Current Working Directory::   
+* Password Database Functions::  
+* Group Database Functions::    
+* System Information::          
+* Hashing Functions::
+ at end menu
+
+ at node Timing Utilities
+ at section Timing Utilities
+
+Octave's core set of functions for manipulating time values are
+patterned after the corresponding functions from the standard C library.
+Several of these functions use a data structure for time that includes
+the following elements:
+
+ at table @code
+ at item usec
+Microseconds after the second (0-999999).
+
+ at item sec
+Seconds after the minute (0-61).  This number can be 61 to account
+for leap seconds.
+
+ at item min
+Minutes after the hour (0-59).
+
+ at item hour
+Hours since midnight (0-23).
+
+ at item mday
+Day of the month (1-31).
+
+ at item mon
+Months since January (0-11).
+
+ at item year
+Years since 1900.
+
+ at item wday
+Days since Sunday (0-6).
+
+ at item yday
+Days since January 1 (0-365).
+
+ at item isdst
+Daylight Savings Time flag.
+
+ at item zone
+Time zone.
+ at end table
+
+ at noindent
+In the descriptions of the following functions, this structure is
+referred to as a @var{tm_struct}.
+
+ at c ./DLD-FUNCTIONS/time.cc
+ at anchor{doc-time}
+ at deftypefn {Loadable Function} {} time ()
+Return the current time as the number of seconds since the epoch.  The
+epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan
+1970.  For example, on Monday February 17, 1997 at 07:15:06 CUT, the
+value returned by @code{time} was 856163706.
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-strptime,,strptime}, @ref{doc-localtime,,localtime}, @ref{doc-gmtime,,gmtime}, @ref{doc-mktime,,mktime}, @ref{doc-now,,now}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./time/now.m
+ at anchor{doc-now}
+ at deftypefn {Function File} {t =} now ()
+Returns the current local time as the number of days since Jan 1, 0000.
+By this reckoning, Jan 1, 1970 is day number 719529.
+
+The integral part, @code{floor (now)} corresponds to 00:00:00 today.
+
+The fractional part, @code{rem (now, 1)} corresponds to the current
+time on Jan 1, 0000.
+
+The returned value is also called a "serial date number"
+(see @code{datenum}).
+ at seealso{@ref{doc-clock,,clock}, @ref{doc-date,,date}, @ref{doc-datenum,,datenum}}
+ at end deftypefn
+
+
+ at c ./time/ctime.m
+ at anchor{doc-ctime}
+ at deftypefn {Function File} {} ctime (@var{t})
+Convert a value returned from @code{time} (or any other non-negative
+integer), to the local time and return a string of the same form as
+ at code{asctime}.  The function @code{ctime (time)} is equivalent to
+ at code{asctime (localtime (time))}.  For example,
+
+ at example
+ at group
+ctime (time ())
+     @result{} "Mon Feb 17 01:15:06 1997\n"
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/time.cc
+ at anchor{doc-gmtime}
+ at deftypefn {Loadable Function} {} gmtime (@var{t})
+Given a value returned from time (or any non-negative integer),
+return a time structure corresponding to CUT.  For example,
+
+ at example
+ at group
+gmtime (time ())
+     @result{} @{
+           usec = 0
+           year = 97
+           mon = 1
+           mday = 17
+           sec = 6
+           zone = CST
+           min = 15
+           wday = 1
+           hour = 7
+           isdst = 0
+           yday = 47
+         @}
+ at end group
+ at end example
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-strptime,,strptime}, @ref{doc-localtime,,localtime}, @ref{doc-mktime,,mktime}, @ref{doc-time,,time}, @ref{doc-now,,now}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/time.cc
+ at anchor{doc-localtime}
+ at deftypefn {Loadable Function} {} localtime (@var{t})
+Given a value returned from time (or any non-negative integer),
+return a time structure corresponding to the local time zone.
+
+ at example
+ at group
+localtime (time ())
+     @result{} @{
+           usec = 0
+           year = 97
+           mon = 1
+           mday = 17
+           sec = 6
+           zone = CST
+           min = 15
+           wday = 1
+           hour = 1
+           isdst = 0
+           yday = 47
+         @}
+ at end group
+ at end example
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-strptime,,strptime}, @ref{doc-gmtime,,gmtime}, @ref{doc-mktime,,mktime}, @ref{doc-time,,time}, @ref{doc-now,,now}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/time.cc
+ at anchor{doc-mktime}
+ at deftypefn {Loadable Function} {} mktime (@var{tm_struct})
+Convert a time structure corresponding to the local time to the number
+of seconds since the epoch.  For example,
+
+ at example
+ at group
+mktime (localtime (time ()))
+     @result{} 856163706
+ at end group
+ at end example
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-strptime,,strptime}, @ref{doc-localtime,,localtime}, @ref{doc-gmtime,,gmtime}, @ref{doc-time,,time}, @ref{doc-now,,now}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./time/asctime.m
+ at anchor{doc-asctime}
+ at deftypefn {Function File} {} asctime (@var{tm_struct})
+Convert a time structure to a string using the following five-field
+format: Thu Mar 28 08:40:14 1996.  For example,
+
+ at example
+ at group
+asctime (localtime (time ()))
+     @result{} "Mon Feb 17 01:15:06 1997\n"
+ at end group
+ at end example
+
+This is equivalent to @code{ctime (time ())}.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/time.cc
+ at anchor{doc-strftime}
+ at deftypefn {Loadable Function} {} strftime (@var{fmt}, @var{tm_struct})
+Format the time structure @var{tm_struct} in a flexible way using the
+format string @var{fmt} that contains @samp{%} substitutions
+similar to those in @code{printf}.  Except where noted, substituted
+fields have a fixed size; numeric fields are padded if necessary.
+Padding is with zeros by default; for fields that display a single
+number, padding can be changed or inhibited by following the @samp{%}
+with one of the modifiers described below.  Unknown field specifiers are
+copied as normal characters.  All other characters are copied to the
+output without change.  For example,
+
+ at example
+ at group
+strftime ("%r (%Z) %A %e %B %Y", localtime (time ()))
+     @result{} "01:15:06 AM (CST) Monday 17 February 1997"
+ at end group
+ at end example
+
+Octave's @code{strftime} function supports a superset of the ANSI C
+field specifiers.
+
+ at noindent
+Literal character fields:
+
+ at table @code
+ at item %
+% character.
+
+ at item n
+Newline character.
+
+ at item t
+Tab character.
+ at end table
+
+ at noindent
+Numeric modifiers (a nonstandard extension):
+
+ at table @code
+ at item - (dash)
+Do not pad the field.
+
+ at item _ (underscore)
+Pad the field with spaces.
+ at end table
+
+ at noindent
+Time fields:
+
+ at table @code
+ at item %H
+Hour (00-23).
+
+ at item %I
+Hour (01-12).
+
+ at item %k
+Hour (0-23).
+
+ at item %l
+Hour (1-12).
+
+ at item %M
+Minute (00-59).
+
+ at item %p
+Locale's AM or PM.
+
+ at item %r
+Time, 12-hour (hh:mm:ss [AP]M).
+
+ at item %R
+Time, 24-hour (hh:mm).
+
+ at item %s
+Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).
+
+ at item %S
+Second (00-61).
+
+ at item %T
+Time, 24-hour (hh:mm:ss).
+
+ at item %X
+Locale's time representation (%H:%M:%S).
+
+ at item %Z
+Time zone (EDT), or nothing if no time zone is determinable.
+ at end table
+
+ at noindent
+Date fields:
+
+ at table @code
+ at item %a
+Locale's abbreviated weekday name (Sun-Sat).
+
+ at item %A
+Locale's full weekday name, variable length (Sunday-Saturday).
+
+ at item %b
+Locale's abbreviated month name (Jan-Dec).
+
+ at item %B
+Locale's full month name, variable length (January-December).
+
+ at item %c
+Locale's date and time (Sat Nov 04 12:02:33 EST 1989).
+
+ at item %C
+Century (00-99).
+
+ at item %d
+Day of month (01-31).
+
+ at item %e
+Day of month ( 1-31).
+
+ at item %D
+Date (mm/dd/yy).
+
+ at item %h
+Same as %b.
+
+ at item %j
+Day of year (001-366).
+
+ at item %m
+Month (01-12).
+
+ at item %U
+Week number of year with Sunday as first day of week (00-53).
+
+ at item %w
+Day of week (0-6).
+
+ at item %W
+Week number of year with Monday as first day of week (00-53).
+
+ at item %x
+Locale's date representation (mm/dd/yy).
+
+ at item %y
+Last two digits of year (00-99).
+
+ at item %Y
+Year (1970-).
+ at end table
+ at seealso{@ref{doc-strptime,,strptime}, @ref{doc-localtime,,localtime}, @ref{doc-gmtime,,gmtime}, @ref{doc-mktime,,mktime}, @ref{doc-time,,time}, @ref{doc-now,,now}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/time.cc
+ at anchor{doc-strptime}
+ at deftypefn {Loadable Function} {[@var{tm_struct}, @var{nchars}] =} strptime (@var{str}, @var{fmt})
+Convert the string @var{str} to the time structure @var{tm_struct} under
+the control of the format string @var{fmt}.
+
+If @var{fmt} fails to match, @var{nchars} is 0; otherwise it is set to the
+position of last matched character plus 1. Always check for this unless
+you're absolutely sure the date string will be parsed correctly.
+ at seealso{@ref{doc-strftime,,strftime}, @ref{doc-localtime,,localtime}, @ref{doc-gmtime,,gmtime}, @ref{doc-mktime,,mktime}, @ref{doc-time,,time}, @ref{doc-now,,now}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+Most of the remaining functions described in this section are not
+patterned after the standard C library.  Some are available for
+compatibility with @sc{matlab} and others are provided because they are
+useful.
+
+ at c ./time/clock.m
+ at anchor{doc-clock}
+ at deftypefn {Function File} {} clock ()
+Return a vector containing the current year, month (1-12), day (1-31),
+hour (0-23), minute (0-59) and second (0-61).  For example,
+
+ at example
+ at group
+clock ()
+     @result{} [ 1993, 8, 20, 4, 56, 1 ]
+ at end group
+ at end example
+
+The function clock is more accurate on systems that have the
+ at code{gettimeofday} function.
+ at end deftypefn
+
+
+ at c ./time/date.m
+ at anchor{doc-date}
+ at deftypefn {Function File} {} date ()
+Return the date as a character string in the form DD-MMM-YY.  For
+example,
+
+ at example
+ at group
+date ()
+     @result{} "20-Aug-93"
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c ./time/etime.m
+ at anchor{doc-etime}
+ at deftypefn {Function File} {} etime (@var{t1}, @var{t2})
+Return the difference (in seconds) between two time values returned from
+ at code{clock}.  For example:
+
+ at example
+ at group
+t0 = clock ();
+ many computations later at dots{}
+elapsed_time = etime (clock (), t0);
+ at end group
+ at end example
+
+ at noindent
+will set the variable @code{elapsed_time} to the number of seconds since
+the variable @code{t0} was set.
+ at seealso{@ref{doc-tic,,tic}, @ref{doc-toc,,toc}, @ref{doc-clock,,clock}, @ref{doc-cputime,,cputime}}
+ at end deftypefn
+
+
+ at c data.cc
+ at anchor{doc-cputime}
+ at deftypefn {Built-in Function} {[@var{total}, @var{user}, @var{system}] =} cputime ();
+Return the CPU time used by your Octave session.  The first output is
+the total time spent executing your process and is equal to the sum of
+second and third outputs, which are the number of CPU seconds spent
+executing in user mode and the number of CPU seconds spent executing in
+system mode, respectively.  If your system does not have a way to report
+CPU time usage, @code{cputime} returns 0 for each of its output values.
+Note that because Octave used some CPU time to start, it is reasonable
+to check to see if @code{cputime} works by checking to see if the total
+CPU time used is nonzero.
+ at end deftypefn
+
+
+ at c ./time/is_leap_year.m
+ at anchor{doc-is_leap_year}
+ at deftypefn {Function File} {} is_leap_year (@var{year})
+Return 1 if the given year is a leap year and 0 otherwise.  If no
+arguments are provided, @code{is_leap_year} will use the current year.
+For example,
+
+ at example
+ at group
+is_leap_year (2000)
+     @result{} 1
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at anchor{doc-toc}
+ at c data.cc
+ at anchor{doc-tic}
+ at deftypefn {Built-in Function} {} tic ()
+ at deftypefnx {Built-in Function} {} toc ()
+Set or check a wall-clock timer.  Calling @code{tic} without an
+output argument sets the timer.  Subsequent calls to @code{toc}
+return the number of seconds since the timer was set.  For example,
+
+ at example
+ at group
+tic ();
+# many computations later at dots{}
+elapsed_time = toc ();
+ at end group
+ at end example
+
+ at noindent
+will set the variable @code{elapsed_time} to the number of seconds since
+the most recent call to the function @code{tic}.
+
+If called with one output argument then this function returns a scalar
+of type @code{uint64} and the wall-clock timer is not started.
+
+ at example
+ at group
+t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6
+     @result{} 5
+ at end group
+ at end example
+
+Nested timing with @code{tic} and @code{toc} is not supported.
+Therefore @code{toc} will always return the elapsed time from the most
+recent call to @code{tic}.
+
+If you are more interested in the CPU time that your process used, you
+should use the @code{cputime} function instead.  The @code{tic} and
+ at code{toc} functions report the actual wall clock time that elapsed
+between the calls.  This may include time spent processing other jobs or
+doing nothing at all.  For example,
+
+ at example
+ at group
+tic (); sleep (5); toc ()
+     @result{} 5
+t = cputime (); sleep (5); cputime () - t
+     @result{} 0
+ at end group
+ at end example
+
+ at noindent
+(This example also illustrates that the CPU timer may have a fairly
+coarse resolution.)
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-pause}
+ at deftypefn {Built-in Function} {} pause (@var{seconds})
+Suspend the execution of the program.  If invoked without any arguments,
+Octave waits until you type a character.  With a numeric argument, it
+pauses for the given number of seconds.  For example, the following
+statement prints a message and then waits 5 seconds before clearing the
+screen.
+
+ at example
+ at group
+fprintf (stderr, "wait please...\n");
+pause (5);
+clc;
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-sleep}
+ at deftypefn {Built-in Function} {} sleep (@var{seconds})
+Suspend the execution of the program for the given number of seconds.
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-usleep}
+ at deftypefn {Built-in Function} {} usleep (@var{microseconds})
+Suspend the execution of the program for the given number of
+microseconds.  On systems where it is not possible to sleep for periods
+of time less than one second, @code{usleep} will pause the execution for
+ at code{round (@var{microseconds} / 1e6)} seconds.
+ at end deftypefn
+
+
+ at c ./time/datenum.m
+ at anchor{doc-datenum}
+ at deftypefn {Function File} {} datenum (@var{year}, @var{month}, @var{day})
+ at deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour})
+ at deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute})
+ at deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}, @var{second})
+ at deftypefnx {Function File} {} datenum (@code{"date"})
+ at deftypefnx {Function File} {} datenum (@code{"date"}, @var{p})
+Returns the specified local time as a day number, with Jan 1, 0000
+being day 1.  By this reckoning, Jan 1, 1970 is day number 719529.  
+The fractional portion, @var{p}, corresponds to the portion of the
+specified day.
+
+Notes:
+
+ at itemize
+ at item
+Years can be negative and/or fractional.
+ at item
+Months below 1 are considered to be January.
+ at item
+Days of the month start at 1.
+ at item
+Days beyond the end of the month go into subsequent months.
+ at item
+Days before the beginning of the month go to the previous month.
+ at item
+Days can be fractional.
+ at end itemize
+
+ at strong{Warning:} this function does not attempt to handle Julian
+calendars so dates before Octave 15, 1582 are wrong by as much
+as eleven days.  Also be aware that only Roman Catholic countries
+adopted the calendar in 1582.  It took until 1924 for it to be 
+adopted everywhere.  See the Wikipedia entry on the Gregorian 
+calendar for more details.
+
+ at strong{Warning:} leap seconds are ignored.  A table of leap seconds
+is available on the Wikipedia entry for leap seconds.
+ at seealso{@ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-now,,now}, @ref{doc-datestr,,datestr}, @ref{doc-datevec,,datevec}, @ref{doc-calendar,,calendar}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./time/datestr.m
+ at anchor{doc-datestr}
+ at deftypefn {Function File} {@var{str} =} datestr (@var{date}, [@var{f}, [@var{p}]])
+Format the given date/time according to the format @code{f} and return
+the result in @var{str}.  @var{date} is a serial date number (see
+ at code{datenum}) or a date vector (see @code{datevec}).  The value of
+ at var{date} may also be a string or cell array of strings.
+
+ at var{f} can be an integer which corresponds to one of the codes in
+the table below, or a date format string.
+
+ at var{p} is the year at the start of the century in which two-digit years
+are to be interpreted in.  If not specified, it defaults to the current
+year minus 50.
+
+For example, the date 730736.65149 (2000-09-07 15:38:09.0934) would be
+formatted as follows:
+
+ at multitable @columnfractions 0.1 0.45 0.35
+ at headitem Code @tab Format @tab Example
+ at item  0 @tab dd-mmm-yyyy HH:MM:SS   @tab 07-Sep-2000 15:38:09
+ at item  1 @tab dd-mmm-yyyy            @tab 07-Sep-2000
+ at item  2 @tab mm/dd/yy               @tab 09/07/00
+ at item  3 @tab mmm                    @tab Sep
+ at item  4 @tab m                      @tab S
+ at item  5 @tab mm                     @tab 09
+ at item  6 @tab mm/dd                  @tab 09/07
+ at item  7 @tab dd                     @tab 07
+ at item  8 @tab ddd                    @tab Thu
+ at item  9 @tab d                      @tab T
+ at item 10 @tab yyyy                   @tab 2000
+ at item 11 @tab yy                     @tab 00
+ at item 12 @tab mmmyy                  @tab Sep00
+ at item 13 @tab HH:MM:SS               @tab 15:38:09
+ at item 14 @tab HH:MM:SS PM            @tab 03:38:09 PM
+ at item 15 @tab HH:MM                  @tab 15:38
+ at item 16 @tab HH:MM PM               @tab 03:38 PM
+ at item 17 @tab QQ-YY                  @tab Q3-00
+ at item 18 @tab QQ                     @tab Q3
+ at item 19 @tab dd/mm                  @tab 13/03
+ at item 20 @tab dd/mm/yy               @tab 13/03/95
+ at item 21 @tab mmm.dd.yyyy HH:MM:SS   @tab Mar.03.1962 13:53:06
+ at item 22 @tab mmm.dd.yyyy            @tab Mar.03.1962
+ at item 23 @tab mm/dd/yyyy             @tab 03/13/1962
+ at item 24 @tab dd/mm/yyyy             @tab 12/03/1962
+ at item 25 @tab yy/mm/dd               @tab 95/03/13
+ at item 26 @tab yyyy/mm/dd             @tab 1995/03/13
+ at item 27 @tab QQ-YYYY                @tab Q4-2132
+ at item 28 @tab mmmyyyy                @tab Mar2047
+ at item 29 @tab yyyymmdd               @tab 20470313
+ at item 30 @tab yyyymmddTHHMMSS        @tab 20470313T132603
+ at item 31 @tab yyyy-mm-dd HH:MM:SS    @tab 1047-03-13 13:26:03
+ at end multitable
+
+If @var{f} is a format string, the following symbols are recognized:
+
+ at multitable @columnfractions 0.1 0.7 0.2
+ at headitem Symbol @tab Meaning @tab Example
+ at item yyyy @tab Full year                                    @tab 2005
+ at item yy   @tab Two-digit year                               @tab 2005
+ at item mmmm @tab Full month name                              @tab December
+ at item mmm  @tab Abbreviated month name                       @tab Dec
+ at item mm   @tab Numeric month number (padded with zeros)     @tab 01, 08, 12
+ at item m    @tab First letter of month name (capitalized)     @tab D
+ at item dddd @tab Full weekday name                            @tab Sunday
+ at item ddd  @tab Abbreviated weekday name                     @tab Sun
+ at item dd   @tab Numeric day of month (padded with zeros)     @tab 11
+ at item d    @tab First letter of weekday name (capitalized)   @tab S
+ at item HH   @tab Hour of day, padded with zeros if PM is set  @tab 09:00
+ at item      @tab and not padded with zeros otherwise          @tab 9:00 AM
+ at item MM   @tab Minute of hour (padded with zeros)           @tab 10:05
+ at item SS   @tab Second of minute (padded with zeros)         @tab 10:05:03
+ at item PM   @tab Use 12-hour time format                      @tab 11:30 PM
+ at end multitable
+
+If @var{f} is not specified or is @code{-1}, then use 0, 1 or 16,
+depending on whether the date portion or the time portion of
+ at var{date} is empty.
+
+If @var{p} is nor specified, it defaults to the current year minus 50.
+
+If a matrix or cell array of dates is given, a vector of date strings is
+returned.
+
+ at seealso{@ref{doc-datenum,,datenum}, @ref{doc-datevec,,datevec}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-now,,now}, @ref{doc-datetick,,datetick}}
+ at end deftypefn
+
+
+ at c ./time/datevec.m
+ at anchor{doc-datevec}
+ at deftypefn {Function File} {@var{v} =} datevec (@var{date})
+ at deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{f})
+ at deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{p})
+ at deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{f}, @var{p})
+ at deftypefnx {Function File} {[@var{y}, @var{m}, @var{d}, @var{h}, @var{mi}, @var{s}] =} datevec (@dots{})
+Convert a serial date number (see @code{datenum}) or date string (see
+ at code{datestr}) into a date vector.
+
+A date vector is a row vector with six members, representing the year,
+month, day, hour, minute, and seconds respectively.
+
+ at var{f} is the format string used to interpret date strings
+(see @code{datestr}).
+
+ at var{p} is the year at the start of the century in which two-digit years
+are to be interpreted in.  If not specified, it defaults to the current
+year minus 50.
+ at seealso{@ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}, @ref{doc-date,,date}, @ref{doc-clock,,clock}, @ref{doc-now,,now}}
+ at end deftypefn
+
+
+ at c ./time/addtodate.m
+ at anchor{doc-addtodate}
+ at deftypefn {Function File} {@var{d} =} addtodate (@var{d}, @var{q}, @var{f})
+Add @var{q} amount of time (with units @var{f}) to the datenum, @var{d}.
+
+ at var{f} must be one of "year", "month", "day", "hour", "minute", or
+"second".
+ at seealso{@ref{doc-datenum,,datenum}, @ref{doc-datevec,,datevec}}
+ at end deftypefn
+
+
+ at c ./time/calendar.m
+ at anchor{doc-calendar}
+ at deftypefn {Function File} {} calendar (@dots{})
+ at deftypefnx {Function File} {@var{c} =} calendar ()
+ at deftypefnx {Function File} {@var{c} =} calendar (@var{d})
+ at deftypefnx {Function File} {@var{c} =} calendar (@var{y}, @var{m})
+If called with no arguments, return the current monthly calendar in
+a 6x7 matrix.
+
+If @var{d} is specified, return the calendar for the month containing
+the day @var{d}, which must be a serial date number or a date string.
+
+If @var{y} and @var{m} are specified, return the calendar for year @var{y}
+and month @var{m}.
+
+If no output arguments are specified, print the calendar on the screen
+instead of returning a matrix.
+ at seealso{@ref{doc-datenum,,datenum}}
+ at end deftypefn
+
+
+ at c ./time/weekday.m
+ at anchor{doc-weekday}
+ at deftypefn {Function File} {[@var{n}, @var{s}] =} weekday (@var{d}, [@var{form}])
+Return the day of week as a number in @var{n} and a string in @var{s},
+for example @code{[1, "Sun"]}, @code{[2, "Mon"]}, @dots{}, or
+ at code{[7, "Sat"]}.
+
+ at var{d} is a serial date number or a date string.
+
+If the string @var{form} is given and is @code{"long"}, @var{s} will
+contain the full name of the weekday; otherwise (or if @var{form} is
+ at code{"short"}), @var{s} will contain the abbreviated name of the weekday.
+ at seealso{@ref{doc-datenum,,datenum}, @ref{doc-datevec,,datevec}, @ref{doc-eomday,,eomday}}
+ at end deftypefn
+
+
+ at c ./time/eomday.m
+ at anchor{doc-eomday}
+ at deftypefn {Function File} {@var{e} =} eomday (@var{y}, @var{m})
+Return the last day of the month @var{m} for the year @var{y}.
+ at seealso{@ref{doc-datenum,,datenum}, @ref{doc-datevec,,datevec}, @ref{doc-weekday,,weekday}}
+ at end deftypefn
+
+
+ at c ./time/datetick.m
+ at anchor{doc-datetick}
+ at deftypefn {Function File} {} datetick (@var{form})
+ at deftypefnx {Function File} {} datetick (@var{axis}, @var{form})
+ at deftypefnx {Function File} {} datetick (@dots{}, "keeplimits")
+ at deftypefnx {Function File} {} datetick (@dots{}, "keepticks")
+ at deftypefnx {Function File} {} datetick (@dots{ax}, @dots{})
+Adds date formatted tick labels to an axis.  The axis the apply the
+ticks to is determined by @var{axis} that can take the values "x",
+"y" or "z".  The default value is "x".  The formatting of the labels is
+determined by the variable @var{form}, that can either be a string in
+the format needed by @code{dateform}, or a positive integer that can
+be accepted by @code{datestr}.
+ at seealso{@ref{doc-datenum,,datenum}, @ref{doc-datestr,,datestr}}
+ at end deftypefn
+
+
+ at node Filesystem Utilities
+ at section Filesystem Utilities
+
+Octave includes the following functions for renaming and deleting files,
+creating, deleting, and reading directories, and for getting information
+about the status of files.
+
+ at c dirfns.cc
+ at anchor{doc-rename}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})
+Change the name of file @var{old} to @var{new}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{@ref{doc-ls,,ls}, @ref{doc-dir,,dir}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-link}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})
+Create a new link (also known as a hard link) to an existing file.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{@ref{doc-symlink,,symlink}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-symlink}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})
+Create a symbolic link @var{new} which contains the string @var{old}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{@ref{doc-link,,link}, @ref{doc-readlink,,readlink}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-readlink}
+ at deftypefn {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})
+Read the value of the symbolic link @var{symlink}.
+
+If successful, @var{result} contains the contents of the symbolic link
+ at var{symlink}, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{@ref{doc-link,,link}, @ref{doc-symlink,,symlink}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-unlink}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} unlink (@var{file})
+Delete the file named @var{file}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-readdir}
+ at deftypefn {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})
+Return names of the files in the directory @var{dir} as a cell array of
+strings.  If an error occurs, return an empty cell array in @var{files}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{@ref{doc-dir,,dir}, @ref{doc-glob,,glob}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-mkdir}
+ at deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{dir})
+ at deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{parent}, @var{dir})
+Create a directory named @var{dir} in the directory @var{parent}.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a
+system-dependent error message, and @var{msgid} contains a unique
+message identifier.
+ at seealso{@ref{doc-rmdir,,rmdir}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-rmdir}
+ at deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir})
+ at deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir}, @code{"s"})
+Remove the directory named @var{dir}.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a
+system-dependent error message, and @var{msgid} contains a unique
+message identifier.
+
+If the optional second parameter is supplied with value @code{"s"},
+recursively remove all subdirectories as well.
+ at seealso{@ref{doc-mkdir,,mkdir}, @ref{doc-confirm_recursive_rmdir,,confirm_recursive_rmdir}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-confirm_recursive_rmdir}
+ at deftypefn {Built-in Function} {@var{val} =} confirm_recursive_rmdir ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} confirm_recursive_rmdir (@var{new_val})
+Query or set the internal variable that controls whether Octave
+will ask for confirmation before recursively removing a directory tree.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-mkfifo}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})
+Create a @var{fifo} special file named @var{name} with file mode @var{mode}
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-umask}
+ at deftypefn {Built-in Function} {} umask (@var{mask})
+Set the permission mask for file creation.  The parameter @var{mask}
+is an integer, interpreted as an octal number.  If successful,
+returns the previous value of the mask (as an integer to be
+interpreted as an octal number); otherwise an error message is printed.
+ at end deftypefn
+
+
+ at anchor{doc-lstat}
+ at c syscalls.cc
+ at anchor{doc-stat}
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{file})
+ at deftypefnx {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})
+Return a structure @var{s} containing the following information about
+ at var{file}.
+
+ at table @code
+ at item dev
+ID of device containing a directory entry for this file.
+
+ at item ino
+File number of the file.
+
+ at item mode
+File mode, as an integer.  Use the functions @w{@code{S_ISREG}},
+ at w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}}, @w{@code{S_ISFIFO}},
+ at w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract information from this
+value.
+
+ at item modestr
+File mode, as a string of ten letters or dashes as would be returned by
+ at kbd{ls -l}.
+
+ at item nlink
+Number of links.
+
+ at item uid
+User ID of file's owner.
+
+ at item gid
+Group ID of file's group.
+
+ at item rdev
+ID of device for block or character special files.
+
+ at item size
+Size in bytes.
+
+ at item atime
+Time of last access in the same form as time values returned from
+ at code{time}.  @xref{Timing Utilities}.
+
+ at item mtime
+Time of last modification in the same form as time values returned from
+ at code{time}.  @xref{Timing Utilities}.
+
+ at item ctime
+Time of last file status change in the same form as time values
+returned from @code{time}.  @xref{Timing Utilities}.
+
+ at item blksize
+Size of blocks in the file.
+
+ at item blocks
+Number of blocks allocated for file.
+ at end table
+
+If the call is successful @var{err} is 0 and @var{msg} is an empty
+string.  If the file does not exist, or some other error occurs, @var{s}
+is an empty matrix, @var{err} is @minus{}1, and @var{msg} contains the
+corresponding system error message.
+
+If @var{file} is a symbolic link, @code{stat} will return information
+about the actual file that is referenced by the link.  Use @code{lstat}
+if you want information about the symbolic link itself.
+
+For example,
+
+ at example
+[s, err, msg] = stat ("/vmlinuz")
+      @result{} s =
+        @{
+          atime = 855399756
+          rdev = 0
+          ctime = 847219094
+          uid = 0
+          size = 389218
+          blksize = 4096
+          mtime = 847219094
+          gid = 6
+          nlink = 1
+          blocks = 768
+          mode = -rw-r--r--
+          modestr = -rw-r--r--
+          ino = 9316
+          dev = 2049
+        @}
+     @result{} err = 0
+     @result{} msg = 
+ at end example
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-fstat}
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} fstat (@var{fid})
+Return information about the open file @var{fid}.  See @code{stat}
+for a description of the contents of @var{info}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/fileattrib.m
+ at anchor{doc-fileattrib}
+ at deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} fileattrib (@var{file})
+Return information about @var{file}.
+
+If successful, @var{status} is 1, with @var{result} containing a
+structure with the following fields:
+
+ at table @code
+ at item Name
+Full name of @var{file}.
+ at item archive
+True if @var{file} is an archive (Windows).
+ at item system
+True if @var{file} is a system file (Windows).
+ at item hidden
+True if @var{file} is a hidden file (Windows).
+ at item directory
+True if @var{file} is a directory.
+ at item UserRead
+ at itemx GroupRead
+ at itemx OtherRead
+True if the user (group; other users) has read permission for
+ at var{file}.
+ at item UserWrite
+ at itemx GroupWrite
+ at itemx OtherWrite
+True if the user (group; other users) has write permission for
+ at var{file}.
+ at item UserExecute
+ at itemx GroupExecute
+ at itemx OtherExecute
+True if the user (group; other users) has execute permission for
+ at var{file}.
+ at end table
+If an attribute does not apply (i.e., archive on a Unix system) then
+the field is set to NaN.
+
+With no input arguments, return information about the current
+directory.
+
+If @var{file} contains globbing characters, return information about
+all the matching files.
+ at seealso{@ref{doc-glob,,glob}}
+ at end deftypefn
+
+
+ at c ./general/isdir.m
+ at anchor{doc-isdir}
+ at deftypefn {Function File} {} isdir (@var{f})
+Return true if @var{f} is a directory.
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-glob}
+ at deftypefn {Built-in Function} {} glob (@var{pattern})
+Given an array of strings (as a char array or a cell array) in
+ at var{pattern}, return a cell array of file names that match any of
+them, or an empty cell array if no patterns match.  Tilde expansion
+is performed on each of the patterns before looking for matching file
+names.  For example,
+
+ at example
+ at group
+glob ("/vm*")
+     @result{} "/vmlinuz"
+ at end group
+ at end example
+ at seealso{@ref{doc-dir,,dir}, @ref{doc-ls,,ls}, @ref{doc-stat,,stat}, @ref{doc-readdir,,readdir}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-fnmatch}
+ at deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})
+Return 1 or zero for each element of @var{string} that matches any of
+the elements of the string array @var{pattern}, using the rules of
+filename pattern matching.  For example,
+
+ at example
+ at group
+fnmatch ("a*b", @{"ab"; "axyzb"; "xyzab"@})
+     @result{} [ 1; 1; 0 ]
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-file_in_path}
+ at deftypefn {Built-in Function} {} file_in_path (@var{path}, @var{file})
+ at deftypefnx {Built-in Function} {} file_in_path (@var{path}, @var{file}, "all")
+Return the absolute name of @var{file} if it can be found in
+ at var{path}.  The value of @var{path} should be a colon-separated list of
+directories in the format described for @code{path}.  If no file
+is found, return an empty matrix.  For example,
+
+ at example
+ at group
+file_in_path (EXEC_PATH, "sh")
+     @result{} "/bin/sh"
+ at end group
+ at end example
+
+If the second argument is a cell array of strings, search each
+directory of the path for element of the cell array and return
+the first that matches.
+
+If the third optional argument @code{"all"} is supplied, return
+a cell array containing the list of all files that have the same
+name in the path.  If no files are found, return an empty cell array.
+ at seealso{@ref{doc-file_in_loadpath,,file_in_loadpath}}
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-tilde_expand}
+ at deftypefn {Built-in Function} {} tilde_expand (@var{string})
+Performs tilde expansion on @var{string}.  If @var{string} begins with a
+tilde character, (@samp{~}), all of the characters preceding the first
+slash (or all characters, if there is no slash) are treated as a
+possible user name, and the tilde and the following characters up to the
+slash are replaced by the home directory of the named user.  If the
+tilde is followed immediately by a slash, the tilde is replaced by the
+home directory of the user running Octave.  For example,
+
+ at example
+ at group
+tilde_expand ("~joeuser/bin")
+     @result{} "/home/joeuser/bin"
+tilde_expand ("~/bin")
+     @result{} "/home/jwe/bin"
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-canonicalize_file_name}
+ at deftypefn {Built-in Function} {[@var{cname}, @var{status}, @var{msg}]} canonicalize_file_name (@var{name})
+Return the canonical name of file @var{name}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/movefile.m
+ at anchor{doc-movefile}
+ at deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@var{f1}, @var{f2})
+Move the file @var{f1} to the new name @var{f2}.  The name @var{f1}
+may contain globbing patterns.  If @var{f1} expands to multiple file
+names, @var{f2} must be a directory.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique\n\
+message identifier.\n\
+ at seealso{@ref{doc-glob,,glob}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/copyfile.m
+ at anchor{doc-copyfile}
+ at deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2}, @var{force})
+Copy the file @var{f1} to the new name @var{f2}.  The name @var{f1}
+may contain globbing patterns.  If @var{f1} expands to multiple file
+names, @var{f2} must be a directory.  If @var{force} is given and equals
+the string "f" the copy operation will be forced.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique\n\
+message identifier.\n\
+ at seealso{@ref{doc-glob,,glob}, @ref{doc-movefile,,movefile}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/fileparts.m
+ at anchor{doc-fileparts}
+ at deftypefn {Function File} {[@var{dir}, @var{name}, @var{ext}, @var{ver}] =} fileparts (@var{filename})
+Return the directory, name, extension, and version components of
+ at var{filename}.
+ at seealso{@ref{doc-fullfile,,fullfile}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-filesep}
+ at deftypefn {Built-in Function} {} filesep ()
+ at deftypefnx {Built-in Function} {} filesep ('all')
+Return the system-dependent character used to separate directory names.
+
+If 'all' is given, the function return all valid file separators in
+the form of a string.  The list of file separators is system-dependent.
+It is / (forward slash) under UNIX or Mac OS X, / and \ (forward and
+backward slashes) under Windows.
+ at seealso{@ref{doc-pathsep,,pathsep}, @ref{doc-dir,,dir}, @ref{doc-ls,,ls}}
+ at end deftypefn
+
+
+ at c input.cc
+ at anchor{doc-filemarker}
+ at deftypefn {Built-in Function} {} filemarker ()
+Returns or sets the character used to separate filename from the
+the subfunction names contained within the file.  This can be used in
+a generic manner to interact with subfunctions.  For example
+
+ at example
+help (["myfunc", filemarker, "mysubfunc"])
+ at end example
+
+ at noindent
+returns the help string associated with the sub-function @code{mysubfunc}
+of the function @code{myfunc}.  Another use of @code{filemarker} is when
+debugging it allows easier placement of breakpoints within sub-functions.
+For example
+
+ at example
+dbstop (["myfunc", filemarker, "mysubfunc"])
+ at end example
+
+ at noindent
+will set a breakpoint at the first line of the subfunction @code{mysubfunc}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/fullfile.m
+ at anchor{doc-fullfile}
+ at deftypefn {Function File} {@var{filename} =} fullfile (@var{dir1}, @var{dir2}, @dots{}, @var{file})
+Return a complete filename constructed from the given components.
+ at seealso{@ref{doc-fileparts,,fileparts}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/tempdir.m
+ at anchor{doc-tempdir}
+ at deftypefn {Function File} {@var{dir} =} tempdir ()
+Return the name of the system's directory for temporary files.
+ at end deftypefn
+
+
+ at c ./miscellaneous/tempname.m
+ at anchor{doc-tempname}
+ at deftypefn {Function File} {filename =} tempname ()
+This function is an alias for @code{tmpnam}.
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-P_tmpdir}
+ at deftypefn {Built-in Function} {} P_tmpdir ()
+Return the default name of the directory for temporary files on
+this system.  The name of this directory is system dependent.
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-is_absolute_filename}
+ at deftypefn {Built-in Function} {} is_absolute_filename (@var{file})
+Return true if @var{file} is an absolute filename.
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-is_rooted_relative_filename}
+ at deftypefn {Built-in Function} {} is_rooted_relative_filename (@var{file})
+Return true if @var{file} is a rooted-relative filename.
+ at end deftypefn
+
+
+ at c utils.cc
+ at anchor{doc-make_absolute_filename}
+ at deftypefn {Built-in Function} {} make_absolute_filename (@var{file})
+Return the full name of @var{file}, relative to the current directory.
+ at end deftypefn
+
+
+ at node File Archiving Utilities
+ at section File Archiving Utilities
+
+ at c ./miscellaneous/bunzip2.m
+ at anchor{doc-bunzip2}
+ at deftypefn {Function File} {} bunzip2 (@var{bzfile}, @var{dir})
+Unpack the bzip2 archive @var{bzfile} to the directory @var{dir}.  If
+ at var{dir} is not specified, it defaults to the current directory.
+ at seealso{@ref{doc-unpack,,unpack}, @ref{doc-bzip2,,bzip2}, @ref{doc-tar,,tar}, @ref{doc-untar,,untar}, @ref{doc-gzip,,gzip}, @ref{doc-gunzip,,gunzip}, @ref{doc-zip,,zip}, @ref{doc-unzip,,unzip}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/gzip.m
+ at anchor{doc-gzip}
+ at deftypefn {Function File} {@var{entries} =} gzip (@var{files})
+ at deftypefnx {Function File} {@var{entries} =} gzip (@var{files}, @var{outdir})
+Compress the list of files and/or directories specified in @var{files}.
+Each file is compressed separately and a new file with a '.gz' extension
+is created.  The original files are not touched.  Existing compressed
+files are silently overwritten.  If @var{outdir} is defined the compressed 
+versions of the files are placed in this directory.
+ at seealso{@ref{doc-gunzip,,gunzip}, @ref{doc-bzip2,,bzip2}, @ref{doc-zip,,zip}, @ref{doc-tar,,tar}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/gunzip.m
+ at anchor{doc-gunzip}
+ at deftypefn {Function File} {} gunzip (@var{gzfile}, @var{dir})
+Unpack the gzip archive @var{gzfile} to the directory @var{dir}.  If
+ at var{dir} is not specified, it defaults to the current directory.  If
+the @var{gzfile} is a directory, all files in the directory will be
+recursively gunzipped.
+ at seealso{@ref{doc-unpack,,unpack}, @ref{doc-bunzip2,,bunzip2}, @ref{doc-tar,,tar}, @ref{doc-untar,,untar}, @ref{doc-gzip,,gzip}, @ref{doc-gunzip,,gunzip}, @ref{doc-zip,,zip}, @ref{doc-unzip,,unzip}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/tar.m
+ at anchor{doc-tar}
+ at deftypefn {Function File} {@var{entries} =} tar (@var{tarfile}, @var{files}, @var{root})
+Pack @var{files} @var{files} into the TAR archive @var{tarfile}.  The
+list of files must be a string or a cell array of strings.
+
+The optional argument @var{root} changes the relative path of @var{files}
+from the current directory.
+
+If an output argument is requested the entries in the archive are
+returned in a cell array.
+ at seealso{@ref{doc-untar,,untar}, @ref{doc-gzip,,gzip}, @ref{doc-gunzip,,gunzip}, @ref{doc-zip,,zip}, @ref{doc-unzip,,unzip}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/untar.m
+ at anchor{doc-untar}
+ at deftypefn {Function File} {} untar (@var{tarfile}, @var{dir})
+Unpack the TAR archive @var{tarfile} to the directory @var{dir}.
+If @var{dir} is not specified, it defaults to the current directory.
+ at seealso{@ref{doc-unpack,,unpack}, @ref{doc-bunzip2,,bunzip2}, @ref{doc-tar,,tar}, @ref{doc-gzip,,gzip}, @ref{doc-gunzip,,gunzip}, @ref{doc-zip,,zip}, @ref{doc-unzip,,unzip}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/zip.m
+ at anchor{doc-zip}
+ at deftypefn {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files})
+ at deftypefnx {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files}, @var{rootdir})
+Compress the list of files and/or directories specified in @var{files} 
+into the archive @var{zipfiles} in the same directory.  If @var{rootdir} 
+is defined the @var{files} is located relative to @var{rootdir} rather 
+than the current directory
+ at seealso{@ref{doc-unzip,,unzip}, @ref{doc-tar,,tar}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/unzip.m
+ at anchor{doc-unzip}
+ at deftypefn {Function File} {} unzip (@var{zipfile}, @var{dir})
+Unpack the ZIP archive @var{zipfile} to the directory @var{dir}.
+If @var{dir} is not specified, it defaults to the current directory.
+ at seealso{@ref{doc-unpack,,unpack}, @ref{doc-bunzip2,,bunzip2}, @ref{doc-tar,,tar}, @ref{doc-untar,,untar}, @ref{doc-gzip,,gzip}, @ref{doc-gunzip,,gunzip}, @ref{doc-zip,,zip}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/pack.m
+ at anchor{doc-pack}
+ at deftypefn {Function File} {} pack ()
+This function is provided for compatibility with @sc{matlab}, but it
+doesn't actually do anything.
+ at end deftypefn
+
+
+ at c ./miscellaneous/unpack.m
+ at anchor{doc-unpack}
+ at deftypefn {Function File} {@var{files} =} unpack (@var{file}, @var{dir})
+ at deftypefnx {Function File} {@var{files} =} unpack (@var{file}, @var{dir}, @var{filetype})
+Unpack the archive @var{file} based on its extension to the directory
+ at var{dir}.  If @var{file} is a cellstr, then all files will be
+handled individually.  If @var{dir} is not specified, it defaults to
+the current directory.  It returns a list of @var{files}
+unpacked.  If a directory is in the file list, then the
+ at var{filetype} to unpack must also be specified.
+
+The @var{files} includes the entire path to the output files.
+ at seealso{@ref{doc-bunzip2,,bunzip2}, @ref{doc-tar,,tar}, @ref{doc-untar,,untar}, @ref{doc-gzip,,gzip}, @ref{doc-gunzip,,gunzip}, @ref{doc-zip,,zip}, @ref{doc-unzip,,unzip}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/bzip2.m
+ at anchor{doc-bzip2}
+ at deftypefn {Function File} {@var{entries} =} bzip2 (@var{files})
+ at deftypefnx {Function File} {@var{entries} =} bzip2 (@var{files}, @var{outdir})
+Compress the list of files specified in @var{files}.
+Each file is compressed separately and a new file with a '.bz2' extension
+is created.  The original files are not touched.  Existing compressed files 
+are silently overwritten.If @var{outdir} is defined the compressed versions 
+of the files are placed in this directory.
+ at seealso{@ref{doc-bunzip2,,bunzip2}, @ref{doc-gzip,,gzip}, @ref{doc-zip,,zip}, @ref{doc-tar,,tar}}
+ at end deftypefn
+
+
+ at node Networking Utilities
+ at section Networking Utilities
+
+ at c ./DLD-FUNCTIONS/urlwrite.cc
+ at anchor{doc-urlread}
+ at deftypefn {Loadable Function} {@var{s} =} urlread (@var{url})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})
+ at deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})
+Download a remote file specified by its @var{URL} and return its content
+in string @var{s}.  For example,
+
+ at example
+s = urlread ("ftp://ftp.octave.org/pub/octave/README");
+ at end example
+
+The variable @var{success} is 1 if the download was successful,
+otherwise it is 0 in which case @var{message} contains an error
+message.  If no output argument is specified and if an error occurs,
+then the error is signaled through Octave's error handling mechanism.
+
+This function uses libcurl.  Curl supports, among others, the HTTP,
+FTP and FILE protocols.  Username and password may be specified in the
+URL.  For example,
+
+ at example
+s = urlread ("http://user:password@@example.com/file.txt");
+ at end example
+
+GET and POST requests can be specified by @var{method} and @var{param}.
+The parameter @var{method} is either @samp{get} or @samp{post}
+and @var{param} is a cell array of parameter and value pairs.
+For example,
+
+ at example
+ at group
+s = urlread ("http://www.google.com/search", "get",
+             @{"query", "octave"@});
+ at end group
+ at end example
+ at seealso{@ref{doc-urlwrite,,urlwrite}}
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/urlwrite.cc
+ at anchor{doc-urlwrite}
+ at deftypefn {Loadable Function} {} urlwrite (@var{URL}, @var{localfile})
+ at deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})
+ at deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})
+ at deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})
+Download a remote file specified by its @var{URL} and save it as
+ at var{localfile}.  For example,
+
+ at example
+ at group
+urlwrite ("ftp://ftp.octave.org/pub/octave/README", 
+          "README.txt");
+ at end group
+ at end example
+
+The full path of the downloaded file is returned in @var{f}.  The
+variable @var{success} is 1 if the download was successful,
+otherwise it is 0 in which case @var{message} contains an error
+message.  If no output argument is specified and if an error occurs,
+then the error is signaled through Octave's error handling mechanism.
+
+This function uses libcurl.  Curl supports, among others, the HTTP,
+FTP and FILE protocols.  Username and password may be specified in
+the URL, for example:
+
+ at example
+ at group
+urlwrite ("http://username:password@@example.com/file.txt",
+          "file.txt");
+ at end group
+ at end example
+
+GET and POST requests can be specified by @var{method} and @var{param}.
+The parameter @var{method} is either @samp{get} or @samp{post}
+and @var{param} is a cell array of parameter and value pairs.
+For example:
+
+ at example
+ at group
+urlwrite ("http://www.google.com/search", "search.html",
+          "get", @{"query", "octave"@});
+ at end group
+ at end example
+ at seealso{@ref{doc-urlread,,urlread}}
+ at end deftypefn
+
+
+ at node Controlling Subprocesses
+ at section Controlling Subprocesses
+
+Octave includes some high-level commands like @code{system} and
+ at code{popen} for starting subprocesses.  If you want to run another
+program to perform some task and then look at its output, you will
+probably want to use these functions.
+
+Octave also provides several very low-level Unix-like functions which
+can also be used for starting subprocesses, but you should probably only
+use them if you can't find any way to do what you need with the
+higher-level functions.
+
+ at c toplev.cc
+ at anchor{doc-system}
+ at deftypefn {Built-in Function} {} system (@var{string}, @var{return_output}, @var{type})
+Execute a shell command specified by @var{string}.  The second
+argument is optional.  If @var{type} is @code{"async"}, the process
+is started in the background and the process id of the child process
+is returned immediately.  Otherwise, the process is started, and
+Octave waits until it exits.  If the @var{type} argument is omitted, a
+value of @code{"sync"} is assumed.
+
+If two input arguments are given (the actual value of
+ at var{return_output} is irrelevant) and the subprocess is started
+synchronously, or if @var{system} is called with one input argument and
+one or more output arguments, the output from the command is returned.
+Otherwise, if the subprocess is executed synchronously, its output is
+sent to the standard output.  To send the output of a command executed
+with @var{system} through the pager, use a command like
+
+ at example
+disp (system (cmd, 1));
+ at end example
+
+ at noindent
+or
+
+ at example
+printf ("%s\n", system (cmd, 1));
+ at end example
+
+The @code{system} function can return two values.  The first is the
+exit status of the command and the second is any output from the
+command that was written to the standard output stream.  For example,
+
+ at example
+[status, output] = system ("echo foo; exit 2");
+ at end example
+
+ at noindent
+will set the variable @code{output} to the string @samp{foo}, and the
+variable @code{status} to the integer @samp{2}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/unix.m
+ at anchor{doc-unix}
+ at deftypefn {Function File} {[@var{status}, @var{text}]} unix (@var{command})
+ at deftypefnx {Function File} {[@var{status}, @var{text}]} unix (@var{command}, "-echo")
+Execute a system command if running under a Unix-like operating
+system, otherwise do nothing.  Return the exit status of the program
+in @var{status} and any output sent to the standard output in
+ at var{text}.  If the optional second argument @code{"-echo"} is given,
+then also send the output from the command to the standard output.
+ at seealso{@ref{doc-isunix,,isunix}, @ref{doc-ispc,,ispc}, @ref{doc-system,,system}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/dos.m
+ at anchor{doc-dos}
+ at deftypefn {Function File} {[@var{status}, @var{text}] =} dos (@var{command})
+ at deftypefnx {Function File} {[@var{status}, @var{text}] =} dos (@var{command}, "-echo")
+Execute a system command if running under a Windows-like operating
+system, otherwise do nothing.  Return the exit status of the program
+in @var{status} and any output sent to the standard output in
+ at var{text}.  If the optional second argument @code{"-echo"} is given,
+then also send the output from the command to the standard output.
+ at seealso{@ref{doc-unix,,unix}, @ref{doc-isunix,,isunix}, @ref{doc-ispc,,ispc}, @ref{doc-system,,system}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/perl.m
+ at anchor{doc-perl}
+ at deftypefn {Function File} {[@var{output}, @var{status}] =} perl (@var{scriptfile})
+ at deftypefnx {Function File} {[@var{output}, @var{status}] =} perl (@var{scriptfile}, @var{argument1}, @var{argument2}, @dots{})
+Invoke perl script @var{scriptfile} with possibly a list of
+command line arguments.
+Returns output in @var{output} and status
+in @var{status}.
+ at seealso{@ref{doc-system,,system}}
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-popen}
+ at deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})
+Start a process and create a pipe.  The name of the command to run is
+given by @var{command}.  The file identifier corresponding to the input
+or output stream of the process is returned in @var{fid}.  The argument
+ at var{mode} may be
+
+ at table @code
+ at item "r"
+The pipe will be connected to the standard output of the process, and
+open for reading.
+
+ at item "w"
+The pipe will be connected to the standard input of the process, and
+open for writing.
+ at end table
+
+For example,
+
+ at example
+ at group
+fid = popen ("ls -ltr / | tail -3", "r");
+while (ischar (s = fgets (fid)))
+  fputs (stdout, s);
+endwhile
+     @print{} drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc
+     @print{} drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib
+     @print{} drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at c file-io.cc
+ at anchor{doc-pclose}
+ at deftypefn {Built-in Function} {} pclose (@var{fid})
+Close a file identifier that was opened by @code{popen}.  You may also
+use @code{fclose} for the same purpose.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-popen2}
+ at deftypefn {Built-in Function} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args})
+Start a subprocess with two-way communication.  The name of the process
+is given by @var{command}, and @var{args} is an array of strings
+containing options for the command.  The file identifiers for the input
+and output streams of the subprocess are returned in @var{in} and
+ at var{out}.  If execution of the command is successful, @var{pid}
+contains the process ID of the subprocess.  Otherwise, @var{pid} is
+ at minus{}1.
+
+For example,
+
+ at example
+[in, out, pid] = popen2 ("sort", "-r");
+fputs (in, "these\nare\nsome\nstrings\n");
+fclose (in);
+EAGAIN = errno ("EAGAIN");
+done = false;
+do
+  s = fgets (out);
+  if (ischar (s))
+    fputs (stdout, s);
+  elseif (errno () == EAGAIN)
+    sleep (0.1);
+    fclear (out);
+  else
+    done = true;
+  endif
+until (done)
+fclose (out);
+waitpid (pid);
+     @print{} these
+     @print{} strings
+     @print{} some
+     @print{} are
+ at end example
+
+Note that @code{popen2}, unlike @code{popen}, will not "reap" the
+child process.  If you don't use @code{waitpid} to check the child's
+exit status, it will linger until Octave exits.
+ at end deftypefn
+
+
+ at c defaults.cc
+ at anchor{doc-EXEC_PATH}
+ at deftypefn {Built-in Function} {@var{val} =} EXEC_PATH ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} EXEC_PATH (@var{new_val})
+Query or set the internal variable that specifies a colon separated
+list of directories to search when executing external programs.
+Its initial value is taken from the environment variable
+ at w{@code{OCTAVE_EXEC_PATH}} (if it exists) or @code{PATH}, but that
+value can be overridden by the command line argument
+ at code{--exec-path PATH}.  At startup, an additional set of
+directories (including the shell PATH) is appended to the path
+specified in the environment or on the command line.  If you use
+the @w{@code{EXEC_PATH}} function to modify the path, you should take
+care to preserve these additional directories.
+ at end deftypefn
+
+
+In most cases, the following functions simply decode their arguments and
+make the corresponding Unix system calls.  For a complete example of how
+they can be used, look at the definition of the function @code{popen2}.
+
+ at c syscalls.cc
+ at anchor{doc-fork}
+ at deftypefn {Built-in Function} {[@var{pid}, @var{msg}] =} fork ()
+Create a copy of the current process.
+
+Fork can return one of the following values:
+
+ at table @asis
+ at item > 0
+You are in the parent process.  The value returned from @code{fork} is
+the process id of the child process.  You should probably arrange to
+wait for any child processes to exit.
+
+ at item 0
+You are in the child process.  You can call @code{exec} to start another
+process.  If that fails, you should probably call @code{exit}.
+
+ at item < 0
+The call to @code{fork} failed for some reason.  You must take evasive
+action.  A system dependent error message will be waiting in @var{msg}.
+ at end table
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-exec}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} exec (@var{file}, @var{args})
+Replace current process with a new process.  Calling @code{exec} without
+first calling @code{fork} will terminate your current Octave process and
+replace it with the program named by @var{file}.  For example,
+
+ at example
+exec ("ls" "-l")
+ at end example
+
+ at noindent
+will run @code{ls} and return you to your shell prompt.
+
+If successful, @code{exec} does not return.  If @code{exec} does return,
+ at var{err} will be nonzero, and @var{msg} will contain a system-dependent
+error message.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-pipe}
+ at deftypefn {Built-in Function} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe ()
+Create a pipe and return the reading and writing ends of the pipe
+into @var{read_fd} and @var{write_fd} respectively.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-dup2}
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} dup2 (@var{old}, @var{new})
+Duplicate a file descriptor.
+
+If successful, @var{fid} is greater than zero and contains the new file
+ID.  Otherwise, @var{fid} is negative and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-waitpid}
+ at deftypefn {Built-in Function} {[@var{pid}, @var{status}, @var{msg}] =} waitpid (@var{pid}, @var{options})
+Wait for process @var{pid} to terminate.  The @var{pid} argument can be:
+
+ at table @asis
+ at item @minus{}1
+Wait for any child process.
+
+ at item 0
+Wait for any child process whose process group ID is equal to that of
+the Octave interpreter process.
+
+ at item > 0
+Wait for termination of the child process with ID @var{pid}.
+ at end table
+
+The @var{options} argument can be a bitwise OR of zero or more of
+the following constants:
+
+ at table @code
+ at item 0
+Wait until signal is received or a child process exits (this is the
+default if the @var{options} argument is missing).
+
+ at item WNOHANG
+Do not hang if status is not immediately available.
+
+ at item WUNTRACED
+Report the status of any child processes that are stopped, and whose
+status has not yet been reported since they stopped.
+
+ at item WCONTINUE
+Return if a stopped child has been resumed by delivery of @code{SIGCONT}.
+This value may not be meaningful on all systems.
+ at end table
+
+If the returned value of @var{pid} is greater than 0, it is the process
+ID of the child process that exited.  If an error occurs, @var{pid} will
+be less than zero and @var{msg} will contain a system-dependent error
+message.  The value of @var{status} contains additional system-dependent
+information about the subprocess that exited.
+ at seealso{@ref{doc-WCONTINUE,,WCONTINUE}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WNOHANG,,WNOHANG}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WUNTRACED,,WUNTRACED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WCONTINUE}
+ at deftypefn {Built-in Function} WCONINTUE ()
+Return the numerical value of the option argument that may be
+passed to @code{waitpid} to indicate that it should also return
+if a stopped child has been resumed by delivery of a @code{SIGCONT}
+signal.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WNOHANG,,WNOHANG}, @ref{doc-WUNTRACED,,WUNTRACED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WCOREDUMP}
+ at deftypefn {Built-in Function} {} WCOREDUMP (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child produced a core dump.  This function should only be employed if
+ at code{WIFSIGNALED} returned true.  The macro used to implement this
+function is not specified in POSIX.1-2001 and is not available on some
+Unix implementations (e.g., AIX, SunOS).
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WEXITSTATUS}
+ at deftypefn {Built-in Function} {} WEXITSTATUS (@var{status})
+Given @var{status} from a call to @code{waitpid}, return the exit
+status of the child.  This function should only be employed if
+ at code{WIFEXITED} returned true.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WIFCONTINUED}
+ at deftypefn {Built-in Function} {} WIFCONTINUED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child process was resumed by delivery of @code{SIGCONT}.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WSTOPSIG,,WSTOPSIG}}
+ at end deftypefn
+
+ 
+ at c syscalls.cc
+ at anchor{doc-WIFSIGNALED}
+ at deftypefn {Built-in Function} {} WIFSIGNALED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child process was terminated by a signal.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WIFSTOPPED}
+ at deftypefn {Built-in Function} {} WIFSTOPPED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child process was stopped by delivery of a signal; this is only
+possible if the call was done using @code{WUNTRACED} or when the child
+is being traced (see ptrace(2)).
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WIFEXITED}
+ at deftypefn {Built-in Function} {} WIFEXITED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child terminated normally.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WNOHANG}
+ at deftypefn {Built-in Function} {} WNOHANG ()
+Return the numerical value of the option argument that may be
+passed to @code{waitpid} to indicate that it should return its
+status immediately instead of waiting for a process to exit.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WUNTRACED,,WUNTRACED}, @ref{doc-WCONTINUE,,WCONTINUE}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WSTOPSIG}
+ at deftypefn {Built-in Function} {} WSTOPSIG (@var{status})
+Given @var{status} from a call to @code{waitpid}, return the number of
+the signal which caused the child to stop.  This function should only
+be employed if @code{WIFSTOPPED} returned true.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WTERMSIG,,WTERMSIG}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+ 
+ at c syscalls.cc
+ at anchor{doc-WTERMSIG}
+ at deftypefn {Built-in Function} {} WTERMSIG (@var{status})
+Given @var{status} from a call to @code{waitpid}, return the number of
+the signal that caused the child process to terminate.  This function
+should only be employed if @code{WIFSIGNALED} returned true.
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WIFEXITED,,WIFEXITED}, @ref{doc-WEXITSTATUS,,WEXITSTATUS}, @ref{doc-WIFSIGNALED,,WIFSIGNALED}, @ref{doc-WCOREDUMP,,WCOREDUMP}, @ref{doc-WIFSTOPPED,,WIFSTOPPED}, @ref{doc-WSTOPSIG,,WSTOPSIG}, @ref{doc-WIFCONTINUED,,WIFCONTINUED}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-WUNTRACED}
+ at deftypefn {Built-in Function} {} WUNTRACED ()
+Return the numerical value of the option argument that may be
+passed to @code{waitpid} to indicate that it should also return
+if the child process has stopped but is not traced via the
+ at code{ptrace} system call
+ at seealso{@ref{doc-waitpid,,waitpid}, @ref{doc-WNOHANG,,WNOHANG}, @ref{doc-WCONTINUE,,WCONTINUE}}
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-fcntl}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg})
+Change the properties of the open file @var{fid}.  The following values
+may be passed as @var{request}:
+
+ at vtable @code
+ at item F_DUPFD
+Return a duplicate file descriptor.
+
+ at item F_GETFD
+Return the file descriptor flags for @var{fid}.
+
+ at item F_SETFD
+Set the file descriptor flags for @var{fid}.
+
+ at item F_GETFL
+Return the file status flags for @var{fid}.  The following codes may be
+returned (some of the flags may be undefined on some systems).
+
+ at vtable @code
+ at item O_RDONLY
+Open for reading only.
+
+ at item O_WRONLY
+Open for writing only.
+
+ at item O_RDWR
+Open for reading and writing.
+
+ at item O_APPEND
+Append on each write.
+
+ at item O_CREAT
+Create the file if it does not exist.
+
+ at item O_NONBLOCK
+Nonblocking mode.
+
+ at item O_SYNC
+Wait for writes to complete.
+
+ at item O_ASYNC
+Asynchronous I/O.
+ at end vtable
+
+ at item F_SETFL
+Set the file status flags for @var{fid} to the value specified by
+ at var{arg}.  The only flags that can be changed are @w{@code{O_APPEND}} and
+ at w{@code{O_NONBLOCK}}.
+ at end vtable
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-kill}
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} kill (@var{pid}, @var{sig})
+Send signal @var{sig} to process @var{pid}.
+
+If @var{pid} is positive, then signal @var{sig} is sent to @var{pid}.
+
+If @var{pid} is 0, then signal @var{sig} is sent to every process
+in the process group of the current process.
+
+If @var{pid} is -1, then signal @var{sig} is sent to every process
+except process 1.
+
+If @var{pid} is less than -1, then signal @var{sig} is sent to every
+process in the process group @var{-pid}.
+
+If @var{sig} is 0, then no signal is sent, but error checking is still
+performed.
+
+Return 0 if successful, otherwise return -1.
+ at end deftypefn
+
+
+ at c sighandlers.cc
+ at anchor{doc-SIG}
+ at deftypefn {Built-in Function} {} SIG ()
+Return a structure containing Unix signal names and their defined values.
+ at end deftypefn
+
+
+ at node Process ID Information
+ at section Process, Group, and User IDs
+
+ at c syscalls.cc
+ at anchor{doc-getpgrp}
+ at deftypefn {Built-in Function} {pgid =} getpgrp ()
+Return the process group id of the current process.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-getpid}
+ at deftypefn {Built-in Function} {pid =} getpid ()
+Return the process id of the current process.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-getppid}
+ at deftypefn {Built-in Function} {pid =} getppid ()
+Return the process id of the parent process.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-geteuid}
+ at deftypefn {Built-in Function} {euid =} geteuid ()
+Return the effective user id of the current process.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-getuid}
+ at deftypefn {Built-in Function} {uid =} getuid ()
+Return the real user id of the current process.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-getegid}
+ at deftypefn {Built-in Function} {egid =} getegid ()
+Return the effective group id of the current process.
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-getgid}
+ at deftypefn {Built-in Function} {gid =} getgid ()
+Return the real group id of the current process.
+ at end deftypefn
+
+
+ at node Environment Variables
+ at section Environment Variables
+
+ at c sysdep.cc
+ at anchor{doc-getenv}
+ at deftypefn {Built-in Function} {} getenv (@var{var})
+Return the value of the environment variable @var{var}.  For example,
+
+ at example
+getenv ("PATH")
+ at end example
+
+ at noindent
+returns a string containing the value of your path.
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-putenv}
+ at deftypefn {Built-in Function} {} putenv (@var{var}, @var{value})
+ at deftypefnx {Built-in Function} {} setenv (@var{var}, @var{value})
+Set the value of the environment variable @var{var} to @var{value}.
+ at end deftypefn
+
+
+ at node Current Working Directory
+ at section Current Working Directory
+
+ at c dirfns.cc
+ at anchor{doc-cd}
+ at deffn {Command} cd dir
+ at deffnx {Command} chdir dir
+Change the current working directory to @var{dir}.  If @var{dir} is
+omitted, the current directory is changed to the user's home
+directory.  For example,
+
+ at example
+cd ~/octave
+ at end example
+
+ at noindent
+Changes the current working directory to @file{~/octave}.  If the
+directory does not exist, an error message is printed and the working
+directory is not changed.
+ at seealso{@ref{doc-mkdir,,mkdir}, @ref{doc-rmdir,,rmdir}, @ref{doc-dir,,dir}}
+ at end deffn
+
+
+ at c ./miscellaneous/ls.m
+ at anchor{doc-ls}
+ at deffn {Command} ls options
+List directory contents.  For example,
+
+ at example
+ at group
+ls -l
+     @print{} total 12
+     @print{} -rw-r--r--   1 jwe  users  4488 Aug 19 04:02 foo.m
+     @print{} -rw-r--r--   1 jwe  users  1315 Aug 17 23:14 bar.m
+ at end group
+ at end example
+
+The @code{dir} and @code{ls} commands are implemented by calling your
+system's directory listing command, so the available options may vary
+from system to system.
+ at seealso{@ref{doc-dir,,dir}, @ref{doc-stat,,stat}, @ref{doc-readdir,,readdir}, @ref{doc-glob,,glob}, @ref{doc-filesep,,filesep}, @ref{doc-ls_command,,ls_command}}
+ at end deffn
+
+
+ at c ./miscellaneous/ls_command.m
+ at anchor{doc-ls_command}
+ at deftypefn {Function File} {[@var{old_cmd} =} ls_command (@var{cmd})
+Set or return the shell command used by Octave's @code{ls} command.
+The value of @var{cmd} must be a character string.
+With no arguments, simply return the previous value.
+ at seealso{@ref{doc-ls,,ls}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/dir.m
+ at anchor{doc-dir}
+ at deftypefn {Function File} {} dir (@var{directory})
+ at deftypefnx {Function File} {[@var{list}] =} dir (@var{directory})
+Display file listing for directory @var{directory}.  If a return
+value is requested, return a structure array with the fields
+
+ at example
+ at group
+name
+bytes
+date
+isdir
+statinfo
+ at end group
+ at end example
+
+ at noindent
+in which @code{statinfo} is the structure returned from @code{stat}.
+
+If @var{directory} is not a directory, return information about the
+named @var{filename}.  @var{directory} may be a list of directories
+specified either by name or with wildcard characters (like * and ?)
+which will be expanded with glob.
+
+Note that for symbolic links, @code{dir} returns information about
+the file that a symbolic link points to instead of the link itself.
+However, if the link points to a nonexistent file, @code{dir} returns
+information about the link.
+ at seealso{@ref{doc-ls,,ls}, @ref{doc-stat,,stat}, @ref{doc-lstat,,lstat}, @ref{doc-readdir,,readdir}, @ref{doc-glob,,glob}, @ref{doc-filesep,,filesep}}
+ at end deftypefn
+
+
+ at c dirfns.cc
+ at anchor{doc-pwd}
+ at deftypefn {Built-in Function} {} pwd ()
+Return the current working directory.
+ at seealso{@ref{doc-dir,,dir}, @ref{doc-ls,,ls}}
+ at end deftypefn
+
+
+ at node Password Database Functions
+ at section Password Database Functions
+
+Octave's password database functions return information in a structure
+with the following fields.
+
+ at table @code
+ at item name
+The user name.
+
+ at item passwd
+The encrypted password, if available.
+
+ at item uid
+The numeric user id.
+
+ at item gid
+The numeric group id.
+
+ at item gecos
+The GECOS field.
+
+ at item dir
+The home directory.
+
+ at item shell
+The initial shell.
+ at end table
+
+In the descriptions of the following functions, this data structure is
+referred to as a @var{pw_struct}.
+
+ at c ./DLD-FUNCTIONS/getpwent.cc
+ at anchor{doc-getpwent}
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwent ()
+Return a structure containing an entry from the password database,
+opening it if necessary.  Once the end of the data has been reached,
+ at code{getpwent} returns 0.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getpwent.cc
+ at anchor{doc-getpwuid}
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwuid (@var{uid}).
+Return a structure containing the first entry from the password database
+with the user ID @var{uid}.  If the user ID does not exist in the
+database, @code{getpwuid} returns 0.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getpwent.cc
+ at anchor{doc-getpwnam}
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwnam (@var{name})
+Return a structure containing the first entry from the password database
+with the user name @var{name}.  If the user name does not exist in the
+database, @code{getpwname} returns 0.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getpwent.cc
+ at anchor{doc-setpwent}
+ at deftypefn {Loadable Function} {} setpwent ()
+Return the internal pointer to the beginning of the password database.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getpwent.cc
+ at anchor{doc-endpwent}
+ at deftypefn {Loadable Function} {} endpwent ()
+Close the password database.
+ at end deftypefn
+
+
+ at node Group Database Functions
+ at section Group Database Functions
+
+Octave's group database functions return information in a structure
+with the following fields.
+
+ at table @code
+ at item name
+The user name.
+
+ at item passwd
+The encrypted password, if available.
+
+ at item gid
+The numeric group id.
+
+ at item mem
+The members of the group.
+ at end table
+
+In the descriptions of the following functions, this data structure is
+referred to as a @var{grp_struct}.
+
+ at c ./DLD-FUNCTIONS/getgrent.cc
+ at anchor{doc-getgrent}
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrent ()
+Return an entry from the group database, opening it if necessary.
+Once the end of the data has been reached, @code{getgrent} returns 0.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getgrent.cc
+ at anchor{doc-getgrgid}
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrgid (@var{gid}).
+Return the first entry from the group database with the group ID
+ at var{gid}.  If the group ID does not exist in the database,
+ at code{getgrgid} returns 0.
+ at end deftypefn
+
+         
+ at c ./DLD-FUNCTIONS/getgrent.cc
+ at anchor{doc-getgrnam}
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrnam (@var{name})
+Return the first entry from the group database with the group name
+ at var{name}.  If the group name does not exist in the database,
+ at code{getgrnam} returns 0.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getgrent.cc
+ at anchor{doc-setgrent}
+ at deftypefn {Loadable Function} {} setgrent ()
+Return the internal pointer to the beginning of the group database.
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getgrent.cc
+ at anchor{doc-endgrent}
+ at deftypefn {Loadable Function} {} endgrent ()
+Close the group database.
+ at end deftypefn
+
+
+ at node System Information
+ at section System Information
+
+ at c ./miscellaneous/computer.m
+ at anchor{doc-computer}
+ at deftypefn {Function File} {[@var{c}, @var{maxsize}, @var{endian}] =} computer ()
+Print or return a string of the form @var{cpu}- at var{vendor}- at var{os}
+that identifies the kind of computer Octave is running on.  If invoked
+with an output argument, the value is returned instead of printed.  For
+example,
+
+ at example
+ at group
+computer ()
+     @print{} i586-pc-linux-gnu
+
+x = computer ()
+     @result{} x = "i586-pc-linux-gnu"
+ at end group
+ at end example
+
+If two output arguments are requested, also return the maximum number
+of elements for an array.
+
+If three output arguments are requested, also return the byte order
+of the current system as a character (@code{"B"} for big-endian or
+ at code{"L"} for little-endian).
+ at end deftypefn
+
+
+ at c syscalls.cc
+ at anchor{doc-uname}
+ at deftypefn {Built-in Function} {[@var{uts}, @var{err}, @var{msg}] =} uname ()
+Return system information in the structure.  For example,
+
+ at example
+ at group
+uname ()
+     @result{} @{
+           sysname = x86_64
+           nodename = segfault
+           release = 2.6.15-1-amd64-k8-smp
+           version = Linux
+           machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006
+         @}
+ at end group
+ at end example
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+
+
+ at c ./miscellaneous/ispc.m
+ at anchor{doc-ispc}
+ at deftypefn {Function File} {} ispc ()
+Return 1 if Octave is running on a Windows system and 0 otherwise.
+ at seealso{@ref{doc-ismac,,ismac}, @ref{doc-isunix,,isunix}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/isunix.m
+ at anchor{doc-isunix}
+ at deftypefn {Function File} {} isunix ()
+Return 1 if Octave is running on a Unix-like system and 0 otherwise.
+ at seealso{@ref{doc-ismac,,ismac}, @ref{doc-ispc,,ispc}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/ismac.m
+ at anchor{doc-ismac}
+ at deftypefn {Function File} {} ismac ()
+Return 1 if Octave is running on a Mac OS X system and 0 otherwise.
+ at seealso{@ref{doc-ispc,,ispc}, @ref{doc-isunix,,isunix}}
+ at end deftypefn
+
+
+ at c sysdep.cc
+ at anchor{doc-isieee}
+ at deftypefn {Built-in Function} {} isieee ()
+Return 1 if your computer claims to conform to the IEEE standard for
+floating point calculations.
+ at end deftypefn
+
+
+ at c defaults.cc
+ at anchor{doc-OCTAVE_HOME}
+ at deftypefn {Built-in Function} {} OCTAVE_HOME ()
+Return the name of the top-level Octave installation directory.
+ at end deftypefn
+
+
+ at c defaults.cc
+ at anchor{doc-OCTAVE_VERSION}
+ at deftypefn {Built-in Function} {} OCTAVE_VERSION ()
+Return the version number of Octave, as a string.
+ at end deftypefn
+
+
+ at c ./miscellaneous/license.m
+ at anchor{doc-license}
+ at deftypefn {Function File} {} license
+Display the license of Octave.
+
+ at deftypefnx {Function File} {} license ("inuse")
+Display a list of packages currently being used.
+
+ at deftypefnx {Function File} {@var{retval} =} license ("inuse")
+Return a structure containing the fields @code{feature} and @code{user}.
+
+ at deftypefnx {Function File} {@var{retval} =} license ("test", @var{feature})
+Return 1 if a license exists for the product identified by the string
+ at var{feature} and 0 otherwise.  The argument @var{feature} is case
+insensitive and only the first 27 characters are checked.
+
+ at deftypefnx {Function File} {} license ("test", @var{feature}, @var{toggle})
+Enable or disable license testing for @var{feature}, depending on
+ at var{toggle}, which may be one of:
+
+ at table @samp
+ at item "enable"
+Future tests for the specified license of @var{feature} are conducted
+as usual.
+ at item "disable"
+Future tests for the specified license of @var{feature} return 0.
+ at end table
+
+ at deftypefnx {Function File} {@var{retval} =} license ("checkout", @var{feature})
+Check out a license for @var{feature}, returning 1 on success and 0
+on failure.
+
+This function is provided for compatibility with @sc{matlab}.
+ at seealso{@ref{doc-ver,,ver}, @ref{doc-version,,version}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/version.m
+ at anchor{doc-version}
+ at deftypefn {Function File} {} version ()
+Return Octave's version number as a string.  This is also the value of
+the built-in variable @w{@code{OCTAVE_VERSION}}.
+ at end deftypefn
+
+
+ at c ./miscellaneous/ver.m
+ at anchor{doc-ver}
+ at deftypefn {Function File} {} ver ()
+Display a header containing the current Octave version
+number, license string and operating system, followed by 
+the installed package names, versions, and installation
+directories.
+ at deftypefnx {Function File} {v =} ver ()
+Return a vector of structures, respecting Octave and each installed package.
+The structure includes the following fields.
+
+ at table @code
+ at item Name
+  Package name.
+ at item Version
+  Version of the package.
+ at item Revision
+  Revision of the package.
+ at item Date
+  Date respecting the version/revision.
+ at end table
+ at deftypefnx {Function File} {v =} ver (@code{"Octave"})
+Return version information for Octave only..
+ at deftypefnx {Function File} {v =} ver (@var{pkg})
+Return version information for the specified package @var{pkg}.
+ at seealso{@ref{doc-license,,license}, @ref{doc-version,,version}}
+ at end deftypefn
+
+
+ at c toplev.cc
+ at anchor{doc-octave_config_info}
+ at deftypefn {Built-in Function} {} octave_config_info (@var{option})
+Return a structure containing configuration and installation
+information for Octave.
+
+if @var{option} is a string, return the configuration information for the
+specified option.
+
+ at end deftypefn
+
+
+ at c ./DLD-FUNCTIONS/getrusage.cc
+ at anchor{doc-getrusage}
+ at deftypefn {Loadable Function} {} getrusage ()
+Return a structure containing a number of statistics about the current
+Octave process.  Not all fields are available on all systems.  If it is
+not possible to get CPU time statistics, the CPU time slots are set to
+zero.  Other missing data are replaced by NaN.  Here is a list of all
+the possible fields that can be present in the structure returned by
+ at code{getrusage}:
+
+ at table @code
+ at item idrss
+Unshared data size.
+
+ at item inblock
+Number of block input operations.
+
+ at item isrss
+Unshared stack size.
+
+ at item ixrss
+Shared memory size.
+
+ at item majflt
+Number of major page faults.
+
+ at item maxrss
+Maximum data size.
+
+ at item minflt
+Number of minor page faults.
+
+ at item msgrcv
+Number of messages received.
+
+ at item msgsnd
+Number of messages sent.
+
+ at item nivcsw
+Number of involuntary context switches.
+
+ at item nsignals
+Number of signals received.
+
+ at item nswap
+Number of swaps.
+
+ at item nvcsw
+Number of voluntary context switches.
+
+ at item oublock
+Number of block output operations.
+
+ at item stime
+A structure containing the system CPU time used.  The structure has the
+elements @code{sec} (seconds) @code{usec} (microseconds).
+
+ at item utime
+A structure containing the user CPU time used.  The structure has the
+elements @code{sec} (seconds) @code{usec} (microseconds).
+ at end table
+ at end deftypefn
+
+
+ at node Hashing Functions
+ at section Hashing Functions
+
+It is often necessary to find if two strings or files are
+identical.  This might be done by comparing them character by character
+and looking for differences.  However, this can be slow, and so comparing
+a hash of the string or file can be a rapid way of finding if the files
+differ.
+
+Another use of the hashing function is to check for file integrity.  The
+user can check the hash of the file against a known value and find if
+the file they have is the same as the one that the original hash was
+produced with.
+
+Octave supplies the @code{md5sum} function to perform MD5 hashes on
+strings and files.  An example of the use of @code{md5sum} function might
+be
+
+ at example
+ at group
+if exist (file, "file")
+  hash = md5sum (file);
+else
+  # Treat the variable "file" as a string
+  hash = md5sum (file, true);
+endif
+ at end group
+ at end example
+
+ at c ./DLD-FUNCTIONS/md5sum.cc
+ at anchor{doc-md5sum}
+ at deftypefn {Loadable Function} {} md5sum (@var{file})
+ at deftypefnx {Loadable Function} {} md5sum (@var{str}, @var{opt})
+Calculates the MD5 sum of the file @var{file}.  If the second parameter
+ at var{opt} exists and is true, then calculate the MD5 sum of the
+string @var{str}.
+ at end deftypefn
+
diff --git a/doc/interpreter/system.txi b/doc/interpreter/system.txi
new file mode 100644
index 0000000..6f73127
--- /dev/null
+++ b/doc/interpreter/system.txi
@@ -0,0 +1,492 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node System Utilities
+ at chapter System Utilities
+
+This chapter describes the functions that are available to allow you to
+get information about what is happening outside of Octave, while it is
+still running, and use this information in your program.  For example,
+you can get information about environment variables, the current time,
+and even start other programs from the Octave prompt.
+
+ at menu
+* Timing Utilities::            
+* Filesystem Utilities::        
+* File Archiving Utilities::
+* Networking Utilities::
+* Controlling Subprocesses::    
+* Process ID Information::      
+* Environment Variables::       
+* Current Working Directory::   
+* Password Database Functions::  
+* Group Database Functions::    
+* System Information::          
+* Hashing Functions::
+ at end menu
+
+ at node Timing Utilities
+ at section Timing Utilities
+
+Octave's core set of functions for manipulating time values are
+patterned after the corresponding functions from the standard C library.
+Several of these functions use a data structure for time that includes
+the following elements:
+
+ at table @code
+ at item usec
+Microseconds after the second (0-999999).
+
+ at item sec
+Seconds after the minute (0-61).  This number can be 61 to account
+for leap seconds.
+
+ at item min
+Minutes after the hour (0-59).
+
+ at item hour
+Hours since midnight (0-23).
+
+ at item mday
+Day of the month (1-31).
+
+ at item mon
+Months since January (0-11).
+
+ at item year
+Years since 1900.
+
+ at item wday
+Days since Sunday (0-6).
+
+ at item yday
+Days since January 1 (0-365).
+
+ at item isdst
+Daylight Savings Time flag.
+
+ at item zone
+Time zone.
+ at end table
+
+ at noindent
+In the descriptions of the following functions, this structure is
+referred to as a @var{tm_struct}.
+
+ at DOCSTRING(time)
+
+ at DOCSTRING(now)
+
+ at DOCSTRING(ctime)
+
+ at DOCSTRING(gmtime)
+
+ at DOCSTRING(localtime)
+
+ at DOCSTRING(mktime)
+
+ at DOCSTRING(asctime)
+
+ at DOCSTRING(strftime)
+
+ at DOCSTRING(strptime)
+
+Most of the remaining functions described in this section are not
+patterned after the standard C library.  Some are available for
+compatibility with @sc{matlab} and others are provided because they are
+useful.
+
+ at DOCSTRING(clock)
+
+ at DOCSTRING(date)
+
+ at DOCSTRING(etime)
+
+ at DOCSTRING(cputime)
+
+ at DOCSTRING(is_leap_year)
+
+ at anchor{doc-toc}
+ at DOCSTRING(tic)
+
+ at DOCSTRING(pause)
+
+ at DOCSTRING(sleep)
+
+ at DOCSTRING(usleep)
+
+ at DOCSTRING(datenum)
+
+ at DOCSTRING(datestr)
+
+ at DOCSTRING(datevec)
+
+ at DOCSTRING(addtodate)
+
+ at DOCSTRING(calendar)
+
+ at DOCSTRING(weekday)
+
+ at DOCSTRING(eomday)
+
+ at DOCSTRING(datetick)
+
+ at node Filesystem Utilities
+ at section Filesystem Utilities
+
+Octave includes the following functions for renaming and deleting files,
+creating, deleting, and reading directories, and for getting information
+about the status of files.
+
+ at DOCSTRING(rename)
+
+ at DOCSTRING(link)
+
+ at DOCSTRING(symlink)
+
+ at DOCSTRING(readlink)
+
+ at DOCSTRING(unlink)
+
+ at DOCSTRING(readdir)
+
+ at DOCSTRING(mkdir)
+
+ at DOCSTRING(rmdir)
+
+ at DOCSTRING(confirm_recursive_rmdir)
+
+ at DOCSTRING(mkfifo)
+
+ at DOCSTRING(umask)
+
+ at anchor{doc-lstat}
+ at DOCSTRING(stat)
+
+ at DOCSTRING(fstat)
+
+ at DOCSTRING(fileattrib)
+
+ at DOCSTRING(isdir)
+
+ at DOCSTRING(glob)
+
+ at DOCSTRING(fnmatch)
+
+ at DOCSTRING(file_in_path)
+
+ at DOCSTRING(tilde_expand)
+
+ at DOCSTRING(canonicalize_file_name)
+
+ at DOCSTRING(movefile)
+
+ at DOCSTRING(copyfile)
+
+ at DOCSTRING(fileparts)
+
+ at DOCSTRING(filesep)
+
+ at DOCSTRING(filemarker)
+
+ at DOCSTRING(fullfile)
+
+ at DOCSTRING(tempdir)
+
+ at DOCSTRING(tempname)
+
+ at DOCSTRING(P_tmpdir)
+
+ at DOCSTRING(is_absolute_filename)
+
+ at DOCSTRING(is_rooted_relative_filename)
+
+ at DOCSTRING(make_absolute_filename)
+
+ at node File Archiving Utilities
+ at section File Archiving Utilities
+
+ at DOCSTRING(bunzip2)
+
+ at DOCSTRING(gzip)
+
+ at DOCSTRING(gunzip)
+
+ at DOCSTRING(tar)
+
+ at DOCSTRING(untar)
+
+ at DOCSTRING(zip)
+
+ at DOCSTRING(unzip)
+
+ at DOCSTRING(pack)
+
+ at DOCSTRING(unpack)
+
+ at DOCSTRING(bzip2)
+
+ at node Networking Utilities
+ at section Networking Utilities
+
+ at DOCSTRING(urlread)
+
+ at DOCSTRING(urlwrite)
+
+ at node Controlling Subprocesses
+ at section Controlling Subprocesses
+
+Octave includes some high-level commands like @code{system} and
+ at code{popen} for starting subprocesses.  If you want to run another
+program to perform some task and then look at its output, you will
+probably want to use these functions.
+
+Octave also provides several very low-level Unix-like functions which
+can also be used for starting subprocesses, but you should probably only
+use them if you can't find any way to do what you need with the
+higher-level functions.
+
+ at DOCSTRING(system)
+
+ at DOCSTRING(unix)
+
+ at DOCSTRING(dos)
+
+ at DOCSTRING(perl)
+
+ at DOCSTRING(popen)
+
+ at DOCSTRING(pclose)
+
+ at DOCSTRING(popen2)
+
+ at DOCSTRING(EXEC_PATH)
+
+In most cases, the following functions simply decode their arguments and
+make the corresponding Unix system calls.  For a complete example of how
+they can be used, look at the definition of the function @code{popen2}.
+
+ at DOCSTRING(fork)
+
+ at DOCSTRING(exec)
+
+ at DOCSTRING(pipe)
+
+ at DOCSTRING(dup2)
+
+ at DOCSTRING(waitpid)
+
+ at DOCSTRING(WCONTINUE)
+
+ at DOCSTRING(WCOREDUMP)
+
+ at DOCSTRING(WEXITSTATUS)
+
+ at DOCSTRING(WIFCONTINUED)
+ 
+ at DOCSTRING(WIFSIGNALED)
+
+ at DOCSTRING(WIFSTOPPED)
+
+ at DOCSTRING(WIFEXITED)
+
+ at DOCSTRING(WNOHANG)
+
+ at DOCSTRING(WSTOPSIG)
+ 
+ at DOCSTRING(WTERMSIG)
+
+ at DOCSTRING(WUNTRACED)
+
+ at DOCSTRING(fcntl)
+
+ at DOCSTRING(kill)
+
+ at DOCSTRING(SIG)
+
+ at node Process ID Information
+ at section Process, Group, and User IDs
+
+ at DOCSTRING(getpgrp)
+
+ at DOCSTRING(getpid)
+
+ at DOCSTRING(getppid)
+
+ at DOCSTRING(geteuid)
+
+ at DOCSTRING(getuid)
+
+ at DOCSTRING(getegid)
+
+ at DOCSTRING(getgid)
+
+ at node Environment Variables
+ at section Environment Variables
+
+ at DOCSTRING(getenv)
+
+ at DOCSTRING(putenv)
+
+ at node Current Working Directory
+ at section Current Working Directory
+
+ at DOCSTRING(cd)
+
+ at DOCSTRING(ls)
+
+ at DOCSTRING(ls_command)
+
+ at DOCSTRING(dir)
+
+ at DOCSTRING(pwd)
+
+ at node Password Database Functions
+ at section Password Database Functions
+
+Octave's password database functions return information in a structure
+with the following fields.
+
+ at table @code
+ at item name
+The user name.
+
+ at item passwd
+The encrypted password, if available.
+
+ at item uid
+The numeric user id.
+
+ at item gid
+The numeric group id.
+
+ at item gecos
+The GECOS field.
+
+ at item dir
+The home directory.
+
+ at item shell
+The initial shell.
+ at end table
+
+In the descriptions of the following functions, this data structure is
+referred to as a @var{pw_struct}.
+
+ at DOCSTRING(getpwent)
+
+ at DOCSTRING(getpwuid)
+
+ at DOCSTRING(getpwnam)
+
+ at DOCSTRING(setpwent)
+
+ at DOCSTRING(endpwent)
+
+ at node Group Database Functions
+ at section Group Database Functions
+
+Octave's group database functions return information in a structure
+with the following fields.
+
+ at table @code
+ at item name
+The user name.
+
+ at item passwd
+The encrypted password, if available.
+
+ at item gid
+The numeric group id.
+
+ at item mem
+The members of the group.
+ at end table
+
+In the descriptions of the following functions, this data structure is
+referred to as a @var{grp_struct}.
+
+ at DOCSTRING(getgrent)
+
+ at DOCSTRING(getgrgid)
+         
+ at DOCSTRING(getgrnam)
+
+ at DOCSTRING(setgrent)
+
+ at DOCSTRING(endgrent)
+
+ at node System Information
+ at section System Information
+
+ at DOCSTRING(computer)
+
+ at DOCSTRING(uname)
+
+ at DOCSTRING(ispc)
+
+ at DOCSTRING(isunix)
+
+ at DOCSTRING(ismac)
+
+ at DOCSTRING(isieee)
+
+ at DOCSTRING(OCTAVE_HOME)
+
+ at DOCSTRING(OCTAVE_VERSION)
+
+ at DOCSTRING(license)
+
+ at DOCSTRING(version)
+
+ at DOCSTRING(ver)
+
+ at DOCSTRING(octave_config_info)
+
+ at DOCSTRING(getrusage)
+
+ at node Hashing Functions
+ at section Hashing Functions
+
+It is often necessary to find if two strings or files are
+identical.  This might be done by comparing them character by character
+and looking for differences.  However, this can be slow, and so comparing
+a hash of the string or file can be a rapid way of finding if the files
+differ.
+
+Another use of the hashing function is to check for file integrity.  The
+user can check the hash of the file against a known value and find if
+the file they have is the same as the one that the original hash was
+produced with.
+
+Octave supplies the @code{md5sum} function to perform MD5 hashes on
+strings and files.  An example of the use of @code{md5sum} function might
+be
+
+ at example
+ at group
+if exist (file, "file")
+  hash = md5sum (file);
+else
+  # Treat the variable "file" as a string
+  hash = md5sum (file, true);
+endif
+ at end group
+ at end example
+
+ at DOCSTRING(md5sum)
diff --git a/doc/interpreter/testfun.texi b/doc/interpreter/testfun.texi
new file mode 100644
index 0000000..809c762
--- /dev/null
+++ b/doc/interpreter/testfun.texi
@@ -0,0 +1,638 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 2005, 2007, 2009 David Bateman
+ at c Copyright (C) 2002, 2003, 2004, 2005 Paul Kienzle
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Test and Demo Functions
+ at appendix Test and Demo Functions
+ at cindex test functions
+
+Octave includes a number of functions to allow the integration of testing
+and demonstration code in the source code of the functions themselves.
+
+ at menu
+* Test Functions::
+* Demonstration Functions::
+ at end menu
+
+ at node Test Functions
+ at section Test Functions
+
+ at c ./testfun/test.m
+ at anchor{doc-test}
+ at deftypefn {Function File} {} test @var{name}
+ at deftypefnx {Function File} {} test @var{name} quiet|normal|verbose
+ at deftypefnx {Function File} {} test ('@var{name}', 'quiet|normal|verbose', @var{fid})
+ at deftypefnx {Function File} {} test ([], 'explain', @var{fid})
+ at deftypefnx {Function File} {@var{success} =} test (@dots{})
+ at deftypefnx {Function File} {[@var{n}, @var{max}] =} test (@dots{})
+ at deftypefnx {Function File} {[@var{code}, @var{idx}] =} test ('@var{name}','grabdemo')
+
+Perform tests from the first file in the loadpath matching @var{name}.
+ at code{test} can be called as a command or as a function.  Called with 
+a single argument @var{name}, the tests are run interactively and stop
+after the first error is encountered.
+
+With a second argument the tests which are performed and the amount of
+output is selected.
+
+ at table @asis
+ at item 'quiet'
+ Don't report all the tests as they happen, just the errors.
+
+ at item 'normal'
+Report all tests as they happen, but don't do tests which require 
+user interaction.
+
+ at item 'verbose'
+Do tests which require user interaction.
+ at end table
+
+The argument @var{fid} can be used to allow batch processing.  Errors
+can be written to the already open file defined by @var{fid}, and 
+hopefully when Octave crashes this file will tell you what was happening
+when it did.  You can use @code{stdout} if you want to see the results as
+they happen.  You can also give a file name rather than an @var{fid}, in
+which case the contents of the file will be replaced with the log from 
+the current test.
+
+Called with a single output argument @var{success}, @code{test} returns
+true if all of the tests were successful.  Called with two output arguments
+ at var{n} and @var{max}, the number of successful tests and the total number
+of tests in the file @var{name} are returned.
+
+If the second argument is the string 'grabdemo', the contents of the demo
+blocks are extracted but not executed.  Code for all code blocks is
+concatenated and returned as @var{code} with @var{idx} being a vector of
+positions of the ends of the demo blocks.
+
+If the second argument is 'explain', then @var{name} is ignored and an
+explanation of the line markers used is written to the file @var{fid}.
+ at seealso{@ref{doc-error,,error}, @ref{doc-assert,,assert}, @ref{doc-fail,,fail}, @ref{doc-demo,,demo}, @ref{doc-example,,example}}
+ at end deftypefn
+
+
+ at code{test} scans the named script file looking for lines which
+start with @code{%!}.  The prefix is stripped off and the rest of the
+line is processed through the Octave interpreter.  If the code
+generates an error, then the test is said to fail.
+
+Since @code{eval()} will stop at the first error it encounters, you must
+divide your tests up into blocks, with anything in a separate
+block evaluated separately.  Blocks are introduced by the keyword
+ at code{test} immediately following the @code{%!}.  For example,
+
+ at example
+ at group
+   %!test error ("this test fails!");
+   %!test "test doesn't fail. it doesn't generate an error";
+ at end group
+ at end example
+
+When a test fails, you will see something like:
+
+ at example
+ at group
+     ***** test error ('this test fails!')
+   !!!!! test failed
+   this test fails!
+ at end group
+ at end example
+
+Generally, to test if something works, you want to assert that it
+produces a correct value.  A real test might look something like
+
+ at example
+ at group
+   %!test
+   %! @var{a} = [1, 2, 3; 4, 5, 6]; B = [1; 2];
+   %! expect = [ @var{a} ; 2*@var{a} ];
+   %! get = kron (@var{b}, @var{a});
+   %! if (any(size(expect) != size(get)))
+   %!    error ("wrong size: expected %d,%d but got %d,%d",
+   %!           size(expect), size(get));
+   %! elseif (any(any(expect!=get)))
+   %!    error ("didn't get what was expected.");
+   %! endif
+ at end group
+ at end example
+
+To make the process easier, use the @code{assert} function.  For example,
+with @code{assert} the previous test is reduced to:
+
+ at example
+ at group
+   %!test
+   %! @var{a} = [1, 2, 3; 4, 5, 6]; @var{b} = [1; 2];
+   %! assert (kron (@var{b}, @var{a}), [ @var{a}; 2*@var{a} ]);
+ at end group
+ at end example
+
+ at code{assert} can accept a tolerance so that you can compare results
+absolutely or relatively.  For example, the following all succeed:
+
+ at example
+ at group
+   %!test assert (1+eps, 1, 2*eps)          # absolute error
+   %!test assert (100+100*eps, 100, -2*eps) # relative error
+ at end group
+ at end example
+
+You can also do the comparison yourself, but still have assert
+generate the error:
+
+ at example
+ at group
+   %!test assert (isempty([]))
+   %!test assert ([ 1,2; 3,4 ] > 0)
+ at end group
+ at end example
+
+Because @code{assert} is so frequently used alone in a test block, there
+is a shorthand form:
+
+ at example
+   %!assert (@dots{})
+ at end example
+
+which is equivalent to:
+
+ at example
+   %!test assert (@dots{})
+ at end example
+
+Sometimes during development there is a test that should work but is
+known to fail.  You still want to leave the test in because when the
+final code is ready the test should pass, but you may not be able to
+fix it immediately.  To avoid unnecessary bug reports for these known
+failures, mark the block with @code{xtest} rather than @code{test}:
+
+ at example
+ at group
+   %!xtest assert (1==0)
+   %!xtest fail ('success=1','error'))
+ at end group
+ at end example
+
+Another use of @code{xtest} is for statistical tests which should
+pass most of the time but are known to fail occasionally.
+
+Each block is evaluated in its own function environment, which means
+that variables defined in one block are not automatically shared
+with other blocks.  If you do want to share variables, then you
+must declare them as @code{shared} before you use them.  For example, the
+following declares the variable @var{a}, gives it an initial value (default
+is empty), then uses it in several subsequent tests.
+
+ at example
+ at group
+   %!shared @var{a}
+   %! @var{a} = [1, 2, 3; 4, 5, 6];
+   %!assert (kron ([1; 2], @var{a}), [ @var{a}; 2*@var{a} ]);
+   %!assert (kron ([1, 2], @var{a}), [ @var{a}, 2*@var{a} ]);
+   %!assert (kron ([1,2; 3,4], @var{a}), [ @var{a},2*@var{a}; 3*@var{a},4*@var{a} ]);
+ at end group
+ at end example
+
+You can share several variables at the same time:
+
+ at example
+   %!shared @var{a}, @var{b}
+ at end example
+
+You can also share test functions:
+
+ at example
+ at group
+   %!function @var{a} = fn(@var{b})
+   %!  @var{a} = 2*@var{b};
+   %!assert (@var{a}(2),4);
+ at end group
+ at end example
+
+Note that all previous variables and values are lost when a new 
+shared block is declared.
+
+Error and warning blocks are like test blocks, but they only succeed 
+if the code generates an error.  You can check the text of the error
+is correct using an optional regular expression @code{<pattern>}.  
+For example:
+
+ at example
+   %!error <passes!> error('this test passes!');
+ at end example
+
+If the code doesn't generate an error, the test fails.  For example,
+
+ at example
+   %!error "this is an error because it succeeds.";
+ at end example
+
+produces
+
+ at example
+ at group
+   ***** error "this is an error because it succeeds.";
+   !!!!! test failed: no error
+ at end group
+ at end example
+
+It is important to automate the tests as much as possible, however
+some tests require user interaction.  These can be isolated into
+demo blocks, which if you are in batch mode, are only run when 
+called with @code{demo} or @code{verbose}.  The code is displayed before
+it is executed.  For example,
+
+ at example
+ at group
+   %!demo
+   %! @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t});
+   %! plot(@var{t}, at var{x});
+   %! you should now see a sine wave in your figure window
+ at end group
+ at end example
+
+produces
+
+ at example
+ at group
+   > @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t});
+   > plot(@var{t}, at var{x});
+   > you should now see a sine wave in your figure window
+   Press <enter> to continue: 
+ at end group
+ at end example
+
+Note that demo blocks cannot use any shared variables.  This is so
+that they can be executed by themselves, ignoring all other tests.
+
+If you want to temporarily disable a test block, put @code{#} in place
+of the block type.  This creates a comment block which is echoed
+in the log file, but is not executed.  For example:
+
+ at example
+ at group
+   %!#demo
+   %! @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t});
+   %! plot(@var{t}, at var{x});
+   %! you should now see a sine wave in your figure window
+ at end group
+ at end example
+
+Block type summary:
+
+ at table @code
+ at item %!test
+check that entire block is correct
+ at item %!error
+check for correct error message
+ at item %!warning
+check for correct warning message
+ at item %!demo
+demo only executes in interactive mode
+ at item %!#
+comment: ignore everything within the block
+ at item %!shared x,y,z
+declares variables for use in multiple tests
+ at item %!function
+defines a function value for a shared variable
+ at item %!assert (x, y, tol)
+shorthand for %!test assert (x, y, tol)
+ at end table
+
+You can also create test scripts for builtins and your own C++
+functions.  Just put a file of the function name on your path without
+any extension and it will be picked up by the test procedure.  You
+can even embed tests directly in your C++ code:
+
+ at example
+ at group
+   #if 0
+   %!test disp('this is a test')
+   #endif
+ at end group
+ at end example
+
+or
+
+ at example
+ at group
+   /*
+   %!test disp('this is a test')
+   */
+ at end group
+ at end example
+
+but then the code will have to be on the load path and the user 
+will have to remember to type test('name.cc').  Conversely, you
+can separate the tests from normal Octave script files by putting
+them in plain files with no extension rather than in script files.
+ at c DO I WANT TO INCLUDE THE EDITOR SPECIFIC STATEMENT BELOW???
+ at c Don't forget to tell emacs that the plain text file you are using
+ at c is actually octave code, using something like:
+ at c   -*-octave-*-
+
+ at c ./testfun/assert.m
+ at anchor{doc-assert}
+ at deftypefn {Function File} {} assert (@var{cond})
+ at deftypefnx {Function File} {} assert (@var{cond}, @var{errmsg}, @dots{})
+ at deftypefnx {Function File} {} assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
+ at deftypefnx {Function File} {} assert (@var{observed}, at var{expected})
+ at deftypefnx {Function File} {} assert (@var{observed}, at var{expected}, at var{tol})
+
+Produces an error if the condition is not met.  @code{assert} can be
+called in three different ways.
+
+ at table @code
+ at item assert (@var{cond})
+ at itemx assert (@var{cond}, @var{errmsg}, @dots{})
+ at itemx assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
+Called with a single argument @var{cond}, @code{assert} produces an
+error if @var{cond} is zero.  If called with a single argument a
+generic error message.  With more than one argument, the additional
+arguments are passed to the @code{error} function.
+
+ at item assert (@var{observed}, @var{expected})
+Produce an error if observed is not the same as expected.  Note that 
+observed and expected can be strings, scalars, vectors, matrices, 
+lists or structures.
+
+ at item assert(@var{observed}, @var{expected}, @var{tol})
+Accept a tolerance when comparing numbers. 
+If @var{tol} is positive use it as an absolute tolerance, will produce an error if
+ at code{abs(@var{observed} - @var{expected}) > abs(@var{tol})}.
+If @var{tol} is negative use it as a relative tolerance, will produce an error if
+ at code{abs(@var{observed} - @var{expected}) > abs(@var{tol} * @var{expected})}.
+If @var{expected} is zero @var{tol} will always be used as an absolute tolerance.
+ at end table
+ at seealso{@ref{doc-test,,test}}
+ at end deftypefn
+
+
+ at c ./testfun/fail.m
+ at anchor{doc-fail}
+ at deftypefn {Function File} {} fail (@var{code}, at var{pattern})
+ at deftypefnx {Function File} {} fail (@var{code},'warning', at var{pattern})
+
+Return true if @var{code} fails with an error message matching
+ at var{pattern}, otherwise produce an error.  Note that @var{code}
+is a string and if @var{code} runs successfully, the error produced is:
+
+ at example
+          expected error but got none  
+ at end example
+
+If the code fails with a different error, the message produced is:
+
+ at example
+ at group
+          expected <pattern>
+          but got <text of actual error>
+ at end group
+ at end example
+
+The angle brackets are not part of the output.
+
+Called with three arguments, the behavior is similar to 
+ at code{fail(@var{code}, @var{pattern})}, but produces an error if no 
+warning is given during code execution or if the code fails.
+
+ at end deftypefn
+
+
+ at node Demonstration Functions
+ at section Demonstration Functions
+
+ at c ./testfun/demo.m
+ at anchor{doc-demo}
+ at deftypefn {Function File} {} demo ('@var{name}', at var{n})
+
+Runs any examples associated with the function '@var{name}'.  
+Examples are stored in the script file, or in a file with the same 
+name but no extension somewhere on your path.  To keep them separate 
+from the usual script code, all lines are prefixed by @code{%!}.  Each
+example is introduced by the keyword 'demo' flush left to the prefix,
+with no intervening spaces.  The remainder of the example can contain 
+arbitrary Octave code.  For example:
+
+ at example
+ at group
+   %!demo
+   %! t=0:0.01:2*pi; x = sin(t);
+   %! plot(t,x)
+   %! %-------------------------------------------------
+   %! % the figure window shows one cycle of a sine wave
+ at end group
+ at end example
+
+Note that the code is displayed before it is executed, so a simple
+comment at the end suffices.  It is generally not necessary to use
+disp or printf within the demo.
+
+Demos are run in a function environment with no access to external
+variables.  This means that all demos in your function must use
+separate initialization code.  Alternatively, you can combine your
+demos into one huge demo, with the code:
+
+ at example
+   %! input("Press <enter> to continue: ","s");
+ at end example
+
+between the sections, but this is discouraged.  Other techniques
+include using multiple plots by saying figure between each, or
+using subplot to put multiple plots in the same window.
+
+Also, since demo evaluates inside a function context, you cannot
+define new functions inside a demo.  Instead you will have to
+use @code{eval(example('function',n))} to see them.  Because eval only
+evaluates one line, or one statement if the statement crosses
+multiple lines, you must wrap your demo in "if 1 <demo stuff> endif"
+with the 'if' on the same line as 'demo'.  For example,
+
+ at example
+ at group
+  %!demo if 1
+  %!  function y=f(x)
+  %!    y=x;
+  %!  endfunction
+  %!  f(3)
+  %! endif
+ at end group
+ at end example
+ at seealso{@ref{doc-test,,test}, @ref{doc-example,,example}}
+ at end deftypefn
+
+
+ at c ./testfun/rundemos.m
+ at anchor{doc-rundemos}
+ at deftypefn {Function File} {} rundemos (@var{directory})
+ at end deftypefn
+
+
+ at c ./testfun/example.m
+ at anchor{doc-example}
+ at deftypefn {Function File} {} example ('@var{name}', at var{n})
+ at deftypefnx {Function File} {[@var{x}, @var{idx}] =} example ('@var{name}', at var{n})
+
+ Display the code for example @var{n} associated with the function 
+'@var{name}', but do not run it.  If @var{n} is not given, all examples 
+are displayed.
+
+Called with output arguments, the examples are returned in the form of
+a string @var{x}, with @var{idx} indicating the ending position of the 
+various examples.
+
+See @code{demo} for a complete explanation.
+ at seealso{@ref{doc-demo,,demo}, @ref{doc-test,,test}}
+ at end deftypefn
+
+
+ at c ./testfun/speed.m
+ at anchor{doc-speed}
+ at deftypefn {Function File} {} speed (@var{f}, @var{init}, @var{max_n}, @var{f2}, @var{tol})
+ at deftypefnx {Function File} {[@var{order}, @var{n}, @var{T_f}, @var{T_f2}] =} speed (@dots{})
+
+Determine the execution time of an expression for various @var{n}.
+The @var{n} are log-spaced from 1 to @var{max_n}.  For each @var{n},
+an initialization expression is computed to create whatever data
+are needed for the test.  If a second expression is given, the
+execution times of the two expressions will be compared.  Called 
+without output arguments the results are presented graphically.
+
+ at table @code
+ at item @var{f}
+The expression to evaluate.
+
+ at item @var{max_n}
+The maximum test length to run.  Default value is 100.  Alternatively,
+use @code{[min_n,max_n]} or for complete control, @code{[n1,n2, at dots{},nk]}.
+
+ at item @var{init}
+Initialization expression for function argument values.  Use @var{k} 
+for the test number and @var{n} for the size of the test.  This should
+compute values for all variables listed in args.  Note that init will
+be evaluated first for @math{k = 0}, so things which are constant throughout
+the test can be computed then.  The default value is @code{@var{x} =
+randn (@var{n}, 1);}.
+
+ at item @var{f2}
+An alternative expression to evaluate, so the speed of the two
+can be compared.  Default is @code{[]}.
+
+ at item @var{tol}
+If @var{tol} is @code{Inf}, then no comparison will be made between the
+results of expression @var{f} and expression @var{f2}.  Otherwise,
+expression @var{f} should produce a value @var{v} and expression @var{f2} 
+should produce a value @var{v2}, and these shall be compared using 
+ at code{assert(@var{v}, at var{v2}, at var{tol})}.  If @var{tol} is positive,
+the tolerance is assumed to be absolute.  If @var{tol} is negative,
+the tolerance is assumed to be relative.  The default is @code{eps}.
+
+ at item @var{order}
+The time complexity of the expression @code{O(a n^p)}.  This
+is a structure with fields @code{a} and @code{p}.
+
+ at item @var{n}
+The values @var{n} for which the expression was calculated and
+the execution time was greater than zero.
+
+ at item @var{T_f}
+The nonzero execution times recorded for the expression @var{f} in seconds.
+
+ at item @var{T_f2}
+The nonzero execution times recorded for the expression @var{f2} in seconds.
+If it is needed, the mean time ratio is just @code{mean(T_f./T_f2)}.
+
+ at end table
+
+The slope of the execution time graph shows the approximate
+power of the asymptotic running time @code{O(n^p)}.  This
+power is plotted for the region over which it is approximated
+(the latter half of the graph).  The estimated power is not
+very accurate, but should be sufficient to determine the
+general order of your algorithm.  It should indicate if for 
+example your implementation is unexpectedly @code{O(n^2)} 
+rather than @code{O(n)} because it extends a vector each 
+time through the loop rather than preallocating one which is 
+big enough.  For example, in the current version of Octave,
+the following is not the expected @code{O(n)}:
+
+ at example
+speed ("for i = 1:n, y@{i@} = x(i); end", "", [1000,10000])
+ at end example
+
+but it is if you preallocate the cell array @code{y}:
+
+ at example
+ at group
+speed ("for i = 1:n, y@{i@} = x(i); end", ...
+       "x = rand (n, 1); y = cell (size (x));", [1000, 10000])
+ at end group
+ at end example
+
+An attempt is made to approximate the cost of the individual 
+operations, but it is wildly inaccurate.  You can improve the
+stability somewhat by doing more work for each @code{n}.  For
+example:
+
+ at example
+speed ("airy(x)", "x = rand (n, 10)", [10000, 100000])
+ at end example
+
+When comparing a new and original expression, the line on the
+speedup ratio graph should be larger than 1 if the new expression
+is faster.  Better algorithms have a shallow slope.  Generally, 
+vectorizing an algorithm will not change the slope of the execution 
+time graph, but it will shift it relative to the original.  For
+example:
+
+ at example
+ at group
+speed ("v = sum (x)", "", [10000, 100000], ...
+       "v = 0; for i = 1:length (x), v += x(i); end")
+ at end group
+ at end example
+
+A more complex example, if you had an original version of @code{xcorr}
+using for loops and another version using an FFT, you could compare the
+run speed for various lags as follows, or for a fixed lag with varying
+vector lengths as follows:
+
+ at example
+ at group
+speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100,
+       "v2 = xcorr_orig (x, n)", -100*eps)
+speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100,
+       "v2 = xcorr_orig (x, n)", -100*eps)
+ at end group
+ at end example
+
+Assuming one of the two versions is in @var{xcorr_orig}, this
+would compare their speed and their output values.  Note that the
+FFT version is not exact, so we specify an acceptable tolerance on
+the comparison @code{100*eps}, and the errors should be computed
+relatively, as @code{abs((@var{x} - @var{y})./@var{y})} rather than 
+absolutely as @code{abs(@var{x} - @var{y})}.
+
+Type @code{example('speed')} to see some real examples.  Note for 
+obscure reasons, you can't run examples 1 and 2 directly using 
+ at code{demo('speed')}.  Instead use, @code{eval(example('speed',1))}
+and @code{eval(example('speed',2))}.
+ at end deftypefn
+
diff --git a/doc/interpreter/testfun.txi b/doc/interpreter/testfun.txi
new file mode 100644
index 0000000..dd8d312
--- /dev/null
+++ b/doc/interpreter/testfun.txi
@@ -0,0 +1,310 @@
+ at c Copyright (C) 2005, 2007, 2009 David Bateman
+ at c Copyright (C) 2002, 2003, 2004, 2005 Paul Kienzle
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Test and Demo Functions
+ at appendix Test and Demo Functions
+ at cindex test functions
+
+Octave includes a number of functions to allow the integration of testing
+and demonstration code in the source code of the functions themselves.
+
+ at menu
+* Test Functions::
+* Demonstration Functions::
+ at end menu
+
+ at node Test Functions
+ at section Test Functions
+
+ at DOCSTRING(test)
+
+ at code{test} scans the named script file looking for lines which
+start with @code{%!}.  The prefix is stripped off and the rest of the
+line is processed through the Octave interpreter.  If the code
+generates an error, then the test is said to fail.
+
+Since @code{eval()} will stop at the first error it encounters, you must
+divide your tests up into blocks, with anything in a separate
+block evaluated separately.  Blocks are introduced by the keyword
+ at code{test} immediately following the @code{%!}.  For example,
+
+ at example
+ at group
+   %!test error ("this test fails!");
+   %!test "test doesn't fail. it doesn't generate an error";
+ at end group
+ at end example
+
+When a test fails, you will see something like:
+
+ at example
+ at group
+     ***** test error ('this test fails!')
+   !!!!! test failed
+   this test fails!
+ at end group
+ at end example
+
+Generally, to test if something works, you want to assert that it
+produces a correct value.  A real test might look something like
+
+ at example
+ at group
+   %!test
+   %! @var{a} = [1, 2, 3; 4, 5, 6]; B = [1; 2];
+   %! expect = [ @var{a} ; 2*@var{a} ];
+   %! get = kron (@var{b}, @var{a});
+   %! if (any(size(expect) != size(get)))
+   %!    error ("wrong size: expected %d,%d but got %d,%d",
+   %!           size(expect), size(get));
+   %! elseif (any(any(expect!=get)))
+   %!    error ("didn't get what was expected.");
+   %! endif
+ at end group
+ at end example
+
+To make the process easier, use the @code{assert} function.  For example,
+with @code{assert} the previous test is reduced to:
+
+ at example
+ at group
+   %!test
+   %! @var{a} = [1, 2, 3; 4, 5, 6]; @var{b} = [1; 2];
+   %! assert (kron (@var{b}, @var{a}), [ @var{a}; 2*@var{a} ]);
+ at end group
+ at end example
+
+ at code{assert} can accept a tolerance so that you can compare results
+absolutely or relatively.  For example, the following all succeed:
+
+ at example
+ at group
+   %!test assert (1+eps, 1, 2*eps)          # absolute error
+   %!test assert (100+100*eps, 100, -2*eps) # relative error
+ at end group
+ at end example
+
+You can also do the comparison yourself, but still have assert
+generate the error:
+
+ at example
+ at group
+   %!test assert (isempty([]))
+   %!test assert ([ 1,2; 3,4 ] > 0)
+ at end group
+ at end example
+
+Because @code{assert} is so frequently used alone in a test block, there
+is a shorthand form:
+
+ at example
+   %!assert (@dots{})
+ at end example
+
+which is equivalent to:
+
+ at example
+   %!test assert (@dots{})
+ at end example
+
+Sometimes during development there is a test that should work but is
+known to fail.  You still want to leave the test in because when the
+final code is ready the test should pass, but you may not be able to
+fix it immediately.  To avoid unnecessary bug reports for these known
+failures, mark the block with @code{xtest} rather than @code{test}:
+
+ at example
+ at group
+   %!xtest assert (1==0)
+   %!xtest fail ('success=1','error'))
+ at end group
+ at end example
+
+Another use of @code{xtest} is for statistical tests which should
+pass most of the time but are known to fail occasionally.
+
+Each block is evaluated in its own function environment, which means
+that variables defined in one block are not automatically shared
+with other blocks.  If you do want to share variables, then you
+must declare them as @code{shared} before you use them.  For example, the
+following declares the variable @var{a}, gives it an initial value (default
+is empty), then uses it in several subsequent tests.
+
+ at example
+ at group
+   %!shared @var{a}
+   %! @var{a} = [1, 2, 3; 4, 5, 6];
+   %!assert (kron ([1; 2], @var{a}), [ @var{a}; 2*@var{a} ]);
+   %!assert (kron ([1, 2], @var{a}), [ @var{a}, 2*@var{a} ]);
+   %!assert (kron ([1,2; 3,4], @var{a}), [ @var{a},2*@var{a}; 3*@var{a},4*@var{a} ]);
+ at end group
+ at end example
+
+You can share several variables at the same time:
+
+ at example
+   %!shared @var{a}, @var{b}
+ at end example
+
+You can also share test functions:
+
+ at example
+ at group
+   %!function @var{a} = fn(@var{b})
+   %!  @var{a} = 2*@var{b};
+   %!assert (@var{a}(2),4);
+ at end group
+ at end example
+
+Note that all previous variables and values are lost when a new 
+shared block is declared.
+
+Error and warning blocks are like test blocks, but they only succeed 
+if the code generates an error.  You can check the text of the error
+is correct using an optional regular expression @code{<pattern>}.  
+For example:
+
+ at example
+   %!error <passes!> error('this test passes!');
+ at end example
+
+If the code doesn't generate an error, the test fails.  For example,
+
+ at example
+   %!error "this is an error because it succeeds.";
+ at end example
+
+produces
+
+ at example
+ at group
+   ***** error "this is an error because it succeeds.";
+   !!!!! test failed: no error
+ at end group
+ at end example
+
+It is important to automate the tests as much as possible, however
+some tests require user interaction.  These can be isolated into
+demo blocks, which if you are in batch mode, are only run when 
+called with @code{demo} or @code{verbose}.  The code is displayed before
+it is executed.  For example,
+
+ at example
+ at group
+   %!demo
+   %! @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t});
+   %! plot(@var{t}, at var{x});
+   %! you should now see a sine wave in your figure window
+ at end group
+ at end example
+
+produces
+
+ at example
+ at group
+   > @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t});
+   > plot(@var{t}, at var{x});
+   > you should now see a sine wave in your figure window
+   Press <enter> to continue: 
+ at end group
+ at end example
+
+Note that demo blocks cannot use any shared variables.  This is so
+that they can be executed by themselves, ignoring all other tests.
+
+If you want to temporarily disable a test block, put @code{#} in place
+of the block type.  This creates a comment block which is echoed
+in the log file, but is not executed.  For example:
+
+ at example
+ at group
+   %!#demo
+   %! @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t});
+   %! plot(@var{t}, at var{x});
+   %! you should now see a sine wave in your figure window
+ at end group
+ at end example
+
+Block type summary:
+
+ at table @code
+ at item %!test
+check that entire block is correct
+ at item %!error
+check for correct error message
+ at item %!warning
+check for correct warning message
+ at item %!demo
+demo only executes in interactive mode
+ at item %!#
+comment: ignore everything within the block
+ at item %!shared x,y,z
+declares variables for use in multiple tests
+ at item %!function
+defines a function value for a shared variable
+ at item %!assert (x, y, tol)
+shorthand for %!test assert (x, y, tol)
+ at end table
+
+You can also create test scripts for builtins and your own C++
+functions.  Just put a file of the function name on your path without
+any extension and it will be picked up by the test procedure.  You
+can even embed tests directly in your C++ code:
+
+ at example
+ at group
+   #if 0
+   %!test disp('this is a test')
+   #endif
+ at end group
+ at end example
+
+or
+
+ at example
+ at group
+   /*
+   %!test disp('this is a test')
+   */
+ at end group
+ at end example
+
+but then the code will have to be on the load path and the user 
+will have to remember to type test('name.cc').  Conversely, you
+can separate the tests from normal Octave script files by putting
+them in plain files with no extension rather than in script files.
+ at c DO I WANT TO INCLUDE THE EDITOR SPECIFIC STATEMENT BELOW???
+ at c Don't forget to tell emacs that the plain text file you are using
+ at c is actually octave code, using something like:
+ at c   -*-octave-*-
+
+ at DOCSTRING(assert)
+
+ at DOCSTRING(fail)
+
+ at node Demonstration Functions
+ at section Demonstration Functions
+
+ at DOCSTRING(demo)
+
+ at DOCSTRING(rundemos)
+
+ at DOCSTRING(example)
+
+ at DOCSTRING(speed)
diff --git a/doc/interpreter/tips.texi b/doc/interpreter/tips.texi
new file mode 100644
index 0000000..46d0f4f
--- /dev/null
+++ b/doc/interpreter/tips.texi
@@ -0,0 +1,724 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2002, 2004, 2005, 2007, 2008,
+ at c               2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Tips and Standards
+ at appendix Tips and Standards
+ at cindex tips
+ at cindex standards of coding style
+ at cindex coding standards
+
+This chapter describes no additional features of Octave.  Instead it
+gives advice on making effective use of the features described in the
+previous chapters.
+
+ at menu
+* Style Tips::                  Writing clean and robust programs.
+* Coding Tips::                 Making code run faster.
+* Comment Tips::                Conventions for writing comments.
+* Function Headers::            Standard headers for functions.
+* Documentation Tips::          Writing readable documentation strings.
+ at end menu
+
+ at node Style Tips
+ at section Writing Clean Octave Programs
+
+Here are some tips for avoiding common errors in writing Octave code
+intended for widespread use:
+
+ at itemize @bullet
+ at item
+Since all global variables share the same name space, and all functions
+share another name space, you should choose a short word to distinguish
+your program from other Octave programs.  Then take care to begin the
+names of all global variables, constants, and functions with the chosen
+prefix.  This helps avoid name conflicts.
+
+If you write a function that you think ought to be added to Octave under
+a certain name, such as @code{fiddle_matrix}, don't call it by that name
+in your program.  Call it @code{mylib_fiddle_matrix} in your program,
+and send mail to @email{maintainers@@octave.org} suggesting that it
+be added to Octave.  If and when it is, the name can be changed easily
+enough.
+
+If one prefix is insufficient, your package may use two or three
+alternative common prefixes, so long as they make sense.
+
+Separate the prefix from the rest of the symbol name with an underscore
+ at samp{_}.  This will be consistent with Octave itself and with most
+Octave programs.
+
+ at item
+When you encounter an error condition, call the function @code{error}
+(or @code{usage}).  The @code{error} and @code{usage} functions do not
+return.
+ at xref{Errors}.
+
+ at item
+Please put a copyright notice on the file if you give copies to anyone.
+Use the same lines that appear at the top of the function files
+distributed with Octave.  If you have not signed papers to assign the
+copyright to anyone else, then place your name in the copyright notice.
+ at end itemize
+
+ at node Coding Tips
+ at section Tips for Making Code Run Faster.
+ at cindex execution speed
+ at cindex speedups
+
+Here are some ways of improving the execution speed of Octave programs.
+
+ at itemize @bullet
+ at item
+Vectorize loops. For instance, rather than
+ at example
+for i = 1:n-1
+  a(i) = b(i+1) - b(i);
+endfor
+ at end example
+
+write
+
+ at example
+a = b(2:n) - b(1:n-1);
+ at end example
+
+This is especially important for loops with "cheap" bodies. Often it suffices to vectorize
+just the innermost loop to get acceptable performance. A general rule of thumb is that the
+"order" of the vectorized body should be greater or equal to the "order" of the enclosing loop.
+
+ at item
+Use built-in and library functions if possible. Built-in and compiled functions are very fast.
+Even with a m-file library function, chances are good that it is already optimized, or will be
+optimized more in a future release.
+
+ at item
+Avoid computing costly intermediate results multiple times. Octave currently
+does not eliminate common subexpressions.
+
+ at item
+Be aware of lazy copies (copy-on-write). When a copy of an object
+is created, the data is not immediately copied, but rather shared. The actual
+copying is postponed until the copied data needs to be modified. For example:
+
+ at example
+a = zeros (1000); # create a 1000x1000 matrix
+b = a; # no copying done here
+b(1) = 1; # copying done here
+ at end example
+
+Lazy copying applies to whole Octave objects such as matrices, cells, struct,
+and also individual cell or struct elements (not array elements).
+
+Additionally, index expressions also use lazy copying when Octave can determine
+that the indexed portion is contiguous in memory. For example:
+
+ at example
+a = zeros (1000); # create a 1000x1000 matrix
+b = a(:,10:100); # no copying done here
+b = a(10:100,:); # copying done here
+ at end example
+
+This applies to arrays (matrices), cell arrays, and structs indexed using ().
+Index expressions generating cs-lists can also benefit of shallow copying
+in some cases. In particular, when @var{a} is a struct array, expressions like
+ at code{@{a.x@}, @{a(:,2).x@}} will use lazy copying, so that data can be shared
+between a struct array and a cell array.
+
+Most indexing expressions do not live longer than their `parent' objects.
+In rare cases, however, a lazily copied slice outlasts its parent, in which
+case it becomes orphaned, still occupying unnecessarily more memory than needed.
+To provide a remedy working in most real cases,
+Octave checks for orphaned lazy slices at certain situations, when a value
+is stored into a "permanent" location, such as a named variable or cell or
+struct element, and possibly economizes them. For example
+
+ at example
+a = zeros (1000); # create a 1000x1000 matrix
+b = a(:,10:100); # lazy slice
+a = []; # the original a array is still allocated
+c@{1@} = b; # b is reallocated at this point
+ at end example
+
+ at item
+Avoid deep recursion. Function calls to m-file functions carry a relatively significant overhead,
+so rewriting a recursion as a loop often helps. Also, note that the maximum level of recursion is
+limited.
+
+ at item
+Avoid resizing matrices unnecessarily. When building a single result
+matrix from a series of calculations, set the size of the result matrix
+first, then insert values into it.  Write
+
+ at example
+ at group
+result = zeros (big_n, big_m)
+for i = over:and_over
+  r1 = @dots{}
+  r2 = @dots{}
+  result (r1, r2) = new_value ();
+endfor
+ at end group
+ at end example
+
+ at noindent
+instead of
+
+ at example
+ at group
+result = [];
+for i = ever:and_ever
+  result = [ result, new_value() ];
+endfor
+ at end group
+ at end example
+
+Sometimes the number of items can't be computed in advance, and stack-like operations
+are needed. When elements are being repeatedly inserted at/removed from the end of an
+array, Octave detects it as stack usage and attempts to use a smarter memory management
+strategy preallocating the array in bigger chunks. Likewise works for cell and
+struct arrays.
+
+ at example
+a = [];
+while (condition)
+  @dots{}
+  a(end+1) = value; # "push" operation
+  @dots{}
+  a(end) = []; # "pop" operation
+  @dots{}
+endwhile
+ at end example
+
+ at item
+Use @code{cellfun} intelligently. The @code{cellfun} function is a useful tool
+for avoiding loops. @xref{Processing Data in Cell Arrays}.
+ at code{cellfun} is often use with anonymous function handles; however, calling
+an anonymous function involves an overhead quite comparable to the overhead
+of an m-file function. Passing a handle to a built-in function is faster,
+because the interpreter is not involved in the internal loop. For example:
+
+ at example
+a = @{@dots{}@}
+v = cellfun (@@(x) det(x), a); # compute determinants
+v = cellfun (@@det, a); # faster
+ at end example
+
+ at item
+Avoid calling @code{eval} or @code{feval} excessively, because
+they require Octave to parse input or look up the name of a function in
+the symbol table.
+
+If you are using @code{eval} as an exception handling mechanism and not
+because you need to execute some arbitrary text, use the @code{try}
+statement instead.  @xref{The @code{try} Statement}.
+
+ at item
+If you are calling lots of functions but none of them will need to
+change during your run, set the variable
+ at code{ignore_function_time_stamp} to @code{"all"} so that Octave doesn't
+waste a lot of time checking to see if you have updated your function
+files.
+ at end itemize
+
+ at node Comment Tips
+ at section Tips on Writing Comments
+
+Here are the conventions to follow when writing comments.
+
+ at table @samp
+ at item #
+Comments that start with a single sharp-sign, @samp{#}, should all be
+aligned to the same column on the right of the source code.  Such
+comments usually explain how the code on the same line does its job.  In
+the Emacs mode for Octave, the @kbd{M-;} (@code{indent-for-comment})
+command automatically inserts such a @samp{#} in the right place, or
+aligns such a comment if it is already present.
+
+ at item ##
+Comments that start with a double sharp-sign, @samp{##}, should be aligned to
+the same level of indentation as the code.  Such comments usually
+describe the purpose of the following lines or the state of the program
+at that point.
+ at end table
+
+ at noindent
+The indentation commands of the Octave mode in Emacs, such as @kbd{M-;}
+(@code{indent-for-comment}) and @kbd{TAB} (@code{octave-indent-line})
+automatically indent comments according to these conventions,
+depending on the number of semicolons.  @xref{Comments,,
+Manipulating Comments, emacs, The GNU Emacs Manual}.
+
+ at node Function Headers
+ at section Conventional Headers for Octave Functions
+ at cindex header comments
+
+Octave has conventions for using special comments in function files
+to give information such as who wrote them.  This section explains these
+conventions.
+
+The top of the file should contain a copyright notice, followed by a
+block of comments that can be used as the help text for the function.
+Here is an example:
+
+ at example
+## Copyright (C) 1996, 1997, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public
+## License as published by the Free Software Foundation;
+## either version 3 of the License, or (at your option) any 
+## later version.
+##
+## Octave is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied
+## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+## PURPOSE.  See the GNU General Public License for more
+## details.
+##
+## You should have received a copy of the GNU General Public
+## License along with Octave; see the file COPYING.  If not,
+## see <http://www.gnu.org/licenses/>.
+
+## usage: [IN, OUT, PID] = popen2 (COMMAND, ARGS)
+##
+## Start a subprocess with two-way communication.  COMMAND
+## specifies the name of the command to start.  ARGS is an
+## array of strings containing options for COMMAND.  IN and
+## OUT are the file ids of the input and streams for the
+## subprocess, and PID is the process id of the subprocess,
+## or -1 if COMMAND could not be executed.
+##
+## Example:
+##
+##  [in, out, pid] = popen2 ("sort", "-nr");
+##  fputs (in, "these\nare\nsome\nstrings\n");
+##  fclose (in);
+##  while (ischar (s = fgets (out)))
+##    fputs (stdout, s);
+##  endwhile
+##  fclose (out);
+ at end example
+
+Octave uses the first block of comments in a function file that do not
+appear to be a copyright notice as the help text for the file.  For
+Octave to recognize the first comment block as a copyright notice, it
+must start with the word `Copyright' after stripping the leading
+comment characters.
+
+After the copyright notice and help text come several @dfn{header
+comment} lines, each beginning with @samp{## @var{header-name}:}.  For
+example,
+
+ at example
+ at group
+## Author: jwe
+## Keywords: subprocesses input-output
+## Maintainer: jwe
+ at end group
+ at end example
+
+Here is a table of the conventional possibilities for @var{header-name}:
+
+ at table @samp
+ at item Author
+This line states the name and net address of at least the principal
+author of the library.
+
+ at example
+## Author: John W. Eaton <jwe@@octave.org>
+ at end example
+
+ at item Maintainer
+This line should contain a single name/address as in the Author line, or
+an address only, or the string @samp{jwe}.  If there is no maintainer
+line, the person(s) in the Author field are presumed to be the
+maintainers.  The example above is mildly bogus because the maintainer
+line is redundant.
+
+The idea behind the @samp{Author} and @samp{Maintainer} lines is to make
+possible a function to ``send mail to the maintainer'' without
+having to mine the name out by hand.
+
+Be sure to surround the network address with @samp{<@dots{}>} if
+you include the person's full name as well as the network address.
+
+ at item Created
+This optional line gives the original creation date of the
+file.  For historical interest only.
+
+ at item Version
+If you wish to record version numbers for the individual Octave program,
+put them in this line.
+
+ at item Adapted-By
+In this header line, place the name of the person who adapted the
+library for installation (to make it fit the style conventions, for
+example).
+
+ at item Keywords
+This line lists keywords.  Eventually, it will be used by an apropos
+command to allow people will find your package when they're looking for
+things by topic area.  To separate the keywords, you can use spaces,
+commas, or both.
+ at end table
+
+Just about every Octave function ought to have the @samp{Author} and
+ at samp{Keywords} header comment lines.  Use the others if they are
+appropriate.  You can also put in header lines with other header
+names---they have no standard meanings, so they can't do any harm.
+
+ at node Documentation Tips
+ at section Tips for Documentation Strings
+
+As noted above, documentation is typically in a commented header block
+on an Octave function following the copyright statement.  The help string
+shown above is an unformatted string and will be displayed as is by
+Octave.  Here are some tips for the writing of documentation strings.
+
+ at itemize @bullet
+ at item
+Every command, function, or variable intended for users to know about
+should have a documentation string.
+
+ at item
+An internal variable or subroutine of an Octave program might as well have
+a documentation string.
+
+ at item
+The first line of the documentation string should consist of one or two
+complete sentences that stand on their own as a summary.
+
+The documentation string can have additional lines that expand on the
+details of how to use the function or variable.  The additional lines
+should also be made up of complete sentences.
+
+ at item
+For consistency, phrase the verb in the first sentence of a
+documentation string as an infinitive with ``to'' omitted.  For
+instance, use ``Return the frob of A and B.'' in preference to ``Returns
+the frob of A and B at .''  Usually it looks good to do likewise for the
+rest of the first paragraph.  Subsequent paragraphs usually look better
+if they have proper subjects.
+
+ at item
+Write documentation strings in the active voice, not the passive, and in
+the present tense, not the future.  For instance, use ``Return a list
+containing A and B.'' instead of ``A list containing A and B will be
+returned.''
+
+ at item
+Avoid using the word ``cause'' (or its equivalents) unnecessarily.
+Instead of, ``Cause Octave to display text in boldface,'' write just
+``Display text in boldface.''
+
+ at item
+Do not start or end a documentation string with whitespace.
+
+ at item
+Format the documentation string so that it fits in an Emacs window on an
+80-column screen.  It is a good idea for most lines to be no wider than
+60 characters.
+
+However, rather than simply filling the entire documentation string, you
+can make it much more readable by choosing line breaks with care.
+Use blank lines between topics if the documentation string is long.
+ 
+ at item
+ at strong{Do not} indent subsequent lines of a documentation string so
+that the text is lined up in the source code with the text of the first
+line.  This looks nice in the source code, but looks bizarre when users
+view the documentation.  Remember that the indentation before the
+starting double-quote is not part of the string!
+
+ at item
+The documentation string for a variable that is a yes-or-no flag should
+start with words such as ``Nonzero means at dots{}'', to make it clear that
+all nonzero values are equivalent and indicate explicitly what zero and
+nonzero mean.
+
+ at item
+When a function's documentation string mentions the value of an argument
+of the function, use the argument name in capital letters as if it were
+a name for that value.  Thus, the documentation string of the operator
+ at code{/} refers to its second argument as @samp{DIVISOR}, because the
+actual argument name is @code{divisor}.
+
+Also use all caps for meta-syntactic variables, such as when you show
+the decomposition of a list or vector into subunits, some of which may
+vary.
+ at end itemize
+
+Octave also allows extensive formatting of the help string of functions
+using Texinfo.  The effect on the online documentation is relatively
+small, but makes the help string of functions conform to the help of
+Octave's own functions.  However, the effect on the appearance of printed
+or online documentation will be greatly improved.
+
+The fundamental building block of Texinfo documentation strings is the
+Texinfo-macro @code{@@deftypefn}, which takes three arguments: The class
+the function is in, its output arguments, and the function's
+signature.  Typical classes for functions include @code{Function File}
+for standard Octave functions, and @code{Loadable Function} for
+dynamically linked functions.  A skeletal Texinfo documentation string
+therefore looks like this
+
+ at example
+ at group
+-*- texinfo -*-
+@@deftypefn@{Function File@} @{@@var@{ret@} =@} fn (@dots{})
+@@cindex index term
+Help text in Texinfo format.  Code samples should be marked 
+like @@code@{sample of code@} and variables should be marked
+as @@var@{variable@}.
+@@seealso@{fn2@}
+@@end deftypefn
+ at end group
+ at end example
+
+This help string must be commented in user functions, or in the help
+string of the @w{@code{DEFUN_DLD}} macro for dynamically loadable
+functions.  The important aspects of the documentation string are
+
+ at table @asis
+ at item -*- texinfo -*-
+This string signals Octave that the following text is in Texinfo format,
+and should be the first part of any help string in Texinfo format.
+ at item @@deftypefn@{class@} @dots{} @@end deftypefn
+The entire help string should be enclosed within the block defined by
+deftypefn.
+ at item @@cindex index term
+This generates an index entry, and can be useful when the function is
+included as part of a larger piece of documentation.  It is ignored
+within Octave's help viewer.  Only one index term may appear per line
+but multiple @@cindex lines are valid if the function should be 
+filed under different terms.
+ at item @@var@{variable@}
+All variables should be marked with this macro.  The markup of variables
+is then changed appropriately for display.
+ at item @@code@{sample of code@}
+All samples of code should be marked with this macro for the same
+reasons as the @@var macro.
+ at item @@seealso@{function2@}
+This is a comma separated list of function names that allows cross
+referencing from one function documentation string to another.
+ at end table
+
+Texinfo format has been designed to generate output for online viewing
+with text terminals as well as generating high-quality printed output.
+To these ends, Texinfo has commands which control the diversion of parts
+of the document into a particular output processor.  Three formats are
+of importance: info, html and @TeX{}.  These are selected with
+
+ at example
+ at group
+@@ifinfo
+Text area for info only
+@@end ifinfo
+ at end group
+ at end example
+
+ at example
+ at group
+@@ifhtml
+Text area for HTML only
+@@end ifhtml
+ at end group
+ at end example
+
+ at example
+ at group
+@@tex
+Text area for TeX only
+@@end tex
+ at end group
+ at end example
+
+Note that often @TeX{} output can be used in html documents and so often
+the @code{@@ifhtml} blocks are unnecessary.  If no specific output
+processor is chosen, by default, the text goes into all output
+processors.  It is usual to have the above blocks in pairs to allow the
+same information to be conveyed in all output formats, but with a
+different markup.  Currently, most Octave documentation only makes a
+distinction between @TeX{} and all other formats.  Therefore, the
+following construct is seen repeatedly.
+
+ at example
+ at group
+@@tex
+text for TeX only
+@@end tex
+@@ifnottex
+text for info, HTML, plaintext
+@@end ifnottex
+ at end group
+ at end example
+
+Another important feature of Texinfo that is often used in Octave help
+strings is the @code{@@example} environment.  An example of its use is
+
+ at example
+ at group
+@@example
+@@group
+@@code@{2 * 2@}
+@@result@{@} 4
+@@end group
+@@end example
+ at end group
+ at end example
+
+which produces
+
+ at example
+ at group
+ at code{2 * 2}
+ at result{} 4
+ at end group
+ at end example
+
+The @code{@@group} block prevents the example from being split across a
+page boundary, while the @code{@@result@{@}} macro produces a right
+arrow signifying the result of a command.  If your example is larger than
+20 lines it is better NOT to use grouping so that a reasonable page boundary
+can be calculated.
+
+In many cases a function has multiple ways in which it can be called,
+and the @code{@@deftypefnx} macro can be used to give alternatives.  For
+example
+
+ at example
+ at group
+-*- texinfo -*-
+@@deftypefn@{Function File@} @{@@var@{a@} =@} fn (@@var@{x@}, @dots{})
+@@deftypefnx@{Function File@} @{@@var@{a@} =@} fn (@@var@{y@}, @dots{})
+Help text in Texinfo format.
+@@end deftypefn
+ at end group
+ at end example
+
+Many complete examples of Texinfo documentation can be taken from the
+help strings for the Octave functions themselves.  A relatively complete
+example of which is the @code{nchoosek} function.  The Texinfo
+documentation string for @code{nchoosek} is
+
+ at example
+-*- texinfo -*-
+@@deftypefn @{Function File@} @{@} nchoosek (@@var@{n@}, @@var@{k@})
+
+Compute the binomial coefficient or all combinations of 
+@@var@{n@}.  If @@var@{n@} is a scalar then, calculate the
+binomial coefficient of @@var@{n@} and @@var@{k@}, defined as
+
+@@tex
+$$
+ @{n \choose k@} = @{n (n-1) (n-2) \cdots (n-k+1) \over k!@}
+$$
+@@end tex
+@@ifnottex
+
+@@example
+@@group
+ /   \
+ | n |    n (n-1) (n-2) @dots{} (n-k+1)
+ |   |  = -------------------------
+ | k |               k!
+ \   /
+@@end group
+@@end example
+@@end ifnottex
+
+If @@var@{n@} is a vector, this generates all combinations
+of the elements of @@var@{n@}, taken @@var@{k@} at a time,
+one row per combination.  The resulting @@var@{c@} has size
+@@code@{[nchoosek (length (@@var@{n@}),@@var@{k@}), @@var@{k@}]@}.
+
+@@code@{nchoosek@} works only for non-negative integer arguments; use
+@@code@{bincoeff@} for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+@@seealso@{bincoeff@}
+@@end deftypefn
+ at end example
+
+which demonstrates most of the concepts discussed above.
+ at iftex
+This documentation string renders as
+
+ at c Note actually use the output of info below rather than try and 
+ at c reproduce it here to prevent it looking different than how it would
+ at c appear with info.
+ at example
+ at group
+ -- Function File: C = nchoosek (N, K)
+     Compute the binomial coefficient or all combinations
+     of N.  If N is a scalar then, calculate the binomial
+     coefficient of N and K, defined as
+
+           /   \
+           | n |    n (n-1) (n-2) @dots{} (n-k+1)       n!
+           |   |  = ------------------------- =  ---------
+           | k |               k!                k! (n-k)!
+           \   /
+
+     If N is a vector generate all combinations of the
+     elements of N, taken K at a time, one row per
+     combination.  The resulting C has size `[nchoosek
+     (length (N), K), K]'.
+
+     `nchoosek' works only for non-negative integer
+     arguments; use `bincoeff' for non-integer scalar 
+     arguments and for using vector arguments to compute
+     many coefficients at once.
+
+     See also: bincoeff.
+ at end group
+ at end example
+
+using info, whereas in a printed documentation using @TeX{} it will appear
+as
+
+ at deftypefn {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
+
+Compute the binomial coefficient or all combinations of @var{n}.
+If @var{n} is a scalar then, calculate the binomial coefficient
+of @var{n} and @var{k}, defined as
+
+ at tex
+$$
+ {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+$$
+ at end tex
+
+If @var{n} is a vector generate all combinations of the elements
+of @var{n}, taken @var{k} at a time, one row per combination.  The 
+resulting @var{c} has size @code{[nchoosek (length (@var{n}), 
+ at var{k}), @var{k}]}.
+
+ at code{nchoosek} works only for non-negative integer arguments; use
+ at code{bincoeff} for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+ at seealso{bincoeff}
+ at end deftypefn
+
+ at end iftex
diff --git a/doc/interpreter/tips.txi b/doc/interpreter/tips.txi
new file mode 100644
index 0000000..e4495d4
--- /dev/null
+++ b/doc/interpreter/tips.txi
@@ -0,0 +1,722 @@
+ at c Copyright (C) 1996, 1997, 1999, 2002, 2004, 2005, 2007, 2008,
+ at c               2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Tips and Standards
+ at appendix Tips and Standards
+ at cindex tips
+ at cindex standards of coding style
+ at cindex coding standards
+
+This chapter describes no additional features of Octave.  Instead it
+gives advice on making effective use of the features described in the
+previous chapters.
+
+ at menu
+* Style Tips::                  Writing clean and robust programs.
+* Coding Tips::                 Making code run faster.
+* Comment Tips::                Conventions for writing comments.
+* Function Headers::            Standard headers for functions.
+* Documentation Tips::          Writing readable documentation strings.
+ at end menu
+
+ at node Style Tips
+ at section Writing Clean Octave Programs
+
+Here are some tips for avoiding common errors in writing Octave code
+intended for widespread use:
+
+ at itemize @bullet
+ at item
+Since all global variables share the same name space, and all functions
+share another name space, you should choose a short word to distinguish
+your program from other Octave programs.  Then take care to begin the
+names of all global variables, constants, and functions with the chosen
+prefix.  This helps avoid name conflicts.
+
+If you write a function that you think ought to be added to Octave under
+a certain name, such as @code{fiddle_matrix}, don't call it by that name
+in your program.  Call it @code{mylib_fiddle_matrix} in your program,
+and send mail to @email{maintainers@@octave.org} suggesting that it
+be added to Octave.  If and when it is, the name can be changed easily
+enough.
+
+If one prefix is insufficient, your package may use two or three
+alternative common prefixes, so long as they make sense.
+
+Separate the prefix from the rest of the symbol name with an underscore
+ at samp{_}.  This will be consistent with Octave itself and with most
+Octave programs.
+
+ at item
+When you encounter an error condition, call the function @code{error}
+(or @code{usage}).  The @code{error} and @code{usage} functions do not
+return.
+ at xref{Errors}.
+
+ at item
+Please put a copyright notice on the file if you give copies to anyone.
+Use the same lines that appear at the top of the function files
+distributed with Octave.  If you have not signed papers to assign the
+copyright to anyone else, then place your name in the copyright notice.
+ at end itemize
+
+ at node Coding Tips
+ at section Tips for Making Code Run Faster.
+ at cindex execution speed
+ at cindex speedups
+
+Here are some ways of improving the execution speed of Octave programs.
+
+ at itemize @bullet
+ at item
+Vectorize loops. For instance, rather than
+ at example
+for i = 1:n-1
+  a(i) = b(i+1) - b(i);
+endfor
+ at end example
+
+write
+
+ at example
+a = b(2:n) - b(1:n-1);
+ at end example
+
+This is especially important for loops with "cheap" bodies. Often it suffices to vectorize
+just the innermost loop to get acceptable performance. A general rule of thumb is that the
+"order" of the vectorized body should be greater or equal to the "order" of the enclosing loop.
+
+ at item
+Use built-in and library functions if possible. Built-in and compiled functions are very fast.
+Even with a m-file library function, chances are good that it is already optimized, or will be
+optimized more in a future release.
+
+ at item
+Avoid computing costly intermediate results multiple times. Octave currently
+does not eliminate common subexpressions.
+
+ at item
+Be aware of lazy copies (copy-on-write). When a copy of an object
+is created, the data is not immediately copied, but rather shared. The actual
+copying is postponed until the copied data needs to be modified. For example:
+
+ at example
+a = zeros (1000); # create a 1000x1000 matrix
+b = a; # no copying done here
+b(1) = 1; # copying done here
+ at end example
+
+Lazy copying applies to whole Octave objects such as matrices, cells, struct,
+and also individual cell or struct elements (not array elements).
+
+Additionally, index expressions also use lazy copying when Octave can determine
+that the indexed portion is contiguous in memory. For example:
+
+ at example
+a = zeros (1000); # create a 1000x1000 matrix
+b = a(:,10:100); # no copying done here
+b = a(10:100,:); # copying done here
+ at end example
+
+This applies to arrays (matrices), cell arrays, and structs indexed using ().
+Index expressions generating cs-lists can also benefit of shallow copying
+in some cases. In particular, when @var{a} is a struct array, expressions like
+ at code{@{a.x@}, @{a(:,2).x@}} will use lazy copying, so that data can be shared
+between a struct array and a cell array.
+
+Most indexing expressions do not live longer than their `parent' objects.
+In rare cases, however, a lazily copied slice outlasts its parent, in which
+case it becomes orphaned, still occupying unnecessarily more memory than needed.
+To provide a remedy working in most real cases,
+Octave checks for orphaned lazy slices at certain situations, when a value
+is stored into a "permanent" location, such as a named variable or cell or
+struct element, and possibly economizes them. For example
+
+ at example
+a = zeros (1000); # create a 1000x1000 matrix
+b = a(:,10:100); # lazy slice
+a = []; # the original a array is still allocated
+c@{1@} = b; # b is reallocated at this point
+ at end example
+
+ at item
+Avoid deep recursion. Function calls to m-file functions carry a relatively significant overhead,
+so rewriting a recursion as a loop often helps. Also, note that the maximum level of recursion is
+limited.
+
+ at item
+Avoid resizing matrices unnecessarily. When building a single result
+matrix from a series of calculations, set the size of the result matrix
+first, then insert values into it.  Write
+
+ at example
+ at group
+result = zeros (big_n, big_m)
+for i = over:and_over
+  r1 = @dots{}
+  r2 = @dots{}
+  result (r1, r2) = new_value ();
+endfor
+ at end group
+ at end example
+
+ at noindent
+instead of
+
+ at example
+ at group
+result = [];
+for i = ever:and_ever
+  result = [ result, new_value() ];
+endfor
+ at end group
+ at end example
+
+Sometimes the number of items can't be computed in advance, and stack-like operations
+are needed. When elements are being repeatedly inserted at/removed from the end of an
+array, Octave detects it as stack usage and attempts to use a smarter memory management
+strategy preallocating the array in bigger chunks. Likewise works for cell and
+struct arrays.
+
+ at example
+a = [];
+while (condition)
+  @dots{}
+  a(end+1) = value; # "push" operation
+  @dots{}
+  a(end) = []; # "pop" operation
+  @dots{}
+endwhile
+ at end example
+
+ at item
+Use @code{cellfun} intelligently. The @code{cellfun} function is a useful tool
+for avoiding loops. @xref{Processing Data in Cell Arrays}.
+ at code{cellfun} is often use with anonymous function handles; however, calling
+an anonymous function involves an overhead quite comparable to the overhead
+of an m-file function. Passing a handle to a built-in function is faster,
+because the interpreter is not involved in the internal loop. For example:
+
+ at example
+a = @{@dots{}@}
+v = cellfun (@@(x) det(x), a); # compute determinants
+v = cellfun (@@det, a); # faster
+ at end example
+
+ at item
+Avoid calling @code{eval} or @code{feval} excessively, because
+they require Octave to parse input or look up the name of a function in
+the symbol table.
+
+If you are using @code{eval} as an exception handling mechanism and not
+because you need to execute some arbitrary text, use the @code{try}
+statement instead.  @xref{The @code{try} Statement}.
+
+ at item
+If you are calling lots of functions but none of them will need to
+change during your run, set the variable
+ at code{ignore_function_time_stamp} to @code{"all"} so that Octave doesn't
+waste a lot of time checking to see if you have updated your function
+files.
+ at end itemize
+
+ at node Comment Tips
+ at section Tips on Writing Comments
+
+Here are the conventions to follow when writing comments.
+
+ at table @samp
+ at item #
+Comments that start with a single sharp-sign, @samp{#}, should all be
+aligned to the same column on the right of the source code.  Such
+comments usually explain how the code on the same line does its job.  In
+the Emacs mode for Octave, the @kbd{M-;} (@code{indent-for-comment})
+command automatically inserts such a @samp{#} in the right place, or
+aligns such a comment if it is already present.
+
+ at item ##
+Comments that start with a double sharp-sign, @samp{##}, should be aligned to
+the same level of indentation as the code.  Such comments usually
+describe the purpose of the following lines or the state of the program
+at that point.
+ at end table
+
+ at noindent
+The indentation commands of the Octave mode in Emacs, such as @kbd{M-;}
+(@code{indent-for-comment}) and @kbd{TAB} (@code{octave-indent-line})
+automatically indent comments according to these conventions,
+depending on the number of semicolons.  @xref{Comments,,
+Manipulating Comments, emacs, The GNU Emacs Manual}.
+
+ at node Function Headers
+ at section Conventional Headers for Octave Functions
+ at cindex header comments
+
+Octave has conventions for using special comments in function files
+to give information such as who wrote them.  This section explains these
+conventions.
+
+The top of the file should contain a copyright notice, followed by a
+block of comments that can be used as the help text for the function.
+Here is an example:
+
+ at example
+## Copyright (C) 1996, 1997, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public
+## License as published by the Free Software Foundation;
+## either version 3 of the License, or (at your option) any 
+## later version.
+##
+## Octave is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied
+## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+## PURPOSE.  See the GNU General Public License for more
+## details.
+##
+## You should have received a copy of the GNU General Public
+## License along with Octave; see the file COPYING.  If not,
+## see <http://www.gnu.org/licenses/>.
+
+## usage: [IN, OUT, PID] = popen2 (COMMAND, ARGS)
+##
+## Start a subprocess with two-way communication.  COMMAND
+## specifies the name of the command to start.  ARGS is an
+## array of strings containing options for COMMAND.  IN and
+## OUT are the file ids of the input and streams for the
+## subprocess, and PID is the process id of the subprocess,
+## or -1 if COMMAND could not be executed.
+##
+## Example:
+##
+##  [in, out, pid] = popen2 ("sort", "-nr");
+##  fputs (in, "these\nare\nsome\nstrings\n");
+##  fclose (in);
+##  while (ischar (s = fgets (out)))
+##    fputs (stdout, s);
+##  endwhile
+##  fclose (out);
+ at end example
+
+Octave uses the first block of comments in a function file that do not
+appear to be a copyright notice as the help text for the file.  For
+Octave to recognize the first comment block as a copyright notice, it
+must start with the word `Copyright' after stripping the leading
+comment characters.
+
+After the copyright notice and help text come several @dfn{header
+comment} lines, each beginning with @samp{## @var{header-name}:}.  For
+example,
+
+ at example
+ at group
+## Author: jwe
+## Keywords: subprocesses input-output
+## Maintainer: jwe
+ at end group
+ at end example
+
+Here is a table of the conventional possibilities for @var{header-name}:
+
+ at table @samp
+ at item Author
+This line states the name and net address of at least the principal
+author of the library.
+
+ at example
+## Author: John W. Eaton <jwe@@octave.org>
+ at end example
+
+ at item Maintainer
+This line should contain a single name/address as in the Author line, or
+an address only, or the string @samp{jwe}.  If there is no maintainer
+line, the person(s) in the Author field are presumed to be the
+maintainers.  The example above is mildly bogus because the maintainer
+line is redundant.
+
+The idea behind the @samp{Author} and @samp{Maintainer} lines is to make
+possible a function to ``send mail to the maintainer'' without
+having to mine the name out by hand.
+
+Be sure to surround the network address with @samp{<@dots{}>} if
+you include the person's full name as well as the network address.
+
+ at item Created
+This optional line gives the original creation date of the
+file.  For historical interest only.
+
+ at item Version
+If you wish to record version numbers for the individual Octave program,
+put them in this line.
+
+ at item Adapted-By
+In this header line, place the name of the person who adapted the
+library for installation (to make it fit the style conventions, for
+example).
+
+ at item Keywords
+This line lists keywords.  Eventually, it will be used by an apropos
+command to allow people will find your package when they're looking for
+things by topic area.  To separate the keywords, you can use spaces,
+commas, or both.
+ at end table
+
+Just about every Octave function ought to have the @samp{Author} and
+ at samp{Keywords} header comment lines.  Use the others if they are
+appropriate.  You can also put in header lines with other header
+names---they have no standard meanings, so they can't do any harm.
+
+ at node Documentation Tips
+ at section Tips for Documentation Strings
+
+As noted above, documentation is typically in a commented header block
+on an Octave function following the copyright statement.  The help string
+shown above is an unformatted string and will be displayed as is by
+Octave.  Here are some tips for the writing of documentation strings.
+
+ at itemize @bullet
+ at item
+Every command, function, or variable intended for users to know about
+should have a documentation string.
+
+ at item
+An internal variable or subroutine of an Octave program might as well have
+a documentation string.
+
+ at item
+The first line of the documentation string should consist of one or two
+complete sentences that stand on their own as a summary.
+
+The documentation string can have additional lines that expand on the
+details of how to use the function or variable.  The additional lines
+should also be made up of complete sentences.
+
+ at item
+For consistency, phrase the verb in the first sentence of a
+documentation string as an infinitive with ``to'' omitted.  For
+instance, use ``Return the frob of A and B.'' in preference to ``Returns
+the frob of A and B at .''  Usually it looks good to do likewise for the
+rest of the first paragraph.  Subsequent paragraphs usually look better
+if they have proper subjects.
+
+ at item
+Write documentation strings in the active voice, not the passive, and in
+the present tense, not the future.  For instance, use ``Return a list
+containing A and B.'' instead of ``A list containing A and B will be
+returned.''
+
+ at item
+Avoid using the word ``cause'' (or its equivalents) unnecessarily.
+Instead of, ``Cause Octave to display text in boldface,'' write just
+``Display text in boldface.''
+
+ at item
+Do not start or end a documentation string with whitespace.
+
+ at item
+Format the documentation string so that it fits in an Emacs window on an
+80-column screen.  It is a good idea for most lines to be no wider than
+60 characters.
+
+However, rather than simply filling the entire documentation string, you
+can make it much more readable by choosing line breaks with care.
+Use blank lines between topics if the documentation string is long.
+ 
+ at item
+ at strong{Do not} indent subsequent lines of a documentation string so
+that the text is lined up in the source code with the text of the first
+line.  This looks nice in the source code, but looks bizarre when users
+view the documentation.  Remember that the indentation before the
+starting double-quote is not part of the string!
+
+ at item
+The documentation string for a variable that is a yes-or-no flag should
+start with words such as ``Nonzero means at dots{}'', to make it clear that
+all nonzero values are equivalent and indicate explicitly what zero and
+nonzero mean.
+
+ at item
+When a function's documentation string mentions the value of an argument
+of the function, use the argument name in capital letters as if it were
+a name for that value.  Thus, the documentation string of the operator
+ at code{/} refers to its second argument as @samp{DIVISOR}, because the
+actual argument name is @code{divisor}.
+
+Also use all caps for meta-syntactic variables, such as when you show
+the decomposition of a list or vector into subunits, some of which may
+vary.
+ at end itemize
+
+Octave also allows extensive formatting of the help string of functions
+using Texinfo.  The effect on the online documentation is relatively
+small, but makes the help string of functions conform to the help of
+Octave's own functions.  However, the effect on the appearance of printed
+or online documentation will be greatly improved.
+
+The fundamental building block of Texinfo documentation strings is the
+Texinfo-macro @code{@@deftypefn}, which takes three arguments: The class
+the function is in, its output arguments, and the function's
+signature.  Typical classes for functions include @code{Function File}
+for standard Octave functions, and @code{Loadable Function} for
+dynamically linked functions.  A skeletal Texinfo documentation string
+therefore looks like this
+
+ at example
+ at group
+-*- texinfo -*-
+@@deftypefn@{Function File@} @{@@var@{ret@} =@} fn (@dots{})
+@@cindex index term
+Help text in Texinfo format.  Code samples should be marked 
+like @@code@{sample of code@} and variables should be marked
+as @@var@{variable@}.
+@@seealso@{fn2@}
+@@end deftypefn
+ at end group
+ at end example
+
+This help string must be commented in user functions, or in the help
+string of the @w{@code{DEFUN_DLD}} macro for dynamically loadable
+functions.  The important aspects of the documentation string are
+
+ at table @asis
+ at item -*- texinfo -*-
+This string signals Octave that the following text is in Texinfo format,
+and should be the first part of any help string in Texinfo format.
+ at item @@deftypefn@{class@} @dots{} @@end deftypefn
+The entire help string should be enclosed within the block defined by
+deftypefn.
+ at item @@cindex index term
+This generates an index entry, and can be useful when the function is
+included as part of a larger piece of documentation.  It is ignored
+within Octave's help viewer.  Only one index term may appear per line
+but multiple @@cindex lines are valid if the function should be 
+filed under different terms.
+ at item @@var@{variable@}
+All variables should be marked with this macro.  The markup of variables
+is then changed appropriately for display.
+ at item @@code@{sample of code@}
+All samples of code should be marked with this macro for the same
+reasons as the @@var macro.
+ at item @@seealso@{function2@}
+This is a comma separated list of function names that allows cross
+referencing from one function documentation string to another.
+ at end table
+
+Texinfo format has been designed to generate output for online viewing
+with text terminals as well as generating high-quality printed output.
+To these ends, Texinfo has commands which control the diversion of parts
+of the document into a particular output processor.  Three formats are
+of importance: info, html and @TeX{}.  These are selected with
+
+ at example
+ at group
+@@ifinfo
+Text area for info only
+@@end ifinfo
+ at end group
+ at end example
+
+ at example
+ at group
+@@ifhtml
+Text area for HTML only
+@@end ifhtml
+ at end group
+ at end example
+
+ at example
+ at group
+@@tex
+Text area for TeX only
+@@end tex
+ at end group
+ at end example
+
+Note that often @TeX{} output can be used in html documents and so often
+the @code{@@ifhtml} blocks are unnecessary.  If no specific output
+processor is chosen, by default, the text goes into all output
+processors.  It is usual to have the above blocks in pairs to allow the
+same information to be conveyed in all output formats, but with a
+different markup.  Currently, most Octave documentation only makes a
+distinction between @TeX{} and all other formats.  Therefore, the
+following construct is seen repeatedly.
+
+ at example
+ at group
+@@tex
+text for TeX only
+@@end tex
+@@ifnottex
+text for info, HTML, plaintext
+@@end ifnottex
+ at end group
+ at end example
+
+Another important feature of Texinfo that is often used in Octave help
+strings is the @code{@@example} environment.  An example of its use is
+
+ at example
+ at group
+@@example
+@@group
+@@code@{2 * 2@}
+@@result@{@} 4
+@@end group
+@@end example
+ at end group
+ at end example
+
+which produces
+
+ at example
+ at group
+ at code{2 * 2}
+ at result{} 4
+ at end group
+ at end example
+
+The @code{@@group} block prevents the example from being split across a
+page boundary, while the @code{@@result@{@}} macro produces a right
+arrow signifying the result of a command.  If your example is larger than
+20 lines it is better NOT to use grouping so that a reasonable page boundary
+can be calculated.
+
+In many cases a function has multiple ways in which it can be called,
+and the @code{@@deftypefnx} macro can be used to give alternatives.  For
+example
+
+ at example
+ at group
+-*- texinfo -*-
+@@deftypefn@{Function File@} @{@@var@{a@} =@} fn (@@var@{x@}, @dots{})
+@@deftypefnx@{Function File@} @{@@var@{a@} =@} fn (@@var@{y@}, @dots{})
+Help text in Texinfo format.
+@@end deftypefn
+ at end group
+ at end example
+
+Many complete examples of Texinfo documentation can be taken from the
+help strings for the Octave functions themselves.  A relatively complete
+example of which is the @code{nchoosek} function.  The Texinfo
+documentation string for @code{nchoosek} is
+
+ at example
+-*- texinfo -*-
+@@deftypefn @{Function File@} @{@} nchoosek (@@var@{n@}, @@var@{k@})
+
+Compute the binomial coefficient or all combinations of 
+@@var@{n@}.  If @@var@{n@} is a scalar then, calculate the
+binomial coefficient of @@var@{n@} and @@var@{k@}, defined as
+
+@@tex
+$$
+ @{n \choose k@} = @{n (n-1) (n-2) \cdots (n-k+1) \over k!@}
+$$
+@@end tex
+@@ifnottex
+
+@@example
+@@group
+ /   \
+ | n |    n (n-1) (n-2) @dots{} (n-k+1)
+ |   |  = -------------------------
+ | k |               k!
+ \   /
+@@end group
+@@end example
+@@end ifnottex
+
+If @@var@{n@} is a vector, this generates all combinations
+of the elements of @@var@{n@}, taken @@var@{k@} at a time,
+one row per combination.  The resulting @@var@{c@} has size
+@@code@{[nchoosek (length (@@var@{n@}),@@var@{k@}), @@var@{k@}]@}.
+
+@@code@{nchoosek@} works only for non-negative integer arguments; use
+@@code@{bincoeff@} for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+@@seealso@{bincoeff@}
+@@end deftypefn
+ at end example
+
+which demonstrates most of the concepts discussed above.
+ at iftex
+This documentation string renders as
+
+ at c Note actually use the output of info below rather than try and 
+ at c reproduce it here to prevent it looking different than how it would
+ at c appear with info.
+ at example
+ at group
+ -- Function File: C = nchoosek (N, K)
+     Compute the binomial coefficient or all combinations
+     of N.  If N is a scalar then, calculate the binomial
+     coefficient of N and K, defined as
+
+           /   \
+           | n |    n (n-1) (n-2) @dots{} (n-k+1)       n!
+           |   |  = ------------------------- =  ---------
+           | k |               k!                k! (n-k)!
+           \   /
+
+     If N is a vector generate all combinations of the
+     elements of N, taken K at a time, one row per
+     combination.  The resulting C has size `[nchoosek
+     (length (N), K), K]'.
+
+     `nchoosek' works only for non-negative integer
+     arguments; use `bincoeff' for non-integer scalar 
+     arguments and for using vector arguments to compute
+     many coefficients at once.
+
+     See also: bincoeff.
+ at end group
+ at end example
+
+using info, whereas in a printed documentation using @TeX{} it will appear
+as
+
+ at deftypefn {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
+
+Compute the binomial coefficient or all combinations of @var{n}.
+If @var{n} is a scalar then, calculate the binomial coefficient
+of @var{n} and @var{k}, defined as
+
+ at tex
+$$
+ {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+$$
+ at end tex
+
+If @var{n} is a vector generate all combinations of the elements
+of @var{n}, taken @var{k} at a time, one row per combination.  The 
+resulting @var{c} has size @code{[nchoosek (length (@var{n}), 
+ at var{k}), @var{k}]}.
+
+ at code{nchoosek} works only for non-negative integer arguments; use
+ at code{bincoeff} for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+ at seealso{bincoeff}
+ at end deftypefn
+
+ at end iftex
diff --git a/doc/interpreter/triplot.eps b/doc/interpreter/triplot.eps
new file mode 100644
index 0000000..b3f940b
--- /dev/null
+++ b/doc/interpreter/triplot.eps
@@ -0,0 +1,792 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: triplot.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:47:01 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (triplot.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:47:01 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2335 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2335 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3742 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3742 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5148 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5148 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6555 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6555 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3259 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3259 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5043 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5043 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6828 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6828 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8612 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8612 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 8928 3601 M
+9945 7213 L
+405 -5006 V
+8928 3601 L
+10004 1181 M
+-73 -60 V
+419 1086 V
+10004 1181 L
+8041 7201 M
+4986 7953 L
+9945 7213 L
+8041 7201 L
+7925 5672 M
+8928 3601 L
+9945 7213 L
+7925 5672 L
+8928 3601 L
+7450 4626 L
+475 1046 V
+116 1529 V
+1904 12 V
+7925 5672 L
+2232 3168 M
+5317 4517 L
+2888 1890 L
+2232 3168 L
+5444 6094 M
+5317 4517 L
+2133 109 V
+5444 6094 L
+3868 7305 L
+1118 648 V
+5444 6094 L
+6881 2589 M
+7 -1493 V
+2888 1890 L
+3993 699 V
+8928 3601 L
+10350 2207 L
+6881 2589 L
+9931 1121 L
+419 1086 V
+6881 2589 L
+7 -1493 V
+3043 25 V
+6881 2589 L
+4224 4871 M
+2232 3168 L
+1979 4198 L
+2245 673 V
+2232 3168 L
+5317 4517 L
+4224 4871 L
+5444 6094 L
+5317 4517 L
+4224 4871 L
+3868 7305 L
+1979 4198 L
+2245 673 V
+5444 6094 L
+3868 7305 L
+4224 4871 L
+6330 6532 M
+7925 5672 L
+7450 4626 L
+6330 6532 L
+5444 6094 L
+7450 4626 L
+6330 6532 L
+7925 5672 L
+116 1529 V
+6330 6532 L
+1711 669 V
+4986 7953 L
+6330 6532 L
+5444 6094 L
+4986 7953 L
+6330 6532 L
+6660 3215 M
+5317 4517 L
+2888 1890 L
+6660 3215 L
+221 -626 V
+2888 1890 L
+6660 3215 L
+5317 4517 L
+2133 109 V
+6660 3215 L
+2268 386 V
+7450 4626 L
+6660 3215 L
+221 -626 V
+8928 3601 L
+6660 3215 L
+% End plot #1
+stroke
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/triplot.pdf b/doc/interpreter/triplot.pdf
new file mode 100644
index 0000000..c8439e6
Binary files /dev/null and b/doc/interpreter/triplot.pdf differ
diff --git a/doc/interpreter/triplot.png b/doc/interpreter/triplot.png
new file mode 100644
index 0000000..1a2ccf9
Binary files /dev/null and b/doc/interpreter/triplot.png differ
diff --git a/doc/interpreter/triplot.txt b/doc/interpreter/triplot.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/triplot.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/interpreter/var.texi b/doc/interpreter/var.texi
new file mode 100644
index 0000000..53b9b22
--- /dev/null
+++ b/doc/interpreter/var.texi
@@ -0,0 +1,759 @@
+ at c DO NOT EDIT!  Generated automatically by munge-texi.
+
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005,
+ at c               2006, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Variables
+ at chapter Variables
+ at cindex variables, user-defined
+ at cindex user-defined variables
+
+Variables let you give names to values and refer to them later.  You have
+already seen variables in many of the examples.  The name of a variable
+must be a sequence of letters, digits and underscores, but it may not begin
+with a digit.  Octave does not enforce a limit on the length of variable
+names, but it is seldom useful to have variables with names longer than
+about 30 characters.  The following are all valid variable names
+
+ at cindex job hunting
+ at cindex getting a good job
+ at cindex flying high and fast
+ at example
+ at group
+x
+x15
+__foo_bar_baz__
+fucnrdthsucngtagdjb
+ at end group
+ at end example
+
+ at noindent
+However, names like @code{__foo_bar_baz__} that begin and end with two
+underscores are understood to be reserved for internal use by Octave.
+You should not use them in code you write, except to access Octave's
+documented internal variables and built-in symbolic constants.
+
+Case is significant in variable names.  The symbols @code{a} and
+ at code{A} are distinct variables.
+
+A variable name is a valid expression by itself.  It represents the
+variable's current value.  Variables are given new values with
+ at dfn{assignment operators} and @dfn{increment operators}.
+ at xref{Assignment Ops, ,Assignment Expressions}.
+
+There is one built-in variable with a special meaning.  The @code{ans} variable
+always contains the result of the last computation, where the output wasn't
+assigned to any variable.  The code @code{a = cos (pi)} will assign the value -1
+to the variable @code{a}, but will not change the value of @code{ans}.  However,
+the code @code{cos (pi)} will set the value of @code{ans} to -1.
+
+Variables in Octave do not have fixed types, so it is possible to first
+store a numeric value in a variable and then to later use the same name
+to hold a string value in the same program.  Variables may not be used
+before they have been given a value.  Doing so results in an error.
+
+ at cindex @code{ans}
+ at c ./miscellaneous/ans.m
+ at anchor{doc-ans}
+ at defvr {Automatic Variable} ans
+The most recently computed result that was not
+explicitly assigned to a variable.  For example, after the expression
+
+ at example
+3^2 + 4^2
+ at end example
+
+ at noindent
+is evaluated, the value returned by @code{ans} is 25.
+ at end defvr
+
+
+ at c utils.cc
+ at anchor{doc-isvarname}
+ at deftypefn {Built-in Function} {} isvarname (@var{name})
+Return true if @var{name} is a valid variable name
+ at end deftypefn
+
+
+ at c ./general/genvarname.m
+ at anchor{doc-genvarname}
+ at deftypefn {Function File} {@var{varname} =} genvarname (@var{str})
+ at deftypefnx {Function File} {@var{varname} =} genvarname (@var{str}, @var{exclusions})
+Create unique variable(s) from @var{str}.  If @var{exclusions} is
+given, then the variable(s) will be unique to each other and to
+ at var{exclusions} (@var{exclusions} may be either a string or a cellstr).
+
+If @var{str} is a cellstr, then a unique variable is created for each
+cell in @var{str}.
+
+ at example
+ at group
+x = 3.141;
+genvarname ("x", who ())
+ at result{} x1
+ at end group
+ at end example
+
+If @var{wanted} is a cell array, genvarname will make sure the returned
+strings are distinct:
+
+ at example
+ at group
+genvarname (@{"foo", "foo"@})
+ at result{}
+@{
+  [1,1] = foo
+  [1,2] = foo1
+@}
+ at end group
+ at end example
+
+Note that the result is a char array/cell array of strings, not the
+variables themselves.  To define a variable, @code{eval()} can be
+used.  The following trivial example sets @code{x} to @code{42}.
+
+ at example
+ at group
+name = genvarname ("x");
+eval([name " = 42"]);
+ at result{} x =  42
+ at end group
+ at end example
+
+Also, this can be useful for creating unique struct field names.
+
+ at example
+ at group
+x = struct ();
+for i = 1:3
+  x.(genvarname ("a", fieldnames (x))) = i;
+endfor
+ at result{}
+x =
+@{
+  a =  1
+  a1 =  2
+  a2 =  3
+@}
+ at end group
+ at end example
+
+Since variable names may only contain letters, digits and underscores,
+genvarname replaces any sequence of disallowed characters with
+an underscore.  Also, variables may not begin with a digit; in this
+case an underscore is added before the variable name.
+
+Variable names beginning and ending with two underscores "__" are valid but
+they are used internally by octave and should generally be avoided, therefore
+genvarname will not generate such names.
+
+genvarname will also make sure that returned names do not clash with
+keywords such as "for" and "if".  A number will be appended if necessary.
+Note, however, that this does @strong{not} include function names,
+such as "sin".  Such names should be included in @var{avoid} if necessary.
+ at seealso{@ref{doc-isvarname,,isvarname}, @ref{doc-exist,,exist}, @ref{doc-tmpnam,,tmpnam}, @ref{doc-eval,,eval}}
+ at end deftypefn
+
+
+ at c ./miscellaneous/namelengthmax.m
+ at anchor{doc-namelengthmax}
+ at deftypefn {Function File} {} namelengthmax ()
+Returns the @sc{matlab} compatible maximum variable name length.  Octave is
+capable of storing strings up to 
+ at tex
+$2^{31} - 1$
+ at end tex
+ at ifnottex
+ at code{2 ^ 31 - 1}
+ at end ifnottex
+in length.  However for @sc{matlab} compatibility all variable, function
+and structure field names should be shorter than the length supplied by
+ at code{namelengthmax}.  In particular variables stored to a @sc{matlab} file
+format will have their names truncated to this length.
+ at end deftypefn
+
+
+ at menu
+* Global Variables::            
+* Persistent Variables::        
+* Status of Variables::         
+ at end menu
+
+ at node Global Variables
+ at section Global Variables
+ at cindex global variables
+ at cindex @code{global} statement
+ at cindex variables, global
+
+A variable that has been declared @dfn{global} may be accessed from
+within a function body without having to pass it as a formal parameter.
+
+A variable may be declared global using a @code{global} declaration
+statement.  The following statements are all global declarations.
+
+ at example
+ at group
+global a
+global a b
+global c = 2
+global d = 3 e f = 5
+ at end group
+ at end example
+
+A global variable may only be initialized once in a @code{global}
+statement.  For example, after executing the following code
+
+ at example
+ at group
+global gvar = 1
+global gvar = 2
+ at end group
+ at end example
+
+ at noindent
+the value of the global variable @code{gvar} is 1, not 2.  Issuing a
+ at samp{clear gvar} command does not change the above behavior, but
+ at samp{clear all} does.
+
+It is necessary declare a variable as global within a function body in
+order to access it.  For example,
+
+ at example
+ at group
+global x
+function f ()
+  x = 1;
+endfunction
+f ()
+ at end group
+ at end example
+
+ at noindent
+does @emph{not} set the value of the global variable @code{x} to 1.  In
+order to change the value of the global variable @code{x}, you must also
+declare it to be global within the function body, like this
+
+ at example
+ at group
+function f ()
+  global x;
+  x = 1;
+endfunction
+ at end group
+ at end example
+
+Passing a global variable in a function parameter list will
+make a local copy and not modify the global value.  For example, given
+the function
+
+ at example
+ at group
+function f (x)
+  x = 0
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and the definition of @code{x} as a global variable at the top level,
+
+ at example
+global x = 13
+ at end example
+
+ at noindent
+the expression
+
+ at example
+f (x)
+ at end example
+
+ at noindent
+will display the value of @code{x} from inside the function as 0,
+but the value of @code{x} at the top level remains unchanged, because
+the function works with a @emph{copy} of its argument.
+
+ at c variables.cc
+ at anchor{doc-isglobal}
+ at deftypefn {Built-in Function} {} isglobal (@var{name})
+Return 1 if @var{name} is globally visible.  Otherwise, return 0.  For
+example,
+
+ at example
+ at group
+global x
+isglobal ("x")
+     @result{} 1
+ at end group
+ at end example
+ at end deftypefn
+
+
+ at node Persistent Variables
+ at section Persistent Variables
+ at cindex persistent variables
+ at cindex @code{persistent} statement
+ at cindex variables, persistent
+ at anchor{doc-persistent}
+
+A variable that has been declared @dfn{persistent} within a function
+will retain its contents in memory between subsequent calls to the
+same function.  The difference between persistent variables and global
+variables is that persistent variables are local in scope to a
+particular function and are not visible elsewhere.
+
+The following example uses a persistent variable to create a function
+that prints the number of times it has been called.
+
+ at example
+ at group
+function count_calls ()
+  persistent calls = 0;
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+
+for i = 1:3
+  count_calls ();
+endfor
+
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+ at print{} 'count_calls' has been called 3 times
+ at end group
+ at end example
+
+As the example shows, a variable may be declared persistent using a
+ at code{persistent} declaration statement.  The following statements are
+all persistent declarations.
+
+ at example
+ at group
+persistent a
+persistent a b
+persistent c = 2
+persistent d = 3 e f = 5
+ at end group
+ at end example
+
+The behavior of persistent variables is equivalent to the behavior of
+static variables in C.  The command @code{static} in Octave is also
+recognized and is equivalent to @code{persistent}.
+
+Like global variables, a persistent variable may only be initialized once.
+For example, after executing the following code
+
+ at example
+ at group
+persistent pvar = 1
+persistent pvar = 2
+ at end group
+ at end example
+
+ at noindent
+the value of the persistent variable @code{pvar} is 1, not 2.
+
+If a persistent variable is declared but not initialized to a specific
+value, it will contain an empty matrix.  So, it is also possible to
+initialize a persistent variable by checking whether it is empty, as the
+following example illustrates.
+
+ at example
+ at group
+function count_calls ()
+  persistent calls;
+  if (isempty (calls))
+    calls = 0;
+  endif
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+This implementation behaves in exactly the same way as the previous
+implementation of @code{count_calls}.
+
+The value of a persistent variable is kept in memory until it is
+explicitly cleared.  Assuming that the implementation of @code{count_calls}
+is saved on disk, we get the following behavior.
+
+ at example
+for i = 1:2
+  count_calls ();
+endfor
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+
+clear
+for i = 1:2
+  count_calls();
+endfor
+ at print{} 'count_calls' has been called 3 times
+ at print{} 'count_calls' has been called 4 times
+
+clear all
+for i = 1:2
+  count_calls();
+endfor
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+
+clear count_calls
+for i = 1:2
+  count_calls();
+endfor
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+ at end example
+
+ at noindent
+That is, the persistent variable is only removed from memory when the
+function containing the variable is removed.  Note that if the function
+definition is typed directly into the Octave prompt, the persistent
+variable will be cleared by a simple @code{clear} command as the entire
+function definition will be removed from memory.  If you do not want
+a persistent variable to be removed from memory even if the function is
+cleared, you should use the @code{mlock} function as described in
+ at xref{Function Locking}.
+
+ at node Status of Variables
+ at section Status of Variables
+
+When creating simple one-shot programs it can be very convenient to
+see which variables are available at the prompt.  The function @code{who}
+and its siblings @code{whos} and @code{whos_line_format} will show
+different information about what is in memory, as the following shows.
+
+ at example
+ at group
+str = "A random string";
+who -variables
+     @print{} *** local user variables:
+     @print{} 
+     @print{} __nargin__  str
+ at end group
+ at end example
+
+ at c variables.cc
+ at anchor{doc-who}
+ at deffn  {Command} who
+ at deffnx {Command} who pattern @dots{}
+ at deffnx {Command} who option pattern @dots{}
+ at deffnx {Command} C = who("pattern", @dots{})
+List currently defined variables matching the given patterns.  Valid
+pattern syntax is the same as described for the @code{clear} command.
+If no patterns are supplied, all variables are listed.
+By default, only variables visible in the local scope are displayed.
+
+The following are valid options but may not be combined.
+
+ at table @code
+ at item global
+List variables in the global scope rather than the current scope.
+ at item -regexp
+The patterns are considered to be regular expressions when matching the
+variables to display.  The same pattern syntax accepted by
+the @code{regexp} function is used.
+ at item -file
+The next argument is treated as a filename.  All variables found within the
+specified file are listed.  No patterns are accepted when reading variables
+from a file.
+ at end table
+
+If called as a function, return a cell array of defined variable names
+matching the given patterns.
+ at seealso{@ref{doc-whos,,whos}, @ref{doc-regexp,,regexp}}
+ at end deffn
+
+
+ at c variables.cc
+ at anchor{doc-whos}
+ at deffn  {Command} whos
+ at deffnx {Command} whos pattern @dots{}
+ at deffnx {Command} whos option pattern @dots{}
+ at deffnx {Command} S = whos("pattern", @dots{})
+Provide detailed information on currently defined variables matching the
+given patterns.  Options and pattern syntax are the same as for the
+ at code{who} command.  Extended information about each variable is
+summarized in a table with the following default entries.
+
+ at table @asis
+ at item Attr
+Attributes of the listed variable.  Possible attributes are:
+ at table @asis
+ at item blank
+Variable in local scope
+ at item @code{g}
+Variable with global scope
+ at item @code{p}
+Persistent variable
+ at end table
+ at item Name
+The name of the variable.
+ at item Size
+The logical size of the variable.  A scalar is 1x1, a vector is 1xN or Nx1,
+a 2-D matrix is MxN.
+ at item Bytes
+The amount of memory currently used to store the variable.
+ at item Class
+The class of the variable.  Examples include double, single, char, uint16,
+cell, and struct.
+ at end table
+
+The table can be customized to display more or less information through
+the function @code{whos_line_format}.
+
+If @code{whos} is called as a function, return a struct array of defined
+variable names matching the given patterns.  Fields in the structure
+describing each variable are: name, size, bytes, class, global, sparse, 
+complex, nesting, persistent.
+ at seealso{@ref{doc-who,,who}, @ref{doc-whos_line_format,,whos_line_format}}
+ at end deffn
+
+
+ at c variables.cc
+ at anchor{doc-whos_line_format}
+ at deftypefn  {Built-in Function} {@var{val} =} whos_line_format ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} whos_line_format (@var{new_val})
+Query or set the format string used by the command @code{whos}.
+
+A full format string is:
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+%[modifier]<command>[:width[:left-min[:balance]]];
+ at end smallexample
+
+The following command sequences are available:
+
+ at table @code
+ at item %a
+Prints attributes of variables (g=global, p=persistent,
+f=formal parameter, a=automatic variable).
+ at item %b
+Prints number of bytes occupied by variables.
+ at item %c
+Prints class names of variables.
+ at item %e
+Prints elements held by variables.
+ at item %n
+Prints variable names.
+ at item %s
+Prints dimensions of variables.
+ at item %t
+Prints type names of variables.
+ at end table
+
+Every command may also have an alignment modifier:
+
+ at table @code
+ at item l
+Left alignment.
+ at item r
+Right alignment (default).
+ at item c
+Column-aligned (only applicable to command %s).
+ at end table
+
+The @code{width} parameter is a positive integer specifying the minimum
+number of columns used for printing.  No maximum is needed as the field will
+auto-expand as required.
+
+The parameters @code{left-min} and @code{balance} are only available when the
+column-aligned modifier is used with the command @samp{%s}.
+ at code{balance} specifies the column number within the field width which will
+be aligned between entries.  Numbering starts from 0 which indicates the
+leftmost column.  @code{left-min} specifies the minimum field width to the
+left of the specified balance column.
+
+The default format is
+ at code{"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\n"}.
+ at seealso{@ref{doc-whos,,whos}}
+ at end deftypefn
+
+
+Instead of displaying which variables are in memory, it is possible
+to determine if a given variable is available.  That way it is possible
+to alter the behavior of a program depending on the existence of a
+variable.  The following example illustrates this.
+
+ at example
+ at group
+if (! exist ("meaning", "var"))
+  disp ("The program has no 'meaning'");
+endif
+ at end group
+ at end example
+
+ at c variables.cc
+ at anchor{doc-exist}
+ at deftypefn {Built-in Function} {} exist (@var{name}, @var{type})
+Return 1 if the name exists as a variable, 2 if the name is an
+absolute file name, an ordinary file in Octave's @code{path}, or (after
+appending @samp{.m}) a function file in Octave's @code{path}, 3 if the
+name is a @samp{.oct} or @samp{.mex} file in Octave's @code{path},
+5 if the name is a built-in function, 7 if the name is a directory, or 103
+if the name is a function not associated with a file (entered on
+the command line).
+
+Otherwise, return 0.
+
+This function also returns 2 if a regular file called @var{name}
+exists in Octave's search path.  If you want information about
+other types of files, you should use some combination of the functions
+ at code{file_in_path} and @code{stat} instead.
+
+If the optional argument @var{type} is supplied, check only for
+symbols of the specified type.  Valid types are
+
+ at table @samp
+ at item "var"
+Check only for variables.
+ at item "builtin"
+Check only for built-in functions.
+ at item "file"
+Check only for files.
+ at item "dir"
+Check only for directories.
+ at end table
+ at end deftypefn
+
+
+Usually Octave will manage the memory, but sometimes it can be practical
+to remove variables from memory manually.  This is usually needed when
+working with large variables that fill a substantial part of the memory.
+On a computer that uses the IEEE floating point format, the following
+program allocates a matrix that requires around 128 MB memory.
+
+ at example
+large_matrix = zeros (4000, 4000);
+ at end example
+
+ at noindent
+Since having this variable in memory might slow down other computations,
+it can be necessary to remove it manually from memory.  The @code{clear}
+function allows this.
+
+ at c variables.cc
+ at anchor{doc-clear}
+ at deffn {Command} clear [options] pattern @dots{}
+Delete the names matching the given patterns from the symbol table.  The
+pattern may contain the following special characters:
+
+ at table @code
+ at item ?
+Match any single character.
+
+ at item *
+Match zero or more characters.
+
+ at item [ @var{list} ]
+Match the list of characters specified by @var{list}.  If the first
+character is @code{!} or @code{^}, match all characters except those
+specified by @var{list}.  For example, the pattern @samp{[a-zA-Z]} will
+match all lower and upper case alphabetic characters.
+ at end table
+
+For example, the command
+
+ at example
+clear foo b*r
+ at end example
+
+ at noindent
+clears the name @code{foo} and all names that begin with the letter
+ at code{b} and end with the letter @code{r}.
+
+If @code{clear} is called without any arguments, all user-defined
+variables (local and global) are cleared from the symbol table.  If
+ at code{clear} is called with at least one argument, only the visible
+names matching the arguments are cleared.  For example, suppose you have
+defined a function @code{foo}, and then hidden it by performing the
+assignment @code{foo = 2}.  Executing the command @kbd{clear foo} once
+will clear the variable definition and restore the definition of
+ at code{foo} as a function.  Executing @kbd{clear foo} a second time will
+clear the function definition.
+
+The following options are available in both long and short form
+ at table @code
+ at item -all, -a
+Clears all local and global user-defined variables and all functions
+from the symbol table.
+
+ at item -exclusive, -x
+Clears the variables that don't match the following pattern.
+
+ at item -functions, -f
+Clears the function names and the built-in symbols names.
+ at item -global, -g
+Clears the global symbol names.
+ at item -variables, -v
+Clears the local variable names.
+ at item -classes, -c
+Clears the class structure table and clears all objects.
+ at item -regexp, -r
+The arguments are treated as regular expressions as any variables that
+match will be cleared.
+ at end table
+With the exception of @code{exclusive}, all long options can be used 
+without the dash as well.
+ at end deffn
+
+
+Information about a function or variable such as its location in the
+file system can also be acquired from within Octave.  This is usually
+only useful during development of programs, and not within a program.
+
+ at c ./help/type.m
+ at anchor{doc-type}
+ at deftypefn {Command} type options name @dots{}
+Display the definition of each @var{name} that refers to a function.
+
+Normally also displays whether each @var{name} is user-defined or built-in;
+the @code{-q} option suppresses this behavior.
+
+If an output argument is requested nothing is displayed.  Instead, a cell 
+array of strings is returned, where each element corresponds to the 
+definition of each requested function.
+ at end deftypefn
+
+
+ at c ./help/which.m
+ at anchor{doc-which}
+ at deffn {Command} which name @dots{}
+Display the type of each @var{name}.  If @var{name} is defined from a
+function file, the full name of the file is also displayed.
+ at seealso{@ref{doc-help,,help}, @ref{doc-lookfor,,lookfor}}
+ at end deffn
+
+
+ at c ./miscellaneous/what.m
+ at anchor{doc-what}
+ at deftypefn {Command} {} what 
+ at deftypefnx {Command} {} what @var{dir}
+ at deftypefnx {Function File} {w =} what (@var{dir})
+List the Octave specific files in a directory.  If the variable @var{dir}
+is given then check that directory rather than the current directory.  If
+a return argument is requested, the files found are returned in the 
+structure @var{w}.
+ at seealso{@ref{doc-which,,which}}
+ at end deftypefn
+
diff --git a/doc/interpreter/var.txi b/doc/interpreter/var.txi
new file mode 100644
index 0000000..a8ed22a
--- /dev/null
+++ b/doc/interpreter/var.txi
@@ -0,0 +1,373 @@
+ at c Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005,
+ at c               2006, 2007, 2008, 2009 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Variables
+ at chapter Variables
+ at cindex variables, user-defined
+ at cindex user-defined variables
+
+Variables let you give names to values and refer to them later.  You have
+already seen variables in many of the examples.  The name of a variable
+must be a sequence of letters, digits and underscores, but it may not begin
+with a digit.  Octave does not enforce a limit on the length of variable
+names, but it is seldom useful to have variables with names longer than
+about 30 characters.  The following are all valid variable names
+
+ at cindex job hunting
+ at cindex getting a good job
+ at cindex flying high and fast
+ at example
+ at group
+x
+x15
+__foo_bar_baz__
+fucnrdthsucngtagdjb
+ at end group
+ at end example
+
+ at noindent
+However, names like @code{__foo_bar_baz__} that begin and end with two
+underscores are understood to be reserved for internal use by Octave.
+You should not use them in code you write, except to access Octave's
+documented internal variables and built-in symbolic constants.
+
+Case is significant in variable names.  The symbols @code{a} and
+ at code{A} are distinct variables.
+
+A variable name is a valid expression by itself.  It represents the
+variable's current value.  Variables are given new values with
+ at dfn{assignment operators} and @dfn{increment operators}.
+ at xref{Assignment Ops, ,Assignment Expressions}.
+
+There is one built-in variable with a special meaning.  The @code{ans} variable
+always contains the result of the last computation, where the output wasn't
+assigned to any variable.  The code @code{a = cos (pi)} will assign the value -1
+to the variable @code{a}, but will not change the value of @code{ans}.  However,
+the code @code{cos (pi)} will set the value of @code{ans} to -1.
+
+Variables in Octave do not have fixed types, so it is possible to first
+store a numeric value in a variable and then to later use the same name
+to hold a string value in the same program.  Variables may not be used
+before they have been given a value.  Doing so results in an error.
+
+ at cindex @code{ans}
+ at DOCSTRING(ans)
+
+ at DOCSTRING(isvarname)
+
+ at DOCSTRING(genvarname)
+
+ at DOCSTRING(namelengthmax)
+
+ at menu
+* Global Variables::            
+* Persistent Variables::        
+* Status of Variables::         
+ at end menu
+
+ at node Global Variables
+ at section Global Variables
+ at cindex global variables
+ at cindex @code{global} statement
+ at cindex variables, global
+
+A variable that has been declared @dfn{global} may be accessed from
+within a function body without having to pass it as a formal parameter.
+
+A variable may be declared global using a @code{global} declaration
+statement.  The following statements are all global declarations.
+
+ at example
+ at group
+global a
+global a b
+global c = 2
+global d = 3 e f = 5
+ at end group
+ at end example
+
+A global variable may only be initialized once in a @code{global}
+statement.  For example, after executing the following code
+
+ at example
+ at group
+global gvar = 1
+global gvar = 2
+ at end group
+ at end example
+
+ at noindent
+the value of the global variable @code{gvar} is 1, not 2.  Issuing a
+ at samp{clear gvar} command does not change the above behavior, but
+ at samp{clear all} does.
+
+It is necessary declare a variable as global within a function body in
+order to access it.  For example,
+
+ at example
+ at group
+global x
+function f ()
+  x = 1;
+endfunction
+f ()
+ at end group
+ at end example
+
+ at noindent
+does @emph{not} set the value of the global variable @code{x} to 1.  In
+order to change the value of the global variable @code{x}, you must also
+declare it to be global within the function body, like this
+
+ at example
+ at group
+function f ()
+  global x;
+  x = 1;
+endfunction
+ at end group
+ at end example
+
+Passing a global variable in a function parameter list will
+make a local copy and not modify the global value.  For example, given
+the function
+
+ at example
+ at group
+function f (x)
+  x = 0
+endfunction
+ at end group
+ at end example
+
+ at noindent
+and the definition of @code{x} as a global variable at the top level,
+
+ at example
+global x = 13
+ at end example
+
+ at noindent
+the expression
+
+ at example
+f (x)
+ at end example
+
+ at noindent
+will display the value of @code{x} from inside the function as 0,
+but the value of @code{x} at the top level remains unchanged, because
+the function works with a @emph{copy} of its argument.
+
+ at DOCSTRING(isglobal)
+
+ at node Persistent Variables
+ at section Persistent Variables
+ at cindex persistent variables
+ at cindex @code{persistent} statement
+ at cindex variables, persistent
+ at anchor{doc-persistent}
+
+A variable that has been declared @dfn{persistent} within a function
+will retain its contents in memory between subsequent calls to the
+same function.  The difference between persistent variables and global
+variables is that persistent variables are local in scope to a
+particular function and are not visible elsewhere.
+
+The following example uses a persistent variable to create a function
+that prints the number of times it has been called.
+
+ at example
+ at group
+function count_calls ()
+  persistent calls = 0;
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+
+for i = 1:3
+  count_calls ();
+endfor
+
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+ at print{} 'count_calls' has been called 3 times
+ at end group
+ at end example
+
+As the example shows, a variable may be declared persistent using a
+ at code{persistent} declaration statement.  The following statements are
+all persistent declarations.
+
+ at example
+ at group
+persistent a
+persistent a b
+persistent c = 2
+persistent d = 3 e f = 5
+ at end group
+ at end example
+
+The behavior of persistent variables is equivalent to the behavior of
+static variables in C.  The command @code{static} in Octave is also
+recognized and is equivalent to @code{persistent}.
+
+Like global variables, a persistent variable may only be initialized once.
+For example, after executing the following code
+
+ at example
+ at group
+persistent pvar = 1
+persistent pvar = 2
+ at end group
+ at end example
+
+ at noindent
+the value of the persistent variable @code{pvar} is 1, not 2.
+
+If a persistent variable is declared but not initialized to a specific
+value, it will contain an empty matrix.  So, it is also possible to
+initialize a persistent variable by checking whether it is empty, as the
+following example illustrates.
+
+ at example
+ at group
+function count_calls ()
+  persistent calls;
+  if (isempty (calls))
+    calls = 0;
+  endif
+  printf ("'count_calls' has been called %d times\n",
+          ++calls);
+endfunction
+ at end group
+ at end example
+
+ at noindent
+This implementation behaves in exactly the same way as the previous
+implementation of @code{count_calls}.
+
+The value of a persistent variable is kept in memory until it is
+explicitly cleared.  Assuming that the implementation of @code{count_calls}
+is saved on disk, we get the following behavior.
+
+ at example
+for i = 1:2
+  count_calls ();
+endfor
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+
+clear
+for i = 1:2
+  count_calls();
+endfor
+ at print{} 'count_calls' has been called 3 times
+ at print{} 'count_calls' has been called 4 times
+
+clear all
+for i = 1:2
+  count_calls();
+endfor
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+
+clear count_calls
+for i = 1:2
+  count_calls();
+endfor
+ at print{} 'count_calls' has been called 1 times
+ at print{} 'count_calls' has been called 2 times
+ at end example
+
+ at noindent
+That is, the persistent variable is only removed from memory when the
+function containing the variable is removed.  Note that if the function
+definition is typed directly into the Octave prompt, the persistent
+variable will be cleared by a simple @code{clear} command as the entire
+function definition will be removed from memory.  If you do not want
+a persistent variable to be removed from memory even if the function is
+cleared, you should use the @code{mlock} function as described in
+ at xref{Function Locking}.
+
+ at node Status of Variables
+ at section Status of Variables
+
+When creating simple one-shot programs it can be very convenient to
+see which variables are available at the prompt.  The function @code{who}
+and its siblings @code{whos} and @code{whos_line_format} will show
+different information about what is in memory, as the following shows.
+
+ at example
+ at group
+str = "A random string";
+who -variables
+     @print{} *** local user variables:
+     @print{} 
+     @print{} __nargin__  str
+ at end group
+ at end example
+
+ at DOCSTRING(who)
+
+ at DOCSTRING(whos)
+
+ at DOCSTRING(whos_line_format)
+
+Instead of displaying which variables are in memory, it is possible
+to determine if a given variable is available.  That way it is possible
+to alter the behavior of a program depending on the existence of a
+variable.  The following example illustrates this.
+
+ at example
+ at group
+if (! exist ("meaning", "var"))
+  disp ("The program has no 'meaning'");
+endif
+ at end group
+ at end example
+
+ at DOCSTRING(exist)
+
+Usually Octave will manage the memory, but sometimes it can be practical
+to remove variables from memory manually.  This is usually needed when
+working with large variables that fill a substantial part of the memory.
+On a computer that uses the IEEE floating point format, the following
+program allocates a matrix that requires around 128 MB memory.
+
+ at example
+large_matrix = zeros (4000, 4000);
+ at end example
+
+ at noindent
+Since having this variable in memory might slow down other computations,
+it can be necessary to remove it manually from memory.  The @code{clear}
+function allows this.
+
+ at DOCSTRING(clear)
+
+Information about a function or variable such as its location in the
+file system can also be acquired from within Octave.  This is usually
+only useful during development of programs, and not within a program.
+
+ at DOCSTRING(type)
+
+ at DOCSTRING(which)
+
+ at DOCSTRING(what)
diff --git a/doc/interpreter/voronoi.eps b/doc/interpreter/voronoi.eps
new file mode 100644
index 0000000..1752a4e
--- /dev/null
+++ b/doc/interpreter/voronoi.eps
@@ -0,0 +1,1084 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: voronoi.eps
+%%Creator: gnuplot 4.3 patchlevel 0
+%%CreationDate: Mon May 25 08:47:00 2009
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 625 481
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (voronoi.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.3 patchlevel 0)
+  /Author (Jaroslav Hajek)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Mon May 25 08:47:00 2009)
+  /DOCINFO pdfmark
+end
+} ifelse
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 625 50 lineto 625 481 lineto 50 481 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.2 (November 2007)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  gsave 1 setgray fill grestore clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+   { dup 5 get 3 ge
+     { 5 get 3 eq {gsave} {grestore} ifelse }
+     {dup dup 0 get findfont exch 1 get scalefont setfont
+     [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+     get exch 4 get {Gshow} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+     {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+     get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+     dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+     show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+     pop aload pop M} ifelse }ifelse }ifelse }
+     ifelse }
+   forall} def
+/Gswidth {dup type /stringtype eq {stringwidth} {pop (n) stringwidth} ifelse} def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+     6 get Gswidth pop add} {pop} ifelse} ifelse} forall} def
+/MLshow { currentpoint stroke M
+  0 exch R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+  exch dup MFwidth neg 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+  exch dup MFwidth -2 div 3 -1 roll R
+  Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave    { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+gsave % colour palette begin
+/maxcolors 64 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .0159 .0317 .0476 .0635 .0794 .0952 .1111 .127 .1429 .1587 .1746 
+  .1905 .2063 .2222 .2381 .254 .2698 .2857 .3016 .3175 .3333 .3492 .3651 
+  .381 .3968 .4127 .4286 .4444 .4603 .4762 .4921 .5079 .5238 .5397 .5556 
+  .5714 .5873 .6032 .619 .6349 .6508 .6667 .6825 .6984 .7143 .7302 .746 
+  .7619 .7778 .7937 .8095 .8254 .8413 .8571 .873 .8889 .9048 .9206 .9365 
+  .9524 .9683 .9841 1 ] def
+/RedA [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .0238 .0873 .1508 
+  .2143 .2778 .3413 .4048 .4683 .5317 .5952 .6587 .7222 .7857 .8492 .9127 
+  .9762 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 .9444 .881 .8175 .754 .6905 .627 
+  .5635 .5 ] def
+/GreenA [0 0 0 0 0 0 0 0 .0079 .0714 .1349 .1984 .2619 .3254 .3889 .4524 
+  .5159 .5794 .6429 .7063 .7698 .8333 .8968 .9603 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9603 .8968 .8333 .7698 .7063 .6429 .5794 .5159 .4524 .3889 .3254 
+  .2619 .1984 .1349 .0714 .0079 0 0 0 0 0 0 0 0 ] def
+/BlueA [.5 .5635 .627 .6905 .754 .8175 .881 .9444 1 1 1 1 1 1 1 1 1 1 1 1 1 
+  1 1 1 .9762 .9127 .8492 .7857 .7222 .6587 .5952 .5317 .4683 .4048 .3413 
+  .2778 .2143 .1508 .0873 .0238 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+  0 0 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color true and { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+0.500 UL
+LTb
+1475 928 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 928 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 2335 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 2335 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 3742 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 3742 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 5148 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 5148 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 6555 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 6555 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 7962 M
+88 0 V
+8833 0 R
+-88 0 V
+stroke
+0.00 0.00 0.00 C 1391 7962 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MRshow
+0.500 UL
+LTb
+1475 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 1475 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0)]
+] -40.0 MCshow
+0.500 UL
+LTb
+3259 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 3259 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.2)]
+] -40.0 MCshow
+0.500 UL
+LTb
+5043 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 5043 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.4)]
+] -40.0 MCshow
+0.500 UL
+LTb
+6828 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 6828 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.6)]
+] -40.0 MCshow
+0.500 UL
+LTb
+8612 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 8612 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (0.8)]
+] -40.0 MCshow
+0.500 UL
+LTb
+10396 928 M
+0 88 V
+0 6946 R
+0 -88 V
+stroke
+0.00 0.00 0.00 C 10396 788 M
+[ [(Helvetica) 120.0 0.0 true true 0 (1)]
+] -40.0 MCshow
+0.500 UL
+LTb
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+% Begin plot #1
+0.500 UL
+LT0
+0.00 0.00 1.00 C 5960 2033 M
+5605 1216 L
+9489 2602 L
+5960 2033 L
+460 2456 V
+9489 2602 L
+5960 2033 L
+5605 1216 L
+2196 1708 L
+3764 325 V
+2711 5876 M
+6976 7426 L
+1532 6028 L
+2711 5876 L
+6976 7426 L
+6420 4489 L
+2711 5876 L
+2196 1708 L
+1532 6028 L
+2711 5876 L
+9206 4108 M
+6420 4489 L
+9489 2602 L
+9206 4108 L
+6976 7426 L
+6420 4489 L
+9206 4108 L
+4805 3594 M
+5960 2033 L
+2196 1708 L
+4805 3594 L
+5960 2033 L
+460 2456 V
+4805 3594 L
+2711 5876 L
+2196 1708 L
+4805 3594 L
+2711 5876 L
+6420 4489 L
+4805 3594 L
+% End plot #1
+% Begin plot #2
+stroke
+LT1
+1.00 0.00 0.00 C % End plot #2
+% Begin plot #3
+0.500 UL
+LT2
+1.00 0.00 0.00 C 10396 3477 M
+7559 3146 L
+% End plot #3
+% Begin plot #4
+stroke
+LT3
+1.00 0.00 0.00 C 10396 6730 M
+8141 5788 L
+% End plot #4
+% Begin plot #5
+stroke
+LT4
+1.00 0.00 0.00 C 7559 3146 M
+582 2642 V
+% End plot #5
+% Begin plot #6
+stroke
+LT5
+1.00 0.00 0.00 C 7559 3146 M
+-39 -39 V
+% End plot #6
+% Begin plot #7
+stroke
+LT6
+1.00 0.00 0.00 C 8141 5788 M
+5142 6141 L
+% End plot #7
+% Begin plot #8
+stroke
+LT7
+1.00 0.00 0.00 C 3777 928 M
+270 1165 V
+% End plot #8
+% Begin plot #9
+stroke
+LT8
+1.00 0.00 0.00 C 4047 2093 M
+8064 1009 L
+% End plot #9
+% Begin plot #10
+stroke
+LT0
+1.00 0.00 0.00 C 4047 2093 M
+-14 100 V
+% End plot #10
+% Begin plot #11
+stroke
+LT1
+1.00 0.00 0.00 C 8064 1009 M
+46 -81 V
+% End plot #11
+% Begin plot #12
+stroke
+LT2
+1.00 0.00 0.00 C 8064 1009 M
+7520 3107 L
+% End plot #12
+% Begin plot #13
+stroke
+LT3
+1.00 0.00 0.00 C 7520 3107 M
+6322 3246 L
+% End plot #13
+% Begin plot #14
+stroke
+LT4
+1.00 0.00 0.00 C 1475 3831 M
+211 20 V
+% End plot #14
+% Begin plot #15
+stroke
+LT5
+1.00 0.00 0.00 C 4077 7962 M
+5142 6141 L
+% End plot #15
+% Begin plot #16
+stroke
+LT6
+1.00 0.00 0.00 C 2538 7962 M
+1686 3851 L
+% End plot #16
+% Begin plot #17
+stroke
+LT7
+1.00 0.00 0.00 C 5142 6141 M
+4577 5202 L
+% End plot #17
+% Begin plot #18
+stroke
+LT8
+1.00 0.00 0.00 C 1686 3851 M
+461 -35 V
+% End plot #18
+% Begin plot #19
+stroke
+LT0
+1.00 0.00 0.00 C 4033 2193 M
+6322 3246 L
+% End plot #19
+% Begin plot #20
+stroke
+LT1
+1.00 0.00 0.00 C 4033 2193 M
+2147 3816 L
+% End plot #20
+% Begin plot #21
+stroke
+LT2
+1.00 0.00 0.00 C 6322 3246 M
+4577 5202 L
+% End plot #21
+% Begin plot #22
+stroke
+LT3
+1.00 0.00 0.00 C LCb setrgbcolor
+9745 7829 M
+[ [(Helvetica) 120.0 0.0 true true 0 (Delaunay Triangulation)]
+] -40.0 MRshow
+LT3
+1.00 0.00 0.00 C 9829 7829 M
+399 0 V
+4577 5202 M
+2147 3816 L
+% End plot #22
+% Begin plot #23
+stroke
+3.000 UL
+LT4
+0.00 1.00 0.00 C LCb setrgbcolor
+9745 7689 M
+[ [(Helvetica) 120.0 0.0 true true 0 (Voronoi Diagram)]
+] -40.0 MRshow
+LT4
+0.00 1.00 0.00 C 9829 7689 M
+399 0 V
+4577 3584 M
+-64 1 V
+-65 2 V
+-64 4 V
+-64 6 V
+-64 7 V
+-63 9 V
+-64 10 V
+-62 12 V
+-63 13 V
+-61 15 V
+-61 17 V
+-60 18 V
+-60 19 V
+-59 21 V
+-58 22 V
+-57 24 V
+-56 25 V
+-55 27 V
+-54 28 V
+-52 29 V
+-52 31 V
+-50 31 V
+-49 33 V
+-48 35 V
+-46 35 V
+-45 37 V
+-44 37 V
+-41 39 V
+-41 39 V
+-38 41 V
+-38 42 V
+-35 42 V
+-34 44 V
+-32 44 V
+-30 45 V
+-28 45 V
+-27 47 V
+-24 47 V
+-23 47 V
+-21 48 V
+-19 49 V
+-17 49 V
+-15 49 V
+-13 50 V
+-11 50 V
+-9 51 V
+-7 50 V
+-5 51 V
+-3 51 V
+-1 50 V
+1 51 V
+3 51 V
+5 51 V
+7 50 V
+9 51 V
+11 50 V
+13 49 V
+15 50 V
+17 49 V
+19 49 V
+21 48 V
+23 47 V
+24 47 V
+27 47 V
+28 45 V
+30 45 V
+32 44 V
+34 44 V
+35 42 V
+38 42 V
+38 40 V
+41 40 V
+41 39 V
+44 37 V
+45 37 V
+46 35 V
+48 34 V
+49 33 V
+50 32 V
+52 31 V
+52 29 V
+54 28 V
+55 27 V
+56 25 V
+57 23 V
+58 23 V
+59 21 V
+60 19 V
+60 18 V
+61 17 V
+61 15 V
+63 13 V
+62 12 V
+64 10 V
+63 9 V
+64 7 V
+64 6 V
+64 4 V
+65 2 V
+64 1 V
+65 -1 V
+64 -2 V
+stroke 4706 6818 M
+64 -4 V
+64 -6 V
+64 -7 V
+64 -9 V
+63 -10 V
+63 -12 V
+62 -13 V
+61 -15 V
+61 -17 V
+61 -18 V
+59 -19 V
+59 -21 V
+58 -23 V
+57 -23 V
+56 -25 V
+55 -27 V
+54 -28 V
+53 -29 V
+51 -31 V
+51 -32 V
+49 -33 V
+47 -34 V
+47 -35 V
+44 -37 V
+44 -37 V
+42 -39 V
+40 -40 V
+39 -40 V
+37 -42 V
+35 -42 V
+34 -44 V
+32 -44 V
+30 -45 V
+28 -45 V
+27 -47 V
+25 -47 V
+22 -47 V
+21 -48 V
+19 -49 V
+17 -49 V
+15 -50 V
+13 -49 V
+12 -50 V
+9 -51 V
+7 -50 V
+5 -51 V
+3 -51 V
+1 -51 V
+-1 -50 V
+-3 -51 V
+-5 -51 V
+-7 -50 V
+-9 -51 V
+-12 -50 V
+-13 -50 V
+-15 -49 V
+-17 -49 V
+-19 -49 V
+-21 -48 V
+-22 -47 V
+-25 -47 V
+-27 -47 V
+-28 -45 V
+-30 -45 V
+-32 -44 V
+-34 -44 V
+-35 -42 V
+-37 -42 V
+-39 -41 V
+-40 -39 V
+-42 -39 V
+-44 -37 V
+-44 -37 V
+-47 -35 V
+-47 -35 V
+-49 -33 V
+-51 -31 V
+-51 -31 V
+-53 -29 V
+-54 -28 V
+-55 -27 V
+-56 -25 V
+-57 -24 V
+-58 -22 V
+-59 -21 V
+-59 -19 V
+-61 -18 V
+-61 -17 V
+-61 -15 V
+-62 -13 V
+-63 -12 V
+-63 -10 V
+-64 -9 V
+-64 -7 V
+-64 -6 V
+-64 -4 V
+-64 -2 V
+-65 -1 V
+% End plot #23
+stroke
+0.500 UL
+LTb
+1475 7962 N
+0 -7034 V
+8921 0 V
+0 7034 V
+-8921 0 V
+Z stroke
+1.000 UP
+0.500 UL
+LTb
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/doc/interpreter/voronoi.pdf b/doc/interpreter/voronoi.pdf
new file mode 100644
index 0000000..7e97caf
Binary files /dev/null and b/doc/interpreter/voronoi.pdf differ
diff --git a/doc/interpreter/voronoi.png b/doc/interpreter/voronoi.png
new file mode 100644
index 0000000..0a1c4b3
Binary files /dev/null and b/doc/interpreter/voronoi.png differ
diff --git a/doc/interpreter/voronoi.txt b/doc/interpreter/voronoi.txt
new file mode 100644
index 0000000..76cea92
--- /dev/null
+++ b/doc/interpreter/voronoi.txt
@@ -0,0 +1,4 @@
+
++---------------------------------+
+| Image unavailable in text mode. |
++---------------------------------+
diff --git a/doc/liboctave/HTML/Acknowledgements.html b/doc/liboctave/HTML/Acknowledgements.html
new file mode 100644
index 0000000..63e3e59
--- /dev/null
+++ b/doc/liboctave/HTML/Acknowledgements.html
@@ -0,0 +1,44 @@
+<html lang="en">
+<head>
+<title>Acknowledgements - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="index.html#Top" title="Top">
+<link rel="next" href="Copying.html#Copying" title="Copying">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<h1 class="settitle">Octave C++ Classes</h1>
+<div class="node">
+<p>
+<a name="Acknowledgements"></a>
+Next: <a rel="next" accesskey="n" href="Copying.html#Copying">Copying</a>,
+Previous: <a rel="previous" accesskey="p" href="index.html#Top">Top</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">1 Acknowledgements</h2>
+
+<p><a name="index-acknowledgements-1"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Contributors.html#Contributors">Contributors</a>:                 People who contributed to developing of Octave. 
+</ul>
+
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Arrays.html b/doc/liboctave/HTML/Arrays.html
new file mode 100644
index 0000000..f4d4b4e
--- /dev/null
+++ b/doc/liboctave/HTML/Arrays.html
@@ -0,0 +1,43 @@
+<html lang="en">
+<head>
+<title>Arrays - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Introduction.html#Introduction" title="Introduction">
+<link rel="next" href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations" title="Matrix and Vector Operations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Arrays"></a>
+Next: <a rel="next" accesskey="n" href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a>,
+Previous: <a rel="previous" accesskey="p" href="Introduction.html#Introduction">Introduction</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">3 Arrays</h2>
+
+<p><a name="index-arrays-6"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Bounds.html b/doc/liboctave/HTML/Bounds.html
new file mode 100644
index 0000000..6214048
--- /dev/null
+++ b/doc/liboctave/HTML/Bounds.html
@@ -0,0 +1,98 @@
+<html lang="en">
+<head>
+<title>Bounds - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Objective-Functions.html#Objective-Functions" title="Objective Functions">
+<link rel="next" href="Linear-Constraints.html#Linear-Constraints" title="Linear Constraints">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bounds"></a>
+Next: <a rel="next" accesskey="n" href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a>,
+Previous: <a rel="previous" accesskey="p" href="Objective-Functions.html#Objective-Functions">Objective Functions</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">9.2 Bounds</h3>
+
+<p><a name="index-bounds-831"></a>
+
+<div class="defun">
+— :  <b>Bounds</b> (<var>void</var>)<var><a name="index-Bounds-832"></a></var><br>
+— :  <b>Bounds</b> (<var>int n</var>)<var><a name="index-Bounds-833"></a></var><br>
+— :  <b>Bounds</b> (<var>const ColumnVector lb, const ColumnVector ub</var>)<var><a name="index-Bounds-834"></a></var><br>
+— :  <b>Bounds</b> (<var>const Bounds &a</var>)<var><a name="index-Bounds-835"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>operator =</b> (<var>const Bounds &a</var>)<var><a name="index-operator-_003d-836"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>resize</b> (<var>int n</var>)<var><a name="index-resize-837"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>lower_bound</b> (<var>int index</var>)<var> const;<a name="index-lower_005fbound-838"></a></var><br>
+— : double <b>upper_bound</b> (<var>int index</var>)<var> const;<a name="index-upper_005fbound-839"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>lower_bounds</b> (<var>void</var>)<var> const;<a name="index-lower_005fbounds-840"></a></var><br>
+— : ColumnVector <b>upper_bounds</b> (<var>void</var>)<var> const;<a name="index-upper_005fbounds-841"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>size</b> (<var>void</var>)<var> const;<a name="index-size-842"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>set_bound</b> (<var>int index, double low, double high</var>)<var><a name="index-set_005fbound-843"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>set_bounds</b> (<var>double low, double high</var>)<var><a name="index-set_005fbounds-844"></a></var><br>
+— : Bounds& <b>set_bounds</b> (<var>const ColumnVector lb, const ColumnVector ub</var>)<var><a name="index-set_005fbounds-845"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>set_lower_bound</b> (<var>int index, double low</var>)<var><a name="index-set_005flower_005fbound-846"></a></var><br>
+— : Bounds& <b>set_upper_bound</b> (<var>int index, double high</var>)<var><a name="index-set_005fupper_005fbound-847"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>set_lower_bounds</b> (<var>double low</var>)<var><a name="index-set_005flower_005fbounds-848"></a></var><br>
+— : Bounds& <b>set_upper_bounds</b> (<var>double high</var>)<var><a name="index-set_005fupper_005fbounds-849"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Bounds& <b>set_lower_bounds</b> (<var>const ColumnVector lb</var>)<var><a name="index-set_005flower_005fbounds-850"></a></var><br>
+— : Bounds& <b>set_upper_bounds</b> (<var>const ColumnVector ub</var>)<var><a name="index-set_005fupper_005fbounds-851"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const Bounds &b</var>)<var><a name="index-operator-_003c_003c-852"></a></var><br>
+        </div>
+
+<!--  -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Bugs.html b/doc/liboctave/HTML/Bugs.html
new file mode 100644
index 0000000..2b1cf3d
--- /dev/null
+++ b/doc/liboctave/HTML/Bugs.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Bugs - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Installation.html#Installation" title="Installation">
+<link rel="next" href="Concept-Index.html#Concept-Index" title="Concept Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Bugs"></a>
+Next: <a rel="next" accesskey="n" href="Concept-Index.html#Concept-Index">Concept Index</a>,
+Previous: <a rel="previous" accesskey="p" href="Installation.html#Installation">Installation</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">15 Bugs</h2>
+
+<p><a name="index-bugs_002c-known-1021"></a><a name="index-installation-trouble-1022"></a><a name="index-known-causes-of-trouble-1023"></a><a name="index-troubleshooting-1024"></a>
+
+<!-- Copyright (C) 1996, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Collocation-Weights.html b/doc/liboctave/HTML/Collocation-Weights.html
new file mode 100644
index 0000000..93bc71e
--- /dev/null
+++ b/doc/liboctave/HTML/Collocation-Weights.html
@@ -0,0 +1,123 @@
+<html lang="en">
+<head>
+<title>Collocation Weights - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Quadrature.html#Quadrature" title="Quadrature">
+<link rel="prev" href="Quadrature.html#Quadrature" title="Quadrature">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Collocation-Weights"></a>
+Previous: <a rel="previous" accesskey="p" href="Quadrature.html#Quadrature">Quadrature</a>,
+Up: <a rel="up" accesskey="u" href="Quadrature.html#Quadrature">Quadrature</a>
+<hr>
+</div>
+
+<h3 class="section">10.1 Collocation Weights</h3>
+
+<p><a name="index-orthogonal-collocation-946"></a><a name="index-collocation-weights-947"></a>
+
+<div class="defun">
+— :  <b>CollocWt</b> (<var>void</var>)<var><a name="index-CollocWt-948"></a></var><br>
+— :  <b>CollocWt</b> (<var>int n, int inc_l, int inc_r</var>)<var><a name="index-CollocWt-949"></a></var><br>
+— :  <b>CollocWt</b> (<var>int n, int inc_l, int inc_r, double l, double r</var>)<var><a name="index-CollocWt-950"></a></var><br>
+— :  <b>CollocWt</b> (<var>int n, double a, double b, int inc_l, int inc_r</var>)<var><a name="index-CollocWt-951"></a></var><br>
+— :  <b>CollocWt</b> (<var>int n, int inc_l, int inc_r, double l, double r</var>)<var><a name="index-CollocWt-952"></a></var><br>
+— :  <b>CollocWt</b> (<var>const CollocWt&</var>)<var><a name="index-CollocWt-953"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CollocWt& <b>operator =</b> (<var>const CollocWt&</var>)<var><a name="index-operator-_003d-954"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CollocWt& <b>resize</b> (<var>int ncol</var>)<var><a name="index-resize-955"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CollocWt& <b>add_left</b> (<var>void</var>)<var><a name="index-add_005fleft-956"></a></var><br>
+— : CollocWt& <b>add_right</b> (<var>void</var>)<var><a name="index-add_005fright-957"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CollocWt& <b>delete_left</b> (<var>void</var>)<var><a name="index-delete_005fleft-958"></a></var><br>
+— : CollocWt& <b>delete_right</b> (<var>void</var>)<var><a name="index-delete_005fright-959"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CollocWt& <b>set_left</b> (<var>double val</var>)<var><a name="index-set_005fleft-960"></a></var><br>
+— : CollocWt& <b>set_right</b> (<var>double val</var>)<var><a name="index-set_005fright-961"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CollocWt& <b>set_alpha</b> (<var>double val</var>)<var><a name="index-set_005falpha-962"></a></var><br>
+— : CollocWt& <b>set_beta</b> (<var>double val</var>)<var><a name="index-set_005fbeta-963"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>ncol</b> (<var>void</var>)<var> const<a name="index-ncol-964"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>left_included</b> (<var>void</var>)<var> const<a name="index-left_005fincluded-965"></a></var><br>
+— : int <b>right_included</b> (<var>void</var>)<var> const<a name="index-right_005fincluded-966"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>left</b> (<var>void</var>)<var> const<a name="index-left-967"></a></var><br>
+— : double <b>right</b> (<var>void</var>)<var> const<a name="index-right-968"></a></var><br>
+— : double <b>width</b> (<var>void</var>)<var> const<a name="index-width-969"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>alpha</b> (<var>void</var>)<var> const<a name="index-alpha-970"></a></var><br>
+— : double <b>beta</b> (<var>void</var>)<var> const<a name="index-beta-971"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>roots</b> (<var>void</var>)<var><a name="index-roots-972"></a></var><br>
+— : ColumnVector <b>quad</b> (<var>void</var>)<var><a name="index-quad-973"></a></var><br>
+— : ColumnVector <b>quad_weights</b> (<var>void</var>)<var><a name="index-quad_005fweights-974"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>first</b> (<var>void</var>)<var><a name="index-first-975"></a></var><br>
+— : Matrix <b>second</b> (<var>void</var>)<var><a name="index-second-976"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const CollocWt &c</var>)<var><a name="index-operator-_003c_003c-977"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Concept-Index.html b/doc/liboctave/HTML/Concept-Index.html
new file mode 100644
index 0000000..8d4739d
--- /dev/null
+++ b/doc/liboctave/HTML/Concept-Index.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Concept Index - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Bugs.html#Bugs" title="Bugs">
+<link rel="next" href="Function-Index.html#Function-Index" title="Function Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Concept-Index"></a>
+Next: <a rel="next" accesskey="n" href="Function-Index.html#Function-Index">Function Index</a>,
+Previous: <a rel="previous" accesskey="p" href="Bugs.html#Bugs">Bugs</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Concept Index</h2>
+
+<ul class="index-cp" compact>
+<li><a href="Acknowledgements.html#index-acknowledgements-1">acknowledgements</a>: <a href="Acknowledgements.html#Acknowledgements">Acknowledgements</a></li>
+<li><a href="Arrays.html#index-arrays-6">arrays</a>: <a href="Arrays.html#Arrays">Arrays</a></li>
+<li><a href="Bounds.html#index-bounds-831">bounds</a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Bugs.html#index-bugs_002c-known-1021">bugs, known</a>: <a href="Bugs.html#Bugs">Bugs</a></li>
+<li><a href="Collocation-Weights.html#index-collocation-weights-947">collocation weights</a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Contributors.html#index-contributors-2">contributors</a>: <a href="Contributors.html#Contributors">Contributors</a></li>
+<li><a href="Contributors.html#index-copyright-4">copyright</a>: <a href="Contributors.html#Contributors">Contributors</a></li>
+<li><a href="Differential-Algebraic-Equations.html#index-DAE-1009">DAE</a>: <a href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a></li>
+<li><a href="Matrix-Factorizations.html#index-factorizations-625">factorizations</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Installation.html#index-installation-1020">installation</a>: <a href="Installation.html#Installation">Installation</a></li>
+<li><a href="Bugs.html#index-installation-trouble-1022">installation trouble</a>: <a href="Bugs.html#Bugs">Bugs</a></li>
+<li><a href="Quadrature.html#index-integration-918">integration</a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Introduction.html#index-introduction-5">introduction</a>: <a href="Introduction.html#Introduction">Introduction</a></li>
+<li><a href="Bugs.html#index-known-causes-of-trouble-1023">known causes of trouble</a>: <a href="Bugs.html#Bugs">Bugs</a></li>
+<li><a href="Linear-Constraints.html#index-linear-Constraints-853">linear Constraints</a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Matrix-Factorizations.html#index-matrix-factorizations-624">matrix factorizations</a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-matrix-manipulations-103">matrix manipulations</a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Nonlinear-Programming.html#index-NLP-895">NLP</a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Nonlinear-Constraints.html#index-nonlinear-Constraints-869">nonlinear Constraints</a>: <a href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a></li>
+<li><a href="Nonlinear-Equations.html#index-nonlinear-equations-799">nonlinear equations</a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Nonlinear-Functions.html#index-nonlinear-functions-789">nonlinear functions</a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Nonlinear-Programming.html#index-nonlinear-programming-896">nonlinear programming</a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Quadrature.html#index-numerical-integration-917">numerical integration</a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Objective-Functions.html#index-objective-functions-821">objective functions</a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-ODE-978">ODE</a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Optimization.html#index-optimization-820">optimization</a>: <a href="Optimization.html#Optimization">Optimization</a></li>
+<li><a href="Collocation-Weights.html#index-orthogonal-collocation-946">orthogonal collocation</a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Quadratic-Programming.html#index-QP-875">QP</a>: <a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a></li>
+<li><a href="Quadratic-Programming.html#index-quadratic-programming-876">quadratic programming</a>: <a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a></li>
+<li><a href="Quadrature.html#index-quadrature-916">quadrature</a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Ranges.html#index-ranges-771">ranges</a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Bugs.html#index-troubleshooting-1024">troubleshooting</a>: <a href="Bugs.html#Bugs">Bugs</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-vector-manipulations-104">vector manipulations</a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Contributors.html#index-warranty-3">warranty</a>: <a href="Contributors.html#Contributors">Contributors</a></li>
+   </ul><!-- Copyright (C) 1996, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+</body></html>
+
diff --git a/doc/liboctave/HTML/Constructors-and-Assignment.html b/doc/liboctave/HTML/Constructors-and-Assignment.html
new file mode 100644
index 0000000..b86e3b3
--- /dev/null
+++ b/doc/liboctave/HTML/Constructors-and-Assignment.html
@@ -0,0 +1,372 @@
+<html lang="en">
+<head>
+<title>Constructors and Assignment - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Arrays.html#Arrays" title="Arrays">
+<link rel="prev" href="Arrays.html#Arrays" title="Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Constructors-and-Assignment"></a>
+Previous: <a rel="previous" accesskey="p" href="Arrays.html#Arrays">Arrays</a>,
+Up: <a rel="up" accesskey="u" href="Arrays.html#Arrays">Arrays</a>
+<hr>
+</div>
+
+<h3 class="section">3.1 Constructors and Assignment</h3>
+
+<div class="defun">
+— Constructor:  <b>Array<T></b> (<var>void</var>)<var><a name="index-Array_003cT_003e-7"></a></var><br>
+<blockquote><p>Create an array with no elements. 
+</p></blockquote></div>
+
+<div class="defun">
+— Constructor:  <b>Array<T></b> (<var>int n </var>[<var>, const T &val</var>])<var><a name="index-Array_003cT_003e-8"></a></var><br>
+<blockquote><p>Create an array with <var>n</var> elements.  If the optional argument
+<var>val</var> is supplied, the elements are initialized to <var>val</var>;
+otherwise, they are left uninitialized.  If <var>n</var> is less than zero,
+the current error handler is invoked (see <a href="Error-Handling.html#Error-Handling">Error Handling</a>). 
+</p></blockquote></div>
+
+<div class="defun">
+— Constructor:  <b>Array<T></b> (<var>const Array<T> &a</var>)<var><a name="index-Array_003cT_003e-9"></a></var><br>
+<blockquote><p>Create a copy of the <var>Array<T></var> object <var>a</var>.  Memory for the
+<var>Array<T></var> class is managed using a reference counting scheme, so
+the cost of this operation is independent of the size of the array. 
+</p></blockquote></div>
+
+<div class="defun">
+— Assignment on Array<T>: Array<T>& <b>operator =</b> (<var>const Array<T> &a</var>)<var><a name="index-operator-_003d-on-Array_003cT_003e-10"></a></var><br>
+<blockquote><p>Assignment operator.  Memory for the <var>Array<T></var> class is managed
+using a reference counting scheme, so the cost of this operation is
+independent of the size of the array. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method on Array<T>: int <b>capacity</b> (<var>void</var>)<var> const<a name="index-capacity-on-Array_003cT_003e-11"></a></var><br>
+— Method on Array<T>: int <b>length</b> (<var>void</var>)<var> const<a name="index-length-on-Array_003cT_003e-12"></a></var><br>
+<blockquote><p>Return the length of the array. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method on Array<T>: T& <b>elem</b> (<var>int n</var>)<var><a name="index-elem-on-Array_003cT_003e-13"></a></var><br>
+— Method on Array<T>: T& <b>checkelem</b> (<var>int n</var>)<var><a name="index-checkelem-on-Array_003cT_003e-14"></a></var><br>
+<blockquote><p>If <var>n</var> is within the bounds of the array, return a reference to the
+element indexed by <var>n</var>; otherwise, the current error handler is
+invoked (see <a href="Error-Handling.html#Error-Handling">Error Handling</a>). 
+</p></blockquote></div>
+
+<div class="defun">
+— Indexing on Array<T>: T& <b>operator ()</b> (<var>int n</var>)<var><a name="index-operator-_0028_0029-on-Array_003cT_003e-15"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array<T>: T <b>elem</b> (<var>int n</var>)<var> const<a name="index-elem-on-Array_003cT_003e-16"></a></var><br>
+— Method on Array<T>: T <b>checkelem</b> (<var>int n</var>)<var> const<a name="index-checkelem-on-Array_003cT_003e-17"></a></var><br>
+<blockquote><p>If <var>n</var> is within the bounds of the array, return the value indexed
+by <var>n</var>; otherwise, call the current error handler. 
+See <a href="Error-Handling.html#Error-Handling">Error Handling</a>. 
+</p></blockquote></div>
+
+<div class="defun">
+— Indexing on Array<T>: T <b>operator ()</b> (<var>int n</var>)<var> const<a name="index-operator-_0028_0029-on-Array_003cT_003e-18"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array<T>: T& <b>xelem</b> (<var>int n</var>)<var><a name="index-xelem-on-Array_003cT_003e-19"></a></var><br>
+— Method on Array<T>: T <b>xelem</b> (<var>int n</var>)<var> const<a name="index-xelem-on-Array_003cT_003e-20"></a></var><br>
+<blockquote><p>Return a reference to, or the value of, the element indexed by <var>n</var>. 
+These methods never perform bounds checking. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method on Array<T>: void <b>resize</b> (<var><a name="index-resize-on-Array_003cT_003e-21"></a></var><br>
+<blockquote><p>Change the size of the array to be <var>n</var> elements.  All elements are
+unchanged, except that if <var>n</var> is greater than the current size and
+the optional argument <var>val</var> is provided, the additional elements are
+initialized to <var>val</var>; otherwise, any additional elements are left
+uninitialized.  In the current implementation, if <var>n</var> is less than
+the current size, the length is updated but no memory is released. 
+</p></blockquote></div>
+
+<div class="defun">
+— Method on Array<T>: const T* <b>data</b> (<var>void</var>)<var> const<a name="index-data-on-Array_003cT_003e-22"></a></var><br>
+        </div>
+
+<!-- Should this be public? -->
+<!-- T *fortran_vec (void) -->
+<div class="defun">
+— Constructor:  <b>Array2<T></b><var> Array2<T> Array2 </var>(<var>void</var>)<var><a name="index-Array2_003cT_003e-23"></a></var><br>
+— Constructor:  <b>Array2<T></b> (<var>int n, int m</var>)<var><a name="index-Array2_003cT_003e-24"></a></var><br>
+— Constructor:  <b>Array2<T></b> (<var>int n, int m, const T &val</var>)<var><a name="index-Array2_003cT_003e-25"></a></var><br>
+— Constructor:  <b>Array2<T></b> (<var>const Array2<T> &a</var>)<var><a name="index-Array2_003cT_003e-26"></a></var><br>
+— Constructor:  <b>Array2<T></b> (<var>const DiagArray<T> &a</var>)<var><a name="index-Array2_003cT_003e-27"></a></var><br>
+        </div>
+
+<div class="defun">
+— Assignment on Array2<T>: Array2<T>& <b>operator =</b> (<var>const Array2<T> &a</var>)<var><a name="index-operator-_003d-on-Array2_003cT_003e-28"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array2<T>: int <b>dim1</b> (<var>void</var>)<var> const<a name="index-dim1-on-Array2_003cT_003e-29"></a></var><br>
+— Method on Array2<T>: int <b>rows</b> (<var>void</var>)<var> const<a name="index-rows-on-Array2_003cT_003e-30"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array2<T>: int <b>dim2</b> (<var>void</var>)<var> const<a name="index-dim2-on-Array2_003cT_003e-31"></a></var><br>
+— Method on Array2<T>: int <b>cols</b> (<var>void</var>)<var> const<a name="index-cols-on-Array2_003cT_003e-32"></a></var><br>
+— Method on Array2<T>: int <b>columns</b> (<var>void</var>)<var> const<a name="index-columns-on-Array2_003cT_003e-33"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array2<T>: T& <b>elem</b> (<var>int i, int j</var>)<var><a name="index-elem-on-Array2_003cT_003e-34"></a></var><br>
+— Method on Array2<T>: T& <b>checkelem</b> (<var>int i, int j</var>)<var><a name="index-checkelem-on-Array2_003cT_003e-35"></a></var><br>
+        </div>
+
+<div class="defun">
+— Indexing on Array2<T>: T& <b>operator ()</b> (<var>int i, int j</var>)<var><a name="index-operator-_0028_0029-on-Array2_003cT_003e-36"></a></var><br>
+        </div>
+
+<!-- This needs to be fixed. -->
+<!-- T& xelem (int i, int j) -->
+<!-- T elem (int i, int j) const -->
+<!-- T checkelem (int i, int j) const -->
+<!-- T operator () (int i, int j) const -->
+<div class="defun">
+— Method on Array2<T>: void <b>resize</b> (<var>int n, int m</var>)<var><a name="index-resize-on-Array2_003cT_003e-37"></a></var><br>
+— Method on Array2<T>: void <b>resize</b> (<var>int n, int m, const T &val</var>)<var><a name="index-resize-on-Array2_003cT_003e-38"></a></var><br>
+        </div>
+
+<div class="defun">
+— Constructor:  <b>Array3<T></b> (<var>void</var>)<var><a name="index-Array3_003cT_003e-39"></a></var><br>
+— Constructor:  <b>Array3<T></b> (<var>int n, int m, int k</var>)<var><a name="index-Array3_003cT_003e-40"></a></var><br>
+— Constructor:  <b>Array3<T></b> (<var>int n, int m, int k, const T &val</var>)<var><a name="index-Array3_003cT_003e-41"></a></var><br>
+— Constructor:  <b>Array3<T></b> (<var>const Array3<T> &a</var>)<var><a name="index-Array3_003cT_003e-42"></a></var><br>
+        </div>
+
+<div class="defun">
+— Assignment on Array3<T>: Array3<T>& <b>operator =</b> (<var>const Array3<T> &a</var>)<var><a name="index-operator-_003d-on-Array3_003cT_003e-43"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array3<T>: int <b>dim1</b> (<var>void</var>)<var> const<a name="index-dim1-on-Array3_003cT_003e-44"></a></var><br>
+— Method on Array3<T>: int <b>dim2</b> (<var>void</var>)<var> const<a name="index-dim2-on-Array3_003cT_003e-45"></a></var><br>
+— Method on Array3<T>: int <b>dim3</b> (<var>void</var>)<var> const<a name="index-dim3-on-Array3_003cT_003e-46"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on Array3<T>: T& <b>elem</b> (<var>int i, int j, int k</var>)<var><a name="index-elem-on-Array3_003cT_003e-47"></a></var><br>
+— Method on Array3<T>: T& <b>checkelem</b> (<var>int i, int j, int k</var>)<var><a name="index-checkelem-on-Array3_003cT_003e-48"></a></var><br>
+        </div>
+
+<div class="defun">
+— Indexing on Array3<T>: T& <b>operator ()</b> (<var>int i, int j, int k</var>)<var><a name="index-operator-_0028_0029-on-Array3_003cT_003e-49"></a></var><br>
+        </div>
+
+<!-- This needs to be fixed. -->
+<!-- T& xelem (int i, int j, int k) -->
+<!-- T elem (int i, int j, int k) const -->
+<!-- T checkelem (int i, int j, int k) const -->
+<!-- T operator () (int i, int j, int k) const -->
+<div class="defun">
+— Method on Array3<T>: void <b>resize</b> (<var>int n, int m, int k</var>)<var><a name="index-resize-on-Array3_003cT_003e-50"></a></var><br>
+— Method on Array3<T>: void <b>resize</b> (<var>int n, int m, int k, const T &val</var>)<var><a name="index-resize-on-Array3_003cT_003e-51"></a></var><br>
+        </div>
+
+<div class="defun">
+— Constructor:  <b>DiagArray<T></b> (<var>void</var>)<var><a name="index-DiagArray_003cT_003e-52"></a></var><br>
+— Constructor:  <b>DiagArray<T></b> (<var>int n</var>)<var><a name="index-DiagArray_003cT_003e-53"></a></var><br>
+— Constructor:  <b>DiagArray<T></b> (<var>int n, const T &val</var>)<var><a name="index-DiagArray_003cT_003e-54"></a></var><br>
+— Constructor:  <b>DiagArray<T></b> (<var>int r, int c</var>)<var><a name="index-DiagArray_003cT_003e-55"></a></var><br>
+— Constructor:  <b>DiagArray<T></b> (<var>int r, int c, const T &val</var>)<var><a name="index-DiagArray_003cT_003e-56"></a></var><br>
+— Constructor:  <b>DiagArray<T></b> (<var>const Array<T> &a</var>)<var><a name="index-DiagArray_003cT_003e-57"></a></var><br>
+— Constructor:  <b>DiagArray<T></b> (<var>const DiagArray<T> &a</var>)<var><a name="index-DiagArray_003cT_003e-58"></a></var><br>
+        </div>
+
+<div class="defun">
+— Assginment on DiagArray<T>&:  <b>operator =</b> (<var>const DiagArray<T> &a</var>)<var><a name="index-operator-_003d-on-DiagArray_003cT_003e_0026-59"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on DiagArray<T>: int <b>dim1</b> (<var>void</var>)<var> const<a name="index-dim1-on-DiagArray_003cT_003e-60"></a></var><br>
+— Method on DiagArray<T>: int <b>rows</b> (<var>void</var>)<var> const<a name="index-rows-on-DiagArray_003cT_003e-61"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on DiagArray<T>: int <b>dim2</b> (<var>void</var>)<var> const<a name="index-dim2-on-DiagArray_003cT_003e-62"></a></var><br>
+— Method on DiagArray<T>: int <b>cols</b> (<var>void</var>)<var> const<a name="index-cols-on-DiagArray_003cT_003e-63"></a></var><br>
+— Method on DiagArray<T>: int <b>columns</b> (<var>void</var>)<var> const<a name="index-columns-on-DiagArray_003cT_003e-64"></a></var><br>
+        </div>
+
+<div class="defun">
+— Method on DiagArray<T>: T& <b>elem</b> (<var>int r, int c</var>)<var><a name="index-elem-on-DiagArray_003cT_003e-65"></a></var><br>
+— Method on DiagArray<T>: T& <b>checkelem</b> (<var>int r, int c</var>)<var><a name="index-checkelem-on-DiagArray_003cT_003e-66"></a></var><br>
+        </div>
+
+<div class="defun">
+— Indexing on DiagArray<T>: T& <b>operator ()</b> (<var>int r, int c</var>)<var><a name="index-operator-_0028_0029-on-DiagArray_003cT_003e-67"></a></var><br>
+        </div>
+
+<!-- This needs to be fixed. -->
+<!-- T& xelem (int r, int c) -->
+<!-- T elem (int r, int c) const -->
+<!-- T checkelem (int r, int c) const -->
+<!-- T operator () (int r, int c) const -->
+<div class="defun">
+— Method on DiagArray<T>: void <b>resize</b> (<var>int n, int m</var>)<var><a name="index-resize-on-DiagArray_003cT_003e-68"></a></var><br>
+— Method on DiagArray<T>: void <b>resize</b> (<var>int n, int m, const T &val</var>)<var><a name="index-resize-on-DiagArray_003cT_003e-69"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1998, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   <p>The real and complex <code>ColumnVector</code> and <code>RowVector</code> classes
+all have the following functions.  These will eventually be part of an
+<code>MArray<T></code> class, derived from the <code>Array<T></code> class.  Then
+the <code>ColumnVector</code> and <code>RowVector</code> classes will be derived
+from the <code>MArray<T></code> class.
+
+   <p>Element by element vector by scalar ops.
+
+<div class="defun">
+— : RowVector <b>operator +</b> (<var>const RowVector &a, const double &s</var>)<var><a name="index-operator-_002b-70"></a></var><br>
+— : RowVector <b>operator -</b> (<var>const RowVector &a, const double &s</var>)<var><a name="index-operator-_002d-71"></a></var><br>
+— : RowVector <b>operator *</b> (<var>const RowVector &a, const double &s</var>)<var><a name="index-operator-_002a-72"></a></var><br>
+— : RowVector <b>operator /</b> (<var>const RowVector &a, const double &s</var>)<var><a name="index-operator-_002f-73"></a></var><br>
+        </div>
+
+   <p>Element by element scalar by vector ops.
+
+<div class="defun">
+— : RowVector <b>operator +</b> (<var>const double &s, const RowVector &a</var>)<var><a name="index-operator-_002b-74"></a></var><br>
+— : RowVector <b>operator -</b> (<var>const double &s, const RowVector &a</var>)<var><a name="index-operator-_002d-75"></a></var><br>
+— : RowVector <b>operator *</b> (<var>const double &s, const RowVector &a</var>)<var><a name="index-operator-_002a-76"></a></var><br>
+— : RowVector <b>operator /</b> (<var>const double &s, const RowVector &a</var>)<var><a name="index-operator-_002f-77"></a></var><br>
+        </div>
+
+   <p>Element by element vector by vector ops.
+
+<div class="defun">
+— : RowVector <b>operator +</b> (<var>const RowVector &a, const RowVector &b</var>)<var><a name="index-operator-_002b-78"></a></var><br>
+— : RowVector <b>operator -</b> (<var>const RowVector &a, const RowVector &b</var>)<var><a name="index-operator-_002d-79"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>product</b> (<var>const RowVector &a, const RowVector &b</var>)<var><a name="index-product-80"></a></var><br>
+— : RowVector <b>quotient</b> (<var>const RowVector &a, const RowVector &b</var>)<var><a name="index-quotient-81"></a></var><br>
+        </div>
+
+   <p>Unary MArray ops.
+
+<div class="defun">
+— : RowVector <b>operator -</b> (<var>const RowVector &a</var>)<var><a name="index-operator-_002d-82"></a></var><br>
+        </div>
+
+<!--  -->
+   <p>The <code>Matrix</code> classes share the following functions.  These will
+eventually be part of an <code>MArray2<T></code> class, derived from the
+<code>Array2<T></code> class.  Then the <code>Matrix</code> class will be derived
+from the <code>MArray<T></code> class.
+
+   <p>Element by element matrix by scalar ops.
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>const Matrix &a, const double &s</var>)<var><a name="index-operator-_002b-83"></a></var><br>
+— : Matrix <b>operator -</b> (<var>const Matrix &a, const double &s</var>)<var><a name="index-operator-_002d-84"></a></var><br>
+— : Matrix <b>operator *</b> (<var>const Matrix &a, const double &s</var>)<var><a name="index-operator-_002a-85"></a></var><br>
+— : Matrix <b>operator /</b> (<var>const Matrix &a, const double &s</var>)<var><a name="index-operator-_002f-86"></a></var><br>
+        </div>
+
+   <p>Element by element scalar by matrix ops.
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>const double &s, const Matrix &a</var>)<var><a name="index-operator-_002b-87"></a></var><br>
+— : Matrix <b>operator -</b> (<var>const double &s, const Matrix &a</var>)<var><a name="index-operator-_002d-88"></a></var><br>
+— : Matrix <b>operator *</b> (<var>const double &s, const Matrix &a</var>)<var><a name="index-operator-_002a-89"></a></var><br>
+— : Matrix <b>operator /</b> (<var>const double &s, const Matrix &a</var>)<var><a name="index-operator-_002f-90"></a></var><br>
+        </div>
+
+   <p>Element by element matrix by matrix ops.
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>const Matrix &a, const Matrix &b</var>)<var><a name="index-operator-_002b-91"></a></var><br>
+— : Matrix <b>operator -</b> (<var>const Matrix &a, const Matrix &b</var>)<var><a name="index-operator-_002d-92"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>product</b> (<var>const Matrix &a, const Matrix &b</var>)<var><a name="index-product-93"></a></var><br>
+— : Matrix <b>quotient</b> (<var>const Matrix &a, const Matrix &b</var>)<var><a name="index-quotient-94"></a></var><br>
+        </div>
+
+   <p>Unary matrix ops.
+
+<div class="defun">
+— : Matrix <b>operator -</b> (<var>const Matrix &a</var>)<var><a name="index-operator-_002d-95"></a></var><br>
+        </div>
+
+<!--  -->
+   <p>The <code>DiagMatrix</code> classes share the following functions.  These will
+eventually be part of an <code>MDiagArray<T></code> class, derived from the
+<code>DiagArray<T></code> class.  Then the <code>DiagMatrix</code> class will be
+derived from the <code>MDiagArray<T></code> class.
+
+   <p>Element by element MDiagArray by scalar ops.
+
+<div class="defun">
+— : DiagMatrix <b>operator *</b> (<var>const DiagMatrix &a, const double &s</var>)<var><a name="index-operator-_002a-96"></a></var><br>
+— : DiagMatrix <b>operator /</b> (<var>const DiagMatrix &a, const double &s</var>)<var><a name="index-operator-_002f-97"></a></var><br>
+        </div>
+
+   <p>Element by element scalar by MDiagArray ops.
+
+<div class="defun">
+— : DiagMatrix <b>operator *</b> (<var>const double &s, const DiagMatrix &a</var>)<var><a name="index-operator-_002a-98"></a></var><br>
+        </div>
+
+   <p>Element by element MDiagArray by MDiagArray ops.
+
+<div class="defun">
+— : DiagMatrix <b>operator +</b> (<var>const DiagMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002b-99"></a></var><br>
+— : DiagMatrix <b>operator -</b> (<var>const DiagMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002d-100"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix <b>product</b> (<var>const DiagMatrix &a, const DiagMatrix &b</var>)<var><a name="index-product-101"></a></var><br>
+        </div>
+
+   <p>Unary MDiagArray ops.
+
+<div class="defun">
+— : DiagMatrix <b>operator -</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002d-102"></a></var><br>
+        </div>
+
+<!--  -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Contributors.html b/doc/liboctave/HTML/Contributors.html
new file mode 100644
index 0000000..5f350f1
--- /dev/null
+++ b/doc/liboctave/HTML/Contributors.html
@@ -0,0 +1,56 @@
+<html lang="en">
+<head>
+<title>Contributors - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Acknowledgements.html#Acknowledgements" title="Acknowledgements">
+<link rel="prev" href="Acknowledgements.html#Acknowledgements" title="Acknowledgements">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Contributors"></a>
+Previous: <a rel="previous" accesskey="p" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>,
+Up: <a rel="up" accesskey="u" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>
+<hr>
+</div>
+
+<h3 class="unnumberedsec">Contributors to Octave</h3>
+
+<p><a name="index-contributors-2"></a>
+In addition to John W. Eaton, several people have written parts
+of liboctave.  (This has been removed because it is the same as what is
+in the Octave manual.)
+
+<!-- Copyright (C) 1996, 1997, 2005, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   <p><a name="index-warranty-3"></a><a name="index-copyright-4"></a>
+
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Copying.html b/doc/liboctave/HTML/Copying.html
new file mode 100644
index 0000000..4181b2e
--- /dev/null
+++ b/doc/liboctave/HTML/Copying.html
@@ -0,0 +1,743 @@
+<html lang="en">
+<head>
+<title>Copying - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Acknowledgements.html#Acknowledgements" title="Acknowledgements">
+<link rel="next" href="Introduction.html#Introduction" title="Introduction">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Copying"></a>
+Next: <a rel="next" accesskey="n" href="Introduction.html#Introduction">Introduction</a>,
+Previous: <a rel="previous" accesskey="p" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">GNU GENERAL PUBLIC LICENSE</h2>
+
+<div align="center">Version 3, 29 June 2007</div>
+
+<pre class="display">     Copyright © 2007 Free Software Foundation, Inc. <a href="http://fsf.org/">http://fsf.org/</a>
+     
+     Everyone is permitted to copy and distribute verbatim copies of this
+     license document, but changing it is not allowed.
+</pre>
+   <h3 class="heading">Preamble</h3>
+
+<p>The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>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.
+
+   <p>The precise terms and conditions for copying, distribution and
+modification follow.
+
+<h3 class="heading">TERMS AND CONDITIONS</h3>
+
+     <ol type=1 start=0>
+<li>Definitions.
+
+     <p>“This License” refers to version 3 of the GNU General Public License.
+
+     <p>“Copyright” also means copyright-like laws that apply to other kinds
+of works, such as semiconductor masks.
+
+     <p>“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.
+
+     <p>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.
+
+     <p>A “covered work” means either the unmodified Program or a work based
+on the Program.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Source Code.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>The Corresponding Source need not include anything that users can
+regenerate automatically from other parts of the Corresponding Source.
+
+     <p>The Corresponding Source for a work in source code form is that same
+work.
+
+     <li>Basic Permissions.
+
+     <p>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.
+
+     <p>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.
+
+     <p>Conveying under any other circumstances is permitted solely under the
+conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+     <li>Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Conveying Verbatim Copies.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Conveying Modified Source Versions.
+
+     <p>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:
+
+          <ol type=a start=1>
+<li>The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+          <li>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”.
+
+          <li>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.
+
+          <li>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.
+          </ol>
+
+     <p>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.
+
+     <li>Conveying Non-Source Forms.
+
+     <p>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:
+
+          <ol type=a start=1>
+<li>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.
+
+          <li>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.
+
+          <li>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.
+
+          <li>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.
+
+          <li>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.
+
+          </ol>
+
+     <p>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.
+
+     <p>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.
+
+     <p>“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.
+
+     <p>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).
+
+     <p>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.
+
+     <p>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.
+
+     <li>Additional Terms.
+
+     <p>“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.
+
+     <p>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.
+
+     <p>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:
+
+          <ol type=a start=1>
+<li>Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+          <li>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
+
+          <li>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
+
+          <li>Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+          <li>Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+          <li>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.
+          </ol>
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Termination.
+
+     <p>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).
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Acceptance Not Required for Having Copies.
+
+     <p>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.
+
+     <li>Automatic Licensing of Downstream Recipients.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Patents.
+
+     <p>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”.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>No Surrender of Others' Freedom.
+
+     <p>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.
+
+     <li>Use with the GNU Affero General Public License.
+
+     <p>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.
+
+     <li>Revised Versions of this License.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <p>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.
+
+     <li>Disclaimer of Warranty.
+
+     <p>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.
+
+     <li>Limitation of Liability.
+
+     <p>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.
+
+     <li>Interpretation of Sections 15 and 16.
+
+     <p>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.
+
+     </ol>
+
+<h3 class="heading">END OF TERMS AND CONDITIONS</h3>
+
+<h3 class="heading">How to Apply These Terms to Your New Programs</h3>
+
+<p>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.
+
+   <p>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.
+
+<pre class="smallexample">     <var>one line to give the program's name and a brief idea of what it does.</var>
+     Copyright (C) <var>year</var> <var>name of author</var>
+     
+     This program is free software: you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation, either version 3 of the License, or (at
+     your option) any later version.
+     
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+     
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
+</pre>
+   <p>Also add information on how to contact you by electronic and paper mail.
+
+   <p>If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+<pre class="smallexample">     <var>program</var> Copyright (C) <var>year</var> <var>name of author</var>
+     This program comes with ABSOLUTELY NO WARRANTY; for details type ‘<samp><span class="samp">show w</span></samp>’.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type ‘<samp><span class="samp">show c</span></samp>’ for details.
+</pre>
+   <p>The hypothetical commands ‘<samp><span class="samp">show w</span></samp>’ and ‘<samp><span class="samp">show c</span></samp>’ 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”.
+
+   <p>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
+<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
+
+   <p>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 <a href="http://www.gnu.org/philosophy/why-not-lgpl.html">http://www.gnu.org/philosophy/why-not-lgpl.html</a>.
+
+<!-- Copyright (C) 1996, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Differential-Algebraic-Equations.html b/doc/liboctave/HTML/Differential-Algebraic-Equations.html
new file mode 100644
index 0000000..70f4d16
--- /dev/null
+++ b/doc/liboctave/HTML/Differential-Algebraic-Equations.html
@@ -0,0 +1,77 @@
+<html lang="en">
+<head>
+<title>Differential Algebraic Equations - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations" title="Ordinary Differential Equations">
+<link rel="next" href="Error-Handling.html#Error-Handling" title="Error Handling">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Differential-Algebraic-Equations"></a>
+Next: <a rel="next" accesskey="n" href="Error-Handling.html#Error-Handling">Error Handling</a>,
+Previous: <a rel="previous" accesskey="p" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">12 Differential Algebraic Equations</h2>
+
+<p><a name="index-DAE-1009"></a>
+
+<div class="defun">
+— :  <b>DAE</b> (<var>void</var>)<var><a name="index-DAE-1010"></a></var><br>
+— :  <b>DAE</b> (<var>int n</var>)<var><a name="index-DAE-1011"></a></var><br>
+— :  <b>DAE</b> (<var>const ColumnVector &x, double time, DAEFunc &f</var>)<var><a name="index-DAE-1012"></a></var><br>
+— :  <b>DAE</b> (<var>const ColumnVector &x, ColumnVector &xdot, double time, DAEFunc &f</var>)<var><a name="index-DAE-1013"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>deriv</b> (<var>void</var>)<var><a name="index-deriv-1014"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual void <b>initialize</b> (<var>const ColumnVector &x, double t</var>)<var><a name="index-initialize-1015"></a></var><br>
+— : virtual void <b>initialize</b> (<var>const ColumnVector &x, ColumnVector &xdot, double t</var>)<var><a name="index-initialize-1016"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>integrate</b> (<var>double t</var>)<var><a name="index-integrate-1017"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>integrate</b> (<var>const ColumnVector &tout, Matrix &xdot_out</var>)<var><a name="index-integrate-1018"></a></var><br>
+— : Matrix <b>integrate</b> (<var>const ColumnVector &tout, Matrix &xdot_out, const ColumnVector &tcrit</var>)<var><a name="index-integrate-1019"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1997, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Error-Handling.html b/doc/liboctave/HTML/Error-Handling.html
new file mode 100644
index 0000000..dc796bd
--- /dev/null
+++ b/doc/liboctave/HTML/Error-Handling.html
@@ -0,0 +1,50 @@
+<html lang="en">
+<head>
+<title>Error Handling - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations" title="Differential Algebraic Equations">
+<link rel="next" href="Installation.html#Installation" title="Installation">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Error-Handling"></a>
+Next: <a rel="next" accesskey="n" href="Installation.html#Installation">Installation</a>,
+Previous: <a rel="previous" accesskey="p" href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">13 Error Handling</h2>
+
+<!-- Copyright (C) 1996, 1997, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+</body></html>
+
diff --git a/doc/liboctave/HTML/Function-Index.html b/doc/liboctave/HTML/Function-Index.html
new file mode 100644
index 0000000..ff790cb
--- /dev/null
+++ b/doc/liboctave/HTML/Function-Index.html
@@ -0,0 +1,327 @@
+<html lang="en">
+<head>
+<title>Function Index - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Concept-Index.html#Concept-Index" title="Concept Index">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Function-Index"></a>
+Previous: <a rel="previous" accesskey="p" href="Concept-Index.html#Concept-Index">Concept Index</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Function Index</h2>
+
+
+
+<ul class="index-fn" compact>
+<li><a href="Ordinary-Differential-Equations.html#index-absolute_005ftolerance-990"><code>absolute_tolerance</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-absolute_005ftolerance-933"><code>absolute_tolerance</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Collocation-Weights.html#index-add_005fleft-956"><code>add_left</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Collocation-Weights.html#index-add_005fright-957"><code>add_right</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-Factorizations.html#index-AEPBALANCE-626"><code>AEPBALANCE</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-all-196"><code>all</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Collocation-Weights.html#index-alpha-970"><code>alpha</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-any-197"><code>any</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-append-121"><code>append</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-Array2_003cT_003e-23"><code>Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-Array3_003cT_003e-39"><code>Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-Array_003cT_003e-7"><code>Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-Factorizations.html#index-balanced_005fa_005fmatrix-662"><code>balanced_a_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-balanced_005fb_005fmatrix-663"><code>balanced_b_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-balanced_005fmatrix-630"><code>balanced_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-balancing_005fmatrix-631"><code>balancing_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Ranges.html#index-base-776"><code>base</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Collocation-Weights.html#index-beta-971"><code>beta</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Bounds.html#index-Bounds-832"><code>Bounds</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Constructors-and-Assignment.html#index-capacity-on-Array_003cT_003e-11"><code>capacity on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-checkelem-on-Array2_003cT_003e-35"><code>checkelem on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-checkelem-on-Array3_003cT_003e-48"><code>checkelem on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-checkelem-on-Array_003cT_003e-14"><code>checkelem on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-checkelem-on-DiagArray_003cT_003e-66"><code>checkelem on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-Factorizations.html#index-CHOL-667"><code>CHOL</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-chol_005fmatrix-672"><code>chol_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-clear_005fstop_005ftime-1004"><code>clear_stop_time</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Matrix-Factorizations.html#index-coefficient-645"><code>coefficient</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-CollocWt-948"><code>CollocWt</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Constructors-and-Assignment.html#index-cols-on-Array2_003cT_003e-32"><code>cols on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-cols-on-DiagArray_003cT_003e-63"><code>cols on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-column-133"><code>column</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-column_005fmax-211"><code>column_max</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-column_005fmax_005floc-212"><code>column_max_loc</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-column_005fmin-209"><code>column_min</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-column_005fmin_005floc-210"><code>column_min_loc</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-columns-on-Array2_003cT_003e-33"><code>columns on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-columns-on-DiagArray_003cT_003e-64"><code>columns on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-ColumnVector-215"><code>ColumnVector</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexAEPBALANCE-633"><code>ComplexAEPBALANCE</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexCHOL-674"><code>ComplexCHOL</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-ComplexColumnVector-465"><code>ComplexColumnVector</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexDET-649"><code>ComplexDET</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-ComplexDiagMatrix-557"><code>ComplexDiagMatrix</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexHESS-689"><code>ComplexHESS</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexLU-749"><code>ComplexLU</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-ComplexMatrix-340"><code>ComplexMatrix</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexQR-764"><code>ComplexQR</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-ComplexRowVector-510"><code>ComplexRowVector</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexSCHUR-705"><code>ComplexSCHUR</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-ComplexSVD-722"><code>ComplexSVD</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-conj-383"><code>conj</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Linear-Constraints.html#index-constraint_005fmatrix-862"><code>constraint_matrix</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-copy-983"><code>copy</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-copy-929"><code>copy</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Nonlinear-Equations.html#index-copy-804"><code>copy</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-cumprod-198"><code>cumprod</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-cumsum-199"><code>cumsum</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Differential-Algebraic-Equations.html#index-DAE-1010"><code>DAE</code></a>: <a href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-data-on-Array_003cT_003e-22"><code>data on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Quadrature.html#index-DefQuad-935"><code>DefQuad</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Collocation-Weights.html#index-delete_005fleft-958"><code>delete_left</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Collocation-Weights.html#index-delete_005fright-959"><code>delete_right</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Differential-Algebraic-Equations.html#index-deriv-1014"><code>deriv</code></a>: <a href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a></li>
+<li><a href="Matrix-Factorizations.html#index-DET-640"><code>DET</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-determinant-140"><code>determinant</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-diag-203"><code>diag</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-DiagArray_003cT_003e-52"><code>DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-DiagMatrix-287"><code>DiagMatrix</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim1-on-Array2_003cT_003e-29"><code>dim1 on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim1-on-Array3_003cT_003e-44"><code>dim1 on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim1-on-DiagArray_003cT_003e-60"><code>dim1 on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim2-on-Array2_003cT_003e-31"><code>dim2 on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim2-on-Array3_003cT_003e-45"><code>dim2 on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim2-on-DiagArray_003cT_003e-62"><code>dim2 on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-dim3-on-Array3_003cT_003e-46"><code>dim3 on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-Factorizations.html#index-EIG-731"><code>EIG</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-eigenvalues-738"><code>eigenvalues</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-eigenvectors-739"><code>eigenvectors</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-elem-on-Array2_003cT_003e-34"><code>elem on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-elem-on-Array3_003cT_003e-47"><code>elem on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-elem-on-Array_003cT_003e-13"><code>elem on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-elem-on-DiagArray_003cT_003e-65"><code>elem on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Linear-Constraints.html#index-eq_005fconstraint_005fmatrix-864"><code>eq_constraint_matrix</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Linear-Constraints.html#index-eq_005fconstraint_005fvector-866"><code>eq_constraint_vector</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Matrix-Factorizations.html#index-exponent-646"><code>exponent</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-extract-130"><code>extract</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-fill-119"><code>fill</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Collocation-Weights.html#index-first-975"><code>first</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-force_005frestart-1001"><code>force_restart</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-fourier-138"><code>fourier</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Nonlinear-Functions.html#index-function-795"><code>function</code></a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Matrix-Factorizations.html#index-GEPBALANCE-658"><code>GEPBALANCE</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Objective-Functions.html#index-gradient_005ffunction-829"><code>gradient_function</code></a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Matrix-Factorizations.html#index-HESS-681"><code>HESS</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-hess_005fmatrix-686"><code>hess_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-ifourier-139"><code>ifourier</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-imag-382"><code>imag</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ranges.html#index-inc-778"><code>inc</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Quadrature.html#index-IndefQuad-942"><code>IndefQuad</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Linear-Constraints.html#index-ineq_005fconstraint_005fmatrix-865"><code>ineq_constraint_matrix</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Linear-Constraints.html#index-ineq_005fconstraint_005fvector-867"><code>ineq_constraint_vector</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-init-982"><code>init</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-init-928"><code>init</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Nonlinear-Equations.html#index-init-803"><code>init</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-initial_005fstep_005fsize-991"><code>initial_step_size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Differential-Algebraic-Equations.html#index-initialize-1015"><code>initialize</code></a>: <a href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-initialize-1002"><code>initialize</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-insert-115"><code>insert</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Differential-Algebraic-Equations.html#index-integrate-1017"><code>integrate</code></a>: <a href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-integrate-1005"><code>integrate</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-integrate-921"><code>integrate</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-inverse-135"><code>inverse</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Nonlinear-Functions.html#index-jacobian_005ffunction-797"><code>jacobian_function</code></a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Matrix-Factorizations.html#index-L-745"><code>L</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-left-967"><code>left</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-Factorizations.html#index-left_005fbalancing_005fmatrix-664"><code>left_balancing_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-left_005fincluded-965"><code>left_included</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-Factorizations.html#index-left_005fsingular_005fmatrix-719"><code>left_singular_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-length-on-Array_003cT_003e-12"><code>length on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Ranges.html#index-limit-777"><code>limit</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Linear-Constraints.html#index-LinConst-854"><code>LinConst</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Bounds.html#index-lower_005fbound-838"><code>lower_bound</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Bounds.html#index-lower_005fbounds-840"><code>lower_bounds</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-lssolve-155"><code>lssolve</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-LU-741"><code>LU</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-map-194"><code>map</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-Matrix-105"><code>Matrix</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ranges.html#index-max-784"><code>max</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-max-248"><code>max</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-maximum_005fstep_005fsize-992"><code>maximum_step_size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Ranges.html#index-min-783"><code>min</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-min-247"><code>min</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Nonlinear-Programming.html#index-minimize-908"><code>minimize</code></a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Quadratic-Programming.html#index-minimize-886"><code>minimize</code></a>: <a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-minimum_005fstep_005fsize-993"><code>minimum_step_size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Collocation-Weights.html#index-ncol-964"><code>ncol</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Ranges.html#index-nelem-782"><code>nelem</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Nonlinear-Constraints.html#index-NLConst-870"><code>NLConst</code></a>: <a href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a></li>
+<li><a href="Nonlinear-Equations.html#index-NLEqn-808"><code>NLEqn</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Nonlinear-Equations.html#index-NLEqn_005foptions-800"><code>NLEqn_options</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Nonlinear-Functions.html#index-NLFunc-790"><code>NLFunc</code></a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Nonlinear-Programming.html#index-NLP-897"><code>NLP</code></a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Objective-Functions.html#index-Objective-822"><code>Objective</code></a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Objective-Functions.html#index-objective_005ffunction-827"><code>objective_function</code></a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-ODE-995"><code>ODE</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-ODE_005foptions-979"><code>ODE_options</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_0021-171"><code>operator !</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_0021_003d-114"><code>operator !=</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_0028_0029-on-Array2_003cT_003e-36"><code>operator () on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_0028_0029-on-Array3_003cT_003e-49"><code>operator () on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_0028_0029-on-Array_003cT_003e-15"><code>operator () on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_0028_0029-on-DiagArray_003cT_003e-67"><code>operator () on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_002a-174"><code>operator *</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_002a-72"><code>operator *</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_002b-172"><code>operator +</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_002b-70"><code>operator +</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_002b_003d-167"><code>operator +=</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_002d-173"><code>operator -</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_002d-71"><code>operator -</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_002d_003d-168"><code>operator -=</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_002f-175"><code>operator /</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_002f-73"><code>operator /</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Collocation-Weights.html#index-operator-_003c_003c-977"><code>operator <<</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Linear-Constraints.html#index-operator-_003c_003c-868"><code>operator <<</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Bounds.html#index-operator-_003c_003c-852"><code>operator <<</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Ranges.html#index-operator-_003c_003c-786"><code>operator <<</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-Factorizations.html#index-operator-_003c_003c-632"><code>operator <<</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_003c_003c-213"><code>operator <<</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-operator-_003d-981"><code>operator =</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Collocation-Weights.html#index-operator-_003d-954"><code>operator =</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Quadrature.html#index-operator-_003d-927"><code>operator =</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Nonlinear-Programming.html#index-operator-_003d-906"><code>operator =</code></a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Nonlinear-Constraints.html#index-operator-_003d-874"><code>operator =</code></a>: <a href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a></li>
+<li><a href="Linear-Constraints.html#index-operator-_003d-860"><code>operator =</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Bounds.html#index-operator-_003d-836"><code>operator =</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Objective-Functions.html#index-operator-_003d-826"><code>operator =</code></a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Nonlinear-Equations.html#index-operator-_003d-802"><code>operator =</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Nonlinear-Functions.html#index-operator-_003d-794"><code>operator =</code></a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Matrix-Factorizations.html#index-operator-_003d-629"><code>operator =</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_003d-112"><code>operator =</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_003d-on-Array2_003cT_003e-28"><code>operator = on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_003d-on-Array3_003cT_003e-43"><code>operator = on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_003d-on-Array_003cT_003e-10"><code>operator = on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-operator-_003d-on-DiagArray_003cT_003e_0026-59"><code>operator = on DiagArray<T>&</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_003d_003d-113"><code>operator ==</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ranges.html#index-operator-_003e_003e-787"><code>operator >></code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-operator-_003e_003e-214"><code>operator >></code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-P-747"><code>P</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Ranges.html#index-print_005frange-788"><code>print_range</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-prod-200"><code>prod</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-product-192"><code>product</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-product-80"><code>product</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-Factorizations.html#index-Q-761"><code>Q</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Quadratic-Programming.html#index-QP-877"><code>QP</code></a>: <a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a></li>
+<li><a href="Matrix-Factorizations.html#index-QR-757"><code>QR</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-quad-973"><code>quad</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Quadrature.html#index-Quad-919"><code>Quad</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Quadrature.html#index-Quad_005foptions-925"><code>Quad_options</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Collocation-Weights.html#index-quad_005fweights-974"><code>quad_weights</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-quotient-193"><code>quotient</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-quotient-81"><code>quotient</code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-Factorizations.html#index-R-762"><code>R</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Ranges.html#index-Range-772"><code>Range</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-real-381"><code>real</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-relative_005ftolerance-994"><code>relative_tolerance</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-relative_005ftolerance-934"><code>relative_tolerance</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Collocation-Weights.html#index-resize-955"><code>resize</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Linear-Constraints.html#index-resize-861"><code>resize</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Bounds.html#index-resize-837"><code>resize</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Nonlinear-Equations.html#index-resize-812"><code>resize</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-resize-on-Array2_003cT_003e-37"><code>resize on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-resize-on-Array3_003cT_003e-50"><code>resize on Array3<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-resize-on-Array_003cT_003e-21"><code>resize on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-resize-on-DiagArray_003cT_003e-68"><code>resize on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Collocation-Weights.html#index-right-968"><code>right</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-Factorizations.html#index-right_005fbalancing_005fmatrix-665"><code>right_balancing_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-right_005fincluded-966"><code>right_included</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-Factorizations.html#index-right_005fsingular_005fmatrix-720"><code>right_singular_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-roots-972"><code>roots</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-row-131"><code>row</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-row_005fmax-207"><code>row_max</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-row_005fmax_005floc-208"><code>row_max_loc</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-row_005fmin-205"><code>row_min</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-row_005fmin_005floc-206"><code>row_min_loc</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Constructors-and-Assignment.html#index-rows-on-Array2_003cT_003e-30"><code>rows on Array2<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Constructors-and-Assignment.html#index-rows-on-DiagArray_003cT_003e-61"><code>rows on DiagArray<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-RowVector-250"><code>RowVector</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-SCHUR-697"><code>SCHUR</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-schur_005fmatrix-702"><code>schur_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-second-976"><code>second</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005fabsolute_005ftolerance-985"><code>set_absolute_tolerance</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-set_005fabsolute_005ftolerance-931"><code>set_absolute_tolerance</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Collocation-Weights.html#index-set_005falpha-962"><code>set_alpha</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Ranges.html#index-set_005fbase-779"><code>set_base</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Collocation-Weights.html#index-set_005fbeta-963"><code>set_beta</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Bounds.html#index-set_005fbound-843"><code>set_bound</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Bounds.html#index-set_005fbounds-844"><code>set_bounds</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Linear-Constraints.html#index-set_005fconstraint_005fmatrix-863"><code>set_constraint_matrix</code></a>: <a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005fdefault_005foptions-984"><code>set_default_options</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-set_005fdefault_005foptions-930"><code>set_default_options</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Nonlinear-Equations.html#index-set_005fdefault_005foptions-805"><code>set_default_options</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Nonlinear-Functions.html#index-set_005ffunction-796"><code>set_function</code></a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Objective-Functions.html#index-set_005fgradient_005ffunction-830"><code>set_gradient_function</code></a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Ranges.html#index-set_005finc-781"><code>set_inc</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005finitial_005fstep_005fsize-986"><code>set_initial_step_size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Nonlinear-Functions.html#index-set_005fjacobian_005ffunction-798"><code>set_jacobian_function</code></a>: <a href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a></li>
+<li><a href="Collocation-Weights.html#index-set_005fleft-960"><code>set_left</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Ranges.html#index-set_005flimit-780"><code>set_limit</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Bounds.html#index-set_005flower_005fbound-846"><code>set_lower_bound</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Bounds.html#index-set_005flower_005fbounds-848"><code>set_lower_bounds</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005fmaximum_005fstep_005fsize-987"><code>set_maximum_step_size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005fminimum_005fstep_005fsize-988"><code>set_minimum_step_size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Objective-Functions.html#index-set_005fobjective_005ffunction-828"><code>set_objective_function</code></a>: <a href="Objective-Functions.html#Objective-Functions">Objective Functions</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005frelative_005ftolerance-989"><code>set_relative_tolerance</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Quadrature.html#index-set_005frelative_005ftolerance-932"><code>set_relative_tolerance</code></a>: <a href="Quadrature.html#Quadrature">Quadrature</a></li>
+<li><a href="Collocation-Weights.html#index-set_005fright-961"><code>set_right</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Nonlinear-Equations.html#index-set_005fstates-813"><code>set_states</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-set_005fstop_005ftime-1003"><code>set_stop_time</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Nonlinear-Equations.html#index-set_005ftolerance-806"><code>set_tolerance</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Bounds.html#index-set_005fupper_005fbound-847"><code>set_upper_bound</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Bounds.html#index-set_005fupper_005fbounds-849"><code>set_upper_bounds</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Matrix-Factorizations.html#index-singular_005fvalues-718"><code>singular_values</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-size-998"><code>size</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Nonlinear-Programming.html#index-size-907"><code>size</code></a>: <a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a></li>
+<li><a href="Bounds.html#index-size-842"><code>size</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Nonlinear-Equations.html#index-size-815"><code>size</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Nonlinear-Equations.html#index-solve-816"><code>solve</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-solve-143"><code>solve</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ranges.html#index-sort-785"><code>sort</code></a>: <a href="Ranges.html#Ranges">Ranges</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-stack-125"><code>stack</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-state-999"><code>state</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Nonlinear-Equations.html#index-states-814"><code>states</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-sum-201"><code>sum</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-sumsq-202"><code>sumsq</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-SVD-713"><code>SVD</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Ordinary-Differential-Equations.html#index-time-1000"><code>time</code></a>: <a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a></li>
+<li><a href="Nonlinear-Equations.html#index-tolerance-807"><code>tolerance</code></a>: <a href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a></li>
+<li><a href="Matrix-and-Vector-Operations.html#index-transpose-129"><code>transpose</code></a>: <a href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a></li>
+<li><a href="Matrix-Factorizations.html#index-U-746"><code>U</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-unitary_005fhess_005fmatrix-687"><code>unitary_hess_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-unitary_005fmatrix-703"><code>unitary_matrix</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Bounds.html#index-upper_005fbound-839"><code>upper_bound</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Bounds.html#index-upper_005fbounds-841"><code>upper_bounds</code></a>: <a href="Bounds.html#Bounds">Bounds</a></li>
+<li><a href="Matrix-Factorizations.html#index-value-647"><code>value</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-value_005fwill_005foverflow-643"><code>value_will_overflow</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Matrix-Factorizations.html#index-value_005fwill_005funderflow-644"><code>value_will_underflow</code></a>: <a href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a></li>
+<li><a href="Collocation-Weights.html#index-width-969"><code>width</code></a>: <a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a></li>
+<li><a href="Constructors-and-Assignment.html#index-xelem-on-Array_003cT_003e-19"><code>xelem on Array<T></code></a>: <a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a></li>
+   </ul></body></html>
+
diff --git a/doc/liboctave/HTML/Installation.html b/doc/liboctave/HTML/Installation.html
new file mode 100644
index 0000000..795e942
--- /dev/null
+++ b/doc/liboctave/HTML/Installation.html
@@ -0,0 +1,52 @@
+<html lang="en">
+<head>
+<title>Installation - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Error-Handling.html#Error-Handling" title="Error Handling">
+<link rel="next" href="Bugs.html#Bugs" title="Bugs">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Installation"></a>
+Next: <a rel="next" accesskey="n" href="Bugs.html#Bugs">Bugs</a>,
+Previous: <a rel="previous" accesskey="p" href="Error-Handling.html#Error-Handling">Error Handling</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">14 Installation</h2>
+
+<p><a name="index-installation-1020"></a>
+
+<!-- Copyright (C) 1996, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Introduction.html b/doc/liboctave/HTML/Introduction.html
new file mode 100644
index 0000000..a0bcf9a
--- /dev/null
+++ b/doc/liboctave/HTML/Introduction.html
@@ -0,0 +1,54 @@
+<html lang="en">
+<head>
+<title>Introduction - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Copying.html#Copying" title="Copying">
+<link rel="next" href="Arrays.html#Arrays" title="Arrays">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Introduction"></a>
+Next: <a rel="next" accesskey="n" href="Arrays.html#Arrays">Arrays</a>,
+Previous: <a rel="previous" accesskey="p" href="Copying.html#Copying">Copying</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">2 A Brief Introduction to Octave</h2>
+
+<p><a name="index-introduction-5"></a>
+This manual documents how to run, install and port Octave's C++ classes,
+and how to report bugs.
+
+<!-- Copyright (C) 1996, 1998, 2002, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Linear-Constraints.html b/doc/liboctave/HTML/Linear-Constraints.html
new file mode 100644
index 0000000..5c1b779
--- /dev/null
+++ b/doc/liboctave/HTML/Linear-Constraints.html
@@ -0,0 +1,80 @@
+<html lang="en">
+<head>
+<title>Linear Constraints - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Bounds.html#Bounds" title="Bounds">
+<link rel="next" href="Nonlinear-Constraints.html#Nonlinear-Constraints" title="Nonlinear Constraints">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Linear-Constraints"></a>
+Next: <a rel="next" accesskey="n" href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a>,
+Previous: <a rel="previous" accesskey="p" href="Bounds.html#Bounds">Bounds</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">9.3 Linear Constraints</h3>
+
+<p><a name="index-linear-Constraints-853"></a>
+
+<div class="defun">
+— :  <b>LinConst</b> (<var>void</var>)<var><a name="index-LinConst-854"></a></var><br>
+— :  <b>LinConst</b> (<var>int nclin, int nx</var>)<var><a name="index-LinConst-855"></a></var><br>
+— :  <b>LinConst</b> (<var>int nclin_eq, int nclin_ineq, int nx</var>)<var><a name="index-LinConst-856"></a></var><br>
+— :  <b>LinConst</b> (<var>const ColumnVector &lb, const Matrix &A, const ColumnVector &ub</var>)<var><a name="index-LinConst-857"></a></var><br>
+— :  <b>LinConst</b> (<var>const Matrix &A_eq, const ColumnVector &b_eq, const Matrix &A_ineq, const ColumnVector &b_ineq</var>)<var><a name="index-LinConst-858"></a></var><br>
+— :  <b>LinConst</b> (<var>const LinConst &a</var>)<var><a name="index-LinConst-859"></a></var><br>
+        </div>
+
+<div class="defun">
+— : LinConst& <b>operator =</b> (<var>const LinConst &a</var>)<var><a name="index-operator-_003d-860"></a></var><br>
+        </div>
+
+<div class="defun">
+— : LinConst& <b>resize</b> (<var>int nclin, int n</var>)<var><a name="index-resize-861"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>constraint_matrix</b> (<var>void</var>)<var> const;<a name="index-constraint_005fmatrix-862"></a></var><br>
+        </div>
+
+<div class="defun">
+— : LinConst& <b>set_constraint_matrix</b> (<var>const Matrix &A</var>)<var><a name="index-set_005fconstraint_005fmatrix-863"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>eq_constraint_matrix</b> (<var>void</var>)<var> const;<a name="index-eq_005fconstraint_005fmatrix-864"></a></var><br>
+— : Matrix <b>ineq_constraint_matrix</b> (<var>void</var>)<var> const;<a name="index-ineq_005fconstraint_005fmatrix-865"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>eq_constraint_vector</b> (<var>void</var>)<var> const;<a name="index-eq_005fconstraint_005fvector-866"></a></var><br>
+— : ColumnVector <b>ineq_constraint_vector</b> (<var>void</var>)<var> const;<a name="index-ineq_005fconstraint_005fvector-867"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const LinConst &b</var>)<var><a name="index-operator-_003c_003c-868"></a></var><br>
+        </div>
+
+<!--  -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Matrix-Factorizations.html b/doc/liboctave/HTML/Matrix-Factorizations.html
new file mode 100644
index 0000000..0114f63
--- /dev/null
+++ b/doc/liboctave/HTML/Matrix-Factorizations.html
@@ -0,0 +1,422 @@
+<html lang="en">
+<head>
+<title>Matrix Factorizations - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations" title="Matrix and Vector Operations">
+<link rel="next" href="Ranges.html#Ranges" title="Ranges">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrix-Factorizations"></a>
+Next: <a rel="next" accesskey="n" href="Ranges.html#Ranges">Ranges</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">5 Matrix Factorizations</h2>
+
+<p><a name="index-matrix-factorizations-624"></a><a name="index-factorizations-625"></a>
+
+<div class="defun">
+— :  <b>AEPBALANCE</b> (<var>void</var>)<var><a name="index-AEPBALANCE-626"></a></var><br>
+— :  <b>AEPBALANCE</b> (<var>const Matrix &a, const char *balance_job</var>)<var><a name="index-AEPBALANCE-627"></a></var><br>
+— :  <b>AEPBALANCE</b> (<var>const AEPBALANCE &a</var>)<var><a name="index-AEPBALANCE-628"></a></var><br>
+        </div>
+
+<div class="defun">
+— : AEPBALANCE& <b>operator =</b> (<var>const AEPBALANCE &a</var>)<var><a name="index-operator-_003d-629"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>balanced_matrix</b> (<var>void</var>)<var> const<a name="index-balanced_005fmatrix-630"></a></var><br>
+— : Matrix <b>balancing_matrix</b> (<var>void</var>)<var> const<a name="index-balancing_005fmatrix-631"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const AEPBALANCE &a</var>)<var><a name="index-operator-_003c_003c-632"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexAEPBALANCE</b> (<var>void</var>)<var><a name="index-ComplexAEPBALANCE-633"></a></var><br>
+— :  <b>ComplexAEPBALANCE</b> (<var>const ComplexMatrix &a, const char *balance_job</var>)<var><a name="index-ComplexAEPBALANCE-634"></a></var><br>
+— :  <b>ComplexAEPBALANCE</b> (<var>const ComplexAEPBALANCE &a</var>)<var><a name="index-ComplexAEPBALANCE-635"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexAEPBALANCE& <b>operator =</b> (<var>const ComplexAEPBALANCE &a</var>)<var><a name="index-operator-_003d-636"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>balanced_matrix</b> (<var>void</var>)<var> const<a name="index-balanced_005fmatrix-637"></a></var><br>
+— : ComplexMatrix <b>balancing_matrix</b> (<var>void</var>)<var> const<a name="index-balancing_005fmatrix-638"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexAEPBALANCE &a</var>)<var><a name="index-operator-_003c_003c-639"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>DET</b> (<var>void</var>)<var><a name="index-DET-640"></a></var><br>
+— :  <b>DET</b> (<var>const DET &a</var>)<var><a name="index-DET-641"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DET& <b>operator =</b> (<var>const DET &a</var>)<var><a name="index-operator-_003d-642"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>value_will_overflow</b> (<var>void</var>)<var> const<a name="index-value_005fwill_005foverflow-643"></a></var><br>
+— : int <b>value_will_underflow</b> (<var>void</var>)<var> const<a name="index-value_005fwill_005funderflow-644"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>coefficient</b> (<var>void</var>)<var> const<a name="index-coefficient-645"></a></var><br>
+— : int <b>exponent</b> (<var>void</var>)<var> const<a name="index-exponent-646"></a></var><br>
+— : double <b>value</b> (<var>void</var>)<var> const<a name="index-value-647"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const DET &a</var>)<var><a name="index-operator-_003c_003c-648"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexDET</b> (<var>void</var>)<var><a name="index-ComplexDET-649"></a></var><br>
+— :  <b>ComplexDET</b> (<var>const ComplexDET &a</var>)<var><a name="index-ComplexDET-650"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDET& <b>operator =</b> (<var>const ComplexDET &a</var>)<var><a name="index-operator-_003d-651"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>value_will_overflow</b> (<var>void</var>)<var> const<a name="index-value_005fwill_005foverflow-652"></a></var><br>
+— : int <b>value_will_underflow</b> (<var>void</var>)<var> const<a name="index-value_005fwill_005funderflow-653"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Complex <b>coefficient</b> (<var>void</var>)<var> const<a name="index-coefficient-654"></a></var><br>
+— : int <b>exponent</b> (<var>void</var>)<var> const<a name="index-exponent-655"></a></var><br>
+— : Complex <b>value</b> (<var>void</var>)<var> const<a name="index-value-656"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexDET &a</var>)<var><a name="index-operator-_003c_003c-657"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>GEPBALANCE</b> (<var>void</var>)<var><a name="index-GEPBALANCE-658"></a></var><br>
+— :  <b>GEPBALANCE</b> (<var>const Matrix &a, const Matrix &, const char *balance_job</var>)<var><a name="index-GEPBALANCE-659"></a></var><br>
+— :  <b>GEPBALANCE</b> (<var>const GEPBALANCE &a</var>)<var><a name="index-GEPBALANCE-660"></a></var><br>
+        </div>
+
+<div class="defun">
+— : GEPBALANCE& <b>operator =</b> (<var>const GEPBALANCE &a</var>)<var><a name="index-operator-_003d-661"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>balanced_a_matrix</b> (<var>void</var>)<var> const<a name="index-balanced_005fa_005fmatrix-662"></a></var><br>
+— : Matrix <b>balanced_b_matrix</b> (<var>void</var>)<var> const<a name="index-balanced_005fb_005fmatrix-663"></a></var><br>
+— : Matrix <b>left_balancing_matrix</b> (<var>void</var>)<var> const<a name="index-left_005fbalancing_005fmatrix-664"></a></var><br>
+— : Matrix <b>right_balancing_matrix</b> (<var>void</var>)<var> const<a name="index-right_005fbalancing_005fmatrix-665"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const GEPBALANCE &a</var>)<var><a name="index-operator-_003c_003c-666"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>CHOL</b> (<var>void</var>)<var><a name="index-CHOL-667"></a></var><br>
+— :  <b>CHOL</b> (<var>const Matrix &a</var>)<var><a name="index-CHOL-668"></a></var><br>
+— :  <b>CHOL</b> (<var>const Matrix &a, int &info</var>)<var><a name="index-CHOL-669"></a></var><br>
+— :  <b>CHOL</b> (<var>const CHOL &a</var>)<var><a name="index-CHOL-670"></a></var><br>
+        </div>
+
+<div class="defun">
+— : CHOL& <b>operator =</b> (<var>const CHOL &a</var>)<var><a name="index-operator-_003d-671"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>chol_matrix</b> (<var>void</var>)<var> const<a name="index-chol_005fmatrix-672"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const CHOL &a</var>)<var><a name="index-operator-_003c_003c-673"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexCHOL</b> (<var>void</var>)<var><a name="index-ComplexCHOL-674"></a></var><br>
+— :  <b>ComplexCHOL</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-ComplexCHOL-675"></a></var><br>
+— :  <b>ComplexCHOL</b> (<var>const ComplexMatrix &a, int &info</var>)<var><a name="index-ComplexCHOL-676"></a></var><br>
+— :  <b>ComplexCHOL</b> (<var>const ComplexCHOL &a</var>)<var><a name="index-ComplexCHOL-677"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexCHOL& <b>operator =</b> (<var>const ComplexCHOL &a</var>)<var><a name="index-operator-_003d-678"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>chol_matrix</b> (<var>void</var>)<var> const<a name="index-chol_005fmatrix-679"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexCHOL &a</var>)<var><a name="index-operator-_003c_003c-680"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>HESS</b> (<var>void</var>)<var><a name="index-HESS-681"></a></var><br>
+— :  <b>HESS</b> (<var>const Matrix &a</var>)<var><a name="index-HESS-682"></a></var><br>
+— :  <b>HESS</b> (<var>const Matrix&a, int &info</var>)<var><a name="index-HESS-683"></a></var><br>
+— :  <b>HESS</b> (<var>const HESS &a</var>)<var><a name="index-HESS-684"></a></var><br>
+        </div>
+
+<div class="defun">
+— : HESS& <b>operator =</b> (<var>const HESS &a</var>)<var><a name="index-operator-_003d-685"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>hess_matrix</b> (<var>void</var>)<var> const<a name="index-hess_005fmatrix-686"></a></var><br>
+— : Matrix <b>unitary_hess_matrix</b> (<var>void</var>)<var> const<a name="index-unitary_005fhess_005fmatrix-687"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const HESS &a</var>)<var><a name="index-operator-_003c_003c-688"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexHESS</b> (<var>void</var>)<var><a name="index-ComplexHESS-689"></a></var><br>
+— :  <b>ComplexHESS</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-ComplexHESS-690"></a></var><br>
+— :  <b>ComplexHESS</b> (<var>const ComplexMatrix &a, int &info</var>)<var><a name="index-ComplexHESS-691"></a></var><br>
+— :  <b>ComplexHESS</b> (<var>const ComplexHESS &a</var>)<var><a name="index-ComplexHESS-692"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexHESS& <b>operator =</b> (<var>const ComplexHESS &a</var>)<var><a name="index-operator-_003d-693"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>hess_matrix</b> (<var>void</var>)<var> const<a name="index-hess_005fmatrix-694"></a></var><br>
+— : ComplexMatrix <b>unitary_hess_matrix</b> (<var>void</var>)<var> const<a name="index-unitary_005fhess_005fmatrix-695"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexHESS &a</var>)<var><a name="index-operator-_003c_003c-696"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>SCHUR</b> (<var>void</var>)<var><a name="index-SCHUR-697"></a></var><br>
+— :  <b>SCHUR</b> (<var>const Matrix &a, const char *ord</var>)<var><a name="index-SCHUR-698"></a></var><br>
+— :  <b>SCHUR</b> (<var>const Matrix &a, const char *ord, int &info</var>)<var><a name="index-SCHUR-699"></a></var><br>
+— :  <b>SCHUR</b> (<var>const SCHUR &a, const char *ord</var>)<var><a name="index-SCHUR-700"></a></var><br>
+        </div>
+
+<div class="defun">
+— : SCHUR& <b>operator =</b> (<var>const SCHUR &a</var>)<var><a name="index-operator-_003d-701"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>schur_matrix</b> (<var>void</var>)<var> const<a name="index-schur_005fmatrix-702"></a></var><br>
+— : Matrix <b>unitary_matrix</b> (<var>void</var>)<var> const<a name="index-unitary_005fmatrix-703"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const SCHUR &a</var>)<var><a name="index-operator-_003c_003c-704"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexSCHUR</b> (<var>void</var>)<var><a name="index-ComplexSCHUR-705"></a></var><br>
+— :  <b>ComplexSCHUR</b> (<var>const ComplexMatrix &a, const char *ord</var>)<var><a name="index-ComplexSCHUR-706"></a></var><br>
+— :  <b>ComplexSCHUR</b> (<var>const ComplexMatrix &a, const char *ord, int &info</var>)<var><a name="index-ComplexSCHUR-707"></a></var><br>
+— :  <b>ComplexSCHUR</b> (<var>const ComplexSCHUR &a, const char *ord</var>)<var><a name="index-ComplexSCHUR-708"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexSCHUR& <b>operator =</b> (<var>const ComplexSCHUR &a</var>)<var><a name="index-operator-_003d-709"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>schur_matrix</b> (<var>void</var>)<var> const<a name="index-schur_005fmatrix-710"></a></var><br>
+— : ComplexMatrix <b>unitary_matrix</b> (<var>void</var>)<var> const<a name="index-unitary_005fmatrix-711"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexSCHUR &a</var>)<var><a name="index-operator-_003c_003c-712"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>SVD</b> (<var>void</var>)<var><a name="index-SVD-713"></a></var><br>
+— :  <b>SVD</b> (<var>const Matrix &a</var>)<var><a name="index-SVD-714"></a></var><br>
+— :  <b>SVD</b> (<var>const Matrix &a, int &info</var>)<var><a name="index-SVD-715"></a></var><br>
+— :  <b>SVD</b> (<var>const SVD &a</var>)<var><a name="index-SVD-716"></a></var><br>
+        </div>
+
+<div class="defun">
+— : SVD& <b>operator =</b> (<var>const SVD &a</var>)<var><a name="index-operator-_003d-717"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix <b>singular_values</b> (<var>void</var>)<var> const<a name="index-singular_005fvalues-718"></a></var><br>
+— : Matrix <b>left_singular_matrix</b> (<var>void</var>)<var> const<a name="index-left_005fsingular_005fmatrix-719"></a></var><br>
+— : Matrix <b>right_singular_matrix</b> (<var>void</var>)<var> const<a name="index-right_005fsingular_005fmatrix-720"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const SVD &a</var>)<var><a name="index-operator-_003c_003c-721"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexSVD</b> (<var>void</var>)<var><a name="index-ComplexSVD-722"></a></var><br>
+— :  <b>ComplexSVD</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-ComplexSVD-723"></a></var><br>
+— :  <b>ComplexSVD</b> (<var>const ComplexMatrix &a, int &info</var>)<var><a name="index-ComplexSVD-724"></a></var><br>
+— :  <b>ComplexSVD</b> (<var>const ComplexSVD &a</var>)<var><a name="index-ComplexSVD-725"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexSVD& <b>operator =</b> (<var>const ComplexSVD &a</var>)<var><a name="index-operator-_003d-726"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix <b>singular_values</b> (<var>void</var>)<var> const<a name="index-singular_005fvalues-727"></a></var><br>
+— : ComplexMatrix <b>left_singular_matrix</b> (<var>void</var>)<var> const<a name="index-left_005fsingular_005fmatrix-728"></a></var><br>
+— : ComplexMatrix <b>right_singular_matrix</b> (<var>void</var>)<var> const<a name="index-right_005fsingular_005fmatrix-729"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexSVD &a</var>)<var><a name="index-operator-_003c_003c-730"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>EIG</b> (<var>void</var>)<var><a name="index-EIG-731"></a></var><br>
+— :  <b>EIG</b> (<var>const Matrix &a</var>)<var><a name="index-EIG-732"></a></var><br>
+— :  <b>EIG</b> (<var>const Matrix &a, int &info</var>)<var><a name="index-EIG-733"></a></var><br>
+— :  <b>EIG</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-EIG-734"></a></var><br>
+— :  <b>EIG</b> (<var>const ComplexMatrix &a, int &info</var>)<var><a name="index-EIG-735"></a></var><br>
+— :  <b>EIG</b> (<var>const EIG &a</var>)<var><a name="index-EIG-736"></a></var><br>
+        </div>
+
+<div class="defun">
+— : EIG& <b>operator =</b> (<var>const EIG &a</var>)<var><a name="index-operator-_003d-737"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>eigenvalues</b> (<var>void</var>)<var> const<a name="index-eigenvalues-738"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>eigenvectors</b> (<var>void</var>)<var> const<a name="index-eigenvectors-739"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const EIG &a</var>)<var><a name="index-operator-_003c_003c-740"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>LU</b> (<var>void</var>)<var><a name="index-LU-741"></a></var><br>
+— :  <b>LU</b> (<var>const Matrix &a</var>)<var><a name="index-LU-742"></a></var><br>
+— :  <b>LU</b> (<var>const LU &a</var>)<var><a name="index-LU-743"></a></var><br>
+        </div>
+
+<div class="defun">
+— : LU& <b>operator =</b> (<var>const LU &a</var>)<var><a name="index-operator-_003d-744"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>L</b> (<var>void</var>)<var> const<a name="index-L-745"></a></var><br>
+— : Matrix <b>U</b> (<var>void</var>)<var> const<a name="index-U-746"></a></var><br>
+— : Matrix <b>P</b> (<var>void</var>)<var> const<a name="index-P-747"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const LU &a</var>)<var><a name="index-operator-_003c_003c-748"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexLU</b> (<var>void</var>)<var><a name="index-ComplexLU-749"></a></var><br>
+— :  <b>ComplexLU</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-ComplexLU-750"></a></var><br>
+— :  <b>ComplexLU</b> (<var>const ComplexLU &a</var>)<var><a name="index-ComplexLU-751"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexLU& <b>operator =</b> (<var>const ComplexLU &a</var>)<var><a name="index-operator-_003d-752"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>L</b> (<var>void</var>)<var> const<a name="index-L-753"></a></var><br>
+— : ComplexMatrix <b>U</b> (<var>void</var>)<var> const<a name="index-U-754"></a></var><br>
+— : Matrix <b>P</b> (<var>void</var>)<var> const<a name="index-P-755"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexLU &a</var>)<var><a name="index-operator-_003c_003c-756"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>QR</b> (<var>void</var>)<var><a name="index-QR-757"></a></var><br>
+— :  <b>QR</b> (<var>const Matrix &A</var>)<var><a name="index-QR-758"></a></var><br>
+— :  <b>QR</b> (<var>const QR &a</var>)<var><a name="index-QR-759"></a></var><br>
+        </div>
+
+<div class="defun">
+— : QR& <b>operator =</b> (<var>const QR &a</var>)<var><a name="index-operator-_003d-760"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>Q</b> (<var>void</var>)<var> const<a name="index-Q-761"></a></var><br>
+— : Matrix <b>R</b> (<var>void</var>)<var> const<a name="index-R-762"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const QR &a</var>)<var><a name="index-operator-_003c_003c-763"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexQR</b> (<var>void</var>)<var><a name="index-ComplexQR-764"></a></var><br>
+— :  <b>ComplexQR</b> (<var>const ComplexMatrix &A</var>)<var><a name="index-ComplexQR-765"></a></var><br>
+— :  <b>ComplexQR</b> (<var>const ComplexQR &a</var>)<var><a name="index-ComplexQR-766"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexQR& <b>operator =</b> (<var>const ComplexQR &a</var>)<var><a name="index-operator-_003d-767"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>Q</b> (<var>void</var>)<var> const<a name="index-Q-768"></a></var><br>
+— : ComplexMatrix <b>R</b> (<var>void</var>)<var> const<a name="index-R-769"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexQR &a</var>)<var><a name="index-operator-_003c_003c-770"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Matrix-and-Vector-Operations.html b/doc/liboctave/HTML/Matrix-and-Vector-Operations.html
new file mode 100644
index 0000000..ccdb288
--- /dev/null
+++ b/doc/liboctave/HTML/Matrix-and-Vector-Operations.html
@@ -0,0 +1,1225 @@
+<html lang="en">
+<head>
+<title>Matrix and Vector Operations - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Arrays.html#Arrays" title="Arrays">
+<link rel="next" href="Matrix-Factorizations.html#Matrix-Factorizations" title="Matrix Factorizations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Matrix-and-Vector-Operations"></a>
+Next: <a rel="next" accesskey="n" href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>,
+Previous: <a rel="previous" accesskey="p" href="Arrays.html#Arrays">Arrays</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">4 Matrix and Vector Operations</h2>
+
+<p><a name="index-matrix-manipulations-103"></a><a name="index-vector-manipulations-104"></a>
+
+<div class="defun">
+— :  <b>Matrix</b> (<var>void</var>)<var><a name="index-Matrix-105"></a></var><br>
+— :  <b>Matrix</b> (<var>int r, int c</var>)<var><a name="index-Matrix-106"></a></var><br>
+— :  <b>Matrix</b> (<var>int r, int c, double val</var>)<var><a name="index-Matrix-107"></a></var><br>
+— :  <b>Matrix</b> (<var>const Array2<double> &a</var>)<var><a name="index-Matrix-108"></a></var><br>
+— :  <b>Matrix</b> (<var>const Matrix &a</var>)<var><a name="index-Matrix-109"></a></var><br>
+— :  <b>Matrix</b> (<var>const DiagArray<double> &a</var>)<var><a name="index-Matrix-110"></a></var><br>
+— :  <b>Matrix</b> (<var>const DiagMatrix &a</var>)<var><a name="index-Matrix-111"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix& <b>operator =</b> (<var>const Matrix &a</var>)<var><a name="index-operator-_003d-112"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const Matrix &a</var>)<var> const<a name="index-operator-_003d_003d-113"></a></var><br>
+— : int <b>operator !=</b> (<var>const Matrix &a</var>)<var> const<a name="index-operator-_0021_003d-114"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix& <b>insert</b> (<var>const Matrix &a, int r, int c</var>)<var><a name="index-insert-115"></a></var><br>
+— : Matrix& <b>insert</b> (<var>const RowVector &a, int r, int c</var>)<var><a name="index-insert-116"></a></var><br>
+— : Matrix& <b>insert</b> (<var>const ColumnVector &a, int r, int c</var>)<var><a name="index-insert-117"></a></var><br>
+— : Matrix& <b>insert</b> (<var>const DiagMatrix &a, int r, int c</var>)<var><a name="index-insert-118"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-119"></a></var><br>
+— : Matrix& <b>fill</b> (<var>double val, int r1, int c1, int r2, int c2</var>)<var><a name="index-fill-120"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>append</b> (<var>const Matrix &a</var>)<var> const<a name="index-append-121"></a></var><br>
+— : Matrix <b>append</b> (<var>const RowVector &a</var>)<var> const<a name="index-append-122"></a></var><br>
+— : Matrix <b>append</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-append-123"></a></var><br>
+— : Matrix <b>append</b> (<var>const DiagMatrix &a</var>)<var> const<a name="index-append-124"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>stack</b> (<var>const Matrix &a</var>)<var> const<a name="index-stack-125"></a></var><br>
+— : Matrix <b>stack</b> (<var>const RowVector &a</var>)<var> const<a name="index-stack-126"></a></var><br>
+— : Matrix <b>stack</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-stack-127"></a></var><br>
+— : Matrix <b>stack</b> (<var>const DiagMatrix &a</var>)<var> const<a name="index-stack-128"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-129"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>extract</b> (<var>int r1, int c1, int r2, int c2</var>)<var> const<a name="index-extract-130"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>row</b> (<var>int i</var>)<var> const<a name="index-row-131"></a></var><br>
+— : RowVector <b>row</b> (<var>char *s</var>)<var> const<a name="index-row-132"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>column</b> (<var>int i</var>)<var> const<a name="index-column-133"></a></var><br>
+— : ColumnVector <b>column</b> (<var>char *s</var>)<var> const<a name="index-column-134"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>inverse</b> (<var>void</var>)<var> const<a name="index-inverse-135"></a></var><br>
+— : Matrix <b>inverse</b> (<var>int &info</var>)<var> const<a name="index-inverse-136"></a></var><br>
+— : Matrix <b>inverse</b> (<var>int &info, double &rcond</var>)<var> const<a name="index-inverse-137"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>fourier</b> (<var>void</var>)<var> const<a name="index-fourier-138"></a></var><br>
+— : ComplexMatrix <b>ifourier</b> (<var>void</var>)<var> const<a name="index-ifourier-139"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DET <b>determinant</b> (<var>void</var>)<var> const<a name="index-determinant-140"></a></var><br>
+— : DET <b>determinant</b> (<var>int &info</var>)<var> const<a name="index-determinant-141"></a></var><br>
+— : DET <b>determinant</b> (<var>int &info, double &rcond</var>)<var> const<a name="index-determinant-142"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>solve</b> (<var>const Matrix &b</var>)<var> const<a name="index-solve-143"></a></var><br>
+— : Matrix <b>solve</b> (<var>const Matrix &b, int &info</var>)<var> const<a name="index-solve-144"></a></var><br>
+— : Matrix <b>solve</b> (<var>const Matrix &b, int &info, double &rcond</var>)<var> const<a name="index-solve-145"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>solve</b> (<var>const ComplexMatrix &b</var>)<var> const<a name="index-solve-146"></a></var><br>
+— : ComplexMatrix <b>solve</b> (<var>const ComplexMatrix &b, int &info</var>)<var> const<a name="index-solve-147"></a></var><br>
+— : ComplexMatrix <b>solve</b> (<var>const ComplexMatrix &b, int &info, double &rcond</var>)<var> const<a name="index-solve-148"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>solve</b> (<var>const ColumnVector &b</var>)<var> const<a name="index-solve-149"></a></var><br>
+— : ColumnVector <b>solve</b> (<var>const ColumnVector &b, int &info</var>)<var> const<a name="index-solve-150"></a></var><br>
+— : ColumnVector <b>solve</b> (<var>const ColumnVector &b, int &info, double &rcond</var>)<var> const<a name="index-solve-151"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>solve</b> (<var>const ComplexColumnVector &b</var>)<var> const<a name="index-solve-152"></a></var><br>
+— : ComplexColumnVector <b>solve</b> (<var>const ComplexColumnVector &b, int &info</var>)<var> const<a name="index-solve-153"></a></var><br>
+— : ComplexColumnVector <b>solve</b> (<var>const ComplexColumnVector &b, int &info, double &rcond</var>)<var> const<a name="index-solve-154"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>lssolve</b> (<var>const Matrix &b</var>)<var> const<a name="index-lssolve-155"></a></var><br>
+— : Matrix <b>lssolve</b> (<var>const Matrix &b, int &info</var>)<var> const<a name="index-lssolve-156"></a></var><br>
+— : Matrix <b>lssolve</b> (<var>const Matrix &b, int &info, int &rank</var>)<var> const<a name="index-lssolve-157"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>lssolve</b> (<var>const ComplexMatrix &b</var>)<var> const<a name="index-lssolve-158"></a></var><br>
+— : ComplexMatrix <b>lssolve</b> (<var>const ComplexMatrix &b, int &info</var>)<var> const<a name="index-lssolve-159"></a></var><br>
+— : ComplexMatrix <b>lssolve</b> (<var>const ComplexMatrix &b, int &info, int &rank</var>)<var> const<a name="index-lssolve-160"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>lssolve</b> (<var>const ColumnVector &b</var>)<var> const<a name="index-lssolve-161"></a></var><br>
+— : ColumnVector <b>lssolve</b> (<var>const ColumnVector &b, int &info</var>)<var> const<a name="index-lssolve-162"></a></var><br>
+— : ColumnVector <b>lssolve</b> (<var>const ColumnVector &b, int &info, int &rank</var>)<var> const<a name="index-lssolve-163"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>lssolve</b> (<var>const ComplexColumnVector &b</var>)<var> const<a name="index-lssolve-164"></a></var><br>
+— : ComplexColumnVector <b>lssolve</b> (<var>const ComplexColumnVector &b, int &info</var>)<var> const<a name="index-lssolve-165"></a></var><br>
+— : ComplexColumnVector <b>lssolve</b> (<var>const ComplexColumnVector &b, int &info, int &rank</var>)<var> const<a name="index-lssolve-166"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix& <b>operator +=</b> (<var>const Matrix &a</var>)<var><a name="index-operator-_002b_003d-167"></a></var><br>
+— : Matrix& <b>operator -=</b> (<var>const Matrix &a</var>)<var><a name="index-operator-_002d_003d-168"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix& <b>operator +=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002b_003d-169"></a></var><br>
+— : Matrix& <b>operator -=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002d_003d-170"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator !</b> (<var>void</var>)<var> const<a name="index-operator-_0021-171"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const Matrix &a, const Complex &s</var>)<var><a name="index-operator-_002b-172"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const Matrix &a, const Complex &s</var>)<var><a name="index-operator-_002d-173"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const Matrix &a, const Complex &s</var>)<var><a name="index-operator-_002a-174"></a></var><br>
+— : ComplexMatrix <b>operator /</b> (<var>const Matrix &a, const Complex &s</var>)<var><a name="index-operator-_002f-175"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const Complex &s, const Matrix &a</var>)<var><a name="index-operator-_002b-176"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const Complex &s, const Matrix &a</var>)<var><a name="index-operator-_002d-177"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const Complex &s, const Matrix &a</var>)<var><a name="index-operator-_002a-178"></a></var><br>
+— : ComplexMatrix <b>operator /</b> (<var>const Complex &s, const Matrix &a</var>)<var><a name="index-operator-_002f-179"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>operator *</b> (<var>const Matrix &a, const ColumnVector &b</var>)<var><a name="index-operator-_002a-180"></a></var><br>
+— : ComplexColumnVector <b>operator *</b> (<var>const Matrix &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002a-181"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>const Matrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002b-182"></a></var><br>
+— : Matrix <b>operator -</b> (<var>const Matrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002d-183"></a></var><br>
+— : Matrix <b>operator *</b> (<var>const Matrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002a-184"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const Matrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002b-185"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const Matrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002d-186"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const Matrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002a-187"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator *</b> (<var>const Matrix &a, const Matrix &b</var>)<var><a name="index-operator-_002a-188"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const Matrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002a-189"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const Matrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002b-190"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const Matrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002d-191"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>product</b> (<var>const Matrix &a, const ComplexMatrix &b</var>)<var><a name="index-product-192"></a></var><br>
+— : ComplexMatrix <b>quotient</b> (<var>const Matrix &a, const ComplexMatrix &b</var>)<var><a name="index-quotient-193"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>map</b> (<var>d_d_Mapper f, const Matrix &a</var>)<var><a name="index-map-194"></a></var><br>
+— : void <b>map</b> (<var>d_d_Mapper f</var>)<var><a name="index-map-195"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>all</b> (<var>void</var>)<var> const<a name="index-all-196"></a></var><br>
+— : Matrix <b>any</b> (<var>void</var>)<var> const<a name="index-any-197"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>cumprod</b> (<var>void</var>)<var> const<a name="index-cumprod-198"></a></var><br>
+— : Matrix <b>cumsum</b> (<var>void</var>)<var> const<a name="index-cumsum-199"></a></var><br>
+— : Matrix <b>prod</b> (<var>void</var>)<var> const<a name="index-prod-200"></a></var><br>
+— : Matrix <b>sum</b> (<var>void</var>)<var> const<a name="index-sum-201"></a></var><br>
+— : Matrix <b>sumsq</b> (<var>void</var>)<var> const<a name="index-sumsq-202"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>diag</b> (<var>void</var>)<var> const<a name="index-diag-203"></a></var><br>
+— : ColumnVector <b>diag</b> (<var>int k</var>)<var> const<a name="index-diag-204"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>row_min</b> (<var>void</var>)<var> const<a name="index-row_005fmin-205"></a></var><br>
+— : ColumnVector <b>row_min_loc</b> (<var>void</var>)<var> const<a name="index-row_005fmin_005floc-206"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>row_max</b> (<var>void</var>)<var> const<a name="index-row_005fmax-207"></a></var><br>
+— : ColumnVector <b>row_max_loc</b> (<var>void</var>)<var> const<a name="index-row_005fmax_005floc-208"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>column_min</b> (<var>void</var>)<var> const<a name="index-column_005fmin-209"></a></var><br>
+— : RowVector <b>column_min_loc</b> (<var>void</var>)<var> const<a name="index-column_005fmin_005floc-210"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>column_max</b> (<var>void</var>)<var> const<a name="index-column_005fmax-211"></a></var><br>
+— : RowVector <b>column_max_loc</b> (<var>void</var>)<var> const<a name="index-column_005fmax_005floc-212"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const Matrix &a</var>)<var><a name="index-operator-_003c_003c-213"></a></var><br>
+— : istream& <b>operator >></b> (<var>istream &is, Matrix &a</var>)<var><a name="index-operator-_003e_003e-214"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ColumnVector</b> (<var>void</var>)<var><a name="index-ColumnVector-215"></a></var><br>
+— :  <b>ColumnVector</b> (<var>int n</var>)<var><a name="index-ColumnVector-216"></a></var><br>
+— :  <b>ColumnVector</b> (<var>int n, double val</var>)<var><a name="index-ColumnVector-217"></a></var><br>
+— :  <b>ColumnVector</b> (<var>const Array<double> &a</var>)<var><a name="index-ColumnVector-218"></a></var><br>
+— :  <b>ColumnVector</b> (<var>const ColumnVector &a</var>)<var><a name="index-ColumnVector-219"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector& <b>operator =</b> (<var>const ColumnVector &a</var>)<var><a name="index-operator-_003d-220"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-operator-_003d_003d-221"></a></var><br>
+— : int <b>operator !=</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-operator-_0021_003d-222"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector& <b>insert</b> (<var>const ColumnVector &a, int r</var>)<var><a name="index-insert-223"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-224"></a></var><br>
+— : ColumnVector& <b>fill</b> (<var>double val, int r1, int r2</var>)<var><a name="index-fill-225"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>stack</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-stack-226"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-227"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>extract</b> (<var>int r1, int r2</var>)<var> const<a name="index-extract-228"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector& <b>operator +=</b> (<var>const ColumnVector &a</var>)<var><a name="index-operator-_002b_003d-229"></a></var><br>
+— : ColumnVector& <b>operator -=</b> (<var>const ColumnVector &a</var>)<var><a name="index-operator-_002d_003d-230"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator +</b> (<var>const ColumnVector &a, const Complex &s</var>)<var><a name="index-operator-_002b-231"></a></var><br>
+— : ComplexColumnVector <b>operator -</b> (<var>const ColumnVector &a, const Complex &s</var>)<var><a name="index-operator-_002d-232"></a></var><br>
+— : ComplexColumnVector <b>operator *</b> (<var>const ColumnVector &a, const Complex &s</var>)<var><a name="index-operator-_002a-233"></a></var><br>
+— : ComplexColumnVector <b>operator /</b> (<var>const ColumnVector &a, const Complex &s</var>)<var><a name="index-operator-_002f-234"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator +</b> (<var>const Complex &s, const ColumnVector &a</var>)<var><a name="index-operator-_002b-235"></a></var><br>
+— : ComplexColumnVector <b>operator -</b> (<var>const Complex &s, const ColumnVector &a</var>)<var><a name="index-operator-_002d-236"></a></var><br>
+— : ComplexColumnVector <b>operator *</b> (<var>const Complex &s, const ColumnVector &a</var>)<var><a name="index-operator-_002a-237"></a></var><br>
+— : ComplexColumnVector <b>operator /</b> (<var>const Complex &s, const ColumnVector &a</var>)<var><a name="index-operator-_002f-238"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator *</b> (<var>const ColumnVector &a, const RowVector &a</var>)<var><a name="index-operator-_002a-239"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator *</b> (<var>const ColumnVector &a, const ComplexRowVector &b</var>)<var><a name="index-operator-_002a-240"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator +</b> (<var>const ComplexColumnVector &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002b-241"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator -</b> (<var>const ComplexColumnVector &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002d-242"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>product</b> (<var>const ComplexColumnVector &a, const ComplexColumnVector &b</var>)<var><a name="index-product-243"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>quotient</b> (<var>const ComplexColumnVector &a, const ComplexColumnVector &b</var>)<var><a name="index-quotient-244"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>map</b> (<var>d_d_Mapper f, const ColumnVector &a</var>)<var><a name="index-map-245"></a></var><br>
+— : void <b>map</b> (<var>d_d_Mapper f</var>)<var><a name="index-map-246"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>min</b> (<var>void</var>)<var> const<a name="index-min-247"></a></var><br>
+— : double <b>max</b> (<var>void</var>)<var> const<a name="index-max-248"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ColumnVector &a</var>)<var><a name="index-operator-_003c_003c-249"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>RowVector</b> (<var>void</var>)<var><a name="index-RowVector-250"></a></var><br>
+— :  <b>RowVector</b> (<var>int n</var>)<var><a name="index-RowVector-251"></a></var><br>
+— :  <b>RowVector</b> (<var>int n, double val</var>)<var><a name="index-RowVector-252"></a></var><br>
+— :  <b>RowVector</b> (<var>const Array<double> &a</var>)<var><a name="index-RowVector-253"></a></var><br>
+— :  <b>RowVector</b> (<var>const RowVector &a</var>)<var><a name="index-RowVector-254"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector& <b>operator =</b> (<var>const RowVector &a</var>)<var><a name="index-operator-_003d-255"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const RowVector &a</var>)<var> const<a name="index-operator-_003d_003d-256"></a></var><br>
+— : int <b>operator !=</b> (<var>const RowVector &a</var>)<var> const<a name="index-operator-_0021_003d-257"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector& <b>insert</b> (<var>const RowVector &a, int c</var>)<var><a name="index-insert-258"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-259"></a></var><br>
+— : RowVector& <b>fill</b> (<var>double val, int c1, int c2</var>)<var><a name="index-fill-260"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>append</b> (<var>const RowVector &a</var>)<var> const<a name="index-append-261"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-262"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>extract</b> (<var>int c1, int c2</var>)<var> const<a name="index-extract-263"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector& <b>operator +=</b> (<var>const RowVector &a</var>)<var><a name="index-operator-_002b_003d-264"></a></var><br>
+— : RowVector& <b>operator -=</b> (<var>const RowVector &a</var>)<var><a name="index-operator-_002d_003d-265"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator +</b> (<var>const RowVector &a, const Complex &s</var>)<var><a name="index-operator-_002b-266"></a></var><br>
+— : ComplexRowVector <b>operator -</b> (<var>const RowVector &a, const Complex &s</var>)<var><a name="index-operator-_002d-267"></a></var><br>
+— : ComplexRowVector <b>operator *</b> (<var>const RowVector &a, const Complex &s</var>)<var><a name="index-operator-_002a-268"></a></var><br>
+— : ComplexRowVector <b>operator /</b> (<var>const RowVector &a, const Complex &s</var>)<var><a name="index-operator-_002f-269"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator +</b> (<var>const Complex &s, const RowVector &a</var>)<var><a name="index-operator-_002b-270"></a></var><br>
+— : ComplexRowVector <b>operator -</b> (<var>const Complex &s, const RowVector &a</var>)<var><a name="index-operator-_002d-271"></a></var><br>
+— : ComplexRowVector <b>operator *</b> (<var>const Complex &s, const RowVector &a</var>)<var><a name="index-operator-_002a-272"></a></var><br>
+— : ComplexRowVector <b>operator /</b> (<var>const Complex &s, const RowVector &a</var>)<var><a name="index-operator-_002f-273"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>operator *</b> (<var>const RowVector &a, ColumnVector &b</var>)<var><a name="index-operator-_002a-274"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Complex <b>operator *</b> (<var>const RowVector &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002a-275"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>operator *</b> (<var>const RowVector &a, const Matrix &b</var>)<var><a name="index-operator-_002a-276"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator *</b> (<var>const RowVector &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002a-277"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator +</b> (<var>const RowVector &a, const ComplexRowVector &b</var>)<var><a name="index-operator-_002b-278"></a></var><br>
+— : ComplexRowVector <b>operator -</b> (<var>const RowVector &a, const ComplexRowVector &b</var>)<var><a name="index-operator-_002d-279"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>product</b> (<var>const RowVector &a, const ComplexRowVector &b</var>)<var><a name="index-product-280"></a></var><br>
+— : ComplexRowVector <b>quotient</b> (<var>const RowVector &a, const ComplexRowVector &b</var>)<var><a name="index-quotient-281"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>map</b> (<var>d_d_Mapper f, const RowVector &a</var>)<var><a name="index-map-282"></a></var><br>
+— : void <b>map</b> (<var>d_d_Mapper f</var>)<var><a name="index-map-283"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>min</b> (<var>void</var>)<var> const<a name="index-min-284"></a></var><br>
+— : double <b>max</b> (<var>void</var>)<var> const<a name="index-max-285"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const RowVector &a</var>)<var><a name="index-operator-_003c_003c-286"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>DiagMatrix</b> (<var>void</var>)<var><a name="index-DiagMatrix-287"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>int n</var>)<var><a name="index-DiagMatrix-288"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>int n, double val</var>)<var><a name="index-DiagMatrix-289"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>int r, int c</var>)<var><a name="index-DiagMatrix-290"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>int r, int c, double val</var>)<var><a name="index-DiagMatrix-291"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>const RowVector &a</var>)<var><a name="index-DiagMatrix-292"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>const ColumnVector &a</var>)<var><a name="index-DiagMatrix-293"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>const DiagArray<double> &a</var>)<var><a name="index-DiagMatrix-294"></a></var><br>
+— :  <b>DiagMatrix</b> (<var>const DiagMatrix &a</var>)<var><a name="index-DiagMatrix-295"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix& <b>operator =</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_003d-296"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const DiagMatrix &a</var>)<var> const<a name="index-operator-_003d_003d-297"></a></var><br>
+— : int <b>operator !=</b> (<var>const DiagMatrix &a</var>)<var> const<a name="index-operator-_0021_003d-298"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-299"></a></var><br>
+— : DiagMatrix& <b>fill</b> (<var>double val, int beg, int end</var>)<var><a name="index-fill-300"></a></var><br>
+— : DiagMatrix& <b>fill</b> (<var>const ColumnVector &a</var>)<var><a name="index-fill-301"></a></var><br>
+— : DiagMatrix& <b>fill</b> (<var>const RowVector &a</var>)<var><a name="index-fill-302"></a></var><br>
+— : DiagMatrix& <b>fill</b> (<var>const ColumnVector &a, int beg</var>)<var><a name="index-fill-303"></a></var><br>
+— : DiagMatrix& <b>fill</b> (<var>const RowVector &a, int beg</var>)<var><a name="index-fill-304"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-305"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>extract</b> (<var>int r1, int c1, int r2, int c2</var>)<var> const<a name="index-extract-306"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>row</b> (<var>int i</var>)<var> const<a name="index-row-307"></a></var><br>
+— : RowVector <b>row</b> (<var>char *s</var>)<var> const<a name="index-row-308"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>column</b> (<var>int i</var>)<var> const<a name="index-column-309"></a></var><br>
+— : ColumnVector <b>column</b> (<var>char *s</var>)<var> const<a name="index-column-310"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix <b>inverse</b> (<var>void</var>)<var> const<a name="index-inverse-311"></a></var><br>
+— : DiagMatrix <b>inverse</b> (<var>int &info</var>)<var> const<a name="index-inverse-312"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix& <b>operator +=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002b_003d-313"></a></var><br>
+— : DiagMatrix& <b>operator -=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002d_003d-314"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>const DiagMatrix &a, double s</var>)<var><a name="index-operator-_002b-315"></a></var><br>
+— : Matrix <b>operator -</b> (<var>const DiagMatrix &a, double s</var>)<var><a name="index-operator-_002d-316"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const DiagMatrix &a, const Complex &s</var>)<var><a name="index-operator-_002b-317"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const DiagMatrix &a, const Complex &s</var>)<var><a name="index-operator-_002d-318"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>operator *</b> (<var>const DiagMatrix &a, const Complex &s</var>)<var><a name="index-operator-_002a-319"></a></var><br>
+— : ComplexDiagMatrix <b>operator /</b> (<var>const DiagMatrix &a, const Complex &s</var>)<var><a name="index-operator-_002f-320"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>double s, const DiagMatrix &a</var>)<var><a name="index-operator-_002b-321"></a></var><br>
+— : Matrix <b>operator -</b> (<var>double s, const DiagMatrix &a</var>)<var><a name="index-operator-_002d-322"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const Complex &s, const DiagMatrix &a</var>)<var><a name="index-operator-_002b-323"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const Complex &s, const DiagMatrix &a</var>)<var><a name="index-operator-_002d-324"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>operator *</b> (<var>const Complex &s, const DiagMatrix &a</var>)<var><a name="index-operator-_002a-325"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>operator *</b> (<var>const DiagMatrix &a, const ColumnVector &b</var>)<var><a name="index-operator-_002a-326"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator *</b> (<var>const DiagMatrix &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002a-327"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>operator +</b> (<var>const DiagMatrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002b-328"></a></var><br>
+— : ComplexDiagMatrix <b>operator -</b> (<var>const DiagMatrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002d-329"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>product</b> (<var>const DiagMatrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-product-330"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator +</b> (<var>const DiagMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002b-331"></a></var><br>
+— : Matrix <b>operator -</b> (<var>const DiagMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002d-332"></a></var><br>
+— : Matrix <b>operator *</b> (<var>const DiagMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002a-333"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const DiagMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002b-334"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const DiagMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002d-335"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const DiagMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002a-336"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>diag</b> (<var>void</var>)<var> const<a name="index-diag-337"></a></var><br>
+— : ColumnVector <b>diag</b> (<var>int k</var>)<var> const<a name="index-diag-338"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const DiagMatrix &a</var>)<var><a name="index-operator-_003c_003c-339"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexMatrix</b> (<var>void</var>)<var><a name="index-ComplexMatrix-340"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>int r, int c</var>)<var><a name="index-ComplexMatrix-341"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>int r, int c, const Complex &val</var>)<var><a name="index-ComplexMatrix-342"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>const Matrix &a</var>)<var><a name="index-ComplexMatrix-343"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>const Array2<Complex> &a</var>)<var><a name="index-ComplexMatrix-344"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-ComplexMatrix-345"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>const DiagMatrix &a</var>)<var><a name="index-ComplexMatrix-346"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>const DiagArray<Complex> &a</var>)<var><a name="index-ComplexMatrix-347"></a></var><br>
+— :  <b>ComplexMatrix</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-ComplexMatrix-348"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>operator =</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-operator-_003d-349"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const ComplexMatrix &a</var>)<var> const<a name="index-operator-_003d_003d-350"></a></var><br>
+— : int <b>operator !=</b> (<var>const ComplexMatrix &a</var>)<var> const<a name="index-operator-_0021_003d-351"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>insert</b> (<var>const Matrix &a, int r, int c</var>)<var><a name="index-insert-352"></a></var><br>
+— : ComplexMatrix& <b>insert</b> (<var>const RowVector &a, int r, int c</var>)<var><a name="index-insert-353"></a></var><br>
+— : ComplexMatrix& <b>insert</b> (<var>const ColumnVector &a, int r, int c</var>)<var><a name="index-insert-354"></a></var><br>
+— : ComplexMatrix& <b>insert</b> (<var>const DiagMatrix &a, int r, int c</var>)<var><a name="index-insert-355"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>insert</b> (<var>const ComplexMatrix &a, int r, int c</var>)<var><a name="index-insert-356"></a></var><br>
+— : ComplexMatrix& <b>insert</b> (<var>const ComplexRowVector &a, int r, int c</var>)<var><a name="index-insert-357"></a></var><br>
+— : ComplexMatrix& <b>insert</b> (<var>const ComplexColumnVector &a, int r, int c</var>)<var><a name="index-insert-358"></a></var><br>
+— : ComplexMatrix& <b>insert</b> (<var>const ComplexDiagMatrix &a, int r, int c</var>)<var><a name="index-insert-359"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-360"></a></var><br>
+— : ComplexMatrix& <b>fill</b> (<var>const Complex &val</var>)<var><a name="index-fill-361"></a></var><br>
+— : ComplexMatrix& <b>fill</b> (<var>double val, int r1, int c1, int r2, int c2</var>)<var><a name="index-fill-362"></a></var><br>
+— : ComplexMatrix& <b>fill</b> (<var>const Complex &val, int r1, int c1, int r2, int c2</var>)<var><a name="index-fill-363"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>append</b> (<var>const Matrix &a</var>)<var> const<a name="index-append-364"></a></var><br>
+— : ComplexMatrix <b>append</b> (<var>const RowVector &a</var>)<var> const<a name="index-append-365"></a></var><br>
+— : ComplexMatrix <b>append</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-append-366"></a></var><br>
+— : ComplexMatrix <b>append</b> (<var>const DiagMatrix &a</var>)<var> const<a name="index-append-367"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>append</b> (<var>const ComplexMatrix &a</var>)<var> const<a name="index-append-368"></a></var><br>
+— : ComplexMatrix <b>append</b> (<var>const ComplexRowVector &a</var>)<var> const<a name="index-append-369"></a></var><br>
+— : ComplexMatrix <b>append</b> (<var>const ComplexColumnVector &a</var>)<var> const<a name="index-append-370"></a></var><br>
+— : ComplexMatrix <b>append</b> (<var>const ComplexDiagMatrix &a</var>)<var> const<a name="index-append-371"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>stack</b> (<var>const Matrix &a</var>)<var> const<a name="index-stack-372"></a></var><br>
+— : ComplexMatrix <b>stack</b> (<var>const RowVector &a</var>)<var> const<a name="index-stack-373"></a></var><br>
+— : ComplexMatrix <b>stack</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-stack-374"></a></var><br>
+— : ComplexMatrix <b>stack</b> (<var>const DiagMatrix &a</var>)<var> const<a name="index-stack-375"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>stack</b> (<var>const ComplexMatrix &a</var>)<var> const<a name="index-stack-376"></a></var><br>
+— : ComplexMatrix <b>stack</b> (<var>const ComplexRowVector &a</var>)<var> const<a name="index-stack-377"></a></var><br>
+— : ComplexMatrix <b>stack</b> (<var>const ComplexColumnVector &a</var>)<var> const<a name="index-stack-378"></a></var><br>
+— : ComplexMatrix <b>stack</b> (<var>const ComplexDiagMatrix &a</var>)<var> const<a name="index-stack-379"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-380"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>real</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-real-381"></a></var><br>
+— : Matrix <b>imag</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-imag-382"></a></var><br>
+— : ComplexMatrix <b>conj</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-conj-383"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>extract</b> (<var>int r1, int c1, int r2, int c2</var>)<var> const<a name="index-extract-384"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>row</b> (<var>int i</var>)<var> const<a name="index-row-385"></a></var><br>
+— : ComplexRowVector <b>row</b> (<var>char *s</var>)<var> const<a name="index-row-386"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>column</b> (<var>int i</var>)<var> const<a name="index-column-387"></a></var><br>
+— : ComplexColumnVector <b>column</b> (<var>char *s</var>)<var> const<a name="index-column-388"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>inverse</b> (<var>void</var>)<var> const<a name="index-inverse-389"></a></var><br>
+— : ComplexMatrix <b>inverse</b> (<var>int &info</var>)<var> const<a name="index-inverse-390"></a></var><br>
+— : ComplexMatrix <b>inverse</b> (<var>int &info, double &rcond</var>)<var> const<a name="index-inverse-391"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>fourier</b> (<var>void</var>)<var> const<a name="index-fourier-392"></a></var><br>
+— : ComplexMatrix <b>ifourier</b> (<var>void</var>)<var> const<a name="index-ifourier-393"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDET <b>determinant</b> (<var>void</var>)<var> const<a name="index-determinant-394"></a></var><br>
+— : ComplexDET <b>determinant</b> (<var>int &info</var>)<var> const<a name="index-determinant-395"></a></var><br>
+— : ComplexDET <b>determinant</b> (<var>int &info, double &rcond</var>)<var> const<a name="index-determinant-396"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>solve</b> (<var>const Matrix &b</var>)<var> const<a name="index-solve-397"></a></var><br>
+— : ComplexMatrix <b>solve</b> (<var>const Matrix &b, int &info</var>)<var> const<a name="index-solve-398"></a></var><br>
+— : ComplexMatrix <b>solve</b> (<var>const Matrix &b, int &info, double &rcond</var>)<var> const<a name="index-solve-399"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>solve</b> (<var>const ComplexMatrix &b</var>)<var> const<a name="index-solve-400"></a></var><br>
+— : ComplexMatrix <b>solve</b> (<var>const ComplexMatrix &b, int &info</var>)<var> const<a name="index-solve-401"></a></var><br>
+— : ComplexMatrix <b>solve</b> (<var>const ComplexMatrix &b, int &info, double &rcond</var>)<var> const<a name="index-solve-402"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>solve</b> (<var>const ComplexColumnVector &b</var>)<var> const<a name="index-solve-403"></a></var><br>
+— : ComplexColumnVector <b>solve</b> (<var>const ComplexColumnVector &b, int &info</var>)<var> const<a name="index-solve-404"></a></var><br>
+— : ComplexColumnVector <b>solve</b> (<var>const ComplexColumnVector &b, int &info, double &rcond</var>)<var> const<a name="index-solve-405"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>lssolve</b> (<var>const ComplexMatrix &b</var>)<var> const<a name="index-lssolve-406"></a></var><br>
+— : ComplexMatrix <b>lssolve</b> (<var>const ComplexMatrix &b, int &info</var>)<var> const<a name="index-lssolve-407"></a></var><br>
+— : ComplexMatrix <b>lssolve</b> (<var>const ComplexMatrix &b, int &info, int &rank</var>)<var> const<a name="index-lssolve-408"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>lssolve</b> (<var>const ComplexColumnVector &b</var>)<var> const<a name="index-lssolve-409"></a></var><br>
+— : ComplexColumnVector <b>lssolve</b> (<var>const ComplexColumnVector &b, int &info</var>)<var> const<a name="index-lssolve-410"></a></var><br>
+— : ComplexColumnVector <b>lssolve</b> (<var>const ComplexColumnVector &b, int &info, int &rank</var>)<var> const<a name="index-lssolve-411"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>operator +=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002b_003d-412"></a></var><br>
+— : ComplexMatrix& <b>operator -=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002d_003d-413"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>operator +=</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002b_003d-414"></a></var><br>
+— : ComplexMatrix& <b>operator -=</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002d_003d-415"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>operator +=</b> (<var>const Matrix &a</var>)<var><a name="index-operator-_002b_003d-416"></a></var><br>
+— : ComplexMatrix& <b>operator -=</b> (<var>const Matrix &a</var>)<var><a name="index-operator-_002d_003d-417"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix& <b>operator +=</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-operator-_002b_003d-418"></a></var><br>
+— : ComplexMatrix& <b>operator -=</b> (<var>const ComplexMatrix &a</var>)<var><a name="index-operator-_002d_003d-419"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>operator !</b> (<var>void</var>)<var> const<a name="index-operator-_0021-420"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexMatrix &a, double s</var>)<var><a name="index-operator-_002b-421"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexMatrix &a, double s</var>)<var><a name="index-operator-_002d-422"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexMatrix &a, double s</var>)<var><a name="index-operator-_002a-423"></a></var><br>
+— : ComplexMatrix <b>operator /</b> (<var>const ComplexMatrix &a, double s</var>)<var><a name="index-operator-_002f-424"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>double s, const ComplexMatrix &a</var>)<var><a name="index-operator-_002b-425"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>double s, const ComplexMatrix &a</var>)<var><a name="index-operator-_002d-426"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>double s, const ComplexMatrix &a</var>)<var><a name="index-operator-_002a-427"></a></var><br>
+— : ComplexMatrix <b>operator /</b> (<var>double s, const ComplexMatrix &a</var>)<var><a name="index-operator-_002f-428"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator *</b> (<var>const ComplexMatrix &a, const ColumnVector &b</var>)<var><a name="index-operator-_002a-429"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator *</b> (<var>const ComplexMatrix &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002a-430"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002b-431"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002d-432"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002a-433"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexMatrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002b-434"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexMatrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002d-435"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexMatrix &a, const ComplexDiagMatrix &b</var>)<var><a name="index-operator-_002a-436"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002b-437"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002d-438"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002a-439"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002a-440"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>product</b> (<var>const ComplexMatrix &a, const Matrix &b</var>)<var><a name="index-product-441"></a></var><br>
+— : ComplexMatrix <b>quotient</b> (<var>const ComplexMatrix &a, const Matrix &b</var>)<var><a name="index-quotient-442"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>map</b> (<var>c_c_Mapper f, const ComplexMatrix &a</var>)<var><a name="index-map-443"></a></var><br>
+— : Matrix <b>map</b> (<var>d_c_Mapper f, const ComplexMatrix &a</var>)<var><a name="index-map-444"></a></var><br>
+— : void <b>map</b> (<var>c_c_Mapper f</var>)<var><a name="index-map-445"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>all</b> (<var>void</var>)<var> const<a name="index-all-446"></a></var><br>
+— : Matrix <b>any</b> (<var>void</var>)<var> const<a name="index-any-447"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>cumprod</b> (<var>void</var>)<var> const<a name="index-cumprod-448"></a></var><br>
+— : ComplexMatrix <b>cumsum</b> (<var>void</var>)<var> const<a name="index-cumsum-449"></a></var><br>
+— : ComplexMatrix <b>prod</b> (<var>void</var>)<var> const<a name="index-prod-450"></a></var><br>
+— : ComplexMatrix <b>sum</b> (<var>void</var>)<var> const<a name="index-sum-451"></a></var><br>
+— : ComplexMatrix <b>sumsq</b> (<var>void</var>)<var> const<a name="index-sumsq-452"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>diag</b> (<var>void</var>)<var> const<a name="index-diag-453"></a></var><br>
+— : ComplexColumnVector <b>diag</b> (<var>int k</var>)<var> const<a name="index-diag-454"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>row_min</b> (<var>void</var>)<var> const<a name="index-row_005fmin-455"></a></var><br>
+— : ComplexColumnVector <b>row_min_loc</b> (<var>void</var>)<var> const<a name="index-row_005fmin_005floc-456"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>row_max</b> (<var>void</var>)<var> const<a name="index-row_005fmax-457"></a></var><br>
+— : ComplexColumnVector <b>row_max_loc</b> (<var>void</var>)<var> const<a name="index-row_005fmax_005floc-458"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>column_min</b> (<var>void</var>)<var> const<a name="index-column_005fmin-459"></a></var><br>
+— : ComplexRowVector <b>column_min_loc</b> (<var>void</var>)<var> const<a name="index-column_005fmin_005floc-460"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>column_max</b> (<var>void</var>)<var> const<a name="index-column_005fmax-461"></a></var><br>
+— : ComplexRowVector <b>column_max_loc</b> (<var>void</var>)<var> const<a name="index-column_005fmax_005floc-462"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexMatrix &a</var>)<var><a name="index-operator-_003c_003c-463"></a></var><br>
+— : istream& <b>operator >></b> (<var>istream &is, ComplexMatrix &a</var>)<var><a name="index-operator-_003e_003e-464"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexColumnVector</b> (<var>void</var>)<var><a name="index-ComplexColumnVector-465"></a></var><br>
+— :  <b>ComplexColumnVector</b> (<var>int n</var>)<var><a name="index-ComplexColumnVector-466"></a></var><br>
+— :  <b>ComplexColumnVector</b> (<var>int n, const Complex &val</var>)<var><a name="index-ComplexColumnVector-467"></a></var><br>
+— :  <b>ComplexColumnVector</b> (<var>const ColumnVector &a</var>)<var><a name="index-ComplexColumnVector-468"></a></var><br>
+— :  <b>ComplexColumnVector</b> (<var>const Array<Complex> &a</var>)<var><a name="index-ComplexColumnVector-469"></a></var><br>
+— :  <b>ComplexColumnVector</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-ComplexColumnVector-470"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector& <b>operator =</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-operator-_003d-471"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const ComplexColumnVector &a</var>)<var> const<a name="index-operator-_003d_003d-472"></a></var><br>
+— : int <b>operator !=</b> (<var>const ComplexColumnVector &a</var>)<var> const<a name="index-operator-_0021_003d-473"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector& <b>insert</b> (<var>const ColumnVector &a, int r</var>)<var><a name="index-insert-474"></a></var><br>
+— : ComplexColumnVector& <b>insert</b> (<var>const ComplexColumnVector &a, int r</var>)<var><a name="index-insert-475"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-476"></a></var><br>
+— : ComplexColumnVector& <b>fill</b> (<var>const Complex &val</var>)<var><a name="index-fill-477"></a></var><br>
+— : ComplexColumnVector& <b>fill</b> (<var>double val, int r1, int r2</var>)<var><a name="index-fill-478"></a></var><br>
+— : ComplexColumnVector& <b>fill</b> (<var>const Complex &val, int r1, int r2</var>)<var><a name="index-fill-479"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>stack</b> (<var>const ColumnVector &a</var>)<var> const<a name="index-stack-480"></a></var><br>
+— : ComplexColumnVector <b>stack</b> (<var>const ComplexColumnVector &a</var>)<var> const<a name="index-stack-481"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-482"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>real</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-real-483"></a></var><br>
+— : ColumnVector <b>imag</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-imag-484"></a></var><br>
+— : ComplexColumnVector <b>conj</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-conj-485"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>extract</b> (<var>int r1, int r2</var>)<var> const<a name="index-extract-486"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector& <b>operator +=</b> (<var>const ColumnVector &a</var>)<var><a name="index-operator-_002b_003d-487"></a></var><br>
+— : ComplexColumnVector& <b>operator -=</b> (<var>const ColumnVector &a</var>)<var><a name="index-operator-_002d_003d-488"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector& <b>operator +=</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-operator-_002b_003d-489"></a></var><br>
+— : ComplexColumnVector& <b>operator -=</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-operator-_002d_003d-490"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator +</b> (<var>const ComplexColumnVector &a, double s</var>)<var><a name="index-operator-_002b-491"></a></var><br>
+— : ComplexColumnVector <b>operator -</b> (<var>const ComplexColumnVector &a, double s</var>)<var><a name="index-operator-_002d-492"></a></var><br>
+— : ComplexColumnVector <b>operator *</b> (<var>const ComplexColumnVector &a, double s</var>)<var><a name="index-operator-_002a-493"></a></var><br>
+— : ComplexColumnVector <b>operator /</b> (<var>const ComplexColumnVector &a, double s</var>)<var><a name="index-operator-_002f-494"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator +</b> (<var>double s, const ComplexColumnVector &a</var>)<var><a name="index-operator-_002b-495"></a></var><br>
+— : ComplexColumnVector <b>operator -</b> (<var>double s, const ComplexColumnVector &a</var>)<var><a name="index-operator-_002d-496"></a></var><br>
+— : ComplexColumnVector <b>operator *</b> (<var>double s, const ComplexColumnVector &a</var>)<var><a name="index-operator-_002a-497"></a></var><br>
+— : ComplexColumnVector <b>operator /</b> (<var>double s, const ComplexColumnVector &a</var>)<var><a name="index-operator-_002f-498"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexColumnVector &a, const ComplexRowVector &b</var>)<var><a name="index-operator-_002a-499"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator +</b> (<var>const ComplexColumnVector &a, const ColumnVector &b</var>)<var><a name="index-operator-_002b-500"></a></var><br>
+— : ComplexColumnVector <b>operator -</b> (<var>const ComplexColumnVector &a, const ColumnVector &b</var>)<var><a name="index-operator-_002d-501"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>product</b> (<var>const ComplexColumnVector &a, const ColumnVector &b</var>)<var><a name="index-product-502"></a></var><br>
+— : ComplexColumnVector <b>quotient</b> (<var>const ComplexColumnVector &a, const ColumnVector &b</var>)<var><a name="index-quotient-503"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>map</b> (<var>c_c_Mapper f, const ComplexColumnVector &a</var>)<var><a name="index-map-504"></a></var><br>
+— : ColumnVector <b>map</b> (<var>d_c_Mapper f, const ComplexColumnVector &a</var>)<var><a name="index-map-505"></a></var><br>
+— : void <b>map</b> (<var>c_c_Mapper f</var>)<var><a name="index-map-506"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Complex <b>min</b> (<var>void</var>)<var> const<a name="index-min-507"></a></var><br>
+— : Complex <b>max</b> (<var>void</var>)<var> const<a name="index-max-508"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexColumnVector &a</var>)<var><a name="index-operator-_003c_003c-509"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexRowVector</b> (<var>void</var>)<var><a name="index-ComplexRowVector-510"></a></var><br>
+— :  <b>ComplexRowVector</b> (<var>int n</var>)<var><a name="index-ComplexRowVector-511"></a></var><br>
+— :  <b>ComplexRowVector</b> (<var>int n, const Complex &val</var>)<var><a name="index-ComplexRowVector-512"></a></var><br>
+— :  <b>ComplexRowVector</b> (<var>const RowVector &a</var>)<var><a name="index-ComplexRowVector-513"></a></var><br>
+— :  <b>ComplexRowVector</b> (<var>const Array<Complex> &a</var>)<var><a name="index-ComplexRowVector-514"></a></var><br>
+— :  <b>ComplexRowVector</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-ComplexRowVector-515"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector& <b>operator =</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-operator-_003d-516"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const ComplexRowVector &a</var>)<var> const<a name="index-operator-_003d_003d-517"></a></var><br>
+— : int <b>operator !=</b> (<var>const ComplexRowVector &a</var>)<var> const<a name="index-operator-_0021_003d-518"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector& <b>insert</b> (<var>const RowVector &a, int c</var>)<var><a name="index-insert-519"></a></var><br>
+— : ComplexRowVector& <b>insert</b> (<var>const ComplexRowVector &a, int c</var>)<var><a name="index-insert-520"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-521"></a></var><br>
+— : ComplexRowVector& <b>fill</b> (<var>const Complex &val</var>)<var><a name="index-fill-522"></a></var><br>
+— : ComplexRowVector& <b>fill</b> (<var>double val, int c1, int c2</var>)<var><a name="index-fill-523"></a></var><br>
+— : ComplexRowVector& <b>fill</b> (<var>const Complex &val, int c1, int c2</var>)<var><a name="index-fill-524"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>append</b> (<var>const RowVector &a</var>)<var> const<a name="index-append-525"></a></var><br>
+— : ComplexRowVector <b>append</b> (<var>const ComplexRowVector &a</var>)<var> const<a name="index-append-526"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-527"></a></var><br>
+        </div>
+
+<div class="defun">
+— : RowVector <b>real</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-real-528"></a></var><br>
+— : RowVector <b>imag</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-imag-529"></a></var><br>
+— : ComplexRowVector <b>conj</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-conj-530"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>extract</b> (<var>int c1, int c2</var>)<var> const<a name="index-extract-531"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector& <b>operator +=</b> (<var>const RowVector &a</var>)<var><a name="index-operator-_002b_003d-532"></a></var><br>
+— : ComplexRowVector& <b>operator -=</b> (<var>const RowVector &a</var>)<var><a name="index-operator-_002d_003d-533"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector& <b>operator +=</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-operator-_002b_003d-534"></a></var><br>
+— : ComplexRowVector& <b>operator -=</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-operator-_002d_003d-535"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator +</b> (<var>const ComplexRowVector &a, double s</var>)<var><a name="index-operator-_002b-536"></a></var><br>
+— : ComplexRowVector <b>operator -</b> (<var>const ComplexRowVector &a, double s</var>)<var><a name="index-operator-_002d-537"></a></var><br>
+— : ComplexRowVector <b>operator *</b> (<var>const ComplexRowVector &a, double s</var>)<var><a name="index-operator-_002a-538"></a></var><br>
+— : ComplexRowVector <b>operator /</b> (<var>const ComplexRowVector &a, double s</var>)<var><a name="index-operator-_002f-539"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator +</b> (<var>double s, const ComplexRowVector &a</var>)<var><a name="index-operator-_002b-540"></a></var><br>
+— : ComplexRowVector <b>operator -</b> (<var>double s, const ComplexRowVector &a</var>)<var><a name="index-operator-_002d-541"></a></var><br>
+— : ComplexRowVector <b>operator *</b> (<var>double s, const ComplexRowVector &a</var>)<var><a name="index-operator-_002a-542"></a></var><br>
+— : ComplexRowVector <b>operator /</b> (<var>double s, const ComplexRowVector &a</var>)<var><a name="index-operator-_002f-543"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Complex <b>operator *</b> (<var>const ComplexRowVector &a, const ColumnVector &b</var>)<var><a name="index-operator-_002a-544"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Complex <b>operator *</b> (<var>const ComplexRowVector &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002a-545"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator *</b> (<var>const ComplexRowVector &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002a-546"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>operator +</b> (<var>const ComplexRowVector &a, const RowVector &b</var>)<var><a name="index-operator-_002b-547"></a></var><br>
+— : ComplexRowVector <b>operator -</b> (<var>const ComplexRowVector &a, const RowVector &b</var>)<var><a name="index-operator-_002d-548"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>product</b> (<var>const ComplexRowVector &a, const RowVector &b</var>)<var><a name="index-product-549"></a></var><br>
+— : ComplexRowVector <b>quotient</b> (<var>const ComplexRowVector &a, const RowVector &b</var>)<var><a name="index-quotient-550"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>map</b> (<var>c_c_Mapper f, const ComplexRowVector &a</var>)<var><a name="index-map-551"></a></var><br>
+— : RowVector <b>map</b> (<var>d_c_Mapper f, const ComplexRowVector &a</var>)<var><a name="index-map-552"></a></var><br>
+— : void <b>map</b> (<var>c_c_Mapper f</var>)<var><a name="index-map-553"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Complex <b>min</b> (<var>void</var>)<var> const<a name="index-min-554"></a></var><br>
+— : Complex <b>max</b> (<var>void</var>)<var> const<a name="index-max-555"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexRowVector &a</var>)<var><a name="index-operator-_003c_003c-556"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ComplexDiagMatrix</b> (<var>void</var>)<var><a name="index-ComplexDiagMatrix-557"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>int n</var>)<var><a name="index-ComplexDiagMatrix-558"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>int n, const Complex &val</var>)<var><a name="index-ComplexDiagMatrix-559"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>int r, int c</var>)<var><a name="index-ComplexDiagMatrix-560"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>int r, int c, const Complex &val</var>)<var><a name="index-ComplexDiagMatrix-561"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const RowVector &a</var>)<var><a name="index-ComplexDiagMatrix-562"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-ComplexDiagMatrix-563"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const ColumnVector &a</var>)<var><a name="index-ComplexDiagMatrix-564"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-ComplexDiagMatrix-565"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const DiagMatrix &a</var>)<var><a name="index-ComplexDiagMatrix-566"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const DiagArray<Complex> &a</var>)<var><a name="index-ComplexDiagMatrix-567"></a></var><br>
+— :  <b>ComplexDiagMatrix</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-ComplexDiagMatrix-568"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix& <b>operator =</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_003d-569"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>operator ==</b> (<var>const ComplexDiagMatrix &a</var>)<var> const<a name="index-operator-_003d_003d-570"></a></var><br>
+— : int <b>operator !=</b> (<var>const ComplexDiagMatrix &a</var>)<var> const<a name="index-operator-_0021_003d-571"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix& <b>fill</b> (<var>double val</var>)<var><a name="index-fill-572"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const Complex &val</var>)<var><a name="index-fill-573"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>double val, int beg, int end</var>)<var><a name="index-fill-574"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const Complex &val, int beg, int end</var>)<var><a name="index-fill-575"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const ColumnVector &a</var>)<var><a name="index-fill-576"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const ComplexColumnVector &a</var>)<var><a name="index-fill-577"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const RowVector &a</var>)<var><a name="index-fill-578"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const ComplexRowVector &a</var>)<var><a name="index-fill-579"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const ColumnVector &a, int beg</var>)<var><a name="index-fill-580"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const ComplexColumnVector &a, int beg</var>)<var><a name="index-fill-581"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const RowVector &a, int beg</var>)<var><a name="index-fill-582"></a></var><br>
+— : ComplexDiagMatrix& <b>fill</b> (<var>const ComplexRowVector &a, int beg</var>)<var><a name="index-fill-583"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>transpose</b> (<var>void</var>)<var> const<a name="index-transpose-584"></a></var><br>
+        </div>
+
+<div class="defun">
+— : DiagMatrix <b>real</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-real-585"></a></var><br>
+— : DiagMatrix <b>imag</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-imag-586"></a></var><br>
+— : ComplexDiagMatrix <b>conj</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-conj-587"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>extract</b> (<var>int r1, int c1, int r2, int c2</var>)<var> const<a name="index-extract-588"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexRowVector <b>row</b> (<var>int i</var>)<var> const<a name="index-row-589"></a></var><br>
+— : ComplexRowVector <b>row</b> (<var>char *s</var>)<var> const<a name="index-row-590"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>column</b> (<var>int i</var>)<var> const<a name="index-column-591"></a></var><br>
+— : ComplexColumnVector <b>column</b> (<var>char *s</var>)<var> const<a name="index-column-592"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>inverse</b> (<var>int &info</var>)<var> const<a name="index-inverse-593"></a></var><br>
+— : ComplexDiagMatrix <b>inverse</b> (<var>void</var>)<var> const<a name="index-inverse-594"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix& <b>operator +=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002b_003d-595"></a></var><br>
+— : ComplexDiagMatrix& <b>operator -=</b> (<var>const DiagMatrix &a</var>)<var><a name="index-operator-_002d_003d-596"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix& <b>operator +=</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002b_003d-597"></a></var><br>
+— : ComplexDiagMatrix& <b>operator -=</b> (<var>const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002d_003d-598"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexDiagMatrix &a, double s</var>)<var><a name="index-operator-_002b-599"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexDiagMatrix &a, double s</var>)<var><a name="index-operator-_002d-600"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexDiagMatrix &a, const Complex &s</var>)<var><a name="index-operator-_002b-601"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexDiagMatrix &a, const Complex &s</var>)<var><a name="index-operator-_002d-602"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>operator *</b> (<var>const ComplexDiagMatrix &a, double s</var>)<var><a name="index-operator-_002a-603"></a></var><br>
+— : ComplexDiagMatrix <b>operator /</b> (<var>const ComplexDiagMatrix &a, double s</var>)<var><a name="index-operator-_002f-604"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>double s, const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002b-605"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>double s, const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002d-606"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const Complex &s, const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002b-607"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const Complex &s, const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002d-608"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>operator *</b> (<var>double s, const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_002a-609"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator *</b> (<var>const ComplexDiagMatrix &a, const ColumnVector &b</var>)<var><a name="index-operator-_002a-610"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>operator *</b> (<var>const ComplexDiagMatrix &a, const ComplexColumnVector &b</var>)<var><a name="index-operator-_002a-611"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>operator +</b> (<var>const ComplexDiagMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002b-612"></a></var><br>
+— : ComplexDiagMatrix <b>operator -</b> (<var>const ComplexDiagMatrix &a, const DiagMatrix &b</var>)<var><a name="index-operator-_002d-613"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexDiagMatrix <b>product</b> (<var>const ComplexDiagMatrix &a, const DiagMatrix &b</var>)<var><a name="index-product-614"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexDiagMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002b-615"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexDiagMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002d-616"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexDiagMatrix &a, const Matrix &b</var>)<var><a name="index-operator-_002a-617"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexMatrix <b>operator +</b> (<var>const ComplexDiagMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002b-618"></a></var><br>
+— : ComplexMatrix <b>operator -</b> (<var>const ComplexDiagMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002d-619"></a></var><br>
+— : ComplexMatrix <b>operator *</b> (<var>const ComplexDiagMatrix &a, const ComplexMatrix &b</var>)<var><a name="index-operator-_002a-620"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ComplexColumnVector <b>diag</b> (<var>void</var>)<var> const<a name="index-diag-621"></a></var><br>
+— : ComplexColumnVector <b>diag</b> (<var>int k</var>)<var> const<a name="index-diag-622"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const ComplexDiagMatrix &a</var>)<var><a name="index-operator-_003c_003c-623"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1998, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Nonlinear-Constraints.html b/doc/liboctave/HTML/Nonlinear-Constraints.html
new file mode 100644
index 0000000..d491e7c
--- /dev/null
+++ b/doc/liboctave/HTML/Nonlinear-Constraints.html
@@ -0,0 +1,51 @@
+<html lang="en">
+<head>
+<title>Nonlinear Constraints - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Linear-Constraints.html#Linear-Constraints" title="Linear Constraints">
+<link rel="next" href="Quadratic-Programming.html#Quadratic-Programming" title="Quadratic Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Nonlinear-Constraints"></a>
+Next: <a rel="next" accesskey="n" href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>,
+Previous: <a rel="previous" accesskey="p" href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">9.4 Nonlinear Constraints</h3>
+
+<p><a name="index-nonlinear-Constraints-869"></a>
+
+<div class="defun">
+— :  <b>NLConst</b> (<var>void</var>)<var><a name="index-NLConst-870"></a></var><br>
+— :  <b>NLConst</b> (<var>int n</var>)<var><a name="index-NLConst-871"></a></var><br>
+— :  <b>NLConst</b> (<var>const ColumnVector lb, const NLFunc f, const ColumnVector ub</var>)<var><a name="index-NLConst-872"></a></var><br>
+— :  <b>NLConst</b> (<var>const NLConst &a</var>)<var><a name="index-NLConst-873"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLConst& <b>operator =</b> (<var>const NLConst &a</var>)<var><a name="index-operator-_003d-874"></a></var><br>
+        </div>
+
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Nonlinear-Equations.html b/doc/liboctave/HTML/Nonlinear-Equations.html
new file mode 100644
index 0000000..141bdec
--- /dev/null
+++ b/doc/liboctave/HTML/Nonlinear-Equations.html
@@ -0,0 +1,117 @@
+<html lang="en">
+<head>
+<title>Nonlinear Equations - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Nonlinear-Functions.html#Nonlinear-Functions" title="Nonlinear Functions">
+<link rel="next" href="Optimization.html#Optimization" title="Optimization">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Nonlinear-Equations"></a>
+Next: <a rel="next" accesskey="n" href="Optimization.html#Optimization">Optimization</a>,
+Previous: <a rel="previous" accesskey="p" href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">8 Nonlinear Equations</h2>
+
+<p><a name="index-nonlinear-equations-799"></a>
+
+<div class="defun">
+— :  <b>NLEqn_options</b> (<var>void</var>)<var><a name="index-NLEqn_005foptions-800"></a></var><br>
+— :  <b>NLEqn_options</b> (<var>const NLEqn_options &opt</var>)<var><a name="index-NLEqn_005foptions-801"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLEqn_options& <b>operator =</b> (<var>const NLEqn_options &opt</var>)<var><a name="index-operator-_003d-802"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>init</b> (<var>void</var>)<var><a name="index-init-803"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>copy</b> (<var>const NLEqn_options &opt</var>)<var><a name="index-copy-804"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_default_options</b> (<var>void</var>)<var><a name="index-set_005fdefault_005foptions-805"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_tolerance</b> (<var>double val</var>)<var><a name="index-set_005ftolerance-806"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>tolerance</b> (<var>void</var>)<var><a name="index-tolerance-807"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>NLEqn</b> (<var>void</var>)<var><a name="index-NLEqn-808"></a></var><br>
+— :  <b>NLEqn</b> (<var>const ColumnVector&, const NLFunc</var>)<var><a name="index-NLEqn-809"></a></var><br>
+— :  <b>NLEqn</b> (<var>const NLEqn &a</var>)<var><a name="index-NLEqn-810"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLEqn& <b>operator =</b> (<var>const NLEqn &a</var>)<var><a name="index-operator-_003d-811"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>resize</b> (<var>int n</var>)<var><a name="index-resize-812"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_states</b> (<var>const ColumnVector &x</var>)<var><a name="index-set_005fstates-813"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>states</b> (<var>void</var>)<var> const<a name="index-states-814"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>size</b> (<var>void</var>)<var> const<a name="index-size-815"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>solve</b> (<var>void</var>)<var><a name="index-solve-816"></a></var><br>
+— : ColumnVector <b>solve</b> (<var>const ColumnVector &x</var>)<var><a name="index-solve-817"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>solve</b> (<var>int &info</var>)<var><a name="index-solve-818"></a></var><br>
+— : ColumnVector <b>solve</b> (<var>const ColumnVector &x, int &info</var>)<var><a name="index-solve-819"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Nonlinear-Functions.html b/doc/liboctave/HTML/Nonlinear-Functions.html
new file mode 100644
index 0000000..7df43f3
--- /dev/null
+++ b/doc/liboctave/HTML/Nonlinear-Functions.html
@@ -0,0 +1,79 @@
+<html lang="en">
+<head>
+<title>Nonlinear Functions - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Ranges.html#Ranges" title="Ranges">
+<link rel="next" href="Nonlinear-Equations.html#Nonlinear-Equations" title="Nonlinear Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Nonlinear-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a>,
+Previous: <a rel="previous" accesskey="p" href="Ranges.html#Ranges">Ranges</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">7 Nonlinear Functions</h2>
+
+<p><a name="index-nonlinear-functions-789"></a>
+
+<div class="defun">
+— :  <b>NLFunc</b> (<var>void</var>)<var><a name="index-NLFunc-790"></a></var><br>
+— :  <b>NLFunc</b> (<var>const nonlinear_fcn</var>)<var><a name="index-NLFunc-791"></a></var><br>
+— :  <b>NLFunc</b> (<var>const nonlinear_fcn, const jacobian_fcn</var>)<var><a name="index-NLFunc-792"></a></var><br>
+— :  <b>NLFunc</b> (<var>const NLFunc &a</var>)<var><a name="index-NLFunc-793"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLFunc& <b>operator =</b> (<var>const NLFunc &a</var>)<var><a name="index-operator-_003d-794"></a></var><br>
+        </div>
+
+<div class="defun">
+— : nonlinear_fcn <b>function</b> (<var>void</var>)<var> const;<a name="index-function-795"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLFunc& <b>set_function</b> (<var>const nonlinear_fcn f</var>)<var><a name="index-set_005ffunction-796"></a></var><br>
+        </div>
+
+<div class="defun">
+— : jacobian_fcn <b>jacobian_function</b> (<var>void</var>)<var> const;<a name="index-jacobian_005ffunction-797"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLFunc& <b>set_jacobian_function</b> (<var>const jacobian_fcn j</var>)<var><a name="index-set_005fjacobian_005ffunction-798"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Nonlinear-Programming.html b/doc/liboctave/HTML/Nonlinear-Programming.html
new file mode 100644
index 0000000..f312cf1
--- /dev/null
+++ b/doc/liboctave/HTML/Nonlinear-Programming.html
@@ -0,0 +1,85 @@
+<html lang="en">
+<head>
+<title>Nonlinear Programming - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Quadratic-Programming.html#Quadratic-Programming" title="Quadratic Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Nonlinear-Programming"></a>
+Previous: <a rel="previous" accesskey="p" href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">9.6 Nonlinear Programming</h3>
+
+<p><a name="index-NLP-895"></a><a name="index-nonlinear-programming-896"></a>
+
+<div class="defun">
+— :  <b>NLP</b> (<var>void</var>)<var><a name="index-NLP-897"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi</var>)<var><a name="index-NLP-898"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const Bounds &b</var>)<var><a name="index-NLP-899"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const Bounds &b, const LinConst &lc</var>)<var><a name="index-NLP-900"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const Bounds &b, const LinConst &lc, const NLConst &nlc</var>)<var><a name="index-NLP-901"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const LinConst &lc</var>)<var><a name="index-NLP-902"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const LinConst &lc, const NLConst &nlc</var>)<var><a name="index-NLP-903"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const NLConst &nlc</var>)<var><a name="index-NLP-904"></a></var><br>
+— :  <b>NLP</b> (<var>const ColumnVector &x, const Objective &phi, const Bounds &b, const NLConst &nlc</var>)<var><a name="index-NLP-905"></a></var><br>
+        </div>
+
+<div class="defun">
+— : NLP& <b>operator =</b> (<var>const NLP &a</var>)<var><a name="index-operator-_003d-906"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>size</b> (<var>void</var>)<var> const<a name="index-size-907"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>minimize</b> (<var>void</var>)<var><a name="index-minimize-908"></a></var><br>
+— : ColumnVector <b>minimize</b> (<var>double &objf</var>)<var><a name="index-minimize-909"></a></var><br>
+— : ColumnVector <b>minimize</b> (<var>double &objf, int &inform</var>)<var><a name="index-minimize-910"></a></var><br>
+— : ColumnVector <b>minimize</b> (<var>double &objf, int &inform, ColumnVector &lambda</var>)<var><a name="index-minimize-911"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>minimize</b> (<var>const ColumnVector &x</var>)<var><a name="index-minimize-912"></a></var><br>
+— : ColumnVector <b>minimize</b> (<var>const ColumnVector &x, double &objf</var>)<var><a name="index-minimize-913"></a></var><br>
+— : ColumnVector <b>minimize</b> (<var>const ColumnVector &x, double &objf, int &inform</var>)<var><a name="index-minimize-914"></a></var><br>
+— : ColumnVector <b>minimize</b> (<var>const ColumnVector &x, double &objf, int &inform, ColumnVector &lambda</var>)<var><a name="index-minimize-915"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Objective-Functions.html b/doc/liboctave/HTML/Objective-Functions.html
new file mode 100644
index 0000000..47e14e8
--- /dev/null
+++ b/doc/liboctave/HTML/Objective-Functions.html
@@ -0,0 +1,68 @@
+<html lang="en">
+<head>
+<title>Objective Functions - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Optimization.html#Optimization" title="Optimization">
+<link rel="next" href="Bounds.html#Bounds" title="Bounds">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Objective-Functions"></a>
+Next: <a rel="next" accesskey="n" href="Bounds.html#Bounds">Bounds</a>,
+Previous: <a rel="previous" accesskey="p" href="Optimization.html#Optimization">Optimization</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">9.1 Objective Functions</h3>
+
+<p><a name="index-objective-functions-821"></a>
+
+<div class="defun">
+— :  <b>Objective</b> (<var>void</var>)<var><a name="index-Objective-822"></a></var><br>
+— :  <b>Objective</b> (<var>const objective_fcn</var>)<var><a name="index-Objective-823"></a></var><br>
+— :  <b>Objective</b> (<var>const objective_fcn, const gradient_fcn</var>)<var><a name="index-Objective-824"></a></var><br>
+— :  <b>Objective</b> (<var>const Objective &a</var>)<var><a name="index-Objective-825"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Objective& <b>operator =</b> (<var>const Objective &a</var>)<var><a name="index-operator-_003d-826"></a></var><br>
+        </div>
+
+<div class="defun">
+— : objective_fcn <b>objective_function</b> (<var>void</var>)<var> const;<a name="index-objective_005ffunction-827"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Objective& <b>set_objective_function</b> (<var>const objective_fcn</var>)<var><a name="index-set_005fobjective_005ffunction-828"></a></var><br>
+        </div>
+
+<div class="defun">
+— : gradient_fcn <b>gradient_function</b> (<var>void</var>)<var> const;<a name="index-gradient_005ffunction-829"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Objective& <b>set_gradient_function</b> (<var>const gradient_fcn</var>)<var><a name="index-set_005fgradient_005ffunction-830"></a></var><br>
+        </div>
+
+<!--  -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Optimization.html b/doc/liboctave/HTML/Optimization.html
new file mode 100644
index 0000000..4d6d02d
--- /dev/null
+++ b/doc/liboctave/HTML/Optimization.html
@@ -0,0 +1,48 @@
+<html lang="en">
+<head>
+<title>Optimization - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Nonlinear-Equations.html#Nonlinear-Equations" title="Nonlinear Equations">
+<link rel="next" href="Quadrature.html#Quadrature" title="Quadrature">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Optimization"></a>
+Next: <a rel="next" accesskey="n" href="Quadrature.html#Quadrature">Quadrature</a>,
+Previous: <a rel="previous" accesskey="p" href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">9 Optimization</h2>
+
+<p><a name="index-optimization-820"></a>
+
+<ul class="menu">
+<li><a accesskey="1" href="Objective-Functions.html#Objective-Functions">Objective Functions</a>
+<li><a accesskey="2" href="Bounds.html#Bounds">Bounds</a>
+<li><a accesskey="3" href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a>
+<li><a accesskey="4" href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a>
+<li><a accesskey="5" href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>
+<li><a accesskey="6" href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Ordinary-Differential-Equations.html b/doc/liboctave/HTML/Ordinary-Differential-Equations.html
new file mode 100644
index 0000000..7a7f4a4
--- /dev/null
+++ b/doc/liboctave/HTML/Ordinary-Differential-Equations.html
@@ -0,0 +1,148 @@
+<html lang="en">
+<head>
+<title>Ordinary Differential Equations - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Quadrature.html#Quadrature" title="Quadrature">
+<link rel="next" href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations" title="Differential Algebraic Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Ordinary-Differential-Equations"></a>
+Next: <a rel="next" accesskey="n" href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a>,
+Previous: <a rel="previous" accesskey="p" href="Quadrature.html#Quadrature">Quadrature</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">11 Ordinary Differential Equations</h2>
+
+<p><a name="index-ODE-978"></a>
+
+<div class="defun">
+— :  <b>ODE_options</b> (<var>void</var>)<var><a name="index-ODE_005foptions-979"></a></var><br>
+— :  <b>ODE_options</b> (<var>const ODE_options &opt</var>)<var><a name="index-ODE_005foptions-980"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ODE_options& <b>operator =</b> (<var>const ODE_options &opt</var>)<var><a name="index-operator-_003d-981"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>init</b> (<var>void</var>)<var><a name="index-init-982"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>copy</b> (<var>const ODE_options &opt</var>)<var><a name="index-copy-983"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_default_options</b> (<var>void</var>)<var><a name="index-set_005fdefault_005foptions-984"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_absolute_tolerance</b> (<var>double val</var>)<var><a name="index-set_005fabsolute_005ftolerance-985"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_initial_step_size</b> (<var>double val</var>)<var><a name="index-set_005finitial_005fstep_005fsize-986"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_maximum_step_size</b> (<var>double val</var>)<var><a name="index-set_005fmaximum_005fstep_005fsize-987"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_minimum_step_size</b> (<var>double val</var>)<var><a name="index-set_005fminimum_005fstep_005fsize-988"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_relative_tolerance</b> (<var>double val</var>)<var><a name="index-set_005frelative_005ftolerance-989"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>absolute_tolerance</b> (<var>void</var>)<var><a name="index-absolute_005ftolerance-990"></a></var><br>
+— : double <b>initial_step_size</b> (<var>void</var>)<var><a name="index-initial_005fstep_005fsize-991"></a></var><br>
+— : double <b>maximum_step_size</b> (<var>void</var>)<var><a name="index-maximum_005fstep_005fsize-992"></a></var><br>
+— : double <b>minimum_step_size</b> (<var>void</var>)<var><a name="index-minimum_005fstep_005fsize-993"></a></var><br>
+— : double <b>relative_tolerance</b> (<var>void</var>)<var><a name="index-relative_005ftolerance-994"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>ODE</b> (<var>void</var>)<var><a name="index-ODE-995"></a></var><br>
+— :  <b>ODE</b> (<var>int n</var>)<var><a name="index-ODE-996"></a></var><br>
+— :  <b>ODE</b> (<var>const ColumnVector &state, double time, const ODEFunc &f</var>)<var><a name="index-ODE-997"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual int <b>size</b> (<var>void</var>)<var> const<a name="index-size-998"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual ColumnVector <b>state</b> (<var>void</var>)<var> const<a name="index-state-999"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual double <b>time</b> (<var>void</var>)<var> const<a name="index-time-1000"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual void <b>force_restart</b> (<var>void</var>)<var><a name="index-force_005frestart-1001"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual void <b>initialize</b> (<var>const ColumnVector &x, double t</var>)<var><a name="index-initialize-1002"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual void <b>set_stop_time</b> (<var>double t</var>)<var><a name="index-set_005fstop_005ftime-1003"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual void <b>clear_stop_time</b> (<var>void</var>)<var><a name="index-clear_005fstop_005ftime-1004"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual ColumnVector <b>integrate</b> (<var>double t</var>)<var><a name="index-integrate-1005"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>integrate</b> (<var>int nsteps, double tstep, ostream &s</var>)<var><a name="index-integrate-1006"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Matrix <b>integrate</b> (<var>const ColumnVector &tout</var>)<var><a name="index-integrate-1007"></a></var><br>
+— : Matrix <b>integrate</b> (<var>const ColumnVector &tout, const ColumnVector &tcrit</var>)<var><a name="index-integrate-1008"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Quadratic-Programming.html b/doc/liboctave/HTML/Quadratic-Programming.html
new file mode 100644
index 0000000..cc7c47d
--- /dev/null
+++ b/doc/liboctave/HTML/Quadratic-Programming.html
@@ -0,0 +1,71 @@
+<html lang="en">
+<head>
+<title>Quadratic Programming - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="up" href="Optimization.html#Optimization" title="Optimization">
+<link rel="prev" href="Nonlinear-Constraints.html#Nonlinear-Constraints" title="Nonlinear Constraints">
+<link rel="next" href="Nonlinear-Programming.html#Nonlinear-Programming" title="Nonlinear Programming">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Quadratic-Programming"></a>
+Next: <a rel="next" accesskey="n" href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>,
+Previous: <a rel="previous" accesskey="p" href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a>,
+Up: <a rel="up" accesskey="u" href="Optimization.html#Optimization">Optimization</a>
+<hr>
+</div>
+
+<h3 class="section">9.5 Quadratic Programming</h3>
+
+<p><a name="index-QP-875"></a><a name="index-quadratic-programming-876"></a>
+
+<div class="defun">
+— :  <b>QP</b> (<var>void</var>)<var><a name="index-QP-877"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H</var>)<var><a name="index-QP-878"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const ColumnVector &c</var>)<var><a name="index-QP-879"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const Bounds &b</var>)<var><a name="index-QP-880"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const LinConst &lc</var>)<var><a name="index-QP-881"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const ColumnVector &c, const Bounds &b</var>)<var><a name="index-QP-882"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const ColumnVector &c, const LinConst &lc</var>)<var><a name="index-QP-883"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const Bounds &b, const LinConst &lc</var>)<var><a name="index-QP-884"></a></var><br>
+— :  <b>QP</b> (<var>const ColumnVector &x, const Matrix &H, const ColumnVector &c, const Bounds &b, const LinConst &lc</var>)<var><a name="index-QP-885"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual ColumnVector <b>minimize</b> (<var>void</var>)<var><a name="index-minimize-886"></a></var><br>
+— : virtual ColumnVector <b>minimize</b> (<var>double &objf</var>)<var><a name="index-minimize-887"></a></var><br>
+— : virtual ColumnVector <b>minimize</b> (<var>double &objf, int &inform</var>)<var><a name="index-minimize-888"></a></var><br>
+— : virtual ColumnVector <b>minimize</b> (<var>double &objf, int &inform, ColumnVector &lambda</var>)<var> = 0;<a name="index-minimize-889"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual ColumnVector <b>minimize</b> (<var>const ColumnVector &x</var>)<var><a name="index-minimize-890"></a></var><br>
+— : virtual ColumnVector <b>minimize</b> (<var>const ColumnVector &x, double &objf</var>)<var><a name="index-minimize-891"></a></var><br>
+— : virtual ColumnVector <b>minimize</b> (<var>const ColumnVector &x, double &objf, int &inform</var>)<var><a name="index-minimize-892"></a></var><br>
+— : virtual ColumnVector <b>minimize</b> (<var>const ColumnVector &x, double &objf, int &inform, ColumnVector &lambda</var>)<var><a name="index-minimize-893"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ColumnVector <b>minimize</b> (<var>double &objf, int &inform, ColumnVector &lambda</var>)<var><a name="index-minimize-894"></a></var><br>
+        </div>
+
+<!--  -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Quadrature.html b/doc/liboctave/HTML/Quadrature.html
new file mode 100644
index 0000000..a4bdfb7
--- /dev/null
+++ b/doc/liboctave/HTML/Quadrature.html
@@ -0,0 +1,106 @@
+<html lang="en">
+<head>
+<title>Quadrature - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Optimization.html#Optimization" title="Optimization">
+<link rel="next" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations" title="Ordinary Differential Equations">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Quadrature"></a>
+Next: <a rel="next" accesskey="n" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a>,
+Previous: <a rel="previous" accesskey="p" href="Optimization.html#Optimization">Optimization</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">10 Quadrature</h2>
+
+<p><a name="index-quadrature-916"></a><a name="index-numerical-integration-917"></a><a name="index-integration-918"></a>
+
+<div class="defun">
+— :  <b>Quad</b> (<var>integrand_fcn fcn</var>)<var><a name="index-Quad-919"></a></var><br>
+— :  <b>Quad</b> (<var>integrand_fcn fcn, double abs, double rel</var>)<var><a name="index-Quad-920"></a></var><br>
+        </div>
+
+<div class="defun">
+— : virtual double <b>integrate</b> (<var>void</var>)<var><a name="index-integrate-921"></a></var><br>
+— : virtual double <b>integrate</b> (<var>int &ier</var>)<var><a name="index-integrate-922"></a></var><br>
+— : virtual double <b>integrate</b> (<var>int &ier, int &neval</var>)<var><a name="index-integrate-923"></a></var><br>
+— : virtual double <b>integrate</b> (<var>int &ier, int &neval, double &abserr</var>)<var> = 0<a name="index-integrate-924"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>Quad_options</b> (<var>void</var>)<var><a name="index-Quad_005foptions-925"></a></var><br>
+— :  <b>Quad_options</b> (<var>const Quad_options &opt</var>)<var><a name="index-Quad_005foptions-926"></a></var><br>
+        </div>
+
+<div class="defun">
+— : Quad_options& <b>operator =</b> (<var>const Quad_options &opt</var>)<var><a name="index-operator-_003d-927"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>init</b> (<var>void</var>)<var><a name="index-init-928"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>copy</b> (<var>const Quad_options &opt</var>)<var><a name="index-copy-929"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_default_options</b> (<var>void</var>)<var><a name="index-set_005fdefault_005foptions-930"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_absolute_tolerance</b> (<var>double val</var>)<var><a name="index-set_005fabsolute_005ftolerance-931"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_relative_tolerance</b> (<var>double val</var>)<var><a name="index-set_005frelative_005ftolerance-932"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>absolute_tolerance</b> (<var>void</var>)<var><a name="index-absolute_005ftolerance-933"></a></var><br>
+— : double <b>relative_tolerance</b> (<var>void</var>)<var><a name="index-relative_005ftolerance-934"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn</var>)<var><a name="index-DefQuad-935"></a></var><br>
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn, double ll, double ul</var>)<var><a name="index-DefQuad-936"></a></var><br>
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn, double ll, double ul, double abs, double rel</var>)<var><a name="index-DefQuad-937"></a></var><br>
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn, double ll, double ul, const ColumnVector &sing</var>)<var><a name="index-DefQuad-938"></a></var><br>
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn, const ColumnVector &sing, double abs, double rel</var>)<var><a name="index-DefQuad-939"></a></var><br>
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn, const ColumnVector &sing</var>)<var><a name="index-DefQuad-940"></a></var><br>
+— :  <b>DefQuad</b> (<var>integrand_fcn fcn, double ll, double ul, const ColumnVector &sing, double abs, double rel</var>)<var><a name="index-DefQuad-941"></a></var><br>
+        </div>
+
+<div class="defun">
+— :  <b>IndefQuad</b> (<var>integrand_fcn fcn</var>)<var><a name="index-IndefQuad-942"></a></var><br>
+— :  <b>IndefQuad</b> (<var>integrand_fcn fcn, double b, IntegralType t</var>)<var><a name="index-IndefQuad-943"></a></var><br>
+— :  <b>IndefQuad</b> (<var>integrand_fcn fcn, double b, IntegralType t, double abs, double rel</var>)<var><a name="index-IndefQuad-944"></a></var><br>
+— :  <b>IndefQuad</b> (<var>integrand_fcn fcn, double abs, double rel</var>)<var><a name="index-IndefQuad-945"></a></var><br>
+        </div>
+
+<ul class="menu">
+<li><a accesskey="1" href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a>
+</ul>
+
+   </body></html>
+
diff --git a/doc/liboctave/HTML/Ranges.html b/doc/liboctave/HTML/Ranges.html
new file mode 100644
index 0000000..53d550a
--- /dev/null
+++ b/doc/liboctave/HTML/Ranges.html
@@ -0,0 +1,93 @@
+<html lang="en">
+<head>
+<title>Ranges - Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="index.html#Top">
+<link rel="prev" href="Matrix-Factorizations.html#Matrix-Factorizations" title="Matrix Factorizations">
+<link rel="next" href="Nonlinear-Functions.html#Nonlinear-Functions" title="Nonlinear Functions">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<div class="node">
+<p>
+<a name="Ranges"></a>
+Next: <a rel="next" accesskey="n" href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a>,
+Previous: <a rel="previous" accesskey="p" href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>,
+Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
+<hr>
+</div>
+
+<h2 class="chapter">6 Ranges</h2>
+
+<p><a name="index-ranges-771"></a>
+
+<div class="defun">
+— :  <b>Range</b> (<var>void</var>)<var><a name="index-Range-772"></a></var><br>
+— :  <b>Range</b> (<var>const Range &r</var>)<var><a name="index-Range-773"></a></var><br>
+— :  <b>Range</b> (<var>double b, double l</var>)<var><a name="index-Range-774"></a></var><br>
+— :  <b>Range</b> (<var>double b, double l, double i</var>)<var><a name="index-Range-775"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>base</b> (<var>void</var>)<var> const<a name="index-base-776"></a></var><br>
+— : double <b>limit</b> (<var>void</var>)<var> const<a name="index-limit-777"></a></var><br>
+— : double <b>inc</b> (<var>void</var>)<var> const<a name="index-inc-778"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>set_base</b> (<var>double b</var>)<var><a name="index-set_005fbase-779"></a></var><br>
+— : void <b>set_limit</b> (<var>double l</var>)<var><a name="index-set_005flimit-780"></a></var><br>
+— : void <b>set_inc</b> (<var>double i</var>)<var><a name="index-set_005finc-781"></a></var><br>
+        </div>
+
+<div class="defun">
+— : int <b>nelem</b> (<var>void</var>)<var> const<a name="index-nelem-782"></a></var><br>
+        </div>
+
+<div class="defun">
+— : double <b>min</b> (<var>void</var>)<var> const<a name="index-min-783"></a></var><br>
+— : double <b>max</b> (<var>void</var>)<var> const<a name="index-max-784"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>sort</b> (<var>void</var>)<var><a name="index-sort-785"></a></var><br>
+        </div>
+
+<div class="defun">
+— : ostream& <b>operator <<</b> (<var>ostream &os, const Range &r</var>)<var><a name="index-operator-_003c_003c-786"></a></var><br>
+— : istream& <b>operator >></b> (<var>istream &is, Range &r</var>)<var><a name="index-operator-_003e_003e-787"></a></var><br>
+        </div>
+
+<div class="defun">
+— : void <b>print_range</b> (<var>void</var>)<var><a name="index-print_005frange-788"></a></var><br>
+        </div>
+
+<!-- Copyright (C) 1997, 2006, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/HTML/index.html b/doc/liboctave/HTML/index.html
new file mode 100644
index 0000000..d1be80b
--- /dev/null
+++ b/doc/liboctave/HTML/index.html
@@ -0,0 +1,167 @@
+<html lang="en">
+<head>
+<title>Octave C++ Classes</title>
+<meta http-equiv="Content-Type" content="text/html">
+<meta name="description" content="Octave C++ Classes">
+<meta name="generator" content="makeinfo 4.11">
+<link title="Top" rel="start" href="#Top">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+Copyright (C) 1996, 1997 John W. Eaton.
+
+   <p>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.
+
+   <p>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.
+
+   <p>Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for
+modified versions.
+
+<div class="contents">
+<h2>Table of Contents</h2>
+<ul>
+<li><a name="toc_Top" href="index.html#Top">Octave C++ Classes</a>
+<li><a name="toc_Acknowledgements" href="Acknowledgements.html#Acknowledgements">1 Acknowledgements</a>
+<ul>
+<li><a href="Contributors.html#Contributors">Contributors to Octave</a>
+</li></ul>
+<li><a name="toc_Copying" href="Copying.html#Copying">GNU GENERAL PUBLIC LICENSE</a>
+<li><a name="toc_Introduction" href="Introduction.html#Introduction">2 A Brief Introduction to Octave</a>
+<li><a name="toc_Arrays" href="Arrays.html#Arrays">3 Arrays</a>
+<ul>
+<li><a href="Constructors-and-Assignment.html#Constructors-and-Assignment">3.1 Constructors and Assignment</a>
+</li></ul>
+<li><a name="toc_Matrix-and-Vector-Operations" href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">4 Matrix and Vector Operations</a>
+<li><a name="toc_Matrix-Factorizations" href="Matrix-Factorizations.html#Matrix-Factorizations">5 Matrix Factorizations</a>
+<li><a name="toc_Ranges" href="Ranges.html#Ranges">6 Ranges</a>
+<li><a name="toc_Nonlinear-Functions" href="Nonlinear-Functions.html#Nonlinear-Functions">7 Nonlinear Functions</a>
+<li><a name="toc_Nonlinear-Equations" href="Nonlinear-Equations.html#Nonlinear-Equations">8 Nonlinear Equations</a>
+<li><a name="toc_Optimization" href="Optimization.html#Optimization">9 Optimization</a>
+<ul>
+<li><a href="Objective-Functions.html#Objective-Functions">9.1 Objective Functions</a>
+<li><a href="Bounds.html#Bounds">9.2 Bounds</a>
+<li><a href="Linear-Constraints.html#Linear-Constraints">9.3 Linear Constraints</a>
+<li><a href="Nonlinear-Constraints.html#Nonlinear-Constraints">9.4 Nonlinear Constraints</a>
+<li><a href="Quadratic-Programming.html#Quadratic-Programming">9.5 Quadratic Programming</a>
+<li><a href="Nonlinear-Programming.html#Nonlinear-Programming">9.6 Nonlinear Programming</a>
+</li></ul>
+<li><a name="toc_Quadrature" href="Quadrature.html#Quadrature">10 Quadrature</a>
+<ul>
+<li><a href="Collocation-Weights.html#Collocation-Weights">10.1 Collocation Weights</a>
+</li></ul>
+<li><a name="toc_Ordinary-Differential-Equations" href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">11 Ordinary Differential Equations</a>
+<li><a name="toc_Differential-Algebraic-Equations" href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">12 Differential Algebraic Equations</a>
+<li><a name="toc_Error-Handling" href="Error-Handling.html#Error-Handling">13 Error Handling</a>
+<li><a name="toc_Installation" href="Installation.html#Installation">14 Installation</a>
+<li><a name="toc_Bugs" href="Bugs.html#Bugs">15 Bugs</a>
+<li><a name="toc_Concept-Index" href="Concept-Index.html#Concept-Index">Concept Index</a>
+<li><a name="toc_Function-Index" href="Function-Index.html#Function-Index">Function Index</a>
+</li></ul>
+</div>
+
+<div class="node">
+<p>
+<a name="Top"></a>
+Next: <a rel="next" accesskey="n" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>,
+Previous: <a rel="previous" accesskey="p" href="../index.html#dir">(dir)</a>,
+Up: <a rel="up" accesskey="u" href="../index.html#dir">(dir)</a>
+<hr>
+</div>
+
+<h2 class="unnumbered">Octave C++ Classes</h2>
+
+<p>This manual documents how to use, install and port Octave's C++ class
+library, and how to report bugs.  It corresponds to Octave version
+3.2.4.
+
+<!--  -->
+<ul class="menu">
+<li><a accesskey="1" href="Acknowledgements.html#Acknowledgements">Acknowledgements</a>
+<li><a accesskey="2" href="Copying.html#Copying">Copying</a>
+<li><a accesskey="3" href="Introduction.html#Introduction">Introduction</a>
+<li><a accesskey="4" href="Arrays.html#Arrays">Arrays</a>
+<li><a accesskey="5" href="Matrix-and-Vector-Operations.html#Matrix-and-Vector-Operations">Matrix and Vector Operations</a>
+<li><a accesskey="6" href="Matrix-Factorizations.html#Matrix-Factorizations">Matrix Factorizations</a>
+<li><a accesskey="7" href="Ranges.html#Ranges">Ranges</a>
+<li><a accesskey="8" href="Nonlinear-Functions.html#Nonlinear-Functions">Nonlinear Functions</a>
+<li><a accesskey="9" href="Nonlinear-Equations.html#Nonlinear-Equations">Nonlinear Equations</a>
+<li><a href="Optimization.html#Optimization">Optimization</a>
+<li><a href="Quadrature.html#Quadrature">Quadrature</a>
+<li><a href="Ordinary-Differential-Equations.html#Ordinary-Differential-Equations">Ordinary Differential Equations</a>
+<li><a href="Differential-Algebraic-Equations.html#Differential-Algebraic-Equations">Differential Algebraic Equations</a>
+<li><a href="Error-Handling.html#Error-Handling">Error Handling</a>
+<li><a href="Installation.html#Installation">Installation</a>
+<li><a href="Bugs.html#Bugs">Bugs</a>
+<li><a href="Concept-Index.html#Concept-Index">Concept Index</a>
+<li><a href="Function-Index.html#Function-Index">Function Index</a>
+
+</li></ul>
+<p>--- The Detailed Node Listing ---
+
+<p>Acknowledgements
+
+</p>
+<ul class="menu">
+<li><a href="Contributors.html#Contributors">Contributors</a>:                 People who contributed to developing of Octave.
+
+</li></ul>
+<p>Arrays
+
+</p>
+<ul class="menu">
+<li><a href="Constructors-and-Assignment.html#Constructors-and-Assignment">Constructors and Assignment</a>
+
+</li></ul>
+<p>Optimization
+
+</p>
+<ul class="menu">
+<li><a href="Objective-Functions.html#Objective-Functions">Objective Functions</a>
+<li><a href="Bounds.html#Bounds">Bounds</a>
+<li><a href="Linear-Constraints.html#Linear-Constraints">Linear Constraints</a>
+<li><a href="Nonlinear-Constraints.html#Nonlinear-Constraints">Nonlinear Constraints</a>
+<li><a href="Quadratic-Programming.html#Quadratic-Programming">Quadratic Programming</a>
+<li><a href="Nonlinear-Programming.html#Nonlinear-Programming">Nonlinear Programming</a>
+
+</li></ul>
+<p>Quadrature
+
+</p>
+<ul class="menu">
+<li><a href="Collocation-Weights.html#Collocation-Weights">Collocation Weights</a>
+</ul>
+
+<!--  -->
+<!-- Copyright (C) 1996, 2007 John W. Eaton -->
+<!-- This file is part of Octave. -->
+<!-- Octave is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU General Public License as published by the -->
+<!-- Free Software Foundation; either version 3 of the License, or (at -->
+<!-- your option) any later version. -->
+<!-- Octave is distributed in the hope that it will be useful, but WITHOUT -->
+<!-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -->
+<!-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License -->
+<!-- for more details. -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with Octave; see the file COPYING.  If not, see -->
+<!-- <http://www.gnu.org/licenses/>. -->
+   </body></html>
+
diff --git a/doc/liboctave/Makefile.in b/doc/liboctave/Makefile.in
new file mode 100644
index 0000000..7e79358
--- /dev/null
+++ b/doc/liboctave/Makefile.in
@@ -0,0 +1,125 @@
+# Makefile for octave's doc/liboctave directory
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+#               2005, 2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES =
+
+MAIN_TEXINFO = liboctave.texi
+
+SUB_TEXINFO = \
+	array.texi bugs.texi cp-idx.texi dae.texi diffeq.texi \
+	error.texi factor.texi fn-idx.texi install.texi intro.texi \
+	matvec.texi nleqn.texi nlfunc.texi ode.texi \
+	optim.texi preface.texi quad.texi range.texi
+
+TEXINFO_SOURCE = $(MAIN_TEXINFO) $(SUB_TEXINFO)
+
+TEXINFO = $(TEXINFO_SOURCE) ../conf.texi
+
+FORMATTED = liboctave.dvi liboctave.ps liboctave.pdf liboctave.info
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in gpl.texi $(TEXINFO_SOURCE)) \
+	 $(FORMATTED)
+
+DISTDIRS = HTML
+
+SPELL = $(patsubst %.texi, %.spell, $(TEXINFO))
+
+%.spell : %.texi
+	rm -f $@
+	$(SED) -e 's/@@/ at /g' -e 's/@[a-zA-Z]*//g' $< | spell > $@.tmp
+	mv $@.tmp $@
+
+all: liboctave.info liboctave.dvi liboctave.ps liboctave.pdf HTML/index.html
+.PHONY: all
+
+liboctave.info: $(TEXINFO)
+	-$(MAKEINFO) -I.. -I$(srcdir) -I$(srcdir)/.. $<
+
+liboctave.dvi: $(TEXINFO)
+	-TEXINPUTS="..$(sepchar)$(srcdir)$(sepchar)$(srcdir)/..$(sepchar)$(TEXINPUTS)$(sepchar)" \
+	  $(TEXI2DVI) $<
+
+liboctave.ps: liboctave.dvi
+	-dvips -o $@ $<
+
+liboctave.pdf: $(TEXINFO)
+	-TEXINPUTS="..$(sepchar)$(srcdir)$(sepchar)$(srcdir)/..$(sepchar)$(TEXINPUTS)$(sepchar)" \
+	  $(TEXI2PDF) $<
+
+HTML/index.html: $(TEXINFO)
+	-$(MAKEINFO) --html --ifinfo --output=HTML -I.. -I$(srcdir) -I$(srcdir)/.. $<
+
+check:
+.PHONY: check
+
+install install-strip: all
+.PHONY: install install-strip
+
+uninstall:
+	rm -f $(DESTDIR)$(infodir)/liboctave.info*
+.PHONY: uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+spell: $(SPELL)
+.PHONY: spell
+
+mostlyclean clean:
+	rm -f liboctave.cp liboctave.fn liboctave.pg liboctave.tp \
+	liboctave.vr liboctave.ky liboctave.op liboctave.vrs \
+	liboctave.kys liboctave.ops liboctave.cps liboctave.fns \
+	liboctave.pgs liboctave.tps liboctave.aux liboctave.log \
+	liboctave.toc
+.PHONY: mostlyclean clean
+
+distclean: clean
+	rm -f Makefile
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS liboctave.info liboctave.info-*
+	rm -f liboctave.dvi liboctave.ps liboctave.pdf
+	rm -rf HTML
+.PHONY: maintainer-clean
+
+dist: all
+	ln $(DISTFILES) ../../`cat ../../.fname`/doc/liboctave
+	for dir in $(DISTDIRS); do \
+	  mkdir ../../`cat ../../.fname`/doc/liboctave/$$dir; \
+	  ln ../../doc/liboctave/$$dir/* ../../`cat ../../.fname`/doc/liboctave/$$dir; \
+	done
+.PHONY: dist
diff --git a/doc/liboctave/array.texi b/doc/liboctave/array.texi
new file mode 100644
index 0000000..efbdb5e
--- /dev/null
+++ b/doc/liboctave/array.texi
@@ -0,0 +1,209 @@
+ at c Copyright (C) 1996, 1998, 2002, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Arrays, Matrix and Vector Operations, Introduction, Top
+ at chapter Arrays
+ at cindex arrays
+
+ at menu
+* Constructors and Assignment::  
+ at end menu
+
+ at node Constructors and Assignment,  , Arrays, Arrays
+ at section Constructors and Assignment
+
+ at deftypefn Constructor {} Array<T> (void)
+Create an array with no elements.
+ at end deftypefn
+
+ at deftypefn Constructor {} Array<T> (int @var{n} [, const T &@var{val}])
+Create an array with @var{n} elements.  If the optional argument
+ at var{val} is supplied, the elements are initialized to @var{val};
+otherwise, they are left uninitialized.  If @var{n} is less than zero,
+the current error handler is invoked (@pxref{Error Handling}).
+ at end deftypefn
+
+ at deftypefn Constructor {} Array<T> (const Array<T> &@var{a})
+Create a copy of the @var{Array<T>} object @var{a}.  Memory for the
+ at var{Array<T>} class is managed using a reference counting scheme, so
+the cost of this operation is independent of the size of the array.
+ at end deftypefn
+
+ at deftypeop Assignment Array<T> Array<T>& {operator =} (const Array<T> &@var{a})
+Assignment operator.  Memory for the @var{Array<T>} class is managed
+using a reference counting scheme, so the cost of this operation is
+independent of the size of the array.
+ at end deftypeop
+
+ at deftypemethod Array<T> int capacity (void) const
+ at deftypemethodx Array<T> int length (void) const
+Return the length of the array.
+ at end deftypemethod
+
+ at deftypemethod Array<T> T& elem (int @var{n})
+ at deftypemethodx Array<T> T& checkelem (int @var{n})
+If @var{n} is within the bounds of the array, return a reference to the
+element indexed by @var{n}; otherwise, the current error handler is
+invoked (@pxref{Error Handling}).
+ at end deftypemethod
+
+ at deftypeop Indexing Array<T> T& {operator ()} (int @var{n})
+ at end deftypeop
+
+ at deftypemethod Array<T> T elem (int @var{n}) const
+ at deftypemethodx Array<T> T checkelem (int @var{n}) const
+If @var{n} is within the bounds of the array, return the value indexed
+by @var{n}; otherwise, call the current error handler.
+ at xref{Error Handling}.
+ at end deftypemethod
+
+ at deftypeop Indexing Array<T> T {operator ()} (int @var{n}) const
+ at end deftypeop
+
+ at deftypemethod Array<T> T& xelem (int @var{n})
+ at deftypemethodx Array<T> T xelem (int @var{n}) const
+Return a reference to, or the value of, the element indexed by @var{n}.
+These methods never perform bounds checking.
+ at end deftypemethod
+
+ at deftypemethod Array<T> void resize {(int @var{n} [, const T &@var{val}])}
+Change the size of the array to be @var{n} elements.  All elements are
+unchanged, except that if @var{n} is greater than the current size and
+the optional argument @var{val} is provided, the additional elements are
+initialized to @var{val}; otherwise, any additional elements are left
+uninitialized.  In the current implementation, if @var{n} is less than
+the current size, the length is updated but no memory is released.
+ at end deftypemethod
+
+ at deftypemethod Array<T> {const T*} data (void) const
+ at end deftypemethod
+
+ at c Should this be public?
+ at c
+ at c T *fortran_vec (void)
+
+ at deftypefn Constructor {} Array2<T> Array2<T> Array2 (void)
+ at deftypefnx Constructor {} Array2<T> (int @var{n}, int @var{m})
+ at deftypefnx Constructor {} Array2<T> (int @var{n}, int @var{m}, const T &@var{val})
+ at deftypefnx Constructor {} Array2<T> (const Array2<T> &@var{a})
+ at deftypefnx Constructor {} Array2<T> (const DiagArray<T> &@var{a})
+ at end deftypefn
+
+ at deftypeop Assignment Array2<T> Array2<T>& {operator =} (const Array2<T> &@var{a})
+ at end deftypeop
+
+ at deftypemethod Array2<T> int dim1 (void) const
+ at deftypemethodx Array2<T> int rows (void) const
+ at end deftypemethod
+
+ at deftypemethod Array2<T> int dim2 (void) const
+ at deftypemethodx Array2<T> int cols (void) const
+ at deftypemethodx Array2<T> int columns (void) const
+ at end deftypemethod
+
+ at deftypemethod Array2<T> T& elem (int @var{i}, int @var{j})
+ at deftypemethodx Array2<T> T& checkelem (int @var{i}, int @var{j})
+ at end deftypemethod
+
+ at deftypeop Indexing Array2<T> T& {operator ()} (int @var{i}, int @var{j})
+ at end deftypeop
+
+ at c This needs to be fixed.
+ at c
+ at c T& xelem (int i, int j)
+ at c
+ at c T elem (int i, int j) const
+ at c T checkelem (int i, int j) const
+ at c T operator () (int i, int j) const
+
+ at deftypemethod Array2<T> void resize (int @var{n}, int @var{m})
+ at deftypemethodx Array2<T> void resize (int @var{n}, int @var{m}, const T &@var{val})
+ at end deftypemethod
+
+ at deftypefn Constructor {} Array3<T> (void)
+ at deftypefnx Constructor {} Array3<T> (int @var{n}, int @var{m}, int @var{k})
+ at deftypefnx Constructor {} Array3<T> (int @var{n}, int @var{m}, int @var{k}, const T &@var{val})
+ at deftypefnx Constructor {} Array3<T> (const Array3<T> &@var{a})
+ at end deftypefn
+
+ at deftypeop Assignment Array3<T> Array3<T>& {operator =} (const Array3<T> &@var{a})
+ at end deftypeop
+
+ at deftypemethod Array3<T> int dim1 (void) const
+ at deftypemethodx Array3<T> int dim2 (void) const
+ at deftypemethodx Array3<T> int dim3 (void) const
+ at end deftypemethod
+
+ at deftypemethod Array3<T> T& elem (int @var{i}, int @var{j}, int @var{k})
+ at deftypemethodx Array3<T> T& checkelem (int @var{i}, int @var{j}, int @var{k})
+ at end deftypemethod
+
+ at deftypeop Indexing Array3<T> T& {operator ()} (int @var{i}, int @var{j}, int @var{k})
+ at end deftypeop
+
+ at c This needs to be fixed.
+ at c
+ at c T& xelem (int i, int j, int k)
+ at c
+ at c T elem (int i, int j, int k) const
+ at c T checkelem (int i, int j, int k) const
+ at c T operator () (int i, int j, int k) const
+
+ at deftypemethod Array3<T> void resize (int @var{n}, int @var{m}, int @var{k})
+ at deftypemethodx Array3<T> void resize (int @var{n}, int @var{m}, int @var{k}, const T &@var{val})
+ at end deftypemethod
+
+ at deftypefn Constructor {} DiagArray<T> (void)
+ at deftypefnx Constructor {} DiagArray<T> (int @var{n})
+ at deftypefnx Constructor {} DiagArray<T> (int @var{n}, const T &@var{val})
+ at deftypefnx Constructor {} DiagArray<T> (int @var{r}, int @var{c})
+ at deftypefnx Constructor {} DiagArray<T> (int @var{r}, int @var{c}, const T &@var{val})
+ at deftypefnx Constructor {} DiagArray<T> (const Array<T> &@var{a})
+ at deftypefnx Constructor {} DiagArray<T> (const DiagArray<T> &@var{a})
+ at end deftypefn
+
+ at deftypeop Assginment DiagArray<T>& {} {operator =} (const DiagArray<T> &@var{a})
+ at end deftypeop
+
+ at deftypemethod DiagArray<T> int dim1 (void) const
+ at deftypemethodx DiagArray<T> int rows (void) const
+ at end deftypemethod
+
+ at deftypemethod DiagArray<T> int dim2 (void) const
+ at deftypemethodx DiagArray<T> int cols (void) const
+ at deftypemethodx DiagArray<T> int columns (void) const
+ at end deftypemethod
+
+ at deftypemethod DiagArray<T> T& elem (int @var{r}, int @var{c})
+ at deftypemethodx DiagArray<T> T& checkelem (int @var{r}, int @var{c})
+ at end deftypemethod
+
+ at deftypeop Indexing DiagArray<T> T& {operator ()} (int @var{r}, int @var{c})
+ at end deftypeop
+
+ at c This needs to be fixed.
+ at c
+ at c T& xelem (int r, int c)
+ at c
+ at c T elem (int r, int c) const
+ at c T checkelem (int r, int c) const
+ at c T operator () (int r, int c) const
+
+ at deftypemethod DiagArray<T> void resize (int @var{n}, int @var{m})
+ at deftypemethodx DiagArray<T> void resize (int @var{n}, int @var{m}, const T &@var{val})
+ at end deftypemethod
diff --git a/doc/liboctave/bugs.texi b/doc/liboctave/bugs.texi
new file mode 100644
index 0000000..2976565
--- /dev/null
+++ b/doc/liboctave/bugs.texi
@@ -0,0 +1,24 @@
+ at c Copyright (C) 1996, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Bugs, Concept Index, Installation, Top
+ at chapter Bugs
+ at cindex bugs, known
+ at cindex installation trouble
+ at cindex known causes of trouble
+ at cindex troubleshooting
diff --git a/doc/liboctave/cp-idx.texi b/doc/liboctave/cp-idx.texi
new file mode 100644
index 0000000..edf6289
--- /dev/null
+++ b/doc/liboctave/cp-idx.texi
@@ -0,0 +1,22 @@
+ at c Copyright (C) 1996, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Concept Index, Function Index, Bugs, Top
+ at unnumbered Concept Index
+
+ at printindex cp
diff --git a/doc/liboctave/dae.texi b/doc/liboctave/dae.texi
new file mode 100644
index 0000000..94f3712
--- /dev/null
+++ b/doc/liboctave/dae.texi
@@ -0,0 +1,41 @@
+ at c Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Differential Algebraic Equations, Error Handling, Ordinary Differential Equations, Top
+ at chapter Differential Algebraic Equations
+ at cindex DAE
+
+ at deftypefn  {} {} DAE (void)
+ at deftypefnx  {} {} DAE (int @var{n})
+ at deftypefnx  {} {} DAE (const ColumnVector &@var{x}, double @var{time}, DAEFunc &@var{f})
+ at deftypefnx  {} {} DAE (const ColumnVector &@var{x}, ColumnVector &@var{xdot}, double @var{time}, DAEFunc &@var{f})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector deriv (void)
+ at end deftypefn
+
+ at deftypefn {} {virtual void} initialize (const ColumnVector &@var{x}, double @var{t})
+ at deftypefnx {} {virtual void} initialize (const ColumnVector &@var{x}, ColumnVector &@var{xdot}, double @var{t})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector integrate (double @var{t})
+ at end deftypefn
+
+ at deftypefn {} Matrix integrate (const ColumnVector &@var{tout}, Matrix &@var{xdot_out})
+ at deftypefnx {} Matrix integrate (const ColumnVector &@var{tout}, Matrix &@var{xdot_out}, const ColumnVector &@var{tcrit})
+ at end deftypefn
diff --git a/doc/liboctave/diffeq.texi b/doc/liboctave/diffeq.texi
new file mode 100644
index 0000000..c5fe28e
--- /dev/null
+++ b/doc/liboctave/diffeq.texi
@@ -0,0 +1,95 @@
+ at c Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Ordinary Differential Equations, Differential Algebraic Equations, Quadrature, Top
+ at chapter Ordinary Differential Equations
+ at cindex ODE
+
+ at deftypefn  {} {} ODE_options (void)
+ at deftypefnx  {} {} ODE_options (const ODE_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} ODE_options& {operator =} (const ODE_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void init (void)
+ at end deftypefn
+
+ at deftypefn {} void copy (const ODE_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void set_default_options (void)
+ at end deftypefn
+
+ at deftypefn {} void set_absolute_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_initial_step_size (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_maximum_step_size (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_minimum_step_size (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_relative_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} double absolute_tolerance (void)
+ at deftypefnx {} double initial_step_size (void)
+ at deftypefnx {} double maximum_step_size (void)
+ at deftypefnx {} double minimum_step_size (void)
+ at deftypefnx {} double relative_tolerance (void)
+ at end deftypefn
+
+ at deftypefn  {} {} ODE (void)
+ at deftypefnx  {} {} ODE (int @var{n})
+ at deftypefnx  {} {} ODE (const ColumnVector &@var{state}, double @var{time}, const ODEFunc &@var{f})
+ at end deftypefn
+
+ at deftypefn {} {virtual int} size (void) const
+ at end deftypefn
+
+ at deftypefn {} {virtual ColumnVector} state (void) const
+ at end deftypefn
+
+ at deftypefn {} {virtual double} time (void) const
+ at end deftypefn
+
+ at deftypefn {} {virtual void} force_restart (void)
+ at end deftypefn
+
+ at deftypefn {} {virtual void} initialize (const ColumnVector &@var{x}, double @var{t})
+ at end deftypefn
+
+ at deftypefn {} {virtual void} set_stop_time (double @var{t})
+ at end deftypefn
+
+ at deftypefn {} {virtual void} clear_stop_time (void)
+ at end deftypefn
+
+ at deftypefn {} {virtual ColumnVector} integrate (double @var{t})
+ at end deftypefn
+
+ at deftypefn {} void integrate (int @var{nsteps}, double @var{tstep}, ostream &@var{s})
+ at end deftypefn
+
+ at deftypefn {} Matrix integrate (const ColumnVector &@var{tout})
+ at deftypefnx {} Matrix integrate (const ColumnVector &@var{tout}, const ColumnVector &@var{tcrit})
+ at end deftypefn
diff --git a/doc/liboctave/error.texi b/doc/liboctave/error.texi
new file mode 100644
index 0000000..0a3ebdd
--- /dev/null
+++ b/doc/liboctave/error.texi
@@ -0,0 +1,21 @@
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Error Handling, Installation, Differential Algebraic Equations, Top
+ at chapter Error Handling
+
diff --git a/doc/liboctave/factor.texi b/doc/liboctave/factor.texi
new file mode 100644
index 0000000..3d24be4
--- /dev/null
+++ b/doc/liboctave/factor.texi
@@ -0,0 +1,317 @@
+ at c Copyright (C) 1996, 1998, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Matrix Factorizations, Ranges, Matrix and Vector Operations, Top
+ at chapter Matrix Factorizations
+ at cindex matrix factorizations
+ at cindex factorizations
+
+ at deftypefn  {} {} AEPBALANCE (void)
+ at deftypefnx  {} {} AEPBALANCE (const Matrix &@var{a}, const char *@var{balance_job})
+ at deftypefnx  {} {} AEPBALANCE (const AEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} AEPBALANCE& {operator =} (const AEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix balanced_matrix (void) const
+ at deftypefnx {} Matrix balancing_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const AEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {} ComplexAEPBALANCE (void)
+ at deftypefnx {} {} ComplexAEPBALANCE (const ComplexMatrix &@var{a}, const char *@var{balance_job})
+ at deftypefnx {} {} ComplexAEPBALANCE (const ComplexAEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexAEPBALANCE& {operator =} (const ComplexAEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix balanced_matrix (void) const
+ at deftypefnx {} ComplexMatrix balancing_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexAEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} DET (void)
+ at deftypefnx  {} {} DET (const DET &@var{a})
+ at end deftypefn
+
+ at deftypefn {} DET& {operator =} (const DET &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int value_will_overflow (void) const
+ at deftypefnx {} int value_will_underflow (void) const
+ at end deftypefn
+
+ at deftypefn {} double coefficient (void) const
+ at deftypefnx {} int exponent (void) const
+ at deftypefnx {} double value (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const DET &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexDET (void)
+ at deftypefnx  {} {} ComplexDET (const ComplexDET &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexDET& {operator =} (const ComplexDET &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int value_will_overflow (void) const
+ at deftypefnx {} int value_will_underflow (void) const
+ at end deftypefn
+
+ at deftypefn {} Complex coefficient (void) const
+ at deftypefnx {} int exponent (void) const
+ at deftypefnx {} Complex value (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexDET &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} GEPBALANCE (void)
+ at deftypefnx  {} {} GEPBALANCE (const Matrix &@var{a}, const Matrix &, const char *@var{balance_job})
+ at deftypefnx  {} {} GEPBALANCE (const GEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} GEPBALANCE& {operator =} (const GEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix balanced_a_matrix (void) const
+ at deftypefnx {} Matrix balanced_b_matrix (void) const
+ at deftypefnx {} Matrix left_balancing_matrix (void) const
+ at deftypefnx {} Matrix right_balancing_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const GEPBALANCE &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} CHOL (void)
+ at deftypefnx  {} {} CHOL (const Matrix &@var{a})
+ at deftypefnx  {} {} CHOL (const Matrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} CHOL (const CHOL &@var{a})
+ at end deftypefn
+
+ at deftypefn {} CHOL& {operator =} (const CHOL &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix chol_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const CHOL &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexCHOL (void)
+ at deftypefnx  {} {} ComplexCHOL (const ComplexMatrix &@var{a})
+ at deftypefnx  {} {} ComplexCHOL (const ComplexMatrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} ComplexCHOL (const ComplexCHOL &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexCHOL& {operator =} (const ComplexCHOL &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix chol_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexCHOL &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} HESS (void)
+ at deftypefnx  {} {} HESS (const Matrix &@var{a})
+ at deftypefnx  {} {} HESS (const Matrix&a, int &@var{info})
+ at deftypefnx  {} {} HESS (const HESS &@var{a})
+ at end deftypefn
+
+ at deftypefn {} HESS& {operator =} (const HESS &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix hess_matrix (void) const
+ at deftypefnx {} Matrix unitary_hess_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const HESS &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexHESS (void)
+ at deftypefnx  {} {} ComplexHESS (const ComplexMatrix &@var{a})
+ at deftypefnx  {} {} ComplexHESS (const ComplexMatrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} ComplexHESS (const ComplexHESS &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexHESS& {operator =} (const ComplexHESS &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix hess_matrix (void) const
+ at deftypefnx {} ComplexMatrix unitary_hess_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexHESS &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} SCHUR (void)
+ at deftypefnx  {} {} SCHUR (const Matrix &@var{a}, const char *@var{ord})
+ at deftypefnx  {} {} SCHUR (const Matrix &@var{a}, const char *@var{ord}, int &@var{info})
+ at deftypefnx  {} {} SCHUR (const SCHUR &@var{a}, const char *@var{ord})
+ at end deftypefn
+
+ at deftypefn {} SCHUR& {operator =} (const SCHUR &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix schur_matrix (void) const
+ at deftypefnx {} Matrix unitary_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const SCHUR &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexSCHUR (void)
+ at deftypefnx  {} {} ComplexSCHUR (const ComplexMatrix &@var{a}, const char *@var{ord})
+ at deftypefnx  {} {} ComplexSCHUR (const ComplexMatrix &@var{a}, const char *@var{ord}, int &@var{info})
+ at deftypefnx  {} {} ComplexSCHUR (const ComplexSCHUR &@var{a}, const char *@var{ord})
+ at end deftypefn
+
+ at deftypefn {} ComplexSCHUR& {operator =} (const ComplexSCHUR &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix schur_matrix (void) const
+ at deftypefnx {} ComplexMatrix unitary_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexSCHUR &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} SVD (void)
+ at deftypefnx  {} {} SVD (const Matrix &@var{a})
+ at deftypefnx  {} {} SVD (const Matrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} SVD (const SVD &@var{a})
+ at end deftypefn
+
+ at deftypefn {} SVD& {operator =} (const SVD &@var{a})
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix singular_values (void) const
+ at deftypefnx {} Matrix left_singular_matrix (void) const
+ at deftypefnx {} Matrix right_singular_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const SVD &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexSVD (void)
+ at deftypefnx  {} {} ComplexSVD (const ComplexMatrix &@var{a})
+ at deftypefnx  {} {} ComplexSVD (const ComplexMatrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} ComplexSVD (const ComplexSVD &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexSVD& {operator =} (const ComplexSVD &@var{a})
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix singular_values (void) const
+ at deftypefnx {} ComplexMatrix left_singular_matrix (void) const
+ at deftypefnx {} ComplexMatrix right_singular_matrix (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexSVD &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} EIG (void)
+ at deftypefnx  {} {} EIG (const Matrix &@var{a})
+ at deftypefnx  {} {} EIG (const Matrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} EIG (const ComplexMatrix &@var{a})
+ at deftypefnx  {} {} EIG (const ComplexMatrix &@var{a}, int &@var{info})
+ at deftypefnx  {} {} EIG (const EIG &@var{a})
+ at end deftypefn
+
+ at deftypefn {} EIG& {operator =} (const EIG &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector eigenvalues (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix eigenvectors (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const EIG &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} LU (void)
+ at deftypefnx  {} {} LU (const Matrix &@var{a})
+ at deftypefnx  {} {} LU (const LU &@var{a})
+ at end deftypefn
+
+ at deftypefn {} LU& {operator =} (const LU &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix L (void) const
+ at deftypefnx {} Matrix U (void) const
+ at deftypefnx {} Matrix P (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const LU &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexLU (void)
+ at deftypefnx  {} {} ComplexLU (const ComplexMatrix &@var{a})
+ at deftypefnx  {} {} ComplexLU (const ComplexLU &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexLU& {operator =} (const ComplexLU &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix L (void) const
+ at deftypefnx {} ComplexMatrix U (void) const
+ at deftypefnx {} Matrix P (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexLU &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} QR (void)
+ at deftypefnx  {} {} QR (const Matrix &@var{A})
+ at deftypefnx  {} {} QR (const QR &@var{a})
+ at end deftypefn
+
+ at deftypefn {} QR& {operator =} (const QR &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix Q (void) const
+ at deftypefnx {} Matrix R (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const QR &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexQR (void)
+ at deftypefnx  {} {} ComplexQR (const ComplexMatrix &@var{A})
+ at deftypefnx  {} {} ComplexQR (const ComplexQR &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexQR& {operator =} (const ComplexQR &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix Q (void) const
+ at deftypefnx {} ComplexMatrix R (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexQR &@var{a})
+ at end deftypefn
diff --git a/doc/liboctave/fn-idx.texi b/doc/liboctave/fn-idx.texi
new file mode 100644
index 0000000..87c334a
--- /dev/null
+++ b/doc/liboctave/fn-idx.texi
@@ -0,0 +1,22 @@
+ at c Copyright (C) 1996, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Function Index, , Concept Index, Top
+ at unnumbered Function Index
+
+ at printindex fn
diff --git a/doc/liboctave/gpl.texi b/doc/liboctave/gpl.texi
new file mode 100644
index 0000000..7eac979
--- /dev/null
+++ b/doc/liboctave/gpl.texi
@@ -0,0 +1,735 @@
+ at c Copyright (C) 1996, 1997, 2005, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at cindex warranty
+ at cindex copyright
+ at node Copying, Introduction, Acknowledgements, Top
+ at unnumbered GNU GENERAL PUBLIC LICENSE
+ at center Version 3, 29 June 2007
+
+ at display
+Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+ at end display
+
+ at heading 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.
+
+ at heading TERMS AND CONDITIONS
+
+ at enumerate 0
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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:
+
+ at enumerate a
+ at item 
+The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+ at item
+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''.
+
+ at item
+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.
+
+ at item
+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.
+ at end enumerate
+
+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.
+
+ at item  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:
+
+ at enumerate a
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at item
+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.
+
+ at end enumerate
+
+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.
+
+ at item 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:
+
+ at enumerate a
+ at item
+Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+ at item
+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
+
+ at item
+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
+
+ at item
+Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+ at item
+Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+ at item
+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.
+ at end enumerate
+
+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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at item 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.
+
+ at end enumerate
+
+ at heading END OF TERMS AND CONDITIONS
+
+ at heading 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.
+
+ at smallexample
+ at var{one line to give the program's name and a brief idea of what it does.}  
+Copyright (C) @var{year} @var{name of author}
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see @url{http://www.gnu.org/licenses/}.
+ at end smallexample
+
+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:
+
+ at smallexample
+ at var{program} Copyright (C) @var{year} @var{name of author} 
+This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type @samp{show c} for details.
+ at end smallexample
+
+The hypothetical commands @samp{show w} and @samp{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
+ at url{http://www.gnu.org/licenses/}.
+
+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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
diff --git a/doc/liboctave/install.texi b/doc/liboctave/install.texi
new file mode 100644
index 0000000..9da9061
--- /dev/null
+++ b/doc/liboctave/install.texi
@@ -0,0 +1,21 @@
+ at c Copyright (C) 1996, 1997, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Installation, Bugs, Error Handling, Top
+ at chapter Installation
+ at cindex installation
diff --git a/doc/liboctave/intro.texi b/doc/liboctave/intro.texi
new file mode 100644
index 0000000..c1bd430
--- /dev/null
+++ b/doc/liboctave/intro.texi
@@ -0,0 +1,24 @@
+ at c Copyright (C) 1996, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Introduction, Arrays, Copying, Top
+ at chapter A Brief Introduction to Octave
+ at cindex introduction
+
+This manual documents how to run, install and port Octave's C++ classes,
+and how to report bugs.
diff --git a/doc/liboctave/liboctave.dvi b/doc/liboctave/liboctave.dvi
new file mode 100644
index 0000000..3823f74
Binary files /dev/null and b/doc/liboctave/liboctave.dvi differ
diff --git a/doc/liboctave/liboctave.info b/doc/liboctave/liboctave.info
new file mode 100644
index 0000000..19bcef9
--- /dev/null
+++ b/doc/liboctave/liboctave.info
@@ -0,0 +1,3192 @@
+START-INFO-DIR-ENTRY
+This is liboctave.info, produced by makeinfo version 4.11 from liboctave.texi.
+
+* liboctave: (liboctave). Octave C++ Classes
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 1996, 1997 John W. Eaton.
+
+   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 above conditions for modified
+versions.
+
+
+File: liboctave.info,  Node: Top,  Next: Acknowledgements,  Prev: (dir),  Up: (dir)
+
+Octave C++ Classes
+******************
+
+This manual documents how to use, install and port Octave's C++ class
+library, and how to report bugs.  It corresponds to Octave version
+3.2.4.
+
+* Menu:
+
+* Acknowledgements::
+* Copying::
+* Introduction::
+* Arrays::
+* Matrix and Vector Operations::
+* Matrix Factorizations::
+* Ranges::
+* Nonlinear Functions::
+* Nonlinear Equations::
+* Optimization::
+* Quadrature::
+* Ordinary Differential Equations::
+* Differential Algebraic Equations::
+* Error Handling::
+* Installation::
+* Bugs::
+* Concept Index::
+* Function Index::
+
+ --- The Detailed Node Listing ---
+
+Acknowledgements
+
+* Contributors::                People who contributed to developing of Octave.
+
+Arrays
+
+* Constructors and Assignment::
+
+Optimization
+
+* Objective Functions::
+* Bounds::
+* Linear Constraints::
+* Nonlinear Constraints::
+* Quadratic Programming::
+* Nonlinear Programming::
+
+Quadrature
+
+* Collocation Weights::
+
+
+File: liboctave.info,  Node: Acknowledgements,  Next: Copying,  Prev: Top,  Up: Top
+
+1 Acknowledgements
+******************
+
+* Menu:
+
+* Contributors::                People who contributed to developing of Octave.
+
+
+File: liboctave.info,  Node: Contributors,  Prev: Acknowledgements,  Up: Acknowledgements
+
+Contributors to Octave
+======================
+
+In addition to John W. Eaton, several people have written parts of
+liboctave.  (This has been removed because it is the same as what is in
+the Octave manual.)
+
+
+File: liboctave.info,  Node: Copying,  Next: Introduction,  Prev: Acknowledgements,  Up: Top
+
+GNU GENERAL PUBLIC LICENSE
+**************************
+
+                        Version 3, 29 June 2007
+
+     Copyright (C) 2007 Free Software Foundation, Inc. `http://fsf.org/'
+
+     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.
+
+     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
+     Copyright (C) YEAR NAME OF AUTHOR
+
+     This program is free software: you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation, either version 3 of the License, or (at
+     your option) any later version.
+
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see `http://www.gnu.org/licenses/'.
+
+   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:
+
+     PROGRAM Copyright (C) YEAR NAME OF AUTHOR
+     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 `http://www.gnu.org/licenses/'.
+
+   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 `http://www.gnu.org/philosophy/why-not-lgpl.html'.
+
+
+File: liboctave.info,  Node: Introduction,  Next: Arrays,  Prev: Copying,  Up: Top
+
+2 A Brief Introduction to Octave
+********************************
+
+This manual documents how to run, install and port Octave's C++ classes,
+and how to report bugs.
+
+
+File: liboctave.info,  Node: Arrays,  Next: Matrix and Vector Operations,  Prev: Introduction,  Up: Top
+
+3 Arrays
+********
+
+* Menu:
+
+* Constructors and Assignment::
+
+
+File: liboctave.info,  Node: Constructors and Assignment,  Prev: Arrays,  Up: Arrays
+
+3.1 Constructors and Assignment
+===============================
+
+ -- Constructor:  Array<T> (void)
+     Create an array with no elements.
+
+ -- Constructor:  Array<T> (int N [, const T &VAL])
+     Create an array with N elements.  If the optional argument VAL is
+     supplied, the elements are initialized to VAL; otherwise, they are
+     left uninitialized.  If N is less than zero, the current error
+     handler is invoked (*note Error Handling::).
+
+ -- Constructor:  Array<T> (const Array<T> &A)
+     Create a copy of the ARRAY<T> object A.  Memory for the ARRAY<T>
+     class is managed using a reference counting scheme, so the cost of
+     this operation is independent of the size of the array.
+
+ -- Assignment on Array<T>: Array<T>& operator = (const Array<T> &A)
+     Assignment operator.  Memory for the ARRAY<T> class is managed
+     using a reference counting scheme, so the cost of this operation is
+     independent of the size of the array.
+
+ -- Method on Array<T>: int capacity (void) const
+ -- Method on Array<T>: int length (void) const
+     Return the length of the array.
+
+ -- Method on Array<T>: T& elem (int N)
+ -- Method on Array<T>: T& checkelem (int N)
+     If N is within the bounds of the array, return a reference to the
+     element indexed by N; otherwise, the current error handler is
+     invoked (*note Error Handling::).
+
+ -- Indexing on Array<T>: T& operator () (int N)
+
+ -- Method on Array<T>: T elem (int N) const
+ -- Method on Array<T>: T checkelem (int N) const
+     If N is within the bounds of the array, return the value indexed
+     by N; otherwise, call the current error handler.  *Note Error
+     Handling::.
+
+ -- Indexing on Array<T>: T operator () (int N) const
+
+ -- Method on Array<T>: T& xelem (int N)
+ -- Method on Array<T>: T xelem (int N) const
+     Return a reference to, or the value of, the element indexed by N.
+     These methods never perform bounds checking.
+
+ -- Method on Array<T>: void resize (
+     Change the size of the array to be N elements.  All elements are
+     unchanged, except that if N is greater than the current size and
+     the optional argument VAL is provided, the additional elements are
+     initialized to VAL; otherwise, any additional elements are left
+     uninitialized.  In the current implementation, if N is less than
+     the current size, the length is updated but no memory is released.
+
+ -- Method on Array<T>: const T* data (void) const
+
+ -- Constructor:  Array2<T> Array2<T> Array2 (void)
+ -- Constructor:  Array2<T> (int N, int M)
+ -- Constructor:  Array2<T> (int N, int M, const T &VAL)
+ -- Constructor:  Array2<T> (const Array2<T> &A)
+ -- Constructor:  Array2<T> (const DiagArray<T> &A)
+
+ -- Assignment on Array2<T>: Array2<T>& operator = (const Array2<T> &A)
+
+ -- Method on Array2<T>: int dim1 (void) const
+ -- Method on Array2<T>: int rows (void) const
+
+ -- Method on Array2<T>: int dim2 (void) const
+ -- Method on Array2<T>: int cols (void) const
+ -- Method on Array2<T>: int columns (void) const
+
+ -- Method on Array2<T>: T& elem (int I, int J)
+ -- Method on Array2<T>: T& checkelem (int I, int J)
+
+ -- Indexing on Array2<T>: T& operator () (int I, int J)
+
+ -- Method on Array2<T>: void resize (int N, int M)
+ -- Method on Array2<T>: void resize (int N, int M, const T &VAL)
+
+ -- Constructor:  Array3<T> (void)
+ -- Constructor:  Array3<T> (int N, int M, int K)
+ -- Constructor:  Array3<T> (int N, int M, int K, const T &VAL)
+ -- Constructor:  Array3<T> (const Array3<T> &A)
+
+ -- Assignment on Array3<T>: Array3<T>& operator = (const Array3<T> &A)
+
+ -- Method on Array3<T>: int dim1 (void) const
+ -- Method on Array3<T>: int dim2 (void) const
+ -- Method on Array3<T>: int dim3 (void) const
+
+ -- Method on Array3<T>: T& elem (int I, int J, int K)
+ -- Method on Array3<T>: T& checkelem (int I, int J, int K)
+
+ -- Indexing on Array3<T>: T& operator () (int I, int J, int K)
+
+ -- Method on Array3<T>: void resize (int N, int M, int K)
+ -- Method on Array3<T>: void resize (int N, int M, int K, const T &VAL)
+
+ -- Constructor:  DiagArray<T> (void)
+ -- Constructor:  DiagArray<T> (int N)
+ -- Constructor:  DiagArray<T> (int N, const T &VAL)
+ -- Constructor:  DiagArray<T> (int R, int C)
+ -- Constructor:  DiagArray<T> (int R, int C, const T &VAL)
+ -- Constructor:  DiagArray<T> (const Array<T> &A)
+ -- Constructor:  DiagArray<T> (const DiagArray<T> &A)
+
+ -- Assginment on DiagArray<T>&:  operator = (const DiagArray<T> &A)
+
+ -- Method on DiagArray<T>: int dim1 (void) const
+ -- Method on DiagArray<T>: int rows (void) const
+
+ -- Method on DiagArray<T>: int dim2 (void) const
+ -- Method on DiagArray<T>: int cols (void) const
+ -- Method on DiagArray<T>: int columns (void) const
+
+ -- Method on DiagArray<T>: T& elem (int R, int C)
+ -- Method on DiagArray<T>: T& checkelem (int R, int C)
+
+ -- Indexing on DiagArray<T>: T& operator () (int R, int C)
+
+ -- Method on DiagArray<T>: void resize (int N, int M)
+ -- Method on DiagArray<T>: void resize (int N, int M, const T &VAL)
+
+   The real and complex `ColumnVector' and `RowVector' classes all have
+the following functions.  These will eventually be part of an
+`MArray<T>' class, derived from the `Array<T>' class.  Then the
+`ColumnVector' and `RowVector' classes will be derived from the
+`MArray<T>' class.
+
+   Element by element vector by scalar ops.
+
+ -- : RowVector operator + (const RowVector &A, const double &S)
+ -- : RowVector operator - (const RowVector &A, const double &S)
+ -- : RowVector operator * (const RowVector &A, const double &S)
+ -- : RowVector operator / (const RowVector &A, const double &S)
+
+   Element by element scalar by vector ops.
+
+ -- : RowVector operator + (const double &S, const RowVector &A)
+ -- : RowVector operator - (const double &S, const RowVector &A)
+ -- : RowVector operator * (const double &S, const RowVector &A)
+ -- : RowVector operator / (const double &S, const RowVector &A)
+
+   Element by element vector by vector ops.
+
+ -- : RowVector operator + (const RowVector &A, const RowVector &B)
+ -- : RowVector operator - (const RowVector &A, const RowVector &B)
+
+ -- : RowVector product (const RowVector &A, const RowVector &B)
+ -- : RowVector quotient (const RowVector &A, const RowVector &B)
+
+   Unary MArray ops.
+
+ -- : RowVector operator - (const RowVector &A)
+
+   The `Matrix' classes share the following functions.  These will
+eventually be part of an `MArray2<T>' class, derived from the
+`Array2<T>' class.  Then the `Matrix' class will be derived from the
+`MArray<T>' class.
+
+   Element by element matrix by scalar ops.
+
+ -- : Matrix operator + (const Matrix &A, const double &S)
+ -- : Matrix operator - (const Matrix &A, const double &S)
+ -- : Matrix operator * (const Matrix &A, const double &S)
+ -- : Matrix operator / (const Matrix &A, const double &S)
+
+   Element by element scalar by matrix ops.
+
+ -- : Matrix operator + (const double &S, const Matrix &A)
+ -- : Matrix operator - (const double &S, const Matrix &A)
+ -- : Matrix operator * (const double &S, const Matrix &A)
+ -- : Matrix operator / (const double &S, const Matrix &A)
+
+   Element by element matrix by matrix ops.
+
+ -- : Matrix operator + (const Matrix &A, const Matrix &B)
+ -- : Matrix operator - (const Matrix &A, const Matrix &B)
+
+ -- : Matrix product (const Matrix &A, const Matrix &B)
+ -- : Matrix quotient (const Matrix &A, const Matrix &B)
+
+   Unary matrix ops.
+
+ -- : Matrix operator - (const Matrix &A)
+
+   The `DiagMatrix' classes share the following functions.  These will
+eventually be part of an `MDiagArray<T>' class, derived from the
+`DiagArray<T>' class.  Then the `DiagMatrix' class will be derived from
+the `MDiagArray<T>' class.
+
+   Element by element MDiagArray by scalar ops.
+
+ -- : DiagMatrix operator * (const DiagMatrix &A, const double &S)
+ -- : DiagMatrix operator / (const DiagMatrix &A, const double &S)
+
+   Element by element scalar by MDiagArray ops.
+
+ -- : DiagMatrix operator * (const double &S, const DiagMatrix &A)
+
+   Element by element MDiagArray by MDiagArray ops.
+
+ -- : DiagMatrix operator + (const DiagMatrix &A, const DiagMatrix &B)
+ -- : DiagMatrix operator - (const DiagMatrix &A, const DiagMatrix &B)
+
+ -- : DiagMatrix product (const DiagMatrix &A, const DiagMatrix &B)
+
+   Unary MDiagArray ops.
+
+ -- : DiagMatrix operator - (const DiagMatrix &A)
+
+
+File: liboctave.info,  Node: Matrix and Vector Operations,  Next: Matrix Factorizations,  Prev: Arrays,  Up: Top
+
+4 Matrix and Vector Operations
+******************************
+
+ -- :  Matrix (void)
+ -- :  Matrix (int R, int C)
+ -- :  Matrix (int R, int C, double VAL)
+ -- :  Matrix (const Array2<double> &A)
+ -- :  Matrix (const Matrix &A)
+ -- :  Matrix (const DiagArray<double> &A)
+ -- :  Matrix (const DiagMatrix &A)
+
+ -- : Matrix& operator = (const Matrix &A)
+
+ -- : int operator == (const Matrix &A) const
+ -- : int operator != (const Matrix &A) const
+
+ -- : Matrix& insert (const Matrix &A, int R, int C)
+ -- : Matrix& insert (const RowVector &A, int R, int C)
+ -- : Matrix& insert (const ColumnVector &A, int R, int C)
+ -- : Matrix& insert (const DiagMatrix &A, int R, int C)
+
+ -- : Matrix& fill (double VAL)
+ -- : Matrix& fill (double VAL, int r1, int c1, int r2, int c2)
+
+ -- : Matrix append (const Matrix &A) const
+ -- : Matrix append (const RowVector &A) const
+ -- : Matrix append (const ColumnVector &A) const
+ -- : Matrix append (const DiagMatrix &A) const
+
+ -- : Matrix stack (const Matrix &A) const
+ -- : Matrix stack (const RowVector &A) const
+ -- : Matrix stack (const ColumnVector &A) const
+ -- : Matrix stack (const DiagMatrix &A) const
+
+ -- : Matrix transpose (void) const
+
+ -- : Matrix extract (int r1, int c1, int r2, int c2) const
+
+ -- : RowVector row (int I) const
+ -- : RowVector row (char *s) const
+
+ -- : ColumnVector column (int I) const
+ -- : ColumnVector column (char *s) const
+
+ -- : Matrix inverse (void) const
+ -- : Matrix inverse (int &INFO) const
+ -- : Matrix inverse (int &INFO, double &RCOND) const
+
+ -- : ComplexMatrix fourier (void) const
+ -- : ComplexMatrix ifourier (void) const
+
+ -- : DET determinant (void) const
+ -- : DET determinant (int &INFO) const
+ -- : DET determinant (int &INFO, double &RCOND) const
+
+ -- : Matrix solve (const Matrix &B) const
+ -- : Matrix solve (const Matrix &B, int &INFO) const
+ -- : Matrix solve (const Matrix &B, int &INFO, double &RCOND) const
+
+ -- : ComplexMatrix solve (const ComplexMatrix &B) const
+ -- : ComplexMatrix solve (const ComplexMatrix &B, int &INFO) const
+ -- : ComplexMatrix solve (const ComplexMatrix &B, int &INFO, double
+          &RCOND) const
+
+ -- : ColumnVector solve (const ColumnVector &B) const
+ -- : ColumnVector solve (const ColumnVector &B, int &INFO) const
+ -- : ColumnVector solve (const ColumnVector &B, int &INFO, double
+          &RCOND) const
+
+ -- : ComplexColumnVector solve (const ComplexColumnVector &B) const
+ -- : ComplexColumnVector solve (const ComplexColumnVector &B, int
+          &INFO) const
+ -- : ComplexColumnVector solve (const ComplexColumnVector &B, int
+          &INFO, double &RCOND) const
+
+ -- : Matrix lssolve (const Matrix &B) const
+ -- : Matrix lssolve (const Matrix &B, int &INFO) const
+ -- : Matrix lssolve (const Matrix &B, int &INFO, int &RANK) const
+
+ -- : ComplexMatrix lssolve (const ComplexMatrix &B) const
+ -- : ComplexMatrix lssolve (const ComplexMatrix &B, int &INFO) const
+ -- : ComplexMatrix lssolve (const ComplexMatrix &B, int &INFO, int
+          &RANK) const
+
+ -- : ColumnVector lssolve (const ColumnVector &B) const
+ -- : ColumnVector lssolve (const ColumnVector &B, int &INFO) const
+ -- : ColumnVector lssolve (const ColumnVector &B, int &INFO, int
+          &RANK) const
+
+ -- : ComplexColumnVector lssolve (const ComplexColumnVector &B) const
+ -- : ComplexColumnVector lssolve (const ComplexColumnVector &B, int
+          &INFO) const
+ -- : ComplexColumnVector lssolve (const ComplexColumnVector &B, int
+          &INFO, int &RANK) const
+
+ -- : Matrix& operator += (const Matrix &A)
+ -- : Matrix& operator -= (const Matrix &A)
+
+ -- : Matrix& operator += (const DiagMatrix &A)
+ -- : Matrix& operator -= (const DiagMatrix &A)
+
+ -- : Matrix operator ! (void) const
+
+ -- : ComplexMatrix operator + (const Matrix &A, const Complex &S)
+ -- : ComplexMatrix operator - (const Matrix &A, const Complex &S)
+ -- : ComplexMatrix operator * (const Matrix &A, const Complex &S)
+ -- : ComplexMatrix operator / (const Matrix &A, const Complex &S)
+
+ -- : ComplexMatrix operator + (const Complex &S, const Matrix &A)
+ -- : ComplexMatrix operator - (const Complex &S, const Matrix &A)
+ -- : ComplexMatrix operator * (const Complex &S, const Matrix &A)
+ -- : ComplexMatrix operator / (const Complex &S, const Matrix &A)
+
+ -- : ColumnVector operator * (const Matrix &A, const ColumnVector &B)
+ -- : ComplexColumnVector operator * (const Matrix &A, const
+          ComplexColumnVector &B)
+
+ -- : Matrix operator + (const Matrix &A, const DiagMatrix &B)
+ -- : Matrix operator - (const Matrix &A, const DiagMatrix &B)
+ -- : Matrix operator * (const Matrix &A, const DiagMatrix &B)
+
+ -- : ComplexMatrix operator + (const Matrix &A, const
+          ComplexDiagMatrix &B)
+ -- : ComplexMatrix operator - (const Matrix &A, const
+          ComplexDiagMatrix &B)
+ -- : ComplexMatrix operator * (const Matrix &A, const
+          ComplexDiagMatrix &B)
+
+ -- : Matrix operator * (const Matrix &A, const Matrix &B)
+ -- : ComplexMatrix operator * (const Matrix &A, const ComplexMatrix &B)
+
+ -- : ComplexMatrix operator + (const Matrix &A, const ComplexMatrix &B)
+ -- : ComplexMatrix operator - (const Matrix &A, const ComplexMatrix &B)
+
+ -- : ComplexMatrix product (const Matrix &A, const ComplexMatrix &B)
+ -- : ComplexMatrix quotient (const Matrix &A, const ComplexMatrix &B)
+
+ -- : Matrix map (d_d_Mapper F, const Matrix &A)
+ -- : void map (d_d_Mapper F)
+
+ -- : Matrix all (void) const
+ -- : Matrix any (void) const
+
+ -- : Matrix cumprod (void) const
+ -- : Matrix cumsum (void) const
+ -- : Matrix prod (void) const
+ -- : Matrix sum (void) const
+ -- : Matrix sumsq (void) const
+
+ -- : ColumnVector diag (void) const
+ -- : ColumnVector diag (int K) const
+
+ -- : ColumnVector row_min (void) const
+ -- : ColumnVector row_min_loc (void) const
+
+ -- : ColumnVector row_max (void) const
+ -- : ColumnVector row_max_loc (void) const
+
+ -- : RowVector column_min (void) const
+ -- : RowVector column_min_loc (void) const
+
+ -- : RowVector column_max (void) const
+ -- : RowVector column_max_loc (void) const
+
+ -- : ostream& operator << (ostream &OS, const Matrix &A)
+ -- : istream& operator >> (istream &IS, Matrix &A)
+
+ -- :  ColumnVector (void)
+ -- :  ColumnVector (int N)
+ -- :  ColumnVector (int N, double VAL)
+ -- :  ColumnVector (const Array<double> &A)
+ -- :  ColumnVector (const ColumnVector &A)
+
+ -- : ColumnVector& operator = (const ColumnVector &A)
+
+ -- : int operator == (const ColumnVector &A) const
+ -- : int operator != (const ColumnVector &A) const
+
+ -- : ColumnVector& insert (const ColumnVector &A, int R)
+
+ -- : ColumnVector& fill (double VAL)
+ -- : ColumnVector& fill (double VAL, int r1, int r2)
+
+ -- : ColumnVector stack (const ColumnVector &A) const
+
+ -- : RowVector transpose (void) const
+
+ -- : ColumnVector extract (int r1, int r2) const
+
+ -- : ColumnVector& operator += (const ColumnVector &A)
+ -- : ColumnVector& operator -= (const ColumnVector &A)
+
+ -- : ComplexColumnVector operator + (const ColumnVector &A, const
+          Complex &S)
+ -- : ComplexColumnVector operator - (const ColumnVector &A, const
+          Complex &S)
+ -- : ComplexColumnVector operator * (const ColumnVector &A, const
+          Complex &S)
+ -- : ComplexColumnVector operator / (const ColumnVector &A, const
+          Complex &S)
+
+ -- : ComplexColumnVector operator + (const Complex &S, const
+          ColumnVector &A)
+ -- : ComplexColumnVector operator - (const Complex &S, const
+          ColumnVector &A)
+ -- : ComplexColumnVector operator * (const Complex &S, const
+          ColumnVector &A)
+ -- : ComplexColumnVector operator / (const Complex &S, const
+          ColumnVector &A)
+
+ -- : Matrix operator * (const ColumnVector &A, const RowVector &A)
+
+ -- : ComplexMatrix operator * (const ColumnVector &A, const
+          ComplexRowVector &B)
+
+ -- : ComplexColumnVector operator + (const ComplexColumnVector &A,
+          const ComplexColumnVector &B)
+
+ -- : ComplexColumnVector operator - (const ComplexColumnVector &A,
+          const ComplexColumnVector &B)
+
+ -- : ComplexColumnVector product (const ComplexColumnVector &A, const
+          ComplexColumnVector &B)
+
+ -- : ComplexColumnVector quotient (const ComplexColumnVector &A, const
+          ComplexColumnVector &B)
+
+ -- : ColumnVector map (d_d_Mapper F, const ColumnVector &A)
+ -- : void map (d_d_Mapper F)
+
+ -- : double min (void) const
+ -- : double max (void) const
+
+ -- : ostream& operator << (ostream &OS, const ColumnVector &A)
+
+ -- :  RowVector (void)
+ -- :  RowVector (int N)
+ -- :  RowVector (int N, double VAL)
+ -- :  RowVector (const Array<double> &A)
+ -- :  RowVector (const RowVector &A)
+
+ -- : RowVector& operator = (const RowVector &A)
+
+ -- : int operator == (const RowVector &A) const
+ -- : int operator != (const RowVector &A) const
+
+ -- : RowVector& insert (const RowVector &A, int C)
+
+ -- : RowVector& fill (double VAL)
+ -- : RowVector& fill (double VAL, int c1, int c2)
+
+ -- : RowVector append (const RowVector &A) const
+
+ -- : ColumnVector transpose (void) const
+
+ -- : RowVector extract (int c1, int c2) const
+
+ -- : RowVector& operator += (const RowVector &A)
+ -- : RowVector& operator -= (const RowVector &A)
+
+ -- : ComplexRowVector operator + (const RowVector &A, const Complex &S)
+ -- : ComplexRowVector operator - (const RowVector &A, const Complex &S)
+ -- : ComplexRowVector operator * (const RowVector &A, const Complex &S)
+ -- : ComplexRowVector operator / (const RowVector &A, const Complex &S)
+
+ -- : ComplexRowVector operator + (const Complex &S, const RowVector &A)
+ -- : ComplexRowVector operator - (const Complex &S, const RowVector &A)
+ -- : ComplexRowVector operator * (const Complex &S, const RowVector &A)
+ -- : ComplexRowVector operator / (const Complex &S, const RowVector &A)
+
+ -- : double operator * (const RowVector &A, ColumnVector &B)
+
+ -- : Complex operator * (const RowVector &A, const ComplexColumnVector
+          &B)
+
+ -- : RowVector operator * (const RowVector &A, const Matrix &B)
+
+ -- : ComplexRowVector operator * (const RowVector &A, const
+          ComplexMatrix &B)
+
+ -- : ComplexRowVector operator + (const RowVector &A, const
+          ComplexRowVector &B)
+ -- : ComplexRowVector operator - (const RowVector &A, const
+          ComplexRowVector &B)
+
+ -- : ComplexRowVector product (const RowVector &A, const
+          ComplexRowVector &B)
+ -- : ComplexRowVector quotient (const RowVector &A, const
+          ComplexRowVector &B)
+
+ -- : RowVector map (d_d_Mapper F, const RowVector &A)
+ -- : void map (d_d_Mapper F)
+
+ -- : double min (void) const
+ -- : double max (void) const
+
+ -- : ostream& operator << (ostream &OS, const RowVector &A)
+
+ -- :  DiagMatrix (void)
+ -- :  DiagMatrix (int N)
+ -- :  DiagMatrix (int N, double VAL)
+ -- :  DiagMatrix (int R, int C)
+ -- :  DiagMatrix (int R, int C, double VAL)
+ -- :  DiagMatrix (const RowVector &A)
+ -- :  DiagMatrix (const ColumnVector &A)
+ -- :  DiagMatrix (const DiagArray<double> &A)
+ -- :  DiagMatrix (const DiagMatrix &A)
+
+ -- : DiagMatrix& operator = (const DiagMatrix &A)
+
+ -- : int operator == (const DiagMatrix &A) const
+ -- : int operator != (const DiagMatrix &A) const
+
+ -- : DiagMatrix& fill (double VAL)
+ -- : DiagMatrix& fill (double VAL, int BEG, int END)
+ -- : DiagMatrix& fill (const ColumnVector &A)
+ -- : DiagMatrix& fill (const RowVector &A)
+ -- : DiagMatrix& fill (const ColumnVector &A, int BEG)
+ -- : DiagMatrix& fill (const RowVector &A, int BEG)
+
+ -- : DiagMatrix transpose (void) const
+
+ -- : Matrix extract (int r1, int c1, int r2, int c2) const
+
+ -- : RowVector row (int I) const
+ -- : RowVector row (char *s) const
+
+ -- : ColumnVector column (int I) const
+ -- : ColumnVector column (char *s) const
+
+ -- : DiagMatrix inverse (void) const
+ -- : DiagMatrix inverse (int &INFO) const
+
+ -- : DiagMatrix& operator += (const DiagMatrix &A)
+ -- : DiagMatrix& operator -= (const DiagMatrix &A)
+
+ -- : Matrix operator + (const DiagMatrix &A, double S)
+ -- : Matrix operator - (const DiagMatrix &A, double S)
+
+ -- : ComplexMatrix operator + (const DiagMatrix &A, const Complex &S)
+ -- : ComplexMatrix operator - (const DiagMatrix &A, const Complex &S)
+
+ -- : ComplexDiagMatrix operator * (const DiagMatrix &A, const Complex
+          &S)
+ -- : ComplexDiagMatrix operator / (const DiagMatrix &A, const Complex
+          &S)
+
+ -- : Matrix operator + (double S, const DiagMatrix &A)
+ -- : Matrix operator - (double S, const DiagMatrix &A)
+
+ -- : ComplexMatrix operator + (const Complex &S, const DiagMatrix &A)
+ -- : ComplexMatrix operator - (const Complex &S, const DiagMatrix &A)
+
+ -- : ComplexDiagMatrix operator * (const Complex &S, const DiagMatrix
+          &A)
+
+ -- : ColumnVector operator * (const DiagMatrix &A, const ColumnVector
+          &B)
+
+ -- : ComplexColumnVector operator * (const DiagMatrix &A, const
+          ComplexColumnVector &B)
+
+ -- : ComplexDiagMatrix operator + (const DiagMatrix &A, const
+          ComplexDiagMatrix &B)
+ -- : ComplexDiagMatrix operator - (const DiagMatrix &A, const
+          ComplexDiagMatrix &B)
+
+ -- : ComplexDiagMatrix product (const DiagMatrix &A, const
+          ComplexDiagMatrix &B)
+
+ -- : Matrix operator + (const DiagMatrix &A, const Matrix &B)
+ -- : Matrix operator - (const DiagMatrix &A, const Matrix &B)
+ -- : Matrix operator * (const DiagMatrix &A, const Matrix &B)
+
+ -- : ComplexMatrix operator + (const DiagMatrix &A, const
+          ComplexMatrix &B)
+ -- : ComplexMatrix operator - (const DiagMatrix &A, const
+          ComplexMatrix &B)
+ -- : ComplexMatrix operator * (const DiagMatrix &A, const
+          ComplexMatrix &B)
+
+ -- : ColumnVector diag (void) const
+ -- : ColumnVector diag (int K) const
+
+ -- : ostream& operator << (ostream &OS, const DiagMatrix &A)
+
+ -- :  ComplexMatrix (void)
+ -- :  ComplexMatrix (int R, int C)
+ -- :  ComplexMatrix (int R, int C, const Complex &VAL)
+ -- :  ComplexMatrix (const Matrix &A)
+ -- :  ComplexMatrix (const Array2<Complex> &A)
+ -- :  ComplexMatrix (const ComplexMatrix &A)
+ -- :  ComplexMatrix (const DiagMatrix &A)
+ -- :  ComplexMatrix (const DiagArray<Complex> &A)
+ -- :  ComplexMatrix (const ComplexDiagMatrix &A)
+
+ -- : ComplexMatrix& operator = (const ComplexMatrix &A)
+
+ -- : int operator == (const ComplexMatrix &A) const
+ -- : int operator != (const ComplexMatrix &A) const
+
+ -- : ComplexMatrix& insert (const Matrix &A, int R, int C)
+ -- : ComplexMatrix& insert (const RowVector &A, int R, int C)
+ -- : ComplexMatrix& insert (const ColumnVector &A, int R, int C)
+ -- : ComplexMatrix& insert (const DiagMatrix &A, int R, int C)
+
+ -- : ComplexMatrix& insert (const ComplexMatrix &A, int R, int C)
+ -- : ComplexMatrix& insert (const ComplexRowVector &A, int R, int C)
+ -- : ComplexMatrix& insert (const ComplexColumnVector &A, int R, int C)
+ -- : ComplexMatrix& insert (const ComplexDiagMatrix &A, int R, int C)
+
+ -- : ComplexMatrix& fill (double VAL)
+ -- : ComplexMatrix& fill (const Complex &VAL)
+ -- : ComplexMatrix& fill (double VAL, int r1, int c1, int r2, int c2)
+ -- : ComplexMatrix& fill (const Complex &VAL, int r1, int c1, int r2,
+          int c2)
+
+ -- : ComplexMatrix append (const Matrix &A) const
+ -- : ComplexMatrix append (const RowVector &A) const
+ -- : ComplexMatrix append (const ColumnVector &A) const
+ -- : ComplexMatrix append (const DiagMatrix &A) const
+
+ -- : ComplexMatrix append (const ComplexMatrix &A) const
+ -- : ComplexMatrix append (const ComplexRowVector &A) const
+ -- : ComplexMatrix append (const ComplexColumnVector &A) const
+ -- : ComplexMatrix append (const ComplexDiagMatrix &A) const
+
+ -- : ComplexMatrix stack (const Matrix &A) const
+ -- : ComplexMatrix stack (const RowVector &A) const
+ -- : ComplexMatrix stack (const ColumnVector &A) const
+ -- : ComplexMatrix stack (const DiagMatrix &A) const
+
+ -- : ComplexMatrix stack (const ComplexMatrix &A) const
+ -- : ComplexMatrix stack (const ComplexRowVector &A) const
+ -- : ComplexMatrix stack (const ComplexColumnVector &A) const
+ -- : ComplexMatrix stack (const ComplexDiagMatrix &A) const
+
+ -- : ComplexMatrix transpose (void) const
+
+ -- : Matrix real (const ComplexMatrix &A)
+ -- : Matrix imag (const ComplexMatrix &A)
+ -- : ComplexMatrix conj (const ComplexMatrix &A)
+
+ -- : ComplexMatrix extract (int r1, int c1, int r2, int c2) const
+
+ -- : ComplexRowVector row (int I) const
+ -- : ComplexRowVector row (char *s) const
+
+ -- : ComplexColumnVector column (int I) const
+ -- : ComplexColumnVector column (char *s) const
+
+ -- : ComplexMatrix inverse (void) const
+ -- : ComplexMatrix inverse (int &INFO) const
+ -- : ComplexMatrix inverse (int &INFO, double &RCOND) const
+
+ -- : ComplexMatrix fourier (void) const
+ -- : ComplexMatrix ifourier (void) const
+
+ -- : ComplexDET determinant (void) const
+ -- : ComplexDET determinant (int &INFO) const
+ -- : ComplexDET determinant (int &INFO, double &RCOND) const
+
+ -- : ComplexMatrix solve (const Matrix &B) const
+ -- : ComplexMatrix solve (const Matrix &B, int &INFO) const
+ -- : ComplexMatrix solve (const Matrix &B, int &INFO, double &RCOND)
+          const
+
+ -- : ComplexMatrix solve (const ComplexMatrix &B) const
+ -- : ComplexMatrix solve (const ComplexMatrix &B, int &INFO) const
+ -- : ComplexMatrix solve (const ComplexMatrix &B, int &INFO, double
+          &RCOND) const
+
+ -- : ComplexColumnVector solve (const ComplexColumnVector &B) const
+ -- : ComplexColumnVector solve (const ComplexColumnVector &B, int
+          &INFO) const
+ -- : ComplexColumnVector solve (const ComplexColumnVector &B, int
+          &INFO, double &RCOND) const
+
+ -- : ComplexMatrix lssolve (const ComplexMatrix &B) const
+ -- : ComplexMatrix lssolve (const ComplexMatrix &B, int &INFO) const
+ -- : ComplexMatrix lssolve (const ComplexMatrix &B, int &INFO, int
+          &RANK) const
+
+ -- : ComplexColumnVector lssolve (const ComplexColumnVector &B) const
+ -- : ComplexColumnVector lssolve (const ComplexColumnVector &B, int
+          &INFO) const
+ -- : ComplexColumnVector lssolve (const ComplexColumnVector &B, int
+          &INFO, int &RANK) const
+
+ -- : ComplexMatrix& operator += (const DiagMatrix &A)
+ -- : ComplexMatrix& operator -= (const DiagMatrix &A)
+
+ -- : ComplexMatrix& operator += (const ComplexDiagMatrix &A)
+ -- : ComplexMatrix& operator -= (const ComplexDiagMatrix &A)
+
+ -- : ComplexMatrix& operator += (const Matrix &A)
+ -- : ComplexMatrix& operator -= (const Matrix &A)
+
+ -- : ComplexMatrix& operator += (const ComplexMatrix &A)
+ -- : ComplexMatrix& operator -= (const ComplexMatrix &A)
+
+ -- : Matrix operator ! (void) const
+
+ -- : ComplexMatrix operator + (const ComplexMatrix &A, double S)
+ -- : ComplexMatrix operator - (const ComplexMatrix &A, double S)
+ -- : ComplexMatrix operator * (const ComplexMatrix &A, double S)
+ -- : ComplexMatrix operator / (const ComplexMatrix &A, double S)
+
+ -- : ComplexMatrix operator + (double S, const ComplexMatrix &A)
+ -- : ComplexMatrix operator - (double S, const ComplexMatrix &A)
+ -- : ComplexMatrix operator * (double S, const ComplexMatrix &A)
+ -- : ComplexMatrix operator / (double S, const ComplexMatrix &A)
+
+ -- : ComplexColumnVector operator * (const ComplexMatrix &A, const
+          ColumnVector &B)
+
+ -- : ComplexColumnVector operator * (const ComplexMatrix &A, const
+          ComplexColumnVector &B)
+
+ -- : ComplexMatrix operator + (const ComplexMatrix &A, const
+          DiagMatrix &B)
+ -- : ComplexMatrix operator - (const ComplexMatrix &A, const
+          DiagMatrix &B)
+ -- : ComplexMatrix operator * (const ComplexMatrix &A, const
+          DiagMatrix &B)
+
+ -- : ComplexMatrix operator + (const ComplexMatrix &A, const
+          ComplexDiagMatrix &B)
+ -- : ComplexMatrix operator - (const ComplexMatrix &A, const
+          ComplexDiagMatrix &B)
+ -- : ComplexMatrix operator * (const ComplexMatrix &A, const
+          ComplexDiagMatrix &B)
+
+ -- : ComplexMatrix operator + (const ComplexMatrix &A, const Matrix &B)
+ -- : ComplexMatrix operator - (const ComplexMatrix &A, const Matrix &B)
+
+ -- : ComplexMatrix operator * (const ComplexMatrix &A, const Matrix &B)
+ -- : ComplexMatrix operator * (const ComplexMatrix &A, const
+          ComplexMatrix &B)
+
+ -- : ComplexMatrix product (const ComplexMatrix &A, const Matrix &B)
+ -- : ComplexMatrix quotient (const ComplexMatrix &A, const Matrix &B)
+
+ -- : ComplexMatrix map (c_c_Mapper F, const ComplexMatrix &A)
+ -- : Matrix map (d_c_Mapper F, const ComplexMatrix &A)
+ -- : void map (c_c_Mapper F)
+
+ -- : Matrix all (void) const
+ -- : Matrix any (void) const
+
+ -- : ComplexMatrix cumprod (void) const
+ -- : ComplexMatrix cumsum (void) const
+ -- : ComplexMatrix prod (void) const
+ -- : ComplexMatrix sum (void) const
+ -- : ComplexMatrix sumsq (void) const
+
+ -- : ComplexColumnVector diag (void) const
+ -- : ComplexColumnVector diag (int K) const
+
+ -- : ComplexColumnVector row_min (void) const
+ -- : ComplexColumnVector row_min_loc (void) const
+
+ -- : ComplexColumnVector row_max (void) const
+ -- : ComplexColumnVector row_max_loc (void) const
+
+ -- : ComplexRowVector column_min (void) const
+ -- : ComplexRowVector column_min_loc (void) const
+
+ -- : ComplexRowVector column_max (void) const
+ -- : ComplexRowVector column_max_loc (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexMatrix &A)
+ -- : istream& operator >> (istream &IS, ComplexMatrix &A)
+
+ -- :  ComplexColumnVector (void)
+ -- :  ComplexColumnVector (int N)
+ -- :  ComplexColumnVector (int N, const Complex &VAL)
+ -- :  ComplexColumnVector (const ColumnVector &A)
+ -- :  ComplexColumnVector (const Array<Complex> &A)
+ -- :  ComplexColumnVector (const ComplexColumnVector &A)
+
+ -- : ComplexColumnVector& operator = (const ComplexColumnVector &A)
+
+ -- : int operator == (const ComplexColumnVector &A) const
+ -- : int operator != (const ComplexColumnVector &A) const
+
+ -- : ComplexColumnVector& insert (const ColumnVector &A, int R)
+ -- : ComplexColumnVector& insert (const ComplexColumnVector &A, int R)
+
+ -- : ComplexColumnVector& fill (double VAL)
+ -- : ComplexColumnVector& fill (const Complex &VAL)
+ -- : ComplexColumnVector& fill (double VAL, int r1, int r2)
+ -- : ComplexColumnVector& fill (const Complex &VAL, int r1, int r2)
+
+ -- : ComplexColumnVector stack (const ColumnVector &A) const
+ -- : ComplexColumnVector stack (const ComplexColumnVector &A) const
+
+ -- : ComplexRowVector transpose (void) const
+
+ -- : ColumnVector real (const ComplexColumnVector &A)
+ -- : ColumnVector imag (const ComplexColumnVector &A)
+ -- : ComplexColumnVector conj (const ComplexColumnVector &A)
+
+ -- : ComplexColumnVector extract (int r1, int r2) const
+
+ -- : ComplexColumnVector& operator += (const ColumnVector &A)
+ -- : ComplexColumnVector& operator -= (const ColumnVector &A)
+
+ -- : ComplexColumnVector& operator += (const ComplexColumnVector &A)
+ -- : ComplexColumnVector& operator -= (const ComplexColumnVector &A)
+
+ -- : ComplexColumnVector operator + (const ComplexColumnVector &A,
+          double S)
+ -- : ComplexColumnVector operator - (const ComplexColumnVector &A,
+          double S)
+ -- : ComplexColumnVector operator * (const ComplexColumnVector &A,
+          double S)
+ -- : ComplexColumnVector operator / (const ComplexColumnVector &A,
+          double S)
+
+ -- : ComplexColumnVector operator + (double S, const
+          ComplexColumnVector &A)
+ -- : ComplexColumnVector operator - (double S, const
+          ComplexColumnVector &A)
+ -- : ComplexColumnVector operator * (double S, const
+          ComplexColumnVector &A)
+ -- : ComplexColumnVector operator / (double S, const
+          ComplexColumnVector &A)
+
+ -- : ComplexMatrix operator * (const ComplexColumnVector &A, const
+          ComplexRowVector &B)
+
+ -- : ComplexColumnVector operator + (const ComplexColumnVector &A,
+          const ColumnVector &B)
+ -- : ComplexColumnVector operator - (const ComplexColumnVector &A,
+          const ColumnVector &B)
+
+ -- : ComplexColumnVector product (const ComplexColumnVector &A, const
+          ColumnVector &B)
+ -- : ComplexColumnVector quotient (const ComplexColumnVector &A, const
+          ColumnVector &B)
+
+ -- : ComplexColumnVector map (c_c_Mapper F, const ComplexColumnVector
+          &A)
+ -- : ColumnVector map (d_c_Mapper F, const ComplexColumnVector &A)
+ -- : void map (c_c_Mapper F)
+
+ -- : Complex min (void) const
+ -- : Complex max (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexColumnVector &A)
+
+ -- :  ComplexRowVector (void)
+ -- :  ComplexRowVector (int N)
+ -- :  ComplexRowVector (int N, const Complex &VAL)
+ -- :  ComplexRowVector (const RowVector &A)
+ -- :  ComplexRowVector (const Array<Complex> &A)
+ -- :  ComplexRowVector (const ComplexRowVector &A)
+
+ -- : ComplexRowVector& operator = (const ComplexRowVector &A)
+
+ -- : int operator == (const ComplexRowVector &A) const
+ -- : int operator != (const ComplexRowVector &A) const
+
+ -- : ComplexRowVector& insert (const RowVector &A, int C)
+ -- : ComplexRowVector& insert (const ComplexRowVector &A, int C)
+
+ -- : ComplexRowVector& fill (double VAL)
+ -- : ComplexRowVector& fill (const Complex &VAL)
+ -- : ComplexRowVector& fill (double VAL, int c1, int c2)
+ -- : ComplexRowVector& fill (const Complex &VAL, int c1, int c2)
+
+ -- : ComplexRowVector append (const RowVector &A) const
+ -- : ComplexRowVector append (const ComplexRowVector &A) const
+
+ -- : ComplexColumnVector transpose (void) const
+
+ -- : RowVector real (const ComplexRowVector &A)
+ -- : RowVector imag (const ComplexRowVector &A)
+ -- : ComplexRowVector conj (const ComplexRowVector &A)
+
+ -- : ComplexRowVector extract (int c1, int c2) const
+
+ -- : ComplexRowVector& operator += (const RowVector &A)
+ -- : ComplexRowVector& operator -= (const RowVector &A)
+
+ -- : ComplexRowVector& operator += (const ComplexRowVector &A)
+ -- : ComplexRowVector& operator -= (const ComplexRowVector &A)
+
+ -- : ComplexRowVector operator + (const ComplexRowVector &A, double S)
+ -- : ComplexRowVector operator - (const ComplexRowVector &A, double S)
+ -- : ComplexRowVector operator * (const ComplexRowVector &A, double S)
+ -- : ComplexRowVector operator / (const ComplexRowVector &A, double S)
+
+ -- : ComplexRowVector operator + (double S, const ComplexRowVector &A)
+ -- : ComplexRowVector operator - (double S, const ComplexRowVector &A)
+ -- : ComplexRowVector operator * (double S, const ComplexRowVector &A)
+ -- : ComplexRowVector operator / (double S, const ComplexRowVector &A)
+
+ -- : Complex operator * (const ComplexRowVector &A, const ColumnVector
+          &B)
+
+ -- : Complex operator * (const ComplexRowVector &A, const
+          ComplexColumnVector &B)
+
+ -- : ComplexRowVector operator * (const ComplexRowVector &A, const
+          ComplexMatrix &B)
+
+ -- : ComplexRowVector operator + (const ComplexRowVector &A, const
+          RowVector &B)
+ -- : ComplexRowVector operator - (const ComplexRowVector &A, const
+          RowVector &B)
+
+ -- : ComplexRowVector product (const ComplexRowVector &A, const
+          RowVector &B)
+ -- : ComplexRowVector quotient (const ComplexRowVector &A, const
+          RowVector &B)
+
+ -- : ComplexRowVector map (c_c_Mapper F, const ComplexRowVector &A)
+ -- : RowVector map (d_c_Mapper F, const ComplexRowVector &A)
+ -- : void map (c_c_Mapper F)
+
+ -- : Complex min (void) const
+ -- : Complex max (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexRowVector &A)
+
+ -- :  ComplexDiagMatrix (void)
+ -- :  ComplexDiagMatrix (int N)
+ -- :  ComplexDiagMatrix (int N, const Complex &VAL)
+ -- :  ComplexDiagMatrix (int R, int C)
+ -- :  ComplexDiagMatrix (int R, int C, const Complex &VAL)
+ -- :  ComplexDiagMatrix (const RowVector &A)
+ -- :  ComplexDiagMatrix (const ComplexRowVector &A)
+ -- :  ComplexDiagMatrix (const ColumnVector &A)
+ -- :  ComplexDiagMatrix (const ComplexColumnVector &A)
+ -- :  ComplexDiagMatrix (const DiagMatrix &A)
+ -- :  ComplexDiagMatrix (const DiagArray<Complex> &A)
+ -- :  ComplexDiagMatrix (const ComplexDiagMatrix &A)
+
+ -- : ComplexDiagMatrix& operator = (const ComplexDiagMatrix &A)
+
+ -- : int operator == (const ComplexDiagMatrix &A) const
+ -- : int operator != (const ComplexDiagMatrix &A) const
+
+ -- : ComplexDiagMatrix& fill (double VAL)
+ -- : ComplexDiagMatrix& fill (const Complex &VAL)
+ -- : ComplexDiagMatrix& fill (double VAL, int BEG, int END)
+ -- : ComplexDiagMatrix& fill (const Complex &VAL, int BEG, int END)
+ -- : ComplexDiagMatrix& fill (const ColumnVector &A)
+ -- : ComplexDiagMatrix& fill (const ComplexColumnVector &A)
+ -- : ComplexDiagMatrix& fill (const RowVector &A)
+ -- : ComplexDiagMatrix& fill (const ComplexRowVector &A)
+ -- : ComplexDiagMatrix& fill (const ColumnVector &A, int BEG)
+ -- : ComplexDiagMatrix& fill (const ComplexColumnVector &A, int BEG)
+ -- : ComplexDiagMatrix& fill (const RowVector &A, int BEG)
+ -- : ComplexDiagMatrix& fill (const ComplexRowVector &A, int BEG)
+
+ -- : ComplexDiagMatrix transpose (void) const
+
+ -- : DiagMatrix real (const ComplexDiagMatrix &A)
+ -- : DiagMatrix imag (const ComplexDiagMatrix &A)
+ -- : ComplexDiagMatrix conj (const ComplexDiagMatrix &A)
+
+ -- : ComplexMatrix extract (int r1, int c1, int r2, int c2) const
+
+ -- : ComplexRowVector row (int I) const
+ -- : ComplexRowVector row (char *s) const
+
+ -- : ComplexColumnVector column (int I) const
+ -- : ComplexColumnVector column (char *s) const
+
+ -- : ComplexDiagMatrix inverse (int &INFO) const
+ -- : ComplexDiagMatrix inverse (void) const
+
+ -- : ComplexDiagMatrix& operator += (const DiagMatrix &A)
+ -- : ComplexDiagMatrix& operator -= (const DiagMatrix &A)
+
+ -- : ComplexDiagMatrix& operator += (const ComplexDiagMatrix &A)
+ -- : ComplexDiagMatrix& operator -= (const ComplexDiagMatrix &A)
+
+ -- : ComplexMatrix operator + (const ComplexDiagMatrix &A, double S)
+ -- : ComplexMatrix operator - (const ComplexDiagMatrix &A, double S)
+
+ -- : ComplexMatrix operator + (const ComplexDiagMatrix &A, const
+          Complex &S)
+ -- : ComplexMatrix operator - (const ComplexDiagMatrix &A, const
+          Complex &S)
+
+ -- : ComplexDiagMatrix operator * (const ComplexDiagMatrix &A, double
+          S)
+ -- : ComplexDiagMatrix operator / (const ComplexDiagMatrix &A, double
+          S)
+
+ -- : ComplexMatrix operator + (double S, const ComplexDiagMatrix &A)
+ -- : ComplexMatrix operator - (double S, const ComplexDiagMatrix &A)
+
+ -- : ComplexMatrix operator + (const Complex &S, const
+          ComplexDiagMatrix &A)
+ -- : ComplexMatrix operator - (const Complex &S, const
+          ComplexDiagMatrix &A)
+
+ -- : ComplexDiagMatrix operator * (double S, const ComplexDiagMatrix
+          &A)
+
+ -- : ComplexColumnVector operator * (const ComplexDiagMatrix &A, const
+          ColumnVector &B)
+
+ -- : ComplexColumnVector operator * (const ComplexDiagMatrix &A, const
+          ComplexColumnVector &B)
+
+ -- : ComplexDiagMatrix operator + (const ComplexDiagMatrix &A, const
+          DiagMatrix &B)
+ -- : ComplexDiagMatrix operator - (const ComplexDiagMatrix &A, const
+          DiagMatrix &B)
+
+ -- : ComplexDiagMatrix product (const ComplexDiagMatrix &A, const
+          DiagMatrix &B)
+
+ -- : ComplexMatrix operator + (const ComplexDiagMatrix &A, const
+          Matrix &B)
+ -- : ComplexMatrix operator - (const ComplexDiagMatrix &A, const
+          Matrix &B)
+ -- : ComplexMatrix operator * (const ComplexDiagMatrix &A, const
+          Matrix &B)
+
+ -- : ComplexMatrix operator + (const ComplexDiagMatrix &A, const
+          ComplexMatrix &B)
+ -- : ComplexMatrix operator - (const ComplexDiagMatrix &A, const
+          ComplexMatrix &B)
+ -- : ComplexMatrix operator * (const ComplexDiagMatrix &A, const
+          ComplexMatrix &B)
+
+ -- : ComplexColumnVector diag (void) const
+ -- : ComplexColumnVector diag (int K) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexDiagMatrix &A)
+
+
+File: liboctave.info,  Node: Matrix Factorizations,  Next: Ranges,  Prev: Matrix and Vector Operations,  Up: Top
+
+5 Matrix Factorizations
+***********************
+
+ -- :  AEPBALANCE (void)
+ -- :  AEPBALANCE (const Matrix &A, const char *BALANCE_JOB)
+ -- :  AEPBALANCE (const AEPBALANCE &A)
+
+ -- : AEPBALANCE& operator = (const AEPBALANCE &A)
+
+ -- : Matrix balanced_matrix (void) const
+ -- : Matrix balancing_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const AEPBALANCE &A)
+
+ -- :  ComplexAEPBALANCE (void)
+ -- :  ComplexAEPBALANCE (const ComplexMatrix &A, const char
+          *BALANCE_JOB)
+ -- :  ComplexAEPBALANCE (const ComplexAEPBALANCE &A)
+
+ -- : ComplexAEPBALANCE& operator = (const ComplexAEPBALANCE &A)
+
+ -- : ComplexMatrix balanced_matrix (void) const
+ -- : ComplexMatrix balancing_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexAEPBALANCE &A)
+
+ -- :  DET (void)
+ -- :  DET (const DET &A)
+
+ -- : DET& operator = (const DET &A)
+
+ -- : int value_will_overflow (void) const
+ -- : int value_will_underflow (void) const
+
+ -- : double coefficient (void) const
+ -- : int exponent (void) const
+ -- : double value (void) const
+
+ -- : ostream& operator << (ostream &OS, const DET &A)
+
+ -- :  ComplexDET (void)
+ -- :  ComplexDET (const ComplexDET &A)
+
+ -- : ComplexDET& operator = (const ComplexDET &A)
+
+ -- : int value_will_overflow (void) const
+ -- : int value_will_underflow (void) const
+
+ -- : Complex coefficient (void) const
+ -- : int exponent (void) const
+ -- : Complex value (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexDET &A)
+
+ -- :  GEPBALANCE (void)
+ -- :  GEPBALANCE (const Matrix &A, const Matrix &, const char
+          *BALANCE_JOB)
+ -- :  GEPBALANCE (const GEPBALANCE &A)
+
+ -- : GEPBALANCE& operator = (const GEPBALANCE &A)
+
+ -- : Matrix balanced_a_matrix (void) const
+ -- : Matrix balanced_b_matrix (void) const
+ -- : Matrix left_balancing_matrix (void) const
+ -- : Matrix right_balancing_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const GEPBALANCE &A)
+
+ -- :  CHOL (void)
+ -- :  CHOL (const Matrix &A)
+ -- :  CHOL (const Matrix &A, int &INFO)
+ -- :  CHOL (const CHOL &A)
+
+ -- : CHOL& operator = (const CHOL &A)
+
+ -- : Matrix chol_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const CHOL &A)
+
+ -- :  ComplexCHOL (void)
+ -- :  ComplexCHOL (const ComplexMatrix &A)
+ -- :  ComplexCHOL (const ComplexMatrix &A, int &INFO)
+ -- :  ComplexCHOL (const ComplexCHOL &A)
+
+ -- : ComplexCHOL& operator = (const ComplexCHOL &A)
+
+ -- : ComplexMatrix chol_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexCHOL &A)
+
+ -- :  HESS (void)
+ -- :  HESS (const Matrix &A)
+ -- :  HESS (const Matrix&a, int &INFO)
+ -- :  HESS (const HESS &A)
+
+ -- : HESS& operator = (const HESS &A)
+
+ -- : Matrix hess_matrix (void) const
+ -- : Matrix unitary_hess_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const HESS &A)
+
+ -- :  ComplexHESS (void)
+ -- :  ComplexHESS (const ComplexMatrix &A)
+ -- :  ComplexHESS (const ComplexMatrix &A, int &INFO)
+ -- :  ComplexHESS (const ComplexHESS &A)
+
+ -- : ComplexHESS& operator = (const ComplexHESS &A)
+
+ -- : ComplexMatrix hess_matrix (void) const
+ -- : ComplexMatrix unitary_hess_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexHESS &A)
+
+ -- :  SCHUR (void)
+ -- :  SCHUR (const Matrix &A, const char *ORD)
+ -- :  SCHUR (const Matrix &A, const char *ORD, int &INFO)
+ -- :  SCHUR (const SCHUR &A, const char *ORD)
+
+ -- : SCHUR& operator = (const SCHUR &A)
+
+ -- : Matrix schur_matrix (void) const
+ -- : Matrix unitary_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const SCHUR &A)
+
+ -- :  ComplexSCHUR (void)
+ -- :  ComplexSCHUR (const ComplexMatrix &A, const char *ORD)
+ -- :  ComplexSCHUR (const ComplexMatrix &A, const char *ORD, int &INFO)
+ -- :  ComplexSCHUR (const ComplexSCHUR &A, const char *ORD)
+
+ -- : ComplexSCHUR& operator = (const ComplexSCHUR &A)
+
+ -- : ComplexMatrix schur_matrix (void) const
+ -- : ComplexMatrix unitary_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexSCHUR &A)
+
+ -- :  SVD (void)
+ -- :  SVD (const Matrix &A)
+ -- :  SVD (const Matrix &A, int &INFO)
+ -- :  SVD (const SVD &A)
+
+ -- : SVD& operator = (const SVD &A)
+
+ -- : DiagMatrix singular_values (void) const
+ -- : Matrix left_singular_matrix (void) const
+ -- : Matrix right_singular_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const SVD &A)
+
+ -- :  ComplexSVD (void)
+ -- :  ComplexSVD (const ComplexMatrix &A)
+ -- :  ComplexSVD (const ComplexMatrix &A, int &INFO)
+ -- :  ComplexSVD (const ComplexSVD &A)
+
+ -- : ComplexSVD& operator = (const ComplexSVD &A)
+
+ -- : DiagMatrix singular_values (void) const
+ -- : ComplexMatrix left_singular_matrix (void) const
+ -- : ComplexMatrix right_singular_matrix (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexSVD &A)
+
+ -- :  EIG (void)
+ -- :  EIG (const Matrix &A)
+ -- :  EIG (const Matrix &A, int &INFO)
+ -- :  EIG (const ComplexMatrix &A)
+ -- :  EIG (const ComplexMatrix &A, int &INFO)
+ -- :  EIG (const EIG &A)
+
+ -- : EIG& operator = (const EIG &A)
+
+ -- : ComplexColumnVector eigenvalues (void) const
+
+ -- : ComplexMatrix eigenvectors (void) const
+
+ -- : ostream& operator << (ostream &OS, const EIG &A)
+
+ -- :  LU (void)
+ -- :  LU (const Matrix &A)
+ -- :  LU (const LU &A)
+
+ -- : LU& operator = (const LU &A)
+
+ -- : Matrix L (void) const
+ -- : Matrix U (void) const
+ -- : Matrix P (void) const
+
+ -- : ostream& operator << (ostream &OS, const LU &A)
+
+ -- :  ComplexLU (void)
+ -- :  ComplexLU (const ComplexMatrix &A)
+ -- :  ComplexLU (const ComplexLU &A)
+
+ -- : ComplexLU& operator = (const ComplexLU &A)
+
+ -- : ComplexMatrix L (void) const
+ -- : ComplexMatrix U (void) const
+ -- : Matrix P (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexLU &A)
+
+ -- :  QR (void)
+ -- :  QR (const Matrix &A)
+ -- :  QR (const QR &A)
+
+ -- : QR& operator = (const QR &A)
+
+ -- : Matrix Q (void) const
+ -- : Matrix R (void) const
+
+ -- : ostream& operator << (ostream &OS, const QR &A)
+
+ -- :  ComplexQR (void)
+ -- :  ComplexQR (const ComplexMatrix &A)
+ -- :  ComplexQR (const ComplexQR &A)
+
+ -- : ComplexQR& operator = (const ComplexQR &A)
+
+ -- : ComplexMatrix Q (void) const
+ -- : ComplexMatrix R (void) const
+
+ -- : ostream& operator << (ostream &OS, const ComplexQR &A)
+
+
+File: liboctave.info,  Node: Ranges,  Next: Nonlinear Functions,  Prev: Matrix Factorizations,  Up: Top
+
+6 Ranges
+********
+
+ -- :  Range (void)
+ -- :  Range (const Range &R)
+ -- :  Range (double B, double L)
+ -- :  Range (double B, double L, double I)
+
+ -- : double base (void) const
+ -- : double limit (void) const
+ -- : double inc (void) const
+
+ -- : void set_base (double B)
+ -- : void set_limit (double L)
+ -- : void set_inc (double I)
+
+ -- : int nelem (void) const
+
+ -- : double min (void) const
+ -- : double max (void) const
+
+ -- : void sort (void)
+
+ -- : ostream& operator << (ostream &OS, const Range &R)
+ -- : istream& operator >> (istream &IS, Range &R)
+
+ -- : void print_range (void)
+
+
+File: liboctave.info,  Node: Nonlinear Functions,  Next: Nonlinear Equations,  Prev: Ranges,  Up: Top
+
+7 Nonlinear Functions
+*********************
+
+ -- :  NLFunc (void)
+ -- :  NLFunc (const NONLINEAR_FCN)
+ -- :  NLFunc (const NONLINEAR_FCN, const JACOBIAN_FCN)
+ -- :  NLFunc (const NLFunc &A)
+
+ -- : NLFunc& operator = (const NLFunc &A)
+
+ -- : nonlinear_fcn function (void) const;
+
+ -- : NLFunc& set_function (const nonlinear_fcn F)
+
+ -- : jacobian_fcn jacobian_function (void) const;
+
+ -- : NLFunc& set_jacobian_function (const jacobian_fcn J)
+
+
+File: liboctave.info,  Node: Nonlinear Equations,  Next: Optimization,  Prev: Nonlinear Functions,  Up: Top
+
+8 Nonlinear Equations
+*********************
+
+ -- :  NLEqn_options (void)
+ -- :  NLEqn_options (const NLEqn_options &OPT)
+
+ -- : NLEqn_options& operator = (const NLEqn_options &OPT)
+
+ -- : void init (void)
+
+ -- : void copy (const NLEqn_options &OPT)
+
+ -- : void set_default_options (void)
+
+ -- : void set_tolerance (double VAL)
+
+ -- : double tolerance (void)
+
+ -- :  NLEqn (void)
+ -- :  NLEqn (const ColumnVector&, const NLFUNC)
+ -- :  NLEqn (const NLEqn &A)
+
+ -- : NLEqn& operator = (const NLEqn &A)
+
+ -- : void resize (int N)
+
+ -- : void set_states (const ColumnVector &X)
+
+ -- : ColumnVector states (void) const
+
+ -- : int size (void) const
+
+ -- : ColumnVector solve (void)
+ -- : ColumnVector solve (const ColumnVector &X)
+
+ -- : ColumnVector solve (int &INFO)
+ -- : ColumnVector solve (const ColumnVector &X, int &INFO)
+
+
+File: liboctave.info,  Node: Optimization,  Next: Quadrature,  Prev: Nonlinear Equations,  Up: Top
+
+9 Optimization
+**************
+
+* Menu:
+
+* Objective Functions::
+* Bounds::
+* Linear Constraints::
+* Nonlinear Constraints::
+* Quadratic Programming::
+* Nonlinear Programming::
+
+
+File: liboctave.info,  Node: Objective Functions,  Next: Bounds,  Prev: Optimization,  Up: Optimization
+
+9.1 Objective Functions
+=======================
+
+ -- :  Objective (void)
+ -- :  Objective (const OBJECTIVE_FCN)
+ -- :  Objective (const OBJECTIVE_FCN, const GRADIENT_FCN)
+ -- :  Objective (const Objective &A)
+
+ -- : Objective& operator = (const Objective &A)
+
+ -- : objective_fcn objective_function (void) const;
+
+ -- : Objective& set_objective_function (const OBJECTIVE_FCN)
+
+ -- : gradient_fcn gradient_function (void) const;
+
+ -- : Objective& set_gradient_function (const GRADIENT_FCN)
+
+
+File: liboctave.info,  Node: Bounds,  Next: Linear Constraints,  Prev: Objective Functions,  Up: Optimization
+
+9.2 Bounds
+==========
+
+ -- :  Bounds (void)
+ -- :  Bounds (int N)
+ -- :  Bounds (const ColumnVector LB, const ColumnVector UB)
+ -- :  Bounds (const Bounds &A)
+
+ -- : Bounds& operator = (const Bounds &A)
+
+ -- : Bounds& resize (int N)
+
+ -- : double lower_bound (int INDEX) const;
+ -- : double upper_bound (int INDEX) const;
+
+ -- : ColumnVector lower_bounds (void) const;
+ -- : ColumnVector upper_bounds (void) const;
+
+ -- : int size (void) const;
+
+ -- : Bounds& set_bound (int INDEX, double LOW, double HIGH)
+
+ -- : Bounds& set_bounds (double LOW, double HIGH)
+ -- : Bounds& set_bounds (const ColumnVector LB, const ColumnVector UB)
+
+ -- : Bounds& set_lower_bound (int INDEX, double LOW)
+ -- : Bounds& set_upper_bound (int INDEX, double HIGH)
+
+ -- : Bounds& set_lower_bounds (double LOW)
+ -- : Bounds& set_upper_bounds (double HIGH)
+
+ -- : Bounds& set_lower_bounds (const ColumnVector LB)
+ -- : Bounds& set_upper_bounds (const ColumnVector UB)
+
+ -- : ostream& operator << (ostream &OS, const Bounds &B)
+
+
+File: liboctave.info,  Node: Linear Constraints,  Next: Nonlinear Constraints,  Prev: Bounds,  Up: Optimization
+
+9.3 Linear Constraints
+======================
+
+ -- :  LinConst (void)
+ -- :  LinConst (int NCLIN, int NX)
+ -- :  LinConst (int NCLIN_EQ, int NCLIN_INEQ, int NX)
+ -- :  LinConst (const ColumnVector &LB, const Matrix &A, const
+          ColumnVector &UB)
+ -- :  LinConst (const Matrix &A_EQ, const ColumnVector &B_EQ, const
+          Matrix &A_INEQ, const ColumnVector &B_INEQ)
+ -- :  LinConst (const LinConst &A)
+
+ -- : LinConst& operator = (const LinConst &A)
+
+ -- : LinConst& resize (int NCLIN, int N)
+
+ -- : Matrix constraint_matrix (void) const;
+
+ -- : LinConst& set_constraint_matrix (const Matrix &A)
+
+ -- : Matrix eq_constraint_matrix (void) const;
+ -- : Matrix ineq_constraint_matrix (void) const;
+
+ -- : ColumnVector eq_constraint_vector (void) const;
+ -- : ColumnVector ineq_constraint_vector (void) const;
+
+ -- : ostream& operator << (ostream &OS, const LinConst &B)
+
+
+File: liboctave.info,  Node: Nonlinear Constraints,  Next: Quadratic Programming,  Prev: Linear Constraints,  Up: Optimization
+
+9.4 Nonlinear Constraints
+=========================
+
+ -- :  NLConst (void)
+ -- :  NLConst (int N)
+ -- :  NLConst (const ColumnVector LB, const NLFunc F, const
+          ColumnVector UB)
+ -- :  NLConst (const NLConst &A)
+
+ -- : NLConst& operator = (const NLConst &A)
+
+
+File: liboctave.info,  Node: Quadratic Programming,  Next: Nonlinear Programming,  Prev: Nonlinear Constraints,  Up: Optimization
+
+9.5 Quadratic Programming
+=========================
+
+ -- :  QP (void)
+ -- :  QP (const ColumnVector &X, const Matrix &H)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const ColumnVector
+          &C)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const Bounds &B)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const LinConst &LC)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const ColumnVector
+          &C, const Bounds &B)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const ColumnVector
+          &C, const LinConst &LC)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const Bounds &B,
+          const LinConst &LC)
+ -- :  QP (const ColumnVector &X, const Matrix &H, const ColumnVector
+          &C, const Bounds &B, const LinConst &LC)
+
+ -- : virtual ColumnVector minimize (void)
+ -- : virtual ColumnVector minimize (double &OBJF)
+ -- : virtual ColumnVector minimize (double &OBJF, int &INFORM)
+ -- : virtual ColumnVector minimize (double &OBJF, int &INFORM,
+          ColumnVector &LAMBDA) = 0;
+
+ -- : virtual ColumnVector minimize (const ColumnVector &X)
+ -- : virtual ColumnVector minimize (const ColumnVector &X, double
+          &OBJF)
+ -- : virtual ColumnVector minimize (const ColumnVector &X, double
+          &OBJF, int &INFORM)
+ -- : virtual ColumnVector minimize (const ColumnVector &X, double
+          &OBJF, int &INFORM, ColumnVector &LAMBDA)
+
+ -- : ColumnVector minimize (double &OBJF, int &INFORM, ColumnVector
+          &LAMBDA)
+
+
+File: liboctave.info,  Node: Nonlinear Programming,  Prev: Quadratic Programming,  Up: Optimization
+
+9.6 Nonlinear Programming
+=========================
+
+ -- :  NLP (void)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const Bounds
+          &B)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const Bounds
+          &B, const LinConst &LC)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const Bounds
+          &B, const LinConst &LC, const NLConst &NLC)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const LinConst
+          &LC)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const LinConst
+          &LC, const NLConst &NLC)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const NLConst
+          &NLC)
+ -- :  NLP (const ColumnVector &X, const Objective &PHI, const Bounds
+          &B, const NLConst &NLC)
+
+ -- : NLP& operator = (const NLP &A)
+
+ -- : int size (void) const
+
+ -- : ColumnVector minimize (void)
+ -- : ColumnVector minimize (double &OBJF)
+ -- : ColumnVector minimize (double &OBJF, int &INFORM)
+ -- : ColumnVector minimize (double &OBJF, int &INFORM, ColumnVector
+          &LAMBDA)
+
+ -- : ColumnVector minimize (const ColumnVector &X)
+ -- : ColumnVector minimize (const ColumnVector &X, double &OBJF)
+ -- : ColumnVector minimize (const ColumnVector &X, double &OBJF, int
+          &INFORM)
+ -- : ColumnVector minimize (const ColumnVector &X, double &OBJF, int
+          &INFORM, ColumnVector &LAMBDA)
+
+
+File: liboctave.info,  Node: Quadrature,  Next: Ordinary Differential Equations,  Prev: Optimization,  Up: Top
+
+10 Quadrature
+*************
+
+ -- :  Quad (integrand_fcn FCN)
+ -- :  Quad (integrand_fcn FCN, double ABS, double REL)
+
+ -- : virtual double integrate (void)
+ -- : virtual double integrate (int &IER)
+ -- : virtual double integrate (int &IER, int &NEVAL)
+ -- : virtual double integrate (int &IER, int &NEVAL, double &ABSERR) =
+          0
+
+ -- :  Quad_options (void)
+ -- :  Quad_options (const Quad_options &OPT)
+
+ -- : Quad_options& operator = (const Quad_options &OPT)
+
+ -- : void init (void)
+
+ -- : void copy (const Quad_options &OPT)
+
+ -- : void set_default_options (void)
+
+ -- : void set_absolute_tolerance (double VAL)
+
+ -- : void set_relative_tolerance (double VAL)
+
+ -- : double absolute_tolerance (void)
+ -- : double relative_tolerance (void)
+
+ -- :  DefQuad (integrand_fcn FCN)
+ -- :  DefQuad (integrand_fcn FCN, double LL, double UL)
+ -- :  DefQuad (integrand_fcn FCN, double LL, double UL, double ABS,
+          double REL)
+ -- :  DefQuad (integrand_fcn FCN, double LL, double UL, const
+          ColumnVector &SING)
+ -- :  DefQuad (integrand_fcn FCN, const ColumnVector &SING, double
+          ABS, double REL)
+ -- :  DefQuad (integrand_fcn FCN, const ColumnVector &SING)
+ -- :  DefQuad (integrand_fcn FCN, double LL, double UL, const
+          ColumnVector &SING, double ABS, double REL)
+
+ -- :  IndefQuad (integrand_fcn FCN)
+ -- :  IndefQuad (integrand_fcn FCN, double B, IntegralType T)
+ -- :  IndefQuad (integrand_fcn FCN, double B, IntegralType T, double
+          ABS, double REL)
+ -- :  IndefQuad (integrand_fcn FCN, double ABS, double REL)
+
+* Menu:
+
+* Collocation Weights::
+
+
+File: liboctave.info,  Node: Collocation Weights,  Prev: Quadrature,  Up: Quadrature
+
+10.1 Collocation Weights
+========================
+
+ -- :  CollocWt (void)
+ -- :  CollocWt (int N, int INC_L, int INC_R)
+ -- :  CollocWt (int N, int INC_L, int INC_R, double L, double R)
+ -- :  CollocWt (int N, double A, double B, int INC_L, int INC_R)
+ -- :  CollocWt (int N, int INC_L, int INC_R, double L, double R)
+ -- :  CollocWt (const CollocWt&)
+
+ -- : CollocWt& operator = (const CollocWt&)
+
+ -- : CollocWt& resize (int NCOL)
+
+ -- : CollocWt& add_left (void)
+ -- : CollocWt& add_right (void)
+
+ -- : CollocWt& delete_left (void)
+ -- : CollocWt& delete_right (void)
+
+ -- : CollocWt& set_left (double VAL)
+ -- : CollocWt& set_right (double VAL)
+
+ -- : CollocWt& set_alpha (double VAL)
+ -- : CollocWt& set_beta (double VAL)
+
+ -- : int ncol (void) const
+
+ -- : int left_included (void) const
+ -- : int right_included (void) const
+
+ -- : double left (void) const
+ -- : double right (void) const
+ -- : double width (void) const
+
+ -- : double alpha (void) const
+ -- : double beta (void) const
+
+ -- : ColumnVector roots (void)
+ -- : ColumnVector quad (void)
+ -- : ColumnVector quad_weights (void)
+
+ -- : Matrix first (void)
+ -- : Matrix second (void)
+
+ -- : ostream& operator << (ostream &OS, const CollocWt &C)
+
+
+File: liboctave.info,  Node: Ordinary Differential Equations,  Next: Differential Algebraic Equations,  Prev: Quadrature,  Up: Top
+
+11 Ordinary Differential Equations
+**********************************
+
+ -- :  ODE_options (void)
+ -- :  ODE_options (const ODE_options &OPT)
+
+ -- : ODE_options& operator = (const ODE_options &OPT)
+
+ -- : void init (void)
+
+ -- : void copy (const ODE_options &OPT)
+
+ -- : void set_default_options (void)
+
+ -- : void set_absolute_tolerance (double VAL)
+
+ -- : void set_initial_step_size (double VAL)
+
+ -- : void set_maximum_step_size (double VAL)
+
+ -- : void set_minimum_step_size (double VAL)
+
+ -- : void set_relative_tolerance (double VAL)
+
+ -- : double absolute_tolerance (void)
+ -- : double initial_step_size (void)
+ -- : double maximum_step_size (void)
+ -- : double minimum_step_size (void)
+ -- : double relative_tolerance (void)
+
+ -- :  ODE (void)
+ -- :  ODE (int N)
+ -- :  ODE (const ColumnVector &STATE, double TIME, const ODEFunc &F)
+
+ -- : virtual int size (void) const
+
+ -- : virtual ColumnVector state (void) const
+
+ -- : virtual double time (void) const
+
+ -- : virtual void force_restart (void)
+
+ -- : virtual void initialize (const ColumnVector &X, double T)
+
+ -- : virtual void set_stop_time (double T)
+
+ -- : virtual void clear_stop_time (void)
+
+ -- : virtual ColumnVector integrate (double T)
+
+ -- : void integrate (int NSTEPS, double TSTEP, ostream &S)
+
+ -- : Matrix integrate (const ColumnVector &TOUT)
+ -- : Matrix integrate (const ColumnVector &TOUT, const ColumnVector
+          &TCRIT)
+
+
+File: liboctave.info,  Node: Differential Algebraic Equations,  Next: Error Handling,  Prev: Ordinary Differential Equations,  Up: Top
+
+12 Differential Algebraic Equations
+***********************************
+
+ -- :  DAE (void)
+ -- :  DAE (int N)
+ -- :  DAE (const ColumnVector &X, double TIME, DAEFunc &F)
+ -- :  DAE (const ColumnVector &X, ColumnVector &XDOT, double TIME,
+          DAEFunc &F)
+
+ -- : ColumnVector deriv (void)
+
+ -- : virtual void initialize (const ColumnVector &X, double T)
+ -- : virtual void initialize (const ColumnVector &X, ColumnVector
+          &XDOT, double T)
+
+ -- : ColumnVector integrate (double T)
+
+ -- : Matrix integrate (const ColumnVector &TOUT, Matrix &XDOT_OUT)
+ -- : Matrix integrate (const ColumnVector &TOUT, Matrix &XDOT_OUT,
+          const ColumnVector &TCRIT)
+
+
+File: liboctave.info,  Node: Error Handling,  Next: Installation,  Prev: Differential Algebraic Equations,  Up: Top
+
+13 Error Handling
+*****************
+
+
+File: liboctave.info,  Node: Installation,  Next: Bugs,  Prev: Error Handling,  Up: Top
+
+14 Installation
+***************
+
+
+File: liboctave.info,  Node: Bugs,  Next: Concept Index,  Prev: Installation,  Up: Top
+
+15 Bugs
+*******
+
+
+File: liboctave.info,  Node: Concept Index,  Next: Function Index,  Prev: Bugs,  Up: Top
+
+Concept Index
+*************
+
+ [index ]
+* Menu:
+
+* acknowledgements:                      Acknowledgements.     (line  6)
+* arrays:                                Arrays.               (line  6)
+* bounds:                                Bounds.               (line  6)
+* bugs, known:                           Bugs.                 (line  6)
+* collocation weights:                   Collocation Weights.  (line  6)
+* contributors:                          Contributors.         (line  6)
+* copyright:                             Contributors.         (line 10)
+* DAE:                                   Differential Algebraic Equations.
+                                                               (line  6)
+* factorizations:                        Matrix Factorizations.
+                                                               (line  6)
+* installation:                          Installation.         (line  6)
+* installation trouble:                  Bugs.                 (line  6)
+* integration:                           Quadrature.           (line  6)
+* introduction:                          Introduction.         (line  6)
+* known causes of trouble:               Bugs.                 (line  6)
+* linear Constraints:                    Linear Constraints.   (line  6)
+* matrix factorizations:                 Matrix Factorizations.
+                                                               (line  6)
+* matrix manipulations:                  Matrix and Vector Operations.
+                                                               (line  6)
+* NLP:                                   Nonlinear Programming.
+                                                               (line  6)
+* nonlinear Constraints:                 Nonlinear Constraints.
+                                                               (line  6)
+* nonlinear equations:                   Nonlinear Equations.  (line  6)
+* nonlinear functions:                   Nonlinear Functions.  (line  6)
+* nonlinear programming:                 Nonlinear Programming.
+                                                               (line  6)
+* numerical integration:                 Quadrature.           (line  6)
+* objective functions:                   Objective Functions.  (line  6)
+* ODE:                                   Ordinary Differential Equations.
+                                                               (line  6)
+* optimization:                          Optimization.         (line  6)
+* orthogonal collocation:                Collocation Weights.  (line  6)
+* QP:                                    Quadratic Programming.
+                                                               (line  6)
+* quadratic programming:                 Quadratic Programming.
+                                                               (line  6)
+* quadrature:                            Quadrature.           (line  6)
+* ranges:                                Ranges.               (line  6)
+* troubleshooting:                       Bugs.                 (line  6)
+* vector manipulations:                  Matrix and Vector Operations.
+                                                               (line  6)
+* warranty:                              Contributors.         (line 10)
+
+
+File: liboctave.info,  Node: Function Index,  Prev: Concept Index,  Up: Top
+
+Function Index
+**************
+
+ [index ]
+* Menu:
+
+* absolute_tolerance <1>:                Ordinary Differential Equations.
+                                                              (line  28)
+* absolute_tolerance:                    Quadrature.          (line  31)
+* add_left:                              Collocation Weights. (line  18)
+* add_right:                             Collocation Weights. (line  19)
+* AEPBALANCE:                            Matrix Factorizations.
+                                                              (line   7)
+* all:                                   Matrix and Vector Operations.
+                                                              (line 144)
+* alpha:                                 Collocation Weights. (line  39)
+* any:                                   Matrix and Vector Operations.
+                                                              (line 145)
+* append:                                Matrix and Vector Operations.
+                                                              (line  28)
+* Array2<T>:                             Constructors and Assignment.
+                                                              (line  61)
+* Array3<T>:                             Constructors and Assignment.
+                                                              (line  84)
+* Array<T>:                              Constructors and Assignment.
+                                                              (line   7)
+* balanced_a_matrix:                     Matrix Factorizations.
+                                                              (line  65)
+* balanced_b_matrix:                     Matrix Factorizations.
+                                                              (line  66)
+* balanced_matrix:                       Matrix Factorizations.
+                                                              (line  13)
+* balancing_matrix:                      Matrix Factorizations.
+                                                              (line  14)
+* base:                                  Ranges.              (line  12)
+* beta:                                  Collocation Weights. (line  40)
+* Bounds:                                Bounds.              (line   7)
+* capacity on Array<T>:                  Constructors and Assignment.
+                                                              (line  26)
+* checkelem on Array2<T>:                Constructors and Assignment.
+                                                              (line  77)
+* checkelem on Array3<T>:                Constructors and Assignment.
+                                                              (line  96)
+* checkelem on Array<T>:                 Constructors and Assignment.
+                                                              (line  31)
+* checkelem on DiagArray<T>:             Constructors and Assignment.
+                                                              (line 121)
+* CHOL:                                  Matrix Factorizations.
+                                                              (line  72)
+* chol_matrix:                           Matrix Factorizations.
+                                                              (line  79)
+* clear_stop_time:                       Ordinary Differential Equations.
+                                                              (line  50)
+* coefficient:                           Matrix Factorizations.
+                                                              (line  38)
+* CollocWt:                              Collocation Weights. (line   7)
+* cols on Array2<T>:                     Constructors and Assignment.
+                                                              (line  73)
+* cols on DiagArray<T>:                  Constructors and Assignment.
+                                                              (line 117)
+* column:                                Matrix and Vector Operations.
+                                                              (line  45)
+* column_max:                            Matrix and Vector Operations.
+                                                              (line 165)
+* column_max_loc:                        Matrix and Vector Operations.
+                                                              (line 166)
+* column_min:                            Matrix and Vector Operations.
+                                                              (line 162)
+* column_min_loc:                        Matrix and Vector Operations.
+                                                              (line 163)
+* columns on Array2<T>:                  Constructors and Assignment.
+                                                              (line  74)
+* columns on DiagArray<T>:               Constructors and Assignment.
+                                                              (line 118)
+* ColumnVector:                          Matrix and Vector Operations.
+                                                              (line 171)
+* ComplexAEPBALANCE:                     Matrix Factorizations.
+                                                              (line  18)
+* ComplexCHOL:                           Matrix Factorizations.
+                                                              (line  83)
+* ComplexColumnVector:                   Matrix and Vector Operations.
+                                                              (line 578)
+* ComplexDET:                            Matrix Factorizations.
+                                                              (line  44)
+* ComplexDiagMatrix:                     Matrix and Vector Operations.
+                                                              (line 731)
+* ComplexHESS:                           Matrix Factorizations.
+                                                              (line 106)
+* ComplexLU:                             Matrix Factorizations.
+                                                              (line 195)
+* ComplexMatrix:                         Matrix and Vector Operations.
+                                                              (line 390)
+* ComplexQR:                             Matrix Factorizations.
+                                                              (line 218)
+* ComplexRowVector:                      Matrix and Vector Operations.
+                                                              (line 656)
+* ComplexSCHUR:                          Matrix Factorizations.
+                                                              (line 130)
+* ComplexSVD:                            Matrix Factorizations.
+                                                              (line 155)
+* conj:                                  Matrix and Vector Operations.
+                                                              (line 445)
+* constraint_matrix:                     Linear Constraints.  (line  20)
+* copy <1>:                              Ordinary Differential Equations.
+                                                              (line  14)
+* copy <2>:                              Quadrature.          (line  23)
+* copy:                                  Nonlinear Equations. (line  14)
+* cumprod:                               Matrix and Vector Operations.
+                                                              (line 147)
+* cumsum:                                Matrix and Vector Operations.
+                                                              (line 148)
+* DAE:                                   Differential Algebraic Equations.
+                                                              (line   7)
+* data on Array<T>:                      Constructors and Assignment.
+                                                              (line  59)
+* DefQuad:                               Quadrature.          (line  34)
+* delete_left:                           Collocation Weights. (line  21)
+* delete_right:                          Collocation Weights. (line  22)
+* deriv:                                 Differential Algebraic Equations.
+                                                              (line  13)
+* DET:                                   Matrix Factorizations.
+                                                              (line  30)
+* determinant:                           Matrix and Vector Operations.
+                                                              (line  55)
+* diag:                                  Matrix and Vector Operations.
+                                                              (line 153)
+* DiagArray<T>:                          Constructors and Assignment.
+                                                              (line 103)
+* DiagMatrix:                            Matrix and Vector Operations.
+                                                              (line 302)
+* dim1 on Array2<T>:                     Constructors and Assignment.
+                                                              (line  69)
+* dim1 on Array3<T>:                     Constructors and Assignment.
+                                                              (line  91)
+* dim1 on DiagArray<T>:                  Constructors and Assignment.
+                                                              (line 113)
+* dim2 on Array2<T>:                     Constructors and Assignment.
+                                                              (line  72)
+* dim2 on Array3<T>:                     Constructors and Assignment.
+                                                              (line  92)
+* dim2 on DiagArray<T>:                  Constructors and Assignment.
+                                                              (line 116)
+* dim3 on Array3<T>:                     Constructors and Assignment.
+                                                              (line  93)
+* EIG:                                   Matrix Factorizations.
+                                                              (line 168)
+* eigenvalues:                           Matrix Factorizations.
+                                                              (line 177)
+* eigenvectors:                          Matrix Factorizations.
+                                                              (line 179)
+* elem on Array2<T>:                     Constructors and Assignment.
+                                                              (line  76)
+* elem on Array3<T>:                     Constructors and Assignment.
+                                                              (line  95)
+* elem on Array<T>:                      Constructors and Assignment.
+                                                              (line  30)
+* elem on DiagArray<T>:                  Constructors and Assignment.
+                                                              (line 120)
+* eq_constraint_matrix:                  Linear Constraints.  (line  24)
+* eq_constraint_vector:                  Linear Constraints.  (line  27)
+* exponent:                              Matrix Factorizations.
+                                                              (line  39)
+* extract:                               Matrix and Vector Operations.
+                                                              (line  40)
+* fill:                                  Matrix and Vector Operations.
+                                                              (line  25)
+* first:                                 Collocation Weights. (line  46)
+* force_restart:                         Ordinary Differential Equations.
+                                                              (line  44)
+* fourier:                               Matrix and Vector Operations.
+                                                              (line  52)
+* function:                              Nonlinear Functions. (line  14)
+* GEPBALANCE:                            Matrix Factorizations.
+                                                              (line  58)
+* gradient_function:                     Objective Functions. (line  18)
+* HESS:                                  Matrix Factorizations.
+                                                              (line  94)
+* hess_matrix:                           Matrix Factorizations.
+                                                              (line 101)
+* ifourier:                              Matrix and Vector Operations.
+                                                              (line  53)
+* imag:                                  Matrix and Vector Operations.
+                                                              (line 444)
+* inc:                                   Ranges.              (line  14)
+* IndefQuad:                             Quadrature.          (line  46)
+* ineq_constraint_matrix:                Linear Constraints.  (line  25)
+* ineq_constraint_vector:                Linear Constraints.  (line  28)
+* init <1>:                              Ordinary Differential Equations.
+                                                              (line  12)
+* init <2>:                              Quadrature.          (line  21)
+* init:                                  Nonlinear Equations. (line  12)
+* initial_step_size:                     Ordinary Differential Equations.
+                                                              (line  29)
+* initialize <1>:                        Differential Algebraic Equations.
+                                                              (line  15)
+* initialize:                            Ordinary Differential Equations.
+                                                              (line  46)
+* insert:                                Matrix and Vector Operations.
+                                                              (line  20)
+* integrate <1>:                         Differential Algebraic Equations.
+                                                              (line  19)
+* integrate <2>:                         Ordinary Differential Equations.
+                                                              (line  52)
+* integrate:                             Quadrature.          (line  10)
+* inverse:                               Matrix and Vector Operations.
+                                                              (line  48)
+* jacobian_function:                     Nonlinear Functions. (line  18)
+* L:                                     Matrix Factorizations.
+                                                              (line 189)
+* left:                                  Collocation Weights. (line  35)
+* left_balancing_matrix:                 Matrix Factorizations.
+                                                              (line  67)
+* left_included:                         Collocation Weights. (line  32)
+* left_singular_matrix:                  Matrix Factorizations.
+                                                              (line 150)
+* length on Array<T>:                    Constructors and Assignment.
+                                                              (line  27)
+* limit:                                 Ranges.              (line  13)
+* LinConst:                              Linear Constraints.  (line   7)
+* lower_bound:                           Bounds.              (line  16)
+* lower_bounds:                          Bounds.              (line  19)
+* lssolve:                               Matrix and Vector Operations.
+                                                              (line  79)
+* LU:                                    Matrix Factorizations.
+                                                              (line 183)
+* map:                                   Matrix and Vector Operations.
+                                                              (line 141)
+* Matrix:                                Matrix and Vector Operations.
+                                                              (line   7)
+* max <1>:                               Ranges.              (line  23)
+* max:                                   Matrix and Vector Operations.
+                                                              (line 235)
+* maximum_step_size:                     Ordinary Differential Equations.
+                                                              (line  30)
+* min <1>:                               Ranges.              (line  22)
+* min:                                   Matrix and Vector Operations.
+                                                              (line 234)
+* minimize <1>:                          Nonlinear Programming.
+                                                              (line  28)
+* minimize:                              Quadratic Programming.
+                                                              (line  22)
+* minimum_step_size:                     Ordinary Differential Equations.
+                                                              (line  31)
+* ncol:                                  Collocation Weights. (line  30)
+* nelem:                                 Ranges.              (line  20)
+* NLConst:                               Nonlinear Constraints.
+                                                              (line   7)
+* NLEqn:                                 Nonlinear Equations. (line  22)
+* NLEqn_options:                         Nonlinear Equations. (line   7)
+* NLFunc:                                Nonlinear Functions. (line   7)
+* NLP:                                   Nonlinear Programming.
+                                                              (line   7)
+* Objective:                             Objective Functions. (line   7)
+* objective_function:                    Objective Functions. (line  14)
+* ODE:                                   Ordinary Differential Equations.
+                                                              (line  34)
+* ODE_options:                           Ordinary Differential Equations.
+                                                              (line   7)
+* operator !:                            Matrix and Vector Operations.
+                                                              (line 105)
+* operator !=:                           Matrix and Vector Operations.
+                                                              (line  18)
+* operator () on Array2<T>:              Constructors and Assignment.
+                                                              (line  79)
+* operator () on Array3<T>:              Constructors and Assignment.
+                                                              (line  98)
+* operator () on Array<T>:               Constructors and Assignment.
+                                                              (line  36)
+* operator () on DiagArray<T>:           Constructors and Assignment.
+                                                              (line 123)
+* operator * <1>:                        Matrix and Vector Operations.
+                                                              (line 109)
+* operator *:                            Constructors and Assignment.
+                                                              (line 138)
+* operator + <1>:                        Matrix and Vector Operations.
+                                                              (line 107)
+* operator +:                            Constructors and Assignment.
+                                                              (line 136)
+* operator +=:                           Matrix and Vector Operations.
+                                                              (line  99)
+* operator - <1>:                        Matrix and Vector Operations.
+                                                              (line 108)
+* operator -:                            Constructors and Assignment.
+                                                              (line 137)
+* operator -=:                           Matrix and Vector Operations.
+                                                              (line 100)
+* operator / <1>:                        Matrix and Vector Operations.
+                                                              (line 110)
+* operator /:                            Constructors and Assignment.
+                                                              (line 139)
+* operator << <1>:                       Collocation Weights. (line  49)
+* operator << <2>:                       Linear Constraints.  (line  30)
+* operator << <3>:                       Bounds.              (line  38)
+* operator << <4>:                       Ranges.              (line  27)
+* operator << <5>:                       Matrix Factorizations.
+                                                              (line  16)
+* operator <<:                           Matrix and Vector Operations.
+                                                              (line 168)
+* operator = <1>:                        Ordinary Differential Equations.
+                                                              (line  10)
+* operator = <2>:                        Collocation Weights. (line  14)
+* operator = <3>:                        Quadrature.          (line  19)
+* operator = <4>:                        Nonlinear Programming.
+                                                              (line  24)
+* operator = <5>:                        Nonlinear Constraints.
+                                                              (line  13)
+* operator = <6>:                        Linear Constraints.  (line  16)
+* operator = <7>:                        Bounds.              (line  12)
+* operator = <8>:                        Objective Functions. (line  12)
+* operator = <9>:                        Nonlinear Equations. (line  10)
+* operator = <10>:                       Nonlinear Functions. (line  12)
+* operator = <11>:                       Matrix Factorizations.
+                                                              (line  11)
+* operator =:                            Matrix and Vector Operations.
+                                                              (line  15)
+* operator = on Array2<T>:               Constructors and Assignment.
+                                                              (line  67)
+* operator = on Array3<T>:               Constructors and Assignment.
+                                                              (line  89)
+* operator = on Array<T>:                Constructors and Assignment.
+                                                              (line  21)
+* operator = on DiagArray<T>&:           Constructors and Assignment.
+                                                              (line 111)
+* operator ==:                           Matrix and Vector Operations.
+                                                              (line  17)
+* operator >> <1>:                       Ranges.              (line  28)
+* operator >>:                           Matrix and Vector Operations.
+                                                              (line 169)
+* P:                                     Matrix Factorizations.
+                                                              (line 191)
+* print_range:                           Ranges.              (line  30)
+* prod:                                  Matrix and Vector Operations.
+                                                              (line 149)
+* product <1>:                           Matrix and Vector Operations.
+                                                              (line 138)
+* product:                               Constructors and Assignment.
+                                                              (line 153)
+* Q:                                     Matrix Factorizations.
+                                                              (line 213)
+* QP:                                    Quadratic Programming.
+                                                              (line   7)
+* QR:                                    Matrix Factorizations.
+                                                              (line 207)
+* quad:                                  Collocation Weights. (line  43)
+* Quad:                                  Quadrature.          (line   7)
+* Quad_options:                          Quadrature.          (line  16)
+* quad_weights:                          Collocation Weights. (line  44)
+* quotient <1>:                          Matrix and Vector Operations.
+                                                              (line 139)
+* quotient:                              Constructors and Assignment.
+                                                              (line 154)
+* R:                                     Matrix Factorizations.
+                                                              (line 214)
+* Range:                                 Ranges.              (line   7)
+* real:                                  Matrix and Vector Operations.
+                                                              (line 443)
+* relative_tolerance <1>:                Ordinary Differential Equations.
+                                                              (line  32)
+* relative_tolerance:                    Quadrature.          (line  32)
+* resize <1>:                            Collocation Weights. (line  16)
+* resize <2>:                            Linear Constraints.  (line  18)
+* resize <3>:                            Bounds.              (line  14)
+* resize:                                Nonlinear Equations. (line  28)
+* resize on Array2<T>:                   Constructors and Assignment.
+                                                              (line  81)
+* resize on Array3<T>:                   Constructors and Assignment.
+                                                              (line 100)
+* resize on Array<T>:                    Constructors and Assignment.
+                                                              (line  51)
+* resize on DiagArray<T>:                Constructors and Assignment.
+                                                              (line 125)
+* right:                                 Collocation Weights. (line  36)
+* right_balancing_matrix:                Matrix Factorizations.
+                                                              (line  68)
+* right_included:                        Collocation Weights. (line  33)
+* right_singular_matrix:                 Matrix Factorizations.
+                                                              (line 151)
+* roots:                                 Collocation Weights. (line  42)
+* row:                                   Matrix and Vector Operations.
+                                                              (line  42)
+* row_max:                               Matrix and Vector Operations.
+                                                              (line 159)
+* row_max_loc:                           Matrix and Vector Operations.
+                                                              (line 160)
+* row_min:                               Matrix and Vector Operations.
+                                                              (line 156)
+* row_min_loc:                           Matrix and Vector Operations.
+                                                              (line 157)
+* rows on Array2<T>:                     Constructors and Assignment.
+                                                              (line  70)
+* rows on DiagArray<T>:                  Constructors and Assignment.
+                                                              (line 114)
+* RowVector:                             Matrix and Vector Operations.
+                                                              (line 239)
+* SCHUR:                                 Matrix Factorizations.
+                                                              (line 118)
+* schur_matrix:                          Matrix Factorizations.
+                                                              (line 125)
+* second:                                Collocation Weights. (line  47)
+* set_absolute_tolerance <1>:            Ordinary Differential Equations.
+                                                              (line  18)
+* set_absolute_tolerance:                Quadrature.          (line  27)
+* set_alpha:                             Collocation Weights. (line  27)
+* set_base:                              Ranges.              (line  16)
+* set_beta:                              Collocation Weights. (line  28)
+* set_bound:                             Bounds.              (line  24)
+* set_bounds:                            Bounds.              (line  26)
+* set_constraint_matrix:                 Linear Constraints.  (line  22)
+* set_default_options <1>:               Ordinary Differential Equations.
+                                                              (line  16)
+* set_default_options <2>:               Quadrature.          (line  25)
+* set_default_options:                   Nonlinear Equations. (line  16)
+* set_function:                          Nonlinear Functions. (line  16)
+* set_gradient_function:                 Objective Functions. (line  20)
+* set_inc:                               Ranges.              (line  18)
+* set_initial_step_size:                 Ordinary Differential Equations.
+                                                              (line  20)
+* set_jacobian_function:                 Nonlinear Functions. (line  20)
+* set_left:                              Collocation Weights. (line  24)
+* set_limit:                             Ranges.              (line  17)
+* set_lower_bound:                       Bounds.              (line  29)
+* set_lower_bounds:                      Bounds.              (line  32)
+* set_maximum_step_size:                 Ordinary Differential Equations.
+                                                              (line  22)
+* set_minimum_step_size:                 Ordinary Differential Equations.
+                                                              (line  24)
+* set_objective_function:                Objective Functions. (line  16)
+* set_relative_tolerance <1>:            Ordinary Differential Equations.
+                                                              (line  26)
+* set_relative_tolerance:                Quadrature.          (line  29)
+* set_right:                             Collocation Weights. (line  25)
+* set_states:                            Nonlinear Equations. (line  30)
+* set_stop_time:                         Ordinary Differential Equations.
+                                                              (line  48)
+* set_tolerance:                         Nonlinear Equations. (line  18)
+* set_upper_bound:                       Bounds.              (line  30)
+* set_upper_bounds:                      Bounds.              (line  33)
+* singular_values:                       Matrix Factorizations.
+                                                              (line 149)
+* size <1>:                              Ordinary Differential Equations.
+                                                              (line  38)
+* size <2>:                              Nonlinear Programming.
+                                                              (line  26)
+* size <3>:                              Bounds.              (line  22)
+* size:                                  Nonlinear Equations. (line  34)
+* solve <1>:                             Nonlinear Equations. (line  36)
+* solve:                                 Matrix and Vector Operations.
+                                                              (line  59)
+* sort:                                  Ranges.              (line  25)
+* stack:                                 Matrix and Vector Operations.
+                                                              (line  33)
+* state:                                 Ordinary Differential Equations.
+                                                              (line  40)
+* states:                                Nonlinear Equations. (line  32)
+* sum:                                   Matrix and Vector Operations.
+                                                              (line 150)
+* sumsq:                                 Matrix and Vector Operations.
+                                                              (line 151)
+* SVD:                                   Matrix Factorizations.
+                                                              (line 142)
+* time:                                  Ordinary Differential Equations.
+                                                              (line  42)
+* tolerance:                             Nonlinear Equations. (line  20)
+* transpose:                             Matrix and Vector Operations.
+                                                              (line  38)
+* U:                                     Matrix Factorizations.
+                                                              (line 190)
+* unitary_hess_matrix:                   Matrix Factorizations.
+                                                              (line 102)
+* unitary_matrix:                        Matrix Factorizations.
+                                                              (line 126)
+* upper_bound:                           Bounds.              (line  17)
+* upper_bounds:                          Bounds.              (line  20)
+* value:                                 Matrix Factorizations.
+                                                              (line  40)
+* value_will_overflow:                   Matrix Factorizations.
+                                                              (line  35)
+* value_will_underflow:                  Matrix Factorizations.
+                                                              (line  36)
+* width:                                 Collocation Weights. (line  37)
+* xelem on Array<T>:                     Constructors and Assignment.
+                                                              (line  46)
+
+
+
+Tag Table:
+Node: Top776
+Node: Acknowledgements1787
+Node: Contributors2003
+Node: Copying2303
+Node: Introduction39855
+Node: Arrays40106
+Node: Constructors and Assignment40274
+Node: Matrix and Vector Operations48616
+Node: Matrix Factorizations80162
+Node: Ranges86531
+Node: Nonlinear Functions87229
+Node: Nonlinear Equations87777
+Node: Optimization88712
+Node: Objective Functions88991
+Node: Bounds89588
+Node: Linear Constraints90703
+Node: Nonlinear Constraints91696
+Node: Quadratic Programming92093
+Node: Nonlinear Programming93705
+Node: Quadrature95243
+Node: Collocation Weights96950
+Node: Ordinary Differential Equations98249
+Node: Differential Algebraic Equations99790
+Node: Error Handling100596
+Node: Installation100752
+Node: Bugs100876
+Node: Concept Index100983
+Node: Function Index104347
+
+End Tag Table
diff --git a/doc/liboctave/liboctave.pdf b/doc/liboctave/liboctave.pdf
new file mode 100644
index 0000000..2f4b02f
Binary files /dev/null and b/doc/liboctave/liboctave.pdf differ
diff --git a/doc/liboctave/liboctave.ps b/doc/liboctave/liboctave.ps
new file mode 100644
index 0000000..5fc8698
--- /dev/null
+++ b/doc/liboctave/liboctave.ps
@@ -0,0 +1,7578 @@
+%!PS-Adobe-2.0
+%%Creator: dvips(k) 5.96 Copyright 2005 Radical Eye Software
+%%Title: liboctave.dvi
+%%CreationDate: Mon Jan 18 14:18:26 2010
+%%Pages: 56
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 612 792
+%%DocumentFonts: CMR10 CMBX12 CMTT12 CMSY10 CMTT10 CMMI12 CMMI10
+%%+ CMSLTT10 CMTT9 CMSS10 CMSL10 CMB10 CMR9 CMMI9
+%%DocumentPaperSizes: Letter
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips -o liboctave.ps liboctave.dvi
+%DVIPSParameters: dpi=600
+%DVIPSSource:  TeX output 2010.01.18:1418
+%%BeginProcSet: tex.pro 0 0
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S
+/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy
+setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask
+restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
+/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{A length product length le{A length product exch 0
+exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
+end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
+grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
+imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
+exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
+fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
+delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
+B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
+p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
+rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+%%BeginProcSet: texps.pro 0 0
+%!
+TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
+index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0
+ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{
+pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get
+div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type
+/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end
+definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
+sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
+mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
+exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
+forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
+end
+
+%%EndProcSet
+%%BeginFont: CMMI9
+%!PS-AdobeFont-1.1: CMMI9 1.100
+%%CreationDate: 1996 Jul 23 07:53:55
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI9) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI9 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 58 /period put
+readonly def
+/FontBBox{-29 -250 1075 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D6F5CA5FED4F9AC9ADE41E04F9FC52E758C9F45A92BED935
+86F9CFDB57732045913A6422AD4206418610C81D882EE493DE9523CC1BFE1505
+DD1390B19BC1947A01B93BC668BE9B2A0E69A968554239B88C00AF9FBDF09CCD
+67D3B2094C11A04762FE8CC1E91D020A28B3C122D24BEAACF82313F4604F2FEF
+6E176D730A879BE45DD0D4996EF0247AEB1CA0AB08FF374D99F06D47B36F9554
+FAD9A2D3CE451B7791C3709D8A1DDDEFBD840C1B42AB824D5A0DFF0E0F15B0B7
+22AEEB877FF489581DA6FA8DA64944555101EB16F7AB0B717E148B7B98D8DBFD
+730C52937E226545CF8DC3E07C5BA30739BAFCD0F2B44275A6D503F582C0FB4F
+449963D0AD2FAFDE33BA3D77BCA9D1DF878DDAFCA2E22CC4BACD542B282164C7
+97C2BDE318AF9D501CA21F6E662E7AAB75A5F24D2C182E598D175D44E88AB19A
+E7CD59584F95B389183EE21B525BF52A3F23C0FE5383A5565A19361D716F508C
+AAB78411CA5A4D27552CC1C435760D5A89D535B71C593E755C616661363308DA
+A683F54ED0C23FB2C225A008392B0B719F66F11A946A090B7C00B662A3C69599
+B4ECB0CC70C85C4BBBF207E0026F6C7A19F2ACFB7A60804FC98A4BFFD7BFFF2B
+9529E6D9D4238002BBC255BC62959D6F3381FE06E0621B879D5FE5B541D45A1E
+759A6E7DC32B1D1632368D09A97039DF255B6492B1B2B7E2C1434E8306ECA7D3
+5A79B6D614B4979F10988BC76ED53A5F45315CD7DA216221F842FD0F3E050DD2
+BAC23C984D506D8F7D614BCB6B244F5F41321549BB0BD041FBF3053307168680
+3435E9C9445A59A7C666418C4F2512C32058B1CE1EA46C7839C6E372F6CC60AE
+2CF46DD2F130B532DE8ECD42D9204500E413799E298CF6426F28D23BB7216BEA
+1A618B3ECC61B44DDEF0BB22D640B47C09AC0DF378CE68FC9CD88BDAE9ED89CB
+431A5CF9C3E9528FEE7A9936C2B1CF7B38DD2B95773F0EA0051607BE1B0B3588
+A8B907A5EF011B4622C5093A7B107DD1EED6FEE9536DECF1CC96E65373D0F433
+30AE3C094654ABF4698C07F8C74E71D023DFD242EE83B1306786124DD8C6BFA7
+801E66CB944BE7EBCB3FE803EC97067AF7AFC8A4E9AC9D11
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR9
+%!PS-AdobeFont-1.1: CMR9 1.0
+%%CreationDate: 1991 Aug 20 16:39:59
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR9) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR9 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 44 /comma put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 65 /A put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 76 /L put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-39 -250 1036 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FADB679CF58BAFDD3E51DFDD314B91A605515D729EE20C42505FD4E0835
+3C9D365B14C003BC6DD352F0228A8C161F172D2551CD1C67CD0B1B21DED53203
+046FAFF9B1129167921DD82C5964F9DDDFE0D2686875BD075FC81831A941F20E
+C5CD90040A092E559F6D1D3B0E9BB71733595AE0EA6093F986377A96060BF12A
+A1B525CD9FA741FE051DD54A32BECD55A868DD63119A4370F8322CCBEC889BC2
+A723CB4015FC4AA90AE873EA14DE13382CA9CF0D8DFB65F0ABEDFD9A64BB3F4D
+731E2E1C9A1789228FF44116230A70C339C9819676022AB31B5C9C589AE9094B
+09882051AD4637C1710D93E8DD117B4E7B478493B91EA6306FDB3FA6D738AAB1
+49FBB21A00AC2A999C21445DE3177F21D8B6AAB33869C882613EA6B5EC56476B
+5634181ECBF03BFEDB57F079EACE3B334F6F384BDF9D70AEBD592C8ECF21378B
+54A8B5DBF7CB9282E16AA517E14843909339B5E7C55B038BF3BB493F3B884A1C
+C25F9E8FB912CBE23199AD9D2C3E573727701BA301526C66C3617B9514D6F11F
+11930B1D97C17816C85B1BFD9B973A191B33CC3B391815AD14F1CBE935942AEC
+D4004E6BEF379066FD72209DC88D2E634E79BCC2B98C766CBD92C561F2703F8A
+109E6C6CEC7B866F2FC7ADF646BF492E520319F3B949AB5D84AE990B33344A40
+3971F58DFDF8D8D67FA0B8F2A0D884F8C09A5A721319B911DBA0A35903877343
+C37BC36C5EB32353272D1E6ED5FCA611BE319A7E1E842CB7576E7A694353ED94
+A49960B6644458162568E61E1ABDD135BA31CEB5F8327642DBCCEF7262C03569
+3E930A9CDDC7776023E849F520D4C14A3F0CE58CEFFAED6610F3F77D1FD94585
+3E107CC709AFF0B608BDC599A43220E881964AD710300D8C394DB6EA33AC8559
+8F64CD722AB782A464F4F61B4FA7810A4119E6587FD00D30DD35630BEE74F7DB
+42B705F656D5D31E3C17BD831FF1A55DB93842BDC5EDB8876936A77FC10381FF
+34F309F2383EF57E689B66B5A70B56633EDE385935B23C6F81FF60F456005E65
+B9EF0905AB311FFAE8A83CCCF658E078E33E56DD02955AA5853D8062E2CA7E15
+57C92ACEA4A5FCCEB0F9C1774B9CED360E2662C66FEC06328A0E43DB7F6DD893
+842624453ED4F29A1B85FC194F7A98795933F444DB747DD0666E662695EFAFD9
+23B85664A70C5EA0D9E0172EF7C09F5BCBA1C363904616C367E136F0E417581D
+193FE2925A3ECEAF8216C8792AEDF998425A677860C2C617D341B980273542B2
+D11BBE1DD2B71CF1C57FAA4D749E7E241BFD7D9CDAE6AF88DFDFAF2A4EC10047
+0FC32199EE51C7244D3A0EF5102592D18241FCABBD9ACF56BB15906FAEDF3593
+C2CF40A27279CD764CDDFE9F29A809335B9DF5075AF9BEE3B1E7EF60121BC9AB
+5583202E4A2230DB6FD15DF1EA00C6BAA6A156CBAF210A65C9D8FE10F837E8B8
+D4427CC3C8D157AEDD7CBD54DAD42B3E4387BFD8D75E85FAECBBC6A96B201CF8
+7228EAE225CF698877FE2C81EE7813C717EDEDB7B0696BE8FD164316F5098E5D
+8A072AEB224A417B2A7BA67640C5D94650A2A21F8DC7870C09471DE18CC6D980
+B2F349ABF3BC27935428A8D34E060EEE6029A2BAB6767160DFBC5EFBB074D7C2
+136FC21FEF1D7D4C8CED2203EB3877CF7E081D29325014DD8A862E5B0670D1C0
+6B21D20F3233147A4FBC7029A57EF3DFFBED575CC66C2AF5B3C4B9B1743A67C5
+39B590FD738B4E661BB4512AEA1420C603B0DFD58E4CFE55E6550F3FFBB5FD8C
+E407E6FF9B43C3E8D80A2E310BB493086CD597A23DAD6D17C47A7CD0915E82C4
+40B233FE6206DAC30854F7E43280E4034DAAA1AF04BA6A4AADACA51FDB053A25
+0D76B438414B6800CA1F48329C383A6F6BF8AAEB264970902EFD6FC416583929
+55C9B2FCE5FE1965098BB20ACF2EC0CD52519DD8BBB31E6978CC40449D236A6D
+C71315316D68B7A8372D7CF1F03F5A2481FCE79D081144ABF8970BE7CF51DBA5
+0A6B29751C51FDF1908567D00AF985148C9E0AAF699AD77F84C75F3C5D40FC80
+E22274FB6B560D1AFB7BE6001C96E3FF9BCF00A9087E4E24BFAAAEB1DD6D00FA
+D221D23F064696320052FDEF211D59B71291066C78DAE10933573F513CEA5918
+4EC4A8DC703624F41D9275DB77BE4E7027E46C76ED73B88CB95AA1DA33796FEA
+F7B87EC7B649C0360D419BE3BE7F700A5DC15A05BF9F9CA7730179E05E9CF6A8
+5FFE24628BFD526BED2A9D2E87F749E4BFFFF16CFF04A1919A041D0350A701CA
+10CE4F576EDEE66B9B48CF26C7582BB9D11C51A57A3320C5788CF70C5D583C05
+DBADA8CCD4C0D8D9CBB93DDFD9300A5B1A3F98E508C1DB9A0259822852BEE217
+6356ACF72EFB0B6933F42D8BF07636043A83A3D0D22B648FD670BC39EF661A76
+EE1DFC43AD571ACA0800E7B4EAF2B12FF264CE4044996011A368B9777FC77D66
+056F257F44C5A9A838FB8DFC05E7F89359F73469AD06984E7328AD01DC0441F4
+26D9720CDA94621A12F427433AD8D8F9B61CBE957D56D7FAFE7D58178AF58F9A
+5524CA825C38C41BD497D6D3F62F0DAAF77F784BE3C7D11052B73A952E8723BE
+5113A9D9765B710E6ECF5775769E05255D9403E2410ACDCA8FD82E46B0274E98
+C6BE7FF31A2C2E81D84310E2CD9B20CE0965A1850862FD719934C1BAB766718B
+6D474C35416C99BB955ABBEDCAA387A43E1B161304A13F5D6DDD1AC7EB9F7041
+D33BB9DD186888E8A35495B21988FF0B0A7D158AB8738D7BCE64AF9140A5908A
+F4FB6CA9813748C936C5285C093C19176EC108D5A37AF5B26B7B125D5C8BFFE6
+AA7D7DFAE0A6AD1B71FF9F42C1ACE22A3EDA4203245042EAAC891496BB4CCE75
+81C55984709AA689CA917AA8FECF8007467116ACF9D197945C8E7017E69434C0
+635FB62C7E13A9D08607D0A95DE1D930569F6338A1CD10EEE44B8E83BF34474B
+0ACAC9A482129A1B8913DE8BFB68D47626ED3E573BDC6ACF2A3B348F757EBEE0
+2F3EB3F81C296F6AA78B105D28309563D6264E70E76A14DD8FE0FFE574A8B3A6
+E53EE63B6D1C9CB97FA900B1AC6E04A4F42A6FBFEE86281C5053CC7490F8CEB8
+2178EAFADD99EA46611BE9A002CC73E303A06009F2712B78820AE0AE8FB30103
+D0BEC3AD98ED72343F72C8DDCAB50DF53BE049B6C914C503C732FA888F765B97
+4D80A0852E0227AEDBEFBF9C4DFA09BD4E8EC0B6279120396F7CD191209C264D
+DA267B49C4EC69D562E85198531A1568FE2EAD305811F28264B8A12526822B53
+549D4145E4EA70BD336617FE2C04EEA5E6311288C57C593E9BF98C1C592D51D4
+C8C7DCDBABCE43A96F57BAA19F8C516D64C3BD4AFC31F80FD8296E1C24C1F677
+234368D6F505F65F35258BEE71E112C50D9D545E9C214793614FB9B0D437B832
+51E1021EB0BAFD8C3263B67928F908AB3E8718944CC7DE8E3A1155A57DE4CA40
+93711B008D2CD1BA569B93C861D0CE6D04396589FAB34D4EE82531E94315A434
+DD6B4DC5722D2FC1578A69468AFD444C903FA03EA948306D7442F074D3C215B2
+18D269C8D78F8B567DCA2A55F01AD9E9884436B66EC4A5BA11A11743BB1D308A
+84E4F10D7E7EE5C74BEE7733837FA7992FAF996B6C0D0B143A5C52BE249227AD
+17A2BE0CA9860BA5E568FC20AFB0B153DA1205726057D52F375692E965BECF8E
+544FBAF6D96BE9C38D8138489FBA13D605405C2C2550E40A92B5438D92A849B1
+E25532EF0B1E42215C92D612997337FD8013D736737185F3745911598363E18A
+FF08C03051BA56154A3B3DB01BAA2BE8A1FF04783ACD2DC70AB9832AF8981096
+01E09A27B6611F04073658042DD7240F4325873205EF5B4D0CAA12535AEA1FAF
+6BF625FBE48841CA27D78456E3E35BABE689DD1C9760D0B3BECFDD724670A61F
+3FED0731E3BCE8F3834669AC2C74E2DCF9FA4D7796C8159B239D49A08097CBDB
+24BBDF1930811E81725505434FA23F86FF45A8C2F35FFAB43F89545D30C8B59C
+A4A2330CCDCC77C3FAB4AAC279F5EFFCA55A9108DA19B26D647E3492C1B2848F
+F584497EA308CAE15DF6E501B8626EF126AA38051840ADACBA4C1B63A3EA151E
+2387CC2B0D8B09E2FE28C73470C06BB5FAB133AD8D7FCAFEA6D0130C9E55781E
+E1EAB6913D618D2EBB6AF8CF3D79094C299D6591068948DA50783E79A9C92F15
+059E5F42719AD9DA2FDC00FC57E93560D92FD1B5918207BCEC5B7752CC1CF97A
+DFA9E7F01DC4C4B7E95040ED954C4ADCAC849CC3A1C93435029B499A0E84C896
+AFCEA53D6879A885038E822473697093CFF55D18BFF8C86A3EED9FCC5B538EE4
+A4BE89FCC9049C6F8292DAA0F51B1609C78B43B5839A9EDE98DC51F4B95ECA06
+FEB0228DD2643FD454CD152822E058EEFAC3F2FFEE1A9A42B66E7DC81FB65A4A
+2026CF4806139B51A6938BF718F6BCD554465069EE2B705B4E7BA053D583EB8D
+E032F695F915A6665768F9539CC2A6C1AAB892188387131E1DAEDA7172BCF8AD
+37D2DCA7143AD1C0DC7AB5C10966012E8829793F654A0755A82C2D2835DF0D37
+59C81A3B0C78F58CE9A1EE11089D8AFA151F3088716BC8C98737F4C0A51BEBF5
+9E38E3F3337629CE3C96AFD84193E049A406BD3EAD4769F4154B358ECE9BC5D5
+1A5D0B0E8E1B1CC8CCCB658F6AD431C43BE792C43C27792003BA6577BA337FD3
+4FF0D406BF85F3D428ADE7328327A0CB404326A872333F86132F18856A08CB6B
+FCDECE8AA9B7737F73148BF84374FDF8E11281ED288E52B7488100074EFA48BA
+103D3F852D1D08B6A170EB3B333925A14D237A0F75AB49D7C8DFAFB97DD364C0
+68F5B9E4EF8A558145A4AE3C2245A78F26A4B1F4848611D3AA4C72C2E3263438
+4B94062B0533B2145D0E92A5F2F86DCBD1DAECF2A58A290BF41352F421EC5564
+AEA5F28A86B7BC477492D519B93AE86B9CE7267297BF9BF347A0B355FABA1CAF
+351811A8E76749009FDB60C4204883E0312146415DE726DD0EA5EBE3F7F613FD
+F847D73B81C05CB5A336874ECEA7B4D8C0E06EC32D969E536B1C9E268E939C36
+374FCF4E2F29A91ACCBC254D3D211FF3632068EB707A5682857A9DB336CA33B1
+2BB9AE622BC001531017D349CF72B1DDA08A28F91247AFB5528CD0914ABD02F8
+C3FAC571852EF348D0FBFD9C1976C8B0E0F9468E433937614D4584B54D1F4502
+75DCE966DB4933259F2F139921B575C1660F06D64DAFCD7B73D45780B5637CB0
+06D460D98530F6EB6F219028C028B8C4D6C1AF9EEFEA61B4258371D3F868FDD4
+3194580D43FD9B61F8F58887FBBC69609B4193F2C0DA646248495B45145DB35F
+71044640FF969AE411DBCB3CEE97D52717797FEDB13BA5E8D97E0567C248E489
+9C337786E34A66CC308D451CF9A51108AFAED1A3912D3C3BFDFF89D130B0012B
+3B53DD7B3E9B9CE32D1722B6AF126D491AECA90BB4FC06488AD08D6609732960
+A3FFA54ACFB2C3BDE98987BAE1B1DF39DC908B8CE974D9465BAEF68385059721
+A5E8900048091552B4805E98E9555033CC6699D5F5A2EF6FDA2E76F2027FF2FD
+EFE78B58E4F1684BBC9926FD91AFDDEFE601DD9A069E9D344A3BDB2B5F836BFA
+5CAECEDB85AEC0934FC5B0919B791E7AC0BB43F8A210A6C0B3CA3E45DCC6E7CD
+A6CF33E5889267307595D23709344D1FE536F4E8951AE5F6BBFDC555077D529A
+6EF1FDC542B07DB08AEF8ABB089B23410022AAA8A76BE62BA4A4B95372E5791D
+1D6B8C045714C778C42EE5B234EA22CE9CFC06F13D3D68C64DB03E35EC071AF0
+6D031F72CD0A2CDAC04AFC436D8E32F155137C3F1FF1AC1F66CB6C65A3DD5F79
+558EFF0B0BF02329BC29E628235468EAC249E35016CAFEE7802E182607278854
+0BA52A110CA7FF61A6142B89DE1B35B4D33A79886AA7E7A6AE2943AEE48A5F37
+FBBDE663D9A8E4A7DBCC0676ECF3EDD2C0B3B176587F7F75CF079718C1B512D9
+F273F4F343598F7549203B5C41556EFF3E317B83CD673DECFA3183F8B7000835
+1604DA6AD0F30653CDCDF69786BE24FCEED1EB29AB7397FDA71A8EE43CC41581
+8D31739225D487FECA8016F48EF8B7EF3576C12B95456DBB56D8F7867A8C1F38
+84A9E7E777BD02A90AEE77C68DE1FA6DD31A29FB24720D4EC861F7EECAAF73B6
+00AC9C89A11E8872FD36B3DF404B73181A8736ACBA2F0B94BA2B68F5548198B3
+9773948E142D2354A1EF2D9F5B019791BE127E7E5E4E9EB214EF64B11CF644DC
+448F63FB3035794543076A81F1061092C61569E27355F93F52F116D04ED52809
+0E118D96CE4266895F6BB9E387ECBE4EB04B5D45F82CD8CABEA1086268821559
+AEA7609D453619D1EDE45A663F5193A8CC6F0EBFA058ED232D1F109C8435E19B
+55188D44FDBA0CC85F5D3B3A2FB70B5D10E96B1B5225EF64FF22073B389DEF7B
+A95E243F606FD4C6C74DDC7F9192309EE6DC91E6470A054B09EE1F41225C54A7
+5F6F0CA10E6192477DB590438D1E6A684157AE4BA775D857BAF1C906C457738B
+135C721BFB2BD6BE724E3BD93DE2780D1ACA437EC9780518ACC9D28C2A6E52E4
+1B9D121CFDE456A1292F1708AEC4BE71C237C73698E88E7225298F439C640700
+13A9D2B5643D672E840EC6792CFC8CDDF73F3234D143EAD6AC6AD07106FC9395
+C1D4433F8C106426FF9DCC9123B6B506E5E48B2C317B251BF73D60B28C63BEEC
+D37FFD3C3EEECD21C05758C1ECE9B19626C9D42C4C9A1AEF37A78576D5EB8BA4
+A0A57455AF2F671E2529B4CCE17DD0570B764C2D1C42F032C1B1503C156C266C
+55A43F065AD33C5B07E18FBC7759E5B38A9E9E8DE29F0EAA232524D667A0FA4B
+E4B4A0E33875BA2B421F84A0A5525C72989D87DCB42453180ADF9A3D894F3609
+1BF6905C302DDB7A073F75B3F6F3952EA01C169DB55271D23F6E8E041B0A248B
+79D22DEF65DE6FF06C6C9A7125A248EDE698C1675ED3137C43C3F293473336ED
+27EC00705E6CBE3E4C12CACF772BA9F2850607E1F6CB9CB0616B9DB124A4A10F
+ACCD5381AD5209AE1BBCE0C6C3FC02AC74D028561E82A59FFE767469409B9D6C
+9458AB86A9824B0CA62575AB5EC18D91D959F0CA7F998948C0C5A23AA75D2EBD
+A0BC8B1A3D4C0D7A283789FAEAF9D5D6AA44D90EC0F4E72CF2983EA6E7A9D3A4
+06657812D4E5B7FB69D1F4097B1723B878272BB6648035CD1A688E511CEAB001
+25204C2B6EF0A4D060DC3B86559078B54C94DFF7A5154671192AA9C5E6AB372A
+831CF6EC2B285B9C9824C36C8FE3A99D7917BECB7E151A621BF4F8D1BB6AD7CE
+1F91B60D1337AF19946E918534892AF0CEA404AE44D101FCD7077575A86D81B3
+ED7A9F22ABE4C6CC6436E51F75C3A670F6E1D2553B7D754A0B9B89C87D445B48
+D30D51AF0EDF1B71F8419D28EF2F6BBECE78BDBE36D89534AC394BFFD2AA2AFA
+A34A658BFEDA52E34407CF17444E69D3C0D819C5BDDD136C2F6417BE2725BA2F
+1CCD5CADB57BF36FAFD0F2DEE7E2A4FA373828BFCF9AF4A9CA2AC899FFBC0E97
+C454ACFB5A9C6E93C42027FA9090192F7380026A6A39E782DD90FE07F3FBDD61
+4F3320D1E762E41C5CB50AB6977781C33BC724E8B57FA3E5546418CFEB4A5A45
+CD83BA01B1BE83FCCED71B3626A6BD18179AA2444F01A359EBB35F87903E67EC
+C9AB23F5A8D56FA0078E2086EAC54B80462AA6C7172BC5AC2E51F4E6C8033A2A
+647A1FF766E26D422FC39F1C5755AC957AA3BA086BB5AD266B01E0631FD380A7
+CFB2BBBBC360E189B94FC02BB8669462B18D1A2CB17657B45703AD1E553252E9
+12929004F579A87D87B0A42534BB32D1EF434F897A7537A4CEB8A7B25DBCDDD5
+8B4E24C8AE07DDB67D695514AEC79AC7D8850DD4404C327EACF0DE4B79D9F9C7
+0AA445A4EE0BD869743E40E3DD5D6189FBBD7FC771CB79A2E65F5E32792D2A95
+342C623A8F9CE4599DD925C52B595C9BCA5B5B6CA44716EF845D8A2542581FC0
+83544178532D51D92F3F02F343FF3DD05ECF87B928700E7A97FC0DD3FEFC11D6
+37EDD87C3BDDC8C4AD3B1C0B366E22C31F214F700D53F9BC6F9EE533F78BA957
+06F0B3F16CEFA50A6EDED147358C129469EC44D6B74F95C2E69AE06E91AB2C19
+FB4B03035051BBE5D46379189189E6F4C2D1A72DF8CD54CEB366D1B46FF1BBF3
+3CD1359B6A10192E9BF9932567395F06CC5276217C6C3AC98C6BD82244707838
+6A6FF2A0BBE52D1416C72228C30AA945BF2FC70FEE45FBE9F5F2B983E400910C
+C3939455AEE8849A5AD307AC290A59F37258CFAC8FBE2CC2823B773753B03CBB
+1DDFDE15E746AE84FA7CE2560E4D786C0F571174880274AED3482E3B28CC5277
+55CEA9A31D4607A0C384CC4E8FAC4721BA3A90D367EB2D4AE09A17131D9B4C84
+2390A444F19EEDE9B1745D99F333EE836CF57415F0FE0F0580991362545BDCE6
+CF0831B45CE07E88916065BC37FCFB57141184271BF19EEC9CD8F798EFD7ABFA
+7332AAF507333D187889DC91F3D3526F9EB879EB4D0F02FBD8D69E828E4927D9
+52682301A76F7508BA37E5E17AC459413C8741257C3B4F5CBDA63BE18B2506F6
+60D0362D35AE2805508657CCDE6059575E5DBD543E1DDBA428B33B05962BFC99
+E1AE356443CDFB83DC129F2D4CE75A1C9A95B98FBB1575C62C4372C805EB2470
+E06C653C5034E7776C1B6D6C84881BD7860A4069AC056BB785631456BB56B237
+249CFAB9F67B5AD05752288B6F9A4151A44F30320E81C663460B40F5367697BC
+5E33A0FF3C7A8BF5666F9974310C93E81C5D4799CE4ACF814B160A75D04DEC21
+69E2B7EE8D790516996DD153625ABBE8CAF80E9055501D8EF78635878A041BA0
+FB15F415309836442126F0DA25C5EBAB971F1EC98BC36BB46CC05E048C192B76
+1F5857B63A1AD57AB189B378C73ADC7620782185CF34BB7BFFBBA9C8E92E5DDC
+F61A3F911E0A8AD2A42E123EE670DF21B18FC008AB3C6BB21638829E08EEBB6F
+AE60BF0CAC37C56E1CA24C6C27030B18AD4F946215CA281C4BB4A781BD4AB324
+23903E09A2FC97ED74519F4FA3B9D1E4C5D3EFD62B40BF75A2BAFE5BA9DAB1CA
+D36D46F02966969F54091E9F223915A7024BAF966A003891CB9349EF816893F1
+24584FE0353E73B8212B0425976C188811389D97DEBB70851ED78D05A47D16C5
+350C053D296508367B8F55ED916773609A2A3221E3423946DD9BBC340C3517AD
+F21C070FBFBCF4513B8D47C578712BB84978FDE7AD7F4802FDEAEE4E412C7C2E
+AD9728E39A5474AF8D5349EDEC61CAE931EA72601959398B20FBDF6930891658
+887CFCE2E697A1E8160683DC5FF5BEA27159016F49DDD0B9CF2BD2D9ECFC61DE
+1094C9BF3127153F8A650A74EDCC592D648AFD0FAA0F49AEE760A78568DE2793
+C7F8E5FE3A01B0AD473E010E989BC898054A284495EFDEE6B73AC1F268995630
+935F8BFBEEC75094FB21FBEE1A664DB11F3E62C98F1598CE7F8DD6893B22A525
+BB4FD410A9E2F7FAC711CBB21B27288C3D9CA84759DA080EC998F80D18472F02
+22EF2545FC637F7A04126BC850159EE04A4F8F0779EDC5DAC8BCB2AF531E5BC3
+D35A8FE535E9FF040F31FA3D7754347AD3E3FCEF10DFA9DD61EE4FAA9CA8F98E
+DF5F2653A316DB3382708257FBF77207D49DD48A0FC6CFFD7C04329D00E5EE94
+EF1545FF6D098A5C121B71EFA91C9DB9C2CB79F7D77147B631D341E9DDBB4E2C
+9DBD2386F7E60FED30118D8A6A4E736B7FEDC3F651F81910529F919ECF768C75
+04C763E7E0D3FE850CFA9D4DAEC9A39FCB808E6B21C9836AF75369D76E478DF9
+8EBA506924546C7877C88D9B9CBBF52A41B71DC6D462B354DA0BF887B2013A89
+E9090CD98EF2FDA25371FB2FF839B908BDF592F3F1737699B0467265E8862C18
+7376A23BF3180B2383D3B31928EBB5468D7E0026139502620645B5BC30BC610B
+A5FEA9E88B0DCF2BDCB2FF19352B802B7B0899A854501A55CF469A5F2030B553
+DCC895074F8008FCEFE1CED45E089D73FE7A6AEF26D696874177B04CA59DAFFA
+44657DCEB79F4F440BC514C046CDD4386AE0919FFFAFC478ACF7FE18EAF0D77A
+2EABE14AC37A59564695CEAAAB26824B0DE2B115289E675291C4420650ACF36C
+C5EAE3D57EC28E3C853F41C31D0331B4969E3300232809891C308361FC8CC91F
+38732E28C93CA574BEAFD32474401F377ED463AFCE30946CD18A6B4AF509166C
+E5B002EE63287B53FB637D965307DFE93E04EC503EDE04BE285B9DE62C9CF0D5
+5C1A991B9AF164BF28435D6A069894E2F59E8B8BA8B12F558B2CC5449D727E8C
+FEFA3B9A97784EEA091C8F037107E30EBDB41118169CFF725D76D05317C5974E
+4C242421865F64045237C2B33F4D42205A896B3F0D1FD6AFC373FAE3A811E4FD
+524053065146BDFE932B6B2A7019C217E11E3CF0660B51E1F84571941EE4AD42
+C8C50EFBB3986DBCBF2162FF04DE9A1F06985D09AC0B38F5260AB019AAFCC0FA
+147A33ED86A0DCC0A32FC81C48F70166580EA6C95B352290BAB5330CB921EA48
+4D942095F36641D457A09605414E3300A13E5D3AA37A3C8DC6ABF28306F74957
+8A6FCB0FCC6EDF628416EC7EE2EA4E815990103511030D44BFDE9C417B70CF84
+457C5648C2A38EE25CC6804D61932CD0A209B701F7A8B4AE5FA0F2B292BE0EE5
+DE08D13BF24BE0C05C9012963F1FDD97E3EA233BE13E01410DAEB2A99E25C8E5
+DCC7CAA9E9F77ADAE2CA20268A6E11235516781D75C71D03303C10B5072BCBE8
+B6875EEA05167A2283E9B0E6B9F3E0041F3F9D5B36F45A519B5A59A4F3660AF2
+814D601EF4A27678C3B2A78337C981192E9C30D63CAE4DA4BEE07CB9A0ED72A3
+682E85790CAE710F16A753E547228C8F6070D5ADEDF5DDD003C858E77A812FF7
+358C5857761777A17E6DB67BF0B8B25C8F2E278BE5ADB3F98288475BC7315723
+97787CC20A535553CADE67271D543746258E3E7F944214108BD7AC7B5F36D119
+D2DF593DF70F50BAE81FCF0109E6A5F54453DA16A576D8FC160DF0A8A93D7647
+B272FB1CF8D9431E6410D9E04132D161DED70CBC38842E6D9976DF711E834BFF
+499F21081B9D7580815631E05DC4705A65CCFBDD832FCE57188607F982DD0A9C
+A25D1F5F4D7A7378A9CBF8B2C962C05B5A834AD93C09C91C8DF7A6BD3ADC6EC8
+8D2A81466646F8729B79D66C561D37D09D66493BFCC63A59F9E52785DB24EB58
+21D5F96162EC7455ACD4CB7DF03A4306C3BE46DC85610CA9347EDBE385897407
+5EF6B715FA488B0D8CAA3B437F469E23BE941FC4A10AC96F66B8D3D86F367CC2
+4843BEEA6EF35572B8A80E8DA97BF341F58FF44D2B09907AA623FC961241EA45
+E4017514BC66FBBE4E006F8F27E639651AC3F51C2D099B7A27DE24567E966317
+5A425B521B6D953036E89B3359103B1BB056
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMB10
+%!PS-AdobeFont-1.1: CMB10 1.0
+%%CreationDate: 1991 Aug 20 16:34:36
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMB10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMB10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 91 /bracketleft put
+dup 93 /bracketright put
+readonly def
+/FontBBox{-62 -250 1011 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8B731A88D7740B0DDAED1B3F82
+7DB9DFB4372D3935C286E39EE7AC9FB6A9B5CE4D2FAE1BC0E55AE02BFC464378
+77B9F65C23E3BAB41EFAE344DDC9AB1B3CCBC0618290D83DC756F9D5BEFECB18
+2DB0E39996C010F3024A5A3C69C8485664A4E3AA81348AE21A30280D0E3B6542
+A770F048F31907891EAB8B57DC70FF775574D6CD26B8AC9C3E64C3631325BF0A
+99AB413BDADAA3B51A3E168B03A856EC7D346A38BBB0A2700A23B2CA91120B9D
+2AA5BE5A359C60CD78F055253785CC9701F5D670ABE4967D74838C3B267C6563
+C9651AC41D8684AD5E913A5C9C547CA225A74782D1AC62020FC38E29C356950A
+00E8F2B0752CDBF81EE4ACD59BDEBBB9523AE4764B995855F3A401EB4B04EE56
+B10758196CB661448A3617B83CA88C41756EF131CFCE0C968B94B6C69AEC1E9F
+BF8B21837BC422D766B5089D81CF35A807394A026FE3160580695B1213968D90
+8ECD1611E719A871E15C6085A17906F77B5B2DFA6AE670976758E67F8A4FC362
+FC7299D85ECC3C0BBAD4649B9DAB4A2FB248D6481CF0CCF274634D37A5AA4DDC
+31F3138AAF10998FD66F3817B77060E71C6D8F17205F9C098D81D952E0FE3831
+2264C55D73215176470D8D75E7BE6E44514984B9D20208DB3ADD4767CAC09D41
+9C8DAB6EDF4FA1AA2CB285CA28E30972B3BFA4F8600DB92164865738B015A331
+EA9EFDD478132047DAC28DD4FFE419F94CF5FCDE732E53FD332ADBED32F76B2E
+69531BCE0D461BA3F41A528DB0CCEFF9663FEB3EC9CE0F760604F835699D7C08
+CADBF7AA3DCCE9E813D66BC62C6E452FA02FE7E5F4FAAA527B4567AA4FACE790
+87910AC2498C0999866614C90AF7DFD65A59B9183FD8AC5DB9AA81E8E8477F07
+3501D4BFCCBFE32C964D3549B420731209237584D274704593F736317D4DB747
+58FD2ED3A0040102DA853D9BBEC07C82A04C4C68069E312D8B69E9B3DD1A4340
+D908CD225284AB331A18D324C405E59D5C37CAF7E0327B21953A024CFBB2B89A
+E47BAFC924BEC97696DF3D54B442703CAEC7DE58297B363521AD1139E25B9B21
+4C30A11B2E2EFF33AE893BA0C9C051F71BED0974327490EE79FF6B197B8AFBD8
+B013CDCCF2AE5D53158E4023124388119C647AB98B2D83A45880B5DEA055167D
+F4A83C438E12BBA5D77C2E0CD32244D8DBEBCD667AB09B30F791005BC9ED979C
+6B32419B3EE520C0BE51D84038C75FE78588997BAD805026FA6564D3B7E226F2
+F1999B72F802519B31AEF0F00670F039C4E709
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSLTT10
+%!PS-AdobeFont-1.1: CMSLTT10 1.0
+%%CreationDate: 1991 Aug 20 16:41:43
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSLTT10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -9.46 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMSLTT10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 39 /quoteright put
+dup 46 /period put
+dup 65 /A put
+dup 70 /F put
+dup 72 /H put
+dup 76 /L put
+dup 78 /N put
+dup 95 /underscore put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-20 -233 617 696}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0528A405DF15F03DB1C3DA8B850431F8
+0E5F73DAC973450D1ED0530313057E971FC7E7CA88E61DA6DB9A5CD61F0F76CB
+4DE9105D0627B8DDF51A655098229920CF429CDAFC3F7788C95E7AB30E84F840
+8CED52E98DB4CFF161D2E62B0D28CB8B0AC82E7A8D2C007953BAFB3056D66079
+8064956E257D31C13509FB81A250D9E875C77A4E91CC49E9FB3C0718B2F691D4
+B4A64F351F4DD68133DED7629B0D96E5124584A16FD2AC7A3EB244A934FF059F
+ED7297B0505F3C2994AD66A3CA5D2728B034DE94B64A8AFAF341601BD4DB5858
+C9950A8BB9C598B8960609F48116ABA8C007190AF0ED335EB5BF61BA6871FA5F
+EAB5A26AEB5C7C352EB80799CEB983F19EEFA801093F62086AADD0B80BB6580F
+2CF61B1390FA56DFA1A0B61C58DEF96BA767A8A37EA44730783C600706606C60
+4EE74EA99B7C0F8E2525C8847F3D31907C3C483EFA98F6C416B6B2C343DE6370
+52FAE423008D086A76A1FFB327CC7FD84B1C66B203A4F41582F4599A82F8362D
+38108452EACCC937FFC4F3ABBFE3628DF51367DA6BA3F6826FC6522D6AC5E8EA
+00BAD300FFB6DEDAB93237704202BACD030AA824B1E97C0AFE17FCE8C75F4FA0
+B8A74329A6CF1788C7EB34DA7307411E9AD7ED8D6582884456E06E033B4FFE7D
+CD4DD8B06AD01340CCCFBC382C18CA451E4C886B01D082FF8CC5793F4727C3DF
+B52B4F1A242F31D1EB79D1E39A1D4FD13D6C5E2A42AD4B4D1CC4EE7BA0E5F80F
+802E5AB57EA15F4DE44D82AC408AA86D4BF58EF967FBC6497BBC7F017C0598AE
+32CF865DFFF0FC7FF9E6DCE9B5F2F4C7491AC674F46E8E7660452CE0A77C1EE8
+00DE382ABED85350033F8ECB97398E4E0A75D4877A107F6A909D0C76D14F9A96
+8A6CFDE3FD9D79B6FD82693A9F354BD2ECF30C6D99F7AC522F8D6C93EA214F7B
+3D0ED77F042ACDE9414264C0698E86398562E2C640DEBBA0734AB4C3ACE3907D
+CC79E6B2C6C3C3F9B01526E8CD98237D4A9B403FF8CE3132222FA60C196A19BC
+A2393AE6935C0F8B67FC1D1A12A7C9ACA59008C1238A2554F7AEBF0756E21FC4
+27AB38DDC7F936401E2ABAF95007859E0AAF494D016911F82717182F6B8A3FE0
+66F999868F097C62D6F450E126F3010F193976AD6EA666FE16DE33AAF0014563
+6514EF6B508FD296A90FB35E92E09000BD9536BAA72AAFD7B0D33BE0FC90DB8E
+CBE3C9288A23144649D34AA49689BFC1EC610D10063FBC7DF8562864D50CD144
+566F98755D007C0B614D734FFD79D6E1EDA44657629EBF1CD3AC97B4471F3D30
+9AC63338385D1CDA8952C5935E84ED29048B2C1C45AFD0D51634752F7C7980EF
+97E9522753A877B34A430F04CE0D13679980E593BFFE8D796C452B4AC7133B88
+398D8A0158A35989C31F3ECA97ECF7604509164798A40BB9CCAC4EB47D36BAF4
+53B33EDB9C91823AC5D69D10BF862AFF86B67E7A62933644D87F46313EE13D9B
+556A2BDE2EFC37DE329AE4FDFE0DFACA767BD44FA0E75A32F44CAF3986DBC770
+3E8BB6BB01933CAB654A2621D0AABE7CDF950C6FD1053704D3036AB716B4D48C
+7CA0E6447FBDB3597612DBF00018BF71B3386876DB30D07E24060650C058EB22
+D383E7C88DE7D8D4DB4A3A467BC80F90BCFB1154D26B5446AF0028D9BCD668E5
+42B305B4BC6F2985C933A94DAFF67A0D56C898B248EDFFCE81440D08273E2E1E
+E0B4D816906A500A3F937F697755BF9FA7607FC165F2BAA255D211E27FEE060A
+257EC6B58B774DAC1C9338C93B2D5449E674393F00FDD9EDA20A4606E4F59C05
+1E5687521DA83154B5B98D0A77BA56BD793F34B86235FB2584075C8F736954F4
+C3F8B93ABF32B3939340AABE6C9BC0D5FE85DB42E1ED48DB3E28A2A0A8781500
+49CF008768F60BA7D45A14107AEC2BF9565BD2BE3114CD22BEFB342866A6A00B
+A4E178618370CAEAD9130F74258B20F1BAC2E4B9D354A47F51736C3327EB9555
+976A2497437AC0456D0AF8B4000D5CDBDB97850AB9123ABE6306A100C93AA24B
+C35CFB115A0552940DE8F71135528DAE9D02C17BDEF180951541A064640C7201
+37068FF5FC9B8E20B023C6306FB1E92504612CF3543D1F14E126408EAF6DCEA0
+7FC0BCCC89DC44C36F4CFA2DCE9DFF129944E8D67D52548C148CC0FECB27C20E
+4A47FA52E14D7D40B03B5CAAF7E81405A234C543723C70942EAC901C535CAEBE
+DA5FEF29F691364089A0E52873E49D00C70B7F7504B70C43ACC2E9345E282891
+9A10ABB3DA1149138185E331425D40C2765562F10E27B9F6BA236A856BD1F16C
+3E6BE78E7212FF385A811BAFC5EA55AB3799CF89E0CB242B02B870143F715097
+8B27CB055211B85891318CBF947E0524B73CC75B727F4B847852493D547FABD3
+D44DBCFE8FD5986B4F652B686CCDA9881C60A55FE5BFD15BBBD392780FCEEF27
+B62D72F2C68C6D21F8C4D817EFFB4971233E72FFA65ED256682696A05C926E70
+2C6CFB31C11584E15DB6DC55E7B5602F3507FD1F77709FBE720B24269FE6E8E8
+EFF963B57C5FD26B116D6A163BD45A64DBF446D1C8190DE521F88E91A04580D3
+2FD12904BA6D82811B219ACECCB688F4B8C26D8EC6F86E56F1AA7BBDE6FD0D30
+E8AF185C48D1A49EAC11BCC89AEAB7167565558394578DC637D8F33AF7CD9F61
+1752D30DA7965BEDA06E0E71AE305ABCD3F33B7FDFE6168D6BFF243F6CBE2148
+0D79BD1AF45480FA872ED7B3CA99717F0E12CF2FC18790CA9D1ADF2B9928F2F6
+30DB1C65F536C2825ADD3FAB787B3BB2220A5E3FAB8FBA03B2377C597DF5FBDC
+760BBD15EE2E3177CE9A6563D2220FABF91EC364A4D9707AF5DD02771F372B37
+43344F3EC07CB320C0E7CA062A11009BCC94C5EC696F8F8D56B4E4C07C97EF81
+107221C21D28AA4A98C84A4D75C9E41277C071C4F1F02BB73C43B7605382ACFB
+B9368142DCDDE882D0D71568FCB0D0349DC9E4F80705CDBFDC7A1C6FCE4E84C5
+7DE420960B9FCD2BF0BF9E195C87D97B90D1D58CD36D37268D67A0A61C36E252
+124240B094D563B0F9908D76E9DE019F0DBF3047117AF2116C35DFCC55ACC6DC
+517F7DDE64298296A7C1004A5A03A7B40C6A506C4DC353C3B9C9F00137C6ED7D
+200D9FDCAAF370B866CB6443B46A2E247FD581B0B810A753AFF3F660F33C081F
+199A8BC80C246DC153A664403A97ED990E611044C53E92036373751378EC4DF6
+3CB24302FB8D181449514FC0F8E15769BE31AB63A5CFC81C45F699F3AD8441C8
+D3D23B84BFE47B049520127FF2A560AECC866F38616ED19F66ABBD87CD518736
+50595F28208157714B1475FA4356246CA89658A30D0B747D39326B3E1210FB61
+67C282EBAD40E2CD90EE1354026499F1EE8AE6FF49573FDF3D53AD4AEE6835A1
+19331D67028B89FAD00A3E988F4DB302088D2DA51044E99869B929B53AD978F5
+FA5EE05E5FF00273BACA89198A206B5BB33E23EBE7A622418936CDA38176C02A
+F8385E42F9A42F0885CCFCD1619581331368F7E7CB48DD152C4015BFF620A013
+BD484A77ABF8B3C7EF84047B96A5806518EE0B848C5413FA930AF5CC2B0DE6C3
+B60FAC79CEAB989B3B49799E91729054E648F564A1C01CB25A7E0C7F374206C9
+1F10FC8405166E4F2FE02FDED2D02353A910781E1830D57B343A0D17EBF66C3C
+759E18363CCB5EE29C20D5039C4E79585E2B6F8A94349C45FF4CBB6BFBE854F3
+13C976B5A2083856A5DFE097B09B974BE93AECAA02099C37661D419816693AB4
+F7BE24FEB1C40E948CDB4BBAA0BA93E884D5ECD885D3ECAD2A6ADA5EFA0FD320
+D36CC58B682E880B8B77E69CCB380F25C8CAA849825D6A8B878BABABBEA8052B
+3EF671CF3DDC67D7C0E4ADAF53C880B7EF53D6A48912939E10F245AE4FE4A318
+E0DC1B06D90E99596E6F56D7201B55C82EEE2C7C47956C164B1B2564A6C4A9D3
+A8582CA084CE577C111C13982CC988B15C4BEBA1BE4C28AB3C1DC408FD2C7B0E
+1DE24A492C48C121A6807F165643805FDD068C19A4B886B5AF3C032F286510F2
+4B3DD91D64F0DCB836C43A9BEA90DD94B2374CB8F6CEA4F764AC6887C120E937
+FA454EA4024E0005E744CC5F7148283863B94561377E5B62611E03DE2756ADA2
+9157DDF385F2E234DB911FB6E99A8B95A49557C4EC61957EDB93A9E00B1DC874
+7BC848DAE604427064893D7E4E3F1BE2C3A2C7337FDB930E427B3545A4401246
+65DAEDE9E36F0AF9A821D5D32AD75B799FE111580DBF1D8D0FE75F6B35B21FAC
+685E1A004F46A268CE2DA6EC074C2B10649063EC2541C0578EF839A8E95738B8
+28E0E5EEE596244CEAB0A807B8B7C1263F62246D2680D7A47B497CE7A5505659
+CA2C351C297D76960D51B2588390807F9D53C81DDEFF980BB9810D002335F1FB
+A9D081D3DE117475ABD43ED4319B1C21FC844FA8E0662692BAC0FE7B654FAF58
+17ABC610A678E2F686C619EAC8A4311E915B0804720E0EEABE67AAAD959D3455
+242E97544DE686275FA0D6C575364B208147F6AC6D3EEC264493C15E6EA9EACB
+D2D587AAB0F01950E5B19D4CB9DB1E2C97B29725E896EE7F254BE4339A199E30
+64EF3ED7096E8CF715E9E3F622C54502FEEC7AC2D7A17C55547C5D9B1AD5A16C
+740B8E9C3603C00B607EB69ECBF9E2F401E809458FB253170D59337CFCFEBAD5
+F2D08ED0911C1D1FE3A8E6B54A6340D107652C4A712BA44F3DA6BD336D471E2D
+FACF6E7BE8DD1F30E3528389059926D93683C8214B3AE390C6601FE94D4B7668
+B9D775784FD7C8BD3F81558C45A556C0965DBBF4A082BAD4915E864B1779D561
+73D921D61FEE6DADCFE818B6B3BD643575950C45184BF13A8D9A9D13AE338137
+0A3ADB8AE13A0002A0786BB91A8C63C28A33254A8027B54D0992D100AFCE8ED5
+2D662E697E86F8C9BB692FC9F21B3CDEE0067A2EF2B0E4641E0A1BD192241DB4
+7AE5705BD1D654B9DEC6AA4CA653810F02052D9334BAFC9FE775405FE1667952
+027D22FC38FAE05BCD02AEB914C7B28B2430674824E43EF97F702C8F6DD0F17E
+78C0685D6D30C044318F6325CF134B16E8D070D1F128301AFC16ACDA572470F9
+4973E43A02331ADA5E02718A1372E62D557C2A85528A3C524F2BF1A02031F247
+811CE50A9A60E220DAA971BFEF4E86F01DDCDA2DD84F87600092A4811138953B
+8E1AAC0FD62164F00AC1D0CED355BB3581321A266FFAC96256A48971CEACAC91
+8FCC3CFCBF2DADB7D5D49CB6675008FCAEFD04D1D85A75AEAC4E062A40B41E2E
+50452BF5940B2FA90F9A04AE296F83618EB2460DC8219DED05C9FE0C3DBF5DDB
+A94421034C068C154325B9E89F158E36EABE02B191BD4BDA752BBF8D04D4F20E
+6F3E3FA8A14FBF20E8E9F3F37FE24D3EC96639188F024267B930C1FE66F4624A
+99DDBFEDD1412EC86D010F4DC6E751DB2FA26FFA3583B744D28B6C43DDC78253
+399BED399709B6C4D595A84DFD586A263707B64E31F75B06C57BD7B96EEABB17
+B32939458832E0F90441B365DF5F13125293955D081E08F84925F568E2875D95
+9524F3EE84D1B580080A47C977CAC8620FB90A5F40A9D4B2E7C2149E36240DBC
+E358855C09DAEB2C0561462FFCDA8634299A6DEF3F6EA5EEA269070675A61FE6
+6C7E260E0D59C852A1180CD9E06E89F023D4E9B349BEA03146B5F371147B77CB
+801A61093EF433DC0B155FF339DB86F3FE80D380088571C2D8E18451F1B622E7
+7512099E2EE6FE9C33456A6D6987FD2338BE45F62B624D99B98E62AEA6A2463E
+304DB01FF79C2514B207426EDF7E235EB2AE66105584C28869973E97588478C0
+FC4654D1E40841EC50E05C75CBF1B9495652606C17F52B29CBC2F6CBB04A1582
+DB60FB2150934102EA8A9A58C178A85ED43572E78F64F2486AAE3F8D3ADD800B
+B553B06F81427DB7650FEA832145C5633F33690D56148151CD2F51EEDBCE5228
+5516F30A6CAFE4F854C9939648F639130C95F7E017D35BE5BEF54F45114A820B
+B852EB40529A88E8346190383E90B9D4EB1AD5EA0225A44BFFB5EB34CA397609
+073585466A738A707691870DDF461468364A9B083AEBFD7F51F92FFA22194EC1
+739085CDE38E76186109CED7645921AB2882A2010C5EE5F8E35A8A85B68FBB5C
+8604170F7FD07C95BDC813485B6A166F05FD093003B481D5018265A2CBE880E4
+390B40453D627268412CF5226C6E7E925FAF33049FC4323AC823032CB5DA5343
+3607F46E9041149BE5E9573FE3AC4B8756303709B1E8634F0CC96749AC4EB07F
+43987E233FA30054894E070A1F610B0B025D4459C1DAB273FBD76890F4099124
+BFEFEA3A0EC72E37032A10F9A46AD13ADA64C3B8E38CFE02A20EC58B7088CD92
+97C046B00791F9BD44665A11D8B7EA815479D887A183F15C69EE999C83D779FC
+0D8EB5C9F6E8FCF36D7638901F4AA74BF58E94ED21F8F755F154EFFDEE3AAFD8
+4053C2DF54DDDC9E2D402A14C09331CDDC66B279A44C1497133D69C0555BDB29
+3DABACD5611AC957FCC7E2CA89BB0825CF8D4F9ADE7D4F4C70E428C33A8F6736
+33EBF6743AFFBB4A5DA57FB073D6FC6FE8E403E8BD531AD1691AF7B05F3E78EC
+BD14D0DBBEA8A07185BB6EAD83E2D8A20797612B1E37BEF6728725E5B161B30A
+CA48D8BAAE7696FECBC8FC10A9B7484F05BDD87A47DE039535E2FD8F2FB9D17F
+B1B9B7E6CA78D5955D2BFC1D36342F1B2271C9BB382B551520496D7E10908B8C
+4D6E4376CECD01A14E72BA4008D2E96C3AA3132BA00094A4865FC7F2A7B239A7
+672877EF442F99C16A7522742DF97B8AA3860AF415960B057DCD48950B30C7D3
+FA28C0CF02E54B065842FB6A1CEBA0C852B1BC4775C2F2BC0282B62F44943ABB
+5BC9F92E13BF18DD1C5F5A4B43EC3843FB16A568B6C5807EB3A1C2F0CDE633B9
+9312426CBDAF5CBDD9A9403EAADF70F1F6127F30E80FD2290EDB03B928127F41
+549C0753468AB19165D105BDB47C0C1395D8AC6F2EBAAAA1D43E6239EF702666
+3D690331F61D7087EC55BA79AB2B8E638343537A23CA95C8FD9C17B639AD3524
+F38F4DA192204C89A836E08FC5561F6D38A8EEFB69F6C7FA7DA7C681154B0B33
+3FC1988CA66499745157AFE393A0FDE81F5AA5B88CB8ADC9201E3EA91CE9C575
+CAB093CC845F9308D845C570C4A588A9A8D462A1D6A1D63F3DD36C0D5B0BE8B9
+770FF8240880EE085B0F53119BD63301594A880BA88E6C90F2759CA29E51B757
+9664D2AB63B02985015CAA8244B21A425ADC0F6E9A47E8DA79F9D44E374A5735
+77F664C86D70CB5149CC03E3DBC33DD361061F1B716C5748E50FC914E7791471
+471991F59C82641CA10F34517AA914D075A9D934AB66861403BD7AF706286D80
+6405FE007A7C1A0867FE3DDF72E81CD83CEFBA68612E47CDF25744E7C3A86E9C
+F255F0849546A7C7BA76195C6EB315B762EAE8C5DD8950FA793F712276045E90
+06F60282CF7A2A76E108ACE2AB037C0725F48390DBEC95DAD167A54CE28DCEF1
+2AD7350A5912182A6B41462BCC24A1635ED448DE50E401F5317043201CE2A2A8
+878EFFFBF3DD5CA0E3B0EDA4698B31F1B6AF219120F7F3B381397B05062E0715
+DDF7855292CF32020D04C4BD22FF98306EE486378472721F601416443178CE0F
+D78721B34923F3AD5FA81E97D9CEB76F2C1D7468D5CAEB32C2AD89B4DD8D804E
+41EED7B842E31476655273637C9417F1FD6D9F6631A11AB60F9D17C876941EA9
+45004D1FE13063914C7109D09FB65FDE65A261E0EACCE6427B4FA7CE90315485
+02AC31B08762D37C55264B35147D5D97C4CF6AB289D8AD32EB919980204D4124
+8F9FC68EBADAA55338CDAD558D10181096765132952E422A167B6271BB08336D
+A28F63BE5FA6DEEBFDEC57358598394EACA84413E8CA0E4EF1E50A2A8AA65EB9
+025AB9C460695C6879426B8B340C8E63352C071AEACE05C98C7E9CA95B39035A
+C0A8F8A1FB3B0FDE9E0491DC6C58FB9546387D4A5C4D982927A94915E712CC82
+72FDD709D007798005F0F6819D74D190E3F203DFF9FDC00B60CDDA85F9E872EC
+04D596E44CF820C4FE26899AA2C9393EAC37F2C915078EB4C60DF074742E5D3C
+7CC34C6A7C312B8A5F4005B1BF6E55A2DC1B7D5696C71FCD24A3EF05B84512AE
+40A03505F6EBA5067FEA439C03B4A91BF0AEA83AF1E468BD96E9CEDEFCBB8958
+C3E8A12FCED6153A030963A0D440CD568FFF539D17705AF15973FB0FD62F03FF
+95D4BB6A270481A5EB548F046DF796BCDD8AEB548317BFCAA2D241404EF37767
+27CD541A753A3A57174E66FA661CEFC12E137716D0E7CB1F6B8FA1F31DBF86A8
+35D8E20860990A79F468188F57C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSL10
+%!PS-AdobeFont-1.1: CMSL10 1.0
+%%CreationDate: 1991 Aug 20 16:40:20
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSL10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -9.46 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSL10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 38 /ampersand put
+dup 42 /asterisk put
+dup 44 /comma put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 59 /semicolon put
+dup 61 /equal put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-62 -250 1123 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9429B9D40924DC059325D9D4CC0344F3F997A99E6CC0676735EBCD685AAC9142
+08DAFEC78BB41AFC2F1C219910BDF41D6279284EF600B69776CA15BC8A34347C
+30783C52AFA60FBE3E353E2AE354CF87B558776A22C776C7A0B5AB5CE1F941EF
+C2D9CAC37294BF407A671F10E4743BF842143F4F7DFEE643BA3BBD8BB9E3F24A
+BCCF7F0ADF8BA500620C81033EAE8C4EF2C1DEF13AC575F1B3BBB66F093D3B78
+5412B82B67FFA087AF57182B2230F9F2137180CA58A7D9B2C822FF04BE6CD01D
+43B2CA7058C7B953F6D9B5D6E91ECBAA5CDE1159B0E59C83DBAD96D6C8C8BAB1
+374EF652D10C0F3EE7104472C98DD3572AAF2D45A70BF7061447E21EE3C3BF23
+DF39C2D1B35B42CD5297BEBE6BC94F7C9DC6E61EC67E4F677256FED9064BD3E4
+B51A71B1D27CA4E5AA9E1D8080E6DAB5310711EEF87C40859FA935B19524AE83
+63B163FA8397BDFF443227FEDF7DB27DC35D89FB1C5E435DA0619A5C88AFC73B
+89A2DF5E767C5B536BC7167A840A0C32BD57A14DE69A7D0D819AC36FF32F908A
+5070F32983BB007437E3500799DF5E0AD3710A4C0000F0098D5BE99F2EB9C1C2
+C444FD9552D0DCA098A94B3BF176F511CEE13DB7EFFAED7C47B5ADCF8D4700F5
+7A5FD1B49560969BF5C44F3749370663A04776F749DDD7B50674D93254426C4B
+EFE264BEE7810EC93784B7C01A7F29EFD92547E13A2C7851A2E709FBD5B87850
+4A44F08F56A542DBE072D2FBC58D9E6468E1AB858DC35240E30D31C7AC13D6C5
+7D2BB634BEE96FA0E10F842B11A789F72A333DD6DDCB1BC23227EBC406E50B40
+30AF0C48E6359AB0C46898CDAF1118E46BFF8B00F54EACBC2AC262AB898C42B9
+2E080C10DE923C195ED0A46BD535972F0A59D3977A0C4E4C4130576A94DDE5EA
+E41FD03E31544D3BA1BE41AA59A8918358EE6A15A0CF9B2C32466165E4EDA1D8
+D935792D21C90EEFC2ECFB39237D4D42818916524A63A0268CD1C8C6D5057994
+4204F4F43CF3DCDAA9CF3A29891F2A3F7DF12B157EC5516AB9ED5A3F557A8804
+6E592FB24FDBFC0B914A4E00906C61D7615456F81DAB395A3B67BC301A7F0C68
+F21C520818CDB25886B6E80472F9CF474CFE83BEB46CDFE2A93847E8BDBB984A
+CC2BDC18ED7001FF3F7B7756FA759331F9651535B03C644CBBA37D9B49199DC2
+75079E48F9C5887E033672C7AF6A598120BD6D5BFF89A1A0FEE633E206A61A34
+2B3F3B1770604FF477182B846F70B6D05CE4CE648BBD018BBBEF6D052A62EC54
+7224E1CB5CE80CAA1F4E0A9261DDB3B0628EB457197BC5DB7A10F60EC20964EC
+1A52BE32DB798C2AA9AEF85854DC950217785B7EBD64C37AE6FEE1B6A35A5770
+005A05C5555A3F5A77A0773C2ACF05B38E68EB3384CB9CDBD2332F63C7CCF0D1
+41C914328B6BCECDACE80228F644B03417AEA8DDD128F3EBC85BE7AEE1B781EC
+AE01164B2A8772CBB318B992BED25825448A9F9B6B18977EF97E1CB065152D7B
+ED89CCC61FD0547653D944DE06D0FD8B21745AE22F01D9A7AE7D9A2327A1D142
+69779681C657E79AA8F5042F0B72FD7896A38C14AED370A737C2EEE58600ED12
+6E082FBB600D2F42F7AFA69BF2E13A3FB9F30A5DBA4E1E6AB3F4FD64F71317BE
+7F985E32337927A1B6F2FB75B50D220DA1EC63DBF714DA4AE710F8B4313EE702
+21DF3E47A1BB8C86A02328A20C216A8B0EF126A8430775E552848D49EF37CC78
+A330AE70746DF916DA1B695FC66543FAD230E23943B8593B09A6BD6522D8B553
+5B1D27B0D8C95EDBDAD16CCC8CA5780E94928F56D804CD59906FCE4DA93D4B07
+48519434FE1FA360E4D9C59ADE6A6CDD6EB4D35621A17DE8542FEAF4C7FA3AEF
+951A4DC19DC3B75EECD632FD6B16A258A448B75BE094A33A895A0C2B06223431
+8418469FA350A0765EF3AD5A1CE737015D18A22D12801E3606E472E07597D31B
+4774151485EDEA5BA15F953EE8B41D96B4DD80317D0667FE446D623ADB461847
+BEE790256A4A72F241EF37E5DABFA3B2EEFE9A83172C1993DEBA5AB3D69DA23B
+9B06F17DDB86F76B66F916555C6540AE261BC4C6BA99CAA56BB6287823F4A77B
+EB0BBB3A28B89394ECA1D1D94EABAA7C807CAD4F39D6768E5D30D37E02EB2417
+E44C8BFC2D73F3023F1762AFB5BA2036DBA8260FE5665E4426B430D961DA2DB2
+710DFE8D6E63907ABBDC453E964938D86F752ECF2B7850E9A8F52F4BCECDD6D9
+CD77D2291E7551DDCC49257459FB28EA72DACBB785862689E1BF8367FB614425
+376E6D816FE21C56BE27D2C78F6B0E0F9ABFB838FBCE03BD26449273C3AB8CB5
+B4B960E0C984E68D22E6A9051E7A567A00DAEF675249687793E2973924995A73
+81BA8CDABC0E646883A0B9A13C46B2C8D72F055E4521C278F13FAC09BCD6649E
+9CBB8FA82A66798D283C1D2D67981D1A4C0DE6A26F16942C3B9565AC13A14202
+F0767B354CA7E6DA72A4EB1135A64C5FF1CA79DA33E649921FE47C04B3CFC2AA
+979494256350D9657960E09C0F6E1D2CCD75D65905C288C38AEA0B8A465AFA01
+1AD5A3FAF469DF5F338C0DF11CB4920CE799408F1F361E2A226CDFD465E0B2B9
+FD49DC551F48F5025EFCE988AE7427505871BCC0663A8D075FFE3C98BFA2595E
+9C82F89D88BB9E380F42808ECF82C732002F6C3AC18CC8441D823BE21FD2EED5
+BF502EA327D0B732796EB26C7D76A1AC22D9930F8C8888B142D2D85C8EA56280
+4F244AD3672D89D65865B64B0CAEC54F32EBB51FDD3FD77B76211320B1919F50
+8B41CC87EDE4E66F5260FCDE4D685B8ADFFA897A070696AB9A360DFF6AA8FD55
+7F59B1556A092A498B3EACC503F9DF0309B6A6A3086270C7F4763655E51222D5
+E24AC23B57DACC4A75D2567717B4EEC01E4899608F66CC28BDF4053BE1C7AD3C
+3D2A4D60C9357FE49DD1DA13BDD2EC4F17A261586FC939BC1319DA456F85B50E
+3ED98A6201AF3CBD49D8361B218FCA522E5A157207DA388BC3D66665A3878A06
+D2B02503DE770ED0E1E112928C9BD607FB64C1A69961540876E8D4D1D12FB67B
+927DE8AD46304AF2C61325134429D7E88D7AD980F5561F38324E4C5201AC18C8
+8CA525363A5C335C3893C630298144C962DB9180D12699C9D1D1F51D2E3A21ED
+0F11E9A9FFEB1390386D39397F1E209D570358881828FAD2A68E4B2552591861
+E5E20EBA64F2394EC4FB071FE9479C47AD7357C846CFADC84CE0D90E1FB3BE67
+B9478B93DE41784AC73B4380A23FCF1AA617C4F17AFF7EF2E6B9656C65A7509C
+66BFCC621CC71CA5D25B052853A5A2FCBDA09498860CF56A336085F34161DC6F
+6A567071C04EB32BE6F4830450A0EB5E6993CFA929D81E65EC41E2AD6C6728D8
+973BC85E2934CFFA358635096E3A0669EC51654C720D3230D18207B77F7CB10D
+C10D932F511F88A1C8C3AA37C6E7AAD45E617CFCD1054F973EBE6B7379D0A2DD
+42848C638D02DCB0D7D34FD3FCC17BF7622C9DC50414352F1618FBA02CA1EEAA
+9CD913E9F8E1A3412ABE9806753EF30AA6BC0995AB9B68F9C0800FE3F385566F
+C42424CBCCFB6B4586ACAD88C7C571E61AFAAABE26329E69B4B2C9856E68A83C
+D662F2669F6A6B09EEC923E25F524A1B04791D515BD0D40E130B15BEB09B0164
+CE1F89E88FEE437B459121F55EAC0C294A077AABD09E87DDD4DB92FB9BEBB8EE
+75CC584D912B1A4095DAC96F3D000F10FB3A59937CC12B0773395CB95D104B07
+BBB5149F59A795CCBB8683CE3B50A156D6CC4D12D6EB2D59E7B1B1F57ADA6473
+B78E2BFD10737ED15295A688B0DD04397848DE3602422DDEC40AF3065F4FBDDB
+ACDC44BCF3A363ECA421DBE597A899E54FA4B7E699B37DA153F33631C512AE87
+6659401D79E9DF6E35765DF08AFAE248E672F52867AB48FD94D8F600433B362B
+25CE618377968F9E4161A12280B23FC45E2A1C3FC6A2AA81F3BB5F22770D5E32
+319C3F67B4735E28D41C5ABBDC04C7F266ED8668895DD30D9637F5121B08C442
+30AF7EFE74A3B01BC23417D595AB8E8FD7665D264851F1B85F576DD529295EA5
+38D24BF8F468A185CF3ED038872482509184448F70F6102D4EF8D2A983E60816
+4A9D390EC677950E75179199018A24489E2F63BE90F72F54C71BB996CACE712F
+51BD71467BC6ADA5C0155B25523B5F018FF42C1ACC5FA3F7F34DA4D3C3072B31
+81010A1B66BB513CD1781E595262FF6FAD9410704B6BA0F125B8AB21C41B32D3
+7E96D10505F6D51F167FC98F1F216467CDBA46A0138F40384AD20D1C64DC6C45
+415B5D5FA0342187B10ED632BBEBC00D3C87CDDB6DE04157D4FB22BA942E1D74
+D8564147CA171C9DC0157045B3F484090A82F51C503DDE27F0F597578EBE2ACB
+BCFBFFF393330BA6721B8637A7F1BD8E892EDAF049F35A0E7BB9C4E7D01E8C75
+C588F0F73DC759DC9C3A71A3DAA5921373BF8A8FE53DA37301DA9054975E2F0F
+0AC5C23F2BDE04F5C2F61885B9DD9963FC65A5B65A416DDC968DF858226FEA91
+3C00EF09F0A3EC4248781F992B9B87E820A0C5EB9795409D01C13C750E53430D
+341B86F77DDB1D5D249B2D2FBC173714E7F159E29536F8CFE0A4B3D7F14F45DB
+33D1F476B1ABDAEFF3412A5E5B3A1EA91571ECD47F3B8829AF42E669AF44D265
+50B5066D23D1645A8EFA274AD660DB2F99DDBFB938E2B4E51A953F787C2F020B
+E3E85AC13941C5DF20EAEC973F3EBA5E502CEECD358853101E31186BC01AA0CF
+CA7E4259D3F04B2A89CCDFFC8A5C45264F5024B30956B47C7425C75AD99E8ACE
+0318A7E1FDFC7A4C5D347320158F6E4D8D0522C90745A68EE527427D387B4B78
+FE4333B805625FC08974AAF3B5B801991E3432565AE019D3DBFF028936644E51
+2866EC1854DC478144A91936E6FB217CF16BA2BC87F7C6463DF4E10D6874B546
+1A03A3010F3890DA3643580053D4D64D9C0922908E96ADB2F4B96A13454A02B0
+E3EC95AF7CD1E48CFCB6EFE68C0EB0708DC8151C10907D6909C2984E8A84A3EF
+A5E7A37631C9723FC395389D5B2D828826D1F3996AD427B1918A35635F3F43F3
+9389EB816693C4C77304E269098FC729BA515358F691A0A2889ECD5BE7C03FE2
+02B10B93BDB4C66920FE4905D01B6215E3323156DA3C9AE6C0231ACBECB7CD75
+18F254811B4DF3402D68D49FAB41EEDC3C42F71CAAF9F45E7898DD9DE65510AA
+07B4D3B4892DD523368836F3E86910CA0E0F391158E3318E11643E53EC0A9937
+B969F74528F79767EBDB9626699FD4A59A1BC82579BA8B237A08F02489DBE262
+973FE5EC935AE293DD37320EFDAE8BA8B6DFC03A3FCE9C7C3229FDF77665AD38
+4302FC81BB69B36181BCCED0FB37B5D631B9E8781398637776009C9E564A808B
+18671CF3854A2E92809BB8BC61014ABBFEAB10DF1DFDAE3F83110E5AB2F391F9
+712DD4D1F2EB8D09BEB7C7433D71253CAF379BE35B0E58A3A7AE00B5F2583055
+35E3234D12E7F123585811ACDB00E4DA31F468471A93C049A5D2882E9418F1E2
+5406D2E34F00D761B2C8ED5B327CC725C98D443047A2831008F1BA5DF40A2610
+ACF48BF3488590901E735C6A3BAA6B2BF11A745AF0A925D14EA07EEDA524D577
+5A844FE6398367E381D4F23ADFE15F2F1D744903A65B7D9B78233B4EE99A08B4
+24E8612AC879BA85E59CDF6EB3431CB8E17F2A16C5677635036A68E4BF21AF6E
+39B02727C381E71A44B35BF0E734C5BFAE026A872E65F07CD352D4BE6B186150
+8CC1DE7E5BCCE0094424BD211A771DF1FD0018BAFED032D36E75A46A1B449CAC
+BAA1AED551DC86ACA4B41C2851E3098A09F388C9D70B59A7F71EFB33DA92D81F
+9337315FEF7C68FCA60ABD50DEA8ED4C17E6C35FD7B90A9DBD3452AE20EBFCB8
+107365495EBE3BC5F46B27000FAD74CEF024956651AD7168A4CAB244961193F1
+60250EB50EC5FFF82ECFF2832882AE1CE895C201F580EFE3BCC316BF0EB37090
+9ADEFF4EB509526645CA0E7B3514A26869B35D83FDC1A27A0444E4B539B59EF9
+0A690B17F200EC246A676351017402C5E9D7A5E0000655051489E6250029269D
+941831B9940543F2B6BFBE009AC2212BBA1E167459955764FB1B6DB83A5228AF
+9C9C3739B706D6DDEB910A5FE799049869F3F70A3F2959E03F02A5590A15EB23
+28589606566A68F7838A7F673E08E54DAA860238FF303B21EA141A039255668B
+BAC35125F3B77F55D87C161D9A6AC34C5B352159A6945F5A326AA1F5C6CC18FC
+DCDC34FC78DE23BA61A4304FD9289168FEFA083F19B030313826E65D5D78D9E0
+FAEA4DC01266911659FF26395D3FD9784381E184566BF9DBD8742CBE3C5BD017
+CEF63DE0D13AF22AC75F58EA5630BF3250F14E731C8BEC44CD129DA2236FD84D
+EBE44AD87CCC4C5F973A0628C4F44A8E9C441EFC6E5434C9F47F0F888AC97F2F
+3905CE0613FFFC8F4EF3EA5B41A7B4AB7795B98CB357917D66ECAEF6FBE51DAF
+5385C984F8EE605866C458FFBF64D03E6EA31710451F1A4D7852A45CEEA50284
+70DD6219E263EA15D33E7A3FA3AE4D30251E885099BD36A8D4D32BB1EE0E91DE
+4D6B20345BEE58BD0AFA8AC3BE451942E2E4E9E6054F8835808F1D8433614FB2
+2F37D8139E88AE7F0AD717A605B7AE140307A098F6C8E578B9A5267E58D2E686
+F928A0C9A6C3665A0CA6B3CF110EBCB04894C9776743B3EEA8D7F1B735547D66
+6AF7CB13D870705550237F6D70C3B0F9B5BFAF52D3EE631AE2E1FF80B6DBDD75
+28A7CE41F1B80F828CE164AA941DC8F901BFBB1733F07272F4260B364E33B4F4
+B8D750063F9CAEC169D6B8039071FF6C85C14D289417F6ED76B83D89B15CF131
+700AF2BF75B62B1F860F58F07639306D6FFC09BA8BBA38410D193E9DF9D55371
+A7267352243AC08B50D0E6A74F43BDD9022B6737781B34583C36022BE494404F
+4B681B49186C48375FF1CBC75060921780C1C09AD16D507AC802B76FA9F61280
+CC0601B12A71B56578CEE367458FE9CB62B2267001CB269D5005453CD22F870B
+84F2907FF7F01ED503D3521021F04F7E7690BAB32A14FCCA90D7EB847154A27D
+9966FA1ECDF6354D9D8990D88AB28F6062D54E143BC46572C5B6382A1717DDE3
+5CDF07BFED877BF0146DDA30CF7972AC4E37AEF7D3090A9305F446522EDB2693
+AE4368A0FCD10355F6592E53BE02D4889E447D905A4E9BD1074575B794D5BD4E
+B92DB433E43AE9C49EF8B3686B3B141F24B1766CE6F383D01EFAF0C6DE464FE6
+94C482039A400390196F6EDF1D899DFD6794A531D4D821BCA4EC9728DC244E4F
+8618C0DF5ABD158893E92791D9D7DFFD4A7C90BD93783936E51D4D77AF582D23
+45703DE2DF03251ADF4ECCD1C33974CFEFA50041FC3A0061087B4BEC1D2BE66A
+FB1F8BF20E05ACCC3990E06D32CA43F9FC89F012C2942BB54580233902328EF4
+7EAAB444A0767A250BBC472359DC39E6A71851DEA73E9139C669B205FE6D62C1
+B4702CC60A13E317065E9479FA10F0724956D4D3CF40AC066A20CFA11D156533
+4AB8D99BF2B74E720369EA2CC4E1C96F3D24A7CA08F569D2099A89500078DA9E
+467FED85240366E368AE2102DB3BA517E7A8C71ED554163FEF59090A3A25BD10
+FB9FC0A2E200DADE3CC9241E72FF378EDDC913A738B5608FF94D1B050B99EE0B
+847237CFF098EA07BFDCEC0EE4AD752599A6AD0EFC7099B887D33EB1EFA2777B
+1F7BF313ECC5B0AC347DBA6C204D80DCDE21791944616F03D5F65E415E97C2FB
+8CB9C50CD2195942ACE669CE46F686D390CF48C69403A5AF76CFD451C6C671FE
+A1C483EB5F946F9EDF41C549C54AAAF1F590157179D7F25FBBCFC439857D1DD5
+97626A34E8FFC111DDD473891C5DE78FBF9719A39272124AEC8EE8FB417BBB37
+2919029DC9552619661F7A1A8107924CF64696F74F950EBA7517A4D8BE679254
+B56E340631029C4E1D45DC9348809FF6197BEC422F5660C44D9E062793393595
+0F13D1E3A54D9413E92A794291F4498F7C670DDE8E79A7DCF8D3DA2C729A5564
+AC2983464A6115458CD1B751C5296A247125492245A1C110EFD1637CC2746C15
+07E8098532D6D0B17DE3F485DA50A0446FEA790C980DC847108D052BE4C866ED
+8A8D5BE3D4645C07F10E5C8C02678B217CA25D4FABFCA71D4C593426087A8B65
+76959740E492ACBCC541EFB8B0C00E589A2BB1778749330B03114D1C95420937
+8C3C25E7950D34DAB6E9E30256CAA7EADF866BBB0F02DF053B93AAC8C59D52E2
+6C7A19D0A1E672DD77DA33FD573E9292D49ABD33E67B126AC4152307CF211B81
+A487C842E199ED60B1AF5F3E551CC8307E1CE15DE5DA951F873C62FCCBA0269D
+0A90F6EA38F79FC7D28F5EA01C83DFD4D292543BBEE9D8CF0FCAB4F8D819175A
+C265A020E69CEB53D6404BAAEA21D3E72D8E96BD4375BA50EBA337E37B25F3A1
+4047D91E9560169492DABCEC6DF35CF5914B31B789CD5AAE847C7D4E249939CC
+703C81FCC31BCD9ACFD0CD9409E7F6DB8C9BFF4A566711842C5685FBD800ACAF
+B758426AC584FBA36039171EE9FB7B8869AB2CA21FEF2865FF1754AC1B704CB5
+6F5D4839C92656234C09BFFED6EF465128C6A6ACFB008379D5E25B5C6AC6BCD0
+87EE643304F24219668373DF7EC07BD9871C76C00D3352880D8EE7C55868A6C5
+CBD49EA4D8B8849461FC14D55DADA6FAAF7F34BE080C2C2116439274C48E1162
+C7213AA03C4C8254F0B7910B6D58C3C553C11B257F775CFCB8CE08445F5B3C59
+6484252DED97DDC4DAD7CC7AF666E2F413096BDF8E21B74C74C56BB95C59397B
+5367ED378E9FE1E6A53174E3B52C35A04D2205A643587167597E0B679C7F6A1F
+F0DA0F8CBB8EA47CE954F23029603F00B5F1FD7BA88840BA613EFACAC0D901F7
+7DB051F8584D0B7F6DE4525F5DD534AE6C163464B7B8B41D1F7ABF5FCF9A5F4E
+F7E32E7F9E124C31C266F1A965EFA2B1FF58DF996F1BD40ADBEABEAEBC2F9F03
+508B3817ECE1E941B7A8DBF392A27BE6282D8D7FCC2765E8E5CBBCD0332E0043
+070973D6DD8F36CDEC8F56A952E0554F773DB412485C0A4D10C49BCBD85A65A0
+74494D23FEC091797EA46EBB6F888C5B7EF0C485C939D935CB134CB2C8949F70
+86DAAC430F71C1CFDB59B77CDA9A812D8DADCF904FEE70B676A354BE5E1CFD69
+CEA0A9DACA56AC6E7A7B99C334856B343DDFBDC2454144483F49140A4DD4013B
+871CA1D97DCFBEF2F41584AD33A84F47ED4F1589316D92387D3433001BA813B0
+04B82B6230F930594634A83E082EAF69120F7376D45BB3F924DC6B048D1FAAA7
+B4177DCAC871080015718CA01E9DD0EF5DE4A8E6CBF6FF787AFBBC5D2719995D
+5FB539A022BA88F650EF1E8162941A707EB833E8BFA94E1EC48004CEE9ADE21A
+DAB88EDD9F8B424F0FB80AC2AFFD79EE331852A65A1CA33B12CE4EAB2006E0D3
+DA816226C3933DECDEA36817A098AF000A33F8B47DC071EE8192C2CD22D21446
+2BB7EA72565293A5B06F70EE51C54AB9061F269F5130104DB1F78F8CD3FC0356
+9AF534CB6FC10CFC16584F1FE06FCCBF90528E95AE3344F9FC3C0D4C986F6E22
+FD0B0E51C4DC988D216DF949160E0FFB6D45F54C800E2D054A5FE276F7A5A620
+D6273B2CA814A8A04DA5175FDAFBBD0E683639342EFC449B1CEC0868FF6A2A7D
+50373384F347F15907843CA631E4DAF045DFDAC5FEB947AF94DCBC2EFABB3605
+1E7AD2B714064074C799EC23BAC51E53ED4F60C5D141BCAFBE00B6787A14C5C1
+198F1FD19FCC8C770D8684DBAB8FB75B4C40E363D14123AFD9E806C5E516A9AC
+F10DB4E598BCBF0F2B46754F3C21B64582D3DF87642F25D94FC4A95F2DC64362
+5E4BE19FA4C5F9C307BDBF44A721B402180378A5C6C98DFFA23919281BE8153F
+C5F905EB0DA46C3DCE8A9DFA2AF74864A6064D10D69F9B88982CA0F1FC2564D9
+AB24A8119FB732654B8B98B7CCBAC2054235B61294F97028ED67E5AB61D3C278
+DC8624C920FB58652E868135E5A30844C501E53A6A596937339818D17C6D156F
+0E6817D180A66A97C0E346ACAD3B6E7DF74D8959DE9DE2620CCEF33BEECB6E2D
+3F4B1D230BDCAEC875F79FF4D86ECD3D1CDEE912E16F63EAC1C9C935AF59E315
+F2F9DB7B8AAC269EFF941A4AAD9E4399042F4E3C47FA0BAD8F5461AD0E22FC09
+EA77903D318BFBBEE1447A5C2E3E11E648E35EC4B81FB11CACD56B56A026F114
+AD29F8B1B69C4121D5C44A7C5CEF90E6B7F80CE10D2CBBFDC439C5824CFFE8EB
+955AE9A5678267ED39619DBBEC988A137CCE40D24EF76E883C622CC9FD6C3966
+4F4A22D9D7E7BD3FC91ABF1ADFBAB1BB97AAC19546CB31E51BBE3E4CCC3545ED
+64B8C7A41F08AC34982F383B4C21EC04C57F496CA569D044DA17E55FEAEBF885
+BCAC03145008863FA4DCB8AA382107C8EB176DCCAC544CD2CC2E3BD8519B38F0
+51025C29BA9BC321516C9ACB98C575DEFD7FBDF189C21551182CA73BC41CD336
+B1F1ED8E5444682B467C1A1869755A16DF91F58F82604F20390FEB1E573770F3
+27BDA3BBBAD4DE53B040D93AB799355893DB36131E0BF324416513D46A35DC66
+484659AED16FCDA2246482B602FBBD4D926003E5826280F67D6560EC0EE4376D
+298194D8EFAA672F2755552C11425279CC669E5209CE6064BB85B4E9130F03FF
+6E143823FEB601862E5DD87D81C0D919F7369780702763A01C5800D54B7AFB41
+7CB2C6D3C79E4B867AF84FD5121B793A7B35B872ABA10CE912551E0C25AFEE28
+60D928DF11BAD1D769E32A63F282AF3CB7C091A13FC099909935DA8179A5F6BA
+54B738E4167F520732C4E7F36A3A7B76F4A534869F4F9B4C010254CDC7CF7B93
+D47C0F79DE37CCEF87C5575649547534841BC46CC61F06D8617A1A7809566EED
+767C727220F447C602AACC93E374DAA822424CD4B25A3859C1D4784016B3D469
+A26F22E55437C1B2FEA5B0E298C0DE93B47DB8B303226C058A0984CE5E3E9182
+FE9F9D30400C171B7DA5E7C7B9B22ACBCA076801D34626F0A264EC81AA53C1E2
+165B95FAF3EB5ED9DC63959CB1A546AEB7E5C36AC5FDF508B94229FC202B25B5
+1E8733F0896078604F4988F277BA84A1206F7FC80238A4D074F3F3D0AE912D7B
+96F2BAE6A7701054A6235E5244715E15194D52493DCEC7FE37F9E66F4E65C17B
+E630E12752D5874940B602DFA404DEF39C1F53FEDB41E611A34C07A70B66CC84
+51BBDA5E36431A6B7DF5950F50668761816A2445DA48BDD81312726E8598C6AE
+5E04839597788622D126A8B15F48C5AD13FAD612CA2F38D900E6B0BA8189582E
+58F026F811910C8DAED1BAA511F5E611696B38F0F354BB1B5AABAE99CB89E0B5
+BE9E102B17451BCF72BD027CA374249075CF42A3A664BD7DDD9F831F516F36F9
+6FBF607A531E915EE91F864F7CA4CE3B6DC1FE6E3B440E34BCF067E70DD76F18
+A2C9B8B4EDEDC45267A4D81750A67F15BCF1CEA0B60F6963FE3BB8E2C2B29199
+55377CCBDAA8020F3A7D1EAA7DA1143427815D26CCC2D87E99420602C6FB3A44
+392062F6B1C4D47862499431E290184C2F3621D0ED7F444E1E46D1320CB23935
+DC02409F141D62037E588939539B12B4E33B556DC2A1522669CB8C8A578B70DC
+6ECFACB48D5388F592737D88A77C3A15F1D795BAA4A290ED9D5516948A084F9D
+F7C4801E84A394D5F56C1004009444E50A155683AA684F82F9ECA5E13128A1C1
+73D4F2474D1BBF2D3DB361C9204A44BE153850828AF04035A38187F89B527C57
+FBB53E7BEF3DF315A9BFDA27B5CC8A73972E7D39841895F8D5172ECDA3F3504C
+9A329B9D2675FE27368E41538B4A746EAB86B7938288B9308319D0B01D0AE2E9
+9C8D9F10FA3C587468B0717A2D5244B44846E4EEAD7FF4E363AE807E1B8B7D08
+5F2F693DAB59BC831C684DC8C76973354E17FE4B8123807503B88AEB0C70CFA8
+5FC85FF0CD353B7F5827CC2E7DC500808F2B5A2C89EB16FE893001A28EDA763F
+B5665F65954C8CBDABC99CD219896D57F0F2107D7A72CE2E7284F6634F928136
+9187D9836BB48185E5C0592A5375075E2BB0245DFE2A89B9DCD2FA8E246AF486
+37B01D0D8141ED8B3B0EA8957113E517B916F360B488B03D14276CE065799A25
+3768FEF2E4576A736D3D5879CE75D27592BC39EF8CF870415549BF14BCB45E3B
+0E0FC460D92F85909E0EADDC13FF7AF50C3DCE1CA2560881D37C9D85E3FE8947
+CD2CBA24A0483B3DD477D58D9673AFFA65656F563FC86CF98C05A06923CEE39E
+E61B4894105A55B728A951920AF2A63D2885F0480D08D33D8AF657D5AD325C5B
+D128B79DB3557BC986FB2EA9BF6E929532CD5F05E6C42D1F4CB4F72A9BA166D5
+BEFA786D3A62ED81818E943904FA8CC6CF3A7BCC698F393C2EE5751127ABF0F7
+1933A14AD0E1732144E30B3713B166E2F72AB4D34E49C4E1F437C953AF1EE55D
+E166FBE799DDC8076D648584F59B50954CCD1BC0615A3198264F6D82658DE609
+CC0291BD2207A1F34BE31FF7EA4055AA58CFCBF062AA4017813F08668EDAE69D
+FB452BFB7BC570E1C16850234EA95C0A87B921F446C72E4CDA7A9A82BE435DFA
+67569D969CCDFEAA3EFAD8C58148BA1C8DA5F65A6EF96D2ACEBCF8758C043449
+43E442B1225DABA8FEB84FE22C456815E6FAA1762D3CB54AB703B992A566180A
+20EEFE272C902630FEDF51CF5EB31D80ECA4B6D9B9500571B18CC0F1B9655166
+2EF1AAF833FC6B9821DD394120B17B57C1A376D5AAAB37A56A5376C3EB1E64BF
+55DC2DC42E48D222D175C7862B8E47B90BBFB5E584F4D737B785613B547E90D3
+A610B1FA4725BDB8485E6DA94431121C5EABF64AEACBC141FC4781854F14A484
+D3513E899B5AD0EC6CA390C4023BBB300AA0C479D30363B819DC99B488CB2271
+198C3C25B8D37A30ACC0E148F8EE770848E543CB05A7CDC9C4A008A09B9945D2
+19D4DAD3C6752B16D6F67443E76880B390DDC88315BCED18C9F9DB380DFEC586
+F71079DD5FECA6D703DCF6024F0BCE626C0C11B3BC559215FD66071E98E05760
+F2333F8D6016B9D7B99A2DAF0CEF220DD03FDB5C9F43A5C3730E33A1F15D084E
+3637D6869CA086D7EF1860A2F69B7812BE3E9B429757A26688A8B873B8E9D5E9
+305907DEC6E8F3F06E3D104259349BC77743C448F0D7DD9E7C516591F0009B97
+05952C37C577377E575DB8BA7A89C6C92D19EC9D89B74B1EC5B63327ABA2331B
+C6E646F88B40FBD2A233F56608B0F1D928CC6A825B3575981990D21FFF13EC38
+1E9360CA1E86153683EC11EBBE84E2D58C85F7BD444DF7F831271F262ADB46CD
+2370D706B0CA8BF4BE4DC4D8F1EF9A2B64BCC5B2BA4E039B47EAF6B7EB1ABE1D
+D44191039129070AFF1096CAC54AD5E74F9AE06CEDD767D06D75B4F6C3275F4C
+2C118B2CCCAB91DA498D724409F2448EA5A59552898CFBFF2F097666B957B6B3
+D8424AC5BDD720D4675CA3CBBB7FAAD341700F555B297834420181E228CAAA09
+5B69AFFB9E8897EBF2E93838D3667B670FAD4443DCA8D3F873979286F0F4343E
+951092FEBADF37281E3D5903A545A6AC92E35DF30C9579BB35D90C4E79C6FBF1
+73B1627D75DB4B4C327A28165F5446337CB7AC1ED36F4289E657DD5EC5DC51FF
+02E3286AA94D437127E7AAE5C46E625FCC637BFE635CD96FB0381AB955C7896B
+F2C67EC18CDEB59E621D324243F02E28F208E1996ADBCAB86E55C8549D470856
+519885C85A157CC01632F98943822ED81C67FCEE06F58D01D04DEF125F850A14
+187B2A2A46D113C6DB2BECA97D8B94DC5A3FEFBC1D3FB314A169448FE046D079
+F1FD4CFD43DA88449B44C11C55BBB3644837D269FFAB5F7DAE87D872112BE48F
+ABAEC12404BEE8BE1262AF8A7684CCE54893E0FEEE3D964AD3D469050E432C2E
+BDA9E097DF2E3D4B4C294374941375711973123935EEB1E53F0F5F0F7AB7AD3C
+58FA3A284AADE041C453260712B0682DA320057225F693CE5665CA75DD08F6AD
+5245485CB66CF507C6C00E62A8A2C185E6CAA936B78D38FFBE47311614B13212
+2B90BFE2E35AF7E356D4E23D306B19373FCDF7A417997D397AEFCCC71212B7A0
+9E8E07DA9BD1F8D842BCFFA628ABA5057D505E24935170BE70FECBF6B2C0270D
+0F8A6752D3E1285A1BAC15FDB0A199420D0F084CE27A8A4A3412764CF5387C79
+043171E65F818117177C8A5B7F9CB4221060C8D9675AA016F57DE3A5DC850330
+D2A46C46DB832FA3CE56CD37D3E40AEAE6385A9FA7D5E73D8EEFF0BDB08B5DC1
+5B4C4F0D1C37D33352194EC0850766BD48D61C6D7DEF95CFBA637C83727686E9
+91EB684B5EB78230C77866238A8811194DF7EB27AD628851AA1A0DE4F85E07DF
+D26D1970E97FD27090D3044BDACF88B979459474C1A07C7E61652B7DA19613E6
+9898669E038FF411E28DEFAF361FFA03E400C19B49D6EB7A0F023178BC0795EC
+D07E28AAB73EAA3189E4B8404554402F76950304504117B0E845FCE9C98EA780
+38E8B2ED0D5264048C4ADE765316C8DE114590FA6821418513CDC0A2B183C240
+7CDD62EA57161E893DEC333D2ECE12B3A7C11A6A12809E404442918D9C502E92
+432AFD545AEADEC31A39CE2C46B1A45450E83900757A838B8F3C5545845E3D45
+1556E712690519B73A2DF2DD0E3554D53A53997D224FA5F581B50B20E5A16697
+7B47E9E8F936C4395A5C8D2470D3C35305BDCE91306E70BDFF2166FF3211B787
+48C41E1AC1E0F580A1D94F5599CDE02130B9AC5A1E1B4CB176D975A1D6CAFD3D
+5DBBF8B98AFA666EF60AF34ED41E8B9759D2C3E8213248739B61E806BEC7CB21
+CC0BF1EE28405A416C089C693543093FB1C3AB5FF33789B801D852A42544819E
+0C455366A20D15B6BAB3E1EF2417D0F9126BD854B132F487AE03B708A0A86FBD
+AA7DF4D6C19F07AABB79546945558EAEFDF726F5AFF3EF08E297FFFE3200E14C
+ED871B63D0B2AD107AE093AA6961204EE03462EAFD981693D8F03C54A448ECB0
+0A05C5D56F6451B2CDE6E947EB1F8FDB59894D53B2C066F864F2172528886E59
+B6088B7ED2B0C7FB98595CA74CD078A031410C3AE90E9ADB32F2D435832BFF2B
+B5E81400E91253409EF981F19E69C08E4B83C9D6315717FBEF16243A2E095809
+584422203B3A3B829FCD778431247BA27031FF8261BCEFB824DF20DD1DC9F195
+03A0CBA185BF3490C3DDFEAF62DFC2FF7AB9C1C04531809E44EB4C4E717E18D8
+6F4364B63A0B0086F1BF45638538346D6F08E559AB2FC8395E63095B0EADBA79
+89E39866FA5DB4239467DEE2F397D1D2530D8A20C80F9C29BF6A9D7AB52230D4
+B934D324D4D89EDE451A037D8B83AFE53D95F6C4956A3210E7159E7CCB182009
+14B93C3B0DF5022EA1DB7D87C4A1E7D4299E94BB205E81ABFB3B5633B6FC133A
+273ED852B18BCED7CF6DD08D60F70FDC0C34CDF3E505AEE46416A1E1117E316D
+B951130637DBAB346C4DB48905B875D403345FF84B8B2F27EB388A04E60F3522
+42A7AE1BE4DEBDC5F818304CDF7A747D7F7D4BCB467628EDD1190ADA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSS10
+%!PS-AdobeFont-1.1: CMSS10 1.0
+%%CreationDate: 1991 Aug 20 17:33:34
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSS10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSS10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 40 /parenleft put
+dup 41 /parenright put
+readonly def
+/FontBBox{-61 -250 999 759}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BDCEEA888D07B439DBD4E8B4C9
+D198C03874B5E6F8FBF4922065A92BC3E66D05DE53971CB1424510E892442858
+D69CE1F76E4DA76C87C763A4B2FE36321E54B1328C9155B8ED6361855A151723
+3386AEA3D042B8D89C8C0E9A33E5DF3B466F7BB8C2C8A4ED4CDAFF55FC6D3EE6
+0AF2CEBFC1AC3A6E6692F8BB81F82D86BAE85016AD62FCB05467082C2E5AD348
+44D1439C2B59F65590E57CA0DE481A7A34E79931B1513C4C30156170409A4BB8
+46D412D1DAF88AD30722F12DBCA1CCC6B4BCC28D06B0D29149DDEC520C8FBA13
+6B82E2E1790F00B216282FF122EF0D47B70A1B29514DDF7C0435ED238C14BDF5
+6DA243117FBEF7398F97EB95597707ED63C6797EBA1B46EA19ABB1DABDA171B3
+16CD500F5D64CBFBE4F9CBC3E66A34427D3C4D0C432710289381F9BFD91B4FF4
+1E3A896C3EEA2F3105C218877D6C0C6B763760FA364D00065E1CAE9DCB5676ED
+286A9ED0D1C946DCA6A2A670EE0936FB4706CC62E234CFEED34AA615C48D2872
+A087F30990C85E64BA68F3D5C117123467DB411C9F2D6F6858CC70C1E352C477
+713097321B4C4FD4C5CDE305415F998E7245908EEDE6E056A736EA77BD8C639C
+3A79FFD0B74B3D28F0494A115F2841CF8A8827AB5608F96FD8998A5F40FB3DFE
+3AA0C7696DE4E1D18DC0D6E84B943175FC38FFC42A9C0CBB13A908978C98BFE5
+034F88480F32B9DEB2FD228FF6CB0B89B045AB02020C82E3F5716DC640613185
+9F597CE262729BC52132F43922B9E28BB71A30AC8709634561B22D13C4FAFE0A
+12C4451969226B220038AD8DDA990A4E2CAD53DBEAB698898BBD3046234EB4EA
+901287E71CB41296C431383AB85F18882F65BE36923F6C0FD6FADAC5B42FDB68
+64C06E047434FA7A659EF7F3D1AA8E547939FBF9C2ED7AC829F03CA59AFFBFA5
+A7AD2E0FC7BBE619961AE1785D09444B333993199FFED007382B54DDAEBE21E0
+1E75E0AB6D309DBE53BC7BB9F95D342F51798574D70B95021FA40163A86BE6C9
+342536A5730837C522D5314B1289D9B7E4EDD108BE7F35A20AB2A16608F6F007
+6DDD702A5A9BA1325CE2C1CD020DF677872135CF04F4E4F1E9AA6B494E2BC22F
+107C331A7E80718B030A1103804D144802E3B03EF7CB083BCCDEAC7B43F1B4F5
+C1BF6016741B741CF7E12B4BF95221A72CC9F4657264771AA69C73DA1DA29102
+65D01A0E61F3024E672AFCCBE13CD0B7F54AE1418B72E357A0BABB4D03073B1D
+F4EB54F899AD4A41A9F94DC200880A0DB99D67235A2451B25F710C29A882865B
+A922E56E9FC16756014FA5CBDB1C32750BD6835A70EB715CEA19A8872041905E
+8C660BACDCA26C8247D6B3C10FA5DC240E433E479AC6AFCF57CF96697FF46BE6
+44748E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT10
+%!PS-AdobeFont-1.1: CMTT10 1.00B
+%%CreationDate: 1992 Apr 26 10:42:42
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 33 /exclam put
+dup 38 /ampersand put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 58 /colon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 95 /underscore put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-4 -235 731 800}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8232429ED8B7CF6A3D879A2D19
+38DD5C4467F9DD8C5D1A2000B3A6BF2F25629BAEC199AE8BD4BA6ED9BBF7DABF
+D0E153BAB1C17900D4FCE209622ACD19E7C74C2807D0397357ED07AB460D5204
+EB3A45B7AC4D106B7303AD8348853032A745F417943F9B4FED652B835AA49727
+A8B4117AFF1D4BCE831EB510B6851796D0BE6982B76620CB3CE0C22CACDD4593
+F244C14EEC0E5A7C4AC42392F81C01BC4257FE12AF33F4BFEA9108FF11CF9714
+4DD6EC70A2C4C1E4F328A1EB25E43525FB1E16C07E28CC359DF61F426B7D41EA
+6A0C84DD63275395A503AAE908E1C82D389FD12A21E86999799E7F24A994472E
+A10EAE77096709BE0D11AAD24A30D96E15A51D720AFB3B10D2E0AC8DC1A1204B
+E8725E00D7E3A96F9978BC19377034D93D080C4391E579C34FF9FC2379CB119F
+1E5BBEA91AE20F343C6420BE1E2BD0636B04FCCC0BEE0DC2D56D66F06DB22438
+452822CBEAF03EE9EAA8398F276EC0D92A7FB978C17805DB2F4A7DFBA56FD6AF
+8670EB364F01DE8FCAFBAF657D68C3A03112915736CEABAA8BA5C0AC25288369
+5D49BD891FABEFE8699A0AE3ED85B48ACB22229E15623399C93DE7D935734ADA
+DA7A1462C111D44AD53EA35B57E5D0B5FC0B481820E43222DB8EFCD5D30E15F9
+BA304FA879392EE0BCC0E1A61E74B3A1FC3A3D170218D7244580C7AA0DC65D19
+741FA5FE6F8CBF60250ACC27454BBF0897CA4B909C83A56672958752ED4B5E79
+E18660764F155E86F09EFA9F7685F2F5027EC85A775287B30E2069DE4E4D5712
+E7D033481A53A2702BA7542C71062173039030CF28D8B9C63B5596A9B42B33E7
+D922944A38713383D3648A4AF160A3B0C8F3379BA4372BE2E7EA49AABA75AEEE
+C5DDE1D8BF68483C3D21271280ABB91D54CC819680322EAB72E1250A760BC8DC
+FF798F2ABFC4F3539392985C4CB324B00072295FC160818BB0355FDC4F12E39B
+984826450553E3D271F03D8DC2D12A92A4D32034FD16DA13B876DF448467B625
+2BA3AEEEC60550844F5300D7FDCBE636D5951411C6F46CF31F03D3517A96309E
+02D0DDC6DFB8FFBAAE1AB34DAAFD32AA716301301AF68F407CFAC4FF8CAF758C
+C62A6765AB1CD0F3EDD3C556A10E94426AEF2D5B015C5196CE77FA94318AC24F
+D38FC8226E90A7D87B727184CE12331FDBB793ABA098017DA84073BB69A2C05A
+37469032C36588D4CE517C4161BF85BFE4B9542536FC0AE5FA535C611B45D8C9
+7A58AE692B886EDB2B1713301D0DB6701D0563A37B8E221920B53CCE01D16D53
+63631A8F7B33AFA0F30A90BF611C4DC39A9DCB4FCF0FF42E721925F0BC60BF16
+E56824DC5E93A63A391CFCE41C5F80AEE98A412E1FB82ADC61BAA39407C35FC6
+931CB24086749CFF46E389590D3B3D2583A54E812BE9298B58FC919FA109D406
+AFB5793640A22B15E6DAC8C7C7FAAC27F147412F2240E3EFBF4C675D6553F07F
+F81168EB8491F56726DDBEB8890ECBA12DE954F3317AE4A671DE95B95A6D148B
+618480E1BCB8EAEBFB0D1492A2793A5E32835F727A43117E7EDA98DD054ED263
+C8B7BF73F7F49E35A45DE9682129AD6331B66C515277B92227DC67E234BD2371
+23CFBA6B8296ACB49EA77AFFD3DE9533A55DC6ECC05A6B6B15F30CD5BCFF8C84
+A719A09266D8E29B8F98CCC9D5E154937668F3F3D3B9C38AFFAB3D807FD419DD
+4BA0B3157E588DE0560783DFC6511D870FBCFB314CFB957757B3A0471A2C6744
+F41E0A43CC33040B2C46FA81E41ED7B00E5E0246058C7E26EFD464C960DBF2CA
+9A27171503191DF989D4E2343D1260ADFCB206ECAB13DC232F59A38F577D025E
+4F9739E9BF70B8A4EFB99176D2E87DE0DCE101FEC71BFF74429999EB4A9C8C0F
+618703AAE02078BC053A65AE1FF153AA5C69952C51648335C1DD1B1A69F79F21
+57141889F9B42D0D85AB1C7334C652995AAEB04755171EA82AC78B8A96D5266E
+C2AABA7044A22BE1E194027C085CB99911A1EE878D46CC9325430B1E011699A1
+0702375B8DFBABC9B305517197056C6A475359AF85099C4F0471DC5FCD99C42C
+2A89E68F289660AC1473A67676185F8FB2993CB9E6056EF77484EE20B92BBC32
+DDCFF24C04D37C8A09C2B9DBC696A028118D45467E7EDF94BF403258B9CC2C75
+224B14C36E7C220BEFA74065A291BA3DD3935D31C97AD9B7DDF7AF408F00CAD2
+8986373E0DAF0BB340C2C3830B4A824F96A5456AD5F8EADB21198C0AF0E389ED
+BB3355104F0DB48F6E96FE9237A62ABBA0C242A1FEE0DD15372FF45CC9BE5CD3
+80FFEE76A5EFAF071152824120FDE5DA59D02F157EC7B70FD3B14CBA0A21CCAE
+973822D099D5CDC9E9A83D1A2CEC0DD015B0E9AEFC1B9880780DBB6748D58807
+A2390AC48F00B548C98550D43980F1C08867DB17EC790F988B505C58BCCB5F5A
+F457619C9600C954FEE782A6EE8E7CBD475335BFA47EFE70E3818B460E9909A0
+8F9316926028E127469FEC79AA050BDA4792C7C79F777953DCC381CCD88C35C3
+3EDA77E3502E3318974C7050D824491B9CAD67A8726F4876E0CFB48F8FBF18C2
+4C724AA2F695646B4802E7B0CDB33AA3A0E0A500656C9B5182ACFF44607C11C4
+56597A63C4A8921622C5744C5F228232B958CC9CAE2F432E22D2C1D90B498D65
+AA0A80C1DD7A66435C3EE3E96DDAD977A092638F9BC3D16A4F9D84382AC46196
+1592F1BB400B1317E8DA9E409C457F38A036E137B48B3B25ACF626C10712E886
+D6550A88C14BDCEE6703B7741FDB449A6D032D152D4720031ED0DCCF9CC50CFB
+3528BDA2FB6D8F4ED2C6D88370C47444E87F672851CC07D392BDEC111E40A8A8
+CE3C182FE3F70C081DE00FB39570100F5B1330B0D799CDC083ED1502CED0B138
+B684F8FD4AEC256FDA80C495C820AA6B2AE9F6ECFABF6186D8E5E9F096C471B1
+0AA289D9ED3092CEBC50356507A6E2936F37A2C8E1432B0CCAD35B63619E0D88
+D7136D09C96DBCE7D21EC4B54C1930A1D4D32FB81A18C2015862A5B1E13E92CC
+3036815DD571C01BB27BADBD8D25DFB4289DFA3CF5E80BEE6D8743D91B3DC524
+5CAC826A102A189B9155DA8EDD97C0711D652C4D8EC89BDDDD3571781DA4ED6D
+798D3A47099142231910838B4CFEAED178829A604B3ADD2A0A0FB675BDF5E93B
+5E63A88DD007D73D693A62A3A5FDB5B509E8C01D9C914F726FD0A8CEE8913DE7
+C7C452E98D5D89AE9D7BCFE41C6608D6CFAE5A842F577A4B168E331A5FE6C240
+A3F5549D800394AFE260F989BB71F719B339C4A3010BE64E92AB4C9B7CB1BA57
+3365470C103488D680CA6A7ABF14F161027A3EA1FA70856CE7D2466A46E11F2A
+C0CBC832798C8F0C0B7574B4A794F2DF1BFAED5DD6B94CEDCFB34461E614C589
+77FD9FBFEA2243F10D2D316B0C7C9A3B4880729A5AAF17B1755C569742AD18E3
+FF0610E65DA59ABEBCD1D1D989C572C79ACC2123F93264134DC14C0363BA251F
+C54D7C5CFB22F05EF20AC458C0DDB171B2F181EA7E7694135616BF158369B974
+4E1C05DCA91F4F8BC482C5BB993C6883D49F2B10472302899EB81593BBAF6E43
+124368EB6472726C4D0D6F76FBBE1C2D0AEC71AEBC98E54A893C0FEB4B842685
+B5334E6D20778F8636B2728BF9537B0036E2B6A56961C9BFE54AC0447D1AD425
+8F9D56F280496F95A250AA3BD2B181366F39AC9BFF4FD3E7539A610419E9AB7A
+4411FD3AC3066683D9EE4FE7D9DAB28E518D2E3F22BBDEFC361C082EA69B3F2E
+18E8B5EEF30831D34EA0355DB508A485B7BE589C7D47D379CA87ACAC062EC937
+B216010B6A1546A4D7F11539BFBF7071F314894430C8DD7B443C493069F4DBB1
+F6242A095EBC622F20CBCC187EB1E738C2D40B544539C91205A9FACC05C32CE5
+DAA5E26D390560BF86E48FE0A64FF2A2DBB4FA94E828919EE75AF914AA25094D
+A3882597B3226127CC7864433B5F157D69306E08970E55DCADE0EF5C1C98B6B7
+14DA573027200182F680FACFD6C15957800DD9B6B8D04CF707E10504D0F4D431
+8456B2553D59C9EADC4451015391D3A27D81677DCB810604BFB4BEEEF837688D
+C48D8EBBFE8D86B613D962D3D2F4AEBDB5FADA6BCB2944F69846B0889E59775C
+3EDC73E33AF475CF108BB953657ABD1008D34EAE7C88D620906928F33A4342EF
+09A3E4D131DA910E61E2D364A0F1177FB84FB04305D137089E39C91EF6AFB24C
+0099E179C2BD3E456901F86ACEBC171FB7A6FFEB8C50304CD387CA958CB2F572
+DA72B209FDF244E99EBC780B6D373E16E4C7A1E8B49AF776FCE95700E681AFE3
+E382E3F58C7C8B296007F2AA946B041E2348A01483E99D2C5F64B396CE9A7628
+4ADF6FA410E746ABD721D71833D7861AC12954137638D5686C6C66BF86A96D44
+877E99B72D8CF182F92924CCCE9C4E38E9CF4A1AC52EAB712CF27964FF0C4F3F
+B99E22452BA75BE6F6EB037F1E691B061377A7D110BCBFEE4AF0CFB7DBF56234
+78353E52FAE73DE854EC46B97E45EB7A8931252F1C5FBB513EA420528B36EB58
+F2F860C7727A1E970DE8A61378330A8FDEFDD392BBA67BBC0D8FAF82F4D03D92
+F1B5BE57CC7CCB0032FA61AEC15C7F9F8848315DE3D86EFFF9E4B1D372443A43
+BE788AA9B7201BF53258A11811A2106D1C4AF1C64482B8082FA0BF706E2ED27E
+1DADAD56C037C041075B90784B5FACE990FC206E92E886C693FDDC70518BF3E2
+259D1C8030D4803DBF47C0DD46E64890D47BF1350D089053E0EAF32A8708E382
+EF058093EACA3E7EC3A43397AECE702FA5BEB43CDADDDE29B4D1820D7AA263B3
+6D371B4117E8F204C3CFB2EEFA89C7D0756DD3EEE446DC361EF446C3C0C89B79
+015A5C260F06BACD1A145553E04D5C9E49195F7E5EE9ACC896F081D63467CB79
+258EB8736666C739255F7EB20376FE0D1180B1858A4D7DAC0A234DE94BB71131
+19FB962A16EE1458A2EB5CF48687F55BB860598EE05326442FEAA04FE2F3DD5A
+D345B46E3693CFD81A6B8CD24C7EEAE2D83964564EBEE46CA017741DEE45A287
+BB90FFC6218F3CC17DA9E160E09F173AF41856DF8B8A6885020B42ED98DA739E
+2ADE2F1F6496D234E4AF2D94D0A63F2C5FA5D0A52B33F97C9DC179ACC829EABB
+72EA5914388932F746578BABDBF2249D2BCB459C430D44939ECCBB2DAED22CA0
+9CA51DB69EE991B7300C92ECFFFF2CB4217C90DD3A599F39B491ED8D6D271FEA
+7272027D2274B099814F29215647CC2E82E5F8FB288E723B445876416C14BC61
+718942A335EFEFEDF0FFDFAB2474C81CADB452E8AD68A3A003B35197129316B7
+7AD252DD3177C80F9E2B009BA40D8A4165627B31F8676C821A473D0182F66B4D
+8A7CE5E528235C0F640E8B6882D0A8E0ADF7DF37D56B3057A4F471F380758CD2
+E20C1B00825D75B01A90FF732DAD7AFD1C7382826FA5E95EFF9A236E20069BBC
+B9143DCECF4CCA3F435FA1A7331B408B6CD5310B13BDF8572ECE1A088D95A8A5
+F54467F955518C059408177EA68A81A37574601321A58CBC90EBFE9A601559CE
+F88689A7E5A9A9E9A4803BE0E2CCFF86478C0AF4CE2D3FCE416783DC93E693A6
+921F678C5E1A9ABFF1CEB71BCC9A336DC21D087D8C3151304D3AF172206BCBF8
+A9B88899B35302BE7C466DF970D4D588CB708EE77AE0DAEA836313696A69FC03
+4E2B912ED1619095AF68471528BE50A0D8DCED44A3D7D135B513DB42EAF9DF9E
+9161DC6BFF4EF4B71B3BE448B935240456F5A9CD1179C75CC5250462C9AE7FA2
+EB531E114EBAA2E894DA25E364554334807F1B4F5978BA92ECFCFED2C6BE5DF8
+BD86BA600D6C9801504B809A550D1DA0DEFE5DBA5D5AD83B464D37586B10A58F
+7E854680BC3FBC26A79BD89BAB0F70829105E3904015FF79077C87B696FA8C8F
+B3E68E62353B14E6B688B5ECA09DA67E5C9EA0C074740C331741672FEA6CFFA3
+63F86BC6665909F4660E704B0762343CBAF05287FAA3CC9CB5DC212459D4A4F3
+96CA95CFB7CBB065AF7F959531AA9A115F9DD0E1A24A4F3D2558A8FB2914F86D
+2970E6733D766D9B6196046E05B06EF145A23DD9D9D61EAA318B07ABC66B19CE
+0AA5A70384A010F03054F49769A68EFF82F92AB35B4F29AE8255B3D2D26D7ADA
+47BDB741D8F6F47B873A205F764CC9706F6F90A48FDBB3EEDE446015788E8A2F
+FC7DC89BFBB25A792792EFA64ACDA174C3AC6339BA47AB22B713277A80863E19
+B0CD2B7DB0F2DB10DC77F4845EE026B3B78E5259CCD23275C4A553157907524B
+46277B3E7938C69E93268EED0C958B825C6A9CAEDAA432EEB111617E2DEBF69B
+CB1B1E93A6D3122A69188176C06C37D37D0CA3CBF68FEFDF8C5D7DC9F4213420
+647BAFB92E631E84F752DFECB0F9190781C89CC6C5AF8C8EB89FC99D2E5C0D87
+4C0A1C6653309326C0152A56D1DB684CCCC7CBB1AB3D44B746C1E1F5736C6129
+0BB83B38CDCB08CB1D99ED518E67E602430E295EBD3D74A221DE24F550C9A2AB
+EBC9CB12927A48D927A23B7EBF69534345E9F711604FAE309744F0704D492A56
+6C7FF26DF53652778F95252922D4CFD082A61406C5DB67B97B110BBB7534D0FC
+C350B60EE4C4198A6C711167B6CB80D9399E6F8F5C539CE36ACCAEE42645C577
+5FF5434D6C64B7C5FF327A316840065B80AB496A14C0190520DB9680ED59EC73
+21271B9216BD4E4891C704B3BF99AF049C9FC3F16B1A30D8CE91C9B4CA6F96EF
+8B6685FD625F6354AA29C7041521E83331FFC5C503DDD78B0F94D466388952AF
+00243CD57AEB28D7083572B83A44DEB241B3D8FC8B04E78BAC89E6860636A787
+462B41881F76F7C120E26E97D7D99591461304B949385C803097C154B025D2A2
+47FE716C22C3178600D4C3D15E2179C7CEBB83A52328487112DC5D3C6BAE98E8
+E31A27AC7CDCDBB00119B62F99241E65C085378D96201601A2D99ED992688C18
+43B4B456E65E9208FC4DACD9EDC41777D90D4CF069BAA1856B9906F4D8BF1A39
+F4699298D3FDF220D143158D452519DFD6DFF6F168D77DF3FF12DBB28B200E78
+2C89B73A5B398D74B23AE401B5DFD3699F9FA145C991CCDCDDDDB957394CCA88
+3B80831FE111489F989AF3C2341C71E6F5F3F7BBCCF25EB474780E00430639C4
+5393057EC069D1233C45476862C8C5390C8103A5CA9EFE091E0A5F26F42508A7
+5A3AE2D37F611EA7EA2D3FDFE6F327BFC8EC828D35007AE1B8BF2F47869D13D4
+31621DEACC951EE2FA5F452CD43E52808FE040E40556315F013C238FD16AA462
+9311A2A67118DB2727911D68BCBA1EE48B29B568B6B5832A1E9FE082B4FEBA50
+2D28E7B45FB74E2A28F0498F1AB9162B1D4E3EE101F7D4FA3843684DCF6F9F78
+05164E49C529BE42966B86B3733A354881E8981403769E3982488A81A115E122
+34B548B6863F08CEB791435DC622AA825D57CE0F52C1C3994BE8DEE39B205164
+24C8E8EC6D28CFB3641F9BA965049F29A707EC5FE399599733339031AAEC3579
+4370C70698208558AC38117C4C0E17596192F76DA1008C7366AF695AD4635CAC
+7BDBEDA7F0A6C00056140C9A9B324DAA13A2873C2DE407B97E02BE2997AA56D6
+F90FCDDCB4646B0325138D67948F9E6642F322D476A7C5B3441960D855B0758C
+A0D0C6F24CA87D5591B18CCDB179D05C6ADF116F08E02332C8A043CAA43E6E18
+7F4C53239AFB748CFF1E24B0C94A00C5C47753D36CBCFA05705B3CEEF2423868
+634A003C55D4B552A8EF530BC2FB2C2C862D0E6DB84EB99688F04D17ABD07E81
+B55B48979848EC6B28AB7643162B6076D581280D9ED83BFCFF9CF7A9F6EA8C8D
+516D9E33B7C98A431A459F76644EAE5CD609C506395B9F8E4DECCD440E393F73
+07249A3655A73561679752EAA5C47B492FEF2F244D7C5E229E2F4DE5C12F4A85
+4016B43C6692359204310CA2C247717EDB16E107A63D70F4AF676ADCF9BC81CA
+248346759737A5FEFDB136D99956DA9360F1947297AD6FBE744C218F11771A48
+F68C05C32CBD981B7BB4D9B9B476D905468CDF76BEBEB34757E6F70DAFAFAD9C
+9D3BCFD877BDB0419B0144DDF98932671FCDBB431959C23A4F0E6F6570DC7080
+2BE881644C008D082AAB94546C18F9B6B44122BA3A5D94E471286C07830D95AB
+E38E763D29ED2B539C86193015E9A8B57F342E1F3AD6B75B8A567E63F7854A18
+3C542B0073EA030150605E573D6E1265AB498BA1DB9A5903800DF81C05E668A2
+4887684EA8052DF8A2D44342A11F77EAFBC517B2F4A55CF8BDC9154B510E4219
+5E068B742E945676B6D92F0C4B5AA8FCD87ED6515B1279305D83F965A33B88FB
+3417D60840C08853E82A1C4D83DDE7E4C03708663920EF989E2643E58D87AAA7
+8C26232E9D91CF5F984B66D0AE838236FB8F34019A1D4BF1BAF5312F178787C6
+458F95BD5ECED37B0BB9207678BBB2684FD033E3CA905E89DA9C95C020F1622F
+93850D4DF12396C82BF910651E34888798E9860AE67477A557AAA1D7031F8EBD
+D5D98DE469683EC68B9DAC46852432AD47BC5A7D1FB3973CCE219E5746893FAB
+875CFDBC7E33B09B1854B8EFDFEF1243B1D10E0372A38C8A1A16C01105A68EF9
+1B0F71BF314AF986692BB6250E275FFFD766C1479EB3C3F6038AE6902D32E921
+484AEA6C9C843F5DF94D98A90B6FCE9A079050AAEF71821C5A24E8BAF69D92F9
+66706BA779D1DA8351539056BD33DD5858B8549C7E902ACF534AE39779B28761
+3F8881D3C12F47A225216F46675F27C857A148FC22693A93E3ED584D91E3FD09
+543C9703B9AFBB47B518F8085051A21B20A9A3B0242D1384C863BF00EC2F9643
+4B764F26A668FDFC712FD822A8324FB9DFB8119E5C089C8E9E83BDB1DBD8ACBD
+32B6472BCF497E72EC0BBDA3FFE637A59D7AAB19A6B5BFA951954B2DDED335BA
+CA5D5BA7E1C8ED838E25E56B3AFE75933DDB0FA8E57C35B89FE415333E5927A1
+95659E14D9C219135990F8FC43AB9B0801266EBAD8E9A48206439E06FF83F6DF
+09063ED1A1CACAA8C7F1BB31951B79EF6077218E77F81F5081829CC54BFDD277
+A7EF618D997DE5E430134DF1075F49FC2FB051920E95450A2866BDCA101DB9DE
+8180758599B203382718B836195B4FB9096CF796AA9FCC5D87432CF3CA42FD2A
+350AEFBAF9FD07B5AE1FADD43DDE0D9071DEFC22F9CA4C921CF8FCDCB79F792F
+E5584B911E88BDB6408195BE3C0D49AC9E1A53511CD12A764A66C7B8F5570F2E
+50A1F164874744E7892C59FFB125203AD2CF76FC3CC15DC0794E618695DCDBB1
+85AEF72E5205D57C69F9E43DBF87E311352C08E7114C7E96BAD2EE9D6F316731
+1582D09C1BD8728AFB61D6AFA7B3BE6C6631931BCE1C3A75C64A2E9101A1743B
+1E0FACB703FC638267180EF017A3B62E8A57816CE85A86C76397057D1ADDBE09
+5CEE774269DBC66F2DA2B8DA1E494F19E5BC8B2D6320F291A75AA52D5816246B
+8CAD6EF2CEAD7F9C87268EC57EC8BF7554B62ACCFE4049EEEB186C4D6E223525
+BF1902CCD9F5799E5626330E25A83F802FF0CBA55502E3E54FF6ABF249A2CDEA
+07DA910428C9B609F9C7D25F59123EBA0B8FD51B0C9431428E4BB19C9A1BF1B5
+EAC6B0EA56613976B8215B0C57C1F21746FC90A924B11B9F6ED31E96EA2D4AC8
+7355F9567253521F798CBA0FEA0157DD23370B9D9CA11BEDA108C1CECC23FB3A
+0D06C43261799931D450FE1F2F0222D0698B7ABBAEF3A492C2E5311BDBF90A69
+3D5A227D7357CE83C69D538BEE6D3E278D2ED8451CBBEEFD0CBA9CA4BAEF2766
+FBBFB4D8D4850827D1EE7B892B4CA3402F62C7C56AD82F98B4FF77D6D7A81E54
+4A857AAEB7EC305D9D3E1D5667FE8081B61421BBAE1BA41EB4C72406BCFCE94F
+67D0158A8F04B268DB4BCC1D54A66D32B8942A328C7954BC4DE5A04044A691D4
+68C962F8CD2592C65164AD09B9A200AFD026A9F58B0A9BBDE234C286661C883E
+C77352B384AF57A472830ACA732A5DEC378C69FD1ADA13C843213F17254E0F2B
+70093FBD2C8DBEEA05E0622471AE200C18C7047A2FAD3471EA74AD466CBB043F
+233481660E53A82E0ACE5CB67D902CC239CC5D301C8F1326A60D5676000C7E25
+D7C246BD784FC8CBEF49C789997999ACCD4255EB1976859567BFF74BFAD1F061
+4E98787561C3466748F2BE2854E6A358DC5103E9B88E7A25117E88F8237F8A34
+FEBA017BFB4C903DC402B947541913838A17E5DE2D1EFAF1F15CCB240346DAE1
+5BE983386368AEBA74C778E565433D693F62C796A976CF764FD996006D3E6608
+D3C237091D3BA601101CB2582F4A648CCDD209396C15A35B901832AD1B2C29B6
+3DBC2E26CB9DA710E3D1AD528CF40F3EBD2DB43DE3736BC636209CE3F73DD7BD
+CED3A2E4B411A89A44C9DED0292692299941313FA22FA61F3D7B84657F5BBB2B
+F90C0A307A0718638E7F3A0735860676E6E5EEFAAF9FABFF9E72E97FB05B6EDC
+43CAA502B780CADBD2509E9B57D5C51093AC6C3035236F7579876C5ED068843B
+67DECBB0CC54A1FB30D51D77C2BDD933D96D3B37B7E11720232F88137372084E
+3954474283C981BD462B91D5AEEC58E54B3B9A85DAD0B658C0E2C88FA95CCAAB
+084E9A21EA86BCF6A313A2834D5A20613763B5F305DBA39EBADCE93E869DDC7B
+44F00D724D094650ABAB3B1243D289DFAE286314EBFB092879C6666360F55AE7
+2DC5769B01E80088430D9760E09AEC8CA4FE7CFC4B5B1B43551208AFC96BA199
+E8DE60B041C4E614911B024A85005BA0DB9574596571CAC903A485E5F79AA82A
+51832F2CCD416A4BDFF6F518825181B12D4091FF3A4C629924CDA2D766318D24
+9F617D93F8FE0BAC0BE04BF912036BF5146553C5CFA34B1EEA491A438D868377
+E9C9A642FD08578A45EC71D0D5712AB7EAABA82C881D57CC547D01E0DCF3F38F
+40228284167DB284531ECEE0992C5E75118EEC82A00D2FB42AACD54849C15137
+E0964AFB32655134D3505B99160BE5E2A903EE233A4DDECEB9F5334B72BD223A
+0F9340112D948AA1B00C5EE637177CF604D3739914F710E300AEEE7280D6A681
+BDEB224E3CE8253D68E63DEFA72031F11B1FB6D3E66FD72F2E692FEC8AF635D5
+6ECFD148B15443F4A2D443CD7B23A2099C43C578757D42FE22CCC6952DAD24A4
+BCD01F92A8C37B15DC7E58072B963CAC34E1CFD05F2D725F94DF1825DFF74F0C
+99D8CE840797103714B75B48F5CE2E9FEE2C80F4E874DA89E1D53A9A7D1C4585
+12DC8CE1CAEEF4C86E310E7E1A8A41BAA71E52203DA5859E31AB531D9D9A2AB5
+FF1D828DD7D804C2BCD640B659E26A8507A5F29ECFF2F6A1A543A2E4CF6186B9
+0A96A017EB29B2856E68873C01519C9AFBEB524EBF47AB7FC7C9EB7CD1B6BED3
+88DE1B6384915F336D53FA6E679528CB3D189FAE7185F9912124729A6E07A9BE
+9B827D23B7899030C0834C3F3C5D9E9983CFA8445098A069235BA0D5523DEC29
+A41C8E27BDE69C7B66BBD582C3BE4B61B48AD8FCFA8721110AD2103F1ACC110B
+A0963A78144CAC6729B230CAB7BFD5B4F71401D5A0558A2060D044DA82427BB3
+A5A5FD764AE783AB473B67BDB104B39DCE37952EF8DECB4B556BC6086BE3C604
+CAE45B4F0AD2E45AB051A7B3CADC9428D90B618CD9928D0ED1110D6394062A17
+45105218010601207776E6F2EF067081741971E24EA51B6753C06C50129AEE37
+9BD89DC33E5D4F39BB816461C063E0B0C88D0C04CAB393B7A8904F6CA312F7E8
+3276B4B96EBC9267CA51B9DEC2AD33B42EF2E19AE7F7DD471B58A04690475A93
+E1CF6BFFBD169DC3023C068868A3778C3BD72AF24E29476D35C97BADBE721C3A
+C397A1C9E0508C40B8A274E52B91E3461A6A68D89DDA315EBE79972091268BA9
+86D80CD9467665A635FD66A54807EBD754B4A705159A9BAB2B59C315C12CBB9A
+23D712C9F8B250F8A728892AAB070DE9C124C99E486468CC8EFC48C13D168E90
+B73A0CB975472DDA7558420B0ECCABE29773E1BA876536326B93D7DB919615EC
+2B83C19021D2E60B9C8F4E4B54344074F4C925AD4DD94DE09EF224641BCE4453
+9813793A0329A834D7520B931F6E4CDFD71F5F63083DECBAFE82FEEAD56D3257
+B57E91D887A7EC752F9051A5142575BB27655A01EEBBA06DE22FC1DCAD627958
+3AC1F304C409E84E07F5F7534DAD6FDF210D04166A61E4ECE7BDEB48FE13A186
+CE4612F1AC0EF77ECA1D637CEF3C915F0BD56E557F009E54C6086A3DE51F81CA
+0DAB98FADDAD6514E78036927F512BDAA8316334DE219F1B407794BDF1DD718C
+3F8E4CEEC9199809EAB99BDA85C31D644C2D00093F2765ECEA1F3A703D89ECEF
+B46CEFF2DFF6C0A97548032BC0D10420F39E52D46F091E874D10D1DA7E932CE5
+7CEA2B77E5FD1FF43460BA2218983A1B45BF625BCD4FACEF81A774FC0A642381
+245DA2BC1D1A8D7A227D9CD0AA495ED471B1DC4EF9DCC20F2B6C8324C316E5AB
+5F5B5A99C000AB9EBCE06493AAA37DA1352D551DB90F249CEE335A395CD054AB
+551ACD5619C7BD3F24D149B6D45F6DF0D0DA46CCF6F31B416B533FA888630317
+97465939D842CCCBDB9AD1546321DC0E7CE0F03325D98C2B8BD267E1988DA78B
+04D8AF1F1F46E606CF7309D1CEC47CD939E698533FC0CDA1A2B0D0EF2AC0A0CC
+E96BBAEAA7B58CDD8D964F40CCD1E53E5214B4DB702743DEC9646A0D34CFD197
+D3E9D15E749829793127DBC1D6FA5F27276D97858132E95E30854D692A9C01F3
+E47F627918C3BC43DFB8C1C72B90A6BE0994D6CCF0DB279362BF19F7D278F1B6
+2ECDD5E7B3D4A61B047B4A19118FF7EA20FA0983771CD2B5FE244AF7D5ECD345
+A88199ADCC8F95A76B461FA70E01468BCDE42804EEC74A4DDE54D22994792E66
+A9EEFC2F756BDD20DCCA6F03CAE26B2A399880AC7ABEBE1046DB8B80E04AE813
+701B0FB4E10C4B851E60CE4335CFF5027773008227B09E03DB9E624D77C4A6D8
+041C184BD122E4650D8D3DD6966B8572919C750EBCDCE7690CF2D9A01B9CFFEB
+33E9D2939700266C6454A419FF58DBBB6DE4B394613E80E9C4FF50948DE87582
+8C335364A7BE6636CCE9F9C5446DF9EA6F65E22EC85998E23D5082AD88F91709
+C3EF0926F73E8347C46D03EF4FCDBD3EFD7219014D864DC2AA0625696B36D3FA
+4DA6D12D0C490104D68478D1C52ABC2E575ABC307680A0B2BDE36017737B1D5A
+CB1D5147E926BD04F361DFB26E703501C3C291FA3F9FF6BA54D89738112D4CAC
+A9146A4BD9397AA396DC081F3C5B5E20C4724AEC4A2769DBADBC3EA499E7292B
+29D311E99CA8BE1A140AB324D144E846553F96D30E55B0E58D7E0B485765109E
+75865F0A47BA77036D1A08D1EA2CC7FF594D590058E6882E4DBBF64B2C0D9BC2
+7DB8AB9EBC0AC73248E13A6C14AC254327BA455FF916708BFF1F65894A80F376
+CB5F3392B60870FE1DE1065B4A514BAFC6EF0237207AB285F0A3B394ABF856ED
+7430366CB759444E84995E7FC415F446C16C73AAA7CCDA2EB309BD2832E2F560
+F6DB9B63B6855CCFF00CC983E83CBC13F9ADDFB2CCF3B18668456799ADAB8C51
+AAAD548E9724EFD0822FA798F200C4EE8C78071AC4144E8080D15916AF5C92FF
+1E47DD4FF510A4F43D4E93155DD123531A527383F21FB6C8D0C952F3B32712A5
+3A103504E3E416CED0D37F51036B74BE7CDD68E0A9394381BD4043A9BB22B25E
+3A9F42BC834EF70221FEA3329916BD96F55A402420777CCE28AAA3019F439822
+7640442CA7AA88CF8D7E8AE3963FE92949DF500C9E023C17C2ACBB0A164DB19E
+3F0690E52AC24E778A8BCAD5085E0057E3ABC08D9A2E158E4FBEA6B379C9AA88
+9A806234C7522D73B43922222D5D09A799A907C7B593BCCCD1F0D05D485D962A
+DB0AA61FCDFEA01458EF1DB02A4C07BF811318DF86362890255798CD2290E4A0
+4677195D1F6E15A076D1A42B49ECC603DFE619C0F7FA940A0EBE1E21E3D2E1CE
+B9E167E0974E72852EB551F96087265581396487F30B2A98B17E7F8B0ABBEA04
+D2A749F5DC7DD1F824C1D2472D507589EC40D853ABB8F54A5FFAAD0ED68698F7
+7D5587D1953F061429D394A717BE6A946ACC9DAB1A859D2A7BB74416A7FB843C
+65A1647ED38F12151BABB90E8790A932A9DBA7CEB1B047B8F3F125335956192A
+9C0FA8A679BF911FD357897183B145471E83A9E9DA12CE082ED09939DD3B7F1C
+240BE7BBA745608D786A2A6E05B62601BEE3B3D9A5311A90CDDD5DEB21941453
+554C5F6698A18522D3334BC9161E5D06912B98A4485F628013B28D812B3F630F
+B0AEE00E68E1D710F9B2EE0EB10E32A36642F77835AAFEE5A27FD7272747BA5B
+FFD417BC629B7AC91F731CD14D942FDBAE34B6B9F2D6D5863DBD0ED6D78C9528
+40832428C9D07277A8296BBEA278C59B8CA93925736EB35B6CA7FB75D1A8D01B
+2CA7EDB6F5F09134C157D7823260301CDA6055E004A0C68C02C68BF985691FB7
+57B9AC240314D0AA37FADD5D045F554932E9438EB5845985A6F794A47AA6AFAA
+6D7FA2752048D71849EF44AD99A50AAB2296E0A00A0FDC2CF83BA78A914932D2
+D3E6E03A7365CD38591DB38A25D61464443E876D4510D7BF3BB3E490097B729E
+558B7D6BE52935D7B2A209F36740EB25EACBEE591F04241A347FF3BA1FD14813
+35693D93EC621718E71B5D10F2A9BF05DCDD6C18BCD2ACDCDDB598171C7ECB28
+99CBAE6AEAA6D3D71F21DC305E0E3DD15171B741D8EF1EAD4BF0212E74124949
+89BBF3FE0D8FF50803EBABE62A78A4078B99F2CEB6836B323482D381F637E783
+5FB65F471D17FAC1D2E69C0484E8DAA28E850C423D4088E41D14655B50ED5BB8
+235132E2C2C04CCF3686385A21DD38F01E6A21E18B3BA2CFA91E18603B9D113C
+B0A8753AF7A7E48E2DCAFFEAB1F336FD5153FD22EBAAF3160C670AB55CE40F5E
+C70B95E9C49F825111243BF8CAEC06B8CE6E039825BCA6B2B8CC0CB85795CD4E
+FC4628FD1E02A73B5392B709086CEE157DA571625454827CF1F776CD49806CFB
+A8E1F2B40E6AB5E86982EE3E728A163696E432B0CF0CC25AF60DCBB7A766519F
+49BA9308EC95FC81617310330F3E4D3EF29FBE9A7A45B1BF181B67B4700FE341
+657EEB26CEE02CDDA3AC0326DCEE647F207747A2C458F7950E1C91C04265192B
+BD344CA75F591B6634D5FC6B9DB33BF91E1304C3EFBB645EC375945F7A5676A0
+EE54573A6E75C5F34A28917F0B73E1860E6E135E661F8E47AA2E0640F7849282
+4BBA5C567A6FDEFB0C88ECBC799F452EBE60C4E1450C64DF88
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT9
+%!PS-AdobeFont-1.1: CMTT9 1.0
+%%CreationDate: 1991 Aug 20 16:46:24
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT9) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT9 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 33 /exclam put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 89 /Y put
+dup 95 /underscore put
+dup 96 /quoteleft put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-6 -233 542 698}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8232429ED8B7CF6A3D879A2D1E
+2931CE5F5D18C658602059F07BE66E6EFC9239D7AB2FB8A4CBD41675B8ECF279
+650C29E53B14AC0E392A664848C1844B1CECBB2D5CFB72D0916B675C9A9A1E35
+F12696A6F628473C604A95376468E06E295AD6F76CEB939D94113532050B9D5A
+D2F41A9EFB9424D986612313B89EFE9C8A71313340B248F6853B1EDBF02B7F9E
+F447220FE131D7D54CFB8AA1281DBAEA73E665BACB1F164552CC0CEDB63BD4B1
+4A9AE8AC6FA02242DBE8DA46B64B6BFC11762F0784F216FC8B9120D688D1705A
+438B14F5E5DEAF2A98408B3B64620DE3732A4DAE6D08D5D97E34C75DAE19EABD
+BA0796165C1151BCBFB1DF8D29A63A8300DBDB9E3323CB82D0337598B83F4F2B
+A97CF5196D4D1CEC1EDB8966E548C0D9C194C932319610FB43EA1B86322FE641
+AB48770FF13BD475A7267E142388563D1A400419C585B22A9886074687BEDF74
+D905BE8EE440BA2ABF28EAB673399B7F129B9729DD5564C681954621903B84BB
+CAF89AC5ADB2932472DF29ADA2BDBDB4D05F65F28F5F4C529613D61858E0074A
+082A852710A62A147C966F2B85B51B0BE85F11D2057C66FDD61F6C5755367980
+9F4DE680601D4DA41B46F8D2148450000413C27AA39B586B74B977B25F0FD3C0
+4BA1EBFAFDBEC531EA1210365091671CE3C86A6D4BC591C37DCC02570042575A
+9D24252D6E01A8603753934D7EA5CAC1BE4E5AD2BA047DE8F3983B23A8A1511F
+B08D373B69E5076CE4300137B8805EBCC0AAB89BBB312A77835795E3C069322D
+42C893A30AD739E2BDD299679B158F7493764F2321E3965141B5ED1C6F4765ED
+F46D391A646B30C90002B1C461AEE79E5F094CACCA656CEA3DB921CC5205F328
+A2C69F817061D6C60B121EEE844CA5008F23DF08DEE1AB6AF2B746CD6E54DB0D
+7578BC281A213CA685BAE7F59D8233078F2AE84F46E0A956CF46B823383DFE98
+3053CBDC7BF758224E2B7AB3AA346470D6BB661C2BA18FFBF69E6CA3F7D81FFA
+BC6B3D5EBE1BE6E23F9E5DA6555BE1A4A9346B91A043E4F0AAE6747461BD2F9F
+AC3A3A54E5520483116FE1F025B105C086A73BE488FEF52A29E8C7E7AA77A4E5
+5031A9DB1DA80A83D54DB1D59D3B5EE784BE3D9ADFF21144411591342AF40B6F
+2F91E0E6FFE068671E1B08B0DC54011B0074E317B65C1BA6666B2856A344C3D3
+3E37C1C9449B82820CD46030195305F03B4E8F8285F7E228BECB6933B19F8701
+F333FAB61500BDA29524201A40265B998733644D29A80A656ED429D5A4E630D5
+29052EBD3D2A83C5A71CE20907FC70FF3C47BA5E0C8586FE92EC07D3886FCF51
+9D3D5F71BD954F77DCC28D5D0E53066F2098ED2806839464CE773A99D4830751
+C1C3BE01DBE2B04AC5DC088C879C0D54AF0B2E2F773EE426EB4DFFC521E51C54
+FF289E480473452C77268DE9CFF7ED89E65C84E555143DAE72C27048292AAD3C
+6C4B315ABEDB89827554587A097855EEC12CBAA1CA62D9ECFD8A612E846FD623
+1DD16F5E68324783276EB661DC4E99179BB3EAD52088369A49C7862A9B254E5C
+E8F38D4B9E8E7764223B1475B75EB4B9EBA426051C40AABE87A439EB9E3EDCB2
+AE6D7518112B20F3B3F332AD4C89AF0C7C13BB18A08D3F4B3AA008FF9A93D420
+77163589B635E55D89520B114DFC4F32114DE4DC53A132A64DF452F62FA3F1FB
+CFE81D5E4749883A21217FAAF0AD5CFFBBEB67AF1402FC5B3252B301929C903C
+D93349A52CA0AABFD983E3D3CC94A5F4AE872170DF37C9B20EAB2F23134957B3
+CBB05EFF103A68658844D7BFB92A9C972103E01001D5989912BA7212A9105898
+D16B26571644AF88DD990AA52E4787E6348B194B83A56C60ED3DA4AA66E68CCB
+A2F91F0D8689C21B06C7CCC77F3C28A95BCE69288B472839951A02E9D1C2C5D4
+1EF4CA6B17E2E8D2968EA2A0B2628582464FC912F6DDC4A0015A9A4644CE91D4
+C8BF97A641635F16C4EC7BED75F22A03AA45629DB6C9CB42B0FD6A034A92441F
+2037ECBF67CF85E25038104FC8D6C894770D5DB3DBDD269B18D88D2DDA88E7AD
+B39604C36301D0DC9CBD2AF4D36908E5743450AB4971615452D96BF810A04086
+E1E9F0675D2026D14FB7163689D19382C68C98A20125CFFDC0D133448318CA22
+290D23481D9B503F1AF1AFB341DA948DB8B7266A474B72338F918536BFA76FD0
+43D9237B7CE497AEBE60D4B7EABA6CBCCB5295C5DFE3ACF09734DA5B63F746EE
+CCBFB54C4AAB75D24CE3BA2B4E6B4F0D7C712C33629CA3E7F18E2B57A1098D51
+AC0A956644F2316A3FE8A078717E909980F1BC0E0C514CD3D58037D6F4335A78
+0BD111FCA69096D200458AB55083888003BEE7FE70880D09FB947A1D854329ED
+7C45FA2747B84380C93B9665A35DBB08C00046996934D0070E772FF423F2508F
+F5AEB11CDDDB6E1A54ABEE54E720F6AE401C3E7136AF3FC1A0CECFFB96E99DD7
+1ACA8732FAC7B1E92A95104E99989DCEBA2C76E87F5E976601F14F615943F2E2
+350745990A2D5241AB9F743CB4A8BC6ACB2FB703C606182EAB8A4AEC7AF16F14
+D8B36E0B2577B3F7ABFF4B71FCD9636FFAAC2E34ACCFECD79FB74C4EE9FCD66C
+DC84BBE31AFEEBD28215C1771F96C55D255A5C20F93AD960574892BA567F7107
+94F0734AFF5D249E50AABFB3EE42A2C28C5F3DDBDEEE4C5CAACFEC0181B87A94
+39557358075C2586EECEE01EBC62F29FDFDEB38AE2728741C1C87B5EE7588BFE
+9C257221748805D1301D99CAA67536CD71BAA8B2D835A2886BDC92087A6B5AE7
+9F2CA4B28D7E5C57DED36D21CDC5860459CF03702950086E240C082E3E7EC824
+17A0DB2D9D1B1E9729DDB521E47DBF11B48406139AB46144DD977E6B02E94D03
+D8336D89244413158DD4073AD369FB3D16D1E6B675DE75C4AE8EC0DD5B6EA77F
+FB7B6D8CE18DDD01ABF50B75DC1ACAC539EC89A20103E33543AF9AE46AE5A96A
+F892785BC4B2A4A3BB56B4EA9D6293C3B75D4246F50759714B051961DCE5A09D
+5270FB2A5B5D7B6BC4B8317D66D7780DAEEE79E3B85FCB2A9DE707ADC4538870
+2B3B2F0A08B6E79A4E26AC93E88E6DAC77923682467F653ECBC01F0E9419DC47
+BB3857BC092449E22657A5D0024E6E60B81E425EB4ECA0DAE9ADF876514CD7C3
+225185A1203C805FCAB8BCC2D02D77A94522D764065015B19499ED7A9A8F2C0D
+35F8C0E6F1DF3848A3488AAF0EF006D18F817A46AB9568AEDD38607446CEFB67
+CBA89862A9815483D60EB123C81D7630EBF27481929277A35A398A9E5F703814
+435AAFEBD9515DC91F8EED38571FFF8DD9114C022DA9954016BE25DEBB383F02
+A2E92AC384F77B278AA616D2550325A9F1FD6C25BADEB2806763371EE5F2055B
+2606429FABF51C78C3B965B0246637B513F3DD9EDF61BDBDD06BC9135364D883
+6AF3A482D066F8D8910ABD83B19DD34BE3541E2B867D235933D09FAE575E0692
+CCD9D399B7D8C9B0C3250EF58E18A20A432BB16F47A93EA2BE3BE4C3AFD13780
+2B41551680A13F92E01189D12D38387577C91AAE6C1067333D41A0A985091F7A
+4661BAC5497B811E396B3579D3EB35F4673CBE4E5E55DEF7372860F2593C9286
+B1965B4FA0B10233E8390CD5E6272EDACDD09D7A017B9D03EE8DCE5218F689C5
+57AF8D370D887A6B7030A78C1A9711594DBC0256B19D953F5B4B5860019C3FFC
+063F5B0F912ACA8B663EF9A47165D0A2578BE49B42A8CBBC98362478C2BF2D60
+8343B0DE641424967ECA84CBD27F43DB6E8CD286BB7A831A7F6308A07F236F04
+AD81E8CF07FF25140738162B248428D826826613D22F84137203F356C86DF60A
+2035C0647CA1EA727B958E2EDC4033E5EE7836FA4AF81A21F7EFA31DE6E0B2B1
+6FA8013BCD66CB43481848615A5C5D77B318C2C8672C4932FAA087E2EE079E06
+2C2834C8B69A8F97EE702329CFC79CE820D2EDB7938BF0DF4FD072A3948D4DBB
+A9AED8F7AB0FCC4B1B5D72CB08B54EE40BAD14CA6B4C00105C5EA1154EC12969
+A0F9ABE9640410B6741B683ABC990A9819C6E6C63D20DA430DC30167A4172CE8
+12911D075422037A31150C7C03EFE10F75139123A682DF71B31943CAE598CADA
+8A0274E4AC9A96AF4F55CACFBB7BE128534ED466E57818D6EFADAF7B1543CEAA
+3C717A61D23601C64E7356F6E7AC85F1B80C69CCE88D92370BA2D7BA0C17457A
+028249073BA350C25D99B2063126C2927DECB77C09F3588EBE957F62A630629A
+9FA2BF8295717FBFDA4325E2E1CBD227A499D911DBADFBDD441027760DB16310
+CE499179586DFD46C0DF1C291CB71B631522922E33DA4AAC3FA3126A4EF6D763
+5879C3BF9C29606D96D64F7657201D59050B5D95A317C6A1CE3D49388702FD6D
+CD855BA5A333B4D173BA4576A8DDE8B627A4D5F33AC6674AE60606CA3766547A
+27F42C730EEC5CA3D8F17789674C2527C2C363E3B1FD1A99C908E875642FC7FE
+61514A8368C9FA4A3445C842D038FDE3DC0409887900E877FEA22852D5DD806E
+868FB613E08ECE8C93DCF57C59A988F3BED0E848A487B2C1E3A193AA4AC62E15
+F7C64BA60C4B1189374E6E21469E88719BA6BD998FA8C1D8D9C1C4F63B996387
+A9ED7B34BCCBB2EB980BA2411380BDF8B51427CF34E1FC0FBC39F572CCD98880
+2F24D61819D0FB790B7B0642715E85B3C058368FC8C09FCDA4CC583842690FC5
+64700294426BFE2056918071B59F12ADCAB74DBE8AC8BB43452745AA8468979F
+852D4F66B6A104EDB2336D3840BFF5C7105BA6D0D1C504509065CF637C501077
+ECC383C89EF51BE37D0F0463CBD5F54DD994DB686D9FA51106A2B12361ABD14F
+9544F2A631EC1B66A57C4B7C290926B4546109396761BD0E5C2F73114CBE1F8C
+0819C7D3854C55834FD1C75A81E002300E06F8287C5505B27FE88F73F7206CEC
+79EDACBC6D025F953DCA6066F77AF2548CD6004BF804C2D62C0C195D02ABDBB9
+8ACD9105A4A986F7103B321DB9E8D49620FCDCAAD62AB25ED47F17FBC6976622
+4D895CF83682B28C2C795E4BBE01BEB2A520F09E36D268460685C0A97B4BA4AA
+057ED81343B6552D2AD54384C7D0899B75D52F9AD58030F823D57E751F68FA56
+404461426F0E503AC14EA99ECD8D7E32CDD81321E2ABBE7F9F0B0A7319F312CE
+53A625ACFB5FE70696017EE7348BF0647B3029B86272DAE4618ED4EA2A1BC804
+D170536E8CB2C23D9263AE80BA4A88498D6EDE73DF1081CCD1A363E345CB8027
+029D6383C0F9D957A4269AFA79A73188953B86C3A68172FD29CB4CD29E8F3419
+D88E1548AD0684C23A58BBA6632069DBFF668EC477E18CA7FDD024CDA3D51E68
+A0D420FCD3EEA5C4AC6D21DBE493D00C66633CD730BD58C67AB8E7FD52DC23BF
+4C37661446DEAD71E2E52BD5FAC3B99EA404ACFFDC65813E06F230C0B384BFAB
+A7CDE6911DA64341429079D80DA1E24768593BA22BA41DFF340E4709076CF152
+7CA693E23F6AC1D3836C5EDDEF5E6CE30BDE054040940F6F39754E206B7BB1F8
+ECF09B6F609475D4BA77D6D7B23CC31D251CBAF7F95A874F9E7F7BD2FEFBEC8D
+0FFACDF6D5D6FC41D9E1FC6058DC34C10E24E1BB54D8611938B05D53A2817028
+A11E29AF5166E5E74D3C2D456C5398C9035BA52063B9A7B9CE202A494D424767
+62A0F5049F948049AAFC9BE52C28D6E12515D0550C4ADFA29EF3E9EFABA13903
+E71F7D7C637A63651B7F234F4EE5A34DFCDB407D0627E3EF7ACEF758308A69E5
+50305B8F66091C8E6680B91824E49ACB06847411C00451579A733CA4C3976DC7
+AFE2B063088CE25D2DEE5A447C606B87A9A27456B2C35CC6777530CCA822BC30
+5C666C3904B5FEFDA755CF30B88E26EAB93AF4B74618E5D6587BBB22F1469F72
+975DCD2A5E35D127A12CC1E97B6DD2AC710139975B8C3E08F64EAAFA930A06A8
+0772685C95AA7AA98DE6A6E4D5F86E4B1677ADFA88A847A3B2EE800DBDB11E2D
+750E08D1E3CB53591611B4FE08403CAC333A189B6151A8F35BD523E2E9E5B126
+13ADA073AB8D72532610332CA20D95DBD530F1E980B19C566F5597F619569881
+5536D88AEFB254E8329558F8B16CED19760E8ED9C585050F5BB661B4CA22271B
+71F8DA52029E4C79926C2D6BCB468A58FA71C189133028B86C4B0FA26E7E5801
+2FD1D40C307D5146B5D262F28C6F939948B26FB104BBEFF7EF72D9DF5930F8CD
+27A3CC0A2C62CFCA8420760D42BAA5126EAC1E2C8BFC899FBFDF25B2C1C26B13
+77288FC0CB0F3C40248D76647D87321EEC4D2A9020BEE2173B34111312D2A9D9
+2CB689630E12E723C9687FB697BA74A8E0E5D833F2732DFB33FADFE822F6A1F5
+8E5533E00D13212C04B217BD881B4B72948E22F7CBA51FF94F6B2A6FE282804E
+CEB6C5A3E534CC0C8B635A369A845CCA9EBFD6BE02A28AAD2D1011593510D3BB
+F12D29B181AE7BE8A22A3991C205C8C2FA10E1E46770C5F5B617FED2188C9613
+C4D775BEAED00511E2FEB3AC8CE6E02E09AACD6CEC68F737F8AF4E70AE271326
+07D8690259EB6B55C2DE83E06C36EDDA33281AE5D23A3FC31922461794192B98
+E4DB6CC9985362B428AC91A586FE0D162B32792827FC46B5161751DBDA9C0759
+38D30AFF7940C0A6B75F66299466BC0DDFC4B64B50F07003769381C18DABB356
+F968002F702805CEBA3EFB2C5BBFFD085054A9633D12F95C0DEB6CA39FA83FC1
+6A1931DD4CAEAB1AEFFE5C21632182461229C3E883CDC51EA48CF4227C6E9B3F
+539F771F4D9860A232854C4CB3FEB7F7EB57719846C26E3D6C42F7AEF4EEB92B
+B5F24C7BBE00AF36DFA41979F771B9EC333F7DE53E267C443E2B6EF05A7965FF
+48422C4E5E2CDDE425F7FB2F4417902D318236CF4B8F9086F9E92BAACCD9C109
+FCFBD4AA44F77255F12883BB8A5EC580F7C2AC6739C8A56A9472D7F38C6CAB3C
+002F651FBC29B3BB3A4E8E5060EFF4978CE1DBE7118D11541266244BB8B0D071
+AE90F9785A69DD69D2809D5C81D11DF1A5CA497F8D1EE4DC16D9B2FD74AFFF80
+BF3AFEBCAD350FBF818FD5DF807E7DCF7A12580EA796809C3BB5F913C8A38C34
+D5C6A6A63ABD40DCA3FFB2702E8D11CD4510E972562BF284E5901B0BD2B7D41E
+D75E805263EE635A65B636BE87EBDAD18C7D111D6B5363030E16C30823F33734
+5407FC6E1E7DF426E3515C2A7236977C999D4DEF876B3F8FB9E7929B7AD345DB
+DCA8C9532C820123B6785EB6BDD032D919E3D250F9799ED5342AB15D27033425
+3A9B1EBA03C494EFD3FAACF3775F71DF3458D37364083F3B433BFC45EC2CC6E1
+E93E1A54738D31B9F087D3B0C4CA876D4ED6C26954591CB919F444E15ECD4B80
+65779A66F93FE87D81E14E6873B74D3FC5FD32E75C3634929FB859E33CA73B15
+3BE923B5069730D1CC6350FD2D2A9B5E86AE2BA44327EB9DEB6AB51C2800E069
+D691ED370C674A94AE640264481B48DFB6A4BFFC93212CAA4E174330F00F54C2
+9CCFB212A5E34B75CFBFC939C1EEF11D059563C443108E69D7D666AC77F98905
+51B5DAAA95DD0E10BA2B345B3EAC4B93D602EAAF06B744D5E22CD441A96BE81C
+F6E1110BB351F68804CA635B5CE83B4B289EB70217F27C5235073D71F3C3092F
+0560DE92465328D5AC4D13CE1CB14F8F60C22CC6CF3BF9D8EAB6335156BC7E4B
+9C35F679ACC52F62224418A41C7FBE1C8B8FA8B32457B7078958D38DCAE54FEE
+7202FD597F2BF65E7BC02059B01C758DD1CFD687AB882E176D610E78D0B33B85
+4B7E8EDF2BEDD905FB492A458E68667F4F7B675FB43244F41479A20481BB9F92
+D3180DFCFE49A033F8AF5CDD7F06C765F2BDD32F71DD6049D176439EB7B481B9
+7A9BF688CF9913EAD44BA2F646324CE039C990D4CE556E9436697D46BDDEF99F
+69F17A34E42AB3800D4218CFAD45F79BB2748107D13DEEE5D4C26A28ABA25F1C
+159F35DEEFBEE58FF7A026E834A3FC3D1134CC4740F4A595C846C8DD1DE99141
+DED145BBF248AD51667729727F37C01541C4B5345709C08718800F7B9E22E6F6
+A0E9C38A582E888BAC122AA32DACCC8865CFAF112FE17405B5A8BD889B3F7BBA
+85E34A0B06EABCE385DA3EDF0796BBC40DB61B0B7217D11DEFD02AAAB1B76C20
+B7E97865890D832F1E400B62F4B1AC174A356FAB6CEE5DC43546F1E8F571D235
+54688559EEFB1E6DCBFF235740EEA1A6689007768560B509E02C0762F19F7071
+BD8C5A83078FA6FD8C56BC6AA798323D55FCEF854D2A7AC1F5B3FA1BFF23F42E
+5D30799199965A3BA993FA16F0E065165D49AE6A2ACC5EC009AEF48E9D8B53A2
+515187C0C606041B9D5BE31DDBA76E58D20ADD185A5238DD780ED252A1B764D4
+951E46CCA0B8C9973901AFA4BEF380A19F381D69AD7C15240C79271D387DF1DA
+5729ED42C61DBCF8E6C7277989E1181803CB06732B579B623429841E422ADDAD
+DC4840C4A3B98DF994E28AD762DE2E0978AE008FEC0F33A28EFA21FE168D2ED4
+4DBC2A72464C69223EF0A356DBCD215A52601E859E84D40550D981BB61B58125
+9A640C678083FFCD5C193AC8FB394169118C06186BE9B20DA71D5A81CCEE9847
+42CDB4020E1280D7BE3B22159FA847DC9B0B29AC03F91C0506AE2D4C8D6676AD
+ABD176CC24203C831D076D50A2768D9E506B508FAC18FA7064CCFA13E0CB42D6
+6DDC79D2D51AD9E91997B31DD950654582BCD39D91A74887EE5CACCFBB01850F
+F2738B29450075C011E3840E2EEA397D06E30713279E2B65CF239A840C04EED5
+BFF488243425F37756F39B2AC5B602B4284F5443BEFC6EC98C5FB95A5C05F66F
+528346D76722F6D1530AB759E37D8AC768B682F51C3078BC325EC0F688106DFE
+8AF007DF934618512A23329540C52C8E56D8D5191D72D6A58C261100194E48A5
+8661CA6928B66E62CF2BE53BDA499578C9CA4F20FCDDCCDE61026C49743DEA57
+A3BBA9C3582A004F93581AD581593DC194AB3D45960D35670AA73A5220381904
+771AAA453EDE171156E13ADD6C4B8BFF66910235ABF22A87C2CC7E79B63F0AAE
+78FE2B546A1DF4CEEC8C987002A4C230E8D2501F32C47F5F5E027FE637EE3DB4
+9A47DA22B0286B0CF9FFBBC9D4ED7D7697E0AAF84C38E0F327CA5B74A5ECB440
+DB42D69D2A97B53738BE90F08138841F581BAF1D438175087E4008B32E824FD5
+C31E46DF9E2056C0D80FEF3F8B9F56440381ADF5ABA755B9DE58C0D1CB8CF890
+3DBD5A424FE27479A408EB385FA34089C261F6AA5712D912E8679C410A8BF1C6
+19238846CCDA709A239A3210A6838EA1F93669C53522CF56680AAF6799912EAB
+0FFCE8594F7AFFC341C240B5490A7EADD8D1288564AABCEC130B3E605F350A5A
+1BF12FA3B1691E00414762C8C8343C650448A8FA989992BD833723682DAB2C06
+A06BFB7D3311D391D2F1051A6E107CFDC5482178D80DACF1A2FC7A163C4BCE8A
+3BA0E512A5399D1CAEB43BBE461803AD8F112D32180206932083A6E96E6CC3CE
+8DA9BE84D7A5D53270A18DB1FC18D77568140A3116630486614FAB4FA0AFF7FF
+26C570B3D7A65A91E909B73781697012F0640F43B62F8E333AC52E36F04E0E96
+B377F1B9DA14E951A5CB5CFADF18BA0BFDC6FBF1EEF3A7520C8F3E4D6B33B1A3
+9B3551BBCFB75D35F99A5E1AE419902BE382041E3BBD9FA0787A9C773102A231
+491755925C3A7FBE0038351C0AAB90BDE25EFD48FFE6C09FA98084D2588B2691
+B80B73C96541FCC16A458434E1D1C22C5FEB10818D10CCF1A6D573427DF58841
+BA7EBD498497FD397758228E00C530A5662EA2725BCA23ACF58A6A42A51A6780
+8E20EBEE11C935C141776FC91B695A2728ED6569383C358001A43DC019135F90
+D6C890589C3D9045654F9C6163C643C35BF774024D23C0D906EA34DC30093BFB
+EBCDF58EA22D61532F1C3645C2D9D19A6A8BA0365CD6DA14E605C1E4C43FFBFC
+627E90E78F224702694D46806D0460755F3509E9686F2FDD0A5F42A42AA2BD7F
+99CA8AAD833A18C011F2D065888278A898E456042DDC6F5938CF5DB49A484BFA
+C030F534914C4AB47B763CDE9742AE60D6FC253247847E2874765635EADC61BA
+8A3BA1A5D44D6015B91EC987FCD067CC8A8E0D9D01EB2539F418C1CD2786C97F
+BDC1CD97B87304BFA0FCAB81E7D669D6BE73CFFE9C16502EAAFF8302A90DE1FD
+5296ED48CF297B66D1C763AC6F3602714ABAAB3AC6F5E1FDFD6926DDC309766B
+1D757D0A76A8407C9E68B2966D5BE4498B09D993560CEC2E12250BB1A59DCE0C
+DEF9932C31C9F88D27D2EB5DDD3EF8AA949BD9E57B9C6F11556EE5EE197BDFDA
+BD9CBACBE9B8091C4270BEFE38FC032C54C7086A0FF2BFD3461F36094E0D2C7E
+148612BECB701225473A504E184FBECD75743E8F81354CBDA599914065E943E2
+F4BA40E17ED12216CB7131AEE5E5FAC146EEE394BC6E0748B3F9C3941E7A8625
+4BDDEBD9A153652B59C4581DEFEEAFFC70C3FEF88534F2BAC7A71CD3367B3CEB
+7B2DEB66161CC4ED6FC7933627C7DC3376FCFFBABE23DAC7526DBF66A4BCC3B5
+9A901AAD960448C36541E575ECE9FF7B58C7747A38C74580058AD823FBA4CB2A
+DF1F1EF43A0308EF301659EB1B473D1BC8EA1A0E71691B99E355FE186055C5CF
+D11ACEF5C8EEEF0523444D612C5CA276EE5A99812E38380481C1ED75676B22EF
+FBD974FE1263B5EE29CCDA34E974F0D298D71CB17193F9D404E5622B8830CB55
+CAF20CEFBDAB119062FEACEE43186D40FF5D2E9DCC76115D1F19F713D5DF651C
+E195A3386FE3C161593AB37AD754D23053E048BB7053791508A789FF7800E7E6
+F13E02370A396C82B08A7B110EBF131C5990FEF91F152FA5CCA84A8D25FD53FE
+8F67666E188B37F558E32D96C36898E2527A61E9FD920C8214885CB74C7DF626
+17FB7AAFD00AFF77EFBF89E445F74E67FD3D9AB1670EB65A815902901A251750
+821A49161317A08A7B07536DEAC96365FA7EF5CFCB18A9046E1885076A9F9E2A
+4C99BCE0E4305DB547F969D5A07190F35B9E9051F8F05E638EAD7DC8AEA6FB0D
+F3C6FBFA587443376DC52A66506431EBBC4D3F2DC411A63E54D91EA959F33FB0
+07D19BE4F818176D9E00E3904882F7A515EF4580499092EFE839D84C4BC113B7
+0776EBC3C1E9AEF237F719FCE95E799BF2488B0A07B288297C5B5CFC94ACD783
+C111BEEC2E5B19A87F55DAEF6A1802800B06187280597090E0CC5BCBF4EE8466
+4189ED41CF6BAFEB11F6922B424A9C084EAE361A954457A4F275D6503A873453
+A578BDDBD1E767C6CB3B72AB6806E652BEC27C17E54C911DA76CE0377205B9A5
+C7D03D385D251428FAC2A31E7D375435ADAF4C7EDD3E02C65546DEEE0D480D77
+0DEF31313AE498C20383182526D38E15E23ED295C61A10D64493E51471393167
+ECB2ABD43777511340F115DBF077E4E09560EC4039101643AB3D6DFF05EC5AA2
+71BBBF9F1995A7CD95E8E280766B2F7CE6BC83883C4A951B33F7521D6DC32D94
+F4FBFADC4C170CCBE78A44466A1F255CC74700DE7DB2097FC3EB7B66284F319D
+200B7E866A8E9167A4AF4E80089C7DB6D5DAFD3BD92FDFD94F6A27BDD99177E9
+757CA4E6D7107BB66B29F1D85580EA0B0D277753F02C5872293B9025F855B162
+1F6C314AD2454E4A77285283F064BCE69B0C5E60B203066B75E70D421CE61ECA
+B25E92C2BD337BEB203416E1B294738FC60954E3DB04E681CD85D6BA15B26856
+8A06CD6B77F350C99CC0842D37E645CE18DC88840B178375051C78BB0381E696
+8587CBE061FA1DD0953925AC091D68942B11C5D183F639ABCFE66526481C1DD8
+04E06BE093A98766C742994E0BE22F6B2C8719900AC3D730BD34ABC350CD47B6
+457B51A7C1301F64267BD6608329115D7D1A9A321AB0D7DE84CD0183638E3905
+35B85A5856C615F5E3FCECDE507F5259A72106484E2E28D8B3C9FD1B74932203
+4B60F79F937DCF533A8D5930A9A77C1A18E7E6AAE19CBA95E153280CD3363F84
+A4A8E8F955C5663691D97A650B8A405D4DA45229132282ADEA093CC48D5D6617
+ECDFF62D4CC337D269BF1BC9496F7C22B878026394BA708C81BFD916C357DD30
+9F576F5BB0BF70E1CF8C9A4AFB9FE1EEE45C953B57687E7297C006EAE3A81EB5
+1ABD59608F257750468F1B7CD9A15DA56DBC4E3BA91E72E47C09CF29B7602FBF
+455085C47A8F3A85B6FD7A1A7750329D6CD9A45FFAFF99CAE6D6BB5CFE1A1481
+E7EF22C7CCD81D28D0F1172763EF5AFD5E4A1F1E13A33E17556802B3CEE3B165
+270405D204B62F6355D74E6B2080C58E70FBFA32BFDC5EE283AFC0D120C245FB
+0CBF54492D23FAAC39F0FF1DA3D7A6FD5274FC8CB5FAE86D597CB1C8485112A1
+E698EC1DE4DC96A2117E4A1F053E70DDBCB73F5FBDC2A7DC211418B58511BA55
+74CA59EB13A7D36937D83342A9AE0F94F57CFA55DD09C95BC69C8BCC6F183934
+6BACCD37F557BCC2304EA15EB15E65D89A62B08AFF416C117FC2A22569BADA1F
+83A5DA853AB52B5A4ACE6735530D2E2FCEEA347F8D78E2347F25EF1AD5D4BB30
+FF5B1D693BC2CDC2F20DDE17E18461F43436404307488B9D123683F4004C278F
+9E1B703CD78006A615D9FCAE529ACCDE1A8A29905C502D177ADDE0973C6C8BD7
+00BC197D872BD64DA50A72B3DE2A29C93CA46805C4E2FDB89CB2DC0A125F2017
+7ACC9239F1B47CDABD6B256D11C384342FB68A738DC84D6B2E3E97B4E23B509F
+B4E06B5AFC18ED32492299A2C680148D4A6799C4767A0A8751F73D16574FB9DF
+B811B961BB5E70149A25CE95E40D2C15A21036BB47D877BA039E53DAF09873A1
+F339345F12718E97F0A5046B63756639FCAE4EB1A9D49448226C638BCDCF860C
+A7155E52D1CDE779D5C659E919DEC9862CE952E4C44BF491E52F02DE78068899
+E88EC3746B052263123BF4530A062F7345B9AB23A07DA9CAA36020301DB42C07
+1CA07617A27733674A83E46E6B3C7FF6D6292AD3C32D28F089063596A38A60CF
+003326DE438779473EDBA0278F31AAA84BC2A313997D71C8D60C38FFB560B3A6
+7088D5E33F682343C0A525394F2CCEF33C29D22B22BA5A0E836987A1E79B1630
+BA6B0276BF7BF7B2472E8F5EA55F415359AA4DC01C6DF58FCE9BD5CEF58189EA
+39396AAD885BF2D853261BCADE53537CAB1C80C96905B96F198DA205AC2B7ED4
+E3F5A649677F47B30F5D4B454A9B5A5F569A1DB9F5192520B9FAF6D067042F74
+1B5DF8204BA10D6484E5B9528BA143BA44B63153DE7F0C3D219506A58F73178A
+DB7EDF884AB4D064DE0115FB879B70736FD8A8C4F2A969E33985A21AAB772C4B
+75BCB8B668A15953DDBADE0B642EAE1558E1EDDB0AA0071B71689E1EFEFA32B6
+A484479C1A9D2C9592341A9D3554376B4A10F92E787210F976A7EE89083402BF
+214EBEE39DB894578FCFE666CDB756ACCD2E1959B1ED082E53A13793A96C21DD
+766814653C9A094FA498645C5CBA857A785F2E4809902672CD5BA5A7EA39AED5
+22547DA916AAA48C4AE990FB923F87E6ED931C0AE5081CD03AF7571B1892ED0B
+E6A9EDCC718861C9BE048D19E0E3BFCD520C03CE3243786D7D9204178E5CA8A4
+7497AEE22669F718DF20BAE5F8AAA0E935A88D7FC32EEDCA41DB0188FC05BBFA
+6850BF4E01911EA39AFAF6D94243B034145CE0D2493A6A29A2AF26CD27C4D6D6
+E34717BA93B5DB85E5080331EE2A311D22ED96D7C4C943B1E5AEA6C102F85C98
+813C500D46B27F985FAF1919C40ABA58E6C1AE950471FDC82C523A2C71F41C3B
+7C5737ECB2E62CAF769D8B23363C9A46C31B4FB636D7D2746A5E63F76B19971F
+725B5EFDE946FE4DD108DCFEF718E2FA0D10B6F6F73497B696945D0AC7FFF70D
+50710168ADA1450EB42F5CB11ABD09B79A1F2DB67D785D5DEA27A84F8443630F
+FC233CD8A625C0A0B88D0CBFA06F316110514F382CBD890A3D2BF7B8BD2C1895
+8E2F28D1024C83088F38094CAC1A5EC32C1DEFD0E624FDAC572C4E3F0A547050
+3E60EE03B18103020F8482E61B0BF87A43BF510E6B49DA2EEA99ACC8CE509D27
+46FC9012FEB275C16759F75D2F72CD5E9CF7934C48D94B6EFDD7928322720075
+337930C85DCC5F545251D2B1000D772C95486F76D94CA3B84B73B9DAE750E24C
+E6EC10C7949206DE984A73383D261456EC3CCE62FBA4715CB675CEF740A112E6
+20EB4BE7C0FF02BF9EBCF27E9088F5B6AE645D578572C603CD941891725547F3
+58E94AFD5FCC705EB70683D6E6F7D62A891BF0CC8B18BE0CC1E202D4764DC262
+1D71877EA6BA1ADC8417EF6B964FA7EBC02037C942EC3D7667B0A2F0867A84C1
+91F43B0A8766FD1D9900A5889A754B2675CE914B111E2A217CEB75C1C6D19C99
+885C61B0DAD8103BEDE3526825E6E6525F543BCAD448F0FCA79348384FBCD5A8
+75856EDC9172CBE6E955A5524E74A5BFABCE80D667D84AF898BA2AB7FFF97C41
+501E443C52616F3857914215C45C7239F3771D4D48D77310B35087F501AF2581
+C0CFD59BED3E9152E92D3A27FBA11D43DD464E5126726A069F3C5C81A309ED3F
+5E144B1297DDFFF790321381C7CA66015890C2068F00B67F1CC005F514D1236F
+F8EDED47E7DCDEB4810CAF16E7328089237BF88B14A2290ACE2997C120290B11
+F0FE1D75D4D1D22CF409B59A23B3CC923FF63870CFFDF0835C759702977FCD2F
+1705C3D8B6231D0043AC9D52F3BD8B0BF48551AB1A8E0EA713F7B5A17D02D559
+A4E5004B7630C25652687D9D281E0A22B6ADE9411BB30EFECB36F9256764D355
+6F66388EA3A34279BA009ADE100D75B401A1EB48DC32FBAED25464CFE0F3438D
+C78E076DE8506611C683BB607EFF9D6EE1490EA592F89C970701D075FDDDBCFA
+96C609B61F7BF0052EECCC24464E3D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMMI10
+%!PS-AdobeFont-1.1: CMMI10 1.100
+%%CreationDate: 1996 Jul 23 07:53:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 58 /period put
+readonly def
+/FontBBox{-32 -250 1048 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321
+990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E
+6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB
+DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721
+59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823
+D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF
+8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808
+6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9
+1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE
+03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909
+95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1
+74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2
+3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8
+47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19
+AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8
+42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8
+40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837
+B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53
+9560176676ABB71BBD0EE56B4CC492C0652750227CEC6CBEEE374709231B00CD
+0DE83AFDE295B314F6C8B1FFD32251C1925D96A64D739FF1DA4926460B28B3DE
+E949AA0BA3DDB16534FBA30C32092D5F712B5E8C8D5142F35AF2906E6C219D2C
+7FD9A368C193E0EB9C7E25FF03C546B6ED993F964CEDB1B8537C617170787F37
+88D6F2AD02384B01067FE3F98257BAB958BB3BCD1001090A4502DA0638080EC6
+DB784CC8AC37CDC01B29BC481D6A05ADC6188785262358C1BF1D694BBF31C1F1
+AF117C1ACED44AAC6EB4B9A2511A6762DDE8FCCBA5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMMI12
+%!PS-AdobeFont-1.1: CMMI12 1.100
+%%CreationDate: 1996 Jul 27 08:57:55
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 58 /period put
+readonly def
+/FontBBox{-30 -250 1026 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5
+5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC
+4391C9DF440285B8FC159D0E98D4258FC57892DCC57F7903449E07914FBE9E67
+3C15C2153C061EB541F66C11E7EE77D5D77C0B11E1AC55101DA976CCACAB6993
+EED1406FBB7FF30EAC9E90B90B2AF4EC7C273CA32F11A5C1426FF641B4A2FB2F
+4E68635C93DB835737567FAF8471CBC05078DCD4E40E25A2F4E5AF46C234CF59
+2A1CE8F39E1BA1B2A594355637E474167EAD4D97D51AF0A899B44387E1FD933A
+323AFDA6BA740534A510B4705C0A15647AFBF3E53A82BF320DD96753639BE49C
+2F79A1988863EF977B800C9DB5B42039C23EB86953713F730E03EA22FF7BB2C1
+D97D33FD77B1BDCC2A60B12CF7805CFC90C5B914C0F30A673DF9587F93E47CEA
+5932DD1930560C4F0D97547BCD805D6D854455B13A4D7382A22F562D7C55041F
+0FD294BDAA1834820F894265A667E5C97D95FF152531EF97258F56374502865D
+A1E7C0C5FB7C6FB7D3C43FEB3431095A59FBF6F61CEC6D6DEE09F4EB0FD70D77
+2A8B0A4984C6120293F6B947944BE23259F6EB64303D627353163B6505FC8A60
+00681F7A3968B6CBB49E0420A691258F5E7B07B417157803FCBE9B9FB1F80FD8
+CA0DA1186446DD565542BCCC7D339A1EB34C7F49246E8D72E987EB477C6DB757
+99AF86CEBCD7605C487A00CD2CD093098182DC57B20D78ECE0BECF3A0BF88EBA
+C866DB19F34BBBED6634AFC0F08D2AFB2A92578A6F8B4ADCD6594737FF6EED7D
+5B536DA9E3E2CADB40DB7C600EA4D100D33C3B92B1CF857E012C4EB370BA8295
+55B50047CC8911C98FE1A7BA6CDEA82D34476286E710776823690AD333DD3A49
+335002F4680DBE1C21174BF016B0DF799B01EB9D6988479A8334BBA2F8DC7146
+BC0DAE9DE3A6453B181808E68A89E0C02DAC6264D002B422EBC1CF14F65D9888
+15EE6D514D3457F7F3C6A3D17EE1DA076F73ECC392D349174DA9E4680F29CE10
+0157E42CA35F5DBFF56BFC3AA07E61A78DBE882C5AB388220C19750D3643E7C8
+23D6673027CE568A4ACCE1D12B1D9E5A43507F4AF9BC873237F65A6B95078DD2
+378007CF0F0DE7CCEF760E19D6D1D7B412EC5D4972
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX12
+%!PS-AdobeFont-1.1: CMBX12 1.0
+%%CreationDate: 1991 Aug 20 16:34:54
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 11 /ff put
+dup 46 /period put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 74 /J put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 89 /Y put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-53 -251 1139 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660F74BEE96790DE35AFA90CCF712
+B1805DA88AE375A04D99598EADFC625BDC1F9C315B6CF28C9BD427F32C745C99
+AEBE70DAAED49EA45AF94F081934AA47894A370D698ABABDA4215500B190AF26
+7FCFB7DDA2BC68605A4EF61ECCA3D61C684B47FFB5887A3BEDE0B4D30E8EBABF
+20980C23312618EB0EAF289B2924FF4A334B85D98FD68545FDADB47F991E7390
+B10EE86A46A5AF8866C010225024D5E5862D49DEB5D8ECCB95D94283C50A363D
+68A49071445610F03CE3600945118A6BC0B3AA4593104E727261C68C4A47F809
+D77E4CF27B3681F6B6F3AC498E45361BF9E01FAF5527F5E3CC790D3084674B3E
+26296F3E03321B5C555D2458578A89E72D3166A3C5D740B3ABB127CF420C316D
+F957873DA04CF0DB25A73574A4DE2E4F2D5D4E8E0B430654CF7F341A1BDB3E26
+77C194764EAD58C585F49EF10843FE020F9FDFD9008D660DE50B9BD7A2A87299
+BC319E66D781101BB956E30643A19B93C8967E1AE4719F300BFE5866F0D6DA5E
+C55E171A24D3B707EFA325D47F473764E99BC8B1108D815CF2ACADFA6C4663E8
+30855D673CE98AB78F5F829F7FA226AB57F07B3E7D4E7CE30ED3B7EB0D3035C5
+148DA8D9FA34483414FDA8E3DC9E6C479E3EEE9A11A0547FC9085FA4631AD19C
+E936E0598E3197207FA7BB6E55CFD5EF72AEC12D9A9675241C7A71316B2E148D
+E2A1732B3627109EA446CB320EBBE2E78281CDF0890E2E72B6711335857F1E23
+337C75E729701E93D5BEC0630CDC7F4E957233EC09F917E5CA703C7E93841598
+0E73843FC6619DE017C8473A6D1B2BE5142DEBA285B98FA1CC5E64D2ADB981E6
+472971848451A245DDF6AA3B8225E9AC8E4630B0FF32D679EC27ACAD85C6394E
+A6F71023B660EE883D8B676837E9EBA4E42BA8F365433A900F1DC3A9F0E88A26
+30F5D8CADBB3C1E3238EB07CFA0721C8370278CF3A76B741E00E5CE0FB24FB6A
+CB19AE8B78076E79F34B90E2710710766D7E7C90FD0F5F8EB484408C176D1DD9
+A6583C0D547E269B85AFA545C912057064D963A98C21A4B31061450DD09E1FAA
+303AFACA176EF65939CF1F21E9774EBE43C434ED02DC2D4267BEFEB6101563D0
+3F0BFD390A6CE04A4D7BFDC8F7FCBB0F350B636B4F6203D9972005456C97E4B3
+B898EDCD7A5D7964DC1F3D8752513F328A7BF73AC1B6E171662E7922D8D849C3
+7FF8AC6E4500F1B5595EC87B319AC7CE3929EFD75A547C76145F2C7A1589A90A
+0E0C2A8F5ADF56B03DC9AF40AEA131B348A225356157FC1ABA2EE61934A17A33
+4A41151E2AB2044AD1A0C8B096B825D1FDA4858B0C10700BABC582F4969F96E9
+0D92C0675EE338093976373ACA47487FB724E9EB1937D1F43168FA65DE8D88EF
+BCD5141C04E6F605465858A5AC012DE546915B0E864CBF3B0AAF9ED4F4E915E7
+5F1B84E7632D24C7D5DCF975ADDFCD5FDDED297B4876F968540128993F172D44
+317654D7E18E74F7001B4ECE84F3A253445F9EB8004A83BC3299420FA079D27C
+17A527DB1D4F80A61EF065D43B96A2B97243425DA2AFB8785BC9A11FBC58F4FD
+FBA1B0C72D816B6E7C38D3BFED9D782FE50BB328995B82B8BDF020516C883102
+D98459F64361BF9071B600C86C39B6874F74F140CA04B0508A4F900E5916E732
+D6E0556A79E7A343B3AD29ADC629C24AF1E8FB66C6E3CC523CD561895A9F238C
+C23835EA06836DEFBF5CAAAE0F1D54E50DDB2A33B5F3AF518264B4284042FDD2
+8B9CB3D1DDB9DB11E6BA63ED3717327183BD20FFD37D78F14440311E1E0CCBC2
+16A0A5976C5AC98961C84C4D9540BD63274078ABB15A89543D64A56310D10263
+69DD0846A556CFB692DBAF3D058C997C78EA25BF068DA0CEDFE46790D55E5800
+6054A433671255269BED650FF8D77AB3B7A621A730E6E65C432E486E036DDE68
+057F09A720450833767561280743A6619E3D729B104AC52762215E1D850F5444
+48867A29FFE02CD0CC8C3EBB61190D408E61B1DAA73749BE8801842EDC73C81B
+CEE405267A1771F3DDC2F553563D123001634EA5F2B2DD9EDB51D7AA118BE168
+ACDC4C07BADED6061F08ECD431D23E6D9CE4D91ECC87547D8A31C5DB1864B31B
+CA8ECB98229FCF50403B1B76511BDBCB03A2EA4D7AE2D785569EC2EBF6641B18
+DBCC943D940A1C5E0697D62A6A1E44F96A35B2DFC0C0DB4AFDDF4F119AC25CFB
+4E6AD5B5B72281316AAF6F904147CFF7FC7F3155423F60A7B5C4BF78E7B8EB56
+94C1899260898959843D0906EAE62883E0B3EFB99EBADB14A70CC6D35B332448
+92A4C8AAAEC75D989A4645F18EDBDA5011101ACF5C454043F86851AE68D283AF
+583386E44206AFE912B0A09D1EA6199AB2FF6A045642A231B132514531183756
+108D99FE7CAA7F9389C5158D2801034305049C9B91FA9AA347FAC311263B1A9B
+AA6C5A140003123F965F5EF39DE2004C182D7E7DB2BC0E176C85BE88D1D1A447
+47E5CFF1EA15DBF06410419A47449CFFCB0A0ED2DBF9FED16E5BAE4A556553E1
+3429D9D56F496BDF1D97AA048998D602418F18152DCED0B73E4A2FD19D6FC242
+DBD88457D879D6D524ED63CD15FD8C0D99FE704317FC42726CD5D0D76B351819
+238C24A3E9ED9F09D781F68396FBE193483F2D4228BC168ADC9646179B49C5E0
+3D8EF8325D5D5BB7054484D4B62E5707734021BA7E47E32BE21B6D6106678488
+1C198E1D864CF9AE0CE4D9D4F25D9B1B1B0B9527D0C8AA9D1D5040826BD46C48
+564B2EC1AB1793C8A9F9E4D2C33B718DB0E1C55734A0DCCEFCAEA81C49452DE9
+7C2754B7775E82B4B6FA79B92EDF1245118960BF47341AD717301ED997EBE4FA
+CCFE98A9D3C6FAD11C5340D6E4B719BE1658A8CECB8C8E01A8A615ACDEAFD72B
+0239E1EA1D8FBFBFAF5378B893B9F55CE497DEF7CE1C98BE255201D7C69DAA58
+2A143BD71C3D7F5A4A6EEECEA23B0378D1D4E435F3FD0EDBB2D30D18E1B8D2ED
+73F248C1018FA7305B827354D8F444D198D855FB2F096A4601734A2161B41EDD
+751C96AEBDCDEE05107D91741D5C829E60FE6A52F43958DBC6D704242271DF12
+6FA136E48BF4CFF491CDFBB3FA215D097A0CFCA31370DF9CD11F4CE84060EA52
+F3E42C28DA145D308591B1D47CDDA417CCEC7C91171969AF29108CD68429C177
+544A037CB9C85E3FC5E7300BDAA6A8A3F5B50374F49B0781DC721DF8B9580993
+4109ABF27F0CB38C162C1FE020C2809A1AEB0AEEBF7AEDAF9FDE829EC6A8C22D
+C24AA95EDE9658FFFDFED7B4146E0BE45473B028500701F434992CDFB6759D9A
+DDDB70E6D31FCE6481C176E36915B2369546DFE415F574B4F807E2DC332C5A8A
+6DF941AA2DF9B265AD7996E59795D8C4B17F4F8040BF2BDFAC955CA79113DFA3
+430B0A5B8E88AE1F6D63B32987A2C772A23AD9D7B0050BB65BF138CBBAAC3842
+3CAACB20A72CDA3D37974EBB1CC4FFE7FD71F47F51D90E711F6B7AD9E94D297F
+2D0ED547FD1E242BFB62A49AC5606D89FDA5075D840A49A96C550DEFC13A76B8
+9DB2EE77463261FDABF310E45DD927636D717851598126554EAA8AD7DABECF66
+7DEECA0A023971405E23A066A2AE49073B467C629F12DA38ED78A72E3FDB5D7C
+4444697C7B3595F8F47F9DDA896ECF98B512E6BCE9CA0DABE54D1D7175B2677C
+3D459E65F4AECE7538202238BB62C165AE4ACF3F2B4F86765360D2F826071E94
+7F05F779D1068D0A40AEE697B08CC29DF6E5E5113B256DBB0F335047F21C36A4
+37474EC0FE50505D663E7F3A698F552D599988848D6D043216EAAECA7A32733E
+3BF0FFC108176CA74B97DF5B14DA45FBCF3C51B4144AD62ADDA0374EFBA6F0AD
+AA82526BB50A354B8699B62549852026B8D6AC16B99697A0E0A993A25C0C70AF
+EBA7C074AD9D3A845481F880FCD56D68FA0EF3AE87A7D2BB193B276C98293375
+6F1A74615A31ADEDA91E1479944B02AE97A36E8BEEBE80A73BC9C4B522AAFDB5
+D4EE603A9F9EF626B68CB8FE1CD7F41698FAECD8435A840F37C4E6647631B50E
+8C408600D7FEC8E8E0877630200F313B103F4F575A26E535414CAF1CBA3E6003
+95FA322E73FC9D008277C0E318B754A371AA70A40AF22963E2A388B47A4EAA2F
+7FADB63806EC574F29382F8A9EE9873DC166F0F9F31C19A52FB81E4131748A61
+70E733AABA62A95A00DB36E4676040785C4E569CE535E332523344D68FB0282F
+08F44307160EDD83F7E855DCD7CFE797C284C61176685D1D8694E36EFFF7FD71
+0FE8AF928D6F2ACABC188429103060BF5D7E9E0F9C57A1D9229669637812762D
+09FBA1F2662ECEE511E2ED04EA158DB378B7EC874710897F0E12BB2EDF03700D
+AE6981AAF02358F73B1DA20C15A45F16005F343305BE8C26EE3FCF373CFD226F
+F7B4CE53F3CED3B121755CB8C930DB69EEDA26BE2F6FF4D7700A7E1B955F648F
+9106B7AA95EB5526E374320C72C2F0EBE403EA285D7E72EF6DC26C1740DD3FE3
+8C365BCAAFCA888BB1C875059677BBF5649EB8075E30FE1914CC89CEA027F7B4
+7882DD23C424EED479C768025F12587970A13B22B22BB26DF062E6083B6D1B82
+F8B8D6B39315E22A2E8AA8F764C7565DC7C257378EFC6756E198D786A801D8C8
+5A18A973EDACD8628E1163450561492A514E873A9FBB66174C78FE9E0C8C84BE
+FB9362A11AA9C10758A9748B082B0D80444BEC63CD7338C76E3F7A4F023A9E4B
+5F896C7C75CCC0322BEE87FE59D464ADEF429042DE673BC5B127180E6FB88760
+65828FEFD698ADBA3E8849074E6D156296A63FB0775DFCA3CC09407B28AAD462
+3E4308B45706983C056D54A03CC123C52821EFE1F18EE7E4F0F6A14A6FAB5815
+B0D965A9ABB722EE34B8939385DA9869E7D5C403F4952FBC0B967066EBA5A2E7
+4FDEF447DAD2AED9417F60FDA4890552707752633FE41A643149FBD993277D1C
+5CF758F8DB9E5DADE57EA7086A882A3C3DCFBF64B026C1D7C87C382D2F85207E
+D65DA6C7A70DD1818DC1A4EE0F5361FC1DE36988E466EFDBAC8D6A593ADA6F75
+1224AD2D645BD184021ADC468F8ED8DDF33367DCE2A3E21696BD217625F20FF9
+C20F2C937691410C225E989586471E3F7D549325855F1128D1A3C46EF8499987
+A7A3BFC4C5D0277DF3A31BA20E748171D8B6FDD83C6E12525AD0B20C170416CA
+CA192828F6968CDB3EB1D8855823DACEE4D8720FF7AC4726273D30FF69209CBA
+0CF5E69CF444EF42F009C446F8E86D49C336AC86B0EA0E031B23CBE3B3B2000E
+6B324CF64E62B949E1D913F6B76E807DE603D5CA1F01FFB1BFB25E03F8CDF616
+37B057EB91CD29AD97F1306D8CC4D57B4671C8CB82357F4C5BF87DF27788230F
+0F7369B68924FEAEEBB2CFE1B9C8AF5B39CA25DC1D3C4A17A1C0EB8C914C5431
+B0F5071E9192075429FD6B175C71E7569C11F2E1E211F71A2DF30FC0B1B0A2D9
+6221DB3D8E4960D86CFCBB6027B8863CFBCF2039338EEF9FE7A39E547841EF5E
+C3A40AD97A0F7A44DD3C640027BF2DB7F5C1B589BE1C347AADABC2A866BBC910
+F8421CF2EAABFCE16B0DD359BDDC23938EECA73550C2472C436978D776B81DA2
+A1AC6C6E0E7A93F1731E714489F8BAEB40947CF71AF203EDD8C62185F4BA3F26
+95F29A5B30DBAFA3A5A43515FD046C2960028BE7BD991A28D309D361D2DF2184
+C9B5475151333BFB81329F95AB6725EEAA3DA4E9D27A5BBB3950AD732809328A
+832E43D1B96AE9B94A3744B355E29410B4188A87557A13DEA28C26D515F28D97
+149F85620D7B9EABFFF4ADAE69CEF959736A542F8A9E4B5A56A63AA1A98B855D
+D3E148A51871F0B5EB96B4223BCF9B8A0C5A274F0D0AD8A92ED2FEA5699DCE5A
+485449CCA32D8E4496589CC505B97B21EFADA2E5247DCDF606ABCA0CCBAC0D2D
+B13FD3CBB8DA2A350FA3792C174EC15A5ED71716F80D8254E80954BDE7BEA9FA
+1E6C51AA6A87F684DB649B4CF423EDA8825AF711DDFCC53B150B6D142DC90D47
+FD3D09B84445997C008FEDCBA3260984272EB55278D624A453C28D499C5CC8BB
+8976C2F7E99C3EFEB2C5C03EB03E0DA0DE6D484DE96845B65FBA934C49B8C793
+7CAF8D1A18F1584C9940043C2D70364B901871FFABE6C3F622DAA61A8F193AD2
+6333417E855E48190F50C2CDBC2DFE4669C4624DC532F5B6C4FDEF1F06A706F1
+B42E2B59BE1D25E495F00803C4BE5FED573259E53CF360FD1CC78EA6C07E2115
+481B26D029CE510E4790A3FE9CD287C55CE828A3AC9573F31C33CA017A32D295
+C34FC73215E2624FBD59C6C49C1D2101E5735E10D2818589EAC391F38E8451E4
+EBCA4DFC2D72A0D326584A4F16676330C6E483CF81973D8FE9CA709808DDE39C
+5AE2040873DF02A6B5B5C997DF1BE3F3863DA65A4F6BB02F8A6B7EF263F60083
+D8C468A7E28D2CDE2D840A58E1BFC48CB118EFA6A8EE6D12F4C08D221A42729E
+AEC32A1B6D79E0434E574C2A2DAC76A8B1C9F41631E4234DC04BDFB59A9FCB83
+98B79706EB47958561BB254C434EB9D58F42363B4AB43163980428C9D32C8CB8
+50A3F54796B5B5965CF56F34BE05B391E82B8A6176A982EB4DDF10C65CBAE36F
+E3C3AFF511AE50403A2B5ABF480A256041E1D2F539BE8268177ED78EB290C735
+63F20C8BEBCB6B6EFFEF8071B99E322CD4518ACFD3053031831087E2D8E650CF
+B19990CA158134132D9607DFC2F9C1DC06323B00F4E517729697C4CBBEEA70ED
+39D125D6B1D9B149BB25ABDD2B4489CCE91477415D552E9BEDCBA4E8A84C05EC
+0C63B0F317991D8ED5F1AB87AF1C7C0E26F799CE35B1EC00502FEEE71836E426
+20B5917FD031D7159A86D8DD95CF6AEB22C5DE3BB8E20B47DE028A67B37DF8BD
+E5D7EA8BE4756D0B8346EABD2D2D68CE0FC459305E2EDDA10A50F8910AE663D0
+AD0DE08302075E097F1E9B000589745666641FC64ED2AA9EE16DC77C9C321A48
+90ABCAD27872D284B219725E5A414B0F27D5FB76A7441B53FA0D73B55684B321
+D1A22BD6290063EEBE902E3C7C76F5BCC71E9089B879CE569D97FDF0FB951E21
+7ABC5C156ABEA4DC9A1C222AC78042A6BF85A2E8D55ECE0AA3C75B0F2440A350
+40AC6EF2D7E6E71167A91AED4AA0CD6201035737E0BBAFC0DE923BFF592CD57D
+264156A382FA95689E6A3C812A3C3A3D18BE4A928337C01B2F9FE6CBB6B51F4B
+4DB25B478D14E09EBA3821B5A7869064EBB19E40B1796E9ECE0BCE5B22A4A9B4
+9BDDD2D26376020994B8A64D5E7614462AB1303433A4D37D5BB5679DDACF5A70
+311A78E2904E3DBF1DE9D03423FD5E3C4C499EB2E05EE9933262061E40D11817
+BEBDBB5DCB9CB4253F91E3B7D2BC6E7D78EFD25F1628FA73A958E780A3D90873
+1B2CCBF6EFBF21077DAEB4AC337FD84DB85B5E1947A1CD9F7715F26388145095
+94FF23C33B61FB2BA481EEBAE5665584A5D732F6E02D33544A78F4E64A897B32
+E8B9B9E75D47A5254B3722FD7CB77812EA8DBD178A2625CCFF3D3A11A4C8B24D
+A6F3A4E2CC4DFDF1AE2D2EF0BE5062A0413E57E536AFCDFD5F9B7CD991AB38F3
+EC6890652AF5C01D4498ACFF62F05F4E7106DCA937B7D00E6C04FD2233FA4F79
+C637B4AB5A7DAB074748646006F7C2D7DE7DC9B3376E96EF5B7AD92C41756FB1
+C4C341FA1B28F5516547D37D6F29F68D27F680DD4F160F06E034F68DC2A9E4FD
+01FE4A4247E419B8E448C6ADF27DE8A0D316C65A8AA7514C3E82297DBFEAB6CC
+A7F8D083DEFD963A35C19C65A4F2D973D4C904B49355B1FDB0766027881FFEDD
+B344BA315CF37F6093D7DA2E89A253DBF6F57B4DE372C09E47231C90EE977E26
+554E5D40D1A8792361024A6B77108AA5AC8119631F43A32F04B2242C30BC4EEB
+9D9C4D14BD41A588CBEA69AC307B90E0DA02215C02FBBCF12D30158EAE9C33D3
+A805535740399E90CEDF906DFCF98257FAFC38449699889E2A10523D275DC87F
+AE780E2E9B90163F07CC156AA1724534463F057338A120E15BA0D26BAAF1DBFB
+EFFF931B25135D8C833BDE934BEF5979ED1CCF8614EC05970107429BA895983C
+75BD6FD03EF39B09933EEB66F3A1F64F05FDB1DB01ED2DA3D58DCD20CCA28BF9
+ACF2BB63D9FA8314E12762E679315094408C2DE7D9A6B3ECC22F7E338EAEBDD3
+E9D1FF20D0382E8F3A9C0A4D32EB87443FCD28AD6F6FE13DD8997960CB1166FD
+4FDF8F1B367F1AE77039B8E668A324DAC378F7C732A9F68C6D7E503BDF4024A0
+C89346213670C3CDDF07F09D98D822F3FB862C528C14FEC8F476D2E0B881C141
+0EFCE8EEAA71D3C7A6231819B2AFCF3CCCE2EB55438CAF7297BC1AB069A2F995
+5541D1A072181486373F09057F52C21BDF2636AE92AFD8CB558CF406B8062B06
+909905EE0812C3B615EC10FD8599A9215123D93838A61066B4438CD82A16AB25
+DBF37F3CDE77E44FF07F890934D37008B87B7EFEF9D6128513062CBD7CA3BF78
+E52764E2EA632D99B7C000D44639DFCB21762C13B314796B1808A250C148134D
+191A641D0934AD4473C9DE68EBABA7555B75C312D5EF0E443F871CF1D26C2EAB
+23AEC8413A5F53D9EBA41B865A4290C06CA801D8556B6DB4D33DC586C81D524B
+5E6CEBAAB011F1C57C74BE9A80C259E03D7D944A20BA869C990928DDC9ADD050
+5CA0973665BB3593F5C6E07AE6BDC297C0C263C288BD8A14844699EF29BF65B9
+6A1858150F2D54FD65C10922630B0BECF7110B8BC202D2BED4600F80A9E0E3EC
+D2067859C30D1556388B10510872DC87384C5DA1B8CCCF81326B4E1E23E528D3
+529F67B08DA74B49BD33408B29E2649743D16B516130D0672BAD58991FDB3C18
+0F889CCB57D9372320522FB077A54677A13DD75342C847AE0D3F845F4B6DF507
+4E24EF00A1D9CD426DE49A47DD34DD99B3EFEB6C2C98A759399D9C3A437DAFD8
+4C802AEBBACB8C58607D8B36D4D9D77F83E66E9921D5EF93A6510911D0E64634
+A752CE74C929F38BBEFF8FBB40F74D5B230047FF31D3ABB64EF13A85BBDB9A52
+756E0FF7B26C0D8D73D3677F3D96A0EC0DF31F0CC25CEA4D41E9C5EC6ED05F5B
+01E0BDEEEB73DA575CE7F542282EA33B8419CAC0199EDB3E07BB5F6A1F0861F1
+A5178BF45E89395B98281323BEB0647A2E17B3F4DD24502E2AEA132830986D0B
+ECDCE09BA4969E9D8581D76FDB1E8B4A84539B07FCEC597AB242D0E3B9CC399D
+9D9D087C6B7D7C392D9E6658BB20A05A87407639C3A51879560870916123D258
+AEC80D80A95D5DB41F6C7BA26198AE7183A79C281D9A8F39C90D571676FF30C0
+5D8842B3470DD3499201F525C6EC0410496C8187BAB0F1E19EDD7050A7CDD0A5
+41B55329638D6FCA3E71C3804BD290EA4880B4B9B4EE57F5450EB7DAD62A4E5D
+47E13D5373E76FC4935BA5853FD959E8F0F7B351ACEAE8E74037913D88A9FE32
+BF345388E61DEAE3A46A4A09237500AC2848D406F59DEF4FC4B02E67DEAEF02E
+70821BC3AECFECF3F668304D76BDA9A97A9B83D76DB39E7EC4C6C142BB87AC29
+E387D5C49A883E1806568A05B173208D264CDB073D1ED07984FB0F82C311B607
+CF9AA43DD38776DEC1E1DD2A6818595734332FFCD78B9C7931DD10F1EE681BF4
+E9EBE978EB10B0068FAAEF2C6E14B03F770BA5A3494874CD1E4BBF5F44474499
+D00DDF80F0A5A454678054318B4624FFFB4333643455531CE5B8CC58FEC8925B
+BEC696A7C17FC73B48B1E75C2850DC44B20F062B43D763D6D621F60004FB1290
+A85F00E6373AFA85BC97187ABE77E25C3A58686072E73F165A6472B93FC8FD0D
+426D02C2867ADA6D6571E5FCFD7E2B62CE2B9DCA4589EBD6172630A931865CF8
+B4D0B6391138512604C7975B1D007A98F2A2BF31CE458BCFA7DD933CDEB19F71
+0E0A4A652C58DE4669C586678CBEE3C03689DAF75200BF53C1BF49D3A758B71A
+4AC0EA9AB16A36299BAEC6301B20CE986B7B9F025EDD207C77A0ED589AA16A4E
+54706F3F47EF1721AA43C453F4B526D940AAC0B22808FD26CA91C1719F9582EE
+94A93F48431C3026AEC0A0B970B2F474DF45F48765197A85A5113DAF3D172DDB
+F22DE43FCB07899A7700916656B6BE818E7241072AB389F010D1CA585A5AE046
+55D01ABA4BD27815A4AAF6D8CB0B7D3A5AA310537E58824AB647957FEDD026E6
+D2CE56CF90D105D3CE15DB73A773C9BA1EAC2B2D06639DC43F23F3C1E4B7052E
+EFDB6D50D7D8CB3ECCE7075D26FDCF73C39281E042E8A693B5FD348003FB7C62
+C150EBD67819BD7939DEB75AC46BAC1EE2FA1F42FDFA7181382F65BCC7A9B341
+D8C0A812DAE2A161AF331FFA3290F7E72DC5B127F35E0205520662F5DF2F6ACD
+8D7769F7F4DC7462DFF38F1C72D6D14A167656F9FC80D69978AD7B0D88FA88D3
+0D8F32864727AD4402EDA56C271CE3E728D548178EFB6359001031783A449D5D
+154BC76BB4C84CB3D08EA3F0A0495B655AA7A0D2C10A44D8C550DEA7FF390C2F
+4A8ED81C6BCDBFBBC82CA31CA1F6068CE140E9EE0CAC29D96F660ADAB0075905
+24062E35DC74A8AC1CFD0A27ABC7838DF81BC1A1AEDA67216FCD23AF70137F55
+E1B585F9D6DBC12064533A9D63D753542E769A86BF763EC860E659D584BDBF21
+8DB31F5EC9645BE2BE77ACD19C03BF1F09131BD276E50A74C2D432BF11F0EB09
+48CAE24D775E1D356FC58DE89DDB9FB6B85E18DACC7071CD51814780115322E2
+8B64CEE4A9F680141F967E687A2A0AAD4E1CAD9D80709B1543392A7930327662
+EFA50A5D9BCB443DBE4A7FB9D06EB57590A84D82E888516AC574603029889C58
+64E10AC2A28182AC150B5F4888821753D6FB6EE5E42F25E5CD58E1ACEAC4C625
+798664627EA875FA1D4E4751A360FAE0D179517F8F1FF55ACCF0212B7B59E5D5
+0FFC28E567D91F94E0CB0F081C24B13C135552583AA53E9D79C08772B8B06E44
+8B41C6241A639CA5B00BBE45D29C8BA6239570EB87725EDFF1ED82D651B4FAE0
+2351A087A9FBBB690036DB244362BE9D58BFBEA124531D15049F1E82BF91ED7E
+2187B2566C73D9D63EC379D769ED28F19BF6BBDC7ADABE24FFD244A12A660F2A
+7A37E6C3A4C291062A8ABB92DE04E7EA5E72AA9EA7DCADC38EB88650F0751418
+F9E7B615468136FC214FC6C221E12B0B0C3069B0C0114BC82BC771E1B62C63AC
+D5D6CCBB16CAFFC38C09B5D127AA791717D4948B755055CB9893A755AD9F7089
+DD6016564BD82C7F3D0B804ABD96192716DF76C6DD7AFEFCF5A921C9E6A76C2E
+C0E221349537A4A167CEAED15E49CFEF4AC62817985F0366F56E30A46B802B80
+D9D066B0E1D38E934266BFEB2917B50AF0B35CF9D1C9833C31578CC1E0E6B527
+1786242AAEAC551C0E5FF868D3D3310510B20B670C811FC8484315764F8CB189
+602379D935AF0BE271F1E319BAE79EEC250AFFF2B409761D7192A7227550A03F
+1476FA970505D5F7BEF9CBD02E5730FB903650229EC1F68E664F96A8C0AA1B0E
+DC4A8EE5989BF1168EE3F96EB3995286A604D66FE66D4B665E39048AAFD478F1
+F5A008255D3DFDC9B9A3DB994C1179F985989DB6EDF92334A4768E34F93EBAD7
+71450FD76FD81682BBAF4B2CFAFF0104E4F45BE245BD4DB402AD8EAE157DDE10
+7B5A0B3D26539649B8E7E183412A325FA64D9173EC14789B8D4B92410D4E8FA1
+DBD231695B7427B29CA747A73E44FFA9E8B920FEA37F3E8275DE409CA4887614
+CA3557A25564F2CACC3BFD7AB6C5F2F7E3303FA8057CCB5F8833349CA2D1CE8A
+FDC0461FA44449703F5E747FDF2D6975110166E423AB4EA43CFBE40179C27F1C
+A83FF3229F850C8778A5BE29233241A5152A77F01923A4BF3E147AC0BE568388
+62608CC6ABD016357B500489F19B48EDBC9B4D20B0D8BAF6375392CD817E7F04
+7D6E2A78A86A65E0F058E1DD8A551E2F60DF9DC3D359152BAC29E0E3C3E43BC9
+B7C97002442F187F35B067F013807D33E02F6CA4446464B0FE765B5389A2D3C5
+97E13DB64A555397F50289174CA9DBB6ACC8D3964CE576E03D4666863F3049F6
+DCAD548929B2153DDAC260398051C0EFE5B00C9C7B1B3CF37BB289B34208616D
+276305EC5245DE8CD7811EFD647BD192885D82833D75497FBE2358918A9AA826
+CE6B37A4ADA7FC0ECD36CD223779269D42EB89F27FE7D7E2DE6CB051E930D4C0
+564AAAA1F5CF2797D5A0BB0B91EC6AC510B5B9233C8308B30E54B103504E0D3D
+06EF80B47B9533ABDE774E070679473BE73F1779181EC87E14CC3B68EC4263B2
+87EEBDF141D8889AAB4D8D4B4BE5AD7AC98AEC8B93BB6C156B3622406CE954F1
+045E50BCAA2A8D8B046D832BBAEAAC58847590FC7FB47132FA44E6279921F854
+70BFE22CBB0C38929DFD67AFAE18B205D181D5DD5613227916782A4950850196
+44E3B38EB880939018D72D3E695C14256E508596210A8392161D764F3876D75B
+AE383B885A703545A94FFB208FB9FBD800C1B588453FBACD490F7552461439E4
+C4C9A81975A2BF85F404DA45D14A3A63E7D1EB41E605421C2939979EBEAF4344
+BCBFA2C24B04982139EBAB7287158388273ACD5E0E08C378743763CB8FFFA3C7
+9B077239531C07FC340FE851F7DEE130A01CA17B5F67FB29487361407B9BE8EF
+AD834D10CB3122640E10FFDC316DC4F47C68715D11453604CDFB9BADE566D10C
+A7820EBB7E36C1215830D1F15A0B48F72AAF7FD9D81D44D82958B2E99C25994E
+F40399D44026A18B07E3BABE6B5F3EDF71D49413D2BBB6C41E1561FE05DFC55C
+3AFF7633F15872B8BD42B99F0A60A0F8CFCF77D05F5471D7F13E59D5D54F7C87
+1261ADB8CFCCB02225B75FCED310ACFFE597756DE6B68C19B31782050BE2982F
+4B8CCDBCE4FC0271068E9EE5AA92BF3602B7487996908A377404CE36B618AC9A
+6E585135B1E7B7B4978695C7F80E39E0CB1757231EDF4B622D3748C32D5A0542
+3D2DE83040BB200EDB3A337B110FCBBE92932171709553EE57DF1B99756C26F6
+511D9B4BC869E01CBAA6B6A62579FA360B0EC9B48CECA270587763F56F599CE7
+D1BCDBD060535BB2936D7C5555C795389A552CE55AE2EA636A37286AE312E3D6
+1C161AD60BC7090F068FA3501DC337B5FC83F9A5CF82252944ED2D6F94743E20
+7FAD0E90DC426E809E43E41FF78859E894BFB6AF1BC6F45C0213F02BF831FFDE
+CC62C2C86D7206EA470B4E4B3D289F9F7F9E7BA3E9A145CD8753FB349C390C11
+3AB519597B55A4A84E0D1DAC63906F96EF1F605C7557B6DF4681F870EF4A70F8
+36B0FB172E5A91DB85A9C275785EAF9BE8DBE41DD2DF4A319BF2BDE298862365
+2716E79732FC37A9309E20417C7649E1A924AA8905A78EC948D631AD62EF4A91
+D57B2A24E12E64DE85A6A015112AE4712FA4A7DB5E6330194D3824DDCB99E7EB
+D1D8663AE225992093FEBFA0B8FEBF16ED565CF333B5DD7377993219F0E600EC
+C47934A3BC02DEB43CEBA189EE121668748E295E952DD4505FCB3CD395A9D1AE
+10B7269958CFF37057DE4BC11EC8CA3F96A751353D20BAF6F6A1B80883E0F3C4
+CFE2D2E9A6B18D499760910EB56EACA2EF5C11A10AB3727E1475FA02C3389F7C
+E590FD4E5309E16F58DE60857D040D4D0039130B67E133E90A5B943ED47AE5AB
+BDBFF5FEBD66F634FA6B7AB630E936CAE5A48DE380B6C615F3C9B83521337009
+1089870C01B1879E7F4EAB8F3215CECE3ABB22FBAC64640A58B1076E5F8F90B0
+29A72435D0F0342EDE9917A1FE3EC154C9954C48A11F25F564505B76A95BEE81
+9D1FEC816850F18E13450FE896A122284EE528ADDCCF1D68DE33D42045974BF6
+2D5A436AFC97B3CD3627D7C67AB64E10B47B8C68F3D0D36F363DCF03845F011F
+5499395035EAA4DE478EBE336DF028309CB2A9B62B9D71C8D851675D8FB6AE65
+83734B0B6094DD288428A9B4FDABDD7AC7CE891C3841F2C385C95FF4C877C080
+97EB51957D5F63933019E1A1150142362C0CDA19295D67BB1A1E4DB866864329
+A41B15016024E414F6869CC7AA41DE409DE0E15F7B4ADA45DBCA0D29674C49BF
+E3A274E57C15D3A61617A6AEEDC191B881668A64F1BDD4F947CC85187191CB71
+FF9730320BC6721B6888C63DFC57106150B9154C58CC21DF2A700903165A769A
+851CC464986CA734D576CB3100C98EFBFC6C834D91FCE814473FF2E4024021D8
+FE63D090AD6EE0E18FD893740ADD8C29F6EF77F2780FCB8EA1BBDC840C5F8E96
+570D4A23498D6C442E74734C6C0E78741EB5AAA3240A9AD3FB73139C889B1753
+3068147938354DC95152ADDFE104158547D986DAE2706794826B557F3CDF7919
+C27013A96E8A527F39C443AD778994576B408A7DF1C66AB958AF5364E33457A6
+55F4A31911CFB8615409CEC3854DEAE2C4C3F45209BAF1642A422E7E550E4BAA
+8B82AACF7CE580C2D8679B985CB9F72CFFDDE29072695EAFB1E7F306EB5CC83F
+128EF349E7BE5662F91F709CCE57F47B2E114A0B01A55D155E69CF11B463E32B
+36F3FAB6D0CFC1594DA62AE882645D5C85AC0611BC4D33B9EB9B95809D92CE6D
+F95CD2F3350B2F105BAF8EAED3F94D86197106B0A3BB8B793D6C98A867BFF177
+1981EABCD2DD2640BCDD6010C8A53C0E3FA6CFB45163923B1F8C5EFFBD94E509
+6109D64519E0591CF3FAF9DFD1681A86DEC72912CC411B4CB7CE2FE107308DA8
+7FD11B6C51AC138834E66268AC3042BFEBB25095AA7013BEF1643C0B41CE4C8C
+152266332790D90DA930EF4AD98E4FEBF8B83EB620057DB1F979EB8186440AEC
+FA037C0A866E54A9B8E7AF68BE55285FB0A1F9374D3F609B026FFF8ECCAAF7E1
+9F57F2E51DEECDECD8ED1921602977AE9241CAD0670234C42DA3EC943FA55F1B
+E57EE806BC27169B2091F5C99FF388EAC206F82F3D69B582EF3514D4A554946C
+2C4F16560C7E6E2602D6073B8DCE78BA4DC052643B42C54D2B40E91206243548
+FF498C15407EC0DC7691600BFB8BCAB68745C6A56E57DA7BE6A81B1CBDDD2CC0
+A8CAE53D506211384DDAF2D730F3E9C1CF0023DA6A5189F161336F8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSY10
+%!PS-AdobeFont-1.1: CMSY10 1.0
+%%CreationDate: 1991 Aug 15 07:20:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSY10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.035 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSY10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 13 /circlecopyrt put
+readonly def
+/FontBBox{-29 -960 1116 775}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964
+7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4
+A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85
+E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A
+221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A
+27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF
+5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09
+0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730
+DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A
+71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09
+4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C
+515DB70A8D4F6146FE068DC1E5DE8BC5703711DA090312BA3FC00A08C453C609
+C627A8BFEF75B4DEFAF34B44B356A516B765AFCDD3F5475B1F928731D09D2170
+B97E40F12CCEDF4F6BB3756C4734F6E98D74B7E942A954B1BAAB83D4AD727FF6
+DF6DC50B2223BCB5568A73A112E4860AD490554E64E780073FF3399CB4688D33
+9E8829667CD6EAEF25E0C7D2D44F2BBFA40E999325F9561514844221B50BC8FC
+4C7AD68CA7220D69125C2AF06849A3E068D18733276F0C0A6A2936D3C2C87CDE
+59CD1AF148C44F85784A5DAD569F5FF53C061056C067CE29AEF1E3BD1FD8B0B8
+71A0A638CDAC6AEEDBD5337D4683C084BB60B1859E600F59CB4E19C5FC5C6327
+EC544A68134496A9BD0B87D83AF6FDA3CB62FBF0B54FACE1F0E6A2D84B467AFF
+0F62DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR10
+%!PS-AdobeFont-1.1: CMR10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:52
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 11 /ff put
+dup 12 /fi put
+dup 13 /fl put
+dup 14 /ffi put
+dup 34 /quotedblright put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /exclamdown put
+dup 62 /questiondown put
+dup 64 /at put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 74 /J put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 89 /Y put
+dup 91 /bracketleft put
+dup 92 /quotedblleft put
+dup 93 /bracketright put
+dup 96 /quoteleft put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+dup 124 /emdash put
+readonly def
+/FontBBox{-251 -250 1009 969}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C
+295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75
+409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C
+4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF
+2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E
+0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E
+B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008
+24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B
+43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF
+D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575
+5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC
+96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3
+7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC3BEFD8D9C400015B65
+0F2F536D035626B1FF0A69D732C7A1836D635C30C06BED4327737029E5BA5830
+B9E88A4024C3326AD2F34F47B54739B48825AD6699F7D117EA4C4AEC4440BF6D
+AA0099DEFD326235965C63647921828BF269ECC87A2B1C8CAD6C78B6E561B007
+97BE2BC7CA32B4534075F6491BE959D1F635463E71679E527F4F456F774B2AF8
+FEF3D8C63B2F8B99FE0F73BA44B3CF15A613471EA3C7A1CD783D3EB41F4ACEE5
+20759B6A4C4466E2D80EF7C7866BAD06E5DF0434D2C607FC82C9EBD4D8902EE4
+0A7617C3AEACCB7CCE00319D0677AA6DB7E0250B51908F966977BD8C8D07FDBD
+F4D058444E7D7D91788DEA997CBE0545902E67194B7BA3CD0BF454FCA60B9A20
+3E6BB526D2D5B5321EE18DD2A0B15E53BCB8E3E01067B30ED2DD2CB9B06D3122
+A737435305D42DE9C6B614926BFD44DF10D14402EBEDFF0B144B1C9BD22D7379
+5262FEEAFE31C8A721C2D46AA00C10681BA9970D09F1EA4FA1566B96E221864A
+45A24ADAEC63F61C9FD18376D3984449A1F998C318A8FE36D0D5020E18A49625
+0F3BB603BA1F3E66FF412F6A32433FF8BD2968D79CE4273AD0E0CDDA5153C2BF
+F8A46A2244F9394A49D339F763F5A7411A3C29336B21CCB01723705AF589B078
+3763035411FE36AB5D744E81379106890688CB5BC41184548B7FEBA08DE7288E
+E6570FEA20C51FACE8E8F824BB61A4A038AB817C47B87391611B77928B2565A9
+3B27A573C05D36ED01D8F27CB2C793370FA9B90021B5696280A55F2CB6117B64
+293EAE0EA5A243F56FD007773CA35DF71B3D28643C25210CCE25F37A5095D6E5
+9CAFD99DD1DB0D7EAD454C13464DF6FF5DD42339797AE5AE467084550FC00139
+6EE818C6365007B2FD6E26285B832CFE6EA7E99665A224C9813C036CED26263F
+C49F0E777B84916E1D6483B365292F304B82DD801CCE0FE749D4B510E63E268F
+3E576C585E6093A1AEB5365720147036692AB13A9F2183C9B0A4536829527A87
+1675FAB2359C933F411544907831BFFDF95A00BC89906CB15B390B4056935FE7
+A3D1015BB185EB7D3520192B2EB04F842B599E820AA732AEF815A7C0E8E6461F
+44EC25D6647CABA9B3A9EA4929E4C6E6FE9D66116D00489138C37E74ECBAA66F
+448A59A7F3987B7C48404DFA79E891C71E5ED5656496D52A56E760131E50759E
+3A8E6BD681F01E0CD4D821FE6B4F057B017A8E732C8A35874D9F52ACA5FC06EE
+B85412A262AB1D3D9D621E90ED588742FDD9762485F58546896475CA6FF1FCA9
+19D56DB33BEB7EB417D5F101827F12F1BA77AE85A64374E8AFEC10ECCDF31E5B
+3F2A26E8C08A95719B80B10C45C588DCFECB70DFEE1793F359409B9ED9932CFE
+E826BC700EA3A5C56F183DCE3395AB80B2F38EFD323FAACC449FE9A8FA546DB1
+A5A2BF321B44A42AFD5180F72C54B3BECF8F45DF82915275973E60D8D4D5C4CE
+66C23BBB1149E16C5C8D02843A33C41A764DEC2F69484B107F5A07BACEEBCA7D
+9C2481740592CB2A64F622D8EAB1CE63B7362019FA72A6FD5004B5D035EAB391
+F39C2B495A83EBDD179928DD895E59036ED21BB5FB1A6EDB78BB1754A2E80DE0
+DB6D3879A8F08E59FF4923DF35F869D79F8547444F901750579634976B4F9DF9
+289F3A163C87B83805FCDE0022568949C60C352251F4CDEDFED566E2C7CA0A40
+B309EC5325453720F02A01A702D73CFB13D4FC524F098CC30853E143BA992468
+09B12F76C0C05D9369E0A8939D8FDBC0EBBE739C6E8675527EFE9C11DF3BFDDC
+991DC68FEC382AC1698C53A2AB16D74A5CF70C5AB5123F70FB08ACCE9A325E52
+40139298F52E0985FFCE7BF010092A345B88B8F03BB0F8649081CF715E63468D
+60166DC3A7ACD6EDFE4AB8B4FD180E91D54CAE13D6F36483564DEA500A872F31
+A131A36E15CB1FF2FDBD14B553FAB24810F077E70031D6C19CB6D6D7AAB9BE67
+B9BA171F90850008E21DCAB96DDB3B57D88B6E8EF658061001EE11D5E1792BCA
+5E98960ED3CA5176441866783D9F3D4522C82848D9FD2FC198946BDCA25CE3C6
+E9459411C452D5025D55CD39A54DA73045C6737F2DEC46229FEDD6B688BB624A
+80C815CF9BF6C0B5BED6A78D180CA4D8603E215E09C28AD5C0AD2CDD701EA54F
+8906D31866CA9E3C4082344453955FCBCA63D215A0E9EE13BD08857E85263DB1
+CD20E95C258BD796F5759D43E6A7CFCC954DF365F27C9E49FB044418DB5A38E1
+F865B87FAC14FEC859C47637739C6CB70CB7FE453C26A16FA8310FE15A6E120B
+D3E58688BFB304C050B9D667C98AA8F98E10C9EFB60E91C9A0992320A21AC91C
+D35A7B323E510B9408640A763E72CDDA94BF9573A2F86EEF8F6F7D806B7C12A2
+1153C990E7D6A86DF99BD07C825029E8784E897DA1A3358E85BF4A6CBCF84BD0
+242FBA6987B6C20F4DDD8AFD3508139C955DED0C92AE1EDD5E9C387B2C2823C3
+3F8A1BD24C7CFC320D437201250CDC1C4472998A2E7F847B5872F4EB4B755478
+88F742E1DE07BE43869FC7A56AB58C956FCCD694523F793D79A644547DD3FBCF
+ECDDD729953B5E1F091224B64650E030CF85DF4CCA77629C37997718B063AF1E
+C0B3F874BCDBBDD388621948EE7A4210EC8653DAA64D5FF983869E41C714ABC6
+9D336E8005FB1822E2B69542036C1A9A865272A25C31C3F64C6D7F3885E9811F
+A75E9D35B0A0225E5C819C77624465513FEE3AEDD88280E5BF917DAF757EBA2A
+76011EBA680E2D44F835398058528FB7DF026F8387D7F9B0469EB617D510077C
+DFA4E2D112EE2245C831BA21192278CC7A408D31126B777D6CD750569C54A285
+6305605486E2AA347CF18EAC50271F0F1A7A0A98BF5876F7225C9439E5EA6463
+67613DC4FFBABC2A28C660F9984DC1E67CF73CA9A766818133BEA94F4A20B74B
+066949CA81B933B1AC992E20E246F50A7666AAA6E76CDEB158BE3B8E9DB8A2F8
+1DEF8175376FEDA83A68F1EE26C5D3572241CC466B0C5643C674371DAD03EEAF
+9AEA36624AB81C60F02BFAC76C20B1AB27B63454EB737E163252E7692113B176
+DA490B87347B0CE59430F48017A604FEABFA985AA9F25B6A0C00F83D60E3C46D
+E3A8FBB5976F94286AA6929EBDBA28EB473BC3B344D8061336B69253A740ED13
+C1474A0E4C032012F0BC8ED03FFE0256163239A3436F03E44D570C6E56D9485E
+01E296848B0F2583C69FF7EFA83458CB383301A06BB7AF968B66EEB34888F653
+5FDFE262DB861F4B08720F2906499F474D167F4A07AD9FE03945070C3EA67484
+7CCCE1E4F9CE0336E6DDED2E0AF15619DCF1EA85805089C1278F8A7DEFB323B9
+1C898065EFB7B5BCEEFB5C59AE85F52C57CD3BDD348B06F9C4CFD42AD2993085
+34789CE150259ABAAD698FEC66D9EF67F075680FF6C6E9FD1D113D0EE32D1B33
+1530B3E058F5CCBC275BEB3AA919B7E9127288227AB038D1FBD2BED9660550E5
+5C02135FF9300E1204F2187F6A595A6D27DFD26A93AC68C0D20F9DFD6BDF6D9B
+37CA0DA0BF02C0C5AB96AC1215DD399CAC6DCCE9C716798098B576F4D4B86BBA
+B92DFC1FCC50EDF9244F6F7A42ABB6DC2A46543F2F1AAEF3B5336A5905846137
+C6A1F8ED3CC8BD2823EE2111F7B7CAA56B4780F86426DC9180D45EA96F77C3F9
+B76F4A43B97A9A719FAC05457FACC2A8C5E73DE19562A5D729E054DB27380D97
+97D17921C76FC284E7B43763A0B67B1AF5762E4D669CCD89D0F7AEB0029F810D
+E0069E1ADB72A619B35747A346591832ABF5EF13D0490247B80D413661E0CC92
+540E34A3B54E73E1A12D6297F81164C561CCEA2B224871CDFE79B72B3D9800F9
+D827B466C5B47F979EFAE9D87BEB36B40DCD52DA5303469FB1C907DD453D2C3F
+6C919A3E92AE0E01F1C32E8497D52E1427C6873CC98671E34269906C5B2B75AD
+822F9F85E75114BA91AB600956888C133CAE8F7A699793A3EEC2BE100803713F
+5143B749D6A85C2D22E6F32DDC2EB1A1EF21FCCB910FE52DA950704E5C514CC0
+D60D5129E4D4A124B570DC7E6A3251A5905D46E8B0BE7809654D056ED2D8A44C
+759D1C6D1EDB6C45505B1413F725B9D7443DD9684A92B532EE0F33261A1C4849
+E1EEF4C64E3CAB07DAE459416A9FB2B16CCD9D8D895244549B8828ADE8D761CB
+D1517FC64C06A70069BA6B16ED355C07425D705135A1E064DE04A597B0C7456D
+1E2ED4E583A5C69183B3D17B41FDB722A7809A13365E21A1D1A99AE60F454B9D
+0599BDED30A04D7C95EFB9D0A10595F8FFD50E562FD0F6127DEE3772EE4F4525
+DC97CC8BC53F7AC995C9E440D0E875E58BF1ACA74EC74FB3A5CE78C5ECFDF8A4
+99E99E5E136938FB34C91F51C7F863AE8BF0AD40EEFBC93DBAE1324C38FBE723
+6B5DBA46F5AD088C61F6D6230AB3C99088D56117193B8301CC6E343338209D01
+EE589D5FA3DF57003043366F60B2139E7A17E10BA8BE4FDE17E27FCB974E9385
+8ACCD7AF715878C6F228A8A8AA9C69693BB5BDB58C1D68C2E28551E3D5C1E33F
+8BDA7C629A9BD6193FA788D920E7A677E57E8552EBFB00C9D84D11389D8A11F4
+21B4EAAD439E346D63458A2A1A3F1583DEBAB5A7A33C4A6335B45A13767987C8
+6E495D7F23FA2DE2F5B4785AE9A7B2C40F0719792F66422D36BE2B4B390F8236
+9BCCFC774E4B5179D9BC8CB1520B75FC0D7ECB4941382DD657BF5ED50175D6C6
+8729D1501358FFE737387E89FE0AD691D8EFF2BD86A57B17709E0EF0ECBC96A9
+F102F3349D95C17AE75754A286FF6959F3CA9FF5651842E75131901E97B3B932
+2E0141017994E413E1F93693D579BD6C521441326C7D25091DBBFA75D9EA9055
+151D028CB66497589A428284BBED7EA4DB2EF7ED566FA9567EF8D56CC980258D
+5ABB441ED1EB04D011303839801EFAA40AE53BE9B48F2B7223708281B5B65AA1
+CEE59736799C02E469DEDB4F9E2F7E33482204843C8D8B5C295362398EC27F53
+907499D43DEF1723EAF19A4E4BD0B8890D91D622CC4A4792631C994F1854B0CF
+A5E63C33DAB1E4EB4A8493B661A2C457AE37512D373B8343BCC981403F70C78D
+341CFD02EBAC5D52A0A491B649F5BC9275DF19DDC255985A426494C500C5D2AD
+4201EDA6B9A96F27CB58831A43F0F0F161E38BA3E0082F7AC9645E9406699723
+FBC0FAF8D4D6081025AB35664F764DB73B3894CDACDA36E3252A12546273A120
+0B496CD9DC64FE924782EF85F22036D7F03857A2EC9D234E2248DC602175A647
+DB5888769B0BC18B063B0FFD535B21A55547661B5D831CA7B200D0E4A3C9C5EE
+99A52B67E8E9EA7951B0D1941732384DE53EC8AC0DDF76C7E27D956B80FE6F37
+381F6965B5AED5BAD763772969D2679FB2022FBB89E512D36114867F40080BFC
+5DDA337E92883D9E9911100782D1EDD68D4266AAF272EC6EB179C460FBC8143F
+3580174679BD7F38847E83B75F5B69D0DE8FA016A76535FE7B4378C494BDB84D
+A116618047358AD430AFF8DBE6983C3F3F75F3040336877F46629DFF423A9035
+371528C298D03FB41DED682A27A00A88BB5DC5856AAE9BF5EF140C52FB2FABFF
+3574923C258760DFE4FD70DF481C73450D48CDA480F1945729AF017CFC837971
+0265DEFF88D97D1FCBAFBF2A8DAE14386CE8A70CC217B0100CC6D37223399E63
+F5B1B98E14D6A4E8DD43C70E87CF0AB8B346F0586D89CDF10ACAF10E49BAD8AD
+AA6C3111F45DA2DB3101AB2746534EC0EFE406F4275F0DA1419E246CBA5C1ADF
+236498E32DD021ECF5F582FC8C551B8640EA58E76BD129E78D90C0EC66466B68
+5A6C803A2D3C0CFF52A3AAD818F5E73D225065DF75CB9846B48DD57F74C9F5C6
+D2792EB327811AF009E0820EB02BD8CD5C62DE2ED7641C62CCB765511BC94B47
+F56CA89814BB97B63D0C2171BBE363D960EE2B7F7083EAAA06D0D6023DD36919
+14F9B84E6494F29E971AEAD27B4E4F85F3EEDBE234E0E6DEE6EA08643A01820C
+43F2C72FF2267966847C38F7D54361DED43EB450E7F4420D0B2FE8BB0688F809
+3D1EDA4F38DC9DB7289622F04DBAC8E171CA4E6D6BCEF593D03E2FC77CC7D116
+E69C4F8F8D51EE7B264A0EAA24BADFCEEACCB7D27B3246EEBB8C8DB2C61AEBEF
+04452D91D9DA8272C213A78D9F78C066FD91BED3BFC5965BA1B8432E8579DA87
+00A808672A90B6CE2EA347E1A0B156B1C27FA507531409D5D8DCC3F02EFE77CC
+0AE903F87425762A168F30CAA62FE9F3EAACB83E1F78E943140F6E85E880B4D0
+E12373B8F9A18F3595EF78E65F7C9ADEFF3CBCA72A2A4DF8ACD2BFB44752156A
+4A514CB52B129D462103D3F5F0BEA110D42875B026085E032A3C1D27D005041B
+6483A5099403C8055405D8B81F4062E943D89852BFB66C55697598D05A6F0E4E
+8E01B4AE6646B443D2E39AF7ADD317425B7355A8D3A7912E5EB0213810E86BC8
+05FBB02B764AC78F213F88C7D331265704B543BF77BEB291253708005999B77A
+DCF8EC2AD83CF640B7AA9B48F2B36C8CB508AA6DD15FBD44B7E2912FA5020B23
+5001AE0AF093E13EF567DC0FCBF2E34B4AB120F7808384F2BDFEE6C38C6D8BF4
+F2764275166BD6EAC3F352AD4B30EDB0FC889FC4EA9FE2633902151B10A82D3D
+84D4FF9EDD0C6A4A1CF9D120EE583FD9169287FF53B1DF5CDC46FD6C8E242091
+C9D8677BC27907FC34333E3AC7C0C26C936AA768811AB3CAD54610CB1E6F2A9F
+5D682B49F1CC43A44AC420E06247A41A086E3B848BB1EF3AA1944D86B3CAB1A3
+BC8CA8EE5A1A309CC8FF6DB97D0D9872F980DEED8108A990648F3BC0EFD029A1
+65B58AA0F86BEFCFCCC96E1C406680F7BE3390A59C795C0758C32A979D1352A0
+9C6D1B0A7D4090A04AF0B506C5880BACA50AF45DE2F0DA6F505C61BB2F585FBE
+B92502C7C4F5A904CB921F6920868193D050EE90B0384B987AFCA9DA2EE65A05
+0FC9F06EFEAA0D5F04F303455DBD46B5B3BDE5C397B74C7820292B69126E8CEE
+3768E7D66DC03C76DCFDE48F18B72F9546AAE0B41C6EEA3AD7E4231C73023B33
+1D337E4C366F604BC12EAF5A539F0D810501488888DCD6F9205C6BA17E49D42D
+7EDCD51347B58B27EDB9AE211267EC44AAFC903A5C5B119A8508B1486EABF78C
+8711C02B5C59E4BAFAFC3BB9BD7EF207A651C98740BF17C6746844111D36518E
+3B987ECF290972CE474FF1D946E340233A5F7D4F3E94CBFB06B2F270BBB26828
+CD77AAF982B578AB6D80A67F013556466095556211ABFEFE06C8EE1FA6856248
+F622404619D380FF3E1C156734550D4D97945A3B4995C3814A498F87250EF77B
+FA82578F38F348288735D2D95CC5603861E0CC3D2564CAA1B1FC025633607B22
+8D2540BFE42F629CFD67ED30DD3E92BE01DA3EDDBC51D6DF28AFEA1B3FCB4D51
+19E277148F66B42351E3B8109B15548118B46DC36D8A3CEC36131831D00C7070
+E6D4A085076A928C41A3826E4D0F5C52627D675EB57960E7FF599D14727FBE00
+A2ED57D22EB2FE87F84407BEE9470172A68E27FC7013C7CA588947CF40E2EF65
+25558B9ED1A088BC0BB2337ACC0F11C2261E9034A4F8CF9315C24C605130631A
+7F4DD262C45CB5B86C7AD37C665423A0250885AC9FFAD228733AA729ED572B88
+B2D39032BDF84FEAD1687E0062E9DFA35C71403CF0ADB903F147606C33442F62
+A8484A11137E9A86D4FBEDCC43FBDE79A3D36072A2E7FB685652D852995AD756
+27639246B2BA6A9119A1F4D067617C2E4D527388C866C98B6C53E8E4A5CBACFE
+1F74F7F9568F5EA86F99CDE98788090E1C38BBACFEEECF902B66AE6F0FE7269C
+F11392901F4032225D13BEE482260DD6BD78DF492F043B51AF1D61D501CA44FF
+EC3F3ECE2C6383AFB6D1F57E434B21F14FAE1552593018D0E685C40303700873
+7E544E87C877B07EFDBB86FE44B5190BE5D00C06729E7E8986E8B35394D3EA68
+E4D3715CF2CCD4C0E165DDE8B6CF59615034539398C5266E2E2B522EC679CE8F
+A0F80D188DC3E2C920ECA30EF637F6362A012A5227BB8770CBD55CEE07D4CBF2
+63458269BEC9780719B04760A06846F8BF4CC64D3DEB7E7E895D3B3F6112841C
+FE545275CCB6C0958ABC83AB9550988080A4292945CC8F89AC18AFBA645EED61
+A3FCB74E4309A13863CE7EA1297AA8549B17DE4730A2E99AC332283E358DAE94
+9F691E1AB022AEBE2020ACC8407DFE1812D2FFE4EDF2323B4B291EFAA2149338
+41E79ED8E6DC2767D80A47E722B35714AB00B4D21837033E5135E7BB829CF666
+849852ECA6347556CD70DCF60CBB7736F0642C96532E80CA5C31E5197E9B2F2D
+D4068F2E326416BB63E4386DF632B72F18D789405E24BB0B6696DB5DB25EACF1
+FF114E060F11B01FE06DE3926B11A11E6E8084F93B5077CC251196AE6733B75A
+7B08BFB39E76B53D9743E0FC303C62A5DEF4DC6958C577B48CBBD3E5F01BC6DA
+404EE6373405A0D4E6DD62D4B8D3D338CFFEEB8B3C2A65483D830E2B48B8BE27
+44DFBAD5C1FEA4F59978C42664CB90E1E94D3C1F8E3FDCF196C602C8659948BA
+9AE923624C3DD746D5FB2D54D2B00EE0C0A1683793D2A97E0E527259338B482B
+FD2623FB5FCA2E747953324E012B4C10E2ACC8BA1A9E608F6364ACCCC756EABC
+36BA4F4C3D5A181A38F1698F9A08D310DC671370AAB4059A49CF17BF8E40148C
+AB78A6C12CD83071BF50341EFA99C1DC354AB2AD1D1D336BE13121B00104DC6A
+07A3F7ED08C45803BEC24544907E63D91AB1239D7561B43F18C67EF80002D3FF
+FB1678D3F5B07ADE54F24C6038119FEFFB7300F7B08BBCD132841E106EF8CC09
+395441427E2E9B33C48E0A6A22542235E86AB4FAD43B2007B2AA744BE9150DF4
+5AA749DCD30ECF71604546B0B847C0103FE48CBC039C4E2BC89DBFE54836AC82
+A3DF906E8B2B0713643A58A8DC5A109DEAB7C59ED161E802014B74234302466A
+09528B86140F068BFD9B1ED193E5BE839022ED1FAAA3AF2FE7B5F686101141B5
+ABAC9750804131DA3D72FFCE16CDC364CBB7544AEDFED89B7CE6D5E4A61D76FB
+F47D627D9D9692CEABBC52677AE6368AE6B5DC6BA026556DEFB02BA58B0E240D
+1EF11267B888B01A63F97CA740D0BC38E3232F90E854DB1EB7DE6DC0115E7303
+B24064EC1741520625AAEBE2550487A1D7C96599CEF70F773397AD7702CD8BB1
+41D880F6973DB58E05AD11FB9B62DB00682AF379C0C0B4E8F581E677AC8447DF
+5FB1161E9D66D3E01C51DF6939955801BD094F1282210E7919B62DCBB04FFBDB
+438AA55E6022627923BBFD38E8487D3500EC063BA02EC4E3DA1D76C95CB23EF7
+407F152278F61F33E8BFAFF54BFA0A0A911E52C74E399884B8E9CC2C198597D4
+0C1E50C2C3A0B3E9776E857CE952FD53292D5ACA5A85B1802696B0A597F1C087
+1BC7D71C2318D42867EDF131A67F48C36F617FA7677A7723A277A09FFF58743B
+489FD8DEBDBCC1FE850A1C88DD55C707AE2690E8EE33596F6C60532C6C5DD108
+0D76AD1BDE8CCDD61CE23F06388A075EDC32A50449AF10227DD402DC65633B3F
+8D2581F23C9F7A8757FFBBB6C84497C305A9F614E12D4D16C985150408AF65EF
+A6A231157C12C2237C831ACC6CE968C097FABC5753074E2C10221E7CC3F1A9B0
+A21FB2F07AF569694834A128392368B9E3D560FCCC43C1E1441F7720A12C99BD
+91023B570A6A3C2FB068D71A8FB7F80633BB2E73810098481D07EE45A3824E3E
+8C5195C192915F4A282AF65371F83EA308032DCD0B1161623972401E6F47E865
+A031FA6BD92F2B4356760A74EC5849330518C77704D87E32790482196B65ED9F
+5A24EA55286342AC01C95E896093E21EC42DE57D46015F5374CABA9CC324A2A4
+A60363A5A671B5883164D139A7562B77FB16EE68DC4A182654A61033D43D837C
+999D59A3D53B13BF904EA38ECDCD7D90D3E126AFD3CD32B838850D2F4C9B331E
+42E2D620D12F8615B32DAF5724E17F877DB46A7D9BC5B5612A6B44EA6196BBEF
+AAA259978530CDBB5FF99645B31B5ED8ECFB40E13BCD5B6C957E779AFE3FC2B4
+56137601503BFD4EDDF65C4FBD6807646F803F67078AEB7016616F3D8396C876
+E7792B33086E6F26FEBA53460610E0B68FB2720CB154C9F87B11F182C62D212E
+47D433329D8542E52EF1C13EE5D079FA85D5706234548B4879E4ACE04CE802D1
+54F2F9032D8E2270B799DBCD225386492FEEA9B86160DF34DFDE2ADC65958810
+C41A3297EFE7AE2A6A596804FB0B9315B2111AB2B8B07C3980C0146E8219B447
+BAA8A92A868921AF315E780A981F5E48143C35EFC814DF692F2DBA30600B0637
+00A65F32445467A4A9519AFC37EB4BDF53EC00BC7ECCFF8768ECC02EFF53AAB9
+4B030CDE05A898EE563128420705A64A98A9D5EED099779C3B5428C63D6FA9DA
+6E04248B2038CCAF754D2F529A236E0244C59C25F36CDCCF57A9985229C96651
+D830CD4733DF5FA7A72261FFE34BB474491372A320A333FF96BA54DFB2E82919
+1B315662629AAF0855A1CD3E58B9ABA1C79E7D5BF24910F00E1292B9C9267E45
+0C7350853AC3BF4F1167BCCCC0F724511F57A6A42B17646E6A3BC7EFAC5BA34F
+352F994C8EBF8912419EF4CC67EA4484C7C7D5C95AA7B71E95C1EF55D2A432A0
+161DEBBC98FFF7C0AFF7264C54437E66C888464323808348EC16F87E5D5C5573
+5F4A64DB7027912380FDFDF5E53A8BB63A024A941A75E26356050228E7E724C5
+438C90FECE44E5697ED6C21856422461178BD5251040D19439F0B1EC66C13867
+58331F062689B713E33074AD062A379B84D5B25F9E5971C2D6687917DC80F064
+A879A8A987182CB30F3708753536374567F929F154D18E5045D687F8C00E281B
+F3A3DCB6B6ED5B77534CFE86F31BA10E9D336DF723B81EBF075EDBBEB0DD0530
+1AAAC49743A6D9CB2865070C3D3654C2E08611251583013B7534B85C7C6609CF
+05D826D960AA9DAE42411522A7B12F54B8AB07B61C96D89BFFD91A1A985464F4
+C2B93B6720A431EB9335E290D0E740367F5F49BE315C03F98323D99E06D9B320
+E09AAA1BD4C8637FBDE1AF162597E0C9D25A76C55109EDBF99229C9C883DA197
+9410C330443AD29216EAC40F6FBEFFC0D056896BA7576411E9308EA52F055442
+85733DAC50E9C6C013719D06435CB85D3E177C25E9D73C6AD5122352D1F45C3E
+D5D0F0FC9C049E384843E7A798935C09BC554D0A1A02AE33D19AB72EFFDEFAD1
+BD2863FCF5A1374EA6F91F2FEF877C047D2DFF37DBFA96AF7CD2845B6211672F
+19912F9B245BCEBDEFBB6A98EACF0DB6C46CB278F8974BC16CD233322E5D5596
+DF4CA18E67239C6FF461932A9110CC6B71DBE419841BC02F236D084175F278D9
+71E8F584C421FFDD93AB1D90A6B72DB22355BED3C674B0DC16C4229A16192F8D
+99060EBD30E7DE1F4C5BEF0E56BC0DBBC7890B0FE367B00EE677AE9DD14D338E
+9DE0B6F3920237964E4C513E40222C0A85B4EC28796A0B611311C14D3CF05243
+29C109A18C32C4612ED7C9A4CE4EE6F110BB43C10794BB54F906E5F5D80B0DB7
+D5251DDD4F8EB602B6C578F28FBD5E446A1C80ECAFD4B997A545C7CD08508CC1
+0C9252A7B740308074C1FF1367FD767097D6A9A7CDF909FF12D06A0AA805F60A
+6634EE43BE791758FE9BD6E371C6AB6B7D0C70974125A155448765A7661F6A02
+0392EBD10085D77503260B681DCBEF4BD5A0F630D5D883738AB8921F0E270758
+44FDDAB152EBA78377BDDDF384005EF1219FD87E03347B77DE593099583C8CCB
+C643747E67AF0E2B22A4A89F0BC289478D1432E1E4849D70F8E41ECF1C0C14D7
+53A4F3076E9628AE6F7FBFC255469A5AC25E6A75EC95F70B5861D063AF205859
+00285ED3C8D06FC22F269A3E8A205CD891695FFA4FE4FEE01B1E47EE6091EEC4
+7C964E1FA464B69F77245963AC771ED09980EEDE19BD32E8021908C231459D45
+AB473C23141DB8191BDE2A192642E01BC82BD4FDE72193E19E27DB2606044E1D
+D754998151D4674E5FCCBF9392D77AEA51BD9AFF8EB1AB4A680ABE0C42F03E26
+18623C039C07B7823564846C5BDD7DF94056A35A41C6DE67C866E5BB2799C1B9
+78F2AAF17DBB97C322740BF625F7F064844429FFE4231567EB7D3E5CF09F0B76
+DD9E9E893A90F67111C04BB36B6C4864A73A50B444118005DBF8ED0399653E7E
+8FA5A071E9FBF06E08A2C6A954AD8C2746B1F96873986F9A7F5ED35D3DE2F948
+B99D5F9DF1463C3FA32D51AE97025E47ECF5B570E9C78BB66ED2ACED1F44EC98
+7F04B4E7216A1FD5C0DA01A36B0FEBE7DD680DAB36080C4B4122F110408D99AA
+D661FFF663A0106BEAB1F3CE1D192CD3C998C34F4400BB6B4125C46CECABB38B
+EBDBDDA35D7EF7CCB1CB3924A04EAA597CF47A835A0360F99DC70168252322D5
+73D7C949A70607479393D7AB97B900E64E7F90EBD3D34DBAA8975F6D1B428CE3
+D1461C2FAC7FAD3F08FDA5D8DE14D13C5B27F502B3C4AA6CC99B90DD73527B5C
+6535C78A69AD66C396B4F1F3CCED8481B716108635582C890AE917B0ECAC02FE
+0A4BD41F8AAA11076717BA4E2C3562B9FBF738DD12E6122298B8133E5A5D0121
+065EEC55D723BEFB199332EF8205A8506FB2A4091BA6946DFDE56582517C7A05
+A9367C7903CCAEAA9BCD50AE0CA454BDC008B6A6AD873D2D5DFD4A5DBF3E18EE
+4FA422E1874964354AD38614F4E51A09B86131BA7FBCC7B0BD388B502112E12F
+4F6A88CC471F904F0C3590FC79AC9AB5CBE92609E7DC5683F9361249A80443E6
+F274715AC12C7FC29A3DCA130D77686D67B2498EBB9C94DEC29D7EC79539061B
+0B6B982ED0F3C720AA9B327F8DCADA82F5060403F7F1C07AF9CD8E2F9F040A28
+3C467CB1417BD9E960CB8EFEEF1D6C9CB5B1F3AE89A456509FA0E990015E8431
+7A5079CAEFB2B2A087FC51DB67391F1E0703DF913FF76B218EB20D1B6AEEBA8A
+94B09B2A4E3C19CEAD189FCC96E8DC5CE71B70BDC72C82EC51C5C4B25BCF9749
+29624E8C3AC8E48D1A65E0AC6D4748881C33DEEA17E7C4338BF0D323116C6F7C
+87FDAD2ED534A42DCDA7B4F5CF7AE66D53D501B7B47C380E66CBFBDB2820258C
+F2AD488A47AF1622AC5DDA36814D7484D6563F0020153BAA0265AEB91E37FFAC
+1EC76AC9861F544AE7CCADAEB58A2D3D931642C314F2DB00E12FCD3632C81289
+BD61597DA6EACEEE3B68249B7237E1CAB1115EBAB2993D47A939200BFD230956
+B89DE0A9D4D280AF7F2616B38035467A6D8E3219AB5DFF4216068A2BE26F6011
+D7A2329ADFA6A2505DC25CC2779B26694FFE055C85689BE8A528FAA4CD231049
+A6445C5F12F161921E402D84B935DB473B92A1CA7BA44BEF990FC0D8F60E89A4
+3AE4914E4F1C5BC868CEAFE38B94649B3B37ECE2248F3C1CFB13DF1C04F3ED92
+735C3287AB76E1A61A7BFA2385B9EE5FEB66507A503159411DEF970028FF0AC1
+23BD4D2147BA0249A180730F4B348F866222D9F9CA9B293953A3039023ACE4DF
+CE369E1E0F791E6EA00CC2A83831F4920725B902B9C2B3F3ED7212C7EF5F0371
+EF9131D1E5B567FFDA00589ABF90659C4E01C21DEAB21EC2EAA112C6C6D88381
+B10107F2ADF6971B319259201401BC10937EFEC7E4A7D24BF43EF2EBC2386563
+6F278203CCC7E58F60D43C062771004652EE186BF514AD71106F19C3F2C53FFD
+1E32B71BC5F77D263C5F8D588140E92D9CA9D6A751BA7F989E04450C0D34B1E1
+1E2BBE8F3FA46864AF93F1701CA72B6FB5FAAC3FF5F171005532E24C56FB3BC7
+4E5A03A76FFC01287AEE8D14A7790D30F9ABE22B9F1CCB71F796BA877BBBA6EA
+6DF0AE60D91E27C4519BF617498A63580A799B8BF34B7160503F836C5D02D328
+60559B4640597022330540CDF67F99745ECFBA6F1DCA95093C5C143EDDD4C0E4
+BE00C66A898595A82CC548FAEC8E085A509F8C8104764AE81A1FA7095E995E33
+C79A3D8B92312F2F02DAD78D89F714AA853C45F0BB9EB602865E61A00923EFCE
+DCDE0DD31AD92EA240838DABC25D5F71CDF6BD45FBD1AA84E36079A86C22EC37
+71946868BD57E88F0B97F28C29008CAB42F790337D3D59E184FB6E3059498E09
+9E2ED4C97BF8AB621689D2C96765E75786F43E7184CA269D8E8052A12D8AEBF3
+23FD7858FFFAF709B6061AE615072061CB64C35861622F5CD9299616F1DEBF8D
+42E8DBC0223B5D92BC2C22FEC79D4FCD32C89AFB7B5A6A5EB0D57B1CE723B76E
+2A8B162C7FA8F086F7FDD9D505B526F70F3ADF1A6B0ED584992F294AB1A1D3D2
+0115923AB229042BA0E9364ED1651859A8C2D6B6437AADE898A682DCB9E1DD4D
+D7CEF7A0E39D5C5257ECD5F668FF5D5D45EE0248D89AFCEAD1D6328FC805C0A5
+03D2B2404E3FD03FE48F858A51736D1538DA01E7D2F508CCF81EA3C794FB1220
+3BDD86D24DF13A39DAEAA8673B1EFA72BA624E842D4B2D1FAB4B7A63067D1500
+081E0DB5805DD6DE4AF411FD43B9B10A7E855B2991AA8965B1A90FFD73333F03
+2C1323A9AC3642FFD74A9BD7A9EFA46308D24D0E27A4A007C8166C162113F361
+D199C3B803D0E324677D9E3447FB1B2C82F113B4A725A418B3617187C57924EB
+845834E46BF99AFB73B6852C9369BD9FCE8CD26838A0D8400CCE1807E5C765F3
+1925348992C0E6C778D92D7A7A1DFB0CE387E5A50D1625657E774302D9A2316E
+59D6076B8C88FD01725381D8FE01DEB764BB1E24E90FE9906DE9481998D8E906
+BB9F95B142AF11D339B8C5482F0E98DAA865023FC0524BF8394DC81DAFB67395
+20AE9459F964087B8362F728B7347394563A4105C9BFF81D0C2F360B69891EE5
+9DB051511C573BCF0597AA0AB3794663CA6CFC0CF9760396A64EF6C2C879B885
+D777CA99B48A8F4D2D0012E4B8FA2749C85E6CEFF1A6C29CA0989DE54E58EC0F
+4D06D82992594960C5DBED6D17536503C159B632AFADE17E774D312B8B6CD995
+BEE0BFBF4EA8F331711A735E4AD7A842AC2B107406F6F0ED54C7B287EFBDB4E5
+E9315B23DE4FBD7426CA49A5BA8292080DFC2D2D77E4F4928A213BFBE7714A94
+8A26553688440C8FA108E9CCA68988F1B31B8038FB509E6BD904F6A17DA19E66
+26E2F1A57657CB9E2B2CB76CAB193EE91D0F0CAB51A506CA7FEE2274164B1409
+37DF39519EF7E6E1A130E100487744854C19A121F35EDFF7C83B0B3FCCBDB024
+9707AA3FF6A3B327F027FCD4E4202E14A2DA3C41B12F157E7B5DB8AE0E81B737
+0D735C2729BA7976A0EE8AE635F0FEE5F96954B469C6A72D480D396BEB9871F0
+C9FC2EE301CB3E1248722A3B86B8134C93321CA88DCA907C282733CCAB35E4CB
+3107BC514C9CAD7D52F75E1A437DD46AF31D7B7EE04943399BE1D255B3279398
+66CD21DD2B4E2875C6F72D5E99C54FEB066798C9AB5545BF15734A4EBD484DAA
+77693E036AC7CB7C5B8527F2F99C31ABE37FD6E4474CC7DD27EF806C5228BDFE
+A06219647952B8530D5D33493AA8ACAFA6BA51729242046942344475293B7BD6
+A2C7390BA0EB60A271DBA0782C91C5E446121A7BF639FBBDF0E77AB76A480AE6
+5B52553323E5C236807BF448480FAF7DE0E2A3FB9D0EFC8F504037673819C089
+16D71C3DBE3A95CCCEEDA2E66CFE3C7E0C7399ACB3E9F6AEB1FC2984F6C00629
+E91EA64EE03E5512106D4C7A012221AC4DA21E374D01E75E270987B1AF330AC7
+02F85C2BE65A88DE3C675D5BE47F1EF1041186F8B60609A326A58379ABCA5C4B
+5620EE3F06B504079A5CA2AEE005638DDEB4594F39B3C6C4AFE03781D6E8251E
+4B9A87C235B262C9781F390696BC0041E488DB65D1C8A17BB4A1F06394621FF5
+B8E6D52742E7189EE34EC85F4F5F1A22FCDDE972D36B75B342BECE3C4B53E50F
+049718BDD7808E9859990A9F1D2F43F96845919ABE72773A98B6B3BB46FC2047
+4C76560C59F2496833653D10FA222AACE6465B57240A9D448E4A5771B8707FB3
+AAB3D0B568044EE1926715083206E6418CFE789EE80C5F47B8EEC0F883D90DED
+6A5224C5FB2850B816C9D3403D4DADDA39262C67281AD9404D56428004DBA4BC
+CE2BA2962076E1A4B9A3FB0F4FB4599FFD84EC1D39724EC05D33C856A9DF55FD
+4BBCCC658037497354691A22EBFDBDB4316A92A7DEC61953361C2311A7ADADA8
+E70C4E5E547BB130680A94F529DEC3114E7C65C34D221B3557B84978306C1D67
+0B8C1EC51FC53C1D3AAA22B8279F5A45A6F412302037B9DC41C21CFB893EFAFE
+4F9DA4F8B376673ABDB6D91E13A9A67DB1E9DFFFEF67A2858BA19EA53FC9B6EA
+236449B4D7F0E227AD57BEE6DA1C1A2A55386A35C1F61F10A5C44F01DB3C8C5E
+D3BE5A9783360271498B22BDC9E234C3EC9D311EB97A9853829B64A7F6B9F3A8
+CC0731568478FA6BE4A007A858BB878582419E17298C7F84F455D199CEF65F09
+B47F30604E0EFC78183D79570DE20B2B327619FF29C2AD813A97130FE746EE88
+8C0D9EAD5C93398344B6AEAB4316DB0E53BB2487000A90CC4200C3919A872CD0
+BBB3B63BA4796F6BCD90718E2181C8E271E70E373838C046FC3C3BA70E928BA5
+1ABDF512EC95AA722D8CB76DAAD2987E6C2691CBE491ACE71A2132F9E6926FDA
+4C43E5DABA82F389C5389B9B8A2FFD9F37560FC811825D443B746583F17E4924
+E23A9F031223FFA7DEE7A867BE14BDCA6ADD6DBDB3208DC6E4E334E68A27ED8F
+120EEC82852DCA35126BF8B2E78D8A0B89BEE17A77FD9CDE2732182619C089CC
+659254AA6B776ED1733AB8C42D225BDBEB672CB9CA775208361386F866F53F74
+164F849BB68AA2442C45D946CCF4D439DB37A4E69082BFA5BB5E91C1EBE32119
+00232F885F36D28CCE574F09FD7C56711B4D107CC1ADB88F0F39B55AE94DB029
+80CCEE436522592DE0329D14846FA1B8C7C9BFF946795C753806DB31CB51E1EE
+7437EC755739E3084ED73225DDC280562161758A7B138DA56008DFBC51EA4FAA
+7BE0A4D7158E61B9037D797015B2F314A210EBAEE66FF3DAF594C3091CD45962
+7A5A086DA2A587E4130D2553EEBCCC45A5D52D95E546C71A73CE8FB389B87A0C
+20CD85FCDC9B3B13BEA453B5363330A48655F619EE410382DA95A0E3AFE68FC8
+911E3575654804F9F977B364A9F4D1E9D08AB9E45A1B0A5A95BFC01E3E84F878
+2C1AA523CD8EED128BCC600928A2AF85645C8A4B1661334E1B438F9E229DC1B4
+64AF943F36BD6BE743C35075321D631CFF5CBC771A365578E0BBD0C7CDA5DF6F
+B1C478C10C7FCD7C332389F20092F15DBB75EA971B937E2B7D38DAE377E7CBA0
+5C54DF3FE72A934B9A3ED94465CD80AFBAC08066F91E727740E9B6C9AC52DEA7
+BC01A2DE05995C3CB47D6BA030C1DA8DB2FB22359D6D0C617C71E4BB1BD1946B
+C91F9FAB619DB1F5BEAB2472F00E176A47E99A83F3445499A55F4A8268016197
+FCE56B1CE01CC3D4C3788B531D02019D696E915F077072F28149BBA4BD0A516C
+6209783A949F1A81BE698845AFFE17DEE349093BD16C0F96568D9D27FE431588
+6AC1769F2135DB186998293B58186D19F5CB7B1EDF970F71A9305B8A26BDC24C
+6BC7922972424528C1997C2F6F410A45445B087CBC0EBB4C0E7D231E9F20726C
+DF58664C08A81BEB23832A0C86FB722AEE3991CF875AB5D8681AD1D8BA58BCB5
+2CFCEB21F795A137615016ADFA307249D61EDB9EDCFFBC8F96B1605A726C97D0
+D37863791B3B0601F73CE10ED6E2C706DAF57FBD7CA7824EDDFAA9C80FE56132
+2F130992876C777927A9118808AF922274197785111953A51535BE32F4AB9CD4
+58282883218C12DC901CEF2AFF8DBB48D6C618DFC32544B176A4F5A11DA372FE
+89EE959DDC089942ED089C04E1E7EF247AA27371CE4BAF643619F562EF4D1177
+4C408F82D076E9D4DAEC9F06070456B1DB58778A4690591BCD4C4A2684DF754C
+78491F1BF14F31E0F54CDDA93C9F676831CC6C939CC1D99045BC1CA0BDA89277
+D97853CC32EF9D24F7AE38B3A1608149213537144ECE8EA0A15C10663A29F8B9
+99DC6FA6D192FFC35175CB0034FD81AE3C3A05C11F366CA1EBF617900EAC5A90
+449920186A7B3104B3C2B2239D0558A68E6D7737329BEE76E7D0241E5B0EADB4
+E0AE1984A31742C57DAB49DBC0590F126393998D383BFA5D19DFA6FD3B76CFD6
+0A3A93B28890F2542671D4A49081810EFAAC16E816167F314F5C1FC39D7CE17C
+A7EB3BB7CE5D4880F8CD08152DB58C0CBFD0AC21488BF625F0CAA80E9BE3EADC
+9C2C4EC608D2115AD51E60B4332F7F725932661C2E5D06F01F79D37BD485996B
+E468A9ADF8CFAD80589216C7EAEAD1C0F710D5DD42CEB4A753692EAB16C8F5BC
+C4C9946A22885B54D7E582427718BB52406D63504D89D6E62BDD739F3BFD3C05
+39A4B7E01F921B9C3608CEF55A081E6A191332790E5002CB863C4910E93F116A
+49D388D04549C91C2DDE669BF8E79E5B41A5542F74502BDE07C55FC7738DB392
+049140B1E4094B6F845E3562D7CA88351D8B061317FCD00EB54BE6A959FB3998
+F04BB2F9FA0259E557700192F45AE12CDCEAFEB5E6A543906D6E519B70C41AC2
+3B11E3E385BD77D68AE8CEE2AE2CAEA3006E1725A5E19F6464EC8C9DB0DA4B43
+52185413E2737BE2EC4BC7CB5F653421B90472B66BDD08E545042EF39D704027
+1CE042B3AFB69207EFB0CD2B1A69EBB246C14436307ACE1C3848DD2CD54A5A18
+06477C6673E3000989EE32D6423E2E6CCB806869D57411EDAA3080A52AF70E4A
+C8D340235F1CFB03AE89391BB7914091A0F6515683B405E7D3BD44AF71FE85CB
+A6CE8B0E81C52ED001E1FCFC5EE85F537DCBF2089C8F955BEEC1C55B75EDF320
+C18002829AD22756EA92D726BD0F875DE1ED6E07E69A6CD9952AAE70EC4997F2
+0B3736F2240D385BDAB32E2524D6714EA9433D5E90A799D574D394852702564C
+0136B51FE442ECAD6A585388C8ED3FF96435C31AAA00C86F5BE439E81579245C
+05F620D82DABD22D76592DB55FEF6697C893C7C96AB5DAE87D978E5A6267A185
+F4C4F3F8D12D1BD122E3DCDC2A04948D270E2E3792C30824BE1AC4DD90AAF4BD
+F3E140BCEB6A8BAB087F1BF5635FFB76CA1A31DDF9A2C0C05547428ECC7350FE
+ED4E9B56F9422129559ACB00BCC3523A4895AE2AB68B521170243285B64AFEE2
+0262805D884DF5600AFAB1C2BA3B08E1431A3B9E2CFCF51A2AD9AFB827A1A204
+9E76BC52C454FD4220F60FEA2988E73973E380DCE4EB901B09EA28A33496176F
+588342A9F341EB165BB88B993027E9F71230CAB96EA0D72B8F7CB13F5EA5EF74
+07466C93119D41F33D402757EBE020F7AE4ACE31503E310E55D81D316C86CC3A
+16A4D860D17E9CF88B64956A3148000771FEB92965FE4F4C4A332D5F48C5FACB
+C089180303A4AB93624F6814E5621EDC7D3A26D933D68CAFFFF41071CACE3EFE
+31870EE6B98F4CCAC51BB58EC54F57DB3E9C99F8D5F57F17AFE692A79B1948A7
+F317F8E21E93918ED26BF614FC08F7D8186B9E04428114EBE899B661F9978A5A
+6E41DF03C3D74E1EFD1F43CC707BDC06B18AE1C524B86A4C3A5D64C2F0ACC7AC
+04BA163263E50F7CB14DCDC671AED73525724BE64A20B20F81CACDDE99FAA932
+59CA876A6EDCDDC2F9F96B96EC88048172B8B43670BB08FFE17C3BA0ADC57CDC
+95400079F64BFAEB76CCC2CE61443B9D50E982085FBE677519121A19631F3F6F
+7B530C85EE131764EEF6627698826D046B1AC468D1446263B4DB16188393132A
+A6F885F355E1EF766CF02115A7BDD8DF107DC1C06C0B84A6FC762ECF3256ABE2
+0B34A64CCCB27019E894D564F1B3F6B633FA8179A14ABE373B7F5EB7D4CF1B64
+9522B36BCD257F42877C8A96EFF3EC9D80AE794BCFB79D4157633E5A6E4765C0
+0A13EDBCF9DBB799A3AC4E8A00621D036F651759F9D9F35D62B4C3E3CF0D80D7
+CC9EBFA4D8CF408358FBFD9005F6E3ED1A031ACDA42EA390C2F7B4151678DD3E
+F3317C7005D100B01AD0013FE40D0E9099862163D876973A0DE300B8EF86AD4B
+04A23E5CE287F971F55660CBC2C92068483CDD2BDCC630C4FD453E931799C3B0
+7A84B693F3763F726989B76AFEF44242AED19CB3BEC6A233EF07861952FF713D
+ECC4AA586543A83DDC9982C31FBB3714A80470F029CECB1C3F647207FB8B3822
+82B9DAB1477F96A4AAF07F2DA33CECFF42380FE29FA075436361E88496E7F371
+30DE318442822FAA3EBBEF7C601739F2F73F9306B832A16AF534226AC5148C3C
+5B89DE5A4B26E9EF2E3A29363BB05A0EAC6B82D28493A95679DDF5E90617440A
+C8AD981302C5E964424B23248D8E54C4019BC4EA9AFCE2A2F40A42C25D50304E
+451C02C8898A07D1BEFD2C6B37B166B2EA0EC754341320BAA3852DBB9A4B38B5
+FCF5A8BD8849348EBAAB298F182EAD8004E642327B1A24BA44493A02B5687932
+E4649D6FBE06B4827B9346A1DAF75CBAEB31160C1CA11D872141BEEB903DC80F
+FA8B9BD5AD68953C69112B0395CC440E5A63EA38C850EEECD062DF737862C9E9
+90953367B16C8C2F2401798E4EF9D6855E52E5F2A0ABE162CDF4C78453855448
+7C9D54F4F03F02E04E09E34597108DCBD8E8C8AB2E5FCE4C44D02DC350AF3CC9
+831ACC98DCA4AE83CB7D64D4F90FB6BB892C724F4016DC38B91D037892CC343C
+0344F9B1397D62F0C5B2E5B66CD8E08621ABDDD8A644369E971526A0F471A8B8
+9D8FDF9FDFBFFE22E13C197BA2E6BF93C24EDCCC623F2934DB72CEE5E3C00DE4
+A37A1423D59788131A0630FD2E2E4FC6DDF403BC3BD827A1B2DAA01DEF1A650B
+22D81F2B1F5CE5119DE1E51DA810CBFB37E482CAE666ADC078534745D579A251
+B3C4A63714E1BD536AFC7C8FAC8659C439DD7215AF636F61E3E793654EF2F1BA
+16D783307E331210A655C6869123BCEED9D6DE84B410A20FFDE8268D715AFCF6
+453D888E39602B1CA13B5EEB66DE0271DEA59F930DCF6C028299C4B9F7EE8EF7
+F760A313DEDBF33BFC7508BBF7E0215D520E162DAEAEE6136556D9F37F40C4E5
+44909214D6FB777212301ABBF372FB056CC9C21AE0C178FC584C640B7CACB594
+D4EDF275BBD7256CFD390B18F5A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT12
+%!PS-AdobeFont-1.1: CMTT12 1.0
+%%CreationDate: 1991 Aug 20 16:45:46
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 43 /plus put
+readonly def
+/FontBBox{-1 -234 524 695}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660FE13FF01BC20148F9C480BCD0E
+C81D5BFC66F04993DD73F0BE0AB13F53B1BA79FE5F618A4F672B16C06BE3251E
+3BCB599BFA0E6041FBD558475370D693A959259A2699BA6E97CF40435B8E8A4B
+426343E145DF14E59028D4E0941AB537E34024E6CDE0EA9AF8038A3260A0358D
+D5B1DB53582F0DAB7ADE29CF8DBA0992D5A94672DFF91573F38D9BFD1A57E161
+E52DA1B41433C82261E47F79997DF603935D2A187A95F7A25D148FB3C2B6AA32
+6B982C32C6B25867871ED7B38E150031A3DE568C8D3731A779EAAF09AC5CE6C5
+A129C4147E56882B8068DF37C97C761694F1316AF93E33FF7E0B2F1F252735CE
+0D9F7BCE136B06EE967ABE0C8DF24DCBBF99874702ED252B677F407CB39678CC
+85DDFC2F45C552BA967E4158165ED16FECC4E32AC4D3B3EB8046DCDD37C92FDF
+F1F3710BB8EF5CA358ABACA33C7E5ACAD6BF5DC58BDFC3CF09BA2A38291D45A4
+C15FF1916FE2EC47FDC80911EB9C61F5D355BEDFC9DB17588547763AC5F0B1CC
+12D2FFB32E0803D37E3281DA9CE36C5433655526ACFB3A301C56FAB09DF07B5D
+048B47687348DEB96F3F9C53CE56DDD312B93D3918CD92AF53FB9461864D11B8
+0138918D0B1270C54873C4012CDE6F886DB11BCEA04B023EBB43E0D0A06BE725
+741D08B9DB688731A6C9886C15A83C28DADCC81385EA239E045E8F3670CE03DB
+9EE77ED067036595C9F3B1854343BE3A12E486B6E5A2F8AC44FA5378D28DCCEE
+306B0E283AA444423F9A4FF38E2B56DCF67A39CEB2C643DAE86865517D5D0371
+CB8797208ADEC637330A3A57902C9A88EDB75A7C16FA9850075D9F19578EC666
+1353CC1FC512D59DFF847ACCD058E2058E262194FA3370E876BBB803BCC86390
+9DA3AF2A74FFCDE3DC525731B9C696BAB3E0CD0D3DB061CA1B00E3BD9C5AF268
+97ECE57F738B592F4F7F9515A29D0D76E93E3C8765020B7840312BE5E4602B75
+A3AAF16F492451ADE4CBF379D22CD167959C5A79679B23E907925A671FB3B63C
+D7E7437162FFF1E33A17492409A1AFDC7C5932260B241507BBB215E4716878F5
+FDA295E8DB5EF28BA26B1E3CF65CEBFADF173782520615E6D8792E366579CFFF
+C35A09C850EB339C2A263183D305C861EF5B39159BA628D036861B66C3D3FE2A
+A7BC6EBE272A0F53E20A4CDE5ADC4D8480096DD7E6EF44F7540A0C47FC17FF5C
+B2149ACFE568B3B8C1AB270C71A5D3072921
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+TeXDict begin 40258431 52099146 1000 600 600 (liboctave.dvi)
+ at start /Fa 197[21 58[{}1 74.7198 /CMMI9 rf /Fb 133[34
+41 41 55 41 43 30 30 30 41 43 38 43 64 21 41 23 21 43
+38 23 34 43 34 43 38 15[60 52 60 58 1[48 6[52 59 55 1[58
+7[38 38 38 38 38 38 38 38 38 38 3[21 44[{}46 74.7198
+/CMR9 rf /Fc 162[28 1[28 91[{}2 99.6264 /CMB10 rf /Fd
+135[52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52
+52 52 52 52 52 52 52 1[52 16[52 1[52 3[52 1[52 4[52 65[{}30
+99.6264 /CMSLTT10 rf /Fe 134[48 48 66 48 51 35 36 36
+48 51 45 51 76 25 1[28 25 51 45 28 40 51 40 51 45 9[93
+68 68 66 51 67 71 62 71 68 83 57 2[33 68 71 59 62 69
+66 64 68 3[71 1[25 7[45 45 45 45 3[25 1[45 3[71 38[{}54
+90.9091 /CMSL10 rf /Ff 214[35 35 40[{}2 90.9091 /CMSS10
+rf /Fg 133[52 52 52 52 52 52 52 52 52 52 52 52 52 52
+52 52 52 52 52 52 52 52 52 52 52 52 1[52 7[52 52 52 52
+52 52 52 52 52 52 52 52 2[52 52 52 52 52 52 52 52 52
+2[52 52 52 8[52 52 52 1[52 1[52 1[52 52 52 52 1[52 4[52
+33[{}62 99.6264 /CMTT10 rf /Fh 133[39 39 39 39 39 39
+39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39
+39 39 39 39 5[39 1[39 39 39 39 39 39 39 39 39 39 39 39
+2[39 39 39 39 39 39 39 39 39 2[39 39 39 39 39 6[39 39
+39 1[39 39 39 39 39 39 39 39 39 39 4[39 33[{}69 74.7198
+/CMTT9 rf /Fi 134[39 1[39 39 39 39 39 39 1[39 39 39 39
+39 2[39 39 39 39 39 39 1[39 39 50[39 6[39 39[{}22 74.7198
+/CMSLTT10 rf /Fj 197[25 58[{}1 90.9091 /CMMI10 rf /Fk
+197[33 58[{}1 119.552 /CMMI12 rf /Fl 133[72 85 85 117
+85 90 63 64 66 85 90 81 90 134 45 85 1[45 1[81 49 74
+90 72 90 78 10[122 124 112 90 120 121 110 121 126 153
+97 2[60 126 127 101 106 124 117 115 122 7[81 81 81 81
+81 81 81 81 81 81 36[94 11[{}55 143.462 /CMBX12 rf /Fm
+134[48 48 48 1[48 48 48 48 1[48 48 48 48 48 2[48 48 48
+48 48 1[48 1[48 10[48 1[48 1[48 4[48 8[48 48 1[48 2[48
+1[48 1[48 6[48 48 2[48 48 48 1[48 4[48 38[{}36 90.9091
+/CMTT10 rf /Fn 242[91 13[{}1 90.9091 /CMSY10 rf /Fo 133[60
+71 71 97 71 75 52 53 55 71 75 67 75 112 37 71 41 37 75
+67 41 61 75 60 75 65 7[102 102 139 102 103 94 75 100
+101 92 101 105 128 81 105 69 50 105 106 85 88 103 97
+96 102 7[67 67 67 67 67 67 67 67 67 67 1[37 34[78 11[{}63
+119.552 /CMBX12 rf /Fp 131[91 1[40 48 48 66 48 51 35
+36 36 48 51 45 51 76 25 48 28 25 51 45 28 40 51 40 51
+45 25 2[25 45 25 1[68 68 93 68 68 66 51 67 71 62 71 68
+83 57 71 47 33 68 71 59 62 69 66 64 68 5[25 25 45 45
+45 45 45 45 45 45 45 45 45 25 30 25 2[35 35 25 4[45 19[76
+51 51 53 11[{}80 90.9091 /CMR10 rf /Fq 212[89 43[{}1
+172.154 /CMTT12 rf /Fr 137[102 1[75 76 6[54 6[88 1[86
+1[94 17[145 11[140 67[{}9 172.154 /CMBX12 rf /Fs 134[44
+1[60 44 46 32 33 33 1[46 42 46 69 23 2[23 46 42 25 37
+46 37 46 42 7[62 1[85 1[62 60 46 61 1[57 65 62 76 52
+1[43 30 62 65 54 57 1[60 59 62 65 1[39 1[23 23 23 42
+42 42 42 42 42 42 42 42 42 42 23 1[23 2[32 32 27[46 12[{}62
+83.022 /CMR10 rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%BeginPaperSize: Letter
+<< /PageSize [612 792] >> setpagedevice
+%%EndPaperSize
+ end
+%%EndSetup
+%%Page: 1 1
+TeXDict begin 1 0 bop 316 83 a Fs(@c)24 b(Cop)n(yrigh)n(t)f(\(C\))j
+(1996,)d(1997,)g(1998,)h(2000,)f(2004,)h(2005,)f(2006,)g(2007)g(John)h
+(W.)i(Eaton)d(@c)h(@c)h(This)f(\014le)h(is)g(part)150
+183 y(of)f(Octa)n(v)n(e.)34 b(@c)24 b(@c)g(Octa)n(v)n(e)f(is)h(free)g
+(soft)n(w)n(are;)g(y)n(ou)f(can)h(redistribute)g(it)h(and/or)d(mo)r
+(dify)j(it)g(@c)f(under)g(the)g(terms)g(of)h(the)150
+282 y(GNU)20 b(General)f(Public)g(License)g(as)g(published)h(b)n(y)f
+(the)g(@c)g(F)-7 b(ree)19 b(Soft)n(w)n(are)f(F)-7 b(oundation;)22
+b(either)e(v)n(ersion)d(3)i(of)h(the)f(License,)150 382
+y(or)33 b(\(at)h(@c)f(y)n(our)g(option\))h(an)n(y)f(later)g(v)n
+(ersion.)54 b(@c)34 b(@c)f(Octa)n(v)n(e)f(is)i(distributed)h(in)f(the)g
+(hop)r(e)g(that)g(it)g(will)g(b)r(e)h(useful,)150 482
+y(but)f(WITHOUT)f(@c)f(ANY)i(W)-9 b(ARRANTY;)35 b(without)e(ev)n(en)f
+(the)i(implied)f(w)n(arran)n(t)n(y)e(of)i(MER)n(CHANT)-7
+b(ABILITY)33 b(or)150 581 y(@c)25 b(FITNESS)g(F)n(OR)g(A)h(P)-7
+b(AR)g(TICULAR)26 b(PURPOSE.)e(See)h(the)h(GNU)g(General)e(Public)h
+(License)g(@c)g(for)g(more)f(details.)150 681 y(@c)29
+b(@c)f(Y)-7 b(ou)29 b(should)g(ha)n(v)n(e)f(receiv)n(ed)g(a)g(cop)n(y)g
+(of)h(the)h(GNU)f(General)g(Public)f(License)h(@c)g(along)e(with)j
+(Octa)n(v)n(e;)e(see)h(the)150 780 y(\014le)f(COPYING.)f(If)h(not,)g
+(see)f(@c)g(<h)n(ttp://www.gn)n(u.org/licenses/>.)150
+1830 y Fr(Octa)-5 b(v)g(e)65 b(C)p Fq(++)f Fr(Classes)p
+150 1896 3600 34 v 2339 1993 a Fp(Edition)30 b(1.0)i(for)e(Octa)m(v)m
+(e)i(v)m(ersion)f(3.2.4)3118 2101 y(Septem)m(b)s(er)f(1993)150
+5091 y Fo(John)45 b(W.)g(Eaton)p 150 5141 3600 17 v eop
+end
+%%Page: 2 2
+TeXDict begin 2 1 bop 150 4137 a Fp(Cop)m(yrigh)m(t)602
+4134 y(c)577 4137 y Fn(\015)30 b Fp(1996,)j(1997)f(John)d(W.)i(Eaton.)
+150 4296 y(This)37 b(is)g(the)h(\014rst)e(edition)i(of)g(the)f(do)s
+(cumen)m(tation)i(for)e(Octa)m(v)m(e's)j(C)p Fm(++)c
+Fp(classes,)k(and)d(is)h(consisten)m(t)150 4406 y(with)30
+b(v)m(ersion)h(3.2.4)h(of)f(Octa)m(v)m(e.)150 4565 y(P)m(ermission)h
+(is)h(gran)m(ted)g(to)f(mak)m(e)i(and)d(distribute)h(v)m(erbatim)h
+(copies)g(of)f(this)g(man)m(ual)h(pro)m(vided)f(the)150
+4675 y(cop)m(yrigh)m(t)g(notice)f(and)f(this)g(p)s(ermission)g(notice)h
+(are)g(preserv)m(ed)f(on)h(all)g(copies.)150 4834 y(P)m(ermission)24
+b(is)f(gran)m(ted)i(to)f(cop)m(y)g(and)f(distribute)g(mo)s(di\014ed)g
+(v)m(ersions)h(of)f(this)h(man)m(ual)g(under)e(the)h(con-)150
+4944 y(ditions)30 b(for)g(v)m(erbatim)g(cop)m(ying,)i(pro)m(vided)d
+(that)i(the)f(en)m(tire)h(resulting)f(deriv)m(ed)g(w)m(ork)g(is)g
+(distributed)150 5053 y(under)f(the)h(terms)h(of)f(a)h(p)s(ermission)e
+(notice)j(iden)m(tical)g(to)f(this)f(one.)150 5213 y(P)m(ermission)j
+(is)h(gran)m(ted)f(to)h(cop)m(y)g(and)f(distribute)f(translations)i(of)
+g(this)f(man)m(ual)g(in)m(to)h(another)f(lan-)150 5322
+y(guage,)f(under)d(the)h(same)h(conditions)g(as)f(for)h(mo)s(di\014ed)e
+(v)m(ersions.)p eop end
+%%Page: -1 3
+TeXDict begin -1 2 bop 3725 -116 a Fp(i)150 299 y Fl(T)-13
+b(able)53 b(of)h(Con)l(ten)l(ts)150 628 y Fo(1)135 b(Ac)l(kno)l
+(wledgemen)l(ts)36 b Fk(:)20 b(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)
+79 b Fo(1)275 765 y Fp(Con)m(tributors)29 b(to)j(Octa)m(v)m(e)16
+b Fj(:)h(:)f(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)46 b Fp(1)150
+1002 y Fo(GNU)f(GENERAL)g(PUBLIC)g(LICENSE)28 b Fk(:)20
+b(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)73 b Fo(2)150
+1266 y(2)135 b(A)44 b(Brief)h(In)l(tro)t(duction)g(to)h(Octa)l(v)l(e)36
+b Fk(:)20 b(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)80
+b Fo(13)150 1530 y(3)135 b(Arra)l(ys)20 b Fk(:)f(:)g(:)h(:)f(:)h(:)f(:)
+h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)
+64 b Fo(14)275 1667 y Fp(3.1)92 b(Constructors)30 b(and)f(Assignmen)m
+(t)d Fj(:)16 b(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+55 b Fp(14)150 1904 y Fo(4)135 b(Matrix)45 b(and)g(V)-11
+b(ector)45 b(Op)t(erations)32 b Fk(:)19 b(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)h(:)f(:)h(:)f(:)g(:)h(:)76 b Fo(18)150 2168 y(5)135
+b(Matrix)45 b(F)-11 b(actorizations)27 b Fk(:)21 b(:)e(:)h(:)f(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)
+f(:)72 b Fo(32)150 2432 y(6)135 b(Ranges)34 b Fk(:)20
+b(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)
+f(:)h(:)f(:)g(:)h(:)78 b Fo(36)150 2696 y(7)135 b(Nonlinear)46
+b(F)-11 b(unctions)16 b Fk(:)j(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)61
+b Fo(37)150 2961 y(8)135 b(Nonlinear)46 b(Equations)35
+b Fk(:)19 b(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)79 b Fo(38)150
+3225 y(9)135 b(Optimization)16 b Fk(:)21 b(:)e(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)61 b Fo(39)275 3362
+y Fp(9.1)92 b(Ob)5 b(jectiv)m(e)31 b(F)-8 b(unctions)14
+b Fj(:)j(:)e(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)44 b Fp(39)275 3471
+y(9.2)92 b(Bounds)22 b Fj(:)14 b(:)i(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)51 b Fp(39)275 3581
+y(9.3)92 b(Linear)30 b(Constrain)m(ts)21 b Fj(:)16 b(:)f(:)h(:)f(:)h(:)
+f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f
+(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)51 b Fp(40)275 3691 y(9.4)92 b(Nonlinear)31
+b(Constrain)m(ts)16 b Fj(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)
+g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f
+(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)45 b Fp(40)275
+3800 y(9.5)92 b(Quadratic)30 b(Programming)e Fj(:)16
+b(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)
+f(:)g(:)58 b Fp(40)275 3910 y(9.6)92 b(Nonlinear)31 b(Programming)14
+b Fj(:)h(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)
+h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)g(:)h(:)f(:)44 b Fp(41)150 4146 y Fo(10)135 b(Quadrature)28
+b Fk(:)20 b(:)g(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)
+h(:)73 b Fo(42)275 4283 y Fp(10.1)92 b(Collo)s(cation)32
+b(W)-8 b(eigh)m(ts)11 b Fj(:)18 b(:)d(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)41
+b Fp(42)150 4520 y Fo(11)135 b(Ordinary)45 b(Di\013eren)l(tial)j
+(Equations)11 b Fk(:)20 b(:)g(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f
+(:)56 b Fo(44)150 4784 y(12)135 b(Di\013eren)l(tial)48
+b(Algebraic)d(Equations)25 b Fk(:)20 b(:)g(:)f(:)h(:)f(:)h(:)f(:)g(:)h
+(:)f(:)h(:)69 b Fo(45)150 5048 y(13)135 b(Error)45 b(Handling)22
+b Fk(:)e(:)g(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)
+g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)67
+b Fo(46)150 5313 y(14)135 b(Installation)37 b Fk(:)19
+b(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h
+(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)79
+b Fo(47)p eop end
+%%Page: -2 4
+TeXDict begin -2 3 bop 3699 -116 a Fp(ii)150 83 y Fo(15)135
+b(Bugs)13 b Fk(:)19 b(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g
+(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)
+f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)58 b
+Fo(48)150 353 y(Concept)45 b(Index)18 b Fk(:)i(:)f(:)g(:)h(:)f(:)h(:)f
+(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)
+f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)63 b
+Fo(49)150 623 y(F)-11 b(unction)44 b(Index)31 b Fk(:)19
+b(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h
+(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)h(:)f(:)h(:)f(:)h(:)f(:)g(:)h(:)f(:)
+76 b Fo(50)p eop end
+%%Page: 1 5
+TeXDict begin 1 4 bop 150 -116 a Fp(Chapter)30 b(1:)41
+b(Ac)m(kno)m(wledgemen)m(ts)2342 b(1)150 299 y Fl(1)80
+b(Ac)l(kno)l(wledgemen)l(ts)150 631 y Fo(Con)l(tributors)46
+b(to)f(Octa)l(v)l(e)150 790 y Fp(In)36 b(addition)h(to)h(John)e(W.)h
+(Eaton,)i(sev)m(eral)f(p)s(eople)f(ha)m(v)m(e)h(written)f(parts)g(of)g
+(lib)s(o)s(cta)m(v)m(e.)62 b(\(This)36 b(has)150 900
+y(b)s(een)30 b(remo)m(v)m(ed)h(b)s(ecause)f(it)h(is)g(the)f(same)h(as)g
+(what)f(is)g(in)g(the)h(Octa)m(v)m(e)i(man)m(ual.\))p
+eop end
+%%Page: 2 6
+TeXDict begin 2 5 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(2)150 299 y Fl(GNU)54 b(GENERAL)g(PUBLIC)f(LICENSE)1477
+534 y Fp(V)-8 b(ersion)31 b(3,)g(29)g(June)e(2007)390
+700 y(Cop)m(yrigh)m(t)842 697 y(c)817 700 y Fn(\015)h
+Fp(2007)i(F)-8 b(ree)32 b(Soft)m(w)m(are)f(F)-8 b(oundation,)32
+b(Inc.)e Fm(http://fsf.org/)390 919 y Fp(Ev)m(ery)m(one)h(is)g(p)s
+(ermitted)f(to)h(cop)m(y)g(and)f(distribute)g(v)m(erbatim)h(copies)g
+(of)g(this)390 1028 y(license)g(do)s(cumen)m(t,)g(but)e(c)m(hanging)j
+(it)f(is)f(not)h(allo)m(w)m(ed.)150 1280 y Fo(Pream)l(ble)150
+1439 y Fp(The)g(GNU)g(General)h(Public)f(License)h(is)f(a)h(free,)f
+(cop)m(yleft)i(license)f(for)f(soft)m(w)m(are)i(and)d(other)i(kinds)e
+(of)150 1549 y(w)m(orks.)275 1715 y(The)d(licenses)i(for)e(most)i(soft)
+m(w)m(are)g(and)e(other)i(practical)g(w)m(orks)f(are)g(designed)g(to)h
+(tak)m(e)g(a)m(w)m(a)m(y)h(y)m(our)150 1824 y(freedom)k(to)h(share)e
+(and)h(c)m(hange)h(the)f(w)m(orks.)51 b(By)35 b(con)m(trast,)h(the)e
+(GNU)h(General)g(Public)e(License)i(is)150 1934 y(in)m(tended)25
+b(to)h(guaran)m(tee)h(y)m(our)e(freedom)g(to)h(share)f(and)f(c)m(hange)
+j(all)f(v)m(ersions)f(of)h(a)f(program|to)h(mak)m(e)150
+2044 y(sure)35 b(it)h(remains)f(free)h(soft)m(w)m(are)h(for)f(all)g
+(its)g(users.)56 b(W)-8 b(e,)38 b(the)e(F)-8 b(ree)37
+b(Soft)m(w)m(are)g(F)-8 b(oundation,)37 b(use)f(the)150
+2153 y(GNU)j(General)g(Public)f(License)g(for)g(most)h(of)f(our)f(soft)
+m(w)m(are;)44 b(it)39 b(applies)f(also)h(to)g(an)m(y)f(other)h(w)m(ork)
+150 2263 y(released)31 b(this)f(w)m(a)m(y)i(b)m(y)e(its)h(authors.)40
+b(Y)-8 b(ou)31 b(can)g(apply)f(it)h(to)g(y)m(our)f(programs,)g(to)s(o.)
+275 2429 y(When)37 b(w)m(e)g(sp)s(eak)g(of)g(free)h(soft)m(w)m(are,)i
+(w)m(e)e(are)g(referring)e(to)i(freedom,)h(not)f(price.)61
+b(Our)36 b(General)150 2538 y(Public)e(Licenses)g(are)h(designed)f(to)h
+(mak)m(e)g(sure)f(that)g(y)m(ou)h(ha)m(v)m(e)g(the)g(freedom)f(to)g
+(distribute)g(copies)150 2648 y(of)e(free)f(soft)m(w)m(are)i(\(and)e(c)
+m(harge)i(for)e(them)h(if)f(y)m(ou)h(wish\),)f(that)h(y)m(ou)g(receiv)m
+(e)h(source)f(co)s(de)g(or)f(can)h(get)150 2757 y(it)e(if)f(y)m(ou)g(w)
+m(an)m(t)i(it,)f(that)g(y)m(ou)f(can)h(c)m(hange)g(the)f(soft)m(w)m
+(are)i(or)e(use)g(pieces)h(of)f(it)h(in)f(new)g(free)g(programs,)150
+2867 y(and)h(that)h(y)m(ou)f(kno)m(w)h(y)m(ou)g(can)f(do)g(these)h
+(things.)275 3033 y(T)-8 b(o)24 b(protect)h(y)m(our)f(righ)m(ts,)i(w)m
+(e)f(need)f(to)h(prev)m(en)m(t)g(others)f(from)g(den)m(ying)g(y)m(ou)g
+(these)h(righ)m(ts)f(or)g(asking)150 3142 y(y)m(ou)37
+b(to)g(surrender)d(the)j(righ)m(ts.)60 b(Therefore,)38
+b(y)m(ou)f(ha)m(v)m(e)g(certain)h(resp)s(onsibilities)e(if)h(y)m(ou)f
+(distribute)150 3252 y(copies)30 b(of)f(the)g(soft)m(w)m(are,)i(or)e
+(if)f(y)m(ou)i(mo)s(dify)e(it:)40 b(resp)s(onsibilities)29
+b(to)h(resp)s(ect)f(the)g(freedom)g(of)g(others.)275
+3418 y(F)-8 b(or)30 b(example,)g(if)g(y)m(ou)f(distribute)g(copies)i
+(of)e(suc)m(h)g(a)h(program,)g(whether)e(gratis)j(or)e(for)g(a)h(fee,)h
+(y)m(ou)150 3527 y(m)m(ust)i(pass)f(on)h(to)h(the)f(recipien)m(ts)h
+(the)f(same)h(freedoms)e(that)i(y)m(ou)f(receiv)m(ed.)50
+b(Y)-8 b(ou)34 b(m)m(ust)f(mak)m(e)h(sure)150 3637 y(that)29
+b(they)-8 b(,)29 b(to)s(o,)h(receiv)m(e)g(or)f(can)f(get)i(the)e
+(source)h(co)s(de.)40 b(And)27 b(y)m(ou)i(m)m(ust)f(sho)m(w)g(them)h
+(these)f(terms)h(so)150 3747 y(they)i(kno)m(w)f(their)g(righ)m(ts.)275
+3912 y(Dev)m(elop)s(ers)i(that)f(use)g(the)g(GNU)h(GPL)f(protect)g(y)m
+(our)g(righ)m(ts)h(with)e(t)m(w)m(o)j(steps:)41 b(\(1\))32
+b(assert)g(cop)m(y-)150 4022 y(righ)m(t)38 b(on)e(the)h(soft)m(w)m
+(are,)k(and)36 b(\(2\))i(o\013er)g(y)m(ou)f(this)g(License)g(giving)h
+(y)m(ou)f(legal)i(p)s(ermission)d(to)i(cop)m(y)-8 b(,)150
+4132 y(distribute)30 b(and/or)g(mo)s(dify)g(it.)275 4297
+y(F)-8 b(or)35 b(the)g(dev)m(elop)s(ers')h(and)e(authors')h
+(protection,)j(the)d(GPL)g(clearly)h(explains)f(that)h(there)f(is)g(no)
+150 4407 y(w)m(arran)m(t)m(y)g(for)f(this)g(free)g(soft)m(w)m(are.)54
+b(F)-8 b(or)35 b(b)s(oth)e(users')h(and)g(authors')g(sak)m(e,)i(the)e
+(GPL)h(requires)e(that)150 4517 y(mo)s(di\014ed)42 b(v)m(ersions)i(b)s
+(e)f(mark)m(ed)g(as)h(c)m(hanged,)j(so)d(that)g(their)f(problems)g
+(will)g(not)h(b)s(e)f(attributed)150 4626 y(erroneously)30
+b(to)h(authors)f(of)h(previous)f(v)m(ersions.)275 4792
+y(Some)e(devices)h(are)f(designed)g(to)h(den)m(y)f(users)g(access)h(to)
+g(install)g(or)f(run)f(mo)s(di\014ed)g(v)m(ersions)h(of)h(the)150
+4902 y(soft)m(w)m(are)34 b(inside)e(them,)g(although)h(the)f(man)m
+(ufacturer)g(can)h(do)f(so.)46 b(This)32 b(is)g(fundamen)m(tally)g
+(incom-)150 5011 y(patible)j(with)e(the)h(aim)h(of)f(protecting)h
+(users')e(freedom)h(to)h(c)m(hange)g(the)f(soft)m(w)m(are.)53
+b(The)33 b(systematic)150 5121 y(pattern)j(of)g(suc)m(h)g(abuse)f(o)s
+(ccurs)h(in)f(the)i(area)f(of)g(pro)s(ducts)f(for)h(individuals)f(to)h
+(use,)i(whic)m(h)d(is)h(pre-)150 5230 y(cisely)d(where)e(it)h(is)f
+(most)h(unacceptable.)46 b(Therefore,)32 b(w)m(e)g(ha)m(v)m(e)h
+(designed)e(this)g(v)m(ersion)h(of)g(the)g(GPL)150 5340
+y(to)38 b(prohibit)e(the)i(practice)g(for)f(those)h(pro)s(ducts.)60
+b(If)37 b(suc)m(h)f(problems)h(arise)h(substan)m(tially)g(in)f(other)p
+eop end
+%%Page: 3 7
+TeXDict begin 3 6 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(3)150 299 y(domains,)28 b(w)m(e)f(stand)g(ready)g(to)h
+(extend)f(this)g(pro)m(vision)g(to)h(those)f(domains)g(in)g(future)f(v)
+m(ersions)i(of)f(the)150 408 y(GPL,)k(as)f(needed)g(to)h(protect)h(the)
+e(freedom)h(of)f(users.)275 568 y(Finally)-8 b(,)34 b(ev)m(ery)f
+(program)f(is)g(threatened)h(constan)m(tly)h(b)m(y)e(soft)m(w)m(are)i
+(paten)m(ts.)47 b(States)33 b(should)f(not)150 678 y(allo)m(w)25
+b(paten)m(ts)e(to)h(restrict)g(dev)m(elopmen)m(t)g(and)f(use)g(of)g
+(soft)m(w)m(are)h(on)f(general-purp)s(ose)g(computers,)i(but)150
+787 y(in)h(those)h(that)g(do,)g(w)m(e)g(wish)f(to)h(a)m(v)m(oid)h(the)e
+(sp)s(ecial)h(danger)f(that)h(paten)m(ts)h(applied)e(to)h(a)g(free)f
+(program)150 897 y(could)h(mak)m(e)i(it)f(e\013ectiv)m(ely)i
+(proprietary)-8 b(.)40 b(T)-8 b(o)28 b(prev)m(en)m(t)g(this,)g(the)g
+(GPL)f(assures)g(that)h(paten)m(ts)g(cannot)150 1006
+y(b)s(e)i(used)f(to)i(render)f(the)g(program)g(non-free.)275
+1166 y(The)f(precise)i(terms)f(and)g(conditions)h(for)f(cop)m(ying,)i
+(distribution)d(and)h(mo)s(di\014cation)h(follo)m(w.)150
+1399 y Fo(TERMS)44 b(AND)h(CONDITIONS)199 1558 y Fp(0.)61
+b(De\014nitions.)330 1693 y(\\This)30 b(License")h(refers)f(to)i(v)m
+(ersion)e(3)h(of)g(the)f(GNU)h(General)g(Public)g(License.)330
+1827 y(\\Cop)m(yrigh)m(t")e(also)g(means)e(cop)m(yrigh)m(t-lik)m(e)k
+(la)m(ws)d(that)g(apply)f(to)h(other)g(kinds)f(of)g(w)m(orks,)h(suc)m
+(h)g(as)330 1937 y(semiconductor)j(masks.)330 2071 y(\\The)40
+b(Program")h(refers)f(to)g(an)m(y)h(cop)m(yrigh)m(table)h(w)m(ork)e
+(licensed)h(under)e(this)h(License.)70 b(Eac)m(h)330
+2181 y(licensee)43 b(is)f(addressed)f(as)h(\\y)m(ou".)76
+b(\\Licensees")44 b(and)d(\\recipien)m(ts")i(ma)m(y)g(b)s(e)e
+(individuals)g(or)330 2291 y(organizations.)330 2425
+y(T)-8 b(o)32 b(\\mo)s(dify")g(a)g(w)m(ork)g(means)g(to)h(cop)m(y)f
+(from)g(or)f(adapt)h(all)h(or)f(part)g(of)g(the)g(w)m(ork)f(in)h(a)g
+(fashion)330 2535 y(requiring)d(cop)m(yrigh)m(t)h(p)s(ermission,)e
+(other)i(than)f(the)g(making)g(of)g(an)g(exact)i(cop)m(y)-8
+b(.)41 b(The)29 b(resulting)330 2644 y(w)m(ork)f(is)f(called)i(a)f
+(\\mo)s(di\014ed)f(v)m(ersion")i(of)f(the)g(earlier)g(w)m(ork)g(or)g(a)
+g(w)m(ork)f(\\based)h(on")g(the)g(earlier)330 2754 y(w)m(ork.)330
+2889 y(A)k(\\co)m(v)m(ered)i(w)m(ork")f(means)f(either)g(the)g(unmo)s
+(di\014ed)e(Program)i(or)g(a)h(w)m(ork)f(based)g(on)g(the)g(Pro-)330
+2998 y(gram.)330 3133 y(T)-8 b(o)31 b(\\propagate")i(a)e(w)m(ork)g
+(means)g(to)h(do)e(an)m(ything)i(with)e(it)h(that,)h(without)f(p)s
+(ermission,)f(w)m(ould)330 3242 y(mak)m(e)c(y)m(ou)e(directly)i(or)e
+(secondarily)h(liable)h(for)e(infringemen)m(t)h(under)e(applicable)i
+(cop)m(yrigh)m(t)h(la)m(w,)330 3352 y(except)34 b(executing)g(it)g(on)e
+(a)i(computer)f(or)f(mo)s(difying)h(a)g(priv)-5 b(ate)33
+b(cop)m(y)-8 b(.)50 b(Propagation)34 b(includes)330 3461
+y(cop)m(ying,)39 b(distribution)c(\(with)h(or)h(without)f(mo)s
+(di\014cation\),)i(making)f(a)m(v)-5 b(ailable)38 b(to)f(the)f(public,)
+330 3571 y(and)30 b(in)g(some)h(coun)m(tries)g(other)f(activities)j(as)
+e(w)m(ell.)330 3706 y(T)-8 b(o)28 b(\\con)m(v)m(ey")j(a)d(w)m(ork)g
+(means)g(an)m(y)g(kind)f(of)h(propagation)h(that)g(enables)f(other)g
+(parties)g(to)h(mak)m(e)330 3815 y(or)k(receiv)m(e)j(copies.)50
+b(Mere)34 b(in)m(teraction)i(with)d(a)g(user)g(through)g(a)g(computer)h
+(net)m(w)m(ork,)h(with)e(no)330 3925 y(transfer)d(of)g(a)h(cop)m(y)-8
+b(,)32 b(is)e(not)h(con)m(v)m(eying.)330 4059 y(An)25
+b(in)m(teractiv)m(e)k(user)c(in)m(terface)j(displa)m(ys)e
+(\\Appropriate)g(Legal)h(Notices")h(to)f(the)f(exten)m(t)h(that)f(it)
+330 4169 y(includes)k(a)g(con)m(v)m(enien)m(t)j(and)c(prominen)m(tly)h
+(visible)h(feature)g(that)f(\(1\))i(displa)m(ys)e(an)g(appropriate)330
+4279 y(cop)m(yrigh)m(t)j(notice,)h(and)d(\(2\))i(tells)f(the)g(user)f
+(that)i(there)e(is)h(no)g(w)m(arran)m(t)m(y)g(for)g(the)g(w)m(ork)g
+(\(except)330 4388 y(to)e(the)g(exten)m(t)h(that)f(w)m(arran)m(ties)g
+(are)g(pro)m(vided\),)g(that)g(licensees)g(ma)m(y)g(con)m(v)m(ey)h(the)
+f(w)m(ork)f(under)330 4498 y(this)37 b(License,)i(and)e(ho)m(w)g(to)g
+(view)h(a)f(cop)m(y)h(of)f(this)g(License.)61 b(If)36
+b(the)i(in)m(terface)g(presen)m(ts)f(a)g(list)330 4607
+y(of)32 b(user)e(commands)h(or)h(options,)g(suc)m(h)f(as)g(a)h(men)m
+(u,)f(a)h(prominen)m(t)f(item)h(in)f(the)h(list)g(meets)g(this)330
+4717 y(criterion.)199 4852 y(1.)61 b(Source)30 b(Co)s(de.)330
+4986 y(The)g(\\source)i(co)s(de")f(for)g(a)g(w)m(ork)g(means)g(the)g
+(preferred)f(form)g(of)h(the)g(w)m(ork)g(for)g(making)g(mo)s(di-)330
+5096 y(\014cations)g(to)g(it.)41 b(\\Ob)5 b(ject)31 b(co)s(de")g(means)
+g(an)m(y)f(non-source)h(form)f(of)g(a)h(w)m(ork.)330
+5230 y(A)36 b(\\Standard)f(In)m(terface")i(means)f(an)f(in)m(terface)i
+(that)g(either)f(is)g(an)f(o\016cial)i(standard)e(de\014ned)330
+5340 y(b)m(y)e(a)g(recognized)i(standards)d(b)s(o)s(dy)-8
+b(,)33 b(or,)h(in)f(the)g(case)h(of)f(in)m(terfaces)i(sp)s(eci\014ed)d
+(for)h(a)h(particular)p eop end
+%%Page: 4 8
+TeXDict begin 4 7 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(4)330 299 y(programming)44 b(language,)49
+b(one)c(that)f(is)g(widely)h(used)e(among)i(dev)m(elop)s(ers)f(w)m
+(orking)h(in)e(that)330 408 y(language.)330 551 y(The)24
+b(\\System)g(Libraries")g(of)g(an)g(executable)i(w)m(ork)e(include)f
+(an)m(ything,)j(other)f(than)e(the)i(w)m(ork)f(as)330
+661 y(a)k(whole,)g(that)g(\(a\))g(is)f(included)g(in)g(the)g(normal)g
+(form)g(of)h(pac)m(k)-5 b(aging)29 b(a)e(Ma)5 b(jor)28
+b(Comp)s(onen)m(t,)g(but)330 770 y(whic)m(h)33 b(is)g(not)h(part)f(of)h
+(that)g(Ma)5 b(jor)34 b(Comp)s(onen)m(t,)g(and)e(\(b\))i(serv)m(es)g
+(only)f(to)h(enable)g(use)f(of)h(the)330 880 y(w)m(ork)c(with)g(that)g
+(Ma)5 b(jor)31 b(Comp)s(onen)m(t,)e(or)h(to)h(implemen)m(t)g(a)f
+(Standard)f(In)m(terface)i(for)e(whic)m(h)h(an)330 989
+y(implemen)m(tation)g(is)e(a)m(v)-5 b(ailable)30 b(to)f(the)f(public)g
+(in)f(source)i(co)s(de)f(form.)39 b(A)29 b(\\Ma)5 b(jor)29
+b(Comp)s(onen)m(t",)330 1099 y(in)38 b(this)g(con)m(text,)k(means)c(a)g
+(ma)5 b(jor)38 b(essen)m(tial)i(comp)s(onen)m(t)e(\(k)m(ernel,)j(windo)
+m(w)d(system,)i(and)e(so)330 1208 y(on\))c(of)g(the)g(sp)s(eci\014c)f
+(op)s(erating)h(system)g(\(if)g(an)m(y\))h(on)e(whic)m(h)h(the)g
+(executable)h(w)m(ork)f(runs,)f(or)h(a)330 1318 y(compiler)d(used)f(to)
+h(pro)s(duce)e(the)h(w)m(ork,)h(or)f(an)h(ob)5 b(ject)31
+b(co)s(de)g(in)m(terpreter)f(used)g(to)h(run)e(it.)330
+1461 y(The)f(\\Corresp)s(onding)g(Source")h(for)f(a)h(w)m(ork)g(in)g
+(ob)5 b(ject)29 b(co)s(de)g(form)g(means)f(all)i(the)f(source)g(co)s
+(de)330 1570 y(needed)35 b(to)h(generate,)i(install,)f(and)e(\(for)g
+(an)h(executable)g(w)m(ork\))g(run)e(the)h(ob)5 b(ject)36
+b(co)s(de)g(and)e(to)330 1680 y(mo)s(dify)39 b(the)g(w)m(ork,)j
+(including)d(scripts)g(to)i(con)m(trol)f(those)g(activities.)71
+b(Ho)m(w)m(ev)m(er,)44 b(it)c(do)s(es)f(not)330 1789
+y(include)i(the)h(w)m(ork's)g(System)g(Libraries,)i(or)e(general-purp)s
+(ose)f(to)s(ols)i(or)f(generally)h(a)m(v)-5 b(ailable)330
+1899 y(free)31 b(programs)g(whic)m(h)g(are)h(used)e(unmo)s(di\014ed)f
+(in)i(p)s(erforming)f(those)h(activities)j(but)d(whic)m(h)g(are)330
+2008 y(not)g(part)f(of)h(the)g(w)m(ork.)42 b(F)-8 b(or)32
+b(example,)f(Corresp)s(onding)e(Source)i(includes)f(in)m(terface)i
+(de\014nition)330 2118 y(\014les)g(asso)s(ciated)i(with)d(source)i
+(\014les)f(for)g(the)g(w)m(ork,)h(and)f(the)g(source)g(co)s(de)h(for)e
+(shared)h(libraries)330 2228 y(and)g(dynamically)g(link)m(ed)h
+(subprograms)e(that)h(the)h(w)m(ork)f(is)g(sp)s(eci\014cally)h
+(designed)f(to)h(require,)330 2337 y(suc)m(h)k(as)g(b)m(y)g(in)m
+(timate)i(data)e(comm)m(unication)i(or)e(con)m(trol)h(\015o)m(w)f(b)s
+(et)m(w)m(een)h(those)f(subprograms)330 2447 y(and)30
+b(other)g(parts)g(of)h(the)g(w)m(ork.)330 2589 y(The)h(Corresp)s
+(onding)f(Source)i(need)f(not)h(include)f(an)m(ything)i(that)f(users)f
+(can)h(regenerate)h(auto-)330 2699 y(matically)e(from)e(other)h(parts)f
+(of)h(the)f(Corresp)s(onding)f(Source.)330 2841 y(The)h(Corresp)s
+(onding)e(Source)j(for)f(a)h(w)m(ork)f(in)g(source)h(co)s(de)f(form)g
+(is)h(that)f(same)h(w)m(ork.)199 2984 y(2.)61 b(Basic)32
+b(P)m(ermissions.)330 3126 y(All)44 b(righ)m(ts)f(gran)m(ted)g(under)f
+(this)h(License)g(are)g(gran)m(ted)h(for)f(the)g(term)g(of)g(cop)m
+(yrigh)m(t)h(on)f(the)330 3236 y(Program,)29 b(and)e(are)i(irrev)m(o)s
+(cable)g(pro)m(vided)f(the)g(stated)h(conditions)g(are)f(met.)40
+b(This)28 b(License)g(ex-)330 3345 y(plicitly)h(a\016rms)e(y)m(our)h
+(unlimited)g(p)s(ermission)e(to)j(run)d(the)i(unmo)s(di\014ed)e
+(Program.)40 b(The)27 b(output)330 3455 y(from)37 b(running)e(a)j(co)m
+(v)m(ered)h(w)m(ork)e(is)g(co)m(v)m(ered)i(b)m(y)e(this)h(License)f
+(only)h(if)f(the)g(output,)i(giv)m(en)g(its)330 3565
+y(con)m(ten)m(t,)33 b(constitutes)f(a)g(co)m(v)m(ered)g(w)m(ork.)42
+b(This)31 b(License)g(ac)m(kno)m(wledges)i(y)m(our)e(righ)m(ts)g(of)g
+(fair)g(use)330 3674 y(or)f(other)h(equiv)-5 b(alen)m(t,)32
+b(as)f(pro)m(vided)f(b)m(y)g(cop)m(yrigh)m(t)i(la)m(w.)330
+3817 y(Y)-8 b(ou)41 b(ma)m(y)h(mak)m(e,)i(run)c(and)g(propagate)i(co)m
+(v)m(ered)g(w)m(orks)f(that)g(y)m(ou)h(do)e(not)h(con)m(v)m(ey)-8
+b(,)46 b(without)330 3926 y(conditions)30 b(so)f(long)h(as)g(y)m(our)f
+(license)h(otherwise)g(remains)f(in)g(force.)41 b(Y)-8
+b(ou)30 b(ma)m(y)f(con)m(v)m(ey)i(co)m(v)m(ered)330 4036
+y(w)m(orks)40 b(to)g(others)g(for)g(the)g(sole)g(purp)s(ose)e(of)i(ha)m
+(ving)h(them)e(mak)m(e)i(mo)s(di\014cations)f(exclusiv)m(ely)330
+4145 y(for)45 b(y)m(ou,)50 b(or)45 b(pro)m(vide)h(y)m(ou)f(with)g
+(facilities)j(for)d(running)f(those)h(w)m(orks,)50 b(pro)m(vided)45
+b(that)h(y)m(ou)330 4255 y(comply)34 b(with)f(the)h(terms)f(of)h(this)f
+(License)i(in)e(con)m(v)m(eying)i(all)g(material)g(for)e(whic)m(h)g(y)m
+(ou)h(do)g(not)330 4365 y(con)m(trol)i(cop)m(yrigh)m(t.)55
+b(Those)35 b(th)m(us)f(making)h(or)g(running)e(the)i(co)m(v)m(ered)h(w)
+m(orks)f(for)f(y)m(ou)h(m)m(ust)g(do)330 4474 y(so)29
+b(exclusiv)m(ely)h(on)e(y)m(our)g(b)s(ehalf,)h(under)d(y)m(our)j
+(direction)g(and)f(con)m(trol,)i(on)e(terms)h(that)g(prohibit)330
+4584 y(them)35 b(from)g(making)g(an)m(y)h(copies)g(of)f(y)m(our)h(cop)m
+(yrigh)m(ted)g(material)h(outside)e(their)h(relationship)330
+4693 y(with)30 b(y)m(ou.)330 4836 y(Con)m(v)m(eying)46
+b(under)d(an)m(y)i(other)g(circumstances)g(is)g(p)s(ermitted)g(solely)g
+(under)f(the)g(conditions)330 4945 y(stated)31 b(b)s(elo)m(w.)41
+b(Sublicensing)30 b(is)g(not)h(allo)m(w)m(ed;)h(section)g(10)f(mak)m
+(es)g(it)g(unnecessary)-8 b(.)199 5088 y(3.)61 b(Protecting)32
+b(Users')e(Legal)i(Righ)m(ts)f(F)-8 b(rom)31 b(An)m(ti-Circum)m(v)m(en)
+m(tion)i(La)m(w.)330 5230 y(No)44 b(co)m(v)m(ered)i(w)m(ork)d(shall)h
+(b)s(e)g(deemed)f(part)h(of)g(an)f(e\013ectiv)m(e)k(tec)m(hnological)g
+(measure)c(under)330 5340 y(an)m(y)30 b(applicable)h(la)m(w)f
+(ful\014lling)g(obligations)h(under)e(article)i(11)g(of)f(the)g(WIPO)f
+(cop)m(yrigh)m(t)i(treat)m(y)p eop end
+%%Page: 5 9
+TeXDict begin 5 8 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(5)330 299 y(adopted)29 b(on)f(20)i(Decem)m(b)s(er)f
+(1996,)i(or)e(similar)g(la)m(ws)g(prohibiting)f(or)h(restricting)g
+(circum)m(v)m(en)m(tion)330 408 y(of)i(suc)m(h)f(measures.)330
+552 y(When)25 b(y)m(ou)h(con)m(v)m(ey)g(a)g(co)m(v)m(ered)h(w)m(ork,)f
+(y)m(ou)g(w)m(aiv)m(e)h(an)m(y)e(legal)i(p)s(o)m(w)m(er)f(to)g(forbid)e
+(circum)m(v)m(en)m(tion)j(of)330 661 y(tec)m(hnological)j(measures)d
+(to)g(the)g(exten)m(t)h(suc)m(h)e(circum)m(v)m(en)m(tion)j(is)d
+(e\013ected)i(b)m(y)f(exercising)g(righ)m(ts)330 771
+y(under)35 b(this)h(License)h(with)e(resp)s(ect)i(to)g(the)f(co)m(v)m
+(ered)i(w)m(ork,)g(and)d(y)m(ou)i(disclaim)g(an)m(y)f(in)m(ten)m(tion)
+330 881 y(to)41 b(limit)g(op)s(eration)g(or)f(mo)s(di\014cation)h(of)g
+(the)f(w)m(ork)h(as)f(a)h(means)f(of)h(enforcing,)i(against)f(the)330
+990 y(w)m(ork's)28 b(users,)f(y)m(our)h(or)f(third)g(parties')h(legal)h
+(righ)m(ts)f(to)g(forbid)f(circum)m(v)m(en)m(tion)i(of)e(tec)m
+(hnological)330 1100 y(measures.)199 1243 y(4.)61 b(Con)m(v)m(eying)31
+b(V)-8 b(erbatim)32 b(Copies.)330 1386 y(Y)-8 b(ou)28
+b(ma)m(y)g(con)m(v)m(ey)h(v)m(erbatim)f(copies)g(of)g(the)f(Program's)h
+(source)g(co)s(de)f(as)h(y)m(ou)f(receiv)m(e)j(it,)f(in)e(an)m(y)330
+1496 y(medium,)33 b(pro)m(vided)g(that)h(y)m(ou)f(conspicuously)g(and)g
+(appropriately)g(publish)f(on)h(eac)m(h)h(cop)m(y)g(an)330
+1606 y(appropriate)e(cop)m(yrigh)m(t)i(notice;)g(k)m(eep)f(in)m(tact)h
+(all)f(notices)g(stating)h(that)e(this)g(License)h(and)f(an)m(y)330
+1715 y(non-p)s(ermissiv)m(e)d(terms)g(added)f(in)h(accord)h(with)f
+(section)h(7)f(apply)g(to)h(the)f(co)s(de;)h(k)m(eep)g(in)m(tact)h(all)
+330 1825 y(notices)37 b(of)f(the)g(absence)g(of)g(an)m(y)g(w)m(arran)m
+(t)m(y;)j(and)c(giv)m(e)i(all)g(recipien)m(ts)f(a)h(cop)m(y)f(of)g
+(this)f(License)330 1934 y(along)c(with)f(the)h(Program.)330
+2078 y(Y)-8 b(ou)27 b(ma)m(y)g(c)m(harge)h(an)m(y)f(price)g(or)f(no)h
+(price)f(for)h(eac)m(h)g(cop)m(y)h(that)f(y)m(ou)g(con)m(v)m(ey)-8
+b(,)29 b(and)d(y)m(ou)h(ma)m(y)h(o\013er)330 2187 y(supp)s(ort)h(or)h
+(w)m(arran)m(t)m(y)h(protection)h(for)e(a)h(fee.)199
+2330 y(5.)61 b(Con)m(v)m(eying)31 b(Mo)s(di\014ed)f(Source)g(V)-8
+b(ersions.)330 2474 y(Y)g(ou)27 b(ma)m(y)g(con)m(v)m(ey)h(a)f(w)m(ork)g
+(based)f(on)h(the)g(Program,)g(or)g(the)g(mo)s(di\014cations)g(to)g
+(pro)s(duce)e(it)i(from)330 2583 y(the)36 b(Program,)h(in)e(the)g(form)
+g(of)g(source)h(co)s(de)g(under)d(the)j(terms)f(of)h(section)g(4,)h
+(pro)m(vided)e(that)330 2693 y(y)m(ou)c(also)g(meet)g(all)h(of)e(these)
+h(conditions:)379 2836 y(a.)61 b(The)28 b(w)m(ork)h(m)m(ust)f(carry)h
+(prominen)m(t)f(notices)i(stating)g(that)f(y)m(ou)g(mo)s(di\014ed)e
+(it,)j(and)e(giving)i(a)510 2946 y(relev)-5 b(an)m(t)32
+b(date.)374 3089 y(b.)60 b(The)34 b(w)m(ork)h(m)m(ust)f(carry)h
+(prominen)m(t)f(notices)i(stating)g(that)f(it)g(is)g(released)g(under)e
+(this)i(Li-)510 3199 y(cense)i(and)f(an)m(y)h(conditions)h(added)e
+(under)f(section)j(7.)60 b(This)36 b(requiremen)m(t)h(mo)s(di\014es)f
+(the)510 3308 y(requiremen)m(t)31 b(in)f(section)h(4)g(to)g(\\k)m(eep)h
+(in)m(tact)g(all)f(notices".)384 3452 y(c.)61 b(Y)-8
+b(ou)36 b(m)m(ust)g(license)g(the)g(en)m(tire)h(w)m(ork,)g(as)f(a)g
+(whole,)h(under)d(this)i(License)g(to)h(an)m(y)m(one)f(who)510
+3561 y(comes)31 b(in)m(to)g(p)s(ossession)e(of)h(a)h(cop)m(y)-8
+b(.)41 b(This)29 b(License)i(will)f(therefore)h(apply)-8
+b(,)30 b(along)h(with)f(an)m(y)510 3671 y(applicable)k(section)f(7)g
+(additional)h(terms,)f(to)h(the)e(whole)h(of)g(the)g(w)m(ork,)g(and)f
+(all)i(its)f(parts,)510 3780 y(regardless)h(of)g(ho)m(w)g(they)g(are)g
+(pac)m(k)-5 b(aged.)52 b(This)33 b(License)h(giv)m(es)h(no)f(p)s
+(ermission)e(to)j(license)510 3890 y(the)c(w)m(ork)h(in)f(an)m(y)g
+(other)h(w)m(a)m(y)-8 b(,)33 b(but)d(it)i(do)s(es)f(not)g(in)m(v)-5
+b(alidate)33 b(suc)m(h)e(p)s(ermission)f(if)h(y)m(ou)h(ha)m(v)m(e)510
+4000 y(separately)g(receiv)m(ed)f(it.)374 4143 y(d.)60
+b(If)36 b(the)h(w)m(ork)g(has)g(in)m(teractiv)m(e)j(user)c(in)m
+(terfaces,)k(eac)m(h)e(m)m(ust)f(displa)m(y)g(Appropriate)g(Legal)510
+4253 y(Notices;)49 b(ho)m(w)m(ev)m(er,)c(if)c(the)h(Program)f(has)g(in)
+m(teractiv)m(e)j(in)m(terfaces)e(that)g(do)f(not)h(displa)m(y)510
+4362 y(Appropriate)30 b(Legal)i(Notices,)g(y)m(our)f(w)m(ork)f(need)g
+(not)h(mak)m(e)g(them)g(do)f(so.)330 4539 y(A)38 b(compilation)h(of)f
+(a)g(co)m(v)m(ered)h(w)m(ork)f(with)f(other)h(separate)h(and)e(indep)s
+(enden)m(t)f(w)m(orks,)k(whic)m(h)330 4649 y(are)c(not)g(b)m(y)g(their)
+g(nature)f(extensions)h(of)g(the)g(co)m(v)m(ered)i(w)m(ork,)f(and)e
+(whic)m(h)h(are)g(not)g(com)m(bined)330 4758 y(with)27
+b(it)i(suc)m(h)e(as)h(to)h(form)e(a)h(larger)h(program,)f(in)f(or)h(on)
+g(a)g(v)m(olume)g(of)g(a)h(storage)g(or)f(distribution)330
+4868 y(medium,)43 b(is)f(called)g(an)g(\\aggregate")j(if)c(the)h
+(compilation)h(and)e(its)g(resulting)h(cop)m(yrigh)m(t)h(are)330
+4977 y(not)31 b(used)f(to)h(limit)h(the)e(access)i(or)f(legal)h(righ)m
+(ts)f(of)g(the)g(compilation's)h(users)e(b)s(ey)m(ond)g(what)h(the)330
+5087 y(individual)j(w)m(orks)h(p)s(ermit.)54 b(Inclusion)34
+b(of)h(a)h(co)m(v)m(ered)g(w)m(ork)f(in)g(an)g(aggregate)j(do)s(es)c
+(not)h(cause)330 5197 y(this)30 b(License)h(to)g(apply)f(to)h(the)g
+(other)g(parts)f(of)g(the)h(aggregate.)199 5340 y(6.)61
+b(Con)m(v)m(eying)31 b(Non-Source)g(F)-8 b(orms.)p eop
+end
+%%Page: 6 10
+TeXDict begin 6 9 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(6)330 299 y(Y)-8 b(ou)29 b(ma)m(y)h(con)m(v)m(ey)g(a)f
+(co)m(v)m(ered)i(w)m(ork)e(in)f(ob)5 b(ject)30 b(co)s(de)f(form)f
+(under)g(the)h(terms)f(of)h(sections)h(4)g(and)330 408
+y(5,)42 b(pro)m(vided)d(that)g(y)m(ou)h(also)g(con)m(v)m(ey)g(the)g
+(mac)m(hine-readable)g(Corresp)s(onding)e(Source)g(under)330
+518 y(the)31 b(terms)f(of)g(this)h(License,)g(in)f(one)h(of)f(these)h
+(w)m(a)m(ys:)379 655 y(a.)61 b(Con)m(v)m(ey)32 b(the)f(ob)5
+b(ject)31 b(co)s(de)g(in,)g(or)g(em)m(b)s(o)s(died)f(in,)h(a)g(ph)m
+(ysical)h(pro)s(duct)d(\(including)i(a)g(ph)m(ys-)510
+765 y(ical)37 b(distribution)d(medium\),)j(accompanied)f(b)m(y)f(the)h
+(Corresp)s(onding)d(Source)j(\014xed)e(on)i(a)510 874
+y(durable)30 b(ph)m(ysical)h(medium)e(customarily)i(used)f(for)g(soft)m
+(w)m(are)i(in)m(terc)m(hange.)374 1011 y(b.)60 b(Con)m(v)m(ey)30
+b(the)f(ob)5 b(ject)30 b(co)s(de)f(in,)g(or)g(em)m(b)s(o)s(died)f(in,)h
+(a)g(ph)m(ysical)g(pro)s(duct)f(\(including)h(a)g(ph)m(ysi-)510
+1121 y(cal)k(distribution)e(medium\),)h(accompanied)h(b)m(y)e(a)i
+(written)f(o\013er,)g(v)-5 b(alid)33 b(for)e(at)i(least)g(three)510
+1230 y(y)m(ears)i(and)f(v)-5 b(alid)35 b(for)f(as)g(long)h(as)g(y)m(ou)
+g(o\013er)f(spare)h(parts)f(or)g(customer)h(supp)s(ort)d(for)i(that)510
+1340 y(pro)s(duct)c(mo)s(del,)i(to)g(giv)m(e)g(an)m(y)m(one)h(who)d(p)s
+(ossesses)h(the)h(ob)5 b(ject)32 b(co)s(de)f(either)h(\(1\))g(a)g(cop)m
+(y)g(of)510 1450 y(the)24 b(Corresp)s(onding)e(Source)i(for)g(all)h
+(the)f(soft)m(w)m(are)h(in)f(the)g(pro)s(duct)f(that)i(is)f(co)m(v)m
+(ered)h(b)m(y)f(this)510 1559 y(License,)30 b(on)g(a)f(durable)g(ph)m
+(ysical)h(medium)e(customarily)i(used)f(for)g(soft)m(w)m(are)i(in)m
+(terc)m(hange,)510 1669 y(for)k(a)g(price)h(no)f(more)g(than)g(y)m(our)
+g(reasonable)h(cost)g(of)f(ph)m(ysically)h(p)s(erforming)e(this)h(con-)
+510 1778 y(v)m(eying)f(of)f(source,)g(or)g(\(2\))h(access)g(to)g(cop)m
+(y)f(the)g(Corresp)s(onding)e(Source)i(from)f(a)h(net)m(w)m(ork)510
+1888 y(serv)m(er)e(at)g(no)f(c)m(harge.)384 2025 y(c.)61
+b(Con)m(v)m(ey)40 b(individual)e(copies)h(of)g(the)g(ob)5
+b(ject)40 b(co)s(de)f(with)g(a)g(cop)m(y)g(of)g(the)g(written)g
+(o\013er)g(to)510 2134 y(pro)m(vide)e(the)g(Corresp)s(onding)e(Source.)
+59 b(This)36 b(alternativ)m(e)k(is)c(allo)m(w)m(ed)j(only)e(o)s
+(ccasionally)510 2244 y(and)29 b(noncommercially)-8 b(,)31
+b(and)e(only)g(if)h(y)m(ou)f(receiv)m(ed)i(the)e(ob)5
+b(ject)31 b(co)s(de)e(with)g(suc)m(h)g(an)g(o\013er,)510
+2354 y(in)h(accord)h(with)f(subsection)h(6b.)374 2491
+y(d.)60 b(Con)m(v)m(ey)37 b(the)f(ob)5 b(ject)37 b(co)s(de)f(b)m(y)g
+(o\013ering)g(access)i(from)d(a)i(designated)f(place)h(\(gratis)g(or)f
+(for)510 2600 y(a)j(c)m(harge\),)k(and)c(o\013er)g(equiv)-5
+b(alen)m(t)41 b(access)f(to)g(the)f(Corresp)s(onding)e(Source)i(in)f
+(the)i(same)510 2710 y(w)m(a)m(y)30 b(through)f(the)g(same)h(place)h
+(at)f(no)f(further)f(c)m(harge.)41 b(Y)-8 b(ou)30 b(need)f(not)h
+(require)f(recipien)m(ts)510 2819 y(to)42 b(cop)m(y)h(the)f(Corresp)s
+(onding)e(Source)h(along)i(with)f(the)g(ob)5 b(ject)42
+b(co)s(de.)75 b(If)42 b(the)f(place)i(to)510 2929 y(cop)m(y)c(the)g(ob)
+5 b(ject)39 b(co)s(de)g(is)g(a)g(net)m(w)m(ork)g(serv)m(er,)i(the)e
+(Corresp)s(onding)e(Source)h(ma)m(y)h(b)s(e)f(on)510
+3039 y(a)45 b(di\013eren)m(t)g(serv)m(er)f(\(op)s(erated)h(b)m(y)f(y)m
+(ou)h(or)g(a)f(third)g(part)m(y\))h(that)g(supp)s(orts)d(equiv)-5
+b(alen)m(t)510 3148 y(cop)m(ying)35 b(facilities,)i(pro)m(vided)c(y)m
+(ou)h(main)m(tain)h(clear)g(directions)f(next)g(to)h(the)f(ob)5
+b(ject)35 b(co)s(de)510 3258 y(sa)m(ying)h(where)f(to)h(\014nd)d(the)i
+(Corresp)s(onding)f(Source.)55 b(Regardless)35 b(of)h(what)f(serv)m(er)
+g(hosts)510 3367 y(the)e(Corresp)s(onding)e(Source,)j(y)m(ou)f(remain)f
+(obligated)j(to)e(ensure)f(that)i(it)f(is)g(a)m(v)-5
+b(ailable)35 b(for)510 3477 y(as)c(long)g(as)f(needed)g(to)h(satisfy)g
+(these)g(requiremen)m(ts.)384 3614 y(e.)61 b(Con)m(v)m(ey)24
+b(the)g(ob)5 b(ject)24 b(co)s(de)f(using)g(p)s(eer-to-p)s(eer)h
+(transmission,)g(pro)m(vided)f(y)m(ou)h(inform)f(other)510
+3724 y(p)s(eers)d(where)g(the)h(ob)5 b(ject)22 b(co)s(de)f(and)f
+(Corresp)s(onding)f(Source)i(of)g(the)g(w)m(ork)g(are)g(b)s(eing)g
+(o\013ered)510 3833 y(to)31 b(the)g(general)g(public)f(at)h(no)f(c)m
+(harge)i(under)d(subsection)h(6d.)330 3998 y(A)35 b(separable)f(p)s
+(ortion)g(of)h(the)g(ob)5 b(ject)35 b(co)s(de,)h(whose)e(source)h(co)s
+(de)g(is)f(excluded)g(from)g(the)h(Cor-)330 4107 y(resp)s(onding)c
+(Source)h(as)h(a)g(System)f(Library)-8 b(,)33 b(need)f(not)h(b)s(e)e
+(included)h(in)g(con)m(v)m(eying)i(the)f(ob)5 b(ject)330
+4217 y(co)s(de)31 b(w)m(ork.)330 4354 y(A)h(\\User)g(Pro)s(duct")f(is)h
+(either)g(\(1\))g(a)g(\\consumer)g(pro)s(duct",)f(whic)m(h)h(means)f
+(an)m(y)h(tangible)h(p)s(er-)330 4463 y(sonal)g(prop)s(ert)m(y)g(whic)m
+(h)f(is)h(normally)h(used)e(for)h(p)s(ersonal,)g(family)-8
+b(,)35 b(or)e(household)f(purp)s(oses,)g(or)330 4573
+y(\(2\))26 b(an)m(ything)f(designed)f(or)h(sold)g(for)f(incorp)s
+(oration)h(in)m(to)h(a)f(dw)m(elling.)39 b(In)24 b(determining)h
+(whether)330 4682 y(a)30 b(pro)s(duct)e(is)h(a)h(consumer)f(pro)s
+(duct,)f(doubtful)h(cases)h(shall)g(b)s(e)e(resolv)m(ed)j(in)e(fa)m(v)m
+(or)h(of)g(co)m(v)m(erage.)330 4792 y(F)-8 b(or)42 b(a)g(particular)g
+(pro)s(duct)f(receiv)m(ed)i(b)m(y)e(a)h(particular)g(user,)i
+(\\normally)f(used")e(refers)g(to)i(a)330 4902 y(t)m(ypical)e(or)e
+(common)h(use)e(of)i(that)g(class)g(of)f(pro)s(duct,)h(regardless)g(of)
+f(the)h(status)f(of)h(the)f(par-)330 5011 y(ticular)d(user)e(or)h(of)h
+(the)f(w)m(a)m(y)h(in)f(whic)m(h)f(the)i(particular)f(user)g(actually)h
+(uses,)g(or)f(exp)s(ects)h(or)f(is)330 5121 y(exp)s(ected)d(to)g(use,)g
+(the)g(pro)s(duct.)43 b(A)32 b(pro)s(duct)f(is)g(a)h(consumer)f(pro)s
+(duct)g(regardless)h(of)g(whether)330 5230 y(the)h(pro)s(duct)f(has)h
+(substan)m(tial)g(commercial,)j(industrial)c(or)h(non-consumer)g(uses,)
+g(unless)f(suc)m(h)330 5340 y(uses)e(represen)m(t)g(the)h(only)f
+(signi\014can)m(t)i(mo)s(de)e(of)g(use)g(of)h(the)f(pro)s(duct.)p
+eop end
+%%Page: 7 11
+TeXDict begin 7 10 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(7)330 299 y(\\Installation)31 b(Information")e(for)g(a)
+g(User)g(Pro)s(duct)f(means)g(an)m(y)i(metho)s(ds,)e(pro)s(cedures,)g
+(autho-)330 408 y(rization)d(k)m(eys,)g(or)f(other)f(information)h
+(required)f(to)h(install)g(and)f(execute)i(mo)s(di\014ed)d(v)m(ersions)
+i(of)g(a)330 518 y(co)m(v)m(ered)h(w)m(ork)e(in)g(that)h(User)f(Pro)s
+(duct)f(from)h(a)h(mo)s(di\014ed)e(v)m(ersion)h(of)h(its)f(Corresp)s
+(onding)f(Source.)330 628 y(The)30 b(information)h(m)m(ust)f(su\016ce)g
+(to)i(ensure)d(that)i(the)g(con)m(tin)m(ued)g(functioning)g(of)f(the)h
+(mo)s(di\014ed)330 737 y(ob)5 b(ject)34 b(co)s(de)f(is)g(in)f(no)h
+(case)h(prev)m(en)m(ted)f(or)g(in)m(terfered)g(with)g(solely)h(b)s
+(ecause)f(mo)s(di\014cation)g(has)330 847 y(b)s(een)d(made.)330
+981 y(If)38 b(y)m(ou)i(con)m(v)m(ey)g(an)f(ob)5 b(ject)40
+b(co)s(de)f(w)m(ork)g(under)e(this)i(section)h(in,)h(or)e(with,)i(or)e
+(sp)s(eci\014cally)g(for)330 1090 y(use)g(in,)i(a)e(User)g(Pro)s(duct,)
+i(and)e(the)g(con)m(v)m(eying)i(o)s(ccurs)d(as)i(part)f(of)g(a)g
+(transaction)h(in)f(whic)m(h)330 1200 y(the)d(righ)m(t)g(of)g(p)s
+(ossession)f(and)g(use)h(of)f(the)h(User)g(Pro)s(duct)f(is)g
+(transferred)g(to)i(the)e(recipien)m(t)i(in)330 1310
+y(p)s(erp)s(etuit)m(y)43 b(or)g(for)g(a)h(\014xed)e(term)i
+(\(regardless)g(of)f(ho)m(w)h(the)f(transaction)i(is)e(c)m
+(haracterized\),)330 1419 y(the)c(Corresp)s(onding)e(Source)i(con)m(v)m
+(ey)m(ed)i(under)c(this)i(section)h(m)m(ust)f(b)s(e)f(accompanied)i(b)m
+(y)f(the)330 1529 y(Installation)d(Information.)52 b(But)35
+b(this)f(requiremen)m(t)g(do)s(es)g(not)h(apply)f(if)g(neither)g(y)m
+(ou)h(nor)f(an)m(y)330 1638 y(third)28 b(part)m(y)i(retains)f(the)g
+(abilit)m(y)i(to)e(install)h(mo)s(di\014ed)e(ob)5 b(ject)30
+b(co)s(de)f(on)g(the)h(User)f(Pro)s(duct)f(\(for)330
+1748 y(example,)j(the)g(w)m(ork)f(has)g(b)s(een)g(installed)h(in)f(R)m
+(OM\).)330 1882 y(The)38 b(requiremen)m(t)g(to)h(pro)m(vide)g
+(Installation)g(Information)g(do)s(es)f(not)g(include)g(a)h(requiremen)
+m(t)330 1991 y(to)32 b(con)m(tin)m(ue)h(to)f(pro)m(vide)g(supp)s(ort)e
+(service,)j(w)m(arran)m(t)m(y)-8 b(,)33 b(or)f(up)s(dates)e(for)i(a)g
+(w)m(ork)f(that)h(has)g(b)s(een)330 2101 y(mo)s(di\014ed)37
+b(or)h(installed)h(b)m(y)g(the)f(recipien)m(t,)k(or)c(for)g(the)g(User)
+h(Pro)s(duct)e(in)h(whic)m(h)g(it)h(has)f(b)s(een)330
+2211 y(mo)s(di\014ed)29 b(or)h(installed.)42 b(Access)31
+b(to)g(a)g(net)m(w)m(ork)g(ma)m(y)g(b)s(e)e(denied)h(when)f(the)i(mo)s
+(di\014cation)f(itself)330 2320 y(materially)i(and)e(adv)m(ersely)h
+(a\013ects)h(the)e(op)s(eration)h(of)g(the)f(net)m(w)m(ork)h(or)g
+(violates)h(the)f(rules)f(and)330 2430 y(proto)s(cols)h(for)f(comm)m
+(unication)i(across)f(the)g(net)m(w)m(ork.)330 2564 y(Corresp)s(onding)
+26 b(Source)h(con)m(v)m(ey)m(ed,)j(and)d(Installation)i(Information)f
+(pro)m(vided,)g(in)f(accord)h(with)330 2673 y(this)d(section)i(m)m(ust)
+e(b)s(e)g(in)g(a)h(format)g(that)f(is)h(publicly)f(do)s(cumen)m(ted)g
+(\(and)g(with)g(an)h(implemen)m(ta-)330 2783 y(tion)i(a)m(v)-5
+b(ailable)29 b(to)f(the)g(public)e(in)h(source)h(co)s(de)f(form\),)h
+(and)f(m)m(ust)g(require)g(no)g(sp)s(ecial)h(passw)m(ord)330
+2892 y(or)i(k)m(ey)i(for)e(unpac)m(king,)g(reading)h(or)f(cop)m(ying.)
+199 3026 y(7.)61 b(Additional)31 b(T)-8 b(erms.)330 3160
+y(\\Additional)29 b(p)s(ermissions")e(are)h(terms)f(that)h(supplemen)m
+(t)f(the)h(terms)g(of)f(this)h(License)g(b)m(y)g(mak-)330
+3270 y(ing)41 b(exceptions)h(from)e(one)h(or)g(more)g(of)g(its)g
+(conditions.)72 b(Additional)42 b(p)s(ermissions)d(that)j(are)330
+3380 y(applicable)31 b(to)f(the)g(en)m(tire)h(Program)f(shall)g(b)s(e)f
+(treated)i(as)f(though)f(they)h(w)m(ere)h(included)e(in)g(this)330
+3489 y(License,)36 b(to)e(the)g(exten)m(t)i(that)e(they)g(are)g(v)-5
+b(alid)34 b(under)f(applicable)i(la)m(w.)52 b(If)33 b(additional)i(p)s
+(ermis-)330 3599 y(sions)27 b(apply)h(only)f(to)h(part)g(of)f(the)h
+(Program,)h(that)f(part)f(ma)m(y)h(b)s(e)f(used)g(separately)h(under)e
+(those)330 3708 y(p)s(ermissions,)31 b(but)g(the)h(en)m(tire)h(Program)
+f(remains)f(go)m(v)m(erned)i(b)m(y)f(this)g(License)g(without)g(regard)
+330 3818 y(to)f(the)g(additional)g(p)s(ermissions.)330
+3952 y(When)45 b(y)m(ou)g(con)m(v)m(ey)i(a)e(cop)m(y)h(of)f(a)g(co)m(v)
+m(ered)i(w)m(ork,)h(y)m(ou)e(ma)m(y)f(at)h(y)m(our)f(option)g(remo)m(v)
+m(e)i(an)m(y)330 4061 y(additional)30 b(p)s(ermissions)e(from)h(that)h
+(cop)m(y)-8 b(,)31 b(or)f(from)e(an)m(y)i(part)f(of)h(it.)41
+b(\(Additional)30 b(p)s(ermissions)330 4171 y(ma)m(y)41
+b(b)s(e)f(written)g(to)h(require)f(their)h(o)m(wn)f(remo)m(v)-5
+b(al)42 b(in)e(certain)h(cases)g(when)f(y)m(ou)g(mo)s(dify)g(the)330
+4281 y(w)m(ork.\))48 b(Y)-8 b(ou)33 b(ma)m(y)g(place)h(additional)f(p)s
+(ermissions)e(on)i(material,)i(added)d(b)m(y)g(y)m(ou)h(to)g(a)g(co)m
+(v)m(ered)330 4390 y(w)m(ork,)e(for)f(whic)m(h)g(y)m(ou)h(ha)m(v)m(e)g
+(or)g(can)f(giv)m(e)i(appropriate)f(cop)m(yrigh)m(t)g(p)s(ermission.)
+330 4524 y(Not)m(withstanding)e(an)m(y)g(other)g(pro)m(vision)f(of)h
+(this)f(License,)h(for)f(material)i(y)m(ou)f(add)f(to)h(a)f(co)m(v)m
+(ered)330 4634 y(w)m(ork,)40 b(y)m(ou)e(ma)m(y)g(\(if)g(authorized)g(b)
+m(y)g(the)g(cop)m(yrigh)m(t)h(holders)e(of)h(that)g(material\))h
+(supplemen)m(t)330 4743 y(the)31 b(terms)f(of)g(this)h(License)g(with)f
+(terms:)379 4877 y(a.)61 b(Disclaiming)31 b(w)m(arran)m(t)m(y)f(or)g
+(limiting)g(liabilit)m(y)h(di\013eren)m(tly)f(from)f(the)g(terms)g(of)h
+(sections)g(15)510 4987 y(and)g(16)h(of)g(this)f(License;)h(or)374
+5121 y(b.)60 b(Requiring)30 b(preserv)-5 b(ation)31 b(of)g(sp)s
+(eci\014ed)f(reasonable)h(legal)i(notices)f(or)e(author)h(attributions)
+510 5230 y(in)24 b(that)i(material)g(or)f(in)f(the)h(Appropriate)g
+(Legal)h(Notices)h(displa)m(y)m(ed)e(b)m(y)g(w)m(orks)f(con)m(taining)
+510 5340 y(it;)31 b(or)p eop end
+%%Page: 8 12
+TeXDict begin 8 11 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(8)384 299 y(c.)61 b(Prohibiting)23 b(misrepresen)m
+(tation)i(of)e(the)h(origin)g(of)f(that)i(material,)h(or)d(requiring)g
+(that)h(mo)s(d-)510 408 y(i\014ed)30 b(v)m(ersions)h(of)f(suc)m(h)g
+(material)i(b)s(e)e(mark)m(ed)h(in)f(reasonable)h(w)m(a)m(ys)g(as)g
+(di\013eren)m(t)g(from)f(the)510 518 y(original)i(v)m(ersion;)f(or)374
+664 y(d.)60 b(Limiting)42 b(the)f(use)g(for)g(publicit)m(y)h(purp)s
+(oses)d(of)i(names)g(of)h(licensors)f(or)h(authors)e(of)i(the)510
+774 y(material;)32 b(or)384 920 y(e.)61 b(Declining)29
+b(to)f(gran)m(t)g(righ)m(ts)f(under)f(trademark)h(la)m(w)h(for)f(use)g
+(of)g(some)h(trade)f(names,)h(trade-)510 1029 y(marks,)i(or)h(service)g
+(marks;)f(or)397 1176 y(f.)60 b(Requiring)26 b(indemni\014cation)g(of)g
+(licensors)h(and)f(authors)f(of)i(that)f(material)i(b)m(y)e(an)m(y)m
+(one)h(who)510 1285 y(con)m(v)m(eys)45 b(the)e(material)h(\(or)g(mo)s
+(di\014ed)e(v)m(ersions)h(of)h(it\))g(with)e(con)m(tractual)k
+(assumptions)510 1395 y(of)40 b(liabilit)m(y)h(to)f(the)f(recipien)m
+(t,)k(for)c(an)m(y)h(liabilit)m(y)h(that)f(these)g(con)m(tractual)i
+(assumptions)510 1504 y(directly)31 b(imp)s(ose)f(on)g(those)h
+(licensors)g(and)f(authors.)330 1687 y(All)i(other)h(non-p)s(ermissiv)m
+(e)e(additional)i(terms)e(are)i(considered)e(\\further)g(restrictions")
+i(within)330 1797 y(the)j(meaning)f(of)h(section)g(10.)57
+b(If)35 b(the)h(Program)f(as)h(y)m(ou)g(receiv)m(ed)g(it,)i(or)d(an)m
+(y)h(part)f(of)h(it,)h(con-)330 1906 y(tains)f(a)g(notice)h(stating)g
+(that)f(it)g(is)g(go)m(v)m(erned)h(b)m(y)e(this)h(License)g(along)h
+(with)e(a)h(term)g(that)g(is)g(a)330 2016 y(further)24
+b(restriction,)k(y)m(ou)e(ma)m(y)g(remo)m(v)m(e)h(that)f(term.)39
+b(If)26 b(a)g(license)g(do)s(cumen)m(t)g(con)m(tains)g(a)g(further)330
+2125 y(restriction)33 b(but)f(p)s(ermits)g(relicensing)h(or)g(con)m(v)m
+(eying)h(under)d(this)i(License,)g(y)m(ou)g(ma)m(y)g(add)f(to)i(a)330
+2235 y(co)m(v)m(ered)g(w)m(ork)e(material)h(go)m(v)m(erned)h(b)m(y)e
+(the)g(terms)g(of)g(that)h(license)g(do)s(cumen)m(t,)g(pro)m(vided)e
+(that)330 2345 y(the)g(further)e(restriction)i(do)s(es)f(not)h(surviv)m
+(e)f(suc)m(h)g(relicensing)h(or)g(con)m(v)m(eying.)330
+2491 y(If)f(y)m(ou)g(add)g(terms)g(to)h(a)g(co)m(v)m(ered)h(w)m(ork)e
+(in)g(accord)h(with)f(this)g(section,)i(y)m(ou)e(m)m(ust)g(place,)i(in)
+e(the)330 2600 y(relev)-5 b(an)m(t)31 b(source)f(\014les,)g(a)g
+(statemen)m(t)h(of)f(the)g(additional)g(terms)g(that)g(apply)f(to)i
+(those)f(\014les,)g(or)g(a)330 2710 y(notice)i(indicating)f(where)f(to)
+h(\014nd)e(the)h(applicable)i(terms.)330 2856 y(Additional)37
+b(terms,)h(p)s(ermissiv)m(e)e(or)h(non-p)s(ermissiv)m(e,)h(ma)m(y)f(b)s
+(e)e(stated)j(in)e(the)h(form)f(of)g(a)h(sep-)330 2966
+y(arately)i(written)f(license,)i(or)e(stated)h(as)e(exceptions;)43
+b(the)38 b(ab)s(o)m(v)m(e)h(requiremen)m(ts)e(apply)g(either)330
+3075 y(w)m(a)m(y)-8 b(.)199 3221 y(8.)61 b(T)-8 b(ermination.)330
+3367 y(Y)g(ou)40 b(ma)m(y)g(not)f(propagate)i(or)e(mo)s(dify)g(a)g(co)m
+(v)m(ered)i(w)m(ork)f(except)g(as)g(expressly)f(pro)m(vided)g(un-)330
+3477 y(der)d(this)h(License.)62 b(An)m(y)37 b(attempt)h(otherwise)f(to)
+h(propagate)g(or)f(mo)s(dify)f(it)i(is)f(v)m(oid,)i(and)e(will)330
+3587 y(automatically)g(terminate)d(y)m(our)g(righ)m(ts)g(under)f(this)g
+(License)i(\(including)e(an)m(y)h(paten)m(t)h(licenses)330
+3696 y(gran)m(ted)c(under)e(the)h(third)g(paragraph)g(of)g(section)i
+(11\).)330 3842 y(Ho)m(w)m(ev)m(er,)j(if)e(y)m(ou)f(cease)i(all)f
+(violation)i(of)d(this)g(License,)i(then)e(y)m(our)h(license)g(from)f
+(a)h(particular)330 3952 y(cop)m(yrigh)m(t)k(holder)e(is)h(reinstated)h
+(\(a\))f(pro)m(visionally)-8 b(,)39 b(unless)c(and)g(un)m(til)h(the)g
+(cop)m(yrigh)m(t)h(holder)330 4061 y(explicitly)42 b(and)e(\014nally)h
+(terminates)g(y)m(our)g(license,)j(and)c(\(b\))h(p)s(ermanen)m(tly)-8
+b(,)43 b(if)e(the)g(cop)m(yrigh)m(t)330 4171 y(holder)34
+b(fails)h(to)g(notify)g(y)m(ou)g(of)f(the)h(violation)h(b)m(y)e(some)h
+(reasonable)g(means)g(prior)e(to)i(60)h(da)m(ys)330 4281
+y(after)31 b(the)f(cessation.)330 4427 y(Moreo)m(v)m(er,)k(y)m(our)d
+(license)i(from)e(a)h(particular)f(cop)m(yrigh)m(t)i(holder)e(is)h
+(reinstated)g(p)s(ermanen)m(tly)f(if)330 4536 y(the)d(cop)m(yrigh)m(t)h
+(holder)f(noti\014es)g(y)m(ou)g(of)g(the)g(violation)h(b)m(y)f(some)g
+(reasonable)h(means,)f(this)g(is)g(the)330 4646 y(\014rst)f(time)i(y)m
+(ou)f(ha)m(v)m(e)h(receiv)m(ed)g(notice)g(of)f(violation)i(of)e(this)f
+(License)i(\(for)f(an)m(y)g(w)m(ork\))g(from)f(that)330
+4756 y(cop)m(yrigh)m(t)33 b(holder,)g(and)e(y)m(ou)h(cure)g(the)g
+(violation)i(prior)d(to)i(30)f(da)m(ys)h(after)f(y)m(our)g(receipt)h
+(of)f(the)330 4865 y(notice.)330 5011 y(T)-8 b(ermination)28
+b(of)g(y)m(our)f(righ)m(ts)h(under)e(this)i(section)g(do)s(es)f(not)h
+(terminate)h(the)e(licenses)i(of)f(parties)330 5121 y(who)38
+b(ha)m(v)m(e)h(receiv)m(ed)h(copies)e(or)h(righ)m(ts)f(from)g(y)m(ou)g
+(under)f(this)h(License.)64 b(If)38 b(y)m(our)g(righ)m(ts)h(ha)m(v)m(e)
+330 5230 y(b)s(een)f(terminated)h(and)e(not)i(p)s(ermanen)m(tly)f
+(reinstated,)j(y)m(ou)e(do)f(not)h(qualify)f(to)h(receiv)m(e)h(new)330
+5340 y(licenses)31 b(for)f(the)h(same)g(material)h(under)c(section)k
+(10.)p eop end
+%%Page: 9 13
+TeXDict begin 9 12 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2052 b(9)199 299 y(9.)61 b(Acceptance)32 b(Not)g(Required)d
+(for)i(Ha)m(ving)g(Copies.)330 430 y(Y)-8 b(ou)38 b(are)g(not)g
+(required)f(to)h(accept)h(this)f(License)g(in)f(order)g(to)h(receiv)m
+(e)i(or)e(run)e(a)i(cop)m(y)g(of)g(the)330 540 y(Program.)i(Ancillary)
+27 b(propagation)g(of)g(a)g(co)m(v)m(ered)h(w)m(ork)e(o)s(ccurring)g
+(solely)i(as)f(a)g(consequence)g(of)330 650 y(using)i(p)s(eer-to-p)s
+(eer)g(transmission)g(to)h(receiv)m(e)h(a)e(cop)m(y)h(lik)m(ewise)h(do)
+s(es)d(not)i(require)e(acceptance.)330 759 y(Ho)m(w)m(ev)m(er,)g
+(nothing)c(other)g(than)g(this)f(License)i(gran)m(ts)g(y)m(ou)f(p)s
+(ermission)f(to)i(propagate)g(or)f(mo)s(dify)330 869
+y(an)m(y)34 b(co)m(v)m(ered)g(w)m(ork.)50 b(These)32
+b(actions)j(infringe)e(cop)m(yrigh)m(t)h(if)f(y)m(ou)h(do)f(not)g
+(accept)i(this)e(License.)330 978 y(Therefore,)f(b)m(y)f(mo)s(difying)g
+(or)g(propagating)h(a)g(co)m(v)m(ered)h(w)m(ork,)f(y)m(ou)g(indicate)g
+(y)m(our)g(acceptance)330 1088 y(of)f(this)f(License)h(to)g(do)f(so.)
+154 1219 y(10.)61 b(Automatic)32 b(Licensing)f(of)f(Do)m(wnstream)i
+(Recipien)m(ts.)330 1351 y(Eac)m(h)39 b(time)g(y)m(ou)g(con)m(v)m(ey)h
+(a)f(co)m(v)m(ered)h(w)m(ork,)h(the)d(recipien)m(t)i(automatically)h
+(receiv)m(es)f(a)f(license)330 1461 y(from)e(the)h(original)h
+(licensors,)h(to)f(run,)f(mo)s(dify)f(and)g(propagate)i(that)f(w)m
+(ork,)i(sub)5 b(ject)38 b(to)g(this)330 1570 y(License.)60
+b(Y)-8 b(ou)38 b(are)f(not)g(resp)s(onsible)e(for)i(enforcing)g
+(compliance)h(b)m(y)f(third)f(parties)h(with)f(this)330
+1680 y(License.)330 1811 y(An)43 b(\\en)m(tit)m(y)i(transaction")g(is)f
+(a)f(transaction)i(transferring)e(con)m(trol)h(of)g(an)f(organization,)
+49 b(or)330 1921 y(substan)m(tially)24 b(all)f(assets)g(of)g(one,)i(or)
+e(sub)s(dividing)d(an)j(organization,)j(or)d(merging)g(organizations.)
+330 2030 y(If)28 b(propagation)i(of)f(a)h(co)m(v)m(ered)g(w)m(ork)f
+(results)g(from)f(an)h(en)m(tit)m(y)i(transaction,)f(eac)m(h)g(part)m
+(y)g(to)f(that)330 2140 y(transaction)g(who)d(receiv)m(es)k(a)d(cop)m
+(y)i(of)e(the)h(w)m(ork)f(also)i(receiv)m(es)g(whatev)m(er)f(licenses)g
+(to)g(the)g(w)m(ork)330 2250 y(the)d(part)m(y's)g(predecessor)g(in)g
+(in)m(terest)h(had)e(or)h(could)g(giv)m(e)h(under)e(the)h(previous)f
+(paragraph,)i(plus)330 2359 y(a)31 b(righ)m(t)g(to)h(p)s(ossession)e
+(of)h(the)g(Corresp)s(onding)e(Source)i(of)g(the)f(w)m(ork)h(from)g
+(the)g(predecessor)f(in)330 2469 y(in)m(terest,)i(if)e(the)h
+(predecessor)f(has)g(it)h(or)f(can)h(get)h(it)e(with)h(reasonable)g
+(e\013orts.)330 2600 y(Y)-8 b(ou)36 b(ma)m(y)g(not)g(imp)s(ose)f(an)m
+(y)h(further)e(restrictions)j(on)e(the)h(exercise)g(of)g(the)g(righ)m
+(ts)g(gran)m(ted)g(or)330 2710 y(a\016rmed)27 b(under)f(this)h
+(License.)40 b(F)-8 b(or)28 b(example,)h(y)m(ou)f(ma)m(y)g(not)g(imp)s
+(ose)f(a)h(license)g(fee,)h(ro)m(y)m(alt)m(y)-8 b(,)31
+b(or)330 2819 y(other)d(c)m(harge)g(for)g(exercise)h(of)e(righ)m(ts)h
+(gran)m(ted)g(under)e(this)i(License,)h(and)d(y)m(ou)i(ma)m(y)g(not)g
+(initiate)330 2929 y(litigation)f(\(including)d(a)g(cross-claim)i(or)e
+(coun)m(terclaim)i(in)e(a)g(la)m(wsuit\))i(alleging)g(that)e(an)m(y)h
+(paten)m(t)330 3039 y(claim)j(is)g(infringed)e(b)m(y)i(making,)g
+(using,)g(selling,)h(o\013ering)f(for)f(sale,)i(or)e(imp)s(orting)g
+(the)h(Program)330 3148 y(or)i(an)m(y)h(p)s(ortion)f(of)h(it.)154
+3280 y(11.)61 b(P)m(aten)m(ts.)330 3411 y(A)41 b(\\con)m(tributor")h
+(is)f(a)g(cop)m(yrigh)m(t)i(holder)d(who)h(authorizes)g(use)g(under)e
+(this)i(License)h(of)f(the)330 3521 y(Program)35 b(or)f(a)h(w)m(ork)g
+(on)f(whic)m(h)g(the)h(Program)f(is)h(based.)53 b(The)34
+b(w)m(ork)g(th)m(us)g(licensed)h(is)g(called)330 3630
+y(the)c(con)m(tributor's)f(\\con)m(tributor)i(v)m(ersion".)330
+3762 y(A)g(con)m(tributor's)g(\\essen)m(tial)i(paten)m(t)e(claims")h
+(are)f(all)h(paten)m(t)f(claims)h(o)m(wned)e(or)h(con)m(trolled)h(b)m
+(y)330 3871 y(the)21 b(con)m(tributor,)j(whether)d(already)g(acquired)g
+(or)h(hereafter)f(acquired,)j(that)d(w)m(ould)g(b)s(e)g(infringed)330
+3981 y(b)m(y)27 b(some)h(manner,)g(p)s(ermitted)f(b)m(y)g(this)h
+(License,)h(of)e(making,)i(using,)f(or)f(selling)i(its)f(con)m
+(tributor)330 4091 y(v)m(ersion,)40 b(but)c(do)i(not)f(include)g
+(claims)i(that)f(w)m(ould)f(b)s(e)f(infringed)h(only)g(as)h(a)g
+(consequence)g(of)330 4200 y(further)33 b(mo)s(di\014cation)h(of)g(the)
+g(con)m(tributor)g(v)m(ersion.)52 b(F)-8 b(or)34 b(purp)s(oses)e(of)i
+(this)g(de\014nition,)h(\\con-)330 4310 y(trol")40 b(includes)f(the)g
+(righ)m(t)h(to)f(gran)m(t)h(paten)m(t)g(sublicenses)f(in)g(a)g(manner)g
+(consisten)m(t)h(with)f(the)330 4419 y(requiremen)m(ts)30
+b(of)h(this)f(License.)330 4551 y(Eac)m(h)44 b(con)m(tributor)h(gran)m
+(ts)f(y)m(ou)g(a)h(non-exclusiv)m(e,)j(w)m(orldwide,)f(ro)m(y)m(alt)m
+(y-free)g(paten)m(t)e(license)330 4661 y(under)26 b(the)h(con)m
+(tributor's)g(essen)m(tial)i(paten)m(t)f(claims,)h(to)f(mak)m(e,)h
+(use,)f(sell,)g(o\013er)g(for)f(sale,)i(imp)s(ort)330
+4770 y(and)h(otherwise)h(run,)e(mo)s(dify)g(and)h(propagate)i(the)e
+(con)m(ten)m(ts)i(of)f(its)g(con)m(tributor)f(v)m(ersion.)330
+4902 y(In)e(the)h(follo)m(wing)h(three)e(paragraphs,)h(a)g(\\paten)m(t)
+h(license")g(is)e(an)m(y)h(express)f(agreemen)m(t)j(or)d(com-)330
+5011 y(mitmen)m(t,)g(ho)m(w)m(ev)m(er)g(denominated,)f(not)f(to)h
+(enforce)g(a)f(paten)m(t)i(\(suc)m(h)e(as)g(an)g(express)g(p)s
+(ermission)330 5121 y(to)32 b(practice)h(a)f(paten)m(t)h(or)e(co)m(v)m
+(enan)m(t)j(not)e(to)g(sue)f(for)h(paten)m(t)g(infringemen)m(t\).)45
+b(T)-8 b(o)32 b(\\gran)m(t")h(suc)m(h)330 5230 y(a)i(paten)m(t)h
+(license)f(to)h(a)f(part)m(y)g(means)f(to)i(mak)m(e)f(suc)m(h)g(an)f
+(agreemen)m(t)j(or)d(commitmen)m(t)i(not)f(to)330 5340
+y(enforce)c(a)g(paten)m(t)g(against)h(the)e(part)m(y)-8
+b(.)p eop end
+%%Page: 10 14
+TeXDict begin 10 13 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2006 b(10)330 299 y(If)36 b(y)m(ou)h(con)m(v)m(ey)h(a)f(co)m
+(v)m(ered)h(w)m(ork,)h(kno)m(wingly)e(relying)g(on)f(a)h(paten)m(t)h
+(license,)h(and)d(the)h(Corre-)330 408 y(sp)s(onding)21
+b(Source)h(of)h(the)g(w)m(ork)g(is)f(not)h(a)m(v)-5 b(ailable)25
+b(for)e(an)m(y)m(one)g(to)h(cop)m(y)-8 b(,)25 b(free)e(of)g(c)m(harge)g
+(and)f(under)330 518 y(the)32 b(terms)f(of)h(this)f(License,)i(through)
+e(a)h(publicly)f(a)m(v)-5 b(ailable)34 b(net)m(w)m(ork)e(serv)m(er)g
+(or)g(other)g(readily)330 628 y(accessible)38 b(means,)g(then)e(y)m(ou)
+h(m)m(ust)f(either)h(\(1\))h(cause)e(the)h(Corresp)s(onding)e(Source)h
+(to)h(b)s(e)f(so)330 737 y(a)m(v)-5 b(ailable,)32 b(or)e(\(2\))g
+(arrange)g(to)h(depriv)m(e)e(y)m(ourself)h(of)g(the)g(b)s(ene\014t)e
+(of)i(the)g(paten)m(t)g(license)h(for)e(this)330 847
+y(particular)35 b(w)m(ork,)g(or)f(\(3\))i(arrange,)g(in)d(a)i(manner)e
+(consisten)m(t)j(with)e(the)g(requiremen)m(ts)h(of)f(this)330
+956 y(License,)j(to)f(extend)g(the)f(paten)m(t)h(license)h(to)f(do)m
+(wnstream)f(recipien)m(ts.)56 b(\\Kno)m(wingly)36 b(relying")330
+1066 y(means)31 b(y)m(ou)h(ha)m(v)m(e)g(actual)h(kno)m(wledge)f(that,)g
+(but)f(for)g(the)g(paten)m(t)i(license,)f(y)m(our)g(con)m(v)m(eying)h
+(the)330 1176 y(co)m(v)m(ered)40 b(w)m(ork)e(in)g(a)g(coun)m(try)-8
+b(,)41 b(or)e(y)m(our)f(recipien)m(t's)h(use)f(of)g(the)h(co)m(v)m
+(ered)g(w)m(ork)g(in)e(a)i(coun)m(try)-8 b(,)330 1285
+y(w)m(ould)35 b(infringe)g(one)g(or)g(more)g(iden)m(ti\014able)h(paten)
+m(ts)g(in)f(that)h(coun)m(try)f(that)h(y)m(ou)f(ha)m(v)m(e)i(reason)330
+1395 y(to)31 b(b)s(eliev)m(e)h(are)e(v)-5 b(alid.)330
+1551 y(If,)31 b(pursuan)m(t)e(to)j(or)e(in)h(connection)h(with)e(a)h
+(single)h(transaction)g(or)f(arrangemen)m(t,)h(y)m(ou)f(con)m(v)m(ey)-8
+b(,)330 1661 y(or)35 b(propagate)h(b)m(y)e(pro)s(curing)g(con)m(v)m(ey)
+m(ance)j(of,)g(a)e(co)m(v)m(ered)h(w)m(ork,)g(and)f(gran)m(t)g(a)g
+(paten)m(t)h(license)330 1771 y(to)c(some)f(of)h(the)f(parties)h
+(receiving)g(the)f(co)m(v)m(ered)i(w)m(ork)e(authorizing)h(them)f(to)h
+(use,)g(propagate,)330 1880 y(mo)s(dify)26 b(or)h(con)m(v)m(ey)h(a)g
+(sp)s(eci\014c)e(cop)m(y)i(of)f(the)g(co)m(v)m(ered)i(w)m(ork,)f(then)e
+(the)h(paten)m(t)h(license)g(y)m(ou)f(gran)m(t)330 1990
+y(is)j(automatically)k(extended)c(to)h(all)g(recipien)m(ts)h(of)e(the)h
+(co)m(v)m(ered)h(w)m(ork)e(and)g(w)m(orks)g(based)g(on)h(it.)330
+2146 y(A)d(paten)m(t)g(license)h(is)e(\\discriminatory")i(if)e(it)h(do)
+s(es)f(not)h(include)f(within)g(the)h(scop)s(e)f(of)h(its)g(co)m(v)m
+(er-)330 2256 y(age,)f(prohibits)c(the)h(exercise)h(of,)h(or)d(is)h
+(conditioned)h(on)f(the)g(non-exercise)h(of)f(one)g(or)g(more)g(of)g
+(the)330 2365 y(righ)m(ts)32 b(that)g(are)g(sp)s(eci\014cally)h(gran)m
+(ted)f(under)e(this)i(License.)45 b(Y)-8 b(ou)32 b(ma)m(y)g(not)g(con)m
+(v)m(ey)h(a)f(co)m(v)m(ered)330 2475 y(w)m(ork)d(if)g(y)m(ou)g(are)h(a)
+f(part)m(y)g(to)h(an)f(arrangemen)m(t)h(with)e(a)i(third)e(part)m(y)h
+(that)g(is)g(in)g(the)g(business)f(of)330 2585 y(distributing)i(soft)m
+(w)m(are,)i(under)d(whic)m(h)h(y)m(ou)h(mak)m(e)g(pa)m(ymen)m(t)g(to)g
+(the)g(third)f(part)m(y)g(based)g(on)h(the)330 2694 y(exten)m(t)f(of)g
+(y)m(our)f(activit)m(y)i(of)e(con)m(v)m(eying)i(the)e(w)m(ork,)h(and)e
+(under)g(whic)m(h)g(the)i(third)e(part)m(y)h(gran)m(ts,)330
+2804 y(to)35 b(an)m(y)g(of)f(the)h(parties)f(who)g(w)m(ould)g(receiv)m
+(e)i(the)f(co)m(v)m(ered)h(w)m(ork)e(from)g(y)m(ou,)i(a)f
+(discriminatory)330 2913 y(paten)m(t)g(license)h(\(a\))f(in)f
+(connection)h(with)f(copies)h(of)g(the)f(co)m(v)m(ered)i(w)m(ork)f(con)
+m(v)m(ey)m(ed)h(b)m(y)e(y)m(ou)h(\(or)330 3023 y(copies)k(made)e(from)h
+(those)g(copies\),)j(or)d(\(b\))g(primarily)f(for)h(and)f(in)h
+(connection)h(with)e(sp)s(eci\014c)330 3133 y(pro)s(ducts)32
+b(or)i(compilations)h(that)f(con)m(tain)h(the)f(co)m(v)m(ered)i(w)m
+(ork,)e(unless)f(y)m(ou)h(en)m(tered)h(in)m(to)f(that)330
+3242 y(arrangemen)m(t,)e(or)e(that)h(paten)m(t)g(license)h(w)m(as)e
+(gran)m(ted,)i(prior)d(to)j(28)f(Marc)m(h)g(2007.)330
+3399 y(Nothing)23 b(in)e(this)h(License)h(shall)f(b)s(e)f(construed)h
+(as)g(excluding)g(or)g(limiting)h(an)m(y)f(implied)g(license)h(or)330
+3508 y(other)k(defenses)f(to)h(infringemen)m(t)g(that)g(ma)m(y)g
+(otherwise)g(b)s(e)e(a)m(v)-5 b(ailable)29 b(to)e(y)m(ou)g(under)e
+(applicable)330 3618 y(paten)m(t)31 b(la)m(w.)154 3774
+y(12.)61 b(No)31 b(Surrender)d(of)i(Others')g(F)-8 b(reedom.)330
+3931 y(If)24 b(conditions)g(are)h(imp)s(osed)f(on)g(y)m(ou)g(\(whether)
+g(b)m(y)g(court)h(order,)g(agreemen)m(t)h(or)e(otherwise\))h(that)330
+4041 y(con)m(tradict)35 b(the)f(conditions)h(of)e(this)h(License,)h
+(they)f(do)g(not)g(excuse)g(y)m(ou)g(from)g(the)f(conditions)330
+4150 y(of)k(this)f(License.)59 b(If)36 b(y)m(ou)h(cannot)g(con)m(v)m
+(ey)h(a)e(co)m(v)m(ered)i(w)m(ork)f(so)g(as)f(to)h(satisfy)g(sim)m
+(ultaneously)330 4260 y(y)m(our)44 b(obligations)i(under)c(this)i
+(License)h(and)e(an)m(y)i(other)f(p)s(ertinen)m(t)g(obligations,)49
+b(then)44 b(as)h(a)330 4369 y(consequence)40 b(y)m(ou)f(ma)m(y)g(not)g
+(con)m(v)m(ey)i(it)e(at)h(all.)67 b(F)-8 b(or)40 b(example,)i(if)d(y)m
+(ou)g(agree)h(to)g(terms)e(that)330 4479 y(obligate)32
+b(y)m(ou)e(to)h(collect)h(a)f(ro)m(y)m(alt)m(y)h(for)e(further)e(con)m
+(v)m(eying)k(from)e(those)g(to)h(whom)e(y)m(ou)h(con)m(v)m(ey)330
+4589 y(the)h(Program,)h(the)f(only)g(w)m(a)m(y)h(y)m(ou)g(could)f
+(satisfy)g(b)s(oth)g(those)g(terms)g(and)g(this)g(License)g(w)m(ould)
+330 4698 y(b)s(e)f(to)h(refrain)f(en)m(tirely)h(from)f(con)m(v)m(eying)
+i(the)f(Program.)154 4855 y(13.)61 b(Use)31 b(with)f(the)g(GNU)h
+(A\013ero)g(General)h(Public)e(License.)330 5011 y(Not)m(withstanding)
+39 b(an)m(y)g(other)f(pro)m(vision)h(of)f(this)g(License,)k(y)m(ou)c
+(ha)m(v)m(e)i(p)s(ermission)d(to)i(link)f(or)330 5121
+y(com)m(bine)h(an)m(y)g(co)m(v)m(ered)i(w)m(ork)e(with)f(a)h(w)m(ork)g
+(licensed)g(under)e(v)m(ersion)i(3)g(of)g(the)g(GNU)g(A\013ero)330
+5230 y(General)29 b(Public)f(License)h(in)m(to)h(a)f(single)g(com)m
+(bined)f(w)m(ork,)h(and)f(to)h(con)m(v)m(ey)h(the)f(resulting)g(w)m
+(ork.)330 5340 y(The)f(terms)g(of)g(this)h(License)f(will)h(con)m(tin)m
+(ue)g(to)g(apply)f(to)h(the)g(part)f(whic)m(h)g(is)g(the)h(co)m(v)m
+(ered)h(w)m(ork,)p eop end
+%%Page: 11 15
+TeXDict begin 11 14 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2006 b(11)330 299 y(but)38 b(the)h(sp)s(ecial)g(requiremen)m
+(ts)f(of)h(the)g(GNU)g(A\013ero)g(General)g(Public)g(License,)i
+(section)f(13,)330 408 y(concerning)31 b(in)m(teraction)h(through)e(a)h
+(net)m(w)m(ork)g(will)f(apply)g(to)i(the)e(com)m(bination)i(as)e(suc)m
+(h.)154 538 y(14.)61 b(Revised)31 b(V)-8 b(ersions)30
+b(of)h(this)f(License.)330 667 y(The)35 b(F)-8 b(ree)36
+b(Soft)m(w)m(are)g(F)-8 b(oundation)36 b(ma)m(y)g(publish)d(revised)i
+(and/or)g(new)g(v)m(ersions)h(of)f(the)g(GNU)330 777
+y(General)f(Public)f(License)g(from)g(time)g(to)h(time.)49
+b(Suc)m(h)33 b(new)f(v)m(ersions)h(will)h(b)s(e)e(similar)h(in)g
+(spirit)330 887 y(to)e(the)g(presen)m(t)f(v)m(ersion,)h(but)f(ma)m(y)h
+(di\013er)f(in)g(detail)i(to)f(address)e(new)h(problems)g(or)g
+(concerns.)330 1016 y(Eac)m(h)37 b(v)m(ersion)g(is)f(giv)m(en)h(a)g
+(distinguishing)e(v)m(ersion)i(n)m(um)m(b)s(er.)57 b(If)36
+b(the)g(Program)g(sp)s(eci\014es)g(that)330 1126 y(a)31
+b(certain)h(n)m(um)m(b)s(ered)d(v)m(ersion)i(of)g(the)g(GNU)g(General)h
+(Public)e(License)h(\\or)g(an)m(y)g(later)h(v)m(ersion")330
+1235 y(applies)h(to)g(it,)h(y)m(ou)e(ha)m(v)m(e)i(the)f(option)g(of)f
+(follo)m(wing)i(the)f(terms)f(and)g(conditions)h(either)g(of)f(that)330
+1345 y(n)m(um)m(b)s(ered)h(v)m(ersion)h(or)g(of)g(an)m(y)g(later)h(v)m
+(ersion)g(published)d(b)m(y)i(the)g(F)-8 b(ree)35 b(Soft)m(w)m(are)g(F)
+-8 b(oundation.)330 1455 y(If)28 b(the)h(Program)g(do)s(es)g(not)g(sp)s
+(ecify)f(a)h(v)m(ersion)g(n)m(um)m(b)s(er)f(of)h(the)g(GNU)g(General)h
+(Public)e(License,)330 1564 y(y)m(ou)j(ma)m(y)g(c)m(ho)s(ose)g(an)m(y)g
+(v)m(ersion)g(ev)m(er)g(published)d(b)m(y)j(the)f(F)-8
+b(ree)32 b(Soft)m(w)m(are)f(F)-8 b(oundation.)330 1694
+y(If)39 b(the)h(Program)g(sp)s(eci\014es)f(that)h(a)g(pro)m(xy)g(can)g
+(decide)g(whic)m(h)f(future)g(v)m(ersions)h(of)f(the)h(GNU)330
+1803 y(General)34 b(Public)e(License)i(can)f(b)s(e)f(used,)h(that)h
+(pro)m(xy's)e(public)h(statemen)m(t)h(of)f(acceptance)j(of)d(a)330
+1913 y(v)m(ersion)e(p)s(ermanen)m(tly)f(authorizes)h(y)m(ou)g(to)g(c)m
+(ho)s(ose)g(that)g(v)m(ersion)g(for)f(the)h(Program.)330
+2042 y(Later)37 b(license)g(v)m(ersions)f(ma)m(y)h(giv)m(e)g(y)m(ou)g
+(additional)g(or)f(di\013eren)m(t)h(p)s(ermissions.)56
+b(Ho)m(w)m(ev)m(er,)40 b(no)330 2152 y(additional)25
+b(obligations)i(are)e(imp)s(osed)f(on)g(an)m(y)h(author)f(or)h(cop)m
+(yrigh)m(t)h(holder)e(as)h(a)g(result)f(of)h(y)m(our)330
+2262 y(c)m(ho)s(osing)31 b(to)g(follo)m(w)h(a)f(later)g(v)m(ersion.)154
+2391 y(15.)61 b(Disclaimer)32 b(of)f(W)-8 b(arran)m(t)m(y)g(.)330
+2521 y(THERE)47 b(IS)f(NO)h(W)-10 b(ARRANTY)48 b(F)m(OR)f(THE)g(PR)m
+(OGRAM,)h(TO)f(THE)g(EXTENT)f(PER-)330 2630 y(MITTED)g(BY)i(APPLICABLE)
+e(LA)-10 b(W.)47 b(EX)m(CEPT)f(WHEN)i(OTHER)-10 b(WISE)45
+b(ST)-8 b(A)g(TED)47 b(IN)330 2740 y(WRITING)34 b(THE)f(COPYRIGHT)g
+(HOLDERS)g(AND/OR)i(OTHER)e(P)-8 b(AR)g(TIES)33 b(PR)m(O)m(VIDE)330
+2849 y(THE)d(PR)m(OGRAM)i(\\AS)e(IS")h(WITHOUT)f(W)-10
+b(ARRANTY)31 b(OF)g(ANY)g(KIND,)g(EITHER)f(EX-)330 2959
+y(PRESSED)k(OR)h(IMPLIED,)g(INCLUDING,)g(BUT)h(NOT)e(LIMITED)h(TO,)f
+(THE)h(IMPLIED)330 3068 y(W)-10 b(ARRANTIES)38 b(OF)g(MER)m(CHANT)-8
+b(ABILITY)39 b(AND)g(FITNESS)e(F)m(OR)i(A)f(P)-8 b(AR)g(TICULAR)330
+3178 y(PURPOSE.)39 b(THE)h(ENTIRE)f(RISK)g(AS)h(TO)f(THE)g(QUALITY)h
+(AND)h(PERF)m(ORMANCE)330 3288 y(OF)29 b(THE)g(PR)m(OGRAM)h(IS)f(WITH)g
+(YOU.)h(SHOULD)f(THE)g(PR)m(OGRAM)h(PR)m(O)m(VE)g(DEFEC-)330
+3397 y(TIVE,)24 b(YOU)g(ASSUME)f(THE)h(COST)f(OF)h(ALL)g(NECESSAR)-8
+b(Y)23 b(SER)-10 b(VICING,)23 b(REP)-8 b(AIR)24 b(OR)330
+3507 y(CORRECTION.)154 3636 y(16.)61 b(Limitation)32
+b(of)e(Liabilit)m(y)-8 b(.)330 3766 y(IN)26 b(NO)g(EVENT)g(UNLESS)f
+(REQUIRED)h(BY)h(APPLICABLE)f(LA)-10 b(W)26 b(OR)g(A)m(GREED)h(TO)f(IN)
+330 3875 y(WRITING)37 b(WILL)f(ANY)i(COPYRIGHT)e(HOLDER,)h(OR)f(ANY)h
+(OTHER)f(P)-8 b(AR)g(TY)38 b(WHO)330 3985 y(MODIFIES)33
+b(AND/OR)h(CONVEYS)e(THE)h(PR)m(OGRAM)h(AS)e(PERMITTED)h(ABO)m(VE,)h
+(BE)330 4095 y(LIABLE)d(TO)e(YOU)i(F)m(OR)g(D)m(AMA)m(GES,)i(INCLUDING)
+e(ANY)g(GENERAL,)g(SPECIAL,)f(IN-)330 4204 y(CIDENT)-8
+b(AL)32 b(OR)f(CONSEQUENTIAL)f(D)m(AMA)m(GES)j(ARISING)f(OUT)f(OF)h
+(THE)f(USE)g(OR)330 4314 y(INABILITY)47 b(TO)f(USE)g(THE)g(PR)m(OGRAM)i
+(\(INCLUDING)f(BUT)g(NOT)f(LIMITED)h(TO)330 4423 y(LOSS)28
+b(OF)h(D)m(A)-8 b(T)g(A)31 b(OR)e(D)m(A)-8 b(T)g(A)31
+b(BEING)f(RENDERED)f(INA)m(CCURA)-8 b(TE)30 b(OR)e(LOSSES)g(SUS-)330
+4533 y(T)-8 b(AINED)43 b(BY)g(YOU)f(OR)g(THIRD)h(P)-8
+b(AR)g(TIES)42 b(OR)g(A)g(F)-10 b(AILURE)43 b(OF)f(THE)g(PR)m(OGRAM)330
+4643 y(TO)30 b(OPERA)-8 b(TE)29 b(WITH)i(ANY)f(OTHER)g(PR)m(OGRAMS\),)h
+(EVEN)f(IF)h(SUCH)e(HOLDER)h(OR)330 4752 y(OTHER)36 b(P)-8
+b(AR)g(TY)37 b(HAS)g(BEEN)f(AD)m(VISED)i(OF)f(THE)f(POSSIBILITY)f(OF)h
+(SUCH)g(D)m(AM-)330 4862 y(A)m(GES.)154 4991 y(17.)61
+b(In)m(terpretation)31 b(of)g(Sections)g(15)g(and)f(16.)330
+5121 y(If)d(the)h(disclaimer)g(of)f(w)m(arran)m(t)m(y)i(and)d
+(limitation)k(of)d(liabilit)m(y)j(pro)m(vided)d(ab)s(o)m(v)m(e)h
+(cannot)g(b)s(e)f(giv)m(en)330 5230 y(lo)s(cal)35 b(legal)h(e\013ect)g
+(according)f(to)f(their)h(terms,)g(reviewing)f(courts)g(shall)h(apply)e
+(lo)s(cal)j(la)m(w)e(that)330 5340 y(most)j(closely)i(appro)m(ximates)f
+(an)f(absolute)g(w)m(aiv)m(er)i(of)e(all)g(civil)i(liabilit)m(y)f(in)f
+(connection)h(with)p eop end
+%%Page: 12 16
+TeXDict begin 12 15 bop 150 -116 a Fp(GNU)31 b(GENERAL)f(PUBLIC)h
+(LICENSE)2006 b(12)330 299 y(the)35 b(Program,)i(unless)d(a)h(w)m
+(arran)m(t)m(y)h(or)f(assumption)g(of)g(liabilit)m(y)i(accompanies)f(a)
+g(cop)m(y)g(of)f(the)330 408 y(Program)c(in)f(return)f(for)h(a)h(fee.)
+150 641 y Fo(END)45 b(OF)g(TERMS)f(AND)h(CONDITIONS)150
+873 y(Ho)l(w)h(to)f(Apply)f(These)h(T)-11 b(erms)45 b(to)g(Y)-11
+b(our)44 b(New)i(Programs)150 1033 y Fp(If)20 b(y)m(ou)i(dev)m(elop)f
+(a)h(new)e(program,)j(and)d(y)m(ou)i(w)m(an)m(t)f(it)h(to)f(b)s(e)g(of)
+g(the)g(greatest)i(p)s(ossible)d(use)h(to)g(the)g(public,)150
+1142 y(the)28 b(b)s(est)f(w)m(a)m(y)i(to)g(ac)m(hiev)m(e)h(this)e(is)g
+(to)g(mak)m(e)h(it)g(free)f(soft)m(w)m(are)h(whic)m(h)e(ev)m(ery)m(one)
+j(can)e(redistribute)g(and)150 1252 y(c)m(hange)k(under)c(these)j
+(terms.)275 1411 y(T)-8 b(o)29 b(do)h(so,)g(attac)m(h)h(the)f(follo)m
+(wing)h(notices)f(to)h(the)e(program.)40 b(It)30 b(is)g(safest)g(to)g
+(attac)m(h)h(them)f(to)g(the)150 1521 y(start)38 b(of)g(eac)m(h)g
+(source)g(\014le)f(to)h(most)g(e\013ectiv)m(ely)i(state)f(the)f
+(exclusion)g(of)f(w)m(arran)m(t)m(y;)42 b(and)37 b(eac)m(h)i(\014le)150
+1631 y(should)29 b(ha)m(v)m(e)j(at)f(least)h(the)e(\\cop)m(yrigh)m(t")j
+(line)e(and)e(a)i(p)s(oin)m(ter)g(to)g(where)f(the)g(full)g(notice)i
+(is)e(found.)390 1768 y Fi(one)40 b(line)g(to)g(give)g(the)g(program's)
+h(name)f(and)g(a)g(brief)g(idea)g(of)g(what)g(it)g(does.)390
+1855 y Fh(Copyright)h(\(C\))f Fi(year)49 b(name)40 b(of)g(author)390
+2029 y Fh(This)g(program)h(is)f(free)g(software:)h(you)f(can)g
+(redistribute)i(it)e(and/or)g(modify)390 2116 y(it)g(under)g(the)g
+(terms)g(of)g(the)g(GNU)g(General)h(Public)f(License)h(as)f(published)h
+(by)390 2203 y(the)f(Free)g(Software)h(Foundation,)h(either)e(version)h
+(3)f(of)f(the)h(License,)h(or)f(\(at)390 2291 y(your)g(option\))h(any)f
+(later)g(version.)390 2465 y(This)g(program)h(is)f(distributed)h(in)f
+(the)g(hope)g(that)g(it)g(will)g(be)g(useful,)h(but)390
+2552 y(WITHOUT)g(ANY)f(WARRANTY;)h(without)g(even)f(the)g(implied)h
+(warranty)g(of)390 2639 y(MERCHANTABILITY)i(or)c(FITNESS)i(FOR)f(A)g
+(PARTICULAR)h(PURPOSE.)80 b(See)40 b(the)g(GNU)390 2726
+y(General)h(Public)f(License)h(for)f(more)g(details.)390
+2901 y(You)g(should)g(have)h(received)g(a)e(copy)h(of)g(the)g(GNU)g
+(General)h(Public)f(License)390 2988 y(along)g(with)g(this)h(program.)
+80 b(If)40 b(not,)g(see)g(http://www.gnu.org/licenses/.)275
+3147 y Fp(Also)31 b(add)e(information)i(on)f(ho)m(w)h(to)g(con)m(tact)i
+(y)m(ou)d(b)m(y)g(electronic)j(and)d(pap)s(er)f(mail.)275
+3307 y(If)e(the)i(program)f(do)s(es)f(terminal)i(in)m(teraction,)i(mak)
+m(e)e(it)g(output)f(a)g(short)g(notice)i(lik)m(e)f(this)f(when)f(it)150
+3416 y(starts)k(in)f(an)g(in)m(teractiv)m(e)j(mo)s(de:)390
+3553 y Fi(program)49 b Fh(Copyright)42 b(\(C\))e Fi(year)48
+b(name)41 b(of)e(author)390 3641 y Fh(This)h(program)h(comes)f(with)g
+(ABSOLUTELY)i(NO)e(WARRANTY;)h(for)f(details)h(type)f(`show)g(w'.)390
+3728 y(This)g(is)g(free)g(software,)h(and)f(you)g(are)g(welcome)h(to)e
+(redistribute)j(it)390 3815 y(under)e(certain)h(conditions;)h(type)e
+(`show)g(c')g(for)g(details.)275 3974 y Fp(The)27 b(h)m(yp)s(othetical)
+i(commands)f(`)p Fm(show)h(w)p Fp(')f(and)f(`)p Fm(show)j(c)p
+Fp(')d(should)g(sho)m(w)h(the)g(appropriate)g(parts)g(of)150
+4084 y(the)i(General)h(Public)f(License.)41 b(Of)30 b(course,)h(y)m
+(our)f(program's)g(commands)f(migh)m(t)i(b)s(e)f(di\013eren)m(t;)h(for)
+f(a)150 4193 y(GUI)h(in)m(terface,)h(y)m(ou)f(w)m(ould)f(use)g(an)g
+(\\ab)s(out)h(b)s(o)m(x".)275 4353 y(Y)-8 b(ou)34 b(should)f(also)i
+(get)g(y)m(our)e(emplo)m(y)m(er)i(\(if)g(y)m(ou)f(w)m(ork)g(as)g(a)g
+(programmer\))g(or)g(sc)m(ho)s(ol,)i(if)d(an)m(y)-8 b(,)36
+b(to)150 4462 y(sign)d(a)g(\\cop)m(yrigh)m(t)h(disclaimer")g(for)e(the)
+h(program,)g(if)f(necessary)-8 b(.)48 b(F)-8 b(or)34
+b(more)e(information)h(on)g(this,)150 4572 y(and)d(ho)m(w)g(to)h(apply)
+f(and)g(follo)m(w)i(the)e(GNU)h(GPL,)g(see)g Fm
+(http://www.gnu.org/licen)o(ses)o(/)p Fp(.)275 4731 y(The)44
+b(GNU)h(General)g(Public)f(License)i(do)s(es)e(not)h(p)s(ermit)e
+(incorp)s(orating)i(y)m(our)g(program)f(in)m(to)150 4841
+y(proprietary)35 b(programs.)57 b(If)35 b(y)m(our)h(program)f(is)h(a)g
+(subroutine)f(library)-8 b(,)37 b(y)m(ou)f(ma)m(y)h(consider)e(it)i
+(more)150 4951 y(useful)30 b(to)i(p)s(ermit)e(linking)i(proprietary)e
+(applications)i(with)f(the)g(library)-8 b(.)43 b(If)31
+b(this)g(is)g(what)g(y)m(ou)g(w)m(an)m(t)150 5060 y(to)f(do,)g(use)f
+(the)g(GNU)h(Lesser)g(General)g(Public)f(License)h(instead)g(of)f(this)
+h(License.)40 b(But)30 b(\014rst,)f(please)150 5170 y(read)h
+Fm(http://www.gnu.org/philos)o(ophy)o(/why)o(-no)o(t-lg)o(pl.h)o(tml)o
+Fp(.)p eop end
+%%Page: 13 17
+TeXDict begin 13 16 bop 150 -116 a Fp(Chapter)30 b(2:)41
+b(A)30 b(Brief)h(In)m(tro)s(duction)f(to)h(Octa)m(v)m(e)1810
+b(13)150 299 y Fl(2)80 b(A)54 b(Brief)f(In)l(tro)t(duction)e(to)j(Octa)
+l(v)l(e)150 558 y Fp(This)40 b(man)m(ual)i(do)s(cumen)m(ts)e(ho)m(w)h
+(to)h(run,)h(install)f(and)e(p)s(ort)g(Octa)m(v)m(e's)k(C)p
+Fm(++)c Fp(classes,)45 b(and)40 b(ho)m(w)h(to)150 667
+y(rep)s(ort)30 b(bugs.)p eop end
+%%Page: 14 18
+TeXDict begin 14 17 bop 150 -116 a Fp(Chapter)30 b(3:)41
+b(Arra)m(ys)2778 b(14)150 299 y Fl(3)80 b(Arra)l(ys)150
+628 y Fo(3.1)68 b(Constructors)45 b(and)g(Assignmen)l(t)3224
+836 y Fp([Constructor])-3600 b Fg(Array<T>)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))390 946 y Fp(Create)31 b(an)f(arra)m(y)h(with)f(no)h
+(elemen)m(ts.)3224 1154 y([Constructor])-3600 b Fg(Array<T>)48
+b Ff(\()p Fe(in)m(t)31 b Fd(n)42 b Fc([)p Fe(,)31 b(const)g(T)f(&)p
+Fd(val)12 b Fc(])p Ff(\))390 1264 y Fp(Create)22 b(an)f(arra)m(y)h
+(with)e Fe(n)h Fp(elemen)m(ts.)39 b(If)21 b(the)g(optional)h(argumen)m
+(t)g Fe(v)-5 b(al)25 b Fp(is)c(supplied,)h(the)g(elemen)m(ts)390
+1373 y(are)32 b(initialized)h(to)f Fe(v)-5 b(al)t Fp(;)32
+b(otherwise,)g(they)g(are)g(left)g(uninitialized.)44
+b(If)31 b Fe(n)g Fp(is)g(less)h(than)f(zero,)i(the)390
+1483 y(curren)m(t)d(error)g(handler)g(is)g(in)m(v)m(ok)m(ed)i(\(see)f
+(Chapter)f(13)h([Error)f(Handling],)h(page)g(46\).)3224
+1691 y([Constructor])-3600 b Fg(Array<T>)48 b Ff(\()p
+Fe(const)31 b(Arra)m(y)p Fg(<)p Fe(T)p Fg(>)g Fe(&)p
+Fd(a)12 b Ff(\))390 1801 y Fp(Create)29 b(a)g(cop)m(y)h(of)f(the)f
+Fe(Arra)m(y)p Fm(<)p Fe(T)p Fm(>)g Fp(ob)5 b(ject)30
+b Fe(a)p Fp(.)40 b(Memory)29 b(for)g(the)g Fe(Arra)m(y)p
+Fm(<)p Fe(T)p Fm(>)e Fp(class)j(is)e(managed)390 1910
+y(using)g(a)h(reference)h(coun)m(ting)f(sc)m(heme,)h(so)f(the)g(cost)h
+(of)f(this)f(op)s(eration)i(is)e(indep)s(enden)m(t)g(of)h(the)390
+2020 y(size)i(of)g(the)f(arra)m(y)-8 b(.)2701 2228 y([Assignmen)m(t)31
+b(on)f Fm(Array<T>)p Fp(])-3602 b Fg(Array<T>&)55 b(operator)g(=)46
+b Ff(\()p Fe(const)31 b(Arra)m(y)p Fg(<)p Fe(T)p Fg(>)g
+Fe(&)p Fd(a)12 b Ff(\))390 2338 y Fp(Assignmen)m(t)34
+b(op)s(erator.)49 b(Memory)34 b(for)f(the)h Fe(Arra)m(y)p
+Fm(<)p Fe(T)p Fm(>)e Fp(class)i(is)f(managed)h(using)f(a)g(reference)
+390 2447 y(coun)m(ting)d(sc)m(heme,)h(so)e(the)h(cost)g(of)g(this)f(op)
+s(eration)h(is)f(indep)s(enden)m(t)f(of)i(the)f(size)i(of)e(the)h(arra)
+m(y)-8 b(.)2853 2656 y([Metho)s(d)31 b(on)f Fm(Array<T>)p
+Fp(])-3602 b Fg(int)53 b(capacity)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)2853 2765 y Fp([Metho)s(d)f(on)f
+Fm(Array<T>)p Fp(])-3602 b Fg(int)53 b(length)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)390 2875 y Fp(Return)e(the)g(length)h
+(of)f(the)h(arra)m(y)-8 b(.)2853 3083 y([Metho)s(d)31
+b(on)f Fm(Array<T>)p Fp(])-3602 b Fg(T&)53 b(elem)47
+b Ff(\()p Fe(in)m(t)31 b Fd(n)12 b Ff(\))2853 3193 y
+Fp([Metho)s(d)31 b(on)f Fm(Array<T>)p Fp(])-3602 b Fg(T&)53
+b(checkelem)48 b Ff(\()p Fe(in)m(t)31 b Fd(n)12 b Ff(\))390
+3302 y Fp(If)33 b Fe(n)g Fp(is)h(within)f(the)h(b)s(ounds)e(of)i(the)g
+(arra)m(y)-8 b(,)35 b(return)e(a)h(reference)g(to)h(the)f(elemen)m(t)h
+(indexed)e(b)m(y)390 3412 y Fe(n)p Fp(;)i(otherwise,)f(the)g(curren)m
+(t)f(error)g(handler)g(is)g(in)m(v)m(ok)m(ed)i(\(see)g(Chapter)d(13)j
+([Error)d(Handling],)390 3522 y(page)f(46\).)2818 3730
+y([Indexing)f(on)g Fm(Array<T>)p Fp(])-3602 b Fg(T&)53
+b(operator)i(\(\))46 b Ff(\()p Fe(in)m(t)31 b Fd(n)12
+b Ff(\))2853 3888 y Fp([Metho)s(d)31 b(on)f Fm(Array<T>)p
+Fp(])-3602 b Fg(T)53 b(elem)46 b Ff(\()p Fe(in)m(t)32
+b Fd(n)12 b Ff(\))30 b Fe(const)2853 3998 y Fp([Metho)s(d)h(on)f
+Fm(Array<T>)p Fp(])-3602 b Fg(T)53 b(checkelem)48 b Ff(\()p
+Fe(in)m(t)31 b Fd(n)12 b Ff(\))31 b Fe(const)390 4107
+y Fp(If)g Fe(n)g Fp(is)h(within)f(the)h(b)s(ounds)d(of)j(the)g(arra)m
+(y)-8 b(,)33 b(return)e(the)g(v)-5 b(alue)32 b(indexed)g(b)m(y)f
+Fe(n)p Fp(;)h(otherwise,)h(call)390 4217 y(the)e(curren)m(t)f(error)g
+(handler.)40 b(See)30 b(Chapter)g(13)h([Error)f(Handling],)h(page)g
+(46.)2818 4425 y([Indexing)f(on)g Fm(Array<T>)p Fp(])-3602
+b Fg(T)53 b(operator)h(\(\))46 b Ff(\()p Fe(in)m(t)32
+b Fd(n)12 b Ff(\))30 b Fe(const)2853 4584 y Fp([Metho)s(d)h(on)f
+Fm(Array<T>)p Fp(])-3602 b Fg(T&)53 b(xelem)47 b Ff(\()p
+Fe(in)m(t)31 b Fd(n)12 b Ff(\))2853 4693 y Fp([Metho)s(d)31
+b(on)f Fm(Array<T>)p Fp(])-3602 b Fg(T)53 b(xelem)47
+b Ff(\()p Fe(in)m(t)31 b Fd(n)12 b Ff(\))30 b Fe(const)390
+4803 y Fp(Return)39 b(a)h(reference)g(to,)j(or)d(the)g(v)-5
+b(alue)40 b(of,)j(the)d(elemen)m(t)h(indexed)e(b)m(y)h
+Fe(n)p Fp(.)68 b(These)40 b(metho)s(ds)390 4913 y(nev)m(er)31
+b(p)s(erform)e(b)s(ounds)f(c)m(hec)m(king.)2853 5121
+y([Metho)s(d)j(on)f Fm(Array<T>)p Fp(])-3602 b Fg(void)54
+b(resize)47 b Ff(\()p Fe(in)m(t)31 b Fd(n)42 b Fc([)p
+Fe(,)31 b(const)g(T)e(&)p Fd(val)12 b Fc(])p Ff(\))390
+5230 y Fp(Change)35 b(the)g(size)h(of)g(the)f(arra)m(y)h(to)g(b)s(e)e
+Fe(n)h Fp(elemen)m(ts.)56 b(All)36 b(elemen)m(ts)g(are)g(unc)m(hanged,)
+g(except)390 5340 y(that)e(if)f Fe(n)f Fp(is)h(greater)i(than)d(the)i
+(curren)m(t)e(size)i(and)f(the)g(optional)h(argumen)m(t)g
+Fe(v)-5 b(al)37 b Fp(is)c(pro)m(vided,)p eop end
+%%Page: 15 19
+TeXDict begin 15 18 bop 150 -116 a Fp(Chapter)30 b(3:)41
+b(Arra)m(ys)2778 b(15)390 299 y(the)33 b(additional)g(elemen)m(ts)h
+(are)e(initialized)i(to)g Fe(v)-5 b(al)t Fp(;)33 b(otherwise,)h(an)m(y)
+f(additional)g(elemen)m(ts)h(are)390 408 y(left)27 b(uninitialized.)41
+b(In)26 b(the)h(curren)m(t)f(implemen)m(tation,)k(if)c
+Fe(n)g Fp(is)h(less)g(than)g(the)g(curren)m(t)f(size,)j(the)390
+518 y(length)i(is)f(up)s(dated)f(but)h(no)g(memory)g(is)h(released.)
+2853 717 y([Metho)s(d)g(on)f Fm(Array<T>)p Fp(])-3602
+b Fg(const)54 b(T*)f(data)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)3224 866 y Fp([Constructor])-3600 b Fg(Array2<T>)48
+b Fe(Arra)m(y2)p Fg(<)p Fe(T)p Fg(>)32 b Fe(Arra)m(y2)f
+Ff(\()p Fe(v)m(oid)p Ff(\))3224 976 y Fp([Constructor])-3600
+b Fg(Array2<T>)48 b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g
+Fd(m)12 b Ff(\))3224 1086 y Fp([Constructor])-3600 b
+Fg(Array2<T>)48 b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g
+Fd(m)p Fe(,)g(const)g(T)f(&)p Fd(val)12 b Ff(\))3224
+1195 y Fp([Constructor])-3600 b Fg(Array2<T>)48 b Ff(\()p
+Fe(const)31 b(Arra)m(y2)p Fg(<)p Fe(T)p Fg(>)h Fe(&)p
+Fd(a)12 b Ff(\))3224 1305 y Fp([Constructor])-3600 b
+Fg(Array2<T>)48 b Ff(\()p Fe(const)31 b(DiagArra)m(y)p
+Fg(<)p Fe(T)p Fg(>)i Fe(&)p Fd(a)12 b Ff(\))2653 1454
+y Fp([Assignmen)m(t)31 b(on)f Fm(Array2<T>)p Fp(])-3602
+b Fg(Array2<T>&)55 b(operator)g(=)46 b Ff(\()p Fe(const)31
+b(Arra)m(y2)p Fg(<)p Fe(T)p Fg(>)g Fe(&)p Fd(a)12 b Ff(\))2805
+1603 y Fp([Metho)s(d)31 b(on)f Fm(Array2<T>)p Fp(])-3602
+b Fg(int)53 b(dim1)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)2805 1713 y Fp([Metho)s(d)f(on)f Fm(Array2<T>)p
+Fp(])-3602 b Fg(int)53 b(rows)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)2805 1862 y Fp([Metho)s(d)f(on)f
+Fm(Array2<T>)p Fp(])-3602 b Fg(int)53 b(dim2)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)2805 1972 y Fp([Metho)s(d)f(on)f
+Fm(Array2<T>)p Fp(])-3602 b Fg(int)53 b(cols)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)2805 2081 y Fp([Metho)s(d)f(on)f
+Fm(Array2<T>)p Fp(])-3602 b Fg(int)53 b(columns)48 b
+Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)2805 2231 y
+Fp([Metho)s(d)g(on)f Fm(Array2<T>)p Fp(])-3602 b Fg(T&)53
+b(elem)47 b Ff(\()p Fe(in)m(t)31 b Fd(i)p Fe(,)g(in)m(t)g
+Fd(j)12 b Ff(\))2805 2340 y Fp([Metho)s(d)31 b(on)f Fm(Array2<T>)p
+Fp(])-3602 b Fg(T&)53 b(checkelem)48 b Ff(\()p Fe(in)m(t)31
+b Fd(i)p Fe(,)g(in)m(t)g Fd(j)12 b Ff(\))2770 2489 y
+Fp([Indexing)30 b(on)g Fm(Array2<T>)p Fp(])-3602 b Fg(T&)53
+b(operator)i(\(\))46 b Ff(\()p Fe(in)m(t)31 b Fd(i)p
+Fe(,)g(in)m(t)g Fd(j)12 b Ff(\))2805 2639 y Fp([Metho)s(d)31
+b(on)f Fm(Array2<T>)p Fp(])-3602 b Fg(void)54 b(resize)47
+b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g Fd(m)12
+b Ff(\))2805 2748 y Fp([Metho)s(d)31 b(on)f Fm(Array2<T>)p
+Fp(])-3602 b Fg(void)54 b(resize)47 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(in)m(t)g Fd(m)p Fe(,)g(const)g(T)e(&)p
+Fd(val)12 b Ff(\))3224 2898 y Fp([Constructor])-3600
+b Fg(Array3<T>)48 b Ff(\()p Fe(v)m(oid)p Ff(\))3224 3007
+y Fp([Constructor])-3600 b Fg(Array3<T>)48 b Ff(\()p
+Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g Fd(m)p Fe(,)g(in)m(t)g
+Fd(k)12 b Ff(\))3224 3117 y Fp([Constructor])-3600 b
+Fg(Array3<T>)48 b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g
+Fd(m)p Fe(,)g(in)m(t)g Fd(k)p Fe(,)g(const)g(T)f(&)p
+Fd(val)12 b Ff(\))3224 3226 y Fp([Constructor])-3600
+b Fg(Array3<T>)48 b Ff(\()p Fe(const)31 b(Arra)m(y3)p
+Fg(<)p Fe(T)p Fg(>)h Fe(&)p Fd(a)12 b Ff(\))2653 3376
+y Fp([Assignmen)m(t)31 b(on)f Fm(Array3<T>)p Fp(])-3602
+b Fg(Array3<T>&)55 b(operator)g(=)46 b Ff(\()p Fe(const)31
+b(Arra)m(y3)p Fg(<)p Fe(T)p Fg(>)g Fe(&)p Fd(a)12 b Ff(\))2805
+3525 y Fp([Metho)s(d)31 b(on)f Fm(Array3<T>)p Fp(])-3602
+b Fg(int)53 b(dim1)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)2805 3634 y Fp([Metho)s(d)f(on)f Fm(Array3<T>)p
+Fp(])-3602 b Fg(int)53 b(dim2)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)2805 3744 y Fp([Metho)s(d)f(on)f
+Fm(Array3<T>)p Fp(])-3602 b Fg(int)53 b(dim3)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)2805 3893 y Fp([Metho)s(d)f(on)f
+Fm(Array3<T>)p Fp(])-3602 b Fg(T&)53 b(elem)47 b Ff(\()p
+Fe(in)m(t)31 b Fd(i)p Fe(,)g(in)m(t)g Fd(j)p Fe(,)f(in)m(t)h
+Fd(k)12 b Ff(\))2805 4003 y Fp([Metho)s(d)31 b(on)f Fm(Array3<T>)p
+Fp(])-3602 b Fg(T&)53 b(checkelem)48 b Ff(\()p Fe(in)m(t)31
+b Fd(i)p Fe(,)g(in)m(t)g Fd(j)p Fe(,)g(in)m(t)g Fd(k)12
+b Ff(\))2770 4152 y Fp([Indexing)30 b(on)g Fm(Array3<T>)p
+Fp(])-3602 b Fg(T&)53 b(operator)i(\(\))46 b Ff(\()p
+Fe(in)m(t)31 b Fd(i)p Fe(,)g(in)m(t)g Fd(j)p Fe(,)g(in)m(t)f
+Fd(k)12 b Ff(\))2805 4301 y Fp([Metho)s(d)31 b(on)f Fm(Array3<T>)p
+Fp(])-3602 b Fg(void)54 b(resize)47 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(in)m(t)g Fd(m)p Fe(,)g(in)m(t)g Fd(k)12
+b Ff(\))2805 4411 y Fp([Metho)s(d)31 b(on)f Fm(Array3<T>)p
+Fp(])-3602 b Fg(void)54 b(resize)47 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(in)m(t)g Fd(m)p Fe(,)g(in)m(t)g Fd(k)p
+Fe(,)f(const)h(T)f(&)p Fd(val)12 b Ff(\))3224 4560 y
+Fp([Constructor])-3600 b Fg(DiagArray<T>)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))3224 4670 y Fp([Constructor])-3600
+b Fg(DiagArray<T>)49 b Ff(\()p Fe(in)m(t)31 b Fd(n)12
+b Ff(\))3224 4779 y Fp([Constructor])-3600 b Fg(DiagArray<T>)49
+b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(const)g(T)f(&)p
+Fd(val)12 b Ff(\))3224 4889 y Fp([Constructor])-3600
+b Fg(DiagArray<T>)49 b Ff(\()p Fe(in)m(t)31 b Fd(r)p
+Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))3224 4999 y Fp([Constructor])-3600
+b Fg(DiagArray<T>)49 b Ff(\()p Fe(in)m(t)31 b Fd(r)p
+Fe(,)g(in)m(t)g Fd(c)p Fe(,)g(const)g(T)f(&)p Fd(val)12
+b Ff(\))3224 5108 y Fp([Constructor])-3600 b Fg(DiagArray<T>)49
+b Ff(\()p Fe(const)31 b(Arra)m(y)p Fg(<)p Fe(T)p Fg(>)g
+Fe(&)p Fd(a)12 b Ff(\))3224 5218 y Fp([Constructor])-3600
+b Fg(DiagArray<T>)49 b Ff(\()p Fe(const)31 b(DiagArra)m(y)p
+Fg(<)p Fe(T)p Fg(>)i Fe(&)p Fd(a)12 b Ff(\))2462 5367
+y Fp([Assginmen)m(t)31 b(on)f Fm(DiagArray<T>&)p Fp(])-3603
+b Fg(operator)55 b(=)45 b Ff(\()p Fe(const)32 b(DiagArra)m(y)p
+Fg(<)p Fe(T)p Fg(>)g Fe(&)p Fd(a)12 b Ff(\))p eop end
+%%Page: 16 20
+TeXDict begin 16 19 bop 150 -116 a Fp(Chapter)30 b(3:)41
+b(Arra)m(ys)2778 b(16)2662 299 y([Metho)s(d)31 b(on)f
+Fm(DiagArray<T>)p Fp(])-3603 b Fg(int)53 b(dim1)47 b
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)2662 408 y Fp([Metho)s(d)f(on)
+f Fm(DiagArray<T>)p Fp(])-3603 b Fg(int)53 b(rows)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)2662 570 y
+Fp([Metho)s(d)f(on)f Fm(DiagArray<T>)p Fp(])-3603 b Fg(int)53
+b(dim2)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)2662
+680 y Fp([Metho)s(d)f(on)f Fm(DiagArray<T>)p Fp(])-3603
+b Fg(int)53 b(cols)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)2662 789 y Fp([Metho)s(d)f(on)f Fm(DiagArray<T>)p
+Fp(])-3603 b Fg(int)53 b(columns)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)2662 951 y Fp([Metho)s(d)g(on)f Fm(DiagArray<T>)p
+Fp(])-3603 b Fg(T&)53 b(elem)47 b Ff(\()p Fe(in)m(t)31
+b Fd(r)p Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))2662 1060 y
+Fp([Metho)s(d)31 b(on)f Fm(DiagArray<T>)p Fp(])-3603
+b Fg(T&)53 b(checkelem)48 b Ff(\()p Fe(in)m(t)31 b Fd(r)p
+Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))2627 1222 y Fp([Indexing)30
+b(on)g Fm(DiagArray<T>)p Fp(])-3603 b Fg(T&)53 b(operator)i(\(\))46
+b Ff(\()p Fe(in)m(t)31 b Fd(r)p Fe(,)g(in)m(t)g Fd(c)12
+b Ff(\))2662 1384 y Fp([Metho)s(d)31 b(on)f Fm(DiagArray<T>)p
+Fp(])-3603 b Fg(void)54 b(resize)47 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(in)m(t)g Fd(m)12 b Ff(\))2662 1493 y
+Fp([Metho)s(d)31 b(on)f Fm(DiagArray<T>)p Fp(])-3603
+b Fg(void)54 b(resize)47 b Ff(\()p Fe(in)m(t)31 b Fd(n)p
+Fe(,)g(in)m(t)g Fd(m)p Fe(,)g(const)g(T)e(&)p Fd(val)12
+b Ff(\))275 1603 y Fp(The)27 b(real)i(and)f(complex)h
+Fm(ColumnVector)24 b Fp(and)k Fm(RowVector)e Fp(classes)j(all)g(ha)m(v)
+m(e)g(the)g(follo)m(wing)h(func-)150 1712 y(tions.)39
+b(These)23 b(will)i(ev)m(en)m(tually)g(b)s(e)f(part)f(of)h(an)g
+Fm(MArray<T>)d Fp(class,)26 b(deriv)m(ed)e(from)f(the)h
+Fm(Array<T>)e Fp(class.)150 1822 y(Then)29 b(the)i Fm(ColumnVector)c
+Fp(and)j Fm(RowVector)e Fp(classes)j(will)g(b)s(e)e(deriv)m(ed)i(from)f
+(the)g Fm(MArray<T>)e Fp(class.)275 1983 y(Elemen)m(t)j(b)m(y)f(elemen)
+m(t)i(v)m(ector)g(b)m(y)e(scalar)i(ops.)150 2195 y Fg(RowVector)55
+b(operator)g(+)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)32 b(&)p Fd(a)p Fe(,)f(const)g(double)f(&)p Fd(s)12
+b Ff(\))150 2305 y Fg(RowVector)55 b(operator)g(-)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p
+Fe(,)f(const)g(double)f(&)p Fd(s)12 b Ff(\))150 2414
+y Fg(RowVector)55 b(operator)g(*)46 b Ff(\()p Fe(const)31
+b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p Fe(,)f(const)g(double)f(&)p
+Fd(s)12 b Ff(\))150 2524 y Fg(RowVector)55 b(operator)g(/)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p
+Fe(,)f(const)g(double)f(&)p Fd(s)12 b Ff(\))275 2633
+y Fp(Elemen)m(t)31 b(b)m(y)f(elemen)m(t)i(scalar)f(b)m(y)g(v)m(ector)h
+(ops.)150 2846 y Fg(RowVector)55 b(operator)g(+)46 b
+Ff(\()p Fe(const)31 b(double)f(&)p Fd(s)p Fe(,)g(const)h(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 2956 y Fg(RowVector)55
+b(operator)g(-)46 b Ff(\()p Fe(const)31 b(double)f(&)p
+Fd(s)p Fe(,)g(const)h(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))150 3065 y Fg(RowVector)55 b(operator)g(*)46
+b Ff(\()p Fe(const)31 b(double)f(&)p Fd(s)p Fe(,)g(const)h(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 3175 y Fg(RowVector)55
+b(operator)g(/)46 b Ff(\()p Fe(const)31 b(double)f(&)p
+Fd(s)p Fe(,)g(const)h(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))275 3284 y Fp(Elemen)m(t)31 b(b)m(y)f(elemen)m(t)i(v)m(ector)g
+(b)m(y)e(v)m(ector)i(ops.)150 3497 y Fg(RowVector)55
+b(operator)g(+)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)32 b(&)p Fd(a)p Fe(,)f(const)g(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(b)12 b Ff(\))150 3606 y Fg(RowVector)55 b(operator)g(-)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p
+Fe(,)f(const)g(Ro)m(wV)-8 b(ector)32 b(&)p Fd(b)12 b
+Ff(\))150 3768 y Fg(RowVector)55 b(product)48 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p Fe(,)f(const)g(Ro)m
+(wV)-8 b(ector)33 b(&)p Fd(b)12 b Ff(\))150 3878 y Fg(RowVector)55
+b(quotient)48 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33
+b(&)p Fd(a)p Fe(,)d(const)h(Ro)m(wV)-8 b(ector)33 b(&)p
+Fd(b)12 b Ff(\))275 3987 y Fp(Unary)30 b(MArra)m(y)h(ops.)150
+4200 y Fg(RowVector)55 b(operator)g(-)46 b Ff(\()p Fe(const)31
+b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))275 4309
+y Fp(The)35 b Fm(Matrix)g Fp(classes)i(share)f(the)g(follo)m(wing)i
+(functions.)58 b(These)35 b(will)i(ev)m(en)m(tually)h(b)s(e)e(part)g
+(of)g(an)150 4419 y Fm(MArray2<T>)23 b Fp(class,)28 b(deriv)m(ed)f
+(from)e(the)h Fm(Array2<T>)e Fp(class.)40 b(Then)25 b(the)i
+Fm(Matrix)d Fp(class)j(will)f(b)s(e)g(deriv)m(ed)150
+4529 y(from)k(the)g Fm(MArray<T>)e Fp(class.)275 4689
+y(Elemen)m(t)j(b)m(y)f(elemen)m(t)i(matrix)f(b)m(y)f(scalar)h(ops.)150
+4902 y Fg(Matrix)54 b(operator)h(+)46 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(double)f(&)p Fd(s)12
+b Ff(\))150 5011 y Fg(Matrix)54 b(operator)h(-)46 b Ff(\()p
+Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(double)f(&)p
+Fd(s)12 b Ff(\))150 5121 y Fg(Matrix)54 b(operator)h(*)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(double)f(&)p
+Fd(s)12 b Ff(\))150 5230 y Fg(Matrix)54 b(operator)h(/)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(double)f(&)p
+Fd(s)12 b Ff(\))275 5340 y Fp(Elemen)m(t)31 b(b)m(y)f(elemen)m(t)i
+(scalar)f(b)m(y)g(matrix)f(ops.)p eop end
+%%Page: 17 21
+TeXDict begin 17 20 bop 150 -116 a Fp(Chapter)30 b(3:)41
+b(Arra)m(ys)2778 b(17)150 299 y Fg(Matrix)54 b(operator)h(+)46
+b Ff(\()p Fe(const)31 b(double)f(&)p Fd(s)p Fe(,)g(const)h(Matrix)h(&)p
+Fd(a)12 b Ff(\))150 408 y Fg(Matrix)54 b(operator)h(-)46
+b Ff(\()p Fe(const)31 b(double)f(&)p Fd(s)p Fe(,)g(const)h(Matrix)h(&)p
+Fd(a)12 b Ff(\))150 518 y Fg(Matrix)54 b(operator)h(*)46
+b Ff(\()p Fe(const)31 b(double)f(&)p Fd(s)p Fe(,)g(const)h(Matrix)h(&)p
+Fd(a)12 b Ff(\))150 628 y Fg(Matrix)54 b(operator)h(/)46
+b Ff(\()p Fe(const)31 b(double)f(&)p Fd(s)p Fe(,)g(const)h(Matrix)h(&)p
+Fd(a)12 b Ff(\))275 737 y Fp(Elemen)m(t)31 b(b)m(y)f(elemen)m(t)i
+(matrix)f(b)m(y)f(matrix)h(ops.)150 946 y Fg(Matrix)54
+b(operator)h(+)46 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(const)g(Matrix)g(&)p Fd(b)12 b Ff(\))150
+1056 y Fg(Matrix)54 b(operator)h(-)46 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(Matrix)g(&)p Fd(b)12
+b Ff(\))150 1215 y Fg(Matrix)54 b(product)48 b Ff(\()p
+Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(Matrix)g(&)p
+Fd(b)12 b Ff(\))150 1325 y Fg(Matrix)54 b(quotient)48
+b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(a)p Fe(,)e(const)h(Matrix)g(&)p
+Fd(b)12 b Ff(\))275 1435 y Fp(Unary)30 b(matrix)g(ops.)150
+1644 y Fg(Matrix)54 b(operator)h(-)46 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(a)12 b Ff(\))275 1753 y Fp(The)31 b
+Fm(DiagMatrix)e Fp(classes)k(share)f(the)g(follo)m(wing)i(functions.)45
+b(These)31 b(will)i(ev)m(en)m(tually)h(b)s(e)d(part)h(of)150
+1863 y(an)26 b Fm(MDiagArray<T>)d Fp(class,)28 b(deriv)m(ed)e(from)g
+(the)h Fm(DiagArray<T>)c Fp(class.)40 b(Then)25 b(the)i
+Fm(DiagMatrix)c Fp(class)150 1973 y(will)31 b(b)s(e)e(deriv)m(ed)i
+(from)f(the)g Fm(MDiagArray<T>)d Fp(class.)275 2132 y(Elemen)m(t)k(b)m
+(y)f(elemen)m(t)i(MDiagArra)m(y)h(b)m(y)d(scalar)h(ops.)150
+2341 y Fg(DiagMatrix)55 b(operator)g(*)46 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)f(double)g(&)p
+Fd(s)12 b Ff(\))150 2451 y Fg(DiagMatrix)55 b(operator)g(/)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)f(double)g
+(&)p Fd(s)12 b Ff(\))275 2560 y Fp(Elemen)m(t)31 b(b)m(y)f(elemen)m(t)i
+(scalar)f(b)m(y)g(MDiagArra)m(y)h(ops.)150 2770 y Fg(DiagMatrix)55
+b(operator)g(*)46 b Ff(\()p Fe(const)31 b(double)f(&)p
+Fd(s)p Fe(,)h(const)f(DiagMatrix)j(&)p Fd(a)12 b Ff(\))275
+2879 y Fp(Elemen)m(t)31 b(b)m(y)f(elemen)m(t)i(MDiagArra)m(y)h(b)m(y)d
+(MDiagArra)m(y)i(ops.)150 3088 y Fg(DiagMatrix)55 b(operator)g(+)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)f
+(DiagMatrix)j(&)p Fd(b)12 b Ff(\))150 3198 y Fg(DiagMatrix)55
+b(operator)g(-)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)p Fe(,)e(const)f(DiagMatrix)j(&)p Fd(b)12 b Ff(\))150
+3357 y Fg(DiagMatrix)55 b(product)48 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)f(DiagMatrix)j(&)p
+Fd(b)12 b Ff(\))275 3517 y Fp(Unary)30 b(MDiagArra)m(y)i(ops.)150
+3726 y Fg(DiagMatrix)55 b(operator)g(-)46 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))p eop end
+%%Page: 18 22
+TeXDict begin 18 21 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(18)150 299 y Fl(4)80 b(Matrix)54 b(and)g(V)-13 b(ector)52
+b(Op)t(erations)150 590 y Fg(Matrix)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 699 y Fg(Matrix)g Ff(\()p Fe(in)m(t)32 b Fd(r)p
+Fe(,)e(in)m(t)h Fd(c)12 b Ff(\))150 809 y Fg(Matrix)47
+b Ff(\()p Fe(in)m(t)32 b Fd(r)p Fe(,)e(in)m(t)h Fd(c)p
+Fe(,)g(double)f Fd(val)12 b Ff(\))150 918 y Fg(Matrix)47
+b Ff(\()p Fe(const)32 b(Arra)m(y2)p Fg(<)p Fe(double)p
+Fg(>)f Fe(&)p Fd(a)12 b Ff(\))150 1028 y Fg(Matrix)47
+b Ff(\()p Fe(const)32 b(Matrix)f(&)p Fd(a)12 b Ff(\))150
+1138 y Fg(Matrix)47 b Ff(\()p Fe(const)32 b(DiagArra)m(y)p
+Fg(<)p Fe(double)p Fg(>)g Fe(&)p Fd(a)12 b Ff(\))150
+1247 y Fg(Matrix)47 b Ff(\()p Fe(const)32 b(DiagMatrix)g(&)p
+Fd(a)12 b Ff(\))150 1401 y Fg(Matrix&)54 b(operator)h(=)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)12 b Ff(\))150
+1554 y Fg(int)53 b(operator)i(==)46 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 1664
+y Fg(int)53 b(operator)i(!=)46 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 1817
+y Fg(Matrix&)54 b(insert)48 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(in)m(t)g Fd(r)p Fe(,)g(in)m(t)f Fd(c)12
+b Ff(\))150 1926 y Fg(Matrix&)54 b(insert)48 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p Fe(,)d(in)m(t)h
+Fd(r)p Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))150 2036 y Fg(Matrix&)54
+b(insert)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(a)p Fe(,)g(in)m(t)g Fd(r)p Fe(,)g(in)m(t)f Fd(c)12
+b Ff(\))150 2146 y Fg(Matrix&)54 b(insert)48 b Ff(\()p
+Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(in)m(t)h
+Fd(r)p Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))150 2299 y Fg(Matrix&)54
+b(fill)47 b Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150
+2409 y Fg(Matrix&)54 b(fill)47 b Ff(\()p Fe(double)30
+b Fd(val)p Fe(,)i(in)m(t)f(r1,)f(in)m(t)h(c1,)h(in)m(t)f(r2,)f(in)m(t)h
+(c2)p Ff(\))150 2562 y Fg(Matrix)54 b(append)47 b Ff(\()p
+Fe(const)32 b(Matrix)f(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+2672 y Fg(Matrix)54 b(append)47 b Ff(\()p Fe(const)32
+b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+2781 y Fg(Matrix)54 b(append)47 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+2891 y Fg(Matrix)54 b(append)47 b Ff(\()p Fe(const)32
+b(DiagMatrix)h(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+3044 y Fg(Matrix)54 b(stack)47 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 3154
+y Fg(Matrix)54 b(stack)47 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 3263
+y Fg(Matrix)54 b(stack)47 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 3373
+y Fg(Matrix)54 b(stack)47 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))30 b Fe(const)150 3526 y Fg(Matrix)54
+b(transpose)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+3680 y Fg(Matrix)54 b(extract)48 b Ff(\()p Fe(in)m(t)31
+b(r1,)g(in)m(t)f(c1,)i(in)m(t)f(r2,)f(in)m(t)h(c2)p Ff(\))h
+Fe(const)150 3833 y Fg(RowVector)55 b(row)46 b Ff(\()p
+Fe(in)m(t)32 b Fd(i)12 b Ff(\))30 b Fe(const)150 3943
+y Fg(RowVector)55 b(row)46 b Ff(\()p Fe(c)m(har)31 b(*s)p
+Ff(\))g Fe(const)150 4096 y Fg(ColumnVector)56 b(column)47
+b Ff(\()p Fe(in)m(t)31 b Fd(i)12 b Ff(\))31 b Fe(const)150
+4206 y Fg(ColumnVector)56 b(column)47 b Ff(\()p Fe(c)m(har)31
+b(*s)p Ff(\))g Fe(const)150 4359 y Fg(Matrix)54 b(inverse)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 4469 y
+Fg(Matrix)54 b(inverse)48 b Ff(\()p Fe(in)m(t)31 b(&)p
+Fd(info)12 b Ff(\))31 b Fe(const)150 4578 y Fg(Matrix)54
+b(inverse)48 b Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)p Fe(,)g(double)f(&)p
+Fd(rcond)12 b Ff(\))32 b Fe(const)150 4732 y Fg(ComplexMatrix)56
+b(fourier)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+4841 y Fg(ComplexMatrix)56 b(ifourier)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 4995 y Fg(DET)53 b(determinant)c
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 5104 y Fg(DET)53
+b(determinant)c Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)12
+b Ff(\))31 b Fe(const)150 5214 y Fg(DET)53 b(determinant)c
+Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)p Fe(,)h(double)e(&)p
+Fd(rcond)12 b Ff(\))31 b Fe(const)150 5367 y Fg(Matrix)54
+b(solve)47 b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(b)12
+b Ff(\))30 b Fe(const)p eop end
+%%Page: 19 23
+TeXDict begin 19 22 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(19)150 299 y Fg(Matrix)54 b(solve)47 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)12
+b Ff(\))31 b Fe(const)150 408 y Fg(Matrix)54 b(solve)47
+b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p
+Fd(info)p Fe(,)h(double)d(&)p Fd(rcond)12 b Ff(\))32
+b Fe(const)150 571 y Fg(ComplexMatrix)56 b(solve)47 b
+Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p Fd(b)12 b Ff(\))30
+b Fe(const)150 680 y Fg(ComplexMatrix)56 b(solve)47 b
+Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p
+Fd(info)12 b Ff(\))31 b Fe(const)150 790 y Fg(ComplexMatrix)56
+b(solve)47 b Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p
+Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)p Fe(,)h(double)e(&)p
+Fd(rcond)12 b Ff(\))565 900 y Fe(const)150 1062 y Fg(ColumnVector)56
+b(solve)47 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))31 b Fe(const)150 1172 y Fg(ColumnVector)56
+b(solve)47 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p Fd(info)12 b Ff(\))31
+b Fe(const)150 1281 y Fg(ColumnVector)56 b(solve)47 b
+Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(b)p
+Fe(,)g(in)m(t)g(&)p Fd(info)p Fe(,)g(double)f(&)p Fd(rcond)12
+b Ff(\))32 b Fe(const)150 1444 y Fg(ComplexColumnVector)58
+b(solve)47 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(b)12 b Ff(\))30 b Fe(const)150 1553
+y Fg(ComplexColumnVector)58 b(solve)47 b Ff(\()p Fe(const)29
+b(ComplexColumnV)-8 b(ector)29 b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)12 b Ff(\))29 b Fe(const)150 1663 y Fg(ComplexColumnVector)58
+b(solve)47 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)p
+Fe(,)565 1772 y(double)f(&)p Fd(rcond)12 b Ff(\))31 b
+Fe(const)150 1935 y Fg(Matrix)54 b(lssolve)48 b Ff(\()p
+Fe(const)31 b(Matrix)g(&)p Fd(b)12 b Ff(\))30 b Fe(const)150
+2044 y Fg(Matrix)54 b(lssolve)48 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p Fd(info)12
+b Ff(\))31 b Fe(const)150 2154 y Fg(Matrix)54 b(lssolve)48
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)p Fe(,)g(in)m(t)g(&)p Fd(rank)12 b Ff(\))31 b
+Fe(const)150 2316 y Fg(ComplexMatrix)56 b(lssolve)48
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(b)12 b
+Ff(\))31 b Fe(const)150 2426 y Fg(ComplexMatrix)56 b(lssolve)48
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)12 b Ff(\))31 b Fe(const)150 2535 y Fg(ComplexMatrix)56
+b(lssolve)48 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(b)p Fe(,)g(in)m(t)g(&)p Fd(info)p Fe(,)g(in)m(t)g(&)p
+Fd(rank)12 b Ff(\))31 b Fe(const)150 2698 y Fg(ColumnVector)56
+b(lssolve)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))30 b Fe(const)150 2807 y Fg(ColumnVector)56
+b(lssolve)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(b)p Fe(,)g(in)m(t)f(&)p Fd(info)12 b Ff(\))32
+b Fe(const)150 2917 y Fg(ColumnVector)56 b(lssolve)48
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(b)p
+Fe(,)g(in)m(t)f(&)p Fd(info)p Fe(,)i(in)m(t)f(&)p Fd(rank)12
+b Ff(\))31 b Fe(const)150 3079 y Fg(ComplexColumnVector)58
+b(lssolve)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))30 b Fe(const)150 3189
+y Fg(ComplexColumnVector)58 b(lssolve)48 b Ff(\()p Fe(const)31
+b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)12 b Ff(\))565 3298 y Fe(const)150 3408 y Fg
+(ComplexColumnVector)58 b(lssolve)48 b Ff(\()p Fe(const)31
+b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)p Fe(,)g(in)m(t)565 3518 y(&)p Fd(rank)12 b Ff(\))31
+b Fe(const)150 3680 y Fg(Matrix&)54 b(operator)h(+=)46
+b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(a)12 b Ff(\))150
+3790 y Fg(Matrix&)54 b(operator)h(-=)46 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(a)12 b Ff(\))150 3952 y Fg(Matrix&)54
+b(operator)h(+=)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))150 4062 y Fg(Matrix&)54 b(operator)h(-=)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))150
+4224 y Fg(Matrix)54 b(operator)h(!)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 4386 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(Complex)f(&)
+p Fd(s)12 b Ff(\))150 4496 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(Complex)f(&)
+p Fd(s)12 b Ff(\))150 4605 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(Complex)f(&)
+p Fd(s)12 b Ff(\))150 4715 y Fg(ComplexMatrix)56 b(operator)f(/)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(Complex)f(&)
+p Fd(s)12 b Ff(\))150 4877 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(Matrix)g(&)
+p Fd(a)12 b Ff(\))150 4987 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(Matrix)g(&)
+p Fd(a)12 b Ff(\))150 5097 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(Matrix)g(&)
+p Fd(a)12 b Ff(\))150 5206 y Fg(ComplexMatrix)56 b(operator)f(/)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(Matrix)g(&)
+p Fd(a)12 b Ff(\))150 5369 y Fg(ColumnVector)56 b(operator)f(*)45
+b Ff(\()p Fe(const)32 b(Matrix)f(&)p Fd(a)p Fe(,)g(const)f(ColumnV)-8
+b(ector)32 b(&)p Fd(b)12 b Ff(\))p eop end
+%%Page: 20 24
+TeXDict begin 20 23 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(20)150 299 y Fg(ComplexColumnVector)58 b(operator)d(*)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)565
+408 y(ComplexColumnV)-8 b(ector)31 b(&)p Fd(b)12 b Ff(\))150
+561 y Fg(Matrix)54 b(operator)h(+)46 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(DiagMatrix)h(&)p
+Fd(b)12 b Ff(\))150 670 y Fg(Matrix)54 b(operator)h(-)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(DiagMatrix)h
+(&)p Fd(b)12 b Ff(\))150 780 y Fg(Matrix)54 b(operator)h(*)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(DiagMatrix)h
+(&)p Fd(b)12 b Ff(\))150 932 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g
+(ComplexDiagMatrix)i(&)p Fd(b)12 b Ff(\))150 1042 y Fg(ComplexMatrix)56
+b(operator)f(-)46 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(const)g(ComplexDiagMatrix)i(&)p Fd(b)12
+b Ff(\))150 1152 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g
+(ComplexDiagMatrix)i(&)p Fd(b)12 b Ff(\))150 1304 y Fg(Matrix)54
+b(operator)h(*)46 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(const)g(Matrix)g(&)p Fd(b)12 b Ff(\))150
+1414 y Fg(ComplexMatrix)56 b(operator)f(*)46 b Ff(\()p
+Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(ComplexMatrix)g(&)p
+Fd(b)12 b Ff(\))150 1566 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g
+(ComplexMatrix)g(&)p Fd(b)12 b Ff(\))150 1676 y Fg(ComplexMatrix)56
+b(operator)f(-)46 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(const)g(ComplexMatrix)g(&)p Fd(b)12 b Ff(\))150
+1828 y Fg(ComplexMatrix)56 b(product)48 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(a)p Fe(,)g(const)g(ComplexMatrix)g(&)p
+Fd(b)12 b Ff(\))150 1937 y Fg(ComplexMatrix)56 b(quotient)48
+b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(a)p Fe(,)e(const)h
+(ComplexMatrix)g(&)p Fd(b)12 b Ff(\))150 2090 y Fg(Matrix)54
+b(map)46 b Ff(\()p Fe(d)p 810 2090 28 4 v 40 w(d)p 901
+2090 V 40 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(Matrix)h(&)p
+Fd(a)12 b Ff(\))150 2199 y Fg(void)54 b(map)46 b Ff(\()p
+Fe(d)p 706 2199 V 40 w(d)p 797 2199 V 39 w(Mapp)s(er)30
+b Fd(f)12 b Ff(\))150 2352 y Fg(Matrix)54 b(all)46 b
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2461 y Fg(Matrix)54
+b(any)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+2614 y Fg(Matrix)54 b(cumprod)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 2723 y Fg(Matrix)54 b(cumsum)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2833 y
+Fg(Matrix)54 b(prod)47 b Ff(\()p Fe(v)m(oid)p Ff(\))31
+b Fe(const)150 2943 y Fg(Matrix)54 b(sum)46 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 3052 y Fg(Matrix)54
+b(sumsq)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+3205 y Fg(ColumnVector)56 b(diag)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 3314 y Fg(ColumnVector)56 b(diag)47
+b Ff(\()p Fe(in)m(t)31 b Fd(k)12 b Ff(\))30 b Fe(const)150
+3466 y Fg(ColumnVector)56 b(row_min)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 3576 y Fg(ColumnVector)56 b(row_min_loc)49
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 3728 y
+Fg(ColumnVector)56 b(row_max)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 3838 y Fg(ColumnVector)56 b(row_max_loc)49
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 3990 y
+Fg(RowVector)55 b(column_min)49 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 4100 y Fg(RowVector)55 b(column_min_loc)50
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 4252 y
+Fg(RowVector)55 b(column_max)49 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 4362 y Fg(RowVector)55 b(column_max_loc)50
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 4514 y
+Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(Matrix)g(&)p Fd(a)12 b Ff(\))150
+4624 y Fg(istream&)55 b(operator)f(>>)47 b Ff(\()p Fe(istream)31
+b(&)p Fd(is)p Fe(,)g(Matrix)g(&)p Fd(a)12 b Ff(\))150
+4776 y Fg(ColumnVector)49 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+4886 y Fg(ColumnVector)g Ff(\()p Fe(in)m(t)31 b Fd(n)12
+b Ff(\))150 4996 y Fg(ColumnVector)49 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(double)f Fd(val)12 b Ff(\))150 5105 y
+Fg(ColumnVector)49 b Ff(\()p Fe(const)31 b(Arra)m(y)p
+Fg(<)p Fe(double)p Fg(>)g Fe(&)p Fd(a)12 b Ff(\))150
+5215 y Fg(ColumnVector)49 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 5367 y Fg(ColumnVector&)56
+b(operator)f(=)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))p eop end
+%%Page: 21 25
+TeXDict begin 21 24 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(21)150 299 y Fg(int)53 b(operator)i(==)46 b Ff(\()p
+Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 408 y Fg(int)53 b(operator)i(!=)46 b Ff(\()p
+Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 560 y Fg(ColumnVector&)56 b(insert)48
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(a)p
+Fe(,)g(in)m(t)f Fd(r)12 b Ff(\))150 711 y Fg(ColumnVector&)56
+b(fill)47 b Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150
+821 y Fg(ColumnVector&)56 b(fill)47 b Ff(\()p Fe(double)30
+b Fd(val)p Fe(,)i(in)m(t)f(r1,)f(in)m(t)h(r2)p Ff(\))150
+972 y Fg(ColumnVector)56 b(stack)47 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b(&)p Fd(a)12 b Ff(\))31 b Fe(const)150
+1124 y Fg(RowVector)55 b(transpose)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 1275 y Fg(ColumnVector)56 b(extract)48
+b Ff(\()p Fe(in)m(t)31 b(r1,)f(in)m(t)h(r2)p Ff(\))g
+Fe(const)150 1426 y Fg(ColumnVector&)56 b(operator)f(+=)46
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 1536 y Fg(ColumnVector&)56 b(operator)f(-=)46
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 1687 y Fg(ComplexColumnVector)58 b(operator)d(+)46
+b Ff(\()p Fe(const)30 b(ColumnV)-8 b(ector)29 b(&)p Fd(a)p
+Fe(,)h(const)g(Complex)f(&)p Fd(s)12 b Ff(\))150 1797
+y Fg(ComplexColumnVector)58 b(operator)d(-)46 b Ff(\()p
+Fe(const)30 b(ColumnV)-8 b(ector)29 b(&)p Fd(a)p Fe(,)h(const)g
+(Complex)f(&)p Fd(s)12 b Ff(\))150 1907 y Fg(ComplexColumnVector)58
+b(operator)d(*)46 b Ff(\()p Fe(const)30 b(ColumnV)-8
+b(ector)29 b(&)p Fd(a)p Fe(,)h(const)g(Complex)f(&)p
+Fd(s)12 b Ff(\))150 2016 y Fg(ComplexColumnVector)58
+b(operator)d(/)46 b Ff(\()p Fe(const)30 b(ColumnV)-8
+b(ector)29 b(&)p Fd(a)p Fe(,)h(const)g(Complex)f(&)p
+Fd(s)12 b Ff(\))150 2168 y Fg(ComplexColumnVector)58
+b(operator)d(+)46 b Ff(\()p Fe(const)30 b(Complex)f(&)p
+Fd(s)p Fe(,)g(const)h(ColumnV)-8 b(ector)30 b(&)p Fd(a)12
+b Ff(\))150 2277 y Fg(ComplexColumnVector)58 b(operator)d(-)46
+b Ff(\()p Fe(const)30 b(Complex)f(&)p Fd(s)p Fe(,)g(const)h(ColumnV)-8
+b(ector)30 b(&)p Fd(a)12 b Ff(\))150 2387 y Fg(ComplexColumnVector)58
+b(operator)d(*)46 b Ff(\()p Fe(const)30 b(Complex)f(&)p
+Fd(s)p Fe(,)g(const)h(ColumnV)-8 b(ector)30 b(&)p Fd(a)12
+b Ff(\))150 2496 y Fg(ComplexColumnVector)58 b(operator)d(/)46
+b Ff(\()p Fe(const)30 b(Complex)f(&)p Fd(s)p Fe(,)g(const)h(ColumnV)-8
+b(ector)30 b(&)p Fd(a)12 b Ff(\))150 2648 y Fg(Matrix)54
+b(operator)h(*)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)g(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))150 2799 y Fg(ComplexMatrix)56
+b(operator)f(*)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)g(ComplexRo)m(wV)-8
+b(ector)565 2909 y(&)p Fd(b)12 b Ff(\))150 3060 y Fg
+(ComplexColumnVector)58 b(operator)d(+)46 b Ff(\()p Fe(const)31
+b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565
+3170 y(ComplexColumnV)-8 b(ector)31 b(&)p Fd(b)12 b Ff(\))150
+3321 y Fg(ComplexColumnVector)58 b(operator)d(-)46 b
+Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)31 b(&)p
+Fd(a)p Fe(,)g(const)565 3431 y(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))150 3582 y Fg(ComplexColumnVector)58
+b(product)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565 3692 y(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 3843 y Fg(ComplexColumnVector)58
+b(quotient)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565 3953 y(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 4104 y Fg(ColumnVector)56
+b(map)46 b Ff(\()p Fe(d)p 1124 4104 28 4 v 40 w(d)p 1215
+4104 V 40 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(ColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 4214 y Fg(void)54
+b(map)46 b Ff(\()p Fe(d)p 706 4214 V 40 w(d)p 797 4214
+V 39 w(Mapp)s(er)30 b Fd(f)12 b Ff(\))150 4365 y Fg(double)54
+b(min)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+4475 y Fg(double)54 b(max)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 4626 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 4777 y Fg(RowVector)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 4887 y Fg(RowVector)g
+Ff(\()p Fe(in)m(t)31 b Fd(n)12 b Ff(\))150 4996 y Fg(RowVector)48
+b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(double)f Fd(val)12
+b Ff(\))150 5106 y Fg(RowVector)48 b Ff(\()p Fe(const)31
+b(Arra)m(y)p Fg(<)p Fe(double)p Fg(>)g Fe(&)p Fd(a)12
+b Ff(\))150 5216 y Fg(RowVector)48 b Ff(\()p Fe(const)31
+b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12 b Ff(\))150 5367
+y Fg(RowVector&)55 b(operator)g(=)46 b Ff(\()p Fe(const)31
+b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12 b Ff(\))p eop end
+%%Page: 22 26
+TeXDict begin 22 25 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(22)150 299 y Fg(int)53 b(operator)i(==)46 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 408 y Fg(int)53 b(operator)i(!=)46 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 568 y Fg(RowVector&)55 b(insert)48 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p Fe(,)f(in)m(t)g
+Fd(c)12 b Ff(\))150 728 y Fg(RowVector&)55 b(fill)47
+b Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150 838 y
+Fg(RowVector&)55 b(fill)47 b Ff(\()p Fe(double)30 b Fd(val)p
+Fe(,)i(in)m(t)f(c1,)g(in)m(t)g(c2)p Ff(\))150 997 y Fg(RowVector)55
+b(append)47 b Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 1157 y Fg(ColumnVector)56
+b(transpose)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+1317 y Fg(RowVector)55 b(extract)48 b Ff(\()p Fe(in)m(t)31
+b(c1,)g(in)m(t)g(c2)p Ff(\))h Fe(const)150 1477 y Fg(RowVector&)55
+b(operator)g(+=)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 1587 y Fg(RowVector&)55
+b(operator)g(-=)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 1746 y Fg(ComplexRowVector)57
+b(operator)e(+)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(Complex)f(&)p
+Fd(s)12 b Ff(\))150 1856 y Fg(ComplexRowVector)57 b(operator)e(-)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p
+Fe(,)d(const)h(Complex)f(&)p Fd(s)12 b Ff(\))150 1966
+y Fg(ComplexRowVector)57 b(operator)e(*)46 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h
+(Complex)f(&)p Fd(s)12 b Ff(\))150 2075 y Fg(ComplexRowVector)57
+b(operator)e(/)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(Complex)f(&)p
+Fd(s)12 b Ff(\))150 2235 y Fg(ComplexRowVector)57 b(operator)e(+)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(Ro)m(wV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 2344 y Fg(ComplexRowVector)57
+b(operator)e(-)46 b Ff(\()p Fe(const)31 b(Complex)f(&)p
+Fd(s)p Fe(,)h(const)g(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 2454 y Fg(ComplexRowVector)57 b(operator)e(*)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(Ro)m(wV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 2564 y Fg(ComplexRowVector)57
+b(operator)e(/)46 b Ff(\()p Fe(const)31 b(Complex)f(&)p
+Fd(s)p Fe(,)h(const)g(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 2723 y Fg(double)54 b(operator)h(*)46 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)p Fe(,)f(ColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 2883 y Fg(Complex)54
+b(operator)h(*)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(b)12 b Ff(\))150 3043 y Fg(RowVector)55
+b(operator)g(*)46 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8
+b(ector)32 b(&)p Fd(a)p Fe(,)f(const)g(Matrix)g(&)p Fd(b)12
+b Ff(\))150 3203 y Fg(ComplexRowVector)57 b(operator)e(*)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p
+Fe(,)d(const)h(ComplexMatrix)g(&)p Fd(b)12 b Ff(\))150
+3363 y Fg(ComplexRowVector)57 b(operator)e(+)46 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h
+(ComplexRo)m(wV)-8 b(ector)565 3472 y(&)p Fd(b)12 b Ff(\))150
+3582 y Fg(ComplexRowVector)57 b(operator)e(-)46 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h
+(ComplexRo)m(wV)-8 b(ector)565 3691 y(&)p Fd(b)12 b Ff(\))150
+3851 y Fg(ComplexRowVector)57 b(product)48 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h
+(ComplexRo)m(wV)-8 b(ector)33 b(&)p Fd(b)12 b Ff(\))150
+3961 y Fg(ComplexRowVector)57 b(quotient)48 b Ff(\()p
+Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h
+(ComplexRo)m(wV)-8 b(ector)565 4070 y(&)p Fd(b)12 b Ff(\))150
+4230 y Fg(RowVector)55 b(map)46 b Ff(\()p Fe(d)p 967
+4230 28 4 v 40 w(d)p 1058 4230 V 40 w(Mapp)s(er)29 b
+Fd(f)p Fe(,)i(const)g(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))150 4340 y Fg(void)54 b(map)46 b Ff(\()p Fe(d)p
+706 4340 V 40 w(d)p 797 4340 V 39 w(Mapp)s(er)30 b Fd(f)12
+b Ff(\))150 4500 y Fg(double)54 b(min)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 4609 y Fg(double)54 b(max)46
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 4769 y
+Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(Ro)m(wV)-8 b(ector)32 b(&)p
+Fd(a)12 b Ff(\))150 4929 y Fg(DiagMatrix)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 5038 y Fg(DiagMatrix)g Ff(\()p
+Fe(in)m(t)32 b Fd(n)12 b Ff(\))150 5148 y Fg(DiagMatrix)48
+b Ff(\()p Fe(in)m(t)32 b Fd(n)p Fe(,)f(double)f Fd(val)12
+b Ff(\))150 5258 y Fg(DiagMatrix)48 b Ff(\()p Fe(in)m(t)32
+b Fd(r)p Fe(,)f(in)m(t)f Fd(c)12 b Ff(\))150 5367 y Fg(DiagMatrix)48
+b Ff(\()p Fe(in)m(t)32 b Fd(r)p Fe(,)f(in)m(t)f Fd(c)p
+Fe(,)h(double)f Fd(val)12 b Ff(\))p eop end
+%%Page: 23 27
+TeXDict begin 23 26 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(23)150 299 y Fg(DiagMatrix)48 b Ff(\()p Fe(const)32
+b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))150 408
+y Fg(DiagMatrix)48 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 518 y Fg(DiagMatrix)48
+b Ff(\()p Fe(const)32 b(DiagArra)m(y)p Fg(<)p Fe(double)p
+Fg(>)g Fe(&)p Fd(a)12 b Ff(\))150 628 y Fg(DiagMatrix)48
+b Ff(\()p Fe(const)32 b(DiagMatrix)h(&)p Fd(a)12 b Ff(\))150
+787 y Fg(DiagMatrix&)56 b(operator)e(=)46 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))150 947 y Fg(int)53
+b(operator)i(==)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))30 b Fe(const)150 1057 y Fg(int)53 b(operator)i(!=)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 1217 y Fg(DiagMatrix&)56 b(fill)46 b Ff(\()p
+Fe(double)31 b Fd(val)12 b Ff(\))150 1326 y Fg(DiagMatrix&)56
+b(fill)46 b Ff(\()p Fe(double)31 b Fd(val)p Fe(,)g(in)m(t)g
+Fd(beg)p Fe(,)g(in)m(t)g Fd(end)12 b Ff(\))150 1436 y
+Fg(DiagMatrix&)56 b(fill)46 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 1545 y Fg(DiagMatrix&)56
+b(fill)46 b Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))150 1655 y Fg(DiagMatrix&)56 b(fill)46
+b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(a)p
+Fe(,)f(in)m(t)h Fd(beg)12 b Ff(\))150 1765 y Fg(DiagMatrix&)56
+b(fill)46 b Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)p Fe(,)f(in)m(t)g Fd(beg)12 b Ff(\))150 1924
+y Fg(DiagMatrix)55 b(transpose)49 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 2084 y Fg(Matrix)54 b(extract)48
+b Ff(\()p Fe(in)m(t)31 b(r1,)g(in)m(t)f(c1,)i(in)m(t)f(r2,)f(in)m(t)h
+(c2)p Ff(\))h Fe(const)150 2244 y Fg(RowVector)55 b(row)46
+b Ff(\()p Fe(in)m(t)32 b Fd(i)12 b Ff(\))30 b Fe(const)150
+2354 y Fg(RowVector)55 b(row)46 b Ff(\()p Fe(c)m(har)31
+b(*s)p Ff(\))g Fe(const)150 2513 y Fg(ColumnVector)56
+b(column)47 b Ff(\()p Fe(in)m(t)31 b Fd(i)12 b Ff(\))31
+b Fe(const)150 2623 y Fg(ColumnVector)56 b(column)47
+b Ff(\()p Fe(c)m(har)31 b(*s)p Ff(\))g Fe(const)150 2783
+y Fg(DiagMatrix)55 b(inverse)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 2892 y Fg(DiagMatrix)55 b(inverse)48
+b Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)12 b Ff(\))31 b
+Fe(const)150 3052 y Fg(DiagMatrix&)56 b(operator)e(+=)46
+b Ff(\()p Fe(const)32 b(DiagMatrix)h(&)p Fd(a)12 b Ff(\))150
+3162 y Fg(DiagMatrix&)56 b(operator)e(-=)46 b Ff(\()p
+Fe(const)32 b(DiagMatrix)h(&)p Fd(a)12 b Ff(\))150 3322
+y Fg(Matrix)54 b(operator)h(+)46 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(double)g Fd(s)12 b Ff(\))150
+3431 y Fg(Matrix)54 b(operator)h(-)46 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(double)g Fd(s)12 b Ff(\))150
+3591 y Fg(ComplexMatrix)56 b(operator)f(+)46 b Ff(\()p
+Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Complex)g(&)p
+Fd(s)12 b Ff(\))150 3701 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Complex)
+g(&)p Fd(s)12 b Ff(\))150 3860 y Fg(ComplexDiagMatrix)57
+b(operator)e(*)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)p Fe(,)e(const)g(Complex)f(&)p Fd(s)12 b Ff(\))150
+3970 y Fg(ComplexDiagMatrix)57 b(operator)e(/)46 b Ff(\()p
+Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)g(Complex)f(&)p
+Fd(s)12 b Ff(\))150 4130 y Fg(Matrix)54 b(operator)h(+)46
+b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))150 4239 y Fg(Matrix)54 b(operator)h(-)46
+b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))150 4399 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(DiagMatrix)
+i(&)p Fd(a)12 b Ff(\))150 4509 y Fg(ComplexMatrix)56
+b(operator)f(-)46 b Ff(\()p Fe(const)31 b(Complex)f(&)p
+Fd(s)p Fe(,)h(const)g(DiagMatrix)i(&)p Fd(a)12 b Ff(\))150
+4669 y Fg(ComplexDiagMatrix)57 b(operator)e(*)46 b Ff(\()p
+Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))150 4828 y Fg(ColumnVector)56 b(operator)f(*)45
+b Ff(\()p Fe(const)32 b(DiagMatrix)h(&)p Fd(a)p Fe(,)d(const)h(ColumnV)
+-8 b(ector)31 b(&)p Fd(b)12 b Ff(\))150 4988 y Fg(ComplexColumnVector)
+58 b(operator)d(*)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)p Fe(,)d(const)565 5098 y(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))150 5258 y Fg(ComplexDiagMatrix)57
+b(operator)e(+)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)p Fe(,)e(const)565 5367 y(ComplexDiagMatrix)i(&)p
+Fd(b)12 b Ff(\))p eop end
+%%Page: 24 28
+TeXDict begin 24 27 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(24)150 299 y Fg(ComplexDiagMatrix)57 b(operator)e(-)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)565
+408 y(ComplexDiagMatrix)i(&)p Fd(b)12 b Ff(\))150 562
+y Fg(ComplexDiagMatrix)57 b(product)48 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(const)g(ComplexDiagMatrix)565
+672 y(&)p Fd(b)12 b Ff(\))150 826 y Fg(Matrix)54 b(operator)h(+)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Matrix)g
+(&)p Fd(b)12 b Ff(\))150 935 y Fg(Matrix)54 b(operator)h(-)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Matrix)g
+(&)p Fd(b)12 b Ff(\))150 1045 y Fg(Matrix)54 b(operator)h(*)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Matrix)g
+(&)p Fd(b)12 b Ff(\))150 1199 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h
+(ComplexMatrix)h(&)p Fd(b)12 b Ff(\))150 1308 y Fg(ComplexMatrix)56
+b(operator)f(-)46 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)p Fe(,)d(const)h(ComplexMatrix)h(&)p Fd(b)12 b Ff(\))150
+1418 y Fg(ComplexMatrix)56 b(operator)f(*)46 b Ff(\()p
+Fe(const)31 b(DiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(ComplexMatrix)h(&)
+p Fd(b)12 b Ff(\))150 1572 y Fg(ColumnVector)56 b(diag)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 1681 y
+Fg(ColumnVector)56 b(diag)47 b Ff(\()p Fe(in)m(t)31 b
+Fd(k)12 b Ff(\))30 b Fe(const)150 1835 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(DiagMatrix)i(&)p Fd(a)12 b Ff(\))150 1989
+y Fg(ComplexMatrix)49 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+2099 y Fg(ComplexMatrix)g Ff(\()p Fe(in)m(t)32 b Fd(r)p
+Fe(,)e(in)m(t)h Fd(c)12 b Ff(\))150 2208 y Fg(ComplexMatrix)49
+b Ff(\()p Fe(in)m(t)32 b Fd(r)p Fe(,)e(in)m(t)h Fd(c)p
+Fe(,)g(const)g(Complex)f(&)p Fd(val)12 b Ff(\))150 2318
+y Fg(ComplexMatrix)49 b Ff(\()p Fe(const)32 b(Matrix)f(&)p
+Fd(a)12 b Ff(\))150 2427 y Fg(ComplexMatrix)49 b Ff(\()p
+Fe(const)32 b(Arra)m(y2)p Fg(<)p Fe(Complex)p Fg(>)f
+Fe(&)p Fd(a)12 b Ff(\))150 2537 y Fg(ComplexMatrix)49
+b Ff(\()p Fe(const)32 b(ComplexMatrix)f(&)p Fd(a)12 b
+Ff(\))150 2646 y Fg(ComplexMatrix)49 b Ff(\()p Fe(const)32
+b(DiagMatrix)h(&)p Fd(a)12 b Ff(\))150 2756 y Fg(ComplexMatrix)49
+b Ff(\()p Fe(const)32 b(DiagArra)m(y)p Fg(<)p Fe(Complex)p
+Fg(>)g Fe(&)p Fd(a)12 b Ff(\))150 2866 y Fg(ComplexMatrix)49
+b Ff(\()p Fe(const)32 b(ComplexDiagMatrix)h(&)p Fd(a)12
+b Ff(\))150 3019 y Fg(ComplexMatrix&)57 b(operator)d(=)46
+b Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p Fd(a)12 b
+Ff(\))150 3173 y Fg(int)53 b(operator)i(==)46 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)h(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 3283 y Fg(int)53 b(operator)i(!=)46 b
+Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 3437 y Fg(ComplexMatrix&)57 b(insert)47
+b Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)p Fe(,)g(in)m(t)g
+Fd(r)p Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))150 3546 y Fg(ComplexMatrix&)57
+b(insert)47 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33
+b(&)p Fd(a)p Fe(,)d(in)m(t)h Fd(r)p Fe(,)g(in)m(t)g Fd(c)12
+b Ff(\))150 3656 y Fg(ComplexMatrix&)57 b(insert)47 b
+Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(a)p
+Fe(,)g(in)m(t)g Fd(r)p Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))150
+3765 y Fg(ComplexMatrix&)57 b(insert)47 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)p Fe(,)e(in)m(t)f Fd(r)p Fe(,)h(in)m(t)g
+Fd(c)12 b Ff(\))150 3919 y Fg(ComplexMatrix&)57 b(insert)47
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(in)m(t)g
+Fd(r)p Fe(,)g(in)m(t)g Fd(c)12 b Ff(\))150 4029 y Fg(ComplexMatrix&)57
+b(insert)47 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(in)m(t)h Fd(r)p Fe(,)g(in)m(t)g
+Fd(c)12 b Ff(\))150 4138 y Fg(ComplexMatrix&)57 b(insert)47
+b Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(a)p Fe(,)g(in)m(t)g Fd(r)p Fe(,)g(in)m(t)g Fd(c)12
+b Ff(\))150 4248 y Fg(ComplexMatrix&)57 b(insert)47 b
+Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)e(in)m(t)f Fd(r)p Fe(,)h(in)m(t)g Fd(c)12 b Ff(\))150
+4402 y Fg(ComplexMatrix&)57 b(fill)46 b Ff(\()p Fe(double)31
+b Fd(val)12 b Ff(\))150 4511 y Fg(ComplexMatrix&)57 b(fill)46
+b Ff(\()p Fe(const)31 b(Complex)g(&)p Fd(val)12 b Ff(\))150
+4621 y Fg(ComplexMatrix&)57 b(fill)46 b Ff(\()p Fe(double)31
+b Fd(val)p Fe(,)g(in)m(t)g(r1,)f(in)m(t)h(c1,)h(in)m(t)f(r2,)f(in)m(t)h
+(c2)p Ff(\))150 4731 y Fg(ComplexMatrix&)57 b(fill)46
+b Ff(\()p Fe(const)31 b(Complex)g(&)p Fd(val)p Fe(,)g(in)m(t)g(r1,)f
+(in)m(t)h(c1,)h(in)m(t)f(r2,)f(in)m(t)h(c2)p Ff(\))150
+4884 y Fg(ComplexMatrix)56 b(append)48 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 4994
+y Fg(ComplexMatrix)56 b(append)48 b Ff(\()p Fe(const)31
+b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))31 b Fe(const)150
+5104 y Fg(ComplexMatrix)56 b(append)48 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+5213 y Fg(ComplexMatrix)56 b(append)48 b Ff(\()p Fe(const)31
+b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+5367 y Fg(ComplexMatrix)56 b(append)48 b Ff(\()p Fe(const)31
+b(ComplexMatrix)g(&)p Fd(a)12 b Ff(\))30 b Fe(const)p
+eop end
+%%Page: 25 29
+TeXDict begin 25 28 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(25)150 299 y Fg(ComplexMatrix)56 b(append)48 b Ff(\()p
+Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))31 b Fe(const)150 408 y Fg(ComplexMatrix)56 b(append)48
+b Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 518 y Fg(ComplexMatrix)56
+b(append)48 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)12 b Ff(\))30 b Fe(const)150 677 y Fg(ComplexMatrix)56
+b(stack)47 b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(a)12
+b Ff(\))30 b Fe(const)150 786 y Fg(ComplexMatrix)56 b(stack)47
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))30 b Fe(const)150 896 y Fg(ComplexMatrix)56 b(stack)47
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))30 b Fe(const)150 1005 y Fg(ComplexMatrix)56
+b(stack)47 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)12
+b Ff(\))31 b Fe(const)150 1164 y Fg(ComplexMatrix)56
+b(stack)47 b Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p
+Fd(a)12 b Ff(\))30 b Fe(const)150 1273 y Fg(ComplexMatrix)56
+b(stack)47 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 1383
+y Fg(ComplexMatrix)56 b(stack)47 b Ff(\()p Fe(const)31
+b(ComplexColumnV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 1493 y Fg(ComplexMatrix)56 b(stack)47
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)12
+b Ff(\))31 b Fe(const)150 1651 y Fg(ComplexMatrix)56
+b(transpose)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+1810 y Fg(Matrix)54 b(real)47 b Ff(\()p Fe(const)31 b(ComplexMatrix)g
+(&)p Fd(a)12 b Ff(\))150 1919 y Fg(Matrix)54 b(imag)47
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)12 b
+Ff(\))150 2029 y Fg(ComplexMatrix)56 b(conj)47 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)12 b Ff(\))150
+2187 y Fg(ComplexMatrix)56 b(extract)48 b Ff(\()p Fe(in)m(t)31
+b(r1,)g(in)m(t)g(c1,)g(in)m(t)g(r2,)f(in)m(t)h(c2)p Ff(\))h
+Fe(const)150 2346 y Fg(ComplexRowVector)57 b(row)47 b
+Ff(\()p Fe(in)m(t)31 b Fd(i)12 b Ff(\))30 b Fe(const)150
+2455 y Fg(ComplexRowVector)57 b(row)47 b Ff(\()p Fe(c)m(har)31
+b(*s)p Ff(\))g Fe(const)150 2614 y Fg(ComplexColumnVector)58
+b(column)47 b Ff(\()p Fe(in)m(t)32 b Fd(i)12 b Ff(\))30
+b Fe(const)150 2723 y Fg(ComplexColumnVector)58 b(column)47
+b Ff(\()p Fe(c)m(har)31 b(*s)p Ff(\))g Fe(const)150 2882
+y Fg(ComplexMatrix)56 b(inverse)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 2991 y Fg(ComplexMatrix)56 b(inverse)48
+b Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)12 b Ff(\))31 b
+Fe(const)150 3101 y Fg(ComplexMatrix)56 b(inverse)48
+b Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)p Fe(,)h(double)d(&)p
+Fd(rcond)12 b Ff(\))32 b Fe(const)150 3260 y Fg(ComplexMatrix)56
+b(fourier)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+3369 y Fg(ComplexMatrix)56 b(ifourier)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 3528 y Fg(ComplexDET)55 b(determinant)49
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 3637 y
+Fg(ComplexDET)55 b(determinant)49 b Ff(\()p Fe(in)m(t)31
+b(&)p Fd(info)12 b Ff(\))31 b Fe(const)150 3747 y Fg(ComplexDET)55
+b(determinant)49 b Ff(\()p Fe(in)m(t)31 b(&)p Fd(info)p
+Fe(,)h(double)e(&)p Fd(rcond)12 b Ff(\))31 b Fe(const)150
+3905 y Fg(ComplexMatrix)56 b(solve)47 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(b)12 b Ff(\))30 b Fe(const)150 4015
+y Fg(ComplexMatrix)56 b(solve)47 b Ff(\()p Fe(const)31
+b(Matrix)h(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)12
+b Ff(\))31 b Fe(const)150 4124 y Fg(ComplexMatrix)56
+b(solve)47 b Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(b)p
+Fe(,)e(in)m(t)h(&)p Fd(info)p Fe(,)h(double)e(&)p Fd(rcond)12
+b Ff(\))31 b Fe(const)150 4283 y Fg(ComplexMatrix)56
+b(solve)47 b Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p
+Fd(b)12 b Ff(\))30 b Fe(const)150 4393 y Fg(ComplexMatrix)56
+b(solve)47 b Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p
+Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)12 b Ff(\))31 b Fe(const)150
+4502 y Fg(ComplexMatrix)56 b(solve)47 b Ff(\()p Fe(const)31
+b(ComplexMatrix)h(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)p
+Fe(,)h(double)e(&)p Fd(rcond)12 b Ff(\))565 4612 y Fe(const)150
+4770 y Fg(ComplexColumnVector)58 b(solve)47 b Ff(\()p
+Fe(const)31 b(ComplexColumnV)-8 b(ector)32 b(&)p Fd(b)12
+b Ff(\))30 b Fe(const)150 4880 y Fg(ComplexColumnVector)58
+b(solve)47 b Ff(\()p Fe(const)29 b(ComplexColumnV)-8
+b(ector)29 b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p Fd(info)12
+b Ff(\))29 b Fe(const)150 4989 y Fg(ComplexColumnVector)58
+b(solve)47 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(b)p Fe(,)e(in)m(t)h(&)p Fd(info)p
+Fe(,)565 5099 y(double)f(&)p Fd(rcond)12 b Ff(\))31 b
+Fe(const)150 5257 y Fg(ComplexMatrix)56 b(lssolve)48
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(b)12 b
+Ff(\))31 b Fe(const)150 5367 y Fg(ComplexMatrix)56 b(lssolve)48
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)12 b Ff(\))31 b Fe(const)p eop end
+%%Page: 26 30
+TeXDict begin 26 29 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(26)150 299 y Fg(ComplexMatrix)56 b(lssolve)48 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p
+Fd(info)p Fe(,)g(in)m(t)g(&)p Fd(rank)12 b Ff(\))31 b
+Fe(const)150 447 y Fg(ComplexColumnVector)58 b(lssolve)48
+b Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))30 b Fe(const)150 556 y Fg(ComplexColumnVector)58
+b(lssolve)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p Fd(info)12
+b Ff(\))565 666 y Fe(const)150 776 y Fg(ComplexColumnVector)58
+b(lssolve)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(b)p Fe(,)g(in)m(t)g(&)p Fd(info)p
+Fe(,)g(in)m(t)565 885 y(&)p Fd(rank)12 b Ff(\))31 b Fe(const)150
+1033 y Fg(ComplexMatrix&)57 b(operator)d(+=)46 b Ff(\()p
+Fe(const)32 b(DiagMatrix)g(&)p Fd(a)12 b Ff(\))150 1143
+y Fg(ComplexMatrix&)57 b(operator)d(-=)46 b Ff(\()p Fe(const)32
+b(DiagMatrix)g(&)p Fd(a)12 b Ff(\))150 1291 y Fg(ComplexMatrix&)57
+b(operator)d(+=)46 b Ff(\()p Fe(const)32 b(ComplexDiagMatrix)g(&)p
+Fd(a)12 b Ff(\))150 1400 y Fg(ComplexMatrix&)57 b(operator)d(-=)46
+b Ff(\()p Fe(const)32 b(ComplexDiagMatrix)g(&)p Fd(a)12
+b Ff(\))150 1548 y Fg(ComplexMatrix&)57 b(operator)d(+=)46
+b Ff(\()p Fe(const)32 b(Matrix)f(&)p Fd(a)12 b Ff(\))150
+1658 y Fg(ComplexMatrix&)57 b(operator)d(-=)46 b Ff(\()p
+Fe(const)32 b(Matrix)f(&)p Fd(a)12 b Ff(\))150 1806 y
+Fg(ComplexMatrix&)57 b(operator)d(+=)46 b Ff(\()p Fe(const)32
+b(ComplexMatrix)f(&)p Fd(a)12 b Ff(\))150 1915 y Fg(ComplexMatrix&)57
+b(operator)d(-=)46 b Ff(\()p Fe(const)32 b(ComplexMatrix)f(&)p
+Fd(a)12 b Ff(\))150 2063 y Fg(Matrix)54 b(operator)h(!)46
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 2211 y
+Fg(ComplexMatrix)56 b(operator)f(+)46 b Ff(\()p Fe(const)31
+b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(double)f Fd(s)12
+b Ff(\))150 2321 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(double)f
+Fd(s)12 b Ff(\))150 2430 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(double)f
+Fd(s)12 b Ff(\))150 2540 y Fg(ComplexMatrix)56 b(operator)f(/)46
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(double)f
+Fd(s)12 b Ff(\))150 2688 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexMatrix)g(&)p
+Fd(a)12 b Ff(\))150 2797 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexMatrix)g(&)p
+Fd(a)12 b Ff(\))150 2907 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexMatrix)g(&)p
+Fd(a)12 b Ff(\))150 3017 y Fg(ComplexMatrix)56 b(operator)f(/)46
+b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexMatrix)g(&)p
+Fd(a)12 b Ff(\))150 3164 y Fg(ComplexColumnVector)58
+b(operator)d(*)46 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(const)565 3274 y(ColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))150 3422 y Fg(ComplexColumnVector)58
+b(operator)d(*)46 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(const)565 3532 y(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))150 3679 y Fg(ComplexMatrix)56
+b(operator)f(+)46 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(const)g(DiagMatrix)i(&)p Fd(b)12 b Ff(\))150
+3789 y Fg(ComplexMatrix)56 b(operator)f(-)46 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g(DiagMatrix)i(&)
+p Fd(b)12 b Ff(\))150 3899 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g
+(DiagMatrix)i(&)p Fd(b)12 b Ff(\))150 4047 y Fg(ComplexMatrix)56
+b(operator)f(+)46 b Ff(\()p Fe(const)30 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(const)g(ComplexDiagMatrix)565 4156 y(&)p
+Fd(b)12 b Ff(\))150 4266 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)30 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g
+(ComplexDiagMatrix)565 4375 y(&)p Fd(b)12 b Ff(\))150
+4485 y Fg(ComplexMatrix)56 b(operator)f(*)46 b Ff(\()p
+Fe(const)30 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g
+(ComplexDiagMatrix)565 4595 y(&)p Fd(b)12 b Ff(\))150
+4742 y Fg(ComplexMatrix)56 b(operator)f(+)46 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g(Matrix)g(&)p
+Fd(b)12 b Ff(\))150 4852 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g
+(Matrix)g(&)p Fd(b)12 b Ff(\))150 5000 y Fg(ComplexMatrix)56
+b(operator)f(*)46 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(const)g(Matrix)g(&)p Fd(b)12 b Ff(\))150
+5110 y Fg(ComplexMatrix)56 b(operator)f(*)46 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g(ComplexMatrix)
+565 5219 y(&)p Fd(b)12 b Ff(\))150 5367 y Fg(ComplexMatrix)56
+b(product)48 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(const)g(Matrix)g(&)p Fd(b)12 b Ff(\))p
+eop end
+%%Page: 27 31
+TeXDict begin 27 30 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(27)150 299 y Fg(ComplexMatrix)56 b(quotient)48 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)h(&)p Fd(a)p Fe(,)e(const)h(Matrix)g(&)p
+Fd(b)12 b Ff(\))150 451 y Fg(ComplexMatrix)56 b(map)47
+b Ff(\()p Fe(c)p 1166 451 28 4 v 40 w(c)p 1246 451 V
+41 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(ComplexMatrix)g(&)p
+Fd(a)12 b Ff(\))150 561 y Fg(Matrix)54 b(map)46 b Ff(\()p
+Fe(d)p 810 561 V 40 w(c)p 890 561 V 41 w(Mapp)s(er)29
+b Fd(f)p Fe(,)i(const)g(ComplexMatrix)g(&)p Fd(a)12 b
+Ff(\))150 670 y Fg(void)54 b(map)46 b Ff(\()p Fe(c)p
+695 670 V 41 w(c)p 776 670 V 40 w(Mapp)s(er)30 b Fd(f)12
+b Ff(\))150 823 y Fg(Matrix)54 b(all)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 932 y Fg(Matrix)54 b(any)46 b
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1085 y Fg(ComplexMatrix)56
+b(cumprod)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+1194 y Fg(ComplexMatrix)56 b(cumsum)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 1304 y Fg(ComplexMatrix)56 b(prod)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1414 y
+Fg(ComplexMatrix)56 b(sum)47 b Ff(\()p Fe(v)m(oid)p Ff(\))31
+b Fe(const)150 1523 y Fg(ComplexMatrix)56 b(sumsq)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1676 y
+Fg(ComplexColumnVector)58 b(diag)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 1785 y Fg(ComplexColumnVector)58
+b(diag)47 b Ff(\()p Fe(in)m(t)31 b Fd(k)12 b Ff(\))30
+b Fe(const)150 1937 y Fg(ComplexColumnVector)58 b(row_min)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 2047 y
+Fg(ComplexColumnVector)58 b(row_min_loc)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2199 y Fg(ComplexColumnVector)58
+b(row_max)48 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+2309 y Fg(ComplexColumnVector)58 b(row_max_loc)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2461 y Fg(ComplexRowVector)57
+b(column_min)49 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+2571 y Fg(ComplexRowVector)57 b(column_min_loc)50 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2723 y Fg(ComplexRowVector)57
+b(column_max)49 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+2833 y Fg(ComplexRowVector)57 b(column_max_loc)50 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2985 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(ComplexMatrix)g(&)p Fd(a)12 b Ff(\))150
+3095 y Fg(istream&)55 b(operator)f(>>)47 b Ff(\()p Fe(istream)31
+b(&)p Fd(is)p Fe(,)g(ComplexMatrix)g(&)p Fd(a)12 b Ff(\))150
+3247 y Fg(ComplexColumnVector)51 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 3357 y Fg(ComplexColumnVector)g Ff(\()p Fe(in)m(t)31
+b Fd(n)12 b Ff(\))150 3466 y Fg(ComplexColumnVector)51
+b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(const)g(Complex)g(&)p
+Fd(val)12 b Ff(\))150 3576 y Fg(ComplexColumnVector)51
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 3686 y Fg(ComplexColumnVector)51 b Ff(\()p
+Fe(const)31 b(Arra)m(y)p Fg(<)p Fe(Complex)p Fg(>)h Fe(&)p
+Fd(a)12 b Ff(\))150 3795 y Fg(ComplexColumnVector)51
+b Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))150 3948 y Fg(ComplexColumnVector&)58
+b(operator)d(=)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 4100 y Fg(int)53
+b(operator)i(==)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 4210
+y Fg(int)53 b(operator)i(!=)46 b Ff(\()p Fe(const)31
+b(ComplexColumnV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))30
+b Fe(const)150 4362 y Fg(ComplexColumnVector&)58 b(insert)48
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(a)p
+Fe(,)g(in)m(t)g Fd(r)12 b Ff(\))150 4472 y Fg(ComplexColumnVector&)58
+b(insert)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(in)m(t)g Fd(r)12 b Ff(\))150
+4624 y Fg(ComplexColumnVector&)58 b(fill)47 b Ff(\()p
+Fe(double)30 b Fd(val)12 b Ff(\))150 4734 y Fg(ComplexColumnVector&)58
+b(fill)47 b Ff(\()p Fe(const)31 b(Complex)g(&)p Fd(val)12
+b Ff(\))150 4843 y Fg(ComplexColumnVector&)58 b(fill)47
+b Ff(\()p Fe(double)30 b Fd(val)p Fe(,)i(in)m(t)f(r1,)f(in)m(t)h(r2)p
+Ff(\))150 4953 y Fg(ComplexColumnVector&)58 b(fill)47
+b Ff(\()p Fe(const)31 b(Complex)g(&)p Fd(val)p Fe(,)g(in)m(t)g(r1,)f
+(in)m(t)h(r2)p Ff(\))150 5105 y Fg(ComplexColumnVector)58
+b(stack)47 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 5215 y Fg(ComplexColumnVector)
+58 b(stack)47 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 5367
+y Fg(ComplexRowVector)57 b(transpose)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)p eop end
+%%Page: 28 32
+TeXDict begin 28 31 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(28)150 299 y Fg(ColumnVector)56 b(real)47 b Ff(\()p
+Fe(const)31 b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)12
+b Ff(\))150 408 y Fg(ColumnVector)56 b(imag)47 b Ff(\()p
+Fe(const)31 b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)12
+b Ff(\))150 518 y Fg(ComplexColumnVector)58 b(conj)47
+b Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(a)12 b Ff(\))150 666 y Fg(ComplexColumnVector)58
+b(extract)48 b Ff(\()p Fe(in)m(t)31 b(r1,)g(in)m(t)f(r2)p
+Ff(\))h Fe(const)150 814 y Fg(ComplexColumnVector&)58
+b(operator)d(+=)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 923 y Fg(ComplexColumnVector&)58
+b(operator)d(-=)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 1071 y Fg(ComplexColumnVector&)58
+b(operator)d(+=)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 1181 y Fg(ComplexColumnVector&)58
+b(operator)d(-=)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 1329 y Fg(ComplexColumnVector)58
+b(operator)d(+)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(double)f Fd(s)12 b Ff(\))150
+1439 y Fg(ComplexColumnVector)58 b(operator)d(-)46 b
+Ff(\()p Fe(const)31 b(ComplexColumnV)-8 b(ector)31 b(&)p
+Fd(a)p Fe(,)g(double)f Fd(s)12 b Ff(\))150 1548 y Fg
+(ComplexColumnVector)58 b(operator)d(*)46 b Ff(\()p Fe(const)31
+b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)p Fe(,)g(double)f
+Fd(s)12 b Ff(\))150 1658 y Fg(ComplexColumnVector)58
+b(operator)d(/)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(double)f Fd(s)12 b Ff(\))150
+1806 y Fg(ComplexColumnVector)58 b(operator)d(+)46 b
+Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 1915 y Fg(ComplexColumnVector)58
+b(operator)d(-)46 b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g
+(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)12 b Ff(\))150
+2025 y Fg(ComplexColumnVector)58 b(operator)d(*)46 b
+Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 2134 y Fg(ComplexColumnVector)58
+b(operator)d(/)46 b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g
+(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)12 b Ff(\))150
+2282 y Fg(ComplexMatrix)56 b(operator)f(*)46 b Ff(\()p
+Fe(const)31 b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)p
+Fe(,)g(const)565 2392 y(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(b)12 b Ff(\))150 2540 y Fg(ComplexColumnVector)58
+b(operator)d(+)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565 2649 y(ColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 2759 y Fg(ComplexColumnVector)58
+b(operator)d(-)46 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565 2869 y(ColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 3017 y Fg(ComplexColumnVector)58
+b(product)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565 3126 y(ColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 3236 y Fg(ComplexColumnVector)58
+b(quotient)48 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)p Fe(,)g(const)565 3345 y(ColumnV)-8
+b(ector)31 b(&)p Fd(b)12 b Ff(\))150 3493 y Fg(ComplexColumnVector)58
+b(map)46 b Ff(\()p Fe(c)p 1479 3493 28 4 v 41 w(c)p 1560
+3493 V 41 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 3603 y Fg(ColumnVector)56
+b(map)46 b Ff(\()p Fe(d)p 1124 3603 V 40 w(c)p 1204 3603
+V 41 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 3712 y Fg(void)54
+b(map)46 b Ff(\()p Fe(c)p 695 3712 V 41 w(c)p 776 3712
+V 40 w(Mapp)s(er)30 b Fd(f)12 b Ff(\))150 3860 y Fg(Complex)54
+b(min)47 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+3970 y Fg(Complex)54 b(max)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 4118 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 4266 y Fg(ComplexRowVector)50
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 4375 y Fg(ComplexRowVector)g
+Ff(\()p Fe(in)m(t)32 b Fd(n)12 b Ff(\))150 4485 y Fg(ComplexRowVector)
+50 b Ff(\()p Fe(in)m(t)32 b Fd(n)p Fe(,)e(const)h(Complex)g(&)p
+Fd(val)12 b Ff(\))150 4595 y Fg(ComplexRowVector)50 b
+Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 4704 y Fg(ComplexRowVector)50 b Ff(\()p Fe(const)32
+b(Arra)m(y)p Fg(<)p Fe(Complex)p Fg(>)f Fe(&)p Fd(a)12
+b Ff(\))150 4814 y Fg(ComplexRowVector)50 b Ff(\()p Fe(const)32
+b(ComplexRo)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))150
+4962 y Fg(ComplexRowVector&)57 b(operator)e(=)46 b Ff(\()p
+Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))150 5110 y Fg(int)53 b(operator)i(==)46 b Ff(\()p
+Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))30 b Fe(const)150 5219 y Fg(int)53 b(operator)i(!=)46
+b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 5367 y Fg(ComplexRowVector&)57
+b(insert)48 b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33
+b(&)p Fd(a)p Fe(,)d(in)m(t)h Fd(c)12 b Ff(\))p eop end
+%%Page: 29 33
+TeXDict begin 29 32 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(29)150 299 y Fg(ComplexRowVector&)57 b(insert)48 b
+Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33 b(&)p
+Fd(a)p Fe(,)d(in)m(t)h Fd(c)12 b Ff(\))150 442 y Fg(ComplexRowVector&)
+57 b(fill)47 b Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150
+552 y Fg(ComplexRowVector&)57 b(fill)47 b Ff(\()p Fe(const)31
+b(Complex)g(&)p Fd(val)12 b Ff(\))150 661 y Fg(ComplexRowVector&)57
+b(fill)47 b Ff(\()p Fe(double)30 b Fd(val)p Fe(,)i(in)m(t)f(c1,)g(in)m
+(t)g(c2)p Ff(\))150 771 y Fg(ComplexRowVector&)57 b(fill)47
+b Ff(\()p Fe(const)31 b(Complex)g(&)p Fd(val)p Fe(,)g(in)m(t)g(c1,)g
+(in)m(t)g(c2)p Ff(\))150 914 y Fg(ComplexRowVector)57
+b(append)47 b Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))30 b Fe(const)150 1024 y Fg(ComplexRowVector)57
+b(append)47 b Ff(\()p Fe(const)32 b(ComplexRo)m(wV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))31 b Fe(const)150 1167
+y Fg(ComplexColumnVector)58 b(transpose)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1311 y Fg(RowVector)55
+b(real)47 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)12 b Ff(\))150 1420 y Fg(RowVector)55 b(imag)47
+b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)12 b Ff(\))150 1530 y Fg(ComplexRowVector)57
+b(conj)47 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)12 b Ff(\))150 1673 y Fg(ComplexRowVector)57
+b(extract)48 b Ff(\()p Fe(in)m(t)31 b(c1,)g(in)m(t)g(c2)p
+Ff(\))h Fe(const)150 1817 y Fg(ComplexRowVector&)57 b(operator)e(+=)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))150 1926 y Fg(ComplexRowVector&)57 b(operator)e(-=)46
+b Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)33 b(&)p Fd(a)12
+b Ff(\))150 2070 y Fg(ComplexRowVector&)57 b(operator)e(+=)46
+b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)12 b Ff(\))150 2179 y Fg(ComplexRowVector&)57
+b(operator)e(-=)46 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 2323 y Fg(ComplexRowVector)57
+b(operator)e(+)46 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(double)g Fd(s)12 b Ff(\))150
+2432 y Fg(ComplexRowVector)57 b(operator)e(-)46 b Ff(\()p
+Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33 b(&)p Fd(a)p
+Fe(,)d(double)g Fd(s)12 b Ff(\))150 2542 y Fg(ComplexRowVector)57
+b(operator)e(*)46 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(double)g Fd(s)12 b Ff(\))150
+2652 y Fg(ComplexRowVector)57 b(operator)e(/)46 b Ff(\()p
+Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33 b(&)p Fd(a)p
+Fe(,)d(double)g Fd(s)12 b Ff(\))150 2795 y Fg(ComplexRowVector)57
+b(operator)e(+)46 b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g
+(ComplexRo)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))150
+2905 y Fg(ComplexRowVector)57 b(operator)e(-)46 b Ff(\()p
+Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexRo)m(wV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 3014 y Fg(ComplexRowVector)57
+b(operator)e(*)46 b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g
+(ComplexRo)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))150
+3124 y Fg(ComplexRowVector)57 b(operator)e(/)46 b Ff(\()p
+Fe(double)30 b Fd(s)p Fe(,)h(const)g(ComplexRo)m(wV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))150 3267 y Fg(Complex)54
+b(operator)h(*)46 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(ColumnV)-8 b(ector)32
+b(&)p Fd(b)12 b Ff(\))150 3411 y Fg(Complex)54 b(operator)h(*)46
+b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)p Fe(,)d(const)h(ComplexColumnV)-8 b(ector)565
+3520 y(&)p Fd(b)12 b Ff(\))150 3664 y Fg(ComplexRowVector)57
+b(operator)e(*)46 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)565 3773 y(ComplexMatrix)h(&)p
+Fd(b)12 b Ff(\))150 3917 y Fg(ComplexRowVector)57 b(operator)e(+)46
+b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8 b(ector)33
+b(&)p Fd(a)p Fe(,)d(const)h(Ro)m(wV)-8 b(ector)565 4026
+y(&)p Fd(b)12 b Ff(\))150 4136 y Fg(ComplexRowVector)57
+b(operator)e(-)46 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(Ro)m(wV)-8 b(ector)565
+4245 y(&)p Fd(b)12 b Ff(\))150 4389 y Fg(ComplexRowVector)57
+b(product)48 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(Ro)m(wV)-8 b(ector)33
+b(&)p Fd(b)12 b Ff(\))150 4498 y Fg(ComplexRowVector)57
+b(quotient)48 b Ff(\()p Fe(const)31 b(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)p Fe(,)d(const)h(Ro)m(wV)-8 b(ector)565
+4608 y(&)p Fd(b)12 b Ff(\))150 4751 y Fg(ComplexRowVector)57
+b(map)47 b Ff(\()p Fe(c)p 1323 4751 28 4 v 40 w(c)p 1403
+4751 V 41 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 4861 y Fg(RowVector)55
+b(map)46 b Ff(\()p Fe(d)p 967 4861 V 40 w(c)p 1047 4861
+V 41 w(Mapp)s(er)29 b Fd(f)p Fe(,)i(const)g(ComplexRo)m(wV)-8
+b(ector)33 b(&)p Fd(a)12 b Ff(\))150 4971 y Fg(void)54
+b(map)46 b Ff(\()p Fe(c)p 695 4971 V 41 w(c)p 776 4971
+V 40 w(Mapp)s(er)30 b Fd(f)12 b Ff(\))150 5114 y Fg(Complex)54
+b(min)47 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+5224 y Fg(Complex)54 b(max)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 5367 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ComplexRo)m(wV)-8
+b(ector)32 b(&)p Fd(a)12 b Ff(\))p eop end
+%%Page: 30 34
+TeXDict begin 30 33 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(30)150 299 y Fg(ComplexDiagMatrix)51 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 408 y Fg(ComplexDiagMatrix)g Ff(\()p Fe(in)m(t)31
+b Fd(n)12 b Ff(\))150 518 y Fg(ComplexDiagMatrix)51 b
+Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(const)g(Complex)f(&)p
+Fd(val)12 b Ff(\))150 628 y Fg(ComplexDiagMatrix)51 b
+Ff(\()p Fe(in)m(t)31 b Fd(r)p Fe(,)g(in)m(t)g Fd(c)12
+b Ff(\))150 737 y Fg(ComplexDiagMatrix)51 b Ff(\()p Fe(in)m(t)31
+b Fd(r)p Fe(,)g(in)m(t)g Fd(c)p Fe(,)f(const)h(Complex)g(&)p
+Fd(val)12 b Ff(\))150 847 y Fg(ComplexDiagMatrix)51 b
+Ff(\()p Fe(const)31 b(Ro)m(wV)-8 b(ector)32 b(&)p Fd(a)12
+b Ff(\))150 956 y Fg(ComplexDiagMatrix)51 b Ff(\()p Fe(const)31
+b(ComplexRo)m(wV)-8 b(ector)32 b(&)p Fd(a)12 b Ff(\))150
+1066 y Fg(ComplexDiagMatrix)51 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b(&)p Fd(a)12 b Ff(\))150 1176
+y Fg(ComplexDiagMatrix)51 b Ff(\()p Fe(const)31 b(ComplexColumnV)-8
+b(ector)31 b(&)p Fd(a)12 b Ff(\))150 1285 y Fg(ComplexDiagMatrix)51
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))150
+1395 y Fg(ComplexDiagMatrix)51 b Ff(\()p Fe(const)31
+b(DiagArra)m(y)p Fg(<)p Fe(Complex)p Fg(>)i Fe(&)p Fd(a)12
+b Ff(\))150 1504 y Fg(ComplexDiagMatrix)51 b Ff(\()p
+Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))150
+1653 y Fg(ComplexDiagMatrix&)58 b(operator)c(=)46 b Ff(\()p
+Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))150
+1801 y Fg(int)53 b(operator)i(==)46 b Ff(\()p Fe(const)31
+b(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+1911 y Fg(int)53 b(operator)i(!=)46 b Ff(\()p Fe(const)31
+b(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))30 b Fe(const)150
+2059 y Fg(ComplexDiagMatrix&)58 b(fill)46 b Ff(\()p Fe(double)31
+b Fd(val)12 b Ff(\))150 2169 y Fg(ComplexDiagMatrix&)58
+b(fill)46 b Ff(\()p Fe(const)32 b(Complex)e(&)p Fd(val)12
+b Ff(\))150 2278 y Fg(ComplexDiagMatrix&)58 b(fill)46
+b Ff(\()p Fe(double)31 b Fd(val)p Fe(,)g(in)m(t)g Fd(beg)p
+Fe(,)h(in)m(t)e Fd(end)12 b Ff(\))150 2388 y Fg(ComplexDiagMatrix&)58
+b(fill)46 b Ff(\()p Fe(const)32 b(Complex)e(&)p Fd(val)p
+Fe(,)h(in)m(t)g Fd(beg)p Fe(,)h(in)m(t)e Fd(end)12 b
+Ff(\))150 2497 y Fg(ComplexDiagMatrix&)58 b(fill)46 b
+Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(a)12
+b Ff(\))150 2607 y Fg(ComplexDiagMatrix&)58 b(fill)46
+b Ff(\()p Fe(const)32 b(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(a)12 b Ff(\))150 2717 y Fg(ComplexDiagMatrix&)58
+b(fill)46 b Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))150 2826 y Fg(ComplexDiagMatrix&)58
+b(fill)46 b Ff(\()p Fe(const)32 b(ComplexRo)m(wV)-8 b(ector)32
+b(&)p Fd(a)12 b Ff(\))150 2936 y Fg(ComplexDiagMatrix&)58
+b(fill)46 b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31
+b(&)p Fd(a)p Fe(,)f(in)m(t)h Fd(beg)12 b Ff(\))150 3045
+y Fg(ComplexDiagMatrix&)58 b(fill)46 b Ff(\()p Fe(const)32
+b(ComplexColumnV)-8 b(ector)31 b(&)p Fd(a)p Fe(,)g(in)m(t)f
+Fd(beg)12 b Ff(\))150 3155 y Fg(ComplexDiagMatrix&)58
+b(fill)46 b Ff(\()p Fe(const)32 b(Ro)m(wV)-8 b(ector)32
+b(&)p Fd(a)p Fe(,)f(in)m(t)g Fd(beg)12 b Ff(\))150 3265
+y Fg(ComplexDiagMatrix&)58 b(fill)46 b Ff(\()p Fe(const)32
+b(ComplexRo)m(wV)-8 b(ector)32 b(&)p Fd(a)p Fe(,)f(in)m(t)g
+Fd(beg)12 b Ff(\))150 3413 y Fg(ComplexDiagMatrix)57
+b(transpose)49 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+3561 y Fg(DiagMatrix)55 b(real)47 b Ff(\()p Fe(const)31
+b(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))150 3671 y
+Fg(DiagMatrix)55 b(imag)47 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i
+(&)p Fd(a)12 b Ff(\))150 3780 y Fg(ComplexDiagMatrix)57
+b(conj)47 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)12 b Ff(\))150 3929 y Fg(ComplexMatrix)56 b(extract)48
+b Ff(\()p Fe(in)m(t)31 b(r1,)g(in)m(t)g(c1,)g(in)m(t)g(r2,)f(in)m(t)h
+(c2)p Ff(\))h Fe(const)150 4077 y Fg(ComplexRowVector)57
+b(row)47 b Ff(\()p Fe(in)m(t)31 b Fd(i)12 b Ff(\))30
+b Fe(const)150 4187 y Fg(ComplexRowVector)57 b(row)47
+b Ff(\()p Fe(c)m(har)31 b(*s)p Ff(\))g Fe(const)150 4335
+y Fg(ComplexColumnVector)58 b(column)47 b Ff(\()p Fe(in)m(t)32
+b Fd(i)12 b Ff(\))30 b Fe(const)150 4445 y Fg(ComplexColumnVector)58
+b(column)47 b Ff(\()p Fe(c)m(har)31 b(*s)p Ff(\))g Fe(const)150
+4593 y Fg(ComplexDiagMatrix)57 b(inverse)48 b Ff(\()p
+Fe(in)m(t)31 b(&)p Fd(info)12 b Ff(\))31 b Fe(const)150
+4703 y Fg(ComplexDiagMatrix)57 b(inverse)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 4851 y Fg(ComplexDiagMatrix&)58
+b(operator)c(+=)47 b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p
+Fd(a)12 b Ff(\))150 4961 y Fg(ComplexDiagMatrix&)58 b(operator)c(-=)47
+b Ff(\()p Fe(const)31 b(DiagMatrix)i(&)p Fd(a)12 b Ff(\))150
+5109 y Fg(ComplexDiagMatrix&)58 b(operator)c(+=)47 b
+Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)12
+b Ff(\))150 5219 y Fg(ComplexDiagMatrix&)58 b(operator)c(-=)47
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)12
+b Ff(\))150 5367 y Fg(ComplexMatrix)56 b(operator)f(+)46
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)d(double)g Fd(s)12 b Ff(\))p eop end
+%%Page: 31 35
+TeXDict begin 31 34 bop 150 -116 a Fp(Chapter)30 b(4:)41
+b(Matrix)31 b(and)f(V)-8 b(ector)32 b(Op)s(erations)1838
+b(31)150 299 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)d(double)g Fd(s)12 b Ff(\))150 458 y Fg(ComplexMatrix)56
+b(operator)f(+)46 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)p Fe(,)d(const)h(Complex)g(&)p Fd(s)12 b Ff(\))150
+568 y Fg(ComplexMatrix)56 b(operator)f(-)46 b Ff(\()p
+Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Complex)g
+(&)p Fd(s)12 b Ff(\))150 727 y Fg(ComplexDiagMatrix)57
+b(operator)e(*)46 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)p Fe(,)e(double)f Fd(s)12 b Ff(\))150 837 y Fg(ComplexDiagMatrix)
+57 b(operator)e(/)46 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)p Fe(,)e(double)f Fd(s)12 b Ff(\))150 996 y Fg(ComplexMatrix)56
+b(operator)f(+)46 b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g
+(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))150 1106 y Fg(ComplexMatrix)56
+b(operator)f(-)46 b Ff(\()p Fe(double)30 b Fd(s)p Fe(,)h(const)g
+(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))150 1265 y Fg(ComplexMatrix)56
+b(operator)f(+)46 b Ff(\()p Fe(const)31 b(Complex)f(&)p
+Fd(s)p Fe(,)h(const)g(ComplexDiagMatrix)i(&)p Fd(a)12
+b Ff(\))150 1375 y Fg(ComplexMatrix)56 b(operator)f(-)46
+b Ff(\()p Fe(const)31 b(Complex)f(&)p Fd(s)p Fe(,)h(const)g
+(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))150 1534 y Fg
+(ComplexDiagMatrix)57 b(operator)e(*)46 b Ff(\()p Fe(double)30
+b Fd(s)p Fe(,)h(const)g(ComplexDiagMatrix)i(&)p Fd(a)12
+b Ff(\))150 1694 y Fg(ComplexColumnVector)58 b(operator)d(*)46
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)d(const)565 1803 y(ColumnV)-8 b(ector)31 b(&)p Fd(b)12
+b Ff(\))150 1963 y Fg(ComplexColumnVector)58 b(operator)d(*)46
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)d(const)565 2072 y(ComplexColumnV)-8 b(ector)31
+b(&)p Fd(b)12 b Ff(\))150 2232 y Fg(ComplexDiagMatrix)57
+b(operator)e(+)46 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)p Fe(,)e(const)565 2341 y(DiagMatrix)i(&)p Fd(b)12
+b Ff(\))150 2451 y Fg(ComplexDiagMatrix)57 b(operator)e(-)46
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)e(const)565 2560 y(DiagMatrix)i(&)p Fd(b)12 b Ff(\))150
+2720 y Fg(ComplexDiagMatrix)57 b(product)48 b Ff(\()p
+Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p Fe(,)e(const)g(DiagMatrix)
+565 2829 y(&)p Fd(b)12 b Ff(\))150 2989 y Fg(ComplexMatrix)56
+b(operator)f(+)46 b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p
+Fd(a)p Fe(,)d(const)h(Matrix)h(&)p Fd(b)12 b Ff(\))150
+3098 y Fg(ComplexMatrix)56 b(operator)f(-)46 b Ff(\()p
+Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p Fe(,)d(const)h(Matrix)h(&)
+p Fd(b)12 b Ff(\))150 3208 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)31 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)d(const)h(Matrix)h(&)p Fd(b)12 b Ff(\))150 3367
+y Fg(ComplexMatrix)56 b(operator)f(+)46 b Ff(\()p Fe(const)30
+b(ComplexDiagMatrix)i(&)p Fd(a)p Fe(,)e(const)g(ComplexMatrix)565
+3477 y(&)p Fd(b)12 b Ff(\))150 3587 y Fg(ComplexMatrix)56
+b(operator)f(-)46 b Ff(\()p Fe(const)30 b(ComplexDiagMatrix)i(&)p
+Fd(a)p Fe(,)e(const)g(ComplexMatrix)565 3696 y(&)p Fd(b)12
+b Ff(\))150 3806 y Fg(ComplexMatrix)56 b(operator)f(*)46
+b Ff(\()p Fe(const)30 b(ComplexDiagMatrix)i(&)p Fd(a)p
+Fe(,)e(const)g(ComplexMatrix)565 3915 y(&)p Fd(b)12 b
+Ff(\))150 4075 y Fg(ComplexColumnVector)58 b(diag)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 4184 y
+Fg(ComplexColumnVector)58 b(diag)47 b Ff(\()p Fe(in)m(t)31
+b Fd(k)12 b Ff(\))30 b Fe(const)150 4344 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(ComplexDiagMatrix)i(&)p Fd(a)12 b Ff(\))p
+eop end
+%%Page: 32 36
+TeXDict begin 32 35 bop 150 -116 a Fp(Chapter)30 b(5:)41
+b(Matrix)31 b(F)-8 b(actorizations)2187 b(32)150 299
+y Fl(5)80 b(Matrix)54 b(F)-13 b(actorizations)150 605
+y Fg(AEPBALANCE)48 b Ff(\()p Fe(v)m(oid)p Ff(\))150 714
+y Fg(AEPBALANCE)g Ff(\()p Fe(const)32 b(Matrix)f(&)p
+Fd(a)p Fe(,)g(const)f(c)m(har)h(*)p Fd(balance_job)12
+b Ff(\))150 824 y Fg(AEPBALANCE)48 b Ff(\()p Fe(const)32
+b(AEPBALANCE)e(&)p Fd(a)12 b Ff(\))150 982 y Fg(AEPBALANCE&)56
+b(operator)e(=)46 b Ff(\()p Fe(const)31 b(AEPBALANCE)g(&)p
+Fd(a)12 b Ff(\))150 1141 y Fg(Matrix)54 b(balanced_matrix)c
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1250 y Fg(Matrix)54
+b(balancing_matrix)c Ff(\()p Fe(v)m(oid)p Ff(\))32 b
+Fe(const)150 1408 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(AEPBALANCE)f(&)p
+Fd(a)12 b Ff(\))150 1567 y Fg(ComplexAEPBALANCE)51 b
+Ff(\()p Fe(v)m(oid)p Ff(\))150 1676 y Fg(ComplexAEPBALANCE)g
+Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(const)g(c)m
+(har)f(*)p Fd(balance_job)12 b Ff(\))150 1786 y Fg(ComplexAEPBALANCE)51
+b Ff(\()p Fe(const)31 b(ComplexAEPBALANCE)f(&)p Fd(a)12
+b Ff(\))150 1944 y Fg(ComplexAEPBALANCE&)58 b(operator)c(=)46
+b Ff(\()p Fe(const)31 b(ComplexAEPBALANCE)g(&)p Fd(a)12
+b Ff(\))150 2103 y Fg(ComplexMatrix)56 b(balanced_matrix)50
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2212 y
+Fg(ComplexMatrix)56 b(balancing_matrix)51 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 2371 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ComplexAEPBALANCE)
+f(&)p Fd(a)12 b Ff(\))150 2529 y Fg(DET)46 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 2639 y Fg(DET)g Ff(\()p Fe(const)32
+b(DET)e(&)p Fd(a)12 b Ff(\))150 2797 y Fg(DET&)54 b(operator)g(=)46
+b Ff(\()p Fe(const)31 b(DET)g(&)p Fd(a)12 b Ff(\))150
+2955 y Fg(int)53 b(value_will_overflow)e Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 3065 y Fg(int)53 b(value_will_underflow)f
+Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 3223 y Fg(double)54
+b(coefficient)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+3333 y Fg(int)53 b(exponent)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 3443 y Fg(double)54 b(value)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 3601 y
+Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(DET)f(&)p Fd(a)12 b Ff(\))150
+3759 y Fg(ComplexDET)48 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+3869 y Fg(ComplexDET)g Ff(\()p Fe(const)32 b(ComplexDET)e(&)p
+Fd(a)12 b Ff(\))150 4027 y Fg(ComplexDET&)56 b(operator)e(=)46
+b Ff(\()p Fe(const)31 b(ComplexDET)g(&)p Fd(a)12 b Ff(\))150
+4186 y Fg(int)53 b(value_will_overflow)e Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 4295 y Fg(int)53 b(value_will_underflow)f
+Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 4454 y Fg(Complex)54
+b(coefficient)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+4563 y Fg(int)53 b(exponent)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 4673 y Fg(Complex)54 b(value)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 4831 y
+Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(ComplexDET)f(&)p Fd(a)12
+b Ff(\))150 4990 y Fg(GEPBALANCE)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 5099 y Fg(GEPBALANCE)g Ff(\()p Fe(const)32
+b(Matrix)f(&)p Fd(a)p Fe(,)g(const)f(Matrix)i(&,)e(const)h(c)m(har)g(*)
+p Fd(balance_job)12 b Ff(\))150 5209 y Fg(GEPBALANCE)48
+b Ff(\()p Fe(const)32 b(GEPBALANCE)e(&)p Fd(a)12 b Ff(\))150
+5367 y Fg(GEPBALANCE&)56 b(operator)e(=)46 b Ff(\()p
+Fe(const)31 b(GEPBALANCE)g(&)p Fd(a)12 b Ff(\))p eop
+end
+%%Page: 33 37
+TeXDict begin 33 36 bop 150 -116 a Fp(Chapter)30 b(5:)41
+b(Matrix)31 b(F)-8 b(actorizations)2187 b(33)150 299
+y Fg(Matrix)54 b(balanced_a_matrix)d Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 408 y Fg(Matrix)54 b(balanced_b_matrix)d
+Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150 518 y Fg(Matrix)54
+b(left_balancing_matrix)e Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 628 y Fg(Matrix)54 b(right_balancing_matrix)e
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 779 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(GEPBALANCE)f(&)p Fd(a)12 b Ff(\))150 930
+y Fg(CHOL)47 b Ff(\()p Fe(v)m(oid)p Ff(\))150 1040 y
+Fg(CHOL)g Ff(\()p Fe(const)31 b(Matrix)g(&)p Fd(a)12
+b Ff(\))150 1150 y Fg(CHOL)47 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(in)m(t)g(&)p Fd(info)12 b Ff(\))150 1259
+y Fg(CHOL)47 b Ff(\()p Fe(const)31 b(CHOL)f(&)p Fd(a)12
+b Ff(\))150 1411 y Fg(CHOL&)54 b(operator)h(=)45 b Ff(\()p
+Fe(const)32 b(CHOL)d(&)p Fd(a)12 b Ff(\))150 1562 y Fg(Matrix)54
+b(chol_matrix)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+1713 y Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(CHOL)e(&)p Fd(a)12 b Ff(\))150
+1865 y Fg(ComplexCHOL)49 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+1974 y Fg(ComplexCHOL)g Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)12 b Ff(\))150 2084 y Fg(ComplexCHOL)49 b Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)p Fe(,)g(in)m(t)g(&)p
+Fd(info)12 b Ff(\))150 2194 y Fg(ComplexCHOL)49 b Ff(\()p
+Fe(const)31 b(ComplexCHOL)f(&)p Fd(a)12 b Ff(\))150 2345
+y Fg(ComplexCHOL&)56 b(operator)f(=)45 b Ff(\()p Fe(const)32
+b(ComplexCHOL)d(&)p Fd(a)12 b Ff(\))150 2496 y Fg(ComplexMatrix)56
+b(chol_matrix)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+2648 y Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(ComplexCHOL)e(&)p Fd(a)12
+b Ff(\))150 2799 y Fg(HESS)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2909 y Fg(HESS)g Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)12 b Ff(\))150 3018 y Fg(HESS)47 b Ff(\()p Fe(const)31
+b(Matrix&a,)h(in)m(t)e(&)p Fd(info)12 b Ff(\))150 3128
+y Fg(HESS)47 b Ff(\()p Fe(const)31 b(HESS)e(&)p Fd(a)12
+b Ff(\))150 3279 y Fg(HESS&)54 b(operator)h(=)45 b Ff(\()p
+Fe(const)32 b(HESS)d(&)p Fd(a)12 b Ff(\))150 3431 y Fg(Matrix)54
+b(hess_matrix)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+3540 y Fg(Matrix)54 b(unitary_hess_matrix)d Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 3692 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(HESS)e(&)p
+Fd(a)12 b Ff(\))150 3843 y Fg(ComplexHESS)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 3953 y Fg(ComplexHESS)g Ff(\()p
+Fe(const)31 b(ComplexMatrix)g(&)p Fd(a)12 b Ff(\))150
+4062 y Fg(ComplexHESS)49 b Ff(\()p Fe(const)31 b(ComplexMatrix)g(&)p
+Fd(a)p Fe(,)g(in)m(t)g(&)p Fd(info)12 b Ff(\))150 4172
+y Fg(ComplexHESS)49 b Ff(\()p Fe(const)31 b(ComplexHESS)e(&)p
+Fd(a)12 b Ff(\))150 4323 y Fg(ComplexHESS&)56 b(operator)f(=)45
+b Ff(\()p Fe(const)32 b(ComplexHESS)d(&)p Fd(a)12 b Ff(\))150
+4475 y Fg(ComplexMatrix)56 b(hess_matrix)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 4584 y Fg(ComplexMatrix)56
+b(unitary_hess_matrix)51 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 4736 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ComplexHESS)e(&)p
+Fd(a)12 b Ff(\))150 4887 y Fg(SCHUR)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 4996 y Fg(SCHUR)g Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(const)g(c)m(har)g(*)p Fd(ord)12 b Ff(\))150
+5106 y Fg(SCHUR)47 b Ff(\()p Fe(const)31 b(Matrix)g(&)p
+Fd(a)p Fe(,)g(const)g(c)m(har)g(*)p Fd(ord)p Fe(,)h(in)m(t)e(&)p
+Fd(info)12 b Ff(\))150 5216 y Fg(SCHUR)47 b Ff(\()p Fe(const)31
+b(SCHUR)f(&)p Fd(a)p Fe(,)h(const)f(c)m(har)h(*)p Fd(ord)12
+b Ff(\))150 5367 y Fg(SCHUR&)54 b(operator)h(=)46 b Ff(\()p
+Fe(const)31 b(SCHUR)f(&)p Fd(a)12 b Ff(\))p eop end
+%%Page: 34 38
+TeXDict begin 34 37 bop 150 -116 a Fp(Chapter)30 b(5:)41
+b(Matrix)31 b(F)-8 b(actorizations)2187 b(34)150 299
+y Fg(Matrix)54 b(schur_matrix)49 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 408 y Fg(Matrix)54 b(unitary_matrix)c
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 568 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(SCHUR)f(&)p Fd(a)12 b Ff(\))150 728 y
+Fg(ComplexSCHUR)49 b Ff(\()p Fe(v)m(oid)p Ff(\))150 838
+y Fg(ComplexSCHUR)g Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p
+Fd(a)p Fe(,)e(const)h(c)m(har)g(*)p Fd(ord)12 b Ff(\))150
+947 y Fg(ComplexSCHUR)49 b Ff(\()p Fe(const)31 b(ComplexMatrix)h(&)p
+Fd(a)p Fe(,)e(const)h(c)m(har)g(*)p Fd(ord)p Fe(,)h(in)m(t)f(&)p
+Fd(info)12 b Ff(\))150 1057 y Fg(ComplexSCHUR)49 b Ff(\()p
+Fe(const)31 b(ComplexSCHUR)f(&)p Fd(a)p Fe(,)h(const)g(c)m(har)f(*)p
+Fd(ord)12 b Ff(\))150 1217 y Fg(ComplexSCHUR&)56 b(operator)f(=)46
+b Ff(\()p Fe(const)31 b(ComplexSCHUR)f(&)p Fd(a)12 b
+Ff(\))150 1376 y Fg(ComplexMatrix)56 b(schur_matrix)49
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1486 y
+Fg(ComplexMatrix)56 b(unitary_matrix)50 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 1646 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ComplexSCHUR)f(&)p
+Fd(a)12 b Ff(\))150 1806 y Fg(SVD)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 1915 y Fg(SVD)g Ff(\()p Fe(const)32 b(Matrix)f(&)p
+Fd(a)12 b Ff(\))150 2025 y Fg(SVD)46 b Ff(\()p Fe(const)32
+b(Matrix)f(&)p Fd(a)p Fe(,)f(in)m(t)h(&)p Fd(info)12
+b Ff(\))150 2134 y Fg(SVD)46 b Ff(\()p Fe(const)32 b(SVD)e(&)p
+Fd(a)12 b Ff(\))150 2294 y Fg(SVD&)54 b(operator)g(=)46
+b Ff(\()p Fe(const)31 b(SVD)g(&)p Fd(a)12 b Ff(\))150
+2454 y Fg(DiagMatrix)55 b(singular_values)50 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2564 y Fg(Matrix)54
+b(left_singular_matrix)e Ff(\()p Fe(v)m(oid)p Ff(\))31
+b Fe(const)150 2673 y Fg(Matrix)54 b(right_singular_matrix)e
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2833 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(SVD)f(&)p Fd(a)12 b Ff(\))150 2993 y Fg(ComplexSVD)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 3102 y Fg(ComplexSVD)g
+Ff(\()p Fe(const)32 b(ComplexMatrix)f(&)p Fd(a)12 b Ff(\))150
+3212 y Fg(ComplexSVD)48 b Ff(\()p Fe(const)32 b(ComplexMatrix)f(&)p
+Fd(a)p Fe(,)g(in)m(t)f(&)p Fd(info)12 b Ff(\))150 3322
+y Fg(ComplexSVD)48 b Ff(\()p Fe(const)32 b(ComplexSVD)e(&)p
+Fd(a)12 b Ff(\))150 3481 y Fg(ComplexSVD&)56 b(operator)e(=)46
+b Ff(\()p Fe(const)31 b(ComplexSVD)g(&)p Fd(a)12 b Ff(\))150
+3641 y Fg(DiagMatrix)55 b(singular_values)50 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 3751 y Fg(ComplexMatrix)56
+b(left_singular_matrix)c Ff(\()p Fe(v)m(oid)p Ff(\))31
+b Fe(const)150 3860 y Fg(ComplexMatrix)56 b(right_singular_matrix)c
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 4020 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(ComplexSVD)f(&)p Fd(a)12 b Ff(\))150 4180
+y Fg(EIG)46 b Ff(\()p Fe(v)m(oid)p Ff(\))150 4290 y Fg(EIG)g
+Ff(\()p Fe(const)32 b(Matrix)f(&)p Fd(a)12 b Ff(\))150
+4399 y Fg(EIG)46 b Ff(\()p Fe(const)32 b(Matrix)f(&)p
+Fd(a)p Fe(,)f(in)m(t)h(&)p Fd(info)12 b Ff(\))150 4509
+y Fg(EIG)46 b Ff(\()p Fe(const)32 b(ComplexMatrix)f(&)p
+Fd(a)12 b Ff(\))150 4618 y Fg(EIG)46 b Ff(\()p Fe(const)32
+b(ComplexMatrix)f(&)p Fd(a)p Fe(,)f(in)m(t)h(&)p Fd(info)12
+b Ff(\))150 4728 y Fg(EIG)46 b Ff(\()p Fe(const)32 b(EIG)e(&)p
+Fd(a)12 b Ff(\))150 4888 y Fg(EIG&)54 b(operator)g(=)46
+b Ff(\()p Fe(const)31 b(EIG)g(&)p Fd(a)12 b Ff(\))150
+5048 y Fg(ComplexColumnVector)58 b(eigenvalues)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 5207 y Fg(ComplexMatrix)56
+b(eigenvectors)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+5367 y Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(EIG)f(&)p Fd(a)12 b Ff(\))p
+eop end
+%%Page: 35 39
+TeXDict begin 35 38 bop 150 -116 a Fp(Chapter)30 b(5:)41
+b(Matrix)31 b(F)-8 b(actorizations)2187 b(35)150 299
+y Fg(LU)46 b Ff(\()p Fe(v)m(oid)p Ff(\))150 408 y Fg(LU)g
+Ff(\()p Fe(const)31 b(Matrix)h(&)p Fd(a)12 b Ff(\))150
+518 y Fg(LU)46 b Ff(\()p Fe(const)31 b(LU)g(&)p Fd(a)12
+b Ff(\))150 677 y Fg(LU&)53 b(operator)i(=)46 b Ff(\()p
+Fe(const)31 b(LU)f(&)p Fd(a)12 b Ff(\))150 837 y Fg(Matrix)54
+b(L)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+946 y Fg(Matrix)54 b(U)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 1056 y Fg(Matrix)54 b(P)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 1215 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(LU)f(&)p
+Fd(a)12 b Ff(\))150 1375 y Fg(ComplexLU)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 1484 y Fg(ComplexLU)g Ff(\()p
+Fe(const)31 b(ComplexMatrix)h(&)p Fd(a)12 b Ff(\))150
+1594 y Fg(ComplexLU)48 b Ff(\()p Fe(const)31 b(ComplexLU)g(&)p
+Fd(a)12 b Ff(\))150 1753 y Fg(ComplexLU&)55 b(operator)g(=)46
+b Ff(\()p Fe(const)31 b(ComplexLU)f(&)p Fd(a)12 b Ff(\))150
+1913 y Fg(ComplexMatrix)56 b(L)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 2022 y Fg(ComplexMatrix)56 b(U)46
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2132 y
+Fg(Matrix)54 b(P)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b
+Fe(const)150 2291 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(ComplexLU)f(&)p
+Fd(a)12 b Ff(\))150 2451 y Fg(QR)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2560 y Fg(QR)g Ff(\()p Fe(const)31 b(Matrix)h(&)p
+Fd(A)12 b Ff(\))150 2670 y Fg(QR)46 b Ff(\()p Fe(const)31
+b(QR)f(&)p Fd(a)12 b Ff(\))150 2829 y Fg(QR&)53 b(operator)i(=)46
+b Ff(\()p Fe(const)31 b(QR)f(&)p Fd(a)12 b Ff(\))150
+2989 y Fg(Matrix)54 b(Q)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 3098 y Fg(Matrix)54 b(R)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 3258 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(QR)f(&)p
+Fd(a)12 b Ff(\))150 3417 y Fg(ComplexQR)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 3527 y Fg(ComplexQR)g Ff(\()p
+Fe(const)31 b(ComplexMatrix)h(&)p Fd(A)12 b Ff(\))150
+3636 y Fg(ComplexQR)48 b Ff(\()p Fe(const)31 b(ComplexQR)f(&)p
+Fd(a)12 b Ff(\))150 3796 y Fg(ComplexQR&)55 b(operator)g(=)46
+b Ff(\()p Fe(const)31 b(ComplexQR)f(&)p Fd(a)12 b Ff(\))150
+3955 y Fg(ComplexMatrix)56 b(Q)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 4065 y Fg(ComplexMatrix)56 b(R)46
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 4224 y
+Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(ComplexQR)f(&)p Fd(a)12
+b Ff(\))p eop end
+%%Page: 36 40
+TeXDict begin 36 39 bop 150 -116 a Fp(Chapter)30 b(6:)41
+b(Ranges)2760 b(36)150 299 y Fl(6)80 b(Ranges)150 608
+y Fg(Range)47 b Ff(\()p Fe(v)m(oid)p Ff(\))150 717 y
+Fg(Range)g Ff(\()p Fe(const)31 b(Range)g(&)p Fd(r)12
+b Ff(\))150 827 y Fg(Range)47 b Ff(\()p Fe(double)30
+b Fd(b)p Fe(,)h(double)f Fd(l)12 b Ff(\))150 936 y Fg(Range)47
+b Ff(\()p Fe(double)30 b Fd(b)p Fe(,)h(double)f Fd(l)p
+Fe(,)h(double)f Fd(i)12 b Ff(\))150 1096 y Fg(double)54
+b(base)47 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+1205 y Fg(double)54 b(limit)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 1315 y Fg(double)54 b(inc)46
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 1474 y
+Fg(void)54 b(set_base)47 b Ff(\()p Fe(double)31 b Fd(b)12
+b Ff(\))150 1584 y Fg(void)54 b(set_limit)48 b Ff(\()p
+Fe(double)30 b Fd(l)12 b Ff(\))150 1694 y Fg(void)54
+b(set_inc)47 b Ff(\()p Fe(double)30 b Fd(i)12 b Ff(\))150
+1853 y Fg(int)53 b(nelem)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 2012 y Fg(double)54 b(min)46 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2122 y Fg(double)54
+b(max)46 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+2281 y Fg(void)54 b(sort)46 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+2441 y Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(Range)g(&)p Fd(r)12 b Ff(\))150
+2550 y Fg(istream&)55 b(operator)f(>>)47 b Ff(\()p Fe(istream)31
+b(&)p Fd(is)p Fe(,)g(Range)g(&)p Fd(r)12 b Ff(\))150
+2710 y Fg(void)54 b(print_range)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))p eop end
+%%Page: 37 41
+TeXDict begin 37 40 bop 150 -116 a Fp(Chapter)30 b(7:)41
+b(Nonlinear)31 b(F)-8 b(unctions)2242 b(37)150 299 y
+Fl(7)80 b(Nonlinear)53 b(F)-13 b(unctions)150 608 y Fg(NLFunc)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 717 y Fg(NLFunc)g Ff(\()p
+Fe(const)32 b Fd(nonlinear_fcn)12 b Ff(\))150 827 y Fg(NLFunc)47
+b Ff(\()p Fe(const)32 b Fd(nonlinear_fcn)p Fe(,)i(const)d
+Fd(jacobian_fcn)12 b Ff(\))150 936 y Fg(NLFunc)47 b Ff(\()p
+Fe(const)32 b(NLF)-8 b(unc)30 b(&)p Fd(a)12 b Ff(\))150
+1096 y Fg(NLFunc&)54 b(operator)h(=)46 b Ff(\()p Fe(const)31
+b(NLF)-8 b(unc)31 b(&)p Fd(a)12 b Ff(\))150 1255 y Fg(nonlinear_fcn)56
+b(function)48 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const;)150
+1415 y Fg(NLFunc&)54 b(set_function)c Ff(\()p Fe(const)31
+b(nonlinear)p 1890 1415 28 4 v 40 w(fcn)f Fd(f)12 b Ff(\))150
+1574 y Fg(jacobian_fcn)56 b(jacobian_function)51 b Ff(\()p
+Fe(v)m(oid)p Ff(\))31 b Fe(const;)150 1733 y Fg(NLFunc&)54
+b(set_jacobian_function)e Ff(\()p Fe(const)31 b(jacobian)p
+2321 1733 V 41 w(fcn)f Fd(j)12 b Ff(\))p eop end
+%%Page: 38 42
+TeXDict begin 38 41 bop 150 -116 a Fp(Chapter)30 b(8:)41
+b(Nonlinear)31 b(Equations)2229 b(38)150 299 y Fl(8)80
+b(Nonlinear)53 b(Equations)150 608 y Fg(NLEqn_options)c
+Ff(\()p Fe(v)m(oid)p Ff(\))150 717 y Fg(NLEqn_options)g
+Ff(\()p Fe(const)32 b(NLEqn)p 1441 717 28 4 v 39 w(options)f(&)p
+Fd(opt)12 b Ff(\))150 877 y Fg(NLEqn_options&)57 b(operator)d(=)46
+b Ff(\()p Fe(const)31 b(NLEqn)p 2068 877 V 40 w(options)f(&)p
+Fd(opt)12 b Ff(\))150 1036 y Fg(void)54 b(init)46 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 1196 y Fg(void)54 b(copy)46 b
+Ff(\()p Fe(const)31 b(NLEqn)p 1231 1196 V 40 w(options)f(&)p
+Fd(opt)12 b Ff(\))150 1355 y Fg(void)54 b(set_default_options)d
+Ff(\()p Fe(v)m(oid)p Ff(\))150 1514 y Fg(void)j(set_tolerance)49
+b Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150 1674 y
+Fg(double)54 b(tolerance)48 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+1833 y Fg(NLEqn)f Ff(\()p Fe(v)m(oid)p Ff(\))150 1943
+y Fg(NLEqn)g Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector&,)31
+b(const)g Fd(NLFunc)12 b Ff(\))150 2052 y Fg(NLEqn)47
+b Ff(\()p Fe(const)31 b(NLEqn)f(&)p Fd(a)12 b Ff(\))150
+2212 y Fg(NLEqn&)54 b(operator)h(=)46 b Ff(\()p Fe(const)31
+b(NLEqn)f(&)p Fd(a)12 b Ff(\))150 2371 y Fg(void)54 b(resize)47
+b Ff(\()p Fe(in)m(t)31 b Fd(n)12 b Ff(\))150 2531 y Fg(void)54
+b(set_states)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32
+b(&)p Fd(x)12 b Ff(\))150 2690 y Fg(ColumnVector)56 b(states)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2849 y
+Fg(int)53 b(size)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b
+Fe(const)150 3009 y Fg(ColumnVector)56 b(solve)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 3118 y Fg(ColumnVector)56 b(solve)47
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)12
+b Ff(\))150 3278 y Fg(ColumnVector)56 b(solve)47 b Ff(\()p
+Fe(in)m(t)31 b(&)p Fd(info)12 b Ff(\))150 3387 y Fg(ColumnVector)56
+b(solve)47 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(x)p Fe(,)g(in)m(t)g(&)p Fd(info)12 b Ff(\))p
+eop end
+%%Page: 39 43
+TeXDict begin 39 42 bop 150 -116 a Fp(Chapter)30 b(9:)41
+b(Optimization)2520 b(39)150 299 y Fl(9)80 b(Optimization)150
+674 y Fo(9.1)68 b(Ob)7 b(jectiv)l(e)47 b(F)-11 b(unctions)150
+895 y Fg(Objective)48 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+1005 y Fg(Objective)g Ff(\()p Fe(const)31 b Fd(objective_fcn)12
+b Ff(\))150 1114 y Fg(Objective)48 b Ff(\()p Fe(const)31
+b Fd(objective_fcn)p Fe(,)k(const)c Fd(gradient_fcn)12
+b Ff(\))150 1224 y Fg(Objective)48 b Ff(\()p Fe(const)31
+b(Ob)5 b(jectiv)m(e)32 b(&)p Fd(a)12 b Ff(\))150 1396
+y Fg(Objective&)55 b(operator)g(=)46 b Ff(\()p Fe(const)31
+b(Ob)5 b(jectiv)m(e)32 b(&)p Fd(a)12 b Ff(\))150 1567
+y Fg(objective_fcn)56 b(objective_function)51 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const;)150 1739 y Fg(Objective&)55
+b(set_objective_functio)q(n)c Ff(\()p Fe(const)32 b Fd(objective_fcn)12
+b Ff(\))150 1911 y Fg(gradient_fcn)56 b(gradient_function)51
+b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const;)150 2082
+y Fg(Objective&)55 b(set_gradient_function)d Ff(\()p
+Fe(const)31 b Fd(gradient_fcn)12 b Ff(\))150 2277 y Fo(9.2)68
+b(Bounds)150 2499 y Fg(Bounds)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2608 y Fg(Bounds)g Ff(\()p Fe(in)m(t)32 b Fd(n)12
+b Ff(\))150 2718 y Fg(Bounds)47 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b Fd(lb)p Fe(,)g(const)g(ColumnV)-8
+b(ector)31 b Fd(ub)12 b Ff(\))150 2827 y Fg(Bounds)47
+b Ff(\()p Fe(const)32 b(Bounds)d(&)p Fd(a)12 b Ff(\))150
+2999 y Fg(Bounds&)54 b(operator)h(=)46 b Ff(\()p Fe(const)31
+b(Bounds)f(&)p Fd(a)12 b Ff(\))150 3171 y Fg(Bounds&)54
+b(resize)48 b Ff(\()p Fe(in)m(t)31 b Fd(n)12 b Ff(\))150
+3342 y Fg(double)54 b(lower_bound)49 b Ff(\()p Fe(in)m(t)31
+b Fd(index)12 b Ff(\))32 b Fe(const;)150 3452 y Fg(double)54
+b(upper_bound)49 b Ff(\()p Fe(in)m(t)31 b Fd(index)12
+b Ff(\))32 b Fe(const;)150 3624 y Fg(ColumnVector)56
+b(lower_bounds)49 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const;)150
+3733 y Fg(ColumnVector)56 b(upper_bounds)49 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const;)150 3905 y Fg(int)53
+b(size)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const;)150
+4077 y Fg(Bounds&)54 b(set_bound)49 b Ff(\()p Fe(in)m(t)31
+b Fd(index)p Fe(,)h(double)e Fd(low)p Fe(,)h(double)f
+Fd(high)12 b Ff(\))150 4248 y Fg(Bounds&)54 b(set_bounds)49
+b Ff(\()p Fe(double)30 b Fd(low)p Fe(,)i(double)e Fd(high)12
+b Ff(\))150 4358 y Fg(Bounds&)54 b(set_bounds)49 b Ff(\()p
+Fe(const)31 b(ColumnV)-8 b(ector)31 b Fd(lb)p Fe(,)h(const)e(ColumnV)-8
+b(ector)32 b Fd(ub)12 b Ff(\))150 4529 y Fg(Bounds&)54
+b(set_lower_bound)c Ff(\()p Fe(in)m(t)32 b Fd(index)p
+Fe(,)g(double)e Fd(low)12 b Ff(\))150 4639 y Fg(Bounds&)54
+b(set_upper_bound)c Ff(\()p Fe(in)m(t)32 b Fd(index)p
+Fe(,)g(double)e Fd(high)12 b Ff(\))150 4811 y Fg(Bounds&)54
+b(set_lower_bounds)d Ff(\()p Fe(double)30 b Fd(low)12
+b Ff(\))150 4920 y Fg(Bounds&)54 b(set_upper_bounds)d
+Ff(\()p Fe(double)30 b Fd(high)12 b Ff(\))150 5092 y
+Fg(Bounds&)54 b(set_lower_bounds)d Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b Fd(lb)12 b Ff(\))150 5202 y
+Fg(Bounds&)54 b(set_upper_bounds)d Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b Fd(ub)12 b Ff(\))150 5373 y
+Fg(ostream&)55 b(operator)f(<<)47 b Ff(\()p Fe(ostream)31
+b(&)p Fd(os)p Fe(,)g(const)g(Bounds)e(&)p Fd(b)12 b Ff(\))p
+eop end
+%%Page: 40 44
+TeXDict begin 40 43 bop 150 -116 a Fp(Chapter)30 b(9:)41
+b(Optimization)2520 b(40)150 299 y Fo(9.3)68 b(Linear)45
+b(Constrain)l(ts)150 509 y Fg(LinConst)j Ff(\()p Fe(v)m(oid)p
+Ff(\))150 618 y Fg(LinConst)g Ff(\()p Fe(in)m(t)31 b
+Fd(nclin)p Fe(,)h(in)m(t)f Fd(nx)12 b Ff(\))150 728 y
+Fg(LinConst)48 b Ff(\()p Fe(in)m(t)31 b Fd(nclin_eq)p
+Fe(,)i(in)m(t)e Fd(nclin_ineq)p Fe(,)j(in)m(t)c Fd(nx)12
+b Ff(\))150 838 y Fg(LinConst)48 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b(&)p Fd(lb)p Fe(,)g(const)g(Matrix)g(&)p
+Fd(A)p Fe(,)g(const)g(ColumnV)-8 b(ector)31 b(&)p Fd(ub)12
+b Ff(\))150 947 y Fg(LinConst)48 b Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(A_eq)p Fe(,)h(const)f(ColumnV)-8 b(ector)31
+b(&)p Fd(b_eq)p Fe(,)g(const)g(Matrix)565 1057 y(&)p
+Fd(A_ineq)p Fe(,)h(const)f(ColumnV)-8 b(ector)31 b(&)p
+Fd(b_ineq)12 b Ff(\))150 1166 y Fg(LinConst)48 b Ff(\()p
+Fe(const)31 b(LinConst)f(&)p Fd(a)12 b Ff(\))150 1327
+y Fg(LinConst&)55 b(operator)g(=)46 b Ff(\()p Fe(const)31
+b(LinConst)e(&)p Fd(a)12 b Ff(\))150 1487 y Fg(LinConst&)55
+b(resize)47 b Ff(\()p Fe(in)m(t)32 b Fd(nclin)p Fe(,)g(in)m(t)f
+Fd(n)12 b Ff(\))150 1647 y Fg(Matrix)54 b(constraint_matrix)d
+Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const;)150 1807 y
+Fg(LinConst&)55 b(set_constraint_matrix)d Ff(\()p Fe(const)31
+b(Matrix)g(&)p Fd(A)12 b Ff(\))150 1967 y Fg(Matrix)54
+b(eq_constraint_matrix)e Ff(\()p Fe(v)m(oid)p Ff(\))31
+b Fe(const;)150 2077 y Fg(Matrix)54 b(ineq_constraint_matrix)e
+Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const;)150 2237 y
+Fg(ColumnVector)56 b(eq_constraint_vector)51 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const;)150 2347 y Fg(ColumnVector)56
+b(ineq_constraint_vector)c Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const;)150 2507 y Fg(ostream&)55 b(operator)f(<<)47
+b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p Fe(,)g(const)g(LinConst)f(&)p
+Fd(b)12 b Ff(\))150 2690 y Fo(9.4)68 b(Nonlinear)46 b(Constrain)l(ts)
+150 2900 y Fg(NLConst)i Ff(\()p Fe(v)m(oid)p Ff(\))150
+3010 y Fg(NLConst)g Ff(\()p Fe(in)m(t)31 b Fd(n)12 b
+Ff(\))150 3119 y Fg(NLConst)48 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)31 b Fd(lb)p Fe(,)g(const)g(NLF)-8
+b(unc)31 b Fd(f)p Fe(,)f(const)h(ColumnV)-8 b(ector)32
+b Fd(ub)12 b Ff(\))150 3229 y Fg(NLConst)48 b Ff(\()p
+Fe(const)31 b(NLConst)f(&)p Fd(a)12 b Ff(\))150 3389
+y Fg(NLConst&)55 b(operator)f(=)46 b Ff(\()p Fe(const)31
+b(NLConst)g(&)p Fd(a)12 b Ff(\))150 3573 y Fo(9.5)68
+b(Quadratic)46 b(Programming)150 3783 y Fg(QP)g Ff(\()p
+Fe(v)m(oid)p Ff(\))150 3892 y Fg(QP)g Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)32 b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p
+Fd(H)12 b Ff(\))150 4002 y Fg(QP)46 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)32 b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p
+Fd(H)p Fe(,)g(const)g(ColumnV)-8 b(ector)31 b(&)p Fd(c)12
+b Ff(\))150 4111 y Fg(QP)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)32 b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p Fd(H)p
+Fe(,)g(const)g(Bounds)e(&)p Fd(b)12 b Ff(\))150 4221
+y Fg(QP)46 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32
+b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p Fd(H)p Fe(,)g(const)g
+(LinConst)e(&)p Fd(lc)12 b Ff(\))150 4331 y Fg(QP)46
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(x)p
+Fe(,)e(const)h(Matrix)g(&)p Fd(H)p Fe(,)g(const)g(ColumnV)-8
+b(ector)31 b(&)p Fd(c)p Fe(,)g(const)565 4440 y(Bounds)f(&)p
+Fd(b)12 b Ff(\))150 4550 y Fg(QP)46 b Ff(\()p Fe(const)31
+b(ColumnV)-8 b(ector)32 b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p
+Fd(H)p Fe(,)g(const)g(ColumnV)-8 b(ector)31 b(&)p Fd(c)p
+Fe(,)g(const)565 4659 y(LinConst)f(&)p Fd(lc)12 b Ff(\))150
+4769 y Fg(QP)46 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32
+b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p Fd(H)p Fe(,)g(const)g(Bounds)e
+(&)p Fd(b)p Fe(,)i(const)g(LinConst)565 4879 y(&)p Fd(lc)12
+b Ff(\))150 4988 y Fg(QP)46 b Ff(\()p Fe(const)31 b(ColumnV)-8
+b(ector)32 b(&)p Fd(x)p Fe(,)e(const)h(Matrix)g(&)p Fd(H)p
+Fe(,)g(const)g(ColumnV)-8 b(ector)31 b(&)p Fd(c)p Fe(,)g(const)565
+5098 y(Bounds)f(&)p Fd(b)p Fe(,)g(const)h(LinConst)f(&)p
+Fd(lc)12 b Ff(\))150 5258 y Fg(virtual)54 b(ColumnVector)i(minimize)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 5367 y Fg(virtual)54
+b(ColumnVector)i(minimize)48 b Ff(\()p Fe(double)31 b(&)p
+Fd(objf)12 b Ff(\))p eop end
+%%Page: 41 45
+TeXDict begin 41 44 bop 150 -116 a Fp(Chapter)30 b(9:)41
+b(Optimization)2520 b(41)150 299 y Fg(virtual)54 b(ColumnVector)i
+(minimize)48 b Ff(\()p Fe(double)31 b(&)p Fd(objf)p Fe(,)g(in)m(t)g(&)p
+Fd(inform)12 b Ff(\))150 408 y Fg(virtual)54 b(ColumnVector)i(minimize)
+48 b Ff(\()p Fe(double)31 b(&)p Fd(objf)p Fe(,)g(in)m(t)g(&)p
+Fd(inform)p Fe(,)h(ColumnV)-8 b(ector)565 518 y(&)p Fd(lambda)12
+b Ff(\))32 b Fe(=)e(0;)150 677 y Fg(virtual)54 b(ColumnVector)i
+(minimize)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32
+b(&)p Fd(x)12 b Ff(\))150 787 y Fg(virtual)54 b(ColumnVector)i
+(minimize)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32
+b(&)p Fd(x)p Fe(,)e(double)g(&)p Fd(objf)12 b Ff(\))150
+897 y Fg(virtual)54 b(ColumnVector)i(minimize)48 b Ff(\()p
+Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(x)p Fe(,)e(double)g(&)p
+Fd(objf)p Fe(,)i(in)m(t)565 1006 y(&)p Fd(inform)12 b
+Ff(\))150 1116 y Fg(virtual)54 b(ColumnVector)i(minimize)48
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)32 b(&)p Fd(x)p
+Fe(,)e(double)g(&)p Fd(objf)p Fe(,)i(in)m(t)565 1225
+y(&)p Fd(inform)p Fe(,)g(ColumnV)-8 b(ector)31 b(&)p
+Fd(lambda)12 b Ff(\))150 1385 y Fg(ColumnVector)56 b(minimize)48
+b Ff(\()p Fe(double)30 b(&)p Fd(objf)p Fe(,)i(in)m(t)e(&)p
+Fd(inform)p Fe(,)j(ColumnV)-8 b(ector)31 b(&)p Fd(lambda)12
+b Ff(\))150 1567 y Fo(9.6)68 b(Nonlinear)46 b(Programming)150
+1777 y Fg(NLP)g Ff(\()p Fe(v)m(oid)p Ff(\))150 1886 y
+Fg(NLP)g Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31
+b(&)p Fd(x)p Fe(,)f(const)h(Ob)5 b(jectiv)m(e)32 b(&)p
+Fd(phi)12 b Ff(\))150 1996 y Fg(NLP)46 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5
+b(jectiv)m(e)32 b(&)p Fd(phi)p Fe(,)f(const)g(Bounds)f(&)p
+Fd(b)12 b Ff(\))150 2105 y Fg(NLP)46 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5
+b(jectiv)m(e)32 b(&)p Fd(phi)p Fe(,)f(const)g(Bounds)f(&)p
+Fd(b)p Fe(,)g(const)565 2215 y(LinConst)g(&)p Fd(lc)12
+b Ff(\))150 2325 y Fg(NLP)46 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5 b(jectiv)m(e)32
+b(&)p Fd(phi)p Fe(,)f(const)g(Bounds)f(&)p Fd(b)p Fe(,)g(const)565
+2434 y(LinConst)g(&)p Fd(lc)p Fe(,)h(const)g(NLConst)f(&)p
+Fd(nlc)12 b Ff(\))150 2544 y Fg(NLP)46 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5
+b(jectiv)m(e)32 b(&)p Fd(phi)p Fe(,)f(const)g(LinConst)f(&)p
+Fd(lc)12 b Ff(\))150 2653 y Fg(NLP)46 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5
+b(jectiv)m(e)32 b(&)p Fd(phi)p Fe(,)f(const)g(LinConst)f(&)p
+Fd(lc)p Fe(,)h(const)565 2763 y(NLConst)f(&)p Fd(nlc)12
+b Ff(\))150 2873 y Fg(NLP)46 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5 b(jectiv)m(e)32
+b(&)p Fd(phi)p Fe(,)f(const)g(NLConst)f(&)p Fd(nlc)12
+b Ff(\))150 2982 y Fg(NLP)46 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(x)p Fe(,)f(const)h(Ob)5 b(jectiv)m(e)32
+b(&)p Fd(phi)p Fe(,)f(const)g(Bounds)f(&)p Fd(b)p Fe(,)g(const)565
+3092 y(NLConst)g(&)p Fd(nlc)12 b Ff(\))150 3251 y Fg(NLP&)54
+b(operator)g(=)46 b Ff(\()p Fe(const)31 b(NLP)f(&)p Fd(a)12
+b Ff(\))150 3411 y Fg(int)53 b(size)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))32 b Fe(const)150 3570 y Fg(ColumnVector)56 b(minimize)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 3680 y Fg(ColumnVector)56
+b(minimize)48 b Ff(\()p Fe(double)30 b(&)p Fd(objf)12
+b Ff(\))150 3789 y Fg(ColumnVector)56 b(minimize)48 b
+Ff(\()p Fe(double)30 b(&)p Fd(objf)p Fe(,)i(in)m(t)e(&)p
+Fd(inform)12 b Ff(\))150 3899 y Fg(ColumnVector)56 b(minimize)48
+b Ff(\()p Fe(double)30 b(&)p Fd(objf)p Fe(,)i(in)m(t)e(&)p
+Fd(inform)p Fe(,)j(ColumnV)-8 b(ector)31 b(&)p Fd(lambda)12
+b Ff(\))150 4058 y Fg(ColumnVector)56 b(minimize)48 b
+Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)12
+b Ff(\))150 4168 y Fg(ColumnVector)56 b(minimize)48 b
+Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p
+Fe(,)g(double)f(&)p Fd(objf)12 b Ff(\))150 4277 y Fg(ColumnVector)56
+b(minimize)48 b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31
+b(&)p Fd(x)p Fe(,)g(double)f(&)p Fd(objf)p Fe(,)h(in)m(t)g(&)p
+Fd(inform)12 b Ff(\))150 4387 y Fg(ColumnVector)56 b(minimize)48
+b Ff(\()p Fe(const)31 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p
+Fe(,)g(double)f(&)p Fd(objf)p Fe(,)h(in)m(t)g(&)p Fd(inform)p
+Fe(,)565 4496 y(ColumnV)-8 b(ector)31 b(&)p Fd(lambda)12
+b Ff(\))p eop end
+%%Page: 42 46
+TeXDict begin 42 45 bop 150 -116 a Fp(Chapter)30 b(10:)41
+b(Quadrature)2538 b(42)150 299 y Fl(10)80 b(Quadrature)150
+639 y Fg(Quad)47 b Ff(\()p Fe(in)m(tegrand)p 822 639
+28 4 v 41 w(fcn)30 b Fd(fcn)12 b Ff(\))150 749 y Fg(Quad)47
+b Ff(\()p Fe(in)m(tegrand)p 822 749 V 41 w(fcn)30 b Fd(fcn)p
+Fe(,)h(double)f Fd(abs)p Fe(,)h(double)f Fd(rel)12 b
+Ff(\))150 917 y Fg(virtual)54 b(double)h(integrate)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 1027 y Fg(virtual)54
+b(double)h(integrate)48 b Ff(\()p Fe(in)m(t)31 b(&)p
+Fd(ier)12 b Ff(\))150 1136 y Fg(virtual)54 b(double)h(integrate)48
+b Ff(\()p Fe(in)m(t)31 b(&)p Fd(ier)p Fe(,)g(in)m(t)g(&)p
+Fd(neval)12 b Ff(\))150 1246 y Fg(virtual)54 b(double)h(integrate)48
+b Ff(\()p Fe(in)m(t)31 b(&)p Fd(ier)p Fe(,)g(in)m(t)g(&)p
+Fd(neval)p Fe(,)h(double)e(&)p Fd(abserr)12 b Ff(\))31
+b Fe(=)f(0)150 1414 y Fg(Quad_options)49 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 1524 y Fg(Quad_options)g Ff(\()p Fe(const)31
+b(Quad)p 1320 1524 V 40 w(options)f(&)p Fd(opt)12 b Ff(\))150
+1692 y Fg(Quad_options&)56 b(operator)f(=)46 b Ff(\()p
+Fe(const)31 b(Quad)p 1948 1692 V 39 w(options)g(&)p Fd(opt)12
+b Ff(\))150 1861 y Fg(void)54 b(init)46 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2029 y Fg(void)54 b(copy)46 b Ff(\()p Fe(const)31
+b(Quad)p 1163 2029 V 40 w(options)f(&)p Fd(opt)12 b Ff(\))150
+2198 y Fg(void)54 b(set_default_options)d Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2366 y Fg(void)j(set_absolute_tolerance)e Ff(\()p
+Fe(double)30 b Fd(val)12 b Ff(\))150 2535 y Fg(void)54
+b(set_relative_tolerance)e Ff(\()p Fe(double)30 b Fd(val)12
+b Ff(\))150 2703 y Fg(double)54 b(absolute_tolerance)d
+Ff(\()p Fe(v)m(oid)p Ff(\))150 2813 y Fg(double)j(relative_tolerance)d
+Ff(\()p Fe(v)m(oid)p Ff(\))150 2981 y Fg(DefQuad)d Ff(\()p
+Fe(in)m(tegrand)p 979 2981 V 40 w(fcn)30 b Fd(fcn)12
+b Ff(\))150 3091 y Fg(DefQuad)48 b Ff(\()p Fe(in)m(tegrand)p
+979 3091 V 40 w(fcn)30 b Fd(fcn)p Fe(,)i(double)e Fd(ll)p
+Fe(,)h(double)f Fd(ul)12 b Ff(\))150 3200 y Fg(DefQuad)48
+b Ff(\()p Fe(in)m(tegrand)p 979 3200 V 40 w(fcn)30 b
+Fd(fcn)p Fe(,)i(double)e Fd(ll)p Fe(,)h(double)f Fd(ul)p
+Fe(,)h(double)f Fd(abs)p Fe(,)h(double)f Fd(rel)12 b
+Ff(\))150 3310 y Fg(DefQuad)48 b Ff(\()p Fe(in)m(tegrand)p
+979 3310 V 40 w(fcn)30 b Fd(fcn)p Fe(,)i(double)e Fd(ll)p
+Fe(,)h(double)f Fd(ul)p Fe(,)h(const)g(ColumnV)-8 b(ector)31
+b(&)p Fd(sing)12 b Ff(\))150 3419 y Fg(DefQuad)48 b Ff(\()p
+Fe(in)m(tegrand)p 979 3419 V 40 w(fcn)30 b Fd(fcn)p Fe(,)i(const)f
+(ColumnV)-8 b(ector)31 b(&)p Fd(sing)p Fe(,)h(double)d
+Fd(abs)p Fe(,)j(double)e Fd(rel)12 b Ff(\))150 3529 y
+Fg(DefQuad)48 b Ff(\()p Fe(in)m(tegrand)p 979 3529 V
+40 w(fcn)30 b Fd(fcn)p Fe(,)i(const)f(ColumnV)-8 b(ector)31
+b(&)p Fd(sing)12 b Ff(\))150 3639 y Fg(DefQuad)48 b Ff(\()p
+Fe(in)m(tegrand)p 979 3639 V 40 w(fcn)30 b Fd(fcn)p Fe(,)i(double)e
+Fd(ll)p Fe(,)h(double)f Fd(ul)p Fe(,)h(const)g(ColumnV)-8
+b(ector)31 b(&)p Fd(sing)p Fe(,)565 3748 y(double)f Fd(abs)p
+Fe(,)i(double)d Fd(rel)12 b Ff(\))150 3917 y Fg(IndefQuad)48
+b Ff(\()p Fe(in)m(tegrand)p 1083 3917 V 41 w(fcn)30 b
+Fd(fcn)12 b Ff(\))150 4026 y Fg(IndefQuad)48 b Ff(\()p
+Fe(in)m(tegrand)p 1083 4026 V 41 w(fcn)30 b Fd(fcn)p
+Fe(,)i(double)d Fd(b)p Fe(,)i(In)m(tegralT)m(yp)s(e)g
+Fd(t)12 b Ff(\))150 4136 y Fg(IndefQuad)48 b Ff(\()p
+Fe(in)m(tegrand)p 1083 4136 V 41 w(fcn)30 b Fd(fcn)p
+Fe(,)i(double)d Fd(b)p Fe(,)i(In)m(tegralT)m(yp)s(e)g
+Fd(t)p Fe(,)g(double)f Fd(abs)p Fe(,)i(double)e Fd(rel)12
+b Ff(\))150 4245 y Fg(IndefQuad)48 b Ff(\()p Fe(in)m(tegrand)p
+1083 4245 V 41 w(fcn)30 b Fd(fcn)p Fe(,)i(double)d Fd(abs)p
+Fe(,)j(double)e Fd(rel)12 b Ff(\))150 4437 y Fo(10.1)68
+b(Collo)t(cation)47 b(W)-11 b(eigh)l(ts)150 4655 y Fg(CollocWt)48
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 4765 y Fg(CollocWt)g
+Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g Fd(inc_l)p
+Fe(,)h(in)m(t)f Fd(inc_r)12 b Ff(\))150 4874 y Fg(CollocWt)48
+b Ff(\()p Fe(in)m(t)31 b Fd(n)p Fe(,)g(in)m(t)g Fd(inc_l)p
+Fe(,)h(in)m(t)f Fd(inc_r)p Fe(,)h(double)e Fd(l)p Fe(,)h(double)f
+Fd(r)12 b Ff(\))150 4984 y Fg(CollocWt)48 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(double)f Fd(a)p Fe(,)h(double)f Fd(b)p
+Fe(,)h(in)m(t)f Fd(inc_l)p Fe(,)j(in)m(t)d Fd(inc_r)12
+b Ff(\))150 5094 y Fg(CollocWt)48 b Ff(\()p Fe(in)m(t)31
+b Fd(n)p Fe(,)g(in)m(t)g Fd(inc_l)p Fe(,)h(in)m(t)f Fd(inc_r)p
+Fe(,)h(double)e Fd(l)p Fe(,)h(double)f Fd(r)12 b Ff(\))150
+5203 y Fg(CollocWt)48 b Ff(\()p Fe(const)31 b(Collo)s(cWt&)p
+Ff(\))150 5372 y Fg(CollocWt&)55 b(operator)g(=)46 b
+Ff(\()p Fe(const)31 b(Collo)s(cWt&)p Ff(\))p eop end
+%%Page: 43 47
+TeXDict begin 43 46 bop 150 -116 a Fp(Chapter)30 b(10:)41
+b(Quadrature)2538 b(43)150 299 y Fg(CollocWt&)55 b(resize)47
+b Ff(\()p Fe(in)m(t)32 b Fd(ncol)12 b Ff(\))150 458 y
+Fg(CollocWt&)55 b(add_left)48 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 568 y Fg(CollocWt&)55 b(add_right)48 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 727 y Fg(CollocWt&)55 b(delete_left)49
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 837 y Fg(CollocWt&)55
+b(delete_right)49 b Ff(\()p Fe(v)m(oid)p Ff(\))150 996
+y Fg(CollocWt&)55 b(set_left)48 b Ff(\()p Fe(double)30
+b Fd(val)12 b Ff(\))150 1106 y Fg(CollocWt&)55 b(set_right)48
+b Ff(\()p Fe(double)31 b Fd(val)12 b Ff(\))150 1265 y
+Fg(CollocWt&)55 b(set_alpha)48 b Ff(\()p Fe(double)31
+b Fd(val)12 b Ff(\))150 1375 y Fg(CollocWt&)55 b(set_beta)48
+b Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150 1534 y
+Fg(int)53 b(ncol)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32 b
+Fe(const)150 1694 y Fg(int)53 b(left_included)d Ff(\()p
+Fe(v)m(oid)p Ff(\))31 b Fe(const)150 1803 y Fg(int)53
+b(right_included)d Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150
+1963 y Fg(double)54 b(left)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))31 b Fe(const)150 2072 y Fg(double)54 b(right)47
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2182 y
+Fg(double)54 b(width)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 2341 y Fg(double)54 b(alpha)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 2451 y Fg(double)54
+b(beta)47 b Ff(\()p Fe(v)m(oid)p Ff(\))31 b Fe(const)150
+2610 y Fg(ColumnVector)56 b(roots)47 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2720 y Fg(ColumnVector)56 b(quad)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 2829 y Fg(ColumnVector)56 b(quad_weights)49
+b Ff(\()p Fe(v)m(oid)p Ff(\))150 2989 y Fg(Matrix)54
+b(first)47 b Ff(\()p Fe(v)m(oid)p Ff(\))150 3098 y Fg(Matrix)54
+b(second)47 b Ff(\()p Fe(v)m(oid)p Ff(\))150 3258 y Fg(ostream&)55
+b(operator)f(<<)47 b Ff(\()p Fe(ostream)31 b(&)p Fd(os)p
+Fe(,)g(const)g(Collo)s(cWt)h(&)p Fd(c)12 b Ff(\))p eop
+end
+%%Page: 44 48
+TeXDict begin 44 47 bop 150 -116 a Fp(Chapter)30 b(11:)41
+b(Ordinary)29 b(Di\013eren)m(tial)k(Equations)1735 b(44)150
+299 y Fl(11)80 b(Ordinary)54 b(Di\013eren)l(tial)d(Equations)150
+608 y Fg(ODE_options)e Ff(\()p Fe(v)m(oid)p Ff(\))150
+717 y Fg(ODE_options)g Ff(\()p Fe(const)31 b(ODE)p 1252
+717 28 4 v 40 w(options)g(&)p Fd(opt)12 b Ff(\))150 877
+y Fg(ODE_options&)56 b(operator)f(=)45 b Ff(\()p Fe(const)32
+b(ODE)p 1880 877 V 40 w(options)e(&)p Fd(opt)12 b Ff(\))150
+1036 y Fg(void)54 b(init)46 b Ff(\()p Fe(v)m(oid)p Ff(\))150
+1196 y Fg(void)54 b(copy)46 b Ff(\()p Fe(const)31 b(ODE)p
+1147 1196 V 40 w(options)g(&)p Fd(opt)12 b Ff(\))150
+1355 y Fg(void)54 b(set_default_options)d Ff(\()p Fe(v)m(oid)p
+Ff(\))150 1514 y Fg(void)j(set_absolute_tolerance)e Ff(\()p
+Fe(double)30 b Fd(val)12 b Ff(\))150 1674 y Fg(void)54
+b(set_initial_step_size)d Ff(\()p Fe(double)31 b Fd(val)12
+b Ff(\))150 1833 y Fg(void)54 b(set_maximum_step_size)d
+Ff(\()p Fe(double)31 b Fd(val)12 b Ff(\))150 1993 y Fg(void)54
+b(set_minimum_step_size)d Ff(\()p Fe(double)31 b Fd(val)12
+b Ff(\))150 2152 y Fg(void)54 b(set_relative_tolerance)e
+Ff(\()p Fe(double)30 b Fd(val)12 b Ff(\))150 2311 y Fg(double)54
+b(absolute_tolerance)d Ff(\()p Fe(v)m(oid)p Ff(\))150
+2421 y Fg(double)j(initial_step_size)d Ff(\()p Fe(v)m(oid)p
+Ff(\))150 2531 y Fg(double)j(maximum_step_size)d Ff(\()p
+Fe(v)m(oid)p Ff(\))150 2640 y Fg(double)j(minimum_step_size)d
+Ff(\()p Fe(v)m(oid)p Ff(\))150 2750 y Fg(double)j(relative_tolerance)d
+Ff(\()p Fe(v)m(oid)p Ff(\))150 2909 y Fg(ODE)46 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 3019 y Fg(ODE)g Ff(\()p Fe(in)m(t)32
+b Fd(n)12 b Ff(\))150 3128 y Fg(ODE)46 b Ff(\()p Fe(const)32
+b(ColumnV)-8 b(ector)31 b(&)p Fd(state)p Fe(,)h(double)e
+Fd(time)p Fe(,)h(const)g(ODEF)-8 b(unc)31 b(&)p Fd(f)12
+b Ff(\))150 3288 y Fg(virtual)54 b(int)g(size)46 b Ff(\()p
+Fe(v)m(oid)p Ff(\))32 b Fe(const)150 3447 y Fg(virtual)54
+b(ColumnVector)i(state)47 b Ff(\()p Fe(v)m(oid)p Ff(\))32
+b Fe(const)150 3606 y Fg(virtual)54 b(double)h(time)46
+b Ff(\()p Fe(v)m(oid)p Ff(\))32 b Fe(const)150 3766 y
+Fg(virtual)54 b(void)g(force_restart)49 b Ff(\()p Fe(v)m(oid)p
+Ff(\))150 3925 y Fg(virtual)54 b(void)g(initialize)48
+b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p
+Fe(,)f(double)g Fd(t)12 b Ff(\))150 4085 y Fg(virtual)54
+b(void)g(set_stop_time)49 b Ff(\()p Fe(double)31 b Fd(t)12
+b Ff(\))150 4244 y Fg(virtual)54 b(void)g(clear_stop_time)c
+Ff(\()p Fe(v)m(oid)p Ff(\))150 4403 y Fg(virtual)k(ColumnVector)i
+(integrate)49 b Ff(\()p Fe(double)30 b Fd(t)12 b Ff(\))150
+4563 y Fg(void)54 b(integrate)48 b Ff(\()p Fe(in)m(t)31
+b Fd(nsteps)p Fe(,)h(double)e Fd(tstep)p Fe(,)i(ostream)g(&)p
+Fd(s)12 b Ff(\))150 4722 y Fg(Matrix)54 b(integrate)48
+b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(tout)12
+b Ff(\))150 4832 y Fg(Matrix)54 b(integrate)48 b Ff(\()p
+Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(tout)p Fe(,)g(const)g
+(ColumnV)-8 b(ector)31 b(&)p Fd(tcrit)12 b Ff(\))p eop
+end
+%%Page: 45 49
+TeXDict begin 45 48 bop 150 -116 a Fp(Chapter)30 b(12:)41
+b(Di\013eren)m(tial)33 b(Algebraic)f(Equations)1720 b(45)150
+299 y Fl(12)80 b(Di\013eren)l(tial)52 b(Algebraic)g(Equations)150
+608 y Fg(DAE)46 b Ff(\()p Fe(v)m(oid)p Ff(\))150 717
+y Fg(DAE)g Ff(\()p Fe(in)m(t)32 b Fd(n)12 b Ff(\))150
+827 y Fg(DAE)46 b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31
+b(&)p Fd(x)p Fe(,)f(double)g Fd(time)p Fe(,)i(D)m(AEF)-8
+b(unc)32 b(&)p Fd(f)12 b Ff(\))150 936 y Fg(DAE)46 b
+Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p
+Fe(,)f(ColumnV)-8 b(ector)32 b(&)p Fd(xdot)p Fe(,)f(double)f
+Fd(time)p Fe(,)i(D)m(AEF)-8 b(unc)31 b(&)p Fd(f)12 b
+Ff(\))150 1096 y Fg(ColumnVector)56 b(deriv)47 b Ff(\()p
+Fe(v)m(oid)p Ff(\))150 1255 y Fg(virtual)54 b(void)g(initialize)48
+b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(x)p
+Fe(,)f(double)g Fd(t)12 b Ff(\))150 1365 y Fg(virtual)54
+b(void)g(initialize)48 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(x)p Fe(,)f(ColumnV)-8 b(ector)32
+b(&)p Fd(xdot)p Fe(,)565 1474 y(double)e Fd(t)12 b Ff(\))150
+1634 y Fg(ColumnVector)56 b(integrate)48 b Ff(\()p Fe(double)30
+b Fd(t)12 b Ff(\))150 1793 y Fg(Matrix)54 b(integrate)48
+b Ff(\()p Fe(const)32 b(ColumnV)-8 b(ector)31 b(&)p Fd(tout)p
+Fe(,)g(Matrix)h(&)p Fd(xdot_out)12 b Ff(\))150 1903 y
+Fg(Matrix)54 b(integrate)48 b Ff(\()p Fe(const)32 b(ColumnV)-8
+b(ector)31 b(&)p Fd(tout)p Fe(,)g(Matrix)h(&)p Fd(xdot_out)p
+Fe(,)g(const)565 2012 y(ColumnV)-8 b(ector)31 b(&)p Fd(tcrit)12
+b Ff(\))p eop end
+%%Page: 46 50
+TeXDict begin 46 49 bop 150 -116 a Fp(Chapter)30 b(13:)41
+b(Error)30 b(Handling)2393 b(46)150 299 y Fl(13)80 b(Error)53
+b(Handling)p eop end
+%%Page: 47 51
+TeXDict begin 47 50 bop 150 -116 a Fp(Chapter)30 b(14:)41
+b(Installation)2548 b(47)150 299 y Fl(14)80 b(Installation)p
+eop end
+%%Page: 48 52
+TeXDict begin 48 51 bop 150 -116 a Fp(Chapter)30 b(15:)41
+b(Bugs)2803 b(48)150 299 y Fl(15)80 b(Bugs)p eop end
+%%Page: 49 53
+TeXDict begin 49 52 bop 150 -116 a Fp(Concept)31 b(Index)2927
+b(49)150 299 y Fl(Concept)52 b(Index)150 638 y Fo(A)150
+754 y Fb(ac)n(kno)n(wledgemen)n(ts)17 b Fa(:)d(:)f(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)44 b Fb(1)150 842 y(arra)n(ys)15
+b Fa(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)41 b Fb(14)150 1091 y Fo(B)150
+1208 y Fb(b)r(ounds)14 b Fa(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)40 b Fb(39)150
+1295 y(bugs,)26 b(kno)n(wn)11 b Fa(:)i(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)37 b Fb(48)150 1545 y
+Fo(C)150 1661 y Fb(collo)r(cation)28 b(w)n(eigh)n(ts)c
+Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)49 b Fb(42)150
+1748 y(con)n(tributors)18 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)45 b Fb(1)150 1835
+y(cop)n(yrigh)n(t)14 b Fa(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)41 b Fb(1)150
+2085 y Fo(D)150 2201 y Fb(D)n(AE)17 b Fa(:)c(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)44
+b Fb(45)150 2435 y Fo(F)150 2551 y Fb(factorizations)12
+b Fa(:)k(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)38
+b Fb(32)150 2784 y Fo(I)150 2900 y Fb(installation)15
+b Fa(:)g(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)41 b Fb(47)150 2987 y(installation)27 b(trouble)20
+b Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)46 b Fb(48)150
+3075 y(in)n(tegration)22 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)47 b Fb(42)150 3162
+y(in)n(tro)r(duction)13 b Fa(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)39 b Fb(13)150 3395 y Fo(K)150
+3511 y Fb(kno)n(wn)25 b(causes)i(of)f(trouble)d Fa(:)13
+b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)49 b Fb(48)150 3745 y Fo(L)150 3861
+y Fb(linear)27 b(Constrain)n(ts)c Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)48 b Fb(40)150 4094 y Fo(M)150 4210 y Fb(matrix)26
+b(factorizations)6 b Fa(:)16 b(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)33
+b Fb(32)2025 638 y(matrix)26 b(manipulations)12 b Fa(:)h(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)38 b Fb(18)2025 900 y Fo(N)2025 1021 y
+Fb(NLP)21 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)48 b Fb(41)2025
+1110 y(nonlinear)26 b(Constrain)n(ts)12 b Fa(:)i(:)f(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)38 b Fb(40)2025 1200 y(nonlinear)26 b(equations)12
+b Fa(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)38 b Fb(38)2025
+1289 y(nonlinear)26 b(functions)18 b Fa(:)c(:)f(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)45 b Fb(37)2025 1379 y(nonlinear)26 b(programming)15
+b Fa(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)42 b Fb(41)2025 1468 y(n)n(umerical)26
+b(in)n(tegration)15 b Fa(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)42
+b Fb(42)2025 1730 y Fo(O)2025 1851 y Fb(ob)t(jectiv)n(e)26
+b(functions)7 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)33
+b Fb(39)2025 1940 y(ODE)15 b Fa(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)42
+b Fb(44)2025 2030 y(optimization)9 b Fa(:)14 b(:)f(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)35 b Fb(39)2025
+2119 y(orthogonal)27 b(collo)r(cation)21 b Fa(:)13 b(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)45 b Fb(42)2025 2381 y Fo(Q)2025 2501 y Fb(QP)11
+b Fa(:)h(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)37 b Fb(40)2025
+2591 y(quadratic)25 b(programming)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)38
+b Fb(40)2025 2681 y(quadrature)18 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)45 b Fb(42)2025
+2942 y Fo(R)2025 3063 y Fb(ranges)11 b Fa(:)j(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)37
+b Fb(36)2025 3325 y Fo(T)2025 3445 y Fb(troublesho)r(oting)10
+b Fa(:)k(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)36
+b Fb(48)2025 3707 y Fo(V)2025 3828 y Fb(v)n(ector)25
+b(manipulations)e Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)48
+b Fb(18)2025 4089 y Fo(W)2025 4210 y Fb(w)n(arran)n(t)n(y)21
+b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)49 b Fb(1)p eop end
+%%Page: 50 54
+TeXDict begin 50 53 bop 150 -116 a Fp(F)-8 b(unction)31
+b(Index)2906 b(50)150 299 y Fl(F)-13 b(unction)52 b(Index)150
+610 y Fo(A)150 728 y Fh(absolute_tolerance)10 b Fa(:)17
+b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)37 b Fb(42,)26 b(44)150 816 y Fh(add_left)12
+b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)38 b Fb(43)150 905 y Fh(add_right)9 b
+Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)36 b Fb(43)150 993 y Fh(AEPBALANCE)7 b Fa(:)15
+b(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+33 b Fb(32)150 1081 y Fh(all)14 b Fa(:)g(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)41
+b Fb(20,)26 b(27)150 1169 y Fh(alpha)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46
+b Fb(43)150 1257 y Fh(any)14 b Fa(:)g(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)41
+b Fb(20,)26 b(27)150 1346 y Fh(append)9 b Fa(:)14 b(:)f(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)36 b Fb(18,)26 b(22,)h(24,)g(25,)f(29)150 1434
+y Fh(Array<T>)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)38 b Fb(14)150 1522 y
+Fh(Array2<T>)9 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)36 b Fb(15)150 1610 y Fh(Array3<T>)9
+b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)36 b Fb(15)150 1867 y Fo(B)150 1985 y Fh(balanced_a_matrix)
+6 b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32
+b Fb(33)150 2073 y Fh(balanced_b_matrix)6 b Fa(:)17 b(:)c(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)32 b Fb(33)150 2162 y Fh(balanced_matrix)11
+b Fa(:)17 b(:)c(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)38
+b Fb(32)150 2250 y Fh(balancing_matrix)9 b Fa(:)16 b(:)e(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)35 b Fb(32)150 2338 y Fh(base)23
+b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)49 b Fb(36)150 2426 y
+Fh(beta)23 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)49 b Fb(43)150
+2514 y Fh(Bounds)17 b Fa(:)e(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)43 b Fb(39)150
+2752 y Fo(C)150 2870 y Fh(capacity)27 b Fb(on)f Fh(Array<T>)11
+b Fa(:)k(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)37 b Fb(14)150 2959 y
+Fh(checkelem)28 b Fb(on)d Fh(Array<T>)8 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+35 b Fb(14)150 3047 y Fh(checkelem)28 b Fb(on)d Fh(Array2<T>)g
+Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)49 b Fb(15)150 3135 y Fh(checkelem)28
+b Fb(on)d Fh(Array3<T>)g Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)49 b Fb(15)150
+3223 y Fh(checkelem)28 b Fb(on)d Fh(DiagArray<T>)15 b
+Fa(:)h(:)d(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)41 b Fb(16)150 3311 y Fh(CHOL)23 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)49 b Fb(33)150 3400 y Fh(chol_matrix)24 b Fa(:)13
+b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)48
+b Fb(33)150 3488 y Fh(clear_stop_time)11 b Fa(:)17 b(:)c(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)38 b Fb(44)150 3576 y Fh(coefficient)24
+b Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+48 b Fb(32)150 3664 y Fh(CollocWt)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)38
+b Fb(42)150 3752 y Fh(cols)27 b Fb(on)e Fh(Array2<T>)c
+Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)45 b Fb(15)150
+3841 y Fh(cols)27 b Fb(on)e Fh(DiagArray<T>)11 b Fa(:)16
+b(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)37 b Fb(16)150 3929 y Fh(column)21
+b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)46
+b Fb(18,)27 b(23,)g(25,)f(30)150 4017 y Fh(column_max)13
+b Fa(:)j(:)d(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)40
+b Fb(20,)26 b(27)150 4105 y Fh(column_max_loc)d Fa(:)14
+b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)47 b Fb(20,)26 b(27)150
+4193 y Fh(column_min)13 b Fa(:)j(:)d(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)40 b Fb(20,)26 b(27)150 4282 y Fh(column_min_loc)d
+Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)47 b Fb(20,)26
+b(27)150 4370 y Fh(columns)h Fb(on)f Fh(Array2<T>)11
+b Fa(:)k(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)37 b Fb(15)150 4458 y
+Fh(columns)27 b Fb(on)f Fh(DiagArray<T>)d Fa(:)13 b(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)47
+b Fb(16)150 4546 y Fh(ColumnVector)22 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)45 b Fb(20)150 4634
+y Fh(ComplexAEPBALANCE)6 b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)32 b Fb(32)150 4723 y Fh(ComplexCHOL)24 b Fa(:)13
+b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)48
+b Fb(33)150 4811 y Fh(ComplexColumnVector)18 b Fa(:)g(:)13
+b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)44 b Fb(27)150 4899 y Fh(ComplexDET)7
+b Fa(:)15 b(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)33 b Fb(32)150 4987 y Fh(ComplexDiagMatrix)6
+b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32 b Fb(30)150
+5075 y Fh(ComplexHESS)24 b Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)48 b Fb(33)150 5164 y Fh(ComplexLU)9
+b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)36 b Fb(35)150 5252 y Fh(ComplexMatrix)16
+b Fa(:)g(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)43
+b Fb(24)150 5340 y Fh(ComplexQR)9 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)36 b
+Fb(35)2025 610 y Fh(ComplexRowVector)9 b Fa(:)16 b(:)d(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)35 b Fb(28)2025 701 y Fh(ComplexSCHUR)21
+b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)45
+b Fb(34)2025 792 y Fh(ComplexSVD)7 b Fa(:)15 b(:)e(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)33 b Fb(34)2025
+882 y Fh(conj)7 b Fa(:)14 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)34 b Fb(25,)27 b(28,)f(29,)h(30)2025 973 y Fh
+(constraint_matrix)6 b Fa(:)17 b(:)c(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)33
+b Fb(40)2025 1064 y Fh(copy)18 b Fa(:)c(:)f(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)45 b Fb(38,)26 b(42,)h(44)2025
+1154 y Fh(cumprod)22 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)47 b Fb(20,)27 b(27)2025 1245
+y Fh(cumsum)6 b Fa(:)15 b(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)33 b Fb(20,)27 b(27)2025
+1513 y Fo(D)2025 1636 y Fh(DAE)8 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)34 b Fb(45)2025 1726 y Fh(data)26 b Fb(on)g Fh(Array<T>)d
+Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)48
+b Fb(15)2025 1817 y Fh(DefQuad)15 b Fa(:)f(:)f(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)41
+b Fb(42)2025 1908 y Fh(delete_left)24 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)48 b Fb(43)2025
+1998 y Fh(delete_right)21 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)45 b Fb(43)2025 2089 y Fh(deriv)21
+b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)46 b Fb(45)2025 2180 y Fh(DET)8
+b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)34 b Fb(32)2025
+2270 y Fh(determinant)11 b Fa(:)k(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)37 b Fb(18,)27 b(25)2025 2361 y Fh(diag)7
+b Fa(:)14 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)34
+b Fb(20,)27 b(24,)f(27,)h(31)2025 2452 y Fh(DiagArray<T>)21
+b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)45
+b Fb(15)2025 2542 y Fh(DiagMatrix)13 b Fa(:)i(:)f(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)40 b Fb(22,)27 b(23)2025
+2633 y Fh(dim1)f Fb(on)g Fh(Array2<T>)20 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)45 b Fb(15)2025 2724 y Fh(dim1)26
+b Fb(on)g Fh(Array3<T>)20 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)45 b Fb(15)2025 2814 y Fh(dim1)26 b Fb(on)g Fh(DiagArray<T>)11
+b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)37 b Fb(16)2025 2905
+y Fh(dim2)26 b Fb(on)g Fh(Array2<T>)20 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)45 b Fb(15)2025 2996 y Fh(dim2)26 b Fb(on)g
+Fh(Array3<T>)20 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)45
+b Fb(15)2025 3086 y Fh(dim2)26 b Fb(on)g Fh(DiagArray<T>)11
+b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)37 b Fb(16)2025 3177
+y Fh(dim3)26 b Fb(on)g Fh(Array3<T>)20 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)45 b Fb(15)2025 3447 y Fo(E)2025 3570
+y Fh(EIG)8 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)34
+b Fb(34)2025 3661 y Fh(eigenvalues)24 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)48 b Fb(34)2025
+3751 y Fh(eigenvectors)21 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)45 b Fb(34)2025 3842 y Fh(elem)26
+b Fb(on)g Fh(Array<T>)d Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)48 b Fb(14)2025 3933 y Fh(elem)26 b Fb(on)g Fh(Array2<T>)20
+b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)45 b Fb(15)2025
+4023 y Fh(elem)26 b Fb(on)g Fh(Array3<T>)20 b Fa(:)14
+b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)45 b Fb(15)2025
+4114 y Fh(elem)26 b Fb(on)g Fh(DiagArray<T>)11 b Fa(:)16
+b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)37 b Fb(16)2025 4205 y Fh
+(eq_constraint_matrix)16 b Fa(:)h(:)c(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)42
+b Fb(40)2025 4295 y Fh(eq_constraint_vector)16 b Fa(:)h(:)c(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)42 b Fb(40)2025 4386 y Fh(exponent)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)39
+b Fb(32)2025 4477 y Fh(extract)8 b Fa(:)15 b(:)e(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)35 b Fb(18,)27 b(21,)g(22,)f(23,)h(25,)g(28,)f
+(29,)h(30)2025 4744 y Fo(F)2025 4867 y Fh(fill)16 b Fa(:)e(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)42
+b Fb(18,)27 b(21,)g(22,)f(23,)h(24,)g(27,)f(29,)h(30)2025
+4958 y Fh(first)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)46 b
+Fb(43)2025 5049 y Fh(force_restart)16 b Fa(:)g(:)d(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)43 b Fb(44)2025 5139 y Fh(fourier)22
+b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)47 b Fb(18,)27 b(25)2025 5230 y Fh(function)12 b
+Fa(:)j(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)39 b Fb(37)p eop end
+%%Page: 51 55
+TeXDict begin 51 54 bop 150 -116 a Fp(F)-8 b(unction)31
+b(Index)2906 b(51)150 299 y Fo(G)150 416 y Fh(GEPBALANCE)7
+b Fa(:)15 b(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)33 b Fb(32)150 504 y Fh(gradient_function)6 b
+Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32 b Fb(39)150
+759 y Fo(H)150 876 y Fh(HESS)23 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)49
+b Fb(33)150 964 y Fh(hess_matrix)24 b Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)48 b Fb(33)150 1209
+y Fo(I)150 1326 y Fh(ifourier)18 b Fa(:)d(:)f(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)45 b Fb(18,)26 b(25)150
+1414 y Fh(imag)7 b Fa(:)14 b(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)34 b Fb(25,)27 b(28,)g(29,)f(30)150 1502 y
+Fh(inc)8 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)34
+b Fb(36)150 1590 y Fh(IndefQuad)9 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)36 b
+Fb(42)150 1678 y Fh(ineq_constraint_matrix)10 b Fa(:)19
+b(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)37 b Fb(40)150 1765 y Fh(ineq_constraint_vector)10
+b Fa(:)19 b(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)37 b Fb(40)150 1853 y Fh(init)18
+b Fa(:)c(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)45 b Fb(38,)27 b(42,)f(44)150 1941 y Fh(initial_step_size)6
+b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32 b Fb(44)150
+2029 y Fh(initialize)13 b Fa(:)j(:)d(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)40 b Fb(44,)26 b(45)150 2117 y Fh(insert)15
+b Fa(:)f(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)42 b Fb(18,)27 b(21,)f(22,)h(24,)g(27,)f(28)150
+2204 y Fh(integrate)e Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+49 b Fb(42,)27 b(44,)f(45)150 2292 y Fh(inverse)17 b
+Fa(:)d(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)43 b Fb(18,)27
+b(23,)g(25,)f(30)150 2545 y Fo(J)150 2662 y Fh(jacobian_function)6
+b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32 b Fb(37)150
+2917 y Fo(L)150 3034 y Fh(L)13 b Fa(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)39 b Fb(35)150 3122 y Fh(left)23 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)49 b Fb(43)150 3210 y Fh(left_balancing_matrix)13
+b Fa(:)18 b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)39 b Fb(33)150 3298 y
+Fh(left_included)16 b Fa(:)g(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)43 b Fb(43)150 3385 y Fh(left_singular_matrix)16
+b Fa(:)h(:)c(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)42 b Fb(34)150 3473 y Fh(length)27
+b Fb(on)f Fh(Array<T>)16 b Fa(:)f(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)42
+b Fb(14)150 3561 y Fh(limit)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46
+b Fb(36)150 3649 y Fh(LinConst)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)38 b
+Fb(40)150 3737 y Fh(lower_bound)24 b Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)48 b Fb(39)150 3824
+y Fh(lower_bounds)22 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)45 b Fb(39)150 3912 y Fh(lssolve)10
+b Fa(:)15 b(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)37
+b Fb(19,)27 b(25,)f(26)150 4000 y Fh(LU)10 b Fa(:)k(:)f(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)37 b Fb(35)150 4236 y Fo(M)150 4353 y
+Fh(map)23 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)50 b Fb(20,)27
+b(21,)f(22,)h(27,)g(28,)f(29)150 4441 y Fh(Matrix)17
+b Fa(:)e(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)43 b Fb(18)150 4529 y Fh(max)16
+b Fa(:)e(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)43 b
+Fb(21,)26 b(22,)h(28,)g(29,)f(36)150 4617 y Fh(maximum_step_size)6
+b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32 b Fb(44)150
+4705 y Fh(min)16 b Fa(:)e(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)43
+b Fb(21,)26 b(22,)h(28,)g(29,)f(36)150 4792 y Fh(minimize)18
+b Fa(:)d(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)45
+b Fb(40,)26 b(41)150 4880 y Fh(minimum_step_size)6 b
+Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)32 b Fb(44)150
+5135 y Fo(N)150 5252 y Fh(ncol)23 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)49
+b Fb(43)150 5340 y Fh(nelem)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46
+b Fb(36)2025 299 y Fh(NLConst)15 b Fa(:)f(:)f(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)41
+b Fb(40)2025 389 y Fh(NLEqn)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)46
+b Fb(38)2025 479 y Fh(NLEqn_options)16 b Fa(:)g(:)d(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)43 b Fb(38)2025 570 y Fh(NLFunc)17
+b Fa(:)d(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)44 b Fb(37)2025 660 y Fh(NLP)8
+b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)34 b Fb(41)2025
+909 y Fo(O)2025 1031 y Fh(Objective)9 b Fa(:)15 b(:)f(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)36
+b Fb(39)2025 1121 y Fh(objective_function)25 b Fa(:)13
+b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)47 b Fb(39)2025 1212 y
+Fh(ODE)8 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)34
+b Fb(44)2025 1302 y Fh(ODE_options)24 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)48 b Fb(44)2025
+1392 y Fh(operator)27 b(!)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)46 b Fb(19,)27 b(26)2025 1483
+y Fh(operator)g(!=)22 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)48
+b Fb(18,)27 b(21,)g(22,)f(23,)h(24,)g(27,)f(28,)h(30)2025
+1573 y Fh(operator)g(\(\))f Fb(on)g Fh(Array<T>)10 b
+Fa(:)15 b(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)37 b Fb(14)2025 1663 y Fh(operator)27
+b(\(\))f Fb(on)g Fh(Array2<T>)7 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)34
+b Fb(15)2025 1753 y Fh(operator)27 b(\(\))f Fb(on)g Fh(Array3<T>)7
+b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)34 b Fb(15)2025 1844 y Fh(operator)27
+b(\(\))f Fb(on)g Fh(DiagArray<T>)17 b Fa(:)f(:)d(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)43 b Fb(16)2025 1934
+y Fh(operator)27 b(*)9 b Fa(:)14 b(:)f(:)36 b Fb(16,)27
+b(17,)g(19,)g(20,)f(21,)h(22,)g(23,)f(24,)h(26,)g(28,)2178
+2021 y(29,)g(31)2025 2111 y Fh(operator)g(+)9 b Fa(:)14
+b(:)f(:)36 b Fb(16,)27 b(17,)g(19,)g(20,)f(21,)h(22,)g(23,)f(24,)h(26,)
+g(28,)2178 2199 y(29,)g(30,)g(31)2025 2289 y Fh(operator)g(+=)22
+b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)48 b Fb(19,)27
+b(21,)g(22,)f(23,)h(26,)g(28,)f(29,)h(30)2025 2379 y
+Fh(operator)g(-)9 b Fa(:)14 b(:)f(:)36 b Fb(16,)27 b(17,)g(19,)g(20,)f
+(21,)h(22,)g(23,)f(24,)h(26,)g(28,)2178 2466 y(29,)g(30,)g(31)2025
+2556 y Fh(operator)g(-=)22 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)48
+b Fb(19,)27 b(21,)g(22,)f(23,)h(26,)g(28,)f(29,)h(30)2025
+2647 y Fh(operator)g(/)21 b Fa(:)13 b(:)g(:)47 b Fb(16,)26
+b(17,)h(19,)g(21,)g(22,)f(23,)h(26,)g(28,)f(29,)h(31)2025
+2737 y Fh(operator)g(<<)10 b Fa(:)k(:)36 b Fb(20,)26
+b(21,)g(22,)h(24,)f(27,)g(28,)g(29,)g(31,)g(32,)g(33,)2178
+2824 y(34,)h(35,)g(36,)g(39,)f(40,)h(43)2025 2914 y Fh(operator)g(=)9
+b Fa(:)14 b(:)f(:)36 b Fb(18,)27 b(20,)g(21,)g(23,)f(24,)h(27,)g(28,)f
+(30,)h(32,)g(33,)2178 3002 y(34,)g(35,)g(37,)g(38,)f(39,)h(40,)g(41,)f
+(42,)h(44)2025 3092 y Fh(operator)g(=)f Fb(on)g Fh(Array<T>)13
+b Fa(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)39 b Fb(14)2025 3182 y Fh(operator)27
+b(=)f Fb(on)g Fh(Array2<T>)10 b Fa(:)15 b(:)e(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)37
+b Fb(15)2025 3272 y Fh(operator)27 b(=)f Fb(on)g Fh(Array3<T>)10
+b Fa(:)15 b(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)37 b Fb(15)2025 3363 y Fh(operator)27
+b(=)f Fb(on)g Fh(DiagArray<T>&)17 b Fa(:)f(:)d(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)43 b Fb(15)2025 3453
+y Fh(operator)27 b(==)22 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)48
+b Fb(18,)27 b(21,)g(22,)f(23,)h(24,)g(27,)f(28,)h(30)2025
+3543 y Fh(operator)g(>>)7 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)34 b Fb(20,)26 b(27,)h(36)2025 3811 y Fo(P)2025 3933
+y Fh(P)13 b Fa(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)39
+b Fb(35)2025 4024 y Fh(print_range)24 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)48 b Fb(36)2025
+4114 y Fh(prod)12 b Fa(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)38 b Fb(20,)27 b(27)2025
+4204 y Fh(product)22 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)48
+b Fb(16,)26 b(17,)h(20,)g(21,)g(22,)f(24,)h(26,)g(28,)f(29,)h(31)2025
+4472 y Fo(Q)2025 4594 y Fh(Q)13 b Fa(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)39 b Fb(35)2025 4684 y Fh(QP)10 b Fa(:)k(:)f(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)37 b Fb(40)2025 4775 y Fh(QR)10 b Fa(:)k(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)37 b Fb(35)2025 4865 y Fh(quad)23 b Fa(:)13
+b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)49 b Fb(43)2025 4955 y Fh(Quad)23
+b Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)49 b Fb(42)2025 5045
+y Fh(Quad_options)21 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)45 b Fb(42)2025 5136 y Fh(quad_weights)21
+b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)45
+b Fb(43)2025 5226 y Fh(quotient)24 b Fa(:)13 b(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)49 b Fb(16,)27 b(17,)g(20,)f(21,)h(22,)g(26,)f(28,)h
+(29)p eop end
+%%Page: 52 56
+TeXDict begin 52 55 bop 150 -116 a Fp(F)-8 b(unction)31
+b(Index)2906 b(52)150 299 y Fo(R)150 416 y Fh(R)13 b
+Fa(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)39 b Fb(35)150
+504 y Fh(Range)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46 b
+Fb(36)150 591 y Fh(real)7 b Fa(:)14 b(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)34 b Fb(25,)27 b(28,)g(29,)f(30)150
+679 y Fh(relative_tolerance)10 b Fa(:)17 b(:)c(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)37
+b Fb(42,)26 b(44)150 767 y Fh(resize)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)46 b Fb(38,)27 b(39,)g(40,)f(43)150
+854 y Fh(resize)h Fb(on)f Fh(Array<T>)16 b Fa(:)f(:)e(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)42 b Fb(14)150 942 y Fh(resize)27 b Fb(on)f
+Fh(Array2<T>)13 b Fa(:)i(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)40
+b Fb(15)150 1030 y Fh(resize)27 b Fb(on)f Fh(Array3<T>)13
+b Fa(:)i(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)40 b Fb(15)150 1117
+y Fh(resize)27 b Fb(on)f Fh(DiagArray<T>)f Fa(:)13 b(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)49
+b Fb(16)150 1205 y Fh(right)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46
+b Fb(43)150 1293 y Fh(right_balancing_matrix)10 b Fa(:)19
+b(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)37 b Fb(33)150 1380 y Fh(right_included)14
+b Fa(:)i(:)d(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)40
+b Fb(43)150 1468 y Fh(right_singular_matrix)13 b Fa(:)18
+b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)39 b Fb(34)150 1556 y Fh(roots)21
+b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)46 b Fb(43)150 1643 y Fh(row)10
+b Fa(:)k(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)36
+b Fb(18,)27 b(23,)g(25,)f(30)150 1731 y Fh(row_max)d
+Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)48 b Fb(20,)26 b(27)150 1819 y Fh(row_max_loc)11
+b Fa(:)k(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)38
+b Fb(20,)26 b(27)150 1906 y Fh(row_min)d Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)48 b Fb(20,)26
+b(27)150 1994 y Fh(row_min_loc)11 b Fa(:)k(:)f(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)38 b Fb(20,)26 b(27)150 2082 y Fh(rows)h
+Fb(on)e Fh(Array2<T>)c Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)45
+b Fb(15)150 2170 y Fh(rows)27 b Fb(on)e Fh(DiagArray<T>)11
+b Fa(:)16 b(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)37 b Fb(16)150 2257
+y Fh(RowVector)9 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)36 b Fb(21)150 2493 y
+Fo(S)150 2610 y Fh(SCHUR)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)46
+b Fb(33)150 2697 y Fh(schur_matrix)22 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)45 b Fb(34)150 2785
+y Fh(second)17 b Fa(:)e(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)43 b Fb(43)150 2873
+y Fh(set_absolute_tolerance)17 b Fa(:)h(:)13 b(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)44 b Fb(42,)26
+b(44)150 2960 y Fh(set_alpha)9 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)36 b Fb(43)150
+3048 y Fh(set_base)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)38 b Fb(36)150 3136
+y Fh(set_beta)12 b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)38 b Fb(43)150 3223 y
+Fh(set_bound)9 b Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)36 b Fb(39)150 3311 y Fh(set_bounds)7
+b Fa(:)15 b(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)33 b Fb(39)150 3399 y Fh(set_constraint_matrix)13
+b Fa(:)18 b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)39 b Fb(40)150 3486 y
+Fh(set_default_options)14 b Fa(:)j(:)c(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)41 b Fb(38,)27 b(42,)f(44)150
+3574 y Fh(set_function)c Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)45 b Fb(37)150 3662 y Fh(set_gradient_function)13
+b Fa(:)18 b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)39 b Fb(39)150 3749 y
+Fh(set_inc)15 b Fa(:)f(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)41 b Fb(36)150 3837 y
+Fh(set_initial_step_size)13 b Fa(:)18 b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)39
+b Fb(44)150 3925 y Fh(set_jacobian_function)13 b Fa(:)18
+b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)39 b Fb(37)150 4013 y Fh(set_left)12
+b Fa(:)j(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)38 b Fb(43)150 4100 y Fh(set_limit)9 b
+Fa(:)16 b(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)36 b Fb(36)150 4188 y Fh(set_lower_bound)11
+b Fa(:)17 b(:)c(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)38
+b Fb(39)150 4276 y Fh(set_lower_bounds)9 b Fa(:)16 b(:)e(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)35 b Fb(39)150 4363 y Fh(set_maximum_step_size)
+13 b Fa(:)18 b(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)39 b Fb(44)2025 299
+y Fh(set_minimum_step_size)13 b Fa(:)18 b(:)13 b(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)40
+b Fb(44)2025 386 y Fh(set_objective_function)10 b Fa(:)18
+b(:)c(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)37 b Fb(39)2025 473 y Fh(set_relative_tolerance)17
+b Fa(:)h(:)13 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)43 b Fb(42,)27 b(44)2025 561 y Fh(set_right)9
+b Fa(:)15 b(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)36 b Fb(43)2025 648 y Fh(set_states)7 b Fa(:)15
+b(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+33 b Fb(38)2025 735 y Fh(set_stop_time)16 b Fa(:)g(:)d(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)43 b Fb(44)2025 823 y
+Fh(set_tolerance)16 b Fa(:)g(:)d(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)43 b Fb(38)2025 910 y Fh(set_upper_bound)11
+b Fa(:)17 b(:)c(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)38
+b Fb(39)2025 997 y Fh(set_upper_bounds)9 b Fa(:)16 b(:)d(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)35 b Fb(39)2025 1085 y Fh(singular_values)11
+b Fa(:)17 b(:)c(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)38
+b Fb(34)2025 1172 y Fh(size)7 b Fa(:)14 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)34 b Fb(38,)27 b(39,)f(41,)h(44)2025
+1259 y Fh(solve)c Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+48 b Fb(18,)27 b(19,)f(25,)h(38)2025 1346 y Fh(sort)c
+Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)49 b Fb(36)2025 1434
+y Fh(stack)23 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)
+48 b Fb(18,)27 b(21,)f(25,)h(27)2025 1521 y Fh(state)21
+b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)46 b Fb(44)2025 1608 y Fh(states)17
+b Fa(:)d(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)44 b Fb(38)2025 1696 y Fh(sum)14
+b Fa(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)
+g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)40 b Fb(20,)27 b(27)2025 1783
+y Fh(sumsq)9 b Fa(:)14 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)35 b Fb(20,)27 b(27)2025
+1870 y Fh(SVD)8 b Fa(:)13 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f
+(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)34
+b Fb(34)2025 2104 y Fo(T)2025 2220 y Fh(time)23 b Fa(:)13
+b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)49 b Fb(44)2025 2307 y Fh(tolerance)9
+b Fa(:)15 b(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g
+(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)
+f(:)g(:)g(:)36 b Fb(38)2025 2394 y Fh(transpose)22 b
+Fa(:)13 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)47 b
+Fb(18,)27 b(21,)g(22,)f(23,)h(25,)g(27,)f(29,)h(30)2025
+2646 y Fo(U)2025 2763 y Fh(U)13 b Fa(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)39 b Fb(35)2025 2850 y Fh(unitary_hess_matrix)18
+b Fa(:)f(:)c(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)45 b Fb(33)2025 2937
+y Fh(unitary_matrix)14 b Fa(:)i(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)40 b Fb(34)2025 3025 y Fh(upper_bound)24 b Fa(:)13
+b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)48
+b Fb(39)2025 3112 y Fh(upper_bounds)21 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g
+(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)
+h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)45 b Fb(39)2025 3364
+y Fo(V)2025 3480 y Fh(value)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h
+(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)
+g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)46
+b Fb(32)2025 3567 y Fh(value_will_overflow)18 b Fa(:)f(:)c(:)h(:)f(:)g
+(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)
+g(:)g(:)45 b Fb(32)2025 3655 y Fh(value_will_underflow)16
+b Fa(:)h(:)c(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)
+g(:)g(:)g(:)h(:)f(:)g(:)g(:)42 b Fb(32)2025 3897 y Fo(W)2025
+4014 y Fh(width)21 b Fa(:)13 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)
+g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)46 b
+Fb(43)2025 4247 y Fo(X)2025 4363 y Fh(xelem)26 b Fb(on)g
+Fh(Array<T>)20 b Fa(:)14 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g
+(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)45
+b Fb(14)p eop end
+%%Trailer
+
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/doc/liboctave/liboctave.texi b/doc/liboctave/liboctave.texi
new file mode 100644
index 0000000..2348ca7
--- /dev/null
+++ b/doc/liboctave/liboctave.texi
@@ -0,0 +1,181 @@
+ at c Copyright (C) 1996, 1997, 1998, 2000, 2004, 2005, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+
+\input texinfo  @c -*-texinfo-*-
+ at setfilename liboctave.info
+ at direntry
+* liboctave: (liboctave). Octave C++ Classes
+ at end direntry
+
+ at c @smallbook
+ at c @setchapternewpage odd
+ at c @cropmarks
+ at c @finalout
+
+ at c Smaller amounts of whitespace for the 8.5 by 11 inch format.
+ at tex
+\global\chapheadingskip = 15pt plus 4pt minus 2pt
+\global\secheadingskip = 12pt plus 3pt minus 2pt
+\global\subsecheadingskip = 9pt plus 2pt minus 2pt
+\global\parskip 6pt plus 1pt
+ at end tex
+
+ at iftex
+ at set DONTINCLUDEGPL
+ at end iftex
+
+ at defindex op
+
+ at c Things like the Octave version number are defined in conf.texi.
+ at c This file doesn't include a chapter, so it must not be included
+ at c if you want to run the Emacs function texinfo-multiple-files-update.
+
+ at include conf.texi
+
+ at settitle Octave C++ Classes
+
+ at ifnottex
+
+Copyright (C) 1996, 1997 John W. Eaton.
+
+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.
+
+ at ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+ at end ignore
+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 above conditions for
+modified versions.
+ at end ifnottex
+
+ at titlepage
+ at title{Octave C++ Classes}
+ at subtitle{Edition 1.0 for Octave version @value{VERSION}}
+ at subtitle{September 1993}
+ at author{John W. Eaton}
+ at page
+ at vskip 0pt plus 1filll
+Copyright @copyright{} 1996, 1997 John W. Eaton.
+
+This is the first edition of the documentation for Octave's C++ classes,
+and is consistent with version @value{VERSION} of Octave.
+
+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.
+ at end titlepage
+
+ at contents
+
+ at ifnottex
+ at node Top, Acknowledgements, (dir), (dir)
+ at top
+
+This manual documents how to use, install and port Octave's C++ class
+library, and how to report bugs.  It corresponds to Octave version
+ at value{VERSION}.
+ at end ifnottex
+
+ at c ------------------------------------------------------------------------
+
+ at menu
+* Acknowledgements::            
+* Copying::                     
+* Introduction::                
+* Arrays::                      
+* Matrix and Vector Operations::  
+* Matrix Factorizations::       
+* Ranges::                      
+* Nonlinear Functions::         
+* Nonlinear Equations::         
+* Optimization::                
+* Quadrature::                  
+* Ordinary Differential Equations::  
+* Differential Algebraic Equations::  
+* Error Handling::              
+* Installation::                
+* Bugs::                        
+* Concept Index::               
+* Function Index::              
+
+ --- The Detailed Node Listing ---
+
+Acknowledgements
+
+* Contributors::                People who contributed to developing of Octave.
+
+Arrays
+
+* Constructors and Assignment::  
+
+Optimization
+
+* Objective Functions::         
+* Bounds::                      
+* Linear Constraints::          
+* Nonlinear Constraints::       
+* Quadratic Programming::       
+* Nonlinear Programming::       
+
+Quadrature
+
+* Collocation Weights::         
+ at end menu
+
+ at c ------------------------------------------------------------------------
+
+ at include preface.texi
+ at include gpl.texi
+ at include intro.texi
+ at include array.texi
+ at include matvec.texi
+ at include factor.texi
+ at include range.texi
+ at include nlfunc.texi
+ at include nleqn.texi
+ at include optim.texi
+ at include quad.texi
+ at include diffeq.texi
+ at include dae.texi
+ at include error.texi
+ at include install.texi
+ at include bugs.texi
+ at include cp-idx.texi
+ at include fn-idx.texi
+
+ at bye
diff --git a/doc/liboctave/matvec.texi b/doc/liboctave/matvec.texi
new file mode 100644
index 0000000..99cfe51
--- /dev/null
+++ b/doc/liboctave/matvec.texi
@@ -0,0 +1,1086 @@
+ at c Copyright (C) 1996, 1998, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+The real and complex @code{ColumnVector} and @code{RowVector} classes
+all have the following functions.  These will eventually be part of an
+ at code{MArray<T>} class, derived from the @code{Array<T>} class.  Then
+the @code{ColumnVector} and @code{RowVector} classes will be derived
+from the @code{MArray<T>} class.
+
+Element by element vector by scalar ops.
+
+ at deftypefn {} {RowVector} {operator +} (const RowVector &@var{a}, const double &@var{s})
+ at deftypefnx {} {RowVector} {operator -} (const RowVector &@var{a}, const double &@var{s})
+ at deftypefnx {} {RowVector} {operator *} (const RowVector &@var{a}, const double &@var{s})
+ at deftypefnx {} {RowVector} {operator /} (const RowVector &@var{a}, const double &@var{s})
+ at end deftypefn
+
+Element by element scalar by vector ops.
+
+ at deftypefn {} {RowVector} {operator +} (const double &@var{s}, const RowVector &@var{a})
+ at deftypefnx {} {RowVector} {operator -} (const double &@var{s}, const RowVector &@var{a})
+ at deftypefnx {} {RowVector} {operator *} (const double &@var{s}, const RowVector &@var{a})
+ at deftypefnx {} {RowVector} {operator /} (const double &@var{s}, const RowVector &@var{a})
+ at end deftypefn
+
+Element by element vector by vector ops.
+
+ at deftypefn {} {RowVector} {operator +} (const RowVector &@var{a}, const RowVector &@var{b})
+ at deftypefnx {} {RowVector} {operator -} (const RowVector &@var{a}, const RowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {RowVector} product (const RowVector &@var{a}, const RowVector &@var{b})
+ at deftypefnx {} {RowVector} quotient (const RowVector &@var{a}, const RowVector &@var{b})
+ at end deftypefn
+
+Unary MArray ops.
+
+ at deftypefn {} {RowVector} {operator -} (const RowVector &@var{a})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+The @code{Matrix} classes share the following functions.  These will
+eventually be part of an @code{MArray2<T>} class, derived from the
+ at code{Array2<T>} class.  Then the @code{Matrix} class will be derived
+from the @code{MArray<T>} class.
+
+Element by element matrix by scalar ops.
+
+ at deftypefn {} {Matrix} {operator +} (const Matrix &@var{a}, const double &@var{s})
+ at deftypefnx {} {Matrix} {operator -} (const Matrix &@var{a}, const double &@var{s})
+ at deftypefnx {} {Matrix} {operator *} (const Matrix &@var{a}, const double &@var{s})
+ at deftypefnx {} {Matrix} {operator /} (const Matrix &@var{a}, const double &@var{s})
+ at end deftypefn
+
+Element by element scalar by matrix ops.
+
+ at deftypefn {} {Matrix} {operator +} (const double &@var{s}, const Matrix &@var{a})
+ at deftypefnx {} {Matrix} {operator -} (const double &@var{s}, const Matrix &@var{a})
+ at deftypefnx {} {Matrix} {operator *} (const double &@var{s}, const Matrix &@var{a})
+ at deftypefnx {} {Matrix} {operator /} (const double &@var{s}, const Matrix &@var{a})
+ at end deftypefn
+
+Element by element matrix by matrix ops.
+
+ at deftypefn {} {Matrix} {operator +} (const Matrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {Matrix} {operator -} (const Matrix &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} product (const Matrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {Matrix} quotient (const Matrix &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+Unary matrix ops.
+
+ at deftypefn {} {Matrix} {operator -} (const Matrix &@var{a})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+The @code{DiagMatrix} classes share the following functions.  These will
+eventually be part of an @code{MDiagArray<T>} class, derived from the
+ at code{DiagArray<T>} class.  Then the @code{DiagMatrix} class will be
+derived from the @code{MDiagArray<T>} class.
+
+Element by element MDiagArray by scalar ops.
+
+ at deftypefn {} {DiagMatrix} {operator *} (const DiagMatrix &@var{a}, const double &@var{s})
+ at deftypefnx {} {DiagMatrix} {operator /} (const DiagMatrix &@var{a}, const double &@var{s})
+ at end deftypefn
+
+Element by element scalar by MDiagArray ops.
+
+ at deftypefn {} {DiagMatrix} {operator *} (const double &@var{s}, const DiagMatrix &@var{a})
+ at end deftypefn
+
+Element by element MDiagArray by MDiagArray ops.
+
+ at deftypefn {} {DiagMatrix} {operator +} (const DiagMatrix &@var{a}, const DiagMatrix &@var{b})
+ at deftypefnx {} {DiagMatrix} {operator -} (const DiagMatrix &@var{a}, const DiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {DiagMatrix} product (const DiagMatrix &@var{a}, const DiagMatrix &@var{b})
+ at end deftypefn
+
+Unary MDiagArray ops.
+
+ at deftypefn {} {DiagMatrix} {operator -} (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+ at node Matrix and Vector Operations, Matrix Factorizations, Arrays, Top
+ at chapter Matrix and Vector Operations
+ at cindex matrix manipulations
+ at cindex vector manipulations
+
+ at deftypefn  {} {} Matrix (void)
+ at deftypefnx  {} {} Matrix (int @var{r}, int @var{c})
+ at deftypefnx  {} {} Matrix (int @var{r}, int @var{c}, double @var{val})
+ at deftypefnx  {} {} Matrix (const Array2<double> &@var{a})
+ at deftypefnx  {} {} Matrix (const Matrix &@var{a})
+ at deftypefnx  {} {} Matrix (const DiagArray<double> &@var{a})
+ at deftypefnx  {} {} Matrix (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix& {operator =} (const Matrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const Matrix &@var{a}) const
+ at deftypefnx {} int {operator !=} (const Matrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} Matrix& insert (const Matrix &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} Matrix& insert (const RowVector &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} Matrix& insert (const ColumnVector &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} Matrix& insert (const DiagMatrix &@var{a}, int @var{r}, int @var{c})
+ at end deftypefn
+
+ at deftypefn {} Matrix& fill (double @var{val})
+ at deftypefnx {} Matrix& fill (double @var{val}, int r1, int c1, int r2, int c2)
+ at end deftypefn
+
+ at deftypefn {} Matrix append (const Matrix &@var{a}) const
+ at deftypefnx {} Matrix append (const RowVector &@var{a}) const
+ at deftypefnx {} Matrix append (const ColumnVector &@var{a}) const
+ at deftypefnx {} Matrix append (const DiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} Matrix stack (const Matrix &@var{a}) const
+ at deftypefnx {} Matrix stack (const RowVector &@var{a}) const
+ at deftypefnx {} Matrix stack (const ColumnVector &@var{a}) const
+ at deftypefnx {} Matrix stack (const DiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} Matrix transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} Matrix extract (int r1, int c1, int r2, int c2) const
+ at end deftypefn
+
+ at deftypefn {} RowVector row (int @var{i}) const
+ at deftypefnx {} RowVector row (char *s) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector column (int @var{i}) const
+ at deftypefnx {} ColumnVector column (char *s) const
+ at end deftypefn
+
+ at deftypefn {} Matrix inverse (void) const
+ at deftypefnx {} Matrix inverse (int &@var{info}) const
+ at deftypefnx {} Matrix inverse (int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix fourier (void) const
+ at deftypefnx {} ComplexMatrix ifourier (void) const
+ at end deftypefn
+
+ at deftypefn {} DET determinant (void) const
+ at deftypefnx {} DET determinant (int &@var{info}) const
+ at deftypefnx {} DET determinant (int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} Matrix solve (const Matrix &@var{b}) const
+ at deftypefnx {} Matrix solve (const Matrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} Matrix solve (const Matrix &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix solve (const ComplexMatrix &@var{b}) const
+ at deftypefnx {} ComplexMatrix solve (const ComplexMatrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexMatrix solve (const ComplexMatrix &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector solve (const ColumnVector &@var{b}) const
+ at deftypefnx {} ColumnVector solve (const ColumnVector &@var{b}, int &@var{info}) const
+ at deftypefnx {} ColumnVector solve (const ColumnVector &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector solve (const ComplexColumnVector &@var{b}) const
+ at deftypefnx {} ComplexColumnVector solve (const ComplexColumnVector &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexColumnVector solve (const ComplexColumnVector &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} Matrix lssolve (const Matrix &@var{b}) const
+ at deftypefnx {} Matrix lssolve (const Matrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} Matrix lssolve (const Matrix &@var{b}, int &@var{info}, int &@var{rank}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix lssolve (const ComplexMatrix &@var{b}) const
+ at deftypefnx {} ComplexMatrix lssolve (const ComplexMatrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexMatrix lssolve (const ComplexMatrix &@var{b}, int &@var{info}, int &@var{rank}) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector lssolve (const ColumnVector &@var{b}) const
+ at deftypefnx {} ColumnVector lssolve (const ColumnVector &@var{b}, int &@var{info}) const
+ at deftypefnx {} ColumnVector lssolve (const ColumnVector &@var{b}, int &@var{info}, int &@var{rank}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector lssolve (const ComplexColumnVector &@var{b}) const
+ at deftypefnx {} ComplexColumnVector lssolve (const ComplexColumnVector &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexColumnVector lssolve (const ComplexColumnVector &@var{b}, int &@var{info}, int &@var{rank}) const
+ at end deftypefn
+
+ at deftypefn {} Matrix& {operator +=} (const Matrix &@var{a})
+ at deftypefnx {} Matrix& {operator -=} (const Matrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix& {operator +=} (const DiagMatrix &@var{a})
+ at deftypefnx {} Matrix& {operator -=} (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix {operator !} (void) const
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const Matrix &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const Matrix &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const Matrix &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexMatrix} {operator /} (const Matrix &@var{a}, const Complex &@var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const Complex &@var{s}, const Matrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const Complex &@var{s}, const Matrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const Complex &@var{s}, const Matrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator /} (const Complex &@var{s}, const Matrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ColumnVector} {operator *} (const Matrix &@var{a}, const ColumnVector &@var{b})
+ at deftypefnx {} {ComplexColumnVector} {operator *} (const Matrix &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} {operator +} (const Matrix &@var{a}, const DiagMatrix &@var{b})
+ at deftypefnx {} {Matrix} {operator -} (const Matrix &@var{a}, const DiagMatrix &@var{b})
+ at deftypefnx {} {Matrix} {operator *} (const Matrix &@var{a}, const DiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const Matrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const Matrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const Matrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} {operator *} (const Matrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const Matrix &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const Matrix &@var{a}, const ComplexMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const Matrix &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} product (const Matrix &@var{a}, const ComplexMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} quotient (const Matrix &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} map (d_d_Mapper @var{f}, const Matrix &@var{a})
+ at deftypefnx {} void map (d_d_Mapper @var{f})
+ at end deftypefn
+
+ at deftypefn {} Matrix all (void) const
+ at deftypefnx {} Matrix any (void) const
+ at end deftypefn
+
+ at deftypefn {} Matrix cumprod (void) const
+ at deftypefnx {} Matrix cumsum (void) const
+ at deftypefnx {} Matrix prod (void) const
+ at deftypefnx {} Matrix sum (void) const
+ at deftypefnx {} Matrix sumsq (void) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector diag (void) const
+ at deftypefnx {} ColumnVector diag (int @var{k}) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector row_min (void) const
+ at deftypefnx {} ColumnVector row_min_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector row_max (void) const
+ at deftypefnx {} ColumnVector row_max_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} RowVector column_min (void) const
+ at deftypefnx {} RowVector column_min_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} RowVector column_max (void) const
+ at deftypefnx {} RowVector column_max_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const Matrix &@var{a})
+ at deftypefnx {} {istream&} {operator >>} (istream &@var{is}, Matrix &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ColumnVector (void)
+ at deftypefnx  {} {} ColumnVector (int @var{n})
+ at deftypefnx  {} {} ColumnVector (int @var{n}, double @var{val})
+ at deftypefnx  {} {} ColumnVector (const Array<double> &@var{a})
+ at deftypefnx  {} {} ColumnVector (const ColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector& {operator =} (const ColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const ColumnVector &@var{a}) const
+ at deftypefnx {} int {operator !=} (const ColumnVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector& insert (const ColumnVector &@var{a}, int @var{r})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector& fill (double @var{val})
+ at deftypefnx {} ColumnVector& fill (double @var{val}, int r1, int r2)
+ at end deftypefn
+
+ at deftypefn {} ColumnVector stack (const ColumnVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} RowVector transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector extract (int r1, int r2) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector& {operator +=} (const ColumnVector &@var{a})
+ at deftypefnx {} ColumnVector& {operator -=} (const ColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator +} (const ColumnVector &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexColumnVector} {operator -} (const ColumnVector &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexColumnVector} {operator *} (const ColumnVector &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexColumnVector} {operator /} (const ColumnVector &@var{a}, const Complex &@var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator +} (const Complex &@var{s}, const ColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} {operator -} (const Complex &@var{s}, const ColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} {operator *} (const Complex &@var{s}, const ColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} {operator /} (const Complex &@var{s}, const ColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} {operator *} (const ColumnVector &@var{a}, const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator *} (const ColumnVector &@var{a}, const ComplexRowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator +} (const ComplexColumnVector &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator -} (const ComplexColumnVector &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} product (const ComplexColumnVector &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} quotient (const ComplexColumnVector &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ColumnVector} map (d_d_Mapper @var{f}, const ColumnVector &@var{a})
+ at deftypefnx {} void map (d_d_Mapper @var{f})
+ at end deftypefn
+
+ at deftypefn {} double min (void) const
+ at deftypefnx {} double max (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} RowVector (void)
+ at deftypefnx  {} {} RowVector (int @var{n})
+ at deftypefnx  {} {} RowVector (int @var{n}, double @var{val})
+ at deftypefnx  {} {} RowVector (const Array<double> &@var{a})
+ at deftypefnx  {} {} RowVector (const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} RowVector& {operator =} (const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const RowVector &@var{a}) const
+ at deftypefnx {} int {operator !=} (const RowVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} RowVector& insert (const RowVector &@var{a}, int @var{c})
+ at end deftypefn
+
+ at deftypefn {} RowVector& fill (double @var{val})
+ at deftypefnx {} RowVector& fill (double @var{val}, int c1, int c2)
+ at end deftypefn
+
+ at deftypefn {} RowVector append (const RowVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} RowVector extract (int c1, int c2) const
+ at end deftypefn
+
+ at deftypefn {} RowVector& {operator +=} (const RowVector &@var{a})
+ at deftypefnx {} RowVector& {operator -=} (const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator +} (const RowVector &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexRowVector} {operator -} (const RowVector &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexRowVector} {operator *} (const RowVector &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexRowVector} {operator /} (const RowVector &@var{a}, const Complex &@var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator +} (const Complex &@var{s}, const RowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} {operator -} (const Complex &@var{s}, const RowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} {operator *} (const Complex &@var{s}, const RowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} {operator /} (const Complex &@var{s}, const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {double} {operator *} (const RowVector &@var{a}, ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Complex} {operator *} (const RowVector &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {RowVector} {operator *} (const RowVector &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator *} (const RowVector &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator +} (const RowVector &@var{a}, const ComplexRowVector &@var{b})
+ at deftypefnx {} {ComplexRowVector} {operator -} (const RowVector &@var{a}, const ComplexRowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} product (const RowVector &@var{a}, const ComplexRowVector &@var{b})
+ at deftypefnx {} {ComplexRowVector} quotient (const RowVector &@var{a}, const ComplexRowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {RowVector} map (d_d_Mapper @var{f}, const RowVector &@var{a})
+ at deftypefnx {} void map (d_d_Mapper @var{f})
+ at end deftypefn
+
+ at deftypefn {} double min (void) const
+ at deftypefnx {} double max (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} DiagMatrix (void)
+ at deftypefnx  {} {} DiagMatrix (int @var{n})
+ at deftypefnx  {} {} DiagMatrix (int @var{n}, double @var{val})
+ at deftypefnx  {} {} DiagMatrix (int @var{r}, int @var{c})
+ at deftypefnx  {} {} DiagMatrix (int @var{r}, int @var{c}, double @var{val})
+ at deftypefnx  {} {} DiagMatrix (const RowVector &@var{a})
+ at deftypefnx  {} {} DiagMatrix (const ColumnVector &@var{a})
+ at deftypefnx  {} {} DiagMatrix (const DiagArray<double> &@var{a})
+ at deftypefnx  {} {} DiagMatrix (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix& {operator =} (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const DiagMatrix &@var{a}) const
+ at deftypefnx {} int {operator !=} (const DiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix& fill (double @var{val})
+ at deftypefnx {} DiagMatrix& fill (double @var{val}, int @var{beg}, int @var{end})
+ at deftypefnx {} DiagMatrix& fill (const ColumnVector &@var{a})
+ at deftypefnx {} DiagMatrix& fill (const RowVector &@var{a})
+ at deftypefnx {} DiagMatrix& fill (const ColumnVector &@var{a}, int @var{beg})
+ at deftypefnx {} DiagMatrix& fill (const RowVector &@var{a}, int @var{beg})
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} Matrix extract (int r1, int c1, int r2, int c2) const
+ at end deftypefn
+
+ at deftypefn {} RowVector row (int @var{i}) const
+ at deftypefnx {} RowVector row (char *s) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector column (int @var{i}) const
+ at deftypefnx {} ColumnVector column (char *s) const
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix inverse (void) const
+ at deftypefnx {} DiagMatrix inverse (int &@var{info}) const
+ at end deftypefn
+
+ at deftypefn {} DiagMatrix& {operator +=} (const DiagMatrix &@var{a})
+ at deftypefnx {} DiagMatrix& {operator -=} (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} {operator +} (const DiagMatrix &@var{a}, double @var{s})
+ at deftypefnx {} {Matrix} {operator -} (const DiagMatrix &@var{a}, double @var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const DiagMatrix &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const DiagMatrix &@var{a}, const Complex &@var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} {operator *} (const DiagMatrix &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexDiagMatrix} {operator /} (const DiagMatrix &@var{a}, const Complex &@var{s})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} {operator +} (double @var{s}, const DiagMatrix &@var{a})
+ at deftypefnx {} {Matrix} {operator -} (double @var{s}, const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const Complex &@var{s}, const DiagMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const Complex &@var{s}, const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} {operator *} (const Complex &@var{s}, const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ColumnVector} {operator *} (const DiagMatrix &@var{a}, const ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator *} (const DiagMatrix &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} {operator +} (const DiagMatrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at deftypefnx {} {ComplexDiagMatrix} {operator -} (const DiagMatrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} product (const DiagMatrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Matrix} {operator +} (const DiagMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {Matrix} {operator -} (const DiagMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {Matrix} {operator *} (const DiagMatrix &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const DiagMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const DiagMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const DiagMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector diag (void) const
+ at deftypefnx {} ColumnVector diag (int @var{k}) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexMatrix (void)
+ at deftypefnx  {} {} ComplexMatrix (int @var{r}, int @var{c})
+ at deftypefnx  {} {} ComplexMatrix (int @var{r}, int @var{c}, const Complex &@var{val})
+ at deftypefnx  {} {} ComplexMatrix (const Matrix &@var{a})
+ at deftypefnx  {} {} ComplexMatrix (const Array2<Complex> &@var{a})
+ at deftypefnx  {} {} ComplexMatrix (const ComplexMatrix &@var{a})
+ at deftypefnx  {} {} ComplexMatrix (const DiagMatrix &@var{a})
+ at deftypefnx  {} {} ComplexMatrix (const DiagArray<Complex> &@var{a})
+ at deftypefnx  {} {} ComplexMatrix (const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& {operator =} (const ComplexMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const ComplexMatrix &@var{a}) const
+ at deftypefnx {} int {operator !=} (const ComplexMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& insert (const Matrix &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} ComplexMatrix& insert (const RowVector &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} ComplexMatrix& insert (const ColumnVector &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} ComplexMatrix& insert (const DiagMatrix &@var{a}, int @var{r}, int @var{c})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& insert (const ComplexMatrix &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} ComplexMatrix& insert (const ComplexRowVector &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} ComplexMatrix& insert (const ComplexColumnVector &@var{a}, int @var{r}, int @var{c})
+ at deftypefnx {} ComplexMatrix& insert (const ComplexDiagMatrix &@var{a}, int @var{r}, int @var{c})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& fill (double @var{val})
+ at deftypefnx {} ComplexMatrix& fill (const Complex &@var{val})
+ at deftypefnx {} ComplexMatrix& fill (double @var{val}, int r1, int c1, int r2, int c2)
+ at deftypefnx {} ComplexMatrix& fill (const Complex &@var{val}, int r1, int c1, int r2, int c2)
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix append (const Matrix &@var{a}) const
+ at deftypefnx {} ComplexMatrix append (const RowVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix append (const ColumnVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix append (const DiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix append (const ComplexMatrix &@var{a}) const
+ at deftypefnx {} ComplexMatrix append (const ComplexRowVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix append (const ComplexColumnVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix append (const ComplexDiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix stack (const Matrix &@var{a}) const
+ at deftypefnx {} ComplexMatrix stack (const RowVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix stack (const ColumnVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix stack (const DiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix stack (const ComplexMatrix &@var{a}) const
+ at deftypefnx {} ComplexMatrix stack (const ComplexRowVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix stack (const ComplexColumnVector &@var{a}) const
+ at deftypefnx {} ComplexMatrix stack (const ComplexDiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} {Matrix} real (const ComplexMatrix &@var{a})
+ at deftypefnx {} {Matrix} imag (const ComplexMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} conj (const ComplexMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix extract (int r1, int c1, int r2, int c2) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector row (int @var{i}) const
+ at deftypefnx {} ComplexRowVector row (char *s) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector column (int @var{i}) const
+ at deftypefnx {} ComplexColumnVector column (char *s) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix inverse (void) const
+ at deftypefnx {} ComplexMatrix inverse (int &@var{info}) const
+ at deftypefnx {} ComplexMatrix inverse (int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix fourier (void) const
+ at deftypefnx {} ComplexMatrix ifourier (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexDET determinant (void) const
+ at deftypefnx {} ComplexDET determinant (int &@var{info}) const
+ at deftypefnx {} ComplexDET determinant (int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix solve (const Matrix &@var{b}) const
+ at deftypefnx {} ComplexMatrix solve (const Matrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexMatrix solve (const Matrix &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix solve (const ComplexMatrix &@var{b}) const
+ at deftypefnx {} ComplexMatrix solve (const ComplexMatrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexMatrix solve (const ComplexMatrix &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector solve (const ComplexColumnVector &@var{b}) const
+ at deftypefnx {} ComplexColumnVector solve (const ComplexColumnVector &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexColumnVector solve (const ComplexColumnVector &@var{b}, int &@var{info}, double &@var{rcond}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix lssolve (const ComplexMatrix &@var{b}) const
+ at deftypefnx {} ComplexMatrix lssolve (const ComplexMatrix &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexMatrix lssolve (const ComplexMatrix &@var{b}, int &@var{info}, int &@var{rank}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector lssolve (const ComplexColumnVector &@var{b}) const
+ at deftypefnx {} ComplexColumnVector lssolve (const ComplexColumnVector &@var{b}, int &@var{info}) const
+ at deftypefnx {} ComplexColumnVector lssolve (const ComplexColumnVector &@var{b}, int &@var{info}, int &@var{rank}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& {operator +=} (const DiagMatrix &@var{a})
+ at deftypefnx {} ComplexMatrix& {operator -=} (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& {operator +=} (const ComplexDiagMatrix &@var{a})
+ at deftypefnx {} ComplexMatrix& {operator -=} (const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& {operator +=} (const Matrix &@var{a})
+ at deftypefnx {} ComplexMatrix& {operator -=} (const Matrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix& {operator +=} (const ComplexMatrix &@var{a})
+ at deftypefnx {} ComplexMatrix& {operator -=} (const ComplexMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Matrix {operator !} (void) const
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexMatrix &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexMatrix &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const ComplexMatrix &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexMatrix} {operator /} (const ComplexMatrix &@var{a}, double @var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (double @var{s}, const ComplexMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator -} (double @var{s}, const ComplexMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator *} (double @var{s}, const ComplexMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator /} (double @var{s}, const ComplexMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator *} (const ComplexMatrix &@var{a}, const ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator *} (const ComplexMatrix &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexMatrix &@var{a}, const DiagMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexMatrix &@var{a}, const DiagMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const ComplexMatrix &@var{a}, const DiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexMatrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexMatrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const ComplexMatrix &@var{a}, const ComplexDiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexMatrix &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator *} (const ComplexMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const ComplexMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} product (const ComplexMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} quotient (const ComplexMatrix &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} map (c_c_Mapper @var{f}, const ComplexMatrix &@var{a})
+ at deftypefnx {} {Matrix} map (d_c_Mapper @var{f}, const ComplexMatrix &@var{a})
+ at deftypefnx {} void map (c_c_Mapper @var{f})
+ at end deftypefn
+
+ at deftypefn {} Matrix all (void) const
+ at deftypefnx {} Matrix any (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix cumprod (void) const
+ at deftypefnx {} ComplexMatrix cumsum (void) const
+ at deftypefnx {} ComplexMatrix prod (void) const
+ at deftypefnx {} ComplexMatrix sum (void) const
+ at deftypefnx {} ComplexMatrix sumsq (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector diag (void) const
+ at deftypefnx {} ComplexColumnVector diag (int @var{k}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector row_min (void) const
+ at deftypefnx {} ComplexColumnVector row_min_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector row_max (void) const
+ at deftypefnx {} ComplexColumnVector row_max_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector column_min (void) const
+ at deftypefnx {} ComplexRowVector column_min_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector column_max (void) const
+ at deftypefnx {} ComplexRowVector column_max_loc (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexMatrix &@var{a})
+ at deftypefnx {} {istream&} {operator >>} (istream &@var{is}, ComplexMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexColumnVector (void)
+ at deftypefnx  {} {} ComplexColumnVector (int @var{n})
+ at deftypefnx  {} {} ComplexColumnVector (int @var{n}, const Complex &@var{val})
+ at deftypefnx  {} {} ComplexColumnVector (const ColumnVector &@var{a})
+ at deftypefnx  {} {} ComplexColumnVector (const Array<Complex> &@var{a})
+ at deftypefnx  {} {} ComplexColumnVector (const ComplexColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector& {operator =} (const ComplexColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const ComplexColumnVector &@var{a}) const
+ at deftypefnx {} int {operator !=} (const ComplexColumnVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector& insert (const ColumnVector &@var{a}, int @var{r})
+ at deftypefnx {} ComplexColumnVector& insert (const ComplexColumnVector &@var{a}, int @var{r})
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector& fill (double @var{val})
+ at deftypefnx {} ComplexColumnVector& fill (const Complex &@var{val})
+ at deftypefnx {} ComplexColumnVector& fill (double @var{val}, int r1, int r2)
+ at deftypefnx {} ComplexColumnVector& fill (const Complex &@var{val}, int r1, int r2)
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector stack (const ColumnVector &@var{a}) const
+ at deftypefnx {} ComplexColumnVector stack (const ComplexColumnVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} {ColumnVector} real (const ComplexColumnVector &@var{a})
+ at deftypefnx {} {ColumnVector} imag (const ComplexColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} conj (const ComplexColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector extract (int r1, int r2) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector& {operator +=} (const ColumnVector &@var{a})
+ at deftypefnx {} ComplexColumnVector& {operator -=} (const ColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector& {operator +=} (const ComplexColumnVector &@var{a})
+ at deftypefnx {} ComplexColumnVector& {operator -=} (const ComplexColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator +} (const ComplexColumnVector &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexColumnVector} {operator -} (const ComplexColumnVector &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexColumnVector} {operator *} (const ComplexColumnVector &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexColumnVector} {operator /} (const ComplexColumnVector &@var{a}, double @var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator +} (double @var{s}, const ComplexColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} {operator -} (double @var{s}, const ComplexColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} {operator *} (double @var{s}, const ComplexColumnVector &@var{a})
+ at deftypefnx {} {ComplexColumnVector} {operator /} (double @var{s}, const ComplexColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator *} (const ComplexColumnVector &@var{a}, const ComplexRowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator +} (const ComplexColumnVector &@var{a}, const ColumnVector &@var{b})
+ at deftypefnx {} {ComplexColumnVector} {operator -} (const ComplexColumnVector &@var{a}, const ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} product (const ComplexColumnVector &@var{a}, const ColumnVector &@var{b})
+ at deftypefnx {} {ComplexColumnVector} quotient (const ComplexColumnVector &@var{a}, const ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} map (c_c_Mapper @var{f}, const ComplexColumnVector &@var{a})
+ at deftypefnx {} {ColumnVector} map (d_c_Mapper @var{f}, const ComplexColumnVector &@var{a})
+ at deftypefnx {} void map (c_c_Mapper @var{f})
+ at end deftypefn
+
+ at deftypefn {} Complex min (void) const
+ at deftypefnx {} Complex max (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexColumnVector &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexRowVector (void)
+ at deftypefnx  {} {} ComplexRowVector (int @var{n})
+ at deftypefnx  {} {} ComplexRowVector (int @var{n}, const Complex &@var{val})
+ at deftypefnx  {} {} ComplexRowVector (const RowVector &@var{a})
+ at deftypefnx  {} {} ComplexRowVector (const Array<Complex> &@var{a})
+ at deftypefnx  {} {} ComplexRowVector (const ComplexRowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector& {operator =} (const ComplexRowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const ComplexRowVector &@var{a}) const
+ at deftypefnx {} int {operator !=} (const ComplexRowVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector& insert (const RowVector &@var{a}, int @var{c})
+ at deftypefnx {} ComplexRowVector& insert (const ComplexRowVector &@var{a}, int @var{c})
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector& fill (double @var{val})
+ at deftypefnx {} ComplexRowVector& fill (const Complex &@var{val})
+ at deftypefnx {} ComplexRowVector& fill (double @var{val}, int c1, int c2)
+ at deftypefnx {} ComplexRowVector& fill (const Complex &@var{val}, int c1, int c2)
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector append (const RowVector &@var{a}) const
+ at deftypefnx {} ComplexRowVector append (const ComplexRowVector &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} {RowVector} real (const ComplexRowVector &@var{a})
+ at deftypefnx {} {RowVector} imag (const ComplexRowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} conj (const ComplexRowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector extract (int c1, int c2) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector& {operator +=} (const RowVector &@var{a})
+ at deftypefnx {} ComplexRowVector& {operator -=} (const RowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector& {operator +=} (const ComplexRowVector &@var{a})
+ at deftypefnx {} ComplexRowVector& {operator -=} (const ComplexRowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator +} (const ComplexRowVector &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexRowVector} {operator -} (const ComplexRowVector &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexRowVector} {operator *} (const ComplexRowVector &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexRowVector} {operator /} (const ComplexRowVector &@var{a}, double @var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator +} (double @var{s}, const ComplexRowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} {operator -} (double @var{s}, const ComplexRowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} {operator *} (double @var{s}, const ComplexRowVector &@var{a})
+ at deftypefnx {} {ComplexRowVector} {operator /} (double @var{s}, const ComplexRowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {Complex} {operator *} (const ComplexRowVector &@var{a}, const ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {Complex} {operator *} (const ComplexRowVector &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator *} (const ComplexRowVector &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} {operator +} (const ComplexRowVector &@var{a}, const RowVector &@var{b})
+ at deftypefnx {} {ComplexRowVector} {operator -} (const ComplexRowVector &@var{a}, const RowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} product (const ComplexRowVector &@var{a}, const RowVector &@var{b})
+ at deftypefnx {} {ComplexRowVector} quotient (const ComplexRowVector &@var{a}, const RowVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexRowVector} map (c_c_Mapper @var{f}, const ComplexRowVector &@var{a})
+ at deftypefnx {} {RowVector} map (d_c_Mapper @var{f}, const ComplexRowVector &@var{a})
+ at deftypefnx {} void map (c_c_Mapper @var{f})
+ at end deftypefn
+
+ at deftypefn {} Complex min (void) const
+ at deftypefnx {} Complex max (void) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexRowVector &@var{a})
+ at end deftypefn
+
+ at deftypefn  {} {} ComplexDiagMatrix (void)
+ at deftypefnx  {} {} ComplexDiagMatrix (int @var{n})
+ at deftypefnx  {} {} ComplexDiagMatrix (int @var{n}, const Complex &@var{val})
+ at deftypefnx  {} {} ComplexDiagMatrix (int @var{r}, int @var{c})
+ at deftypefnx  {} {} ComplexDiagMatrix (int @var{r}, int @var{c}, const Complex &@var{val})
+ at deftypefnx  {} {} ComplexDiagMatrix (const RowVector &@var{a})
+ at deftypefnx  {} {} ComplexDiagMatrix (const ComplexRowVector &@var{a})
+ at deftypefnx  {} {} ComplexDiagMatrix (const ColumnVector &@var{a})
+ at deftypefnx  {} {} ComplexDiagMatrix (const ComplexColumnVector &@var{a})
+ at deftypefnx  {} {} ComplexDiagMatrix (const DiagMatrix &@var{a})
+ at deftypefnx  {} {} ComplexDiagMatrix (const DiagArray<Complex> &@var{a})
+ at deftypefnx  {} {} ComplexDiagMatrix (const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexDiagMatrix& {operator =} (const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int {operator ==} (const ComplexDiagMatrix &@var{a}) const
+ at deftypefnx {} int {operator !=} (const ComplexDiagMatrix &@var{a}) const
+ at end deftypefn
+
+ at deftypefn {} ComplexDiagMatrix& fill (double @var{val})
+ at deftypefnx {} ComplexDiagMatrix& fill (const Complex &@var{val})
+ at deftypefnx {} ComplexDiagMatrix& fill (double @var{val}, int @var{beg}, int @var{end})
+ at deftypefnx {} ComplexDiagMatrix& fill (const Complex &@var{val}, int @var{beg}, int @var{end})
+ at deftypefnx {} ComplexDiagMatrix& fill (const ColumnVector &@var{a})
+ at deftypefnx {} ComplexDiagMatrix& fill (const ComplexColumnVector &@var{a})
+ at deftypefnx {} ComplexDiagMatrix& fill (const RowVector &@var{a})
+ at deftypefnx {} ComplexDiagMatrix& fill (const ComplexRowVector &@var{a})
+ at deftypefnx {} ComplexDiagMatrix& fill (const ColumnVector &@var{a}, int @var{beg})
+ at deftypefnx {} ComplexDiagMatrix& fill (const ComplexColumnVector &@var{a}, int @var{beg})
+ at deftypefnx {} ComplexDiagMatrix& fill (const RowVector &@var{a}, int @var{beg})
+ at deftypefnx {} ComplexDiagMatrix& fill (const ComplexRowVector &@var{a}, int @var{beg})
+ at end deftypefn
+
+ at deftypefn {} ComplexDiagMatrix transpose (void) const
+ at end deftypefn
+
+ at deftypefn {} {DiagMatrix} real (const ComplexDiagMatrix &@var{a})
+ at deftypefnx {} {DiagMatrix} imag (const ComplexDiagMatrix &@var{a})
+ at deftypefnx {} {ComplexDiagMatrix} conj (const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexMatrix extract (int r1, int c1, int r2, int c2) const
+ at end deftypefn
+
+ at deftypefn {} ComplexRowVector row (int @var{i}) const
+ at deftypefnx {} ComplexRowVector row (char *s) const
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector column (int @var{i}) const
+ at deftypefnx {} ComplexColumnVector column (char *s) const
+ at end deftypefn
+
+ at deftypefn {} ComplexDiagMatrix inverse (int &@var{info}) const
+ at deftypefnx {} ComplexDiagMatrix inverse (void) const
+ at end deftypefn
+
+ at deftypefn {} ComplexDiagMatrix& {operator +=} (const DiagMatrix &@var{a})
+ at deftypefnx {} ComplexDiagMatrix& {operator -=} (const DiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} ComplexDiagMatrix& {operator +=} (const ComplexDiagMatrix &@var{a})
+ at deftypefnx {} ComplexDiagMatrix& {operator -=} (const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexDiagMatrix &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexDiagMatrix &@var{a}, double @var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexDiagMatrix &@var{a}, const Complex &@var{s})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexDiagMatrix &@var{a}, const Complex &@var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} {operator *} (const ComplexDiagMatrix &@var{a}, double @var{s})
+ at deftypefnx {} {ComplexDiagMatrix} {operator /} (const ComplexDiagMatrix &@var{a}, double @var{s})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (double @var{s}, const ComplexDiagMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator -} (double @var{s}, const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const Complex &@var{s}, const ComplexDiagMatrix &@var{a})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const Complex &@var{s}, const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} {operator *} (double @var{s}, const ComplexDiagMatrix &@var{a})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator *} (const ComplexDiagMatrix &@var{a}, const ColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexColumnVector} {operator *} (const ComplexDiagMatrix &@var{a}, const ComplexColumnVector &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} {operator +} (const ComplexDiagMatrix &@var{a}, const DiagMatrix &@var{b})
+ at deftypefnx {} {ComplexDiagMatrix} {operator -} (const ComplexDiagMatrix &@var{a}, const DiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexDiagMatrix} product (const ComplexDiagMatrix &@var{a}, const DiagMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexDiagMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexDiagMatrix &@var{a}, const Matrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const ComplexDiagMatrix &@var{a}, const Matrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} {ComplexMatrix} {operator +} (const ComplexDiagMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator -} (const ComplexDiagMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at deftypefnx {} {ComplexMatrix} {operator *} (const ComplexDiagMatrix &@var{a}, const ComplexMatrix &@var{b})
+ at end deftypefn
+
+ at deftypefn {} ComplexColumnVector diag (void) const
+ at deftypefnx {} ComplexColumnVector diag (int @var{k}) const
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const ComplexDiagMatrix &@var{a})
+ at end deftypefn
diff --git a/doc/liboctave/nleqn.texi b/doc/liboctave/nleqn.texi
new file mode 100644
index 0000000..57c6ede
--- /dev/null
+++ b/doc/liboctave/nleqn.texi
@@ -0,0 +1,71 @@
+ at c Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Nonlinear Equations, Optimization, Nonlinear Functions, Top
+ at chapter Nonlinear Equations
+ at cindex nonlinear equations
+
+ at deftypefn  {} {} NLEqn_options (void)
+ at deftypefnx  {} {} NLEqn_options (const NLEqn_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} NLEqn_options& {operator =} (const NLEqn_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void init (void)
+ at end deftypefn
+
+ at deftypefn {} void copy (const NLEqn_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void set_default_options (void)
+ at end deftypefn
+
+ at deftypefn {} void set_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} double tolerance (void)
+ at end deftypefn
+
+ at deftypefn  {} {} NLEqn (void)
+ at deftypefnx  {} {} NLEqn (const ColumnVector&, const @var{NLFunc})
+ at deftypefnx  {} {} NLEqn (const NLEqn &@var{a})
+ at end deftypefn
+
+ at deftypefn {} NLEqn& {operator =} (const NLEqn &@var{a})
+ at end deftypefn
+
+ at deftypefn {} void resize (int @var{n})
+ at end deftypefn
+
+ at deftypefn {} void set_states (const ColumnVector &@var{x})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector states (void) const
+ at end deftypefn
+
+ at deftypefn {} int size (void) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector solve (void)
+ at deftypefnx {} ColumnVector solve (const ColumnVector &@var{x})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector solve (int &@var{info})
+ at deftypefnx{} ColumnVector solve (const ColumnVector &@var{x}, int &@var{info})
+ at end deftypefn
diff --git a/doc/liboctave/nlfunc.texi b/doc/liboctave/nlfunc.texi
new file mode 100644
index 0000000..384170c
--- /dev/null
+++ b/doc/liboctave/nlfunc.texi
@@ -0,0 +1,42 @@
+ at c Copyright (C) 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Nonlinear Functions, Nonlinear Equations, Ranges, Top
+ at chapter Nonlinear Functions
+ at cindex nonlinear functions
+
+ at deftypefn  {} {} NLFunc (void)
+ at deftypefnx  {} {} NLFunc (const @var{nonlinear_fcn})
+ at deftypefnx  {} {} NLFunc (const @var{nonlinear_fcn}, const @var{jacobian_fcn})
+ at deftypefnx  {} {} NLFunc (const NLFunc &@var{a})
+ at end deftypefn
+
+ at deftypefn {} NLFunc& {operator =} (const NLFunc &@var{a})
+ at end deftypefn
+
+ at deftypefn {} nonlinear_fcn function (void) const;
+ at end deftypefn
+
+ at deftypefn {} NLFunc& set_function (const nonlinear_fcn @var{f})
+ at end deftypefn
+
+ at deftypefn {} jacobian_fcn jacobian_function (void) const;
+ at end deftypefn
+
+ at deftypefn {} NLFunc& set_jacobian_function (const jacobian_fcn @var{j})
+ at end deftypefn
diff --git a/doc/liboctave/ode.texi b/doc/liboctave/ode.texi
new file mode 100644
index 0000000..13ffd34
--- /dev/null
+++ b/doc/liboctave/ode.texi
@@ -0,0 +1,95 @@
+ at c Copyright (C) 1996, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Ordinary Differential Equations, Differential Algebraic Equations, Nonlinear Equations, Top
+ at chapter Ordinary Differential Equations
+ at cindex ODE
+
+ at deftypefn  {} {}ODE_options (void)
+ at deftypefnx  {} {}ODE_options (const ODE_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} ODE_options& {operator =} (const ODE_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void init (void)
+ at end deftypefn
+
+ at deftypefn {} void copy (const ODE_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void set_default_options (void)
+ at end deftypefn
+
+ at deftypefn {} void set_absolute_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_initial_step_size (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_maximum_step_size (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_minimum_step_size (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_relative_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} double absolute_tolerance (void)
+ at deftypefnx {} double initial_step_size (void)
+ at deftypefnx {} double maximum_step_size (void)
+ at deftypefnx {} double minimum_step_size (void)
+ at deftypefnx {} double relative_tolerance (void)
+ at end deftypefn
+
+ at deftypefn  {} {}ODE (void)
+ at deftypefnx  {} {}ODE (int @var{n})
+ at deftypefnx  {} {}ODE (const ColumnVector &@var{state}, double @var{time}, const ODEFunc &@var{f})
+ at end deftypefn
+
+ at deftypefn {} {virtual int} size (void) const
+ at end deftypefn
+
+ at deftypefn {} {virtual ColumnVector} state (void) const
+ at end deftypefn
+
+ at deftypefn {} {virtual double} time (void) const
+ at end deftypefn
+
+ at deftypefn {} {virtual void} force_restart (void)
+ at end deftypefn
+
+ at deftypefn {} {virtual void} initialize (const ColumnVector &@var{x}, double @var{t})
+ at end deftypefn
+
+ at deftypefn {} {virtual void} set_stop_time (double @var{t})
+ at end deftypefn
+
+ at deftypefn {} {virtual void} clear_stop_time (void)
+ at end deftypefn
+
+ at deftypefn {} {virtual ColumnVector} integrate (double @var{t})
+ at end deftypefn
+
+ at deftypefn {} void integrate (int @var{nsteps}, double @var{tstep}, ostream &@var{s})
+ at end deftypefn
+
+ at deftypefn {} Matrix integrate (const ColumnVector &@var{tout})
+ at deftypefnx {} Matrix integrate (const ColumnVector &@var{tout}, const ColumnVector &@var{tcrit})
+ at end deftypefn
diff --git a/doc/liboctave/optim.texi b/doc/liboctave/optim.texi
new file mode 100644
index 0000000..105e89e
--- /dev/null
+++ b/doc/liboctave/optim.texi
@@ -0,0 +1,225 @@
+ at c Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Optimization, Quadrature, Nonlinear Equations, Top
+ at chapter Optimization
+ at cindex optimization
+
+ at menu
+* Objective Functions::         
+* Bounds::                      
+* Linear Constraints::          
+* Nonlinear Constraints::       
+* Quadratic Programming::       
+* Nonlinear Programming::       
+ at end menu
+
+ at node Objective Functions, Bounds, Optimization, Optimization
+ at section Objective Functions
+ at cindex objective functions
+
+ at deftypefn  {} {} Objective (void)
+ at deftypefnx  {} {} Objective (const @var{objective_fcn})
+ at deftypefnx  {} {} Objective (const @var{objective_fcn}, const @var{gradient_fcn})
+ at deftypefnx  {} {} Objective (const Objective &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Objective& {operator =} (const Objective &@var{a})
+ at end deftypefn
+
+ at deftypefn {} objective_fcn objective_function (void) const;
+ at end deftypefn
+
+ at deftypefn {} Objective& set_objective_function (const @var{objective_fcn})
+ at end deftypefn
+
+ at deftypefn {} gradient_fcn gradient_function (void) const;
+ at end deftypefn
+
+ at deftypefn {} Objective& set_gradient_function (const @var{gradient_fcn})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+ at node Bounds, Linear Constraints, Objective Functions, Optimization
+ at section Bounds
+ at cindex bounds
+
+ at deftypefn  {} {} Bounds (void)
+ at deftypefnx  {} {} Bounds (int @var{n})
+ at deftypefnx  {} {} Bounds (const ColumnVector @var{lb}, const ColumnVector @var{ub})
+ at deftypefnx  {} {} Bounds (const Bounds &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Bounds& {operator =} (const Bounds &@var{a})
+ at end deftypefn
+
+ at deftypefn {} Bounds& resize (int @var{n})
+ at end deftypefn
+
+ at deftypefn {} double lower_bound (int @var{index}) const;
+ at deftypefnx {} double upper_bound (int @var{index}) const;
+ at end deftypefn
+
+ at deftypefn {} ColumnVector lower_bounds (void) const;
+ at deftypefnx {} ColumnVector upper_bounds (void) const;
+ at end deftypefn
+
+ at deftypefn {} int size (void) const;
+ at end deftypefn
+
+ at deftypefn {} Bounds& set_bound (int @var{index}, double @var{low}, double @var{high})
+ at end deftypefn
+
+ at deftypefn {} Bounds& set_bounds (double @var{low}, double @var{high})
+ at deftypefnx {} Bounds& set_bounds (const ColumnVector @var{lb}, const ColumnVector @var{ub})
+ at end deftypefn
+
+ at deftypefn {} Bounds& set_lower_bound (int @var{index}, double @var{low})
+ at deftypefnx {} Bounds& set_upper_bound (int @var{index}, double @var{high})
+ at end deftypefn
+
+ at deftypefn {} Bounds& set_lower_bounds (double @var{low})
+ at deftypefnx {} Bounds& set_upper_bounds (double @var{high})
+ at end deftypefn
+
+ at deftypefn {} Bounds& set_lower_bounds (const ColumnVector @var{lb})
+ at deftypefnx {} Bounds& set_upper_bounds (const ColumnVector @var{ub})
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const Bounds &@var{b})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+ at node Linear Constraints, Nonlinear Constraints, Bounds, Optimization
+ at section Linear Constraints
+ at cindex linear Constraints
+
+ at deftypefn  {} {} LinConst (void)
+ at deftypefnx  {} {} LinConst (int @var{nclin}, int @var{nx})
+ at deftypefnx  {} {} LinConst (int @var{nclin_eq}, int @var{nclin_ineq}, int @var{nx})
+ at deftypefnx  {} {} LinConst (const ColumnVector &@var{lb}, const Matrix &@var{A}, const ColumnVector &@var{ub})
+ at deftypefnx  {} {} LinConst (const Matrix &@var{A_eq}, const ColumnVector &@var{b_eq}, const Matrix &@var{A_ineq}, const ColumnVector &@var{b_ineq})
+ at deftypefnx  {} {} LinConst (const LinConst &@var{a})
+ at end deftypefn
+
+ at deftypefn {} LinConst& {operator =} (const LinConst &@var{a})
+ at end deftypefn
+
+ at deftypefn {} LinConst& resize (int @var{nclin}, int @var{n})
+ at end deftypefn
+
+ at deftypefn {} Matrix constraint_matrix (void) const;
+ at end deftypefn
+
+ at deftypefn {} LinConst& set_constraint_matrix (const Matrix &@var{A})
+ at end deftypefn
+
+ at deftypefn {} Matrix eq_constraint_matrix (void) const;
+ at deftypefnx {} Matrix ineq_constraint_matrix (void) const;
+ at end deftypefn
+
+ at deftypefn {} ColumnVector eq_constraint_vector (void) const;
+ at deftypefnx {} ColumnVector ineq_constraint_vector (void) const;
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const LinConst &@var{b})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+ at node Nonlinear Constraints, Quadratic Programming, Linear Constraints, Optimization
+ at section Nonlinear Constraints
+ at cindex nonlinear Constraints
+
+ at deftypefn  {} {} NLConst (void)
+ at deftypefnx  {} {} NLConst (int @var{n})
+ at deftypefnx  {} {} NLConst (const ColumnVector @var{lb}, const NLFunc @var{f}, const ColumnVector @var{ub})
+ at deftypefnx  {} {} NLConst (const NLConst &@var{a})
+ at end deftypefn
+
+ at deftypefn {} NLConst& {operator =} (const NLConst &@var{a})
+ at end deftypefn
+
+ at node Quadratic Programming, Nonlinear Programming, Nonlinear Constraints, Optimization
+ at section Quadratic Programming
+ at cindex QP
+ at cindex quadratic programming
+
+ at deftypefn  {} {} QP (void)
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const ColumnVector &@var{c})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const Bounds &@var{b})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const LinConst &@var{lc})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const ColumnVector &@var{c}, const Bounds &@var{b})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const ColumnVector &@var{c}, const LinConst &@var{lc})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const Bounds &@var{b}, const LinConst &@var{lc})
+ at deftypefnx  {} {} QP (const ColumnVector &@var{x}, const Matrix &@var{H}, const ColumnVector &@var{c}, const Bounds &@var{b}, const LinConst &@var{lc})
+ at end deftypefn
+
+ at deftypefn {} {virtual ColumnVector} minimize (void)
+ at deftypefnx {} {virtual ColumnVector} minimize (double &@var{objf})
+ at deftypefnx {} {virtual ColumnVector} minimize (double &@var{objf}, int &@var{inform})
+ at deftypefnx {} {virtual ColumnVector} minimize (double &@var{objf}, int &@var{inform}, ColumnVector &@var{lambda}) = 0;
+ at end deftypefn
+
+ at deftypefn {} {virtual ColumnVector} minimize (const ColumnVector &@var{x})
+ at deftypefnx {} {virtual ColumnVector} minimize (const ColumnVector &@var{x}, double &@var{objf})
+ at deftypefnx {} {virtual ColumnVector} minimize (const ColumnVector &@var{x}, double &@var{objf}, int &@var{inform})
+ at deftypefnx {} {virtual ColumnVector} minimize (const ColumnVector &@var{x}, double &@var{objf}, int &@var{inform}, ColumnVector &@var{lambda})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector minimize (double &@var{objf}, int &@var{inform}, ColumnVector &@var{lambda})
+ at end deftypefn
+
+ at c ------------------------------------------------------------------------
+
+ at node Nonlinear Programming,  , Quadratic Programming, Optimization
+ at section Nonlinear Programming
+ at cindex NLP
+ at cindex nonlinear programming
+
+ at deftypefn  {} {} NLP (void)
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const Bounds &@var{b})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const Bounds &@var{b}, const LinConst &@var{lc})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const Bounds &@var{b}, const LinConst &@var{lc}, const NLConst &@var{nlc})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const LinConst &@var{lc})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const LinConst &@var{lc}, const NLConst &@var{nlc})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const NLConst &@var{nlc})
+ at deftypefnx  {} {} NLP (const ColumnVector &@var{x}, const Objective &@var{phi}, const Bounds &@var{b}, const NLConst &@var{nlc})
+ at end deftypefn
+
+ at deftypefn {} NLP& {operator =} (const NLP &@var{a})
+ at end deftypefn
+
+ at deftypefn {} int size (void) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector minimize (void)
+ at deftypefnx {} ColumnVector minimize (double &@var{objf})
+ at deftypefnx {} ColumnVector minimize (double &@var{objf}, int &@var{inform})
+ at deftypefnx {} ColumnVector minimize (double &@var{objf}, int &@var{inform}, ColumnVector &@var{lambda})
+ at end deftypefn
+
+ at deftypefn {} ColumnVector minimize (const ColumnVector &@var{x})
+ at deftypefnx {} ColumnVector minimize (const ColumnVector &@var{x}, double &@var{objf})
+ at deftypefnx {} ColumnVector minimize (const ColumnVector &@var{x}, double &@var{objf}, int &@var{inform})
+ at deftypefnx {} ColumnVector minimize (const ColumnVector &@var{x}, double &@var{objf}, int &@var{inform}, ColumnVector &@var{lambda})
+ at end deftypefn
diff --git a/doc/liboctave/preface.texi b/doc/liboctave/preface.texi
new file mode 100644
index 0000000..75bdf04
--- /dev/null
+++ b/doc/liboctave/preface.texi
@@ -0,0 +1,33 @@
+ at c Copyright (C) 1996, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Acknowledgements, Copying, Top, Top
+ at chapter Acknowledgements
+ at cindex acknowledgements
+
+ at menu
+* Contributors::                People who contributed to developing of Octave.
+ at end menu
+
+ at node Contributors,  , Acknowledgements, Acknowledgements
+ at unnumberedsec Contributors to Octave
+ at cindex contributors
+
+In addition to John W. Eaton, several people have written parts
+of liboctave.  (This has been removed because it is the same as what is
+in the Octave manual.)
diff --git a/doc/liboctave/quad.texi b/doc/liboctave/quad.texi
new file mode 100644
index 0000000..0cb7288
--- /dev/null
+++ b/doc/liboctave/quad.texi
@@ -0,0 +1,141 @@
+ at c Copyright (C) 1996, 1997, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Quadrature, Ordinary Differential Equations, Optimization, Top
+ at chapter Quadrature
+ at cindex quadrature
+ at cindex numerical integration
+ at cindex integration
+
+ at deftypefn  {} {} Quad (integrand_fcn @var{fcn})
+ at deftypefnx  {} {} Quad (integrand_fcn @var{fcn}, double @var{abs}, double @var{rel})
+ at end deftypefn
+
+ at deftypefn {} {virtual double} integrate (void)
+ at deftypefnx {} {virtual double} integrate (int &@var{ier})
+ at deftypefnx {} {virtual double} integrate (int &@var{ier}, int &@var{neval})
+ at deftypefnx {} {virtual double} integrate (int &@var{ier}, int &@var{neval}, double &@var{abserr}) = 0
+ at end deftypefn
+
+ at deftypefn {} {} Quad_options (void)
+ at deftypefnx {} {} Quad_options (const Quad_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} Quad_options& {operator =} (const Quad_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void init (void)
+ at end deftypefn
+
+ at deftypefn {} void copy (const Quad_options &@var{opt})
+ at end deftypefn
+
+ at deftypefn {} void set_default_options (void)
+ at end deftypefn
+
+ at deftypefn {} void set_absolute_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} void set_relative_tolerance (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} double absolute_tolerance (void)
+ at deftypefnx {} double relative_tolerance (void)
+ at end deftypefn
+
+ at deftypefn  {} {} DefQuad (integrand_fcn @var{fcn})
+ at deftypefnx  {} {} DefQuad (integrand_fcn @var{fcn}, double @var{ll}, double @var{ul})
+ at deftypefnx  {} {} DefQuad (integrand_fcn @var{fcn}, double @var{ll}, double @var{ul}, double @var{abs}, double @var{rel})
+ at deftypefnx  {} {} DefQuad (integrand_fcn @var{fcn}, double @var{ll}, double @var{ul}, const ColumnVector &@var{sing})
+ at deftypefnx  {} {} DefQuad (integrand_fcn @var{fcn}, const ColumnVector &@var{sing}, double @var{abs}, double @var{rel})
+ at deftypefnx  {} {} DefQuad (integrand_fcn @var{fcn}, const ColumnVector &@var{sing})
+ at deftypefnx  {} {} DefQuad (integrand_fcn @var{fcn}, double @var{ll}, double @var{ul}, const ColumnVector &@var{sing}, double @var{abs}, double @var{rel})
+ at end deftypefn
+
+ at deftypefn  {} {} IndefQuad (integrand_fcn @var{fcn})
+ at deftypefnx  {} {} IndefQuad (integrand_fcn @var{fcn}, double @var{b}, IntegralType @var{t})
+ at deftypefnx  {} {} IndefQuad (integrand_fcn @var{fcn}, double @var{b}, IntegralType @var{t}, double @var{abs}, double @var{rel})
+ at deftypefnx  {} {} IndefQuad (integrand_fcn @var{fcn}, double @var{abs}, double @var{rel})
+ at end deftypefn
+
+ at menu
+* Collocation Weights::         
+ at end menu
+
+ at node Collocation Weights,  , Quadrature, Quadrature
+ at section Collocation Weights
+ at cindex orthogonal collocation
+ at cindex collocation weights
+
+ at deftypefn  {} {} CollocWt (void)
+ at deftypefnx  {} {} CollocWt (int @var{n}, int @var{inc_l}, int @var{inc_r})
+ at deftypefnx  {} {} CollocWt (int @var{n}, int @var{inc_l}, int @var{inc_r}, double @var{l}, double @var{r})
+ at deftypefnx  {} {} CollocWt (int @var{n}, double @var{a}, double @var{b}, int @var{inc_l}, int @var{inc_r})
+ at deftypefnx  {} {} CollocWt (int @var{n}, int @var{inc_l}, int @var{inc_r}, double @var{l}, double @var{r})
+ at deftypefnx  {} {} CollocWt (const CollocWt&)
+ at end deftypefn
+
+ at deftypefn {} CollocWt& {operator =} (const CollocWt&)
+ at end deftypefn
+
+ at deftypefn {} CollocWt& resize (int @var{ncol})
+ at end deftypefn
+
+ at deftypefn {} CollocWt& add_left (void)
+ at deftypefnx {} CollocWt& add_right (void)
+ at end deftypefn
+
+ at deftypefn {} CollocWt& delete_left (void)
+ at deftypefnx {} CollocWt& delete_right (void)
+ at end deftypefn
+
+ at deftypefn {} CollocWt& set_left (double @var{val})
+ at deftypefnx {} CollocWt& set_right (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} CollocWt& set_alpha (double @var{val})
+ at deftypefnx {} CollocWt& set_beta (double @var{val})
+ at end deftypefn
+
+ at deftypefn {} int ncol (void) const
+ at end deftypefn
+
+ at deftypefn {} int left_included (void) const
+ at deftypefnx {} int right_included (void) const
+ at end deftypefn
+
+ at deftypefn {} double left (void) const
+ at deftypefnx {} double right (void) const
+ at deftypefnx {} double width (void) const
+ at end deftypefn
+
+ at deftypefn {} double alpha (void) const
+ at deftypefnx {} double beta (void) const
+ at end deftypefn
+
+ at deftypefn {} ColumnVector roots (void)
+ at deftypefnx {} ColumnVector quad (void)
+ at deftypefnx {} ColumnVector quad_weights (void)
+ at end deftypefn
+
+ at deftypefn {} Matrix first (void)
+ at deftypefnx {} Matrix second (void)
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const CollocWt &@var{c})
+ at end deftypefn
diff --git a/doc/liboctave/range.texi b/doc/liboctave/range.texi
new file mode 100644
index 0000000..4a104dd
--- /dev/null
+++ b/doc/liboctave/range.texi
@@ -0,0 +1,54 @@
+ at c Copyright (C) 1996, 2006, 2007 John W. Eaton
+ at c
+ at c This file is part of Octave.
+ at c
+ at c Octave is free software; you can redistribute it and/or modify it
+ at c under the terms of the GNU General Public License as published by the
+ at c Free Software Foundation; either version 3 of the License, or (at
+ at c your option) any later version.
+ at c 
+ at c Octave is distributed in the hope that it will be useful, but WITHOUT
+ at c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ at c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ at c for more details.
+ at c 
+ at c You should have received a copy of the GNU General Public License
+ at c along with Octave; see the file COPYING.  If not, see
+ at c <http://www.gnu.org/licenses/>.
+
+ at node Ranges, Nonlinear Functions, Matrix Factorizations, Top
+ at chapter Ranges
+ at cindex ranges
+
+ at deftypefn  {} {} Range (void)
+ at deftypefnx  {} {} Range (const Range &@var{r})
+ at deftypefnx  {} {} Range (double @var{b}, double @var{l})
+ at deftypefnx  {} {} Range (double @var{b}, double @var{l}, double @var{i})
+ at end deftypefn
+
+ at deftypefn {} double base (void) const
+ at deftypefnx {} double limit (void) const
+ at deftypefnx {} double inc (void) const
+ at end deftypefn
+
+ at deftypefn {} void set_base (double @var{b})
+ at deftypefnx {} void set_limit (double @var{l})
+ at deftypefnx {} void set_inc (double @var{i})
+ at end deftypefn
+
+ at deftypefn {} int nelem (void) const
+ at end deftypefn
+
+ at deftypefn {} double min (void) const
+ at deftypefnx {} double max (void) const
+ at end deftypefn
+
+ at deftypefn {} void sort (void)
+ at end deftypefn
+
+ at deftypefn {} {ostream&} {operator <<} (ostream &@var{os}, const Range &@var{r})
+ at deftypefnx {} {istream&} {operator >>} (istream &@var{is}, Range &@var{r})
+ at end deftypefn
+
+ at deftypefn {} void print_range (void)
+ at end deftypefn
diff --git a/doc/refcard/Makefile.in b/doc/refcard/Makefile.in
new file mode 100644
index 0000000..6085455
--- /dev/null
+++ b/doc/refcard/Makefile.in
@@ -0,0 +1,93 @@
+# Makefile for octave's doc/refcard directory
+#
+# Copyright (C) 1996, 1997, 2003, 2004, 2005, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+TEX := refcard.tex refcard-a4.tex refcard-legal.tex refcard-letter.tex 
+
+FORMATTED := refcard-a4.dvi refcard-a4.ps refcard-a4.pdf \
+	refcard-legal.dvi refcard-legal.ps refcard-legal.pdf \
+	refcard-letter.dvi refcard-letter.ps refcard-letter.pdf
+
+DISTFILES := $(addprefix $(srcdir)/, Makefile.in $(TEX)) $(FORMATTED)
+
+all: $(FORMATTED)
+
+refcard-a4.dvi: refcard-a4.tex refcard.tex
+	-TEXINPUTS="$(srcdir):$(TEXINPUTS):" tex $<
+
+refcard-a4.ps: refcard-a4.dvi
+	-dvips -T 297mm,210mm -o $@ $<
+
+refcard-a4.pdf: refcard-a4.tex refcard.tex
+	-TEXINPUTS="$(srcdir):$(TEXINPUTS):" pdftex $<
+
+refcard-legal.dvi: refcard-legal.tex refcard.tex
+	-TEXINPUTS="$(srcdir):$(TEXINPUTS):" tex $<
+
+refcard-legal.ps: refcard-legal.dvi
+	-dvips -T 14in,8.5in -o $@ $<
+
+refcard-legal.pdf: refcard-legal.tex refcard.tex
+	-TEXINPUTS="$(srcdir):$(TEXINPUTS):" pdftex $<
+
+refcard-letter.dvi: refcard-letter.tex refcard.tex
+	-TEXINPUTS="$(srcdir):$(TEXINPUTS):" tex $<
+
+refcard-letter.ps: refcard-letter.dvi
+	-dvips -T 11in,8.5in -o $@ $<
+
+refcard-letter.pdf: refcard-letter.tex refcard.tex
+	-TEXINPUTS="$(srcdir):$(TEXINPUTS):" pdftex $<
+
+check install install-strip uninstall:
+.PHONY: check install install-strip uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean clean:
+	rm -f refcard-*.log
+.PHONY: mostlyclean clean
+
+distclean: clean
+	rm -f Makefile
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS	refcard-*.dvi refcard-*.ps refcard-*.pdf
+.PHONY: maintainer-clean
+
+dist: all
+	ln $(DISTFILES) ../../`cat ../../.fname`/doc/refcard
+.PHONY: dist
diff --git a/doc/refcard/refcard-a4.dvi b/doc/refcard/refcard-a4.dvi
new file mode 100644
index 0000000..ecd2d45
Binary files /dev/null and b/doc/refcard/refcard-a4.dvi differ
diff --git a/doc/refcard/refcard-a4.pdf b/doc/refcard/refcard-a4.pdf
new file mode 100644
index 0000000..9ab88f9
Binary files /dev/null and b/doc/refcard/refcard-a4.pdf differ
diff --git a/doc/refcard/refcard-a4.ps b/doc/refcard/refcard-a4.ps
new file mode 100644
index 0000000..3db6750
--- /dev/null
+++ b/doc/refcard/refcard-a4.ps
@@ -0,0 +1,3054 @@
+%!PS-Adobe-2.0
+%%Creator: dvips(k) 5.96 Copyright 2005 Radical Eye Software
+%%Title: refcard-a4.dvi
+%%CreationDate: Thu Dec 10 12:05:33 2009
+%%Pages: 3
+%%PageOrder: Ascend
+%%Orientation: Landscape
+%%BoundingBox: 0 0 595 843
+%%DocumentFonts: CMBX12 CMR6 CMBX10 CMTT8 CMR7 CMTI7 CMR10 CMSY10 CMMI10
+%%DocumentPaperSizes: a4
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips -T 297mm,210mm -o refcard-a4.ps refcard-a4.dvi
+%DVIPSParameters: dpi=600
+%DVIPSSource:  TeX output 2009.12.10:1205
+%%BeginProcSet: tex.pro 0 0
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S
+/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy
+setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask
+restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
+/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{A length product length le{A length product exch 0
+exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
+end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
+grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
+imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
+exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
+fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
+delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
+B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
+p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
+rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+%%BeginProcSet: texps.pro 0 0
+%!
+TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
+index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0
+ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{
+pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get
+div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type
+/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end
+definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
+sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
+mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
+exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
+forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
+end
+
+%%EndProcSet
+%%BeginFont: CMMI10
+%!PS-AdobeFont-1.1: CMMI10 1.100
+%%CreationDate: 1996 Jul 23 07:53:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 25 /pi put
+readonly def
+/FontBBox{-32 -250 1048 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321
+990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E
+6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB
+DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721
+59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823
+D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF
+8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808
+6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9
+1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE
+03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909
+95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1
+74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2
+3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8
+47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19
+AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8
+42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8
+40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837
+B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53
+9560176676ABB71BBD0EE56B4CC492C0652750227CEC6CB2CF13A3AF2C7762AC
+4A63E9A8A45F08316E4C871193F4DFD406CAA01FA8545A9CEB4726D979FE9BBE
+FD50A389F9DF9BEA83F2E73963D6A328A143DECE3F2E4FE2F917BF80A63A2D2F
+815370A53A4D17BE225E9BF4D896AFA151C86D7CAB01F11F02E9A5C3FFAB6402
+328643DF72A68FB4E4A346EE995F94789B2209E56F188F1CDBF8AF92A1695000
+C1A08CC04F5213CFE3943D9087133D2EB280A073DC8E6EFCF446DD92CD5F9E75
+A8D44140D0D46858673E7C1FC07EDB08D41785BB3A374E0941AC69A327F0AE8A
+FF6DCE28B303DDDDC9AB9D01F332ED731416B5E8B9AB03A8E2F4E8768B77AFAB
+19CD5697B5BA7755773DDFD7FAD543CBEB8E4DBD4CA7F5ADD10150521D73B132
+733E24E673CA65BBE49A3F81A5780E69379715F0D2F3A906EA756D3C6515CE2F
+8B2B40A986FF4D949137A2AE2D53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSY10
+%!PS-AdobeFont-1.1: CMSY10 1.0
+%%CreationDate: 1991 Aug 15 07:20:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSY10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.035 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSY10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 0 /minus put
+dup 2 /multiply put
+dup 102 /braceleft put
+dup 103 /braceright put
+dup 106 /bar put
+dup 112 /radical put
+readonly def
+/FontBBox{-29 -960 1116 775}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964
+7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4
+A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85
+E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A
+221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A
+27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF
+5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09
+0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730
+DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A
+71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09
+4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C
+515DB70A8D4F6146FE068DC1E5DE8BC57032092296D5371C275E56FB4903A60E
+73A22818DE22EB78EEE0E69EDE2E31BA367FE9AFFF8C7D74AB1E2400953F643B
+7BC604F821A4CCC56FC4E40E0B40B8CB82A045EFB4B9F681EDBD012AC35166EF
+62940137319D3082AF2B42F5E0138804C62FCFF2DDD0AAAB3E2A1249BBBAB593
+00577FAE2BC50E3A7B37BAF90BA56525DC498A971A487617DA028EDAC7F8BDF5
+225C6E2C63564D35ABBDBDFC523302D6D28A3A8E2D8332F6A1FAE2E71D2C6EE0
+64275E875009ABEB233E981A8C36996D0CAA8267981F04BF421C8C4A5162B736
+21DB026EECEDDDC9E1DC92761140410416A7F17A92DE302890C67472E4770E22
+3CFA4B800FA29D765039F9704DD0554F5F5AA479322F46E89A67A5B52709A2E3
+13B14C530AC58684DE01F555FA08D9E3BEC56A6198049AC4463BC0667DA3B092
+9072E0067FF74B36A85A10DEFFBDD3F6C55802E8FB6A84F1C61D42DE55CE8C3A
+5202B098AE5EBE989E3DD38C9D1E8D198E959C946F83EC667B2AD398BAE7C003
+B540D5474D351A90660618D4B185B05DDC3D72CDC22635283ACCD253C56380AC
+27C6EC7C7ECFE5DB1257F62F8B7C6C55A7E40C9C26C48F777C51C442FE0610D5
+65EE0FBC1E9537D51C4D25B22F48B58DF64A09C9FF2150903EC75F1DC0152668
+5CFDC5E9E38E04B453235752D62079FDC7BF0979E6C3327123DA1BCEE9A6CAF6
+1CAC0BCF4B0D02FB3518998CF007016FAA03005251E622D6E67ED2F19D80CE25
+AB274919736E3E2B685DD4C1F6C6B4F624E238AE536978159E184517C14A08D6
+0807D4C4E76E0CBD99A28E8E068D233BFB8204BD820AE1807C757DA13E580CAA
+AD459E754C9AED669CF46B7F11AC6E8B5B8F16AD7AFF0B5D9CDA82B040D8F40B
+78F8241E70A347EE98260BD50AAEB772629D9BEE93A9F3A57EC45756F73C1AAB
+B0F9E00572B6BAE2542BE8022F0D385F23475FDB0CB7ADF37495D3D8B6E01168
+C0B0CD75C2166255E4A2D7741B6DBBCF7760C25C2BE7791204E925D318260FD2
+589DD1EEE2D6CC3CD456D8341DD0B0A7C2729BEFBF0E8B3F218C2FAD9510AEAC
+C23F3AE8B643614195D60C1DC3AE19A477963F7E8F9FC36F9573F1941F33D557
+5698823F742DDA6482FBAEE4A512D59DB4902412A9D257C275B278D950CA9947
+C07C11B50055D309B874ECE21EE5F95FECD47C1216779BA81FB8307A064563F8
+499FF484DA648B91AB11BBE44A8D2E5A960295B90D9CD8672B0F628C3BE4BBD2
+1D1B9DE38289E4B9ABA59BC9741A81900E8A1B6706A0AEE3CC61F24E7056E18F
+B421A06FFA208FBA6F1D764B90C2B14D8294E2922154A8BC7DEF2BB73B3CD6FE
+988A4FE1D635D9F89F040D0753323D78D33735B5BA70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR10
+%!PS-AdobeFont-1.1: CMR10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:52
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 49 /one put
+dup 91 /bracketleft put
+dup 93 /bracketright put
+readonly def
+/FontBBox{-251 -250 1009 969}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C
+295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75
+409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C
+4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF
+2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E
+0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E
+B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008
+24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B
+43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF
+D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575
+5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC
+96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3
+7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC3C8578EF9A20A0E06E
+4F7ADDAF0E7D1E182D115BF1AD931977325AD391E72E2B13CC108E3726C11099
+E2000623188AAAC9F3E233EB253BDD8B0A4759A66A113E066238B0086AC1B634
+5ABFF90E4B5ED3FA69C22541981B2BFC9710AEF6B50A8BB53431C7B4D380D721
+639E005D6B4688EE16BFF48443E7C9E5FB5BC5883E271CB03428955D5B6A6C01
+F9D9F44C93F0C94D9D0728D2A6F5390B793E4205F4BBFADB26785DCF0EAE8467
+0F2CB7F2ECC80860473B0AF607E131ADC315664B74C8FBBB3169708EC9EF9977
+FB3172531CB7AFD5E6CE40A819129D46BA23A46C548A8713BE1A4125FE8E4E94
+FD2FB0777C4853D15397A4FF99571D812F3D1FAF4885974F234F0AF75B36ED35
+812979028DAD6F7EE30A55ECA354CD5179A9FDFE5A010AC0206E05E73CC3BFC7
+04839BCBF01DCA4946CE91A83735797021F57B4ABEF2324D8F4A4AF4BA86318F
+E6DB11B2908C051AB886FE7BC28BEF2ABB9955A321103A2E6C4B8078FFAED99F
+768CA23B44F429BFD9B2CFF6456CFBBA8E04E3BEC7921E691BBE0A98F0F7CF0D
+58E8CB7057C661E85BA2DF8AAA713BC6DA03449AB38339CD4E834C08154FF725
+9895FF5744A96D9A326780EF0F312F0005CFC261EB9080D943EF23E1849A224C
+F92C8F4AD38D66E0EFFE38E76A8FA3D4888FB7FB6FD5FE1797DCD0B4751710A6
+ACF7170C7BD29C1CCD634D290C36FE683AF227CF333D2AE30AEB5E96FD6BB838
+E3BF46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTI7
+%!PS-AdobeFont-1.1: CMTI7 1.0
+%%CreationDate: 1991 Aug 18 21:07:18
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTI7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMTI7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 41 /parenright put
+dup 45 /hyphen put
+dup 46 /period put
+dup 49 /one put
+dup 50 /two put
+dup 78 /N put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-27 -250 1268 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D77639DF1232A4D6233A9CAF69B151DFD33F
+C0962CCA6FACCEA6B71BEEF7C056FBD376F2F0D0BD6BE0A0A8259139B28B99C6
+25119B8C60FF7BA002476930DFDC2F6B1B5A80F1C0E544A22E3F0FB2FEAB64B6
+A509B61E1AB96121FBF7F2BC27CDE5B4961048FC2169C8DB745FCC7AF0EED507
+284038B15CE53E69AA22CA76C2A208F6AD8614CD500D479A5E0FD25E7BB14C7F
+C47C503E4CC38975CB0A8F7E109665FB69EBAE6EB68B2D6FA3C967D5BDE7830E
+9CE6F13DFAEBC852DF1D7D0CDD33DD4D5CD6D94DD8AE0D48AB638013CF75A25C
+04FDEA8775EC52A13AF40FA41F7354624D917EE620318C702237AF8C0E1FFA02
+127F862D4DFD0A56774235A881AFBB8F7F4BCB33811C581CFF38462F669B7F97
+1F97AC09373B8F9B7E653013AF8170613E8D7E17235A893BE296A0CD2096B71F
+16778388993EDF1B003EBCE23DD02949CBFAAAB5D9F6A08178BFB8ED1043FC1B
+0B90D9AFC27B19783740E8DDE0E5E01D116A8CB083C721FBB8EBF71018A9570E
+78590CD831116BC0FDA4229F79A581874FC3A1F108A4FCA80CE27FA54A2A7505
+5BDB3D52E2595512837732322FB5BBE459C0205EB38439E34A39544F0A1567C6
+F29FBB7CF931708C8F92786CCBCBB443D54462B3B4B7BD38E90D325EBC31BA05
+FAAB393C7EBDB9EC48E4ACC15A247D2348A62293A726FCA4250B4A407F64270F
+923EB516CB8A3B5D19876C8755EB291357E4E4CC5903D1A536A635E267F7A971
+B1C33AA7F58E1ADA931C450EA8367B18E20E683CCEEC1BC079E837DDAFFF0D16
+23C4AED0DC04DD9458A630FD498794823FFA55705315F0687E7592A5DFC8B8D6
+FE2F3C6550976415640267DD73C0C64FE63F1E81172FB979F7575C459CB0DD02
+1EAD6AE29D5383A7B0B7C197DED6D8E9CE621CBF1EEF641E699C8836D6A8160D
+E50FB6D6A5F356D504A49E7A92D88C540D03D406521D8464C7EAACC0111B6589
+40AF23202778F36F6E4632714401D95E5AE569FDEF2FF90A17998D9DFC5492C9
+A7138A59222043BC4E55E50425A74AEC11DE8597CE8165972895B767528615E4
+B52A855386B377D36CEA5E3F4714B0934C8980470714E85764745EF1C7462686
+AF55B39B82931298A3144154D9515B726CE0FAFC20B87925DF472BBD25F922A6
+6518EF30460ACE2BAFC71A1597F96812946C21DFF1CB430284804497292470EB
+6E0D2F22C2B168DDC63AC78600AFCCBE55AA8890C2357A692FB7DDEC32B57EFC
+7D15F814F2539FB3ECF75B062F3A3CF2B2BDC3D376B887BCA71D80F1564A9F24
+3AE133B7390A4C049241D8EEECDAF8E6873E30F19D1EBE7EB1744D0FD3820490
+F0A94738BA811B04952A2F1CE8D91F0A013A8FBA50DD6723758B0CB8419E4ED9
+A75256DD5A11250795C845F9994D6ABAB0D52FE6302E9EA85F45E7F6A85F14C8
+98D2E2B9973885487B30D60021D9DA65AC0EEC39228ADC8E171F0492BF51DD5A
+ED7BB96B11D644279EB5FF774A0F901BB5858308D2D7B5848430ACB2D67B7B9A
+BD2B984328C2ABBDB9CF087700994038C4B3A96C7511F3B92BD503C264858541
+199554B6A98B7386C5AC7EFE3909C50DE3B85755907E77730F7024DA01F4BDFE
+1E430FE15A78C1E2A3671770DA46CC3FE8DC6D1B99B31D3E7D4AC7581053D679
+C22F515E02D17DEEF99FCFEBDE55B05C81BE418D43B8C8F20F319E2B29C46DF0
+93AF8C5DE9D101326C0828A4AF567B952B181F97606371C079AD03196CDB0733
+5EF0A29DE66CA65261922AE01B0B3BB712352D6D01DABA931080A4FB0B148407
+792A0731B34470FF72A8FB558ED70ECB5F9DD7F1D3285F0BCD007E015BD937E6
+275F61ABA68D1E8443E97783E3F60273C025F65DC5EC46A85C8893776AB3C947
+87F861D5FCAD70ADC281CC64909F0BC268A317E3443AEEEAECB006A9D484B618
+89EF2E40BD426C79A76BC74C584AEA5B44D8290AD9FEF1893EE48A3098FF59FD
+C51079E0B3B116CB6A57B05A887A7CF646B9849EF6FE79F75D086FF36176D2E9
+6CC08A1EB37F046DDB85D2F132F2F1633E4FFCABBCAC644B19783D5943C691A7
+56DBB18967093094275FD051783A57DB27221B595C6371805AD612BE5D46D830
+BA6A0CB6011E60F63B743F845C44F32BF750D7CA28E32BA8C1693E3B647F9312
+36FAB072D5168E87C35E668BCF519F4B1F3606C5A86CE5EF801F24AD72A17579
+1603087DE7254C8E07B6E979205C691E482D9D3EF4AD1216646C696544F6D556
+8CFA87A28B49D51697E94BEFBDB9F680C23D038CBC903386B249CB5AC33DDD20
+502FFCA63C49C0101186CEEEE512B2ED0B7F2AF213FDF8FEBAF2F4365A07EC61
+C251FA30ED70FBF08BC5FB3F4629E41DD9565D44FFCA00FB9780958273A32C6F
+652D2E6CE3E6F7CA3F70E872F5217066FAC0839F49980CF750FE1317E2D856D4
+59FE32AA35D41C6C091BB328319F8C89EB0C1210794F891657BD755382923BD4
+F76A88EEA14D48B0061E5481B0896E872F4C2895C30FFBFD7D9D5467EBF41D6E
+43D14E425430AA50259A1F83E8243566E22AED459FF4A76E882D1B3C9DEF1DAD
+42BE223E53F8C09D49EA840384DB9E16EF66C448386B061E806279219E39CD61
+2808A7DFE105193E6CE9C0E9B1174D7B0ADB2B10F53F9BFF55C377214E7B0234
+EC2FB9796B03164B3DD5CDC16E63D5A9A49FD0A5BBA69CC31499106B674D4E31
+19748F7715F541331B3A723D139EFCD5173E016C7B4030979F15CCCF511FB088
+D86088A8766E455C54DB2DEB3AC33B458DC87146013264295F00F1E69415160B
+FCA55B3BA7FB8F9D98EC485A2C62756973F0D609CC8F91B760B2D8DC64794499
+8CC106E2A12573109BEC55C66053343016D32A90A88301114A3B862A9B79D754
+6E7CF60FD398B22245B81CC57FBFF41AC3F14DB29502549E0FF905D057FB1D01
+EA0191B6D7ADFD2DCE2D1A482F95BBDE8ADC2E383DA77B79628D87007A757F4D
+F64902A85D9E1ED9D5269CC3779BA04569E50281E4F0599693C2A1ECC627CBBC
+7931D3BC7785A330C210C7A9EDD9FCAA1655375F893308914CAAB151E886D8E5
+E6766E69325AD0A19217D50B2772B0301A8D93D89CA4B89DDC3288998278F5BC
+80EB605B215E949A81F0269C8E4E2A0ED8A4302DC7052F057F9542E0455558F8
+9FCA1B350CDBFB804DCCDAEFFCEE794D1114C58B2A2200F5F59466ECD8126DEB
+BE45D6B85D49F79AA4D461A3D3D9B70BBC0EDAD5B3190551B20B1AFCFCD5FF65
+B0EA0D44FA158BE546E0ECAD9916C8C4F017DC916A4F671A9977E778CF7570A3
+6446DCF3285378491E34884913A5518DAB2ED41C6B7614B69F72F472E41F4F6B
+0CE11E0AA76AAF72E28C8FED1E4625578147CB0106B770F1CFD01E12398B2D78
+E24835489B857F26DB3CB02AB1BAD787DCBC595CBFDBD9CADA1DEFF61327ED13
+9E8E9E815CF5490A415BA72FF81D8047E3FEFAF123002EA87EFE93016C5DF2FD
+8153382E38E03815EDB41AAFA788A4BCD399AD81702EF877A03AA61E71CE8B6D
+B8559661C56DF18A27102F9A855C354EE7AEBAE3A7739D33F3ACD93B406F2EF1
+F3DA8E031377C6B609855E081078A1BCA8E406A1E76EDE9FDD4CD8D29CEA4A08
+2B0A5BD7230873D6C58BC551B9DB4B2AC5D3A68988505125A4DD34922773C561
+79640CF8E406A143F2A9CA1AD1A130797619D35B8238E13013AF8010C62B43DB
+09F4C88B65C86A18956F317CC76182DB16C30043BC87C05D19FF5CEFC4A98DCB
+3A541BC97C80ACC39D9F48467DAE59D28028A6B75078D7832B369A333C15D3AB
+7CB3E3F016F841B5AC5A4A9AEBA9A941C822EC67EABB58215E0BFD286EDFB751
+981EB82ED9FD95ECC14ABF0B3BC822C6C7CB4141107611FEA631E9F96292EF73
+079D417C0A0BC9CBBA6B761BD5A76C43CCB63700A098D993C47C4A5C0299027C
+C271AA718EDB4682F605F69B4428068D0DC5DDD7B1FE1CC868F1A9F2AAA49842
+DF20E7572CD96216FEC97273A40DDF7BBD489414CBEE3D23A57F3A77E10043D4
+51C02468564AC3E80FA517A893078766D05998AF7B78F8B0B47BE6C7316F71E5
+D40D85FAE2781E63B6D770B5FA45FF06A1659EE6B65CDB025B4E3CA8623515E3
+0BF1AE5E748ABA5E52A94C8403A8732CBD291FAFCF59CA90CF8D0D21DECA1493
+34CA42AB3F537A442CAA114639E5CC96E5D045F133D020374C6B0A5E10D4D8C6
+224060D1686A9DB77D252D57D66248C7880073E5442D2522FFCCD556557297D7
+B92B8E656A191DC388E985ABCBBA8635B6389B584D62E247AF4C81AC7581FB84
+7F4B443DAFCCD261A3AB85A9A9F42781EADEA6A68863805810216787BE0BA291
+A44705A98930B55E5B5265F7B56089BFD576E714F1C1281F05D4D35E4BDE4470
+BEB39E057E431647DCBB6D7FD26F60FFB68051BF2A0524AC94F3F6190BC531F0
+4C4F2AA339D619988E00ECC1BAE259B7324404803018EAAB32E5206831615748
+2652957CD044512F185B9A14749E4751992C2F9CF183647DA6CD21B0F03D2BE4
+225E1C28298B5D8DE6930C09C239E20741EFB954694A649AC6BC0880186B5463
+FE5AAF0A69E0AE1AAA0F5502CE8F2FEF00B36EDF545236B3506FB37EEA03B3C6
+8B9D56729452E176FDCB12926E31A062AA37CF2C455822351C285ABFE6737F82
+48BEC7E325A2DF054C528F481D9B83FC788A7243ABDA5D9BCC1D8851EE949BD0
+114D5C3E51BCC4E19ADCC188E556480DDC2663AE524A2BDD7744916D62C531D7
+0E90659E0640A43BCCBCDB702D0C5AE585538EA37BB4089EDAB4B44AC3393A6D
+87EEC78AF5EC54CAE31D188293524284D6412DC7DBEF26AC4E129BAF8DA6702F
+A0C216F91AA3874D467542055994A9C24E8E1272D2EF266C211CA70C98E0C7D3
+B537CB87E9BB9C46B78F20CEDE5BFDCAB3902093991DEA96B0D7CC41D0117843
+957FEBF578A8B1A57C3D295CC145B72D54F46A636E80B5163B91BA61C8279F0D
+ED61A1ADCB0AA32EC9A30BCE1717AE2BA2138CE60A53313DFEFBDF95D770C4C0
+1ED286FC3196F35C47569951479DD788BD4AC0A4353DFE984A61069B201B5E8B
+889B8BCBAE39CB2F964B51CD85CA4EE98C78A27034D2DCD951BF17C8877269B1
+660146B9215655FD5EB08823E4528047B2950A87A232BAFDBA4BFC7E6CA25305
+E839B9E7F049F0443DFA6D487D12045F6022F93D98C7C6FF1DA174F96D2CF0C3
+EF23A0E03FA2E95E1C69199E50971E014EAC678F7EE677966D6B76855FF4CF0F
+4FCEB9950077FEAD21ACDB139E0D9773DC84CEEFE07AF3E8EB2A7F5722C4B226
+102B9CD4AB721282C5EAE85940714CAF3DB41EABD703143E9D3D2205A75CB709
+F316D7AE5CB88AA8F57B08CB5AD27849D2E937515473EFAB72A54EAF7F066E47
+C63B1F6246A4B4EF0FB8B08CBDC821DAB987E4B82B1097D318096A3087B9C1A0
+AC68F596C661F3CB6DC6C9A56E8DC2028288B04A31BD248F5DFE952848FCB0A4
+B1CDCB5A2D2E2867B297716C326102A0578E899E3B5E7D78D1F4D4DC4592702E
+509F6CE853B9FBC3FAB683DBAC4AE02BFB30F4B976CA4A2E002CB19216303B9B
+3181DE9877AA761D2BB3B0B9AC907B0564F44409250EB4A6ECA7922C8E8DB001
+CFF8ACFAA49AE65324226B8B8FC3772F657D8F6F3CA6E898B344C8BCEAA7B1BF
+1128FBE2BD58BA62BC4144DA0D9DCD707FF865F218C5C559A1C254BF0750BDA8
+AFD330603322BAF3A30A1F0B019A7585FC1E12E56CD097558845A130F4B7ABB3
+A5C496CB064AEA05A4EC0126A67FB5093683ADA2C25BE9874350E677514D9511
+37873AF6F81AA3011587AD4E5419C2C0E265BC5A36AA7FA51B3DAB525CA8A1D9
+7AC624E46ED25C3371C927D75893DD8FC9B5522D80A7258EBB05745845FBCF7B
+6E8077C118AD5E84C174F292775D088116791F02B3979320F296602FDD22CA47
+E6BB58E45FB085FCF290639B2F763CE15481D9720D758E5685892D3FB78D9B12
+9CEE9BD41D9437C3B85C8461722DEBBCCB8BF2417DBAE644CA7F9C6519A5E39A
+5A422E3DC005A0AB7D275B470733E1318BE936AF1FEAACD729CF5AD3892428EC
+5268A2439BB2B89EE11FBD436C47AE0614EF986F0EAD848545A377D56594E00A
+D6228BF5B440DA5F28A0B3F805295DB4A9ED928BAB290576C5610FEBD485DB85
+DC3B5091BEF7B1A70282F8BFFABE273FC53003026EA5D1E9CE955F657BFF5462
+A0F36BC0AEC7F0DD42AF9A233078F660D498B668319E3CC65F24271B87E0FB26
+01014FDCAB87D5F65D72AF5B00AFE4D8BA8B5D8D4A1FBFE34E430F54F0B5D214
+0C86404400C5CF33CECE5FEC03BECE952955078C740E639843E724802170212A
+2C65B65B18B04D7008034609E8C4F9119DE06DF13B1CA55DE4CB964229954680
+D36FCF1D0F47B15ACE44758B8710C69AC9F9A54486F8A18C4E3CE153D0265BBD
+0CD887BAE6F6375FF20A6B72BB7A84FC5E2B34F94706297E1019D84821BC4A8D
+5BCE43AFB29E1F551D962BF37F73BA8791C3C0DF37537E3BBB84FCBD1480C33B
+5BF6AFC860EE6203B7589F38AC5738EDEA5F6D1AF261DC8E973AFBBF837030BA
+441C94D1BBBAAA7FAB6A9030ACA19B91CA53268A1FE80ED25C309D71B89313FB
+27D49A0BFEB9C5DEDBB6F99C730C0540C8939220B54BA63C7FCC8F7CC709B3BF
+6098E1776A4EBA3717CC26404B669DFF41053711D8F2EC5D98954DFCA45C497B
+36A3470524E96417ACFEB62C9CECB62AFCD5F44D206C7680D12D32FCC4563D9F
+F492C4436CF049F989353770533050853ACE9EED7C856127F01144A970189E93
+A92E88619A426CC551AD57FD54BF0DB2DF9059C2C669DB4FE640B828361F2CC8
+4B4BAD8936FBE06CB979816A2881E6B9CF458A3C8504A5700BFDB8B7175E1B89
+8DB4DEA351077857E9D8A06D077F7760A9161D4102E3FB16AC6111C5C0558022
+E4E89561337E5B15723F6C97057435E8D354A113D163189A93D028424A99FD39
+41BC461D5EF7F75E2897461CFCA1D77B6051F5BA4E703E67C5B904C7C8D31040
+D8A732F9B0A2F3DD2EE6D7B167BCE925A5632CB635DAD838C12BA8D44B9C1BA2
+C29F80825CADC5E8A15D7A8E64DECFA4A18DCC9BC96ABFC39963158C14FD3EC8
+4ED979310E798AF6CDFD8504D804CB0DF43F95F7271F7B366ED0B8CCB4F0505C
+73FA14CF73C391A0466CE81F2485B993108D32EA73A4D26E2FD995A135E67FAF
+CC3EDE5A70E90F9FB1667631FC4B351786D96A3CE329D0781A66A727B3F2A33C
+0B663B8756A1C739D07B39AC858519B23A3D81500A6EF130AE6A45A81C843123
+2414D06830A2F5AD5936A8E5FBBE12CCB59563672FC69E2BC5EA5A06EABC3985
+359F2683ADC07EE164B819CB6DA2FAD378C9F60CD49D6D21A00F2C2471A18502
+20B8BA7E9CD9500F592028F90095BA0D213FA19FA70C0909958CCF1DE4287878
+CB93C4101DAB123E8F3F7152BC82E43C1629326655422936B32EB4632D7DFD0A
+E0D9D296BBE4ED231BBD7DEFF79E0AAF8B2F867EECF4B9CD3BDF6AE3F4D3DC95
+BD85F66B9DBBC8934B4756CA11C11C08BD0FF8BBF90C5B70294D011A9E75C15F
+6FD09150AFEE1588A557CE31F1758D941C420C300CF326E83E1FA0587A4AB80E
+85F195DE49830B25617B90A93F1256C40CEB3852851D86D803EEC19C665F17E6
+D56040936810740574961A4FB48BAC5B03545262253284AA23BD82DB7EAE8F41
+33B6DC8796C6019518DC7E27A72EAECA6CFB74450F7A4A575F00A50B256971AA
+91DFAAC0A12CB9550E390A93CAE821020D68513EB89E151F77E384DFA28E60D4
+1CF8203F213AA89BC1128C8D3D235294BA2D7B66D552364FE03156C0AA648571
+4100624BFA090FA81BBB524D98C6173BF900E8E74BB58FADB072B4A60B292A68
+28F686DDE1CC02468D87C22E6C4EF00EABDF545A9369A338394581FDCEFC5708
+3FE330D130D8F224A4293C0229388044328913F4C141C83CE0E339095A1404CC
+4DAE96487EFE02B69D8B46FA2FFCA2281BF95F494797E989619A2F54B5E53B36
+C829DC61E3A565ACF6F3647BC21716758075378EC994B9780AD361E7A3BFC483
+15D381DF90052625D61248B724D41B32714B413E6C6237682E565B45F622CBB6
+08506AED024011268DF8D9349773F5C66A70BDB4AF2FE99711710CB316053FF8
+67F2AD9C36B72411712B2C63D185827981503593B1029770911A78B78D401E7A
+0D0986D84213FD610F7DEBB5981A570F898852128AB3B9C3C572C14BE236AB05
+D8ED683F455D79C8B95C43A06A4F7CEDEDC689DF89D6B2D803A4FF3F5C9430DD
+37123FB3B0228A35C28DE23BDC12F79EF31C37E9EC3A288D7C2CC94B699519EE
+7D25B8749C8C934E6A04F8720A2BA290864D4D8E822A85A510D1ABD61A604C43
+A6E4E8A57A473B60BB6E173969AB1E06EAC9F7D349551FD24A4BAE5F87C6828B
+D2A5048D9D91B1DD552E88C6B3FE1FBE774AD19A03F4F51782BBAE33D8CA1D99
+99DBCDB5DFB6C219EA8D246861DDEA5F47EDA4E115130DBD9E5B02BF734F28A8
+5AEE854B99016061E632EBF500E225780B8CD7848B1AADFBC05DE4D8F67B1B4B
+24C700214AE3F1827455D7C848FAEE5DE3311873E40005776AA50E14952814E3
+575E51D3534A5E1F54B4D3C3A64134BA6ACE4F26F46B0C9073D5C53A073DD617
+7D76E4CFC648496F229C731CB5FCAFBBC5B81D0E3CC0CEF7CB0866607FBAADE9
+18A358D2F3E827BE637550E92767E874227109D380557D8DC5458785958AEB6C
+34E904B1488297A4F33E2B6E07F091A2CF8FD62BB36957103DE3C72EE0EB27EE
+0B1224C4570D35C3AF14E504B48C1E4BF3B321C3EE623288C82CBE96ABA181B7
+F7C8B9D69B1B1B97AF3B086C82E42343320F7065C210929C05C741F05CCBEC96
+D14B3498139C7BBA9481C05E1CA5E46AB06C2CD418EDCCAE3278E515E905CAD9
+B09D88AC4587943C510ADCC857F59A5E66C80E4D621006FD4735FC54E8B73660
+40CCE67FC6F6CC4FDD9931A26A339755567AA2D6FBD4316A8F16F2EFF51D4C8F
+B3F619E6C7814AFA109261F0B2BAAFF92D0BC25980FAA7F7C5CB566520725DB3
+957B73267A9C4E0610E5327E47C39C74AA285BEAB2E8230806184C60E5509BA6
+1A185BD6D8DA6DEE48C87E0B782A11071D08A1701DE89F69BC70ED9EF335FBAC
+72F8DABA2A378BB458B73603EC8C3B491EB551BF2ADB613E43A0E6DBBE806FBF
+2EABF00B8BE6400F5F117CA4F0EEB6B09F03F36245EDEED0AA78FEECD4D23362
+869398D52329AD0239EE539835BDEAE15B64FCF3BA2471B16AB99C74DED0901A
+A37AC51DEBDD9AC63609C5083BED26DB9C4EFA601DE7B67FD7AA74A72D854F17
+1F2C5AC5936DFA9D56F6A131C47CBEFAD0383463358E66207112F4D9FE1E0D2F
+C4C8BD1212C9DBF9A980E6E9CBB1A8271F73DD47C58C7978C134FF6BB57B6E77
+9B6F14F2D0B74587FE1E6A4607F19CF469C0D6417A406981DFD88076F79D4BDA
+2767ADCDD8151CAB176D9905672B255951395A3F64AC1B521DF2A4F70609ADA3
+E1484B04243BE4F05E5A53252D3B0548600F31EDA74B7D1820F6DEE9F8D1B234
+4529583AD95FBC74C8A019D64EF50C7F170D5075AD5D0BE8C41571C5C272D870
+CB936F418ECB04F48590D56CFAAD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR7
+%!PS-AdobeFont-1.1: CMR7 1.0
+%%CreationDate: 1991 Aug 20 16:39:21
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 11 /ff put
+dup 12 /fi put
+dup 13 /fl put
+dup 14 /ffi put
+dup 34 /quotedblright put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 57 /nine put
+dup 58 /colon put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 87 /W put
+dup 92 /quotedblleft put
+dup 96 /quoteleft put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-27 -250 1122 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF5B8CABB9FFC6CC3F1E9AE32F234EB60FE7D
+E34995B1ACFF52428EA20C8ED4FD73E3935CEBD40E0EAD70C0887A451E1B1AC8
+47AEDE4191CCDB8B61345FD070FD30C4F375D8418DDD454729A251B3F61DAE7C
+8882384282FDD6102AE8EEFEDE6447576AFA181F27A48216A9CAD730561469E4
+78B286F22328F2AE84EF183DE4119C402771A249AAC1FA5435690A28D1B47486
+1060C8000D3FE1BF45133CF847A24B4F8464A63CEA01EC84AA22FD005E74847E
+01426B6890951A7DD1F50A5F3285E1F958F11FC7F00EE26FEE7C63998EA1328B
+C9841C57C80946D2C2FC81346249A664ECFB08A2CE075036CEA7359FCA1E90C0
+F686C3BB27EEFA45D548F7BD074CE60E626A4F83C69FE93A5324133A78362F30
+8E8DCC80DD0C49E137CDC9AC08BAE39282E26A7A4D8C159B95F227BDA2A281AF
+A9DAEBF31F504380B20812A211CF9FEB112EC29A3FB3BD3E81809FC6293487A7
+455EB3B879D2B4BD46942BB1243896264722CB59146C3F65BD59B96A74B12BB2
+9A1354AF174932210C6E19FE584B1B14C00E746089CBB17E68845D7B3EA05105
+EEE461E3697FCF835CBE6D46C75523478E766832751CF6D96EC338BDAD57D53B
+52F5340FAC9FE0456AD13101824234B262AC0CABA43B62EBDA39795BAE6CFE97
+563A50AAE1F195888739F2676086A9811E5C9A4A7E0BF34E6F4C9A04BEEA891E
+4D22B39729EE4F0ECBF3CF3C429B3BB657DF66811D3A108A73513A22D252AEBA
+66664B33422FED0E63D93F9F8E24320719C09F50626EABAAE93F5649E1981AEC
+E8F19F6105EA978C51CBF54E94F3DBC93516313F00B281D1B8C8E4C1DB33363E
+B81B61D7224245842A6B98939F0ACF3ED081BFE7A813215D36CD6ABC3EBD6B99
+A5FAC5AA7A0DB126B0A1FB14B58525546D4D8BB6E95F803D6E48BADA30DAED03
+942D55691A3E5FC195F3AD4297A1A5E9C2F61F9F123AFC6CCA78BC17BF2F0F21
+9F07458D74BB65C10DA76B2D8A7595FE457E74DCF33EF5960E547CB301D7448F
+481932BDD0B999648074C1D48E8CFE4C863E4926B3B9C5F48512E59F3CE5F6E0
+2BE5EEB299259FDC25851EEC203FE0C8146DA5DE9D9D0A69E629994A008C50B0
+794B86C6B29CF688BD915BACA1C895EC3D10C25D1652405D5AE963C68F5BF164
+14CAF662FA3B468A3C7F80DACE40DAC79EA6CF24666B8096FAFE5C6FEFF97159
+4235543AA8D28481D10FFD41D36E4E69662380B606DA8584B808E8684B0DD1E0
+17D96E3EC23C2918A4320D14256945714F40886807D0E95E62D274E0A9338A70
+C44B1B3E4E4672C8753146873301E4C13BF3FECF350202B9831D556C9E47B873
+029EB02FBA04C39F87CF7845E5BCD095646A17D799FF1E9F057C54F6FF2F58A2
+3E708F8629F3E4B656C4C89F697C39DCCE00DC7A7F0DCDCD2846E1F1F1C11BE9
+12E73D274A8C2AB5C3D192F6A4301D4D8DABC4BF4BB2DF9EDD7DBEEF30C32F79
+EB865039C47B903CA6EF162FC7F6B665C4BBBB07405FFA2E9B7E658971BB98B5
+1038378D0CEE25EA4A05C351F9D26D8C51E7F95CF547E7A1EEFF7AB3BC7F9999
+A8DA8393FB2F713F292B9ECC594C06C2B7788A9FB8FDD30437264371EBB89508
+4BABE312946B6F0E71538E8DB3A356DEA9198B47BBB65065ECA7F0D9A33DDD5D
+AE0F360DF4B23B9BAE61528492077ED46764056D0352DA06DC92489CBEDA6979
+67B07D598123218CDB5180E93894C60717BBC0A2D59B6DA88A18B475755E8601
+FF2C76450883E8B87AFCB6129CE78FDDF1B0051901376FBBE836853D65DF35E5
+51D83CCD4F06E5FD94832BFBBFE809E2F3EEB26EAFF1F4B343E28E299C4BE030
+209704F1EE5182036468365545C202F2E8065701E57AD7A15572F2FE12AE81C3
+6AB77AF07B162F1BF8FAF8AFC3F8AC9DCE6FE95E792AEDFCDB13C49B9A545E1F
+D62057389422AB6C77F00E96DE72799FD34E58AD8643D45017A61C42A932A7A2
+46D34BB68D821E1F4DBFE9DAB50771CAA864D2A8C2FA3C173E2BE11F2C9D9E73
+04E47B430318F1AE8A7E495112A9654046EC10A913BB60FF45F6FA636A640F62
+3EAC2279C21A93EF15B2B36440A50FAF73580CAED243D6013F0C852821B33542
+53432C41CBA08BFBD219A72D68FBA5D41E5A0C779E071D6C5954A62C712D6757
+2AE3F815173D0B9D6D9F5EA17DCDA24F98A93F4DF9367C2A13555B27034AD29D
+92E58C118DD27564B37DDA5E1BBE609B09DD3008DB15E46A161C5867AA473A26
+C52DAC92D51E34E2A797844825E6F6C24BABFB9B80C4282D0AD2746397E8DE0A
+1E030B636BD1B00AFC3BF9DD59DC7D0D96DF3A9BE133CD7B8CF640D1381BAC97
+DFBE3B2C5CEFB66E4BC51D85B316B7BD2CC6CE96CF4C128E181BBBB849903003
+57AD671BA64DC53F46F4085BA3980750EA149C31BA92B27DA0839A667F1F5C7A
+9BCA01692411CDA70C5DB370B9D6767B36F8A52A2078F7549AC24AF28CA40A93
+304C5D2A71CEDB760F6089FDF09B3315ECDDC73F0F143A2D2C4DA2460D709D82
+18AACB213135A3648EF604BB5CA3BD0EC18FD7A0A5180376E3E2BBBD83863469
+3CD7348B18A29750D93E5BDF2EE6A94FD2BDED974CD326BB67042FB361C0D2AB
+77E57516AB701BA70EE678F265B3933C9BB41D979212B31CC3DC8F12FB6FE09E
+8B35D60F2DDD3CA0CB837FA0A90C2ADFDB140ACCE3026EC68EA90BD30B9C0290
+5AD6A59CB0FD2C8C8DBE9770414560CE966FFB413D47970C3464F2DEB1CDF16D
+F90790447C22C7A1DAE78C14C780296D4CD3F8E3C0787678A88AA23E525C2738
+A6FA50F12CBDDB02C3F49A62D73A552E21D069EAB44DED93B41DE6BEE9E840B0
+32F4C9BB72EDF1283A88152DE0654F9C05FF424064A311BEB9F13692CD5042F6
+87612F5138AA158D73BFDC6EA23B14EF748BF3A039E263C34F0CF6682A191735
+83AF4EF1BF7B441EDA836498F6728E25523C42E2BC3F309D148EF61D6FA47660
+CD26C61F71087B189DF39F5A72DC386E505FA0CBF07F2E9B4E149311FFF7B80D
+10A7223D4160214A41580EEE261D671CAD6011415C87716FB3AACBDB771888C7
+E278A86B515939DE1F1831D00C7048B627123DD552F654C493A69C211B642E18
+1FB9BAA905ECEE762DBFD7994B8FFA412B07D1F8028CEEC7ECBE836F39732D64
+FBF90E46AAB1CE56C916F86A823DED0730FBE6FB122447BFC60E0534EA8C99B9
+60CB50A4FF0F6BF2D94AD6BF517EAFA586269A90B94A4A178AD4994BB4B8E52B
+4CF8B68B26B5CD10493C814AF0656F9B181101099756BA7B7C8B9DFA2AF609F8
+EA960710CD16B3F9CF3E5FDC452EC08237E794B82C1C85F1B6B12A709771DD9D
+A77C4BBC94D31ECF4760666BBD6000CC8C49CF1D1ED3F3DE3505BAA0F77E70E4
+C6CF7A2DBA73C254BA90B2EE7AF45BFC65E8520309762FF07B87C0C81E0C4F25
+30FEDA98C85EF785B7574EB961C590B1CF9B40E36B87B836201EFED54256AEED
+0C4B10E2247A42FDC870638FEBF20314935E65AD73AC798501C3AAA891F9EAD9
+6783D0BE48C6CB3EE89F3538E15162490FA9C4BDE0EDDD1D2EC63B8EFB093840
+3027C5C8964B10636C2773B859EB8B2D28ED589BD57F3AD6D9AE3A0ADADA0311
+776440781D9F5739F123301646C5156DFEEF8786930C7ED88816DCB9B67B828F
+730536F7DA34EFB2F2AF77481ED68542B0DDD96894A6AF33E282FF09B61C85FF
+5206B358F695D572FF48D005DF54D65A602FD6BE7B6F15BB9AB59003717CCE44
+D4DF50D0BB66CD926E6DAED26B90F562B287B7CF46DD44CAD7BE29E6D84907FC
+5DC8769F4C17611CE0177712AF12086A849440EC71E81778BF572B19352F6955
+A7C3FF5813E88E09FDA5742D2687FF5A52CE741B6A674739A5D30A77118648D2
+BC4766E87B8D166671C5518845FDFBCA2E738CF078CAFF8240829EAE172444B2
+BEAC2C899694029BCDE8F0E7BCE6A049481B41226336D0EDB19A68B597F379B0
+7D1BC9CE42DC548A768F0C4DA0D0C3A8C4630CA9195328B33936AB78691818A4
+4A92380A0EAF5974CB52A1284806A1D13877BB347367BD3BC68AA511CA86E6DB
+84DD4157BE5CF68D7D0FE1F9ADC8F8988EEFA57E74344CD458EE45DD6DD13B47
+FE8E8F2F34CB5E734675B49DF36B6C14CCFD67CDDEFF80AA921DBF1E09638F06
+DBE8194F5125DE73C9F8EDD9E2CE7DBBDC1B572E42F542C114A3500782E8ED33
+3020E314DC7A8BC5AC60FADE9E4BD6A9C1978A4CE41BFBA81271726009FADCD7
+CA4C17F9FBA7D0F64F781E5B7DEF535196371A9A37C9D2D6B22B4C3627199DCD
+E2B979674FBA6230FE8081FE848B5E53F6CA26B494BA8E2374EB31180E5F77A5
+9DEE3C52F0F2D2AEA3BB7190BFAAFDAD38F10CBFCA8843D3FBC05B55E81A0EDA
+886A9D294BB5A6E76DE646CB3BABA1EDF63ED953BD6BC1BD79B2D83FD9D7125A
+095EBCD713E88EB3FCCA6941F05AB1C0C92A488C6A41F4598F57BFB6BBCCFA60
+44602ED83AF694CA988298BD482B3FE8230BE5AF6DFC45D8B242B500A0CDCA16
+82E028FF52F8B004D2A5B799C70C3E6A8784521600A855B909961DA8FA1DC7B9
+89064996C0C2C2FE12B69B43ABB534FFB57BDCFF511B28F1398EA1B357D92A26
+F0B76BFC0E802D4E33E80A2E7741E0B80488842F4905FD04C9894F896DC7BB0C
+D10AC6A99FF3AE582D354362A4CBBBA261F807218B4418EA8C632E8A4276A0C6
+A04E2D35D91A1C31C7435C5DF08AB130C75F1DC0042D5FA182A54310163F4B9F
+719A47196400D39F7BAC83DB34B0128869EBC17B0FE0B881C94C42187692341B
+340A6BEF7186DCA1BB1F085D6E4FE2CF2043E05F105B49CECFBD8278C2E418DE
+FCDD23A1F50D47A1150288FAF90B88C5FC28CEE8CDF9F65F4D3AB698F033ED0F
+66F83E114450384F5EEE60077981DFFA7C9D03FA719A1AB2C4FB2A1947478B5D
+0F5D7A3C110C80C97E9C0A37937E3F848AFF0EEEF00D7625A8DAC0EF0B70CAB8
+E596EA5F5CB3CFB5648A8E990CAEFDA7AF7D029AAB65298B575A94DE25975C84
+712AED72A1125645DF943B5EA4249C0E3FB551B3892BBC55AFB5C4C7B641B846
+3D850409408C5C3FBE32EEB7F97F93A47D481188C10533B0EF697C89A3295C74
+82D40F460A6FD165310EDC482900ECCDED9140EB07F6B6C2A3EEC6E7927625B2
+E47DD2365D5B238C28321554C2A19B1EF33F3C779ED59CA4CE97FF370B2E77F6
+1A956A6C49F610EB88ABD3D13833ED6A65B867ECA5BBD34202258978219B8A09
+55EA0C4862FF8DF1A4AE8C7DD13A8FAEC2F9B3721B1770B8F020A0D8B539F436
+20883821C321C9E1CC83428D3643D77CAC04DFC56D4A729C22E2B896C9F2AED8
+2864937E141EF28450C82CA73AE40631071C68B5850B90393E68C8F7A2FEC352
+74F6B3E5219DC79C8CA9A5C3035C215139B9A2EBFE72F99193611498C814F21C
+ADDCF87497A016C760925550732CC1E7D61190AFE35B92A44992166B4B2300E5
+971E097E58F9E110016C712AC2BB4C8781B1811F6A1F4E322F9D739834E80633
+6AA69AF19875F790F43752CB7C10D250E651A4F5B6FAA72218B103031B6EDA33
+74F6BB36E32AB5EE0CBACA7F896C646D4CF5AEEE149672865E132C0052290910
+149CEA8473DC1BEF71D1B5D04EBC3583027D2A19E0182AE942FDEEAC29BD6DF5
+0972AECF408EC62810651175232EA3E9DBAD731752137E2CFF8AF05D28EE824C
+5E7E6C18CA698D05759FB5282EF9494AF8D213813FCD36D65A395FCA352A0B12
+E45F86DD09F2296338BAF56D7057B331A61E79B2D16DB60FB8F8E8391F375BB5
+5B9CC5060346BEFC02EE9E34A4AFF948FC49AA42B1187D567AEE5B3593136585
+585602F85BBD2219641BF514E86A7E175D543E8B120BCF821883D97AAD39A368
+0EF627DFB67C301C8F3ADB2AF71B3DF8E0503BA85048FBEEBF48C846B7B02489
+055ABA2E3244441CEF3D40B01DD06CE2471EDC081D628CE4856D7B39ECE70604
+B8936E8998CB4EC3F09250DD35B405A84D13F7C852E6BA8160DABC4BF94CB527
+D6254A4A204B0CF35961D19634BBED724A7434AE3AF4960EB4F3AF0174A91EF1
+E383AD336E1CE585B2E42C76F9829EEC08E7D095658B23AB576756B6FF5D70FD
+4B611A735E64EB2B428E46921966FE804901540E5D21680881FA316266239068
+91C23DA5DEC146B63E5B660BCBEA353E7BA49A15F661F2CB7AC95A11823B565B
+474242BA9C41297E2C85B7A0DFFB501C50271826F2979814314B104E1E9B79FA
+6FBD38EA9208EE8873D554C9E80B8B2E25418A3A84849AB29453E28F659A0523
+F1EBA1488B58E3871C73DF7713ABA56462E307F97A9B2EF58854FD3CA3AB03DE
+0E9BD2718E22139549A43EDE8817FC2942A50B0B1973633C3A24ACC4B5E0E7B0
+7F64B21C7A326E9C11BDAC4AC703866A6B77CE1CEAE582F0DED24D635C9FE5E9
+089525CEA85B8BA38A452DE1B15FDD98531EBFD98231F98E6D0E173CED9A9CA2
+99D901E777C113DC94E90DA8DAAC366DE5106FCF915A5403E97A450CBEE2A7AE
+51FC93EAB8F19EB8EC0C774CA15B71B42A705882FC62B72F596A5C97BEEC8793
+23386E86282F773EEE00364704C45DA46A87F8FE4B8151E157B619E06DD0FBAA
+6001E1D2AE9AC01248C087910CD46EA1D245A508B3ACB5F0DEEEC5759F4C0A4C
+1006C84E5F95BA59C81D24E3EDEC5C9C7665C49A90251395457032B41DFAA938
+5A4C1907B43DE42AF31A4F5A3C884A4DCCFCAEFE089360ACA22C787B05A94B82
+A9C2AD44DCA07C2117B21A3AEDB03C31895918D2459B7C3E05B992C27991CD80
+8CB969CE96975477E75DD73B19A135B7F115872C0599E812ACBAAE059C2F64D7
+0B065521FDAC5C5EA97C7C08ABF56426A89945A7DBAC2A278AC861245D7A653F
+B7054FC04443648CA3B5C84DCBF8CD7C5AA4D49EBD51B98D6A249126C168F956
+1A91B140C1A8FCBFFABA976416860D12606396D06A232C3E907D9BF386F21AA9
+E3879385E70C00BA28F999CAB8BFDD8881C142E72782ED09D0DBB0A4D90A239F
+557D8595A2E1C7B171C76EFBFF920E8B45376B50F8686C16F07A1D5C2002BB20
+A8FA69DF7DAD452248D65141B24DE217BCA29A8313E286DB8E7580C46518CF96
+2901F7177C8DB36597967B8D657723DE950DA91C16A8003E42E68BC0455DFCBF
+B591C1F3DA56AE7E667CA7D230BDF5BC526B26E36C0404467282027828BB016D
+8ADB60FD0DF78D689D330319C06EB9D525BC4B4DBEDE358EE2BD7C9041BD4030
+38026697495E8BF0775CA00DFC92922796C240E6CF43037C1D0AA4868E2A28B0
+638814DC05A6D9A65898EDAF9BE5623B2406EE4FF458841BB84BB2C55994D0B0
+7888F3978FA762FD36D63AAF2E4925B4A6241AC1735E92C9E9B60744A9D02B58
+6F2DE72C8F8C4C8D60578C28091031577D15BA1C4EE02C0D3170CA490409372C
+F2998B72F17AF3698CBF8DC494EAECDC0A7692C105A05A9C28340DF7B127F8CD
+F6DD70F190BE5DB39D4BDBAA3E8B66C6C296A58C89DE064DDF56D29F134CB5C8
+A37F78A21B5A8D5DC69C7010977FDBAB4AC413E419D3961A679F4500554369CB
+F19FA601839B5E2FA6D6FA1443782B5575C3666B0EF3C0A60419624A52AD88E2
+A5A120E26A1F0B055E0F36413F9D929EE527A35F59DB0D50C5139EC9C51098B8
+11176067A95D883488B6CBFF22A273D7C32DD8DA236138D035A35EE0A053E0FF
+238C1FD4D11A31DE7BD4D7FB427467389F81F9F338413B06DDE780345D5DD974
+A131C82C1FAA7FAB1D9865676B87CCA505E7066E11FA5B45F6D3EFED871C2756
+02DCED72FD1909F278CF5AC0E18B224E2217FE5B2B7EB107BBBCEBE5F4823A37
+7507C861A296D66905F10D227C6D6EA7F46CF937EA0F42CBE444F11D2159EF83
+775EFDC3F6F400F03FD527CBF434E5B305E17FE2ED69A3EE289D7FD525F1F5F7
+C40F076FF61C0F3A17880216D4ECF038EE7FF589945AD0585F4D96B72558E7CE
+F71106D7DF2170A5791210389E8F2D546CD485A11C4AE4EC5D416C11D9F2CF92
+CA6469D18021C913E875CBD47CB8EEA9BCB44301DE88ECBFAA2632A6B3BF9C26
+CA8D041DD4D0E7D8FFE90C585F870606D892A90F7C63517CB31E69BA29C0400A
+EF8C14BD860BA8F3031F1019A9E97CADC9C9FDB9564534EED221B4C3F4FDBB0D
+0EA49935312D351F23E51FF611D3E4ACE91D0245C647E989050FF51FAA22E7E3
+599F7DAC8DACD13CF2CBCFAACF28FC2F9AE999B2C96A6195D8392E86741B95AA
+A28260C4556EA9680E439BD401D2FD507E636DA8F82662FE8A3FA3DCBE07A910
+744FDECECA4D37C1D409B45C00A8083DFA1878BE01F6B601B6DCC90D19F67B2C
+DC6306FEF183FC6BE537A5C4D19EF7532071915EE17CE30DE92D758C10651F24
+761B60C49E7B7EABCA79749FEC338077D28046CDFAA1C616DCC325E060F9469D
+F8EB4F9270FD298C6AA215942C6D279CF20687E1A37AC2F73C317827E54EC341
+187C97C1943C90257C44D286BBA966C65F17E27D767C123495BE54FD11A9943D
+812D27949EBA7DEAD3A447F53370ADCE724D74D008B0920BF3423F297F08D9B9
+760922869A2F22EF3B54E1F26C74CA1DF0F243BFC910AE37296F7B9A3BABA356
+8A197757F66897ACE8A0297513C20BFA4DF019D6412428558698F2E3BE88F5B3
+5D79127EBC1F40F9FB7FF78674364FCA7547E46F7AC070A6BE1C78BB6290D95C
+879AC41E20647F5C013B2D11EA5323ED8C44716B5C4BF01DD8FDE585E232B2E4
+EA21BA47EC71332860245ADE3931D5244637C026086A109095B5BDF099D0BDE9
+3F182013F1A66212D81449F0B26B4DACF5CA99ED98F18B4DA94C111E92360DE8
+33AEF6C7F0DBBD538C81EF1F4F22BF1A80C21D47085D2C282B098872111FF472
+9C136570BCD0F23DC3710690C92EF231A4BC410B1062AB840503F2F77277F7E5
+C790E50E5A9521BF003E9482EB8DC192CAC2B6B543B9F3957017609D436876F3
+E650EC123DF7D2EC89DF03837D2B35F246F05699A06239008DB2FA2E1615E57E
+1A6BC3A15B8EB98798569C5E46FF639C7373689AF8300CA200AD1E6A3470D18E
+ECF2DB83618AD6D0DDC1774968C18D683A49332586184B11882B4E3D01A95AC0
+3C02EF32FB509238CE6784832A9FED420B03AF43459AD786037CB0A746922D4E
+0DB36E3DB0FF48B845ABB6BDCA61CD3CC696A89ADF2E22D33D01CABA7192AC44
+60510EDEBE116812C010786E0A23D2C2C455A7FE5AA964EAD8DB914914376B4A
+DABDB6E15D932872715627E226B5D3C813651BE179CAFD44184DD3EDB5219FB3
+E41313116CF4E7D1EB379CFCC539C38015288E74C9C5DF65ED94AE2036A5EA81
+2639DDDFDC856D13C557E7A1815ACD18967023659730D1D23A1E214966412F60
+5EC395161C946D2AF9BE0F433A6AA554DA092907FD976A763D230AAEA81357C4
+DEE626BF35789C10B5B41F2A91D8581CBBDBF1AD46DB98ACB3EA7DF942C005EF
+B1E64F1728D53B3A5892DAC032A3D9B397E6CBF9ED1AA2DC43CA38D6B990AC3F
+656CA2D3661D74C76D4C3501AAB24F515C5440F01F97CFCDC8EF865586DF91A0
+EC7CDB099042978264C0729315EFBE1CDC81B0100AAA0D12D1644AF2868111E2
+F02E0E0A963DE672F148B19A2D51F468C01AFF2E3264F3B7CCCEEE3908367806
+484CB066FC7B3A9E00AEC83101BCFF093BD4C3DA6B57B4448F0D358037C3B8DE
+CB1AB4DC60F95AE5345FDEA5052E867F86DA66958A2AAB9C140F0C05713B1920
+E120A4EF101121BD0FF6EC4B212A0C984B6ED432078EF9473BE73914ECA78D77
+B84B838AFE5288C35BD52BA556F361CCB88A8BD6255C5E8323614B2E84A4B27F
+6CD9B7EDFD4AFDBF33E89754CCF00B0D5EF7702509EA60F7B551928D2D14CCE9
+EBC0E79F9D346248AA527DF22C3C4A82597EAC827BC55F93403402D8FBEA7639
+40BDF8DBCFF38C02868E96AE562F0192BA99EE56AFA4D0B64B5D897E0A9A4085
+56D664541B218BF6801889EF0F7AE7381CA8BE66CCF40911036EC0C2FD060B34
+F67F3A6DE12FA736231200966E47F69976F84046D673DC546947D18AE5176522
+EC237FEBA8BF1352382BBA72FC822E9B81DB9EF771EE6AEE109B87B1F6A54274
+1D9A8095CDDD1A0576EA77FD4B5C859282F75B0E8BABC151CB363D730A0C63C9
+3A2FA8557EE12815FB8F5A53D0F36EE5483FCA49F9D643AC8B26B0B68EAD0A34
+EBA2F5EEE0828C16391E5D0F5C0C759655F822B4C12BECA5B81C8A737280989A
+AEF491D2378A7F0907F137A955B2BE24BF30C8B71382643A6F8DDE45ED9D9566
+0CBDF39945F70918DAF39C0D9C989BF337C224357CE001F8C868C1B0E24EE88F
+92090DD28E0E4F12CC6ABDE9989754F1DF6F0B9305E08260A834E3C2F97FB36B
+C6750FB19D900154116C5C2D7294CC4682993ACD754BBB3915C126EE1CB47EF8
+43F0044EED399C7D59A9CFE788E36AC583198FAEA799F310EB54E5F3524734D0
+9484024BEB1717A3E76F4E2C325606E39AFD9250D0A4FC82E229FC9D062E26F9
+BD8A42F289345AEE7DB7A0066B4CA6E02FF77C3D9569A40A2BECA472E085E362
+DE842CB3AF49C98CC485C6D1B9401CC7B073445AF80E59E38AAD8C08B172A235
+913B894C7C5FA15F8012A5022F65B6D35A486E2DE487B3897A4245AE65C28019
+5E304EA97D7E1C5601C596ED82CB135DAEAA246179B11607C7798DFE8A8F32B1
+E175420B79AAFA0A23F5D0CAE915870F8D4A840B0647F509FF836DD9A81BAFF4
+EEC0B0283DD15D09615E02C1EA92610184E0B4F127E2D635AA6B236827DCEF49
+81E16DF5BBD2939FBC9C5089AAB6BE997E412254DDBF427332C42A5A55D62BE0
+B593AF26E2B34E076FC71DA6E4F21D7EE6000C72DB3AA84D9E0B1A05684FD787
+1B8E62F844EFF5529ECCB971145AF13BE7F2ADD2D62DDDEB34099CA54CEEF882
+8846BA06AF5CF88499446ECE01AF058084B1E4D6D005D4292034EE716E7E1204
+20D2722D023BAFA222A4B36FBD2B447F8457C6E2B223FADE55A49FB3678823D6
+94F094850D6007F3823EC4805E5D8F106936C9452355FB30A32972B0755A109B
+9D889ED128E0B10C1BB22A93F5385F7021918699B692D1CF64137817811FA635
+92FC6831A34E3FB22E16E7F431333022F3AE17183B7D466EF8962FD6D6A77598
+8B9EB0ECF01A276CF1D977417BF0A83FFE3F4E2C1F04116F2C81BDCB47940BA9
+672E31B7E9748A15EAF0979490700B9F3D403A1D625F5B229E4940ACFC62E08E
+DAC48E011B89EFADEF9111F9528BC2092B772F7C80C493F1043FC8D55194C108
+FEDCBD1782ED6D64088BEA1C398E12D8F8B56807D0EEFFE341DE8F69050B01E9
+F3AEBC8A420605EAABB1FD20A2C6DDBB016CA3C198596D0D95978E3A950B2880
+ECAA0091D14F107095241446C4A693DC0D038645FDABDC622F3D92E3DD51A526
+42AEF69625E7941487FDE579F6474754291B2215E2D5C8EEB62B0223510007D8
+18B48237B669091E8F81204AE1DFD0BE28C39C7FE61F4C796079C60AC90B4223
+372DE6A5BC492686072F0226C525D575F717070BDAEAA22379CE508BE96D8CDD
+9EB3520F88B0E69F56E72DAED0CB77FDE37DF220A02A1AEB445A2701E1085864
+E8FBC64F0B53E10EE1FFEC765C766B05B35E430BFD83E55A94AF677DCFC2FD16
+A2BA4F1B80FECCE197D0C246A9A3329DE1988892494FCF17272D4243A4562FAA
+604DFEA30540DB06E9EB5F028BC7FB59E138B4C0E5973A023A7DDB768F037AB9
+6D3A55BA64C723406FE4AEAC0FC198060230CD1DCE4AD9A38A265347458927F6
+8D6CF4BBD02FD21C8D48241123E4563B2A448C07E0ADDC26DF600108A7584B92
+696F324E06D186E67E5F3954B69E04DC7DDAD01D833EADDCB802562FB5D383C8
+1B4B37EE95546EA470856F010A6C9A7E314F16AD49F1EFCB64C49AAB640BBBA2
+9A54D16FA80286D06AA56972932C9DD7BE797912BFB430E75BF0C5571FAE652B
+636D6C329CC634234B5BCD44FF11CB4F50EE9A1EBFCB2ACA2ABC01708F1742ED
+BF0345AE22366106EDBC937171D6FB973CF7BC017BEB2D1DEC23D5EA8BFBA775
+A622F99CA58583E600016B26574B9DF996E5B8DA6E3C3963D8CA6D883F2AE3E6
+5D5B75F4CCBE8C351AF744EE8EC447B9A5F1355D2F6D1C00350D1523879274CB
+0DEAD99DB739F0BEB6B8057857F8842DB8C14C55AD2EFDCE989B70DC1C8EA024
+25010965B54859147B01CD6D14849F14B2975D6BCE0B6E5424C8B24B202F699D
+2B25C3EDA416388FB272725F097A61B9B83CA3C7B10EB446485F9BF022C3A49D
+8CB3BA72DC84DCABECB1652DDA6D051A53ACAFA716E04BEF88D092FD24552A15
+E56C3D45379F3DE16ED2F4EDB063276C0CBB3367E0D3CC7A22361FA087DD777B
+7700DF681CA7F8553A785767C30B6EE64CEF0F5D71D7F730D943AEC07FECCE74
+B56561DFFEE203A3E7E324E608134C0EF63E6DE95A744B8425F2633CF988F140
+B850A301D3DC3A593F7A7917A6FF14F5CE8A988857F8B7FC6EE4DEFABD0DD204
+EA64C9E0AD749C6F808B84C2E70FF91FD038FA224E8F1EF92E6AE8161A3481E6
+FAFA49F50F549F60999AA156DD6B81B86266248E6C92A8BEB3435A6C1BE2841E
+AD5C859D0A106813C6DA8D80715C8D26AB447E081F3E6EA832386577BAE02C4F
+32DE579FCA6719ABDD7790C78512787987EBBF8E31D930CA869C2632BDF05FB4
+FC711310A33067C1EB254FDD96D5D1561C5C33C6E2F6D6116B1AE129EE305506
+9BE2A3BF2A014862056F72DD779A759EF65F56D124B4A9B645FB412825AE478B
+B900D11F64BC918D7B693A6B8F99E0ABF7EA9A90E8F1844D57D6CBCB91378406
+C4AF1A285D42819A6CBF9035BC9EC980A1F06C3761CFEDD2CEA92348AEB81981
+B44FCBC14C4711E1772EC20BA23DF1B87360B966074BBDB6BEFE0DC113D932F1
+BFB62CBCAE014F93E0A982E32A7BBABE093A0F613C2293B93A50E3C92F7C86F7
+03C57833BC8AA953EAF04C812B7BBF69401BFBD12175CE30A383F9C0E665F5C4
+47D064D71B7C55E3EDE73D4FDB39474E3477C1F41DDF0676004856981DD66BC8
+52A02BD9FB315AF8E1C8C46D913FBCD8BAB672A63416317D044C0BC9D94D07C8
+F9869396352681EECB7111B6EB787B41F863BEE90DACA852E36AB4566011D279
+BCAC46C22ACF967CC133B8B56275AFA4811BCA2F5ABDD5851E10AC9062EA5899
+88698F5CFC0EFA9B83B71E9BEB3E583D63D6A0E00F7BD257D9CE89A6475D7887
+D2A2824C99BA304A8D6728CC9DB1420295339429E93839B5BD33FD52171A5D04
+0E31E2C3F4A59AF980CBAFE2C0E9F0E3A364E58F981528AE87FEC2F49214CC78
+235787626246215F2EB7EE93BA23B269183D0844798246AEA9F0AEC7913E70F8
+979ADC112D6B9B4630B59952662B3E5410FC51925E1A9D65AE9E34068A8B9E89
+E5AA71F1821A242AAE6FB07E3CE346CD190D5B426227555D8E230EA97579ABEC
+1A9CD2444944F7046B16652A8B028A8019FB42DF74FA89F9019BBA88C3E60F49
+3FAF0BD601A5C05FB3CAAF69E8E2DCC73DB9FAD38F55D4C278B5C87314AD7248
+0C2C3BF34B16B7D3ED8ABFC4AA1B09672F00455486E2277384448F1D7C7419EC
+9BD3910468C06D1201A63F8E94A97D2827E92FA9C9C2E3B5C35DC438DA1F26F8
+7E854D9024664920D6B34AAA9752226FD8E2F55BBA64B7771F72D5C819956B66
+444985F3D121E3484A05C8FD7D979A0BF121705C030BE8D72A0C7D7676B8272C
+61031238833FFD66570C2CAD91E3A007B66ABF47B39664B3E4E8FCAD1D7EBC9B
+F9B260D4F29CAF2250DD465C2C139D088B3EC581A2ED4EF173E5BF0B2F0CA408
+90D79B4DF2CB441059F4FC2A87C836CA9D143DC75EB56AA3E42DA8BF14DDCBAA
+EA0AFB38E56054AE830F8C318ADCC618B52B57ECF18C8A0C9FDC24B51EA348C6
+A9A1063934AD4CAF79FF11ADFF51D1DA20A2F8F7CFF5490A9C9D2DB97A94569B
+1611A53C24F8949345E0E4B44053897C7F96DDFFEA8E228EBF734741667E190D
+4A6D92566B23076622CBA33B9ED8BD9600BABF2248CBC9FE077FD59E3C3D72E1
+95D564FF109714AF51B7499CD15636E1446C9DA0904427C28BD2FD268B2B29D9
+D578AD312880FFA16A784DA6B7ABD8CEF20229F39A963E9FF5D46078DF3F55C3
+ED814ECC054675A2E02115F1A5BF45F8B4F74A6810B7956379BED10C55907467
+C9E9F5A8375B3C96F7B69E06E55879D73D8B46FEDE5682C5C3A98829D84ADBED
+A210335AF38B413C750D6D0535A57A743E0DA9B1815CD73E57DB021BDB147CC5
+BD0F50707AAD31FE3A5CD37C3543C660CD7FE65138A1C411722659C976B9B68E
+A881429B559AD9360271394F195E28092BA0FEDA0BC47879885B418E6E8DB7D9
+7709751F979360D8FECE89EB92CE5E583788E5ECBCD5291C5BA1A33B7113B021
+CB66F820CFD79554CB718FDC9FC0059CDCFC45BC3AB39FC06668DA03F9DB8565
+E07277C11FE2498078A52CF2EF39C825B149E272B484747FBDFA56016EF378C9
+B3ACCDBDD7E36C273676FD3FE43B9A0B41A1A42F49AFD14F0C8F6C2DDB9E25BA
+D9BFBB6A4C521EEAC81F50E54A5A9271D299301D559D22FE00E914FFFB0197C9
+98EA934A19C4E3173FC55AF7210A9662AC29B93B89E31AE842A8D99166FB3A61
+8C620235318769B9C11CB9F3BF88A6FCA52387FF22273580CC3EF225BE4E6D83
+ADBD20361DFDE529FA426A635C3F757CBFA901DF3B5BCA7B950B16A6778F5E3D
+0844017DF62C84A0EFF556B4BC25BDB84A399E4DE188CD3440358A38359974C6
+FA9FFFB69C6CBBC7471EE52AE31066DAFDB4B203232C1C31AFA55BF188177001
+144216E0093E43EAC08857DB1231E39FB13D5DEBAFB7782755BE138B1A77AD67
+8F9E6F233E4912DDAAB2594B4DA0C32F4F956CF9C74303A33B5B61EEAE053F9F
+A2707E8C88C200835E261AB5B27341277ED501FE9A81CA0CCD67459CC0B40245
+D74BDDAFAD40D89F503EC435A98F9438362A1FAC5854ABC086A0E09E0C74EF29
+7F91D038B8B3DD4ED7C47E587EE6EB99DF1DA66B392A2652B8FD8704B2FBC18F
+DB014B15A4A08FD71AD4FE13C862B0F1B48B5BE7C246A308ADB1EABA662BB2BA
+177DACCCE0FEEF2A68B5F2B998B0E5E371BC4CF69E09929310E45218EAF157C2
+18D702A450BF8C0057CBA39132CC04E17E9AD2F8F1D5A3AF0B68C21B11446E51
+51216B23A6E1F49081C5C4DC58EFB0361D077DCDEFCA0B4BCCDAB28EE2194E91
+AF6C99987737998BCE51C61CAFF318CA6215A21B8770F9755AFFC7CC1BD7E538
+8F46DE997B8481C13C46560BF76F8BF4A4426392CF5C56C6EC5E888DB6C8F5DC
+38E426BBED085ABE840AC95D8CA07C3036CACC677FF710A5FF2316D1236D4637
+8857039A64CE593BEF5620EB9BC86B0F674E402C662A7A12B2B3F247A3EADC51
+8459BC247E35EDA8D0EFE5AB59015D0838A883724F9C7CCEF7EC82BDA4F3FB6A
+6A6C3C298111F60F918293FB8A55E1A870F87DEBFAD5F1B27DD475619982174F
+95BEB80760789199DD0F21F6DCDAEA1759068E08B4F346E2893C0C56C9E37036
+476B9B614E727625F838D807074F07AB3059AB26F3D5121A1D54E131B983024E
+DBD29F788B507B034A34B2EEACEECE8309320561CD4363612B86EA5D2E2FE273
+1856BCA3EA097D94CA7B852A2CC829871077090CB6B857614B91BC6D04B84D3A
+0D6326349CBBC24E3F86BFCE5F1BA018466161A6E9EA8CEEDAB5878DC1619C8F
+7E288E9353B7F866D2729CBEAE9FC03AF9734565D7CDCB0EFE4D26E16DB80A5E
+61CEFEE33D280600849DC7EFEADE8E8DC910451687F92418B340608F22EAD7F7
+82262CF10117A75E9B64937EB50687EACAECC0A385EDF8CBFEF3C3E288F781E3
+E6A3D328AB09273C0217E04ED080A696799F215CFCC84CBAC3BD150228C98536
+D8CBCA18350B8BEAF8365144F90D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT8
+%!PS-AdobeFont-1.1: CMTT8 1.0
+%%CreationDate: 1991 Aug 20 16:46:05
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT8) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT8 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 33 /exclam put
+dup 34 /quotedbl put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 63 /question put
+dup 64 /at put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 88 /X put
+dup 91 /bracketleft put
+dup 92 /backslash put
+dup 93 /bracketright put
+dup 94 /asciicircum put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+dup 124 /bar put
+dup 126 /asciitilde put
+readonly def
+/FontBBox{-5 -232 545 699}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0187316F83DDE3E2D27FCDF6C5CE4F95B6EE
+3317BD91B7921F3039DD35FEA387D5CFB6C6E9DC84C178F3432994FC7FAC6E5A
+ED41A1E2EBA350178FBFEB45944511731BA827167DDAC238FC69A5486B995477
+C469E2E27493B0B711DF8E267D3D5613B450011921685147114106C9472580BD
+F531022F6DF5432B2A4EBC51A8032C7F9689B6FA942D849B29709631613DA68D
+4DF7B6F059A19304F40A3C3580CE3B51D79D42984194D4F178801720892FB6E7
+61FF43C63F9256B5E9F4227B1378222BAAD4D52C77462DF01892220E11129C16
+6C9E45BB9F01ED7C1AD5D8B4D72BE0E12969AFEA90FEF170603CDB91CB243173
+B19A56084D10293B80A35275F41BF78A054DDC98F4A1FFF592463D944960FB31
+6BE5F03960F9B1F213CBCC7FD448657FE388F10104D42B0715FC9571CC60CF23
+C72560CBB8835A0CA208FE06676B3B48B093CB7FB2C0C53AF17EC5B372A9771B
+BFD52FFB7062B4FE0106A01A2A1A1DD4EF5C8C7623EC9324A2CB3B402FCC1FCE
+52BFC8662F8A39D5F1B41C97E7CE34E16AC28A1E94007AEA7D4C519399F1B7A9
+48FA7DDB671067244F09C29F95DD60668223F45BBDA8B1C452E930A9F3F341C5
+351D59EA87462FFB30277D3B24E2104D4AAB873BB2B16DA5B23BEE25BE2C8128
+C4CF2F4F438A4E520CD864F3EAFB5363753B82978F6FD664A14E5D6F3A929348
+5839EA752FD635619C4FABF1E1454510BD9D6B538A343BE748AE05B47F917367
+1BA5EDB15F1BDBE806E51B294257D7087334165419A6520462D794D670A1D6E1
+3BB03BF689391D056D55AD660D15A386E6D222C9572BDC4DC8A46EEC75124BB5
+F0E8978FD6031A90E4768CCBF62A5ED8C8087FD66D2033011947634878BDC0AB
+6501DA7E6D96E227068E993DBB0072F037CA4111CAA4C896B6CE9EE0250B51C5
+0EFFAFB8EF7A92590B4EC384EE1929683207E4929CD7257433101E27DC54947D
+F00978B054847365048F06F69F8DEFFE073E32F59CA98FD9247A731415CE6908
+153BD01A58F2A482D52F14F7DD894ED0A02B191CDC565FA10C6ED6DC3344AE56
+E9FC70E591272388021F4A8748A67BC0A18A9B288FCD4C39979A44500B86E099
+A370DB711D17469950297B835EBFB63130EB61014997493D87CC689645D41BD4
+99AABB9646309F174DB93723DFA8CFCBCA0FEDFAB79DEFFA012A57A046606B88
+58BE939A18B4636E21AC5ACF54D0CF400C71095DC07FE6A4E99E765AE193FC70
+42EA351128E04FC669F1CA3A291FC393BF60EA9CD97CC2BD857370D868CC3C2D
+5ABD84AAEC869BFAF8488F39480B8CB70CEB6E185EE4285EC732179CEBE94604
+5148D3097D9CD2ECB9E4A6EFC03AB1D2F88F4C7ED937CF3CDBCC701B4CAA619C
+B9941FDC8DB4D039822B678A464B0CCB1874C1C8E765146DCD430FF6CF5DC96C
+4826860E966E215FAC9BDFC834D700D2FC269B2F410509EBC13C25CD9A6D9881
+E2571DDC88527319EDD129EFAA3C9FFF38BFC3A9A88F518E1D240BA5DB4DFA56
+D6B28B2B7CC75C52C9A9367DC0CE9DEBA73F47A7FBB20DE236A40435159F9254
+5859B587ACD4752CCBDCA9E231D165C2CFC3F4AA1C7D1E247A0FA17091DFD513
+E7D8B400B9FB554FED4FF3E3CE82600D11147BAFF76F679D1A13D29935F77C5D
+95E975F2B598BD9513EFCD772D6F733A926880E6D6014C7A74B1F1C949310571
+A7DE4F7875DB96FE4F43D9D9C1041A43041BB52C05AF16486BE415365FA384C4
+5CF9EFA63F37AA33B84D6450943534A0E4CB218B6918D824629C8F6702C9F199
+C8B4DA38CED24A3459E8F781D0992C9FC46D455D06F1DB03C6BC36026B9BAC0D
+0C8902F27FF548E6E610B570DD8B6EDB6AB09712DEC4459D1CC8C8D21C5C26B0
+7FC2225F44C3D80161B8D9E6FFE3050B952B2E49D760E690A31040E28E2B37E6
+879875DE12F87D3E7B1FDD8E82ED97F9FBA6D2813ADF982EBA9CF4D422503EA5
+283EB10280B29F74865B96B83801D73F0BCD851D6848470F4B55F360EA10B3B3
+965B70BD9851E0E5129337E83D911F20B92D4BA91EF39DD0A84576F23297B6B4
+9DF2B793FA14CEA29EEEC52BDD2BD3A496FEB0D5AE235D12A47B3ED4021F126F
+462268C4C76C547464A9947C2357F33BC0FA9EF35D7DC332E1E7D9F7A2E3A018
+C244C6462890374389CD7DD2CC38AD437F659AB7802F82EA9BD46CB86E832F18
+1546F839FE038B1E3B8C9DA0FCC002B541B2E0E00B7A5AF854C48E4F333E46F2
+BAF6F02038367CAB39F94A6F5B13B34A0E0F6DB6BEA9015303908C025F981A5C
+C8167A1528DC7DC39EA6614F1C9986B80B1E74F350637BE6075CB3B388CF80E9
+3549A87345ED58933B42248AF367625ACACE747F82A2761696AF3BAB8882AF0C
+E2BF72565BD9206BB42D18B39608F8B32B1A106DAB2F53BB47A05BE458655427
+F7B3CAD17B65AAE920EFD2D05C426EE762D29A70E67A3561C496A95958A8169C
+F7308423EB93FD3FA607986411901BEA258A3E3593CF32A039CCC43598BE87A9
+F911FD42C11150FFB9E363F0A68F2260D1BA18A66572201EC3C3DDB96E202A94
+AD750DD8F7FB29D2C8D08C47F8E38AE0E016061D22552A0D120E66E641AF1279
+CA365D5641A279C9F752938C89208E0D415D0DDD2A2A2E6CCF8A92A22166CB8D
+E6DD3BF30CB892C1909EAA8609D918BA28B713CEBE57F608581F7476253AA383
+7A3161C13966BA31FDF6C9C5F761D9D0E78AD6ED732AEEBCCA69130C64E2CB77
+CAC7F5B75B048CD0951E0A672FD44A4437AC12A6A1CEC11FED0FEAE526927751
+FFA46DD429B8158F9BE2D6145C22D64220B82E826E386AAB05315AEF0B0C14FC
+3CC30CCDB25DFE696E760CA40E2D3B6DA1B32EE92FEB7E477EBE902ACFF42D02
+9D35BBA5EB0FA8D01602BFF8AB2EB0108810027DAE95DFDAD9E05D6565745153
+3958F5AB775E719806F9641F25C4DABFED6E555F6B6FD99DEE835D02D756A49B
+DA24C0A82D53DC185CA9F86D3A937470D9D6F429034223DD1DCA717173FB0738
+8F97AE8DADA5B033B69E469FA653AAD4C11D24A32EC9039D425890519F660F26
+79F8DB03C11D480AD5954C3CC2ECADE848D29726F46C0998F48A0A00C68B481F
+65899353CEE0853C27683FCCBDC4B3492B90B63AAEBDEFB80B80789C6C7205EB
+B82E72E9B31A452FDD3084B82DC4E52F674B790F6CB76D98918980539A242FB3
+07DAF98FF48244A650CDA661EBA17E4F0A9085CCB1167A3649E73ABD8C4A10BB
+E0F9736BD694404986065DBA7659FA548D7AA9DC211FC354067D571ED7B93AC7
+3E72A580043BD45239B1972D4B76A46C264D96435777DFD295EF35AA4FF5605C
+664F98208E12E9FF182768AFBDDC0D85CC5012BD8A3940AF7D590B588AD33F0D
+7C402B814D087B867A31B25C500C0806D9EA56F602D574B9D53AE1B62E583840
+2C82C0FF6AAE7BB31170EB18B78938E107036395F1EE04906509EB25664722D4
+B8BA69AFC4C1AD56CA362E721132C076AD2F19CF210F37F1EF9CFA815C82AD71
+8942F60B1CDAB7C94D8F11F272E2E6E04762584665DF78A37006409ECF881666
+C6A8A75613790D6D1D935A57430E7B82CC28582391AEBFA22C89EDEE5C11099C
+1BA35F332CB3AA0AA71FCA7715D2A755FB5535C2BE9347D62AE1C9A78769B18C
+D90D2B4475FB5F74A9C555C7896DD6D7D29166FF7CD927DFE0F57803246237B6
+9437C784950127A54B7095F6C26B16D8B66A1A3EBF53FFEE3E0A389DC9DB8A16
+BA2E5E3AAA6C0D4287BEA288BE1E67430069E70C66669CE73EEA4F13F46BE637
+D4E62A3092B5384326A01DEAE8D8D6C1699B089CB951CDC13C10252CA724EBBB
+8BE747374E691B11C8E6E34C3A3C345B369D99B4DA5D1F3A8CAA7494CDAF09AE
+048235F7F20C3F08EA6B0A224EF6EA13E3BF5DD39B2B4D48F3E51D70A00D135B
+96C261CE4C757D5A8A49F579D067B785608A6DB806E48A7D19CD5018653DE4CD
+A77217665C8F454CE1AA49E307FD189138CA6EBB269F5A8E9A8ECF75B42B2861
+A042E06256388BE90A5DE3772D685ECC5B5ACF663182E41BA5EFC2BA060E277D
+EEB21BDDD99A430E7A7A601F00DC2AD210C6793C613C09DB9335720E202F8231
+BC4184C86073472D41360BD3C25987E6E3668266273704A226FC74C534AB8ECB
+1DBE98EEC7C08471542BCB0DCB387A35DF3DEC4F8EB9EBFFC2E924975943FFD2
+4E0606C6443950B528F2D332789E5D64F94633E3BAB4E55CDADBD7115A8C0ADA
+47AF34B0C4D0F40668247C08B7904BB19E15219C067D3C6CF6A3919638FAF17F
+D929245909E8D87CB1DB811725BFEFB4AD457AB43F8D8CF730FBA475D445F74F
+4FB7084B60A9F833D5A39D0B456858B1C3A435840858404F875215C0A4976F35
+0C7DE54A889C84688D900F971A6798DC372E7E8D72CFEEC40D4A4D8E12BC1442
+D9A4159DDFC81EE7F818E70AF49239D1565CC2E34A4F7D8E140CB6182AC980A7
+4522855B9744B313D96027C30E32A7FA51BB11885F8E38DC8C2B6ED446B66B85
+2DC8D22A348EEA171234F7EDB6151C1C95B5F1BBA45ECB8AFB808F78FDD735FB
+E7366C2881D44A9CC1F060F9A910A361FAB01C1579CC4E605FE3C3ECF73DE057
+A7C27D9AED325A03D4DF4C92FA3A23E8AEE4458C762309D69DACDB5E067621FD
+5E5002D09253062EB7613991A6A3F430A7B67DCFC6CD2544295D18A12914A615
+59DCA81E53080EA3906416FB1000151D32E30EA714CBDF32C3D0A3B927C69DB6
+B9420EA26FA751CF764376C50539BE3E7B71407698E7EA0284AFD1B2A3B4D3ED
+A6D489E706EA852B1FC9235BF28E6F0FF740CFBD3AFB581C66D313D7706692F8
+F8B7969508A4B015B8BE63879F71CC8B0E0205C6D995F0E860E71ACE9FAC93D0
+4B947AF8DEAE35D11DB8F051EB806B2A6AAB414A1EE8188B1F1652FE111177C7
+D7C68FDEBD8A79776D43B9C88FB245CF85D471B50FC5DE9372496CC0A9811C4F
+5AE78A4B8377F6C259C149496E8AF25634C7CA2D8741D9D2E3DD4CEFDFB40444
+4223E4A3D6AE8BE00EE8A72755C35BA04251D3ADF0F913D757BD5FCF2C0D2560
+CA386A34E6B9770178307985ABD1494655869009704776BA6DCC7E8026B2C271
+D539123814B1152A46B99CE07E17941AC8D3F3DB18FD8FDEEECF00278D942437
+C260C44FA423C49E8BE0C2A626029AC92A375203CE45A82284F02BB42EDA5FBE
+B5FD38CCBECE4AD9FAA0404AAE1B7B44024716C37671972552CD73F5C0EA36DF
+76F08D45C48925FAE354A83A2F4023E4D2FF6FE44ED69FEC1ECE52086F5D6470
+A20CB929F6E52D797C42C7A3DA259C878D2CE92E33F24B0A0D315EFA7F607283
+D33C87FC45F9BADE0B0A8741898E23AEF5E28E075862110C8C1CBAEF80961369
+C1CABE3125357350D3150A1821D3B629FA667801556CEBD2C9767F6DADA4B0DA
+FB41BD72ADC6A71CD7BAB7F9AE4DC3C8AD3C362552BF7A3F8D58194627D1074B
+E16059DFECA7531AC8D498772ACA20D79202F21AAAF7BC30A7572C8C6652F49B
+1B50B734D55B30760F529799B5CCD62027FBB67784A8FF6C9F58A0F990301C43
+A6160E8DA551BC3A30897C4E3D2DDD20DEE777173D6D92B94BF898A13D4FD48A
+51979672A13A21205AC67CE4AD609857CEC4C3AECB4C769748A44E06AA4F968C
+B30D049968E2624AF0540F7FD4EC2547145827CAF0572DE8BADB158D0A00F0DB
+46DFFD8DDBADD30469A0CC3D1135DCE8C146D0DF34006D4AA216AE2609C18CF1
+3D122477BEA2747297654D34C116ABE7DA503556E3A02423EB775FED68935A93
+AC3980F55DCB7AE69F0F99C0FD5F6DE270B7989E2D6879B0368C8D88F45D4749
+D80FDA45BDA1AAC875B1398F2DB250ABCB693EF8E5A3FB726AA43EB15717E8C7
+256746DE97DDB2EDDCC467958591A4A23BEEFBA7DA35BA5ACF0D9346375CC4ED
+A54EF505A722FE2C987F79FB07A415BE36D436DE2A30A14DFC1005E97B5253D8
+D1F4E60ED182E94D690CF9DEB9BF6E59B62AB0E96DCE41E3972FDCA85E0E3E82
+36572F9780658AA2012C07F00A9EE6C961E10BCC4B79C653FBC171A8AAF35594
+DD271C556396D59E8F423D4CF333C53C2084D820C7306D70C6FB1842B64F0ECF
+3148A1AE92A6D18B65AACC667EF4227D03ABADDD37E6FC7E08C741D236DDE5DD
+72A761FAE1AB90D3B13F3FB7DAE7CEDD0B446B185749F2B1F1148FE8D0A6A5E8
+57B890F37642A1EF9CFD9A64A45A83F1333D2CC98C136B884142CD3B80C761E4
+9C37C29039108D6C19B7E98038920F5E7B55982D84D368C785D1F4D2B71EE478
+57E2E991F0F85F78F07D472D42D4316A5B21C272AEA47F0748CF1D73E1B8614D
+09189887022E86B1BE68EF06559087FAAF2FD3988A1AEF646F8E0D30FC16E7F3
+8EFA26484306247E169053318C86B730C28BE0EEEF3A8F0646FBCE7F68F3E100
+6F9F30250E2A33BE18B1DF2DCDA26707F2329C8B4B9763692205AA3F3DCACC32
+2016850BD53DED0BFEC4DBE7E47AE9C1F57AAE5FC7CED07D868F313836F1B526
+95AAB531D1D25B4182065FDD81AC9D8E6F2AD38DA4326BE0234E3D4FB470036E
+5F634D6B0965598D9CE759235CC6B934DA952BD18C4AC7A5C8CBC3F6A306C630
+81842485A5EA2B4C0C76D370A2190C6609C2AFADBB4E41A61E356811B2998A97
+11AFD15D0FA0FC8EE02B6CF9728FD4FFB8CD9B29C25DBB28B74F605D59A440DC
+7ABD24B49A07073175CE8FABA09FC9113D5C031FA492D646ED71E85664C3D156
+78C43CCAD79D6478C6032D02C4C7032EE16354557B3F62129ED4AAD382CD659C
+1C60C24380667DBCAFC246CC0E546598AB09736DDD3A73CA4BF8CD92FBDE782C
+485A9144E7498B087C90FB5E62571BD3AAEBA84867743AA5CCDD490064AB6179
+0278384C481B539C62A4BE2A1D5BD132441558C8EAECF17F94509F8C57BF63CB
+E1906E88B54788F6941EF51F1030CAAD0C7813EB1946625B9F198DA1BF67458E
+89248AFE2E27513501F850E9168B989E83E01CE45911D9C52092A8C05E8C81DF
+AB2D2C0A286B7F0C8CD08CA5B93B0C1570345F4133031B3025FA12C1FEBD3897
+63E98E3BDAF56A8908474231693E0B5D8CB1E7CC50D79547E2D01D76B1D34923
+A1F45E7C14D3FE9D25A95E61EC7D053513FF4062DB4A9DED1D39FF4C0FE4A7D4
+4E3F5E7607182B431639BD042A24E4022E41D3F0EBE57EB9BFC21C53F3B601B9
+3626F2339C848567F43DBC66207F22138102B8FC2D80B558D27D2911FFF051ED
+8334F7418075002CD6F9100BF93EE3ABFFFE5EFFEBCA4E35470C97DD58E11C80
+B5E8A77D13A60C9FE68F298AE3E331E81AB8CD0F3AB83CF2A81060D296EA3287
+590C03F0C490CB0BE3B4F8096E57F3F199F70E6C10526D1F345D87C7D0F0BC5A
+D64AFA60A3E5184E96182DEA126406A0E56D5AD96CB7514269EAAACFF23A591A
+BE83978762FAFBEBEB1C42FD230514FCD905B28796DA068F9E8C03B0BE7113C0
+22B278EC32A462B0A0FC9626BA387EDE3BB595E53D01CFD596FE224AEE05D2B8
+8EA91999E6194A02A59A66B552FB49F1D9FE5ED4D29C53A2EE78F9D1C79903CD
+6F42E4C0DFB942E029796B542F44657D5DB334BC38608ECF78138AFB90CC355E
+2CCB9F821892410695FA7827BFEE269B918954D8EEBF2ABA78CCC772837C3393
+CA8C0AEBD7715C89AF096F819457CB7025412838885453132D380A5914A46CA1
+BEBAEDBFC55B18049331E887C9CBC1D1DC9CA83FAEE7B89794AB297C9BB5BE9D
+66C1AF64CE0229A73512885AE1845406FE785B007A6DA8D3133703CCCF93FB90
+1D8C131E9718B3A036C6BBEA1D5089C07ABCE7AACDC8DB1FB5DA2A0DFEAD7FBB
+3D21C4EE1DA505D4ED6A7D10AA7E2D56E88092AB64E6752BCF4F59670CE681C4
+4B78DF95970437EBA2D23AF8ABA02F8B7B866EBC2A00FDECCE08634490BA6624
+B192A37F8B4B6F8C297CEB992FBD08992B443FCC536CBD68DEC67367DDCB4558
+BFD6D21C943D5AFFE869DF4C5AE9C54B9F7A75E633D15AE242C0D248E82B84A4
+2CDD3146EA749C161E5A1FE702EB66DB820841C6B538A35D90FA28CEDE2AD78C
+4291D459C371B806B13C2406C557B456BBC8E805E31E9663580E2751DA583C56
+86D5A5A56B831B90053B79046DC35AD611521FE64C8B71C21B07605FCAD63F8A
+5018363DF7DCAD4D327BEAD99605280620FDB39AB819906E4B5DF8D8D11CC825
+A8585971BC1E3130FFBD055546555B4D0623CAC4125BE73E020EF968EAC4CED6
+3D8E3CB2D2321D50062307474AC45806A7632F415D102A40FD9BF5A23E0E6D4F
+A7D872B54666065B8EDF1E0AFAEF94D2209DD3863C90CD82A9B6C04A66900767
+6F00DFD4EDBF6021E416C3B42B30C7137355DEEE2D18F4CC95C30C45C90B142F
+7195C8A9786A3C1AD00B813A84D59EB0404CCB88F7D0B1EB732888B96F9B2192
+71479CBFECDFDFFFA3C6BB355B3C9FE1D36F82EA9D8C1EB9753E2EFB97DA2B73
+A0538657D2026F7F7CE539CF5062986AEAD7D9F5B3D799153AB17D7BBDDFF735
+2418647685D05A8BDF0AF59A1F4AB93870D49D2A029A837921C9A6C3D91C54EB
+6BCA27A97BA4FC19C0467CF8438C3C007BBEA6075F683CC5C0EFAB366CFEB409
+14662C150CB5DEF14930E497EC4CA56E9219926C53FDD87E2807F92629784975
+1EAA8392FCC89BA6F77BA689BDC903ECBF05A0E031C2ABB4B6C8DA4CAF93445B
+0DE5B7788639BFF3CB6B1A9EB6B8847DDFFA679530B85284B8D8B97D8C231F3A
+89DD3AC023AB047A6007358C7EDACECAEC273839BD3AB978DE5BDDE57468F67D
+4E6AB6E557B81AB232C039D462216779FA25ED35744442F6BD18F6A2FA827617
+6BBC802A41FF4B74EE717E2C5D470C2E866623F4737BE7228A6D87342F1103CD
+3681DECF3CA1DC6EB595DD32C360B4B7EC21BEFBA3BBDE28DBD27D5761DAC1A3
+3A4CC3B23AAF9DE8E9C711D06B49443E2A71B7DC0AEB3E73FB438324E0D81E93
+5387B59955CD4E8BFB8AD9D07E848E38C2E32F9863FAA440AAD9ABC1A003FCC1
+D825E1B5F8FADE481BB5356E9E5B13070D63AA63C1B9F99FFDE234C17B28C50D
+9FCBBA638F786FDA347D3A6228B61B5F726413194801C3B3EC9486E1B8EEAEEB
+B9322AB9832F69FA3126162476E549594D52955006E4A9B2726952E562A39546
+1548D255C5E6966EF60E6F07C5E076AD17215E08C7BCF6AB3C2B181BAEA7A757
+9F7557B9824EE211DCF1D3E4105DB69A9A776BB55AEDBEB563C0FA2A20041AFE
+28F8301ECDB44C2F8D540A48E23E47251E07CCB66100A98611A9A6DD311F88BD
+AC3C391078BDC7B1B0FEE6DA1F3851BCEFB9191654D427B2419E7016B6E7F62C
+A5B22D6FEC9B0D75EEA91BED9D95D20913390B873D2B1F4B3940DB0D1F1E1187
+EBF4C71AAA864723D91EBD3907179174194BDBB7CD79C70D231136EF8B6BB8BE
+47ADB2788798614165B4DFC099CEEF7330627A16BA7E2D2CB4B319728E2934D5
+4941DADB68F1C3AD870DA304E7C8AA8CC44A15F8B9BA14F12A7625169180D2C6
+02618A2A79D089B0909C24F389B545631EACDD55A6444540CA778C18C71668B1
+7AEBF82DFB1B300B83196DAF50CD5973BEF326720A9C148FFDC1FED9428547BD
+E9A4DD0075079E0D712944073DF485C4BFAA6FD7C1895379F8BA00C673916146
+9B79CE2D547F0795FFE54E18621D7EDA22C829828B4CD681968F4934F7ED23BE
+05D0AA4076ADB784215851841D4E98FA280BB5997C62C83234D6C8C913E6BDB1
+41561831E4961E39D88A2B66930CCF642F63B8ED38F9322613411700933D2AC0
+BD940EC4E4073121AA0FF4B4BB0CA59201514A97132206D384E04A490376C560
+BCB235EF089AC60F6B1C9895FC4A7B23D0B83E64A13BA1653573C1554A33E9D9
+B4B6DE94222A0D540FAC8BB6201D73DC187E8D0D4FB0BA2695BAD9947C8386F1
+9F45CECE4985D9CA6D87EDE40706FCDF568A741A8AAAC5DFF573AFFF61A3862B
+E3148B3227812D171F0115FD88570764B83702659919C2F372C9D24BF65BF543
+A62EB34432F7813F2A014574F8BCD08896A26B34CE4F55CB02DA4F9CF1962C3E
+7A317E672A42D9A9EC06BA5B10BA0A1CF21F6F4779F087CD659734E22036BF03
+FBCF026811AA2BDF3EEEDE1E9191499227E6269E4EFA965BBB7DCE8ED02902BF
+E67D6903BE5821CFFA06057788E85D3455825574D5D001E78C059489B2BD1BA7
+77C8BC109B385C4CAA7D460510BFD736937290404B0AE17241BE08A90E0CA666
+929E7B789D4CCD0E4DB271D82F912989F90CB90834B9223DF8AD24F245B1B5F8
+310478227BA1A8FF2D03E1EBAFBDCAE2BC34B02BB74842DE65276F2E6F4E0D4D
+12005907ECB4D49C635195D25D64A19F3645EDA989590210E0BA1D73FAF37444
+FDF945684232C0212EEE51434C839D14C16A26578068A1759C299B29BA0A8D80
+CB942F1F0BB4E61784EE89D737196CEE29715069DFCB80D6C279B3E4DD4F551C
+6D0A1BE85798ED20AB0C2AEB2E88B6FE961E37145D6D1BF0A267C3423B5A441E
+2566E5463718B85C60F2ABB02434BD0C7EA5CD3750181F0D1916817FD85ABD38
+DF7555C33FC9F528F34FFC371F98DE2F213DA6D33A5496EC904DFE9B6D194781
+7A7A06E47677F98951580726051E47E700DF41C0A806216B666157D4DAFA1DC1
+CE159E7E379F0C98C8559506A9D5F36235BF183A426E19F5325C1629B7A33764
+28C58D41057EEB3B45FAD2EE68E2CECB4F65F5BA025325CB0B9B55FB8055C9EC
+54D366D43C3DFD961CB0B5F035ADED58ABF3C7D76D6059F5E142921A8919A1B2
+6543FB64441C350F0D1F8E54F35EAB79636AF0768E186DEA1FAA825A1A6F9BB4
+95A8980ECFFDBD9E086201DD6A0C3986A3F0A81907F427D3F32B61D02368B706
+9C69273D09C323D07AF9A0ABD2B971BB41069BAC212459AC8D3EEE0D7BF03C5D
+07EB71BAC86594FC746342FFB8D0D058508C350666CA61F175C42F0CD9B5A079
+BE6227053986728DDF9EC1E017E405B3ACBE1C4CA2477693B8E062502672C87B
+789E525BAC85E91C99726981B5F15EC61373E59467BEA179C78594FBC36174CA
+77270EE8670AE46373D9E4AFC7810ADC41A7A6688305E2E8D8E11EA7595104FC
+72C887507F8159E1B18FA7B19E6233F80DE2276CF2265A7127F843E1205F6F04
+1DED840B310E97E38B7CC7FE4615B061DF2366DD385BE46FD7E1FD79050210ED
+FD38126BE1925ABDC95081ABABA21E9D74733678012E5D98FAC3B9A96B1FCCC2
+83C27902B6132480433387D64B6FFE66D73D6AA6EB3A323525173C946E90B0BE
+10C76B18D735243EDA3890D0B30FC41094FBF6133E741425182B0BACE55E1D14
+2311E8C5833E25C7CD017BA4059E6956D8A626F7993B8B3FE8C0B2C22424F7C9
+DB1982E704431C0371C6A342C506129783D084366AC287412D61D2F6FFCB9A38
+05CA79E742EEEF8104701513F519A64679BA60711AA6509144A139F18755693F
+225078F885A6722BF7B2D28B4E01621B8949EF4DEA99DF31E159C1E6CDAB2CBF
+3A32DF2F53F8E95079CF9083F9B952ADC98AC214CC8BCB7A04D4C9A5E6DE0B8D
+2E60F6DB353796DE2367D4CB3432D6F794CB7DFF4F9BEB9EA8E8B275C8B12883
+340C2EC8A6967C09D20FB116E2F27A7D2E6381C2A30533817790A47ADB9B7C81
+57F2EF1B3762A86B61AA9D74954DDFA4F918722E7141E1E12D7C37E2B20CACED
+62BD84E09364B7023DB0AE4FFD8C9BBE29525D84CF0F973ADEFE61CB85593FF3
+8FEC4AD3239DA242428460AC4D4EF13FF2A5AEC0883A69B27073E703731FF8D0
+1E6488ABD8652CDD0ED93C01E2577ECD1455E19DF3AB9352C84AB1FCBE6B95FE
+D19360F8DD293E6D0F759705061503922C97006B3F265877BF6C7B9C2EFA5CC8
+56442D6C35B5CC773808EA85E741414BED70B09686E823F4DB7F8FA8E69190F4
+40BEF07E6FF54A3874100107D8D5808C64B978CB0F098A6609ABD94168C2B0FE
+A41C5BA1CAA825135C983BFBEC7C7E39A6D2C0645DA68DACCF84FB2AD5C08501
+687BB99E71652CB4E8E31497666A076D93EE375990CDA920B58969C946ADC9F0
+8341FE62C61C97A062AC76699675315FC141F11074BBA913B48D522EDE2BAB1D
+27C0B5778AD48B34F9A8B3A3CE0EC2CA44C786E546F8379E47E2F6C92EA8F2F9
+884335D0257CACBB902B7A55AD4B0570241F09AE34EF609B81DF8FFAE7DC0FD1
+9508095B5B59AF4DE0CC70993EABF0FB883611CCE7230A3D7EECA1BA763BF85B
+6629502BE58B944AF96827EA3BBD17D3BE0134979AC8CEC1FF25D6B2D194D079
+091ADC62E02E86A58FF98C01E91D8D8E8BAEC7A1F89D9583A0AB6579DC6BF4BB
+A82ECE8300725F6A40FF6B684EF8D3DEE1076CE2A27F2205CC25D37E2B65E8B5
+B9C98BBF61D25F88242DA0F85893A22DF39435738B4120C6658939593A56870C
+C3BDD6B6E6D1EDDBEF5314407E4160D729F39A6BB3EE79B4C88CD7062C775367
+3B7827A59FB64C12273AB3102ABEAEF14005FA6154F5CB9EE3E1DE94AF3510E6
+B01A6059F71C20E90E1572653F47A68C0261F8EA96D65EFE3F0E130ADEEA7261
+14E85BE04C9605DECFC02360D45CBBC4B0C27924BEF67253E1F1BEDB3129D673
+4E701A542265E53F950CA525C7ADCFF99777263B36F4C8E80E6F1AA3F0F6AC68
+D57F392752482ADF6914C5F9BDBA863BB659869E593969B275724A5090D88418
+AFCD3EBDA945876FCEC394938E039840621F764773BBB92E1DCC15E1B05CCD68
+A89C124A872E8A9E820B40EE517B580C049E2ACA2F2ACEA02094F79659D86DFC
+69DFFDFB9DA5383AA1CE42E9E68B7BF92FB62931EF2F155486818CEF4AE5C773
+3532D1BAD43F342DD9CFF5E7C16982B1F85C8EE873E4C660384EC769CCBD0DA9
+33E5A85E453924E188DE515AADE9C3B3609C663FF926951B9BC51A1F76D67FFB
+1BCC26739ABAD5E14EFD7198464169878F51F56A6AE1D63F7085C07A359702A6
+02B04E28A2A0B7B74762488AEAFA87914535BCA742EAF3BB44D874D076BE369C
+C88687E3A165FC5D8A5E3DDAB5A6365C2FD7FED713DC7F13348084B1C6150460
+FAEBE385212FBF488E6407469A02DF990ACF17E12BA2FAA09C39825ABA4217EB
+7684C1EA4AC42D5EF252C39287607A57B29C30F6DCD6FE387465772A9E241561
+5AF6D64E87E4F407FAF9E8CFCD7014AD6B83140ACCE5DDA0BC17568EA0C726BE
+07F6BB90F60C7C15CB339F3BA750ACEBE48AE45A30F9B18E414C1F39FE9C3448
+C75CFE6E1AB36BBF22D323108AEC0447668C40A60CE76ADE931F1BAB4DD18F70
+911A35415FBB10373533F6546FF180EF8CADA342A5DEF702E8B154DA9BB7B96D
+51FD29C281CEEDDDD7CAB5DF94DEB37E67E41D13AFB96C89D9BA96CBE43BB508
+5D42FBA45F217F0E87A6E1656B27F7A9B0C3CB25DA3CF493CA0EED4D59F98C2E
+32E441DFA6762B94FC20917D0EE55693C86F094061EBA18053CDD028D792B0DC
+A2C506FDFF1C9CB9DE1EBBB4A83EC7EA15C20AE6B5D52F3B3D0FCD8A9EAFAB16
+3FFBCA949E2700EE3664CD503A64B90DC6B431AA3F37307D0C5E60B611893518
+D39FD898169EF2E526B734F688CE20CFB65FABD434770BD1E28A0FF21BDA5E7D
+B3CFFBD4CEDD9919898EA41BDFDB92976CCEDF2AD7F53EFD4E5977909857B798
+C793D7D0A1ED62EAB720CA0A883FA813AB7E99D388022A634613166F667A15DD
+186003112EC6CFC45A061312242800CE03282C13E31E1414FBF5CD84889AD15B
+834CE935F21BA04E3E62821290E39B2BF1F753C051D985E16BB3E452645D96C6
+34AB18695C2D75D862494E7B5173D2C77A9E72EA99E780FE7F95BB1ABA02FF57
+5C4250507F10CE82E07C635696EFBCF0E616101EBB09DD7ACA088C6A8AB62AA8
+EBA919B5CBC0DD94C3DA1E7CA021FF31C36B8001558525AF71C8C048EC9B1A8E
+B8EF4067E69DFC2919EE3BE7EECBC9641A090DA833C0154F1E2E3DB7511ED7FB
+03CE31EA7EDCDA0F7D41DCBBA00A66A7F093E29D02C3DAC1221A33EA64EE2975
+323D09C8291A0D9159648E8235E8881B6982C4C13C969884E91543FE3FCCAAAD
+513D0CD45D674E28596BEBA1207C5593E12769E79E35940FDF05EE2F331624C5
+B4F363EA58E5143BEB7D73D8475D5BD09A23CFFD7D4CAFCBB847BCE311FE99F9
+548558DBF2E1DABA5510987F836A94FF3168341DCEBED7DB8D7DC3A027D8B76F
+033CF1D63A5EBA39B12F7ACA4CADF42616FBB1978064047858DDF55A8F702925
+64F1E1B1411C0106DEE8BEEB002D64BF1A2CFA9C3DC65B5689308AF1EEE4C762
+03ED130FC5532E6C79053FA26BAA3C4484F5744806D1B5C259337CB9099BC989
+9270EA2A34672C358BE6EC6E90BA480C01117D252BD39BB4D34B61F0A9F7BD10
+F0EAAD2B40BC5840D52356A9562B28EAF12DBB56771D9A5CA39EC220B1D12D89
+DEB17AFC1226AFC710668AD895C59B545B378982731EDABECA1B173BB123248F
+282CC6C4B8F2BC77A07F3F3A3B03219463587B746DA564B14F2A3105C87D45C0
+F5E73F048902F581B29F31A0DED4C54983CD32F0217DF9CDA2348474BE4755E1
+ECF77B963A182FD015579F6C8BE70A95667132141576D8ED6532026ECFC4CDBA
+4C7B523C883AADAACF83759FD2364E4CD4A7A44B32955F01AC69378694DDBCDA
+F3A61C754DD812231642C7448A7EC0FD7DA39AC844A94C7AB2F7FCF1E9A49CD1
+AEC862DC3EF8A5893230747E6339085E8C7F4F0B669CE08B5EF9393B5ACCF9D8
+54D58B0D5C8C45041076D6B51E62DD840FAC37144B11245C1EB10010C9AC80F7
+F2588F918D3DEB35E08B0C04496840F739515760B07D4285621721084E12F716
+6307A01333DEE9BC4B9F4AA9F1AB8B3088E7844CF2A4FA1F1C33B7A2C057CF32
+DD3414F0F1D620F4F85E67A1B8120E9E63C389EC17DF4022A1E2E7D2C4F3DCC0
+572286CC2A75B5FB70D7CDBF32A180F0FAD9A338799B4CF03B62E2030ECD11B4
+44378365FACC772B7785A1ECF3F17590777F3F76F189D1B9C57181FE5FA3C9EF
+33F4C60709D6E0F2AC613CB3DE485877AD003EABA727C552679E983695E9B5E2
+6EBFD4A43DCF2AE24001FAF0F05899E380178EE1B0AEF69202A3D41CA5675F6F
+A738540523145710F8932A8EFA407259E05DF7C640EF817300864F38264A8CA4
+14A79D2C66640F9E852B8782E43E90D150F0C80DA7B0FCBF5577BED4ED71F3CC
+5C963DFB6CD49461C17593E3B9440B7E4D4279B2096AF024EF759C47DB30E51A
+76F0DD543FA66742EFBAAF78A50EE109DD0864FCD953C3469AD6EFB933304494
+91775A44562A8702C99913C5549C622EC57DFA62281CEF1F60EA1FABD26FCCEA
+6FFFF6F27E7D6576A241EEFCBB3ED8716340E286EF152CE4488D17AFDDD0DEC6
+EB05F3C9674F22CF2FA110F53AC4E33B28F0A41ED0DD549563988434AB9F6F12
+900F498466FAE983623AB034816C64C3C1B3A764F3DFD1E475D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX10
+%!PS-AdobeFont-1.1: CMBX10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:06
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 86 /V put
+dup 89 /Y put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-301 -250 1164 946}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8B731A88D7740B0DDAED1B3F82
+7DB9DFB4372D3935C286E39EE7AC9FB6A9B5CE4D2FAE1BC0E55AE02BFC464378
+77B9F65C23E3BAB41EFAE344DDC9AB1B3CCBC0618290D83DC756F9D5BEFECB18
+2DB0E39997F264D408BD076F65A50E7E94C9C88D849AB2E92005CFA316ACCD91
+FF524AAD7262B10351C50EBAD08FB4CD55D2E369F6E836C82C591606E1E5C73F
+DE3FA3CAD272C67C6CBF43B66FE4B8677DAFEEA19288428D07FEB1F4001BAA68
+7AAD6DDBE432714E799CFA49D8A1A128F32E8B280524BC8041F1E64ECE4053C4
+9F0AEC699A75B827002E9F95826DB3F643338F858011008E338A899020962176
+CF66A62E3AEF046D91C88C87DEB03CE6CCDF4FB651990F0E86D17409F121773D
+6877DF0085DFB269A3C07AA6660419BD0F0EF3C53DA2318BA1860AB34E28BAC6
+E82DDB1C43E5203AC9DF9277098F2E42C0F7BD03C6D90B629DE97730245B8E8E
+8903B9225098079C55A37E4E59AE2A9E36B6349FA2C09BB1F5F4433E4EEFC75E
+3F9830EB085E7E6FBE2666AC5A398C2DF228062ACF9FCA5656390A15837C4A99
+EC3740D873CFEF2E248B44CA134693A782594DD0692B4DBF1F16C4CDECA692C4
+0E44FDBEF704101118BC53575BF22731E7F7717934AD715AC33B5D3679B784C9
+4046E6CD3C0AD80ED1F65626B14E33CFDA6EB2825DC444FA6209615BC08173FF
+1805BDFCCA4B11F50D6BD483FD8639F9E8D0245B463D65A0F12C26C8A8EE2910
+757696C3F13144D8EA5649816AAD61A949C3A723ABB585990593F20A35CD6B7E
+0FA0AD8551CEE41F61924DC36A464A10A1B14C33FAFB04862E30C66C1BC55665
+6D07D93B8C0D596E109EE2B1AAB479F7FAA35279ADB468A624BE26D527BFF5ED
+E067598E1B8B78188FA4BCFB0B51692D07B0BEBB930C6F0997B437E2C51B876B
+61A563A2673932C2045833FAA35DB22ADE12102335D5DC734AE3AC5EEE6658D7
+92EB62131E1DFBA441F53EFF9021D9D4C491F26BE8F54C61165CAD778CE8695C
+EEAF70E3B20C64D4C2B34A084B5770BAB2A974E898F62BFE90F132A37E2DCA4F
+43E13DB13C94DFA8ECE2B7374827AE168634FA007F8981ADA046CED3448BF453
+FCD9A4F194FA648F9FC0971734BB69CB75348A88CC361FF06E984C86AF0EA429
+DAA5808CCE3583664AEFE0C59EDA04A147FB51227A5AB0C13942323E9B3733DD
+3EE7DF7F774DE5D0D0980DA8C0192983F1E3EF18481EAF1EFEDA0068BCBDB28A
+7FC7D9191EFFC574588DEC1E180341DC959F8EF56ED5B19F50AA82A4653649B7
+CDCA11A1FF27AFA7FF189A7E8A7C099AEEE0CAF3E121798B2721ABE8808D20A4
+AB6E704C0C376BD242C4966325D4C939669E28B55BC335405C400A9983B89EBB
+B13D8C5F3A148E38E9ABD86D0171C927F1051266CBBD5C5D12522AF7CC17918F
+410BABDD5FDD279338E8B17434DBF20B8E06B58D9E13B731E3C07E4CC350C431
+CE2034CB23828A19AE93124011BF053A3C5705D9BEF6D95205FB8360391C84B3
+7C6D719C0FB459A312AAC3C4256EAB293B6DC729CC5070524D1BDA41091E8B42
+2B6C4A092995AFB40CCF35730350CBA197F3D5BC5BB83CEDDBC6FBDE23A885CE
+61D416B3A6CEC46474A0F42D5B923A61832262F234001DBCED9A7A00F5511F3D
+C2178422A46CA5494AA8C37F51C40339CF9392A7098DF8596EA97C440989CA06
+EEEB5025B29EBF6038EFDDFD6F70989D63440E9C14E2A1040FAF427EB41259E3
+FF3BA255BD4C04BAAC47326181EC7CA1FFB32CBCAB92B1F8CDE6ED0DD3FE6D5F
+EE14B739FC25BB13CD94A0C0DD7CEDD886AAC62248C64B8439064D1038886DB3
+187F017A79318B69963296B4812128EACEFBAAE983646E021F24BDAA2B78E8FE
+2BCD5BFB302103D7DD28668DA7A60C446A27BFF8D6C66F4FBC61D271B91F0470
+16F567DABCD1E8B04CFBEF602BD9CE44B724B3EB8D30CE573EBB13BAA047F947
+90B24F2E49C20E2474EE9D019565E6FF25BDB3F74DF05BB9E148E1C5883A9EA1
+53AD3833A612643316CB420AF3DB29F008BA36A2EF00D25D9AA606862E0B96B4
+A1AA4BAAFF8999589849411F07E2D77946CBCB5FDBD2B0B19717997CBFD658D7
+04F62F79ED661F4D7DC87B9D27F976C7A2CCE456408703083D0044AC4063789B
+6A407EA9CBED9C091E4FB511833EAF520213B0378623279402EA99B58929D292
+143E0E986592AE731097872378122A70DED836C1AB5C759F84FE2E907BE8897A
+940785D5F56F46DE7BDDFE353A61B5B3BC8322A8310695AA9041C143EE88739F
+A6B7BB4B70EDE1BE28560F21D2A2B0A703C1B91418870B50D5C08E42C27909F4
+17CCD15D47E5F771AFC8DB660F80CFFAFA1DD19C350756444E719A0CED5EB0FC
+05B94A27F784D3F01FEBE6724039B24F3460719C5D82315EC7E7E3BD6E611C9D
+B28C9EBC83E3C89F2857F9AAB35FA5C7243F7545208092C342058A27FDF8EA66
+CFFDF8C918EC50DFD4F331732B523A288EDCBD1B2FD4961C88F9614CE987E3A3
+4EFFFC34CBBD2A96F80AD69E6598B48C84077E511939CD280206F90367E1EFB1
+523D20A15FA835C8D8FEBDE17B75F49CD0D67A4C071E7B63C5B3878BA7B6ABB0
+D17B6322FCA7C5F979EF3FC60D9F07524EF72E2D102C0BB93A7BE8CFD40D6E6E
+FAACDC3A118D4D7B112160CF5E4E9BEF9078C087CDC8A386F02C07DFC9975CAB
+75F500A0B836EC037A2A5ECD803BF9661299F4ED191C54633E4D466C2976665C
+7E360AAFA1B86583AEE708AFD51B0D73EBE32BA7C3629CEC58A1184D9794DF1E
+BB126D4D55A033A94582BC5F28A1C89097F95A50D77156A7829C6510F6E81AE2
+8B4A6F14F125929A094EC3F819BB6574F6139BEF625EC2642E42C7E6DA9B0104
+DA93D16659225E7A111A764AA3B86570F71E2ED26D55742557E8416AD7DD7863
+B8D1190EC70E8BB3561656061410EF42E4EBF7C8478C786B6A6BCB8E1CECCB6C
+9A77992E2D6896D1BFEFB93312B987F44E64C010F3F43BDD110A6DF973A32DEC
+8E49BA72D75A266493B2AB3A42A307179011D0307E727633793607716C751FEB
+0784596E0989AEE8BBFE586F7B4AC15A5D2016A3F12F8A10EA8E08F524FD25C2
+C7195F111E6BA5588C15059B17A967A6BE2DADCA51D9455DAA7671AC195401F2
+A8F9EEC851502E4B6EBAC7F4102F6ECEE8F876D3D591926EC7E46B19F950993E
+5F275D12C48C50ECAD497517919BF85E3D196546E4D1A416752283A0C986A4A0
+09DD4995D66B1D8C59EECBD736E514809BC3D34AF7749B11736FB88AA89AA39D
+5F964E12DB4DBCD25CC750B2821BCDD4E012C1900D64F3D1E4D8CD0850660BE5
+CCD101D79FEF25B3181F18B0421F90EE1D7E5CD5E4735974BA5A6943BA7583DE
+8CD4C21B230CE9D98DDE7992AE64E99EA041B8138A01053C2574F9B0C50F0E45
+01189C276F3264B6DEB4105775430A7A4D8C0550AAB0DEF33FAE4C4BC637A21B
+71712CF7EDC45CAEF1CDE6D08D7E615BC47919806D84CFA35F886EEC4C8404C1
+104DDA98A2E1E17B8692FA5F5CE7ADAD126A4629C26F30A22F3A76A512056560
+65FAEAF40D2A3797066795FDA6895F5349C3D660294FC85D0522618BFDE6BDCF
+8D4E5C32AE9CA1E52BD3EBE6948DF98F43AA8DDDEC63B1061B2F8C8BBD8B8C7B
+0DF1E941CEEE366A0C7D1976E59DD67ED5346F90B6EF07FE1A0EE6967E1507E6
+510E7C9051849D50F0A7E9F4FFABB2B995EBF4DF570645FF6636DB9BA2FAF466
+DEF21ADC735BEC2AF45E4113D1A89F0CC116E198B5709BA71FAE4862864EC28F
+3D86DB74FC4CB0BBBD0376F1AB6CE3E07DE6C2979F8029CF13DAAC74A0F04BFE
+3A40D748D63CE5B5914C0881915C5B8B060C79D1B9B6A7C146057196D855B5EF
+02C0E38B0EAF41EAE4D23C4905C1498723970B2C23EB775FC79E9A0E0C1643D6
+2EBC128E05D3EC7D9761CD58C39D4E722183F52F1C526B303EF2786D14904D26
+BA90A9166980368873999F208FD0A768D0E3B934A1D3DE4A097B5E5DC7869FC0
+9334DD1304CF2DA83FF18C136EBAFBC50ACC540D8DD7C321536934DA89A5C666
+8FED4A1D82DD9EC0681A19DCECF5C4D606B1D6BDA9459392C1BD6348B90B912C
+CE7262705F4300D20B5BFA5A6CDCC843094BE16D9451F722CA8071F40D2CF4DE
+F47044201547ABF54538665F627671EE3379AE20493A5982F3DEDE997B7801EC
+6E07A873DB5BDB95C82844A6BA927B02B63069930B590A2E62EB7BD5A02E8738
+61D0232A38749A52DEE13C8A2317430FC649FDB47AD5006E43A01E87D1A313F1
+189F3B463D86A5A6002D4B0FC9EFA9773D01EE89BBF9D559D212440892C53ECF
+5A768BF87F6E26E9A9B8B4A57A7B29312D9A48B085CB6D60FB388B149B1075BF
+18EBABC575A5A2A993FBEE137FC0DAB27C0B34927C9D7A4D5F491F68B084068B
+A3A10F884809CD1F38F6EB69B020F4FD54DF69F5E3D5F13D5713C75B01A45A4B
+291A5B62641B42474A3D7EC798EA07CE27DC61D7E7F8BF0A0C1E10314A3457FF
+E11F9A1423BEAFE227CF8092D429E0F14909D74EA31AB4292D739D6CA7663056
+E4E95803A994534FC8A6F7F3AF00B60D65E3262C1FB3307CB237E0E092225DA1
+25A69354D72B51E55631E1F0568CFA0F0778AD7DF71A4001B432292391987892
+997DB3691A20C0809253282200E03F02D11E486B7D93775C34DC251E5E3DBA71
+CEEBDC0CE4DF094CE610BB96CAC47541C871A6FBC09693B4175465239F109E2A
+EA0AB6A5393C1F99E75531880C40D6669579DC8834B2D321416D2EDA99060794
+F82BB7BF27F494F5BF149921D2544C7187628AE353B5AE33FBCC8581FED745B5
+16293342D9D80E9736C76A7A7A8C16368240144D402A089CF4BDF4129054FE6D
+F04728A3D9C7C1368FFF22658C5F76C2571F59FD7EA643D107349B916C9B6D23
+3C42D236FA3DC633C62F7D0662F0AF0377A5AAD963F4BAEEFF25770B646962BD
+E669DA4CC6E7E05441FF73E1E50B31A89AAE2D62AA1B1947E42F0B5356B689E8
+2434DC9234A42CCC9CB68F0F906ADC01C67A79C1A645D8CF74C261707C33EE2D
+09314A6FEF969D88415575F1544898822BC381D2A7A81EEB6CF5320161F5F372
+F071B2EDE7A30CD6D3FA76E95A31DDB7737481B1F092F14904FEA7D3754E9E1F
+B4EB8AA8735BA8062D2364A40A54BA4C78C8275C0C7429DDCD5E045A6A1A3EC9
+CD51B2DCD90EC791B08E2550C5071B586A14519B178D2340F4694476CDC4C604
+DE48A1D557F99483088E602BDA970DDC07E238C17065420100E5DA30B07EBEC7
+4D46FC4E1A4A8E9206553E927C63CF99AD7C318CABCE03B6D7EEBEEA1FDBBCAA
+8ACEB7BF96EF6268E82934D32CD3A9BCCA08EA7FFB3CC320BB5FAF6B2F7202EF
+32493724223CCC1A8A0D76808DC97E89ED72F5E45C64E63DCE06603C918B4564
+8E942314A50DA37504CA704039BB9FBA4F79A78E48F65238FD7D924D9423C9CC
+A63EB75ED3E127E9C62103582A507A2837F54824FF922A19498527F46448394B
+8F9D09A132F260F484E88BB56543AAC18F07AF27A276210A2B1C84F1C5DEB002
+8BF3652C6D6C32949191594F63C166AAF66F7F26CCCBCAA659115AC8F977D8C3
+8E5A6FC1C7C27D3C52CDEA11D7EA3F0217AE402965732CE4EC4E5C8CF2E4EE59
+3F9DE39269BEDDAB9DBC642CBFA3A49CD0448E439B63EEB766B8113B5061990E
+161128940AE10E435DD0B7A539E77B5B4971AAF5278D41853A196A779ED62E38
+6106055CF481A00B8DE50D1A4A93A0D08DF38A3261E62C4037C57D75302D924A
+EC5336E2AE088711E103044A9A35EA1F861802A731C57D5C04C9E79DF246CFA7
+9D1B79F193A3D103FD179ACF217742232E88B465D9E8EA746D6D7B1D005C590B
+2BE4C2E8FDBE3FEE3A9476A8AEDF122D73D4B2AA3E58A41F41DB37DE4583E851
+BD8F86F9CDE513F58A9001B5DCF01F22260FB1758BC51F317ECFF3993C576BD6
+329932B44B8C5C4B5AA0145AEF3ABE845BF461B34D65096ACCF7209892EC7CEB
+489C44BC2F5B7C23F6382FDA0ABE68E8B112BAFBBB55B51B957F7B90032D17B3
+5336A76E3FE324A1E3358936E98CCEAB0E6516CA8D060A669A35A06FF466B0B5
+E528EED39667893D9AE0D353F05EE3041FEBB4F38AD7A8EA17B76F209B4D92F7
+FB0EF74DF97F2C5F4813E72EB63A2BBCECD65550AF85693F7FDDF9B5EC16287B
+4570F0775753530B047DD04671BA910FB447F686CE7F999A0766C95A6DE9FF4A
+1E9EF0CC43D14CDB46BECC3FC6548D95A978DB644857853F3340862227DD2354
+5072CF0D7050E5431E1DFD2FA15BAAC284151488D0ABA88BD718551FD7D36F71
+1507667CAED6ADC861E442CF645AE3CBBC789E949DDAF39437A6352766DA4430
+764839822DA891EEE1D83F732DBE943A2F03A61480ACC77660DF405608B0450B
+CDE772D1BEA4D2912F39C29AA78D8EE35B7402711281BEEC6430116AB3551843
+F4654829B04540AC9ED8B20A34F7BA5D11B0ECA89BAF6134A4E0FAC945F6DD6D
+3561C4A3B1431AAEF64C12ECF0A51ADA579BD082AAD93781FBF55B56855A2868
+B0839CDE7F033B6A7E68CF374A175DAB6E017C241CB9A52CAD316903D93AC6BF
+C9A5206D972E405BEBE2FB1E0CACAE44B1DBF8B704DF80B0557E1CEDB9C5A00D
+358A1E232E8AA9A15A6E5E0CDC3F13A2689B157688579F88EEC3F0F9795577E5
+7AF18B0A6B3F810BCA3232CC7C6E7C13F724589F0A0469FF8A5DFAB7375317AC
+E6C074327424FBBDFBA1D75187BCA424932465D7AEED4EB29FE30B2B14832110
+DB02648E509BE11BAF600D9B0DF493B5E00ABEB977D8C6D37E4B614EB385A11A
+AB12D8B0280ADF9EBA79B10F7D0F042698D353617680B066B9BD8DE170D2BBA9
+7AB9EE51F18180AD84E95C168DA3AB07DF7D548815647B6DF9853A5DE14D68CA
+FF85B18233634B6234EF540C368A32ADEC2E734E87E7718289AB66745763EC58
+0D5D0C6A9B5096633A84CCE8AFA9737BCFADD9027F32576CD7B74123D6159077
+5A9AAFB82B6975FCD8DC92244F7AA5CD5F9A5ADF9898EC10549B7B01C585C5A9
+E1A00EAAD335267D628E8845BC62DBE5D2199D96DEA73A03626B7A245C61B55E
+1E7A037B7244C62F68914118CE521BAD8B3A73136883E98514CB6538F1A33AAC
+6390F6D2DE3AEEA9CC566A7CD3F5A0152990B390BA314452128FB2AF0AB4BC14
+7CC61DC0D2ED5C91A07631AEA7172B2E0E4C377BE1C529CDB813AE72F73A285E
+A608E889E0BA048909CF36D852456A83D1136EF1AC4806ED8FAE3A40BCCBA286
+2B73C68082E7FA5606046A22CFD608EDBBD7F442967F88F4EDF7D61A48CBCD73
+EF8084307DFECB1B834FC03C613A3564D2E47D6AAB54528402AB6156F76E9698
+31ED512E4C6709550849507FF36D37ECA05AE5F0F4C64DD3EE576BBBE4079503
+189BFE7F5C01830D285AA4183CF942DF08EE8290A3C4C9E8D393F551F51037CB
+0D87FF5AE177F1A67AD1EAC96116C2C4B8436FA9DD3BDF8F340AF4FB9CF9A7A1
+640C820A354D1401B848D3089EFF37048C4D928A474ED10EE0B6C60C7B885515
+0CB1A25BCF66594ED4026C446DE1BA2D561BD253B907B324C79C1FF19C209F5B
+9985621CE7596916F23214F74C55BBCAC93ABFFFF13DAB33B116B410F3B6EF3A
+9C1A4F44C2BC3A96A6FA3F477D1F399F1E04A5EC2F3F3256487FAA61951EF6E8
+51E2F89E9B4372155FDCC61F225BCD7E8839B4BF4DC26774827377C29882B782
+F15D63DF628FC02546B67A52EDE501D8966AD00B7B85E2405F5E8D7F151A8367
+A0A501FCF6E98078AA95E1F2A39E507475C10BC23247907B40B471B3FC5DED87
+577F23FA2C652CEA09E5CE3805A450D4524AE26B59C7401DD474A01961FBA3EF
+F833B3198AB10E4EDB9EB59241A9E26C29882989B3FCC261C89D898B5EB4D4D3
+C09F11FD7AB94449AE249C3842D4A1853B4D8D29EAA9CB7ED649619B8813BF43
+6B9C46163B166FB6689004022D143E7FD9803FA05C6848EF3B61A40DE7A93BCA
+B01DDED4796355BBB69CCEE2746BA1613A682769435FE26D0D8279CFF49149A3
+78DC2608BE4AFAA792101CD0FD8CE284FC1835F964578317E3358183B07FB5F6
+9625D0E8F7BC7BA99828A981B0771C44A1FE910F204C63E8437B364EC4CAC62C
+B54BA2AECF30DEB60C80C6D7CB45C00C7045974C5166DF72EE414A18B77ACD14
+6F5F7E12F51435F3F5D6280F61F8C027C8BDF7BD338FD84C84ED84B47CEF6EDA
+78941D5623506F1BAEF02E092399D9288C13B7FD7C98BFD4B398FA6EA76CDAA0
+8FAA6EC2E4B9FAFCE1CFFFC883563A11AB7EE141BBA45A372E62CFE64AD60E2E
+856E93AB0507153D4FE8C80060C8572FBB64EFD044E8908FA7AE5152FC5A2A54
+0DC576D679829AAB5D60AACB61E5E81F5395D27C4C43CB4B2A847755B072E916
+A42B33851E6510CBF1627B0AF8FA67DD94563E3DA1D8226FD25B61EB926AB12E
+F736BD697ADEE50CC44A5F71470770E76AE89846769927259907DCC3E128C982
+9557153F1C19AF0DC5A0FA8BE3672866154D9D1F026F0C60508C8EFDC2135107
+6676FBE69C17DA13E273946F80DAB620F8332D680AD46537099B457CBCC08B77
+66D75D1EAA0EAB9E8EEE429B8D6805A7B304B3C4557AB4C9F5F99A5F2B559A7C
+185D2469063529F1C6788D79D497D6055FDEC230751C1C5A8C1911B7409E4ACA
+D8A13431C2AFAF44D8485C59C4F3ECD11DEDFF969B614CB0ECDF8B0622A10982
+F36B66CAF38A0D064D0EB9147986DD43E8E022CEF1681A914712BE66DB2DDD22
+565F852F6CEAD759EFA0475DFB3054B12D58A052E949992680F0E22EC393B553
+D5DF16E684B928CCB2A3E5F1F41DB906CF8125936C070308DCCB60A2C7CF0C99
+D1D3B880DED82E7E32A889017150124EFC88BE3181208FB6228CAA3919F69D80
+AAADEFB2421887027F822A13C4D2E108B7DDE620A6F56D7E7E2C32AE2FBD9B9D
+1C80B62B1B86D03E84B64A95542555A04516953F1828B16E6E8C3CCBD9319F8D
+55001CD1E82406900C25E73C0EC3859F450C08FBBE7428BCF7629DBAD5BAD9A3
+75B72AAC95318F861AFB52BC3831421AF8F9797C8F38267E90C976768CD10497
+13B77F14285C32DA23B4F97C24E8C0D9CC645BC093E3FD237EAEE0F55BA1FB8F
+37014723DEA2583E071E61E88C1105381431D5D29A9980A79ED7447BE0C2B836
+8105177C8217C3EE6DB289AFEC6C7046F10FBA62AB2C6B7D1D1A1FFCFB940A8F
+4DB600E9731E6050C2FB6A186F9315201A83AEF9AAC719C283775F653915FC86
+40DC2A205062E7F490495AD6C3F135041E9DE1B3B6154172BF9E647F87F5083C
+91156A75DA0A57FA4930B646B3703A2790BFF7CF49283C2CEBB39BB63BB39D8A
+61166F64713DBE3D05CD303BAA34A686A9EEA6FB10E2B6B0B08795A86A3BDB95
+09E6F08F32D27B97C23F3386B4B7940997CDCE0991430DD00CC8124CDFC3E0DE
+66495BB405CDDA47AAEB46A0A5C857D3B867FB3D847A3020E37427C2B403578B
+D30F90BDAD46FB913C057637D5FAEA06B2760766870CDD99386561C70BC21668
+03873AC26EBA0D1ED46C1AD9AEEF1B9123970C60E7770A97325B94F6F572C992
+5831BB0253DB542DDE3D9546BF991150600758E3E5A1D4BA40BEB56B709E6C80
+295CA4E20B46C57E6F414EF03971C13661229844453A960007B754BB84678039
+211803A4880DBAB6AE1B6B76263D26EEEA8845F53EA92EA6E904F0725F96F34E
+CE6D64196E360353510DAFD4AE9763B3686AEF2AF2A0B098A7056A663D52D881
+D03073E80FFCF47895C4270009770460A9719AFDB8BF59D5A12E24502D12E507
+96864083B754E889114BE8FC15D9F6867DDB8EAE5EB7AE173020A148AD4DB668
+C400D091EAA6EA5D4A660DB78BF7BCFD7339EF9F7E34F5029E39BD3C3C610E15
+4EE1181388B4FC544C28040BB416AD1FDB1FD7703E478063AF918437D96357BA
+F1EB24122599018A6C8AD37E4A902FA3D3041E3D7F3A2F4BB7E7BBB9AFCC0906
+5873A31DFEC3D437835CA0479B20DC4FEC2E283EAC4754E13985C043EDCAED97
+25D9E51ED27EB8CA29B1E8C51493BE08AF34C2E4406362E5EDDECF85F06DF945
+F074D6EA7A5B606DD3D7D6E81C96DB690749D54633F471FDD2EE9A1F754AB6E4
+B4DF7604C3DE0840BA1F58CBE0FB20DF2C33D975894AF9EAE6C63461DF29072E
+AD4CFE0E97F57E2B457C32293178519CF9FEA669D63EDDE08DC55581060333DD
+5196DE5EC144364557537E0E869D02A9CCF35D930579E21ACE434567DAADE92A
+503EE8DEFA0C4C0F7D2115B8D803C8746F24A1CD0ECF6F8EB5A9DF8F3E601A90
+42165D15B55B9C53C622892E7D6C26E67CD91AE0114F5979563969FDA33A687B
+C3825AA15A79091642DCE0A132FAAECCF9590243E87956330F09A776175A3C2F
+C651E89A73A9E1EF387AE9FD68BA48660E0B8E80B2E84990586DE7FEBBE6481B
+E79DF22E50AA118CC07AAF6D53C5B612561532E7B9486CD0E2428D871A7CA4BD
+6C797A665DC72C3D925DB2208586EB735127920CD5523DC59501E62D0516AB34
+B48A12891881C5511B4781DD8532F998C7CE305DC9E7C879F3C59404F21EC643
+9446AF52094211E37631D6FDDD3F010755EBB0D4318B237C7B8E5B892A1CE8B8
+3DA402E41FA2DCBD21543B9EBC7311DEC1559C0D4B477B31C9AC27329869550B
+5AD5F31E98FBCD6294C0067C9D7BF7FCA97F03810025F64C08C858A58DCBAEF4
+23CEA7081D2E35F13E8E2F94CCDD325DD9844BB6AF8CB7D8B8EB82AD4D7C42CC
+38265F74CC3DE12C249822038FE84EEC468F77A333369136768D4A0260D18E8D
+AC6E55C8752B4EAF17E74BC6C10DF86383B6CECC66AD367C8A485F9333AE060C
+0A4FC60DCF85AAC2DF16BE84E8472DC07CD4B8FC0F8B860BB9864925EEF83DED
+B4495813D0ADF6E0D98FD8AB87C65E681CE71B4782BED1B525B595A59C5273E3
+B5AD7CAF306E6E0CF7CACBDF910ABF94DD6AFC4F0CBB729F0445FCB834D63BE7
+51D90E072E9CA8CE0893DEBE52E0A53DE4F3F447C58DE0D13477ACCDC7AB64B4
+E548633227CDBCD82E4C010070E2A10DCBB2BFC5FB90C0782971D509B3864A28
+A06B0DF9044F356D728DAE6831488B8A0C15E366CAC6B390CBD68E5424C6F5B5
+E1F76E015E7F1C2A97FF0914EAB3ED733F72659DACF61E63069205706F50E0AE
+AB9C5FAFC8E05C87FEA2E668F3B38AE5EF85878404BE1CC1EBAE25CE6489D033
+095DE9BD116A56FFA093412EE92D4327CC3B45445CC0410DAFF51EFCC032A24C
+B8297A2EEEA06D2C27F73E051F0CA4BE02E3C53018AD869BE707BD114C3020AA
+F3BC48D08B2786EEC91E9C018371D164A1B5872A5D7251468A60BB81B75A04A0
+BABCAF0B71A0AB3148FD9CB93978AC25055946048D3625364E9875F8C05523BA
+BBF68378FF985BBFC0252191790FB0ACC846D0B7396B914564EDA49586F3CD3E
+6A187DDADBA664E76B4EDEB2AA8D47EF717233F7428884E8BDBB7BF207840622
+AEB0CE00A2F046B8AF798FD593BEDD862D00111B84B2A657A30F68DDF92F9E98
+B40D99CEF5DA140C1D3DD28AF14C94DA3FB2BE4121977A4EF2CECE55A6D8ED38
+5F1E5A43A64AEC55F4D5A0256453F0559DA22A5AF1C9DEA56B7B1592F650EEA3
+8FECB0AC1CC54BB64A36DFA34484765A74A2D6619C849E84697001BA85A31550
+030807484E3F2DDFB9299D4BFA52BA93EE7FF8F788CBDA374C9156466124E492
+C80D94D5A377A270A6BAE28E2872599223080BC9F665BAD78D8A46A67F466158
+F943C31CBFB7B294DD0204CB0E1AD04B9487AC550C4F8815AF19A2EAC52AF5CD
+640F65E4F9F22C49A56B581C06A03CE7B68FB398FFF7332E74FEF5F6533CF525
+73727249D1888FAD0383C523F6508F5ED8EB9449F2D5AA99A04B093CBB38FC43
+CA3FDBF847738F0D40F5D57A9121AC7238788D0E96E09433E9F8DF0287C970E8
+E832A9C206B332E15443A2D23FA5FD2BE4370A0FA7AF8DDB606F6736725CFEC8
+31BF024FF9DADB6BEF610A2034490BBC95B4CC6604D9A39870540652DE6F99DD
+E703113756F1DF3A6554718866254051CD8C310D8E96952868044E945A29914C
+1EDA47B12301DA809618412BC1A7A6CD7668778F7732C223304F88477AF1F9BC
+071707D9B2131A966BED3D5F06E083B295DB919277D6A336FE689BDDD3C221B2
+37682D2998B5DFF0123E87596A85DBA412B542620426CBDEDBAA5393AADAA221
+42167CEA7B60888D9D7AD22424A60A5E54E7414C8B591F4C238A4CB278D2B7BB
+D2425638F23BA2EF8F1D87E2AEC76418B7E6F2427BAA92EB0D998F07477312B9
+E67394C2861036328B40EE689E3AFC556424FCAFA263D7DB40814A8BC9D160EB
+DC3F62DD78089BC292A78EACDA0BFB3246B065E670038148243E331D53B318D5
+4AE78A620D3CB22DCB80AA7368718902B72DF0771F6DAC80E7D605CD10BFF85D
+E26CB4E653AAD36AB162FC2424FC3353D3E57B07A509B1287C3399F56163ECEA
+2CA1AC11BE9361476FBB65C99EA7BF1DAA607ADF5A3D5113F230567819848912
+B427D8183AB4D4A28760DE738CE192DCFBFDB421AAF2AB14F6E3E83A602EC907
+BC8B4FE0EF9FB6C4163537B6B6A9E2248E4A9D491E5831D0121C1DB6243F55C6
+081295E06D6FD01C107CA8E2AD4FCB77CAF127240A3B0FE67F8BE310037089D0
+7F92005B068F1ACBC76355347C5EC6E370D773D6FADC16C74F31300A0F4974B8
+7340C89DEAE5DE97474F2281FBCC9EE2092D75AF7E9332BA71363750BE083427
+EC22AB844AFB76A8DD7E521D932E9AAD7D73909E8C67B427E64D4AB7F07F117D
+099272F97DD809791E1A1B3C098AE75E00BA58613409365823D0D9E541290439
+1AA98D4CDA14DF3D931554ABFA51D4EAEB13D0761842C243F6F9998F83105790
+7F160341B392045FB7730BB21F0029E2B1E2804373E35E65DF45A0B3BCB2B038
+D9C5B5324A031E0019B003488A314F0DB4F83C6FF82CDF84B3F1DFEC10D471A8
+D2668EDBB9DCF3D7DC4334B2799652D16F49F67164FF668B1094E1AE0CA5BC61
+110C9FE775954D1DC36848F9135C0EF8B99B17D75D929CE94FDC285611299029
+7722B0C3938094A49DA4DF04082DA0B0E944
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR6
+%!PS-AdobeFont-1.1: CMR6 1.0
+%%CreationDate: 1991 Aug 20 16:39:02
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR6) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR6 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 46 /period put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 54 /six put
+dup 55 /seven put
+dup 57 /nine put
+dup 59 /semicolon put
+dup 64 /at put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 74 /J put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 82 /R put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 121 /y put
+readonly def
+/FontBBox{-20 -250 1193 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C
+68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361
+3645B82392D5CAE11A7CB49D7E2E82DCD485CBA17D1AFFF95F4224CF7ECEE45C
+BFB7C8C77C22A01C345078D28D3ECBF804CDC2FE5025FA0D05CCC5EFC0C4F87E
+CBED13DDDF8F34E404F471C6DD2E43331D73E89BBC71E7BF889F6293793FEF5A
+C9DD3792F032E37A364C70914843F7AA314413D022AE3238730B420A7E9D0CF5
+D0E24F501451F9CDECE10AF7E14FF15C4F12F3FCA47DD9CD3C7AEA8D1551017D
+23131C09ED104C052054520268A4FA3C6338BA6CF14C3DE3BAF2EA35296EE3D8
+D6496277E11DFF6076FE64C8A8C3419FA774473D63223FFA41CBAE609C3D976B
+93DFB4079ADC7C4EF07303F93808DDA9F651F61BCCF79555059A44CBAF84A711
+6D98083CEF58230D54AD486C74C4A257FC703ACF918219D0A597A5F680B606E4
+EF94ADF8BF91A5096A806DB64EC96636A98397D22A74932EB7346A9C4B5EE953
+CB3C80AA634BFC28AA938C704BDA8DC4D13551CCFE2B2784BE8BF54502EBA9AF
+D49B79237B9C56310550BC30E9108BB06EAC755D6AA4E688EFE2A0AAB17F20FE
+00CD0BFF1B9CB6BDA0FA3A29A3117388B6686657A150CE6421FD5D420F4F7FB5
+B0DAA1BA19D638676E9CF159AC7325EF17B9F74E082BEF75E07BB563C96C0A3E
+6D4DF600BB73729BC4A5B134928F1370B9F07C587F79388B1D9AC62BFB1566DD
+CCBD1F58ABBF1F53AD21E3BFF25EEEB046F66A924E5F431EBD7228050BE2DF43
+0B9B538DAAD511EED97630CD9A9C05CC49DC251325A93EA842C6D07B44BE620F
+08E66B611F54314B0177E299304F2294F8DEDE9914736944F125A50B5007373E
+588AD80D9983CE7824DA30CEE5DC3114D69D7ACEC0758D8201805B82925EF216
+BD209C5FF436AD3D4BAC20D6F214D9F89CCA7D963A27C231A6B5D4CB1613AB6B
+2B9A74603C2C27CDE0482B706838C3C968D63B077CB589B6AACD734CC4C5873D
+D0821F16BB4572B85A0B669B65DA6E4B7BCBF3016ADFE80C0FE131DF9E55680A
+7762E47233779AE4F61F0CCD20E3747C1B023C4CF08F04194AF4B6674B208B26
+FEF84CDA523C3C2539A82CA8C4248CFAD0B65D64C40D2A505A9A14DFBEA1B1ED
+F63CB30577AFBE901B77B11041D98FF728DE220FC017F07BBFCC6EFB63634626
+67A03FF6E946F4EE0483C34BC782C6F94E0CB7C4096AE8996135DD720EEE24A2
+DCB1284C445D012018E6960BFF60D78392A6BD909F1F6D849C989F6DDEE426B8
+6C1177103EABF2D3CF3ADBFBE2F8BC630C9AD3B101FED93600C4B88C5F105D85
+A544D61185B178BAACF327A94FED7F86A836C268266113E8D9B26B5E2F3A97D9
+CDC32259261BC4FFC26E7F113672168A46B7542EBA62D0C524263EB27A117EAC
+DAF3141E2D1D963552F3E54D973DF1F559C16A5C2E75D971B5E8D1525C269013
+9DE947965A70E81C4B7952BC9B8A62AEC594721B6E10CC96C106183F8113EE20
+09B8B1D0FDBF4E9385F33C183F23DF88379141920BE2BE049F2EE0FF83E52CD9
+125596E14FBF9689135EB9BC926F4359AE2364804689A11C963A1D06B9839125
+DCD6F3419FEE9F9E8319140DF508540FB591CD0B33BD6137FE2874B931F810DB
+589CB9323A7F14E92C3BF41768D34CD59F9E0DCCA83A64AB940946DE847687A0
+C7E45EA858A260DF5E5BC92C1789F5B1BA8C7F01AC9189511F3A34CDB3EA203E
+6365B832BC84E4C578AD41797AA86B1DC362E9A9484FB52F1F2B5B3857BF2968
+0AD18607DBDD6250FEC6057265431247B98960126CB5C358B99586DAA488D12D
+6CF6BB4732803B407A32ECB88C4E24D484255A5E197B67EA9F062ABB466A6ED5
+F15C6E27B892D368060AD5ACFD625C633AC492C073E0FA92EC7EBBFC0652066A
+D0E27513EBD0181AC9EE867434CB87FB6C3B1988568B6C3D89E288F39CC702EA
+1B1F6861308D6F1137BD59B94A45B46294B0659BA579BA61AF2A7BC1785E30B6
+0C1CC24B10B50615BA0934523F700FE57834CFD6944E1A750B5F9BFA3490A010
+6D92A71E6BD35122671DEF37DFAA83CA6CD176BD9C26D146692C3C6EBAE3B489
+E76997CA21191BA944083285ECA76EBE94E470949D49B8C646856B3C879E6689
+1A093FCF6A42D46FE224B007AA995177B8E697BD4F1E2A29F0D30952C842AA7C
+A6BB0960CBFFA5EDCA5919174BE52769A8DEADA9398B1C7584F80E52237D9798
+1F81230F3F1260180F49F856F04E72D02C024B5FB4AAA03133EE18DAA05692B7
+9FBF64466AFDF3536809D4863EDBE1B9AB81200A69FF52AB355D08D5D55DE12D
+0D55C507D8C561CF9D3D55A5AAB2039986AD34CDDF8E582801D61543DA4CF1AE
+83E2BB0531B3E42D6594D8F4169CF187AA568688D8FA65ED8357191B4EC058B5
+CB47859857A8225D775CB3E972A35C84A85821C3BDAE9602F41507D30A7BF575
+B1E6827CA9FC6D7A528AAE10C50C6C4FEDCE773E5743D0790E10B0CC6673F956
+8A642A35B251AA31E8AA9871E79E3B77FE556C4D9E5E31AB58298B58C7451762
+67CA429EE8CF8F47D6BAC28A3AFB0CBA47C08033A45F33DFEE8BC4E2C3D8B003
+CA46F7AC88CCE2F3FB89D75B4AAEE56A1B2BC8C05CE88A6F28B901D2B3A0A2EB
+B9AFF04424BA1476C8FB008DE558C74114B2827822B9311726154507B7B85C57
+4F6E90663C8151B62A1471B273E52C1C2D7CA31125CEA0DB8EFF71711EBD35AB
+65F020D486F8FF8C94764E47E244621F2B6EA2032DEBB8D29959D86D5A74FC44
+ACFE94E8A9C5DAD6F381AE2F3D6F79E3493530B348E4F90D2A69C4968EACD81D
+C7F851685D0CDB5B0CF33A9383B697C2993915FA01744EB98A35DEF685BDC574
+A66FCD19585679B181A6CE4EB42C2F1F0DEA01084D46C0C5842ABE7B4B0948A6
+283630E84201362384D80CD0573936E601D8D993783739153649D3B9BC7C1218
+4356BA585BA414E8799C9E9DD506E7B9ADC3AE3BE0460AC1A4E0ACD570B1A780
+773A1F7E0980A15439949B4170115A6F04459E8D1793731D04B52DEACAEFC64F
+E17A4B3C7320625B05711B6CF1E38BFF5357DC6364BD2CFED6F28555CC9041BF
+3CF4B52C413B53C48C169490E91ED3547B05034257A626B6676096AEE978BEBC
+A286A3C4AB3B07F33E9648C31F1E3D68FDAC2B8612AD55CA25F0D5168FBC7FAE
+9F3DD37A9855EE0C41CF8CF089B916B37D8E8C1738D99CC19193BF6B25D927EC
+E0410496679FAF5957DB5C910A06A5AAEF993B9D6748DD3B09033C312076E8A3
+CA6646E22A83CF8229CA5CFF432D5F0CDF914A0CC5CAC5D0ABF779C306E7E0EA
+E5FF8011CD264ACBA1B388165B72111854B221DEB49AC4B577E4A1F6B7D9DAB6
+07B645D223BB35036AFBA18C99C7157DADA7CB99E1D05A0D6ADFCC905EC0AA50
+0B7E03A1A96154FFA174F8118DAC7AC66015907DD8E141932DA170B56ECD039A
+AABECFE29F1D7380DF65509AD4BA93D76CD6D7CC5C3AB70B80E2F94EDF404EAC
+376DFA48D1155F2F5DAFBA71362243E1DC7023314A977549FA0FB64C0E973725
+DE4A2FCD067A0A51915D8F788DC8092116DCC3FF5E23E4D935E59237F04BEA83
+85083330FE527922067B6EB1F09716D8C5A4525F9ABEA5482EC28DD13C222BBC
+CD9E05D435E1923E8B3B42CF85729746E24095A3EADCD06A845F4C2AF93DFE6E
+12A563B0B200EDE7E6CDFF5FD0724374126B1767FF5498467E0D49C4A07D3770
+ACDBE62159BB1898E2B433DB7D629CD8F3F4C2B9392DFC0C4ADA5BF9B03710D1
+68011E3154B61A6A38D43797F33015E4E97F2C57D3CDD8295B0E7EEFB1B1F8EE
+F97AB546EEE447B356ABB06EDC324824438A5287821BCB7E7A5338EB36DB768D
+462E008469FE4BADFDCAF7AADCBFBB63CFDBBE5147EAD6C5AF942753A9A7D2F0
+CB6291EE5441F0C6F3AE799826A54758EA0D4F8EA00F2E450D91474AD4B3178B
+B65A6D86909C8242B814F3087557B4108F0B052708257B6CDEBDAE931CAA2295
+32B3788FF3AD4E3833D247A2B86E067B5175B5D157B7A6D57FEE783269146078
+0C9259218F6EEEBB2EF746DE074FFF5066BB8BBE4694E2FF8FAF91C878DBD117
+9465D65A881AC5CA4C74778E41739F2A3BE03A33FE49FEBB98E90234DE4D835F
+97A3DDE860E4A30DEDBFF61B36717DD91D5C9417640B0E4BA31F4F8494A1F645
+34CBB593EF1D1571BF27FD2A3F81C4F1622034FEB55C44D2852BCF4B7571249A
+2C5D8AB60FFCD931370D747C7834776594450C968AA7DD5F1D491726B0B22469
+E5ECE0FF49B67500A78BB012B1DAC77B58D4BD311EB394C4A7AC27227AE67211
+33F3D2EAE4A08D62413AC73058BF50F2CDDDD4D655AC737DC8AEAF2A8B8F69B6
+2EE5432182EE306FFCA3E777225D500E02D54DBE5E271AAFCD49071A3FE3160A
+4EF901B61EDF106059A368F3640A432ACB6C0C05E2D7511C3AB6DF1F9C032F27
+62E017E03829D80AD3B6FF3A896276DE7B5264FD0457C490FABD47C79F6B9988
+6A2AD7761C70593A43DE797FB02C009F0FEEA3A52B53E9BF2BAE190FF5698A13
+8DE051DFA8FC9C385F7B0CF002351A6AAEA542D6C4FB182A103CBFBED0777CD0
+A5414084C2BB56B0139F19DDB06D7C99F676CB42F10FE4822D0FEB145D1BBC3A
+90FF29B94FC74447FFB54888E3B45611D4683E9FF329A47DD6B4D2B6AAB98357
+2CB2FE78D0DBF36724D0C42729B27153098B077B08DFC9404CF7A0D3C586B48C
+4049F8E66CA713E797FA701FE1DBBF06C900ADD95F8138359DE83E9217AE928C
+B1DC6853E5DED8A685217E50AF484C2AA2B784F14963CEC41E66F203B8522102
+A104119C2D413AC44A2DFA900251C64DE8B0EA2E3EDB9658E2BDD53707FC60BA
+CD9701B4E720EE584577BB24875E385E66A3BC154E56676C401281410F212F5A
+EFDA1268663987262690277ACCAEFAC04F91BC95C04EA441E33EA026D56EA0FB
+FAF3CC4582AFC9D83081F8EA80ED24CA4B29C269EECF0C3560A138E8B6FA9F7E
+8A4177AEF0F6B174E9699150CB18DF8C7BF7AF4AB87056B0E670163020CFB69C
+4E98B6A79E656C6F44B449112508C8AB5D7C380B7D0B38E843868AE6C6500299
+4C61C764B24D8E914EC2E4372FFC12C172B628E35B1E4B42233E8737E313A83D
+7C9BB76883B0A7939A960295B947FAA4C251A2944DF27C986D69E2848729FCF7
+A180A1599E1E5878A3CED8E25C3732B32CB3FDCA6DE0A1502456D9B0799351F9
+DC611A28F998508AA347A690DB2B2B4E99B61499655F9F014DC13A4E7C4E3FD9
+1FF48559DE1BE245CC876A8B011CB0A167ADD9A77F4E66996BB244A589475BCB
+9B916DF647198063E404F99675C33442C5DF04BE569616A2E2FD01A6884419A6
+311DACADD1083AF250132D42FB8A0F5B217454A64B23F4967A0138182C0AACD7
+268D01F080B58213DEC981923138D6D10D5073AE73CB4E6D75329DAB0B58C229
+FCFF7FCEABDB89613857350A221865CEEF23FC065D1B1E70C717724320D27FF9
+07754BB4AA8DBBD122050BE3B4106B5FA453D8AC98A0F86D829755EF4D3324AF
+5E271D4E7ED463461D8311E384AD5391756F35DC5AB78AD1C5F55ABA13035466
+004CC16AB52BA0227D4B6E645BF0C2679A154C24AF6A267C227C0A2FDDACC610
+9F8A51DC3759D8949DC69557B19E24E8B2A829A7408B7BFBBB9486B972172621
+162BFD558B14F75E0B922140144A275F665CB1DB78AF3ABC9895547018AF7A52
+52B34F26289CAAF7C5F1E2B058F38F65BFDA4585268436B2DB4929534BFBF0AA
+C8F836C0D37FE90E294D44C88CA39931E3219F9DDC38A6472FDAB01557FF4E06
+D423FAA6958983AEADA09DB2A2F6874A87D9C6BB07B7312A7889EE4396767DD9
+C83ED5998ADD19328CEC32DCAA43D0949A6D94C7463BB910687D7715FF0B5FD4
+DCA4C626FA548158BDBBBD1BB56A4A1B92C88B1771D76ED986CBEDA938E02241
+80C4C14EFDD4B7D8A5892C47C14F3DB4165DCBA083ABA9183B4EC464109D714E
+41CCF74A390C638C2A483ECAC9C5634B390E4C794D79A92E73E9252BFFBB5F29
+2DDEF53897ACEC81170F25A7D939F991F301951AB07FA844FF18CBDEE8B4C915
+743C05B5FFFE92A06F1B741ACB311F2A68D7455EE94DBE94B949705F188E91FC
+480836288F583B88E2D3476A84A1458334046E25A3458FB56D184A88A2445BFC
+CED319C452BAA61945E6427457BC7F064BEB030C9346857448889A78C57500D0
+49D020BAF5ED109D31049D35C8CA83B0F9E41DD6BB22A22FC6E642E012853E32
+AC00650B6DF411D915EC7E7AE54B266BB6747A80E2A0344AA3CC4D77832D57F7
+49E234D86514CC2E5B668D385E281B207772F8B6843CCC3FD3EA4BCEF86D9FF7
+11EB8CA9BC3B5458E64F7CF674D2A0BC71C14FAE3E028045B1B6AFF84949713A
+F7710CE7F0BCC4CE9ED1E052E033903775C6BA67DF64A0EB22572BDE2E8E3A84
+4907C8BC3F54D6B77DCD301EBE0A16BF8647558CE25C8D68086C5952999E4F51
+434396040FF1E2CA290C7535C8A28D2A3C8F4D8A0E70890B5CB40A47DB60B31A
+8F74AA15C22696BD7171D206E71FF0DCBB418F786BE0D49B358F3BA888433FB7
+23980E50C48FD5DB43BF0E2223460CB791FE6D5276A9404480CEC4643BE8A0A2
+ECEDD54B4307A416406735AB9776C25838E774E09DCF2FDA749D71D26FD30B06
+F99A0663A82279495B975C2B17C82B05E58EEBFBB5E12F98DE82FE7867FAAA2D
+91756A4F7FC54E368C3AF0BF9DA2A344E2FCC76A86E20DBB6CC026F05154A9D8
+EB08E200711BA1E330F0FF1279C571925ED0E7BE86A74BD036A4D9E6EA4295B2
+0148D8AC11B8A36321728931D000C264BD878BEC1D94FC6FCC4720CA3FEAABE9
+2C97D6AA01B3DCCF0D89CF7437BB9EC1F077641AC357C4AD7E9D0D3C953E839D
+92B4A25FD83C88F3F1D759DE0293DEAD30B9C080C6B6BBE45149044CBE530696
+36FEE48A1DCE1F615EFC87AD3FFB414DADF49767897E213B8E9F49936BA6273B
+A0064C8F3D74CE323493C5571287F481A082B266C957920AAE3387ADFAB40D0E
+B7DB85BE36556ADB72F6D9B8A30716A2D6254CED3AFE7BBF8C2787116AF53615
+E8F5A23C7AECFFC783AD47D2F390FDE458DFAA5CABA6EF8F26FFA519A2265426
+25CE185DF484C7CE53BC5EEDA5D9842FA5F0ABA36D84BD476CE6120A95AE231B
+C6F5D56D8FC52BC16FFB0839F2E203C3ABA654408EA36E200156C6874196FAE7
+E879A83716AD1FE3F61E0FB83FDE97D6A7E7AA12250698F7761EB11AD46B974D
+B799E2919F893268BCD0FD3A7BB9BDBCD31387752AF40594FADB1C9EA80F0B2C
+8F75C24D6FCA63D5533274D9ABB82D9D087D4EC3064DD43FBDC410CB0480F1D6
+81D4B2A153A9E4105D6E737367889C2879B0BA23D0E3445C52F43BD915A6F544
+DF28F8AE1AE184E93E5C0F148A08F0BE110399F492683049378F7D02C8586C78
+39BA15813021006E0849081D0E2EB0A4D931BC53E9F3ABDD2A4CF6CFCA519CA4
+BD3BF6151B8DAC894ECC909200338E018E5D688222FF75DA2ACDA3A0B6757F8E
+12566973481D36C737FF09416F80B9ADAFAE94050248CF687C791F3B18A758D4
+EE78CD0337AC1ED867DB7DCDF17EE43916FA5157DFB8D0C0EF4892EFEF2163C3
+F761D679E1C32138D6312AA484446653FF67E3C42229A6C66962430E7633A2AC
+085D44E2C27A27B5E466EFE665B803890DC6678064DE29C9FE42AF022A91033C
+C8E47B5C727229C4E15A425C0EB6F5645CE8B52858D7E808EC9163704D20708A
+C0CBBDC4F1A7C678F56EF0BA905BD8B43A27FFB433A300115BAABDB3C06D5BB0
+D6AC5C204D3B0E4E985C611C22D9AD61BB0A9D3EBE382C703F2EF449FA451B0A
+50FCA07C36D661ADBEE41CC37E98EA8921E2421080D0032012E84F7C3D803DE5
+391C0E7C2D229F495D1DA055DCCCC408B1481503E942300493448D4A589CC2C3
+A2801C29342BD06ED565394F9AF9D940A329C96C18E2FA405CA3CAD558592506
+04659173B2F9EC1081FAB95BEDB32941925AAE45C6F6D742D153BC9B924930B1
+9EAA14216548EDDF70A203501F7C660EFCA287906965B24C2D7889F91AA8F64F
+7EB7D098DC911FD416D08471EBF37C65BF2F9D78FFADF498598D018CA1892305
+BD14091D8D3DB79589F68EC891BD788DAF85F0A9568718F95DEE9CE1C039A22F
+D8BEC548AF39E26DB4566EE12BD7DF7D5E147C368FE5D24F764F955EBD2FC1A7
+DAA4EB4233CAF94141FBA18927C6E4B1C80B96CF186AEF2064A0B1F76E13307D
+ACA7A3750D4EA808DEF78FC0BACFE291C3ED2E322385B0D18498C2F028A65979
+DA9743B16A9570979036C51AE4AD710CC444D55A62D61010687124E4FAFB7CC4
+79741B38588A3631700D73B619BA42FCF9DEC2A4A032E70E6AF7D47060A17EFA
+E31DD2D37F8B3103AE27A0D1C6D982FEE048946CE3EDC22BEBF3A9829E89775E
+2944B6D3A1BB36E66DD5C0213A05D379D03C58A624033FF1E3E8837AA0532366
+2A05830690EACD3AB4C111D0B824997DE953791D76B6C1FA4714D3D98FFB218D
+60948D2D2C96B07B4B0AC7FBC3C938AF3604BDAD43BFBCCA5B66E2093CC7E2A3
+C980B0D634AFE7C2173FA197C6DCA10807B6F66BAEF9770FEDE5D1BFC9A1008E
+3E3C9B532ED7C3F829ED9E19062B5CC5C8A2473C9FEF131DFB61A0F957CB7035
+F051B9B9B553142B6C35FF43A58159CA30CC9232852897230F30FB15D1E55AFA
+6AE0B7073C41043594D4897B81316A82CF5C7FC054A0D0872CD83C561C757F3D
+F8B50D23586EA6A3496B0EFA63A5D8C89CF7968927F4AC9033ED7D2CC7390CD7
+EA0D69BA01C693D11B71CE21BD92BFEB1AD2BA96A6B15985E7D4C4F1662AEFCD
+6D2C0334E50EEF2A878DCFA645E051B7FE9EF9C3AFE063D4FDAC983B5ADD8880
+CF6462D68546DD3B38FE1338BB699749DA5703367FC990BC8512F013BCC822EE
+58168E8AD5B76219ACF58E7238D1E956393C5809D9430DDD4F574123F47C3F59
+0617288ACA69EB57200FA00CBAF5537D3DC1664E8CE5981E86E49FF8E468857B
+6AB30501CAA8B0D957D6220D9D552436DE71E6BAAD9332F7EC647295D1A8725A
+61FEE01CEB6BEA0831C01AF94001C4E1A69F43742E6BAD5649A305EC36ACC638
+8C24A4976F5B7A63917394C99FF499BD922314593F78FD7156907DC167F761A0
+37707433D75C4B98AC48A08FC4F3988CF9F71752D894646412CE7390D99CE2BE
+AC4459AD4D097368BC3942611EEC7BF8E481CF0AD0050E18E36A1C0E9CFB63D8
+F4D88A59899CBCE6BA593703AC923DFDC85A85F885AD0D7147B6CD6EA0782B3B
+DFE92ADD2075B8056A6C4B4964606D68B47662317A71428A1A9579AA78CD8A79
+CBC839D0CD46FD84C1F1588F16BC80A6D5648F3F2DFEDCED33141A1DD8B86E64
+30D209D031B61F2DD9009C9202571F4E99E0E75A21D9AA7A3649FD4CDA1933BB
+4E53C3D9BF188EA5D95AFD8ACE132FD91C81CD382E68F3D1432FC8392ACB452F
+A6F581563239CFF30CD8EC3EF799BC8291E3A76B76AC107554329BDA12603760
+8970A5616359681D6A038DB1F4BDF08C10FFEADDB97DE44C27BA269175F91D61
+A33944E7EEC7F6EB9139AB0F3E49AF2373B3A9C9224E2645CA3CD3556063EB66
+4905D4824C23D261B53C6B49FDEF19D4E113EEA148A1541136DD83ACD4272A61
+4285419B10961726E5FF088A8833234C6C39632D1D86211330EAB80F47C64378
+4771739DED203D692A62DB30F3D875417473BF05E2111EAB8536EBA399EF10C8
+05937E677E128767F108185B19B102E7E5612E8F49B71CD4AF4F391BD5550A7C
+2B0472E935830E3F84A0D01ACA25EAC40611CCAAC0175BF5470CC9721F2689CA
+396ECBA85EE5B16690E970C05F9AF82F0617D834CADF01B29A9AC20FA6860385
+6C3790CDCA54C4B8C0A7E7FCB29369181BCC55978CF8C45F20C2807B58B2946B
+F73B1C32600A2EFDEDB05771E2328C10B078A8B5D68AF527522C1DC28E6B0C6F
+28B14656C07E7B355B7B41FB7D6B8BDC0543B8A86B688F21993D82096A99412B
+2C5EF2C850F1DA47923D4AA1F7AA1FD0AF09088385B286F4E91BCBF2E62B4BE2
+4795A9E7AB0CA5C3572AEDFD66A627CFB3554CC9E98A13902508C407CEDF92CC
+AFA3871CF38A64DF1F3107745A6BF68C93EF67355AF32F3994AD228BC4FCC45A
+B37F32098C42A9ABD1020F59CD486C11A5A9ECE00597C3345A01566FA85F30E4
+E8C2008ED1A35630782340645E9DF5F72FC3F1EC93E29CB5EDBBD0B6B9B8B8D7
+D1CF0D6D6E68C53E72DE452A72A7F1EFAA266462E302495F5953A18515C61E33
+AC663A23471281E6DDB7783FA8DBC681EB29D3C4D46E281507D4AA8B04E6442D
+12D0F98EA735898401454BE76DD0161CC35CC17BAB0799A32B486C03FE362DF2
+D650937B554219FA9D55122B0D23BC65DD993BB5A373ADE161F4EA6CD22ED48E
+2267B630D15843B3C6A29D25834DEFEFE5145D17FCAD59F50438D1AF8CCCAA2B
+68FDC7D4B8C8C9CF9293185CE66DE80E94BCB81E4290A808762F485B7BF67BF4
+853C05507951732DC9DF2FCB294A688A1344C6F13D83040EB3CF6FE43F93C6B5
+3CFD96F8ACE65B553036874C5E001F058FD45AD73EFDC6441D34FCB36482F162
+65BFE82A0A3D0FA84BDC488ED0A29A1D8F24DD6236BA14F37F1273477B17A1D6
+8BBA6FA890FF25F902DA9801CE453163A724307680675443178328A7972623F9
+E376E904396B32884B235A3A2F2E485037DB93DE70DC3CF616228012290236E1
+003C34A04ADF18C9452700CB3542ECA78CD76A31DA6854A14BACAD93CD713FF5
+7E44A88B475766ABBA4492664623DF4B18145400219AF12007C0F1614B21971D
+1C01364BC2C318C0F95F2C761418B072B92EDDCDA7D8A39D73DF44F2CD948CFC
+1195611110B1D29A94AEDB03D4F2C1823F8D0422B3A7C93ECDCB28686973B758
+A36F3C2A464B8DC0B8E472306126126B4C97C84C4CF74BF463D3C282DB7110D5
+B119467517E3FDC3EFC6187A090A913C1D9149BA359AB5D6C73CE801AA3943A3
+FB7599B33CDF46D3E519B7A129DA1C8F519ADDCC950A0FB8C27F4DDBFCA1421D
+ED041D2566D6692444C326A913EEF73EE5E7B1B0CE7D346EA94BBE77C4BAD703
+8CBB8DBC6F345C4FA0887D7D77CC295E18BC60A9C4EC6457BF233805AF08D988
+6A2F4110FCB0320E56E7AF7601E034D2793EB5764536B2944BD90CFB4FD53C0C
+2554B4B97274605249A085B1B71C7F53E3D30B19546A0858E4B6116AB3A3C20F
+D223153FB7DCA8A0E3D7D9E906F673AF94A92854E2A25B819E47AEAD27485196
+6AF4DE6C88CC79B8F72625B762490C6C279916C6C8CAFD0054FFEFF11F8C7152
+B2EA7981ADED9F706E2EA21D2BDFA59CE404D0AFE11FFCD68732DEC63C2FB0D3
+A96E14E5046ABC98C8FBF8F1BA121BFD1FDC94EB5597FD44219DAF19F871AF75
+136D8AD20E17985F25527A46B175C1E48E760F8086639FB5C086A6588BE797C1
+A5F71D3F66C51FB1E49A00201127877DBD00534E1E8EE719C6EEDD7E4ECF740C
+272ED2F338AA5E1FD8AE9B0B4D9C405615C19DA824DFF40D92505BD37EAB2E62
+B7AFB69AD7B76EB6FAA90ED8119FB8D710F5536E564EF8E11C7422B4985B0017
+C760C753B521B474787E23A64DCC32FA2800BC8DE36F9561DF822DA75450CE51
+8E7B9A0DD0A57762E7F85930DC0D9C37F7AF177F9B8F355D8032FCE0D010DF3A
+4AA00B0754B79C8F5B314DA028DC12260A5C6CC42EA8A5AA0F4E814171701653
+32FC6F1D94DE5FC999977735DEE0129E8394BBF6986F4392261936D74BA19ADE
+37742B698CE29CFB8395601FDDD7228CFBAE86406422387A83B2901D9C1B8665
+31B0F6273537D77F0B4F142C6B210071694D1B8E7BDECFBA2725A7E1AE1D81B8
+02B34FA02D0A7BA383763B44BB31ED7F9237936774590EC93B52914BB6E9C931
+C3D8C7A13FAB7F2346C861685FD0AAEA9CD8DAC1F995A86185660DD25A46E3E3
+76E9328C9C68331AF07AED6E7E8305E056EB489A1436733438368B1084D414E2
+3FEBEB53EEA500392D754F8EB2AA96D3EC336064C713D63ED180A0E777F152D8
+8E3F0D82348C1C4B3613CBE1A9982DC5AC19443D66E5C98221982DF65D9AA392
+A1C24B28051313D8CCCA650A1ED617B61E93FAA49499F1A12B0F8378514DE99D
+B4AFE780B3776F5F0E5D8F1627075F763C61291515F9361968D9750E41AD0CBF
+2F074C4C1E86E175D163CE1DF4088CBCBB89FD725F256BA370D27B1695EFE072
+D3CAA0388F5FFB4F19B49183D001282DB413BA2B558AA437E5C08166C90E943A
+2986253909E1898600B7311D1129610CC5181131D166CB5F5354B4D4E5ADADAA
+C0987CCDD522F0035626399B9996704632298D726F86C0A5CD3775C594E32DDD
+06466CA1A6903B694C5D9695F6F2B3FD9ED2DB99D9B38B78ABF97BD43A55B7F0
+CD4D43509B72E4B4C094701EF0FCC3B9E5D98996807F2A8AFF6E6A86229E0530
+AEB30DBC61EA58B555BF01360E4158C3EAF4FF10BD5C87B5745AC1512A57EA4D
+E231EF0EAE461CA3031BEACA80615FF8F50BD2FE95C51C7FAAD7E6BD70F1DF4F
+86474964084739126E16BF18E32857D862CD42ED7E7F462EAD75D2923B1B9634
+B8B6E1D3091CCC23EAD246C82EC602A84C82D4FD9F5E867817299921C844D685
+19C008BC2025B36C03DA5BB272375FE9997EDD64471F30EDA21EB796743F3B42
+D43FF785C900EA62BDC3C46BB2AC1B3F00A74B0F0C3B348033369ADF630D1C83
+E5E741B697EE045CA6325D151F5819C6C2BAB793A0A40E1A48E6B1F442CDEE12
+7B61C68C60172C0D09191FE1B0C1C3A082EC31CFAC70E298D00C04BB7C6B4E99
+00558D641DF88ABF7C7D712C8DE23340C6200D8539B674BA1B60B2BB9AA99EC5
+CF57713B56C2941C3DA98A47F6C3DCDDE7C047251CE493DE954028EDB34D3DE8
+946ED87023E348EBBE7BE424D92A89CAC21B7B81061C999FC8DCD9B7814BBBCE
+
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX12
+%!PS-AdobeFont-1.1: CMBX12 1.0
+%%CreationDate: 1991 Aug 20 16:34:54
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 97 /a put
+dup 99 /c put
+dup 101 /e put
+dup 102 /f put
+dup 105 /i put
+dup 107 /k put
+dup 110 /n put
+dup 114 /r put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+readonly def
+/FontBBox{-53 -251 1139 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660F74BEE96790DE35AFA90CCF712
+B1805DA88AE375A04D99598EADFC625BDC1F9C315B6CF28C9BD427F32C745C99
+AEBE70DAAED49EA45AF94F081934AA47894A370D698ABABDA4215500B190AF26
+7FCFB7DDA2BC68605A4EF61ECCA3D61C684B47FFB5887A3BEDE0B4D30E8EBABF
+20980C23312618EB0EAF289B2924FF4A334B85D98FD68545FDADB47F991E7390
+B10EE86A46A5AF8866C010225024D5E5862D49DEB5D8ECCB95D94283C50A363D
+68A49071445610F03CE3600945118A6BC0B3AA4593104E727261C68C4A47F809
+D77E4CF27B3681F6B6F3AC498E45361BF9E01FAF5527F5E3CC790D3084674B3E
+26296F3E03321B5C555D2458578A89E72D3166A3C5D740B3ABB127CF420C316D
+F957873DA04CF0DB25A73574A4DE2E4F2D5D4E8E0B430654CF7F341A1BDB3E26
+77C194764EAD58C585F49EF10843FE020F9FDFD9008D660DE50B9BD7A2A87299
+BC319E66D781101BB956E30643A19B93C8967E1AE4719F300BFE5866F0D6DA5E
+C55E171A24D3B707EFA325D47F473764E99BC8B1108D815CF2ACADFA6C4663E8
+30855D673CE98AB78F5F829F7FA226AB57F07B3E7D4E7CE30ED3B7EB0D3035C5
+148DA8D9FA34483414FDA8E3DC9E6C479E3EEE9A11A0547FC9085FA4631AD19C
+E936E0598E3197207FA7BB6E55CFD5EF72AEC12D9A9675241C7A71316B2E148D
+E2A1732B3627109EA446CB320EBBE2E78281CDF0890E2E72B6711335857F1E23
+337C75E729701E93D5BEC0630CDC7F4E957233EC09F917E5CA703C7E93841598
+0E73843FC6619DE017C8473A6D1B2BE5142DEBA285B98FA1CC5E64D2ADB981E6
+472971848451A245DDF6AA3B8225E9AC8E4630B0FF32D679EC27ACAD85C6394E
+A6F71023B660EE883D8B676837E9EBA4E42BA8F365433A900F1DC3A9F0E88A26
+3753B03B38D6FF2C1D845166BAF4998598D00F26A33F36C22E2C93B0A38650D5
+61BC36F521625DA1DD5E3133F573575101D9B21CEE92F241DF9A5A4ECACEE0C0
+1FD4DE44E06C1923CA444F762B6B448DE4A52715961063CEC16B6C371E93F0CF
+56C47321C2345C083787EEB699FD2F9D3E2FEFB010E05E0DAC4F2934DC1BF47E
+21DDAE3E56F669A0C934F7F751A01CB55635B7590D2AE3B6F4777BC0EC8F7585
+BADC41E3DEAD3C1CC4AC3020CCB7CC60ED93CDBD17D8D10A3014099E5FCBA6E2
+B18DDB1086CEEBBB1A2A38D011E5ABA027C28E72AADFEC805D080238B4633408
+41EB166F3E8CA60D77071FD7CD0A127516FDBDB49199E598BA61F195678A0796
+86FEE45B30B60033CA49A5922F28E4E0C9D4BAF66EBB536AD8BA9A0E6F126E1C
+6C5B2B81A7D5992F0FAABA18DDE700056E6D85798126ED387B62C5F076ED907B
+E50B145B588823906FBAD973E60CFF9868F9844299B07CEBFE7B2219CB531193
+1D0E1D953492FB81E90BE977EC4CF0C5ECEB6BADA7A1D86A3E1B944B044BC90F
+020F5E76C7353C0F8C5D76DE012AE7A37F9859C85A6C4681C29A644F2F119138
+9D113569E9EFB85101AE6A46D660C5C7E205B272BD53CFCBA8C9A51DBE678806
+CA0B6FB7975C3EBE449A9C3DE0DDA3C0CA74D0F2085E070945726C1594A611FF
+5B4BD0E2EC240CA21CECE1601E1705ACC14EA52AF8114A16061FF317167AC9F5
+DECC692C4E2727D970E1171D980379B56E2C51BD3D608FCE89A7A2E832B0B815
+A7B334D470817F2623109D0BDD66C8AA697ED3CA02AF684E5766B3470374F9B1
+5BCF04D178D5B4F12C4A0303AE1AC1ED6C19BFDFEE60DCA168E90AE9EE49CB4A
+2FFC5DFED5179AAC027F6D415089A795EC9292C58B009165717D1C0B6126C55C
+C10E4D686A735F787B3D693D841198A6EA185C691C070601938FB8BEC74278B5
+E88003C6CFA16C7DC52FB135D48D0A85B42F261B64876815BD2DB1DBA403B5DC
+87DF034DDEDBFE962A5AC112DCC6B8415A518F463AB278DE3C6B5998ADFF4065
+6AF00AE2591D3C3750030C18CA2D4B78FAB4B03E72D6135D69DD68BDB2023F1B
+7F9C0ADCEE2576D5BA1130F89E93BE5716252173339A2FC1B11F5E5D5AD31F4C
+9BF98CD0765C92031185C3BED78BA36425487B4BA569114BC5B46EBB968CEBC7
+3742501440A04BC19C12E8BBB4DC962DB619DF7C3298892F216CFF9140FD974E
+B1EB752EBB82935BDFBA064B81F7302888C4B767BF2AB4CD44CEB1C5D6809FDE
+617A2B93E3FB231DD54B9875E59823A2DC666DF6D781D249898A2F05C5C88E77
+90DFD1DC1F3488714BAEFFD8FC1C3633EE8E793320FB51436784FA82EF28FE8F
+65AF0F5C5471A99478B99CEA235AC0003E6C5BBBCE4652BF2CBC0610B29AC8A6
+ED3034B7BC76EB2009ED76751404F14061BF4890FE9A1A01476F1C2BA310A82D
+A1B77BA6A71AB8CF54563315338A35B1D3A3369BF77312C87EE88E9B1E40DD17
+3CEBC13E73A90A9B40655B2BA43C93D95DB9B47BCC60CF801EAE26242FC4E7FA
+32328BFA8B7AB57095638A3F154D9AA0769C7B02A6BADC3DC59297C46E51DB92
+0BAFAC207DA75D39D7A9066D0EDF73FBF28A332F8C800806D9512268241FAF9E
+C6279BE0FB884244D022E38C8D748D8928A5A44BC1B2006034ED8819446FF8BF
+98BE8A2ECC149B6E795E35DF7CBBA29482260D67EE7544CB5FBA4E4EF627D476
+5CD6F741C5CE950F14550940AF65EC541C053C6B18203562F6BC7ED6CAEBBB73
+300798634EDB4926CE56B2BF0F4226EC1F472B8EF674AC3AB8597EA93135A4A3
+AFAFAFB943DEEE1C155EDD689BC3CB7EE95EF96BA686BC723C56235848985604
+8A3EDED9013B609FC8855EE4A044F7C0634471F5372796391BF7820E579D7704
+FA6837B717733DA04D5DBDA91A028F14317EF115FDB9A952A93D6133A533F081
+D0715B6D90FFD9177C44D8731692D823098D04080B61F5D54C8D300DDCCBD145
+92601ED8216D3245E104DE65087D3A0E36ACCCB0A971D9163EA7DE727F2345B1
+8879D24FF363E8623D30F2E0DA8A41028D32D93AB4BF94C18C21C22BEF1D4FC8
+1B64AE052ABA20F8988F614CE3E42773F2DC4B1BDFB5F7B826D0DB68D92AB25E
+FF2C19BDE6287731B72979D733A9F79B51B97D4D823C7E6899953B425CCBA13D
+26211E53C38BA9182C90243BE9EEF1A86C78B756AF2A74C60B9DDC7DAF99C430
+407B0E49032DB092DC0F36B2F9CFE375E3C4737E122FBA57D89778C7922D5CA8
+4EEB5F50B96EAE7BA1850FBB30E15CA5C368139062036066CF92CFB20C7860F2
+67FF81549D70B048831750FF06A71B91512710DDD86EBFF5FA43E9534F5FA6AA
+E87843B8EB1A40D203880B6EFB38EA5CD5CD4E163CDF36D018B62E482F2E633E
+029516D8BC1C02344BD85B1DF3F3EE1098104A5E754D6D4E86C29F08CBE8BAAD
+7A5EC1E654BFDCAF8EB2A8BFA28DE9E857EA7CBD9E3C0012DAF79A114C55AD77
+952BC5A5FCB40C76760460C58836DBC927D4231EDBBF3B06A420ADCAE8564CDD
+85DD501C31E3915FB7A3CA9DF157B7F4C183DF6791E1FE071EBF75A47C8184C3
+F7BFD40AFD10CB3D4835AC9EB170CCE05E01E76497D022E263D4ACA540AE7A0B
+F99EFB3A4E82D400FF79CE97AC2654E2D4FA0092E2D27097FD9AE0476CB33B64
+7722F482E0B148252740F435F52D2A610C195E340A86472C5D41D1B03CE311ED
+8C2C81A9D77352B27BBFECDF828781D7ABB2485FBEEED6B7BBF042884F499C64
+8B32FE5F8D8FD13BCEA7CF8D763D47E8040D0ED2EEED52039AA93B950491C9F8
+8C7BFF7002F6B5267176B71E8C408258E401978A723DE12A969732CF910D60E5
+4E8ED3C0B4C76F9A7BA41BEC303237B8256B6F78492EE137CB0B83E84EC69AFB
+3A91446762891E2C2867F40F62A31D04C9D42D2D77F4751084810B839AD5CD70
+C79A694BA0160A8BFEB87BFE5AF51B01306886897429C88577006988D48BE24C
+98E7F2512860346E5112D0063B79F3A983259F766A89ED3660D39AD7B1E237A4
+097102EDBC8EDEC3D93D4BC71E557956649AF5641D7508EAED4DECDB9BB31C29
+2F0918025367A9A394EDD59B4AF99892BB84558479690949DE631572EDE73A04
+662C9FDACFD281F7ABD8CDCCAF604A28DA61B3BD8EF9BCC64FFFAD782F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+TeXDict begin 55380996 39158280 1000 600 600 (refcard-a4.dvi)
+ at start /Fa 230[47 25[{}1 83.022 /CMMI10 rf /Fb 143[69
+5[23 2[42 42 99[65 1[65{}6 83.022 /CMSY10 rf /Fc 162[23
+1[23 41[42 49[{}3 83.022 /CMR10 rf /Fd 133[28 33 32 45
+32 37 23 28 29 1[35 35 38 56 18 32 1[21 35 32 21 32 35
+32 32 35 18[50 27[35 35 2[21 25 3[28 28[39 12[{}31 58.1154
+/CMTI7 rf /Fe 133[30 35 35 47 35 37 26 26 26 35 37 33
+37 55 19 35 21 19 37 33 21 30 37 30 37 33 19 3[33 4[67
+2[47 37 48 51 1[51 49 60 41 2[24 49 51 43 45 50 47 46
+49 6[19 33 5[33 33 33 33 33 19 22 19 2[26 26 19 51 3[33
+19[56 38 38 39 11[{}65 58.1154 /CMR7 rf /Ff 129[35 1[35
+1[35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 1[35
+35 35 35 35 35 35 35 35 2[35 35 35 35 2[35 2[35 35 35
+35 1[35 35 35 35 35 2[35 35 35 1[35 35 35 35 35 35 35
+35 35 35 35 35 6[35 35 35 1[35 35 35 35 35 35 35 35 35
+35 3[35 35 33[{}71 66.4176 /CMTT8 rf /Fg 134[50 50 1[50
+53 37 38 39 50 53 48 53 80 27 50 1[27 53 48 29 44 53
+42 53 46 7[72 2[72 1[66 53 72 72 65 72 75 91 57 75 1[36
+75 75 60 63 73 69 68 72 19[32 27 31[53 12[{}47 83.022
+/CMBX10 rf /Fh 134[32 1[43 32 34 24 24 24 1[34 30 34
+50 18 32 19 18 34 30 19 27 34 27 34 30 8[45 61 45 45
+43 1[44 1[41 47 45 54 38 1[31 2[47 1[41 46 43 42 1[47
+4[18 1[30 1[30 30 2[30 30 30 30 1[18 1[18 2[24 24 40[{}53
+49.8132 /CMR6 rf /Fi 137[59 62 44 1[46 3[62 2[59 1[31
+2[34 51 1[50 1[54 14[84 84 1[84 79[{}14 99.6264 /CMBX12
+rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%BeginPaperSize: a4
+<< /PageSize [595 842] >> setpagedevice
+%%EndPaperSize
+ @landscape end
+%%EndSetup
+%%Page: 1 1
+TeXDict begin @landscape 1 0 bop -387 -352 a Fi(Octa)m(v)m(e)27
+b(Quic)m(k)h(Reference)98 b Fh(Octa)n(v)n(e)29 b(V)-5
+b(ersion)28 b(3.0.0)-387 -195 y Fg(Starting)g(Octa)m(v)m(e)-387
+-111 y Ff(octave)413 b Fe(start)28 b(in)n(teractiv)n(e)e(Octa)n(v)n(e)h
+(session)-387 -37 y Ff(octave)i Fd(\014le)295 b Fe(run)27
+b(Octa)n(v)n(e)g(on)h(commands)e(in)h Fd(\014le)-387
+38 y Ff(octave)i(--eval)g Fd(c)m(o)m(de)17 b Fe(Ev)l(aluate)27
+b Fd(c)m(o)m(de)f Fe(using)i(Octa)n(v)n(e)-387 113 y
+Ff(octave)h(--help)174 b Fe(describ)r(e)26 b(command)g(line)g(options)
+-387 274 y Fg(Stopping)h(Octa)m(v)m(e)-387 358 y Ff(quit)h
+Fe(or)g Ff(exit)228 b Fe(exit)27 b(Octa)n(v)n(e)-387
+433 y Ff(INTERRUPT)308 b Fe(\()p Fd(e.g.)42 b Ff(C-c)p
+Fe(\))28 b(terminate)e(curren)n(t)g(command)g(and)278
+508 y(return)g(to)i(top-lev)n(el)e(prompt)-387 665 y
+Fg(Getting)h(Help)-387 749 y Ff(help)483 b Fe(list)28
+b(all)f(commands)f(and)h(built-in)g(v)l(ariables)-387
+824 y Ff(help)h Fd(c)m(ommand)171 b Fe(brie\015y)26 b(describ)r(e)g
+Fd(c)m(ommand)-387 899 y Ff(doc)518 b Fe(use)28 b(Info)f(to)g(bro)n
+(wse)h(Octa)n(v)n(e)f(man)n(ual)-387 973 y Ff(doc)h Fd(c)m(ommand)206
+b Fe(searc)n(h)27 b(for)h Fd(c)m(ommand)e Fe(in)h(Octa)n(v)n(e)g(man)n
+(ual)-387 1048 y Ff(lookfor)i Fd(str)269 b Fe(searc)n(h)27
+b(for)h Fd(c)m(ommand)e Fe(based)h(on)h Fd(str)-387 1194
+y Fg(Motion)e(in)h(Info)-387 1278 y Ff(SPC)h Fe(or)g
+Ff(C-v)298 b Fe(scroll)27 b(forw)n(ard)h(one)f(screenful)-387
+1353 y Ff(DEL)h Fe(or)g Ff(M-v)298 b Fe(scroll)27 b(bac)n(kw)n(ard)h
+(one)f(screenful)-387 1427 y Ff(C-l)518 b Fe(redra)n(w)28
+b(the)f(displa)n(y)-387 1585 y Fg(No)s(de)f(Selection)h(in)g(Info)-387
+1669 y Ff(n)588 b Fe(select)27 b(the)f(next)h(no)r(de)-387
+1744 y Ff(p)588 b Fe(select)27 b(the)f(previous)h(no)r(de)-387
+1819 y Ff(u)588 b Fe(select)27 b(the)f(`up')h(no)r(de)-387
+1893 y Ff(t)588 b Fe(select)27 b(the)f(`top')h(no)r(de)-387
+1968 y Ff(d)588 b Fe(select)27 b(the)f(directory)g(no)r(de)-387
+2043 y Ff(<)588 b Fe(select)27 b(the)f(\014rst)i(no)r(de)e(in)h(the)g
+(curren)n(t)f(\014le)-387 2117 y Ff(>)588 b Fe(select)27
+b(the)f(last)i(no)r(de)f(in)g(the)g(curren)n(t)f(\014le)-387
+2192 y Ff(g)588 b Fe(reads)28 b(the)e(name)h(of)g(a)h(no)r(de)e(and)h
+(selects)g(it)-387 2267 y Ff(C-x)h(k)455 b Fe(kills)28
+b(the)e(curren)n(t)h(no)r(de)-387 2412 y Fg(Searc)m(hing)h(in)f(Info)
+-387 2497 y Ff(s)588 b Fe(searc)n(h)27 b(for)h(a)f(string)-387
+2571 y Ff(C-s)518 b Fe(searc)n(h)27 b(forw)n(ard)h(incremen)n(tally)
+-387 2646 y Ff(C-r)518 b Fe(searc)n(h)27 b(bac)n(kw)n(ard)h(incremen)n
+(tally)-387 2721 y Ff(i)588 b Fe(searc)n(h)27 b(index)g(&)g(go)h(to)g
+(corresp)r(onding)d(no)r(de)-387 2795 y Ff(,)588 b Fe(go)28
+b(to)g(next)f(matc)n(h)f(from)h(last)h(`i')f(command)-387
+2953 y Fg(Command-Line)f(Cursor)i(Motion)-387 3037 y
+Ff(C-b)518 b Fe(mo)n(v)n(e)28 b(bac)n(k)f(one)g(c)n(haracter)-387
+3112 y Ff(C-f)518 b Fe(mo)n(v)n(e)28 b(forw)n(ard)f(one)g(c)n(haracter)
+-387 3187 y Ff(C-a)518 b Fe(mo)n(v)n(e)28 b(to)f(the)g(start)h(of)f
+(the)g(line)-387 3261 y Ff(C-e)518 b Fe(mo)n(v)n(e)28
+b(to)f(the)g(end)g(of)g(the)g(line)-387 3336 y Ff(M-f)518
+b Fe(mo)n(v)n(e)28 b(forw)n(ard)f(a)h(w)n(ord)-387 3411
+y Ff(M-b)518 b Fe(mo)n(v)n(e)28 b(bac)n(kw)n(ard)f(a)h(w)n(ord)-387
+3486 y Ff(C-l)518 b Fe(clear)27 b(screen,)f(reprin)n(ting)g(curren)n(t)
+g(line)g(at)i(top)-387 3643 y Fg(Inserting)f(or)g(Changing)h(T)-8
+b(ext)-387 3727 y Ff(M-TAB)448 b Fe(insert)27 b(a)h(tab)f(c)n(haracter)
+-387 3802 y Ff(DEL)518 b Fe(delete)26 b(c)n(haracter)g(to)i(the)f(left)
+f(of)i(the)e(cursor)-387 3877 y Ff(C-d)518 b Fe(delete)26
+b(c)n(haracter)g(under)g(the)h(cursor)-387 3951 y Ff(C-v)518
+b Fe(add)27 b(the)g(next)g(c)n(haracter)f(v)n(erbatim)-387
+4026 y Ff(C-t)518 b Fe(transp)r(ose)27 b(c)n(haracters)g(at)h(the)e(p)r
+(oin)n(t)-387 4101 y Ff(M-t)518 b Fe(transp)r(ose)27
+b(w)n(ords)i(at)e(the)g(p)r(oin)n(t)-387 4195 y Fc([)g(])h
+Fh(surround)f(optional)g(argumen)n(ts)138 b(...)40 b(sho)n(w)29
+b(one)f(or)g(more)h(argumen)n(ts)p 1738 -418 1 17 v 1738
+4195 V 1951 -352 a Fg(Killing)d(and)i(Y)-8 b(anking)1951
+-267 y Ff(C-k)519 b Fe(kill)27 b(to)h(the)f(end)f(of)i(the)e(line)1951
+-193 y Ff(C-y)519 b Fe(y)n(ank)28 b(the)e(most)i(recen)n(tly)e(killed)g
+(text)1951 -118 y Ff(M-d)519 b Fe(kill)27 b(to)h(the)f(end)f(of)i(the)e
+(curren)n(t)g(w)n(ord)1951 -43 y Ff(M-DEL)449 b Fe(kill)27
+b(the)g(w)n(ord)h(b)r(ehind)d(the)i(cursor)1951 31 y
+Ff(M-y)519 b Fe(rotate)27 b(the)g(kill)g(ring)g(and)g(y)n(ank)h(the)f
+(new)g(top)1951 192 y Fg(Command)g(Completion)f(and)i(History)1951
+277 y Ff(TAB)519 b Fe(complete)26 b(a)h(command)f(or)i(v)l(ariable)f
+(name)1951 351 y Ff(M-?)519 b Fe(list)28 b(p)r(ossible)e(completions)
+1951 426 y Ff(RET)519 b Fe(en)n(ter)27 b(the)g(curren)n(t)f(line)1951
+501 y Ff(C-p)519 b Fe(mo)n(v)n(e)27 b(`up')g(through)g(the)g(history)g
+(list)1951 576 y Ff(C-n)519 b Fe(mo)n(v)n(e)27 b(`do)n(wn')h(through)e
+(the)h(history)h(list)1951 650 y Ff(M-<)519 b Fe(mo)n(v)n(e)27
+b(to)h(the)f(\014rst)g(line)g(in)g(the)g(history)1951
+725 y Ff(M->)519 b Fe(mo)n(v)n(e)27 b(to)h(the)f(last)h(line)e(in)h
+(the)g(history)1951 800 y Ff(C-r)519 b Fe(searc)n(h)27
+b(bac)n(kw)n(ard)h(in)f(the)f(history)i(list)1951 874
+y Ff(C-s)519 b Fe(searc)n(h)27 b(forw)n(ard)h(in)f(the)g(history)g
+(list)1951 966 y Ff(history)j Fc([)p Fe(-q)p Fc(])e([)p
+Fd(N)9 b Fc(])113 b Fe(list)28 b Fd(N)36 b Fe(previous)27
+b(history)g(lines,)g(omitting)2617 1040 y(history)g(n)n(um)n(b)r(ers)f
+(if)h Ff(-q)1951 1135 y(history)j(-w)e Fc([)p Fd(\014le)p
+Fc(])116 b Fe(write)27 b(history)h(to)g Fd(\014le)j Fe(\()p
+Ff(~/.octave)p 3532 1135 22 4 v 28 w(hist)e Fe(if)e(no)2617
+1210 y Fd(\014le)32 b Fe(argumen)n(t\))1951 1304 y Ff(history)e(-r)e
+Fc([)p Fd(\014le)p Fc(])116 b Fe(read)27 b(history)g(from)g
+Fd(\014le)32 b Fe(\()p Ff(~/.octave)p 3585 1304 V 28
+w(hist)d Fe(if)2617 1379 y(no)e Fd(\014le)32 b Fe(argumen)n(t\))1951
+1452 y Ff(edit)p 2095 1452 V 27 w(history)e Fd(lines)45
+b Fe(edit)27 b(and)g(then)f(run)h(previous)g(commands)2617
+1527 y(from)g(the)f(history)i(list)1951 1596 y Ff(run)p
+2060 1596 V 27 w(history)h Fd(lines)81 b Fe(run)27 b(previous)g
+(commands)f(from)h(the)f(history)2617 1671 y(list)2022
+1751 y Fc([)p Fd(b)m(e)m(g)5 b Fc(])26 b([)p Fd(end)5
+b Fc(])230 b Fe(Sp)r(ecify)25 b(the)i(\014rst)h(and)f(last)g(history)
+2617 1826 y(commands)f(to)i(edit)e(or)i(run.)2034 1890
+y(If)g Fd(b)m(e)m(g)i Fe(is)e(greater)f(than)g Fd(end)p
+Fe(,)h(rev)n(erse)e(the)h(list)g(of)h(commands)2034 1965
+y(b)r(efore)e(editing.)40 b(If)27 b Fd(end)34 b Fe(is)27
+b(omitted,)f(select)h(commands)f(from)2034 2040 y Fd(b)m(e)m(g)31
+b Fe(to)d(the)f(end)f(of)i(the)e(history)i(list.)41 b(If)27
+b(b)r(oth)g(argumen)n(ts)g(are)2034 2114 y(omitted,)f(edit)h(the)g
+(previous)f(item)h(in)g(the)g(history)g(list.)1951 2260
+y Fg(Shell)g(Commands)1951 2344 y Ff(cd)i Fd(dir)440
+b Fe(c)n(hange)27 b(w)n(orking)g(directory)f(to)i Fd(dir)1951
+2419 y Ff(pwd)519 b Fe(prin)n(t)27 b(w)n(orking)h(directory)1951
+2514 y Ff(ls)h Fc([)p Fd(options)p Fc(])264 b Fe(prin)n(t)27
+b(directory)f(listing)1951 2598 y Ff(getenv)k(\()p Fd(string)p
+Ff(\))143 b Fe(return)27 b(v)l(alue)g(of)g(named)f(en)n(vironmen)n(t)
+2617 2673 y(v)l(ariable)1951 2737 y Ff(system)k(\()p
+Fd(cmd)p Ff(\))191 b Fe(execute)25 b(arbitrary)i(shell)g(command)f
+(string)1951 2898 y Fg(Matrices)1951 2962 y Fe(Square)h(brac)n(k)n(ets)
+g(delimit)f(literal)g(matrices.)40 b(Commas)28 b(separate)1951
+3037 y(elemen)n(ts)e(on)i(the)e(same)i(ro)n(w.)41 b(Semicolons)26
+b(separate)h(ro)n(ws.)42 b(Commas)1951 3112 y(ma)n(y)28
+b(b)r(e)f(replaced)e(b)n(y)i(spaces,)g(and)g(semicolons)g(ma)n(y)g(b)r
+(e)g(replaced)e(b)n(y)1951 3186 y(one)i(or)h(more)f(newlines.)40
+b(Elemen)n(ts)26 b(of)h(a)h(matrix)f(ma)n(y)g(b)r(e)g(arbitrary)1951
+3261 y(expressions,)g(assuming)g(all)g(the)g(dimensions)f(agree.)1951
+3366 y Ff([)i Fd(x)p Ff(,)g Fd(y)p Ff(,)g(...)43 b(])187
+b Fe(en)n(ter)27 b(a)g(ro)n(w)i(v)n(ector)1951 3441 y
+Ff([)f Fd(x)p Ff(;)g Fd(y)p Ff(;)g(...)43 b(])187 b Fe(en)n(ter)27
+b(a)g(column)f(v)n(ector)1951 3515 y Ff([)i Fd(w)p Ff(,)h
+Fd(x)p Ff(;)e Fd(y)p Ff(,)i Fd(z)e Ff(])171 b Fe(en)n(ter)27
+b(a)g(2)p Fb(\002)p Fe(2)h(matrix)1951 3673 y Fg(Multi-dimensional)d
+(Arra)m(ys)1951 3753 y Fe(Multi-dimensional)g(arra)n(ys)k(ma)n(y)e(b)r
+(e)g(created)e(with)j(the)f Fd(c)m(at)g Fe(or)1951 3828
+y Fd(r)m(eshap)m(e)g Fe(commands)f(from)h(t)n(w)n(o-dimensional)g
+(sub-matrices.)1951 3933 y Ff(squeeze)j(\()p Fd(arr)p
+Ff(\))186 b Fe(remo)n(v)n(e)27 b(singleton)f(dimensions)g(of)i(the)f
+(arra)n(y)-5 b(.)1951 4008 y Ff(ndims)30 b(\()p Fd(arr)p
+Ff(\))256 b Fe(n)n(um)n(b)r(er)26 b(of)h(dimensions)f(in)i(the)e(arra)n
+(y)-5 b(.)1951 4082 y Ff(permute)30 b(\()p Fd(arr)p Ff(,)f
+Fd(p)p Ff(\))87 b Fe(p)r(erm)n(ute)26 b(the)h(dimensions)f(of)h(an)g
+(arra)n(y)-5 b(.)1951 4157 y Ff(ipermute)30 b(\()p Fd(arr)p
+Ff(,)f Fd(p)p Ff(\))52 b Fe(arra)n(y)28 b(in)n(v)n(erse)f(p)r(erm)n
+(utation.)p 4077 -418 1 17 v 4077 4195 V 4290 -352 a
+Ff(shiftdim)j(\()p Fd(arr)p Ff(,)f Fd(s)p Ff(\))59 b
+Fe(rotate)27 b(the)g(arra)n(y)h(dimensions.)4290 -277
+y Ff(circshift)j(\()p Fd(arr)p Ff(,)d Fd(s)p Ff(\))c
+Fe(rotate)j(the)g(arra)n(y)h(elemen)n(ts.)4290 -119 y
+Fg(Sparse)g(Matrices)4290 -35 y Ff(sparse)i(\(...\))209
+b Fe(create)26 b(a)i(sparse)g(matrix.)4290 40 y Ff(speye)h(\()p
+Fd(n\))319 b Fe(create)26 b(sparse)i(iden)n(tify)e(matrix.)4290
+114 y Ff(sprand)k(\()p Fd(n)p Ff(,)e Fd(m)p Ff(,)g Fd(d)p
+Ff(\))59 b Fe(sparse)28 b(rand)f(matrix)g(of)g(densit)n(y)g
+Fd(d)p Fe(.)4290 189 y Ff(spdiags)j(\(...\))174 b Fe(sparse)28
+b(generalization)d(of)i Fd(diag)p Fe(.)4290 264 y Ff(nnz)i(\()p
+Fd(s)p Ff(\))392 b Fe(No.)41 b(non-zero)27 b(elemen)n(ts)f(in)h(sparse)
+g(matrix.)4290 421 y Fg(Ranges)4290 505 y Fd(b)m(ase)g
+Ff(:)42 b Fd(limit)4290 579 y(b)m(ase)27 b Ff(:)42 b
+Fd(incr)28 b Ff(:)42 b Fd(limit)4290 656 y Fe(Sp)r(ecify)25
+b(a)j(range)f(of)h(v)l(alues)f(b)r(eginning)e(with)j
+Fd(b)m(ase)j Fe(with)c(no)4290 731 y(elemen)n(ts)f(greater)h(than)g
+Fd(limit)p Fe(.)42 b(If)27 b(it)g(is)h(omitted,)e(the)h(default)4290
+806 y(v)l(alue)g(of)h Fd(incr)34 b Fe(is)28 b(1.)41 b(Negativ)n(e)27
+b(incremen)n(ts)e(are)j(p)r(ermitted.)4290 951 y Fg(Strings)f(and)i
+(Common)d(Escap)s(e)h(Sequences)4290 1038 y Fe(A)h Fd(string)h(c)m
+(onstant)k Fe(consists)28 b(of)f(a)h(sequence)d(of)j(c)n(haracters)e
+(enclosed)4290 1113 y(in)h(either)g(double-quote)e(or)j(single-quote)e
+(marks.)41 b(Strings)27 b(in)g(double-)4290 1188 y(quotes)g(allo)n(w)h
+(the)f(use)g(of)h(the)f(escap)r(e)f(sequences)f(b)r(elo)n(w.)4290
+1292 y Ff(\\\\)554 b Fe(a)28 b(literal)e(bac)n(kslash)4290
+1367 y Ff(\\")554 b Fe(a)28 b(literal)e(double-quote)g(c)n(haracter)
+4290 1442 y Ff(\\')554 b Fe(a)28 b(literal)e(single-quote)h(c)n
+(haracter)4290 1517 y Ff(\\n)554 b Fe(newline,)26 b(ASCI)r(I)h(co)r(de)
+g(10)4290 1591 y Ff(\\t)554 b Fe(horizon)n(tal)27 b(tab,)g(ASCI)r(I)g
+(co)r(de)g(9)4290 1749 y Fg(Index)h(Expressions)4290
+1833 y Fd(var)g Ff(\()p Fd(idx)p Ff(\))342 b Fe(select)26
+b(elemen)n(ts)g(of)h(a)h(v)n(ector)4290 1908 y Fd(var)g
+Ff(\()p Fd(idx1)p Ff(,)g Fd(idx2)p Ff(\))121 b Fe(select)26
+b(elemen)n(ts)g(of)h(a)h(matrix)4361 1982 y Fd(sc)m(alar)379
+b Fe(select)26 b(ro)n(w)j(\(column\))d(corresp)r(onding)f(to)4956
+2057 y Fd(sc)m(alar)4361 2118 y(ve)m(ctor)373 b Fe(select)26
+b(ro)n(ws)j(\(columns\))d(corresp)r(onding)g(to)h(the)4956
+2193 y(elemen)n(ts)e(of)j Fd(ve)m(ctor)4361 2255 y(r)m(ange)390
+b Fe(select)26 b(ro)n(ws)j(\(columns\))d(corresp)r(onding)g(to)h(the)
+4956 2329 y(elemen)n(ts)e(of)j Fd(r)m(ange)4361 2402
+y Ff(:)518 b Fe(select)26 b(all)i(ro)n(ws)g(\(columns\))4290
+2563 y Fg(Global)f(and)h(P)m(ersisten)m(t)g(V)-8 b(ariables)4290
+2647 y Ff(global)30 b Fd(var1)d Ff(...)121 b Fe(Declare)26
+b(v)l(ariables)h(global.)4290 2722 y Ff(global)j Fd(var1)d
+Ff(=)h Fd(val)78 b Fe(Declare)26 b(v)l(ariable)h(global.)41
+b(Set)27 b(in)n(tial)g(v)l(alue.)4290 2796 y Ff(persistent)k
+Fd(var1)112 b Fe(Declare)26 b(a)i(v)l(ariable)f(as)h(static)f(to)h(a)g
+(function.)4290 2871 y Ff(persistent)j Fd(var1)c Ff(=)4290
+2946 y Fd(val)4914 2871 y Fe(Declare)f(a)i(v)l(ariable)f(as)h(static)f
+(to)h(a)g(function)4956 2946 y(and)f(set)g(its)h(initial)e(v)l(alue.)
+4290 3010 y(Global)i(v)l(ariables)f(ma)n(y)g(b)r(e)g(accessed)f(inside)
+h(the)f(b)r(o)r(dy)h(of)g(a)h(function)4290 3085 y(without)f(ha)n(ving)
+h(to)f(b)r(e)g(passed)g(in)g(the)g(function)f(parameter)g(list)4290
+3160 y(pro)n(vided)g(they)h(are)g(declared)f(global)h(when)g(used.)4290
+3305 y Fg(Selected)g(Built-in)g(F)-8 b(unctions)4290
+3389 y Ff(EDITOR)414 b Fe(editor)27 b(to)g(use)h(with)f
+Ff(edit)p 5619 3389 22 4 v 27 w(history)4290 3464 y(Inf,)i(NaN)350
+b Fe(IEEE)27 b(in\014nit)n(y)-5 b(,)25 b(NaN)4290 3539
+y Ff(NA)554 b Fe(Missing)27 b(v)l(alue)4290 3613 y Ff(PAGER)449
+b Fe(program)27 b(to)h(use)f(to)h(paginate)e(output)4290
+3688 y Ff(ans)519 b Fe(last)28 b(result)f(not)g(explicitly)e(assigned)
+4290 3763 y Ff(eps)519 b Fe(mac)n(hine)26 b(precision)4290
+3838 y Ff(pi)554 b Fa(\031)4290 3942 y Ff(1i)4914 3877
+y Fb(p)p 4983 3877 107 4 v 65 x(\000)p Fc(1)4290 4017
+y Ff(realmax)379 b Fe(maxim)n(um)26 b(represen)n(table)f(v)l(alue)4290
+4091 y Ff(realmin)379 b Fe(minim)n(um)26 b(represen)n(table)f(v)l(alue)
+4310 4195 y Fh(Cop)n(yrigh)n(t)j(1996,)h(1997,)g(2007)h(John)d(W.)g
+(Eaton)122 b(P)n(ermissions)28 b(on)g(bac)n(k)p eop end
+%%Page: 2 2
+TeXDict begin @landscape 2 1 bop -387 -352 a Fg(Assignmen)m(t)26
+b(Expressions)-387 -267 y Fd(var)h Ff(=)h Fd(expr)309
+b Fe(assign)28 b(expression)f(to)g(v)l(ariable)-387 -193
+y Fd(var)g Ff(\()p Fd(idx)p Ff(\))h(=)g Fd(expr)123 b
+Fe(assign)28 b(expression)f(to)g(indexed)f(v)l(ariable)-387
+-118 y Fd(var)h Ff(\()p Fd(idx)p Ff(\))h(=)g([])181 b
+Fe(delete)26 b(the)h(indexed)e(elemen)n(ts.)-387 -32
+y Fd(var)i Fb(f)p Fd(idx)p Fb(g)g Ff(=)h Fd(expr)110
+b Fe(assign)28 b(elemen)n(ts)e(of)h(a)h(cell)e(arra)n(y)-5
+b(.)-387 135 y Fg(Arithmetic)27 b(and)h(Incremen)m(t)g(Op)s(erators)
+-387 219 y Fd(x)f Ff(+)h Fd(y)468 b Fe(addition)-387
+293 y Fd(x)27 b Ff(-)h Fd(y)468 b Fe(subtraction)-387
+368 y Fd(x)27 b Ff(*)h Fd(y)468 b Fe(matrix)27 b(m)n(ultiplication)-387
+443 y Fd(x)g Ff(.*)h Fd(y)433 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)f
+(m)n(ultiplication)-387 518 y Fd(x)h Ff(/)h Fd(y)468
+b Fe(righ)n(t)28 b(division,)e(conceptually)f(equiv)l(alen)n(t)h(to)278
+592 y Ff(\(inverse)k(\(y'\))f(*)f(x'\)')-387 671 y Fd(x)f
+Ff(./)h Fd(y)433 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)f(righ)n(t)h
+(division)-387 746 y Fd(x)g Ff(\\)h Fd(y)468 b Fe(left)27
+b(division,)f(conceptually)f(equiv)l(alen)n(t)h(to)278
+820 y Ff(inverse)k(\(x\))e(*)g(y)-387 899 y Fd(x)f Ff(.\\)h
+Fd(y)433 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)f(left)g(division)-387
+974 y Fd(x)h Ff(^)h Fd(y)468 b Fe(p)r(o)n(w)n(er)28 b(op)r(erator)-387
+1048 y Fd(x)f Ff(.^)h Fd(y)433 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)
+f(p)r(o)n(w)n(er)h(op)r(erator)-387 1123 y Ff(-)h Fd(x)528
+b Fe(negation)-387 1198 y Ff(+)28 b Fd(x)528 b Fe(unary)27
+b(plus)g(\(a)h(no-op\))-387 1273 y Fd(x)f Ff(')529 b
+Fe(complex)26 b(conjugate)g(transp)r(ose)-387 1347 y
+Fd(x)h Ff(.')494 b Fe(transp)r(ose)-387 1422 y Ff(++)28
+b Fd(x)70 b Fe(\()p Ff(--)28 b Fd(x)p Fe(\))241 b(incremen)n(t)25
+b(\(decremen)n(t\),)g(return)h Fd(new)34 b Fe(v)l(alue)-387
+1497 y Fd(x)27 b Ff(++)71 b Fe(\()p Fd(x)27 b Ff(--)p
+Fe(\))242 b(incremen)n(t)25 b(\(decremen)n(t\),)g(return)h
+Fd(old)33 b Fe(v)l(alue)-387 1658 y Fg(Comparison)26
+b(and)i(Bo)s(olean)f(Op)s(erators)-387 1751 y Fe(These)g(op)r(erators)g
+(w)n(ork)h(on)f(an)h(elemen)n(t-b)n(y-elemen)n(t)23 b(basis.)42
+b(Both)-387 1825 y(argumen)n(ts)26 b(are)h(alw)n(a)n(ys)i(ev)l
+(aluated.)-387 1930 y Fd(x)e Ff(<)h Fd(y)468 b Fe(true)27
+b(if)g Fd(x)35 b Fe(is)27 b(less)h(than)f Fd(y)-387 2005
+y(x)g Ff(<=)h Fd(y)433 b Fe(true)27 b(if)g Fd(x)35 b
+Fe(is)27 b(less)h(than)f(or)h(equal)e(to)i Fd(y)-387
+2080 y(x)f Ff(==)h Fd(y)433 b Fe(true)27 b(if)g Fd(x)35
+b Fe(is)27 b(equal)g(to)h Fd(y)-387 2154 y(x)f Ff(>=)h
+Fd(y)433 b Fe(true)27 b(if)g Fd(x)35 b Fe(is)27 b(greater)g(than)g(or)h
+(equal)e(to)i Fd(y)-387 2229 y(x)f Ff(>)h Fd(y)468 b
+Fe(true)27 b(if)g Fd(x)35 b Fe(is)27 b(greater)g(than)g
+Fd(y)-387 2304 y(x)g Ff(!=)h Fd(y)433 b Fe(true)27 b(if)g
+Fd(x)35 b Fe(is)27 b(not)h(equal)e(to)i Fd(y)-387 2378
+y(x)f Ff(&)h Fd(y)468 b Fe(true)27 b(if)g(b)r(oth)g Fd(x)34
+b Fe(and)28 b Fd(y)33 b Fe(are)27 b(true)-387 2453 y
+Fd(x)g Ff(|)h Fd(y)468 b Fe(true)27 b(if)g(at)h(least)f(one)g(of)h
+Fd(x)34 b Fe(or)28 b Fd(y)33 b Fe(is)27 b(true)-387 2528
+y Ff(!)41 b Fd(b)m(o)m(ol)433 b Fe(true)27 b(if)g Fd(b)m(o)m(ol)32
+b Fe(is)c(false)-387 2673 y Fg(Short-circuit)g(Bo)s(olean)e(Op)s
+(erators)-387 2766 y Fe(Op)r(erators)h(ev)l(aluate)f(left-to-righ)n(t.)
+41 b(Op)r(erands)26 b(are)h(only)g(ev)l(aluated)g(if)-387
+2841 y(necessary)-5 b(,)25 b(stopping)i(once)g(o)n(v)n(erall)g(truth)g
+(v)l(alue)g(can)g(b)r(e)g(determined.)-387 2916 y(Op)r(erands)f(are)h
+(con)n(v)n(erted)f(to)i(scalars)f(using)h(the)e Ff(all)j
+Fe(function.)-387 3021 y Fd(x)e Ff(&&)h Fd(y)433 b Fe(true)27
+b(if)g(b)r(oth)g Fd(x)34 b Fe(and)28 b Fd(y)33 b Fe(are)27
+b(true)-387 3095 y Fd(x)g Ff(||)h Fd(y)433 b Fe(true)27
+b(if)g(at)h(least)f(one)g(of)h Fd(x)34 b Fe(or)28 b Fd(y)33
+b Fe(is)27 b(true)-387 3253 y Fg(Op)s(erator)g(Precedence)-387
+3340 y Fe(T)-5 b(able)26 b(of)i(Octa)n(v)n(e)f(op)r(erators,)g(in)g
+(order)g(of)g(increasing)f(precedence.)-387 3445 y Ff(;)55
+b(,)498 b Fe(statemen)n(t)27 b(separators)-387 3519 y
+Ff(=)588 b Fe(assignmen)n(t,)27 b(groups)g(left)g(to)h(righ)n(t)-387
+3594 y Ff(||)56 b(&&)427 b Fe(logical)27 b(\\or")h(and)f(\\and")-387
+3669 y Ff(|)55 b(&)498 b Fe(elemen)n(t-wise)26 b(\\or")i(and)f(\\and")
+-387 3743 y Ff(<)h(<=)g(==)g(>=)g(>)g(!=)133 b Fe(relational)27
+b(op)r(erators)-387 3818 y Ff(:)588 b Fe(colon)-387 3893
+y Ff(+)55 b(-)498 b Fe(addition)27 b(and)g(subtraction)-387
+3968 y Ff(*)h(/)g(\\)55 b(.*)h(./)g(.\\)85 b Fe(m)n(ultiplication)25
+b(and)i(division)-387 4042 y Ff(')55 b(.')463 b Fe(transp)r(ose)-387
+4117 y Ff(+)55 b(-)h(++)g(--)g(!)155 b Fe(unary)27 b(min)n(us,)g
+(incremen)n(t,)e(logical)i(\\not")-387 4192 y Ff(^)55
+b(.^)463 b Fe(exp)r(onen)n(tiation)p 1738 -418 1 17 v
+1738 4195 V 1951 -352 a Fg(P)m(aths)29 b(and)f(P)m(ac)m(k)-5
+b(ages)1951 -267 y Ff(path)484 b Fe(displa)n(y)27 b(the)g(curren)n(t)f
+(Octa)n(v)n(e)h(cunction)f(path.)1951 -193 y Ff(pathdef)379
+b Fe(displa)n(y)27 b(the)g(default)f(path.)1951 -118
+y Ff(addpath\()p Fd(dir)p Ff(\))224 b Fe(add)27 b(a)h(directory)e(to)i
+(the)f(path.)1951 -43 y Ff(EXEC)p 2095 -43 22 4 v 27
+w(PATH)317 b Fe(manipulate)26 b(the)g(Octa)n(v)n(e)i(executable)c
+(path.)1951 31 y Ff(pkg)29 b(list)350 b Fe(displa)n(y)27
+b(installed)g(pac)n(k)l(ages.)1951 106 y Ff(pkg)i(load)g
+Fd(p)m(ack)190 b Fe(Load)28 b(an)f(installed)f(pac)n(k)l(age.)1951
+267 y Fg(Cells)h(and)h(Structures)1951 351 y Fd(var)p
+Ff(.)p Fd(\014eld)g Ff(=)g(...)173 b Fe(set)28 b(a)f(\014eld)g(of)g(a)h
+(structure.)1951 443 y Fd(var)p Fb(f)p Fd(idx)p Fb(g)f
+Ff(=)h(...)161 b Fe(set)28 b(an)f(elemen)n(t)e(of)j(a)g(cell)e(arra)n
+(y)-5 b(.)1951 527 y Ff(cellfun\()p Fd(f)p Ff(,)31 b
+Fd(c)p Ff(\))190 b Fe(apply)27 b(a)h(function)d(to)j(elemen)n(ts)e(of)h
+(cell)f(arra)n(y)-5 b(.)1951 602 y Ff(fieldnames\()p
+Fd(s)p Ff(\))176 b Fe(returns)27 b(the)g(\014elds)f(of)i(a)f
+(structure.)1951 748 y Fg(Statemen)m(ts)1951 830 y Ff(for)i
+Fd(identi\014er)g Ff(=)f Fd(expr)f(stmt-list)h Ff(endfor)2034
+906 y Fe(Execute)e Fd(stmt-list)i Fe(once)e(for)i(eac)n(h)e(column)g
+(of)i Fd(expr)p Fe(.)40 b(The)28 b(v)l(ariable)2034 980
+y Fd(identi\014er)h Fe(is)f(set)g(to)f(the)g(v)l(alue)g(of)g(the)g
+(curren)n(t)f(column)g(during)2034 1055 y(eac)n(h)h(iteration.)1951
+1199 y Ff(while)j(\()p Fd(c)m(ondition)p Ff(\))f Fd(stmt-list)f
+Ff(endwhile)2034 1280 y Fe(Execute)e Fd(stmt-list)i Fe(while)f
+Fd(c)m(ondition)i Fe(is)f(true.)1951 1417 y Ff(break)477
+b Fe(exit)27 b(innermost)f(lo)r(op)1951 1492 y Ff(continue)372
+b Fe(go)28 b(to)f(b)r(eginning)f(of)h(innermost)f(lo)r(op)1951
+1567 y Ff(return)442 b Fe(return)26 b(to)i(calling)e(function)1951
+1733 y Ff(if)j(\()p Fd(c)m(ondition)p Ff(\))g Fd(if-b)m(o)m(dy)f
+Fc([)p Ff(else)h Fd(else-b)m(o)m(dy)p Fc(])d Ff(endif)2034
+1818 y Fe(Execute)g Fd(if-b)m(o)m(dy)h Fe(if)g Fd(c)m(ondition)i
+Fe(is)f(true,)f(otherwise)g(execute)e Fd(else-)2034 1893
+y(b)m(o)m(dy)p Fe(.)1951 1984 y Ff(if)k(\()p Fd(c)m(ondition)p
+Ff(\))g Fd(if-b)m(o)m(dy)f Fc([)p Ff(elseif)h Fe(\()p
+Fd(c)m(ondition)p Fe(\))g Fd(elseif-b)m(o)m(dy)p Fc(])e
+Ff(endif)2034 2069 y Fe(Execute)f Fd(if-b)m(o)m(dy)h
+Fe(if)g Fd(c)m(ondition)i Fe(is)f(true,)f(otherwise)g(execute)e(the)
+2034 2144 y Fd(elseif-b)m(o)m(dy)j Fe(corresp)r(onding)d(to)j(the)e
+(\014rst)i Ff(elseif)h Fe(condition)d(that)2034 2219
+y(is)i(true,)f(otherwise)g(execute)e Fd(else-b)m(o)m(dy)p
+Fe(.)2034 2294 y(An)n(y)j(n)n(um)n(b)r(er)e(of)h Ff(elseif)j
+Fe(clauses)c(ma)n(y)i(app)r(ear)e(in)h(an)h Ff(if)2034
+2369 y Fe(statemen)n(t.)1951 2504 y Ff(unwind)p 2165
+2504 V 28 w(protect)h Fd(b)m(o)m(dy)e Ff(unwind)p 2833
+2504 V 27 w(protect)p 3105 2504 V 28 w(cleanup)i Fd(cle)m(anup)e
+Ff(end)2034 2583 y Fe(Execute)f Fd(b)m(o)m(dy)p Fe(.)40
+b(Execute)26 b Fd(cle)m(anup)h Fe(no)g(matter)g(ho)n(w)h(con)n(trol)f
+(exits)2034 2658 y Fd(b)m(o)m(dy)p Fe(.)1951 2729 y Ff(try)i
+Fd(b)m(o)m(dy)e Ff(catch)i Fd(cle)m(anup)e Ff(end)2034
+2807 y Fe(Execute)f Fd(b)m(o)m(dy)p Fe(.)40 b(Execute)26
+b Fd(cle)m(anup)h Fe(if)g Fd(b)m(o)m(dy)g Fe(fails.)1951
+2973 y Fg(Strings)1951 3058 y Ff(strcmp)j(\()p Fd(s)p
+Ff(,)e Fd(t)p Ff(\))410 b Fe(compare)26 b(strings)1951
+3132 y Ff(strcat)k(\()p Fd(s)p Ff(,)e Fd(t)p Ff(,)g(...\))242
+b Fe(concatenate)25 b(strings)1951 3207 y Ff(regexp)30
+b(\()p Fd(str)p Ff(,)e Fd(p)m(at)p Ff(\))291 b Fe(strings)28
+b(matc)n(hing)e(regular)h(expression)1951 3282 y Ff(regexprep)k(\()p
+Fd(str)p Ff(,)d Fd(p)m(at)p Ff(,)g Fd(r)m(ep)p Ff(\))h
+Fe(Matc)n(h)e(and)g(replace)f(sub-strings)1951 3443 y
+Fg(De\014ning)h(F)-8 b(unctions)1951 3558 y Ff(function)30
+b Fc([)p Fd(r)m(et-list)p Fc(])e Fd(function-name)h Fc([)13
+b Fe(\()p Fd(ar)m(g-list)p Fe(\))g Fc(])2022 3642 y Fd(function-b)m(o)m
+(dy)1951 3728 y Ff(endfunction)1951 3861 y Fd(r)m(et-list)33
+b Fe(ma)n(y)28 b(b)r(e)f(a)g(single)g(iden)n(ti\014er)e(or)j(a)g
+(comma-separated)e(list)h(of)1951 3936 y(iden)n(ti\014ers)f(delimited)f
+(b)n(y)i(square-brac)n(k)n(ets.)1951 4024 y Fd(ar)m(g-list)33
+b Fe(is)28 b(a)g(comma-separated)e(list)h(of)g(iden)n(ti\014ers)f(and)h
+(ma)n(y)h(b)r(e)1951 4098 y(empt)n(y)-5 b(.)p 4077 -418
+1 17 v 4077 4195 V 4290 -352 a Fg(F)d(unction)28 b(Handles)4290
+-267 y Ff(@)p Fd(func)461 b Fe(De\014ne)26 b(a)i(function)d(handle)i
+(to)g Fd(func)p Fe(.)4290 -193 y Ff(@\()p Fd(var1)p Ff(,)i(...\))42
+b Fd(expr)49 b Fe(De\014ne)26 b(an)h(anon)n(ymous)g(function)f(handle.)
+4290 -118 y Ff(str2func)k(\()p Fd(str)p Ff(\))164 b Fe(Create)27
+b(a)h(function)e(handle)g(from)g(a)i(string.)4290 -43
+y Ff(functions)j(\()p Fd(hand)s(le)p Ff(\))12 b Fe(Return)27
+b(information)f(ab)r(out)h(a)g(function)4956 31 y(handle.)4290
+95 y Ff(func2str)j(\()p Fd(hand)s(le)p Ff(\))48 b Fe(Return)27
+b(a)g(string)h(represen)n(tation)d(of)j(a)4956 170 y(function)d
+(handle.)4290 234 y Fd(hand)s(le)k Ff(\()p Fd(ar)m(g1)p
+Ff(,)e(...\))34 b Fe(Ev)l(aluate)27 b(a)h(function)d(handle.)4290
+309 y Ff(feval)k(\()p Fd(func)p Ff(,)g Fd(ar)m(g1)p Ff(,)4290
+383 y(...\))4914 309 y Fe(Ev)l(aluate)e(a)h(function)d(handle)h(or)i
+(string,)4956 383 y(passing)f(remaining)f(args)i(to)g
+Fd(func)4290 459 y Fe(Anon)n(ymous)f(function)f(handles)g(tak)n(e)h(a)h
+(cop)n(y)f(of)h(the)e(v)l(ariables)i(in)f(the)4290 534
+y(curren)n(t)f(w)n(orkspace.)4290 709 y Fg(Miscellaneous)g(F)-8
+b(unctions)4290 794 y Ff(eval)29 b(\()p Fd(str)p Ff(\))305
+b Fe(ev)l(aluate)27 b Fd(str)h Fe(as)g(a)g(command)4290
+868 y Ff(error)h(\()p Fd(message)p Ff(\))107 b Fe(prin)n(t)27
+b(message)g(and)g(return)f(to)i(top)g(lev)n(el)4290 943
+y Ff(warning)i(\()p Fd(message)p Ff(\))36 b Fe(prin)n(t)27
+b(a)h(w)n(arning)f(message)4290 1018 y Ff(clear)i Fd(p)m(attern)208
+b Fe(clear)27 b(v)l(ariables)g(matc)n(hing)f(pattern)4290
+1092 y Ff(exist)j(\()p Fd(str)p Ff(\))270 b Fe(c)n(hec)n(k)26
+b(existence)g(of)h(v)l(ariable)g(or)h(function)4290 1167
+y Ff(who,)h(whos)315 b Fe(list)28 b(curren)n(t)e(v)l(ariables)4290
+1242 y Ff(whos)j Fd(var)359 b Fe(details)27 b(of)g(the)g(v)l(aribale)g
+Fd(var)4290 1387 y Fg(Basic)h(Matrix)g(Manipulations)4290
+1472 y Ff(rows)h(\()p Fd(a)p Ff(\))350 b Fe(return)26
+b(n)n(um)n(b)r(er)g(of)i(ro)n(ws)g(of)g Fd(a)4290 1546
+y Ff(columns)i(\()p Fd(a)p Ff(\))244 b Fe(return)26 b(n)n(um)n(b)r(er)g
+(of)i(columns)e(of)h Fd(a)4290 1621 y Ff(all)i(\()p Fd(a)p
+Ff(\))385 b Fe(c)n(hec)n(k)26 b(if)h(all)h(elemen)n(ts)d(of)j
+Fd(a)k Fe(nonzero)4290 1696 y Ff(any)d(\()p Fd(a)p Ff(\))385
+b Fe(c)n(hec)n(k)26 b(if)h(an)n(y)h(elemen)n(ts)e(of)h
+Fd(a)33 b Fe(nonzero)4290 1851 y Ff(find)c(\()p Fd(a)p
+Ff(\))350 b Fe(return)26 b(indices)g(of)i(nonzero)e(elemen)n(ts)4290
+1926 y Ff(sort)j(\()p Fd(a)p Ff(\))350 b Fe(order)27
+b(elemen)n(ts)f(in)h(eac)n(h)f(column)g(of)i Fd(a)4290
+2000 y Ff(sum)h(\()p Fd(a)p Ff(\))385 b Fe(sum)27 b(elemen)n(ts)f(in)h
+(columns)f(of)i Fd(a)4290 2075 y Ff(prod)h(\()p Fd(a)p
+Ff(\))350 b Fe(pro)r(duct)26 b(of)h(elemen)n(ts)f(in)h(columns)f(of)i
+Fd(a)4290 2150 y Ff(min)h(\()p Fd(ar)m(gs)p Ff(\))299
+b Fe(\014nd)27 b(minim)n(um)e(v)l(alues)4290 2224 y Ff(max)k(\()p
+Fd(ar)m(gs)p Ff(\))299 b Fe(\014nd)27 b(maxim)n(um)f(v)l(alues)4290
+2299 y Ff(rem)j(\()p Fd(x)p Ff(,)f Fd(y)p Ff(\))292 b
+Fe(\014nd)27 b(remainder)e(of)i Fd(x)p Fe(/)p Fd(y)4290
+2374 y Ff(reshape)j(\()p Fd(a)p Ff(,)e Fd(m)p Ff(,)g
+Fd(n)p Ff(\))c Fe(reformat)i Fd(a)i Fe(to)g(b)r(e)f Fd(m)g
+Fe(b)n(y)g Fd(n)4290 2449 y Ff(diag)i(\()p Fd(v)p Ff(,)f
+Fd(k)p Ff(\))258 b Fe(create)26 b(diagonal)h(matrices)4290
+2523 y Ff(linspace)j(\()p Fd(b)p Ff(,)e Fd(l)p Ff(,)g
+Fd(n)p Ff(\))i Fe(create)c(v)n(ector)h(of)g(linearly-spaced)f(elemen)n
+(ts)4290 2598 y Ff(logspace)k(\()p Fd(b)p Ff(,)e Fd(l)p
+Ff(,)g Fd(n)p Ff(\))i Fe(create)c(v)n(ector)h(of)g(log-spaced)g(elemen)
+n(ts)4290 2673 y Ff(eye)i(\()p Fd(n)p Ff(,)g Fd(m)p Ff(\))262
+b Fe(create)26 b Fd(n)33 b Fe(b)n(y)28 b Fd(m)k Fe(iden)n(tit)n(y)26
+b(matrix)4290 2747 y Ff(ones)j(\()p Fd(n)p Ff(,)g Fd(m)p
+Ff(\))227 b Fe(create)26 b Fd(n)33 b Fe(b)n(y)28 b Fd(m)k
+Fe(matrix)27 b(of)g(ones)4290 2822 y Ff(zeros)i(\()p
+Fd(n)p Ff(,)g Fd(m)p Ff(\))192 b Fe(create)26 b Fd(n)33
+b Fe(b)n(y)28 b Fd(m)k Fe(matrix)27 b(of)g(zeros)4290
+2897 y Ff(rand)i(\()p Fd(n)p Ff(,)g Fd(m)p Ff(\))227
+b Fe(create)26 b Fd(n)33 b Fe(b)n(y)28 b Fd(m)k Fe(matrix)27
+b(of)g(random)g(v)l(alues)4290 3054 y Fg(Linear)h(Algebra)4290
+3139 y Ff(chol)h(\()p Fd(a)p Ff(\))350 b Fe(Cholesky)27
+b(factorization)4290 3213 y Ff(det)i(\()p Fd(a)p Ff(\))385
+b Fe(compute)26 b(the)h(determinan)n(t)e(of)i(a)h(matrix)4290
+3288 y Ff(eig)h(\()p Fd(a)p Ff(\))385 b Fe(eigen)n(v)l(alues)26
+b(and)h(eigen)n(v)n(ectors)4290 3363 y Ff(expm)i(\()p
+Fd(a)p Ff(\))350 b Fe(compute)26 b(the)h(exp)r(onen)n(tial)e(of)i(a)h
+(matrix)4290 3437 y Ff(hess)h(\()p Fd(a)p Ff(\))350 b
+Fe(compute)26 b(Hessen)n(b)r(erg)g(decomp)r(osition)4290
+3512 y Ff(inverse)k(\()p Fd(a)p Ff(\))244 b Fe(in)n(v)n(ert)27
+b(a)h(square)f(matrix)4290 3587 y Ff(norm)i(\()p Fd(a)p
+Ff(,)f Fd(p)p Ff(\))252 b Fe(compute)26 b(the)h Fd(p)p
+Fe(-norm)g(of)g(a)h(matrix)4290 3662 y Ff(pinv)h(\()p
+Fd(a)p Ff(\))350 b Fe(compute)26 b(pseudoin)n(v)n(erse)f(of)j
+Fd(a)4290 3736 y Ff(qr)h(\()p Fd(a)p Ff(\))420 b Fe(compute)26
+b(the)h(QR)g(factorization)f(of)h(a)h(matrix)4290 3811
+y Ff(rank)h(\()p Fd(a)p Ff(\))350 b Fe(matrix)27 b(rank)4290
+3886 y Ff(sprank)j(\()p Fd(a)p Ff(\))279 b Fe(structrual)27
+b(matrix)f(rank)4290 3961 y Ff(schur)j(\()p Fd(a)p Ff(\))315
+b Fe(Sc)n(h)n(ur)27 b(decomp)r(osition)e(of)i(a)h(matrix)4290
+4035 y Ff(svd)h(\()p Fd(a)p Ff(\))385 b Fe(singular)27
+b(v)l(alue)g(decomp)r(osition)4290 4110 y Ff(syl)i(\()p
+Fd(a)p Ff(,)f Fd(b)p Ff(,)g Fd(c)p Ff(\))195 b Fe(solv)n(e)28
+b(the)e(Sylv)n(ester)h(equation)p eop end
+%%Page: 3 3
+TeXDict begin @landscape 3 2 bop -387 -352 a Fg(Equations,)26
+b(ODEs,)h(D)m(AEs,)g(Quadrature)-387 -267 y Ff(*fsolve)378
+b Fe(solv)n(e)28 b(nonlinear)e(algebraic)g(equations)-387
+-193 y Ff(*lsode)413 b Fe(in)n(tegrate)27 b(nonlinear)f(ODEs)-387
+-118 y Ff(*dassl)413 b Fe(in)n(tegrate)27 b(nonlinear)f(D)n(AEs)-387
+-43 y Ff(*quad)448 b Fe(in)n(tegrate)27 b(nonlinear)f(functions)-387
+31 y Ff(perror)j(\()p Fd(nm)p Ff(,)f Fd(c)m(o)m(de)p
+Ff(\))h Fe(for)f(functions)e(that)h(return)f(n)n(umeric)g(co)r(des,)278
+106 y(prin)n(t)h(error)g(message)g(for)g(named)f(function)278
+181 y(and)h(giv)n(en)g(error)g(co)r(de)-387 268 y Ff(*)h
+Fe(See)e(the)h(on-line)f(or)i(prin)n(ted)e(man)n(ual)h(for)g(the)g
+(complete)e(list)j(of)-387 343 y(argumen)n(ts)e(for)i(these)e
+(functions.)-387 488 y Fg(Signal)h(Pro)s(cessing)-387
+572 y Ff(fft)h(\()p Fd(a)p Ff(\))385 b Fe(F)-5 b(ast)28
+b(F)-5 b(ourier)26 b(T)-5 b(ransform)27 b(using)g(FFTW)-387
+647 y Ff(ifft)h(\()p Fd(a)p Ff(\))350 b Fe(in)n(v)n(erse)27
+b(FFT)h(using)f(FFTW)-387 722 y Ff(freqz)i(\()p Fd(ar)m(gs)p
+Ff(\))228 b Fe(FIR)28 b(\014lter)f(frequency)d(resp)r(onse)-387
+797 y Ff(filter)29 b(\()p Fd(a)p Ff(,)f Fd(b)p Ff(,)g
+Fd(x)p Ff(\))89 b Fe(\014lter)27 b(b)n(y)g(transfer)g(function)-387
+871 y Ff(conv)h(\()p Fd(a)p Ff(,)h Fd(b)p Ff(\))254 b
+Fe(con)n(v)n(olv)n(e)27 b(t)n(w)n(o)i(v)n(ectors)-387
+946 y Ff(hamming)g(\()p Fd(n)p Ff(\))241 b Fe(return)27
+b(Hamming)f(windo)n(w)i(co)r(e\016cen)n(ts)-387 1021
+y Ff(hanning)h(\()p Fd(n)p Ff(\))241 b Fe(return)27 b(Hanning)f(windo)n
+(w)i(co)r(e\016cen)n(ts)-387 1182 y Fg(Image)f(Pro)s(cessing)-387
+1266 y Ff(colormap)j(\()p Fd(map)p Ff(\))327 b Fe(set)28
+b(the)f(curren)n(t)f(colormap)-387 1341 y Ff(gray2ind)k(\()p
+Fd(i)p Ff(,)e Fd(n)p Ff(\))331 b Fe(con)n(v)n(ert)27
+b(gra)n(y)h(scale)f(to)h(Octa)n(v)n(e)f(image)-387 1415
+y Ff(image)i(\()p Fd(img)p Ff(,)f Fd(zo)m(om)p Ff(\))236
+b Fe(displa)n(y)27 b(an)h(Octa)n(v)n(e)f(image)g(matrix)-387
+1490 y Ff(imagesc)i(\()p Fd(img)p Ff(,)f Fd(zo)m(om)p
+Ff(\))166 b Fe(displa)n(y)27 b(scaled)g(matrix)g(as)h(image)-387
+1565 y Ff(imshow)h(\()p Fd(img)p Ff(,)f Fd(map)p Ff(\))226
+b Fe(displa)n(y)27 b(Octa)n(v)n(e)g(image)-387 1640 y
+Ff(imshow)i(\()p Fd(i)p Ff(,)g Fd(n)p Ff(\))401 b Fe(displa)n(y)27
+b(gra)n(y)h(scale)f(image)-387 1714 y Ff(imshow)i(\()p
+Fd(r)p Ff(,)f Fd(g)p Ff(,)g Fd(b)p Ff(\))305 b Fe(displa)n(y)27
+b(R)n(GB)i(image)-387 1789 y Ff(ind2gray)h(\()p Fd(img)p
+Ff(,)d Fd(map)p Ff(\))156 b Fe(con)n(v)n(ert)27 b(Octa)n(v)n(e)g(image)
+g(to)g(gra)n(y)h(scale)-387 1864 y Ff(ind2rgb)h(\()p
+Fd(img)p Ff(,)f Fd(map)p Ff(\))191 b Fe(con)n(v)n(ert)27
+b(indexed)e(image)i(to)h(R)n(GB)-387 1938 y Ff(loadimage)i(\()p
+Fd(\014le)p Ff(\))329 b Fe(load)28 b(an)f(image)g(\014le)-387
+2013 y Ff(rgb2ind)i(\()p Fd(r)p Ff(,)g Fd(g)p Ff(,)e
+Fd(b)p Ff(\))270 b Fe(con)n(v)n(ert)27 b(R)n(GB)i(to)f(Octa)n(v)n(e)f
+(image)-387 2088 y Ff(saveimage)j(\()p Fd(\014le)p Ff(,)e
+Fd(img)p Ff(,)g Fd(fmt)p Ff(,)g Fd(map)p Ff(\))70 b Fe(sa)n(v)n(e)28
+b(a)g(matrix)f(to)g Fd(\014le)-387 2234 y Fg(C-st)m(yle)g(Input)h(and)g
+(Output)-387 2318 y Ff(fopen)h(\()p Fd(name)p Ff(,)f
+Fd(mo)m(de)p Ff(\))180 b Fe(op)r(en)27 b(\014le)f Fd(name)-387
+2392 y Ff(fclose)j(\()p Fd(\014le)p Ff(\))435 b Fe(close)27
+b Fd(\014le)-387 2467 y Ff(printf)i(\()p Fd(fmt)p Ff(,)f(...\))256
+b Fe(formatted)26 b(output)h(to)h Ff(stdout)-387 2542
+y(fprintf)h(\()p Fd(\014le)p Ff(,)g Fd(fmt)p Ff(,)f(...\))68
+b Fe(formatted)26 b(output)h(to)h Fd(\014le)-387 2617
+y Ff(sprintf)h(\()p Fd(fmt)p Ff(,)g(...\))220 b Fe(formatted)26
+b(output)h(to)h(string)-387 2691 y Ff(scanf)h(\()p Fd(fmt)p
+Ff(\))459 b Fe(formatted)26 b(input)h(from)g Ff(stdin)-387
+2766 y(fscanf)i(\()p Fd(\014le)p Ff(,)f Fd(fmt)p Ff(\))272
+b Fe(formatted)26 b(input)h(from)g Fd(\014le)-387 2841
+y Ff(sscanf)i(\()p Fd(str)p Ff(,)g Fd(fmt)p Ff(\))280
+b Fe(formatted)26 b(input)h(from)g Fd(string)-387 2915
+y Ff(fgets)i(\()p Fd(\014le)p Ff(,)f Fd(len)p Ff(\))319
+b Fe(read)27 b Fd(len)33 b Fe(c)n(haracters)26 b(from)h
+Fd(\014le)-387 2990 y Ff(fflush)i(\()p Fd(\014le)p Ff(\))435
+b Fe(\015ush)27 b(p)r(ending)f(output)g(to)i Fd(\014le)-387
+3065 y Ff(ftell)h(\()p Fd(\014le)p Ff(\))470 b Fe(return)27
+b(\014le)f(p)r(oin)n(ter)h(p)r(osition)-387 3140 y Ff(frewind)i(\()p
+Fd(\014le)p Ff(\))400 b Fe(mo)n(v)n(e)28 b(\014le)e(p)r(oin)n(ter)g(to)
+i(b)r(eginning)-387 3214 y Ff(freport)588 b Fe(prin)n(t)27
+b(a)h(info)f(for)g(op)r(en)g(\014les)-387 3289 y Ff(fread)i(\()p
+Fd(\014le)p Ff(,)f Fd(size)p Ff(,)g Fd(pr)m(e)m(c)p Ff(\))113
+b Fe(read)27 b(binary)g(data)g(\014les)-387 3364 y Ff(fwrite)i(\()p
+Fd(\014le)p Ff(,)f Fd(size)p Ff(,)h Fd(pr)m(e)m(c)p Ff(\))77
+b Fe(write)28 b(binary)e(data)i(\014les)-387 3438 y Ff(feof)g(\()p
+Fd(\014le)p Ff(\))506 b Fe(determine)25 b(if)i(p)r(oin)n(ter)g(is)g(at)
+h(EOF)-387 3527 y(A)f(\014le)g(ma)n(y)g(b)r(e)g(referenced)d(either)i
+(b)n(y)h(name)g(or)h(b)n(y)f(the)g(n)n(um)n(b)r(er)-387
+3601 y(returned)e(from)i Ff(fopen)p Fe(.)43 b(Three)26
+b(\014les)h(are)h(preconnected)23 b(when)k(Octa)n(v)n(e)-387
+3676 y(starts:)41 b Ff(stdin)p Fe(,)29 b Ff(stdout)p
+Fe(,)h(and)d Ff(stderr)p Fe(.)-387 3852 y Fg(Other)g(Input)h(and)h
+(Output)e(functions)-387 3936 y Ff(save)h Fd(\014le)g(var)g
+Ff(...)109 b Fe(sa)n(v)n(e)28 b(v)l(ariables)f(in)h Fd(\014le)-387
+4011 y Ff(load)g Fd(\014le)366 b Fe(load)28 b(v)l(ariables)f(from)g
+Fd(\014le)-387 4085 y Ff(disp)h(\()p Fd(var)p Ff(\))289
+b Fe(displa)n(y)27 b(v)l(alue)h(of)f Fd(var)g Fe(to)h(screen)p
+1738 -418 1 17 v 1738 4195 V 1951 -352 a Fg(P)m(olynomials)1951
+-267 y Ff(compan)i(\()p Fd(p)p Ff(\))279 b Fe(companion)26
+b(matrix)1951 -193 y Ff(conv)j(\()p Fd(a)p Ff(,)g Fd(b)p
+Ff(\))254 b Fe(con)n(v)n(olution)1951 -118 y Ff(deconv)30
+b(\()p Fd(a)p Ff(,)e Fd(b)p Ff(\))184 b Fe(decon)n(v)n(olv)n(e)26
+b(t)n(w)n(o)j(v)n(ectors)1951 -43 y Ff(poly)g(\()p Fd(a)p
+Ff(\))350 b Fe(create)26 b(p)r(olynomial)g(from)h(a)h(matrix)1951
+31 y Ff(polyderiv)j(\()p Fd(p)p Ff(\))173 b Fe(deriv)l(ativ)n(e)27
+b(of)g(p)r(olynomial)1951 106 y Ff(polyreduce)k(\()p
+Fd(p)p Ff(\))138 b Fe(in)n(tegral)27 b(of)g(p)r(olynomial)1951
+181 y Ff(polyval)j(\()p Fd(p)p Ff(,)e Fd(x)p Ff(\))149
+b Fe(v)l(alue)27 b(of)h(p)r(olynomial)e(at)h Fd(x)1951
+256 y Ff(polyvalm)j(\()p Fd(p)p Ff(,)f Fd(x)p Ff(\))113
+b Fe(v)l(alue)27 b(of)h(p)r(olynomial)e(at)h Fd(x)1951
+330 y Ff(roots)j(\()p Fd(p)p Ff(\))314 b Fe(p)r(olynomial)26
+b(ro)r(ots)1951 405 y Ff(residue)k(\()p Fd(a)p Ff(,)e
+Fd(b)p Ff(\))149 b Fe(partial)27 b(fraction)g(expansion)f(of)h(ratio)h
+Fd(a)p Fe(/)p Fd(b)1951 566 y Fg(Statistics)1951 650
+y Ff(corrcoef)i(\()p Fd(x)p Ff(,)e Fd(y)p Ff(\))116 b
+Fe(correlation)26 b(co)r(e\016cien)n(t)1951 725 y Ff(cov)j(\()p
+Fd(x)p Ff(,)f Fd(y)p Ff(\))292 b Fe(co)n(v)l(ariance)1951
+799 y Ff(mean)29 b(\()p Fd(a)p Ff(\))350 b Fe(mean)27
+b(v)l(alue)1951 874 y Ff(median)j(\()p Fd(a)p Ff(\))279
+b Fe(median)26 b(v)l(alue)1951 949 y Ff(std)j(\()p Fd(a)p
+Ff(\))385 b Fe(standard)27 b(deviation)1951 1024 y Ff(var)i(\()p
+Fd(a)p Ff(\))385 b Fe(v)l(ariance)1951 1169 y Fg(Plotting)27
+b(F)-8 b(unctions)1951 1253 y Ff(plot)29 b(\()p Fd(ar)m(gs)p
+Ff(\))264 b Fe(2D)28 b(plot)f(with)h(linear)e(axes)1951
+1328 y Ff(plot3)k(\()p Fd(ar)m(gs)p Ff(\))228 b Fe(3D)28
+b(plot)f(with)h(linear)e(axes)1951 1403 y Ff(line)j(\()p
+Fd(ar)m(gs)p Ff(\))264 b Fe(2D)28 b(or)g(3D)f(line)1951
+1478 y Ff(patch)j(\()p Fd(ar)m(gs)p Ff(\))228 b Fe(2D)28
+b(patc)n(h)1951 1552 y Ff(semilogx)i(\()p Fd(ar)m(gs)p
+Ff(\))123 b Fe(2D)28 b(plot)f(with)h(logarithmic)e(x-axis)1951
+1627 y Ff(semilogy)k(\()p Fd(ar)m(gs)p Ff(\))123 b Fe(2D)28
+b(plot)f(with)h(logarithmic)e(y-axis)1951 1702 y Ff(loglog)k(\()p
+Fd(ar)m(gs)p Ff(\))193 b Fe(2D)28 b(plot)f(with)h(logarithmic)e(axes)
+1951 1776 y Ff(bar)j(\()p Fd(ar)m(gs)p Ff(\))299 b Fe(plot)27
+b(bar)h(c)n(harts)1951 1851 y Ff(stairs)i(\()p Fd(x)p
+Ff(,)e Fd(y)p Ff(\))186 b Fe(plot)27 b(stairsteps)1951
+1926 y Ff(stem)i(\()p Fd(x)p Ff(,)f(it)g(y\))157 b Fe(plot)27
+b(a)h(stem)f(graph)1951 2001 y Ff(hist)i(\()p Fd(y)p
+Ff(,)g Fd(x)p Ff(\))256 b Fe(plot)27 b(histograms)1951
+2075 y Ff(contour)j(\()p Fd(x)p Ff(,)e Fd(y)p Ff(,)g
+Fd(z)p Ff(\))60 b Fe(con)n(tour)27 b(plot)1951 2150 y
+Ff(title)j(\()p Fd(string)p Ff(\))178 b Fe(set)28 b(plot)f(title)1951
+2225 y Ff(axis)i(\()p Fd(limits)p Ff(\))218 b Fe(set)28
+b(axis)f(ranges)1951 2299 y Ff(xlabel)j(\()p Fd(string)p
+Ff(\))143 b Fe(set)28 b(x-axis)g(lab)r(el)1951 2374 y
+Ff(ylabel)i(\()p Fd(string)p Ff(\))143 b Fe(set)28 b(y-axis)g(lab)r(el)
+1951 2449 y Ff(zlabel)i(\()p Fd(string)p Ff(\))143 b
+Fe(set)28 b(z-axis)f(lab)r(el)1951 2524 y Ff(text)i(\()p
+Fd(x)p Ff(,)f Fd(y)p Ff(,)g Fd(str)p Ff(\))114 b Fe(add)27
+b(text)g(to)h(a)g(plot)1951 2598 y Ff(legend)i(\()p Fd(string)p
+Ff(\))143 b Fe(set)28 b(lab)r(el)e(in)h(plot)g(k)n(ey)1951
+2693 y Ff(grid)i Fc([)p Fe(on)p Fb(j)p Fe(o\013)p Fc(])244
+b Fe(set)28 b(grid)f(state)1951 2794 y Ff(hold)i Fc([)p
+Fe(on)p Fb(j)p Fe(o\013)p Fc(])244 b Fe(set)28 b(hold)f(state)1951
+2869 y Ff(ishold)414 b Fe(return)27 b(1)g(if)g(hold)g(is)h(on,)f(0)h
+(otherwise)1951 2943 y Ff(mesh)h(\()p Fd(x)p Ff(,)f Fd(y)p
+Ff(,)g Fd(z)p Ff(\))166 b Fe(plot)27 b(3D)h(surface)1951
+3018 y Ff(meshgrid)i(\()p Fd(x)p Ff(,)e Fd(y)p Ff(\))116
+b Fe(create)26 b(mesh)h(co)r(ordinate)f(matrices)p 1951
+3146 1913 4 v 1951 3313 a Fh(Edition)h(2.0)h(for)g(Octa)n(v)n(e)h(V)-5
+b(ersion)28 b(3.0.0.)41 b(Cop)n(yrigh)n(t)29 b(1996,)g(2007,)f(John)
+1951 3388 y(W.)f(Eaton)h(\(jw)n(e at o)r(cta)n(v)n(e.org\).)44
+b(The)28 b(author)g(assumes)h(no)f(resp)r(onsibilit)n(y)1951
+3463 y(for)h(an)n(y)f(errors)g(on)g(this)f(card.)1951
+3587 y(This)h(card)g(ma)n(y)g(b)r(e)f(freely)h(distributed)e(under)h
+(the)h(terms)g(of)g(the)f(GNU)1951 3662 y(General)h(Public)e(License.)
+1951 3787 y(T)1984 3798 y(E)2018 3787 y(X)h(Macros)j(for)e(this)f(card)
+h(b)n(y)g(Roland)f(P)n(esc)n(h)i(\(p)r(esc)n(h at cygn)n(us.com\),)1951
+3861 y(originally)e(for)i(the)e(GDB)h(reference)g(card)1951
+3986 y(Octa)n(v)n(e)h(itself)f(is)f(free)h(soft)n(w)n(are;)i(y)n(ou)f
+(are)f(w)n(elcome)h(to)f(distribute)e(copies)1951 4061
+y(of)j(it)e(under)g(the)g(terms)h(of)h(the)e(GNU)g(General)h(Public)e
+(License.)40 b(There)28 b(is)1951 4135 y(absolutely)g(no)g(w)n(arran)n
+(t)n(y)h(for)g(Octa)n(v)n(e.)p 4077 -418 1 17 v 4077
+4195 V eop end
+%%Trailer
+
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/doc/refcard/refcard-a4.tex b/doc/refcard/refcard-a4.tex
new file mode 100644
index 0000000..3ea9abd
--- /dev/null
+++ b/doc/refcard/refcard-a4.tex
@@ -0,0 +1,24 @@
+% refcard-a4.tex
+%
+% Make a reference card that will fit on A4 paper.
+%
+% Copyright (C) 1996 John W. Eaton
+%
+% This file is part of Octave.
+%
+% Octave is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 3 of the License, or (at your
+% option) any later version.
+%
+% Octave is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Octave; see the file COPYING.  If not, see
+% <http://www.gnu.org/licenses/>.
+
+\def\refcardsize{a4}
+\input refcard.tex
diff --git a/doc/refcard/refcard-legal.dvi b/doc/refcard/refcard-legal.dvi
new file mode 100644
index 0000000..ac7591c
Binary files /dev/null and b/doc/refcard/refcard-legal.dvi differ
diff --git a/doc/refcard/refcard-legal.pdf b/doc/refcard/refcard-legal.pdf
new file mode 100644
index 0000000..c3463b0
Binary files /dev/null and b/doc/refcard/refcard-legal.pdf differ
diff --git a/doc/refcard/refcard-legal.ps b/doc/refcard/refcard-legal.ps
new file mode 100644
index 0000000..55a2649
--- /dev/null
+++ b/doc/refcard/refcard-legal.ps
@@ -0,0 +1,3054 @@
+%!PS-Adobe-2.0
+%%Creator: dvips(k) 5.96 Copyright 2005 Radical Eye Software
+%%Title: refcard-legal.dvi
+%%CreationDate: Thu Dec 10 12:05:33 2009
+%%Pages: 2
+%%PageOrder: Ascend
+%%Orientation: Landscape
+%%BoundingBox: 0 0 612 1008
+%%DocumentFonts: CMBX12 CMR6 CMBX10 CMTT8 CMR7 CMTI7 CMR10 CMSY10 CMMI10
+%%DocumentPaperSizes: Legal
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips -T 14in,8.5in -o refcard-legal.ps
+%+ refcard-legal.dvi
+%DVIPSParameters: dpi=600
+%DVIPSSource:  TeX output 2009.12.10:1205
+%%BeginProcSet: tex.pro 0 0
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S
+/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy
+setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask
+restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
+/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{A length product length le{A length product exch 0
+exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
+end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
+grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
+imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
+exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
+fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
+delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
+B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
+p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
+rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+%%BeginProcSet: texps.pro 0 0
+%!
+TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
+index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0
+ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{
+pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get
+div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type
+/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end
+definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
+sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
+mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
+exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
+forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
+end
+
+%%EndProcSet
+%%BeginFont: CMMI10
+%!PS-AdobeFont-1.1: CMMI10 1.100
+%%CreationDate: 1996 Jul 23 07:53:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 25 /pi put
+readonly def
+/FontBBox{-32 -250 1048 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321
+990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E
+6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB
+DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721
+59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823
+D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF
+8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808
+6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9
+1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE
+03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909
+95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1
+74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2
+3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8
+47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19
+AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8
+42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8
+40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837
+B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53
+9560176676ABB71BBD0EE56B4CC492C0652750227CEC6CB2CF13A3AF2C7762AC
+4A63E9A8A45F08316E4C871193F4DFD406CAA01FA8545A9CEB4726D979FE9BBE
+FD50A389F9DF9BEA83F2E73963D6A328A143DECE3F2E4FE2F917BF80A63A2D2F
+815370A53A4D17BE225E9BF4D896AFA151C86D7CAB01F11F02E9A5C3FFAB6402
+328643DF72A68FB4E4A346EE995F94789B2209E56F188F1CDBF8AF92A1695000
+C1A08CC04F5213CFE3943D9087133D2EB280A073DC8E6EFCF446DD92CD5F9E75
+A8D44140D0D46858673E7C1FC07EDB08D41785BB3A374E0941AC69A327F0AE8A
+FF6DCE28B303DDDDC9AB9D01F332ED731416B5E8B9AB03A8E2F4E8768B77AFAB
+19CD5697B5BA7755773DDFD7FAD543CBEB8E4DBD4CA7F5ADD10150521D73B132
+733E24E673CA65BBE49A3F81A5780E69379715F0D2F3A906EA756D3C6515CE2F
+8B2B40A986FF4D949137A2AE2D53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSY10
+%!PS-AdobeFont-1.1: CMSY10 1.0
+%%CreationDate: 1991 Aug 15 07:20:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSY10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.035 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSY10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 0 /minus put
+dup 2 /multiply put
+dup 102 /braceleft put
+dup 103 /braceright put
+dup 106 /bar put
+dup 112 /radical put
+readonly def
+/FontBBox{-29 -960 1116 775}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964
+7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4
+A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85
+E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A
+221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A
+27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF
+5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09
+0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730
+DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A
+71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09
+4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C
+515DB70A8D4F6146FE068DC1E5DE8BC57032092296D5371C275E56FB4903A60E
+73A22818DE22EB78EEE0E69EDE2E31BA367FE9AFFF8C7D74AB1E2400953F643B
+7BC604F821A4CCC56FC4E40E0B40B8CB82A045EFB4B9F681EDBD012AC35166EF
+62940137319D3082AF2B42F5E0138804C62FCFF2DDD0AAAB3E2A1249BBBAB593
+00577FAE2BC50E3A7B37BAF90BA56525DC498A971A487617DA028EDAC7F8BDF5
+225C6E2C63564D35ABBDBDFC523302D6D28A3A8E2D8332F6A1FAE2E71D2C6EE0
+64275E875009ABEB233E981A8C36996D0CAA8267981F04BF421C8C4A5162B736
+21DB026EECEDDDC9E1DC92761140410416A7F17A92DE302890C67472E4770E22
+3CFA4B800FA29D765039F9704DD0554F5F5AA479322F46E89A67A5B52709A2E3
+13B14C530AC58684DE01F555FA08D9E3BEC56A6198049AC4463BC0667DA3B092
+9072E0067FF74B36A85A10DEFFBDD3F6C55802E8FB6A84F1C61D42DE55CE8C3A
+5202B098AE5EBE989E3DD38C9D1E8D198E959C946F83EC667B2AD398BAE7C003
+B540D5474D351A90660618D4B185B05DDC3D72CDC22635283ACCD253C56380AC
+27C6EC7C7ECFE5DB1257F62F8B7C6C55A7E40C9C26C48F777C51C442FE0610D5
+65EE0FBC1E9537D51C4D25B22F48B58DF64A09C9FF2150903EC75F1DC0152668
+5CFDC5E9E38E04B453235752D62079FDC7BF0979E6C3327123DA1BCEE9A6CAF6
+1CAC0BCF4B0D02FB3518998CF007016FAA03005251E622D6E67ED2F19D80CE25
+AB274919736E3E2B685DD4C1F6C6B4F624E238AE536978159E184517C14A08D6
+0807D4C4E76E0CBD99A28E8E068D233BFB8204BD820AE1807C757DA13E580CAA
+AD459E754C9AED669CF46B7F11AC6E8B5B8F16AD7AFF0B5D9CDA82B040D8F40B
+78F8241E70A347EE98260BD50AAEB772629D9BEE93A9F3A57EC45756F73C1AAB
+B0F9E00572B6BAE2542BE8022F0D385F23475FDB0CB7ADF37495D3D8B6E01168
+C0B0CD75C2166255E4A2D7741B6DBBCF7760C25C2BE7791204E925D318260FD2
+589DD1EEE2D6CC3CD456D8341DD0B0A7C2729BEFBF0E8B3F218C2FAD9510AEAC
+C23F3AE8B643614195D60C1DC3AE19A477963F7E8F9FC36F9573F1941F33D557
+5698823F742DDA6482FBAEE4A512D59DB4902412A9D257C275B278D950CA9947
+C07C11B50055D309B874ECE21EE5F95FECD47C1216779BA81FB8307A064563F8
+499FF484DA648B91AB11BBE44A8D2E5A960295B90D9CD8672B0F628C3BE4BBD2
+1D1B9DE38289E4B9ABA59BC9741A81900E8A1B6706A0AEE3CC61F24E7056E18F
+B421A06FFA208FBA6F1D764B90C2B14D8294E2922154A8BC7DEF2BB73B3CD6FE
+988A4FE1D635D9F89F040D0753323D78D33735B5BA70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR10
+%!PS-AdobeFont-1.1: CMR10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:52
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 49 /one put
+dup 91 /bracketleft put
+dup 93 /bracketright put
+readonly def
+/FontBBox{-251 -250 1009 969}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C
+295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75
+409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C
+4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF
+2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E
+0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E
+B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008
+24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B
+43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF
+D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575
+5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC
+96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3
+7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC3C8578EF9A20A0E06E
+4F7ADDAF0E7D1E182D115BF1AD931977325AD391E72E2B13CC108E3726C11099
+E2000623188AAAC9F3E233EB253BDD8B0A4759A66A113E066238B0086AC1B634
+5ABFF90E4B5ED3FA69C22541981B2BFC9710AEF6B50A8BB53431C7B4D380D721
+639E005D6B4688EE16BFF48443E7C9E5FB5BC5883E271CB03428955D5B6A6C01
+F9D9F44C93F0C94D9D0728D2A6F5390B793E4205F4BBFADB26785DCF0EAE8467
+0F2CB7F2ECC80860473B0AF607E131ADC315664B74C8FBBB3169708EC9EF9977
+FB3172531CB7AFD5E6CE40A819129D46BA23A46C548A8713BE1A4125FE8E4E94
+FD2FB0777C4853D15397A4FF99571D812F3D1FAF4885974F234F0AF75B36ED35
+812979028DAD6F7EE30A55ECA354CD5179A9FDFE5A010AC0206E05E73CC3BFC7
+04839BCBF01DCA4946CE91A83735797021F57B4ABEF2324D8F4A4AF4BA86318F
+E6DB11B2908C051AB886FE7BC28BEF2ABB9955A321103A2E6C4B8078FFAED99F
+768CA23B44F429BFD9B2CFF6456CFBBA8E04E3BEC7921E691BBE0A98F0F7CF0D
+58E8CB7057C661E85BA2DF8AAA713BC6DA03449AB38339CD4E834C08154FF725
+9895FF5744A96D9A326780EF0F312F0005CFC261EB9080D943EF23E1849A224C
+F92C8F4AD38D66E0EFFE38E76A8FA3D4888FB7FB6FD5FE1797DCD0B4751710A6
+ACF7170C7BD29C1CCD634D290C36FE683AF227CF333D2AE30AEB5E96FD6BB838
+E3BF46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTI7
+%!PS-AdobeFont-1.1: CMTI7 1.0
+%%CreationDate: 1991 Aug 18 21:07:18
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTI7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMTI7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 41 /parenright put
+dup 45 /hyphen put
+dup 46 /period put
+dup 49 /one put
+dup 50 /two put
+dup 78 /N put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-27 -250 1268 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D77639DF1232A4D6233A9CAF69B151DFD33F
+C0962CCA6FACCEA6B71BEEF7C056FBD376F2F0D0BD6BE0A0A8259139B28B99C6
+25119B8C60FF7BA002476930DFDC2F6B1B5A80F1C0E544A22E3F0FB2FEAB64B6
+A509B61E1AB96121FBF7F2BC27CDE5B4961048FC2169C8DB745FCC7AF0EED507
+284038B15CE53E69AA22CA76C2A208F6AD8614CD500D479A5E0FD25E7BB14C7F
+C47C503E4CC38975CB0A8F7E109665FB69EBAE6EB68B2D6FA3C967D5BDE7830E
+9CE6F13DFAEBC852DF1D7D0CDD33DD4D5CD6D94DD8AE0D48AB638013CF75A25C
+04FDEA8775EC52A13AF40FA41F7354624D917EE620318C702237AF8C0E1FFA02
+127F862D4DFD0A56774235A881AFBB8F7F4BCB33811C581CFF38462F669B7F97
+1F97AC09373B8F9B7E653013AF8170613E8D7E17235A893BE296A0CD2096B71F
+16778388993EDF1B003EBCE23DD02949CBFAAAB5D9F6A08178BFB8ED1043FC1B
+0B90D9AFC27B19783740E8DDE0E5E01D116A8CB083C721FBB8EBF71018A9570E
+78590CD831116BC0FDA4229F79A581874FC3A1F108A4FCA80CE27FA54A2A7505
+5BDB3D52E2595512837732322FB5BBE459C0205EB38439E34A39544F0A1567C6
+F29FBB7CF931708C8F92786CCBCBB443D54462B3B4B7BD38E90D325EBC31BA05
+FAAB393C7EBDB9EC48E4ACC15A247D2348A62293A726FCA4250B4A407F64270F
+923EB516CB8A3B5D19876C8755EB291357E4E4CC5903D1A536A635E267F7A971
+B1C33AA7F58E1ADA931C450EA8367B18E20E683CCEEC1BC079E837DDAFFF0D16
+23C4AED0DC04DD9458A630FD498794823FFA55705315F0687E7592A5DFC8B8D6
+FE2F3C6550976415640267DD73C0C64FE63F1E81172FB979F7575C459CB0DD02
+1EAD6AE29D5383A7B0B7C197DED6D8E9CE621CBF1EEF641E699C8836D6A8160D
+E50FB6D6A5F356D504A49E7A92D88C540D03D406521D8464C7EAACC0111B6589
+40AF23202778F36F6E4632714401D95E5AE569FDEF2FF90A17998D9DFC5492C9
+A7138A59222043BC4E55E50425A74AEC11DE8597CE8165972895B767528615E4
+B52A855386B377D36CEA5E3F4714B0934C8980470714E85764745EF1C7462686
+AF55B39B82931298A3144154D9515B726CE0FAFC20B87925DF472BBD25F922A6
+6518EF30460ACE2BAFC71A1597F96812946C21DFF1CB430284804497292470EB
+6E0D2F22C2B168DDC63AC78600AFCCBE55AA8890C2357A692FB7DDEC32B57EFC
+7D15F814F2539FB3ECF75B062F3A3CF2B2BDC3D376B887BCA71D80F1564A9F24
+3AE133B7390A4C049241D8EEECDAF8E6873E30F19D1EBE7EB1744D0FD3820490
+F0A94738BA811B04952A2F1CE8D91F0A013A8FBA50DD6723758B0CB8419E4ED9
+A75256DD5A11250795C845F9994D6ABAB0D52FE6302E9EA85F45E7F6A85F14C8
+98D2E2B9973885487B30D60021D9DA65AC0EEC39228ADC8E171F0492BF51DD5A
+ED7BB96B11D644279EB5FF774A0F901BB5858308D2D7B5848430ACB2D67B7B9A
+BD2B984328C2ABBDB9CF087700994038C4B3A96C7511F3B92BD503C264858541
+199554B6A98B7386C5AC7EFE3909C50DE3B85755907E77730F7024DA01F4BDFE
+1E430FE15A78C1E2A3671770DA46CC3FE8DC6D1B99B31D3E7D4AC7581053D679
+C22F515E02D17DEEF99FCFEBDE55B05C81BE418D43B8C8F20F319E2B29C46DF0
+93AF8C5DE9D101326C0828A4AF567B952B181F97606371C079AD03196CDB0733
+5EF0A29DE66CA65261922AE01B0B3BB712352D6D01DABA931080A4FB0B148407
+792A0731B34470FF72A8FB558ED70ECB5F9DD7F1D3285F0BCD007E015BD937E6
+275F61ABA68D1E8443E97783E3F60273C025F65DC5EC46A85C8893776AB3C947
+87F861D5FCAD70ADC281CC64909F0BC268A317E3443AEEEAECB006A9D484B618
+89EF2E40BD426C79A76BC74C584AEA5B44D8290AD9FEF1893EE48A3098FF59FD
+C51079E0B3B116CB6A57B05A887A7CF646B9849EF6FE79F75D086FF36176D2E9
+6CC08A1EB37F046DDB85D2F132F2F1633E4FFCABBCAC644B19783D5943C691A7
+56DBB18967093094275FD051783A57DB27221B595C6371805AD612BE5D46D830
+BA6A0CB6011E60F63B743F845C44F32BF750D7CA28E32BA8C1693E3B647F9312
+36FAB072D5168E87C35E668BCF519F4B1F3606C5A86CE5EF801F24AD72A17579
+1603087DE7254C8E07B6E979205C691E482D9D3EF4AD1216646C696544F6D556
+8CFA87A28B49D51697E94BEFBDB9F680C23D038CBC903386B249CB5AC33DDD20
+502FFCA63C49C0101186CEEEE512B2ED0B7F2AF213FDF8FEBAF2F4365A07EC61
+C251FA30ED70FBF08BC5FB3F4629E41DD9565D44FFCA00FB9780958273A32C6F
+652D2E6CE3E6F7CA3F70E872F5217066FAC0839F49980CF750FE1317E2D856D4
+59FE32AA35D41C6C091BB328319F8C89EB0C1210794F891657BD755382923BD4
+F76A88EEA14D48B0061E5481B0896E872F4C2895C30FFBFD7D9D5467EBF41D6E
+43D14E425430AA50259A1F83E8243566E22AED459FF4A76E882D1B3C9DEF1DAD
+42BE223E53F8C09D49EA840384DB9E16EF66C448386B061E806279219E39CD61
+2808A7DFE105193E6CE9C0E9B1174D7B0ADB2B10F53F9BFF55C377214E7B0234
+EC2FB9796B03164B3DD5CDC16E63D5A9A49FD0A5BBA69CC31499106B674D4E31
+19748F7715F541331B3A723D139EFCD5173E016C7B4030979F15CCCF511FB088
+D86088A8766E455C54DB2DEB3AC33B458DC87146013264295F00F1E69415160B
+FCA55B3BA7FB8F9D98EC485A2C62756973F0D609CC8F91B760B2D8DC64794499
+8CC106E2A12573109BEC55C66053343016D32A90A88301114A3B862A9B79D754
+6E7CF60FD398B22245B81CC57FBFF41AC3F14DB29502549E0FF905D057FB1D01
+EA0191B6D7ADFD2DCE2D1A482F95BBDE8ADC2E383DA77B79628D87007A757F4D
+F64902A85D9E1ED9D5269CC3779BA04569E50281E4F0599693C2A1ECC627CBBC
+7931D3BC7785A330C210C7A9EDD9FCAA1655375F893308914CAAB151E886D8E5
+E6766E69325AD0A19217D50B2772B0301A8D93D89CA4B89DDC3288998278F5BC
+80EB605B215E949A81F0269C8E4E2A0ED8A4302DC7052F057F9542E0455558F8
+9FCA1B350CDBFB804DCCDAEFFCEE794D1114C58B2A2200F5F59466ECD8126DEB
+BE45D6B85D49F79AA4D461A3D3D9B70BBC0EDAD5B3190551B20B1AFCFCD5FF65
+B0EA0D44FA158BE546E0ECAD9916C8C4F017DC916A4F671A9977E778CF7570A3
+6446DCF3285378491E34884913A5518DAB2ED41C6B7614B69F72F472E41F4F6B
+0CE11E0AA76AAF72E28C8FED1E4625578147CB0106B770F1CFD01E12398B2D78
+E24835489B857F26DB3CB02AB1BAD787DCBC595CBFDBD9CADA1DEFF61327ED13
+9E8E9E815CF5490A415BA72FF81D8047E3FEFAF123002EA87EFE93016C5DF2FD
+8153382E38E03815EDB41AAFA788A4BCD399AD81702EF877A03AA61E71CE8B6D
+B8559661C56DF18A27102F9A855C354EE7AEBAE3A7739D33F3ACD93B406F2EF1
+F3DA8E031377C6B609855E081078A1BCA8E406A1E76EDE9FDD4CD8D29CEA4A08
+2B0A5BD7230873D6C58BC551B9DB4B2AC5D3A68988505125A4DD34922773C561
+79640CF8E406A143F2A9CA1AD1A130797619D35B8238E13013AF8010C62B43DB
+09F4C88B65C86A18956F317CC76182DB16C30043BC87C05D19FF5CEFC4A98DCB
+3A541BC97C80ACC39D9F48467DAE59D28028A6B75078D7832B369A333C15D3AB
+7CB3E3F016F841B5AC5A4A9AEBA9A941C822EC67EABB58215E0BFD286EDFB751
+981EB82ED9FD95ECC14ABF0B3BC822C6C7CB4141107611FEA631E9F96292EF73
+079D417C0A0BC9CBBA6B761BD5A76C43CCB63700A098D993C47C4A5C0299027C
+C271AA718EDB4682F605F69B4428068D0DC5DDD7B1FE1CC868F1A9F2AAA49842
+DF20E7572CD96216FEC97273A40DDF7BBD489414CBEE3D23A57F3A77E10043D4
+51C02468564AC3E80FA517A893078766D05998AF7B78F8B0B47BE6C7316F71E5
+D40D85FAE2781E63B6D770B5FA45FF06A1659EE6B65CDB025B4E3CA8623515E3
+0BF1AE5E748ABA5E52A94C8403A8732CBD291FAFCF59CA90CF8D0D21DECA1493
+34CA42AB3F537A442CAA114639E5CC96E5D045F133D020374C6B0A5E10D4D8C6
+224060D1686A9DB77D252D57D66248C7880073E5442D2522FFCCD556557297D7
+B92B8E656A191DC388E985ABCBBA8635B6389B584D62E247AF4C81AC7581FB84
+7F4B443DAFCCD261A3AB85A9A9F42781EADEA6A68863805810216787BE0BA291
+A44705A98930B55E5B5265F7B56089BFD576E714F1C1281F05D4D35E4BDE4470
+BEB39E057E431647DCBB6D7FD26F60FFB68051BF2A0524AC94F3F6190BC531F0
+4C4F2AA339D619988E00ECC1BAE259B7324404803018EAAB32E5206831615748
+2652957CD044512F185B9A14749E4751992C2F9CF183647DA6CD21B0F03D2BE4
+225E1C28298B5D8DE6930C09C239E20741EFB954694A649AC6BC0880186B5463
+FE5AAF0A69E0AE1AAA0F5502CE8F2FEF00B36EDF545236B3506FB37EEA03B3C6
+8B9D56729452E176FDCB12926E31A062AA37CF2C455822351C285ABFE6737F82
+48BEC7E325A2DF054C528F481D9B83FC788A7243ABDA5D9BCC1D8851EE949BD0
+114D5C3E51BCC4E19ADCC188E556480DDC2663AE524A2BDD7744916D62C531D7
+0E90659E0640A43BCCBCDB702D0C5AE585538EA37BB4089EDAB4B44AC3393A6D
+87EEC78AF5EC54CAE31D188293524284D6412DC7DBEF26AC4E129BAF8DA6702F
+A0C216F91AA3874D467542055994A9C24E8E1272D2EF266C211CA70C98E0C7D3
+B537CB87E9BB9C46B78F20CEDE5BFDCAB3902093991DEA96B0D7CC41D0117843
+957FEBF578A8B1A57C3D295CC145B72D54F46A636E80B5163B91BA61C8279F0D
+ED61A1ADCB0AA32EC9A30BCE1717AE2BA2138CE60A53313DFEFBDF95D770C4C0
+1ED286FC3196F35C47569951479DD788BD4AC0A4353DFE984A61069B201B5E8B
+889B8BCBAE39CB2F964B51CD85CA4EE98C78A27034D2DCD951BF17C8877269B1
+660146B9215655FD5EB08823E4528047B2950A87A232BAFDBA4BFC7E6CA25305
+E839B9E7F049F0443DFA6D487D12045F6022F93D98C7C6FF1DA174F96D2CF0C3
+EF23A0E03FA2E95E1C69199E50971E014EAC678F7EE677966D6B76855FF4CF0F
+4FCEB9950077FEAD21ACDB139E0D9773DC84CEEFE07AF3E8EB2A7F5722C4B226
+102B9CD4AB721282C5EAE85940714CAF3DB41EABD703143E9D3D2205A75CB709
+F316D7AE5CB88AA8F57B08CB5AD27849D2E937515473EFAB72A54EAF7F066E47
+C63B1F6246A4B4EF0FB8B08CBDC821DAB987E4B82B1097D318096A3087B9C1A0
+AC68F596C661F3CB6DC6C9A56E8DC2028288B04A31BD248F5DFE952848FCB0A4
+B1CDCB5A2D2E2867B297716C326102A0578E899E3B5E7D78D1F4D4DC4592702E
+509F6CE853B9FBC3FAB683DBAC4AE02BFB30F4B976CA4A2E002CB19216303B9B
+3181DE9877AA761D2BB3B0B9AC907B0564F44409250EB4A6ECA7922C8E8DB001
+CFF8ACFAA49AE65324226B8B8FC3772F657D8F6F3CA6E898B344C8BCEAA7B1BF
+1128FBE2BD58BA62BC4144DA0D9DCD707FF865F218C5C559A1C254BF0750BDA8
+AFD330603322BAF3A30A1F0B019A7585FC1E12E56CD097558845A130F4B7ABB3
+A5C496CB064AEA05A4EC0126A67FB5093683ADA2C25BE9874350E677514D9511
+37873AF6F81AA3011587AD4E5419C2C0E265BC5A36AA7FA51B3DAB525CA8A1D9
+7AC624E46ED25C3371C927D75893DD8FC9B5522D80A7258EBB05745845FBCF7B
+6E8077C118AD5E84C174F292775D088116791F02B3979320F296602FDD22CA47
+E6BB58E45FB085FCF290639B2F763CE15481D9720D758E5685892D3FB78D9B12
+9CEE9BD41D9437C3B85C8461722DEBBCCB8BF2417DBAE644CA7F9C6519A5E39A
+5A422E3DC005A0AB7D275B470733E1318BE936AF1FEAACD729CF5AD3892428EC
+5268A2439BB2B89EE11FBD436C47AE0614EF986F0EAD848545A377D56594E00A
+D6228BF5B440DA5F28A0B3F805295DB4A9ED928BAB290576C5610FEBD485DB85
+DC3B5091BEF7B1A70282F8BFFABE273FC53003026EA5D1E9CE955F657BFF5462
+A0F36BC0AEC7F0DD42AF9A233078F660D498B668319E3CC65F24271B87E0FB26
+01014FDCAB87D5F65D72AF5B00AFE4D8BA8B5D8D4A1FBFE34E430F54F0B5D214
+0C86404400C5CF33CECE5FEC03BECE952955078C740E639843E724802170212A
+2C65B65B18B04D7008034609E8C4F9119DE06DF13B1CA55DE4CB964229954680
+D36FCF1D0F47B15ACE44758B8710C69AC9F9A54486F8A18C4E3CE153D0265BBD
+0CD887BAE6F6375FF20A6B72BB7A84FC5E2B34F94706297E1019D84821BC4A8D
+5BCE43AFB29E1F551D962BF37F73BA8791C3C0DF37537E3BBB84FCBD1480C33B
+5BF6AFC860EE6203B7589F38AC5738EDEA5F6D1AF261DC8E973AFBBF837030BA
+441C94D1BBBAAA7FAB6A9030ACA19B91CA53268A1FE80ED25C309D71B89313FB
+27D49A0BFEB9C5DEDBB6F99C730C0540C8939220B54BA63C7FCC8F7CC709B3BF
+6098E1776A4EBA3717CC26404B669DFF41053711D8F2EC5D98954DFCA45C497B
+36A3470524E96417ACFEB62C9CECB62AFCD5F44D206C7680D12D32FCC4563D9F
+F492C4436CF049F989353770533050853ACE9EED7C856127F01144A970189E93
+A92E88619A426CC551AD57FD54BF0DB2DF9059C2C669DB4FE640B828361F2CC8
+4B4BAD8936FBE06CB979816A2881E6B9CF458A3C8504A5700BFDB8B7175E1B89
+8DB4DEA351077857E9D8A06D077F7760A9161D4102E3FB16AC6111C5C0558022
+E4E89561337E5B15723F6C97057435E8D354A113D163189A93D028424A99FD39
+41BC461D5EF7F75E2897461CFCA1D77B6051F5BA4E703E67C5B904C7C8D31040
+D8A732F9B0A2F3DD2EE6D7B167BCE925A5632CB635DAD838C12BA8D44B9C1BA2
+C29F80825CADC5E8A15D7A8E64DECFA4A18DCC9BC96ABFC39963158C14FD3EC8
+4ED979310E798AF6CDFD8504D804CB0DF43F95F7271F7B366ED0B8CCB4F0505C
+73FA14CF73C391A0466CE81F2485B993108D32EA73A4D26E2FD995A135E67FAF
+CC3EDE5A70E90F9FB1667631FC4B351786D96A3CE329D0781A66A727B3F2A33C
+0B663B8756A1C739D07B39AC858519B23A3D81500A6EF130AE6A45A81C843123
+2414D06830A2F5AD5936A8E5FBBE12CCB59563672FC69E2BC5EA5A06EABC3985
+359F2683ADC07EE164B819CB6DA2FAD378C9F60CD49D6D21A00F2C2471A18502
+20B8BA7E9CD9500F592028F90095BA0D213FA19FA70C0909958CCF1DE4287878
+CB93C4101DAB123E8F3F7152BC82E43C1629326655422936B32EB4632D7DFD0A
+E0D9D296BBE4ED231BBD7DEFF79E0AAF8B2F867EECF4B9CD3BDF6AE3F4D3DC95
+BD85F66B9DBBC8934B4756CA11C11C08BD0FF8BBF90C5B70294D011A9E75C15F
+6FD09150AFEE1588A557CE31F1758D941C420C300CF326E83E1FA0587A4AB80E
+85F195DE49830B25617B90A93F1256C40CEB3852851D86D803EEC19C665F17E6
+D56040936810740574961A4FB48BAC5B03545262253284AA23BD82DB7EAE8F41
+33B6DC8796C6019518DC7E27A72EAECA6CFB74450F7A4A575F00A50B256971AA
+91DFAAC0A12CB9550E390A93CAE821020D68513EB89E151F77E384DFA28E60D4
+1CF8203F213AA89BC1128C8D3D235294BA2D7B66D552364FE03156C0AA648571
+4100624BFA090FA81BBB524D98C6173BF900E8E74BB58FADB072B4A60B292A68
+28F686DDE1CC02468D87C22E6C4EF00EABDF545A9369A338394581FDCEFC5708
+3FE330D130D8F224A4293C0229388044328913F4C141C83CE0E339095A1404CC
+4DAE96487EFE02B69D8B46FA2FFCA2281BF95F494797E989619A2F54B5E53B36
+C829DC61E3A565ACF6F3647BC21716758075378EC994B9780AD361E7A3BFC483
+15D381DF90052625D61248B724D41B32714B413E6C6237682E565B45F622CBB6
+08506AED024011268DF8D9349773F5C66A70BDB4AF2FE99711710CB316053FF8
+67F2AD9C36B72411712B2C63D185827981503593B1029770911A78B78D401E7A
+0D0986D84213FD610F7DEBB5981A570F898852128AB3B9C3C572C14BE236AB05
+D8ED683F455D79C8B95C43A06A4F7CEDEDC689DF89D6B2D803A4FF3F5C9430DD
+37123FB3B0228A35C28DE23BDC12F79EF31C37E9EC3A288D7C2CC94B699519EE
+7D25B8749C8C934E6A04F8720A2BA290864D4D8E822A85A510D1ABD61A604C43
+A6E4E8A57A473B60BB6E173969AB1E06EAC9F7D349551FD24A4BAE5F87C6828B
+D2A5048D9D91B1DD552E88C6B3FE1FBE774AD19A03F4F51782BBAE33D8CA1D99
+99DBCDB5DFB6C219EA8D246861DDEA5F47EDA4E115130DBD9E5B02BF734F28A8
+5AEE854B99016061E632EBF500E225780B8CD7848B1AADFBC05DE4D8F67B1B4B
+24C700214AE3F1827455D7C848FAEE5DE3311873E40005776AA50E14952814E3
+575E51D3534A5E1F54B4D3C3A64134BA6ACE4F26F46B0C9073D5C53A073DD617
+7D76E4CFC648496F229C731CB5FCAFBBC5B81D0E3CC0CEF7CB0866607FBAADE9
+18A358D2F3E827BE637550E92767E874227109D380557D8DC5458785958AEB6C
+34E904B1488297A4F33E2B6E07F091A2CF8FD62BB36957103DE3C72EE0EB27EE
+0B1224C4570D35C3AF14E504B48C1E4BF3B321C3EE623288C82CBE96ABA181B7
+F7C8B9D69B1B1B97AF3B086C82E42343320F7065C210929C05C741F05CCBEC96
+D14B3498139C7BBA9481C05E1CA5E46AB06C2CD418EDCCAE3278E515E905CAD9
+B09D88AC4587943C510ADCC857F59A5E66C80E4D621006FD4735FC54E8B73660
+40CCE67FC6F6CC4FDD9931A26A339755567AA2D6FBD4316A8F16F2EFF51D4C8F
+B3F619E6C7814AFA109261F0B2BAAFF92D0BC25980FAA7F7C5CB566520725DB3
+957B73267A9C4E0610E5327E47C39C74AA285BEAB2E8230806184C60E5509BA6
+1A185BD6D8DA6DEE48C87E0B782A11071D08A1701DE89F69BC70ED9EF335FBAC
+72F8DABA2A378BB458B73603EC8C3B491EB551BF2ADB613E43A0E6DBBE806FBF
+2EABF00B8BE6400F5F117CA4F0EEB6B09F03F36245EDEED0AA78FEECD4D23362
+869398D52329AD0239EE539835BDEAE15B64FCF3BA2471B16AB99C74DED0901A
+A37AC51DEBDD9AC63609C5083BED26DB9C4EFA601DE7B67FD7AA74A72D854F17
+1F2C5AC5936DFA9D56F6A131C47CBEFAD0383463358E66207112F4D9FE1E0D2F
+C4C8BD1212C9DBF9A980E6E9CBB1A8271F73DD47C58C7978C134FF6BB57B6E77
+9B6F14F2D0B74587FE1E6A4607F19CF469C0D6417A406981DFD88076F79D4BDA
+2767ADCDD8151CAB176D9905672B255951395A3F64AC1B521DF2A4F70609ADA3
+E1484B04243BE4F05E5A53252D3B0548600F31EDA74B7D1820F6DEE9F8D1B234
+4529583AD95FBC74C8A019D64EF50C7F170D5075AD5D0BE8C41571C5C272D870
+CB936F418ECB04F48590D56CFAAD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR7
+%!PS-AdobeFont-1.1: CMR7 1.0
+%%CreationDate: 1991 Aug 20 16:39:21
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 11 /ff put
+dup 12 /fi put
+dup 13 /fl put
+dup 14 /ffi put
+dup 34 /quotedblright put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 57 /nine put
+dup 58 /colon put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 87 /W put
+dup 92 /quotedblleft put
+dup 96 /quoteleft put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-27 -250 1122 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF5B8CABB9FFC6CC3F1E9AE32F234EB60FE7D
+E34995B1ACFF52428EA20C8ED4FD73E3935CEBD40E0EAD70C0887A451E1B1AC8
+47AEDE4191CCDB8B61345FD070FD30C4F375D8418DDD454729A251B3F61DAE7C
+8882384282FDD6102AE8EEFEDE6447576AFA181F27A48216A9CAD730561469E4
+78B286F22328F2AE84EF183DE4119C402771A249AAC1FA5435690A28D1B47486
+1060C8000D3FE1BF45133CF847A24B4F8464A63CEA01EC84AA22FD005E74847E
+01426B6890951A7DD1F50A5F3285E1F958F11FC7F00EE26FEE7C63998EA1328B
+C9841C57C80946D2C2FC81346249A664ECFB08A2CE075036CEA7359FCA1E90C0
+F686C3BB27EEFA45D548F7BD074CE60E626A4F83C69FE93A5324133A78362F30
+8E8DCC80DD0C49E137CDC9AC08BAE39282E26A7A4D8C159B95F227BDA2A281AF
+A9DAEBF31F504380B20812A211CF9FEB112EC29A3FB3BD3E81809FC6293487A7
+455EB3B879D2B4BD46942BB1243896264722CB59146C3F65BD59B96A74B12BB2
+9A1354AF174932210C6E19FE584B1B14C00E746089CBB17E68845D7B3EA05105
+EEE461E3697FCF835CBE6D46C75523478E766832751CF6D96EC338BDAD57D53B
+52F5340FAC9FE0456AD13101824234B262AC0CABA43B62EBDA39795BAE6CFE97
+563A50AAE1F195888739F2676086A9811E5C9A4A7E0BF34E6F4C9A04BEEA891E
+4D22B39729EE4F0ECBF3CF3C429B3BB657DF66811D3A108A73513A22D252AEBA
+66664B33422FED0E63D93F9F8E24320719C09F50626EABAAE93F5649E1981AEC
+E8F19F6105EA978C51CBF54E94F3DBC93516313F00B281D1B8C8E4C1DB33363E
+B81B61D7224245842A6B98939F0ACF3ED081BFE7A813215D36CD6ABC3EBD6B99
+A5FAC5AA7A0DB126B0A1FB14B58525546D4D8BB6E95F803D6E48BADA30DAED03
+942D55691A3E5FC195F3AD4297A1A5E9C2F61F9F123AFC6CCA78BC17BF2F0F21
+9F07458D74BB65C10DA76B2D8A7595FE457E74DCF33EF5960E547CB301D7448F
+481932BDD0B999648074C1D48E8CFE4C863E4926B3B9C5F48512E59F3CE5F6E0
+2BE5EEB299259FDC25851EEC203FE0C8146DA5DE9D9D0A69E629994A008C50B0
+794B86C6B29CF688BD915BACA1C895EC3D10C25D1652405D5AE963C68F5BF164
+14CAF662FA3B468A3C7F80DACE40DAC79EA6CF24666B8096FAFE5C6FEFF97159
+4235543AA8D28481D10FFD41D36E4E69662380B606DA8584B808E8684B0DD1E0
+17D96E3EC23C2918A4320D14256945714F40886807D0E95E62D274E0A9338A70
+C44B1B3E4E4672C8753146873301E4C13BF3FECF350202B9831D556C9E47B873
+029EB02FBA04C39F87CF7845E5BCD095646A17D799FF1E9F057C54F6FF2F58A2
+3E708F8629F3E4B656C4C89F697C39DCCE00DC7A7F0DCDCD2846E1F1F1C11BE9
+12E73D274A8C2AB5C3D192F6A4301D4D8DABC4BF4BB2DF9EDD7DBEEF30C32F79
+EB865039C47B903CA6EF162FC7F6B665C4BBBB07405FFA2E9B7E658971BB98B5
+1038378D0CEE25EA4A05C351F9D26D8C51E7F95CF547E7A1EEFF7AB3BC7F9999
+A8DA8393FB2F713F292B9ECC594C06C2B7788A9FB8FDD30437264371EBB89508
+4BABE312946B6F0E71538E8DB3A356DEA9198B47BBB65065ECA7F0D9A33DDD5D
+AE0F360DF4B23B9BAE61528492077ED46764056D0352DA06DC92489CBEDA6979
+67B07D598123218CDB5180E93894C60717BBC0A2D59B6DA88A18B475755E8601
+FF2C76450883E8B87AFCB6129CE78FDDF1B0051901376FBBE836853D65DF35E5
+51D83CCD4F06E5FD94832BFBBFE809E2F3EEB26EAFF1F4B343E28E299C4BE030
+209704F1EE5182036468365545C202F2E8065701E57AD7A15572F2FE12AE81C3
+6AB77AF07B162F1BF8FAF8AFC3F8AC9DCE6FE95E792AEDFCDB13C49B9A545E1F
+D62057389422AB6C77F00E96DE72799FD34E58AD8643D45017A61C42A932A7A2
+46D34BB68D821E1F4DBFE9DAB50771CAA864D2A8C2FA3C173E2BE11F2C9D9E73
+04E47B430318F1AE8A7E495112A9654046EC10A913BB60FF45F6FA636A640F62
+3EAC2279C21A93EF15B2B36440A50FAF73580CAED243D6013F0C852821B33542
+53432C41CBA08BFBD219A72D68FBA5D41E5A0C779E071D6C5954A62C712D6757
+2AE3F815173D0B9D6D9F5EA17DCDA24F98A93F4DF9367C2A13555B27034AD29D
+92E58C118DD27564B37DDA5E1BBE609B09DD3008DB15E46A161C5867AA473A26
+C52DAC92D51E34E2A797844825E6F6C24BABFB9B80C4282D0AD2746397E8DE0A
+1E030B636BD1B00AFC3BF9DD59DC7D0D96DF3A9BE133CD7B8CF640D1381BAC97
+DFBE3B2C5CEFB66E4BC51D85B316B7BD2CC6CE96CF4C128E181BBBB849903003
+57AD671BA64DC53F46F4085BA3980750EA149C31BA92B27DA0839A667F1F5C7A
+9BCA01692411CDA70C5DB370B9D6767B36F8A52A2078F7549AC24AF28CA40A93
+304C5D2A71CEDB760F6089FDF09B3315ECDDC73F0F143A2D2C4DA2460D709D82
+18AACB213135A3648EF604BB5CA3BD0EC18FD7A0A5180376E3E2BBBD83863469
+3CD7348B18A29750D93E5BDF2EE6A94FD2BDED974CD326BB67042FB361C0D2AB
+77E57516AB701BA70EE678F265B3933C9BB41D979212B31CC3DC8F12FB6FE09E
+8B35D60F2DDD3CA0CB837FA0A90C2ADFDB140ACCE3026EC68EA90BD30B9C0290
+5AD6A59CB0FD2C8C8DBE9770414560CE966FFB413D47970C3464F2DEB1CDF16D
+F90790447C22C7A1DAE78C14C780296D4CD3F8E3C0787678A88AA23E525C2738
+A6FA50F12CBDDB02C3F49A62D73A552E21D069EAB44DED93B41DE6BEE9E840B0
+32F4C9BB72EDF1283A88152DE0654F9C05FF424064A311BEB9F13692CD5042F6
+87612F5138AA158D73BFDC6EA23B14EF748BF3A039E263C34F0CF6682A191735
+83AF4EF1BF7B441EDA836498F6728E25523C42E2BC3F309D148EF61D6FA47660
+CD26C61F71087B189DF39F5A72DC386E505FA0CBF07F2E9B4E149311FFF7B80D
+10A7223D4160214A41580EEE261D671CAD6011415C87716FB3AACBDB771888C7
+E278A86B515939DE1F1831D00C7048B627123DD552F654C493A69C211B642E18
+1FB9BAA905ECEE762DBFD7994B8FFA412B07D1F8028CEEC7ECBE836F39732D64
+FBF90E46AAB1CE56C916F86A823DED0730FBE6FB122447BFC60E0534EA8C99B9
+60CB50A4FF0F6BF2D94AD6BF517EAFA586269A90B94A4A178AD4994BB4B8E52B
+4CF8B68B26B5CD10493C814AF0656F9B181101099756BA7B7C8B9DFA2AF609F8
+EA960710CD16B3F9CF3E5FDC452EC08237E794B82C1C85F1B6B12A709771DD9D
+A77C4BBC94D31ECF4760666BBD6000CC8C49CF1D1ED3F3DE3505BAA0F77E70E4
+C6CF7A2DBA73C254BA90B2EE7AF45BFC65E8520309762FF07B87C0C81E0C4F25
+30FEDA98C85EF785B7574EB961C590B1CF9B40E36B87B836201EFED54256AEED
+0C4B10E2247A42FDC870638FEBF20314935E65AD73AC798501C3AAA891F9EAD9
+6783D0BE48C6CB3EE89F3538E15162490FA9C4BDE0EDDD1D2EC63B8EFB093840
+3027C5C8964B10636C2773B859EB8B2D28ED589BD57F3AD6D9AE3A0ADADA0311
+776440781D9F5739F123301646C5156DFEEF8786930C7ED88816DCB9B67B828F
+730536F7DA34EFB2F2AF77481ED68542B0DDD96894A6AF33E282FF09B61C85FF
+5206B358F695D572FF48D005DF54D65A602FD6BE7B6F15BB9AB59003717CCE44
+D4DF50D0BB66CD926E6DAED26B90F562B287B7CF46DD44CAD7BE29E6D84907FC
+5DC8769F4C17611CE0177712AF12086A849440EC71E81778BF572B19352F6955
+A7C3FF5813E88E09FDA5742D2687FF5A52CE741B6A674739A5D30A77118648D2
+BC4766E87B8D166671C5518845FDFBCA2E738CF078CAFF8240829EAE172444B2
+BEAC2C899694029BCDE8F0E7BCE6A049481B41226336D0EDB19A68B597F379B0
+7D1BC9CE42DC548A768F0C4DA0D0C3A8C4630CA9195328B33936AB78691818A4
+4A92380A0EAF5974CB52A1284806A1D13877BB347367BD3BC68AA511CA86E6DB
+84DD4157BE5CF68D7D0FE1F9ADC8F8988EEFA57E74344CD458EE45DD6DD13B47
+FE8E8F2F34CB5E734675B49DF36B6C14CCFD67CDDEFF80AA921DBF1E09638F06
+DBE8194F5125DE73C9F8EDD9E2CE7DBBDC1B572E42F542C114A3500782E8ED33
+3020E314DC7A8BC5AC60FADE9E4BD6A9C1978A4CE41BFBA81271726009FADCD7
+CA4C17F9FBA7D0F64F781E5B7DEF535196371A9A37C9D2D6B22B4C3627199DCD
+E2B979674FBA6230FE8081FE848B5E53F6CA26B494BA8E2374EB31180E5F77A5
+9DEE3C52F0F2D2AEA3BB7190BFAAFDAD38F10CBFCA8843D3FBC05B55E81A0EDA
+886A9D294BB5A6E76DE646CB3BABA1EDF63ED953BD6BC1BD79B2D83FD9D7125A
+095EBCD713E88EB3FCCA6941F05AB1C0C92A488C6A41F4598F57BFB6BBCCFA60
+44602ED83AF694CA988298BD482B3FE8230BE5AF6DFC45D8B242B500A0CDCA16
+82E028FF52F8B004D2A5B799C70C3E6A8784521600A855B909961DA8FA1DC7B9
+89064996C0C2C2FE12B69B43ABB534FFB57BDCFF511B28F1398EA1B357D92A26
+F0B76BFC0E802D4E33E80A2E7741E0B80488842F4905FD04C9894F896DC7BB0C
+D10AC6A99FF3AE582D354362A4CBBBA261F807218B4418EA8C632E8A4276A0C6
+A04E2D35D91A1C31C7435C5DF08AB130C75F1DC0042D5FA182A54310163F4B9F
+719A47196400D39F7BAC83DB34B0128869EBC17B0FE0B881C94C42187692341B
+340A6BEF7186DCA1BB1F085D6E4FE2CF2043E05F105B49CECFBD8278C2E418DE
+FCDD23A1F50D47A1150288FAF90B88C5FC28CEE8CDF9F65F4D3AB698F033ED0F
+66F83E114450384F5EEE60077981DFFA7C9D03FA719A1AB2C4FB2A1947478B5D
+0F5D7A3C110C80C97E9C0A37937E3F848AFF0EEEF00D7625A8DAC0EF0B70CAB8
+E596EA5F5CB3CFB5648A8E990CAEFDA7AF7D029AAB65298B575A94DE25975C84
+712AED72A1125645DF943B5EA4249C0E3FB551B3892BBC55AFB5C4C7B641B846
+3D850409408C5C3FBE32EEB7F97F93A47D481188C10533B0EF697C89A3295C74
+82D40F460A6FD165310EDC482900ECCDED9140EB07F6B6C2A3EEC6E7927625B2
+E47DD2365D5B238C28321554C2A19B1EF33F3C779ED59CA4CE97FF370B2E77F6
+1A956A6C49F610EB88ABD3D13833ED6A65B867ECA5BBD34202258978219B8A09
+55EA0C4862FF8DF1A4AE8C7DD13A8FAEC2F9B3721B1770B8F020A0D8B539F436
+20883821C321C9E1CC83428D3643D77CAC04DFC56D4A729C22E2B896C9F2AED8
+2864937E141EF28450C82CA73AE40631071C68B5850B90393E68C8F7A2FEC352
+74F6B3E5219DC79C8CA9A5C3035C215139B9A2EBFE72F99193611498C814F21C
+ADDCF87497A016C760925550732CC1E7D61190AFE35B92A44992166B4B2300E5
+971E097E58F9E110016C712AC2BB4C8781B1811F6A1F4E322F9D739834E80633
+6AA69AF19875F790F43752CB7C10D250E651A4F5B6FAA72218B103031B6EDA33
+74F6BB36E32AB5EE0CBACA7F896C646D4CF5AEEE149672865E132C0052290910
+149CEA8473DC1BEF71D1B5D04EBC3583027D2A19E0182AE942FDEEAC29BD6DF5
+0972AECF408EC62810651175232EA3E9DBAD731752137E2CFF8AF05D28EE824C
+5E7E6C18CA698D05759FB5282EF9494AF8D213813FCD36D65A395FCA352A0B12
+E45F86DD09F2296338BAF56D7057B331A61E79B2D16DB60FB8F8E8391F375BB5
+5B9CC5060346BEFC02EE9E34A4AFF948FC49AA42B1187D567AEE5B3593136585
+585602F85BBD2219641BF514E86A7E175D543E8B120BCF821883D97AAD39A368
+0EF627DFB67C301C8F3ADB2AF71B3DF8E0503BA85048FBEEBF48C846B7B02489
+055ABA2E3244441CEF3D40B01DD06CE2471EDC081D628CE4856D7B39ECE70604
+B8936E8998CB4EC3F09250DD35B405A84D13F7C852E6BA8160DABC4BF94CB527
+D6254A4A204B0CF35961D19634BBED724A7434AE3AF4960EB4F3AF0174A91EF1
+E383AD336E1CE585B2E42C76F9829EEC08E7D095658B23AB576756B6FF5D70FD
+4B611A735E64EB2B428E46921966FE804901540E5D21680881FA316266239068
+91C23DA5DEC146B63E5B660BCBEA353E7BA49A15F661F2CB7AC95A11823B565B
+474242BA9C41297E2C85B7A0DFFB501C50271826F2979814314B104E1E9B79FA
+6FBD38EA9208EE8873D554C9E80B8B2E25418A3A84849AB29453E28F659A0523
+F1EBA1488B58E3871C73DF7713ABA56462E307F97A9B2EF58854FD3CA3AB03DE
+0E9BD2718E22139549A43EDE8817FC2942A50B0B1973633C3A24ACC4B5E0E7B0
+7F64B21C7A326E9C11BDAC4AC703866A6B77CE1CEAE582F0DED24D635C9FE5E9
+089525CEA85B8BA38A452DE1B15FDD98531EBFD98231F98E6D0E173CED9A9CA2
+99D901E777C113DC94E90DA8DAAC366DE5106FCF915A5403E97A450CBEE2A7AE
+51FC93EAB8F19EB8EC0C774CA15B71B42A705882FC62B72F596A5C97BEEC8793
+23386E86282F773EEE00364704C45DA46A87F8FE4B8151E157B619E06DD0FBAA
+6001E1D2AE9AC01248C087910CD46EA1D245A508B3ACB5F0DEEEC5759F4C0A4C
+1006C84E5F95BA59C81D24E3EDEC5C9C7665C49A90251395457032B41DFAA938
+5A4C1907B43DE42AF31A4F5A3C884A4DCCFCAEFE089360ACA22C787B05A94B82
+A9C2AD44DCA07C2117B21A3AEDB03C31895918D2459B7C3E05B992C27991CD80
+8CB969CE96975477E75DD73B19A135B7F115872C0599E812ACBAAE059C2F64D7
+0B065521FDAC5C5EA97C7C08ABF56426A89945A7DBAC2A278AC861245D7A653F
+B7054FC04443648CA3B5C84DCBF8CD7C5AA4D49EBD51B98D6A249126C168F956
+1A91B140C1A8FCBFFABA976416860D12606396D06A232C3E907D9BF386F21AA9
+E3879385E70C00BA28F999CAB8BFDD8881C142E72782ED09D0DBB0A4D90A239F
+557D8595A2E1C7B171C76EFBFF920E8B45376B50F8686C16F07A1D5C2002BB20
+A8FA69DF7DAD452248D65141B24DE217BCA29A8313E286DB8E7580C46518CF96
+2901F7177C8DB36597967B8D657723DE950DA91C16A8003E42E68BC0455DFCBF
+B591C1F3DA56AE7E667CA7D230BDF5BC526B26E36C0404467282027828BB016D
+8ADB60FD0DF78D689D330319C06EB9D525BC4B4DBEDE358EE2BD7C9041BD4030
+38026697495E8BF0775CA00DFC92922796C240E6CF43037C1D0AA4868E2A28B0
+638814DC05A6D9A65898EDAF9BE5623B2406EE4FF458841BB84BB2C55994D0B0
+7888F3978FA762FD36D63AAF2E4925B4A6241AC1735E92C9E9B60744A9D02B58
+6F2DE72C8F8C4C8D60578C28091031577D15BA1C4EE02C0D3170CA490409372C
+F2998B72F17AF3698CBF8DC494EAECDC0A7692C105A05A9C28340DF7B127F8CD
+F6DD70F190BE5DB39D4BDBAA3E8B66C6C296A58C89DE064DDF56D29F134CB5C8
+A37F78A21B5A8D5DC69C7010977FDBAB4AC413E419D3961A679F4500554369CB
+F19FA601839B5E2FA6D6FA1443782B5575C3666B0EF3C0A60419624A52AD88E2
+A5A120E26A1F0B055E0F36413F9D929EE527A35F59DB0D50C5139EC9C51098B8
+11176067A95D883488B6CBFF22A273D7C32DD8DA236138D035A35EE0A053E0FF
+238C1FD4D11A31DE7BD4D7FB427467389F81F9F338413B06DDE780345D5DD974
+A131C82C1FAA7FAB1D9865676B87CCA505E7066E11FA5B45F6D3EFED871C2756
+02DCED72FD1909F278CF5AC0E18B224E2217FE5B2B7EB107BBBCEBE5F4823A37
+7507C861A296D66905F10D227C6D6EA7F46CF937EA0F42CBE444F11D2159EF83
+775EFDC3F6F400F03FD527CBF434E5B305E17FE2ED69A3EE289D7FD525F1F5F7
+C40F076FF61C0F3A17880216D4ECF038EE7FF589945AD0585F4D96B72558E7CE
+F71106D7DF2170A5791210389E8F2D546CD485A11C4AE4EC5D416C11D9F2CF92
+CA6469D18021C913E875CBD47CB8EEA9BCB44301DE88ECBFAA2632A6B3BF9C26
+CA8D041DD4D0E7D8FFE90C585F870606D892A90F7C63517CB31E69BA29C0400A
+EF8C14BD860BA8F3031F1019A9E97CADC9C9FDB9564534EED221B4C3F4FDBB0D
+0EA49935312D351F23E51FF611D3E4ACE91D0245C647E989050FF51FAA22E7E3
+599F7DAC8DACD13CF2CBCFAACF28FC2F9AE999B2C96A6195D8392E86741B95AA
+A28260C4556EA9680E439BD401D2FD507E636DA8F82662FE8A3FA3DCBE07A910
+744FDECECA4D37C1D409B45C00A8083DFA1878BE01F6B601B6DCC90D19F67B2C
+DC6306FEF183FC6BE537A5C4D19EF7532071915EE17CE30DE92D758C10651F24
+761B60C49E7B7EABCA79749FEC338077D28046CDFAA1C616DCC325E060F9469D
+F8EB4F9270FD298C6AA215942C6D279CF20687E1A37AC2F73C317827E54EC341
+187C97C1943C90257C44D286BBA966C65F17E27D767C123495BE54FD11A9943D
+812D27949EBA7DEAD3A447F53370ADCE724D74D008B0920BF3423F297F08D9B9
+760922869A2F22EF3B54E1F26C74CA1DF0F243BFC910AE37296F7B9A3BABA356
+8A197757F66897ACE8A0297513C20BFA4DF019D6412428558698F2E3BE88F5B3
+5D79127EBC1F40F9FB7FF78674364FCA7547E46F7AC070A6BE1C78BB6290D95C
+879AC41E20647F5C013B2D11EA5323ED8C44716B5C4BF01DD8FDE585E232B2E4
+EA21BA47EC71332860245ADE3931D5244637C026086A109095B5BDF099D0BDE9
+3F182013F1A66212D81449F0B26B4DACF5CA99ED98F18B4DA94C111E92360DE8
+33AEF6C7F0DBBD538C81EF1F4F22BF1A80C21D47085D2C282B098872111FF472
+9C136570BCD0F23DC3710690C92EF231A4BC410B1062AB840503F2F77277F7E5
+C790E50E5A9521BF003E9482EB8DC192CAC2B6B543B9F3957017609D436876F3
+E650EC123DF7D2EC89DF03837D2B35F246F05699A06239008DB2FA2E1615E57E
+1A6BC3A15B8EB98798569C5E46FF639C7373689AF8300CA200AD1E6A3470D18E
+ECF2DB83618AD6D0DDC1774968C18D683A49332586184B11882B4E3D01A95AC0
+3C02EF32FB509238CE6784832A9FED420B03AF43459AD786037CB0A746922D4E
+0DB36E3DB0FF48B845ABB6BDCA61CD3CC696A89ADF2E22D33D01CABA7192AC44
+60510EDEBE116812C010786E0A23D2C2C455A7FE5AA964EAD8DB914914376B4A
+DABDB6E15D932872715627E226B5D3C813651BE179CAFD44184DD3EDB5219FB3
+E41313116CF4E7D1EB379CFCC539C38015288E74C9C5DF65ED94AE2036A5EA81
+2639DDDFDC856D13C557E7A1815ACD18967023659730D1D23A1E214966412F60
+5EC395161C946D2AF9BE0F433A6AA554DA092907FD976A763D230AAEA81357C4
+DEE626BF35789C10B5B41F2A91D8581CBBDBF1AD46DB98ACB3EA7DF942C005EF
+B1E64F1728D53B3A5892DAC032A3D9B397E6CBF9ED1AA2DC43CA38D6B990AC3F
+656CA2D3661D74C76D4C3501AAB24F515C5440F01F97CFCDC8EF865586DF91A0
+EC7CDB099042978264C0729315EFBE1CDC81B0100AAA0D12D1644AF2868111E2
+F02E0E0A963DE672F148B19A2D51F468C01AFF2E3264F3B7CCCEEE3908367806
+484CB066FC7B3A9E00AEC83101BCFF093BD4C3DA6B57B4448F0D358037C3B8DE
+CB1AB4DC60F95AE5345FDEA5052E867F86DA66958A2AAB9C140F0C05713B1920
+E120A4EF101121BD0FF6EC4B212A0C984B6ED432078EF9473BE73914ECA78D77
+B84B838AFE5288C35BD52BA556F361CCB88A8BD6255C5E8323614B2E84A4B27F
+6CD9B7EDFD4AFDBF33E89754CCF00B0D5EF7702509EA60F7B551928D2D14CCE9
+EBC0E79F9D346248AA527DF22C3C4A82597EAC827BC55F93403402D8FBEA7639
+40BDF8DBCFF38C02868E96AE562F0192BA99EE56AFA4D0B64B5D897E0A9A4085
+56D664541B218BF6801889EF0F7AE7381CA8BE66CCF40911036EC0C2FD060B34
+F67F3A6DE12FA736231200966E47F69976F84046D673DC546947D18AE5176522
+EC237FEBA8BF1352382BBA72FC822E9B81DB9EF771EE6AEE109B87B1F6A54274
+1D9A8095CDDD1A0576EA77FD4B5C859282F75B0E8BABC151CB363D730A0C63C9
+3A2FA8557EE12815FB8F5A53D0F36EE5483FCA49F9D643AC8B26B0B68EAD0A34
+EBA2F5EEE0828C16391E5D0F5C0C759655F822B4C12BECA5B81C8A737280989A
+AEF491D2378A7F0907F137A955B2BE24BF30C8B71382643A6F8DDE45ED9D9566
+0CBDF39945F70918DAF39C0D9C989BF337C224357CE001F8C868C1B0E24EE88F
+92090DD28E0E4F12CC6ABDE9989754F1DF6F0B9305E08260A834E3C2F97FB36B
+C6750FB19D900154116C5C2D7294CC4682993ACD754BBB3915C126EE1CB47EF8
+43F0044EED399C7D59A9CFE788E36AC583198FAEA799F310EB54E5F3524734D0
+9484024BEB1717A3E76F4E2C325606E39AFD9250D0A4FC82E229FC9D062E26F9
+BD8A42F289345AEE7DB7A0066B4CA6E02FF77C3D9569A40A2BECA472E085E362
+DE842CB3AF49C98CC485C6D1B9401CC7B073445AF80E59E38AAD8C08B172A235
+913B894C7C5FA15F8012A5022F65B6D35A486E2DE487B3897A4245AE65C28019
+5E304EA97D7E1C5601C596ED82CB135DAEAA246179B11607C7798DFE8A8F32B1
+E175420B79AAFA0A23F5D0CAE915870F8D4A840B0647F509FF836DD9A81BAFF4
+EEC0B0283DD15D09615E02C1EA92610184E0B4F127E2D635AA6B236827DCEF49
+81E16DF5BBD2939FBC9C5089AAB6BE997E412254DDBF427332C42A5A55D62BE0
+B593AF26E2B34E076FC71DA6E4F21D7EE6000C72DB3AA84D9E0B1A05684FD787
+1B8E62F844EFF5529ECCB971145AF13BE7F2ADD2D62DDDEB34099CA54CEEF882
+8846BA06AF5CF88499446ECE01AF058084B1E4D6D005D4292034EE716E7E1204
+20D2722D023BAFA222A4B36FBD2B447F8457C6E2B223FADE55A49FB3678823D6
+94F094850D6007F3823EC4805E5D8F106936C9452355FB30A32972B0755A109B
+9D889ED128E0B10C1BB22A93F5385F7021918699B692D1CF64137817811FA635
+92FC6831A34E3FB22E16E7F431333022F3AE17183B7D466EF8962FD6D6A77598
+8B9EB0ECF01A276CF1D977417BF0A83FFE3F4E2C1F04116F2C81BDCB47940BA9
+672E31B7E9748A15EAF0979490700B9F3D403A1D625F5B229E4940ACFC62E08E
+DAC48E011B89EFADEF9111F9528BC2092B772F7C80C493F1043FC8D55194C108
+FEDCBD1782ED6D64088BEA1C398E12D8F8B56807D0EEFFE341DE8F69050B01E9
+F3AEBC8A420605EAABB1FD20A2C6DDBB016CA3C198596D0D95978E3A950B2880
+ECAA0091D14F107095241446C4A693DC0D038645FDABDC622F3D92E3DD51A526
+42AEF69625E7941487FDE579F6474754291B2215E2D5C8EEB62B0223510007D8
+18B48237B669091E8F81204AE1DFD0BE28C39C7FE61F4C796079C60AC90B4223
+372DE6A5BC492686072F0226C525D575F717070BDAEAA22379CE508BE96D8CDD
+9EB3520F88B0E69F56E72DAED0CB77FDE37DF220A02A1AEB445A2701E1085864
+E8FBC64F0B53E10EE1FFEC765C766B05B35E430BFD83E55A94AF677DCFC2FD16
+A2BA4F1B80FECCE197D0C246A9A3329DE1988892494FCF17272D4243A4562FAA
+604DFEA30540DB06E9EB5F028BC7FB59E138B4C0E5973A023A7DDB768F037AB9
+6D3A55BA64C723406FE4AEAC0FC198060230CD1DCE4AD9A38A265347458927F6
+8D6CF4BBD02FD21C8D48241123E4563B2A448C07E0ADDC26DF600108A7584B92
+696F324E06D186E67E5F3954B69E04DC7DDAD01D833EADDCB802562FB5D383C8
+1B4B37EE95546EA470856F010A6C9A7E314F16AD49F1EFCB64C49AAB640BBBA2
+9A54D16FA80286D06AA56972932C9DD7BE797912BFB430E75BF0C5571FAE652B
+636D6C329CC634234B5BCD44FF11CB4F50EE9A1EBFCB2ACA2ABC01708F1742ED
+BF0345AE22366106EDBC937171D6FB973CF7BC017BEB2D1DEC23D5EA8BFBA775
+A622F99CA58583E600016B26574B9DF996E5B8DA6E3C3963D8CA6D883F2AE3E6
+5D5B75F4CCBE8C351AF744EE8EC447B9A5F1355D2F6D1C00350D1523879274CB
+0DEAD99DB739F0BEB6B8057857F8842DB8C14C55AD2EFDCE989B70DC1C8EA024
+25010965B54859147B01CD6D14849F14B2975D6BCE0B6E5424C8B24B202F699D
+2B25C3EDA416388FB272725F097A61B9B83CA3C7B10EB446485F9BF022C3A49D
+8CB3BA72DC84DCABECB1652DDA6D051A53ACAFA716E04BEF88D092FD24552A15
+E56C3D45379F3DE16ED2F4EDB063276C0CBB3367E0D3CC7A22361FA087DD777B
+7700DF681CA7F8553A785767C30B6EE64CEF0F5D71D7F730D943AEC07FECCE74
+B56561DFFEE203A3E7E324E608134C0EF63E6DE95A744B8425F2633CF988F140
+B850A301D3DC3A593F7A7917A6FF14F5CE8A988857F8B7FC6EE4DEFABD0DD204
+EA64C9E0AD749C6F808B84C2E70FF91FD038FA224E8F1EF92E6AE8161A3481E6
+FAFA49F50F549F60999AA156DD6B81B86266248E6C92A8BEB3435A6C1BE2841E
+AD5C859D0A106813C6DA8D80715C8D26AB447E081F3E6EA832386577BAE02C4F
+32DE579FCA6719ABDD7790C78512787987EBBF8E31D930CA869C2632BDF05FB4
+FC711310A33067C1EB254FDD96D5D1561C5C33C6E2F6D6116B1AE129EE305506
+9BE2A3BF2A014862056F72DD779A759EF65F56D124B4A9B645FB412825AE478B
+B900D11F64BC918D7B693A6B8F99E0ABF7EA9A90E8F1844D57D6CBCB91378406
+C4AF1A285D42819A6CBF9035BC9EC980A1F06C3761CFEDD2CEA92348AEB81981
+B44FCBC14C4711E1772EC20BA23DF1B87360B966074BBDB6BEFE0DC113D932F1
+BFB62CBCAE014F93E0A982E32A7BBABE093A0F613C2293B93A50E3C92F7C86F7
+03C57833BC8AA953EAF04C812B7BBF69401BFBD12175CE30A383F9C0E665F5C4
+47D064D71B7C55E3EDE73D4FDB39474E3477C1F41DDF0676004856981DD66BC8
+52A02BD9FB315AF8E1C8C46D913FBCD8BAB672A63416317D044C0BC9D94D07C8
+F9869396352681EECB7111B6EB787B41F863BEE90DACA852E36AB4566011D279
+BCAC46C22ACF967CC133B8B56275AFA4811BCA2F5ABDD5851E10AC9062EA5899
+88698F5CFC0EFA9B83B71E9BEB3E583D63D6A0E00F7BD257D9CE89A6475D7887
+D2A2824C99BA304A8D6728CC9DB1420295339429E93839B5BD33FD52171A5D04
+0E31E2C3F4A59AF980CBAFE2C0E9F0E3A364E58F981528AE87FEC2F49214CC78
+235787626246215F2EB7EE93BA23B269183D0844798246AEA9F0AEC7913E70F8
+979ADC112D6B9B4630B59952662B3E5410FC51925E1A9D65AE9E34068A8B9E89
+E5AA71F1821A242AAE6FB07E3CE346CD190D5B426227555D8E230EA97579ABEC
+1A9CD2444944F7046B16652A8B028A8019FB42DF74FA89F9019BBA88C3E60F49
+3FAF0BD601A5C05FB3CAAF69E8E2DCC73DB9FAD38F55D4C278B5C87314AD7248
+0C2C3BF34B16B7D3ED8ABFC4AA1B09672F00455486E2277384448F1D7C7419EC
+9BD3910468C06D1201A63F8E94A97D2827E92FA9C9C2E3B5C35DC438DA1F26F8
+7E854D9024664920D6B34AAA9752226FD8E2F55BBA64B7771F72D5C819956B66
+444985F3D121E3484A05C8FD7D979A0BF121705C030BE8D72A0C7D7676B8272C
+61031238833FFD66570C2CAD91E3A007B66ABF47B39664B3E4E8FCAD1D7EBC9B
+F9B260D4F29CAF2250DD465C2C139D088B3EC581A2ED4EF173E5BF0B2F0CA408
+90D79B4DF2CB441059F4FC2A87C836CA9D143DC75EB56AA3E42DA8BF14DDCBAA
+EA0AFB38E56054AE830F8C318ADCC618B52B57ECF18C8A0C9FDC24B51EA348C6
+A9A1063934AD4CAF79FF11ADFF51D1DA20A2F8F7CFF5490A9C9D2DB97A94569B
+1611A53C24F8949345E0E4B44053897C7F96DDFFEA8E228EBF734741667E190D
+4A6D92566B23076622CBA33B9ED8BD9600BABF2248CBC9FE077FD59E3C3D72E1
+95D564FF109714AF51B7499CD15636E1446C9DA0904427C28BD2FD268B2B29D9
+D578AD312880FFA16A784DA6B7ABD8CEF20229F39A963E9FF5D46078DF3F55C3
+ED814ECC054675A2E02115F1A5BF45F8B4F74A6810B7956379BED10C55907467
+C9E9F5A8375B3C96F7B69E06E55879D73D8B46FEDE5682C5C3A98829D84ADBED
+A210335AF38B413C750D6D0535A57A743E0DA9B1815CD73E57DB021BDB147CC5
+BD0F50707AAD31FE3A5CD37C3543C660CD7FE65138A1C411722659C976B9B68E
+A881429B559AD9360271394F195E28092BA0FEDA0BC47879885B418E6E8DB7D9
+7709751F979360D8FECE89EB92CE5E583788E5ECBCD5291C5BA1A33B7113B021
+CB66F820CFD79554CB718FDC9FC0059CDCFC45BC3AB39FC06668DA03F9DB8565
+E07277C11FE2498078A52CF2EF39C825B149E272B484747FBDFA56016EF378C9
+B3ACCDBDD7E36C273676FD3FE43B9A0B41A1A42F49AFD14F0C8F6C2DDB9E25BA
+D9BFBB6A4C521EEAC81F50E54A5A9271D299301D559D22FE00E914FFFB0197C9
+98EA934A19C4E3173FC55AF7210A9662AC29B93B89E31AE842A8D99166FB3A61
+8C620235318769B9C11CB9F3BF88A6FCA52387FF22273580CC3EF225BE4E6D83
+ADBD20361DFDE529FA426A635C3F757CBFA901DF3B5BCA7B950B16A6778F5E3D
+0844017DF62C84A0EFF556B4BC25BDB84A399E4DE188CD3440358A38359974C6
+FA9FFFB69C6CBBC7471EE52AE31066DAFDB4B203232C1C31AFA55BF188177001
+144216E0093E43EAC08857DB1231E39FB13D5DEBAFB7782755BE138B1A77AD67
+8F9E6F233E4912DDAAB2594B4DA0C32F4F956CF9C74303A33B5B61EEAE053F9F
+A2707E8C88C200835E261AB5B27341277ED501FE9A81CA0CCD67459CC0B40245
+D74BDDAFAD40D89F503EC435A98F9438362A1FAC5854ABC086A0E09E0C74EF29
+7F91D038B8B3DD4ED7C47E587EE6EB99DF1DA66B392A2652B8FD8704B2FBC18F
+DB014B15A4A08FD71AD4FE13C862B0F1B48B5BE7C246A308ADB1EABA662BB2BA
+177DACCCE0FEEF2A68B5F2B998B0E5E371BC4CF69E09929310E45218EAF157C2
+18D702A450BF8C0057CBA39132CC04E17E9AD2F8F1D5A3AF0B68C21B11446E51
+51216B23A6E1F49081C5C4DC58EFB0361D077DCDEFCA0B4BCCDAB28EE2194E91
+AF6C99987737998BCE51C61CAFF318CA6215A21B8770F9755AFFC7CC1BD7E538
+8F46DE997B8481C13C46560BF76F8BF4A4426392CF5C56C6EC5E888DB6C8F5DC
+38E426BBED085ABE840AC95D8CA07C3036CACC677FF710A5FF2316D1236D4637
+8857039A64CE593BEF5620EB9BC86B0F674E402C662A7A12B2B3F247A3EADC51
+8459BC247E35EDA8D0EFE5AB59015D0838A883724F9C7CCEF7EC82BDA4F3FB6A
+6A6C3C298111F60F918293FB8A55E1A870F87DEBFAD5F1B27DD475619982174F
+95BEB80760789199DD0F21F6DCDAEA1759068E08B4F346E2893C0C56C9E37036
+476B9B614E727625F838D807074F07AB3059AB26F3D5121A1D54E131B983024E
+DBD29F788B507B034A34B2EEACEECE8309320561CD4363612B86EA5D2E2FE273
+1856BCA3EA097D94CA7B852A2CC829871077090CB6B857614B91BC6D04B84D3A
+0D6326349CBBC24E3F86BFCE5F1BA018466161A6E9EA8CEEDAB5878DC1619C8F
+7E288E9353B7F866D2729CBEAE9FC03AF9734565D7CDCB0EFE4D26E16DB80A5E
+61CEFEE33D280600849DC7EFEADE8E8DC910451687F92418B340608F22EAD7F7
+82262CF10117A75E9B64937EB50687EACAECC0A385EDF8CBFEF3C3E288F781E3
+E6A3D328AB09273C0217E04ED080A696799F215CFCC84CBAC3BD150228C98536
+D8CBCA18350B8BEAF8365144F90D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT8
+%!PS-AdobeFont-1.1: CMTT8 1.0
+%%CreationDate: 1991 Aug 20 16:46:05
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT8) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT8 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 33 /exclam put
+dup 34 /quotedbl put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 63 /question put
+dup 64 /at put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 88 /X put
+dup 91 /bracketleft put
+dup 92 /backslash put
+dup 93 /bracketright put
+dup 94 /asciicircum put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+dup 124 /bar put
+dup 126 /asciitilde put
+readonly def
+/FontBBox{-5 -232 545 699}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0187316F83DDE3E2D27FCDF6C5CE4F95B6EE
+3317BD91B7921F3039DD35FEA387D5CFB6C6E9DC84C178F3432994FC7FAC6E5A
+ED41A1E2EBA350178FBFEB45944511731BA827167DDAC238FC69A5486B995477
+C469E2E27493B0B711DF8E267D3D5613B450011921685147114106C9472580BD
+F531022F6DF5432B2A4EBC51A8032C7F9689B6FA942D849B29709631613DA68D
+4DF7B6F059A19304F40A3C3580CE3B51D79D42984194D4F178801720892FB6E7
+61FF43C63F9256B5E9F4227B1378222BAAD4D52C77462DF01892220E11129C16
+6C9E45BB9F01ED7C1AD5D8B4D72BE0E12969AFEA90FEF170603CDB91CB243173
+B19A56084D10293B80A35275F41BF78A054DDC98F4A1FFF592463D944960FB31
+6BE5F03960F9B1F213CBCC7FD448657FE388F10104D42B0715FC9571CC60CF23
+C72560CBB8835A0CA208FE06676B3B48B093CB7FB2C0C53AF17EC5B372A9771B
+BFD52FFB7062B4FE0106A01A2A1A1DD4EF5C8C7623EC9324A2CB3B402FCC1FCE
+52BFC8662F8A39D5F1B41C97E7CE34E16AC28A1E94007AEA7D4C519399F1B7A9
+48FA7DDB671067244F09C29F95DD60668223F45BBDA8B1C452E930A9F3F341C5
+351D59EA87462FFB30277D3B24E2104D4AAB873BB2B16DA5B23BEE25BE2C8128
+C4CF2F4F438A4E520CD864F3EAFB5363753B82978F6FD664A14E5D6F3A929348
+5839EA752FD635619C4FABF1E1454510BD9D6B538A343BE748AE05B47F917367
+1BA5EDB15F1BDBE806E51B294257D7087334165419A6520462D794D670A1D6E1
+3BB03BF689391D056D55AD660D15A386E6D222C9572BDC4DC8A46EEC75124BB5
+F0E8978FD6031A90E4768CCBF62A5ED8C8087FD66D2033011947634878BDC0AB
+6501DA7E6D96E227068E993DBB0072F037CA4111CAA4C896B6CE9EE0250B51C5
+0EFFAFB8EF7A92590B4EC384EE1929683207E4929CD7257433101E27DC54947D
+F00978B054847365048F06F69F8DEFFE073E32F59CA98FD9247A731415CE6908
+153BD01A58F2A482D52F14F7DD894ED0A02B191CDC565FA10C6ED6DC3344AE56
+E9FC70E591272388021F4A8748A67BC0A18A9B288FCD4C39979A44500B86E099
+A370DB711D17469950297B835EBFB63130EB61014997493D87CC689645D41BD4
+99AABB9646309F174DB93723DFA8CFCBCA0FEDFAB79DEFFA012A57A046606B88
+58BE939A18B4636E21AC5ACF54D0CF400C71095DC07FE6A4E99E765AE193FC70
+42EA351128E04FC669F1CA3A291FC393BF60EA9CD97CC2BD857370D868CC3C2D
+5ABD84AAEC869BFAF8488F39480B8CB70CEB6E185EE4285EC732179CEBE94604
+5148D3097D9CD2ECB9E4A6EFC03AB1D2F88F4C7ED937CF3CDBCC701B4CAA619C
+B9941FDC8DB4D039822B678A464B0CCB1874C1C8E765146DCD430FF6CF5DC96C
+4826860E966E215FAC9BDFC834D700D2FC269B2F410509EBC13C25CD9A6D9881
+E2571DDC88527319EDD129EFAA3C9FFF38BFC3A9A88F518E1D240BA5DB4DFA56
+D6B28B2B7CC75C52C9A9367DC0CE9DEBA73F47A7FBB20DE236A40435159F9254
+5859B587ACD4752CCBDCA9E231D165C2CFC3F4AA1C7D1E247A0FA17091DFD513
+E7D8B400B9FB554FED4FF3E3CE82600D11147BAFF76F679D1A13D29935F77C5D
+95E975F2B598BD9513EFCD772D6F733A926880E6D6014C7A74B1F1C949310571
+A7DE4F7875DB96FE4F43D9D9C1041A43041BB52C05AF16486BE415365FA384C4
+5CF9EFA63F37AA33B84D6450943534A0E4CB218B6918D824629C8F6702C9F199
+C8B4DA38CED24A3459E8F781D0992C9FC46D455D06F1DB03C6BC36026B9BAC0D
+0C8902F27FF548E6E610B570DD8B6EDB6AB09712DEC4459D1CC8C8D21C5C26B0
+7FC2225F44C3D80161B8D9E6FFE3050B952B2E49D760E690A31040E28E2B37E6
+879875DE12F87D3E7B1FDD8E82ED97F9FBA6D2813ADF982EBA9CF4D422503EA5
+283EB10280B29F74865B96B83801D73F0BCD851D6848470F4B55F360EA10B3B3
+965B70BD9851E0E5129337E83D911F20B92D4BA91EF39DD0A84576F23297B6B4
+9DF2B793FA14CEA29EEEC52BDD2BD3A496FEB0D5AE235D12A47B3ED4021F126F
+462268C4C76C547464A9947C2357F33BC0FA9EF35D7DC332E1E7D9F7A2E3A018
+C244C6462890374389CD7DD2CC38AD437F659AB7802F82EA9BD46CB86E832F18
+1546F839FE038B1E3B8C9DA0FCC002B541B2E0E00B7A5AF854C48E4F333E46F2
+BAF6F02038367CAB39F94A6F5B13B34A0E0F6DB6BEA9015303908C025F981A5C
+C8167A1528DC7DC39EA6614F1C9986B80B1E74F350637BE6075CB3B388CF80E9
+3549A87345ED58933B42248AF367625ACACE747F82A2761696AF3BAB8882AF0C
+E2BF72565BD9206BB42D18B39608F8B32B1A106DAB2F53BB47A05BE458655427
+F7B3CAD17B65AAE920EFD2D05C426EE762D29A70E67A3561C496A95958A8169C
+F7308423EB93FD3FA607986411901BEA258A3E3593CF32A039CCC43598BE87A9
+F911FD42C11150FFB9E363F0A68F2260D1BA18A66572201EC3C3DDB96E202A94
+AD750DD8F7FB29D2C8D08C47F8E38AE0E016061D22552A0D120E66E641AF1279
+CA365D5641A279C9F752938C89208E0D415D0DDD2A2A2E6CCF8A92A22166CB8D
+E6DD3BF30CB892C1909EAA8609D918BA28B713CEBE57F608581F7476253AA383
+7A3161C13966BA31FDF6C9C5F761D9D0E78AD6ED732AEEBCCA69130C64E2CB77
+CAC7F5B75B048CD0951E0A672FD44A4437AC12A6A1CEC11FED0FEAE526927751
+FFA46DD429B8158F9BE2D6145C22D64220B82E826E386AAB05315AEF0B0C14FC
+3CC30CCDB25DFE696E760CA40E2D3B6DA1B32EE92FEB7E477EBE902ACFF42D02
+9D35BBA5EB0FA8D01602BFF8AB2EB0108810027DAE95DFDAD9E05D6565745153
+3958F5AB775E719806F9641F25C4DABFED6E555F6B6FD99DEE835D02D756A49B
+DA24C0A82D53DC185CA9F86D3A937470D9D6F429034223DD1DCA717173FB0738
+8F97AE8DADA5B033B69E469FA653AAD4C11D24A32EC9039D425890519F660F26
+79F8DB03C11D480AD5954C3CC2ECADE848D29726F46C0998F48A0A00C68B481F
+65899353CEE0853C27683FCCBDC4B3492B90B63AAEBDEFB80B80789C6C7205EB
+B82E72E9B31A452FDD3084B82DC4E52F674B790F6CB76D98918980539A242FB3
+07DAF98FF48244A650CDA661EBA17E4F0A9085CCB1167A3649E73ABD8C4A10BB
+E0F9736BD694404986065DBA7659FA548D7AA9DC211FC354067D571ED7B93AC7
+3E72A580043BD45239B1972D4B76A46C264D96435777DFD295EF35AA4FF5605C
+664F98208E12E9FF182768AFBDDC0D85CC5012BD8A3940AF7D590B588AD33F0D
+7C402B814D087B867A31B25C500C0806D9EA56F602D574B9D53AE1B62E583840
+2C82C0FF6AAE7BB31170EB18B78938E107036395F1EE04906509EB25664722D4
+B8BA69AFC4C1AD56CA362E721132C076AD2F19CF210F37F1EF9CFA815C82AD71
+8942F60B1CDAB7C94D8F11F272E2E6E04762584665DF78A37006409ECF881666
+C6A8A75613790D6D1D935A57430E7B82CC28582391AEBFA22C89EDEE5C11099C
+1BA35F332CB3AA0AA71FCA7715D2A755FB5535C2BE9347D62AE1C9A78769B18C
+D90D2B4475FB5F74A9C555C7896DD6D7D29166FF7CD927DFE0F57803246237B6
+9437C784950127A54B7095F6C26B16D8B66A1A3EBF53FFEE3E0A389DC9DB8A16
+BA2E5E3AAA6C0D4287BEA288BE1E67430069E70C66669CE73EEA4F13F46BE637
+D4E62A3092B5384326A01DEAE8D8D6C1699B089CB951CDC13C10252CA724EBBB
+8BE747374E691B11C8E6E34C3A3C345B369D99B4DA5D1F3A8CAA7494CDAF09AE
+048235F7F20C3F08EA6B0A224EF6EA13E3BF5DD39B2B4D48F3E51D70A00D135B
+96C261CE4C757D5A8A49F579D067B785608A6DB806E48A7D19CD5018653DE4CD
+A77217665C8F454CE1AA49E307FD189138CA6EBB269F5A8E9A8ECF75B42B2861
+A042E06256388BE90A5DE3772D685ECC5B5ACF663182E41BA5EFC2BA060E277D
+EEB21BDDD99A430E7A7A601F00DC2AD210C6793C613C09DB9335720E202F8231
+BC4184C86073472D41360BD3C25987E6E3668266273704A226FC74C534AB8ECB
+1DBE98EEC7C08471542BCB0DCB387A35DF3DEC4F8EB9EBFFC2E924975943FFD2
+4E0606C6443950B528F2D332789E5D64F94633E3BAB4E55CDADBD7115A8C0ADA
+47AF34B0C4D0F40668247C08B7904BB19E15219C067D3C6CF6A3919638FAF17F
+D929245909E8D87CB1DB811725BFEFB4AD457AB43F8D8CF730FBA475D445F74F
+4FB7084B60A9F833D5A39D0B456858B1C3A435840858404F875215C0A4976F35
+0C7DE54A889C84688D900F971A6798DC372E7E8D72CFEEC40D4A4D8E12BC1442
+D9A4159DDFC81EE7F818E70AF49239D1565CC2E34A4F7D8E140CB6182AC980A7
+4522855B9744B313D96027C30E32A7FA51BB11885F8E38DC8C2B6ED446B66B85
+2DC8D22A348EEA171234F7EDB6151C1C95B5F1BBA45ECB8AFB808F78FDD735FB
+E7366C2881D44A9CC1F060F9A910A361FAB01C1579CC4E605FE3C3ECF73DE057
+A7C27D9AED325A03D4DF4C92FA3A23E8AEE4458C762309D69DACDB5E067621FD
+5E5002D09253062EB7613991A6A3F430A7B67DCFC6CD2544295D18A12914A615
+59DCA81E53080EA3906416FB1000151D32E30EA714CBDF32C3D0A3B927C69DB6
+B9420EA26FA751CF764376C50539BE3E7B71407698E7EA0284AFD1B2A3B4D3ED
+A6D489E706EA852B1FC9235BF28E6F0FF740CFBD3AFB581C66D313D7706692F8
+F8B7969508A4B015B8BE63879F71CC8B0E0205C6D995F0E860E71ACE9FAC93D0
+4B947AF8DEAE35D11DB8F051EB806B2A6AAB414A1EE8188B1F1652FE111177C7
+D7C68FDEBD8A79776D43B9C88FB245CF85D471B50FC5DE9372496CC0A9811C4F
+5AE78A4B8377F6C259C149496E8AF25634C7CA2D8741D9D2E3DD4CEFDFB40444
+4223E4A3D6AE8BE00EE8A72755C35BA04251D3ADF0F913D757BD5FCF2C0D2560
+CA386A34E6B9770178307985ABD1494655869009704776BA6DCC7E8026B2C271
+D539123814B1152A46B99CE07E17941AC8D3F3DB18FD8FDEEECF00278D942437
+C260C44FA423C49E8BE0C2A626029AC92A375203CE45A82284F02BB42EDA5FBE
+B5FD38CCBECE4AD9FAA0404AAE1B7B44024716C37671972552CD73F5C0EA36DF
+76F08D45C48925FAE354A83A2F4023E4D2FF6FE44ED69FEC1ECE52086F5D6470
+A20CB929F6E52D797C42C7A3DA259C878D2CE92E33F24B0A0D315EFA7F607283
+D33C87FC45F9BADE0B0A8741898E23AEF5E28E075862110C8C1CBAEF80961369
+C1CABE3125357350D3150A1821D3B629FA667801556CEBD2C9767F6DADA4B0DA
+FB41BD72ADC6A71CD7BAB7F9AE4DC3C8AD3C362552BF7A3F8D58194627D1074B
+E16059DFECA7531AC8D498772ACA20D79202F21AAAF7BC30A7572C8C6652F49B
+1B50B734D55B30760F529799B5CCD62027FBB67784A8FF6C9F58A0F990301C43
+A6160E8DA551BC3A30897C4E3D2DDD20DEE777173D6D92B94BF898A13D4FD48A
+51979672A13A21205AC67CE4AD609857CEC4C3AECB4C769748A44E06AA4F968C
+B30D049968E2624AF0540F7FD4EC2547145827CAF0572DE8BADB158D0A00F0DB
+46DFFD8DDBADD30469A0CC3D1135DCE8C146D0DF34006D4AA216AE2609C18CF1
+3D122477BEA2747297654D34C116ABE7DA503556E3A02423EB775FED68935A93
+AC3980F55DCB7AE69F0F99C0FD5F6DE270B7989E2D6879B0368C8D88F45D4749
+D80FDA45BDA1AAC875B1398F2DB250ABCB693EF8E5A3FB726AA43EB15717E8C7
+256746DE97DDB2EDDCC467958591A4A23BEEFBA7DA35BA5ACF0D9346375CC4ED
+A54EF505A722FE2C987F79FB07A415BE36D436DE2A30A14DFC1005E97B5253D8
+D1F4E60ED182E94D690CF9DEB9BF6E59B62AB0E96DCE41E3972FDCA85E0E3E82
+36572F9780658AA2012C07F00A9EE6C961E10BCC4B79C653FBC171A8AAF35594
+DD271C556396D59E8F423D4CF333C53C2084D820C7306D70C6FB1842B64F0ECF
+3148A1AE92A6D18B65AACC667EF4227D03ABADDD37E6FC7E08C741D236DDE5DD
+72A761FAE1AB90D3B13F3FB7DAE7CEDD0B446B185749F2B1F1148FE8D0A6A5E8
+57B890F37642A1EF9CFD9A64A45A83F1333D2CC98C136B884142CD3B80C761E4
+9C37C29039108D6C19B7E98038920F5E7B55982D84D368C785D1F4D2B71EE478
+57E2E991F0F85F78F07D472D42D4316A5B21C272AEA47F0748CF1D73E1B8614D
+09189887022E86B1BE68EF06559087FAAF2FD3988A1AEF646F8E0D30FC16E7F3
+8EFA26484306247E169053318C86B730C28BE0EEEF3A8F0646FBCE7F68F3E100
+6F9F30250E2A33BE18B1DF2DCDA26707F2329C8B4B9763692205AA3F3DCACC32
+2016850BD53DED0BFEC4DBE7E47AE9C1F57AAE5FC7CED07D868F313836F1B526
+95AAB531D1D25B4182065FDD81AC9D8E6F2AD38DA4326BE0234E3D4FB470036E
+5F634D6B0965598D9CE759235CC6B934DA952BD18C4AC7A5C8CBC3F6A306C630
+81842485A5EA2B4C0C76D370A2190C6609C2AFADBB4E41A61E356811B2998A97
+11AFD15D0FA0FC8EE02B6CF9728FD4FFB8CD9B29C25DBB28B74F605D59A440DC
+7ABD24B49A07073175CE8FABA09FC9113D5C031FA492D646ED71E85664C3D156
+78C43CCAD79D6478C6032D02C4C7032EE16354557B3F62129ED4AAD382CD659C
+1C60C24380667DBCAFC246CC0E546598AB09736DDD3A73CA4BF8CD92FBDE782C
+485A9144E7498B087C90FB5E62571BD3AAEBA84867743AA5CCDD490064AB6179
+0278384C481B539C62A4BE2A1D5BD132441558C8EAECF17F94509F8C57BF63CB
+E1906E88B54788F6941EF51F1030CAAD0C7813EB1946625B9F198DA1BF67458E
+89248AFE2E27513501F850E9168B989E83E01CE45911D9C52092A8C05E8C81DF
+AB2D2C0A286B7F0C8CD08CA5B93B0C1570345F4133031B3025FA12C1FEBD3897
+63E98E3BDAF56A8908474231693E0B5D8CB1E7CC50D79547E2D01D76B1D34923
+A1F45E7C14D3FE9D25A95E61EC7D053513FF4062DB4A9DED1D39FF4C0FE4A7D4
+4E3F5E7607182B431639BD042A24E4022E41D3F0EBE57EB9BFC21C53F3B601B9
+3626F2339C848567F43DBC66207F22138102B8FC2D80B558D27D2911FFF051ED
+8334F7418075002CD6F9100BF93EE3ABFFFE5EFFEBCA4E35470C97DD58E11C80
+B5E8A77D13A60C9FE68F298AE3E331E81AB8CD0F3AB83CF2A81060D296EA3287
+590C03F0C490CB0BE3B4F8096E57F3F199F70E6C10526D1F345D87C7D0F0BC5A
+D64AFA60A3E5184E96182DEA126406A0E56D5AD96CB7514269EAAACFF23A591A
+BE83978762FAFBEBEB1C42FD230514FCD905B28796DA068F9E8C03B0BE7113C0
+22B278EC32A462B0A0FC9626BA387EDE3BB595E53D01CFD596FE224AEE05D2B8
+8EA91999E6194A02A59A66B552FB49F1D9FE5ED4D29C53A2EE78F9D1C79903CD
+6F42E4C0DFB942E029796B542F44657D5DB334BC38608ECF78138AFB90CC355E
+2CCB9F821892410695FA7827BFEE269B918954D8EEBF2ABA78CCC772837C3393
+CA8C0AEBD7715C89AF096F819457CB7025412838885453132D380A5914A46CA1
+BEBAEDBFC55B18049331E887C9CBC1D1DC9CA83FAEE7B89794AB297C9BB5BE9D
+66C1AF64CE0229A73512885AE1845406FE785B007A6DA8D3133703CCCF93FB90
+1D8C131E9718B3A036C6BBEA1D5089C07ABCE7AACDC8DB1FB5DA2A0DFEAD7FBB
+3D21C4EE1DA505D4ED6A7D10AA7E2D56E88092AB64E6752BCF4F59670CE681C4
+4B78DF95970437EBA2D23AF8ABA02F8B7B866EBC2A00FDECCE08634490BA6624
+B192A37F8B4B6F8C297CEB992FBD08992B443FCC536CBD68DEC67367DDCB4558
+BFD6D21C943D5AFFE869DF4C5AE9C54B9F7A75E633D15AE242C0D248E82B84A4
+2CDD3146EA749C161E5A1FE702EB66DB820841C6B538A35D90FA28CEDE2AD78C
+4291D459C371B806B13C2406C557B456BBC8E805E31E9663580E2751DA583C56
+86D5A5A56B831B90053B79046DC35AD611521FE64C8B71C21B07605FCAD63F8A
+5018363DF7DCAD4D327BEAD99605280620FDB39AB819906E4B5DF8D8D11CC825
+A8585971BC1E3130FFBD055546555B4D0623CAC4125BE73E020EF968EAC4CED6
+3D8E3CB2D2321D50062307474AC45806A7632F415D102A40FD9BF5A23E0E6D4F
+A7D872B54666065B8EDF1E0AFAEF94D2209DD3863C90CD82A9B6C04A66900767
+6F00DFD4EDBF6021E416C3B42B30C7137355DEEE2D18F4CC95C30C45C90B142F
+7195C8A9786A3C1AD00B813A84D59EB0404CCB88F7D0B1EB732888B96F9B2192
+71479CBFECDFDFFFA3C6BB355B3C9FE1D36F82EA9D8C1EB9753E2EFB97DA2B73
+A0538657D2026F7F7CE539CF5062986AEAD7D9F5B3D799153AB17D7BBDDFF735
+2418647685D05A8BDF0AF59A1F4AB93870D49D2A029A837921C9A6C3D91C54EB
+6BCA27A97BA4FC19C0467CF8438C3C007BBEA6075F683CC5C0EFAB366CFEB409
+14662C150CB5DEF14930E497EC4CA56E9219926C53FDD87E2807F92629784975
+1EAA8392FCC89BA6F77BA689BDC903ECBF05A0E031C2ABB4B6C8DA4CAF93445B
+0DE5B7788639BFF3CB6B1A9EB6B8847DDFFA679530B85284B8D8B97D8C231F3A
+89DD3AC023AB047A6007358C7EDACECAEC273839BD3AB978DE5BDDE57468F67D
+4E6AB6E557B81AB232C039D462216779FA25ED35744442F6BD18F6A2FA827617
+6BBC802A41FF4B74EE717E2C5D470C2E866623F4737BE7228A6D87342F1103CD
+3681DECF3CA1DC6EB595DD32C360B4B7EC21BEFBA3BBDE28DBD27D5761DAC1A3
+3A4CC3B23AAF9DE8E9C711D06B49443E2A71B7DC0AEB3E73FB438324E0D81E93
+5387B59955CD4E8BFB8AD9D07E848E38C2E32F9863FAA440AAD9ABC1A003FCC1
+D825E1B5F8FADE481BB5356E9E5B13070D63AA63C1B9F99FFDE234C17B28C50D
+9FCBBA638F786FDA347D3A6228B61B5F726413194801C3B3EC9486E1B8EEAEEB
+B9322AB9832F69FA3126162476E549594D52955006E4A9B2726952E562A39546
+1548D255C5E6966EF60E6F07C5E076AD17215E08C7BCF6AB3C2B181BAEA7A757
+9F7557B9824EE211DCF1D3E4105DB69A9A776BB55AEDBEB563C0FA2A20041AFE
+28F8301ECDB44C2F8D540A48E23E47251E07CCB66100A98611A9A6DD311F88BD
+AC3C391078BDC7B1B0FEE6DA1F3851BCEFB9191654D427B2419E7016B6E7F62C
+A5B22D6FEC9B0D75EEA91BED9D95D20913390B873D2B1F4B3940DB0D1F1E1187
+EBF4C71AAA864723D91EBD3907179174194BDBB7CD79C70D231136EF8B6BB8BE
+47ADB2788798614165B4DFC099CEEF7330627A16BA7E2D2CB4B319728E2934D5
+4941DADB68F1C3AD870DA304E7C8AA8CC44A15F8B9BA14F12A7625169180D2C6
+02618A2A79D089B0909C24F389B545631EACDD55A6444540CA778C18C71668B1
+7AEBF82DFB1B300B83196DAF50CD5973BEF326720A9C148FFDC1FED9428547BD
+E9A4DD0075079E0D712944073DF485C4BFAA6FD7C1895379F8BA00C673916146
+9B79CE2D547F0795FFE54E18621D7EDA22C829828B4CD681968F4934F7ED23BE
+05D0AA4076ADB784215851841D4E98FA280BB5997C62C83234D6C8C913E6BDB1
+41561831E4961E39D88A2B66930CCF642F63B8ED38F9322613411700933D2AC0
+BD940EC4E4073121AA0FF4B4BB0CA59201514A97132206D384E04A490376C560
+BCB235EF089AC60F6B1C9895FC4A7B23D0B83E64A13BA1653573C1554A33E9D9
+B4B6DE94222A0D540FAC8BB6201D73DC187E8D0D4FB0BA2695BAD9947C8386F1
+9F45CECE4985D9CA6D87EDE40706FCDF568A741A8AAAC5DFF573AFFF61A3862B
+E3148B3227812D171F0115FD88570764B83702659919C2F372C9D24BF65BF543
+A62EB34432F7813F2A014574F8BCD08896A26B34CE4F55CB02DA4F9CF1962C3E
+7A317E672A42D9A9EC06BA5B10BA0A1CF21F6F4779F087CD659734E22036BF03
+FBCF026811AA2BDF3EEEDE1E9191499227E6269E4EFA965BBB7DCE8ED02902BF
+E67D6903BE5821CFFA06057788E85D3455825574D5D001E78C059489B2BD1BA7
+77C8BC109B385C4CAA7D460510BFD736937290404B0AE17241BE08A90E0CA666
+929E7B789D4CCD0E4DB271D82F912989F90CB90834B9223DF8AD24F245B1B5F8
+310478227BA1A8FF2D03E1EBAFBDCAE2BC34B02BB74842DE65276F2E6F4E0D4D
+12005907ECB4D49C635195D25D64A19F3645EDA989590210E0BA1D73FAF37444
+FDF945684232C0212EEE51434C839D14C16A26578068A1759C299B29BA0A8D80
+CB942F1F0BB4E61784EE89D737196CEE29715069DFCB80D6C279B3E4DD4F551C
+6D0A1BE85798ED20AB0C2AEB2E88B6FE961E37145D6D1BF0A267C3423B5A441E
+2566E5463718B85C60F2ABB02434BD0C7EA5CD3750181F0D1916817FD85ABD38
+DF7555C33FC9F528F34FFC371F98DE2F213DA6D33A5496EC904DFE9B6D194781
+7A7A06E47677F98951580726051E47E700DF41C0A806216B666157D4DAFA1DC1
+CE159E7E379F0C98C8559506A9D5F36235BF183A426E19F5325C1629B7A33764
+28C58D41057EEB3B45FAD2EE68E2CECB4F65F5BA025325CB0B9B55FB8055C9EC
+54D366D43C3DFD961CB0B5F035ADED58ABF3C7D76D6059F5E142921A8919A1B2
+6543FB64441C350F0D1F8E54F35EAB79636AF0768E186DEA1FAA825A1A6F9BB4
+95A8980ECFFDBD9E086201DD6A0C3986A3F0A81907F427D3F32B61D02368B706
+9C69273D09C323D07AF9A0ABD2B971BB41069BAC212459AC8D3EEE0D7BF03C5D
+07EB71BAC86594FC746342FFB8D0D058508C350666CA61F175C42F0CD9B5A079
+BE6227053986728DDF9EC1E017E405B3ACBE1C4CA2477693B8E062502672C87B
+789E525BAC85E91C99726981B5F15EC61373E59467BEA179C78594FBC36174CA
+77270EE8670AE46373D9E4AFC7810ADC41A7A6688305E2E8D8E11EA7595104FC
+72C887507F8159E1B18FA7B19E6233F80DE2276CF2265A7127F843E1205F6F04
+1DED840B310E97E38B7CC7FE4615B061DF2366DD385BE46FD7E1FD79050210ED
+FD38126BE1925ABDC95081ABABA21E9D74733678012E5D98FAC3B9A96B1FCCC2
+83C27902B6132480433387D64B6FFE66D73D6AA6EB3A323525173C946E90B0BE
+10C76B18D735243EDA3890D0B30FC41094FBF6133E741425182B0BACE55E1D14
+2311E8C5833E25C7CD017BA4059E6956D8A626F7993B8B3FE8C0B2C22424F7C9
+DB1982E704431C0371C6A342C506129783D084366AC287412D61D2F6FFCB9A38
+05CA79E742EEEF8104701513F519A64679BA60711AA6509144A139F18755693F
+225078F885A6722BF7B2D28B4E01621B8949EF4DEA99DF31E159C1E6CDAB2CBF
+3A32DF2F53F8E95079CF9083F9B952ADC98AC214CC8BCB7A04D4C9A5E6DE0B8D
+2E60F6DB353796DE2367D4CB3432D6F794CB7DFF4F9BEB9EA8E8B275C8B12883
+340C2EC8A6967C09D20FB116E2F27A7D2E6381C2A30533817790A47ADB9B7C81
+57F2EF1B3762A86B61AA9D74954DDFA4F918722E7141E1E12D7C37E2B20CACED
+62BD84E09364B7023DB0AE4FFD8C9BBE29525D84CF0F973ADEFE61CB85593FF3
+8FEC4AD3239DA242428460AC4D4EF13FF2A5AEC0883A69B27073E703731FF8D0
+1E6488ABD8652CDD0ED93C01E2577ECD1455E19DF3AB9352C84AB1FCBE6B95FE
+D19360F8DD293E6D0F759705061503922C97006B3F265877BF6C7B9C2EFA5CC8
+56442D6C35B5CC773808EA85E741414BED70B09686E823F4DB7F8FA8E69190F4
+40BEF07E6FF54A3874100107D8D5808C64B978CB0F098A6609ABD94168C2B0FE
+A41C5BA1CAA825135C983BFBEC7C7E39A6D2C0645DA68DACCF84FB2AD5C08501
+687BB99E71652CB4E8E31497666A076D93EE375990CDA920B58969C946ADC9F0
+8341FE62C61C97A062AC76699675315FC141F11074BBA913B48D522EDE2BAB1D
+27C0B5778AD48B34F9A8B3A3CE0EC2CA44C786E546F8379E47E2F6C92EA8F2F9
+884335D0257CACBB902B7A55AD4B0570241F09AE34EF609B81DF8FFAE7DC0FD1
+9508095B5B59AF4DE0CC70993EABF0FB883611CCE7230A3D7EECA1BA763BF85B
+6629502BE58B944AF96827EA3BBD17D3BE0134979AC8CEC1FF25D6B2D194D079
+091ADC62E02E86A58FF98C01E91D8D8E8BAEC7A1F89D9583A0AB6579DC6BF4BB
+A82ECE8300725F6A40FF6B684EF8D3DEE1076CE2A27F2205CC25D37E2B65E8B5
+B9C98BBF61D25F88242DA0F85893A22DF39435738B4120C6658939593A56870C
+C3BDD6B6E6D1EDDBEF5314407E4160D729F39A6BB3EE79B4C88CD7062C775367
+3B7827A59FB64C12273AB3102ABEAEF14005FA6154F5CB9EE3E1DE94AF3510E6
+B01A6059F71C20E90E1572653F47A68C0261F8EA96D65EFE3F0E130ADEEA7261
+14E85BE04C9605DECFC02360D45CBBC4B0C27924BEF67253E1F1BEDB3129D673
+4E701A542265E53F950CA525C7ADCFF99777263B36F4C8E80E6F1AA3F0F6AC68
+D57F392752482ADF6914C5F9BDBA863BB659869E593969B275724A5090D88418
+AFCD3EBDA945876FCEC394938E039840621F764773BBB92E1DCC15E1B05CCD68
+A89C124A872E8A9E820B40EE517B580C049E2ACA2F2ACEA02094F79659D86DFC
+69DFFDFB9DA5383AA1CE42E9E68B7BF92FB62931EF2F155486818CEF4AE5C773
+3532D1BAD43F342DD9CFF5E7C16982B1F85C8EE873E4C660384EC769CCBD0DA9
+33E5A85E453924E188DE515AADE9C3B3609C663FF926951B9BC51A1F76D67FFB
+1BCC26739ABAD5E14EFD7198464169878F51F56A6AE1D63F7085C07A359702A6
+02B04E28A2A0B7B74762488AEAFA87914535BCA742EAF3BB44D874D076BE369C
+C88687E3A165FC5D8A5E3DDAB5A6365C2FD7FED713DC7F13348084B1C6150460
+FAEBE385212FBF488E6407469A02DF990ACF17E12BA2FAA09C39825ABA4217EB
+7684C1EA4AC42D5EF252C39287607A57B29C30F6DCD6FE387465772A9E241561
+5AF6D64E87E4F407FAF9E8CFCD7014AD6B83140ACCE5DDA0BC17568EA0C726BE
+07F6BB90F60C7C15CB339F3BA750ACEBE48AE45A30F9B18E414C1F39FE9C3448
+C75CFE6E1AB36BBF22D323108AEC0447668C40A60CE76ADE931F1BAB4DD18F70
+911A35415FBB10373533F6546FF180EF8CADA342A5DEF702E8B154DA9BB7B96D
+51FD29C281CEEDDDD7CAB5DF94DEB37E67E41D13AFB96C89D9BA96CBE43BB508
+5D42FBA45F217F0E87A6E1656B27F7A9B0C3CB25DA3CF493CA0EED4D59F98C2E
+32E441DFA6762B94FC20917D0EE55693C86F094061EBA18053CDD028D792B0DC
+A2C506FDFF1C9CB9DE1EBBB4A83EC7EA15C20AE6B5D52F3B3D0FCD8A9EAFAB16
+3FFBCA949E2700EE3664CD503A64B90DC6B431AA3F37307D0C5E60B611893518
+D39FD898169EF2E526B734F688CE20CFB65FABD434770BD1E28A0FF21BDA5E7D
+B3CFFBD4CEDD9919898EA41BDFDB92976CCEDF2AD7F53EFD4E5977909857B798
+C793D7D0A1ED62EAB720CA0A883FA813AB7E99D388022A634613166F667A15DD
+186003112EC6CFC45A061312242800CE03282C13E31E1414FBF5CD84889AD15B
+834CE935F21BA04E3E62821290E39B2BF1F753C051D985E16BB3E452645D96C6
+34AB18695C2D75D862494E7B5173D2C77A9E72EA99E780FE7F95BB1ABA02FF57
+5C4250507F10CE82E07C635696EFBCF0E616101EBB09DD7ACA088C6A8AB62AA8
+EBA919B5CBC0DD94C3DA1E7CA021FF31C36B8001558525AF71C8C048EC9B1A8E
+B8EF4067E69DFC2919EE3BE7EECBC9641A090DA833C0154F1E2E3DB7511ED7FB
+03CE31EA7EDCDA0F7D41DCBBA00A66A7F093E29D02C3DAC1221A33EA64EE2975
+323D09C8291A0D9159648E8235E8881B6982C4C13C969884E91543FE3FCCAAAD
+513D0CD45D674E28596BEBA1207C5593E12769E79E35940FDF05EE2F331624C5
+B4F363EA58E5143BEB7D73D8475D5BD09A23CFFD7D4CAFCBB847BCE311FE99F9
+548558DBF2E1DABA5510987F836A94FF3168341DCEBED7DB8D7DC3A027D8B76F
+033CF1D63A5EBA39B12F7ACA4CADF42616FBB1978064047858DDF55A8F702925
+64F1E1B1411C0106DEE8BEEB002D64BF1A2CFA9C3DC65B5689308AF1EEE4C762
+03ED130FC5532E6C79053FA26BAA3C4484F5744806D1B5C259337CB9099BC989
+9270EA2A34672C358BE6EC6E90BA480C01117D252BD39BB4D34B61F0A9F7BD10
+F0EAAD2B40BC5840D52356A9562B28EAF12DBB56771D9A5CA39EC220B1D12D89
+DEB17AFC1226AFC710668AD895C59B545B378982731EDABECA1B173BB123248F
+282CC6C4B8F2BC77A07F3F3A3B03219463587B746DA564B14F2A3105C87D45C0
+F5E73F048902F581B29F31A0DED4C54983CD32F0217DF9CDA2348474BE4755E1
+ECF77B963A182FD015579F6C8BE70A95667132141576D8ED6532026ECFC4CDBA
+4C7B523C883AADAACF83759FD2364E4CD4A7A44B32955F01AC69378694DDBCDA
+F3A61C754DD812231642C7448A7EC0FD7DA39AC844A94C7AB2F7FCF1E9A49CD1
+AEC862DC3EF8A5893230747E6339085E8C7F4F0B669CE08B5EF9393B5ACCF9D8
+54D58B0D5C8C45041076D6B51E62DD840FAC37144B11245C1EB10010C9AC80F7
+F2588F918D3DEB35E08B0C04496840F739515760B07D4285621721084E12F716
+6307A01333DEE9BC4B9F4AA9F1AB8B3088E7844CF2A4FA1F1C33B7A2C057CF32
+DD3414F0F1D620F4F85E67A1B8120E9E63C389EC17DF4022A1E2E7D2C4F3DCC0
+572286CC2A75B5FB70D7CDBF32A180F0FAD9A338799B4CF03B62E2030ECD11B4
+44378365FACC772B7785A1ECF3F17590777F3F76F189D1B9C57181FE5FA3C9EF
+33F4C60709D6E0F2AC613CB3DE485877AD003EABA727C552679E983695E9B5E2
+6EBFD4A43DCF2AE24001FAF0F05899E380178EE1B0AEF69202A3D41CA5675F6F
+A738540523145710F8932A8EFA407259E05DF7C640EF817300864F38264A8CA4
+14A79D2C66640F9E852B8782E43E90D150F0C80DA7B0FCBF5577BED4ED71F3CC
+5C963DFB6CD49461C17593E3B9440B7E4D4279B2096AF024EF759C47DB30E51A
+76F0DD543FA66742EFBAAF78A50EE109DD0864FCD953C3469AD6EFB933304494
+91775A44562A8702C99913C5549C622EC57DFA62281CEF1F60EA1FABD26FCCEA
+6FFFF6F27E7D6576A241EEFCBB3ED8716340E286EF152CE4488D17AFDDD0DEC6
+EB05F3C9674F22CF2FA110F53AC4E33B28F0A41ED0DD549563988434AB9F6F12
+900F498466FAE983623AB034816C64C3C1B3A764F3DFD1E475D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX10
+%!PS-AdobeFont-1.1: CMBX10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:06
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 86 /V put
+dup 89 /Y put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-301 -250 1164 946}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8B731A88D7740B0DDAED1B3F82
+7DB9DFB4372D3935C286E39EE7AC9FB6A9B5CE4D2FAE1BC0E55AE02BFC464378
+77B9F65C23E3BAB41EFAE344DDC9AB1B3CCBC0618290D83DC756F9D5BEFECB18
+2DB0E39997F264D408BD076F65A50E7E94C9C88D849AB2E92005CFA316ACCD91
+FF524AAD7262B10351C50EBAD08FB4CD55D2E369F6E836C82C591606E1E5C73F
+DE3FA3CAD272C67C6CBF43B66FE4B8677DAFEEA19288428D07FEB1F4001BAA68
+7AAD6DDBE432714E799CFA49D8A1A128F32E8B280524BC8041F1E64ECE4053C4
+9F0AEC699A75B827002E9F95826DB3F643338F858011008E338A899020962176
+CF66A62E3AEF046D91C88C87DEB03CE6CCDF4FB651990F0E86D17409F121773D
+6877DF0085DFB269A3C07AA6660419BD0F0EF3C53DA2318BA1860AB34E28BAC6
+E82DDB1C43E5203AC9DF9277098F2E42C0F7BD03C6D90B629DE97730245B8E8E
+8903B9225098079C55A37E4E59AE2A9E36B6349FA2C09BB1F5F4433E4EEFC75E
+3F9830EB085E7E6FBE2666AC5A398C2DF228062ACF9FCA5656390A15837C4A99
+EC3740D873CFEF2E248B44CA134693A782594DD0692B4DBF1F16C4CDECA692C4
+0E44FDBEF704101118BC53575BF22731E7F7717934AD715AC33B5D3679B784C9
+4046E6CD3C0AD80ED1F65626B14E33CFDA6EB2825DC444FA6209615BC08173FF
+1805BDFCCA4B11F50D6BD483FD8639F9E8D0245B463D65A0F12C26C8A8EE2910
+757696C3F13144D8EA5649816AAD61A949C3A723ABB585990593F20A35CD6B7E
+0FA0AD8551CEE41F61924DC36A464A10A1B14C33FAFB04862E30C66C1BC55665
+6D07D93B8C0D596E109EE2B1AAB479F7FAA35279ADB468A624BE26D527BFF5ED
+E067598E1B8B78188FA4BCFB0B51692D07B0BEBB930C6F0997B437E2C51B876B
+61A563A2673932C2045833FAA35DB22ADE12102335D5DC734AE3AC5EEE6658D7
+92EB62131E1DFBA441F53EFF9021D9D4C491F26BE8F54C61165CAD778CE8695C
+EEAF70E3B20C64D4C2B34A084B5770BAB2A974E898F62BFE90F132A37E2DCA4F
+43E13DB13C94DFA8ECE2B7374827AE168634FA007F8981ADA046CED3448BF453
+FCD9A4F194FA648F9FC0971734BB69CB75348A88CC361FF06E984C86AF0EA429
+DAA5808CCE3583664AEFE0C59EDA04A147FB51227A5AB0C13942323E9B3733DD
+3EE7DF7F774DE5D0D0980DA8C0192983F1E3EF18481EAF1EFEDA0068BCBDB28A
+7FC7D9191EFFC574588DEC1E180341DC959F8EF56ED5B19F50AA82A4653649B7
+CDCA11A1FF27AFA7FF189A7E8A7C099AEEE0CAF3E121798B2721ABE8808D20A4
+AB6E704C0C376BD242C4966325D4C939669E28B55BC335405C400A9983B89EBB
+B13D8C5F3A148E38E9ABD86D0171C927F1051266CBBD5C5D12522AF7CC17918F
+410BABDD5FDD279338E8B17434DBF20B8E06B58D9E13B731E3C07E4CC350C431
+CE2034CB23828A19AE93124011BF053A3C5705D9BEF6D95205FB8360391C84B3
+7C6D719C0FB459A312AAC3C4256EAB293B6DC729CC5070524D1BDA41091E8B42
+2B6C4A092995AFB40CCF35730350CBA197F3D5BC5BB83CEDDBC6FBDE23A885CE
+61D416B3A6CEC46474A0F42D5B923A61832262F234001DBCED9A7A00F5511F3D
+C2178422A46CA5494AA8C37F51C40339CF9392A7098DF8596EA97C440989CA06
+EEEB5025B29EBF6038EFDDFD6F70989D63440E9C14E2A1040FAF427EB41259E3
+FF3BA255BD4C04BAAC47326181EC7CA1FFB32CBCAB92B1F8CDE6ED0DD3FE6D5F
+EE14B739FC25BB13CD94A0C0DD7CEDD886AAC62248C64B8439064D1038886DB3
+187F017A79318B69963296B4812128EACEFBAAE983646E021F24BDAA2B78E8FE
+2BCD5BFB302103D7DD28668DA7A60C446A27BFF8D6C66F4FBC61D271B91F0470
+16F567DABCD1E8B04CFBEF602BD9CE44B724B3EB8D30CE573EBB13BAA047F947
+90B24F2E49C20E2474EE9D019565E6FF25BDB3F74DF05BB9E148E1C5883A9EA1
+53AD3833A612643316CB420AF3DB29F008BA36A2EF00D25D9AA606862E0B96B4
+A1AA4BAAFF8999589849411F07E2D77946CBCB5FDBD2B0B19717997CBFD658D7
+04F62F79ED661F4D7DC87B9D27F976C7A2CCE456408703083D0044AC4063789B
+6A407EA9CBED9C091E4FB511833EAF520213B0378623279402EA99B58929D292
+143E0E986592AE731097872378122A70DED836C1AB5C759F84FE2E907BE8897A
+940785D5F56F46DE7BDDFE353A61B5B3BC8322A8310695AA9041C143EE88739F
+A6B7BB4B70EDE1BE28560F21D2A2B0A703C1B91418870B50D5C08E42C27909F4
+17CCD15D47E5F771AFC8DB660F80CFFAFA1DD19C350756444E719A0CED5EB0FC
+05B94A27F784D3F01FEBE6724039B24F3460719C5D82315EC7E7E3BD6E611C9D
+B28C9EBC83E3C89F2857F9AAB35FA5C7243F7545208092C342058A27FDF8EA66
+CFFDF8C918EC50DFD4F331732B523A288EDCBD1B2FD4961C88F9614CE987E3A3
+4EFFFC34CBBD2A96F80AD69E6598B48C84077E511939CD280206F90367E1EFB1
+523D20A15FA835C8D8FEBDE17B75F49CD0D67A4C071E7B63C5B3878BA7B6ABB0
+D17B6322FCA7C5F979EF3FC60D9F07524EF72E2D102C0BB93A7BE8CFD40D6E6E
+FAACDC3A118D4D7B112160CF5E4E9BEF9078C087CDC8A386F02C07DFC9975CAB
+75F500A0B836EC037A2A5ECD803BF9661299F4ED191C54633E4D466C2976665C
+7E360AAFA1B86583AEE708AFD51B0D73EBE32BA7C3629CEC58A1184D9794DF1E
+BB126D4D55A033A94582BC5F28A1C89097F95A50D77156A7829C6510F6E81AE2
+8B4A6F14F125929A094EC3F819BB6574F6139BEF625EC2642E42C7E6DA9B0104
+DA93D16659225E7A111A764AA3B86570F71E2ED26D55742557E8416AD7DD7863
+B8D1190EC70E8BB3561656061410EF42E4EBF7C8478C786B6A6BCB8E1CECCB6C
+9A77992E2D6896D1BFEFB93312B987F44E64C010F3F43BDD110A6DF973A32DEC
+8E49BA72D75A266493B2AB3A42A307179011D0307E727633793607716C751FEB
+0784596E0989AEE8BBFE586F7B4AC15A5D2016A3F12F8A10EA8E08F524FD25C2
+C7195F111E6BA5588C15059B17A967A6BE2DADCA51D9455DAA7671AC195401F2
+A8F9EEC851502E4B6EBAC7F4102F6ECEE8F876D3D591926EC7E46B19F950993E
+5F275D12C48C50ECAD497517919BF85E3D196546E4D1A416752283A0C986A4A0
+09DD4995D66B1D8C59EECBD736E514809BC3D34AF7749B11736FB88AA89AA39D
+5F964E12DB4DBCD25CC750B2821BCDD4E012C1900D64F3D1E4D8CD0850660BE5
+CCD101D79FEF25B3181F18B0421F90EE1D7E5CD5E4735974BA5A6943BA7583DE
+8CD4C21B230CE9D98DDE7992AE64E99EA041B8138A01053C2574F9B0C50F0E45
+01189C276F3264B6DEB4105775430A7A4D8C0550AAB0DEF33FAE4C4BC637A21B
+71712CF7EDC45CAEF1CDE6D08D7E615BC47919806D84CFA35F886EEC4C8404C1
+104DDA98A2E1E17B8692FA5F5CE7ADAD126A4629C26F30A22F3A76A512056560
+65FAEAF40D2A3797066795FDA6895F5349C3D660294FC85D0522618BFDE6BDCF
+8D4E5C32AE9CA1E52BD3EBE6948DF98F43AA8DDDEC63B1061B2F8C8BBD8B8C7B
+0DF1E941CEEE366A0C7D1976E59DD67ED5346F90B6EF07FE1A0EE6967E1507E6
+510E7C9051849D50F0A7E9F4FFABB2B995EBF4DF570645FF6636DB9BA2FAF466
+DEF21ADC735BEC2AF45E4113D1A89F0CC116E198B5709BA71FAE4862864EC28F
+3D86DB74FC4CB0BBBD0376F1AB6CE3E07DE6C2979F8029CF13DAAC74A0F04BFE
+3A40D748D63CE5B5914C0881915C5B8B060C79D1B9B6A7C146057196D855B5EF
+02C0E38B0EAF41EAE4D23C4905C1498723970B2C23EB775FC79E9A0E0C1643D6
+2EBC128E05D3EC7D9761CD58C39D4E722183F52F1C526B303EF2786D14904D26
+BA90A9166980368873999F208FD0A768D0E3B934A1D3DE4A097B5E5DC7869FC0
+9334DD1304CF2DA83FF18C136EBAFBC50ACC540D8DD7C321536934DA89A5C666
+8FED4A1D82DD9EC0681A19DCECF5C4D606B1D6BDA9459392C1BD6348B90B912C
+CE7262705F4300D20B5BFA5A6CDCC843094BE16D9451F722CA8071F40D2CF4DE
+F47044201547ABF54538665F627671EE3379AE20493A5982F3DEDE997B7801EC
+6E07A873DB5BDB95C82844A6BA927B02B63069930B590A2E62EB7BD5A02E8738
+61D0232A38749A52DEE13C8A2317430FC649FDB47AD5006E43A01E87D1A313F1
+189F3B463D86A5A6002D4B0FC9EFA9773D01EE89BBF9D559D212440892C53ECF
+5A768BF87F6E26E9A9B8B4A57A7B29312D9A48B085CB6D60FB388B149B1075BF
+18EBABC575A5A2A993FBEE137FC0DAB27C0B34927C9D7A4D5F491F68B084068B
+A3A10F884809CD1F38F6EB69B020F4FD54DF69F5E3D5F13D5713C75B01A45A4B
+291A5B62641B42474A3D7EC798EA07CE27DC61D7E7F8BF0A0C1E10314A3457FF
+E11F9A1423BEAFE227CF8092D429E0F14909D74EA31AB4292D739D6CA7663056
+E4E95803A994534FC8A6F7F3AF00B60D65E3262C1FB3307CB237E0E092225DA1
+25A69354D72B51E55631E1F0568CFA0F0778AD7DF71A4001B432292391987892
+997DB3691A20C0809253282200E03F02D11E486B7D93775C34DC251E5E3DBA71
+CEEBDC0CE4DF094CE610BB96CAC47541C871A6FBC09693B4175465239F109E2A
+EA0AB6A5393C1F99E75531880C40D6669579DC8834B2D321416D2EDA99060794
+F82BB7BF27F494F5BF149921D2544C7187628AE353B5AE33FBCC8581FED745B5
+16293342D9D80E9736C76A7A7A8C16368240144D402A089CF4BDF4129054FE6D
+F04728A3D9C7C1368FFF22658C5F76C2571F59FD7EA643D107349B916C9B6D23
+3C42D236FA3DC633C62F7D0662F0AF0377A5AAD963F4BAEEFF25770B646962BD
+E669DA4CC6E7E05441FF73E1E50B31A89AAE2D62AA1B1947E42F0B5356B689E8
+2434DC9234A42CCC9CB68F0F906ADC01C67A79C1A645D8CF74C261707C33EE2D
+09314A6FEF969D88415575F1544898822BC381D2A7A81EEB6CF5320161F5F372
+F071B2EDE7A30CD6D3FA76E95A31DDB7737481B1F092F14904FEA7D3754E9E1F
+B4EB8AA8735BA8062D2364A40A54BA4C78C8275C0C7429DDCD5E045A6A1A3EC9
+CD51B2DCD90EC791B08E2550C5071B586A14519B178D2340F4694476CDC4C604
+DE48A1D557F99483088E602BDA970DDC07E238C17065420100E5DA30B07EBEC7
+4D46FC4E1A4A8E9206553E927C63CF99AD7C318CABCE03B6D7EEBEEA1FDBBCAA
+8ACEB7BF96EF6268E82934D32CD3A9BCCA08EA7FFB3CC320BB5FAF6B2F7202EF
+32493724223CCC1A8A0D76808DC97E89ED72F5E45C64E63DCE06603C918B4564
+8E942314A50DA37504CA704039BB9FBA4F79A78E48F65238FD7D924D9423C9CC
+A63EB75ED3E127E9C62103582A507A2837F54824FF922A19498527F46448394B
+8F9D09A132F260F484E88BB56543AAC18F07AF27A276210A2B1C84F1C5DEB002
+8BF3652C6D6C32949191594F63C166AAF66F7F26CCCBCAA659115AC8F977D8C3
+8E5A6FC1C7C27D3C52CDEA11D7EA3F0217AE402965732CE4EC4E5C8CF2E4EE59
+3F9DE39269BEDDAB9DBC642CBFA3A49CD0448E439B63EEB766B8113B5061990E
+161128940AE10E435DD0B7A539E77B5B4971AAF5278D41853A196A779ED62E38
+6106055CF481A00B8DE50D1A4A93A0D08DF38A3261E62C4037C57D75302D924A
+EC5336E2AE088711E103044A9A35EA1F861802A731C57D5C04C9E79DF246CFA7
+9D1B79F193A3D103FD179ACF217742232E88B465D9E8EA746D6D7B1D005C590B
+2BE4C2E8FDBE3FEE3A9476A8AEDF122D73D4B2AA3E58A41F41DB37DE4583E851
+BD8F86F9CDE513F58A9001B5DCF01F22260FB1758BC51F317ECFF3993C576BD6
+329932B44B8C5C4B5AA0145AEF3ABE845BF461B34D65096ACCF7209892EC7CEB
+489C44BC2F5B7C23F6382FDA0ABE68E8B112BAFBBB55B51B957F7B90032D17B3
+5336A76E3FE324A1E3358936E98CCEAB0E6516CA8D060A669A35A06FF466B0B5
+E528EED39667893D9AE0D353F05EE3041FEBB4F38AD7A8EA17B76F209B4D92F7
+FB0EF74DF97F2C5F4813E72EB63A2BBCECD65550AF85693F7FDDF9B5EC16287B
+4570F0775753530B047DD04671BA910FB447F686CE7F999A0766C95A6DE9FF4A
+1E9EF0CC43D14CDB46BECC3FC6548D95A978DB644857853F3340862227DD2354
+5072CF0D7050E5431E1DFD2FA15BAAC284151488D0ABA88BD718551FD7D36F71
+1507667CAED6ADC861E442CF645AE3CBBC789E949DDAF39437A6352766DA4430
+764839822DA891EEE1D83F732DBE943A2F03A61480ACC77660DF405608B0450B
+CDE772D1BEA4D2912F39C29AA78D8EE35B7402711281BEEC6430116AB3551843
+F4654829B04540AC9ED8B20A34F7BA5D11B0ECA89BAF6134A4E0FAC945F6DD6D
+3561C4A3B1431AAEF64C12ECF0A51ADA579BD082AAD93781FBF55B56855A2868
+B0839CDE7F033B6A7E68CF374A175DAB6E017C241CB9A52CAD316903D93AC6BF
+C9A5206D972E405BEBE2FB1E0CACAE44B1DBF8B704DF80B0557E1CEDB9C5A00D
+358A1E232E8AA9A15A6E5E0CDC3F13A2689B157688579F88EEC3F0F9795577E5
+7AF18B0A6B3F810BCA3232CC7C6E7C13F724589F0A0469FF8A5DFAB7375317AC
+E6C074327424FBBDFBA1D75187BCA424932465D7AEED4EB29FE30B2B14832110
+DB02648E509BE11BAF600D9B0DF493B5E00ABEB977D8C6D37E4B614EB385A11A
+AB12D8B0280ADF9EBA79B10F7D0F042698D353617680B066B9BD8DE170D2BBA9
+7AB9EE51F18180AD84E95C168DA3AB07DF7D548815647B6DF9853A5DE14D68CA
+FF85B18233634B6234EF540C368A32ADEC2E734E87E7718289AB66745763EC58
+0D5D0C6A9B5096633A84CCE8AFA9737BCFADD9027F32576CD7B74123D6159077
+5A9AAFB82B6975FCD8DC92244F7AA5CD5F9A5ADF9898EC10549B7B01C585C5A9
+E1A00EAAD335267D628E8845BC62DBE5D2199D96DEA73A03626B7A245C61B55E
+1E7A037B7244C62F68914118CE521BAD8B3A73136883E98514CB6538F1A33AAC
+6390F6D2DE3AEEA9CC566A7CD3F5A0152990B390BA314452128FB2AF0AB4BC14
+7CC61DC0D2ED5C91A07631AEA7172B2E0E4C377BE1C529CDB813AE72F73A285E
+A608E889E0BA048909CF36D852456A83D1136EF1AC4806ED8FAE3A40BCCBA286
+2B73C68082E7FA5606046A22CFD608EDBBD7F442967F88F4EDF7D61A48CBCD73
+EF8084307DFECB1B834FC03C613A3564D2E47D6AAB54528402AB6156F76E9698
+31ED512E4C6709550849507FF36D37ECA05AE5F0F4C64DD3EE576BBBE4079503
+189BFE7F5C01830D285AA4183CF942DF08EE8290A3C4C9E8D393F551F51037CB
+0D87FF5AE177F1A67AD1EAC96116C2C4B8436FA9DD3BDF8F340AF4FB9CF9A7A1
+640C820A354D1401B848D3089EFF37048C4D928A474ED10EE0B6C60C7B885515
+0CB1A25BCF66594ED4026C446DE1BA2D561BD253B907B324C79C1FF19C209F5B
+9985621CE7596916F23214F74C55BBCAC93ABFFFF13DAB33B116B410F3B6EF3A
+9C1A4F44C2BC3A96A6FA3F477D1F399F1E04A5EC2F3F3256487FAA61951EF6E8
+51E2F89E9B4372155FDCC61F225BCD7E8839B4BF4DC26774827377C29882B782
+F15D63DF628FC02546B67A52EDE501D8966AD00B7B85E2405F5E8D7F151A8367
+A0A501FCF6E98078AA95E1F2A39E507475C10BC23247907B40B471B3FC5DED87
+577F23FA2C652CEA09E5CE3805A450D4524AE26B59C7401DD474A01961FBA3EF
+F833B3198AB10E4EDB9EB59241A9E26C29882989B3FCC261C89D898B5EB4D4D3
+C09F11FD7AB94449AE249C3842D4A1853B4D8D29EAA9CB7ED649619B8813BF43
+6B9C46163B166FB6689004022D143E7FD9803FA05C6848EF3B61A40DE7A93BCA
+B01DDED4796355BBB69CCEE2746BA1613A682769435FE26D0D8279CFF49149A3
+78DC2608BE4AFAA792101CD0FD8CE284FC1835F964578317E3358183B07FB5F6
+9625D0E8F7BC7BA99828A981B0771C44A1FE910F204C63E8437B364EC4CAC62C
+B54BA2AECF30DEB60C80C6D7CB45C00C7045974C5166DF72EE414A18B77ACD14
+6F5F7E12F51435F3F5D6280F61F8C027C8BDF7BD338FD84C84ED84B47CEF6EDA
+78941D5623506F1BAEF02E092399D9288C13B7FD7C98BFD4B398FA6EA76CDAA0
+8FAA6EC2E4B9FAFCE1CFFFC883563A11AB7EE141BBA45A372E62CFE64AD60E2E
+856E93AB0507153D4FE8C80060C8572FBB64EFD044E8908FA7AE5152FC5A2A54
+0DC576D679829AAB5D60AACB61E5E81F5395D27C4C43CB4B2A847755B072E916
+A42B33851E6510CBF1627B0AF8FA67DD94563E3DA1D8226FD25B61EB926AB12E
+F736BD697ADEE50CC44A5F71470770E76AE89846769927259907DCC3E128C982
+9557153F1C19AF0DC5A0FA8BE3672866154D9D1F026F0C60508C8EFDC2135107
+6676FBE69C17DA13E273946F80DAB620F8332D680AD46537099B457CBCC08B77
+66D75D1EAA0EAB9E8EEE429B8D6805A7B304B3C4557AB4C9F5F99A5F2B559A7C
+185D2469063529F1C6788D79D497D6055FDEC230751C1C5A8C1911B7409E4ACA
+D8A13431C2AFAF44D8485C59C4F3ECD11DEDFF969B614CB0ECDF8B0622A10982
+F36B66CAF38A0D064D0EB9147986DD43E8E022CEF1681A914712BE66DB2DDD22
+565F852F6CEAD759EFA0475DFB3054B12D58A052E949992680F0E22EC393B553
+D5DF16E684B928CCB2A3E5F1F41DB906CF8125936C070308DCCB60A2C7CF0C99
+D1D3B880DED82E7E32A889017150124EFC88BE3181208FB6228CAA3919F69D80
+AAADEFB2421887027F822A13C4D2E108B7DDE620A6F56D7E7E2C32AE2FBD9B9D
+1C80B62B1B86D03E84B64A95542555A04516953F1828B16E6E8C3CCBD9319F8D
+55001CD1E82406900C25E73C0EC3859F450C08FBBE7428BCF7629DBAD5BAD9A3
+75B72AAC95318F861AFB52BC3831421AF8F9797C8F38267E90C976768CD10497
+13B77F14285C32DA23B4F97C24E8C0D9CC645BC093E3FD237EAEE0F55BA1FB8F
+37014723DEA2583E071E61E88C1105381431D5D29A9980A79ED7447BE0C2B836
+8105177C8217C3EE6DB289AFEC6C7046F10FBA62AB2C6B7D1D1A1FFCFB940A8F
+4DB600E9731E6050C2FB6A186F9315201A83AEF9AAC719C283775F653915FC86
+40DC2A205062E7F490495AD6C3F135041E9DE1B3B6154172BF9E647F87F5083C
+91156A75DA0A57FA4930B646B3703A2790BFF7CF49283C2CEBB39BB63BB39D8A
+61166F64713DBE3D05CD303BAA34A686A9EEA6FB10E2B6B0B08795A86A3BDB95
+09E6F08F32D27B97C23F3386B4B7940997CDCE0991430DD00CC8124CDFC3E0DE
+66495BB405CDDA47AAEB46A0A5C857D3B867FB3D847A3020E37427C2B403578B
+D30F90BDAD46FB913C057637D5FAEA06B2760766870CDD99386561C70BC21668
+03873AC26EBA0D1ED46C1AD9AEEF1B9123970C60E7770A97325B94F6F572C992
+5831BB0253DB542DDE3D9546BF991150600758E3E5A1D4BA40BEB56B709E6C80
+295CA4E20B46C57E6F414EF03971C13661229844453A960007B754BB84678039
+211803A4880DBAB6AE1B6B76263D26EEEA8845F53EA92EA6E904F0725F96F34E
+CE6D64196E360353510DAFD4AE9763B3686AEF2AF2A0B098A7056A663D52D881
+D03073E80FFCF47895C4270009770460A9719AFDB8BF59D5A12E24502D12E507
+96864083B754E889114BE8FC15D9F6867DDB8EAE5EB7AE173020A148AD4DB668
+C400D091EAA6EA5D4A660DB78BF7BCFD7339EF9F7E34F5029E39BD3C3C610E15
+4EE1181388B4FC544C28040BB416AD1FDB1FD7703E478063AF918437D96357BA
+F1EB24122599018A6C8AD37E4A902FA3D3041E3D7F3A2F4BB7E7BBB9AFCC0906
+5873A31DFEC3D437835CA0479B20DC4FEC2E283EAC4754E13985C043EDCAED97
+25D9E51ED27EB8CA29B1E8C51493BE08AF34C2E4406362E5EDDECF85F06DF945
+F074D6EA7A5B606DD3D7D6E81C96DB690749D54633F471FDD2EE9A1F754AB6E4
+B4DF7604C3DE0840BA1F58CBE0FB20DF2C33D975894AF9EAE6C63461DF29072E
+AD4CFE0E97F57E2B457C32293178519CF9FEA669D63EDDE08DC55581060333DD
+5196DE5EC144364557537E0E869D02A9CCF35D930579E21ACE434567DAADE92A
+503EE8DEFA0C4C0F7D2115B8D803C8746F24A1CD0ECF6F8EB5A9DF8F3E601A90
+42165D15B55B9C53C622892E7D6C26E67CD91AE0114F5979563969FDA33A687B
+C3825AA15A79091642DCE0A132FAAECCF9590243E87956330F09A776175A3C2F
+C651E89A73A9E1EF387AE9FD68BA48660E0B8E80B2E84990586DE7FEBBE6481B
+E79DF22E50AA118CC07AAF6D53C5B612561532E7B9486CD0E2428D871A7CA4BD
+6C797A665DC72C3D925DB2208586EB735127920CD5523DC59501E62D0516AB34
+B48A12891881C5511B4781DD8532F998C7CE305DC9E7C879F3C59404F21EC643
+9446AF52094211E37631D6FDDD3F010755EBB0D4318B237C7B8E5B892A1CE8B8
+3DA402E41FA2DCBD21543B9EBC7311DEC1559C0D4B477B31C9AC27329869550B
+5AD5F31E98FBCD6294C0067C9D7BF7FCA97F03810025F64C08C858A58DCBAEF4
+23CEA7081D2E35F13E8E2F94CCDD325DD9844BB6AF8CB7D8B8EB82AD4D7C42CC
+38265F74CC3DE12C249822038FE84EEC468F77A333369136768D4A0260D18E8D
+AC6E55C8752B4EAF17E74BC6C10DF86383B6CECC66AD367C8A485F9333AE060C
+0A4FC60DCF85AAC2DF16BE84E8472DC07CD4B8FC0F8B860BB9864925EEF83DED
+B4495813D0ADF6E0D98FD8AB87C65E681CE71B4782BED1B525B595A59C5273E3
+B5AD7CAF306E6E0CF7CACBDF910ABF94DD6AFC4F0CBB729F0445FCB834D63BE7
+51D90E072E9CA8CE0893DEBE52E0A53DE4F3F447C58DE0D13477ACCDC7AB64B4
+E548633227CDBCD82E4C010070E2A10DCBB2BFC5FB90C0782971D509B3864A28
+A06B0DF9044F356D728DAE6831488B8A0C15E366CAC6B390CBD68E5424C6F5B5
+E1F76E015E7F1C2A97FF0914EAB3ED733F72659DACF61E63069205706F50E0AE
+AB9C5FAFC8E05C87FEA2E668F3B38AE5EF85878404BE1CC1EBAE25CE6489D033
+095DE9BD116A56FFA093412EE92D4327CC3B45445CC0410DAFF51EFCC032A24C
+B8297A2EEEA06D2C27F73E051F0CA4BE02E3C53018AD869BE707BD114C3020AA
+F3BC48D08B2786EEC91E9C018371D164A1B5872A5D7251468A60BB81B75A04A0
+BABCAF0B71A0AB3148FD9CB93978AC25055946048D3625364E9875F8C05523BA
+BBF68378FF985BBFC0252191790FB0ACC846D0B7396B914564EDA49586F3CD3E
+6A187DDADBA664E76B4EDEB2AA8D47EF717233F7428884E8BDBB7BF207840622
+AEB0CE00A2F046B8AF798FD593BEDD862D00111B84B2A657A30F68DDF92F9E98
+B40D99CEF5DA140C1D3DD28AF14C94DA3FB2BE4121977A4EF2CECE55A6D8ED38
+5F1E5A43A64AEC55F4D5A0256453F0559DA22A5AF1C9DEA56B7B1592F650EEA3
+8FECB0AC1CC54BB64A36DFA34484765A74A2D6619C849E84697001BA85A31550
+030807484E3F2DDFB9299D4BFA52BA93EE7FF8F788CBDA374C9156466124E492
+C80D94D5A377A270A6BAE28E2872599223080BC9F665BAD78D8A46A67F466158
+F943C31CBFB7B294DD0204CB0E1AD04B9487AC550C4F8815AF19A2EAC52AF5CD
+640F65E4F9F22C49A56B581C06A03CE7B68FB398FFF7332E74FEF5F6533CF525
+73727249D1888FAD0383C523F6508F5ED8EB9449F2D5AA99A04B093CBB38FC43
+CA3FDBF847738F0D40F5D57A9121AC7238788D0E96E09433E9F8DF0287C970E8
+E832A9C206B332E15443A2D23FA5FD2BE4370A0FA7AF8DDB606F6736725CFEC8
+31BF024FF9DADB6BEF610A2034490BBC95B4CC6604D9A39870540652DE6F99DD
+E703113756F1DF3A6554718866254051CD8C310D8E96952868044E945A29914C
+1EDA47B12301DA809618412BC1A7A6CD7668778F7732C223304F88477AF1F9BC
+071707D9B2131A966BED3D5F06E083B295DB919277D6A336FE689BDDD3C221B2
+37682D2998B5DFF0123E87596A85DBA412B542620426CBDEDBAA5393AADAA221
+42167CEA7B60888D9D7AD22424A60A5E54E7414C8B591F4C238A4CB278D2B7BB
+D2425638F23BA2EF8F1D87E2AEC76418B7E6F2427BAA92EB0D998F07477312B9
+E67394C2861036328B40EE689E3AFC556424FCAFA263D7DB40814A8BC9D160EB
+DC3F62DD78089BC292A78EACDA0BFB3246B065E670038148243E331D53B318D5
+4AE78A620D3CB22DCB80AA7368718902B72DF0771F6DAC80E7D605CD10BFF85D
+E26CB4E653AAD36AB162FC2424FC3353D3E57B07A509B1287C3399F56163ECEA
+2CA1AC11BE9361476FBB65C99EA7BF1DAA607ADF5A3D5113F230567819848912
+B427D8183AB4D4A28760DE738CE192DCFBFDB421AAF2AB14F6E3E83A602EC907
+BC8B4FE0EF9FB6C4163537B6B6A9E2248E4A9D491E5831D0121C1DB6243F55C6
+081295E06D6FD01C107CA8E2AD4FCB77CAF127240A3B0FE67F8BE310037089D0
+7F92005B068F1ACBC76355347C5EC6E370D773D6FADC16C74F31300A0F4974B8
+7340C89DEAE5DE97474F2281FBCC9EE2092D75AF7E9332BA71363750BE083427
+EC22AB844AFB76A8DD7E521D932E9AAD7D73909E8C67B427E64D4AB7F07F117D
+099272F97DD809791E1A1B3C098AE75E00BA58613409365823D0D9E541290439
+1AA98D4CDA14DF3D931554ABFA51D4EAEB13D0761842C243F6F9998F83105790
+7F160341B392045FB7730BB21F0029E2B1E2804373E35E65DF45A0B3BCB2B038
+D9C5B5324A031E0019B003488A314F0DB4F83C6FF82CDF84B3F1DFEC10D471A8
+D2668EDBB9DCF3D7DC4334B2799652D16F49F67164FF668B1094E1AE0CA5BC61
+110C9FE775954D1DC36848F9135C0EF8B99B17D75D929CE94FDC285611299029
+7722B0C3938094A49DA4DF04082DA0B0E944
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR6
+%!PS-AdobeFont-1.1: CMR6 1.0
+%%CreationDate: 1991 Aug 20 16:39:02
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR6) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR6 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 46 /period put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 54 /six put
+dup 55 /seven put
+dup 57 /nine put
+dup 59 /semicolon put
+dup 64 /at put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 74 /J put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 82 /R put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 121 /y put
+readonly def
+/FontBBox{-20 -250 1193 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C
+68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361
+3645B82392D5CAE11A7CB49D7E2E82DCD485CBA17D1AFFF95F4224CF7ECEE45C
+BFB7C8C77C22A01C345078D28D3ECBF804CDC2FE5025FA0D05CCC5EFC0C4F87E
+CBED13DDDF8F34E404F471C6DD2E43331D73E89BBC71E7BF889F6293793FEF5A
+C9DD3792F032E37A364C70914843F7AA314413D022AE3238730B420A7E9D0CF5
+D0E24F501451F9CDECE10AF7E14FF15C4F12F3FCA47DD9CD3C7AEA8D1551017D
+23131C09ED104C052054520268A4FA3C6338BA6CF14C3DE3BAF2EA35296EE3D8
+D6496277E11DFF6076FE64C8A8C3419FA774473D63223FFA41CBAE609C3D976B
+93DFB4079ADC7C4EF07303F93808DDA9F651F61BCCF79555059A44CBAF84A711
+6D98083CEF58230D54AD486C74C4A257FC703ACF918219D0A597A5F680B606E4
+EF94ADF8BF91A5096A806DB64EC96636A98397D22A74932EB7346A9C4B5EE953
+CB3C80AA634BFC28AA938C704BDA8DC4D13551CCFE2B2784BE8BF54502EBA9AF
+D49B79237B9C56310550BC30E9108BB06EAC755D6AA4E688EFE2A0AAB17F20FE
+00CD0BFF1B9CB6BDA0FA3A29A3117388B6686657A150CE6421FD5D420F4F7FB5
+B0DAA1BA19D638676E9CF159AC7325EF17B9F74E082BEF75E07BB563C96C0A3E
+6D4DF600BB73729BC4A5B134928F1370B9F07C587F79388B1D9AC62BFB1566DD
+CCBD1F58ABBF1F53AD21E3BFF25EEEB046F66A924E5F431EBD7228050BE2DF43
+0B9B538DAAD511EED97630CD9A9C05CC49DC251325A93EA842C6D07B44BE620F
+08E66B611F54314B0177E299304F2294F8DEDE9914736944F125A50B5007373E
+588AD80D9983CE7824DA30CEE5DC3114D69D7ACEC0758D8201805B82925EF216
+BD209C5FF436AD3D4BAC20D6F214D9F89CCA7D963A27C231A6B5D4CB1613AB6B
+2B9A74603C2C27CDE0482B706838C3C968D63B077CB589B6AACD734CC4C5873D
+D0821F16BB4572B85A0B669B65DA6E4B7BCBF3016ADFE80C0FE131DF9E55680A
+7762E47233779AE4F61F0CCD20E3747C1B023C4CF08F04194AF4B6674B208B26
+FEF84CDA523C3C2539A82CA8C4248CFAD0B65D64C40D2A505A9A14DFBEA1B1ED
+F63CB30577AFBE901B77B11041D98FF728DE220FC017F07BBFCC6EFB63634626
+67A03FF6E946F4EE0483C34BC782C6F94E0CB7C4096AE8996135DD720EEE24A2
+DCB1284C445D012018E6960BFF60D78392A6BD909F1F6D849C989F6DDEE426B8
+6C1177103EABF2D3CF3ADBFBE2F8BC630C9AD3B101FED93600C4B88C5F105D85
+A544D61185B178BAACF327A94FED7F86A836C268266113E8D9B26B5E2F3A97D9
+CDC32259261BC4FFC26E7F113672168A46B7542EBA62D0C524263EB27A117EAC
+DAF3141E2D1D963552F3E54D973DF1F559C16A5C2E75D971B5E8D1525C269013
+9DE947965A70E81C4B7952BC9B8A62AEC594721B6E10CC96C106183F8113EE20
+09B8B1D0FDBF4E9385F33C183F23DF88379141920BE2BE049F2EE0FF83E52CD9
+125596E14FBF9689135EB9BC926F4359AE2364804689A11C963A1D06B9839125
+DCD6F3419FEE9F9E8319140DF508540FB591CD0B33BD6137FE2874B931F810DB
+589CB9323A7F14E92C3BF41768D34CD59F9E0DCCA83A64AB940946DE847687A0
+C7E45EA858A260DF5E5BC92C1789F5B1BA8C7F01AC9189511F3A34CDB3EA203E
+6365B832BC84E4C578AD41797AA86B1DC362E9A9484FB52F1F2B5B3857BF2968
+0AD18607DBDD6250FEC6057265431247B98960126CB5C358B99586DAA488D12D
+6CF6BB4732803B407A32ECB88C4E24D484255A5E197B67EA9F062ABB466A6ED5
+F15C6E27B892D368060AD5ACFD625C633AC492C073E0FA92EC7EBBFC0652066A
+D0E27513EBD0181AC9EE867434CB87FB6C3B1988568B6C3D89E288F39CC702EA
+1B1F6861308D6F1137BD59B94A45B46294B0659BA579BA61AF2A7BC1785E30B6
+0C1CC24B10B50615BA0934523F700FE57834CFD6944E1A750B5F9BFA3490A010
+6D92A71E6BD35122671DEF37DFAA83CA6CD176BD9C26D146692C3C6EBAE3B489
+E76997CA21191BA944083285ECA76EBE94E470949D49B8C646856B3C879E6689
+1A093FCF6A42D46FE224B007AA995177B8E697BD4F1E2A29F0D30952C842AA7C
+A6BB0960CBFFA5EDCA5919174BE52769A8DEADA9398B1C7584F80E52237D9798
+1F81230F3F1260180F49F856F04E72D02C024B5FB4AAA03133EE18DAA05692B7
+9FBF64466AFDF3536809D4863EDBE1B9AB81200A69FF52AB355D08D5D55DE12D
+0D55C507D8C561CF9D3D55A5AAB2039986AD34CDDF8E582801D61543DA4CF1AE
+83E2BB0531B3E42D6594D8F4169CF187AA568688D8FA65ED8357191B4EC058B5
+CB47859857A8225D775CB3E972A35C84A85821C3BDAE9602F41507D30A7BF575
+B1E6827CA9FC6D7A528AAE10C50C6C4FEDCE773E5743D0790E10B0CC6673F956
+8A642A35B251AA31E8AA9871E79E3B77FE556C4D9E5E31AB58298B58C7451762
+67CA429EE8CF8F47D6BAC28A3AFB0CBA47C08033A45F33DFEE8BC4E2C3D8B003
+CA46F7AC88CCE2F3FB89D75B4AAEE56A1B2BC8C05CE88A6F28B901D2B3A0A2EB
+B9AFF04424BA1476C8FB008DE558C74114B2827822B9311726154507B7B85C57
+4F6E90663C8151B62A1471B273E52C1C2D7CA31125CEA0DB8EFF71711EBD35AB
+65F020D486F8FF8C94764E47E244621F2B6EA2032DEBB8D29959D86D5A74FC44
+ACFE94E8A9C5DAD6F381AE2F3D6F79E3493530B348E4F90D2A69C4968EACD81D
+C7F851685D0CDB5B0CF33A9383B697C2993915FA01744EB98A35DEF685BDC574
+A66FCD19585679B181A6CE4EB42C2F1F0DEA01084D46C0C5842ABE7B4B0948A6
+283630E84201362384D80CD0573936E601D8D993783739153649D3B9BC7C1218
+4356BA585BA414E8799C9E9DD506E7B9ADC3AE3BE0460AC1A4E0ACD570B1A780
+773A1F7E0980A15439949B4170115A6F04459E8D1793731D04B52DEACAEFC64F
+E17A4B3C7320625B05711B6CF1E38BFF5357DC6364BD2CFED6F28555CC9041BF
+3CF4B52C413B53C48C169490E91ED3547B05034257A626B6676096AEE978BEBC
+A286A3C4AB3B07F33E9648C31F1E3D68FDAC2B8612AD55CA25F0D5168FBC7FAE
+9F3DD37A9855EE0C41CF8CF089B916B37D8E8C1738D99CC19193BF6B25D927EC
+E0410496679FAF5957DB5C910A06A5AAEF993B9D6748DD3B09033C312076E8A3
+CA6646E22A83CF8229CA5CFF432D5F0CDF914A0CC5CAC5D0ABF779C306E7E0EA
+E5FF8011CD264ACBA1B388165B72111854B221DEB49AC4B577E4A1F6B7D9DAB6
+07B645D223BB35036AFBA18C99C7157DADA7CB99E1D05A0D6ADFCC905EC0AA50
+0B7E03A1A96154FFA174F8118DAC7AC66015907DD8E141932DA170B56ECD039A
+AABECFE29F1D7380DF65509AD4BA93D76CD6D7CC5C3AB70B80E2F94EDF404EAC
+376DFA48D1155F2F5DAFBA71362243E1DC7023314A977549FA0FB64C0E973725
+DE4A2FCD067A0A51915D8F788DC8092116DCC3FF5E23E4D935E59237F04BEA83
+85083330FE527922067B6EB1F09716D8C5A4525F9ABEA5482EC28DD13C222BBC
+CD9E05D435E1923E8B3B42CF85729746E24095A3EADCD06A845F4C2AF93DFE6E
+12A563B0B200EDE7E6CDFF5FD0724374126B1767FF5498467E0D49C4A07D3770
+ACDBE62159BB1898E2B433DB7D629CD8F3F4C2B9392DFC0C4ADA5BF9B03710D1
+68011E3154B61A6A38D43797F33015E4E97F2C57D3CDD8295B0E7EEFB1B1F8EE
+F97AB546EEE447B356ABB06EDC324824438A5287821BCB7E7A5338EB36DB768D
+462E008469FE4BADFDCAF7AADCBFBB63CFDBBE5147EAD6C5AF942753A9A7D2F0
+CB6291EE5441F0C6F3AE799826A54758EA0D4F8EA00F2E450D91474AD4B3178B
+B65A6D86909C8242B814F3087557B4108F0B052708257B6CDEBDAE931CAA2295
+32B3788FF3AD4E3833D247A2B86E067B5175B5D157B7A6D57FEE783269146078
+0C9259218F6EEEBB2EF746DE074FFF5066BB8BBE4694E2FF8FAF91C878DBD117
+9465D65A881AC5CA4C74778E41739F2A3BE03A33FE49FEBB98E90234DE4D835F
+97A3DDE860E4A30DEDBFF61B36717DD91D5C9417640B0E4BA31F4F8494A1F645
+34CBB593EF1D1571BF27FD2A3F81C4F1622034FEB55C44D2852BCF4B7571249A
+2C5D8AB60FFCD931370D747C7834776594450C968AA7DD5F1D491726B0B22469
+E5ECE0FF49B67500A78BB012B1DAC77B58D4BD311EB394C4A7AC27227AE67211
+33F3D2EAE4A08D62413AC73058BF50F2CDDDD4D655AC737DC8AEAF2A8B8F69B6
+2EE5432182EE306FFCA3E777225D500E02D54DBE5E271AAFCD49071A3FE3160A
+4EF901B61EDF106059A368F3640A432ACB6C0C05E2D7511C3AB6DF1F9C032F27
+62E017E03829D80AD3B6FF3A896276DE7B5264FD0457C490FABD47C79F6B9988
+6A2AD7761C70593A43DE797FB02C009F0FEEA3A52B53E9BF2BAE190FF5698A13
+8DE051DFA8FC9C385F7B0CF002351A6AAEA542D6C4FB182A103CBFBED0777CD0
+A5414084C2BB56B0139F19DDB06D7C99F676CB42F10FE4822D0FEB145D1BBC3A
+90FF29B94FC74447FFB54888E3B45611D4683E9FF329A47DD6B4D2B6AAB98357
+2CB2FE78D0DBF36724D0C42729B27153098B077B08DFC9404CF7A0D3C586B48C
+4049F8E66CA713E797FA701FE1DBBF06C900ADD95F8138359DE83E9217AE928C
+B1DC6853E5DED8A685217E50AF484C2AA2B784F14963CEC41E66F203B8522102
+A104119C2D413AC44A2DFA900251C64DE8B0EA2E3EDB9658E2BDD53707FC60BA
+CD9701B4E720EE584577BB24875E385E66A3BC154E56676C401281410F212F5A
+EFDA1268663987262690277ACCAEFAC04F91BC95C04EA441E33EA026D56EA0FB
+FAF3CC4582AFC9D83081F8EA80ED24CA4B29C269EECF0C3560A138E8B6FA9F7E
+8A4177AEF0F6B174E9699150CB18DF8C7BF7AF4AB87056B0E670163020CFB69C
+4E98B6A79E656C6F44B449112508C8AB5D7C380B7D0B38E843868AE6C6500299
+4C61C764B24D8E914EC2E4372FFC12C172B628E35B1E4B42233E8737E313A83D
+7C9BB76883B0A7939A960295B947FAA4C251A2944DF27C986D69E2848729FCF7
+A180A1599E1E5878A3CED8E25C3732B32CB3FDCA6DE0A1502456D9B0799351F9
+DC611A28F998508AA347A690DB2B2B4E99B61499655F9F014DC13A4E7C4E3FD9
+1FF48559DE1BE245CC876A8B011CB0A167ADD9A77F4E66996BB244A589475BCB
+9B916DF647198063E404F99675C33442C5DF04BE569616A2E2FD01A6884419A6
+311DACADD1083AF250132D42FB8A0F5B217454A64B23F4967A0138182C0AACD7
+268D01F080B58213DEC981923138D6D10D5073AE73CB4E6D75329DAB0B58C229
+FCFF7FCEABDB89613857350A221865CEEF23FC065D1B1E70C717724320D27FF9
+07754BB4AA8DBBD122050BE3B4106B5FA453D8AC98A0F86D829755EF4D3324AF
+5E271D4E7ED463461D8311E384AD5391756F35DC5AB78AD1C5F55ABA13035466
+004CC16AB52BA0227D4B6E645BF0C2679A154C24AF6A267C227C0A2FDDACC610
+9F8A51DC3759D8949DC69557B19E24E8B2A829A7408B7BFBBB9486B972172621
+162BFD558B14F75E0B922140144A275F665CB1DB78AF3ABC9895547018AF7A52
+52B34F26289CAAF7C5F1E2B058F38F65BFDA4585268436B2DB4929534BFBF0AA
+C8F836C0D37FE90E294D44C88CA39931E3219F9DDC38A6472FDAB01557FF4E06
+D423FAA6958983AEADA09DB2A2F6874A87D9C6BB07B7312A7889EE4396767DD9
+C83ED5998ADD19328CEC32DCAA43D0949A6D94C7463BB910687D7715FF0B5FD4
+DCA4C626FA548158BDBBBD1BB56A4A1B92C88B1771D76ED986CBEDA938E02241
+80C4C14EFDD4B7D8A5892C47C14F3DB4165DCBA083ABA9183B4EC464109D714E
+41CCF74A390C638C2A483ECAC9C5634B390E4C794D79A92E73E9252BFFBB5F29
+2DDEF53897ACEC81170F25A7D939F991F301951AB07FA844FF18CBDEE8B4C915
+743C05B5FFFE92A06F1B741ACB311F2A68D7455EE94DBE94B949705F188E91FC
+480836288F583B88E2D3476A84A1458334046E25A3458FB56D184A88A2445BFC
+CED319C452BAA61945E6427457BC7F064BEB030C9346857448889A78C57500D0
+49D020BAF5ED109D31049D35C8CA83B0F9E41DD6BB22A22FC6E642E012853E32
+AC00650B6DF411D915EC7E7AE54B266BB6747A80E2A0344AA3CC4D77832D57F7
+49E234D86514CC2E5B668D385E281B207772F8B6843CCC3FD3EA4BCEF86D9FF7
+11EB8CA9BC3B5458E64F7CF674D2A0BC71C14FAE3E028045B1B6AFF84949713A
+F7710CE7F0BCC4CE9ED1E052E033903775C6BA67DF64A0EB22572BDE2E8E3A84
+4907C8BC3F54D6B77DCD301EBE0A16BF8647558CE25C8D68086C5952999E4F51
+434396040FF1E2CA290C7535C8A28D2A3C8F4D8A0E70890B5CB40A47DB60B31A
+8F74AA15C22696BD7171D206E71FF0DCBB418F786BE0D49B358F3BA888433FB7
+23980E50C48FD5DB43BF0E2223460CB791FE6D5276A9404480CEC4643BE8A0A2
+ECEDD54B4307A416406735AB9776C25838E774E09DCF2FDA749D71D26FD30B06
+F99A0663A82279495B975C2B17C82B05E58EEBFBB5E12F98DE82FE7867FAAA2D
+91756A4F7FC54E368C3AF0BF9DA2A344E2FCC76A86E20DBB6CC026F05154A9D8
+EB08E200711BA1E330F0FF1279C571925ED0E7BE86A74BD036A4D9E6EA4295B2
+0148D8AC11B8A36321728931D000C264BD878BEC1D94FC6FCC4720CA3FEAABE9
+2C97D6AA01B3DCCF0D89CF7437BB9EC1F077641AC357C4AD7E9D0D3C953E839D
+92B4A25FD83C88F3F1D759DE0293DEAD30B9C080C6B6BBE45149044CBE530696
+36FEE48A1DCE1F615EFC87AD3FFB414DADF49767897E213B8E9F49936BA6273B
+A0064C8F3D74CE323493C5571287F481A082B266C957920AAE3387ADFAB40D0E
+B7DB85BE36556ADB72F6D9B8A30716A2D6254CED3AFE7BBF8C2787116AF53615
+E8F5A23C7AECFFC783AD47D2F390FDE458DFAA5CABA6EF8F26FFA519A2265426
+25CE185DF484C7CE53BC5EEDA5D9842FA5F0ABA36D84BD476CE6120A95AE231B
+C6F5D56D8FC52BC16FFB0839F2E203C3ABA654408EA36E200156C6874196FAE7
+E879A83716AD1FE3F61E0FB83FDE97D6A7E7AA12250698F7761EB11AD46B974D
+B799E2919F893268BCD0FD3A7BB9BDBCD31387752AF40594FADB1C9EA80F0B2C
+8F75C24D6FCA63D5533274D9ABB82D9D087D4EC3064DD43FBDC410CB0480F1D6
+81D4B2A153A9E4105D6E737367889C2879B0BA23D0E3445C52F43BD915A6F544
+DF28F8AE1AE184E93E5C0F148A08F0BE110399F492683049378F7D02C8586C78
+39BA15813021006E0849081D0E2EB0A4D931BC53E9F3ABDD2A4CF6CFCA519CA4
+BD3BF6151B8DAC894ECC909200338E018E5D688222FF75DA2ACDA3A0B6757F8E
+12566973481D36C737FF09416F80B9ADAFAE94050248CF687C791F3B18A758D4
+EE78CD0337AC1ED867DB7DCDF17EE43916FA5157DFB8D0C0EF4892EFEF2163C3
+F761D679E1C32138D6312AA484446653FF67E3C42229A6C66962430E7633A2AC
+085D44E2C27A27B5E466EFE665B803890DC6678064DE29C9FE42AF022A91033C
+C8E47B5C727229C4E15A425C0EB6F5645CE8B52858D7E808EC9163704D20708A
+C0CBBDC4F1A7C678F56EF0BA905BD8B43A27FFB433A300115BAABDB3C06D5BB0
+D6AC5C204D3B0E4E985C611C22D9AD61BB0A9D3EBE382C703F2EF449FA451B0A
+50FCA07C36D661ADBEE41CC37E98EA8921E2421080D0032012E84F7C3D803DE5
+391C0E7C2D229F495D1DA055DCCCC408B1481503E942300493448D4A589CC2C3
+A2801C29342BD06ED565394F9AF9D940A329C96C18E2FA405CA3CAD558592506
+04659173B2F9EC1081FAB95BEDB32941925AAE45C6F6D742D153BC9B924930B1
+9EAA14216548EDDF70A203501F7C660EFCA287906965B24C2D7889F91AA8F64F
+7EB7D098DC911FD416D08471EBF37C65BF2F9D78FFADF498598D018CA1892305
+BD14091D8D3DB79589F68EC891BD788DAF85F0A9568718F95DEE9CE1C039A22F
+D8BEC548AF39E26DB4566EE12BD7DF7D5E147C368FE5D24F764F955EBD2FC1A7
+DAA4EB4233CAF94141FBA18927C6E4B1C80B96CF186AEF2064A0B1F76E13307D
+ACA7A3750D4EA808DEF78FC0BACFE291C3ED2E322385B0D18498C2F028A65979
+DA9743B16A9570979036C51AE4AD710CC444D55A62D61010687124E4FAFB7CC4
+79741B38588A3631700D73B619BA42FCF9DEC2A4A032E70E6AF7D47060A17EFA
+E31DD2D37F8B3103AE27A0D1C6D982FEE048946CE3EDC22BEBF3A9829E89775E
+2944B6D3A1BB36E66DD5C0213A05D379D03C58A624033FF1E3E8837AA0532366
+2A05830690EACD3AB4C111D0B824997DE953791D76B6C1FA4714D3D98FFB218D
+60948D2D2C96B07B4B0AC7FBC3C938AF3604BDAD43BFBCCA5B66E2093CC7E2A3
+C980B0D634AFE7C2173FA197C6DCA10807B6F66BAEF9770FEDE5D1BFC9A1008E
+3E3C9B532ED7C3F829ED9E19062B5CC5C8A2473C9FEF131DFB61A0F957CB7035
+F051B9B9B553142B6C35FF43A58159CA30CC9232852897230F30FB15D1E55AFA
+6AE0B7073C41043594D4897B81316A82CF5C7FC054A0D0872CD83C561C757F3D
+F8B50D23586EA6A3496B0EFA63A5D8C89CF7968927F4AC9033ED7D2CC7390CD7
+EA0D69BA01C693D11B71CE21BD92BFEB1AD2BA96A6B15985E7D4C4F1662AEFCD
+6D2C0334E50EEF2A878DCFA645E051B7FE9EF9C3AFE063D4FDAC983B5ADD8880
+CF6462D68546DD3B38FE1338BB699749DA5703367FC990BC8512F013BCC822EE
+58168E8AD5B76219ACF58E7238D1E956393C5809D9430DDD4F574123F47C3F59
+0617288ACA69EB57200FA00CBAF5537D3DC1664E8CE5981E86E49FF8E468857B
+6AB30501CAA8B0D957D6220D9D552436DE71E6BAAD9332F7EC647295D1A8725A
+61FEE01CEB6BEA0831C01AF94001C4E1A69F43742E6BAD5649A305EC36ACC638
+8C24A4976F5B7A63917394C99FF499BD922314593F78FD7156907DC167F761A0
+37707433D75C4B98AC48A08FC4F3988CF9F71752D894646412CE7390D99CE2BE
+AC4459AD4D097368BC3942611EEC7BF8E481CF0AD0050E18E36A1C0E9CFB63D8
+F4D88A59899CBCE6BA593703AC923DFDC85A85F885AD0D7147B6CD6EA0782B3B
+DFE92ADD2075B8056A6C4B4964606D68B47662317A71428A1A9579AA78CD8A79
+CBC839D0CD46FD84C1F1588F16BC80A6D5648F3F2DFEDCED33141A1DD8B86E64
+30D209D031B61F2DD9009C9202571F4E99E0E75A21D9AA7A3649FD4CDA1933BB
+4E53C3D9BF188EA5D95AFD8ACE132FD91C81CD382E68F3D1432FC8392ACB452F
+A6F581563239CFF30CD8EC3EF799BC8291E3A76B76AC107554329BDA12603760
+8970A5616359681D6A038DB1F4BDF08C10FFEADDB97DE44C27BA269175F91D61
+A33944E7EEC7F6EB9139AB0F3E49AF2373B3A9C9224E2645CA3CD3556063EB66
+4905D4824C23D261B53C6B49FDEF19D4E113EEA148A1541136DD83ACD4272A61
+4285419B10961726E5FF088A8833234C6C39632D1D86211330EAB80F47C64378
+4771739DED203D692A62DB30F3D875417473BF05E2111EAB8536EBA399EF10C8
+05937E677E128767F108185B19B102E7E5612E8F49B71CD4AF4F391BD5550A7C
+2B0472E935830E3F84A0D01ACA25EAC40611CCAAC0175BF5470CC9721F2689CA
+396ECBA85EE5B16690E970C05F9AF82F0617D834CADF01B29A9AC20FA6860385
+6C3790CDCA54C4B8C0A7E7FCB29369181BCC55978CF8C45F20C2807B58B2946B
+F73B1C32600A2EFDEDB05771E2328C10B078A8B5D68AF527522C1DC28E6B0C6F
+28B14656C07E7B355B7B41FB7D6B8BDC0543B8A86B688F21993D82096A99412B
+2C5EF2C850F1DA47923D4AA1F7AA1FD0AF09088385B286F4E91BCBF2E62B4BE2
+4795A9E7AB0CA5C3572AEDFD66A627CFB3554CC9E98A13902508C407CEDF92CC
+AFA3871CF38A64DF1F3107745A6BF68C93EF67355AF32F3994AD228BC4FCC45A
+B37F32098C42A9ABD1020F59CD486C11A5A9ECE00597C3345A01566FA85F30E4
+E8C2008ED1A35630782340645E9DF5F72FC3F1EC93E29CB5EDBBD0B6B9B8B8D7
+D1CF0D6D6E68C53E72DE452A72A7F1EFAA266462E302495F5953A18515C61E33
+AC663A23471281E6DDB7783FA8DBC681EB29D3C4D46E281507D4AA8B04E6442D
+12D0F98EA735898401454BE76DD0161CC35CC17BAB0799A32B486C03FE362DF2
+D650937B554219FA9D55122B0D23BC65DD993BB5A373ADE161F4EA6CD22ED48E
+2267B630D15843B3C6A29D25834DEFEFE5145D17FCAD59F50438D1AF8CCCAA2B
+68FDC7D4B8C8C9CF9293185CE66DE80E94BCB81E4290A808762F485B7BF67BF4
+853C05507951732DC9DF2FCB294A688A1344C6F13D83040EB3CF6FE43F93C6B5
+3CFD96F8ACE65B553036874C5E001F058FD45AD73EFDC6441D34FCB36482F162
+65BFE82A0A3D0FA84BDC488ED0A29A1D8F24DD6236BA14F37F1273477B17A1D6
+8BBA6FA890FF25F902DA9801CE453163A724307680675443178328A7972623F9
+E376E904396B32884B235A3A2F2E485037DB93DE70DC3CF616228012290236E1
+003C34A04ADF18C9452700CB3542ECA78CD76A31DA6854A14BACAD93CD713FF5
+7E44A88B475766ABBA4492664623DF4B18145400219AF12007C0F1614B21971D
+1C01364BC2C318C0F95F2C761418B072B92EDDCDA7D8A39D73DF44F2CD948CFC
+1195611110B1D29A94AEDB03D4F2C1823F8D0422B3A7C93ECDCB28686973B758
+A36F3C2A464B8DC0B8E472306126126B4C97C84C4CF74BF463D3C282DB7110D5
+B119467517E3FDC3EFC6187A090A913C1D9149BA359AB5D6C73CE801AA3943A3
+FB7599B33CDF46D3E519B7A129DA1C8F519ADDCC950A0FB8C27F4DDBFCA1421D
+ED041D2566D6692444C326A913EEF73EE5E7B1B0CE7D346EA94BBE77C4BAD703
+8CBB8DBC6F345C4FA0887D7D77CC295E18BC60A9C4EC6457BF233805AF08D988
+6A2F4110FCB0320E56E7AF7601E034D2793EB5764536B2944BD90CFB4FD53C0C
+2554B4B97274605249A085B1B71C7F53E3D30B19546A0858E4B6116AB3A3C20F
+D223153FB7DCA8A0E3D7D9E906F673AF94A92854E2A25B819E47AEAD27485196
+6AF4DE6C88CC79B8F72625B762490C6C279916C6C8CAFD0054FFEFF11F8C7152
+B2EA7981ADED9F706E2EA21D2BDFA59CE404D0AFE11FFCD68732DEC63C2FB0D3
+A96E14E5046ABC98C8FBF8F1BA121BFD1FDC94EB5597FD44219DAF19F871AF75
+136D8AD20E17985F25527A46B175C1E48E760F8086639FB5C086A6588BE797C1
+A5F71D3F66C51FB1E49A00201127877DBD00534E1E8EE719C6EEDD7E4ECF740C
+272ED2F338AA5E1FD8AE9B0B4D9C405615C19DA824DFF40D92505BD37EAB2E62
+B7AFB69AD7B76EB6FAA90ED8119FB8D710F5536E564EF8E11C7422B4985B0017
+C760C753B521B474787E23A64DCC32FA2800BC8DE36F9561DF822DA75450CE51
+8E7B9A0DD0A57762E7F85930DC0D9C37F7AF177F9B8F355D8032FCE0D010DF3A
+4AA00B0754B79C8F5B314DA028DC12260A5C6CC42EA8A5AA0F4E814171701653
+32FC6F1D94DE5FC999977735DEE0129E8394BBF6986F4392261936D74BA19ADE
+37742B698CE29CFB8395601FDDD7228CFBAE86406422387A83B2901D9C1B8665
+31B0F6273537D77F0B4F142C6B210071694D1B8E7BDECFBA2725A7E1AE1D81B8
+02B34FA02D0A7BA383763B44BB31ED7F9237936774590EC93B52914BB6E9C931
+C3D8C7A13FAB7F2346C861685FD0AAEA9CD8DAC1F995A86185660DD25A46E3E3
+76E9328C9C68331AF07AED6E7E8305E056EB489A1436733438368B1084D414E2
+3FEBEB53EEA500392D754F8EB2AA96D3EC336064C713D63ED180A0E777F152D8
+8E3F0D82348C1C4B3613CBE1A9982DC5AC19443D66E5C98221982DF65D9AA392
+A1C24B28051313D8CCCA650A1ED617B61E93FAA49499F1A12B0F8378514DE99D
+B4AFE780B3776F5F0E5D8F1627075F763C61291515F9361968D9750E41AD0CBF
+2F074C4C1E86E175D163CE1DF4088CBCBB89FD725F256BA370D27B1695EFE072
+D3CAA0388F5FFB4F19B49183D001282DB413BA2B558AA437E5C08166C90E943A
+2986253909E1898600B7311D1129610CC5181131D166CB5F5354B4D4E5ADADAA
+C0987CCDD522F0035626399B9996704632298D726F86C0A5CD3775C594E32DDD
+06466CA1A6903B694C5D9695F6F2B3FD9ED2DB99D9B38B78ABF97BD43A55B7F0
+CD4D43509B72E4B4C094701EF0FCC3B9E5D98996807F2A8AFF6E6A86229E0530
+AEB30DBC61EA58B555BF01360E4158C3EAF4FF10BD5C87B5745AC1512A57EA4D
+E231EF0EAE461CA3031BEACA80615FF8F50BD2FE95C51C7FAAD7E6BD70F1DF4F
+86474964084739126E16BF18E32857D862CD42ED7E7F462EAD75D2923B1B9634
+B8B6E1D3091CCC23EAD246C82EC602A84C82D4FD9F5E867817299921C844D685
+19C008BC2025B36C03DA5BB272375FE9997EDD64471F30EDA21EB796743F3B42
+D43FF785C900EA62BDC3C46BB2AC1B3F00A74B0F0C3B348033369ADF630D1C83
+E5E741B697EE045CA6325D151F5819C6C2BAB793A0A40E1A48E6B1F442CDEE12
+7B61C68C60172C0D09191FE1B0C1C3A082EC31CFAC70E298D00C04BB7C6B4E99
+00558D641DF88ABF7C7D712C8DE23340C6200D8539B674BA1B60B2BB9AA99EC5
+CF57713B56C2941C3DA98A47F6C3DCDDE7C047251CE493DE954028EDB34D3DE8
+946ED87023E348EBBE7BE424D92A89CAC21B7B81061C999FC8DCD9B7814BBBCE
+
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX12
+%!PS-AdobeFont-1.1: CMBX12 1.0
+%%CreationDate: 1991 Aug 20 16:34:54
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 97 /a put
+dup 99 /c put
+dup 101 /e put
+dup 102 /f put
+dup 105 /i put
+dup 107 /k put
+dup 110 /n put
+dup 114 /r put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+readonly def
+/FontBBox{-53 -251 1139 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660F74BEE96790DE35AFA90CCF712
+B1805DA88AE375A04D99598EADFC625BDC1F9C315B6CF28C9BD427F32C745C99
+AEBE70DAAED49EA45AF94F081934AA47894A370D698ABABDA4215500B190AF26
+7FCFB7DDA2BC68605A4EF61ECCA3D61C684B47FFB5887A3BEDE0B4D30E8EBABF
+20980C23312618EB0EAF289B2924FF4A334B85D98FD68545FDADB47F991E7390
+B10EE86A46A5AF8866C010225024D5E5862D49DEB5D8ECCB95D94283C50A363D
+68A49071445610F03CE3600945118A6BC0B3AA4593104E727261C68C4A47F809
+D77E4CF27B3681F6B6F3AC498E45361BF9E01FAF5527F5E3CC790D3084674B3E
+26296F3E03321B5C555D2458578A89E72D3166A3C5D740B3ABB127CF420C316D
+F957873DA04CF0DB25A73574A4DE2E4F2D5D4E8E0B430654CF7F341A1BDB3E26
+77C194764EAD58C585F49EF10843FE020F9FDFD9008D660DE50B9BD7A2A87299
+BC319E66D781101BB956E30643A19B93C8967E1AE4719F300BFE5866F0D6DA5E
+C55E171A24D3B707EFA325D47F473764E99BC8B1108D815CF2ACADFA6C4663E8
+30855D673CE98AB78F5F829F7FA226AB57F07B3E7D4E7CE30ED3B7EB0D3035C5
+148DA8D9FA34483414FDA8E3DC9E6C479E3EEE9A11A0547FC9085FA4631AD19C
+E936E0598E3197207FA7BB6E55CFD5EF72AEC12D9A9675241C7A71316B2E148D
+E2A1732B3627109EA446CB320EBBE2E78281CDF0890E2E72B6711335857F1E23
+337C75E729701E93D5BEC0630CDC7F4E957233EC09F917E5CA703C7E93841598
+0E73843FC6619DE017C8473A6D1B2BE5142DEBA285B98FA1CC5E64D2ADB981E6
+472971848451A245DDF6AA3B8225E9AC8E4630B0FF32D679EC27ACAD85C6394E
+A6F71023B660EE883D8B676837E9EBA4E42BA8F365433A900F1DC3A9F0E88A26
+3753B03B38D6FF2C1D845166BAF4998598D00F26A33F36C22E2C93B0A38650D5
+61BC36F521625DA1DD5E3133F573575101D9B21CEE92F241DF9A5A4ECACEE0C0
+1FD4DE44E06C1923CA444F762B6B448DE4A52715961063CEC16B6C371E93F0CF
+56C47321C2345C083787EEB699FD2F9D3E2FEFB010E05E0DAC4F2934DC1BF47E
+21DDAE3E56F669A0C934F7F751A01CB55635B7590D2AE3B6F4777BC0EC8F7585
+BADC41E3DEAD3C1CC4AC3020CCB7CC60ED93CDBD17D8D10A3014099E5FCBA6E2
+B18DDB1086CEEBBB1A2A38D011E5ABA027C28E72AADFEC805D080238B4633408
+41EB166F3E8CA60D77071FD7CD0A127516FDBDB49199E598BA61F195678A0796
+86FEE45B30B60033CA49A5922F28E4E0C9D4BAF66EBB536AD8BA9A0E6F126E1C
+6C5B2B81A7D5992F0FAABA18DDE700056E6D85798126ED387B62C5F076ED907B
+E50B145B588823906FBAD973E60CFF9868F9844299B07CEBFE7B2219CB531193
+1D0E1D953492FB81E90BE977EC4CF0C5ECEB6BADA7A1D86A3E1B944B044BC90F
+020F5E76C7353C0F8C5D76DE012AE7A37F9859C85A6C4681C29A644F2F119138
+9D113569E9EFB85101AE6A46D660C5C7E205B272BD53CFCBA8C9A51DBE678806
+CA0B6FB7975C3EBE449A9C3DE0DDA3C0CA74D0F2085E070945726C1594A611FF
+5B4BD0E2EC240CA21CECE1601E1705ACC14EA52AF8114A16061FF317167AC9F5
+DECC692C4E2727D970E1171D980379B56E2C51BD3D608FCE89A7A2E832B0B815
+A7B334D470817F2623109D0BDD66C8AA697ED3CA02AF684E5766B3470374F9B1
+5BCF04D178D5B4F12C4A0303AE1AC1ED6C19BFDFEE60DCA168E90AE9EE49CB4A
+2FFC5DFED5179AAC027F6D415089A795EC9292C58B009165717D1C0B6126C55C
+C10E4D686A735F787B3D693D841198A6EA185C691C070601938FB8BEC74278B5
+E88003C6CFA16C7DC52FB135D48D0A85B42F261B64876815BD2DB1DBA403B5DC
+87DF034DDEDBFE962A5AC112DCC6B8415A518F463AB278DE3C6B5998ADFF4065
+6AF00AE2591D3C3750030C18CA2D4B78FAB4B03E72D6135D69DD68BDB2023F1B
+7F9C0ADCEE2576D5BA1130F89E93BE5716252173339A2FC1B11F5E5D5AD31F4C
+9BF98CD0765C92031185C3BED78BA36425487B4BA569114BC5B46EBB968CEBC7
+3742501440A04BC19C12E8BBB4DC962DB619DF7C3298892F216CFF9140FD974E
+B1EB752EBB82935BDFBA064B81F7302888C4B767BF2AB4CD44CEB1C5D6809FDE
+617A2B93E3FB231DD54B9875E59823A2DC666DF6D781D249898A2F05C5C88E77
+90DFD1DC1F3488714BAEFFD8FC1C3633EE8E793320FB51436784FA82EF28FE8F
+65AF0F5C5471A99478B99CEA235AC0003E6C5BBBCE4652BF2CBC0610B29AC8A6
+ED3034B7BC76EB2009ED76751404F14061BF4890FE9A1A01476F1C2BA310A82D
+A1B77BA6A71AB8CF54563315338A35B1D3A3369BF77312C87EE88E9B1E40DD17
+3CEBC13E73A90A9B40655B2BA43C93D95DB9B47BCC60CF801EAE26242FC4E7FA
+32328BFA8B7AB57095638A3F154D9AA0769C7B02A6BADC3DC59297C46E51DB92
+0BAFAC207DA75D39D7A9066D0EDF73FBF28A332F8C800806D9512268241FAF9E
+C6279BE0FB884244D022E38C8D748D8928A5A44BC1B2006034ED8819446FF8BF
+98BE8A2ECC149B6E795E35DF7CBBA29482260D67EE7544CB5FBA4E4EF627D476
+5CD6F741C5CE950F14550940AF65EC541C053C6B18203562F6BC7ED6CAEBBB73
+300798634EDB4926CE56B2BF0F4226EC1F472B8EF674AC3AB8597EA93135A4A3
+AFAFAFB943DEEE1C155EDD689BC3CB7EE95EF96BA686BC723C56235848985604
+8A3EDED9013B609FC8855EE4A044F7C0634471F5372796391BF7820E579D7704
+FA6837B717733DA04D5DBDA91A028F14317EF115FDB9A952A93D6133A533F081
+D0715B6D90FFD9177C44D8731692D823098D04080B61F5D54C8D300DDCCBD145
+92601ED8216D3245E104DE65087D3A0E36ACCCB0A971D9163EA7DE727F2345B1
+8879D24FF363E8623D30F2E0DA8A41028D32D93AB4BF94C18C21C22BEF1D4FC8
+1B64AE052ABA20F8988F614CE3E42773F2DC4B1BDFB5F7B826D0DB68D92AB25E
+FF2C19BDE6287731B72979D733A9F79B51B97D4D823C7E6899953B425CCBA13D
+26211E53C38BA9182C90243BE9EEF1A86C78B756AF2A74C60B9DDC7DAF99C430
+407B0E49032DB092DC0F36B2F9CFE375E3C4737E122FBA57D89778C7922D5CA8
+4EEB5F50B96EAE7BA1850FBB30E15CA5C368139062036066CF92CFB20C7860F2
+67FF81549D70B048831750FF06A71B91512710DDD86EBFF5FA43E9534F5FA6AA
+E87843B8EB1A40D203880B6EFB38EA5CD5CD4E163CDF36D018B62E482F2E633E
+029516D8BC1C02344BD85B1DF3F3EE1098104A5E754D6D4E86C29F08CBE8BAAD
+7A5EC1E654BFDCAF8EB2A8BFA28DE9E857EA7CBD9E3C0012DAF79A114C55AD77
+952BC5A5FCB40C76760460C58836DBC927D4231EDBBF3B06A420ADCAE8564CDD
+85DD501C31E3915FB7A3CA9DF157B7F4C183DF6791E1FE071EBF75A47C8184C3
+F7BFD40AFD10CB3D4835AC9EB170CCE05E01E76497D022E263D4ACA540AE7A0B
+F99EFB3A4E82D400FF79CE97AC2654E2D4FA0092E2D27097FD9AE0476CB33B64
+7722F482E0B148252740F435F52D2A610C195E340A86472C5D41D1B03CE311ED
+8C2C81A9D77352B27BBFECDF828781D7ABB2485FBEEED6B7BBF042884F499C64
+8B32FE5F8D8FD13BCEA7CF8D763D47E8040D0ED2EEED52039AA93B950491C9F8
+8C7BFF7002F6B5267176B71E8C408258E401978A723DE12A969732CF910D60E5
+4E8ED3C0B4C76F9A7BA41BEC303237B8256B6F78492EE137CB0B83E84EC69AFB
+3A91446762891E2C2867F40F62A31D04C9D42D2D77F4751084810B839AD5CD70
+C79A694BA0160A8BFEB87BFE5AF51B01306886897429C88577006988D48BE24C
+98E7F2512860346E5112D0063B79F3A983259F766A89ED3660D39AD7B1E237A4
+097102EDBC8EDEC3D93D4BC71E557956649AF5641D7508EAED4DECDB9BB31C29
+2F0918025367A9A394EDD59B4AF99892BB84558479690949DE631572EDE73A04
+662C9FDACFD281F7ABD8CDCCAF604A28DA61B3BD8EF9BCC64FFFAD782F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+TeXDict begin 66308004 40258431 1000 600 600 (refcard-legal.dvi)
+ at start /Fa 230[47 25[{}1 83.022 /CMMI10 rf /Fb 143[69
+5[23 2[42 42 99[65 1[65{}6 83.022 /CMSY10 rf /Fc 162[23
+1[23 41[42 49[{}3 83.022 /CMR10 rf /Fd 133[28 33 32 45
+32 37 23 28 29 1[35 35 38 56 18 32 1[21 35 32 21 32 35
+32 32 35 18[50 27[35 35 2[21 25 3[28 28[39 12[{}31 58.1154
+/CMTI7 rf /Fe 133[30 35 35 47 35 37 26 26 26 35 37 33
+37 55 19 35 21 19 37 33 21 30 37 30 37 33 19 3[33 4[67
+2[47 37 48 51 1[51 49 60 41 2[24 49 51 43 45 50 47 46
+49 6[19 33 5[33 33 33 33 33 19 22 19 2[26 26 19 51 3[33
+19[56 38 38 39 11[{}65 58.1154 /CMR7 rf /Ff 129[35 1[35
+1[35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 1[35
+35 35 35 35 35 35 35 35 2[35 35 35 35 2[35 2[35 35 35
+35 1[35 35 35 35 35 2[35 35 35 1[35 35 35 35 35 35 35
+35 35 35 35 35 6[35 35 35 1[35 35 35 35 35 35 35 35 35
+35 3[35 35 33[{}71 66.4176 /CMTT8 rf /Fg 134[50 50 1[50
+53 37 38 39 50 53 48 53 80 27 50 1[27 53 48 29 44 53
+42 53 46 7[72 2[72 1[66 53 72 72 65 72 75 91 57 75 1[36
+75 75 60 63 73 69 68 72 19[32 27 31[53 12[{}47 83.022
+/CMBX10 rf /Fh 134[32 1[43 32 34 24 24 24 1[34 30 34
+50 18 32 19 18 34 30 19 27 34 27 34 30 8[45 61 45 45
+43 1[44 1[41 47 45 54 38 1[31 2[47 1[41 46 43 42 1[47
+4[18 1[30 1[30 30 2[30 30 30 30 1[18 1[18 2[24 24 40[{}53
+49.8132 /CMR6 rf /Fi 137[59 62 44 1[46 3[62 2[59 1[31
+2[34 51 1[50 1[54 14[84 84 1[84 79[{}14 99.6264 /CMBX12
+rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%BeginPaperSize: Legal
+<< /PageSize [612 1008] >> setpagedevice
+%%EndPaperSize
+ @landscape end
+%%EndSetup
+%%Page: 1 1
+TeXDict begin @landscape 1 0 bop -480 -367 a Fi(Octa)m(v)m(e)28
+b(Quic)m(k)g(Reference)71 b Fh(Octa)n(v)n(e)29 b(V)-5
+b(ersion)27 b(3.0.0)-480 -207 y Fg(Starting)h(Octa)m(v)m(e)-480
+-116 y Ff(octave)396 b Fe(start)28 b(in)n(teractiv)n(e)e(Octa)n(v)n(e)h
+(session)-480 -41 y Ff(octave)i Fd(\014le)278 b Fe(run)27
+b(Octa)n(v)n(e)g(on)g(commands)f(in)i Fd(\014le)-480
+34 y Ff(octave)h(--eval)h Fd(c)m(o)m(de)o Fe(Ev)l(aluate)d
+Fd(c)m(o)m(de)f Fe(using)h(Octa)n(v)n(e)-480 109 y Ff(octave)i(--help)
+157 b Fe(describ)r(e)25 b(command)h(line)h(options)-480
+281 y Fg(Stopping)g(Octa)m(v)m(e)-480 372 y Ff(quit)i
+Fe(or)f Ff(exit)210 b Fe(exit)27 b(Octa)n(v)n(e)-480
+455 y Ff(INTERRUPT)291 b Fe(\()p Fd(e.g.)41 b Ff(C-c)p
+Fe(\))29 b(terminate)d(curren)n(t)g(command)167 530 y(and)i(return)e
+(to)i(top-lev)n(el)e(prompt)-480 698 y Fg(Getting)h(Help)-480
+790 y Ff(help)466 b Fe(list)27 b(all)h(commands)e(and)h(built-in)f(v)l
+(ariables)-480 865 y Ff(help)j Fd(c)m(ommand)153 b Fe(brie\015y)26
+b(describ)r(e)f Fd(c)m(ommand)-480 939 y Ff(doc)501 b
+Fe(use)27 b(Info)g(to)h(bro)n(wse)g(Octa)n(v)n(e)f(man)n(ual)-480
+1014 y Ff(doc)i Fd(c)m(ommand)188 b Fe(searc)n(h)27 b(for)g
+Fd(c)m(ommand)g Fe(in)g(Octa)n(v)n(e)g(man)n(ual)-480
+1089 y Ff(lookfor)j Fd(str)251 b Fe(searc)n(h)27 b(for)g
+Fd(c)m(ommand)g Fe(based)g(on)g Fd(str)-480 1238 y Fg(Motion)f(in)i
+(Info)-480 1329 y Ff(SPC)h Fe(or)e Ff(C-v)281 b Fe(scroll)27
+b(forw)n(ard)h(one)f(screenful)-480 1404 y Ff(DEL)i Fe(or)e
+Ff(M-v)281 b Fe(scroll)27 b(bac)n(kw)n(ard)g(one)g(screenful)-480
+1479 y Ff(C-l)501 b Fe(redra)n(w)27 b(the)g(displa)n(y)-480
+1647 y Fg(No)s(de)g(Selection)f(in)h(Info)-480 1739 y
+Ff(n)571 b Fe(select)26 b(the)h(next)g(no)r(de)-480 1814
+y Ff(p)571 b Fe(select)26 b(the)h(previous)g(no)r(de)-480
+1888 y Ff(u)571 b Fe(select)26 b(the)h(`up')g(no)r(de)-480
+1963 y Ff(t)571 b Fe(select)26 b(the)h(`top')g(no)r(de)-480
+2038 y Ff(d)571 b Fe(select)26 b(the)h(directory)f(no)r(de)-480
+2112 y Ff(<)571 b Fe(select)26 b(the)h(\014rst)g(no)r(de)g(in)g(the)g
+(curren)n(t)f(\014le)-480 2187 y Ff(>)571 b Fe(select)26
+b(the)h(last)h(no)r(de)e(in)h(the)g(curren)n(t)f(\014le)-480
+2262 y Ff(g)571 b Fe(reads)27 b(the)g(name)f(of)i(a)g(no)r(de)e(and)h
+(selects)g(it)-480 2337 y Ff(C-x)i(k)437 b Fe(kills)27
+b(the)g(curren)n(t)f(no)r(de)-480 2486 y Fg(Searc)m(hing)i(in)g(Info)
+-480 2577 y Ff(s)571 b Fe(searc)n(h)27 b(for)g(a)h(string)-480
+2652 y Ff(C-s)501 b Fe(searc)n(h)27 b(forw)n(ard)g(incremen)n(tally)
+-480 2727 y Ff(C-r)501 b Fe(searc)n(h)27 b(bac)n(kw)n(ard)g(incremen)n
+(tally)-480 2801 y Ff(i)571 b Fe(searc)n(h)27 b(index)f(&)i(go)g(to)f
+(corresp)r(onding)f(no)r(de)-480 2876 y Ff(,)571 b Fe(go)28
+b(to)g(next)e(matc)n(h)h(from)g(last)g(`i')h(command)-480
+3045 y Fg(Command-Line)f(Cursor)g(Motion)-480 3136 y
+Ff(C-b)501 b Fe(mo)n(v)n(e)27 b(bac)n(k)g(one)g(c)n(haracter)-480
+3211 y Ff(C-f)501 b Fe(mo)n(v)n(e)27 b(forw)n(ard)h(one)f(c)n(haracter)
+-480 3286 y Ff(C-a)501 b Fe(mo)n(v)n(e)27 b(to)h(the)f(start)g(of)h
+(the)f(line)-480 3360 y Ff(C-e)501 b Fe(mo)n(v)n(e)27
+b(to)h(the)f(end)f(of)h(the)g(line)-480 3435 y Ff(M-f)501
+b Fe(mo)n(v)n(e)27 b(forw)n(ard)h(a)f(w)n(ord)-480 3510
+y Ff(M-b)501 b Fe(mo)n(v)n(e)27 b(bac)n(kw)n(ard)g(a)h(w)n(ord)-480
+3584 y Ff(C-l)501 b Fe(clear)26 b(screen,)g(reprin)n(ting)g(curren)n(t)
+g(line)h(at)h(top)-480 3753 y Fg(Inserting)f(or)h(Changing)f(T)-8
+b(ext)-480 3844 y Ff(M-TAB)431 b Fe(insert)27 b(a)h(tab)f(c)n(haracter)
+-480 3919 y Ff(DEL)501 b Fe(delete)26 b(c)n(haracter)g(to)h(the)g(left)
+g(of)g(the)g(cursor)-480 3994 y Ff(C-d)501 b Fe(delete)26
+b(c)n(haracter)g(under)g(the)h(cursor)-480 4068 y Ff(C-v)501
+b Fe(add)27 b(the)g(next)g(c)n(haracter)f(v)n(erbatim)-480
+4143 y Ff(C-t)501 b Fe(transp)r(ose)27 b(c)n(haracters)f(at)i(the)f(p)r
+(oin)n(t)-480 4218 y Ff(M-t)501 b Fe(transp)r(ose)27
+b(w)n(ords)h(at)g(the)f(p)r(oin)n(t)-480 4350 y Fc([)h(])f
+Fh(surround)h(optional)f(argumen)n(ts)84 b(...)40 b(sho)n(w)29
+b(one)f(or)g(more)g(argumen)n(ts)p 1499 -433 1 17 v 1499
+4350 V 1620 -367 a Fg(Killing)e(and)i(Y)-8 b(anking)1620
+-276 y Ff(C-k)501 b Fe(kill)27 b(to)h(the)f(end)f(of)h(the)g(line)1620
+-201 y Ff(C-y)501 b Fe(y)n(ank)28 b(the)e(most)i(recen)n(tly)e(killed)g
+(text)1620 -126 y Ff(M-d)501 b Fe(kill)27 b(to)h(the)f(end)f(of)h(the)g
+(curren)n(t)f(w)n(ord)1620 -51 y Ff(M-DEL)431 b Fe(kill)27
+b(the)g(w)n(ord)h(b)r(ehind)d(the)i(cursor)1620 23 y
+Ff(M-y)501 b Fe(rotate)27 b(the)g(kill)g(ring)g(and)g(y)n(ank)h(the)f
+(new)g(top)1620 195 y Fg(Command)g(Completion)f(and)i(History)1620
+287 y Ff(TAB)501 b Fe(complete)25 b(a)j(command)e(or)i(v)l(ariable)f
+(name)1620 361 y Ff(M-?)501 b Fe(list)28 b(p)r(ossible)e(completions)
+1620 436 y Ff(RET)501 b Fe(en)n(ter)27 b(the)f(curren)n(t)h(line)1620
+511 y Ff(C-p)501 b Fe(mo)n(v)n(e)27 b(`up')g(through)g(the)f(history)i
+(list)1620 585 y Ff(C-n)501 b Fe(mo)n(v)n(e)27 b(`do)n(wn')h(through)e
+(the)h(history)g(list)1620 660 y Ff(M-<)501 b Fe(mo)n(v)n(e)27
+b(to)h(the)f(\014rst)g(line)g(in)g(the)g(history)1620
+735 y Ff(M->)501 b Fe(mo)n(v)n(e)27 b(to)h(the)f(last)h(line)e(in)h
+(the)g(history)1620 810 y Ff(C-r)501 b Fe(searc)n(h)27
+b(bac)n(kw)n(ard)g(in)h(the)e(history)i(list)1620 884
+y Ff(C-s)501 b Fe(searc)n(h)27 b(forw)n(ard)h(in)f(the)g(history)g
+(list)1620 983 y Ff(history)j Fc([)p Fe(-q)p Fc(])e([)p
+Fd(N)9 b Fc(])95 b Fe(list)28 b Fd(N)36 b Fe(previous)27
+b(history)g(lines,)g(omitting)2268 1058 y(history)g(n)n(um)n(b)r(ers)f
+(if)h Ff(-q)1620 1159 y(history)j(-w)e Fc([)p Fd(\014le)p
+Fc(])98 b Fe(write)27 b(history)h(to)f Fd(\014le)32 b
+Fe(\()p Ff(~/.octave)p 3183 1159 22 4 v 28 w(hist)d Fe(if)2268
+1234 y(no)e Fd(\014le)32 b Fe(argumen)n(t\))1620 1336
+y Ff(history)e(-r)e Fc([)p Fd(\014le)p Fc(])98 b Fe(read)27
+b(history)g(from)g Fd(\014le)32 b Fe(\()p Ff(~/.octave)p
+3236 1336 V 28 w(hist)d Fe(if)2268 1411 y(no)e Fd(\014le)32
+b Fe(argumen)n(t\))1620 1491 y Ff(edit)p 1764 1491 V
+27 w(history)d Fd(lines)f Fe(edit)f(and)g(then)f(run)h(previous)g
+(commands)2268 1565 y(from)g(the)f(history)i(list)1620
+1642 y Ff(run)p 1729 1642 V 26 w(history)i Fd(lines)63
+b Fe(run)27 b(previous)g(commands)f(from)h(the)f(history)2268
+1717 y(list)1691 1804 y Fc([)p Fd(b)m(e)m(g)5 b Fc(])26
+b([)p Fd(end)5 b Fc(])212 b Fe(Sp)r(ecify)25 b(the)i(\014rst)h(and)f
+(last)g(history)2268 1879 y(commands)f(to)h(edit)g(or)h(run.)1703
+1950 y(If)f Fd(b)m(e)m(g)k Fe(is)d(greater)f(than)g Fd(end)p
+Fe(,)g(rev)n(erse)g(the)g(list)g(of)h(commands)1703 2025
+y(b)r(efore)e(editing.)40 b(If)27 b Fd(end)33 b Fe(is)28
+b(omitted,)e(select)g(commands)g(from)1703 2100 y Fd(b)m(e)m(g)31
+b Fe(to)d(the)e(end)h(of)g(the)g(history)g(list.)42 b(If)27
+b(b)r(oth)g(argumen)n(ts)f(are)1703 2174 y(omitted,)g(edit)h(the)g
+(previous)f(item)h(in)g(the)g(history)g(list.)1620 2324
+y Fg(Shell)g(Commands)1620 2415 y Ff(cd)h Fd(dir)423
+b Fe(c)n(hange)27 b(w)n(orking)g(directory)f(to)i Fd(dir)1620
+2490 y Ff(pwd)501 b Fe(prin)n(t)27 b(w)n(orking)h(directory)1620
+2592 y Ff(ls)g Fc([)p Fd(options)p Fc(])247 b Fe(prin)n(t)27
+b(directory)f(listing)1620 2684 y Ff(getenv)k(\()p Fd(string)p
+Ff(\))125 b Fe(return)27 b(v)l(alue)g(of)g(named)f(en)n(vironmen)n(t)
+2268 2758 y(v)l(ariable)1620 2829 y Ff(system)k(\()p
+Fd(cmd)p Ff(\))173 b Fe(execute)25 b(arbitrary)i(shell)g(command)f
+(string)1620 3001 y Fg(Matrices)1620 3073 y Fe(Square)h(brac)n(k)n(ets)
+g(delimit)e(literal)i(matrices.)40 b(Commas)28 b(separate)1620
+3148 y(elemen)n(ts)e(on)h(the)g(same)g(ro)n(w.)42 b(Semicolons)26
+b(separate)h(ro)n(ws.)1620 3222 y(Commas)h(ma)n(y)f(b)r(e)g(replaced)e
+(b)n(y)j(spaces,)f(and)g(semicolons)f(ma)n(y)h(b)r(e)1620
+3297 y(replaced)f(b)n(y)h(one)g(or)h(more)e(newlines.)40
+b(Elemen)n(ts)26 b(of)i(a)f(matrix)g(ma)n(y)1620 3372
+y(b)r(e)g(arbitrary)g(expressions,)f(assuming)h(all)h(the)f(dimensions)
+f(agree.)1620 3477 y Ff([)i Fd(x)p Ff(,)g Fd(y)p Ff(,)g(...)42
+b(])170 b Fe(en)n(ter)27 b(a)g(ro)n(w)i(v)n(ector)1620
+3551 y Ff([)f Fd(x)p Ff(;)g Fd(y)p Ff(;)g(...)42 b(])170
+b Fe(en)n(ter)27 b(a)g(column)f(v)n(ector)1620 3636 y
+Ff([)i Fd(w)p Ff(,)g Fd(x)p Ff(;)g Fd(y)p Ff(,)g Fd(z)g
+Ff(])153 b Fe(en)n(ter)27 b(a)g(2)p Fb(\002)p Fe(2)h(matrix)1620
+3805 y Fg(Multi-dimensional)c(Arra)m(ys)1620 3892 y Fe
+(Multi-dimensional)h(arra)n(ys)j(ma)n(y)g(b)r(e)e(created)g(with)i(the)
+e Fd(c)m(at)i Fe(or)1620 3967 y Fd(r)m(eshap)m(e)f Fe(commands)f(from)h
+(t)n(w)n(o-dimensional)g(sub-matrices.)1620 4072 y Ff(squeeze)j(\()p
+Fd(arr)p Ff(\))168 b Fe(remo)n(v)n(e)27 b(singleton)f(dimensions)g(of)i
+(the)e(arra)n(y)-5 b(.)1620 4158 y Ff(ndims)29 b(\()p
+Fd(arr)p Ff(\))239 b Fe(n)n(um)n(b)r(er)26 b(of)h(dimensions)f(in)i
+(the)e(arra)n(y)-5 b(.)1620 4232 y Ff(permute)30 b(\()p
+Fd(arr)p Ff(,)e Fd(p)p Ff(\))70 b Fe(p)r(erm)n(ute)26
+b(the)g(dimensions)g(of)i(an)f(arra)n(y)-5 b(.)1620 4318
+y Ff(ipermute)30 b(\()p Fd(arr)p Ff(,)f Fd(p)p Ff(\))34
+b Fe(arra)n(y)28 b(in)n(v)n(erse)f(p)r(erm)n(utation.)p
+3600 -433 1 17 v 3600 4350 V 3720 -367 a Ff(shiftdim)j(\()p
+Fd(arr)p Ff(,)f Fd(s)p Ff(\))41 b Fe(rotate)28 b(the)e(arra)n(y)i
+(dimensions.)3720 -292 y Ff(circshift)j(\()p Fd(arr)p
+Ff(,)d Fd(s)p Ff(\))6 b Fe(rotate)28 b(the)e(arra)n(y)i(elemen)n(ts.)
+3720 -124 y Fg(Sparse)g(Matrices)3720 -32 y Ff(sparse)i(\(...\))191
+b Fe(create)27 b(a)g(sparse)h(matrix.)3720 53 y Ff(speye)i(\()p
+Fd(n\))300 b Fe(create)27 b(sparse)g(iden)n(tify)f(matrix.)3720
+139 y Ff(sprand)k(\()p Fd(n)p Ff(,)f Fd(m)p Ff(,)e Fd(d)p
+Ff(\))41 b Fe(sparse)28 b(rand)f(matrix)g(of)g(densit)n(y)g
+Fd(d)p Fe(.)3720 225 y Ff(spdiags)j(\(...\))156 b Fe(sparse)28
+b(generalization)d(of)i Fd(diag)p Fe(.)3720 311 y Ff(nnz)i(\()p
+Fd(s)p Ff(\))374 b Fe(No.)42 b(non-zero)26 b(elemen)n(ts)g(in)h(sparse)
+h(matrix.)3720 479 y Fg(Ranges)3720 570 y Fd(b)m(ase)f
+Ff(:)42 b Fd(limit)3720 645 y(b)m(ase)27 b Ff(:)42 b
+Fd(incr)28 b Ff(:)42 b Fd(limit)3720 729 y Fe(Sp)r(ecify)26
+b(a)h(range)g(of)h(v)l(alues)f(b)r(eginning)e(with)j
+Fd(b)m(ase)j Fe(with)c(no)3720 803 y(elemen)n(ts)f(greater)h(than)g
+Fd(limit)p Fe(.)42 b(If)27 b(it)g(is)h(omitted,)e(the)h(default)3720
+878 y(v)l(alue)g(of)h Fd(incr)34 b Fe(is)28 b(1.)41 b(Negativ)n(e)27
+b(incremen)n(ts)f(are)h(p)r(ermitted.)3720 1028 y Fg(Strings)h(and)g
+(Common)e(Escap)s(e)h(Sequences)3720 1122 y Fe(A)h Fd(string)h(c)m
+(onstant)k Fe(consists)28 b(of)f(a)h(sequence)d(of)j(c)n(haracters)3720
+1196 y(enclosed)e(in)h(either)f(double-quote)g(or)i(single-quote)e
+(marks.)41 b(Strings)3720 1271 y(in)28 b(double-quotes)d(allo)n(w)j
+(the)f(use)g(of)h(the)f(escap)r(e)f(sequences)f(b)r(elo)n(w.)3720
+1376 y Ff(\\\\)536 b Fe(a)28 b(literal)f(bac)n(kslash)3720
+1451 y Ff(\\")536 b Fe(a)28 b(literal)f(double-quote)e(c)n(haracter)
+3720 1525 y Ff(\\')536 b Fe(a)28 b(literal)f(single-quote)f(c)n
+(haracter)3720 1600 y Ff(\\n)536 b Fe(newline,)26 b(ASCI)r(I)i(co)r(de)
+e(10)3720 1675 y Ff(\\t)536 b Fe(horizon)n(tal)27 b(tab,)g(ASCI)r(I)h
+(co)r(de)e(9)3720 1843 y Fg(Index)j(Expressions)3720
+1935 y Fd(var)f Ff(\()p Fd(idx)p Ff(\))324 b Fe(select)27
+b(elemen)n(ts)e(of)j(a)f(v)n(ector)3720 2009 y Fd(var)h
+Ff(\()p Fd(idx1)p Ff(,)g Fd(idx2)p Ff(\))103 b Fe(select)27
+b(elemen)n(ts)e(of)j(a)f(matrix)3791 2084 y Fd(sc)m(alar)361
+b Fe(select)27 b(ro)n(w)h(\(column\))e(corresp)r(onding)f(to)4368
+2159 y Fd(sc)m(alar)3791 2227 y(ve)m(ctor)355 b Fe(select)27
+b(ro)n(ws)h(\(columns\))e(corresp)r(onding)g(to)4368
+2302 y(the)h(elemen)n(ts)e(of)j Fd(ve)m(ctor)3791 2370
+y(r)m(ange)372 b Fe(select)27 b(ro)n(ws)h(\(columns\))e(corresp)r
+(onding)g(to)4368 2445 y(the)h(elemen)n(ts)e(of)j Fd(r)m(ange)3791
+2525 y Ff(:)500 b Fe(select)27 b(all)g(ro)n(ws)i(\(columns\))3720
+2697 y Fg(Global)e(and)i(P)m(ersisten)m(t)e(V)-8 b(ariables)3720
+2788 y Ff(global)30 b Fd(var1)d Ff(...)103 b Fe(Declare)26
+b(v)l(ariables)i(global.)3720 2863 y Ff(global)i Fd(var1)d
+Ff(=)h Fd(val)60 b Fe(Declare)26 b(v)l(ariable)h(global.)41
+b(Set)27 b(in)n(tial)g(v)l(alue.)3720 2938 y Ff(persistent)k
+Fd(var1)94 b Fe(Declare)26 b(a)i(v)l(ariable)f(as)h(static)f(to)h(a)g
+(function.)3720 3012 y Ff(persistent)j Fd(var1)c Ff(=)3720
+3087 y Fd(val)4326 3012 y Fe(Declare)f(a)i(v)l(ariable)f(as)h(static)f
+(to)h(a)g(function)4368 3087 y(and)f(set)g(its)h(initial)f(v)l(alue.)
+3720 3158 y(Global)h(v)l(ariables)f(ma)n(y)g(b)r(e)g(accessed)f(inside)
+h(the)f(b)r(o)r(dy)h(of)g(a)3720 3233 y(function)f(without)h(ha)n(ving)
+g(to)h(b)r(e)f(passed)g(in)g(the)g(function)3720 3308
+y(parameter)f(list)i(pro)n(vided)e(they)h(are)g(declared)e(global)j
+(when)e(used.)3720 3457 y Fg(Selected)i(Built-in)e(F)-8
+b(unctions)3720 3549 y Ff(EDITOR)396 b Fe(editor)27 b(to)h(use)f(with)g
+Ff(edit)p 5031 3549 22 4 v 27 w(history)3720 3623 y(Inf,)i(NaN)332
+b Fe(IEEE)27 b(in\014nit)n(y)-5 b(,)26 b(NaN)3720 3698
+y Ff(NA)536 b Fe(Missing)28 b(v)l(alue)3720 3773 y Ff(PAGER)431
+b Fe(program)27 b(to)h(use)f(to)h(paginate)f(output)3720
+3848 y Ff(ans)501 b Fe(last)28 b(result)f(not)g(explicitly)f(assigned)
+3720 3922 y Ff(eps)501 b Fe(mac)n(hine)26 b(precision)3720
+3997 y Ff(pi)536 b Fa(\031)3720 4109 y Ff(1i)4326 4043
+y Fb(p)p 4396 4043 107 4 v 4396 4109 a(\000)p Fc(1)3720
+4183 y Ff(realmax)361 b Fe(maxim)n(um)26 b(represen)n(table)f(v)l(alue)
+3720 4258 y Ff(realmin)361 b Fe(minim)n(um)26 b(represen)n(table)f(v)l
+(alue)3713 4350 y Fh(Cop)n(yrigh)n(t)k(1996,)g(1997,)g(2007)g(John)f
+(W.)f(Eaton)122 b(P)n(ermissions)28 b(on)f(bac)n(k)p
+5700 -433 1 17 v 5700 4350 V 5821 -367 a Fg(Assignmen)m(t)f
+(Expressions)5821 -276 y Fd(var)h Ff(=)h Fd(expr)292
+b Fe(assign)28 b(expression)e(to)i(v)l(ariable)5821 -201
+y Fd(var)f Ff(\()p Fd(idx)p Ff(\))h(=)g Fd(expr)106 b
+Fe(assign)28 b(expression)e(to)i(indexed)d(v)l(ariable)5821
+-126 y Fd(var)i Ff(\()p Fd(idx)p Ff(\))h(=)g([])164 b
+Fe(delete)25 b(the)i(indexed)e(elemen)n(ts.)5821 -34
+y Fd(var)i Fb(f)p Fd(idx)p Fb(g)g Ff(=)h Fd(expr)93 b
+Fe(assign)28 b(elemen)n(ts)d(of)j(a)f(cell)g(arra)n(y)-5
+b(.)5821 145 y Fg(Arithmetic)27 b(and)h(Incremen)m(t)g(Op)s(erators)
+5821 236 y Fd(x)f Ff(+)h Fd(y)451 b Fe(addition)5821
+311 y Fd(x)27 b Ff(-)h Fd(y)451 b Fe(subtraction)5821
+385 y Fd(x)27 b Ff(*)h Fd(y)451 b Fe(matrix)26 b(m)n(ultiplication)5821
+460 y Fd(x)h Ff(.*)h Fd(y)416 b Fe(elemen)n(t)25 b(b)n(y)i(elemen)n(t)f
+(m)n(ultiplication)5821 535 y Fd(x)h Ff(/)h Fd(y)451
+b Fe(righ)n(t)27 b(division,)f(conceptually)f(equiv)l(alen)n(t)h(to)
+6468 609 y Ff(\(inverse)k(\(y'\))f(*)f(x'\)')5821 695
+y Fd(x)f Ff(./)h Fd(y)416 b Fe(elemen)n(t)25 b(b)n(y)i(elemen)n(t)f
+(righ)n(t)h(division)5821 770 y Fd(x)g Ff(\\)h Fd(y)451
+b Fe(left)26 b(division,)h(conceptually)d(equiv)l(alen)n(t)i(to)6468
+845 y Ff(inverse)k(\(x\))e(*)g(y)5821 930 y Fd(x)f Ff(.\\)h
+Fd(y)416 b Fe(elemen)n(t)25 b(b)n(y)i(elemen)n(t)f(left)g(division)5821
+1005 y Fd(x)h Ff(^)h Fd(y)451 b Fe(p)r(o)n(w)n(er)27
+b(op)r(erator)5821 1080 y Fd(x)g Ff(.^)h Fd(y)416 b Fe(elemen)n(t)25
+b(b)n(y)i(elemen)n(t)f(p)r(o)n(w)n(er)h(op)r(erator)5821
+1155 y Ff(-)h Fd(x)511 b Fe(negation)5821 1229 y Ff(+)28
+b Fd(x)511 b Fe(unary)27 b(plus)g(\(a)g(no-op\))5821
+1304 y Fd(x)g Ff(')512 b Fe(complex)25 b(conjugate)h(transp)r(ose)5821
+1379 y Fd(x)h Ff(.')477 b Fe(transp)r(ose)5821 1454 y
+Ff(++)28 b Fd(x)70 b Fe(\()p Ff(--)28 b Fd(x)p Fe(\))224
+b(incremen)n(t)25 b(\(decremen)n(t\),)f(return)i Fd(new)35
+b Fe(v)l(alue)5821 1528 y Fd(x)27 b Ff(++)71 b Fe(\()p
+Fd(x)27 b Ff(--)p Fe(\))225 b(incremen)n(t)25 b(\(decremen)n(t\),)f
+(return)i Fd(old)34 b Fe(v)l(alue)5821 1700 y Fg(Comparison)26
+b(and)i(Bo)s(olean)f(Op)s(erators)5821 1800 y Fe(These)g(op)r(erators)g
+(w)n(ork)h(on)f(an)h(elemen)n(t-b)n(y-elemen)n(t)23 b(basis.)42
+b(Both)5821 1875 y(argumen)n(ts)26 b(are)i(alw)n(a)n(ys)g(ev)l
+(aluated.)5821 1980 y Fd(x)f Ff(<)h Fd(y)451 b Fe(true)26
+b(if)h Fd(x)35 b Fe(is)28 b(less)f(than)g Fd(y)5821 2054
+y(x)g Ff(<=)h Fd(y)416 b Fe(true)26 b(if)h Fd(x)35 b
+Fe(is)28 b(less)f(than)g(or)h(equal)f(to)g Fd(y)5821
+2129 y(x)g Ff(==)h Fd(y)416 b Fe(true)26 b(if)h Fd(x)35
+b Fe(is)28 b(equal)e(to)i Fd(y)5821 2204 y(x)f Ff(>=)h
+Fd(y)416 b Fe(true)26 b(if)h Fd(x)35 b Fe(is)28 b(greater)e(than)h(or)h
+(equal)f(to)g Fd(y)5821 2279 y(x)g Ff(>)h Fd(y)451 b
+Fe(true)26 b(if)h Fd(x)35 b Fe(is)28 b(greater)e(than)h
+Fd(y)5821 2353 y(x)g Ff(!=)h Fd(y)416 b Fe(true)26 b(if)h
+Fd(x)35 b Fe(is)28 b(not)f(equal)g(to)g Fd(y)5821 2428
+y(x)g Ff(&)h Fd(y)451 b Fe(true)26 b(if)h(b)r(oth)g Fd(x)35
+b Fe(and)27 b Fd(y)33 b Fe(are)27 b(true)5821 2503 y
+Fd(x)g Ff(|)h Fd(y)451 b Fe(true)26 b(if)h(at)h(least)f(one)g(of)h
+Fd(x)34 b Fe(or)28 b Fd(y)33 b Fe(is)28 b(true)5821 2577
+y Ff(!)41 b Fd(b)m(o)m(ol)416 b Fe(true)26 b(if)h Fd(b)m(o)m(ol)32
+b Fe(is)c(false)5821 2727 y Fg(Short-circuit)g(Bo)s(olean)e(Op)s
+(erators)5821 2827 y Fe(Op)r(erators)h(ev)l(aluate)f(left-to-righ)n(t.)
+41 b(Op)r(erands)26 b(are)h(only)g(ev)l(aluated)5821
+2902 y(if)g(necessary)-5 b(,)26 b(stopping)g(once)h(o)n(v)n(erall)g
+(truth)g(v)l(alue)g(can)g(b)r(e)5821 2977 y(determined.)38
+b(Op)r(erands)26 b(are)h(con)n(v)n(erted)f(to)i(scalars)g(using)f(the)g
+Ff(all)5821 3051 y Fe(function.)5821 3145 y Fd(x)g Ff(&&)h
+Fd(y)416 b Fe(true)26 b(if)h(b)r(oth)g Fd(x)35 b Fe(and)27
+b Fd(y)33 b Fe(are)27 b(true)5821 3219 y Fd(x)g Ff(||)h
+Fd(y)416 b Fe(true)26 b(if)h(at)h(least)f(one)g(of)h
+Fd(x)34 b Fe(or)28 b Fd(y)33 b Fe(is)28 b(true)5821 3388
+y Fg(Op)s(erator)f(Precedence)5821 3482 y Fe(T)-5 b(able)26
+b(of)i(Octa)n(v)n(e)f(op)r(erators,)g(in)g(order)g(of)g(increasing)f
+(precedence.)5821 3587 y Ff(;)55 b(,)481 b Fe(statemen)n(t)26
+b(separators)5821 3661 y Ff(=)571 b Fe(assignmen)n(t,)26
+b(groups)i(left)e(to)i(righ)n(t)5821 3736 y Ff(||)56
+b(&&)410 b Fe(logical)26 b(\\or")i(and)f(\\and")5821
+3811 y Ff(|)55 b(&)481 b Fe(elemen)n(t-wise)25 b(\\or")j(and)f(\\and")
+5821 3886 y Ff(<)h(<=)g(==)g(>=)g(>)g(!=)116 b Fe(relational)26
+b(op)r(erators)5821 3960 y Ff(:)571 b Fe(colon)5821 4035
+y Ff(+)55 b(-)481 b Fe(addition)26 b(and)h(subtraction)5821
+4110 y Ff(*)h(/)g(\\)55 b(.*)h(./)g(.\\)68 b Fe(m)n(ultiplication)25
+b(and)i(division)5821 4185 y Ff(')55 b(.')446 b Fe(transp)r(ose)5821
+4259 y Ff(+)55 b(-)h(++)g(--)g(!)138 b Fe(unary)27 b(min)n(us,)f
+(incremen)n(t,)f(logical)i(\\not")5821 4334 y Ff(^)55
+b(.^)446 b Fe(exp)r(onen)n(tiation)p eop end
+%%Page: 2 2
+TeXDict begin @landscape 2 1 bop -480 -367 a Fg(P)m(aths)29
+b(and)f(P)m(ac)m(k)-5 b(ages)-480 -276 y Ff(path)466
+b Fe(displa)n(y)27 b(the)g(curren)n(t)f(Octa)n(v)n(e)h(cunction)f
+(path.)-480 -201 y Ff(pathdef)361 b Fe(displa)n(y)27
+b(the)g(default)f(path.)-480 -115 y Ff(addpath\()p Fd(dir)p
+Ff(\))206 b Fe(add)27 b(a)h(directory)e(to)i(the)e(path.)-480
+-40 y Ff(EXEC)p -336 -40 22 4 v 27 w(PATH)299 b Fe(manipulate)25
+b(the)i(Octa)n(v)n(e)g(executable)e(path.)-480 34 y Ff(pkg)k(list)332
+b Fe(displa)n(y)27 b(installed)f(pac)n(k)l(ages.)-480
+109 y Ff(pkg)j(load)f Fd(p)m(ack)173 b Fe(Load)28 b(an)f(installed)f
+(pac)n(k)l(age.)-480 281 y Fg(Cells)g(and)i(Structures)-480
+372 y Fd(var)p Ff(.)p Fd(\014eld)g Ff(=)g(...)155 b Fe(set)27
+b(a)h(\014eld)e(of)i(a)g(structure.)-480 471 y Fd(var)p
+Fb(f)p Fd(idx)p Fb(g)f Ff(=)h(...)143 b Fe(set)27 b(an)h(elemen)n(t)d
+(of)j(a)f(cell)g(arra)n(y)-5 b(.)-480 563 y Ff(cellfun\()p
+Fd(f)p Ff(,)31 b Fd(c)p Ff(\))172 b Fe(apply)27 b(a)g(function)f(to)i
+(elemen)n(ts)e(of)h(cell)f(arra)n(y)-5 b(.)-480 637 y
+Ff(fieldnames\()p Fd(s)p Ff(\))158 b Fe(returns)27 b(the)f(\014elds)h
+(of)g(a)h(structure.)-480 799 y Fg(Statemen)m(ts)-480
+896 y Ff(for)h Fd(identi\014er)f Ff(=)g Fd(expr)f(stmt-list)i
+Ff(endfor)-397 979 y Fe(Execute)c Fd(stmt-list)k Fe(once)d(for)h(eac)n
+(h)g(column)f(of)h Fd(expr)p Fe(.)41 b(The)-397 1054
+y(v)l(ariable)27 b Fd(identi\014er)i Fe(is)f(set)f(to)h(the)e(v)l(alue)
+i(of)f(the)g(curren)n(t)f(column)-397 1128 y(during)h(eac)n(h)f
+(iteration.)-480 1284 y Ff(while)j(\()p Fd(c)m(ondition)p
+Ff(\))h Fd(stmt-list)e Ff(endwhile)-397 1364 y Fe(Execute)d
+Fd(stmt-list)k Fe(while)d Fd(c)m(ondition)j Fe(is)f(true.)-480
+1502 y Ff(break)459 b Fe(exit)26 b(innermost)h(lo)r(op)-480
+1577 y Ff(continue)354 b Fe(go)27 b(to)h(b)r(eginning)e(of)h(innermost)
+f(lo)r(op)-480 1651 y Ff(return)424 b Fe(return)26 b(to)i(calling)e
+(function)-480 1825 y Ff(if)i(\()p Fd(c)m(ondition)p
+Ff(\))i Fd(if-b)m(o)m(dy)d Fc([)p Ff(else)i Fd(else-b)m(o)m(dy)p
+Fc(])d Ff(endif)-397 1917 y Fe(Execute)f Fd(if-b)m(o)m(dy)j
+Fe(if)f Fd(c)m(ondition)i Fe(is)f(true,)e(otherwise)h(execute)e
+Fd(else-)-397 1992 y(b)m(o)m(dy)p Fe(.)-480 2090 y Ff(if)j(\()p
+Fd(c)m(ondition)p Ff(\))i Fd(if-b)m(o)m(dy)d Fc([)p Ff(elseif)j
+Fe(\()p Fd(c)m(ondition)p Fe(\))f Fd(elseif-b)m(o)m(dy)p
+Fc(])e Ff(endif)-397 2182 y Fe(Execute)e Fd(if-b)m(o)m(dy)j
+Fe(if)f Fd(c)m(ondition)i Fe(is)f(true,)e(otherwise)h(execute)e(the)
+-397 2257 y Fd(elseif-b)m(o)m(dy)i Fe(corresp)r(onding)f(to)h(the)g
+(\014rst)g Ff(elseif)j Fe(condition)c(that)-397 2332
+y(is)i(true,)e(otherwise)h(execute)e Fd(else-b)m(o)m(dy)p
+Fe(.)-397 2415 y(An)n(y)i(n)n(um)n(b)r(er)f(of)i Ff(elseif)h
+Fe(clauses)e(ma)n(y)g(app)r(ear)g(in)g(an)g Ff(if)-397
+2490 y Fe(statemen)n(t.)-480 2624 y Ff(unwind)p -266
+2624 V 27 w(protect)j Fd(b)m(o)m(dy)d Ff(unwind)p 402
+2624 V 27 w(protect)p 674 2624 V 27 w(cleanup)j Fd(cle)m(anup)d
+Ff(end)-397 2711 y Fe(Execute)e Fd(b)m(o)m(dy)p Fe(.)41
+b(Execute)25 b Fd(cle)m(anup)i Fe(no)h(matter)e(ho)n(w)i(con)n(trol)
+-397 2785 y(exits)f Fd(b)m(o)m(dy)p Fe(.)-480 2856 y
+Ff(try)i Fd(b)m(o)m(dy)d Ff(catch)k Fd(cle)m(anup)c Ff(end)-397
+2935 y Fe(Execute)f Fd(b)m(o)m(dy)p Fe(.)41 b(Execute)25
+b Fd(cle)m(anup)i Fe(if)g Fd(b)m(o)m(dy)g Fe(fails.)-480
+3112 y Fg(Strings)-480 3203 y Ff(strcmp)i(\()p Fd(s)p
+Ff(,)g Fd(t)p Ff(\))392 b Fe(compare)26 b(strings)-480
+3289 y Ff(strcat)j(\()p Fd(s)p Ff(,)g Fd(t)p Ff(,)f(...\))224
+b Fe(concatenate)25 b(strings)-480 3364 y Ff(regexp)k(\()p
+Fd(str)p Ff(,)g Fd(p)m(at)p Ff(\))273 b Fe(strings)28
+b(matc)n(hing)e(regular)h(expression)-480 3450 y Ff(regexprep)j(\()p
+Fd(str)p Ff(,)f Fd(p)m(at)p Ff(,)f Fd(r)m(ep)p Ff(\))11
+b Fe(Matc)n(h)27 b(and)g(replace)f(sub-strings)-480 3622
+y Fg(De\014ning)h(F)-8 b(unctions)-480 3758 y Ff(function)30
+b Fc([)p Fd(r)m(et-list)p Fc(])e Fd(function-name)g Fc([)13
+b Fe(\()p Fd(ar)m(g-list)p Fe(\))h Fc(])-409 3842 y Fd(function-b)m(o)m
+(dy)-480 3928 y Ff(endfunction)-480 4068 y Fd(r)m(et-list)33
+b Fe(ma)n(y)27 b(b)r(e)g(a)h(single)f(iden)n(ti\014er)e(or)j(a)f
+(comma-separated)f(list)-480 4143 y(of)h(iden)n(ti\014ers)f(delimited)f
+(b)n(y)i(square-brac)n(k)n(ets.)-480 4238 y Fd(ar)m(g-list)33
+b Fe(is)28 b(a)g(comma-separated)d(list)j(of)f(iden)n(ti\014ers)f(and)h
+(ma)n(y)g(b)r(e)-480 4313 y(empt)n(y)-5 b(.)p 1499 -433
+1 17 v 1499 4350 V 1620 -367 a Fg(F)d(unction)28 b(Handles)1620
+-276 y Ff(@)p Fd(func)443 b Fe(De\014ne)26 b(a)i(function)d(handle)i
+(to)g Fd(func)p Fe(.)1620 -201 y Ff(@\()p Fd(var1)p Ff(,)i(...\))42
+b Fd(expr)31 b Fe(De\014ne)26 b(an)i(anon)n(ymous)e(function)g(handle.)
+1620 -126 y Ff(str2func)k(\()p Fd(str)p Ff(\))146 b Fe(Create)27
+b(a)h(function)e(handle)g(from)h(a)g(string.)1620 -51
+y Ff(functions)1620 23 y(\()p Fd(hand)s(le)p Ff(\))2226
+-51 y Fe(Return)g(information)f(ab)r(out)h(a)g(function)2268
+23 y(handle.)1620 100 y Ff(func2str)j(\()p Fd(hand)s(le)p
+Ff(\))g Fe(Return)d(a)h(string)f(represen)n(tation)e(of)j(a)2268
+175 y(function)d(handle.)1620 246 y Fd(hand)s(le)k Ff(\()p
+Fd(ar)m(g1)p Ff(,)e(...\))16 b Fe(Ev)l(aluate)27 b(a)h(function)d
+(handle.)1620 320 y Ff(feval)k(\()p Fd(func)p Ff(,)g
+Fd(ar)m(g1)p Ff(,)1620 395 y(...\))2226 320 y Fe(Ev)l(aluate)e(a)h
+(function)d(handle)h(or)i(string,)2268 395 y(passing)f(remaining)f
+(args)i(to)g Fd(func)1620 478 y Fe(Anon)n(ymous)f(function)f(handles)g
+(tak)n(e)h(a)h(cop)n(y)f(of)g(the)g(v)l(ariables)g(in)1620
+553 y(the)g(curren)n(t)f(w)n(orkspace.)1620 732 y Fg(Miscellaneous)g(F)
+-8 b(unctions)1620 823 y Ff(eval)29 b(\()p Fd(str)p Ff(\))287
+b Fe(ev)l(aluate)27 b Fd(str)h Fe(as)g(a)g(command)1620
+898 y Ff(error)h(\()p Fd(message)p Ff(\))89 b Fe(prin)n(t)27
+b(message)g(and)g(return)g(to)g(top)h(lev)n(el)1620 973
+y Ff(warning)i(\()p Fd(message)p Ff(\))18 b Fe(prin)n(t)27
+b(a)h(w)n(arning)f(message)1620 1048 y Ff(clear)i Fd(p)m(attern)190
+b Fe(clear)27 b(v)l(ariables)g(matc)n(hing)f(pattern)1620
+1122 y Ff(exist)j(\()p Fd(str)p Ff(\))252 b Fe(c)n(hec)n(k)26
+b(existence)g(of)h(v)l(ariable)g(or)h(function)1620 1197
+y Ff(who,)h(whos)297 b Fe(list)28 b(curren)n(t)e(v)l(ariables)1620
+1272 y Ff(whos)j Fd(var)341 b Fe(details)27 b(of)g(the)g(v)l(aribale)g
+Fd(var)1620 1421 y Fg(Basic)h(Matrix)g(Manipulations)1620
+1512 y Ff(rows)h(\()p Fd(a)p Ff(\))332 b Fe(return)27
+b(n)n(um)n(b)r(er)e(of)j(ro)n(ws)g(of)g Fd(a)1620 1587
+y Ff(columns)i(\()p Fd(a)p Ff(\))226 b Fe(return)27 b(n)n(um)n(b)r(er)e
+(of)j(columns)e(of)h Fd(a)1620 1662 y Ff(all)i(\()p Fd(a)p
+Ff(\))367 b Fe(c)n(hec)n(k)26 b(if)h(all)h(elemen)n(ts)d(of)j
+Fd(a)33 b Fe(nonzero)1620 1737 y Ff(any)c(\()p Fd(a)p
+Ff(\))367 b Fe(c)n(hec)n(k)26 b(if)h(an)n(y)h(elemen)n(ts)e(of)h
+Fd(a)33 b Fe(nonzero)1620 1914 y Ff(find)c(\()p Fd(a)p
+Ff(\))332 b Fe(return)27 b(indices)e(of)j(nonzero)e(elemen)n(ts)1620
+1988 y Ff(sort)j(\()p Fd(a)p Ff(\))332 b Fe(order)27
+b(elemen)n(ts)f(in)h(eac)n(h)g(column)e(of)j Fd(a)1620
+2063 y Ff(sum)h(\()p Fd(a)p Ff(\))367 b Fe(sum)27 b(elemen)n(ts)f(in)h
+(columns)f(of)i Fd(a)1620 2138 y Ff(prod)h(\()p Fd(a)p
+Ff(\))332 b Fe(pro)r(duct)26 b(of)h(elemen)n(ts)f(in)h(columns)g(of)g
+Fd(a)1620 2224 y Ff(min)i(\()p Fd(ar)m(gs)p Ff(\))281
+b Fe(\014nd)27 b(minim)n(um)e(v)l(alues)1620 2298 y Ff(max)k(\()p
+Fd(ar)m(gs)p Ff(\))281 b Fe(\014nd)27 b(maxim)n(um)f(v)l(alues)1620
+2373 y Ff(rem)j(\()p Fd(x)p Ff(,)f Fd(y)p Ff(\))274 b
+Fe(\014nd)27 b(remainder)e(of)i Fd(x)p Fe(/)p Fd(y)1620
+2459 y Ff(reshape)j(\()p Fd(a)p Ff(,)e Fd(m)p Ff(,)g
+Fd(n)p Ff(\))6 b Fe(reformat)26 b Fd(a)i Fe(to)g(b)r(e)f
+Fd(m)g Fe(b)n(y)g Fd(n)1620 2544 y Ff(diag)i(\()p Fd(v)p
+Ff(,)f Fd(k)p Ff(\))240 b Fe(create)26 b(diagonal)h(matrices)1620
+2630 y Ff(linspace)j(\()p Fd(b)p Ff(,)e Fd(l)p Ff(,)g
+Fd(n)p Ff(\))12 b Fe(create)26 b(v)n(ector)h(of)h(linearly-spaced)d
+(elemen)n(ts)1620 2716 y Ff(logspace)30 b(\()p Fd(b)p
+Ff(,)e Fd(l)p Ff(,)g Fd(n)p Ff(\))12 b Fe(create)26 b(v)n(ector)h(of)h
+(log-spaced)e(elemen)n(ts)1620 2802 y Ff(eye)j(\()p Fd(n)p
+Ff(,)f Fd(m)p Ff(\))245 b Fe(create)26 b Fd(n)34 b Fe(b)n(y)27
+b Fd(m)32 b Fe(iden)n(tit)n(y)26 b(matrix)1620 2888 y
+Ff(ones)j(\()p Fd(n)p Ff(,)g Fd(m)p Ff(\))209 b Fe(create)26
+b Fd(n)34 b Fe(b)n(y)27 b Fd(m)32 b Fe(matrix)27 b(of)g(ones)1620
+2962 y Ff(zeros)i(\()p Fd(n)p Ff(,)g Fd(m)p Ff(\))174
+b Fe(create)26 b Fd(n)34 b Fe(b)n(y)27 b Fd(m)32 b Fe(matrix)27
+b(of)g(zeros)1620 3037 y Ff(rand)i(\()p Fd(n)p Ff(,)g
+Fd(m)p Ff(\))209 b Fe(create)26 b Fd(n)34 b Fe(b)n(y)27
+b Fd(m)32 b Fe(matrix)27 b(of)g(random)g(v)l(alues)1620
+3206 y Fg(Linear)h(Algebra)1620 3297 y Ff(chol)h(\()p
+Fd(a)p Ff(\))332 b Fe(Cholesky)27 b(factorization)1620
+3372 y Ff(det)i(\()p Fd(a)p Ff(\))367 b Fe(compute)26
+b(the)h(determinan)n(t)e(of)i(a)h(matrix)1620 3446 y
+Ff(eig)h(\()p Fd(a)p Ff(\))367 b Fe(eigen)n(v)l(alues)26
+b(and)h(eigen)n(v)n(ectors)1620 3532 y Ff(expm)i(\()p
+Fd(a)p Ff(\))332 b Fe(compute)26 b(the)h(exp)r(onen)n(tial)e(of)i(a)h
+(matrix)1620 3618 y Ff(hess)h(\()p Fd(a)p Ff(\))332 b
+Fe(compute)26 b(Hessen)n(b)r(erg)g(decomp)r(osition)1620
+3693 y Ff(inverse)k(\()p Fd(a)p Ff(\))226 b Fe(in)n(v)n(ert)27
+b(a)h(square)f(matrix)1620 3767 y Ff(norm)i(\()p Fd(a)p
+Ff(,)f Fd(p)p Ff(\))234 b Fe(compute)26 b(the)h Fd(p)p
+Fe(-norm)g(of)g(a)h(matrix)1620 3842 y Ff(pinv)h(\()p
+Fd(a)p Ff(\))332 b Fe(compute)26 b(pseudoin)n(v)n(erse)f(of)j
+Fd(a)1620 3928 y Ff(qr)g(\()p Fd(a)p Ff(\))403 b Fe(compute)26
+b(the)h(QR)g(factorization)f(of)i(a)f(matrix)1620 4014
+y Ff(rank)i(\()p Fd(a)p Ff(\))332 b Fe(matrix)27 b(rank)1620
+4088 y Ff(sprank)j(\()p Fd(a)p Ff(\))261 b Fe(structrual)27
+b(matrix)g(rank)1620 4174 y Ff(schur)i(\()p Fd(a)p Ff(\))297
+b Fe(Sc)n(h)n(ur)27 b(decomp)r(osition)e(of)i(a)h(matrix)1620
+4249 y Ff(svd)h(\()p Fd(a)p Ff(\))367 b Fe(singular)27
+b(v)l(alue)g(decomp)r(osition)1620 4324 y Ff(syl)i(\()p
+Fd(a)p Ff(,)f Fd(b)p Ff(,)g Fd(c)p Ff(\))177 b Fe(solv)n(e)28
+b(the)e(Sylv)n(ester)h(equation)p 3600 -433 V 3600 4350
+V 3720 -367 a Fg(Equations,)g(ODEs,)g(D)m(AEs,)g(Quadrature)3720
+-276 y Ff(*fsolve)361 b Fe(solv)n(e)28 b(nonlinear)e(algebraic)g
+(equations)3720 -201 y Ff(*lsode)396 b Fe(in)n(tegrate)27
+b(nonlinear)f(ODEs)3720 -126 y Ff(*dassl)396 b Fe(in)n(tegrate)27
+b(nonlinear)f(D)n(AEs)3720 -51 y Ff(*quad)431 b Fe(in)n(tegrate)27
+b(nonlinear)f(functions)3720 34 y Ff(perror)k(\()p Fd(nm)p
+Ff(,)e Fd(c)m(o)m(de)p Ff(\))11 b Fe(for)28 b(functions)e(that)h
+(return)f(n)n(umeric)g(co)r(des,)4368 109 y(prin)n(t)h(error)g(message)
+g(for)g(named)f(function)4368 184 y(and)h(giv)n(en)g(error)g(co)r(de)
+3720 285 y Ff(*)h Fe(See)f(the)g(on-line)f(or)i(prin)n(ted)e(man)n(ual)
+h(for)g(the)g(complete)e(list)j(of)3720 360 y(argumen)n(ts)f(for)g
+(these)g(functions.)3720 509 y Fg(Signal)g(Pro)s(cessing)3720
+601 y Ff(fft)i(\()p Fd(a)p Ff(\))367 b Fe(F)-5 b(ast)28
+b(F)-5 b(ourier)26 b(T)-5 b(ransform)27 b(using)g(FFTW)3720
+675 y Ff(ifft)i(\()p Fd(a)p Ff(\))332 b Fe(in)n(v)n(erse)27
+b(FFT)h(using)f(FFTW)3720 750 y Ff(freqz)j(\()p Fd(ar)m(gs)p
+Ff(\))210 b Fe(FIR)28 b(\014lter)f(frequency)d(resp)r(onse)3720
+836 y Ff(filter)30 b(\()p Fd(a)p Ff(,)e Fd(b)p Ff(,)g
+Fd(x)p Ff(\))71 b Fe(\014lter)27 b(b)n(y)g(transfer)g(function)3720
+911 y Ff(conv)i(\()p Fd(a)p Ff(,)g Fd(b)p Ff(\))236 b
+Fe(con)n(v)n(olv)n(e)27 b(t)n(w)n(o)i(v)n(ectors)3720
+985 y Ff(hamming)h(\()p Fd(n)p Ff(\))223 b Fe(return)27
+b(Hamming)f(windo)n(w)i(co)r(e\016cen)n(ts)3720 1071
+y Ff(hanning)i(\()p Fd(n)p Ff(\))223 b Fe(return)27 b(Hanning)f(windo)n
+(w)i(co)r(e\016cen)n(ts)3720 1243 y Fg(Image)g(Pro)s(cessing)3720
+1335 y Ff(colormap)i(\()p Fd(map)p Ff(\))310 b Fe(set)28
+b(the)f(curren)n(t)f(colormap)3720 1420 y Ff(gray2ind)k(\()p
+Fd(i)p Ff(,)f Fd(n)p Ff(\))313 b Fe(con)n(v)n(ert)27
+b(gra)n(y)h(scale)f(to)h(Octa)n(v)n(e)f(image)3720 1506
+y Ff(image)j(\()p Fd(img)p Ff(,)d Fd(zo)m(om)p Ff(\))219
+b Fe(displa)n(y)27 b(an)h(Octa)n(v)n(e)f(image)g(matrix)3720
+1592 y Ff(imagesc)j(\()p Fd(img)p Ff(,)e Fd(zo)m(om)p
+Ff(\))148 b Fe(displa)n(y)27 b(scaled)g(matrix)g(as)h(image)3720
+1678 y Ff(imshow)i(\()p Fd(img)p Ff(,)e Fd(map)p Ff(\))208
+b Fe(displa)n(y)27 b(Octa)n(v)n(e)g(image)3720 1752 y
+Ff(imshow)j(\()p Fd(i)p Ff(,)e Fd(n)p Ff(\))384 b Fe(displa)n(y)27
+b(gra)n(y)h(scale)f(image)3720 1827 y Ff(imshow)j(\()p
+Fd(r)p Ff(,)e Fd(g)p Ff(,)g Fd(b)p Ff(\))287 b Fe(displa)n(y)27
+b(R)n(GB)i(image)3720 1902 y Ff(ind2gray)h(\()p Fd(img)p
+Ff(,)e Fd(map)p Ff(\))138 b Fe(con)n(v)n(ert)27 b(Octa)n(v)n(e)g(image)
+g(to)g(gra)n(y)h(scale)3720 1988 y Ff(ind2rgb)i(\()p
+Fd(img)p Ff(,)e Fd(map)p Ff(\))173 b Fe(con)n(v)n(ert)27
+b(indexed)e(image)i(to)h(R)n(GB)3720 2073 y Ff(loadimage)j(\()p
+Fd(\014le)p Ff(\))311 b Fe(load)28 b(an)f(image)g(\014le)3720
+2159 y Ff(rgb2ind)j(\()p Fd(r)p Ff(,)e Fd(g)p Ff(,)g
+Fd(b)p Ff(\))252 b Fe(con)n(v)n(ert)27 b(R)n(GB)i(to)f(Octa)n(v)n(e)f
+(image)3720 2245 y Ff(saveimage)k(\()p Fd(\014le)p Ff(,)d
+Fd(img)p Ff(,)f Fd(fmt)p Ff(,)h Fd(map)p Ff(\))71 b Fe(sa)n(v)n(e)28
+b(a)g(matrix)e(to)i Fd(\014le)3720 2394 y Fg(C-st)m(yle)g(Input)g(and)g
+(Output)3720 2486 y Ff(fopen)i(\()p Fd(name)p Ff(,)d
+Fd(mo)m(de)p Ff(\))163 b Fe(op)r(en)27 b(\014le)f Fd(name)3720
+2572 y Ff(fclose)k(\()p Fd(\014le)p Ff(\))417 b Fe(close)27
+b Fd(\014le)3720 2646 y Ff(printf)j(\()p Fd(fmt)p Ff(,)e(...\))238
+b Fe(formatted)26 b(output)h(to)h Ff(stdout)3720 2732
+y(fprintf)i(\()p Fd(\014le)p Ff(,)e Fd(fmt)p Ff(,)g(...\))51
+b Fe(formatted)26 b(output)h(to)h Fd(\014le)3720 2818
+y Ff(sprintf)i(\()p Fd(fmt)p Ff(,)e(...\))203 b Fe(formatted)26
+b(output)h(to)h(string)3720 2904 y Ff(scanf)i(\()p Fd(fmt)p
+Ff(\))441 b Fe(formatted)26 b(input)h(from)g Ff(stdin)3720
+2978 y(fscanf)j(\()p Fd(\014le)p Ff(,)e Fd(fmt)p Ff(\))254
+b Fe(formatted)26 b(input)h(from)g Fd(\014le)3720 3053
+y Ff(sscanf)j(\()p Fd(str)p Ff(,)e Fd(fmt)p Ff(\))263
+b Fe(formatted)26 b(input)h(from)g Fd(string)3720 3128
+y Ff(fgets)j(\()p Fd(\014le)p Ff(,)e Fd(len)p Ff(\))301
+b Fe(read)27 b Fd(len)33 b Fe(c)n(haracters)26 b(from)h
+Fd(\014le)3720 3214 y Ff(fflush)j(\()p Fd(\014le)p Ff(\))417
+b Fe(\015ush)27 b(p)r(ending)f(output)g(to)i Fd(\014le)3720
+3288 y Ff(ftell)i(\()p Fd(\014le)p Ff(\))452 b Fe(return)27
+b(\014le)f(p)r(oin)n(ter)h(p)r(osition)3720 3363 y Ff(frewind)j(\()p
+Fd(\014le)p Ff(\))382 b Fe(mo)n(v)n(e)28 b(\014le)e(p)r(oin)n(ter)g(to)
+i(b)r(eginning)3720 3438 y Ff(freport)571 b Fe(prin)n(t)27
+b(a)h(info)f(for)g(op)r(en)g(\014les)3720 3524 y Ff(fread)j(\()p
+Fd(\014le)p Ff(,)e Fd(size)p Ff(,)g Fd(pr)m(e)m(c)p Ff(\))95
+b Fe(read)27 b(binary)g(data)g(\014les)3720 3598 y Ff(fwrite)j(\()p
+Fd(\014le)p Ff(,)e Fd(size)p Ff(,)h Fd(pr)m(e)m(c)p Ff(\))59
+b Fe(write)28 b(binary)e(data)i(\014les)3720 3673 y Ff(feof)h(\()p
+Fd(\014le)p Ff(\))488 b Fe(determine)25 b(if)i(p)r(oin)n(ter)g(is)g(at)
+h(EOF)3720 3768 y(A)g(\014le)f(ma)n(y)g(b)r(e)g(referenced)d(either)i
+(b)n(y)h(name)g(or)g(b)n(y)h(the)f(n)n(um)n(b)r(er)3720
+3843 y(returned)f(from)h Ff(fopen)p Fe(.)43 b(Three)26
+b(\014les)h(are)g(preconnected)d(when)3720 3918 y(Octa)n(v)n(e)j
+(starts:)42 b Ff(stdin)p Fe(,)29 b Ff(stdout)p Fe(,)g(and)e
+Ff(stderr)p Fe(.)3720 4097 y Fg(Other)h(Input)g(and)g(Output)g
+(functions)3720 4189 y Ff(save)h Fd(\014le)f(var)f Ff(...)92
+b Fe(sa)n(v)n(e)28 b(v)l(ariables)f(in)h Fd(\014le)3720
+4263 y Ff(load)h Fd(\014le)348 b Fe(load)28 b(v)l(ariables)f(from)g
+Fd(\014le)3720 4338 y Ff(disp)i(\()p Fd(var)p Ff(\))271
+b Fe(displa)n(y)27 b(v)l(alue)h(of)f Fd(var)g Fe(to)h(screen)p
+5700 -433 V 5700 4350 V 5821 -367 a Fg(P)m(olynomials)5821
+-276 y Ff(compan)h(\()p Fd(p)p Ff(\))262 b Fe(companion)25
+b(matrix)5821 -190 y Ff(conv)j(\()p Fd(a)p Ff(,)h Fd(b)p
+Ff(\))237 b Fe(con)n(v)n(olution)5821 -115 y Ff(deconv)29
+b(\()p Fd(a)p Ff(,)f Fd(b)p Ff(\))167 b Fe(decon)n(v)n(olv)n(e)26
+b(t)n(w)n(o)i(v)n(ectors)5821 -40 y Ff(poly)g(\()p Fd(a)p
+Ff(\))333 b Fe(create)26 b(p)r(olynomial)g(from)h(a)g(matrix)5821
+45 y Ff(polyderiv)j(\()p Fd(p)p Ff(\))156 b Fe(deriv)l(ativ)n(e)26
+b(of)h(p)r(olynomial)5821 131 y Ff(polyreduce)j(\()p
+Fd(p)p Ff(\))121 b Fe(in)n(tegral)26 b(of)i(p)r(olynomial)5821
+217 y Ff(polyval)h(\()p Fd(p)p Ff(,)g Fd(x)p Ff(\))131
+b Fe(v)l(alue)27 b(of)g(p)r(olynomial)f(at)i Fd(x)5821
+303 y Ff(polyvalm)i(\()p Fd(p)p Ff(,)e Fd(x)p Ff(\))96
+b Fe(v)l(alue)27 b(of)g(p)r(olynomial)f(at)i Fd(x)5821
+389 y Ff(roots)h(\()p Fd(p)p Ff(\))297 b Fe(p)r(olynomial)25
+b(ro)r(ots)5821 463 y Ff(residue)k(\()p Fd(a)p Ff(,)g
+Fd(b)p Ff(\))131 b Fe(partial)27 b(fraction)f(expansion)g(of)i(ratio)f
+Fd(a)p Fe(/)p Fd(b)5821 635 y Fg(Statistics)5821 726
+y Ff(corrcoef)j(\()p Fd(x)p Ff(,)d Fd(y)p Ff(\))99 b
+Fe(correlation)26 b(co)r(e\016cien)n(t)5821 801 y Ff(cov)i(\()p
+Fd(x)p Ff(,)g Fd(y)p Ff(\))275 b Fe(co)n(v)l(ariance)5821
+876 y Ff(mean)28 b(\()p Fd(a)p Ff(\))333 b Fe(mean)26
+b(v)l(alue)5821 951 y Ff(median)j(\()p Fd(a)p Ff(\))262
+b Fe(median)26 b(v)l(alue)5821 1025 y Ff(std)i(\()p Fd(a)p
+Ff(\))368 b Fe(standard)27 b(deviation)5821 1100 y Ff(var)h(\()p
+Fd(a)p Ff(\))368 b Fe(v)l(ariance)5821 1263 y Fg(Plotting)26
+b(F)-8 b(unctions)5821 1354 y Ff(plot)28 b(\()p Fd(ar)m(gs)p
+Ff(\))247 b Fe(2D)27 b(plot)h(with)f(linear)f(axes)5821
+1440 y Ff(plot3)j(\()p Fd(ar)m(gs)p Ff(\))211 b Fe(3D)27
+b(plot)h(with)f(linear)f(axes)5821 1526 y Ff(line)i(\()p
+Fd(ar)m(gs)p Ff(\))247 b Fe(2D)27 b(or)h(3D)g(line)5821
+1600 y Ff(patch)h(\()p Fd(ar)m(gs)p Ff(\))211 b Fe(2D)27
+b(patc)n(h)5821 1686 y Ff(semilogx)j(\()p Fd(ar)m(gs)p
+Ff(\))105 b Fe(2D)27 b(plot)h(with)f(logarithmic)f(x-axis)5821
+1772 y Ff(semilogy)k(\()p Fd(ar)m(gs)p Ff(\))105 b Fe(2D)27
+b(plot)h(with)f(logarithmic)f(y-axis)5821 1858 y Ff(loglog)j(\()p
+Fd(ar)m(gs)p Ff(\))176 b Fe(2D)27 b(plot)h(with)f(logarithmic)f(axes)
+5821 1944 y Ff(bar)i(\()p Fd(ar)m(gs)p Ff(\))282 b Fe(plot)27
+b(bar)g(c)n(harts)5821 2018 y Ff(stairs)i(\()p Fd(x)p
+Ff(,)f Fd(y)p Ff(\))169 b Fe(plot)27 b(stairsteps)5821
+2093 y Ff(stem)h(\()p Fd(x)p Ff(,)g(it)h(y\))139 b Fe(plot)27
+b(a)h(stem)e(graph)5821 2179 y Ff(hist)i(\()p Fd(y)p
+Ff(,)h Fd(x)p Ff(\))239 b Fe(plot)27 b(histograms)5821
+2254 y Ff(contour)i(\()p Fd(x)p Ff(,)f Fd(y)p Ff(,)g
+Fd(z)p Ff(\))43 b Fe(con)n(tour)26 b(plot)5821 2328 y
+Ff(title)j(\()p Fd(string)p Ff(\))161 b Fe(set)27 b(plot)g(title)5821
+2403 y Ff(axis)h(\()p Fd(limits)p Ff(\))201 b Fe(set)27
+b(axis)h(ranges)5821 2478 y Ff(xlabel)h(\()p Fd(string)p
+Ff(\))126 b Fe(set)27 b(x-axis)h(lab)r(el)5821 2552 y
+Ff(ylabel)h(\()p Fd(string)p Ff(\))126 b Fe(set)27 b(y-axis)h(lab)r(el)
+5821 2638 y Ff(zlabel)h(\()p Fd(string)p Ff(\))126 b
+Fe(set)27 b(z-axis)h(lab)r(el)5821 2713 y Ff(text)g(\()p
+Fd(x)p Ff(,)g Fd(y)p Ff(,)h Fd(str)p Ff(\))96 b Fe(add)27
+b(text)g(to)g(a)h(plot)5821 2788 y Ff(legend)h(\()p Fd(string)p
+Ff(\))126 b Fe(set)27 b(lab)r(el)f(in)h(plot)h(k)n(ey)5821
+2890 y Ff(grid)g Fc([)p Fe(on)p Fb(j)p Fe(o\013)p Fc(])227
+b Fe(set)27 b(grid)g(state)5821 2997 y Ff(hold)h Fc([)p
+Fe(on)p Fb(j)p Fe(o\013)p Fc(])227 b Fe(set)27 b(hold)g(state)5821
+3084 y Ff(ishold)396 b Fe(return)26 b(1)i(if)f(hold)g(is)g(on,)h(0)f
+(otherwise)5821 3158 y Ff(mesh)h(\()p Fd(x)p Ff(,)g Fd(y)p
+Ff(,)h Fd(z)p Ff(\))148 b Fe(plot)27 b(3D)h(surface)5821
+3233 y Ff(meshgrid)i(\()p Fd(x)p Ff(,)d Fd(y)p Ff(\))99
+b Fe(create)26 b(mesh)g(co)r(ordinate)g(matrices)p 5821
+3323 1860 4 v 5821 3491 a Fh(Edition)g(2.0)i(for)g(Octa)n(v)n(e)h(V)-5
+b(ersion)28 b(3.0.0.)41 b(Cop)n(yrigh)n(t)29 b(1996,)g(2007,)g(John)
+5821 3565 y(W.)e(Eaton)h(\(jw)n(e at o)r(cta)n(v)n(e.org\).)43
+b(The)28 b(author)g(assumes)h(no)f(resp)r(onsibilit)n(y)5821
+3640 y(for)g(an)n(y)g(errors)h(on)e(this)h(card.)5821
+3765 y(This)f(card)h(ma)n(y)g(b)r(e)g(freely)f(distributed)f(under)h
+(the)h(terms)g(of)g(the)g(GNU)5821 3839 y(General)f(Public)f(License.)
+5821 3964 y(T)5854 3975 y(E)5887 3964 y(X)h(Macros)j(for)e(this)f(card)
+h(b)n(y)g(Roland)f(P)n(esc)n(h)i(\(p)r(esc)n(h at cygn)n(us.com\),)5821
+4039 y(originally)d(for)j(the)e(GDB)h(reference)g(card)5821
+4163 y(Octa)n(v)n(e)h(itself)e(is)g(free)i(soft)n(w)n(are;)g(y)n(ou)g
+(are)f(w)n(elcome)h(to)f(distribute)e(copies)5821 4238
+y(of)i(it)f(under)g(the)g(terms)h(of)h(the)e(GNU)g(General)h(Public)e
+(License.)40 b(There)5821 4313 y(is)27 b(absolutely)h(no)f(w)n(arran)n
+(t)n(y)j(for)e(Octa)n(v)n(e.)p eop end
+%%Trailer
+
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/doc/refcard/refcard-legal.tex b/doc/refcard/refcard-legal.tex
new file mode 100644
index 0000000..fb0ecb8
--- /dev/null
+++ b/doc/refcard/refcard-legal.tex
@@ -0,0 +1,24 @@
+% refcard-legal.tex
+%
+% Make a reference card that will fit on US legal paper.
+%
+% Copyright (C) 1996 John W. Eaton
+%
+% This file is part of Octave.
+%
+% Octave is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 3 of the License, or (at your
+% option) any later version.
+%
+% Octave is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Octave; see the file COPYING.  If not, see
+% <http://www.gnu.org/licenses/>.
+
+\def\refcardsize{legal}
+\input refcard.tex
diff --git a/doc/refcard/refcard-letter.dvi b/doc/refcard/refcard-letter.dvi
new file mode 100644
index 0000000..a9a6533
Binary files /dev/null and b/doc/refcard/refcard-letter.dvi differ
diff --git a/doc/refcard/refcard-letter.pdf b/doc/refcard/refcard-letter.pdf
new file mode 100644
index 0000000..9ded4fc
Binary files /dev/null and b/doc/refcard/refcard-letter.pdf differ
diff --git a/doc/refcard/refcard-letter.ps b/doc/refcard/refcard-letter.ps
new file mode 100644
index 0000000..c060b66
--- /dev/null
+++ b/doc/refcard/refcard-letter.ps
@@ -0,0 +1,3055 @@
+%!PS-Adobe-2.0
+%%Creator: dvips(k) 5.96 Copyright 2005 Radical Eye Software
+%%Title: refcard-letter.dvi
+%%CreationDate: Thu Dec 10 12:05:33 2009
+%%Pages: 3
+%%PageOrder: Ascend
+%%Orientation: Landscape
+%%BoundingBox: 0 0 612 792
+%%DocumentFonts: CMBX12 CMR6 CMBX10 CMTT8 CMR7 CMTI7 CMR10 CMSY10 CMMI10
+%%DocumentPaperSizes: Letter
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips -T 11in,8.5in -o refcard-letter.ps
+%+ refcard-letter.dvi
+%DVIPSParameters: dpi=600
+%DVIPSSource:  TeX output 2009.12.10:1205
+%%BeginProcSet: tex.pro 0 0
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S
+/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy
+setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask
+restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
+/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{A length product length le{A length product exch 0
+exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
+end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
+grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
+imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
+exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
+fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
+delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
+B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
+p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
+rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+%%BeginProcSet: texps.pro 0 0
+%!
+TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
+index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0
+ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{
+pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get
+div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type
+/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end
+definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
+sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
+mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
+exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
+forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
+end
+
+%%EndProcSet
+%%BeginFont: CMMI10
+%!PS-AdobeFont-1.1: CMMI10 1.100
+%%CreationDate: 1996 Jul 23 07:53:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMMI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 25 /pi put
+readonly def
+/FontBBox{-32 -250 1048 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958
+9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321
+990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E
+6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB
+DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721
+59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823
+D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF
+8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808
+6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9
+1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE
+03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909
+95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1
+74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2
+3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8
+47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19
+AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8
+42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8
+40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837
+B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53
+9560176676ABB71BBD0EE56B4CC492C0652750227CEC6CB2CF13A3AF2C7762AC
+4A63E9A8A45F08316E4C871193F4DFD406CAA01FA8545A9CEB4726D979FE9BBE
+FD50A389F9DF9BEA83F2E73963D6A328A143DECE3F2E4FE2F917BF80A63A2D2F
+815370A53A4D17BE225E9BF4D896AFA151C86D7CAB01F11F02E9A5C3FFAB6402
+328643DF72A68FB4E4A346EE995F94789B2209E56F188F1CDBF8AF92A1695000
+C1A08CC04F5213CFE3943D9087133D2EB280A073DC8E6EFCF446DD92CD5F9E75
+A8D44140D0D46858673E7C1FC07EDB08D41785BB3A374E0941AC69A327F0AE8A
+FF6DCE28B303DDDDC9AB9D01F332ED731416B5E8B9AB03A8E2F4E8768B77AFAB
+19CD5697B5BA7755773DDFD7FAD543CBEB8E4DBD4CA7F5ADD10150521D73B132
+733E24E673CA65BBE49A3F81A5780E69379715F0D2F3A906EA756D3C6515CE2F
+8B2B40A986FF4D949137A2AE2D53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMSY10
+%!PS-AdobeFont-1.1: CMSY10 1.0
+%%CreationDate: 1991 Aug 15 07:20:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSY10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.035 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMSY10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 0 /minus put
+dup 2 /multiply put
+dup 102 /braceleft put
+dup 103 /braceright put
+dup 106 /bar put
+dup 112 /radical put
+readonly def
+/FontBBox{-29 -960 1116 775}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964
+7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4
+A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85
+E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A
+221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A
+27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF
+5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09
+0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730
+DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A
+71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09
+4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C
+515DB70A8D4F6146FE068DC1E5DE8BC57032092296D5371C275E56FB4903A60E
+73A22818DE22EB78EEE0E69EDE2E31BA367FE9AFFF8C7D74AB1E2400953F643B
+7BC604F821A4CCC56FC4E40E0B40B8CB82A045EFB4B9F681EDBD012AC35166EF
+62940137319D3082AF2B42F5E0138804C62FCFF2DDD0AAAB3E2A1249BBBAB593
+00577FAE2BC50E3A7B37BAF90BA56525DC498A971A487617DA028EDAC7F8BDF5
+225C6E2C63564D35ABBDBDFC523302D6D28A3A8E2D8332F6A1FAE2E71D2C6EE0
+64275E875009ABEB233E981A8C36996D0CAA8267981F04BF421C8C4A5162B736
+21DB026EECEDDDC9E1DC92761140410416A7F17A92DE302890C67472E4770E22
+3CFA4B800FA29D765039F9704DD0554F5F5AA479322F46E89A67A5B52709A2E3
+13B14C530AC58684DE01F555FA08D9E3BEC56A6198049AC4463BC0667DA3B092
+9072E0067FF74B36A85A10DEFFBDD3F6C55802E8FB6A84F1C61D42DE55CE8C3A
+5202B098AE5EBE989E3DD38C9D1E8D198E959C946F83EC667B2AD398BAE7C003
+B540D5474D351A90660618D4B185B05DDC3D72CDC22635283ACCD253C56380AC
+27C6EC7C7ECFE5DB1257F62F8B7C6C55A7E40C9C26C48F777C51C442FE0610D5
+65EE0FBC1E9537D51C4D25B22F48B58DF64A09C9FF2150903EC75F1DC0152668
+5CFDC5E9E38E04B453235752D62079FDC7BF0979E6C3327123DA1BCEE9A6CAF6
+1CAC0BCF4B0D02FB3518998CF007016FAA03005251E622D6E67ED2F19D80CE25
+AB274919736E3E2B685DD4C1F6C6B4F624E238AE536978159E184517C14A08D6
+0807D4C4E76E0CBD99A28E8E068D233BFB8204BD820AE1807C757DA13E580CAA
+AD459E754C9AED669CF46B7F11AC6E8B5B8F16AD7AFF0B5D9CDA82B040D8F40B
+78F8241E70A347EE98260BD50AAEB772629D9BEE93A9F3A57EC45756F73C1AAB
+B0F9E00572B6BAE2542BE8022F0D385F23475FDB0CB7ADF37495D3D8B6E01168
+C0B0CD75C2166255E4A2D7741B6DBBCF7760C25C2BE7791204E925D318260FD2
+589DD1EEE2D6CC3CD456D8341DD0B0A7C2729BEFBF0E8B3F218C2FAD9510AEAC
+C23F3AE8B643614195D60C1DC3AE19A477963F7E8F9FC36F9573F1941F33D557
+5698823F742DDA6482FBAEE4A512D59DB4902412A9D257C275B278D950CA9947
+C07C11B50055D309B874ECE21EE5F95FECD47C1216779BA81FB8307A064563F8
+499FF484DA648B91AB11BBE44A8D2E5A960295B90D9CD8672B0F628C3BE4BBD2
+1D1B9DE38289E4B9ABA59BC9741A81900E8A1B6706A0AEE3CC61F24E7056E18F
+B421A06FFA208FBA6F1D764B90C2B14D8294E2922154A8BC7DEF2BB73B3CD6FE
+988A4FE1D635D9F89F040D0753323D78D33735B5BA70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR10
+%!PS-AdobeFont-1.1: CMR10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:52
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 49 /one put
+dup 91 /bracketleft put
+dup 93 /bracketright put
+readonly def
+/FontBBox{-251 -250 1009 969}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4
+87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F
+D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0
+92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C
+295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75
+409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C
+4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF
+2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E
+0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E
+B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008
+24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B
+43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF
+D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575
+5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC
+96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3
+7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC3C8578EF9A20A0E06E
+4F7ADDAF0E7D1E182D115BF1AD931977325AD391E72E2B13CC108E3726C11099
+E2000623188AAAC9F3E233EB253BDD8B0A4759A66A113E066238B0086AC1B634
+5ABFF90E4B5ED3FA69C22541981B2BFC9710AEF6B50A8BB53431C7B4D380D721
+639E005D6B4688EE16BFF48443E7C9E5FB5BC5883E271CB03428955D5B6A6C01
+F9D9F44C93F0C94D9D0728D2A6F5390B793E4205F4BBFADB26785DCF0EAE8467
+0F2CB7F2ECC80860473B0AF607E131ADC315664B74C8FBBB3169708EC9EF9977
+FB3172531CB7AFD5E6CE40A819129D46BA23A46C548A8713BE1A4125FE8E4E94
+FD2FB0777C4853D15397A4FF99571D812F3D1FAF4885974F234F0AF75B36ED35
+812979028DAD6F7EE30A55ECA354CD5179A9FDFE5A010AC0206E05E73CC3BFC7
+04839BCBF01DCA4946CE91A83735797021F57B4ABEF2324D8F4A4AF4BA86318F
+E6DB11B2908C051AB886FE7BC28BEF2ABB9955A321103A2E6C4B8078FFAED99F
+768CA23B44F429BFD9B2CFF6456CFBBA8E04E3BEC7921E691BBE0A98F0F7CF0D
+58E8CB7057C661E85BA2DF8AAA713BC6DA03449AB38339CD4E834C08154FF725
+9895FF5744A96D9A326780EF0F312F0005CFC261EB9080D943EF23E1849A224C
+F92C8F4AD38D66E0EFFE38E76A8FA3D4888FB7FB6FD5FE1797DCD0B4751710A6
+ACF7170C7BD29C1CCD634D290C36FE683AF227CF333D2AE30AEB5E96FD6BB838
+E3BF46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTI7
+%!PS-AdobeFont-1.1: CMTI7 1.0
+%%CreationDate: 1991 Aug 18 21:07:18
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTI7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMTI7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 41 /parenright put
+dup 45 /hyphen put
+dup 46 /period put
+dup 49 /one put
+dup 50 /two put
+dup 78 /N put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-27 -250 1268 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE
+3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B
+532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470
+B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B
+986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE
+D919C2DDD26BDC0D99398B9F4D03D77639DF1232A4D6233A9CAF69B151DFD33F
+C0962CCA6FACCEA6B71BEEF7C056FBD376F2F0D0BD6BE0A0A8259139B28B99C6
+25119B8C60FF7BA002476930DFDC2F6B1B5A80F1C0E544A22E3F0FB2FEAB64B6
+A509B61E1AB96121FBF7F2BC27CDE5B4961048FC2169C8DB745FCC7AF0EED507
+284038B15CE53E69AA22CA76C2A208F6AD8614CD500D479A5E0FD25E7BB14C7F
+C47C503E4CC38975CB0A8F7E109665FB69EBAE6EB68B2D6FA3C967D5BDE7830E
+9CE6F13DFAEBC852DF1D7D0CDD33DD4D5CD6D94DD8AE0D48AB638013CF75A25C
+04FDEA8775EC52A13AF40FA41F7354624D917EE620318C702237AF8C0E1FFA02
+127F862D4DFD0A56774235A881AFBB8F7F4BCB33811C581CFF38462F669B7F97
+1F97AC09373B8F9B7E653013AF8170613E8D7E17235A893BE296A0CD2096B71F
+16778388993EDF1B003EBCE23DD02949CBFAAAB5D9F6A08178BFB8ED1043FC1B
+0B90D9AFC27B19783740E8DDE0E5E01D116A8CB083C721FBB8EBF71018A9570E
+78590CD831116BC0FDA4229F79A581874FC3A1F108A4FCA80CE27FA54A2A7505
+5BDB3D52E2595512837732322FB5BBE459C0205EB38439E34A39544F0A1567C6
+F29FBB7CF931708C8F92786CCBCBB443D54462B3B4B7BD38E90D325EBC31BA05
+FAAB393C7EBDB9EC48E4ACC15A247D2348A62293A726FCA4250B4A407F64270F
+923EB516CB8A3B5D19876C8755EB291357E4E4CC5903D1A536A635E267F7A971
+B1C33AA7F58E1ADA931C450EA8367B18E20E683CCEEC1BC079E837DDAFFF0D16
+23C4AED0DC04DD9458A630FD498794823FFA55705315F0687E7592A5DFC8B8D6
+FE2F3C6550976415640267DD73C0C64FE63F1E81172FB979F7575C459CB0DD02
+1EAD6AE29D5383A7B0B7C197DED6D8E9CE621CBF1EEF641E699C8836D6A8160D
+E50FB6D6A5F356D504A49E7A92D88C540D03D406521D8464C7EAACC0111B6589
+40AF23202778F36F6E4632714401D95E5AE569FDEF2FF90A17998D9DFC5492C9
+A7138A59222043BC4E55E50425A74AEC11DE8597CE8165972895B767528615E4
+B52A855386B377D36CEA5E3F4714B0934C8980470714E85764745EF1C7462686
+AF55B39B82931298A3144154D9515B726CE0FAFC20B87925DF472BBD25F922A6
+6518EF30460ACE2BAFC71A1597F96812946C21DFF1CB430284804497292470EB
+6E0D2F22C2B168DDC63AC78600AFCCBE55AA8890C2357A692FB7DDEC32B57EFC
+7D15F814F2539FB3ECF75B062F3A3CF2B2BDC3D376B887BCA71D80F1564A9F24
+3AE133B7390A4C049241D8EEECDAF8E6873E30F19D1EBE7EB1744D0FD3820490
+F0A94738BA811B04952A2F1CE8D91F0A013A8FBA50DD6723758B0CB8419E4ED9
+A75256DD5A11250795C845F9994D6ABAB0D52FE6302E9EA85F45E7F6A85F14C8
+98D2E2B9973885487B30D60021D9DA65AC0EEC39228ADC8E171F0492BF51DD5A
+ED7BB96B11D644279EB5FF774A0F901BB5858308D2D7B5848430ACB2D67B7B9A
+BD2B984328C2ABBDB9CF087700994038C4B3A96C7511F3B92BD503C264858541
+199554B6A98B7386C5AC7EFE3909C50DE3B85755907E77730F7024DA01F4BDFE
+1E430FE15A78C1E2A3671770DA46CC3FE8DC6D1B99B31D3E7D4AC7581053D679
+C22F515E02D17DEEF99FCFEBDE55B05C81BE418D43B8C8F20F319E2B29C46DF0
+93AF8C5DE9D101326C0828A4AF567B952B181F97606371C079AD03196CDB0733
+5EF0A29DE66CA65261922AE01B0B3BB712352D6D01DABA931080A4FB0B148407
+792A0731B34470FF72A8FB558ED70ECB5F9DD7F1D3285F0BCD007E015BD937E6
+275F61ABA68D1E8443E97783E3F60273C025F65DC5EC46A85C8893776AB3C947
+87F861D5FCAD70ADC281CC64909F0BC268A317E3443AEEEAECB006A9D484B618
+89EF2E40BD426C79A76BC74C584AEA5B44D8290AD9FEF1893EE48A3098FF59FD
+C51079E0B3B116CB6A57B05A887A7CF646B9849EF6FE79F75D086FF36176D2E9
+6CC08A1EB37F046DDB85D2F132F2F1633E4FFCABBCAC644B19783D5943C691A7
+56DBB18967093094275FD051783A57DB27221B595C6371805AD612BE5D46D830
+BA6A0CB6011E60F63B743F845C44F32BF750D7CA28E32BA8C1693E3B647F9312
+36FAB072D5168E87C35E668BCF519F4B1F3606C5A86CE5EF801F24AD72A17579
+1603087DE7254C8E07B6E979205C691E482D9D3EF4AD1216646C696544F6D556
+8CFA87A28B49D51697E94BEFBDB9F680C23D038CBC903386B249CB5AC33DDD20
+502FFCA63C49C0101186CEEEE512B2ED0B7F2AF213FDF8FEBAF2F4365A07EC61
+C251FA30ED70FBF08BC5FB3F4629E41DD9565D44FFCA00FB9780958273A32C6F
+652D2E6CE3E6F7CA3F70E872F5217066FAC0839F49980CF750FE1317E2D856D4
+59FE32AA35D41C6C091BB328319F8C89EB0C1210794F891657BD755382923BD4
+F76A88EEA14D48B0061E5481B0896E872F4C2895C30FFBFD7D9D5467EBF41D6E
+43D14E425430AA50259A1F83E8243566E22AED459FF4A76E882D1B3C9DEF1DAD
+42BE223E53F8C09D49EA840384DB9E16EF66C448386B061E806279219E39CD61
+2808A7DFE105193E6CE9C0E9B1174D7B0ADB2B10F53F9BFF55C377214E7B0234
+EC2FB9796B03164B3DD5CDC16E63D5A9A49FD0A5BBA69CC31499106B674D4E31
+19748F7715F541331B3A723D139EFCD5173E016C7B4030979F15CCCF511FB088
+D86088A8766E455C54DB2DEB3AC33B458DC87146013264295F00F1E69415160B
+FCA55B3BA7FB8F9D98EC485A2C62756973F0D609CC8F91B760B2D8DC64794499
+8CC106E2A12573109BEC55C66053343016D32A90A88301114A3B862A9B79D754
+6E7CF60FD398B22245B81CC57FBFF41AC3F14DB29502549E0FF905D057FB1D01
+EA0191B6D7ADFD2DCE2D1A482F95BBDE8ADC2E383DA77B79628D87007A757F4D
+F64902A85D9E1ED9D5269CC3779BA04569E50281E4F0599693C2A1ECC627CBBC
+7931D3BC7785A330C210C7A9EDD9FCAA1655375F893308914CAAB151E886D8E5
+E6766E69325AD0A19217D50B2772B0301A8D93D89CA4B89DDC3288998278F5BC
+80EB605B215E949A81F0269C8E4E2A0ED8A4302DC7052F057F9542E0455558F8
+9FCA1B350CDBFB804DCCDAEFFCEE794D1114C58B2A2200F5F59466ECD8126DEB
+BE45D6B85D49F79AA4D461A3D3D9B70BBC0EDAD5B3190551B20B1AFCFCD5FF65
+B0EA0D44FA158BE546E0ECAD9916C8C4F017DC916A4F671A9977E778CF7570A3
+6446DCF3285378491E34884913A5518DAB2ED41C6B7614B69F72F472E41F4F6B
+0CE11E0AA76AAF72E28C8FED1E4625578147CB0106B770F1CFD01E12398B2D78
+E24835489B857F26DB3CB02AB1BAD787DCBC595CBFDBD9CADA1DEFF61327ED13
+9E8E9E815CF5490A415BA72FF81D8047E3FEFAF123002EA87EFE93016C5DF2FD
+8153382E38E03815EDB41AAFA788A4BCD399AD81702EF877A03AA61E71CE8B6D
+B8559661C56DF18A27102F9A855C354EE7AEBAE3A7739D33F3ACD93B406F2EF1
+F3DA8E031377C6B609855E081078A1BCA8E406A1E76EDE9FDD4CD8D29CEA4A08
+2B0A5BD7230873D6C58BC551B9DB4B2AC5D3A68988505125A4DD34922773C561
+79640CF8E406A143F2A9CA1AD1A130797619D35B8238E13013AF8010C62B43DB
+09F4C88B65C86A18956F317CC76182DB16C30043BC87C05D19FF5CEFC4A98DCB
+3A541BC97C80ACC39D9F48467DAE59D28028A6B75078D7832B369A333C15D3AB
+7CB3E3F016F841B5AC5A4A9AEBA9A941C822EC67EABB58215E0BFD286EDFB751
+981EB82ED9FD95ECC14ABF0B3BC822C6C7CB4141107611FEA631E9F96292EF73
+079D417C0A0BC9CBBA6B761BD5A76C43CCB63700A098D993C47C4A5C0299027C
+C271AA718EDB4682F605F69B4428068D0DC5DDD7B1FE1CC868F1A9F2AAA49842
+DF20E7572CD96216FEC97273A40DDF7BBD489414CBEE3D23A57F3A77E10043D4
+51C02468564AC3E80FA517A893078766D05998AF7B78F8B0B47BE6C7316F71E5
+D40D85FAE2781E63B6D770B5FA45FF06A1659EE6B65CDB025B4E3CA8623515E3
+0BF1AE5E748ABA5E52A94C8403A8732CBD291FAFCF59CA90CF8D0D21DECA1493
+34CA42AB3F537A442CAA114639E5CC96E5D045F133D020374C6B0A5E10D4D8C6
+224060D1686A9DB77D252D57D66248C7880073E5442D2522FFCCD556557297D7
+B92B8E656A191DC388E985ABCBBA8635B6389B584D62E247AF4C81AC7581FB84
+7F4B443DAFCCD261A3AB85A9A9F42781EADEA6A68863805810216787BE0BA291
+A44705A98930B55E5B5265F7B56089BFD576E714F1C1281F05D4D35E4BDE4470
+BEB39E057E431647DCBB6D7FD26F60FFB68051BF2A0524AC94F3F6190BC531F0
+4C4F2AA339D619988E00ECC1BAE259B7324404803018EAAB32E5206831615748
+2652957CD044512F185B9A14749E4751992C2F9CF183647DA6CD21B0F03D2BE4
+225E1C28298B5D8DE6930C09C239E20741EFB954694A649AC6BC0880186B5463
+FE5AAF0A69E0AE1AAA0F5502CE8F2FEF00B36EDF545236B3506FB37EEA03B3C6
+8B9D56729452E176FDCB12926E31A062AA37CF2C455822351C285ABFE6737F82
+48BEC7E325A2DF054C528F481D9B83FC788A7243ABDA5D9BCC1D8851EE949BD0
+114D5C3E51BCC4E19ADCC188E556480DDC2663AE524A2BDD7744916D62C531D7
+0E90659E0640A43BCCBCDB702D0C5AE585538EA37BB4089EDAB4B44AC3393A6D
+87EEC78AF5EC54CAE31D188293524284D6412DC7DBEF26AC4E129BAF8DA6702F
+A0C216F91AA3874D467542055994A9C24E8E1272D2EF266C211CA70C98E0C7D3
+B537CB87E9BB9C46B78F20CEDE5BFDCAB3902093991DEA96B0D7CC41D0117843
+957FEBF578A8B1A57C3D295CC145B72D54F46A636E80B5163B91BA61C8279F0D
+ED61A1ADCB0AA32EC9A30BCE1717AE2BA2138CE60A53313DFEFBDF95D770C4C0
+1ED286FC3196F35C47569951479DD788BD4AC0A4353DFE984A61069B201B5E8B
+889B8BCBAE39CB2F964B51CD85CA4EE98C78A27034D2DCD951BF17C8877269B1
+660146B9215655FD5EB08823E4528047B2950A87A232BAFDBA4BFC7E6CA25305
+E839B9E7F049F0443DFA6D487D12045F6022F93D98C7C6FF1DA174F96D2CF0C3
+EF23A0E03FA2E95E1C69199E50971E014EAC678F7EE677966D6B76855FF4CF0F
+4FCEB9950077FEAD21ACDB139E0D9773DC84CEEFE07AF3E8EB2A7F5722C4B226
+102B9CD4AB721282C5EAE85940714CAF3DB41EABD703143E9D3D2205A75CB709
+F316D7AE5CB88AA8F57B08CB5AD27849D2E937515473EFAB72A54EAF7F066E47
+C63B1F6246A4B4EF0FB8B08CBDC821DAB987E4B82B1097D318096A3087B9C1A0
+AC68F596C661F3CB6DC6C9A56E8DC2028288B04A31BD248F5DFE952848FCB0A4
+B1CDCB5A2D2E2867B297716C326102A0578E899E3B5E7D78D1F4D4DC4592702E
+509F6CE853B9FBC3FAB683DBAC4AE02BFB30F4B976CA4A2E002CB19216303B9B
+3181DE9877AA761D2BB3B0B9AC907B0564F44409250EB4A6ECA7922C8E8DB001
+CFF8ACFAA49AE65324226B8B8FC3772F657D8F6F3CA6E898B344C8BCEAA7B1BF
+1128FBE2BD58BA62BC4144DA0D9DCD707FF865F218C5C559A1C254BF0750BDA8
+AFD330603322BAF3A30A1F0B019A7585FC1E12E56CD097558845A130F4B7ABB3
+A5C496CB064AEA05A4EC0126A67FB5093683ADA2C25BE9874350E677514D9511
+37873AF6F81AA3011587AD4E5419C2C0E265BC5A36AA7FA51B3DAB525CA8A1D9
+7AC624E46ED25C3371C927D75893DD8FC9B5522D80A7258EBB05745845FBCF7B
+6E8077C118AD5E84C174F292775D088116791F02B3979320F296602FDD22CA47
+E6BB58E45FB085FCF290639B2F763CE15481D9720D758E5685892D3FB78D9B12
+9CEE9BD41D9437C3B85C8461722DEBBCCB8BF2417DBAE644CA7F9C6519A5E39A
+5A422E3DC005A0AB7D275B470733E1318BE936AF1FEAACD729CF5AD3892428EC
+5268A2439BB2B89EE11FBD436C47AE0614EF986F0EAD848545A377D56594E00A
+D6228BF5B440DA5F28A0B3F805295DB4A9ED928BAB290576C5610FEBD485DB85
+DC3B5091BEF7B1A70282F8BFFABE273FC53003026EA5D1E9CE955F657BFF5462
+A0F36BC0AEC7F0DD42AF9A233078F660D498B668319E3CC65F24271B87E0FB26
+01014FDCAB87D5F65D72AF5B00AFE4D8BA8B5D8D4A1FBFE34E430F54F0B5D214
+0C86404400C5CF33CECE5FEC03BECE952955078C740E639843E724802170212A
+2C65B65B18B04D7008034609E8C4F9119DE06DF13B1CA55DE4CB964229954680
+D36FCF1D0F47B15ACE44758B8710C69AC9F9A54486F8A18C4E3CE153D0265BBD
+0CD887BAE6F6375FF20A6B72BB7A84FC5E2B34F94706297E1019D84821BC4A8D
+5BCE43AFB29E1F551D962BF37F73BA8791C3C0DF37537E3BBB84FCBD1480C33B
+5BF6AFC860EE6203B7589F38AC5738EDEA5F6D1AF261DC8E973AFBBF837030BA
+441C94D1BBBAAA7FAB6A9030ACA19B91CA53268A1FE80ED25C309D71B89313FB
+27D49A0BFEB9C5DEDBB6F99C730C0540C8939220B54BA63C7FCC8F7CC709B3BF
+6098E1776A4EBA3717CC26404B669DFF41053711D8F2EC5D98954DFCA45C497B
+36A3470524E96417ACFEB62C9CECB62AFCD5F44D206C7680D12D32FCC4563D9F
+F492C4436CF049F989353770533050853ACE9EED7C856127F01144A970189E93
+A92E88619A426CC551AD57FD54BF0DB2DF9059C2C669DB4FE640B828361F2CC8
+4B4BAD8936FBE06CB979816A2881E6B9CF458A3C8504A5700BFDB8B7175E1B89
+8DB4DEA351077857E9D8A06D077F7760A9161D4102E3FB16AC6111C5C0558022
+E4E89561337E5B15723F6C97057435E8D354A113D163189A93D028424A99FD39
+41BC461D5EF7F75E2897461CFCA1D77B6051F5BA4E703E67C5B904C7C8D31040
+D8A732F9B0A2F3DD2EE6D7B167BCE925A5632CB635DAD838C12BA8D44B9C1BA2
+C29F80825CADC5E8A15D7A8E64DECFA4A18DCC9BC96ABFC39963158C14FD3EC8
+4ED979310E798AF6CDFD8504D804CB0DF43F95F7271F7B366ED0B8CCB4F0505C
+73FA14CF73C391A0466CE81F2485B993108D32EA73A4D26E2FD995A135E67FAF
+CC3EDE5A70E90F9FB1667631FC4B351786D96A3CE329D0781A66A727B3F2A33C
+0B663B8756A1C739D07B39AC858519B23A3D81500A6EF130AE6A45A81C843123
+2414D06830A2F5AD5936A8E5FBBE12CCB59563672FC69E2BC5EA5A06EABC3985
+359F2683ADC07EE164B819CB6DA2FAD378C9F60CD49D6D21A00F2C2471A18502
+20B8BA7E9CD9500F592028F90095BA0D213FA19FA70C0909958CCF1DE4287878
+CB93C4101DAB123E8F3F7152BC82E43C1629326655422936B32EB4632D7DFD0A
+E0D9D296BBE4ED231BBD7DEFF79E0AAF8B2F867EECF4B9CD3BDF6AE3F4D3DC95
+BD85F66B9DBBC8934B4756CA11C11C08BD0FF8BBF90C5B70294D011A9E75C15F
+6FD09150AFEE1588A557CE31F1758D941C420C300CF326E83E1FA0587A4AB80E
+85F195DE49830B25617B90A93F1256C40CEB3852851D86D803EEC19C665F17E6
+D56040936810740574961A4FB48BAC5B03545262253284AA23BD82DB7EAE8F41
+33B6DC8796C6019518DC7E27A72EAECA6CFB74450F7A4A575F00A50B256971AA
+91DFAAC0A12CB9550E390A93CAE821020D68513EB89E151F77E384DFA28E60D4
+1CF8203F213AA89BC1128C8D3D235294BA2D7B66D552364FE03156C0AA648571
+4100624BFA090FA81BBB524D98C6173BF900E8E74BB58FADB072B4A60B292A68
+28F686DDE1CC02468D87C22E6C4EF00EABDF545A9369A338394581FDCEFC5708
+3FE330D130D8F224A4293C0229388044328913F4C141C83CE0E339095A1404CC
+4DAE96487EFE02B69D8B46FA2FFCA2281BF95F494797E989619A2F54B5E53B36
+C829DC61E3A565ACF6F3647BC21716758075378EC994B9780AD361E7A3BFC483
+15D381DF90052625D61248B724D41B32714B413E6C6237682E565B45F622CBB6
+08506AED024011268DF8D9349773F5C66A70BDB4AF2FE99711710CB316053FF8
+67F2AD9C36B72411712B2C63D185827981503593B1029770911A78B78D401E7A
+0D0986D84213FD610F7DEBB5981A570F898852128AB3B9C3C572C14BE236AB05
+D8ED683F455D79C8B95C43A06A4F7CEDEDC689DF89D6B2D803A4FF3F5C9430DD
+37123FB3B0228A35C28DE23BDC12F79EF31C37E9EC3A288D7C2CC94B699519EE
+7D25B8749C8C934E6A04F8720A2BA290864D4D8E822A85A510D1ABD61A604C43
+A6E4E8A57A473B60BB6E173969AB1E06EAC9F7D349551FD24A4BAE5F87C6828B
+D2A5048D9D91B1DD552E88C6B3FE1FBE774AD19A03F4F51782BBAE33D8CA1D99
+99DBCDB5DFB6C219EA8D246861DDEA5F47EDA4E115130DBD9E5B02BF734F28A8
+5AEE854B99016061E632EBF500E225780B8CD7848B1AADFBC05DE4D8F67B1B4B
+24C700214AE3F1827455D7C848FAEE5DE3311873E40005776AA50E14952814E3
+575E51D3534A5E1F54B4D3C3A64134BA6ACE4F26F46B0C9073D5C53A073DD617
+7D76E4CFC648496F229C731CB5FCAFBBC5B81D0E3CC0CEF7CB0866607FBAADE9
+18A358D2F3E827BE637550E92767E874227109D380557D8DC5458785958AEB6C
+34E904B1488297A4F33E2B6E07F091A2CF8FD62BB36957103DE3C72EE0EB27EE
+0B1224C4570D35C3AF14E504B48C1E4BF3B321C3EE623288C82CBE96ABA181B7
+F7C8B9D69B1B1B97AF3B086C82E42343320F7065C210929C05C741F05CCBEC96
+D14B3498139C7BBA9481C05E1CA5E46AB06C2CD418EDCCAE3278E515E905CAD9
+B09D88AC4587943C510ADCC857F59A5E66C80E4D621006FD4735FC54E8B73660
+40CCE67FC6F6CC4FDD9931A26A339755567AA2D6FBD4316A8F16F2EFF51D4C8F
+B3F619E6C7814AFA109261F0B2BAAFF92D0BC25980FAA7F7C5CB566520725DB3
+957B73267A9C4E0610E5327E47C39C74AA285BEAB2E8230806184C60E5509BA6
+1A185BD6D8DA6DEE48C87E0B782A11071D08A1701DE89F69BC70ED9EF335FBAC
+72F8DABA2A378BB458B73603EC8C3B491EB551BF2ADB613E43A0E6DBBE806FBF
+2EABF00B8BE6400F5F117CA4F0EEB6B09F03F36245EDEED0AA78FEECD4D23362
+869398D52329AD0239EE539835BDEAE15B64FCF3BA2471B16AB99C74DED0901A
+A37AC51DEBDD9AC63609C5083BED26DB9C4EFA601DE7B67FD7AA74A72D854F17
+1F2C5AC5936DFA9D56F6A131C47CBEFAD0383463358E66207112F4D9FE1E0D2F
+C4C8BD1212C9DBF9A980E6E9CBB1A8271F73DD47C58C7978C134FF6BB57B6E77
+9B6F14F2D0B74587FE1E6A4607F19CF469C0D6417A406981DFD88076F79D4BDA
+2767ADCDD8151CAB176D9905672B255951395A3F64AC1B521DF2A4F70609ADA3
+E1484B04243BE4F05E5A53252D3B0548600F31EDA74B7D1820F6DEE9F8D1B234
+4529583AD95FBC74C8A019D64EF50C7F170D5075AD5D0BE8C41571C5C272D870
+CB936F418ECB04F48590D56CFAAD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR7
+%!PS-AdobeFont-1.1: CMR7 1.0
+%%CreationDate: 1991 Aug 20 16:39:21
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR7) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR7 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 11 /ff put
+dup 12 /fi put
+dup 13 /fl put
+dup 14 /ffi put
+dup 34 /quotedblright put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 57 /nine put
+dup 58 /colon put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 87 /W put
+dup 92 /quotedblleft put
+dup 96 /quoteleft put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+readonly def
+/FontBBox{-27 -250 1122 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF5B8CABB9FFC6CC3F1E9AE32F234EB60FE7D
+E34995B1ACFF52428EA20C8ED4FD73E3935CEBD40E0EAD70C0887A451E1B1AC8
+47AEDE4191CCDB8B61345FD070FD30C4F375D8418DDD454729A251B3F61DAE7C
+8882384282FDD6102AE8EEFEDE6447576AFA181F27A48216A9CAD730561469E4
+78B286F22328F2AE84EF183DE4119C402771A249AAC1FA5435690A28D1B47486
+1060C8000D3FE1BF45133CF847A24B4F8464A63CEA01EC84AA22FD005E74847E
+01426B6890951A7DD1F50A5F3285E1F958F11FC7F00EE26FEE7C63998EA1328B
+C9841C57C80946D2C2FC81346249A664ECFB08A2CE075036CEA7359FCA1E90C0
+F686C3BB27EEFA45D548F7BD074CE60E626A4F83C69FE93A5324133A78362F30
+8E8DCC80DD0C49E137CDC9AC08BAE39282E26A7A4D8C159B95F227BDA2A281AF
+A9DAEBF31F504380B20812A211CF9FEB112EC29A3FB3BD3E81809FC6293487A7
+455EB3B879D2B4BD46942BB1243896264722CB59146C3F65BD59B96A74B12BB2
+9A1354AF174932210C6E19FE584B1B14C00E746089CBB17E68845D7B3EA05105
+EEE461E3697FCF835CBE6D46C75523478E766832751CF6D96EC338BDAD57D53B
+52F5340FAC9FE0456AD13101824234B262AC0CABA43B62EBDA39795BAE6CFE97
+563A50AAE1F195888739F2676086A9811E5C9A4A7E0BF34E6F4C9A04BEEA891E
+4D22B39729EE4F0ECBF3CF3C429B3BB657DF66811D3A108A73513A22D252AEBA
+66664B33422FED0E63D93F9F8E24320719C09F50626EABAAE93F5649E1981AEC
+E8F19F6105EA978C51CBF54E94F3DBC93516313F00B281D1B8C8E4C1DB33363E
+B81B61D7224245842A6B98939F0ACF3ED081BFE7A813215D36CD6ABC3EBD6B99
+A5FAC5AA7A0DB126B0A1FB14B58525546D4D8BB6E95F803D6E48BADA30DAED03
+942D55691A3E5FC195F3AD4297A1A5E9C2F61F9F123AFC6CCA78BC17BF2F0F21
+9F07458D74BB65C10DA76B2D8A7595FE457E74DCF33EF5960E547CB301D7448F
+481932BDD0B999648074C1D48E8CFE4C863E4926B3B9C5F48512E59F3CE5F6E0
+2BE5EEB299259FDC25851EEC203FE0C8146DA5DE9D9D0A69E629994A008C50B0
+794B86C6B29CF688BD915BACA1C895EC3D10C25D1652405D5AE963C68F5BF164
+14CAF662FA3B468A3C7F80DACE40DAC79EA6CF24666B8096FAFE5C6FEFF97159
+4235543AA8D28481D10FFD41D36E4E69662380B606DA8584B808E8684B0DD1E0
+17D96E3EC23C2918A4320D14256945714F40886807D0E95E62D274E0A9338A70
+C44B1B3E4E4672C8753146873301E4C13BF3FECF350202B9831D556C9E47B873
+029EB02FBA04C39F87CF7845E5BCD095646A17D799FF1E9F057C54F6FF2F58A2
+3E708F8629F3E4B656C4C89F697C39DCCE00DC7A7F0DCDCD2846E1F1F1C11BE9
+12E73D274A8C2AB5C3D192F6A4301D4D8DABC4BF4BB2DF9EDD7DBEEF30C32F79
+EB865039C47B903CA6EF162FC7F6B665C4BBBB07405FFA2E9B7E658971BB98B5
+1038378D0CEE25EA4A05C351F9D26D8C51E7F95CF547E7A1EEFF7AB3BC7F9999
+A8DA8393FB2F713F292B9ECC594C06C2B7788A9FB8FDD30437264371EBB89508
+4BABE312946B6F0E71538E8DB3A356DEA9198B47BBB65065ECA7F0D9A33DDD5D
+AE0F360DF4B23B9BAE61528492077ED46764056D0352DA06DC92489CBEDA6979
+67B07D598123218CDB5180E93894C60717BBC0A2D59B6DA88A18B475755E8601
+FF2C76450883E8B87AFCB6129CE78FDDF1B0051901376FBBE836853D65DF35E5
+51D83CCD4F06E5FD94832BFBBFE809E2F3EEB26EAFF1F4B343E28E299C4BE030
+209704F1EE5182036468365545C202F2E8065701E57AD7A15572F2FE12AE81C3
+6AB77AF07B162F1BF8FAF8AFC3F8AC9DCE6FE95E792AEDFCDB13C49B9A545E1F
+D62057389422AB6C77F00E96DE72799FD34E58AD8643D45017A61C42A932A7A2
+46D34BB68D821E1F4DBFE9DAB50771CAA864D2A8C2FA3C173E2BE11F2C9D9E73
+04E47B430318F1AE8A7E495112A9654046EC10A913BB60FF45F6FA636A640F62
+3EAC2279C21A93EF15B2B36440A50FAF73580CAED243D6013F0C852821B33542
+53432C41CBA08BFBD219A72D68FBA5D41E5A0C779E071D6C5954A62C712D6757
+2AE3F815173D0B9D6D9F5EA17DCDA24F98A93F4DF9367C2A13555B27034AD29D
+92E58C118DD27564B37DDA5E1BBE609B09DD3008DB15E46A161C5867AA473A26
+C52DAC92D51E34E2A797844825E6F6C24BABFB9B80C4282D0AD2746397E8DE0A
+1E030B636BD1B00AFC3BF9DD59DC7D0D96DF3A9BE133CD7B8CF640D1381BAC97
+DFBE3B2C5CEFB66E4BC51D85B316B7BD2CC6CE96CF4C128E181BBBB849903003
+57AD671BA64DC53F46F4085BA3980750EA149C31BA92B27DA0839A667F1F5C7A
+9BCA01692411CDA70C5DB370B9D6767B36F8A52A2078F7549AC24AF28CA40A93
+304C5D2A71CEDB760F6089FDF09B3315ECDDC73F0F143A2D2C4DA2460D709D82
+18AACB213135A3648EF604BB5CA3BD0EC18FD7A0A5180376E3E2BBBD83863469
+3CD7348B18A29750D93E5BDF2EE6A94FD2BDED974CD326BB67042FB361C0D2AB
+77E57516AB701BA70EE678F265B3933C9BB41D979212B31CC3DC8F12FB6FE09E
+8B35D60F2DDD3CA0CB837FA0A90C2ADFDB140ACCE3026EC68EA90BD30B9C0290
+5AD6A59CB0FD2C8C8DBE9770414560CE966FFB413D47970C3464F2DEB1CDF16D
+F90790447C22C7A1DAE78C14C780296D4CD3F8E3C0787678A88AA23E525C2738
+A6FA50F12CBDDB02C3F49A62D73A552E21D069EAB44DED93B41DE6BEE9E840B0
+32F4C9BB72EDF1283A88152DE0654F9C05FF424064A311BEB9F13692CD5042F6
+87612F5138AA158D73BFDC6EA23B14EF748BF3A039E263C34F0CF6682A191735
+83AF4EF1BF7B441EDA836498F6728E25523C42E2BC3F309D148EF61D6FA47660
+CD26C61F71087B189DF39F5A72DC386E505FA0CBF07F2E9B4E149311FFF7B80D
+10A7223D4160214A41580EEE261D671CAD6011415C87716FB3AACBDB771888C7
+E278A86B515939DE1F1831D00C7048B627123DD552F654C493A69C211B642E18
+1FB9BAA905ECEE762DBFD7994B8FFA412B07D1F8028CEEC7ECBE836F39732D64
+FBF90E46AAB1CE56C916F86A823DED0730FBE6FB122447BFC60E0534EA8C99B9
+60CB50A4FF0F6BF2D94AD6BF517EAFA586269A90B94A4A178AD4994BB4B8E52B
+4CF8B68B26B5CD10493C814AF0656F9B181101099756BA7B7C8B9DFA2AF609F8
+EA960710CD16B3F9CF3E5FDC452EC08237E794B82C1C85F1B6B12A709771DD9D
+A77C4BBC94D31ECF4760666BBD6000CC8C49CF1D1ED3F3DE3505BAA0F77E70E4
+C6CF7A2DBA73C254BA90B2EE7AF45BFC65E8520309762FF07B87C0C81E0C4F25
+30FEDA98C85EF785B7574EB961C590B1CF9B40E36B87B836201EFED54256AEED
+0C4B10E2247A42FDC870638FEBF20314935E65AD73AC798501C3AAA891F9EAD9
+6783D0BE48C6CB3EE89F3538E15162490FA9C4BDE0EDDD1D2EC63B8EFB093840
+3027C5C8964B10636C2773B859EB8B2D28ED589BD57F3AD6D9AE3A0ADADA0311
+776440781D9F5739F123301646C5156DFEEF8786930C7ED88816DCB9B67B828F
+730536F7DA34EFB2F2AF77481ED68542B0DDD96894A6AF33E282FF09B61C85FF
+5206B358F695D572FF48D005DF54D65A602FD6BE7B6F15BB9AB59003717CCE44
+D4DF50D0BB66CD926E6DAED26B90F562B287B7CF46DD44CAD7BE29E6D84907FC
+5DC8769F4C17611CE0177712AF12086A849440EC71E81778BF572B19352F6955
+A7C3FF5813E88E09FDA5742D2687FF5A52CE741B6A674739A5D30A77118648D2
+BC4766E87B8D166671C5518845FDFBCA2E738CF078CAFF8240829EAE172444B2
+BEAC2C899694029BCDE8F0E7BCE6A049481B41226336D0EDB19A68B597F379B0
+7D1BC9CE42DC548A768F0C4DA0D0C3A8C4630CA9195328B33936AB78691818A4
+4A92380A0EAF5974CB52A1284806A1D13877BB347367BD3BC68AA511CA86E6DB
+84DD4157BE5CF68D7D0FE1F9ADC8F8988EEFA57E74344CD458EE45DD6DD13B47
+FE8E8F2F34CB5E734675B49DF36B6C14CCFD67CDDEFF80AA921DBF1E09638F06
+DBE8194F5125DE73C9F8EDD9E2CE7DBBDC1B572E42F542C114A3500782E8ED33
+3020E314DC7A8BC5AC60FADE9E4BD6A9C1978A4CE41BFBA81271726009FADCD7
+CA4C17F9FBA7D0F64F781E5B7DEF535196371A9A37C9D2D6B22B4C3627199DCD
+E2B979674FBA6230FE8081FE848B5E53F6CA26B494BA8E2374EB31180E5F77A5
+9DEE3C52F0F2D2AEA3BB7190BFAAFDAD38F10CBFCA8843D3FBC05B55E81A0EDA
+886A9D294BB5A6E76DE646CB3BABA1EDF63ED953BD6BC1BD79B2D83FD9D7125A
+095EBCD713E88EB3FCCA6941F05AB1C0C92A488C6A41F4598F57BFB6BBCCFA60
+44602ED83AF694CA988298BD482B3FE8230BE5AF6DFC45D8B242B500A0CDCA16
+82E028FF52F8B004D2A5B799C70C3E6A8784521600A855B909961DA8FA1DC7B9
+89064996C0C2C2FE12B69B43ABB534FFB57BDCFF511B28F1398EA1B357D92A26
+F0B76BFC0E802D4E33E80A2E7741E0B80488842F4905FD04C9894F896DC7BB0C
+D10AC6A99FF3AE582D354362A4CBBBA261F807218B4418EA8C632E8A4276A0C6
+A04E2D35D91A1C31C7435C5DF08AB130C75F1DC0042D5FA182A54310163F4B9F
+719A47196400D39F7BAC83DB34B0128869EBC17B0FE0B881C94C42187692341B
+340A6BEF7186DCA1BB1F085D6E4FE2CF2043E05F105B49CECFBD8278C2E418DE
+FCDD23A1F50D47A1150288FAF90B88C5FC28CEE8CDF9F65F4D3AB698F033ED0F
+66F83E114450384F5EEE60077981DFFA7C9D03FA719A1AB2C4FB2A1947478B5D
+0F5D7A3C110C80C97E9C0A37937E3F848AFF0EEEF00D7625A8DAC0EF0B70CAB8
+E596EA5F5CB3CFB5648A8E990CAEFDA7AF7D029AAB65298B575A94DE25975C84
+712AED72A1125645DF943B5EA4249C0E3FB551B3892BBC55AFB5C4C7B641B846
+3D850409408C5C3FBE32EEB7F97F93A47D481188C10533B0EF697C89A3295C74
+82D40F460A6FD165310EDC482900ECCDED9140EB07F6B6C2A3EEC6E7927625B2
+E47DD2365D5B238C28321554C2A19B1EF33F3C779ED59CA4CE97FF370B2E77F6
+1A956A6C49F610EB88ABD3D13833ED6A65B867ECA5BBD34202258978219B8A09
+55EA0C4862FF8DF1A4AE8C7DD13A8FAEC2F9B3721B1770B8F020A0D8B539F436
+20883821C321C9E1CC83428D3643D77CAC04DFC56D4A729C22E2B896C9F2AED8
+2864937E141EF28450C82CA73AE40631071C68B5850B90393E68C8F7A2FEC352
+74F6B3E5219DC79C8CA9A5C3035C215139B9A2EBFE72F99193611498C814F21C
+ADDCF87497A016C760925550732CC1E7D61190AFE35B92A44992166B4B2300E5
+971E097E58F9E110016C712AC2BB4C8781B1811F6A1F4E322F9D739834E80633
+6AA69AF19875F790F43752CB7C10D250E651A4F5B6FAA72218B103031B6EDA33
+74F6BB36E32AB5EE0CBACA7F896C646D4CF5AEEE149672865E132C0052290910
+149CEA8473DC1BEF71D1B5D04EBC3583027D2A19E0182AE942FDEEAC29BD6DF5
+0972AECF408EC62810651175232EA3E9DBAD731752137E2CFF8AF05D28EE824C
+5E7E6C18CA698D05759FB5282EF9494AF8D213813FCD36D65A395FCA352A0B12
+E45F86DD09F2296338BAF56D7057B331A61E79B2D16DB60FB8F8E8391F375BB5
+5B9CC5060346BEFC02EE9E34A4AFF948FC49AA42B1187D567AEE5B3593136585
+585602F85BBD2219641BF514E86A7E175D543E8B120BCF821883D97AAD39A368
+0EF627DFB67C301C8F3ADB2AF71B3DF8E0503BA85048FBEEBF48C846B7B02489
+055ABA2E3244441CEF3D40B01DD06CE2471EDC081D628CE4856D7B39ECE70604
+B8936E8998CB4EC3F09250DD35B405A84D13F7C852E6BA8160DABC4BF94CB527
+D6254A4A204B0CF35961D19634BBED724A7434AE3AF4960EB4F3AF0174A91EF1
+E383AD336E1CE585B2E42C76F9829EEC08E7D095658B23AB576756B6FF5D70FD
+4B611A735E64EB2B428E46921966FE804901540E5D21680881FA316266239068
+91C23DA5DEC146B63E5B660BCBEA353E7BA49A15F661F2CB7AC95A11823B565B
+474242BA9C41297E2C85B7A0DFFB501C50271826F2979814314B104E1E9B79FA
+6FBD38EA9208EE8873D554C9E80B8B2E25418A3A84849AB29453E28F659A0523
+F1EBA1488B58E3871C73DF7713ABA56462E307F97A9B2EF58854FD3CA3AB03DE
+0E9BD2718E22139549A43EDE8817FC2942A50B0B1973633C3A24ACC4B5E0E7B0
+7F64B21C7A326E9C11BDAC4AC703866A6B77CE1CEAE582F0DED24D635C9FE5E9
+089525CEA85B8BA38A452DE1B15FDD98531EBFD98231F98E6D0E173CED9A9CA2
+99D901E777C113DC94E90DA8DAAC366DE5106FCF915A5403E97A450CBEE2A7AE
+51FC93EAB8F19EB8EC0C774CA15B71B42A705882FC62B72F596A5C97BEEC8793
+23386E86282F773EEE00364704C45DA46A87F8FE4B8151E157B619E06DD0FBAA
+6001E1D2AE9AC01248C087910CD46EA1D245A508B3ACB5F0DEEEC5759F4C0A4C
+1006C84E5F95BA59C81D24E3EDEC5C9C7665C49A90251395457032B41DFAA938
+5A4C1907B43DE42AF31A4F5A3C884A4DCCFCAEFE089360ACA22C787B05A94B82
+A9C2AD44DCA07C2117B21A3AEDB03C31895918D2459B7C3E05B992C27991CD80
+8CB969CE96975477E75DD73B19A135B7F115872C0599E812ACBAAE059C2F64D7
+0B065521FDAC5C5EA97C7C08ABF56426A89945A7DBAC2A278AC861245D7A653F
+B7054FC04443648CA3B5C84DCBF8CD7C5AA4D49EBD51B98D6A249126C168F956
+1A91B140C1A8FCBFFABA976416860D12606396D06A232C3E907D9BF386F21AA9
+E3879385E70C00BA28F999CAB8BFDD8881C142E72782ED09D0DBB0A4D90A239F
+557D8595A2E1C7B171C76EFBFF920E8B45376B50F8686C16F07A1D5C2002BB20
+A8FA69DF7DAD452248D65141B24DE217BCA29A8313E286DB8E7580C46518CF96
+2901F7177C8DB36597967B8D657723DE950DA91C16A8003E42E68BC0455DFCBF
+B591C1F3DA56AE7E667CA7D230BDF5BC526B26E36C0404467282027828BB016D
+8ADB60FD0DF78D689D330319C06EB9D525BC4B4DBEDE358EE2BD7C9041BD4030
+38026697495E8BF0775CA00DFC92922796C240E6CF43037C1D0AA4868E2A28B0
+638814DC05A6D9A65898EDAF9BE5623B2406EE4FF458841BB84BB2C55994D0B0
+7888F3978FA762FD36D63AAF2E4925B4A6241AC1735E92C9E9B60744A9D02B58
+6F2DE72C8F8C4C8D60578C28091031577D15BA1C4EE02C0D3170CA490409372C
+F2998B72F17AF3698CBF8DC494EAECDC0A7692C105A05A9C28340DF7B127F8CD
+F6DD70F190BE5DB39D4BDBAA3E8B66C6C296A58C89DE064DDF56D29F134CB5C8
+A37F78A21B5A8D5DC69C7010977FDBAB4AC413E419D3961A679F4500554369CB
+F19FA601839B5E2FA6D6FA1443782B5575C3666B0EF3C0A60419624A52AD88E2
+A5A120E26A1F0B055E0F36413F9D929EE527A35F59DB0D50C5139EC9C51098B8
+11176067A95D883488B6CBFF22A273D7C32DD8DA236138D035A35EE0A053E0FF
+238C1FD4D11A31DE7BD4D7FB427467389F81F9F338413B06DDE780345D5DD974
+A131C82C1FAA7FAB1D9865676B87CCA505E7066E11FA5B45F6D3EFED871C2756
+02DCED72FD1909F278CF5AC0E18B224E2217FE5B2B7EB107BBBCEBE5F4823A37
+7507C861A296D66905F10D227C6D6EA7F46CF937EA0F42CBE444F11D2159EF83
+775EFDC3F6F400F03FD527CBF434E5B305E17FE2ED69A3EE289D7FD525F1F5F7
+C40F076FF61C0F3A17880216D4ECF038EE7FF589945AD0585F4D96B72558E7CE
+F71106D7DF2170A5791210389E8F2D546CD485A11C4AE4EC5D416C11D9F2CF92
+CA6469D18021C913E875CBD47CB8EEA9BCB44301DE88ECBFAA2632A6B3BF9C26
+CA8D041DD4D0E7D8FFE90C585F870606D892A90F7C63517CB31E69BA29C0400A
+EF8C14BD860BA8F3031F1019A9E97CADC9C9FDB9564534EED221B4C3F4FDBB0D
+0EA49935312D351F23E51FF611D3E4ACE91D0245C647E989050FF51FAA22E7E3
+599F7DAC8DACD13CF2CBCFAACF28FC2F9AE999B2C96A6195D8392E86741B95AA
+A28260C4556EA9680E439BD401D2FD507E636DA8F82662FE8A3FA3DCBE07A910
+744FDECECA4D37C1D409B45C00A8083DFA1878BE01F6B601B6DCC90D19F67B2C
+DC6306FEF183FC6BE537A5C4D19EF7532071915EE17CE30DE92D758C10651F24
+761B60C49E7B7EABCA79749FEC338077D28046CDFAA1C616DCC325E060F9469D
+F8EB4F9270FD298C6AA215942C6D279CF20687E1A37AC2F73C317827E54EC341
+187C97C1943C90257C44D286BBA966C65F17E27D767C123495BE54FD11A9943D
+812D27949EBA7DEAD3A447F53370ADCE724D74D008B0920BF3423F297F08D9B9
+760922869A2F22EF3B54E1F26C74CA1DF0F243BFC910AE37296F7B9A3BABA356
+8A197757F66897ACE8A0297513C20BFA4DF019D6412428558698F2E3BE88F5B3
+5D79127EBC1F40F9FB7FF78674364FCA7547E46F7AC070A6BE1C78BB6290D95C
+879AC41E20647F5C013B2D11EA5323ED8C44716B5C4BF01DD8FDE585E232B2E4
+EA21BA47EC71332860245ADE3931D5244637C026086A109095B5BDF099D0BDE9
+3F182013F1A66212D81449F0B26B4DACF5CA99ED98F18B4DA94C111E92360DE8
+33AEF6C7F0DBBD538C81EF1F4F22BF1A80C21D47085D2C282B098872111FF472
+9C136570BCD0F23DC3710690C92EF231A4BC410B1062AB840503F2F77277F7E5
+C790E50E5A9521BF003E9482EB8DC192CAC2B6B543B9F3957017609D436876F3
+E650EC123DF7D2EC89DF03837D2B35F246F05699A06239008DB2FA2E1615E57E
+1A6BC3A15B8EB98798569C5E46FF639C7373689AF8300CA200AD1E6A3470D18E
+ECF2DB83618AD6D0DDC1774968C18D683A49332586184B11882B4E3D01A95AC0
+3C02EF32FB509238CE6784832A9FED420B03AF43459AD786037CB0A746922D4E
+0DB36E3DB0FF48B845ABB6BDCA61CD3CC696A89ADF2E22D33D01CABA7192AC44
+60510EDEBE116812C010786E0A23D2C2C455A7FE5AA964EAD8DB914914376B4A
+DABDB6E15D932872715627E226B5D3C813651BE179CAFD44184DD3EDB5219FB3
+E41313116CF4E7D1EB379CFCC539C38015288E74C9C5DF65ED94AE2036A5EA81
+2639DDDFDC856D13C557E7A1815ACD18967023659730D1D23A1E214966412F60
+5EC395161C946D2AF9BE0F433A6AA554DA092907FD976A763D230AAEA81357C4
+DEE626BF35789C10B5B41F2A91D8581CBBDBF1AD46DB98ACB3EA7DF942C005EF
+B1E64F1728D53B3A5892DAC032A3D9B397E6CBF9ED1AA2DC43CA38D6B990AC3F
+656CA2D3661D74C76D4C3501AAB24F515C5440F01F97CFCDC8EF865586DF91A0
+EC7CDB099042978264C0729315EFBE1CDC81B0100AAA0D12D1644AF2868111E2
+F02E0E0A963DE672F148B19A2D51F468C01AFF2E3264F3B7CCCEEE3908367806
+484CB066FC7B3A9E00AEC83101BCFF093BD4C3DA6B57B4448F0D358037C3B8DE
+CB1AB4DC60F95AE5345FDEA5052E867F86DA66958A2AAB9C140F0C05713B1920
+E120A4EF101121BD0FF6EC4B212A0C984B6ED432078EF9473BE73914ECA78D77
+B84B838AFE5288C35BD52BA556F361CCB88A8BD6255C5E8323614B2E84A4B27F
+6CD9B7EDFD4AFDBF33E89754CCF00B0D5EF7702509EA60F7B551928D2D14CCE9
+EBC0E79F9D346248AA527DF22C3C4A82597EAC827BC55F93403402D8FBEA7639
+40BDF8DBCFF38C02868E96AE562F0192BA99EE56AFA4D0B64B5D897E0A9A4085
+56D664541B218BF6801889EF0F7AE7381CA8BE66CCF40911036EC0C2FD060B34
+F67F3A6DE12FA736231200966E47F69976F84046D673DC546947D18AE5176522
+EC237FEBA8BF1352382BBA72FC822E9B81DB9EF771EE6AEE109B87B1F6A54274
+1D9A8095CDDD1A0576EA77FD4B5C859282F75B0E8BABC151CB363D730A0C63C9
+3A2FA8557EE12815FB8F5A53D0F36EE5483FCA49F9D643AC8B26B0B68EAD0A34
+EBA2F5EEE0828C16391E5D0F5C0C759655F822B4C12BECA5B81C8A737280989A
+AEF491D2378A7F0907F137A955B2BE24BF30C8B71382643A6F8DDE45ED9D9566
+0CBDF39945F70918DAF39C0D9C989BF337C224357CE001F8C868C1B0E24EE88F
+92090DD28E0E4F12CC6ABDE9989754F1DF6F0B9305E08260A834E3C2F97FB36B
+C6750FB19D900154116C5C2D7294CC4682993ACD754BBB3915C126EE1CB47EF8
+43F0044EED399C7D59A9CFE788E36AC583198FAEA799F310EB54E5F3524734D0
+9484024BEB1717A3E76F4E2C325606E39AFD9250D0A4FC82E229FC9D062E26F9
+BD8A42F289345AEE7DB7A0066B4CA6E02FF77C3D9569A40A2BECA472E085E362
+DE842CB3AF49C98CC485C6D1B9401CC7B073445AF80E59E38AAD8C08B172A235
+913B894C7C5FA15F8012A5022F65B6D35A486E2DE487B3897A4245AE65C28019
+5E304EA97D7E1C5601C596ED82CB135DAEAA246179B11607C7798DFE8A8F32B1
+E175420B79AAFA0A23F5D0CAE915870F8D4A840B0647F509FF836DD9A81BAFF4
+EEC0B0283DD15D09615E02C1EA92610184E0B4F127E2D635AA6B236827DCEF49
+81E16DF5BBD2939FBC9C5089AAB6BE997E412254DDBF427332C42A5A55D62BE0
+B593AF26E2B34E076FC71DA6E4F21D7EE6000C72DB3AA84D9E0B1A05684FD787
+1B8E62F844EFF5529ECCB971145AF13BE7F2ADD2D62DDDEB34099CA54CEEF882
+8846BA06AF5CF88499446ECE01AF058084B1E4D6D005D4292034EE716E7E1204
+20D2722D023BAFA222A4B36FBD2B447F8457C6E2B223FADE55A49FB3678823D6
+94F094850D6007F3823EC4805E5D8F106936C9452355FB30A32972B0755A109B
+9D889ED128E0B10C1BB22A93F5385F7021918699B692D1CF64137817811FA635
+92FC6831A34E3FB22E16E7F431333022F3AE17183B7D466EF8962FD6D6A77598
+8B9EB0ECF01A276CF1D977417BF0A83FFE3F4E2C1F04116F2C81BDCB47940BA9
+672E31B7E9748A15EAF0979490700B9F3D403A1D625F5B229E4940ACFC62E08E
+DAC48E011B89EFADEF9111F9528BC2092B772F7C80C493F1043FC8D55194C108
+FEDCBD1782ED6D64088BEA1C398E12D8F8B56807D0EEFFE341DE8F69050B01E9
+F3AEBC8A420605EAABB1FD20A2C6DDBB016CA3C198596D0D95978E3A950B2880
+ECAA0091D14F107095241446C4A693DC0D038645FDABDC622F3D92E3DD51A526
+42AEF69625E7941487FDE579F6474754291B2215E2D5C8EEB62B0223510007D8
+18B48237B669091E8F81204AE1DFD0BE28C39C7FE61F4C796079C60AC90B4223
+372DE6A5BC492686072F0226C525D575F717070BDAEAA22379CE508BE96D8CDD
+9EB3520F88B0E69F56E72DAED0CB77FDE37DF220A02A1AEB445A2701E1085864
+E8FBC64F0B53E10EE1FFEC765C766B05B35E430BFD83E55A94AF677DCFC2FD16
+A2BA4F1B80FECCE197D0C246A9A3329DE1988892494FCF17272D4243A4562FAA
+604DFEA30540DB06E9EB5F028BC7FB59E138B4C0E5973A023A7DDB768F037AB9
+6D3A55BA64C723406FE4AEAC0FC198060230CD1DCE4AD9A38A265347458927F6
+8D6CF4BBD02FD21C8D48241123E4563B2A448C07E0ADDC26DF600108A7584B92
+696F324E06D186E67E5F3954B69E04DC7DDAD01D833EADDCB802562FB5D383C8
+1B4B37EE95546EA470856F010A6C9A7E314F16AD49F1EFCB64C49AAB640BBBA2
+9A54D16FA80286D06AA56972932C9DD7BE797912BFB430E75BF0C5571FAE652B
+636D6C329CC634234B5BCD44FF11CB4F50EE9A1EBFCB2ACA2ABC01708F1742ED
+BF0345AE22366106EDBC937171D6FB973CF7BC017BEB2D1DEC23D5EA8BFBA775
+A622F99CA58583E600016B26574B9DF996E5B8DA6E3C3963D8CA6D883F2AE3E6
+5D5B75F4CCBE8C351AF744EE8EC447B9A5F1355D2F6D1C00350D1523879274CB
+0DEAD99DB739F0BEB6B8057857F8842DB8C14C55AD2EFDCE989B70DC1C8EA024
+25010965B54859147B01CD6D14849F14B2975D6BCE0B6E5424C8B24B202F699D
+2B25C3EDA416388FB272725F097A61B9B83CA3C7B10EB446485F9BF022C3A49D
+8CB3BA72DC84DCABECB1652DDA6D051A53ACAFA716E04BEF88D092FD24552A15
+E56C3D45379F3DE16ED2F4EDB063276C0CBB3367E0D3CC7A22361FA087DD777B
+7700DF681CA7F8553A785767C30B6EE64CEF0F5D71D7F730D943AEC07FECCE74
+B56561DFFEE203A3E7E324E608134C0EF63E6DE95A744B8425F2633CF988F140
+B850A301D3DC3A593F7A7917A6FF14F5CE8A988857F8B7FC6EE4DEFABD0DD204
+EA64C9E0AD749C6F808B84C2E70FF91FD038FA224E8F1EF92E6AE8161A3481E6
+FAFA49F50F549F60999AA156DD6B81B86266248E6C92A8BEB3435A6C1BE2841E
+AD5C859D0A106813C6DA8D80715C8D26AB447E081F3E6EA832386577BAE02C4F
+32DE579FCA6719ABDD7790C78512787987EBBF8E31D930CA869C2632BDF05FB4
+FC711310A33067C1EB254FDD96D5D1561C5C33C6E2F6D6116B1AE129EE305506
+9BE2A3BF2A014862056F72DD779A759EF65F56D124B4A9B645FB412825AE478B
+B900D11F64BC918D7B693A6B8F99E0ABF7EA9A90E8F1844D57D6CBCB91378406
+C4AF1A285D42819A6CBF9035BC9EC980A1F06C3761CFEDD2CEA92348AEB81981
+B44FCBC14C4711E1772EC20BA23DF1B87360B966074BBDB6BEFE0DC113D932F1
+BFB62CBCAE014F93E0A982E32A7BBABE093A0F613C2293B93A50E3C92F7C86F7
+03C57833BC8AA953EAF04C812B7BBF69401BFBD12175CE30A383F9C0E665F5C4
+47D064D71B7C55E3EDE73D4FDB39474E3477C1F41DDF0676004856981DD66BC8
+52A02BD9FB315AF8E1C8C46D913FBCD8BAB672A63416317D044C0BC9D94D07C8
+F9869396352681EECB7111B6EB787B41F863BEE90DACA852E36AB4566011D279
+BCAC46C22ACF967CC133B8B56275AFA4811BCA2F5ABDD5851E10AC9062EA5899
+88698F5CFC0EFA9B83B71E9BEB3E583D63D6A0E00F7BD257D9CE89A6475D7887
+D2A2824C99BA304A8D6728CC9DB1420295339429E93839B5BD33FD52171A5D04
+0E31E2C3F4A59AF980CBAFE2C0E9F0E3A364E58F981528AE87FEC2F49214CC78
+235787626246215F2EB7EE93BA23B269183D0844798246AEA9F0AEC7913E70F8
+979ADC112D6B9B4630B59952662B3E5410FC51925E1A9D65AE9E34068A8B9E89
+E5AA71F1821A242AAE6FB07E3CE346CD190D5B426227555D8E230EA97579ABEC
+1A9CD2444944F7046B16652A8B028A8019FB42DF74FA89F9019BBA88C3E60F49
+3FAF0BD601A5C05FB3CAAF69E8E2DCC73DB9FAD38F55D4C278B5C87314AD7248
+0C2C3BF34B16B7D3ED8ABFC4AA1B09672F00455486E2277384448F1D7C7419EC
+9BD3910468C06D1201A63F8E94A97D2827E92FA9C9C2E3B5C35DC438DA1F26F8
+7E854D9024664920D6B34AAA9752226FD8E2F55BBA64B7771F72D5C819956B66
+444985F3D121E3484A05C8FD7D979A0BF121705C030BE8D72A0C7D7676B8272C
+61031238833FFD66570C2CAD91E3A007B66ABF47B39664B3E4E8FCAD1D7EBC9B
+F9B260D4F29CAF2250DD465C2C139D088B3EC581A2ED4EF173E5BF0B2F0CA408
+90D79B4DF2CB441059F4FC2A87C836CA9D143DC75EB56AA3E42DA8BF14DDCBAA
+EA0AFB38E56054AE830F8C318ADCC618B52B57ECF18C8A0C9FDC24B51EA348C6
+A9A1063934AD4CAF79FF11ADFF51D1DA20A2F8F7CFF5490A9C9D2DB97A94569B
+1611A53C24F8949345E0E4B44053897C7F96DDFFEA8E228EBF734741667E190D
+4A6D92566B23076622CBA33B9ED8BD9600BABF2248CBC9FE077FD59E3C3D72E1
+95D564FF109714AF51B7499CD15636E1446C9DA0904427C28BD2FD268B2B29D9
+D578AD312880FFA16A784DA6B7ABD8CEF20229F39A963E9FF5D46078DF3F55C3
+ED814ECC054675A2E02115F1A5BF45F8B4F74A6810B7956379BED10C55907467
+C9E9F5A8375B3C96F7B69E06E55879D73D8B46FEDE5682C5C3A98829D84ADBED
+A210335AF38B413C750D6D0535A57A743E0DA9B1815CD73E57DB021BDB147CC5
+BD0F50707AAD31FE3A5CD37C3543C660CD7FE65138A1C411722659C976B9B68E
+A881429B559AD9360271394F195E28092BA0FEDA0BC47879885B418E6E8DB7D9
+7709751F979360D8FECE89EB92CE5E583788E5ECBCD5291C5BA1A33B7113B021
+CB66F820CFD79554CB718FDC9FC0059CDCFC45BC3AB39FC06668DA03F9DB8565
+E07277C11FE2498078A52CF2EF39C825B149E272B484747FBDFA56016EF378C9
+B3ACCDBDD7E36C273676FD3FE43B9A0B41A1A42F49AFD14F0C8F6C2DDB9E25BA
+D9BFBB6A4C521EEAC81F50E54A5A9271D299301D559D22FE00E914FFFB0197C9
+98EA934A19C4E3173FC55AF7210A9662AC29B93B89E31AE842A8D99166FB3A61
+8C620235318769B9C11CB9F3BF88A6FCA52387FF22273580CC3EF225BE4E6D83
+ADBD20361DFDE529FA426A635C3F757CBFA901DF3B5BCA7B950B16A6778F5E3D
+0844017DF62C84A0EFF556B4BC25BDB84A399E4DE188CD3440358A38359974C6
+FA9FFFB69C6CBBC7471EE52AE31066DAFDB4B203232C1C31AFA55BF188177001
+144216E0093E43EAC08857DB1231E39FB13D5DEBAFB7782755BE138B1A77AD67
+8F9E6F233E4912DDAAB2594B4DA0C32F4F956CF9C74303A33B5B61EEAE053F9F
+A2707E8C88C200835E261AB5B27341277ED501FE9A81CA0CCD67459CC0B40245
+D74BDDAFAD40D89F503EC435A98F9438362A1FAC5854ABC086A0E09E0C74EF29
+7F91D038B8B3DD4ED7C47E587EE6EB99DF1DA66B392A2652B8FD8704B2FBC18F
+DB014B15A4A08FD71AD4FE13C862B0F1B48B5BE7C246A308ADB1EABA662BB2BA
+177DACCCE0FEEF2A68B5F2B998B0E5E371BC4CF69E09929310E45218EAF157C2
+18D702A450BF8C0057CBA39132CC04E17E9AD2F8F1D5A3AF0B68C21B11446E51
+51216B23A6E1F49081C5C4DC58EFB0361D077DCDEFCA0B4BCCDAB28EE2194E91
+AF6C99987737998BCE51C61CAFF318CA6215A21B8770F9755AFFC7CC1BD7E538
+8F46DE997B8481C13C46560BF76F8BF4A4426392CF5C56C6EC5E888DB6C8F5DC
+38E426BBED085ABE840AC95D8CA07C3036CACC677FF710A5FF2316D1236D4637
+8857039A64CE593BEF5620EB9BC86B0F674E402C662A7A12B2B3F247A3EADC51
+8459BC247E35EDA8D0EFE5AB59015D0838A883724F9C7CCEF7EC82BDA4F3FB6A
+6A6C3C298111F60F918293FB8A55E1A870F87DEBFAD5F1B27DD475619982174F
+95BEB80760789199DD0F21F6DCDAEA1759068E08B4F346E2893C0C56C9E37036
+476B9B614E727625F838D807074F07AB3059AB26F3D5121A1D54E131B983024E
+DBD29F788B507B034A34B2EEACEECE8309320561CD4363612B86EA5D2E2FE273
+1856BCA3EA097D94CA7B852A2CC829871077090CB6B857614B91BC6D04B84D3A
+0D6326349CBBC24E3F86BFCE5F1BA018466161A6E9EA8CEEDAB5878DC1619C8F
+7E288E9353B7F866D2729CBEAE9FC03AF9734565D7CDCB0EFE4D26E16DB80A5E
+61CEFEE33D280600849DC7EFEADE8E8DC910451687F92418B340608F22EAD7F7
+82262CF10117A75E9B64937EB50687EACAECC0A385EDF8CBFEF3C3E288F781E3
+E6A3D328AB09273C0217E04ED080A696799F215CFCC84CBAC3BD150228C98536
+D8CBCA18350B8BEAF8365144F90D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMTT8
+%!PS-AdobeFont-1.1: CMTT8 1.0
+%%CreationDate: 1991 Aug 20 16:46:05
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMTT8) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+end readonly def
+/FontName /CMTT8 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 33 /exclam put
+dup 34 /quotedbl put
+dup 38 /ampersand put
+dup 39 /quoteright put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asterisk put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 46 /period put
+dup 47 /slash put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 63 /question put
+dup 64 /at put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 85 /U put
+dup 88 /X put
+dup 91 /bracketleft put
+dup 92 /backslash put
+dup 93 /bracketright put
+dup 94 /asciicircum put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 120 /x put
+dup 121 /y put
+dup 122 /z put
+dup 124 /bar put
+dup 126 /asciitilde put
+readonly def
+/FontBBox{-5 -232 545 699}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0187316F83DDE3E2D27FCDF6C5CE4F95B6EE
+3317BD91B7921F3039DD35FEA387D5CFB6C6E9DC84C178F3432994FC7FAC6E5A
+ED41A1E2EBA350178FBFEB45944511731BA827167DDAC238FC69A5486B995477
+C469E2E27493B0B711DF8E267D3D5613B450011921685147114106C9472580BD
+F531022F6DF5432B2A4EBC51A8032C7F9689B6FA942D849B29709631613DA68D
+4DF7B6F059A19304F40A3C3580CE3B51D79D42984194D4F178801720892FB6E7
+61FF43C63F9256B5E9F4227B1378222BAAD4D52C77462DF01892220E11129C16
+6C9E45BB9F01ED7C1AD5D8B4D72BE0E12969AFEA90FEF170603CDB91CB243173
+B19A56084D10293B80A35275F41BF78A054DDC98F4A1FFF592463D944960FB31
+6BE5F03960F9B1F213CBCC7FD448657FE388F10104D42B0715FC9571CC60CF23
+C72560CBB8835A0CA208FE06676B3B48B093CB7FB2C0C53AF17EC5B372A9771B
+BFD52FFB7062B4FE0106A01A2A1A1DD4EF5C8C7623EC9324A2CB3B402FCC1FCE
+52BFC8662F8A39D5F1B41C97E7CE34E16AC28A1E94007AEA7D4C519399F1B7A9
+48FA7DDB671067244F09C29F95DD60668223F45BBDA8B1C452E930A9F3F341C5
+351D59EA87462FFB30277D3B24E2104D4AAB873BB2B16DA5B23BEE25BE2C8128
+C4CF2F4F438A4E520CD864F3EAFB5363753B82978F6FD664A14E5D6F3A929348
+5839EA752FD635619C4FABF1E1454510BD9D6B538A343BE748AE05B47F917367
+1BA5EDB15F1BDBE806E51B294257D7087334165419A6520462D794D670A1D6E1
+3BB03BF689391D056D55AD660D15A386E6D222C9572BDC4DC8A46EEC75124BB5
+F0E8978FD6031A90E4768CCBF62A5ED8C8087FD66D2033011947634878BDC0AB
+6501DA7E6D96E227068E993DBB0072F037CA4111CAA4C896B6CE9EE0250B51C5
+0EFFAFB8EF7A92590B4EC384EE1929683207E4929CD7257433101E27DC54947D
+F00978B054847365048F06F69F8DEFFE073E32F59CA98FD9247A731415CE6908
+153BD01A58F2A482D52F14F7DD894ED0A02B191CDC565FA10C6ED6DC3344AE56
+E9FC70E591272388021F4A8748A67BC0A18A9B288FCD4C39979A44500B86E099
+A370DB711D17469950297B835EBFB63130EB61014997493D87CC689645D41BD4
+99AABB9646309F174DB93723DFA8CFCBCA0FEDFAB79DEFFA012A57A046606B88
+58BE939A18B4636E21AC5ACF54D0CF400C71095DC07FE6A4E99E765AE193FC70
+42EA351128E04FC669F1CA3A291FC393BF60EA9CD97CC2BD857370D868CC3C2D
+5ABD84AAEC869BFAF8488F39480B8CB70CEB6E185EE4285EC732179CEBE94604
+5148D3097D9CD2ECB9E4A6EFC03AB1D2F88F4C7ED937CF3CDBCC701B4CAA619C
+B9941FDC8DB4D039822B678A464B0CCB1874C1C8E765146DCD430FF6CF5DC96C
+4826860E966E215FAC9BDFC834D700D2FC269B2F410509EBC13C25CD9A6D9881
+E2571DDC88527319EDD129EFAA3C9FFF38BFC3A9A88F518E1D240BA5DB4DFA56
+D6B28B2B7CC75C52C9A9367DC0CE9DEBA73F47A7FBB20DE236A40435159F9254
+5859B587ACD4752CCBDCA9E231D165C2CFC3F4AA1C7D1E247A0FA17091DFD513
+E7D8B400B9FB554FED4FF3E3CE82600D11147BAFF76F679D1A13D29935F77C5D
+95E975F2B598BD9513EFCD772D6F733A926880E6D6014C7A74B1F1C949310571
+A7DE4F7875DB96FE4F43D9D9C1041A43041BB52C05AF16486BE415365FA384C4
+5CF9EFA63F37AA33B84D6450943534A0E4CB218B6918D824629C8F6702C9F199
+C8B4DA38CED24A3459E8F781D0992C9FC46D455D06F1DB03C6BC36026B9BAC0D
+0C8902F27FF548E6E610B570DD8B6EDB6AB09712DEC4459D1CC8C8D21C5C26B0
+7FC2225F44C3D80161B8D9E6FFE3050B952B2E49D760E690A31040E28E2B37E6
+879875DE12F87D3E7B1FDD8E82ED97F9FBA6D2813ADF982EBA9CF4D422503EA5
+283EB10280B29F74865B96B83801D73F0BCD851D6848470F4B55F360EA10B3B3
+965B70BD9851E0E5129337E83D911F20B92D4BA91EF39DD0A84576F23297B6B4
+9DF2B793FA14CEA29EEEC52BDD2BD3A496FEB0D5AE235D12A47B3ED4021F126F
+462268C4C76C547464A9947C2357F33BC0FA9EF35D7DC332E1E7D9F7A2E3A018
+C244C6462890374389CD7DD2CC38AD437F659AB7802F82EA9BD46CB86E832F18
+1546F839FE038B1E3B8C9DA0FCC002B541B2E0E00B7A5AF854C48E4F333E46F2
+BAF6F02038367CAB39F94A6F5B13B34A0E0F6DB6BEA9015303908C025F981A5C
+C8167A1528DC7DC39EA6614F1C9986B80B1E74F350637BE6075CB3B388CF80E9
+3549A87345ED58933B42248AF367625ACACE747F82A2761696AF3BAB8882AF0C
+E2BF72565BD9206BB42D18B39608F8B32B1A106DAB2F53BB47A05BE458655427
+F7B3CAD17B65AAE920EFD2D05C426EE762D29A70E67A3561C496A95958A8169C
+F7308423EB93FD3FA607986411901BEA258A3E3593CF32A039CCC43598BE87A9
+F911FD42C11150FFB9E363F0A68F2260D1BA18A66572201EC3C3DDB96E202A94
+AD750DD8F7FB29D2C8D08C47F8E38AE0E016061D22552A0D120E66E641AF1279
+CA365D5641A279C9F752938C89208E0D415D0DDD2A2A2E6CCF8A92A22166CB8D
+E6DD3BF30CB892C1909EAA8609D918BA28B713CEBE57F608581F7476253AA383
+7A3161C13966BA31FDF6C9C5F761D9D0E78AD6ED732AEEBCCA69130C64E2CB77
+CAC7F5B75B048CD0951E0A672FD44A4437AC12A6A1CEC11FED0FEAE526927751
+FFA46DD429B8158F9BE2D6145C22D64220B82E826E386AAB05315AEF0B0C14FC
+3CC30CCDB25DFE696E760CA40E2D3B6DA1B32EE92FEB7E477EBE902ACFF42D02
+9D35BBA5EB0FA8D01602BFF8AB2EB0108810027DAE95DFDAD9E05D6565745153
+3958F5AB775E719806F9641F25C4DABFED6E555F6B6FD99DEE835D02D756A49B
+DA24C0A82D53DC185CA9F86D3A937470D9D6F429034223DD1DCA717173FB0738
+8F97AE8DADA5B033B69E469FA653AAD4C11D24A32EC9039D425890519F660F26
+79F8DB03C11D480AD5954C3CC2ECADE848D29726F46C0998F48A0A00C68B481F
+65899353CEE0853C27683FCCBDC4B3492B90B63AAEBDEFB80B80789C6C7205EB
+B82E72E9B31A452FDD3084B82DC4E52F674B790F6CB76D98918980539A242FB3
+07DAF98FF48244A650CDA661EBA17E4F0A9085CCB1167A3649E73ABD8C4A10BB
+E0F9736BD694404986065DBA7659FA548D7AA9DC211FC354067D571ED7B93AC7
+3E72A580043BD45239B1972D4B76A46C264D96435777DFD295EF35AA4FF5605C
+664F98208E12E9FF182768AFBDDC0D85CC5012BD8A3940AF7D590B588AD33F0D
+7C402B814D087B867A31B25C500C0806D9EA56F602D574B9D53AE1B62E583840
+2C82C0FF6AAE7BB31170EB18B78938E107036395F1EE04906509EB25664722D4
+B8BA69AFC4C1AD56CA362E721132C076AD2F19CF210F37F1EF9CFA815C82AD71
+8942F60B1CDAB7C94D8F11F272E2E6E04762584665DF78A37006409ECF881666
+C6A8A75613790D6D1D935A57430E7B82CC28582391AEBFA22C89EDEE5C11099C
+1BA35F332CB3AA0AA71FCA7715D2A755FB5535C2BE9347D62AE1C9A78769B18C
+D90D2B4475FB5F74A9C555C7896DD6D7D29166FF7CD927DFE0F57803246237B6
+9437C784950127A54B7095F6C26B16D8B66A1A3EBF53FFEE3E0A389DC9DB8A16
+BA2E5E3AAA6C0D4287BEA288BE1E67430069E70C66669CE73EEA4F13F46BE637
+D4E62A3092B5384326A01DEAE8D8D6C1699B089CB951CDC13C10252CA724EBBB
+8BE747374E691B11C8E6E34C3A3C345B369D99B4DA5D1F3A8CAA7494CDAF09AE
+048235F7F20C3F08EA6B0A224EF6EA13E3BF5DD39B2B4D48F3E51D70A00D135B
+96C261CE4C757D5A8A49F579D067B785608A6DB806E48A7D19CD5018653DE4CD
+A77217665C8F454CE1AA49E307FD189138CA6EBB269F5A8E9A8ECF75B42B2861
+A042E06256388BE90A5DE3772D685ECC5B5ACF663182E41BA5EFC2BA060E277D
+EEB21BDDD99A430E7A7A601F00DC2AD210C6793C613C09DB9335720E202F8231
+BC4184C86073472D41360BD3C25987E6E3668266273704A226FC74C534AB8ECB
+1DBE98EEC7C08471542BCB0DCB387A35DF3DEC4F8EB9EBFFC2E924975943FFD2
+4E0606C6443950B528F2D332789E5D64F94633E3BAB4E55CDADBD7115A8C0ADA
+47AF34B0C4D0F40668247C08B7904BB19E15219C067D3C6CF6A3919638FAF17F
+D929245909E8D87CB1DB811725BFEFB4AD457AB43F8D8CF730FBA475D445F74F
+4FB7084B60A9F833D5A39D0B456858B1C3A435840858404F875215C0A4976F35
+0C7DE54A889C84688D900F971A6798DC372E7E8D72CFEEC40D4A4D8E12BC1442
+D9A4159DDFC81EE7F818E70AF49239D1565CC2E34A4F7D8E140CB6182AC980A7
+4522855B9744B313D96027C30E32A7FA51BB11885F8E38DC8C2B6ED446B66B85
+2DC8D22A348EEA171234F7EDB6151C1C95B5F1BBA45ECB8AFB808F78FDD735FB
+E7366C2881D44A9CC1F060F9A910A361FAB01C1579CC4E605FE3C3ECF73DE057
+A7C27D9AED325A03D4DF4C92FA3A23E8AEE4458C762309D69DACDB5E067621FD
+5E5002D09253062EB7613991A6A3F430A7B67DCFC6CD2544295D18A12914A615
+59DCA81E53080EA3906416FB1000151D32E30EA714CBDF32C3D0A3B927C69DB6
+B9420EA26FA751CF764376C50539BE3E7B71407698E7EA0284AFD1B2A3B4D3ED
+A6D489E706EA852B1FC9235BF28E6F0FF740CFBD3AFB581C66D313D7706692F8
+F8B7969508A4B015B8BE63879F71CC8B0E0205C6D995F0E860E71ACE9FAC93D0
+4B947AF8DEAE35D11DB8F051EB806B2A6AAB414A1EE8188B1F1652FE111177C7
+D7C68FDEBD8A79776D43B9C88FB245CF85D471B50FC5DE9372496CC0A9811C4F
+5AE78A4B8377F6C259C149496E8AF25634C7CA2D8741D9D2E3DD4CEFDFB40444
+4223E4A3D6AE8BE00EE8A72755C35BA04251D3ADF0F913D757BD5FCF2C0D2560
+CA386A34E6B9770178307985ABD1494655869009704776BA6DCC7E8026B2C271
+D539123814B1152A46B99CE07E17941AC8D3F3DB18FD8FDEEECF00278D942437
+C260C44FA423C49E8BE0C2A626029AC92A375203CE45A82284F02BB42EDA5FBE
+B5FD38CCBECE4AD9FAA0404AAE1B7B44024716C37671972552CD73F5C0EA36DF
+76F08D45C48925FAE354A83A2F4023E4D2FF6FE44ED69FEC1ECE52086F5D6470
+A20CB929F6E52D797C42C7A3DA259C878D2CE92E33F24B0A0D315EFA7F607283
+D33C87FC45F9BADE0B0A8741898E23AEF5E28E075862110C8C1CBAEF80961369
+C1CABE3125357350D3150A1821D3B629FA667801556CEBD2C9767F6DADA4B0DA
+FB41BD72ADC6A71CD7BAB7F9AE4DC3C8AD3C362552BF7A3F8D58194627D1074B
+E16059DFECA7531AC8D498772ACA20D79202F21AAAF7BC30A7572C8C6652F49B
+1B50B734D55B30760F529799B5CCD62027FBB67784A8FF6C9F58A0F990301C43
+A6160E8DA551BC3A30897C4E3D2DDD20DEE777173D6D92B94BF898A13D4FD48A
+51979672A13A21205AC67CE4AD609857CEC4C3AECB4C769748A44E06AA4F968C
+B30D049968E2624AF0540F7FD4EC2547145827CAF0572DE8BADB158D0A00F0DB
+46DFFD8DDBADD30469A0CC3D1135DCE8C146D0DF34006D4AA216AE2609C18CF1
+3D122477BEA2747297654D34C116ABE7DA503556E3A02423EB775FED68935A93
+AC3980F55DCB7AE69F0F99C0FD5F6DE270B7989E2D6879B0368C8D88F45D4749
+D80FDA45BDA1AAC875B1398F2DB250ABCB693EF8E5A3FB726AA43EB15717E8C7
+256746DE97DDB2EDDCC467958591A4A23BEEFBA7DA35BA5ACF0D9346375CC4ED
+A54EF505A722FE2C987F79FB07A415BE36D436DE2A30A14DFC1005E97B5253D8
+D1F4E60ED182E94D690CF9DEB9BF6E59B62AB0E96DCE41E3972FDCA85E0E3E82
+36572F9780658AA2012C07F00A9EE6C961E10BCC4B79C653FBC171A8AAF35594
+DD271C556396D59E8F423D4CF333C53C2084D820C7306D70C6FB1842B64F0ECF
+3148A1AE92A6D18B65AACC667EF4227D03ABADDD37E6FC7E08C741D236DDE5DD
+72A761FAE1AB90D3B13F3FB7DAE7CEDD0B446B185749F2B1F1148FE8D0A6A5E8
+57B890F37642A1EF9CFD9A64A45A83F1333D2CC98C136B884142CD3B80C761E4
+9C37C29039108D6C19B7E98038920F5E7B55982D84D368C785D1F4D2B71EE478
+57E2E991F0F85F78F07D472D42D4316A5B21C272AEA47F0748CF1D73E1B8614D
+09189887022E86B1BE68EF06559087FAAF2FD3988A1AEF646F8E0D30FC16E7F3
+8EFA26484306247E169053318C86B730C28BE0EEEF3A8F0646FBCE7F68F3E100
+6F9F30250E2A33BE18B1DF2DCDA26707F2329C8B4B9763692205AA3F3DCACC32
+2016850BD53DED0BFEC4DBE7E47AE9C1F57AAE5FC7CED07D868F313836F1B526
+95AAB531D1D25B4182065FDD81AC9D8E6F2AD38DA4326BE0234E3D4FB470036E
+5F634D6B0965598D9CE759235CC6B934DA952BD18C4AC7A5C8CBC3F6A306C630
+81842485A5EA2B4C0C76D370A2190C6609C2AFADBB4E41A61E356811B2998A97
+11AFD15D0FA0FC8EE02B6CF9728FD4FFB8CD9B29C25DBB28B74F605D59A440DC
+7ABD24B49A07073175CE8FABA09FC9113D5C031FA492D646ED71E85664C3D156
+78C43CCAD79D6478C6032D02C4C7032EE16354557B3F62129ED4AAD382CD659C
+1C60C24380667DBCAFC246CC0E546598AB09736DDD3A73CA4BF8CD92FBDE782C
+485A9144E7498B087C90FB5E62571BD3AAEBA84867743AA5CCDD490064AB6179
+0278384C481B539C62A4BE2A1D5BD132441558C8EAECF17F94509F8C57BF63CB
+E1906E88B54788F6941EF51F1030CAAD0C7813EB1946625B9F198DA1BF67458E
+89248AFE2E27513501F850E9168B989E83E01CE45911D9C52092A8C05E8C81DF
+AB2D2C0A286B7F0C8CD08CA5B93B0C1570345F4133031B3025FA12C1FEBD3897
+63E98E3BDAF56A8908474231693E0B5D8CB1E7CC50D79547E2D01D76B1D34923
+A1F45E7C14D3FE9D25A95E61EC7D053513FF4062DB4A9DED1D39FF4C0FE4A7D4
+4E3F5E7607182B431639BD042A24E4022E41D3F0EBE57EB9BFC21C53F3B601B9
+3626F2339C848567F43DBC66207F22138102B8FC2D80B558D27D2911FFF051ED
+8334F7418075002CD6F9100BF93EE3ABFFFE5EFFEBCA4E35470C97DD58E11C80
+B5E8A77D13A60C9FE68F298AE3E331E81AB8CD0F3AB83CF2A81060D296EA3287
+590C03F0C490CB0BE3B4F8096E57F3F199F70E6C10526D1F345D87C7D0F0BC5A
+D64AFA60A3E5184E96182DEA126406A0E56D5AD96CB7514269EAAACFF23A591A
+BE83978762FAFBEBEB1C42FD230514FCD905B28796DA068F9E8C03B0BE7113C0
+22B278EC32A462B0A0FC9626BA387EDE3BB595E53D01CFD596FE224AEE05D2B8
+8EA91999E6194A02A59A66B552FB49F1D9FE5ED4D29C53A2EE78F9D1C79903CD
+6F42E4C0DFB942E029796B542F44657D5DB334BC38608ECF78138AFB90CC355E
+2CCB9F821892410695FA7827BFEE269B918954D8EEBF2ABA78CCC772837C3393
+CA8C0AEBD7715C89AF096F819457CB7025412838885453132D380A5914A46CA1
+BEBAEDBFC55B18049331E887C9CBC1D1DC9CA83FAEE7B89794AB297C9BB5BE9D
+66C1AF64CE0229A73512885AE1845406FE785B007A6DA8D3133703CCCF93FB90
+1D8C131E9718B3A036C6BBEA1D5089C07ABCE7AACDC8DB1FB5DA2A0DFEAD7FBB
+3D21C4EE1DA505D4ED6A7D10AA7E2D56E88092AB64E6752BCF4F59670CE681C4
+4B78DF95970437EBA2D23AF8ABA02F8B7B866EBC2A00FDECCE08634490BA6624
+B192A37F8B4B6F8C297CEB992FBD08992B443FCC536CBD68DEC67367DDCB4558
+BFD6D21C943D5AFFE869DF4C5AE9C54B9F7A75E633D15AE242C0D248E82B84A4
+2CDD3146EA749C161E5A1FE702EB66DB820841C6B538A35D90FA28CEDE2AD78C
+4291D459C371B806B13C2406C557B456BBC8E805E31E9663580E2751DA583C56
+86D5A5A56B831B90053B79046DC35AD611521FE64C8B71C21B07605FCAD63F8A
+5018363DF7DCAD4D327BEAD99605280620FDB39AB819906E4B5DF8D8D11CC825
+A8585971BC1E3130FFBD055546555B4D0623CAC4125BE73E020EF968EAC4CED6
+3D8E3CB2D2321D50062307474AC45806A7632F415D102A40FD9BF5A23E0E6D4F
+A7D872B54666065B8EDF1E0AFAEF94D2209DD3863C90CD82A9B6C04A66900767
+6F00DFD4EDBF6021E416C3B42B30C7137355DEEE2D18F4CC95C30C45C90B142F
+7195C8A9786A3C1AD00B813A84D59EB0404CCB88F7D0B1EB732888B96F9B2192
+71479CBFECDFDFFFA3C6BB355B3C9FE1D36F82EA9D8C1EB9753E2EFB97DA2B73
+A0538657D2026F7F7CE539CF5062986AEAD7D9F5B3D799153AB17D7BBDDFF735
+2418647685D05A8BDF0AF59A1F4AB93870D49D2A029A837921C9A6C3D91C54EB
+6BCA27A97BA4FC19C0467CF8438C3C007BBEA6075F683CC5C0EFAB366CFEB409
+14662C150CB5DEF14930E497EC4CA56E9219926C53FDD87E2807F92629784975
+1EAA8392FCC89BA6F77BA689BDC903ECBF05A0E031C2ABB4B6C8DA4CAF93445B
+0DE5B7788639BFF3CB6B1A9EB6B8847DDFFA679530B85284B8D8B97D8C231F3A
+89DD3AC023AB047A6007358C7EDACECAEC273839BD3AB978DE5BDDE57468F67D
+4E6AB6E557B81AB232C039D462216779FA25ED35744442F6BD18F6A2FA827617
+6BBC802A41FF4B74EE717E2C5D470C2E866623F4737BE7228A6D87342F1103CD
+3681DECF3CA1DC6EB595DD32C360B4B7EC21BEFBA3BBDE28DBD27D5761DAC1A3
+3A4CC3B23AAF9DE8E9C711D06B49443E2A71B7DC0AEB3E73FB438324E0D81E93
+5387B59955CD4E8BFB8AD9D07E848E38C2E32F9863FAA440AAD9ABC1A003FCC1
+D825E1B5F8FADE481BB5356E9E5B13070D63AA63C1B9F99FFDE234C17B28C50D
+9FCBBA638F786FDA347D3A6228B61B5F726413194801C3B3EC9486E1B8EEAEEB
+B9322AB9832F69FA3126162476E549594D52955006E4A9B2726952E562A39546
+1548D255C5E6966EF60E6F07C5E076AD17215E08C7BCF6AB3C2B181BAEA7A757
+9F7557B9824EE211DCF1D3E4105DB69A9A776BB55AEDBEB563C0FA2A20041AFE
+28F8301ECDB44C2F8D540A48E23E47251E07CCB66100A98611A9A6DD311F88BD
+AC3C391078BDC7B1B0FEE6DA1F3851BCEFB9191654D427B2419E7016B6E7F62C
+A5B22D6FEC9B0D75EEA91BED9D95D20913390B873D2B1F4B3940DB0D1F1E1187
+EBF4C71AAA864723D91EBD3907179174194BDBB7CD79C70D231136EF8B6BB8BE
+47ADB2788798614165B4DFC099CEEF7330627A16BA7E2D2CB4B319728E2934D5
+4941DADB68F1C3AD870DA304E7C8AA8CC44A15F8B9BA14F12A7625169180D2C6
+02618A2A79D089B0909C24F389B545631EACDD55A6444540CA778C18C71668B1
+7AEBF82DFB1B300B83196DAF50CD5973BEF326720A9C148FFDC1FED9428547BD
+E9A4DD0075079E0D712944073DF485C4BFAA6FD7C1895379F8BA00C673916146
+9B79CE2D547F0795FFE54E18621D7EDA22C829828B4CD681968F4934F7ED23BE
+05D0AA4076ADB784215851841D4E98FA280BB5997C62C83234D6C8C913E6BDB1
+41561831E4961E39D88A2B66930CCF642F63B8ED38F9322613411700933D2AC0
+BD940EC4E4073121AA0FF4B4BB0CA59201514A97132206D384E04A490376C560
+BCB235EF089AC60F6B1C9895FC4A7B23D0B83E64A13BA1653573C1554A33E9D9
+B4B6DE94222A0D540FAC8BB6201D73DC187E8D0D4FB0BA2695BAD9947C8386F1
+9F45CECE4985D9CA6D87EDE40706FCDF568A741A8AAAC5DFF573AFFF61A3862B
+E3148B3227812D171F0115FD88570764B83702659919C2F372C9D24BF65BF543
+A62EB34432F7813F2A014574F8BCD08896A26B34CE4F55CB02DA4F9CF1962C3E
+7A317E672A42D9A9EC06BA5B10BA0A1CF21F6F4779F087CD659734E22036BF03
+FBCF026811AA2BDF3EEEDE1E9191499227E6269E4EFA965BBB7DCE8ED02902BF
+E67D6903BE5821CFFA06057788E85D3455825574D5D001E78C059489B2BD1BA7
+77C8BC109B385C4CAA7D460510BFD736937290404B0AE17241BE08A90E0CA666
+929E7B789D4CCD0E4DB271D82F912989F90CB90834B9223DF8AD24F245B1B5F8
+310478227BA1A8FF2D03E1EBAFBDCAE2BC34B02BB74842DE65276F2E6F4E0D4D
+12005907ECB4D49C635195D25D64A19F3645EDA989590210E0BA1D73FAF37444
+FDF945684232C0212EEE51434C839D14C16A26578068A1759C299B29BA0A8D80
+CB942F1F0BB4E61784EE89D737196CEE29715069DFCB80D6C279B3E4DD4F551C
+6D0A1BE85798ED20AB0C2AEB2E88B6FE961E37145D6D1BF0A267C3423B5A441E
+2566E5463718B85C60F2ABB02434BD0C7EA5CD3750181F0D1916817FD85ABD38
+DF7555C33FC9F528F34FFC371F98DE2F213DA6D33A5496EC904DFE9B6D194781
+7A7A06E47677F98951580726051E47E700DF41C0A806216B666157D4DAFA1DC1
+CE159E7E379F0C98C8559506A9D5F36235BF183A426E19F5325C1629B7A33764
+28C58D41057EEB3B45FAD2EE68E2CECB4F65F5BA025325CB0B9B55FB8055C9EC
+54D366D43C3DFD961CB0B5F035ADED58ABF3C7D76D6059F5E142921A8919A1B2
+6543FB64441C350F0D1F8E54F35EAB79636AF0768E186DEA1FAA825A1A6F9BB4
+95A8980ECFFDBD9E086201DD6A0C3986A3F0A81907F427D3F32B61D02368B706
+9C69273D09C323D07AF9A0ABD2B971BB41069BAC212459AC8D3EEE0D7BF03C5D
+07EB71BAC86594FC746342FFB8D0D058508C350666CA61F175C42F0CD9B5A079
+BE6227053986728DDF9EC1E017E405B3ACBE1C4CA2477693B8E062502672C87B
+789E525BAC85E91C99726981B5F15EC61373E59467BEA179C78594FBC36174CA
+77270EE8670AE46373D9E4AFC7810ADC41A7A6688305E2E8D8E11EA7595104FC
+72C887507F8159E1B18FA7B19E6233F80DE2276CF2265A7127F843E1205F6F04
+1DED840B310E97E38B7CC7FE4615B061DF2366DD385BE46FD7E1FD79050210ED
+FD38126BE1925ABDC95081ABABA21E9D74733678012E5D98FAC3B9A96B1FCCC2
+83C27902B6132480433387D64B6FFE66D73D6AA6EB3A323525173C946E90B0BE
+10C76B18D735243EDA3890D0B30FC41094FBF6133E741425182B0BACE55E1D14
+2311E8C5833E25C7CD017BA4059E6956D8A626F7993B8B3FE8C0B2C22424F7C9
+DB1982E704431C0371C6A342C506129783D084366AC287412D61D2F6FFCB9A38
+05CA79E742EEEF8104701513F519A64679BA60711AA6509144A139F18755693F
+225078F885A6722BF7B2D28B4E01621B8949EF4DEA99DF31E159C1E6CDAB2CBF
+3A32DF2F53F8E95079CF9083F9B952ADC98AC214CC8BCB7A04D4C9A5E6DE0B8D
+2E60F6DB353796DE2367D4CB3432D6F794CB7DFF4F9BEB9EA8E8B275C8B12883
+340C2EC8A6967C09D20FB116E2F27A7D2E6381C2A30533817790A47ADB9B7C81
+57F2EF1B3762A86B61AA9D74954DDFA4F918722E7141E1E12D7C37E2B20CACED
+62BD84E09364B7023DB0AE4FFD8C9BBE29525D84CF0F973ADEFE61CB85593FF3
+8FEC4AD3239DA242428460AC4D4EF13FF2A5AEC0883A69B27073E703731FF8D0
+1E6488ABD8652CDD0ED93C01E2577ECD1455E19DF3AB9352C84AB1FCBE6B95FE
+D19360F8DD293E6D0F759705061503922C97006B3F265877BF6C7B9C2EFA5CC8
+56442D6C35B5CC773808EA85E741414BED70B09686E823F4DB7F8FA8E69190F4
+40BEF07E6FF54A3874100107D8D5808C64B978CB0F098A6609ABD94168C2B0FE
+A41C5BA1CAA825135C983BFBEC7C7E39A6D2C0645DA68DACCF84FB2AD5C08501
+687BB99E71652CB4E8E31497666A076D93EE375990CDA920B58969C946ADC9F0
+8341FE62C61C97A062AC76699675315FC141F11074BBA913B48D522EDE2BAB1D
+27C0B5778AD48B34F9A8B3A3CE0EC2CA44C786E546F8379E47E2F6C92EA8F2F9
+884335D0257CACBB902B7A55AD4B0570241F09AE34EF609B81DF8FFAE7DC0FD1
+9508095B5B59AF4DE0CC70993EABF0FB883611CCE7230A3D7EECA1BA763BF85B
+6629502BE58B944AF96827EA3BBD17D3BE0134979AC8CEC1FF25D6B2D194D079
+091ADC62E02E86A58FF98C01E91D8D8E8BAEC7A1F89D9583A0AB6579DC6BF4BB
+A82ECE8300725F6A40FF6B684EF8D3DEE1076CE2A27F2205CC25D37E2B65E8B5
+B9C98BBF61D25F88242DA0F85893A22DF39435738B4120C6658939593A56870C
+C3BDD6B6E6D1EDDBEF5314407E4160D729F39A6BB3EE79B4C88CD7062C775367
+3B7827A59FB64C12273AB3102ABEAEF14005FA6154F5CB9EE3E1DE94AF3510E6
+B01A6059F71C20E90E1572653F47A68C0261F8EA96D65EFE3F0E130ADEEA7261
+14E85BE04C9605DECFC02360D45CBBC4B0C27924BEF67253E1F1BEDB3129D673
+4E701A542265E53F950CA525C7ADCFF99777263B36F4C8E80E6F1AA3F0F6AC68
+D57F392752482ADF6914C5F9BDBA863BB659869E593969B275724A5090D88418
+AFCD3EBDA945876FCEC394938E039840621F764773BBB92E1DCC15E1B05CCD68
+A89C124A872E8A9E820B40EE517B580C049E2ACA2F2ACEA02094F79659D86DFC
+69DFFDFB9DA5383AA1CE42E9E68B7BF92FB62931EF2F155486818CEF4AE5C773
+3532D1BAD43F342DD9CFF5E7C16982B1F85C8EE873E4C660384EC769CCBD0DA9
+33E5A85E453924E188DE515AADE9C3B3609C663FF926951B9BC51A1F76D67FFB
+1BCC26739ABAD5E14EFD7198464169878F51F56A6AE1D63F7085C07A359702A6
+02B04E28A2A0B7B74762488AEAFA87914535BCA742EAF3BB44D874D076BE369C
+C88687E3A165FC5D8A5E3DDAB5A6365C2FD7FED713DC7F13348084B1C6150460
+FAEBE385212FBF488E6407469A02DF990ACF17E12BA2FAA09C39825ABA4217EB
+7684C1EA4AC42D5EF252C39287607A57B29C30F6DCD6FE387465772A9E241561
+5AF6D64E87E4F407FAF9E8CFCD7014AD6B83140ACCE5DDA0BC17568EA0C726BE
+07F6BB90F60C7C15CB339F3BA750ACEBE48AE45A30F9B18E414C1F39FE9C3448
+C75CFE6E1AB36BBF22D323108AEC0447668C40A60CE76ADE931F1BAB4DD18F70
+911A35415FBB10373533F6546FF180EF8CADA342A5DEF702E8B154DA9BB7B96D
+51FD29C281CEEDDDD7CAB5DF94DEB37E67E41D13AFB96C89D9BA96CBE43BB508
+5D42FBA45F217F0E87A6E1656B27F7A9B0C3CB25DA3CF493CA0EED4D59F98C2E
+32E441DFA6762B94FC20917D0EE55693C86F094061EBA18053CDD028D792B0DC
+A2C506FDFF1C9CB9DE1EBBB4A83EC7EA15C20AE6B5D52F3B3D0FCD8A9EAFAB16
+3FFBCA949E2700EE3664CD503A64B90DC6B431AA3F37307D0C5E60B611893518
+D39FD898169EF2E526B734F688CE20CFB65FABD434770BD1E28A0FF21BDA5E7D
+B3CFFBD4CEDD9919898EA41BDFDB92976CCEDF2AD7F53EFD4E5977909857B798
+C793D7D0A1ED62EAB720CA0A883FA813AB7E99D388022A634613166F667A15DD
+186003112EC6CFC45A061312242800CE03282C13E31E1414FBF5CD84889AD15B
+834CE935F21BA04E3E62821290E39B2BF1F753C051D985E16BB3E452645D96C6
+34AB18695C2D75D862494E7B5173D2C77A9E72EA99E780FE7F95BB1ABA02FF57
+5C4250507F10CE82E07C635696EFBCF0E616101EBB09DD7ACA088C6A8AB62AA8
+EBA919B5CBC0DD94C3DA1E7CA021FF31C36B8001558525AF71C8C048EC9B1A8E
+B8EF4067E69DFC2919EE3BE7EECBC9641A090DA833C0154F1E2E3DB7511ED7FB
+03CE31EA7EDCDA0F7D41DCBBA00A66A7F093E29D02C3DAC1221A33EA64EE2975
+323D09C8291A0D9159648E8235E8881B6982C4C13C969884E91543FE3FCCAAAD
+513D0CD45D674E28596BEBA1207C5593E12769E79E35940FDF05EE2F331624C5
+B4F363EA58E5143BEB7D73D8475D5BD09A23CFFD7D4CAFCBB847BCE311FE99F9
+548558DBF2E1DABA5510987F836A94FF3168341DCEBED7DB8D7DC3A027D8B76F
+033CF1D63A5EBA39B12F7ACA4CADF42616FBB1978064047858DDF55A8F702925
+64F1E1B1411C0106DEE8BEEB002D64BF1A2CFA9C3DC65B5689308AF1EEE4C762
+03ED130FC5532E6C79053FA26BAA3C4484F5744806D1B5C259337CB9099BC989
+9270EA2A34672C358BE6EC6E90BA480C01117D252BD39BB4D34B61F0A9F7BD10
+F0EAAD2B40BC5840D52356A9562B28EAF12DBB56771D9A5CA39EC220B1D12D89
+DEB17AFC1226AFC710668AD895C59B545B378982731EDABECA1B173BB123248F
+282CC6C4B8F2BC77A07F3F3A3B03219463587B746DA564B14F2A3105C87D45C0
+F5E73F048902F581B29F31A0DED4C54983CD32F0217DF9CDA2348474BE4755E1
+ECF77B963A182FD015579F6C8BE70A95667132141576D8ED6532026ECFC4CDBA
+4C7B523C883AADAACF83759FD2364E4CD4A7A44B32955F01AC69378694DDBCDA
+F3A61C754DD812231642C7448A7EC0FD7DA39AC844A94C7AB2F7FCF1E9A49CD1
+AEC862DC3EF8A5893230747E6339085E8C7F4F0B669CE08B5EF9393B5ACCF9D8
+54D58B0D5C8C45041076D6B51E62DD840FAC37144B11245C1EB10010C9AC80F7
+F2588F918D3DEB35E08B0C04496840F739515760B07D4285621721084E12F716
+6307A01333DEE9BC4B9F4AA9F1AB8B3088E7844CF2A4FA1F1C33B7A2C057CF32
+DD3414F0F1D620F4F85E67A1B8120E9E63C389EC17DF4022A1E2E7D2C4F3DCC0
+572286CC2A75B5FB70D7CDBF32A180F0FAD9A338799B4CF03B62E2030ECD11B4
+44378365FACC772B7785A1ECF3F17590777F3F76F189D1B9C57181FE5FA3C9EF
+33F4C60709D6E0F2AC613CB3DE485877AD003EABA727C552679E983695E9B5E2
+6EBFD4A43DCF2AE24001FAF0F05899E380178EE1B0AEF69202A3D41CA5675F6F
+A738540523145710F8932A8EFA407259E05DF7C640EF817300864F38264A8CA4
+14A79D2C66640F9E852B8782E43E90D150F0C80DA7B0FCBF5577BED4ED71F3CC
+5C963DFB6CD49461C17593E3B9440B7E4D4279B2096AF024EF759C47DB30E51A
+76F0DD543FA66742EFBAAF78A50EE109DD0864FCD953C3469AD6EFB933304494
+91775A44562A8702C99913C5549C622EC57DFA62281CEF1F60EA1FABD26FCCEA
+6FFFF6F27E7D6576A241EEFCBB3ED8716340E286EF152CE4488D17AFDDD0DEC6
+EB05F3C9674F22CF2FA110F53AC4E33B28F0A41ED0DD549563988434AB9F6F12
+900F498466FAE983623AB034816C64C3C1B3A764F3DFD1E475D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX10
+%!PS-AdobeFont-1.1: CMBX10 1.00B
+%%CreationDate: 1992 Feb 19 19:54:06
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.00B) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 12 /fi put
+dup 44 /comma put
+dup 45 /hyphen put
+dup 65 /A put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 70 /F put
+dup 71 /G put
+dup 72 /H put
+dup 73 /I put
+dup 75 /K put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 81 /Q put
+dup 82 /R put
+dup 83 /S put
+dup 84 /T put
+dup 86 /V put
+dup 89 /Y put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 113 /q put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 120 /x put
+dup 121 /y put
+readonly def
+/FontBBox{-301 -250 1164 946}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F00F963068B8B731A88D7740B0DDAED1B3F82
+7DB9DFB4372D3935C286E39EE7AC9FB6A9B5CE4D2FAE1BC0E55AE02BFC464378
+77B9F65C23E3BAB41EFAE344DDC9AB1B3CCBC0618290D83DC756F9D5BEFECB18
+2DB0E39997F264D408BD076F65A50E7E94C9C88D849AB2E92005CFA316ACCD91
+FF524AAD7262B10351C50EBAD08FB4CD55D2E369F6E836C82C591606E1E5C73F
+DE3FA3CAD272C67C6CBF43B66FE4B8677DAFEEA19288428D07FEB1F4001BAA68
+7AAD6DDBE432714E799CFA49D8A1A128F32E8B280524BC8041F1E64ECE4053C4
+9F0AEC699A75B827002E9F95826DB3F643338F858011008E338A899020962176
+CF66A62E3AEF046D91C88C87DEB03CE6CCDF4FB651990F0E86D17409F121773D
+6877DF0085DFB269A3C07AA6660419BD0F0EF3C53DA2318BA1860AB34E28BAC6
+E82DDB1C43E5203AC9DF9277098F2E42C0F7BD03C6D90B629DE97730245B8E8E
+8903B9225098079C55A37E4E59AE2A9E36B6349FA2C09BB1F5F4433E4EEFC75E
+3F9830EB085E7E6FBE2666AC5A398C2DF228062ACF9FCA5656390A15837C4A99
+EC3740D873CFEF2E248B44CA134693A782594DD0692B4DBF1F16C4CDECA692C4
+0E44FDBEF704101118BC53575BF22731E7F7717934AD715AC33B5D3679B784C9
+4046E6CD3C0AD80ED1F65626B14E33CFDA6EB2825DC444FA6209615BC08173FF
+1805BDFCCA4B11F50D6BD483FD8639F9E8D0245B463D65A0F12C26C8A8EE2910
+757696C3F13144D8EA5649816AAD61A949C3A723ABB585990593F20A35CD6B7E
+0FA0AD8551CEE41F61924DC36A464A10A1B14C33FAFB04862E30C66C1BC55665
+6D07D93B8C0D596E109EE2B1AAB479F7FAA35279ADB468A624BE26D527BFF5ED
+E067598E1B8B78188FA4BCFB0B51692D07B0BEBB930C6F0997B437E2C51B876B
+61A563A2673932C2045833FAA35DB22ADE12102335D5DC734AE3AC5EEE6658D7
+92EB62131E1DFBA441F53EFF9021D9D4C491F26BE8F54C61165CAD778CE8695C
+EEAF70E3B20C64D4C2B34A084B5770BAB2A974E898F62BFE90F132A37E2DCA4F
+43E13DB13C94DFA8ECE2B7374827AE168634FA007F8981ADA046CED3448BF453
+FCD9A4F194FA648F9FC0971734BB69CB75348A88CC361FF06E984C86AF0EA429
+DAA5808CCE3583664AEFE0C59EDA04A147FB51227A5AB0C13942323E9B3733DD
+3EE7DF7F774DE5D0D0980DA8C0192983F1E3EF18481EAF1EFEDA0068BCBDB28A
+7FC7D9191EFFC574588DEC1E180341DC959F8EF56ED5B19F50AA82A4653649B7
+CDCA11A1FF27AFA7FF189A7E8A7C099AEEE0CAF3E121798B2721ABE8808D20A4
+AB6E704C0C376BD242C4966325D4C939669E28B55BC335405C400A9983B89EBB
+B13D8C5F3A148E38E9ABD86D0171C927F1051266CBBD5C5D12522AF7CC17918F
+410BABDD5FDD279338E8B17434DBF20B8E06B58D9E13B731E3C07E4CC350C431
+CE2034CB23828A19AE93124011BF053A3C5705D9BEF6D95205FB8360391C84B3
+7C6D719C0FB459A312AAC3C4256EAB293B6DC729CC5070524D1BDA41091E8B42
+2B6C4A092995AFB40CCF35730350CBA197F3D5BC5BB83CEDDBC6FBDE23A885CE
+61D416B3A6CEC46474A0F42D5B923A61832262F234001DBCED9A7A00F5511F3D
+C2178422A46CA5494AA8C37F51C40339CF9392A7098DF8596EA97C440989CA06
+EEEB5025B29EBF6038EFDDFD6F70989D63440E9C14E2A1040FAF427EB41259E3
+FF3BA255BD4C04BAAC47326181EC7CA1FFB32CBCAB92B1F8CDE6ED0DD3FE6D5F
+EE14B739FC25BB13CD94A0C0DD7CEDD886AAC62248C64B8439064D1038886DB3
+187F017A79318B69963296B4812128EACEFBAAE983646E021F24BDAA2B78E8FE
+2BCD5BFB302103D7DD28668DA7A60C446A27BFF8D6C66F4FBC61D271B91F0470
+16F567DABCD1E8B04CFBEF602BD9CE44B724B3EB8D30CE573EBB13BAA047F947
+90B24F2E49C20E2474EE9D019565E6FF25BDB3F74DF05BB9E148E1C5883A9EA1
+53AD3833A612643316CB420AF3DB29F008BA36A2EF00D25D9AA606862E0B96B4
+A1AA4BAAFF8999589849411F07E2D77946CBCB5FDBD2B0B19717997CBFD658D7
+04F62F79ED661F4D7DC87B9D27F976C7A2CCE456408703083D0044AC4063789B
+6A407EA9CBED9C091E4FB511833EAF520213B0378623279402EA99B58929D292
+143E0E986592AE731097872378122A70DED836C1AB5C759F84FE2E907BE8897A
+940785D5F56F46DE7BDDFE353A61B5B3BC8322A8310695AA9041C143EE88739F
+A6B7BB4B70EDE1BE28560F21D2A2B0A703C1B91418870B50D5C08E42C27909F4
+17CCD15D47E5F771AFC8DB660F80CFFAFA1DD19C350756444E719A0CED5EB0FC
+05B94A27F784D3F01FEBE6724039B24F3460719C5D82315EC7E7E3BD6E611C9D
+B28C9EBC83E3C89F2857F9AAB35FA5C7243F7545208092C342058A27FDF8EA66
+CFFDF8C918EC50DFD4F331732B523A288EDCBD1B2FD4961C88F9614CE987E3A3
+4EFFFC34CBBD2A96F80AD69E6598B48C84077E511939CD280206F90367E1EFB1
+523D20A15FA835C8D8FEBDE17B75F49CD0D67A4C071E7B63C5B3878BA7B6ABB0
+D17B6322FCA7C5F979EF3FC60D9F07524EF72E2D102C0BB93A7BE8CFD40D6E6E
+FAACDC3A118D4D7B112160CF5E4E9BEF9078C087CDC8A386F02C07DFC9975CAB
+75F500A0B836EC037A2A5ECD803BF9661299F4ED191C54633E4D466C2976665C
+7E360AAFA1B86583AEE708AFD51B0D73EBE32BA7C3629CEC58A1184D9794DF1E
+BB126D4D55A033A94582BC5F28A1C89097F95A50D77156A7829C6510F6E81AE2
+8B4A6F14F125929A094EC3F819BB6574F6139BEF625EC2642E42C7E6DA9B0104
+DA93D16659225E7A111A764AA3B86570F71E2ED26D55742557E8416AD7DD7863
+B8D1190EC70E8BB3561656061410EF42E4EBF7C8478C786B6A6BCB8E1CECCB6C
+9A77992E2D6896D1BFEFB93312B987F44E64C010F3F43BDD110A6DF973A32DEC
+8E49BA72D75A266493B2AB3A42A307179011D0307E727633793607716C751FEB
+0784596E0989AEE8BBFE586F7B4AC15A5D2016A3F12F8A10EA8E08F524FD25C2
+C7195F111E6BA5588C15059B17A967A6BE2DADCA51D9455DAA7671AC195401F2
+A8F9EEC851502E4B6EBAC7F4102F6ECEE8F876D3D591926EC7E46B19F950993E
+5F275D12C48C50ECAD497517919BF85E3D196546E4D1A416752283A0C986A4A0
+09DD4995D66B1D8C59EECBD736E514809BC3D34AF7749B11736FB88AA89AA39D
+5F964E12DB4DBCD25CC750B2821BCDD4E012C1900D64F3D1E4D8CD0850660BE5
+CCD101D79FEF25B3181F18B0421F90EE1D7E5CD5E4735974BA5A6943BA7583DE
+8CD4C21B230CE9D98DDE7992AE64E99EA041B8138A01053C2574F9B0C50F0E45
+01189C276F3264B6DEB4105775430A7A4D8C0550AAB0DEF33FAE4C4BC637A21B
+71712CF7EDC45CAEF1CDE6D08D7E615BC47919806D84CFA35F886EEC4C8404C1
+104DDA98A2E1E17B8692FA5F5CE7ADAD126A4629C26F30A22F3A76A512056560
+65FAEAF40D2A3797066795FDA6895F5349C3D660294FC85D0522618BFDE6BDCF
+8D4E5C32AE9CA1E52BD3EBE6948DF98F43AA8DDDEC63B1061B2F8C8BBD8B8C7B
+0DF1E941CEEE366A0C7D1976E59DD67ED5346F90B6EF07FE1A0EE6967E1507E6
+510E7C9051849D50F0A7E9F4FFABB2B995EBF4DF570645FF6636DB9BA2FAF466
+DEF21ADC735BEC2AF45E4113D1A89F0CC116E198B5709BA71FAE4862864EC28F
+3D86DB74FC4CB0BBBD0376F1AB6CE3E07DE6C2979F8029CF13DAAC74A0F04BFE
+3A40D748D63CE5B5914C0881915C5B8B060C79D1B9B6A7C146057196D855B5EF
+02C0E38B0EAF41EAE4D23C4905C1498723970B2C23EB775FC79E9A0E0C1643D6
+2EBC128E05D3EC7D9761CD58C39D4E722183F52F1C526B303EF2786D14904D26
+BA90A9166980368873999F208FD0A768D0E3B934A1D3DE4A097B5E5DC7869FC0
+9334DD1304CF2DA83FF18C136EBAFBC50ACC540D8DD7C321536934DA89A5C666
+8FED4A1D82DD9EC0681A19DCECF5C4D606B1D6BDA9459392C1BD6348B90B912C
+CE7262705F4300D20B5BFA5A6CDCC843094BE16D9451F722CA8071F40D2CF4DE
+F47044201547ABF54538665F627671EE3379AE20493A5982F3DEDE997B7801EC
+6E07A873DB5BDB95C82844A6BA927B02B63069930B590A2E62EB7BD5A02E8738
+61D0232A38749A52DEE13C8A2317430FC649FDB47AD5006E43A01E87D1A313F1
+189F3B463D86A5A6002D4B0FC9EFA9773D01EE89BBF9D559D212440892C53ECF
+5A768BF87F6E26E9A9B8B4A57A7B29312D9A48B085CB6D60FB388B149B1075BF
+18EBABC575A5A2A993FBEE137FC0DAB27C0B34927C9D7A4D5F491F68B084068B
+A3A10F884809CD1F38F6EB69B020F4FD54DF69F5E3D5F13D5713C75B01A45A4B
+291A5B62641B42474A3D7EC798EA07CE27DC61D7E7F8BF0A0C1E10314A3457FF
+E11F9A1423BEAFE227CF8092D429E0F14909D74EA31AB4292D739D6CA7663056
+E4E95803A994534FC8A6F7F3AF00B60D65E3262C1FB3307CB237E0E092225DA1
+25A69354D72B51E55631E1F0568CFA0F0778AD7DF71A4001B432292391987892
+997DB3691A20C0809253282200E03F02D11E486B7D93775C34DC251E5E3DBA71
+CEEBDC0CE4DF094CE610BB96CAC47541C871A6FBC09693B4175465239F109E2A
+EA0AB6A5393C1F99E75531880C40D6669579DC8834B2D321416D2EDA99060794
+F82BB7BF27F494F5BF149921D2544C7187628AE353B5AE33FBCC8581FED745B5
+16293342D9D80E9736C76A7A7A8C16368240144D402A089CF4BDF4129054FE6D
+F04728A3D9C7C1368FFF22658C5F76C2571F59FD7EA643D107349B916C9B6D23
+3C42D236FA3DC633C62F7D0662F0AF0377A5AAD963F4BAEEFF25770B646962BD
+E669DA4CC6E7E05441FF73E1E50B31A89AAE2D62AA1B1947E42F0B5356B689E8
+2434DC9234A42CCC9CB68F0F906ADC01C67A79C1A645D8CF74C261707C33EE2D
+09314A6FEF969D88415575F1544898822BC381D2A7A81EEB6CF5320161F5F372
+F071B2EDE7A30CD6D3FA76E95A31DDB7737481B1F092F14904FEA7D3754E9E1F
+B4EB8AA8735BA8062D2364A40A54BA4C78C8275C0C7429DDCD5E045A6A1A3EC9
+CD51B2DCD90EC791B08E2550C5071B586A14519B178D2340F4694476CDC4C604
+DE48A1D557F99483088E602BDA970DDC07E238C17065420100E5DA30B07EBEC7
+4D46FC4E1A4A8E9206553E927C63CF99AD7C318CABCE03B6D7EEBEEA1FDBBCAA
+8ACEB7BF96EF6268E82934D32CD3A9BCCA08EA7FFB3CC320BB5FAF6B2F7202EF
+32493724223CCC1A8A0D76808DC97E89ED72F5E45C64E63DCE06603C918B4564
+8E942314A50DA37504CA704039BB9FBA4F79A78E48F65238FD7D924D9423C9CC
+A63EB75ED3E127E9C62103582A507A2837F54824FF922A19498527F46448394B
+8F9D09A132F260F484E88BB56543AAC18F07AF27A276210A2B1C84F1C5DEB002
+8BF3652C6D6C32949191594F63C166AAF66F7F26CCCBCAA659115AC8F977D8C3
+8E5A6FC1C7C27D3C52CDEA11D7EA3F0217AE402965732CE4EC4E5C8CF2E4EE59
+3F9DE39269BEDDAB9DBC642CBFA3A49CD0448E439B63EEB766B8113B5061990E
+161128940AE10E435DD0B7A539E77B5B4971AAF5278D41853A196A779ED62E38
+6106055CF481A00B8DE50D1A4A93A0D08DF38A3261E62C4037C57D75302D924A
+EC5336E2AE088711E103044A9A35EA1F861802A731C57D5C04C9E79DF246CFA7
+9D1B79F193A3D103FD179ACF217742232E88B465D9E8EA746D6D7B1D005C590B
+2BE4C2E8FDBE3FEE3A9476A8AEDF122D73D4B2AA3E58A41F41DB37DE4583E851
+BD8F86F9CDE513F58A9001B5DCF01F22260FB1758BC51F317ECFF3993C576BD6
+329932B44B8C5C4B5AA0145AEF3ABE845BF461B34D65096ACCF7209892EC7CEB
+489C44BC2F5B7C23F6382FDA0ABE68E8B112BAFBBB55B51B957F7B90032D17B3
+5336A76E3FE324A1E3358936E98CCEAB0E6516CA8D060A669A35A06FF466B0B5
+E528EED39667893D9AE0D353F05EE3041FEBB4F38AD7A8EA17B76F209B4D92F7
+FB0EF74DF97F2C5F4813E72EB63A2BBCECD65550AF85693F7FDDF9B5EC16287B
+4570F0775753530B047DD04671BA910FB447F686CE7F999A0766C95A6DE9FF4A
+1E9EF0CC43D14CDB46BECC3FC6548D95A978DB644857853F3340862227DD2354
+5072CF0D7050E5431E1DFD2FA15BAAC284151488D0ABA88BD718551FD7D36F71
+1507667CAED6ADC861E442CF645AE3CBBC789E949DDAF39437A6352766DA4430
+764839822DA891EEE1D83F732DBE943A2F03A61480ACC77660DF405608B0450B
+CDE772D1BEA4D2912F39C29AA78D8EE35B7402711281BEEC6430116AB3551843
+F4654829B04540AC9ED8B20A34F7BA5D11B0ECA89BAF6134A4E0FAC945F6DD6D
+3561C4A3B1431AAEF64C12ECF0A51ADA579BD082AAD93781FBF55B56855A2868
+B0839CDE7F033B6A7E68CF374A175DAB6E017C241CB9A52CAD316903D93AC6BF
+C9A5206D972E405BEBE2FB1E0CACAE44B1DBF8B704DF80B0557E1CEDB9C5A00D
+358A1E232E8AA9A15A6E5E0CDC3F13A2689B157688579F88EEC3F0F9795577E5
+7AF18B0A6B3F810BCA3232CC7C6E7C13F724589F0A0469FF8A5DFAB7375317AC
+E6C074327424FBBDFBA1D75187BCA424932465D7AEED4EB29FE30B2B14832110
+DB02648E509BE11BAF600D9B0DF493B5E00ABEB977D8C6D37E4B614EB385A11A
+AB12D8B0280ADF9EBA79B10F7D0F042698D353617680B066B9BD8DE170D2BBA9
+7AB9EE51F18180AD84E95C168DA3AB07DF7D548815647B6DF9853A5DE14D68CA
+FF85B18233634B6234EF540C368A32ADEC2E734E87E7718289AB66745763EC58
+0D5D0C6A9B5096633A84CCE8AFA9737BCFADD9027F32576CD7B74123D6159077
+5A9AAFB82B6975FCD8DC92244F7AA5CD5F9A5ADF9898EC10549B7B01C585C5A9
+E1A00EAAD335267D628E8845BC62DBE5D2199D96DEA73A03626B7A245C61B55E
+1E7A037B7244C62F68914118CE521BAD8B3A73136883E98514CB6538F1A33AAC
+6390F6D2DE3AEEA9CC566A7CD3F5A0152990B390BA314452128FB2AF0AB4BC14
+7CC61DC0D2ED5C91A07631AEA7172B2E0E4C377BE1C529CDB813AE72F73A285E
+A608E889E0BA048909CF36D852456A83D1136EF1AC4806ED8FAE3A40BCCBA286
+2B73C68082E7FA5606046A22CFD608EDBBD7F442967F88F4EDF7D61A48CBCD73
+EF8084307DFECB1B834FC03C613A3564D2E47D6AAB54528402AB6156F76E9698
+31ED512E4C6709550849507FF36D37ECA05AE5F0F4C64DD3EE576BBBE4079503
+189BFE7F5C01830D285AA4183CF942DF08EE8290A3C4C9E8D393F551F51037CB
+0D87FF5AE177F1A67AD1EAC96116C2C4B8436FA9DD3BDF8F340AF4FB9CF9A7A1
+640C820A354D1401B848D3089EFF37048C4D928A474ED10EE0B6C60C7B885515
+0CB1A25BCF66594ED4026C446DE1BA2D561BD253B907B324C79C1FF19C209F5B
+9985621CE7596916F23214F74C55BBCAC93ABFFFF13DAB33B116B410F3B6EF3A
+9C1A4F44C2BC3A96A6FA3F477D1F399F1E04A5EC2F3F3256487FAA61951EF6E8
+51E2F89E9B4372155FDCC61F225BCD7E8839B4BF4DC26774827377C29882B782
+F15D63DF628FC02546B67A52EDE501D8966AD00B7B85E2405F5E8D7F151A8367
+A0A501FCF6E98078AA95E1F2A39E507475C10BC23247907B40B471B3FC5DED87
+577F23FA2C652CEA09E5CE3805A450D4524AE26B59C7401DD474A01961FBA3EF
+F833B3198AB10E4EDB9EB59241A9E26C29882989B3FCC261C89D898B5EB4D4D3
+C09F11FD7AB94449AE249C3842D4A1853B4D8D29EAA9CB7ED649619B8813BF43
+6B9C46163B166FB6689004022D143E7FD9803FA05C6848EF3B61A40DE7A93BCA
+B01DDED4796355BBB69CCEE2746BA1613A682769435FE26D0D8279CFF49149A3
+78DC2608BE4AFAA792101CD0FD8CE284FC1835F964578317E3358183B07FB5F6
+9625D0E8F7BC7BA99828A981B0771C44A1FE910F204C63E8437B364EC4CAC62C
+B54BA2AECF30DEB60C80C6D7CB45C00C7045974C5166DF72EE414A18B77ACD14
+6F5F7E12F51435F3F5D6280F61F8C027C8BDF7BD338FD84C84ED84B47CEF6EDA
+78941D5623506F1BAEF02E092399D9288C13B7FD7C98BFD4B398FA6EA76CDAA0
+8FAA6EC2E4B9FAFCE1CFFFC883563A11AB7EE141BBA45A372E62CFE64AD60E2E
+856E93AB0507153D4FE8C80060C8572FBB64EFD044E8908FA7AE5152FC5A2A54
+0DC576D679829AAB5D60AACB61E5E81F5395D27C4C43CB4B2A847755B072E916
+A42B33851E6510CBF1627B0AF8FA67DD94563E3DA1D8226FD25B61EB926AB12E
+F736BD697ADEE50CC44A5F71470770E76AE89846769927259907DCC3E128C982
+9557153F1C19AF0DC5A0FA8BE3672866154D9D1F026F0C60508C8EFDC2135107
+6676FBE69C17DA13E273946F80DAB620F8332D680AD46537099B457CBCC08B77
+66D75D1EAA0EAB9E8EEE429B8D6805A7B304B3C4557AB4C9F5F99A5F2B559A7C
+185D2469063529F1C6788D79D497D6055FDEC230751C1C5A8C1911B7409E4ACA
+D8A13431C2AFAF44D8485C59C4F3ECD11DEDFF969B614CB0ECDF8B0622A10982
+F36B66CAF38A0D064D0EB9147986DD43E8E022CEF1681A914712BE66DB2DDD22
+565F852F6CEAD759EFA0475DFB3054B12D58A052E949992680F0E22EC393B553
+D5DF16E684B928CCB2A3E5F1F41DB906CF8125936C070308DCCB60A2C7CF0C99
+D1D3B880DED82E7E32A889017150124EFC88BE3181208FB6228CAA3919F69D80
+AAADEFB2421887027F822A13C4D2E108B7DDE620A6F56D7E7E2C32AE2FBD9B9D
+1C80B62B1B86D03E84B64A95542555A04516953F1828B16E6E8C3CCBD9319F8D
+55001CD1E82406900C25E73C0EC3859F450C08FBBE7428BCF7629DBAD5BAD9A3
+75B72AAC95318F861AFB52BC3831421AF8F9797C8F38267E90C976768CD10497
+13B77F14285C32DA23B4F97C24E8C0D9CC645BC093E3FD237EAEE0F55BA1FB8F
+37014723DEA2583E071E61E88C1105381431D5D29A9980A79ED7447BE0C2B836
+8105177C8217C3EE6DB289AFEC6C7046F10FBA62AB2C6B7D1D1A1FFCFB940A8F
+4DB600E9731E6050C2FB6A186F9315201A83AEF9AAC719C283775F653915FC86
+40DC2A205062E7F490495AD6C3F135041E9DE1B3B6154172BF9E647F87F5083C
+91156A75DA0A57FA4930B646B3703A2790BFF7CF49283C2CEBB39BB63BB39D8A
+61166F64713DBE3D05CD303BAA34A686A9EEA6FB10E2B6B0B08795A86A3BDB95
+09E6F08F32D27B97C23F3386B4B7940997CDCE0991430DD00CC8124CDFC3E0DE
+66495BB405CDDA47AAEB46A0A5C857D3B867FB3D847A3020E37427C2B403578B
+D30F90BDAD46FB913C057637D5FAEA06B2760766870CDD99386561C70BC21668
+03873AC26EBA0D1ED46C1AD9AEEF1B9123970C60E7770A97325B94F6F572C992
+5831BB0253DB542DDE3D9546BF991150600758E3E5A1D4BA40BEB56B709E6C80
+295CA4E20B46C57E6F414EF03971C13661229844453A960007B754BB84678039
+211803A4880DBAB6AE1B6B76263D26EEEA8845F53EA92EA6E904F0725F96F34E
+CE6D64196E360353510DAFD4AE9763B3686AEF2AF2A0B098A7056A663D52D881
+D03073E80FFCF47895C4270009770460A9719AFDB8BF59D5A12E24502D12E507
+96864083B754E889114BE8FC15D9F6867DDB8EAE5EB7AE173020A148AD4DB668
+C400D091EAA6EA5D4A660DB78BF7BCFD7339EF9F7E34F5029E39BD3C3C610E15
+4EE1181388B4FC544C28040BB416AD1FDB1FD7703E478063AF918437D96357BA
+F1EB24122599018A6C8AD37E4A902FA3D3041E3D7F3A2F4BB7E7BBB9AFCC0906
+5873A31DFEC3D437835CA0479B20DC4FEC2E283EAC4754E13985C043EDCAED97
+25D9E51ED27EB8CA29B1E8C51493BE08AF34C2E4406362E5EDDECF85F06DF945
+F074D6EA7A5B606DD3D7D6E81C96DB690749D54633F471FDD2EE9A1F754AB6E4
+B4DF7604C3DE0840BA1F58CBE0FB20DF2C33D975894AF9EAE6C63461DF29072E
+AD4CFE0E97F57E2B457C32293178519CF9FEA669D63EDDE08DC55581060333DD
+5196DE5EC144364557537E0E869D02A9CCF35D930579E21ACE434567DAADE92A
+503EE8DEFA0C4C0F7D2115B8D803C8746F24A1CD0ECF6F8EB5A9DF8F3E601A90
+42165D15B55B9C53C622892E7D6C26E67CD91AE0114F5979563969FDA33A687B
+C3825AA15A79091642DCE0A132FAAECCF9590243E87956330F09A776175A3C2F
+C651E89A73A9E1EF387AE9FD68BA48660E0B8E80B2E84990586DE7FEBBE6481B
+E79DF22E50AA118CC07AAF6D53C5B612561532E7B9486CD0E2428D871A7CA4BD
+6C797A665DC72C3D925DB2208586EB735127920CD5523DC59501E62D0516AB34
+B48A12891881C5511B4781DD8532F998C7CE305DC9E7C879F3C59404F21EC643
+9446AF52094211E37631D6FDDD3F010755EBB0D4318B237C7B8E5B892A1CE8B8
+3DA402E41FA2DCBD21543B9EBC7311DEC1559C0D4B477B31C9AC27329869550B
+5AD5F31E98FBCD6294C0067C9D7BF7FCA97F03810025F64C08C858A58DCBAEF4
+23CEA7081D2E35F13E8E2F94CCDD325DD9844BB6AF8CB7D8B8EB82AD4D7C42CC
+38265F74CC3DE12C249822038FE84EEC468F77A333369136768D4A0260D18E8D
+AC6E55C8752B4EAF17E74BC6C10DF86383B6CECC66AD367C8A485F9333AE060C
+0A4FC60DCF85AAC2DF16BE84E8472DC07CD4B8FC0F8B860BB9864925EEF83DED
+B4495813D0ADF6E0D98FD8AB87C65E681CE71B4782BED1B525B595A59C5273E3
+B5AD7CAF306E6E0CF7CACBDF910ABF94DD6AFC4F0CBB729F0445FCB834D63BE7
+51D90E072E9CA8CE0893DEBE52E0A53DE4F3F447C58DE0D13477ACCDC7AB64B4
+E548633227CDBCD82E4C010070E2A10DCBB2BFC5FB90C0782971D509B3864A28
+A06B0DF9044F356D728DAE6831488B8A0C15E366CAC6B390CBD68E5424C6F5B5
+E1F76E015E7F1C2A97FF0914EAB3ED733F72659DACF61E63069205706F50E0AE
+AB9C5FAFC8E05C87FEA2E668F3B38AE5EF85878404BE1CC1EBAE25CE6489D033
+095DE9BD116A56FFA093412EE92D4327CC3B45445CC0410DAFF51EFCC032A24C
+B8297A2EEEA06D2C27F73E051F0CA4BE02E3C53018AD869BE707BD114C3020AA
+F3BC48D08B2786EEC91E9C018371D164A1B5872A5D7251468A60BB81B75A04A0
+BABCAF0B71A0AB3148FD9CB93978AC25055946048D3625364E9875F8C05523BA
+BBF68378FF985BBFC0252191790FB0ACC846D0B7396B914564EDA49586F3CD3E
+6A187DDADBA664E76B4EDEB2AA8D47EF717233F7428884E8BDBB7BF207840622
+AEB0CE00A2F046B8AF798FD593BEDD862D00111B84B2A657A30F68DDF92F9E98
+B40D99CEF5DA140C1D3DD28AF14C94DA3FB2BE4121977A4EF2CECE55A6D8ED38
+5F1E5A43A64AEC55F4D5A0256453F0559DA22A5AF1C9DEA56B7B1592F650EEA3
+8FECB0AC1CC54BB64A36DFA34484765A74A2D6619C849E84697001BA85A31550
+030807484E3F2DDFB9299D4BFA52BA93EE7FF8F788CBDA374C9156466124E492
+C80D94D5A377A270A6BAE28E2872599223080BC9F665BAD78D8A46A67F466158
+F943C31CBFB7B294DD0204CB0E1AD04B9487AC550C4F8815AF19A2EAC52AF5CD
+640F65E4F9F22C49A56B581C06A03CE7B68FB398FFF7332E74FEF5F6533CF525
+73727249D1888FAD0383C523F6508F5ED8EB9449F2D5AA99A04B093CBB38FC43
+CA3FDBF847738F0D40F5D57A9121AC7238788D0E96E09433E9F8DF0287C970E8
+E832A9C206B332E15443A2D23FA5FD2BE4370A0FA7AF8DDB606F6736725CFEC8
+31BF024FF9DADB6BEF610A2034490BBC95B4CC6604D9A39870540652DE6F99DD
+E703113756F1DF3A6554718866254051CD8C310D8E96952868044E945A29914C
+1EDA47B12301DA809618412BC1A7A6CD7668778F7732C223304F88477AF1F9BC
+071707D9B2131A966BED3D5F06E083B295DB919277D6A336FE689BDDD3C221B2
+37682D2998B5DFF0123E87596A85DBA412B542620426CBDEDBAA5393AADAA221
+42167CEA7B60888D9D7AD22424A60A5E54E7414C8B591F4C238A4CB278D2B7BB
+D2425638F23BA2EF8F1D87E2AEC76418B7E6F2427BAA92EB0D998F07477312B9
+E67394C2861036328B40EE689E3AFC556424FCAFA263D7DB40814A8BC9D160EB
+DC3F62DD78089BC292A78EACDA0BFB3246B065E670038148243E331D53B318D5
+4AE78A620D3CB22DCB80AA7368718902B72DF0771F6DAC80E7D605CD10BFF85D
+E26CB4E653AAD36AB162FC2424FC3353D3E57B07A509B1287C3399F56163ECEA
+2CA1AC11BE9361476FBB65C99EA7BF1DAA607ADF5A3D5113F230567819848912
+B427D8183AB4D4A28760DE738CE192DCFBFDB421AAF2AB14F6E3E83A602EC907
+BC8B4FE0EF9FB6C4163537B6B6A9E2248E4A9D491E5831D0121C1DB6243F55C6
+081295E06D6FD01C107CA8E2AD4FCB77CAF127240A3B0FE67F8BE310037089D0
+7F92005B068F1ACBC76355347C5EC6E370D773D6FADC16C74F31300A0F4974B8
+7340C89DEAE5DE97474F2281FBCC9EE2092D75AF7E9332BA71363750BE083427
+EC22AB844AFB76A8DD7E521D932E9AAD7D73909E8C67B427E64D4AB7F07F117D
+099272F97DD809791E1A1B3C098AE75E00BA58613409365823D0D9E541290439
+1AA98D4CDA14DF3D931554ABFA51D4EAEB13D0761842C243F6F9998F83105790
+7F160341B392045FB7730BB21F0029E2B1E2804373E35E65DF45A0B3BCB2B038
+D9C5B5324A031E0019B003488A314F0DB4F83C6FF82CDF84B3F1DFEC10D471A8
+D2668EDBB9DCF3D7DC4334B2799652D16F49F67164FF668B1094E1AE0CA5BC61
+110C9FE775954D1DC36848F9135C0EF8B99B17D75D929CE94FDC285611299029
+7722B0C3938094A49DA4DF04082DA0B0E944
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMR6
+%!PS-AdobeFont-1.1: CMR6 1.0
+%%CreationDate: 1991 Aug 20 16:39:02
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMR6) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMR6 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 44 /comma put
+dup 46 /period put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 54 /six put
+dup 55 /seven put
+dup 57 /nine put
+dup 59 /semicolon put
+dup 64 /at put
+dup 66 /B put
+dup 67 /C put
+dup 68 /D put
+dup 69 /E put
+dup 71 /G put
+dup 74 /J put
+dup 76 /L put
+dup 77 /M put
+dup 78 /N put
+dup 79 /O put
+dup 80 /P put
+dup 82 /R put
+dup 84 /T put
+dup 85 /U put
+dup 86 /V put
+dup 87 /W put
+dup 88 /X put
+dup 97 /a put
+dup 98 /b put
+dup 99 /c put
+dup 100 /d put
+dup 101 /e put
+dup 102 /f put
+dup 103 /g put
+dup 104 /h put
+dup 105 /i put
+dup 106 /j put
+dup 107 /k put
+dup 108 /l put
+dup 109 /m put
+dup 110 /n put
+dup 111 /o put
+dup 112 /p put
+dup 114 /r put
+dup 115 /s put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+dup 119 /w put
+dup 121 /y put
+readonly def
+/FontBBox{-20 -250 1193 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C
+68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361
+3645B82392D5CAE11A7CB49D7E2E82DCD485CBA17D1AFFF95F4224CF7ECEE45C
+BFB7C8C77C22A01C345078D28D3ECBF804CDC2FE5025FA0D05CCC5EFC0C4F87E
+CBED13DDDF8F34E404F471C6DD2E43331D73E89BBC71E7BF889F6293793FEF5A
+C9DD3792F032E37A364C70914843F7AA314413D022AE3238730B420A7E9D0CF5
+D0E24F501451F9CDECE10AF7E14FF15C4F12F3FCA47DD9CD3C7AEA8D1551017D
+23131C09ED104C052054520268A4FA3C6338BA6CF14C3DE3BAF2EA35296EE3D8
+D6496277E11DFF6076FE64C8A8C3419FA774473D63223FFA41CBAE609C3D976B
+93DFB4079ADC7C4EF07303F93808DDA9F651F61BCCF79555059A44CBAF84A711
+6D98083CEF58230D54AD486C74C4A257FC703ACF918219D0A597A5F680B606E4
+EF94ADF8BF91A5096A806DB64EC96636A98397D22A74932EB7346A9C4B5EE953
+CB3C80AA634BFC28AA938C704BDA8DC4D13551CCFE2B2784BE8BF54502EBA9AF
+D49B79237B9C56310550BC30E9108BB06EAC755D6AA4E688EFE2A0AAB17F20FE
+00CD0BFF1B9CB6BDA0FA3A29A3117388B6686657A150CE6421FD5D420F4F7FB5
+B0DAA1BA19D638676E9CF159AC7325EF17B9F74E082BEF75E07BB563C96C0A3E
+6D4DF600BB73729BC4A5B134928F1370B9F07C587F79388B1D9AC62BFB1566DD
+CCBD1F58ABBF1F53AD21E3BFF25EEEB046F66A924E5F431EBD7228050BE2DF43
+0B9B538DAAD511EED97630CD9A9C05CC49DC251325A93EA842C6D07B44BE620F
+08E66B611F54314B0177E299304F2294F8DEDE9914736944F125A50B5007373E
+588AD80D9983CE7824DA30CEE5DC3114D69D7ACEC0758D8201805B82925EF216
+BD209C5FF436AD3D4BAC20D6F214D9F89CCA7D963A27C231A6B5D4CB1613AB6B
+2B9A74603C2C27CDE0482B706838C3C968D63B077CB589B6AACD734CC4C5873D
+D0821F16BB4572B85A0B669B65DA6E4B7BCBF3016ADFE80C0FE131DF9E55680A
+7762E47233779AE4F61F0CCD20E3747C1B023C4CF08F04194AF4B6674B208B26
+FEF84CDA523C3C2539A82CA8C4248CFAD0B65D64C40D2A505A9A14DFBEA1B1ED
+F63CB30577AFBE901B77B11041D98FF728DE220FC017F07BBFCC6EFB63634626
+67A03FF6E946F4EE0483C34BC782C6F94E0CB7C4096AE8996135DD720EEE24A2
+DCB1284C445D012018E6960BFF60D78392A6BD909F1F6D849C989F6DDEE426B8
+6C1177103EABF2D3CF3ADBFBE2F8BC630C9AD3B101FED93600C4B88C5F105D85
+A544D61185B178BAACF327A94FED7F86A836C268266113E8D9B26B5E2F3A97D9
+CDC32259261BC4FFC26E7F113672168A46B7542EBA62D0C524263EB27A117EAC
+DAF3141E2D1D963552F3E54D973DF1F559C16A5C2E75D971B5E8D1525C269013
+9DE947965A70E81C4B7952BC9B8A62AEC594721B6E10CC96C106183F8113EE20
+09B8B1D0FDBF4E9385F33C183F23DF88379141920BE2BE049F2EE0FF83E52CD9
+125596E14FBF9689135EB9BC926F4359AE2364804689A11C963A1D06B9839125
+DCD6F3419FEE9F9E8319140DF508540FB591CD0B33BD6137FE2874B931F810DB
+589CB9323A7F14E92C3BF41768D34CD59F9E0DCCA83A64AB940946DE847687A0
+C7E45EA858A260DF5E5BC92C1789F5B1BA8C7F01AC9189511F3A34CDB3EA203E
+6365B832BC84E4C578AD41797AA86B1DC362E9A9484FB52F1F2B5B3857BF2968
+0AD18607DBDD6250FEC6057265431247B98960126CB5C358B99586DAA488D12D
+6CF6BB4732803B407A32ECB88C4E24D484255A5E197B67EA9F062ABB466A6ED5
+F15C6E27B892D368060AD5ACFD625C633AC492C073E0FA92EC7EBBFC0652066A
+D0E27513EBD0181AC9EE867434CB87FB6C3B1988568B6C3D89E288F39CC702EA
+1B1F6861308D6F1137BD59B94A45B46294B0659BA579BA61AF2A7BC1785E30B6
+0C1CC24B10B50615BA0934523F700FE57834CFD6944E1A750B5F9BFA3490A010
+6D92A71E6BD35122671DEF37DFAA83CA6CD176BD9C26D146692C3C6EBAE3B489
+E76997CA21191BA944083285ECA76EBE94E470949D49B8C646856B3C879E6689
+1A093FCF6A42D46FE224B007AA995177B8E697BD4F1E2A29F0D30952C842AA7C
+A6BB0960CBFFA5EDCA5919174BE52769A8DEADA9398B1C7584F80E52237D9798
+1F81230F3F1260180F49F856F04E72D02C024B5FB4AAA03133EE18DAA05692B7
+9FBF64466AFDF3536809D4863EDBE1B9AB81200A69FF52AB355D08D5D55DE12D
+0D55C507D8C561CF9D3D55A5AAB2039986AD34CDDF8E582801D61543DA4CF1AE
+83E2BB0531B3E42D6594D8F4169CF187AA568688D8FA65ED8357191B4EC058B5
+CB47859857A8225D775CB3E972A35C84A85821C3BDAE9602F41507D30A7BF575
+B1E6827CA9FC6D7A528AAE10C50C6C4FEDCE773E5743D0790E10B0CC6673F956
+8A642A35B251AA31E8AA9871E79E3B77FE556C4D9E5E31AB58298B58C7451762
+67CA429EE8CF8F47D6BAC28A3AFB0CBA47C08033A45F33DFEE8BC4E2C3D8B003
+CA46F7AC88CCE2F3FB89D75B4AAEE56A1B2BC8C05CE88A6F28B901D2B3A0A2EB
+B9AFF04424BA1476C8FB008DE558C74114B2827822B9311726154507B7B85C57
+4F6E90663C8151B62A1471B273E52C1C2D7CA31125CEA0DB8EFF71711EBD35AB
+65F020D486F8FF8C94764E47E244621F2B6EA2032DEBB8D29959D86D5A74FC44
+ACFE94E8A9C5DAD6F381AE2F3D6F79E3493530B348E4F90D2A69C4968EACD81D
+C7F851685D0CDB5B0CF33A9383B697C2993915FA01744EB98A35DEF685BDC574
+A66FCD19585679B181A6CE4EB42C2F1F0DEA01084D46C0C5842ABE7B4B0948A6
+283630E84201362384D80CD0573936E601D8D993783739153649D3B9BC7C1218
+4356BA585BA414E8799C9E9DD506E7B9ADC3AE3BE0460AC1A4E0ACD570B1A780
+773A1F7E0980A15439949B4170115A6F04459E8D1793731D04B52DEACAEFC64F
+E17A4B3C7320625B05711B6CF1E38BFF5357DC6364BD2CFED6F28555CC9041BF
+3CF4B52C413B53C48C169490E91ED3547B05034257A626B6676096AEE978BEBC
+A286A3C4AB3B07F33E9648C31F1E3D68FDAC2B8612AD55CA25F0D5168FBC7FAE
+9F3DD37A9855EE0C41CF8CF089B916B37D8E8C1738D99CC19193BF6B25D927EC
+E0410496679FAF5957DB5C910A06A5AAEF993B9D6748DD3B09033C312076E8A3
+CA6646E22A83CF8229CA5CFF432D5F0CDF914A0CC5CAC5D0ABF779C306E7E0EA
+E5FF8011CD264ACBA1B388165B72111854B221DEB49AC4B577E4A1F6B7D9DAB6
+07B645D223BB35036AFBA18C99C7157DADA7CB99E1D05A0D6ADFCC905EC0AA50
+0B7E03A1A96154FFA174F8118DAC7AC66015907DD8E141932DA170B56ECD039A
+AABECFE29F1D7380DF65509AD4BA93D76CD6D7CC5C3AB70B80E2F94EDF404EAC
+376DFA48D1155F2F5DAFBA71362243E1DC7023314A977549FA0FB64C0E973725
+DE4A2FCD067A0A51915D8F788DC8092116DCC3FF5E23E4D935E59237F04BEA83
+85083330FE527922067B6EB1F09716D8C5A4525F9ABEA5482EC28DD13C222BBC
+CD9E05D435E1923E8B3B42CF85729746E24095A3EADCD06A845F4C2AF93DFE6E
+12A563B0B200EDE7E6CDFF5FD0724374126B1767FF5498467E0D49C4A07D3770
+ACDBE62159BB1898E2B433DB7D629CD8F3F4C2B9392DFC0C4ADA5BF9B03710D1
+68011E3154B61A6A38D43797F33015E4E97F2C57D3CDD8295B0E7EEFB1B1F8EE
+F97AB546EEE447B356ABB06EDC324824438A5287821BCB7E7A5338EB36DB768D
+462E008469FE4BADFDCAF7AADCBFBB63CFDBBE5147EAD6C5AF942753A9A7D2F0
+CB6291EE5441F0C6F3AE799826A54758EA0D4F8EA00F2E450D91474AD4B3178B
+B65A6D86909C8242B814F3087557B4108F0B052708257B6CDEBDAE931CAA2295
+32B3788FF3AD4E3833D247A2B86E067B5175B5D157B7A6D57FEE783269146078
+0C9259218F6EEEBB2EF746DE074FFF5066BB8BBE4694E2FF8FAF91C878DBD117
+9465D65A881AC5CA4C74778E41739F2A3BE03A33FE49FEBB98E90234DE4D835F
+97A3DDE860E4A30DEDBFF61B36717DD91D5C9417640B0E4BA31F4F8494A1F645
+34CBB593EF1D1571BF27FD2A3F81C4F1622034FEB55C44D2852BCF4B7571249A
+2C5D8AB60FFCD931370D747C7834776594450C968AA7DD5F1D491726B0B22469
+E5ECE0FF49B67500A78BB012B1DAC77B58D4BD311EB394C4A7AC27227AE67211
+33F3D2EAE4A08D62413AC73058BF50F2CDDDD4D655AC737DC8AEAF2A8B8F69B6
+2EE5432182EE306FFCA3E777225D500E02D54DBE5E271AAFCD49071A3FE3160A
+4EF901B61EDF106059A368F3640A432ACB6C0C05E2D7511C3AB6DF1F9C032F27
+62E017E03829D80AD3B6FF3A896276DE7B5264FD0457C490FABD47C79F6B9988
+6A2AD7761C70593A43DE797FB02C009F0FEEA3A52B53E9BF2BAE190FF5698A13
+8DE051DFA8FC9C385F7B0CF002351A6AAEA542D6C4FB182A103CBFBED0777CD0
+A5414084C2BB56B0139F19DDB06D7C99F676CB42F10FE4822D0FEB145D1BBC3A
+90FF29B94FC74447FFB54888E3B45611D4683E9FF329A47DD6B4D2B6AAB98357
+2CB2FE78D0DBF36724D0C42729B27153098B077B08DFC9404CF7A0D3C586B48C
+4049F8E66CA713E797FA701FE1DBBF06C900ADD95F8138359DE83E9217AE928C
+B1DC6853E5DED8A685217E50AF484C2AA2B784F14963CEC41E66F203B8522102
+A104119C2D413AC44A2DFA900251C64DE8B0EA2E3EDB9658E2BDD53707FC60BA
+CD9701B4E720EE584577BB24875E385E66A3BC154E56676C401281410F212F5A
+EFDA1268663987262690277ACCAEFAC04F91BC95C04EA441E33EA026D56EA0FB
+FAF3CC4582AFC9D83081F8EA80ED24CA4B29C269EECF0C3560A138E8B6FA9F7E
+8A4177AEF0F6B174E9699150CB18DF8C7BF7AF4AB87056B0E670163020CFB69C
+4E98B6A79E656C6F44B449112508C8AB5D7C380B7D0B38E843868AE6C6500299
+4C61C764B24D8E914EC2E4372FFC12C172B628E35B1E4B42233E8737E313A83D
+7C9BB76883B0A7939A960295B947FAA4C251A2944DF27C986D69E2848729FCF7
+A180A1599E1E5878A3CED8E25C3732B32CB3FDCA6DE0A1502456D9B0799351F9
+DC611A28F998508AA347A690DB2B2B4E99B61499655F9F014DC13A4E7C4E3FD9
+1FF48559DE1BE245CC876A8B011CB0A167ADD9A77F4E66996BB244A589475BCB
+9B916DF647198063E404F99675C33442C5DF04BE569616A2E2FD01A6884419A6
+311DACADD1083AF250132D42FB8A0F5B217454A64B23F4967A0138182C0AACD7
+268D01F080B58213DEC981923138D6D10D5073AE73CB4E6D75329DAB0B58C229
+FCFF7FCEABDB89613857350A221865CEEF23FC065D1B1E70C717724320D27FF9
+07754BB4AA8DBBD122050BE3B4106B5FA453D8AC98A0F86D829755EF4D3324AF
+5E271D4E7ED463461D8311E384AD5391756F35DC5AB78AD1C5F55ABA13035466
+004CC16AB52BA0227D4B6E645BF0C2679A154C24AF6A267C227C0A2FDDACC610
+9F8A51DC3759D8949DC69557B19E24E8B2A829A7408B7BFBBB9486B972172621
+162BFD558B14F75E0B922140144A275F665CB1DB78AF3ABC9895547018AF7A52
+52B34F26289CAAF7C5F1E2B058F38F65BFDA4585268436B2DB4929534BFBF0AA
+C8F836C0D37FE90E294D44C88CA39931E3219F9DDC38A6472FDAB01557FF4E06
+D423FAA6958983AEADA09DB2A2F6874A87D9C6BB07B7312A7889EE4396767DD9
+C83ED5998ADD19328CEC32DCAA43D0949A6D94C7463BB910687D7715FF0B5FD4
+DCA4C626FA548158BDBBBD1BB56A4A1B92C88B1771D76ED986CBEDA938E02241
+80C4C14EFDD4B7D8A5892C47C14F3DB4165DCBA083ABA9183B4EC464109D714E
+41CCF74A390C638C2A483ECAC9C5634B390E4C794D79A92E73E9252BFFBB5F29
+2DDEF53897ACEC81170F25A7D939F991F301951AB07FA844FF18CBDEE8B4C915
+743C05B5FFFE92A06F1B741ACB311F2A68D7455EE94DBE94B949705F188E91FC
+480836288F583B88E2D3476A84A1458334046E25A3458FB56D184A88A2445BFC
+CED319C452BAA61945E6427457BC7F064BEB030C9346857448889A78C57500D0
+49D020BAF5ED109D31049D35C8CA83B0F9E41DD6BB22A22FC6E642E012853E32
+AC00650B6DF411D915EC7E7AE54B266BB6747A80E2A0344AA3CC4D77832D57F7
+49E234D86514CC2E5B668D385E281B207772F8B6843CCC3FD3EA4BCEF86D9FF7
+11EB8CA9BC3B5458E64F7CF674D2A0BC71C14FAE3E028045B1B6AFF84949713A
+F7710CE7F0BCC4CE9ED1E052E033903775C6BA67DF64A0EB22572BDE2E8E3A84
+4907C8BC3F54D6B77DCD301EBE0A16BF8647558CE25C8D68086C5952999E4F51
+434396040FF1E2CA290C7535C8A28D2A3C8F4D8A0E70890B5CB40A47DB60B31A
+8F74AA15C22696BD7171D206E71FF0DCBB418F786BE0D49B358F3BA888433FB7
+23980E50C48FD5DB43BF0E2223460CB791FE6D5276A9404480CEC4643BE8A0A2
+ECEDD54B4307A416406735AB9776C25838E774E09DCF2FDA749D71D26FD30B06
+F99A0663A82279495B975C2B17C82B05E58EEBFBB5E12F98DE82FE7867FAAA2D
+91756A4F7FC54E368C3AF0BF9DA2A344E2FCC76A86E20DBB6CC026F05154A9D8
+EB08E200711BA1E330F0FF1279C571925ED0E7BE86A74BD036A4D9E6EA4295B2
+0148D8AC11B8A36321728931D000C264BD878BEC1D94FC6FCC4720CA3FEAABE9
+2C97D6AA01B3DCCF0D89CF7437BB9EC1F077641AC357C4AD7E9D0D3C953E839D
+92B4A25FD83C88F3F1D759DE0293DEAD30B9C080C6B6BBE45149044CBE530696
+36FEE48A1DCE1F615EFC87AD3FFB414DADF49767897E213B8E9F49936BA6273B
+A0064C8F3D74CE323493C5571287F481A082B266C957920AAE3387ADFAB40D0E
+B7DB85BE36556ADB72F6D9B8A30716A2D6254CED3AFE7BBF8C2787116AF53615
+E8F5A23C7AECFFC783AD47D2F390FDE458DFAA5CABA6EF8F26FFA519A2265426
+25CE185DF484C7CE53BC5EEDA5D9842FA5F0ABA36D84BD476CE6120A95AE231B
+C6F5D56D8FC52BC16FFB0839F2E203C3ABA654408EA36E200156C6874196FAE7
+E879A83716AD1FE3F61E0FB83FDE97D6A7E7AA12250698F7761EB11AD46B974D
+B799E2919F893268BCD0FD3A7BB9BDBCD31387752AF40594FADB1C9EA80F0B2C
+8F75C24D6FCA63D5533274D9ABB82D9D087D4EC3064DD43FBDC410CB0480F1D6
+81D4B2A153A9E4105D6E737367889C2879B0BA23D0E3445C52F43BD915A6F544
+DF28F8AE1AE184E93E5C0F148A08F0BE110399F492683049378F7D02C8586C78
+39BA15813021006E0849081D0E2EB0A4D931BC53E9F3ABDD2A4CF6CFCA519CA4
+BD3BF6151B8DAC894ECC909200338E018E5D688222FF75DA2ACDA3A0B6757F8E
+12566973481D36C737FF09416F80B9ADAFAE94050248CF687C791F3B18A758D4
+EE78CD0337AC1ED867DB7DCDF17EE43916FA5157DFB8D0C0EF4892EFEF2163C3
+F761D679E1C32138D6312AA484446653FF67E3C42229A6C66962430E7633A2AC
+085D44E2C27A27B5E466EFE665B803890DC6678064DE29C9FE42AF022A91033C
+C8E47B5C727229C4E15A425C0EB6F5645CE8B52858D7E808EC9163704D20708A
+C0CBBDC4F1A7C678F56EF0BA905BD8B43A27FFB433A300115BAABDB3C06D5BB0
+D6AC5C204D3B0E4E985C611C22D9AD61BB0A9D3EBE382C703F2EF449FA451B0A
+50FCA07C36D661ADBEE41CC37E98EA8921E2421080D0032012E84F7C3D803DE5
+391C0E7C2D229F495D1DA055DCCCC408B1481503E942300493448D4A589CC2C3
+A2801C29342BD06ED565394F9AF9D940A329C96C18E2FA405CA3CAD558592506
+04659173B2F9EC1081FAB95BEDB32941925AAE45C6F6D742D153BC9B924930B1
+9EAA14216548EDDF70A203501F7C660EFCA287906965B24C2D7889F91AA8F64F
+7EB7D098DC911FD416D08471EBF37C65BF2F9D78FFADF498598D018CA1892305
+BD14091D8D3DB79589F68EC891BD788DAF85F0A9568718F95DEE9CE1C039A22F
+D8BEC548AF39E26DB4566EE12BD7DF7D5E147C368FE5D24F764F955EBD2FC1A7
+DAA4EB4233CAF94141FBA18927C6E4B1C80B96CF186AEF2064A0B1F76E13307D
+ACA7A3750D4EA808DEF78FC0BACFE291C3ED2E322385B0D18498C2F028A65979
+DA9743B16A9570979036C51AE4AD710CC444D55A62D61010687124E4FAFB7CC4
+79741B38588A3631700D73B619BA42FCF9DEC2A4A032E70E6AF7D47060A17EFA
+E31DD2D37F8B3103AE27A0D1C6D982FEE048946CE3EDC22BEBF3A9829E89775E
+2944B6D3A1BB36E66DD5C0213A05D379D03C58A624033FF1E3E8837AA0532366
+2A05830690EACD3AB4C111D0B824997DE953791D76B6C1FA4714D3D98FFB218D
+60948D2D2C96B07B4B0AC7FBC3C938AF3604BDAD43BFBCCA5B66E2093CC7E2A3
+C980B0D634AFE7C2173FA197C6DCA10807B6F66BAEF9770FEDE5D1BFC9A1008E
+3E3C9B532ED7C3F829ED9E19062B5CC5C8A2473C9FEF131DFB61A0F957CB7035
+F051B9B9B553142B6C35FF43A58159CA30CC9232852897230F30FB15D1E55AFA
+6AE0B7073C41043594D4897B81316A82CF5C7FC054A0D0872CD83C561C757F3D
+F8B50D23586EA6A3496B0EFA63A5D8C89CF7968927F4AC9033ED7D2CC7390CD7
+EA0D69BA01C693D11B71CE21BD92BFEB1AD2BA96A6B15985E7D4C4F1662AEFCD
+6D2C0334E50EEF2A878DCFA645E051B7FE9EF9C3AFE063D4FDAC983B5ADD8880
+CF6462D68546DD3B38FE1338BB699749DA5703367FC990BC8512F013BCC822EE
+58168E8AD5B76219ACF58E7238D1E956393C5809D9430DDD4F574123F47C3F59
+0617288ACA69EB57200FA00CBAF5537D3DC1664E8CE5981E86E49FF8E468857B
+6AB30501CAA8B0D957D6220D9D552436DE71E6BAAD9332F7EC647295D1A8725A
+61FEE01CEB6BEA0831C01AF94001C4E1A69F43742E6BAD5649A305EC36ACC638
+8C24A4976F5B7A63917394C99FF499BD922314593F78FD7156907DC167F761A0
+37707433D75C4B98AC48A08FC4F3988CF9F71752D894646412CE7390D99CE2BE
+AC4459AD4D097368BC3942611EEC7BF8E481CF0AD0050E18E36A1C0E9CFB63D8
+F4D88A59899CBCE6BA593703AC923DFDC85A85F885AD0D7147B6CD6EA0782B3B
+DFE92ADD2075B8056A6C4B4964606D68B47662317A71428A1A9579AA78CD8A79
+CBC839D0CD46FD84C1F1588F16BC80A6D5648F3F2DFEDCED33141A1DD8B86E64
+30D209D031B61F2DD9009C9202571F4E99E0E75A21D9AA7A3649FD4CDA1933BB
+4E53C3D9BF188EA5D95AFD8ACE132FD91C81CD382E68F3D1432FC8392ACB452F
+A6F581563239CFF30CD8EC3EF799BC8291E3A76B76AC107554329BDA12603760
+8970A5616359681D6A038DB1F4BDF08C10FFEADDB97DE44C27BA269175F91D61
+A33944E7EEC7F6EB9139AB0F3E49AF2373B3A9C9224E2645CA3CD3556063EB66
+4905D4824C23D261B53C6B49FDEF19D4E113EEA148A1541136DD83ACD4272A61
+4285419B10961726E5FF088A8833234C6C39632D1D86211330EAB80F47C64378
+4771739DED203D692A62DB30F3D875417473BF05E2111EAB8536EBA399EF10C8
+05937E677E128767F108185B19B102E7E5612E8F49B71CD4AF4F391BD5550A7C
+2B0472E935830E3F84A0D01ACA25EAC40611CCAAC0175BF5470CC9721F2689CA
+396ECBA85EE5B16690E970C05F9AF82F0617D834CADF01B29A9AC20FA6860385
+6C3790CDCA54C4B8C0A7E7FCB29369181BCC55978CF8C45F20C2807B58B2946B
+F73B1C32600A2EFDEDB05771E2328C10B078A8B5D68AF527522C1DC28E6B0C6F
+28B14656C07E7B355B7B41FB7D6B8BDC0543B8A86B688F21993D82096A99412B
+2C5EF2C850F1DA47923D4AA1F7AA1FD0AF09088385B286F4E91BCBF2E62B4BE2
+4795A9E7AB0CA5C3572AEDFD66A627CFB3554CC9E98A13902508C407CEDF92CC
+AFA3871CF38A64DF1F3107745A6BF68C93EF67355AF32F3994AD228BC4FCC45A
+B37F32098C42A9ABD1020F59CD486C11A5A9ECE00597C3345A01566FA85F30E4
+E8C2008ED1A35630782340645E9DF5F72FC3F1EC93E29CB5EDBBD0B6B9B8B8D7
+D1CF0D6D6E68C53E72DE452A72A7F1EFAA266462E302495F5953A18515C61E33
+AC663A23471281E6DDB7783FA8DBC681EB29D3C4D46E281507D4AA8B04E6442D
+12D0F98EA735898401454BE76DD0161CC35CC17BAB0799A32B486C03FE362DF2
+D650937B554219FA9D55122B0D23BC65DD993BB5A373ADE161F4EA6CD22ED48E
+2267B630D15843B3C6A29D25834DEFEFE5145D17FCAD59F50438D1AF8CCCAA2B
+68FDC7D4B8C8C9CF9293185CE66DE80E94BCB81E4290A808762F485B7BF67BF4
+853C05507951732DC9DF2FCB294A688A1344C6F13D83040EB3CF6FE43F93C6B5
+3CFD96F8ACE65B553036874C5E001F058FD45AD73EFDC6441D34FCB36482F162
+65BFE82A0A3D0FA84BDC488ED0A29A1D8F24DD6236BA14F37F1273477B17A1D6
+8BBA6FA890FF25F902DA9801CE453163A724307680675443178328A7972623F9
+E376E904396B32884B235A3A2F2E485037DB93DE70DC3CF616228012290236E1
+003C34A04ADF18C9452700CB3542ECA78CD76A31DA6854A14BACAD93CD713FF5
+7E44A88B475766ABBA4492664623DF4B18145400219AF12007C0F1614B21971D
+1C01364BC2C318C0F95F2C761418B072B92EDDCDA7D8A39D73DF44F2CD948CFC
+1195611110B1D29A94AEDB03D4F2C1823F8D0422B3A7C93ECDCB28686973B758
+A36F3C2A464B8DC0B8E472306126126B4C97C84C4CF74BF463D3C282DB7110D5
+B119467517E3FDC3EFC6187A090A913C1D9149BA359AB5D6C73CE801AA3943A3
+FB7599B33CDF46D3E519B7A129DA1C8F519ADDCC950A0FB8C27F4DDBFCA1421D
+ED041D2566D6692444C326A913EEF73EE5E7B1B0CE7D346EA94BBE77C4BAD703
+8CBB8DBC6F345C4FA0887D7D77CC295E18BC60A9C4EC6457BF233805AF08D988
+6A2F4110FCB0320E56E7AF7601E034D2793EB5764536B2944BD90CFB4FD53C0C
+2554B4B97274605249A085B1B71C7F53E3D30B19546A0858E4B6116AB3A3C20F
+D223153FB7DCA8A0E3D7D9E906F673AF94A92854E2A25B819E47AEAD27485196
+6AF4DE6C88CC79B8F72625B762490C6C279916C6C8CAFD0054FFEFF11F8C7152
+B2EA7981ADED9F706E2EA21D2BDFA59CE404D0AFE11FFCD68732DEC63C2FB0D3
+A96E14E5046ABC98C8FBF8F1BA121BFD1FDC94EB5597FD44219DAF19F871AF75
+136D8AD20E17985F25527A46B175C1E48E760F8086639FB5C086A6588BE797C1
+A5F71D3F66C51FB1E49A00201127877DBD00534E1E8EE719C6EEDD7E4ECF740C
+272ED2F338AA5E1FD8AE9B0B4D9C405615C19DA824DFF40D92505BD37EAB2E62
+B7AFB69AD7B76EB6FAA90ED8119FB8D710F5536E564EF8E11C7422B4985B0017
+C760C753B521B474787E23A64DCC32FA2800BC8DE36F9561DF822DA75450CE51
+8E7B9A0DD0A57762E7F85930DC0D9C37F7AF177F9B8F355D8032FCE0D010DF3A
+4AA00B0754B79C8F5B314DA028DC12260A5C6CC42EA8A5AA0F4E814171701653
+32FC6F1D94DE5FC999977735DEE0129E8394BBF6986F4392261936D74BA19ADE
+37742B698CE29CFB8395601FDDD7228CFBAE86406422387A83B2901D9C1B8665
+31B0F6273537D77F0B4F142C6B210071694D1B8E7BDECFBA2725A7E1AE1D81B8
+02B34FA02D0A7BA383763B44BB31ED7F9237936774590EC93B52914BB6E9C931
+C3D8C7A13FAB7F2346C861685FD0AAEA9CD8DAC1F995A86185660DD25A46E3E3
+76E9328C9C68331AF07AED6E7E8305E056EB489A1436733438368B1084D414E2
+3FEBEB53EEA500392D754F8EB2AA96D3EC336064C713D63ED180A0E777F152D8
+8E3F0D82348C1C4B3613CBE1A9982DC5AC19443D66E5C98221982DF65D9AA392
+A1C24B28051313D8CCCA650A1ED617B61E93FAA49499F1A12B0F8378514DE99D
+B4AFE780B3776F5F0E5D8F1627075F763C61291515F9361968D9750E41AD0CBF
+2F074C4C1E86E175D163CE1DF4088CBCBB89FD725F256BA370D27B1695EFE072
+D3CAA0388F5FFB4F19B49183D001282DB413BA2B558AA437E5C08166C90E943A
+2986253909E1898600B7311D1129610CC5181131D166CB5F5354B4D4E5ADADAA
+C0987CCDD522F0035626399B9996704632298D726F86C0A5CD3775C594E32DDD
+06466CA1A6903B694C5D9695F6F2B3FD9ED2DB99D9B38B78ABF97BD43A55B7F0
+CD4D43509B72E4B4C094701EF0FCC3B9E5D98996807F2A8AFF6E6A86229E0530
+AEB30DBC61EA58B555BF01360E4158C3EAF4FF10BD5C87B5745AC1512A57EA4D
+E231EF0EAE461CA3031BEACA80615FF8F50BD2FE95C51C7FAAD7E6BD70F1DF4F
+86474964084739126E16BF18E32857D862CD42ED7E7F462EAD75D2923B1B9634
+B8B6E1D3091CCC23EAD246C82EC602A84C82D4FD9F5E867817299921C844D685
+19C008BC2025B36C03DA5BB272375FE9997EDD64471F30EDA21EB796743F3B42
+D43FF785C900EA62BDC3C46BB2AC1B3F00A74B0F0C3B348033369ADF630D1C83
+E5E741B697EE045CA6325D151F5819C6C2BAB793A0A40E1A48E6B1F442CDEE12
+7B61C68C60172C0D09191FE1B0C1C3A082EC31CFAC70E298D00C04BB7C6B4E99
+00558D641DF88ABF7C7D712C8DE23340C6200D8539B674BA1B60B2BB9AA99EC5
+CF57713B56C2941C3DA98A47F6C3DCDDE7C047251CE493DE954028EDB34D3DE8
+946ED87023E348EBBE7BE424D92A89CAC21B7B81061C999FC8DCD9B7814BBBCE
+
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+%%BeginFont: CMBX12
+%!PS-AdobeFont-1.1: CMBX12 1.0
+%%CreationDate: 1991 Aug 20 16:34:54
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMBX12) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+end readonly def
+/FontName /CMBX12 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 79 /O put
+dup 81 /Q put
+dup 82 /R put
+dup 97 /a put
+dup 99 /c put
+dup 101 /e put
+dup 102 /f put
+dup 105 /i put
+dup 107 /k put
+dup 110 /n put
+dup 114 /r put
+dup 116 /t put
+dup 117 /u put
+dup 118 /v put
+readonly def
+/FontBBox{-53 -251 1139 750}readonly def
+currentdict end
+currentfile eexec
+D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891
+016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171
+9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F
+D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758
+469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8
+2BDBF16FBC7512FAA308A093FE5F0364CD5660F74BEE96790DE35AFA90CCF712
+B1805DA88AE375A04D99598EADFC625BDC1F9C315B6CF28C9BD427F32C745C99
+AEBE70DAAED49EA45AF94F081934AA47894A370D698ABABDA4215500B190AF26
+7FCFB7DDA2BC68605A4EF61ECCA3D61C684B47FFB5887A3BEDE0B4D30E8EBABF
+20980C23312618EB0EAF289B2924FF4A334B85D98FD68545FDADB47F991E7390
+B10EE86A46A5AF8866C010225024D5E5862D49DEB5D8ECCB95D94283C50A363D
+68A49071445610F03CE3600945118A6BC0B3AA4593104E727261C68C4A47F809
+D77E4CF27B3681F6B6F3AC498E45361BF9E01FAF5527F5E3CC790D3084674B3E
+26296F3E03321B5C555D2458578A89E72D3166A3C5D740B3ABB127CF420C316D
+F957873DA04CF0DB25A73574A4DE2E4F2D5D4E8E0B430654CF7F341A1BDB3E26
+77C194764EAD58C585F49EF10843FE020F9FDFD9008D660DE50B9BD7A2A87299
+BC319E66D781101BB956E30643A19B93C8967E1AE4719F300BFE5866F0D6DA5E
+C55E171A24D3B707EFA325D47F473764E99BC8B1108D815CF2ACADFA6C4663E8
+30855D673CE98AB78F5F829F7FA226AB57F07B3E7D4E7CE30ED3B7EB0D3035C5
+148DA8D9FA34483414FDA8E3DC9E6C479E3EEE9A11A0547FC9085FA4631AD19C
+E936E0598E3197207FA7BB6E55CFD5EF72AEC12D9A9675241C7A71316B2E148D
+E2A1732B3627109EA446CB320EBBE2E78281CDF0890E2E72B6711335857F1E23
+337C75E729701E93D5BEC0630CDC7F4E957233EC09F917E5CA703C7E93841598
+0E73843FC6619DE017C8473A6D1B2BE5142DEBA285B98FA1CC5E64D2ADB981E6
+472971848451A245DDF6AA3B8225E9AC8E4630B0FF32D679EC27ACAD85C6394E
+A6F71023B660EE883D8B676837E9EBA4E42BA8F365433A900F1DC3A9F0E88A26
+3753B03B38D6FF2C1D845166BAF4998598D00F26A33F36C22E2C93B0A38650D5
+61BC36F521625DA1DD5E3133F573575101D9B21CEE92F241DF9A5A4ECACEE0C0
+1FD4DE44E06C1923CA444F762B6B448DE4A52715961063CEC16B6C371E93F0CF
+56C47321C2345C083787EEB699FD2F9D3E2FEFB010E05E0DAC4F2934DC1BF47E
+21DDAE3E56F669A0C934F7F751A01CB55635B7590D2AE3B6F4777BC0EC8F7585
+BADC41E3DEAD3C1CC4AC3020CCB7CC60ED93CDBD17D8D10A3014099E5FCBA6E2
+B18DDB1086CEEBBB1A2A38D011E5ABA027C28E72AADFEC805D080238B4633408
+41EB166F3E8CA60D77071FD7CD0A127516FDBDB49199E598BA61F195678A0796
+86FEE45B30B60033CA49A5922F28E4E0C9D4BAF66EBB536AD8BA9A0E6F126E1C
+6C5B2B81A7D5992F0FAABA18DDE700056E6D85798126ED387B62C5F076ED907B
+E50B145B588823906FBAD973E60CFF9868F9844299B07CEBFE7B2219CB531193
+1D0E1D953492FB81E90BE977EC4CF0C5ECEB6BADA7A1D86A3E1B944B044BC90F
+020F5E76C7353C0F8C5D76DE012AE7A37F9859C85A6C4681C29A644F2F119138
+9D113569E9EFB85101AE6A46D660C5C7E205B272BD53CFCBA8C9A51DBE678806
+CA0B6FB7975C3EBE449A9C3DE0DDA3C0CA74D0F2085E070945726C1594A611FF
+5B4BD0E2EC240CA21CECE1601E1705ACC14EA52AF8114A16061FF317167AC9F5
+DECC692C4E2727D970E1171D980379B56E2C51BD3D608FCE89A7A2E832B0B815
+A7B334D470817F2623109D0BDD66C8AA697ED3CA02AF684E5766B3470374F9B1
+5BCF04D178D5B4F12C4A0303AE1AC1ED6C19BFDFEE60DCA168E90AE9EE49CB4A
+2FFC5DFED5179AAC027F6D415089A795EC9292C58B009165717D1C0B6126C55C
+C10E4D686A735F787B3D693D841198A6EA185C691C070601938FB8BEC74278B5
+E88003C6CFA16C7DC52FB135D48D0A85B42F261B64876815BD2DB1DBA403B5DC
+87DF034DDEDBFE962A5AC112DCC6B8415A518F463AB278DE3C6B5998ADFF4065
+6AF00AE2591D3C3750030C18CA2D4B78FAB4B03E72D6135D69DD68BDB2023F1B
+7F9C0ADCEE2576D5BA1130F89E93BE5716252173339A2FC1B11F5E5D5AD31F4C
+9BF98CD0765C92031185C3BED78BA36425487B4BA569114BC5B46EBB968CEBC7
+3742501440A04BC19C12E8BBB4DC962DB619DF7C3298892F216CFF9140FD974E
+B1EB752EBB82935BDFBA064B81F7302888C4B767BF2AB4CD44CEB1C5D6809FDE
+617A2B93E3FB231DD54B9875E59823A2DC666DF6D781D249898A2F05C5C88E77
+90DFD1DC1F3488714BAEFFD8FC1C3633EE8E793320FB51436784FA82EF28FE8F
+65AF0F5C5471A99478B99CEA235AC0003E6C5BBBCE4652BF2CBC0610B29AC8A6
+ED3034B7BC76EB2009ED76751404F14061BF4890FE9A1A01476F1C2BA310A82D
+A1B77BA6A71AB8CF54563315338A35B1D3A3369BF77312C87EE88E9B1E40DD17
+3CEBC13E73A90A9B40655B2BA43C93D95DB9B47BCC60CF801EAE26242FC4E7FA
+32328BFA8B7AB57095638A3F154D9AA0769C7B02A6BADC3DC59297C46E51DB92
+0BAFAC207DA75D39D7A9066D0EDF73FBF28A332F8C800806D9512268241FAF9E
+C6279BE0FB884244D022E38C8D748D8928A5A44BC1B2006034ED8819446FF8BF
+98BE8A2ECC149B6E795E35DF7CBBA29482260D67EE7544CB5FBA4E4EF627D476
+5CD6F741C5CE950F14550940AF65EC541C053C6B18203562F6BC7ED6CAEBBB73
+300798634EDB4926CE56B2BF0F4226EC1F472B8EF674AC3AB8597EA93135A4A3
+AFAFAFB943DEEE1C155EDD689BC3CB7EE95EF96BA686BC723C56235848985604
+8A3EDED9013B609FC8855EE4A044F7C0634471F5372796391BF7820E579D7704
+FA6837B717733DA04D5DBDA91A028F14317EF115FDB9A952A93D6133A533F081
+D0715B6D90FFD9177C44D8731692D823098D04080B61F5D54C8D300DDCCBD145
+92601ED8216D3245E104DE65087D3A0E36ACCCB0A971D9163EA7DE727F2345B1
+8879D24FF363E8623D30F2E0DA8A41028D32D93AB4BF94C18C21C22BEF1D4FC8
+1B64AE052ABA20F8988F614CE3E42773F2DC4B1BDFB5F7B826D0DB68D92AB25E
+FF2C19BDE6287731B72979D733A9F79B51B97D4D823C7E6899953B425CCBA13D
+26211E53C38BA9182C90243BE9EEF1A86C78B756AF2A74C60B9DDC7DAF99C430
+407B0E49032DB092DC0F36B2F9CFE375E3C4737E122FBA57D89778C7922D5CA8
+4EEB5F50B96EAE7BA1850FBB30E15CA5C368139062036066CF92CFB20C7860F2
+67FF81549D70B048831750FF06A71B91512710DDD86EBFF5FA43E9534F5FA6AA
+E87843B8EB1A40D203880B6EFB38EA5CD5CD4E163CDF36D018B62E482F2E633E
+029516D8BC1C02344BD85B1DF3F3EE1098104A5E754D6D4E86C29F08CBE8BAAD
+7A5EC1E654BFDCAF8EB2A8BFA28DE9E857EA7CBD9E3C0012DAF79A114C55AD77
+952BC5A5FCB40C76760460C58836DBC927D4231EDBBF3B06A420ADCAE8564CDD
+85DD501C31E3915FB7A3CA9DF157B7F4C183DF6791E1FE071EBF75A47C8184C3
+F7BFD40AFD10CB3D4835AC9EB170CCE05E01E76497D022E263D4ACA540AE7A0B
+F99EFB3A4E82D400FF79CE97AC2654E2D4FA0092E2D27097FD9AE0476CB33B64
+7722F482E0B148252740F435F52D2A610C195E340A86472C5D41D1B03CE311ED
+8C2C81A9D77352B27BBFECDF828781D7ABB2485FBEEED6B7BBF042884F499C64
+8B32FE5F8D8FD13BCEA7CF8D763D47E8040D0ED2EEED52039AA93B950491C9F8
+8C7BFF7002F6B5267176B71E8C408258E401978A723DE12A969732CF910D60E5
+4E8ED3C0B4C76F9A7BA41BEC303237B8256B6F78492EE137CB0B83E84EC69AFB
+3A91446762891E2C2867F40F62A31D04C9D42D2D77F4751084810B839AD5CD70
+C79A694BA0160A8BFEB87BFE5AF51B01306886897429C88577006988D48BE24C
+98E7F2512860346E5112D0063B79F3A983259F766A89ED3660D39AD7B1E237A4
+097102EDBC8EDEC3D93D4BC71E557956649AF5641D7508EAED4DECDB9BB31C29
+2F0918025367A9A394EDD59B4AF99892BB84558479690949DE631572EDE73A04
+662C9FDACFD281F7ABD8CDCCAF604A28DA61B3BD8EF9BCC64FFFAD782F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndFont 
+TeXDict begin 52099146 40258431 1000 600 600 (refcard-letter.dvi)
+ at start /Fa 230[47 25[{}1 83.022 /CMMI10 rf /Fb 143[69
+5[23 2[42 42 99[65 1[65{}6 83.022 /CMSY10 rf /Fc 162[23
+1[23 41[42 49[{}3 83.022 /CMR10 rf /Fd 133[28 33 32 45
+32 37 23 28 29 1[35 35 38 56 18 32 1[21 35 32 21 32 35
+32 32 35 18[50 27[35 35 2[21 25 3[28 28[39 12[{}31 58.1154
+/CMTI7 rf /Fe 133[30 35 35 47 35 37 26 26 26 35 37 33
+37 55 19 35 21 19 37 33 21 30 37 30 37 33 19 3[33 4[67
+2[47 37 48 51 1[51 49 60 41 2[24 49 51 43 45 50 47 46
+49 6[19 33 5[33 33 33 33 33 19 22 19 2[26 26 19 51 3[33
+19[56 38 38 39 11[{}65 58.1154 /CMR7 rf /Ff 129[35 1[35
+1[35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 1[35
+35 35 35 35 35 35 35 35 2[35 35 35 35 2[35 2[35 35 35
+35 1[35 35 35 35 35 2[35 35 35 1[35 35 35 35 35 35 35
+35 35 35 35 35 6[35 35 35 1[35 35 35 35 35 35 35 35 35
+35 3[35 35 33[{}71 66.4176 /CMTT8 rf /Fg 134[50 50 1[50
+53 37 38 39 50 53 48 53 80 27 50 1[27 53 48 29 44 53
+42 53 46 7[72 2[72 1[66 53 72 72 65 72 75 91 57 75 1[36
+75 75 60 63 73 69 68 72 19[32 27 31[53 12[{}47 83.022
+/CMBX10 rf /Fh 134[32 1[43 32 34 24 24 24 1[34 30 34
+50 18 32 19 18 34 30 19 27 34 27 34 30 8[45 61 45 45
+43 1[44 1[41 47 45 54 38 1[31 2[47 1[41 46 43 42 1[47
+4[18 1[30 1[30 30 2[30 30 30 30 1[18 1[18 2[24 24 40[{}53
+49.8132 /CMR6 rf /Fi 137[59 62 44 1[46 3[62 2[59 1[31
+2[34 51 1[50 1[54 14[84 84 1[84 79[{}14 99.6264 /CMBX12
+rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%BeginPaperSize: Letter
+<< /PageSize [612 792] >> setpagedevice
+%%EndPaperSize
+ @landscape end
+%%EndSetup
+%%Page: 1 1
+TeXDict begin @landscape 1 0 bop -450 -367 a Fi(Octa)m(v)m(e)28
+b(Quic)m(k)g(Reference)91 b Fh(Octa)n(v)n(e)29 b(V)-5
+b(ersion)27 b(3.0.0)-450 -207 y Fg(Starting)h(Octa)m(v)m(e)-450
+-116 y Ff(octave)409 b Fe(start)28 b(in)n(teractiv)n(e)e(Octa)n(v)n(e)h
+(session)-450 -41 y Ff(octave)i Fd(\014le)291 b Fe(run)27
+b(Octa)n(v)n(e)g(on)h(commands)e(in)h Fd(\014le)-450
+34 y Ff(octave)i(--eval)h Fd(c)m(o)m(de)12 b Fe(Ev)l(aluate)27
+b Fd(c)m(o)m(de)f Fe(using)h(Octa)n(v)n(e)-450 109 y
+Ff(octave)i(--help)170 b Fe(describ)r(e)26 b(command)g(line)g(options)
+-450 281 y Fg(Stopping)h(Octa)m(v)m(e)-450 372 y Ff(quit)i
+Fe(or)f Ff(exit)223 b Fe(exit)27 b(Octa)n(v)n(e)-450
+455 y Ff(INTERRUPT)304 b Fe(\()p Fd(e.g.)42 b Ff(C-c)p
+Fe(\))28 b(terminate)e(curren)n(t)g(command)211 530 y(and)h(return)f
+(to)i(top-lev)n(el)e(prompt)-450 698 y Fg(Getting)h(Help)-450
+790 y Ff(help)479 b Fe(list)28 b(all)f(commands)f(and)h(built-in)g(v)l
+(ariables)-450 865 y Ff(help)i Fd(c)m(ommand)166 b Fe(brie\015y)26
+b(describ)r(e)g Fd(c)m(ommand)-450 939 y Ff(doc)514 b
+Fe(use)27 b(Info)g(to)h(bro)n(wse)g(Octa)n(v)n(e)f(man)n(ual)-450
+1014 y Ff(doc)i Fd(c)m(ommand)201 b Fe(searc)n(h)27 b(for)h
+Fd(c)m(ommand)e Fe(in)h(Octa)n(v)n(e)g(man)n(ual)-450
+1089 y Ff(lookfor)j Fd(str)264 b Fe(searc)n(h)27 b(for)h
+Fd(c)m(ommand)e Fe(based)h(on)g Fd(str)-450 1238 y Fg(Motion)f(in)i
+(Info)-450 1329 y Ff(SPC)h Fe(or)e Ff(C-v)294 b Fe(scroll)27
+b(forw)n(ard)h(one)f(screenful)-450 1404 y Ff(DEL)i Fe(or)e
+Ff(M-v)294 b Fe(scroll)27 b(bac)n(kw)n(ard)h(one)f(screenful)-450
+1479 y Ff(C-l)514 b Fe(redra)n(w)28 b(the)f(displa)n(y)-450
+1647 y Fg(No)s(de)g(Selection)f(in)h(Info)-450 1739 y
+Ff(n)584 b Fe(select)27 b(the)f(next)h(no)r(de)-450 1814
+y Ff(p)584 b Fe(select)27 b(the)f(previous)h(no)r(de)-450
+1888 y Ff(u)584 b Fe(select)27 b(the)f(`up')h(no)r(de)-450
+1963 y Ff(t)584 b Fe(select)27 b(the)f(`top')h(no)r(de)-450
+2038 y Ff(d)584 b Fe(select)27 b(the)f(directory)g(no)r(de)-450
+2112 y Ff(<)584 b Fe(select)27 b(the)f(\014rst)i(no)r(de)e(in)h(the)g
+(curren)n(t)f(\014le)-450 2187 y Ff(>)584 b Fe(select)27
+b(the)f(last)i(no)r(de)f(in)g(the)g(curren)n(t)f(\014le)-450
+2262 y Ff(g)584 b Fe(reads)28 b(the)e(name)h(of)g(a)h(no)r(de)e(and)h
+(selects)g(it)-450 2337 y Ff(C-x)i(k)450 b Fe(kills)28
+b(the)e(curren)n(t)g(no)r(de)-450 2486 y Fg(Searc)m(hing)i(in)g(Info)
+-450 2577 y Ff(s)584 b Fe(searc)n(h)27 b(for)h(a)f(string)-450
+2652 y Ff(C-s)514 b Fe(searc)n(h)27 b(forw)n(ard)h(incremen)n(tally)
+-450 2727 y Ff(C-r)514 b Fe(searc)n(h)27 b(bac)n(kw)n(ard)h(incremen)n
+(tally)-450 2801 y Ff(i)584 b Fe(searc)n(h)27 b(index)f(&)i(go)g(to)g
+(corresp)r(onding)d(no)r(de)-450 2876 y Ff(,)584 b Fe(go)28
+b(to)g(next)f(matc)n(h)f(from)h(last)h(`i')f(command)-450
+3045 y Fg(Command-Line)g(Cursor)g(Motion)-450 3136 y
+Ff(C-b)514 b Fe(mo)n(v)n(e)27 b(bac)n(k)g(one)g(c)n(haracter)-450
+3211 y Ff(C-f)514 b Fe(mo)n(v)n(e)27 b(forw)n(ard)h(one)f(c)n(haracter)
+-450 3286 y Ff(C-a)514 b Fe(mo)n(v)n(e)27 b(to)h(the)f(start)h(of)f
+(the)g(line)-450 3360 y Ff(C-e)514 b Fe(mo)n(v)n(e)27
+b(to)h(the)f(end)f(of)i(the)f(line)-450 3435 y Ff(M-f)514
+b Fe(mo)n(v)n(e)27 b(forw)n(ard)h(a)g(w)n(ord)-450 3510
+y Ff(M-b)514 b Fe(mo)n(v)n(e)27 b(bac)n(kw)n(ard)h(a)g(w)n(ord)-450
+3584 y Ff(C-l)514 b Fe(clear)27 b(screen,)f(reprin)n(ting)g(curren)n(t)
+g(line)g(at)i(top)-450 3753 y Fg(Inserting)f(or)h(Changing)f(T)-8
+b(ext)-450 3844 y Ff(M-TAB)444 b Fe(insert)27 b(a)h(tab)f(c)n(haracter)
+-450 3919 y Ff(DEL)514 b Fe(delete)26 b(c)n(haracter)g(to)i(the)f(left)
+f(of)h(the)g(cursor)-450 3994 y Ff(C-d)514 b Fe(delete)26
+b(c)n(haracter)g(under)g(the)h(cursor)-450 4068 y Ff(C-v)514
+b Fe(add)27 b(the)g(next)g(c)n(haracter)f(v)n(erbatim)-450
+4143 y Ff(C-t)514 b Fe(transp)r(ose)27 b(c)n(haracters)g(at)g(the)g(p)r
+(oin)n(t)-450 4218 y Ff(M-t)514 b Fe(transp)r(ose)27
+b(w)n(ords)i(at)e(the)g(p)r(oin)n(t)-450 4350 y Fc([)h(])f
+Fh(surround)h(optional)f(argumen)n(ts)124 b(...)41 b(sho)n(w)28
+b(one)g(or)g(more)h(argumen)n(ts)p 1599 -433 1 17 v 1599
+4350 V 1750 -367 a Fg(Killing)d(and)i(Y)-8 b(anking)1750
+-276 y Ff(C-k)515 b Fe(kill)27 b(to)g(the)g(end)g(of)g(the)g(line)1750
+-201 y Ff(C-y)515 b Fe(y)n(ank)27 b(the)g(most)g(recen)n(tly)f(killed)g
+(text)1750 -126 y Ff(M-d)515 b Fe(kill)27 b(to)g(the)g(end)g(of)g(the)g
+(curren)n(t)f(w)n(ord)1750 -51 y Ff(M-DEL)445 b Fe(kill)27
+b(the)f(w)n(ord)i(b)r(ehind)e(the)h(cursor)1750 23 y
+Ff(M-y)515 b Fe(rotate)27 b(the)g(kill)g(ring)g(and)g(y)n(ank)g(the)g
+(new)g(top)1750 195 y Fg(Command)g(Completion)f(and)i(History)1750
+287 y Ff(TAB)515 b Fe(complete)25 b(a)j(command)d(or)j(v)l(ariable)f
+(name)1750 361 y Ff(M-?)515 b Fe(list)27 b(p)r(ossible)g(completions)
+1750 436 y Ff(RET)515 b Fe(en)n(ter)26 b(the)h(curren)n(t)f(line)1750
+511 y Ff(C-p)515 b Fe(mo)n(v)n(e)27 b(`up')f(through)h(the)g(history)g
+(list)1750 585 y Ff(C-n)515 b Fe(mo)n(v)n(e)27 b(`do)n(wn')g(through)g
+(the)g(history)g(list)1750 660 y Ff(M-<)515 b Fe(mo)n(v)n(e)27
+b(to)g(the)g(\014rst)h(line)e(in)h(the)g(history)1750
+735 y Ff(M->)515 b Fe(mo)n(v)n(e)27 b(to)g(the)g(last)h(line)e(in)i
+(the)e(history)1750 810 y Ff(C-r)515 b Fe(searc)n(h)27
+b(bac)n(kw)n(ard)g(in)g(the)g(history)g(list)1750 884
+y Ff(C-s)515 b Fe(searc)n(h)27 b(forw)n(ard)g(in)g(the)g(history)g
+(list)1750 983 y Ff(history)j Fc([)p Fe(-q)p Fc(])e([)p
+Fd(N)9 b Fc(])109 b Fe(list)27 b Fd(N)37 b Fe(previous)26
+b(history)i(lines,)e(omitting)2411 1058 y(history)h(n)n(um)n(b)r(ers)g
+(if)g Ff(-q)1750 1159 y(history)j(-w)e Fc([)p Fd(\014le)p
+Fc(])112 b Fe(write)27 b(history)g(to)h Fd(\014le)k Fe(\()p
+Ff(~/.octave)p 3327 1159 22 4 v 28 w(hist)d Fe(if)2411
+1234 y(no)f Fd(\014le)j Fe(argumen)n(t\))1750 1336 y
+Ff(history)f(-r)e Fc([)p Fd(\014le)p Fc(])112 b Fe(read)26
+b(history)i(from)f Fd(\014le)32 b Fe(\()p Ff(~/.octave)p
+3380 1336 V 27 w(hist)d Fe(if)2411 1411 y(no)f Fd(\014le)j
+Fe(argumen)n(t\))1750 1491 y Ff(edit)p 1894 1491 V 27
+w(history)e Fd(lines)42 b Fe(edit)26 b(and)h(then)g(run)g(previous)f
+(commands)2411 1565 y(from)h(the)g(history)g(list)1750
+1642 y Ff(run)p 1859 1642 V 27 w(history)i Fd(lines)77
+b Fe(run)27 b(previous)f(commands)g(from)h(the)g(history)2411
+1717 y(list)1821 1804 y Fc([)p Fd(b)m(e)m(g)5 b Fc(])26
+b([)p Fd(end)5 b Fc(])226 b Fe(Sp)r(ecify)25 b(the)h(\014rst)i(and)f
+(last)h(history)2411 1879 y(commands)e(to)i(edit)f(or)g(run.)1833
+1950 y(If)h Fd(b)m(e)m(g)i Fe(is)e(greater)f(than)g Fd(end)p
+Fe(,)g(rev)n(erse)g(the)g(list)g(of)h(commands)1833 2025
+y(b)r(efore)e(editing.)40 b(If)27 b Fd(end)33 b Fe(is)28
+b(omitted,)e(select)g(commands)g(from)1833 2100 y Fd(b)m(e)m(g)31
+b Fe(to)d(the)f(end)f(of)h(the)g(history)h(list.)41 b(If)27
+b(b)r(oth)g(argumen)n(ts)f(are)1833 2174 y(omitted,)g(edit)h(the)g
+(previous)f(item)h(in)g(the)g(history)g(list.)1750 2324
+y Fg(Shell)g(Commands)1750 2415 y Ff(cd)i Fd(dir)436
+b Fe(c)n(hange)26 b(w)n(orking)i(directory)e(to)h Fd(dir)1750
+2490 y Ff(pwd)515 b Fe(prin)n(t)26 b(w)n(orking)i(directory)1750
+2592 y Ff(ls)h Fc([)p Fd(options)p Fc(])260 b Fe(prin)n(t)26
+b(directory)g(listing)1750 2684 y Ff(getenv)k(\()p Fd(string)p
+Ff(\))139 b Fe(return)26 b(v)l(alue)h(of)g(named)g(en)n(vironmen)n(t)
+2411 2758 y(v)l(ariable)1750 2829 y Ff(system)j(\()p
+Fd(cmd)p Ff(\))187 b Fe(execute)25 b(arbitrary)i(shell)g(command)e
+(string)1750 3001 y Fg(Matrices)1750 3073 y Fe(Square)i(brac)n(k)n(ets)
+g(delimit)e(literal)i(matrices.)40 b(Commas)28 b(separate)1750
+3148 y(elemen)n(ts)e(on)h(the)g(same)g(ro)n(w.)42 b(Semicolons)26
+b(separate)h(ro)n(ws.)42 b(Commas)1750 3222 y(ma)n(y)28
+b(b)r(e)e(replaced)g(b)n(y)h(spaces,)g(and)g(semicolons)f(ma)n(y)i(b)r
+(e)e(replaced)g(b)n(y)1750 3297 y(one)h(or)h(more)f(newlines.)40
+b(Elemen)n(ts)25 b(of)j(a)g(matrix)e(ma)n(y)i(b)r(e)e(arbitrary)1750
+3372 y(expressions,)h(assuming)g(all)g(the)g(dimensions)f(agree.)1750
+3477 y Ff([)i Fd(x)p Ff(,)g Fd(y)p Ff(,)g(...)42 b(])184
+b Fe(en)n(ter)26 b(a)i(ro)n(w)g(v)n(ector)1750 3551 y
+Ff([)g Fd(x)p Ff(;)g Fd(y)p Ff(;)g(...)42 b(])184 b Fe(en)n(ter)26
+b(a)i(column)e(v)n(ector)1750 3636 y Ff([)i Fd(w)p Ff(,)g
+Fd(x)p Ff(;)g Fd(y)p Ff(,)g Fd(z)g Ff(])167 b Fe(en)n(ter)26
+b(a)i(2)p Fb(\002)p Fe(2)f(matrix)1750 3805 y Fg(Multi-dimensional)d
+(Arra)m(ys)1750 3892 y Fe(Multi-dimensional)h(arra)n(ys)j(ma)n(y)g(b)r
+(e)e(created)g(with)i(the)f Fd(c)m(at)g Fe(or)1750 3967
+y Fd(r)m(eshap)m(e)g Fe(commands)f(from)h(t)n(w)n(o-dimensional)g
+(sub-matrices.)1750 4072 y Ff(squeeze)j(\()p Fd(arr)p
+Ff(\))182 b Fe(remo)n(v)n(e)26 b(singleton)h(dimensions)f(of)h(the)g
+(arra)n(y)-5 b(.)1750 4158 y Ff(ndims)29 b(\()p Fd(arr)p
+Ff(\))253 b Fe(n)n(um)n(b)r(er)25 b(of)j(dimensions)e(in)h(the)g(arra)n
+(y)-5 b(.)1750 4232 y Ff(permute)30 b(\()p Fd(arr)p Ff(,)e
+Fd(p)p Ff(\))84 b Fe(p)r(erm)n(ute)25 b(the)i(dimensions)f(of)h(an)h
+(arra)n(y)-5 b(.)1750 4318 y Ff(ipermute)30 b(\()p Fd(arr)p
+Ff(,)f Fd(p)p Ff(\))48 b Fe(arra)n(y)27 b(in)n(v)n(erse)g(p)r(erm)n
+(utation.)p 3800 -433 1 17 v 3800 4350 V 3951 -367 a
+Ff(shiftdim)j(\()p Fd(arr)p Ff(,)e Fd(s)p Ff(\))55 b
+Fe(rotate)27 b(the)g(arra)n(y)h(dimensions.)3951 -292
+y Ff(circshift)i(\()p Fd(arr)p Ff(,)e Fd(s)p Ff(\))20
+b Fe(rotate)27 b(the)g(arra)n(y)h(elemen)n(ts.)3951 -124
+y Fg(Sparse)f(Matrices)3951 -32 y Ff(sparse)i(\(...\))205
+b Fe(create)26 b(a)i(sparse)f(matrix.)3951 53 y Ff(speye)i(\()p
+Fd(n\))314 b Fe(create)26 b(sparse)i(iden)n(tify)d(matrix.)3951
+139 y Ff(sprand)k(\()p Fd(n)p Ff(,)g Fd(m)p Ff(,)e Fd(d)p
+Ff(\))55 b Fe(sparse)27 b(rand)g(matrix)g(of)h(densit)n(y)e
+Fd(d)p Fe(.)3951 225 y Ff(spdiags)j(\(...\))170 b Fe(sparse)27
+b(generalization)f(of)h Fd(diag)p Fe(.)3951 311 y Ff(nnz)h(\()p
+Fd(s)p Ff(\))388 b Fe(No.)41 b(non-zero)27 b(elemen)n(ts)f(in)h(sparse)
+g(matrix.)3951 479 y Fg(Ranges)3951 570 y Fd(b)m(ase)f
+Ff(:)42 b Fd(limit)3951 645 y(b)m(ase)26 b Ff(:)42 b
+Fd(incr)28 b Ff(:)42 b Fd(limit)3951 729 y Fe(Sp)r(ecify)25
+b(a)i(range)g(of)h(v)l(alues)f(b)r(eginning)f(with)h
+Fd(b)m(ase)k Fe(with)d(no)3951 803 y(elemen)n(ts)d(greater)i(than)g
+Fd(limit)p Fe(.)42 b(If)27 b(it)g(is)h(omitted,)e(the)h(default)3951
+878 y(v)l(alue)g(of)g Fd(incr)34 b Fe(is)28 b(1.)42 b(Negativ)n(e)26
+b(incremen)n(ts)g(are)h(p)r(ermitted.)3951 1028 y Fg(Strings)g(and)h
+(Common)e(Escap)s(e)h(Sequences)3951 1122 y Fe(A)g Fd(string)i(c)m
+(onstant)34 b Fe(consists)27 b(of)h(a)f(sequence)f(of)h(c)n(haracters)f
+(enclosed)3951 1196 y(in)h(either)f(double-quote)f(or)j(single-quote)e
+(marks.)41 b(Strings)27 b(in)3951 1271 y(double-quotes)e(allo)n(w)j
+(the)f(use)g(of)h(the)f(escap)r(e)f(sequences)f(b)r(elo)n(w.)3951
+1376 y Ff(\\\\)549 b Fe(a)28 b(literal)e(bac)n(kslash)3951
+1451 y Ff(\\")549 b Fe(a)28 b(literal)e(double-quote)g(c)n(haracter)
+3951 1525 y Ff(\\')549 b Fe(a)28 b(literal)e(single-quote)h(c)n
+(haracter)3951 1600 y Ff(\\n)549 b Fe(newline,)26 b(ASCI)r(I)h(co)r(de)
+f(10)3951 1675 y Ff(\\t)549 b Fe(horizon)n(tal)26 b(tab,)i(ASCI)r(I)f
+(co)r(de)f(9)3951 1843 y Fg(Index)i(Expressions)3951
+1935 y Fd(var)f Ff(\()p Fd(idx)p Ff(\))338 b Fe(select)26
+b(elemen)n(ts)g(of)h(a)h(v)n(ector)3951 2009 y Fd(var)f
+Ff(\()p Fd(idx1)p Ff(,)h Fd(idx2)p Ff(\))117 b Fe(select)26
+b(elemen)n(ts)g(of)h(a)h(matrix)4021 2084 y Fd(sc)m(alar)375
+b Fe(select)26 b(ro)n(w)i(\(column\))e(corresp)r(onding)g(to)4611
+2159 y Fd(sc)m(alar)4021 2227 y(ve)m(ctor)369 b Fe(select)26
+b(ro)n(ws)j(\(columns\))d(corresp)r(onding)f(to)j(the)4611
+2302 y(elemen)n(ts)e(of)h Fd(ve)m(ctor)4021 2370 y(r)m(ange)386
+b Fe(select)26 b(ro)n(ws)j(\(columns\))d(corresp)r(onding)f(to)j(the)
+4611 2445 y(elemen)n(ts)e(of)h Fd(r)m(ange)4021 2525
+y Ff(:)514 b Fe(select)26 b(all)h(ro)n(ws)i(\(columns\))3951
+2697 y Fg(Global)e(and)h(P)m(ersisten)m(t)f(V)-8 b(ariables)3951
+2788 y Ff(global)29 b Fd(var1)e Ff(...)117 b Fe(Declare)26
+b(v)l(ariables)h(global.)3951 2863 y Ff(global)i Fd(var1)e
+Ff(=)h Fd(val)74 b Fe(Declare)26 b(v)l(ariable)h(global.)41
+b(Set)26 b(in)n(tial)h(v)l(alue.)3951 2938 y Ff(persistent)j
+Fd(var1)108 b Fe(Declare)26 b(a)i(v)l(ariable)f(as)h(static)f(to)h(a)f
+(function.)3951 3012 y Ff(persistent)j Fd(var1)e Ff(=)3951
+3087 y Fd(val)4570 3012 y Fe(Declare)e(a)i(v)l(ariable)f(as)h(static)f
+(to)h(a)f(function)4611 3087 y(and)g(set)h(its)g(initial)e(v)l(alue.)
+3951 3158 y(Global)h(v)l(ariables)g(ma)n(y)h(b)r(e)e(accessed)g(inside)
+h(the)g(b)r(o)r(dy)f(of)i(a)f(function)3951 3233 y(without)g(ha)n(ving)
+g(to)h(b)r(e)e(passed)h(in)h(the)e(function)g(parameter)g(list)3951
+3308 y(pro)n(vided)g(they)g(are)i(declared)d(global)i(when)g(used.)3951
+3457 y Fg(Selected)g(Built-in)f(F)-8 b(unctions)3951
+3549 y Ff(EDITOR)409 b Fe(editor)27 b(to)g(use)g(with)h
+Ff(edit)p 5275 3549 22 4 v 26 w(history)3951 3623 y(Inf,)g(NaN)346
+b Fe(IEEE)26 b(in\014nit)n(y)-5 b(,)26 b(NaN)3951 3698
+y Ff(NA)549 b Fe(Missing)27 b(v)l(alue)3951 3773 y Ff(PAGER)444
+b Fe(program)27 b(to)h(use)f(to)g(paginate)g(output)3951
+3848 y Ff(ans)514 b Fe(last)28 b(result)f(not)g(explicitly)e(assigned)
+3951 3922 y Ff(eps)514 b Fe(mac)n(hine)26 b(precision)3951
+3997 y Ff(pi)549 b Fa(\031)3951 4109 y Ff(1i)4570 4043
+y Fb(p)p 4639 4043 107 4 v 66 x(\000)p Fc(1)3951 4183
+y Ff(realmax)374 b Fe(maxim)n(um)26 b(represen)n(table)f(v)l(alue)3951
+4258 y Ff(realmin)374 b Fe(minim)n(um)25 b(represen)n(table)g(v)l(alue)
+3963 4350 y Fh(Cop)n(yrigh)n(t)k(1996,)g(1997,)g(2007)g(John)f(W.)f
+(Eaton)122 b(P)n(ermissions)28 b(on)g(bac)n(k)p eop end
+%%Page: 2 2
+TeXDict begin @landscape 2 1 bop -450 -367 a Fg(Assignmen)m(t)26
+b(Expressions)-450 -276 y Fd(var)h Ff(=)h Fd(expr)305
+b Fe(assign)28 b(expression)f(to)g(v)l(ariable)-450 -201
+y Fd(var)g Ff(\()p Fd(idx)p Ff(\))i(=)f Fd(expr)118 b
+Fe(assign)28 b(expression)f(to)g(indexed)f(v)l(ariable)-450
+-126 y Fd(var)h Ff(\()p Fd(idx)p Ff(\))i(=)f([])176 b
+Fe(delete)26 b(the)h(indexed)e(elemen)n(ts.)-450 -34
+y Fd(var)i Fb(f)p Fd(idx)p Fb(g)g Ff(=)h Fd(expr)106
+b Fe(assign)28 b(elemen)n(ts)e(of)h(a)h(cell)e(arra)n(y)-5
+b(.)-450 145 y Fg(Arithmetic)27 b(and)h(Incremen)m(t)h(Op)s(erators)
+-450 236 y Fd(x)e Ff(+)h Fd(y)464 b Fe(addition)-450
+311 y Fd(x)27 b Ff(-)h Fd(y)464 b Fe(subtraction)-450
+385 y Fd(x)27 b Ff(*)h Fd(y)464 b Fe(matrix)27 b(m)n(ultiplication)-450
+460 y Fd(x)g Ff(.*)i Fd(y)428 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)f
+(m)n(ultiplication)-450 535 y Fd(x)h Ff(/)h Fd(y)464
+b Fe(righ)n(t)28 b(division,)e(conceptually)f(equiv)l(alen)n(t)h(to)211
+609 y Ff(\(inverse)k(\(y'\))f(*)f(x'\)')-450 695 y Fd(x)f
+Ff(./)i Fd(y)428 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)f(righ)n(t)h
+(division)-450 770 y Fd(x)g Ff(\\)h Fd(y)464 b Fe(left)27
+b(division,)f(conceptually)f(equiv)l(alen)n(t)h(to)211
+845 y Ff(inverse)j(\(x\))g(*)f(y)-450 930 y Fd(x)f Ff(.\\)i
+Fd(y)428 b Fe(elemen)n(t)26 b(b)n(y)h(elemen)n(t)f(left)g(division)-450
+1005 y Fd(x)h Ff(^)h Fd(y)464 b Fe(p)r(o)n(w)n(er)28
+b(op)r(erator)-450 1080 y Fd(x)f Ff(.^)i Fd(y)428 b Fe(elemen)n(t)26
+b(b)n(y)h(elemen)n(t)f(p)r(o)n(w)n(er)h(op)r(erator)-450
+1155 y Ff(-)h Fd(x)524 b Fe(negation)-450 1229 y Ff(+)28
+b Fd(x)524 b Fe(unary)27 b(plus)g(\(a)h(no-op\))-450
+1304 y Fd(x)f Ff(')525 b Fe(complex)26 b(conjugate)g(transp)r(ose)-450
+1379 y Fd(x)h Ff(.')490 b Fe(transp)r(ose)-450 1454 y
+Ff(++)28 b Fd(x)70 b Fe(\()p Ff(--)29 b Fd(x)p Fe(\))236
+b(incremen)n(t)25 b(\(decremen)n(t\),)g(return)h Fd(new)34
+b Fe(v)l(alue)-450 1528 y Fd(x)27 b Ff(++)71 b Fe(\()p
+Fd(x)28 b Ff(--)p Fe(\))237 b(incremen)n(t)25 b(\(decremen)n(t\),)g
+(return)h Fd(old)33 b Fe(v)l(alue)-450 1700 y Fg(Comparison)27
+b(and)h(Bo)s(olean)e(Op)s(erators)-450 1800 y Fe(These)h(op)r(erators)g
+(w)n(ork)h(on)g(an)f(elemen)n(t-b)n(y-elemen)n(t)d(basis.)41
+b(Both)-450 1875 y(argumen)n(ts)27 b(are)g(alw)n(a)n(ys)i(ev)l
+(aluated.)-450 1980 y Fd(x)e Ff(<)h Fd(y)464 b Fe(true)27
+b(if)g Fd(x)35 b Fe(is)27 b(less)h(than)f Fd(y)-450 2054
+y(x)g Ff(<=)i Fd(y)428 b Fe(true)27 b(if)g Fd(x)35 b
+Fe(is)27 b(less)h(than)f(or)h(equal)e(to)i Fd(y)-450
+2129 y(x)f Ff(==)i Fd(y)428 b Fe(true)27 b(if)g Fd(x)35
+b Fe(is)27 b(equal)g(to)h Fd(y)-450 2204 y(x)f Ff(>=)i
+Fd(y)428 b Fe(true)27 b(if)g Fd(x)35 b Fe(is)27 b(greater)g(than)g(or)h
+(equal)e(to)i Fd(y)-450 2279 y(x)f Ff(>)h Fd(y)464 b
+Fe(true)27 b(if)g Fd(x)35 b Fe(is)27 b(greater)g(than)g
+Fd(y)-450 2353 y(x)g Ff(!=)i Fd(y)428 b Fe(true)27 b(if)g
+Fd(x)35 b Fe(is)27 b(not)h(equal)e(to)i Fd(y)-450 2428
+y(x)f Ff(&)h Fd(y)464 b Fe(true)27 b(if)g(b)r(oth)g Fd(x)34
+b Fe(and)27 b Fd(y)33 b Fe(are)28 b(true)-450 2503 y
+Fd(x)f Ff(|)h Fd(y)464 b Fe(true)27 b(if)g(at)h(least)f(one)g(of)g
+Fd(x)35 b Fe(or)28 b Fd(y)33 b Fe(is)27 b(true)-450 2577
+y Ff(!)42 b Fd(b)m(o)m(ol)428 b Fe(true)27 b(if)g Fd(b)m(o)m(ol)32
+b Fe(is)c(false)-450 2727 y Fg(Short-circuit)g(Bo)s(olean)f(Op)s
+(erators)-450 2827 y Fe(Op)r(erators)g(ev)l(aluate)g(left-to-righ)n(t.)
+40 b(Op)r(erands)26 b(are)i(only)f(ev)l(aluated)f(if)-450
+2902 y(necessary)-5 b(,)26 b(stopping)h(once)f(o)n(v)n(erall)h(truth)g
+(v)l(alue)g(can)g(b)r(e)g(determined.)-450 2977 y(Op)r(erands)f(are)i
+(con)n(v)n(erted)d(to)j(scalars)g(using)f(the)g Ff(all)h
+Fe(function.)-450 3081 y Fd(x)f Ff(&&)i Fd(y)428 b Fe(true)27
+b(if)g(b)r(oth)g Fd(x)34 b Fe(and)27 b Fd(y)33 b Fe(are)28
+b(true)-450 3156 y Fd(x)f Ff(||)i Fd(y)428 b Fe(true)27
+b(if)g(at)h(least)f(one)g(of)g Fd(x)35 b Fe(or)28 b Fd(y)33
+b Fe(is)27 b(true)-450 3325 y Fg(Op)s(erator)h(Precedence)-450
+3419 y Fe(T)-5 b(able)27 b(of)g(Octa)n(v)n(e)g(op)r(erators,)g(in)g
+(order)g(of)g(increasing)f(precedence.)-450 3523 y Ff(;)56
+b(,)493 b Fe(statemen)n(t)27 b(separators)-450 3598 y
+Ff(=)584 b Fe(assignmen)n(t,)27 b(groups)g(left)g(to)h(righ)n(t)-450
+3673 y Ff(||)56 b(&&)423 b Fe(logical)27 b(\\or")h(and)f(\\and")-450
+3747 y Ff(|)56 b(&)493 b Fe(elemen)n(t-wise)26 b(\\or")i(and)f(\\and")
+-450 3822 y Ff(<)h(<=)g(==)g(>=)h(>)f(!=)128 b Fe(relational)27
+b(op)r(erators)-450 3897 y Ff(:)584 b Fe(colon)-450 3972
+y Ff(+)56 b(-)493 b Fe(addition)27 b(and)g(subtraction)-450
+4046 y Ff(*)h(/)g(\\)56 b(.*)f(./)h(.\\)81 b Fe(m)n(ultiplication)25
+b(and)i(division)-450 4121 y Ff(')56 b(.')458 b Fe(transp)r(ose)-450
+4196 y Ff(+)56 b(-)f(++)h(--)g(!)151 b Fe(unary)27 b(min)n(us,)g
+(incremen)n(t,)e(logical)i(\\not")-450 4271 y Ff(^)56
+b(.^)458 b Fe(exp)r(onen)n(tiation)p 1599 -433 1 17 v
+1599 4350 V 1750 -367 a Fg(P)m(aths)29 b(and)f(P)m(ac)m(k)-5
+b(ages)1750 -276 y Ff(path)480 b Fe(displa)n(y)27 b(the)f(curren)n(t)h
+(Octa)n(v)n(e)g(cunction)e(path.)1750 -201 y Ff(pathdef)375
+b Fe(displa)n(y)27 b(the)f(default)g(path.)1750 -115
+y Ff(addpath\()p Fd(dir)p Ff(\))220 b Fe(add)27 b(a)g(directory)f(to)i
+(the)f(path.)1750 -40 y Ff(EXEC)p 1894 -40 22 4 v 27
+w(PATH)313 b Fe(manipulate)25 b(the)i(Octa)n(v)n(e)g(executable)e
+(path.)1750 34 y Ff(pkg)k(list)346 b Fe(displa)n(y)27
+b(installed)f(pac)n(k)l(ages.)1750 109 y Ff(pkg)j(load)g
+Fd(p)m(ack)186 b Fe(Load)27 b(an)h(installed)e(pac)n(k)l(age.)1750
+281 y Fg(Cells)g(and)j(Structures)1750 372 y Fd(var)p
+Ff(.)p Fd(\014eld)f Ff(=)g(...)169 b Fe(set)27 b(a)h(\014eld)e(of)h(a)h
+(structure.)1750 471 y Fd(var)p Fb(f)p Fd(idx)p Fb(g)f
+Ff(=)h(...)157 b Fe(set)27 b(an)g(elemen)n(t)f(of)h(a)h(cell)e(arra)n
+(y)-5 b(.)1750 563 y Ff(cellfun\()p Fd(f)p Ff(,)31 b
+Fd(c)p Ff(\))186 b Fe(apply)26 b(a)i(function)e(to)h(elemen)n(ts)f(of)h
+(cell)g(arra)n(y)-5 b(.)1750 637 y Ff(fieldnames\()p
+Fd(s)p Ff(\))172 b Fe(returns)26 b(the)h(\014elds)g(of)g(a)h
+(structure.)1750 799 y Fg(Statemen)m(ts)1750 896 y Ff(for)h
+Fd(identi\014er)g Ff(=)f Fd(expr)f(stmt-list)h Ff(endfor)1833
+979 y Fe(Execute)e Fd(stmt-list)i Fe(once)e(for)i(eac)n(h)e(column)g
+(of)i Fd(expr)p Fe(.)40 b(The)1833 1054 y(v)l(ariable)27
+b Fd(identi\014er)i Fe(is)f(set)f(to)h(the)f(v)l(alue)g(of)g(the)g
+(curren)n(t)f(column)1833 1128 y(during)h(eac)n(h)f(iteration.)1750
+1284 y Ff(while)j(\()p Fd(c)m(ondition)p Ff(\))h Fd(stmt-list)e
+Ff(endwhile)1833 1364 y Fe(Execute)e Fd(stmt-list)i Fe(while)f
+Fd(c)m(ondition)i Fe(is)e(true.)1750 1502 y Ff(break)472
+b Fe(exit)27 b(innermost)f(lo)r(op)1750 1577 y Ff(continue)367
+b Fe(go)28 b(to)g(b)r(eginning)d(of)j(innermost)e(lo)r(op)1750
+1651 y Ff(return)437 b Fe(return)27 b(to)g(calling)g(function)1750
+1825 y Ff(if)i(\()p Fd(c)m(ondition)p Ff(\))g Fd(if-b)m(o)m(dy)f
+Fc([)p Ff(else)g Fd(else-b)m(o)m(dy)p Fc(])f Ff(endif)1833
+1917 y Fe(Execute)f Fd(if-b)m(o)m(dy)h Fe(if)g Fd(c)m(ondition)i
+Fe(is)f(true,)e(otherwise)h(execute)f Fd(else-)1833 1992
+y(b)m(o)m(dy)p Fe(.)1750 2090 y Ff(if)j(\()p Fd(c)m(ondition)p
+Ff(\))g Fd(if-b)m(o)m(dy)f Fc([)p Ff(elseif)h Fe(\()p
+Fd(c)m(ondition)p Fe(\))g Fd(elseif-b)m(o)m(dy)p Fc(])e
+Ff(endif)1833 2182 y Fe(Execute)f Fd(if-b)m(o)m(dy)h
+Fe(if)g Fd(c)m(ondition)i Fe(is)f(true,)e(otherwise)h(execute)f(the)
+1833 2257 y Fd(elseif-b)m(o)m(dy)h Fe(corresp)r(onding)f(to)i(the)e
+(\014rst)i Ff(elseif)h Fe(condition)d(that)1833 2332
+y(is)i(true,)f(otherwise)f(execute)g Fd(else-b)m(o)m(dy)p
+Fe(.)1833 2415 y(An)n(y)i(n)n(um)n(b)r(er)e(of)h Ff(elseif)i
+Fe(clauses)e(ma)n(y)h(app)r(ear)e(in)h(an)h Ff(if)1833
+2490 y Fe(statemen)n(t.)1750 2624 y Ff(unwind)p 1964
+2624 V 27 w(protect)i Fd(b)m(o)m(dy)d Ff(unwind)p 2632
+2624 V 27 w(protect)p 2904 2624 V 28 w(cleanup)i Fd(cle)m(anup)e
+Ff(end)1833 2711 y Fe(Execute)f Fd(b)m(o)m(dy)p Fe(.)40
+b(Execute)26 b Fd(cle)m(anup)g Fe(no)i(matter)f(ho)n(w)h(con)n(trol)f
+(exits)1833 2785 y Fd(b)m(o)m(dy)p Fe(.)1750 2856 y Ff(try)i
+Fd(b)m(o)m(dy)e Ff(catch)i Fd(cle)m(anup)e Ff(end)1833
+2935 y Fe(Execute)f Fd(b)m(o)m(dy)p Fe(.)40 b(Execute)26
+b Fd(cle)m(anup)g Fe(if)h Fd(b)m(o)m(dy)g Fe(fails.)1750
+3112 y Fg(Strings)1750 3203 y Ff(strcmp)j(\()p Fd(s)p
+Ff(,)e Fd(t)p Ff(\))406 b Fe(compare)26 b(strings)1750
+3289 y Ff(strcat)k(\()p Fd(s)p Ff(,)e Fd(t)p Ff(,)g(...\))238
+b Fe(concatenate)25 b(strings)1750 3364 y Ff(regexp)30
+b(\()p Fd(str)p Ff(,)e Fd(p)m(at)p Ff(\))287 b Fe(strings)27
+b(matc)n(hing)g(regular)f(expression)1750 3450 y Ff(regexprep)31
+b(\()p Fd(str)p Ff(,)d Fd(p)m(at)p Ff(,)g Fd(r)m(ep)p
+Ff(\))d Fe(Matc)n(h)h(and)i(replace)d(sub-strings)1750
+3622 y Fg(De\014ning)i(F)-8 b(unctions)1750 3758 y Ff(function)30
+b Fc([)p Fd(r)m(et-list)p Fc(])e Fd(function-name)g Fc([)13
+b Fe(\()p Fd(ar)m(g-list)p Fe(\))h Fc(])1821 3842 y Fd(function-b)m(o)m
+(dy)1750 3928 y Ff(endfunction)1750 4068 y Fd(r)m(et-list)33
+b Fe(ma)n(y)28 b(b)r(e)e(a)i(single)f(iden)n(ti\014er)e(or)j(a)g
+(comma-separated)d(list)j(of)1750 4143 y(iden)n(ti\014ers)e(delimited)f
+(b)n(y)i(square-brac)n(k)n(ets.)1750 4238 y Fd(ar)m(g-list)33
+b Fe(is)28 b(a)g(comma-separated)d(list)j(of)f(iden)n(ti\014ers)f(and)h
+(ma)n(y)g(b)r(e)1750 4313 y(empt)n(y)-5 b(.)p 3800 -433
+1 17 v 3800 4350 V 3951 -367 a Fg(F)d(unction)27 b(Handles)3951
+-276 y Ff(@)p Fd(func)456 b Fe(De\014ne)26 b(a)i(function)d(handle)h
+(to)i Fd(func)p Fe(.)3951 -201 y Ff(@\()p Fd(var1)p Ff(,)g(...\))43
+b Fd(expr)h Fe(De\014ne)26 b(an)h(anon)n(ymous)g(function)f(handle.)
+3951 -126 y Ff(str2func)k(\()p Fd(str)p Ff(\))159 b Fe(Create)27
+b(a)h(function)d(handle)h(from)h(a)h(string.)3951 -51
+y Ff(functions)i(\()p Fd(hand)s(le)p Ff(\))8 b Fe(Return)26
+b(information)g(ab)r(out)h(a)h(function)4611 23 y(handle.)3951
+94 y Ff(func2str)i(\()p Fd(hand)s(le)p Ff(\))43 b Fe(Return)26
+b(a)i(string)g(represen)n(tation)d(of)j(a)4611 169 y(function)e
+(handle.)3951 240 y Fd(hand)s(le)i Ff(\()p Fd(ar)m(g1)p
+Ff(,)g(...\))h Fe(Ev)l(aluate)e(a)g(function)f(handle.)3951
+315 y Ff(feval)j(\()p Fd(func)p Ff(,)f Fd(ar)m(g1)p Ff(,)3951
+389 y(...\))4570 315 y Fe(Ev)l(aluate)f(a)g(function)f(handle)g(or)i
+(string,)4611 389 y(passing)g(remaining)e(args)i(to)g
+Fd(func)3951 472 y Fe(Anon)n(ymous)e(function)g(handles)g(tak)n(e)i(a)f
+(cop)n(y)g(of)h(the)f(v)l(ariables)g(in)3951 547 y(the)f(curren)n(t)g
+(w)n(orkspace.)3951 726 y Fg(Miscellaneous)f(F)-8 b(unctions)3951
+818 y Ff(eval)28 b(\()p Fd(str)p Ff(\))301 b Fe(ev)l(aluate)26
+b Fd(str)j Fe(as)f(a)f(command)3951 893 y Ff(error)i(\()p
+Fd(message)p Ff(\))102 b Fe(prin)n(t)27 b(message)g(and)g(return)f(to)i
+(top)f(lev)n(el)3951 967 y Ff(warning)i(\()p Fd(message)p
+Ff(\))j Fe(prin)n(t)27 b(a)h(w)n(arning)f(message)3951
+1042 y Ff(clear)i Fd(p)m(attern)203 b Fe(clear)26 b(v)l(ariables)i
+(matc)n(hing)e(pattern)3951 1117 y Ff(exist)j(\()p Fd(str)p
+Ff(\))265 b Fe(c)n(hec)n(k)26 b(existence)f(of)j(v)l(ariable)f(or)g
+(function)3951 1191 y Ff(who,)h(whos)311 b Fe(list)27
+b(curren)n(t)f(v)l(ariables)3951 1266 y Ff(whos)i Fd(var)355
+b Fe(details)27 b(of)g(the)g(v)l(aribale)g Fd(var)3951
+1416 y Fg(Basic)g(Matrix)h(Manipulations)3951 1507 y
+Ff(rows)g(\()p Fd(a)p Ff(\))346 b Fe(return)26 b(n)n(um)n(b)r(er)g(of)h
+(ro)n(ws)i(of)e Fd(a)3951 1582 y Ff(columns)i(\()p Fd(a)p
+Ff(\))240 b Fe(return)26 b(n)n(um)n(b)r(er)g(of)h(columns)g(of)g
+Fd(a)3951 1656 y Ff(all)h(\()p Fd(a)p Ff(\))381 b Fe(c)n(hec)n(k)26
+b(if)h(all)g(elemen)n(ts)f(of)i Fd(a)k Fe(nonzero)3951
+1731 y Ff(any)c(\()p Fd(a)p Ff(\))381 b Fe(c)n(hec)n(k)26
+b(if)h(an)n(y)h(elemen)n(ts)d(of)j Fd(a)k Fe(nonzero)3951
+1908 y Ff(find)c(\()p Fd(a)p Ff(\))346 b Fe(return)26
+b(indices)g(of)i(nonzero)e(elemen)n(ts)3951 1983 y Ff(sort)i(\()p
+Fd(a)p Ff(\))346 b Fe(order)27 b(elemen)n(ts)e(in)j(eac)n(h)e(column)g
+(of)i Fd(a)3951 2058 y Ff(sum)g(\()p Fd(a)p Ff(\))381
+b Fe(sum)27 b(elemen)n(ts)f(in)h(columns)f(of)h Fd(a)3951
+2132 y Ff(prod)h(\()p Fd(a)p Ff(\))346 b Fe(pro)r(duct)26
+b(of)h(elemen)n(ts)f(in)h(columns)f(of)i Fd(a)3951 2218
+y Ff(min)g(\()p Fd(ar)m(gs)p Ff(\))295 b Fe(\014nd)26
+b(minim)n(um)g(v)l(alues)3951 2293 y Ff(max)i(\()p Fd(ar)m(gs)p
+Ff(\))295 b Fe(\014nd)26 b(maxim)n(um)g(v)l(alues)3951
+2368 y Ff(rem)i(\()p Fd(x)p Ff(,)g Fd(y)p Ff(\))288 b
+Fe(\014nd)26 b(remainder)g(of)h Fd(x)p Fe(/)p Fd(y)3951
+2453 y Ff(reshape)i(\()p Fd(a)p Ff(,)g Fd(m)p Ff(,)e
+Fd(n)p Ff(\))20 b Fe(reformat)26 b Fd(a)i Fe(to)g(b)r(e)e
+Fd(m)h Fe(b)n(y)h Fd(n)3951 2539 y Ff(diag)g(\()p Fd(v)p
+Ff(,)g Fd(k)p Ff(\))254 b Fe(create)26 b(diagonal)h(matrices)3951
+2625 y Ff(linspace)j(\()p Fd(b)p Ff(,)d Fd(l)p Ff(,)h
+Fd(n)p Ff(\))e Fe(create)g(v)n(ector)h(of)g(linearly-spaced)f(elemen)n
+(ts)3951 2710 y Ff(logspace)k(\()p Fd(b)p Ff(,)d Fd(l)p
+Ff(,)h Fd(n)p Ff(\))e Fe(create)g(v)n(ector)h(of)g(log-spaced)g(elemen)
+n(ts)3951 2796 y Ff(eye)h(\()p Fd(n)p Ff(,)h Fd(m)p Ff(\))258
+b Fe(create)26 b Fd(n)33 b Fe(b)n(y)28 b Fd(m)k Fe(iden)n(tit)n(y)26
+b(matrix)3951 2882 y Ff(ones)i(\()p Fd(n)p Ff(,)h Fd(m)p
+Ff(\))223 b Fe(create)26 b Fd(n)33 b Fe(b)n(y)28 b Fd(m)k
+Fe(matrix)27 b(of)g(ones)3951 2957 y Ff(zeros)i(\()p
+Fd(n)p Ff(,)f Fd(m)p Ff(\))188 b Fe(create)26 b Fd(n)33
+b Fe(b)n(y)28 b Fd(m)k Fe(matrix)27 b(of)g(zeros)3951
+3032 y Ff(rand)h(\()p Fd(n)p Ff(,)h Fd(m)p Ff(\))223
+b Fe(create)26 b Fd(n)33 b Fe(b)n(y)28 b Fd(m)k Fe(matrix)27
+b(of)g(random)g(v)l(alues)3951 3200 y Fg(Linear)h(Algebra)3951
+3291 y Ff(chol)g(\()p Fd(a)p Ff(\))346 b Fe(Cholesky)27
+b(factorization)3951 3366 y Ff(det)h(\()p Fd(a)p Ff(\))381
+b Fe(compute)25 b(the)i(determinan)n(t)e(of)j(a)g(matrix)3951
+3441 y Ff(eig)g(\()p Fd(a)p Ff(\))381 b Fe(eigen)n(v)l(alues)26
+b(and)h(eigen)n(v)n(ectors)3951 3527 y Ff(expm)h(\()p
+Fd(a)p Ff(\))346 b Fe(compute)25 b(the)i(exp)r(onen)n(tial)f(of)h(a)h
+(matrix)3951 3612 y Ff(hess)g(\()p Fd(a)p Ff(\))346 b
+Fe(compute)25 b(Hessen)n(b)r(erg)i(decomp)r(osition)3951
+3687 y Ff(inverse)i(\()p Fd(a)p Ff(\))240 b Fe(in)n(v)n(ert)27
+b(a)g(square)h(matrix)3951 3762 y Ff(norm)g(\()p Fd(a)p
+Ff(,)h Fd(p)p Ff(\))247 b Fe(compute)25 b(the)i Fd(p)p
+Fe(-norm)h(of)f(a)h(matrix)3951 3837 y Ff(pinv)g(\()p
+Fd(a)p Ff(\))346 b Fe(compute)25 b(pseudoin)n(v)n(erse)h(of)h
+Fd(a)3951 3922 y Ff(qr)h(\()p Fd(a)p Ff(\))416 b Fe(compute)25
+b(the)i(QR)h(factorization)e(of)h(a)h(matrix)3951 4008
+y Ff(rank)g(\()p Fd(a)p Ff(\))346 b Fe(matrix)27 b(rank)3951
+4083 y Ff(sprank)i(\()p Fd(a)p Ff(\))275 b Fe(structrual)26
+b(matrix)h(rank)3951 4169 y Ff(schur)i(\()p Fd(a)p Ff(\))310
+b Fe(Sc)n(h)n(ur)26 b(decomp)r(osition)g(of)h(a)h(matrix)3951
+4243 y Ff(svd)g(\()p Fd(a)p Ff(\))381 b Fe(singular)27
+b(v)l(alue)g(decomp)r(osition)3951 4318 y Ff(syl)h(\()p
+Fd(a)p Ff(,)g Fd(b)p Ff(,)g Fd(c)p Ff(\))191 b Fe(solv)n(e)27
+b(the)g(Sylv)n(ester)f(equation)p eop end
+%%Page: 3 3
+TeXDict begin @landscape 3 2 bop -450 -367 a Fg(Equations,)27
+b(ODEs,)f(D)m(AEs,)i(Quadrature)-450 -276 y Ff(*fsolve)374
+b Fe(solv)n(e)28 b(nonlinear)e(algebraic)g(equations)-450
+-201 y Ff(*lsode)409 b Fe(in)n(tegrate)27 b(nonlinear)f(ODEs)-450
+-126 y Ff(*dassl)409 b Fe(in)n(tegrate)27 b(nonlinear)f(D)n(AEs)-450
+-51 y Ff(*quad)444 b Fe(in)n(tegrate)27 b(nonlinear)f(functions)-450
+34 y Ff(perror)j(\()p Fd(nm)p Ff(,)g Fd(c)m(o)m(de)p
+Ff(\))24 b Fe(for)k(functions)e(that)h(return)f(n)n(umeric)g(co)r(des,)
+211 109 y(prin)n(t)h(error)g(message)g(for)g(named)f(function)211
+184 y(and)h(giv)n(en)g(error)g(co)r(de)-450 285 y Ff(*)h
+Fe(See)e(the)h(on-line)g(or)g(prin)n(ted)g(man)n(ual)f(for)i(the)e
+(complete)g(list)h(of)-450 360 y(argumen)n(ts)g(for)g(these)g
+(functions.)-450 509 y Fg(Signal)g(Pro)s(cessing)-450
+601 y Ff(fft)i(\()p Fd(a)p Ff(\))380 b Fe(F)-5 b(ast)28
+b(F)-5 b(ourier)26 b(T)-5 b(ransform)27 b(using)g(FFTW)-450
+675 y Ff(ifft)i(\()p Fd(a)p Ff(\))345 b Fe(in)n(v)n(erse)27
+b(FFT)h(using)f(FFTW)-450 750 y Ff(freqz)i(\()p Fd(ar)m(gs)p
+Ff(\))224 b Fe(FIR)28 b(\014lter)e(frequency)f(resp)r(onse)-450
+836 y Ff(filter)k(\()p Fd(a)p Ff(,)g Fd(b)p Ff(,)e Fd(x)p
+Ff(\))85 b Fe(\014lter)27 b(b)n(y)g(transfer)g(function)-450
+911 y Ff(conv)i(\()p Fd(a)p Ff(,)f Fd(b)p Ff(\))250 b
+Fe(con)n(v)n(olv)n(e)27 b(t)n(w)n(o)i(v)n(ectors)-450
+985 y Ff(hamming)h(\()p Fd(n)p Ff(\))236 b Fe(return)27
+b(Hamming)f(windo)n(w)i(co)r(e\016cen)n(ts)-450 1071
+y Ff(hanning)i(\()p Fd(n)p Ff(\))236 b Fe(return)27 b(Hanning)f(windo)n
+(w)i(co)r(e\016cen)n(ts)-450 1243 y Fg(Image)f(Pro)s(cessing)-450
+1335 y Ff(colormap)j(\()p Fd(map)p Ff(\))323 b Fe(set)28
+b(the)f(curren)n(t)f(colormap)-450 1420 y Ff(gray2ind)k(\()p
+Fd(i)p Ff(,)f Fd(n)p Ff(\))326 b Fe(con)n(v)n(ert)27
+b(gra)n(y)h(scale)f(to)g(Octa)n(v)n(e)h(image)-450 1506
+y Ff(image)h(\()p Fd(img)p Ff(,)f Fd(zo)m(om)p Ff(\))232
+b Fe(displa)n(y)27 b(an)h(Octa)n(v)n(e)f(image)g(matrix)-450
+1592 y Ff(imagesc)j(\()p Fd(img)p Ff(,)d Fd(zo)m(om)p
+Ff(\))162 b Fe(displa)n(y)27 b(scaled)g(matrix)g(as)h(image)-450
+1678 y Ff(imshow)h(\()p Fd(img)p Ff(,)f Fd(map)p Ff(\))222
+b Fe(displa)n(y)27 b(Octa)n(v)n(e)g(image)-450 1752 y
+Ff(imshow)i(\()p Fd(i)p Ff(,)g Fd(n)p Ff(\))397 b Fe(displa)n(y)27
+b(gra)n(y)h(scale)f(image)-450 1827 y Ff(imshow)i(\()p
+Fd(r)p Ff(,)g Fd(g)p Ff(,)e Fd(b)p Ff(\))301 b Fe(displa)n(y)27
+b(R)n(GB)i(image)-450 1902 y Ff(ind2gray)h(\()p Fd(img)p
+Ff(,)e Fd(map)p Ff(\))151 b Fe(con)n(v)n(ert)27 b(Octa)n(v)n(e)g(image)
+g(to)g(gra)n(y)h(scale)-450 1988 y Ff(ind2rgb)i(\()p
+Fd(img)p Ff(,)d Fd(map)p Ff(\))187 b Fe(con)n(v)n(ert)27
+b(indexed)e(image)i(to)h(R)n(GB)-450 2073 y Ff(loadimage)i(\()p
+Fd(\014le)p Ff(\))325 b Fe(load)28 b(an)f(image)g(\014le)-450
+2159 y Ff(rgb2ind)j(\()p Fd(r)p Ff(,)e Fd(g)p Ff(,)g
+Fd(b)p Ff(\))265 b Fe(con)n(v)n(ert)27 b(R)n(GB)i(to)f(Octa)n(v)n(e)f
+(image)-450 2245 y Ff(saveimage)j(\()p Fd(\014le)p Ff(,)e
+Fd(img)p Ff(,)g Fd(fmt)p Ff(,)g Fd(map)p Ff(\))71 b Fe(sa)n(v)n(e)27
+b(a)h(matrix)f(to)h Fd(\014le)-450 2394 y Fg(C-st)m(yle)f(Input)h(and)h
+(Output)-450 2486 y Ff(fopen)g(\()p Fd(name)p Ff(,)f
+Fd(mo)m(de)p Ff(\))176 b Fe(op)r(en)27 b(\014le)f Fd(name)-450
+2572 y Ff(fclose)j(\()p Fd(\014le)p Ff(\))431 b Fe(close)27
+b Fd(\014le)-450 2646 y Ff(printf)i(\()p Fd(fmt)p Ff(,)g(...\))251
+b Fe(formatted)26 b(output)h(to)h Ff(stdout)-450 2732
+y(fprintf)i(\()p Fd(\014le)p Ff(,)e Fd(fmt)p Ff(,)g(...\))64
+b Fe(formatted)26 b(output)h(to)h Fd(\014le)-450 2818
+y Ff(sprintf)i(\()p Fd(fmt)p Ff(,)e(...\))216 b Fe(formatted)26
+b(output)h(to)h(string)-450 2904 y Ff(scanf)h(\()p Fd(fmt)p
+Ff(\))455 b Fe(formatted)26 b(input)h(from)g Ff(stdin)-450
+2978 y(fscanf)i(\()p Fd(\014le)p Ff(,)g Fd(fmt)p Ff(\))267
+b Fe(formatted)26 b(input)h(from)g Fd(\014le)-450 3053
+y Ff(sscanf)i(\()p Fd(str)p Ff(,)g Fd(fmt)p Ff(\))276
+b Fe(formatted)26 b(input)h(from)g Fd(string)-450 3128
+y Ff(fgets)i(\()p Fd(\014le)p Ff(,)f Fd(len)p Ff(\))315
+b Fe(read)27 b Fd(len)33 b Fe(c)n(haracters)26 b(from)h
+Fd(\014le)-450 3214 y Ff(fflush)i(\()p Fd(\014le)p Ff(\))431
+b Fe(\015ush)27 b(p)r(ending)f(output)g(to)i Fd(\014le)-450
+3288 y Ff(ftell)h(\()p Fd(\014le)p Ff(\))466 b Fe(return)27
+b(\014le)f(p)r(oin)n(ter)h(p)r(osition)-450 3363 y Ff(frewind)j(\()p
+Fd(\014le)p Ff(\))395 b Fe(mo)n(v)n(e)27 b(\014le)g(p)r(oin)n(ter)f(to)
+i(b)r(eginning)-450 3438 y Ff(freport)584 b Fe(prin)n(t)27
+b(a)h(info)f(for)g(op)r(en)f(\014les)-450 3524 y Ff(fread)j(\()p
+Fd(\014le)p Ff(,)f Fd(size)p Ff(,)h Fd(pr)m(e)m(c)p Ff(\))108
+b Fe(read)27 b(binary)g(data)g(\014les)-450 3598 y Ff(fwrite)i(\()p
+Fd(\014le)p Ff(,)g Fd(size)p Ff(,)f Fd(pr)m(e)m(c)p Ff(\))73
+b Fe(write)28 b(binary)e(data)i(\014les)-450 3673 y Ff(feof)h(\()p
+Fd(\014le)p Ff(\))501 b Fe(determine)25 b(if)i(p)r(oin)n(ter)f(is)i(at)
+g(EOF)-450 3768 y(A)g(\014le)e(ma)n(y)i(b)r(e)e(referenced)e(either)i
+(b)n(y)i(name)e(or)i(b)n(y)g(the)e(n)n(um)n(b)r(er)-450
+3843 y(returned)g(from)g Ff(fopen)p Fe(.)43 b(Three)27
+b(\014les)g(are)g(preconnected)d(when)-450 3918 y(Octa)n(v)n(e)j
+(starts:)42 b Ff(stdin)p Fe(,)29 b Ff(stdout)p Fe(,)g(and)e
+Ff(stderr)p Fe(.)-450 4097 y Fg(Other)h(Input)g(and)g(Output)g
+(functions)-450 4189 y Ff(save)h Fd(\014le)f(var)f Ff(...)105
+b Fe(sa)n(v)n(e)28 b(v)l(ariables)f(in)h Fd(\014le)-450
+4263 y Ff(load)h Fd(\014le)361 b Fe(load)28 b(v)l(ariables)f(from)g
+Fd(\014le)-450 4338 y Ff(disp)i(\()p Fd(var)p Ff(\))284
+b Fe(displa)n(y)27 b(v)l(alue)g(of)h Fd(var)f Fe(to)h(screen)p
+1599 -433 1 17 v 1599 4350 V 1750 -367 a Fg(P)m(olynomials)1750
+-276 y Ff(compan)i(\()p Fd(p)p Ff(\))275 b Fe(companion)25
+b(matrix)1750 -190 y Ff(conv)k(\()p Fd(a)p Ff(,)f Fd(b)p
+Ff(\))251 b Fe(con)n(v)n(olution)1750 -115 y Ff(deconv)30
+b(\()p Fd(a)p Ff(,)e Fd(b)p Ff(\))180 b Fe(decon)n(v)n(olv)n(e)26
+b(t)n(w)n(o)i(v)n(ectors)1750 -40 y Ff(poly)h(\()p Fd(a)p
+Ff(\))346 b Fe(create)26 b(p)r(olynomial)g(from)h(a)g(matrix)1750
+45 y Ff(polyderiv)k(\()p Fd(p)p Ff(\))169 b Fe(deriv)l(ativ)n(e)26
+b(of)h(p)r(olynomial)1750 131 y Ff(polyreduce)k(\()p
+Fd(p)p Ff(\))134 b Fe(in)n(tegral)26 b(of)i(p)r(olynomial)1750
+217 y Ff(polyval)i(\()p Fd(p)p Ff(,)e Fd(x)p Ff(\))145
+b Fe(v)l(alue)27 b(of)g(p)r(olynomial)f(at)i Fd(x)1750
+303 y Ff(polyvalm)i(\()p Fd(p)p Ff(,)f Fd(x)p Ff(\))109
+b Fe(v)l(alue)27 b(of)g(p)r(olynomial)f(at)i Fd(x)1750
+389 y Ff(roots)h(\()p Fd(p)p Ff(\))311 b Fe(p)r(olynomial)25
+b(ro)r(ots)1750 463 y Ff(residue)30 b(\()p Fd(a)p Ff(,)e
+Fd(b)p Ff(\))145 b Fe(partial)27 b(fraction)f(expansion)g(of)i(ratio)f
+Fd(a)p Fe(/)p Fd(b)1750 635 y Fg(Statistics)1750 726
+y Ff(corrcoef)j(\()p Fd(x)p Ff(,)e Fd(y)p Ff(\))112 b
+Fe(correlation)26 b(co)r(e\016cien)n(t)1750 801 y Ff(cov)j(\()p
+Fd(x)p Ff(,)f Fd(y)p Ff(\))288 b Fe(co)n(v)l(ariance)1750
+876 y Ff(mean)29 b(\()p Fd(a)p Ff(\))346 b Fe(mean)26
+b(v)l(alue)1750 951 y Ff(median)k(\()p Fd(a)p Ff(\))275
+b Fe(median)26 b(v)l(alue)1750 1025 y Ff(std)j(\()p Fd(a)p
+Ff(\))381 b Fe(standard)27 b(deviation)1750 1100 y Ff(var)i(\()p
+Fd(a)p Ff(\))381 b Fe(v)l(ariance)1750 1263 y Fg(Plotting)27
+b(F)-8 b(unctions)1750 1354 y Ff(plot)29 b(\()p Fd(ar)m(gs)p
+Ff(\))260 b Fe(2D)27 b(plot)h(with)f(linear)f(axes)1750
+1440 y Ff(plot3)j(\()p Fd(ar)m(gs)p Ff(\))225 b Fe(3D)27
+b(plot)h(with)f(linear)f(axes)1750 1526 y Ff(line)j(\()p
+Fd(ar)m(gs)p Ff(\))260 b Fe(2D)27 b(or)h(3D)g(line)1750
+1600 y Ff(patch)h(\()p Fd(ar)m(gs)p Ff(\))225 b Fe(2D)27
+b(patc)n(h)1750 1686 y Ff(semilogx)j(\()p Fd(ar)m(gs)p
+Ff(\))119 b Fe(2D)27 b(plot)h(with)f(logarithmic)f(x-axis)1750
+1772 y Ff(semilogy)k(\()p Fd(ar)m(gs)p Ff(\))119 b Fe(2D)27
+b(plot)h(with)f(logarithmic)f(y-axis)1750 1858 y Ff(loglog)k(\()p
+Fd(ar)m(gs)p Ff(\))189 b Fe(2D)27 b(plot)h(with)f(logarithmic)f(axes)
+1750 1944 y Ff(bar)j(\()p Fd(ar)m(gs)p Ff(\))295 b Fe(plot)27
+b(bar)g(c)n(harts)1750 2018 y Ff(stairs)j(\()p Fd(x)p
+Ff(,)e Fd(y)p Ff(\))182 b Fe(plot)27 b(stairsteps)1750
+2093 y Ff(stem)i(\()p Fd(x)p Ff(,)f(it)g(y\))153 b Fe(plot)27
+b(a)h(stem)f(graph)1750 2179 y Ff(hist)i(\()p Fd(y)p
+Ff(,)g Fd(x)p Ff(\))252 b Fe(plot)27 b(histograms)1750
+2254 y Ff(contour)j(\()p Fd(x)p Ff(,)e Fd(y)p Ff(,)g
+Fd(z)p Ff(\))56 b Fe(con)n(tour)26 b(plot)1750 2328 y
+Ff(title)j(\()p Fd(string)p Ff(\))175 b Fe(set)27 b(plot)g(title)1750
+2403 y Ff(axis)i(\()p Fd(limits)p Ff(\))214 b Fe(set)27
+b(axis)h(ranges)1750 2478 y Ff(xlabel)i(\()p Fd(string)p
+Ff(\))139 b Fe(set)27 b(x-axis)h(lab)r(el)1750 2552 y
+Ff(ylabel)i(\()p Fd(string)p Ff(\))139 b Fe(set)27 b(y-axis)h(lab)r(el)
+1750 2638 y Ff(zlabel)i(\()p Fd(string)p Ff(\))139 b
+Fe(set)27 b(z-axis)h(lab)r(el)1750 2713 y Ff(text)h(\()p
+Fd(x)p Ff(,)f Fd(y)p Ff(,)g Fd(str)p Ff(\))110 b Fe(add)27
+b(text)g(to)g(a)h(plot)1750 2788 y Ff(legend)i(\()p Fd(string)p
+Ff(\))139 b Fe(set)27 b(lab)r(el)f(in)h(plot)h(k)n(ey)1750
+2890 y Ff(grid)h Fc([)p Fe(on)p Fb(j)p Fe(o\013)p Fc(])240
+b Fe(set)27 b(grid)g(state)1750 2997 y Ff(hold)i Fc([)p
+Fe(on)p Fb(j)p Fe(o\013)p Fc(])240 b Fe(set)27 b(hold)g(state)1750
+3084 y Ff(ishold)410 b Fe(return)26 b(1)i(if)f(hold)g(is)g(on,)h(0)f
+(otherwise)1750 3158 y Ff(mesh)i(\()p Fd(x)p Ff(,)f Fd(y)p
+Ff(,)g Fd(z)p Ff(\))162 b Fe(plot)27 b(3D)h(surface)1750
+3233 y Ff(meshgrid)i(\()p Fd(x)p Ff(,)e Fd(y)p Ff(\))112
+b Fe(create)26 b(mesh)h(co)r(ordinate)e(matrices)p 1750
+3323 1900 4 v 1750 3491 a Fh(Edition)i(2.0)h(for)g(Octa)n(v)n(e)h(V)-5
+b(ersion)27 b(3.0.0.)42 b(Cop)n(yrigh)n(t)28 b(1996,)h(2007,)g(John)
+1750 3565 y(W.)e(Eaton)h(\(jw)n(e at o)r(cta)n(v)n(e.org\).)44
+b(The)28 b(author)g(assumes)h(no)e(resp)r(onsibilit)n(y)1750
+3640 y(for)i(an)n(y)f(errors)g(on)g(this)f(card.)1750
+3765 y(This)h(card)g(ma)n(y)g(b)r(e)f(freely)h(distributed)e(under)h
+(the)g(terms)h(of)h(the)e(GNU)1750 3839 y(General)h(Public)e(License.)
+1750 3964 y(T)1783 3975 y(E)1817 3964 y(X)h(Macros)i(for)g(this)e(card)
+h(b)n(y)g(Roland)f(P)n(esc)n(h)i(\(p)r(esc)n(h at cygn)n(us.com\),)1750
+4039 y(originally)e(for)h(the)g(GDB)f(reference)i(card)1750
+4163 y(Octa)n(v)n(e)g(itself)f(is)f(free)h(soft)n(w)n(are;)i(y)n(ou)e
+(are)h(w)n(elcome)f(to)h(distribute)d(copies)1750 4238
+y(of)j(it)e(under)g(the)g(terms)h(of)g(the)g(GNU)f(General)g(Public)f
+(License.)41 b(There)28 b(is)1750 4313 y(absolutely)g(no)g(w)n(arran)n
+(t)n(y)h(for)g(Octa)n(v)n(e.)p 3800 -433 1 17 v 3800
+4350 V eop end
+%%Trailer
+
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/doc/refcard/refcard-letter.tex b/doc/refcard/refcard-letter.tex
new file mode 100644
index 0000000..2a9c58f
--- /dev/null
+++ b/doc/refcard/refcard-letter.tex
@@ -0,0 +1,25 @@
+% refcard-letter.tex
+%
+% Make a reference card that will fit on US letter paper
+% (8-1/2 by 11 inches).
+%
+% Copyright (C) 1996 John W. Eaton
+%
+% This file is part of Octave.
+%
+% Octave is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 3 of the License, or (at your
+% option) any later version.
+%
+% Octave is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Octave; see the file COPYING.  If not, see
+% <http://www.gnu.org/licenses/>.
+
+\def\refcardsize{letter}
+\input refcard.tex
diff --git a/doc/refcard/refcard.tex b/doc/refcard/refcard.tex
new file mode 100644
index 0000000..b253a02
--- /dev/null
+++ b/doc/refcard/refcard.tex
@@ -0,0 +1,985 @@
+% refcard.tex
+%
+% This file is TeX source for a reference card describing Octave.
+%
+% Copyright (C) 1996, 1997, 2000, 2003, 2004, 2005, 2007 John W. Eaton
+%
+% This file is part of Octave.
+%
+% Octave is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 3 of the License, or (at your
+% option) any later version.
+%
+% Octave is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Octave; see the file COPYING.  If not, see
+% <http://www.gnu.org/licenses/>.
+%
+% Heavily modified by jwe from the source for the gdb reference card,
+% which was orignally written by Roland Pesch <pesch at cygnus.com>.
+%
+%   Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+%   Permission is granted to make and distribute verbatim copies of
+%   this reference provided the copyright notices and permission notices
+%   are preserved on all copies.
+%
+% TeX markup is a programming language; accordingly this file is source
+% for a program to generate a reference.
+%
+% You only have to set the total width and height of the paper, the
+% horizontal and vertical margin space measured from *paper edge*
+% and the interline and interspec spacing.
+% In order to support a new papersize, you have to fiddle with the
+% latter four dimensions. Just try out a few values.
+% All other values will be computed at process time so it should be
+% quite easy to support different paper sizes - only four values to
+% guess :-)
+%
+% To find the configuration places, just search for the string
+% "User configuration".
+%
+%   -- Andreas Vogel (av at ssw.de)
+%
+% NOTE ON INTENTIONAL OMISSIONS: This reference card includes many
+% Octave commands, but due to space constraints there are some things
+% I chose to omit.  In general, not all synonyms for commands are
+% covered, nor all variations of a command.
+
+\def\octaveversion{3.0.0}
+\def\refcardedition{2.0}
+
+% ------------------
+% multicolumn format
+% ------------------
+
+% Declarations (these must come first)
+
+\newdimen\totalwidth
+\newdimen\totalheight
+\newdimen\hmargin
+\newdimen\vmargin
+\newdimen\secskip
+\newdimen\lskip
+\newdimen\barwidth
+\newdimen\barheight
+\newdimen\intersecwidth
+
+\newcount\columnsperpage
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                     %
+% CONFIGURATION                                                       %
+%                                                                     %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% There are currently 8 total columns, so some of these options will
+% not create a single page reference card.
+
+% Choose a paper size.  Default is US letter size.
+
+\def\refcardafoursize{a4}      % 3 columns, A4 paper (1 in = 254 mm)
+\def\refcardlegalsize{legal}   % 4 columns, US legal paper (8.5 x 14in)
+\def\refcardlettersize{letter} % 3 columns, US letter paper (8.5 x 11in)
+
+\ifx\refcardsize\refcardafoursize
+  \columnsperpage=3     % total number of columns to typeset
+  \totalwidth=297mm     % total width of paper
+  \totalheight=210mm    % total height of paper
+  \hmargin=9mm          % horizontal margin width
+  \vmargin=7mm          % vertical margin width
+  \secskip=3mm          % space between refcard secs
+  \lskip=0.4mm          % extra skip between \sec entries
+\else
+  \ifx\refcardsize\refcardlegalsize
+    \columnsperpage=4   % total number of columns to typeset
+    \totalwidth=14in    % total width of paper
+    \totalheight=8.5in  % total height of paper
+    \hmargin=0.20in     % horizontal margin width
+    \vmargin=0.25in     % vertical margin width
+    \secskip=0.75pc     % space between refcard secs
+    \lskip=2pt          % extra skip between \sec entries
+  \else
+    \columnsperpage=3   % total number of columns to typeset
+    \totalwidth=11in    % total width of paper
+    \totalheight=8.5in  % total height of paper
+    \hmargin=0.25in     % horizontal margin width
+    \vmargin=0.25in     % vertical margin width
+    \secskip=0.75pc     % space between refcard secs
+    \lskip=2pt          % extra skip between \sec entries
+  \fi
+\fi
+
+\ifx\pdfoutput\undefined
+\else
+  \pdfpageheight=\totalheight
+  \pdfpagewidth=\totalwidth
+\fi
+
+% Change according to personal taste, not papersize dependent.
+
+\barwidth=.1pt       % width of the cropmark bar
+\barheight=2pt       % height of the cropmark bar
+\intersecwidth=0.5em % width between \itmwid and \dfnwid
+
+% Uncomment only one of the following definitions for folding guides.
+
+% No printed folding guide:
+
+%\def\vdecor{\hskip\hmargin plus1fil
+%  \hskip\barwidth plus1fil
+%  \hskip\hmargin plus1fil}
+
+% Solid line folding guide:
+
+%\def\vdecor{\hskip\hmargin plus1fil%
+%  \vrule width \barwidth%
+%  \hskip\hmargin plus1fil}
+
+% For small marks near top and bottom as folding guide:
+
+\def\vdecor{\hskip\hmargin plus1fil%
+  \vbox to \vsize{\hbox to \barwidth{\vrule height\barheight width\barwidth}%
+  \vfill
+  \hbox to \barwidth{\vrule height\barheight width\barwidth}}%
+  \hskip\hmargin plus1fil}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                      %
+% END CONFIGURATION                                                    %
+%                                                                      %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% values to be computed based on above definitions.
+% nothing to configure
+
+\newdimen\fullhsize          % width of area without margins
+\newdimen\itmwid             % width of item column
+\newdimen\dfnwid             % width of definition column
+\newdimen\idnwid             % width of indented text
+\newdimen\temp               % only for temporary use
+
+% an alternate section format, used in some cases to make text fit better.
+
+\newdimen\altitmwid        % width of item column in altsec
+\newdimen\altdfnwid        % width of definition column in altsec
+
+% Subtract hmargin for left and right sides of paper from full width.
+%
+%   fullhsize = totalwidth - (2 * hmargin)
+
+\fullhsize=\totalwidth
+\temp=\hmargin
+\multiply \temp by 2
+\advance \fullhsize by -\temp
+
+% intercolumn space is composed of hmargin barwidth hmargin so that we
+% get the same amount of space on either side of the (optional) rule
+% between columns.  For N columns, we need to subtract this amount of
+% space N-1 times.  Divide by the number of columns to get the final
+% value of \hsize that we use to typeset columns.
+
+% hsize = (fullhsize - (ncols-1)*barwidth - 2*(ncols-1)*hmargin) / ncols
+
+\newcount\tmpcnt
+\tmpcnt\columnsperpage
+\advance \tmpcnt by -1
+
+\hsize=\fullhsize
+
+\temp=\barwidth
+\multiply \temp by \tmpcnt
+\advance \hsize by -\temp
+
+\multiply \tmpcnt by 2
+
+\temp=\hmargin
+\multiply \temp by \tmpcnt
+\advance \hsize by -\temp
+
+\divide \hsize by \columnsperpage
+
+% Vertical size is easy -- same amount of space above and below.
+%
+%   vsize = totalheight - (2 * vmargin)
+
+\vsize=\totalheight
+\temp=\vmargin
+\multiply \temp by 2
+\advance \vsize by -\temp
+
+% adjust the offsets so the margins are measured *from paper edge*
+
+\hoffset=-1in \advance \hoffset by \hmargin
+\voffset=-1in \advance \voffset by \vmargin
+
+% Width of items in a section.
+
+% itmwid = (hsize - intersecwidth) * 1/3
+% dfnwid = (hsize - intersecwidth) * 2/3
+
+% width of the item
+
+\temp=\hsize
+\advance \temp by -\intersecwidth
+\divide \temp by 3
+\itmwid=\temp
+
+% width of the corresponding definition
+
+\dfnwid=\hsize
+\advance \dfnwid by -\itmwid
+
+% indentation for sub items, etc.
+
+\temp=\hsize \advance\temp by -1em
+\idnwid=\temp
+
+% Width of items in an alt section.
+
+\altitmwid=\itmwid \advance \altitmwid by 0.35in
+\altdfnwid=\dfnwid \advance \altdfnwid by -0.35in
+
+% Output macros.
+%
+% Strategy:
+%
+%   * set each column in a box
+%   * append new columns in a global `holding' box, inserting
+%     intercolumn decorations as necessary.
+%   * when we fill a page, dump the saved box and the latest column,
+%     separated by the intercolumn decoration.
+
+\newbox\holdbox
+\newcount\colno
+\colno=0
+
+\output={\relax
+  \global\advance\colno by 1
+  \ifnum\colno=1
+    \global\setbox\holdbox=\columnbox
+  \else
+    \ifnum\colno=\columnsperpage
+      \shipout\hbox to \fullhsize{\box\holdbox\vdecor\columnbox}
+      \advancepageno
+      \global\colno=0
+    \else
+      \global\setbox\holdbox=\vbox{\hbox{\box\holdbox\vdecor\columnbox}}
+    \fi
+  \fi}
+
+\def\columnbox{\leftline{\pagebody}}
+
+\def\bye{\par\vfill
+  \supereject
+  \if R\lcr \null\vfill\eject \fi
+  \end}
+
+% -----
+% Fonts
+% -----
+
+\font\bbf=cmbx10
+\font\vbbf=cmbx12
+\font\smrm=cmr6
+\font\brm=cmr10
+\font\rm=cmr7
+\font\it=cmti7
+\font\tt=cmtt8
+
+% We can afford to allow some slop
+
+\hfuzz=1pt
+\vfuzz=1pt
+\hyphenpenalty=5000
+\tolerance=2000
+\raggedright
+\raggedbottom
+\normalbaselineskip=9pt
+\baselineskip=9pt
+
+\parindent=0pt
+\parskip=0pt
+\footline={\vbox to0pt{\hss}}
+
+\def\ctl#1{{\tt C-#1}}
+\def\opt#1{{\brm[{\rm #1}]}}
+\def\xtra#1{\noalign{\smallskip{\tt#1}}}
+
+% A normal section
+
+\long\def\sec#1;#2\endsec{\vskip \secskip
+  \halign{%
+%
+% column 1 (of halign):
+%
+    \vtop{\hsize=\itmwid\tt ##\par\vskip \lskip }\hfil
+%
+% column 2 (of halign):
+%
+    &\vtop{%
+      \hsize=\dfnwid
+      \hangafter=1
+      \hangindent=\intersecwidth
+      \rm ##\par\vskip \lskip}\cr
+%
+% Tail of \long\def fills in halign body with \sec args:
+%
+    \noalign{{\bbf #1}%
+      \vskip \lskip}
+    #2}}
+
+\long\def\widesec#1;#2\endsec{\vskip \secskip
+  \halign{%
+%
+% column 1 (of halign):
+%
+    \vbox{\tt
+      ##\par\vskip \lskip }\cr
+%
+% Tail of \long\def fills in halign body with \sec args:
+%
+      \noalign{{\bbf #1}\vskip 3\lskip}
+    #2}}
+
+% an alternate section format, used in some cases to make text fit better.
+
+\long\def\altsec#1;#2\endsec{\vskip \secskip
+  \halign{%
+%
+% column 1 (of halign):
+%
+    \vtop{\hsize=\altitmwid\tt
+      ##\par\vskip \lskip}\hfil
+%
+% column 2 (of halign):
+%
+    &\vtop{%
+      \hsize=\altdfnwid
+      \hangafter=1
+      \hangindent=\intersecwidth
+      \rm ##\par\vskip \lskip}\cr
+%
+% Tail of \long\def fills in halign body with \sec args:
+%
+    \noalign{{\bbf #1}\vskip \lskip}
+    #2}}
+
+% -------------------------------------
+% The actual text of the reference card
+% -------------------------------------
+
+{\vbbf Octave Quick Reference}\hfil{\smrm Octave Version \octaveversion}\qquad
+
+\sec Starting Octave;
+octave&start interactive Octave session\cr
+octave {\it file}&run Octave on commands in {\it file}\cr
+octave --eval {\it code}&Evaluate {\it code} using Octave\cr
+octave --help&describe command line options\cr
+\endsec
+
+\sec Stopping Octave;
+quit {\rm or} exit&exit Octave\cr
+INTERRUPT&({\it e.g.} \ctl{c}) terminate current command and return to
+  top-level prompt\cr
+\endsec
+
+\sec Getting Help;
+help&list all commands and built-in variables\cr
+help {\it command}&briefly describe {\it command}\cr
+doc&use Info to browse Octave manual\cr
+doc {\it command}&search for {\it command} in Octave manual\cr
+lookfor {\it str}&search for {\it command} based on {\it str}\cr
+\endsec
+
+\sec Motion in Info;
+SPC {\rm or} C-v&scroll forward one screenful\cr
+DEL {\rm or} M-v&scroll backward one screenful\cr
+C-l&redraw the display\cr
+\endsec
+
+\sec Node Selection in Info;
+n&select the next node\cr
+p&select the previous node\cr
+u&select the `up' node\cr
+t&select the `top' node\cr
+d&select the directory node\cr
+<&select the first node in the current file\cr
+>&select the last node in the current file\cr
+% ]&move forward through the node structure\cr
+% [&move backward through the nodes\cr
+g&reads the name of a node and selects it\cr
+C-x k&kills the current node\cr
+\endsec
+
+\sec Searching in Info;
+s&search for a string\cr
+C-s&search forward incrementally\cr
+C-r&search backward incrementally\cr
+i&search index \& go to corresponding node\cr
+,&go to next match from last `i' command\cr
+\endsec
+
+\sec Command-Line Cursor Motion;
+C-b&move back one character\cr
+C-f&move forward one character\cr
+C-a&move to the start of the line\cr
+C-e&move to the end of the line\cr
+M-f&move forward a word\cr
+M-b&move backward a word\cr
+C-l&clear screen, reprinting current line at top\cr
+\endsec
+
+\sec Inserting or Changing Text;
+M-TAB&insert a tab character\cr
+DEL&delete character to the left of the cursor\cr
+C-d&delete character under the cursor\cr
+C-v&add the next character verbatim\cr
+C-t&transpose characters at the point\cr
+M-t&transpose words at the point\cr
+% M-u&uppercase the current word\cr
+% M-l&lowercase the current word\cr
+% M-c&capitalize the current word\cr
+\endsec
+
+\vfill
+\line{\smrm \opt{ } surround optional arguments
+  \hfill ... show one or more arguments}
+\vskip0.25\baselineskip
+\eject
+
+\sec Killing and Yanking;
+C-k&kill to the end of the line\cr
+C-y&yank the most recently killed text\cr
+M-d&kill to the end of the current word\cr
+M-DEL&kill the word behind the cursor\cr
+M-y&rotate the kill ring and yank the new top\cr
+\endsec
+
+\sec Command Completion and History;
+TAB&complete a command or variable name\cr
+M-?&list possible completions\cr
+
+RET&enter the current line \cr
+C-p&move `up' through the history list\cr
+C-n&move `down' through the history list\cr
+M-<&move to the first line in the history\cr
+M->&move to the last line in the history\cr
+C-r&search backward in the history list\cr
+C-s&search forward in the history list\cr
+
+history \opt{{-q}} \opt{{\it N\/}}&list {\it N\/} previous history lines,
+  omitting history numbers if {\tt -q}\cr
+history -w \opt{{\it file}}&write history to {\it file\/} ({\tt
+  \char'0176/.octave\_hist} if no {\it file\/} argument)\cr
+history -r \opt{{\it file}}&read history from {\it file\/} ({\tt
+  \char'0176/.octave\_hist} if no {\it file\/} argument)\cr
+
+edit\_history {\it lines}&edit and then run previous
+  commands from the history list\cr
+run\_history {\it lines}&run previous commands from the
+  history list\cr
+\quad\opt{{\it beg\/}} \opt{{\it end\/}}&Specify the first and last
+  history commands to edit or run.\cr
+\omit\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  If {\it beg}\/ is greater than {\it end},
+  reverse the list of commands before editing.  If {\it end\/} is
+  omitted, select commands from {\it beg\/} to the end of the history
+  list.  If both arguments are omitted, edit the previous item in the
+  history list.}\span\cr
+\endsec
+
+\sec Shell Commands;
+cd {\it dir}&change working directory to {\it dir}\cr
+pwd&print working directory\cr
+ls \opt{{\it options}}&print directory listing\cr
+getenv ({\it string})&return value of named environment variable\cr
+system ({\it cmd})&execute arbitrary shell command string\cr
+\endsec
+
+\sec Matrices;
+\omit\vbox{\rm\vskip0.25ex
+  Square brackets delimit literal matrices.  Commas separate elements
+  on the same row.  Semicolons separate rows.  Commas may be replaced
+  by spaces, and semicolons may be replaced by one or more newlines.
+  Elements of a matrix may be arbitrary expressions, assuming
+  all the dimensions agree.\vskip0.75ex}\span\cr
+[ {\it x}, {\it y}, ... ]&enter a row vector\cr
+[ {\it x}; {\it y}; ... ]&enter a column vector\cr
+[ {\it w}, {\it x}; {\it y}, {\it z} ]&enter a 2$\times$2 matrix\cr
+\endsec
+
+\sec Multi-dimensional Arrays;
+\omit\vbox{\rm\vskip0.25ex
+  Multi-dimensional arrays may be created with the {\it cat} or
+  {\it reshape} commands from two-dimensional sub-matrices.
+  \vskip0.75ex}\span\cr
+squeeze ({\it arr})&remove singleton dimensions of the array.\cr
+ndims ({\it arr})&number of dimensions in the array.\cr
+permute ({\it arr}, {\it p})&permute the dimensions of an array.\cr
+ipermute ({\it arr}, {\it p})&array inverse permutation.\cr
+\endsec
+
+\vfill\eject
+
+\sec ;
+shiftdim ({\it arr}, {\it s})&rotate the array dimensions.\cr
+circshift ({\it arr}, {\it s})&rotate the array elements.\cr
+\endsec
+
+\sec Sparse Matrices;
+sparse (...)&create a sparse matrix.\cr
+speye ({\it n)}&create sparse identify matrix.\cr
+sprand ({\it n}, {\it m}, {\it d})&sparse rand matrix of density {\it d}.\cr
+spdiags (...)&sparse generalization of {\it diag}.\cr
+nnz ({\it s})&No. non-zero elements in sparse matrix.\cr
+\endsec
+
+\sec Ranges;
+{\it base} : {\it limit}\cr
+{\it base} : {\it incr} : {\it limit}\cr
+\omit\hfill\vbox{\hsize=\idnwid\rm\vskip0.75ex
+  Specify a range of values beginning with {\it base\/} with no elements
+  greater than {\it limit}.  If it is omitted, the default value of
+  {\it incr\/} is 1.  Negative increments are permitted.}\span\cr
+\endsec
+
+\sec Strings and Common Escape Sequences;
+\omit\vbox{\rm\vskip0.5ex
+  A {\it string constant\/} consists of a sequence of characters
+  enclosed in either double-quote or single-quote marks. Strings
+  in double-quotes allow the use of the escape sequences below.
+  \vskip0.75ex}\span\cr
+\char'134\char'134&a literal backslash\cr
+\char'134 "&a literal double-quote character\cr
+\char'134 '&a literal single-quote character\cr
+\char'134 n&newline, ASCII code 10\cr
+\char'134 t&horizontal tab, ASCII code 9\cr
+\endsec
+
+\sec Index Expressions;
+{\it var} ({\it idx})&select elements of a vector\cr
+{\it var} ({\it idx1}, {\it idx2})&select elements of a matrix\cr
+
+\quad {\it scalar}&select row (column) corresponding to {\it scalar}\cr
+\quad {\it vector}&select rows (columns) corresponding to the elements
+  of {\it vector}\cr
+\quad {\it range}&select rows (columns) corresponding to the elements
+  of {\it range}\cr
+\quad :&select all rows (columns)\cr
+\endsec
+
+\sec Global and Persistent Variables;
+global {\it var1} ...&Declare variables global.\cr
+global {\it var1} = {\it val}&Declare variable global. Set intial value.\cr
+persistent {\it var1}&Declare a variable as static to a function.\cr
+persistent {\it var1} = {\it val}&Declare a variable as static to a 
+  function and set its initial value.\cr
+\omit\hfill\vbox{\rm\vskip0.25ex
+  Global variables may be accessed inside the body of a function
+  without having to be passed in the function parameter list provided
+  they are declared global when used.}\span\cr
+\endsec
+
+\sec Selected Built-in Functions;
+EDITOR&editor to use with {\tt edit\_history}\cr
+Inf, NaN&IEEE infinity, NaN\cr
+NA&Missing value\cr
+PAGER&program to use to paginate output\cr
+ans&last result not explicitly assigned\cr
+eps&machine precision\cr
+pi&$\pi$\cr
+1i&$\sqrt{-1}$\cr
+realmax&maximum representable value\cr
+realmin&minimum representable value\cr
+\endsec
+
+\vfill
+\centerline{\smrm Copyright 1996, 1997, 2007 John W. Eaton\qquad Permissions on back}
+\eject
+
+\sec Assignment Expressions;
+{\it var} = {\it expr}&assign expression to variable\cr
+{\it var} ({\it idx}) = {\it expr}&assign expression to indexed variable\cr
+{\it var} ({\it idx}) = []&delete the indexed elements.\cr
+{\it var} $\{${\it idx}$\}$ = {\it expr}&assign elements of a cell array.\cr
+\endsec
+
+\sec Arithmetic and Increment Operators;
+{\it x} + {\it y}&addition\cr
+{\it x} - {\it y}&subtraction\cr
+{\it x} * {\it y}&matrix multiplication\cr
+{\it x} .* {\it y}&element by element multiplication\cr
+{\it x} / {\it y}&right division, conceptually equivalent to
+  {\tt (inverse~(y')~*~x')'}\cr
+{\it x} ./ {\it y}&element by element right division\cr
+{\it x} \char'134{} {\it y}&left division, conceptually equivalent to
+  {\tt inverse~(x)~*~y}\cr
+{\it x} .\char'134{} {\it y}&element by element left division\cr
+{\it x} \char'136{} {\it y}&power operator\cr
+{\it x} .\char'136{} {\it y}&element by element power operator\cr
+- {\it x}&negation\cr
++ {\it x}&unary plus (a no-op)\cr
+{\it x} '&complex conjugate transpose\cr
+{\it x} .'&transpose\cr
+++ {\it x}\quad{\rm(}-- {\it x}{\rm)}&increment (decrement),
+  return {\it new\/} value\cr
+{\it x} ++\quad{\rm(}{\it x} --{\rm)}&increment (decrement),
+  return {\it old\/} value\cr
+\endsec
+
+\sec Comparison and Boolean Operators;
+\omit \vbox{\rm\vskip0.75ex
+  These operators work on an element-by-element basis.  Both arguments
+  are always evaluated.\vskip0.75ex}\span\cr
+{\it x} < {\it y}&true if {\it x\/} is less than {\it y}\cr
+{\it x} <= {\it y}&true if {\it x\/} is less than or equal to {\it y}\cr
+{\it x} == {\it y}&true if {\it x\/} is equal to {\it y}\cr
+{\it x} >= {\it y}&true if {\it x\/} is greater than or equal to {\it y}\cr
+{\it x} > {\it y}&true if {\it x\/} is greater than {\it y}\cr
+{\it x} != {\it y}&true if {\it x\/} is not equal to {\it y}\cr
+{\it x} \& {\it y}&true if both {\it x\/} and {\it y\/} are true\cr
+{\it x} | {\it y}&true if at least one of {\it x\/} or {\it y\/} is true\cr 
+! {\it bool}&true if {\it bool\/} is false\cr
+\endsec
+
+\sec Short-circuit Boolean Operators;
+\omit \vbox{\rm\vskip0.75ex
+  Operators evaluate left-to-right. Operands are only evaluated if 
+  necessary, stopping once overall truth value can be determined.  
+  Operands are converted to scalars using the {\tt all} 
+  function.\vskip0.75ex}\span\cr   
+{\it x} \&\& {\it y}&true if both {\it x\/} and {\it y\/} are true\cr
+{\it x} || {\it y}&true if at least one of {\it x\/} or {\it y\/} is true\cr
+\endsec
+
+\sec Operator Precedence;
+\omit \vbox{\rm\vskip0.5ex
+  Table of Octave operators, in order of increasing
+  precedence.\vskip0.75ex}\span\cr
+;\ \ ,&statement separators\cr
+=&assignment, groups left to right\cr
+||\ \ \&\&&logical ``or'' and ``and''\cr
+|\ \ \&&element-wise ``or'' and ``and''\cr
+< <= == >= > !=&relational operators\cr
+:&colon\cr
++\ \ -&addition and subtraction\cr
+* / \char'134\ \ .*\ \ ./\ \ .\char'134&multiplication and division\cr
+'\ \ .'&transpose\cr
++\ \ -\ \ ++\ \ --\ \ !&unary minus, increment, logical ``not''\cr
+\char'136\ \ .\char'136&exponentiation\cr
+\endsec
+
+\vfill\eject
+
+\sec Paths and Packages;
+path&display the current Octave cunction path.\cr
+pathdef&display the default path.\cr
+addpath({\it dir})&add a directory to the path.\cr
+EXEC\_PATH&manipulate the Octave executable path.\cr
+pkg list&display installed packages.\cr
+pkg load {\it pack}&Load an installed package.\cr
+\endsec
+
+\sec Cells and Structures;
+{\it{var}}.{\it{field}} = ...&set a field of a structure.\cr
+{\it{var}}$\{${\it{idx}}$\}$ = ...&set an element of a cell array.\cr
+cellfun({\it f}, {\it c})&apply a function to elements of cell array.\cr
+fieldnames({\it s})&returns the fields of a structure.\cr
+\endsec
+
+\widesec Statements;
+for {\it identifier} = {\it expr} {\it stmt-list} endfor\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Execute {\it stmt-list} once for each column of {\it expr}.  The
+  variable {\it identifier} is set to the value of the current column
+  during each iteration.}\cr\cr
+while ({\it condition}) {\it stmt-list} endwhile\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Execute {\it stmt-list} while {\it condition} is true.}\cr\cr
+\hbox{\vtop{\hsize=\itmwid\tt break}
+  \vtop{\hsize=\dfnwid\rm exit innermost loop}}\cr
+\hbox{\vtop{\hsize=\itmwid\tt continue}
+  \vtop{\hsize=\dfnwid\rm go to beginning of innermost loop}}\cr
+\hbox{\vtop{\hsize=\itmwid\tt return}
+  \vtop{\hsize=\dfnwid\rm return to calling function}}\cr\cr
+if ({\it condition}) {\it if-body} \opt{{\tt else} {\it else-body}} endif\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Execute {\it if-body} if {\it condition} is true, otherwise execute
+  {\it else-body}.}\cr
+if ({\it condition}) {\it if-body} \opt{{\tt elseif} ({\it condition})
+  {\it elseif-body}} endif\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Execute {\it if-body} if {\it condition} is true, otherwise execute
+  the {\it elseif-body} corresponding to the first {\tt elseif}
+  condition that is true, otherwise execute {\it else-body}.}\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Any number of {\tt elseif} clauses may appear in an {\tt if}
+  statement.}\cr\cr
+unwind\_protect {\it body} unwind\_protect\_cleanup {\it cleanup} end\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Execute {\it body}.  Execute {\it cleanup} no matter how control
+exits {\it body}.}\cr
+try {\it body} catch {\it cleanup} end\cr
+\hfill\vbox{\hsize=\idnwid\rm\vskip0.25ex
+  Execute {\it body}. Execute {\it cleanup} if {\it body} fails.}\cr
+\endsec
+
+\altsec Strings;
+strcmp ({\it s}, {\it t})&compare strings\cr
+strcat ({\it s}, {\it t}, ...)&concatenate strings\cr
+regexp ({\it str}, {\it pat})&strings matching regular expression\cr
+regexprep ({\it str}, {\it pat}, {\it rep})&Match and replace sub-strings\cr
+\endsec
+
+\widesec Defining Functions;
+function \opt{{\it ret-list}} {\it function-name}
+  \opt{\hskip0.2em({\it arg-list})\hskip0.2em}\cr
+\quad{\it function-body}\cr
+endfunction\cr\cr
+{\rm {\it ret-list\/} may be a single identifier or a comma-separated
+  list of identifiers delimited by square-brackets.\vskip0.75ex}\cr
+{\rm {\it arg-list\/} is a comma-separated list of identifiers and may
+  be empty.}\cr
+\endsec
+
+\vfill\eject
+
+\sec Function Handles;
+@{\it{func}}& Define a function handle to {\it func}.\cr
+@({\it var1}, ...) {\it expr}&Define an anonymous function handle.\cr
+str2func ({\it str})&Create a function handle from a string.\cr
+functions ({\it handle})&Return information about a function handle.\cr
+func2str ({\it handle})&Return a string representation of a
+function handle.\cr
+{\it handle} ({\it arg1}, ...)&Evaluate a function handle.\cr
+feval ({\it func}, {\it arg1}, ...)&Evaluate a function handle or
+  string, passing remaining args to {\it func}\cr
+\omit\vbox{\rm\vskip0.25ex
+  Anonymous function handles take a copy of the variables in the
+  current workspace.\vskip0.75ex}\span\cr
+\endsec
+
+\sec Miscellaneous Functions;
+eval ({\it str})&evaluate {\it str} as a command\cr
+error ({\it message})&print message and return to top level\cr
+warning ({\it message})&print a warning message\cr
+clear {\it pattern}&clear variables matching pattern\cr
+exist ({\it str})&check existence of variable or function\cr
+who, whos&list current variables\cr
+whos {\it var}&details of the varibale {\it var}\cr
+\endsec
+
+\sec Basic Matrix Manipulations;
+rows ({\it a})&return number of rows of {\it a}\cr
+columns ({\it a})&return number of columns of {\it a}\cr
+all ({\it a})&check if all elements of {\it a\/} nonzero\cr
+any ({\it a})&check if any elements of {\it a\/} nonzero\cr
+\endsec
+
+\sec ;
+find ({\it a})&return indices of nonzero elements\cr
+sort ({\it a})&order elements in each column of {\it a}\cr
+sum ({\it a})&sum elements in columns of {\it a}\cr
+prod ({\it a})&product of elements in columns of {\it a}\cr
+min ({\it args})&find minimum values\cr
+max ({\it args})&find maximum values\cr
+rem ({\it x}, {\it y})&find remainder of {\it x}/{\it y}\cr
+reshape ({\it a}, {\it m}, {\it n})&reformat {\it a} to be {\it m} by
+  {\it n}\cr
+diag ({\it v}, {\it k})&create diagonal matrices\cr
+linspace ({\it b}, {\it l}, {\it n})&create vector of linearly-spaced
+  elements\cr
+logspace ({\it b}, {\it l}, {\it n})&create vector of log-spaced
+  elements\cr
+eye ({\it n}, {\it m})&create {\it n\/} by {\it m\/} identity matrix\cr
+ones ({\it n}, {\it m})&create {\it n\/} by {\it m\/} matrix of ones\cr
+zeros ({\it n}, {\it m})&create {\it n\/} by {\it m\/} matrix of zeros\cr
+rand ({\it n}, {\it m})&create {\it n\/} by {\it m\/} matrix of random
+  values\cr 
+\endsec
+
+% sin({\it a}) cos({\it a}) tan({\it a})&trigonometric functions\cr
+% asin({\it a}) acos({\it a}) atan({\it a})&inverse trigonometric functions\cr
+% sinh({\it a}) cosh({\it a}) tanh({\it a})&hyperbolic trig functions\cr
+% asinh({\it a}) acosh({\it a}) atanh({\it a})&inverse hyperbolic trig
+% functions\cr\cr 
+
+\sec Linear Algebra;
+chol ({\it a})&Cholesky factorization\cr
+det ({\it a})&compute the determinant of a matrix\cr
+eig ({\it a})&eigenvalues and eigenvectors\cr
+expm ({\it a})&compute the exponential of a matrix\cr
+hess ({\it a})&compute Hessenberg decomposition\cr
+inverse ({\it a})&invert a square matrix\cr
+norm ({\it a}, {\it p})&compute the {\it p}-norm of a matrix\cr
+pinv ({\it a})&compute pseudoinverse of {\it a}\cr
+qr ({\it a})&compute the QR factorization of a matrix\cr
+rank ({\it a})&matrix rank\cr
+sprank ({\it a})&structrual matrix rank\cr
+schur ({\it a})&Schur decomposition of a matrix\cr
+svd ({\it a})&singular value decomposition\cr
+syl ({\it a}, {\it b}, {\it c})&solve the Sylvester equation\cr
+\endsec
+
+\vfill\eject
+
+\sec Equations, ODEs, DAEs, Quadrature;
+*fsolve&solve nonlinear algebraic equations\cr
+*lsode&integrate nonlinear ODEs\cr
+*dassl&integrate nonlinear DAEs\cr
+*quad&integrate nonlinear functions\cr
+perror ({\it nm}, {\it code})&for functions that return numeric
+  codes, print error message for named function and given error
+  code\cr\cr
+\omit \vbox{\rm
+  {\tt *} See the on-line or printed manual for the complete list of
+  arguments for these functions.}\span\cr
+\endsec
+
+% \altsec Sets;
+% create\_set ({\it a}, {\it b})&create row vector of unique values\cr
+% complement ({\it a}, {\it b})&elements of {\it b} not in {\it a}\cr
+% intersection ({\it a}, {\it b})&intersection of sets {\it a} and {\it b}\cr
+% union ({\it a}, {\it b})&union of sets {\it a} and {\it b}\cr
+% \endsec
+
+\sec Signal Processing;
+fft ({\it a})&Fast Fourier Transform using FFTW\cr
+ifft ({\it a})&inverse FFT using FFTW\cr
+freqz ({\it args})&FIR filter frequency response\cr
+filter ({\it a}, {\it b}, {\it x})&filter by transfer function\cr
+conv ({\it a}, {\it b})&convolve two vectors\cr
+hamming ({\it n})&return Hamming window coefficents\cr
+hanning ({\it n})&return Hanning window coefficents\cr
+\endsec
+
+\altsec Image Processing;
+colormap ({\it map})&set the current colormap\cr
+gray2ind ({\it i}, {\it n})&convert gray scale to Octave image\cr
+image ({\it img}, {\it zoom})&display an Octave image matrix\cr
+imagesc ({\it img}, {\it zoom})&display scaled matrix as image\cr
+imshow ({\it img}, {\it map})&display Octave image\cr
+imshow ({\it i}, {\it n})&display gray scale image\cr
+imshow ({\it r}, {\it g}, {\it b})&display RGB image\cr
+ind2gray ({\it img}, {\it map})&convert Octave image to gray scale\cr
+ind2rgb ({\it img}, {\it map})&convert indexed image to RGB\cr
+loadimage ({\it file})&load an image file\cr
+rgb2ind ({\it r}, {\it g}, {\it b})&convert RGB to Octave image\cr
+\omit\tt saveimage ({\it file}, {\it img}, {\it fmt}, {\it map})\quad\rm
+save a matrix to {\it file}\span\cr
+\endsec
+
+\altsec C-style Input and Output;
+fopen ({\it name}, {\it mode})&open file {\it name}\cr
+fclose ({\it file})&close {\it file}\cr
+printf ({\it fmt}, ...)&formatted output to {\tt stdout}\cr
+fprintf ({\it file}, {\it fmt}, ...)&formatted output to {\it file}\cr
+sprintf ({\it fmt}, ...)&formatted output to string\cr
+scanf ({\it fmt})&formatted input from {\tt stdin}\cr
+fscanf ({\it file}, {\it fmt})&formatted input from {\it file}\cr
+sscanf ({\it str}, {\it fmt})&formatted input from {\it string}\cr
+fgets ({\it file}, {\it len})&read {\it len\/} characters from {\it file\/}\cr
+fflush ({\it file})&flush pending output to {\it file}\cr
+ftell ({\it file})&return file pointer position\cr
+frewind ({\it file})&move file pointer to beginning\cr
+freport&print a info for open files\cr
+fread ({\it file}, {\it size}, {\it prec})&read binary data files\cr
+fwrite ({\it file}, {\it size}, {\it prec})&write binary data files\cr
+feof ({\it file})&determine if pointer is at EOF\cr
+\omit \vbox{\rm\vskip0.75ex
+  A file may be referenced either by name or by the number returned
+  from {\tt fopen}.  Three files are preconnected when Octave starts:
+  {\tt stdin}, {\tt stdout}, and {\tt stderr}.\vskip0.75ex}\span\cr
+\endsec
+
+\sec Other Input and Output functions;
+save {\it file} {\it var} ...&save variables in {\it file}\cr
+load {\it file}&load variables from {\it file}\cr
+disp ({\it var})&display value of {\it var} to screen\cr
+\endsec
+
+\vfill\eject
+
+\sec Polynomials;
+compan ({\it p})&companion matrix\cr
+conv ({\it a}, {\it b})&convolution\cr
+deconv ({\it a}, {\it b})&deconvolve two vectors\cr
+poly ({\it a})&create polynomial from a matrix\cr
+polyderiv ({\it p})&derivative of polynomial\cr
+polyreduce ({\it p})&integral of polynomial\cr
+polyval ({\it p}, {\it x})&value of polynomial at {\it x}\cr
+polyvalm ({\it p}, {\it x})&value of polynomial at {\it x}\cr
+roots ({\it p})&polynomial roots\cr
+residue ({\it a}, {\it b})&partial fraction expansion of
+ratio {\it a}/{\it b}\cr
+\endsec
+
+\sec Statistics;
+corrcoef ({\it x}, {\it y})&correlation coefficient\cr
+cov ({\it x}, {\it y})&covariance\cr
+mean ({\it a})&mean value\cr
+median ({\it a})&median value\cr
+std ({\it a})&standard deviation\cr
+var ({\it a})&variance\cr
+\endsec
+
+\sec Plotting Functions;
+plot ({\it args})&2D plot with linear axes\cr
+plot3 ({\it args})&3D plot with linear axes\cr
+line ({\it args})&2D or 3D line\cr
+patch ({\it args})&2D patch\cr
+semilogx ({\it args})&2D plot with logarithmic x-axis\cr
+semilogy ({\it args})&2D plot with logarithmic y-axis\cr
+loglog ({\it args})&2D plot with logarithmic axes\cr
+bar ({\it args})&plot bar charts\cr
+stairs ({\it x}, {\it y})&plot stairsteps\cr
+stem ({\it x}, {it y})&plot a stem graph\cr
+hist ({\it y}, {\it x})&plot histograms\cr
+contour ({\it x}, {\it y}, {\it z})&contour plot\cr
+title ({\it string})&set plot title\cr
+axis ({\it limits})&set axis ranges\cr
+xlabel ({\it string})&set x-axis label\cr
+ylabel ({\it string})&set y-axis label\cr
+zlabel ({\it string})&set z-axis label\cr
+text ({\it x}, {\it y}, {\it str})&add text to a plot\cr
+legend ({\it string})&set label in plot key\cr
+grid \opt{on$|$off}&set grid state\cr
+hold \opt{on$|$off}&set hold state\cr
+ishold&return 1 if hold is on, 0 otherwise\cr
+mesh ({\it x}, {\it y}, {\it z})&plot 3D surface\cr
+meshgrid ({\it x}, {\it y})&create mesh coordinate matrices\cr
+\endsec
+
+\vskip 0pt plus 2fill
+\hrule width \hsize
+\par\vskip10pt
+{\smrm\parskip=6pt
+Edition \refcardedition\ for Octave Version \octaveversion.  Copyright
+1996, 2007, John W. Eaton
+(jwe at octave.org).  The author assumes no responsibility for any
+errors on this card.
+
+This card may be freely distributed under the terms of the GNU
+General Public License.
+
+\TeX{} Macros for this card by Roland Pesch (pesch at cygnus.com),
+originally for the GDB reference card
+
+Octave itself is free software; you are welcome to distribute copies of
+it under the terms of the GNU General Public License.  There is
+absolutely no warranty for Octave.
+}
+
+\end
+
+% For AUCTeX:
+%
+% Local Variables: 
+% mode: tex
+% TeX-master: t
+% End: 
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
new file mode 100644
index 0000000..1c489a4
--- /dev/null
+++ b/doc/texinfo.tex
@@ -0,0 +1,9026 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2009-04-06.11}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software: you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program.  If not, see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction.  (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo at gnu.org.  Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem.  Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution.  For a simple
+% manual foo.texi, however, you can get away with this:
+%   tex foo.texi
+%   texindex foo.??
+%   tex foo.texi
+%   tex foo.texi
+%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent.  You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+  \catcode`+=\active \catcode`\_=\active}
+
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextop=\top
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Pre-3.0.
+\else
+  \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar  = `\-
+\chardef\dotChar   = `\.
+\chardef\exclamChar= `\!
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar  = `\;
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+  ap-pen-dix bit-map bit-maps
+  data-base data-bases eshell fall-ing half-way long-est man-u-script
+  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+  spell-ing spell-ings
+  stand-alone strong-est time-stamp time-stamps which-ever white-space
+  wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.  We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+  \tracingstats2
+  \tracingpages1
+  \tracinglostchars2  % 2 gives us more in etex
+  \tracingparagraphs1
+  \tracingoutput1
+  \tracingmacros2
+  \tracingrestores1
+  \showboxbreadth\maxdimen \showboxdepth\maxdimen
+  \ifx\eTeXversion\undefined\else % etex gives us more logging
+    \tracingscantokens1
+    \tracingifs1
+    \tracinggroups1
+    \tracingnesting2
+    \tracingassigns1
+  \fi
+  \tracingcommands3  % 3 gives us more in etex
+  \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions.  If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+  \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+  \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+  \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong  \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page.  The solution is
+% described on page 260 of The TeXbook.  It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after.  I won't pretend I can describe this better than DEK...
+\def\domark{%
+  \toks0=\expandafter{\lastchapterdefs}%
+  \toks2=\expandafter{\lastsectiondefs}%
+  \toks4=\expandafter{\prevchapterdefs}%
+  \toks6=\expandafter{\prevsectiondefs}%
+  \toks8=\expandafter{\lastcolordefs}%
+  \mark{%
+                   \the\toks0 \the\toks2
+      \noexpand\or \the\toks4 \the\toks6
+    \noexpand\else \the\toks8
+  }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+  \ifcase0\topmark\fi
+  \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+  %
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  %
+  % Do this outside of the \shipout so @code etc. will be expanded in
+  % the headline as they should be, not taken literally (outputting ''code).
+  \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+  \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+  %
+  {%
+    % Have to do this stuff outside the \shipout because we want it to
+    % take effect in \write's, yet the group defined by the \vbox ends
+    % before the \shipout runs.
+    %
+    \indexdummies         % don't expand commands in the output.
+    \normalturnoffactive  % \ in index entries must not stay \, e.g., if
+               % the page break happens to be in the middle of an example.
+               % We don't want .vr (or whatever) entries like this:
+               % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+               % "\acronym" won't work when it's read back in;
+               % it needs to be 
+               % {\code {{\tt \backslashcurfont }acronym}
+    \shipout\vbox{%
+      % Do this early so pdf references go to the beginning of the page.
+      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+      %
+      \ifcropmarks \vbox to \outervsize\bgroup
+        \hsize = \outerhsize
+        \vskip-\topandbottommargin
+        \vtop to0pt{%
+          \line{\ewtop\hfil\ewtop}%
+          \nointerlineskip
+          \line{%
+            \vbox{\moveleft\cornerthick\nstop}%
+            \hfill
+            \vbox{\moveright\cornerthick\nstop}%
+          }%
+          \vss}%
+        \vskip\topandbottommargin
+        \line\bgroup
+          \hfil % center the page within the outer (page) hsize.
+          \ifodd\pageno\hskip\bindingoffset\fi
+          \vbox\bgroup
+      \fi
+      %
+      \unvbox\headlinebox
+      \pagebody{#1}%
+      \ifdim\ht\footlinebox > 0pt
+        % Only leave this space if the footline is nonempty.
+        % (We lessened \vsize for it in \oddfootingyyy.)
+        % The \baselineskip=24pt in plain's \makefootline has no effect.
+        \vskip 24pt
+        \unvbox\footlinebox
+      \fi
+      %
+      \ifcropmarks
+          \egroup % end of \vbox\bgroup
+        \hfil\egroup % end of (centering) \line\bgroup
+        \vskip\topandbottommargin plus1fill minus1fill
+        \boxmaxdepth = \cornerthick
+        \vbox to0pt{\vss
+          \line{%
+            \vbox{\moveleft\cornerthick\nsbot}%
+            \hfill
+            \vbox{\moveright\cornerthick\nsbot}%
+          }%
+          \nointerlineskip
+          \line{\ewbot\hfil\ewbot}%
+        }%
+      \egroup % \vbox from first cropmarks clause
+      \fi
+    }% end of \shipout\vbox
+  }% end of group with \indexdummies
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha at viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr at ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+  \def\argtorun{#2}%
+  \begingroup
+    \obeylines
+    \spaceisspace
+    #1%
+    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    \argremovecomment #1\comment\ArgTerm%
+  }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+%    @end itemize  @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+  \def\temp{#3}%
+  \ifx\temp\empty
+    % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+    \let\temp\finishparsearg
+  \else
+    \let\temp\argcheckspaces
+  \fi
+  % Put the space token in:
+  \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+%	is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick.  --kasal, 16nov03
+
+\def\parseargdef#1{%
+  \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+  \def#2{\parsearg#1}%
+  \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+  \obeyspaces
+  \gdef\obeyedspace{ }
+
+  % Make each space character in the input produce a normal interword
+  % space in the output.  Don't allow a line break at this space, as this
+  % is used only in environments like @example, where each line of input
+  % should produce a line of output anyway.
+  %
+  \gdef\sepspaces{\obeyspaces\let =\tie}
+
+  % If an index command is used in an @example environment, any spaces
+  % therein should become regular spaces in the raw index file, not the
+  % expansion of \tie (\leavevmode \penalty \@M \ ).
+  \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex.  It's used like this:
+%
+%   \envdef\foo{...}
+%   \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo.  \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches.  The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group.  (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At run-time, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+  \def\temp{#1}%
+  \ifx\thisenv\temp
+  \else
+    \badenverr
+  \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+  \errhelp = \EMsimple
+  \errmessage{This command can appear only \inenvironment\temp,
+    not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+  \ifx#1\empty
+    out of any environment%
+  \else
+    in environment \expandafter\string#1%
+  \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+  \if 1\csname iscond.#1\endcsname
+  \else
+    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+    \expandafter\checkenv\csname#1\endcsname
+    \csname E#1\endcsname
+    \endgroup
+  \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce \{ and \} commands for indices,
+  % and @{ and @} for the aux/toc files.
+  \catcode`\{ = \other \catcode`\} = \other
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\! = 0 \catcode`\\ = \other
+  !gdef!lbracecmd[\{]%
+  !gdef!rbracecmd[\}]%
+  !gdef!lbraceatcmd[@{]%
+  !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+  \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence.  (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo.  Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+  L\kern-.36em
+  {\setbox0=\hbox{T}%
+   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+  \kern-.15em
+  \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off  says whether to put extra space after punctuation.
+% 
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+  \def\temp{#1}%
+  \ifx\temp\onword \plainfrenchspacing
+  \else\ifx\temp\offword \plainnonfrenchspacing
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+  \fi\fi
+}
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large.  This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material.  In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom.  The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+  \ifnum\catcode`\^^M=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  \startsavinginserts
+  %
+  \setbox\groupbox = \vtop\bgroup
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it.  Thus, space below is not quite equal to space
+% above.  But it's pretty close.
+\def\Egroup{%
+    % To get correct interline space between the last line of the group
+    % and the first line afterwards, we have to propagate \prevdepth.
+    \endgraf % Not \par, as it may have been set to \lisppar.
+    \global\dimen1 = \prevdepth
+  \egroup           % End the \vtop.
+  % \dimen0 is the vertical size of the group's box.
+  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
+  % \dimen2 is how much space is left on the page (more or less).
+  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
+  % if the group doesn't fit on the current page, and it's a big big
+  % group, force a page break.
+  \ifdim \dimen0 > \dimen2
+    \ifdim \pagetotal < \vfilllimit\pageheight
+      \page
+    \fi
+  \fi
+  \box\groupbox
+  \prevdepth = \dimen1
+  \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+  % Ensure vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % If the @need value is less than one line space, it's useless.
+  \dimen0 = #1\mil
+  \dimen2 = \ht\strutbox
+  \advance\dimen2 by \dp\strutbox
+  \ifdim\dimen0 > \dimen2
+    %
+    % Do a \strut just to make the height of this box be normal, so the
+    % normal leading is inserted relative to the preceding line.
+    % And a page break here is fine.
+    \vtop to #1\mil{\strut\vfil}%
+    %
+    % TeX does not even consider page breaks if a penalty added to the
+    % main vertical list is 10000 or more.  But in order to see if the
+    % empty box we just added fits on the page, we must make it consider
+    % page breaks.  On the other hand, we don't want to actually break the
+    % page after the empty box.  So we use a penalty of 9999.
+    %
+    % There is an extremely small chance that TeX will actually break the
+    % page at this \penalty, if there are no other feasible breakpoints in
+    % sight.  (If the user is using lots of big @group commands, which
+    % almost-but-not-quite fill up a page, TeX will have a hard time doing
+    % good page breaking, for example.)  However, I could not construct an
+    % example where a page broke at this \penalty; if it happens in a real
+    % document, then we can reconsider our strategy.
+    \penalty9999
+    %
+    % Back up by the size of the box, whether we did a page break or not.
+    \kern -#1\mil
+    %
+    % Do not allow a page break right after this kern.
+    \nobreak
+  \fi
+}
+
+% @br   forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+  \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph.  For more general purposes, use the \margin insertion
+% class.  WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+  \nobreak
+  \kern-\strutdepth
+  \vtop to \strutdepth{%
+    \baselineskip=\strutdepth
+    \vss
+    % if you have multiple lines of stuff to put here, you'll need to
+    % make the vbox yourself of the appropriate size.
+    \ifx#1l%
+      \llap{\ignorespaces #2\hskip\inmarginspacing}%
+    \else
+      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+    \fi
+    \null
+  }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+  \setbox0 = \hbox{\ignorespaces #2}%
+  \ifdim\wd0 > 0pt
+    \def\lefttext{#1}%  have both texts
+    \def\righttext{#2}%
+  \else
+    \def\lefttext{#1}%  have only one text
+    \def\righttext{#1}%
+  \fi
+  %
+  \ifodd\pageno
+    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+  \else
+    \def\temp{\inleftmargin\lefttext}%
+  \fi
+  \temp
+}
+
+% @include FILE -- \input text of FILE.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+  \pushthisfilestack
+  \def\thisfile{#1}%
+  {%
+    \makevalueexpandable  % we want to expand any @value in FILE.
+    \turnoffactive        % and allow special characters in the expansion
+    \indexnofonts         % Allow `@@' and other weird things in file names.
+    \edef\temp{\noexpand\input #1 }%
+    %
+    % This trickery is to read FILE outside of a group, in case it makes
+    % definitions, etc.
+    \expandafter
+  }\temp
+  \popthisfilestack
+}
+\def\filenamecatcodes{%
+  \catcode`\\=\other
+  \catcode`~=\other
+  \catcode`^=\other
+  \catcode`_=\other
+  \catcode`|=\other
+  \catcode`<=\other
+  \catcode`>=\other
+  \catcode`+=\other
+  \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+  \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+  the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+  \ifhmode
+    \let\next\centerH
+  \else
+    \let\next\centerV
+  \fi
+  \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+  {%
+    \hfil\break
+    \advance\hsize by -\leftskip
+    \advance\hsize by -\rightskip
+    \line{#1}%
+    \break
+  }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n   outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \defaultparindent = 0pt
+    \else
+      \defaultparindent = #1em
+    \fi
+  \fi
+  \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \lispnarrowing = 0pt
+    \else
+      \lispnarrowing = #1em
+    \fi
+  \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading.  If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\noneword
+    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+  \else\ifx\temp\insertword
+    \let\suppressfirstparagraphindent = \relax
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @firstparagraphindent option `\temp'}%
+  \fi\fi
+}
+
+% Here is how we actually suppress indentation.  Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+  \gdef\indent{%
+    \restorefirstparagraphindent
+    \indent
+  }%
+  \gdef\noindent{%
+    \restorefirstparagraphindent
+    \noindent
+  }%
+  \global\everypar = {%
+    \kern -\parindent
+    \restorefirstparagraphindent
+  }%
+}
+
+\gdef\restorefirstparagraphindent{%
+  \global \let \indent = \ptexindent
+  \global \let \noindent = \ptexnoindent
+  \global \everypar = {}%
+}
+
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+  \catcode`\_ = \active
+  \gdef\mathunderscore{%
+    \catcode`\_=\active
+    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+  }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care.  Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+  \tex
+  \mathunderscore
+  \let\\ = \mathbackslash
+  \mathactive
+  % make the texinfo accent commands work in math mode
+  \let\"=\ddot
+  \let\'=\acute
+  \let\==\bar
+  \let\^=\hat
+  \let\`=\grave
+  \let\u=\breve
+  \let\v=\check
+  \let\~=\tilde
+  \let\dotaccent=\dot
+  $\finishmath
+}
+\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+  \catcode`^ = \active
+  \catcode`< = \active
+  \catcode`> = \active
+  \catcode`+ = \active
+  \gdef\mathactive{%
+    \let^ = \ptexhat
+    \let< = \ptexless
+    \let> = \ptexgtr
+    \let+ = \ptexplus
+  }
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em.  So do
+% whichever is larger.
+%
+\def\dots{%
+  \leavevmode
+  \setbox0=\hbox{...}% get width of three periods
+  \ifdim\wd0 > 1.5em
+    \dimen0 = \wd0
+  \else
+    \dimen0 = 1.5em
+  \fi
+  \hbox to \dimen0{%
+    \hskip 0pt plus.25fil
+    .\hskip 0pt plus1fil
+    .\hskip 0pt plus1fil
+    .\hskip 0pt plus.5fil
+  }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+  \dots
+  \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \iflinks
+     \tryauxfile
+     % Open the new aux file.  TeX will close it automatically at exit.
+     \immediate\openout\auxfile=\jobname.aux
+   \fi % \openindices needs to do some work in any case.
+   \openindices
+   \let\setfilename=\comment % Ignore extra @setfilename cmds.
+   %
+   % If texinfo.cnf is present on the system, read it.
+   % Useful for site-wide @afourpaper, etc.
+   \openin 1 texinfo.cnf
+   \ifeof 1 \else \input texinfo.cnf \fi
+   \closein 1
+   %
+   \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+  \newindex{cp}%
+  \newcodeindex{fn}%
+  \newcodeindex{vr}%
+  \newcodeindex{tp}%
+  \newcodeindex{ky}%
+  \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set).  So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+  \ifx\pdfoutput\relax
+  \else
+    \ifcase\pdfoutput
+    \else
+      \pdftrue
+    \fi
+  \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places.  Thus, we have to
+% double any backslashes.  Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e.  Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's what we do).
+
+% double active backslashes.
+% 
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef at activebackslashdouble{%
+   @catcode`@\=@active
+   @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters.  hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens, with minor
+% changes for Texinfo.  It is included here under the GPL by permission
+% from the author, Heiko Oberdiek.
+% 
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+% 
+\def\HyPsdSubst#1#2#3{%
+  \def\HyPsdReplace##1#1##2\END{%
+    ##1%
+    \ifx\\##2\\%
+    \else
+      #2%
+      \HyReturnAfterFi{%
+        \HyPsdReplace##2\END
+      }%
+    \fi
+  }%
+  \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+  \xdef#1{#1}% redefine it as its expansion; the definition is simply
+             % \lastnode when called from \setref -> \pdfmkdest.
+  \HyPsdSubst{(}{\realbackslash(}{#1}%
+  \HyPsdSubst{)}{\realbackslash)}{#1}%
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found.  (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+  %
+  % Color manipulation macros based on pdfcolor.tex.
+  \def\cmykDarkRed{0.28 1 1 0.35}
+  \def\cmykBlack{0 0 0 1}
+  %
+  \def\pdfsetcolor#1{\pdfliteral{#1 k}}
+  % Set color, and create a mark which defines \thiscolor accordingly,
+  % so that \makeheadline knows which color to restore.
+  \def\setcolor#1{%
+    \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+    \domark
+    \pdfsetcolor{#1}%
+  }
+  %
+  \def\maincolor{\cmykBlack}
+  \pdfsetcolor{\maincolor}
+  \edef\thiscolor{\maincolor}
+  \def\lastcolordefs{}
+  %
+  \def\makefootline{%
+    \baselineskip24pt
+    \line{\pdfsetcolor{\maincolor}\the\footline}%
+  }
+  %
+  \def\makeheadline{%
+    \vbox to 0pt{%
+      \vskip-22.5pt
+      \line{%
+        \vbox to8.5pt{}%
+        % Extract \thiscolor definition from the marks.
+        \getcolormarks
+        % Typeset the headline with \maincolor, then restore the color.
+        \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+      }%
+      \vss
+    }%
+    \nointerlineskip
+  }
+  %
+  %
+  \pdfcatalog{/PageMode /UseOutlines}
+  %
+  % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+  \def\dopdfimage#1#2#3{%
+    \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+    \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+    %
+    % pdftex (and the PDF format) support .png, .jpg, .pdf (among
+    % others).  Let's try in that order.
+    \let\pdfimgext=\empty
+    \begingroup
+      \openin 1 #1.pdf \ifeof 1
+        \openin 1 #1.PDF \ifeof 1
+          \openin 1 #1.png \ifeof 1
+            \openin 1 #1.jpg \ifeof 1
+              \openin 1 #1.jpeg \ifeof 1
+                \openin 1 #1.JPG \ifeof 1
+                  \errhelp = \nopdfimagehelp
+                  \errmessage{Could not find image file #1 for pdf}%
+                 \else \gdef\pdfimgext{JPG}%
+                 \fi
+                \else \gdef\pdfimgext{jpeg}%
+                \fi
+              \else \gdef\pdfimgext{jpg}%
+              \fi
+            \else \gdef\pdfimgext{png}%
+            \fi
+          \else \gdef\pdfimgext{PDF}%
+          \fi
+        \else \gdef\pdfimgext{pdf}%
+        \fi
+      \closein 1
+    \endgroup
+    %
+    % without \immediate, ancient pdftex seg faults when the same image is
+    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
+    \ifnum\pdftexversion < 14
+      \immediate\pdfimage
+    \else
+      \immediate\pdfximage
+    \fi
+      \ifdim \wd0 >0pt width \imagewidth \fi
+      \ifdim \wd2 >0pt height \imageheight \fi
+      \ifnum\pdftexversion<13
+         #1.\pdfimgext
+       \else
+         {#1.\pdfimgext}%
+       \fi
+    \ifnum\pdftexversion < 14 \else
+      \pdfrefximage \pdflastximage
+    \fi}
+  %
+  \def\pdfmkdest#1{{%
+    % We have to set dummies so commands such as @code, and characters
+    % such as \, aren't expanded when present in a section title.
+    \indexnofonts
+    \turnoffactive
+    \activebackslashdouble
+    \makevalueexpandable
+    \def\pdfdestname{#1}%
+    \backslashparens\pdfdestname
+    \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+  }}
+  %
+  % used to mark target names; must be expandable.
+  \def\pdfmkpgn#1{#1}
+  %
+  % by default, use a color that is dark enough to print on paper as
+  % nearly black, but still distinguishable for online viewing.
+  \def\urlcolor{\cmykDarkRed}
+  \def\linkcolor{\cmykDarkRed}
+  \def\endlink{\setcolor{\maincolor}\pdfendlink}
+  %
+  % Adding outlines to PDF; macros for calculating structure of outlines
+  % come from Petr Olsak
+  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+    \else \csname#1\endcsname \fi}
+  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+    \advance\tempnum by 1
+    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+  %
+  % #1 is the section text, which is what will be displayed in the
+  % outline by the pdf viewer.  #2 is the pdf expression for the number
+  % of subentries (or empty, for subsubsections).  #3 is the node text,
+  % which might be empty if this toc entry had no corresponding node.
+  % #4 is the page number
+  %
+  \def\dopdfoutline#1#2#3#4{%
+    % Generate a link to the node text if that exists; else, use the
+    % page number.  We could generate a destination for the section
+    % text in the case where a section has no node, but it doesn't
+    % seem worth the trouble, since most documents are normally structured.
+    \def\pdfoutlinedest{#3}%
+    \ifx\pdfoutlinedest\empty
+      \def\pdfoutlinedest{#4}%
+    \else
+      % Doubled backslashes in the name.
+      {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+       \backslashparens\pdfoutlinedest}%
+    \fi
+    %
+    % Also double the backslashes in the display string.
+    {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+     \backslashparens\pdfoutlinetext}%
+    %
+    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+  }
+  %
+  \def\pdfmakeoutlines{%
+    \begingroup
+      % Thanh's hack / proper braces in bookmarks
+      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+      %
+      % Read toc silently, to get counts of subentries for \pdfoutline.
+      \def\numchapentry##1##2##3##4{%
+	\def\thischapnum{##2}%
+	\def\thissecnum{0}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsecentry##1##2##3##4{%
+	\advancenumber{chap\thischapnum}%
+	\def\thissecnum{##2}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsubsecentry##1##2##3##4{%
+	\advancenumber{sec\thissecnum}%
+	\def\thissubsecnum{##2}%
+      }%
+      \def\numsubsubsecentry##1##2##3##4{%
+	\advancenumber{subsec\thissubsecnum}%
+      }%
+      \def\thischapnum{0}%
+      \def\thissecnum{0}%
+      \def\thissubsecnum{0}%
+      %
+      % use \def rather than \let here because we redefine \chapentry et
+      % al. a second time, below.
+      \def\appentry{\numchapentry}%
+      \def\appsecentry{\numsecentry}%
+      \def\appsubsecentry{\numsubsecentry}%
+      \def\appsubsubsecentry{\numsubsubsecentry}%
+      \def\unnchapentry{\numchapentry}%
+      \def\unnsecentry{\numsecentry}%
+      \def\unnsubsecentry{\numsubsecentry}%
+      \def\unnsubsubsecentry{\numsubsubsecentry}%
+      \readdatafile{toc}%
+      %
+      % Read toc second time, this time actually producing the outlines.
+      % The `-' means take the \expnumber as the absolute number of
+      % subentries, which we calculated on our first read of the .toc above.
+      %
+      % We use the node names as the destinations.
+      \def\numchapentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+      \def\numsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+      \def\numsubsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+      \def\numsubsubsecentry##1##2##3##4{% count is always zero
+        \dopdfoutline{##1}{}{##3}{##4}}%
+      %
+      % PDF outlines are displayed using system fonts, instead of
+      % document fonts.  Therefore we cannot use special characters,
+      % since the encoding is unknown.  For example, the eogonek from
+      % Latin 2 (0xea) gets translated to a | character.  Info from
+      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+      %
+      % xx to do this right, we have to translate 8-bit characters to
+      % their "best" equivalent, based on the @documentencoding.  Right
+      % now, I guess we'll just let the pdf reader have its way.
+      \indexnofonts
+      \setupdatafile
+      \catcode`\\=\active \otherbackslash
+      \input \tocreadfilename
+    \endgroup
+  }
+  %
+  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+    \ifx\PP\D\let\nextsp\relax
+    \else\let\nextsp\skipspaces
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
+    \fi
+    \nextsp}
+  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+  \ifnum\pdftexversion < 14
+    \let \startlink \pdfannotlink
+  \else
+    \let \startlink \pdfstartlink
+  \fi
+  % make a live url in pdf output.
+  \def\pdfurl#1{%
+    \begingroup
+      % it seems we really need yet another set of dummies; have not
+      % tried to figure out what each command should do in the context
+      % of @url.  for now, just make @/ a no-op, that's the only one
+      % people have actually reported a problem with.
+      % 
+      \normalturnoffactive
+      \def\@{@}%
+      \let\/=\empty
+      \makevalueexpandable
+      \leavevmode\setcolor{\urlcolor}%
+      \startlink attr{/Border [0 0 0]}%
+        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+    \endgroup}
+  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+  \def\maketoks{%
+    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+    \ifx\first0\adn0
+    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+    \else
+      \ifnum0=\countA\else\makelink\fi
+      \ifx\first.\let\next=\done\else
+        \let\next=\maketoks
+        \addtokens{\toksB}{\the\toksD}
+        \ifx\first,\addtokens{\toksB}{\space}\fi
+      \fi
+    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+    \next}
+  \def\makelink{\addtokens{\toksB}%
+    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+  \def\pdflink#1{%
+    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+    \setcolor{\linkcolor}#1\endlink}
+  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+  \let\pdfmkdest = \gobble
+  \let\pdfurl = \gobble
+  \let\endlink = \relax
+  \let\setcolor = \gobble
+  \let\pdfsetcolor = \gobble
+  \let\pdfmakeoutlines = \relax
+\fi  % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+  \csname ten#1\endcsname  % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\def\setleading#1{%
+  \dimen0 = #1\relax
+  \normalbaselineskip = \baselinefactor\dimen0
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+% PDF CMaps.  See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\undefined \else
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1IT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1TT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+  \font#1=\fontprefix#2#3 scaled #4
+  \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+% emacs-page end of cmaps
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt.  This is the default in
+% Texinfo.
+% 
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit.  This is for the GNU
+% Press printing of the Emacs 22 manual.  Maybe other manuals in the
+% future.  Used with @smallbook, which sets the leading to 12pt.
+% 
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12 
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+% reduce space between paragraphs
+\divide\parskip by 2
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% We provide the user-level command
+%   @fonttextsize 10
+% (or 11) to redefine the text font size.  pt is assumed.
+% 
+\def\xword{10}
+\def\xiword{11}
+%
+\parseargdef\fonttextsize{%
+  \def\textsizearg{#1}%
+  \wlog{doing @fonttextsize \textsizearg}%
+  %
+  % Set \globaldefs so that documents can use this inside @tex, since
+  % makeinfo 4.8 does not support it, but we need it nonetheless.
+  % 
+ \begingroup \globaldefs=1
+  \ifx\textsizearg\xword \definetextfontsizex
+  \else \ifx\textsizearg\xiword \definetextfontsizexi
+  \else
+    \errhelp=\EMsimple
+    \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+  \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+  \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this because \STYLE needs to also set the
+% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower).  These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+  \let\tenttsl=\textttsl
+  \def\curfontsize{text}%
+  \def\lsize{reduced}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+  \let\tenttsl=\titlettsl
+  \def\curfontsize{title}%
+  \def\lsize{chap}\def\lllsize{subsec}%
+  \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+  \let\tenttsl=\chapttsl
+  \def\curfontsize{chap}%
+  \def\lsize{sec}\def\lllsize{text}%
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+  \let\tenttsl=\secttsl
+  \def\curfontsize{sec}%
+  \def\lsize{subsec}\def\lllsize{reduced}%
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+  \let\tenttsl=\ssecttsl
+  \def\curfontsize{ssec}%
+  \def\lsize{text}\def\lllsize{small}%
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+  \let\tenttsl=\reducedttsl
+  \def\curfontsize{reduced}%
+  \def\lsize{small}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+  \let\tenttsl=\smallttsl
+  \def\curfontsize{small}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+  \let\tenttsl=\smallerttsl
+  \def\curfontsize{smaller}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+%   8.5x11=86   smallbook=72  a4=90  a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+%   8.5x11=90+  smallbook=80  a4=90+  a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt.  So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+%   8.5x11=71  smallbook=60  a4=75  a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+                    \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl.  We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+  \def\plainfrenchspacing{%
+    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+    \def\endofsentencespacefactor{1000}% for @. and friends
+  }
+  \def\plainnonfrenchspacing{%
+    \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+    \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+    \def\endofsentencespacefactor{3000}% for @. and friends
+  }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+  {\tt \rawbackslash \plainfrenchspacing #1}%
+  \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}{OT1}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+    \vbox{\hrule\kern-0.4pt
+     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+    \kern-0.4pt\hrule}%
+  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+\def\key #1{{\nohyphenation \uppercase{#1}}\null}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \plainfrenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+  \catcode`\-=\active \catcode`\_=\active
+  \catcode`\'=\active \catcode`\`=\active
+  %
+  \global\def\code{\begingroup
+    \catcode\rquoteChar=\active \catcode\lquoteChar=\active
+    \let'\codequoteright \let`\codequoteleft
+    %
+    \catcode\dashChar=\active  \catcode\underChar=\active
+    \ifallowcodebreaks
+     \let-\codedash
+     \let_\codeunder
+    \else
+     \let-\realdash
+     \let_\realunder
+    \fi
+    \codex
+  }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+  % will therefore expand the active definition of _, which is us
+  % (inside @code that is), therefore an endless loop.
+  \ifusingtt{\ifmmode
+               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+             \else\normalunderscore \fi
+             \discretionary{}{}{}}%
+            {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__.  This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general.  @allowcodebreaks provides a way to control this.
+% 
+\newif\ifallowcodebreaks  \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\keywordtrue
+    \allowcodebreakstrue
+  \else\ifx\txiarg\keywordfalse
+    \allowcodebreaksfalse
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+  \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+%   `example' (@kbd uses ttsl only inside of @example and friends),
+%   or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\worddistinct
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+  \else\ifx\txiarg\wordexample
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+  \else\ifx\txiarg\wordcode
+    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+  \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow   (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+  \unsepspaces
+  \pdfurl{#1}%
+  \setbox0 = \hbox{\ignorespaces #3}%
+  \ifdim\wd0 > 0pt
+    \unhbox0 % third arg given, show only that
+  \else
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0 > 0pt
+      \ifpdf
+        \unhbox0             % PDF: 2nd arg given, show only it
+      \else
+        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+      \fi
+    \else
+      \code{#1}% only url given, so show it
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+  \def\email#1{\doemail#1,,\finish}
+  \def\doemail#1,#2,#3\finish{\begingroup
+    \unsepspaces
+    \pdfurl{mailto:#1}%
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+    \endlink
+  \endgroup}
+\else
+  \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}}              % roman font
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+% 
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+  {\selectfonts\lsize #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+% 
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+  {\plainfrenchspacing #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+% 
+% Although only regular is the truly official Euro symbol, we ignore
+% that.  The Euro is designed to be slightly taller than the regular
+% font height.
+% 
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+% 
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+% 
+% Also doesn't work in math.  Do we need to do math with euro symbols?
+% Hope not.
+% 
+% 
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+  % We set the font at each command, rather than predefining it in
+  % \textfonts and the other font-switching commands, so that
+  % installations which never need the symbol don't have to have the
+  % font installed.
+  % 
+  % There is only one designed size (nominal 10pt), so we always scale
+  % that to the current nominal size.
+  % 
+  % By the way, simply using "at 1em" works for cmr10 and the like, but
+  % does not work for cmbx10 and other extended/shrunken fonts.
+  % 
+  \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+  %
+  \ifx\curfontstyle\bfstylename 
+    % bold:
+    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+  \else 
+    % regular:
+    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+  \fi
+  \thiseurofont
+}
+
+% Hacks for glyphs from the EC fonts similar to \euro.  We don't
+% use \let for the aliases, because sometimes we redefine the original
+% macro, and the alias should reflect the redefinition.
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+\def\ecfont{%
+  % We can't distinguish serif/sanserif and italic/slanted, but this
+  % is used for crude hacks anyway (like adding French and German
+  % quotes to documents typeset with CM, where we lose kerning), so
+  % hopefully nobody will notice/care.
+  \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+  \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+  \ifx\curfontstyle\bfstylename
+    % bold:
+    \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+  \else
+    % regular:
+    \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+  \fi
+  \thisecfont
+}
+
+% @registeredsymbol - R in a circle.  The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+               \hfil\crcr\Orb}}%
+    }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+%  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
+% so we'll define it if necessary.
+% 
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+  % Open one extra group, as we want to close it in the middle of \Etitlepage.
+  \begingroup
+    \parindent=0pt \textfonts
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+      \iffinishedtitlepage\else
+	 \finishtitlepage
+      \fi
+      \let\page = \oldpage
+      \page
+      \null
+    }%
+}
+
+\def\Etitlepage{%
+    \iffinishedtitlepage\else
+	\finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+  \endgroup
+  %
+  % Need this before the \...aftertitlepage checks so that if they are
+  % in effect the toc pages will come out with page numbers.
+  \HEADINGSon
+  %
+  % If they want short, they certainly want long too.
+  \ifsetshortcontentsaftertitlepage
+    \shortcontents
+    \contents
+    \global\let\shortcontents = \relax
+    \global\let\contents = \relax
+  \fi
+  %
+  \ifsetcontentsaftertitlepage
+    \contents
+    \global\let\contents = \relax
+    \global\let\shortcontents = \relax
+  \fi
+}
+
+\def\finishtitlepage{%
+  \vskip4pt \hrule height 2pt width \hsize
+  \vskip\titlepagebottomglue
+  \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+		\let\tt=\authortt}
+
+\parseargdef\title{%
+  \checkenv\titlepage
+  \leftline{\titlefonts\rm #1}
+  % print a rule at the page bottom also.
+  \finishedtitlepagefalse
+  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+  \checkenv\titlepage
+  {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+  \def\temp{\quotation}%
+  \ifx\thisenv\temp
+    \def\quotationauthor{#1}% printed in \Equotation.
+  \else
+    \checkenv\titlepage
+    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+    {\authorfont \leftline{#1}}%
+  \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline    % headline on even pages
+\newtoks\oddheadline     % headline on odd pages
+\newtoks\evenfootline    % footline on even pages
+\newtoks\oddfootline     % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+  %
+  % Leave some space for the footline.  Hopefully ok to assume
+  % @evenfooting will not be used by itself.
+  \global\advance\pageheight by -12pt
+  \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top     \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom  \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+                          \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+                          \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+  \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+  \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+  \number\day\space
+  \ifcase\month
+  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+  \fi
+  \space\number\year}
+\fi
+
+% @settitle line...  specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemindicate{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  However, if
+    % what follows is an environment such as @example, there will be no
+    % \parskip glue; then the negative vskip we just inserted would
+    % cause the example and the item to crash together.  So we use this
+    % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+    % \parskip glue after all.  Section titles are handled this way also.
+    % 
+    \penalty 10001
+    \endgroup
+    \itemxneedsnegativevskipfalse
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.
+    \noindent
+    % Do this with kerns and \unhbox so that if there is a footnote in
+    % the item text, it can migrate to the main vertical list and
+    % eventually be printed.
+    \nobreak\kern-\tableindent
+    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+    \unhbox0
+    \nobreak\kern\dimen0
+    \endgroup
+    \itemxneedsnegativevskiptrue
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+  \let\itemindex\gobble
+  \tablecheck{table}%
+}
+\envdef\ftable{%
+  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+  \tablecheck{ftable}%
+}
+\envdef\vtable{%
+  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+  \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+  \ifnum \the\catcode`\^^M=\active
+    \endgroup
+    \errmessage{This command won't work in this context; perhaps the problem is
+      that we are \inenvironment\thisenv}%
+    \def\next{\doignore{#1}}%
+  \else
+    \let\next\tablex
+  \fi
+  \next
+}
+\def\tablex#1{%
+  \def\itemindicate{#1}%
+  \parsearg\tabley
+}
+\def\tabley#1{%
+  {%
+    \makevalueexpandable
+    \edef\temp{\noexpand\tablez #1\space\space\space}%
+    \expandafter
+  }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+  \aboveenvbreak
+  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+  \ifnum 0#2>0 \tableindent=#2\mil \fi
+  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+  \itemmax=\tableindent
+  \advance \itemmax by -\itemmargin
+  \advance \leftskip by \tableindent
+  \exdentamount=\tableindent
+  \parindent = 0pt
+  \parskip = \smallskipamount
+  \ifdim \parskip=0pt \parskip=2pt \fi
+  \let\item = \internalBitem
+  \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+  \aboveenvbreak
+  \itemmax=\itemindent
+  \advance\itemmax by -\itemmargin
+  \advance\leftskip by \itemindent
+  \exdentamount=\itemindent
+  \parindent=0pt
+  \parskip=\smallskipamount
+  \ifdim\parskip=0pt \parskip=2pt \fi
+  \def\itemcontents{#1}%
+  % @itemize with no arg is equivalent to @itemize @bullet.
+  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+  \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+  \advance\itemno by 1  % for enumerations
+  {\let\par=\endgraf \smallbreak}% reasonable place to break
+  {%
+   % If the document has an @itemize directly after a section title, a
+   % \nobreak will be last on the list, and \sectionheading will have
+   % done a \vskip-\parskip.  In that case, we don't want to zero
+   % parskip, or the item text will crash with the heading.  On the
+   % other hand, when there is normal text preceding the item (as there
+   % usually is), we do want to zero parskip, or there would be too much
+   % space.  In that case, we won't have a \nobreak before.  At least
+   % that's the theory.
+   \ifnum\lastpenalty<10000 \parskip=0in \fi
+   \noindent
+   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+   \vadjust{\penalty 1200}}% not good to break after first line of item.
+  \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab at tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item
+%   first col stuff
+%   @tab
+%   second col stuff
+%   @tab
+%   third col
+%   @item first col stuff @tab second col stuff
+%   @tab Many paragraphs of text may be used in any column.
+%
+%         They will wrap at the width determined by the template.
+%   @item at tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1.  We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+  \global\advance\colcount by 1
+  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+  \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+  \def\firstarg{#1}%
+  \ifx\firstarg\xendsetuptable
+    \let\go = \relax
+  \else
+    \ifx\firstarg\xcolumnfractions
+      \global\setpercenttrue
+    \else
+      \ifsetpercent
+         \let\go\pickupwholefraction
+      \else
+         \global\advance\colcount by 1
+         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+                   % separator; typically that is always in the input, anyway.
+         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+      \fi
+    \fi
+    \ifx\go\pickupwholefraction
+      % Put the argument back for the \pickupwholefraction call, so
+      % we'll always have a period there to be parsed.
+      \def\go{\pickupwholefraction#1}%
+    \else
+      \let\go = \setuptable
+    \fi%
+  \fi
+  \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry.  Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp.  But then the space in a template
+% line is not enough.  That is bad.  So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+%					--karl, nathan at acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab  % insert after every tab.
+%
+\envdef\multitable{%
+  \vskip\parskip
+  \startsavinginserts
+  %
+  % @item within a multitable starts a normal row.
+  % We use \def instead of \let so that if one of the multitable entries
+  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+  % \endtemplate) expanding \doitemize.
+  \def\item{\crcr}%
+  %
+  \tolerance=9500
+  \hbadness=9500
+  \setmultitablespacing
+  \parskip=\multitableparskip
+  \parindent=\multitableparindent
+  \overfullrule=0pt
+  \global\colcount=0
+  %
+  \everycr = {%
+    \noalign{%
+      \global\everytab={}%
+      \global\colcount=0 % Reset the column counter.
+      % Check for saved footnotes, etc.
+      \checkinserts
+      % Keeps underfull box messages off when table breaks over pages.
+      %\filbreak
+	% Maybe so, but it also creates really weird page breaks when the
+	% table breaks over pages. Wouldn't \vfil be better?  Wait until the
+	% problem manifests itself, so it can be fixed for real --karl.
+    }%
+  }%
+  %
+  \parsearg\domultitable
+}
+\def\domultitable#1{%
+  % To parse everything between @multitable and @item:
+  \setuptable#1 \endsetuptable
+  %
+  % This preamble sets up a generic column definition, which will
+  % be used as many times as user calls for columns.
+  % \vtop will set a single line and will also let text wrap and
+  % continue for many paragraphs if desired.
+  \halign\bgroup &%
+    \global\advance\colcount by 1
+    \multistrut
+    \vtop{%
+      % Use the current \colcount to find the correct column width:
+      \hsize=\expandafter\csname col\the\colcount\endcsname
+      %
+      % In order to keep entries from bumping into each other
+      % we will add a \leftskip of \multitablecolspace to all columns after
+      % the first one.
+      %
+      % If a template has been used, we will add \multitablecolspace
+      % to the width of each template entry.
+      %
+      % If the user has set preamble in terms of percent of \hsize we will
+      % use that dimension as the width of the column, and the \leftskip
+      % will keep entries from bumping into each other.  Table will start at
+      % left margin and final column will justify at right margin.
+      %
+      % Make sure we don't inherit \rightskip from the outer environment.
+      \rightskip=0pt
+      \ifnum\colcount=1
+	% The first column will be indented with the surrounding text.
+	\advance\hsize by\leftskip
+      \else
+	\ifsetpercent \else
+	  % If user has not set preamble in terms of percent of \hsize
+	  % we will advance \hsize by \multitablecolspace.
+	  \advance\hsize by \multitablecolspace
+	\fi
+       % In either case we will make \leftskip=\multitablecolspace:
+      \leftskip=\multitablecolspace
+      \fi
+      % Ignoring space at the beginning and end avoids an occasional spurious
+      % blank line, when TeX decides to break the line at the space before the
+      % box from the multistrut, so the strut ends up on a line by itself.
+      % For example:
+      % @multitable @columnfractions .11 .89
+      % @item @code{#}
+      % @tab Legal holiday which is valid in major parts of the whole country.
+      % Is automatically provided with highlighting sequences respectively
+      % marking characters.
+      \noindent\ignorespaces##\unskip\multistrut
+    }\cr
+}
+\def\Emultitable{%
+  \crcr
+  \egroup % end the \halign
+  \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+  \def\multistrut{\strut}% just use the standard line spacing
+  %
+  % Compute \multitablelinespace (if not defined by user) for use in
+  % \multitableparskip calculation.  We used define \multistrut based on
+  % this, but (ironically) that caused the spacing to be off.
+  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%%        If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed.  They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested.  But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+  \expandafter\let\csname #1\endcsname = \relax
+  \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+  % Scan in ``verbatim'' mode:
+  \obeylines
+  \catcode`\@ = \other
+  \catcode`\{ = \other
+  \catcode`\} = \other
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \spaceisspace
+  %
+  % Count number of #1's that we've seen.
+  \doignorecount = 0
+  %
+  % Swallow text until we reach the matching `@end #1'.
+  \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+  \obeylines %
+  %
+  \gdef\dodoignore#1{%
+    % #1 contains the command name as a string, e.g., `ifinfo'.
+    %
+    % Define a command to find the next `@end #1'.
+    \long\def\doignoretext##1^^M at end #1{%
+      \doignoretextyyy##1^^M@#1\_STOP_}%
+    %
+    % And this command to find another #1 command, at the beginning of a
+    % line.  (Otherwise, we would consider a line `@c @ifset', for
+    % example, to count as an @ifset for nesting.)
+    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+    %
+    % And now expand that command.
+    \doignoretext ^^M%
+  }%
+}
+
+\def\doignoreyyy#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty			% Nothing found.
+    \let\next\doignoretextzzz
+  \else					% Found a nested condition, ...
+    \advance\doignorecount by 1
+    \let\next\doignoretextyyy		% ..., look for another.
+    % If we're here, #1 ends with ^^M\ifinfo (for example).
+  \fi
+  \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+  \ifnum\doignorecount = 0	% We have just found the outermost @end.
+    \let\next\enddoignore
+  \else				% Still inside a nested condition.
+    \advance\doignorecount by -1
+    \let\next\doignoretext      % Look for the next @end.
+  \fi
+  \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+  % Ignore anything after the last `@end #1'; this matters in verbatim
+  % environments, where otherwise the newline after an ignored conditional
+  % would result in a blank line in the output.
+  \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  {%
+    \makevalueexpandable
+    \def\temp{#2}%
+    \edef\next{\gdef\makecsname{SET#1}}%
+    \ifx\temp\empty
+      \next{}%
+    \else
+      \setzzz#2\endsetzzz
+    \fi
+  }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+  {%
+    \makevalueexpandable
+    \global\expandafter\let\csname SET#1\endcsname=\relax
+  }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+  \catcode`\- = \active \catcode`\_ = \active
+  %
+  \gdef\makevalueexpandable{%
+    \let\value = \expandablevalue
+    % We don't want these characters active, ...
+    \catcode`\-=\other \catcode`\_=\other
+    % ..., but we might end up with active ones in the argument if
+    % we're called from @code, as @code{@value{foo-bar_}}, though.
+    % So \let them to their normal equivalents.
+    \let-\realdash \let_\normalunderscore
+  }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file.  This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    {[No value for ``#1'']}%
+    \message{Variable `#1', used in @value, is not set.}%
+  \else
+    \csname SET#1\endcsname
+  \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+  {%
+    \makevalueexpandable
+    \let\next=\empty
+    \expandafter\ifx\csname SET#2\endcsname\relax
+      #1% If not set, redefine \next.
+    \fi
+    \expandafter
+  }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+    \noexpand\doindex{#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%
+    \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+  % Only do \closeout if we haven't already done it, else we'll end up
+  % closing the target index.
+  \expandafter \ifx\csname donesynindex#2\endcsname \relax
+    % The \closeout helps reduce unnecessary open files; the limit on the
+    % Acorn RISC OS is a mere 16 files.
+    \expandafter\closeout\csname#2indfile\endcsname
+    \expandafter\let\csname donesynindex#2\endcsname = 1
+  \fi
+  % redefine \fooindfile:
+  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+  \expandafter\let\csname#2indfile\endcsname=\temp
+  % redefine \fooindex:
+  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+  \escapechar = `\\     % use backslash in output files.
+  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+  \def\ {\realbackslash\space }%
+  %
+  % Need these in case \tex is in effect and \{ is a \delimiter again.
+  % But can't use \lbracecmd and \rbracecmd because texindex assumes
+  % braces and backslashes are used only as delimiters.
+  \let\{ = \mylbrace
+  \let\} = \myrbrace
+  %
+  % I don't entirely understand this, but when an index entry is
+  % generated from a macro call, the \endinput which \scanmacro inserts
+  % causes processing to be prematurely terminated.  This is,
+  % apparently, because \indexsorttmp is fully expanded, and \endinput
+  % is an expandable command.  The redefinition below makes \endinput
+  % disappear altogether for that purpose -- although logging shows that
+  % processing continues to some further point.  On the other hand, it
+  % seems \endinput does not hurt in the printed index arg, since that
+  % is still getting written without apparent harm.
+  % 
+  % Sample source (mac-idx3.tex, reported by Graham Percival to
+  % help-texinfo, 22may06):
+  % @macro funindex {WORD}
+  % @findex xyz
+  % @end macro
+  % ...
+  % @funindex commtest
+  % 
+  % The above is not enough to reproduce the bug, but it gives the flavor.
+  % 
+  % Sample whatsit resulting:
+  % . at write3{\entry{xyz}{@folio }{@code {xyz at endinput }}}
+  % 
+  % So:
+  \let\endinput = \empty
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% For the aux and toc files, @ is the escape character.  So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files).  When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+  \def\@{@@}%
+  \def\ {@ }%
+  \let\{ = \lbraceatcmd
+  \let\} = \rbraceatcmd
+  %
+  % Do the redefinitions.
+  \commondummies
+  \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+  %
+  % \definedummyword defines \#1 as \string\#1\space, thus effectively
+  % preventing its expansion.  This is used only for control% words,
+  % not control letters, because the \space would be incorrect for
+  % control characters, but is needed to separate the control word
+  % from whatever follows.
+  %
+  % For control letters, we have \definedummyletter, which omits the
+  % space.
+  %
+  % These can be used both for control words that take an argument and
+  % those that do not.  If it is followed by {arg} in the input, then
+  % that will dutifully get written to the index (or wherever).
+  %
+  \def\definedummyword  ##1{\def##1{\string##1\space}}%
+  \def\definedummyletter##1{\def##1{\string##1}}%
+  \let\definedummyaccent\definedummyletter
+  %
+  \commondummiesnofonts
+  %
+  \definedummyletter\_%
+  %
+  % Non-English letters.
+  \definedummyword\AA
+  \definedummyword\AE
+  \definedummyword\L
+  \definedummyword\OE
+  \definedummyword\O
+  \definedummyword\aa
+  \definedummyword\ae
+  \definedummyword\l
+  \definedummyword\oe
+  \definedummyword\o
+  \definedummyword\ss
+  \definedummyword\exclamdown
+  \definedummyword\questiondown
+  \definedummyword\ordf
+  \definedummyword\ordm
+  %
+  % Although these internal commands shouldn't show up, sometimes they do.
+  \definedummyword\bf
+  \definedummyword\gtr
+  \definedummyword\hat
+  \definedummyword\less
+  \definedummyword\sf
+  \definedummyword\sl
+  \definedummyword\tclose
+  \definedummyword\tt
+  %
+  \definedummyword\LaTeX
+  \definedummyword\TeX
+  %
+  % Assorted special characters.
+  \definedummyword\bullet
+  \definedummyword\comma
+  \definedummyword\copyright
+  \definedummyword\registeredsymbol
+  \definedummyword\dots
+  \definedummyword\enddots
+  \definedummyword\equiv
+  \definedummyword\error
+  \definedummyword\euro
+  \definedummyword\guillemetleft
+  \definedummyword\guillemetright
+  \definedummyword\guilsinglleft
+  \definedummyword\guilsinglright
+  \definedummyword\expansion
+  \definedummyword\minus
+  \definedummyword\pounds
+  \definedummyword\point
+  \definedummyword\print
+  \definedummyword\quotedblbase
+  \definedummyword\quotedblleft
+  \definedummyword\quotedblright
+  \definedummyword\quoteleft
+  \definedummyword\quoteright
+  \definedummyword\quotesinglbase
+  \definedummyword\result
+  \definedummyword\textdegree
+  %
+  % We want to disable all macros so that they are not expanded by \write.
+  \macrolist
+  %
+  \normalturnoffactive
+  %
+  % Handle some cases of @value -- where it does not contain any
+  % (non-fully-expandable) commands.
+  \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+  % Control letters and accents.
+  \definedummyletter\!%
+  \definedummyaccent\"%
+  \definedummyaccent\'%
+  \definedummyletter\*%
+  \definedummyaccent\,%
+  \definedummyletter\.%
+  \definedummyletter\/%
+  \definedummyletter\:%
+  \definedummyaccent\=%
+  \definedummyletter\?%
+  \definedummyaccent\^%
+  \definedummyaccent\`%
+  \definedummyaccent\~%
+  \definedummyword\u
+  \definedummyword\v
+  \definedummyword\H
+  \definedummyword\dotaccent
+  \definedummyword\ringaccent
+  \definedummyword\tieaccent
+  \definedummyword\ubaraccent
+  \definedummyword\udotaccent
+  \definedummyword\dotless
+  %
+  % Texinfo font commands.
+  \definedummyword\b
+  \definedummyword\i
+  \definedummyword\r
+  \definedummyword\sc
+  \definedummyword\t
+  %
+  % Commands that take arguments.
+  \definedummyword\acronym
+  \definedummyword\cite
+  \definedummyword\code
+  \definedummyword\command
+  \definedummyword\dfn
+  \definedummyword\emph
+  \definedummyword\env
+  \definedummyword\file
+  \definedummyword\kbd
+  \definedummyword\key
+  \definedummyword\math
+  \definedummyword\option
+  \definedummyword\pxref
+  \definedummyword\ref
+  \definedummyword\samp
+  \definedummyword\strong
+  \definedummyword\tie
+  \definedummyword\uref
+  \definedummyword\url
+  \definedummyword\var
+  \definedummyword\verb
+  \definedummyword\w
+  \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names.  It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+  % Accent commands should become @asis.
+  \def\definedummyaccent##1{\let##1\asis}%
+  % We can just ignore other control letters.
+  \def\definedummyletter##1{\let##1\empty}%
+  % Hopefully, all control words can become @asis.
+  \let\definedummyword\definedummyaccent
+  %
+  \commondummiesnofonts
+  %
+  % Don't no-op \tt, since it isn't a user-level command
+  % and is used in the definitions of the active chars like <, >, |, etc.
+  % Likewise with the other plain tex font commands.
+  %\let\tt=\asis
+  %
+  \def\ { }%
+  \def\@{@}%
+  % how to handle braces?
+  \def\_{\normalunderscore}%
+  %
+  % Non-English letters.
+  \def\AA{AA}%
+  \def\AE{AE}%
+  \def\L{L}%
+  \def\OE{OE}%
+  \def\O{O}%
+  \def\aa{aa}%
+  \def\ae{ae}%
+  \def\l{l}%
+  \def\oe{oe}%
+  \def\o{o}%
+  \def\ss{ss}%
+  \def\exclamdown{!}%
+  \def\questiondown{?}%
+  \def\ordf{a}%
+  \def\ordm{o}%
+  %
+  \def\LaTeX{LaTeX}%
+  \def\TeX{TeX}%
+  %
+  % Assorted special characters.
+  % (The following {} will end up in the sort string, but that's ok.)
+  \def\bullet{bullet}%
+  \def\comma{,}%
+  \def\copyright{copyright}%
+  \def\registeredsymbol{R}%
+  \def\dots{...}%
+  \def\enddots{...}%
+  \def\equiv{==}%
+  \def\error{error}%
+  \def\euro{euro}%
+  \def\guillemetleft{<<}%
+  \def\guillemetright{>>}%
+  \def\guilsinglleft{<}%
+  \def\guilsinglright{>}%
+  \def\expansion{==>}%
+  \def\minus{-}%
+  \def\pounds{pounds}%
+  \def\point{.}%
+  \def\print{-|}%
+  \def\quotedblbase{"}%
+  \def\quotedblleft{"}%
+  \def\quotedblright{"}%
+  \def\quoteleft{`}%
+  \def\quoteright{'}%
+  \def\quotesinglbase{,}%
+  \def\result{=>}%
+  \def\textdegree{degrees}%
+  %
+  % We need to get rid of all macros, leaving only the arguments (if present).
+  % Of course this is not nearly correct, but it is the best we can do for now.
+  % makeinfo does not expand macros in the argument to @deffn, which ends up
+  % writing an index entry, and texindex isn't prepared for an index sort entry
+  % that starts with \.
+  % 
+  % Since macro invocations are followed by braces, we can just redefine them
+  % to take a single TeX argument.  The case of a macro invocation that
+  % goes to end-of-line is not handled.
+  % 
+  \macrolist
+}
+
+\let\indexbackslash=0  %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+  \iflinks
+  {%
+    % Store the main index entry text (including the third arg).
+    \toks0 = {#2}%
+    % If third arg is present, precede it with a space.
+    \def\thirdarg{#3}%
+    \ifx\thirdarg\empty \else
+      \toks0 = \expandafter{\the\toks0 \space #3}%
+    \fi
+    %
+    \edef\writeto{\csname#1indfile\endcsname}%
+    %
+    \safewhatsit\dosubindwrite
+  }%
+  \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+  \fi
+  %
+  % Remember, we are within a group.
+  \indexdummies % Must do this here, since \bf, etc expand at this stage
+  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+      % so it will be output as is; and it will print as backslash.
+  %
+  % Process the index entry with all font commands turned off, to
+  % get the string to sort by.
+  {\indexnofonts
+   \edef\temp{\the\toks0}% need full expansion
+   \xdef\indexsorttmp{\temp}%
+  }%
+  %
+  % Set up the complete index entry, with both the sort key and
+  % the original text, including any font commands.  We write
+  % three arguments to \entry to the .?? file (four in the
+  % subentry case), texindex reduces to two when writing the .??s
+  % sorted result.
+  \edef\temp{%
+    \write\writeto{%
+      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+  }%
+  \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again.  Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero.  The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode.  We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip.  \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip.  The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z at skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{%
+\ifhmode
+  #1%
+\else
+  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+  \whatsitskip = \lastskip
+  \edef\lastskipmacro{\the\lastskip}%
+  \whatsitpenalty = \lastpenalty
+  %
+  % If \lastskip is nonzero, that means the last item was a
+  % skip.  And since a skip is discardable, that means this
+  % -\whatsitskip glue we're inserting is preceded by a
+  % non-discardable item, therefore it is not a potential
+  % breakpoint, therefore no \nobreak needed.
+  \ifx\lastskipmacro\zeroskipmacro
+  \else
+    \vskip-\whatsitskip
+  \fi
+  %
+  #1%
+  %
+  \ifx\lastskipmacro\zeroskipmacro
+    % If \lastskip was zero, perhaps the last item was a penalty, and
+    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
+    % to re-insert the same penalty (values >10000 are used for various
+    % signals); since we just inserted a non-discardable item, any
+    % following glue (such as a \parskip) would be a breakpoint.  For example:
+    % 
+    %   @deffn deffn-whatever
+    %   @vindex index-whatever
+    %   Description.
+    % would allow a break between the index-whatever whatsit
+    % and the "Description." paragraph.
+    \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+  \else
+    % On the other hand, if we had a nonzero \lastskip,
+    % this make-up glue would be preceded by a non-discardable item
+    % (the whatsit from the \write), so we must insert a \nobreak.
+    \nobreak\vskip\whatsitskip
+  \fi
+\fi
+}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \smallfonts \rm
+  \tolerance = 9500
+  \plainfrenchspacing
+  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+  %
+  % See if the index file exists and is nonempty.
+  % Change catcode of @ here so that if the index file contains
+  % \initial {@}
+  % as its first line, TeX doesn't complain about mismatched braces
+  % (because it thinks @} is a control sequence).
+  \catcode`\@ = 11
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    \putwordIndexNonexistent
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      \putwordIndexIsEmpty
+    \else
+      % Index files are almost Texinfo source, but we use \ as the escape
+      % character.  It would be better to use @, but that's too big a change
+      % to make right now.
+      \def\indexbackslash{\backslashcurfont}%
+      \catcode`\\ = 0
+      \escapechar = `\\
+      \begindoublecolumns
+      \input \jobname.#1s
+      \enddoublecolumns
+    \fi
+  \fi
+  \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  %
+  % We like breaks before the index initials, so insert a bonus.
+  \nobreak
+  \vskip 0pt plus 3\baselineskip
+  \penalty 0
+  \vskip 0pt plus -3\baselineskip
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  %
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  % Do our best not to break after the initial.
+  \nobreak
+  \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin.  It is used for index
+% and table of contents entries.  The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+%	\def\entry#1#2{...
+% But this freezes the catcodes in the argument, and can cause problems to
+% @code, which sets - active.  This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+%                                 --kasal, 21nov03
+\def\entry{%
+  \begingroup
+    %
+    % Start a new paragraph if necessary, so our assignments below can't
+    % affect previous text.
+    \par
+    %
+    % Do not fill out the last line with white space.
+    \parfillskip = 0in
+    %
+    % No extra space above this paragraph.
+    \parskip = 0in
+    %
+    % Do not prefer a separate line ending with a hyphen to fewer lines.
+    \finalhyphendemerits = 0
+    %
+    % \hangindent is only relevant when the entry text and page number
+    % don't both fit on one line.  In that case, bob suggests starting the
+    % dots pretty far over on the line.  Unfortunately, a large
+    % indentation looks wrong when the entry text itself is broken across
+    % lines.  So we use a small indentation and put up with long leaders.
+    %
+    % \hangafter is reset to 1 (which is the value we want) at the start
+    % of each paragraph, so we need not do anything with that.
+    \hangindent = 2em
+    %
+    % When the entry text needs to be broken, just fill out the first line
+    % with blank space.
+    \rightskip = 0pt plus1fil
+    %
+    % A bit of stretch before each entry for the benefit of balancing
+    % columns.
+    \vskip 0pt plus1pt
+    %
+    % Swallow the left brace of the text (first parameter):
+    \afterassignment\doentry
+    \let\temp =
+}
+\def\doentry{%
+    \bgroup % Instead of the swallowed brace.
+      \noindent
+      \aftergroup\finishentry
+      % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+    % #1 is the page number.
+    %
+    % The following is kludged to not output a line of dots in the index if
+    % there are no page numbers.  The next person who breaks this will be
+    % cursed by a Unix daemon.
+    \setbox\boxA = \hbox{#1}%
+    \ifdim\wd\boxA = 0pt
+      \ %
+    \else
+      %
+      % If we must, put the page number on a line of its own, and fill out
+      % this line with blank space.  (The \hfil is overwhelmed with the
+      % fill leaders glue in \indexdotfill if the page number does fit.)
+      \hfil\penalty50
+      \null\nobreak\indexdotfill % Have leaders before the page number.
+      %
+      % The `\ ' here is removed by the implicit \unskip that TeX does as
+      % part of (the primitive) \par.  Without it, a spurious underfull
+      % \hbox ensues.
+      \ifpdf
+	\pdfgettoks#1.%
+	\ \the\toksA
+      \else
+	\ #1%
+      \fi
+    \fi
+    \par
+  \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+  \parfillskip=0in
+  \parskip=0in
+  \hangindent=1in
+  \hangafter=1
+  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+  \ifpdf
+    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+  \else
+    #2
+  \fi
+  \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {%
+    %
+    % Here is a possibility not foreseen in manmac: if we accumulate a
+    % whole lot of material, we might end up calling this \output
+    % routine twice in a row (see the doublecol-lose test, which is
+    % essentially a couple of indexes with @setchapternewpage off).  In
+    % that case we just ship out what is in \partialpage with the normal
+    % output routine.  Generally, \partialpage will be empty when this
+    % runs and this will be a no-op.  See the indexspread.tex test case.
+    \ifvoid\partialpage \else
+      \onepageout{\pagecontents\partialpage}%
+    \fi
+    %
+    \global\setbox\partialpage = \vbox{%
+      % Unvbox the main output page.
+      \unvbox\PAGE
+      \kern-\topskip \kern\baselineskip
+    }%
+  }%
+  \eject % run that output routine to set \partialpage
+  %
+  % Use the double-column output routine for subsequent pages.
+  \output = {\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it in one place.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +-<1pt)
+  % as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  \advance\dimen@ by -\ht\partialpage
+  %
+  % box0 will be the left-hand column, box2 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255
+  \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+  \unvbox\partialpage
+  %
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+  % The following penalty ensures that the page builder is exercised
+  % _before_ we change the output routine.  This is necessary in the
+  % following situation:
+  %
+  % The last section of the index consists only of a single entry.
+  % Before this section, \pagetotal is less than \pagegoal, so no
+  % break occurs before the last section starts.  However, the last
+  % section, consisting of \initial and the single \entry, does not
+  % fit on the page and has to be broken off.  Without the following
+  % penalty the page builder will not be exercised until \eject
+  % below, and by that time we'll already have changed the output
+  % routine to the \balancecolumns version, so the next-to-last
+  % double-column page will be processed with \balancecolumns, which
+  % is wrong:  The two columns will go to the main vertical list, with
+  % the broken-off section in the recent contributions.  As soon as
+  % the output routine finishes, TeX starts reconsidering the page
+  % break.  The two columns and the broken-off section both fit on the
+  % page, because the two columns now take up only half of the page
+  % goal.  When TeX sees \eject from below which follows the final
+  % section, it invokes the new output routine that we've set after
+  % \balancecolumns below; \onepageout will try to fit the two columns
+  % and the final section into the vbox of \pageheight (see
+  % \pagebody), causing an overfull box.
+  %
+  % Note that glue won't work here, because glue does not exercise the
+  % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+  \penalty0
+  %
+  \output = {%
+    % Split the last of the double-column material.  Leave it on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+  }%
+  \eject
+  \endgroup % started in \begindoublecolumns
+  %
+  % \pagegoal was set to the doubled \vsize above, since we restarted
+  % the current page.  We're now back to normal single-column
+  % typesetting, so reset \pagegoal to the normal \vsize (after the
+  % \endgroup where \vsize got restored).
+  \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen at .}%
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
+  \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number".  We avoid collisions with chapter
+% numbers by starting them at 10000.  (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno        \secno=0
+\newcount\subsecno     \subsecno=0
+\newcount\subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno  \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+  \ifnum\appendixno=`A A%
+  \else\ifnum\appendixno=`B B%
+  \else\ifnum\appendixno=`C C%
+  \else\ifnum\appendixno=`D D%
+  \else\ifnum\appendixno=`E E%
+  \else\ifnum\appendixno=`F F%
+  \else\ifnum\appendixno=`G G%
+  \else\ifnum\appendixno=`H H%
+  \else\ifnum\appendixno=`I I%
+  \else\ifnum\appendixno=`J J%
+  \else\ifnum\appendixno=`K K%
+  \else\ifnum\appendixno=`L L%
+  \else\ifnum\appendixno=`M M%
+  \else\ifnum\appendixno=`N N%
+  \else\ifnum\appendixno=`O O%
+  \else\ifnum\appendixno=`P P%
+  \else\ifnum\appendixno=`Q Q%
+  \else\ifnum\appendixno=`R R%
+  \else\ifnum\appendixno=`S S%
+  \else\ifnum\appendixno=`T T%
+  \else\ifnum\appendixno=`U U%
+  \else\ifnum\appendixno=`V V%
+  \else\ifnum\appendixno=`W W%
+  \else\ifnum\appendixno=`X X%
+  \else\ifnum\appendixno=`Y Y%
+  \else\ifnum\appendixno=`Z Z%
+  % The \the is necessary, despite appearances, because \appendixletter is
+  % expanded while writing the .toc file.  \char\appendixno is not
+  % expandable, thus it is written literally, thus all appendixes come out
+  % with the same letter (or @) in the toc without it.
+  \else\char\the\appendixno
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter.  Page headings and footings can use
+% these.  @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+  % Compute the abs. sec. level:
+  \absseclevel=#2
+  \advance\absseclevel by \secbase
+  % Make sure \absseclevel doesn't fall outside the range:
+  \ifnum \absseclevel < 0
+    \absseclevel = 0
+  \else
+    \ifnum \absseclevel > 3
+      \absseclevel = 3
+    \fi
+  \fi
+  % The heading type:
+  \def\headtype{#1}%
+  \if \headtype U%
+    \ifnum \absseclevel < \unmlevel
+      \chardef\unmlevel = \absseclevel
+    \fi
+  \else
+    % Check for appendix sections:
+    \ifnum \absseclevel = 0
+      \edef\chapheadtype{\headtype}%
+    \else
+      \if \headtype A\if \chapheadtype N%
+	\errmessage{@appendix... within a non-appendix chapter}%
+      \fi\fi
+    \fi
+    % Check for numbered within unnumbered:
+    \ifnum \absseclevel > \unmlevel
+      \def\headtype{U}%
+    \else
+      \chardef\unmlevel = 3
+    \fi
+  \fi
+  % Now print the heading:
+  \if \headtype U%
+    \ifcase\absseclevel
+	\unnumberedzzz{#3}%
+    \or \unnumberedseczzz{#3}%
+    \or \unnumberedsubseczzz{#3}%
+    \or \unnumberedsubsubseczzz{#3}%
+    \fi
+  \else
+    \if \headtype A%
+      \ifcase\absseclevel
+	  \appendixzzz{#3}%
+      \or \appendixsectionzzz{#3}%
+      \or \appendixsubseczzz{#3}%
+      \or \appendixsubsubseczzz{#3}%
+      \fi
+    \else
+      \ifcase\absseclevel
+	  \chapterzzz{#3}%
+      \or \seczzz{#3}%
+      \or \numberedsubseczzz{#3}%
+      \or \numberedsubsubseczzz{#3}%
+      \fi
+    \fi
+  \fi
+  \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v.  By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+  % section resetting is \global in case the chapter is in a group, such
+  % as an @include file.
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\chapno by 1
+  %
+  % Used for \float.
+  \gdef\chaplevelprefix{\the\chapno.}%
+  \resetallfloatnos
+  %
+  \message{\putwordChapter\space \the\chapno}%
+  %
+  % Write the actual heading.
+  \chapmacro{#1}{Ynumbered}{\the\chapno}%
+  %
+  % So @section and the like are numbered underneath this chapter.
+  \global\let\section = \numberedsec
+  \global\let\subsection = \numberedsubsec
+  \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\appendixno by 1
+  \gdef\chaplevelprefix{\appendixletter.}%
+  \resetallfloatnos
+  %
+  \def\appendixnum{\putwordAppendix\space \appendixletter}%
+  \message{\appendixnum}%
+  %
+  \chapmacro{#1}{Yappendix}{\appendixletter}%
+  %
+  \global\let\section = \appendixsec
+  \global\let\subsection = \appendixsubsec
+  \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\unnumberedno by 1
+  %
+  % Since an unnumbered has no number, no prefix for figures.
+  \global\let\chaplevelprefix = \empty
+  \resetallfloatnos
+  %
+  % This used to be simply \message{#1}, but TeX fully expands the
+  % argument to \message.  Therefore, if #1 contained @-commands, TeX
+  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+  % expanded @cite (which turns out to cause errors because \cite is meant
+  % to be executed, not expanded).
+  %
+  % Anyway, we don't want the fully-expanded definition of @cite to appear
+  % as a result of the \message, we just want `@cite' itself.  We use
+  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+  % simply yielding the contents of <toks register>.  (We also do this for
+  % the toc entries.)
+  \toks0 = {#1}%
+  \message{(\the\toks0)}%
+  %
+  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+  %
+  \global\let\section = \unnumberedsec
+  \global\let\subsection = \unnumberedsubsec
+  \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+  % Well, we could do the following in a group, but that would break
+  % an assumption that \chapmacro is called at the outermost level.
+  % Thus we are safer this way:		--kasal, 24feb04
+  \let\centerparametersmaybe = \centerparameters
+  \unnmhead0{#1}%
+  \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynumbered}%
+                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+
+\def\majorheading{%
+  {\advance\chapheadingskip by 10pt \chapbreak }%
+  \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\raggedright
+                    \rm #1\hfill}}%
+  \bigskip \par\penalty 200\relax
+  \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong.  But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+  \chappager
+  \ifodd\pageno \else
+    \begingroup
+      \evenheadline={\hfil}\evenfootline={\hfil}%
+      \oddheadline={\hfil}\oddfootline={\hfil}%
+      \hbox to 0pt{}%
+      \chappager
+    \endgroup
+  \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+  % Insert the first mark before the heading break (see notes for \domark).
+  \let\prevchapterdefs=\lastchapterdefs
+  \let\prevsectiondefs=\lastsectiondefs
+  \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+                        \gdef\thissection{}}%
+  %
+  \def\temptype{#2}%
+  \ifx\temptype\Ynothingkeyword
+    \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+                          \gdef\thischapter{\thischaptername}}%
+  \else\ifx\temptype\Yomitfromtockeyword
+    \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+                          \gdef\thischapter{}}%
+  \else\ifx\temptype\Yappendixkeyword
+    \toks0={#1}%
+    \xdef\lastchapterdefs{%
+      \gdef\noexpand\thischaptername{\the\toks0}%
+      \gdef\noexpand\thischapternum{\appendixletter}%
+      \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum:
+                                 \noexpand\thischaptername}%
+    }%
+  \else
+    \toks0={#1}%
+    \xdef\lastchapterdefs{%
+      \gdef\noexpand\thischaptername{\the\toks0}%
+      \gdef\noexpand\thischapternum{\the\chapno}%
+      \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum:
+                                 \noexpand\thischaptername}%
+    }%
+  \fi\fi\fi
+  %
+  % Output the mark.  Pass it through \safewhatsit, to take care of
+  % the preceding space.
+  \safewhatsit\domark
+  %
+  % Insert the chapter heading break.
+  \pchapsepmacro
+  %
+  % Now the second mark, after the heading break.  No break points
+  % between here and the heading.
+  \let\prevchapterdefs=\lastchapterdefs
+  \let\prevsectiondefs=\lastsectiondefs
+  \domark
+  %
+  {%
+    \chapfonts \rm
+    %
+    % Have to define \lastsection before calling \donoderef, because the
+    % xref code eventually uses it.  On the other hand, it has to be called
+    % after \pchapsepmacro, or the headline will change too soon.
+    \gdef\lastsection{#1}%
+    %
+    % Only insert the separating space if we have a chapter/appendix
+    % number, and don't print the unnumbered ``number''.
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unnchap}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+      \def\toctype{omit}%
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+      \def\toctype{app}%
+    \else
+      \setbox0 = \hbox{#3\enspace}%
+      \def\toctype{numchap}%
+    \fi\fi\fi
+    %
+    % Write the toc entry for this chapter.  Must come before the
+    % \donoderef, because we include the current node name in the toc
+    % entry, and \donoderef resets it to empty.
+    \writetocentry{\toctype}{#1}{#3}%
+    %
+    % For pdftex, we have to write out the node definition (aka, make
+    % the pdfdest) after any page break, but before the actual text has
+    % been typeset.  If the destination for the pdf outline is after the
+    % text, then jumping from the outline may wind up with the text not
+    % being visible, for instance under high magnification.
+    \donoderef{#2}%
+    %
+    % Typeset the actual heading.
+    \nobreak % Avoid page breaks at the interline glue.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+  \advance\rightskip by 3\rightskip
+  \leftskip = \rightskip
+  \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\raggedright
+                       \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+  \global\let\chapmacro=\chfopen
+  \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.  These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+  {%
+    % Switch to the right set of fonts.
+    \csname #2fonts\endcsname \rm
+    %
+    \def\sectionlevel{#2}%
+    \def\temptype{#3}%
+    %
+    % Insert first mark before the heading break (see notes for \domark).
+    \let\prevsectiondefs=\lastsectiondefs
+    \ifx\temptype\Ynothingkeyword
+      \ifx\sectionlevel\seckeyword
+        \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+                              \gdef\thissection{\thissectionname}}%
+      \fi
+    \else\ifx\temptype\Yomitfromtockeyword
+      % Don't redefine \thissection.
+    \else\ifx\temptype\Yappendixkeyword
+      \ifx\sectionlevel\seckeyword
+        \toks0={#1}%
+        \xdef\lastsectiondefs{%
+          \gdef\noexpand\thissectionname{\the\toks0}%
+          \gdef\noexpand\thissectionnum{#4}%
+          \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+                                     \noexpand\thissectionname}%
+        }%
+      \fi
+    \else
+      \ifx\sectionlevel\seckeyword
+        \toks0={#1}%
+        \xdef\lastsectiondefs{%
+          \gdef\noexpand\thissectionname{\the\toks0}%
+          \gdef\noexpand\thissectionnum{#4}%
+          \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+                                     \noexpand\thissectionname}%
+        }%
+      \fi
+    \fi\fi\fi
+    %
+    % Output the mark.  Pass it through \safewhatsit, to take care of
+    % the preceding space.
+    \safewhatsit\domark
+    %
+    % Insert space above the heading.
+    \csname #2headingbreak\endcsname
+    %
+    % Now the second mark, after the heading break.  No break points
+    % between here and the heading.
+    \let\prevsectiondefs=\lastsectiondefs
+    \domark
+    %
+    % Only insert the space after the number if we have a section number.
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unn}%
+      \gdef\lastsection{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      % for @headings -- no section number, don't include in toc,
+      % and don't redefine \lastsection.
+      \setbox0 = \hbox{}%
+      \def\toctype{omit}%
+      \let\sectionlevel=\empty
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{app}%
+      \gdef\lastsection{#1}%
+    \else
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{num}%
+      \gdef\lastsection{#1}%
+    \fi\fi\fi
+    %
+    % Write the toc entry (before \donoderef).  See comments in \chapmacro.
+    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+    %
+    % Write the node reference (= pdf destination for pdftex).
+    % Again, see comments in \chapmacro.
+    \donoderef{#3}%
+    %
+    % Interline glue will be inserted when the vbox is completed.
+    % That glue will be a valid breakpoint for the page, since it'll be
+    % preceded by a whatsit (usually from the \donoderef, or from the
+    % \writetocentry if there was no node).  We don't want to allow that
+    % break, since then the whatsits could end up on page n while the
+    % section is on page n+1, thus toc/etc. are wrong.  Debian bug 276000.
+    \nobreak
+    %
+    % Output the actual section heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0  % zero if no section number
+          \unhbox0 #1}%
+  }%
+  % Add extra space after the heading -- half of whatever came above it.
+  % Don't allow stretch, though.
+  \kern .5 \csname #2headingskip\endcsname
+  %
+  % Do not let the kern be a potential breakpoint, as it would be if it
+  % was followed by glue.
+  \nobreak
+  %
+  % We'll almost certainly start a paragraph next, so don't let that
+  % glue accumulate.  (Not a breakpoint because it's preceded by a
+  % discardable item.)
+  \vskip-\parskip
+  % 
+  % This is purely so the last item on the list is a known \penalty >
+  % 10000.  This is so \startdefun can avoid allowing breakpoints after
+  % section headings.  Otherwise, it would insert a valid breakpoint between:
+  % 
+  %   @section sec-whatever
+  %   @deffn def-whatever
+  \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this.  The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything.  This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+  \edef\writetoctype{#1}%
+  \ifx\writetoctype\omitkeyword \else
+    \iftocfileopened\else
+      \immediate\openout\tocfile = \jobname.toc
+      \global\tocfileopenedtrue
+    \fi
+    %
+    \iflinks
+      {\atdummies
+       \edef\temp{%
+         \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+       \temp
+      }%
+    \fi
+  \fi
+  %
+  % Tell \shipout to create a pdf destination on each page, if we're
+  % writing pdf.  These are used in the table of contents.  We can't
+  % just write one on every page because the title pages are numbered
+  % 1 and 2 (the page numbers aren't printed), and so are the first
+  % two pages of the document.  Thus, we'd have two destinations named
+  % `1', and two named `2'.
+  \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care.  This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+% 
+\def\activecatcodes{%
+  \catcode`\"=\active
+  \catcode`\$=\active
+  \catcode`\<=\active
+  \catcode`\>=\active
+  \catcode`\\=\active
+  \catcode`\^=\active
+  \catcode`\_=\active
+  \catcode`\|=\active
+  \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+  \setupdatafile
+  \activecatcodes
+  \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+  % If @setchapternewpage on, and @headings double, the contents should
+  % start on an odd page, unlike chapters.  Thus, we maintain
+  % \contentsalignmacro in parallel with \pagealignmacro.
+  % From: Torbjorn Granlund <tege at matematik.su.se>
+  \contentsalignmacro
+  \immediate\closeout\tocfile
+  %
+  % Don't need to put `Contents' or `Short Contents' in the headline.
+  % It is abundantly clear what they are.
+  \chapmacro{#1}{Yomitfromtoc}{}%
+  %
+  \savepageno = \pageno
+  \begingroup                  % Set up to handle contents files properly.
+    \raggedbottom              % Worry more about breakpoints than the bottom.
+    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+    %
+    % Roman numerals for page numbers.
+    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref.  We always output on
+% \jobname.toc even if this is redefined.
+% 
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+  \startcontents{\putwordTOC}%
+    \openin 1 \tocreadfilename\space
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+    \ifeof 1 \else
+      \pdfmakeoutlines
+    \fi
+    \closein 1
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+  \startcontents{\putwordShortTOC}%
+    %
+    \let\numchapentry = \shortchapentry
+    \let\appentry = \shortchapentry
+    \let\unnchapentry = \shortunnchapentry
+    % We want a true roman here for the page numbers.
+    \secfonts
+    \let\rm=\shortcontrm \let\bf=\shortcontbf
+    \let\sl=\shortcontsl \let\tt=\shortconttt
+    \rm
+    \hyphenpenalty = 10000
+    \advance\baselineskip by 1pt % Open it up a little.
+    \def\numsecentry##1##2##3##4{}
+    \let\appsecentry = \numsecentry
+    \let\unnsecentry = \numsecentry
+    \let\numsubsecentry = \numsecentry
+    \let\appsubsecentry = \numsecentry
+    \let\unnsubsecentry = \numsecentry
+    \let\numsubsubsecentry = \numsecentry
+    \let\appsubsubsecentry = \numsecentry
+    \let\unnsubsubsecentry = \numsecentry
+    \openin 1 \tocreadfilename\space
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \closein 1
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+  % This space should be enough, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % But use \hss just in case.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  %
+  % We'd like to right-justify chapter numbers, but that looks strange
+  % with appendix letters.  And right-justifying numbers and
+  % left-justifying letters looks strange when there is less than 10
+  % chapters.  Have to read the whole toc once to know how many chapters
+  % there are before deciding ...
+  \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+  % We use M since it's probably the widest letter.
+  \setbox0 = \hbox{\putwordAppendix{} M}%
+  \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{%
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+  \catcode `\%=14
+  \catcode `\+=\other
+  \catcode `\"=\other
+  \catcode `\|=\other
+  \catcode `\<=\other
+  \catcode `\>=\other
+  \escapechar=`\\
+  %
+  \let\b=\ptexb
+  \let\bullet=\ptexbullet
+  \let\c=\ptexc
+  \let\,=\ptexcomma
+  \let\.=\ptexdot
+  \let\dots=\ptexdots
+  \let\equiv=\ptexequiv
+  \let\!=\ptexexclam
+  \let\i=\ptexi
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \let\{=\ptexlbrace
+  \let\+=\tabalign
+  \let\}=\ptexrbrace
+  \let\/=\ptexslash
+  \let\*=\ptexstar
+  \let\t=\ptext
+  \expandafter \let\csname top\endcsname=\ptextop  % outer
+  \let\frenchspacing=\plainfrenchspacing
+  %
+  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+  \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+  % =10000 instead of <10000 because of a special case in \itemzzz and
+  % \sectionheading, q.v.
+  \ifnum \lastpenalty=10000 \else
+    \advance\envskipamount by \parskip
+    \endgraf
+    \ifdim\lastskip<\envskipamount
+      \removelastskip
+      % it's not a good place to break if the last penalty was \nobreak
+      % or better ...
+      \ifnum\lastpenalty<10000 \penalty-50 \fi
+      \vskip\envskipamount
+    \fi
+  \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+  \ifhmode\par\fi  % can't be in the midst of a paragraph.
+  \startsavinginserts
+  \lskip=\leftskip \rskip=\rightskip
+  \leftskip=0pt\rightskip=0pt % we want these *outside*.
+  \cartinner=\hsize \advance\cartinner by-\lskip
+  \advance\cartinner by-\rskip
+  \cartouter=\hsize
+  \advance\cartouter by 18.4pt	% allow for 3pt kerns on either
+				% side, and for 6pt waste from
+				% each corner char, and rule thickness
+  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+  % Flag to tell @lisp, etc., not to narrow margin.
+  \let\nonarrowing = t%
+  \vbox\bgroup
+      \baselineskip=0pt\parskip=0pt\lineskip=0pt
+      \carttop
+      \hbox\bgroup
+	  \hskip\lskip
+	  \vrule\kern3pt
+	  \vbox\bgroup
+	      \kern3pt
+	      \hsize=\cartinner
+	      \baselineskip=\normbskip
+	      \lineskip=\normlskip
+	      \parskip=\normpskip
+	      \vskip -\parskip
+	      \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+              \ifhmode\par\fi
+	      \kern3pt
+	  \egroup
+	  \kern3pt\vrule
+	  \hskip\rskip
+      \egroup
+      \cartbot
+  \egroup
+  \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+  \aboveenvbreak
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  \parindent = 0pt
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+%    @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+  \ifx\SETdispenvsize\smallword
+    % end paragraph for sake of leading, in case document has no blank
+    % line.  This is redundant with what happens in \aboveenvbreak, but
+    % we need to do it before changing the fonts, and it's inconvenient
+    % to change the fonts afterward.
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
+    \smallexamplefonts \rm
+  \fi
+}
+\def\setsmalldispenv{%
+  \ifx\SETdispenvsize\nosmallword
+  \else
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
+    \smallexamplefonts \rm
+  \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+  \expandafter\let\csname E#1\endcsname \afterenvbreak
+  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+  \makedispenv{#1}{#3}
+  \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel at xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+  \nonfillstart
+  \tt\quoteexpand
+  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+  \gobble       % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+  \nonfillstart
+  \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \advance\leftskip by 0pt plus 1fill
+  \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.  We keep \parskip nonzero in general, since
+% we're doing normal filling.  So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \parindent=0pt
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+  \par
+  \ifx\quotationauthor\undefined\else
+    % indent a bit.
+    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+  \fi
+  {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty \else
+    {\bf #1: }%
+  \fi
+}
+
+
+% LaTeX-like @verbatim... at end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command.  --janneke at gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too.  Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+  \do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+  \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+  \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+  \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+  \tt  % easiest (and conventionally used) font for verbatim
+  \def\par{\leavevmode\endgraf}%
+  \catcode`\`=\active
+  \tabeightspaces
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+
+% Allow an option to not replace quotes with a regular directed right
+% quote/apostrophe (char 0x27), but instead use the undirected quote
+% from cmtt (char 0x0d).  The undirected quote is ugly, so don't make it
+% the default, but it works for pasting with more pdf viewers (at least
+% evince), the lilypond developers report.  xpdf does work with the
+% regular 0x27.  
+% 
+\def\codequoteright{%
+  \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+    \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+      '%
+    \else \char'15 \fi
+  \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+% 
+\def\codequoteleft{%
+  \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+    \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+      `%
+    \else \char'22 \fi
+  \else \char'22 \fi
+}
+%
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabexpand{%
+    \catcode`\^^I=\active
+    \def^^I{\leavevmode\egroup
+      \dimen0=\wd0 % the width so far, or since the previous tab
+      \divide\dimen0 by\tabw
+      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
+      \wd0=\dimen0 \box0 \starttabbox
+    }%
+  }
+  \catcode`\'=\active
+  \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
+  %
+  \catcode`\`=\active
+  \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
+  %
+  \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  % Easiest (and conventionally used) font for verbatim
+  \tt
+  \def\par{\leavevmode\egroup\box0\endgraf}%
+  \catcode`\`=\active
+  \tabexpand
+  \quoteexpand
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+  \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters.  Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+%    \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+%     \def\doverbatim#1 at end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+  \catcode`\ =\active
+  \obeylines %
+  % ignore everything up to the first ^^M, that's the newline at the end
+  % of the @verbatim input line itself.  Otherwise we get an extra blank
+  % line in the output.
+  \xdef\doverbatim#1^^M#2 at end verbatim{#2\noexpand\end\gobble verbatim}%
+  % We really want {...\end verbatim} in the body of the macro, but
+  % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+    \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+  {%
+    \makevalueexpandable
+    \setupverbatim
+    \indexnofonts       % Allow `@@' and other weird things in file names.
+    \input #1
+    \afterenvbreak
+  }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1 at end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+  \begingroup
+    \parindent = 0pt  % paragraph indentation looks wrong on title page
+    \scanexp\copyingtext
+  \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+  \ifnum\lastpenalty<10000
+    \medbreak
+    \defunpenalty=10003 % Will keep this @deffn together with the
+                        % following @def command, see below.
+  \else
+    % If there are two @def commands in a row, we'll have a \nobreak,
+    % which is there to keep the function description together with its
+    % header.  But if there's nothing but headers, we need to allow a
+    % break somewhere.  Check specifically for penalty 10002, inserted
+    % by \printdefunline, instead of 10000, since the sectioning
+    % commands also insert a nobreak penalty, and we don't want to allow
+    % a break between a section heading and a defun.
+    %
+    % As a minor refinement, we avoid "club" headers by signalling
+    % with penalty of 10003 after the very first @deffn in the
+    % sequence (see above), and penalty of 10002 after any following
+    % @def command.
+    \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+    %
+    % Similarly, after a section heading, do not allow a break.
+    % But do insert the glue.
+    \medskip  % preceded by discardable penalty, so not a breakpoint
+  \fi
+  %
+  \parindent=0in
+  \advance\leftskip by \defbodyindent
+  \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+  % First, check whether we are in the right environment:
+  \checkenv#1%
+  %
+  % As above, allow line break if we have multiple x headers in a row.
+  % It's not a great place, though.
+  \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+  %
+  % And now, it's time to reuse the body of the original defun:
+  \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+  \begingroup
+    % call \deffnheader:
+    #1#2 \endheader
+    % common ending:
+    \interlinepenalty = 10000
+    \advance\rightskip by 0pt plus 1fil
+    \endgraf
+    \nobreak\vskip -\parskip
+    \penalty\defunpenalty  % signal to \startdefun and \dodefunx
+    % Some of the @defun-type tags do not enable magic parentheses,
+    % rendering the following check redundant.  But we don't optimize.
+    \checkparencounts
+  \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remaining is to define \deffnheader.
+%
+\def\makedefun#1{%
+  \expandafter\let\csname E#1\endcsname = \Edefun
+  \edef\temp{\noexpand\domakedefun
+    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+  \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+  \envdef#1{%
+    \startdefun
+    \parseargusing\activeparens{\printdefunline#3}%
+  }%
+  \def#2{\dodefunx#1}%
+  \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+  \dosubind{fn}{\code{#3}}{#1}%
+  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{fn}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{vr}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+  \doind{tp}{\code{#2}}%
+  \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+  % Get the values of \leftskip and \rightskip as they were outside the @def...
+  \advance\leftskip by -\defbodyindent
+  %
+  % How we'll format the type name.  Putting it in brackets helps
+  % distinguish it from the body text that may end up on the next line
+  % just below it.
+  \def\temp{#1}%
+  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+  %
+  % Figure out line sizes for the paragraph shape.
+  % The first line needs space for \box0; but if \rightskip is nonzero,
+  % we need only space for the part of \box0 which exceeds it:
+  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
+  % The continuations:
+  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
+  % (plain.tex says that \dimen1 should be used only as global.)
+  \parshape 2 0in \dimen0 \defargsindent \dimen2
+  %
+  % Put the type name to the right margin.
+  \noindent
+  \hbox to 0pt{%
+    \hfil\box0 \kern-\hsize
+    % \hsize has to be shortened this way:
+    \kern\leftskip
+    % Intentionally do not respect \rightskip, since we need the space.
+  }%
+  %
+  % Allow all lines to be underfull without complaint:
+  \tolerance=10000 \hbadness=10000
+  \exdentamount=\defbodyindent
+  {%
+    % defun fonts. We use typewriter by default (used to be bold) because:
+    % . we're printing identifiers, they should be in tt in principle.
+    % . in languages with many accents, such as Czech or French, it's
+    %   common to leave accents off identifiers.  The result looks ok in
+    %   tt, but exceedingly strange in rm.
+    % . we don't want -- and --- to be treated as ligatures.
+    % . this still does not fix the ?` and !` ligatures, but so far no
+    %   one has made identifiers using them :).
+    \df \tt
+    \def\temp{#2}% return value type
+    \ifx\temp\empty\else \tclose{\temp} \fi
+    #3% output function name
+  }%
+  {\rm\enskip}% hskip 0.5 em of \tenrm
+  %
+  \boldbrax
+  % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name.  This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable.  Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+  % use sl by default (not ttsl),
+  % tt for the names.
+  \df \sl \hyphenchar\font=0
+  %
+  % On the other hand, if an argument has two dashes (for instance), we
+  % want a way to get ttsl.  Let's try @var for that.
+  \let\var=\ttslanted
+  #1%
+  \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+  \catcode`\(=\active \catcode`\)=\active
+  \catcode`\[=\active \catcode`\]=\active
+  \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+  \activeparens
+  \global\let(=\lparen \global\let)=\rparen
+  \global\let[=\lbrack \global\let]=\rbrack
+  \global\let& = \&
+
+  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+  \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+  \ifampseen
+    % At the first level, print parens in roman,
+    % otherwise use the default font.
+    \ifnum \parencount=1 \rm \fi
+  \else
+    % The \sf parens (in \boldbrax) actually are a little bolder than
+    % the contained text.  This is especially needed for [ and ] .
+    \sf
+  \fi
+}
+\def\infirstlevel#1{%
+  \ifampseen
+    \ifnum\parencount=1
+      #1%
+    \fi
+  \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+  \global\advance\parencount by 1
+  {\parenfont(}%
+  \infirstlevel \bfafterword
+}
+\def\clnr{%
+  {\parenfont)}%
+  \infirstlevel \sl
+  \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+  \global\advance\brackcount by 1
+  {\bf[}%
+}
+\def\rbrb{%
+  {\bf]}%
+  \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+  \ifnum\parencount=0 \else \badparencount \fi
+  \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+  \message{Warning: unbalanced parentheses in @def...}%
+  \global\parencount=0
+}
+\def\badbrackcount{%
+  \message{Warning: unbalanced square brackets in @def...}%
+  \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scantokens#1{%
+    \toks0={#1}%
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{\the\toks0}%
+    \immediate\closeout\macscribble
+    \input \jobname.tmp
+  }
+\fi
+
+\def\scanmacro#1{%
+  \begingroup
+    \newlinechar`\^^M
+    \let\xeatspaces\eatspaces
+    % Undo catcode changes of \startcontents and \doprintindex
+    % When called from @insertcopying or (short)caption, we need active
+    % backslash to get it printed correctly.  Previously, we had
+    % \catcode`\\=\other instead.  We'll see whether a problem appears
+    % with macro expansion.				--kasal, 19aug04
+    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+    % ... and \example
+    \spaceisspace
+    %
+    % Append \endinput to make sure that TeX does not see the ending newline.
+    % I've verified that it is necessary both for e-TeX and for ordinary TeX
+    %							--kasal, 29nov03
+    \scantokens{#1\endinput}%
+  \endgroup
+}
+
+\def\scanexp#1{%
+  \edef\temp{\noexpand\scanmacro{#1}}%
+  \temp
+}
+
+\newcount\paramno   % Count of parameters
+\newtoks\macname    % Macro name
+\newif\ifrecursive  % Is it recursive?
+
+% List of all defined macros in the form
+%    \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+     \toks0 = \expandafter{\macrolist\definedummyword#1}%
+     \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+%   \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+% 
+\def\cslet#1#2{%
+  \expandafter\let
+  \csname#1\expandafter\endcsname
+  \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion.  Must do this non-globally, to
+% confine the change to the current group.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+  \catcode`\"=\other
+  \catcode`\+=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\@=\other
+  \catcode`\^=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\~=\other
+  \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+  \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+  \scanctxt
+  \catcode`\{=\other
+  \catcode`\}=\other
+  \catcode`\^^M=\other
+  \usembodybackslash
+}
+
+\def\macroargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef at usembodybackslash{@let\=@mbodybackslash}
+ @gdef at mbodybackslash#1\{@csname macarg.#1 at endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+  \getargs{#1}%           now \macname is the macname and \argl the arglist
+  \ifx\argl\empty       % no arguments
+     \paramno=0%
+  \else
+     \expandafter\parsemargdef \argl;%
+  \fi
+  \if1\csname ismacro.\the\macname\endcsname
+     \message{Warning: redefining \the\macname}%
+  \else
+     \expandafter\ifx\csname \the\macname\endcsname \relax
+     \else \errmessage{Macro name \the\macname\space already defined}\fi
+     \global\cslet{macsave.\the\macname}{\the\macname}%
+     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+     \addtomacrolist{\the\macname}%
+  \fi
+  \begingroup \macrobodyctxt
+  \ifrecursive \expandafter\parsermacbody
+  \else \expandafter\parsemacbody
+  \fi}
+
+\parseargdef\unmacro{%
+  \if1\csname ismacro.#1\endcsname
+    \global\cslet{#1}{macsave.#1}%
+    \global\expandafter\let \csname ismacro.#1\endcsname=0%
+    % Remove the macro name from \macrolist:
+    \begingroup
+      \expandafter\let\csname#1\endcsname \relax
+      \let\definedummyword\unmacrodo
+      \xdef\macrolist{\macrolist}%
+    \endgroup
+  \else
+    \errmessage{Macro #1 not defined}%
+  \fi
+}
+
+% Called by \do from \dounmacro on each macro.  The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+  \ifx #1\relax
+    % remove this
+  \else
+    \noexpand\definedummyword \noexpand#1%
+  \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list.  Set up \paramno and \paramlist
+% so \defmacro knows what to do.  Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX:  let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+  \if#1;\let\next=\relax
+  \else \let\next=\parsemargdefxxx
+    \advance\paramno by 1%
+    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+        {\xeatspaces{\hash\the\paramno}}%
+    \edef\paramlist{\paramlist\hash\the\paramno,}%
+  \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1 at end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1 at end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+  \let\hash=##% convert placeholders to macro parameter chars
+  \ifrecursive
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\scanmacro{\temp}}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup\noexpand\scanmacro{\temp}}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+        \csname\the\macname xxx\endcsname
+          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+    \fi
+  \else
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+        \egroup
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \expandafter\noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+      \csname\the\macname xxx\endcsname
+      \paramlist{%
+          \egroup
+          \noexpand\norecurse{\the\macname}%
+          \noexpand\scanmacro{\temp}\egroup}%
+    \fi
+  \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {.  If so it reads up to the closing }, if not, it reads the whole
+% line.  Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+  \ifx\nchar\bgroup\else
+    \expandafter\parsearg
+  \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign.  Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+  {%
+    \expandafter\let\obeyedspace=\empty
+    \addtomacrolist{#1}%
+    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+  }%
+  \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs    % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.  The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross,  ,  , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node.  #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+  \ifx\lastnode\empty\else
+    \setref{\lastnode}{#1}%
+    \global\let\lastnode=\empty
+  \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+%                 or the anchor name.
+% 2) NAME-snt   - section number and type, passed as the SNT arg, or
+%                 empty for anchors.
+% 3) NAME-pg    - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat.  In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof   - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+  \pdfmkdest{#1}%
+  \iflinks
+    {%
+      \atdummies  % preserve commands, but don't expand them
+      \edef\writexrdef##1##2{%
+	\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+	  ##1}{##2}}% these are parameters of \writexrdef
+      }%
+      \toks0 = \expandafter{\lastsection}%
+      \immediate \writexrdef{title}{\the\toks0 }%
+      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+      \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
+    }%
+  \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual.  All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \unsepspaces
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printedrefname{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual\unskip}%
+  \setbox0=\hbox{\printedrefname\unskip}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printedrefname{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1 > 0pt
+        % It is in another manual, so we don't have it.
+        \def\printedrefname{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printedrefname{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printedrefname{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % Make link in pdf output.
+  \ifpdf
+    {\indexnofonts
+     \turnoffactive
+     % This expands tokens, so do it after making catcode changes, so _
+     % etc. don't get their TeX definitions.
+     \getfilename{#4}%
+     %
+     % See comments at \activebackslashdouble.
+     {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+      \backslashparens\pdfxrefdest}%
+     %
+     \leavevmode
+     \startlink attr{/Border [0 0 0]}%
+     \ifnum\filenamelength>0
+       goto file{\the\filename.pdf} name{\pdfxrefdest}%
+     \else
+       goto name{\pdfmkpgn{\pdfxrefdest}}%
+     \fi
+    }%
+    \setcolor{\linkcolor}%
+  \fi
+  %
+  % Float references are printed completely differently: "Figure 1.2"
+  % instead of "[somenode], p.3".  We distinguish them by the
+  % LABEL-title being set to a magic string.
+  {%
+    % Have to otherify everything special to allow the \csname to
+    % include an _ in the xref name, etc.
+    \indexnofonts
+    \turnoffactive
+    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+      \csname XR#1-title\endcsname
+  }%
+  \iffloat\Xthisreftitle
+    % If the user specified the print name (third arg) to the ref,
+    % print it instead of our usual "Figure 1.2".
+    \ifdim\wd0 = 0pt
+      \refx{#1-snt}{}%
+    \else
+      \printedrefname
+    \fi
+    %
+    % if the user also gave the printed manual name (fifth arg), append
+    % "in MANUALNAME".
+    \ifdim \wd1 > 0pt
+      \space \putwordin{} \cite{\printedmanual}%
+    \fi
+  \else
+    % node/anchor (non-float) references.
+    %
+    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+    % insert empty discretionaries after hyphens, which means that it will
+    % not find a line break at a hyphen in a node names.  Since some manuals
+    % are best written with fairly long node names, containing hyphens, this
+    % is a loss.  Therefore, we give the text of the node name again, so it
+    % is as if TeX is seeing it for the first time.
+    \ifdim \wd1 > 0pt
+      \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+    \else
+      % _ (for example) has to be the character _ for the purposes of the
+      % control sequence corresponding to the node, but it has to expand
+      % into the usual \leavevmode...\vrule stuff for purposes of
+      % printing. So we \turnoffactive for the \refx-snt, back on for the
+      % printing, back off for the \refx-pg.
+      {\turnoffactive
+       % Only output a following space if the -snt ref is nonempty; for
+       % @unnumbered and @anchor, it won't be.
+       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+      }%
+      % output the `[mynode]' via a macro so it can be overridden.
+      \xrefprintnodename\printedrefname
+      %
+      % But we always want a comma and a space:
+      ,\space
+      %
+      % output the `page 3'.
+      \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output.  It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents.  Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+  \ifnum\secno=0
+    \putwordChapter at tie \the\chapno
+  \else \ifnum\subsecno=0
+    \putwordSection at tie \the\chapno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection at tie \the\chapno.\the\secno.\the\subsecno
+  \else
+    \putwordSection at tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+\def\Yappendix{%
+  \ifnum\secno=0
+     \putwordAppendix at tie @char\the\appendixno{}%
+  \else \ifnum\subsecno=0
+     \putwordSection at tie @char\the\appendixno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection at tie @char\the\appendixno.\the\secno.\the\subsecno
+  \else
+    \putwordSection at tie
+      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+  {%
+    \indexnofonts
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\thisrefX
+      \csname XR#1\endcsname
+  }%
+  \ifx\thisrefX\relax
+    % If not defined, say something at least.
+    \angleleft un\-de\-fined\angleright
+    \iflinks
+      \ifhavexrefs
+        \message{\linenumber Undefined cross reference `#1'.}%
+      \else
+        \ifwarnedxrefs\else
+          \global\warnedxrefstrue
+          \message{Cross reference values unknown; you must run TeX again.}%
+        \fi
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \thisrefX
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.  Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions).  But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+  {% The node name might contain 8-bit characters, which in our current
+   % implementation are changed to commands like @'e.  Don't let these
+   % mess up the control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safexrefname{#1}%
+  }%
+  %
+  \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+  %
+  % Was that xref control sequence that we just defined for a float?
+  \expandafter\iffloat\csname XR\safexrefname\endcsname
+    % it was a float, and we have the (safe) float type in \iffloattype.
+    \expandafter\let\expandafter\floatlist
+      \csname floatlist\iffloattype\endcsname
+    %
+    % Is this the first time we've seen this float type?
+    \expandafter\ifx\floatlist\relax
+      \toks0 = {\do}% yes, so just \do
+    \else
+      % had it before, so preserve previous elements in list.
+      \toks0 = \expandafter{\floatlist\do}%
+    \fi
+    %
+    % Remember this xref in the control sequence \floatlistFLOATTYPE,
+    % for later use in \listoffloats.
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+      {\safexrefname}}%
+  \fi
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+%
+\def\tryauxfile{%
+  \openin 1 \jobname.aux
+  \ifeof 1 \else
+    \readdatafile{aux}%
+    \global\havexrefstrue
+  \fi
+  \closein 1
+}
+
+\def\setupdatafile{%
+  \catcode`\^^@=\other
+  \catcode`\^^A=\other
+  \catcode`\^^B=\other
+  \catcode`\^^C=\other
+  \catcode`\^^D=\other
+  \catcode`\^^E=\other
+  \catcode`\^^F=\other
+  \catcode`\^^G=\other
+  \catcode`\^^H=\other
+  \catcode`\^^K=\other
+  \catcode`\^^L=\other
+  \catcode`\^^N=\other
+  \catcode`\^^P=\other
+  \catcode`\^^Q=\other
+  \catcode`\^^R=\other
+  \catcode`\^^S=\other
+  \catcode`\^^T=\other
+  \catcode`\^^U=\other
+  \catcode`\^^V=\other
+  \catcode`\^^W=\other
+  \catcode`\^^X=\other
+  \catcode`\^^Z=\other
+  \catcode`\^^[=\other
+  \catcode`\^^\=\other
+  \catcode`\^^]=\other
+  \catcode`\^^^=\other
+  \catcode`\^^_=\other
+  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+  % supported in the main text, it doesn't seem desirable.  Furthermore,
+  % that is not enough: for node names that actually contain a ^
+  % character, we would end up writing a line like this: 'xrdef {'hat
+  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+  % argument, and \hat is not an expandable control sequence.  It could
+  % all be worked out, but why?  Either we support ^^ or we don't.
+  %
+  % The other change necessary for this was to define \auxhat:
+  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+  % and then to call \auxhat in \setq.
+  %
+  \catcode`\^=\other
+  %
+  % Special characters.  Should be turned off anyway, but...
+  \catcode`\~=\other
+  \catcode`\[=\other
+  \catcode`\]=\other
+  \catcode`\"=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\$=\other
+  \catcode`\#=\other
+  \catcode`\&=\other
+  \catcode`\%=\other
+  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+  %
+  % This is to support \ in node names and titles, since the \
+  % characters end up in a \csname.  It's easier than
+  % leaving it active and making its active definition an actual \
+  % character.  What I don't understand is why it works in the *value*
+  % of the xrdef.  Seems like it should be a catcode12 \, and that
+  % should not typeset properly.  But it works, so I'm moving on for
+  % now.  --karl, 15jan04.
+  \catcode`\\=\other
+  %
+  % Make the characters 128-255 be printing characters.
+  {%
+    \count1=128
+    \def\loop{%
+      \catcode\count1=\other
+      \advance\count1 by 1
+      \ifnum \count1<256 \loop \fi
+    }%
+  }%
+  %
+  % @ is our escape character in .aux files, and we need braces.
+  \catcode`\{=1
+  \catcode`\}=2
+  \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+  \setupdatafile
+  \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read.  --karl, 16nov96.
+%
+\gdef\dofootnote{%
+  \insert\footins\bgroup
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \hsize=\pagewidth
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z at skip
+  \rightskip\z at skip
+  \spaceskip\z at skip
+  \xspaceskip\z at skip
+  \parindent\defaultparindent
+  %
+  \smallfonts \rm
+  %
+  % Because we use hanging indentation in footnotes, a @noindent appears
+  % to exdent this text, so make it be a no-op.  makeinfo does not use
+  % hanging indentation so @noindent can still be needed within footnote
+  % text after an @example or the like (not that this is good style).
+  \let\noindent = \relax
+  %
+  % Hang the footnote text off the number.  Use \everypar in case the
+  % footnote extends for more than one paragraph.
+  \everypar = {\hang}%
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  \futurelet\next\fo at t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished.  Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes.  --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+  \ifx \insert\ptexinsert
+    \let\insert\saveinsert
+  \else
+    \let\checkinserts\relax
+  \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+  \afterassignment\next
+  % swallow the left brace
+  \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+    {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
+  \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+  \next
+}
+\def\newsaveinsX #1{%
+  \csname newbox\endcsname #1%
+  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+    \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image.  We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front.  If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+  % Do not bother showing banner with epsf.tex v2.7k (available in
+  % doc/epsf.tex and on ctan).
+  \def\epsfannounce{\toks0 = }%
+  \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+  work.  It is also included in the Texinfo distribution, or you can get
+  it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+  \ifx\epsfbox\undefined
+    \ifwarnednoepsf \else
+      \errhelp = \noepsfhelp
+      \errmessage{epsf.tex not found, images will be ignored}%
+      \global\warnednoepsftrue
+    \fi
+  \else
+    \imagexxx #1,,,,,\finish
+  \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+  \catcode`\^^M = 5     % in case we're inside an example
+  \normalturnoffactive  % allow _ et al. in names
+  % If the image is by itself, center it.
+  \ifvmode
+    \imagevmodetrue
+    \nobreak\medskip
+    % Usually we'll have text after the image which will insert
+    % \parskip glue, so insert it here too to equalize the space
+    % above and below.
+    \nobreak\vskip\parskip
+    \nobreak
+  \fi
+  %
+  % Leave vertical mode so that indentation from an enclosing
+  % environment such as @quotation is respected.  On the other hand, if
+  % it's at the top level, we don't want the normal paragraph indentation.
+  \noindent
+  %
+  % Output the image.
+  \ifpdf
+    \dopdfimage{#1}{#2}{#3}%
+  \else
+    % \epsfbox itself resets \epsf?size at each figure.
+    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+    \epsfbox{#1.eps}%
+  \fi
+  %
+  \ifimagevmode \medskip \fi  % space after the standalone image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc.  We don't actually implement floating yet, we always include the
+% float "here".  But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label.  Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored.  It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+  \let\thiscaption=\empty
+  \let\thisshortcaption=\empty
+  %
+  % don't lose footnotes inside @float.
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \startsavinginserts
+  %
+  % We can't be used inside a paragraph.
+  \par
+  %
+  \vtop\bgroup
+    \def\floattype{#1}%
+    \def\floatlabel{#2}%
+    \def\floatloc{#3}% we do nothing with this yet.
+    %
+    \ifx\floattype\empty
+      \let\safefloattype=\empty
+    \else
+      {%
+        % the floattype might have accents or other special characters,
+        % but we need to use it in a control sequence name.
+        \indexnofonts
+        \turnoffactive
+        \xdef\safefloattype{\floattype}%
+      }%
+    \fi
+    %
+    % If label is given but no type, we handle that as the empty type.
+    \ifx\floatlabel\empty \else
+      % We want each FLOATTYPE to be numbered separately (Figure 1,
+      % Table 1, Figure 2, ...).  (And if no label, no number.)
+      %
+      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+      \global\advance\floatno by 1
+      %
+      {%
+        % This magic value for \lastsection is output by \setref as the
+        % XREFLABEL-title value.  \xrefX uses it to distinguish float
+        % labels (which have a completely different output format) from
+        % node and anchor labels.  And \xrdef uses it to construct the
+        % lists of floats.
+        %
+        \edef\lastsection{\floatmagic=\safefloattype}%
+        \setref{\floatlabel}{Yfloat}%
+      }%
+    \fi
+    %
+    % start with \parskip glue, I guess.
+    \vskip\parskip
+    %
+    % Don't suppress indentation if a float happens to start a section.
+    \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption:    Foo 1.1
+% @float Foo & @caption{Cap}:     Foo: Cap
+% @float Foo & no caption:        Foo
+% @float ,lbl & Caption{Cap}:     1.1: Cap
+% @float ,lbl & no caption:       1.1
+% @float & @caption{Cap}:         Cap
+% @float & no caption:
+%
+\def\Efloat{%
+    \let\floatident = \empty
+    %
+    % In all cases, if we have a float type, it comes first.
+    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+    %
+    % If we have an xref label, the number comes next.
+    \ifx\floatlabel\empty \else
+      \ifx\floattype\empty \else % if also had float type, need tie first.
+        \appendtomacro\floatident{\tie}%
+      \fi
+      % the number.
+      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+    \fi
+    %
+    % Start the printed caption with what we've constructed in
+    % \floatident, but keep it separate; we need \floatident again.
+    \let\captionline = \floatident
+    %
+    \ifx\thiscaption\empty \else
+      \ifx\floatident\empty \else
+	\appendtomacro\captionline{: }% had ident, so need a colon between
+      \fi
+      %
+      % caption text.
+      \appendtomacro\captionline{\scanexp\thiscaption}%
+    \fi
+    %
+    % If we have anything to print, print it, with space before.
+    % Eventually this needs to become an \insert.
+    \ifx\captionline\empty \else
+      \vskip.5\parskip
+      \captionline
+      %
+      % Space below caption.
+      \vskip\parskip
+    \fi
+    %
+    % If have an xref label, write the list of floats info.  Do this
+    % after the caption, to avoid chance of it being a breakpoint.
+    \ifx\floatlabel\empty \else
+      % Write the text that goes in the lof to the aux file as
+      % \floatlabel-lof.  Besides \floatident, we include the short
+      % caption if specified, else the full caption if specified, else nothing.
+      {%
+        \atdummies
+        %
+        % since we read the caption text in the macro world, where ^^M
+        % is turned into a normal character, we have to scan it back, so
+        % we don't write the literal three characters "^^M" into the aux file.
+	\scanexp{%
+	  \xdef\noexpand\gtemp{%
+	    \ifx\thisshortcaption\empty
+	      \thiscaption
+	    \else
+	      \thisshortcaption
+	    \fi
+	  }%
+	}%
+        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+	  \ifx\gtemp\empty \else : \gtemp \fi}}%
+      }%
+    \fi
+  \egroup  % end of \vtop
+  %
+  % place the captured inserts
+  %
+  % BEWARE: when the floats start floating, we have to issue warning
+  % whenever an insert appears inside a float which could possibly
+  % float. --kasal, 26may04
+  %
+  \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+  \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use.  Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+  \ifx#1\relax
+      % Haven't seen this figure type before.
+      \csname newcount\endcsname #1%
+      %
+      % Remember to reset this floatno at the next chap.
+      \expandafter\gdef\expandafter\resetallfloatnos
+        \expandafter{\resetallfloatnos #1=0 }%
+  \fi
+  \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype at tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref.  That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
+% (safe) float type for this float.  We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+  \def\temp{#1}%
+  \def\iffloattype{#2}%
+  \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+  \def\floattype{#1}% floattype
+  {%
+    % the floattype might have accents or other special characters,
+    % but we need to use it in a control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safefloattype{\floattype}%
+  }%
+  %
+  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+    \ifhavexrefs
+      % if the user said @listoffloats foo but never @float foo.
+      \message{\linenumber No `\safefloattype' floats to list.}%
+    \fi
+  \else
+    \begingroup
+      \leftskip=\tocindent  % indent these entries like a toc
+      \let\do=\listoffloatsdo
+      \csname floatlist\safefloattype\endcsname
+    \endgroup
+  \fi
+}
+
+% This is called on each entry in a list of floats.  We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file.  We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+  % Can't fully expand XR#1-lof because it can contain anything.  Just
+  % pass the control sequence.  On the other hand, XR#1-pg is just the
+  % page number, and we want to fully expand that so we can get a link
+  % in pdf output.
+  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+  %
+  % use the same \entry macro we use to generate the TOC and index.
+  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+  \writeentry
+}}
+
+
+\message{localization,}
+
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding.  Single argument is the language
+% (de) or locale (de_DE) abbreviation.
+%
+{
+  \catcode`\_ = \active
+  \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+  \let_=\normalunderscore  % normal _ character for filenames
+  \tex % read txi-??.tex file in plain TeX.
+    % Read the file by the name they passed if it exists.
+    \openin 1 txi-#1.tex
+    \ifeof 1
+      \documentlanguagetrywithoutunderscore{#1_\finish}%
+    \else
+      \globaldefs = 1  % everything in the txi-LL files needs to persist
+      \input txi-#1.tex
+    \fi
+    \closein 1
+  \endgroup % end raw TeX
+\endgroup}
+}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+% 
+\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
+  \openin 1 txi-#1.tex
+  \ifeof 1
+    \errhelp = \nolanghelp
+    \errmessage{Cannot read language file txi-#1.tex}%
+  \else
+    \input txi-#1.tex
+  \fi
+  \closein 1
+}
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty.  Maybe you need to install it?  Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+% 
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+% 
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages.  This means we can support hyphenation in
+% Texinfo, at least to some extent.  (This still doesn't solve the
+% accented characters problem.)
+% 
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+  % do not set the language if the name is undefined in the current TeX.
+  \expandafter\ifx\csname lang@#1\endcsname \relax
+    \message{no patterns for #1}%
+  \else
+    \global\language = \csname lang@#1\endcsname
+  \fi
+  % but there is no harm in adjusting the hyphenmin values regardless.
+  \global\lefthyphenmin = #2\relax
+  \global\righthyphenmin = #3\relax
+}
+
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \global\catcode\count255=#1\relax
+      \advance\count255 by 1
+   \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \catcode\count255=#1\relax
+      \advance\count255 by 1
+   \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+  % Encoding being declared for the document.
+  \def\declaredencoding{\csname #1.enc\endcsname}%
+  %
+  % Supported encodings: names converted to tokens in order to be able
+  % to compare them with \ifx.
+  \def\ascii{\csname US-ASCII.enc\endcsname}%
+  \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+  \def\latone{\csname ISO-8859-1.enc\endcsname}%
+  \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+  \def\utfeight{\csname UTF-8.enc\endcsname}%
+  %
+  \ifx \declaredencoding \ascii
+     \asciichardefs
+  %
+  \else \ifx \declaredencoding \lattwo
+     \setnonasciicharscatcode\active
+     \lattwochardefs
+  %
+  \else \ifx \declaredencoding \latone 
+     \setnonasciicharscatcode\active
+     \latonechardefs
+  %
+  \else \ifx \declaredencoding \latnine
+     \setnonasciicharscatcode\active
+     \latninechardefs
+  %
+  \else \ifx \declaredencoding \utfeight
+     \setnonasciicharscatcode\active
+     \utfeightchardefs
+  %
+  \else 
+    \message{Unknown document encoding #1, ignoring.}%
+  %
+  \fi % utfeight
+  \fi % latnine
+  \fi % latone
+  \fi % lattwo
+  \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+% 
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+  \gdef^^a0{~} 
+  \gdef^^a1{\exclamdown}
+  \gdef^^a2{\missingcharmsg{CENT SIGN}} 
+  \gdef^^a3{{\pounds}}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\missingcharmsg{YEN SIGN}}
+  \gdef^^a6{\missingcharmsg{BROKEN BAR}} 
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}} 
+  \gdef^^a9{\copyright} 
+  \gdef^^aa{\ordf}
+  \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}} 
+  \gdef^^ac{$\lnot$}
+  \gdef^^ad{\-} 
+  \gdef^^ae{\registeredsymbol} 
+  \gdef^^af{\={}}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{$\pm$}
+  \gdef^^b2{$^2$}
+  \gdef^^b3{$^3$}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{$\mu$}
+  \gdef^^b6{\P}
+  %
+  \gdef^^b7{$^.$}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{$^1$}
+  \gdef^^ba{\ordm}
+  %
+  \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+  \gdef^^bc{$1\over4$}
+  \gdef^^bd{$1\over2$}
+  \gdef^^be{$3\over4$}
+  \gdef^^bf{\questiondown}
+  %
+  \gdef^^c0{\`A}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\~A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\ringaccent A} 
+  \gdef^^c6{\AE}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\`E}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\^E}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\`I}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\"I}
+  %
+  \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
+  \gdef^^d1{\~N}
+  \gdef^^d2{\`O}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\~O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\O}
+  \gdef^^d9{\`U}
+  \gdef^^da{\'U}
+  \gdef^^db{\^U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\`a}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\~a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\ringaccent a}
+  \gdef^^e6{\ae}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\`e}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\^e}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\`{\dotless i}}
+  \gdef^^ed{\'{\dotless i}}
+  \gdef^^ee{\^{\dotless i}}
+  \gdef^^ef{\"{\dotless i}}
+  %
+  \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
+  \gdef^^f1{\~n}
+  \gdef^^f2{\`o}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\~o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\o}
+  \gdef^^f9{\`u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\^u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
+  \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+  % Encoding is almost identical to Latin1.
+  \latonechardefs
+  %
+  \gdef^^a4{\euro}
+  \gdef^^a6{\v S}
+  \gdef^^a8{\v s}
+  \gdef^^b4{\v Z}
+  \gdef^^b8{\v z}
+  \gdef^^bc{\OE}
+  \gdef^^bd{\oe}
+  \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
+  \gdef^^a2{\u{}}
+  \gdef^^a3{\L}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\v L}
+  \gdef^^a6{\'S}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\v S}
+  \gdef^^aa{\cedilla S}
+  \gdef^^ab{\v T}
+  \gdef^^ac{\'Z}
+  \gdef^^ad{\-}
+  \gdef^^ae{\v Z}
+  \gdef^^af{\dotaccent Z}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
+  \gdef^^b2{\missingcharmsg{OGONEK}}
+  \gdef^^b3{\l}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{\v l}
+  \gdef^^b6{\'s}
+  \gdef^^b7{\v{}}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{\v s}
+  \gdef^^ba{\cedilla s}
+  \gdef^^bb{\v t}
+  \gdef^^bc{\'z}
+  \gdef^^bd{\H{}}
+  \gdef^^be{\v z}
+  \gdef^^bf{\dotaccent z}
+  %
+  \gdef^^c0{\'R}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\u A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\'L}
+  \gdef^^c6{\'C}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\v C}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\v E}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\v D}
+  %
+  \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
+  \gdef^^d1{\'N}
+  \gdef^^d2{\v N}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\H O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\v R}
+  \gdef^^d9{\ringaccent U} 
+  \gdef^^da{\'U}
+  \gdef^^db{\H U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\cedilla T}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\'r}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\u a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\'l}
+  \gdef^^e6{\'c}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\v c}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\v e}
+  \gdef^^ed{\'\i}
+  \gdef^^ee{\^\i}
+  \gdef^^ef{\v d}
+  %
+  \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
+  \gdef^^f1{\'n}
+  \gdef^^f2{\v n}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\H o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\v r}
+  \gdef^^f9{\ringaccent u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\H u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\cedilla t}
+  \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+% 
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions.  It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+% 
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+  \ifx #1\relax
+    \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+  \else
+    \expandafter #1%
+  \fi
+}
+
+\begingroup
+  \catcode`\~13
+  \catcode`\"12
+
+  \def\UTFviiiLoop{%
+    \global\catcode\countUTFx\active
+    \uccode`\~\countUTFx
+    \uppercase\expandafter{\UTFviiiTmp}%
+    \advance\countUTFx by 1
+    \ifnum\countUTFx < \countUTFy
+      \expandafter\UTFviiiLoop
+    \fi}
+
+  \countUTFx = "C2
+  \countUTFy = "E0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "E0
+  \countUTFy = "F0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "F0
+  \countUTFy = "F4
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+  \UTFviiiLoop
+\endgroup
+
+\begingroup
+  \catcode`\"=12
+  \catcode`\<=12
+  \catcode`\.=12
+  \catcode`\,=12
+  \catcode`\;=12
+  \catcode`\!=12
+  \catcode`\~=13
+
+  \gdef\DeclareUnicodeCharacter#1#2{%
+    \countUTFz = "#1\relax
+    \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+    \begingroup
+      \parseXMLCharref
+      \def\UTFviiiTwoOctets##1##2{%
+        \csname u8:##1\string ##2\endcsname}%
+      \def\UTFviiiThreeOctets##1##2##3{%
+        \csname u8:##1\string ##2\string ##3\endcsname}%
+      \def\UTFviiiFourOctets##1##2##3##4{%
+        \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+      \expandafter\expandafter\expandafter\expandafter
+       \expandafter\expandafter\expandafter
+       \gdef\UTFviiiTmp{#2}%
+    \endgroup}
+
+  \gdef\parseXMLCharref{%
+    \ifnum\countUTFz < "A0\relax
+      \errhelp = \EMsimple
+      \errmessage{Cannot define Unicode char value < 00A0}%
+    \else\ifnum\countUTFz < "800\relax
+      \parseUTFviiiA,%
+      \parseUTFviiiB C\UTFviiiTwoOctets.,%
+    \else\ifnum\countUTFz < "10000\relax
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+    \else
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiA!%
+      \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+    \fi\fi\fi
+  }
+
+  \gdef\parseUTFviiiA#1{%
+    \countUTFx = \countUTFz
+    \divide\countUTFz by 64
+    \countUTFy = \countUTFz
+    \multiply\countUTFz by 64
+    \advance\countUTFx by -\countUTFz
+    \advance\countUTFx by 128
+    \uccode `#1\countUTFx
+    \countUTFz = \countUTFy}
+
+  \gdef\parseUTFviiiB#1#2#3#4{%
+    \advance\countUTFz by "#10\relax
+    \uccode `#3\countUTFz
+    \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+  \DeclareUnicodeCharacter{00A0}{\tie}
+  \DeclareUnicodeCharacter{00A1}{\exclamdown}
+  \DeclareUnicodeCharacter{00A3}{\pounds}
+  \DeclareUnicodeCharacter{00A8}{\"{ }}
+  \DeclareUnicodeCharacter{00A9}{\copyright}
+  \DeclareUnicodeCharacter{00AA}{\ordf}
+  \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+  \DeclareUnicodeCharacter{00AD}{\-}
+  \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+  \DeclareUnicodeCharacter{00AF}{\={ }}
+
+  \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+  \DeclareUnicodeCharacter{00B4}{\'{ }}
+  \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+  \DeclareUnicodeCharacter{00BA}{\ordm}
+  \DeclareUnicodeCharacter{00BB}{\guillemetright}
+  \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+  \DeclareUnicodeCharacter{00C0}{\`A}
+  \DeclareUnicodeCharacter{00C1}{\'A}
+  \DeclareUnicodeCharacter{00C2}{\^A}
+  \DeclareUnicodeCharacter{00C3}{\~A}
+  \DeclareUnicodeCharacter{00C4}{\"A}
+  \DeclareUnicodeCharacter{00C5}{\AA}
+  \DeclareUnicodeCharacter{00C6}{\AE}
+  \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+  \DeclareUnicodeCharacter{00C8}{\`E}
+  \DeclareUnicodeCharacter{00C9}{\'E}
+  \DeclareUnicodeCharacter{00CA}{\^E}
+  \DeclareUnicodeCharacter{00CB}{\"E}
+  \DeclareUnicodeCharacter{00CC}{\`I}
+  \DeclareUnicodeCharacter{00CD}{\'I}
+  \DeclareUnicodeCharacter{00CE}{\^I}
+  \DeclareUnicodeCharacter{00CF}{\"I}
+
+  \DeclareUnicodeCharacter{00D1}{\~N}
+  \DeclareUnicodeCharacter{00D2}{\`O}
+  \DeclareUnicodeCharacter{00D3}{\'O}
+  \DeclareUnicodeCharacter{00D4}{\^O}
+  \DeclareUnicodeCharacter{00D5}{\~O}
+  \DeclareUnicodeCharacter{00D6}{\"O}
+  \DeclareUnicodeCharacter{00D8}{\O}
+  \DeclareUnicodeCharacter{00D9}{\`U}
+  \DeclareUnicodeCharacter{00DA}{\'U}
+  \DeclareUnicodeCharacter{00DB}{\^U}
+  \DeclareUnicodeCharacter{00DC}{\"U}
+  \DeclareUnicodeCharacter{00DD}{\'Y}
+  \DeclareUnicodeCharacter{00DF}{\ss}
+
+  \DeclareUnicodeCharacter{00E0}{\`a}
+  \DeclareUnicodeCharacter{00E1}{\'a}
+  \DeclareUnicodeCharacter{00E2}{\^a}
+  \DeclareUnicodeCharacter{00E3}{\~a}
+  \DeclareUnicodeCharacter{00E4}{\"a}
+  \DeclareUnicodeCharacter{00E5}{\aa}
+  \DeclareUnicodeCharacter{00E6}{\ae}
+  \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+  \DeclareUnicodeCharacter{00E8}{\`e}
+  \DeclareUnicodeCharacter{00E9}{\'e}
+  \DeclareUnicodeCharacter{00EA}{\^e}
+  \DeclareUnicodeCharacter{00EB}{\"e}
+  \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+  \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{00F1}{\~n}
+  \DeclareUnicodeCharacter{00F2}{\`o}
+  \DeclareUnicodeCharacter{00F3}{\'o}
+  \DeclareUnicodeCharacter{00F4}{\^o}
+  \DeclareUnicodeCharacter{00F5}{\~o}
+  \DeclareUnicodeCharacter{00F6}{\"o}
+  \DeclareUnicodeCharacter{00F8}{\o}
+  \DeclareUnicodeCharacter{00F9}{\`u}
+  \DeclareUnicodeCharacter{00FA}{\'u}
+  \DeclareUnicodeCharacter{00FB}{\^u}
+  \DeclareUnicodeCharacter{00FC}{\"u}
+  \DeclareUnicodeCharacter{00FD}{\'y}
+  \DeclareUnicodeCharacter{00FF}{\"y}
+
+  \DeclareUnicodeCharacter{0100}{\=A}
+  \DeclareUnicodeCharacter{0101}{\=a}
+  \DeclareUnicodeCharacter{0102}{\u{A}}
+  \DeclareUnicodeCharacter{0103}{\u{a}}
+  \DeclareUnicodeCharacter{0106}{\'C}
+  \DeclareUnicodeCharacter{0107}{\'c}
+  \DeclareUnicodeCharacter{0108}{\^C}
+  \DeclareUnicodeCharacter{0109}{\^c}
+  \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+  \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+  \DeclareUnicodeCharacter{010C}{\v{C}}
+  \DeclareUnicodeCharacter{010D}{\v{c}}
+  \DeclareUnicodeCharacter{010E}{\v{D}}
+
+  \DeclareUnicodeCharacter{0112}{\=E}
+  \DeclareUnicodeCharacter{0113}{\=e}
+  \DeclareUnicodeCharacter{0114}{\u{E}}
+  \DeclareUnicodeCharacter{0115}{\u{e}}
+  \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+  \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+  \DeclareUnicodeCharacter{011A}{\v{E}}
+  \DeclareUnicodeCharacter{011B}{\v{e}}
+  \DeclareUnicodeCharacter{011C}{\^G}
+  \DeclareUnicodeCharacter{011D}{\^g}
+  \DeclareUnicodeCharacter{011E}{\u{G}}
+  \DeclareUnicodeCharacter{011F}{\u{g}}
+
+  \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+  \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+  \DeclareUnicodeCharacter{0124}{\^H}
+  \DeclareUnicodeCharacter{0125}{\^h}
+  \DeclareUnicodeCharacter{0128}{\~I}
+  \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+  \DeclareUnicodeCharacter{012A}{\=I}
+  \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+  \DeclareUnicodeCharacter{012C}{\u{I}}
+  \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+  \DeclareUnicodeCharacter{0131}{\dotless{i}}
+  \DeclareUnicodeCharacter{0132}{IJ}
+  \DeclareUnicodeCharacter{0133}{ij}
+  \DeclareUnicodeCharacter{0134}{\^J}
+  \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+  \DeclareUnicodeCharacter{0139}{\'L}
+  \DeclareUnicodeCharacter{013A}{\'l}
+
+  \DeclareUnicodeCharacter{0141}{\L}
+  \DeclareUnicodeCharacter{0142}{\l}
+  \DeclareUnicodeCharacter{0143}{\'N}
+  \DeclareUnicodeCharacter{0144}{\'n}
+  \DeclareUnicodeCharacter{0147}{\v{N}}
+  \DeclareUnicodeCharacter{0148}{\v{n}}
+  \DeclareUnicodeCharacter{014C}{\=O}
+  \DeclareUnicodeCharacter{014D}{\=o}
+  \DeclareUnicodeCharacter{014E}{\u{O}}
+  \DeclareUnicodeCharacter{014F}{\u{o}}
+
+  \DeclareUnicodeCharacter{0150}{\H{O}}
+  \DeclareUnicodeCharacter{0151}{\H{o}}
+  \DeclareUnicodeCharacter{0152}{\OE}
+  \DeclareUnicodeCharacter{0153}{\oe}
+  \DeclareUnicodeCharacter{0154}{\'R}
+  \DeclareUnicodeCharacter{0155}{\'r}
+  \DeclareUnicodeCharacter{0158}{\v{R}}
+  \DeclareUnicodeCharacter{0159}{\v{r}}
+  \DeclareUnicodeCharacter{015A}{\'S}
+  \DeclareUnicodeCharacter{015B}{\'s}
+  \DeclareUnicodeCharacter{015C}{\^S}
+  \DeclareUnicodeCharacter{015D}{\^s}
+  \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+  \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+  \DeclareUnicodeCharacter{0160}{\v{S}}
+  \DeclareUnicodeCharacter{0161}{\v{s}}
+  \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+  \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+  \DeclareUnicodeCharacter{0164}{\v{T}}
+
+  \DeclareUnicodeCharacter{0168}{\~U}
+  \DeclareUnicodeCharacter{0169}{\~u}
+  \DeclareUnicodeCharacter{016A}{\=U}
+  \DeclareUnicodeCharacter{016B}{\=u}
+  \DeclareUnicodeCharacter{016C}{\u{U}}
+  \DeclareUnicodeCharacter{016D}{\u{u}}
+  \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+  \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+  \DeclareUnicodeCharacter{0170}{\H{U}}
+  \DeclareUnicodeCharacter{0171}{\H{u}}
+  \DeclareUnicodeCharacter{0174}{\^W}
+  \DeclareUnicodeCharacter{0175}{\^w}
+  \DeclareUnicodeCharacter{0176}{\^Y}
+  \DeclareUnicodeCharacter{0177}{\^y}
+  \DeclareUnicodeCharacter{0178}{\"Y}
+  \DeclareUnicodeCharacter{0179}{\'Z}
+  \DeclareUnicodeCharacter{017A}{\'z}
+  \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+  \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+  \DeclareUnicodeCharacter{017D}{\v{Z}}
+  \DeclareUnicodeCharacter{017E}{\v{z}}
+
+  \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+  \DeclareUnicodeCharacter{01C5}{D\v{z}}
+  \DeclareUnicodeCharacter{01C6}{d\v{z}}
+  \DeclareUnicodeCharacter{01C7}{LJ}
+  \DeclareUnicodeCharacter{01C8}{Lj}
+  \DeclareUnicodeCharacter{01C9}{lj}
+  \DeclareUnicodeCharacter{01CA}{NJ}
+  \DeclareUnicodeCharacter{01CB}{Nj}
+  \DeclareUnicodeCharacter{01CC}{nj}
+  \DeclareUnicodeCharacter{01CD}{\v{A}}
+  \DeclareUnicodeCharacter{01CE}{\v{a}}
+  \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+  \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+  \DeclareUnicodeCharacter{01D1}{\v{O}}
+  \DeclareUnicodeCharacter{01D2}{\v{o}}
+  \DeclareUnicodeCharacter{01D3}{\v{U}}
+  \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+  \DeclareUnicodeCharacter{01E2}{\={\AE}}
+  \DeclareUnicodeCharacter{01E3}{\={\ae}}
+  \DeclareUnicodeCharacter{01E6}{\v{G}}
+  \DeclareUnicodeCharacter{01E7}{\v{g}}
+  \DeclareUnicodeCharacter{01E8}{\v{K}}
+  \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+  \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+  \DeclareUnicodeCharacter{01F1}{DZ}
+  \DeclareUnicodeCharacter{01F2}{Dz}
+  \DeclareUnicodeCharacter{01F3}{dz}
+  \DeclareUnicodeCharacter{01F4}{\'G}
+  \DeclareUnicodeCharacter{01F5}{\'g}
+  \DeclareUnicodeCharacter{01F8}{\`N}
+  \DeclareUnicodeCharacter{01F9}{\`n}
+  \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+  \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+  \DeclareUnicodeCharacter{01FE}{\'{\O}}
+  \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+  \DeclareUnicodeCharacter{021E}{\v{H}}
+  \DeclareUnicodeCharacter{021F}{\v{h}}
+
+  \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+  \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+  \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+  \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+  \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+  \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+  \DeclareUnicodeCharacter{0232}{\=Y}
+  \DeclareUnicodeCharacter{0233}{\=y}
+  \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+  \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+  \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+  \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+  \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+  \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+  \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+  \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+  \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+  \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+  \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+  \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+  \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+  \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+  \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+  \DeclareUnicodeCharacter{1E20}{\=G}
+  \DeclareUnicodeCharacter{1E21}{\=g}
+  \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+  \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+  \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+  \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+  \DeclareUnicodeCharacter{1E26}{\"H}
+  \DeclareUnicodeCharacter{1E27}{\"h}
+
+  \DeclareUnicodeCharacter{1E30}{\'K}
+  \DeclareUnicodeCharacter{1E31}{\'k}
+  \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+  \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+  \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+  \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+  \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+  \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+  \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+  \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+  \DeclareUnicodeCharacter{1E3E}{\'M}
+  \DeclareUnicodeCharacter{1E3F}{\'m}
+
+  \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+  \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+  \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+  \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+  \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+  \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+  \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+  \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+  \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+  \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+  \DeclareUnicodeCharacter{1E54}{\'P}
+  \DeclareUnicodeCharacter{1E55}{\'p}
+  \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+  \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+  \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+  \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+  \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+  \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+  \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+  \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+  \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+  \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+  \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+  \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+  \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+  \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+  \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+  \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+  \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+  \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+  \DeclareUnicodeCharacter{1E7C}{\~V}
+  \DeclareUnicodeCharacter{1E7D}{\~v}
+  \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+  \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+  \DeclareUnicodeCharacter{1E80}{\`W}
+  \DeclareUnicodeCharacter{1E81}{\`w}
+  \DeclareUnicodeCharacter{1E82}{\'W}
+  \DeclareUnicodeCharacter{1E83}{\'w}
+  \DeclareUnicodeCharacter{1E84}{\"W}
+  \DeclareUnicodeCharacter{1E85}{\"w}
+  \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+  \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+  \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+  \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+  \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+  \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+  \DeclareUnicodeCharacter{1E8C}{\"X}
+  \DeclareUnicodeCharacter{1E8D}{\"x}
+  \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+  \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+  \DeclareUnicodeCharacter{1E90}{\^Z}
+  \DeclareUnicodeCharacter{1E91}{\^z}
+  \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+  \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+  \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+  \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+  \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+  \DeclareUnicodeCharacter{1E97}{\"t}
+  \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+  \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+  \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+  \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+  \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+  \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+  \DeclareUnicodeCharacter{1EBC}{\~E}
+  \DeclareUnicodeCharacter{1EBD}{\~e}
+
+  \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+  \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+  \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+  \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+  \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+  \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+  \DeclareUnicodeCharacter{1EF2}{\`Y}
+  \DeclareUnicodeCharacter{1EF3}{\`y}
+  \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+  \DeclareUnicodeCharacter{1EF8}{\~Y}
+  \DeclareUnicodeCharacter{1EF9}{\~y}
+
+  \DeclareUnicodeCharacter{2013}{--}
+  \DeclareUnicodeCharacter{2014}{---}
+  \DeclareUnicodeCharacter{2018}{\quoteleft}
+  \DeclareUnicodeCharacter{2019}{\quoteright}
+  \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+  \DeclareUnicodeCharacter{201C}{\quotedblleft}
+  \DeclareUnicodeCharacter{201D}{\quotedblright}
+  \DeclareUnicodeCharacter{201E}{\quotedblbase}
+  \DeclareUnicodeCharacter{2022}{\bullet}
+  \DeclareUnicodeCharacter{2026}{\dots}
+  \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+  \DeclareUnicodeCharacter{203A}{\guilsinglright}
+  \DeclareUnicodeCharacter{20AC}{\euro}
+
+  \DeclareUnicodeCharacter{2192}{\expansion}
+  \DeclareUnicodeCharacter{21D2}{\result}
+
+  \DeclareUnicodeCharacter{2212}{\minus}
+  \DeclareUnicodeCharacter{2217}{\point}
+  \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+   \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+  \ifx\emergencystretch\thisisundefined
+    % Allow us to assign to \emergencystretch anyway.
+    \def\emergencystretch{\dimen0}%
+  \else
+    \emergencystretch = .15\hsize
+  \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading.  The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+  \voffset = #3\relax
+  \topskip = #6\relax
+  \splittopskip = \topskip
+  %
+  \vsize = #1\relax
+  \advance\vsize by \topskip
+  \outervsize = \vsize
+  \advance\outervsize by 2\topandbottommargin
+  \pageheight = \vsize
+  %
+  \hsize = #2\relax
+  \outerhsize = \hsize
+  \advance\outerhsize by 0.5in
+  \pagewidth = \hsize
+  %
+  \normaloffset = #4\relax
+  \bindingoffset = #5\relax
+  %
+  \ifpdf
+    \pdfpageheight #7\relax
+    \pdfpagewidth #8\relax
+    % if we don't reset these, they will remain at "1 true in" of
+    % whatever layout pdftex was dumped with.
+    \pdfhorigin = 1 true in
+    \pdfvorigin = 1 true in
+  \fi
+  %
+  \setleading{\textleading}
+  %
+  \parindent = \defaultparindent
+  \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % If page is nothing but text, make it come out even.
+  \internalpagesizes{607.2pt}{6in}% that's 46 lines
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{36pt}%
+                    {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+  \parskip = 2pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.5in}{5in}%
+                    {-.2in}{0in}%
+                    {\bindingoffset}{16pt}%
+                    {9.25in}{7in}%
+  %
+  \lispnarrowing = 0.3in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+  \parskip = 1.5pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.4in}{4.8in}%
+                    {-.2in}{-.4in}%
+                    {0pt}{14pt}%
+                    {9in}{6in}%
+  %
+  \lispnarrowing = 0.25in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % Double-side printing via postscript on Laserjet 4050
+  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+  % To change the settings for a different printer or situation, adjust
+  % \normaloffset until the front-side and back-side texts align.  Then
+  % do the same for \bindingoffset.  You can set these for testing in
+  % your texinfo source file like this:
+  % @tex
+  % \global\normaloffset = -6mm
+  % \global\bindingoffset = 10mm
+  % @end tex
+  \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{44pt}%
+                    {297mm}{210mm}%
+  %
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo at urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+  \parskip = 2pt plus 1pt minus 0.1pt
+  \textleading = 12.5pt
+  %
+  \internalpagesizes{160mm}{120mm}%
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{8pt}%
+                    {210mm}{148mm}%
+  %
+  \lispnarrowing = 0.2in
+  \tolerance = 800
+  \hfuzz = 1.2pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 2mm
+  \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{237mm}{150mm}%
+                    {\voffset}{4.6mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  %
+  % Must explicitly reset to 0 because we call \afourpaper.
+  \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{241mm}{165mm}%
+                    {\voffset}{-2.95mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+  \globaldefs = 1
+  %
+  \parskip = 3pt plus 2pt minus 1pt
+  \setleading{\textleading}%
+  %
+  \dimen0 = #1\relax
+  \advance\dimen0 by \voffset
+  %
+  \dimen2 = \hsize
+  \advance\dimen2 by \normaloffset
+  %
+  \internalpagesizes{#1}{\hsize}%
+                    {\voffset}{\normaloffset}%
+                    {\bindingoffset}{44pt}%
+                    {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font.  Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts.  But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+  \normalturnoffactive
+  \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef at realbackslash{\} @gdef at doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active
+ at def@normalbackslash{{@tt at backslashcurfont}}
+% On startup, @fixbackslash assigns:
+%  @let \ = @normalbackslash
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+ at gdef@rawbackslash{@let\=@backslashcurfont}
+ at gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+% 
+ at def@normalturnoffactive{%
+  @let\=@normalbackslash
+  @let"=@normaldoublequote
+  @let~=@normaltilde
+  @let^=@normalcaret
+  @let_=@normalunderscore
+  @let|=@normalverticalbar
+  @let<=@normalless
+  @let>=@normalgreater
+  @let+=@normalplus
+  @let$=@normaldollar %$ font-lock fix
+  @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+ at otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+ at gdef@eatinput input texinfo{@fixbackslash}
+ at global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+ at gdef@fixbackslash{%
+  @ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active
+  @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+ at escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+ at catcode`@& = @other
+ at catcode`@# = @other
+ at catcode`@% = @other
+
+
+ at c Local variables:
+ at c eval: (add-hook 'write-file-hooks 'time-stamp)
+ at c page-delimiter: "^\\\\message"
+ at c time-stamp-start: "def\\\\texinfoversion{"
+ at c time-stamp-format: "%:y-%02m-%02d.%02H"
+ at c time-stamp-end: "}"
+ at c End:
+
+ at c vim:sw=2:
+
+ at ignore
+   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+ at end ignore
diff --git a/emacs/Makefile.in b/emacs/Makefile.in
new file mode 100644
index 0000000..8420e2a
--- /dev/null
+++ b/emacs/Makefile.in
@@ -0,0 +1,70 @@
+# Makefile for octave's emacs directory
+#
+# Copyright (C) 1997, 1998, 1999, 2003, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_DATA = @INSTALL_DATA@
+
+EL_FILES = octave-hlp.el octave-inf.el octave-mod.el
+
+SOURCES = $(EL_FILES) octave-tags
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(EL_FILES) octave-tags octave-tags.1 NEWS FIXME README)
+
+all:
+.PHONY: all
+
+install install-strip:
+	$(INSTALL_SCRIPT) octave-tags $(DESTDIR)$(bindir)/octave-tags
+.PHONY: install install-strip
+
+uninstall:
+	rm -f $(DESTDIR)$(bindir)/octave-tags
+.PHONY: uninstall
+
+tags:
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+clean mostlyclean:
+.PHONY: clean mostlyclean
+
+distclean:
+	rm -f Makefile
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../`cat ../.fname`/emacs
+.PHONY: dist
diff --git a/emacs/NEWS b/emacs/NEWS
new file mode 100644
index 0000000..bef404b
--- /dev/null
+++ b/emacs/NEWS
@@ -0,0 +1,225 @@
+Changes in version 0.8
+**********************
+
+* Comment types.
+
+Octave mode can now distinguish between various types of comments,
+similar to Emacs Lisp:
+
+`#'	To be aligned to the same column on the right of the source
+	code.
+
+`##'	To be aligned to the same level of indentation as the code.
+
+`###'	To start at the left margin.
+
+(Without this distinction, things like
+
+	code			# This is an inline comment which extends 
+				# across on line
+
+were not uniquely identifiable, because the second line of the in-line
+comment could not be distinguished from a full-line comment.)
+
+* Inferior Octave support.
+
+It is now possible to run Octave from within Emacs, either by directly
+entering commands at the prompt in a buffer in Inferior Octave mode, or
+by interacting with Octave from within a file with Octave code.  This is
+useful in particular for debugging Octave code.
+
+For more details, see the Texinfo documentation.
+
+* New function `octave-insert-defun' to reduce typing effort.
+
+
+Changes in version 0.7
+**********************
+
+This version is a rather complete rewrite of 0.6.
+
+In general, it was attempted to use standard Emacs features and
+functions as much as possible.
+
+* Font Lock support was improved and enhanced.
+
+Function declarations are now fontified correctly.  Builtin keywords
+(reserved words and text functions) and variables are now fontified as
+well.
+
+* Partial Imenu support was added.
+
+Function declarations can now be indexed.
+
+* A completion mechanism for builtin keywords and variables was added.
+
+Completion can be performed by pressing M-TAB (octave-complete-symbol)
+after typing the initial characters of the keyword.
+
+In a future release, completion (as well as imenu and font locking) may
+also include user defined variables.
+
+* Bug reporting.
+
+The function octave-submit-bug-report was added.
+
+* Commands for dealing with blocks.
+
+The functions for dealing with begin-else-end blocks were rewritten from
+scratch.  They are now based on the function octave-scan-blocks, which
+works similar to the standard Emacs scan-lists function.  One can now go
+forward and backward across balanced blocks, and go up and down block
+levels.  It is no longer required that extended `end' keywords are used;
+in fact, an error message will be issued in the case of nonmatching
+block keywords.  Matching is achieved through one general function, and
+now also works for else keywords.
+
+The block motion commands are
+
+	octave-forward-block
+	octave-backward-block
+	octave-down-block
+	octave-up-block
+	octave-backward-up-block
+
+One can also mark the `current' block (the innermost block containing
+point) using octave-mark-block.
+
+* Commands for dealing with functions.
+
+Moving across functions, as well as marking and indenting them now works
+as for defuns in Lisp mode.
+
+* Filling.
+
+The code for auto-filling was rewritten, and octave-fill-paragraph was
+added.  The code for filling is far from perfection yet.  In future
+releases, a function for filling the region will be added.
+
+The problem of getting the right fill function after toggling Auto-Fill
+mode was solved by an advice to auto-fill-mode.
+
+* Abbrevs.
+
+The mechanism of listing all abbrevs using `? or ` was retained.  All
+other abbrev code was dropped---why should Octave mode only use its own
+abbrevs?
+
+* Comments.
+
+As the comment syntax and comment-start are specified correctly, one can
+use the standard comment-region.  The function octave-uncomment-region
+is still provided, but now based on comment-region.
+
+The special treatment of commenting regions was removed, but may easily
+be added again.
+
+* Paragraphs.
+
+Empty lines and form feeds are now recognized as separating paragraphs
+of Octave code, so one can now move across them and fill them.
+
+* Indentation.
+
+Indentation should work without problems now, assuming `sane' coding.
+The problems in 0.6 which came from assuming that only one else or end
+keyword would occur in one line should now have disappeared.
+
+The user-level variables for customizing indentation were renamed as
+follows:
+
+	0.7				0.6
+
+	octave-block-offset		octave-stmt-indent
+	octave-continuation-offset	octave-continuation-indent
+
+Of course, it is still easy to write code in a way that makes Octave
+mode get the indentations wrong.  For example,
+
+	if (something) \
+
+will result in having octave-continuation-offset added although this is
+wrong.  Or,
+
+	printf ("This is some stupid %s \
+	for getting indentation wrong.",
+		"text")
+
+is what you deserve anyway :-)  Octave mode currently assumes that
+strings do not extend across lines ...
+
+* Other commands for moving.
+
+The functions octave-previous-statement and octave-next-statement were
+removed, partially because their names do not coincide with the usage of
+`statement' in the Octave manual.  The functions now provided are
+
+	octave-previous-code-line
+	octave-next-code-line
+	octave-beginning-of-line
+	octave-end-of-line
+
+The first two look for the previous or next `code' line, i.e., they skip
+across all empty or comment lines.  The latter two also go understand
+continuation lines, and move to their beginning and end, respectively.
+
+The effect of the former octave-previous-statement can now be achieved
+upon following octave-previous-code-line by octave-beginning-of-line.
+
+* Special insertions:  LFD, SPC and semicolon.
+
+These characters are now `electric', doing a little extra work.  All
+three expand abbrevs if abbrev mode is on and blink matching blocks if
+octave-blink-matching-blocks is t.
+
+In future versions, SPC might also do auto-newlining after certain
+keywords (or e.g., a continuation character).
+
+* User-level customization.
+
+The variables for customizing Octave mode are as follows.
+
+** As in 0.6.
+
+	octave-auto-newline
+	octave-comment-column
+	octave-comment-start
+	octave-continuation-string
+
+** Different from 0.6.
+
+	0.7				0.6
+
+	octave-blink-matching-block	octave-blink-matching-blocks
+	octave-block-offset		octave-statement-indent
+	octave-continuation-offset	octave-continuation-indent
+	octave-inhibit-startup-message	octave-startup-message
+
+The first three have only been renamed.  (The first in analogy to the
+standard blink-matching-paren, the others because they are really extra
+offsets and not the absolute indentations.)
+
+Controlling startup messages now works as in Emacs itself.
+
+** New in 0.7.
+
+	octave-fill-column
+
+** Removed from 0.7.
+
+	octave-comment-indent-style
+	octave-comment-indent-char
+	octave-comment-region
+
+* Help
+
+A mechanism for looking up entries in the indices of ALL info files with
+documentation for Octave (as specified by octave-help-files) was added
+(octave-help).  If multiple matches are found, one can cycle through the
+matches.
+
+* Other changes.
+
+octave-comment-hook was removed.  One can instead use the standard Emacs
+indent-for-comment.
+
diff --git a/emacs/README b/emacs/README
new file mode 100644
index 0000000..522721d
--- /dev/null
+++ b/emacs/README
@@ -0,0 +1,20 @@
+These lisp files should work under recent versions (19 onwards) of
+both Emacs and XEmacs.  See the Octave documentation (info node
+`Emacs') on how to install and use these packages.
+
+These files use the custom package so that user variables can be
+changed easily.  The custom package has been included in Emacs since
+around version 19.34.  If you have an old version of Emacs without the
+custom package, you should get the following error when trying to load
+the octave files:
+
+  Cannot open load file: custom
+
+In this case, you should use the simple replacement custom library
+here, renaming it to custom.el so that Emacs can find it:
+
+% mv custom-old.el custom.el
+
+But remember when you upgrade Emacs to version 20 and beyond, you
+should delete this primitive custom file and use the built-in version
+instead.
diff --git a/emacs/octave-hlp.el b/emacs/octave-hlp.el
new file mode 100644
index 0000000..8c7ee19
--- /dev/null
+++ b/emacs/octave-hlp.el
@@ -0,0 +1,138 @@
+;;; octave-hlp.el --- getting help on Octave symbols using info
+
+;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; Free Software Foundation, Inc.
+
+;; Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+;; Author: John Eaton <jwe at octave.org>
+;; Maintainer: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+;; Keywords: languages
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, see
+;; <http://www.gnu.org/licenses>.
+
+;;; Commentary:
+
+;; Provides the command `octave-help' which allows index lookup of a
+;; symbol in the Octave-related info files, as specified by the list
+;; `octave-help-files'.
+
+;; Other features may be added in future versions.
+
+;;; Code:
+
+(require 'octave-mod)
+(require 'info)
+
+(defvar octave-help-files '("octave")
+  "List of info files with documentation for Octave.
+Default is (\"octave\").")
+
+(defvar octave-help-lookup-alist nil
+  "Alist of Octave index entries for lookup.")
+
+(defvar octave-help-completion-alist nil
+  "Alist of Octave index entries for completion.
+The entries are of the form (VAR . VAR), where VAR runs through all
+different keys in `octave-help-lookup-alist'.")
+
+;;;###autoload
+(defun octave-help (key)
+  "Get help on Octave symbols from the Octave info files.
+Look up KEY in the function, operator and variable indices of the files
+specified by `octave-help-files'.
+If KEY is not a string, prompt for it with completion."
+  (interactive
+   (list
+    (completing-read (format "Describe Octave symbol: ")
+		     (octave-help-get-completion-alist)
+		     nil t)))
+  (if (get-buffer "*info*")
+      (set-buffer "*info*"))
+  (if (zerop (length key))
+      (Info-find-node (car octave-help-files) "Top")
+    (let ((alist (copy-alist (octave-help-get-lookup-alist)))
+	  entry matches)
+      (while (setq entry (car alist))
+	(if (string-match key (car entry))
+	    (add-to-list 'matches entry))
+	(setq alist (cdr alist)))
+      (if matches
+	  (progn
+	    (setq Info-index-alternatives matches)
+	    (Info-index-next 0))))))
+
+(defun octave-help-get-lookup-alist ()
+  "Build the index lookup alist from all Octave info files.
+The files specified by `octave-help-files' are searched."
+  (if octave-help-lookup-alist
+      ()
+    (message "Building help lookup alist...")
+    (let ((files octave-help-files) file key node)
+      (save-window-excursion
+	(while files
+	  (setq file (car files))
+ 	  (Info-goto-node (concat "(" file ")"))
+	  (condition-case nil
+	      (progn
+		(Info-index "")
+		(while
+		    (progn
+		      (while (re-search-forward
+			      "^\\* \\([^(:]+\\)[^:]*: *\\(.+\\)\\.$"
+			      nil t)
+			(setq key (match-string 1)
+			      node (concat "(" file ")" (match-string 2)))
+			(and (string-match "\\(.*\\>\\) *$" key)
+			     (setq key (replace-match "\\1" t nil key)))
+			(add-to-list 'octave-help-lookup-alist
+				     (list key
+					   node
+					   (concat (concat "(" file ")")
+						   Info-current-node)
+					   0)))
+		      (and (setq node (Info-extract-pointer "next" t))
+			   (string-match
+			    (concat "\\(Function\\|Operator\\|Variable\\) "
+				    "\\<Index\\>")
+			    node)))
+		  (Info-goto-node node)))
+	    (error nil))
+	  (setq files (cdr files)))))
+    (message "Building help lookup alist...done"))
+  octave-help-lookup-alist)
+
+(defun octave-help-get-completion-alist ()
+  "Build the index completion alist from all Octave info files.
+The files specified by `octave-help-files' are searched."
+  (if octave-help-completion-alist
+      ()
+    (message "Building help completion alist...")
+    (let ((alist (octave-help-get-lookup-alist)) entry)
+      (while alist
+	(setq entry (car alist))
+	(add-to-list 'octave-help-completion-alist
+		     (cons (car entry) (car entry)))
+	(setq alist (cdr alist))))
+    (message "Building help completion alist...done"))
+  octave-help-completion-alist)
+
+;;; provide ourself
+
+(provide 'octave-hlp)
+
+;;; arch-tag: df5ef8fa-76c9-44e5-9835-cb5a502c6282
+;;; octave-hlp.el ends here
diff --git a/emacs/octave-inf.el b/emacs/octave-inf.el
new file mode 100644
index 0000000..ab26cfe
--- /dev/null
+++ b/emacs/octave-inf.el
@@ -0,0 +1,408 @@
+;;; octave-inf.el --- running Octave as an inferior Emacs process
+
+;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; Free Software Foundation, Inc.
+
+;; Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+;; Author: John Eaton <jwe at octave.org>
+;; Maintainer: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+;; Keywords: languages
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, see
+;; <http://www.gnu.org/licenses>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'octave-mod)
+(require 'comint)
+
+(defgroup octave-inferior nil
+  "Running Octave as an inferior Emacs process."
+  :group 'octave)
+
+(defcustom inferior-octave-program "octave"
+  "Program invoked by `inferior-octave'."
+  :type 'string
+  :group 'octave-inferior)
+
+(defcustom inferior-octave-prompt
+  "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ "
+  "Regexp to match prompts for the inferior Octave process."
+  :type 'regexp
+  :group 'octave-inferior)
+
+(defcustom inferior-octave-startup-file nil
+  "Name of the inferior Octave startup file.
+The contents of this file are sent to the inferior Octave process on
+startup."
+  :type '(choice (const :tag "None" nil)
+		 file)
+  :group 'octave-inferior)
+
+(defcustom inferior-octave-startup-args nil
+  "List of command line arguments for the inferior Octave process.
+For example, for suppressing the startup message and using `traditional'
+mode, set this to (\"-q\" \"--traditional\")."
+  :type '(repeat string)
+  :group 'octave-inferior)
+
+(defvar inferior-octave-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map comint-mode-map)
+    (define-key map "\t" 'comint-dynamic-complete)
+    (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
+    (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring)
+    (define-key map [menu-bar inout list-history]
+      '("List Input History" . inferior-octave-dynamic-list-input-ring))
+    (define-key map "\C-c\C-h" 'octave-help)
+    map)
+  "Keymap used in Inferior Octave mode.")
+
+(defvar inferior-octave-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?\` "w" table)
+    (modify-syntax-entry ?\# "<" table)
+    (modify-syntax-entry ?\n ">" table)
+    table)
+  "Syntax table in use in inferior-octave-mode buffers.")
+
+(defcustom inferior-octave-mode-hook nil
+  "*Hook to be run when Inferior Octave mode is started."
+  :type 'hook
+  :group 'octave-inferior)
+
+(defvar inferior-octave-font-lock-keywords
+  (list
+   (cons inferior-octave-prompt 'font-lock-type-face))
+  ;; Could certainly do more font locking in inferior Octave ...
+  "Additional expressions to highlight in Inferior Octave mode.")
+
+
+;;; Compatibility functions
+(if (not (fboundp 'comint-line-beginning-position))
+    ;; comint-line-beginning-position is defined in Emacs 21
+    (defun comint-line-beginning-position ()
+      "Returns the buffer position of the beginning of the line, after any prompt.
+The prompt is assumed to be any text at the beginning of the line matching
+the regular expression `comint-prompt-regexp', a buffer local variable."
+      (save-excursion (comint-bol nil) (point))))
+
+
+(defvar inferior-octave-output-list nil)
+(defvar inferior-octave-output-string nil)
+(defvar inferior-octave-receive-in-progress nil)
+
+(defvar inferior-octave-startup-hook nil)
+
+(defvar inferior-octave-complete-impossible nil
+  "Non-nil means that `inferior-octave-complete' is impossible.")
+
+(defvar inferior-octave-has-built-in-variables nil
+  "Non-nil means that Octave has built-in variables.")
+
+(defvar inferior-octave-dynamic-complete-functions
+  '(inferior-octave-complete comint-dynamic-complete-filename)
+  "List of functions called to perform completion for inferior Octave.
+This variable is used to initialize `comint-dynamic-complete-functions'
+in the Inferior Octave buffer.")
+
+(defun inferior-octave-mode ()
+  "Major mode for interacting with an inferior Octave process.
+Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs
+buffer.
+
+Entry to this mode successively runs the hooks `comint-mode-hook' and
+`inferior-octave-mode-hook'."
+  (interactive)
+  (delay-mode-hooks (comint-mode))
+  (setq comint-prompt-regexp inferior-octave-prompt
+	major-mode 'inferior-octave-mode
+	mode-name "Inferior Octave"
+	mode-line-process '(":%s")
+	local-abbrev-table octave-abbrev-table)
+  (use-local-map inferior-octave-mode-map)
+  (set-syntax-table inferior-octave-mode-syntax-table)
+
+  (make-local-variable 'comment-start)
+  (setq comment-start octave-comment-start)
+  (make-local-variable 'comment-end)
+  (setq comment-end "")
+  (make-local-variable 'comment-column)
+  (setq comment-column 32)
+  (make-local-variable 'comment-start-skip)
+  (setq comment-start-skip octave-comment-start-skip)
+
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil))
+
+  (setq comint-input-ring-file-name
+	(or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
+	comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024))
+  (set (make-local-variable 'comint-dynamic-complete-functions)
+       inferior-octave-dynamic-complete-functions)
+  (add-hook 'comint-input-filter-functions
+	'inferior-octave-directory-tracker nil t)
+  (comint-read-input-ring t)
+
+  (run-mode-hooks 'inferior-octave-mode-hook))
+
+;;;###autoload
+(defun inferior-octave (&optional arg)
+  "Run an inferior Octave process, I/O via `inferior-octave-buffer'.
+This buffer is put in Inferior Octave mode.  See `inferior-octave-mode'.
+
+Unless ARG is non-nil, switches to this buffer.
+
+The elements of the list `inferior-octave-startup-args' are sent as
+command line arguments to the inferior Octave process on startup.
+
+Additional commands to be executed on startup can be provided either in
+the file specified by `inferior-octave-startup-file' or by the default
+startup file, `~/.emacs-octave'."
+  (interactive "P")
+  (let ((buffer inferior-octave-buffer))
+    (get-buffer-create buffer)
+    (if (comint-check-proc buffer)
+	()
+      (save-excursion
+	(set-buffer buffer)
+	(comint-mode)
+	(inferior-octave-startup)
+	(inferior-octave-mode)))
+    (if (not arg)
+	(pop-to-buffer buffer))))
+
+;;;###autoload
+(defalias 'run-octave 'inferior-octave)
+
+(defun inferior-octave-startup ()
+  "Start an inferior Octave process."
+  (let ((proc (comint-exec-1
+	       (substring inferior-octave-buffer 1 -1)
+	       inferior-octave-buffer
+	       inferior-octave-program
+	       (append (list "-i" "--no-line-editing")
+		       inferior-octave-startup-args))))
+    (set-process-filter proc 'inferior-octave-output-digest)
+    (setq comint-ptyp process-connection-type
+	  inferior-octave-process proc
+	  inferior-octave-output-list nil
+	  inferior-octave-output-string nil
+	  inferior-octave-receive-in-progress t)
+
+    ;; This may look complicated ... However, we need to make sure that
+    ;; we additional startup code only AFTER Octave is ready (otherwise,
+    ;; output may be mixed up).  Hence, we need to digest the Octave
+    ;; output to see when it issues a prompt.
+    (while inferior-octave-receive-in-progress
+      (accept-process-output inferior-octave-process))
+    (goto-char (point-max))
+    (set-marker (process-mark proc) (point))
+    (insert-before-markers
+     (concat
+      (if (not (bobp)) "\n")
+      (if inferior-octave-output-list
+	  (concat (mapconcat
+		   'identity inferior-octave-output-list "\n")
+		  "\n"))))
+
+     ;; Find out whether Octave has built-in variables.
+     (inferior-octave-send-list-and-digest
+      (list "exist \"LOADPATH\"\n"))
+     (setq inferior-octave-has-built-in-variables
+ 	  (string-match "101$" (car inferior-octave-output-list)))
+
+    ;; An empty secondary prompt, as e.g. obtained by '--braindead',
+    ;; means trouble.
+    (inferior-octave-send-list-and-digest (list "PS2\n"))
+    (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list))
+ 	(inferior-octave-send-list-and-digest
+ 	 (list (if inferior-octave-has-built-in-variables
+ 		   "PS2 = \"> \"\n"
+ 		 "PS2 (\"> \");\n"))))
+
+    ;; O.k., now we are ready for the Inferior Octave startup commands.
+    (let* (commands
+	   (program (file-name-nondirectory inferior-octave-program))
+	   (file (or inferior-octave-startup-file
+			  (concat "~/.emacs-" program))))
+      (setq commands
+	    (list "more off;\n"
+		  (if (not (string-equal
+			    inferior-octave-output-string ">> "))
+		      (if inferior-octave-has-built-in-variables
+			  "PS1=\"\\\\s> \";\n"
+			"PS1 (\"\\\\s> \");\n"))
+		  (if (file-exists-p file)
+		      (format "source (\"%s\");\n" file))))
+      (inferior-octave-send-list-and-digest commands))
+    (insert-before-markers
+     (concat
+      (if inferior-octave-output-list
+	  (concat (mapconcat
+		   'identity inferior-octave-output-list "\n")
+		  "\n"))
+      inferior-octave-output-string))
+    ;; Next, we check whether Octave supports `completion_matches' ...
+    (inferior-octave-send-list-and-digest
+     (list "exist \"completion_matches\"\n"))
+    (setq inferior-octave-complete-impossible
+	  (not (string-match "5$" (car inferior-octave-output-list))))
+
+    ;; And finally, everything is back to normal.
+    (set-process-filter proc 'inferior-octave-output-filter)
+    (run-hooks 'inferior-octave-startup-hook)
+    (run-hooks 'inferior-octave-startup-hook)
+    ;; Just in case, to be sure a cd in the startup file
+    ;; won't have detrimental effects.
+    (inferior-octave-resync-dirs)))
+
+
+(defun inferior-octave-complete ()
+  "Perform completion on the Octave symbol preceding point.
+This is implemented using the Octave command `completion_matches' which
+is NOT available with versions of Octave prior to 2.0."
+  (interactive)
+  (let* ((end (point))
+	 (command
+	  (save-excursion
+	    (skip-syntax-backward "w_" (comint-line-beginning-position))
+	    (buffer-substring-no-properties (point) end)))
+	 (proc (get-buffer-process inferior-octave-buffer)))
+    (cond (inferior-octave-complete-impossible
+	   (error (concat
+		   "Your Octave does not have `completion_matches'.  "
+		   "Please upgrade to version 2.X.")))
+	  ((string-equal command "")
+	   (message "Cannot complete an empty string"))
+	  (t
+	   (inferior-octave-send-list-and-digest
+	    (list (concat "completion_matches (\"" command "\");\n")))
+	   ;; Sort the list
+	   (setq inferior-octave-output-list
+		 (sort inferior-octave-output-list 'string-lessp))
+	   ;; Remove duplicates
+	   (let* ((x inferior-octave-output-list)
+		  (y (cdr x)))
+	     (while y
+	       (if (string-equal (car x) (car y))
+		   (setcdr x (setq y (cdr y)))
+		 (setq x y
+		       y (cdr y)))))
+	   ;; And let comint handle the rest
+	   (comint-dynamic-simple-complete
+	    command inferior-octave-output-list)))))
+
+(defun inferior-octave-dynamic-list-input-ring ()
+  "List the buffer's input history in a help buffer."
+  ;; We cannot use `comint-dynamic-list-input-ring', because it replaces
+  ;; "completion" by "history reference" ...
+  (interactive)
+  (if (or (not (ring-p comint-input-ring))
+          (ring-empty-p comint-input-ring))
+      (message "No history")
+    (let ((history nil)
+          (history-buffer " *Input History*")
+          (index (1- (ring-length comint-input-ring)))
+          (conf (current-window-configuration)))
+      ;; We have to build up a list ourselves from the ring vector.
+      (while (>= index 0)
+        (setq history (cons (ring-ref comint-input-ring index) history)
+              index (1- index)))
+      ;; Change "completion" to "history reference"
+      ;; to make the display accurate.
+      (with-output-to-temp-buffer history-buffer
+        (display-completion-list history)
+        (set-buffer history-buffer))
+      (message "Hit space to flush")
+      (let ((ch (read-event)))
+        (if (eq ch ?\ )
+            (set-window-configuration conf)
+          (setq unread-command-events (list ch)))))))
+
+(defun inferior-octave-strip-ctrl-g (string)
+  "Strip leading `^G' character.
+If STRING starts with a `^G', ring the bell and strip it."
+  (if (string-match "^\a" string)
+      (progn
+        (ding)
+        (setq string (substring string 1))))
+  string)
+
+(defun inferior-octave-output-filter (proc string)
+  "Standard output filter for the inferior Octave process.
+Ring Emacs bell if process output starts with an ASCII bell, and pass
+the rest to `comint-output-filter'."
+  (comint-output-filter proc (inferior-octave-strip-ctrl-g string)))
+
+(defun inferior-octave-output-digest (proc string)
+  "Special output filter for the inferior Octave process.
+Save all output between newlines into `inferior-octave-output-list', and
+the rest to `inferior-octave-output-string'."
+  (setq string (concat inferior-octave-output-string string))
+  (while (string-match "\n" string)
+    (setq inferior-octave-output-list
+	  (append inferior-octave-output-list
+		  (list (substring string 0 (match-beginning 0))))
+	  string (substring string (match-end 0))))
+  (if (string-match inferior-octave-prompt string)
+      (setq inferior-octave-receive-in-progress nil))
+  (setq inferior-octave-output-string string))
+
+(defun inferior-octave-send-list-and-digest (list)
+  "Send LIST to the inferior Octave process and digest the output.
+The elements of LIST have to be strings and are sent one by one.  All
+output is passed to the filter `inferior-octave-output-digest'."
+  (let* ((proc inferior-octave-process)
+	 (filter (process-filter proc))
+	 string)
+    (set-process-filter proc 'inferior-octave-output-digest)
+    (setq inferior-octave-output-list nil)
+    (unwind-protect
+	(while (setq string (car list))
+	  (setq inferior-octave-output-string nil
+		inferior-octave-receive-in-progress t)
+	  (comint-send-string proc string)
+	  (while inferior-octave-receive-in-progress
+	    (accept-process-output proc))
+	  (setq list (cdr list)))
+      (set-process-filter proc filter))))
+
+(defun inferior-octave-directory-tracker (string)
+  "Tracks `cd' commands issued to the inferior Octave process.
+Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
+  (cond
+   ((string-match "^[ \t]*cd[ \t;]*$" string)
+    (cd "~"))
+   ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string)
+    (cd (substring string (match-beginning 1) (match-end 1))))))
+
+(defun inferior-octave-resync-dirs ()
+  "Resync the buffer's idea of the current directory.
+This command queries the inferior Octave process about its current
+directory and makes this the current buffer's default directory."
+  (interactive)
+  (inferior-octave-send-list-and-digest '("disp (pwd ())\n"))
+  (cd (car inferior-octave-output-list)))
+
+;;; provide ourself
+
+(provide 'octave-inf)
+
+;; arch-tag: bdce0395-24d1-4bb4-bfba-6fb1eeb1a660
+;;; octave-inf.el ends here
diff --git a/emacs/octave-mod.el b/emacs/octave-mod.el
new file mode 100644
index 0000000..f5ecd7a
--- /dev/null
+++ b/emacs/octave-mod.el
@@ -0,0 +1,1515 @@
+;;; octave-mod.el --- editing Octave source files under Emacs
+
+;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;; Free Software Foundation, Inc.
+
+;; Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+;; Author: John Eaton <jwe at octave.org>
+;; Maintainer: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+;; Keywords: languages
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, see
+;; <http://www.gnu.org/licenses>.
+
+;;; Commentary:
+
+;; This package provides Emacs support for Octave.
+;; It defines Octave mode, a major mode for editing
+;; Octave code.
+
+;; The file octave-hlp.el provides `octave-help', a facility for looking up
+;; documentation on a symbol in the Octave info files.
+
+;; The file octave-inf.el contains code for interacting with an inferior
+;; Octave process using comint.
+
+;; See the documentation of `octave-mode', `octave-help' and
+;; `run-octave' for further information on usage and customization.
+
+;;; Code:
+(require 'custom)
+
+(defgroup octave nil
+  "Major mode for editing Octave source files."
+  :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
+  :group 'languages)
+
+(defvar inferior-octave-output-list nil)
+(defvar inferior-octave-output-string nil)
+(defvar inferior-octave-receive-in-progress nil)
+
+(defconst octave-maintainer-address
+  "Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>, bug-gnu-emacs at gnu.org"
+  "Current maintainer of the Emacs Octave package.")
+
+(defvar octave-abbrev-table nil
+  "Abbrev table for Octave's reserved words.
+Used in `octave-mode' and inferior-octave-mode buffers.
+All Octave abbrevs start with a grave accent (`).")
+(unless octave-abbrev-table
+  (define-abbrev-table 'octave-abbrev-table ()))
+
+(let ((abbrevs-changed abbrevs-changed))
+  (define-abbrev octave-abbrev-table "`a" "all_va_args" nil)
+  (define-abbrev octave-abbrev-table "`b" "break" nil)
+  (define-abbrev octave-abbrev-table "`cs" "case" nil)
+  (define-abbrev octave-abbrev-table "`ca" "catch" nil)
+  (define-abbrev octave-abbrev-table "`c" "continue" nil)
+  (define-abbrev octave-abbrev-table "`el" "else" nil)
+  (define-abbrev octave-abbrev-table "`eli" "elseif" nil)
+  (define-abbrev octave-abbrev-table "`et" "end_try_catch" nil)
+  (define-abbrev octave-abbrev-table "`eu" "end_unwind_protect" nil)
+  (define-abbrev octave-abbrev-table "`ef" "endfor" nil)
+  (define-abbrev octave-abbrev-table "`efu" "endfunction" nil)
+  (define-abbrev octave-abbrev-table "`ei" "endif" nil)
+  (define-abbrev octave-abbrev-table "`es" "endswitch" nil)
+  (define-abbrev octave-abbrev-table "`ew" "endwhile" nil)
+  (define-abbrev octave-abbrev-table "`f" "for" nil)
+  (define-abbrev octave-abbrev-table "`fu" "function" nil)
+  (define-abbrev octave-abbrev-table "`gl" "global" nil)
+  (define-abbrev octave-abbrev-table "`gp" "gplot" nil)
+  (define-abbrev octave-abbrev-table "`gs" "gsplot" nil)
+  (define-abbrev octave-abbrev-table "`if" "if ()" nil)
+  (define-abbrev octave-abbrev-table "`o" "otherwise" nil)
+  (define-abbrev octave-abbrev-table "`rp" "replot" nil)
+  (define-abbrev octave-abbrev-table "`r" "return" nil)
+  (define-abbrev octave-abbrev-table "`s" "switch" nil)
+  (define-abbrev octave-abbrev-table "`t" "try" nil)
+  (define-abbrev octave-abbrev-table "`u" "until ()" nil)
+  (define-abbrev octave-abbrev-table "`up" "unwind_protect" nil)
+  (define-abbrev octave-abbrev-table "`upc" "unwind_protect_cleanup" nil)
+  (define-abbrev octave-abbrev-table "`w" "while ()" nil))
+
+(defvar octave-comment-char ?#
+  "Character to start an Octave comment.")
+(defvar octave-comment-start
+  (string octave-comment-char ?\ )
+  "String to insert to start a new Octave in-line comment.")
+(defvar octave-comment-start-skip "\\s<+\\s-*"
+  "Regexp to match the start of an Octave comment up to its body.")
+
+(defvar octave-begin-keywords
+  '("do" "for" "function" "if" "switch" "try" "unwind_protect" "while"))
+(defvar octave-else-keywords
+  '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup"))
+;; FIXME: only use specific "end" tokens here to avoid confusion when "end"
+;; is used in indexing (the real fix is much more complex).
+(defvar octave-end-keywords
+  '("endfor" "endfunction" "endif" "endswitch" "end_try_catch"
+    "end_unwind_protect" "endwhile" "until"))
+
+(defvar octave-reserved-words
+  (append octave-begin-keywords
+	  octave-else-keywords
+	  octave-end-keywords
+	  '("break" "continue" "end" "global" "persistent" "return"))
+  "Reserved words in Octave.")
+
+(defvar octave-text-functions
+  '("casesen" "cd" "chdir" "clear" "diary" "dir" "document" "echo"
+    "edit_history" "format" "help" "history" "hold"
+    "load" "ls" "more" "run_history" "save" "type"
+    "which" "who" "whos")
+  "Text functions in Octave.")
+
+(defvar octave-variables
+  '("DEFAULT_EXEC_PATH" "DEFAULT_LOADPATH"
+    "EDITOR" "EXEC_PATH" "F_DUPFD" "F_GETFD" "F_GETFL" "F_SETFD"
+    "F_SETFL" "I" "IMAGE_PATH" "Inf" "J"
+    "NaN" "OCTAVE_VERSION" "O_APPEND" "O_CREAT" "O_EXCL"
+    "O_NONBLOCK" "O_RDONLY" "O_RDWR" "O_TRUNC" "O_WRONLY" "PAGER" "PS1"
+    "PS2" "PS4" "PWD" "SEEK_CUR" "SEEK_END" "SEEK_SET" "__F_DUPFD__"
+    "__F_GETFD__" "__F_GETFL__" "__F_SETFD__" "__F_SETFL__" "__I__"
+    "__Inf__" "__J__" "__NaN__" "__OCTAVE_VERSION__" "__O_APPEND__"
+    "__O_CREAT__" "__O_EXCL__" "__O_NONBLOCK__" "__O_RDONLY__"
+    "__O_RDWR__" "__O_TRUNC__" "__O_WRONLY__" "__PWD__" "__SEEK_CUR__"
+    "__SEEK_END__" "__SEEK_SET__" "__argv__" "__e__" "__eps__"
+    "__i__" "__inf__" "__j__" "__nan__" "__pi__"
+    "__program_invocation_name__" "__program_name__" "__realmax__"
+    "__realmin__" "__stderr__" "__stdin__" "__stdout__" "ans" "argv"
+    "beep_on_error" "completion_append_char"
+    "crash_dumps_octave_core" "default_save_format"
+    "e" "echo_executing_commands" "eps"
+    "error_text" "gnuplot_binary" "history_file"
+    "history_size" "ignore_function_time_stamp"
+    "inf" "nan" "nargin" "output_max_field_width" "output_precision"
+    "page_output_immediately" "page_screen_output" "pi"
+    "print_answer_id_name" "print_empty_dimensions"
+    "program_invocation_name" "program_name"
+    "realmax" "realmin" "save_precision"
+    "saving_history" "sighup_dumps_octave_core" "sigterm_dumps_octave_core"
+    "silent_functions" "split_long_rows" "stderr" "stdin" "stdout"
+    "string_fill_char" "struct_levels_to_print"
+    "suppress_verbose_help_message")
+  "Builtin variables in Octave.")
+
+(defvar octave-function-header-regexp
+  (concat "^\\s-*\\<\\(function\\)\\>"
+	  "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\w+\\)\\>")
+  "Regexp to match an Octave function header.
+The string `function' and its name are given by the first and third
+parenthetical grouping.")
+
+(defvar octave-font-lock-keywords
+  (list
+   ;; Fontify all builtin keywords.
+   (cons (concat "\\<\\("
+		 (mapconcat 'identity octave-reserved-words "\\|")
+		 (mapconcat 'identity octave-text-functions "\\|")
+		 "\\)\\>")
+	 'font-lock-keyword-face)
+   ;; Fontify all builtin operators.
+   (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
+	 (if (boundp 'font-lock-builtin-face)
+	     'font-lock-builtin-face
+	   'font-lock-preprocessor-face))
+   ;; Fontify all builtin variables.
+   (cons (concat "\\<\\("
+		 (mapconcat 'identity octave-variables "\\|")
+		 "\\)\\>")
+	 'font-lock-variable-name-face)
+   ;; Fontify all function declarations.
+   (list octave-function-header-regexp
+	 '(1 font-lock-keyword-face)
+	 '(3 font-lock-function-name-face nil t)))
+  "Additional Octave expressions to highlight.")
+
+(defcustom inferior-octave-buffer "*Inferior Octave*"
+  "Name of buffer for running an inferior Octave process."
+  :type 'string
+  :group 'octave-inferior)
+
+(defvar inferior-octave-process nil)
+
+(defvar octave-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "`" 'octave-abbrev-start)
+    (define-key map ";" 'octave-electric-semi)
+    (define-key map " " 'octave-electric-space)
+    (define-key map "\n" 'octave-reindent-then-newline-and-indent)
+    (define-key map "\e;" 'octave-indent-for-comment)
+    (define-key map "\e\n" 'octave-indent-new-comment-line)
+    (define-key map "\e\t" 'octave-complete-symbol)
+    (define-key map "\M-\C-a" 'octave-beginning-of-defun)
+    (define-key map "\M-\C-e" 'octave-end-of-defun)
+    (define-key map "\M-\C-h" 'octave-mark-defun)
+    (define-key map "\M-\C-q" 'octave-indent-defun)
+    (define-key map "\C-c;" 'octave-comment-region)
+    (define-key map "\C-c:" 'octave-uncomment-region)
+    (define-key map "\C-c\C-b" 'octave-submit-bug-report)
+    (define-key map "\C-c\C-p" 'octave-previous-code-line)
+    (define-key map "\C-c\C-n" 'octave-next-code-line)
+    (define-key map "\C-c\C-a" 'octave-beginning-of-line)
+    (define-key map "\C-c\C-e" 'octave-end-of-line)
+    (define-key map "\C-c\M-\C-n" 'octave-forward-block)
+    (define-key map "\C-c\M-\C-p" 'octave-backward-block)
+    (define-key map "\C-c\M-\C-u" 'octave-backward-up-block)
+    (define-key map "\C-c\M-\C-d" 'octave-down-block)
+    (define-key map "\C-c\M-\C-h" 'octave-mark-block)
+    (define-key map "\C-c]" 'octave-close-block)
+    (define-key map "\C-c\C-f" 'octave-insert-defun)
+    (define-key map "\C-c\C-h" 'octave-help)
+    (define-key map "\C-c\C-il" 'octave-send-line)
+    (define-key map "\C-c\C-ib" 'octave-send-block)
+    (define-key map "\C-c\C-if" 'octave-send-defun)
+    (define-key map "\C-c\C-ir" 'octave-send-region)
+    (define-key map "\C-c\C-is" 'octave-show-process-buffer)
+    (define-key map "\C-c\C-ih" 'octave-hide-process-buffer)
+    (define-key map "\C-c\C-ik" 'octave-kill-process)
+    (define-key map "\C-c\C-i\C-l" 'octave-send-line)
+    (define-key map "\C-c\C-i\C-b" 'octave-send-block)
+    (define-key map "\C-c\C-i\C-f" 'octave-send-defun)
+    (define-key map "\C-c\C-i\C-r" 'octave-send-region)
+    (define-key map "\C-c\C-i\C-s" 'octave-show-process-buffer)
+    (define-key map "\C-c\C-i\C-h" 'octave-hide-process-buffer)
+    (define-key map "\C-c\C-i\C-k" 'octave-kill-process)
+    map)
+  "Keymap used in Octave mode.")
+
+
+(defvar octave-mode-menu
+  '("Octave"
+    '("Lines"
+      ["Previous Code Line"	octave-previous-code-line t]
+      ["Next Code Line"		octave-next-code-line t]
+      ["Begin of Continuation"	octave-beginning-of-line t]
+      ["End of Continuation"	octave-end-of-line t]
+      ["Split Line at Point"	octave-indent-new-comment-line t])
+    '("Blocks"
+      ["Next Block"		octave-forward-block t]
+      ["Previous Block"		octave-backward-block t]
+      ["Down Block"		octave-down-block t]
+      ["Up Block"		octave-backward-up-block t]
+      ["Mark Block"		octave-mark-block t]
+      ["Close Block"		octave-close-block t])
+    '("Functions"
+      ["Begin of Function"	octave-beginning-of-defun t]
+      ["End of Function"	octave-end-of-defun t]
+      ["Mark Function"		octave-mark-defun t]
+      ["Indent Function"	octave-indent-defun t]
+      ["Insert Function"	octave-insert-defun t])
+    "-"
+    '("Debug"
+      ["Send Current Line"	octave-send-line t]
+      ["Send Current Block"	octave-send-block t]
+      ["Send Current Function"	octave-send-defun t]
+      ["Send Region"		octave-send-region t]
+      ["Show Process Buffer"	octave-show-process-buffer t]
+      ["Hide Process Buffer"	octave-hide-process-buffer t]
+      ["Kill Process"		octave-kill-process t])
+    "-"
+    ["Indent Line"		indent-according-to-mode t]
+    ["Complete Symbol"		octave-complete-symbol t]
+    "-"
+    ["Toggle Abbrev Mode"	abbrev-mode t]
+    ["Toggle Auto-Fill Mode"	auto-fill-mode t]
+    "-"
+    ["Submit Bug Report"	octave-submit-bug-report t]
+    "-"
+    ["Describe Octave Mode"	octave-describe-major-mode t]
+    ["Lookup Octave Index"	octave-help t])
+  "Menu for Octave mode.")
+
+(defvar octave-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?\r " "  table)
+    (modify-syntax-entry ?+ "."   table)
+    (modify-syntax-entry ?- "."   table)
+    (modify-syntax-entry ?= "."   table)
+    (modify-syntax-entry ?* "."   table)
+    (modify-syntax-entry ?/ "."   table)
+    (modify-syntax-entry ?> "."   table)
+    (modify-syntax-entry ?< "."   table)
+    (modify-syntax-entry ?& "."   table)
+    (modify-syntax-entry ?| "."   table)
+    (modify-syntax-entry ?! "."   table)
+    (modify-syntax-entry ?\\ "\\" table)
+    (modify-syntax-entry ?\' "."  table)
+    (modify-syntax-entry ?\` "w"  table)
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?. "w"   table)
+    (modify-syntax-entry ?_ "w"   table)
+    (modify-syntax-entry ?\% "<"  table)
+    (modify-syntax-entry ?\# "<"  table)
+    (modify-syntax-entry ?\n ">"  table)
+    table)
+  "Syntax table in use in `octave-mode' buffers.")
+
+(defcustom octave-auto-indent nil
+  "Non-nil means indent line after a semicolon or space in Octave mode."
+  :type 'boolean
+  :group 'octave)
+
+(defcustom octave-auto-newline nil
+  "Non-nil means automatically newline after a semicolon in Octave mode."
+  :type 'boolean
+  :group 'octave)
+
+(defcustom octave-blink-matching-block t
+  "Control the blinking of matching Octave block keywords.
+Non-nil means show matching begin of block when inserting a space,
+newline or semicolon after an else or end keyword."
+  :type 'boolean
+  :group 'octave)
+(defcustom octave-block-offset 2
+  "Extra indentation applied to statements in Octave block structures."
+  :type 'integer
+  :group 'octave)
+
+(defvar octave-block-begin-regexp
+  (concat "\\<\\("
+	  (mapconcat 'identity octave-begin-keywords "\\|")
+	  "\\)\\>"))
+(defvar octave-block-else-regexp
+  (concat "\\<\\("
+	  (mapconcat 'identity octave-else-keywords "\\|")
+	  "\\)\\>"))
+(defvar octave-block-end-regexp
+  (concat "\\<\\("
+	  (mapconcat 'identity octave-end-keywords "\\|")
+	  "\\)\\>"))
+(defvar octave-block-begin-or-end-regexp
+  (concat octave-block-begin-regexp "\\|" octave-block-end-regexp))
+(defvar octave-block-else-or-end-regexp
+  (concat octave-block-else-regexp "\\|" octave-block-end-regexp))
+;; FIXME: only use specific "end" tokens here to avoid confusion when "end"
+;; is used in indexing (the real fix is much more complex).
+(defvar octave-block-match-alist
+  '(("do" . ("until"))
+    ("for" . ("endfor"))
+    ("function" . ("endfunction"))
+    ("if" . ("else" "elseif" "endif"))
+    ("switch" . ("case" "otherwise" "endswitch"))
+    ("try" . ("catch" "end_try_catch"))
+    ("unwind_protect" . ("unwind_protect_cleanup" "end_unwind_protect"))
+    ("while" . ("endwhile")))
+  "Alist with Octave's matching block keywords.
+Has Octave's begin keywords as keys and a list of the matching else or
+end keywords as associated values.")
+
+(defvar octave-block-comment-start
+  (concat (make-string 2 octave-comment-char) " ")
+  "String to insert to start a new Octave comment on an empty line.")
+
+(defcustom octave-continuation-offset 4
+  "Extra indentation applied to Octave continuation lines."
+  :type 'integer
+  :group 'octave)
+(defvar octave-continuation-regexp
+  "[^#%\n]*\\(\\\\\\|\\.\\.\\.\\)\\s-*\\(\\s<.*\\)?$")
+(defcustom octave-continuation-string "\\"
+  "Character string used for Octave continuation lines.  Normally \\."
+  :type 'string
+  :group 'octave)
+
+(defvar octave-completion-alist nil
+  "Alist of Octave symbols for completion in Octave mode.
+Each element looks like (VAR . VAR), where the car and cdr are the same
+symbol (an Octave command or variable name).
+Currently, only builtin variables can be completed.")
+
+(defvar octave-mode-imenu-generic-expression
+  (list
+   ;; Functions
+   (list nil octave-function-header-regexp 3))
+  "Imenu expression for Octave mode.  See `imenu-generic-expression'.")
+
+(defcustom octave-mode-hook nil
+  "Hook to be run when Octave mode is started."
+  :type 'hook
+  :group 'octave)
+
+(defcustom octave-send-show-buffer t
+  "Non-nil means display `inferior-octave-buffer' after sending to it."
+  :type 'boolean
+  :group 'octave)
+(defcustom octave-send-line-auto-forward t
+  "Control auto-forward after sending to the inferior Octave process.
+Non-nil means always go to the next Octave code line after sending."
+  :type 'boolean
+  :group 'octave)
+(defcustom octave-send-echo-input t
+  "Non-nil means echo input sent to the inferior Octave process."
+  :type 'boolean
+  :group 'octave)
+
+
+;;;###autoload
+(defun octave-mode ()
+  "Major mode for editing Octave code.
+
+This mode makes it easier to write Octave code by helping with
+indentation, doing some of the typing for you (with Abbrev mode) and by
+showing keywords, comments, strings, etc.. in different faces (with
+Font Lock mode on terminals that support it).
+
+Octave itself is a high-level language, primarily intended for numerical
+computations.  It provides a convenient command line interface for
+solving linear and nonlinear problems numerically.  Function definitions
+can also be stored in files, and it can be used in a batch mode (which
+is why you need this mode!).
+
+The latest released version of Octave is always available via anonymous
+ftp from ftp.octave.org in the directory `/pub/octave'.  Complete
+source and binaries for several popular systems are available.
+
+Type \\[list-abbrevs] to display the built-in abbrevs for Octave keywords.
+
+Keybindings
+===========
+
+\\{octave-mode-map}
+
+Variables you can use to customize Octave mode
+==============================================
+
+`octave-auto-indent'
+  Non-nil means indent current line after a semicolon or space.
+  Default is nil.
+
+`octave-auto-newline'
+  Non-nil means auto-insert a newline and indent after a semicolon.
+  Default is nil.
+
+`octave-blink-matching-block'
+  Non-nil means show matching begin of block when inserting a space,
+  newline or semicolon after an else or end keyword.  Default is t.
+
+`octave-block-offset'
+  Extra indentation applied to statements in block structures.
+  Default is 2.
+
+`octave-continuation-offset'
+  Extra indentation applied to Octave continuation lines.
+  Default is 4.
+
+`octave-continuation-string'
+  String used for Octave continuation lines.
+  Default is a backslash.
+
+`octave-send-echo-input'
+  Non-nil means always display `inferior-octave-buffer' after sending a
+  command to the inferior Octave process.
+
+`octave-send-line-auto-forward'
+  Non-nil means always go to the next unsent line of Octave code after
+  sending a line to the inferior Octave process.
+
+`octave-send-echo-input'
+  Non-nil means echo input sent to the inferior Octave process.
+
+Turning on Octave mode runs the hook `octave-mode-hook'.
+
+To begin using this mode for all `.m' files that you edit, add the
+following lines to your `.emacs' file:
+
+  (add-to-list 'auto-mode-alist '(\"\\\\.m\\\\'\" . octave-mode))
+
+To automatically turn on the abbrev and auto-fill features,
+add the following lines to your `.emacs' file as well:
+
+  (add-hook 'octave-mode-hook
+	    (lambda ()
+	      (abbrev-mode 1)
+	      (auto-fill-mode 1)))
+
+To submit a problem report, enter \\[octave-submit-bug-report] from \
+an Octave mode buffer.
+This automatically sets up a mail buffer with version information
+already added.  You just need to add a description of the problem,
+including a reproducible test case and send the message."
+  (interactive)
+  (kill-all-local-variables)
+
+  (use-local-map octave-mode-map)
+  (setq major-mode 'octave-mode)
+  (setq mode-name "Octave")
+  (setq local-abbrev-table octave-abbrev-table)
+  (set-syntax-table octave-mode-syntax-table)
+
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'octave-indent-line)
+
+  (make-local-variable 'comment-start)
+  (setq comment-start octave-comment-start)
+  (make-local-variable 'comment-end)
+  (setq comment-end "")
+  (make-local-variable 'comment-column)
+  (setq comment-column 32)
+  (make-local-variable 'comment-start-skip)
+  (setq comment-start-skip "\\s<+\\s-*")
+  (make-local-variable 'comment-indent-function)
+  (setq comment-indent-function 'octave-comment-indent)
+
+  (make-local-variable 'parse-sexp-ignore-comments)
+  (setq parse-sexp-ignore-comments t)
+  (make-local-variable 'paragraph-start)
+  (setq paragraph-start (concat "\\s-*$\\|" page-delimiter))
+  (make-local-variable 'paragraph-separate)
+  (setq paragraph-separate paragraph-start)
+  (make-local-variable 'paragraph-ignore-fill-prefix)
+  (setq paragraph-ignore-fill-prefix t)
+  (make-local-variable 'fill-paragraph-function)
+  (setq fill-paragraph-function 'octave-fill-paragraph)
+  (make-local-variable 'adaptive-fill-regexp)
+  (setq adaptive-fill-regexp nil)
+  (make-local-variable 'fill-column)
+  (setq fill-column 72)
+  (make-local-variable 'normal-auto-fill-function)
+  (setq normal-auto-fill-function 'octave-auto-fill)
+
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '(octave-font-lock-keywords nil nil))
+
+  (make-local-variable 'imenu-generic-expression)
+  (setq imenu-generic-expression octave-mode-imenu-generic-expression
+        imenu-case-fold-search nil)
+
+  (octave-add-octave-menu)
+  (octave-initialize-completions)
+  (run-mode-hooks 'octave-mode-hook))
+
+;;; Miscellaneous useful functions
+(defun octave-describe-major-mode ()
+  "Describe the current major mode."
+  (interactive)
+  (describe-function major-mode))
+
+(defsubst octave-in-comment-p ()
+  "Return t if point is inside an Octave comment."
+  (interactive)
+  (save-excursion
+    (nth 4 (parse-partial-sexp (line-beginning-position) (point)))))
+
+(defsubst octave-in-string-p ()
+  "Return t if point is inside an Octave string."
+  (interactive)
+  (save-excursion
+    (nth 3 (parse-partial-sexp (line-beginning-position) (point)))))
+
+(defsubst octave-not-in-string-or-comment-p ()
+  "Return t if point is not inside an Octave string or comment."
+  (let ((pps (parse-partial-sexp (line-beginning-position) (point))))
+    (not (or (nth 3 pps) (nth 4 pps)))))
+
+(defun octave-in-block-p ()
+  "Return t if point is inside an Octave block.
+The block is taken to start at the first letter of the begin keyword and
+to end after the end keyword."
+  (let ((pos (point)))
+    (save-excursion
+      (condition-case nil
+	  (progn
+	    (skip-syntax-forward "w")
+	    (octave-up-block -1)
+	    (octave-forward-block)
+	    t)
+	(error nil))
+      (< pos (point)))))
+
+(defun octave-in-defun-p ()
+  "Return t if point is inside an Octave function declaration.
+The function is taken to start at the `f' of `function' and to end after
+the end keyword."
+  (let ((pos (point)))
+    (save-excursion
+      (or (and (looking-at "\\<function\\>")
+	       (octave-not-in-string-or-comment-p))
+	  (and (octave-beginning-of-defun)
+	       (condition-case nil
+		   (progn
+		     (octave-forward-block)
+		     t)
+		 (error nil))
+	       (< pos (point)))))))
+
+(defun octave-maybe-insert-continuation-string ()
+  (if (or (octave-in-comment-p)
+	  (save-excursion
+	    (beginning-of-line)
+	    (looking-at octave-continuation-regexp)))
+      nil
+    (delete-horizontal-space)
+    (insert (concat " " octave-continuation-string))))
+
+(defvar octave-xemacs-p
+  (string-match "XEmacs\\|Lucid" emacs-version))
+
+;;; Comments
+(defun octave-comment-region (beg end &optional arg)
+  "Comment or uncomment each line in the region as Octave code.
+See `comment-region'."
+  (interactive "r\nP")
+  (let ((comment-start (char-to-string octave-comment-char)))
+    (comment-region beg end arg)))
+
+(defun octave-uncomment-region (beg end &optional arg)
+  "Uncomment each line in the region as Octave code."
+  (interactive "r\nP")
+  (or arg (setq arg 1))
+  (octave-comment-region beg end (- arg)))
+
+
+;;; Indentation
+(defun calculate-octave-indent ()
+  "Return appropriate indentation for current line as Octave code.
+Returns an integer (the column to indent to) unless the line is a
+comment line with fixed goal golumn.  In that case, returns a list whose
+car is the column to indent to, and whose cdr is the current indentation
+level."
+  (let ((is-continuation-line
+	 (save-excursion
+	   (if (zerop (octave-previous-code-line))
+	       (looking-at octave-continuation-regexp))))
+	(icol 0))
+    (save-excursion
+      (beginning-of-line)
+      ;; If we can move backward out one level of parentheses, take 1
+      ;; plus the indentation of that parenthesis.  Otherwise, go back
+      ;; to the beginning of the previous code line, and compute the
+      ;; offset this line gives.
+      (if (condition-case nil
+	      (progn
+		(up-list -1)
+		t)
+	    (error nil))
+	  (setq icol (+ 1 (current-column)))
+	(if (zerop (octave-previous-code-line))
+	    (progn
+	      (octave-beginning-of-line)
+	      (back-to-indentation)
+	      (setq icol (current-column))
+	      (let ((bot (point))
+		    (eol (line-end-position)))
+		(while (< (point) eol)
+		  (if (octave-not-in-string-or-comment-p)
+		      (cond
+		       ((looking-at "\\<switch\\>")
+			(setq icol (+ icol (* 2 octave-block-offset))))
+		       ((looking-at octave-block-begin-regexp)
+			(setq icol (+ icol octave-block-offset)))
+		       ((looking-at octave-block-else-regexp)
+			(if (= bot (point))
+			    (setq icol (+ icol octave-block-offset))))
+		       ((looking-at octave-block-end-regexp)
+			(if (not (= bot (point)))
+			    (setq icol (- icol
+					  (octave-block-end-offset)))))))
+		  (forward-char)))
+	      (if is-continuation-line
+		  (setq icol (+ icol octave-continuation-offset)))))))
+    (save-excursion
+      (back-to-indentation)
+      (cond
+       ((and (looking-at octave-block-else-regexp)
+	     (octave-not-in-string-or-comment-p))
+	(setq icol (- icol octave-block-offset)))
+       ((and (looking-at octave-block-end-regexp)
+	     (octave-not-in-string-or-comment-p))
+	(setq icol (- icol (octave-block-end-offset))))
+       ((or (looking-at "\\s<\\s<\\s<\\S<")
+	    (octave-before-magic-comment-p))
+	(setq icol (list 0 icol)))
+       ((looking-at "\\s<\\S<")
+	(setq icol (list comment-column icol)))))
+    icol))
+
+(defun octave-block-end-offset ()
+  (save-excursion
+    (octave-backward-up-block 1)
+    (* octave-block-offset
+       (if (string-match (match-string 0) "switch") 2 1))))
+
+(defun octave-before-magic-comment-p ()
+  (save-excursion
+    (beginning-of-line)
+    (and (bobp) (looking-at "\\s-*#!"))))
+
+(defun octave-comment-indent ()
+  (if (or (looking-at "\\s<\\s<\\s<")
+	  (octave-before-magic-comment-p))
+      0
+    (if (looking-at "\\s<\\s<")
+	(calculate-octave-indent)
+      (skip-syntax-backward " ")
+      (max (if (bolp) 0 (+ 1 (current-column)))
+	   comment-column))))
+
+(defun octave-indent-for-comment ()
+  "Maybe insert and indent an Octave comment.
+If there is no comment already on this line, create a code-level comment
+\(started by two comment characters) if the line is empty, or an in-line
+comment (started by one comment character) otherwise.
+Point is left after the start of the comment which is properly aligned."
+  (interactive)
+  (beginning-of-line)
+  (if (looking-at "^\\s-*$")
+      (insert octave-block-comment-start)
+    (indent-for-comment))
+  (indent-according-to-mode))
+
+(defun octave-indent-line (&optional arg)
+  "Indent current line as Octave code.
+With optional ARG, use this as offset unless this line is a comment with
+fixed goal column."
+  (interactive)
+  (or arg (setq arg 0))
+  (let ((icol (calculate-octave-indent))
+	(relpos (- (current-column) (current-indentation))))
+    (if (listp icol)
+	(setq icol (car icol))
+      (setq icol (+ icol arg)))
+    (if (< icol 0)
+	(error "Unmatched end keyword")
+      (indent-line-to icol)
+      (if (> relpos 0)
+	  (move-to-column (+ icol relpos))))))
+
+(defun octave-indent-new-comment-line ()
+  "Break Octave line at point, continuing comment if within one.
+If within code, insert `octave-continuation-string' before breaking the
+line.  If within a string, signal an error.
+The new line is properly indented."
+  (interactive)
+  (delete-horizontal-space)
+  (cond
+   ((octave-in-comment-p)
+    (indent-new-comment-line))
+   ((octave-in-string-p)
+    (error "Cannot split a code line inside a string"))
+   (t
+    (insert (concat " " octave-continuation-string))
+    (octave-reindent-then-newline-and-indent))))
+
+(defun octave-indent-defun ()
+  "Properly indent the Octave function which contains point."
+  (interactive)
+  (save-excursion
+    (octave-mark-defun)
+    (message "Indenting function...")
+    (indent-region (point) (mark) nil))
+  (message "Indenting function...done."))
+
+
+;;; Motion
+(defun octave-next-code-line (&optional arg)
+  "Move ARG lines of Octave code forward (backward if ARG is negative).
+Skips past all empty and comment lines.  Default for ARG is 1.
+
+On success, return 0.  Otherwise, go as far as possible and return -1."
+  (interactive "p")
+  (or arg (setq arg 1))
+  (beginning-of-line)
+  (let ((n 0)
+	(inc (if (> arg 0) 1 -1)))
+    (while (and (/= arg 0) (= n 0))
+      (setq n (forward-line inc))
+      (while (and (= n 0)
+		  (looking-at "\\s-*\\($\\|\\s<\\)"))
+	(setq n (forward-line inc)))
+      (setq arg (- arg inc)))
+    n))
+
+(defun octave-previous-code-line (&optional arg)
+  "Move ARG lines of Octave code backward (forward if ARG is negative).
+Skips past all empty and comment lines.  Default for ARG is 1.
+
+On success, return 0.  Otherwise, go as far as possible and return -1."
+  (interactive "p")
+  (or arg (setq arg 1))
+  (octave-next-code-line (- arg)))
+
+(defun octave-beginning-of-line ()
+  "Move point to beginning of current Octave line.
+If on an empty or comment line, go to the beginning of that line.
+Otherwise, move backward to the beginning of the first Octave code line
+which is not inside a continuation statement, i.e., which does not
+follow a code line ending in `...' or `\\', or is inside an open
+parenthesis list."
+  (interactive)
+  (beginning-of-line)
+  (if (not (looking-at "\\s-*\\($\\|\\s<\\)"))
+      (while (or (condition-case nil
+		     (progn
+		       (up-list -1)
+		       (beginning-of-line)
+		       t)
+		   (error nil))
+		 (and (or (looking-at "\\s-*\\($\\|\\s<\\)")
+			  (save-excursion
+			    (if (zerop (octave-previous-code-line))
+				(looking-at octave-continuation-regexp))))
+		      (zerop (forward-line -1)))))))
+
+(defun octave-end-of-line ()
+  "Move point to end of current Octave line.
+If on an empty or comment line, go to the end of that line.
+Otherwise, move forward to the end of the first Octave code line which
+does not end in `...' or `\\' or is inside an open parenthesis list."
+  (interactive)
+  (end-of-line)
+  (if (save-excursion
+	(beginning-of-line)
+	(looking-at "\\s-*\\($\\|\\s<\\)"))
+      ()
+    (while (or (condition-case nil
+		   (progn
+		     (up-list 1)
+		     (end-of-line)
+		     t)
+		 (error nil))
+	       (and (save-excursion
+		      (beginning-of-line)
+		      (or (looking-at "\\s-*\\($\\|\\s<\\)")
+			  (looking-at octave-continuation-regexp)))
+		    (zerop (forward-line 1)))))
+    (end-of-line)))
+
+(defun octave-scan-blocks (count depth)
+  "Scan from point by COUNT Octave begin-end blocks.
+Returns the character number of the position thus found.
+
+If DEPTH is nonzero, block depth begins counting from that value.
+Only places where the depth in blocks becomes zero are candidates for
+stopping; COUNT such places are counted.
+
+If the beginning or end of the buffer is reached and the depth is wrong,
+an error is signaled."
+  (let ((min-depth (if (> depth 0) 0 depth))
+	(inc (if (> count 0) 1 -1)))
+    (save-excursion
+      (while (/= count 0)
+	(catch 'foo
+	  (while (or (re-search-forward
+		      octave-block-begin-or-end-regexp nil 'move inc)
+		     (if (/= depth 0)
+			 (error "Unbalanced block")))
+	    (if (octave-not-in-string-or-comment-p)
+		(progn
+		  (cond
+		   ((match-end 1)
+		    (setq depth (+ depth inc)))
+		   ((match-end 2)
+		    (setq depth (- depth inc))))
+		  (if (< depth min-depth)
+		      (error "Containing expression ends prematurely"))
+		  (if (= depth 0)
+		      (throw 'foo nil))))))
+	(setq count (- count inc)))
+      (point))))
+
+(defun octave-forward-block (&optional arg)
+  "Move forward across one balanced Octave begin-end block.
+With argument, do it that many times.
+Negative arg -N means move backward across N blocks."
+  (interactive "p")
+  (or arg (setq arg 1))
+  (goto-char (or (octave-scan-blocks arg 0) (buffer-end arg))))
+
+(defun octave-backward-block (&optional arg)
+  "Move backward across one balanced Octave begin-end block.
+With argument, do it that many times.
+Negative arg -N means move forward across N blocks."
+  (interactive "p")
+  (or arg (setq arg 1))
+  (octave-forward-block (- arg)))
+
+(defun octave-down-block (arg)
+  "Move forward down one begin-end block level of Octave code.
+With argument, do this that many times.
+A negative argument means move backward but still go down a level.
+In Lisp programs, an argument is required."
+  (interactive "p")
+  (let ((inc (if (> arg 0) 1 -1)))
+    (while (/= arg 0)
+      (goto-char (or (octave-scan-blocks inc -1)
+		     (buffer-end arg)))
+      (setq arg (- arg inc)))))
+
+(defun octave-backward-up-block (arg)
+  "Move backward out of one begin-end block level of Octave code.
+With argument, do this that many times.
+A negative argument means move forward but still to a less deep spot.
+In Lisp programs, an argument is required."
+  (interactive "p")
+  (octave-up-block (- arg)))
+
+(defun octave-up-block (arg)
+  "Move forward out of one begin-end block level of Octave code.
+With argument, do this that many times.
+A negative argument means move backward but still to a less deep spot.
+In Lisp programs, an argument is required."
+  (interactive "p")
+  (let ((inc (if (> arg 0) 1 -1)))
+    (while (/= arg 0)
+      (goto-char (or (octave-scan-blocks inc 1)
+		     (buffer-end arg)))
+      (setq arg (- arg inc)))))
+
+(defun octave-mark-block ()
+  "Put point at the beginning of this Octave block, mark at the end.
+The block marked is the one that contains point or follows point."
+  (interactive)
+  (let ((pos (point)))
+    (if (or (and (octave-in-block-p)
+		 (skip-syntax-forward "w"))
+	    (condition-case nil
+		(progn
+		  (octave-down-block 1)
+		  (octave-in-block-p))
+	      (error nil)))
+	(progn
+	  (octave-up-block -1)
+	  (push-mark (point))
+	  (octave-forward-block)
+	  (exchange-point-and-mark))
+      (goto-char pos)
+      (message "No block to mark found"))))
+
+(defun octave-close-block ()
+  "Close the current Octave block on a separate line.
+An error is signaled if no block to close is found."
+  (interactive)
+  (let (bb-keyword)
+    (condition-case nil
+	(progn
+	  (save-excursion
+	    (octave-backward-up-block 1)
+	    (setq bb-keyword (buffer-substring-no-properties
+			      (match-beginning 1) (match-end 1))))
+	  (if (save-excursion
+		(beginning-of-line)
+		(looking-at "^\\s-*$"))
+	      (indent-according-to-mode)
+	    (octave-reindent-then-newline-and-indent))
+	  (insert (car (reverse
+			(assoc bb-keyword
+			       octave-block-match-alist))))
+	  (octave-reindent-then-newline-and-indent)
+	  t)
+      (error (message "No block to close found")))))
+
+(defun octave-blink-matching-block-open ()
+  "Blink the matching Octave begin block keyword.
+If point is right after an Octave else or end type block keyword, move
+cursor momentarily to the corresponding begin keyword.
+Signal an error if the keywords are incompatible."
+  (interactive)
+  (let (bb-keyword bb-arg eb-keyword pos eol)
+    (if (and (octave-not-in-string-or-comment-p)
+	     (looking-at "\\>")
+	     (save-excursion
+	       (skip-syntax-backward "w")
+	       (looking-at octave-block-else-or-end-regexp)))
+	(save-excursion
+	  (cond
+	   ((match-end 1)
+	    (setq eb-keyword
+		  (buffer-substring-no-properties
+		   (match-beginning 1) (match-end 1)))
+	    (octave-backward-up-block 1))
+	   ((match-end 2)
+	    (setq eb-keyword
+		  (buffer-substring-no-properties
+		   (match-beginning 2) (match-end 2)))
+	    (octave-backward-block)))
+	  (setq pos (match-end 0)
+		bb-keyword
+		(buffer-substring-no-properties
+		 (match-beginning 0) pos)
+		pos (+ pos 1)
+		eol (line-end-position)
+		bb-arg
+		(save-excursion
+		  (save-restriction
+		    (goto-char pos)
+		    (while (and (skip-syntax-forward "^<" eol)
+				(octave-in-string-p)
+				(not (forward-char 1))))
+		    (skip-syntax-backward " ")
+		    (buffer-substring-no-properties pos (point)))))
+	  (if (member eb-keyword
+		      (cdr (assoc bb-keyword octave-block-match-alist)))
+	      (progn
+		(message "Matches `%s %s'" bb-keyword bb-arg)
+		(if (pos-visible-in-window-p)
+		    (sit-for blink-matching-delay)))
+	    (error "Block keywords `%s' and `%s' do not match"
+		   bb-keyword eb-keyword))))))
+
+(defun octave-beginning-of-defun (&optional arg)
+  "Move backward to the beginning of an Octave function.
+With positive ARG, do it that many times.  Negative argument -N means
+move forward to Nth following beginning of a function.
+Returns t unless search stops at the beginning or end of the buffer."
+  (interactive "p")
+  (let* ((arg (or arg 1))
+	 (inc (if (> arg 0) 1 -1))
+	 (found))
+    (and (not (eobp))
+	 (not (and (> arg 0) (looking-at "\\<function\\>")))
+	 (skip-syntax-forward "w"))
+    (while (and (/= arg 0)
+		(setq found
+		      (re-search-backward "\\<function\\>" nil 'move inc)))
+      (if (octave-not-in-string-or-comment-p)
+	  (setq arg (- arg inc))))
+    (if found
+	(progn
+	  (and (< inc 0) (goto-char (match-beginning 0)))
+	  t))))
+
+(defun octave-end-of-defun (&optional arg)
+  "Move forward to the end of an Octave function.
+With positive ARG, do it that many times.  Negative argument -N means
+move back to Nth preceding end of a function.
+
+An end of a function occurs right after the end keyword matching the
+`function' keyword that starts the function."
+  (interactive "p")
+  (or arg (setq arg 1))
+  (and (< arg 0) (skip-syntax-backward "w"))
+  (and (> arg 0) (skip-syntax-forward "w"))
+  (if (octave-in-defun-p)
+      (setq arg (- arg 1)))
+  (if (= arg 0) (setq arg -1))
+  (if (octave-beginning-of-defun (- arg))
+      (octave-forward-block)))
+
+(defun octave-mark-defun ()
+  "Put point at the beginning of this Octave function, mark at its end.
+The function marked is the one containing point or following point."
+  (interactive)
+  (let ((pos (point)))
+    (if (or (octave-in-defun-p)
+	    (and (octave-beginning-of-defun -1)
+		 (octave-in-defun-p)))
+	(progn
+	  (skip-syntax-forward "w")
+	  (octave-beginning-of-defun)
+	  (push-mark (point))
+	  (octave-end-of-defun)
+	  (exchange-point-and-mark))
+      (goto-char pos)
+      (message "No function to mark found"))))
+
+
+;;; Filling
+(defun octave-auto-fill ()
+  "Perform auto-fill in Octave mode.
+Returns nil if no feasible place to break the line could be found, and t
+otherwise."
+  (let (fc give-up)
+    (if (or (null (setq fc (current-fill-column)))
+	    (save-excursion
+	      (beginning-of-line)
+	      (and auto-fill-inhibit-regexp
+		   (looking-at auto-fill-inhibit-regexp))))
+	nil				; Can't do anything
+      (if (and (not (octave-in-comment-p))
+	       (> (current-column) fc))
+	  (setq fc (- fc (+ (length octave-continuation-string) 1))))
+      (while (and (not give-up) (> (current-column) fc))
+	(let* ((opoint (point))
+	       (fpoint
+		(save-excursion
+		  (move-to-column (+ fc 1))
+		  (skip-chars-backward "^ \t\n")
+		  ;; If we're at the beginning of the line, break after
+		  ;; the first word
+		  (if (bolp)
+		      (re-search-forward "[ \t]" opoint t))
+		  ;; If we're in a comment line, don't break after the
+		  ;; comment chars
+		  (if (save-excursion
+			(skip-syntax-backward " <")
+			(bolp))
+		      (re-search-forward "[ \t]" (line-end-position)
+					 'move))
+		  ;; If we're not in a comment line and just ahead the
+		  ;; continuation string, don't break here.
+		  (if (and (not (octave-in-comment-p))
+			   (looking-at
+			    (concat "\\s-*"
+				    (regexp-quote
+				     octave-continuation-string)
+				    "\\s-*$")))
+		      (end-of-line))
+		  (skip-chars-backward " \t")
+		  (point))))
+	  (if (save-excursion
+		(goto-char fpoint)
+		(not (or (bolp) (eolp))))
+	      (let ((prev-column (current-column)))
+		(if (save-excursion
+		      (skip-chars-backward " \t")
+		      (= (point) fpoint))
+		    (progn
+		      (octave-maybe-insert-continuation-string)
+		      (indent-new-comment-line t))
+		  (save-excursion
+		    (goto-char fpoint)
+		    (octave-maybe-insert-continuation-string)
+		    (indent-new-comment-line t)))
+		(if (>= (current-column) prev-column)
+		    (setq give-up t)))
+	    (setq give-up t))))
+      (not give-up))))
+
+(defun octave-fill-paragraph (&optional arg)
+ "Fill paragraph of Octave code, handling Octave comments."
+ ;; FIXME: now that the default fill-paragraph takes care of similar issues,
+ ;; this seems obsolete.  --Stef
+ (interactive "P")
+ (save-excursion
+   (let ((end (progn (forward-paragraph) (point)))
+	 (beg (progn
+		(forward-paragraph -1)
+		(skip-chars-forward " \t\n")
+		(beginning-of-line)
+		(point)))
+	 (cfc (current-fill-column))
+	 (ind (calculate-octave-indent))
+	 comment-prefix)
+     (save-restriction
+       (goto-char beg)
+       (narrow-to-region beg end)
+       (if (listp ind) (setq ind (nth 1 ind)))
+       (while (not (eobp))
+	 (condition-case nil
+	     (octave-indent-line ind)
+	   (error nil))
+	 (if (and (> ind 0)
+		  (not
+		   (save-excursion
+		     (beginning-of-line)
+		     (looking-at "^\\s-*\\($\\|\\s<+\\)"))))
+	     (setq ind 0))
+	 (move-to-column cfc)
+	 ;; First check whether we need to combine non-empty comment lines
+	 (if (and (< (current-column) cfc)
+		  (octave-in-comment-p)
+		  (not (save-excursion
+			 (beginning-of-line)
+			 (looking-at "^\\s-*\\s<+\\s-*$"))))
+	     ;; This is a nonempty comment line which does not extend
+	     ;; past the fill column.  If it is followed by a nonempty
+	     ;; comment line with the same comment prefix, try to
+	     ;; combine them, and repeat this until either we reach the
+	     ;; fill-column or there is nothing more to combine.
+	     (progn
+	       ;; Get the comment prefix
+	       (save-excursion
+		 (beginning-of-line)
+		 (while (and (re-search-forward "\\s<+")
+			     (not (octave-in-comment-p))))
+		 (setq comment-prefix (match-string 0)))
+	       ;; And keep combining ...
+	       (while (and (< (current-column) cfc)
+			   (save-excursion
+			     (forward-line 1)
+			     (and (looking-at
+				   (concat "^\\s-*"
+					   comment-prefix
+					   "\\S<"))
+				  (not (looking-at
+					(concat "^\\s-*"
+						comment-prefix
+						"\\s-*$"))))))
+		 (delete-char 1)
+		 (re-search-forward comment-prefix)
+		 (delete-region (match-beginning 0) (match-end 0))
+		 (fixup-whitespace)
+		 (move-to-column cfc))))
+	 ;; We might also try to combine continued code lines>  Perhaps
+	 ;; some other time ...
+	 (skip-chars-forward "^ \t\n")
+	 (delete-horizontal-space)
+	 (if (or (< (current-column) cfc)
+		 (and (= (current-column) cfc) (eolp)))
+	     (forward-line 1)
+	   (if (not (eolp)) (insert " "))
+	   (or (octave-auto-fill)
+	       (forward-line 1)))))
+     t)))
+
+
+;;; Completions
+(defun octave-initialize-completions ()
+  "Create an alist for Octave completions."
+  (if octave-completion-alist
+      ()
+    (setq octave-completion-alist
+	  (mapcar '(lambda (var) (cons var var))
+		  (append octave-reserved-words
+			  octave-text-functions
+			  octave-variables)))))
+
+(defun octave-complete-symbol ()
+  "Perform completion on Octave symbol preceding point.
+Compare that symbol against Octave's reserved words and builtin
+variables."
+  ;; This code taken from lisp-complete-symbol
+  (interactive)
+  (let* ((end (point))
+	 (beg (save-excursion (backward-sexp 1) (point)))
+	 (string (buffer-substring-no-properties beg end))
+	 (completion (try-completion string octave-completion-alist)))
+    (cond ((eq completion t))		; ???
+	  ((null completion)
+	   (message "Can't find completion for \"%s\"" string)
+	   (ding))
+	  ((not (string= string completion))
+           (delete-region beg end)
+           (insert completion))
+	  (t
+	   (let ((list (all-completions string octave-completion-alist))
+		 (conf (current-window-configuration)))
+	     ;; Taken from comint.el
+	     (message "Making completion list...")
+	     (with-output-to-temp-buffer "*Completions*"
+	       (display-completion-list list string))
+	     (message "Hit space to flush")
+	     (let (key first)
+	       (if (save-excursion
+		     (set-buffer (get-buffer "*Completions*"))
+		     (setq key (read-key-sequence nil)
+			   first (aref key 0))
+		     (and (consp first) (consp (event-start first))
+			  (eq (window-buffer (posn-window (event-start
+							   first)))
+			      (get-buffer "*Completions*"))
+			  (eq (key-binding key) 'mouse-choose-completion)))
+		   (progn
+		     (mouse-choose-completion first)
+		     (set-window-configuration conf))
+		 (if (eq first ?\ )
+		     (set-window-configuration conf)
+		   (setq unread-command-events
+			 (listify-key-sequence key))))))))))
+
+
+;;; Electric characters && friends
+(defun octave-reindent-then-newline-and-indent ()
+  "Reindent current Octave line, insert newline, and indent the new line.
+If Abbrev mode is on, expand abbrevs first."
+  (interactive)
+  (if abbrev-mode (expand-abbrev))
+  (if octave-blink-matching-block
+      (octave-blink-matching-block-open))
+  (save-excursion
+    (delete-region (point) (progn (skip-chars-backward " \t") (point)))
+    (indent-according-to-mode))
+  (insert "\n")
+  (indent-according-to-mode))
+
+(defun octave-electric-semi ()
+  "Insert a semicolon in Octave mode.
+Maybe expand abbrevs and blink matching block open keywords.
+Reindent the line of `octave-auto-indent' is non-nil.
+Insert a newline if `octave-auto-newline' is non-nil."
+  (interactive)
+  (if (not (octave-not-in-string-or-comment-p))
+      (insert ";")
+    (if abbrev-mode (expand-abbrev))
+    (if octave-blink-matching-block
+	(octave-blink-matching-block-open))
+    (if octave-auto-indent
+	(indent-according-to-mode))
+    (insert ";")
+    (if octave-auto-newline
+	(newline-and-indent))))
+
+(defun octave-electric-space ()
+  "Insert a space in Octave mode.
+Maybe expand abbrevs and blink matching block open keywords.
+Reindent the line of `octave-auto-indent' is non-nil."
+  (interactive)
+  (setq last-command-char ? )
+  (if (and octave-auto-indent
+	   (not (octave-not-in-string-or-comment-p)))
+      (progn
+	(indent-according-to-mode)
+	(self-insert-command 1))
+    (if abbrev-mode (expand-abbrev))
+    (if octave-blink-matching-block
+	(octave-blink-matching-block-open))
+    (if (and octave-auto-indent
+	     (save-excursion
+	       (skip-syntax-backward " ")
+	       (not (bolp))))
+	(indent-according-to-mode))
+    (self-insert-command 1)))
+
+(defun octave-abbrev-start ()
+  "Start entering an Octave abbreviation.
+If Abbrev mode is turned on, typing ` (grave accent) followed by ? or
+\\[help-command] lists all Octave abbrevs.  Any other key combination is
+executed normally.
+Note that all Octave mode abbrevs start with a grave accent."
+  (interactive)
+  (if (not abbrev-mode)
+      (self-insert-command 1)
+    (let (c)
+      (insert last-command-char)
+      (if (if octave-xemacs-p
+	      (or (eq (event-to-character (setq c (next-event))) ??)
+		  (eq (event-to-character c) help-char))
+	    (or (eq (setq c (read-event)) ??)
+		(eq c help-char)))
+	  (let ((abbrev-table-name-list '(octave-abbrev-table)))
+	    (list-abbrevs))
+	(setq unread-command-events (list c))))))
+
+(defun octave-insert-defun (name args vals)
+  "Insert an Octave function skeleton.
+Prompt for the function's name, arguments and return values (to be
+entered without parens)."
+  (interactive
+   (list
+    (read-from-minibuffer "Function name: "
+			  (substring (buffer-name) 0 -2))
+    (read-from-minibuffer "Arguments: ")
+    (read-from-minibuffer "Return values: ")))
+  (let ((string (format "%s %s (%s)"
+			(cond
+			 ((string-equal vals "")
+			  vals)
+			 ((string-match "[ ,]" vals)
+			  (concat " [" vals "] ="))
+			 (t
+			  (concat " " vals " =")))
+			name
+			args))
+	(prefix octave-block-comment-start))
+    (if (not (bobp)) (newline))
+    (insert "function" string)
+    (indent-according-to-mode)
+    (newline 2)
+    (insert prefix "usage: " string)
+    (reindent-then-newline-and-indent)
+    (insert prefix)
+    (reindent-then-newline-and-indent)
+    (insert prefix)
+    (indent-according-to-mode)
+    (save-excursion
+      (newline 2)
+      (insert "endfunction")
+      (indent-according-to-mode))))
+
+
+;;; Menu
+(defun octave-add-octave-menu ()
+  "Add the `Octave' menu to the menu bar in Octave mode."
+  (require 'easymenu)
+  (easy-menu-define octave-mode-menu-map octave-mode-map
+		    "Menu keymap for Octave mode." octave-mode-menu)
+  (easy-menu-add octave-mode-menu-map octave-mode-map))
+
+
+;;; Communication with the inferior Octave process
+(defun octave-kill-process ()
+  "Kill inferior Octave process and its buffer."
+  (interactive)
+  (if inferior-octave-process
+      (progn
+	(process-send-string inferior-octave-process "quit;\n")
+	(accept-process-output inferior-octave-process)))
+  (if inferior-octave-buffer
+      (kill-buffer inferior-octave-buffer)))
+
+(defun octave-show-process-buffer ()
+  "Make sure that `inferior-octave-buffer' is displayed."
+  (interactive)
+  (if (get-buffer inferior-octave-buffer)
+      (display-buffer inferior-octave-buffer)
+    (message "No buffer named %s" inferior-octave-buffer)))
+
+(defun octave-hide-process-buffer ()
+  "Delete all windows that display `inferior-octave-buffer'."
+  (interactive)
+  (if (get-buffer inferior-octave-buffer)
+      (delete-windows-on inferior-octave-buffer)
+    (message "No buffer named %s" inferior-octave-buffer)))
+
+(defun octave-send-region (beg end)
+  "Send current region to the inferior Octave process."
+  (interactive "r")
+  (inferior-octave t)
+  (let ((proc inferior-octave-process)
+	(string (buffer-substring-no-properties beg end))
+	line)
+    (save-excursion
+      (set-buffer inferior-octave-buffer)
+      (setq inferior-octave-output-list nil)
+      (while (not (string-equal string ""))
+	(if (string-match "\n" string)
+	    (setq line (substring string 0 (match-beginning 0))
+		  string (substring string (match-end 0)))
+	  (setq line string string ""))
+	(setq inferior-octave-receive-in-progress t)
+	(inferior-octave-send-list-and-digest (list (concat line "\n")))
+	(while inferior-octave-receive-in-progress
+	  (accept-process-output proc))
+	(insert-before-markers
+	 (mapconcat 'identity
+		    (append
+		     (if octave-send-echo-input (list line) (list ""))
+		     (mapcar 'inferior-octave-strip-ctrl-g
+			     inferior-octave-output-list)
+		     (list inferior-octave-output-string))
+		    "\n")))))
+  (if octave-send-show-buffer
+      (display-buffer inferior-octave-buffer)))
+
+(defun octave-send-block ()
+  "Send current Octave block to the inferior Octave process."
+  (interactive)
+  (save-excursion
+    (octave-mark-block)
+    (octave-send-region (point) (mark))))
+
+(defun octave-send-defun ()
+  "Send current Octave function to the inferior Octave process."
+  (interactive)
+  (save-excursion
+    (octave-mark-defun)
+    (octave-send-region (point) (mark))))
+
+(defun octave-send-line (&optional arg)
+  "Send current Octave code line to the inferior Octave process.
+With positive prefix ARG, send that many lines.
+If `octave-send-line-auto-forward' is non-nil, go to the next unsent
+code line."
+  (interactive "P")
+  (or arg (setq arg 1))
+  (if (> arg 0)
+      (let (beg end)
+	(beginning-of-line)
+	(setq beg (point))
+	(octave-next-code-line (- arg 1))
+	(end-of-line)
+	(setq end (point))
+	(if octave-send-line-auto-forward
+	    (octave-next-code-line 1))
+	(octave-send-region beg end))))
+
+(defun octave-eval-print-last-sexp ()
+  "Evaluate Octave sexp before point and print value into current buffer."
+  (interactive)
+  (inferior-octave t)
+  (let ((standard-output (current-buffer))
+	(print-escape-newlines nil)
+	(opoint (point)))
+    (terpri)
+    (prin1
+     (save-excursion
+       (forward-sexp -1)
+       (inferior-octave-send-list-and-digest
+	(list (concat (buffer-substring-no-properties (point) opoint)
+		      "\n")))
+       (mapconcat 'identity inferior-octave-output-list "\n")))
+    (terpri)))
+
+;;; Bug reporting
+(defun octave-submit-bug-report ()
+  "Submit a bug report on the Emacs Octave package via mail."
+  (interactive)
+  (require 'reporter)
+  (and
+   (y-or-n-p "Do you want to submit a bug report? ")
+   (reporter-submit-bug-report
+    octave-maintainer-address
+    (concat "Emacs version " emacs-version)
+    (list
+     'octave-auto-indent
+     'octave-auto-newline
+     'octave-blink-matching-block
+     'octave-block-offset
+     'octave-comment-char
+     'octave-continuation-offset
+     'octave-continuation-string
+     'octave-help-files
+     'octave-send-echo-input
+     'octave-send-line-auto-forward
+     'octave-send-show-buffer))))
+
+;;; provide ourself
+
+(provide 'octave-mod)
+
+;; arch-tag: 05f1ce09-be87-4c00-803e-4919ffa26c23
+;;; octave-mod.el ends here
diff --git a/emacs/octave-tags b/emacs/octave-tags
new file mode 100644
index 0000000..de36b23
--- /dev/null
+++ b/emacs/octave-tags
@@ -0,0 +1,47 @@
+#! /bin/sh
+#
+# Copyright (C) 1998, 2002, 2003, 2006, 2007 Mario Storti
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Author: Mario Storti <mstorti at minerva.unl.edu.ar>
+
+# Generate a TAGS file from a set of Octave .m files for use with Emacs.
+#
+# Run as '$ octave-tags' in the given Octave directory to generate a
+# TAGS file.  If you want to include another directory, add a line
+# prior to the "*.m" line containing something like
+#  `--include=/path/to/other/directory/TAGS" \'.
+
+# Tags are generated for function names and for global variables. For
+# global variables it doesn't work for more than one line global
+# variables.  :-(
+
+# Tags are also created for lines of the form '###key foobar' so that
+# you can jump to this specific place just by typing `M-. foobar'.
+# Note that tags are not generated for scripts so that you have to add
+# a line by yourself of the form `###key <script-name>' if you want to
+# jump to it.  :-(
+
+etags --lang=none \
+      --regex='/[ \t]*function.*=[ \t]*\([^ \t()]*\)[ \t]*(/\1/' \
+      --regex='/[ \t]*function.*=[ \t]*\([^ \t()]*\)[ \t]*$/\1/' \
+      --regex='/[ \t]*function[ \t]*\([^ \t()]*\)[ \t]*(/\1/' \
+      --regex='/[ \t]*function[ \t]*\([^ \t()]*\)[ \t]*$/\1/' \
+      --regex='/###key \(.*\)/\1/' \
+      --regex='/[ \t]*global[ \t].*/' \
+      *.m
diff --git a/emacs/octave-tags.1 b/emacs/octave-tags.1
new file mode 100644
index 0000000..2863dc2
--- /dev/null
+++ b/emacs/octave-tags.1
@@ -0,0 +1,64 @@
+.\" Copyright (C) 2003, 2006, 2007 Dirk Eddelbuettel
+.\"
+.\" This file is part of Octave.
+.\"
+.\" Octave is free software; you can redistribute it and/or modify it
+.\" under the terms of the GNU General Public License as published by the
+.\" Free Software Foundation; either version 3 of the License, or (at
+.\" your option) any later version.
+.\"
+.\" Octave is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+.\" for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with Octave; see the file COPYING.  If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.\" This page was contributed by Dirk Eddelbuettel <edd at debian.org>
+.\" 
+.TH OCTAVE-TAGS 1 "31 October 2001" "GNU Octave"
+.SH NAME
+OCTAVE-TAGS - Generate Emacs tags file from GNU Octave code
+.SH SYNOPSIS
+.BR octave-tags\  [--include\ dir]
+\fIfile\fP .\|.\|.  
+.SH DESCRIPTION
+.PP
+.B octave-tags
+program is used to create a tag table file, in a format understood by 
+.BR emacs (1)
+and
+.BR xemacs (1).
+.B octave-tags
+reads the files specified on the command line, and write a tag table  
+(defaults: `TAGS') in the current working directory. Files specified with
+relative file names will be  recorded in the tag table with file names
+relative to the directory where the tag table resides.  Files specified  with
+absolute file names will be recorded with absolute file names.
+
+The 
+.I --include
+option can be used to specify another directoy with Octave files for which
+tags shall be generated.
+ 
+Tags are generated for function names and for global variables. For
+global variables it doesn't work for more than one line global
+variables.  
+ 
+Tags are also created for lines of the form '###key foobar' so that
+you can jump to this specific place just by typing `M-. foobar'.
+Note that tags are not generated for scripts so that you have to add
+a line by yourself of the form `###key <script-name>' if you want to
+jump to it.  
+
+.SH SEE ALSO
+.BR etags (1).
+
+.SH AUTHORS
+Mario Storti <mstorti at minerva.unl.edu.ar>
+
+This manual page was contributed by Dirk Eddelbuettel
+<edd at debian.org> for the Debian GNU/Linux distribution but 
+may be used by others.
diff --git a/examples/@FIRfilter/FIRfilter.m b/examples/@FIRfilter/FIRfilter.m
new file mode 100644
index 0000000..484feee
--- /dev/null
+++ b/examples/@FIRfilter/FIRfilter.m
@@ -0,0 +1,22 @@
+## -*- texinfo -*-
+## @deftypefn {Function File} {} FIRfilter ()
+## @deftypefnx {Function File} {} FIRfilter (@var{p})
+## Creates an FIR filter with polynomial @var{p} as
+## coefficient vector.
+##
+## @end deftypefn
+
+function f = FIRfilter (p)
+
+  f.polynomial = [];
+  if (nargin == 0)
+    p = @polynomial ([1]);
+  elseif (nargin == 1)
+    if (!isa (p, "polynomial"))
+      error ("FIRfilter: expecting polynomial as input argument");
+    endif
+  else
+    print_usage ();
+  endif
+  f = class (f, "FIRfilter", p);
+endfunction
diff --git a/examples/@FIRfilter/FIRfilter_aggregation.m b/examples/@FIRfilter/FIRfilter_aggregation.m
new file mode 100644
index 0000000..d6b4951
--- /dev/null
+++ b/examples/@FIRfilter/FIRfilter_aggregation.m
@@ -0,0 +1,23 @@
+## -*- texinfo -*-
+## @deftypefn {Function File} {} FIRfilter ()
+## @deftypefnx {Function File} {} FIRfilter (@var{p})
+## Creates an FIR filter with polynomial @var{p} as
+## coefficient vector.
+##
+## @end deftypefn
+
+function f = FIRfilter (p)
+
+  if (nargin == 0)
+    f.polynomial = @polynomial ([1]);
+  elseif (nargin == 1)
+    if (isa (p, "polynomial"))
+      f.polynomial = p;
+    else
+      error ("FIRfilter: expecting polynomial as input argument");
+    endif
+  else
+    print_usage ();
+  endif
+  f = class (f, "FIRfilter");
+endfunction
diff --git a/examples/@FIRfilter/Makefile.in b/examples/@FIRfilter/Makefile.in
new file mode 100644
index 0000000..222d51c
--- /dev/null
+++ b/examples/@FIRfilter/Makefile.in
@@ -0,0 +1,95 @@
+# Makefile for octave's scripts/geometry directory
+#
+# Copyright (C) 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = @FIRfilter
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+define do-mkpkgadd
+$(top_srcdir)/scripts/mkpkgadd $(srcdir) > PKG_ADD.t
+if [ -n "`cat PKG_ADD.t`" ]; then \
+  mv PKG_ADD.t PKG_ADD ; \
+else \
+  rm -f PKG_ADD.t ; \
+fi
+endef
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = \
+  display.m \
+  FIRfilter_aggregation.m \
+  FIRfilter.m \
+  subsasgn.m \
+  subsref.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+.PHONY: install install-strip
+
+uninstall:
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/examples/$(script_sub_dir)
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/examples/@FIRfilter/display.m b/examples/@FIRfilter/display.m
new file mode 100644
index 0000000..f614286
--- /dev/null
+++ b/examples/@FIRfilter/display.m
@@ -0,0 +1,6 @@
+function display (f)
+
+  display(f.polynomial);
+
+endfunction
+
diff --git a/examples/@FIRfilter/subsasgn.m b/examples/@FIRfilter/subsasgn.m
new file mode 100644
index 0000000..8fc23cd
--- /dev/null
+++ b/examples/@FIRfilter/subsasgn.m
@@ -0,0 +1,14 @@
+function out = subsasgn (f, index, val)
+  switch (index.type)
+    case "."
+      fld = index.subs;
+      if (strcmp (fld, "polynomial"))
+        out = f;
+        out.polynomial = val;
+      else
+        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("FIRfilter/subsagn: Invalid index type")
+  endswitch
+endfunction
diff --git a/examples/@FIRfilter/subsref.m b/examples/@FIRfilter/subsref.m
new file mode 100644
index 0000000..5df9971
--- /dev/null
+++ b/examples/@FIRfilter/subsref.m
@@ -0,0 +1,16 @@
+function out = subsref (f, x)
+  switch x.type
+    case "()"
+      n = f.polynomial;
+      out = filter(n.poly, 1, x.subs{1});
+    case "."
+      fld = x.subs;
+      if (strcmp (fld, "polynomial"))
+        out = f.polynomial;
+      else
+        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("@FIRfilter/subsref: invalid subscript type for FIR filter");
+  endswitch
+endfunction
diff --git a/examples/@polynomial/Makefile.in b/examples/@polynomial/Makefile.in
new file mode 100644
index 0000000..7ccb6e9
--- /dev/null
+++ b/examples/@polynomial/Makefile.in
@@ -0,0 +1,103 @@
+# Makefile for octave's scripts/geometry directory
+#
+# Copyright (C) 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = @polynomial
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+define do-mkpkgadd
+$(top_srcdir)/scripts/mkpkgadd $(srcdir) > PKG_ADD.t
+if [ -n "`cat PKG_ADD.t`" ]; then \
+  mv PKG_ADD.t PKG_ADD ; \
+else \
+  rm -f PKG_ADD.t ; \
+fi
+endef
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = \
+  display.m \
+  double.m \
+  end.m \
+  get.m \
+  mtimes.m \
+  plot.m \
+  polynomial.m \
+  polynomial_superiorto.m \
+  polyval.m \
+  roots.m \
+  set.m \
+  subsasgn.m \
+  subsref.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+.PHONY: install install-strip
+
+uninstall:
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/examples/$(script_sub_dir)
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/examples/@polynomial/display.m b/examples/@polynomial/display.m
new file mode 100644
index 0000000..a0ae075
--- /dev/null
+++ b/examples/@polynomial/display.m
@@ -0,0 +1,32 @@
+function display (p)
+  a = p.poly;
+  first = true;
+  fprintf("%s =", inputname(1));
+  for i = 1 : length (a);
+    if (a(i) != 0)
+      if (first)
+        first = false;
+      elseif (a(i) > 0)
+        fprintf (" +");
+      endif
+      if (a(i) < 0)
+        fprintf (" -");
+      endif
+      if (i == 1)
+        fprintf (" %g", abs (a(i)));
+      elseif (abs(a(i)) != 1)
+        fprintf (" %g *", abs (a(i)));
+      endif
+      if (i > 1)
+        fprintf (" X");
+      endif
+      if (i > 2)
+        fprintf (" ^ %d", i - 1);
+      endif
+    endif
+  endfor
+  if (first)
+    fprintf(" 0");
+  endif
+  fprintf("\n");
+endfunction
diff --git a/examples/@polynomial/double.m b/examples/@polynomial/double.m
new file mode 100644
index 0000000..b024af7
--- /dev/null
+++ b/examples/@polynomial/double.m
@@ -0,0 +1,3 @@
+function b = double (a)
+  b = a.poly;
+endfunction
diff --git a/examples/@polynomial/end.m b/examples/@polynomial/end.m
new file mode 100644
index 0000000..1b8d715
--- /dev/null
+++ b/examples/@polynomial/end.m
@@ -0,0 +1,9 @@
+function r = end (obj, index_pos, num_indices)
+
+  if (num_indices != 1)
+    error ("polynomial object may only have one index")
+  endif
+  
+  r = length (obj.poly) - 1;
+
+endfunction
diff --git a/examples/@polynomial/get.m b/examples/@polynomial/get.m
new file mode 100644
index 0000000..748e704
--- /dev/null
+++ b/examples/@polynomial/get.m
@@ -0,0 +1,18 @@
+function s = get (p, f)
+  if (nargin == 1)
+    s.poly = p.poly;
+  elseif (nargin == 2)
+    if (ischar (f))
+      switch (f)
+        case "poly"
+          s = p.poly;
+        otherwise
+          error ("get: invalid property %s", f);
+      endswitch
+    else
+      error ("get: expecting the property to be a string");
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
diff --git a/examples/@polynomial/mtimes.m b/examples/@polynomial/mtimes.m
new file mode 100644
index 0000000..7fefe13
--- /dev/null
+++ b/examples/@polynomial/mtimes.m
@@ -0,0 +1,3 @@
+function y = mtimes (a, b)
+  y = polynomial (conv (double(a),double(b)));
+endfunction
\ No newline at end of file
diff --git a/examples/@polynomial/plot.m b/examples/@polynomial/plot.m
new file mode 100644
index 0000000..c28eaee
--- /dev/null
+++ b/examples/@polynomial/plot.m
@@ -0,0 +1,10 @@
+function h = plot(p, varargin)
+  n = 128;
+  rmax = max (abs (roots (p.poly)));
+  x = [0 : (n - 1)] / (n - 1) * 2.2 * rmax - 1.1 * rmax;
+  if (nargout > 0)
+    h = plot(x, p(x), varargin{:});
+  else
+    plot(x, p(x), varargin{:});
+  endif
+endfunction
\ No newline at end of file
diff --git a/examples/@polynomial/polynomial.m b/examples/@polynomial/polynomial.m
new file mode 100644
index 0000000..31e6f24
--- /dev/null
+++ b/examples/@polynomial/polynomial.m
@@ -0,0 +1,29 @@
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polynomial ()
+## @deftypefnx {Function File} {} polynomial (@var{a})
+## Creates a polynomial object representing the polynomial
+##
+## @example
+## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+## @end example
+##
+## from a vector of coefficients [a0 a1 a2 ... an].
+## @end deftypefn
+
+function p = polynomial (a)
+  if (nargin == 0)
+    p.poly = [0];
+    p = class (p, "polynomial");
+  elseif (nargin == 1)
+    if (strcmp (class (a), "polynomial"))
+      p = a;
+    elseif (isvector (a) && isreal (a))
+      p.poly = a(:).';
+      p = class (p, "polynomial");
+    else
+      error ("polynomial: expecting real vector");
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
diff --git a/examples/@polynomial/polynomial_superiorto.m b/examples/@polynomial/polynomial_superiorto.m
new file mode 100644
index 0000000..68febae
--- /dev/null
+++ b/examples/@polynomial/polynomial_superiorto.m
@@ -0,0 +1,30 @@
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polynomial ()
+## @deftypefnx {Function File} {} polynomial (@var{a})
+## Creates a polynomial object representing the polynomial
+##
+## @example
+## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+## @end example
+##
+## from a vector of coefficients [a0 a1 a2 ... an].
+## @end deftypefn
+
+function p = polynomial (a)
+  if (nargin == 0)
+    p.poly = [0];
+    p = class (p, "polynomial");
+  elseif (nargin == 1)
+    if (strcmp (class (a), "polynomial"))
+      p = a;
+    elseif (isvector (a) && isreal (a))
+      p.poly = a(:).';
+      p = class (p, "polynomial");
+    else
+      error ("polynomial: expecting real vector");
+    endif
+  else
+    print_usage ();
+  endif
+  superiorto ("double");
+endfunction
diff --git a/examples/@polynomial/polyval.m b/examples/@polynomial/polyval.m
new file mode 100644
index 0000000..0fb36b4
--- /dev/null
+++ b/examples/@polynomial/polyval.m
@@ -0,0 +1,7 @@
+function [y, dy] = polyval (p, varargin)
+  if (nargout == 2)
+    [y, dy] = polyval (fliplr(p.poly), varargin{:});
+  else
+    y = polyval (fliplr(p.poly), varargin{:});
+  endif
+endfunction
diff --git a/examples/@polynomial/roots.m b/examples/@polynomial/roots.m
new file mode 100644
index 0000000..fbec007
--- /dev/null
+++ b/examples/@polynomial/roots.m
@@ -0,0 +1,3 @@
+function y = roots (p)
+  y = roots(fliplr(p.poly));
+endfunction
\ No newline at end of file
diff --git a/examples/@polynomial/set.m b/examples/@polynomial/set.m
new file mode 100644
index 0000000..a86542e
--- /dev/null
+++ b/examples/@polynomial/set.m
@@ -0,0 +1,20 @@
+function s = set (p, varargin)
+  s = p;
+  if (length (varargin) < 2 || rem (length (varargin), 2) != 0)
+    error ("set: expecting property/value pairs");
+  endif
+  while (length (varargin) > 1)
+    prop = varargin{1};
+    val = varargin{2};
+    varargin(1:2) = [];
+    if (ischar (prop) && strcmp (prop, "poly"))
+      if (isvector (val) && isreal (val))
+        s.poly = val(:).';
+      else
+        error ("set: expecting the value to be a real vector");
+      endif
+    else
+      error ("set: invalid property of polynomial class");
+    endif
+  endwhile
+endfunction
diff --git a/examples/@polynomial/subsasgn.m b/examples/@polynomial/subsasgn.m
new file mode 100644
index 0000000..a4ff404
--- /dev/null
+++ b/examples/@polynomial/subsasgn.m
@@ -0,0 +1,35 @@
+function p = subsasgn (p, s, val)
+  if (length (s) < 1)
+    error ("polynomial: needs index");
+  endif
+  switch (s(1).type)
+    case "{}"
+      ind = s(1).subs;
+      if (numel (ind) != 1)
+        error ("polynomial: need exactly one index");
+      else
+        if (length (s) == 1)
+          if (isnumeric (ind{1}))
+            p.poly(ind{1}+1) = val; 
+          else
+            p.poly(ind{1}) = val;
+          endif
+        else
+          error ("polynomial: chained subscripts not allowed for {}");
+        endif
+      endif
+    case "."
+      fld = s(1).subs;
+      if (strcmp (fld, "poly"))
+        if (length (s) == 1)
+          p.poly = val;
+        else
+          p.poly = subsasgn (p.poly, s(2:end), val);
+        endif
+      else
+        error ("@polynomial/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("invalid subscript type");
+  endswitch
+endfunction
diff --git a/examples/@polynomial/subsref.m b/examples/@polynomial/subsref.m
new file mode 100644
index 0000000..8a9045f
--- /dev/null
+++ b/examples/@polynomial/subsref.m
@@ -0,0 +1,37 @@
+function b = subsref (a, s)
+  if (isempty (s))
+    error ("polynomial: missing index");
+  endif
+  switch (s(1).type)
+    case "()"
+      ind = s(1).subs;
+      if (numel (ind) != 1)
+        error ("polynomial: need exactly one index");
+      else
+        b = polyval (fliplr (a.poly), ind{1});
+      endif
+    case "{}"
+      ind = s(1).subs;
+      if (numel (ind) != 1)
+        error ("polynomial: need exactly one index");
+      else
+        if (isnumeric (ind{1}))
+          b = a.poly(ind{1}+1);
+        else
+          b = a.poly(ind{1});
+        endif
+      endif
+    case "."
+      fld = s.subs;
+      if (strcmp (fld, "poly"))
+        b = a.poly;
+      else
+        error ("@polynomial/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("invalid subscript type");
+  endswitch
+  if (numel (s) > 1)
+    b = subsref (b, s(2:end));
+  endif
+endfunction
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..cbdbce0
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,142 @@
+# Makefile for octave's examples directory
+#
+# Copyright (C) 1996, 1997, 2003, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_DATA = @INSTALL_DATA@
+
+SUBDIRS = @polynomial @FIRfilter
+
+DISTSUBDIRS = $(SUBDIRS)
+
+SCRIPTS = info-emacs-info info-emacs-octave-help
+
+SOURCES = \
+  addtwomatrices.cc \
+  celldemo.cc \
+  embedded.cc \
+  firstmexdemo.c \
+  fortdemo.cc \
+  fortsub.f \
+  funcdemo.cc \
+  globaldemo.cc \
+  hello.cc \
+  helloworld.cc \
+  make_int.cc \
+  mycell.c \
+  myfeval.c \
+  myfevalf.f \
+  myfunc.c \
+  myhello.c \
+  mypow2.c \
+  myprop.c \
+  myset.c \
+  mysparse.c \
+  mystring.c \
+  mystruct.c \
+  octave.desktop.in \
+  oregonator.cc \
+  oregonator.m \
+  paramdemo.cc \
+  standalone.cc \
+  stringdemo.cc \
+  structdemo.cc \
+  unwinddemo.cc
+
+IMAGE_FILES = $(srcdir)/octave-sombrero.png
+IMAGE_FILES_NO_DIR = $(notdir $(IMAGE_FILES))
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES) $(SCRIPTS)) \
+	 $(IMAGE_FILES)
+
+all: $(SUBDIRS) octave.desktop
+.PHONY: all
+
+$(SUBDIRS):
+	$(MAKE) -C $@ all
+.PHONY: $(SUBDIRS)
+
+octave.desktop: octave.desktop.in Makefile ../Makeconf
+	echo "making $@ from $<"
+	$(SED) < $< > $@-t \
+	  -e "s|%OCTAVE_IMAGEDIR%|${imagedir}|" \
+	  -e "s|%OCTAVE_PREFIX%|${prefix}|"
+	mv $@-t $@
+
+install install-strip:
+	for f in $(SCRIPTS); do \
+	  $(INSTALL_SCRIPT) $(srcdir)/$$f $(DESTDIR)$(archlibdir)/$$f; \
+	done
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(imagedir)
+	for f in $(IMAGE_FILES_NO_DIR); do \
+	  rm -f $(DESTDIR)$(imagedir)/$$f; \
+	  $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(imagedir)/$$f; \
+	done
+	-if test -n "$(DESKTOP_FILE_INSTALL)"; then \
+	  $(DESKTOP_FILE_INSTALL) --dir=$(DESTDIR)$(datadir)/applications \
+	    --vendor www.octave.org octave.desktop; \
+	fi
+.PHONY: install install-strip
+
+uninstall:
+	for f in $(SCRIPTS); do \
+	  rm -f $(DESTDIR)$(archlibdir)/$$f; \
+	done
+	for f in $(IMAGE_FILES_NO_DIR); do \
+	  rm -f $(DESTDIR)$(imagedir)/$$f; \
+	done
+	if test -n "$(DESKTOP_FILE_INSTALL)"; then \
+	  rm -f $(DESTDIR)$(datadir)/applications/www.octave.org-octave.desktop; \
+	fi
+.PHONY: uninstall
+
+tags:
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+clean mostlyclean:
+.PHONY: clean mostlyclean
+
+distclean::
+	rm -f Makefile octave.desktop
+.PHONY: distclean
+
+maintainer-clean:: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+distclean maintainer-clean::
+	@$(subdir-for-command)
+
+dist:
+	ln $(DISTFILES) ../`cat ../.fname`/examples
+	for dir in $(DISTSUBDIRS); do mkdir ../`cat ../.fname`/examples/$$dir; $(MAKE) -C $$dir $@; done
+.PHONY: dist
diff --git a/examples/addtwomatrices.cc b/examples/addtwomatrices.cc
new file mode 100644
index 0000000..1774eb0
--- /dev/null
+++ b/examples/addtwomatrices.cc
@@ -0,0 +1,16 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (addtwomatrices, args, , "Add A to B")
+{
+  int nargin = args.length ();
+  if (nargin != 2)
+    print_usage ();
+  else
+    {
+      NDArray A = args(0).array_value ();
+      NDArray B = args(1).array_value ();
+      if (! error_state)
+        return octave_value (A + B);
+    }
+  return octave_value_list ();
+}
diff --git a/examples/celldemo.cc b/examples/celldemo.cc
new file mode 100644
index 0000000..332076f
--- /dev/null
+++ b/examples/celldemo.cc
@@ -0,0 +1,20 @@
+#include <octave/oct.h>
+#include <octave/Cell.h>
+
+DEFUN_DLD (celldemo, args, , "Cell Demo") 
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      Cell c = args (0).cell_value ();
+      if (! error_state)
+        for (octave_idx_type i = 0; i < c.nelem (); i++)
+          retval(i) = c.elem (i);
+    }
+
+  return retval;
+}
diff --git a/examples/embedded.cc b/examples/embedded.cc
new file mode 100644
index 0000000..84d164d
--- /dev/null
+++ b/examples/embedded.cc
@@ -0,0 +1,44 @@
+#include <iostream>
+#include <octave/oct.h>
+#include <octave/octave.h>
+#include <octave/parse.h>
+
+int
+main (void)
+{
+  string_vector argv (2);
+  argv(0) = "embedded";
+  argv(1) = "-q";
+
+  octave_main (2, argv.c_str_vec(), 1);
+
+  octave_idx_type n = 2;
+  Matrix a_matrix = Matrix (1, 2);
+
+  std::cout << "GCD of [";
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      a_matrix (i) = 5 * (i + 1); 
+      if (i != 0)
+	std::cout << ", " << 5 * (i + 2);
+      else
+	std::cout << 5 * (i + 2);
+    }
+  std::cout << "] is ";
+
+  octave_value_list in = octave_value (a_matrix);
+  octave_value_list out = feval ("gcd", in, 1);
+
+  if (!error_state && out.length () > 0)
+    {
+      a_matrix = out(0).matrix_value ();
+      if (a_matrix.numel () == 1)
+	std::cout << a_matrix(0) << "\n";
+      else
+	std::cout << "invalid\n";
+    }
+  else
+    std::cout << "invalid\n";
+
+  return 0;
+}
diff --git a/examples/firstmexdemo.c b/examples/firstmexdemo.c
new file mode 100644
index 0000000..3cff66a
--- /dev/null
+++ b/examples/firstmexdemo.c
@@ -0,0 +1,11 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+	     const mxArray *prhs[])
+{
+  mxArray *v = mxCreateDoubleMatrix (1, 1, mxREAL);
+  double *data = mxGetPr (v);
+  *data = 1.23456789;
+  plhs[0] = v;
+}
diff --git a/examples/fortdemo.cc b/examples/fortdemo.cc
new file mode 100644
index 0000000..1a11a1f
--- /dev/null
+++ b/examples/fortdemo.cc
@@ -0,0 +1,35 @@
+#include <octave/oct.h>
+#include <octave/f77-fcn.h>
+
+extern "C" 
+{
+  F77_RET_T 
+  F77_FUNC (fortsub, FORTSUB) 
+        (const int&, double*, F77_CHAR_ARG_DECL  
+         F77_CHAR_ARG_LEN_DECL);
+}
+
+DEFUN_DLD (fortdemo , args , , "Fortran Demo.")
+{
+  octave_value_list retval;  
+  int nargin = args.length();
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      NDArray a = args(0).array_value ();
+      if (! error_state)
+        {
+          double *av = a.fortran_vec ();
+          octave_idx_type na = a.nelem ();
+          OCTAVE_LOCAL_BUFFER (char, ctmp, 128);
+
+          F77_XFCN (fortsub, FORTSUB, (na, av, ctmp 
+                    F77_CHAR_ARG_LEN (128)));
+
+	  retval(1) = std::string (ctmp);
+	  retval(0) = a;
+        }
+    }
+  return retval;
+}
diff --git a/examples/fortsub.f b/examples/fortsub.f
new file mode 100644
index 0000000..37ac8aa
--- /dev/null
+++ b/examples/fortsub.f
@@ -0,0 +1,21 @@
+      subroutine fortsub (n, a, s)
+      implicit none
+      character*(*) s
+      real*8 a(*)
+      integer*4 i, n, ioerr
+      do i = 1, n
+        if (a(i) .eq. 0d0) then
+          call xstopx ('fortsub: divide by zero')
+        else
+          a(i) = 1d0 / a(i)
+        endif
+      enddo
+      write (unit = s, fmt = '(a,i3,a,a)', iostat = ioerr)
+     $       'There are ', n,
+     $       ' values in the input vector', char(0)
+      if (ioerr .ne. 0) then
+        call xstopx ('fortsub: error writing string')
+      endif
+      return
+      end
+
diff --git a/examples/funcdemo.cc b/examples/funcdemo.cc
new file mode 100644
index 0000000..9ee8199
--- /dev/null
+++ b/examples/funcdemo.cc
@@ -0,0 +1,34 @@
+#include <octave/oct.h>
+#include <octave/parse.h>
+
+DEFUN_DLD (funcdemo, args, nargout, "Function Demo")
+{
+  int nargin = args.length();
+  octave_value_list retval;
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    {
+      octave_value_list newargs;
+      for (octave_idx_type i = nargin - 1; i > 0; i--)
+        newargs (i - 1) = args(i);
+      if (args(0).is_function_handle ()
+          || args(0).is_inline_function ())
+        {
+          octave_function *fcn = args(0).function_value ();
+          if (! error_state)
+            retval = feval (fcn, newargs, nargout);
+        }
+      else if (args(0).is_string ())
+        {
+          std::string fcn = args (0).string_value ();
+          if (! error_state)
+            retval = feval (fcn, newargs, nargout);
+        }
+      else
+        error ("funcdemo: expected string,",
+	       " inline or function handle");
+    }
+  return retval;
+}
diff --git a/examples/globaldemo.cc b/examples/globaldemo.cc
new file mode 100644
index 0000000..3a7fb32
--- /dev/null
+++ b/examples/globaldemo.cc
@@ -0,0 +1,25 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (globaldemo, args, , "Global demo.")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      std::string s = args(0).string_value ();
+      if (! error_state)
+        {
+          octave_value tmp = get_global_value (s, true);
+          if (tmp.is_defined ())
+            retval = tmp;
+          else
+            retval = "Global variable not found";
+
+          set_global_value ("a", 42.0);
+        }
+    }
+  return retval;
+}
diff --git a/examples/hello.cc b/examples/hello.cc
new file mode 100644
index 0000000..e17ffd3
--- /dev/null
+++ b/examples/hello.cc
@@ -0,0 +1,98 @@
+// hello.cc -- example of a dynamically linked function for Octave.
+
+// To use this file, your version of Octave must support dynamic
+// linking.  To find out if it does, type the command
+//
+//   octave_config_info ("ENABLE_DYNAMIC_LINKING")
+//
+// at the Octave prompt.  Support for dynamic linking is included if
+// this expression returns the string "true".
+//
+// To compile this file, type the command
+//
+//   mkoctfile hello.cc
+//
+// at the shell prompt.  The script mkoctfile should have been
+// installed along with Octave.  Running it will create a file called
+// hello.oct that can be loaded by Octave.  To test the hello.oct
+// file, start Octave and type the command
+//
+//   hello ("easy as", 1, 2, 3)
+//
+// at the Octave prompt.  Octave should respond by printing
+//
+//   Hello, world!
+//   easy as
+//   1
+//   2
+//   3
+//   ans = 3
+
+// Additional examples are available in the files in the src directory
+// of the Octave distribution that use the macro DEFUN_DLD_BUILTIN.
+// Currently, this includes the files
+//
+//   balance.cc  fft.cc      ifft.cc     minmax.cc   sort.cc
+//   chol.cc	 fft2.cc     ifft2.cc    pinv.cc     svd.cc
+//   colloc.cc   filter.cc   inv.cc      qr.cc       syl.cc
+//   dassl.cc    find.cc     log.cc      quad.cc
+//   det.cc	 fsolve.cc   lsode.cc    qzval.cc
+//   eig.cc	 givens.cc   lu.cc       rand.cc
+//   expm.cc	 hess.cc     minmax.cc   schur.cc
+//
+// The difference between DEFUN_DLD and DEFUN_DLD_BUILTIN is that
+// DEFUN_DLD_BUILTIN can define a built-in function that is not
+// dynamically loaded if the operating system does not support dynamic
+// linking.  To define your own dynamically linked functions you
+// should use DEFUN_DLD.
+
+#include <octave/config.h>
+
+#include <iostream>
+
+#include <octave/defun-dld.h>
+#include <octave/error.h>
+#include <octave/oct-obj.h>
+#include <octave/pager.h>
+#include <octave/symtab.h>
+#include <octave/variables.h>
+
+// DEFUN_DLD and the macros that it depends on are defined in the
+// files defun-dld.h, defun.h, and defun-int.h.
+
+// Note that the third parameter (nargout) is not used, so it is
+// omitted from the list of arguments to DEFUN_DLD in order to avoid
+// the warning from gcc about an unused function parameter. 
+
+DEFUN_DLD (hello, args, ,
+  "[...] = hello (...)\n\
+\n\
+Print greeting followed by the values of all the arguments passed.\n\
+Returns all arguments in reverse order.")
+{
+  // The list of values to return.  See the declaration in oct-obj.h
+
+  octave_value_list retval;
+
+  // This stream is normally connected to the pager.
+
+  octave_stdout << "Hello, world!\n";
+
+  // The arguments to this function are available in args.
+
+  int nargin = args.length ();
+
+  // The octave_value_list class is a zero-based array of octave_value
+  // objects.  The declaration for the octave_value class is in the
+  // file ov.h.  The print() method will send its output to
+  // octave_stdout, so it will also end up going through the pager.
+
+  for (int i = 0; i < nargin; i++)
+    {
+      octave_value tmp = args (i);
+      tmp.print (octave_stdout);
+      retval (nargin-i-1) = tmp;
+    }
+
+  return retval;
+}
diff --git a/examples/helloworld.cc b/examples/helloworld.cc
new file mode 100644
index 0000000..61d66ed
--- /dev/null
+++ b/examples/helloworld.cc
@@ -0,0 +1,11 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (helloworld, args, nargout,
+  "Hello World Help String")
+{
+  int nargin = args.length ();
+  octave_stdout << "Hello World has " << nargin 
+        << " input arguments and "
+        << nargout << " output arguments.\n";
+  return octave_value_list ();
+}
diff --git a/examples/info-emacs-info b/examples/info-emacs-info
new file mode 100755
index 0000000..b026fa0
--- /dev/null
+++ b/examples/info-emacs-info
@@ -0,0 +1,34 @@
+#! /bin/sh
+# info-emacs-info
+#
+# Copyright (C) 1996, 2005, 2007 Kurt Hornik
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Written by Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 1996/07/01
+
+# Make Octave's `help -i' use Emacs info.
+# Requires a running Emacs and gnuserv.
+cmd="(Info-find-node \"$2\" \"Top\")"
+if [ $3 = "--directory" ];
+then
+	cmd="(add-to-list 'Info-directory-list \"$4\") $cmd"
+	shift 2
+fi
+cmd="(require 'info) $cmd"
+[ $4 ] && cmd="$cmd (Info-index \"$4\")"
+gnuclient -batch -q -eval "$cmd"
diff --git a/examples/info-emacs-octave-help b/examples/info-emacs-octave-help
new file mode 100755
index 0000000..0575b6b
--- /dev/null
+++ b/examples/info-emacs-octave-help
@@ -0,0 +1,35 @@
+#! /bin/sh
+# info-emacs-octave-help
+#
+# Copyright (C) 1996, 1997, 2005, 2007 Kurt Hornik
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Written by KH <Kurt.Hornik at wu-wien.ac.at> on 1996/07/01
+# Updated by KH on 1997/03/04
+
+# Make Octave's `help -i' use Emacs octave-help.
+# Requires a running Emacs and gnuserv.
+
+cmd="(require 'octave-hlp)"
+if [ $3 = "--directory" ];
+then
+    cmd="$cmd (add-to-list 'Info-directory-list \"$4\")"
+    shift 2
+fi
+cmd="$cmd (octave-help \"$4\")"
+gnuclient -batch -q -eval "$cmd"
diff --git a/examples/make_int.cc b/examples/make_int.cc
new file mode 100644
index 0000000..df7b4db
--- /dev/null
+++ b/examples/make_int.cc
@@ -0,0 +1,323 @@
+#include <octave/config.h>
+
+#include <cstdlib>
+
+#include <string>
+
+#include <ostream>
+
+#include <octave/lo-mappers.h>
+#include <octave/lo-utils.h>
+#include <octave/mx-base.h>
+#include <octave/str-vec.h>
+
+#include <octave/defun-dld.h>
+#include <octave/error.h>
+#include <octave/gripes.h>
+#include <octave/oct-obj.h>
+#include <octave/ops.h>
+#include <octave/ov-base.h>
+#include <octave/ov-typeinfo.h>
+#include <octave/ov.h>
+#include <octave/ov-scalar.h>
+#include <octave/pager.h>
+#include <octave/pr-output.h>
+#include <octave/symtab.h>
+#include <octave/variables.h>
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Integer values.
+
+class
+octave_integer : public octave_base_value
+{
+public:
+
+  octave_integer (void)
+    : octave_base_value (), scalar (0) { }
+
+  octave_integer (int i)
+    : octave_base_value (), scalar (i) { }
+
+  octave_integer (const octave_integer& s)
+    : octave_base_value (), scalar (s.scalar) { }
+
+  ~octave_integer (void) { }
+
+  octave_base_value *clone (void) { return new octave_integer (*this); }
+
+#if 0
+  void *operator new (size_t size);
+  void operator delete (void *p, size_t size);
+#endif
+
+  idx_vector index_vector (void) const { return idx_vector ((double) scalar); }
+
+  int rows (void) const { return 1; }
+  int columns (void) const { return 1; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+  bool is_real_scalar (void) const { return true; }
+
+  octave_value all (void) const { return (double) (scalar != 0); }
+  octave_value any (void) const { return (double) (scalar != 0); }
+
+  bool is_real_type (void) const { return true; }
+  bool is_scalar_type (void) const { return true; }
+  bool is_numeric_type (void) const { return true; }
+
+  bool valid_as_scalar_index (void) const
+    { return scalar == 1; }
+
+  bool valid_as_zero_index (void) const
+    { return scalar == 0; }
+
+  bool is_true (void) const { return (scalar != 0); }
+
+  double double_value (bool = false) const { return (double) scalar; }
+
+  int integer_value (bool = false) const { return scalar; }
+
+  Matrix matrix_value (bool = false) const { return Matrix (1, 1, scalar); }
+
+  Complex complex_value (bool = false) const { return scalar; }
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return  ComplexMatrix (1, 1, Complex (scalar)); }
+
+  octave_value gnot (void) const { return octave_value ((double) ! scalar); }
+
+  octave_value uminus (void) const { return new octave_integer (- scalar); }
+
+  octave_value transpose (void) const { return new octave_integer (scalar); }
+
+  octave_value hermitian (void) const { return new octave_integer (scalar); }
+
+  void increment (void) { ++scalar; }
+
+  void decrement (void) { --scalar; }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+private:
+
+  int scalar;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+void
+octave_integer::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  os << scalar;
+  // octave_print_internal (os, scalar, pr_as_read_syntax);
+}
+
+#ifdef DEFUNOP_OP
+#undef DEFUNOP_OP
+#endif
+
+#define DEFUNOP_OP(name, t, op) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## t&); \
+    return octave_value (new octave_integer (op v.t ## _value ())); \
+  }
+
+DEFUNOP_OP (gnot, integer, !)
+DEFUNOP_OP (uminus, integer, -)
+DEFUNOP_OP (transpose, integer, /* no-op */)
+DEFUNOP_OP (hermitian, integer, /* no-op */)
+
+DEFNCUNOP_METHOD (incr, integer, increment)
+DEFNCUNOP_METHOD (decr, integer, decrement)
+
+#ifdef DEFBINOP_OP
+#undef DEFBINOP_OP
+#endif
+
+#define DEFBINOP_OP(name, t1, t2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    return octave_value \
+      (new octave_integer (v1.t1 ## _value () op v2.t2 ## _value ())); \
+  }
+
+// integer by integer ops.
+
+DEFBINOP_OP (add, integer, integer, +)
+DEFBINOP_OP (sub, integer, integer, -)
+DEFBINOP_OP (mul, integer, integer, *)
+
+DEFBINOP (div, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v2.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v1.integer_value () / d);
+}
+
+
+DEFBINOP (i_s_div, integer, scalar)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return new octave_scalar (v1.double_value () / d);
+}
+
+DEFBINOP (ldiv, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v1.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v2.integer_value () / d);
+}
+
+DEFBINOP_OP (lt, integer, integer, <)
+DEFBINOP_OP (le, integer, integer, <=)
+DEFBINOP_OP (eq, integer, integer, ==)
+DEFBINOP_OP (ge, integer, integer, >=)
+DEFBINOP_OP (gt, integer, integer, >)
+DEFBINOP_OP (ne, integer, integer, !=)
+
+DEFBINOP_OP (el_mul, integer, integer, !=)
+
+DEFBINOP (el_div, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v2.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v1.integer_value () / d);
+}
+
+DEFBINOP (el_ldiv, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v1.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v2.integer_value () / d);
+}
+
+DEFBINOP_OP (el_and, integer, integer, &&)
+DEFBINOP_OP (el_or, integer, integer, ||)
+
+DEFUN_DLD (make_int, args, ,
+  "int_val = make_int (val)\n\
+\n\
+Creates an integer variable from VAL.")
+{
+  static bool type_loaded = false;
+
+  if (! type_loaded)
+    {
+      octave_integer::register_type ();
+      mlock ("make_int");
+
+      octave_stdout << "installing integer type at type-id = "
+	   << octave_integer::static_type_id () << "\n";
+
+      INSTALL_UNOP (op_not, octave_integer, gnot);
+      INSTALL_UNOP (op_uminus, octave_integer, uminus);
+      INSTALL_UNOP (op_transpose, octave_integer, transpose);
+      INSTALL_UNOP (op_hermitian, octave_integer, hermitian);
+
+      INSTALL_NCUNOP (op_incr, octave_integer, incr);
+      INSTALL_NCUNOP (op_decr, octave_integer, decr);
+
+      INSTALL_BINOP (op_add, octave_integer, octave_integer, add);
+      INSTALL_BINOP (op_sub, octave_integer, octave_integer, sub);
+      INSTALL_BINOP (op_mul, octave_integer, octave_integer, mul);
+      INSTALL_BINOP (op_div, octave_integer, octave_integer, div);
+      INSTALL_BINOP (op_ldiv, octave_integer, octave_integer, ldiv);
+      INSTALL_BINOP (op_lt, octave_integer, octave_integer, lt);
+      INSTALL_BINOP (op_le, octave_integer, octave_integer, le);
+      INSTALL_BINOP (op_eq, octave_integer, octave_integer, eq);
+      INSTALL_BINOP (op_ge, octave_integer, octave_integer, ge);
+      INSTALL_BINOP (op_gt, octave_integer, octave_integer, gt);
+      INSTALL_BINOP (op_ne, octave_integer, octave_integer, ne);
+      INSTALL_BINOP (op_el_mul, octave_integer, octave_integer, el_mul);
+      INSTALL_BINOP (op_el_div, octave_integer, octave_integer, el_div);
+      INSTALL_BINOP (op_el_ldiv, octave_integer, octave_integer, el_ldiv);
+      INSTALL_BINOP (op_el_and, octave_integer, octave_integer, el_and);
+      INSTALL_BINOP (op_el_or, octave_integer, octave_integer, el_or);
+
+      INSTALL_BINOP (op_div, octave_integer, octave_scalar, i_s_div);
+    }
+
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      double d = args(0).double_value ();
+
+      if (! error_state)
+	retval = octave_value (new octave_integer (NINT (d)));
+    }
+  else
+    usage ("make_int");
+
+  return retval;
+}
+
+DEFUN_DLD (doit, args, ,
+  "doit (I)")
+{
+  octave_value_list retval;
+
+  if (args(0).type_id () == octave_integer::static_type_id ())
+    {
+      // At this point, we know we have a handle for an octave_integer
+      // object, so we can peek at the representation and extract the
+      // data.
+
+      const octave_base_value& rep = args(0).get_rep ();
+
+      int my_value = ((const octave_integer&) rep) . integer_value ();
+
+      message ("doit", "your lucky number is: %d", my_value);
+    }
+  else
+    gripe_wrong_type_arg ("doit", args(0));
+
+  return retval;
+}
+
+DEFINE_OCTAVE_ALLOCATOR (octave_integer);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_integer, "integer", "integer");
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/examples/mycell.c b/examples/mycell.c
new file mode 100644
index 0000000..ba3577d
--- /dev/null
+++ b/examples/mycell.c
@@ -0,0 +1,18 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+	     const mxArray* prhs[])
+{
+  mwSize n;
+  mwIndex i;
+
+  if (nrhs != 1 || ! mxIsCell (prhs[0]))
+    mexErrMsgTxt ("expects cell");
+
+  n = mxGetNumberOfElements (prhs[0]);
+  n = (n > nlhs ? nlhs : n);
+  
+  for (i = 0; i < n; i++)
+    plhs[i] = mxDuplicateArray (mxGetCell (prhs[0], i));
+}
diff --git a/examples/myfeval.c b/examples/myfeval.c
new file mode 100644
index 0000000..73b908b
--- /dev/null
+++ b/examples/myfeval.c
@@ -0,0 +1,24 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+	     const mxArray* prhs[])
+{
+  char *str;
+
+  mexPrintf ("Hello, World!\n");
+
+  mexPrintf ("I have %d inputs and %d outputs\n", nrhs,
+	     nlhs);
+
+  if (nrhs < 1 || ! mxIsString (prhs[0])) 
+    mexErrMsgTxt ("function name expected");
+
+  str = mxArrayToString (prhs[0]);
+
+  mexPrintf ("I'm going to call the function %s\n", str);
+
+  mexCallMATLAB (nlhs, plhs, nrhs-1, prhs+1, str);
+
+  mxFree (str);
+}
diff --git a/examples/myfevalf.f b/examples/myfevalf.f
new file mode 100644
index 0000000..03a0b72
--- /dev/null
+++ b/examples/myfevalf.f
@@ -0,0 +1,30 @@
+      subroutine mexFunction (nlhs, plhs, nrhs, prhs)
+
+      implicit none
+
+      integer*4 nlhs, nrhs
+
+* The following will need to be integer*8 on 64-bit systems, otherwise
+* these variables won't be large enough to hold pointers...
+      integer*4 plhs(*), prhs(*)
+
+      integer*4 mxIsString, mxGetString, mxGetN, mexCallMATLAB
+      integer*4 status, len
+      character*100 str
+
+      call mexPrintf ('Hello, World!')
+
+      if (nrhs .lt. 1 .or. mxIsString (prhs(1)) .ne. 1) then
+        call mexErrMsgTxt ('function name expected')
+      endif
+
+      len = mxGetN (prhs(1))
+
+      status = mxGetString (prhs(1), str, 100)
+
+      call mexPrintf ('FORTRAN will call the interpreter now')
+
+      status = mexCallMATLAB (nlhs, plhs, nrhs-1, prhs(2), str(1:len))
+
+      return
+      end
diff --git a/examples/myfunc.c b/examples/myfunc.c
new file mode 100644
index 0000000..ff3d38d
--- /dev/null
+++ b/examples/myfunc.c
@@ -0,0 +1,13 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+	     const mxArray *prhs[])
+{
+  const char *nm;
+  nm = mexFunctionName ();
+  mexPrintf ("You called function: %s\n", nm);
+  if (strcmp (nm, "myfunc") == 0)
+    mexPrintf ("This is the principal function\n", nm);
+  return; 
+}
diff --git a/examples/myhello.c b/examples/myhello.c
new file mode 100644
index 0000000..94a447a
--- /dev/null
+++ b/examples/myhello.c
@@ -0,0 +1,13 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+  mxArray *v = mxCreateDoubleMatrix (1, 1, mxREAL);
+
+  double *data = mxGetPr (v);
+
+  *data = 1.23456789;
+
+  plhs[0] = v;
+}
diff --git a/examples/mypow2.c b/examples/mypow2.c
new file mode 100644
index 0000000..b799854
--- /dev/null
+++ b/examples/mypow2.c
@@ -0,0 +1,39 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+	     const mxArray* prhs[])
+{
+  mwIndex i;
+  mwSize n;
+  double *vri, *vro;
+  
+  if (nrhs != 1 || ! mxIsNumeric (prhs[0]))
+    mexErrMsgTxt ("expects matrix");
+
+  n = mxGetNumberOfElements (prhs[0]);
+  plhs[0] = (mxArray *) mxCreateNumericArray 
+    (mxGetNumberOfDimensions (prhs[0]),
+     mxGetDimensions (prhs[0]), mxGetClassID (prhs[0]),
+     mxIsComplex (prhs[0]));
+  vri = mxGetPr (prhs[0]);
+  vro = mxGetPr (plhs[0]);
+
+  if (mxIsComplex (prhs[0]))
+    {
+      double *vii, *vio;
+      vii = mxGetPi (prhs[0]);
+      vio = mxGetPi (plhs[0]);
+
+      for (i = 0; i < n; i++)
+	{
+	  vro [i] = vri [i] * vri [i] - vii [i] * vii [i];
+	  vio [i] = 2 * vri [i] * vii [i];
+	}
+    }
+  else
+    {
+      for (i = 0; i < n; i++)
+	vro [i] = vri [i] * vri [i];
+    }
+}
diff --git a/examples/myprop.c b/examples/myprop.c
new file mode 100644
index 0000000..14ae9e6
--- /dev/null
+++ b/examples/myprop.c
@@ -0,0 +1,25 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+  double handle;
+  char property[256];
+
+  if (nrhs < 2 || nrhs > 3)
+    mexErrMsgTxt ("incorrect number of arguments");
+  if (!mxIsDouble(prhs[0]))
+    mexErrMsgTxt ("handle expected to be a double scalar");
+  if (!mxIsChar (prhs[1]))
+    mexErrMsgTxt ("expected property to be a string");
+  
+  handle = mxGetScalar (prhs[0]);
+  mxGetString (prhs[1], property, 256);
+  plhs[0] = mxDuplicateArray (mexGet (handle, property));
+  
+  if (nrhs == 3)
+    if (mexSet (handle, property, mxDuplicateArray (prhs[2])))
+      mexErrMsgTxt ("failed to set property");
+}
+  
+
diff --git a/examples/myset.c b/examples/myset.c
new file mode 100644
index 0000000..f3b58a4
--- /dev/null
+++ b/examples/myset.c
@@ -0,0 +1,33 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+  char *str;
+  mxArray *v;
+
+  if (nrhs != 2 || ! mxIsString (prhs[0]))
+    mexErrMsgTxt ("expects symbol name and value");
+
+  str = mxArrayToString (prhs[0]);
+
+  v = mexGetArray (str, "global");
+
+  if (v)
+    {
+      mexPrintf ("%s is a global variable with the following value:\n", str);
+      mexCallMATLAB (0, 0, 1, &v, "disp");
+    }
+
+  v = mexGetArray (str, "caller");
+
+  if (v)
+    {
+      mexPrintf ("%s is a caller variable with the following value:\n", str);
+      mexCallMATLAB (0, 0, 1, &v, "disp");
+    }
+
+  // WARNING!! Can't do this in MATLAB!  Must copy variable first.
+  mxSetName (prhs[1], str);  
+  mexPutArray (prhs[1], "caller");
+}
diff --git a/examples/mysparse.c b/examples/mysparse.c
new file mode 100644
index 0000000..4478f2b
--- /dev/null
+++ b/examples/mysparse.c
@@ -0,0 +1,120 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+	     const mxArray *prhs[])
+{
+  mwSize n, m, nz;
+  mxArray *v;
+  mwIndex i;
+  double *pr, *pi;
+  double *pr2, *pi2;
+  mwIndex *ir, *jc;
+  mwIndex *ir2, *jc2;
+  
+  if (nrhs != 1 || ! mxIsSparse (prhs[0]))
+    mexErrMsgTxt ("expects sparse matrix");
+
+  m = mxGetM (prhs [0]);
+  n = mxGetN (prhs [0]);
+  nz = mxGetNzmax (prhs [0]);
+  
+  if (mxIsComplex (prhs[0]))
+    {
+      mexPrintf ("Matrix is %d-by-%d complex",
+		 " sparse matrix", m, n);
+      mexPrintf (" with %d elements\n", nz);
+
+      pr = mxGetPr (prhs[0]);
+      pi = mxGetPi (prhs[0]);
+      ir = mxGetIr (prhs[0]);
+      jc = mxGetJc (prhs[0]);
+
+      i = n;
+      while (jc[i] == jc[i-1] && i != 0) i--;
+      mexPrintf ("last non-zero element (%d, %d) =", 
+		 ir[nz-1]+ 1, i);
+      mexPrintf (" (%g, %g)\n", pr[nz-1], pi[nz-1]);
+
+      v = mxCreateSparse (m, n, nz, mxCOMPLEX);
+      pr2 = mxGetPr (v);
+      pi2 = mxGetPi (v);
+      ir2 = mxGetIr (v);
+      jc2 = mxGetJc (v);
+      
+      for (i = 0; i < nz; i++)
+        {
+          pr2[i] = 2 * pr[i];
+          pi2[i] = 2 * pi[i];
+          ir2[i] = ir[i];
+        }
+      for (i = 0; i < n + 1; i++)
+        jc2[i] = jc[i];
+
+      if (nlhs > 0)
+        plhs[0] = v;
+    }
+  else if (mxIsLogical (prhs[0]))
+    {
+      bool *pbr, *pbr2;
+      mexPrintf ("Matrix is %d-by-%d logical",
+		 " sparse matrix", m, n);
+      mexPrintf (" with %d elements\n", nz);
+
+      pbr = mxGetLogicals (prhs[0]);
+      ir = mxGetIr (prhs[0]);
+      jc = mxGetJc (prhs[0]);
+
+      i = n;
+      while (jc[i] == jc[i-1] && i != 0) i--;
+      mexPrintf ("last non-zero element (%d, %d) = %d\n",
+                 ir[nz-1]+ 1, i, pbr[nz-1]);
+
+      v = mxCreateSparseLogicalMatrix (m, n, nz);
+      pbr2 = mxGetLogicals (v);
+      ir2 = mxGetIr (v);
+      jc2 = mxGetJc (v);
+      
+      for (i = 0; i < nz; i++)
+        {
+          pbr2[i] = pbr[i];
+          ir2[i] = ir[i];
+        }
+      for (i = 0; i < n + 1; i++)
+        jc2[i] = jc[i];
+
+      if (nlhs > 0)
+        plhs[0] = v;
+    }
+  else
+    {
+      mexPrintf ("Matrix is %d-by-%d real",
+		 " sparse matrix", m, n);
+      mexPrintf (" with %d elements\n", nz);
+
+      pr = mxGetPr (prhs[0]);
+      ir = mxGetIr (prhs[0]);
+      jc = mxGetJc (prhs[0]);
+
+      i = n;
+      while (jc[i] == jc[i-1] && i != 0) i--;
+      mexPrintf ("last non-zero element (%d, %d) = %g\n",
+                ir[nz-1]+ 1, i, pr[nz-1]);
+
+      v = mxCreateSparse (m, n, nz, mxREAL);
+      pr2 = mxGetPr (v);
+      ir2 = mxGetIr (v);
+      jc2 = mxGetJc (v);
+      
+      for (i = 0; i < nz; i++)
+        {
+          pr2[i] = 2 * pr[i];
+          ir2[i] = ir[i];
+        }
+      for (i = 0; i < n + 1; i++)
+        jc2[i] = jc[i];
+
+      if (nlhs > 0)
+        plhs[0] = v;
+    }
+}
diff --git a/examples/mystring.c b/examples/mystring.c
new file mode 100644
index 0000000..7854616
--- /dev/null
+++ b/examples/mystring.c
@@ -0,0 +1,26 @@
+#include <string.h>
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[], int nrhs, 
+	     const mxArray *prhs[])
+{
+  mwIndex i, j;
+  mwSize m, n;
+  mxChar *pi, *po;
+
+  if (nrhs != 1 || ! mxIsChar (prhs[0]) || 
+      mxGetNumberOfDimensions (prhs[0]) > 2)
+    mexErrMsgTxt ("expecting char matrix");
+
+  m = mxGetM (prhs[0]);
+  n = mxGetN (prhs[0]);
+  pi = mxGetChars (prhs[0]);
+  plhs[0] = mxCreateNumericMatrix (m, n, mxCHAR_CLASS, 
+				   mxREAL);
+  po = mxGetChars (plhs[0]);
+
+  for (j = 0; j < n; j++)
+    for (i = 0; i < m; i++)
+      po [j*m + m - 1 - i] = pi [j*m + i];
+}
diff --git a/examples/mystruct.c b/examples/mystruct.c
new file mode 100644
index 0000000..70ae969
--- /dev/null
+++ b/examples/mystruct.c
@@ -0,0 +1,37 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[], int nrhs, 
+	     const mxArray* prhs[])
+{
+  int i;
+  mwIndex j;
+  mxArray *v;
+  const char *keys[] = { "this", "that" };
+
+  if (nrhs != 1 || ! mxIsStruct (prhs[0]))
+    mexErrMsgTxt ("expects struct");
+
+  for (i = 0; i < mxGetNumberOfFields (prhs[0]); i++)
+    for (j = 0; j < mxGetNumberOfElements (prhs[0]); j++)
+      {
+        mexPrintf ("field %s(%d) = ", 
+                   mxGetFieldNameByNumber (prhs[0], i), j);
+        v = mxGetFieldByNumber (prhs[0], j, i);
+        mexCallMATLAB (0, 0, 1, &v, "disp");
+      }
+
+  v = mxCreateStructMatrix (2, 2, 2, keys);
+
+  mxSetFieldByNumber (v, 0, 0, mxCreateString ("this1"));
+  mxSetFieldByNumber (v, 0, 1, mxCreateString ("that1"));
+  mxSetFieldByNumber (v, 1, 0, mxCreateString ("this2"));
+  mxSetFieldByNumber (v, 1, 1, mxCreateString ("that2"));
+  mxSetFieldByNumber (v, 2, 0, mxCreateString ("this3"));
+  mxSetFieldByNumber (v, 2, 1, mxCreateString ("that3"));
+  mxSetFieldByNumber (v, 3, 0, mxCreateString ("this4"));
+  mxSetFieldByNumber (v, 3, 1, mxCreateString ("that4"));
+
+  if (nlhs)
+    plhs[0] = v;
+}
diff --git a/examples/octave-sombrero.png b/examples/octave-sombrero.png
new file mode 100644
index 0000000..e18557c
Binary files /dev/null and b/examples/octave-sombrero.png differ
diff --git a/examples/octave.desktop.in b/examples/octave.desktop.in
new file mode 100644
index 0000000..0587ea1
--- /dev/null
+++ b/examples/octave.desktop.in
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Name=GNU Octave
+Comment=Scientific Computing using GNU Octave
+TryExec=%OCTAVE_PREFIX%/bin/octave
+Exec=%OCTAVE_PREFIX%/bin/octave
+Icon=%OCTAVE_IMAGEDIR%/octave-sombrero.png
+Terminal=true
+Type=Application
+Categories=Development;Math;Science;
+StartupNotify=false
diff --git a/examples/oregonator.cc b/examples/oregonator.cc
new file mode 100644
index 0000000..06f2088
--- /dev/null
+++ b/examples/oregonator.cc
@@ -0,0 +1,22 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (oregonator, args, ,
+  "The `oregonator'.\n\
+\n\
+Reference:\n\
+\n\
+  Oscillations in chemical systems.  IV.  Limit cycle behavior in a\n\
+  model of a real chemical reaction. Richard J. Field and Richard\n\
+  M. Noyes, The Journal of Chemical Physics, Volume 60 Number 5,\n\
+  March 1974.")
+{
+  ColumnVector dx (3);
+
+  ColumnVector x (args(0).vector_value ());
+
+  dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0) - 8.375e-06*pow (x(0), 2.0));
+  dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27;
+  dx(2) = 0.161*(x(0) - x(2));
+
+  return octave_value (dx);
+}
diff --git a/examples/oregonator.m b/examples/oregonator.m
new file mode 100644
index 0000000..deed751
--- /dev/null
+++ b/examples/oregonator.m
@@ -0,0 +1,18 @@
+## The `oregonator'.
+##
+## Reference:
+##
+##   Oscillations in chemical systems.  IV.  Limit cycle behavior in a
+##   model of a real chemical reaction. Richard J. Field and Richard
+##   M. Noyes, The Journal of Chemical Physics, Volume 60 Number 5,
+##   March 1974.
+
+function dx = oregonator (x, t)
+
+  dx = zeros (3, 1);
+
+  dx(1) = 77.27*(x(2) - x(1)*x(2) + x(1) - 8.375e-06*x(1)^2);
+  dx(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
+  dx(3) = 0.161*(x(1) - x(3));
+
+end
diff --git a/examples/paramdemo.cc b/examples/paramdemo.cc
new file mode 100644
index 0000000..0b896fe
--- /dev/null
+++ b/examples/paramdemo.cc
@@ -0,0 +1,34 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (paramdemo, args, nargout, 
+	   "Parameter Check Demo.")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin != 1)
+    print_usage();
+  else if (nargout != 0)
+    error ("paramdemo: function has no output arguments");
+  else
+    {
+      NDArray m = args(0).array_value();
+      double min_val = -10.0;
+      double max_val = 10.0;
+      octave_stdout << "Properties of input array:\n";
+      if (m.any_element_is_negative ())
+        octave_stdout << "  includes negative values\n";
+      if (m.any_element_is_inf_or_nan())
+        octave_stdout << "  includes Inf or NaN values\n";
+      if (m.any_element_not_one_or_zero())
+        octave_stdout << 
+	  "  includes other values than 1 and 0\n";
+      if (m.all_elements_are_int_or_inf_or_nan())
+        octave_stdout << 
+	  "  includes only int, Inf or NaN values\n";
+      if (m.all_integers (min_val, max_val))
+        octave_stdout << 
+	  "  includes only integers in [-10,10]\n";
+    }
+  return retval;
+}
diff --git a/examples/standalone.cc b/examples/standalone.cc
new file mode 100644
index 0000000..f79add0
--- /dev/null
+++ b/examples/standalone.cc
@@ -0,0 +1,19 @@
+#include <iostream>
+#include <octave/oct.h>
+
+int
+main (void)
+{
+  std::cout << "Hello Octave world!\n";
+  int n = 2;
+  Matrix a_matrix = Matrix (n, n);
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      for (octave_idx_type j = 0; j < n; j++)
+        {
+          a_matrix (i, j) = (i + 1) * 10 + (j + 1);
+        }
+    }
+  std::cout << a_matrix;
+  return 0;
+}
diff --git a/examples/stringdemo.cc b/examples/stringdemo.cc
new file mode 100644
index 0000000..6599424
--- /dev/null
+++ b/examples/stringdemo.cc
@@ -0,0 +1,33 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (stringdemo, args, , "String Demo")
+{
+  int nargin = args.length();
+  octave_value_list retval; 
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      charMatrix ch = args(0).char_matrix_value ();
+
+      if (! error_state)
+        {
+          if (args(0).is_sq_string ())
+            retval(1) = octave_value (ch, true);
+          else
+            retval(1) = octave_value (ch, true, '\'');
+
+          octave_idx_type nr = ch.rows();
+          for (octave_idx_type i = 0; i < nr / 2; i++)
+            {
+              std::string tmp = ch.row_as_string (i);
+              ch.insert (ch.row_as_string(nr-i-1).c_str(), 
+			 i, 0);
+              ch.insert (tmp.c_str(), nr-i-1, 0);
+            }
+          retval(0) = octave_value (ch, true);
+        }
+    }
+  return retval;
+}
diff --git a/examples/structdemo.cc b/examples/structdemo.cc
new file mode 100644
index 0000000..794ffbb
--- /dev/null
+++ b/examples/structdemo.cc
@@ -0,0 +1,38 @@
+#include <octave/oct.h>
+#include <octave/ov-struct.h>
+
+DEFUN_DLD (structdemo, args, , "Struct demo.")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin != 2)
+    print_usage ();
+  else
+    {
+      Octave_map arg0 = args(0).map_value ();
+      std::string arg1 = args(1).string_value ();
+
+      if (! error_state && arg0.contains (arg1))
+        {
+          // The following two lines might be written as
+          //    octave_value tmp;
+          //    for (Octave_map::iterator p0 = 
+	  //        arg0.begin(); 
+          //        p0 != arg0.end(); p0++ )
+          //      if (arg0.key (p0) == arg1)
+          //        {
+          //          tmp = arg0.contents (p0) (0);
+          //          break;
+          //        }
+          // though using seek is more concise.
+          Octave_map::const_iterator p1 = arg0.seek (arg1);
+          octave_value tmp =  arg0.contents(p1)(0);
+          Octave_map st;
+          st.assign ("selected", tmp);
+          retval = octave_value (st);
+        }
+    }
+  return retval; 
+}
+
diff --git a/examples/unwinddemo.cc b/examples/unwinddemo.cc
new file mode 100644
index 0000000..4cd049d
--- /dev/null
+++ b/examples/unwinddemo.cc
@@ -0,0 +1,32 @@
+#include <octave/oct.h>
+#include <octave/unwind-prot.h>
+
+void
+err_hand (const char *fmt, ...)
+{
+  // Do nothing!!
+}
+
+DEFUN_DLD (unwinddemo, args, nargout, "Unwind Demo")
+{
+  int nargin = args.length();
+  octave_value retval;
+  if (nargin < 2)
+    print_usage ();
+  else
+    {
+      NDArray a = args(0).array_value ();
+      NDArray b = args(1).array_value ();
+
+      if (! error_state)
+        {
+          unwind_protect::begin_frame ("Funwinddemo");
+          unwind_protect_ptr 
+	    (current_liboctave_warning_handler);
+          set_liboctave_warning_handler(err_hand);
+          retval = octave_value (quotient (a, b));
+          unwind_protect::run_frame ("Funwinddemo");
+        }
+    }
+  return retval;
+}
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..0ff4b6a
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/libcruft/ChangeLog b/libcruft/ChangeLog
new file mode 100644
index 0000000..8f6e8aa
--- /dev/null
+++ b/libcruft/ChangeLog
@@ -0,0 +1,1677 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-06-22  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (MISC_OBJ): Remove misc/machar.o and misc/smachar.o
+	from the list.
+
+	* misc/i1mach.f, misc/r1mach.f, misc/d1mach.f: Rewite in terms of
+	LAPACK functions slamch and dlamch.
+	* misc/machar.c: Delete.
+	* misc/Makefile.in (CSRC): Remove machar.c from the list.
+	(CEXTRA, XCC, XALL_CFLAGS): Delete variables.
+	(machar.o, smachar.o, pic/machar.o, pic/smachar.o): Delete rules.
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-05-07  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+        * Makefile.in: (SHLPRE): Rename from SHLLIBPRE.
+
+2009-03-07  John W. Eaton  <jwe at octave.org>
+
+	* misc/quit.h (octave_rethrow_exception):
+	Don't tag with GCC_ATTR_NORETURN.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (maintainer-clean): Also remove libraries.
+
+	* Makerules.in: Make maintainer-clean and distclean the same.
+
+2009-02-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* misc/quit.h (octave_signal_caught): Declare as volatile.
+	* misc/cquit.cc (octave_signal_caught): Likewise.
+
+2009-02-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* blas/ssymm.f, blas/dsymm.f, blas/chemm.f, blas/zhemm.f: New sources.
+	* blas/Makefile.in: Include them.
+
+2009-01-28  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (LIBRARIES, install, uninstall): use SHLLIBPRE and
+	SHLBINPRE library prefixes.
+	From Marco Atzeri <marco_atzeri at yahoo.it>.
+
+2008-12-21  Jaroslav Hajek <highegg at gmail.com>
+
+	* lapack/chegs2.f lapack/chegst.f lapack/chegv.f lapack/dsygs2.f 
+	lapack/dsygst.f lapack/dsygv.f lapack/ssygs2.f lapack/ssygst.f 
+	lapack/ssygv.f lapack/zhegs2.f lapack/zhegst.f lapack/zhegv.f:
+	New sources.
+	* lapack/Makefile.in: Include them.
+
+2008-12-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* blas/zsyrk.f: New source.
+	* lapack/cggbak.f, lapack/cggev.f, lapack/cgghrd.f, lapack/chgeqz.f,
+	lapack/ctgevc.f, lapack/dggev.f, lapack/sggev.f, lapack/zggbak.f,
+	lapack/zggev.f, lapack/zgghrd.f, lapack/zhgeqz.f, lapack/ztgevc.f:
+	New sources.
+	* lapack/Makefile.in: Include them.
+
+2008-08-12  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* blas/icamax.f, blas/isamax.f: New files.
+	* blas/Makefile.in (FSRC): Add them to the list.
+
+	* lapack/icmax1.f: New file.
+	* lapack/Makefile.in (FSRC): Add it to the list.
+	
+2008-06-16  David Bateman  <dbateman at free.fr>
+
+	* slatec-fn/xacosh.f, slatec-fn/xasinh.f: Replace xsacosh with
+	xacosh, xdacosh with xacosh and xdasinh with xasinh.
+
+2008-06-12  Jaroslav Hajek <highegg at gmail.com>
+
+	* misc/Makefile.in (MAKEDEPS): Remove CEXTRA.
+
+2008-06-04  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* misc/oct-dlldefs.h (OCTGRAPHICS_API): New macro for import/export
+	in graphics related libraries.
+
+2008-06-02  David Bateman  <dbateman at free.fr>
+
+	* libcruft/xsgmainc.f: Replace DLGAMS with ALGAMS.
+
+2008-05-30  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* quadpack/qk15i.f: Delete extraneous semicolons.
+
+2008-05-21  David Bateman  <dbateman at free.fr>
+
+	* odepack/slsode.f, odepack/sintdy.f: Replace the use of xerrwv
+	with xerrwd and rumach with d1mach(4).
+
+	* odepack/scfode.f, odepack/sewset.f, odepack/sintdy.f,
+	odepack/slsode.f, odepack/sprepj.f, odepack/ssolsy.f,
+	odepack/sstode.f, odepack/svnorm.f: New files.
+	* odepack/Makefile.in (FSRC): Add them.
+
+	* ordered-qz/sexchqz.f, ordered-qz/ssubsp.f: New files.
+	* ordered-qz/Makefile.in (FSRC): Add them.
+	* quadpack/qagi.f, quadpack/qagie.f, quadpack/qagp.f,
+	quadpack/qagpe.f, quadpack/qelg.f, quadpack/qk15i.f,
+	quadpack/qk21.f, quadpack/qpsrt.f: New files.
+	* quadpack/Makefile.in (FSRC): Add them.
+
+2008-05-20  Jaroslav Hajek <highegg at gmail.com>
+
+	* qrupdate/cch1dn.f, qrupdate/cchinx.f, qrupdate/cqhqr.f, 
+	qrupdate/cqrinc.f, qrupdate/cqrinr.f, qrupdate/cqrqhu.f, 
+	qrupdate/cqrqhv.f, qrupdate/sch1dn.f, qrupdate/schinx.f, 
+	qrupdate/sqhqr.f, qrupdate/sqrinc.f, qrupdate/sqrinr.f, 
+	qrupdate/sqrqhu.f: Convert DOUBLE PRECISION constants to REAL.
+	* qrupdate/cqrinr.f, qrupdate/sqrinr.f: Correct EXTERNAL
+	declarations.
+	* qrupdate/sqrinr.f: Convert DOUBLE PRECISION calls to
+	REAL counterparts.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (MISC_OBJ): Add misc/smachar.o
+	* Makerules.in (CRUFT_CSRC, CRUFT_CPICOBJ): Add CEXTRA, allowing
+	objects files with no corresponding source file in the
+	distribution.
+
+	* amos/cacai.f, amos/cacon.f, amos/cbesh.f, amos/cbesi.f,
+	amos/cbesj.f, amos/cbesk.f, amos/cbesy.f, amos/cbinu.f,
+	amos/cbuni.f, amos/cbunk.f, amos/cunk1.f amos/cunk2.f,
+	amos/crati.f, amos/cshch.f, amos/cuni1.f, amos/cuoik.f,
+	amos/cairy.f, amos/cbiry.f, amos/ckscl.f, amos/cs1s2.f,
+	amos/cuchk.f, amos/cuni2.f, amos/cwrsk.f, amos/casyi.f,
+	amos/cbknu.f, amos/cmlri.f, amos/cseri.f, amos/cunhj.f,
+	amos/cunik.f: New files.
+	* amos/Makefile.in (FSRC): Add them.
+
+	* blas-xtra/xsdot.f, blas-xtra/xsnrm2.f, blas-xtra/xscnrm2.f,
+	blas-xtra/xcdotc.f, blas-xtra/xcdotu.f: New files
+	* blas-xtra/Makefile.in (FSRC): Add them.
+
+	* blas/sasum.f, blas/saxpy.f, blas/scabs1.f, blas/scopy.f,
+	blas/sger.f, blas/smach.f, blas/snrm2.f, blas/srot.f,
+	blas/sswap.f, blas/ssymv.f, blas/ssyr.f, blas/ssyr2.f,
+	blas/ssyr2k.f, blas/stbsv.f, blas/strmm.f, blas/strmv.f,
+	blas/strsv.f, blas/scasum.f, blas/scnrm2.f, blas/caxpy.f,
+	blas/ccopy.f, blas/cdotc.f, blas/cdotu.f, blas/, blas/csrot.f,
+	blas/csscal.f, blas/cgemm.f, blas/cgemv.f, blas/cgerc.f,
+	blas/cgeru.f, blas/chemv.f, blas/cher.f, blas/cher2.f,
+	blas/cher2k.f, blas/cherk.f, blas/cscal.f, blas/cswap.f,
+	blas/ctbsv.f, blas/ctrmm.f, blas/ctrmv.f, blas/, blas/ctrsm.f,
+	blas/ctrsv.f: New files
+	* blas/Makefile.in (FSRC): Add them.
+
+	* fftpack/zfftb.f, zfftb1.f, fftpack/zfftf.f, fftpack/zfftf1.f,
+	fftpack/zffti.f, fftpack/zffti1.f, fftpack/zpassb.f,
+	fftpack/zpassb2.f, fftpack/zpassb3.f, fftpack/zpassb4.f,
+	fftpack/zpassb5.f, fftpack/zpassf.f, fftpack/zpassf2.f,
+	fftpack/zpassf3.f, fftpack/zpassf4.f, fftpack/zpassf5.f: Rename
+	function (c -> z | add z).
+	* fftpack/cfftb.f, cfftb1.f, fftpack/cfftf.f, fftpack/cfftf1.f,
+	fftpack/cffti.f, fftpack/cffti1.f, fftpack/passb.f,
+	fftpack/passb2.f, fftpack/passb3.f, fftpack/passb4.f,
+	fftpack/passb5.f, fftpack/passf.f, fftpack/passf2.f,
+	fftpack/passf3.f, fftpack/passf4.f, fftpack/passf5.f: New files
+	for single precision.
+	* fftpack/Makefile.in (FSRC): Add new files.
+
+	* lapack-xtra/xclange.f, lapack-xtra/xslamch.f,
+	lapack-xtra/xslange.f: New files.
+	* lapack-xtra/Makefile.in (FSRC): Add them.
+
+	* lapack/cbdsqr.f, lapack/csrscl.f, lapack/cgbcon.f,
+	lapack/cgbtf2.f, lapack/cgbtrf.f, lapack/cgbtrs.f,
+	lapack/cgebak.f, lapack/cgebal.f, lapack/cgebd2.f,
+	lapack/cgebrd.f, lapack/cgecon.f, lapack/cgeesx.f, lapack/cgeev.f,
+	lapack/cgehd2.f, lapack/cgehrd.f, lapack/cgelq2.f,
+	lapack/cgelqf.f, lapack/cgelsd.f, lapack/cgelss.f,
+	lapack/cgelsy.f, lapack/cgeqp3.f, lapack/cgeqpf.f,
+	lapack/cgeqr2.f, lapack/cgeqrf.f, lapack/cgesv.f, lapack/cgesvd.f,
+	lapack/cgetf2.f, lapack/cgetrf.f, lapack/cgetri.f,
+	lapack/cgetrs.f, lapack/cggbal.f, lapack/cgtsv.f, lapack/cgttrf.f,
+	lapack/cgttrs.f, lapack/cgtts2.f, lapack/cheev.f, lapack/chetd2.f,
+	lapack/chetrd.f, lapack/chseqr.f, lapack/clabrd.f,
+	lapack/clacgv.f, lapack/clacn2.f, lapack/clacon.f,
+	lapack/clacpy.f, lapack/cladiv.f, lapack/clahqr.f,
+	lapack/clahr2.f, lapack/clahrd.f, lapack/claic1.f,
+	lapack/clals0.f, lapack/clalsa.f, lapack/clalsd.f,
+	lapack/clange.f, lapack/clanhe.f, lapack/clanhs.f,
+	lapack/clantr.f, lapack/claqp2.f, lapack/claqps.f,
+	lapack/claqr0.f, lapack/claqr1.f, lapack/claqr2.f,
+	lapack/claqr3.f, lapack/claqr4.f, lapack/claqr5.f, lapack/clarf.f,
+	lapack/clarfb.f, lapack/clarfg.f, lapack/clarft.f,
+	lapack/clarfx.f, lapack/clartg.f, lapack/clarz.f, lapack/clarzb.f,
+	lapack/clarzt.f, lapack/clascl.f, lapack/claset.f, lapack/clasr.f,
+	lapack/classq.f, lapack/claswp.f, lapack/clatbs.f,
+	lapack/clatrd.f, lapack/clatrs.f, lapack/clatrz.f,
+	lapack/clauu2.f, lapack/clauum.f, lapack/cpbcon.f,
+	lapack/cpbtf2.f, lapack/cpbtrf.f, lapack/cpbtrs.f,
+	lapack/cpocon.f, lapack/cpotf2.f, lapack/cpotrf.f,
+	lapack/cpotri.f, lapack/cpotrs.f, lapack/cptsv.f, lapack/cpttrf.f,
+	lapack/cpttrs.f, lapack/cptts2.f, lapack/crot.f, lapack/csteqr.f,
+	lapack/ctrcon.f, lapack/ctrevc.f, lapack/ctrexc.f,
+	lapack/ctrsen.f, lapack/ctrsyl.f, lapack/ctrti2.f,
+	lapack/ctrtri.f, lapack/ctrtrs.f, lapack/ctzrzf.f,
+	lapack/cung2l.f, lapack/cung2r.f, lapack/cungbr.f,
+	lapack/cunghr.f, lapack/cungl2.f, lapack/cunglq.f,
+	lapack/cungql.f, lapack/cungqr.f, lapack/cungtr.f,
+	lapack/cunm2r.f, lapack/cunmbr.f, lapack/cunml2.f,
+	lapack/cunmlq.f, lapack/cunmqr.f, lapack/cunmr3.f,
+	lapack/cunmrz.f, lapack/sbdsqr.f, lapack/sgbcon.f,
+	lapack/sgbtf2.f, lapack/sgbtrf.f, lapack/sgbtrs.f,
+	lapack/sgebak.f, lapack/sgebal.f, lapack/sgebd2.f,
+	lapack/sgebrd.f, lapack/sgecon.f, lapack/sgeesx.f, lapack/sgeev.f,
+	lapack/sgehd2.f, lapack/sgehrd.f, lapack/sgelq2.f,
+	lapack/sgelqf.f, lapack/sgelsd.f, lapack/sgelss.f,
+	lapack/sgelsy.f, lapack/sgeqp3.f, lapack/sgeqpf.f,
+	lapack/sgeqr2.f, lapack/sgeqrf.f, lapack/sgesv.f, lapack/sgesvd.f,
+	lapack/sgetf2.f, lapack/sgetrf.f, lapack/sgetri.f,
+	lapack/sgetrs.f, lapack/sggbak.f, lapack/sggbal.f,
+	lapack/sgghrd.f, lapack/sgtsv.f, lapack/sgttrf.f, lapack/sgttrs.f,
+	lapack/sgtts2.f, lapack/shgeqz.f, lapack/shseqr.f,
+	lapack/slabad.f, lapack/slabrd.f, lapack/slacn2.f,
+	lapack/slacon.f, lapack/slacpy.f, lapack/sladiv.f, lapack/slae2.f,
+	lapack/slaed6.f, lapack/slaev2.f, lapack/slaexc.f, lapack/slag2.f,
+	lapack/slahqr.f, lapack/slahr2.f, lapack/slahrd.f,
+	lapack/slaic1.f, lapack/slaln2.f, lapack/slals0.f,
+	lapack/slalsa.f, lapack/slalsd.f, lapack/slamc1.f,
+	lapack/slamc2.f, lapack/slamc3.f, lapack/slamc4.f,
+	lapack/slamc5.f, lapack/slamch.f, lapack/slamrg.f,
+	lapack/slange.f, lapack/slanhs.f, lapack/slanst.f,
+	lapack/slansy.f, lapack/slantr.f, lapack/slanv2.f,
+	lapack/slapy2.f, lapack/slapy3.f, lapack/slaqp2.f,
+	lapack/slaqps.f, lapack/slaqr0.f, lapack/slaqr1.f,
+	lapack/slaqr2.f, lapack/slaqr3.f, lapack/slaqr4.f,
+	lapack/slaqr5.f, lapack/slarf.f, lapack/slarfb.f, lapack/slarfg.f,
+	lapack/slarft.f, lapack/slarfx.f, lapack/slartg.f, lapack/slarz.f,
+	lapack/slarzb.f, lapack/slarzt.f, lapack/slas2.f, lapack/slascl.f,
+	lapack/slasd0.f, lapack/slasd1.f, lapack/slasd2.f,
+	lapack/slasd3.f, lapack/slasd4.f, lapack/slasd5.f,
+	lapack/slasd6.f, lapack/slasd7.f, lapack/slasd8.f,
+	lapack/slasda.f, lapack/slasdq.f, lapack/slasdt.f,
+	lapack/slaset.f, lapack/slasq1.f, lapack/slasq2.f,
+	lapack/slasq3.f, lapack/slasq4.f, lapack/slasq5.f,
+	lapack/slasq6.f, lapack/slasr.f, lapack/slasrt.f, lapack/slassq.f,
+	lapack/slasv2.f, lapack/slaswp.f, lapack/slasy2.f,
+	lapack/slatbs.f, lapack/slatrd.f, lapack/slatrs.f,
+	lapack/slatrz.f, lapack/slauu2.f, lapack/slauum.f,
+	lapack/slazq3.f, lapack/slazq4.f, lapack/sorg2l.f,
+	lapack/sorg2r.f, lapack/sorgbr.f, lapack/sorghr.f,
+	lapack/sorgl2.f, lapack/sorglq.f, lapack/sorgql.f,
+	lapack/sorgqr.f, lapack/sorgtr.f, lapack/sorm2r.f,
+	lapack/sormbr.f, lapack/sorml2.f, lapack/sormlq.f,
+	lapack/sormqr.f, lapack/sormr3.f, lapack/sormrz.f,
+	lapack/spbcon.f, lapack/spbtf2.f, lapack/spbtrf.f,
+	lapack/spbtrs.f, lapack/spocon.f, lapack/spotri.f,
+	lapack/spotrs.f, lapack/sptsv.f, lapack/spttrf.f, lapack/spttrs.f,
+	lapack/sptts2.f, lapack/srscl.f, lapack/ssteqr.f, lapack/ssterf.f,
+	lapack/ssyev.f, lapack/ssytd2.f, lapack/ssytrd.f, lapack/stgevc.f,
+	lapack/strcon.f, lapack/strevc.f, lapack/strexc.f,
+	lapack/strsen.f, lapack/strsyl.f, lapack/strti2.f,
+	lapack/strtri.f, lapack/strtrs.f, lapack/stzrzf.f,
+	lapack/scsum1.f: New files
+	* lapack/Makefile.in (FSRC): Add them.
+
+	* misc/r1mach.f: New file
+	* misc/machar.cc: Modify to allow to be build twice, once for
+	double precision and once for single precision.
+	* misc/Makefile.in (FSRC): Add it.
+	(CEXTRA): Add smachar.c, and target for smachar.o
+	(MAKEDEPS): Include CEXTRA.
+
+	* qrupdate/sch1up.f, qrupdate/cch1up.f, qrupdate/sqrinc.f,
+	qrupdate/cqrinc.f, qrupdate/sqrdec.f, qrupdate/cqrdec.f,
+	qrupdate/sqrinr.f, qrupdate/cqrinr.f, qrupdate/sqrder.f,
+	qrupdate/cqrder.f, qrupdate/sqrshc.f, qrupdate/cqrshc.f,
+	qrupdate/sqr1up.f, qrupdate/cqr1up.f, qrupdate/sch1dn.f,
+	qrupdate/cch1dn.f, qrupdate/schinx.f, qrupdate/cchinx.f,
+	qrupdate/schdex.f, qrupdate/cchdex.f, qrupdate/sqrqhu.f,
+	qrupdate/cqrqhu.f, qrupdate/sqrqhv.f, qrupdate/cqrqhv.f,
+	qrupdate/sqhqr.f, qrupdate/cqhqr.f: New files.
+	* qrupdate/Makefile.in (FSRC): Add them.
+
+	* slatec-fn/acosh.f, slatec-fn/albeta.f, slatec-fn/algams.f,
+	slatec-fn/alngam.f, slatec-fn/alnrel.f, slatec-fn/asinh.f,
+	slatec-fn/atanh.f, slatec-fn/betai.f, slatec-fn/csevl.f,
+	slatec-fn/erf.f, slatec-fn/erfc.f, slatec-fn/gami.f,
+	slatec-fn/gamit.f, slatec-fn/gamlim.f, slatec-fn/gamma.f,
+	slatec-fn/gamr.f, slatec-fn/inits.f, slatec-fn/pchim.f,
+	slatec-fn/pchst.f, slatec-fn/r9gmit.f, slatec-fn/r9lgic.f,
+	slatec-fn/r9lgit.f, slatec-fn/r9lgmc.f, slatec-fn/xacosh.f,
+	slatec-fn/xasinh.f, slatec-fn/xatanh.f, slatec-fn/xbetai.f,
+	slatec-fn/xerf.f, slatec-fn/xerfc.f, slatec-fn/xgamma.f,
+	slatec-fn/xsgmainc.f: New files.
+	* slatec-fn/Makefile.in (FSRC): Add them.	
+
+2008-04-20  Jaroslav Hajek <highegg at gmail.com>
+
+	* qrupdate/dch1dn.f, qrupdate/dchdex.f, qrupdate/dchinx.f,
+	qrupdate/dqhqr.f, qrupdate/dqrdec.f, qrupdate/dqrinc.f,
+	qrupdate/dqrqhu.f, qrupdate/dqrqhv.f, qrupdate/dqrshc.f,
+	qrupdate/zch1dn.f, qrupdate/zchdex.f, qrupdate/zchinx.f,
+	qrupdate/zqhqr.f, qrupdate/zqrdec.f, qrupdate/zqrder.f,
+	qrupdate/zqrinc.f, qrupdate/zqrinr.f, qrupdate/zqrqhu.f,
+	qrupdate/zqrqhv.f, qrupdate/zqrshc.f:
+	Fix external declarations, XERBLA calls, and docs.
+
+2008-04-07  Jaroslav Hajek <highegg at gmail.com>
+
+	* qrupdate/dqrqhu.f, qrupdate/zqrqhu.f,
+	* qrupdate/dqrshc.f, qrupdate/zqrshc.f,
+	* qrupdate/dchinx.f, qrupdate/zchinx.f,
+	* qrupdate/dchdex.f, qrupdate/zchdex.f: New files.
+
+2008-04-02  Jaroslav Hajek <highegg at gmail.com>
+
+	* blas-xtra/xzdotu.f: Turn into simple wrapper for zdotu.
+	* blas-xtra/xzdotc.f: Turn into simple wrapper for zdotc.
+	* qrupdate/zqrqhv.f: Undo previous change.
+
+2008-03-22  David Bateman  <dbateman at free.fr>
+
+	* qrupdate/dch1up.f: Remove unused external reference to dlartv.
+
+2008-03-18  John W. Eaton  <jwe at octave.org>
+
+	* qrupdate/zqrqhv.f (zqrqhv): Call xzdotc instead of zdotc.
+	* blas-xtra/xzdotu.f: Eliminate local zdotu variable.
+	* blas-xtra/xzdotc.f: New file.
+	* blas-xtra/Makefile.in (FSRC): Add it to the list.
+
+2008-03-10  John W. Eaton  <jwe at octave.org>
+
+	* blas/zdrot.f, odepack/dlsode.f, odepack/ewset.f,
+	odepack/intdy.f, fftpack/cffti.f, fftpack/cfftb.f,
+	fftpack/cfftf.f:
+	Use (*) instead of (1) for assumed-size dimensions.
+
+2008-03-06  Jaroslav Hajek <highegg at gmail.com>
+
+	* qrupdate/dqrinc.f: Declare DGEMV external.
+	* qrupdate/zqrinc.f: Declare ZGEMV external.
+	Fix complex constant args in call to ZGEMV.
+
+2008-03-05  Jaroslav Hajek <highegg at gmail.com>
+
+	* qrupdate/dch1dn.f, qrupdate/zch1dn.f: add "quick return" checks.
+
+2008-03-04 Jaroslav Hajek <highegg at gmail.com>
+
+	* qrupdate/dch1dn.f, qrupdate/dch1up.f, 
+	qrupdate/zch1dn.f, qrupdate/zch1up.f: New files.
+	* qrupdate/Makefile.in (FSRC): Add them to the list.
+
+	* qrupdate/Makefile.in, qrupdate/dqhqr.f, qrupdate/dqr1up.f,
+	qrupdate/dqrdec.f, qrupdate/dqrder.f, qrupdate/dqrinc.f,
+	qrupdate/dqrinr.f, qrupdate/dqrqhv.f, qrupdate/zqhqr.f,
+	qrupdate/zqr1up.f, qrupdate/zqrdec.f, qrupdate/zqrder.f,
+	qrupdate/zqrinc.f, qrupdate/zqrinr.f, qrupdate/zqrqhv.f:
+	New files.
+	* Makefile.in (CRUFT_DIRS): Add qrupdate to the list.
+
+2008-02-14  John W. Eaton  <jwe at octave.org>
+
+	* misc/f77-fcn.h (F77_XFCN): Call octave_rethrow_exception here
+	instead of checking octave_allocation_error.
+	* misc/quit.cc (octave_execution_exception): New function.
+	(octave_rethrow_exception): New function.
+	(octave_handle_signal): Call octave_rethrow_exception instead of
+	octave_throw_interrupt_exception.
+	* misc/quit.h (octave_execution_error): New variable.
+	(END_INTERRUPT_WITH_EXCEPTIONS): Catch octave_execution_exception.
+	(octave_execution_exception): New class.
+	(octave_exception): New enum.
+	(octave_exception_state): Rename from octave_allocation_error.
+	Change all uses.
+
+2008-02-12  John W. Eaton  <jwe at octave.org>
+
+	* lapack-xtra/xilaenv.f: New wrapper for Fortran function ilaenv.
+	* lapack-xtra/Makefile.in (FSRC): Add it to the list.
+
+2008-02-06  John W. Eaton  <jwe at octave.org>
+
+	* Makerules.in (%.def : %.f): Use mv instead of move-if-change.
+
+2008-02-05  John W. Eaton  <jwe at octave.org>
+
+	* misc/Makefile.in: Unconditionally include $(MAKEDEPS).
+	Mark $(MAKEDEPS) as .PHONY targets if omit_deps is true.
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+2007-11-01  John W. Eaton  <jwe at octave.org>
+
+	* lapack-xtra/xzlange.f: Include complete implementation of ZLANGE
+	function here.
+
+	* blas-xtra/xzdotu.f: Include complete implementation of ZDOTU
+	function here.
+
+2007-10-26  John W. Eaton  <jwe at octave.org>
+
+	* lapack/dlals0.f: New file.
+	* lapack/Makefile.in (FSRC): Add it to the list.
+
+2007-10-26  David Bateman  <dbateman at free.fr>
+
+	* lapack/dgelsd.f, lapack/dlalsd.f, lapack/dlalsa.f,
+	lapack/dlasda.f, lapack/dlasdt.f, lapack/dlasdq.f 
+	lapack/dlamrg.f, lapack/dlasd0.f, lapack/dlasd1.f, 
+	lapack/dlasd2.f, lapack/dlasd3.f, lapack/dlasd4.f, 
+	lapack/dlasd5.f, lapack/dlasd6.f, lapack/dlasd7.f, 
+	lapack/dlasd8.f, lapack/dlaed6.f, lapack/zgelsd.f, 
+	lapack/zlalsd.f , lapack/zlalsa.f, lapack/zlals0.f: New files.
+	* lapack/Makefile.in (FSRC): Include them here.
+
+2007-10-23  John W. Eaton  <jwe at octave.org>
+
+	* lapack/dgtts2.f, lapack/zgtts2.f: New files.
+	* lapack/Makefile.in (FSRC): Add them to the list.
+
+2007-10-16  John W. Eaton  <jwe at octave.org>
+
+	* lapack/dlacn2.f, lapack/dlacn2.f, lapack/dlahr2.f,
+	lapack/dlahr2.f, lapack/dlaqr0.f, lapack/dlazq3.f,
+	lapack/dlazq3.f, lapack/dormr3.f, lapack/dormrz.f,
+	lapack/iparmq.f, lapack/iparmq.f, lapack/zlacn2.f,
+	lapack/zlahr2.f, lapack/zlaqr0.f: New files.
+	* lapack/Makefile.in (FSRC): Add them to the list.
+
+	* lapack: Update all files to current versions from Lapack 3.1.1.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+2007-10-03  John W. Eaton  <jwe at octave.org>
+
+	* mkf77def.in: Combine sed expressions.
+
+2007-09-26  David Bateman  <dbateman at free.fr>
+
+	* lapack/dgelsy.f,  lapack/dlatrz.f,  lapack/zlarz.f,
+	lapack/dgeqp3.f,  lapack/dtzrzf.f,  lapack/zlarzt.f,
+	lapack/dlaic1.f,  lapack/zgelsy.f,  lapack/zlatrz.f,
+	lapack/dlaqp2.f,  lapack/zgeqp3.f,  lapack/ztzrzf.f,
+	lapack/dlaqps.f,  lapack/zlaic1.f,  lapack/zunmr3.f,
+	lapack/dlarzb.f,  lapack/zlaqp2.f,  lapack/zunmrz.f,
+	lapack/dlarz.f,   lapack/zlaqps.f, lapack/dlarzt.f,  
+	lapack/zlarzb.f: New files
+	* lapack/Makefile.in (FSRC): Add the new files.
+
+2007-07-25  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in, Makerules.in, fftpack/Makefile.in,
+	randlib/Makefile.in: Adjust DISTFILES to allow out of tree "make dist" 
+	to work.
+
+2007-04-23  John W. Eaton  <jwe at octave.org>
+
+	* ranlib/phrtsd.f (phrtsd): Store result of call to index
+	instrinsic in an INTEGER variable to ensure that the types of the
+	arguments passed to mod really are the same even on 64-bit systems.
+
+2007-04-18  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* libcruft/blas-xtra/xdnrm2.f, libcruft/blas-xtra/xdznrm2.f:
+	Delete spurious semicolons.
+
+2007-04-06  John W. Eaton  <jwe at octave.org>
+
+	* blas-xtra/xdnrm2.f, blas-xtra/xdznrm2.f: New functions.
+	* blas-xtra/Makefile.in (FSRC): Add them to the list.
+
+	* ranlib/phrtsd.f (phrtsd): Ensure that the types of the arguments
+	passed to mod are the same even on 64-bit systems.
+
+2007-04-04  John W. Eaton  <jwe at octave.org>
+
+	* Makefules.in: Handle Fortran, C, and C++ sources with separate
+	variables.
+	* misc/Makefile.in: Use new variables for Fortran, C, and C++ files.
+	* Makefile.in (clean mostlyclean distclean): No need to remove
+	$(CRUFT_OBJ) here.
+
+2007-04-04  Rafael Laboissiere  <rafael at debian.org>
+
+	* Makefile.in (clean): Remove mkf77def.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* Makerules.in, Makefile.in (dist): Use ln instead of $(LN_S).
+
+2007-02-26  John W. Eaton  <jwe at octave.org>
+
+	* misc/Makefile.in (CPICDEP): Also set if CPICFLAG is not defined.
+	(CXXPICDEP): Also set if CXXPICFLAG is not defined.
+
+2007-02-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in, Makerules.in: Use $(LN_S) instead of ln or ln -s.
+
+2007-02-07  John W. Eaton  <jwe at octave.org>
+
+	* Makerules.in: Don't use wildcard function to generate source
+	efile list.
+	* amos/Makefile.in, blas-xtra/Makefile.in, blas/Makefile.in,
+	daspk/Makefile.in, dasrt/Makefile.in, dassl/Makefile.in,
+	fftpack/Makefile.in, lapack-xtra/Makefile.in, lapack/Makefile.in,
+	minpack/Makefile.in, misc/Makefile.in, odepack/Makefile.in,
+	ordered-qz/Makefile.in, quadpack/Makefile.in, ranlib/Makefile.in,
+	slatec-err/Makefile.in, slatec-fn/Makefile.in, villad/Makefile.in:
+	Explicitly list source files.
+
+2007-01-24  Alexander Barth  <abarth at marine.usf.edu>
+
+	* misc/f77-fcn.h (F77_CSTRING): Call OCTAVE_LOCAL_BUFFER with cs,
+	not F77_CHAR_ARG_USE (s).
+
+2006-11-11  John W. Eaton  <jwe at octave.org>
+
+	* Makerules.in (%.def : %.f): Use $(simple-move-if-change-rule) here.
+
+2006-11-03  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DLL_CXXDEFS): Rename from XTRA_CXXDEFS.
+	(DLL_CDEFS): Rename from XTRA_CDEFS.
+	Substitute CRUFT_DLL_DEFS, not XTRA_CRUFT_DEFS.
+	(XTRA_CRUFT_SH_LDFLAGS): Rename from XTRA_CRUFT_LINK_DEPS.
+	Add $(XTRA_CRUFT_SH_LDFLAGS) to SH_LDFLAGS instead of to LINK_DEPS.
+
+2006-10-31  John W. Eaton  <jwe at octave.org>
+
+	* misc/Makefile.in (INCLUDES): Add oct-dlldefs.h to the list.
+
+2006-10-29  John W. Eaton  <jwe at octave.org>
+
+	* misc/Makefile.in (SPECIAL_INCLUDE): Add oct-dlldefs.h to the list.
+
+2006-10-28  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* misc/quit.h: Undefine min and max after including windows.h.
+
+2006-10-27  John W. Eaton  <jwe at octave.org>
+
+	* misc/oct-dlldefs.h: New file.
+
+	* mkf77def.in: Downcase all input to simplify matching.
+	Match only lines beginning with whitespace.
+	Match function return types.
+	Use literal TAB characters instead of \t in sed patterns.
+	From Michael Goffioul <michael.goffioul at swing.be>.
+
+2006-10-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in (XTRA_CRUFT_LINK_DEPS): Substitute.
+	(CRUFT_DEFS): New variable.
+	(LINK_DEPS): Include $(XTRA_CRUFT_LINK_DEPS) in the list.
+	(clean, mostlyclean, distclean): Delete cruft.def.
+	(cruft.def): New target.
+	(libraries): Depend on cruft.def.
+
+	* misc/f77-fcn.h (f77_exception_encountered, xstopx):
+	Tag with CRUFT_API.
+	* misc/lo-error.h (current_liboctave_error_handler,
+	current_liboctave_warning_handler,
+	current_liboctave_warning_with_id_handler,
+	set_liboctave_error_handler, set_liboctave_warning_handler,
+	set_liboctave_warning_with_id_handler): Likewise.
+	* misc/quit.h (w32_sigint_init, w32_raise_final,
+	w32_raise, w32_in_main_thread, current_context,
+	octave_save_current_context, octave_restore_current_context,
+	octave_jump_to_enclosing_context, octave_save_signal_mask,
+	octave_restore_signal_mask, octave_interrupt_immediately,
+	octave_interrupt_state, octave_allocation_error,
+	octave_signal_caught, octave_handle_signal,
+	octave_throw_interrupt_exception, octave_throw_bad_alloc,
+	octave_signal_hook, octave_interrupt_hook, octave_bad_alloc_hook):
+	Likewise.
+	
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in ($(CRUFT_DEFS)): Depend on $(SUBDIRS).
+	(cruft.def): Depend on $(CRUFT_DEFS).
+	(libraries): Depend on cruft.def only.
+
+	* mk77def.in: New script template
+	* Makefile.in (DISTFILES): Include mk77def.in in the list.
+	($(SUBDIRS)): Depend on mk77def.
+	(mk77def): New target.
+	(CRUFT_DEFS): New variable.
+	* Makerules.in (CRUFT_FSRC, CRUFT_CSRC, CRUFT_CXXSRC): New variables.
+	(CRUFT_SRC): Define using $(CRUFT_FSRC), $(CRUFT_CSRC), and
+	$(CRUFT_CXXSRC).
+	(CRUFT_DEFS): New variable.
+	($(CRUFT_DEFS)): Depend on $(TOPDIR)/libcruft/mkf77def.
+	(%.def : %.f): New pattern rule.  Use mkf77def script to do
+	Fortran name mangling.
+	(clean, mostlyclean, distclean): Delete $(CRUFT_DEFS).
+	(all): Depend on $(CRUFT_DEFS)
+	Partially from Michael Goffioul  <michael.goffioul at swing.be>.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* Makerules.in (XTRA_CDEFS, XTRA_CXXDEFS): Substitute here.
+
+2006-10-23  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* misc/f77-fcn.h (F77_CHAR_ARG_DEF, F77_CONST_CHAR_ARG_DEF,
+	F77_CHAR_ARG_LEN_DEF, F77_CHAR_ARG_USE, F77_CHAR_ARG_LEN_USE,
+	F77_CSTRING): New macros to handle passing C character strings to
+	Fortran.
+
+2006-10-17  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* lapack-xtra/xdlamch.f: Begin lines with spaces, not tabs.
+
+	* misc/Makefile.in (machar.o, pic/machar.o): Specify output file
+	name in compile command.
+
+2006-10-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Adapt rules to use $(LIBPRE).
+
+2006-09-11  John W. Eaton  <jwe at octave.org>
+
+	* blas-xtra/xddot.f, blas-xtra/xzdotu.f: New files.
+
+2006-06-01  David Bateman  <dbateman at free.fr>
+
+	* slatec-fn/dpchim.f, slatec-fn/dpchst.f: New files.
+
+2006-05-22  John W. Eaton  <jwe at octave.org>
+
+	* lapack/dlantr.f, lapack/zlantr.f: New files.
+
+2006-05-03  David Bateman  <dbateman at free.fr>
+
+	* lapack/dpocon.f, lapack/zpocon.f, lapack/dpotrs.f, 
+	lapack/zpotrs.f, lapack/dtrcon.f, lapack/ztrcon.f,
+	lapack/dtrtrs.f, lapack/ztrtrs.f: New files.
+
+2006-04-29  John W. Eaton  <jwe at octave.org>
+
+	* misc/lo-error.c (set_liboctave_warning_with_id_handler,
+	liboctave_warning_with_id): New functions.
+	(current_liboctave_warning_with_id_handler): New variable.
+	* misc/lo-error.h (liboctave_warning_with_id_handler): New typedef.
+	(current_liboctave_warning_with_id_handler, liboctave_warning_with_id
+	set_liboctave_warning_with_id_handler): Provide decls.
+
+2006-04-18  John W. Eaton  <jwe at octave.org>
+
+	* misc/f77-fcn.h (F77_XFCN): Move decls to beginning of blocks for C.
+
+2006-04-13  John W. Eaton  <jwe at octave.org>
+
+	* misc/quit.h BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1,
+	END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE): Omit unnecessary casts.
+	* misc/f77-fcn.h (F77_XFCN, F77_CHAR_ARG_LEN): Likewise.
+
+2006-04-03  David Bateman  <dbateman at free.fr>
+
+	* ranlib/wrap.f (dgenexp, dgengam, dignpoi): New functions.
+
+2006-03-21  John W. Eaton  <jwe at octave.org>
+
+	* misc/f77-fcn.h (F77_XFCN): Save octave_interrupt_immediately and
+	restore it if an exception occurs that causes a longjmp.
+
+2005-11-01  John W. Eaton  <jwe at octave.org>
+
+	* ranlib/ignbin.f, ranlib/ignpoi.f: Avoid arithmetic IF statements.
+
+2005-10-17  John W. Eaton  <jwe at octave.org>
+
+	* lapack/Makefile.in (dlamc1.o pic/dlamc1.o):
+	Add $(F77_FLOAT_STORE_FLAG) to FFLAGS.
+
+2005-09-23  John W. Eaton  <jwe at octave.org>
+
+	* misc/machar.c: Restore test code.
+
+2005-09-15  John W. Eaton  <jwe at octave.org>
+
+	* misc/quit.h Rename all win32_ symbols to w32.  Change all uses.
+
+2005-09-15  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (LN_S): Change to DESTDIR before LN_S to avoid
+	lack of symlinks under mingw.
+	* misc/cquit.c (w32_thread_setjmp_mutex, win32_signal_context,
+	win32_signal_to_raise, win32_main_thread_id, win32_main_thread,
+	win32_restore_thread): New static variables.
+	(win32_in_main_thread): Returns 1 if in main thread for win32.
+	(win32_reset_context): Reset context (longjmp style) for win32.
+	(win32_raise_in_main): Raise signal in main thread for win32.
+	(win32_raise): Raise signal for win32.
+	(win32_raise_final): Clean up win32 signalling.
+	(win32_sigint_init): Initialize win32 signalling.
+	* quit.h (win32_sigint_init, win32_raise_final, win32_raise,
+	win32_in_main_thread): Declaration.
+	
+2005-09-14  Daniel  <durbano at shbano.com>
+
+	* lapack/zbdsqr.f: Fix typo in docs.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-05-06  John W. Eaton  <jwe at octave.org>
+
+	* lapack/dpotri.f, lapack/dlauum.f, lapack/dlauu2.f,
+	lapack/zpotri.f, lapack/zlauum.f, lapack/zlauu2.f: New files.
+
+2005-04-08  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in, Makerules.in (clean, distclean, maintainer-clean):
+	Avoid duplication in rules.
+
+2005-03-17  Andy Adler  <adler at site.uottawa.ca>
+
+	* Makerules.in (install-strip): Include double-colon target here too.
+
+2005-03-09  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (bin-dist): Delete target.
+	(BINDISTLIBS, BINDISTFILES): Delete variables.
+
+2005-03-01  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (CRUFT_DIRS): Remove it from the list.
+	* odessa: Delete directory.
+
+	* misc/machar.c (rmachar): Declare local REAL variables volatile.
+
+2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	* blas/zher.f: New file.
+
+	Sparse merge.
+
+	2005-01-13 David Bateman  <dbateman at free.fr>
+
+	* lapack/dgttrf.f lapack/dgttrs.f lapacl/zgttrf.f lapack/zgttrs.f:
+	new files
+
+	2005-01-23  David Bateman  <dbateman at free.fr>
+
+	* lapack/dgtsv.f lapack/dpbcon.f lapack/dpbtf2.f lapack/dpbtrf.f 
+	lapack/dpbtrs.f lapack/dptsv.f lapack/dpttrf.f lapack/dpttrs.f 
+	lapack/dptts2.f lapack/zgtsv.f lapack/zpbcon.f lapack/zpbtf2.f 
+	lapack/zpbtrf.f lapack/zpbtrs.f lapack/zptsv.f lapack/zpttrf.f 
+	lapack/zpttrs.f lapck/zptts2.f: New files.
+
+	2004-12-29  John W. Eaton  <jwe at octave.org>
+
+	* blas/zbtsv.f: New file.
+	* lapack/dgbcon.f, lapack/dgbtrf.f, lapack/dgbtrs.f,
+	lapack/dlatbs.f, lapack/zgbcon.f, lapack/zgbtf2.f,
+	lapack/zgbtrf.f, lapack/zgbtrs.f, lapack/zlatbs.f: New files.
+
+2005-02-10  John W. Eaton  <jwe at octave.org>
+
+	* misc/cquit.c (octave_signal_caught): New global variable.
+	* misc/quit.cc (occtave_handle_signal): New function.
+	(octave_signal_hook): New global pointer.
+	* misc/quit.h: Provide decls.
+	(OCTAVE_QUIT): Check octave_signal_caught, not
+	octave_interrupt_state, and call octave_handle_signal, not
+	octave_throw_interrupt_exception.
+	
+2005-02-08  John W. Eaton  <jwe at octave.org>
+
+	* misc/quit.h: Use C-style comments.
+
+2004-09-08  John W. Eaton  <jwe at octave.org>
+
+	* misc/machar.c (rmachar): Use modern C declaration.
+
+2004-02-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/f77-fcn.c: Handle Cray, CVF, and f2c calling conventions.
+
+	* misc/f77-fcn.h (xstopx): Use F77_CHAR_ARG_DECL and
+	F77_CHAR_ARG_LEN_DECL in declaration.
+
+2004-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/quit.h (OCTAVE_QUIT): Set octave_interrupt_state to -1
+	while we are handling interrupts.
+
+2004-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (LINK_DEPS): Always define.
+
+2003-11-12  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/machar.c (machar) [CRAY]: Kluge to make it work.
+
+2003-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* odepack/dlsode.f: Rename from odepack/lsode.f.
+	* odepack/dlsode.f (DLSODE): Rename from LSODE to avoid name
+	conflict with LSODE class constructors on systems that upcase
+	Fortran names.
+
+	* odessa/dodessa.f: Rename from odessa/odessa.f.
+	* odessa/dodessa.f (DODESSA): Rename from ODESSA to avoid name
+	conflict with ODESSA class constructors on systems that upcase
+	Fortran names.
+
+2003-10-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (MISC_OBJ): Add misc/cquit.o to the list.
+
+	* misc/Makefile.in (SPECIAL_SRC): Add cquit.c to the list.
+	* misc/cquit.c: New file.
+	* misc/quit.cc: Move everything except octave_interrupt_hook,
+	octave_bad_alloc_hook, octave_throw_interrupt_exception, and
+	octave_throw_bad_alloc to cquit.c.
+
+2003-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/quit.h (octave_interrupt_hook, octave_bad_alloc_hook):
+	Move declarations outside of extern "C" block.
+
+2003-10-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/f77-fcn.h: Only use inline if this is C++.
+
+	* misc/f77-fcn.c (xstopx): Return type is now F77_RET_T.
+	Use F77_RETURN.
+	* misc/machar.c (machar): Likewise.
+
+	* misc/f77-fcn.h (F77_CHAR_ARG, F77_CONST_CHAR_ARG, F77_CHAR_ARG2,
+	F77_CONST_CHAR_ARG2, F77_CXX_STRING_ARG, F77_CHAR_ARG_LEN,
+	F77_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, F77_CHAR_ARG_LEN_DECL,
+	F77_RET_T, F77_RETURN): New macros.
+	[F77_USES_CRAY_CALLING_CONVENTION]: New data conversion functions.
+
+	* misc/quit.h (octave_interrupt_hook, octave_bad_alloc_hook):
+	Move function pointer declarations inside __cplusplus section.
+
+2003-07-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-lib): Use $(INSTALL), not
+	$(INSTALL_PROGRAM) for $(SHLLIB) files.
+
+2003-07-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (CLEAN_SUBDIRS): New variable.
+	(clean mostlyclean distclean maintainer-clean): Use it to ensure
+	cleaning in all subdirs, not just those we build in.
+
+	* Makerules.in (maintainer-clean, distclean): Don't use
+	dependencies on double colon rules.
+	(distclean): Also remove *.d, *.a, *.o, pic/*.o, pic, and stmp-pic.
+	(maintainer-clean): Also remove *.d, *.a, *.o, pic/*.o, pic, and
+	stmp-pic, and Makefile.
+
+	* Makefile.in (maintainer-clean, distclean): Also remove *.$(SHLEXT).
+
+2003-06-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dasrt/ddasrt.f (DDASRT): Print correct message for invalid MXSTP.
+
+	* dassl/ddassl.f (DDASSL): Handle MXSTP as in DASRT.
+
+	* dassl/ddajac.f (DDAJAC): LIPVT is now 22.
+	* dassl/ddassl.f (DDASSL): Likewise.
+	* dassl/ddaslv.f (DDASLV): Likewise.
+
+	* misc/quit.h (octave_interrupt_hook, octave_bad_alloc_hook):
+	New function pointers.
+	* misc/quit.cc: Initialize them.
+	(octave_throw_interrupt_exception): If octave_interrupt_hook is
+	set, call it.
+	(octave_throw_bad_alloc): Likewise, for octave_bad_alloc_hook.
+
+	* dasrt/ddasrt.f (DDASRT): Set LMXSTP to 21 and LIPVT to 22 to
+	avoid conflict with LLAST in DRCHECK.  Change docs for INFO(12)
+	and LIW.
+
+2003-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, misc/Makefile.in: Handle DESTDIR.
+
+2003-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* blas/sgemm.f, blas/strsm.f, blas/ssyrk.f, blas/sscal.f,
+	blas/sgemv.f, blas/sdot.f: New files.
+
+2003-02-20  Paul Kienzle <pkienzle at users.sf.net>
+
+	* dassl/ddaslv.f: Fortran doesn't use ; in statements.
+
+2003-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* libcruft/blas/dtbsv.f: New file.
+	* libcruft/lapack/dlatrs.f, libcruft/lapack/dtrti2.f,
+	libcruft/lapack/dtrtri.f, libcruft/lapack/ztrti2.f,
+	libcruft/lapack/ztrtri.f: New files.
+
+2003-02-04  David Bateman <dbateman at free.fr>
+
+	* libcruft/Makefile.in (CRUFT_DIRS): Remove linpack from list.
+
+	* libcruft/linpackdgbfa.f, libcruft/linpackdgbsl.f
+	libcruft/linpackdgeco.f, libcruft/linpackdgedi.f,
+	libcruft/linpackdgefa.f, libcruft/linpackdgesl.f,
+	libcruft/linpackspofa.f, libcruft/linpackzgeco.f,
+	libcruft/linpackzgedi.f, libcruft/linpackzgefa.f,
+	libcruft/linpackzgesl.f: Delete.
+
+	* libcruft/dassl/ddajac.f, libcruft/dassl/ddaslv.f:  Use DGxTRF and
+	DGxTRS instead of DGxFA and DGxSL.
+	* libcruft/daspk/ddaspk.f, libcruft/daspk/dmatd.f,
+	libcruft/daspk/dslvd.f: Likewise.
+	* libcruft/odepack/lsode.f, libcruft/odepack/prepj.f,
+	libcruft/odepack/solsy.f: Likewise.
+	* libcruft/odessa/odessa.f, libcruft/odessa/odessa_prepj.f,
+	libcruft/odessa/odessa_solsy.f: Likewise.
+	* libcrudt/ranlib/setgmn.f: Use SPOTRF instead of SPOFA.
+
+	* libcruft/lapack/dgbtf2.f, libcruft/lapack/dgbtrf.f,
+	libcruft/lapack/dgbtrs.f, libcruft/lapack/dgecon.f,
+	libcruft/lapack/dgetri.f, libcruft/lapack/spotf2.f,
+	libcruft/lapack/spotrf.f, libcruft/lapack/zgecon.f,
+	libcruft/lapack/zgetri.f: New files.
+
+2003-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/quit.h (BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1,
+	BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2): New macros.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* odessa/odessa_rscom.f (ODESSA_RSCOM): Fix apparent typo (LODE2
+	should probably be LIODE2).
+
+	* Makerules.in (clean, mostlyclean): Also remove *.d.
+
+	* misc/quit.cc: Add std:: qualifiers to memcpy calls.
+
+2003-01-03  Paul Kienzle <pkienzle at users.sf.net>
+
+	* misc/quit.h: Move #include <new> outside extern "C" block.
+	* misc/f77-fcn.h: Move #include "quit.h" outside extern "C" block.
+
+2002-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/quit.h (BEGIN_INTERRUPT_WITH_EXCEPTIONS,
+	END_INTERRUPT_WITH_EXCEPTIONS): Only define for C++ source.
+	Include <new> for C++ source.
+
+2002-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/quit.h, misc/quit.cc [! USE_EXCEPTIONS_FOR_INTERRUPTS]):
+	Always use exceptions for handling interrupts.
+	(BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE): 
+
+	* misc/quit.h (OCTAVE_TRY_WITH_INTERRUPTS, OCTAVE_THROW_BAD_ALLOC,
+	OCTAVE_CATCH_INTERRUPTS, SAVE_OCTAVE_INTERRUPT_IMMEDIATELY,
+	INCREMENT_OCTAVE_INTERRUPT_IMMEDIATELY, OCTAVE_THROW_TO_TOP_LEVEL,
+	DECREMENT_OCTAVE_INTERRUPT_IMMEDIATELY, OCTAVE_JUMP_TO_TOP_LEVEL,
+	SET_OCTAVE_INTERRUPT_IMMEDIATELY): Replace all uses with
+	definitions, delete macros.
+
+2002-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/quit.cc (octave_allocation_error): New variable.
+	(octave_throw_bad_alloc): New function.
+	* misc/quit.h: Provide decls.
+	(OCTAVE_THROW_BAD_ALLOC): New macro.
+	(END_INTERRUPT_WITH_EXCEPTIONS): Also catch bad_alloc.
+	* misc/f77-fcn.h (F77_XFCN): Handle allocation errors.
+
+	* misc/quit.h (octave_jmp_buf): New typedef.
+	(current_context): Type is now octave_jmp_buf.
+	(octave_set_current_context): Use sigsetjmp if we have it.
+	(octave_interrupt_immediately, octave_interrupt_state): Type is
+	now sig_atomic_t.
+	(BEGIN_INTERRUPT_WITH_EXCEPTIONS, END_INTERRUPT_WITH_EXCEPTIONS):
+	New macros.
+
+	* misc/quit.cc (octave_jump_to_enclosing_context): Use siglongjmp
+	if we have it.	
+	(octave_save_current_context, octave_restore_current_context): Use
+	octave_jmp_buf type here.
+
+2002-11-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in: Handle automatic dependency generation for
+	C/C++ source files.
+
+	* misc/quit.h (INCREMENT_OCTAVE_INTERRUPT_IMMEDIATELY,
+	DECREMENT_OCTAVE_INTERRUPT_IMMEDIATELY,
+	SET_OCTAVE_INTERRUPT_IMMEDIATELY): New macros.
+	(BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE,
+	BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE): Use them.
+	* f77-fcn.h (F77_XFCN): Likewise.
+
+	* misc/quit.cc: Include <cstring> for memcpy decl.
+
+2002-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/f77-fcn.h (F77_XFCN): Adapt to new signal/exception
+	handling scheme.
+	(f77_context): Delete decl.
+	(copy_f77_context): Likewise.
+	* misc/f77-fcn.cn (copy_f77_context): Delete.
+	(Fxstopx): Set f77_exception_encountered.
+	Use octave_jump_to_enclosing_context, not longjmp.
+
+	* misc/f77-extern.cc (f77_context): Delete definition.
+
+	* misc/quit.h, misc/quit.cc: New files.
+	* misc/Makefile: Add them to the appropriate lists.
+
+	* Makefile (MISC_OBJ): Add misc/quit.o
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* odessa/odessa.f (ODESSA): Second arg of xerrwd is string length.
+	* odessa/odessa_intdy.f (ODESSA_INTDY): Likewise.
+
+2002-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dasrt/ddasrt.f (DDASRT): Fix computation of LENRW.
+
+2002-10-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install): Don't bother with versions for $(SHLBIN)
+	files.
+
+	* slatec-err/xerrwd.f (XERRWD): Print msg(1:nmes), not just msg.
+
+2002-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install): No need to use cd to create links.
+
+2002-10-14  Paul Kienzle <pkienzle at users.sf.net>
+
+	* Makefile.in: Use link dependencies for shared libs if
+	INCLUDE_LINK_DEPS.
+	(LIBRARIES): If doing shared libs, include versioned library in	list.
+	(libcruft.$(SHLEXT), libcruft.$(SHLEXT_VER)): Reverse actions --
+	build unversioned library, symbolic link adds version info.
+	(install, uninstall): Handle link and load forms of the library
+	separately.
+
+2002-09-30  Paul Kienzle <pkienzle at users.sf.net>
+
+	* slatec-fn/xdacosh.f: Mark external functions as external.
+	* slatec-fn/xdasinh.f: Ditto.
+	* slatec-fn/xdatanh.f: Ditto.
+	* slatec-fn/xdbetai.f: Ditto.
+	* slatec-fn/xderf.f: Ditto.
+	* slatec-fn/xderfc.f: Ditto.
+	* slatec-fn/xdgami.f: Ditto.
+	* slatec-fn/xdgamit.f: Ditto.
+	* slatec-fn/xdgamma.f: Ditto.
+	* slatec-fn/xgmainc.f: Ditto.
+
+2002-08-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* odessa/odessa.f (ODESSA): Use XERRWD instead of XERR.
+	* odessa/intdy.f (ODESSA_INTDY): Likewise.
+	* odessa_rscom.f (ODESSA_RSCOM): Delete unused common block EH0001.
+	* odessa_svcom.f (ODESSA_SVCOM): Likewise.
+
+	* dasrt/xerrwv.f, odepack/xerrwv.f: Delete.
+	* slatec-err/xerrwd.f (XERRWD): Call XSTOPX instead of using STOP.
+
+	* quadpack/dqagi.f (DQAGI): Replace Hollerith constants with
+	character string constants.
+	* quadpack/dqagp.f (DQAGP): Likewise.
+	* odepack/lsode.f (LSODE): Likewise.
+
+	* odepack/lsode.f (LSODE): Use XERRWD instead of XERRWV.
+	* odepack/intdy.f (INTDY): Likewise.
+	* dasrt/ddasrt.f (DDASRT): Likewise.
+	* quadpack/xerror.f (XERROR): Likewise.
+
+2002-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-fn/xgmainc.f: New file.
+
+2002-07-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dasrt: New subdirectory.
+	* Makefile.in (CRUFT_DIRS): Add it to the list.
+
+2002-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* odessa: New subdirectory.
+	* Makefile.in (CRUFT_DIRS): Add it to the list.
+
+2002-06-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-err/xermsg.f (XERMSG): If MAXMES .LT. 0, messages may be
+	printed an unlimited number of times.
+	* slatec-err/j4save.f (J4SAVE) Default for MAXMES is now -1.
+
+	* misc/f77-fcn.c (xstopx): Pass args in proper order.
+
+2002-05-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ordered-qz/dsubsp.f (DSUBSP): Delete decl for unused variable J.
+
+	* misc/f77-fcn.c (xstopx): Return type is void, not volatile void.
+	* misc/f77-fcn.h (xstopx): Provide decl.  Add special gcc noreturn
+	attribute here.
+
+2002-05-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/f77-fcn.h: Define F77_FCN for backward compatibility.
+
+2002-04-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-err/ixsav.f, slatec-err/xerrwd.f: New files.
+
+	* daspk: New directory.
+	* Makefile.in (CRUFT_DIRS): Add it to the list
+
+2002-04-03  Steven G. Johnson <stevenj at alum.mit.edu>
+
+	* misc/machar.c: Use F77_FUNC instead of checking
+	F77_APPEND_UNDERSCORE.
+	* misc/f77-fcn.h: Don't define F77_FCN.
+	(xSTRINGIZE, STRINGIZE): New macros.
+	(F77_XFCN_ERROR): Simplify by using STRINGIZE and F77_FUNC.
+	(F77_XFCN): Use F77_FUNC instead of F77_FCN.
+	* misc/f77-fcn.c: Use F77_FUNC instead of F77_FCN.
+
+2001-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTSUBDIRS): Add fftpack.
+
+2001-08-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lapack/dlasq3.f: Update from netlib.
+	* lapack/dlasq5.f: Ditto.
+
+2001-05-02  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* Makefile.in (CRUFT_DIRS): Substitute @FFT_DIR at . 
+
+2001-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install): Don't use mk-libdir-link.
+
+2001-04-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (CPICDEP): Remove pic/dostop.o from the list.
+
+2001-03-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/xstopx.f: Delete.
+	* misc/dostop.c: Delete.
+	* misc/Makefile.in (SPECIAL, SPECIAL_DEPEND): Delete dostop.c and
+	dostop.o from lists.
+	* Makefile.in (MISC_OBJ): Delete misc/dostop.o from the list.
+
+	* misc/dostop.c (dostop): Use F77_FCN macro for function definition.
+	Specify length in error format to avoid need for copying string.
+	From Paul Kienzle <pkienzle at kienzle.powernet.co.uk>.
+
+2000-12-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lapack/dgelss.f (DGELSS): Use correct leading dimension for
+	workspace array passed to dgemm and dlacpy.
+	(ZGELSS): Likewise, for calls to zgemm and zlacpy.
+
+2000-07-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTSUBDIRS): New macro.
+	(dist): Use it instead of SUBDIRS.
+
+2000-06-30  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* blas-xtra, lapack-xtra: New directories.
+	* Makefile.in (CRUFT_DIRS): Add them to the list.
+	Substitute @BLAS_DIR@ and @LAPACK_DIR@ here.
+	* blas-xtra/xerbla.f: Move here from blas subdirectory.
+	* blas-xtra/Makefile.in: New file.
+	* lapack-xtra/xdlamch.f, lapack-xtra/xdlange.f,
+	lapack-xtra/xzlange.f: Move here from lapack subdirectory.
+	* lapack-xtra/Makefile.in: New file.
+
+2000-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (install, uninstall): Include files go in
+	$(octincludedir)/octave, not just $(octincludedir).
+
+2000-03-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (LIBRARIES): Conditionally define. 	
+	(libraries): Depend on $(SUBDIRS) only.
+	Make $(LIBRARIES) using a recursive invocation of make once
+	$(SUBDIRS) are up to date.
+	(.NOTPARALLEL): New target, for GNU Make 3.79.
+
+2000-03-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (libcruft.$(LIBEXT)): New target.
+	(all): Depend on `libraries', not `$(SUBDIRS) shared-lib'.
+	Conditionally construct `libraries' target.
+	(libcruft.$(SHLEXT_VER)): Delete target before rebuilding.
+	* Makerules.in (LIBCRUFT): Delete variable.
+	(LIBCRUFT_DEPEND): Conditionally define to $(LIBCRUFT_OBJS) only.
+	(all): Print warning if anything is done.
+	(stmp-pic): New target.
+	($CRUFT_PICOBJ): Depend on stmp-pic.
+	(clean, mostlyclean): Remove pic and stmp-pic.
+
+2000-02-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lapack/dbdsqr.f, lapack/dgeesv.f, lapack/dgelss.f,
+	lapack/dgesvd.f, lapack/dlasq1.f, lapack/dlasq2.f,
+	lapack/dlasq3.f, lapack/dlasq3.f, lapack/dlasq4.f,
+	lapack/dlasq5.f, lapack/dlasq6.f, lapack/zbdsqr.f,
+	lapack/zgelss.f, lapack/zgesvd.f, lapack/zhetd2.f:
+	Update from netlib.
+
+1999-11-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Update to Lapack version 3.0.
+	* lapack/ieeeck.f, lapack/dlasq2.f, lapack/dlasq3.f,
+	lapack/dlasq5.f, lapack/dlasq6.f: New files.
+
+1999-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/lo-error.cc (current_liboctave_warning_handler): Define	here.
+	(set_liboctave_warning_handler): New function.
+	(liboctave_warning): Ditto.
+	* misc/lo-error.h: Provide declararations for them here.
+
+1999-10-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (dist): Use `$(MAKE) -C dir' instead of `cd dir;
+	$(MAKE); cd ..'.
+
+1999-10-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dassl/dpotrf.f, dassl/dpotf2.f: Move to lapack subdirectory.
+
+Fri Mar 26 01:19:04 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makerules.in (all): Don't try to use a special rule for making
+	the archive.  The default rules may be slower, but they are also
+	correct.
+
+Wed Nov 11 17:27:35 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (CRUFT_DIRS): Add amos.  Delete specfun.
+	* specfun: Delete directory.
+	* amos: New directory
+
+Thu Oct 15 00:43:13 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ranlib: Update to newer version of randlib.
+	* ranlib/Makefile.in (SPECIAL): Update list.
+
+Thu Sep 24 11:59:02 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* balgen, eispack: Delete directories and unnecesary files.
+	* Makefile.in (CRUFT_DIRS): Delete eispack and balgen from the list.
+
+	* lapack/xdlamch.f: New file.
+
+	* ordered-qz: New directory.
+	* Makefile.in (CRUFT_DIRS): Add it to the list.
+
+	* lapack/dggbak.f, lapack/dtgevc.f, lapack/zggbal.f: New files.
+
+Tue Jun  2 09:57:52 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/rybesl.f (rybesl): Don't access by(2) unless nb .gt. 1.
+
+Mon May 11 12:33:42 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* fftpack/passb3.f, fftpack/passb5.f, fftpack/passf3.f,
+	fftpack/passf5.f: Use double precision constants in data
+	statements.
+
+Tue Apr 14 14:01:22 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-fn/xdgamit.f (xdgamit): New file.
+
+Mon Apr  6 00:26:35 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-fn/xdgami.f (xdgami): Reorder args to match dgami.
+
+Thu Feb 19 21:00:00 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/ribesl.f, specfun/rjbesl.f: Compute NSIG correctly.
+	Add missing comma in declaration statement.
+
+Sun Feb  1 12:39:10 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install, uninstall): Use $(octlibdir), not $(libdir).
+	Use $(mk-libdir-link).
+
+	* quadpack/dqagi.f, quadpack/dqagie.f, quadpack/dqagp.f,
+	quadpack/dqagpe.f, quadpack/dqk15i.f, quadpack/dqk21.f:
+	Make user-supplied code a subroutine instead of a function.
+
+Mon Jan 19 23:11:21 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lapack/xdlange.f, lapack/xzlange.f: New files.
+
+Mon Dec  1 00:51:03 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dassl/xerhlt.f, dassl/xermsg.f, dassl/xerprn.f, dassl/xgetua.f,
+	dassl/xsetua.f: Delete.
+
+	* slatec-err: New directory.
+	* Makefile.in: Add it to the list.
+
+Sun Nov 30 17:55:20 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-fn/xdgami.f, slatec-fn/xdbetai.f, slatec-fn/xderfc.f,
+	slatec-fn/xderf.f, slatec-fn/xdatanh.f, slatec-fn/xdasinh.f,
+	slatec-fn/xdacosh.f: New files.
+
+Sat Nov 29 13:02:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/ribesl.f (ribesl): Use d1mach to get machine parameters.
+	SAVE static data between calls.  Use PARAMETERS where possible.
+	* specfun/rjbesl.f (rjbesl): Likewise.
+	* specfun/rkbesl.f (rkbesl): Likewise.
+	* specfun/rybesl.f (rybesl): Likewise.
+
+Fri Nov 28 14:05:12 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun: New subdirectory.
+	* specfun/Makefile.in, specfun/ribesl.f, specfun/rjbesl.f,
+	specfun/rkbesl.f, specfun/rybesl.f: New files.
+	* Makefile.in (CRUFT_DIRS): Add specfun.
+
+Wed Nov 26 01:49:47 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-fn/d9gmit.f, slatec-fn/d9lgic.f, slatec-fn/d9lgit.f,
+	slatec-fn/dbetai.f, slatec-fn/dgami.f, slatec-fn/dgamit.f,
+	slatec-fn/dgamr.f, slatec-fn/dlbeta.f, slatec-fn/dlnrel.f:
+	New files for incomplete beta and incomplete gamma functions.
+
+Thu Jul 17 13:18:57 1997  Klaus Gebhardt <gebhardt at crunch.ikp.physik.th-darmstadt.de>
+
+	* blas/xerbla.f (xerbla): Call XSTOPX instead of using STOP.
+
+Fri Jun  6 16:49:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* slatec-fn/xdgamma.f: New file.
+
+	* fsqp, npsol, qpsol: Delete directories.
+	* Makefile.in (CRUFT_DIRS): Delete fsqp, npsol, and qpsol from list.
+
+Thu Jun  5 01:40:36 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, Makerules.in: Make building of static library optional.
+	(liboctave.$(SHLEXT_VER)): Add $(SONAME_FLAGS) to command.
+
+	* Makerules.in (stamp-picdir): Delete.
+	(pic): New target.  Don't worry so much about creating pic
+	directory only when it is really needed.
+
+	* Makefile.in (stamp-shared): Delete.
+	(shared-lib): New target.  Depend on shared libraries directly.
+
+Wed May 21 16:29:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (install): Ensure include directory link is made.
+	(uninstall): Delete all installed files. 
+
+Thu Mar 13 22:31:35 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* blas, lapack: Add new files for symmetric eigenvalue
+	computation.
+
+Wed Mar 12 16:59:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (install-strip): New target.
+
+	* Makefile.in (install-strip): New target.
+
+Mon Mar  3 15:38:39 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ranlib/Makefile.in (EXTERNAL_DISTFILES): Add Basegen.doc.
+
+	* fftpack/Makefile.in (EXTERNAL_DISTFILES): Add fftpack.doc.
+
+	* Makefile.in (DISTFILES): Add configure.in.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.5 released.
+
+Wed Feb 26 12:08:39 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (maintainer-clean): Also remove configure.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.3 released.
+
+Fri Feb 14 16:23:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (bin-dist): Don't write empty strings to LIBRARIES.
+
+Thu Feb 13 17:33:41 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-shared): Use $(SH_LD) $(SH_LDFLAGS) instead
+	of $(CXX) -shared.
+
+	* Makerules.in (stamp-picdir): Silence noise about making pic.
+
+Mon Jan 27 15:52:29 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+Sat Jan 25 22:34:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, balgen/Makefile.in, blas/Makefile.in,
+	cfsqp/Makefile.in, dassl/Makefile.in, eispack/Makefile.in,
+	fftpack/Makefile.in, fsqp/Makefile.in, lapack/Makefile.in,
+	linpack/Makefile.in, minpack/Makefile.in, misc/Makefile.in,
+	npsol/Makefile.in, odepack/Makefile.in, qpsol/Makefile.in,
+	quadpack/Makefile.in, ranlib/Makefile.in, slatec-fn/Makefile.in,
+	villad/Makefile.in (bin-dist): New target.
+
+Wed Jan 22 15:03:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (pic/machar.o): Add $(CPICFLAG) for this target.
+
+	* misc/d1mach.f (d1mach): Move SAVE statement ahead of DATA statment.
+
+Wed Jan 15 21:04:29 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* blas/*.f: Update to latest version from Netlib.
+
+Tue Jan  7 00:17:17 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Tue Dec 17 11:02:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/lo-error.c: Convert C++-style comments to C-style comments.
+
+Wed Dec 11 01:50:31 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (SPECIAL_DEPEND): Delete d1mach.o from the list.
+
+Tue Dec 10 01:43:10 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+Fri Dec  6 15:23:50 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.94.
+
+Wed Nov 20 01:00:43 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (install): Also install lo-error.h.
+
+	* Makefile.in (MISC_OBJ): Add misc/f77-fcn.o.
+
+	* misc/lo-error.h: New file, moved here from liboctave.
+	* misc/lo-error.c: Rename from lo-error.cc.  Make this a C-file
+	instead of C++.
+
+	* Version 1.93.
+
+Tue Nov 19 23:04:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in: Add variables for installing things.
+
+	* Makerules.in (install, uninstall): Make these double colon rules.
+
+	* f77-fcn.c, f77-fcn.h: New files, from liboctave.
+
+	* misc/Makefile.in (SPECIAL_DEPEND): Add f77-fcn.o.
+	(SPECIAL): Add f77-fcn.c and f77-fcn.h.
+	(CPICDEP): Add pic/f77-fcn.o.
+	(install): Install f77-fcn.h in $(octincludedir).
+	(uninstall): Delete f77-fcn.h from $(octincludedir).
+
+	* Makerules.in (CRUFT_CSRC): Delete unsed variable.
+
+Thu Nov 14 00:07:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.92.
+
+Fri Nov  8 09:55:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (libcruft.a): Delete target.
+	* Makerules.in, Makefile.in: Use real archive rules to build
+	libcruft.a in parts.
+
+	* Makefile.in (install): Use $(INSTALL_PROGRAM) for installing
+	shared library.
+
+Thu Nov  7 12:43:17 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Add -lm when building shared library.
+
+	* Version 1.91.
+
+Mon Nov  4 10:09:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lapack/dlag2.f, lapack/dggbal.f, lapack/dgghrd.f, lapack/dhgeqz.f:
+	New files.
+
+	* Makefile.in (install): Use INSTALL_PROGRAM for shared version of
+	libcruft.	
+
+Sun Nov  3 19:37:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in (distclean): Delete target, since there is
+	nothing special to do.
+
+Wed Oct 30 17:20:14 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* Makefile.in (DISTFILES): Add ChangeLog.
+
+	* misc/Makefile.in: Make pic/machar.o using special rule.
+	Use CPPFLAGS, not CPP_FLAGS.
+
+Thu Oct 24 20:22:47 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (CRUFT_OBJ): No special treatment for d1mach.o.
+
+	* misc/machar.c, misc/d1mach.f: New files
+	* misc/Makefile.in: Fix to not generate d1mach.f.
+
+Mon Oct 14 11:07:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (distclean): Remove stamp-shared too.
+
+Sat Oct 12 00:20:41 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (maintainer-clean): Don't depend on distclean.
+	* Makerules.in (maintainer-clean): Ditto.
+
+Tue Aug 20 22:09:08 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makerules.in (stamp-picdir): Only create a pic subdirectory if
+	SHARED_LIBS is true AND FPICFLAG is not empty.
+
+Wed May 22 15:07:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-shared): Use CC, not CXX to create shared
+	library.  Also use SHARED_FLIBS here instead of FLIBS.
+
+Sat Apr  6 21:28:47 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makerules.in (clean, mostlyclean): Also remove pic/*.o.
+	(maintainer-clean, distclean): Also remove stamp-picdir and pic
+	directory.
+
+Wed Apr  3 01:01:31 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/Makefile.in: Set SPECIAL_PICDEPEND after including Makeconf
+	and before including Makerules.
+
+Fri Mar 29 13:45:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (distclean): Delete so_locations, which is created
+	on DEC Alpha systems.
+	(distclean, maintainer-clean): Don't depend on clean.
+
+Wed Mar 27 05:59:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makerules.in: Add rules for making PIC code here.
+	* Makefile.in (libcruft.a): Depend on $(CRUFT_PICOBJ)
+	* misc/Makefile.in: Add rules for making PIC code from C and C++
+	files.
+
+Fri Feb  9 21:04:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/f77-extern.cc, misc/lo-error.cc: New files.
+	* misc/Makefile.in (SPECIAL, SPECIAL_DEPEND): Add them to the lists.
+	* Makefile.in (CRUFT_OBJ): Add it f77-extern.o and lo-error.o here
+	too.
+
+Sat Feb  3 07:57:39 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/dostop.c (dostop): Call error handler if we have a message.
+	Call longjmp on f77_context, not jump_to_top_level().
+	* misc/xstopx.f (xstopx): Pass non-blank strings on to dostop.
+
+Mon Jan  8 22:55:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (clean): If $(SHARED_LIBS), remove shared libs.
+	(mostlyclean): Ditto.
+
+Fri Dec 29 21:43:24 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, Makerules.in: Handle creating position independent
+	code and shared libraries for Octave.
+
+Tue Dec 26 00:15:31 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makerules.in (stamp-picdir): New target.
+	(all): Depend on it.
+
+	* Makefile.in: Delete references to configure stuff.
+	* configure.in, mkinstalldirs: Delete.
+	
+Sun Dec 24 02:42:29 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linpack/spofa.f: New file.
+	* blas/level-1/sdot.f: New file.
+	* blas/level-2/dsyr.f: New file.
+
+Thu Dec 14 02:34:19 1995  Rick Niles  <niles at axp745.gsfc.nasa.gov>
+
+	* fftpack/cfftb1.f, fftpack/cfftf1.f, fftpack/cffti1.f,
+	odepack/prepj.f, odepack/solsy.f, odepack/stode.f:
+	Avoid warnings for nonstandard dimension statements of the form
+	`real foo(1)' by using `real foo(*)' instead.
+
+Mon Nov  6 07:24:03 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/dostop.c: Only call jump_to_top_level() if OCTAVE_SOURCE.
+
+Fri Nov  3 11:08:31 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* misc/dostop.c: Just call jump_to_top_level() directly here.
+
+Wed Sep 20 00:01:03 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkinstalldirs: New file.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+	* Makerules.in: Fix cleaning rules.  Use double colon so we can
+	add things in the makefiles in the subdirectories.
+
+	* Makefile.in (DISTFILES): Distribute configure.in and configure.
+	(distclean): Also remove Makerules, config.log, and config.status.
+	(maintainer-clean): Depend on distclean.
+
+Mon Apr 10 09:55:13 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: New file.
+
+Fri Mar 10 10:38:29 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (install uninstall clean mostlyclean distclean
+	realclean): Use SUBDIR_FOR_COMMAND.  Combine actions.
+
+See ChangeLog.1 in the top level directory for earlier changes.
diff --git a/libcruft/Makefile.in b/libcruft/Makefile.in
new file mode 100644
index 0000000..23097fd
--- /dev/null
+++ b/libcruft/Makefile.in
@@ -0,0 +1,206 @@
+# Makefile for octave's libcruft directory
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+#               2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# List of the directories that contain Fortran source.  Simply copying
+# a new .f file into one of these directories is sufficient to have it
+# added to $(LIBPRE)cruft.a.  If you add a new directory here, you also need
+# generate a new configure script in the top-level directory (edit
+# configure.in and run autoconf).
+
+# Some of the directories in libcruft may be only optionally built,
+# e.g. if they are already present on the system.  For these, their
+# dirname is substituted by configure and may be the empty string.
+
+CRUFT_DIRS = amos @BLAS_DIR@ blas-xtra daspk dasrt dassl \
+	@FFT_DIR@ @LAPACK_DIR@ lapack-xtra \
+	misc odepack ordered-qz quadpack ranlib \
+	slatec-err slatec-fn villad
+
+SUBDIRS = $(CRUFT_DIRS)
+
+DISTSUBDIRS = $(sort $(CRUFT_DIRS) blas fftpack lapack)
+
+CLEAN_SUBDIRS = $(DISTSUBDIRS)
+
+DISTFILES = Makefile.in ChangeLog Makerules.in $(SOURCES) \
+	STOP.patch mkf77def.in
+
+XTRA_CRUFT_SH_LDFLAGS = @XTRA_CRUFT_SH_LDFLAGS@
+SH_LDFLAGS += $(XTRA_CRUFT_SH_LDFLAGS)
+
+# Include BLAS and FFTW just in case some of libcruft depends on them
+LINK_DEPS = $(BLAS_LIBS) $(FFTW_LIBS) $(FLIBS)
+
+all: libraries
+.PHONY: all
+
+mkf77def: mkf77def.in $(TOPDIR)/Makeconf
+	@$(do-subst-f77-mangling)
+	chmod a+rx $@
+
+$(SUBDIRS): mkf77def
+	$(MAKE) -C $@ all
+.PHONY: $(SUBDIRS)
+
+# FIXME -- this should build the shared library directly from
+# a normal archive file (created from PIC code, though).
+
+MISC_OBJ := misc/f77-extern.o misc/f77-fcn.o misc/lo-error.o \
+  misc/quit.o misc/cquit.o
+
+CRUFT_FSRC := $(foreach dir, $(SUBDIRS), $(wildcard $(srcdir)/$(dir)/*.f))
+CRUFT_OBJ2 := $(patsubst $(srcdir)/%, %, $(CRUFT_FSRC))
+CRUFT_OBJ1 := $(patsubst %.f, %.o, $(CRUFT_OBJ2))
+CRUFT_OBJ := $(CRUFT_OBJ1) $(MISC_OBJ)
+CRUFT_DEFS := $(patsubst %.f, %.def, $(CRUFT_OBJ2))
+
+ifeq ($(SHARED_LIBS), true)
+  ifdef FPICFLAG
+    CRUFT_OBJ_DIR := $(dir $(CRUFT_OBJ))
+    CRUFT_OBJ_PICDIR := $(addsuffix pic/, $(CRUFT_OBJ_DIR))
+    CRUFT_OBJ_NOTDIR := $(notdir $(CRUFT_OBJ))
+    CRUFT_PICOBJ := $(join $(CRUFT_OBJ_PICDIR), $(CRUFT_OBJ_NOTDIR))
+  else
+    CRUFT_PICOBJ := $(CRUFT_OBJ)
+  endif
+endif
+
+ifeq ($(SHARED_LIBS), true)
+  ifeq ($(STATIC_LIBS), true)
+    LIBRARIES = $(LIBPRE)cruft.$(LIBEXT) $(SHLPRE)cruft.$(SHLEXT_VER)
+  else
+    LIBRARIES = $(SHLPRE)cruft.$(SHLEXT_VER)
+  endif
+else
+  ifeq ($(STATIC_LIBS), true)
+    LIBRARIES = $(LIBPRE)cruft.$(LIBEXT)
+  else
+    LIBRARIES =
+  endif
+endif
+
+$(CRUFT_DEFS): $(SUBDIRS)
+
+cruft.def: $(CRUFT_DEFS)
+	echo "EXPORTS" > $@
+	cat $(CRUFT_DEFS) >> $@
+
+libraries: cruft.def
+	$(MAKE) $(LIBRARIES)
+.PHONY: libraries
+
+$(LIBPRE)cruft.$(LIBEXT): $(CRUFT_OBJ)
+	rm -f $@
+	$(AR) $(ARFLAGS) $@ $^
+	$(RANLIB) $@
+
+$(SHLPRE)cruft.$(SHLEXT_VER): $(SHLPRE)cruft.$(SHLEXT)
+	rm -f $@
+	$(LN_S) $< $@
+
+$(SHLPRE)cruft.$(SHLEXT): $(CRUFT_PICOBJ)
+	rm -f $@
+	$(SH_LD) $(SH_LDFLAGS) $(SONAME_FLAGS) -o $@ $^ $(LINK_DEPS)
+
+$(CRUFT_OBJ):
+
+check: all
+.PHONY: check
+
+install install-strip uninstall::
+	@$(subdir-for-command)
+
+clean mostlyclean distclean maintainer-clean::
+	@$(foreach d, $(CLEAN_SUBDIRS), $(do-subdir-for-command))
+
+install::
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octlibdir)
+	if $(STATIC_LIBS); then \
+	  rm -f $(DESTDIR)$(octlibdir)/$(LIBPRE)cruft.$(LIBEXT) ; \
+	  $(INSTALL_DATA) $(LIBPRE)cruft.$(LIBEXT) \
+	    $(DESTDIR)$(octlibdir)/$(LIBPRE)cruft.$(LIBEXT) ; \
+	  $(RANLIB) $(DESTDIR)$(octlibdir)/$(LIBPRE)cruft.$(LIBEXT) ; \
+	fi
+	if $(SHARED_LIBS); then \
+	  rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)cruft.$(SHLLIB_VER); \
+	  $(INSTALL) \
+	    $(SHLLIBPRE)cruft.$(SHLLIB) $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)cruft.$(SHLLIB_VER); \
+	  rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)cruft.$(SHLLIB); \
+	  (cd $(DESTDIR)$(octlibdir); \
+	  $(LN_S) $(SHLLIBPRE)cruft.$(SHLLIB_VER) $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)cruft.$(SHLLIB)); \
+	  if  test x$(SHLBIN) != x ; then \
+	    rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)cruft.$(SHLBIN); \
+	    $(INSTALL_PROGRAM) \
+	      $(SHLBINPRE)cruft.$(SHLBIN) $(DESTDIR)$(bindir)/$(SHLBINPRE)cruft.$(SHLBIN); \
+	  fi; \
+	fi
+
+install-strip::
+	$(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM) -s" install
+
+uninstall::
+	rm -f $(DESTDIR)$(octlibdir)/$(LIBPRE)cruft.$(LIBEXT)
+	rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)cruft.$(SHLLIB)
+	rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)cruft.$(SHLLIB_VER)
+	if test x$(SHLBIN) != x; then \
+	  rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)cruft.$(SHLBIN); \
+	  rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)cruft.$(SHLBIN_VER); \
+	fi
+
+tags TAGS:: $(SOURCES)
+	$(SUBDIR_FOR_COMMAND)
+
+tags::
+	ctags $(SOURCES)
+
+TAGS:: $(SOURCES)
+	etags $(SOURCES)
+
+clean mostlyclean distclean maintainer-clean::
+	rm -f $(LIBPRE)cruft.$(LIBEXT)
+	rm -f $(SHLPRE)cruft.$(SHLEXT_VER) $(SHLPRE)cruft.$(SHLEXT)
+	rm -f $(SHLBINPRE)cruft.$(SHLBIN_VER) $(SHLBINPRE)cruft.$(SHLBIN)
+	rm -f $(CRUFT_DEFS) cruft.def mkf77def
+
+distclean maintainer-clean::
+	rm -f Makefile Makerules so_locations
+
+maintainer-clean::
+	rm -f tags TAGS
+
+dist:
+	for dir in $(DISTSUBDIRS); do mkdir ../`cat ../.fname`/libcruft/$$dir; $(MAKE) -C $$dir $@; done
+	ln $(addprefix $(srcdir)/, $(DISTFILES)) ../`cat ../.fname`/libcruft
+.PHONY: dist
+
+.NOTPARALLEL:
diff --git a/libcruft/Makerules.in b/libcruft/Makerules.in
new file mode 100644
index 0000000..8971d3c
--- /dev/null
+++ b/libcruft/Makerules.in
@@ -0,0 +1,145 @@
+# @configure_input@
+#
+# Common rules for octave's libcruft directories.
+#
+# FIXME -- assumes that the libcruft directory tree is only
+# one level deep.
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2003, 2005,
+#               2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+DLL_CDEFS = @CRUFT_DLL_DEFS@
+DLL_CXXDEFS = @CRUFT_DLL_DEFS@
+
+CRUFT_FSRC = $(addprefix $(srcdir)/, $(FSRC))
+CRUFT_CSRC = $(addprefix $(srcdir)/, $(CSRC) $(CEXTRA))
+CRUFT_CXXSRC = $(addprefix $(srcdir)/, $(CXXSRC))
+
+CRUFT_SRC = $(CRUFT_FSRC) $(CRUFT_CSRC) $(CRUFT_CXXSRC)
+
+CRUFT_FBASE = $(basename $(notdir $(CRUFT_FSRC)))
+CRUFT_CBASE = $(basename $(notdir $(CRUFT_CSRC)))
+CRUFT_CXXBASE = $(basename $(notdir $(CRUFT_CXXSRC)))
+
+CRUFT_BASE = $(CRUFT_FBASE) $(CRUFT_CBASE) $(CRUFT_CXXBASE)
+
+CRUFT_FOBJ = $(addsuffix .o, $(CRUFT_FBASE))
+CRUFT_COBJ = $(addsuffix .o, $(CRUFT_CBASE))
+CRUFT_CXXOBJ = $(addsuffix .o, $(CRUFT_CXXBASE))
+
+CRUFT_OBJ = $(CRUFT_FOBJ) $(CRUFT_COBJ) $(CRUFT_CXXOBJ)
+
+CRUFT_FDEFS = $(patsubst %.f, %.def, $(notdir $(CRUFT_FSRC)))
+CRUFT_CDEFS = $(patsubst %.c, %.def, $(notdir $(CRUFT_CSRC)))
+CRUFT_CXXDEFS = $(patsubst %.cc, %.def, $(notdir $(CRUFT_CXXSRC)))
+
+CRUFT_DEFS = $(CRUFT_FDEFS) $(CRUFT_CDEFS) $(CRUFT_CXXDEFS)
+
+DISTFILES = $(CRUFT_SRC) $(addprefix $(srcdir)/, Makefile.in $(SPECIAL))
+
+ifeq ($(SHARED_LIBS), true)
+  ifdef FPICFLAG
+    CRUFT_FPICOBJ := $(addprefix pic/, $(CRUFT_FOBJ))
+  else
+    CRUFT_FPICOBJ := $(CRUFT_FOBJ)
+  endif
+  ifdef CPICFLAG
+    CRUFT_CPICOBJ := $(addprefix pic/, $(CRUFT_COBJ) $(CEXTRA))
+  else
+    CRUFT_CPICOBJ := $(CRUFT_COBJ) $(CEXTRA)
+  endif
+  ifdef CXXPICFLAG
+    CRUFT_CXXPICOBJ := $(addprefix pic/, $(CRUFT_CXXOBJ))
+  else
+    CRUFT_CXXPICOBJ := $(CRUFT_CXXOBJ)
+  endif
+  CRUFT_PICOBJ := $(CRUFT_FPICOBJ) $(CRUFT_CPICOBJ) $(CRUFT_CXXPICOBJ)
+endif
+
+CWD = $(shell pwd)
+THISDIR = $(notdir $(CWD))
+
+ifeq ($(STATIC_LIBS), true)
+  LIBCRUFT_DEPEND := $(CRUFT_OBJ)
+.PRECIOUS: $(CRUFT_OBJ)
+endif
+
+ifeq ($(SHARED_LIBS), true)
+  LIBCRUFT_PICDEPEND := $(CRUFT_PICOBJ)
+.PRECIOUS: $(CRUFT_PICOBJ)
+endif
+
+all: pic $(CRUFT_DEFS) $(LIBCRUFT_DEPEND) $(LIBCRUFT_PICDEPEND)
+	@echo "warning: run make in parent directory to update libraries"
+.PHONY: all
+
+stmp-pic: pic
+	@if [ -f stmp-pic ]; then \
+	  true; \
+	else \
+	  echo "touch stmp-pic"; \
+	  touch stmp-pic; \
+	fi
+
+pic:
+	@if [ -d pic ]; then \
+	  true; \
+	else \
+	  echo "mkdir pic"; \
+	  mkdir pic; \
+	fi
+
+$(CRUFT_PICOBJ): stmp-pic
+
+$(CRUFT_DEFS): $(TOPDIR)/libcruft/mkf77def
+
+%.def : %.f
+	@echo "making $@ from $<"
+	@$(TOPDIR)/libcruft/mkf77def < $< > $@-t
+	@mv $@-t $@
+
+install:: all
+.PHONY: install
+
+install-strip:: all
+.PHONY: install-strip
+
+uninstall::
+.PHONY: uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+clean mostlyclean distclean maintainer-clean::
+	rm -f $(MAKEDEPS) $(CRUFT_OBJ) $(CRUFT_PICOBJ) $(CRUFT_DEFS)
+	-rmdir pic
+	rm -f stmp-pic
+.PHONY: clean mostlyclean
+
+distclean maintainer-clean::
+	rm -f tags TAGS Makefile
+.PHONY: distclean maintainer-clean
+
+dist:
+	ln $(EXTERNAL_DISTFILES) ../../`cat ../../.fname`/libcruft/$(THISDIR)
+.PHONY: dist
diff --git a/libcruft/STOP.patch b/libcruft/STOP.patch
new file mode 100644
index 0000000..5976110
--- /dev/null
+++ b/libcruft/STOP.patch
@@ -0,0 +1,423 @@
+This patch replaces all STOP statements with calls to XSTOPX so that
+Fortran routines won't be able to kill Octave.
+
+If you decide not to use the versions of the Fortran subroutines that
+are distributed with Octave, you might want to apply this patch (or
+something like it) to your sources.
+
+John W. Eaton
+jwe at octave.org
+
+diff -rc libcruft.orig/blas/xerbla.f libcruft/blas/xerbla.f
+*** libcruft.orig/blas/xerbla.f	Wed Feb 19 21:46:03 1992
+--- libcruft/blas/xerbla.f	Mon Jun  7 14:33:52 1993
+***************
+*** 35,41 ****
+  *
+        WRITE (*,99999) SRNAME, INFO
+  *
+!       STOP
+  *
+  99999 FORMAT ( ' ** On entry to ', A6, ' parameter number ', I2,
+       $         ' had an illegal value' )
+--- 35,41 ----
+  *
+        WRITE (*,99999) SRNAME, INFO
+  *
+!       CALL XSTOPX (' ')
+  *
+  99999 FORMAT ( ' ** On entry to ', A6, ' parameter number ', I2,
+       $         ' had an illegal value' )
+diff -rc libcruft.orig/dassl/xerhlt.f libcruft/dassl/xerhlt.f
+*** libcruft.orig/dassl/xerhlt.f	Wed Feb 19 23:46:22 1992
+--- libcruft/dassl/xerhlt.f	Mon Jun  7 14:34:44 1993
+***************
+*** 33,37 ****
+  C***END PROLOGUE  XERHLT
+        CHARACTER*(*) MESSG
+  C***FIRST EXECUTABLE STATEMENT  XERHLT
+!       STOP
+        END
+--- 33,37 ----
+  C***END PROLOGUE  XERHLT
+        CHARACTER*(*) MESSG
+  C***FIRST EXECUTABLE STATEMENT  XERHLT
+!       CALL XSTOPX (MESSG)
+        END
+diff -rc libcruft.orig/misc/i1mach.f libcruft/misc/i1mach.f
+*** libcruft.orig/misc/i1mach.f	Tue Jul 21 22:31:59 1992
+--- libcruft/misc/i1mach.f	Mon Jun  7 14:36:50 1993
+***************
+*** 523,527 ****
+        RETURN
+     10 WRITE(OUTPUT,1999) I
+   1999 FORMAT(' I1MACH - I OUT OF BOUNDS',I10)
+!       STOP
+        END
+--- 523,527 ----
+        RETURN
+     10 WRITE(OUTPUT,1999) I
+   1999 FORMAT(' I1MACH - I OUT OF BOUNDS',I10)
+!       CALL XSTOPX (' ')
+        END
+diff -rc libcruft.orig/odepack/xerrwv.f libcruft/odepack/xerrwv.f
+*** libcruft.orig/odepack/xerrwv.f	Wed Feb 19 23:50:24 1992
+--- libcruft/odepack/xerrwv.f	Mon Jun  7 14:38:00 1993
+***************
+*** 109,114 ****
+   50   FORMAT(6X,15HIN ABOVE,  R1 =,D21.13,3X,4HR2 =,D21.13) 
+  C ABORT THE RUN IF LEVEL = 2. ------------------------------------------
+   100  IF (LEVEL .NE. 2) RETURN
+!       STOP
+  C----------------------- END OF SUBROUTINE XERRWV ----------------------
+        END 
+--- 109,114 ----
+   50   FORMAT(6X,15HIN ABOVE,  R1 =,D21.13,3X,4HR2 =,D21.13) 
+  C ABORT THE RUN IF LEVEL = 2. ------------------------------------------
+   100  IF (LEVEL .NE. 2) RETURN
+!       CALL XSTOPX (' ')
+  C----------------------- END OF SUBROUTINE XERRWV ----------------------
+        END 
+diff -rc libcruft.orig/ranlib/advnst.f libcruft/ranlib/advnst.f
+*** libcruft.orig/ranlib/advnst.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/advnst.f	Mon Jun  7 15:35:37 1993
+***************
+*** 60,66 ****
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' ADVNST called before random number generator ',
+       +  ' initialized -- abort!'
+!       STOP ' ADVNST called before random number generator initialized'
+  
+     10 CALL getcgn(g)
+  C
+--- 60,67 ----
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' ADVNST called before random number generator ',
+       +  ' initialized -- abort!'
+!       CALL XSTOPX
+!      + (' ADVNST called before random number generator initialized')
+  
+     10 CALL getcgn(g)
+  C
+diff -rc libcruft.orig/ranlib/genbet.f libcruft/ranlib/genbet.f
+*** libcruft.orig/ranlib/genbet.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/genbet.f	Mon Jun  7 15:35:23 1993
+***************
+*** 67,73 ****
+        IF (.NOT. (aa.LE.0.0.OR.bb.LE.0.0)) GO TO 10
+        WRITE (*,*) ' AA or BB <= 0 in GENBET - Abort!'
+        WRITE (*,*) ' AA: ',aa,' BB ',bb
+!       STOP ' AA or BB <= 0 in GENBET - Abort!'
+  
+     10 olda = aa
+        oldb = bb
+--- 67,73 ----
+        IF (.NOT. (aa.LE.0.0.OR.bb.LE.0.0)) GO TO 10
+        WRITE (*,*) ' AA or BB <= 0 in GENBET - Abort!'
+        WRITE (*,*) ' AA: ',aa,' BB ',bb
+!       CALL XSTOPX (' AA or BB <= 0 in GENBET - Abort!')
+  
+     10 olda = aa
+        oldb = bb
+diff -rc libcruft.orig/ranlib/genchi.f libcruft/ranlib/genchi.f
+*** libcruft.orig/ranlib/genchi.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/genchi.f	Mon Jun  7 15:35:17 1993
+***************
+*** 37,43 ****
+        IF (.NOT. (df.LE.0.0)) GO TO 10
+        WRITE (*,*) 'DF <= 0 in GENCHI - ABORT'
+        WRITE (*,*) 'Value of DF: ',df
+!       STOP 'DF <= 0 in GENCHI - ABORT'
+  
+     10 genchi = 2.0*gengam(1.0,df/2.0)
+        RETURN
+--- 37,43 ----
+        IF (.NOT. (df.LE.0.0)) GO TO 10
+        WRITE (*,*) 'DF <= 0 in GENCHI - ABORT'
+        WRITE (*,*) 'Value of DF: ',df
+!       CALL XSTOPX ('DF <= 0 in GENCHI - ABORT')
+  
+     10 genchi = 2.0*gengam(1.0,df/2.0)
+        RETURN
+diff -rc libcruft.orig/ranlib/genf.f libcruft/ranlib/genf.f
+*** libcruft.orig/ranlib/genf.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/genf.f	Mon Jun  7 15:35:07 1993
+***************
+*** 44,50 ****
+        IF (.NOT. (dfn.LE.0.0.OR.dfd.LE.0.0)) GO TO 10
+        WRITE (*,*) 'Degrees of freedom nonpositive in GENF - abort!'
+        WRITE (*,*) 'DFN value: ',dfn,'DFD value: ',dfd
+!       STOP 'Degrees of freedom nonpositive in GENF - abort!'
+  
+     10 xnum = genchi(dfn)/dfn
+  C      GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD )
+--- 44,50 ----
+        IF (.NOT. (dfn.LE.0.0.OR.dfd.LE.0.0)) GO TO 10
+        WRITE (*,*) 'Degrees of freedom nonpositive in GENF - abort!'
+        WRITE (*,*) 'DFN value: ',dfn,'DFD value: ',dfd
+!       CALL XSTOPX ('Degrees of freedom nonpositive in GENF - abort!')
+  
+     10 xnum = genchi(dfn)/dfn
+  C      GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD )
+diff -rc libcruft.orig/ranlib/gennch.f libcruft/ranlib/gennch.f
+*** libcruft.orig/ranlib/gennch.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/gennch.f	Mon Jun  7 15:34:58 1993
+***************
+*** 48,54 ****
+        IF (.NOT. (df.LE.1.0.OR.xnonc.LT.0.0)) GO TO 10
+        WRITE (*,*) 'DF <= 1 or XNONC < 0 in GENNCH - ABORT'
+        WRITE (*,*) 'Value of DF: ',df,' Value of XNONC',xnonc
+!       STOP 'DF <= 1 or XNONC < 0 in GENNCH - ABORT'
+  
+     10 gennch = genchi(df-1.0) + gennor(sqrt(xnonc),1.0)**2
+        RETURN
+--- 48,54 ----
+        IF (.NOT. (df.LE.1.0.OR.xnonc.LT.0.0)) GO TO 10
+        WRITE (*,*) 'DF <= 1 or XNONC < 0 in GENNCH - ABORT'
+        WRITE (*,*) 'Value of DF: ',df,' Value of XNONC',xnonc
+!       CALL XSTOPX ('DF <= 1 or XNONC < 0 in GENNCH - ABORT')
+  
+     10 gennch = genchi(df-1.0) + gennor(sqrt(xnonc),1.0)**2
+        RETURN
+diff -rc libcruft.orig/ranlib/gennf.f libcruft/ranlib/gennf.f
+*** libcruft.orig/ranlib/gennf.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/gennf.f	Mon Jun  7 15:56:26 1993
+***************
+*** 56,62 ****
+        WRITE (*,*) '(3) Noncentrality parameter < 0.0'
+        WRITE (*,*) 'DFN value: ',dfn,'DFD value: ',dfd,'XNONC value: ',
+       +  xnonc
+!       STOP 'Degrees of freedom or noncent param our of range in GENNF'
+  
+     10 xnum = gennch(dfn,xnonc)/dfn
+  C      GENNF = ( GENNCH( DFN, XNONC ) / DFN ) / ( GENCHI( DFD ) / DFD )
+--- 56,63 ----
+        WRITE (*,*) '(3) Noncentrality parameter < 0.0'
+        WRITE (*,*) 'DFN value: ',dfn,'DFD value: ',dfd,'XNONC value: ',
+       +  xnonc
+!       CALL XSTOPX
+!      + ('Degrees of freedom or noncent param our of range in GENNF')
+  
+     10 xnum = gennch(dfn,xnonc)/dfn
+  C      GENNF = ( GENNCH( DFN, XNONC ) / DFN ) / ( GENCHI( DFD ) / DFD )
+diff -rc libcruft.orig/ranlib/genunf.f libcruft/ranlib/genunf.f
+*** libcruft.orig/ranlib/genunf.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/genunf.f	Mon Jun  7 15:34:37 1993
+***************
+*** 33,39 ****
+        IF (.NOT. (low.GT.high)) GO TO 10
+        WRITE (*,*) 'LOW > HIGH in GENUNF: LOW ',low,' HIGH: ',high
+        WRITE (*,*) 'Abort'
+!       STOP 'LOW > High in GENUNF - Abort'
+  
+     10 genunf = low + (high-low)*ranf()
+  
+--- 33,39 ----
+        IF (.NOT. (low.GT.high)) GO TO 10
+        WRITE (*,*) 'LOW > HIGH in GENUNF: LOW ',low,' HIGH: ',high
+        WRITE (*,*) 'Abort'
+!       CALL XSTOPX ('LOW > High in GENUNF - Abort')
+  
+     10 genunf = low + (high-low)*ranf()
+  
+diff -rc libcruft.orig/ranlib/getcgn.f libcruft/ranlib/getcgn.f
+*** libcruft.orig/ranlib/getcgn.f	Wed Apr 22 08:49:00 1992
+--- libcruft/ranlib/getcgn.f	Mon Jun  7 15:34:31 1993
+***************
+*** 47,53 ****
+        IF (.NOT. (g.LT.0.OR.g.GT.numg)) GO TO 10
+        WRITE (*,*) ' Generator number out of range in SETCGN:',
+       +  ' Legal range is 1 to ',numg,' -- ABORT!'
+!       STOP ' Generator number out of range in SETCGN'
+  
+     10 curntg = g
+        RETURN
+--- 47,53 ----
+        IF (.NOT. (g.LT.0.OR.g.GT.numg)) GO TO 10
+        WRITE (*,*) ' Generator number out of range in SETCGN:',
+       +  ' Legal range is 1 to ',numg,' -- ABORT!'
+!       CALL XSTOPX (' Generator number out of range in SETCGN')
+  
+     10 curntg = g
+        RETURN
+diff -rc libcruft.orig/ranlib/getsd.f libcruft/ranlib/getsd.f
+*** libcruft.orig/ranlib/getsd.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/getsd.f	Mon Jun  7 15:34:23 1993
+***************
+*** 62,68 ****
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' GETSD called before random number generator ',
+       +  ' initialized -- abort!'
+!       STOP ' GETSD called before random number generator initialized'
+  
+     10 CALL getcgn(g)
+        iseed1 = cg1(g)
+--- 62,69 ----
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' GETSD called before random number generator ',
+       +  ' initialized -- abort!'
+!       CALL XSTOPX
+!      + (' GETSD called before random number generator initialized')
+  
+     10 CALL getcgn(g)
+        iseed1 = cg1(g)
+diff -rc libcruft.orig/ranlib/ignuin.f libcruft/ranlib/ignuin.f
+*** libcruft.orig/ranlib/ignuin.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/ignuin.f	Mon Jun  7 15:34:09 1993
+***************
+*** 94,100 ****
+    100 WRITE (*,*) ' LOW: ',low,' HIGH: ',high
+        WRITE (*,*) ' Abort on Fatal ERROR'
+        IF (.NOT. (err.EQ.1)) GO TO 110
+!       STOP 'LOW > HIGH in IGNUIN'
+  
+        GO TO 120
+  
+--- 94,100 ----
+    100 WRITE (*,*) ' LOW: ',low,' HIGH: ',high
+        WRITE (*,*) ' Abort on Fatal ERROR'
+        IF (.NOT. (err.EQ.1)) GO TO 110
+!       CALL XSTOPX ('LOW > HIGH in IGNUIN')
+  
+        GO TO 120
+  
+diff -rc libcruft.orig/ranlib/initgn.f libcruft/ranlib/initgn.f
+*** libcruft.orig/ranlib/initgn.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/initgn.f	Mon Jun  7 15:34:03 1993
+***************
+*** 66,72 ****
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' INITGN called before random number generator ',
+       +  ' initialized -- abort!'
+!       STOP ' INITGN called before random number generator initialized'
+  
+     10 CALL getcgn(g)
+        IF ((-1).NE. (isdtyp)) GO TO 20
+--- 66,73 ----
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' INITGN called before random number generator ',
+       +  ' initialized -- abort!'
+!       CALL XSTOPX
+!      + (' INITGN called before random number generator initialized')
+  
+     10 CALL getcgn(g)
+        IF ((-1).NE. (isdtyp)) GO TO 20
+diff -rc libcruft.orig/ranlib/mltmod.f libcruft/ranlib/mltmod.f
+*** libcruft.orig/ranlib/mltmod.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/mltmod.f	Mon Jun  7 15:33:49 1993
+***************
+*** 39,45 ****
+        WRITE (*,*) ' A, M, S out of order in MLTMOD - ABORT!'
+        WRITE (*,*) ' A = ',a,' S = ',s,' M = ',m
+        WRITE (*,*) ' MLTMOD requires: 0 < A < M; 0 < S < M'
+!       STOP ' A, M, S out of order in MLTMOD - ABORT!'
+  
+     10 IF (.NOT. (a.LT.h)) GO TO 20
+        a0 = a
+--- 39,45 ----
+        WRITE (*,*) ' A, M, S out of order in MLTMOD - ABORT!'
+        WRITE (*,*) ' A = ',a,' S = ',s,' M = ',m
+        WRITE (*,*) ' MLTMOD requires: 0 < A < M; 0 < S < M'
+!       CALL XSTOPX (' A, M, S out of order in MLTMOD - ABORT!')
+  
+     10 IF (.NOT. (a.LT.h)) GO TO 20
+        a0 = a
+diff -rc libcruft.orig/ranlib/setant.f libcruft/ranlib/setant.f
+*** libcruft.orig/ranlib/setant.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/setant.f	Mon Jun  7 15:33:36 1993
+***************
+*** 65,71 ****
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' SETANT called before random number generator ',
+       +  ' initialized -- abort!'
+!       STOP ' SETANT called before random number generator initialized'
+  
+     10 CALL getcgn(g)
+        qanti(g) = qvalue
+--- 65,72 ----
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' SETANT called before random number generator ',
+       +  ' initialized -- abort!'
+!       CALL XSTOPX
+!      + (' SETANT called before random number generator initialized')
+  
+     10 CALL getcgn(g)
+        qanti(g) = qvalue
+diff -rc libcruft.orig/ranlib/setgmn.f libcruft/ranlib/setgmn.f
+*** libcruft.orig/ranlib/setgmn.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/setgmn.f	Mon Jun  7 15:33:21 1993
+***************
+*** 55,61 ****
+        IF (.NOT. (p.LE.0)) GO TO 10
+        WRITE (*,*) 'P nonpositive in SETGMN'
+        WRITE (*,*) 'Value of P: ',p
+!       STOP 'P nonpositive in SETGMN'
+  
+     10 parm(1) = p
+  C
+--- 55,61 ----
+        IF (.NOT. (p.LE.0)) GO TO 10
+        WRITE (*,*) 'P nonpositive in SETGMN'
+        WRITE (*,*) 'Value of P: ',p
+!       CALL XSTOPX ('P nonpositive in SETGMN')
+  
+     10 parm(1) = p
+  C
+***************
+*** 70,76 ****
+        CALL spofa(covm,p,p,info)
+        IF (.NOT. (info.NE.0)) GO TO 30
+        WRITE (*,*) ' COVM not positive definite in SETGMN'
+!       STOP ' COVM not positive definite in SETGMN'
+  
+     30 icount = p + 1
+  C
+--- 70,76 ----
+        CALL spofa(covm,p,p,info)
+        IF (.NOT. (info.NE.0)) GO TO 30
+        WRITE (*,*) ' COVM not positive definite in SETGMN'
+!       CALL XSTOPX (' COVM not positive definite in SETGMN')
+  
+     30 icount = p + 1
+  C
+diff -rc libcruft.orig/ranlib/setsd.f libcruft/ranlib/setsd.f
+*** libcruft.orig/ranlib/setsd.f	Wed Apr 22 08:49:01 1992
+--- libcruft/ranlib/setsd.f	Mon Jun  7 15:32:58 1993
+***************
+*** 62,68 ****
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' SETSD called before random number generator ',
+       +  ' initialized -- abort!'
+!       STOP ' SETSD called before random number generator initialized'
+  
+     10 CALL getcgn(g)
+        ig1(g) = iseed1
+--- 62,69 ----
+        IF (qrgnin()) GO TO 10
+        WRITE (*,*) ' SETSD called before random number generator ',
+       +  ' initialized -- abort!'
+!       CALL XSTOPX
+!      + (' SETSD called before random number generator initialized')
+  
+     10 CALL getcgn(g)
+        ig1(g) = iseed1
+diff -rc libcruft.orig/villad/vilerr.f libcruft/villad/vilerr.f
+*** libcruft.orig/villad/vilerr.f	Wed Dec  2 21:54:57 1992
+--- libcruft/villad/vilerr.f	Mon Jun  7 15:55:08 1993
+***************
+*** 80,86 ****
+  C
+  C -- PROGRAM EXECUTION TERMINATES HERE
+  C
+!         STOP
+  C
+        ELSE
+        END IF
+--- 80,86 ----
+  C
+  C -- PROGRAM EXECUTION TERMINATES HERE
+  C
+!         CALL XSTOPX (' ')
+  C
+        ELSE
+        END IF
diff --git a/libcruft/amos/Makefile.in b/libcruft/amos/Makefile.in
new file mode 100644
index 0000000..d7bd011
--- /dev/null
+++ b/libcruft/amos/Makefile.in
@@ -0,0 +1,41 @@
+# Makefile for octave's libcruft/amos directory
+#
+# Copyright (C) 1998, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = cacai.f cacon.f cbesh.f cbesi.f cbesj.f cbesk.f cbesy.f cbinu.f \
+  cbuni.f cbunk.f cunk1.f cunk2.f crati.f cshch.f cuni1.f \
+  cuoik.f cairy.f cbiry.f ckscl.f cs1s2.f cuchk.f cuni2.f cwrsk.f \
+  casyi.f cbknu.f cmlri.f cseri.f cunhj.f cunik.f dgamln.f gamln.f \
+  xzabs.f xzexp.f xzlog.f xzsqrt.f zacai.f zacon.f \
+  zairy.f zasyi.f zbesh.f zbesi.f zbesj.f zbesk.f zbesy.f zbinu.f \
+  zbiry.f zbknu.f zbuni.f zbunk.f zdiv.f zkscl.f zmlri.f zmlt.f \
+  zrati.f zs1s2.f zseri.f zshch.f zuchk.f zunhj.f zuni1.f zuni2.f \
+  zunik.f zunk1.f zunk2.f zuoik.f zwrsk.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/amos/cacai.f b/libcruft/amos/cacai.f
new file mode 100644
index 0000000..d8ce744
--- /dev/null
+++ b/libcruft/amos/cacai.f
@@ -0,0 +1,90 @@
+      SUBROUTINE CACAI(Z, FNU, KODE, MR, N, Y, NZ, RL, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CACAI
+C***REFER TO  CAIRY
+C
+C     CACAI APPLIES THE ANALYTIC CONTINUATION FORMULA
+C
+C         K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN)
+C                 MP=PI*MR*CMPLX(0.0,1.0)
+C
+C     TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT
+C     HALF Z PLANE FOR USE WITH CAIRY WHERE FNU=1/3 OR 2/3 AND N=1.
+C     CACAI IS THE SAME AS CACON WITH THE PARTS FOR LARGER ORDERS AND
+C     RECURRENCE REMOVED. A RECURSIVE CALL TO CACON CAN RESULT IF CACON
+C     IS CALLED FROM CAIRY.
+C
+C***ROUTINES CALLED  CASYI,CBKNU,CMLRI,CSERI,CS1S2,R1MACH
+C***END PROLOGUE  CACAI
+      COMPLEX CSGN, CSPN, C1, C2, Y, Z, ZN, CY
+      REAL ALIM, ARG, ASCLE, AZ, CPN, DFNU, ELIM, FMR, FNU, PI, RL,
+     * SGN, SPN, TOL, YY, R1MACH
+      INTEGER INU, IUF, KODE, MR, N, NN, NW, NZ
+      DIMENSION Y(N), CY(2)
+      DATA PI / 3.14159265358979324E0 /
+      NZ = 0
+      ZN = -Z
+      AZ = CABS(Z)
+      NN = N
+      DFNU = FNU + FLOAT(N-1)
+      IF (AZ.LE.2.0E0) GO TO 10
+      IF (AZ*AZ*0.25E0.GT.DFNU+1.0E0) GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      CALL CSERI(ZN, FNU, KODE, NN, Y, NW, TOL, ELIM, ALIM)
+      GO TO 40
+   20 CONTINUE
+      IF (AZ.LT.RL) GO TO 30
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR LARGE Z FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      CALL CASYI(ZN, FNU, KODE, NN, Y, NW, RL, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 70
+      GO TO 40
+   30 CONTINUE
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM NORMALIZED BY THE SERIES FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      CALL CMLRI(ZN, FNU, KODE, NN, Y, NW, TOL)
+      IF(NW.LT.0) GO TO 70
+   40 CONTINUE
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION
+C-----------------------------------------------------------------------
+      CALL CBKNU(ZN, FNU, KODE, 1, CY, NW, TOL, ELIM, ALIM)
+      IF (NW.NE.0) GO TO 70
+      FMR = FLOAT(MR)
+      SGN = -SIGN(PI,FMR)
+      CSGN = CMPLX(0.0E0,SGN)
+      IF (KODE.EQ.1) GO TO 50
+      YY = -AIMAG(ZN)
+      CPN = COS(YY)
+      SPN = SIN(YY)
+      CSGN = CSGN*CMPLX(CPN,SPN)
+   50 CONTINUE
+C-----------------------------------------------------------------------
+C     CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(FNU)
+      ARG = (FNU-FLOAT(INU))*SGN
+      CPN = COS(ARG)
+      SPN = SIN(ARG)
+      CSPN = CMPLX(CPN,SPN)
+      IF (MOD(INU,2).EQ.1) CSPN = -CSPN
+      C1 = CY(1)
+      C2 = Y(1)
+      IF (KODE.EQ.1) GO TO 60
+      IUF = 0
+      ASCLE = 1.0E+3*R1MACH(1)/TOL
+      CALL CS1S2(ZN, C1, C2, NW, ASCLE, ALIM, IUF)
+      NZ = NZ + NW
+   60 CONTINUE
+      Y(1) = CSPN*C1 + CSGN*C2
+      RETURN
+   70 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/cacon.f b/libcruft/amos/cacon.f
new file mode 100644
index 0000000..c2e25ba
--- /dev/null
+++ b/libcruft/amos/cacon.f
@@ -0,0 +1,149 @@
+      SUBROUTINE CACON(Z, FNU, KODE, MR, N, Y, NZ, RL, FNUL, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  CACON
+C***REFER TO  CBESK,CBESH
+C
+C     CACON APPLIES THE ANALYTIC CONTINUATION FORMULA
+C
+C         K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN)
+C                 MP=PI*MR*CMPLX(0.0,1.0)
+C
+C     TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT
+C     HALF Z PLANE
+C
+C***ROUTINES CALLED  CBINU,CBKNU,CS1S2,R1MACH
+C***END PROLOGUE  CACON
+      COMPLEX CK, CONE, CS, CSCL, CSCR, CSGN, CSPN, CSS, CSR, C1, C2,
+     * RZ, SC1, SC2, ST, S1, S2, Y, Z, ZN, CY
+      REAL ALIM, ARG, ASCLE, AS2, BSCLE, BRY, CPN, C1I, C1M, C1R, ELIM,
+     * FMR, FNU, FNUL, PI, RL, SGN, SPN, TOL, YY, R1MACH
+      INTEGER I, INU, IUF, KFLAG, KODE, MR, N, NN, NW, NZ
+      DIMENSION Y(N), CY(2), CSS(3), CSR(3), BRY(3)
+      DATA PI / 3.14159265358979324E0 /
+      DATA CONE / (1.0E0,0.0E0) /
+      NZ = 0
+      ZN = -Z
+      NN = N
+      CALL CBINU(ZN, FNU, KODE, NN, Y, NW, RL, FNUL, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 80
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION
+C-----------------------------------------------------------------------
+      NN = MIN0(2,N)
+      CALL CBKNU(ZN, FNU, KODE, NN, CY, NW, TOL, ELIM, ALIM)
+      IF (NW.NE.0) GO TO 80
+      S1 = CY(1)
+      FMR = FLOAT(MR)
+      SGN = -SIGN(PI,FMR)
+      CSGN = CMPLX(0.0E0,SGN)
+      IF (KODE.EQ.1) GO TO 10
+      YY = -AIMAG(ZN)
+      CPN = COS(YY)
+      SPN = SIN(YY)
+      CSGN = CSGN*CMPLX(CPN,SPN)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(FNU)
+      ARG = (FNU-FLOAT(INU))*SGN
+      CPN = COS(ARG)
+      SPN = SIN(ARG)
+      CSPN = CMPLX(CPN,SPN)
+      IF (MOD(INU,2).EQ.1) CSPN = -CSPN
+      IUF = 0
+      C1 = S1
+      C2 = Y(1)
+      ASCLE = 1.0E+3*R1MACH(1)/TOL
+      IF (KODE.EQ.1) GO TO 20
+      CALL CS1S2(ZN, C1, C2, NW, ASCLE, ALIM, IUF)
+      NZ = NZ + NW
+      SC1 = C1
+   20 CONTINUE
+      Y(1) = CSPN*C1 + CSGN*C2
+      IF (N.EQ.1) RETURN
+      CSPN = -CSPN
+      S2 = CY(2)
+      C1 = S2
+      C2 = Y(2)
+      IF (KODE.EQ.1) GO TO 30
+      CALL CS1S2(ZN, C1, C2, NW, ASCLE, ALIM, IUF)
+      NZ = NZ + NW
+      SC2 = C1
+   30 CONTINUE
+      Y(2) = CSPN*C1 + CSGN*C2
+      IF (N.EQ.2) RETURN
+      CSPN = -CSPN
+      RZ = CMPLX(2.0E0,0.0E0)/ZN
+      CK = CMPLX(FNU+1.0E0,0.0E0)*RZ
+C-----------------------------------------------------------------------
+C     SCALE NEAR EXPONENT EXTREMES DURING RECURRENCE ON K FUNCTIONS
+C-----------------------------------------------------------------------
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      CSCR = CMPLX(TOL,0.0E0)
+      CSS(1) = CSCL
+      CSS(2) = CONE
+      CSS(3) = CSCR
+      CSR(1) = CSCR
+      CSR(2) = CONE
+      CSR(3) = CSCL
+      BRY(1) = ASCLE
+      BRY(2) = 1.0E0/ASCLE
+      BRY(3) = R1MACH(2)
+      AS2 = CABS(S2)
+      KFLAG = 2
+      IF (AS2.GT.BRY(1)) GO TO 40
+      KFLAG = 1
+      GO TO 50
+   40 CONTINUE
+      IF (AS2.LT.BRY(2)) GO TO 50
+      KFLAG = 3
+   50 CONTINUE
+      BSCLE = BRY(KFLAG)
+      S1 = S1*CSS(KFLAG)
+      S2 = S2*CSS(KFLAG)
+      CS = CSR(KFLAG)
+      DO 70 I=3,N
+        ST = S2
+        S2 = CK*S2 + S1
+        S1 = ST
+        C1 = S2*CS
+        ST = C1
+        C2 = Y(I)
+        IF (KODE.EQ.1) GO TO 60
+        IF (IUF.LT.0) GO TO 60
+        CALL CS1S2(ZN, C1, C2, NW, ASCLE, ALIM, IUF)
+        NZ = NZ + NW
+        SC1 = SC2
+        SC2 = C1
+        IF (IUF.NE.3) GO TO 60
+        IUF = -4
+        S1 = SC1*CSS(KFLAG)
+        S2 = SC2*CSS(KFLAG)
+        ST = SC2
+   60   CONTINUE
+        Y(I) = CSPN*C1 + CSGN*C2
+        CK = CK + RZ
+        CSPN = -CSPN
+        IF (KFLAG.GE.3) GO TO 70
+        C1R = REAL(C1)
+        C1I = AIMAG(C1)
+        C1R = ABS(C1R)
+        C1I = ABS(C1I)
+        C1M = AMAX1(C1R,C1I)
+        IF (C1M.LE.BSCLE) GO TO 70
+        KFLAG = KFLAG + 1
+        BSCLE = BRY(KFLAG)
+        S1 = S1*CS
+        S2 = ST
+        S1 = S1*CSS(KFLAG)
+        S2 = S2*CSS(KFLAG)
+        CS = CSR(KFLAG)
+   70 CONTINUE
+      RETURN
+   80 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/cairy.f b/libcruft/amos/cairy.f
new file mode 100644
index 0000000..d4700d8
--- /dev/null
+++ b/libcruft/amos/cairy.f
@@ -0,0 +1,336 @@
+      SUBROUTINE CAIRY(Z, ID, KODE, AI, NZ, IERR)
+C***BEGIN PROLOGUE  CAIRY
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z
+C***DESCRIPTION
+C
+C         ON KODE=1, CAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR
+C         ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON
+C         KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)*
+C         DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN
+C         -PI/3.LT.ARG(Z).LT.PI/3 AND THE EXPONENTIAL GROWTH IN
+C         PI/3.LT.ABS(ARG(Z)).LT.PI WHERE ZTA=(2/3)*Z*CSQRT(Z)
+C
+C         WHILE THE AIRY FUNCTIONS AI(Z) AND DAI(Z)/DZ ARE ANALYTIC IN
+C         THE WHOLE Z PLANE, THE CORRESPONDING SCALED FUNCTIONS DEFINED
+C         FOR KODE=2 HAVE A CUT ALONG THE NEGATIVE REAL AXIS.
+C         DEFINITIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF
+C         MATHEMATICAL FUNCTIONS (REF. 1).
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y)
+C           ID     - ORDER OF DERIVATIVE, ID=0 OR ID=1
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             AI=AI(Z)                ON ID=0 OR
+C                             AI=DAI(Z)/DZ            ON ID=1
+C                        = 2  RETURNS
+C                             AI=CEXP(ZTA)*AI(Z)       ON ID=0 OR
+C                             AI=CEXP(ZTA)*DAI(Z)/DZ   ON ID=1 WHERE
+C                             ZTA=(2/3)*Z*CSQRT(Z)
+C
+C         OUTPUT
+C           AI     - COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND
+C                    KODE
+C           NZ     - UNDERFLOW INDICATOR
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ= 1   , AI=CMPLX(0.0,0.0) DUE TO UNDERFLOW IN
+C                              -PI/3.LT.ARG(Z).LT.PI/3 ON KODE=1
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, REAL(ZTA)
+C                            TOO LARGE WITH KODE=1.
+C                    IERR=3, CABS(Z) LARGE      - COMPUTATION COMPLETED
+C                            LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION
+C                            PRODUCE LESS THAN HALF OF MACHINE ACCURACY
+C                    IERR=4, CABS(Z) TOO LARGE  - NO COMPUTATION
+C                            COMPLETE LOSS OF ACCURACY BY ARGUMENT
+C                            REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C
+C***LONG DESCRIPTION
+C
+C         AI AND DAI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE K BESSEL
+C         FUNCTIONS BY
+C
+C            AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA)
+C                           C=1.0/(PI*SQRT(3.0))
+C                           ZTA=(2/3)*Z**(3/2)
+C
+C         WITH THE POWER SERIES FOR CABS(Z).LE.1.0.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES
+C         OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF
+C         THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR),
+C         THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR
+C         FLAG IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF.
+C         ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN
+C         ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT
+C         FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE
+C         LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA
+C         MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2,
+C         AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE
+C         PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE
+C         PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT-
+C         ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG-
+C         NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN
+C         DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN
+C         EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES,
+C         NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE
+C         PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER
+C         MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CACAI,CBKNU,I1MACH,R1MACH
+C***END PROLOGUE  CAIRY
+      COMPLEX AI, CONE, CSQ, CY, S1, S2, TRM1, TRM2, Z, ZTA, Z3
+      REAL AA, AD, AK, ALIM, ATRM, AZ, AZ3, BK, CK, COEF, C1, C2, DIG,
+     * DK, D1, D2, ELIM, FID, FNU, RL, R1M5, SFAC, TOL, TTH, ZI, ZR,
+     * Z3I, Z3R, R1MACH, BB, ALAZ
+      INTEGER ID, IERR, IFLAG, K, KODE, K1, K2, MR, NN, NZ, I1MACH
+      DIMENSION CY(1)
+      DATA TTH, C1, C2, COEF /6.66666666666666667E-01,
+     * 3.55028053887817240E-01,2.58819403792806799E-01,
+     * 1.83776298473930683E-01/
+      DATA  CONE / (1.0E0,0.0E0) /
+C***FIRST EXECUTABLE STATEMENT  CAIRY
+      IERR = 0
+      NZ=0
+      IF (ID.LT.0 .OR. ID.GT.1) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (IERR.NE.0) RETURN
+      AZ = CABS(Z)
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      FID = FLOAT(ID)
+      IF (AZ.GT.1.0E0) GO TO 60
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR CABS(Z).LE.1.
+C-----------------------------------------------------------------------
+      S1 = CONE
+      S2 = CONE
+      IF (AZ.LT.TOL) GO TO 160
+      AA = AZ*AZ
+      IF (AA.LT.TOL/AZ) GO TO 40
+      TRM1 = CONE
+      TRM2 = CONE
+      ATRM = 1.0E0
+      Z3 = Z*Z*Z
+      AZ3 = AZ*AA
+      AK = 2.0E0 + FID
+      BK = 3.0E0 - FID - FID
+      CK = 4.0E0 - FID
+      DK = 3.0E0 + FID + FID
+      D1 = AK*DK
+      D2 = BK*CK
+      AD = AMIN1(D1,D2)
+      AK = 24.0E0 + 9.0E0*FID
+      BK = 30.0E0 - 9.0E0*FID
+      Z3R = REAL(Z3)
+      Z3I = AIMAG(Z3)
+      DO 30 K=1,25
+        TRM1 = TRM1*CMPLX(Z3R/D1,Z3I/D1)
+        S1 = S1 + TRM1
+        TRM2 = TRM2*CMPLX(Z3R/D2,Z3I/D2)
+        S2 = S2 + TRM2
+        ATRM = ATRM*AZ3/AD
+        D1 = D1 + AK
+        D2 = D2 + BK
+        AD = AMIN1(D1,D2)
+        IF (ATRM.LT.TOL*AD) GO TO 40
+        AK = AK + 18.0E0
+        BK = BK + 18.0E0
+   30 CONTINUE
+   40 CONTINUE
+      IF (ID.EQ.1) GO TO 50
+      AI = S1*CMPLX(C1,0.0E0) - Z*S2*CMPLX(C2,0.0E0)
+      IF (KODE.EQ.1) RETURN
+      ZTA = Z*CSQRT(Z)*CMPLX(TTH,0.0E0)
+      AI = AI*CEXP(ZTA)
+      RETURN
+   50 CONTINUE
+      AI = -S2*CMPLX(C2,0.0E0)
+      IF (AZ.GT.TOL) AI = AI + Z*Z*S1*CMPLX(C1/(1.0E0+FID),0.0E0)
+      IF (KODE.EQ.1) RETURN
+      ZTA = Z*CSQRT(Z)*CMPLX(TTH,0.0E0)
+      AI = AI*CEXP(ZTA)
+      RETURN
+C-----------------------------------------------------------------------
+C     CASE FOR CABS(Z).GT.1.0
+C-----------------------------------------------------------------------
+   60 CONTINUE
+      FNU = (1.0E0+FID)/3.0E0
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C-----------------------------------------------------------------------
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      R1M5 = R1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      K1 = I1MACH(11) - 1
+      AA = R1M5*FLOAT(K1)
+      DIG = AMIN1(AA,18.0E0)
+      AA = AA*2.303E0
+      ALIM = ELIM + AMAX1(-AA,-41.45E0)
+      RL = 1.2E0*DIG + 3.0E0
+      ALAZ=ALOG(AZ)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA=0.5E0/TOL
+      BB=FLOAT(I1MACH(9))*0.5E0
+      AA=AMIN1(AA,BB)
+      AA=AA**TTH
+      IF (AZ.GT.AA) GO TO 260
+      AA=SQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      CSQ=CSQRT(Z)
+      ZTA=Z*CSQ*CMPLX(TTH,0.0E0)
+C-----------------------------------------------------------------------
+C     RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL
+C-----------------------------------------------------------------------
+      IFLAG = 0
+      SFAC = 1.0E0
+      ZI = AIMAG(Z)
+      ZR = REAL(Z)
+      AK = AIMAG(ZTA)
+      IF (ZR.GE.0.0E0) GO TO 70
+      BK = REAL(ZTA)
+      CK = -ABS(BK)
+      ZTA = CMPLX(CK,AK)
+   70 CONTINUE
+      IF (ZI.NE.0.0E0) GO TO 80
+      IF (ZR.GT.0.0E0) GO TO 80
+      ZTA = CMPLX(0.0E0,AK)
+   80 CONTINUE
+      AA = REAL(ZTA)
+      IF (AA.GE.0.0E0 .AND. ZR.GT.0.0E0) GO TO 100
+      IF (KODE.EQ.2) GO TO 90
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (AA.GT.(-ALIM)) GO TO 90
+      AA = -AA + 0.25E0*ALAZ
+      IFLAG = 1
+      SFAC = TOL
+      IF (AA.GT.ELIM) GO TO 240
+   90 CONTINUE
+C-----------------------------------------------------------------------
+C     CBKNU AND CACAI RETURN EXP(ZTA)*K(FNU,ZTA) ON KODE=2
+C-----------------------------------------------------------------------
+      MR = 1
+      IF (ZI.LT.0.0E0) MR = -1
+      CALL CACAI(ZTA, FNU, KODE, MR, 1, CY, NN, RL, TOL, ELIM, ALIM)
+      IF (NN.LT.0) GO TO 250
+      NZ = NZ + NN
+      GO TO 120
+  100 CONTINUE
+      IF (KODE.EQ.2) GO TO 110
+C-----------------------------------------------------------------------
+C     UNDERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (AA.LT.ALIM) GO TO 110
+      AA = -AA - 0.25E0*ALAZ
+      IFLAG = 2
+      SFAC = 1.0E0/TOL
+      IF (AA.LT.(-ELIM)) GO TO 180
+  110 CONTINUE
+      CALL CBKNU(ZTA, FNU, KODE, 1, CY, NZ, TOL, ELIM, ALIM)
+  120 CONTINUE
+      S1 = CY(1)*CMPLX(COEF,0.0E0)
+      IF (IFLAG.NE.0) GO TO 140
+      IF (ID.EQ.1) GO TO 130
+      AI = CSQ*S1
+      RETURN
+  130 AI = -Z*S1
+      RETURN
+  140 CONTINUE
+      S1 = S1*CMPLX(SFAC,0.0E0)
+      IF (ID.EQ.1) GO TO 150
+      S1 = S1*CSQ
+      AI = S1*CMPLX(1.0E0/SFAC,0.0E0)
+      RETURN
+  150 CONTINUE
+      S1 = -S1*Z
+      AI = S1*CMPLX(1.0E0/SFAC,0.0E0)
+      RETURN
+  160 CONTINUE
+      AA = 1.0E+3*R1MACH(1)
+      S1 = CMPLX(0.0E0,0.0E0)
+      IF (ID.EQ.1) GO TO 170
+      IF (AZ.GT.AA) S1 = CMPLX(C2,0.0E0)*Z
+      AI = CMPLX(C1,0.0E0) - S1
+      RETURN
+  170 CONTINUE
+      AI = -CMPLX(C2,0.0E0)
+      AA = SQRT(AA)
+      IF (AZ.GT.AA) S1 = Z*Z*CMPLX(0.5E0,0.0E0)
+      AI = AI + S1*CMPLX(C1,0.0E0)
+      RETURN
+  180 CONTINUE
+      NZ = 1
+      AI = CMPLX(0.0E0,0.0E0)
+      RETURN
+  240 CONTINUE
+      NZ = 0
+      IERR=2
+      RETURN
+  250 CONTINUE
+      IF(NN.EQ.(-1)) GO TO 240
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      IERR=4
+      NZ=0
+      RETURN
+      END
diff --git a/libcruft/amos/casyi.f b/libcruft/amos/casyi.f
new file mode 100644
index 0000000..1cdbc20
--- /dev/null
+++ b/libcruft/amos/casyi.f
@@ -0,0 +1,126 @@
+      SUBROUTINE CASYI(Z, FNU, KODE, N, Y, NZ, RL, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CASYI
+C***REFER TO  CBESI,CBESK
+C
+C     CASYI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
+C     MEANS OF THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z) IN THE
+C     REGION CABS(Z).GT.MAX(RL,FNU*FNU/2). NZ=0 IS A NORMAL RETURN.
+C     NZ.LT.0 INDICATES AN OVERFLOW ON KODE=1.
+C
+C***ROUTINES CALLED  R1MACH
+C***END PROLOGUE  CASYI
+      COMPLEX AK1, CK, CONE, CS1, CS2, CZ, CZERO, DK, EZ, P1, RZ, S2,
+     * Y, Z
+      REAL AA, ACZ, AEZ, AK, ALIM, ARG, ARM, ATOL, AZ, BB, BK, DFNU,
+     * DNU2, ELIM, FDN, FNU, PI, RL, RTPI, RTR1, S, SGN, SQK, TOL, X,
+     * YY, R1MACH
+      INTEGER I, IB, IL, INU, J, JL, K, KODE, KODED, M, N, NN, NZ
+      DIMENSION Y(N)
+      DATA PI, RTPI  /3.14159265358979324E0 , 0.159154943091895336E0 /
+      DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
+C
+      NZ = 0
+      AZ = CABS(Z)
+      X = REAL(Z)
+      ARM = 1.0E+3*R1MACH(1)
+      RTR1 = SQRT(ARM)
+      IL = MIN0(2,N)
+      DFNU = FNU + FLOAT(N-IL)
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      AK1 = CMPLX(RTPI,0.0E0)/Z
+      AK1 = CSQRT(AK1)
+      CZ = Z
+      IF (KODE.EQ.2) CZ = Z - CMPLX(X,0.0E0)
+      ACZ = REAL(CZ)
+      IF (ABS(ACZ).GT.ELIM) GO TO 80
+      DNU2 = DFNU + DFNU
+      KODED = 1
+      IF ((ABS(ACZ).GT.ALIM) .AND. (N.GT.2)) GO TO 10
+      KODED = 0
+      AK1 = AK1*CEXP(CZ)
+   10 CONTINUE
+      FDN = 0.0E0
+      IF (DNU2.GT.RTR1) FDN = DNU2*DNU2
+      EZ = Z*CMPLX(8.0E0,0.0E0)
+C-----------------------------------------------------------------------
+C     WHEN Z IS IMAGINARY, THE ERROR TEST MUST BE MADE RELATIVE TO THE
+C     FIRST RECIPROCAL POWER SINCE THIS IS THE LEADING TERM OF THE
+C     EXPANSION FOR THE IMAGINARY PART.
+C-----------------------------------------------------------------------
+      AEZ = 8.0E0*AZ
+      S = TOL/AEZ
+      JL = INT(RL+RL) + 2
+      YY = AIMAG(Z)
+      P1 = CZERO
+      IF (YY.EQ.0.0E0) GO TO 20
+C-----------------------------------------------------------------------
+C     CALCULATE EXP(PI*(0.5+FNU+N-IL)*I) TO MINIMIZE LOSSES OF
+C     SIGNIFICANCE WHEN FNU OR N IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(FNU)
+      ARG = (FNU-FLOAT(INU))*PI
+      INU = INU + N - IL
+      AK = -SIN(ARG)
+      BK = COS(ARG)
+      IF (YY.LT.0.0E0) BK = -BK
+      P1 = CMPLX(AK,BK)
+      IF (MOD(INU,2).EQ.1) P1 = -P1
+   20 CONTINUE
+      DO 50 K=1,IL
+        SQK = FDN - 1.0E0
+        ATOL = S*ABS(SQK)
+        SGN = 1.0E0
+        CS1 = CONE
+        CS2 = CONE
+        CK = CONE
+        AK = 0.0E0
+        AA = 1.0E0
+        BB = AEZ
+        DK = EZ
+        DO 30 J=1,JL
+          CK = CK*CMPLX(SQK,0.0E0)/DK
+          CS2 = CS2 + CK
+          SGN = -SGN
+          CS1 = CS1 + CK*CMPLX(SGN,0.0E0)
+          DK = DK + EZ
+          AA = AA*ABS(SQK)/BB
+          BB = BB + AEZ
+          AK = AK + 8.0E0
+          SQK = SQK - AK
+          IF (AA.LE.ATOL) GO TO 40
+   30   CONTINUE
+        GO TO 90
+   40   CONTINUE
+        S2 = CS1
+        IF (X+X.LT.ELIM) S2 = S2 + P1*CS2*CEXP(-Z-Z)
+        FDN = FDN + 8.0E0*DFNU + 4.0E0
+        P1 = -P1
+        M = N - IL + K
+        Y(M) = S2*AK1
+   50 CONTINUE
+      IF (N.LE.2) RETURN
+      NN = N
+      K = NN - 2
+      AK = FLOAT(K)
+      RZ = (CONE+CONE)/Z
+      IB = 3
+      DO 60 I=IB,NN
+        Y(K) = CMPLX(AK+FNU,0.0E0)*RZ*Y(K+1) + Y(K+2)
+        AK = AK - 1.0E0
+        K = K - 1
+   60 CONTINUE
+      IF (KODED.EQ.0) RETURN
+      CK = CEXP(CZ)
+      DO 70 I=1,NN
+        Y(I) = Y(I)*CK
+   70 CONTINUE
+      RETURN
+   80 CONTINUE
+      NZ = -1
+      RETURN
+   90 CONTINUE
+      NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/cbesh.f b/libcruft/amos/cbesh.f
new file mode 100644
index 0000000..d5eba11
--- /dev/null
+++ b/libcruft/amos/cbesh.f
@@ -0,0 +1,331 @@
+      SUBROUTINE CBESH(Z, FNU, KODE, M, N, CY, NZ, IERR)
+C***BEGIN PROLOGUE  CBESH
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  H-BESSEL FUNCTIONS,BESSEL FUNCTIONS OF COMPLEX ARGUMENT,
+C             BESSEL FUNCTIONS OF THIRD KIND,HANKEL FUNCTIONS
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE H-BESSEL FUNCTIONS OF A COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C         ON KODE=1, CBESH COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         HANKEL (BESSEL) FUNCTIONS CY(J)=H(M,FNU+J-1,Z) FOR KINDS M=1
+C         OR 2, REAL, NONNEGATIVE ORDERS FNU+J-1, J=1,...,N, AND COMPLEX
+C         Z.NE.CMPLX(0.0E0,0.0E0) IN THE CUT PLANE -PI.LT.ARG(Z).LE.PI.
+C         ON KODE=2, CBESH COMPUTES THE SCALED HANKEL FUNCTIONS
+C
+C         CY(I)=H(M,FNU+J-1,Z)*EXP(-MM*Z*I)       MM=3-2M,      I**2=-1.
+C
+C         WHICH REMOVES THE EXPONENTIAL BEHAVIOR IN BOTH THE UPPER
+C         AND LOWER HALF PLANES. DEFINITIONS AND NOTATION ARE FOUND IN
+C         THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS (REF. 1).
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y), Z.NE.CMPLX(0.,0.),-PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL H FUNCTION, FNU.GE.0.0E0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(J)=H(M,FNU+J-1,Z),      J=1,...,N
+C                        = 2  RETURNS
+C                             CY(J)=H(M,FNU+J-1,Z)*EXP(-I*Z*(3-2M))
+C                                  J=1,...,N  ,  I**2=-1
+C           M      - KIND OF HANKEL FUNCTION, M=1 OR 2
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C
+C         OUTPUT
+C           CY     - A COMPLEX VECTOR WHOSE FIRST N COMPONENTS CONTAIN
+C                    VALUES FOR THE SEQUENCE
+C                    CY(J)=H(M,FNU+J-1,Z)  OR
+C                    CY(J)=H(M,FNU+J-1,Z)*EXP(-I*Z*(3-2M))  J=1,...,N
+C                    DEPENDING ON KODE, I**2=-1.
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , FIRST NZ COMPONENTS OF CY SET TO ZERO
+C                              DUE TO UNDERFLOW, CY(J)=CMPLX(0.0,0.0)
+C                              J=1,...,NZ WHEN Y.GT.0.0 AND M=1 OR
+C                              Y.LT.0.0 AND M=2. FOR THE COMPLMENTARY
+C                              HALF PLANES, NZ STATES ONLY THE NUMBER
+C                              OF UNDERFLOWS.
+C           IERR    -ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, FNU+N-1 TOO
+C                            LARGE OR CABS(Z) TOO SMALL OR BOTH
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE RELATION
+C
+C         H(M,FNU,Z)=(1/MP)*EXP(-MP*FNU)*K(FNU,Z*EXP(-MP))
+C             MP=MM*HPI*I,  MM=3-2*M,  HPI=PI/2,  I**2=-1
+C
+C         FOR M=1 OR 2 WHERE THE K BESSEL FUNCTION IS COMPUTED FOR THE
+C         RIGHT HALF PLANE RE(Z).GE.0.0. THE K FUNCTION IS CONTINUED
+C         TO THE LEFT HALF PLANE BY THE RELATION
+C
+C         K(FNU,Z*EXP(MP)) = EXP(-MP*FNU)*K(FNU,Z)-MP*I(FNU,Z)
+C         MP=MR*PI*I, MR=+1 OR -1, RE(Z).GT.0, I**2=-1
+C
+C         WHERE I(FNU,Z) IS THE I BESSEL FUNCTION.
+C
+C         EXPONENTIAL DECAY OF H(M,FNU,Z) OCCURS IN THE UPPER HALF Z
+C         PLANE FOR M=1 AND THE LOWER HALF Z PLANE FOR M=2.  EXPONENTIAL
+C         GROWTH OCCURS IN THE COMPLEMENTARY HALF PLANES.  SCALING
+C         BY EXP(-MM*Z*I) REMOVES THE EXPONENTIAL BEHAVIOR IN THE
+C         WHOLE Z PLANE FOR Z TO INFINITY.
+C
+C         FOR NEGATIVE ORDERS,THE FORMULAE
+C
+C               H(1,-FNU,Z) = H(1,FNU,Z)*CEXP( PI*FNU*I)
+C               H(2,-FNU,Z) = H(2,FNU,Z)*CEXP(-PI*FNU*I)
+C                         I**2=-1
+C
+C         CAN BE USED.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF. ALSO
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CACON,CBKNU,CBUNK,CUOIK,I1MACH,R1MACH
+C***END PROLOGUE  CBESH
+C
+      COMPLEX CY, Z, ZN, ZT, CSGN
+      REAL AA, ALIM, ALN, ARG, AZ, CPN, DIG, ELIM, FMM, FN, FNU, FNUL,
+     * HPI, RHPI, RL, R1M5, SGN, SPN, TOL, UFL, XN, XX, YN, YY, R1MACH,
+     * BB, ASCLE, RTOL, ATOL
+      INTEGER I, IERR, INU, INUH, IR, K, KODE, K1, K2, M,
+     * MM, MR, N, NN, NUF, NW, NZ, I1MACH
+      DIMENSION CY(N)
+C
+      DATA HPI /1.57079632679489662E0/
+C
+C***FIRST EXECUTABLE STATEMENT  CBESH
+      NZ=0
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+      IERR = 0
+      IF (XX.EQ.0.0E0 .AND. YY.EQ.0.0E0) IERR=1
+      IF (FNU.LT.0.0E0) IERR=1
+      IF (M.LT.1 .OR. M.GT.2) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      NN = N
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU
+C-----------------------------------------------------------------------
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      R1M5 = R1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      K1 = I1MACH(11) - 1
+      AA = R1M5*FLOAT(K1)
+      DIG = AMIN1(AA,18.0E0)
+      AA = AA*2.303E0
+      ALIM = ELIM + AMAX1(-AA,-41.45E0)
+      FNUL = 10.0E0 + 6.0E0*(DIG-3.0E0)
+      RL = 1.2E0*DIG + 3.0E0
+      FN = FNU + FLOAT(NN-1)
+      MM = 3 - M - M
+      FMM = FLOAT(MM)
+      ZN = Z*CMPLX(0.0E0,-FMM)
+      XN = REAL(ZN)
+      YN = AIMAG(ZN)
+      AZ = CABS(Z)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA = 0.5E0/TOL
+      BB=FLOAT(I1MACH(9))*0.5E0
+      AA=AMIN1(AA,BB)
+      IF(AZ.GT.AA) GO TO 240
+      IF(FN.GT.AA) GO TO 240
+      AA=SQRT(AA)
+      IF(AZ.GT.AA) IERR=3
+      IF(FN.GT.AA) IERR=3
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST ON THE LAST MEMBER OF THE SEQUENCE
+C-----------------------------------------------------------------------
+      UFL = R1MACH(1)*1.0E+3
+      IF (AZ.LT.UFL) GO TO 220
+      IF (FNU.GT.FNUL) GO TO 90
+      IF (FN.LE.1.0E0) GO TO 70
+      IF (FN.GT.2.0E0) GO TO 60
+      IF (AZ.GT.TOL) GO TO 70
+      ARG = 0.5E0*AZ
+      ALN = -FN*ALOG(ARG)
+      IF (ALN.GT.ELIM) GO TO 220
+      GO TO 70
+   60 CONTINUE
+      CALL CUOIK(ZN, FNU, KODE, 2, NN, CY, NUF, TOL, ELIM, ALIM)
+      IF (NUF.LT.0) GO TO 220
+      NZ = NZ + NUF
+      NN = NN - NUF
+C-----------------------------------------------------------------------
+C     HERE NN=N OR NN=0 SINCE NUF=0,NN, OR -1 ON RETURN FROM CUOIK
+C     IF NUF=NN, THEN CY(I)=CZERO FOR ALL I
+C-----------------------------------------------------------------------
+      IF (NN.EQ.0) GO TO 130
+   70 CONTINUE
+      IF ((XN.LT.0.0E0) .OR. (XN.EQ.0.0E0 .AND. YN.LT.0.0E0 .AND.
+     * M.EQ.2)) GO TO 80
+C-----------------------------------------------------------------------
+C     RIGHT HALF PLANE COMPUTATION, XN.GE.0. .AND. (XN.NE.0. .OR.
+C     YN.GE.0. .OR. M=1)
+C-----------------------------------------------------------------------
+      CALL CBKNU(ZN, FNU, KODE, NN, CY, NZ, TOL, ELIM, ALIM)
+      GO TO 110
+C-----------------------------------------------------------------------
+C     LEFT HALF PLANE COMPUTATION
+C-----------------------------------------------------------------------
+   80 CONTINUE
+      MR = -MM
+      CALL CACON(ZN, FNU, KODE, MR, NN, CY, NW, RL, FNUL, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 230
+      NZ=NW
+      GO TO 110
+   90 CONTINUE
+C-----------------------------------------------------------------------
+C     UNIFORM ASYMPTOTIC EXPANSIONS FOR FNU.GT.FNUL
+C-----------------------------------------------------------------------
+      MR = 0
+      IF ((XN.GE.0.0E0) .AND. (XN.NE.0.0E0 .OR. YN.GE.0.0E0 .OR.
+     * M.NE.2)) GO TO 100
+      MR = -MM
+      IF (XN.EQ.0.0E0 .AND. YN.LT.0.0E0) ZN = -ZN
+  100 CONTINUE
+      CALL CBUNK(ZN, FNU, KODE, MR, NN, CY, NW, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 230
+      NZ = NZ + NW
+  110 CONTINUE
+C-----------------------------------------------------------------------
+C     H(M,FNU,Z) = -FMM*(I/HPI)*(ZT**FNU)*K(FNU,-Z*ZT)
+C
+C     ZT=EXP(-FMM*HPI*I) = CMPLX(0.0,-FMM), FMM=3-2*M, M=1,2
+C-----------------------------------------------------------------------
+      SGN = SIGN(HPI,-FMM)
+C-----------------------------------------------------------------------
+C     CALCULATE EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(FNU)
+      INUH = INU/2
+      IR = INU - 2*INUH
+      ARG = (FNU-FLOAT(INU-IR))*SGN
+      RHPI = 1.0E0/SGN
+      CPN = RHPI*COS(ARG)
+      SPN = RHPI*SIN(ARG)
+C     ZN = CMPLX(-SPN,CPN)
+      CSGN = CMPLX(-SPN,CPN)
+C     IF (MOD(INUH,2).EQ.1) ZN = -ZN
+      IF (MOD(INUH,2).EQ.1) CSGN = -CSGN
+      ZT = CMPLX(0.0E0,-FMM)
+      RTOL = 1.0E0/TOL
+      ASCLE = UFL*RTOL
+      DO 120 I=1,NN
+C       CY(I) = CY(I)*ZN
+C       ZN = ZN*ZT
+        ZN=CY(I)
+        AA=REAL(ZN)
+        BB=AIMAG(ZN)
+        ATOL=1.0E0
+        IF (AMAX1(ABS(AA),ABS(BB)).GT.ASCLE) GO TO 125
+          ZN = ZN*CMPLX(RTOL,0.0E0)
+          ATOL = TOL
+  125   CONTINUE
+        ZN = ZN*CSGN
+        CY(I) = ZN*CMPLX(ATOL,0.0E0)
+        CSGN = CSGN*ZT
+  120 CONTINUE
+      RETURN
+  130 CONTINUE
+      IF (XN.LT.0.0E0) GO TO 220
+      RETURN
+  220 CONTINUE
+      IERR=2
+      NZ=0
+      RETURN
+  230 CONTINUE
+      IF(NW.EQ.(-1)) GO TO 220
+      NZ=0
+      IERR=5
+      RETURN
+  240 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/cbesi.f b/libcruft/amos/cbesi.f
new file mode 100644
index 0000000..49e6a6d
--- /dev/null
+++ b/libcruft/amos/cbesi.f
@@ -0,0 +1,258 @@
+      SUBROUTINE CBESI(Z, FNU, KODE, N, CY, NZ, IERR)
+C***BEGIN PROLOGUE  CBESI
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  I-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION,
+C             MODIFIED BESSEL FUNCTION OF THE FIRST KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE I-BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C         ON KODE=1, CBESI COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(J)=I(FNU+J-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z IN THE CUT PLANE
+C         -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESI RETURNS THE SCALED
+C         FUNCTIONS
+C
+C         CY(J)=EXP(-ABS(X))*I(FNU+J-1,Z)   J = 1,...,N , X=REAL(Z)
+C
+C         WITH THE EXPONENTIAL GROWTH REMOVED IN BOTH THE LEFT AND
+C         RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND
+C         NOTATION ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL
+C         FUNCTIONS (REF.1)
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y),  -PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL I FUNCTION, FNU.GE.0.0E0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(J)=I(FNU+J-1,Z), J=1,...,N
+C                        = 2  RETURNS
+C                             CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X)), J=1,...,N
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C
+C         OUTPUT
+C           CY     - A COMPLEX VECTOR WHOSE FIRST N COMPONENTS CONTAIN
+C                    VALUES FOR THE SEQUENCE
+C                    CY(J)=I(FNU+J-1,Z)  OR
+C                    CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X))  J=1,...,N
+C                    DEPENDING ON KODE, X=REAL(Z)
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , LAST NZ COMPONENTS OF CY SET TO ZERO
+C                              DUE TO UNDERFLOW, CY(J)=CMPLX(0.0,0.0),
+C                              J = N-NZ+1,...,N
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, REAL(Z) TOO
+C                            LARGE ON KODE=1
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE POWER SERIES FOR
+C         SMALL CABS(Z), THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z),
+C         THE MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN AND A
+C         NEUMANN SERIES FOR IMTERMEDIATE MAGNITUDES, AND THE
+C         UNIFORM ASYMPTOTIC EXPANSIONS FOR I(FNU,Z) AND J(FNU,Z)
+C         FOR LARGE ORDERS. BACKWARD RECURRENCE IS USED TO GENERATE
+C         SEQUENCES OR REDUCE ORDERS WHEN NECESSARY.
+C
+C         THE CALCULATIONS ABOVE ARE DONE IN THE RIGHT HALF PLANE AND
+C         CONTINUED INTO THE LEFT HALF PLANE BY THE FORMULA
+C
+C         I(FNU,Z*EXP(M*PI)) = EXP(M*PI*FNU)*I(FNU,Z)  REAL(Z).GT.0.0
+C                       M = +I OR -I,  I**2=-1
+C
+C         FOR NEGATIVE ORDERS,THE FORMULA
+C
+C              I(-FNU,Z) = I(FNU,Z) + (2/PI)*SIN(PI*FNU)*K(FNU,Z)
+C
+C         CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE
+C         THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE
+C         INTEGER,THE MAGNITUDE OF I(-FNU,Z)=I(FNU,Z) IS A LARGE
+C         NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER,
+C         K(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF
+C         TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY
+C         UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN
+C         OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE,
+C         LARGE MEANS FNU.GT.CABS(Z).
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF. ALSO
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CBINU,I1MACH,R1MACH
+C***END PROLOGUE  CBESI
+      COMPLEX CONE, CSGN, CY, Z, ZN
+      REAL AA, ALIM, ARG, DIG, ELIM, FNU, FNUL, PI, RL, R1M5, S1, S2,
+     * TOL, XX, YY, R1MACH, AZ, FN, BB, ASCLE, RTOL, ATOL
+      INTEGER I, IERR, INU, K, KODE, K1, K2, N, NN, NZ, I1MACH
+      DIMENSION CY(N)
+      DATA PI /3.14159265358979324E0/
+      DATA CONE / (1.0E0,0.0E0) /
+C
+C***FIRST EXECUTABLE STATEMENT  CBESI
+      IERR = 0
+      NZ=0
+      IF (FNU.LT.0.0E0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU.
+C-----------------------------------------------------------------------
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      R1M5 = R1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      K1 = I1MACH(11) - 1
+      AA = R1M5*FLOAT(K1)
+      DIG = AMIN1(AA,18.0E0)
+      AA = AA*2.303E0
+      ALIM = ELIM + AMAX1(-AA,-41.45E0)
+      RL = 1.2E0*DIG + 3.0E0
+      FNUL = 10.0E0 + 6.0E0*(DIG-3.0E0)
+      AZ = CABS(Z)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA = 0.5E0/TOL
+      BB=FLOAT(I1MACH(9))*0.5E0
+      AA=AMIN1(AA,BB)
+      IF(AZ.GT.AA) GO TO 140
+      FN=FNU+FLOAT(N-1)
+      IF(FN.GT.AA) GO TO 140
+      AA=SQRT(AA)
+      IF(AZ.GT.AA) IERR=3
+      IF(FN.GT.AA) IERR=3
+      ZN = Z
+      CSGN = CONE
+      IF (XX.GE.0.0E0) GO TO 40
+      ZN = -Z
+C-----------------------------------------------------------------------
+C     CALCULATE CSGN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(FNU)
+      ARG = (FNU-FLOAT(INU))*PI
+      IF (YY.LT.0.0E0) ARG = -ARG
+      S1 = COS(ARG)
+      S2 = SIN(ARG)
+      CSGN = CMPLX(S1,S2)
+      IF (MOD(INU,2).EQ.1) CSGN = -CSGN
+   40 CONTINUE
+      CALL CBINU(ZN, FNU, KODE, N, CY, NZ, RL, FNUL, TOL, ELIM, ALIM)
+      IF (NZ.LT.0) GO TO 120
+      IF (XX.GE.0.0E0) RETURN
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION TO THE LEFT HALF PLANE
+C-----------------------------------------------------------------------
+      NN = N - NZ
+      IF (NN.EQ.0) RETURN
+      RTOL = 1.0E0/TOL
+      ASCLE = R1MACH(1)*RTOL*1.0E+3
+      DO 50 I=1,NN
+C       CY(I) = CY(I)*CSGN
+        ZN=CY(I)
+        AA=REAL(ZN)
+        BB=AIMAG(ZN)
+        ATOL=1.0E0
+        IF (AMAX1(ABS(AA),ABS(BB)).GT.ASCLE) GO TO 55
+          ZN = ZN*CMPLX(RTOL,0.0E0)
+          ATOL = TOL
+   55   CONTINUE
+        ZN = ZN*CSGN
+        CY(I) = ZN*CMPLX(ATOL,0.0E0)
+        CSGN = -CSGN
+   50 CONTINUE
+      RETURN
+  120 CONTINUE
+      IF(NZ.EQ.(-2)) GO TO 130
+      NZ = 0
+      IERR=2
+      RETURN
+  130 CONTINUE
+      NZ=0
+      IERR=5
+      RETURN
+  140 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/cbesj.f b/libcruft/amos/cbesj.f
new file mode 100644
index 0000000..9038f79
--- /dev/null
+++ b/libcruft/amos/cbesj.f
@@ -0,0 +1,253 @@
+      SUBROUTINE CBESJ(Z, FNU, KODE, N, CY, NZ, IERR)
+C***BEGIN PROLOGUE  CBESJ
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  J-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT,
+C             BESSEL FUNCTION OF FIRST KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE J-BESSEL FUNCTION OF A COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C         ON KODE=1, CBESJ COMPUTES AN N MEMBER  SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(I)=J(FNU+I-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE
+C         -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESJ RETURNS THE SCALED
+C         FUNCTIONS
+C
+C         CY(I)=EXP(-ABS(Y))*J(FNU+I-1,Z)   I = 1,...,N , Y=AIMAG(Z)
+C
+C         WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND
+C         LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION
+C         ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS
+C         (REF. 1).
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y),  -PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL J FUNCTION, FNU.GE.0.0E0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(I)=J(FNU+I-1,Z), I=1,...,N
+C                        = 2  RETURNS
+C                             CY(I)=J(FNU+I-1,Z)*EXP(-ABS(Y)), I=1,...
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C
+C         OUTPUT
+C           CY     - A COMPLEX VECTOR WHOSE FIRST N COMPONENTS CONTAIN
+C                    VALUES FOR THE SEQUENCE
+C                    CY(I)=J(FNU+I-1,Z)  OR
+C                    CY(I)=J(FNU+I-1,Z)*EXP(-ABS(Y))  I=1,...,N
+C                    DEPENDING ON KODE, Y=AIMAG(Z).
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , LAST NZ COMPONENTS OF CY SET TO ZERO
+C                              DUE TO UNDERFLOW, CY(I)=CMPLX(0.0,0.0),
+C                              I = N-NZ+1,...,N
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, AIMAG(Z)
+C                            TOO LARGE ON KODE=1
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE FORMULA
+C
+C         J(FNU,Z)=EXP( FNU*PI*I/2)*I(FNU,-I*Z)    AIMAG(Z).GE.0.0
+C
+C         J(FNU,Z)=EXP(-FNU*PI*I/2)*I(FNU, I*Z)    AIMAG(Z).LT.0.0
+C
+C         WHERE I**2 = -1 AND I(FNU,Z) IS THE I BESSEL FUNCTION.
+C
+C         FOR NEGATIVE ORDERS,THE FORMULA
+C
+C              J(-FNU,Z) = J(FNU,Z)*COS(PI*FNU) - Y(FNU,Z)*SIN(PI*FNU)
+C
+C         CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE
+C         THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE
+C         INTEGER,THE MAGNITUDE OF J(-FNU,Z)=J(FNU,Z)*COS(PI*FNU) IS A
+C         LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER,
+C         Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF
+C         TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY
+C         UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN
+C         OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE,
+C         LARGE MEANS FNU.GT.CABS(Z).
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF. ALSO
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CBINU,I1MACH,R1MACH
+C***END PROLOGUE  CBESJ
+C
+      COMPLEX CI, CSGN, CY, Z, ZN
+      REAL AA, ALIM, ARG, DIG, ELIM, FNU, FNUL, HPI, RL, R1, R1M5, R2,
+     * TOL, YY, R1MACH, AZ, FN, BB, ASCLE, RTOL, ATOL
+      INTEGER I, IERR, INU, INUH, IR, KODE, K1, K2, N, NL, NZ, I1MACH, K
+      DIMENSION CY(N)
+      DATA HPI /1.57079632679489662E0/
+C
+C***FIRST EXECUTABLE STATEMENT  CBESJ
+      IERR = 0
+      NZ=0
+      IF (FNU.LT.0.0E0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU.
+C-----------------------------------------------------------------------
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      R1M5 = R1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      K1 = I1MACH(11) - 1
+      AA = R1M5*FLOAT(K1)
+      DIG = AMIN1(AA,18.0E0)
+      AA = AA*2.303E0
+      ALIM = ELIM + AMAX1(-AA,-41.45E0)
+      RL = 1.2E0*DIG + 3.0E0
+      FNUL = 10.0E0 + 6.0E0*(DIG-3.0E0)
+      CI = CMPLX(0.0E0,1.0E0)
+      YY = AIMAG(Z)
+      AZ = CABS(Z)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA = 0.5E0/TOL
+      BB=FLOAT(I1MACH(9))*0.5E0
+      AA=AMIN1(AA,BB)
+      FN=FNU+FLOAT(N-1)
+      IF(AZ.GT.AA) GO TO 140
+      IF(FN.GT.AA) GO TO 140
+      AA=SQRT(AA)
+      IF(AZ.GT.AA) IERR=3
+      IF(FN.GT.AA) IERR=3
+C-----------------------------------------------------------------------
+C     CALCULATE CSGN=EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(FNU)
+      INUH = INU/2
+      IR = INU - 2*INUH
+      ARG = (FNU-FLOAT(INU-IR))*HPI
+      R1 = COS(ARG)
+      R2 = SIN(ARG)
+      CSGN = CMPLX(R1,R2)
+      IF (MOD(INUH,2).EQ.1) CSGN = -CSGN
+C-----------------------------------------------------------------------
+C     ZN IS IN THE RIGHT HALF PLANE
+C-----------------------------------------------------------------------
+      ZN = -Z*CI
+      IF (YY.GE.0.0E0) GO TO 40
+      ZN = -ZN
+      CSGN = CONJG(CSGN)
+      CI = CONJG(CI)
+   40 CONTINUE
+      CALL CBINU(ZN, FNU, KODE, N, CY, NZ, RL, FNUL, TOL, ELIM, ALIM)
+      IF (NZ.LT.0) GO TO 120
+      NL = N - NZ
+      IF (NL.EQ.0) RETURN
+      RTOL = 1.0E0/TOL
+      ASCLE = R1MACH(1)*RTOL*1.0E+3
+      DO 50 I=1,NL
+C       CY(I)=CY(I)*CSGN
+        ZN=CY(I)
+        AA=REAL(ZN)
+        BB=AIMAG(ZN)
+        ATOL=1.0E0
+        IF (AMAX1(ABS(AA),ABS(BB)).GT.ASCLE) GO TO 55
+          ZN = ZN*CMPLX(RTOL,0.0E0)
+          ATOL = TOL
+   55   CONTINUE
+        ZN = ZN*CSGN
+        CY(I) = ZN*CMPLX(ATOL,0.0E0)
+        CSGN = CSGN*CI
+   50 CONTINUE
+      RETURN
+  120 CONTINUE
+      IF(NZ.EQ.(-2)) GO TO 130
+      NZ = 0
+      IERR = 2
+      RETURN
+  130 CONTINUE
+      NZ=0
+      IERR=5
+      RETURN
+  140 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/cbesk.f b/libcruft/amos/cbesk.f
new file mode 100644
index 0000000..6d346f9
--- /dev/null
+++ b/libcruft/amos/cbesk.f
@@ -0,0 +1,276 @@
+      SUBROUTINE CBESK(Z, FNU, KODE, N, CY, NZ, IERR)
+C***BEGIN PROLOGUE  CBESK
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  K-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION,
+C             MODIFIED BESSEL FUNCTION OF THE SECOND KIND,
+C             BESSEL FUNCTION OF THE THIRD KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE K-BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C         ON KODE=1, CBESK COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(J)=K(FNU+J-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z.NE.CMPLX(0.0,0.0)
+C         IN THE CUT PLANE -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESK
+C         RETURNS THE SCALED K FUNCTIONS,
+C
+C         CY(J)=EXP(Z)*K(FNU+J-1,Z) , J=1,...,N,
+C
+C         WHICH REMOVE THE EXPONENTIAL BEHAVIOR IN BOTH THE LEFT AND
+C         RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND
+C         NOTATION ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL
+C         FUNCTIONS (REF. 1).
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y),Z.NE.CMPLX(0.,0.),-PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL K FUNCTION, FNU.GE.0.0E0
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(I)=K(FNU+I-1,Z), I=1,...,N
+C                        = 2  RETURNS
+C                             CY(I)=K(FNU+I-1,Z)*EXP(Z), I=1,...,N
+C
+C         OUTPUT
+C           CY     - A COMPLEX VECTOR WHOSE FIRST N COMPONENTS CONTAIN
+C                    VALUES FOR THE SEQUENCE
+C                    CY(I)=K(FNU+I-1,Z), I=1,...,N OR
+C                    CY(I)=K(FNU+I-1,Z)*EXP(Z), I=1,...,N
+C                    DEPENDING ON KODE
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW.
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , FIRST NZ COMPONENTS OF CY SET TO ZERO
+C                              DUE TO UNDERFLOW, CY(I)=CMPLX(0.0,0.0),
+C                              I=1,...,N WHEN X.GE.0.0. WHEN X.LT.0.0
+C                              NZ STATES ONLY THE NUMBER OF UNDERFLOWS
+C                              IN THE SEQUENCE.
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, FNU+N-1 IS
+C                            TOO LARGE OR CABS(Z) IS TOO SMALL OR BOTH
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         EQUATIONS OF THE REFERENCE ARE IMPLEMENTED FOR SMALL ORDERS
+C         DNU AND DNU+1.0 IN THE RIGHT HALF PLANE X.GE.0.0. FORWARD
+C         RECURRENCE GENERATES HIGHER ORDERS. K IS CONTINUED TO THE LEFT
+C         HALF PLANE BY THE RELATION
+C
+C         K(FNU,Z*EXP(MP)) = EXP(-MP*FNU)*K(FNU,Z)-MP*I(FNU,Z)
+C         MP=MR*PI*I, MR=+1 OR -1, RE(Z).GT.0, I**2=-1
+C
+C         WHERE I(FNU,Z) IS THE I BESSEL FUNCTION.
+C
+C         FOR LARGE ORDERS, FNU.GT.FNUL, THE K FUNCTION IS COMPUTED
+C         BY MEANS OF ITS UNIFORM ASYMPTOTIC EXPANSIONS.
+C
+C         FOR NEGATIVE ORDERS, THE FORMULA
+C
+C                       K(-FNU,Z) = K(FNU,Z)
+C
+C         CAN BE USED.
+C
+C         CBESK ASSUMES THAT A SIGNIFICANT DIGIT SINH(X) FUNCTION IS
+C         AVAILABLE.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF. ALSO
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983.
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CACON,CBKNU,CBUNK,CUOIK,I1MACH,R1MACH
+C***END PROLOGUE  CBESK
+C
+      COMPLEX CY, Z
+      REAL AA, ALIM, ALN, ARG, AZ, DIG, ELIM, FN, FNU, FNUL, RL, R1M5,
+     * TOL, UFL, XX, YY, R1MACH, BB
+      INTEGER IERR, K, KODE, K1, K2, MR, N, NN, NUF, NW, NZ, I1MACH
+      DIMENSION CY(N)
+C***FIRST EXECUTABLE STATEMENT  CBESK
+      IERR = 0
+      NZ=0
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+      IF (YY.EQ.0.0E0 .AND. XX.EQ.0.0E0) IERR=1
+      IF (FNU.LT.0.0E0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      NN = N
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU
+C-----------------------------------------------------------------------
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      R1M5 = R1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      K1 = I1MACH(11) - 1
+      AA = R1M5*FLOAT(K1)
+      DIG = AMIN1(AA,18.0E0)
+      AA = AA*2.303E0
+      ALIM = ELIM + AMAX1(-AA,-41.45E0)
+      FNUL = 10.0E0 + 6.0E0*(DIG-3.0E0)
+      RL = 1.2E0*DIG + 3.0E0
+      AZ = CABS(Z)
+      FN = FNU + FLOAT(NN-1)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA = 0.5E0/TOL
+      BB=FLOAT(I1MACH(9))*0.5E0
+      AA=AMIN1(AA,BB)
+      IF(AZ.GT.AA) GO TO 210
+      IF(FN.GT.AA) GO TO 210
+      AA=SQRT(AA)
+      IF(AZ.GT.AA) IERR=3
+      IF(FN.GT.AA) IERR=3
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST ON THE LAST MEMBER OF THE SEQUENCE
+C-----------------------------------------------------------------------
+C     UFL = EXP(-ELIM)
+      UFL = R1MACH(1)*1.0E+3
+      IF (AZ.LT.UFL) GO TO 180
+      IF (FNU.GT.FNUL) GO TO 80
+      IF (FN.LE.1.0E0) GO TO 60
+      IF (FN.GT.2.0E0) GO TO 50
+      IF (AZ.GT.TOL) GO TO 60
+      ARG = 0.5E0*AZ
+      ALN = -FN*ALOG(ARG)
+      IF (ALN.GT.ELIM) GO TO 180
+      GO TO 60
+   50 CONTINUE
+      CALL CUOIK(Z, FNU, KODE, 2, NN, CY, NUF, TOL, ELIM, ALIM)
+      IF (NUF.LT.0) GO TO 180
+      NZ = NZ + NUF
+      NN = NN - NUF
+C-----------------------------------------------------------------------
+C     HERE NN=N OR NN=0 SINCE NUF=0,NN, OR -1 ON RETURN FROM CUOIK
+C     IF NUF=NN, THEN CY(I)=CZERO FOR ALL I
+C-----------------------------------------------------------------------
+      IF (NN.EQ.0) GO TO 100
+   60 CONTINUE
+      IF (XX.LT.0.0E0) GO TO 70
+C-----------------------------------------------------------------------
+C     RIGHT HALF PLANE COMPUTATION, REAL(Z).GE.0.
+C-----------------------------------------------------------------------
+      CALL CBKNU(Z, FNU, KODE, NN, CY, NW, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 200
+      NZ=NW
+      RETURN
+C-----------------------------------------------------------------------
+C     LEFT HALF PLANE COMPUTATION
+C     PI/2.LT.ARG(Z).LE.PI AND -PI.LT.ARG(Z).LT.-PI/2.
+C-----------------------------------------------------------------------
+   70 CONTINUE
+      IF (NZ.NE.0) GO TO 180
+      MR = 1
+      IF (YY.LT.0.0E0) MR = -1
+      CALL CACON(Z, FNU, KODE, MR, NN, CY, NW, RL, FNUL, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 200
+      NZ=NW
+      RETURN
+C-----------------------------------------------------------------------
+C     UNIFORM ASYMPTOTIC EXPANSIONS FOR FNU.GT.FNUL
+C-----------------------------------------------------------------------
+   80 CONTINUE
+      MR = 0
+      IF (XX.GE.0.0E0) GO TO 90
+      MR = 1
+      IF (YY.LT.0.0E0) MR = -1
+   90 CONTINUE
+      CALL CBUNK(Z, FNU, KODE, MR, NN, CY, NW, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 200
+      NZ = NZ + NW
+      RETURN
+  100 CONTINUE
+      IF (XX.LT.0.0E0) GO TO 180
+      RETURN
+  180 CONTINUE
+      NZ = 0
+      IERR=2
+      RETURN
+  200 CONTINUE
+      IF(NW.EQ.(-1)) GO TO 180
+      NZ=0
+      IERR=5
+      RETURN
+  210 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/cbesy.f b/libcruft/amos/cbesy.f
new file mode 100644
index 0000000..c029ab7
--- /dev/null
+++ b/libcruft/amos/cbesy.f
@@ -0,0 +1,226 @@
+      SUBROUTINE CBESY(Z, FNU, KODE, N, CY, NZ, CWRK, IERR)
+C***BEGIN PROLOGUE  CBESY
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  Y-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT,
+C             BESSEL FUNCTION OF SECOND KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE Y-BESSEL FUNCTION OF A COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C         ON KODE=1, CBESY COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(I)=Y(FNU+I-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE
+C         -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESY RETURNS THE SCALED
+C         FUNCTIONS
+C
+C         CY(I)=EXP(-ABS(Y))*Y(FNU+I-1,Z)   I = 1,...,N , Y=AIMAG(Z)
+C
+C         WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND
+C         LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION
+C         ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS
+C         (REF. 1).
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y), Z.NE.CMPLX(0.,0.),-PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL Y FUNCTION, FNU.GE.0.0E0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(I)=Y(FNU+I-1,Z), I=1,...,N
+C                        = 2  RETURNS
+C                             CY(I)=Y(FNU+I-1,Z)*EXP(-ABS(Y)), I=1,...,N
+C                             WHERE Y=AIMAG(Z)
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C           CWRK   - A COMPLEX WORK VECTOR OF DIMENSION AT LEAST N
+C
+C         OUTPUT
+C           CY     - A COMPLEX VECTOR WHOSE FIRST N COMPONENTS CONTAIN
+C                    VALUES FOR THE SEQUENCE
+C                    CY(I)=Y(FNU+I-1,Z)  OR
+C                    CY(I)=Y(FNU+I-1,Z)*EXP(-ABS(Y))  I=1,...,N
+C                    DEPENDING ON KODE.
+C           NZ     - NZ=0 , A NORMAL RETURN
+C                    NZ.GT.0 , NZ COMPONENTS OF CY SET TO ZERO DUE TO
+C                    UNDERFLOW (GENERALLY ON KODE=2)
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, FNU+N-1 IS
+C                            TOO LARGE OR CABS(Z) IS TOO SMALL OR BOTH
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE FORMULA
+C
+C         Y(FNU,Z)=0.5*(H(1,FNU,Z)-H(2,FNU,Z))/I
+C
+C         WHERE I**2 = -1 AND THE HANKEL BESSEL FUNCTIONS H(1,FNU,Z)
+C         AND H(2,FNU,Z) ARE CALCULATED IN CBESH.
+C
+C         FOR NEGATIVE ORDERS,THE FORMULA
+C
+C              Y(-FNU,Z) = Y(FNU,Z)*COS(PI*FNU) + J(FNU,Z)*SIN(PI*FNU)
+C
+C         CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO HALF ODD
+C         INTEGERS THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE
+C         POSITIVE HALF ODD INTEGER,THE MAGNITUDE OF Y(-FNU,Z)=J(FNU,Z)*
+C         SIN(PI*FNU) IS A LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS
+C         NOT A HALF ODD INTEGER, Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A
+C         LARGE POSITIVE POWER OF TEN AND THE MOST THAT THE SECOND TERM
+C         CAN BE REDUCED IS BY UNIT ROUNDOFF FROM THE COEFFICIENT. THUS,
+C         WIDE CHANGES CAN OCCUR WITHIN UNIT ROUNDOFF OF A LARGE HALF
+C         ODD INTEGER. HERE, LARGE MEANS FNU.GT.CABS(Z).
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF. ALSO
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CBESH,I1MACH,R1MACH
+C***END PROLOGUE  CBESY
+C
+      COMPLEX CWRK, CY, C1, C2, EX, HCI, Z, ZU, ZV
+      REAL ELIM, EY, FNU, R1, R2, TAY, XX, YY, R1MACH, ASCLE, RTOL,
+     * ATOL, AA, BB
+      INTEGER I, IERR, K, KODE, K1, K2, N, NZ, NZ1, NZ2, I1MACH
+      DIMENSION CY(N), CWRK(N)
+C***FIRST EXECUTABLE STATEMENT  CBESY
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+      IERR = 0
+      NZ=0
+      IF (XX.EQ.0.0E0 .AND. YY.EQ.0.0E0) IERR=1
+      IF (FNU.LT.0.0E0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      HCI = CMPLX(0.0E0,0.5E0)
+      CALL CBESH(Z, FNU, KODE, 1, N, CY, NZ1, IERR)
+      IF (IERR.NE.0.AND.IERR.NE.3) GO TO 170
+      CALL CBESH(Z, FNU, KODE, 2, N, CWRK, NZ2, IERR)
+      IF (IERR.NE.0.AND.IERR.NE.3) GO TO 170
+      NZ = MIN0(NZ1,NZ2)
+      IF (KODE.EQ.2) GO TO 60
+      DO 50 I=1,N
+        CY(I) = HCI*(CWRK(I)-CY(I))
+   50 CONTINUE
+      RETURN
+   60 CONTINUE
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      K = MIN0(IABS(K1),IABS(K2))
+      R1M5 = R1MACH(5)
+C-----------------------------------------------------------------------
+C     ELIM IS THE APPROXIMATE EXPONENTIAL UNDER- AND OVERFLOW LIMIT
+C-----------------------------------------------------------------------
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      R1 = COS(XX)
+      R2 = SIN(XX)
+      EX = CMPLX(R1,R2)
+      EY = 0.0E0
+      TAY = ABS(YY+YY)
+      IF (TAY.LT.ELIM) EY = EXP(-TAY)
+      IF (YY.LT.0.0E0) GO TO 90
+      C1 = EX*CMPLX(EY,0.0E0)
+      C2 = CONJG(EX)
+   70 CONTINUE
+      NZ = 0
+      RTOL = 1.0E0/TOL
+      ASCLE = R1MACH(1)*RTOL*1.0E+3
+      DO 80 I=1,N
+C       CY(I) = HCI*(C2*CWRK(I)-C1*CY(I))
+        ZV = CWRK(I)
+        AA=REAL(ZV)
+        BB=AIMAG(ZV)
+        ATOL=1.0E0
+        IF (AMAX1(ABS(AA),ABS(BB)).GT.ASCLE) GO TO 75
+          ZV = ZV*CMPLX(RTOL,0.0E0)
+          ATOL = TOL
+   75   CONTINUE
+        ZV = ZV*C2*HCI
+        ZV = ZV*CMPLX(ATOL,0.0E0)
+        ZU=CY(I)
+        AA=REAL(ZU)
+        BB=AIMAG(ZU)
+        ATOL=1.0E0
+        IF (AMAX1(ABS(AA),ABS(BB)).GT.ASCLE) GO TO 85
+          ZU = ZU*CMPLX(RTOL,0.0E0)
+          ATOL = TOL
+   85   CONTINUE
+        ZU = ZU*C1*HCI
+        ZU = ZU*CMPLX(ATOL,0.0E0)
+        CY(I) = ZV - ZU
+        IF (CY(I).EQ.CMPLX(0.0E0,0.0E0) .AND. EY.EQ.0.0E0) NZ = NZ + 1
+   80 CONTINUE
+      RETURN
+   90 CONTINUE
+      C1 = EX
+      C2 = CONJG(EX)*CMPLX(EY,0.0E0)
+      GO TO 70
+  170 CONTINUE
+      NZ = 0
+      RETURN
+      END
diff --git a/libcruft/amos/cbinu.f b/libcruft/amos/cbinu.f
new file mode 100644
index 0000000..6a8a55e
--- /dev/null
+++ b/libcruft/amos/cbinu.f
@@ -0,0 +1,105 @@
+      SUBROUTINE CBINU(Z, FNU, KODE, N, CY, NZ, RL, FNUL, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  CBINU
+C***REFER TO  CBESH,CBESI,CBESJ,CBESK,CAIRY,CBIRY
+C
+C     CBINU COMPUTES THE I FUNCTION IN THE RIGHT HALF Z PLANE
+C
+C***ROUTINES CALLED  CASYI,CBUNI,CMLRI,CSERI,CUOIK,CWRSK
+C***END PROLOGUE  CBINU
+      COMPLEX CW, CY, CZERO, Z
+      REAL ALIM, AZ, DFNU, ELIM, FNU, FNUL, RL, TOL
+      INTEGER I, INW, KODE, N, NLAST, NN, NUI, NW, NZ
+      DIMENSION CY(N), CW(2)
+      DATA CZERO / (0.0E0,0.0E0) /
+C
+      NZ = 0
+      AZ = CABS(Z)
+      NN = N
+      DFNU = FNU + FLOAT(N-1)
+      IF (AZ.LE.2.0E0) GO TO 10
+      IF (AZ*AZ*0.25E0.GT.DFNU+1.0E0) GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     POWER SERIES
+C-----------------------------------------------------------------------
+      CALL CSERI(Z, FNU, KODE, NN, CY, NW, TOL, ELIM, ALIM)
+      INW = IABS(NW)
+      NZ = NZ + INW
+      NN = NN - INW
+      IF (NN.EQ.0) RETURN
+      IF (NW.GE.0) GO TO 120
+      DFNU = FNU + FLOAT(NN-1)
+   20 CONTINUE
+      IF (AZ.LT.RL) GO TO 40
+      IF (DFNU.LE.1.0E0) GO TO 30
+      IF (AZ+AZ.LT.DFNU*DFNU) GO TO 50
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR LARGE Z
+C-----------------------------------------------------------------------
+   30 CONTINUE
+      CALL CASYI(Z, FNU, KODE, NN, CY, NW, RL, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 130
+      GO TO 120
+   40 CONTINUE
+      IF (DFNU.LE.1.0E0) GO TO 70
+   50 CONTINUE
+C-----------------------------------------------------------------------
+C     OVERFLOW AND UNDERFLOW TEST ON I SEQUENCE FOR MILLER ALGORITHM
+C-----------------------------------------------------------------------
+      CALL CUOIK(Z, FNU, KODE, 1, NN, CY, NW, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 130
+      NZ = NZ + NW
+      NN = NN - NW
+      IF (NN.EQ.0) RETURN
+      DFNU = FNU+FLOAT(NN-1)
+      IF (DFNU.GT.FNUL) GO TO 110
+      IF (AZ.GT.FNUL) GO TO 110
+   60 CONTINUE
+      IF (AZ.GT.RL) GO TO 80
+   70 CONTINUE
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM NORMALIZED BY THE SERIES
+C-----------------------------------------------------------------------
+      CALL CMLRI(Z, FNU, KODE, NN, CY, NW, TOL)
+      IF(NW.LT.0) GO TO 130
+      GO TO 120
+   80 CONTINUE
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST ON K FUNCTIONS USED IN WRONSKIAN
+C-----------------------------------------------------------------------
+      CALL CUOIK(Z, FNU, KODE, 2, 2, CW, NW, TOL, ELIM, ALIM)
+      IF (NW.GE.0) GO TO 100
+      NZ = NN
+      DO 90 I=1,NN
+        CY(I) = CZERO
+   90 CONTINUE
+      RETURN
+  100 CONTINUE
+      IF (NW.GT.0) GO TO 130
+      CALL CWRSK(Z, FNU, KODE, NN, CY, NW, CW, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 130
+      GO TO 120
+  110 CONTINUE
+C-----------------------------------------------------------------------
+C     INCREMENT FNU+NN-1 UP TO FNUL, COMPUTE AND RECUR BACKWARD
+C-----------------------------------------------------------------------
+      NUI = INT(FNUL-DFNU) + 1
+      NUI = MAX0(NUI,0)
+      CALL CBUNI(Z, FNU, KODE, NN, CY, NW, NUI, NLAST, FNUL, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 130
+      NZ = NZ + NW
+      IF (NLAST.EQ.0) GO TO 120
+      NN = NLAST
+      GO TO 60
+  120 CONTINUE
+      RETURN
+  130 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/cbiry.f b/libcruft/amos/cbiry.f
new file mode 100644
index 0000000..69068ee
--- /dev/null
+++ b/libcruft/amos/cbiry.f
@@ -0,0 +1,309 @@
+      SUBROUTINE CBIRY(Z, ID, KODE, BI, IERR)
+C***BEGIN PROLOGUE  CBIRY
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE AIRY FUNCTIONS BI(Z) AND DBI(Z) FOR COMPLEX Z
+C***DESCRIPTION
+C
+C         ON KODE=1, CBIRY COMPUTES THE COMPLEX AIRY FUNCTION BI(Z) OR
+C         ITS DERIVATIVE DBI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON
+C         KODE=2, A SCALING OPTION CEXP(-AXZTA)*BI(Z) OR CEXP(-AXZTA)*
+C         DBI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL BEHAVIOR IN
+C         BOTH THE LEFT AND RIGHT HALF PLANES WHERE
+C         ZTA=(2/3)*Z*CSQRT(Z)=CMPLX(XZTA,YZTA) AND AXZTA=ABS(XZTA).
+C         DEFINITIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF
+C         MATHEMATICAL FUNCTIONS (REF. 1).
+C
+C         INPUT
+C           Z      - Z=CMPLX(X,Y)
+C           ID     - ORDER OF DERIVATIVE, ID=0 OR ID=1
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             BI=BI(Z)                 ON ID=0 OR
+C                             BI=DBI(Z)/DZ             ON ID=1
+C                        = 2  RETURNS
+C                             BI=CEXP(-AXZTA)*BI(Z)     ON ID=0 OR
+C                             BI=CEXP(-AXZTA)*DBI(Z)/DZ ON ID=1 WHERE
+C                             ZTA=(2/3)*Z*CSQRT(Z)=CMPLX(XZTA,YZTA)
+C                             AND AXZTA=ABS(XZTA)
+C
+C         OUTPUT
+C           BI     - COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND
+C                    KODE
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, REAL(Z)
+C                            TOO LARGE WITH KODE=1
+C                    IERR=3, CABS(Z) LARGE      - COMPUTATION COMPLETED
+C                            LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION
+C                            PRODUCE LESS THAN HALF OF MACHINE ACCURACY
+C                    IERR=4, CABS(Z) TOO LARGE  - NO COMPUTATION
+C                            COMPLETE LOSS OF ACCURACY BY ARGUMENT
+C                            REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         BI AND DBI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE I BESSEL
+C         FUNCTIONS BY
+C
+C                BI(Z)=C*SQRT(Z)*( I(-1/3,ZTA) + I(1/3,ZTA) )
+C               DBI(Z)=C *  Z  * ( I(-2/3,ZTA) + I(2/3,ZTA) )
+C                               C=1.0/SQRT(3.0)
+C                               ZTA=(2/3)*Z**(3/2)
+C
+C         WITH THE POWER SERIES FOR CABS(Z).LE.1.0.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES
+C         OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF
+C         THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR),
+C         THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR
+C         FLAG IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF.
+C         ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN
+C         ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT
+C         FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE
+C         LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA
+C         MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2,
+C         AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE
+C         PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE
+C         PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT-
+C         ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG-
+C         NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN
+C         DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN
+C         EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES,
+C         NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE
+C         PRECISION ARITHMETIC.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  CBINU,I1MACH,R1MACH
+C***END PROLOGUE  CBIRY
+      COMPLEX BI, CONE, CSQ, CY, S1, S2, TRM1, TRM2, Z, ZTA, Z3
+      REAL AA, AD, AK, ALIM, ATRM, AZ, AZ3, BB, BK, CK, COEF, C1, C2,
+     * DIG, DK, D1, D2, ELIM, FID, FMR, FNU, FNUL, PI, RL, R1M5, SFAC,
+     * TOL, TTH, ZI, ZR, Z3I, Z3R, R1MACH
+      INTEGER ID, IERR, K, KODE, K1, K2, NZ, I1MACH
+      DIMENSION CY(2)
+      DATA TTH, C1, C2, COEF, PI /6.66666666666666667E-01,
+     * 6.14926627446000736E-01,4.48288357353826359E-01,
+     * 5.77350269189625765E-01,3.14159265358979324E+00/
+      DATA  CONE / (1.0E0,0.0E0) /
+C***FIRST EXECUTABLE STATEMENT  CBIRY
+      IERR = 0
+      NZ=0
+      IF (ID.LT.0 .OR. ID.GT.1) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (IERR.NE.0) RETURN
+      AZ = CABS(Z)
+      TOL = AMAX1(R1MACH(4),1.0E-18)
+      FID = FLOAT(ID)
+      IF (AZ.GT.1.0E0) GO TO 60
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR CABS(Z).LE.1.
+C-----------------------------------------------------------------------
+      S1 = CONE
+      S2 = CONE
+      IF (AZ.LT.TOL) GO TO 110
+      AA = AZ*AZ
+      IF (AA.LT.TOL/AZ) GO TO 40
+      TRM1 = CONE
+      TRM2 = CONE
+      ATRM = 1.0E0
+      Z3 = Z*Z*Z
+      AZ3 = AZ*AA
+      AK = 2.0E0 + FID
+      BK = 3.0E0 - FID - FID
+      CK = 4.0E0 - FID
+      DK = 3.0E0 + FID + FID
+      D1 = AK*DK
+      D2 = BK*CK
+      AD = AMIN1(D1,D2)
+      AK = 24.0E0 + 9.0E0*FID
+      BK = 30.0E0 - 9.0E0*FID
+      Z3R = REAL(Z3)
+      Z3I = AIMAG(Z3)
+      DO 30 K=1,25
+        TRM1 = TRM1*CMPLX(Z3R/D1,Z3I/D1)
+        S1 = S1 + TRM1
+        TRM2 = TRM2*CMPLX(Z3R/D2,Z3I/D2)
+        S2 = S2 + TRM2
+        ATRM = ATRM*AZ3/AD
+        D1 = D1 + AK
+        D2 = D2 + BK
+        AD = AMIN1(D1,D2)
+        IF (ATRM.LT.TOL*AD) GO TO 40
+        AK = AK + 18.0E0
+        BK = BK + 18.0E0
+   30 CONTINUE
+   40 CONTINUE
+      IF (ID.EQ.1) GO TO 50
+      BI = S1*CMPLX(C1,0.0E0) + Z*S2*CMPLX(C2,0.0E0)
+      IF (KODE.EQ.1) RETURN
+      ZTA = Z*CSQRT(Z)*CMPLX(TTH,0.0E0)
+      AA = REAL(ZTA)
+      AA = -ABS(AA)
+      BI = BI*CMPLX(EXP(AA),0.0E0)
+      RETURN
+   50 CONTINUE
+      BI = S2*CMPLX(C2,0.0E0)
+      IF (AZ.GT.TOL) BI = BI + Z*Z*S1*CMPLX(C1/(1.0E0+FID),0.0E0)
+      IF (KODE.EQ.1) RETURN
+      ZTA = Z*CSQRT(Z)*CMPLX(TTH,0.0E0)
+      AA = REAL(ZTA)
+      AA = -ABS(AA)
+      BI = BI*CMPLX(EXP(AA),0.0E0)
+      RETURN
+C-----------------------------------------------------------------------
+C     CASE FOR CABS(Z).GT.1.0
+C-----------------------------------------------------------------------
+   60 CONTINUE
+      FNU = (1.0E0+FID)/3.0E0
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU.
+C-----------------------------------------------------------------------
+      K1 = I1MACH(12)
+      K2 = I1MACH(13)
+      R1M5 = R1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303E0*(FLOAT(K)*R1M5-3.0E0)
+      K1 = I1MACH(11) - 1
+      AA = R1M5*FLOAT(K1)
+      DIG = AMIN1(AA,18.0E0)
+      AA = AA*2.303E0
+      ALIM = ELIM + AMAX1(-AA,-41.45E0)
+      RL = 1.2E0*DIG + 3.0E0
+      FNUL = 10.0E0 + 6.0E0*(DIG-3.0E0)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA=0.5E0/TOL
+      BB=FLOAT(I1MACH(9))*0.5E0
+      AA=AMIN1(AA,BB)
+      AA=AA**TTH
+      IF (AZ.GT.AA) GO TO 190
+      AA=SQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      CSQ=CSQRT(Z)
+      ZTA=Z*CSQ*CMPLX(TTH,0.0E0)
+C-----------------------------------------------------------------------
+C     RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL
+C-----------------------------------------------------------------------
+      SFAC = 1.0E0
+      ZI = AIMAG(Z)
+      ZR = REAL(Z)
+      AK = AIMAG(ZTA)
+      IF (ZR.GE.0.0E0) GO TO 70
+      BK = REAL(ZTA)
+      CK = -ABS(BK)
+      ZTA = CMPLX(CK,AK)
+   70 CONTINUE
+      IF (ZI.EQ.0.0E0 .AND. ZR.LE.0.0E0) ZTA = CMPLX(0.0E0,AK)
+      AA = REAL(ZTA)
+      IF (KODE.EQ.2) GO TO 80
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      BB = ABS(AA)
+      IF (BB.LT.ALIM) GO TO 80
+      BB = BB + 0.25E0*ALOG(AZ)
+      SFAC = TOL
+      IF (BB.GT.ELIM) GO TO 170
+   80 CONTINUE
+      FMR = 0.0E0
+      IF (AA.GE.0.0E0 .AND. ZR.GT.0.0E0) GO TO 90
+      FMR = PI
+      IF (ZI.LT.0.0E0) FMR = -PI
+      ZTA = -ZTA
+   90 CONTINUE
+C-----------------------------------------------------------------------
+C     AA=FACTOR FOR ANALYTIC CONTINUATION OF I(FNU,ZTA)
+C     KODE=2 RETURNS EXP(-ABS(XZTA))*I(FNU,ZTA) FROM CBINU
+C-----------------------------------------------------------------------
+      CALL CBINU(ZTA, FNU, KODE, 1, CY, NZ, RL, FNUL, TOL, ELIM, ALIM)
+      IF (NZ.LT.0) GO TO 180
+      AA = FMR*FNU
+      Z3 = CMPLX(SFAC,0.0E0)
+      S1 = CY(1)*CMPLX(COS(AA),SIN(AA))*Z3
+      FNU = (2.0E0-FID)/3.0E0
+      CALL CBINU(ZTA, FNU, KODE, 2, CY, NZ, RL, FNUL, TOL, ELIM, ALIM)
+      CY(1) = CY(1)*Z3
+      CY(2) = CY(2)*Z3
+C-----------------------------------------------------------------------
+C     BACKWARD RECUR ONE STEP FOR ORDERS -1/3 OR -2/3
+C-----------------------------------------------------------------------
+      S2 = CY(1)*CMPLX(FNU+FNU,0.0E0)/ZTA + CY(2)
+      AA = FMR*(FNU-1.0E0)
+      S1 = (S1+S2*CMPLX(COS(AA),SIN(AA)))*CMPLX(COEF,0.0E0)
+      IF (ID.EQ.1) GO TO 100
+      S1 = CSQ*S1
+      BI = S1*CMPLX(1.0E0/SFAC,0.0E0)
+      RETURN
+  100 CONTINUE
+      S1 = Z*S1
+      BI = S1*CMPLX(1.0E0/SFAC,0.0E0)
+      RETURN
+  110 CONTINUE
+      AA = C1*(1.0E0-FID) + FID*C2
+      BI = CMPLX(AA,0.0E0)
+      RETURN
+  170 CONTINUE
+      NZ=0
+      IERR=2
+      RETURN
+  180 CONTINUE
+      IF(NZ.EQ.(-1)) GO TO 170
+      NZ=0
+      IERR=5
+      RETURN
+  190 CONTINUE
+      IERR=4
+      NZ=0
+      RETURN
+      END
diff --git a/libcruft/amos/cbknu.f b/libcruft/amos/cbknu.f
new file mode 100644
index 0000000..145c7bf
--- /dev/null
+++ b/libcruft/amos/cbknu.f
@@ -0,0 +1,455 @@
+      SUBROUTINE CBKNU(Z, FNU, KODE, N, Y, NZ, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CBKNU
+C***REFER TO  CBESI,CBESK,CAIRY,CBESH
+C
+C     CBKNU COMPUTES THE K BESSEL FUNCTION IN THE RIGHT HALF Z PLANE
+C
+C***ROUTINES CALLED  CKSCL,CSHCH,GAMLN,I1MACH,R1MACH,CUCHK
+C***END PROLOGUE  CBKNU
+C
+      COMPLEX CCH, CK, COEF, CONE, CRSC, CS, CSCL, CSH, CSR, CSS, CTWO,
+     * CZ, CZERO, F, FMU, P, PT, P1, P2, Q, RZ, SMU, ST, S1, S2, Y, Z,
+     * ZD, CELM, CY
+      REAL AA, AK, ALIM, ASCLE, A1, A2, BB, BK, BRY, CAZ, CC, DNU,
+     * DNU2, ELIM, ETEST, FC, FHS, FK, FKS, FNU, FPI, G1, G2, HPI, PI,
+     * P2I, P2M, P2R, RK, RTHPI, R1, S, SPI, TM, TOL, TTH, T1, T2, XX,
+     * YY, GAMLN, R1MACH, HELIM, ELM, XD, YD, ALAS, AS
+      INTEGER I, IDUM, IFLAG, INU, K, KFLAG, KK, KMAX, KODE, KODED, N,
+     * NZ, I1MACH, NW, J, IC, INUB
+      DIMENSION BRY(3), CC(8), CSS(3), CSR(3), Y(N), CY(2)
+C
+      DATA KMAX / 30 /
+      DATA R1 / 2.0E0 /
+      DATA CZERO,CONE,CTWO /(0.0E0,0.0E0),(1.0E0,0.0E0),(2.0E0,0.0E0)/
+C
+      DATA PI, RTHPI, SPI ,HPI, FPI, TTH /
+     1     3.14159265358979324E0,       1.25331413731550025E0,
+     2     1.90985931710274403E0,       1.57079632679489662E0,
+     3     1.89769999331517738E0,       6.66666666666666666E-01/
+C
+      DATA CC(1), CC(2), CC(3), CC(4), CC(5), CC(6), CC(7), CC(8)/
+     1     5.77215664901532861E-01,    -4.20026350340952355E-02,
+     2    -4.21977345555443367E-02,     7.21894324666309954E-03,
+     3    -2.15241674114950973E-04,    -2.01348547807882387E-05,
+     4     1.13302723198169588E-06,     6.11609510448141582E-09/
+C
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+      CAZ = CABS(Z)
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      CRSC = CMPLX(TOL,0.0E0)
+      CSS(1) = CSCL
+      CSS(2) = CONE
+      CSS(3) = CRSC
+      CSR(1) = CRSC
+      CSR(2) = CONE
+      CSR(3) = CSCL
+      BRY(1) = 1.0E+3*R1MACH(1)/TOL
+      BRY(2) = 1.0E0/BRY(1)
+      BRY(3) = R1MACH(2)
+      NZ = 0
+      IFLAG = 0
+      KODED = KODE
+      RZ = CTWO/Z
+      INU = INT(FNU+0.5E0)
+      DNU = FNU - FLOAT(INU)
+      IF (ABS(DNU).EQ.0.5E0) GO TO 110
+      DNU2 = 0.0E0
+      IF (ABS(DNU).GT.TOL) DNU2 = DNU*DNU
+      IF (CAZ.GT.R1) GO TO 110
+C-----------------------------------------------------------------------
+C     SERIES FOR CABS(Z).LE.R1
+C-----------------------------------------------------------------------
+      FC = 1.0E0
+      SMU = CLOG(RZ)
+      FMU = SMU*CMPLX(DNU,0.0E0)
+      CALL CSHCH(FMU, CSH, CCH)
+      IF (DNU.EQ.0.0E0) GO TO 10
+      FC = DNU*PI
+      FC = FC/SIN(FC)
+      SMU = CSH*CMPLX(1.0E0/DNU,0.0E0)
+   10 CONTINUE
+      A2 = 1.0E0 + DNU
+C-----------------------------------------------------------------------
+C     GAM(1-Z)*GAM(1+Z)=PI*Z/SIN(PI*Z), T1=1/GAM(1-DNU), T2=1/GAM(1+DNU)
+C-----------------------------------------------------------------------
+      T2 = EXP(-GAMLN(A2,IDUM))
+      T1 = 1.0E0/(T2*FC)
+      IF (ABS(DNU).GT.0.1E0) GO TO 40
+C-----------------------------------------------------------------------
+C     SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU)
+C-----------------------------------------------------------------------
+      AK = 1.0E0
+      S = CC(1)
+      DO 20 K=2,8
+        AK = AK*DNU2
+        TM = CC(K)*AK
+        S = S + TM
+        IF (ABS(TM).LT.TOL) GO TO 30
+   20 CONTINUE
+   30 G1 = -S
+      GO TO 50
+   40 CONTINUE
+      G1 = (T1-T2)/(DNU+DNU)
+   50 CONTINUE
+      G2 = 0.5E0*(T1+T2)*FC
+      G1 = G1*FC
+      F = CMPLX(G1,0.0E0)*CCH + SMU*CMPLX(G2,0.0E0)
+      PT = CEXP(FMU)
+      P = CMPLX(0.5E0/T2,0.0E0)*PT
+      Q = CMPLX(0.5E0/T1,0.0E0)/PT
+      S1 = F
+      S2 = P
+      AK = 1.0E0
+      A1 = 1.0E0
+      CK = CONE
+      BK = 1.0E0 - DNU2
+      IF (INU.GT.0 .OR. N.GT.1) GO TO 80
+C-----------------------------------------------------------------------
+C     GENERATE K(FNU,Z), 0.0D0 .LE. FNU .LT. 0.5D0 AND N=1
+C-----------------------------------------------------------------------
+      IF (CAZ.LT.TOL) GO TO 70
+      CZ = Z*Z*CMPLX(0.25E0,0.0E0)
+      T1 = 0.25E0*CAZ*CAZ
+   60 CONTINUE
+      F = (F*CMPLX(AK,0.0E0)+P+Q)*CMPLX(1.0E0/BK,0.0E0)
+      P = P*CMPLX(1.0E0/(AK-DNU),0.0E0)
+      Q = Q*CMPLX(1.0E0/(AK+DNU),0.0E0)
+      RK = 1.0E0/AK
+      CK = CK*CZ*CMPLX(RK,0.0)
+      S1 = S1 + CK*F
+      A1 = A1*T1*RK
+      BK = BK + AK + AK + 1.0E0
+      AK = AK + 1.0E0
+      IF (A1.GT.TOL) GO TO 60
+   70 CONTINUE
+      Y(1) = S1
+      IF (KODED.EQ.1) RETURN
+      Y(1) = S1*CEXP(Z)
+      RETURN
+C-----------------------------------------------------------------------
+C     GENERATE K(DNU,Z) AND K(DNU+1,Z) FOR FORWARD RECURRENCE
+C-----------------------------------------------------------------------
+   80 CONTINUE
+      IF (CAZ.LT.TOL) GO TO 100
+      CZ = Z*Z*CMPLX(0.25E0,0.0E0)
+      T1 = 0.25E0*CAZ*CAZ
+   90 CONTINUE
+      F = (F*CMPLX(AK,0.0E0)+P+Q)*CMPLX(1.0E0/BK,0.0E0)
+      P = P*CMPLX(1.0E0/(AK-DNU),0.0E0)
+      Q = Q*CMPLX(1.0E0/(AK+DNU),0.0E0)
+      RK = 1.0E0/AK
+      CK = CK*CZ*CMPLX(RK,0.0E0)
+      S1 = S1 + CK*F
+      S2 = S2 + CK*(P-F*CMPLX(AK,0.0E0))
+      A1 = A1*T1*RK
+      BK = BK + AK + AK + 1.0E0
+      AK = AK + 1.0E0
+      IF (A1.GT.TOL) GO TO 90
+  100 CONTINUE
+      KFLAG = 2
+      BK = REAL(SMU)
+      A1 = FNU + 1.0E0
+      AK = A1*ABS(BK)
+      IF (AK.GT.ALIM) KFLAG = 3
+      P2 = S2*CSS(KFLAG)
+      S2 = P2*RZ
+      S1 = S1*CSS(KFLAG)
+      IF (KODED.EQ.1) GO TO 210
+      F = CEXP(Z)
+      S1 = S1*F
+      S2 = S2*F
+      GO TO 210
+C-----------------------------------------------------------------------
+C     IFLAG=0 MEANS NO UNDERFLOW OCCURRED
+C     IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH
+C     KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD
+C     RECURSION
+C-----------------------------------------------------------------------
+  110 CONTINUE
+      COEF = CMPLX(RTHPI,0.0E0)/CSQRT(Z)
+      KFLAG = 2
+      IF (KODED.EQ.2) GO TO 120
+      IF (XX.GT.ALIM) GO TO 290
+C     BLANK LINE
+      A1 = EXP(-XX)*REAL(CSS(KFLAG))
+      PT = CMPLX(A1,0.0E0)*CMPLX(COS(YY),-SIN(YY))
+      COEF = COEF*PT
+  120 CONTINUE
+      IF (ABS(DNU).EQ.0.5E0) GO TO 300
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM FOR CABS(Z).GT.R1
+C-----------------------------------------------------------------------
+      AK = COS(PI*DNU)
+      AK = ABS(AK)
+      IF (AK.EQ.0.0E0) GO TO 300
+      FHS = ABS(0.25E0-DNU2)
+      IF (FHS.EQ.0.0E0) GO TO 300
+C-----------------------------------------------------------------------
+C     COMPUTE R2=F(E). IF CABS(Z).GE.R2, USE FORWARD RECURRENCE TO
+C     DETERMINE THE BACKWARD INDEX K. R2=F(E) IS A STRAIGHT LINE ON
+C     12.LE.E.LE.60. E IS COMPUTED FROM 2**(-E)=B**(1-I1MACH(11))=
+C     TOL WHERE B IS THE BASE OF THE ARITHMETIC.
+C-----------------------------------------------------------------------
+      T1 = FLOAT(I1MACH(11)-1)*R1MACH(5)*3.321928094E0
+      T1 = AMAX1(T1,12.0E0)
+      T1 = AMIN1(T1,60.0E0)
+      T2 = TTH*T1 - 6.0E0
+      IF (XX.NE.0.0E0) GO TO 130
+      T1 = HPI
+      GO TO 140
+  130 CONTINUE
+      T1 = ATAN(YY/XX)
+      T1 = ABS(T1)
+  140 CONTINUE
+      IF (T2.GT.CAZ) GO TO 170
+C-----------------------------------------------------------------------
+C     FORWARD RECURRENCE LOOP WHEN CABS(Z).GE.R2
+C-----------------------------------------------------------------------
+      ETEST = AK/(PI*CAZ*TOL)
+      FK = 1.0E0
+      IF (ETEST.LT.1.0E0) GO TO 180
+      FKS = 2.0E0
+      RK = CAZ + CAZ + 2.0E0
+      A1 = 0.0E0
+      A2 = 1.0E0
+      DO 150 I=1,KMAX
+        AK = FHS/FKS
+        BK = RK/(FK+1.0E0)
+        TM = A2
+        A2 = BK*A2 - AK*A1
+        A1 = TM
+        RK = RK + 2.0E0
+        FKS = FKS + FK + FK + 2.0E0
+        FHS = FHS + FK + FK
+        FK = FK + 1.0E0
+        TM = ABS(A2)*FK
+        IF (ETEST.LT.TM) GO TO 160
+  150 CONTINUE
+      GO TO 310
+  160 CONTINUE
+      FK = FK + SPI*T1*SQRT(T2/CAZ)
+      FHS = ABS(0.25E0-DNU2)
+      GO TO 180
+  170 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE BACKWARD INDEX K FOR CABS(Z).LT.R2
+C-----------------------------------------------------------------------
+      A2 = SQRT(CAZ)
+      AK = FPI*AK/(TOL*SQRT(A2))
+      AA = 3.0E0*T1/(1.0E0+CAZ)
+      BB = 14.7E0*T1/(28.0E0+CAZ)
+      AK = (ALOG(AK)+CAZ*COS(AA)/(1.0E0+0.008E0*CAZ))/COS(BB)
+      FK = 0.12125E0*AK*AK/CAZ + 1.5E0
+  180 CONTINUE
+      K = INT(FK)
+C-----------------------------------------------------------------------
+C     BACKWARD RECURRENCE LOOP FOR MILLER ALGORITHM
+C-----------------------------------------------------------------------
+      FK = FLOAT(K)
+      FKS = FK*FK
+      P1 = CZERO
+      P2 = CMPLX(TOL,0.0E0)
+      CS = P2
+      DO 190 I=1,K
+        A1 = FKS - FK
+        A2 = (FKS+FK)/(A1+FHS)
+        RK = 2.0E0/(FK+1.0E0)
+        T1 = (FK+XX)*RK
+        T2 = YY*RK
+        PT = P2
+        P2 = (P2*CMPLX(T1,T2)-P1)*CMPLX(A2,0.0E0)
+        P1 = PT
+        CS = CS + P2
+        FKS = A1 - FK + 1.0E0
+        FK = FK - 1.0E0
+  190 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE (P2/CS)=(P2/CABS(CS))*(CONJG(CS)/CABS(CS)) FOR BETTER
+C     SCALING
+C-----------------------------------------------------------------------
+      TM = CABS(CS)
+      PT = CMPLX(1.0E0/TM,0.0E0)
+      S1 = PT*P2
+      CS = CONJG(CS)*PT
+      S1 = COEF*S1*CS
+      IF (INU.GT.0 .OR. N.GT.1) GO TO 200
+      ZD = Z
+      IF(IFLAG.EQ.1) GO TO 270
+      GO TO 240
+  200 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE P1/P2=(P1/CABS(P2)*CONJG(P2)/CABS(P2) FOR SCALING
+C-----------------------------------------------------------------------
+      TM = CABS(P2)
+      PT = CMPLX(1.0E0/TM,0.0E0)
+      P1 = PT*P1
+      P2 = CONJG(P2)*PT
+      PT = P1*P2
+      S2 = S1*(CONE+(CMPLX(DNU+0.5E0,0.0E0)-PT)/Z)
+C-----------------------------------------------------------------------
+C     FORWARD RECURSION ON THE THREE TERM RECURSION RELATION WITH
+C     SCALING NEAR EXPONENT EXTREMES ON KFLAG=1 OR KFLAG=3
+C-----------------------------------------------------------------------
+  210 CONTINUE
+      CK = CMPLX(DNU+1.0E0,0.0E0)*RZ
+      IF (N.EQ.1) INU = INU - 1
+      IF (INU.GT.0) GO TO 220
+      IF (N.EQ.1) S1=S2
+      ZD = Z
+      IF(IFLAG.EQ.1) GO TO 270
+      GO TO 240
+  220 CONTINUE
+      INUB = 1
+      IF (IFLAG.EQ.1) GO TO 261
+  225 CONTINUE
+      P1 = CSR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 230 I=INUB,INU
+        ST = S2
+        S2 = CK*S2 + S1
+        S1 = ST
+        CK = CK + RZ
+        IF (KFLAG.GE.3) GO TO 230
+        P2 = S2*P1
+        P2R = REAL(P2)
+        P2I = AIMAG(P2)
+        P2R = ABS(P2R)
+        P2I = ABS(P2I)
+        P2M = AMAX1(P2R,P2I)
+        IF (P2M.LE.ASCLE) GO TO 230
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1 = S1*P1
+        S2 = P2
+        S1 = S1*CSS(KFLAG)
+        S2 = S2*CSS(KFLAG)
+        P1 = CSR(KFLAG)
+  230 CONTINUE
+      IF (N.EQ.1) S1 = S2
+  240 CONTINUE
+      Y(1) = S1*CSR(KFLAG)
+      IF (N.EQ.1) RETURN
+      Y(2) = S2*CSR(KFLAG)
+      IF (N.EQ.2) RETURN
+      KK = 2
+  250 CONTINUE
+      KK = KK + 1
+      IF (KK.GT.N) RETURN
+      P1 = CSR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 260 I=KK,N
+        P2 = S2
+        S2 = CK*S2 + S1
+        S1 = P2
+        CK = CK + RZ
+        P2 = S2*P1
+        Y(I) = P2
+        IF (KFLAG.GE.3) GO TO 260
+        P2R = REAL(P2)
+        P2I = AIMAG(P2)
+        P2R = ABS(P2R)
+        P2I = ABS(P2I)
+        P2M = AMAX1(P2R,P2I)
+        IF (P2M.LE.ASCLE) GO TO 260
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1 = S1*P1
+        S2 = P2
+        S1 = S1*CSS(KFLAG)
+        S2 = S2*CSS(KFLAG)
+        P1 = CSR(KFLAG)
+  260 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     IFLAG=1 CASES, FORWARD RECURRENCE ON SCALED VALUES ON UNDERFLOW
+C-----------------------------------------------------------------------
+  261 CONTINUE
+      HELIM = 0.5E0*ELIM
+      ELM = EXP(-ELIM)
+      CELM = CMPLX(ELM,0.0)
+      ASCLE = BRY(1)
+      ZD = Z
+      XD = XX
+      YD = YY
+      IC = -1
+      J = 2
+      DO 262 I=1,INU
+        ST = S2
+        S2 = CK*S2+S1
+        S1 = ST
+        CK = CK+RZ
+        AS = CABS(S2)
+        ALAS = ALOG(AS)
+        P2R = -XD+ALAS
+        IF(P2R.LT.(-ELIM)) GO TO 263
+        P2 = -ZD+CLOG(S2)
+        P2R = REAL(P2)
+        P2I = AIMAG(P2)
+        P2M = EXP(P2R)/TOL
+        P1 = CMPLX(P2M,0.0E0)*CMPLX(COS(P2I),SIN(P2I))
+        CALL CUCHK(P1,NW,ASCLE,TOL)
+        IF(NW.NE.0) GO TO 263
+        J=3-J
+        CY(J) = P1
+        IF(IC.EQ.(I-1)) GO TO 264
+        IC = I
+        GO TO 262
+  263   CONTINUE
+        IF(ALAS.LT.HELIM) GO TO 262
+        XD = XD-ELIM
+        S1 = S1*CELM
+        S2 = S2*CELM
+        ZD = CMPLX(XD,YD)
+  262 CONTINUE
+      IF(N.EQ.1) S1 = S2
+      GO TO 270
+  264 CONTINUE
+      KFLAG = 1
+      INUB = I+1
+      S2 = CY(J)
+      J = 3 - J
+      S1 = CY(J)
+      IF(INUB.LE.INU) GO TO 225
+      IF(N.EQ.1) S1 = S2
+      GO TO 240
+  270 CONTINUE
+      Y(1) = S1
+      IF (N.EQ.1) GO TO 280
+      Y(2) = S2
+  280 CONTINUE
+      ASCLE = BRY(1)
+      CALL CKSCL(ZD, FNU, N, Y, NZ, RZ, ASCLE, TOL, ELIM)
+      INU = N - NZ
+      IF (INU.LE.0) RETURN
+      KK = NZ + 1
+      S1 = Y(KK)
+      Y(KK) = S1*CSR(1)
+      IF (INU.EQ.1) RETURN
+      KK = NZ + 2
+      S2 = Y(KK)
+      Y(KK) = S2*CSR(1)
+      IF (INU.EQ.2) RETURN
+      T2 = FNU + FLOAT(KK-1)
+      CK = CMPLX(T2,0.0E0)*RZ
+      KFLAG = 1
+      GO TO 250
+  290 CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE BY EXP(Z), IFLAG = 1 CASES
+C-----------------------------------------------------------------------
+      KODED = 2
+      IFLAG = 1
+      KFLAG = 2
+      GO TO 120
+C-----------------------------------------------------------------------
+C     FNU=HALF ODD INTEGER CASE, DNU=-0.5
+C-----------------------------------------------------------------------
+  300 CONTINUE
+      S1 = COEF
+      S2 = COEF
+      GO TO 210
+  310 CONTINUE
+      NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/cbuni.f b/libcruft/amos/cbuni.f
new file mode 100644
index 0000000..0999d72
--- /dev/null
+++ b/libcruft/amos/cbuni.f
@@ -0,0 +1,158 @@
+      SUBROUTINE CBUNI(Z, FNU, KODE, N, Y, NZ, NUI, NLAST, FNUL, TOL,
+     * ELIM, ALIM)
+C***BEGIN PROLOGUE  CBUNI
+C***REFER TO  CBESI,CBESK
+C
+C     CBUNI COMPUTES THE I BESSEL FUNCTION FOR LARGE CABS(Z).GT.
+C     FNUL AND FNU+N-1.LT.FNUL. THE ORDER IS INCREASED FROM
+C     FNU+N-1 GREATER THAN FNUL BY ADDING NUI AND COMPUTING
+C     ACCORDING TO THE UNIFORM ASYMPTOTIC EXPANSION FOR I(FNU,Z)
+C     ON IFORM=1 AND THE EXPANSION FOR J(FNU,Z) ON IFORM=2
+C
+C***ROUTINES CALLED  CUNI1,CUNI2,R1MACH
+C***END PROLOGUE  CBUNI
+      COMPLEX CSCL, CSCR, CY, RZ, ST, S1, S2, Y, Z
+      REAL ALIM, AX, AY, DFNU, ELIM, FNU, FNUI, FNUL, GNU, TOL, XX, YY,
+     * ASCLE, BRY, STR, STI, STM, R1MACH
+      INTEGER I, IFLAG, IFORM, K, KODE, N, NL, NLAST, NUI, NW, NZ
+      DIMENSION Y(N), CY(2), BRY(3)
+      NZ = 0
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+      AX = ABS(XX)*1.7321E0
+      AY = ABS(YY)
+      IFORM = 1
+      IF (AY.GT.AX) IFORM = 2
+      IF (NUI.EQ.0) GO TO 60
+      FNUI = FLOAT(NUI)
+      DFNU = FNU + FLOAT(N-1)
+      GNU = DFNU + FNUI
+      IF (IFORM.EQ.2) GO TO 10
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR I(FNU,Z) FOR LARGE FNU APPLIED IN
+C     -PI/3.LE.ARG(Z).LE.PI/3
+C-----------------------------------------------------------------------
+      CALL CUNI1(Z, GNU, KODE, 2, CY, NW, NLAST, FNUL, TOL, ELIM, ALIM)
+      GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR J(FNU,Z*EXP(M*HPI)) FOR LARGE FNU
+C     APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I
+C     AND HPI=PI/2
+C-----------------------------------------------------------------------
+      CALL CUNI2(Z, GNU, KODE, 2, CY, NW, NLAST, FNUL, TOL, ELIM, ALIM)
+   20 CONTINUE
+      IF (NW.LT.0) GO TO 50
+      IF (NW.NE.0) GO TO 90
+      AY = CABS(CY(1))
+C----------------------------------------------------------------------
+C     SCALE BACKWARD RECURRENCE, BRY(3) IS DEFINED BUT NEVER USED
+C----------------------------------------------------------------------
+      BRY(1) = 1.0E+3*R1MACH(1)/TOL
+      BRY(2) = 1.0E0/BRY(1)
+      BRY(3) = BRY(2)
+      IFLAG = 2
+      ASCLE = BRY(2)
+      AX = 1.0E0
+      CSCL = CMPLX(AX,0.0E0)
+      IF (AY.GT.BRY(1)) GO TO 21
+      IFLAG = 1
+      ASCLE = BRY(1)
+      AX = 1.0E0/TOL
+      CSCL = CMPLX(AX,0.0E0)
+      GO TO 25
+   21 CONTINUE
+      IF (AY.LT.BRY(2)) GO TO 25
+      IFLAG = 3
+      ASCLE = BRY(3)
+      AX = TOL
+      CSCL = CMPLX(AX,0.0E0)
+   25 CONTINUE
+      AY = 1.0E0/AX
+      CSCR = CMPLX(AY,0.0E0)
+      S1 = CY(2)*CSCL
+      S2 = CY(1)*CSCL
+      RZ = CMPLX(2.0E0,0.0E0)/Z
+      DO 30 I=1,NUI
+        ST = S2
+        S2 = CMPLX(DFNU+FNUI,0.0E0)*RZ*S2 + S1
+        S1 = ST
+        FNUI = FNUI - 1.0E0
+        IF (IFLAG.GE.3) GO TO 30
+        ST = S2*CSCR
+        STR = REAL(ST)
+        STI = AIMAG(ST)
+        STR = ABS(STR)
+        STI = ABS(STI)
+        STM = AMAX1(STR,STI)
+        IF (STM.LE.ASCLE) GO TO 30
+        IFLAG = IFLAG+1
+        ASCLE = BRY(IFLAG)
+        S1 = S1*CSCR
+        S2 = ST
+        AX = AX*TOL
+        AY = 1.0E0/AX
+        CSCL = CMPLX(AX,0.0E0)
+        CSCR = CMPLX(AY,0.0E0)
+        S1 = S1*CSCL
+        S2 = S2*CSCL
+   30 CONTINUE
+      Y(N) = S2*CSCR
+      IF (N.EQ.1) RETURN
+      NL = N - 1
+      FNUI = FLOAT(NL)
+      K = NL
+      DO 40 I=1,NL
+        ST = S2
+        S2 = CMPLX(FNU+FNUI,0.0E0)*RZ*S2 + S1
+        S1 = ST
+        ST = S2*CSCR
+        Y(K) = ST
+        FNUI = FNUI - 1.0E0
+        K = K - 1
+        IF (IFLAG.GE.3) GO TO 40
+        STR = REAL(ST)
+        STI = AIMAG(ST)
+        STR = ABS(STR)
+        STI = ABS(STI)
+        STM = AMAX1(STR,STI)
+        IF (STM.LE.ASCLE) GO TO 40
+        IFLAG = IFLAG+1
+        ASCLE = BRY(IFLAG)
+        S1 = S1*CSCR
+        S2 = ST
+        AX = AX*TOL
+        AY = 1.0E0/AX
+        CSCL = CMPLX(AX,0.0E0)
+        CSCR = CMPLX(AY,0.0E0)
+        S1 = S1*CSCL
+        S2 = S2*CSCL
+   40 CONTINUE
+      RETURN
+   50 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+   60 CONTINUE
+      IF (IFORM.EQ.2) GO TO 70
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR I(FNU,Z) FOR LARGE FNU APPLIED IN
+C     -PI/3.LE.ARG(Z).LE.PI/3
+C-----------------------------------------------------------------------
+      CALL CUNI1(Z, FNU, KODE, N, Y, NW, NLAST, FNUL, TOL, ELIM, ALIM)
+      GO TO 80
+   70 CONTINUE
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR J(FNU,Z*EXP(M*HPI)) FOR LARGE FNU
+C     APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I
+C     AND HPI=PI/2
+C-----------------------------------------------------------------------
+      CALL CUNI2(Z, FNU, KODE, N, Y, NW, NLAST, FNUL, TOL, ELIM, ALIM)
+   80 CONTINUE
+      IF (NW.LT.0) GO TO 50
+      NZ = NW
+      RETURN
+   90 CONTINUE
+      NLAST = N
+      RETURN
+      END
diff --git a/libcruft/amos/cbunk.f b/libcruft/amos/cbunk.f
new file mode 100644
index 0000000..79bee7d
--- /dev/null
+++ b/libcruft/amos/cbunk.f
@@ -0,0 +1,36 @@
+      SUBROUTINE CBUNK(Z, FNU, KODE, MR, N, Y, NZ, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CBUNK
+C***REFER TO  CBESK,CBESH
+C
+C     CBUNK COMPUTES THE K BESSEL FUNCTION FOR FNU.GT.FNUL.
+C     ACCORDING TO THE UNIFORM ASYMPTOTIC EXPANSION FOR K(FNU,Z)
+C     IN CUNK1 AND THE EXPANSION FOR H(2,FNU,Z) IN CUNK2
+C
+C***ROUTINES CALLED  CUNK1,CUNK2
+C***END PROLOGUE  CBUNK
+      COMPLEX Y, Z
+      REAL ALIM, AX, AY, ELIM, FNU, TOL, XX, YY
+      INTEGER KODE, MR, N, NZ
+      DIMENSION Y(N)
+      NZ = 0
+      XX = REAL(Z)
+      YY = AIMAG(Z)
+      AX = ABS(XX)*1.7321E0
+      AY = ABS(YY)
+      IF (AY.GT.AX) GO TO 10
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR K(FNU,Z) FOR LARGE FNU APPLIED IN
+C     -PI/3.LE.ARG(Z).LE.PI/3
+C-----------------------------------------------------------------------
+      CALL CUNK1(Z, FNU, KODE, MR, N, Y, NZ, TOL, ELIM, ALIM)
+      GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR H(2,FNU,Z*EXP(M*HPI)) FOR LARGE FNU
+C     APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I
+C     AND HPI=PI/2
+C-----------------------------------------------------------------------
+      CALL CUNK2(Z, FNU, KODE, MR, N, Y, NZ, TOL, ELIM, ALIM)
+   20 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/ckscl.f b/libcruft/amos/ckscl.f
new file mode 100644
index 0000000..83c8474
--- /dev/null
+++ b/libcruft/amos/ckscl.f
@@ -0,0 +1,102 @@
+      SUBROUTINE CKSCL(ZR, FNU, N, Y, NZ, RZ, ASCLE, TOL, ELIM)
+C***BEGIN PROLOGUE  CKSCL
+C***REFER TO  CBKNU,CUNK1,CUNK2
+C
+C     SET K FUNCTIONS TO ZERO ON UNDERFLOW, CONTINUE RECURRENCE
+C     ON SCALED FUNCTIONS UNTIL TWO MEMBERS COME ON SCALE, THEN
+C     RETURN WITH MIN(NZ+2,N) VALUES SCALED BY 1/TOL.
+C
+C***ROUTINES CALLED  CUCHK
+C***END PROLOGUE  CKSCL
+      COMPLEX CK, CS, CY, CZERO, RZ, S1, S2, Y, ZR, ZD, CELM
+      REAL AA, ASCLE, ACS, AS, CSI, CSR, ELIM, FN, FNU, TOL, XX, ZRI,
+     * ELM, ALAS, HELIM
+      INTEGER I, IC, K, KK, N, NN, NW, NZ
+      DIMENSION Y(N), CY(2)
+      DATA CZERO / (0.0E0,0.0E0) /
+C
+      NZ = 0
+      IC = 0
+      XX = REAL(ZR)
+      NN = MIN0(2,N)
+      DO 10 I=1,NN
+        S1 = Y(I)
+        CY(I) = S1
+        AS = CABS(S1)
+        ACS = -XX + ALOG(AS)
+        NZ = NZ + 1
+        Y(I) = CZERO
+        IF (ACS.LT.(-ELIM)) GO TO 10
+        CS = -ZR + CLOG(S1)
+        CSR = REAL(CS)
+        CSI = AIMAG(CS)
+        AA = EXP(CSR)/TOL
+        CS = CMPLX(AA,0.0E0)*CMPLX(COS(CSI),SIN(CSI))
+        CALL CUCHK(CS, NW, ASCLE, TOL)
+        IF (NW.NE.0) GO TO 10
+        Y(I) = CS
+        NZ = NZ - 1
+        IC = I
+   10 CONTINUE
+      IF (N.EQ.1) RETURN
+      IF (IC.GT.1) GO TO 20
+      Y(1) = CZERO
+      NZ = 2
+   20 CONTINUE
+      IF (N.EQ.2) RETURN
+      IF (NZ.EQ.0) RETURN
+      FN = FNU + 1.0E0
+      CK = CMPLX(FN,0.0E0)*RZ
+      S1 = CY(1)
+      S2 = CY(2)
+      HELIM = 0.5E0*ELIM
+      ELM = EXP(-ELIM)
+      CELM = CMPLX(ELM,0.0E0)
+      ZRI =AIMAG(ZR)
+      ZD = ZR
+C
+C     FIND TWO CONSECUTIVE Y VALUES ON SCALE. SCALE RECURRENCE IF
+C     S2 GETS LARGER THAN EXP(ELIM/2)
+C
+      DO 30 I=3,N
+        KK = I
+        CS = S2
+        S2 = CK*S2 + S1
+        S1 = CS
+        CK = CK + RZ
+        AS = CABS(S2)
+        ALAS = ALOG(AS)
+        ACS = -XX + ALAS
+        NZ = NZ + 1
+        Y(I) = CZERO
+        IF (ACS.LT.(-ELIM)) GO TO 25
+        CS = -ZD + CLOG(S2)
+        CSR = REAL(CS)
+        CSI = AIMAG(CS)
+        AA = EXP(CSR)/TOL
+        CS = CMPLX(AA,0.0E0)*CMPLX(COS(CSI),SIN(CSI))
+        CALL CUCHK(CS, NW, ASCLE, TOL)
+        IF (NW.NE.0) GO TO 25
+        Y(I) = CS
+        NZ = NZ - 1
+        IF (IC.EQ.(KK-1)) GO TO 40
+        IC = KK
+        GO TO 30
+   25   CONTINUE
+        IF(ALAS.LT.HELIM) GO TO 30
+        XX = XX-ELIM
+        S1 = S1*CELM
+        S2 = S2*CELM
+        ZD = CMPLX(XX,ZRI)
+   30 CONTINUE
+      NZ = N
+      IF(IC.EQ.N) NZ=N-1
+      GO TO 45
+   40 CONTINUE
+      NZ = KK - 2
+   45 CONTINUE
+      DO 50 K=1,NZ
+        Y(K) = CZERO
+   50 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/cmlri.f b/libcruft/amos/cmlri.f
new file mode 100644
index 0000000..be63b03
--- /dev/null
+++ b/libcruft/amos/cmlri.f
@@ -0,0 +1,155 @@
+      SUBROUTINE CMLRI(Z, FNU, KODE, N, Y, NZ, TOL)
+C***BEGIN PROLOGUE  CMLRI
+C***REFER TO  CBESI,CBESK
+C
+C     CMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY THE
+C     MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES.
+C
+C***ROUTINES CALLED  GAMLN,R1MACH
+C***END PROLOGUE  CMLRI
+      COMPLEX CK, CNORM, CONE, CTWO, CZERO, PT, P1, P2, RZ, SUM, Y, Z
+      REAL ACK, AK, AP, AT, AZ, BK, FKAP, FKK, FLAM, FNF, FNU, RHO,
+     * RHO2, SCLE, TFNF, TOL, TST, X, GAMLN, R1MACH
+      INTEGER I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, KODE, M, N
+      DIMENSION Y(N)
+      DATA CZERO,CONE,CTWO /(0.0E0,0.0E0),(1.0E0,0.0E0),(2.0E0,0.0E0)/
+      SCLE = 1.0E+3*R1MACH(1)/TOL
+      NZ=0
+      AZ = CABS(Z)
+      X = REAL(Z)
+      IAZ = INT(AZ)
+      IFNU = INT(FNU)
+      INU = IFNU + N - 1
+      AT = FLOAT(IAZ) + 1.0E0
+      CK = CMPLX(AT,0.0E0)/Z
+      RZ = CTWO/Z
+      P1 = CZERO
+      P2 = CONE
+      ACK = (AT+1.0E0)/AZ
+      RHO = ACK + SQRT(ACK*ACK-1.0E0)
+      RHO2 = RHO*RHO
+      TST = (RHO2+RHO2)/((RHO2-1.0E0)*(RHO-1.0E0))
+      TST = TST/TOL
+C-----------------------------------------------------------------------
+C     COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES
+C-----------------------------------------------------------------------
+      AK = AT
+      DO 10 I=1,80
+        PT = P2
+        P2 = P1 - CK*P2
+        P1 = PT
+        CK = CK + RZ
+        AP = CABS(P2)
+        IF (AP.GT.TST*AK*AK) GO TO 20
+        AK = AK + 1.0E0
+   10 CONTINUE
+      GO TO 110
+   20 CONTINUE
+      I = I + 1
+      K = 0
+      IF (INU.LT.IAZ) GO TO 40
+C-----------------------------------------------------------------------
+C     COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS
+C-----------------------------------------------------------------------
+      P1 = CZERO
+      P2 = CONE
+      AT = FLOAT(INU) + 1.0E0
+      CK = CMPLX(AT,0.0E0)/Z
+      ACK = AT/AZ
+      TST = SQRT(ACK/TOL)
+      ITIME = 1
+      DO 30 K=1,80
+        PT = P2
+        P2 = P1 - CK*P2
+        P1 = PT
+        CK = CK + RZ
+        AP = CABS(P2)
+        IF (AP.LT.TST) GO TO 30
+        IF (ITIME.EQ.2) GO TO 40
+        ACK = CABS(CK)
+        FLAM = ACK + SQRT(ACK*ACK-1.0E0)
+        FKAP = AP/CABS(P1)
+        RHO = AMIN1(FLAM,FKAP)
+        TST = TST*SQRT(RHO/(RHO*RHO-1.0E0))
+        ITIME = 2
+   30 CONTINUE
+      GO TO 110
+   40 CONTINUE
+C-----------------------------------------------------------------------
+C     BACKWARD RECURRENCE AND SUM NORMALIZING RELATION
+C-----------------------------------------------------------------------
+      K = K + 1
+      KK = MAX0(I+IAZ,K+INU)
+      FKK = FLOAT(KK)
+      P1 = CZERO
+C-----------------------------------------------------------------------
+C     SCALE P2 AND SUM BY SCLE
+C-----------------------------------------------------------------------
+      P2 = CMPLX(SCLE,0.0E0)
+      FNF = FNU - FLOAT(IFNU)
+      TFNF = FNF + FNF
+      BK = GAMLN(FKK+TFNF+1.0E0,IDUM) - GAMLN(FKK+1.0E0,IDUM)
+     *     -GAMLN(TFNF+1.0E0,IDUM)
+      BK = EXP(BK)
+      SUM = CZERO
+      KM = KK - INU
+      DO 50 I=1,KM
+        PT = P2
+        P2 = P1 + CMPLX(FKK+FNF,0.0E0)*RZ*P2
+        P1 = PT
+        AK = 1.0E0 - TFNF/(FKK+TFNF)
+        ACK = BK*AK
+        SUM = SUM + CMPLX(ACK+BK,0.0E0)*P1
+        BK = ACK
+        FKK = FKK - 1.0E0
+   50 CONTINUE
+      Y(N) = P2
+      IF (N.EQ.1) GO TO 70
+      DO 60 I=2,N
+        PT = P2
+        P2 = P1 + CMPLX(FKK+FNF,0.0E0)*RZ*P2
+        P1 = PT
+        AK = 1.0E0 - TFNF/(FKK+TFNF)
+        ACK = BK*AK
+        SUM = SUM + CMPLX(ACK+BK,0.0E0)*P1
+        BK = ACK
+        FKK = FKK - 1.0E0
+        M = N - I + 1
+        Y(M) = P2
+   60 CONTINUE
+   70 CONTINUE
+      IF (IFNU.LE.0) GO TO 90
+      DO 80 I=1,IFNU
+        PT = P2
+        P2 = P1 + CMPLX(FKK+FNF,0.0E0)*RZ*P2
+        P1 = PT
+        AK = 1.0E0 - TFNF/(FKK+TFNF)
+        ACK = BK*AK
+        SUM = SUM + CMPLX(ACK+BK,0.0E0)*P1
+        BK = ACK
+        FKK = FKK - 1.0E0
+   80 CONTINUE
+   90 CONTINUE
+      PT = Z
+      IF (KODE.EQ.2) PT = PT - CMPLX(X,0.0E0)
+      P1 = -CMPLX(FNF,0.0E0)*CLOG(RZ) + PT
+      AP = GAMLN(1.0E0+FNF,IDUM)
+      PT = P1 - CMPLX(AP,0.0E0)
+C-----------------------------------------------------------------------
+C     THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW
+C     IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES
+C-----------------------------------------------------------------------
+      P2 = P2 + SUM
+      AP = CABS(P2)
+      P1 = CMPLX(1.0E0/AP,0.0E0)
+      CK = CEXP(PT)*P1
+      PT = CONJG(P2)*P1
+      CNORM = CK*PT
+      DO 100 I=1,N
+        Y(I) = Y(I)*CNORM
+  100 CONTINUE
+      RETURN
+  110 CONTINUE
+      NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/crati.f b/libcruft/amos/crati.f
new file mode 100644
index 0000000..c1e68c4
--- /dev/null
+++ b/libcruft/amos/crati.f
@@ -0,0 +1,100 @@
+      SUBROUTINE CRATI(Z, FNU, N, CY, TOL)
+C***BEGIN PROLOGUE  CRATI
+C***REFER TO  CBESI,CBESK,CBESH
+C
+C     CRATI COMPUTES RATIOS OF I BESSEL FUNCTIONS BY BACKWARD
+C     RECURRENCE.  THE STARTING INDEX IS DETERMINED BY FORWARD
+C     RECURRENCE AS DESCRIBED IN J. RES. OF NAT. BUR. OF STANDARDS-B,
+C     MATHEMATICAL SCIENCES, VOL 77B, P111-114, SEPTEMBER, 1973,
+C     BESSEL FUNCTIONS I AND J OF COMPLEX ARGUMENT AND INTEGER ORDER,
+C     BY D. J. SOOKNE.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  CRATI
+      COMPLEX CDFNU, CONE, CY, CZERO, PT, P1, P2, RZ, T1, Z
+      REAL AK, AMAGZ, AP1, AP2, ARG, AZ, DFNU, FDNU, FLAM, FNU, FNUP,
+     * RAP1, RHO, TEST, TEST1, TOL
+      INTEGER I, ID, IDNU, INU, ITIME, K, KK, MAGZ, N
+      DIMENSION CY(N)
+      DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
+      AZ = CABS(Z)
+      INU = INT(FNU)
+      IDNU = INU + N - 1
+      FDNU = FLOAT(IDNU)
+      MAGZ = INT(AZ)
+      AMAGZ = FLOAT(MAGZ+1)
+      FNUP = AMAX1(AMAGZ,FDNU)
+      ID = IDNU - MAGZ - 1
+      ITIME = 1
+      K = 1
+      RZ = (CONE+CONE)/Z
+      T1 = CMPLX(FNUP,0.0E0)*RZ
+      P2 = -T1
+      P1 = CONE
+      T1 = T1 + RZ
+      IF (ID.GT.0) ID = 0
+      AP2 = CABS(P2)
+      AP1 = CABS(P1)
+C-----------------------------------------------------------------------
+C     THE OVERFLOW TEST ON K(FNU+I-1,Z) BEFORE THE CALL TO CBKNX
+C     GUARANTEES THAT P2 IS ON SCALE. SCALE TEST1 AND ALL SUBSEQUENT
+C     P2 VALUES BY AP1 TO ENSURE THAT AN OVERFLOW DOES NOT OCCUR
+C     PREMATURELY.
+C-----------------------------------------------------------------------
+      ARG = (AP2+AP2)/(AP1*TOL)
+      TEST1 = SQRT(ARG)
+      TEST = TEST1
+      RAP1 = 1.0E0/AP1
+      P1 = P1*CMPLX(RAP1,0.0E0)
+      P2 = P2*CMPLX(RAP1,0.0E0)
+      AP2 = AP2*RAP1
+   10 CONTINUE
+      K = K + 1
+      AP1 = AP2
+      PT = P2
+      P2 = P1 - T1*P2
+      P1 = PT
+      T1 = T1 + RZ
+      AP2 = CABS(P2)
+      IF (AP1.LE.TEST) GO TO 10
+      IF (ITIME.EQ.2) GO TO 20
+      AK = CABS(T1)*0.5E0
+      FLAM = AK + SQRT(AK*AK-1.0E0)
+      RHO = AMIN1(AP2/AP1,FLAM)
+      TEST = TEST1*SQRT(RHO/(RHO*RHO-1.0E0))
+      ITIME = 2
+      GO TO 10
+   20 CONTINUE
+      KK = K + 1 - ID
+      AK = FLOAT(KK)
+      DFNU = FNU + FLOAT(N-1)
+      CDFNU = CMPLX(DFNU,0.0E0)
+      T1 = CMPLX(AK,0.0E0)
+      P1 = CMPLX(1.0E0/AP2,0.0E0)
+      P2 = CZERO
+      DO 30 I=1,KK
+        PT = P1
+        P1 = RZ*(CDFNU+T1)*P1 + P2
+        P2 = PT
+        T1 = T1 - CONE
+   30 CONTINUE
+      IF (REAL(P1).NE.0.0E0 .OR. AIMAG(P1).NE.0.0E0) GO TO 40
+      P1 = CMPLX(TOL,TOL)
+   40 CONTINUE
+      CY(N) = P2/P1
+      IF (N.EQ.1) RETURN
+      K = N - 1
+      AK = FLOAT(K)
+      T1 = CMPLX(AK,0.0E0)
+      CDFNU = CMPLX(FNU,0.0E0)*RZ
+      DO 60 I=2,N
+        PT = CDFNU + T1*RZ + CY(K+1)
+        IF (REAL(PT).NE.0.0E0 .OR. AIMAG(PT).NE.0.0E0) GO TO 50
+        PT = CMPLX(TOL,TOL)
+   50   CONTINUE
+        CY(K) = CONE/PT
+        T1 = T1 - CONE
+        K = K - 1
+   60 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/cs1s2.f b/libcruft/amos/cs1s2.f
new file mode 100644
index 0000000..a4bdf50
--- /dev/null
+++ b/libcruft/amos/cs1s2.f
@@ -0,0 +1,44 @@
+      SUBROUTINE CS1S2(ZR, S1, S2, NZ, ASCLE, ALIM, IUF)
+C***BEGIN PROLOGUE  CS1S2
+C***REFER TO  CBESK,CAIRY
+C
+C     CS1S2 TESTS FOR A POSSIBLE UNDERFLOW RESULTING FROM THE
+C     ADDITION OF THE I AND K FUNCTIONS IN THE ANALYTIC CON-
+C     TINUATION FORMULA WHERE S1=K FUNCTION AND S2=I FUNCTION.
+C     ON KODE=1 THE I AND K FUNCTIONS ARE DIFFERENT ORDERS OF
+C     MAGNITUDE, BUT FOR KODE=2 THEY CAN BE OF THE SAME ORDER
+C     OF MAGNITUDE AND THE MAXIMUM MUST BE AT LEAST ONE
+C     PRECISION ABOVE THE UNDERFLOW LIMIT.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  CS1S2
+      COMPLEX CZERO, C1, S1, S1D, S2, ZR
+      REAL AA, ALIM, ALN, ASCLE, AS1, AS2, XX
+      INTEGER IUF, NZ
+      DATA CZERO / (0.0E0,0.0E0) /
+      NZ = 0
+      AS1 = CABS(S1)
+      AS2 = CABS(S2)
+      AA = REAL(S1)
+      ALN = AIMAG(S1)
+      IF (AA.EQ.0.0E0 .AND. ALN.EQ.0.0E0) GO TO 10
+      IF (AS1.EQ.0.0E0) GO TO 10
+      XX = REAL(ZR)
+      ALN = -XX - XX + ALOG(AS1)
+      S1D = S1
+      S1 = CZERO
+      AS1 = 0.0E0
+      IF (ALN.LT.(-ALIM)) GO TO 10
+      C1 = CLOG(S1D) - ZR - ZR
+      S1 = CEXP(C1)
+      AS1 = CABS(S1)
+      IUF = IUF + 1
+   10 CONTINUE
+      AA = AMAX1(AS1,AS2)
+      IF (AA.GT.ASCLE) RETURN
+      S1 = CZERO
+      S2 = CZERO
+      NZ = 1
+      IUF = 0
+      RETURN
+      END
diff --git a/libcruft/amos/cseri.f b/libcruft/amos/cseri.f
new file mode 100644
index 0000000..77d66ea
--- /dev/null
+++ b/libcruft/amos/cseri.f
@@ -0,0 +1,154 @@
+      SUBROUTINE CSERI(Z, FNU, KODE, N, Y, NZ, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CSERI
+C***REFER TO  CBESI,CBESK
+C
+C     CSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
+C     MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE
+C     REGION CABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN.
+C     NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO
+C     DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE
+C     CONDITION CABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE
+C     COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ).
+C
+C***ROUTINES CALLED  CUCHK,GAMLN,R1MACH
+C***END PROLOGUE  CSERI
+      COMPLEX AK1, CK, COEF, CONE, CRSC, CZ, CZERO, HZ, RZ, S1, S2, W,
+     * Y, Z
+      REAL AA, ACZ, AK, ALIM, ARM, ASCLE, ATOL, AZ, DFNU, ELIM, FNU,
+     * FNUP, RAK1, RS, RTR1, S, SS, TOL, X, GAMLN, R1MACH
+      INTEGER I, IB, IDUM, IFLAG, IL, K, KODE, L, M, N, NN, NW, NZ
+      DIMENSION Y(N), W(2)
+      DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
+C
+      NZ = 0
+      AZ = CABS(Z)
+      IF (AZ.EQ.0.0E0) GO TO 150
+      X = REAL(Z)
+      ARM = 1.0E+3*R1MACH(1)
+      RTR1 = SQRT(ARM)
+      CRSC = CMPLX(1.0E0,0.0E0)
+      IFLAG = 0
+      IF (AZ.LT.ARM) GO TO 140
+      HZ = Z*CMPLX(0.5E0,0.0E0)
+      CZ = CZERO
+      IF (AZ.GT.RTR1) CZ = HZ*HZ
+      ACZ = CABS(CZ)
+      NN = N
+      CK = CLOG(HZ)
+   10 CONTINUE
+      DFNU = FNU + FLOAT(NN-1)
+      FNUP = DFNU + 1.0E0
+C-----------------------------------------------------------------------
+C     UNDERFLOW TEST
+C-----------------------------------------------------------------------
+      AK1 = CK*CMPLX(DFNU,0.0E0)
+      AK = GAMLN(FNUP,IDUM)
+      AK1 = AK1 - CMPLX(AK,0.0E0)
+      IF (KODE.EQ.2) AK1 = AK1 - CMPLX(X,0.0E0)
+      RAK1 = REAL(AK1)
+      IF (RAK1.GT.(-ELIM)) GO TO 30
+   20 CONTINUE
+      NZ = NZ + 1
+      Y(NN) = CZERO
+      IF (ACZ.GT.DFNU) GO TO 170
+      NN = NN - 1
+      IF (NN.EQ.0) RETURN
+      GO TO 10
+   30 CONTINUE
+      IF (RAK1.GT.(-ALIM)) GO TO 40
+      IFLAG = 1
+      SS = 1.0E0/TOL
+      CRSC = CMPLX(TOL,0.0E0)
+      ASCLE = ARM*SS
+   40 CONTINUE
+      AK = AIMAG(AK1)
+      AA = EXP(RAK1)
+      IF (IFLAG.EQ.1) AA = AA*SS
+      COEF = CMPLX(AA,0.0E0)*CMPLX(COS(AK),SIN(AK))
+      ATOL = TOL*ACZ/FNUP
+      IL = MIN0(2,NN)
+      DO 80 I=1,IL
+        DFNU = FNU + FLOAT(NN-I)
+        FNUP = DFNU + 1.0E0
+        S1 = CONE
+        IF (ACZ.LT.TOL*FNUP) GO TO 60
+        AK1 = CONE
+        AK = FNUP + 2.0E0
+        S = FNUP
+        AA = 2.0E0
+   50   CONTINUE
+        RS = 1.0E0/S
+        AK1 = AK1*CZ*CMPLX(RS,0.0E0)
+        S1 = S1 + AK1
+        S = S + AK
+        AK = AK + 2.0E0
+        AA = AA*ACZ*RS
+        IF (AA.GT.ATOL) GO TO 50
+   60   CONTINUE
+        M = NN - I + 1
+        S2 = S1*COEF
+        W(I) = S2
+        IF (IFLAG.EQ.0) GO TO 70
+        CALL CUCHK(S2, NW, ASCLE, TOL)
+        IF (NW.NE.0) GO TO 20
+   70   CONTINUE
+        Y(M) = S2*CRSC
+        IF (I.NE.IL) COEF = COEF*CMPLX(DFNU,0.0E0)/HZ
+   80 CONTINUE
+      IF (NN.LE.2) RETURN
+      K = NN - 2
+      AK = FLOAT(K)
+      RZ = (CONE+CONE)/Z
+      IF (IFLAG.EQ.1) GO TO 110
+      IB = 3
+   90 CONTINUE
+      DO 100 I=IB,NN
+        Y(K) = CMPLX(AK+FNU,0.0E0)*RZ*Y(K+1) + Y(K+2)
+        AK = AK - 1.0E0
+        K = K - 1
+  100 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     RECUR BACKWARD WITH SCALED VALUES
+C-----------------------------------------------------------------------
+  110 CONTINUE
+C-----------------------------------------------------------------------
+C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE
+C     UNDERFLOW LIMIT = ASCLE = R1MACH(1)*CSCL*1.0E+3
+C-----------------------------------------------------------------------
+      S1 = W(1)
+      S2 = W(2)
+      DO 120 L=3,NN
+        CK = S2
+        S2 = S1 + CMPLX(AK+FNU,0.0E0)*RZ*S2
+        S1 = CK
+        CK = S2*CRSC
+        Y(K) = CK
+        AK = AK - 1.0E0
+        K = K - 1
+        IF (CABS(CK).GT.ASCLE) GO TO 130
+  120 CONTINUE
+      RETURN
+  130 CONTINUE
+      IB = L + 1
+      IF (IB.GT.NN) RETURN
+      GO TO 90
+  140 CONTINUE
+      NZ = N
+      IF (FNU.EQ.0.0E0) NZ = NZ - 1
+  150 CONTINUE
+      Y(1) = CZERO
+      IF (FNU.EQ.0.0E0) Y(1) = CONE
+      IF (N.EQ.1) RETURN
+      DO 160 I=2,N
+        Y(I) = CZERO
+  160 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     RETURN WITH NZ.LT.0 IF CABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE
+C     THE CALCULATION IN CBINU WITH N=N-IABS(NZ)
+C-----------------------------------------------------------------------
+  170 CONTINUE
+      NZ = -NZ
+      RETURN
+      END
diff --git a/libcruft/amos/cshch.f b/libcruft/amos/cshch.f
new file mode 100644
index 0000000..e0008da
--- /dev/null
+++ b/libcruft/amos/cshch.f
@@ -0,0 +1,25 @@
+      SUBROUTINE CSHCH(Z, CSH, CCH)
+C***BEGIN PROLOGUE  CSHCH
+C***REFER TO  CBESK,CBESH
+C
+C     CSHCH COMPUTES THE COMPLEX HYPERBOLIC FUNCTIONS CSH=SINH(X+I*Y)
+C     AND CCH=COSH(X+I*Y), WHERE I**2=-1.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  CSHCH
+      COMPLEX CCH, CSH, Z
+      REAL CCHI, CCHR, CH, CN, CSHI, CSHR, SH, SN, X, Y, COSH, SINH
+      X = REAL(Z)
+      Y = AIMAG(Z)
+      SH = SINH(X)
+      CH = COSH(X)
+      SN = SIN(Y)
+      CN = COS(Y)
+      CSHR = SH*CN
+      CSHI = CH*SN
+      CSH = CMPLX(CSHR,CSHI)
+      CCHR = CH*CN
+      CCHI = SH*SN
+      CCH = CMPLX(CCHR,CCHI)
+      RETURN
+      END
diff --git a/libcruft/amos/cuchk.f b/libcruft/amos/cuchk.f
new file mode 100644
index 0000000..86b2cb1
--- /dev/null
+++ b/libcruft/amos/cuchk.f
@@ -0,0 +1,30 @@
+      SUBROUTINE CUCHK(Y, NZ, ASCLE, TOL)
+C***BEGIN PROLOGUE  CUCHK
+C***REFER TO CSERI,CUOIK,CUNK1,CUNK2,CUNI1,CUNI2,CKSCL
+C
+C      Y ENTERS AS A SCALED QUANTITY WHOSE MAGNITUDE IS GREATER THAN
+C      EXP(-ALIM)=ASCLE=1.0E+3*R1MACH(1)/TOL. THE TEST IS MADE TO SEE
+C      IF THE MAGNITUDE OF THE REAL OR IMAGINARY PART WOULD UNDER FLOW
+C      WHEN Y IS SCALED (BY TOL) TO ITS PROPER VALUE. Y IS ACCEPTED
+C      IF THE UNDERFLOW IS AT LEAST ONE PRECISION BELOW THE MAGNITUDE
+C      OF THE LARGEST COMPONENT; OTHERWISE THE PHASE ANGLE DOES NOT HAVE
+C      ABSOLUTE ACCURACY AND AN UNDERFLOW IS ASSUMED.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  CUCHK
+C
+      COMPLEX Y
+      REAL ASCLE, SS, ST, TOL, YR, YI
+      INTEGER NZ
+      NZ = 0
+      YR = REAL(Y)
+      YI = AIMAG(Y)
+      YR = ABS(YR)
+      YI = ABS(YI)
+      ST = AMIN1(YR,YI)
+      IF (ST.GT.ASCLE) RETURN
+      SS = AMAX1(YR,YI)
+      ST=ST/TOL
+      IF (SS.LT.ST) NZ = 1
+      RETURN
+      END
diff --git a/libcruft/amos/cunhj.f b/libcruft/amos/cunhj.f
new file mode 100644
index 0000000..855b1bc
--- /dev/null
+++ b/libcruft/amos/cunhj.f
@@ -0,0 +1,648 @@
+      SUBROUTINE CUNHJ(Z, FNU, IPMTR, TOL, PHI, ARG, ZETA1, ZETA2,
+     * ASUM, BSUM)
+C***BEGIN PROLOGUE  CUNHJ
+C***REFER TO  CBESI,CBESK
+C
+C     REFERENCES
+C         HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ AND I.A.
+C         STEGUN, AMS55, NATIONAL BUREAU OF STANDARDS, 1965, CHAPTER 9.
+C
+C         ASYMPTOTICS AND SPECIAL FUNCTIONS BY F.W.J. OLVER, ACADEMIC
+C         PRESS, N.Y., 1974, PAGE 420
+C
+C     ABSTRACT
+C         CUNHJ COMPUTES PARAMETERS FOR BESSEL FUNCTIONS C(FNU,Z) =
+C         J(FNU,Z), Y(FNU,Z) OR H(I,FNU,Z) I=1,2 FOR LARGE ORDERS FNU
+C         BY MEANS OF THE UNIFORM ASYMPTOTIC EXPANSION
+C
+C         C(FNU,Z)=C1*PHI*( ASUM*AIRY(ARG) + C2*BSUM*DAIRY(ARG) )
+C
+C         FOR PROPER CHOICES OF C1, C2, AIRY AND DAIRY WHERE AIRY IS
+C         AN AIRY FUNCTION AND DAIRY IS ITS DERIVATIVE.
+C
+C               (2/3)*FNU*ZETA**1.5 = ZETA1-ZETA2,
+C
+C         ZETA1=0.5*FNU*CLOG((1+W)/(1-W)), ZETA2=FNU*W FOR SCALING
+C         PURPOSES IN AIRY FUNCTIONS FROM CAIRY OR CBIRY.
+C
+C         MCONJ=SIGN OF AIMAG(Z), BUT IS AMBIGUOUS WHEN Z IS REAL AND
+C         MUST BE SPECIFIED. IPMTR=0 RETURNS ALL PARAMETERS. IPMTR=
+C         1 COMPUTES ALL EXCEPT ASUM AND BSUM.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  CUNHJ
+      COMPLEX ARG, ASUM, BSUM, CFNU, CONE, CR, CZERO, DR, P, PHI,
+     * PRZTH, PTFN, RFN13, RTZTA, RZTH, SUMA, SUMB, TFN, T2, UP, W, W2,
+     * Z, ZA, ZB, ZC, ZETA, ZETA1, ZETA2, ZTH
+      REAL ALFA, ANG, AP, AR, ATOL, AW2, AZTH, BETA, BR, BTOL, C, EX1,
+     * EX2, FNU, FN13, FN23, GAMA, HPI, PI, PP, RFNU, RFNU2, THPI, TOL,
+     * WI, WR, ZCI, ZCR, ZETAI, ZETAR, ZTHI, ZTHR, ASUMR, ASUMI, BSUMR,
+     * BSUMI, TEST, TSTR, TSTI, AC
+      INTEGER IAS, IBS, IPMTR, IS, J, JR, JU, K, KMAX, KP1, KS, L, LR,
+     * LRP1, L1, L2, M
+      DIMENSION AR(14), BR(14), C(105), ALFA(180), BETA(210), GAMA(30),
+     * AP(30), P(30), UP(14), CR(14), DR(14)
+      DATA AR(1), AR(2), AR(3), AR(4), AR(5), AR(6), AR(7), AR(8),
+     1     AR(9), AR(10), AR(11), AR(12), AR(13), AR(14)/
+     2     1.00000000000000000E+00,     1.04166666666666667E-01,
+     3     8.35503472222222222E-02,     1.28226574556327160E-01,
+     4     2.91849026464140464E-01,     8.81627267443757652E-01,
+     5     3.32140828186276754E+00,     1.49957629868625547E+01,
+     6     7.89230130115865181E+01,     4.74451538868264323E+02,
+     7     3.20749009089066193E+03,     2.40865496408740049E+04,
+     8     1.98923119169509794E+05,     1.79190200777534383E+06/
+      DATA BR(1), BR(2), BR(3), BR(4), BR(5), BR(6), BR(7), BR(8),
+     1     BR(9), BR(10), BR(11), BR(12), BR(13), BR(14)/
+     2     1.00000000000000000E+00,    -1.45833333333333333E-01,
+     3    -9.87413194444444444E-02,    -1.43312053915895062E-01,
+     4    -3.17227202678413548E-01,    -9.42429147957120249E-01,
+     5    -3.51120304082635426E+00,    -1.57272636203680451E+01,
+     6    -8.22814390971859444E+01,    -4.92355370523670524E+02,
+     7    -3.31621856854797251E+03,    -2.48276742452085896E+04,
+     8    -2.04526587315129788E+05,    -1.83844491706820990E+06/
+      DATA C(1), C(2), C(3), C(4), C(5), C(6), C(7), C(8), C(9), C(10),
+     1     C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18),
+     2     C(19), C(20), C(21), C(22), C(23), C(24)/
+     3     1.00000000000000000E+00,    -2.08333333333333333E-01,
+     4     1.25000000000000000E-01,     3.34201388888888889E-01,
+     5    -4.01041666666666667E-01,     7.03125000000000000E-02,
+     6    -1.02581259645061728E+00,     1.84646267361111111E+00,
+     7    -8.91210937500000000E-01,     7.32421875000000000E-02,
+     8     4.66958442342624743E+00,    -1.12070026162229938E+01,
+     9     8.78912353515625000E+00,    -2.36408691406250000E+00,
+     A     1.12152099609375000E-01,    -2.82120725582002449E+01,
+     B     8.46362176746007346E+01,    -9.18182415432400174E+01,
+     C     4.25349987453884549E+01,    -7.36879435947963170E+00,
+     D     2.27108001708984375E-01,     2.12570130039217123E+02,
+     E    -7.65252468141181642E+02,     1.05999045252799988E+03/
+      DATA C(25), C(26), C(27), C(28), C(29), C(30), C(31), C(32),
+     1     C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(40),
+     2     C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48)/
+     3    -6.99579627376132541E+02,     2.18190511744211590E+02,
+     4    -2.64914304869515555E+01,     5.72501420974731445E-01,
+     5    -1.91945766231840700E+03,     8.06172218173730938E+03,
+     6    -1.35865500064341374E+04,     1.16553933368645332E+04,
+     7    -5.30564697861340311E+03,     1.20090291321635246E+03,
+     8    -1.08090919788394656E+02,     1.72772750258445740E+00,
+     9     2.02042913309661486E+04,    -9.69805983886375135E+04,
+     A     1.92547001232531532E+05,    -2.03400177280415534E+05,
+     B     1.22200464983017460E+05,    -4.11926549688975513E+04,
+     C     7.10951430248936372E+03,    -4.93915304773088012E+02,
+     D     6.07404200127348304E+00,    -2.42919187900551333E+05,
+     E     1.31176361466297720E+06,    -2.99801591853810675E+06/
+      DATA C(49), C(50), C(51), C(52), C(53), C(54), C(55), C(56),
+     1     C(57), C(58), C(59), C(60), C(61), C(62), C(63), C(64),
+     2     C(65), C(66), C(67), C(68), C(69), C(70), C(71), C(72)/
+     3     3.76327129765640400E+06,    -2.81356322658653411E+06,
+     4     1.26836527332162478E+06,    -3.31645172484563578E+05,
+     5     4.52187689813627263E+04,    -2.49983048181120962E+03,
+     6     2.43805296995560639E+01,     3.28446985307203782E+06,
+     7    -1.97068191184322269E+07,     5.09526024926646422E+07,
+     8    -7.41051482115326577E+07,     6.63445122747290267E+07,
+     9    -3.75671766607633513E+07,     1.32887671664218183E+07,
+     A    -2.78561812808645469E+06,     3.08186404612662398E+05,
+     B    -1.38860897537170405E+04,     1.10017140269246738E+02,
+     C    -4.93292536645099620E+07,     3.25573074185765749E+08,
+     D    -9.39462359681578403E+08,     1.55359689957058006E+09,
+     E    -1.62108055210833708E+09,     1.10684281682301447E+09/
+      DATA C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(80),
+     1     C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88),
+     2     C(89), C(90), C(91), C(92), C(93), C(94), C(95), C(96)/
+     3    -4.95889784275030309E+08,     1.42062907797533095E+08,
+     4    -2.44740627257387285E+07,     2.24376817792244943E+06,
+     5    -8.40054336030240853E+04,     5.51335896122020586E+02,
+     6     8.14789096118312115E+08,    -5.86648149205184723E+09,
+     7     1.86882075092958249E+10,    -3.46320433881587779E+10,
+     8     4.12801855797539740E+10,    -3.30265997498007231E+10,
+     9     1.79542137311556001E+10,    -6.56329379261928433E+09,
+     A     1.55927986487925751E+09,    -2.25105661889415278E+08,
+     B     1.73951075539781645E+07,    -5.49842327572288687E+05,
+     C     3.03809051092238427E+03,    -1.46792612476956167E+10,
+     D     1.14498237732025810E+11,    -3.99096175224466498E+11,
+     E     8.19218669548577329E+11,    -1.09837515608122331E+12/
+      DATA C(97), C(98), C(99), C(100), C(101), C(102), C(103), C(104),
+     1     C(105)/
+     2     1.00815810686538209E+12,    -6.45364869245376503E+11,
+     3     2.87900649906150589E+11,    -8.78670721780232657E+10,
+     4     1.76347306068349694E+10,    -2.16716498322379509E+09,
+     5     1.43157876718888981E+08,    -3.87183344257261262E+06,
+     6     1.82577554742931747E+04/
+      DATA ALFA(1), ALFA(2), ALFA(3), ALFA(4), ALFA(5), ALFA(6),
+     1     ALFA(7), ALFA(8), ALFA(9), ALFA(10), ALFA(11), ALFA(12),
+     2     ALFA(13), ALFA(14), ALFA(15), ALFA(16), ALFA(17), ALFA(18),
+     3     ALFA(19), ALFA(20), ALFA(21), ALFA(22)/
+     4    -4.44444444444444444E-03,    -9.22077922077922078E-04,
+     5    -8.84892884892884893E-05,     1.65927687832449737E-04,
+     6     2.46691372741792910E-04,     2.65995589346254780E-04,
+     7     2.61824297061500945E-04,     2.48730437344655609E-04,
+     8     2.32721040083232098E-04,     2.16362485712365082E-04,
+     9     2.00738858762752355E-04,     1.86267636637545172E-04,
+     A     1.73060775917876493E-04,     1.61091705929015752E-04,
+     B     1.50274774160908134E-04,     1.40503497391269794E-04,
+     C     1.31668816545922806E-04,     1.23667445598253261E-04,
+     D     1.16405271474737902E-04,     1.09798298372713369E-04,
+     E     1.03772410422992823E-04,     9.82626078369363448E-05/
+      DATA ALFA(23), ALFA(24), ALFA(25), ALFA(26), ALFA(27), ALFA(28),
+     1     ALFA(29), ALFA(30), ALFA(31), ALFA(32), ALFA(33), ALFA(34),
+     2     ALFA(35), ALFA(36), ALFA(37), ALFA(38), ALFA(39), ALFA(40),
+     3     ALFA(41), ALFA(42), ALFA(43), ALFA(44)/
+     4     9.32120517249503256E-05,     8.85710852478711718E-05,
+     5     8.42963105715700223E-05,     8.03497548407791151E-05,
+     6     7.66981345359207388E-05,     7.33122157481777809E-05,
+     7     7.01662625163141333E-05,     6.72375633790160292E-05,
+     8     6.93735541354588974E-04,     2.32241745182921654E-04,
+     9    -1.41986273556691197E-05,    -1.16444931672048640E-04,
+     A    -1.50803558053048762E-04,    -1.55121924918096223E-04,
+     B    -1.46809756646465549E-04,    -1.33815503867491367E-04,
+     C    -1.19744975684254051E-04,    -1.06184319207974020E-04,
+     D    -9.37699549891194492E-05,    -8.26923045588193274E-05,
+     E    -7.29374348155221211E-05,    -6.44042357721016283E-05/
+      DATA ALFA(45), ALFA(46), ALFA(47), ALFA(48), ALFA(49), ALFA(50),
+     1     ALFA(51), ALFA(52), ALFA(53), ALFA(54), ALFA(55), ALFA(56),
+     2     ALFA(57), ALFA(58), ALFA(59), ALFA(60), ALFA(61), ALFA(62),
+     3     ALFA(63), ALFA(64), ALFA(65), ALFA(66)/
+     4    -5.69611566009369048E-05,    -5.04731044303561628E-05,
+     5    -4.48134868008882786E-05,    -3.98688727717598864E-05,
+     6    -3.55400532972042498E-05,    -3.17414256609022480E-05,
+     7    -2.83996793904174811E-05,    -2.54522720634870566E-05,
+     8    -2.28459297164724555E-05,    -2.05352753106480604E-05,
+     9    -1.84816217627666085E-05,    -1.66519330021393806E-05,
+     A    -1.50179412980119482E-05,    -1.35554031379040526E-05,
+     B    -1.22434746473858131E-05,    -1.10641884811308169E-05,
+     C    -3.54211971457743841E-04,    -1.56161263945159416E-04,
+     D     3.04465503594936410E-05,     1.30198655773242693E-04,
+     E     1.67471106699712269E-04,     1.70222587683592569E-04/
+      DATA ALFA(67), ALFA(68), ALFA(69), ALFA(70), ALFA(71), ALFA(72),
+     1     ALFA(73), ALFA(74), ALFA(75), ALFA(76), ALFA(77), ALFA(78),
+     2     ALFA(79), ALFA(80), ALFA(81), ALFA(82), ALFA(83), ALFA(84),
+     3     ALFA(85), ALFA(86), ALFA(87), ALFA(88)/
+     4     1.56501427608594704E-04,     1.36339170977445120E-04,
+     5     1.14886692029825128E-04,     9.45869093034688111E-05,
+     6     7.64498419250898258E-05,     6.07570334965197354E-05,
+     7     4.74394299290508799E-05,     3.62757512005344297E-05,
+     8     2.69939714979224901E-05,     1.93210938247939253E-05,
+     9     1.30056674793963203E-05,     7.82620866744496661E-06,
+     A     3.59257485819351583E-06,     1.44040049814251817E-07,
+     B    -2.65396769697939116E-06,    -4.91346867098485910E-06,
+     C    -6.72739296091248287E-06,    -8.17269379678657923E-06,
+     D    -9.31304715093561232E-06,    -1.02011418798016441E-05,
+     E    -1.08805962510592880E-05,    -1.13875481509603555E-05/
+      DATA ALFA(89), ALFA(90), ALFA(91), ALFA(92), ALFA(93), ALFA(94),
+     1     ALFA(95), ALFA(96), ALFA(97), ALFA(98), ALFA(99), ALFA(100),
+     2     ALFA(101), ALFA(102), ALFA(103), ALFA(104), ALFA(105),
+     3     ALFA(106), ALFA(107), ALFA(108), ALFA(109), ALFA(110)/
+     4    -1.17519675674556414E-05,    -1.19987364870944141E-05,
+     5     3.78194199201772914E-04,     2.02471952761816167E-04,
+     6    -6.37938506318862408E-05,    -2.38598230603005903E-04,
+     7    -3.10916256027361568E-04,    -3.13680115247576316E-04,
+     8    -2.78950273791323387E-04,    -2.28564082619141374E-04,
+     9    -1.75245280340846749E-04,    -1.25544063060690348E-04,
+     A    -8.22982872820208365E-05,    -4.62860730588116458E-05,
+     B    -1.72334302366962267E-05,     5.60690482304602267E-06,
+     C     2.31395443148286800E-05,     3.62642745856793957E-05,
+     D     4.58006124490188752E-05,     5.24595294959114050E-05,
+     E     5.68396208545815266E-05,     5.94349820393104052E-05/
+      DATA ALFA(111), ALFA(112), ALFA(113), ALFA(114), ALFA(115),
+     1     ALFA(116), ALFA(117), ALFA(118), ALFA(119), ALFA(120),
+     2     ALFA(121), ALFA(122), ALFA(123), ALFA(124), ALFA(125),
+     3     ALFA(126), ALFA(127), ALFA(128), ALFA(129), ALFA(130)/
+     4     6.06478527578421742E-05,     6.08023907788436497E-05,
+     5     6.01577894539460388E-05,     5.89199657344698500E-05,
+     6     5.72515823777593053E-05,     5.52804375585852577E-05,
+     7     5.31063773802880170E-05,     5.08069302012325706E-05,
+     8     4.84418647620094842E-05,     4.60568581607475370E-05,
+     9    -6.91141397288294174E-04,    -4.29976633058871912E-04,
+     A     1.83067735980039018E-04,     6.60088147542014144E-04,
+     B     8.75964969951185931E-04,     8.77335235958235514E-04,
+     C     7.49369585378990637E-04,     5.63832329756980918E-04,
+     D     3.68059319971443156E-04,     1.88464535514455599E-04/
+      DATA ALFA(131), ALFA(132), ALFA(133), ALFA(134), ALFA(135),
+     1     ALFA(136), ALFA(137), ALFA(138), ALFA(139), ALFA(140),
+     2     ALFA(141), ALFA(142), ALFA(143), ALFA(144), ALFA(145),
+     3     ALFA(146), ALFA(147), ALFA(148), ALFA(149), ALFA(150)/
+     4     3.70663057664904149E-05,    -8.28520220232137023E-05,
+     5    -1.72751952869172998E-04,    -2.36314873605872983E-04,
+     6    -2.77966150694906658E-04,    -3.02079514155456919E-04,
+     7    -3.12594712643820127E-04,    -3.12872558758067163E-04,
+     8    -3.05678038466324377E-04,    -2.93226470614557331E-04,
+     9    -2.77255655582934777E-04,    -2.59103928467031709E-04,
+     A    -2.39784014396480342E-04,    -2.20048260045422848E-04,
+     B    -2.00443911094971498E-04,    -1.81358692210970687E-04,
+     C    -1.63057674478657464E-04,    -1.45712672175205844E-04,
+     D    -1.29425421983924587E-04,    -1.14245691942445952E-04/
+      DATA ALFA(151), ALFA(152), ALFA(153), ALFA(154), ALFA(155),
+     1     ALFA(156), ALFA(157), ALFA(158), ALFA(159), ALFA(160),
+     2     ALFA(161), ALFA(162), ALFA(163), ALFA(164), ALFA(165),
+     3     ALFA(166), ALFA(167), ALFA(168), ALFA(169), ALFA(170)/
+     4     1.92821964248775885E-03,     1.35592576302022234E-03,
+     5    -7.17858090421302995E-04,    -2.58084802575270346E-03,
+     6    -3.49271130826168475E-03,    -3.46986299340960628E-03,
+     7    -2.82285233351310182E-03,    -1.88103076404891354E-03,
+     8    -8.89531718383947600E-04,     3.87912102631035228E-06,
+     9     7.28688540119691412E-04,     1.26566373053457758E-03,
+     A     1.62518158372674427E-03,     1.83203153216373172E-03,
+     B     1.91588388990527909E-03,     1.90588846755546138E-03,
+     C     1.82798982421825727E-03,     1.70389506421121530E-03,
+     D     1.55097127171097686E-03,     1.38261421852276159E-03/
+      DATA ALFA(171), ALFA(172), ALFA(173), ALFA(174), ALFA(175),
+     1     ALFA(176), ALFA(177), ALFA(178), ALFA(179), ALFA(180)/
+     2     1.20881424230064774E-03,     1.03676532638344962E-03,
+     3     8.71437918068619115E-04,     7.16080155297701002E-04,
+     4     5.72637002558129372E-04,     4.42089819465802277E-04,
+     5     3.24724948503090564E-04,     2.20342042730246599E-04,
+     6     1.28412898401353882E-04,     4.82005924552095464E-05/
+      DATA BETA(1), BETA(2), BETA(3), BETA(4), BETA(5), BETA(6),
+     1     BETA(7), BETA(8), BETA(9), BETA(10), BETA(11), BETA(12),
+     2     BETA(13), BETA(14), BETA(15), BETA(16), BETA(17), BETA(18),
+     3     BETA(19), BETA(20), BETA(21), BETA(22)/
+     4     1.79988721413553309E-02,     5.59964911064388073E-03,
+     5     2.88501402231132779E-03,     1.80096606761053941E-03,
+     6     1.24753110589199202E-03,     9.22878876572938311E-04,
+     7     7.14430421727287357E-04,     5.71787281789704872E-04,
+     8     4.69431007606481533E-04,     3.93232835462916638E-04,
+     9     3.34818889318297664E-04,     2.88952148495751517E-04,
+     A     2.52211615549573284E-04,     2.22280580798883327E-04,
+     B     1.97541838033062524E-04,     1.76836855019718004E-04,
+     C     1.59316899661821081E-04,     1.44347930197333986E-04,
+     D     1.31448068119965379E-04,     1.20245444949302884E-04,
+     E     1.10449144504599392E-04,     1.01828770740567258E-04/
+      DATA BETA(23), BETA(24), BETA(25), BETA(26), BETA(27), BETA(28),
+     1     BETA(29), BETA(30), BETA(31), BETA(32), BETA(33), BETA(34),
+     2     BETA(35), BETA(36), BETA(37), BETA(38), BETA(39), BETA(40),
+     3     BETA(41), BETA(42), BETA(43), BETA(44)/
+     4     9.41998224204237509E-05,     8.74130545753834437E-05,
+     5     8.13466262162801467E-05,     7.59002269646219339E-05,
+     6     7.09906300634153481E-05,     6.65482874842468183E-05,
+     7     6.25146958969275078E-05,     5.88403394426251749E-05,
+     8    -1.49282953213429172E-03,    -8.78204709546389328E-04,
+     9    -5.02916549572034614E-04,    -2.94822138512746025E-04,
+     A    -1.75463996970782828E-04,    -1.04008550460816434E-04,
+     B    -5.96141953046457895E-05,    -3.12038929076098340E-05,
+     C    -1.26089735980230047E-05,    -2.42892608575730389E-07,
+     D     8.05996165414273571E-06,     1.36507009262147391E-05,
+     E     1.73964125472926261E-05,     1.98672978842133780E-05/
+      DATA BETA(45), BETA(46), BETA(47), BETA(48), BETA(49), BETA(50),
+     1     BETA(51), BETA(52), BETA(53), BETA(54), BETA(55), BETA(56),
+     2     BETA(57), BETA(58), BETA(59), BETA(60), BETA(61), BETA(62),
+     3     BETA(63), BETA(64), BETA(65), BETA(66)/
+     4     2.14463263790822639E-05,     2.23954659232456514E-05,
+     5     2.28967783814712629E-05,     2.30785389811177817E-05,
+     6     2.30321976080909144E-05,     2.28236073720348722E-05,
+     7     2.25005881105292418E-05,     2.20981015361991429E-05,
+     8     2.16418427448103905E-05,     2.11507649256220843E-05,
+     9     2.06388749782170737E-05,     2.01165241997081666E-05,
+     A     1.95913450141179244E-05,     1.90689367910436740E-05,
+     B     1.85533719641636667E-05,     1.80475722259674218E-05,
+     C     5.52213076721292790E-04,     4.47932581552384646E-04,
+     D     2.79520653992020589E-04,     1.52468156198446602E-04,
+     E     6.93271105657043598E-05,     1.76258683069991397E-05/
+      DATA BETA(67), BETA(68), BETA(69), BETA(70), BETA(71), BETA(72),
+     1     BETA(73), BETA(74), BETA(75), BETA(76), BETA(77), BETA(78),
+     2     BETA(79), BETA(80), BETA(81), BETA(82), BETA(83), BETA(84),
+     3     BETA(85), BETA(86), BETA(87), BETA(88)/
+     4    -1.35744996343269136E-05,    -3.17972413350427135E-05,
+     5    -4.18861861696693365E-05,    -4.69004889379141029E-05,
+     6    -4.87665447413787352E-05,    -4.87010031186735069E-05,
+     7    -4.74755620890086638E-05,    -4.55813058138628452E-05,
+     8    -4.33309644511266036E-05,    -4.09230193157750364E-05,
+     9    -3.84822638603221274E-05,    -3.60857167535410501E-05,
+     A    -3.37793306123367417E-05,    -3.15888560772109621E-05,
+     B    -2.95269561750807315E-05,    -2.75978914828335759E-05,
+     C    -2.58006174666883713E-05,    -2.41308356761280200E-05,
+     D    -2.25823509518346033E-05,    -2.11479656768912971E-05,
+     E    -1.98200638885294927E-05,    -1.85909870801065077E-05/
+      DATA BETA(89), BETA(90), BETA(91), BETA(92), BETA(93), BETA(94),
+     1     BETA(95), BETA(96), BETA(97), BETA(98), BETA(99), BETA(100),
+     2     BETA(101), BETA(102), BETA(103), BETA(104), BETA(105),
+     3     BETA(106), BETA(107), BETA(108), BETA(109), BETA(110)/
+     4    -1.74532699844210224E-05,    -1.63997823854497997E-05,
+     5    -4.74617796559959808E-04,    -4.77864567147321487E-04,
+     6    -3.20390228067037603E-04,    -1.61105016119962282E-04,
+     7    -4.25778101285435204E-05,     3.44571294294967503E-05,
+     8     7.97092684075674924E-05,     1.03138236708272200E-04,
+     9     1.12466775262204158E-04,     1.13103642108481389E-04,
+     A     1.08651634848774268E-04,     1.01437951597661973E-04,
+     B     9.29298396593363896E-05,     8.40293133016089978E-05,
+     C     7.52727991349134062E-05,     6.69632521975730872E-05,
+     D     5.92564547323194704E-05,     5.22169308826975567E-05,
+     E     4.58539485165360646E-05,     4.01445513891486808E-05/
+      DATA BETA(111), BETA(112), BETA(113), BETA(114), BETA(115),
+     1     BETA(116), BETA(117), BETA(118), BETA(119), BETA(120),
+     2     BETA(121), BETA(122), BETA(123), BETA(124), BETA(125),
+     3     BETA(126), BETA(127), BETA(128), BETA(129), BETA(130)/
+     4     3.50481730031328081E-05,     3.05157995034346659E-05,
+     5     2.64956119950516039E-05,     2.29363633690998152E-05,
+     6     1.97893056664021636E-05,     1.70091984636412623E-05,
+     7     1.45547428261524004E-05,     1.23886640995878413E-05,
+     8     1.04775876076583236E-05,     8.79179954978479373E-06,
+     9     7.36465810572578444E-04,     8.72790805146193976E-04,
+     A     6.22614862573135066E-04,     2.85998154194304147E-04,
+     B     3.84737672879366102E-06,    -1.87906003636971558E-04,
+     C    -2.97603646594554535E-04,    -3.45998126832656348E-04,
+     D    -3.53382470916037712E-04,    -3.35715635775048757E-04/
+      DATA BETA(131), BETA(132), BETA(133), BETA(134), BETA(135),
+     1     BETA(136), BETA(137), BETA(138), BETA(139), BETA(140),
+     2     BETA(141), BETA(142), BETA(143), BETA(144), BETA(145),
+     3     BETA(146), BETA(147), BETA(148), BETA(149), BETA(150)/
+     4    -3.04321124789039809E-04,    -2.66722723047612821E-04,
+     5    -2.27654214122819527E-04,    -1.89922611854562356E-04,
+     6    -1.55058918599093870E-04,    -1.23778240761873630E-04,
+     7    -9.62926147717644187E-05,    -7.25178327714425337E-05,
+     8    -5.22070028895633801E-05,    -3.50347750511900522E-05,
+     9    -2.06489761035551757E-05,    -8.70106096849767054E-06,
+     A     1.13698686675100290E-06,     9.16426474122778849E-06,
+     B     1.56477785428872620E-05,     2.08223629482466847E-05,
+     C     2.48923381004595156E-05,     2.80340509574146325E-05,
+     D     3.03987774629861915E-05,     3.21156731406700616E-05/
+      DATA BETA(151), BETA(152), BETA(153), BETA(154), BETA(155),
+     1     BETA(156), BETA(157), BETA(158), BETA(159), BETA(160),
+     2     BETA(161), BETA(162), BETA(163), BETA(164), BETA(165),
+     3     BETA(166), BETA(167), BETA(168), BETA(169), BETA(170)/
+     4    -1.80182191963885708E-03,    -2.43402962938042533E-03,
+     5    -1.83422663549856802E-03,    -7.62204596354009765E-04,
+     6     2.39079475256927218E-04,     9.49266117176881141E-04,
+     7     1.34467449701540359E-03,     1.48457495259449178E-03,
+     8     1.44732339830617591E-03,     1.30268261285657186E-03,
+     9     1.10351597375642682E-03,     8.86047440419791759E-04,
+     A     6.73073208165665473E-04,     4.77603872856582378E-04,
+     B     3.05991926358789362E-04,     1.60315694594721630E-04,
+     C     4.00749555270613286E-05,    -5.66607461635251611E-05,
+     D    -1.32506186772982638E-04,    -1.90296187989614057E-04/
+      DATA BETA(171), BETA(172), BETA(173), BETA(174), BETA(175),
+     1     BETA(176), BETA(177), BETA(178), BETA(179), BETA(180),
+     2     BETA(181), BETA(182), BETA(183), BETA(184), BETA(185),
+     3     BETA(186), BETA(187), BETA(188), BETA(189), BETA(190)/
+     4    -2.32811450376937408E-04,    -2.62628811464668841E-04,
+     5    -2.82050469867598672E-04,    -2.93081563192861167E-04,
+     6    -2.97435962176316616E-04,    -2.96557334239348078E-04,
+     7    -2.91647363312090861E-04,    -2.83696203837734166E-04,
+     8    -2.73512317095673346E-04,    -2.61750155806768580E-04,
+     9     6.38585891212050914E-03,     9.62374215806377941E-03,
+     A     7.61878061207001043E-03,     2.83219055545628054E-03,
+     B    -2.09841352012720090E-03,    -5.73826764216626498E-03,
+     C    -7.70804244495414620E-03,    -8.21011692264844401E-03,
+     D    -7.65824520346905413E-03,    -6.47209729391045177E-03/
+      DATA BETA(191), BETA(192), BETA(193), BETA(194), BETA(195),
+     1     BETA(196), BETA(197), BETA(198), BETA(199), BETA(200),
+     2     BETA(201), BETA(202), BETA(203), BETA(204), BETA(205),
+     3     BETA(206), BETA(207), BETA(208), BETA(209), BETA(210)/
+     4    -4.99132412004966473E-03,    -3.45612289713133280E-03,
+     5    -2.01785580014170775E-03,    -7.59430686781961401E-04,
+     6     2.84173631523859138E-04,     1.10891667586337403E-03,
+     7     1.72901493872728771E-03,     2.16812590802684701E-03,
+     8     2.45357710494539735E-03,     2.61281821058334862E-03,
+     9     2.67141039656276912E-03,     2.65203073395980430E-03,
+     A     2.57411652877287315E-03,     2.45389126236094427E-03,
+     B     2.30460058071795494E-03,     2.13684837686712662E-03,
+     C     1.95896528478870911E-03,     1.77737008679454412E-03,
+     D     1.59690280765839059E-03,     1.42111975664438546E-03/
+      DATA GAMA(1), GAMA(2), GAMA(3), GAMA(4), GAMA(5), GAMA(6),
+     1     GAMA(7), GAMA(8), GAMA(9), GAMA(10), GAMA(11), GAMA(12),
+     2     GAMA(13), GAMA(14), GAMA(15), GAMA(16), GAMA(17), GAMA(18),
+     3     GAMA(19), GAMA(20), GAMA(21), GAMA(22)/
+     4     6.29960524947436582E-01,     2.51984209978974633E-01,
+     5     1.54790300415655846E-01,     1.10713062416159013E-01,
+     6     8.57309395527394825E-02,     6.97161316958684292E-02,
+     7     5.86085671893713576E-02,     5.04698873536310685E-02,
+     8     4.42600580689154809E-02,     3.93720661543509966E-02,
+     9     3.54283195924455368E-02,     3.21818857502098231E-02,
+     A     2.94646240791157679E-02,     2.71581677112934479E-02,
+     B     2.51768272973861779E-02,     2.34570755306078891E-02,
+     C     2.19508390134907203E-02,     2.06210828235646240E-02,
+     D     1.94388240897880846E-02,     1.83810633800683158E-02,
+     E     1.74293213231963172E-02,     1.65685837786612353E-02/
+      DATA GAMA(23), GAMA(24), GAMA(25), GAMA(26), GAMA(27), GAMA(28),
+     1     GAMA(29), GAMA(30)/
+     2     1.57865285987918445E-02,     1.50729501494095594E-02,
+     3     1.44193250839954639E-02,     1.38184805735341786E-02,
+     4     1.32643378994276568E-02,     1.27517121970498651E-02,
+     5     1.22761545318762767E-02,     1.18338262398482403E-02/
+      DATA EX1, EX2, HPI, PI, THPI /
+     1     3.33333333333333333E-01,     6.66666666666666667E-01,
+     2     1.57079632679489662E+00,     3.14159265358979324E+00,
+     3     4.71238898038468986E+00/
+      DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
+C
+      RFNU = 1.0E0/FNU
+C     ZB = Z*CMPLX(RFNU,0.0E0)
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST (Z/FNU TOO SMALL)
+C-----------------------------------------------------------------------
+      TSTR = REAL(Z)
+      TSTI = AIMAG(Z)
+      TEST = R1MACH(1)*1.0E+3
+      AC = FNU*TEST
+      IF (ABS(TSTR).GT.AC .OR. ABS(TSTI).GT.AC) GO TO 15
+      AC = 2.0E0*ABS(ALOG(TEST))+FNU
+      ZETA1 = CMPLX(AC,0.0E0)
+      ZETA2 = CMPLX(FNU,0.0E0)
+      PHI=CONE
+      ARG=CONE
+      RETURN
+   15 CONTINUE
+      ZB = Z*CMPLX(RFNU,0.0E0)
+      RFNU2 = RFNU*RFNU
+C-----------------------------------------------------------------------
+C     COMPUTE IN THE FOURTH QUADRANT
+C-----------------------------------------------------------------------
+      FN13 = FNU**EX1
+      FN23 = FN13*FN13
+      RFN13 = CMPLX(1.0E0/FN13,0.0E0)
+      W2 = CONE - ZB*ZB
+      AW2 = CABS(W2)
+      IF (AW2.GT.0.25E0) GO TO 130
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR CABS(W2).LE.0.25E0
+C-----------------------------------------------------------------------
+      K = 1
+      P(1) = CONE
+      SUMA = CMPLX(GAMA(1),0.0E0)
+      AP(1) = 1.0E0
+      IF (AW2.LT.TOL) GO TO 20
+      DO 10 K=2,30
+        P(K) = P(K-1)*W2
+        SUMA = SUMA + P(K)*CMPLX(GAMA(K),0.0E0)
+        AP(K) = AP(K-1)*AW2
+        IF (AP(K).LT.TOL) GO TO 20
+   10 CONTINUE
+      K = 30
+   20 CONTINUE
+      KMAX = K
+      ZETA = W2*SUMA
+      ARG = ZETA*CMPLX(FN23,0.0E0)
+      ZA = CSQRT(SUMA)
+      ZETA2 = CSQRT(W2)*CMPLX(FNU,0.0E0)
+      ZETA1 = ZETA2*(CONE+ZETA*ZA*CMPLX(EX2,0.0E0))
+      ZA = ZA + ZA
+      PHI = CSQRT(ZA)*RFN13
+      IF (IPMTR.EQ.1) GO TO 120
+C-----------------------------------------------------------------------
+C     SUM SERIES FOR ASUM AND BSUM
+C-----------------------------------------------------------------------
+      SUMB = CZERO
+      DO 30 K=1,KMAX
+        SUMB = SUMB + P(K)*CMPLX(BETA(K),0.0E0)
+   30 CONTINUE
+      ASUM = CZERO
+      BSUM = SUMB
+      L1 = 0
+      L2 = 30
+      BTOL = TOL*CABS(BSUM)
+      ATOL = TOL
+      PP = 1.0E0
+      IAS = 0
+      IBS = 0
+      IF (RFNU2.LT.TOL) GO TO 110
+      DO 100 IS=2,7
+        ATOL = ATOL/RFNU2
+        PP = PP*RFNU2
+        IF (IAS.EQ.1) GO TO 60
+        SUMA = CZERO
+        DO 40 K=1,KMAX
+          M = L1 + K
+          SUMA = SUMA + P(K)*CMPLX(ALFA(M),0.0E0)
+          IF (AP(K).LT.ATOL) GO TO 50
+   40   CONTINUE
+   50   CONTINUE
+        ASUM = ASUM + SUMA*CMPLX(PP,0.0E0)
+        IF (PP.LT.TOL) IAS = 1
+   60   CONTINUE
+        IF (IBS.EQ.1) GO TO 90
+        SUMB = CZERO
+        DO 70 K=1,KMAX
+          M = L2 + K
+          SUMB = SUMB + P(K)*CMPLX(BETA(M),0.0E0)
+          IF (AP(K).LT.ATOL) GO TO 80
+   70   CONTINUE
+   80   CONTINUE
+        BSUM = BSUM + SUMB*CMPLX(PP,0.0E0)
+        IF (PP.LT.BTOL) IBS = 1
+   90   CONTINUE
+        IF (IAS.EQ.1 .AND. IBS.EQ.1) GO TO 110
+        L1 = L1 + 30
+        L2 = L2 + 30
+  100 CONTINUE
+  110 CONTINUE
+      ASUM = ASUM + CONE
+      PP = RFNU*REAL(RFN13)
+      BSUM = BSUM*CMPLX(PP,0.0E0)
+  120 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     CABS(W2).GT.0.25E0
+C-----------------------------------------------------------------------
+  130 CONTINUE
+      W = CSQRT(W2)
+      WR = REAL(W)
+      WI = AIMAG(W)
+      IF (WR.LT.0.0E0) WR = 0.0E0
+      IF (WI.LT.0.0E0) WI = 0.0E0
+      W = CMPLX(WR,WI)
+      ZA = (CONE+W)/ZB
+      ZC = CLOG(ZA)
+      ZCR = REAL(ZC)
+      ZCI = AIMAG(ZC)
+      IF (ZCI.LT.0.0E0) ZCI = 0.0E0
+      IF (ZCI.GT.HPI) ZCI = HPI
+      IF (ZCR.LT.0.0E0) ZCR = 0.0E0
+      ZC = CMPLX(ZCR,ZCI)
+      ZTH = (ZC-W)*CMPLX(1.5E0,0.0E0)
+      CFNU = CMPLX(FNU,0.0E0)
+      ZETA1 = ZC*CFNU
+      ZETA2 = W*CFNU
+      AZTH = CABS(ZTH)
+      ZTHR = REAL(ZTH)
+      ZTHI = AIMAG(ZTH)
+      ANG = THPI
+      IF (ZTHR.GE.0.0E0 .AND. ZTHI.LT.0.0E0) GO TO 140
+      ANG = HPI
+      IF (ZTHR.EQ.0.0E0) GO TO 140
+      ANG = ATAN(ZTHI/ZTHR)
+      IF (ZTHR.LT.0.0E0) ANG = ANG + PI
+  140 CONTINUE
+      PP = AZTH**EX2
+      ANG = ANG*EX2
+      ZETAR = PP*COS(ANG)
+      ZETAI = PP*SIN(ANG)
+      IF (ZETAI.LT.0.0E0) ZETAI = 0.0E0
+      ZETA = CMPLX(ZETAR,ZETAI)
+      ARG = ZETA*CMPLX(FN23,0.0E0)
+      RTZTA = ZTH/ZETA
+      ZA = RTZTA/W
+      PHI = CSQRT(ZA+ZA)*RFN13
+      IF (IPMTR.EQ.1) GO TO 120
+      TFN = CMPLX(RFNU,0.0E0)/W
+      RZTH = CMPLX(RFNU,0.0E0)/ZTH
+      ZC = RZTH*CMPLX(AR(2),0.0E0)
+      T2 = CONE/W2
+      UP(2) = (T2*CMPLX(C(2),0.0E0)+CMPLX(C(3),0.0E0))*TFN
+      BSUM = UP(2) + ZC
+      ASUM = CZERO
+      IF (RFNU.LT.TOL) GO TO 220
+      PRZTH = RZTH
+      PTFN = TFN
+      UP(1) = CONE
+      PP = 1.0E0
+      BSUMR = REAL(BSUM)
+      BSUMI = AIMAG(BSUM)
+      BTOL = TOL*(ABS(BSUMR)+ABS(BSUMI))
+      KS = 0
+      KP1 = 2
+      L = 3
+      IAS = 0
+      IBS = 0
+      DO 210 LR=2,12,2
+        LRP1 = LR + 1
+C-----------------------------------------------------------------------
+C     COMPUTE TWO ADDITIONAL CR, DR, AND UP FOR TWO MORE TERMS IN
+C     NEXT SUMA AND SUMB
+C-----------------------------------------------------------------------
+        DO 160 K=LR,LRP1
+          KS = KS + 1
+          KP1 = KP1 + 1
+          L = L + 1
+          ZA = CMPLX(C(L),0.0E0)
+          DO 150 J=2,KP1
+            L = L + 1
+            ZA = ZA*T2 + CMPLX(C(L),0.0E0)
+  150     CONTINUE
+          PTFN = PTFN*TFN
+          UP(KP1) = PTFN*ZA
+          CR(KS) = PRZTH*CMPLX(BR(KS+1),0.0E0)
+          PRZTH = PRZTH*RZTH
+          DR(KS) = PRZTH*CMPLX(AR(KS+2),0.0E0)
+  160   CONTINUE
+        PP = PP*RFNU2
+        IF (IAS.EQ.1) GO TO 180
+        SUMA = UP(LRP1)
+        JU = LRP1
+        DO 170 JR=1,LR
+          JU = JU - 1
+          SUMA = SUMA + CR(JR)*UP(JU)
+  170   CONTINUE
+        ASUM = ASUM + SUMA
+        ASUMR = REAL(ASUM)
+        ASUMI = AIMAG(ASUM)
+        TEST = ABS(ASUMR) + ABS(ASUMI)
+        IF (PP.LT.TOL .AND. TEST.LT.TOL) IAS = 1
+  180   CONTINUE
+        IF (IBS.EQ.1) GO TO 200
+        SUMB = UP(LR+2) + UP(LRP1)*ZC
+        JU = LRP1
+        DO 190 JR=1,LR
+          JU = JU - 1
+          SUMB = SUMB + DR(JR)*UP(JU)
+  190   CONTINUE
+        BSUM = BSUM + SUMB
+        BSUMR = REAL(BSUM)
+        BSUMI = AIMAG(BSUM)
+        TEST = ABS(BSUMR) + ABS(BSUMI)
+        IF (PP.LT.BTOL .AND. TEST.LT.TOL) IBS = 1
+  200   CONTINUE
+        IF (IAS.EQ.1 .AND. IBS.EQ.1) GO TO 220
+  210 CONTINUE
+  220 CONTINUE
+      ASUM = ASUM + CONE
+      BSUM = -BSUM*RFN13/RTZTA
+      GO TO 120
+      END
diff --git a/libcruft/amos/cuni1.f b/libcruft/amos/cuni1.f
new file mode 100644
index 0000000..5e01f7c
--- /dev/null
+++ b/libcruft/amos/cuni1.f
@@ -0,0 +1,168 @@
+      SUBROUTINE CUNI1(Z, FNU, KODE, N, Y, NZ, NLAST, FNUL, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  CUNI1
+C***REFER TO  CBESI,CBESK
+C
+C     CUNI1 COMPUTES I(FNU,Z)  BY MEANS OF THE UNIFORM ASYMPTOTIC
+C     EXPANSION FOR I(FNU,Z) IN -PI/3.LE.ARG Z.LE.PI/3.
+C
+C     FNUL IS THE SMALLEST ORDER PERMITTED FOR THE ASYMPTOTIC
+C     EXPANSION. NLAST=0 MEANS ALL OF THE Y VALUES WERE SET.
+C     NLAST.NE.0 IS THE NUMBER LEFT TO BE COMPUTED BY ANOTHER
+C     FORMULA FOR ORDERS FNU TO FNU+NLAST-1 BECAUSE FNU+NLAST-1.LT.FNUL.
+C     Y(I)=CZERO FOR I=NLAST+1,N
+C
+C***ROUTINES CALLED  CUCHK,CUNIK,CUOIK,R1MACH
+C***END PROLOGUE  CUNI1
+      COMPLEX CFN, CONE, CRSC, CSCL, CSR, CSS, CWRK, CZERO, C1, C2,
+     * PHI, RZ, SUM, S1, S2, Y, Z, ZETA1, ZETA2, CY
+      REAL ALIM, APHI, ASCLE, BRY, C2I, C2M, C2R, ELIM, FN, FNU, FNUL,
+     * RS1, TOL, YY, R1MACH
+      INTEGER I, IFLAG, INIT, K, KODE, M, N, ND, NLAST, NN, NUF, NW, NZ
+      DIMENSION BRY(3), Y(N), CWRK(16), CSS(3), CSR(3), CY(2)
+      DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
+C
+      NZ = 0
+      ND = N
+      NLAST = 0
+C-----------------------------------------------------------------------
+C     COMPUTED VALUES WITH EXPONENTS BETWEEN ALIM AND ELIM IN MAG-
+C     NITUDE ARE SCALED TO KEEP INTERMEDIATE ARITHMETIC ON SCALE,
+C     EXP(ALIM)=EXP(ELIM)*TOL
+C-----------------------------------------------------------------------
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      CRSC = CMPLX(TOL,0.0E0)
+      CSS(1) = CSCL
+      CSS(2) = CONE
+      CSS(3) = CRSC
+      CSR(1) = CRSC
+      CSR(2) = CONE
+      CSR(3) = CSCL
+      BRY(1) = 1.0E+3*R1MACH(1)/TOL
+C-----------------------------------------------------------------------
+C     CHECK FOR UNDERFLOW AND OVERFLOW ON FIRST MEMBER
+C-----------------------------------------------------------------------
+      FN = AMAX1(FNU,1.0E0)
+      INIT = 0
+      CALL CUNIK(Z, FN, 1, 1, TOL, INIT, PHI, ZETA1, ZETA2, SUM, CWRK)
+      IF (KODE.EQ.1) GO TO 10
+      CFN = CMPLX(FN,0.0E0)
+      S1 = -ZETA1 + CFN*(CFN/(Z+ZETA2))
+      GO TO 20
+   10 CONTINUE
+      S1 = -ZETA1 + ZETA2
+   20 CONTINUE
+      RS1 = REAL(S1)
+      IF (ABS(RS1).GT.ELIM) GO TO 130
+   30 CONTINUE
+      NN = MIN0(2,ND)
+      DO 80 I=1,NN
+        FN = FNU + FLOAT(ND-I)
+        INIT = 0
+        CALL CUNIK(Z, FN, 1, 0, TOL, INIT, PHI, ZETA1, ZETA2, SUM, CWRK)
+        IF (KODE.EQ.1) GO TO 40
+        CFN = CMPLX(FN,0.0E0)
+        YY = AIMAG(Z)
+        S1 = -ZETA1 + CFN*(CFN/(Z+ZETA2)) + CMPLX(0.0E0,YY)
+        GO TO 50
+   40   CONTINUE
+        S1 = -ZETA1 + ZETA2
+   50   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = REAL(S1)
+        IF (ABS(RS1).GT.ELIM) GO TO 110
+        IF (I.EQ.1) IFLAG = 2
+        IF (ABS(RS1).LT.ALIM) GO TO 60
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = CABS(PHI)
+        RS1 = RS1 + ALOG(APHI)
+        IF (ABS(RS1).GT.ELIM) GO TO 110
+        IF (I.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0E0) GO TO 60
+        IF (I.EQ.1) IFLAG = 3
+   60   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 IF CABS(S1).LT.ASCLE
+C-----------------------------------------------------------------------
+        S2 = PHI*SUM
+        C2R = REAL(S1)
+        C2I = AIMAG(S1)
+        C2M = EXP(C2R)*REAL(CSS(IFLAG))
+        S1 = CMPLX(C2M,0.0E0)*CMPLX(COS(C2I),SIN(C2I))
+        S2 = S2*S1
+        IF (IFLAG.NE.1) GO TO 70
+        CALL CUCHK(S2, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 110
+   70   CONTINUE
+        M = ND - I + 1
+        CY(I) = S2
+        Y(M) = S2*CSR(IFLAG)
+   80 CONTINUE
+      IF (ND.LE.2) GO TO 100
+      RZ = CMPLX(2.0E0,0.0E0)/Z
+      BRY(2) = 1.0E0/BRY(1)
+      BRY(3) = R1MACH(2)
+      S1 = CY(1)
+      S2 = CY(2)
+      C1 = CSR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      K = ND - 2
+      FN = FLOAT(K)
+      DO 90 I=3,ND
+        C2 = S2
+        S2 = S1 + CMPLX(FNU+FN,0.0E0)*RZ*S2
+        S1 = C2
+        C2 = S2*C1
+        Y(K) = C2
+        K = K - 1
+        FN = FN - 1.0E0
+        IF (IFLAG.GE.3) GO TO 90
+        C2R = REAL(C2)
+        C2I = AIMAG(C2)
+        C2R = ABS(C2R)
+        C2I = ABS(C2I)
+        C2M = AMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 90
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1 = S1*C1
+        S2 = C2
+        S1 = S1*CSS(IFLAG)
+        S2 = S2*CSS(IFLAG)
+        C1 = CSR(IFLAG)
+   90 CONTINUE
+  100 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     SET UNDERFLOW AND UPDATE PARAMETERS
+C-----------------------------------------------------------------------
+  110 CONTINUE
+      IF (RS1.GT.0.0E0) GO TO 120
+      Y(ND) = CZERO
+      NZ = NZ + 1
+      ND = ND - 1
+      IF (ND.EQ.0) GO TO 100
+      CALL CUOIK(Z, FNU, KODE, 1, ND, Y, NUF, TOL, ELIM, ALIM)
+      IF (NUF.LT.0) GO TO 120
+      ND = ND - NUF
+      NZ = NZ + NUF
+      IF (ND.EQ.0) GO TO 100
+      FN = FNU + FLOAT(ND-1)
+      IF (FN.GE.FNUL) GO TO 30
+      NLAST = ND
+      RETURN
+  120 CONTINUE
+      NZ = -1
+      RETURN
+  130 CONTINUE
+      IF (RS1.GT.0.0E0) GO TO 120
+      NZ = N
+      DO 140 I=1,N
+        Y(I) = CZERO
+  140 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/cuni2.f b/libcruft/amos/cuni2.f
new file mode 100644
index 0000000..67c702c
--- /dev/null
+++ b/libcruft/amos/cuni2.f
@@ -0,0 +1,215 @@
+      SUBROUTINE CUNI2(Z, FNU, KODE, N, Y, NZ, NLAST, FNUL, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  CUNI2
+C***REFER TO  CBESI,CBESK
+C
+C     CUNI2 COMPUTES I(FNU,Z) IN THE RIGHT HALF PLANE BY MEANS OF
+C     UNIFORM ASYMPTOTIC EXPANSION FOR J(FNU,ZN) WHERE ZN IS Z*I
+C     OR -Z*I AND ZN IS IN THE RIGHT HALF PLANE ALSO.
+C
+C     FNUL IS THE SMALLEST ORDER PERMITTED FOR THE ASYMPTOTIC
+C     EXPANSION. NLAST=0 MEANS ALL OF THE Y VALUES WERE SET.
+C     NLAST.NE.0 IS THE NUMBER LEFT TO BE COMPUTED BY ANOTHER
+C     FORMULA FOR ORDERS FNU TO FNU+NLAST-1 BECAUSE FNU+NLAST-1.LT.FNUL.
+C     Y(I)=CZERO FOR I=NLAST+1,N
+C
+C***ROUTINES CALLED  CAIRY,CUCHK,CUNHJ,CUOIK,R1MACH
+C***END PROLOGUE  CUNI2
+      COMPLEX AI, ARG, ASUM, BSUM, CFN, CI, CID, CIP, CONE, CRSC, CSCL,
+     * CSR, CSS, CY, CZERO, C1, C2, DAI, PHI, RZ, S1, S2, Y, Z, ZB,
+     * ZETA1, ZETA2, ZN, ZAR
+      REAL AARG, AIC, ALIM, ANG, APHI, ASCLE, AY, BRY, CAR, C2I, C2M,
+     * C2R, ELIM, FN, FNU, FNUL, HPI, RS1, SAR, TOL, YY, R1MACH
+      INTEGER I, IFLAG, IN, INU, J, K, KODE, N, NAI, ND, NDAI, NLAST,
+     * NN, NUF, NW, NZ, IDUM
+      DIMENSION BRY(3), Y(N), CIP(4), CSS(3), CSR(3), CY(2)
+      DATA CZERO,CONE,CI/(0.0E0,0.0E0),(1.0E0,0.0E0),(0.0E0,1.0E0)/
+      DATA CIP(1),CIP(2),CIP(3),CIP(4)/
+     1 (1.0E0,0.0E0), (0.0E0,1.0E0), (-1.0E0,0.0E0), (0.0E0,-1.0E0)/
+      DATA HPI, AIC  /
+     1      1.57079632679489662E+00,     1.265512123484645396E+00/
+C
+      NZ = 0
+      ND = N
+      NLAST = 0
+C-----------------------------------------------------------------------
+C     COMPUTED VALUES WITH EXPONENTS BETWEEN ALIM AND ELIM IN MAG-
+C     NITUDE ARE SCALED TO KEEP INTERMEDIATE ARITHMETIC ON SCALE,
+C     EXP(ALIM)=EXP(ELIM)*TOL
+C-----------------------------------------------------------------------
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      CRSC = CMPLX(TOL,0.0E0)
+      CSS(1) = CSCL
+      CSS(2) = CONE
+      CSS(3) = CRSC
+      CSR(1) = CRSC
+      CSR(2) = CONE
+      CSR(3) = CSCL
+      BRY(1) = 1.0E+3*R1MACH(1)/TOL
+      YY = AIMAG(Z)
+C-----------------------------------------------------------------------
+C     ZN IS IN THE RIGHT HALF PLANE AFTER ROTATION BY CI OR -CI
+C-----------------------------------------------------------------------
+      ZN = -Z*CI
+      ZB = Z
+      CID = -CI
+      INU = INT(FNU)
+      ANG = HPI*(FNU-FLOAT(INU))
+      CAR = COS(ANG)
+      SAR = SIN(ANG)
+      C2 = CMPLX(CAR,SAR)
+      ZAR = C2
+      IN = INU + N - 1
+      IN = MOD(IN,4)
+      C2 = C2*CIP(IN+1)
+      IF (YY.GT.0.0E0) GO TO 10
+      ZN = CONJG(-ZN)
+      ZB = CONJG(ZB)
+      CID = -CID
+      C2 = CONJG(C2)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     CHECK FOR UNDERFLOW AND OVERFLOW ON FIRST MEMBER
+C-----------------------------------------------------------------------
+      FN = AMAX1(FNU,1.0E0)
+      CALL CUNHJ(ZN, FN, 1, TOL, PHI, ARG, ZETA1, ZETA2, ASUM, BSUM)
+      IF (KODE.EQ.1) GO TO 20
+      CFN = CMPLX(FNU,0.0E0)
+      S1 = -ZETA1 + CFN*(CFN/(ZB+ZETA2))
+      GO TO 30
+   20 CONTINUE
+      S1 = -ZETA1 + ZETA2
+   30 CONTINUE
+      RS1 = REAL(S1)
+      IF (ABS(RS1).GT.ELIM) GO TO 150
+   40 CONTINUE
+      NN = MIN0(2,ND)
+      DO 90 I=1,NN
+        FN = FNU + FLOAT(ND-I)
+        CALL CUNHJ(ZN, FN, 0, TOL, PHI, ARG, ZETA1, ZETA2, ASUM, BSUM)
+        IF (KODE.EQ.1) GO TO 50
+        CFN = CMPLX(FN,0.0E0)
+        AY = ABS(YY)
+        S1 = -ZETA1 + CFN*(CFN/(ZB+ZETA2)) + CMPLX(0.0E0,AY)
+        GO TO 60
+   50   CONTINUE
+        S1 = -ZETA1 + ZETA2
+   60   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = REAL(S1)
+        IF (ABS(RS1).GT.ELIM) GO TO 120
+        IF (I.EQ.1) IFLAG = 2
+        IF (ABS(RS1).LT.ALIM) GO TO 70
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+        APHI = CABS(PHI)
+        AARG = CABS(ARG)
+        RS1 = RS1 + ALOG(APHI) - 0.25E0*ALOG(AARG) - AIC
+        IF (ABS(RS1).GT.ELIM) GO TO 120
+        IF (I.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0E0) GO TO 70
+        IF (I.EQ.1) IFLAG = 3
+   70   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR
+C     EXPONENT EXTREMES
+C-----------------------------------------------------------------------
+        CALL CAIRY(ARG, 0, 2, AI, NAI, IDUM)
+        CALL CAIRY(ARG, 1, 2, DAI, NDAI, IDUM)
+        S2 = PHI*(AI*ASUM+DAI*BSUM)
+        C2R = REAL(S1)
+        C2I = AIMAG(S1)
+        C2M = EXP(C2R)*REAL(CSS(IFLAG))
+        S1 = CMPLX(C2M,0.0E0)*CMPLX(COS(C2I),SIN(C2I))
+        S2 = S2*S1
+        IF (IFLAG.NE.1) GO TO 80
+        CALL CUCHK(S2, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 120
+   80   CONTINUE
+        IF (YY.LE.0.0E0) S2 = CONJG(S2)
+        J = ND - I + 1
+        S2 = S2*C2
+        CY(I) = S2
+        Y(J) = S2*CSR(IFLAG)
+        C2 = C2*CID
+   90 CONTINUE
+      IF (ND.LE.2) GO TO 110
+      RZ = CMPLX(2.0E0,0.0E0)/Z
+      BRY(2) = 1.0E0/BRY(1)
+      BRY(3) = R1MACH(2)
+      S1 = CY(1)
+      S2 = CY(2)
+      C1 = CSR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      K = ND - 2
+      FN = FLOAT(K)
+      DO 100 I=3,ND
+        C2 = S2
+        S2 = S1 + CMPLX(FNU+FN,0.0E0)*RZ*S2
+        S1 = C2
+        C2 = S2*C1
+        Y(K) = C2
+        K = K - 1
+        FN = FN - 1.0E0
+        IF (IFLAG.GE.3) GO TO 100
+        C2R = REAL(C2)
+        C2I = AIMAG(C2)
+        C2R = ABS(C2R)
+        C2I = ABS(C2I)
+        C2M = AMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 100
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1 = S1*C1
+        S2 = C2
+        S1 = S1*CSS(IFLAG)
+        S2 = S2*CSS(IFLAG)
+        C1 = CSR(IFLAG)
+  100 CONTINUE
+  110 CONTINUE
+      RETURN
+  120 CONTINUE
+      IF (RS1.GT.0.0E0) GO TO 140
+C-----------------------------------------------------------------------
+C     SET UNDERFLOW AND UPDATE PARAMETERS
+C-----------------------------------------------------------------------
+      Y(ND) = CZERO
+      NZ = NZ + 1
+      ND = ND - 1
+      IF (ND.EQ.0) GO TO 110
+      CALL CUOIK(Z, FNU, KODE, 1, ND, Y, NUF, TOL, ELIM, ALIM)
+      IF (NUF.LT.0) GO TO 140
+      ND = ND - NUF
+      NZ = NZ + NUF
+      IF (ND.EQ.0) GO TO 110
+      FN = FNU + FLOAT(ND-1)
+      IF (FN.LT.FNUL) GO TO 130
+C      FN = AIMAG(CID)
+C      J = NUF + 1
+C      K = MOD(J,4) + 1
+C      S1 = CIP(K)
+C      IF (FN.LT.0.0E0) S1 = CONJG(S1)
+C      C2 = C2*S1
+      IN = INU + ND - 1
+      IN = MOD(IN,4) + 1
+      C2 = ZAR*CIP(IN)
+      IF (YY.LE.0.0E0)C2=CONJG(C2)
+      GO TO 40
+  130 CONTINUE
+      NLAST = ND
+      RETURN
+  140 CONTINUE
+      NZ = -1
+      RETURN
+  150 CONTINUE
+      IF (RS1.GT.0.0E0) GO TO 140
+      NZ = N
+      DO 160 I=1,N
+        Y(I) = CZERO
+  160 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/cunik.f b/libcruft/amos/cunik.f
new file mode 100644
index 0000000..53d2c9d
--- /dev/null
+++ b/libcruft/amos/cunik.f
@@ -0,0 +1,188 @@
+      SUBROUTINE CUNIK(ZR, FNU, IKFLG, IPMTR, TOL, INIT, PHI, ZETA1,
+     * ZETA2, SUM, CWRK)
+C***BEGIN PROLOGUE  CUNIK
+C***REFER TO  CBESI,CBESK
+C
+C        CUNIK COMPUTES PARAMETERS FOR THE UNIFORM ASYMPTOTIC
+C        EXPANSIONS OF THE I AND K FUNCTIONS ON IKFLG= 1 OR 2
+C        RESPECTIVELY BY
+C
+C        W(FNU,ZR) = PHI*EXP(ZETA)*SUM
+C
+C        WHERE       ZETA=-ZETA1 + ZETA2       OR
+C                          ZETA1 - ZETA2
+C
+C        THE FIRST CALL MUST HAVE INIT=0. SUBSEQUENT CALLS WITH THE
+C        SAME ZR AND FNU WILL RETURN THE I OR K FUNCTION ON IKFLG=
+C        1 OR 2 WITH NO CHANGE IN INIT. CWRK IS A COMPLEX WORK
+C        ARRAY. IPMTR=0 COMPUTES ALL PARAMETERS. IPMTR=1 COMPUTES PHI,
+C        ZETA1,ZETA2.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  CUNIK
+      COMPLEX CFN, CON, CONE, CRFN, CWRK, CZERO, PHI, S, SR, SUM, T,
+     * T2, ZETA1, ZETA2, ZN, ZR
+      REAL AC, C, FNU, RFN, TEST, TOL, TSTR, TSTI
+      INTEGER I, IKFLG, INIT, IPMTR, J, K, L
+      DIMENSION C(120), CWRK(16), CON(2)
+      DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
+      DATA CON(1), CON(2)  /
+     1(3.98942280401432678E-01,0.0E0),(1.25331413731550025E+00,0.0E0)/
+      DATA C(1), C(2), C(3), C(4), C(5), C(6), C(7), C(8), C(9), C(10),
+     1     C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18),
+     2     C(19), C(20), C(21), C(22), C(23), C(24)/
+     3     1.00000000000000000E+00,    -2.08333333333333333E-01,
+     4     1.25000000000000000E-01,     3.34201388888888889E-01,
+     5    -4.01041666666666667E-01,     7.03125000000000000E-02,
+     6    -1.02581259645061728E+00,     1.84646267361111111E+00,
+     7    -8.91210937500000000E-01,     7.32421875000000000E-02,
+     8     4.66958442342624743E+00,    -1.12070026162229938E+01,
+     9     8.78912353515625000E+00,    -2.36408691406250000E+00,
+     A     1.12152099609375000E-01,    -2.82120725582002449E+01,
+     B     8.46362176746007346E+01,    -9.18182415432400174E+01,
+     C     4.25349987453884549E+01,    -7.36879435947963170E+00,
+     D     2.27108001708984375E-01,     2.12570130039217123E+02,
+     E    -7.65252468141181642E+02,     1.05999045252799988E+03/
+      DATA C(25), C(26), C(27), C(28), C(29), C(30), C(31), C(32),
+     1     C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(40),
+     2     C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48)/
+     3    -6.99579627376132541E+02,     2.18190511744211590E+02,
+     4    -2.64914304869515555E+01,     5.72501420974731445E-01,
+     5    -1.91945766231840700E+03,     8.06172218173730938E+03,
+     6    -1.35865500064341374E+04,     1.16553933368645332E+04,
+     7    -5.30564697861340311E+03,     1.20090291321635246E+03,
+     8    -1.08090919788394656E+02,     1.72772750258445740E+00,
+     9     2.02042913309661486E+04,    -9.69805983886375135E+04,
+     A     1.92547001232531532E+05,    -2.03400177280415534E+05,
+     B     1.22200464983017460E+05,    -4.11926549688975513E+04,
+     C     7.10951430248936372E+03,    -4.93915304773088012E+02,
+     D     6.07404200127348304E+00,    -2.42919187900551333E+05,
+     E     1.31176361466297720E+06,    -2.99801591853810675E+06/
+      DATA C(49), C(50), C(51), C(52), C(53), C(54), C(55), C(56),
+     1     C(57), C(58), C(59), C(60), C(61), C(62), C(63), C(64),
+     2     C(65), C(66), C(67), C(68), C(69), C(70), C(71), C(72)/
+     3     3.76327129765640400E+06,    -2.81356322658653411E+06,
+     4     1.26836527332162478E+06,    -3.31645172484563578E+05,
+     5     4.52187689813627263E+04,    -2.49983048181120962E+03,
+     6     2.43805296995560639E+01,     3.28446985307203782E+06,
+     7    -1.97068191184322269E+07,     5.09526024926646422E+07,
+     8    -7.41051482115326577E+07,     6.63445122747290267E+07,
+     9    -3.75671766607633513E+07,     1.32887671664218183E+07,
+     A    -2.78561812808645469E+06,     3.08186404612662398E+05,
+     B    -1.38860897537170405E+04,     1.10017140269246738E+02,
+     C    -4.93292536645099620E+07,     3.25573074185765749E+08,
+     D    -9.39462359681578403E+08,     1.55359689957058006E+09,
+     E    -1.62108055210833708E+09,     1.10684281682301447E+09/
+      DATA C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(80),
+     1     C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88),
+     2     C(89), C(90), C(91), C(92), C(93), C(94), C(95), C(96)/
+     3    -4.95889784275030309E+08,     1.42062907797533095E+08,
+     4    -2.44740627257387285E+07,     2.24376817792244943E+06,
+     5    -8.40054336030240853E+04,     5.51335896122020586E+02,
+     6     8.14789096118312115E+08,    -5.86648149205184723E+09,
+     7     1.86882075092958249E+10,    -3.46320433881587779E+10,
+     8     4.12801855797539740E+10,    -3.30265997498007231E+10,
+     9     1.79542137311556001E+10,    -6.56329379261928433E+09,
+     A     1.55927986487925751E+09,    -2.25105661889415278E+08,
+     B     1.73951075539781645E+07,    -5.49842327572288687E+05,
+     C     3.03809051092238427E+03,    -1.46792612476956167E+10,
+     D     1.14498237732025810E+11,    -3.99096175224466498E+11,
+     E     8.19218669548577329E+11,    -1.09837515608122331E+12/
+      DATA C(97), C(98), C(99), C(100), C(101), C(102), C(103), C(104),
+     1     C(105), C(106), C(107), C(108), C(109), C(110), C(111),
+     2     C(112), C(113), C(114), C(115), C(116), C(117), C(118)/
+     3     1.00815810686538209E+12,    -6.45364869245376503E+11,
+     4     2.87900649906150589E+11,    -8.78670721780232657E+10,
+     5     1.76347306068349694E+10,    -2.16716498322379509E+09,
+     6     1.43157876718888981E+08,    -3.87183344257261262E+06,
+     7     1.82577554742931747E+04,     2.86464035717679043E+11,
+     8    -2.40629790002850396E+12,     9.10934118523989896E+12,
+     9    -2.05168994109344374E+13,     3.05651255199353206E+13,
+     A    -3.16670885847851584E+13,     2.33483640445818409E+13,
+     B    -1.23204913055982872E+13,     4.61272578084913197E+12,
+     C    -1.19655288019618160E+12,     2.05914503232410016E+11,
+     D    -2.18229277575292237E+10,     1.24700929351271032E+09/
+      DATA C(119), C(120)/
+     1    -2.91883881222208134E+07,     1.18838426256783253E+05/
+C
+      IF (INIT.NE.0) GO TO 40
+C-----------------------------------------------------------------------
+C     INITIALIZE ALL VARIABLES
+C-----------------------------------------------------------------------
+      RFN = 1.0E0/FNU
+      CRFN = CMPLX(RFN,0.0E0)
+C     T = ZR*CRFN
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST (ZR/FNU TOO SMALL)
+C-----------------------------------------------------------------------
+      TSTR = REAL(ZR)
+      TSTI = AIMAG(ZR)
+      TEST = R1MACH(1)*1.0E+3
+      AC = FNU*TEST
+      IF (ABS(TSTR).GT.AC .OR. ABS(TSTI).GT.AC) GO TO 15
+      AC = 2.0E0*ABS(ALOG(TEST))+FNU
+      ZETA1 = CMPLX(AC,0.0E0)
+      ZETA2 = CMPLX(FNU,0.0E0)
+      PHI=CONE
+      RETURN
+   15 CONTINUE
+      T=ZR*CRFN
+      S = CONE + T*T
+      SR = CSQRT(S)
+      CFN = CMPLX(FNU,0.0E0)
+      ZN = (CONE+SR)/T
+      ZETA1 = CFN*CLOG(ZN)
+      ZETA2 = CFN*SR
+      T = CONE/SR
+      SR = T*CRFN
+      CWRK(16) = CSQRT(SR)
+      PHI = CWRK(16)*CON(IKFLG)
+      IF (IPMTR.NE.0) RETURN
+      T2 = CONE/S
+      CWRK(1) = CONE
+      CRFN = CONE
+      AC = 1.0E0
+      L = 1
+      DO 20 K=2,15
+        S = CZERO
+        DO 10 J=1,K
+          L = L + 1
+          S = S*T2 + CMPLX(C(L),0.0E0)
+   10   CONTINUE
+        CRFN = CRFN*SR
+        CWRK(K) = CRFN*S
+        AC = AC*RFN
+        TSTR = REAL(CWRK(K))
+        TSTI = AIMAG(CWRK(K))
+        TEST = ABS(TSTR) + ABS(TSTI)
+        IF (AC.LT.TOL .AND. TEST.LT.TOL) GO TO 30
+   20 CONTINUE
+      K = 15
+   30 CONTINUE
+      INIT = K
+   40 CONTINUE
+      IF (IKFLG.EQ.2) GO TO 60
+C-----------------------------------------------------------------------
+C     COMPUTE SUM FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      S = CZERO
+      DO 50 I=1,INIT
+        S = S + CWRK(I)
+   50 CONTINUE
+      SUM = S
+      PHI = CWRK(16)*CON(1)
+      RETURN
+   60 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE SUM FOR THE K FUNCTION
+C-----------------------------------------------------------------------
+      S = CZERO
+      T = CONE
+      DO 70 I=1,INIT
+        S = S + T*CWRK(I)
+        T = -T
+   70 CONTINUE
+      SUM = S
+      PHI = CWRK(16)*CON(2)
+      RETURN
+      END
diff --git a/libcruft/amos/cunk1.f b/libcruft/amos/cunk1.f
new file mode 100644
index 0000000..62e4bf5
--- /dev/null
+++ b/libcruft/amos/cunk1.f
@@ -0,0 +1,343 @@
+      SUBROUTINE CUNK1(Z, FNU, KODE, MR, N, Y, NZ, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CUNK1
+C***REFER TO  CBESK
+C
+C     CUNK1 COMPUTES K(FNU,Z) AND ITS ANALYTIC CONTINUATION FROM THE
+C     RIGHT HALF PLANE TO THE LEFT HALF PLANE BY MEANS OF THE
+C     UNIFORM ASYMPTOTIC EXPANSION.
+C     MR INDICATES THE DIRECTION OF ROTATION FOR ANALYTIC CONTINUATION.
+C     NZ=-1 MEANS AN OVERFLOW WILL OCCUR
+C
+C***ROUTINES CALLED  CS1S2,CUCHK,CUNIK,R1MACH
+C***END PROLOGUE  CUNK1
+      COMPLEX CFN, CK, CONE, CRSC, CS, CSCL, CSGN, CSPN, CSR, CSS,
+     * CWRK, CY, CZERO, C1, C2, PHI,  RZ, SUM,  S1, S2, Y, Z,
+     * ZETA1,  ZETA2,  ZR, PHID, ZETA1D, ZETA2D, SUMD
+      REAL ALIM, ANG, APHI, ASC, ASCLE, BRY, CPN, C2I, C2M, C2R, ELIM,
+     * FMR, FN, FNF, FNU, PI, RS1, SGN, SPN, TOL, X, R1MACH
+      INTEGER I, IB, IFLAG, IFN, IL, INIT, INU, IUF, K, KDFLG, KFLAG,
+     * KK, KODE, MR, N, NW, NZ, J, IPARD, INITD, IC
+      DIMENSION BRY(3), INIT(2), Y(N), SUM(2), PHI(2), ZETA1(2),
+     * ZETA2(2), CY(2), CWRK(16,3), CSS(3), CSR(3)
+      DATA CZERO, CONE / (0.0E0,0.0E0) , (1.0E0,0.0E0) /
+      DATA PI / 3.14159265358979324E0 /
+C
+      KDFLG = 1
+      NZ = 0
+C-----------------------------------------------------------------------
+C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION GREATER THAN
+C     THE UNDERFLOW LIMIT
+C-----------------------------------------------------------------------
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      CRSC = CMPLX(TOL,0.0E0)
+      CSS(1) = CSCL
+      CSS(2) = CONE
+      CSS(3) = CRSC
+      CSR(1) = CRSC
+      CSR(2) = CONE
+      CSR(3) = CSCL
+      BRY(1) = 1.0E+3*R1MACH(1)/TOL
+      BRY(2) = 1.0E0/BRY(1)
+      BRY(3) = R1MACH(2)
+      X = REAL(Z)
+      ZR = Z
+      IF (X.LT.0.0E0) ZR = -Z
+      J=2
+      DO 70 I=1,N
+C-----------------------------------------------------------------------
+C     J FLIP FLOPS BETWEEN 1 AND 2 IN J = 3 - J
+C-----------------------------------------------------------------------
+        J = 3 - J
+        FN = FNU + FLOAT(I-1)
+        INIT(J) = 0
+        CALL CUNIK(ZR, FN, 2, 0, TOL, INIT(J), PHI(J), ZETA1(J),
+     *   ZETA2(J), SUM(J), CWRK(1,J))
+        IF (KODE.EQ.1) GO TO 20
+        CFN = CMPLX(FN,0.0E0)
+        S1 = ZETA1(J) - CFN*(CFN/(ZR+ZETA2(J)))
+        GO TO 30
+   20   CONTINUE
+        S1 = ZETA1(J) - ZETA2(J)
+   30   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = REAL(S1)
+        IF (ABS(RS1).GT.ELIM) GO TO 60
+        IF (KDFLG.EQ.1) KFLAG = 2
+        IF (ABS(RS1).LT.ALIM) GO TO 40
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = CABS(PHI(J))
+        RS1 = RS1 + ALOG(APHI)
+        IF (ABS(RS1).GT.ELIM) GO TO 60
+        IF (KDFLG.EQ.1) KFLAG = 1
+        IF (RS1.LT.0.0E0) GO TO 40
+        IF (KDFLG.EQ.1) KFLAG = 3
+   40   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR
+C     EXPONENT EXTREMES
+C-----------------------------------------------------------------------
+        S2 = PHI(J)*SUM(J)
+        C2R = REAL(S1)
+        C2I = AIMAG(S1)
+        C2M = EXP(C2R)*REAL(CSS(KFLAG))
+        S1 = CMPLX(C2M,0.0E0)*CMPLX(COS(C2I),SIN(C2I))
+        S2 = S2*S1
+        IF (KFLAG.NE.1) GO TO 50
+        CALL CUCHK(S2, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 60
+   50   CONTINUE
+        CY(KDFLG) = S2
+        Y(I) = S2*CSR(KFLAG)
+        IF (KDFLG.EQ.2) GO TO 75
+        KDFLG = 2
+        GO TO 70
+   60   CONTINUE
+        IF (RS1.GT.0.0E0) GO TO 290
+C-----------------------------------------------------------------------
+C     FOR X.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+        IF (X.LT.0.0E0) GO TO 290
+        KDFLG = 1
+        Y(I) = CZERO
+        NZ=NZ+1
+        IF (I.EQ.1) GO TO 70
+        IF (Y(I-1).EQ.CZERO) GO TO 70
+        Y(I-1) = CZERO
+        NZ=NZ+1
+   70 CONTINUE
+      I=N
+   75 CONTINUE
+      RZ = CMPLX(2.0E0,0.0E0)/ZR
+      CK = CMPLX(FN,0.0E0)*RZ
+      IB = I+1
+      IF (N.LT.IB) GO TO 160
+C-----------------------------------------------------------------------
+C     TEST LAST MEMBER FOR UNDERFLOW AND OVERFLOW, SET SEQUENCE TO ZERO
+C     ON UNDERFLOW
+C-----------------------------------------------------------------------
+      FN = FNU+FLOAT(N-1)
+      IPARD = 1
+      IF (MR.NE.0) IPARD = 0
+      INITD = 0
+      CALL CUNIK(ZR,FN,2,IPARD,TOL,INITD,PHID,ZETA1D,ZETA2D,SUMD,
+     *CWRK(1,3))
+      IF (KODE.EQ.1) GO TO 80
+      CFN=CMPLX(FN,0.0E0)
+      S1=ZETA1D-CFN*(CFN/(ZR+ZETA2D))
+      GO TO 90
+   80 CONTINUE
+      S1=ZETA1D-ZETA2D
+   90 CONTINUE
+      RS1=REAL(S1)
+      IF (ABS(RS1).GT.ELIM) GO TO 95
+      IF (ABS(RS1).LT.ALIM) GO TO 100
+C-----------------------------------------------------------------------
+C     REFINE ESTIMATE AND TEST
+C-----------------------------------------------------------------------
+      APHI=CABS(PHID)
+      RS1=RS1+ALOG(APHI)
+      IF (ABS(RS1).LT.ELIM) GO TO 100
+   95 CONTINUE
+      IF (RS1.GT.0.0E0) GO TO 290
+C-----------------------------------------------------------------------
+C     FOR X.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+      IF (X.LT.0.0E0) GO TO 290
+      NZ=N
+      DO 96 I=1,N
+        Y(I) = CZERO
+   96 CONTINUE
+      RETURN
+  100 CONTINUE
+C-----------------------------------------------------------------------
+C     RECUR FORWARD FOR REMAINDER OF THE SEQUENCE
+C-----------------------------------------------------------------------
+      S1 = CY(1)
+      S2 = CY(2)
+      C1 = CSR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 120 I=IB,N
+        C2 = S2
+        S2 = CK*S2 + S1
+        S1 = C2
+        CK = CK + RZ
+        C2 = S2*C1
+        Y(I) = C2
+        IF (KFLAG.GE.3) GO TO 120
+        C2R = REAL(C2)
+        C2I = AIMAG(C2)
+        C2R = ABS(C2R)
+        C2I = ABS(C2I)
+        C2M = AMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 120
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1 = S1*C1
+        S2 = C2
+        S1 = S1*CSS(KFLAG)
+        S2 = S2*CSS(KFLAG)
+        C1 = CSR(KFLAG)
+  120 CONTINUE
+  160 CONTINUE
+      IF (MR.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION FOR RE(Z).LT.0.0E0
+C-----------------------------------------------------------------------
+      NZ = 0
+      FMR = FLOAT(MR)
+      SGN = -SIGN(PI,FMR)
+C-----------------------------------------------------------------------
+C     CSPN AND CSGN ARE COEFF OF K AND I FUNCIONS RESP.
+C-----------------------------------------------------------------------
+      CSGN = CMPLX(0.0E0,SGN)
+      INU = INT(FNU)
+      FNF = FNU - FLOAT(INU)
+      IFN = INU + N - 1
+      ANG = FNF*SGN
+      CPN = COS(ANG)
+      SPN = SIN(ANG)
+      CSPN = CMPLX(CPN,SPN)
+      IF (MOD(IFN,2).EQ.1) CSPN = -CSPN
+      ASC = BRY(1)
+      KK = N
+      IUF = 0
+      KDFLG = 1
+      IB = IB-1
+      IC = IB-1
+      DO 260 K=1,N
+        FN = FNU + FLOAT(KK-1)
+C-----------------------------------------------------------------------
+C     LOGIC TO SORT OUT CASES WHOSE PARAMETERS WERE SET FOR THE K
+C     FUNCTION ABOVE
+C-----------------------------------------------------------------------
+        M=3
+        IF (N.GT.2) GO TO 175
+  170   CONTINUE
+        INITD = INIT(J)
+        PHID = PHI(J)
+        ZETA1D = ZETA1(J)
+        ZETA2D = ZETA2(J)
+        SUMD = SUM(J)
+        M = J
+        J = 3 - J
+        GO TO 180
+  175   CONTINUE
+        IF ((KK.EQ.N).AND.(IB.LT.N)) GO TO 180
+        IF ((KK.EQ.IB).OR.(KK.EQ.IC)) GO TO 170
+        INITD = 0
+  180   CONTINUE
+        CALL CUNIK(ZR, FN, 1, 0, TOL, INITD, PHID, ZETA1D,
+     *   ZETA2D, SUMD, CWRK(1,M))
+        IF (KODE.EQ.1) GO TO 190
+        CFN = CMPLX(FN,0.0E0)
+        S1 = -ZETA1D + CFN*(CFN/(ZR+ZETA2D))
+        GO TO 200
+  190   CONTINUE
+        S1 = -ZETA1D + ZETA2D
+  200   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = REAL(S1)
+        IF (ABS(RS1).GT.ELIM) GO TO 250
+        IF (KDFLG.EQ.1) IFLAG = 2
+        IF (ABS(RS1).LT.ALIM) GO TO 210
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = CABS(PHID)
+        RS1 = RS1 + ALOG(APHI)
+        IF (ABS(RS1).GT.ELIM) GO TO 250
+        IF (KDFLG.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0E0) GO TO 210
+        IF (KDFLG.EQ.1) IFLAG = 3
+  210   CONTINUE
+        S2 = CSGN*PHID*SUMD
+        C2R = REAL(S1)
+        C2I = AIMAG(S1)
+        C2M = EXP(C2R)*REAL(CSS(IFLAG))
+        S1 = CMPLX(C2M,0.0E0)*CMPLX(COS(C2I),SIN(C2I))
+        S2 = S2*S1
+        IF (IFLAG.NE.1) GO TO 220
+        CALL CUCHK(S2, NW, BRY(1), TOL)
+        IF (NW.NE.0) S2 = CMPLX(0.0E0,0.0E0)
+  220   CONTINUE
+        CY(KDFLG) = S2
+        C2 = S2
+        S2 = S2*CSR(IFLAG)
+C-----------------------------------------------------------------------
+C     ADD I AND K FUNCTIONS, K SEQUENCE IN Y(I), I=1,N
+C-----------------------------------------------------------------------
+        S1 = Y(KK)
+        IF (KODE.EQ.1) GO TO 240
+        CALL CS1S2(ZR, S1, S2, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  240   CONTINUE
+        Y(KK) = S1*CSPN + S2
+        KK = KK - 1
+        CSPN = -CSPN
+        IF (C2.NE.CZERO) GO TO 245
+        KDFLG = 1
+        GO TO 260
+  245   CONTINUE
+        IF (KDFLG.EQ.2) GO TO 265
+        KDFLG = 2
+        GO TO 260
+  250   CONTINUE
+        IF (RS1.GT.0.0E0) GO TO 290
+        S2 = CZERO
+        GO TO 220
+  260 CONTINUE
+      K = N
+  265 CONTINUE
+      IL = N - K
+      IF (IL.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     RECUR BACKWARD FOR REMAINDER OF I SEQUENCE AND ADD IN THE
+C     K FUNCTIONS, SCALING THE I SEQUENCE DURING RECURRENCE TO KEEP
+C     INTERMEDIATE ARITHMETIC ON SCALE NEAR EXPONENT EXTREMES.
+C-----------------------------------------------------------------------
+      S1 = CY(1)
+      S2 = CY(2)
+      CS = CSR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      FN = FLOAT(INU+IL)
+      DO 280 I=1,IL
+        C2 = S2
+        S2 = S1 + CMPLX(FN+FNF,0.0E0)*RZ*S2
+        S1 = C2
+        FN = FN - 1.0E0
+        C2 = S2*CS
+        CK = C2
+        C1 = Y(KK)
+        IF (KODE.EQ.1) GO TO 270
+        CALL CS1S2(ZR, C1, C2, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  270   CONTINUE
+        Y(KK) = C1*CSPN + C2
+        KK = KK - 1
+        CSPN = -CSPN
+        IF (IFLAG.GE.3) GO TO 280
+        C2R = REAL(CK)
+        C2I = AIMAG(CK)
+        C2R = ABS(C2R)
+        C2I = ABS(C2I)
+        C2M = AMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 280
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1 = S1*CS
+        S2 = CK
+        S1 = S1*CSS(IFLAG)
+        S2 = S2*CSS(IFLAG)
+        CS = CSR(IFLAG)
+  280 CONTINUE
+      RETURN
+  290 CONTINUE
+      NZ = -1
+      RETURN
+      END
diff --git a/libcruft/amos/cunk2.f b/libcruft/amos/cunk2.f
new file mode 100644
index 0000000..fd01aad
--- /dev/null
+++ b/libcruft/amos/cunk2.f
@@ -0,0 +1,393 @@
+      SUBROUTINE CUNK2(Z, FNU, KODE, MR, N, Y, NZ, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CUNK2
+C***REFER TO  CBESK
+C
+C     CUNK2 COMPUTES K(FNU,Z) AND ITS ANALYTIC CONTINUATION FROM THE
+C     RIGHT HALF PLANE TO THE LEFT HALF PLANE BY MEANS OF THE
+C     UNIFORM ASYMPTOTIC EXPANSIONS FOR H(KIND,FNU,ZN) AND J(FNU,ZN)
+C     WHERE ZN IS IN THE RIGHT HALF PLANE, KIND=(3-MR)/2, MR=+1 OR
+C     -1. HERE ZN=ZR*I OR -ZR*I WHERE ZR=Z IF Z IS IN THE RIGHT
+C     HALF PLANE OR ZR=-Z IF Z IS IN THE LEFT HALF PLANE. MR INDIC-
+C     ATES THE DIRECTION OF ROTATION FOR ANALYTIC CONTINUATION.
+C     NZ=-1 MEANS AN OVERFLOW WILL OCCUR
+C
+C***ROUTINES CALLED  CAIRY,CS1S2,CUCHK,CUNHJ,R1MACH
+C***END PROLOGUE  CUNK2
+      COMPLEX AI, ARG, ASUM, BSUM, CFN, CI, CIP,
+     * CK, CONE, CRSC, CR1, CR2, CS, CSCL, CSGN, CSPN, CSR, CSS, CY,
+     * CZERO, C1, C2, DAI, PHI,  RZ, S1, S2, Y, Z, ZB, ZETA1,
+     * ZETA2, ZN, ZR, PHID, ARGD, ZETA1D, ZETA2D, ASUMD, BSUMD
+      REAL AARG, AIC, ALIM, ANG, APHI, ASC, ASCLE, BRY, CAR, CPN, C2I,
+     * C2M, C2R, ELIM, FMR, FN, FNF, FNU, HPI, PI, RS1, SAR, SGN, SPN,
+     * TOL, X, YY, R1MACH
+      INTEGER I, IB, IFLAG, IFN, IL, IN, INU, IUF, K, KDFLG, KFLAG, KK,
+     * KODE, MR, N, NAI, NDAI, NW, NZ, IDUM, J, IPARD, IC
+      DIMENSION BRY(3), Y(N), ASUM(2), BSUM(2), PHI(2), ARG(2),
+     * ZETA1(2), ZETA2(2), CY(2), CIP(4), CSS(3), CSR(3)
+      DATA CZERO, CONE, CI, CR1, CR2 /
+     1         (0.0E0,0.0E0),(1.0E0,0.0E0),(0.0E0,1.0E0),
+     1(1.0E0,1.73205080756887729E0),(-0.5E0,-8.66025403784438647E-01)/
+      DATA HPI, PI, AIC /
+     1     1.57079632679489662E+00,     3.14159265358979324E+00,
+     1     1.26551212348464539E+00/
+      DATA CIP(1),CIP(2),CIP(3),CIP(4)/
+     1 (1.0E0,0.0E0), (0.0E0,-1.0E0), (-1.0E0,0.0E0), (0.0E0,1.0E0)/
+C
+      KDFLG = 1
+      NZ = 0
+C-----------------------------------------------------------------------
+C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION GREATER THAN
+C     THE UNDERFLOW LIMIT
+C-----------------------------------------------------------------------
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      CRSC = CMPLX(TOL,0.0E0)
+      CSS(1) = CSCL
+      CSS(2) = CONE
+      CSS(3) = CRSC
+      CSR(1) = CRSC
+      CSR(2) = CONE
+      CSR(3) = CSCL
+      BRY(1) = 1.0E+3*R1MACH(1)/TOL
+      BRY(2) = 1.0E0/BRY(1)
+      BRY(3) = R1MACH(2)
+      X = REAL(Z)
+      ZR = Z
+      IF (X.LT.0.0E0) ZR = -Z
+      YY = AIMAG(ZR)
+      ZN = -ZR*CI
+      ZB = ZR
+      INU = INT(FNU)
+      FNF = FNU - FLOAT(INU)
+      ANG = -HPI*FNF
+      CAR = COS(ANG)
+      SAR = SIN(ANG)
+      CPN = -HPI*CAR
+      SPN = -HPI*SAR
+      C2 = CMPLX(-SPN,CPN)
+      KK = MOD(INU,4) + 1
+      CS = CR1*C2*CIP(KK)
+      IF (YY.GT.0.0E0) GO TO 10
+      ZN = CONJG(-ZN)
+      ZB = CONJG(ZB)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     K(FNU,Z) IS COMPUTED FROM H(2,FNU,-I*Z) WHERE Z IS IN THE FIRST
+C     QUADRANT. FOURTH QUADRANT VALUES (YY.LE.0.0E0) ARE COMPUTED BY
+C     CONJUGATION SINCE THE K FUNCTION IS REAL ON THE POSITIVE REAL AXIS
+C-----------------------------------------------------------------------
+      J = 2
+      DO 70 I=1,N
+C-----------------------------------------------------------------------
+C     J FLIP FLOPS BETWEEN 1 AND 2 IN J = 3 - J
+C-----------------------------------------------------------------------
+        J = 3 - J
+        FN = FNU + FLOAT(I-1)
+        CALL CUNHJ(ZN, FN, 0, TOL, PHI(J), ARG(J), ZETA1(J), ZETA2(J),
+     *   ASUM(J), BSUM(J))
+        IF (KODE.EQ.1) GO TO 20
+        CFN = CMPLX(FN,0.0E0)
+        S1 = ZETA1(J) - CFN*(CFN/(ZB+ZETA2(J)))
+        GO TO 30
+   20   CONTINUE
+        S1 = ZETA1(J) - ZETA2(J)
+   30   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = REAL(S1)
+        IF (ABS(RS1).GT.ELIM) GO TO 60
+        IF (KDFLG.EQ.1) KFLAG = 2
+        IF (ABS(RS1).LT.ALIM) GO TO 40
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = CABS(PHI(J))
+        AARG = CABS(ARG(J))
+        RS1 = RS1 + ALOG(APHI) - 0.25E0*ALOG(AARG) - AIC
+        IF (ABS(RS1).GT.ELIM) GO TO 60
+        IF (KDFLG.EQ.1) KFLAG = 1
+        IF (RS1.LT.0.0E0) GO TO 40
+        IF (KDFLG.EQ.1) KFLAG = 3
+   40   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR
+C     EXPONENT EXTREMES
+C-----------------------------------------------------------------------
+        C2 = ARG(J)*CR2
+        CALL CAIRY(C2, 0, 2, AI, NAI, IDUM)
+        CALL CAIRY(C2, 1, 2, DAI, NDAI, IDUM)
+        S2 = CS*PHI(J)*(AI*ASUM(J)+CR2*DAI*BSUM(J))
+        C2R = REAL(S1)
+        C2I = AIMAG(S1)
+        C2M = EXP(C2R)*REAL(CSS(KFLAG))
+        S1 = CMPLX(C2M,0.0E0)*CMPLX(COS(C2I),SIN(C2I))
+        S2 = S2*S1
+        IF (KFLAG.NE.1) GO TO 50
+        CALL CUCHK(S2, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 60
+   50   CONTINUE
+        IF (YY.LE.0.0E0) S2 = CONJG(S2)
+        CY(KDFLG) = S2
+        Y(I) = S2*CSR(KFLAG)
+        CS = -CI*CS
+        IF (KDFLG.EQ.2) GO TO 75
+        KDFLG = 2
+        GO TO 70
+   60   CONTINUE
+        IF (RS1.GT.0.0E0) GO TO 300
+C-----------------------------------------------------------------------
+C     FOR X.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+        IF (X.LT.0.0E0) GO TO 300
+        KDFLG = 1
+        Y(I) = CZERO
+        CS = -CI*CS
+        NZ=NZ+1
+        IF (I.EQ.1) GO TO 70
+        IF (Y(I-1).EQ.CZERO) GO TO 70
+        Y(I-1) = CZERO
+        NZ=NZ+1
+   70 CONTINUE
+      I=N
+   75 CONTINUE
+      RZ = CMPLX(2.0E0,0.0E0)/ZR
+      CK = CMPLX(FN,0.0E0)*RZ
+      IB = I + 1
+      IF (N.LT.IB) GO TO 170
+C-----------------------------------------------------------------------
+C     TEST LAST MEMBER FOR UNDERFLOW AND OVERFLOW, SET SEQUENCE TO ZERO
+C     ON UNDERFLOW
+C-----------------------------------------------------------------------
+      FN = FNU+FLOAT(N-1)
+      IPARD = 1
+      IF (MR.NE.0) IPARD = 0
+      CALL CUNHJ(ZN,FN,IPARD,TOL,PHID,ARGD,ZETA1D,ZETA2D,ASUMD,BSUMD)
+      IF (KODE.EQ.1) GO TO 80
+      CFN=CMPLX(FN,0.0E0)
+      S1=ZETA1D-CFN*(CFN/(ZB+ZETA2D))
+      GO TO 90
+   80 CONTINUE
+      S1=ZETA1D-ZETA2D
+   90 CONTINUE
+      RS1=REAL(S1)
+      IF (ABS(RS1).GT.ELIM) GO TO 95
+      IF (ABS(RS1).LT.ALIM) GO TO 100
+C-----------------------------------------------------------------------
+C     REFINE ESTIMATE AND TEST
+C-----------------------------------------------------------------------
+      APHI=CABS(PHID)
+      AARG = CABS(ARGD)
+      RS1=RS1+ALOG(APHI)-0.25E0*ALOG(AARG)-AIC
+      IF (ABS(RS1).LT.ELIM) GO TO 100
+   95 CONTINUE
+      IF (RS1.GT.0.0E0) GO TO 300
+C-----------------------------------------------------------------------
+C     FOR X.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+      IF (X.LT.0.0E0) GO TO 300
+      NZ=N
+      DO 96 I=1,N
+        Y(I) = CZERO
+   96 CONTINUE
+      RETURN
+  100 CONTINUE
+C-----------------------------------------------------------------------
+C     SCALED FORWARD RECURRENCE FOR REMAINDER OF THE SEQUENCE
+C-----------------------------------------------------------------------
+      S1 = CY(1)
+      S2 = CY(2)
+      C1 = CSR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 120 I=IB,N
+        C2 = S2
+        S2 = CK*S2 + S1
+        S1 = C2
+        CK = CK + RZ
+        C2 = S2*C1
+        Y(I) = C2
+        IF (KFLAG.GE.3) GO TO 120
+        C2R = REAL(C2)
+        C2I = AIMAG(C2)
+        C2R = ABS(C2R)
+        C2I = ABS(C2I)
+        C2M = AMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 120
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1 = S1*C1
+        S2 = C2
+        S1 = S1*CSS(KFLAG)
+        S2 = S2*CSS(KFLAG)
+        C1 = CSR(KFLAG)
+  120 CONTINUE
+  170 CONTINUE
+      IF (MR.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION FOR RE(Z).LT.0.0E0
+C-----------------------------------------------------------------------
+      NZ = 0
+      FMR = FLOAT(MR)
+      SGN = -SIGN(PI,FMR)
+C-----------------------------------------------------------------------
+C     CSPN AND CSGN ARE COEFF OF K AND I FUNCTIONS RESP.
+C-----------------------------------------------------------------------
+      CSGN = CMPLX(0.0E0,SGN)
+      IF (YY.LE.0.0E0) CSGN = CONJG(CSGN)
+      IFN = INU + N - 1
+      ANG = FNF*SGN
+      CPN = COS(ANG)
+      SPN = SIN(ANG)
+      CSPN = CMPLX(CPN,SPN)
+      IF (MOD(IFN,2).EQ.1) CSPN = -CSPN
+C-----------------------------------------------------------------------
+C     CS=COEFF OF THE J FUNCTION TO GET THE I FUNCTION. I(FNU,Z) IS
+C     COMPUTED FROM EXP(I*FNU*HPI)*J(FNU,-I*Z) WHERE Z IS IN THE FIRST
+C     QUADRANT. FOURTH QUADRANT VALUES (YY.LE.0.0E0) ARE COMPUTED BY
+C     CONJUGATION SINCE THE I FUNCTION IS REAL ON THE POSITIVE REAL AXIS
+C-----------------------------------------------------------------------
+      CS = CMPLX(CAR,-SAR)*CSGN
+      IN = MOD(IFN,4) + 1
+      C2 = CIP(IN)
+      CS = CS*CONJG(C2)
+      ASC = BRY(1)
+      KK = N
+      KDFLG = 1
+      IB = IB-1
+      IC = IB-1
+      IUF = 0
+      DO 270 K=1,N
+C-----------------------------------------------------------------------
+C     LOGIC TO SORT OUT CASES WHOSE PARAMETERS WERE SET FOR THE K
+C     FUNCTION ABOVE
+C-----------------------------------------------------------------------
+        FN = FNU+FLOAT(KK-1)
+        IF (N.GT.2) GO TO 180
+  175   CONTINUE
+        PHID = PHI(J)
+        ARGD = ARG(J)
+        ZETA1D = ZETA1(J)
+        ZETA2D = ZETA2(J)
+        ASUMD = ASUM(J)
+        BSUMD = BSUM(J)
+        J = 3 - J
+        GO TO 190
+  180   CONTINUE
+        IF ((KK.EQ.N).AND.(IB.LT.N)) GO TO 190
+        IF ((KK.EQ.IB).OR.(KK.EQ.IC)) GO TO 175
+        CALL CUNHJ(ZN, FN, 0, TOL, PHID, ARGD, ZETA1D, ZETA2D,
+     *   ASUMD, BSUMD)
+  190   CONTINUE
+        IF (KODE.EQ.1) GO TO 200
+        CFN = CMPLX(FN,0.0E0)
+        S1 = -ZETA1D + CFN*(CFN/(ZB+ZETA2D))
+        GO TO 210
+  200   CONTINUE
+        S1 = -ZETA1D + ZETA2D
+  210   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = REAL(S1)
+        IF (ABS(RS1).GT.ELIM) GO TO 260
+        IF (KDFLG.EQ.1) IFLAG = 2
+        IF (ABS(RS1).LT.ALIM) GO TO 220
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = CABS(PHID)
+        AARG = CABS(ARGD)
+        RS1 = RS1 + ALOG(APHI) - 0.25E0*ALOG(AARG) - AIC
+        IF (ABS(RS1).GT.ELIM) GO TO 260
+        IF (KDFLG.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0E0) GO TO 220
+        IF (KDFLG.EQ.1) IFLAG = 3
+  220   CONTINUE
+        CALL CAIRY(ARGD, 0, 2, AI, NAI, IDUM)
+        CALL CAIRY(ARGD, 1, 2, DAI, NDAI, IDUM)
+        S2 = CS*PHID*(AI*ASUMD+DAI*BSUMD)
+        C2R = REAL(S1)
+        C2I = AIMAG(S1)
+        C2M = EXP(C2R)*REAL(CSS(IFLAG))
+        S1 = CMPLX(C2M,0.0E0)*CMPLX(COS(C2I),SIN(C2I))
+        S2 = S2*S1
+        IF (IFLAG.NE.1) GO TO 230
+        CALL CUCHK(S2, NW, BRY(1), TOL)
+        IF (NW.NE.0) S2 = CMPLX(0.0E0,0.0E0)
+  230   CONTINUE
+        IF (YY.LE.0.0E0) S2 = CONJG(S2)
+        CY(KDFLG) = S2
+        C2 = S2
+        S2 = S2*CSR(IFLAG)
+C-----------------------------------------------------------------------
+C     ADD I AND K FUNCTIONS, K SEQUENCE IN Y(I), I=1,N
+C-----------------------------------------------------------------------
+        S1 = Y(KK)
+        IF (KODE.EQ.1) GO TO 250
+        CALL CS1S2(ZR, S1, S2, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  250   CONTINUE
+        Y(KK) = S1*CSPN + S2
+        KK = KK - 1
+        CSPN = -CSPN
+        CS = -CS*CI
+        IF (C2.NE.CZERO) GO TO 255
+        KDFLG = 1
+        GO TO 270
+  255   CONTINUE
+        IF (KDFLG.EQ.2) GO TO 275
+        KDFLG = 2
+        GO TO 270
+  260   CONTINUE
+        IF (RS1.GT.0.0E0) GO TO 300
+        S2 = CZERO
+        GO TO 230
+  270 CONTINUE
+      K = N
+  275 CONTINUE
+      IL = N-K
+      IF (IL.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     RECUR BACKWARD FOR REMAINDER OF I SEQUENCE AND ADD IN THE
+C     K FUNCTIONS, SCALING THE I SEQUENCE DURING RECURRENCE TO KEEP
+C     INTERMEDIATE ARITHMETIC ON SCALE NEAR EXPONENT EXTREMES.
+C-----------------------------------------------------------------------
+      S1 = CY(1)
+      S2 = CY(2)
+      CS = CSR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      FN = FLOAT(INU+IL)
+      DO 290 I=1,IL
+        C2 = S2
+        S2 = S1 + CMPLX(FN+FNF,0.0E0)*RZ*S2
+        S1 = C2
+        FN = FN - 1.0E0
+        C2 = S2*CS
+        CK = C2
+        C1 = Y(KK)
+        IF (KODE.EQ.1) GO TO 280
+        CALL CS1S2(ZR, C1, C2, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  280   CONTINUE
+        Y(KK) = C1*CSPN + C2
+        KK = KK - 1
+        CSPN = -CSPN
+        IF (IFLAG.GE.3) GO TO 290
+        C2R = REAL(CK)
+        C2I = AIMAG(CK)
+        C2R = ABS(C2R)
+        C2I = ABS(C2I)
+        C2M = AMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 290
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1 = S1*CS
+        S2 = CK
+        S1 = S1*CSS(IFLAG)
+        S2 = S2*CSS(IFLAG)
+        CS = CSR(IFLAG)
+  290 CONTINUE
+      RETURN
+  300 CONTINUE
+      NZ = -1
+      RETURN
+      END
diff --git a/libcruft/amos/cuoik.f b/libcruft/amos/cuoik.f
new file mode 100644
index 0000000..de45ad7
--- /dev/null
+++ b/libcruft/amos/cuoik.f
@@ -0,0 +1,159 @@
+      SUBROUTINE CUOIK(Z, FNU, KODE, IKFLG, N, Y, NUF, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CUOIK
+C***REFER TO  CBESI,CBESK,CBESH
+C
+C     CUOIK COMPUTES THE LEADING TERMS OF THE UNIFORM ASYMPTOTIC
+C     EXPANSIONS FOR THE I AND K FUNCTIONS AND COMPARES THEM
+C     (IN LOGARITHMIC FORM) TO ALIM AND ELIM FOR OVER AND UNDERFLOW
+C     WHERE ALIM.LT.ELIM. IF THE MAGNITUDE, BASED ON THE LEADING
+C     EXPONENTIAL, IS LESS THAN ALIM OR GREATER THAN -ALIM, THEN
+C     THE RESULT IS ON SCALE. IF NOT, THEN A REFINED TEST USING OTHER
+C     MULTIPLIERS (IN LOGARITHMIC FORM) IS MADE BASED ON ELIM. HERE
+C     EXP(-ELIM)=SMALLEST MACHINE NUMBER*1.0E+3 AND EXP(-ALIM)=
+C     EXP(-ELIM)/TOL
+C
+C     IKFLG=1 MEANS THE I SEQUENCE IS TESTED
+C          =2 MEANS THE K SEQUENCE IS TESTED
+C     NUF = 0 MEANS THE LAST MEMBER OF THE SEQUENCE IS ON SCALE
+C         =-1 MEANS AN OVERFLOW WOULD OCCUR
+C     IKFLG=1 AND NUF.GT.0 MEANS THE LAST NUF Y VALUES WERE SET TO ZERO
+C             THE FIRST N-NUF VALUES MUST BE SET BY ANOTHER ROUTINE
+C     IKFLG=2 AND NUF.EQ.N MEANS ALL Y VALUES WERE SET TO ZERO
+C     IKFLG=2 AND 0.LT.NUF.LT.N NOT CONSIDERED. Y MUST BE SET BY
+C             ANOTHER ROUTINE
+C
+C***ROUTINES CALLED  CUCHK,CUNHJ,CUNIK,R1MACH
+C***END PROLOGUE  CUOIK
+      COMPLEX ARG, ASUM, BSUM, CWRK, CZ, CZERO, PHI, SUM, Y, Z, ZB,
+     * ZETA1, ZETA2, ZN, ZR
+      REAL AARG, AIC, ALIM, APHI, ASCLE, AX, AY, ELIM, FNN, FNU, GNN,
+     * GNU, RCZ, TOL, X, YY
+      INTEGER I, IFORM, IKFLG, INIT, KODE, N, NN, NUF, NW
+      DIMENSION Y(N), CWRK(16)
+      DATA CZERO / (0.0E0,0.0E0) /
+      DATA AIC / 1.265512123484645396E+00 /
+      NUF = 0
+      NN = N
+      X = REAL(Z)
+      ZR = Z
+      IF (X.LT.0.0E0) ZR = -Z
+      ZB = ZR
+      YY = AIMAG(ZR)
+      AX = ABS(X)*1.7321E0
+      AY = ABS(YY)
+      IFORM = 1
+      IF (AY.GT.AX) IFORM = 2
+      GNU = AMAX1(FNU,1.0E0)
+      IF (IKFLG.EQ.1) GO TO 10
+      FNN = FLOAT(NN)
+      GNN = FNU + FNN - 1.0E0
+      GNU = AMAX1(GNN,FNN)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ONLY THE MAGNITUDE OF ARG AND PHI ARE NEEDED ALONG WITH THE
+C     REAL PARTS OF ZETA1, ZETA2 AND ZB. NO ATTEMPT IS MADE TO GET
+C     THE SIGN OF THE IMAGINARY PART CORRECT.
+C-----------------------------------------------------------------------
+      IF (IFORM.EQ.2) GO TO 20
+      INIT = 0
+      CALL CUNIK(ZR, GNU, IKFLG, 1, TOL, INIT, PHI, ZETA1, ZETA2, SUM,
+     * CWRK)
+      CZ = -ZETA1 + ZETA2
+      GO TO 40
+   20 CONTINUE
+      ZN = -ZR*CMPLX(0.0E0,1.0E0)
+      IF (YY.GT.0.0E0) GO TO 30
+      ZN = CONJG(-ZN)
+   30 CONTINUE
+      CALL CUNHJ(ZN, GNU, 1, TOL, PHI, ARG, ZETA1, ZETA2, ASUM, BSUM)
+      CZ = -ZETA1 + ZETA2
+      AARG = CABS(ARG)
+   40 CONTINUE
+      IF (KODE.EQ.2) CZ = CZ - ZB
+      IF (IKFLG.EQ.2) CZ = -CZ
+      APHI = CABS(PHI)
+      RCZ = REAL(CZ)
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (RCZ.GT.ELIM) GO TO 170
+      IF (RCZ.LT.ALIM) GO TO 50
+      RCZ = RCZ + ALOG(APHI)
+      IF (IFORM.EQ.2) RCZ = RCZ - 0.25E0*ALOG(AARG) - AIC
+      IF (RCZ.GT.ELIM) GO TO 170
+      GO TO 100
+   50 CONTINUE
+C-----------------------------------------------------------------------
+C     UNDERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (RCZ.LT.(-ELIM)) GO TO 60
+      IF (RCZ.GT.(-ALIM)) GO TO 100
+      RCZ = RCZ + ALOG(APHI)
+      IF (IFORM.EQ.2) RCZ = RCZ - 0.25E0*ALOG(AARG) - AIC
+      IF (RCZ.GT.(-ELIM)) GO TO 80
+   60 CONTINUE
+      DO 70 I=1,NN
+        Y(I) = CZERO
+   70 CONTINUE
+      NUF = NN
+      RETURN
+   80 CONTINUE
+      ASCLE = 1.0E+3*R1MACH(1)/TOL
+      CZ = CZ + CLOG(PHI)
+      IF (IFORM.EQ.1) GO TO 90
+      CZ = CZ - CMPLX(0.25E0,0.0E0)*CLOG(ARG) - CMPLX(AIC,0.0E0)
+   90 CONTINUE
+      AX = EXP(RCZ)/TOL
+      AY = AIMAG(CZ)
+      CZ = CMPLX(AX,0.0E0)*CMPLX(COS(AY),SIN(AY))
+      CALL CUCHK(CZ, NW, ASCLE, TOL)
+      IF (NW.EQ.1) GO TO 60
+  100 CONTINUE
+      IF (IKFLG.EQ.2) RETURN
+      IF (N.EQ.1) RETURN
+C-----------------------------------------------------------------------
+C     SET UNDERFLOWS ON I SEQUENCE
+C-----------------------------------------------------------------------
+  110 CONTINUE
+      GNU = FNU + FLOAT(NN-1)
+      IF (IFORM.EQ.2) GO TO 120
+      INIT = 0
+      CALL CUNIK(ZR, GNU, IKFLG, 1, TOL, INIT, PHI, ZETA1, ZETA2, SUM,
+     * CWRK)
+      CZ = -ZETA1 + ZETA2
+      GO TO 130
+  120 CONTINUE
+      CALL CUNHJ(ZN, GNU, 1, TOL, PHI, ARG, ZETA1, ZETA2, ASUM, BSUM)
+      CZ = -ZETA1 + ZETA2
+      AARG = CABS(ARG)
+  130 CONTINUE
+      IF (KODE.EQ.2) CZ = CZ - ZB
+      APHI = CABS(PHI)
+      RCZ = REAL(CZ)
+      IF (RCZ.LT.(-ELIM)) GO TO 140
+      IF (RCZ.GT.(-ALIM)) RETURN
+      RCZ = RCZ + ALOG(APHI)
+      IF (IFORM.EQ.2) RCZ = RCZ - 0.25E0*ALOG(AARG) - AIC
+      IF (RCZ.GT.(-ELIM)) GO TO 150
+  140 CONTINUE
+      Y(NN) = CZERO
+      NN = NN - 1
+      NUF = NUF + 1
+      IF (NN.EQ.0) RETURN
+      GO TO 110
+  150 CONTINUE
+      ASCLE = 1.0E+3*R1MACH(1)/TOL
+      CZ = CZ + CLOG(PHI)
+      IF (IFORM.EQ.1) GO TO 160
+      CZ = CZ - CMPLX(0.25E0,0.0E0)*CLOG(ARG) - CMPLX(AIC,0.0E0)
+  160 CONTINUE
+      AX = EXP(RCZ)/TOL
+      AY = AIMAG(CZ)
+      CZ = CMPLX(AX,0.0E0)*CMPLX(COS(AY),SIN(AY))
+      CALL CUCHK(CZ, NW, ASCLE, TOL)
+      IF (NW.EQ.1) GO TO 140
+      RETURN
+  170 CONTINUE
+      NUF = -1
+      RETURN
+      END
diff --git a/libcruft/amos/cwrsk.f b/libcruft/amos/cwrsk.f
new file mode 100644
index 0000000..edc2f4c
--- /dev/null
+++ b/libcruft/amos/cwrsk.f
@@ -0,0 +1,75 @@
+      SUBROUTINE CWRSK(ZR, FNU, KODE, N, Y, NZ, CW, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  CWRSK
+C***REFER TO  CBESI,CBESK
+C
+C     CWRSK COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY
+C     NORMALIZING THE I FUNCTION RATIOS FROM CRATI BY THE WRONSKIAN
+C
+C***ROUTINES CALLED  CBKNU,CRATI,R1MACH
+C***END PROLOGUE  CWRSK
+      COMPLEX CINU, CSCL, CT, CW, C1, C2, RCT, ST, Y, ZR
+      REAL ACT, ACW, ALIM, ASCLE, ELIM, FNU, S1, S2, TOL, YY
+      INTEGER I, KODE, N, NW, NZ
+      DIMENSION Y(N), CW(2)
+C-----------------------------------------------------------------------
+C     I(FNU+I-1,Z) BY BACKWARD RECURRENCE FOR RATIOS
+C     Y(I)=I(FNU+I,Z)/I(FNU+I-1,Z) FROM CRATI NORMALIZED BY THE
+C     WRONSKIAN WITH K(FNU,Z) AND K(FNU+1,Z) FROM CBKNU.
+C-----------------------------------------------------------------------
+      NZ = 0
+      CALL CBKNU(ZR, FNU, KODE, 2, CW, NW, TOL, ELIM, ALIM)
+      IF (NW.NE.0) GO TO 50
+      CALL CRATI(ZR, FNU, N, Y, TOL)
+C-----------------------------------------------------------------------
+C     RECUR FORWARD ON I(FNU+1,Z) = R(FNU,Z)*I(FNU,Z),
+C     R(FNU+J-1,Z)=Y(J),  J=1,...,N
+C-----------------------------------------------------------------------
+      CINU = CMPLX(1.0E0,0.0E0)
+      IF (KODE.EQ.1) GO TO 10
+      YY = AIMAG(ZR)
+      S1 = COS(YY)
+      S2 = SIN(YY)
+      CINU = CMPLX(S1,S2)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ON LOW EXPONENT MACHINES THE K FUNCTIONS CAN BE CLOSE TO BOTH
+C     THE UNDER AND OVERFLOW LIMITS AND THE NORMALIZATION MUST BE
+C     SCALED TO PREVENT OVER OR UNDERFLOW. CUOIK HAS DETERMINED THAT
+C     THE RESULT IS ON SCALE.
+C-----------------------------------------------------------------------
+      ACW = CABS(CW(2))
+      ASCLE = 1.0E+3*R1MACH(1)/TOL
+      CSCL = CMPLX(1.0E0,0.0E0)
+      IF (ACW.GT.ASCLE) GO TO 20
+      CSCL = CMPLX(1.0E0/TOL,0.0E0)
+      GO TO 30
+   20 CONTINUE
+      ASCLE = 1.0E0/ASCLE
+      IF (ACW.LT.ASCLE) GO TO 30
+      CSCL = CMPLX(TOL,0.0E0)
+   30 CONTINUE
+      C1 = CW(1)*CSCL
+      C2 = CW(2)*CSCL
+      ST = Y(1)
+C-----------------------------------------------------------------------
+C     CINU=CINU*(CONJG(CT)/CABS(CT))*(1.0E0/CABS(CT) PREVENTS
+C     UNDER- OR OVERFLOW PREMATURELY BY SQUARING CABS(CT)
+C-----------------------------------------------------------------------
+      CT = ZR*(C2+ST*C1)
+      ACT = CABS(CT)
+      RCT = CMPLX(1.0E0/ACT,0.0E0)
+      CT = CONJG(CT)*RCT
+      CINU = CINU*RCT*CT
+      Y(1) = CINU*CSCL
+      IF (N.EQ.1) RETURN
+      DO 40 I=2,N
+        CINU = ST*CINU
+        ST = Y(I)
+        Y(I) = CINU*CSCL
+   40 CONTINUE
+      RETURN
+   50 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/dgamln.f b/libcruft/amos/dgamln.f
new file mode 100644
index 0000000..792014b
--- /dev/null
+++ b/libcruft/amos/dgamln.f
@@ -0,0 +1,189 @@
+      DOUBLE PRECISION FUNCTION DGAMLN(Z,IERR)
+C***BEGIN PROLOGUE  DGAMLN
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  830501   (YYMMDD)
+C***CATEGORY NO.  B5F
+C***KEYWORDS  GAMMA FUNCTION,LOGARITHM OF GAMMA FUNCTION
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE LOGARITHM OF THE GAMMA FUNCTION
+C***DESCRIPTION
+C
+C               **** A DOUBLE PRECISION ROUTINE ****
+C         DGAMLN COMPUTES THE NATURAL LOG OF THE GAMMA FUNCTION FOR
+C         Z.GT.0.  THE ASYMPTOTIC EXPANSION IS USED TO GENERATE VALUES
+C         GREATER THAN ZMIN WHICH ARE ADJUSTED BY THE RECURSION
+C         G(Z+1)=Z*G(Z) FOR Z.LE.ZMIN.  THE FUNCTION WAS MADE AS
+C         PORTABLE AS POSSIBLE BY COMPUTIMG ZMIN FROM THE NUMBER OF BASE
+C         10 DIGITS IN A WORD, RLN=AMAX1(-ALOG10(R1MACH(4)),0.5E-18)
+C         LIMITED TO 18 DIGITS OF (RELATIVE) ACCURACY.
+C
+C         SINCE INTEGER ARGUMENTS ARE COMMON, A TABLE LOOK UP ON 100
+C         VALUES IS USED FOR SPEED OF EXECUTION.
+C
+C     DESCRIPTION OF ARGUMENTS
+C
+C         INPUT      Z IS D0UBLE PRECISION
+C           Z      - ARGUMENT, Z.GT.0.0D0
+C
+C         OUTPUT      DGAMLN IS DOUBLE PRECISION
+C           DGAMLN  - NATURAL LOG OF THE GAMMA FUNCTION AT Z.NE.0.0D0
+C           IERR    - ERROR FLAG
+C                     IERR=0, NORMAL RETURN, COMPUTATION COMPLETED
+C                     IERR=1, Z.LE.0.0D0,    NO COMPUTATION
+C
+C
+C***REFERENCES  COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C***ROUTINES CALLED  I1MACH,D1MACH
+C***END PROLOGUE  DGAMLN
+      DOUBLE PRECISION CF, CON, FLN, FZ, GLN, RLN, S, TLG, TRM, TST,
+     * T1, WDTOL, Z, ZDMY, ZINC, ZM, ZMIN, ZP, ZSQ, D1MACH
+      INTEGER I, IERR, I1M, K, MZ, NZ, I1MACH
+      DIMENSION CF(22), GLN(100)
+C           LNGAMMA(N), N=1,100
+      DATA GLN(1), GLN(2), GLN(3), GLN(4), GLN(5), GLN(6), GLN(7),
+     1     GLN(8), GLN(9), GLN(10), GLN(11), GLN(12), GLN(13), GLN(14),
+     2     GLN(15), GLN(16), GLN(17), GLN(18), GLN(19), GLN(20),
+     3     GLN(21), GLN(22)/
+     4     0.00000000000000000D+00,     0.00000000000000000D+00,
+     5     6.93147180559945309D-01,     1.79175946922805500D+00,
+     6     3.17805383034794562D+00,     4.78749174278204599D+00,
+     7     6.57925121201010100D+00,     8.52516136106541430D+00,
+     8     1.06046029027452502D+01,     1.28018274800814696D+01,
+     9     1.51044125730755153D+01,     1.75023078458738858D+01,
+     A     1.99872144956618861D+01,     2.25521638531234229D+01,
+     B     2.51912211827386815D+01,     2.78992713838408916D+01,
+     C     3.06718601060806728D+01,     3.35050734501368889D+01,
+     D     3.63954452080330536D+01,     3.93398841871994940D+01,
+     E     4.23356164607534850D+01,     4.53801388984769080D+01/
+      DATA GLN(23), GLN(24), GLN(25), GLN(26), GLN(27), GLN(28),
+     1     GLN(29), GLN(30), GLN(31), GLN(32), GLN(33), GLN(34),
+     2     GLN(35), GLN(36), GLN(37), GLN(38), GLN(39), GLN(40),
+     3     GLN(41), GLN(42), GLN(43), GLN(44)/
+     4     4.84711813518352239D+01,     5.16066755677643736D+01,
+     5     5.47847293981123192D+01,     5.80036052229805199D+01,
+     6     6.12617017610020020D+01,     6.45575386270063311D+01,
+     7     6.78897431371815350D+01,     7.12570389671680090D+01,
+     8     7.46582363488301644D+01,     7.80922235533153106D+01,
+     9     8.15579594561150372D+01,     8.50544670175815174D+01,
+     A     8.85808275421976788D+01,     9.21361756036870925D+01,
+     B     9.57196945421432025D+01,     9.93306124547874269D+01,
+     C     1.02968198614513813D+02,     1.06631760260643459D+02,
+     D     1.10320639714757395D+02,     1.14034211781461703D+02,
+     E     1.17771881399745072D+02,     1.21533081515438634D+02/
+      DATA GLN(45), GLN(46), GLN(47), GLN(48), GLN(49), GLN(50),
+     1     GLN(51), GLN(52), GLN(53), GLN(54), GLN(55), GLN(56),
+     2     GLN(57), GLN(58), GLN(59), GLN(60), GLN(61), GLN(62),
+     3     GLN(63), GLN(64), GLN(65), GLN(66)/
+     4     1.25317271149356895D+02,     1.29123933639127215D+02,
+     5     1.32952575035616310D+02,     1.36802722637326368D+02,
+     6     1.40673923648234259D+02,     1.44565743946344886D+02,
+     7     1.48477766951773032D+02,     1.52409592584497358D+02,
+     8     1.56360836303078785D+02,     1.60331128216630907D+02,
+     9     1.64320112263195181D+02,     1.68327445448427652D+02,
+     A     1.72352797139162802D+02,     1.76395848406997352D+02,
+     B     1.80456291417543771D+02,     1.84533828861449491D+02,
+     C     1.88628173423671591D+02,     1.92739047287844902D+02,
+     D     1.96866181672889994D+02,     2.01009316399281527D+02,
+     E     2.05168199482641199D+02,     2.09342586752536836D+02/
+      DATA GLN(67), GLN(68), GLN(69), GLN(70), GLN(71), GLN(72),
+     1     GLN(73), GLN(74), GLN(75), GLN(76), GLN(77), GLN(78),
+     2     GLN(79), GLN(80), GLN(81), GLN(82), GLN(83), GLN(84),
+     3     GLN(85), GLN(86), GLN(87), GLN(88)/
+     4     2.13532241494563261D+02,     2.17736934113954227D+02,
+     5     2.21956441819130334D+02,     2.26190548323727593D+02,
+     6     2.30439043565776952D+02,     2.34701723442818268D+02,
+     7     2.38978389561834323D+02,     2.43268849002982714D+02,
+     8     2.47572914096186884D+02,     2.51890402209723194D+02,
+     9     2.56221135550009525D+02,     2.60564940971863209D+02,
+     A     2.64921649798552801D+02,     2.69291097651019823D+02,
+     B     2.73673124285693704D+02,     2.78067573440366143D+02,
+     C     2.82474292687630396D+02,     2.86893133295426994D+02,
+     D     2.91323950094270308D+02,     2.95766601350760624D+02,
+     E     3.00220948647014132D+02,     3.04686856765668715D+02/
+      DATA GLN(89), GLN(90), GLN(91), GLN(92), GLN(93), GLN(94),
+     1     GLN(95), GLN(96), GLN(97), GLN(98), GLN(99), GLN(100)/
+     2     3.09164193580146922D+02,     3.13652829949879062D+02,
+     3     3.18152639620209327D+02,     3.22663499126726177D+02,
+     4     3.27185287703775217D+02,     3.31717887196928473D+02,
+     5     3.36261181979198477D+02,     3.40815058870799018D+02,
+     6     3.45379407062266854D+02,     3.49954118040770237D+02,
+     7     3.54539085519440809D+02,     3.59134205369575399D+02/
+C             COEFFICIENTS OF ASYMPTOTIC EXPANSION
+      DATA CF(1), CF(2), CF(3), CF(4), CF(5), CF(6), CF(7), CF(8),
+     1     CF(9), CF(10), CF(11), CF(12), CF(13), CF(14), CF(15),
+     2     CF(16), CF(17), CF(18), CF(19), CF(20), CF(21), CF(22)/
+     3     8.33333333333333333D-02,    -2.77777777777777778D-03,
+     4     7.93650793650793651D-04,    -5.95238095238095238D-04,
+     5     8.41750841750841751D-04,    -1.91752691752691753D-03,
+     6     6.41025641025641026D-03,    -2.95506535947712418D-02,
+     7     1.79644372368830573D-01,    -1.39243221690590112D+00,
+     8     1.34028640441683920D+01,    -1.56848284626002017D+02,
+     9     2.19310333333333333D+03,    -3.61087712537249894D+04,
+     A     6.91472268851313067D+05,    -1.52382215394074162D+07,
+     B     3.82900751391414141D+08,    -1.08822660357843911D+10,
+     C     3.47320283765002252D+11,    -1.23696021422692745D+13,
+     D     4.88788064793079335D+14,    -2.13203339609193739D+16/
+C
+C             LN(2*PI)
+      DATA CON                    /     1.83787706640934548D+00/
+C
+C***FIRST EXECUTABLE STATEMENT  DGAMLN
+      IERR=0
+      IF (Z.LE.0.0D0) GO TO 70
+      IF (Z.GT.101.0D0) GO TO 10
+      NZ = INT(SNGL(Z))
+      FZ = Z - FLOAT(NZ)
+      IF (FZ.GT.0.0D0) GO TO 10
+      IF (NZ.GT.100) GO TO 10
+      DGAMLN = GLN(NZ)
+      RETURN
+   10 CONTINUE
+      WDTOL = D1MACH(4)
+      WDTOL = DMAX1(WDTOL,0.5D-18)
+      I1M = I1MACH(14)
+      RLN = D1MACH(5)*FLOAT(I1M)
+      FLN = DMIN1(RLN,20.0D0)
+      FLN = DMAX1(FLN,3.0D0)
+      FLN = FLN - 3.0D0
+      ZM = 1.8000D0 + 0.3875D0*FLN
+      MZ = INT(SNGL(ZM)) + 1
+      ZMIN = FLOAT(MZ)
+      ZDMY = Z
+      ZINC = 0.0D0
+      IF (Z.GE.ZMIN) GO TO 20
+      ZINC = ZMIN - FLOAT(NZ)
+      ZDMY = Z + ZINC
+   20 CONTINUE
+      ZP = 1.0D0/ZDMY
+      T1 = CF(1)*ZP
+      S = T1
+      IF (ZP.LT.WDTOL) GO TO 40
+      ZSQ = ZP*ZP
+      TST = T1*WDTOL
+      DO 30 K=2,22
+        ZP = ZP*ZSQ
+        TRM = CF(K)*ZP
+        IF (DABS(TRM).LT.TST) GO TO 40
+        S = S + TRM
+   30 CONTINUE
+   40 CONTINUE
+      IF (ZINC.NE.0.0D0) GO TO 50
+      TLG = DLOG(Z)
+      DGAMLN = Z*(TLG-1.0D0) + 0.5D0*(CON-TLG) + S
+      RETURN
+   50 CONTINUE
+      ZP = 1.0D0
+      NZ = INT(SNGL(ZINC))
+      DO 60 I=1,NZ
+        ZP = ZP*(Z+FLOAT(I-1))
+   60 CONTINUE
+      TLG = DLOG(ZDMY)
+      DGAMLN = ZDMY*(TLG-1.0D0) - DLOG(ZP) + 0.5D0*(CON-TLG) + S
+      RETURN
+C
+C
+   70 CONTINUE
+      IERR=1
+      RETURN
+      END
diff --git a/libcruft/amos/gamln.f b/libcruft/amos/gamln.f
new file mode 100644
index 0000000..99ba42f
--- /dev/null
+++ b/libcruft/amos/gamln.f
@@ -0,0 +1,189 @@
+      FUNCTION GAMLN(Z,IERR)
+C***BEGIN PROLOGUE  GAMLN
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  830501   (YYMMDD)
+C***CATEGORY NO.  B5F
+C***KEYWORDS  GAMMA FUNCTION,LOGARITHM OF GAMMA FUNCTION
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE LOGARITHM OF THE GAMMA FUNCTION
+C***DESCRIPTION
+C
+C         GAMLN COMPUTES THE NATURAL LOG OF THE GAMMA FUNCTION FOR
+C         Z.GT.0.  THE ASYMPTOTIC EXPANSION IS USED TO GENERATE VALUES
+C         GREATER THAN ZMIN WHICH ARE ADJUSTED BY THE RECURSION
+C         G(Z+1)=Z*G(Z) FOR Z.LE.ZMIN.  THE FUNCTION WAS MADE AS
+C         PORTABLE AS POSSIBLE BY COMPUTIMG ZMIN FROM THE NUMBER OF BASE
+C         10 DIGITS IN A WORD, RLN=AMAX1(-ALOG10(R1MACH(4)),0.5E-18)
+C         LIMITED TO 18 DIGITS OF (RELATIVE) ACCURACY.
+C
+C         SINCE INTEGER ARGUMENTS ARE COMMON, A TABLE LOOK UP ON 100
+C         VALUES IS USED FOR SPEED OF EXECUTION.
+C
+C     DESCRIPTION OF ARGUMENTS
+C
+C         INPUT
+C           Z      - REAL ARGUMENT, Z.GT.0.0E0
+C
+C         OUTPUT
+C           GAMLN  - NATURAL LOG OF THE GAMMA FUNCTION AT Z
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN, COMPUTATION COMPLETED
+C                    IERR=1, Z.LE.0.0E0,    NO COMPUTATION
+C
+C***REFERENCES  COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C***ROUTINES CALLED  I1MACH,R1MACH
+C***END PROLOGUE  GAMLN
+C
+      INTEGER I, I1M, K, MZ, NZ, IERR, I1MACH
+      REAL CF, CON, FLN, FZ, GLN, RLN, S, TLG, TRM, TST, T1, WDTOL, Z,
+     * ZDMY, ZINC, ZM, ZMIN, ZP, ZSQ
+      REAL R1MACH
+      DIMENSION CF(22), GLN(100)
+C           LNGAMMA(N), N=1,100
+      DATA GLN(1), GLN(2), GLN(3), GLN(4), GLN(5), GLN(6), GLN(7),
+     1     GLN(8), GLN(9), GLN(10), GLN(11), GLN(12), GLN(13), GLN(14),
+     2     GLN(15), GLN(16), GLN(17), GLN(18), GLN(19), GLN(20),
+     3     GLN(21), GLN(22)/
+     4     0.00000000000000000E+00,     0.00000000000000000E+00,
+     5     6.93147180559945309E-01,     1.79175946922805500E+00,
+     6     3.17805383034794562E+00,     4.78749174278204599E+00,
+     7     6.57925121201010100E+00,     8.52516136106541430E+00,
+     8     1.06046029027452502E+01,     1.28018274800814696E+01,
+     9     1.51044125730755153E+01,     1.75023078458738858E+01,
+     A     1.99872144956618861E+01,     2.25521638531234229E+01,
+     B     2.51912211827386815E+01,     2.78992713838408916E+01,
+     C     3.06718601060806728E+01,     3.35050734501368889E+01,
+     D     3.63954452080330536E+01,     3.93398841871994940E+01,
+     E     4.23356164607534850E+01,     4.53801388984769080E+01/
+      DATA GLN(23), GLN(24), GLN(25), GLN(26), GLN(27), GLN(28),
+     1     GLN(29), GLN(30), GLN(31), GLN(32), GLN(33), GLN(34),
+     2     GLN(35), GLN(36), GLN(37), GLN(38), GLN(39), GLN(40),
+     3     GLN(41), GLN(42), GLN(43), GLN(44)/
+     4     4.84711813518352239E+01,     5.16066755677643736E+01,
+     5     5.47847293981123192E+01,     5.80036052229805199E+01,
+     6     6.12617017610020020E+01,     6.45575386270063311E+01,
+     7     6.78897431371815350E+01,     7.12570389671680090E+01,
+     8     7.46582363488301644E+01,     7.80922235533153106E+01,
+     9     8.15579594561150372E+01,     8.50544670175815174E+01,
+     A     8.85808275421976788E+01,     9.21361756036870925E+01,
+     B     9.57196945421432025E+01,     9.93306124547874269E+01,
+     C     1.02968198614513813E+02,     1.06631760260643459E+02,
+     D     1.10320639714757395E+02,     1.14034211781461703E+02,
+     E     1.17771881399745072E+02,     1.21533081515438634E+02/
+      DATA GLN(45), GLN(46), GLN(47), GLN(48), GLN(49), GLN(50),
+     1     GLN(51), GLN(52), GLN(53), GLN(54), GLN(55), GLN(56),
+     2     GLN(57), GLN(58), GLN(59), GLN(60), GLN(61), GLN(62),
+     3     GLN(63), GLN(64), GLN(65), GLN(66)/
+     4     1.25317271149356895E+02,     1.29123933639127215E+02,
+     5     1.32952575035616310E+02,     1.36802722637326368E+02,
+     6     1.40673923648234259E+02,     1.44565743946344886E+02,
+     7     1.48477766951773032E+02,     1.52409592584497358E+02,
+     8     1.56360836303078785E+02,     1.60331128216630907E+02,
+     9     1.64320112263195181E+02,     1.68327445448427652E+02,
+     A     1.72352797139162802E+02,     1.76395848406997352E+02,
+     B     1.80456291417543771E+02,     1.84533828861449491E+02,
+     C     1.88628173423671591E+02,     1.92739047287844902E+02,
+     D     1.96866181672889994E+02,     2.01009316399281527E+02,
+     E     2.05168199482641199E+02,     2.09342586752536836E+02/
+      DATA GLN(67), GLN(68), GLN(69), GLN(70), GLN(71), GLN(72),
+     1     GLN(73), GLN(74), GLN(75), GLN(76), GLN(77), GLN(78),
+     2     GLN(79), GLN(80), GLN(81), GLN(82), GLN(83), GLN(84),
+     3     GLN(85), GLN(86), GLN(87), GLN(88)/
+     4     2.13532241494563261E+02,     2.17736934113954227E+02,
+     5     2.21956441819130334E+02,     2.26190548323727593E+02,
+     6     2.30439043565776952E+02,     2.34701723442818268E+02,
+     7     2.38978389561834323E+02,     2.43268849002982714E+02,
+     8     2.47572914096186884E+02,     2.51890402209723194E+02,
+     9     2.56221135550009525E+02,     2.60564940971863209E+02,
+     A     2.64921649798552801E+02,     2.69291097651019823E+02,
+     B     2.73673124285693704E+02,     2.78067573440366143E+02,
+     C     2.82474292687630396E+02,     2.86893133295426994E+02,
+     D     2.91323950094270308E+02,     2.95766601350760624E+02,
+     E     3.00220948647014132E+02,     3.04686856765668715E+02/
+      DATA GLN(89), GLN(90), GLN(91), GLN(92), GLN(93), GLN(94),
+     1     GLN(95), GLN(96), GLN(97), GLN(98), GLN(99), GLN(100)/
+     2     3.09164193580146922E+02,     3.13652829949879062E+02,
+     3     3.18152639620209327E+02,     3.22663499126726177E+02,
+     4     3.27185287703775217E+02,     3.31717887196928473E+02,
+     5     3.36261181979198477E+02,     3.40815058870799018E+02,
+     6     3.45379407062266854E+02,     3.49954118040770237E+02,
+     7     3.54539085519440809E+02,     3.59134205369575399E+02/
+C             COEFFICIENTS OF ASYMPTOTIC EXPANSION
+      DATA CF(1), CF(2), CF(3), CF(4), CF(5), CF(6), CF(7), CF(8),
+     1     CF(9), CF(10), CF(11), CF(12), CF(13), CF(14), CF(15),
+     2     CF(16), CF(17), CF(18), CF(19), CF(20), CF(21), CF(22)/
+     3     8.33333333333333333E-02,    -2.77777777777777778E-03,
+     4     7.93650793650793651E-04,    -5.95238095238095238E-04,
+     5     8.41750841750841751E-04,    -1.91752691752691753E-03,
+     6     6.41025641025641026E-03,    -2.95506535947712418E-02,
+     7     1.79644372368830573E-01,    -1.39243221690590112E+00,
+     8     1.34028640441683920E+01,    -1.56848284626002017E+02,
+     9     2.19310333333333333E+03,    -3.61087712537249894E+04,
+     A     6.91472268851313067E+05,    -1.52382215394074162E+07,
+     B     3.82900751391414141E+08,    -1.08822660357843911E+10,
+     C     3.47320283765002252E+11,    -1.23696021422692745E+13,
+     D     4.88788064793079335E+14,    -2.13203339609193739E+16/
+C
+C             LN(2*PI)
+      DATA CON                    /     1.83787706640934548E+00/
+C
+C***FIRST EXECUTABLE STATEMENT  GAMLN
+      IERR=0
+      IF (Z.LE.0.0E0) GO TO 70
+      IF (Z.GT.101.0E0) GO TO 10
+      NZ = INT(Z)
+      FZ = Z - FLOAT(NZ)
+      IF (FZ.GT.0.0E0) GO TO 10
+      IF (NZ.GT.100) GO TO 10
+      GAMLN = GLN(NZ)
+      RETURN
+   10 CONTINUE
+      WDTOL = R1MACH(4)
+      WDTOL = AMAX1(WDTOL,0.5E-18)
+      I1M = I1MACH(11)
+      RLN = R1MACH(5)*FLOAT(I1M)
+      FLN = AMIN1(RLN,20.0E0)
+      FLN = AMAX1(FLN,3.0E0)
+      FLN = FLN - 3.0E0
+      ZM = 1.8000E0 + 0.3875E0*FLN
+      MZ = INT(ZM) + 1
+      ZMIN = FLOAT(MZ)
+      ZDMY = Z
+      ZINC = 0.0E0
+      IF (Z.GE.ZMIN) GO TO 20
+      ZINC = ZMIN - FLOAT(NZ)
+      ZDMY = Z + ZINC
+   20 CONTINUE
+      ZP = 1.0E0/ZDMY
+      T1 = CF(1)*ZP
+      S = T1
+      IF (ZP.LT.WDTOL) GO TO 40
+      ZSQ = ZP*ZP
+      TST = T1*WDTOL
+      DO 30 K=2,22
+        ZP = ZP*ZSQ
+        TRM = CF(K)*ZP
+        IF (ABS(TRM).LT.TST) GO TO 40
+        S = S + TRM
+   30 CONTINUE
+   40 CONTINUE
+      IF (ZINC.NE.0.0E0) GO TO 50
+      TLG = ALOG(Z)
+      GAMLN = Z*(TLG-1.0E0) + 0.5E0*(CON-TLG) + S
+      RETURN
+   50 CONTINUE
+      ZP = 1.0E0
+      NZ = INT(ZINC)
+      DO 60 I=1,NZ
+        ZP = ZP*(Z+FLOAT(I-1))
+   60 CONTINUE
+      TLG = ALOG(ZDMY)
+      GAMLN = ZDMY*(TLG-1.0E0) - ALOG(ZP) + 0.5E0*(CON-TLG) + S
+      RETURN
+C
+C
+   70 CONTINUE
+      IERR=1
+      RETURN
+      END
diff --git a/libcruft/amos/xzabs.f b/libcruft/amos/xzabs.f
new file mode 100644
index 0000000..cb01604
--- /dev/null
+++ b/libcruft/amos/xzabs.f
@@ -0,0 +1,29 @@
+      DOUBLE PRECISION FUNCTION XZABS(ZR, ZI)
+C***BEGIN PROLOGUE  XZABS
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY
+C
+C     XZABS COMPUTES THE ABSOLUTE VALUE OR MAGNITUDE OF A DOUBLE
+C     PRECISION COMPLEX VARIABLE CMPLX(ZR,ZI)
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  XZABS
+      DOUBLE PRECISION ZR, ZI, U, V, Q, S
+      U = DABS(ZR)
+      V = DABS(ZI)
+      S = U + V
+C-----------------------------------------------------------------------
+C     S*1.0D0 MAKES AN UNNORMALIZED UNDERFLOW ON CDC MACHINES INTO A
+C     TRUE FLOATING ZERO
+C-----------------------------------------------------------------------
+      S = S*1.0D+0
+      IF (S.EQ.0.0D+0) GO TO 20
+      IF (U.GT.V) GO TO 10
+      Q = U/V
+      XZABS = V*DSQRT(1.D+0+Q*Q)
+      RETURN
+   10 Q = V/U
+      XZABS = U*DSQRT(1.D+0+Q*Q)
+      RETURN
+   20 XZABS = 0.0D+0
+      RETURN
+      END
diff --git a/libcruft/amos/xzexp.f b/libcruft/amos/xzexp.f
new file mode 100644
index 0000000..3617925
--- /dev/null
+++ b/libcruft/amos/xzexp.f
@@ -0,0 +1,16 @@
+      SUBROUTINE XZEXP(AR, AI, BR, BI)
+C***BEGIN PROLOGUE  XZEXP
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY
+C
+C     DOUBLE PRECISION COMPLEX EXPONENTIAL FUNCTION B=EXP(A)
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  XZEXP
+      DOUBLE PRECISION AR, AI, BR, BI, ZM, CA, CB
+      ZM = DEXP(AR)
+      CA = ZM*DCOS(AI)
+      CB = ZM*DSIN(AI)
+      BR = CA
+      BI = CB
+      RETURN
+      END
diff --git a/libcruft/amos/xzlog.f b/libcruft/amos/xzlog.f
new file mode 100644
index 0000000..c7128b6
--- /dev/null
+++ b/libcruft/amos/xzlog.f
@@ -0,0 +1,41 @@
+      SUBROUTINE XZLOG(AR, AI, BR, BI, IERR)
+C***BEGIN PROLOGUE  XZLOG
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY
+C
+C     DOUBLE PRECISION COMPLEX LOGARITHM B=CLOG(A)
+C     IERR=0,NORMAL RETURN      IERR=1, Z=CMPLX(0.0,0.0)
+C***ROUTINES CALLED  XZABS
+C***END PROLOGUE  XZLOG
+      DOUBLE PRECISION AR, AI, BR, BI, ZM, DTHETA, DPI, DHPI
+      DOUBLE PRECISION XZABS
+      DATA DPI , DHPI  / 3.141592653589793238462643383D+0,
+     1                   1.570796326794896619231321696D+0/
+C
+      IERR=0
+      IF (AR.EQ.0.0D+0) GO TO 10
+      IF (AI.EQ.0.0D+0) GO TO 20
+      DTHETA = DATAN(AI/AR)
+      IF (DTHETA.LE.0.0D+0) GO TO 40
+      IF (AR.LT.0.0D+0) DTHETA = DTHETA - DPI
+      GO TO 50
+   10 IF (AI.EQ.0.0D+0) GO TO 60
+      BI = DHPI
+      BR = DLOG(DABS(AI))
+      IF (AI.LT.0.0D+0) BI = -BI
+      RETURN
+   20 IF (AR.GT.0.0D+0) GO TO 30
+      BR = DLOG(DABS(AR))
+      BI = DPI
+      RETURN
+   30 BR = DLOG(AR)
+      BI = 0.0D+0
+      RETURN
+   40 IF (AR.LT.0.0D+0) DTHETA = DTHETA + DPI
+   50 ZM = XZABS(AR,AI)
+      BR = DLOG(ZM)
+      BI = DTHETA
+      RETURN
+   60 CONTINUE
+      IERR=1
+      RETURN
+      END
diff --git a/libcruft/amos/xzsqrt.f b/libcruft/amos/xzsqrt.f
new file mode 100644
index 0000000..221f195
--- /dev/null
+++ b/libcruft/amos/xzsqrt.f
@@ -0,0 +1,44 @@
+      SUBROUTINE XZSQRT(AR, AI, BR, BI)
+C***BEGIN PROLOGUE  XZSQRT
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY
+C
+C     DOUBLE PRECISION COMPLEX SQUARE ROOT, B=CSQRT(A)
+C
+C***ROUTINES CALLED  XZABS
+C***END PROLOGUE  XZSQRT
+      DOUBLE PRECISION AR, AI, BR, BI, ZM, DTHETA, DPI, DRT
+      DOUBLE PRECISION XZABS
+      DATA DRT , DPI / 7.071067811865475244008443621D-1,
+     1                 3.141592653589793238462643383D+0/
+      ZM = XZABS(AR,AI)
+      ZM = DSQRT(ZM)
+      IF (AR.EQ.0.0D+0) GO TO 10
+      IF (AI.EQ.0.0D+0) GO TO 20
+      DTHETA = DATAN(AI/AR)
+      IF (DTHETA.LE.0.0D+0) GO TO 40
+      IF (AR.LT.0.0D+0) DTHETA = DTHETA - DPI
+      GO TO 50
+   10 IF (AI.GT.0.0D+0) GO TO 60
+      IF (AI.LT.0.0D+0) GO TO 70
+      BR = 0.0D+0
+      BI = 0.0D+0
+      RETURN
+   20 IF (AR.GT.0.0D+0) GO TO 30
+      BR = 0.0D+0
+      BI = DSQRT(DABS(AR))
+      RETURN
+   30 BR = DSQRT(AR)
+      BI = 0.0D+0
+      RETURN
+   40 IF (AR.LT.0.0D+0) DTHETA = DTHETA + DPI
+   50 DTHETA = DTHETA*0.5D+0
+      BR = ZM*DCOS(DTHETA)
+      BI = ZM*DSIN(DTHETA)
+      RETURN
+   60 BR = ZM*DRT
+      BI = ZM*DRT
+      RETURN
+   70 BR = ZM*DRT
+      BI = -ZM*DRT
+      RETURN
+      END
diff --git a/libcruft/amos/zacai.f b/libcruft/amos/zacai.f
new file mode 100644
index 0000000..4fd30e8
--- /dev/null
+++ b/libcruft/amos/zacai.f
@@ -0,0 +1,99 @@
+      SUBROUTINE ZACAI(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL,
+     * ELIM, ALIM)
+C***BEGIN PROLOGUE  ZACAI
+C***REFER TO  ZAIRY
+C
+C     ZACAI APPLIES THE ANALYTIC CONTINUATION FORMULA
+C
+C         K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN)
+C                 MP=PI*MR*CMPLX(0.0,1.0)
+C
+C     TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT
+C     HALF Z PLANE FOR USE WITH ZAIRY WHERE FNU=1/3 OR 2/3 AND N=1.
+C     ZACAI IS THE SAME AS ZACON WITH THE PARTS FOR LARGER ORDERS AND
+C     RECURRENCE REMOVED. A RECURSIVE CALL TO ZACON CAN RESULT IF ZACON
+C     IS CALLED FROM ZAIRY.
+C
+C***ROUTINES CALLED  ZASYI,ZBKNU,ZMLRI,ZSERI,ZS1S2,D1MACH,XZABS
+C***END PROLOGUE  ZACAI
+C     COMPLEX CSGN,CSPN,C1,C2,Y,Z,ZN,CY
+      DOUBLE PRECISION ALIM, ARG, ASCLE, AZ, CSGNR, CSGNI, CSPNR,
+     * CSPNI, C1R, C1I, C2R, C2I, CYR, CYI, DFNU, ELIM, FMR, FNU, PI,
+     * RL, SGN, TOL, YY, YR, YI, ZR, ZI, ZNR, ZNI, D1MACH, XZABS
+      INTEGER INU, IUF, KODE, MR, N, NN, NW, NZ
+      DIMENSION YR(N), YI(N), CYR(2), CYI(2)
+      DATA PI / 3.14159265358979324D0 /
+      NZ = 0
+      ZNR = -ZR
+      ZNI = -ZI
+      AZ = XZABS(ZR,ZI)
+      NN = N
+      DFNU = FNU + DBLE(FLOAT(N-1))
+      IF (AZ.LE.2.0D0) GO TO 10
+      IF (AZ*AZ*0.25D0.GT.DFNU+1.0D0) GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      CALL ZSERI(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL, ELIM, ALIM)
+      GO TO 40
+   20 CONTINUE
+      IF (AZ.LT.RL) GO TO 30
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR LARGE Z FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      CALL ZASYI(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 80
+      GO TO 40
+   30 CONTINUE
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM NORMALIZED BY THE SERIES FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      CALL ZMLRI(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL)
+      IF(NW.LT.0) GO TO 80
+   40 CONTINUE
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION
+C-----------------------------------------------------------------------
+      CALL ZBKNU(ZNR, ZNI, FNU, KODE, 1, CYR, CYI, NW, TOL, ELIM, ALIM)
+      IF (NW.NE.0) GO TO 80
+      FMR = DBLE(FLOAT(MR))
+      SGN = -DSIGN(PI,FMR)
+      CSGNR = 0.0D0
+      CSGNI = SGN
+      IF (KODE.EQ.1) GO TO 50
+      YY = -ZNI
+      CSGNR = -CSGNI*DSIN(YY)
+      CSGNI = CSGNI*DCOS(YY)
+   50 CONTINUE
+C-----------------------------------------------------------------------
+C     CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(SNGL(FNU))
+      ARG = (FNU-DBLE(FLOAT(INU)))*SGN
+      CSPNR = DCOS(ARG)
+      CSPNI = DSIN(ARG)
+      IF (MOD(INU,2).EQ.0) GO TO 60
+      CSPNR = -CSPNR
+      CSPNI = -CSPNI
+   60 CONTINUE
+      C1R = CYR(1)
+      C1I = CYI(1)
+      C2R = YR(1)
+      C2I = YI(1)
+      IF (KODE.EQ.1) GO TO 70
+      IUF = 0
+      ASCLE = 1.0D+3*D1MACH(1)/TOL
+      CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF)
+      NZ = NZ + NW
+   70 CONTINUE
+      YR(1) = CSPNR*C1R - CSPNI*C1I + CSGNR*C2R - CSGNI*C2I
+      YI(1) = CSPNR*C1I + CSPNI*C1R + CSGNR*C2I + CSGNI*C2R
+      RETURN
+   80 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/zacon.f b/libcruft/amos/zacon.f
new file mode 100644
index 0000000..f3c1e3d
--- /dev/null
+++ b/libcruft/amos/zacon.f
@@ -0,0 +1,203 @@
+      SUBROUTINE ZACON(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, FNUL,
+     * TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  ZACON
+C***REFER TO  ZBESK,ZBESH
+C
+C     ZACON APPLIES THE ANALYTIC CONTINUATION FORMULA
+C
+C         K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN)
+C                 MP=PI*MR*CMPLX(0.0,1.0)
+C
+C     TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT
+C     HALF Z PLANE
+C
+C***ROUTINES CALLED  ZBINU,ZBKNU,ZS1S2,D1MACH,XZABS,ZMLT
+C***END PROLOGUE  ZACON
+C     COMPLEX CK,CONE,CSCL,CSCR,CSGN,CSPN,CY,CZERO,C1,C2,RZ,SC1,SC2,ST,
+C    *S1,S2,Y,Z,ZN
+      DOUBLE PRECISION ALIM, ARG, ASCLE, AS2, AZN, BRY, BSCLE, CKI,
+     * CKR, CONER, CPN, CSCL, CSCR, CSGNI, CSGNR, CSPNI, CSPNR,
+     * CSR, CSRR, CSSR, CYI, CYR, C1I, C1M, C1R, C2I, C2R, ELIM, FMR,
+     * FN, FNU, FNUL, PI, PTI, PTR, RAZN, RL, RZI, RZR, SC1I, SC1R,
+     * SC2I, SC2R, SGN, SPN, STI, STR, S1I, S1R, S2I, S2R, TOL, YI, YR,
+     * YY, ZEROR, ZI, ZNI, ZNR, ZR, D1MACH, XZABS
+      INTEGER I, INU, IUF, KFLAG, KODE, MR, N, NN, NW, NZ
+      DIMENSION YR(N), YI(N), CYR(2), CYI(2), CSSR(3), CSRR(3), BRY(3)
+      DATA PI / 3.14159265358979324D0 /
+      DATA ZEROR,CONER / 0.0D0,1.0D0 /
+      NZ = 0
+      ZNR = -ZR
+      ZNI = -ZI
+      NN = N
+      CALL ZBINU(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, FNUL, TOL,
+     * ELIM, ALIM)
+      IF (NW.LT.0) GO TO 90
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION
+C-----------------------------------------------------------------------
+      NN = MIN0(2,N)
+      CALL ZBKNU(ZNR, ZNI, FNU, KODE, NN, CYR, CYI, NW, TOL, ELIM, ALIM)
+      IF (NW.NE.0) GO TO 90
+      S1R = CYR(1)
+      S1I = CYI(1)
+      FMR = DBLE(FLOAT(MR))
+      SGN = -DSIGN(PI,FMR)
+      CSGNR = ZEROR
+      CSGNI = SGN
+      IF (KODE.EQ.1) GO TO 10
+      YY = -ZNI
+      CPN = DCOS(YY)
+      SPN = DSIN(YY)
+      CALL ZMLT(CSGNR, CSGNI, CPN, SPN, CSGNR, CSGNI)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(SNGL(FNU))
+      ARG = (FNU-DBLE(FLOAT(INU)))*SGN
+      CPN = DCOS(ARG)
+      SPN = DSIN(ARG)
+      CSPNR = CPN
+      CSPNI = SPN
+      IF (MOD(INU,2).EQ.0) GO TO 20
+      CSPNR = -CSPNR
+      CSPNI = -CSPNI
+   20 CONTINUE
+      IUF = 0
+      C1R = S1R
+      C1I = S1I
+      C2R = YR(1)
+      C2I = YI(1)
+      ASCLE = 1.0D+3*D1MACH(1)/TOL
+      IF (KODE.EQ.1) GO TO 30
+      CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF)
+      NZ = NZ + NW
+      SC1R = C1R
+      SC1I = C1I
+   30 CONTINUE
+      CALL ZMLT(CSPNR, CSPNI, C1R, C1I, STR, STI)
+      CALL ZMLT(CSGNR, CSGNI, C2R, C2I, PTR, PTI)
+      YR(1) = STR + PTR
+      YI(1) = STI + PTI
+      IF (N.EQ.1) RETURN
+      CSPNR = -CSPNR
+      CSPNI = -CSPNI
+      S2R = CYR(2)
+      S2I = CYI(2)
+      C1R = S2R
+      C1I = S2I
+      C2R = YR(2)
+      C2I = YI(2)
+      IF (KODE.EQ.1) GO TO 40
+      CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF)
+      NZ = NZ + NW
+      SC2R = C1R
+      SC2I = C1I
+   40 CONTINUE
+      CALL ZMLT(CSPNR, CSPNI, C1R, C1I, STR, STI)
+      CALL ZMLT(CSGNR, CSGNI, C2R, C2I, PTR, PTI)
+      YR(2) = STR + PTR
+      YI(2) = STI + PTI
+      IF (N.EQ.2) RETURN
+      CSPNR = -CSPNR
+      CSPNI = -CSPNI
+      AZN = XZABS(ZNR,ZNI)
+      RAZN = 1.0D0/AZN
+      STR = ZNR*RAZN
+      STI = -ZNI*RAZN
+      RZR = (STR+STR)*RAZN
+      RZI = (STI+STI)*RAZN
+      FN = FNU + 1.0D0
+      CKR = FN*RZR
+      CKI = FN*RZI
+C-----------------------------------------------------------------------
+C     SCALE NEAR EXPONENT EXTREMES DURING RECURRENCE ON K FUNCTIONS
+C-----------------------------------------------------------------------
+      CSCL = 1.0D0/TOL
+      CSCR = TOL
+      CSSR(1) = CSCL
+      CSSR(2) = CONER
+      CSSR(3) = CSCR
+      CSRR(1) = CSCR
+      CSRR(2) = CONER
+      CSRR(3) = CSCL
+      BRY(1) = ASCLE
+      BRY(2) = 1.0D0/ASCLE
+      BRY(3) = D1MACH(2)
+      AS2 = XZABS(S2R,S2I)
+      KFLAG = 2
+      IF (AS2.GT.BRY(1)) GO TO 50
+      KFLAG = 1
+      GO TO 60
+   50 CONTINUE
+      IF (AS2.LT.BRY(2)) GO TO 60
+      KFLAG = 3
+   60 CONTINUE
+      BSCLE = BRY(KFLAG)
+      S1R = S1R*CSSR(KFLAG)
+      S1I = S1I*CSSR(KFLAG)
+      S2R = S2R*CSSR(KFLAG)
+      S2I = S2I*CSSR(KFLAG)
+      CSR = CSRR(KFLAG)
+      DO 80 I=3,N
+        STR = S2R
+        STI = S2I
+        S2R = CKR*STR - CKI*STI + S1R
+        S2I = CKR*STI + CKI*STR + S1I
+        S1R = STR
+        S1I = STI
+        C1R = S2R*CSR
+        C1I = S2I*CSR
+        STR = C1R
+        STI = C1I
+        C2R = YR(I)
+        C2I = YI(I)
+        IF (KODE.EQ.1) GO TO 70
+        IF (IUF.LT.0) GO TO 70
+        CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF)
+        NZ = NZ + NW
+        SC1R = SC2R
+        SC1I = SC2I
+        SC2R = C1R
+        SC2I = C1I
+        IF (IUF.NE.3) GO TO 70
+        IUF = -4
+        S1R = SC1R*CSSR(KFLAG)
+        S1I = SC1I*CSSR(KFLAG)
+        S2R = SC2R*CSSR(KFLAG)
+        S2I = SC2I*CSSR(KFLAG)
+        STR = SC2R
+        STI = SC2I
+   70   CONTINUE
+        PTR = CSPNR*C1R - CSPNI*C1I
+        PTI = CSPNR*C1I + CSPNI*C1R
+        YR(I) = PTR + CSGNR*C2R - CSGNI*C2I
+        YI(I) = PTI + CSGNR*C2I + CSGNI*C2R
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        CSPNR = -CSPNR
+        CSPNI = -CSPNI
+        IF (KFLAG.GE.3) GO TO 80
+        PTR = DABS(C1R)
+        PTI = DABS(C1I)
+        C1M = DMAX1(PTR,PTI)
+        IF (C1M.LE.BSCLE) GO TO 80
+        KFLAG = KFLAG + 1
+        BSCLE = BRY(KFLAG)
+        S1R = S1R*CSR
+        S1I = S1I*CSR
+        S2R = STR
+        S2I = STI
+        S1R = S1R*CSSR(KFLAG)
+        S1I = S1I*CSSR(KFLAG)
+        S2R = S2R*CSSR(KFLAG)
+        S2I = S2I*CSSR(KFLAG)
+        CSR = CSRR(KFLAG)
+   80 CONTINUE
+      RETURN
+   90 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/zairy.f b/libcruft/amos/zairy.f
new file mode 100644
index 0000000..70f7485
--- /dev/null
+++ b/libcruft/amos/zairy.f
@@ -0,0 +1,393 @@
+      SUBROUTINE ZAIRY(ZR, ZI, ID, KODE, AIR, AII, NZ, IERR)
+C***BEGIN PROLOGUE  ZAIRY
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z
+C***DESCRIPTION
+C
+C                      ***A DOUBLE PRECISION ROUTINE***
+C         ON KODE=1, ZAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR
+C         ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON
+C         KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)*
+C         DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN
+C         -PI/3.LT.ARG(Z).LT.PI/3 AND THE EXPONENTIAL GROWTH IN
+C         PI/3.LT.ABS(ARG(Z)).LT.PI WHERE ZTA=(2/3)*Z*CSQRT(Z).
+C
+C         WHILE THE AIRY FUNCTIONS AI(Z) AND DAI(Z)/DZ ARE ANALYTIC IN
+C         THE WHOLE Z PLANE, THE CORRESPONDING SCALED FUNCTIONS DEFINED
+C         FOR KODE=2 HAVE A CUT ALONG THE NEGATIVE REAL AXIS.
+C         DEFINTIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF
+C         MATHEMATICAL FUNCTIONS (REF. 1).
+C
+C         INPUT      ZR,ZI ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI)
+C           ID     - ORDER OF DERIVATIVE, ID=0 OR ID=1
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             AI=AI(Z)                ON ID=0 OR
+C                             AI=DAI(Z)/DZ            ON ID=1
+C                        = 2  RETURNS
+C                             AI=CEXP(ZTA)*AI(Z)       ON ID=0 OR
+C                             AI=CEXP(ZTA)*DAI(Z)/DZ   ON ID=1 WHERE
+C                             ZTA=(2/3)*Z*CSQRT(Z)
+C
+C         OUTPUT     AIR,AII ARE DOUBLE PRECISION
+C           AIR,AII- COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND
+C                    KODE
+C           NZ     - UNDERFLOW INDICATOR
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ= 1   , AI=CMPLX(0.0D0,0.0D0) DUE TO UNDERFLOW IN
+C                              -PI/3.LT.ARG(Z).LT.PI/3 ON KODE=1
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, REAL(ZTA)
+C                            TOO LARGE ON KODE=1
+C                    IERR=3, CABS(Z) LARGE      - COMPUTATION COMPLETED
+C                            LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION
+C                            PRODUCE LESS THAN HALF OF MACHINE ACCURACY
+C                    IERR=4, CABS(Z) TOO LARGE  - NO COMPUTATION
+C                            COMPLETE LOSS OF ACCURACY BY ARGUMENT
+C                            REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         AI AND DAI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE K BESSEL
+C         FUNCTIONS BY
+C
+C            AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA)
+C                           C=1.0/(PI*SQRT(3.0))
+C                            ZTA=(2/3)*Z**(3/2)
+C
+C         WITH THE POWER SERIES FOR CABS(Z).LE.1.0.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES
+C         OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF
+C         THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR),
+C         THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR
+C         FLAG IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN
+C         ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT
+C         FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE
+C         LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA
+C         MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2,
+C         AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE
+C         PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE
+C         PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT-
+C         ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG-
+C         NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN
+C         DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN
+C         EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES,
+C         NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE
+C         PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER
+C         MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZACAI,ZBKNU,XZEXP,XZSQRT,I1MACH,D1MACH
+C***END PROLOGUE  ZAIRY
+C     COMPLEX AI,CONE,CSQ,CY,S1,S2,TRM1,TRM2,Z,ZTA,Z3
+      DOUBLE PRECISION AA, AD, AII, AIR, AK, ALIM, ATRM, AZ, AZ3, BK,
+     * CC, CK, COEF, CONEI, CONER, CSQI, CSQR, CYI, CYR, C1, C2, DIG,
+     * DK, D1, D2, ELIM, FID, FNU, PTR, RL, R1M5, SFAC, STI, STR,
+     * S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I, TRM2R, TTH, ZEROI,
+     * ZEROR, ZI, ZR, ZTAI, ZTAR, Z3I, Z3R, D1MACH, XZABS, ALAZ, BB
+      INTEGER ID, IERR, IFLAG, K, KODE, K1, K2, MR, NN, NZ, I1MACH
+      DIMENSION CYR(1), CYI(1)
+      DATA TTH, C1, C2, COEF /6.66666666666666667D-01,
+     * 3.55028053887817240D-01,2.58819403792806799D-01,
+     * 1.83776298473930683D-01/
+      DATA ZEROR, ZEROI, CONER, CONEI /0.0D0,0.0D0,1.0D0,0.0D0/
+C***FIRST EXECUTABLE STATEMENT  ZAIRY
+      IERR = 0
+      NZ=0
+      IF (ID.LT.0 .OR. ID.GT.1) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (IERR.NE.0) RETURN
+      AZ = XZABS(ZR,ZI)
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      FID = DBLE(FLOAT(ID))
+      IF (AZ.GT.1.0D0) GO TO 70
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR CABS(Z).LE.1.
+C-----------------------------------------------------------------------
+      S1R = CONER
+      S1I = CONEI
+      S2R = CONER
+      S2I = CONEI
+      IF (AZ.LT.TOL) GO TO 170
+      AA = AZ*AZ
+      IF (AA.LT.TOL/AZ) GO TO 40
+      TRM1R = CONER
+      TRM1I = CONEI
+      TRM2R = CONER
+      TRM2I = CONEI
+      ATRM = 1.0D0
+      STR = ZR*ZR - ZI*ZI
+      STI = ZR*ZI + ZI*ZR
+      Z3R = STR*ZR - STI*ZI
+      Z3I = STR*ZI + STI*ZR
+      AZ3 = AZ*AA
+      AK = 2.0D0 + FID
+      BK = 3.0D0 - FID - FID
+      CK = 4.0D0 - FID
+      DK = 3.0D0 + FID + FID
+      D1 = AK*DK
+      D2 = BK*CK
+      AD = DMIN1(D1,D2)
+      AK = 24.0D0 + 9.0D0*FID
+      BK = 30.0D0 - 9.0D0*FID
+      DO 30 K=1,25
+        STR = (TRM1R*Z3R-TRM1I*Z3I)/D1
+        TRM1I = (TRM1R*Z3I+TRM1I*Z3R)/D1
+        TRM1R = STR
+        S1R = S1R + TRM1R
+        S1I = S1I + TRM1I
+        STR = (TRM2R*Z3R-TRM2I*Z3I)/D2
+        TRM2I = (TRM2R*Z3I+TRM2I*Z3R)/D2
+        TRM2R = STR
+        S2R = S2R + TRM2R
+        S2I = S2I + TRM2I
+        ATRM = ATRM*AZ3/AD
+        D1 = D1 + AK
+        D2 = D2 + BK
+        AD = DMIN1(D1,D2)
+        IF (ATRM.LT.TOL*AD) GO TO 40
+        AK = AK + 18.0D0
+        BK = BK + 18.0D0
+   30 CONTINUE
+   40 CONTINUE
+      IF (ID.EQ.1) GO TO 50
+      AIR = S1R*C1 - C2*(ZR*S2R-ZI*S2I)
+      AII = S1I*C1 - C2*(ZR*S2I+ZI*S2R)
+      IF (KODE.EQ.1) RETURN
+      CALL XZSQRT(ZR, ZI, STR, STI)
+      ZTAR = TTH*(ZR*STR-ZI*STI)
+      ZTAI = TTH*(ZR*STI+ZI*STR)
+      CALL XZEXP(ZTAR, ZTAI, STR, STI)
+      PTR = AIR*STR - AII*STI
+      AII = AIR*STI + AII*STR
+      AIR = PTR
+      RETURN
+   50 CONTINUE
+      AIR = -S2R*C2
+      AII = -S2I*C2
+      IF (AZ.LE.TOL) GO TO 60
+      STR = ZR*S1R - ZI*S1I
+      STI = ZR*S1I + ZI*S1R
+      CC = C1/(1.0D0+FID)
+      AIR = AIR + CC*(STR*ZR-STI*ZI)
+      AII = AII + CC*(STR*ZI+STI*ZR)
+   60 CONTINUE
+      IF (KODE.EQ.1) RETURN
+      CALL XZSQRT(ZR, ZI, STR, STI)
+      ZTAR = TTH*(ZR*STR-ZI*STI)
+      ZTAI = TTH*(ZR*STI+ZI*STR)
+      CALL XZEXP(ZTAR, ZTAI, STR, STI)
+      PTR = STR*AIR - STI*AII
+      AII = STR*AII + STI*AIR
+      AIR = PTR
+      RETURN
+C-----------------------------------------------------------------------
+C     CASE FOR CABS(Z).GT.1.0
+C-----------------------------------------------------------------------
+   70 CONTINUE
+      FNU = (1.0D0+FID)/3.0D0
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0D-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C-----------------------------------------------------------------------
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      R1M5 = D1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      K1 = I1MACH(14) - 1
+      AA = R1M5*DBLE(FLOAT(K1))
+      DIG = DMIN1(AA,18.0D0)
+      AA = AA*2.303D0
+      ALIM = ELIM + DMAX1(-AA,-41.45D0)
+      RL = 1.2D0*DIG + 3.0D0
+      ALAZ = DLOG(AZ)
+C--------------------------------------------------------------------------
+C     TEST FOR PROPER RANGE
+C-----------------------------------------------------------------------
+      AA=0.5D0/TOL
+      BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
+      AA=DMIN1(AA,BB)
+      AA=AA**TTH
+      IF (AZ.GT.AA) GO TO 260
+      AA=DSQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      CALL XZSQRT(ZR, ZI, CSQR, CSQI)
+      ZTAR = TTH*(ZR*CSQR-ZI*CSQI)
+      ZTAI = TTH*(ZR*CSQI+ZI*CSQR)
+C-----------------------------------------------------------------------
+C     RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL
+C-----------------------------------------------------------------------
+      IFLAG = 0
+      SFAC = 1.0D0
+      AK = ZTAI
+      IF (ZR.GE.0.0D0) GO TO 80
+      BK = ZTAR
+      CK = -DABS(BK)
+      ZTAR = CK
+      ZTAI = AK
+   80 CONTINUE
+      IF (ZI.NE.0.0D0) GO TO 90
+      IF (ZR.GT.0.0D0) GO TO 90
+      ZTAR = 0.0D0
+      ZTAI = AK
+   90 CONTINUE
+      AA = ZTAR
+      IF (AA.GE.0.0D0 .AND. ZR.GT.0.0D0) GO TO 110
+      IF (KODE.EQ.2) GO TO 100
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (AA.GT.(-ALIM)) GO TO 100
+      AA = -AA + 0.25D0*ALAZ
+      IFLAG = 1
+      SFAC = TOL
+      IF (AA.GT.ELIM) GO TO 270
+  100 CONTINUE
+C-----------------------------------------------------------------------
+C     CBKNU AND CACON RETURN EXP(ZTA)*K(FNU,ZTA) ON KODE=2
+C-----------------------------------------------------------------------
+      MR = 1
+      IF (ZI.LT.0.0D0) MR = -1
+      CALL ZACAI(ZTAR, ZTAI, FNU, KODE, MR, 1, CYR, CYI, NN, RL, TOL,
+     * ELIM, ALIM)
+      IF (NN.LT.0) GO TO 280
+      NZ = NZ + NN
+      GO TO 130
+  110 CONTINUE
+      IF (KODE.EQ.2) GO TO 120
+C-----------------------------------------------------------------------
+C     UNDERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (AA.LT.ALIM) GO TO 120
+      AA = -AA - 0.25D0*ALAZ
+      IFLAG = 2
+      SFAC = 1.0D0/TOL
+      IF (AA.LT.(-ELIM)) GO TO 210
+  120 CONTINUE
+      CALL ZBKNU(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, TOL, ELIM,
+     * ALIM)
+  130 CONTINUE
+      S1R = CYR(1)*COEF
+      S1I = CYI(1)*COEF
+      IF (IFLAG.NE.0) GO TO 150
+      IF (ID.EQ.1) GO TO 140
+      AIR = CSQR*S1R - CSQI*S1I
+      AII = CSQR*S1I + CSQI*S1R
+      RETURN
+  140 CONTINUE
+      AIR = -(ZR*S1R-ZI*S1I)
+      AII = -(ZR*S1I+ZI*S1R)
+      RETURN
+  150 CONTINUE
+      S1R = S1R*SFAC
+      S1I = S1I*SFAC
+      IF (ID.EQ.1) GO TO 160
+      STR = S1R*CSQR - S1I*CSQI
+      S1I = S1R*CSQI + S1I*CSQR
+      S1R = STR
+      AIR = S1R/SFAC
+      AII = S1I/SFAC
+      RETURN
+  160 CONTINUE
+      STR = -(S1R*ZR-S1I*ZI)
+      S1I = -(S1R*ZI+S1I*ZR)
+      S1R = STR
+      AIR = S1R/SFAC
+      AII = S1I/SFAC
+      RETURN
+  170 CONTINUE
+      AA = 1.0D+3*D1MACH(1)
+      S1R = ZEROR
+      S1I = ZEROI
+      IF (ID.EQ.1) GO TO 190
+      IF (AZ.LE.AA) GO TO 180
+      S1R = C2*ZR
+      S1I = C2*ZI
+  180 CONTINUE
+      AIR = C1 - S1R
+      AII = -S1I
+      RETURN
+  190 CONTINUE
+      AIR = -C2
+      AII = 0.0D0
+      AA = DSQRT(AA)
+      IF (AZ.LE.AA) GO TO 200
+      S1R = 0.5D0*(ZR*ZR-ZI*ZI)
+      S1I = ZR*ZI
+  200 CONTINUE
+      AIR = AIR + C1*S1R
+      AII = AII + C1*S1I
+      RETURN
+  210 CONTINUE
+      NZ = 1
+      AIR = ZEROR
+      AII = ZEROI
+      RETURN
+  270 CONTINUE
+      NZ = 0
+      IERR=2
+      RETURN
+  280 CONTINUE
+      IF(NN.EQ.(-1)) GO TO 270
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      IERR=4
+      NZ=0
+      RETURN
+      END
diff --git a/libcruft/amos/zasyi.f b/libcruft/amos/zasyi.f
new file mode 100644
index 0000000..ad87546
--- /dev/null
+++ b/libcruft/amos/zasyi.f
@@ -0,0 +1,165 @@
+      SUBROUTINE ZASYI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  ZASYI
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZASYI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
+C     MEANS OF THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z) IN THE
+C     REGION CABS(Z).GT.MAX(RL,FNU*FNU/2). NZ=0 IS A NORMAL RETURN.
+C     NZ.LT.0 INDICATES AN OVERFLOW ON KODE=1.
+C
+C***ROUTINES CALLED  D1MACH,XZABS,ZDIV,XZEXP,ZMLT,XZSQRT
+C***END PROLOGUE  ZASYI
+C     COMPLEX AK1,CK,CONE,CS1,CS2,CZ,CZERO,DK,EZ,P1,RZ,S2,Y,Z
+      DOUBLE PRECISION AA, AEZ, AK, AK1I, AK1R, ALIM, ARG, ARM, ATOL,
+     * AZ, BB, BK, CKI, CKR, CONEI, CONER, CS1I, CS1R, CS2I, CS2R, CZI,
+     * CZR, DFNU, DKI, DKR, DNU2, ELIM, EZI, EZR, FDN, FNU, PI, P1I,
+     * P1R, RAZ, RL, RTPI, RTR1, RZI, RZR, S, SGN, SQK, STI, STR, S2I,
+     * S2R, TOL, TZI, TZR, YI, YR, ZEROI, ZEROR, ZI, ZR, D1MACH, XZABS
+      INTEGER I, IB, IL, INU, J, JL, K, KODE, KODED, M, N, NN, NZ
+      DIMENSION YR(N), YI(N)
+      DATA PI, RTPI  /3.14159265358979324D0 , 0.159154943091895336D0 /
+      DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
+C
+      NZ = 0
+      AZ = XZABS(ZR,ZI)
+      ARM = 1.0D+3*D1MACH(1)
+      RTR1 = DSQRT(ARM)
+      IL = MIN0(2,N)
+      DFNU = FNU + DBLE(FLOAT(N-IL))
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      RAZ = 1.0D0/AZ
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      AK1R = RTPI*STR*RAZ
+      AK1I = RTPI*STI*RAZ
+      CALL XZSQRT(AK1R, AK1I, AK1R, AK1I)
+      CZR = ZR
+      CZI = ZI
+      IF (KODE.NE.2) GO TO 10
+      CZR = ZEROR
+      CZI = ZI
+   10 CONTINUE
+      IF (DABS(CZR).GT.ELIM) GO TO 100
+      DNU2 = DFNU + DFNU
+      KODED = 1
+      IF ((DABS(CZR).GT.ALIM) .AND. (N.GT.2)) GO TO 20
+      KODED = 0
+      CALL XZEXP(CZR, CZI, STR, STI)
+      CALL ZMLT(AK1R, AK1I, STR, STI, AK1R, AK1I)
+   20 CONTINUE
+      FDN = 0.0D0
+      IF (DNU2.GT.RTR1) FDN = DNU2*DNU2
+      EZR = ZR*8.0D0
+      EZI = ZI*8.0D0
+C-----------------------------------------------------------------------
+C     WHEN Z IS IMAGINARY, THE ERROR TEST MUST BE MADE RELATIVE TO THE
+C     FIRST RECIPROCAL POWER SINCE THIS IS THE LEADING TERM OF THE
+C     EXPANSION FOR THE IMAGINARY PART.
+C-----------------------------------------------------------------------
+      AEZ = 8.0D0*AZ
+      S = TOL/AEZ
+      JL = INT(SNGL(RL+RL)) + 2
+      P1R = ZEROR
+      P1I = ZEROI
+      IF (ZI.EQ.0.0D0) GO TO 30
+C-----------------------------------------------------------------------
+C     CALCULATE EXP(PI*(0.5+FNU+N-IL)*I) TO MINIMIZE LOSSES OF
+C     SIGNIFICANCE WHEN FNU OR N IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(SNGL(FNU))
+      ARG = (FNU-DBLE(FLOAT(INU)))*PI
+      INU = INU + N - IL
+      AK = -DSIN(ARG)
+      BK = DCOS(ARG)
+      IF (ZI.LT.0.0D0) BK = -BK
+      P1R = AK
+      P1I = BK
+      IF (MOD(INU,2).EQ.0) GO TO 30
+      P1R = -P1R
+      P1I = -P1I
+   30 CONTINUE
+      DO 70 K=1,IL
+        SQK = FDN - 1.0D0
+        ATOL = S*DABS(SQK)
+        SGN = 1.0D0
+        CS1R = CONER
+        CS1I = CONEI
+        CS2R = CONER
+        CS2I = CONEI
+        CKR = CONER
+        CKI = CONEI
+        AK = 0.0D0
+        AA = 1.0D0
+        BB = AEZ
+        DKR = EZR
+        DKI = EZI
+        DO 40 J=1,JL
+          CALL ZDIV(CKR, CKI, DKR, DKI, STR, STI)
+          CKR = STR*SQK
+          CKI = STI*SQK
+          CS2R = CS2R + CKR
+          CS2I = CS2I + CKI
+          SGN = -SGN
+          CS1R = CS1R + CKR*SGN
+          CS1I = CS1I + CKI*SGN
+          DKR = DKR + EZR
+          DKI = DKI + EZI
+          AA = AA*DABS(SQK)/BB
+          BB = BB + AEZ
+          AK = AK + 8.0D0
+          SQK = SQK - AK
+          IF (AA.LE.ATOL) GO TO 50
+   40   CONTINUE
+        GO TO 110
+   50   CONTINUE
+        S2R = CS1R
+        S2I = CS1I
+        IF (ZR+ZR.GE.ELIM) GO TO 60
+        TZR = ZR + ZR
+        TZI = ZI + ZI
+        CALL XZEXP(-TZR, -TZI, STR, STI)
+        CALL ZMLT(STR, STI, P1R, P1I, STR, STI)
+        CALL ZMLT(STR, STI, CS2R, CS2I, STR, STI)
+        S2R = S2R + STR
+        S2I = S2I + STI
+   60   CONTINUE
+        FDN = FDN + 8.0D0*DFNU + 4.0D0
+        P1R = -P1R
+        P1I = -P1I
+        M = N - IL + K
+        YR(M) = S2R*AK1R - S2I*AK1I
+        YI(M) = S2R*AK1I + S2I*AK1R
+   70 CONTINUE
+      IF (N.LE.2) RETURN
+      NN = N
+      K = NN - 2
+      AK = DBLE(FLOAT(K))
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      RZR = (STR+STR)*RAZ
+      RZI = (STI+STI)*RAZ
+      IB = 3
+      DO 80 I=IB,NN
+        YR(K) = (AK+FNU)*(RZR*YR(K+1)-RZI*YI(K+1)) + YR(K+2)
+        YI(K) = (AK+FNU)*(RZR*YI(K+1)+RZI*YR(K+1)) + YI(K+2)
+        AK = AK - 1.0D0
+        K = K - 1
+   80 CONTINUE
+      IF (KODED.EQ.0) RETURN
+      CALL XZEXP(CZR, CZI, CKR, CKI)
+      DO 90 I=1,NN
+        STR = YR(I)*CKR - YI(I)*CKI
+        YI(I) = YR(I)*CKI + YI(I)*CKR
+        YR(I) = STR
+   90 CONTINUE
+      RETURN
+  100 CONTINUE
+      NZ = -1
+      RETURN
+  110 CONTINUE
+      NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/zbesh.f b/libcruft/amos/zbesh.f
new file mode 100644
index 0000000..273f30a
--- /dev/null
+++ b/libcruft/amos/zbesh.f
@@ -0,0 +1,348 @@
+      SUBROUTINE ZBESH(ZR, ZI, FNU, KODE, M, N, CYR, CYI, NZ, IERR)
+C***BEGIN PROLOGUE  ZBESH
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  H-BESSEL FUNCTIONS,BESSEL FUNCTIONS OF COMPLEX ARGUMENT,
+C             BESSEL FUNCTIONS OF THIRD KIND,HANKEL FUNCTIONS
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE H-BESSEL FUNCTIONS OF A COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C                      ***A DOUBLE PRECISION ROUTINE***
+C         ON KODE=1, ZBESH COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         HANKEL (BESSEL) FUNCTIONS CY(J)=H(M,FNU+J-1,Z) FOR KINDS M=1
+C         OR 2, REAL, NONNEGATIVE ORDERS FNU+J-1, J=1,...,N, AND COMPLEX
+C         Z.NE.CMPLX(0.0,0.0) IN THE CUT PLANE -PI.LT.ARG(Z).LE.PI.
+C         ON KODE=2, ZBESH RETURNS THE SCALED HANKEL FUNCTIONS
+C
+C         CY(I)=EXP(-MM*Z*I)*H(M,FNU+J-1,Z)       MM=3-2*M,   I**2=-1.
+C
+C         WHICH REMOVES THE EXPONENTIAL BEHAVIOR IN BOTH THE UPPER AND
+C         LOWER HALF PLANES. DEFINITIONS AND NOTATION ARE FOUND IN THE
+C         NBS HANDBOOK OF MATHEMATICAL FUNCTIONS (REF. 1).
+C
+C         INPUT      ZR,ZI,FNU ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI), Z.NE.CMPLX(0.0D0,0.0D0),
+C                    -PT.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL H FUNCTION, FNU.GE.0.0D0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(J)=H(M,FNU+J-1,Z),   J=1,...,N
+C                        = 2  RETURNS
+C                             CY(J)=H(M,FNU+J-1,Z)*EXP(-I*Z*(3-2M))
+C                                  J=1,...,N  ,  I**2=-1
+C           M      - KIND OF HANKEL FUNCTION, M=1 OR 2
+C           N      - NUMBER OF MEMBERS IN THE SEQUENCE, N.GE.1
+C
+C         OUTPUT     CYR,CYI ARE DOUBLE PRECISION
+C           CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS
+C                    CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE
+C                    CY(J)=H(M,FNU+J-1,Z)  OR
+C                    CY(J)=H(M,FNU+J-1,Z)*EXP(-I*Z*(3-2M))  J=1,...,N
+C                    DEPENDING ON KODE, I**2=-1.
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , FIRST NZ COMPONENTS OF CY SET TO ZERO DUE
+C                              TO UNDERFLOW, CY(J)=CMPLX(0.0D0,0.0D0)
+C                              J=1,...,NZ WHEN Y.GT.0.0 AND M=1 OR
+C                              Y.LT.0.0 AND M=2. FOR THE COMPLMENTARY
+C                              HALF PLANES, NZ STATES ONLY THE NUMBER
+C                              OF UNDERFLOWS.
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, FNU TOO
+C                            LARGE OR CABS(Z) TOO SMALL OR BOTH
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE RELATION
+C
+C         H(M,FNU,Z)=(1/MP)*EXP(-MP*FNU)*K(FNU,Z*EXP(-MP))
+C             MP=MM*HPI*I,  MM=3-2*M,  HPI=PI/2,  I**2=-1
+C
+C         FOR M=1 OR 2 WHERE THE K BESSEL FUNCTION IS COMPUTED FOR THE
+C         RIGHT HALF PLANE RE(Z).GE.0.0. THE K FUNCTION IS CONTINUED
+C         TO THE LEFT HALF PLANE BY THE RELATION
+C
+C         K(FNU,Z*EXP(MP)) = EXP(-MP*FNU)*K(FNU,Z)-MP*I(FNU,Z)
+C         MP=MR*PI*I, MR=+1 OR -1, RE(Z).GT.0, I**2=-1
+C
+C         WHERE I(FNU,Z) IS THE I BESSEL FUNCTION.
+C
+C         EXPONENTIAL DECAY OF H(M,FNU,Z) OCCURS IN THE UPPER HALF Z
+C         PLANE FOR M=1 AND THE LOWER HALF Z PLANE FOR M=2.  EXPONENTIAL
+C         GROWTH OCCURS IN THE COMPLEMENTARY HALF PLANES.  SCALING
+C         BY EXP(-MM*Z*I) REMOVES THE EXPONENTIAL BEHAVIOR IN THE
+C         WHOLE Z PLANE FOR Z TO INFINITY.
+C
+C         FOR NEGATIVE ORDERS,THE FORMULAE
+C
+C               H(1,-FNU,Z) = H(1,FNU,Z)*CEXP( PI*FNU*I)
+C               H(2,-FNU,Z) = H(2,FNU,Z)*CEXP(-PI*FNU*I)
+C                         I**2=-1
+C
+C         CAN BE USED.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0D-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZACON,ZBKNU,ZBUNK,ZUOIK,XZABS,I1MACH,D1MACH
+C***END PROLOGUE  ZBESH
+C
+C     COMPLEX CY,Z,ZN,ZT,CSGN
+      DOUBLE PRECISION AA, ALIM, ALN, ARG, AZ, CYI, CYR, DIG, ELIM,
+     * FMM, FN, FNU, FNUL, HPI, RHPI, RL, R1M5, SGN, STR, TOL, UFL, ZI,
+     * ZNI, ZNR, ZR, ZTI, D1MACH, XZABS, BB, ASCLE, RTOL, ATOL, STI,
+     * CSGNR, CSGNI
+      INTEGER I, IERR, INU, INUH, IR, K, KODE, K1, K2, M,
+     * MM, MR, N, NN, NUF, NW, NZ, I1MACH
+      DIMENSION CYR(N), CYI(N)
+C
+      DATA HPI /1.57079632679489662D0/
+C
+C***FIRST EXECUTABLE STATEMENT  ZBESH
+      IERR = 0
+      NZ=0
+      IF (ZR.EQ.0.0D0 .AND. ZI.EQ.0.0D0) IERR=1
+      IF (FNU.LT.0.0D0) IERR=1
+      IF (M.LT.1 .OR. M.GT.2) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      NN = N
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU
+C-----------------------------------------------------------------------
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      R1M5 = D1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      K1 = I1MACH(14) - 1
+      AA = R1M5*DBLE(FLOAT(K1))
+      DIG = DMIN1(AA,18.0D0)
+      AA = AA*2.303D0
+      ALIM = ELIM + DMAX1(-AA,-41.45D0)
+      FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0)
+      RL = 1.2D0*DIG + 3.0D0
+      FN = FNU + DBLE(FLOAT(NN-1))
+      MM = 3 - M - M
+      FMM = DBLE(FLOAT(MM))
+      ZNR = FMM*ZI
+      ZNI = -FMM*ZR
+C-----------------------------------------------------------------------
+C     TEST FOR PROPER RANGE
+C-----------------------------------------------------------------------
+      AZ = XZABS(ZR,ZI)
+      AA = 0.5D0/TOL
+      BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
+      AA = DMIN1(AA,BB)
+      IF (AZ.GT.AA) GO TO 260
+      IF (FN.GT.AA) GO TO 260
+      AA = DSQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      IF (FN.GT.AA) IERR=3
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST ON THE LAST MEMBER OF THE SEQUENCE
+C-----------------------------------------------------------------------
+      UFL = D1MACH(1)*1.0D+3
+      IF (AZ.LT.UFL) GO TO 230
+      IF (FNU.GT.FNUL) GO TO 90
+      IF (FN.LE.1.0D0) GO TO 70
+      IF (FN.GT.2.0D0) GO TO 60
+      IF (AZ.GT.TOL) GO TO 70
+      ARG = 0.5D0*AZ
+      ALN = -FN*DLOG(ARG)
+      IF (ALN.GT.ELIM) GO TO 230
+      GO TO 70
+   60 CONTINUE
+      CALL ZUOIK(ZNR, ZNI, FNU, KODE, 2, NN, CYR, CYI, NUF, TOL, ELIM,
+     * ALIM)
+      IF (NUF.LT.0) GO TO 230
+      NZ = NZ + NUF
+      NN = NN - NUF
+C-----------------------------------------------------------------------
+C     HERE NN=N OR NN=0 SINCE NUF=0,NN, OR -1 ON RETURN FROM CUOIK
+C     IF NUF=NN, THEN CY(I)=CZERO FOR ALL I
+C-----------------------------------------------------------------------
+      IF (NN.EQ.0) GO TO 140
+   70 CONTINUE
+      IF ((ZNR.LT.0.0D0) .OR. (ZNR.EQ.0.0D0 .AND. ZNI.LT.0.0D0 .AND.
+     * M.EQ.2)) GO TO 80
+C-----------------------------------------------------------------------
+C     RIGHT HALF PLANE COMPUTATION, XN.GE.0. .AND. (XN.NE.0. .OR.
+C     YN.GE.0. .OR. M=1)
+C-----------------------------------------------------------------------
+      CALL ZBKNU(ZNR, ZNI, FNU, KODE, NN, CYR, CYI, NZ, TOL, ELIM, ALIM)
+      GO TO 110
+C-----------------------------------------------------------------------
+C     LEFT HALF PLANE COMPUTATION
+C-----------------------------------------------------------------------
+   80 CONTINUE
+      MR = -MM
+      CALL ZACON(ZNR, ZNI, FNU, KODE, MR, NN, CYR, CYI, NW, RL, FNUL,
+     * TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 240
+      NZ=NW
+      GO TO 110
+   90 CONTINUE
+C-----------------------------------------------------------------------
+C     UNIFORM ASYMPTOTIC EXPANSIONS FOR FNU.GT.FNUL
+C-----------------------------------------------------------------------
+      MR = 0
+      IF ((ZNR.GE.0.0D0) .AND. (ZNR.NE.0.0D0 .OR. ZNI.GE.0.0D0 .OR.
+     * M.NE.2)) GO TO 100
+      MR = -MM
+      IF (ZNR.NE.0.0D0 .OR. ZNI.GE.0.0D0) GO TO 100
+      ZNR = -ZNR
+      ZNI = -ZNI
+  100 CONTINUE
+      CALL ZBUNK(ZNR, ZNI, FNU, KODE, MR, NN, CYR, CYI, NW, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 240
+      NZ = NZ + NW
+  110 CONTINUE
+C-----------------------------------------------------------------------
+C     H(M,FNU,Z) = -FMM*(I/HPI)*(ZT**FNU)*K(FNU,-Z*ZT)
+C
+C     ZT=EXP(-FMM*HPI*I) = CMPLX(0.0,-FMM), FMM=3-2*M, M=1,2
+C-----------------------------------------------------------------------
+      SGN = DSIGN(HPI,-FMM)
+C-----------------------------------------------------------------------
+C     CALCULATE EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(SNGL(FNU))
+      INUH = INU/2
+      IR = INU - 2*INUH
+      ARG = (FNU-DBLE(FLOAT(INU-IR)))*SGN
+      RHPI = 1.0D0/SGN
+C     ZNI = RHPI*DCOS(ARG)
+C     ZNR = -RHPI*DSIN(ARG)
+      CSGNI = RHPI*DCOS(ARG)
+      CSGNR = -RHPI*DSIN(ARG)
+      IF (MOD(INUH,2).EQ.0) GO TO 120
+C     ZNR = -ZNR
+C     ZNI = -ZNI
+      CSGNR = -CSGNR
+      CSGNI = -CSGNI
+  120 CONTINUE
+      ZTI = -FMM
+      RTOL = 1.0D0/TOL
+      ASCLE = UFL*RTOL
+      DO 130 I=1,NN
+C       STR = CYR(I)*ZNR - CYI(I)*ZNI
+C       CYI(I) = CYR(I)*ZNI + CYI(I)*ZNR
+C       CYR(I) = STR
+C       STR = -ZNI*ZTI
+C       ZNI = ZNR*ZTI
+C       ZNR = STR
+        AA = CYR(I)
+        BB = CYI(I)
+        ATOL = 1.0D0
+        IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 135
+          AA = AA*RTOL
+          BB = BB*RTOL
+          ATOL = TOL
+  135 CONTINUE
+      STR = AA*CSGNR - BB*CSGNI
+      STI = AA*CSGNI + BB*CSGNR
+      CYR(I) = STR*ATOL
+      CYI(I) = STI*ATOL
+      STR = -CSGNI*ZTI
+      CSGNI = CSGNR*ZTI
+      CSGNR = STR
+  130 CONTINUE
+      RETURN
+  140 CONTINUE
+      IF (ZNR.LT.0.0D0) GO TO 230
+      RETURN
+  230 CONTINUE
+      NZ=0
+      IERR=2
+      RETURN
+  240 CONTINUE
+      IF(NW.EQ.(-1)) GO TO 230
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/zbesi.f b/libcruft/amos/zbesi.f
new file mode 100644
index 0000000..1376599
--- /dev/null
+++ b/libcruft/amos/zbesi.f
@@ -0,0 +1,269 @@
+      SUBROUTINE ZBESI(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, IERR)
+C***BEGIN PROLOGUE  ZBESI
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  I-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION,
+C             MODIFIED BESSEL FUNCTION OF THE FIRST KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE I-BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C                    ***A DOUBLE PRECISION ROUTINE***
+C         ON KODE=1, ZBESI COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(J)=I(FNU+J-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z IN THE CUT PLANE
+C         -PI.LT.ARG(Z).LE.PI. ON KODE=2, ZBESI RETURNS THE SCALED
+C         FUNCTIONS
+C
+C         CY(J)=EXP(-ABS(X))*I(FNU+J-1,Z)   J = 1,...,N , X=REAL(Z)
+C
+C         WITH THE EXPONENTIAL GROWTH REMOVED IN BOTH THE LEFT AND
+C         RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION
+C         ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS
+C         (REF. 1).
+C
+C         INPUT      ZR,ZI,FNU ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI),  -PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL I FUNCTION, FNU.GE.0.0D0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(J)=I(FNU+J-1,Z), J=1,...,N
+C                        = 2  RETURNS
+C                             CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X)), J=1,...,N
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C
+C         OUTPUT     CYR,CYI ARE DOUBLE PRECISION
+C           CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS
+C                    CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE
+C                    CY(J)=I(FNU+J-1,Z)  OR
+C                    CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X))  J=1,...,N
+C                    DEPENDING ON KODE, X=REAL(Z)
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , LAST NZ COMPONENTS OF CY SET TO ZERO
+C                              TO UNDERFLOW, CY(J)=CMPLX(0.0D0,0.0D0)
+C                              J = N-NZ+1,...,N
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, REAL(Z) TOO
+C                            LARGE ON KODE=1
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE POWER SERIES FOR
+C         SMALL CABS(Z), THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z),
+C         THE MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN AND A
+C         NEUMANN SERIES FOR IMTERMEDIATE MAGNITUDES, AND THE
+C         UNIFORM ASYMPTOTIC EXPANSIONS FOR I(FNU,Z) AND J(FNU,Z)
+C         FOR LARGE ORDERS. BACKWARD RECURRENCE IS USED TO GENERATE
+C         SEQUENCES OR REDUCE ORDERS WHEN NECESSARY.
+C
+C         THE CALCULATIONS ABOVE ARE DONE IN THE RIGHT HALF PLANE AND
+C         CONTINUED INTO THE LEFT HALF PLANE BY THE FORMULA
+C
+C         I(FNU,Z*EXP(M*PI)) = EXP(M*PI*FNU)*I(FNU,Z)  REAL(Z).GT.0.0
+C                       M = +I OR -I,  I**2=-1
+C
+C         FOR NEGATIVE ORDERS,THE FORMULA
+C
+C              I(-FNU,Z) = I(FNU,Z) + (2/PI)*SIN(PI*FNU)*K(FNU,Z)
+C
+C         CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE
+C         THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE
+C         INTEGER,THE MAGNITUDE OF I(-FNU,Z)=I(FNU,Z) IS A LARGE
+C         NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER,
+C         K(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF
+C         TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY
+C         UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN
+C         OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE,
+C         LARGE MEANS FNU.GT.CABS(Z).
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZBINU,I1MACH,D1MACH
+C***END PROLOGUE  ZBESI
+C     COMPLEX CONE,CSGN,CW,CY,CZERO,Z,ZN
+      DOUBLE PRECISION AA, ALIM, ARG, CONEI, CONER, CSGNI, CSGNR, CYI,
+     * CYR, DIG, ELIM, FNU, FNUL, PI, RL, R1M5, STR, TOL, ZI, ZNI, ZNR,
+     * ZR, D1MACH, AZ, BB, FN, XZABS, ASCLE, RTOL, ATOL, STI
+      INTEGER I, IERR, INU, K, KODE, K1,K2,N,NZ,NN, I1MACH
+      DIMENSION CYR(N), CYI(N)
+      DATA PI /3.14159265358979324D0/
+      DATA CONER, CONEI /1.0D0,0.0D0/
+C
+C***FIRST EXECUTABLE STATEMENT  ZBESI
+      IERR = 0
+      NZ=0
+      IF (FNU.LT.0.0D0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU.
+C-----------------------------------------------------------------------
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      R1M5 = D1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      K1 = I1MACH(14) - 1
+      AA = R1M5*DBLE(FLOAT(K1))
+      DIG = DMIN1(AA,18.0D0)
+      AA = AA*2.303D0
+      ALIM = ELIM + DMAX1(-AA,-41.45D0)
+      RL = 1.2D0*DIG + 3.0D0
+      FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0)
+C-----------------------------------------------------------------------------
+C     TEST FOR PROPER RANGE
+C-----------------------------------------------------------------------
+      AZ = XZABS(ZR,ZI)
+      FN = FNU+DBLE(FLOAT(N-1))
+      AA = 0.5D0/TOL
+      BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
+      AA = DMIN1(AA,BB)
+      IF (AZ.GT.AA) GO TO 260
+      IF (FN.GT.AA) GO TO 260
+      AA = DSQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      IF (FN.GT.AA) IERR=3
+      ZNR = ZR
+      ZNI = ZI
+      CSGNR = CONER
+      CSGNI = CONEI
+      IF (ZR.GE.0.0D0) GO TO 40
+      ZNR = -ZR
+      ZNI = -ZI
+C-----------------------------------------------------------------------
+C     CALCULATE CSGN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      INU = INT(SNGL(FNU))
+      ARG = (FNU-DBLE(FLOAT(INU)))*PI
+      IF (ZI.LT.0.0D0) ARG = -ARG
+      CSGNR = DCOS(ARG)
+      CSGNI = DSIN(ARG)
+      IF (MOD(INU,2).EQ.0) GO TO 40
+      CSGNR = -CSGNR
+      CSGNI = -CSGNI
+   40 CONTINUE
+      CALL ZBINU(ZNR, ZNI, FNU, KODE, N, CYR, CYI, NZ, RL, FNUL, TOL,
+     * ELIM, ALIM)
+      IF (NZ.LT.0) GO TO 120
+      IF (ZR.GE.0.0D0) RETURN
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION TO THE LEFT HALF PLANE
+C-----------------------------------------------------------------------
+      NN = N - NZ
+      IF (NN.EQ.0) RETURN
+      RTOL = 1.0D0/TOL
+      ASCLE = D1MACH(1)*RTOL*1.0D+3
+      DO 50 I=1,NN
+C       STR = CYR(I)*CSGNR - CYI(I)*CSGNI
+C       CYI(I) = CYR(I)*CSGNI + CYI(I)*CSGNR
+C       CYR(I) = STR
+        AA = CYR(I)
+        BB = CYI(I)
+        ATOL = 1.0D0
+        IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 55
+          AA = AA*RTOL
+          BB = BB*RTOL
+          ATOL = TOL
+   55   CONTINUE
+        STR = AA*CSGNR - BB*CSGNI
+        STI = AA*CSGNI + BB*CSGNR
+        CYR(I) = STR*ATOL
+        CYI(I) = STI*ATOL
+        CSGNR = -CSGNR
+        CSGNI = -CSGNI
+   50 CONTINUE
+      RETURN
+  120 CONTINUE
+      IF(NZ.EQ.(-2)) GO TO 130
+      NZ = 0
+      IERR=2
+      RETURN
+  130 CONTINUE
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/zbesj.f b/libcruft/amos/zbesj.f
new file mode 100644
index 0000000..a72eca0
--- /dev/null
+++ b/libcruft/amos/zbesj.f
@@ -0,0 +1,266 @@
+      SUBROUTINE ZBESJ(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, IERR)
+C***BEGIN PROLOGUE  ZBESJ
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  J-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT,
+C             BESSEL FUNCTION OF FIRST KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE J-BESSEL FUNCTION OF A COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C                      ***A DOUBLE PRECISION ROUTINE***
+C         ON KODE=1, CBESJ COMPUTES AN N MEMBER  SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(I)=J(FNU+I-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE
+C         -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESJ RETURNS THE SCALED
+C         FUNCTIONS
+C
+C         CY(I)=EXP(-ABS(Y))*J(FNU+I-1,Z)   I = 1,...,N , Y=AIMAG(Z)
+C
+C         WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND
+C         LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION
+C         ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS
+C         (REF. 1).
+C
+C         INPUT      ZR,ZI,FNU ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI),  -PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL J FUNCTION, FNU.GE.0.0D0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(I)=J(FNU+I-1,Z), I=1,...,N
+C                        = 2  RETURNS
+C                             CY(I)=J(FNU+I-1,Z)EXP(-ABS(Y)), I=1,...,N
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C
+C         OUTPUT     CYR,CYI ARE DOUBLE PRECISION
+C           CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS
+C                    CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE
+C                    CY(I)=J(FNU+I-1,Z)  OR
+C                    CY(I)=J(FNU+I-1,Z)EXP(-ABS(Y))  I=1,...,N
+C                    DEPENDING ON KODE, Y=AIMAG(Z).
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , LAST NZ COMPONENTS OF CY SET  ZERO DUE
+C                              TO UNDERFLOW, CY(I)=CMPLX(0.0D0,0.0D0),
+C                              I = N-NZ+1,...,N
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, AIMAG(Z)
+C                            TOO LARGE ON KODE=1
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE FORMULA
+C
+C         J(FNU,Z)=EXP( FNU*PI*I/2)*I(FNU,-I*Z)    AIMAG(Z).GE.0.0
+C
+C         J(FNU,Z)=EXP(-FNU*PI*I/2)*I(FNU, I*Z)    AIMAG(Z).LT.0.0
+C
+C         WHERE I**2 = -1 AND I(FNU,Z) IS THE I BESSEL FUNCTION.
+C
+C         FOR NEGATIVE ORDERS,THE FORMULA
+C
+C              J(-FNU,Z) = J(FNU,Z)*COS(PI*FNU) - Y(FNU,Z)*SIN(PI*FNU)
+C
+C         CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE
+C         THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE
+C         INTEGER,THE MAGNITUDE OF J(-FNU,Z)=J(FNU,Z)*COS(PI*FNU) IS A
+C         LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER,
+C         Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF
+C         TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY
+C         UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN
+C         OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE,
+C         LARGE MEANS FNU.GT.CABS(Z).
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZBINU,I1MACH,D1MACH
+C***END PROLOGUE  ZBESJ
+C
+C     COMPLEX CI,CSGN,CY,Z,ZN
+      DOUBLE PRECISION AA, ALIM, ARG, CII, CSGNI, CSGNR, CYI, CYR, DIG,
+     * ELIM, FNU, FNUL, HPI, RL, R1M5, STR, TOL, ZI, ZNI, ZNR, ZR,
+     * D1MACH, BB, FN, AZ, XZABS, ASCLE, RTOL, ATOL, STI
+      INTEGER I, IERR, INU, INUH, IR, K, KODE, K1, K2, N, NL, NZ, I1MACH
+      DIMENSION CYR(N), CYI(N)
+      DATA HPI /1.57079632679489662D0/
+C
+C***FIRST EXECUTABLE STATEMENT  ZBESJ
+      IERR = 0
+      NZ=0
+      IF (FNU.LT.0.0D0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU.
+C-----------------------------------------------------------------------
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      R1M5 = D1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      K1 = I1MACH(14) - 1
+      AA = R1M5*DBLE(FLOAT(K1))
+      DIG = DMIN1(AA,18.0D0)
+      AA = AA*2.303D0
+      ALIM = ELIM + DMAX1(-AA,-41.45D0)
+      RL = 1.2D0*DIG + 3.0D0
+      FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0)
+C-----------------------------------------------------------------------
+C     TEST FOR PROPER RANGE
+C-----------------------------------------------------------------------
+      AZ = XZABS(ZR,ZI)
+      FN = FNU+DBLE(FLOAT(N-1))
+      AA = 0.5D0/TOL
+      BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
+      AA = DMIN1(AA,BB)
+      IF (AZ.GT.AA) GO TO 260
+      IF (FN.GT.AA) GO TO 260
+      AA = DSQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      IF (FN.GT.AA) IERR=3
+C-----------------------------------------------------------------------
+C     CALCULATE CSGN=EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE
+C     WHEN FNU IS LARGE
+C-----------------------------------------------------------------------
+      CII = 1.0D0
+      INU = INT(SNGL(FNU))
+      INUH = INU/2
+      IR = INU - 2*INUH
+      ARG = (FNU-DBLE(FLOAT(INU-IR)))*HPI
+      CSGNR = DCOS(ARG)
+      CSGNI = DSIN(ARG)
+      IF (MOD(INUH,2).EQ.0) GO TO 40
+      CSGNR = -CSGNR
+      CSGNI = -CSGNI
+   40 CONTINUE
+C-----------------------------------------------------------------------
+C     ZN IS IN THE RIGHT HALF PLANE
+C-----------------------------------------------------------------------
+      ZNR = ZI
+      ZNI = -ZR
+      IF (ZI.GE.0.0D0) GO TO 50
+      ZNR = -ZNR
+      ZNI = -ZNI
+      CSGNI = -CSGNI
+      CII = -CII
+   50 CONTINUE
+      CALL ZBINU(ZNR, ZNI, FNU, KODE, N, CYR, CYI, NZ, RL, FNUL, TOL,
+     * ELIM, ALIM)
+      IF (NZ.LT.0) GO TO 130
+      NL = N - NZ
+      IF (NL.EQ.0) RETURN
+      RTOL = 1.0D0/TOL
+      ASCLE = D1MACH(1)*RTOL*1.0D+3
+      DO 60 I=1,NL
+C       STR = CYR(I)*CSGNR - CYI(I)*CSGNI
+C       CYI(I) = CYR(I)*CSGNI + CYI(I)*CSGNR
+C       CYR(I) = STR
+        AA = CYR(I)
+        BB = CYI(I)
+        ATOL = 1.0D0
+        IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 55
+          AA = AA*RTOL
+          BB = BB*RTOL
+          ATOL = TOL
+   55   CONTINUE
+        STR = AA*CSGNR - BB*CSGNI
+        STI = AA*CSGNI + BB*CSGNR
+        CYR(I) = STR*ATOL
+        CYI(I) = STI*ATOL
+        STR = -CSGNI*CII
+        CSGNI = CSGNR*CII
+        CSGNR = STR
+   60 CONTINUE
+      RETURN
+  130 CONTINUE
+      IF(NZ.EQ.(-2)) GO TO 140
+      NZ = 0
+      IERR = 2
+      RETURN
+  140 CONTINUE
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/zbesk.f b/libcruft/amos/zbesk.f
new file mode 100644
index 0000000..485bb68
--- /dev/null
+++ b/libcruft/amos/zbesk.f
@@ -0,0 +1,281 @@
+      SUBROUTINE ZBESK(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, IERR)
+C***BEGIN PROLOGUE  ZBESK
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  K-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION,
+C             MODIFIED BESSEL FUNCTION OF THE SECOND KIND,
+C             BESSEL FUNCTION OF THE THIRD KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE K-BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C                      ***A DOUBLE PRECISION ROUTINE***
+C
+C         ON KODE=1, CBESK COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(J)=K(FNU+J-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z.NE.CMPLX(0.0,0.0)
+C         IN THE CUT PLANE -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESK
+C         RETURNS THE SCALED K FUNCTIONS,
+C
+C         CY(J)=EXP(Z)*K(FNU+J-1,Z) , J=1,...,N,
+C
+C         WHICH REMOVE THE EXPONENTIAL BEHAVIOR IN BOTH THE LEFT AND
+C         RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND
+C         NOTATION ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL
+C         FUNCTIONS (REF. 1).
+C
+C         INPUT      ZR,ZI,FNU ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI), Z.NE.CMPLX(0.0D0,0.0D0),
+C                    -PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL K FUNCTION, FNU.GE.0.0D0
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(I)=K(FNU+I-1,Z), I=1,...,N
+C                        = 2  RETURNS
+C                             CY(I)=K(FNU+I-1,Z)*EXP(Z), I=1,...,N
+C
+C         OUTPUT     CYR,CYI ARE DOUBLE PRECISION
+C           CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS
+C                    CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE
+C                    CY(I)=K(FNU+I-1,Z), I=1,...,N OR
+C                    CY(I)=K(FNU+I-1,Z)*EXP(Z), I=1,...,N
+C                    DEPENDING ON KODE
+C           NZ     - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW.
+C                    NZ= 0   , NORMAL RETURN
+C                    NZ.GT.0 , FIRST NZ COMPONENTS OF CY SET TO ZERO DUE
+C                              TO UNDERFLOW, CY(I)=CMPLX(0.0D0,0.0D0),
+C                              I=1,...,N WHEN X.GE.0.0. WHEN X.LT.0.0
+C                              NZ STATES ONLY THE NUMBER OF UNDERFLOWS
+C                              IN THE SEQUENCE.
+C
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, FNU IS
+C                            TOO LARGE OR CABS(Z) IS TOO SMALL OR BOTH
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         EQUATIONS OF THE REFERENCE ARE IMPLEMENTED FOR SMALL ORDERS
+C         DNU AND DNU+1.0 IN THE RIGHT HALF PLANE X.GE.0.0. FORWARD
+C         RECURRENCE GENERATES HIGHER ORDERS. K IS CONTINUED TO THE LEFT
+C         HALF PLANE BY THE RELATION
+C
+C         K(FNU,Z*EXP(MP)) = EXP(-MP*FNU)*K(FNU,Z)-MP*I(FNU,Z)
+C         MP=MR*PI*I, MR=+1 OR -1, RE(Z).GT.0, I**2=-1
+C
+C         WHERE I(FNU,Z) IS THE I BESSEL FUNCTION.
+C
+C         FOR LARGE ORDERS, FNU.GT.FNUL, THE K FUNCTION IS COMPUTED
+C         BY MEANS OF ITS UNIFORM ASYMPTOTIC EXPANSIONS.
+C
+C         FOR NEGATIVE ORDERS, THE FORMULA
+C
+C                       K(-FNU,Z) = K(FNU,Z)
+C
+C         CAN BE USED.
+C
+C         CBESK ASSUMES THAT A SIGNIFICANT DIGIT SINH(X) FUNCTION IS
+C         AVAILABLE.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983.
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZACON,ZBKNU,ZBUNK,ZUOIK,XZABS,I1MACH,D1MACH
+C***END PROLOGUE  ZBESK
+C
+C     COMPLEX CY,Z
+      DOUBLE PRECISION AA, ALIM, ALN, ARG, AZ, CYI, CYR, DIG, ELIM, FN,
+     * FNU, FNUL, RL, R1M5, TOL, UFL, ZI, ZR, D1MACH, XZABS, BB
+      INTEGER IERR, K, KODE, K1, K2, MR, N, NN, NUF, NW, NZ, I1MACH
+      DIMENSION CYR(N), CYI(N)
+C***FIRST EXECUTABLE STATEMENT  ZBESK
+      IERR = 0
+      NZ=0
+      IF (ZI.EQ.0.0E0 .AND. ZR.EQ.0.0E0) IERR=1
+      IF (FNU.LT.0.0D0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      NN = N
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU
+C-----------------------------------------------------------------------
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      R1M5 = D1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      K1 = I1MACH(14) - 1
+      AA = R1M5*DBLE(FLOAT(K1))
+      DIG = DMIN1(AA,18.0D0)
+      AA = AA*2.303D0
+      ALIM = ELIM + DMAX1(-AA,-41.45D0)
+      FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0)
+      RL = 1.2D0*DIG + 3.0D0
+C-----------------------------------------------------------------------------
+C     TEST FOR PROPER RANGE
+C-----------------------------------------------------------------------
+      AZ = XZABS(ZR,ZI)
+      FN = FNU + DBLE(FLOAT(NN-1))
+      AA = 0.5D0/TOL
+      BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
+      AA = DMIN1(AA,BB)
+      IF (AZ.GT.AA) GO TO 260
+      IF (FN.GT.AA) GO TO 260
+      AA = DSQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      IF (FN.GT.AA) IERR=3
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST ON THE LAST MEMBER OF THE SEQUENCE
+C-----------------------------------------------------------------------
+C     UFL = DEXP(-ELIM)
+      UFL = D1MACH(1)*1.0D+3
+      IF (AZ.LT.UFL) GO TO 180
+      IF (FNU.GT.FNUL) GO TO 80
+      IF (FN.LE.1.0D0) GO TO 60
+      IF (FN.GT.2.0D0) GO TO 50
+      IF (AZ.GT.TOL) GO TO 60
+      ARG = 0.5D0*AZ
+      ALN = -FN*DLOG(ARG)
+      IF (ALN.GT.ELIM) GO TO 180
+      GO TO 60
+   50 CONTINUE
+      CALL ZUOIK(ZR, ZI, FNU, KODE, 2, NN, CYR, CYI, NUF, TOL, ELIM,
+     * ALIM)
+      IF (NUF.LT.0) GO TO 180
+      NZ = NZ + NUF
+      NN = NN - NUF
+C-----------------------------------------------------------------------
+C     HERE NN=N OR NN=0 SINCE NUF=0,NN, OR -1 ON RETURN FROM CUOIK
+C     IF NUF=NN, THEN CY(I)=CZERO FOR ALL I
+C-----------------------------------------------------------------------
+      IF (NN.EQ.0) GO TO 100
+   60 CONTINUE
+      IF (ZR.LT.0.0D0) GO TO 70
+C-----------------------------------------------------------------------
+C     RIGHT HALF PLANE COMPUTATION, REAL(Z).GE.0.
+C-----------------------------------------------------------------------
+      CALL ZBKNU(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 200
+      NZ=NW
+      RETURN
+C-----------------------------------------------------------------------
+C     LEFT HALF PLANE COMPUTATION
+C     PI/2.LT.ARG(Z).LE.PI AND -PI.LT.ARG(Z).LT.-PI/2.
+C-----------------------------------------------------------------------
+   70 CONTINUE
+      IF (NZ.NE.0) GO TO 180
+      MR = 1
+      IF (ZI.LT.0.0D0) MR = -1
+      CALL ZACON(ZR, ZI, FNU, KODE, MR, NN, CYR, CYI, NW, RL, FNUL,
+     * TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 200
+      NZ=NW
+      RETURN
+C-----------------------------------------------------------------------
+C     UNIFORM ASYMPTOTIC EXPANSIONS FOR FNU.GT.FNUL
+C-----------------------------------------------------------------------
+   80 CONTINUE
+      MR = 0
+      IF (ZR.GE.0.0D0) GO TO 90
+      MR = 1
+      IF (ZI.LT.0.0D0) MR = -1
+   90 CONTINUE
+      CALL ZBUNK(ZR, ZI, FNU, KODE, MR, NN, CYR, CYI, NW, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 200
+      NZ = NZ + NW
+      RETURN
+  100 CONTINUE
+      IF (ZR.LT.0.0D0) GO TO 180
+      RETURN
+  180 CONTINUE
+      NZ = 0
+      IERR=2
+      RETURN
+  200 CONTINUE
+      IF(NW.EQ.(-1)) GO TO 180
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      NZ=0
+      IERR=4
+      RETURN
+      END
diff --git a/libcruft/amos/zbesy.f b/libcruft/amos/zbesy.f
new file mode 100644
index 0000000..05ec40b
--- /dev/null
+++ b/libcruft/amos/zbesy.f
@@ -0,0 +1,244 @@
+      SUBROUTINE ZBESY(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, CWRKR, CWRKI,
+     *                 IERR)
+C***BEGIN PROLOGUE  ZBESY
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  Y-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT,
+C             BESSEL FUNCTION OF SECOND KIND
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE THE Y-BESSEL FUNCTION OF A COMPLEX ARGUMENT
+C***DESCRIPTION
+C
+C                      ***A DOUBLE PRECISION ROUTINE***
+C
+C         ON KODE=1, CBESY COMPUTES AN N MEMBER SEQUENCE OF COMPLEX
+C         BESSEL FUNCTIONS CY(I)=Y(FNU+I-1,Z) FOR REAL, NONNEGATIVE
+C         ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE
+C         -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESY RETURNS THE SCALED
+C         FUNCTIONS
+C
+C         CY(I)=EXP(-ABS(Y))*Y(FNU+I-1,Z)   I = 1,...,N , Y=AIMAG(Z)
+C
+C         WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND
+C         LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION
+C         ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS
+C         (REF. 1).
+C
+C         INPUT      ZR,ZI,FNU ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI), Z.NE.CMPLX(0.0D0,0.0D0),
+C                    -PI.LT.ARG(Z).LE.PI
+C           FNU    - ORDER OF INITIAL Y FUNCTION, FNU.GE.0.0D0
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             CY(I)=Y(FNU+I-1,Z), I=1,...,N
+C                        = 2  RETURNS
+C                             CY(I)=Y(FNU+I-1,Z)*EXP(-ABS(Y)), I=1,...,N
+C                             WHERE Y=AIMAG(Z)
+C           N      - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1
+C           CWRKR, - DOUBLE PRECISION WORK VECTORS OF DIMENSION AT
+C           CWRKI    AT LEAST N
+C
+C         OUTPUT     CYR,CYI ARE DOUBLE PRECISION
+C           CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS
+C                    CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE
+C                    CY(I)=Y(FNU+I-1,Z)  OR
+C                    CY(I)=Y(FNU+I-1,Z)*EXP(-ABS(Y))  I=1,...,N
+C                    DEPENDING ON KODE.
+C           NZ     - NZ=0 , A NORMAL RETURN
+C                    NZ.GT.0 , NZ COMPONENTS OF CY SET TO ZERO DUE TO
+C                    UNDERFLOW (GENERALLY ON KODE=2)
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, FNU IS
+C                            TOO LARGE OR CABS(Z) IS TOO SMALL OR BOTH
+C                    IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
+C                            BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
+C                            REDUCTION PRODUCE LESS THAN HALF OF MACHINE
+C                            ACCURACY
+C                    IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
+C                            TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
+C                            CANCE BY ARGUMENT REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         THE COMPUTATION IS CARRIED OUT BY THE FORMULA
+C
+C         Y(FNU,Z)=0.5*(H(1,FNU,Z)-H(2,FNU,Z))/I
+C
+C         WHERE I**2 = -1 AND THE HANKEL BESSEL FUNCTIONS H(1,FNU,Z)
+C         AND H(2,FNU,Z) ARE CALCULATED IN CBESH.
+C
+C         FOR NEGATIVE ORDERS,THE FORMULA
+C
+C              Y(-FNU,Z) = Y(FNU,Z)*COS(PI*FNU) + J(FNU,Z)*SIN(PI*FNU)
+C
+C         CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO HALF ODD
+C         INTEGERS THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE
+C         POSITIVE HALF ODD INTEGER,THE MAGNITUDE OF Y(-FNU,Z)=J(FNU,Z)*
+C         SIN(PI*FNU) IS A LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS
+C         NOT A HALF ODD INTEGER, Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A
+C         LARGE POSITIVE POWER OF TEN AND THE MOST THAT THE SECOND TERM
+C         CAN BE REDUCED IS BY UNIT ROUNDOFF FROM THE COEFFICIENT. THUS,
+C         WIDE CHANGES CAN OCCUR WITHIN UNIT ROUNDOFF OF A LARGE HALF
+C         ODD INTEGER. HERE, LARGE MEANS FNU.GT.CABS(Z).
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS
+C         LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR.
+C         CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN
+C         LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG
+C         IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS
+C         LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS
+C         MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE
+C         INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS
+C         RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3
+C         ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION
+C         ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION
+C         ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN
+C         THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT
+C         TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS
+C         IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC.
+C         SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 BY D. E. AMOS, SAND83-0083, MAY, 1983.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZBESH,I1MACH,D1MACH
+C***END PROLOGUE  ZBESY
+C
+C     COMPLEX CWRK,CY,C1,C2,EX,HCI,Z,ZU,ZV
+      DOUBLE PRECISION CWRKI, CWRKR, CYI, CYR, C1I, C1R, C2I, C2R,
+     * ELIM, EXI, EXR, EY, FNU, HCII, STI, STR, TAY, ZI, ZR, DEXP,
+     * D1MACH, ASCLE, RTOL, ATOL, AA, BB, TOL
+      INTEGER I, IERR, K, KODE, K1, K2, N, NZ, NZ1, NZ2, I1MACH
+      DIMENSION CYR(N), CYI(N), CWRKR(N), CWRKI(N)
+C***FIRST EXECUTABLE STATEMENT  ZBESY
+      IERR = 0
+      NZ=0
+      IF (ZR.EQ.0.0D0 .AND. ZI.EQ.0.0D0) IERR=1
+      IF (FNU.LT.0.0D0) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (N.LT.1) IERR=1
+      IF (IERR.NE.0) RETURN
+      HCII = 0.5D0
+      CALL ZBESH(ZR, ZI, FNU, KODE, 1, N, CYR, CYI, NZ1, IERR)
+      IF (IERR.NE.0.AND.IERR.NE.3) GO TO 170
+      CALL ZBESH(ZR, ZI, FNU, KODE, 2, N, CWRKR, CWRKI, NZ2, IERR)
+      IF (IERR.NE.0.AND.IERR.NE.3) GO TO 170
+      NZ = MIN0(NZ1,NZ2)
+      IF (KODE.EQ.2) GO TO 60
+      DO 50 I=1,N
+        STR = CWRKR(I) - CYR(I)
+        STI = CWRKI(I) - CYI(I)
+        CYR(I) = -STI*HCII
+        CYI(I) = STR*HCII
+   50 CONTINUE
+      RETURN
+   60 CONTINUE
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      K = MIN0(IABS(K1),IABS(K2))
+      R1M5 = D1MACH(5)
+C-----------------------------------------------------------------------
+C     ELIM IS THE APPROXIMATE EXPONENTIAL UNDER- AND OVERFLOW LIMIT
+C-----------------------------------------------------------------------
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      EXR = DCOS(ZR)
+      EXI = DSIN(ZR)
+      EY = 0.0D0
+      TAY = DABS(ZI+ZI)
+      IF (TAY.LT.ELIM) EY = DEXP(-TAY)
+      IF (ZI.LT.0.0D0) GO TO 90
+      C1R = EXR*EY
+      C1I = EXI*EY
+      C2R = EXR
+      C2I = -EXI
+   70 CONTINUE
+      NZ = 0
+      RTOL = 1.0D0/TOL
+      ASCLE = D1MACH(1)*RTOL*1.0D+3
+      DO 80 I=1,N
+C       STR = C1R*CYR(I) - C1I*CYI(I)
+C       STI = C1R*CYI(I) + C1I*CYR(I)
+C       STR = -STR + C2R*CWRKR(I) - C2I*CWRKI(I)
+C       STI = -STI + C2R*CWRKI(I) + C2I*CWRKR(I)
+C       CYR(I) = -STI*HCII
+C       CYI(I) = STR*HCII
+        AA = CWRKR(I)
+        BB = CWRKI(I)
+        ATOL = 1.0D0
+        IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 75
+          AA = AA*RTOL
+          BB = BB*RTOL
+          ATOL = TOL
+   75   CONTINUE
+        STR = (AA*C2R - BB*C2I)*ATOL
+        STI = (AA*C2I + BB*C2R)*ATOL
+        AA = CYR(I)
+        BB = CYI(I)
+        ATOL = 1.0D0
+        IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 85
+          AA = AA*RTOL
+          BB = BB*RTOL
+          ATOL = TOL
+   85   CONTINUE
+        STR = STR - (AA*C1R - BB*C1I)*ATOL
+        STI = STI - (AA*C1I + BB*C1R)*ATOL
+        CYR(I) = -STI*HCII
+        CYI(I) =  STR*HCII
+        IF (STR.EQ.0.0D0 .AND. STI.EQ.0.0D0 .AND. EY.EQ.0.0D0) NZ = NZ
+     *   + 1
+   80 CONTINUE
+      RETURN
+   90 CONTINUE
+      C1R = EXR
+      C1I = EXI
+      C2R = EXR*EY
+      C2I = -EXI*EY
+      GO TO 70
+  170 CONTINUE
+      NZ = 0
+      RETURN
+      END
diff --git a/libcruft/amos/zbinu.f b/libcruft/amos/zbinu.f
new file mode 100644
index 0000000..fc0baef
--- /dev/null
+++ b/libcruft/amos/zbinu.f
@@ -0,0 +1,110 @@
+      SUBROUTINE ZBINU(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, RL, FNUL,
+     * TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  ZBINU
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZAIRY,ZBIRY
+C
+C     ZBINU COMPUTES THE I FUNCTION IN THE RIGHT HALF Z PLANE
+C
+C***ROUTINES CALLED  XZABS,ZASYI,ZBUNI,ZMLRI,ZSERI,ZUOIK,ZWRSK
+C***END PROLOGUE  ZBINU
+      DOUBLE PRECISION ALIM, AZ, CWI, CWR, CYI, CYR, DFNU, ELIM, FNU,
+     * FNUL, RL, TOL, ZEROI, ZEROR, ZI, ZR, XZABS
+      INTEGER I, INW, KODE, N, NLAST, NN, NUI, NW, NZ
+      DIMENSION CYR(N), CYI(N), CWR(2), CWI(2)
+      DATA ZEROR,ZEROI / 0.0D0, 0.0D0 /
+C
+      NZ = 0
+      AZ = XZABS(ZR,ZI)
+      NN = N
+      DFNU = FNU + DBLE(FLOAT(N-1))
+      IF (AZ.LE.2.0D0) GO TO 10
+      IF (AZ*AZ*0.25D0.GT.DFNU+1.0D0) GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     POWER SERIES
+C-----------------------------------------------------------------------
+      CALL ZSERI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, TOL, ELIM, ALIM)
+      INW = IABS(NW)
+      NZ = NZ + INW
+      NN = NN - INW
+      IF (NN.EQ.0) RETURN
+      IF (NW.GE.0) GO TO 120
+      DFNU = FNU + DBLE(FLOAT(NN-1))
+   20 CONTINUE
+      IF (AZ.LT.RL) GO TO 40
+      IF (DFNU.LE.1.0D0) GO TO 30
+      IF (AZ+AZ.LT.DFNU*DFNU) GO TO 50
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR LARGE Z
+C-----------------------------------------------------------------------
+   30 CONTINUE
+      CALL ZASYI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, RL, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 130
+      GO TO 120
+   40 CONTINUE
+      IF (DFNU.LE.1.0D0) GO TO 70
+   50 CONTINUE
+C-----------------------------------------------------------------------
+C     OVERFLOW AND UNDERFLOW TEST ON I SEQUENCE FOR MILLER ALGORITHM
+C-----------------------------------------------------------------------
+      CALL ZUOIK(ZR, ZI, FNU, KODE, 1, NN, CYR, CYI, NW, TOL, ELIM,
+     * ALIM)
+      IF (NW.LT.0) GO TO 130
+      NZ = NZ + NW
+      NN = NN - NW
+      IF (NN.EQ.0) RETURN
+      DFNU = FNU+DBLE(FLOAT(NN-1))
+      IF (DFNU.GT.FNUL) GO TO 110
+      IF (AZ.GT.FNUL) GO TO 110
+   60 CONTINUE
+      IF (AZ.GT.RL) GO TO 80
+   70 CONTINUE
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM NORMALIZED BY THE SERIES
+C-----------------------------------------------------------------------
+      CALL ZMLRI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, TOL)
+      IF(NW.LT.0) GO TO 130
+      GO TO 120
+   80 CONTINUE
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST ON K FUNCTIONS USED IN WRONSKIAN
+C-----------------------------------------------------------------------
+      CALL ZUOIK(ZR, ZI, FNU, KODE, 2, 2, CWR, CWI, NW, TOL, ELIM,
+     * ALIM)
+      IF (NW.GE.0) GO TO 100
+      NZ = NN
+      DO 90 I=1,NN
+        CYR(I) = ZEROR
+        CYI(I) = ZEROI
+   90 CONTINUE
+      RETURN
+  100 CONTINUE
+      IF (NW.GT.0) GO TO 130
+      CALL ZWRSK(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, CWR, CWI, TOL,
+     * ELIM, ALIM)
+      IF (NW.LT.0) GO TO 130
+      GO TO 120
+  110 CONTINUE
+C-----------------------------------------------------------------------
+C     INCREMENT FNU+NN-1 UP TO FNUL, COMPUTE AND RECUR BACKWARD
+C-----------------------------------------------------------------------
+      NUI = INT(SNGL(FNUL-DFNU)) + 1
+      NUI = MAX0(NUI,0)
+      CALL ZBUNI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, NUI, NLAST, FNUL,
+     * TOL, ELIM, ALIM)
+      IF (NW.LT.0) GO TO 130
+      NZ = NZ + NW
+      IF (NLAST.EQ.0) GO TO 120
+      NN = NLAST
+      GO TO 60
+  120 CONTINUE
+      RETURN
+  130 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/zbiry.f b/libcruft/amos/zbiry.f
new file mode 100644
index 0000000..e559544
--- /dev/null
+++ b/libcruft/amos/zbiry.f
@@ -0,0 +1,364 @@
+      SUBROUTINE ZBIRY(ZR, ZI, ID, KODE, BIR, BII, IERR)
+C***BEGIN PROLOGUE  ZBIRY
+C***DATE WRITTEN   830501   (YYMMDD)
+C***REVISION DATE  890801   (YYMMDD)
+C***CATEGORY NO.  B5K
+C***KEYWORDS  AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD
+C***AUTHOR  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
+C***PURPOSE  TO COMPUTE AIRY FUNCTIONS BI(Z) AND DBI(Z) FOR COMPLEX Z
+C***DESCRIPTION
+C
+C                      ***A DOUBLE PRECISION ROUTINE***
+C         ON KODE=1, CBIRY COMPUTES THE COMPLEX AIRY FUNCTION BI(Z) OR
+C         ITS DERIVATIVE DBI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON
+C         KODE=2, A SCALING OPTION CEXP(-AXZTA)*BI(Z) OR CEXP(-AXZTA)*
+C         DBI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL BEHAVIOR IN
+C         BOTH THE LEFT AND RIGHT HALF PLANES WHERE
+C         ZTA=(2/3)*Z*CSQRT(Z)=CMPLX(XZTA,YZTA) AND AXZTA=ABS(XZTA).
+C         DEFINTIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF
+C         MATHEMATICAL FUNCTIONS (REF. 1).
+C
+C         INPUT      ZR,ZI ARE DOUBLE PRECISION
+C           ZR,ZI  - Z=CMPLX(ZR,ZI)
+C           ID     - ORDER OF DERIVATIVE, ID=0 OR ID=1
+C           KODE   - A PARAMETER TO INDICATE THE SCALING OPTION
+C                    KODE= 1  RETURNS
+C                             BI=BI(Z)                 ON ID=0 OR
+C                             BI=DBI(Z)/DZ             ON ID=1
+C                        = 2  RETURNS
+C                             BI=CEXP(-AXZTA)*BI(Z)     ON ID=0 OR
+C                             BI=CEXP(-AXZTA)*DBI(Z)/DZ ON ID=1 WHERE
+C                             ZTA=(2/3)*Z*CSQRT(Z)=CMPLX(XZTA,YZTA)
+C                             AND AXZTA=ABS(XZTA)
+C
+C         OUTPUT     BIR,BII ARE DOUBLE PRECISION
+C           BIR,BII- COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND
+C                    KODE
+C           IERR   - ERROR FLAG
+C                    IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
+C                    IERR=1, INPUT ERROR   - NO COMPUTATION
+C                    IERR=2, OVERFLOW      - NO COMPUTATION, REAL(Z)
+C                            TOO LARGE ON KODE=1
+C                    IERR=3, CABS(Z) LARGE      - COMPUTATION COMPLETED
+C                            LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION
+C                            PRODUCE LESS THAN HALF OF MACHINE ACCURACY
+C                    IERR=4, CABS(Z) TOO LARGE  - NO COMPUTATION
+C                            COMPLETE LOSS OF ACCURACY BY ARGUMENT
+C                            REDUCTION
+C                    IERR=5, ERROR              - NO COMPUTATION,
+C                            ALGORITHM TERMINATION CONDITION NOT MET
+C
+C***LONG DESCRIPTION
+C
+C         BI AND DBI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE I BESSEL
+C         FUNCTIONS BY
+C
+C                BI(Z)=C*SQRT(Z)*( I(-1/3,ZTA) + I(1/3,ZTA) )
+C               DBI(Z)=C *  Z  * ( I(-2/3,ZTA) + I(2/3,ZTA) )
+C                               C=1.0/SQRT(3.0)
+C                             ZTA=(2/3)*Z**(3/2)
+C
+C         WITH THE POWER SERIES FOR CABS(Z).LE.1.0.
+C
+C         IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
+C         MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES
+C         OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF
+C         THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR),
+C         THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR
+C         FLAG IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS
+C         DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION.
+C         ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN
+C         ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT
+C         FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE
+C         LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA
+C         MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2,
+C         AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE
+C         PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE
+C         PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT-
+C         ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG-
+C         NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN
+C         DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN
+C         EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES,
+C         NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE
+C         PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER
+C         MACHINES.
+C
+C         THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
+C         BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
+C         ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
+C         SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
+C         ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
+C         ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
+C         CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
+C         HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
+C         ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
+C         SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
+C         THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
+C         0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
+C         THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
+C         COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
+C         BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
+C         COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
+C         MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
+C         THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
+C         OR -PI/2+P.
+C
+C***REFERENCES  HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
+C                 AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
+C                 COMMERCE, 1955.
+C
+C               COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
+C                 AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
+C
+C               A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
+C                 1018, MAY, 1985
+C
+C               A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
+C                 ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
+C                 MATH. SOFTWARE, 1986
+C
+C***ROUTINES CALLED  ZBINU,XZABS,ZDIV,XZSQRT,D1MACH,I1MACH
+C***END PROLOGUE  ZBIRY
+C     COMPLEX BI,CONE,CSQ,CY,S1,S2,TRM1,TRM2,Z,ZTA,Z3
+      DOUBLE PRECISION AA, AD, AK, ALIM, ATRM, AZ, AZ3, BB, BII, BIR,
+     * BK, CC, CK, COEF, CONEI, CONER, CSQI, CSQR, CYI, CYR, C1, C2,
+     * DIG, DK, D1, D2, EAA, ELIM, FID, FMR, FNU, FNUL, PI, RL, R1M5,
+     * SFAC, STI, STR, S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I,
+     * TRM2R, TTH, ZI, ZR, ZTAI, ZTAR, Z3I, Z3R, D1MACH, XZABS
+      INTEGER ID, IERR, K, KODE, K1, K2, NZ, I1MACH
+      DIMENSION CYR(2), CYI(2)
+      DATA TTH, C1, C2, COEF, PI /6.66666666666666667D-01,
+     * 6.14926627446000736D-01,4.48288357353826359D-01,
+     * 5.77350269189625765D-01,3.14159265358979324D+00/
+      DATA CONER, CONEI /1.0D0,0.0D0/
+C***FIRST EXECUTABLE STATEMENT  ZBIRY
+      IERR = 0
+      NZ=0
+      IF (ID.LT.0 .OR. ID.GT.1) IERR=1
+      IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1
+      IF (IERR.NE.0) RETURN
+      AZ = XZABS(ZR,ZI)
+      TOL = DMAX1(D1MACH(4),1.0D-18)
+      FID = DBLE(FLOAT(ID))
+      IF (AZ.GT.1.0E0) GO TO 70
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR CABS(Z).LE.1.
+C-----------------------------------------------------------------------
+      S1R = CONER
+      S1I = CONEI
+      S2R = CONER
+      S2I = CONEI
+      IF (AZ.LT.TOL) GO TO 130
+      AA = AZ*AZ
+      IF (AA.LT.TOL/AZ) GO TO 40
+      TRM1R = CONER
+      TRM1I = CONEI
+      TRM2R = CONER
+      TRM2I = CONEI
+      ATRM = 1.0D0
+      STR = ZR*ZR - ZI*ZI
+      STI = ZR*ZI + ZI*ZR
+      Z3R = STR*ZR - STI*ZI
+      Z3I = STR*ZI + STI*ZR
+      AZ3 = AZ*AA
+      AK = 2.0D0 + FID
+      BK = 3.0D0 - FID - FID
+      CK = 4.0D0 - FID
+      DK = 3.0D0 + FID + FID
+      D1 = AK*DK
+      D2 = BK*CK
+      AD = DMIN1(D1,D2)
+      AK = 24.0D0 + 9.0D0*FID
+      BK = 30.0D0 - 9.0D0*FID
+      DO 30 K=1,25
+        STR = (TRM1R*Z3R-TRM1I*Z3I)/D1
+        TRM1I = (TRM1R*Z3I+TRM1I*Z3R)/D1
+        TRM1R = STR
+        S1R = S1R + TRM1R
+        S1I = S1I + TRM1I
+        STR = (TRM2R*Z3R-TRM2I*Z3I)/D2
+        TRM2I = (TRM2R*Z3I+TRM2I*Z3R)/D2
+        TRM2R = STR
+        S2R = S2R + TRM2R
+        S2I = S2I + TRM2I
+        ATRM = ATRM*AZ3/AD
+        D1 = D1 + AK
+        D2 = D2 + BK
+        AD = DMIN1(D1,D2)
+        IF (ATRM.LT.TOL*AD) GO TO 40
+        AK = AK + 18.0D0
+        BK = BK + 18.0D0
+   30 CONTINUE
+   40 CONTINUE
+      IF (ID.EQ.1) GO TO 50
+      BIR = C1*S1R + C2*(ZR*S2R-ZI*S2I)
+      BII = C1*S1I + C2*(ZR*S2I+ZI*S2R)
+      IF (KODE.EQ.1) RETURN
+      CALL XZSQRT(ZR, ZI, STR, STI)
+      ZTAR = TTH*(ZR*STR-ZI*STI)
+      ZTAI = TTH*(ZR*STI+ZI*STR)
+      AA = ZTAR
+      AA = -DABS(AA)
+      EAA = DEXP(AA)
+      BIR = BIR*EAA
+      BII = BII*EAA
+      RETURN
+   50 CONTINUE
+      BIR = S2R*C2
+      BII = S2I*C2
+      IF (AZ.LE.TOL) GO TO 60
+      CC = C1/(1.0D0+FID)
+      STR = S1R*ZR - S1I*ZI
+      STI = S1R*ZI + S1I*ZR
+      BIR = BIR + CC*(STR*ZR-STI*ZI)
+      BII = BII + CC*(STR*ZI+STI*ZR)
+   60 CONTINUE
+      IF (KODE.EQ.1) RETURN
+      CALL XZSQRT(ZR, ZI, STR, STI)
+      ZTAR = TTH*(ZR*STR-ZI*STI)
+      ZTAI = TTH*(ZR*STI+ZI*STR)
+      AA = ZTAR
+      AA = -DABS(AA)
+      EAA = DEXP(AA)
+      BIR = BIR*EAA
+      BII = BII*EAA
+      RETURN
+C-----------------------------------------------------------------------
+C     CASE FOR CABS(Z).GT.1.0
+C-----------------------------------------------------------------------
+   70 CONTINUE
+      FNU = (1.0D0+FID)/3.0D0
+C-----------------------------------------------------------------------
+C     SET PARAMETERS RELATED TO MACHINE CONSTANTS.
+C     TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
+C     ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
+C     EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL    AND
+C     EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL       ARE INTERVALS NEAR
+C     UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
+C     RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
+C     DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
+C     FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU.
+C-----------------------------------------------------------------------
+      K1 = I1MACH(15)
+      K2 = I1MACH(16)
+      R1M5 = D1MACH(5)
+      K = MIN0(IABS(K1),IABS(K2))
+      ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0)
+      K1 = I1MACH(14) - 1
+      AA = R1M5*DBLE(FLOAT(K1))
+      DIG = DMIN1(AA,18.0D0)
+      AA = AA*2.303D0
+      ALIM = ELIM + DMAX1(-AA,-41.45D0)
+      RL = 1.2D0*DIG + 3.0D0
+      FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0)
+C-----------------------------------------------------------------------
+C     TEST FOR RANGE
+C-----------------------------------------------------------------------
+      AA=0.5D0/TOL
+      BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
+      AA=DMIN1(AA,BB)
+      AA=AA**TTH
+      IF (AZ.GT.AA) GO TO 260
+      AA=DSQRT(AA)
+      IF (AZ.GT.AA) IERR=3
+      CALL XZSQRT(ZR, ZI, CSQR, CSQI)
+      ZTAR = TTH*(ZR*CSQR-ZI*CSQI)
+      ZTAI = TTH*(ZR*CSQI+ZI*CSQR)
+C-----------------------------------------------------------------------
+C     RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL
+C-----------------------------------------------------------------------
+      SFAC = 1.0D0
+      AK = ZTAI
+      IF (ZR.GE.0.0D0) GO TO 80
+      BK = ZTAR
+      CK = -DABS(BK)
+      ZTAR = CK
+      ZTAI = AK
+   80 CONTINUE
+      IF (ZI.NE.0.0D0 .OR. ZR.GT.0.0D0) GO TO 90
+      ZTAR = 0.0D0
+      ZTAI = AK
+   90 CONTINUE
+      AA = ZTAR
+      IF (KODE.EQ.2) GO TO 100
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      BB = DABS(AA)
+      IF (BB.LT.ALIM) GO TO 100
+      BB = BB + 0.25D0*DLOG(AZ)
+      SFAC = TOL
+      IF (BB.GT.ELIM) GO TO 190
+  100 CONTINUE
+      FMR = 0.0D0
+      IF (AA.GE.0.0D0 .AND. ZR.GT.0.0D0) GO TO 110
+      FMR = PI
+      IF (ZI.LT.0.0D0) FMR = -PI
+      ZTAR = -ZTAR
+      ZTAI = -ZTAI
+  110 CONTINUE
+C-----------------------------------------------------------------------
+C     AA=FACTOR FOR ANALYTIC CONTINUATION OF I(FNU,ZTA)
+C     KODE=2 RETURNS EXP(-ABS(XZTA))*I(FNU,ZTA) FROM CBESI
+C-----------------------------------------------------------------------
+      CALL ZBINU(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, RL, FNUL, TOL,
+     * ELIM, ALIM)
+      IF (NZ.LT.0) GO TO 200
+      AA = FMR*FNU
+      Z3R = SFAC
+      STR = DCOS(AA)
+      STI = DSIN(AA)
+      S1R = (STR*CYR(1)-STI*CYI(1))*Z3R
+      S1I = (STR*CYI(1)+STI*CYR(1))*Z3R
+      FNU = (2.0D0-FID)/3.0D0
+      CALL ZBINU(ZTAR, ZTAI, FNU, KODE, 2, CYR, CYI, NZ, RL, FNUL, TOL,
+     * ELIM, ALIM)
+      CYR(1) = CYR(1)*Z3R
+      CYI(1) = CYI(1)*Z3R
+      CYR(2) = CYR(2)*Z3R
+      CYI(2) = CYI(2)*Z3R
+C-----------------------------------------------------------------------
+C     BACKWARD RECUR ONE STEP FOR ORDERS -1/3 OR -2/3
+C-----------------------------------------------------------------------
+      CALL ZDIV(CYR(1), CYI(1), ZTAR, ZTAI, STR, STI)
+      S2R = (FNU+FNU)*STR + CYR(2)
+      S2I = (FNU+FNU)*STI + CYI(2)
+      AA = FMR*(FNU-1.0D0)
+      STR = DCOS(AA)
+      STI = DSIN(AA)
+      S1R = COEF*(S1R+S2R*STR-S2I*STI)
+      S1I = COEF*(S1I+S2R*STI+S2I*STR)
+      IF (ID.EQ.1) GO TO 120
+      STR = CSQR*S1R - CSQI*S1I
+      S1I = CSQR*S1I + CSQI*S1R
+      S1R = STR
+      BIR = S1R/SFAC
+      BII = S1I/SFAC
+      RETURN
+  120 CONTINUE
+      STR = ZR*S1R - ZI*S1I
+      S1I = ZR*S1I + ZI*S1R
+      S1R = STR
+      BIR = S1R/SFAC
+      BII = S1I/SFAC
+      RETURN
+  130 CONTINUE
+      AA = C1*(1.0D0-FID) + FID*C2
+      BIR = AA
+      BII = 0.0D0
+      RETURN
+  190 CONTINUE
+      IERR=2
+      NZ=0
+      RETURN
+  200 CONTINUE
+      IF(NZ.EQ.(-1)) GO TO 190
+      NZ=0
+      IERR=5
+      RETURN
+  260 CONTINUE
+      IERR=4
+      NZ=0
+      RETURN
+      END
diff --git a/libcruft/amos/zbknu.f b/libcruft/amos/zbknu.f
new file mode 100644
index 0000000..a720d01
--- /dev/null
+++ b/libcruft/amos/zbknu.f
@@ -0,0 +1,568 @@
+      SUBROUTINE ZBKNU(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  ZBKNU
+C***REFER TO  ZBESI,ZBESK,ZAIRY,ZBESH
+C
+C     ZBKNU COMPUTES THE K BESSEL FUNCTION IN THE RIGHT HALF Z PLANE.
+C
+C***ROUTINES CALLED  DGAMLN,I1MACH,D1MACH,ZKSCL,ZSHCH,ZUCHK,XZABS,ZDIV,
+C                    XZEXP,XZLOG,ZMLT,XZSQRT
+C***END PROLOGUE  ZBKNU
+C
+      DOUBLE PRECISION AA, AK, ALIM, ASCLE, A1, A2, BB, BK, BRY, CAZ,
+     * CBI, CBR, CC, CCHI, CCHR, CKI, CKR, COEFI, COEFR, CONEI, CONER,
+     * CRSCR, CSCLR, CSHI, CSHR, CSI, CSR, CSRR, CSSR, CTWOR,
+     * CZEROI, CZEROR, CZI, CZR, DNU, DNU2, DPI, ELIM, ETEST, FC, FHS,
+     * FI, FK, FKS, FMUI, FMUR, FNU, FPI, FR, G1, G2, HPI, PI, PR, PTI,
+     * PTR, P1I, P1R, P2I, P2M, P2R, QI, QR, RAK, RCAZ, RTHPI, RZI,
+     * RZR, R1, S, SMUI, SMUR, SPI, STI, STR, S1I, S1R, S2I, S2R, TM,
+     * TOL, TTH, T1, T2, YI, YR, ZI, ZR, DGAMLN, D1MACH, XZABS, ELM,
+     * CELMR, ZDR, ZDI, AS, ALAS, HELIM, CYR, CYI
+      INTEGER I, IFLAG, INU, K, KFLAG, KK, KMAX, KODE, KODED, N, NZ,
+     * IDUM, I1MACH, J, IC, INUB, NW
+      DIMENSION YR(N), YI(N), CC(8), CSSR(3), CSRR(3), BRY(3), CYR(2),
+     * CYI(2)
+C     COMPLEX Z,Y,A,B,RZ,SMU,FU,FMU,F,FLRZ,CZ,S1,S2,CSH,CCH
+C     COMPLEX CK,P,Q,COEF,P1,P2,CBK,PT,CZERO,CONE,CTWO,ST,EZ,CS,DK
+C
+      DATA KMAX / 30 /
+      DATA CZEROR,CZEROI,CONER,CONEI,CTWOR,R1/
+     1  0.0D0 , 0.0D0 , 1.0D0 , 0.0D0 , 2.0D0 , 2.0D0 /
+      DATA DPI, RTHPI, SPI ,HPI, FPI, TTH /
+     1     3.14159265358979324D0,       1.25331413731550025D0,
+     2     1.90985931710274403D0,       1.57079632679489662D0,
+     3     1.89769999331517738D0,       6.66666666666666666D-01/
+      DATA CC(1), CC(2), CC(3), CC(4), CC(5), CC(6), CC(7), CC(8)/
+     1     5.77215664901532861D-01,    -4.20026350340952355D-02,
+     2    -4.21977345555443367D-02,     7.21894324666309954D-03,
+     3    -2.15241674114950973D-04,    -2.01348547807882387D-05,
+     4     1.13302723198169588D-06,     6.11609510448141582D-09/
+C
+      CAZ = XZABS(ZR,ZI)
+      CSCLR = 1.0D0/TOL
+      CRSCR = TOL
+      CSSR(1) = CSCLR
+      CSSR(2) = 1.0D0
+      CSSR(3) = CRSCR
+      CSRR(1) = CRSCR
+      CSRR(2) = 1.0D0
+      CSRR(3) = CSCLR
+      BRY(1) = 1.0D+3*D1MACH(1)/TOL
+      BRY(2) = 1.0D0/BRY(1)
+      BRY(3) = D1MACH(2)
+      NZ = 0
+      IFLAG = 0
+      KODED = KODE
+      RCAZ = 1.0D0/CAZ
+      STR = ZR*RCAZ
+      STI = -ZI*RCAZ
+      RZR = (STR+STR)*RCAZ
+      RZI = (STI+STI)*RCAZ
+      INU = INT(SNGL(FNU+0.5D0))
+      DNU = FNU - DBLE(FLOAT(INU))
+      IF (DABS(DNU).EQ.0.5D0) GO TO 110
+      DNU2 = 0.0D0
+      IF (DABS(DNU).GT.TOL) DNU2 = DNU*DNU
+      IF (CAZ.GT.R1) GO TO 110
+C-----------------------------------------------------------------------
+C     SERIES FOR CABS(Z).LE.R1
+C-----------------------------------------------------------------------
+      FC = 1.0D0
+      CALL XZLOG(RZR, RZI, SMUR, SMUI, IDUM)
+      FMUR = SMUR*DNU
+      FMUI = SMUI*DNU
+      CALL ZSHCH(FMUR, FMUI, CSHR, CSHI, CCHR, CCHI)
+      IF (DNU.EQ.0.0D0) GO TO 10
+      FC = DNU*DPI
+      FC = FC/DSIN(FC)
+      SMUR = CSHR/DNU
+      SMUI = CSHI/DNU
+   10 CONTINUE
+      A2 = 1.0D0 + DNU
+C-----------------------------------------------------------------------
+C     GAM(1-Z)*GAM(1+Z)=PI*Z/SIN(PI*Z), T1=1/GAM(1-DNU), T2=1/GAM(1+DNU)
+C-----------------------------------------------------------------------
+      T2 = DEXP(-DGAMLN(A2,IDUM))
+      T1 = 1.0D0/(T2*FC)
+      IF (DABS(DNU).GT.0.1D0) GO TO 40
+C-----------------------------------------------------------------------
+C     SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU)
+C-----------------------------------------------------------------------
+      AK = 1.0D0
+      S = CC(1)
+      DO 20 K=2,8
+        AK = AK*DNU2
+        TM = CC(K)*AK
+        S = S + TM
+        IF (DABS(TM).LT.TOL) GO TO 30
+   20 CONTINUE
+   30 G1 = -S
+      GO TO 50
+   40 CONTINUE
+      G1 = (T1-T2)/(DNU+DNU)
+   50 CONTINUE
+      G2 = (T1+T2)*0.5D0
+      FR = FC*(CCHR*G1+SMUR*G2)
+      FI = FC*(CCHI*G1+SMUI*G2)
+      CALL XZEXP(FMUR, FMUI, STR, STI)
+      PR = 0.5D0*STR/T2
+      PI = 0.5D0*STI/T2
+      CALL ZDIV(0.5D0, 0.0D0, STR, STI, PTR, PTI)
+      QR = PTR/T1
+      QI = PTI/T1
+      S1R = FR
+      S1I = FI
+      S2R = PR
+      S2I = PI
+      AK = 1.0D0
+      A1 = 1.0D0
+      CKR = CONER
+      CKI = CONEI
+      BK = 1.0D0 - DNU2
+      IF (INU.GT.0 .OR. N.GT.1) GO TO 80
+C-----------------------------------------------------------------------
+C     GENERATE K(FNU,Z), 0.0D0 .LE. FNU .LT. 0.5D0 AND N=1
+C-----------------------------------------------------------------------
+      IF (CAZ.LT.TOL) GO TO 70
+      CALL ZMLT(ZR, ZI, ZR, ZI, CZR, CZI)
+      CZR = 0.25D0*CZR
+      CZI = 0.25D0*CZI
+      T1 = 0.25D0*CAZ*CAZ
+   60 CONTINUE
+      FR = (FR*AK+PR+QR)/BK
+      FI = (FI*AK+PI+QI)/BK
+      STR = 1.0D0/(AK-DNU)
+      PR = PR*STR
+      PI = PI*STR
+      STR = 1.0D0/(AK+DNU)
+      QR = QR*STR
+      QI = QI*STR
+      STR = CKR*CZR - CKI*CZI
+      RAK = 1.0D0/AK
+      CKI = (CKR*CZI+CKI*CZR)*RAK
+      CKR = STR*RAK
+      S1R = CKR*FR - CKI*FI + S1R
+      S1I = CKR*FI + CKI*FR + S1I
+      A1 = A1*T1*RAK
+      BK = BK + AK + AK + 1.0D0
+      AK = AK + 1.0D0
+      IF (A1.GT.TOL) GO TO 60
+   70 CONTINUE
+      YR(1) = S1R
+      YI(1) = S1I
+      IF (KODED.EQ.1) RETURN
+      CALL XZEXP(ZR, ZI, STR, STI)
+      CALL ZMLT(S1R, S1I, STR, STI, YR(1), YI(1))
+      RETURN
+C-----------------------------------------------------------------------
+C     GENERATE K(DNU,Z) AND K(DNU+1,Z) FOR FORWARD RECURRENCE
+C-----------------------------------------------------------------------
+   80 CONTINUE
+      IF (CAZ.LT.TOL) GO TO 100
+      CALL ZMLT(ZR, ZI, ZR, ZI, CZR, CZI)
+      CZR = 0.25D0*CZR
+      CZI = 0.25D0*CZI
+      T1 = 0.25D0*CAZ*CAZ
+   90 CONTINUE
+      FR = (FR*AK+PR+QR)/BK
+      FI = (FI*AK+PI+QI)/BK
+      STR = 1.0D0/(AK-DNU)
+      PR = PR*STR
+      PI = PI*STR
+      STR = 1.0D0/(AK+DNU)
+      QR = QR*STR
+      QI = QI*STR
+      STR = CKR*CZR - CKI*CZI
+      RAK = 1.0D0/AK
+      CKI = (CKR*CZI+CKI*CZR)*RAK
+      CKR = STR*RAK
+      S1R = CKR*FR - CKI*FI + S1R
+      S1I = CKR*FI + CKI*FR + S1I
+      STR = PR - FR*AK
+      STI = PI - FI*AK
+      S2R = CKR*STR - CKI*STI + S2R
+      S2I = CKR*STI + CKI*STR + S2I
+      A1 = A1*T1*RAK
+      BK = BK + AK + AK + 1.0D0
+      AK = AK + 1.0D0
+      IF (A1.GT.TOL) GO TO 90
+  100 CONTINUE
+      KFLAG = 2
+      A1 = FNU + 1.0D0
+      AK = A1*DABS(SMUR)
+      IF (AK.GT.ALIM) KFLAG = 3
+      STR = CSSR(KFLAG)
+      P2R = S2R*STR
+      P2I = S2I*STR
+      CALL ZMLT(P2R, P2I, RZR, RZI, S2R, S2I)
+      S1R = S1R*STR
+      S1I = S1I*STR
+      IF (KODED.EQ.1) GO TO 210
+      CALL XZEXP(ZR, ZI, FR, FI)
+      CALL ZMLT(S1R, S1I, FR, FI, S1R, S1I)
+      CALL ZMLT(S2R, S2I, FR, FI, S2R, S2I)
+      GO TO 210
+C-----------------------------------------------------------------------
+C     IFLAG=0 MEANS NO UNDERFLOW OCCURRED
+C     IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH
+C     KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD
+C     RECURSION
+C-----------------------------------------------------------------------
+  110 CONTINUE
+      CALL XZSQRT(ZR, ZI, STR, STI)
+      CALL ZDIV(RTHPI, CZEROI, STR, STI, COEFR, COEFI)
+      KFLAG = 2
+      IF (KODED.EQ.2) GO TO 120
+      IF (ZR.GT.ALIM) GO TO 290
+C     BLANK LINE
+      STR = DEXP(-ZR)*CSSR(KFLAG)
+      STI = -STR*DSIN(ZI)
+      STR = STR*DCOS(ZI)
+      CALL ZMLT(COEFR, COEFI, STR, STI, COEFR, COEFI)
+  120 CONTINUE
+      IF (DABS(DNU).EQ.0.5D0) GO TO 300
+C-----------------------------------------------------------------------
+C     MILLER ALGORITHM FOR CABS(Z).GT.R1
+C-----------------------------------------------------------------------
+      AK = DCOS(DPI*DNU)
+      AK = DABS(AK)
+      IF (AK.EQ.CZEROR) GO TO 300
+      FHS = DABS(0.25D0-DNU2)
+      IF (FHS.EQ.CZEROR) GO TO 300
+C-----------------------------------------------------------------------
+C     COMPUTE R2=F(E). IF CABS(Z).GE.R2, USE FORWARD RECURRENCE TO
+C     DETERMINE THE BACKWARD INDEX K. R2=F(E) IS A STRAIGHT LINE ON
+C     12.LE.E.LE.60. E IS COMPUTED FROM 2**(-E)=B**(1-I1MACH(14))=
+C     TOL WHERE B IS THE BASE OF THE ARITHMETIC.
+C-----------------------------------------------------------------------
+      T1 = DBLE(FLOAT(I1MACH(14)-1))
+      T1 = T1*D1MACH(5)*3.321928094D0
+      T1 = DMAX1(T1,12.0D0)
+      T1 = DMIN1(T1,60.0D0)
+      T2 = TTH*T1 - 6.0D0
+      IF (ZR.NE.0.0D0) GO TO 130
+      T1 = HPI
+      GO TO 140
+  130 CONTINUE
+      T1 = DATAN(ZI/ZR)
+      T1 = DABS(T1)
+  140 CONTINUE
+      IF (T2.GT.CAZ) GO TO 170
+C-----------------------------------------------------------------------
+C     FORWARD RECURRENCE LOOP WHEN CABS(Z).GE.R2
+C-----------------------------------------------------------------------
+      ETEST = AK/(DPI*CAZ*TOL)
+      FK = CONER
+      IF (ETEST.LT.CONER) GO TO 180
+      FKS = CTWOR
+      CKR = CAZ + CAZ + CTWOR
+      P1R = CZEROR
+      P2R = CONER
+      DO 150 I=1,KMAX
+        AK = FHS/FKS
+        CBR = CKR/(FK+CONER)
+        PTR = P2R
+        P2R = CBR*P2R - P1R*AK
+        P1R = PTR
+        CKR = CKR + CTWOR
+        FKS = FKS + FK + FK + CTWOR
+        FHS = FHS + FK + FK
+        FK = FK + CONER
+        STR = DABS(P2R)*FK
+        IF (ETEST.LT.STR) GO TO 160
+  150 CONTINUE
+      GO TO 310
+  160 CONTINUE
+      FK = FK + SPI*T1*DSQRT(T2/CAZ)
+      FHS = DABS(0.25D0-DNU2)
+      GO TO 180
+  170 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE BACKWARD INDEX K FOR CABS(Z).LT.R2
+C-----------------------------------------------------------------------
+      A2 = DSQRT(CAZ)
+      AK = FPI*AK/(TOL*DSQRT(A2))
+      AA = 3.0D0*T1/(1.0D0+CAZ)
+      BB = 14.7D0*T1/(28.0D0+CAZ)
+      AK = (DLOG(AK)+CAZ*DCOS(AA)/(1.0D0+0.008D0*CAZ))/DCOS(BB)
+      FK = 0.12125D0*AK*AK/CAZ + 1.5D0
+  180 CONTINUE
+C-----------------------------------------------------------------------
+C     BACKWARD RECURRENCE LOOP FOR MILLER ALGORITHM
+C-----------------------------------------------------------------------
+      K = INT(SNGL(FK))
+      FK = DBLE(FLOAT(K))
+      FKS = FK*FK
+      P1R = CZEROR
+      P1I = CZEROI
+      P2R = TOL
+      P2I = CZEROI
+      CSR = P2R
+      CSI = P2I
+      DO 190 I=1,K
+        A1 = FKS - FK
+        AK = (FKS+FK)/(A1+FHS)
+        RAK = 2.0D0/(FK+CONER)
+        CBR = (FK+ZR)*RAK
+        CBI = ZI*RAK
+        PTR = P2R
+        PTI = P2I
+        P2R = (PTR*CBR-PTI*CBI-P1R)*AK
+        P2I = (PTI*CBR+PTR*CBI-P1I)*AK
+        P1R = PTR
+        P1I = PTI
+        CSR = CSR + P2R
+        CSI = CSI + P2I
+        FKS = A1 - FK + CONER
+        FK = FK - CONER
+  190 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE (P2/CS)=(P2/CABS(CS))*(CONJG(CS)/CABS(CS)) FOR BETTER
+C     SCALING
+C-----------------------------------------------------------------------
+      TM = XZABS(CSR,CSI)
+      PTR = 1.0D0/TM
+      S1R = P2R*PTR
+      S1I = P2I*PTR
+      CSR = CSR*PTR
+      CSI = -CSI*PTR
+      CALL ZMLT(COEFR, COEFI, S1R, S1I, STR, STI)
+      CALL ZMLT(STR, STI, CSR, CSI, S1R, S1I)
+      IF (INU.GT.0 .OR. N.GT.1) GO TO 200
+      ZDR = ZR
+      ZDI = ZI
+      IF(IFLAG.EQ.1) GO TO 270
+      GO TO 240
+  200 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE P1/P2=(P1/CABS(P2)*CONJG(P2)/CABS(P2) FOR SCALING
+C-----------------------------------------------------------------------
+      TM = XZABS(P2R,P2I)
+      PTR = 1.0D0/TM
+      P1R = P1R*PTR
+      P1I = P1I*PTR
+      P2R = P2R*PTR
+      P2I = -P2I*PTR
+      CALL ZMLT(P1R, P1I, P2R, P2I, PTR, PTI)
+      STR = DNU + 0.5D0 - PTR
+      STI = -PTI
+      CALL ZDIV(STR, STI, ZR, ZI, STR, STI)
+      STR = STR + 1.0D0
+      CALL ZMLT(STR, STI, S1R, S1I, S2R, S2I)
+C-----------------------------------------------------------------------
+C     FORWARD RECURSION ON THE THREE TERM RECURSION WITH RELATION WITH
+C     SCALING NEAR EXPONENT EXTREMES ON KFLAG=1 OR KFLAG=3
+C-----------------------------------------------------------------------
+  210 CONTINUE
+      STR = DNU + 1.0D0
+      CKR = STR*RZR
+      CKI = STR*RZI
+      IF (N.EQ.1) INU = INU - 1
+      IF (INU.GT.0) GO TO 220
+      IF (N.GT.1) GO TO 215
+      S1R = S2R
+      S1I = S2I
+  215 CONTINUE
+      ZDR = ZR
+      ZDI = ZI
+      IF(IFLAG.EQ.1) GO TO 270
+      GO TO 240
+  220 CONTINUE
+      INUB = 1
+      IF(IFLAG.EQ.1) GO TO 261
+  225 CONTINUE
+      P1R = CSRR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 230 I=INUB,INU
+        STR = S2R
+        STI = S2I
+        S2R = CKR*STR - CKI*STI + S1R
+        S2I = CKR*STI + CKI*STR + S1I
+        S1R = STR
+        S1I = STI
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        IF (KFLAG.GE.3) GO TO 230
+        P2R = S2R*P1R
+        P2I = S2I*P1R
+        STR = DABS(P2R)
+        STI = DABS(P2I)
+        P2M = DMAX1(STR,STI)
+        IF (P2M.LE.ASCLE) GO TO 230
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1R = S1R*P1R
+        S1I = S1I*P1R
+        S2R = P2R
+        S2I = P2I
+        STR = CSSR(KFLAG)
+        S1R = S1R*STR
+        S1I = S1I*STR
+        S2R = S2R*STR
+        S2I = S2I*STR
+        P1R = CSRR(KFLAG)
+  230 CONTINUE
+      IF (N.NE.1) GO TO 240
+      S1R = S2R
+      S1I = S2I
+  240 CONTINUE
+      STR = CSRR(KFLAG)
+      YR(1) = S1R*STR
+      YI(1) = S1I*STR
+      IF (N.EQ.1) RETURN
+      YR(2) = S2R*STR
+      YI(2) = S2I*STR
+      IF (N.EQ.2) RETURN
+      KK = 2
+  250 CONTINUE
+      KK = KK + 1
+      IF (KK.GT.N) RETURN
+      P1R = CSRR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 260 I=KK,N
+        P2R = S2R
+        P2I = S2I
+        S2R = CKR*P2R - CKI*P2I + S1R
+        S2I = CKI*P2R + CKR*P2I + S1I
+        S1R = P2R
+        S1I = P2I
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        P2R = S2R*P1R
+        P2I = S2I*P1R
+        YR(I) = P2R
+        YI(I) = P2I
+        IF (KFLAG.GE.3) GO TO 260
+        STR = DABS(P2R)
+        STI = DABS(P2I)
+        P2M = DMAX1(STR,STI)
+        IF (P2M.LE.ASCLE) GO TO 260
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1R = S1R*P1R
+        S1I = S1I*P1R
+        S2R = P2R
+        S2I = P2I
+        STR = CSSR(KFLAG)
+        S1R = S1R*STR
+        S1I = S1I*STR
+        S2R = S2R*STR
+        S2I = S2I*STR
+        P1R = CSRR(KFLAG)
+  260 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     IFLAG=1 CASES, FORWARD RECURRENCE ON SCALED VALUES ON UNDERFLOW
+C-----------------------------------------------------------------------
+  261 CONTINUE
+      HELIM = 0.5D0*ELIM
+      ELM = DEXP(-ELIM)
+      CELMR = ELM
+      ASCLE = BRY(1)
+      ZDR = ZR
+      ZDI = ZI
+      IC = -1
+      J = 2
+      DO 262 I=1,INU
+        STR = S2R
+        STI = S2I
+        S2R = STR*CKR-STI*CKI+S1R
+        S2I = STI*CKR+STR*CKI+S1I
+        S1R = STR
+        S1I = STI
+        CKR = CKR+RZR
+        CKI = CKI+RZI
+        AS = XZABS(S2R,S2I)
+        ALAS = DLOG(AS)
+        P2R = -ZDR+ALAS
+        IF(P2R.LT.(-ELIM)) GO TO 263
+        CALL XZLOG(S2R,S2I,STR,STI,IDUM)
+        P2R = -ZDR+STR
+        P2I = -ZDI+STI
+        P2M = DEXP(P2R)/TOL
+        P1R = P2M*DCOS(P2I)
+        P1I = P2M*DSIN(P2I)
+        CALL ZUCHK(P1R,P1I,NW,ASCLE,TOL)
+        IF(NW.NE.0) GO TO 263
+        J = 3 - J
+        CYR(J) = P1R
+        CYI(J) = P1I
+        IF(IC.EQ.(I-1)) GO TO 264
+        IC = I
+        GO TO 262
+  263   CONTINUE
+        IF(ALAS.LT.HELIM) GO TO 262
+        ZDR = ZDR-ELIM
+        S1R = S1R*CELMR
+        S1I = S1I*CELMR
+        S2R = S2R*CELMR
+        S2I = S2I*CELMR
+  262 CONTINUE
+      IF(N.NE.1) GO TO 270
+      S1R = S2R
+      S1I = S2I
+      GO TO 270
+  264 CONTINUE
+      KFLAG = 1
+      INUB = I+1
+      S2R = CYR(J)
+      S2I = CYI(J)
+      J = 3 - J
+      S1R = CYR(J)
+      S1I = CYI(J)
+      IF(INUB.LE.INU) GO TO 225
+      IF(N.NE.1) GO TO 240
+      S1R = S2R
+      S1I = S2I
+      GO TO 240
+  270 CONTINUE
+      YR(1) = S1R
+      YI(1) = S1I
+      IF(N.EQ.1) GO TO 280
+      YR(2) = S2R
+      YI(2) = S2I
+  280 CONTINUE
+      ASCLE = BRY(1)
+      CALL ZKSCL(ZDR,ZDI,FNU,N,YR,YI,NZ,RZR,RZI,ASCLE,TOL,ELIM)
+      INU = N - NZ
+      IF (INU.LE.0) RETURN
+      KK = NZ + 1
+      S1R = YR(KK)
+      S1I = YI(KK)
+      YR(KK) = S1R*CSRR(1)
+      YI(KK) = S1I*CSRR(1)
+      IF (INU.EQ.1) RETURN
+      KK = NZ + 2
+      S2R = YR(KK)
+      S2I = YI(KK)
+      YR(KK) = S2R*CSRR(1)
+      YI(KK) = S2I*CSRR(1)
+      IF (INU.EQ.2) RETURN
+      T2 = FNU + DBLE(FLOAT(KK-1))
+      CKR = T2*RZR
+      CKI = T2*RZI
+      KFLAG = 1
+      GO TO 250
+  290 CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE BY DEXP(Z), IFLAG = 1 CASES
+C-----------------------------------------------------------------------
+      KODED = 2
+      IFLAG = 1
+      KFLAG = 2
+      GO TO 120
+C-----------------------------------------------------------------------
+C     FNU=HALF ODD INTEGER CASE, DNU=-0.5
+C-----------------------------------------------------------------------
+  300 CONTINUE
+      S1R = COEFR
+      S1I = COEFI
+      S2R = COEFR
+      S2I = COEFI
+      GO TO 210
+C
+C
+  310 CONTINUE
+      NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/zbuni.f b/libcruft/amos/zbuni.f
new file mode 100644
index 0000000..d42ff48
--- /dev/null
+++ b/libcruft/amos/zbuni.f
@@ -0,0 +1,174 @@
+      SUBROUTINE ZBUNI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, NUI, NLAST,
+     * FNUL, TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  ZBUNI
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZBUNI COMPUTES THE I BESSEL FUNCTION FOR LARGE CABS(Z).GT.
+C     FNUL AND FNU+N-1.LT.FNUL. THE ORDER IS INCREASED FROM
+C     FNU+N-1 GREATER THAN FNUL BY ADDING NUI AND COMPUTING
+C     ACCORDING TO THE UNIFORM ASYMPTOTIC EXPANSION FOR I(FNU,Z)
+C     ON IFORM=1 AND THE EXPANSION FOR J(FNU,Z) ON IFORM=2
+C
+C***ROUTINES CALLED  ZUNI1,ZUNI2,XZABS,D1MACH
+C***END PROLOGUE  ZBUNI
+C     COMPLEX CSCL,CSCR,CY,RZ,ST,S1,S2,Y,Z
+      DOUBLE PRECISION ALIM, AX, AY, CSCLR, CSCRR, CYI, CYR, DFNU,
+     * ELIM, FNU, FNUI, FNUL, GNU, RAZ, RZI, RZR, STI, STR, S1I, S1R,
+     * S2I, S2R, TOL, YI, YR, ZI, ZR, XZABS, ASCLE, BRY, C1R, C1I, C1M,
+     * D1MACH
+      INTEGER I, IFLAG, IFORM, K, KODE, N, NL, NLAST, NUI, NW, NZ
+      DIMENSION YR(N), YI(N), CYR(2), CYI(2), BRY(3)
+      NZ = 0
+      AX = DABS(ZR)*1.7321D0
+      AY = DABS(ZI)
+      IFORM = 1
+      IF (AY.GT.AX) IFORM = 2
+      IF (NUI.EQ.0) GO TO 60
+      FNUI = DBLE(FLOAT(NUI))
+      DFNU = FNU + DBLE(FLOAT(N-1))
+      GNU = DFNU + FNUI
+      IF (IFORM.EQ.2) GO TO 10
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR I(FNU,Z) FOR LARGE FNU APPLIED IN
+C     -PI/3.LE.ARG(Z).LE.PI/3
+C-----------------------------------------------------------------------
+      CALL ZUNI1(ZR, ZI, GNU, KODE, 2, CYR, CYI, NW, NLAST, FNUL, TOL,
+     * ELIM, ALIM)
+      GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR J(FNU,Z*EXP(M*HPI)) FOR LARGE FNU
+C     APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I
+C     AND HPI=PI/2
+C-----------------------------------------------------------------------
+      CALL ZUNI2(ZR, ZI, GNU, KODE, 2, CYR, CYI, NW, NLAST, FNUL, TOL,
+     * ELIM, ALIM)
+   20 CONTINUE
+      IF (NW.LT.0) GO TO 50
+      IF (NW.NE.0) GO TO 90
+      STR = XZABS(CYR(1),CYI(1))
+C----------------------------------------------------------------------
+C     SCALE BACKWARD RECURRENCE, BRY(3) IS DEFINED BUT NEVER USED
+C----------------------------------------------------------------------
+      BRY(1)=1.0D+3*D1MACH(1)/TOL
+      BRY(2) = 1.0D0/BRY(1)
+      BRY(3) = BRY(2)
+      IFLAG = 2
+      ASCLE = BRY(2)
+      CSCLR = 1.0D0
+      IF (STR.GT.BRY(1)) GO TO 21
+      IFLAG = 1
+      ASCLE = BRY(1)
+      CSCLR = 1.0D0/TOL
+      GO TO 25
+   21 CONTINUE
+      IF (STR.LT.BRY(2)) GO TO 25
+      IFLAG = 3
+      ASCLE=BRY(3)
+      CSCLR = TOL
+   25 CONTINUE
+      CSCRR = 1.0D0/CSCLR
+      S1R = CYR(2)*CSCLR
+      S1I = CYI(2)*CSCLR
+      S2R = CYR(1)*CSCLR
+      S2I = CYI(1)*CSCLR
+      RAZ = 1.0D0/XZABS(ZR,ZI)
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      RZR = (STR+STR)*RAZ
+      RZI = (STI+STI)*RAZ
+      DO 30 I=1,NUI
+        STR = S2R
+        STI = S2I
+        S2R = (DFNU+FNUI)*(RZR*STR-RZI*STI) + S1R
+        S2I = (DFNU+FNUI)*(RZR*STI+RZI*STR) + S1I
+        S1R = STR
+        S1I = STI
+        FNUI = FNUI - 1.0D0
+        IF (IFLAG.GE.3) GO TO 30
+        STR = S2R*CSCRR
+        STI = S2I*CSCRR
+        C1R = DABS(STR)
+        C1I = DABS(STI)
+        C1M = DMAX1(C1R,C1I)
+        IF (C1M.LE.ASCLE) GO TO 30
+        IFLAG = IFLAG+1
+        ASCLE = BRY(IFLAG)
+        S1R = S1R*CSCRR
+        S1I = S1I*CSCRR
+        S2R = STR
+        S2I = STI
+        CSCLR = CSCLR*TOL
+        CSCRR = 1.0D0/CSCLR
+        S1R = S1R*CSCLR
+        S1I = S1I*CSCLR
+        S2R = S2R*CSCLR
+        S2I = S2I*CSCLR
+   30 CONTINUE
+      YR(N) = S2R*CSCRR
+      YI(N) = S2I*CSCRR
+      IF (N.EQ.1) RETURN
+      NL = N - 1
+      FNUI = DBLE(FLOAT(NL))
+      K = NL
+      DO 40 I=1,NL
+        STR = S2R
+        STI = S2I
+        S2R = (FNU+FNUI)*(RZR*STR-RZI*STI) + S1R
+        S2I = (FNU+FNUI)*(RZR*STI+RZI*STR) + S1I
+        S1R = STR
+        S1I = STI
+        STR = S2R*CSCRR
+        STI = S2I*CSCRR
+        YR(K) = STR
+        YI(K) = STI
+        FNUI = FNUI - 1.0D0
+        K = K - 1
+        IF (IFLAG.GE.3) GO TO 40
+        C1R = DABS(STR)
+        C1I = DABS(STI)
+        C1M = DMAX1(C1R,C1I)
+        IF (C1M.LE.ASCLE) GO TO 40
+        IFLAG = IFLAG+1
+        ASCLE = BRY(IFLAG)
+        S1R = S1R*CSCRR
+        S1I = S1I*CSCRR
+        S2R = STR
+        S2I = STI
+        CSCLR = CSCLR*TOL
+        CSCRR = 1.0D0/CSCLR
+        S1R = S1R*CSCLR
+        S1I = S1I*CSCLR
+        S2R = S2R*CSCLR
+        S2I = S2I*CSCLR
+   40 CONTINUE
+      RETURN
+   50 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+   60 CONTINUE
+      IF (IFORM.EQ.2) GO TO 70
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR I(FNU,Z) FOR LARGE FNU APPLIED IN
+C     -PI/3.LE.ARG(Z).LE.PI/3
+C-----------------------------------------------------------------------
+      CALL ZUNI1(ZR, ZI, FNU, KODE, N, YR, YI, NW, NLAST, FNUL, TOL,
+     * ELIM, ALIM)
+      GO TO 80
+   70 CONTINUE
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR J(FNU,Z*EXP(M*HPI)) FOR LARGE FNU
+C     APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I
+C     AND HPI=PI/2
+C-----------------------------------------------------------------------
+      CALL ZUNI2(ZR, ZI, FNU, KODE, N, YR, YI, NW, NLAST, FNUL, TOL,
+     * ELIM, ALIM)
+   80 CONTINUE
+      IF (NW.LT.0) GO TO 50
+      NZ = NW
+      RETURN
+   90 CONTINUE
+      NLAST = N
+      RETURN
+      END
diff --git a/libcruft/amos/zbunk.f b/libcruft/amos/zbunk.f
new file mode 100644
index 0000000..b20b79f
--- /dev/null
+++ b/libcruft/amos/zbunk.f
@@ -0,0 +1,35 @@
+      SUBROUTINE ZBUNK(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  ZBUNK
+C***REFER TO  ZBESK,ZBESH
+C
+C     ZBUNK COMPUTES THE K BESSEL FUNCTION FOR FNU.GT.FNUL.
+C     ACCORDING TO THE UNIFORM ASYMPTOTIC EXPANSION FOR K(FNU,Z)
+C     IN ZUNK1 AND THE EXPANSION FOR H(2,FNU,Z) IN ZUNK2
+C
+C***ROUTINES CALLED  ZUNK1,ZUNK2
+C***END PROLOGUE  ZBUNK
+C     COMPLEX Y,Z
+      DOUBLE PRECISION ALIM, AX, AY, ELIM, FNU, TOL, YI, YR, ZI, ZR
+      INTEGER KODE, MR, N, NZ
+      DIMENSION YR(N), YI(N)
+      NZ = 0
+      AX = DABS(ZR)*1.7321D0
+      AY = DABS(ZI)
+      IF (AY.GT.AX) GO TO 10
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR K(FNU,Z) FOR LARGE FNU APPLIED IN
+C     -PI/3.LE.ARG(Z).LE.PI/3
+C-----------------------------------------------------------------------
+      CALL ZUNK1(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, ALIM)
+      GO TO 20
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ASYMPTOTIC EXPANSION FOR H(2,FNU,Z*EXP(M*HPI)) FOR LARGE FNU
+C     APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I
+C     AND HPI=PI/2
+C-----------------------------------------------------------------------
+      CALL ZUNK2(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, ALIM)
+   20 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/zdiv.f b/libcruft/amos/zdiv.f
new file mode 100644
index 0000000..34a6694
--- /dev/null
+++ b/libcruft/amos/zdiv.f
@@ -0,0 +1,19 @@
+      SUBROUTINE ZDIV(AR, AI, BR, BI, CR, CI)
+C***BEGIN PROLOGUE  ZDIV
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY
+C
+C     DOUBLE PRECISION COMPLEX DIVIDE C=A/B.
+C
+C***ROUTINES CALLED  XZABS
+C***END PROLOGUE  ZDIV
+      DOUBLE PRECISION AR, AI, BR, BI, CR, CI, BM, CA, CB, CC, CD
+      DOUBLE PRECISION XZABS
+      BM = 1.0D0/XZABS(BR,BI)
+      CC = BR*BM
+      CD = BI*BM
+      CA = (AR*CC+AI*CD)*BM
+      CB = (AI*CC-AR*CD)*BM
+      CR = CA
+      CI = CB
+      RETURN
+      END
diff --git a/libcruft/amos/zkscl.f b/libcruft/amos/zkscl.f
new file mode 100644
index 0000000..62d8342
--- /dev/null
+++ b/libcruft/amos/zkscl.f
@@ -0,0 +1,121 @@
+      SUBROUTINE ZKSCL(ZRR,ZRI,FNU,N,YR,YI,NZ,RZR,RZI,ASCLE,TOL,ELIM)
+C***BEGIN PROLOGUE  ZKSCL
+C***REFER TO  ZBESK
+C
+C     SET K FUNCTIONS TO ZERO ON UNDERFLOW, CONTINUE RECURRENCE
+C     ON SCALED FUNCTIONS UNTIL TWO MEMBERS COME ON SCALE, THEN
+C     RETURN WITH MIN(NZ+2,N) VALUES SCALED BY 1/TOL.
+C
+C***ROUTINES CALLED  ZUCHK,XZABS,XZLOG
+C***END PROLOGUE  ZKSCL
+C     COMPLEX CK,CS,CY,CZERO,RZ,S1,S2,Y,ZR,ZD,CELM
+      DOUBLE PRECISION ACS, AS, ASCLE, CKI, CKR, CSI, CSR, CYI,
+     * CYR, ELIM, FN, FNU, RZI, RZR, STR, S1I, S1R, S2I,
+     * S2R, TOL, YI, YR, ZEROI, ZEROR, ZRI, ZRR, XZABS,
+     * ZDR, ZDI, CELMR, ELM, HELIM, ALAS
+      INTEGER I, IC, IDUM, KK, N, NN, NW, NZ
+      DIMENSION YR(N), YI(N), CYR(2), CYI(2)
+      DATA ZEROR,ZEROI / 0.0D0 , 0.0D0 /
+C
+      NZ = 0
+      IC = 0
+      NN = MIN0(2,N)
+      DO 10 I=1,NN
+        S1R = YR(I)
+        S1I = YI(I)
+        CYR(I) = S1R
+        CYI(I) = S1I
+        AS = XZABS(S1R,S1I)
+        ACS = -ZRR + DLOG(AS)
+        NZ = NZ + 1
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+        IF (ACS.LT.(-ELIM)) GO TO 10
+        CALL XZLOG(S1R, S1I, CSR, CSI, IDUM)
+        CSR = CSR - ZRR
+        CSI = CSI - ZRI
+        STR = DEXP(CSR)/TOL
+        CSR = STR*DCOS(CSI)
+        CSI = STR*DSIN(CSI)
+        CALL ZUCHK(CSR, CSI, NW, ASCLE, TOL)
+        IF (NW.NE.0) GO TO 10
+        YR(I) = CSR
+        YI(I) = CSI
+        IC = I
+        NZ = NZ - 1
+   10 CONTINUE
+      IF (N.EQ.1) RETURN
+      IF (IC.GT.1) GO TO 20
+      YR(1) = ZEROR
+      YI(1) = ZEROI
+      NZ = 2
+   20 CONTINUE
+      IF (N.EQ.2) RETURN
+      IF (NZ.EQ.0) RETURN
+      FN = FNU + 1.0D0
+      CKR = FN*RZR
+      CKI = FN*RZI
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      HELIM = 0.5D0*ELIM
+      ELM = DEXP(-ELIM)
+      CELMR = ELM
+      ZDR = ZRR
+      ZDI = ZRI
+C
+C     FIND TWO CONSECUTIVE Y VALUES ON SCALE. SCALE RECURRENCE IF
+C     S2 GETS LARGER THAN EXP(ELIM/2)
+C
+      DO 30 I=3,N
+        KK = I
+        CSR = S2R
+        CSI = S2I
+        S2R = CKR*CSR - CKI*CSI + S1R
+        S2I = CKI*CSR + CKR*CSI + S1I
+        S1R = CSR
+        S1I = CSI
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        AS = XZABS(S2R,S2I)
+        ALAS = DLOG(AS)
+        ACS = -ZDR + ALAS
+        NZ = NZ + 1
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+        IF (ACS.LT.(-ELIM)) GO TO 25
+        CALL XZLOG(S2R, S2I, CSR, CSI, IDUM)
+        CSR = CSR - ZDR
+        CSI = CSI - ZDI
+        STR = DEXP(CSR)/TOL
+        CSR = STR*DCOS(CSI)
+        CSI = STR*DSIN(CSI)
+        CALL ZUCHK(CSR, CSI, NW, ASCLE, TOL)
+        IF (NW.NE.0) GO TO 25
+        YR(I) = CSR
+        YI(I) = CSI
+        NZ = NZ - 1
+        IF (IC.EQ.KK-1) GO TO 40
+        IC = KK
+        GO TO 30
+   25   CONTINUE
+        IF(ALAS.LT.HELIM) GO TO 30
+        ZDR = ZDR - ELIM
+        S1R = S1R*CELMR
+        S1I = S1I*CELMR
+        S2R = S2R*CELMR
+        S2I = S2I*CELMR
+   30 CONTINUE
+      NZ = N
+      IF(IC.EQ.N) NZ=N-1
+      GO TO 45
+   40 CONTINUE
+      NZ = KK - 2
+   45 CONTINUE
+      DO 50 I=1,NZ
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+   50 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/zmlri.f b/libcruft/amos/zmlri.f
new file mode 100644
index 0000000..2f85bb5
--- /dev/null
+++ b/libcruft/amos/zmlri.f
@@ -0,0 +1,204 @@
+      SUBROUTINE ZMLRI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL)
+C***BEGIN PROLOGUE  ZMLRI
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY THE
+C     MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES.
+C
+C***ROUTINES CALLED  DGAMLN,D1MACH,XZABS,XZEXP,XZLOG,ZMLT
+C***END PROLOGUE  ZMLRI
+C     COMPLEX CK,CNORM,CONE,CTWO,CZERO,PT,P1,P2,RZ,SUM,Y,Z
+      DOUBLE PRECISION ACK, AK, AP, AT, AZ, BK, CKI, CKR, CNORMI,
+     * CNORMR, CONEI, CONER, FKAP, FKK, FLAM, FNF, FNU, PTI, PTR, P1I,
+     * P1R, P2I, P2R, RAZ, RHO, RHO2, RZI, RZR, SCLE, STI, STR, SUMI,
+     * SUMR, TFNF, TOL, TST, YI, YR, ZEROI, ZEROR, ZI, ZR, DGAMLN,
+     * D1MACH, XZABS
+      INTEGER I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, KODE, M, N, NZ
+      DIMENSION YR(N), YI(N)
+      DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
+      SCLE = D1MACH(1)/TOL
+      NZ=0
+      AZ = XZABS(ZR,ZI)
+      IAZ = INT(SNGL(AZ))
+      IFNU = INT(SNGL(FNU))
+      INU = IFNU + N - 1
+      AT = DBLE(FLOAT(IAZ)) + 1.0D0
+      RAZ = 1.0D0/AZ
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      CKR = STR*AT*RAZ
+      CKI = STI*AT*RAZ
+      RZR = (STR+STR)*RAZ
+      RZI = (STI+STI)*RAZ
+      P1R = ZEROR
+      P1I = ZEROI
+      P2R = CONER
+      P2I = CONEI
+      ACK = (AT+1.0D0)*RAZ
+      RHO = ACK + DSQRT(ACK*ACK-1.0D0)
+      RHO2 = RHO*RHO
+      TST = (RHO2+RHO2)/((RHO2-1.0D0)*(RHO-1.0D0))
+      TST = TST/TOL
+C-----------------------------------------------------------------------
+C     COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES
+C-----------------------------------------------------------------------
+      AK = AT
+      DO 10 I=1,80
+        PTR = P2R
+        PTI = P2I
+        P2R = P1R - (CKR*PTR-CKI*PTI)
+        P2I = P1I - (CKI*PTR+CKR*PTI)
+        P1R = PTR
+        P1I = PTI
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        AP = XZABS(P2R,P2I)
+        IF (AP.GT.TST*AK*AK) GO TO 20
+        AK = AK + 1.0D0
+   10 CONTINUE
+      GO TO 110
+   20 CONTINUE
+      I = I + 1
+      K = 0
+      IF (INU.LT.IAZ) GO TO 40
+C-----------------------------------------------------------------------
+C     COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS
+C-----------------------------------------------------------------------
+      P1R = ZEROR
+      P1I = ZEROI
+      P2R = CONER
+      P2I = CONEI
+      AT = DBLE(FLOAT(INU)) + 1.0D0
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      CKR = STR*AT*RAZ
+      CKI = STI*AT*RAZ
+      ACK = AT*RAZ
+      TST = DSQRT(ACK/TOL)
+      ITIME = 1
+      DO 30 K=1,80
+        PTR = P2R
+        PTI = P2I
+        P2R = P1R - (CKR*PTR-CKI*PTI)
+        P2I = P1I - (CKR*PTI+CKI*PTR)
+        P1R = PTR
+        P1I = PTI
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        AP = XZABS(P2R,P2I)
+        IF (AP.LT.TST) GO TO 30
+        IF (ITIME.EQ.2) GO TO 40
+        ACK = XZABS(CKR,CKI)
+        FLAM = ACK + DSQRT(ACK*ACK-1.0D0)
+        FKAP = AP/XZABS(P1R,P1I)
+        RHO = DMIN1(FLAM,FKAP)
+        TST = TST*DSQRT(RHO/(RHO*RHO-1.0D0))
+        ITIME = 2
+   30 CONTINUE
+      GO TO 110
+   40 CONTINUE
+C-----------------------------------------------------------------------
+C     BACKWARD RECURRENCE AND SUM NORMALIZING RELATION
+C-----------------------------------------------------------------------
+      K = K + 1
+      KK = MAX0(I+IAZ,K+INU)
+      FKK = DBLE(FLOAT(KK))
+      P1R = ZEROR
+      P1I = ZEROI
+C-----------------------------------------------------------------------
+C     SCALE P2 AND SUM BY SCLE
+C-----------------------------------------------------------------------
+      P2R = SCLE
+      P2I = ZEROI
+      FNF = FNU - DBLE(FLOAT(IFNU))
+      TFNF = FNF + FNF
+      BK = DGAMLN(FKK+TFNF+1.0D0,IDUM) - DGAMLN(FKK+1.0D0,IDUM) -
+     * DGAMLN(TFNF+1.0D0,IDUM)
+      BK = DEXP(BK)
+      SUMR = ZEROR
+      SUMI = ZEROI
+      KM = KK - INU
+      DO 50 I=1,KM
+        PTR = P2R
+        PTI = P2I
+        P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI)
+        P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI)
+        P1R = PTR
+        P1I = PTI
+        AK = 1.0D0 - TFNF/(FKK+TFNF)
+        ACK = BK*AK
+        SUMR = SUMR + (ACK+BK)*P1R
+        SUMI = SUMI + (ACK+BK)*P1I
+        BK = ACK
+        FKK = FKK - 1.0D0
+   50 CONTINUE
+      YR(N) = P2R
+      YI(N) = P2I
+      IF (N.EQ.1) GO TO 70
+      DO 60 I=2,N
+        PTR = P2R
+        PTI = P2I
+        P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI)
+        P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI)
+        P1R = PTR
+        P1I = PTI
+        AK = 1.0D0 - TFNF/(FKK+TFNF)
+        ACK = BK*AK
+        SUMR = SUMR + (ACK+BK)*P1R
+        SUMI = SUMI + (ACK+BK)*P1I
+        BK = ACK
+        FKK = FKK - 1.0D0
+        M = N - I + 1
+        YR(M) = P2R
+        YI(M) = P2I
+   60 CONTINUE
+   70 CONTINUE
+      IF (IFNU.LE.0) GO TO 90
+      DO 80 I=1,IFNU
+        PTR = P2R
+        PTI = P2I
+        P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI)
+        P2I = P1I + (FKK+FNF)*(RZR*PTI+RZI*PTR)
+        P1R = PTR
+        P1I = PTI
+        AK = 1.0D0 - TFNF/(FKK+TFNF)
+        ACK = BK*AK
+        SUMR = SUMR + (ACK+BK)*P1R
+        SUMI = SUMI + (ACK+BK)*P1I
+        BK = ACK
+        FKK = FKK - 1.0D0
+   80 CONTINUE
+   90 CONTINUE
+      PTR = ZR
+      PTI = ZI
+      IF (KODE.EQ.2) PTR = ZEROR
+      CALL XZLOG(RZR, RZI, STR, STI, IDUM)
+      P1R = -FNF*STR + PTR
+      P1I = -FNF*STI + PTI
+      AP = DGAMLN(1.0D0+FNF,IDUM)
+      PTR = P1R - AP
+      PTI = P1I
+C-----------------------------------------------------------------------
+C     THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW
+C     IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES
+C-----------------------------------------------------------------------
+      P2R = P2R + SUMR
+      P2I = P2I + SUMI
+      AP = XZABS(P2R,P2I)
+      P1R = 1.0D0/AP
+      CALL XZEXP(PTR, PTI, STR, STI)
+      CKR = STR*P1R
+      CKI = STI*P1R
+      PTR = P2R*P1R
+      PTI = -P2I*P1R
+      CALL ZMLT(CKR, CKI, PTR, PTI, CNORMR, CNORMI)
+      DO 100 I=1,N
+        STR = YR(I)*CNORMR - YI(I)*CNORMI
+        YI(I) = YR(I)*CNORMI + YI(I)*CNORMR
+        YR(I) = STR
+  100 CONTINUE
+      RETURN
+  110 CONTINUE
+      NZ=-2
+      RETURN
+      END
diff --git a/libcruft/amos/zmlt.f b/libcruft/amos/zmlt.f
new file mode 100644
index 0000000..3bde7d3
--- /dev/null
+++ b/libcruft/amos/zmlt.f
@@ -0,0 +1,15 @@
+      SUBROUTINE ZMLT(AR, AI, BR, BI, CR, CI)
+C***BEGIN PROLOGUE  ZMLT
+C***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY
+C
+C     DOUBLE PRECISION COMPLEX MULTIPLY, C=A*B.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  ZMLT
+      DOUBLE PRECISION AR, AI, BR, BI, CR, CI, CA, CB
+      CA = AR*BR - AI*BI
+      CB = AR*BI + AI*BR
+      CR = CA
+      CI = CB
+      RETURN
+      END
diff --git a/libcruft/amos/zrati.f b/libcruft/amos/zrati.f
new file mode 100644
index 0000000..fb2a377
--- /dev/null
+++ b/libcruft/amos/zrati.f
@@ -0,0 +1,132 @@
+      SUBROUTINE ZRATI(ZR, ZI, FNU, N, CYR, CYI, TOL)
+C***BEGIN PROLOGUE  ZRATI
+C***REFER TO  ZBESI,ZBESK,ZBESH
+C
+C     ZRATI COMPUTES RATIOS OF I BESSEL FUNCTIONS BY BACKWARD
+C     RECURRENCE.  THE STARTING INDEX IS DETERMINED BY FORWARD
+C     RECURRENCE AS DESCRIBED IN J. RES. OF NAT. BUR. OF STANDARDS-B,
+C     MATHEMATICAL SCIENCES, VOL 77B, P111-114, SEPTEMBER, 1973,
+C     BESSEL FUNCTIONS I AND J OF COMPLEX ARGUMENT AND INTEGER ORDER,
+C     BY D. J. SOOKNE.
+C
+C***ROUTINES CALLED  XZABS,ZDIV
+C***END PROLOGUE  ZRATI
+C     COMPLEX Z,CY(1),CONE,CZERO,P1,P2,T1,RZ,PT,CDFNU
+      DOUBLE PRECISION AK, AMAGZ, AP1, AP2, ARG, AZ, CDFNUI, CDFNUR,
+     * CONEI, CONER, CYI, CYR, CZEROI, CZEROR, DFNU, FDNU, FLAM, FNU,
+     * FNUP, PTI, PTR, P1I, P1R, P2I, P2R, RAK, RAP1, RHO, RT2, RZI,
+     * RZR, TEST, TEST1, TOL, TTI, TTR, T1I, T1R, ZI, ZR, XZABS
+      INTEGER I, ID, IDNU, INU, ITIME, K, KK, MAGZ, N
+      DIMENSION CYR(N), CYI(N)
+      DATA CZEROR,CZEROI,CONER,CONEI,RT2/
+     1 0.0D0, 0.0D0, 1.0D0, 0.0D0, 1.41421356237309505D0 /
+      AZ = XZABS(ZR,ZI)
+      INU = INT(SNGL(FNU))
+      IDNU = INU + N - 1
+      MAGZ = INT(SNGL(AZ))
+      AMAGZ = DBLE(FLOAT(MAGZ+1))
+      FDNU = DBLE(FLOAT(IDNU))
+      FNUP = DMAX1(AMAGZ,FDNU)
+      ID = IDNU - MAGZ - 1
+      ITIME = 1
+      K = 1
+      PTR = 1.0D0/AZ
+      RZR = PTR*(ZR+ZR)*PTR
+      RZI = -PTR*(ZI+ZI)*PTR
+      T1R = RZR*FNUP
+      T1I = RZI*FNUP
+      P2R = -T1R
+      P2I = -T1I
+      P1R = CONER
+      P1I = CONEI
+      T1R = T1R + RZR
+      T1I = T1I + RZI
+      IF (ID.GT.0) ID = 0
+      AP2 = XZABS(P2R,P2I)
+      AP1 = XZABS(P1R,P1I)
+C-----------------------------------------------------------------------
+C     THE OVERFLOW TEST ON K(FNU+I-1,Z) BEFORE THE CALL TO CBKNU
+C     GUARANTEES THAT P2 IS ON SCALE. SCALE TEST1 AND ALL SUBSEQUENT
+C     P2 VALUES BY AP1 TO ENSURE THAT AN OVERFLOW DOES NOT OCCUR
+C     PREMATURELY.
+C-----------------------------------------------------------------------
+      ARG = (AP2+AP2)/(AP1*TOL)
+      TEST1 = DSQRT(ARG)
+      TEST = TEST1
+      RAP1 = 1.0D0/AP1
+      P1R = P1R*RAP1
+      P1I = P1I*RAP1
+      P2R = P2R*RAP1
+      P2I = P2I*RAP1
+      AP2 = AP2*RAP1
+   10 CONTINUE
+      K = K + 1
+      AP1 = AP2
+      PTR = P2R
+      PTI = P2I
+      P2R = P1R - (T1R*PTR-T1I*PTI)
+      P2I = P1I - (T1R*PTI+T1I*PTR)
+      P1R = PTR
+      P1I = PTI
+      T1R = T1R + RZR
+      T1I = T1I + RZI
+      AP2 = XZABS(P2R,P2I)
+      IF (AP1.LE.TEST) GO TO 10
+      IF (ITIME.EQ.2) GO TO 20
+      AK = XZABS(T1R,T1I)*0.5D0
+      FLAM = AK + DSQRT(AK*AK-1.0D0)
+      RHO = DMIN1(AP2/AP1,FLAM)
+      TEST = TEST1*DSQRT(RHO/(RHO*RHO-1.0D0))
+      ITIME = 2
+      GO TO 10
+   20 CONTINUE
+      KK = K + 1 - ID
+      AK = DBLE(FLOAT(KK))
+      T1R = AK
+      T1I = CZEROI
+      DFNU = FNU + DBLE(FLOAT(N-1))
+      P1R = 1.0D0/AP2
+      P1I = CZEROI
+      P2R = CZEROR
+      P2I = CZEROI
+      DO 30 I=1,KK
+        PTR = P1R
+        PTI = P1I
+        RAP1 = DFNU + T1R
+        TTR = RZR*RAP1
+        TTI = RZI*RAP1
+        P1R = (PTR*TTR-PTI*TTI) + P2R
+        P1I = (PTR*TTI+PTI*TTR) + P2I
+        P2R = PTR
+        P2I = PTI
+        T1R = T1R - CONER
+   30 CONTINUE
+      IF (P1R.NE.CZEROR .OR. P1I.NE.CZEROI) GO TO 40
+      P1R = TOL
+      P1I = TOL
+   40 CONTINUE
+      CALL ZDIV(P2R, P2I, P1R, P1I, CYR(N), CYI(N))
+      IF (N.EQ.1) RETURN
+      K = N - 1
+      AK = DBLE(FLOAT(K))
+      T1R = AK
+      T1I = CZEROI
+      CDFNUR = FNU*RZR
+      CDFNUI = FNU*RZI
+      DO 60 I=2,N
+        PTR = CDFNUR + (T1R*RZR-T1I*RZI) + CYR(K+1)
+        PTI = CDFNUI + (T1R*RZI+T1I*RZR) + CYI(K+1)
+        AK = XZABS(PTR,PTI)
+        IF (AK.NE.CZEROR) GO TO 50
+        PTR = TOL
+        PTI = TOL
+        AK = TOL*RT2
+   50   CONTINUE
+        RAK = CONER/AK
+        CYR(K) = RAK*PTR*RAK
+        CYI(K) = -RAK*PTI*RAK
+        T1R = T1R - CONER
+        K = K - 1
+   60 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/zs1s2.f b/libcruft/amos/zs1s2.f
new file mode 100644
index 0000000..59c9377
--- /dev/null
+++ b/libcruft/amos/zs1s2.f
@@ -0,0 +1,49 @@
+      SUBROUTINE ZS1S2(ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM,
+     * IUF)
+C***BEGIN PROLOGUE  ZS1S2
+C***REFER TO  ZBESK,ZAIRY
+C
+C     ZS1S2 TESTS FOR A POSSIBLE UNDERFLOW RESULTING FROM THE
+C     ADDITION OF THE I AND K FUNCTIONS IN THE ANALYTIC CON-
+C     TINUATION FORMULA WHERE S1=K FUNCTION AND S2=I FUNCTION.
+C     ON KODE=1 THE I AND K FUNCTIONS ARE DIFFERENT ORDERS OF
+C     MAGNITUDE, BUT FOR KODE=2 THEY CAN BE OF THE SAME ORDER
+C     OF MAGNITUDE AND THE MAXIMUM MUST BE AT LEAST ONE
+C     PRECISION ABOVE THE UNDERFLOW LIMIT.
+C
+C***ROUTINES CALLED  XZABS,XZEXP,XZLOG
+C***END PROLOGUE  ZS1S2
+C     COMPLEX CZERO,C1,S1,S1D,S2,ZR
+      DOUBLE PRECISION AA, ALIM, ALN, ASCLE, AS1, AS2, C1I, C1R, S1DI,
+     * S1DR, S1I, S1R, S2I, S2R, ZEROI, ZEROR, ZRI, ZRR, XZABS
+      INTEGER IUF, IDUM, NZ
+      DATA ZEROR,ZEROI  / 0.0D0 , 0.0D0 /
+      NZ = 0
+      AS1 = XZABS(S1R,S1I)
+      AS2 = XZABS(S2R,S2I)
+      IF (S1R.EQ.0.0D0 .AND. S1I.EQ.0.0D0) GO TO 10
+      IF (AS1.EQ.0.0D0) GO TO 10
+      ALN = -ZRR - ZRR + DLOG(AS1)
+      S1DR = S1R
+      S1DI = S1I
+      S1R = ZEROR
+      S1I = ZEROI
+      AS1 = ZEROR
+      IF (ALN.LT.(-ALIM)) GO TO 10
+      CALL XZLOG(S1DR, S1DI, C1R, C1I, IDUM)
+      C1R = C1R - ZRR - ZRR
+      C1I = C1I - ZRI - ZRI
+      CALL XZEXP(C1R, C1I, S1R, S1I)
+      AS1 = XZABS(S1R,S1I)
+      IUF = IUF + 1
+   10 CONTINUE
+      AA = DMAX1(AS1,AS2)
+      IF (AA.GT.ASCLE) RETURN
+      S1R = ZEROR
+      S1I = ZEROI
+      S2R = ZEROR
+      S2I = ZEROI
+      NZ = 1
+      IUF = 0
+      RETURN
+      END
diff --git a/libcruft/amos/zseri.f b/libcruft/amos/zseri.f
new file mode 100644
index 0000000..96f2ecd
--- /dev/null
+++ b/libcruft/amos/zseri.f
@@ -0,0 +1,190 @@
+      SUBROUTINE ZSERI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  ZSERI
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
+C     MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE
+C     REGION CABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN.
+C     NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO
+C     DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE
+C     CONDITION CABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE
+C     COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ).
+C
+C***ROUTINES CALLED  DGAMLN,D1MACH,ZUCHK,XZABS,ZDIV,XZLOG,ZMLT
+C***END PROLOGUE  ZSERI
+C     COMPLEX AK1,CK,COEF,CONE,CRSC,CSCL,CZ,CZERO,HZ,RZ,S1,S2,Y,Z
+      DOUBLE PRECISION AA, ACZ, AK, AK1I, AK1R, ALIM, ARM, ASCLE, ATOL,
+     * AZ, CKI, CKR, COEFI, COEFR, CONEI, CONER, CRSCR, CZI, CZR, DFNU,
+     * ELIM, FNU, FNUP, HZI, HZR, RAZ, RS, RTR1, RZI, RZR, S, SS, STI,
+     * STR, S1I, S1R, S2I, S2R, TOL, YI, YR, WI, WR, ZEROI, ZEROR, ZI,
+     * ZR, DGAMLN, D1MACH, XZABS
+      INTEGER I, IB, IDUM, IFLAG, IL, K, KODE, L, M, N, NN, NZ, NW
+      DIMENSION YR(N), YI(N), WR(2), WI(2)
+      DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
+C
+      NZ = 0
+      AZ = XZABS(ZR,ZI)
+      IF (AZ.EQ.0.0D0) GO TO 160
+      ARM = 1.0D+3*D1MACH(1)
+      RTR1 = DSQRT(ARM)
+      CRSCR = 1.0D0
+      IFLAG = 0
+      IF (AZ.LT.ARM) GO TO 150
+      HZR = 0.5D0*ZR
+      HZI = 0.5D0*ZI
+      CZR = ZEROR
+      CZI = ZEROI
+      IF (AZ.LE.RTR1) GO TO 10
+      CALL ZMLT(HZR, HZI, HZR, HZI, CZR, CZI)
+   10 CONTINUE
+      ACZ = XZABS(CZR,CZI)
+      NN = N
+      CALL XZLOG(HZR, HZI, CKR, CKI, IDUM)
+   20 CONTINUE
+      DFNU = FNU + DBLE(FLOAT(NN-1))
+      FNUP = DFNU + 1.0D0
+C-----------------------------------------------------------------------
+C     UNDERFLOW TEST
+C-----------------------------------------------------------------------
+      AK1R = CKR*DFNU
+      AK1I = CKI*DFNU
+      AK = DGAMLN(FNUP,IDUM)
+      AK1R = AK1R - AK
+      IF (KODE.EQ.2) AK1R = AK1R - ZR
+      IF (AK1R.GT.(-ELIM)) GO TO 40
+   30 CONTINUE
+      NZ = NZ + 1
+      YR(NN) = ZEROR
+      YI(NN) = ZEROI
+      IF (ACZ.GT.DFNU) GO TO 190
+      NN = NN - 1
+      IF (NN.EQ.0) RETURN
+      GO TO 20
+   40 CONTINUE
+      IF (AK1R.GT.(-ALIM)) GO TO 50
+      IFLAG = 1
+      SS = 1.0D0/TOL
+      CRSCR = TOL
+      ASCLE = ARM*SS
+   50 CONTINUE
+      AA = DEXP(AK1R)
+      IF (IFLAG.EQ.1) AA = AA*SS
+      COEFR = AA*DCOS(AK1I)
+      COEFI = AA*DSIN(AK1I)
+      ATOL = TOL*ACZ/FNUP
+      IL = MIN0(2,NN)
+      DO 90 I=1,IL
+        DFNU = FNU + DBLE(FLOAT(NN-I))
+        FNUP = DFNU + 1.0D0
+        S1R = CONER
+        S1I = CONEI
+        IF (ACZ.LT.TOL*FNUP) GO TO 70
+        AK1R = CONER
+        AK1I = CONEI
+        AK = FNUP + 2.0D0
+        S = FNUP
+        AA = 2.0D0
+   60   CONTINUE
+        RS = 1.0D0/S
+        STR = AK1R*CZR - AK1I*CZI
+        STI = AK1R*CZI + AK1I*CZR
+        AK1R = STR*RS
+        AK1I = STI*RS
+        S1R = S1R + AK1R
+        S1I = S1I + AK1I
+        S = S + AK
+        AK = AK + 2.0D0
+        AA = AA*ACZ*RS
+        IF (AA.GT.ATOL) GO TO 60
+   70   CONTINUE
+        S2R = S1R*COEFR - S1I*COEFI
+        S2I = S1R*COEFI + S1I*COEFR
+        WR(I) = S2R
+        WI(I) = S2I
+        IF (IFLAG.EQ.0) GO TO 80
+        CALL ZUCHK(S2R, S2I, NW, ASCLE, TOL)
+        IF (NW.NE.0) GO TO 30
+   80   CONTINUE
+        M = NN - I + 1
+        YR(M) = S2R*CRSCR
+        YI(M) = S2I*CRSCR
+        IF (I.EQ.IL) GO TO 90
+        CALL ZDIV(COEFR, COEFI, HZR, HZI, STR, STI)
+        COEFR = STR*DFNU
+        COEFI = STI*DFNU
+   90 CONTINUE
+      IF (NN.LE.2) RETURN
+      K = NN - 2
+      AK = DBLE(FLOAT(K))
+      RAZ = 1.0D0/AZ
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      RZR = (STR+STR)*RAZ
+      RZI = (STI+STI)*RAZ
+      IF (IFLAG.EQ.1) GO TO 120
+      IB = 3
+  100 CONTINUE
+      DO 110 I=IB,NN
+        YR(K) = (AK+FNU)*(RZR*YR(K+1)-RZI*YI(K+1)) + YR(K+2)
+        YI(K) = (AK+FNU)*(RZR*YI(K+1)+RZI*YR(K+1)) + YI(K+2)
+        AK = AK - 1.0D0
+        K = K - 1
+  110 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     RECUR BACKWARD WITH SCALED VALUES
+C-----------------------------------------------------------------------
+  120 CONTINUE
+C-----------------------------------------------------------------------
+C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE
+C     UNDERFLOW LIMIT = ASCLE = D1MACH(1)*SS*1.0D+3
+C-----------------------------------------------------------------------
+      S1R = WR(1)
+      S1I = WI(1)
+      S2R = WR(2)
+      S2I = WI(2)
+      DO 130 L=3,NN
+        CKR = S2R
+        CKI = S2I
+        S2R = S1R + (AK+FNU)*(RZR*CKR-RZI*CKI)
+        S2I = S1I + (AK+FNU)*(RZR*CKI+RZI*CKR)
+        S1R = CKR
+        S1I = CKI
+        CKR = S2R*CRSCR
+        CKI = S2I*CRSCR
+        YR(K) = CKR
+        YI(K) = CKI
+        AK = AK - 1.0D0
+        K = K - 1
+        IF (XZABS(CKR,CKI).GT.ASCLE) GO TO 140
+  130 CONTINUE
+      RETURN
+  140 CONTINUE
+      IB = L + 1
+      IF (IB.GT.NN) RETURN
+      GO TO 100
+  150 CONTINUE
+      NZ = N
+      IF (FNU.EQ.0.0D0) NZ = NZ - 1
+  160 CONTINUE
+      YR(1) = ZEROR
+      YI(1) = ZEROI
+      IF (FNU.NE.0.0D0) GO TO 170
+      YR(1) = CONER
+      YI(1) = CONEI
+  170 CONTINUE
+      IF (N.EQ.1) RETURN
+      DO 180 I=2,N
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+  180 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     RETURN WITH NZ.LT.0 IF CABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE
+C     THE CALCULATION IN CBINU WITH N=N-IABS(NZ)
+C-----------------------------------------------------------------------
+  190 CONTINUE
+      NZ = -NZ
+      RETURN
+      END
diff --git a/libcruft/amos/zshch.f b/libcruft/amos/zshch.f
new file mode 100644
index 0000000..168e62e
--- /dev/null
+++ b/libcruft/amos/zshch.f
@@ -0,0 +1,22 @@
+      SUBROUTINE ZSHCH(ZR, ZI, CSHR, CSHI, CCHR, CCHI)
+C***BEGIN PROLOGUE  ZSHCH
+C***REFER TO  ZBESK,ZBESH
+C
+C     ZSHCH COMPUTES THE COMPLEX HYPERBOLIC FUNCTIONS CSH=SINH(X+I*Y)
+C     AND CCH=COSH(X+I*Y), WHERE I**2=-1.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  ZSHCH
+C
+      DOUBLE PRECISION CCHI, CCHR, CH, CN, CSHI, CSHR, SH, SN, ZI, ZR,
+     * DCOSH, DSINH
+      SH = DSINH(ZR)
+      CH = DCOSH(ZR)
+      SN = DSIN(ZI)
+      CN = DCOS(ZI)
+      CSHR = SH*CN
+      CSHI = CH*SN
+      CCHR = CH*CN
+      CCHI = SH*SN
+      RETURN
+      END
diff --git a/libcruft/amos/zuchk.f b/libcruft/amos/zuchk.f
new file mode 100644
index 0000000..d15dc84
--- /dev/null
+++ b/libcruft/amos/zuchk.f
@@ -0,0 +1,28 @@
+      SUBROUTINE ZUCHK(YR, YI, NZ, ASCLE, TOL)
+C***BEGIN PROLOGUE  ZUCHK
+C***REFER TO ZSERI,ZUOIK,ZUNK1,ZUNK2,ZUNI1,ZUNI2,ZKSCL
+C
+C      Y ENTERS AS A SCALED QUANTITY WHOSE MAGNITUDE IS GREATER THAN
+C      EXP(-ALIM)=ASCLE=1.0E+3*D1MACH(1)/TOL. THE TEST IS MADE TO SEE
+C      IF THE MAGNITUDE OF THE REAL OR IMAGINARY PART WOULD UNDERFLOW
+C      WHEN Y IS SCALED (BY TOL) TO ITS PROPER VALUE. Y IS ACCEPTED
+C      IF THE UNDERFLOW IS AT LEAST ONE PRECISION BELOW THE MAGNITUDE
+C      OF THE LARGEST COMPONENT; OTHERWISE THE PHASE ANGLE DOES NOT HAVE
+C      ABSOLUTE ACCURACY AND AN UNDERFLOW IS ASSUMED.
+C
+C***ROUTINES CALLED  (NONE)
+C***END PROLOGUE  ZUCHK
+C
+C     COMPLEX Y
+      DOUBLE PRECISION ASCLE, SS, ST, TOL, WR, WI, YR, YI
+      INTEGER NZ
+      NZ = 0
+      WR = DABS(YR)
+      WI = DABS(YI)
+      ST = DMIN1(WR,WI)
+      IF (ST.GT.ASCLE) RETURN
+      SS = DMAX1(WR,WI)
+      ST = ST/TOL
+      IF (SS.LT.ST) NZ = 1
+      RETURN
+      END
diff --git a/libcruft/amos/zunhj.f b/libcruft/amos/zunhj.f
new file mode 100644
index 0000000..eb4e9c9
--- /dev/null
+++ b/libcruft/amos/zunhj.f
@@ -0,0 +1,714 @@
+      SUBROUTINE ZUNHJ(ZR, ZI, FNU, IPMTR, TOL, PHIR, PHII, ARGR, ARGI,
+     * ZETA1R, ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
+C***BEGIN PROLOGUE  ZUNHJ
+C***REFER TO  ZBESI,ZBESK
+C
+C     REFERENCES
+C         HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ AND I.A.
+C         STEGUN, AMS55, NATIONAL BUREAU OF STANDARDS, 1965, CHAPTER 9.
+C
+C         ASYMPTOTICS AND SPECIAL FUNCTIONS BY F.W.J. OLVER, ACADEMIC
+C         PRESS, N.Y., 1974, PAGE 420
+C
+C     ABSTRACT
+C         ZUNHJ COMPUTES PARAMETERS FOR BESSEL FUNCTIONS C(FNU,Z) =
+C         J(FNU,Z), Y(FNU,Z) OR H(I,FNU,Z) I=1,2 FOR LARGE ORDERS FNU
+C         BY MEANS OF THE UNIFORM ASYMPTOTIC EXPANSION
+C
+C         C(FNU,Z)=C1*PHI*( ASUM*AIRY(ARG) + C2*BSUM*DAIRY(ARG) )
+C
+C         FOR PROPER CHOICES OF C1, C2, AIRY AND DAIRY WHERE AIRY IS
+C         AN AIRY FUNCTION AND DAIRY IS ITS DERIVATIVE.
+C
+C               (2/3)*FNU*ZETA**1.5 = ZETA1-ZETA2,
+C
+C         ZETA1=0.5*FNU*CLOG((1+W)/(1-W)), ZETA2=FNU*W FOR SCALING
+C         PURPOSES IN AIRY FUNCTIONS FROM CAIRY OR CBIRY.
+C
+C         MCONJ=SIGN OF AIMAG(Z), BUT IS AMBIGUOUS WHEN Z IS REAL AND
+C         MUST BE SPECIFIED. IPMTR=0 RETURNS ALL PARAMETERS. IPMTR=
+C         1 COMPUTES ALL EXCEPT ASUM AND BSUM.
+C
+C***ROUTINES CALLED  XZABS,ZDIV,XZLOG,XZSQRT,D1MACH
+C***END PROLOGUE  ZUNHJ
+C     COMPLEX ARG,ASUM,BSUM,CFNU,CONE,CR,CZERO,DR,P,PHI,PRZTH,PTFN,
+C    *RFN13,RTZTA,RZTH,SUMA,SUMB,TFN,T2,UP,W,W2,Z,ZA,ZB,ZC,ZETA,ZETA1,
+C    *ZETA2,ZTH
+      DOUBLE PRECISION ALFA, ANG, AP, AR, ARGI, ARGR, ASUMI, ASUMR,
+     * ATOL, AW2, AZTH, BETA, BR, BSUMI, BSUMR, BTOL, C, CONEI, CONER,
+     * CRI, CRR, DRI, DRR, EX1, EX2, FNU, FN13, FN23, GAMA, GPI, HPI,
+     * PHII, PHIR, PI, PP, PR, PRZTHI, PRZTHR, PTFNI, PTFNR, RAW, RAW2,
+     * RAZTH, RFNU, RFNU2, RFN13, RTZTI, RTZTR, RZTHI, RZTHR, STI, STR,
+     * SUMAI, SUMAR, SUMBI, SUMBR, TEST, TFNI, TFNR, THPI, TOL, TZAI,
+     * TZAR, T2I, T2R, UPI, UPR, WI, WR, W2I, W2R, ZAI, ZAR, ZBI, ZBR,
+     * ZCI, ZCR, ZEROI, ZEROR, ZETAI, ZETAR, ZETA1I, ZETA1R, ZETA2I,
+     * ZETA2R, ZI, ZR, ZTHI, ZTHR, XZABS, AC, D1MACH
+      INTEGER IAS, IBS, IPMTR, IS, J, JR, JU, K, KMAX, KP1, KS, L, LR,
+     * LRP1, L1, L2, M, IDUM
+      DIMENSION AR(14), BR(14), C(105), ALFA(180), BETA(210), GAMA(30),
+     * AP(30), PR(30), PI(30), UPR(14), UPI(14), CRR(14), CRI(14),
+     * DRR(14), DRI(14)
+      DATA AR(1), AR(2), AR(3), AR(4), AR(5), AR(6), AR(7), AR(8),
+     1     AR(9), AR(10), AR(11), AR(12), AR(13), AR(14)/
+     2     1.00000000000000000D+00,     1.04166666666666667D-01,
+     3     8.35503472222222222D-02,     1.28226574556327160D-01,
+     4     2.91849026464140464D-01,     8.81627267443757652D-01,
+     5     3.32140828186276754D+00,     1.49957629868625547D+01,
+     6     7.89230130115865181D+01,     4.74451538868264323D+02,
+     7     3.20749009089066193D+03,     2.40865496408740049D+04,
+     8     1.98923119169509794D+05,     1.79190200777534383D+06/
+      DATA BR(1), BR(2), BR(3), BR(4), BR(5), BR(6), BR(7), BR(8),
+     1     BR(9), BR(10), BR(11), BR(12), BR(13), BR(14)/
+     2     1.00000000000000000D+00,    -1.45833333333333333D-01,
+     3    -9.87413194444444444D-02,    -1.43312053915895062D-01,
+     4    -3.17227202678413548D-01,    -9.42429147957120249D-01,
+     5    -3.51120304082635426D+00,    -1.57272636203680451D+01,
+     6    -8.22814390971859444D+01,    -4.92355370523670524D+02,
+     7    -3.31621856854797251D+03,    -2.48276742452085896D+04,
+     8    -2.04526587315129788D+05,    -1.83844491706820990D+06/
+      DATA C(1), C(2), C(3), C(4), C(5), C(6), C(7), C(8), C(9), C(10),
+     1     C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18),
+     2     C(19), C(20), C(21), C(22), C(23), C(24)/
+     3     1.00000000000000000D+00,    -2.08333333333333333D-01,
+     4     1.25000000000000000D-01,     3.34201388888888889D-01,
+     5    -4.01041666666666667D-01,     7.03125000000000000D-02,
+     6    -1.02581259645061728D+00,     1.84646267361111111D+00,
+     7    -8.91210937500000000D-01,     7.32421875000000000D-02,
+     8     4.66958442342624743D+00,    -1.12070026162229938D+01,
+     9     8.78912353515625000D+00,    -2.36408691406250000D+00,
+     A     1.12152099609375000D-01,    -2.82120725582002449D+01,
+     B     8.46362176746007346D+01,    -9.18182415432400174D+01,
+     C     4.25349987453884549D+01,    -7.36879435947963170D+00,
+     D     2.27108001708984375D-01,     2.12570130039217123D+02,
+     E    -7.65252468141181642D+02,     1.05999045252799988D+03/
+      DATA C(25), C(26), C(27), C(28), C(29), C(30), C(31), C(32),
+     1     C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(40),
+     2     C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48)/
+     3    -6.99579627376132541D+02,     2.18190511744211590D+02,
+     4    -2.64914304869515555D+01,     5.72501420974731445D-01,
+     5    -1.91945766231840700D+03,     8.06172218173730938D+03,
+     6    -1.35865500064341374D+04,     1.16553933368645332D+04,
+     7    -5.30564697861340311D+03,     1.20090291321635246D+03,
+     8    -1.08090919788394656D+02,     1.72772750258445740D+00,
+     9     2.02042913309661486D+04,    -9.69805983886375135D+04,
+     A     1.92547001232531532D+05,    -2.03400177280415534D+05,
+     B     1.22200464983017460D+05,    -4.11926549688975513D+04,
+     C     7.10951430248936372D+03,    -4.93915304773088012D+02,
+     D     6.07404200127348304D+00,    -2.42919187900551333D+05,
+     E     1.31176361466297720D+06,    -2.99801591853810675D+06/
+      DATA C(49), C(50), C(51), C(52), C(53), C(54), C(55), C(56),
+     1     C(57), C(58), C(59), C(60), C(61), C(62), C(63), C(64),
+     2     C(65), C(66), C(67), C(68), C(69), C(70), C(71), C(72)/
+     3     3.76327129765640400D+06,    -2.81356322658653411D+06,
+     4     1.26836527332162478D+06,    -3.31645172484563578D+05,
+     5     4.52187689813627263D+04,    -2.49983048181120962D+03,
+     6     2.43805296995560639D+01,     3.28446985307203782D+06,
+     7    -1.97068191184322269D+07,     5.09526024926646422D+07,
+     8    -7.41051482115326577D+07,     6.63445122747290267D+07,
+     9    -3.75671766607633513D+07,     1.32887671664218183D+07,
+     A    -2.78561812808645469D+06,     3.08186404612662398D+05,
+     B    -1.38860897537170405D+04,     1.10017140269246738D+02,
+     C    -4.93292536645099620D+07,     3.25573074185765749D+08,
+     D    -9.39462359681578403D+08,     1.55359689957058006D+09,
+     E    -1.62108055210833708D+09,     1.10684281682301447D+09/
+      DATA C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(80),
+     1     C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88),
+     2     C(89), C(90), C(91), C(92), C(93), C(94), C(95), C(96)/
+     3    -4.95889784275030309D+08,     1.42062907797533095D+08,
+     4    -2.44740627257387285D+07,     2.24376817792244943D+06,
+     5    -8.40054336030240853D+04,     5.51335896122020586D+02,
+     6     8.14789096118312115D+08,    -5.86648149205184723D+09,
+     7     1.86882075092958249D+10,    -3.46320433881587779D+10,
+     8     4.12801855797539740D+10,    -3.30265997498007231D+10,
+     9     1.79542137311556001D+10,    -6.56329379261928433D+09,
+     A     1.55927986487925751D+09,    -2.25105661889415278D+08,
+     B     1.73951075539781645D+07,    -5.49842327572288687D+05,
+     C     3.03809051092238427D+03,    -1.46792612476956167D+10,
+     D     1.14498237732025810D+11,    -3.99096175224466498D+11,
+     E     8.19218669548577329D+11,    -1.09837515608122331D+12/
+      DATA C(97), C(98), C(99), C(100), C(101), C(102), C(103), C(104),
+     1     C(105)/
+     2     1.00815810686538209D+12,    -6.45364869245376503D+11,
+     3     2.87900649906150589D+11,    -8.78670721780232657D+10,
+     4     1.76347306068349694D+10,    -2.16716498322379509D+09,
+     5     1.43157876718888981D+08,    -3.87183344257261262D+06,
+     6     1.82577554742931747D+04/
+      DATA ALFA(1), ALFA(2), ALFA(3), ALFA(4), ALFA(5), ALFA(6),
+     1     ALFA(7), ALFA(8), ALFA(9), ALFA(10), ALFA(11), ALFA(12),
+     2     ALFA(13), ALFA(14), ALFA(15), ALFA(16), ALFA(17), ALFA(18),
+     3     ALFA(19), ALFA(20), ALFA(21), ALFA(22)/
+     4    -4.44444444444444444D-03,    -9.22077922077922078D-04,
+     5    -8.84892884892884893D-05,     1.65927687832449737D-04,
+     6     2.46691372741792910D-04,     2.65995589346254780D-04,
+     7     2.61824297061500945D-04,     2.48730437344655609D-04,
+     8     2.32721040083232098D-04,     2.16362485712365082D-04,
+     9     2.00738858762752355D-04,     1.86267636637545172D-04,
+     A     1.73060775917876493D-04,     1.61091705929015752D-04,
+     B     1.50274774160908134D-04,     1.40503497391269794D-04,
+     C     1.31668816545922806D-04,     1.23667445598253261D-04,
+     D     1.16405271474737902D-04,     1.09798298372713369D-04,
+     E     1.03772410422992823D-04,     9.82626078369363448D-05/
+      DATA ALFA(23), ALFA(24), ALFA(25), ALFA(26), ALFA(27), ALFA(28),
+     1     ALFA(29), ALFA(30), ALFA(31), ALFA(32), ALFA(33), ALFA(34),
+     2     ALFA(35), ALFA(36), ALFA(37), ALFA(38), ALFA(39), ALFA(40),
+     3     ALFA(41), ALFA(42), ALFA(43), ALFA(44)/
+     4     9.32120517249503256D-05,     8.85710852478711718D-05,
+     5     8.42963105715700223D-05,     8.03497548407791151D-05,
+     6     7.66981345359207388D-05,     7.33122157481777809D-05,
+     7     7.01662625163141333D-05,     6.72375633790160292D-05,
+     8     6.93735541354588974D-04,     2.32241745182921654D-04,
+     9    -1.41986273556691197D-05,    -1.16444931672048640D-04,
+     A    -1.50803558053048762D-04,    -1.55121924918096223D-04,
+     B    -1.46809756646465549D-04,    -1.33815503867491367D-04,
+     C    -1.19744975684254051D-04,    -1.06184319207974020D-04,
+     D    -9.37699549891194492D-05,    -8.26923045588193274D-05,
+     E    -7.29374348155221211D-05,    -6.44042357721016283D-05/
+      DATA ALFA(45), ALFA(46), ALFA(47), ALFA(48), ALFA(49), ALFA(50),
+     1     ALFA(51), ALFA(52), ALFA(53), ALFA(54), ALFA(55), ALFA(56),
+     2     ALFA(57), ALFA(58), ALFA(59), ALFA(60), ALFA(61), ALFA(62),
+     3     ALFA(63), ALFA(64), ALFA(65), ALFA(66)/
+     4    -5.69611566009369048D-05,    -5.04731044303561628D-05,
+     5    -4.48134868008882786D-05,    -3.98688727717598864D-05,
+     6    -3.55400532972042498D-05,    -3.17414256609022480D-05,
+     7    -2.83996793904174811D-05,    -2.54522720634870566D-05,
+     8    -2.28459297164724555D-05,    -2.05352753106480604D-05,
+     9    -1.84816217627666085D-05,    -1.66519330021393806D-05,
+     A    -1.50179412980119482D-05,    -1.35554031379040526D-05,
+     B    -1.22434746473858131D-05,    -1.10641884811308169D-05,
+     C    -3.54211971457743841D-04,    -1.56161263945159416D-04,
+     D     3.04465503594936410D-05,     1.30198655773242693D-04,
+     E     1.67471106699712269D-04,     1.70222587683592569D-04/
+      DATA ALFA(67), ALFA(68), ALFA(69), ALFA(70), ALFA(71), ALFA(72),
+     1     ALFA(73), ALFA(74), ALFA(75), ALFA(76), ALFA(77), ALFA(78),
+     2     ALFA(79), ALFA(80), ALFA(81), ALFA(82), ALFA(83), ALFA(84),
+     3     ALFA(85), ALFA(86), ALFA(87), ALFA(88)/
+     4     1.56501427608594704D-04,     1.36339170977445120D-04,
+     5     1.14886692029825128D-04,     9.45869093034688111D-05,
+     6     7.64498419250898258D-05,     6.07570334965197354D-05,
+     7     4.74394299290508799D-05,     3.62757512005344297D-05,
+     8     2.69939714979224901D-05,     1.93210938247939253D-05,
+     9     1.30056674793963203D-05,     7.82620866744496661D-06,
+     A     3.59257485819351583D-06,     1.44040049814251817D-07,
+     B    -2.65396769697939116D-06,    -4.91346867098485910D-06,
+     C    -6.72739296091248287D-06,    -8.17269379678657923D-06,
+     D    -9.31304715093561232D-06,    -1.02011418798016441D-05,
+     E    -1.08805962510592880D-05,    -1.13875481509603555D-05/
+      DATA ALFA(89), ALFA(90), ALFA(91), ALFA(92), ALFA(93), ALFA(94),
+     1     ALFA(95), ALFA(96), ALFA(97), ALFA(98), ALFA(99), ALFA(100),
+     2     ALFA(101), ALFA(102), ALFA(103), ALFA(104), ALFA(105),
+     3     ALFA(106), ALFA(107), ALFA(108), ALFA(109), ALFA(110)/
+     4    -1.17519675674556414D-05,    -1.19987364870944141D-05,
+     5     3.78194199201772914D-04,     2.02471952761816167D-04,
+     6    -6.37938506318862408D-05,    -2.38598230603005903D-04,
+     7    -3.10916256027361568D-04,    -3.13680115247576316D-04,
+     8    -2.78950273791323387D-04,    -2.28564082619141374D-04,
+     9    -1.75245280340846749D-04,    -1.25544063060690348D-04,
+     A    -8.22982872820208365D-05,    -4.62860730588116458D-05,
+     B    -1.72334302366962267D-05,     5.60690482304602267D-06,
+     C     2.31395443148286800D-05,     3.62642745856793957D-05,
+     D     4.58006124490188752D-05,     5.24595294959114050D-05,
+     E     5.68396208545815266D-05,     5.94349820393104052D-05/
+      DATA ALFA(111), ALFA(112), ALFA(113), ALFA(114), ALFA(115),
+     1     ALFA(116), ALFA(117), ALFA(118), ALFA(119), ALFA(120),
+     2     ALFA(121), ALFA(122), ALFA(123), ALFA(124), ALFA(125),
+     3     ALFA(126), ALFA(127), ALFA(128), ALFA(129), ALFA(130)/
+     4     6.06478527578421742D-05,     6.08023907788436497D-05,
+     5     6.01577894539460388D-05,     5.89199657344698500D-05,
+     6     5.72515823777593053D-05,     5.52804375585852577D-05,
+     7     5.31063773802880170D-05,     5.08069302012325706D-05,
+     8     4.84418647620094842D-05,     4.60568581607475370D-05,
+     9    -6.91141397288294174D-04,    -4.29976633058871912D-04,
+     A     1.83067735980039018D-04,     6.60088147542014144D-04,
+     B     8.75964969951185931D-04,     8.77335235958235514D-04,
+     C     7.49369585378990637D-04,     5.63832329756980918D-04,
+     D     3.68059319971443156D-04,     1.88464535514455599D-04/
+      DATA ALFA(131), ALFA(132), ALFA(133), ALFA(134), ALFA(135),
+     1     ALFA(136), ALFA(137), ALFA(138), ALFA(139), ALFA(140),
+     2     ALFA(141), ALFA(142), ALFA(143), ALFA(144), ALFA(145),
+     3     ALFA(146), ALFA(147), ALFA(148), ALFA(149), ALFA(150)/
+     4     3.70663057664904149D-05,    -8.28520220232137023D-05,
+     5    -1.72751952869172998D-04,    -2.36314873605872983D-04,
+     6    -2.77966150694906658D-04,    -3.02079514155456919D-04,
+     7    -3.12594712643820127D-04,    -3.12872558758067163D-04,
+     8    -3.05678038466324377D-04,    -2.93226470614557331D-04,
+     9    -2.77255655582934777D-04,    -2.59103928467031709D-04,
+     A    -2.39784014396480342D-04,    -2.20048260045422848D-04,
+     B    -2.00443911094971498D-04,    -1.81358692210970687D-04,
+     C    -1.63057674478657464D-04,    -1.45712672175205844D-04,
+     D    -1.29425421983924587D-04,    -1.14245691942445952D-04/
+      DATA ALFA(151), ALFA(152), ALFA(153), ALFA(154), ALFA(155),
+     1     ALFA(156), ALFA(157), ALFA(158), ALFA(159), ALFA(160),
+     2     ALFA(161), ALFA(162), ALFA(163), ALFA(164), ALFA(165),
+     3     ALFA(166), ALFA(167), ALFA(168), ALFA(169), ALFA(170)/
+     4     1.92821964248775885D-03,     1.35592576302022234D-03,
+     5    -7.17858090421302995D-04,    -2.58084802575270346D-03,
+     6    -3.49271130826168475D-03,    -3.46986299340960628D-03,
+     7    -2.82285233351310182D-03,    -1.88103076404891354D-03,
+     8    -8.89531718383947600D-04,     3.87912102631035228D-06,
+     9     7.28688540119691412D-04,     1.26566373053457758D-03,
+     A     1.62518158372674427D-03,     1.83203153216373172D-03,
+     B     1.91588388990527909D-03,     1.90588846755546138D-03,
+     C     1.82798982421825727D-03,     1.70389506421121530D-03,
+     D     1.55097127171097686D-03,     1.38261421852276159D-03/
+      DATA ALFA(171), ALFA(172), ALFA(173), ALFA(174), ALFA(175),
+     1     ALFA(176), ALFA(177), ALFA(178), ALFA(179), ALFA(180)/
+     2     1.20881424230064774D-03,     1.03676532638344962D-03,
+     3     8.71437918068619115D-04,     7.16080155297701002D-04,
+     4     5.72637002558129372D-04,     4.42089819465802277D-04,
+     5     3.24724948503090564D-04,     2.20342042730246599D-04,
+     6     1.28412898401353882D-04,     4.82005924552095464D-05/
+      DATA BETA(1), BETA(2), BETA(3), BETA(4), BETA(5), BETA(6),
+     1     BETA(7), BETA(8), BETA(9), BETA(10), BETA(11), BETA(12),
+     2     BETA(13), BETA(14), BETA(15), BETA(16), BETA(17), BETA(18),
+     3     BETA(19), BETA(20), BETA(21), BETA(22)/
+     4     1.79988721413553309D-02,     5.59964911064388073D-03,
+     5     2.88501402231132779D-03,     1.80096606761053941D-03,
+     6     1.24753110589199202D-03,     9.22878876572938311D-04,
+     7     7.14430421727287357D-04,     5.71787281789704872D-04,
+     8     4.69431007606481533D-04,     3.93232835462916638D-04,
+     9     3.34818889318297664D-04,     2.88952148495751517D-04,
+     A     2.52211615549573284D-04,     2.22280580798883327D-04,
+     B     1.97541838033062524D-04,     1.76836855019718004D-04,
+     C     1.59316899661821081D-04,     1.44347930197333986D-04,
+     D     1.31448068119965379D-04,     1.20245444949302884D-04,
+     E     1.10449144504599392D-04,     1.01828770740567258D-04/
+      DATA BETA(23), BETA(24), BETA(25), BETA(26), BETA(27), BETA(28),
+     1     BETA(29), BETA(30), BETA(31), BETA(32), BETA(33), BETA(34),
+     2     BETA(35), BETA(36), BETA(37), BETA(38), BETA(39), BETA(40),
+     3     BETA(41), BETA(42), BETA(43), BETA(44)/
+     4     9.41998224204237509D-05,     8.74130545753834437D-05,
+     5     8.13466262162801467D-05,     7.59002269646219339D-05,
+     6     7.09906300634153481D-05,     6.65482874842468183D-05,
+     7     6.25146958969275078D-05,     5.88403394426251749D-05,
+     8    -1.49282953213429172D-03,    -8.78204709546389328D-04,
+     9    -5.02916549572034614D-04,    -2.94822138512746025D-04,
+     A    -1.75463996970782828D-04,    -1.04008550460816434D-04,
+     B    -5.96141953046457895D-05,    -3.12038929076098340D-05,
+     C    -1.26089735980230047D-05,    -2.42892608575730389D-07,
+     D     8.05996165414273571D-06,     1.36507009262147391D-05,
+     E     1.73964125472926261D-05,     1.98672978842133780D-05/
+      DATA BETA(45), BETA(46), BETA(47), BETA(48), BETA(49), BETA(50),
+     1     BETA(51), BETA(52), BETA(53), BETA(54), BETA(55), BETA(56),
+     2     BETA(57), BETA(58), BETA(59), BETA(60), BETA(61), BETA(62),
+     3     BETA(63), BETA(64), BETA(65), BETA(66)/
+     4     2.14463263790822639D-05,     2.23954659232456514D-05,
+     5     2.28967783814712629D-05,     2.30785389811177817D-05,
+     6     2.30321976080909144D-05,     2.28236073720348722D-05,
+     7     2.25005881105292418D-05,     2.20981015361991429D-05,
+     8     2.16418427448103905D-05,     2.11507649256220843D-05,
+     9     2.06388749782170737D-05,     2.01165241997081666D-05,
+     A     1.95913450141179244D-05,     1.90689367910436740D-05,
+     B     1.85533719641636667D-05,     1.80475722259674218D-05,
+     C     5.52213076721292790D-04,     4.47932581552384646D-04,
+     D     2.79520653992020589D-04,     1.52468156198446602D-04,
+     E     6.93271105657043598D-05,     1.76258683069991397D-05/
+      DATA BETA(67), BETA(68), BETA(69), BETA(70), BETA(71), BETA(72),
+     1     BETA(73), BETA(74), BETA(75), BETA(76), BETA(77), BETA(78),
+     2     BETA(79), BETA(80), BETA(81), BETA(82), BETA(83), BETA(84),
+     3     BETA(85), BETA(86), BETA(87), BETA(88)/
+     4    -1.35744996343269136D-05,    -3.17972413350427135D-05,
+     5    -4.18861861696693365D-05,    -4.69004889379141029D-05,
+     6    -4.87665447413787352D-05,    -4.87010031186735069D-05,
+     7    -4.74755620890086638D-05,    -4.55813058138628452D-05,
+     8    -4.33309644511266036D-05,    -4.09230193157750364D-05,
+     9    -3.84822638603221274D-05,    -3.60857167535410501D-05,
+     A    -3.37793306123367417D-05,    -3.15888560772109621D-05,
+     B    -2.95269561750807315D-05,    -2.75978914828335759D-05,
+     C    -2.58006174666883713D-05,    -2.41308356761280200D-05,
+     D    -2.25823509518346033D-05,    -2.11479656768912971D-05,
+     E    -1.98200638885294927D-05,    -1.85909870801065077D-05/
+      DATA BETA(89), BETA(90), BETA(91), BETA(92), BETA(93), BETA(94),
+     1     BETA(95), BETA(96), BETA(97), BETA(98), BETA(99), BETA(100),
+     2     BETA(101), BETA(102), BETA(103), BETA(104), BETA(105),
+     3     BETA(106), BETA(107), BETA(108), BETA(109), BETA(110)/
+     4    -1.74532699844210224D-05,    -1.63997823854497997D-05,
+     5    -4.74617796559959808D-04,    -4.77864567147321487D-04,
+     6    -3.20390228067037603D-04,    -1.61105016119962282D-04,
+     7    -4.25778101285435204D-05,     3.44571294294967503D-05,
+     8     7.97092684075674924D-05,     1.03138236708272200D-04,
+     9     1.12466775262204158D-04,     1.13103642108481389D-04,
+     A     1.08651634848774268D-04,     1.01437951597661973D-04,
+     B     9.29298396593363896D-05,     8.40293133016089978D-05,
+     C     7.52727991349134062D-05,     6.69632521975730872D-05,
+     D     5.92564547323194704D-05,     5.22169308826975567D-05,
+     E     4.58539485165360646D-05,     4.01445513891486808D-05/
+      DATA BETA(111), BETA(112), BETA(113), BETA(114), BETA(115),
+     1     BETA(116), BETA(117), BETA(118), BETA(119), BETA(120),
+     2     BETA(121), BETA(122), BETA(123), BETA(124), BETA(125),
+     3     BETA(126), BETA(127), BETA(128), BETA(129), BETA(130)/
+     4     3.50481730031328081D-05,     3.05157995034346659D-05,
+     5     2.64956119950516039D-05,     2.29363633690998152D-05,
+     6     1.97893056664021636D-05,     1.70091984636412623D-05,
+     7     1.45547428261524004D-05,     1.23886640995878413D-05,
+     8     1.04775876076583236D-05,     8.79179954978479373D-06,
+     9     7.36465810572578444D-04,     8.72790805146193976D-04,
+     A     6.22614862573135066D-04,     2.85998154194304147D-04,
+     B     3.84737672879366102D-06,    -1.87906003636971558D-04,
+     C    -2.97603646594554535D-04,    -3.45998126832656348D-04,
+     D    -3.53382470916037712D-04,    -3.35715635775048757D-04/
+      DATA BETA(131), BETA(132), BETA(133), BETA(134), BETA(135),
+     1     BETA(136), BETA(137), BETA(138), BETA(139), BETA(140),
+     2     BETA(141), BETA(142), BETA(143), BETA(144), BETA(145),
+     3     BETA(146), BETA(147), BETA(148), BETA(149), BETA(150)/
+     4    -3.04321124789039809D-04,    -2.66722723047612821D-04,
+     5    -2.27654214122819527D-04,    -1.89922611854562356D-04,
+     6    -1.55058918599093870D-04,    -1.23778240761873630D-04,
+     7    -9.62926147717644187D-05,    -7.25178327714425337D-05,
+     8    -5.22070028895633801D-05,    -3.50347750511900522D-05,
+     9    -2.06489761035551757D-05,    -8.70106096849767054D-06,
+     A     1.13698686675100290D-06,     9.16426474122778849D-06,
+     B     1.56477785428872620D-05,     2.08223629482466847D-05,
+     C     2.48923381004595156D-05,     2.80340509574146325D-05,
+     D     3.03987774629861915D-05,     3.21156731406700616D-05/
+      DATA BETA(151), BETA(152), BETA(153), BETA(154), BETA(155),
+     1     BETA(156), BETA(157), BETA(158), BETA(159), BETA(160),
+     2     BETA(161), BETA(162), BETA(163), BETA(164), BETA(165),
+     3     BETA(166), BETA(167), BETA(168), BETA(169), BETA(170)/
+     4    -1.80182191963885708D-03,    -2.43402962938042533D-03,
+     5    -1.83422663549856802D-03,    -7.62204596354009765D-04,
+     6     2.39079475256927218D-04,     9.49266117176881141D-04,
+     7     1.34467449701540359D-03,     1.48457495259449178D-03,
+     8     1.44732339830617591D-03,     1.30268261285657186D-03,
+     9     1.10351597375642682D-03,     8.86047440419791759D-04,
+     A     6.73073208165665473D-04,     4.77603872856582378D-04,
+     B     3.05991926358789362D-04,     1.60315694594721630D-04,
+     C     4.00749555270613286D-05,    -5.66607461635251611D-05,
+     D    -1.32506186772982638D-04,    -1.90296187989614057D-04/
+      DATA BETA(171), BETA(172), BETA(173), BETA(174), BETA(175),
+     1     BETA(176), BETA(177), BETA(178), BETA(179), BETA(180),
+     2     BETA(181), BETA(182), BETA(183), BETA(184), BETA(185),
+     3     BETA(186), BETA(187), BETA(188), BETA(189), BETA(190)/
+     4    -2.32811450376937408D-04,    -2.62628811464668841D-04,
+     5    -2.82050469867598672D-04,    -2.93081563192861167D-04,
+     6    -2.97435962176316616D-04,    -2.96557334239348078D-04,
+     7    -2.91647363312090861D-04,    -2.83696203837734166D-04,
+     8    -2.73512317095673346D-04,    -2.61750155806768580D-04,
+     9     6.38585891212050914D-03,     9.62374215806377941D-03,
+     A     7.61878061207001043D-03,     2.83219055545628054D-03,
+     B    -2.09841352012720090D-03,    -5.73826764216626498D-03,
+     C    -7.70804244495414620D-03,    -8.21011692264844401D-03,
+     D    -7.65824520346905413D-03,    -6.47209729391045177D-03/
+      DATA BETA(191), BETA(192), BETA(193), BETA(194), BETA(195),
+     1     BETA(196), BETA(197), BETA(198), BETA(199), BETA(200),
+     2     BETA(201), BETA(202), BETA(203), BETA(204), BETA(205),
+     3     BETA(206), BETA(207), BETA(208), BETA(209), BETA(210)/
+     4    -4.99132412004966473D-03,    -3.45612289713133280D-03,
+     5    -2.01785580014170775D-03,    -7.59430686781961401D-04,
+     6     2.84173631523859138D-04,     1.10891667586337403D-03,
+     7     1.72901493872728771D-03,     2.16812590802684701D-03,
+     8     2.45357710494539735D-03,     2.61281821058334862D-03,
+     9     2.67141039656276912D-03,     2.65203073395980430D-03,
+     A     2.57411652877287315D-03,     2.45389126236094427D-03,
+     B     2.30460058071795494D-03,     2.13684837686712662D-03,
+     C     1.95896528478870911D-03,     1.77737008679454412D-03,
+     D     1.59690280765839059D-03,     1.42111975664438546D-03/
+      DATA GAMA(1), GAMA(2), GAMA(3), GAMA(4), GAMA(5), GAMA(6),
+     1     GAMA(7), GAMA(8), GAMA(9), GAMA(10), GAMA(11), GAMA(12),
+     2     GAMA(13), GAMA(14), GAMA(15), GAMA(16), GAMA(17), GAMA(18),
+     3     GAMA(19), GAMA(20), GAMA(21), GAMA(22)/
+     4     6.29960524947436582D-01,     2.51984209978974633D-01,
+     5     1.54790300415655846D-01,     1.10713062416159013D-01,
+     6     8.57309395527394825D-02,     6.97161316958684292D-02,
+     7     5.86085671893713576D-02,     5.04698873536310685D-02,
+     8     4.42600580689154809D-02,     3.93720661543509966D-02,
+     9     3.54283195924455368D-02,     3.21818857502098231D-02,
+     A     2.94646240791157679D-02,     2.71581677112934479D-02,
+     B     2.51768272973861779D-02,     2.34570755306078891D-02,
+     C     2.19508390134907203D-02,     2.06210828235646240D-02,
+     D     1.94388240897880846D-02,     1.83810633800683158D-02,
+     E     1.74293213231963172D-02,     1.65685837786612353D-02/
+      DATA GAMA(23), GAMA(24), GAMA(25), GAMA(26), GAMA(27), GAMA(28),
+     1     GAMA(29), GAMA(30)/
+     2     1.57865285987918445D-02,     1.50729501494095594D-02,
+     3     1.44193250839954639D-02,     1.38184805735341786D-02,
+     4     1.32643378994276568D-02,     1.27517121970498651D-02,
+     5     1.22761545318762767D-02,     1.18338262398482403D-02/
+      DATA EX1, EX2, HPI, GPI, THPI /
+     1     3.33333333333333333D-01,     6.66666666666666667D-01,
+     2     1.57079632679489662D+00,     3.14159265358979324D+00,
+     3     4.71238898038468986D+00/
+      DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
+C
+      RFNU = 1.0D0/FNU
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST (Z/FNU TOO SMALL)
+C-----------------------------------------------------------------------
+      TEST = D1MACH(1)*1.0D+3
+      AC = FNU*TEST
+      IF (DABS(ZR).GT.AC .OR. DABS(ZI).GT.AC) GO TO 15
+      ZETA1R = 2.0D0*DABS(DLOG(TEST))+FNU
+      ZETA1I = 0.0D0
+      ZETA2R = FNU
+      ZETA2I = 0.0D0
+      PHIR = 1.0D0
+      PHII = 0.0D0
+      ARGR = 1.0D0
+      ARGI = 0.0D0
+      RETURN
+   15 CONTINUE
+      ZBR = ZR*RFNU
+      ZBI = ZI*RFNU
+      RFNU2 = RFNU*RFNU
+C-----------------------------------------------------------------------
+C     COMPUTE IN THE FOURTH QUADRANT
+C-----------------------------------------------------------------------
+      FN13 = FNU**EX1
+      FN23 = FN13*FN13
+      RFN13 = 1.0D0/FN13
+      W2R = CONER - ZBR*ZBR + ZBI*ZBI
+      W2I = CONEI - ZBR*ZBI - ZBR*ZBI
+      AW2 = XZABS(W2R,W2I)
+      IF (AW2.GT.0.25D0) GO TO 130
+C-----------------------------------------------------------------------
+C     POWER SERIES FOR CABS(W2).LE.0.25D0
+C-----------------------------------------------------------------------
+      K = 1
+      PR(1) = CONER
+      PI(1) = CONEI
+      SUMAR = GAMA(1)
+      SUMAI = ZEROI
+      AP(1) = 1.0D0
+      IF (AW2.LT.TOL) GO TO 20
+      DO 10 K=2,30
+        PR(K) = PR(K-1)*W2R - PI(K-1)*W2I
+        PI(K) = PR(K-1)*W2I + PI(K-1)*W2R
+        SUMAR = SUMAR + PR(K)*GAMA(K)
+        SUMAI = SUMAI + PI(K)*GAMA(K)
+        AP(K) = AP(K-1)*AW2
+        IF (AP(K).LT.TOL) GO TO 20
+   10 CONTINUE
+      K = 30
+   20 CONTINUE
+      KMAX = K
+      ZETAR = W2R*SUMAR - W2I*SUMAI
+      ZETAI = W2R*SUMAI + W2I*SUMAR
+      ARGR = ZETAR*FN23
+      ARGI = ZETAI*FN23
+      CALL XZSQRT(SUMAR, SUMAI, ZAR, ZAI)
+      CALL XZSQRT(W2R, W2I, STR, STI)
+      ZETA2R = STR*FNU
+      ZETA2I = STI*FNU
+      STR = CONER + EX2*(ZETAR*ZAR-ZETAI*ZAI)
+      STI = CONEI + EX2*(ZETAR*ZAI+ZETAI*ZAR)
+      ZETA1R = STR*ZETA2R - STI*ZETA2I
+      ZETA1I = STR*ZETA2I + STI*ZETA2R
+      ZAR = ZAR + ZAR
+      ZAI = ZAI + ZAI
+      CALL XZSQRT(ZAR, ZAI, STR, STI)
+      PHIR = STR*RFN13
+      PHII = STI*RFN13
+      IF (IPMTR.EQ.1) GO TO 120
+C-----------------------------------------------------------------------
+C     SUM SERIES FOR ASUM AND BSUM
+C-----------------------------------------------------------------------
+      SUMBR = ZEROR
+      SUMBI = ZEROI
+      DO 30 K=1,KMAX
+        SUMBR = SUMBR + PR(K)*BETA(K)
+        SUMBI = SUMBI + PI(K)*BETA(K)
+   30 CONTINUE
+      ASUMR = ZEROR
+      ASUMI = ZEROI
+      BSUMR = SUMBR
+      BSUMI = SUMBI
+      L1 = 0
+      L2 = 30
+      BTOL = TOL*(DABS(BSUMR)+DABS(BSUMI))
+      ATOL = TOL
+      PP = 1.0D0
+      IAS = 0
+      IBS = 0
+      IF (RFNU2.LT.TOL) GO TO 110
+      DO 100 IS=2,7
+        ATOL = ATOL/RFNU2
+        PP = PP*RFNU2
+        IF (IAS.EQ.1) GO TO 60
+        SUMAR = ZEROR
+        SUMAI = ZEROI
+        DO 40 K=1,KMAX
+          M = L1 + K
+          SUMAR = SUMAR + PR(K)*ALFA(M)
+          SUMAI = SUMAI + PI(K)*ALFA(M)
+          IF (AP(K).LT.ATOL) GO TO 50
+   40   CONTINUE
+   50   CONTINUE
+        ASUMR = ASUMR + SUMAR*PP
+        ASUMI = ASUMI + SUMAI*PP
+        IF (PP.LT.TOL) IAS = 1
+   60   CONTINUE
+        IF (IBS.EQ.1) GO TO 90
+        SUMBR = ZEROR
+        SUMBI = ZEROI
+        DO 70 K=1,KMAX
+          M = L2 + K
+          SUMBR = SUMBR + PR(K)*BETA(M)
+          SUMBI = SUMBI + PI(K)*BETA(M)
+          IF (AP(K).LT.ATOL) GO TO 80
+   70   CONTINUE
+   80   CONTINUE
+        BSUMR = BSUMR + SUMBR*PP
+        BSUMI = BSUMI + SUMBI*PP
+        IF (PP.LT.BTOL) IBS = 1
+   90   CONTINUE
+        IF (IAS.EQ.1 .AND. IBS.EQ.1) GO TO 110
+        L1 = L1 + 30
+        L2 = L2 + 30
+  100 CONTINUE
+  110 CONTINUE
+      ASUMR = ASUMR + CONER
+      PP = RFNU*RFN13
+      BSUMR = BSUMR*PP
+      BSUMI = BSUMI*PP
+  120 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     CABS(W2).GT.0.25D0
+C-----------------------------------------------------------------------
+  130 CONTINUE
+      CALL XZSQRT(W2R, W2I, WR, WI)
+      IF (WR.LT.0.0D0) WR = 0.0D0
+      IF (WI.LT.0.0D0) WI = 0.0D0
+      STR = CONER + WR
+      STI = WI
+      CALL ZDIV(STR, STI, ZBR, ZBI, ZAR, ZAI)
+      CALL XZLOG(ZAR, ZAI, ZCR, ZCI, IDUM)
+      IF (ZCI.LT.0.0D0) ZCI = 0.0D0
+      IF (ZCI.GT.HPI) ZCI = HPI
+      IF (ZCR.LT.0.0D0) ZCR = 0.0D0
+      ZTHR = (ZCR-WR)*1.5D0
+      ZTHI = (ZCI-WI)*1.5D0
+      ZETA1R = ZCR*FNU
+      ZETA1I = ZCI*FNU
+      ZETA2R = WR*FNU
+      ZETA2I = WI*FNU
+      AZTH = XZABS(ZTHR,ZTHI)
+      ANG = THPI
+      IF (ZTHR.GE.0.0D0 .AND. ZTHI.LT.0.0D0) GO TO 140
+      ANG = HPI
+      IF (ZTHR.EQ.0.0D0) GO TO 140
+      ANG = DATAN(ZTHI/ZTHR)
+      IF (ZTHR.LT.0.0D0) ANG = ANG + GPI
+  140 CONTINUE
+      PP = AZTH**EX2
+      ANG = ANG*EX2
+      ZETAR = PP*DCOS(ANG)
+      ZETAI = PP*DSIN(ANG)
+      IF (ZETAI.LT.0.0D0) ZETAI = 0.0D0
+      ARGR = ZETAR*FN23
+      ARGI = ZETAI*FN23
+      CALL ZDIV(ZTHR, ZTHI, ZETAR, ZETAI, RTZTR, RTZTI)
+      CALL ZDIV(RTZTR, RTZTI, WR, WI, ZAR, ZAI)
+      TZAR = ZAR + ZAR
+      TZAI = ZAI + ZAI
+      CALL XZSQRT(TZAR, TZAI, STR, STI)
+      PHIR = STR*RFN13
+      PHII = STI*RFN13
+      IF (IPMTR.EQ.1) GO TO 120
+      RAW = 1.0D0/DSQRT(AW2)
+      STR = WR*RAW
+      STI = -WI*RAW
+      TFNR = STR*RFNU*RAW
+      TFNI = STI*RFNU*RAW
+      RAZTH = 1.0D0/AZTH
+      STR = ZTHR*RAZTH
+      STI = -ZTHI*RAZTH
+      RZTHR = STR*RAZTH*RFNU
+      RZTHI = STI*RAZTH*RFNU
+      ZCR = RZTHR*AR(2)
+      ZCI = RZTHI*AR(2)
+      RAW2 = 1.0D0/AW2
+      STR = W2R*RAW2
+      STI = -W2I*RAW2
+      T2R = STR*RAW2
+      T2I = STI*RAW2
+      STR = T2R*C(2) + C(3)
+      STI = T2I*C(2)
+      UPR(2) = STR*TFNR - STI*TFNI
+      UPI(2) = STR*TFNI + STI*TFNR
+      BSUMR = UPR(2) + ZCR
+      BSUMI = UPI(2) + ZCI
+      ASUMR = ZEROR
+      ASUMI = ZEROI
+      IF (RFNU.LT.TOL) GO TO 220
+      PRZTHR = RZTHR
+      PRZTHI = RZTHI
+      PTFNR = TFNR
+      PTFNI = TFNI
+      UPR(1) = CONER
+      UPI(1) = CONEI
+      PP = 1.0D0
+      BTOL = TOL*(DABS(BSUMR)+DABS(BSUMI))
+      KS = 0
+      KP1 = 2
+      L = 3
+      IAS = 0
+      IBS = 0
+      DO 210 LR=2,12,2
+        LRP1 = LR + 1
+C-----------------------------------------------------------------------
+C     COMPUTE TWO ADDITIONAL CR, DR, AND UP FOR TWO MORE TERMS IN
+C     NEXT SUMA AND SUMB
+C-----------------------------------------------------------------------
+        DO 160 K=LR,LRP1
+          KS = KS + 1
+          KP1 = KP1 + 1
+          L = L + 1
+          ZAR = C(L)
+          ZAI = ZEROI
+          DO 150 J=2,KP1
+            L = L + 1
+            STR = ZAR*T2R - T2I*ZAI + C(L)
+            ZAI = ZAR*T2I + ZAI*T2R
+            ZAR = STR
+  150     CONTINUE
+          STR = PTFNR*TFNR - PTFNI*TFNI
+          PTFNI = PTFNR*TFNI + PTFNI*TFNR
+          PTFNR = STR
+          UPR(KP1) = PTFNR*ZAR - PTFNI*ZAI
+          UPI(KP1) = PTFNI*ZAR + PTFNR*ZAI
+          CRR(KS) = PRZTHR*BR(KS+1)
+          CRI(KS) = PRZTHI*BR(KS+1)
+          STR = PRZTHR*RZTHR - PRZTHI*RZTHI
+          PRZTHI = PRZTHR*RZTHI + PRZTHI*RZTHR
+          PRZTHR = STR
+          DRR(KS) = PRZTHR*AR(KS+2)
+          DRI(KS) = PRZTHI*AR(KS+2)
+  160   CONTINUE
+        PP = PP*RFNU2
+        IF (IAS.EQ.1) GO TO 180
+        SUMAR = UPR(LRP1)
+        SUMAI = UPI(LRP1)
+        JU = LRP1
+        DO 170 JR=1,LR
+          JU = JU - 1
+          SUMAR = SUMAR + CRR(JR)*UPR(JU) - CRI(JR)*UPI(JU)
+          SUMAI = SUMAI + CRR(JR)*UPI(JU) + CRI(JR)*UPR(JU)
+  170   CONTINUE
+        ASUMR = ASUMR + SUMAR
+        ASUMI = ASUMI + SUMAI
+        TEST = DABS(SUMAR) + DABS(SUMAI)
+        IF (PP.LT.TOL .AND. TEST.LT.TOL) IAS = 1
+  180   CONTINUE
+        IF (IBS.EQ.1) GO TO 200
+        SUMBR = UPR(LR+2) + UPR(LRP1)*ZCR - UPI(LRP1)*ZCI
+        SUMBI = UPI(LR+2) + UPR(LRP1)*ZCI + UPI(LRP1)*ZCR
+        JU = LRP1
+        DO 190 JR=1,LR
+          JU = JU - 1
+          SUMBR = SUMBR + DRR(JR)*UPR(JU) - DRI(JR)*UPI(JU)
+          SUMBI = SUMBI + DRR(JR)*UPI(JU) + DRI(JR)*UPR(JU)
+  190   CONTINUE
+        BSUMR = BSUMR + SUMBR
+        BSUMI = BSUMI + SUMBI
+        TEST = DABS(SUMBR) + DABS(SUMBI)
+        IF (PP.LT.BTOL .AND. TEST.LT.BTOL) IBS = 1
+  200   CONTINUE
+        IF (IAS.EQ.1 .AND. IBS.EQ.1) GO TO 220
+  210 CONTINUE
+  220 CONTINUE
+      ASUMR = ASUMR + CONER
+      STR = -BSUMR*RFN13
+      STI = -BSUMI*RFN13
+      CALL ZDIV(STR, STI, RTZTR, RTZTI, BSUMR, BSUMI)
+      GO TO 120
+      END
diff --git a/libcruft/amos/zuni1.f b/libcruft/amos/zuni1.f
new file mode 100644
index 0000000..a4694e5
--- /dev/null
+++ b/libcruft/amos/zuni1.f
@@ -0,0 +1,204 @@
+      SUBROUTINE ZUNI1(ZR, ZI, FNU, KODE, N, YR, YI, NZ, NLAST, FNUL,
+     * TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  ZUNI1
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZUNI1 COMPUTES I(FNU,Z)  BY MEANS OF THE UNIFORM ASYMPTOTIC
+C     EXPANSION FOR I(FNU,Z) IN -PI/3.LE.ARG Z.LE.PI/3.
+C
+C     FNUL IS THE SMALLEST ORDER PERMITTED FOR THE ASYMPTOTIC
+C     EXPANSION. NLAST=0 MEANS ALL OF THE Y VALUES WERE SET.
+C     NLAST.NE.0 IS THE NUMBER LEFT TO BE COMPUTED BY ANOTHER
+C     FORMULA FOR ORDERS FNU TO FNU+NLAST-1 BECAUSE FNU+NLAST-1.LT.FNUL.
+C     Y(I)=CZERO FOR I=NLAST+1,N
+C
+C***ROUTINES CALLED  ZUCHK,ZUNIK,ZUOIK,D1MACH,XZABS
+C***END PROLOGUE  ZUNI1
+C     COMPLEX CFN,CONE,CRSC,CSCL,CSR,CSS,CWRK,CZERO,C1,C2,PHI,RZ,SUM,S1,
+C    *S2,Y,Z,ZETA1,ZETA2
+      DOUBLE PRECISION ALIM, APHI, ASCLE, BRY, CONER, CRSC,
+     * CSCL, CSRR, CSSR, CWRKI, CWRKR, C1R, C2I, C2M, C2R, ELIM, FN,
+     * FNU, FNUL, PHII, PHIR, RAST, RS1, RZI, RZR, STI, STR, SUMI,
+     * SUMR, S1I, S1R, S2I, S2R, TOL, YI, YR, ZEROI, ZEROR, ZETA1I,
+     * ZETA1R, ZETA2I, ZETA2R, ZI, ZR, CYR, CYI, D1MACH, XZABS
+      INTEGER I, IFLAG, INIT, K, KODE, M, N, ND, NLAST, NN, NUF, NW, NZ
+      DIMENSION BRY(3), YR(N), YI(N), CWRKR(16), CWRKI(16), CSSR(3),
+     * CSRR(3), CYR(2), CYI(2)
+      DATA ZEROR,ZEROI,CONER / 0.0D0, 0.0D0, 1.0D0 /
+C
+      NZ = 0
+      ND = N
+      NLAST = 0
+C-----------------------------------------------------------------------
+C     COMPUTED VALUES WITH EXPONENTS BETWEEN ALIM AND ELIM IN MAG-
+C     NITUDE ARE SCALED TO KEEP INTERMEDIATE ARITHMETIC ON SCALE,
+C     EXP(ALIM)=EXP(ELIM)*TOL
+C-----------------------------------------------------------------------
+      CSCL = 1.0D0/TOL
+      CRSC = TOL
+      CSSR(1) = CSCL
+      CSSR(2) = CONER
+      CSSR(3) = CRSC
+      CSRR(1) = CRSC
+      CSRR(2) = CONER
+      CSRR(3) = CSCL
+      BRY(1) = 1.0D+3*D1MACH(1)/TOL
+C-----------------------------------------------------------------------
+C     CHECK FOR UNDERFLOW AND OVERFLOW ON FIRST MEMBER
+C-----------------------------------------------------------------------
+      FN = DMAX1(FNU,1.0D0)
+      INIT = 0
+      CALL ZUNIK(ZR, ZI, FN, 1, 1, TOL, INIT, PHIR, PHII, ZETA1R,
+     * ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
+      IF (KODE.EQ.1) GO TO 10
+      STR = ZR + ZETA2R
+      STI = ZI + ZETA2I
+      RAST = FN/XZABS(STR,STI)
+      STR = STR*RAST*RAST
+      STI = -STI*RAST*RAST
+      S1R = -ZETA1R + STR
+      S1I = -ZETA1I + STI
+      GO TO 20
+   10 CONTINUE
+      S1R = -ZETA1R + ZETA2R
+      S1I = -ZETA1I + ZETA2I
+   20 CONTINUE
+      RS1 = S1R
+      IF (DABS(RS1).GT.ELIM) GO TO 130
+   30 CONTINUE
+      NN = MIN0(2,ND)
+      DO 80 I=1,NN
+        FN = FNU + DBLE(FLOAT(ND-I))
+        INIT = 0
+        CALL ZUNIK(ZR, ZI, FN, 1, 0, TOL, INIT, PHIR, PHII, ZETA1R,
+     *   ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
+        IF (KODE.EQ.1) GO TO 40
+        STR = ZR + ZETA2R
+        STI = ZI + ZETA2I
+        RAST = FN/XZABS(STR,STI)
+        STR = STR*RAST*RAST
+        STI = -STI*RAST*RAST
+        S1R = -ZETA1R + STR
+        S1I = -ZETA1I + STI + ZI
+        GO TO 50
+   40   CONTINUE
+        S1R = -ZETA1R + ZETA2R
+        S1I = -ZETA1I + ZETA2I
+   50   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = S1R
+        IF (DABS(RS1).GT.ELIM) GO TO 110
+        IF (I.EQ.1) IFLAG = 2
+        IF (DABS(RS1).LT.ALIM) GO TO 60
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = XZABS(PHIR,PHII)
+        RS1 = RS1 + DLOG(APHI)
+        IF (DABS(RS1).GT.ELIM) GO TO 110
+        IF (I.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0D0) GO TO 60
+        IF (I.EQ.1) IFLAG = 3
+   60   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 IF CABS(S1).LT.ASCLE
+C-----------------------------------------------------------------------
+        S2R = PHIR*SUMR - PHII*SUMI
+        S2I = PHIR*SUMI + PHII*SUMR
+        STR = DEXP(S1R)*CSSR(IFLAG)
+        S1R = STR*DCOS(S1I)
+        S1I = STR*DSIN(S1I)
+        STR = S2R*S1R - S2I*S1I
+        S2I = S2R*S1I + S2I*S1R
+        S2R = STR
+        IF (IFLAG.NE.1) GO TO 70
+        CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 110
+   70   CONTINUE
+        CYR(I) = S2R
+        CYI(I) = S2I
+        M = ND - I + 1
+        YR(M) = S2R*CSRR(IFLAG)
+        YI(M) = S2I*CSRR(IFLAG)
+   80 CONTINUE
+      IF (ND.LE.2) GO TO 100
+      RAST = 1.0D0/XZABS(ZR,ZI)
+      STR = ZR*RAST
+      STI = -ZI*RAST
+      RZR = (STR+STR)*RAST
+      RZI = (STI+STI)*RAST
+      BRY(2) = 1.0D0/BRY(1)
+      BRY(3) = D1MACH(2)
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      C1R = CSRR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      K = ND - 2
+      FN = DBLE(FLOAT(K))
+      DO 90 I=3,ND
+        C2R = S2R
+        C2I = S2I
+        S2R = S1R + (FNU+FN)*(RZR*C2R-RZI*C2I)
+        S2I = S1I + (FNU+FN)*(RZR*C2I+RZI*C2R)
+        S1R = C2R
+        S1I = C2I
+        C2R = S2R*C1R
+        C2I = S2I*C1R
+        YR(K) = C2R
+        YI(K) = C2I
+        K = K - 1
+        FN = FN - 1.0D0
+        IF (IFLAG.GE.3) GO TO 90
+        STR = DABS(C2R)
+        STI = DABS(C2I)
+        C2M = DMAX1(STR,STI)
+        IF (C2M.LE.ASCLE) GO TO 90
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1R = S1R*C1R
+        S1I = S1I*C1R
+        S2R = C2R
+        S2I = C2I
+        S1R = S1R*CSSR(IFLAG)
+        S1I = S1I*CSSR(IFLAG)
+        S2R = S2R*CSSR(IFLAG)
+        S2I = S2I*CSSR(IFLAG)
+        C1R = CSRR(IFLAG)
+   90 CONTINUE
+  100 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C     SET UNDERFLOW AND UPDATE PARAMETERS
+C-----------------------------------------------------------------------
+  110 CONTINUE
+      IF (RS1.GT.0.0D0) GO TO 120
+      YR(ND) = ZEROR
+      YI(ND) = ZEROI
+      NZ = NZ + 1
+      ND = ND - 1
+      IF (ND.EQ.0) GO TO 100
+      CALL ZUOIK(ZR, ZI, FNU, KODE, 1, ND, YR, YI, NUF, TOL, ELIM, ALIM)
+      IF (NUF.LT.0) GO TO 120
+      ND = ND - NUF
+      NZ = NZ + NUF
+      IF (ND.EQ.0) GO TO 100
+      FN = FNU + DBLE(FLOAT(ND-1))
+      IF (FN.GE.FNUL) GO TO 30
+      NLAST = ND
+      RETURN
+  120 CONTINUE
+      NZ = -1
+      RETURN
+  130 CONTINUE
+      IF (RS1.GT.0.0D0) GO TO 120
+      NZ = N
+      DO 140 I=1,N
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+  140 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/zuni2.f b/libcruft/amos/zuni2.f
new file mode 100644
index 0000000..026b54b
--- /dev/null
+++ b/libcruft/amos/zuni2.f
@@ -0,0 +1,267 @@
+      SUBROUTINE ZUNI2(ZR, ZI, FNU, KODE, N, YR, YI, NZ, NLAST, FNUL,
+     * TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  ZUNI2
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZUNI2 COMPUTES I(FNU,Z) IN THE RIGHT HALF PLANE BY MEANS OF
+C     UNIFORM ASYMPTOTIC EXPANSION FOR J(FNU,ZN) WHERE ZN IS Z*I
+C     OR -Z*I AND ZN IS IN THE RIGHT HALF PLANE ALSO.
+C
+C     FNUL IS THE SMALLEST ORDER PERMITTED FOR THE ASYMPTOTIC
+C     EXPANSION. NLAST=0 MEANS ALL OF THE Y VALUES WERE SET.
+C     NLAST.NE.0 IS THE NUMBER LEFT TO BE COMPUTED BY ANOTHER
+C     FORMULA FOR ORDERS FNU TO FNU+NLAST-1 BECAUSE FNU+NLAST-1.LT.FNUL.
+C     Y(I)=CZERO FOR I=NLAST+1,N
+C
+C***ROUTINES CALLED  ZAIRY,ZUCHK,ZUNHJ,ZUOIK,D1MACH,XZABS
+C***END PROLOGUE  ZUNI2
+C     COMPLEX AI,ARG,ASUM,BSUM,CFN,CI,CID,CIP,CONE,CRSC,CSCL,CSR,CSS,
+C    *CZERO,C1,C2,DAI,PHI,RZ,S1,S2,Y,Z,ZB,ZETA1,ZETA2,ZN
+      DOUBLE PRECISION AARG, AIC, AII, AIR, ALIM, ANG, APHI, ARGI,
+     * ARGR, ASCLE, ASUMI, ASUMR, BRY, BSUMI, BSUMR, CIDI, CIPI, CIPR,
+     * CONER, CRSC, CSCL, CSRR, CSSR, C1R, C2I, C2M, C2R, DAII,
+     * DAIR, ELIM, FN, FNU, FNUL, HPI, PHII, PHIR, RAST, RAZ, RS1, RZI,
+     * RZR, STI, STR, S1I, S1R, S2I, S2R, TOL, YI, YR, ZBI, ZBR, ZEROI,
+     * ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZI, ZNI, ZNR, ZR, CYR,
+     * CYI, D1MACH, XZABS, CAR, SAR
+      INTEGER I, IFLAG, IN, INU, J, K, KODE, N, NAI, ND, NDAI, NLAST,
+     * NN, NUF, NW, NZ, IDUM
+      DIMENSION BRY(3), YR(N), YI(N), CIPR(4), CIPI(4), CSSR(3),
+     * CSRR(3), CYR(2), CYI(2)
+      DATA ZEROR,ZEROI,CONER / 0.0D0, 0.0D0, 1.0D0 /
+      DATA CIPR(1),CIPI(1),CIPR(2),CIPI(2),CIPR(3),CIPI(3),CIPR(4),
+     * CIPI(4)/ 1.0D0,0.0D0, 0.0D0,1.0D0, -1.0D0,0.0D0, 0.0D0,-1.0D0/
+      DATA HPI, AIC  /
+     1      1.57079632679489662D+00,     1.265512123484645396D+00/
+C
+      NZ = 0
+      ND = N
+      NLAST = 0
+C-----------------------------------------------------------------------
+C     COMPUTED VALUES WITH EXPONENTS BETWEEN ALIM AND ELIM IN MAG-
+C     NITUDE ARE SCALED TO KEEP INTERMEDIATE ARITHMETIC ON SCALE,
+C     EXP(ALIM)=EXP(ELIM)*TOL
+C-----------------------------------------------------------------------
+      CSCL = 1.0D0/TOL
+      CRSC = TOL
+      CSSR(1) = CSCL
+      CSSR(2) = CONER
+      CSSR(3) = CRSC
+      CSRR(1) = CRSC
+      CSRR(2) = CONER
+      CSRR(3) = CSCL
+      BRY(1) = 1.0D+3*D1MACH(1)/TOL
+C-----------------------------------------------------------------------
+C     ZN IS IN THE RIGHT HALF PLANE AFTER ROTATION BY CI OR -CI
+C-----------------------------------------------------------------------
+      ZNR = ZI
+      ZNI = -ZR
+      ZBR = ZR
+      ZBI = ZI
+      CIDI = -CONER
+      INU = INT(SNGL(FNU))
+      ANG = HPI*(FNU-DBLE(FLOAT(INU)))
+      C2R = DCOS(ANG)
+      C2I = DSIN(ANG)
+      CAR = C2R
+      SAR = C2I
+      IN = INU + N - 1
+      IN = MOD(IN,4) + 1
+      STR = C2R*CIPR(IN) - C2I*CIPI(IN)
+      C2I = C2R*CIPI(IN) + C2I*CIPR(IN)
+      C2R = STR
+      IF (ZI.GT.0.0D0) GO TO 10
+      ZNR = -ZNR
+      ZBI = -ZBI
+      CIDI = -CIDI
+      C2I = -C2I
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     CHECK FOR UNDERFLOW AND OVERFLOW ON FIRST MEMBER
+C-----------------------------------------------------------------------
+      FN = DMAX1(FNU,1.0D0)
+      CALL ZUNHJ(ZNR, ZNI, FN, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R,
+     * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
+      IF (KODE.EQ.1) GO TO 20
+      STR = ZBR + ZETA2R
+      STI = ZBI + ZETA2I
+      RAST = FN/XZABS(STR,STI)
+      STR = STR*RAST*RAST
+      STI = -STI*RAST*RAST
+      S1R = -ZETA1R + STR
+      S1I = -ZETA1I + STI
+      GO TO 30
+   20 CONTINUE
+      S1R = -ZETA1R + ZETA2R
+      S1I = -ZETA1I + ZETA2I
+   30 CONTINUE
+      RS1 = S1R
+      IF (DABS(RS1).GT.ELIM) GO TO 150
+   40 CONTINUE
+      NN = MIN0(2,ND)
+      DO 90 I=1,NN
+        FN = FNU + DBLE(FLOAT(ND-I))
+        CALL ZUNHJ(ZNR, ZNI, FN, 0, TOL, PHIR, PHII, ARGR, ARGI,
+     *   ZETA1R, ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
+        IF (KODE.EQ.1) GO TO 50
+        STR = ZBR + ZETA2R
+        STI = ZBI + ZETA2I
+        RAST = FN/XZABS(STR,STI)
+        STR = STR*RAST*RAST
+        STI = -STI*RAST*RAST
+        S1R = -ZETA1R + STR
+        S1I = -ZETA1I + STI + DABS(ZI)
+        GO TO 60
+   50   CONTINUE
+        S1R = -ZETA1R + ZETA2R
+        S1I = -ZETA1I + ZETA2I
+   60   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = S1R
+        IF (DABS(RS1).GT.ELIM) GO TO 120
+        IF (I.EQ.1) IFLAG = 2
+        IF (DABS(RS1).LT.ALIM) GO TO 70
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+        APHI = XZABS(PHIR,PHII)
+        AARG = XZABS(ARGR,ARGI)
+        RS1 = RS1 + DLOG(APHI) - 0.25D0*DLOG(AARG) - AIC
+        IF (DABS(RS1).GT.ELIM) GO TO 120
+        IF (I.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0D0) GO TO 70
+        IF (I.EQ.1) IFLAG = 3
+   70   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR
+C     EXPONENT EXTREMES
+C-----------------------------------------------------------------------
+        CALL ZAIRY(ARGR, ARGI, 0, 2, AIR, AII, NAI, IDUM)
+        CALL ZAIRY(ARGR, ARGI, 1, 2, DAIR, DAII, NDAI, IDUM)
+        STR = DAIR*BSUMR - DAII*BSUMI
+        STI = DAIR*BSUMI + DAII*BSUMR
+        STR = STR + (AIR*ASUMR-AII*ASUMI)
+        STI = STI + (AIR*ASUMI+AII*ASUMR)
+        S2R = PHIR*STR - PHII*STI
+        S2I = PHIR*STI + PHII*STR
+        STR = DEXP(S1R)*CSSR(IFLAG)
+        S1R = STR*DCOS(S1I)
+        S1I = STR*DSIN(S1I)
+        STR = S2R*S1R - S2I*S1I
+        S2I = S2R*S1I + S2I*S1R
+        S2R = STR
+        IF (IFLAG.NE.1) GO TO 80
+        CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 120
+   80   CONTINUE
+        IF (ZI.LE.0.0D0) S2I = -S2I
+        STR = S2R*C2R - S2I*C2I
+        S2I = S2R*C2I + S2I*C2R
+        S2R = STR
+        CYR(I) = S2R
+        CYI(I) = S2I
+        J = ND - I + 1
+        YR(J) = S2R*CSRR(IFLAG)
+        YI(J) = S2I*CSRR(IFLAG)
+        STR = -C2I*CIDI
+        C2I = C2R*CIDI
+        C2R = STR
+   90 CONTINUE
+      IF (ND.LE.2) GO TO 110
+      RAZ = 1.0D0/XZABS(ZR,ZI)
+      STR = ZR*RAZ
+      STI = -ZI*RAZ
+      RZR = (STR+STR)*RAZ
+      RZI = (STI+STI)*RAZ
+      BRY(2) = 1.0D0/BRY(1)
+      BRY(3) = D1MACH(2)
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      C1R = CSRR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      K = ND - 2
+      FN = DBLE(FLOAT(K))
+      DO 100 I=3,ND
+        C2R = S2R
+        C2I = S2I
+        S2R = S1R + (FNU+FN)*(RZR*C2R-RZI*C2I)
+        S2I = S1I + (FNU+FN)*(RZR*C2I+RZI*C2R)
+        S1R = C2R
+        S1I = C2I
+        C2R = S2R*C1R
+        C2I = S2I*C1R
+        YR(K) = C2R
+        YI(K) = C2I
+        K = K - 1
+        FN = FN - 1.0D0
+        IF (IFLAG.GE.3) GO TO 100
+        STR = DABS(C2R)
+        STI = DABS(C2I)
+        C2M = DMAX1(STR,STI)
+        IF (C2M.LE.ASCLE) GO TO 100
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1R = S1R*C1R
+        S1I = S1I*C1R
+        S2R = C2R
+        S2I = C2I
+        S1R = S1R*CSSR(IFLAG)
+        S1I = S1I*CSSR(IFLAG)
+        S2R = S2R*CSSR(IFLAG)
+        S2I = S2I*CSSR(IFLAG)
+        C1R = CSRR(IFLAG)
+  100 CONTINUE
+  110 CONTINUE
+      RETURN
+  120 CONTINUE
+      IF (RS1.GT.0.0D0) GO TO 140
+C-----------------------------------------------------------------------
+C     SET UNDERFLOW AND UPDATE PARAMETERS
+C-----------------------------------------------------------------------
+      YR(ND) = ZEROR
+      YI(ND) = ZEROI
+      NZ = NZ + 1
+      ND = ND - 1
+      IF (ND.EQ.0) GO TO 110
+      CALL ZUOIK(ZR, ZI, FNU, KODE, 1, ND, YR, YI, NUF, TOL, ELIM, ALIM)
+      IF (NUF.LT.0) GO TO 140
+      ND = ND - NUF
+      NZ = NZ + NUF
+      IF (ND.EQ.0) GO TO 110
+      FN = FNU + DBLE(FLOAT(ND-1))
+      IF (FN.LT.FNUL) GO TO 130
+C      FN = CIDI
+C      J = NUF + 1
+C      K = MOD(J,4) + 1
+C      S1R = CIPR(K)
+C      S1I = CIPI(K)
+C      IF (FN.LT.0.0D0) S1I = -S1I
+C      STR = C2R*S1R - C2I*S1I
+C      C2I = C2R*S1I + C2I*S1R
+C      C2R = STR
+      IN = INU + ND - 1
+      IN = MOD(IN,4) + 1
+      C2R = CAR*CIPR(IN) - SAR*CIPI(IN)
+      C2I = CAR*CIPI(IN) + SAR*CIPR(IN)
+      IF (ZI.LE.0.0D0) C2I = -C2I
+      GO TO 40
+  130 CONTINUE
+      NLAST = ND
+      RETURN
+  140 CONTINUE
+      NZ = -1
+      RETURN
+  150 CONTINUE
+      IF (RS1.GT.0.0D0) GO TO 140
+      NZ = N
+      DO 160 I=1,N
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+  160 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/amos/zunik.f b/libcruft/amos/zunik.f
new file mode 100644
index 0000000..f34f385
--- /dev/null
+++ b/libcruft/amos/zunik.f
@@ -0,0 +1,211 @@
+      SUBROUTINE ZUNIK(ZRR, ZRI, FNU, IKFLG, IPMTR, TOL, INIT, PHIR,
+     * PHII, ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
+C***BEGIN PROLOGUE  ZUNIK
+C***REFER TO  ZBESI,ZBESK
+C
+C        ZUNIK COMPUTES PARAMETERS FOR THE UNIFORM ASYMPTOTIC
+C        EXPANSIONS OF THE I AND K FUNCTIONS ON IKFLG= 1 OR 2
+C        RESPECTIVELY BY
+C
+C        W(FNU,ZR) = PHI*EXP(ZETA)*SUM
+C
+C        WHERE       ZETA=-ZETA1 + ZETA2       OR
+C                          ZETA1 - ZETA2
+C
+C        THE FIRST CALL MUST HAVE INIT=0. SUBSEQUENT CALLS WITH THE
+C        SAME ZR AND FNU WILL RETURN THE I OR K FUNCTION ON IKFLG=
+C        1 OR 2 WITH NO CHANGE IN INIT. CWRK IS A COMPLEX WORK
+C        ARRAY. IPMTR=0 COMPUTES ALL PARAMETERS. IPMTR=1 COMPUTES PHI,
+C        ZETA1,ZETA2.
+C
+C***ROUTINES CALLED  ZDIV,XZLOG,XZSQRT,D1MACH
+C***END PROLOGUE  ZUNIK
+C     COMPLEX CFN,CON,CONE,CRFN,CWRK,CZERO,PHI,S,SR,SUM,T,T2,ZETA1,
+C    *ZETA2,ZN,ZR
+      DOUBLE PRECISION AC, C, CON, CONEI, CONER, CRFNI, CRFNR, CWRKI,
+     * CWRKR, FNU, PHII, PHIR, RFN, SI, SR, SRI, SRR, STI, STR, SUMI,
+     * SUMR, TEST, TI, TOL, TR, T2I, T2R, ZEROI, ZEROR, ZETA1I, ZETA1R,
+     * ZETA2I, ZETA2R, ZNI, ZNR, ZRI, ZRR, D1MACH
+      INTEGER I, IDUM, IKFLG, INIT, IPMTR, J, K, L
+      DIMENSION C(120), CWRKR(16), CWRKI(16), CON(2)
+      DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
+      DATA CON(1), CON(2)  /
+     1 3.98942280401432678D-01,  1.25331413731550025D+00 /
+      DATA C(1), C(2), C(3), C(4), C(5), C(6), C(7), C(8), C(9), C(10),
+     1     C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18),
+     2     C(19), C(20), C(21), C(22), C(23), C(24)/
+     3     1.00000000000000000D+00,    -2.08333333333333333D-01,
+     4     1.25000000000000000D-01,     3.34201388888888889D-01,
+     5    -4.01041666666666667D-01,     7.03125000000000000D-02,
+     6    -1.02581259645061728D+00,     1.84646267361111111D+00,
+     7    -8.91210937500000000D-01,     7.32421875000000000D-02,
+     8     4.66958442342624743D+00,    -1.12070026162229938D+01,
+     9     8.78912353515625000D+00,    -2.36408691406250000D+00,
+     A     1.12152099609375000D-01,    -2.82120725582002449D+01,
+     B     8.46362176746007346D+01,    -9.18182415432400174D+01,
+     C     4.25349987453884549D+01,    -7.36879435947963170D+00,
+     D     2.27108001708984375D-01,     2.12570130039217123D+02,
+     E    -7.65252468141181642D+02,     1.05999045252799988D+03/
+      DATA C(25), C(26), C(27), C(28), C(29), C(30), C(31), C(32),
+     1     C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(40),
+     2     C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48)/
+     3    -6.99579627376132541D+02,     2.18190511744211590D+02,
+     4    -2.64914304869515555D+01,     5.72501420974731445D-01,
+     5    -1.91945766231840700D+03,     8.06172218173730938D+03,
+     6    -1.35865500064341374D+04,     1.16553933368645332D+04,
+     7    -5.30564697861340311D+03,     1.20090291321635246D+03,
+     8    -1.08090919788394656D+02,     1.72772750258445740D+00,
+     9     2.02042913309661486D+04,    -9.69805983886375135D+04,
+     A     1.92547001232531532D+05,    -2.03400177280415534D+05,
+     B     1.22200464983017460D+05,    -4.11926549688975513D+04,
+     C     7.10951430248936372D+03,    -4.93915304773088012D+02,
+     D     6.07404200127348304D+00,    -2.42919187900551333D+05,
+     E     1.31176361466297720D+06,    -2.99801591853810675D+06/
+      DATA C(49), C(50), C(51), C(52), C(53), C(54), C(55), C(56),
+     1     C(57), C(58), C(59), C(60), C(61), C(62), C(63), C(64),
+     2     C(65), C(66), C(67), C(68), C(69), C(70), C(71), C(72)/
+     3     3.76327129765640400D+06,    -2.81356322658653411D+06,
+     4     1.26836527332162478D+06,    -3.31645172484563578D+05,
+     5     4.52187689813627263D+04,    -2.49983048181120962D+03,
+     6     2.43805296995560639D+01,     3.28446985307203782D+06,
+     7    -1.97068191184322269D+07,     5.09526024926646422D+07,
+     8    -7.41051482115326577D+07,     6.63445122747290267D+07,
+     9    -3.75671766607633513D+07,     1.32887671664218183D+07,
+     A    -2.78561812808645469D+06,     3.08186404612662398D+05,
+     B    -1.38860897537170405D+04,     1.10017140269246738D+02,
+     C    -4.93292536645099620D+07,     3.25573074185765749D+08,
+     D    -9.39462359681578403D+08,     1.55359689957058006D+09,
+     E    -1.62108055210833708D+09,     1.10684281682301447D+09/
+      DATA C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(80),
+     1     C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88),
+     2     C(89), C(90), C(91), C(92), C(93), C(94), C(95), C(96)/
+     3    -4.95889784275030309D+08,     1.42062907797533095D+08,
+     4    -2.44740627257387285D+07,     2.24376817792244943D+06,
+     5    -8.40054336030240853D+04,     5.51335896122020586D+02,
+     6     8.14789096118312115D+08,    -5.86648149205184723D+09,
+     7     1.86882075092958249D+10,    -3.46320433881587779D+10,
+     8     4.12801855797539740D+10,    -3.30265997498007231D+10,
+     9     1.79542137311556001D+10,    -6.56329379261928433D+09,
+     A     1.55927986487925751D+09,    -2.25105661889415278D+08,
+     B     1.73951075539781645D+07,    -5.49842327572288687D+05,
+     C     3.03809051092238427D+03,    -1.46792612476956167D+10,
+     D     1.14498237732025810D+11,    -3.99096175224466498D+11,
+     E     8.19218669548577329D+11,    -1.09837515608122331D+12/
+      DATA C(97), C(98), C(99), C(100), C(101), C(102), C(103), C(104),
+     1     C(105), C(106), C(107), C(108), C(109), C(110), C(111),
+     2     C(112), C(113), C(114), C(115), C(116), C(117), C(118)/
+     3     1.00815810686538209D+12,    -6.45364869245376503D+11,
+     4     2.87900649906150589D+11,    -8.78670721780232657D+10,
+     5     1.76347306068349694D+10,    -2.16716498322379509D+09,
+     6     1.43157876718888981D+08,    -3.87183344257261262D+06,
+     7     1.82577554742931747D+04,     2.86464035717679043D+11,
+     8    -2.40629790002850396D+12,     9.10934118523989896D+12,
+     9    -2.05168994109344374D+13,     3.05651255199353206D+13,
+     A    -3.16670885847851584D+13,     2.33483640445818409D+13,
+     B    -1.23204913055982872D+13,     4.61272578084913197D+12,
+     C    -1.19655288019618160D+12,     2.05914503232410016D+11,
+     D    -2.18229277575292237D+10,     1.24700929351271032D+09/
+      DATA C(119), C(120)/
+     1    -2.91883881222208134D+07,     1.18838426256783253D+05/
+C
+      IF (INIT.NE.0) GO TO 40
+C-----------------------------------------------------------------------
+C     INITIALIZE ALL VARIABLES
+C-----------------------------------------------------------------------
+      RFN = 1.0D0/FNU
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST (ZR/FNU TOO SMALL)
+C-----------------------------------------------------------------------
+      TEST = D1MACH(1)*1.0D+3
+      AC = FNU*TEST
+      IF (DABS(ZRR).GT.AC .OR. DABS(ZRI).GT.AC) GO TO 15
+      ZETA1R = 2.0D0*DABS(DLOG(TEST))+FNU
+      ZETA1I = 0.0D0
+      ZETA2R = FNU
+      ZETA2I = 0.0D0
+      PHIR = 1.0D0
+      PHII = 0.0D0
+      RETURN
+   15 CONTINUE
+      TR = ZRR*RFN
+      TI = ZRI*RFN
+      SR = CONER + (TR*TR-TI*TI)
+      SI = CONEI + (TR*TI+TI*TR)
+      CALL XZSQRT(SR, SI, SRR, SRI)
+      STR = CONER + SRR
+      STI = CONEI + SRI
+      CALL ZDIV(STR, STI, TR, TI, ZNR, ZNI)
+      CALL XZLOG(ZNR, ZNI, STR, STI, IDUM)
+      ZETA1R = FNU*STR
+      ZETA1I = FNU*STI
+      ZETA2R = FNU*SRR
+      ZETA2I = FNU*SRI
+      CALL ZDIV(CONER, CONEI, SRR, SRI, TR, TI)
+      SRR = TR*RFN
+      SRI = TI*RFN
+      CALL XZSQRT(SRR, SRI, CWRKR(16), CWRKI(16))
+      PHIR = CWRKR(16)*CON(IKFLG)
+      PHII = CWRKI(16)*CON(IKFLG)
+      IF (IPMTR.NE.0) RETURN
+      CALL ZDIV(CONER, CONEI, SR, SI, T2R, T2I)
+      CWRKR(1) = CONER
+      CWRKI(1) = CONEI
+      CRFNR = CONER
+      CRFNI = CONEI
+      AC = 1.0D0
+      L = 1
+      DO 20 K=2,15
+        SR = ZEROR
+        SI = ZEROI
+        DO 10 J=1,K
+          L = L + 1
+          STR = SR*T2R - SI*T2I + C(L)
+          SI = SR*T2I + SI*T2R
+          SR = STR
+   10   CONTINUE
+        STR = CRFNR*SRR - CRFNI*SRI
+        CRFNI = CRFNR*SRI + CRFNI*SRR
+        CRFNR = STR
+        CWRKR(K) = CRFNR*SR - CRFNI*SI
+        CWRKI(K) = CRFNR*SI + CRFNI*SR
+        AC = AC*RFN
+        TEST = DABS(CWRKR(K)) + DABS(CWRKI(K))
+        IF (AC.LT.TOL .AND. TEST.LT.TOL) GO TO 30
+   20 CONTINUE
+      K = 15
+   30 CONTINUE
+      INIT = K
+   40 CONTINUE
+      IF (IKFLG.EQ.2) GO TO 60
+C-----------------------------------------------------------------------
+C     COMPUTE SUM FOR THE I FUNCTION
+C-----------------------------------------------------------------------
+      SR = ZEROR
+      SI = ZEROI
+      DO 50 I=1,INIT
+        SR = SR + CWRKR(I)
+        SI = SI + CWRKI(I)
+   50 CONTINUE
+      SUMR = SR
+      SUMI = SI
+      PHIR = CWRKR(16)*CON(1)
+      PHII = CWRKI(16)*CON(1)
+      RETURN
+   60 CONTINUE
+C-----------------------------------------------------------------------
+C     COMPUTE SUM FOR THE K FUNCTION
+C-----------------------------------------------------------------------
+      SR = ZEROR
+      SI = ZEROI
+      TR = CONER
+      DO 70 I=1,INIT
+        SR = SR + TR*CWRKR(I)
+        SI = SI + TR*CWRKI(I)
+        TR = -TR
+   70 CONTINUE
+      SUMR = SR
+      SUMI = SI
+      PHIR = CWRKR(16)*CON(2)
+      PHII = CWRKI(16)*CON(2)
+      RETURN
+      END
diff --git a/libcruft/amos/zunk1.f b/libcruft/amos/zunk1.f
new file mode 100644
index 0000000..c156b14
--- /dev/null
+++ b/libcruft/amos/zunk1.f
@@ -0,0 +1,426 @@
+      SUBROUTINE ZUNK1(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  ZUNK1
+C***REFER TO  ZBESK
+C
+C     ZUNK1 COMPUTES K(FNU,Z) AND ITS ANALYTIC CONTINUATION FROM THE
+C     RIGHT HALF PLANE TO THE LEFT HALF PLANE BY MEANS OF THE
+C     UNIFORM ASYMPTOTIC EXPANSION.
+C     MR INDICATES THE DIRECTION OF ROTATION FOR ANALYTIC CONTINUATION.
+C     NZ=-1 MEANS AN OVERFLOW WILL OCCUR
+C
+C***ROUTINES CALLED  ZKSCL,ZS1S2,ZUCHK,ZUNIK,D1MACH,XZABS
+C***END PROLOGUE  ZUNK1
+C     COMPLEX CFN,CK,CONE,CRSC,CS,CSCL,CSGN,CSPN,CSR,CSS,CWRK,CY,CZERO,
+C    *C1,C2,PHI,PHID,RZ,SUM,SUMD,S1,S2,Y,Z,ZETA1,ZETA1D,ZETA2,ZETA2D,ZR
+      DOUBLE PRECISION ALIM, ANG, APHI, ASC, ASCLE, BRY, CKI, CKR,
+     * CONER, CRSC, CSCL, CSGNI, CSPNI, CSPNR, CSR, CSRR, CSSR,
+     * CWRKI, CWRKR, CYI, CYR, C1I, C1R, C2I, C2M, C2R, ELIM, FMR, FN,
+     * FNF, FNU, PHIDI, PHIDR, PHII, PHIR, PI, RAST, RAZR, RS1, RZI,
+     * RZR, SGN, STI, STR, SUMDI, SUMDR, SUMI, SUMR, S1I, S1R, S2I,
+     * S2R, TOL, YI, YR, ZEROI, ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R,
+     * ZET1DI, ZET1DR, ZET2DI, ZET2DR, ZI, ZR, ZRI, ZRR, D1MACH, XZABS
+      INTEGER I, IB, IFLAG, IFN, IL, INIT, INU, IUF, K, KDFLG, KFLAG,
+     * KK, KODE, MR, N, NW, NZ, INITD, IC, IPARD, J
+      DIMENSION BRY(3), INIT(2), YR(N), YI(N), SUMR(2), SUMI(2),
+     * ZETA1R(2), ZETA1I(2), ZETA2R(2), ZETA2I(2), CYR(2), CYI(2),
+     * CWRKR(16,3), CWRKI(16,3), CSSR(3), CSRR(3), PHIR(2), PHII(2)
+      DATA ZEROR,ZEROI,CONER / 0.0D0, 0.0D0, 1.0D0 /
+      DATA PI / 3.14159265358979324D0 /
+C
+      KDFLG = 1
+      NZ = 0
+C-----------------------------------------------------------------------
+C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION GREATER THAN
+C     THE UNDERFLOW LIMIT
+C-----------------------------------------------------------------------
+      CSCL = 1.0D0/TOL
+      CRSC = TOL
+      CSSR(1) = CSCL
+      CSSR(2) = CONER
+      CSSR(3) = CRSC
+      CSRR(1) = CRSC
+      CSRR(2) = CONER
+      CSRR(3) = CSCL
+      BRY(1) = 1.0D+3*D1MACH(1)/TOL
+      BRY(2) = 1.0D0/BRY(1)
+      BRY(3) = D1MACH(2)
+      ZRR = ZR
+      ZRI = ZI
+      IF (ZR.GE.0.0D0) GO TO 10
+      ZRR = -ZR
+      ZRI = -ZI
+   10 CONTINUE
+      J = 2
+      DO 70 I=1,N
+C-----------------------------------------------------------------------
+C     J FLIP FLOPS BETWEEN 1 AND 2 IN J = 3 - J
+C-----------------------------------------------------------------------
+        J = 3 - J
+        FN = FNU + DBLE(FLOAT(I-1))
+        INIT(J) = 0
+        CALL ZUNIK(ZRR, ZRI, FN, 2, 0, TOL, INIT(J), PHIR(J), PHII(J),
+     *   ZETA1R(J), ZETA1I(J), ZETA2R(J), ZETA2I(J), SUMR(J), SUMI(J),
+     *   CWRKR(1,J), CWRKI(1,J))
+        IF (KODE.EQ.1) GO TO 20
+        STR = ZRR + ZETA2R(J)
+        STI = ZRI + ZETA2I(J)
+        RAST = FN/XZABS(STR,STI)
+        STR = STR*RAST*RAST
+        STI = -STI*RAST*RAST
+        S1R = ZETA1R(J) - STR
+        S1I = ZETA1I(J) - STI
+        GO TO 30
+   20   CONTINUE
+        S1R = ZETA1R(J) - ZETA2R(J)
+        S1I = ZETA1I(J) - ZETA2I(J)
+   30   CONTINUE
+        RS1 = S1R
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        IF (DABS(RS1).GT.ELIM) GO TO 60
+        IF (KDFLG.EQ.1) KFLAG = 2
+        IF (DABS(RS1).LT.ALIM) GO TO 40
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = XZABS(PHIR(J),PHII(J))
+        RS1 = RS1 + DLOG(APHI)
+        IF (DABS(RS1).GT.ELIM) GO TO 60
+        IF (KDFLG.EQ.1) KFLAG = 1
+        IF (RS1.LT.0.0D0) GO TO 40
+        IF (KDFLG.EQ.1) KFLAG = 3
+   40   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR
+C     EXPONENT EXTREMES
+C-----------------------------------------------------------------------
+        S2R = PHIR(J)*SUMR(J) - PHII(J)*SUMI(J)
+        S2I = PHIR(J)*SUMI(J) + PHII(J)*SUMR(J)
+        STR = DEXP(S1R)*CSSR(KFLAG)
+        S1R = STR*DCOS(S1I)
+        S1I = STR*DSIN(S1I)
+        STR = S2R*S1R - S2I*S1I
+        S2I = S1R*S2I + S2R*S1I
+        S2R = STR
+        IF (KFLAG.NE.1) GO TO 50
+        CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 60
+   50   CONTINUE
+        CYR(KDFLG) = S2R
+        CYI(KDFLG) = S2I
+        YR(I) = S2R*CSRR(KFLAG)
+        YI(I) = S2I*CSRR(KFLAG)
+        IF (KDFLG.EQ.2) GO TO 75
+        KDFLG = 2
+        GO TO 70
+   60   CONTINUE
+        IF (RS1.GT.0.0D0) GO TO 300
+C-----------------------------------------------------------------------
+C     FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+        IF (ZR.LT.0.0D0) GO TO 300
+        KDFLG = 1
+        YR(I)=ZEROR
+        YI(I)=ZEROI
+        NZ=NZ+1
+        IF (I.EQ.1) GO TO 70
+        IF ((YR(I-1).EQ.ZEROR).AND.(YI(I-1).EQ.ZEROI)) GO TO 70
+        YR(I-1)=ZEROR
+        YI(I-1)=ZEROI
+        NZ=NZ+1
+   70 CONTINUE
+      I = N
+   75 CONTINUE
+      RAZR = 1.0D0/XZABS(ZRR,ZRI)
+      STR = ZRR*RAZR
+      STI = -ZRI*RAZR
+      RZR = (STR+STR)*RAZR
+      RZI = (STI+STI)*RAZR
+      CKR = FN*RZR
+      CKI = FN*RZI
+      IB = I + 1
+      IF (N.LT.IB) GO TO 160
+C-----------------------------------------------------------------------
+C     TEST LAST MEMBER FOR UNDERFLOW AND OVERFLOW. SET SEQUENCE TO ZERO
+C     ON UNDERFLOW.
+C-----------------------------------------------------------------------
+      FN = FNU + DBLE(FLOAT(N-1))
+      IPARD = 1
+      IF (MR.NE.0) IPARD = 0
+      INITD = 0
+      CALL ZUNIK(ZRR, ZRI, FN, 2, IPARD, TOL, INITD, PHIDR, PHIDI,
+     * ZET1DR, ZET1DI, ZET2DR, ZET2DI, SUMDR, SUMDI, CWRKR(1,3),
+     * CWRKI(1,3))
+      IF (KODE.EQ.1) GO TO 80
+      STR = ZRR + ZET2DR
+      STI = ZRI + ZET2DI
+      RAST = FN/XZABS(STR,STI)
+      STR = STR*RAST*RAST
+      STI = -STI*RAST*RAST
+      S1R = ZET1DR - STR
+      S1I = ZET1DI - STI
+      GO TO 90
+   80 CONTINUE
+      S1R = ZET1DR - ZET2DR
+      S1I = ZET1DI - ZET2DI
+   90 CONTINUE
+      RS1 = S1R
+      IF (DABS(RS1).GT.ELIM) GO TO 95
+      IF (DABS(RS1).LT.ALIM) GO TO 100
+C----------------------------------------------------------------------------
+C     REFINE ESTIMATE AND TEST
+C-------------------------------------------------------------------------
+      APHI = XZABS(PHIDR,PHIDI)
+      RS1 = RS1+DLOG(APHI)
+      IF (DABS(RS1).LT.ELIM) GO TO 100
+   95 CONTINUE
+      IF (DABS(RS1).GT.0.0D0) GO TO 300
+C-----------------------------------------------------------------------
+C     FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+      IF (ZR.LT.0.0D0) GO TO 300
+      NZ = N
+      DO 96 I=1,N
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+   96 CONTINUE
+      RETURN
+C---------------------------------------------------------------------------
+C     FORWARD RECUR FOR REMAINDER OF THE SEQUENCE
+C----------------------------------------------------------------------------
+  100 CONTINUE
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      C1R = CSRR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 120 I=IB,N
+        C2R = S2R
+        C2I = S2I
+        S2R = CKR*C2R - CKI*C2I + S1R
+        S2I = CKR*C2I + CKI*C2R + S1I
+        S1R = C2R
+        S1I = C2I
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        C2R = S2R*C1R
+        C2I = S2I*C1R
+        YR(I) = C2R
+        YI(I) = C2I
+        IF (KFLAG.GE.3) GO TO 120
+        STR = DABS(C2R)
+        STI = DABS(C2I)
+        C2M = DMAX1(STR,STI)
+        IF (C2M.LE.ASCLE) GO TO 120
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1R = S1R*C1R
+        S1I = S1I*C1R
+        S2R = C2R
+        S2I = C2I
+        S1R = S1R*CSSR(KFLAG)
+        S1I = S1I*CSSR(KFLAG)
+        S2R = S2R*CSSR(KFLAG)
+        S2I = S2I*CSSR(KFLAG)
+        C1R = CSRR(KFLAG)
+  120 CONTINUE
+  160 CONTINUE
+      IF (MR.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION FOR RE(Z).LT.0.0D0
+C-----------------------------------------------------------------------
+      NZ = 0
+      FMR = DBLE(FLOAT(MR))
+      SGN = -DSIGN(PI,FMR)
+C-----------------------------------------------------------------------
+C     CSPN AND CSGN ARE COEFF OF K AND I FUNCTIONS RESP.
+C-----------------------------------------------------------------------
+      CSGNI = SGN
+      INU = INT(SNGL(FNU))
+      FNF = FNU - DBLE(FLOAT(INU))
+      IFN = INU + N - 1
+      ANG = FNF*SGN
+      CSPNR = DCOS(ANG)
+      CSPNI = DSIN(ANG)
+      IF (MOD(IFN,2).EQ.0) GO TO 170
+      CSPNR = -CSPNR
+      CSPNI = -CSPNI
+  170 CONTINUE
+      ASC = BRY(1)
+      IUF = 0
+      KK = N
+      KDFLG = 1
+      IB = IB - 1
+      IC = IB - 1
+      DO 270 K=1,N
+        FN = FNU + DBLE(FLOAT(KK-1))
+C-----------------------------------------------------------------------
+C     LOGIC TO SORT OUT CASES WHOSE PARAMETERS WERE SET FOR THE K
+C     FUNCTION ABOVE
+C-----------------------------------------------------------------------
+        M=3
+        IF (N.GT.2) GO TO 175
+  172   CONTINUE
+        INITD = INIT(J)
+        PHIDR = PHIR(J)
+        PHIDI = PHII(J)
+        ZET1DR = ZETA1R(J)
+        ZET1DI = ZETA1I(J)
+        ZET2DR = ZETA2R(J)
+        ZET2DI = ZETA2I(J)
+        SUMDR = SUMR(J)
+        SUMDI = SUMI(J)
+        M = J
+        J = 3 - J
+        GO TO 180
+  175   CONTINUE
+        IF ((KK.EQ.N).AND.(IB.LT.N)) GO TO 180
+        IF ((KK.EQ.IB).OR.(KK.EQ.IC)) GO TO 172
+        INITD = 0
+  180   CONTINUE
+        CALL ZUNIK(ZRR, ZRI, FN, 1, 0, TOL, INITD, PHIDR, PHIDI,
+     *   ZET1DR, ZET1DI, ZET2DR, ZET2DI, SUMDR, SUMDI,
+     *   CWRKR(1,M), CWRKI(1,M))
+        IF (KODE.EQ.1) GO TO 200
+        STR = ZRR + ZET2DR
+        STI = ZRI + ZET2DI
+        RAST = FN/XZABS(STR,STI)
+        STR = STR*RAST*RAST
+        STI = -STI*RAST*RAST
+        S1R = -ZET1DR + STR
+        S1I = -ZET1DI + STI
+        GO TO 210
+  200   CONTINUE
+        S1R = -ZET1DR + ZET2DR
+        S1I = -ZET1DI + ZET2DI
+  210   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = S1R
+        IF (DABS(RS1).GT.ELIM) GO TO 260
+        IF (KDFLG.EQ.1) IFLAG = 2
+        IF (DABS(RS1).LT.ALIM) GO TO 220
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = XZABS(PHIDR,PHIDI)
+        RS1 = RS1 + DLOG(APHI)
+        IF (DABS(RS1).GT.ELIM) GO TO 260
+        IF (KDFLG.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0D0) GO TO 220
+        IF (KDFLG.EQ.1) IFLAG = 3
+  220   CONTINUE
+        STR = PHIDR*SUMDR - PHIDI*SUMDI
+        STI = PHIDR*SUMDI + PHIDI*SUMDR
+        S2R = -CSGNI*STI
+        S2I = CSGNI*STR
+        STR = DEXP(S1R)*CSSR(IFLAG)
+        S1R = STR*DCOS(S1I)
+        S1I = STR*DSIN(S1I)
+        STR = S2R*S1R - S2I*S1I
+        S2I = S2R*S1I + S2I*S1R
+        S2R = STR
+        IF (IFLAG.NE.1) GO TO 230
+        CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL)
+        IF (NW.EQ.0) GO TO 230
+        S2R = ZEROR
+        S2I = ZEROI
+  230   CONTINUE
+        CYR(KDFLG) = S2R
+        CYI(KDFLG) = S2I
+        C2R = S2R
+        C2I = S2I
+        S2R = S2R*CSRR(IFLAG)
+        S2I = S2I*CSRR(IFLAG)
+C-----------------------------------------------------------------------
+C     ADD I AND K FUNCTIONS, K SEQUENCE IN Y(I), I=1,N
+C-----------------------------------------------------------------------
+        S1R = YR(KK)
+        S1I = YI(KK)
+        IF (KODE.EQ.1) GO TO 250
+        CALL ZS1S2(ZRR, ZRI, S1R, S1I, S2R, S2I, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  250   CONTINUE
+        YR(KK) = S1R*CSPNR - S1I*CSPNI + S2R
+        YI(KK) = CSPNR*S1I + CSPNI*S1R + S2I
+        KK = KK - 1
+        CSPNR = -CSPNR
+        CSPNI = -CSPNI
+        IF (C2R.NE.0.0D0 .OR. C2I.NE.0.0D0) GO TO 255
+        KDFLG = 1
+        GO TO 270
+  255   CONTINUE
+        IF (KDFLG.EQ.2) GO TO 275
+        KDFLG = 2
+        GO TO 270
+  260   CONTINUE
+        IF (RS1.GT.0.0D0) GO TO 300
+        S2R = ZEROR
+        S2I = ZEROI
+        GO TO 230
+  270 CONTINUE
+      K = N
+  275 CONTINUE
+      IL = N - K
+      IF (IL.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     RECUR BACKWARD FOR REMAINDER OF I SEQUENCE AND ADD IN THE
+C     K FUNCTIONS, SCALING THE I SEQUENCE DURING RECURRENCE TO KEEP
+C     INTERMEDIATE ARITHMETIC ON SCALE NEAR EXPONENT EXTREMES.
+C-----------------------------------------------------------------------
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      CSR = CSRR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      FN = DBLE(FLOAT(INU+IL))
+      DO 290 I=1,IL
+        C2R = S2R
+        C2I = S2I
+        S2R = S1R + (FN+FNF)*(RZR*C2R-RZI*C2I)
+        S2I = S1I + (FN+FNF)*(RZR*C2I+RZI*C2R)
+        S1R = C2R
+        S1I = C2I
+        FN = FN - 1.0D0
+        C2R = S2R*CSR
+        C2I = S2I*CSR
+        CKR = C2R
+        CKI = C2I
+        C1R = YR(KK)
+        C1I = YI(KK)
+        IF (KODE.EQ.1) GO TO 280
+        CALL ZS1S2(ZRR, ZRI, C1R, C1I, C2R, C2I, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  280   CONTINUE
+        YR(KK) = C1R*CSPNR - C1I*CSPNI + C2R
+        YI(KK) = C1R*CSPNI + C1I*CSPNR + C2I
+        KK = KK - 1
+        CSPNR = -CSPNR
+        CSPNI = -CSPNI
+        IF (IFLAG.GE.3) GO TO 290
+        C2R = DABS(CKR)
+        C2I = DABS(CKI)
+        C2M = DMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 290
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1R = S1R*CSR
+        S1I = S1I*CSR
+        S2R = CKR
+        S2I = CKI
+        S1R = S1R*CSSR(IFLAG)
+        S1I = S1I*CSSR(IFLAG)
+        S2R = S2R*CSSR(IFLAG)
+        S2I = S2I*CSSR(IFLAG)
+        CSR = CSRR(IFLAG)
+  290 CONTINUE
+      RETURN
+  300 CONTINUE
+      NZ = -1
+      RETURN
+      END
diff --git a/libcruft/amos/zunk2.f b/libcruft/amos/zunk2.f
new file mode 100644
index 0000000..02a7636
--- /dev/null
+++ b/libcruft/amos/zunk2.f
@@ -0,0 +1,505 @@
+      SUBROUTINE ZUNK2(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM,
+     * ALIM)
+C***BEGIN PROLOGUE  ZUNK2
+C***REFER TO  ZBESK
+C
+C     ZUNK2 COMPUTES K(FNU,Z) AND ITS ANALYTIC CONTINUATION FROM THE
+C     RIGHT HALF PLANE TO THE LEFT HALF PLANE BY MEANS OF THE
+C     UNIFORM ASYMPTOTIC EXPANSIONS FOR H(KIND,FNU,ZN) AND J(FNU,ZN)
+C     WHERE ZN IS IN THE RIGHT HALF PLANE, KIND=(3-MR)/2, MR=+1 OR
+C     -1. HERE ZN=ZR*I OR -ZR*I WHERE ZR=Z IF Z IS IN THE RIGHT
+C     HALF PLANE OR ZR=-Z IF Z IS IN THE LEFT HALF PLANE. MR INDIC-
+C     ATES THE DIRECTION OF ROTATION FOR ANALYTIC CONTINUATION.
+C     NZ=-1 MEANS AN OVERFLOW WILL OCCUR
+C
+C***ROUTINES CALLED  ZAIRY,ZKSCL,ZS1S2,ZUCHK,ZUNHJ,D1MACH,XZABS
+C***END PROLOGUE  ZUNK2
+C     COMPLEX AI,ARG,ARGD,ASUM,ASUMD,BSUM,BSUMD,CFN,CI,CIP,CK,CONE,CRSC,
+C    *CR1,CR2,CS,CSCL,CSGN,CSPN,CSR,CSS,CY,CZERO,C1,C2,DAI,PHI,PHID,RZ,
+C    *S1,S2,Y,Z,ZB,ZETA1,ZETA1D,ZETA2,ZETA2D,ZN,ZR
+      DOUBLE PRECISION AARG, AIC, AII, AIR, ALIM, ANG, APHI, ARGDI,
+     * ARGDR, ARGI, ARGR, ASC, ASCLE, ASUMDI, ASUMDR, ASUMI, ASUMR,
+     * BRY, BSUMDI, BSUMDR, BSUMI, BSUMR, CAR, CIPI, CIPR, CKI, CKR,
+     * CONER, CRSC, CR1I, CR1R, CR2I, CR2R, CSCL, CSGNI, CSI,
+     * CSPNI, CSPNR, CSR, CSRR, CSSR, CYI, CYR, C1I, C1R, C2I, C2M,
+     * C2R, DAII, DAIR, ELIM, FMR, FN, FNF, FNU, HPI, PHIDI, PHIDR,
+     * PHII, PHIR, PI, PTI, PTR, RAST, RAZR, RS1, RZI, RZR, SAR, SGN,
+     * STI, STR, S1I, S1R, S2I, S2R, TOL, YI, YR, YY, ZBI, ZBR, ZEROI,
+     * ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZET1DI, ZET1DR, ZET2DI,
+     * ZET2DR, ZI, ZNI, ZNR, ZR, ZRI, ZRR, D1MACH, XZABS
+      INTEGER I, IB, IFLAG, IFN, IL, IN, INU, IUF, K, KDFLG, KFLAG, KK,
+     * KODE, MR, N, NAI, NDAI, NW, NZ, IDUM, J, IPARD, IC
+      DIMENSION BRY(3), YR(N), YI(N), ASUMR(2), ASUMI(2), BSUMR(2),
+     * BSUMI(2), PHIR(2), PHII(2), ARGR(2), ARGI(2), ZETA1R(2),
+     * ZETA1I(2), ZETA2R(2), ZETA2I(2), CYR(2), CYI(2), CIPR(4),
+     * CIPI(4), CSSR(3), CSRR(3)
+      DATA ZEROR,ZEROI,CONER,CR1R,CR1I,CR2R,CR2I /
+     1         0.0D0, 0.0D0, 1.0D0,
+     1 1.0D0,1.73205080756887729D0 , -0.5D0,-8.66025403784438647D-01 /
+      DATA HPI, PI, AIC /
+     1     1.57079632679489662D+00,     3.14159265358979324D+00,
+     1     1.26551212348464539D+00/
+      DATA CIPR(1),CIPI(1),CIPR(2),CIPI(2),CIPR(3),CIPI(3),CIPR(4),
+     * CIPI(4) /
+     1  1.0D0,0.0D0 ,  0.0D0,-1.0D0 ,  -1.0D0,0.0D0 ,  0.0D0,1.0D0 /
+C
+      KDFLG = 1
+      NZ = 0
+C-----------------------------------------------------------------------
+C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION GREATER THAN
+C     THE UNDERFLOW LIMIT
+C-----------------------------------------------------------------------
+      CSCL = 1.0D0/TOL
+      CRSC = TOL
+      CSSR(1) = CSCL
+      CSSR(2) = CONER
+      CSSR(3) = CRSC
+      CSRR(1) = CRSC
+      CSRR(2) = CONER
+      CSRR(3) = CSCL
+      BRY(1) = 1.0D+3*D1MACH(1)/TOL
+      BRY(2) = 1.0D0/BRY(1)
+      BRY(3) = D1MACH(2)
+      ZRR = ZR
+      ZRI = ZI
+      IF (ZR.GE.0.0D0) GO TO 10
+      ZRR = -ZR
+      ZRI = -ZI
+   10 CONTINUE
+      YY = ZRI
+      ZNR = ZRI
+      ZNI = -ZRR
+      ZBR = ZRR
+      ZBI = ZRI
+      INU = INT(SNGL(FNU))
+      FNF = FNU - DBLE(FLOAT(INU))
+      ANG = -HPI*FNF
+      CAR = DCOS(ANG)
+      SAR = DSIN(ANG)
+      C2R = HPI*SAR
+      C2I = -HPI*CAR
+      KK = MOD(INU,4) + 1
+      STR = C2R*CIPR(KK) - C2I*CIPI(KK)
+      STI = C2R*CIPI(KK) + C2I*CIPR(KK)
+      CSR = CR1R*STR - CR1I*STI
+      CSI = CR1R*STI + CR1I*STR
+      IF (YY.GT.0.0D0) GO TO 20
+      ZNR = -ZNR
+      ZBI = -ZBI
+   20 CONTINUE
+C-----------------------------------------------------------------------
+C     K(FNU,Z) IS COMPUTED FROM H(2,FNU,-I*Z) WHERE Z IS IN THE FIRST
+C     QUADRANT. FOURTH QUADRANT VALUES (YY.LE.0.0E0) ARE COMPUTED BY
+C     CONJUGATION SINCE THE K FUNCTION IS REAL ON THE POSITIVE REAL AXIS
+C-----------------------------------------------------------------------
+      J = 2
+      DO 80 I=1,N
+C-----------------------------------------------------------------------
+C     J FLIP FLOPS BETWEEN 1 AND 2 IN J = 3 - J
+C-----------------------------------------------------------------------
+        J = 3 - J
+        FN = FNU + DBLE(FLOAT(I-1))
+        CALL ZUNHJ(ZNR, ZNI, FN, 0, TOL, PHIR(J), PHII(J), ARGR(J),
+     *   ARGI(J), ZETA1R(J), ZETA1I(J), ZETA2R(J), ZETA2I(J), ASUMR(J),
+     *   ASUMI(J), BSUMR(J), BSUMI(J))
+        IF (KODE.EQ.1) GO TO 30
+        STR = ZBR + ZETA2R(J)
+        STI = ZBI + ZETA2I(J)
+        RAST = FN/XZABS(STR,STI)
+        STR = STR*RAST*RAST
+        STI = -STI*RAST*RAST
+        S1R = ZETA1R(J) - STR
+        S1I = ZETA1I(J) - STI
+        GO TO 40
+   30   CONTINUE
+        S1R = ZETA1R(J) - ZETA2R(J)
+        S1I = ZETA1I(J) - ZETA2I(J)
+   40   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = S1R
+        IF (DABS(RS1).GT.ELIM) GO TO 70
+        IF (KDFLG.EQ.1) KFLAG = 2
+        IF (DABS(RS1).LT.ALIM) GO TO 50
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = XZABS(PHIR(J),PHII(J))
+        AARG = XZABS(ARGR(J),ARGI(J))
+        RS1 = RS1 + DLOG(APHI) - 0.25D0*DLOG(AARG) - AIC
+        IF (DABS(RS1).GT.ELIM) GO TO 70
+        IF (KDFLG.EQ.1) KFLAG = 1
+        IF (RS1.LT.0.0D0) GO TO 50
+        IF (KDFLG.EQ.1) KFLAG = 3
+   50   CONTINUE
+C-----------------------------------------------------------------------
+C     SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR
+C     EXPONENT EXTREMES
+C-----------------------------------------------------------------------
+        C2R = ARGR(J)*CR2R - ARGI(J)*CR2I
+        C2I = ARGR(J)*CR2I + ARGI(J)*CR2R
+        CALL ZAIRY(C2R, C2I, 0, 2, AIR, AII, NAI, IDUM)
+        CALL ZAIRY(C2R, C2I, 1, 2, DAIR, DAII, NDAI, IDUM)
+        STR = DAIR*BSUMR(J) - DAII*BSUMI(J)
+        STI = DAIR*BSUMI(J) + DAII*BSUMR(J)
+        PTR = STR*CR2R - STI*CR2I
+        PTI = STR*CR2I + STI*CR2R
+        STR = PTR + (AIR*ASUMR(J)-AII*ASUMI(J))
+        STI = PTI + (AIR*ASUMI(J)+AII*ASUMR(J))
+        PTR = STR*PHIR(J) - STI*PHII(J)
+        PTI = STR*PHII(J) + STI*PHIR(J)
+        S2R = PTR*CSR - PTI*CSI
+        S2I = PTR*CSI + PTI*CSR
+        STR = DEXP(S1R)*CSSR(KFLAG)
+        S1R = STR*DCOS(S1I)
+        S1I = STR*DSIN(S1I)
+        STR = S2R*S1R - S2I*S1I
+        S2I = S1R*S2I + S2R*S1I
+        S2R = STR
+        IF (KFLAG.NE.1) GO TO 60
+        CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL)
+        IF (NW.NE.0) GO TO 70
+   60   CONTINUE
+        IF (YY.LE.0.0D0) S2I = -S2I
+        CYR(KDFLG) = S2R
+        CYI(KDFLG) = S2I
+        YR(I) = S2R*CSRR(KFLAG)
+        YI(I) = S2I*CSRR(KFLAG)
+        STR = CSI
+        CSI = -CSR
+        CSR = STR
+        IF (KDFLG.EQ.2) GO TO 85
+        KDFLG = 2
+        GO TO 80
+   70   CONTINUE
+        IF (RS1.GT.0.0D0) GO TO 320
+C-----------------------------------------------------------------------
+C     FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+        IF (ZR.LT.0.0D0) GO TO 320
+        KDFLG = 1
+        YR(I)=ZEROR
+        YI(I)=ZEROI
+        NZ=NZ+1
+        STR = CSI
+        CSI =-CSR
+        CSR = STR
+        IF (I.EQ.1) GO TO 80
+        IF ((YR(I-1).EQ.ZEROR).AND.(YI(I-1).EQ.ZEROI)) GO TO 80
+        YR(I-1)=ZEROR
+        YI(I-1)=ZEROI
+        NZ=NZ+1
+   80 CONTINUE
+      I = N
+   85 CONTINUE
+      RAZR = 1.0D0/XZABS(ZRR,ZRI)
+      STR = ZRR*RAZR
+      STI = -ZRI*RAZR
+      RZR = (STR+STR)*RAZR
+      RZI = (STI+STI)*RAZR
+      CKR = FN*RZR
+      CKI = FN*RZI
+      IB = I + 1
+      IF (N.LT.IB) GO TO 180
+C-----------------------------------------------------------------------
+C     TEST LAST MEMBER FOR UNDERFLOW AND OVERFLOW. SET SEQUENCE TO ZERO
+C     ON UNDERFLOW.
+C-----------------------------------------------------------------------
+      FN = FNU + DBLE(FLOAT(N-1))
+      IPARD = 1
+      IF (MR.NE.0) IPARD = 0
+      CALL ZUNHJ(ZNR, ZNI, FN, IPARD, TOL, PHIDR, PHIDI, ARGDR, ARGDI,
+     * ZET1DR, ZET1DI, ZET2DR, ZET2DI, ASUMDR, ASUMDI, BSUMDR, BSUMDI)
+      IF (KODE.EQ.1) GO TO 90
+      STR = ZBR + ZET2DR
+      STI = ZBI + ZET2DI
+      RAST = FN/XZABS(STR,STI)
+      STR = STR*RAST*RAST
+      STI = -STI*RAST*RAST
+      S1R = ZET1DR - STR
+      S1I = ZET1DI - STI
+      GO TO 100
+   90 CONTINUE
+      S1R = ZET1DR - ZET2DR
+      S1I = ZET1DI - ZET2DI
+  100 CONTINUE
+      RS1 = S1R
+      IF (DABS(RS1).GT.ELIM) GO TO 105
+      IF (DABS(RS1).LT.ALIM) GO TO 120
+C----------------------------------------------------------------------------
+C     REFINE ESTIMATE AND TEST
+C-------------------------------------------------------------------------
+      APHI = XZABS(PHIDR,PHIDI)
+      RS1 = RS1+DLOG(APHI)
+      IF (DABS(RS1).LT.ELIM) GO TO 120
+  105 CONTINUE
+      IF (RS1.GT.0.0D0) GO TO 320
+C-----------------------------------------------------------------------
+C     FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW
+C-----------------------------------------------------------------------
+      IF (ZR.LT.0.0D0) GO TO 320
+      NZ = N
+      DO 106 I=1,N
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+  106 CONTINUE
+      RETURN
+  120 CONTINUE
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      C1R = CSRR(KFLAG)
+      ASCLE = BRY(KFLAG)
+      DO 130 I=IB,N
+        C2R = S2R
+        C2I = S2I
+        S2R = CKR*C2R - CKI*C2I + S1R
+        S2I = CKR*C2I + CKI*C2R + S1I
+        S1R = C2R
+        S1I = C2I
+        CKR = CKR + RZR
+        CKI = CKI + RZI
+        C2R = S2R*C1R
+        C2I = S2I*C1R
+        YR(I) = C2R
+        YI(I) = C2I
+        IF (KFLAG.GE.3) GO TO 130
+        STR = DABS(C2R)
+        STI = DABS(C2I)
+        C2M = DMAX1(STR,STI)
+        IF (C2M.LE.ASCLE) GO TO 130
+        KFLAG = KFLAG + 1
+        ASCLE = BRY(KFLAG)
+        S1R = S1R*C1R
+        S1I = S1I*C1R
+        S2R = C2R
+        S2I = C2I
+        S1R = S1R*CSSR(KFLAG)
+        S1I = S1I*CSSR(KFLAG)
+        S2R = S2R*CSSR(KFLAG)
+        S2I = S2I*CSSR(KFLAG)
+        C1R = CSRR(KFLAG)
+  130 CONTINUE
+  180 CONTINUE
+      IF (MR.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     ANALYTIC CONTINUATION FOR RE(Z).LT.0.0D0
+C-----------------------------------------------------------------------
+      NZ = 0
+      FMR = DBLE(FLOAT(MR))
+      SGN = -DSIGN(PI,FMR)
+C-----------------------------------------------------------------------
+C     CSPN AND CSGN ARE COEFF OF K AND I FUNCIONS RESP.
+C-----------------------------------------------------------------------
+      CSGNI = SGN
+      IF (YY.LE.0.0D0) CSGNI = -CSGNI
+      IFN = INU + N - 1
+      ANG = FNF*SGN
+      CSPNR = DCOS(ANG)
+      CSPNI = DSIN(ANG)
+      IF (MOD(IFN,2).EQ.0) GO TO 190
+      CSPNR = -CSPNR
+      CSPNI = -CSPNI
+  190 CONTINUE
+C-----------------------------------------------------------------------
+C     CS=COEFF OF THE J FUNCTION TO GET THE I FUNCTION. I(FNU,Z) IS
+C     COMPUTED FROM EXP(I*FNU*HPI)*J(FNU,-I*Z) WHERE Z IS IN THE FIRST
+C     QUADRANT. FOURTH QUADRANT VALUES (YY.LE.0.0E0) ARE COMPUTED BY
+C     CONJUGATION SINCE THE I FUNCTION IS REAL ON THE POSITIVE REAL AXIS
+C-----------------------------------------------------------------------
+      CSR = SAR*CSGNI
+      CSI = CAR*CSGNI
+      IN = MOD(IFN,4) + 1
+      C2R = CIPR(IN)
+      C2I = CIPI(IN)
+      STR = CSR*C2R + CSI*C2I
+      CSI = -CSR*C2I + CSI*C2R
+      CSR = STR
+      ASC = BRY(1)
+      IUF = 0
+      KK = N
+      KDFLG = 1
+      IB = IB - 1
+      IC = IB - 1
+      DO 290 K=1,N
+        FN = FNU + DBLE(FLOAT(KK-1))
+C-----------------------------------------------------------------------
+C     LOGIC TO SORT OUT CASES WHOSE PARAMETERS WERE SET FOR THE K
+C     FUNCTION ABOVE
+C-----------------------------------------------------------------------
+        IF (N.GT.2) GO TO 175
+  172   CONTINUE
+        PHIDR = PHIR(J)
+        PHIDI = PHII(J)
+        ARGDR = ARGR(J)
+        ARGDI = ARGI(J)
+        ZET1DR = ZETA1R(J)
+        ZET1DI = ZETA1I(J)
+        ZET2DR = ZETA2R(J)
+        ZET2DI = ZETA2I(J)
+        ASUMDR = ASUMR(J)
+        ASUMDI = ASUMI(J)
+        BSUMDR = BSUMR(J)
+        BSUMDI = BSUMI(J)
+        J = 3 - J
+        GO TO 210
+  175   CONTINUE
+        IF ((KK.EQ.N).AND.(IB.LT.N)) GO TO 210
+        IF ((KK.EQ.IB).OR.(KK.EQ.IC)) GO TO 172
+        CALL ZUNHJ(ZNR, ZNI, FN, 0, TOL, PHIDR, PHIDI, ARGDR,
+     *   ARGDI, ZET1DR, ZET1DI, ZET2DR, ZET2DI, ASUMDR,
+     *   ASUMDI, BSUMDR, BSUMDI)
+  210   CONTINUE
+        IF (KODE.EQ.1) GO TO 220
+        STR = ZBR + ZET2DR
+        STI = ZBI + ZET2DI
+        RAST = FN/XZABS(STR,STI)
+        STR = STR*RAST*RAST
+        STI = -STI*RAST*RAST
+        S1R = -ZET1DR + STR
+        S1I = -ZET1DI + STI
+        GO TO 230
+  220   CONTINUE
+        S1R = -ZET1DR + ZET2DR
+        S1I = -ZET1DI + ZET2DI
+  230   CONTINUE
+C-----------------------------------------------------------------------
+C     TEST FOR UNDERFLOW AND OVERFLOW
+C-----------------------------------------------------------------------
+        RS1 = S1R
+        IF (DABS(RS1).GT.ELIM) GO TO 280
+        IF (KDFLG.EQ.1) IFLAG = 2
+        IF (DABS(RS1).LT.ALIM) GO TO 240
+C-----------------------------------------------------------------------
+C     REFINE  TEST AND SCALE
+C-----------------------------------------------------------------------
+        APHI = XZABS(PHIDR,PHIDI)
+        AARG = XZABS(ARGDR,ARGDI)
+        RS1 = RS1 + DLOG(APHI) - 0.25D0*DLOG(AARG) - AIC
+        IF (DABS(RS1).GT.ELIM) GO TO 280
+        IF (KDFLG.EQ.1) IFLAG = 1
+        IF (RS1.LT.0.0D0) GO TO 240
+        IF (KDFLG.EQ.1) IFLAG = 3
+  240   CONTINUE
+        CALL ZAIRY(ARGDR, ARGDI, 0, 2, AIR, AII, NAI, IDUM)
+        CALL ZAIRY(ARGDR, ARGDI, 1, 2, DAIR, DAII, NDAI, IDUM)
+        STR = DAIR*BSUMDR - DAII*BSUMDI
+        STI = DAIR*BSUMDI + DAII*BSUMDR
+        STR = STR + (AIR*ASUMDR-AII*ASUMDI)
+        STI = STI + (AIR*ASUMDI+AII*ASUMDR)
+        PTR = STR*PHIDR - STI*PHIDI
+        PTI = STR*PHIDI + STI*PHIDR
+        S2R = PTR*CSR - PTI*CSI
+        S2I = PTR*CSI + PTI*CSR
+        STR = DEXP(S1R)*CSSR(IFLAG)
+        S1R = STR*DCOS(S1I)
+        S1I = STR*DSIN(S1I)
+        STR = S2R*S1R - S2I*S1I
+        S2I = S2R*S1I + S2I*S1R
+        S2R = STR
+        IF (IFLAG.NE.1) GO TO 250
+        CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL)
+        IF (NW.EQ.0) GO TO 250
+        S2R = ZEROR
+        S2I = ZEROI
+  250   CONTINUE
+        IF (YY.LE.0.0D0) S2I = -S2I
+        CYR(KDFLG) = S2R
+        CYI(KDFLG) = S2I
+        C2R = S2R
+        C2I = S2I
+        S2R = S2R*CSRR(IFLAG)
+        S2I = S2I*CSRR(IFLAG)
+C-----------------------------------------------------------------------
+C     ADD I AND K FUNCTIONS, K SEQUENCE IN Y(I), I=1,N
+C-----------------------------------------------------------------------
+        S1R = YR(KK)
+        S1I = YI(KK)
+        IF (KODE.EQ.1) GO TO 270
+        CALL ZS1S2(ZRR, ZRI, S1R, S1I, S2R, S2I, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  270   CONTINUE
+        YR(KK) = S1R*CSPNR - S1I*CSPNI + S2R
+        YI(KK) = S1R*CSPNI + S1I*CSPNR + S2I
+        KK = KK - 1
+        CSPNR = -CSPNR
+        CSPNI = -CSPNI
+        STR = CSI
+        CSI = -CSR
+        CSR = STR
+        IF (C2R.NE.0.0D0 .OR. C2I.NE.0.0D0) GO TO 255
+        KDFLG = 1
+        GO TO 290
+  255   CONTINUE
+        IF (KDFLG.EQ.2) GO TO 295
+        KDFLG = 2
+        GO TO 290
+  280   CONTINUE
+        IF (RS1.GT.0.0D0) GO TO 320
+        S2R = ZEROR
+        S2I = ZEROI
+        GO TO 250
+  290 CONTINUE
+      K = N
+  295 CONTINUE
+      IL = N - K
+      IF (IL.EQ.0) RETURN
+C-----------------------------------------------------------------------
+C     RECUR BACKWARD FOR REMAINDER OF I SEQUENCE AND ADD IN THE
+C     K FUNCTIONS, SCALING THE I SEQUENCE DURING RECURRENCE TO KEEP
+C     INTERMEDIATE ARITHMETIC ON SCALE NEAR EXPONENT EXTREMES.
+C-----------------------------------------------------------------------
+      S1R = CYR(1)
+      S1I = CYI(1)
+      S2R = CYR(2)
+      S2I = CYI(2)
+      CSR = CSRR(IFLAG)
+      ASCLE = BRY(IFLAG)
+      FN = DBLE(FLOAT(INU+IL))
+      DO 310 I=1,IL
+        C2R = S2R
+        C2I = S2I
+        S2R = S1R + (FN+FNF)*(RZR*C2R-RZI*C2I)
+        S2I = S1I + (FN+FNF)*(RZR*C2I+RZI*C2R)
+        S1R = C2R
+        S1I = C2I
+        FN = FN - 1.0D0
+        C2R = S2R*CSR
+        C2I = S2I*CSR
+        CKR = C2R
+        CKI = C2I
+        C1R = YR(KK)
+        C1I = YI(KK)
+        IF (KODE.EQ.1) GO TO 300
+        CALL ZS1S2(ZRR, ZRI, C1R, C1I, C2R, C2I, NW, ASC, ALIM, IUF)
+        NZ = NZ + NW
+  300   CONTINUE
+        YR(KK) = C1R*CSPNR - C1I*CSPNI + C2R
+        YI(KK) = C1R*CSPNI + C1I*CSPNR + C2I
+        KK = KK - 1
+        CSPNR = -CSPNR
+        CSPNI = -CSPNI
+        IF (IFLAG.GE.3) GO TO 310
+        C2R = DABS(CKR)
+        C2I = DABS(CKI)
+        C2M = DMAX1(C2R,C2I)
+        IF (C2M.LE.ASCLE) GO TO 310
+        IFLAG = IFLAG + 1
+        ASCLE = BRY(IFLAG)
+        S1R = S1R*CSR
+        S1I = S1I*CSR
+        S2R = CKR
+        S2I = CKI
+        S1R = S1R*CSSR(IFLAG)
+        S1I = S1I*CSSR(IFLAG)
+        S2R = S2R*CSSR(IFLAG)
+        S2I = S2I*CSSR(IFLAG)
+        CSR = CSRR(IFLAG)
+  310 CONTINUE
+      RETURN
+  320 CONTINUE
+      NZ = -1
+      RETURN
+      END
diff --git a/libcruft/amos/zuoik.f b/libcruft/amos/zuoik.f
new file mode 100644
index 0000000..3223f5b
--- /dev/null
+++ b/libcruft/amos/zuoik.f
@@ -0,0 +1,194 @@
+      SUBROUTINE ZUOIK(ZR, ZI, FNU, KODE, IKFLG, N, YR, YI, NUF, TOL,
+     * ELIM, ALIM)
+C***BEGIN PROLOGUE  ZUOIK
+C***REFER TO  ZBESI,ZBESK,ZBESH
+C
+C     ZUOIK COMPUTES THE LEADING TERMS OF THE UNIFORM ASYMPTOTIC
+C     EXPANSIONS FOR THE I AND K FUNCTIONS AND COMPARES THEM
+C     (IN LOGARITHMIC FORM) TO ALIM AND ELIM FOR OVER AND UNDERFLOW
+C     WHERE ALIM.LT.ELIM. IF THE MAGNITUDE, BASED ON THE LEADING
+C     EXPONENTIAL, IS LESS THAN ALIM OR GREATER THAN -ALIM, THEN
+C     THE RESULT IS ON SCALE. IF NOT, THEN A REFINED TEST USING OTHER
+C     MULTIPLIERS (IN LOGARITHMIC FORM) IS MADE BASED ON ELIM. HERE
+C     EXP(-ELIM)=SMALLEST MACHINE NUMBER*1.0E+3 AND EXP(-ALIM)=
+C     EXP(-ELIM)/TOL
+C
+C     IKFLG=1 MEANS THE I SEQUENCE IS TESTED
+C          =2 MEANS THE K SEQUENCE IS TESTED
+C     NUF = 0 MEANS THE LAST MEMBER OF THE SEQUENCE IS ON SCALE
+C         =-1 MEANS AN OVERFLOW WOULD OCCUR
+C     IKFLG=1 AND NUF.GT.0 MEANS THE LAST NUF Y VALUES WERE SET TO ZERO
+C             THE FIRST N-NUF VALUES MUST BE SET BY ANOTHER ROUTINE
+C     IKFLG=2 AND NUF.EQ.N MEANS ALL Y VALUES WERE SET TO ZERO
+C     IKFLG=2 AND 0.LT.NUF.LT.N NOT CONSIDERED. Y MUST BE SET BY
+C             ANOTHER ROUTINE
+C
+C***ROUTINES CALLED  ZUCHK,ZUNHJ,ZUNIK,D1MACH,XZABS,XZLOG
+C***END PROLOGUE  ZUOIK
+C     COMPLEX ARG,ASUM,BSUM,CWRK,CZ,CZERO,PHI,SUM,Y,Z,ZB,ZETA1,ZETA2,ZN,
+C    *ZR
+      DOUBLE PRECISION AARG, AIC, ALIM, APHI, ARGI, ARGR, ASUMI, ASUMR,
+     * ASCLE, AX, AY, BSUMI, BSUMR, CWRKI, CWRKR, CZI, CZR, ELIM, FNN,
+     * FNU, GNN, GNU, PHII, PHIR, RCZ, STR, STI, SUMI, SUMR, TOL, YI,
+     * YR, ZBI, ZBR, ZEROI, ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZI,
+     * ZNI, ZNR, ZR, ZRI, ZRR, D1MACH, XZABS
+      INTEGER I, IDUM, IFORM, IKFLG, INIT, KODE, N, NN, NUF, NW
+      DIMENSION YR(N), YI(N), CWRKR(16), CWRKI(16)
+      DATA ZEROR,ZEROI / 0.0D0, 0.0D0 /
+      DATA AIC / 1.265512123484645396D+00 /
+      NUF = 0
+      NN = N
+      ZRR = ZR
+      ZRI = ZI
+      IF (ZR.GE.0.0D0) GO TO 10
+      ZRR = -ZR
+      ZRI = -ZI
+   10 CONTINUE
+      ZBR = ZRR
+      ZBI = ZRI
+      AX = DABS(ZR)*1.7321D0
+      AY = DABS(ZI)
+      IFORM = 1
+      IF (AY.GT.AX) IFORM = 2
+      GNU = DMAX1(FNU,1.0D0)
+      IF (IKFLG.EQ.1) GO TO 20
+      FNN = DBLE(FLOAT(NN))
+      GNN = FNU + FNN - 1.0D0
+      GNU = DMAX1(GNN,FNN)
+   20 CONTINUE
+C-----------------------------------------------------------------------
+C     ONLY THE MAGNITUDE OF ARG AND PHI ARE NEEDED ALONG WITH THE
+C     REAL PARTS OF ZETA1, ZETA2 AND ZB. NO ATTEMPT IS MADE TO GET
+C     THE SIGN OF THE IMAGINARY PART CORRECT.
+C-----------------------------------------------------------------------
+      IF (IFORM.EQ.2) GO TO 30
+      INIT = 0
+      CALL ZUNIK(ZRR, ZRI, GNU, IKFLG, 1, TOL, INIT, PHIR, PHII,
+     * ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
+      CZR = -ZETA1R + ZETA2R
+      CZI = -ZETA1I + ZETA2I
+      GO TO 50
+   30 CONTINUE
+      ZNR = ZRI
+      ZNI = -ZRR
+      IF (ZI.GT.0.0D0) GO TO 40
+      ZNR = -ZNR
+   40 CONTINUE
+      CALL ZUNHJ(ZNR, ZNI, GNU, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R,
+     * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
+      CZR = -ZETA1R + ZETA2R
+      CZI = -ZETA1I + ZETA2I
+      AARG = XZABS(ARGR,ARGI)
+   50 CONTINUE
+      IF (KODE.EQ.1) GO TO 60
+      CZR = CZR - ZBR
+      CZI = CZI - ZBI
+   60 CONTINUE
+      IF (IKFLG.EQ.1) GO TO 70
+      CZR = -CZR
+      CZI = -CZI
+   70 CONTINUE
+      APHI = XZABS(PHIR,PHII)
+      RCZ = CZR
+C-----------------------------------------------------------------------
+C     OVERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (RCZ.GT.ELIM) GO TO 210
+      IF (RCZ.LT.ALIM) GO TO 80
+      RCZ = RCZ + DLOG(APHI)
+      IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC
+      IF (RCZ.GT.ELIM) GO TO 210
+      GO TO 130
+   80 CONTINUE
+C-----------------------------------------------------------------------
+C     UNDERFLOW TEST
+C-----------------------------------------------------------------------
+      IF (RCZ.LT.(-ELIM)) GO TO 90
+      IF (RCZ.GT.(-ALIM)) GO TO 130
+      RCZ = RCZ + DLOG(APHI)
+      IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC
+      IF (RCZ.GT.(-ELIM)) GO TO 110
+   90 CONTINUE
+      DO 100 I=1,NN
+        YR(I) = ZEROR
+        YI(I) = ZEROI
+  100 CONTINUE
+      NUF = NN
+      RETURN
+  110 CONTINUE
+      ASCLE = 1.0D+3*D1MACH(1)/TOL
+      CALL XZLOG(PHIR, PHII, STR, STI, IDUM)
+      CZR = CZR + STR
+      CZI = CZI + STI
+      IF (IFORM.EQ.1) GO TO 120
+      CALL XZLOG(ARGR, ARGI, STR, STI, IDUM)
+      CZR = CZR - 0.25D0*STR - AIC
+      CZI = CZI - 0.25D0*STI
+  120 CONTINUE
+      AX = DEXP(RCZ)/TOL
+      AY = CZI
+      CZR = AX*DCOS(AY)
+      CZI = AX*DSIN(AY)
+      CALL ZUCHK(CZR, CZI, NW, ASCLE, TOL)
+      IF (NW.NE.0) GO TO 90
+  130 CONTINUE
+      IF (IKFLG.EQ.2) RETURN
+      IF (N.EQ.1) RETURN
+C-----------------------------------------------------------------------
+C     SET UNDERFLOWS ON I SEQUENCE
+C-----------------------------------------------------------------------
+  140 CONTINUE
+      GNU = FNU + DBLE(FLOAT(NN-1))
+      IF (IFORM.EQ.2) GO TO 150
+      INIT = 0
+      CALL ZUNIK(ZRR, ZRI, GNU, IKFLG, 1, TOL, INIT, PHIR, PHII,
+     * ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
+      CZR = -ZETA1R + ZETA2R
+      CZI = -ZETA1I + ZETA2I
+      GO TO 160
+  150 CONTINUE
+      CALL ZUNHJ(ZNR, ZNI, GNU, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R,
+     * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
+      CZR = -ZETA1R + ZETA2R
+      CZI = -ZETA1I + ZETA2I
+      AARG = XZABS(ARGR,ARGI)
+  160 CONTINUE
+      IF (KODE.EQ.1) GO TO 170
+      CZR = CZR - ZBR
+      CZI = CZI - ZBI
+  170 CONTINUE
+      APHI = XZABS(PHIR,PHII)
+      RCZ = CZR
+      IF (RCZ.LT.(-ELIM)) GO TO 180
+      IF (RCZ.GT.(-ALIM)) RETURN
+      RCZ = RCZ + DLOG(APHI)
+      IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC
+      IF (RCZ.GT.(-ELIM)) GO TO 190
+  180 CONTINUE
+      YR(NN) = ZEROR
+      YI(NN) = ZEROI
+      NN = NN - 1
+      NUF = NUF + 1
+      IF (NN.EQ.0) RETURN
+      GO TO 140
+  190 CONTINUE
+      ASCLE = 1.0D+3*D1MACH(1)/TOL
+      CALL XZLOG(PHIR, PHII, STR, STI, IDUM)
+      CZR = CZR + STR
+      CZI = CZI + STI
+      IF (IFORM.EQ.1) GO TO 200
+      CALL XZLOG(ARGR, ARGI, STR, STI, IDUM)
+      CZR = CZR - 0.25D0*STR - AIC
+      CZI = CZI - 0.25D0*STI
+  200 CONTINUE
+      AX = DEXP(RCZ)/TOL
+      AY = CZI
+      CZR = AX*DCOS(AY)
+      CZI = AX*DSIN(AY)
+      CALL ZUCHK(CZR, CZI, NW, ASCLE, TOL)
+      IF (NW.NE.0) GO TO 180
+      RETURN
+  210 CONTINUE
+      NUF = -1
+      RETURN
+      END
diff --git a/libcruft/amos/zwrsk.f b/libcruft/amos/zwrsk.f
new file mode 100644
index 0000000..1645484
--- /dev/null
+++ b/libcruft/amos/zwrsk.f
@@ -0,0 +1,94 @@
+      SUBROUTINE ZWRSK(ZRR, ZRI, FNU, KODE, N, YR, YI, NZ, CWR, CWI,
+     * TOL, ELIM, ALIM)
+C***BEGIN PROLOGUE  ZWRSK
+C***REFER TO  ZBESI,ZBESK
+C
+C     ZWRSK COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY
+C     NORMALIZING THE I FUNCTION RATIOS FROM ZRATI BY THE WRONSKIAN
+C
+C***ROUTINES CALLED  D1MACH,ZBKNU,ZRATI,XZABS
+C***END PROLOGUE  ZWRSK
+C     COMPLEX CINU,CSCL,CT,CW,C1,C2,RCT,ST,Y,ZR
+      DOUBLE PRECISION ACT, ACW, ALIM, ASCLE, CINUI, CINUR, CSCLR, CTI,
+     * CTR, CWI, CWR, C1I, C1R, C2I, C2R, ELIM, FNU, PTI, PTR, RACT,
+     * STI, STR, TOL, YI, YR, ZRI, ZRR, XZABS, D1MACH
+      INTEGER I, KODE, N, NW, NZ
+      DIMENSION YR(N), YI(N), CWR(2), CWI(2)
+C-----------------------------------------------------------------------
+C     I(FNU+I-1,Z) BY BACKWARD RECURRENCE FOR RATIOS
+C     Y(I)=I(FNU+I,Z)/I(FNU+I-1,Z) FROM CRATI NORMALIZED BY THE
+C     WRONSKIAN WITH K(FNU,Z) AND K(FNU+1,Z) FROM CBKNU.
+C-----------------------------------------------------------------------
+      NZ = 0
+      CALL ZBKNU(ZRR, ZRI, FNU, KODE, 2, CWR, CWI, NW, TOL, ELIM, ALIM)
+      IF (NW.NE.0) GO TO 50
+      CALL ZRATI(ZRR, ZRI, FNU, N, YR, YI, TOL)
+C-----------------------------------------------------------------------
+C     RECUR FORWARD ON I(FNU+1,Z) = R(FNU,Z)*I(FNU,Z),
+C     R(FNU+J-1,Z)=Y(J),  J=1,...,N
+C-----------------------------------------------------------------------
+      CINUR = 1.0D0
+      CINUI = 0.0D0
+      IF (KODE.EQ.1) GO TO 10
+      CINUR = DCOS(ZRI)
+      CINUI = DSIN(ZRI)
+   10 CONTINUE
+C-----------------------------------------------------------------------
+C     ON LOW EXPONENT MACHINES THE K FUNCTIONS CAN BE CLOSE TO BOTH
+C     THE UNDER AND OVERFLOW LIMITS AND THE NORMALIZATION MUST BE
+C     SCALED TO PREVENT OVER OR UNDERFLOW. CUOIK HAS DETERMINED THAT
+C     THE RESULT IS ON SCALE.
+C-----------------------------------------------------------------------
+      ACW = XZABS(CWR(2),CWI(2))
+      ASCLE = 1.0D+3*D1MACH(1)/TOL
+      CSCLR = 1.0D0
+      IF (ACW.GT.ASCLE) GO TO 20
+      CSCLR = 1.0D0/TOL
+      GO TO 30
+   20 CONTINUE
+      ASCLE = 1.0D0/ASCLE
+      IF (ACW.LT.ASCLE) GO TO 30
+      CSCLR = TOL
+   30 CONTINUE
+      C1R = CWR(1)*CSCLR
+      C1I = CWI(1)*CSCLR
+      C2R = CWR(2)*CSCLR
+      C2I = CWI(2)*CSCLR
+      STR = YR(1)
+      STI = YI(1)
+C-----------------------------------------------------------------------
+C     CINU=CINU*(CONJG(CT)/CABS(CT))*(1.0D0/CABS(CT) PREVENTS
+C     UNDER- OR OVERFLOW PREMATURELY BY SQUARING CABS(CT)
+C-----------------------------------------------------------------------
+      PTR = STR*C1R - STI*C1I
+      PTI = STR*C1I + STI*C1R
+      PTR = PTR + C2R
+      PTI = PTI + C2I
+      CTR = ZRR*PTR - ZRI*PTI
+      CTI = ZRR*PTI + ZRI*PTR
+      ACT = XZABS(CTR,CTI)
+      RACT = 1.0D0/ACT
+      CTR = CTR*RACT
+      CTI = -CTI*RACT
+      PTR = CINUR*RACT
+      PTI = CINUI*RACT
+      CINUR = PTR*CTR - PTI*CTI
+      CINUI = PTR*CTI + PTI*CTR
+      YR(1) = CINUR*CSCLR
+      YI(1) = CINUI*CSCLR
+      IF (N.EQ.1) RETURN
+      DO 40 I=2,N
+        PTR = STR*CINUR - STI*CINUI
+        CINUI = STR*CINUI + STI*CINUR
+        CINUR = PTR
+        STR = YR(I)
+        STI = YI(I)
+        YR(I) = CINUR*CSCLR
+        YI(I) = CINUI*CSCLR
+   40 CONTINUE
+      RETURN
+   50 CONTINUE
+      NZ = -1
+      IF(NW.EQ.(-2)) NZ=-2
+      RETURN
+      END
diff --git a/libcruft/blas-xtra/Makefile.in b/libcruft/blas-xtra/Makefile.in
new file mode 100644
index 0000000..56ef440
--- /dev/null
+++ b/libcruft/blas-xtra/Makefile.in
@@ -0,0 +1,35 @@
+# Makefile for octave's libcruft/blas-xtra directory
+#
+# Copyright (C) 2000, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = xddot.f xdnrm2.f xdznrm2.f xzdotc.f xzdotu.f \
+	xsdot.f xsnrm2.f xscnrm2.f xcdotc.f xcdotu.f \
+	xerbla.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/blas-xtra/xcdotc.f b/libcruft/blas-xtra/xcdotc.f
new file mode 100644
index 0000000..073a524
--- /dev/null
+++ b/libcruft/blas-xtra/xcdotc.f
@@ -0,0 +1,7 @@
+      subroutine xcdotc (n, zx, incx, zy, incy, retval)
+      complex cdotc, zx(*), zy(*), retval
+      integer n, incx, incy
+      external cdotc
+      retval = cdotc (n, zx, incx, zy, incy)
+      return
+      end
diff --git a/libcruft/blas-xtra/xcdotu.f b/libcruft/blas-xtra/xcdotu.f
new file mode 100644
index 0000000..e0b0d9a
--- /dev/null
+++ b/libcruft/blas-xtra/xcdotu.f
@@ -0,0 +1,7 @@
+      subroutine xcdotu (n, zx, incx, zy, incy, retval)
+      complex cdotu, zx(*), zy(*), retval
+      integer n, incx, incy
+      external cdotu
+      retval = cdotu (n, zx, incx, zy, incy)
+      return
+      end
diff --git a/libcruft/blas-xtra/xddot.f b/libcruft/blas-xtra/xddot.f
new file mode 100644
index 0000000..cc984af
--- /dev/null
+++ b/libcruft/blas-xtra/xddot.f
@@ -0,0 +1,6 @@
+      subroutine xddot (n, dx, incx, dy, incy, retval)
+      double precision ddot, dx(*), dy(*), retval
+      integer n, incx, incy
+      retval = ddot (n, dx, incx, dy, incy)
+      return
+      end
diff --git a/libcruft/blas-xtra/xdnrm2.f b/libcruft/blas-xtra/xdnrm2.f
new file mode 100644
index 0000000..9c73254
--- /dev/null
+++ b/libcruft/blas-xtra/xdnrm2.f
@@ -0,0 +1,6 @@
+      subroutine xdnrm2 (n, x, incx, retval)
+      double precision dnrm2, x(*), retval
+      integer n, incx
+      retval = dnrm2 (n, x, incx)
+      return
+      end
diff --git a/libcruft/blas-xtra/xdznrm2.f b/libcruft/blas-xtra/xdznrm2.f
new file mode 100644
index 0000000..c1cecd2
--- /dev/null
+++ b/libcruft/blas-xtra/xdznrm2.f
@@ -0,0 +1,7 @@
+      subroutine xdznrm2 (n, x, incx, retval)
+      double precision dznrm2, retval
+      double complex x(*)
+      integer n, incx
+      retval = dznrm2 (n, x, incx)
+      return
+      end
diff --git a/libcruft/blas-xtra/xerbla.f b/libcruft/blas-xtra/xerbla.f
new file mode 100644
index 0000000..7976aef
--- /dev/null
+++ b/libcruft/blas-xtra/xerbla.f
@@ -0,0 +1,43 @@
+      SUBROUTINE XERBLA( SRNAME, INFO )
+*
+*  -- LAPACK auxiliary routine (preliminary version) --
+*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+*     Courant Institute, Argonne National Lab, and Rice University
+*     February 29, 1992
+*
+*     .. Scalar Arguments ..
+      CHARACTER*6        SRNAME
+      INTEGER            INFO
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  XERBLA  is an error handler for the LAPACK routines.
+*  It is called by an LAPACK routine if an input parameter has an
+*  invalid value.  A message is printed and execution stops.
+*
+*  Installers may consider modifying the STOP statement in order to
+*  call system-specific exception-handling facilities.
+*
+*  Arguments
+*  =========
+*
+*  SRNAME  (input) CHARACTER*6
+*          The name of the routine which called XERBLA.
+*
+*  INFO    (input) INTEGER
+*          The position of the invalid parameter in the parameter list
+*          of the calling routine.
+*
+*
+      WRITE( *, FMT = 9999 )SRNAME, INFO
+*
+      CALL XSTOPX (' ')
+*
+ 9999 FORMAT( ' ** On entry to ', A6, ' parameter number ', I2, ' had ',
+     $      'an illegal value' )
+*
+*     End of XERBLA
+*
+      END
diff --git a/libcruft/blas-xtra/xscnrm2.f b/libcruft/blas-xtra/xscnrm2.f
new file mode 100644
index 0000000..3a78157
--- /dev/null
+++ b/libcruft/blas-xtra/xscnrm2.f
@@ -0,0 +1,7 @@
+      subroutine xscnrm2 (n, x, incx, retval)
+      real scnrm2, retval
+      complex x(*)
+      integer n, incx
+      retval = scnrm2 (n, x, incx)
+      return
+      end
diff --git a/libcruft/blas-xtra/xsdot.f b/libcruft/blas-xtra/xsdot.f
new file mode 100644
index 0000000..2189e6e
--- /dev/null
+++ b/libcruft/blas-xtra/xsdot.f
@@ -0,0 +1,6 @@
+      subroutine xsdot (n, dx, incx, dy, incy, retval)
+      real ddot, dx(*), dy(*), retval
+      integer n, incx, incy
+      retval = sdot (n, dx, incx, dy, incy)
+      return
+      end
diff --git a/libcruft/blas-xtra/xsnrm2.f b/libcruft/blas-xtra/xsnrm2.f
new file mode 100644
index 0000000..7eeb867
--- /dev/null
+++ b/libcruft/blas-xtra/xsnrm2.f
@@ -0,0 +1,6 @@
+      subroutine xsnrm2 (n, x, incx, retval)
+      real snrm2, x(*), retval
+      integer n, incx
+      retval = snrm2 (n, x, incx)
+      return
+      end
diff --git a/libcruft/blas-xtra/xzdotc.f b/libcruft/blas-xtra/xzdotc.f
new file mode 100644
index 0000000..5b5f46d
--- /dev/null
+++ b/libcruft/blas-xtra/xzdotc.f
@@ -0,0 +1,7 @@
+      subroutine xzdotc (n, zx, incx, zy, incy, retval)
+      double complex zdotc, zx(*), zy(*), retval
+      integer n, incx, incy
+      external zdotc
+      retval = zdotc (n, zx, incx, zy, incy)
+      return
+      end
diff --git a/libcruft/blas-xtra/xzdotu.f b/libcruft/blas-xtra/xzdotu.f
new file mode 100644
index 0000000..5ed65df
--- /dev/null
+++ b/libcruft/blas-xtra/xzdotu.f
@@ -0,0 +1,7 @@
+      subroutine xzdotu (n, zx, incx, zy, incy, retval)
+      double complex zdotu, zx(*), zy(*), retval
+      integer n, incx, incy
+      external zdotu
+      retval = zdotu (n, zx, incx, zy, incy)
+      return
+      end
diff --git a/libcruft/blas/Makefile.in b/libcruft/blas/Makefile.in
new file mode 100644
index 0000000..6167c31
--- /dev/null
+++ b/libcruft/blas/Makefile.in
@@ -0,0 +1,46 @@
+# Makefile for octave's libcruft/blas directory
+#
+# Copyright (C) 1993, 1994, 1995, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = dasum.f daxpy.f dcabs1.f dcopy.f ddot.f dgemm.f dgemv.f \
+  dger.f dmach.f dnrm2.f drot.f dscal.f dswap.f dsymv.f dsyr.f dsymm.f \
+  dsyr2.f dsyr2k.f dsyrk.f dtbsv.f dtrmm.f dtrmv.f dtrsm.f dtrsv.f \
+  dzasum.f dznrm2.f icamax.f idamax.f isamax.f izamax.f lsame.f sdot.f \
+  sgemm.f sgemv.f sscal.f ssyrk.f strsm.f zaxpy.f zcopy.f zdotc.f \
+  zdotu.f zdrot.f zdscal.f zgemm.f zgemv.f zgerc.f zgeru.f zhemv.f zhemm.f \
+  zher.f zher2.f zher2k.f zherk.f zscal.f zswap.f zsyrk.f ztbsv.f ztrmm.f \
+  ztrmv.f ztrsm.f ztrsv.f sasum.f saxpy.f scabs1.f scopy.f \
+  sger.f smach.f snrm2.f srot.f sswap.f ssymv.f ssyr.f ssymm.f \
+  ssyr2.f ssyr2k.f stbsv.f strmm.f strmv.f strsv.f \
+  scasum.f scnrm2.f caxpy.f ccopy.f cdotc.f cdotu.f chemm.f \
+  csrot.f csscal.f cgemm.f cgemv.f cgerc.f cgeru.f chemv.f cher.f \
+  cher2.f cher2k.f cherk.f cscal.f cswap.f csyrk.f ctbsv.f ctrmm.f ctrmv.f \
+  ctrsm.f ctrsv.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/blas/caxpy.f b/libcruft/blas/caxpy.f
new file mode 100644
index 0000000..ece603c
--- /dev/null
+++ b/libcruft/blas/caxpy.f
@@ -0,0 +1,52 @@
+      SUBROUTINE CAXPY(N,CA,CX,INCX,CY,INCY)
+*     .. Scalar Arguments ..
+      COMPLEX CA
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     CAXPY constant times a vector plus a vector.
+*
+*  Further Details
+*  ===============
+*
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY
+*     ..
+*     .. External Functions ..
+      REAL SCABS1
+      EXTERNAL SCABS1
+*     ..
+      IF (N.LE.0) RETURN
+      IF (SCABS1(CA).EQ.0.0E+0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          CY(IY) = CY(IY) + CA*CX(IX)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*        code for both increments equal to 1
+*
+   20 DO 30 I = 1,N
+          CY(I) = CY(I) + CA*CX(I)
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/ccopy.f b/libcruft/blas/ccopy.f
new file mode 100644
index 0000000..97e6a23
--- /dev/null
+++ b/libcruft/blas/ccopy.f
@@ -0,0 +1,46 @@
+      SUBROUTINE CCOPY(N,CX,INCX,CY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     CCOPY copies a vector x to a vector y.
+*
+*  Further Details
+*  ===============
+*
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          CY(IY) = CX(IX)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*        code for both increments equal to 1
+*
+   20 DO 30 I = 1,N
+          CY(I) = CX(I)
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/cdotc.f b/libcruft/blas/cdotc.f
new file mode 100644
index 0000000..40b7748
--- /dev/null
+++ b/libcruft/blas/cdotc.f
@@ -0,0 +1,55 @@
+      COMPLEX FUNCTION CDOTC(N,CX,INCX,CY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     forms the dot product of two vectors, conjugating the first
+*     vector.
+*
+*  Further Details
+*  ===============
+*
+*     jack dongarra, linpack,  3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*     .. Local Scalars ..
+      COMPLEX CTEMP
+      INTEGER I,IX,IY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG
+*     ..
+      CTEMP = (0.0,0.0)
+      CDOTC = (0.0,0.0)
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          CTEMP = CTEMP + CONJG(CX(IX))*CY(IY)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      CDOTC = CTEMP
+      RETURN
+*
+*        code for both increments equal to 1
+*
+   20 DO 30 I = 1,N
+          CTEMP = CTEMP + CONJG(CX(I))*CY(I)
+   30 CONTINUE
+      CDOTC = CTEMP
+      RETURN
+      END
diff --git a/libcruft/blas/cdotu.f b/libcruft/blas/cdotu.f
new file mode 100644
index 0000000..529c0e2
--- /dev/null
+++ b/libcruft/blas/cdotu.f
@@ -0,0 +1,51 @@
+      COMPLEX FUNCTION CDOTU(N,CX,INCX,CY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     CDOTU forms the dot product of two vectors.
+*
+*  Further Details
+*  ===============
+*
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*     .. Local Scalars ..
+      COMPLEX CTEMP
+      INTEGER I,IX,IY
+*     ..
+      CTEMP = (0.0,0.0)
+      CDOTU = (0.0,0.0)
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          CTEMP = CTEMP + CX(IX)*CY(IY)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      CDOTU = CTEMP
+      RETURN
+*
+*        code for both increments equal to 1
+*
+   20 DO 30 I = 1,N
+          CTEMP = CTEMP + CX(I)*CY(I)
+   30 CONTINUE
+      CDOTU = CTEMP
+      RETURN
+      END
diff --git a/libcruft/blas/cgemm.f b/libcruft/blas/cgemm.f
new file mode 100644
index 0000000..68b3cf4
--- /dev/null
+++ b/libcruft/blas/cgemm.f
@@ -0,0 +1,414 @@
+      SUBROUTINE CGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,M,N
+      CHARACTER TRANSA,TRANSB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*op( A )*op( B ) + beta*C,
+*
+*  where  op( X ) is one of
+*
+*     op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
+*
+*  alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*  an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n',  op( A ) = A.
+*
+*              TRANSA = 'T' or 't',  op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c',  op( A ) = conjg( A' ).
+*
+*           Unchanged on exit.
+*
+*  TRANSB - CHARACTER*1.
+*           On entry, TRANSB specifies the form of op( B ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSB = 'N' or 'n',  op( B ) = B.
+*
+*              TRANSB = 'T' or 't',  op( B ) = B'.
+*
+*              TRANSB = 'C' or 'c',  op( B ) = conjg( B' ).
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies  the number  of rows  of the  matrix
+*           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N  specifies the number  of columns of the matrix
+*           op( B ) and the number of columns of the matrix C. N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry,  K  specifies  the number of columns of the matrix
+*           op( A ) and the number of rows of the matrix op( B ). K must
+*           be at least  zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by m  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX          array of DIMENSION ( LDB, kb ), where kb is
+*           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  n by k  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*           least  max( 1, n ).
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX         .
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX          array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n  matrix
+*           ( alpha*op( A )*op( B ) + beta*C ).
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
+      LOGICAL CONJA,CONJB,NOTA,NOTB
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     conjugated or transposed, set  CONJA and CONJB  as true if  A  and
+*     B  respectively are to be  transposed but  not conjugated  and set
+*     NROWA, NCOLA and  NROWB  as the number of rows and  columns  of  A
+*     and the number of rows of  B  respectively.
+*
+      NOTA = LSAME(TRANSA,'N')
+      NOTB = LSAME(TRANSB,'N')
+      CONJA = LSAME(TRANSA,'C')
+      CONJB = LSAME(TRANSB,'C')
+      IF (NOTA) THEN
+          NROWA = M
+          NCOLA = K
+      ELSE
+          NROWA = K
+          NCOLA = M
+      END IF
+      IF (NOTB) THEN
+          NROWB = K
+      ELSE
+          NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.NOTA) .AND. (.NOT.CONJA) .AND.
+     +    (.NOT.LSAME(TRANSA,'T'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.NOTB) .AND. (.NOT.CONJB) .AND.
+     +         (.NOT.LSAME(TRANSB,'T'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 8
+      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
+          INFO = 10
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (NOTB) THEN
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+              DO 90 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 50 I = 1,M
+                          C(I,J) = ZERO
+   50                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 60 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+   60                 CONTINUE
+                  END IF
+                  DO 80 L = 1,K
+                      IF (B(L,J).NE.ZERO) THEN
+                          TEMP = ALPHA*B(L,J)
+                          DO 70 I = 1,M
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+   70                     CONTINUE
+                      END IF
+   80             CONTINUE
+   90         CONTINUE
+          ELSE IF (CONJA) THEN
+*
+*           Form  C := alpha*conjg( A' )*B + beta*C.
+*
+              DO 120 J = 1,N
+                  DO 110 I = 1,M
+                      TEMP = ZERO
+                      DO 100 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*B(L,J)
+  100                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  110             CONTINUE
+  120         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A'*B + beta*C
+*
+              DO 150 J = 1,N
+                  DO 140 I = 1,M
+                      TEMP = ZERO
+                      DO 130 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(L,J)
+  130                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  140             CONTINUE
+  150         CONTINUE
+          END IF
+      ELSE IF (NOTA) THEN
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A*conjg( B' ) + beta*C.
+*
+              DO 200 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 160 I = 1,M
+                          C(I,J) = ZERO
+  160                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 170 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  170                 CONTINUE
+                  END IF
+                  DO 190 L = 1,K
+                      IF (B(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*CONJG(B(J,L))
+                          DO 180 I = 1,M
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  180                     CONTINUE
+                      END IF
+  190             CONTINUE
+  200         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A*B'          + beta*C
+*
+              DO 250 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 210 I = 1,M
+                          C(I,J) = ZERO
+  210                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 220 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  220                 CONTINUE
+                  END IF
+                  DO 240 L = 1,K
+                      IF (B(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*B(J,L)
+                          DO 230 I = 1,M
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  230                     CONTINUE
+                      END IF
+  240             CONTINUE
+  250         CONTINUE
+          END IF
+      ELSE IF (CONJA) THEN
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*conjg( A' )*conjg( B' ) + beta*C.
+*
+              DO 280 J = 1,N
+                  DO 270 I = 1,M
+                      TEMP = ZERO
+                      DO 260 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*CONJG(B(J,L))
+  260                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  270             CONTINUE
+  280         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*conjg( A' )*B' + beta*C
+*
+              DO 310 J = 1,N
+                  DO 300 I = 1,M
+                      TEMP = ZERO
+                      DO 290 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*B(J,L)
+  290                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  300             CONTINUE
+  310         CONTINUE
+          END IF
+      ELSE
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A'*conjg( B' ) + beta*C
+*
+              DO 340 J = 1,N
+                  DO 330 I = 1,M
+                      TEMP = ZERO
+                      DO 320 L = 1,K
+                          TEMP = TEMP + A(L,I)*CONJG(B(J,L))
+  320                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  330             CONTINUE
+  340         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A'*B' + beta*C
+*
+              DO 370 J = 1,N
+                  DO 360 I = 1,M
+                      TEMP = ZERO
+                      DO 350 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(J,L)
+  350                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  360             CONTINUE
+  370         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CGEMM .
+*
+      END
diff --git a/libcruft/blas/cgemv.f b/libcruft/blas/cgemv.f
new file mode 100644
index 0000000..18e1bbe
--- /dev/null
+++ b/libcruft/blas/cgemv.f
@@ -0,0 +1,281 @@
+      SUBROUTINE CGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEMV performs one of the matrix-vector operations
+*
+*     y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,   or
+*
+*     y := alpha*conjg( A' )*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are vectors and A is an
+*  m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*
+*              TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.
+*
+*              TRANS = 'C' or 'c'   y := alpha*conjg( A' )*x + beta*y.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of DIMENSION at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*           Before entry, the incremented array X must contain the
+*           vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX         .
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX          array of DIMENSION at least
+*           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*           Before entry with BETA non-zero, the incremented array Y
+*           must contain the vector y. On exit, Y is overwritten by the
+*           updated vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY
+      LOGICAL NOCONJ
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      DO 50 I = 1,M
+                          Y(I) = Y(I) + TEMP*A(I,J)
+   50                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IY = KY
+                      DO 70 I = 1,M
+                          Y(IY) = Y(IY) + TEMP*A(I,J)
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A'*x + y  or  y := alpha*conjg( A' )*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 110 J = 1,N
+                  TEMP = ZERO
+                  IF (NOCONJ) THEN
+                      DO 90 I = 1,M
+                          TEMP = TEMP + A(I,J)*X(I)
+   90                 CONTINUE
+                  ELSE
+                      DO 100 I = 1,M
+                          TEMP = TEMP + CONJG(A(I,J))*X(I)
+  100                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  110         CONTINUE
+          ELSE
+              DO 140 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  IF (NOCONJ) THEN
+                      DO 120 I = 1,M
+                          TEMP = TEMP + A(I,J)*X(IX)
+                          IX = IX + INCX
+  120                 CONTINUE
+                  ELSE
+                      DO 130 I = 1,M
+                          TEMP = TEMP + CONJG(A(I,J))*X(IX)
+                          IX = IX + INCX
+  130                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  140         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CGEMV .
+*
+      END
diff --git a/libcruft/blas/cgerc.f b/libcruft/blas/cgerc.f
new file mode 100644
index 0000000..02e4bd1
--- /dev/null
+++ b/libcruft/blas/cgerc.f
@@ -0,0 +1,159 @@
+      SUBROUTINE CGERC(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGERC  performs the rank 1 operation
+*
+*     A := alpha*x*conjg( y' ) + A,
+*
+*  where alpha is a scalar, x is an m element vector, y is an n element
+*  vector and A is an m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the m
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients. On exit, A is
+*           overwritten by the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGERC ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*CONJG(Y(JY))
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*CONJG(Y(JY))
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CGERC .
+*
+      END
diff --git a/libcruft/blas/cgeru.f b/libcruft/blas/cgeru.f
new file mode 100644
index 0000000..1373548
--- /dev/null
+++ b/libcruft/blas/cgeru.f
@@ -0,0 +1,159 @@
+      SUBROUTINE CGERU(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGERU  performs the rank 1 operation
+*
+*     A := alpha*x*y' + A,
+*
+*  where alpha is a scalar, x is an m element vector, y is an n element
+*  vector and A is an m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the m
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients. On exit, A is
+*           overwritten by the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGERU ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CGERU .
+*
+      END
diff --git a/libcruft/blas/chemm.f b/libcruft/blas/chemm.f
new file mode 100644
index 0000000..2e4492b
--- /dev/null
+++ b/libcruft/blas/chemm.f
@@ -0,0 +1,298 @@
+      SUBROUTINE CHEMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHEMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*A*B + beta*C,
+*
+*  or
+*
+*     C := alpha*B*A + beta*C,
+*
+*  where alpha and beta are scalars, A is an hermitian matrix and  B and
+*  C are m by n matrices.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE  specifies whether  the  hermitian matrix  A
+*           appears on the  left or right  in the  operation as follows:
+*
+*              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*
+*              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of  the  hermitian  matrix   A  is  to  be
+*           referenced as follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*                                  hermitian matrix is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*                                  hermitian matrix is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies the number of rows of the matrix  C.
+*           M  must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix C.
+*           N  must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, ka ), where ka is
+*           m  when  SIDE = 'L' or 'l'  and is n  otherwise.
+*           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*           the array  A  must contain the  hermitian matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  hermitian matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  m by m  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  hermitian
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*           the array  A  must contain the  hermitian matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  hermitian matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  n by n  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  hermitian
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Note that the imaginary parts  of the diagonal elements need
+*           not be set, they are assumed to be zero.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the  calling (sub) program. When  SIDE = 'L' or 'l'  then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX          array of DIMENSION ( LDB, n ).
+*           Before entry, the leading  m by n part of the array  B  must
+*           contain the matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX         .
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX          array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n updated
+*           matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*CONJG(A(K,I))
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*REAL(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*REAL(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*CONJG(A(K,I))
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*REAL(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*REAL(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*REAL(A(J,J))
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*CONJG(A(J,K))
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*CONJG(A(J,K))
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CHEMM .
+*
+      END
diff --git a/libcruft/blas/chemv.f b/libcruft/blas/chemv.f
new file mode 100644
index 0000000..9c03c6e
--- /dev/null
+++ b/libcruft/blas/chemv.f
@@ -0,0 +1,266 @@
+      SUBROUTINE CHEMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHEMV  performs the matrix-vector  operation
+*
+*     y := alpha*A*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are n element vectors and
+*  A is an n by n hermitian matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the hermitian matrix and the strictly
+*           lower triangular part of A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the hermitian matrix and the strictly
+*           upper triangular part of A is not referenced.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set and are assumed to be zero.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX         .
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y. On exit, Y is overwritten by the updated
+*           vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 5
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*REAL(A(J,J)) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 I = 1,J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*REAL(A(J,J)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*REAL(A(J,J))
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*REAL(A(J,J))
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,N
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHEMV .
+*
+      END
diff --git a/libcruft/blas/cher.f b/libcruft/blas/cher.f
new file mode 100644
index 0000000..054ea68
--- /dev/null
+++ b/libcruft/blas/cher.f
@@ -0,0 +1,214 @@
+      SUBROUTINE CHER(UPLO,N,ALPHA,X,INCX,A,LDA)
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHER   performs the hermitian rank 1 operation
+*
+*     A := alpha*x*conjg( x' ) + A,
+*
+*  where alpha is a real scalar, x is an n element vector and A is an
+*  n by n hermitian matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the hermitian matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the hermitian matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set, they are assumed to be zero, and on exit they
+*           are set to zero.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHER  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.REAL(ZERO))) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(J))
+                      DO 10 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   10                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) + REAL(X(J)*TEMP)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(JX))
+                      IX = KX
+                      DO 30 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) + REAL(X(JX)*TEMP)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(J))
+                      A(J,J) = REAL(A(J,J)) + REAL(TEMP*X(J))
+                      DO 50 I = J + 1,N
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   50                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(JX))
+                      A(J,J) = REAL(A(J,J)) + REAL(TEMP*X(JX))
+                      IX = JX
+                      DO 70 I = J + 1,N
+                          IX = IX + INCX
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+   70                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHER  .
+*
+      END
diff --git a/libcruft/blas/cher2.f b/libcruft/blas/cher2.f
new file mode 100644
index 0000000..fd43c3d
--- /dev/null
+++ b/libcruft/blas/cher2.f
@@ -0,0 +1,249 @@
+      SUBROUTINE CHER2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHER2  performs the hermitian rank 2 operation
+*
+*     A := alpha*x*conjg( y' ) + conjg( alpha )*y*conjg( x' ) + A,
+*
+*  where alpha is a scalar, x and y are n element vectors and A is an n
+*  by n hermitian matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the hermitian matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the hermitian matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set, they are assumed to be zero, and on exit they
+*           are set to zero.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHER2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(J))
+                      TEMP2 = CONJG(ALPHA*X(J))
+                      DO 10 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   10                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(J)*TEMP1+Y(J)*TEMP2)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(JY))
+                      TEMP2 = CONJG(ALPHA*X(JX))
+                      IX = KX
+                      IY = KY
+                      DO 30 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(JX)*TEMP1+Y(JY)*TEMP2)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(J))
+                      TEMP2 = CONJG(ALPHA*X(J))
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(J)*TEMP1+Y(J)*TEMP2)
+                      DO 50 I = J + 1,N
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   50                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(JY))
+                      TEMP2 = CONJG(ALPHA*X(JX))
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(JX)*TEMP1+Y(JY)*TEMP2)
+                      IX = JX
+                      IY = JY
+                      DO 70 I = J + 1,N
+                          IX = IX + INCX
+                          IY = IY + INCY
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+   70                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHER2 .
+*
+      END
diff --git a/libcruft/blas/cher2k.f b/libcruft/blas/cher2k.f
new file mode 100644
index 0000000..b2d2c32
--- /dev/null
+++ b/libcruft/blas/cher2k.f
@@ -0,0 +1,368 @@
+      SUBROUTINE CHER2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      REAL BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHER2K  performs one of the hermitian rank 2k operations
+*
+*     C := alpha*A*conjg( B' ) + conjg( alpha )*B*conjg( A' ) + beta*C,
+*
+*  or
+*
+*     C := alpha*conjg( A' )*B + conjg( alpha )*conjg( B' )*A + beta*C,
+*
+*  where  alpha and beta  are scalars with  beta  real,  C is an  n by n
+*  hermitian matrix and  A and B  are  n by k matrices in the first case
+*  and  k by n  matrices in the second case.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'    C := alpha*A*conjg( B' )          +
+*                                         conjg( alpha )*B*conjg( A' ) +
+*                                         beta*C.
+*
+*              TRANS = 'C' or 'c'    C := alpha*conjg( A' )*B          +
+*                                         conjg( alpha )*conjg( B' )*A +
+*                                         beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns  of the  matrices  A and B,  and on  entry  with
+*           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*           matrices  A and B.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX          array of DIMENSION ( LDB, kb ), where kb is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  k by n  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX          array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  hermitian matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  hermitian matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set,  they are assumed to be zero,  and on exit they
+*           are set to zero.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*  -- Modified 8-Nov-93 to set C(J,J) to REAL( C(J,J) ) when BETA = 1.
+*     Ed Anderson, Cray Research Inc.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE
+      PARAMETER (ONE=1.0E+0)
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHER2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.REAL(ZERO)) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.REAL(ZERO)) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      C(J,J) = BETA*REAL(C(J,J))
+                      DO 70 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*conjg( B' ) + conjg( alpha )*B*conjg( A' ) +
+*                   C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.REAL(ZERO)) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*CONJG(B(J,L))
+                          TEMP2 = CONJG(ALPHA*A(J,L))
+                          DO 110 I = 1,J - 1
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                          C(J,J) = REAL(C(J,J)) +
+     +                             REAL(A(J,L)*TEMP1+B(J,L)*TEMP2)
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.REAL(ZERO)) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*CONJG(B(J,L))
+                          TEMP2 = CONJG(ALPHA*A(J,L))
+                          DO 160 I = J + 1,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                          C(J,J) = REAL(C(J,J)) +
+     +                             REAL(A(J,L)*TEMP1+B(J,L)*TEMP2)
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*conjg( A' )*B + conjg( alpha )*conjg( B' )*A +
+*                   C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + CONJG(A(L,I))*B(L,J)
+                          TEMP2 = TEMP2 + CONJG(B(L,I))*A(L,J)
+  190                 CONTINUE
+                      IF (I.EQ.J) THEN
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(J,J) = REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          ELSE
+                              C(J,J) = BETA*REAL(C(J,J)) +
+     +                                 REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          END IF
+                      ELSE
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(I,J) = ALPHA*TEMP1 + CONJG(ALPHA)*TEMP2
+                          ELSE
+                              C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                                 CONJG(ALPHA)*TEMP2
+                          END IF
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + CONJG(A(L,I))*B(L,J)
+                          TEMP2 = TEMP2 + CONJG(B(L,I))*A(L,J)
+  220                 CONTINUE
+                      IF (I.EQ.J) THEN
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(J,J) = REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          ELSE
+                              C(J,J) = BETA*REAL(C(J,J)) +
+     +                                 REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          END IF
+                      ELSE
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(I,J) = ALPHA*TEMP1 + CONJG(ALPHA)*TEMP2
+                          ELSE
+                              C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                                 CONJG(ALPHA)*TEMP2
+                          END IF
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHER2K.
+*
+      END
diff --git a/libcruft/blas/cherk.f b/libcruft/blas/cherk.f
new file mode 100644
index 0000000..79cf90d
--- /dev/null
+++ b/libcruft/blas/cherk.f
@@ -0,0 +1,327 @@
+      SUBROUTINE CHERK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHERK  performs one of the hermitian rank k operations
+*
+*     C := alpha*A*conjg( A' ) + beta*C,
+*
+*  or
+*
+*     C := alpha*conjg( A' )*A + beta*C,
+*
+*  where  alpha and beta  are  real scalars,  C is an  n by n  hermitian
+*  matrix and  A  is an  n by k  matrix in the  first case and a  k by n
+*  matrix in the second case.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*conjg( A' ) + beta*C.
+*
+*              TRANS = 'C' or 'c'   C := alpha*conjg( A' )*A + beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns   of  the   matrix   A,   and  on   entry   with
+*           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*           matrix A.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX          array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  hermitian matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  hermitian matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set,  they are assumed to be zero,  and on exit they
+*           are set to zero.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*  -- Modified 8-Nov-93 to set C(J,J) to REAL( C(J,J) ) when BETA = 1.
+*     Ed Anderson, Cray Research Inc.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CMPLX,CONJG,MAX,REAL
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      REAL RTEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHERK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      C(J,J) = BETA*REAL(C(J,J))
+                      DO 70 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*conjg( A' ) + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.CMPLX(ZERO)) THEN
+                          TEMP = ALPHA*CONJG(A(J,L))
+                          DO 110 I = 1,J - 1
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                          C(J,J) = REAL(C(J,J)) + REAL(TEMP*A(I,L))
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      C(J,J) = BETA*REAL(C(J,J))
+                      DO 150 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.CMPLX(ZERO)) THEN
+                          TEMP = ALPHA*CONJG(A(J,L))
+                          C(J,J) = REAL(C(J,J)) + REAL(TEMP*A(J,L))
+                          DO 160 I = J + 1,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*conjg( A' )*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 220 J = 1,N
+                  DO 200 I = 1,J - 1
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+                  RTEMP = ZERO
+                  DO 210 L = 1,K
+                      RTEMP = RTEMP + CONJG(A(L,J))*A(L,J)
+  210             CONTINUE
+                  IF (BETA.EQ.ZERO) THEN
+                      C(J,J) = ALPHA*RTEMP
+                  ELSE
+                      C(J,J) = ALPHA*RTEMP + BETA*REAL(C(J,J))
+                  END IF
+  220         CONTINUE
+          ELSE
+              DO 260 J = 1,N
+                  RTEMP = ZERO
+                  DO 230 L = 1,K
+                      RTEMP = RTEMP + CONJG(A(L,J))*A(L,J)
+  230             CONTINUE
+                  IF (BETA.EQ.ZERO) THEN
+                      C(J,J) = ALPHA*RTEMP
+                  ELSE
+                      C(J,J) = ALPHA*RTEMP + BETA*REAL(C(J,J))
+                  END IF
+                  DO 250 I = J + 1,N
+                      TEMP = ZERO
+                      DO 240 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*A(L,J)
+  240                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  250             CONTINUE
+  260         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHERK .
+*
+      END
diff --git a/libcruft/blas/cscal.f b/libcruft/blas/cscal.f
new file mode 100644
index 0000000..3bcdff6
--- /dev/null
+++ b/libcruft/blas/cscal.f
@@ -0,0 +1,39 @@
+      SUBROUTINE CSCAL(N,CA,CX,INCX)
+*     .. Scalar Arguments ..
+      COMPLEX CA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     scales a vector by a constant.
+*     jack dongarra, linpack,  3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      INTEGER I,NINCX
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1,NINCX,INCX
+          CX(I) = CA*CX(I)
+   10 CONTINUE
+      RETURN
+*
+*        code for increment equal to 1
+*
+   20 DO 30 I = 1,N
+          CX(I) = CA*CX(I)
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/csrot.f b/libcruft/blas/csrot.f
new file mode 100644
index 0000000..d413288
--- /dev/null
+++ b/libcruft/blas/csrot.f
@@ -0,0 +1,95 @@
+      SUBROUTINE CSROT( N, CX, INCX, CY, INCY, C, S )
+*
+*     .. Scalar Arguments ..
+      INTEGER           INCX, INCY, N
+      REAL              C, S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX           CX( * ), CY( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Applies a plane rotation, where the cos and sin (c and s) are real
+*  and the vectors cx and cy are complex.
+*  jack dongarra, linpack, 3/11/78.
+*
+*  Arguments
+*  ==========
+*
+*  N        (input) INTEGER
+*           On entry, N specifies the order of the vectors cx and cy.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  CX       (input) COMPLEX array, dimension at least
+*           ( 1 + ( N - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array CX must contain the n
+*           element vector cx. On exit, CX is overwritten by the updated
+*           vector cx.
+*
+*  INCX     (input) INTEGER
+*           On entry, INCX specifies the increment for the elements of
+*           CX. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  CY       (input) COMPLEX array, dimension at least
+*           ( 1 + ( N - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array CY must contain the n
+*           element vector cy. On exit, CY is overwritten by the updated
+*           vector cy.
+*
+*  INCY     (input) INTEGER
+*           On entry, INCY specifies the increment for the elements of
+*           CY. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  C        (input) REAL
+*           On entry, C specifies the cosine, cos.
+*           Unchanged on exit.
+*
+*  S        (input) REAL
+*           On entry, S specifies the sine, sin.
+*           Unchanged on exit.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER           I, IX, IY
+      COMPLEX           CTEMP
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 .AND. INCY.EQ.1 )
+     $   GO TO 20
+*
+*        code for unequal increments or equal increments not equal
+*          to 1
+*
+      IX = 1
+      IY = 1
+      IF( INCX.LT.0 )
+     $   IX = ( -N+1 )*INCX + 1
+      IF( INCY.LT.0 )
+     $   IY = ( -N+1 )*INCY + 1
+      DO 10 I = 1, N
+         CTEMP = C*CX( IX ) + S*CY( IY )
+         CY( IY ) = C*CY( IY ) - S*CX( IX )
+         CX( IX ) = CTEMP
+         IX = IX + INCX
+         IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*        code for both increments equal to 1
+*
+   20 DO 30 I = 1, N
+         CTEMP = C*CX( I ) + S*CY( I )
+         CY( I ) = C*CY( I ) - S*CX( I )
+         CX( I ) = CTEMP
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/csscal.f b/libcruft/blas/csscal.f
new file mode 100644
index 0000000..1bc2b60
--- /dev/null
+++ b/libcruft/blas/csscal.f
@@ -0,0 +1,42 @@
+      SUBROUTINE CSSCAL(N,SA,CX,INCX)
+*     .. Scalar Arguments ..
+      REAL SA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     scales a complex vector by a real constant.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      INTEGER I,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC AIMAG,CMPLX,REAL
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1,NINCX,INCX
+          CX(I) = CMPLX(SA*REAL(CX(I)),SA*AIMAG(CX(I)))
+   10 CONTINUE
+      RETURN
+*
+*        code for increment equal to 1
+*
+   20 DO 30 I = 1,N
+          CX(I) = CMPLX(SA*REAL(CX(I)),SA*AIMAG(CX(I)))
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/cswap.f b/libcruft/blas/cswap.f
new file mode 100644
index 0000000..4a2b33b
--- /dev/null
+++ b/libcruft/blas/cswap.f
@@ -0,0 +1,47 @@
+      SUBROUTINE CSWAP(N,CX,INCX,CY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     interchanges two vectors.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      COMPLEX CTEMP
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          CTEMP = CX(IX)
+          CX(IX) = CY(IY)
+          CY(IY) = CTEMP
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*       code for both increments equal to 1
+   20 DO 30 I = 1,N
+          CTEMP = CX(I)
+          CX(I) = CY(I)
+          CY(I) = CTEMP
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/csyrk.f b/libcruft/blas/csyrk.f
new file mode 100644
index 0000000..ebed80d
--- /dev/null
+++ b/libcruft/blas/csyrk.f
@@ -0,0 +1,294 @@
+      SUBROUTINE CSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CSYRK  performs one of the symmetric rank k operations
+*
+*     C := alpha*A*A' + beta*C,
+*
+*  or
+*
+*     C := alpha*A'*A + beta*C,
+*
+*  where  alpha and beta  are scalars,  C is an  n by n symmetric matrix
+*  and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*  in the second case.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*A' + beta*C.
+*
+*              TRANS = 'T' or 't'   C := alpha*A'*A + beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns   of  the   matrix   A,   and  on   entry   with
+*           TRANS = 'T' or 't',  K  specifies  the number of rows of the
+*           matrix A.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX         .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX          array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  symmetric matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  symmetric matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A' + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A'*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CSYRK .
+*
+      END
diff --git a/libcruft/blas/ctbsv.f b/libcruft/blas/ctbsv.f
new file mode 100644
index 0000000..5dfd849
--- /dev/null
+++ b/libcruft/blas/ctbsv.f
@@ -0,0 +1,367 @@
+      SUBROUTINE CTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTBSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,   or   conjg( A' )*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*  diagonals.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   conjg( A' )*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with UPLO = 'U' or 'u', K specifies the number of
+*           super-diagonals of the matrix A.
+*           On entry with UPLO = 'L' or 'l', K specifies the number of
+*           sub-diagonals of the matrix A.
+*           K must satisfy  0 .le. K.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*           by n part of the array A must contain the upper triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row
+*           ( k + 1 ) of the array, the first super-diagonal starting at
+*           position 2 in row k, and so on. The top left k by k triangle
+*           of the array A is not referenced.
+*           The following program segment will transfer an upper
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = K + 1 - J
+*                    DO 10, I = MAX( 1, J - K ), J
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*           by n part of the array A must contain the lower triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row 1 of
+*           the array, the first sub-diagonal starting at position 1 in
+*           row 2, and so on. The bottom right k by k triangle of the
+*           array A is not referenced.
+*           The following program segment will transfer a lower
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = 1 - J
+*                    DO 10, I = J, MIN( N, J + K )
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Note that when DIAG = 'U' or 'u' the elements of the array A
+*           corresponding to the diagonal elements of the matrix are not
+*           referenced, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           ( k + 1 ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTBSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(KPLUS1,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,MAX(1,J-K),-1
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 40 J = N,1,-1
+                      KX = KX - INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(KPLUS1,J)
+                          TEMP = X(JX)
+                          DO 30 I = J - 1,MAX(1,J-K),-1
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX - INCX
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          L = 1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(1,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,MIN(N,J+K)
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      KX = KX + INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = 1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(1,J)
+                          TEMP = X(JX)
+                          DO 70 I = J + 1,MIN(N,J+K)
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX + INCX
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A' )*x  or  x := inv( conjg( A') )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          DO 90 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - A(L+I,J)*X(I)
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      ELSE
+                          DO 100 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(I)
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(KPLUS1,J))
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          DO 120 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - A(L+I,J)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      ELSE
+                          DO 130 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(KPLUS1,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          DO 150 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - A(L+I,J)*X(I)
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      ELSE
+                          DO 160 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(I)
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(1,J))
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          DO 180 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - A(L+I,J)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      ELSE
+                          DO 190 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(1,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTBSV .
+*
+      END
diff --git a/libcruft/blas/ctrmm.f b/libcruft/blas/ctrmm.f
new file mode 100644
index 0000000..5a3552e
--- /dev/null
+++ b/libcruft/blas/ctrmm.f
@@ -0,0 +1,383 @@
+      SUBROUTINE CTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRMM  performs one of the matrix-matrix operations
+*
+*     B := alpha*op( A )*B,   or   B := alpha*B*op( A )
+*
+*  where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'   or   op( A ) = conjg( A' ).
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*           the left or right as follows:
+*
+*              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*
+*              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = conjg( A' ).
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX          array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain the matrix  B,  and  on exit  is overwritten  by the
+*           transformed matrix.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOCONJ = LSAME(TRANSA,'T')
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*A*B.
+*
+              IF (UPPER) THEN
+                  DO 50 J = 1,N
+                      DO 40 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              DO 30 I = 1,K - 1
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   30                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP*A(K,K)
+                              B(K,J) = TEMP
+                          END IF
+   40                 CONTINUE
+   50             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              B(K,J) = TEMP
+                              IF (NOUNIT) B(K,J) = B(K,J)*A(K,K)
+                              DO 60 I = K + 1,M
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   60                         CONTINUE
+                          END IF
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*A'*B   or   B := alpha*conjg( A' )*B.
+*
+              IF (UPPER) THEN
+                  DO 120 J = 1,N
+                      DO 110 I = M,1,-1
+                          TEMP = B(I,J)
+                          IF (NOCONJ) THEN
+                              IF (NOUNIT) TEMP = TEMP*A(I,I)
+                              DO 90 K = 1,I - 1
+                                  TEMP = TEMP + A(K,I)*B(K,J)
+   90                         CONTINUE
+                          ELSE
+                              IF (NOUNIT) TEMP = TEMP*CONJG(A(I,I))
+                              DO 100 K = 1,I - 1
+                                  TEMP = TEMP + CONJG(A(K,I))*B(K,J)
+  100                         CONTINUE
+                          END IF
+                          B(I,J) = ALPHA*TEMP
+  110                 CONTINUE
+  120             CONTINUE
+              ELSE
+                  DO 160 J = 1,N
+                      DO 150 I = 1,M
+                          TEMP = B(I,J)
+                          IF (NOCONJ) THEN
+                              IF (NOUNIT) TEMP = TEMP*A(I,I)
+                              DO 130 K = I + 1,M
+                                  TEMP = TEMP + A(K,I)*B(K,J)
+  130                         CONTINUE
+                          ELSE
+                              IF (NOUNIT) TEMP = TEMP*CONJG(A(I,I))
+                              DO 140 K = I + 1,M
+                                  TEMP = TEMP + CONJG(A(K,I))*B(K,J)
+  140                         CONTINUE
+                          END IF
+                          B(I,J) = ALPHA*TEMP
+  150                 CONTINUE
+  160             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*A.
+*
+              IF (UPPER) THEN
+                  DO 200 J = N,1,-1
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 170 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  170                 CONTINUE
+                      DO 190 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 180 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  180                         CONTINUE
+                          END IF
+  190                 CONTINUE
+  200             CONTINUE
+              ELSE
+                  DO 240 J = 1,N
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 210 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  210                 CONTINUE
+                      DO 230 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 220 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  220                         CONTINUE
+                          END IF
+  230                 CONTINUE
+  240             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*A'   or   B := alpha*B*conjg( A' ).
+*
+              IF (UPPER) THEN
+                  DO 280 K = 1,N
+                      DO 260 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = ALPHA*A(J,K)
+                              ELSE
+                                  TEMP = ALPHA*CONJG(A(J,K))
+                              END IF
+                              DO 250 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  250                         CONTINUE
+                          END IF
+  260                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = TEMP*A(K,K)
+                          ELSE
+                              TEMP = TEMP*CONJG(A(K,K))
+                          END IF
+                      END IF
+                      IF (TEMP.NE.ONE) THEN
+                          DO 270 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  270                     CONTINUE
+                      END IF
+  280             CONTINUE
+              ELSE
+                  DO 320 K = N,1,-1
+                      DO 300 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = ALPHA*A(J,K)
+                              ELSE
+                                  TEMP = ALPHA*CONJG(A(J,K))
+                              END IF
+                              DO 290 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  290                         CONTINUE
+                          END IF
+  300                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = TEMP*A(K,K)
+                          ELSE
+                              TEMP = TEMP*CONJG(A(K,K))
+                          END IF
+                      END IF
+                      IF (TEMP.NE.ONE) THEN
+                          DO 310 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  310                     CONTINUE
+                      END IF
+  320             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRMM .
+*
+      END
diff --git a/libcruft/blas/ctrmv.f b/libcruft/blas/ctrmv.f
new file mode 100644
index 0000000..a7c7aa7
--- /dev/null
+++ b/libcruft/blas/ctrmv.f
@@ -0,0 +1,309 @@
+      SUBROUTINE CTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRMV  performs one of the matrix-vector operations
+*
+*     x := A*x,   or   x := A'*x,   or   x := conjg( A' )*x,
+*
+*  where x is an n element vector and  A is an n by n unit, or non-unit,
+*  upper or lower triangular matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   x := A*x.
+*
+*              TRANS = 'T' or 't'   x := A'*x.
+*
+*              TRANS = 'C' or 'c'   x := conjg( A' )*x.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x. On exit, X is overwritten with the
+*           tranformed vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*A(I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 I = 1,J - 1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*A(I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 I = N,J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A'*x  or  x := conjg( A' )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 90 I = J - 1,1,-1
+                              TEMP = TEMP + A(I,J)*X(I)
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 100 I = J - 1,1,-1
+                              TEMP = TEMP + CONJG(A(I,J))*X(I)
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 120 I = J - 1,1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + A(I,J)*X(IX)
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 130 I = J - 1,1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + CONJG(A(I,J))*X(IX)
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 150 I = J + 1,N
+                              TEMP = TEMP + A(I,J)*X(I)
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 160 I = J + 1,N
+                              TEMP = TEMP + CONJG(A(I,J))*X(I)
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 180 I = J + 1,N
+                              IX = IX + INCX
+                              TEMP = TEMP + A(I,J)*X(IX)
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 190 I = J + 1,N
+                              IX = IX + INCX
+                              TEMP = TEMP + CONJG(A(I,J))*X(IX)
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRMV .
+*
+      END
diff --git a/libcruft/blas/ctrsm.f b/libcruft/blas/ctrsm.f
new file mode 100644
index 0000000..1f73ef7
--- /dev/null
+++ b/libcruft/blas/ctrsm.f
@@ -0,0 +1,407 @@
+      SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRSM  solves one of the matrix equations
+*
+*     op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*
+*  where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'   or   op( A ) = conjg( A' ).
+*
+*  The matrix X is overwritten on B.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry, SIDE specifies whether op( A ) appears on the left
+*           or right of X as follows:
+*
+*              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*
+*              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = conjg( A' ).
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX         .
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX          array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*           overwritten by the solution matrix  X.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOCONJ = LSAME(TRANSA,'T')
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRSM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+              IF (UPPER) THEN
+                  DO 60 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 30 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   30                     CONTINUE
+                      END IF
+                      DO 50 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 40 I = 1,K - 1
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   40                         CONTINUE
+                          END IF
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 100 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 70 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   70                     CONTINUE
+                      END IF
+                      DO 90 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 80 I = K + 1,M
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   80                         CONTINUE
+                          END IF
+   90                 CONTINUE
+  100             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*inv( A' )*B
+*           or    B := alpha*inv( conjg( A' ) )*B.
+*
+              IF (UPPER) THEN
+                  DO 140 J = 1,N
+                      DO 130 I = 1,M
+                          TEMP = ALPHA*B(I,J)
+                          IF (NOCONJ) THEN
+                              DO 110 K = 1,I - 1
+                                  TEMP = TEMP - A(K,I)*B(K,J)
+  110                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          ELSE
+                              DO 120 K = 1,I - 1
+                                  TEMP = TEMP - CONJG(A(K,I))*B(K,J)
+  120                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I))
+                          END IF
+                          B(I,J) = TEMP
+  130                 CONTINUE
+  140             CONTINUE
+              ELSE
+                  DO 180 J = 1,N
+                      DO 170 I = M,1,-1
+                          TEMP = ALPHA*B(I,J)
+                          IF (NOCONJ) THEN
+                              DO 150 K = I + 1,M
+                                  TEMP = TEMP - A(K,I)*B(K,J)
+  150                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          ELSE
+                              DO 160 K = I + 1,M
+                                  TEMP = TEMP - CONJG(A(K,I))*B(K,J)
+  160                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I))
+                          END IF
+                          B(I,J) = TEMP
+  170                 CONTINUE
+  180             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+              IF (UPPER) THEN
+                  DO 230 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 190 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  190                     CONTINUE
+                      END IF
+                      DO 210 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 200 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  200                         CONTINUE
+                          END IF
+  210                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 220 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  220                     CONTINUE
+                      END IF
+  230             CONTINUE
+              ELSE
+                  DO 280 J = N,1,-1
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 240 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  240                     CONTINUE
+                      END IF
+                      DO 260 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 250 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  250                         CONTINUE
+                          END IF
+  260                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 270 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  270                     CONTINUE
+                      END IF
+  280             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*inv( A' )
+*           or    B := alpha*B*inv( conjg( A' ) ).
+*
+              IF (UPPER) THEN
+                  DO 330 K = N,1,-1
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = ONE/A(K,K)
+                          ELSE
+                              TEMP = ONE/CONJG(A(K,K))
+                          END IF
+                          DO 290 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  290                     CONTINUE
+                      END IF
+                      DO 310 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = A(J,K)
+                              ELSE
+                                  TEMP = CONJG(A(J,K))
+                              END IF
+                              DO 300 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  300                         CONTINUE
+                          END IF
+  310                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 320 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  320                     CONTINUE
+                      END IF
+  330             CONTINUE
+              ELSE
+                  DO 380 K = 1,N
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = ONE/A(K,K)
+                          ELSE
+                              TEMP = ONE/CONJG(A(K,K))
+                          END IF
+                          DO 340 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  340                     CONTINUE
+                      END IF
+                      DO 360 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = A(J,K)
+                              ELSE
+                                  TEMP = CONJG(A(J,K))
+                              END IF
+                              DO 350 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  350                         CONTINUE
+                          END IF
+  360                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 370 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  370                     CONTINUE
+                      END IF
+  380             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRSM .
+*
+      END
diff --git a/libcruft/blas/ctrsv.f b/libcruft/blas/ctrsv.f
new file mode 100644
index 0000000..280a7bc
--- /dev/null
+++ b/libcruft/blas/ctrsv.f
@@ -0,0 +1,312 @@
+      SUBROUTINE CTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,   or   conjg( A' )*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular matrix.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   conjg( A' )*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX          array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX          array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*A(I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 I = J - 1,1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*A(I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 I = J + 1,N
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A' )*x  or  x := inv( conjg( A' ) )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          DO 90 I = 1,J - 1
+                              TEMP = TEMP - A(I,J)*X(I)
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 100 I = 1,J - 1
+                              TEMP = TEMP - CONJG(A(I,J))*X(I)
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      IX = KX
+                      TEMP = X(JX)
+                      IF (NOCONJ) THEN
+                          DO 120 I = 1,J - 1
+                              TEMP = TEMP - A(I,J)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 130 I = 1,J - 1
+                              TEMP = TEMP - CONJG(A(I,J))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          DO 150 I = N,J + 1,-1
+                              TEMP = TEMP - A(I,J)*X(I)
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 160 I = N,J + 1,-1
+                              TEMP = TEMP - CONJG(A(I,J))*X(I)
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      IX = KX
+                      TEMP = X(JX)
+                      IF (NOCONJ) THEN
+                          DO 180 I = N,J + 1,-1
+                              TEMP = TEMP - A(I,J)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 190 I = N,J + 1,-1
+                              TEMP = TEMP - CONJG(A(I,J))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRSV .
+*
+      END
diff --git a/libcruft/blas/dasum.f b/libcruft/blas/dasum.f
new file mode 100644
index 0000000..28b128a
--- /dev/null
+++ b/libcruft/blas/dasum.f
@@ -0,0 +1,43 @@
+      double precision function dasum(n,dx,incx)
+c
+c     takes the sum of the absolute values.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dtemp
+      integer i,incx,m,mp1,n,nincx
+c
+      dasum = 0.0d0
+      dtemp = 0.0d0
+      if( n.le.0 .or. incx.le.0 )return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      nincx = n*incx
+      do 10 i = 1,nincx,incx
+        dtemp = dtemp + dabs(dx(i))
+   10 continue
+      dasum = dtemp
+      return
+c
+c        code for increment equal to 1
+c
+c
+c        clean-up loop
+c
+   20 m = mod(n,6)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        dtemp = dtemp + dabs(dx(i))
+   30 continue
+      if( n .lt. 6 ) go to 60
+   40 mp1 = m + 1
+      do 50 i = mp1,n,6
+        dtemp = dtemp + dabs(dx(i)) + dabs(dx(i + 1)) + dabs(dx(i + 2))
+     *  + dabs(dx(i + 3)) + dabs(dx(i + 4)) + dabs(dx(i + 5))
+   50 continue
+   60 dasum = dtemp
+      return
+      end
diff --git a/libcruft/blas/daxpy.f b/libcruft/blas/daxpy.f
new file mode 100644
index 0000000..91daa3c
--- /dev/null
+++ b/libcruft/blas/daxpy.f
@@ -0,0 +1,48 @@
+      subroutine daxpy(n,da,dx,incx,dy,incy)
+c
+c     constant times a vector plus a vector.
+c     uses unrolled loops for increments equal to one.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dy(*),da
+      integer i,incx,incy,ix,iy,m,mp1,n
+c
+      if(n.le.0)return
+      if (da .eq. 0.0d0) return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        dy(iy) = dy(iy) + da*dx(ix)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c        code for both increments equal to 1
+c
+c
+c        clean-up loop
+c
+   20 m = mod(n,4)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        dy(i) = dy(i) + da*dx(i)
+   30 continue
+      if( n .lt. 4 ) return
+   40 mp1 = m + 1
+      do 50 i = mp1,n,4
+        dy(i) = dy(i) + da*dx(i)
+        dy(i + 1) = dy(i + 1) + da*dx(i + 1)
+        dy(i + 2) = dy(i + 2) + da*dx(i + 2)
+        dy(i + 3) = dy(i + 3) + da*dx(i + 3)
+   50 continue
+      return
+      end
diff --git a/libcruft/blas/dcabs1.f b/libcruft/blas/dcabs1.f
new file mode 100644
index 0000000..385ea5e
--- /dev/null
+++ b/libcruft/blas/dcabs1.f
@@ -0,0 +1,8 @@
+      double precision function dcabs1(z)
+      double complex z,zz
+      double precision t(2)
+      equivalence (zz,t(1))
+      zz = z
+      dcabs1 = dabs(t(1)) + dabs(t(2))
+      return
+      end
diff --git a/libcruft/blas/dcopy.f b/libcruft/blas/dcopy.f
new file mode 100644
index 0000000..e168927
--- /dev/null
+++ b/libcruft/blas/dcopy.f
@@ -0,0 +1,50 @@
+      subroutine  dcopy(n,dx,incx,dy,incy)
+c
+c     copies a vector, x, to a vector, y.
+c     uses unrolled loops for increments equal to one.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dy(*)
+      integer i,incx,incy,ix,iy,m,mp1,n
+c
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        dy(iy) = dx(ix)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c        code for both increments equal to 1
+c
+c
+c        clean-up loop
+c
+   20 m = mod(n,7)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        dy(i) = dx(i)
+   30 continue
+      if( n .lt. 7 ) return
+   40 mp1 = m + 1
+      do 50 i = mp1,n,7
+        dy(i) = dx(i)
+        dy(i + 1) = dx(i + 1)
+        dy(i + 2) = dx(i + 2)
+        dy(i + 3) = dx(i + 3)
+        dy(i + 4) = dx(i + 4)
+        dy(i + 5) = dx(i + 5)
+        dy(i + 6) = dx(i + 6)
+   50 continue
+      return
+      end
diff --git a/libcruft/blas/ddot.f b/libcruft/blas/ddot.f
new file mode 100644
index 0000000..e04c7c2
--- /dev/null
+++ b/libcruft/blas/ddot.f
@@ -0,0 +1,49 @@
+      double precision function ddot(n,dx,incx,dy,incy)
+c
+c     forms the dot product of two vectors.
+c     uses unrolled loops for increments equal to one.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dy(*),dtemp
+      integer i,incx,incy,ix,iy,m,mp1,n
+c
+      ddot = 0.0d0
+      dtemp = 0.0d0
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        dtemp = dtemp + dx(ix)*dy(iy)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      ddot = dtemp
+      return
+c
+c        code for both increments equal to 1
+c
+c
+c        clean-up loop
+c
+   20 m = mod(n,5)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        dtemp = dtemp + dx(i)*dy(i)
+   30 continue
+      if( n .lt. 5 ) go to 60
+   40 mp1 = m + 1
+      do 50 i = mp1,n,5
+        dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) +
+     *   dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4)
+   50 continue
+   60 ddot = dtemp
+      return
+      end
diff --git a/libcruft/blas/dgemm.f b/libcruft/blas/dgemm.f
new file mode 100644
index 0000000..baabe4c
--- /dev/null
+++ b/libcruft/blas/dgemm.f
@@ -0,0 +1,313 @@
+      SUBROUTINE DGEMM ( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB,
+     $                   BETA, C, LDC )
+*     .. Scalar Arguments ..
+      CHARACTER*1        TRANSA, TRANSB
+      INTEGER            M, N, K, LDA, LDB, LDC
+      DOUBLE PRECISION   ALPHA, BETA
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*op( A )*op( B ) + beta*C,
+*
+*  where  op( X ) is one of
+*
+*     op( X ) = X   or   op( X ) = X',
+*
+*  alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*  an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n',  op( A ) = A.
+*
+*              TRANSA = 'T' or 't',  op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c',  op( A ) = A'.
+*
+*           Unchanged on exit.
+*
+*  TRANSB - CHARACTER*1.
+*           On entry, TRANSB specifies the form of op( B ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSB = 'N' or 'n',  op( B ) = B.
+*
+*              TRANSB = 'T' or 't',  op( B ) = B'.
+*
+*              TRANSB = 'C' or 'c',  op( B ) = B'.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies  the number  of rows  of the  matrix
+*           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N  specifies the number  of columns of the matrix
+*           op( B ) and the number of columns of the matrix C. N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry,  K  specifies  the number of columns of the matrix
+*           op( A ) and the number of rows of the matrix op( B ). K must
+*           be at least  zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by m  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is
+*           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  n by k  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*           least  max( 1, n ).
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n  matrix
+*           ( alpha*op( A )*op( B ) + beta*C ).
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     .. Local Scalars ..
+      LOGICAL            NOTA, NOTB
+      INTEGER            I, INFO, J, L, NCOLA, NROWA, NROWB
+      DOUBLE PRECISION   TEMP
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE         , ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     transposed and set  NROWA, NCOLA and  NROWB  as the number of rows
+*     and  columns of  A  and the  number of  rows  of  B  respectively.
+*
+      NOTA  = LSAME( TRANSA, 'N' )
+      NOTB  = LSAME( TRANSB, 'N' )
+      IF( NOTA )THEN
+         NROWA = M
+         NCOLA = K
+      ELSE
+         NROWA = K
+         NCOLA = M
+      END IF
+      IF( NOTB )THEN
+         NROWB = K
+      ELSE
+         NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF(      ( .NOT.NOTA                 ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'C' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'T' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.NOTB                 ).AND.
+     $         ( .NOT.LSAME( TRANSB, 'C' ) ).AND.
+     $         ( .NOT.LSAME( TRANSB, 'T' ) )      )THEN
+         INFO = 2
+      ELSE IF( M  .LT.0               )THEN
+         INFO = 3
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 4
+      ELSE IF( K  .LT.0               )THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 8
+      ELSE IF( LDB.LT.MAX( 1, NROWB ) )THEN
+         INFO = 10
+      ELSE IF( LDC.LT.MAX( 1, M     ) )THEN
+         INFO = 13
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DGEMM ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.
+     $    ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     And if  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         IF( BETA.EQ.ZERO )THEN
+            DO 20, J = 1, N
+               DO 10, I = 1, M
+                  C( I, J ) = ZERO
+   10          CONTINUE
+   20       CONTINUE
+         ELSE
+            DO 40, J = 1, N
+               DO 30, I = 1, M
+                  C( I, J ) = BETA*C( I, J )
+   30          CONTINUE
+   40       CONTINUE
+         END IF
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( NOTB )THEN
+         IF( NOTA )THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+            DO 90, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 50, I = 1, M
+                     C( I, J ) = ZERO
+   50             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 60, I = 1, M
+                     C( I, J ) = BETA*C( I, J )
+   60             CONTINUE
+               END IF
+               DO 80, L = 1, K
+                  IF( B( L, J ).NE.ZERO )THEN
+                     TEMP = ALPHA*B( L, J )
+                     DO 70, I = 1, M
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+   70                CONTINUE
+                  END IF
+   80          CONTINUE
+   90       CONTINUE
+         ELSE
+*
+*           Form  C := alpha*A'*B + beta*C
+*
+            DO 120, J = 1, N
+               DO 110, I = 1, M
+                  TEMP = ZERO
+                  DO 100, L = 1, K
+                     TEMP = TEMP + A( L, I )*B( L, J )
+  100             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  110          CONTINUE
+  120       CONTINUE
+         END IF
+      ELSE
+         IF( NOTA )THEN
+*
+*           Form  C := alpha*A*B' + beta*C
+*
+            DO 170, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 130, I = 1, M
+                     C( I, J ) = ZERO
+  130             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 140, I = 1, M
+                     C( I, J ) = BETA*C( I, J )
+  140             CONTINUE
+               END IF
+               DO 160, L = 1, K
+                  IF( B( J, L ).NE.ZERO )THEN
+                     TEMP = ALPHA*B( J, L )
+                     DO 150, I = 1, M
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  150                CONTINUE
+                  END IF
+  160          CONTINUE
+  170       CONTINUE
+         ELSE
+*
+*           Form  C := alpha*A'*B' + beta*C
+*
+            DO 200, J = 1, N
+               DO 190, I = 1, M
+                  TEMP = ZERO
+                  DO 180, L = 1, K
+                     TEMP = TEMP + A( L, I )*B( J, L )
+  180             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  190          CONTINUE
+  200       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DGEMM .
+*
+      END
diff --git a/libcruft/blas/dgemv.f b/libcruft/blas/dgemv.f
new file mode 100644
index 0000000..8ef80b3
--- /dev/null
+++ b/libcruft/blas/dgemv.f
@@ -0,0 +1,261 @@
+      SUBROUTINE DGEMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX,
+     $                   BETA, Y, INCY )
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   ALPHA, BETA
+      INTEGER            INCX, INCY, LDA, M, N
+      CHARACTER*1        TRANS
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEMV  performs one of the matrix-vector operations
+*
+*     y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are vectors and A is an
+*  m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*
+*              TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.
+*
+*              TRANS = 'C' or 'c'   y := alpha*A'*x + beta*y.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of DIMENSION at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*           Before entry, the incremented array X must contain the
+*           vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - DOUBLE PRECISION array of DIMENSION at least
+*           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*           Before entry with BETA non-zero, the incremented array Y
+*           must contain the vector y. On exit, Y is overwritten by the
+*           updated vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE         , ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP
+      INTEGER            I, INFO, IX, IY, J, JX, JY, KX, KY, LENX, LENY
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 1
+      ELSE IF( M.LT.0 )THEN
+         INFO = 2
+      ELSE IF( N.LT.0 )THEN
+         INFO = 3
+      ELSE IF( LDA.LT.MAX( 1, M ) )THEN
+         INFO = 6
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 8
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 11
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DGEMV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.
+     $    ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+         LENX = N
+         LENY = M
+      ELSE
+         LENX = M
+         LENY = N
+      END IF
+      IF( INCX.GT.0 )THEN
+         KX = 1
+      ELSE
+         KX = 1 - ( LENX - 1 )*INCX
+      END IF
+      IF( INCY.GT.0 )THEN
+         KY = 1
+      ELSE
+         KY = 1 - ( LENY - 1 )*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF( BETA.NE.ONE )THEN
+         IF( INCY.EQ.1 )THEN
+            IF( BETA.EQ.ZERO )THEN
+               DO 10, I = 1, LENY
+                  Y( I ) = ZERO
+   10          CONTINUE
+            ELSE
+               DO 20, I = 1, LENY
+                  Y( I ) = BETA*Y( I )
+   20          CONTINUE
+            END IF
+         ELSE
+            IY = KY
+            IF( BETA.EQ.ZERO )THEN
+               DO 30, I = 1, LENY
+                  Y( IY ) = ZERO
+                  IY      = IY   + INCY
+   30          CONTINUE
+            ELSE
+               DO 40, I = 1, LENY
+                  Y( IY ) = BETA*Y( IY )
+                  IY      = IY           + INCY
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      IF( ALPHA.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+         JX = KX
+         IF( INCY.EQ.1 )THEN
+            DO 60, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( JX )
+                  DO 50, I = 1, M
+                     Y( I ) = Y( I ) + TEMP*A( I, J )
+   50             CONTINUE
+               END IF
+               JX = JX + INCX
+   60       CONTINUE
+         ELSE
+            DO 80, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( JX )
+                  IY   = KY
+                  DO 70, I = 1, M
+                     Y( IY ) = Y( IY ) + TEMP*A( I, J )
+                     IY      = IY      + INCY
+   70             CONTINUE
+               END IF
+               JX = JX + INCX
+   80       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  y := alpha*A'*x + y.
+*
+         JY = KY
+         IF( INCX.EQ.1 )THEN
+            DO 100, J = 1, N
+               TEMP = ZERO
+               DO 90, I = 1, M
+                  TEMP = TEMP + A( I, J )*X( I )
+   90          CONTINUE
+               Y( JY ) = Y( JY ) + ALPHA*TEMP
+               JY      = JY      + INCY
+  100       CONTINUE
+         ELSE
+            DO 120, J = 1, N
+               TEMP = ZERO
+               IX   = KX
+               DO 110, I = 1, M
+                  TEMP = TEMP + A( I, J )*X( IX )
+                  IX   = IX   + INCX
+  110          CONTINUE
+               Y( JY ) = Y( JY ) + ALPHA*TEMP
+               JY      = JY      + INCY
+  120       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DGEMV .
+*
+      END
diff --git a/libcruft/blas/dger.f b/libcruft/blas/dger.f
new file mode 100644
index 0000000..d316000
--- /dev/null
+++ b/libcruft/blas/dger.f
@@ -0,0 +1,157 @@
+      SUBROUTINE DGER  ( M, N, ALPHA, X, INCX, Y, INCY, A, LDA )
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   ALPHA
+      INTEGER            INCX, INCY, LDA, M, N
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGER   performs the rank 1 operation
+*
+*     A := alpha*x*y' + A,
+*
+*  where alpha is a scalar, x is an m element vector, y is an n element
+*  vector and A is an m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the m
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients. On exit, A is
+*           overwritten by the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER        ( ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP
+      INTEGER            I, INFO, IX, J, JY, KX
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( M.LT.0 )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( LDA.LT.MAX( 1, M ) )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DGER  ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) )
+     $   RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( INCY.GT.0 )THEN
+         JY = 1
+      ELSE
+         JY = 1 - ( N - 1 )*INCY
+      END IF
+      IF( INCX.EQ.1 )THEN
+         DO 20, J = 1, N
+            IF( Y( JY ).NE.ZERO )THEN
+               TEMP = ALPHA*Y( JY )
+               DO 10, I = 1, M
+                  A( I, J ) = A( I, J ) + X( I )*TEMP
+   10          CONTINUE
+            END IF
+            JY = JY + INCY
+   20    CONTINUE
+      ELSE
+         IF( INCX.GT.0 )THEN
+            KX = 1
+         ELSE
+            KX = 1 - ( M - 1 )*INCX
+         END IF
+         DO 40, J = 1, N
+            IF( Y( JY ).NE.ZERO )THEN
+               TEMP = ALPHA*Y( JY )
+               IX   = KX
+               DO 30, I = 1, M
+                  A( I, J ) = A( I, J ) + X( IX )*TEMP
+                  IX        = IX        + INCX
+   30          CONTINUE
+            END IF
+            JY = JY + INCY
+   40    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DGER  .
+*
+      END
diff --git a/libcruft/blas/dmach.f b/libcruft/blas/dmach.f
new file mode 100644
index 0000000..6ed16bf
--- /dev/null
+++ b/libcruft/blas/dmach.f
@@ -0,0 +1,58 @@
+      DOUBLE PRECISION FUNCTION DMACH(JOB)
+      INTEGER JOB
+C
+C     SMACH COMPUTES MACHINE PARAMETERS OF FLOATING POINT
+C     ARITHMETIC FOR USE IN TESTING ONLY.  NOT REQUIRED BY
+C     LINPACK PROPER.
+C
+C     IF TROUBLE WITH AUTOMATIC COMPUTATION OF THESE QUANTITIES,
+C     THEY CAN BE SET BY DIRECT ASSIGNMENT STATEMENTS.
+C     ASSUME THE COMPUTER HAS
+C
+C        B = BASE OF ARITHMETIC
+C        T = NUMBER OF BASE  B  DIGITS
+C        L = SMALLEST POSSIBLE EXPONENT
+C        U = LARGEST POSSIBLE EXPONENT
+C
+C     THEN
+C
+C        EPS = B**(1-T)
+C        TINY = 100.0*B**(-L+T)
+C        HUGE = 0.01*B**(U-T)
+C
+C     DMACH SAME AS SMACH EXCEPT T, L, U APPLY TO
+C     DOUBLE PRECISION.
+C
+C     CMACH SAME AS SMACH EXCEPT IF COMPLEX DIVISION
+C     IS DONE BY
+C
+C        1/(X+I*Y) = (X-I*Y)/(X**2+Y**2)
+C
+C     THEN
+C
+C        TINY = SQRT(TINY)
+C        HUGE = SQRT(HUGE)
+C
+C
+C     JOB IS 1, 2 OR 3 FOR EPSILON, TINY AND HUGE, RESPECTIVELY.
+C
+      DOUBLE PRECISION EPS,TINY,HUGE,S
+C
+      EPS = 1.0D0
+   10 EPS = EPS/2.0D0
+      S = 1.0D0 + EPS
+      IF (S .GT. 1.0D0) GO TO 10
+      EPS = 2.0D0*EPS
+C
+      S = 1.0D0
+   20 TINY = S
+      S = S/16.0D0
+      IF (S*1.0 .NE. 0.0D0) GO TO 20
+      TINY = (TINY/EPS)*100.0
+      HUGE = 1.0D0/TINY
+C
+      IF (JOB .EQ. 1) DMACH = EPS
+      IF (JOB .EQ. 2) DMACH = TINY
+      IF (JOB .EQ. 3) DMACH = HUGE
+      RETURN
+      END
diff --git a/libcruft/blas/dnrm2.f b/libcruft/blas/dnrm2.f
new file mode 100644
index 0000000..119d047
--- /dev/null
+++ b/libcruft/blas/dnrm2.f
@@ -0,0 +1,60 @@
+      DOUBLE PRECISION FUNCTION DNRM2 ( N, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER                           INCX, N
+*     .. Array Arguments ..
+      DOUBLE PRECISION                  X( * )
+*     ..
+*
+*  DNRM2 returns the euclidean norm of a vector via the function
+*  name, so that
+*
+*     DNRM2 := sqrt( x'*x )
+*
+*
+*
+*  -- This version written on 25-October-1982.
+*     Modified on 14-October-1993 to inline the call to DLASSQ.
+*     Sven Hammarling, Nag Ltd.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION      ONE         , ZERO
+      PARAMETER           ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      INTEGER               IX
+      DOUBLE PRECISION      ABSXI, NORM, SCALE, SSQ
+*     .. Intrinsic Functions ..
+      INTRINSIC             ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+      IF( N.LT.1 .OR. INCX.LT.1 )THEN
+         NORM  = ZERO
+      ELSE IF( N.EQ.1 )THEN
+         NORM  = ABS( X( 1 ) )
+      ELSE
+         SCALE = ZERO
+         SSQ   = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL DLASSQ( N, X, INCX, SCALE, SSQ )
+*
+         DO 10, IX = 1, 1 + ( N - 1 )*INCX, INCX
+            IF( X( IX ).NE.ZERO )THEN
+               ABSXI = ABS( X( IX ) )
+               IF( SCALE.LT.ABSXI )THEN
+                  SSQ   = ONE   + SSQ*( SCALE/ABSXI )**2
+                  SCALE = ABSXI
+               ELSE
+                  SSQ   = SSQ   +     ( ABSXI/SCALE )**2
+               END IF
+            END IF
+   10    CONTINUE
+         NORM  = SCALE * SQRT( SSQ )
+      END IF
+*
+      DNRM2 = NORM
+      RETURN
+*
+*     End of DNRM2.
+*
+      END
diff --git a/libcruft/blas/drot.f b/libcruft/blas/drot.f
new file mode 100644
index 0000000..b9ea3bd
--- /dev/null
+++ b/libcruft/blas/drot.f
@@ -0,0 +1,37 @@
+      subroutine  drot (n,dx,incx,dy,incy,c,s)
+c
+c     applies a plane rotation.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dy(*),dtemp,c,s
+      integer i,incx,incy,ix,iy,n
+c
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c       code for unequal increments or equal increments not equal
+c         to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        dtemp = c*dx(ix) + s*dy(iy)
+        dy(iy) = c*dy(iy) - s*dx(ix)
+        dx(ix) = dtemp
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c       code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        dtemp = c*dx(i) + s*dy(i)
+        dy(i) = c*dy(i) - s*dx(i)
+        dx(i) = dtemp
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/dscal.f b/libcruft/blas/dscal.f
new file mode 100644
index 0000000..e1467fa
--- /dev/null
+++ b/libcruft/blas/dscal.f
@@ -0,0 +1,43 @@
+      subroutine  dscal(n,da,dx,incx)
+c
+c     scales a vector by a constant.
+c     uses unrolled loops for increment equal to one.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision da,dx(*)
+      integer i,incx,m,mp1,n,nincx
+c
+      if( n.le.0 .or. incx.le.0 )return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      nincx = n*incx
+      do 10 i = 1,nincx,incx
+        dx(i) = da*dx(i)
+   10 continue
+      return
+c
+c        code for increment equal to 1
+c
+c
+c        clean-up loop
+c
+   20 m = mod(n,5)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        dx(i) = da*dx(i)
+   30 continue
+      if( n .lt. 5 ) return
+   40 mp1 = m + 1
+      do 50 i = mp1,n,5
+        dx(i) = da*dx(i)
+        dx(i + 1) = da*dx(i + 1)
+        dx(i + 2) = da*dx(i + 2)
+        dx(i + 3) = da*dx(i + 3)
+        dx(i + 4) = da*dx(i + 4)
+   50 continue
+      return
+      end
diff --git a/libcruft/blas/dswap.f b/libcruft/blas/dswap.f
new file mode 100644
index 0000000..7f7d1fb
--- /dev/null
+++ b/libcruft/blas/dswap.f
@@ -0,0 +1,56 @@
+      subroutine  dswap (n,dx,incx,dy,incy)
+c
+c     interchanges two vectors.
+c     uses unrolled loops for increments equal one.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dy(*),dtemp
+      integer i,incx,incy,ix,iy,m,mp1,n
+c
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c       code for unequal increments or equal increments not equal
+c         to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        dtemp = dx(ix)
+        dx(ix) = dy(iy)
+        dy(iy) = dtemp
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c       code for both increments equal to 1
+c
+c
+c       clean-up loop
+c
+   20 m = mod(n,3)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        dtemp = dx(i)
+        dx(i) = dy(i)
+        dy(i) = dtemp
+   30 continue
+      if( n .lt. 3 ) return
+   40 mp1 = m + 1
+      do 50 i = mp1,n,3
+        dtemp = dx(i)
+        dx(i) = dy(i)
+        dy(i) = dtemp
+        dtemp = dx(i + 1)
+        dx(i + 1) = dy(i + 1)
+        dy(i + 1) = dtemp
+        dtemp = dx(i + 2)
+        dx(i + 2) = dy(i + 2)
+        dy(i + 2) = dtemp
+   50 continue
+      return
+      end
diff --git a/libcruft/blas/dsymm.f b/libcruft/blas/dsymm.f
new file mode 100644
index 0000000..6556777
--- /dev/null
+++ b/libcruft/blas/dsymm.f
@@ -0,0 +1,294 @@
+      SUBROUTINE DSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*A*B + beta*C,
+*
+*  or
+*
+*     C := alpha*B*A + beta*C,
+*
+*  where alpha and beta are scalars,  A is a symmetric matrix and  B and
+*  C are  m by n matrices.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE  specifies whether  the  symmetric matrix  A
+*           appears on the  left or right  in the  operation as follows:
+*
+*              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*
+*              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of  the  symmetric  matrix   A  is  to  be
+*           referenced as follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*                                  symmetric matrix is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*                                  symmetric matrix is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies the number of rows of the matrix  C.
+*           M  must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix C.
+*           N  must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*           m  when  SIDE = 'L' or 'l'  and is  n otherwise.
+*           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*           the array  A  must contain the  symmetric matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  symmetric matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  m by m  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  symmetric
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*           the array  A  must contain the  symmetric matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  symmetric matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  n by n  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  symmetric
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least  max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+*           Before entry, the leading  m by n part of the array  B  must
+*           contain the matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n updated
+*           matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*A(J,J)
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*A(J,K)
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(J,K)
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DSYMM .
+*
+      END
diff --git a/libcruft/blas/dsymv.f b/libcruft/blas/dsymv.f
new file mode 100644
index 0000000..e1b1492
--- /dev/null
+++ b/libcruft/blas/dsymv.f
@@ -0,0 +1,265 @@
+*
+************************************************************************
+*
+      SUBROUTINE DSYMV ( UPLO, N, ALPHA, A, LDA, X, INCX,
+     $                   BETA, Y, INCY )
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   ALPHA, BETA
+      INTEGER            INCX, INCY, LDA, N
+      CHARACTER*1        UPLO
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYMV  performs the matrix-vector  operation
+*
+*     y := alpha*A*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are n element vectors and
+*  A is an n by n symmetric matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the symmetric matrix and the strictly
+*           lower triangular part of A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the symmetric matrix and the strictly
+*           upper triangular part of A is not referenced.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y. On exit, Y is overwritten by the updated
+*           vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE         , ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP1, TEMP2
+      INTEGER            I, INFO, IX, IY, J, JX, JY, KX, KY
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO, 'U' ).AND.
+     $         .NOT.LSAME( UPLO, 'L' )      )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 5
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 10
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DSYMV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF( INCX.GT.0 )THEN
+         KX = 1
+      ELSE
+         KX = 1 - ( N - 1 )*INCX
+      END IF
+      IF( INCY.GT.0 )THEN
+         KY = 1
+      ELSE
+         KY = 1 - ( N - 1 )*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF( BETA.NE.ONE )THEN
+         IF( INCY.EQ.1 )THEN
+            IF( BETA.EQ.ZERO )THEN
+               DO 10, I = 1, N
+                  Y( I ) = ZERO
+   10          CONTINUE
+            ELSE
+               DO 20, I = 1, N
+                  Y( I ) = BETA*Y( I )
+   20          CONTINUE
+            END IF
+         ELSE
+            IY = KY
+            IF( BETA.EQ.ZERO )THEN
+               DO 30, I = 1, N
+                  Y( IY ) = ZERO
+                  IY      = IY   + INCY
+   30          CONTINUE
+            ELSE
+               DO 40, I = 1, N
+                  Y( IY ) = BETA*Y( IY )
+                  IY      = IY           + INCY
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      IF( ALPHA.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( UPLO, 'U' ) )THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 60, J = 1, N
+               TEMP1 = ALPHA*X( J )
+               TEMP2 = ZERO
+               DO 50, I = 1, J - 1
+                  Y( I ) = Y( I ) + TEMP1*A( I, J )
+                  TEMP2  = TEMP2  + A( I, J )*X( I )
+   50          CONTINUE
+               Y( J ) = Y( J ) + TEMP1*A( J, J ) + ALPHA*TEMP2
+   60       CONTINUE
+         ELSE
+            JX = KX
+            JY = KY
+            DO 80, J = 1, N
+               TEMP1 = ALPHA*X( JX )
+               TEMP2 = ZERO
+               IX    = KX
+               IY    = KY
+               DO 70, I = 1, J - 1
+                  Y( IY ) = Y( IY ) + TEMP1*A( I, J )
+                  TEMP2   = TEMP2   + A( I, J )*X( IX )
+                  IX      = IX      + INCX
+                  IY      = IY      + INCY
+   70          CONTINUE
+               Y( JY ) = Y( JY ) + TEMP1*A( J, J ) + ALPHA*TEMP2
+               JX      = JX      + INCX
+               JY      = JY      + INCY
+   80       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 100, J = 1, N
+               TEMP1  = ALPHA*X( J )
+               TEMP2  = ZERO
+               Y( J ) = Y( J )       + TEMP1*A( J, J )
+               DO 90, I = J + 1, N
+                  Y( I ) = Y( I ) + TEMP1*A( I, J )
+                  TEMP2  = TEMP2  + A( I, J )*X( I )
+   90          CONTINUE
+               Y( J ) = Y( J ) + ALPHA*TEMP2
+  100       CONTINUE
+         ELSE
+            JX = KX
+            JY = KY
+            DO 120, J = 1, N
+               TEMP1   = ALPHA*X( JX )
+               TEMP2   = ZERO
+               Y( JY ) = Y( JY )       + TEMP1*A( J, J )
+               IX      = JX
+               IY      = JY
+               DO 110, I = J + 1, N
+                  IX      = IX      + INCX
+                  IY      = IY      + INCY
+                  Y( IY ) = Y( IY ) + TEMP1*A( I, J )
+                  TEMP2   = TEMP2   + A( I, J )*X( IX )
+  110          CONTINUE
+               Y( JY ) = Y( JY ) + ALPHA*TEMP2
+               JX      = JX      + INCX
+               JY      = JY      + INCY
+  120       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYMV .
+*
+      END
diff --git a/libcruft/blas/dsyr.f b/libcruft/blas/dsyr.f
new file mode 100644
index 0000000..8737719
--- /dev/null
+++ b/libcruft/blas/dsyr.f
@@ -0,0 +1,197 @@
+      SUBROUTINE DSYR  ( UPLO, N, ALPHA, X, INCX, A, LDA )
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   ALPHA
+      INTEGER            INCX, LDA, N
+      CHARACTER*1        UPLO
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYR   performs the symmetric rank 1 operation
+*
+*     A := alpha*x*x' + A,
+*
+*  where alpha is a real scalar, x is an n element vector and A is an
+*  n by n symmetric matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the symmetric matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the symmetric matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER        ( ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP
+      INTEGER            I, INFO, IX, J, JX, KX
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO, 'U' ).AND.
+     $         .NOT.LSAME( UPLO, 'L' )      )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 7
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DSYR  ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) )
+     $   RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF( LSAME( UPLO, 'U' ) )THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+         IF( INCX.EQ.1 )THEN
+            DO 20, J = 1, N
+               IF( X( J ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( J )
+                  DO 10, I = 1, J
+                     A( I, J ) = A( I, J ) + X( I )*TEMP
+   10             CONTINUE
+               END IF
+   20       CONTINUE
+         ELSE
+            JX = KX
+            DO 40, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( JX )
+                  IX   = KX
+                  DO 30, I = 1, J
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP
+                     IX        = IX        + INCX
+   30             CONTINUE
+               END IF
+               JX = JX + INCX
+   40       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+         IF( INCX.EQ.1 )THEN
+            DO 60, J = 1, N
+               IF( X( J ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( J )
+                  DO 50, I = J, N
+                     A( I, J ) = A( I, J ) + X( I )*TEMP
+   50             CONTINUE
+               END IF
+   60       CONTINUE
+         ELSE
+            JX = KX
+            DO 80, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( JX )
+                  IX   = JX
+                  DO 70, I = J, N
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP
+                     IX        = IX        + INCX
+   70             CONTINUE
+               END IF
+               JX = JX + INCX
+   80       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYR  .
+*
+      END
diff --git a/libcruft/blas/dsyr2.f b/libcruft/blas/dsyr2.f
new file mode 100644
index 0000000..ff47d78
--- /dev/null
+++ b/libcruft/blas/dsyr2.f
@@ -0,0 +1,233 @@
+*
+************************************************************************
+*
+      SUBROUTINE DSYR2 ( UPLO, N, ALPHA, X, INCX, Y, INCY, A, LDA )
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   ALPHA
+      INTEGER            INCX, INCY, LDA, N
+      CHARACTER*1        UPLO
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYR2  performs the symmetric rank 2 operation
+*
+*     A := alpha*x*y' + alpha*y*x' + A,
+*
+*  where alpha is a scalar, x and y are n element vectors and A is an n
+*  by n symmetric matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the symmetric matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the symmetric matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER        ( ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP1, TEMP2
+      INTEGER            I, INFO, IX, IY, J, JX, JY, KX, KY
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO, 'U' ).AND.
+     $         .NOT.LSAME( UPLO, 'L' )      )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DSYR2 ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) )
+     $   RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF( ( INCX.NE.1 ).OR.( INCY.NE.1 ) )THEN
+         IF( INCX.GT.0 )THEN
+            KX = 1
+         ELSE
+            KX = 1 - ( N - 1 )*INCX
+         END IF
+         IF( INCY.GT.0 )THEN
+            KY = 1
+         ELSE
+            KY = 1 - ( N - 1 )*INCY
+         END IF
+         JX = KX
+         JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF( LSAME( UPLO, 'U' ) )THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 20, J = 1, N
+               IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN
+                  TEMP1 = ALPHA*Y( J )
+                  TEMP2 = ALPHA*X( J )
+                  DO 10, I = 1, J
+                     A( I, J ) = A( I, J ) + X( I )*TEMP1 + Y( I )*TEMP2
+   10             CONTINUE
+               END IF
+   20       CONTINUE
+         ELSE
+            DO 40, J = 1, N
+               IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN
+                  TEMP1 = ALPHA*Y( JY )
+                  TEMP2 = ALPHA*X( JX )
+                  IX    = KX
+                  IY    = KY
+                  DO 30, I = 1, J
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP1
+     $                                     + Y( IY )*TEMP2
+                     IX        = IX        + INCX
+                     IY        = IY        + INCY
+   30             CONTINUE
+               END IF
+               JX = JX + INCX
+               JY = JY + INCY
+   40       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 60, J = 1, N
+               IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN
+                  TEMP1 = ALPHA*Y( J )
+                  TEMP2 = ALPHA*X( J )
+                  DO 50, I = J, N
+                     A( I, J ) = A( I, J ) + X( I )*TEMP1 + Y( I )*TEMP2
+   50             CONTINUE
+               END IF
+   60       CONTINUE
+         ELSE
+            DO 80, J = 1, N
+               IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN
+                  TEMP1 = ALPHA*Y( JY )
+                  TEMP2 = ALPHA*X( JX )
+                  IX    = JX
+                  IY    = JY
+                  DO 70, I = J, N
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP1
+     $                                     + Y( IY )*TEMP2
+                     IX        = IX        + INCX
+                     IY        = IY        + INCY
+   70             CONTINUE
+               END IF
+               JX = JX + INCX
+               JY = JY + INCY
+   80       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYR2 .
+*
+      END
diff --git a/libcruft/blas/dsyr2k.f b/libcruft/blas/dsyr2k.f
new file mode 100644
index 0000000..7f359e1
--- /dev/null
+++ b/libcruft/blas/dsyr2k.f
@@ -0,0 +1,330 @@
+*
+************************************************************************
+*
+      SUBROUTINE DSYR2K( UPLO, TRANS, N, K, ALPHA, A, LDA, B, LDB,
+     $                   BETA, C, LDC )
+*     .. Scalar Arguments ..
+      CHARACTER*1        UPLO, TRANS
+      INTEGER            N, K, LDA, LDB, LDC
+      DOUBLE PRECISION   ALPHA, BETA
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYR2K  performs one of the symmetric rank 2k operations
+*
+*     C := alpha*A*B' + alpha*B*A' + beta*C,
+*
+*  or
+*
+*     C := alpha*A'*B + alpha*B'*A + beta*C,
+*
+*  where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*  and  A and B  are  n by k  matrices  in the  first  case  and  k by n
+*  matrices in the second case.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*B' + alpha*B*A' +
+*                                        beta*C.
+*
+*              TRANS = 'T' or 't'   C := alpha*A'*B + alpha*B'*A +
+*                                        beta*C.
+*
+*              TRANS = 'C' or 'c'   C := alpha*A'*B + alpha*B'*A +
+*                                        beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns  of the  matrices  A and B,  and on  entry  with
+*           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*           of rows of the matrices  A and B.  K must be at least  zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  k by n  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  symmetric matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  symmetric matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, INFO, J, L, NROWA
+      DOUBLE PRECISION   TEMP1, TEMP2
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE         , ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+         NROWA = N
+      ELSE
+         NROWA = K
+      END IF
+      UPPER = LSAME( UPLO, 'U' )
+*
+      INFO = 0
+      IF(      ( .NOT.UPPER               ).AND.
+     $         ( .NOT.LSAME( UPLO , 'L' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ).AND.
+     $         ( .NOT.LSAME( TRANS, 'T' ) ).AND.
+     $         ( .NOT.LSAME( TRANS, 'C' ) )      )THEN
+         INFO = 2
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 3
+      ELSE IF( K  .LT.0               )THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 7
+      ELSE IF( LDB.LT.MAX( 1, NROWA ) )THEN
+         INFO = 9
+      ELSE IF( LDC.LT.MAX( 1, N     ) )THEN
+         INFO = 12
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DSYR2K', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.
+     $    ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         IF( UPPER )THEN
+            IF( BETA.EQ.ZERO )THEN
+               DO 20, J = 1, N
+                  DO 10, I = 1, J
+                     C( I, J ) = ZERO
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40, J = 1, N
+                  DO 30, I = 1, J
+                     C( I, J ) = BETA*C( I, J )
+   30             CONTINUE
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( BETA.EQ.ZERO )THEN
+               DO 60, J = 1, N
+                  DO 50, I = J, N
+                     C( I, J ) = ZERO
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80, J = 1, N
+                  DO 70, I = J, N
+                     C( I, J ) = BETA*C( I, J )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  C := alpha*A*B' + alpha*B*A' + C.
+*
+         IF( UPPER )THEN
+            DO 130, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 90, I = 1, J
+                     C( I, J ) = ZERO
+   90             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 100, I = 1, J
+                     C( I, J ) = BETA*C( I, J )
+  100             CONTINUE
+               END IF
+               DO 120, L = 1, K
+                  IF( ( A( J, L ).NE.ZERO ).OR.
+     $                ( B( J, L ).NE.ZERO )     )THEN
+                     TEMP1 = ALPHA*B( J, L )
+                     TEMP2 = ALPHA*A( J, L )
+                     DO 110, I = 1, J
+                        C( I, J ) = C( I, J ) +
+     $                              A( I, L )*TEMP1 + B( I, L )*TEMP2
+  110                CONTINUE
+                  END IF
+  120          CONTINUE
+  130       CONTINUE
+         ELSE
+            DO 180, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 140, I = J, N
+                     C( I, J ) = ZERO
+  140             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 150, I = J, N
+                     C( I, J ) = BETA*C( I, J )
+  150             CONTINUE
+               END IF
+               DO 170, L = 1, K
+                  IF( ( A( J, L ).NE.ZERO ).OR.
+     $                ( B( J, L ).NE.ZERO )     )THEN
+                     TEMP1 = ALPHA*B( J, L )
+                     TEMP2 = ALPHA*A( J, L )
+                     DO 160, I = J, N
+                        C( I, J ) = C( I, J ) +
+     $                              A( I, L )*TEMP1 + B( I, L )*TEMP2
+  160                CONTINUE
+                  END IF
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  C := alpha*A'*B + alpha*B'*A + C.
+*
+         IF( UPPER )THEN
+            DO 210, J = 1, N
+               DO 200, I = 1, J
+                  TEMP1 = ZERO
+                  TEMP2 = ZERO
+                  DO 190, L = 1, K
+                     TEMP1 = TEMP1 + A( L, I )*B( L, J )
+                     TEMP2 = TEMP2 + B( L, I )*A( L, J )
+  190             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP1 + ALPHA*TEMP2
+                  ELSE
+                     C( I, J ) = BETA *C( I, J ) +
+     $                           ALPHA*TEMP1 + ALPHA*TEMP2
+                  END IF
+  200          CONTINUE
+  210       CONTINUE
+         ELSE
+            DO 240, J = 1, N
+               DO 230, I = J, N
+                  TEMP1 = ZERO
+                  TEMP2 = ZERO
+                  DO 220, L = 1, K
+                     TEMP1 = TEMP1 + A( L, I )*B( L, J )
+                     TEMP2 = TEMP2 + B( L, I )*A( L, J )
+  220             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP1 + ALPHA*TEMP2
+                  ELSE
+                     C( I, J ) = BETA *C( I, J ) +
+     $                           ALPHA*TEMP1 + ALPHA*TEMP2
+                  END IF
+  230          CONTINUE
+  240       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYR2K.
+*
+      END
diff --git a/libcruft/blas/dsyrk.f b/libcruft/blas/dsyrk.f
new file mode 100644
index 0000000..b618b29
--- /dev/null
+++ b/libcruft/blas/dsyrk.f
@@ -0,0 +1,294 @@
+      SUBROUTINE DSYRK ( UPLO, TRANS, N, K, ALPHA, A, LDA,
+     $                   BETA, C, LDC )
+*     .. Scalar Arguments ..
+      CHARACTER*1        UPLO, TRANS
+      INTEGER            N, K, LDA, LDC
+      DOUBLE PRECISION   ALPHA, BETA
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYRK  performs one of the symmetric rank k operations
+*
+*     C := alpha*A*A' + beta*C,
+*
+*  or
+*
+*     C := alpha*A'*A + beta*C,
+*
+*  where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*  and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*  in the second case.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*A' + beta*C.
+*
+*              TRANS = 'T' or 't'   C := alpha*A'*A + beta*C.
+*
+*              TRANS = 'C' or 'c'   C := alpha*A'*A + beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns   of  the   matrix   A,   and  on   entry   with
+*           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*           of rows of the matrix  A.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  symmetric matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  symmetric matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, INFO, J, L, NROWA
+      DOUBLE PRECISION   TEMP
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE ,         ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+         NROWA = N
+      ELSE
+         NROWA = K
+      END IF
+      UPPER = LSAME( UPLO, 'U' )
+*
+      INFO = 0
+      IF(      ( .NOT.UPPER               ).AND.
+     $         ( .NOT.LSAME( UPLO , 'L' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ).AND.
+     $         ( .NOT.LSAME( TRANS, 'T' ) ).AND.
+     $         ( .NOT.LSAME( TRANS, 'C' ) )      )THEN
+         INFO = 2
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 3
+      ELSE IF( K  .LT.0               )THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 7
+      ELSE IF( LDC.LT.MAX( 1, N     ) )THEN
+         INFO = 10
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DSYRK ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.
+     $    ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         IF( UPPER )THEN
+            IF( BETA.EQ.ZERO )THEN
+               DO 20, J = 1, N
+                  DO 10, I = 1, J
+                     C( I, J ) = ZERO
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40, J = 1, N
+                  DO 30, I = 1, J
+                     C( I, J ) = BETA*C( I, J )
+   30             CONTINUE
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( BETA.EQ.ZERO )THEN
+               DO 60, J = 1, N
+                  DO 50, I = J, N
+                     C( I, J ) = ZERO
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80, J = 1, N
+                  DO 70, I = J, N
+                     C( I, J ) = BETA*C( I, J )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  C := alpha*A*A' + beta*C.
+*
+         IF( UPPER )THEN
+            DO 130, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 90, I = 1, J
+                     C( I, J ) = ZERO
+   90             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 100, I = 1, J
+                     C( I, J ) = BETA*C( I, J )
+  100             CONTINUE
+               END IF
+               DO 120, L = 1, K
+                  IF( A( J, L ).NE.ZERO )THEN
+                     TEMP = ALPHA*A( J, L )
+                     DO 110, I = 1, J
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  110                CONTINUE
+                  END IF
+  120          CONTINUE
+  130       CONTINUE
+         ELSE
+            DO 180, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 140, I = J, N
+                     C( I, J ) = ZERO
+  140             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 150, I = J, N
+                     C( I, J ) = BETA*C( I, J )
+  150             CONTINUE
+               END IF
+               DO 170, L = 1, K
+                  IF( A( J, L ).NE.ZERO )THEN
+                     TEMP      = ALPHA*A( J, L )
+                     DO 160, I = J, N
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  160                CONTINUE
+                  END IF
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  C := alpha*A'*A + beta*C.
+*
+         IF( UPPER )THEN
+            DO 210, J = 1, N
+               DO 200, I = 1, J
+                  TEMP = ZERO
+                  DO 190, L = 1, K
+                     TEMP = TEMP + A( L, I )*A( L, J )
+  190             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  200          CONTINUE
+  210       CONTINUE
+         ELSE
+            DO 240, J = 1, N
+               DO 230, I = J, N
+                  TEMP = ZERO
+                  DO 220, L = 1, K
+                     TEMP = TEMP + A( L, I )*A( L, J )
+  220             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  230          CONTINUE
+  240       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYRK .
+*
+      END
diff --git a/libcruft/blas/dtbsv.f b/libcruft/blas/dtbsv.f
new file mode 100644
index 0000000..d87ed82
--- /dev/null
+++ b/libcruft/blas/dtbsv.f
@@ -0,0 +1,346 @@
+      SUBROUTINE DTBSV ( UPLO, TRANS, DIAG, N, K, A, LDA, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER            INCX, K, LDA, N
+      CHARACTER*1        DIAG, TRANS, UPLO
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTBSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*  diagonals.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   A'*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with UPLO = 'U' or 'u', K specifies the number of
+*           super-diagonals of the matrix A.
+*           On entry with UPLO = 'L' or 'l', K specifies the number of
+*           sub-diagonals of the matrix A.
+*           K must satisfy  0 .le. K.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*           by n part of the array A must contain the upper triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row
+*           ( k + 1 ) of the array, the first super-diagonal starting at
+*           position 2 in row k, and so on. The top left k by k triangle
+*           of the array A is not referenced.
+*           The following program segment will transfer an upper
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = K + 1 - J
+*                    DO 10, I = MAX( 1, J - K ), J
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*           by n part of the array A must contain the lower triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row 1 of
+*           the array, the first sub-diagonal starting at position 1 in
+*           row 2, and so on. The bottom right k by k triangle of the
+*           array A is not referenced.
+*           The following program segment will transfer a lower
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = 1 - J
+*                    DO 10, I = J, MIN( N, J + K )
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Note that when DIAG = 'U' or 'u' the elements of the array A
+*           corresponding to the diagonal elements of the matrix are not
+*           referenced, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           ( k + 1 ).
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER        ( ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP
+      INTEGER            I, INFO, IX, J, JX, KPLUS1, KX, L
+      LOGICAL            NOUNIT
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO , 'U' ).AND.
+     $         .NOT.LSAME( UPLO , 'L' )      )THEN
+         INFO = 1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 2
+      ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
+     $         .NOT.LSAME( DIAG , 'N' )      )THEN
+         INFO = 3
+      ELSE IF( N.LT.0 )THEN
+         INFO = 4
+      ELSE IF( K.LT.0 )THEN
+         INFO = 5
+      ELSE IF( LDA.LT.( K + 1 ) )THEN
+         INFO = 7
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DTBSV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  x := inv( A )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            KPLUS1 = K + 1
+            IF( INCX.EQ.1 )THEN
+               DO 20, J = N, 1, -1
+                  IF( X( J ).NE.ZERO )THEN
+                     L = KPLUS1 - J
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( KPLUS1, J )
+                     TEMP = X( J )
+                     DO 10, I = J - 1, MAX( 1, J - K ), -1
+                        X( I ) = X( I ) - TEMP*A( L + I, J )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 40, J = N, 1, -1
+                  KX = KX - INCX
+                  IF( X( JX ).NE.ZERO )THEN
+                     IX = KX
+                     L  = KPLUS1 - J
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( KPLUS1, J )
+                     TEMP = X( JX )
+                     DO 30, I = J - 1, MAX( 1, J - K ), -1
+                        X( IX ) = X( IX ) - TEMP*A( L + I, J )
+                        IX      = IX      - INCX
+   30                CONTINUE
+                  END IF
+                  JX = JX - INCX
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 60, J = 1, N
+                  IF( X( J ).NE.ZERO )THEN
+                     L = 1 - J
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( 1, J )
+                     TEMP = X( J )
+                     DO 50, I = J + 1, MIN( N, J + K )
+                        X( I ) = X( I ) - TEMP*A( L + I, J )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE
+               JX = KX
+               DO 80, J = 1, N
+                  KX = KX + INCX
+                  IF( X( JX ).NE.ZERO )THEN
+                     IX = KX
+                     L  = 1  - J
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( 1, J )
+                     TEMP = X( JX )
+                     DO 70, I = J + 1, MIN( N, J + K )
+                        X( IX ) = X( IX ) - TEMP*A( L + I, J )
+                        IX      = IX      + INCX
+   70                CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE
+*
+*        Form  x := inv( A')*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            KPLUS1 = K + 1
+            IF( INCX.EQ.1 )THEN
+               DO 100, J = 1, N
+                  TEMP = X( J )
+                  L    = KPLUS1 - J
+                  DO 90, I = MAX( 1, J - K ), J - 1
+                     TEMP = TEMP - A( L + I, J )*X( I )
+   90             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( KPLUS1, J )
+                  X( J ) = TEMP
+  100          CONTINUE
+            ELSE
+               JX = KX
+               DO 120, J = 1, N
+                  TEMP = X( JX )
+                  IX   = KX
+                  L    = KPLUS1  - J
+                  DO 110, I = MAX( 1, J - K ), J - 1
+                     TEMP = TEMP - A( L + I, J )*X( IX )
+                     IX   = IX   + INCX
+  110             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( KPLUS1, J )
+                  X( JX ) = TEMP
+                  JX      = JX   + INCX
+                  IF( J.GT.K )
+     $               KX = KX + INCX
+  120          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 140, J = N, 1, -1
+                  TEMP = X( J )
+                  L    = 1      - J
+                  DO 130, I = MIN( N, J + K ), J + 1, -1
+                     TEMP = TEMP - A( L + I, J )*X( I )
+  130             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( 1, J )
+                  X( J ) = TEMP
+  140          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 160, J = N, 1, -1
+                  TEMP = X( JX )
+                  IX   = KX
+                  L    = 1       - J
+                  DO 150, I = MIN( N, J + K ), J + 1, -1
+                     TEMP = TEMP - A( L + I, J )*X( IX )
+                     IX   = IX   - INCX
+  150             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( 1, J )
+                  X( JX ) = TEMP
+                  JX      = JX   - INCX
+                  IF( ( N - J ).GE.K )
+     $               KX = KX - INCX
+  160          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTBSV .
+*
+      END
diff --git a/libcruft/blas/dtrmm.f b/libcruft/blas/dtrmm.f
new file mode 100644
index 0000000..40c7740
--- /dev/null
+++ b/libcruft/blas/dtrmm.f
@@ -0,0 +1,355 @@
+      SUBROUTINE DTRMM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA,
+     $                   B, LDB )
+*     .. Scalar Arguments ..
+      CHARACTER*1        SIDE, UPLO, TRANSA, DIAG
+      INTEGER            M, N, LDA, LDB
+      DOUBLE PRECISION   ALPHA
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRMM  performs one of the matrix-matrix operations
+*
+*     B := alpha*op( A )*B,   or   B := alpha*B*op( A ),
+*
+*  where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'.
+*
+*  Parameters
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*           the left or right as follows:
+*
+*              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*
+*              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = A'.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain the matrix  B,  and  on exit  is overwritten  by the
+*           transformed matrix.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     .. Local Scalars ..
+      LOGICAL            LSIDE, NOUNIT, UPPER
+      INTEGER            I, INFO, J, K, NROWA
+      DOUBLE PRECISION   TEMP
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE         , ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      LSIDE  = LSAME( SIDE  , 'L' )
+      IF( LSIDE )THEN
+         NROWA = M
+      ELSE
+         NROWA = N
+      END IF
+      NOUNIT = LSAME( DIAG  , 'N' )
+      UPPER  = LSAME( UPLO  , 'U' )
+*
+      INFO   = 0
+      IF(      ( .NOT.LSIDE                ).AND.
+     $         ( .NOT.LSAME( SIDE  , 'R' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.UPPER                ).AND.
+     $         ( .NOT.LSAME( UPLO  , 'L' ) )      )THEN
+         INFO = 2
+      ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'T' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'C' ) )      )THEN
+         INFO = 3
+      ELSE IF( ( .NOT.LSAME( DIAG  , 'U' ) ).AND.
+     $         ( .NOT.LSAME( DIAG  , 'N' ) )      )THEN
+         INFO = 4
+      ELSE IF( M  .LT.0               )THEN
+         INFO = 5
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 6
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 9
+      ELSE IF( LDB.LT.MAX( 1, M     ) )THEN
+         INFO = 11
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DTRMM ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         DO 20, J = 1, N
+            DO 10, I = 1, M
+               B( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSIDE )THEN
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*A*B.
+*
+            IF( UPPER )THEN
+               DO 50, J = 1, N
+                  DO 40, K = 1, M
+                     IF( B( K, J ).NE.ZERO )THEN
+                        TEMP = ALPHA*B( K, J )
+                        DO 30, I = 1, K - 1
+                           B( I, J ) = B( I, J ) + TEMP*A( I, K )
+   30                   CONTINUE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP*A( K, K )
+                        B( K, J ) = TEMP
+                     END IF
+   40             CONTINUE
+   50          CONTINUE
+            ELSE
+               DO 80, J = 1, N
+                  DO 70 K = M, 1, -1
+                     IF( B( K, J ).NE.ZERO )THEN
+                        TEMP      = ALPHA*B( K, J )
+                        B( K, J ) = TEMP
+                        IF( NOUNIT )
+     $                     B( K, J ) = B( K, J )*A( K, K )
+                        DO 60, I = K + 1, M
+                           B( I, J ) = B( I, J ) + TEMP*A( I, K )
+   60                   CONTINUE
+                     END IF
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*A'*B.
+*
+            IF( UPPER )THEN
+               DO 110, J = 1, N
+                  DO 100, I = M, 1, -1
+                     TEMP = B( I, J )
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*A( I, I )
+                     DO 90, K = 1, I - 1
+                        TEMP = TEMP + A( K, I )*B( K, J )
+   90                CONTINUE
+                     B( I, J ) = ALPHA*TEMP
+  100             CONTINUE
+  110          CONTINUE
+            ELSE
+               DO 140, J = 1, N
+                  DO 130, I = 1, M
+                     TEMP = B( I, J )
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*A( I, I )
+                     DO 120, K = I + 1, M
+                        TEMP = TEMP + A( K, I )*B( K, J )
+  120                CONTINUE
+                     B( I, J ) = ALPHA*TEMP
+  130             CONTINUE
+  140          CONTINUE
+            END IF
+         END IF
+      ELSE
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*B*A.
+*
+            IF( UPPER )THEN
+               DO 180, J = N, 1, -1
+                  TEMP = ALPHA
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 150, I = 1, M
+                     B( I, J ) = TEMP*B( I, J )
+  150             CONTINUE
+                  DO 170, K = 1, J - 1
+                     IF( A( K, J ).NE.ZERO )THEN
+                        TEMP = ALPHA*A( K, J )
+                        DO 160, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  160                   CONTINUE
+                     END IF
+  170             CONTINUE
+  180          CONTINUE
+            ELSE
+               DO 220, J = 1, N
+                  TEMP = ALPHA
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 190, I = 1, M
+                     B( I, J ) = TEMP*B( I, J )
+  190             CONTINUE
+                  DO 210, K = J + 1, N
+                     IF( A( K, J ).NE.ZERO )THEN
+                        TEMP = ALPHA*A( K, J )
+                        DO 200, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  200                   CONTINUE
+                     END IF
+  210             CONTINUE
+  220          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*B*A'.
+*
+            IF( UPPER )THEN
+               DO 260, K = 1, N
+                  DO 240, J = 1, K - 1
+                     IF( A( J, K ).NE.ZERO )THEN
+                        TEMP = ALPHA*A( J, K )
+                        DO 230, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  230                   CONTINUE
+                     END IF
+  240             CONTINUE
+                  TEMP = ALPHA
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( K, K )
+                  IF( TEMP.NE.ONE )THEN
+                     DO 250, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  250                CONTINUE
+                  END IF
+  260          CONTINUE
+            ELSE
+               DO 300, K = N, 1, -1
+                  DO 280, J = K + 1, N
+                     IF( A( J, K ).NE.ZERO )THEN
+                        TEMP = ALPHA*A( J, K )
+                        DO 270, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  270                   CONTINUE
+                     END IF
+  280             CONTINUE
+                  TEMP = ALPHA
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( K, K )
+                  IF( TEMP.NE.ONE )THEN
+                     DO 290, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  290                CONTINUE
+                  END IF
+  300          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRMM .
+*
+      END
diff --git a/libcruft/blas/dtrmv.f b/libcruft/blas/dtrmv.f
new file mode 100644
index 0000000..3d5c61b
--- /dev/null
+++ b/libcruft/blas/dtrmv.f
@@ -0,0 +1,286 @@
+      SUBROUTINE DTRMV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER            INCX, LDA, N
+      CHARACTER*1        DIAG, TRANS, UPLO
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRMV  performs one of the matrix-vector operations
+*
+*     x := A*x,   or   x := A'*x,
+*
+*  where x is an n element vector and  A is an n by n unit, or non-unit,
+*  upper or lower triangular matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   x := A*x.
+*
+*              TRANS = 'T' or 't'   x := A'*x.
+*
+*              TRANS = 'C' or 'c'   x := A'*x.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x. On exit, X is overwritten with the
+*           tranformed vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER        ( ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP
+      INTEGER            I, INFO, IX, J, JX, KX
+      LOGICAL            NOUNIT
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO , 'U' ).AND.
+     $         .NOT.LSAME( UPLO , 'L' )      )THEN
+         INFO = 1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 2
+      ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
+     $         .NOT.LSAME( DIAG , 'N' )      )THEN
+         INFO = 3
+      ELSE IF( N.LT.0 )THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 6
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 8
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DTRMV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  x := A*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 20, J = 1, N
+                  IF( X( J ).NE.ZERO )THEN
+                     TEMP = X( J )
+                     DO 10, I = 1, J - 1
+                        X( I ) = X( I ) + TEMP*A( I, J )
+   10                CONTINUE
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )*A( J, J )
+                  END IF
+   20          CONTINUE
+            ELSE
+               JX = KX
+               DO 40, J = 1, N
+                  IF( X( JX ).NE.ZERO )THEN
+                     TEMP = X( JX )
+                     IX   = KX
+                     DO 30, I = 1, J - 1
+                        X( IX ) = X( IX ) + TEMP*A( I, J )
+                        IX      = IX      + INCX
+   30                CONTINUE
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )*A( J, J )
+                  END IF
+                  JX = JX + INCX
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 60, J = N, 1, -1
+                  IF( X( J ).NE.ZERO )THEN
+                     TEMP = X( J )
+                     DO 50, I = N, J + 1, -1
+                        X( I ) = X( I ) + TEMP*A( I, J )
+   50                CONTINUE
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )*A( J, J )
+                  END IF
+   60          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 80, J = N, 1, -1
+                  IF( X( JX ).NE.ZERO )THEN
+                     TEMP = X( JX )
+                     IX   = KX
+                     DO 70, I = N, J + 1, -1
+                        X( IX ) = X( IX ) + TEMP*A( I, J )
+                        IX      = IX      - INCX
+   70                CONTINUE
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )*A( J, J )
+                  END IF
+                  JX = JX - INCX
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE
+*
+*        Form  x := A'*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 100, J = N, 1, -1
+                  TEMP = X( J )
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 90, I = J - 1, 1, -1
+                     TEMP = TEMP + A( I, J )*X( I )
+   90             CONTINUE
+                  X( J ) = TEMP
+  100          CONTINUE
+            ELSE
+               JX = KX + ( N - 1 )*INCX
+               DO 120, J = N, 1, -1
+                  TEMP = X( JX )
+                  IX   = JX
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 110, I = J - 1, 1, -1
+                     IX   = IX   - INCX
+                     TEMP = TEMP + A( I, J )*X( IX )
+  110             CONTINUE
+                  X( JX ) = TEMP
+                  JX      = JX   - INCX
+  120          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 140, J = 1, N
+                  TEMP = X( J )
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 130, I = J + 1, N
+                     TEMP = TEMP + A( I, J )*X( I )
+  130             CONTINUE
+                  X( J ) = TEMP
+  140          CONTINUE
+            ELSE
+               JX = KX
+               DO 160, J = 1, N
+                  TEMP = X( JX )
+                  IX   = JX
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 150, I = J + 1, N
+                     IX   = IX   + INCX
+                     TEMP = TEMP + A( I, J )*X( IX )
+  150             CONTINUE
+                  X( JX ) = TEMP
+                  JX      = JX   + INCX
+  160          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRMV .
+*
+      END
diff --git a/libcruft/blas/dtrsm.f b/libcruft/blas/dtrsm.f
new file mode 100644
index 0000000..e842514
--- /dev/null
+++ b/libcruft/blas/dtrsm.f
@@ -0,0 +1,378 @@
+      SUBROUTINE DTRSM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA,
+     $                   B, LDB )
+*     .. Scalar Arguments ..
+      CHARACTER*1        SIDE, UPLO, TRANSA, DIAG
+      INTEGER            M, N, LDA, LDB
+      DOUBLE PRECISION   ALPHA
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRSM  solves one of the matrix equations
+*
+*     op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*
+*  where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'.
+*
+*  The matrix X is overwritten on B.
+*
+*  Parameters
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry, SIDE specifies whether op( A ) appears on the left
+*           or right of X as follows:
+*
+*              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*
+*              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = A'.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*           overwritten by the solution matrix  X.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     .. Local Scalars ..
+      LOGICAL            LSIDE, NOUNIT, UPPER
+      INTEGER            I, INFO, J, K, NROWA
+      DOUBLE PRECISION   TEMP
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE         , ZERO
+      PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      LSIDE  = LSAME( SIDE  , 'L' )
+      IF( LSIDE )THEN
+         NROWA = M
+      ELSE
+         NROWA = N
+      END IF
+      NOUNIT = LSAME( DIAG  , 'N' )
+      UPPER  = LSAME( UPLO  , 'U' )
+*
+      INFO   = 0
+      IF(      ( .NOT.LSIDE                ).AND.
+     $         ( .NOT.LSAME( SIDE  , 'R' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.UPPER                ).AND.
+     $         ( .NOT.LSAME( UPLO  , 'L' ) )      )THEN
+         INFO = 2
+      ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'T' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'C' ) )      )THEN
+         INFO = 3
+      ELSE IF( ( .NOT.LSAME( DIAG  , 'U' ) ).AND.
+     $         ( .NOT.LSAME( DIAG  , 'N' ) )      )THEN
+         INFO = 4
+      ELSE IF( M  .LT.0               )THEN
+         INFO = 5
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 6
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 9
+      ELSE IF( LDB.LT.MAX( 1, M     ) )THEN
+         INFO = 11
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DTRSM ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         DO 20, J = 1, N
+            DO 10, I = 1, M
+               B( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSIDE )THEN
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+            IF( UPPER )THEN
+               DO 60, J = 1, N
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 30, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+   30                CONTINUE
+                  END IF
+                  DO 50, K = M, 1, -1
+                     IF( B( K, J ).NE.ZERO )THEN
+                        IF( NOUNIT )
+     $                     B( K, J ) = B( K, J )/A( K, K )
+                        DO 40, I = 1, K - 1
+                           B( I, J ) = B( I, J ) - B( K, J )*A( I, K )
+   40                   CONTINUE
+                     END IF
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 100, J = 1, N
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 70, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+   70                CONTINUE
+                  END IF
+                  DO 90 K = 1, M
+                     IF( B( K, J ).NE.ZERO )THEN
+                        IF( NOUNIT )
+     $                     B( K, J ) = B( K, J )/A( K, K )
+                        DO 80, I = K + 1, M
+                           B( I, J ) = B( I, J ) - B( K, J )*A( I, K )
+   80                   CONTINUE
+                     END IF
+   90             CONTINUE
+  100          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*inv( A' )*B.
+*
+            IF( UPPER )THEN
+               DO 130, J = 1, N
+                  DO 120, I = 1, M
+                     TEMP = ALPHA*B( I, J )
+                     DO 110, K = 1, I - 1
+                        TEMP = TEMP - A( K, I )*B( K, J )
+  110                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( I, I )
+                     B( I, J ) = TEMP
+  120             CONTINUE
+  130          CONTINUE
+            ELSE
+               DO 160, J = 1, N
+                  DO 150, I = M, 1, -1
+                     TEMP = ALPHA*B( I, J )
+                     DO 140, K = I + 1, M
+                        TEMP = TEMP - A( K, I )*B( K, J )
+  140                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( I, I )
+                     B( I, J ) = TEMP
+  150             CONTINUE
+  160          CONTINUE
+            END IF
+         END IF
+      ELSE
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+            IF( UPPER )THEN
+               DO 210, J = 1, N
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 170, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+  170                CONTINUE
+                  END IF
+                  DO 190, K = 1, J - 1
+                     IF( A( K, J ).NE.ZERO )THEN
+                        DO 180, I = 1, M
+                           B( I, J ) = B( I, J ) - A( K, J )*B( I, K )
+  180                   CONTINUE
+                     END IF
+  190             CONTINUE
+                  IF( NOUNIT )THEN
+                     TEMP = ONE/A( J, J )
+                     DO 200, I = 1, M
+                        B( I, J ) = TEMP*B( I, J )
+  200                CONTINUE
+                  END IF
+  210          CONTINUE
+            ELSE
+               DO 260, J = N, 1, -1
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 220, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+  220                CONTINUE
+                  END IF
+                  DO 240, K = J + 1, N
+                     IF( A( K, J ).NE.ZERO )THEN
+                        DO 230, I = 1, M
+                           B( I, J ) = B( I, J ) - A( K, J )*B( I, K )
+  230                   CONTINUE
+                     END IF
+  240             CONTINUE
+                  IF( NOUNIT )THEN
+                     TEMP = ONE/A( J, J )
+                     DO 250, I = 1, M
+                       B( I, J ) = TEMP*B( I, J )
+  250                CONTINUE
+                  END IF
+  260          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*B*inv( A' ).
+*
+            IF( UPPER )THEN
+               DO 310, K = N, 1, -1
+                  IF( NOUNIT )THEN
+                     TEMP = ONE/A( K, K )
+                     DO 270, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  270                CONTINUE
+                  END IF
+                  DO 290, J = 1, K - 1
+                     IF( A( J, K ).NE.ZERO )THEN
+                        TEMP = A( J, K )
+                        DO 280, I = 1, M
+                           B( I, J ) = B( I, J ) - TEMP*B( I, K )
+  280                   CONTINUE
+                     END IF
+  290             CONTINUE
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 300, I = 1, M
+                        B( I, K ) = ALPHA*B( I, K )
+  300                CONTINUE
+                  END IF
+  310          CONTINUE
+            ELSE
+               DO 360, K = 1, N
+                  IF( NOUNIT )THEN
+                     TEMP = ONE/A( K, K )
+                     DO 320, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  320                CONTINUE
+                  END IF
+                  DO 340, J = K + 1, N
+                     IF( A( J, K ).NE.ZERO )THEN
+                        TEMP = A( J, K )
+                        DO 330, I = 1, M
+                           B( I, J ) = B( I, J ) - TEMP*B( I, K )
+  330                   CONTINUE
+                     END IF
+  340             CONTINUE
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 350, I = 1, M
+                        B( I, K ) = ALPHA*B( I, K )
+  350                CONTINUE
+                  END IF
+  360          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRSM .
+*
+      END
diff --git a/libcruft/blas/dtrsv.f b/libcruft/blas/dtrsv.f
new file mode 100644
index 0000000..9c3e90a
--- /dev/null
+++ b/libcruft/blas/dtrsv.f
@@ -0,0 +1,289 @@
+      SUBROUTINE DTRSV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER            INCX, LDA, N
+      CHARACTER*1        DIAG, TRANS, UPLO
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular matrix.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   A'*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - DOUBLE PRECISION array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER        ( ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      DOUBLE PRECISION   TEMP
+      INTEGER            I, INFO, IX, J, JX, KX
+      LOGICAL            NOUNIT
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO , 'U' ).AND.
+     $         .NOT.LSAME( UPLO , 'L' )      )THEN
+         INFO = 1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 2
+      ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
+     $         .NOT.LSAME( DIAG , 'N' )      )THEN
+         INFO = 3
+      ELSE IF( N.LT.0 )THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 6
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 8
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'DTRSV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  x := inv( A )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 20, J = N, 1, -1
+                  IF( X( J ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( J, J )
+                     TEMP = X( J )
+                     DO 10, I = J - 1, 1, -1
+                        X( I ) = X( I ) - TEMP*A( I, J )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE
+               JX = KX + ( N - 1 )*INCX
+               DO 40, J = N, 1, -1
+                  IF( X( JX ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( J, J )
+                     TEMP = X( JX )
+                     IX   = JX
+                     DO 30, I = J - 1, 1, -1
+                        IX      = IX      - INCX
+                        X( IX ) = X( IX ) - TEMP*A( I, J )
+   30                CONTINUE
+                  END IF
+                  JX = JX - INCX
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 60, J = 1, N
+                  IF( X( J ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( J, J )
+                     TEMP = X( J )
+                     DO 50, I = J + 1, N
+                        X( I ) = X( I ) - TEMP*A( I, J )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE
+               JX = KX
+               DO 80, J = 1, N
+                  IF( X( JX ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( J, J )
+                     TEMP = X( JX )
+                     IX   = JX
+                     DO 70, I = J + 1, N
+                        IX      = IX      + INCX
+                        X( IX ) = X( IX ) - TEMP*A( I, J )
+   70                CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE
+*
+*        Form  x := inv( A' )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 100, J = 1, N
+                  TEMP = X( J )
+                  DO 90, I = 1, J - 1
+                     TEMP = TEMP - A( I, J )*X( I )
+   90             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( J, J )
+                  X( J ) = TEMP
+  100          CONTINUE
+            ELSE
+               JX = KX
+               DO 120, J = 1, N
+                  TEMP = X( JX )
+                  IX   = KX
+                  DO 110, I = 1, J - 1
+                     TEMP = TEMP - A( I, J )*X( IX )
+                     IX   = IX   + INCX
+  110             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( J, J )
+                  X( JX ) = TEMP
+                  JX      = JX   + INCX
+  120          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 140, J = N, 1, -1
+                  TEMP = X( J )
+                  DO 130, I = N, J + 1, -1
+                     TEMP = TEMP - A( I, J )*X( I )
+  130             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( J, J )
+                  X( J ) = TEMP
+  140          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 160, J = N, 1, -1
+                  TEMP = X( JX )
+                  IX   = KX
+                  DO 150, I = N, J + 1, -1
+                     TEMP = TEMP - A( I, J )*X( IX )
+                     IX   = IX   - INCX
+  150             CONTINUE
+                  IF( NOUNIT )
+     $               TEMP = TEMP/A( J, J )
+                  X( JX ) = TEMP
+                  JX      = JX   - INCX
+  160          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRSV .
+*
+      END
diff --git a/libcruft/blas/dzasum.f b/libcruft/blas/dzasum.f
new file mode 100644
index 0000000..d21c1ff
--- /dev/null
+++ b/libcruft/blas/dzasum.f
@@ -0,0 +1,34 @@
+      double precision function dzasum(n,zx,incx)
+c
+c     takes the sum of the absolute values.
+c     jack dongarra, 3/11/78.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*)
+      double precision stemp,dcabs1
+      integer i,incx,ix,n
+c
+      dzasum = 0.0d0
+      stemp = 0.0d0
+      if( n.le.0 .or. incx.le.0 )return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      ix = 1
+      do 10 i = 1,n
+        stemp = stemp + dcabs1(zx(ix))
+        ix = ix + incx
+   10 continue
+      dzasum = stemp
+      return
+c
+c        code for increment equal to 1
+c
+   20 do 30 i = 1,n
+        stemp = stemp + dcabs1(zx(i))
+   30 continue
+      dzasum = stemp
+      return
+      end
diff --git a/libcruft/blas/dznrm2.f b/libcruft/blas/dznrm2.f
new file mode 100644
index 0000000..205ce39
--- /dev/null
+++ b/libcruft/blas/dznrm2.f
@@ -0,0 +1,67 @@
+      DOUBLE PRECISION FUNCTION DZNRM2( N, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER                           INCX, N
+*     .. Array Arguments ..
+      COMPLEX*16                        X( * )
+*     ..
+*
+*  DZNRM2 returns the euclidean norm of a vector via the function
+*  name, so that
+*
+*     DZNRM2 := sqrt( conjg( x' )*x )
+*
+*
+*
+*  -- This version written on 25-October-1982.
+*     Modified on 14-October-1993 to inline the call to ZLASSQ.
+*     Sven Hammarling, Nag Ltd.
+*
+*
+*     .. Parameters ..
+      DOUBLE PRECISION      ONE         , ZERO
+      PARAMETER           ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     .. Local Scalars ..
+      INTEGER               IX
+      DOUBLE PRECISION      NORM, SCALE, SSQ, TEMP
+*     .. Intrinsic Functions ..
+      INTRINSIC             ABS, DIMAG, DBLE, SQRT
+*     ..
+*     .. Executable Statements ..
+      IF( N.LT.1 .OR. INCX.LT.1 )THEN
+         NORM  = ZERO
+      ELSE
+         SCALE = ZERO
+         SSQ   = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL ZLASSQ( N, X, INCX, SCALE, SSQ )
+*
+         DO 10, IX = 1, 1 + ( N - 1 )*INCX, INCX
+            IF( DBLE( X( IX ) ).NE.ZERO )THEN
+               TEMP = ABS( DBLE( X( IX ) ) )
+               IF( SCALE.LT.TEMP )THEN
+                  SSQ   = ONE   + SSQ*( SCALE/TEMP )**2
+                  SCALE = TEMP
+               ELSE
+                  SSQ   = SSQ   +     ( TEMP/SCALE )**2
+               END IF
+            END IF
+            IF( DIMAG( X( IX ) ).NE.ZERO )THEN
+               TEMP = ABS( DIMAG( X( IX ) ) )
+               IF( SCALE.LT.TEMP )THEN
+                  SSQ   = ONE   + SSQ*( SCALE/TEMP )**2
+                  SCALE = TEMP
+               ELSE
+                  SSQ   = SSQ   +     ( TEMP/SCALE )**2
+               END IF
+            END IF
+   10    CONTINUE
+         NORM  = SCALE * SQRT( SSQ )
+      END IF
+*
+      DZNRM2 = NORM
+      RETURN
+*
+*     End of DZNRM2.
+*
+      END
diff --git a/libcruft/blas/icamax.f b/libcruft/blas/icamax.f
new file mode 100644
index 0000000..9a6afc1
--- /dev/null
+++ b/libcruft/blas/icamax.f
@@ -0,0 +1,54 @@
+      INTEGER FUNCTION ICAMAX(N,CX,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     finds the index of element having max. absolute value.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      REAL SMAX
+      INTEGER I,IX
+*     ..
+*     .. External Functions ..
+      REAL SCABS1
+      EXTERNAL SCABS1
+*     ..
+      ICAMAX = 0
+      IF (N.LT.1 .OR. INCX.LE.0) RETURN
+      ICAMAX = 1
+      IF (N.EQ.1) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      IX = 1
+      SMAX = SCABS1(CX(1))
+      IX = IX + INCX
+      DO 10 I = 2,N
+          IF (SCABS1(CX(IX)).LE.SMAX) GO TO 5
+          ICAMAX = I
+          SMAX = SCABS1(CX(IX))
+    5     IX = IX + INCX
+   10 CONTINUE
+      RETURN
+*
+*        code for increment equal to 1
+*
+   20 SMAX = SCABS1(CX(1))
+      DO 30 I = 2,N
+          IF (SCABS1(CX(I)).LE.SMAX) GO TO 30
+          ICAMAX = I
+          SMAX = SCABS1(CX(I))
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/idamax.f b/libcruft/blas/idamax.f
new file mode 100644
index 0000000..59d80dc
--- /dev/null
+++ b/libcruft/blas/idamax.f
@@ -0,0 +1,39 @@
+      integer function idamax(n,dx,incx)
+c
+c     finds the index of element having max. absolute value.
+c     jack dongarra, linpack, 3/11/78.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double precision dx(*),dmax
+      integer i,incx,ix,n
+c
+      idamax = 0
+      if( n.lt.1 .or. incx.le.0 ) return
+      idamax = 1
+      if(n.eq.1)return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      ix = 1
+      dmax = dabs(dx(1))
+      ix = ix + incx
+      do 10 i = 2,n
+         if(dabs(dx(ix)).le.dmax) go to 5
+         idamax = i
+         dmax = dabs(dx(ix))
+    5    ix = ix + incx
+   10 continue
+      return
+c
+c        code for increment equal to 1
+c
+   20 dmax = dabs(dx(1))
+      do 30 i = 2,n
+         if(dabs(dx(i)).le.dmax) go to 30
+         idamax = i
+         dmax = dabs(dx(i))
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/isamax.f b/libcruft/blas/isamax.f
new file mode 100644
index 0000000..f6fd312
--- /dev/null
+++ b/libcruft/blas/isamax.f
@@ -0,0 +1,53 @@
+      INTEGER FUNCTION ISAMAX(N,SX,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     finds the index of element having max. absolute value.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      REAL SMAX
+      INTEGER I,IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS
+*     ..
+      ISAMAX = 0
+      IF (N.LT.1 .OR. INCX.LE.0) RETURN
+      ISAMAX = 1
+      IF (N.EQ.1) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      IX = 1
+      SMAX = ABS(SX(1))
+      IX = IX + INCX
+      DO 10 I = 2,N
+          IF (ABS(SX(IX)).LE.SMAX) GO TO 5
+          ISAMAX = I
+          SMAX = ABS(SX(IX))
+    5     IX = IX + INCX
+   10 CONTINUE
+      RETURN
+*
+*        code for increment equal to 1
+*
+   20 SMAX = ABS(SX(1))
+      DO 30 I = 2,N
+          IF (ABS(SX(I)).LE.SMAX) GO TO 30
+          ISAMAX = I
+          SMAX = ABS(SX(I))
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/izamax.f b/libcruft/blas/izamax.f
new file mode 100644
index 0000000..ec14f82
--- /dev/null
+++ b/libcruft/blas/izamax.f
@@ -0,0 +1,41 @@
+      integer function izamax(n,zx,incx)
+c
+c     finds the index of element having max. absolute value.
+c     jack dongarra, 1/15/85.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*)
+      double precision smax
+      integer i,incx,ix,n
+      double precision dcabs1
+c
+      izamax = 0
+      if( n.lt.1 .or. incx.le.0 )return
+      izamax = 1
+      if(n.eq.1)return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      ix = 1
+      smax = dcabs1(zx(1))
+      ix = ix + incx
+      do 10 i = 2,n
+         if(dcabs1(zx(ix)).le.smax) go to 5
+         izamax = i
+         smax = dcabs1(zx(ix))
+    5    ix = ix + incx
+   10 continue
+      return
+c
+c        code for increment equal to 1
+c
+   20 smax = dcabs1(zx(1))
+      do 30 i = 2,n
+         if(dcabs1(zx(i)).le.smax) go to 30
+         izamax = i
+         smax = dcabs1(zx(i))
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/lsame.f b/libcruft/blas/lsame.f
new file mode 100644
index 0000000..f895174
--- /dev/null
+++ b/libcruft/blas/lsame.f
@@ -0,0 +1,87 @@
+      LOGICAL          FUNCTION LSAME( CA, CB )
+*
+*  -- LAPACK auxiliary routine (version 2.0) --
+*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+*     Courant Institute, Argonne National Lab, and Rice University
+*     January 31, 1994
+*
+*     .. Scalar Arguments ..
+      CHARACTER          CA, CB
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  LSAME returns .TRUE. if CA is the same letter as CB regardless of
+*  case.
+*
+*  Arguments
+*  =========
+*
+*  CA      (input) CHARACTER*1
+*  CB      (input) CHARACTER*1
+*          CA and CB specify the single characters to be compared.
+*
+* =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC          ICHAR
+*     ..
+*     .. Local Scalars ..
+      INTEGER            INTA, INTB, ZCODE
+*     ..
+*     .. Executable Statements ..
+*
+*     Test if the characters are equal
+*
+      LSAME = CA.EQ.CB
+      IF( LSAME )
+     $   RETURN
+*
+*     Now test for equivalence if both characters are alphabetic.
+*
+      ZCODE = ICHAR( 'Z' )
+*
+*     Use 'Z' rather than 'A' so that ASCII can be detected on Prime
+*     machines, on which ICHAR returns a value with bit 8 set.
+*     ICHAR('A') on Prime machines returns 193 which is the same as
+*     ICHAR('A') on an EBCDIC machine.
+*
+      INTA = ICHAR( CA )
+      INTB = ICHAR( CB )
+*
+      IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN
+*
+*        ASCII is assumed - ZCODE is the ASCII code of either lower or
+*        upper case 'Z'.
+*
+         IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32
+         IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32
+*
+      ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN
+*
+*        EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or
+*        upper case 'Z'.
+*
+         IF( INTA.GE.129 .AND. INTA.LE.137 .OR.
+     $       INTA.GE.145 .AND. INTA.LE.153 .OR.
+     $       INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64
+         IF( INTB.GE.129 .AND. INTB.LE.137 .OR.
+     $       INTB.GE.145 .AND. INTB.LE.153 .OR.
+     $       INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64
+*
+      ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN
+*
+*        ASCII is assumed, on Prime machines - ZCODE is the ASCII code
+*        plus 128 of either lower or upper case 'Z'.
+*
+         IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32
+         IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32
+      END IF
+      LSAME = INTA.EQ.INTB
+*
+*     RETURN
+*
+*     End of LSAME
+*
+      END
diff --git a/libcruft/blas/sasum.f b/libcruft/blas/sasum.f
new file mode 100644
index 0000000..0677ba4
--- /dev/null
+++ b/libcruft/blas/sasum.f
@@ -0,0 +1,59 @@
+      REAL FUNCTION SASUM(N,SX,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     takes the sum of the absolute values.
+*     uses unrolled loops for increment equal to one.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,M,MP1,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,MOD
+*     ..
+      SASUM = 0.0e0
+      STEMP = 0.0e0
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1,NINCX,INCX
+          STEMP = STEMP + ABS(SX(I))
+   10 CONTINUE
+      SASUM = STEMP
+      RETURN
+*
+*        code for increment equal to 1
+*
+*
+*        clean-up loop
+*
+   20 M = MOD(N,6)
+      IF (M.EQ.0) GO TO 40
+      DO 30 I = 1,M
+          STEMP = STEMP + ABS(SX(I))
+   30 CONTINUE
+      IF (N.LT.6) GO TO 60
+   40 MP1 = M + 1
+      DO 50 I = MP1,N,6
+          STEMP = STEMP + ABS(SX(I)) + ABS(SX(I+1)) + ABS(SX(I+2)) +
+     +            ABS(SX(I+3)) + ABS(SX(I+4)) + ABS(SX(I+5))
+   50 CONTINUE
+   60 SASUM = STEMP
+      RETURN
+      END
diff --git a/libcruft/blas/saxpy.f b/libcruft/blas/saxpy.f
new file mode 100644
index 0000000..6241a71
--- /dev/null
+++ b/libcruft/blas/saxpy.f
@@ -0,0 +1,62 @@
+      SUBROUTINE SAXPY(N,SA,SX,INCX,SY,INCY)
+*     .. Scalar Arguments ..
+      REAL SA
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     SAXPY constant times a vector plus a vector.
+*     uses unrolled loop for increments equal to one.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (SA.EQ.0.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          SY(IY) = SY(IY) + SA*SX(IX)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+   20 M = MOD(N,4)
+      IF (M.EQ.0) GO TO 40
+      DO 30 I = 1,M
+          SY(I) = SY(I) + SA*SX(I)
+   30 CONTINUE
+      IF (N.LT.4) RETURN
+   40 MP1 = M + 1
+      DO 50 I = MP1,N,4
+          SY(I) = SY(I) + SA*SX(I)
+          SY(I+1) = SY(I+1) + SA*SX(I+1)
+          SY(I+2) = SY(I+2) + SA*SX(I+2)
+          SY(I+3) = SY(I+3) + SA*SX(I+3)
+   50 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/scabs1.f b/libcruft/blas/scabs1.f
new file mode 100644
index 0000000..ce6b63f
--- /dev/null
+++ b/libcruft/blas/scabs1.f
@@ -0,0 +1,16 @@
+      REAL FUNCTION SCABS1(Z)
+*     .. Scalar Arguments ..
+      COMPLEX Z
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SCABS1 computes absolute value of a complex number
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,AIMAG,REAL
+*     ..
+      SCABS1 = ABS(REAL(Z)) + ABS(AIMAG(Z))
+      RETURN
+      END
diff --git a/libcruft/blas/scasum.f b/libcruft/blas/scasum.f
new file mode 100644
index 0000000..5a4abfa
--- /dev/null
+++ b/libcruft/blas/scasum.f
@@ -0,0 +1,47 @@
+      REAL FUNCTION SCASUM(N,CX,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     takes the sum of the absolute values of a complex vector and
+*     returns a single precision result.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,AIMAG,REAL
+*     ..
+      SCASUM = 0.0e0
+      STEMP = 0.0e0
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1,NINCX,INCX
+          STEMP = STEMP + ABS(REAL(CX(I))) + ABS(AIMAG(CX(I)))
+   10 CONTINUE
+      SCASUM = STEMP
+      RETURN
+*
+*        code for increment equal to 1
+*
+   20 DO 30 I = 1,N
+          STEMP = STEMP + ABS(REAL(CX(I))) + ABS(AIMAG(CX(I)))
+   30 CONTINUE
+      SCASUM = STEMP
+      RETURN
+      END
diff --git a/libcruft/blas/scnrm2.f b/libcruft/blas/scnrm2.f
new file mode 100644
index 0000000..160e2c4
--- /dev/null
+++ b/libcruft/blas/scnrm2.f
@@ -0,0 +1,72 @@
+      REAL FUNCTION SCNRM2(N,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SCNRM2 returns the euclidean norm of a vector via the function
+*  name, so that
+*
+*     SCNRM2 := sqrt( conjg( x' )*x )
+*
+*
+*
+*  -- This version written on 25-October-1982.
+*     Modified on 14-October-1993 to inline the call to CLASSQ.
+*     Sven Hammarling, Nag Ltd.
+*
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL NORM,SCALE,SSQ,TEMP
+      INTEGER IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,AIMAG,REAL,SQRT
+*     ..
+      IF (N.LT.1 .OR. INCX.LT.1) THEN
+          NORM = ZERO
+      ELSE
+          SCALE = ZERO
+          SSQ = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL CLASSQ( N, X, INCX, SCALE, SSQ )
+*
+          DO 10 IX = 1,1 + (N-1)*INCX,INCX
+              IF (REAL(X(IX)).NE.ZERO) THEN
+                  TEMP = ABS(REAL(X(IX)))
+                  IF (SCALE.LT.TEMP) THEN
+                      SSQ = ONE + SSQ* (SCALE/TEMP)**2
+                      SCALE = TEMP
+                  ELSE
+                      SSQ = SSQ + (TEMP/SCALE)**2
+                  END IF
+              END IF
+              IF (AIMAG(X(IX)).NE.ZERO) THEN
+                  TEMP = ABS(AIMAG(X(IX)))
+                  IF (SCALE.LT.TEMP) THEN
+                      SSQ = ONE + SSQ* (SCALE/TEMP)**2
+                      SCALE = TEMP
+                  ELSE
+                      SSQ = SSQ + (TEMP/SCALE)**2
+                  END IF
+              END IF
+   10     CONTINUE
+          NORM = SCALE*SQRT(SSQ)
+      END IF
+*
+      SCNRM2 = NORM
+      RETURN
+*
+*     End of SCNRM2.
+*
+      END
diff --git a/libcruft/blas/scopy.f b/libcruft/blas/scopy.f
new file mode 100644
index 0000000..ad04ee6
--- /dev/null
+++ b/libcruft/blas/scopy.f
@@ -0,0 +1,63 @@
+      SUBROUTINE SCOPY(N,SX,INCX,SY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     copies a vector, x, to a vector, y.
+*     uses unrolled loops for increments equal to 1.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          SY(IY) = SX(IX)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+   20 M = MOD(N,7)
+      IF (M.EQ.0) GO TO 40
+      DO 30 I = 1,M
+          SY(I) = SX(I)
+   30 CONTINUE
+      IF (N.LT.7) RETURN
+   40 MP1 = M + 1
+      DO 50 I = MP1,N,7
+          SY(I) = SX(I)
+          SY(I+1) = SX(I+1)
+          SY(I+2) = SX(I+2)
+          SY(I+3) = SX(I+3)
+          SY(I+4) = SX(I+4)
+          SY(I+5) = SX(I+5)
+          SY(I+6) = SX(I+6)
+   50 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/sdot.f b/libcruft/blas/sdot.f
new file mode 100644
index 0000000..deebc34
--- /dev/null
+++ b/libcruft/blas/sdot.f
@@ -0,0 +1,64 @@
+      REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     forms the dot product of two vectors.
+*     uses unrolled loops for increments equal to one.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      STEMP = 0.0e0
+      SDOT = 0.0e0
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          STEMP = STEMP + SX(IX)*SY(IY)
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      SDOT = STEMP
+      RETURN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+   20 M = MOD(N,5)
+      IF (M.EQ.0) GO TO 40
+      DO 30 I = 1,M
+          STEMP = STEMP + SX(I)*SY(I)
+   30 CONTINUE
+      IF (N.LT.5) GO TO 60
+   40 MP1 = M + 1
+      DO 50 I = MP1,N,5
+          STEMP = STEMP + SX(I)*SY(I) + SX(I+1)*SY(I+1) +
+     +            SX(I+2)*SY(I+2) + SX(I+3)*SY(I+3) + SX(I+4)*SY(I+4)
+   50 CONTINUE
+   60 SDOT = STEMP
+      RETURN
+      END
diff --git a/libcruft/blas/sgemm.f b/libcruft/blas/sgemm.f
new file mode 100644
index 0000000..06e33c0
--- /dev/null
+++ b/libcruft/blas/sgemm.f
@@ -0,0 +1,313 @@
+      SUBROUTINE SGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,M,N
+      CHARACTER TRANSA,TRANSB
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*op( A )*op( B ) + beta*C,
+*
+*  where  op( X ) is one of
+*
+*     op( X ) = X   or   op( X ) = X',
+*
+*  alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*  an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n',  op( A ) = A.
+*
+*              TRANSA = 'T' or 't',  op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c',  op( A ) = A'.
+*
+*           Unchanged on exit.
+*
+*  TRANSB - CHARACTER*1.
+*           On entry, TRANSB specifies the form of op( B ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSB = 'N' or 'n',  op( B ) = B.
+*
+*              TRANSB = 'T' or 't',  op( B ) = B'.
+*
+*              TRANSB = 'C' or 'c',  op( B ) = B'.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies  the number  of rows  of the  matrix
+*           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N  specifies the number  of columns of the matrix
+*           op( B ) and the number of columns of the matrix C. N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry,  K  specifies  the number of columns of the matrix
+*           op( A ) and the number of rows of the matrix op( B ). K must
+*           be at least  zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by m  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - REAL             array of DIMENSION ( LDB, kb ), where kb is
+*           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  n by k  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*           least  max( 1, n ).
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - REAL             array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n  matrix
+*           ( alpha*op( A )*op( B ) + beta*C ).
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
+      LOGICAL NOTA,NOTB
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     transposed and set  NROWA, NCOLA and  NROWB  as the number of rows
+*     and  columns of  A  and the  number of  rows  of  B  respectively.
+*
+      NOTA = LSAME(TRANSA,'N')
+      NOTB = LSAME(TRANSB,'N')
+      IF (NOTA) THEN
+          NROWA = M
+          NCOLA = K
+      ELSE
+          NROWA = K
+          NCOLA = M
+      END IF
+      IF (NOTB) THEN
+          NROWB = K
+      ELSE
+          NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.NOTA) .AND. (.NOT.LSAME(TRANSA,'C')) .AND.
+     +    (.NOT.LSAME(TRANSA,'T'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.NOTB) .AND. (.NOT.LSAME(TRANSB,'C')) .AND.
+     +         (.NOT.LSAME(TRANSB,'T'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 8
+      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
+          INFO = 10
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And if  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (NOTB) THEN
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+              DO 90 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 50 I = 1,M
+                          C(I,J) = ZERO
+   50                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 60 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+   60                 CONTINUE
+                  END IF
+                  DO 80 L = 1,K
+                      IF (B(L,J).NE.ZERO) THEN
+                          TEMP = ALPHA*B(L,J)
+                          DO 70 I = 1,M
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+   70                     CONTINUE
+                      END IF
+   80             CONTINUE
+   90         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A'*B + beta*C
+*
+              DO 120 J = 1,N
+                  DO 110 I = 1,M
+                      TEMP = ZERO
+                      DO 100 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(L,J)
+  100                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  110             CONTINUE
+  120         CONTINUE
+          END IF
+      ELSE
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B' + beta*C
+*
+              DO 170 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 130 I = 1,M
+                          C(I,J) = ZERO
+  130                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 140 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  140                 CONTINUE
+                  END IF
+                  DO 160 L = 1,K
+                      IF (B(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*B(J,L)
+                          DO 150 I = 1,M
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  150                     CONTINUE
+                      END IF
+  160             CONTINUE
+  170         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A'*B' + beta*C
+*
+              DO 200 J = 1,N
+                  DO 190 I = 1,M
+                      TEMP = ZERO
+                      DO 180 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(J,L)
+  180                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  190             CONTINUE
+  200         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SGEMM .
+*
+      END
diff --git a/libcruft/blas/sgemv.f b/libcruft/blas/sgemv.f
new file mode 100644
index 0000000..494cfc9
--- /dev/null
+++ b/libcruft/blas/sgemv.f
@@ -0,0 +1,261 @@
+      SUBROUTINE SGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEMV  performs one of the matrix-vector operations
+*
+*     y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are vectors and A is an
+*  m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*
+*              TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.
+*
+*              TRANS = 'C' or 'c'   y := alpha*A'*x + beta*y.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  X      - REAL             array of DIMENSION at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*           Before entry, the incremented array X must contain the
+*           vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - REAL             array of DIMENSION at least
+*           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*           Before entry with BETA non-zero, the incremented array Y
+*           must contain the vector y. On exit, Y is overwritten by the
+*           updated vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      DO 50 I = 1,M
+                          Y(I) = Y(I) + TEMP*A(I,J)
+   50                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IY = KY
+                      DO 70 I = 1,M
+                          Y(IY) = Y(IY) + TEMP*A(I,J)
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A'*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 100 J = 1,N
+                  TEMP = ZERO
+                  DO 90 I = 1,M
+                      TEMP = TEMP + A(I,J)*X(I)
+   90             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  100         CONTINUE
+          ELSE
+              DO 120 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  DO 110 I = 1,M
+                      TEMP = TEMP + A(I,J)*X(IX)
+                      IX = IX + INCX
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SGEMV .
+*
+      END
diff --git a/libcruft/blas/sger.f b/libcruft/blas/sger.f
new file mode 100644
index 0000000..5f94cf6
--- /dev/null
+++ b/libcruft/blas/sger.f
@@ -0,0 +1,159 @@
+      SUBROUTINE SGER(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGER   performs the rank 1 operation
+*
+*     A := alpha*x*y' + A,
+*
+*  where alpha is a scalar, x is an m element vector, y is an n element
+*  vector and A is an m by n matrix.
+*
+*  Arguments
+*  ==========
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the m
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients. On exit, A is
+*           overwritten by the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGER  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SGER  .
+*
+      END
diff --git a/libcruft/blas/smach.f b/libcruft/blas/smach.f
new file mode 100644
index 0000000..387e44d
--- /dev/null
+++ b/libcruft/blas/smach.f
@@ -0,0 +1,59 @@
+      real function smach(job)
+      integer job
+c
+c     smach computes machine parameters of floating point
+c     arithmetic for use in testing only.  not required by
+c     linpack proper.
+c
+c     if trouble with automatic computation of these quantities,
+c     they can be set by direct assignment statements.
+c     assume the computer has
+c
+c        b = base of arithmetic
+c        t = number of base  b  digits
+c        l = smallest possible exponent
+c        u = largest possible exponent
+c
+c     then
+c
+c        eps = b**(1-t)
+c        tiny = 100.0*b**(-l+t)
+c        huge = 0.01*b**(u-t)
+c
+c     dmach same as smach except t, l, u apply to
+c     double precision.
+c
+c     cmach same as smach except if complex division
+c     is done by
+c
+c        1/(x+i*y) = (x-i*y)/(x**2+y**2)
+c
+c     then
+c
+c        tiny = sqrt(tiny)
+c        huge = sqrt(huge)
+c
+c
+c     job is 1, 2 or 3 for epsilon, tiny and huge, respectively.
+c
+c
+      real eps,tiny,huge,s
+c
+      eps = 1.0
+   10 eps = eps/2.0
+      s = 1.0 + eps
+      if (s .gt. 1.0) go to 10
+      eps = 2.0*eps
+c
+      s = 1.0
+   20 tiny = s
+      s = s/16.0
+      if (s*100. .ne. 0.0) go to 20
+      tiny = (tiny/eps)*100.0
+      huge = 1.0/tiny
+c
+      if (job .eq. 1) smach = eps
+      if (job .eq. 2) smach = tiny
+      if (job .eq. 3) smach = huge
+      return
+      end
diff --git a/libcruft/blas/snrm2.f b/libcruft/blas/snrm2.f
new file mode 100644
index 0000000..fa54ba1
--- /dev/null
+++ b/libcruft/blas/snrm2.f
@@ -0,0 +1,66 @@
+      REAL FUNCTION SNRM2(N,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SNRM2 returns the euclidean norm of a vector via the function
+*  name, so that
+*
+*     SNRM2 := sqrt( x'*x ).
+*
+*  Further Details
+*  ===============
+*
+*  -- This version written on 25-October-1982.
+*     Modified on 14-October-1993 to inline the call to SLASSQ.
+*     Sven Hammarling, Nag Ltd.
+*
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL ABSXI,NORM,SCALE,SSQ
+      INTEGER IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,SQRT
+*     ..
+      IF (N.LT.1 .OR. INCX.LT.1) THEN
+          NORM = ZERO
+      ELSE IF (N.EQ.1) THEN
+          NORM = ABS(X(1))
+      ELSE
+          SCALE = ZERO
+          SSQ = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL SLASSQ( N, X, INCX, SCALE, SSQ )
+*
+          DO 10 IX = 1,1 + (N-1)*INCX,INCX
+              IF (X(IX).NE.ZERO) THEN
+                  ABSXI = ABS(X(IX))
+                  IF (SCALE.LT.ABSXI) THEN
+                      SSQ = ONE + SSQ* (SCALE/ABSXI)**2
+                      SCALE = ABSXI
+                  ELSE
+                      SSQ = SSQ + (ABSXI/SCALE)**2
+                  END IF
+              END IF
+   10     CONTINUE
+          NORM = SCALE*SQRT(SSQ)
+      END IF
+*
+      SNRM2 = NORM
+      RETURN
+*
+*     End of SNRM2.
+*
+      END
diff --git a/libcruft/blas/srot.f b/libcruft/blas/srot.f
new file mode 100644
index 0000000..e9f1cf7
--- /dev/null
+++ b/libcruft/blas/srot.f
@@ -0,0 +1,54 @@
+      SUBROUTINE SROT(N,SX,INCX,SY,INCY,C,S)
+*     .. Scalar Arguments ..
+      REAL C,S
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     applies a plane rotation.
+*
+*  Further Details
+*  ===============
+*
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          STEMP = C*SX(IX) + S*SY(IY)
+          SY(IY) = C*SY(IY) - S*SX(IX)
+          SX(IX) = STEMP
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*       code for both increments equal to 1
+*
+   20 DO 30 I = 1,N
+          STEMP = C*SX(I) + S*SY(I)
+          SY(I) = C*SY(I) - S*SX(I)
+          SX(I) = STEMP
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/sscal.f b/libcruft/blas/sscal.f
new file mode 100644
index 0000000..b900be9
--- /dev/null
+++ b/libcruft/blas/sscal.f
@@ -0,0 +1,57 @@
+      SUBROUTINE SSCAL(N,SA,SX,INCX)
+*     .. Scalar Arguments ..
+      REAL SA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     scales a vector by a constant.
+*     uses unrolled loops for increment equal to 1.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 3/93 to return if incx .le. 0.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      INTEGER I,M,MP1,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) GO TO 20
+*
+*        code for increment not equal to 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1,NINCX,INCX
+          SX(I) = SA*SX(I)
+   10 CONTINUE
+      RETURN
+*
+*        code for increment equal to 1
+*
+*
+*        clean-up loop
+*
+   20 M = MOD(N,5)
+      IF (M.EQ.0) GO TO 40
+      DO 30 I = 1,M
+          SX(I) = SA*SX(I)
+   30 CONTINUE
+      IF (N.LT.5) RETURN
+   40 MP1 = M + 1
+      DO 50 I = MP1,N,5
+          SX(I) = SA*SX(I)
+          SX(I+1) = SA*SX(I+1)
+          SX(I+2) = SA*SX(I+2)
+          SX(I+3) = SA*SX(I+3)
+          SX(I+4) = SA*SX(I+4)
+   50 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/sswap.f b/libcruft/blas/sswap.f
new file mode 100644
index 0000000..e23f380
--- /dev/null
+++ b/libcruft/blas/sswap.f
@@ -0,0 +1,70 @@
+      SUBROUTINE SSWAP(N,SX,INCX,SY,INCY)
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*     interchanges two vectors.
+*     uses unrolled loops for increments equal to 1.
+*     jack dongarra, linpack, 3/11/78.
+*     modified 12/3/93, array(1) declarations changed to array(*)
+*
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) GO TO 20
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+      IX = 1
+      IY = 1
+      IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+      IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+      DO 10 I = 1,N
+          STEMP = SX(IX)
+          SX(IX) = SY(IY)
+          SY(IY) = STEMP
+          IX = IX + INCX
+          IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*       code for both increments equal to 1
+*
+*
+*       clean-up loop
+*
+   20 M = MOD(N,3)
+      IF (M.EQ.0) GO TO 40
+      DO 30 I = 1,M
+          STEMP = SX(I)
+          SX(I) = SY(I)
+          SY(I) = STEMP
+   30 CONTINUE
+      IF (N.LT.3) RETURN
+   40 MP1 = M + 1
+      DO 50 I = MP1,N,3
+          STEMP = SX(I)
+          SX(I) = SY(I)
+          SY(I) = STEMP
+          STEMP = SX(I+1)
+          SX(I+1) = SY(I+1)
+          SY(I+1) = STEMP
+          STEMP = SX(I+2)
+          SX(I+2) = SY(I+2)
+          SY(I+2) = STEMP
+   50 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/blas/ssymm.f b/libcruft/blas/ssymm.f
new file mode 100644
index 0000000..344cd35
--- /dev/null
+++ b/libcruft/blas/ssymm.f
@@ -0,0 +1,294 @@
+      SUBROUTINE SSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*A*B + beta*C,
+*
+*  or
+*
+*     C := alpha*B*A + beta*C,
+*
+*  where alpha and beta are scalars,  A is a symmetric matrix and  B and
+*  C are  m by n matrices.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE  specifies whether  the  symmetric matrix  A
+*           appears on the  left or right  in the  operation as follows:
+*
+*              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*
+*              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of  the  symmetric  matrix   A  is  to  be
+*           referenced as follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*                                  symmetric matrix is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*                                  symmetric matrix is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies the number of rows of the matrix  C.
+*           M  must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix C.
+*           N  must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, ka ), where ka is
+*           m  when  SIDE = 'L' or 'l'  and is  n otherwise.
+*           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*           the array  A  must contain the  symmetric matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  symmetric matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  m by m  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  symmetric
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*           the array  A  must contain the  symmetric matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  symmetric matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  n by n  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  symmetric
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least  max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - REAL             array of DIMENSION ( LDB, n ).
+*           Before entry, the leading  m by n part of the array  B  must
+*           contain the matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - REAL             array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n updated
+*           matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*A(J,J)
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*A(J,K)
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(J,K)
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SSYMM .
+*
+      END
diff --git a/libcruft/blas/ssymv.f b/libcruft/blas/ssymv.f
new file mode 100644
index 0000000..2b9bedd
--- /dev/null
+++ b/libcruft/blas/ssymv.f
@@ -0,0 +1,262 @@
+      SUBROUTINE SSYMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYMV  performs the matrix-vector  operation
+*
+*     y := alpha*A*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are n element vectors and
+*  A is an n by n symmetric matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the symmetric matrix and the strictly
+*           lower triangular part of A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the symmetric matrix and the strictly
+*           upper triangular part of A is not referenced.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y. On exit, Y is overwritten by the updated
+*           vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 5
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*A(J,J) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 I = 1,J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*A(J,J) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*A(J,J)
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*A(J,J)
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,N
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYMV .
+*
+      END
diff --git a/libcruft/blas/ssyr.f b/libcruft/blas/ssyr.f
new file mode 100644
index 0000000..aea091b
--- /dev/null
+++ b/libcruft/blas/ssyr.f
@@ -0,0 +1,199 @@
+      SUBROUTINE SSYR(UPLO,N,ALPHA,X,INCX,A,LDA)
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYR   performs the symmetric rank 1 operation
+*
+*     A := alpha*x*x' + A,
+*
+*  where alpha is a real scalar, x is an n element vector and A is an
+*  n by n symmetric matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the symmetric matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the symmetric matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      DO 10 I = 1,J
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   10                 CONTINUE
+                  END IF
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = KX
+                      DO 30 I = 1,J
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      DO 50 I = J,N
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   50                 CONTINUE
+                  END IF
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = JX
+                      DO 70 I = J,N
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYR  .
+*
+      END
diff --git a/libcruft/blas/ssyr2.f b/libcruft/blas/ssyr2.f
new file mode 100644
index 0000000..4e4fcaa
--- /dev/null
+++ b/libcruft/blas/ssyr2.f
@@ -0,0 +1,230 @@
+      SUBROUTINE SSYR2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYR2  performs the symmetric rank 2 operation
+*
+*     A := alpha*x*y' + alpha*y*x' + A,
+*
+*  where alpha is a scalar, x and y are n element vectors and A is an n
+*  by n symmetric matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the symmetric matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the symmetric matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      DO 10 I = 1,J
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   10                 CONTINUE
+                  END IF
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = KX
+                      IY = KY
+                      DO 30 I = 1,J
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      DO 50 I = J,N
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   50                 CONTINUE
+                  END IF
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = JX
+                      IY = JY
+                      DO 70 I = J,N
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYR2 .
+*
+      END
diff --git a/libcruft/blas/ssyr2k.f b/libcruft/blas/ssyr2k.f
new file mode 100644
index 0000000..cc8acb6
--- /dev/null
+++ b/libcruft/blas/ssyr2k.f
@@ -0,0 +1,326 @@
+      SUBROUTINE SSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYR2K  performs one of the symmetric rank 2k operations
+*
+*     C := alpha*A*B' + alpha*B*A' + beta*C,
+*
+*  or
+*
+*     C := alpha*A'*B + alpha*B'*A + beta*C,
+*
+*  where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*  and  A and B  are  n by k  matrices  in the  first  case  and  k by n
+*  matrices in the second case.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*B' + alpha*B*A' +
+*                                        beta*C.
+*
+*              TRANS = 'T' or 't'   C := alpha*A'*B + alpha*B'*A +
+*                                        beta*C.
+*
+*              TRANS = 'C' or 'c'   C := alpha*A'*B + alpha*B'*A +
+*                                        beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns  of the  matrices  A and B,  and on  entry  with
+*           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*           of rows of the matrices  A and B.  K must be at least  zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - REAL             array of DIMENSION ( LDB, kb ), where kb is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  k by n  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - REAL             array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  symmetric matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  symmetric matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYR2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B' + alpha*B*A' + C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A'*B + alpha*B'*A + C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYR2K.
+*
+      END
diff --git a/libcruft/blas/ssyrk.f b/libcruft/blas/ssyrk.f
new file mode 100644
index 0000000..0565910
--- /dev/null
+++ b/libcruft/blas/ssyrk.f
@@ -0,0 +1,295 @@
+      SUBROUTINE SSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYRK  performs one of the symmetric rank k operations
+*
+*     C := alpha*A*A' + beta*C,
+*
+*  or
+*
+*     C := alpha*A'*A + beta*C,
+*
+*  where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*  and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*  in the second case.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*A' + beta*C.
+*
+*              TRANS = 'T' or 't'   C := alpha*A'*A + beta*C.
+*
+*              TRANS = 'C' or 'c'   C := alpha*A'*A + beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns   of  the   matrix   A,   and  on   entry   with
+*           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*           of rows of the matrix  A.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - REAL            .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - REAL             array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  symmetric matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  symmetric matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A' + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A'*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYRK .
+*
+      END
diff --git a/libcruft/blas/stbsv.f b/libcruft/blas/stbsv.f
new file mode 100644
index 0000000..c98cac7
--- /dev/null
+++ b/libcruft/blas/stbsv.f
@@ -0,0 +1,336 @@
+      SUBROUTINE STBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STBSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*  diagonals.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   A'*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with UPLO = 'U' or 'u', K specifies the number of
+*           super-diagonals of the matrix A.
+*           On entry with UPLO = 'L' or 'l', K specifies the number of
+*           sub-diagonals of the matrix A.
+*           K must satisfy  0 .le. K.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*           by n part of the array A must contain the upper triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row
+*           ( k + 1 ) of the array, the first super-diagonal starting at
+*           position 2 in row k, and so on. The top left k by k triangle
+*           of the array A is not referenced.
+*           The following program segment will transfer an upper
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = K + 1 - J
+*                    DO 10, I = MAX( 1, J - K ), J
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*           by n part of the array A must contain the lower triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row 1 of
+*           the array, the first sub-diagonal starting at position 1 in
+*           row 2, and so on. The bottom right k by k triangle of the
+*           array A is not referenced.
+*           The following program segment will transfer a lower
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = 1 - J
+*                    DO 10, I = J, MIN( N, J + K )
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Note that when DIAG = 'U' or 'u' the elements of the array A
+*           corresponding to the diagonal elements of the matrix are not
+*           referenced, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           ( k + 1 ).
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STBSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(KPLUS1,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,MAX(1,J-K),-1
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 40 J = N,1,-1
+                      KX = KX - INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(KPLUS1,J)
+                          TEMP = X(JX)
+                          DO 30 I = J - 1,MAX(1,J-K),-1
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX - INCX
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          L = 1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(1,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,MIN(N,J+K)
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      KX = KX + INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = 1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(1,J)
+                          TEMP = X(JX)
+                          DO 70 I = J + 1,MIN(N,J+K)
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX + INCX
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A')*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      DO 90 I = MAX(1,J-K),J - 1
+                          TEMP = TEMP - A(L+I,J)*X(I)
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      L = KPLUS1 - J
+                      DO 110 I = MAX(1,J-K),J - 1
+                          TEMP = TEMP - A(L+I,J)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      L = 1 - J
+                      DO 130 I = MIN(N,J+K),J + 1,-1
+                          TEMP = TEMP - A(L+I,J)*X(I)
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      L = 1 - J
+                      DO 150 I = MIN(N,J+K),J + 1,-1
+                          TEMP = TEMP - A(L+I,J)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STBSV .
+*
+      END
diff --git a/libcruft/blas/strmm.f b/libcruft/blas/strmm.f
new file mode 100644
index 0000000..e610743
--- /dev/null
+++ b/libcruft/blas/strmm.f
@@ -0,0 +1,346 @@
+      SUBROUTINE STRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRMM  performs one of the matrix-matrix operations
+*
+*     B := alpha*op( A )*B,   or   B := alpha*B*op( A ),
+*
+*  where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*           the left or right as follows:
+*
+*              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*
+*              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = A'.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - REAL             array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain the matrix  B,  and  on exit  is overwritten  by the
+*           transformed matrix.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*A*B.
+*
+              IF (UPPER) THEN
+                  DO 50 J = 1,N
+                      DO 40 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              DO 30 I = 1,K - 1
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   30                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP*A(K,K)
+                              B(K,J) = TEMP
+                          END IF
+   40                 CONTINUE
+   50             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              B(K,J) = TEMP
+                              IF (NOUNIT) B(K,J) = B(K,J)*A(K,K)
+                              DO 60 I = K + 1,M
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   60                         CONTINUE
+                          END IF
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*A'*B.
+*
+              IF (UPPER) THEN
+                  DO 110 J = 1,N
+                      DO 100 I = M,1,-1
+                          TEMP = B(I,J)
+                          IF (NOUNIT) TEMP = TEMP*A(I,I)
+                          DO 90 K = 1,I - 1
+                              TEMP = TEMP + A(K,I)*B(K,J)
+   90                     CONTINUE
+                          B(I,J) = ALPHA*TEMP
+  100                 CONTINUE
+  110             CONTINUE
+              ELSE
+                  DO 140 J = 1,N
+                      DO 130 I = 1,M
+                          TEMP = B(I,J)
+                          IF (NOUNIT) TEMP = TEMP*A(I,I)
+                          DO 120 K = I + 1,M
+                              TEMP = TEMP + A(K,I)*B(K,J)
+  120                     CONTINUE
+                          B(I,J) = ALPHA*TEMP
+  130                 CONTINUE
+  140             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*A.
+*
+              IF (UPPER) THEN
+                  DO 180 J = N,1,-1
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 150 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  150                 CONTINUE
+                      DO 170 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 160 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  160                         CONTINUE
+                          END IF
+  170                 CONTINUE
+  180             CONTINUE
+              ELSE
+                  DO 220 J = 1,N
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 190 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  190                 CONTINUE
+                      DO 210 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 200 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  200                         CONTINUE
+                          END IF
+  210                 CONTINUE
+  220             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*A'.
+*
+              IF (UPPER) THEN
+                  DO 260 K = 1,N
+                      DO 240 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = ALPHA*A(J,K)
+                              DO 230 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  230                         CONTINUE
+                          END IF
+  240                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(K,K)
+                      IF (TEMP.NE.ONE) THEN
+                          DO 250 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  250                     CONTINUE
+                      END IF
+  260             CONTINUE
+              ELSE
+                  DO 300 K = N,1,-1
+                      DO 280 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = ALPHA*A(J,K)
+                              DO 270 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  270                         CONTINUE
+                          END IF
+  280                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(K,K)
+                      IF (TEMP.NE.ONE) THEN
+                          DO 290 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  290                     CONTINUE
+                      END IF
+  300             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRMM .
+*
+      END
diff --git a/libcruft/blas/strmv.f b/libcruft/blas/strmv.f
new file mode 100644
index 0000000..ea31b5f
--- /dev/null
+++ b/libcruft/blas/strmv.f
@@ -0,0 +1,278 @@
+      SUBROUTINE STRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRMV  performs one of the matrix-vector operations
+*
+*     x := A*x,   or   x := A'*x,
+*
+*  where x is an n element vector and  A is an n by n unit, or non-unit,
+*  upper or lower triangular matrix.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   x := A*x.
+*
+*              TRANS = 'T' or 't'   x := A'*x.
+*
+*              TRANS = 'C' or 'c'   x := A'*x.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x. On exit, X is overwritten with the
+*           tranformed vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*A(I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 I = 1,J - 1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*A(I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 I = N,J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A'*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 90 I = J - 1,1,-1
+                          TEMP = TEMP + A(I,J)*X(I)
+   90                 CONTINUE
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 110 I = J - 1,1,-1
+                          IX = IX - INCX
+                          TEMP = TEMP + A(I,J)*X(IX)
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 130 I = J + 1,N
+                          TEMP = TEMP + A(I,J)*X(I)
+  130                 CONTINUE
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 150 I = J + 1,N
+                          IX = IX + INCX
+                          TEMP = TEMP + A(I,J)*X(IX)
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRMV .
+*
+      END
diff --git a/libcruft/blas/strsm.f b/libcruft/blas/strsm.f
new file mode 100644
index 0000000..0560638
--- /dev/null
+++ b/libcruft/blas/strsm.f
@@ -0,0 +1,373 @@
+      SUBROUTINE STRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRSM  solves one of the matrix equations
+*
+*     op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*
+*  where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'.
+*
+*  The matrix X is overwritten on B.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry, SIDE specifies whether op( A ) appears on the left
+*           or right of X as follows:
+*
+*              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*
+*              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = A'.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - REAL            .
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - REAL             array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*           overwritten by the solution matrix  X.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRSM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+              IF (UPPER) THEN
+                  DO 60 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 30 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   30                     CONTINUE
+                      END IF
+                      DO 50 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 40 I = 1,K - 1
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   40                         CONTINUE
+                          END IF
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 100 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 70 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   70                     CONTINUE
+                      END IF
+                      DO 90 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 80 I = K + 1,M
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   80                         CONTINUE
+                          END IF
+   90                 CONTINUE
+  100             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*inv( A' )*B.
+*
+              IF (UPPER) THEN
+                  DO 130 J = 1,N
+                      DO 120 I = 1,M
+                          TEMP = ALPHA*B(I,J)
+                          DO 110 K = 1,I - 1
+                              TEMP = TEMP - A(K,I)*B(K,J)
+  110                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          B(I,J) = TEMP
+  120                 CONTINUE
+  130             CONTINUE
+              ELSE
+                  DO 160 J = 1,N
+                      DO 150 I = M,1,-1
+                          TEMP = ALPHA*B(I,J)
+                          DO 140 K = I + 1,M
+                              TEMP = TEMP - A(K,I)*B(K,J)
+  140                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          B(I,J) = TEMP
+  150                 CONTINUE
+  160             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+              IF (UPPER) THEN
+                  DO 210 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 170 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  170                     CONTINUE
+                      END IF
+                      DO 190 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 180 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  180                         CONTINUE
+                          END IF
+  190                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 200 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  200                     CONTINUE
+                      END IF
+  210             CONTINUE
+              ELSE
+                  DO 260 J = N,1,-1
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 220 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  220                     CONTINUE
+                      END IF
+                      DO 240 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 230 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  230                         CONTINUE
+                          END IF
+  240                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 250 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  250                     CONTINUE
+                      END IF
+  260             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*inv( A' ).
+*
+              IF (UPPER) THEN
+                  DO 310 K = N,1,-1
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(K,K)
+                          DO 270 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  270                     CONTINUE
+                      END IF
+                      DO 290 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = A(J,K)
+                              DO 280 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  280                         CONTINUE
+                          END IF
+  290                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 300 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  300                     CONTINUE
+                      END IF
+  310             CONTINUE
+              ELSE
+                  DO 360 K = 1,N
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(K,K)
+                          DO 320 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  320                     CONTINUE
+                      END IF
+                      DO 340 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = A(J,K)
+                              DO 330 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  330                         CONTINUE
+                          END IF
+  340                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 350 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  350                     CONTINUE
+                      END IF
+  360             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRSM .
+*
+      END
diff --git a/libcruft/blas/strsv.f b/libcruft/blas/strsv.f
new file mode 100644
index 0000000..026cbc7
--- /dev/null
+++ b/libcruft/blas/strsv.f
@@ -0,0 +1,281 @@
+      SUBROUTINE STRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular matrix.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   A'*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - REAL             array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - REAL             array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*A(I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 I = J - 1,1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*A(I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 I = J + 1,N
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A' )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      DO 90 I = 1,J - 1
+                          TEMP = TEMP - A(I,J)*X(I)
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 110 I = 1,J - 1
+                          TEMP = TEMP - A(I,J)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      DO 130 I = N,J + 1,-1
+                          TEMP = TEMP - A(I,J)*X(I)
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 150 I = N,J + 1,-1
+                          TEMP = TEMP - A(I,J)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRSV .
+*
+      END
diff --git a/libcruft/blas/zaxpy.f b/libcruft/blas/zaxpy.f
new file mode 100644
index 0000000..4fa3b1e
--- /dev/null
+++ b/libcruft/blas/zaxpy.f
@@ -0,0 +1,34 @@
+      subroutine zaxpy(n,za,zx,incx,zy,incy)
+c
+c     constant times a vector plus a vector.
+c     jack dongarra, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*),zy(*),za
+      integer i,incx,incy,ix,iy,n
+      double precision dcabs1
+      if(n.le.0)return
+      if (dcabs1(za) .eq. 0.0d0) return
+      if (incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        zy(iy) = zy(iy) + za*zx(ix)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c        code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        zy(i) = zy(i) + za*zx(i)
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/zcopy.f b/libcruft/blas/zcopy.f
new file mode 100644
index 0000000..9ccfa88
--- /dev/null
+++ b/libcruft/blas/zcopy.f
@@ -0,0 +1,33 @@
+      subroutine  zcopy(n,zx,incx,zy,incy)
+c
+c     copies a vector, x, to a vector, y.
+c     jack dongarra, linpack, 4/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*),zy(*)
+      integer i,incx,incy,ix,iy,n
+c
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        zy(iy) = zx(ix)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c        code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        zy(i) = zx(i)
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/zdotc.f b/libcruft/blas/zdotc.f
new file mode 100644
index 0000000..d6ac685
--- /dev/null
+++ b/libcruft/blas/zdotc.f
@@ -0,0 +1,36 @@
+      double complex function zdotc(n,zx,incx,zy,incy)
+c
+c     forms the dot product of a vector.
+c     jack dongarra, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*),zy(*),ztemp
+      integer i,incx,incy,ix,iy,n
+      ztemp = (0.0d0,0.0d0)
+      zdotc = (0.0d0,0.0d0)
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        ztemp = ztemp + dconjg(zx(ix))*zy(iy)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      zdotc = ztemp
+      return
+c
+c        code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        ztemp = ztemp + dconjg(zx(i))*zy(i)
+   30 continue
+      zdotc = ztemp
+      return
+      end
diff --git a/libcruft/blas/zdotu.f b/libcruft/blas/zdotu.f
new file mode 100644
index 0000000..329e988
--- /dev/null
+++ b/libcruft/blas/zdotu.f
@@ -0,0 +1,36 @@
+      double complex function zdotu(n,zx,incx,zy,incy)
+c
+c     forms the dot product of two vectors.
+c     jack dongarra, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*),zy(*),ztemp
+      integer i,incx,incy,ix,iy,n
+      ztemp = (0.0d0,0.0d0)
+      zdotu = (0.0d0,0.0d0)
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        ztemp = ztemp + zx(ix)*zy(iy)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      zdotu = ztemp
+      return
+c
+c        code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        ztemp = ztemp + zx(i)*zy(i)
+   30 continue
+      zdotu = ztemp
+      return
+      end
diff --git a/libcruft/blas/zdrot.f b/libcruft/blas/zdrot.f
new file mode 100644
index 0000000..450bed6
--- /dev/null
+++ b/libcruft/blas/zdrot.f
@@ -0,0 +1,38 @@
+      subroutine  zdrot (n,zx,incx,zy,incy,c,s)
+c
+c     applies a plane rotation, where the cos and sin (c and s) are
+c     double precision and the vectors zx and zy are double complex.
+c     jack dongarra, linpack, 3/11/78.
+c
+      double complex zx(*),zy(*),ztemp
+      double precision c,s
+      integer i,incx,incy,ix,iy,n
+c
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c       code for unequal increments or equal increments not equal
+c         to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        ztemp = c*zx(ix) + s*zy(iy)
+        zy(iy) = c*zy(iy) - s*zx(ix)
+        zx(ix) = ztemp
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c       code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        ztemp = c*zx(i) + s*zy(i)
+        zy(i) = c*zy(i) - s*zx(i)
+        zx(i) = ztemp
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/zdscal.f b/libcruft/blas/zdscal.f
new file mode 100644
index 0000000..8123424
--- /dev/null
+++ b/libcruft/blas/zdscal.f
@@ -0,0 +1,30 @@
+      subroutine  zdscal(n,da,zx,incx)
+c
+c     scales a vector by a constant.
+c     jack dongarra, 3/11/78.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*)
+      double precision da
+      integer i,incx,ix,n
+c
+      if( n.le.0 .or. incx.le.0 )return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      ix = 1
+      do 10 i = 1,n
+        zx(ix) = dcmplx(da,0.0d0)*zx(ix)
+        ix = ix + incx
+   10 continue
+      return
+c
+c        code for increment equal to 1
+c
+   20 do 30 i = 1,n
+        zx(i) = dcmplx(da,0.0d0)*zx(i)
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/zgemm.f b/libcruft/blas/zgemm.f
new file mode 100644
index 0000000..09cd151
--- /dev/null
+++ b/libcruft/blas/zgemm.f
@@ -0,0 +1,415 @@
+      SUBROUTINE ZGEMM ( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB,
+     $                   BETA, C, LDC )
+*     .. Scalar Arguments ..
+      CHARACTER*1        TRANSA, TRANSB
+      INTEGER            M, N, K, LDA, LDB, LDC
+      COMPLEX*16         ALPHA, BETA
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*op( A )*op( B ) + beta*C,
+*
+*  where  op( X ) is one of
+*
+*     op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
+*
+*  alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*  an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n',  op( A ) = A.
+*
+*              TRANSA = 'T' or 't',  op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c',  op( A ) = conjg( A' ).
+*
+*           Unchanged on exit.
+*
+*  TRANSB - CHARACTER*1.
+*           On entry, TRANSB specifies the form of op( B ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSB = 'N' or 'n',  op( B ) = B.
+*
+*              TRANSB = 'T' or 't',  op( B ) = B'.
+*
+*              TRANSB = 'C' or 'c',  op( B ) = conjg( B' ).
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies  the number  of rows  of the  matrix
+*           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N  specifies the number  of columns of the matrix
+*           op( B ) and the number of columns of the matrix C. N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry,  K  specifies  the number of columns of the matrix
+*           op( A ) and the number of rows of the matrix op( B ). K must
+*           be at least  zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by m  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX*16       array of DIMENSION ( LDB, kb ), where kb is
+*           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  n by k  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*           least  max( 1, n ).
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX*16      .
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX*16       array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n  matrix
+*           ( alpha*op( A )*op( B ) + beta*C ).
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     .. Local Scalars ..
+      LOGICAL            CONJA, CONJB, NOTA, NOTB
+      INTEGER            I, INFO, J, L, NCOLA, NROWA, NROWB
+      COMPLEX*16         TEMP
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER        ( ONE  = ( 1.0D+0, 0.0D+0 ) )
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     conjugated or transposed, set  CONJA and CONJB  as true if  A  and
+*     B  respectively are to be  transposed but  not conjugated  and set
+*     NROWA, NCOLA and  NROWB  as the number of rows and  columns  of  A
+*     and the number of rows of  B  respectively.
+*
+      NOTA  = LSAME( TRANSA, 'N' )
+      NOTB  = LSAME( TRANSB, 'N' )
+      CONJA = LSAME( TRANSA, 'C' )
+      CONJB = LSAME( TRANSB, 'C' )
+      IF( NOTA )THEN
+         NROWA = M
+         NCOLA = K
+      ELSE
+         NROWA = K
+         NCOLA = M
+      END IF
+      IF( NOTB )THEN
+         NROWB = K
+      ELSE
+         NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF(      ( .NOT.NOTA                 ).AND.
+     $         ( .NOT.CONJA                ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'T' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.NOTB                 ).AND.
+     $         ( .NOT.CONJB                ).AND.
+     $         ( .NOT.LSAME( TRANSB, 'T' ) )      )THEN
+         INFO = 2
+      ELSE IF( M  .LT.0               )THEN
+         INFO = 3
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 4
+      ELSE IF( K  .LT.0               )THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 8
+      ELSE IF( LDB.LT.MAX( 1, NROWB ) )THEN
+         INFO = 10
+      ELSE IF( LDC.LT.MAX( 1, M     ) )THEN
+         INFO = 13
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZGEMM ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.
+     $    ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         IF( BETA.EQ.ZERO )THEN
+            DO 20, J = 1, N
+               DO 10, I = 1, M
+                  C( I, J ) = ZERO
+   10          CONTINUE
+   20       CONTINUE
+         ELSE
+            DO 40, J = 1, N
+               DO 30, I = 1, M
+                  C( I, J ) = BETA*C( I, J )
+   30          CONTINUE
+   40       CONTINUE
+         END IF
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( NOTB )THEN
+         IF( NOTA )THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+            DO 90, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 50, I = 1, M
+                     C( I, J ) = ZERO
+   50             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 60, I = 1, M
+                     C( I, J ) = BETA*C( I, J )
+   60             CONTINUE
+               END IF
+               DO 80, L = 1, K
+                  IF( B( L, J ).NE.ZERO )THEN
+                     TEMP = ALPHA*B( L, J )
+                     DO 70, I = 1, M
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+   70                CONTINUE
+                  END IF
+   80          CONTINUE
+   90       CONTINUE
+         ELSE IF( CONJA )THEN
+*
+*           Form  C := alpha*conjg( A' )*B + beta*C.
+*
+            DO 120, J = 1, N
+               DO 110, I = 1, M
+                  TEMP = ZERO
+                  DO 100, L = 1, K
+                     TEMP = TEMP + DCONJG( A( L, I ) )*B( L, J )
+  100             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  110          CONTINUE
+  120       CONTINUE
+         ELSE
+*
+*           Form  C := alpha*A'*B + beta*C
+*
+            DO 150, J = 1, N
+               DO 140, I = 1, M
+                  TEMP = ZERO
+                  DO 130, L = 1, K
+                     TEMP = TEMP + A( L, I )*B( L, J )
+  130             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  140          CONTINUE
+  150       CONTINUE
+         END IF
+      ELSE IF( NOTA )THEN
+         IF( CONJB )THEN
+*
+*           Form  C := alpha*A*conjg( B' ) + beta*C.
+*
+            DO 200, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 160, I = 1, M
+                     C( I, J ) = ZERO
+  160             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 170, I = 1, M
+                     C( I, J ) = BETA*C( I, J )
+  170             CONTINUE
+               END IF
+               DO 190, L = 1, K
+                  IF( B( J, L ).NE.ZERO )THEN
+                     TEMP = ALPHA*DCONJG( B( J, L ) )
+                     DO 180, I = 1, M
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  180                CONTINUE
+                  END IF
+  190          CONTINUE
+  200       CONTINUE
+         ELSE
+*
+*           Form  C := alpha*A*B'          + beta*C
+*
+            DO 250, J = 1, N
+               IF( BETA.EQ.ZERO )THEN
+                  DO 210, I = 1, M
+                     C( I, J ) = ZERO
+  210             CONTINUE
+               ELSE IF( BETA.NE.ONE )THEN
+                  DO 220, I = 1, M
+                     C( I, J ) = BETA*C( I, J )
+  220             CONTINUE
+               END IF
+               DO 240, L = 1, K
+                  IF( B( J, L ).NE.ZERO )THEN
+                     TEMP = ALPHA*B( J, L )
+                     DO 230, I = 1, M
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  230                CONTINUE
+                  END IF
+  240          CONTINUE
+  250       CONTINUE
+         END IF
+      ELSE IF( CONJA )THEN
+         IF( CONJB )THEN
+*
+*           Form  C := alpha*conjg( A' )*conjg( B' ) + beta*C.
+*
+            DO 280, J = 1, N
+               DO 270, I = 1, M
+                  TEMP = ZERO
+                  DO 260, L = 1, K
+                     TEMP = TEMP +
+     $                      DCONJG( A( L, I ) )*DCONJG( B( J, L ) )
+  260             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  270          CONTINUE
+  280       CONTINUE
+         ELSE
+*
+*           Form  C := alpha*conjg( A' )*B' + beta*C
+*
+            DO 310, J = 1, N
+               DO 300, I = 1, M
+                  TEMP = ZERO
+                  DO 290, L = 1, K
+                     TEMP = TEMP + DCONJG( A( L, I ) )*B( J, L )
+  290             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  300          CONTINUE
+  310       CONTINUE
+         END IF
+      ELSE
+         IF( CONJB )THEN
+*
+*           Form  C := alpha*A'*conjg( B' ) + beta*C
+*
+            DO 340, J = 1, N
+               DO 330, I = 1, M
+                  TEMP = ZERO
+                  DO 320, L = 1, K
+                     TEMP = TEMP + A( L, I )*DCONJG( B( J, L ) )
+  320             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  330          CONTINUE
+  340       CONTINUE
+         ELSE
+*
+*           Form  C := alpha*A'*B' + beta*C
+*
+            DO 370, J = 1, N
+               DO 360, I = 1, M
+                  TEMP = ZERO
+                  DO 350, L = 1, K
+                     TEMP = TEMP + A( L, I )*B( J, L )
+  350             CONTINUE
+                  IF( BETA.EQ.ZERO )THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  360          CONTINUE
+  370       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZGEMM .
+*
+      END
diff --git a/libcruft/blas/zgemv.f b/libcruft/blas/zgemv.f
new file mode 100644
index 0000000..014a5e0
--- /dev/null
+++ b/libcruft/blas/zgemv.f
@@ -0,0 +1,281 @@
+      SUBROUTINE ZGEMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX,
+     $                   BETA, Y, INCY )
+*     .. Scalar Arguments ..
+      COMPLEX*16         ALPHA, BETA
+      INTEGER            INCX, INCY, LDA, M, N
+      CHARACTER*1        TRANS
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEMV  performs one of the matrix-vector operations
+*
+*     y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,   or
+*
+*     y := alpha*conjg( A' )*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are vectors and A is an
+*  m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*
+*              TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.
+*
+*              TRANS = 'C' or 'c'   y := alpha*conjg( A' )*x + beta*y.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of DIMENSION at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*           Before entry, the incremented array X must contain the
+*           vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX*16      .
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX*16       array of DIMENSION at least
+*           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*           and at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*           Before entry with BETA non-zero, the incremented array Y
+*           must contain the vector y. On exit, Y is overwritten by the
+*           updated vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER        ( ONE  = ( 1.0D+0, 0.0D+0 ) )
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, IY, J, JX, JY, KX, KY, LENX, LENY
+      LOGICAL            NOCONJ
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 1
+      ELSE IF( M.LT.0 )THEN
+         INFO = 2
+      ELSE IF( N.LT.0 )THEN
+         INFO = 3
+      ELSE IF( LDA.LT.MAX( 1, M ) )THEN
+         INFO = 6
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 8
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 11
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZGEMV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.
+     $    ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+      NOCONJ = LSAME( TRANS, 'T' )
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+         LENX = N
+         LENY = M
+      ELSE
+         LENX = M
+         LENY = N
+      END IF
+      IF( INCX.GT.0 )THEN
+         KX = 1
+      ELSE
+         KX = 1 - ( LENX - 1 )*INCX
+      END IF
+      IF( INCY.GT.0 )THEN
+         KY = 1
+      ELSE
+         KY = 1 - ( LENY - 1 )*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF( BETA.NE.ONE )THEN
+         IF( INCY.EQ.1 )THEN
+            IF( BETA.EQ.ZERO )THEN
+               DO 10, I = 1, LENY
+                  Y( I ) = ZERO
+   10          CONTINUE
+            ELSE
+               DO 20, I = 1, LENY
+                  Y( I ) = BETA*Y( I )
+   20          CONTINUE
+            END IF
+         ELSE
+            IY = KY
+            IF( BETA.EQ.ZERO )THEN
+               DO 30, I = 1, LENY
+                  Y( IY ) = ZERO
+                  IY      = IY   + INCY
+   30          CONTINUE
+            ELSE
+               DO 40, I = 1, LENY
+                  Y( IY ) = BETA*Y( IY )
+                  IY      = IY           + INCY
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      IF( ALPHA.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+         JX = KX
+         IF( INCY.EQ.1 )THEN
+            DO 60, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( JX )
+                  DO 50, I = 1, M
+                     Y( I ) = Y( I ) + TEMP*A( I, J )
+   50             CONTINUE
+               END IF
+               JX = JX + INCX
+   60       CONTINUE
+         ELSE
+            DO 80, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*X( JX )
+                  IY   = KY
+                  DO 70, I = 1, M
+                     Y( IY ) = Y( IY ) + TEMP*A( I, J )
+                     IY      = IY      + INCY
+   70             CONTINUE
+               END IF
+               JX = JX + INCX
+   80       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  y := alpha*A'*x + y  or  y := alpha*conjg( A' )*x + y.
+*
+         JY = KY
+         IF( INCX.EQ.1 )THEN
+            DO 110, J = 1, N
+               TEMP = ZERO
+               IF( NOCONJ )THEN
+                  DO 90, I = 1, M
+                     TEMP = TEMP + A( I, J )*X( I )
+   90             CONTINUE
+               ELSE
+                  DO 100, I = 1, M
+                     TEMP = TEMP + DCONJG( A( I, J ) )*X( I )
+  100             CONTINUE
+               END IF
+               Y( JY ) = Y( JY ) + ALPHA*TEMP
+               JY      = JY      + INCY
+  110       CONTINUE
+         ELSE
+            DO 140, J = 1, N
+               TEMP = ZERO
+               IX   = KX
+               IF( NOCONJ )THEN
+                  DO 120, I = 1, M
+                     TEMP = TEMP + A( I, J )*X( IX )
+                     IX   = IX   + INCX
+  120             CONTINUE
+               ELSE
+                  DO 130, I = 1, M
+                     TEMP = TEMP + DCONJG( A( I, J ) )*X( IX )
+                     IX   = IX   + INCX
+  130             CONTINUE
+               END IF
+               Y( JY ) = Y( JY ) + ALPHA*TEMP
+               JY      = JY      + INCY
+  140       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZGEMV .
+*
+      END
diff --git a/libcruft/blas/zgerc.f b/libcruft/blas/zgerc.f
new file mode 100644
index 0000000..968c5b4
--- /dev/null
+++ b/libcruft/blas/zgerc.f
@@ -0,0 +1,157 @@
+      SUBROUTINE ZGERC ( M, N, ALPHA, X, INCX, Y, INCY, A, LDA )
+*     .. Scalar Arguments ..
+      COMPLEX*16         ALPHA
+      INTEGER            INCX, INCY, LDA, M, N
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGERC  performs the rank 1 operation
+*
+*     A := alpha*x*conjg( y' ) + A,
+*
+*  where alpha is a scalar, x is an m element vector, y is an n element
+*  vector and A is an m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the m
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients. On exit, A is
+*           overwritten by the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, J, JY, KX
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( M.LT.0 )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( LDA.LT.MAX( 1, M ) )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZGERC ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) )
+     $   RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( INCY.GT.0 )THEN
+         JY = 1
+      ELSE
+         JY = 1 - ( N - 1 )*INCY
+      END IF
+      IF( INCX.EQ.1 )THEN
+         DO 20, J = 1, N
+            IF( Y( JY ).NE.ZERO )THEN
+               TEMP = ALPHA*DCONJG( Y( JY ) )
+               DO 10, I = 1, M
+                  A( I, J ) = A( I, J ) + X( I )*TEMP
+   10          CONTINUE
+            END IF
+            JY = JY + INCY
+   20    CONTINUE
+      ELSE
+         IF( INCX.GT.0 )THEN
+            KX = 1
+         ELSE
+            KX = 1 - ( M - 1 )*INCX
+         END IF
+         DO 40, J = 1, N
+            IF( Y( JY ).NE.ZERO )THEN
+               TEMP = ALPHA*DCONJG( Y( JY ) )
+               IX   = KX
+               DO 30, I = 1, M
+                  A( I, J ) = A( I, J ) + X( IX )*TEMP
+                  IX        = IX        + INCX
+   30          CONTINUE
+            END IF
+            JY = JY + INCY
+   40    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZGERC .
+*
+      END
diff --git a/libcruft/blas/zgeru.f b/libcruft/blas/zgeru.f
new file mode 100644
index 0000000..5283af6
--- /dev/null
+++ b/libcruft/blas/zgeru.f
@@ -0,0 +1,157 @@
+      SUBROUTINE ZGERU ( M, N, ALPHA, X, INCX, Y, INCY, A, LDA )
+*     .. Scalar Arguments ..
+      COMPLEX*16         ALPHA
+      INTEGER            INCX, INCY, LDA, M, N
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGERU  performs the rank 1 operation
+*
+*     A := alpha*x*y' + A,
+*
+*  where alpha is a scalar, x is an m element vector, y is an n element
+*  vector and A is an m by n matrix.
+*
+*  Parameters
+*  ==========
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of the matrix A.
+*           M must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( m - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the m
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry, the leading m by n part of the array A must
+*           contain the matrix of coefficients. On exit, A is
+*           overwritten by the updated matrix.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, J, JY, KX
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( M.LT.0 )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( LDA.LT.MAX( 1, M ) )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZGERU ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) )
+     $   RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( INCY.GT.0 )THEN
+         JY = 1
+      ELSE
+         JY = 1 - ( N - 1 )*INCY
+      END IF
+      IF( INCX.EQ.1 )THEN
+         DO 20, J = 1, N
+            IF( Y( JY ).NE.ZERO )THEN
+               TEMP = ALPHA*Y( JY )
+               DO 10, I = 1, M
+                  A( I, J ) = A( I, J ) + X( I )*TEMP
+   10          CONTINUE
+            END IF
+            JY = JY + INCY
+   20    CONTINUE
+      ELSE
+         IF( INCX.GT.0 )THEN
+            KX = 1
+         ELSE
+            KX = 1 - ( M - 1 )*INCX
+         END IF
+         DO 40, J = 1, N
+            IF( Y( JY ).NE.ZERO )THEN
+               TEMP = ALPHA*Y( JY )
+               IX   = KX
+               DO 30, I = 1, M
+                  A( I, J ) = A( I, J ) + X( IX )*TEMP
+                  IX        = IX        + INCX
+   30          CONTINUE
+            END IF
+            JY = JY + INCY
+   40    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZGERU .
+*
+      END
diff --git a/libcruft/blas/zhemm.f b/libcruft/blas/zhemm.f
new file mode 100644
index 0000000..f22fbe9
--- /dev/null
+++ b/libcruft/blas/zhemm.f
@@ -0,0 +1,298 @@
+      SUBROUTINE ZHEMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      DOUBLE COMPLEX ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHEMM  performs one of the matrix-matrix operations
+*
+*     C := alpha*A*B + beta*C,
+*
+*  or
+*
+*     C := alpha*B*A + beta*C,
+*
+*  where alpha and beta are scalars, A is an hermitian matrix and  B and
+*  C are m by n matrices.
+*
+*  Arguments
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE  specifies whether  the  hermitian matrix  A
+*           appears on the  left or right  in the  operation as follows:
+*
+*              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*
+*              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of  the  hermitian  matrix   A  is  to  be
+*           referenced as follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*                                  hermitian matrix is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*                                  hermitian matrix is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry,  M  specifies the number of rows of the matrix  C.
+*           M  must be at least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of the matrix C.
+*           N  must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, ka ), where ka is
+*           m  when  SIDE = 'L' or 'l'  and is n  otherwise.
+*           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*           the array  A  must contain the  hermitian matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  hermitian matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  m by m  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  hermitian
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*           the array  A  must contain the  hermitian matrix,  such that
+*           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*           part of the array  A  must contain the upper triangular part
+*           of the  hermitian matrix and the  strictly  lower triangular
+*           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*           the leading  n by n  lower triangular part  of the  array  A
+*           must  contain  the  lower triangular part  of the  hermitian
+*           matrix and the  strictly upper triangular part of  A  is not
+*           referenced.
+*           Note that the imaginary parts  of the diagonal elements need
+*           not be set, they are assumed to be zero.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the  calling (sub) program. When  SIDE = 'L' or 'l'  then
+*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*           least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX*16       array of DIMENSION ( LDB, n ).
+*           Before entry, the leading  m by n part of the array  B  must
+*           contain the matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX*16      .
+*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*           supplied as zero then C need not be set on input.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX*16       array of DIMENSION ( LDC, n ).
+*           Before entry, the leading  m by n  part of the array  C must
+*           contain the matrix  C,  except when  beta  is zero, in which
+*           case C need not be set on entry.
+*           On exit, the array  C  is overwritten by the  m by n updated
+*           matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE COMPLEX ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      DOUBLE COMPLEX ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*DCONJG(A(K,I))
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*DBLE(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*DBLE(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*DCONJG(A(K,I))
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*DBLE(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*DBLE(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*DBLE(A(J,J))
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*DCONJG(A(J,K))
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*DCONJG(A(J,K))
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZHEMM .
+*
+      END
diff --git a/libcruft/blas/zhemv.f b/libcruft/blas/zhemv.f
new file mode 100644
index 0000000..659a8e4
--- /dev/null
+++ b/libcruft/blas/zhemv.f
@@ -0,0 +1,269 @@
+*
+************************************************************************
+*
+      SUBROUTINE ZHEMV ( UPLO, N, ALPHA, A, LDA, X, INCX,
+     $                   BETA, Y, INCY )
+*     .. Scalar Arguments ..
+      COMPLEX*16         ALPHA, BETA
+      INTEGER            INCX, INCY, LDA, N
+      CHARACTER*1        UPLO
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHEMV  performs the matrix-vector  operation
+*
+*     y := alpha*A*x + beta*y,
+*
+*  where alpha and beta are scalars, x and y are n element vectors and
+*  A is an n by n hermitian matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the hermitian matrix and the strictly
+*           lower triangular part of A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the hermitian matrix and the strictly
+*           upper triangular part of A is not referenced.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set and are assumed to be zero.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX*16      .
+*           On entry, BETA specifies the scalar beta. When BETA is
+*           supplied as zero then Y need not be set on input.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y. On exit, Y is overwritten by the updated
+*           vector y.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER        ( ONE  = ( 1.0D+0, 0.0D+0 ) )
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP1, TEMP2
+      INTEGER            I, INFO, IX, IY, J, JX, JY, KX, KY
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, DBLE
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO, 'U' ).AND.
+     $         .NOT.LSAME( UPLO, 'L' )      )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 5
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 10
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZHEMV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
+     $   RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF( INCX.GT.0 )THEN
+         KX = 1
+      ELSE
+         KX = 1 - ( N - 1 )*INCX
+      END IF
+      IF( INCY.GT.0 )THEN
+         KY = 1
+      ELSE
+         KY = 1 - ( N - 1 )*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF( BETA.NE.ONE )THEN
+         IF( INCY.EQ.1 )THEN
+            IF( BETA.EQ.ZERO )THEN
+               DO 10, I = 1, N
+                  Y( I ) = ZERO
+   10          CONTINUE
+            ELSE
+               DO 20, I = 1, N
+                  Y( I ) = BETA*Y( I )
+   20          CONTINUE
+            END IF
+         ELSE
+            IY = KY
+            IF( BETA.EQ.ZERO )THEN
+               DO 30, I = 1, N
+                  Y( IY ) = ZERO
+                  IY      = IY   + INCY
+   30          CONTINUE
+            ELSE
+               DO 40, I = 1, N
+                  Y( IY ) = BETA*Y( IY )
+                  IY      = IY           + INCY
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      IF( ALPHA.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( UPLO, 'U' ) )THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 60, J = 1, N
+               TEMP1 = ALPHA*X( J )
+               TEMP2 = ZERO
+               DO 50, I = 1, J - 1
+                  Y( I ) = Y( I ) + TEMP1*A( I, J )
+                  TEMP2  = TEMP2  + DCONJG( A( I, J ) )*X( I )
+   50          CONTINUE
+               Y( J ) = Y( J ) + TEMP1*DBLE( A( J, J ) ) + ALPHA*TEMP2
+   60       CONTINUE
+         ELSE
+            JX = KX
+            JY = KY
+            DO 80, J = 1, N
+               TEMP1 = ALPHA*X( JX )
+               TEMP2 = ZERO
+               IX    = KX
+               IY    = KY
+               DO 70, I = 1, J - 1
+                  Y( IY ) = Y( IY ) + TEMP1*A( I, J )
+                  TEMP2   = TEMP2   + DCONJG( A( I, J ) )*X( IX )
+                  IX      = IX      + INCX
+                  IY      = IY      + INCY
+   70          CONTINUE
+               Y( JY ) = Y( JY ) + TEMP1*DBLE( A( J, J ) ) + ALPHA*TEMP2
+               JX      = JX      + INCX
+               JY      = JY      + INCY
+   80       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 100, J = 1, N
+               TEMP1  = ALPHA*X( J )
+               TEMP2  = ZERO
+               Y( J ) = Y( J ) + TEMP1*DBLE( A( J, J ) )
+               DO 90, I = J + 1, N
+                  Y( I ) = Y( I ) + TEMP1*A( I, J )
+                  TEMP2  = TEMP2  + DCONJG( A( I, J ) )*X( I )
+   90          CONTINUE
+               Y( J ) = Y( J ) + ALPHA*TEMP2
+  100       CONTINUE
+         ELSE
+            JX = KX
+            JY = KY
+            DO 120, J = 1, N
+               TEMP1   = ALPHA*X( JX )
+               TEMP2   = ZERO
+               Y( JY ) = Y( JY ) + TEMP1*DBLE( A( J, J ) )
+               IX      = JX
+               IY      = JY
+               DO 110, I = J + 1, N
+                  IX      = IX      + INCX
+                  IY      = IY      + INCY
+                  Y( IY ) = Y( IY ) + TEMP1*A( I, J )
+                  TEMP2   = TEMP2   + DCONJG( A( I, J ) )*X( IX )
+  110          CONTINUE
+               Y( JY ) = Y( JY ) + ALPHA*TEMP2
+               JX      = JX      + INCX
+               JY      = JY      + INCY
+  120       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHEMV .
+*
+      END
diff --git a/libcruft/blas/zher.f b/libcruft/blas/zher.f
new file mode 100644
index 0000000..fcf40a5
--- /dev/null
+++ b/libcruft/blas/zher.f
@@ -0,0 +1,212 @@
+      SUBROUTINE ZHER  ( UPLO, N, ALPHA, X, INCX, A, LDA )
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   ALPHA
+      INTEGER            INCX, LDA, N
+      CHARACTER*1        UPLO
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHER   performs the hermitian rank 1 operation
+*
+*     A := alpha*x*conjg( x' ) + A,
+*
+*  where alpha is a real scalar, x is an n element vector and A is an
+*  n by n hermitian matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION.
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the hermitian matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the hermitian matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set, they are assumed to be zero, and on exit they
+*           are set to zero.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, J, JX, KX
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, DBLE
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO, 'U' ).AND.
+     $         .NOT.LSAME( UPLO, 'L' )      )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 7
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZHER  ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.( ALPHA.EQ.DBLE( ZERO ) ) )
+     $   RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF( LSAME( UPLO, 'U' ) )THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+         IF( INCX.EQ.1 )THEN
+            DO 20, J = 1, N
+               IF( X( J ).NE.ZERO )THEN
+                  TEMP = ALPHA*DCONJG( X( J ) )
+                  DO 10, I = 1, J - 1
+                     A( I, J ) = A( I, J ) + X( I )*TEMP
+   10             CONTINUE
+                  A( J, J ) = DBLE( A( J, J ) ) + DBLE( X( J )*TEMP )
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+   20       CONTINUE
+         ELSE
+            JX = KX
+            DO 40, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP = ALPHA*DCONJG( X( JX ) )
+                  IX   = KX
+                  DO 30, I = 1, J - 1
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP
+                     IX        = IX        + INCX
+   30             CONTINUE
+                  A( J, J ) = DBLE( A( J, J ) ) + DBLE( X( JX )*TEMP )
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+               JX = JX + INCX
+   40       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+         IF( INCX.EQ.1 )THEN
+            DO 60, J = 1, N
+               IF( X( J ).NE.ZERO )THEN
+                  TEMP      = ALPHA*DCONJG( X( J ) )
+                  A( J, J ) = DBLE( A( J, J ) ) + DBLE( TEMP*X( J ) )
+                  DO 50, I = J + 1, N
+                     A( I, J ) = A( I, J ) + X( I )*TEMP
+   50             CONTINUE
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+   60       CONTINUE
+         ELSE
+            JX = KX
+            DO 80, J = 1, N
+               IF( X( JX ).NE.ZERO )THEN
+                  TEMP      = ALPHA*DCONJG( X( JX ) )
+                  A( J, J ) = DBLE( A( J, J ) ) + DBLE( TEMP*X( JX ) )
+                  IX        = JX
+                  DO 70, I = J + 1, N
+                     IX        = IX        + INCX
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP
+   70             CONTINUE
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+               JX = JX + INCX
+   80       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHER  .
+*
+      END
diff --git a/libcruft/blas/zher2.f b/libcruft/blas/zher2.f
new file mode 100644
index 0000000..603783b
--- /dev/null
+++ b/libcruft/blas/zher2.f
@@ -0,0 +1,252 @@
+*
+************************************************************************
+*
+      SUBROUTINE ZHER2 ( UPLO, N, ALPHA, X, INCX, Y, INCY, A, LDA )
+*     .. Scalar Arguments ..
+      COMPLEX*16         ALPHA
+      INTEGER            INCX, INCY, LDA, N
+      CHARACTER*1        UPLO
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * ), Y( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHER2  performs the hermitian rank 2 operation
+*
+*     A := alpha*x*conjg( y' ) + conjg( alpha )*y*conjg( x' ) + A,
+*
+*  where alpha is a scalar, x and y are n element vectors and A is an n
+*  by n hermitian matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the upper or lower
+*           triangular part of the array A is to be referenced as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x.
+*           Unchanged on exit.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*  Y      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCY ) ).
+*           Before entry, the incremented array Y must contain the n
+*           element vector y.
+*           Unchanged on exit.
+*
+*  INCY   - INTEGER.
+*           On entry, INCY specifies the increment for the elements of
+*           Y. INCY must not be zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular part of the hermitian matrix and the strictly
+*           lower triangular part of A is not referenced. On exit, the
+*           upper triangular part of the array A is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular part of the hermitian matrix and the strictly
+*           upper triangular part of A is not referenced. On exit, the
+*           lower triangular part of the array A is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set, they are assumed to be zero, and on exit they
+*           are set to zero.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP1, TEMP2
+      INTEGER            I, INFO, IX, IY, J, JX, JY, KX, KY
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, DBLE
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO, 'U' ).AND.
+     $         .NOT.LSAME( UPLO, 'L' )      )THEN
+         INFO = 1
+      ELSE IF( N.LT.0 )THEN
+         INFO = 2
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 5
+      ELSE IF( INCY.EQ.0 )THEN
+         INFO = 7
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZHER2 ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) )
+     $   RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF( ( INCX.NE.1 ).OR.( INCY.NE.1 ) )THEN
+         IF( INCX.GT.0 )THEN
+            KX = 1
+         ELSE
+            KX = 1 - ( N - 1 )*INCX
+         END IF
+         IF( INCY.GT.0 )THEN
+            KY = 1
+         ELSE
+            KY = 1 - ( N - 1 )*INCY
+         END IF
+         JX = KX
+         JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF( LSAME( UPLO, 'U' ) )THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 20, J = 1, N
+               IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN
+                  TEMP1 = ALPHA*DCONJG( Y( J ) )
+                  TEMP2 = DCONJG( ALPHA*X( J ) )
+                  DO 10, I = 1, J - 1
+                     A( I, J ) = A( I, J ) + X( I )*TEMP1 + Y( I )*TEMP2
+   10             CONTINUE
+                  A( J, J ) = DBLE( A( J, J ) ) +
+     $                        DBLE( X( J )*TEMP1 + Y( J )*TEMP2 )
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+   20       CONTINUE
+         ELSE
+            DO 40, J = 1, N
+               IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN
+                  TEMP1 = ALPHA*DCONJG( Y( JY ) )
+                  TEMP2 = DCONJG( ALPHA*X( JX ) )
+                  IX    = KX
+                  IY    = KY
+                  DO 30, I = 1, J - 1
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP1
+     $                                     + Y( IY )*TEMP2
+                     IX        = IX        + INCX
+                     IY        = IY        + INCY
+   30             CONTINUE
+                  A( J, J ) = DBLE( A( J, J ) ) +
+     $                        DBLE( X( JX )*TEMP1 + Y( JY )*TEMP2 )
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+               JX = JX + INCX
+               JY = JY + INCY
+   40       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+         IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN
+            DO 60, J = 1, N
+               IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN
+                  TEMP1     = ALPHA*DCONJG( Y( J ) )
+                  TEMP2     = DCONJG( ALPHA*X( J ) )
+                  A( J, J ) = DBLE( A( J, J ) ) +
+     $                        DBLE( X( J )*TEMP1 + Y( J )*TEMP2 )
+                  DO 50, I = J + 1, N
+                     A( I, J ) = A( I, J ) + X( I )*TEMP1 + Y( I )*TEMP2
+   50             CONTINUE
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+   60       CONTINUE
+         ELSE
+            DO 80, J = 1, N
+               IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN
+                  TEMP1     = ALPHA*DCONJG( Y( JY ) )
+                  TEMP2     = DCONJG( ALPHA*X( JX ) )
+                  A( J, J ) = DBLE( A( J, J ) ) +
+     $                        DBLE( X( JX )*TEMP1 + Y( JY )*TEMP2 )
+                  IX        = JX
+                  IY        = JY
+                  DO 70, I = J + 1, N
+                     IX        = IX        + INCX
+                     IY        = IY        + INCY
+                     A( I, J ) = A( I, J ) + X( IX )*TEMP1
+     $                                     + Y( IY )*TEMP2
+   70             CONTINUE
+               ELSE
+                  A( J, J ) = DBLE( A( J, J ) )
+               END IF
+               JX = JX + INCX
+               JY = JY + INCY
+   80       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHER2 .
+*
+      END
diff --git a/libcruft/blas/zher2k.f b/libcruft/blas/zher2k.f
new file mode 100644
index 0000000..408d75c
--- /dev/null
+++ b/libcruft/blas/zher2k.f
@@ -0,0 +1,372 @@
+      SUBROUTINE ZHER2K( UPLO, TRANS, N, K, ALPHA, A, LDA, B, LDB, BETA,
+     $                   C, LDC )
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS, UPLO
+      INTEGER            K, LDA, LDB, LDC, N
+      DOUBLE PRECISION   BETA
+      COMPLEX*16         ALPHA
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHER2K  performs one of the hermitian rank 2k operations
+*
+*     C := alpha*A*conjg( B' ) + conjg( alpha )*B*conjg( A' ) + beta*C,
+*
+*  or
+*
+*     C := alpha*conjg( A' )*B + conjg( alpha )*conjg( B' )*A + beta*C,
+*
+*  where  alpha and beta  are scalars with  beta  real,  C is an  n by n
+*  hermitian matrix and  A and B  are  n by k matrices in the first case
+*  and  k by n  matrices in the second case.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'    C := alpha*A*conjg( B' )          +
+*                                         conjg( alpha )*B*conjg( A' ) +
+*                                         beta*C.
+*
+*              TRANS = 'C' or 'c'    C := alpha*conjg( A' )*B          +
+*                                         conjg( alpha )*conjg( B' )*A +
+*                                         beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns  of the  matrices  A and B,  and on  entry  with
+*           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*           matrices  A and B.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16         .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX*16       array of DIMENSION ( LDB, kb ), where kb is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  B  must contain the matrix  B,  otherwise
+*           the leading  k by n  part of the array  B  must contain  the
+*           matrix B.
+*           Unchanged on exit.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION            .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX*16          array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  hermitian matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  hermitian matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set,  they are assumed to be zero,  and on exit they
+*           are set to zero.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*  -- Modified 8-Nov-93 to set C(J,J) to DBLE( C(J,J) ) when BETA = 1.
+*     Ed Anderson, Cray Research Inc.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCONJG, MAX
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, INFO, J, L, NROWA
+      COMPLEX*16         TEMP1, TEMP2
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         NROWA = N
+      ELSE
+         NROWA = K
+      END IF
+      UPPER = LSAME( UPLO, 'U' )
+*
+      INFO = 0
+      IF( ( .NOT.UPPER ) .AND. ( .NOT.LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = 1
+      ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ) .AND.
+     $         ( .NOT.LSAME( TRANS, 'C' ) ) ) THEN
+         INFO = 2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = 3
+      ELSE IF( K.LT.0 ) THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) ) THEN
+         INFO = 7
+      ELSE IF( LDB.LT.MAX( 1, NROWA ) ) THEN
+         INFO = 9
+      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
+         INFO = 12
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHER2K', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ) .OR. ( ( ( ALPHA.EQ.ZERO ) .OR. ( K.EQ.0 ) ) .AND.
+     $    ( BETA.EQ.ONE ) ) )RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO ) THEN
+         IF( UPPER ) THEN
+            IF( BETA.EQ.DBLE( ZERO ) ) THEN
+               DO 20 J = 1, N
+                  DO 10 I = 1, J
+                     C( I, J ) = ZERO
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40 J = 1, N
+                  DO 30 I = 1, J - 1
+                     C( I, J ) = BETA*C( I, J )
+   30             CONTINUE
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( BETA.EQ.DBLE( ZERO ) ) THEN
+               DO 60 J = 1, N
+                  DO 50 I = J, N
+                     C( I, J ) = ZERO
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80 J = 1, N
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+                  DO 70 I = J + 1, N
+                     C( I, J ) = BETA*C( I, J )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+*
+*        Form  C := alpha*A*conjg( B' ) + conjg( alpha )*B*conjg( A' ) +
+*                   C.
+*
+         IF( UPPER ) THEN
+            DO 130 J = 1, N
+               IF( BETA.EQ.DBLE( ZERO ) ) THEN
+                  DO 90 I = 1, J
+                     C( I, J ) = ZERO
+   90             CONTINUE
+               ELSE IF( BETA.NE.ONE ) THEN
+                  DO 100 I = 1, J - 1
+                     C( I, J ) = BETA*C( I, J )
+  100             CONTINUE
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+               ELSE
+                  C( J, J ) = DBLE( C( J, J ) )
+               END IF
+               DO 120 L = 1, K
+                  IF( ( A( J, L ).NE.ZERO ) .OR. ( B( J, L ).NE.ZERO ) )
+     $                 THEN
+                     TEMP1 = ALPHA*DCONJG( B( J, L ) )
+                     TEMP2 = DCONJG( ALPHA*A( J, L ) )
+                     DO 110 I = 1, J - 1
+                        C( I, J ) = C( I, J ) + A( I, L )*TEMP1 +
+     $                              B( I, L )*TEMP2
+  110                CONTINUE
+                     C( J, J ) = DBLE( C( J, J ) ) +
+     $                           DBLE( A( J, L )*TEMP1+B( J, L )*TEMP2 )
+                  END IF
+  120          CONTINUE
+  130       CONTINUE
+         ELSE
+            DO 180 J = 1, N
+               IF( BETA.EQ.DBLE( ZERO ) ) THEN
+                  DO 140 I = J, N
+                     C( I, J ) = ZERO
+  140             CONTINUE
+               ELSE IF( BETA.NE.ONE ) THEN
+                  DO 150 I = J + 1, N
+                     C( I, J ) = BETA*C( I, J )
+  150             CONTINUE
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+               ELSE
+                  C( J, J ) = DBLE( C( J, J ) )
+               END IF
+               DO 170 L = 1, K
+                  IF( ( A( J, L ).NE.ZERO ) .OR. ( B( J, L ).NE.ZERO ) )
+     $                 THEN
+                     TEMP1 = ALPHA*DCONJG( B( J, L ) )
+                     TEMP2 = DCONJG( ALPHA*A( J, L ) )
+                     DO 160 I = J + 1, N
+                        C( I, J ) = C( I, J ) + A( I, L )*TEMP1 +
+     $                              B( I, L )*TEMP2
+  160                CONTINUE
+                     C( J, J ) = DBLE( C( J, J ) ) +
+     $                           DBLE( A( J, L )*TEMP1+B( J, L )*TEMP2 )
+                  END IF
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  C := alpha*conjg( A' )*B + conjg( alpha )*conjg( B' )*A +
+*                   C.
+*
+         IF( UPPER ) THEN
+            DO 210 J = 1, N
+               DO 200 I = 1, J
+                  TEMP1 = ZERO
+                  TEMP2 = ZERO
+                  DO 190 L = 1, K
+                     TEMP1 = TEMP1 + DCONJG( A( L, I ) )*B( L, J )
+                     TEMP2 = TEMP2 + DCONJG( B( L, I ) )*A( L, J )
+  190             CONTINUE
+                  IF( I.EQ.J ) THEN
+                     IF( BETA.EQ.DBLE( ZERO ) ) THEN
+                        C( J, J ) = DBLE( ALPHA*TEMP1+DCONJG( ALPHA )*
+     $                              TEMP2 )
+                     ELSE
+                        C( J, J ) = BETA*DBLE( C( J, J ) ) +
+     $                              DBLE( ALPHA*TEMP1+DCONJG( ALPHA )*
+     $                              TEMP2 )
+                     END IF
+                  ELSE
+                     IF( BETA.EQ.DBLE( ZERO ) ) THEN
+                        C( I, J ) = ALPHA*TEMP1 + DCONJG( ALPHA )*TEMP2
+                     ELSE
+                        C( I, J ) = BETA*C( I, J ) + ALPHA*TEMP1 +
+     $                              DCONJG( ALPHA )*TEMP2
+                     END IF
+                  END IF
+  200          CONTINUE
+  210       CONTINUE
+         ELSE
+            DO 240 J = 1, N
+               DO 230 I = J, N
+                  TEMP1 = ZERO
+                  TEMP2 = ZERO
+                  DO 220 L = 1, K
+                     TEMP1 = TEMP1 + DCONJG( A( L, I ) )*B( L, J )
+                     TEMP2 = TEMP2 + DCONJG( B( L, I ) )*A( L, J )
+  220             CONTINUE
+                  IF( I.EQ.J ) THEN
+                     IF( BETA.EQ.DBLE( ZERO ) ) THEN
+                        C( J, J ) = DBLE( ALPHA*TEMP1+DCONJG( ALPHA )*
+     $                              TEMP2 )
+                     ELSE
+                        C( J, J ) = BETA*DBLE( C( J, J ) ) +
+     $                              DBLE( ALPHA*TEMP1+DCONJG( ALPHA )*
+     $                              TEMP2 )
+                     END IF
+                  ELSE
+                     IF( BETA.EQ.DBLE( ZERO ) ) THEN
+                        C( I, J ) = ALPHA*TEMP1 + DCONJG( ALPHA )*TEMP2
+                     ELSE
+                        C( I, J ) = BETA*C( I, J ) + ALPHA*TEMP1 +
+     $                              DCONJG( ALPHA )*TEMP2
+                     END IF
+                  END IF
+  230          CONTINUE
+  240       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHER2K.
+*
+      END
diff --git a/libcruft/blas/zherk.f b/libcruft/blas/zherk.f
new file mode 100644
index 0000000..cfbf718
--- /dev/null
+++ b/libcruft/blas/zherk.f
@@ -0,0 +1,330 @@
+      SUBROUTINE ZHERK( UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, C, LDC )
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS, UPLO
+      INTEGER            K, LDA, LDC, N
+      DOUBLE PRECISION   ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHERK  performs one of the hermitian rank k operations
+*
+*     C := alpha*A*conjg( A' ) + beta*C,
+*
+*  or
+*
+*     C := alpha*conjg( A' )*A + beta*C,
+*
+*  where  alpha and beta  are  real scalars,  C is an  n by n  hermitian
+*  matrix and  A  is an  n by k  matrix in the  first case and a  k by n
+*  matrix in the second case.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*conjg( A' ) + beta*C.
+*
+*              TRANS = 'C' or 'c'   C := alpha*conjg( A' )*A + beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns   of  the   matrix   A,   and  on   entry   with
+*           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*           matrix A.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - DOUBLE PRECISION            .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - DOUBLE PRECISION.
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX*16          array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  hermitian matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  hermitian matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*           Note that the imaginary parts of the diagonal elements need
+*           not be set,  they are assumed to be zero,  and on exit they
+*           are set to zero.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*  -- Modified 8-Nov-93 to set C(J,J) to DBLE( C(J,J) ) when BETA = 1.
+*     Ed Anderson, Cray Research Inc.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, DCONJG, MAX
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, INFO, J, L, NROWA
+      DOUBLE PRECISION   RTEMP
+      COMPLEX*16         TEMP
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         NROWA = N
+      ELSE
+         NROWA = K
+      END IF
+      UPPER = LSAME( UPLO, 'U' )
+*
+      INFO = 0
+      IF( ( .NOT.UPPER ) .AND. ( .NOT.LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = 1
+      ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ) .AND.
+     $         ( .NOT.LSAME( TRANS, 'C' ) ) ) THEN
+         INFO = 2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = 3
+      ELSE IF( K.LT.0 ) THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) ) THEN
+         INFO = 7
+      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
+         INFO = 10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHERK ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( ( N.EQ.0 ) .OR. ( ( ( ALPHA.EQ.ZERO ) .OR. ( K.EQ.0 ) ) .AND.
+     $    ( BETA.EQ.ONE ) ) )RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO ) THEN
+         IF( UPPER ) THEN
+            IF( BETA.EQ.ZERO ) THEN
+               DO 20 J = 1, N
+                  DO 10 I = 1, J
+                     C( I, J ) = ZERO
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40 J = 1, N
+                  DO 30 I = 1, J - 1
+                     C( I, J ) = BETA*C( I, J )
+   30             CONTINUE
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( BETA.EQ.ZERO ) THEN
+               DO 60 J = 1, N
+                  DO 50 I = J, N
+                     C( I, J ) = ZERO
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80 J = 1, N
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+                  DO 70 I = J + 1, N
+                     C( I, J ) = BETA*C( I, J )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+*
+*        Form  C := alpha*A*conjg( A' ) + beta*C.
+*
+         IF( UPPER ) THEN
+            DO 130 J = 1, N
+               IF( BETA.EQ.ZERO ) THEN
+                  DO 90 I = 1, J
+                     C( I, J ) = ZERO
+   90             CONTINUE
+               ELSE IF( BETA.NE.ONE ) THEN
+                  DO 100 I = 1, J - 1
+                     C( I, J ) = BETA*C( I, J )
+  100             CONTINUE
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+               ELSE
+                  C( J, J ) = DBLE( C( J, J ) )
+               END IF
+               DO 120 L = 1, K
+                  IF( A( J, L ).NE.DCMPLX( ZERO ) ) THEN
+                     TEMP = ALPHA*DCONJG( A( J, L ) )
+                     DO 110 I = 1, J - 1
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  110                CONTINUE
+                     C( J, J ) = DBLE( C( J, J ) ) +
+     $                           DBLE( TEMP*A( I, L ) )
+                  END IF
+  120          CONTINUE
+  130       CONTINUE
+         ELSE
+            DO 180 J = 1, N
+               IF( BETA.EQ.ZERO ) THEN
+                  DO 140 I = J, N
+                     C( I, J ) = ZERO
+  140             CONTINUE
+               ELSE IF( BETA.NE.ONE ) THEN
+                  C( J, J ) = BETA*DBLE( C( J, J ) )
+                  DO 150 I = J + 1, N
+                     C( I, J ) = BETA*C( I, J )
+  150             CONTINUE
+               ELSE
+                  C( J, J ) = DBLE( C( J, J ) )
+               END IF
+               DO 170 L = 1, K
+                  IF( A( J, L ).NE.DCMPLX( ZERO ) ) THEN
+                     TEMP = ALPHA*DCONJG( A( J, L ) )
+                     C( J, J ) = DBLE( C( J, J ) ) +
+     $                           DBLE( TEMP*A( J, L ) )
+                     DO 160 I = J + 1, N
+                        C( I, J ) = C( I, J ) + TEMP*A( I, L )
+  160                CONTINUE
+                  END IF
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+      ELSE
+*
+*        Form  C := alpha*conjg( A' )*A + beta*C.
+*
+         IF( UPPER ) THEN
+            DO 220 J = 1, N
+               DO 200 I = 1, J - 1
+                  TEMP = ZERO
+                  DO 190 L = 1, K
+                     TEMP = TEMP + DCONJG( A( L, I ) )*A( L, J )
+  190             CONTINUE
+                  IF( BETA.EQ.ZERO ) THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  200          CONTINUE
+               RTEMP = ZERO
+               DO 210 L = 1, K
+                  RTEMP = RTEMP + DCONJG( A( L, J ) )*A( L, J )
+  210          CONTINUE
+               IF( BETA.EQ.ZERO ) THEN
+                  C( J, J ) = ALPHA*RTEMP
+               ELSE
+                  C( J, J ) = ALPHA*RTEMP + BETA*DBLE( C( J, J ) )
+               END IF
+  220       CONTINUE
+         ELSE
+            DO 260 J = 1, N
+               RTEMP = ZERO
+               DO 230 L = 1, K
+                  RTEMP = RTEMP + DCONJG( A( L, J ) )*A( L, J )
+  230          CONTINUE
+               IF( BETA.EQ.ZERO ) THEN
+                  C( J, J ) = ALPHA*RTEMP
+               ELSE
+                  C( J, J ) = ALPHA*RTEMP + BETA*DBLE( C( J, J ) )
+               END IF
+               DO 250 I = J + 1, N
+                  TEMP = ZERO
+                  DO 240 L = 1, K
+                     TEMP = TEMP + DCONJG( A( L, I ) )*A( L, J )
+  240             CONTINUE
+                  IF( BETA.EQ.ZERO ) THEN
+                     C( I, J ) = ALPHA*TEMP
+                  ELSE
+                     C( I, J ) = ALPHA*TEMP + BETA*C( I, J )
+                  END IF
+  250          CONTINUE
+  260       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHERK .
+*
+      END
diff --git a/libcruft/blas/zscal.f b/libcruft/blas/zscal.f
new file mode 100644
index 0000000..6fa8576
--- /dev/null
+++ b/libcruft/blas/zscal.f
@@ -0,0 +1,29 @@
+      subroutine  zscal(n,za,zx,incx)
+c
+c     scales a vector by a constant.
+c     jack dongarra, 3/11/78.
+c     modified 3/93 to return if incx .le. 0.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex za,zx(*)
+      integer i,incx,ix,n
+c
+      if( n.le.0 .or. incx.le.0 )return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      ix = 1
+      do 10 i = 1,n
+        zx(ix) = za*zx(ix)
+        ix = ix + incx
+   10 continue
+      return
+c
+c        code for increment equal to 1
+c
+   20 do 30 i = 1,n
+        zx(i) = za*zx(i)
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/zswap.f b/libcruft/blas/zswap.f
new file mode 100644
index 0000000..f28a4e4
--- /dev/null
+++ b/libcruft/blas/zswap.f
@@ -0,0 +1,36 @@
+      subroutine  zswap (n,zx,incx,zy,incy)
+c
+c     interchanges two vectors.
+c     jack dongarra, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*),zy(*),ztemp
+      integer i,incx,incy,ix,iy,n
+c
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c       code for unequal increments or equal increments not equal
+c         to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        ztemp = zx(ix)
+        zx(ix) = zy(iy)
+        zy(iy) = ztemp
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+c
+c       code for both increments equal to 1
+   20 do 30 i = 1,n
+        ztemp = zx(i)
+        zx(i) = zy(i)
+        zy(i) = ztemp
+   30 continue
+      return
+      end
diff --git a/libcruft/blas/zsyrk.f b/libcruft/blas/zsyrk.f
new file mode 100644
index 0000000..0e0d7ce
--- /dev/null
+++ b/libcruft/blas/zsyrk.f
@@ -0,0 +1,294 @@
+      SUBROUTINE ZSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*     .. Scalar Arguments ..
+      DOUBLE COMPLEX ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE COMPLEX A(LDA,*),C(LDC,*)
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZSYRK  performs one of the symmetric rank k operations
+*
+*     C := alpha*A*A' + beta*C,
+*
+*  or
+*
+*     C := alpha*A'*A + beta*C,
+*
+*  where  alpha and beta  are scalars,  C is an  n by n symmetric matrix
+*  and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*  in the second case.
+*
+*  Arguments
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*           triangular  part  of the  array  C  is to be  referenced  as
+*           follows:
+*
+*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*                                  is to be referenced.
+*
+*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*                                  is to be referenced.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry,  TRANS  specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   C := alpha*A*A' + beta*C.
+*
+*              TRANS = 'T' or 't'   C := alpha*A'*A + beta*C.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry,  N specifies the order of the matrix C.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*           of  columns   of  the   matrix   A,   and  on   entry   with
+*           TRANS = 'T' or 't',  K  specifies  the number of rows of the
+*           matrix A.  K must be at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry, ALPHA specifies the scalar alpha.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, ka ), where ka is
+*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*           part of the array  A  must contain the matrix  A,  otherwise
+*           the leading  k by n  part of the array  A  must contain  the
+*           matrix A.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*           be at least  max( 1, k ).
+*           Unchanged on exit.
+*
+*  BETA   - COMPLEX*16      .
+*           On entry, BETA specifies the scalar beta.
+*           Unchanged on exit.
+*
+*  C      - COMPLEX*16       array of DIMENSION ( LDC, n ).
+*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*           upper triangular part of the array C must contain the upper
+*           triangular part  of the  symmetric matrix  and the strictly
+*           lower triangular part of C is not referenced.  On exit, the
+*           upper triangular part of the array  C is overwritten by the
+*           upper triangular part of the updated matrix.
+*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*           lower triangular part of the array C must contain the lower
+*           triangular part  of the  symmetric matrix  and the strictly
+*           upper triangular part of C is not referenced.  On exit, the
+*           lower triangular part of the array  C is overwritten by the
+*           lower triangular part of the updated matrix.
+*
+*  LDC    - INTEGER.
+*           On entry, LDC specifies the first dimension of C as declared
+*           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE COMPLEX TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE COMPLEX ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      DOUBLE COMPLEX ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A' + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A'*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZSYRK .
+*
+      END
diff --git a/libcruft/blas/ztbsv.f b/libcruft/blas/ztbsv.f
new file mode 100644
index 0000000..f3ded81
--- /dev/null
+++ b/libcruft/blas/ztbsv.f
@@ -0,0 +1,381 @@
+      SUBROUTINE ZTBSV ( UPLO, TRANS, DIAG, N, K, A, LDA, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER            INCX, K, LDA, N
+      CHARACTER*1        DIAG, TRANS, UPLO
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTBSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,   or   conjg( A' )*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*  diagonals.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   conjg( A' )*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  K      - INTEGER.
+*           On entry with UPLO = 'U' or 'u', K specifies the number of
+*           super-diagonals of the matrix A.
+*           On entry with UPLO = 'L' or 'l', K specifies the number of
+*           sub-diagonals of the matrix A.
+*           K must satisfy  0 .le. K.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*           by n part of the array A must contain the upper triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row
+*           ( k + 1 ) of the array, the first super-diagonal starting at
+*           position 2 in row k, and so on. The top left k by k triangle
+*           of the array A is not referenced.
+*           The following program segment will transfer an upper
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = K + 1 - J
+*                    DO 10, I = MAX( 1, J - K ), J
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*           by n part of the array A must contain the lower triangular
+*           band part of the matrix of coefficients, supplied column by
+*           column, with the leading diagonal of the matrix in row 1 of
+*           the array, the first sub-diagonal starting at position 1 in
+*           row 2, and so on. The bottom right k by k triangle of the
+*           array A is not referenced.
+*           The following program segment will transfer a lower
+*           triangular band matrix from conventional full matrix storage
+*           to band storage:
+*
+*                 DO 20, J = 1, N
+*                    M = 1 - J
+*                    DO 10, I = J, MIN( N, J + K )
+*                       A( M + I, J ) = matrix( I, J )
+*              10    CONTINUE
+*              20 CONTINUE
+*
+*           Note that when DIAG = 'U' or 'u' the elements of the array A
+*           corresponding to the diagonal elements of the matrix are not
+*           referenced, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           ( k + 1 ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, J, JX, KPLUS1, KX, L
+      LOGICAL            NOCONJ, NOUNIT
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO , 'U' ).AND.
+     $         .NOT.LSAME( UPLO , 'L' )      )THEN
+         INFO = 1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 2
+      ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
+     $         .NOT.LSAME( DIAG , 'N' )      )THEN
+         INFO = 3
+      ELSE IF( N.LT.0 )THEN
+         INFO = 4
+      ELSE IF( K.LT.0 )THEN
+         INFO = 5
+      ELSE IF( LDA.LT.( K + 1 ) )THEN
+         INFO = 7
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZTBSV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      NOCONJ = LSAME( TRANS, 'T' )
+      NOUNIT = LSAME( DIAG , 'N' )
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  x := inv( A )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            KPLUS1 = K + 1
+            IF( INCX.EQ.1 )THEN
+               DO 20, J = N, 1, -1
+                  IF( X( J ).NE.ZERO )THEN
+                     L = KPLUS1 - J
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( KPLUS1, J )
+                     TEMP = X( J )
+                     DO 10, I = J - 1, MAX( 1, J - K ), -1
+                        X( I ) = X( I ) - TEMP*A( L + I, J )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 40, J = N, 1, -1
+                  KX = KX - INCX
+                  IF( X( JX ).NE.ZERO )THEN
+                     IX = KX
+                     L  = KPLUS1 - J
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( KPLUS1, J )
+                     TEMP = X( JX )
+                     DO 30, I = J - 1, MAX( 1, J - K ), -1
+                        X( IX ) = X( IX ) - TEMP*A( L + I, J )
+                        IX      = IX      - INCX
+   30                CONTINUE
+                  END IF
+                  JX = JX - INCX
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 60, J = 1, N
+                  IF( X( J ).NE.ZERO )THEN
+                     L = 1 - J
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( 1, J )
+                     TEMP = X( J )
+                     DO 50, I = J + 1, MIN( N, J + K )
+                        X( I ) = X( I ) - TEMP*A( L + I, J )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE
+               JX = KX
+               DO 80, J = 1, N
+                  KX = KX + INCX
+                  IF( X( JX ).NE.ZERO )THEN
+                     IX = KX
+                     L  = 1  - J
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( 1, J )
+                     TEMP = X( JX )
+                     DO 70, I = J + 1, MIN( N, J + K )
+                        X( IX ) = X( IX ) - TEMP*A( L + I, J )
+                        IX      = IX      + INCX
+   70                CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE
+*
+*        Form  x := inv( A' )*x  or  x := inv( conjg( A') )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            KPLUS1 = K + 1
+            IF( INCX.EQ.1 )THEN
+               DO 110, J = 1, N
+                  TEMP = X( J )
+                  L    = KPLUS1 - J
+                  IF( NOCONJ )THEN
+                     DO 90, I = MAX( 1, J - K ), J - 1
+                        TEMP = TEMP - A( L + I, J )*X( I )
+   90                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( KPLUS1, J )
+                  ELSE
+                     DO 100, I = MAX( 1, J - K ), J - 1
+                        TEMP = TEMP - DCONJG( A( L + I, J ) )*X( I )
+  100                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( KPLUS1, J ) )
+                  END IF
+                  X( J ) = TEMP
+  110          CONTINUE
+            ELSE
+               JX = KX
+               DO 140, J = 1, N
+                  TEMP = X( JX )
+                  IX   = KX
+                  L    = KPLUS1  - J
+                  IF( NOCONJ )THEN
+                     DO 120, I = MAX( 1, J - K ), J - 1
+                        TEMP = TEMP - A( L + I, J )*X( IX )
+                        IX   = IX   + INCX
+  120                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( KPLUS1, J )
+                  ELSE
+                     DO 130, I = MAX( 1, J - K ), J - 1
+                        TEMP = TEMP - DCONJG( A( L + I, J ) )*X( IX )
+                        IX   = IX   + INCX
+  130                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( KPLUS1, J ) )
+                  END IF
+                  X( JX ) = TEMP
+                  JX      = JX   + INCX
+                  IF( J.GT.K )
+     $               KX = KX + INCX
+  140          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 170, J = N, 1, -1
+                  TEMP = X( J )
+                  L    = 1      - J
+                  IF( NOCONJ )THEN
+                     DO 150, I = MIN( N, J + K ), J + 1, -1
+                        TEMP = TEMP - A( L + I, J )*X( I )
+  150                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( 1, J )
+                  ELSE
+                     DO 160, I = MIN( N, J + K ), J + 1, -1
+                        TEMP = TEMP - DCONJG( A( L + I, J ) )*X( I )
+  160                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( 1, J ) )
+                  END IF
+                  X( J ) = TEMP
+  170          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 200, J = N, 1, -1
+                  TEMP = X( JX )
+                  IX   = KX
+                  L    = 1       - J
+                  IF( NOCONJ )THEN
+                     DO 180, I = MIN( N, J + K ), J + 1, -1
+                        TEMP = TEMP - A( L + I, J )*X( IX )
+                        IX   = IX   - INCX
+  180                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( 1, J )
+                  ELSE
+                     DO 190, I = MIN( N, J + K ), J + 1, -1
+                        TEMP = TEMP - DCONJG( A( L + I, J ) )*X( IX )
+                        IX   = IX   - INCX
+  190                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( 1, J ) )
+                  END IF
+                  X( JX ) = TEMP
+                  JX      = JX   - INCX
+                  IF( ( N - J ).GE.K )
+     $               KX = KX - INCX
+  200          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTBSV .
+*
+      END
diff --git a/libcruft/blas/ztrmm.f b/libcruft/blas/ztrmm.f
new file mode 100644
index 0000000..30910d1
--- /dev/null
+++ b/libcruft/blas/ztrmm.f
@@ -0,0 +1,392 @@
+      SUBROUTINE ZTRMM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA,
+     $                   B, LDB )
+*     .. Scalar Arguments ..
+      CHARACTER*1        SIDE, UPLO, TRANSA, DIAG
+      INTEGER            M, N, LDA, LDB
+      COMPLEX*16         ALPHA
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRMM  performs one of the matrix-matrix operations
+*
+*     B := alpha*op( A )*B,   or   B := alpha*B*op( A )
+*
+*  where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'   or   op( A ) = conjg( A' ).
+*
+*  Parameters
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*           the left or right as follows:
+*
+*              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*
+*              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = conjg( A' ).
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX*16       array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain the matrix  B,  and  on exit  is overwritten  by the
+*           transformed matrix.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     .. Local Scalars ..
+      LOGICAL            LSIDE, NOCONJ, NOUNIT, UPPER
+      INTEGER            I, INFO, J, K, NROWA
+      COMPLEX*16         TEMP
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER        ( ONE  = ( 1.0D+0, 0.0D+0 ) )
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      LSIDE  = LSAME( SIDE  , 'L' )
+      IF( LSIDE )THEN
+         NROWA = M
+      ELSE
+         NROWA = N
+      END IF
+      NOCONJ = LSAME( TRANSA, 'T' )
+      NOUNIT = LSAME( DIAG  , 'N' )
+      UPPER  = LSAME( UPLO  , 'U' )
+*
+      INFO   = 0
+      IF(      ( .NOT.LSIDE                ).AND.
+     $         ( .NOT.LSAME( SIDE  , 'R' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.UPPER                ).AND.
+     $         ( .NOT.LSAME( UPLO  , 'L' ) )      )THEN
+         INFO = 2
+      ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'T' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'C' ) )      )THEN
+         INFO = 3
+      ELSE IF( ( .NOT.LSAME( DIAG  , 'U' ) ).AND.
+     $         ( .NOT.LSAME( DIAG  , 'N' ) )      )THEN
+         INFO = 4
+      ELSE IF( M  .LT.0               )THEN
+         INFO = 5
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 6
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 9
+      ELSE IF( LDB.LT.MAX( 1, M     ) )THEN
+         INFO = 11
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZTRMM ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         DO 20, J = 1, N
+            DO 10, I = 1, M
+               B( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSIDE )THEN
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*A*B.
+*
+            IF( UPPER )THEN
+               DO 50, J = 1, N
+                  DO 40, K = 1, M
+                     IF( B( K, J ).NE.ZERO )THEN
+                        TEMP = ALPHA*B( K, J )
+                        DO 30, I = 1, K - 1
+                           B( I, J ) = B( I, J ) + TEMP*A( I, K )
+   30                   CONTINUE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP*A( K, K )
+                        B( K, J ) = TEMP
+                     END IF
+   40             CONTINUE
+   50          CONTINUE
+            ELSE
+               DO 80, J = 1, N
+                  DO 70 K = M, 1, -1
+                     IF( B( K, J ).NE.ZERO )THEN
+                        TEMP      = ALPHA*B( K, J )
+                        B( K, J ) = TEMP
+                        IF( NOUNIT )
+     $                     B( K, J ) = B( K, J )*A( K, K )
+                        DO 60, I = K + 1, M
+                           B( I, J ) = B( I, J ) + TEMP*A( I, K )
+   60                   CONTINUE
+                     END IF
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*A'*B   or   B := alpha*conjg( A' )*B.
+*
+            IF( UPPER )THEN
+               DO 120, J = 1, N
+                  DO 110, I = M, 1, -1
+                     TEMP = B( I, J )
+                     IF( NOCONJ )THEN
+                        IF( NOUNIT )
+     $                     TEMP = TEMP*A( I, I )
+                        DO 90, K = 1, I - 1
+                           TEMP = TEMP + A( K, I )*B( K, J )
+   90                   CONTINUE
+                     ELSE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP*DCONJG( A( I, I ) )
+                        DO 100, K = 1, I - 1
+                           TEMP = TEMP + DCONJG( A( K, I ) )*B( K, J )
+  100                   CONTINUE
+                     END IF
+                     B( I, J ) = ALPHA*TEMP
+  110             CONTINUE
+  120          CONTINUE
+            ELSE
+               DO 160, J = 1, N
+                  DO 150, I = 1, M
+                     TEMP = B( I, J )
+                     IF( NOCONJ )THEN
+                        IF( NOUNIT )
+     $                     TEMP = TEMP*A( I, I )
+                        DO 130, K = I + 1, M
+                           TEMP = TEMP + A( K, I )*B( K, J )
+  130                   CONTINUE
+                     ELSE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP*DCONJG( A( I, I ) )
+                        DO 140, K = I + 1, M
+                           TEMP = TEMP + DCONJG( A( K, I ) )*B( K, J )
+  140                   CONTINUE
+                     END IF
+                     B( I, J ) = ALPHA*TEMP
+  150             CONTINUE
+  160          CONTINUE
+            END IF
+         END IF
+      ELSE
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*B*A.
+*
+            IF( UPPER )THEN
+               DO 200, J = N, 1, -1
+                  TEMP = ALPHA
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 170, I = 1, M
+                     B( I, J ) = TEMP*B( I, J )
+  170             CONTINUE
+                  DO 190, K = 1, J - 1
+                     IF( A( K, J ).NE.ZERO )THEN
+                        TEMP = ALPHA*A( K, J )
+                        DO 180, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  180                   CONTINUE
+                     END IF
+  190             CONTINUE
+  200          CONTINUE
+            ELSE
+               DO 240, J = 1, N
+                  TEMP = ALPHA
+                  IF( NOUNIT )
+     $               TEMP = TEMP*A( J, J )
+                  DO 210, I = 1, M
+                     B( I, J ) = TEMP*B( I, J )
+  210             CONTINUE
+                  DO 230, K = J + 1, N
+                     IF( A( K, J ).NE.ZERO )THEN
+                        TEMP = ALPHA*A( K, J )
+                        DO 220, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  220                   CONTINUE
+                     END IF
+  230             CONTINUE
+  240          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*B*A'   or   B := alpha*B*conjg( A' ).
+*
+            IF( UPPER )THEN
+               DO 280, K = 1, N
+                  DO 260, J = 1, K - 1
+                     IF( A( J, K ).NE.ZERO )THEN
+                        IF( NOCONJ )THEN
+                           TEMP = ALPHA*A( J, K )
+                        ELSE
+                           TEMP = ALPHA*DCONJG( A( J, K ) )
+                        END IF
+                        DO 250, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  250                   CONTINUE
+                     END IF
+  260             CONTINUE
+                  TEMP = ALPHA
+                  IF( NOUNIT )THEN
+                     IF( NOCONJ )THEN
+                        TEMP = TEMP*A( K, K )
+                     ELSE
+                        TEMP = TEMP*DCONJG( A( K, K ) )
+                     END IF
+                  END IF
+                  IF( TEMP.NE.ONE )THEN
+                     DO 270, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  270                CONTINUE
+                  END IF
+  280          CONTINUE
+            ELSE
+               DO 320, K = N, 1, -1
+                  DO 300, J = K + 1, N
+                     IF( A( J, K ).NE.ZERO )THEN
+                        IF( NOCONJ )THEN
+                           TEMP = ALPHA*A( J, K )
+                        ELSE
+                           TEMP = ALPHA*DCONJG( A( J, K ) )
+                        END IF
+                        DO 290, I = 1, M
+                           B( I, J ) = B( I, J ) + TEMP*B( I, K )
+  290                   CONTINUE
+                     END IF
+  300             CONTINUE
+                  TEMP = ALPHA
+                  IF( NOUNIT )THEN
+                     IF( NOCONJ )THEN
+                        TEMP = TEMP*A( K, K )
+                     ELSE
+                        TEMP = TEMP*DCONJG( A( K, K ) )
+                     END IF
+                  END IF
+                  IF( TEMP.NE.ONE )THEN
+                     DO 310, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  310                CONTINUE
+                  END IF
+  320          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRMM .
+*
+      END
diff --git a/libcruft/blas/ztrmv.f b/libcruft/blas/ztrmv.f
new file mode 100644
index 0000000..677e212
--- /dev/null
+++ b/libcruft/blas/ztrmv.f
@@ -0,0 +1,321 @@
+      SUBROUTINE ZTRMV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER            INCX, LDA, N
+      CHARACTER*1        DIAG, TRANS, UPLO
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRMV  performs one of the matrix-vector operations
+*
+*     x := A*x,   or   x := A'*x,   or   x := conjg( A' )*x,
+*
+*  where x is an n element vector and  A is an n by n unit, or non-unit,
+*  upper or lower triangular matrix.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the operation to be performed as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   x := A*x.
+*
+*              TRANS = 'T' or 't'   x := A'*x.
+*
+*              TRANS = 'C' or 'c'   x := conjg( A' )*x.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element vector x. On exit, X is overwritten with the
+*           tranformed vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, J, JX, KX
+      LOGICAL            NOCONJ, NOUNIT
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO , 'U' ).AND.
+     $         .NOT.LSAME( UPLO , 'L' )      )THEN
+         INFO = 1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 2
+      ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
+     $         .NOT.LSAME( DIAG , 'N' )      )THEN
+         INFO = 3
+      ELSE IF( N.LT.0 )THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 6
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 8
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZTRMV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      NOCONJ = LSAME( TRANS, 'T' )
+      NOUNIT = LSAME( DIAG , 'N' )
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  x := A*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 20, J = 1, N
+                  IF( X( J ).NE.ZERO )THEN
+                     TEMP = X( J )
+                     DO 10, I = 1, J - 1
+                        X( I ) = X( I ) + TEMP*A( I, J )
+   10                CONTINUE
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )*A( J, J )
+                  END IF
+   20          CONTINUE
+            ELSE
+               JX = KX
+               DO 40, J = 1, N
+                  IF( X( JX ).NE.ZERO )THEN
+                     TEMP = X( JX )
+                     IX   = KX
+                     DO 30, I = 1, J - 1
+                        X( IX ) = X( IX ) + TEMP*A( I, J )
+                        IX      = IX      + INCX
+   30                CONTINUE
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )*A( J, J )
+                  END IF
+                  JX = JX + INCX
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 60, J = N, 1, -1
+                  IF( X( J ).NE.ZERO )THEN
+                     TEMP = X( J )
+                     DO 50, I = N, J + 1, -1
+                        X( I ) = X( I ) + TEMP*A( I, J )
+   50                CONTINUE
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )*A( J, J )
+                  END IF
+   60          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 80, J = N, 1, -1
+                  IF( X( JX ).NE.ZERO )THEN
+                     TEMP = X( JX )
+                     IX   = KX
+                     DO 70, I = N, J + 1, -1
+                        X( IX ) = X( IX ) + TEMP*A( I, J )
+                        IX      = IX      - INCX
+   70                CONTINUE
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )*A( J, J )
+                  END IF
+                  JX = JX - INCX
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE
+*
+*        Form  x := A'*x  or  x := conjg( A' )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 110, J = N, 1, -1
+                  TEMP = X( J )
+                  IF( NOCONJ )THEN
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*A( J, J )
+                     DO 90, I = J - 1, 1, -1
+                        TEMP = TEMP + A( I, J )*X( I )
+   90                CONTINUE
+                  ELSE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*DCONJG( A( J, J ) )
+                     DO 100, I = J - 1, 1, -1
+                        TEMP = TEMP + DCONJG( A( I, J ) )*X( I )
+  100                CONTINUE
+                  END IF
+                  X( J ) = TEMP
+  110          CONTINUE
+            ELSE
+               JX = KX + ( N - 1 )*INCX
+               DO 140, J = N, 1, -1
+                  TEMP = X( JX )
+                  IX   = JX
+                  IF( NOCONJ )THEN
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*A( J, J )
+                     DO 120, I = J - 1, 1, -1
+                        IX   = IX   - INCX
+                        TEMP = TEMP + A( I, J )*X( IX )
+  120                CONTINUE
+                  ELSE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*DCONJG( A( J, J ) )
+                     DO 130, I = J - 1, 1, -1
+                        IX   = IX   - INCX
+                        TEMP = TEMP + DCONJG( A( I, J ) )*X( IX )
+  130                CONTINUE
+                  END IF
+                  X( JX ) = TEMP
+                  JX      = JX   - INCX
+  140          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 170, J = 1, N
+                  TEMP = X( J )
+                  IF( NOCONJ )THEN
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*A( J, J )
+                     DO 150, I = J + 1, N
+                        TEMP = TEMP + A( I, J )*X( I )
+  150                CONTINUE
+                  ELSE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*DCONJG( A( J, J ) )
+                     DO 160, I = J + 1, N
+                        TEMP = TEMP + DCONJG( A( I, J ) )*X( I )
+  160                CONTINUE
+                  END IF
+                  X( J ) = TEMP
+  170          CONTINUE
+            ELSE
+               JX = KX
+               DO 200, J = 1, N
+                  TEMP = X( JX )
+                  IX   = JX
+                  IF( NOCONJ )THEN
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*A( J, J )
+                     DO 180, I = J + 1, N
+                        IX   = IX   + INCX
+                        TEMP = TEMP + A( I, J )*X( IX )
+  180                CONTINUE
+                  ELSE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP*DCONJG( A( J, J ) )
+                     DO 190, I = J + 1, N
+                        IX   = IX   + INCX
+                        TEMP = TEMP + DCONJG( A( I, J ) )*X( IX )
+  190                CONTINUE
+                  END IF
+                  X( JX ) = TEMP
+                  JX      = JX   + INCX
+  200          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRMV .
+*
+      END
diff --git a/libcruft/blas/ztrsm.f b/libcruft/blas/ztrsm.f
new file mode 100644
index 0000000..e414ec6
--- /dev/null
+++ b/libcruft/blas/ztrsm.f
@@ -0,0 +1,414 @@
+      SUBROUTINE ZTRSM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA,
+     $                   B, LDB )
+*     .. Scalar Arguments ..
+      CHARACTER*1        SIDE, UPLO, TRANSA, DIAG
+      INTEGER            M, N, LDA, LDB
+      COMPLEX*16         ALPHA
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRSM  solves one of the matrix equations
+*
+*     op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*
+*  where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*  non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*
+*     op( A ) = A   or   op( A ) = A'   or   op( A ) = conjg( A' ).
+*
+*  The matrix X is overwritten on B.
+*
+*  Parameters
+*  ==========
+*
+*  SIDE   - CHARACTER*1.
+*           On entry, SIDE specifies whether op( A ) appears on the left
+*           or right of X as follows:
+*
+*              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*
+*              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*
+*           Unchanged on exit.
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix A is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANSA - CHARACTER*1.
+*           On entry, TRANSA specifies the form of op( A ) to be used in
+*           the matrix multiplication as follows:
+*
+*              TRANSA = 'N' or 'n'   op( A ) = A.
+*
+*              TRANSA = 'T' or 't'   op( A ) = A'.
+*
+*              TRANSA = 'C' or 'c'   op( A ) = conjg( A' ).
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit triangular
+*           as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  M      - INTEGER.
+*           On entry, M specifies the number of rows of B. M must be at
+*           least zero.
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the number of columns of B.  N must be
+*           at least zero.
+*           Unchanged on exit.
+*
+*  ALPHA  - COMPLEX*16      .
+*           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*           zero then  A is not referenced and  B need not be set before
+*           entry.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, k ), where k is m
+*           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*           upper triangular part of the array  A must contain the upper
+*           triangular matrix  and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*           lower triangular part of the array  A must contain the lower
+*           triangular matrix  and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*           A  are not referenced either,  but are assumed to be  unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*           then LDA must be at least max( 1, n ).
+*           Unchanged on exit.
+*
+*  B      - COMPLEX*16       array of DIMENSION ( LDB, n ).
+*           Before entry,  the leading  m by n part of the array  B must
+*           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*           overwritten by the solution matrix  X.
+*
+*  LDB    - INTEGER.
+*           On entry, LDB specifies the first dimension of B as declared
+*           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*           max( 1, m ).
+*           Unchanged on exit.
+*
+*
+*  Level 3 Blas routine.
+*
+*  -- Written on 8-February-1989.
+*     Jack Dongarra, Argonne National Laboratory.
+*     Iain Duff, AERE Harwell.
+*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*     Sven Hammarling, Numerical Algorithms Group Ltd.
+*
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     .. Local Scalars ..
+      LOGICAL            LSIDE, NOCONJ, NOUNIT, UPPER
+      INTEGER            I, INFO, J, K, NROWA
+      COMPLEX*16         TEMP
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER        ( ONE  = ( 1.0D+0, 0.0D+0 ) )
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      LSIDE  = LSAME( SIDE  , 'L' )
+      IF( LSIDE )THEN
+         NROWA = M
+      ELSE
+         NROWA = N
+      END IF
+      NOCONJ = LSAME( TRANSA, 'T' )
+      NOUNIT = LSAME( DIAG  , 'N' )
+      UPPER  = LSAME( UPLO  , 'U' )
+*
+      INFO   = 0
+      IF(      ( .NOT.LSIDE                ).AND.
+     $         ( .NOT.LSAME( SIDE  , 'R' ) )      )THEN
+         INFO = 1
+      ELSE IF( ( .NOT.UPPER                ).AND.
+     $         ( .NOT.LSAME( UPLO  , 'L' ) )      )THEN
+         INFO = 2
+      ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'T' ) ).AND.
+     $         ( .NOT.LSAME( TRANSA, 'C' ) )      )THEN
+         INFO = 3
+      ELSE IF( ( .NOT.LSAME( DIAG  , 'U' ) ).AND.
+     $         ( .NOT.LSAME( DIAG  , 'N' ) )      )THEN
+         INFO = 4
+      ELSE IF( M  .LT.0               )THEN
+         INFO = 5
+      ELSE IF( N  .LT.0               )THEN
+         INFO = 6
+      ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
+         INFO = 9
+      ELSE IF( LDB.LT.MAX( 1, M     ) )THEN
+         INFO = 11
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZTRSM ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF( ALPHA.EQ.ZERO )THEN
+         DO 20, J = 1, N
+            DO 10, I = 1, M
+               B( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+         RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF( LSIDE )THEN
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+            IF( UPPER )THEN
+               DO 60, J = 1, N
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 30, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+   30                CONTINUE
+                  END IF
+                  DO 50, K = M, 1, -1
+                     IF( B( K, J ).NE.ZERO )THEN
+                        IF( NOUNIT )
+     $                     B( K, J ) = B( K, J )/A( K, K )
+                        DO 40, I = 1, K - 1
+                           B( I, J ) = B( I, J ) - B( K, J )*A( I, K )
+   40                   CONTINUE
+                     END IF
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 100, J = 1, N
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 70, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+   70                CONTINUE
+                  END IF
+                  DO 90 K = 1, M
+                     IF( B( K, J ).NE.ZERO )THEN
+                        IF( NOUNIT )
+     $                     B( K, J ) = B( K, J )/A( K, K )
+                        DO 80, I = K + 1, M
+                           B( I, J ) = B( I, J ) - B( K, J )*A( I, K )
+   80                   CONTINUE
+                     END IF
+   90             CONTINUE
+  100          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*inv( A' )*B
+*           or    B := alpha*inv( conjg( A' ) )*B.
+*
+            IF( UPPER )THEN
+               DO 140, J = 1, N
+                  DO 130, I = 1, M
+                     TEMP = ALPHA*B( I, J )
+                     IF( NOCONJ )THEN
+                        DO 110, K = 1, I - 1
+                           TEMP = TEMP - A( K, I )*B( K, J )
+  110                   CONTINUE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP/A( I, I )
+                     ELSE
+                        DO 120, K = 1, I - 1
+                           TEMP = TEMP - DCONJG( A( K, I ) )*B( K, J )
+  120                   CONTINUE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP/DCONJG( A( I, I ) )
+                     END IF
+                     B( I, J ) = TEMP
+  130             CONTINUE
+  140          CONTINUE
+            ELSE
+               DO 180, J = 1, N
+                  DO 170, I = M, 1, -1
+                     TEMP = ALPHA*B( I, J )
+                     IF( NOCONJ )THEN
+                        DO 150, K = I + 1, M
+                           TEMP = TEMP - A( K, I )*B( K, J )
+  150                   CONTINUE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP/A( I, I )
+                     ELSE
+                        DO 160, K = I + 1, M
+                           TEMP = TEMP - DCONJG( A( K, I ) )*B( K, J )
+  160                   CONTINUE
+                        IF( NOUNIT )
+     $                     TEMP = TEMP/DCONJG( A( I, I ) )
+                     END IF
+                     B( I, J ) = TEMP
+  170             CONTINUE
+  180          CONTINUE
+            END IF
+         END IF
+      ELSE
+         IF( LSAME( TRANSA, 'N' ) )THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+            IF( UPPER )THEN
+               DO 230, J = 1, N
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 190, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+  190                CONTINUE
+                  END IF
+                  DO 210, K = 1, J - 1
+                     IF( A( K, J ).NE.ZERO )THEN
+                        DO 200, I = 1, M
+                           B( I, J ) = B( I, J ) - A( K, J )*B( I, K )
+  200                   CONTINUE
+                     END IF
+  210             CONTINUE
+                  IF( NOUNIT )THEN
+                     TEMP = ONE/A( J, J )
+                     DO 220, I = 1, M
+                        B( I, J ) = TEMP*B( I, J )
+  220                CONTINUE
+                  END IF
+  230          CONTINUE
+            ELSE
+               DO 280, J = N, 1, -1
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 240, I = 1, M
+                        B( I, J ) = ALPHA*B( I, J )
+  240                CONTINUE
+                  END IF
+                  DO 260, K = J + 1, N
+                     IF( A( K, J ).NE.ZERO )THEN
+                        DO 250, I = 1, M
+                           B( I, J ) = B( I, J ) - A( K, J )*B( I, K )
+  250                   CONTINUE
+                     END IF
+  260             CONTINUE
+                  IF( NOUNIT )THEN
+                     TEMP = ONE/A( J, J )
+                     DO 270, I = 1, M
+                       B( I, J ) = TEMP*B( I, J )
+  270                CONTINUE
+                  END IF
+  280          CONTINUE
+            END IF
+         ELSE
+*
+*           Form  B := alpha*B*inv( A' )
+*           or    B := alpha*B*inv( conjg( A' ) ).
+*
+            IF( UPPER )THEN
+               DO 330, K = N, 1, -1
+                  IF( NOUNIT )THEN
+                     IF( NOCONJ )THEN
+                        TEMP = ONE/A( K, K )
+                     ELSE
+                        TEMP = ONE/DCONJG( A( K, K ) )
+                     END IF
+                     DO 290, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  290                CONTINUE
+                  END IF
+                  DO 310, J = 1, K - 1
+                     IF( A( J, K ).NE.ZERO )THEN
+                        IF( NOCONJ )THEN
+                           TEMP = A( J, K )
+                        ELSE
+                           TEMP = DCONJG( A( J, K ) )
+                        END IF
+                        DO 300, I = 1, M
+                           B( I, J ) = B( I, J ) - TEMP*B( I, K )
+  300                   CONTINUE
+                     END IF
+  310             CONTINUE
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 320, I = 1, M
+                        B( I, K ) = ALPHA*B( I, K )
+  320                CONTINUE
+                  END IF
+  330          CONTINUE
+            ELSE
+               DO 380, K = 1, N
+                  IF( NOUNIT )THEN
+                     IF( NOCONJ )THEN
+                        TEMP = ONE/A( K, K )
+                     ELSE
+                        TEMP = ONE/DCONJG( A( K, K ) )
+                     END IF
+                     DO 340, I = 1, M
+                        B( I, K ) = TEMP*B( I, K )
+  340                CONTINUE
+                  END IF
+                  DO 360, J = K + 1, N
+                     IF( A( J, K ).NE.ZERO )THEN
+                        IF( NOCONJ )THEN
+                           TEMP = A( J, K )
+                        ELSE
+                           TEMP = DCONJG( A( J, K ) )
+                        END IF
+                        DO 350, I = 1, M
+                           B( I, J ) = B( I, J ) - TEMP*B( I, K )
+  350                   CONTINUE
+                     END IF
+  360             CONTINUE
+                  IF( ALPHA.NE.ONE )THEN
+                     DO 370, I = 1, M
+                        B( I, K ) = ALPHA*B( I, K )
+  370                CONTINUE
+                  END IF
+  380          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRSM .
+*
+      END
diff --git a/libcruft/blas/ztrsv.f b/libcruft/blas/ztrsv.f
new file mode 100644
index 0000000..d0a57c4
--- /dev/null
+++ b/libcruft/blas/ztrsv.f
@@ -0,0 +1,324 @@
+      SUBROUTINE ZTRSV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX )
+*     .. Scalar Arguments ..
+      INTEGER            INCX, LDA, N
+      CHARACTER*1        DIAG, TRANS, UPLO
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRSV  solves one of the systems of equations
+*
+*     A*x = b,   or   A'*x = b,   or   conjg( A' )*x = b,
+*
+*  where b and x are n element vectors and A is an n by n unit, or
+*  non-unit, upper or lower triangular matrix.
+*
+*  No test for singularity or near-singularity is included in this
+*  routine. Such tests must be performed before calling this routine.
+*
+*  Parameters
+*  ==========
+*
+*  UPLO   - CHARACTER*1.
+*           On entry, UPLO specifies whether the matrix is an upper or
+*           lower triangular matrix as follows:
+*
+*              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*
+*              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*
+*           Unchanged on exit.
+*
+*  TRANS  - CHARACTER*1.
+*           On entry, TRANS specifies the equations to be solved as
+*           follows:
+*
+*              TRANS = 'N' or 'n'   A*x = b.
+*
+*              TRANS = 'T' or 't'   A'*x = b.
+*
+*              TRANS = 'C' or 'c'   conjg( A' )*x = b.
+*
+*           Unchanged on exit.
+*
+*  DIAG   - CHARACTER*1.
+*           On entry, DIAG specifies whether or not A is unit
+*           triangular as follows:
+*
+*              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*
+*              DIAG = 'N' or 'n'   A is not assumed to be unit
+*                                  triangular.
+*
+*           Unchanged on exit.
+*
+*  N      - INTEGER.
+*           On entry, N specifies the order of the matrix A.
+*           N must be at least zero.
+*           Unchanged on exit.
+*
+*  A      - COMPLEX*16       array of DIMENSION ( LDA, n ).
+*           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*           upper triangular part of the array A must contain the upper
+*           triangular matrix and the strictly lower triangular part of
+*           A is not referenced.
+*           Before entry with UPLO = 'L' or 'l', the leading n by n
+*           lower triangular part of the array A must contain the lower
+*           triangular matrix and the strictly upper triangular part of
+*           A is not referenced.
+*           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*           A are not referenced either, but are assumed to be unity.
+*           Unchanged on exit.
+*
+*  LDA    - INTEGER.
+*           On entry, LDA specifies the first dimension of A as declared
+*           in the calling (sub) program. LDA must be at least
+*           max( 1, n ).
+*           Unchanged on exit.
+*
+*  X      - COMPLEX*16       array of dimension at least
+*           ( 1 + ( n - 1 )*abs( INCX ) ).
+*           Before entry, the incremented array X must contain the n
+*           element right-hand side vector b. On exit, X is overwritten
+*           with the solution vector x.
+*
+*  INCX   - INTEGER.
+*           On entry, INCX specifies the increment for the elements of
+*           X. INCX must not be zero.
+*           Unchanged on exit.
+*
+*
+*  Level 2 Blas routine.
+*
+*  -- Written on 22-October-1986.
+*     Jack Dongarra, Argonne National Lab.
+*     Jeremy Du Croz, Nag Central Office.
+*     Sven Hammarling, Nag Central Office.
+*     Richard Hanson, Sandia National Labs.
+*
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER        ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     .. Local Scalars ..
+      COMPLEX*16         TEMP
+      INTEGER            I, INFO, IX, J, JX, KX
+      LOGICAL            NOCONJ, NOUNIT
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF     ( .NOT.LSAME( UPLO , 'U' ).AND.
+     $         .NOT.LSAME( UPLO , 'L' )      )THEN
+         INFO = 1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
+     $         .NOT.LSAME( TRANS, 'T' ).AND.
+     $         .NOT.LSAME( TRANS, 'C' )      )THEN
+         INFO = 2
+      ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
+     $         .NOT.LSAME( DIAG , 'N' )      )THEN
+         INFO = 3
+      ELSE IF( N.LT.0 )THEN
+         INFO = 4
+      ELSE IF( LDA.LT.MAX( 1, N ) )THEN
+         INFO = 6
+      ELSE IF( INCX.EQ.0 )THEN
+         INFO = 8
+      END IF
+      IF( INFO.NE.0 )THEN
+         CALL XERBLA( 'ZTRSV ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      NOCONJ = LSAME( TRANS, 'T' )
+      NOUNIT = LSAME( DIAG , 'N' )
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF( INCX.LE.0 )THEN
+         KX = 1 - ( N - 1 )*INCX
+      ELSE IF( INCX.NE.1 )THEN
+         KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF( LSAME( TRANS, 'N' ) )THEN
+*
+*        Form  x := inv( A )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 20, J = N, 1, -1
+                  IF( X( J ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( J, J )
+                     TEMP = X( J )
+                     DO 10, I = J - 1, 1, -1
+                        X( I ) = X( I ) - TEMP*A( I, J )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE
+               JX = KX + ( N - 1 )*INCX
+               DO 40, J = N, 1, -1
+                  IF( X( JX ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( J, J )
+                     TEMP = X( JX )
+                     IX   = JX
+                     DO 30, I = J - 1, 1, -1
+                        IX      = IX      - INCX
+                        X( IX ) = X( IX ) - TEMP*A( I, J )
+   30                CONTINUE
+                  END IF
+                  JX = JX - INCX
+   40          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 60, J = 1, N
+                  IF( X( J ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( J ) = X( J )/A( J, J )
+                     TEMP = X( J )
+                     DO 50, I = J + 1, N
+                        X( I ) = X( I ) - TEMP*A( I, J )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE
+               JX = KX
+               DO 80, J = 1, N
+                  IF( X( JX ).NE.ZERO )THEN
+                     IF( NOUNIT )
+     $                  X( JX ) = X( JX )/A( J, J )
+                     TEMP = X( JX )
+                     IX   = JX
+                     DO 70, I = J + 1, N
+                        IX      = IX      + INCX
+                        X( IX ) = X( IX ) - TEMP*A( I, J )
+   70                CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE
+*
+*        Form  x := inv( A' )*x  or  x := inv( conjg( A' ) )*x.
+*
+         IF( LSAME( UPLO, 'U' ) )THEN
+            IF( INCX.EQ.1 )THEN
+               DO 110, J = 1, N
+                  TEMP = X( J )
+                  IF( NOCONJ )THEN
+                     DO 90, I = 1, J - 1
+                        TEMP = TEMP - A( I, J )*X( I )
+   90                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( J, J )
+                  ELSE
+                     DO 100, I = 1, J - 1
+                        TEMP = TEMP - DCONJG( A( I, J ) )*X( I )
+  100                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( J, J ) )
+                  END IF
+                  X( J ) = TEMP
+  110          CONTINUE
+            ELSE
+               JX = KX
+               DO 140, J = 1, N
+                  IX   = KX
+                  TEMP = X( JX )
+                  IF( NOCONJ )THEN
+                     DO 120, I = 1, J - 1
+                        TEMP = TEMP - A( I, J )*X( IX )
+                        IX   = IX   + INCX
+  120                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( J, J )
+                  ELSE
+                     DO 130, I = 1, J - 1
+                        TEMP = TEMP - DCONJG( A( I, J ) )*X( IX )
+                        IX   = IX   + INCX
+  130                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( J, J ) )
+                  END IF
+                  X( JX ) = TEMP
+                  JX      = JX   + INCX
+  140          CONTINUE
+            END IF
+         ELSE
+            IF( INCX.EQ.1 )THEN
+               DO 170, J = N, 1, -1
+                  TEMP = X( J )
+                  IF( NOCONJ )THEN
+                     DO 150, I = N, J + 1, -1
+                        TEMP = TEMP - A( I, J )*X( I )
+  150                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( J, J )
+                  ELSE
+                     DO 160, I = N, J + 1, -1
+                        TEMP = TEMP - DCONJG( A( I, J ) )*X( I )
+  160                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( J, J ) )
+                  END IF
+                  X( J ) = TEMP
+  170          CONTINUE
+            ELSE
+               KX = KX + ( N - 1 )*INCX
+               JX = KX
+               DO 200, J = N, 1, -1
+                  IX   = KX
+                  TEMP = X( JX )
+                  IF( NOCONJ )THEN
+                     DO 180, I = N, J + 1, -1
+                        TEMP = TEMP - A( I, J )*X( IX )
+                        IX   = IX   - INCX
+  180                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/A( J, J )
+                  ELSE
+                     DO 190, I = N, J + 1, -1
+                        TEMP = TEMP - DCONJG( A( I, J ) )*X( IX )
+                        IX   = IX   - INCX
+  190                CONTINUE
+                     IF( NOUNIT )
+     $                  TEMP = TEMP/DCONJG( A( J, J ) )
+                  END IF
+                  X( JX ) = TEMP
+                  JX      = JX   - INCX
+  200          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRSV .
+*
+      END
diff --git a/libcruft/daspk/Makefile.in b/libcruft/daspk/Makefile.in
new file mode 100644
index 0000000..cb5df8d
--- /dev/null
+++ b/libcruft/daspk/Makefile.in
@@ -0,0 +1,36 @@
+# Makefile for octave's libcruft/daspk directory
+#
+# Copyright (C) 2002, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = datv.f dcnst0.f dcnstr.f ddasic.f ddasid.f ddasik.f ddaspk.f \
+  ddstp.f ddwnrm.f dfnrmd.f dfnrmk.f dhels.f dheqr.f dinvwt.f \
+  dlinsd.f dlinsk.f dmatd.f dnedd.f dnedk.f dnsd.f dnsid.f dnsik.f \
+  dnsk.f dorth.f dslvd.f dslvk.f dspigm.f dyypnw.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/daspk/datv.f b/libcruft/daspk/datv.f
new file mode 100644
index 0000000..06e8baa
--- /dev/null
+++ b/libcruft/daspk/datv.f
@@ -0,0 +1,130 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DATV (NEQ, Y, TN, YPRIME, SAVR, V, WGHT, YPTEM, RES,
+     *   IRES, PSOL, Z, VTEM, WP, IWP, CJ, EPLIN, IER, NRE, NPSL,
+     *   RPAR,IPAR)
+C
+C***BEGIN PROLOGUE  DATV
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C This routine computes the product
+C
+C   Z = (D-inverse)*(P-inverse)*(dF/dY)*(D*V),
+C
+C where F(Y) = G(T, Y, CJ*(Y-A)), CJ is a scalar proportional to 1/H,
+C and A involves the past history of Y.  The quantity CJ*(Y-A) is
+C an approximation to the first derivative of Y and is stored
+C in the array YPRIME.  Note that dF/dY = dG/dY + CJ*dG/dYPRIME.
+C
+C D is a diagonal scaling matrix, and P is the left preconditioning
+C matrix.  V is assumed to have L2 norm equal to 1.
+C The product is stored in Z and is computed by means of a
+C difference quotient, a call to RES, and one call to PSOL.
+C
+C      On entry
+C
+C          NEQ = Problem size, passed to RES and PSOL.
+C
+C            Y = Array containing current dependent variable vector.
+C
+C       YPRIME = Array containing current first derivative of y.
+C
+C         SAVR = Array containing current value of G(T,Y,YPRIME).
+C
+C            V = Real array of length NEQ (can be the same array as Z).
+C
+C         WGHT = Array of length NEQ containing scale factors.
+C                1/WGHT(I) are the diagonal elements of the matrix D.
+C
+C        YPTEM = Work array of length NEQ.
+C
+C         VTEM = Work array of length NEQ used to store the
+C                unscaled version of V.
+C
+C         WP = Real work array used by preconditioner PSOL.
+C
+C         IWP = Integer work array used by preconditioner PSOL.
+C
+C           CJ = Scalar proportional to current value of 
+C                1/(step size H).
+C
+C
+C      On return
+C
+C            Z = Array of length NEQ containing desired scaled
+C                matrix-vector product.
+C
+C         IRES = Error flag from RES.
+C
+C          IER = Error flag from PSOL.
+C
+C         NRE  = The number of calls to RES.
+C
+C         NPSL = The number of calls to PSOL.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   RES, PSOL
+C
+C***END PROLOGUE  DATV
+C
+      INTEGER NEQ, IRES, IWP, IER, NRE, NPSL, IPAR
+      DOUBLE PRECISION Y, TN, YPRIME, SAVR, V, WGHT, YPTEM, Z, VTEM,
+     1   WP, CJ, RPAR
+      DIMENSION Y(*), YPRIME(*), SAVR(*), V(*), WGHT(*), YPTEM(*),
+     1   Z(*), VTEM(*), WP(*), IWP(*), RPAR(*), IPAR(*)
+      INTEGER I
+      DOUBLE PRECISION EPLIN
+      EXTERNAL  RES, PSOL
+C
+      IRES = 0
+C-----------------------------------------------------------------------
+C Set VTEM = D * V.
+C-----------------------------------------------------------------------
+      DO 10 I = 1,NEQ
+ 10     VTEM(I) = V(I)/WGHT(I)
+      IER = 0
+C-----------------------------------------------------------------------
+C Store Y in Z and increment Z by VTEM.
+C Store YPRIME in YPTEM and increment YPTEM by VTEM*CJ.
+C-----------------------------------------------------------------------
+      DO 20 I = 1,NEQ
+        YPTEM(I) = YPRIME(I) + VTEM(I)*CJ
+ 20     Z(I) = Y(I) + VTEM(I)
+C-----------------------------------------------------------------------
+C Call RES with incremented Y, YPRIME arguments
+C stored in Z, YPTEM.  VTEM is overwritten with new residual.
+C-----------------------------------------------------------------------
+      CONTINUE
+      CALL RES(TN,Z,YPTEM,CJ,VTEM,IRES,RPAR,IPAR)
+      NRE = NRE + 1
+      IF (IRES .LT. 0) RETURN
+C-----------------------------------------------------------------------
+C Set Z = (dF/dY) * VBAR using difference quotient.
+C (VBAR is old value of VTEM before calling RES)
+C-----------------------------------------------------------------------
+      DO 70 I = 1,NEQ
+ 70     Z(I) = VTEM(I) - SAVR(I)
+C-----------------------------------------------------------------------
+C Apply inverse of left preconditioner to Z.
+C-----------------------------------------------------------------------
+      CALL PSOL (NEQ, TN, Y, YPRIME, SAVR, YPTEM, CJ, WGHT, WP, IWP,
+     1   Z, EPLIN, IER, RPAR, IPAR)
+      NPSL = NPSL + 1
+      IF (IER .NE. 0) RETURN
+C-----------------------------------------------------------------------
+C Apply D-inverse to Z and return.
+C-----------------------------------------------------------------------
+      DO 90 I = 1,NEQ
+ 90     Z(I) = Z(I)*WGHT(I)
+      RETURN
+C
+C------END OF SUBROUTINE DATV-------------------------------------------
+      END
diff --git a/libcruft/daspk/dcnst0.f b/libcruft/daspk/dcnst0.f
new file mode 100644
index 0000000..538a8d6
--- /dev/null
+++ b/libcruft/daspk/dcnst0.f
@@ -0,0 +1,75 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number
+C W-7405-Eng-48.
+C
+      SUBROUTINE DCNST0 (NEQ, Y, ICNSTR, IRET)
+C
+C***BEGIN PROLOGUE  DCNST0
+C***DATE WRITTEN   950808   (YYMMDD)
+C***REVISION DATE  950808   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C This subroutine checks for constraint violations in the initial 
+C approximate solution u.
+C
+C On entry
+C
+C   NEQ    -- size of the nonlinear system, and the length of arrays
+C             Y and ICNSTR.
+C
+C   Y      -- real array containing the initial approximate root.
+C
+C   ICNSTR -- INTEGER array of length NEQ containing flags indicating
+C             which entries in Y are to be constrained.
+C             if ICNSTR(I) =  2, then Y(I) must be .GT. 0,
+C             if ICNSTR(I) =  1, then Y(I) must be .GE. 0,
+C             if ICNSTR(I) = -1, then Y(I) must be .LE. 0, while
+C             if ICNSTR(I) = -2, then Y(I) must be .LT. 0, while
+C             if ICNSTR(I) =  0, then Y(I) is not constrained.
+C
+C On return
+C
+C   IRET   -- output flag.
+C             IRET=0    means that u satisfied all constraints.
+C             IRET.NE.0 means that Y(IRET) failed to satisfy its
+C                       constraint.
+C
+C-----------------------------------------------------------------------
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(NEQ), ICNSTR(NEQ)
+      SAVE ZERO
+      DATA ZERO/0.D0/
+C-----------------------------------------------------------------------
+C Check constraints for initial Y.  If a constraint has been violated,
+C set IRET = I to signal an error return to calling routine.
+C-----------------------------------------------------------------------
+      IRET = 0
+      DO 100 I = 1,NEQ
+         IF (ICNSTR(I) .EQ. 2) THEN
+            IF (Y(I) .LE. ZERO) THEN
+               IRET = I
+               RETURN
+            ENDIF
+         ELSEIF (ICNSTR(I) .EQ. 1) THEN
+            IF (Y(I) .LT. ZERO) THEN
+               IRET = I
+               RETURN
+            ENDIF 
+         ELSEIF (ICNSTR(I) .EQ. -1) THEN
+            IF (Y(I) .GT. ZERO) THEN
+               IRET = I
+               RETURN
+            ENDIF 
+         ELSEIF (ICNSTR(I) .EQ. -2) THEN
+            IF (Y(I) .GE. ZERO) THEN
+               IRET = I
+               RETURN
+            ENDIF 
+        ENDIF
+ 100  CONTINUE
+      RETURN
+C----------------------- END OF SUBROUTINE DCNST0 ----------------------
+      END
diff --git a/libcruft/daspk/dcnstr.f b/libcruft/daspk/dcnstr.f
new file mode 100644
index 0000000..1bf10cc
--- /dev/null
+++ b/libcruft/daspk/dcnstr.f
@@ -0,0 +1,124 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number
+C W-7405-Eng-48.
+C
+      SUBROUTINE DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR)
+C
+C***BEGIN PROLOGUE  DCNSTR
+C***DATE WRITTEN   950808   (YYMMDD)
+C***REVISION DATE  950814   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C This subroutine checks for constraint violations in the proposed 
+C new approximate solution YNEW.
+C If a constraint violation occurs, then a new step length, TAU,
+C is calculated, and this value is to be given to the linesearch routine
+C to calculate a new approximate solution YNEW.
+C
+C On entry:
+C
+C   NEQ    -- size of the nonlinear system, and the length of arrays
+C             Y, YNEW and ICNSTR.
+C
+C   Y      -- real array containing the current approximate y.
+C
+C   YNEW   -- real array containing the new approximate y.
+C
+C   ICNSTR -- INTEGER array of length NEQ containing flags indicating
+C             which entries in YNEW are to be constrained.
+C             if ICNSTR(I) =  2, then YNEW(I) must be .GT. 0,
+C             if ICNSTR(I) =  1, then YNEW(I) must be .GE. 0,
+C             if ICNSTR(I) = -1, then YNEW(I) must be .LE. 0, while
+C             if ICNSTR(I) = -2, then YNEW(I) must be .LT. 0, while
+C             if ICNSTR(I) =  0, then YNEW(I) is not constrained.
+C
+C   RLX    -- real scalar restricting update, if ICNSTR(I) = 2 or -2,
+C             to ABS( (YNEW-Y)/Y ) < FAC2*RLX in component I.
+C
+C   TAU    -- the current size of the step length for the linesearch.
+C
+C On return
+C
+C   TAU    -- the adjusted size of the step length if a constraint
+C             violation occurred (otherwise, it is unchanged).  it is
+C             the step length to give to the linesearch routine.
+C
+C   IRET   -- output flag.
+C             IRET=0 means that YNEW satisfied all constraints.
+C             IRET=1 means that YNEW failed to satisfy all the
+C                    constraints, and a new linesearch step
+C                    must be computed.
+C
+C   IVAR   -- index of variable causing constraint to be violated.
+C
+C-----------------------------------------------------------------------
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(NEQ), YNEW(NEQ), ICNSTR(NEQ)
+      SAVE FAC, FAC2, ZERO
+      DATA FAC /0.6D0/, FAC2 /0.9D0/, ZERO/0.0D0/
+C-----------------------------------------------------------------------
+C Check constraints for proposed new step YNEW.  If a constraint has
+C been violated, then calculate a new step length, TAU, to be
+C used in the linesearch routine.
+C-----------------------------------------------------------------------
+      IRET = 0
+      RDYMX = ZERO
+      IVAR = 0
+      DO 100 I = 1,NEQ
+C
+         IF (ICNSTR(I) .EQ. 2) THEN
+            RDY = ABS( (YNEW(I)-Y(I))/Y(I) )
+            IF (RDY .GT. RDYMX) THEN
+               RDYMX = RDY
+               IVAR = I
+            ENDIF
+            IF (YNEW(I) .LE. ZERO) THEN
+               TAU = FAC*TAU
+               IVAR = I
+               IRET = 1
+               RETURN
+            ENDIF
+C
+         ELSEIF (ICNSTR(I) .EQ. 1) THEN
+            IF (YNEW(I) .LT. ZERO) THEN
+               TAU = FAC*TAU
+               IVAR = I
+               IRET = 1
+               RETURN
+            ENDIF
+C
+         ELSEIF (ICNSTR(I) .EQ. -1) THEN
+            IF (YNEW(I) .GT. ZERO) THEN
+               TAU = FAC*TAU
+               IVAR = I
+               IRET = 1
+               RETURN
+            ENDIF
+C
+         ELSEIF (ICNSTR(I) .EQ. -2) THEN
+            RDY = ABS( (YNEW(I)-Y(I))/Y(I) )
+            IF (RDY .GT. RDYMX) THEN
+               RDYMX = RDY
+               IVAR = I
+            ENDIF
+            IF (YNEW(I) .GE. ZERO) THEN
+               TAU = FAC*TAU
+               IVAR = I
+               IRET = 1
+               RETURN
+            ENDIF
+C
+         ENDIF
+ 100  CONTINUE
+
+      IF(RDYMX .GE. RLX) THEN
+         TAU = FAC2*TAU*RLX/RDYMX
+         IRET = 1
+      ENDIF
+C
+      RETURN
+C----------------------- END OF SUBROUTINE DCNSTR ----------------------
+      END
diff --git a/libcruft/daspk/ddasic.f b/libcruft/daspk/ddasic.f
new file mode 100644
index 0000000..373613b
--- /dev/null
+++ b/libcruft/daspk/ddasic.f
@@ -0,0 +1,169 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DDASIC (X, Y, YPRIME, NEQ, ICOPT, ID, RES, JAC, PSOL,
+     *   H, WT, NIC, IDID, RPAR, IPAR, PHI, SAVR, DELTA, E, YIC, YPIC,
+     *   PWK, WM, IWM, HMIN, UROUND, EPLI, SQRTN, RSQRTN, EPCONI,
+     *   STPTOL, JFLG, ICNFLG, ICNSTR, NLSIC)
+C
+C***BEGIN PROLOGUE  DDASIC
+C***REFER TO  DDASPK
+C***DATE WRITTEN   940628   (YYMMDD)
+C***REVISION DATE  941206   (YYMMDD)
+C***REVISION DATE  950714   (YYMMDD)
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DDASIC is a driver routine to compute consistent initial values
+C     for Y and YPRIME.  There are two different options:  
+C     Denoting the differential variables in Y by Y_d, and
+C     the algebraic variables by Y_a, the problem solved is either:
+C     1.  Given Y_d, calculate Y_a and Y_d', or
+C     2.  Given Y', calculate Y.
+C     In either case, initial values for the given components
+C     are input, and initial guesses for the unknown components
+C     must also be provided as input.
+C
+C     The external routine NLSIC solves the resulting nonlinear system.
+C
+C     The parameters represent
+C
+C     X  --        Independent variable.
+C     Y  --        Solution vector at X.
+C     YPRIME --    Derivative of solution vector.
+C     NEQ --       Number of equations to be integrated.
+C     ICOPT     -- Flag indicating initial condition option chosen.
+C                    ICOPT = 1 for option 1 above.
+C                    ICOPT = 2 for option 2.
+C     ID        -- Array of dimension NEQ, which must be initialized
+C                  if option 1 is chosen.
+C                    ID(i) = +1 if Y_i is a differential variable,
+C                    ID(i) = -1 if Y_i is an algebraic variable. 
+C     RES --       External user-supplied subroutine to evaluate the
+C                  residual.  See RES description in DDASPK prologue.
+C     JAC --       External user-supplied routine to update Jacobian
+C                  or preconditioner information in the nonlinear solver
+C                  (optional).  See JAC description in DDASPK prologue.
+C     PSOL --      External user-supplied routine to solve
+C                  a linear system using preconditioning. 
+C                  See PSOL in DDASPK prologue.
+C     H --         Scaling factor in iteration matrix.  DDASIC may 
+C                  reduce H to achieve convergence.
+C     WT --        Vector of weights for error criterion.
+C     NIC --       Input number of initial condition calculation call 
+C                  (= 1 or 2).
+C     IDID --      Completion code.  See IDID in DDASPK prologue.
+C     RPAR,IPAR -- Real and integer parameter arrays that
+C                  are used for communication between the
+C                  calling program and external user routines.
+C                  They are not altered by DNSK
+C     PHI --       Work space for DDASIC of length at least 2*NEQ.
+C     SAVR --      Work vector for DDASIC of length NEQ.
+C     DELTA --     Work vector for DDASIC of length NEQ.
+C     E --         Work vector for DDASIC of length NEQ.
+C     YIC,YPIC --  Work vectors for DDASIC, each of length NEQ.
+C     PWK --       Work vector for DDASIC of length NEQ.
+C     WM,IWM --    Real and integer arrays storing
+C                  information required by the linear solver.
+C     EPCONI --    Test constant for Newton iteration convergence.
+C     ICNFLG --    Flag showing whether constraints on Y are to apply.
+C     ICNSTR --    Integer array of length NEQ with constraint types.
+C
+C     The other parameters are for use internally by DDASIC.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   DCOPY, NLSIC
+C
+C***END PROLOGUE  DDASIC
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),ID(*),WT(*),PHI(NEQ,*)
+      DIMENSION SAVR(*),DELTA(*),E(*),YIC(*),YPIC(*),PWK(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*), ICNSTR(*)
+      EXTERNAL RES, JAC, PSOL, NLSIC
+C
+      PARAMETER (LCFN=15)
+      PARAMETER (LMXNH=34)
+C
+C The following parameters are data-loaded here:
+C     RHCUT  = factor by which H is reduced on retry of Newton solve.
+C     RATEMX = maximum convergence rate for which Newton iteration
+C              is considered converging.
+C
+      SAVE RHCUT, RATEMX
+      DATA RHCUT/0.1D0/, RATEMX/0.8D0/
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 1.
+C     Initializations.
+C     JSKIP is a flag set to 1 when NIC = 2 and NH = 1, to signal that
+C     the initial call to the JAC routine is to be skipped then.
+C     Save Y and YPRIME in PHI.  Initialize IDID, NH, and CJ.
+C-----------------------------------------------------------------------
+C
+      MXNH = IWM(LMXNH)
+      IDID = 1
+      NH = 1
+      JSKIP = 0
+      IF (NIC .EQ. 2) JSKIP = 1
+      CALL DCOPY (NEQ, Y, 1, PHI(1,1), 1)
+      CALL DCOPY (NEQ, YPRIME, 1, PHI(1,2), 1)
+C
+      IF (ICOPT .EQ. 2) THEN
+        CJ = 0.0D0 
+      ELSE
+        CJ = 1.0D0/H
+      ENDIF
+C
+C-----------------------------------------------------------------------
+C     BLOCK 2
+C     Call the nonlinear system solver to obtain
+C     consistent initial values for Y and YPRIME.
+C-----------------------------------------------------------------------
+C
+ 200  CONTINUE
+      CALL NLSIC(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JAC,PSOL,H,WT,JSKIP,
+     *   RPAR,IPAR,SAVR,DELTA,E,YIC,YPIC,PWK,WM,IWM,CJ,UROUND,
+     *   EPLI,SQRTN,RSQRTN,EPCONI,RATEMX,STPTOL,JFLG,ICNFLG,ICNSTR,
+     *   IERNLS)
+C
+      IF (IERNLS .EQ. 0) RETURN
+C
+C-----------------------------------------------------------------------
+C     BLOCK 3
+C     The nonlinear solver was unsuccessful.  Increment NCFN.
+C     Return with IDID = -12 if either
+C       IERNLS = -1: error is considered unrecoverable,
+C       ICOPT = 2: we are doing initialization problem type 2, or
+C       NH = MXNH: the maximum number of H values has been tried.
+C     Otherwise (problem 1 with IERNLS .GE. 1), reduce H and try again.
+C     If IERNLS > 1, restore Y and YPRIME to their original values.
+C-----------------------------------------------------------------------
+C
+      IWM(LCFN) = IWM(LCFN) + 1
+      JSKIP = 0
+C
+      IF (IERNLS .EQ. -1) GO TO 350
+      IF (ICOPT .EQ. 2) GO TO 350
+      IF (NH .EQ. MXNH) GO TO 350
+C
+      NH = NH + 1
+      H = H*RHCUT
+      CJ = 1.0D0/H
+C
+      IF (IERNLS .EQ. 1) GO TO 200
+C
+      CALL DCOPY (NEQ, PHI(1,1), 1, Y, 1)
+      CALL DCOPY (NEQ, PHI(1,2), 1, YPRIME, 1)
+      GO TO 200
+C
+ 350  IDID = -12
+      RETURN
+C
+C------END OF SUBROUTINE DDASIC-----------------------------------------
+      END
diff --git a/libcruft/daspk/ddasid.f b/libcruft/daspk/ddasid.f
new file mode 100644
index 0000000..e5b12ad
--- /dev/null
+++ b/libcruft/daspk/ddasid.f
@@ -0,0 +1,168 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DDASID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JACD,PDUM,H,WT,
+     *  JSDUM,RPAR,IPAR,DUMSVR,DELTA,R,YIC,YPIC,DUMPWK,WM,IWM,CJ,UROUND,
+     *  DUME,DUMS,DUMR,EPCON,RATEMX,STPTOL,JFDUM,
+     *  ICNFLG,ICNSTR,IERNLS)
+C
+C***BEGIN PROLOGUE  DDASID
+C***REFER TO  DDASPK
+C***DATE WRITTEN   940701   (YYMMDD)
+C***REVISION DATE  950808   (YYMMDD)
+C***REVISION DATE  951110   Removed unreachable block 390.
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C
+C     DDASID solves a nonlinear system of algebraic equations of the
+C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in
+C     the initial conditions.
+C
+C     The method used is a modified Newton scheme.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of unknowns.
+C     ICOPT     -- Initial condition option chosen (1 or 2).
+C     ID        -- Array of dimension NEQ, which must be initialized
+C                  if ICOPT = 1.  See DDASIC.
+C     RES       -- External user-supplied subroutine to evaluate the
+C                  residual.  See RES description in DDASPK prologue.
+C     JACD      -- External user-supplied routine to evaluate the
+C                  Jacobian.  See JAC description for the case
+C                  INFO(12) = 0 in the DDASPK prologue.
+C     PDUM      -- Dummy argument.
+C     H         -- Scaling factor for this initial condition calc.
+C     WT        -- Vector of weights for error criterion.
+C     JSDUM     -- Dummy argument.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     DUMSVR    -- Dummy argument.
+C     DELTA     -- Work vector for NLS of length NEQ.
+C     R         -- Work vector for NLS of length NEQ.
+C     YIC,YPIC  -- Work vectors for NLS, each of length NEQ.
+C     DUMPWK    -- Dummy argument.
+C     WM,IWM    -- Real and integer arrays storing matrix information
+C                  such as the matrix of partial derivatives,
+C                  permutation vector, and various other information.
+C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
+C     UROUND    -- Unit roundoff.
+C     DUME      -- Dummy argument.
+C     DUMS      -- Dummy argument.
+C     DUMR      -- Dummy argument.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     RATEMX    -- Maximum convergence rate for which Newton iteration
+C                  is considered converging.
+C     JFDUM     -- Dummy argument.
+C     STPTOL    -- Tolerance used in calculating the minimum lambda
+C                  value allowed.
+C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
+C                  violations in the proposed new approximate solution
+C                  will be checked for, and the maximum step length 
+C                  will be adjusted accordingly.
+C     ICNSTR    -- Integer array of length NEQ containing flags for
+C                  checking constraints.
+C     IERNLS    -- Error flag for nonlinear solver.
+C                   0   ==> nonlinear solver converged.
+C                   1,2 ==> recoverable error inside nonlinear solver.
+C                           1 => retry with current Y, YPRIME
+C                           2 => retry with original Y, YPRIME
+C                  -1   ==> unrecoverable error in nonlinear solver.
+C
+C     All variables with "DUM" in their names are dummy variables
+C     which are not used in this routine.
+C
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   RES, DMATD, DNSID
+C
+C***END PROLOGUE  DDASID
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),ID(*),WT(*),ICNSTR(*)
+      DIMENSION DELTA(*),R(*),YIC(*),YPIC(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      EXTERNAL  RES, JACD
+C
+      PARAMETER (LNRE=12, LNJE=13, LMXNIT=32, LMXNJ=33)
+C
+C
+C     Perform initializations.
+C
+      MXNIT = IWM(LMXNIT)
+      MXNJ = IWM(LMXNJ)
+      IERNLS = 0
+      NJ = 0
+C
+C     Call RES to initialize DELTA.
+C
+      IRES = 0
+      IWM(LNRE) = IWM(LNRE) + 1
+      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 370
+C
+C     Looping point for updating the Jacobian.
+C
+300   CONTINUE
+C
+C     Initialize all error flags to zero.
+C
+      IERJ = 0
+      IRES = 0
+      IERNEW = 0
+C
+C     Reevaluate the iteration matrix, J = dG/dY + CJ*dG/dYPRIME,
+C     where G(X,Y,YPRIME) = 0.
+C
+      NJ = NJ + 1
+      IWM(LNJE)=IWM(LNJE)+1
+      CALL DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IERJ,WT,R,
+     *              WM,IWM,RES,IRES,UROUND,JACD,RPAR,IPAR)
+      IF (IRES .LT. 0 .OR. IERJ .NE. 0) GO TO 370
+C
+C     Call the nonlinear Newton solver for up to MXNIT iterations.
+C
+      CALL DNSID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,WT,RPAR,IPAR,DELTA,R,
+     *     YIC,YPIC,WM,IWM,CJ,EPCON,RATEMX,MXNIT,STPTOL,
+     *     ICNFLG,ICNSTR,IERNEW)
+C
+      IF (IERNEW .EQ. 1 .AND. NJ .LT. MXNJ) THEN
+C
+C        MXNIT iterations were done, the convergence rate is < 1,
+C        and the number of Jacobian evaluations is less than MXNJ.
+C        Call RES, reevaluate the Jacobian, and try again.
+C
+         IWM(LNRE)=IWM(LNRE)+1
+         CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+         IF (IRES .LT. 0) GO TO 370
+         GO TO 300
+         ENDIF
+C
+      IF (IERNEW .NE. 0) GO TO 380
+
+      RETURN
+C
+C
+C     Unsuccessful exits from nonlinear solver.
+C     Compute IERNLS accordingly.
+C
+370   IERNLS = 2
+      IF (IRES .LE. -2) IERNLS = -1
+      RETURN
+C
+380   IERNLS = MIN(IERNEW,2)
+      RETURN
+C
+C------END OF SUBROUTINE DDASID-----------------------------------------
+      END
diff --git a/libcruft/daspk/ddasik.f b/libcruft/daspk/ddasik.f
new file mode 100644
index 0000000..1658373
--- /dev/null
+++ b/libcruft/daspk/ddasik.f
@@ -0,0 +1,176 @@
+C Work perfored under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DDASIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JACK,PSOL,H,WT,
+     *   JSKIP,RPAR,IPAR,SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,UROUND,
+     *   EPLI,SQRTN,RSQRTN,EPCON,RATEMX,STPTOL,JFLG,
+     *   ICNFLG,ICNSTR,IERNLS)
+C
+C***BEGIN PROLOGUE  DDASIK
+C***REFER TO  DDASPK
+C***DATE WRITTEN   941026   (YYMMDD)
+C***REVISION DATE  950808   (YYMMDD)
+C***REVISION DATE  951110   Removed unreachable block 390.
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C
+C     DDASIK solves a nonlinear system of algebraic equations of the
+C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in
+C     the initial conditions.
+C
+C     An initial value for Y and initial guess for YPRIME are input.
+C
+C     The method used is a Newton scheme with Krylov iteration and a
+C     linesearch algorithm.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector at x.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of equations to be integrated.
+C     ICOPT     -- Initial condition option chosen (1 or 2).
+C     ID        -- Array of dimension NEQ, which must be initialized
+C                  if ICOPT = 1.  See DDASIC.
+C     RES       -- External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     JACK     --  External user-supplied routine to update
+C                  the preconditioner.  (This is optional).
+C                  See JAC description for the case
+C                  INFO(12) = 1 in the DDASPK prologue.
+C     PSOL      -- External user-supplied routine to solve
+C                  a linear system using preconditioning.
+C                  (This is optional).  See explanation inside DDASPK.
+C     H         -- Scaling factor for this initial condition calc.
+C     WT        -- Vector of weights for error criterion.
+C     JSKIP     -- input flag to signal if initial JAC call is to be
+C                  skipped.  1 => skip the call, 0 => do not skip call.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     SAVR      -- Work vector for DDASIK of length NEQ.
+C     DELTA     -- Work vector for DDASIK of length NEQ.
+C     R         -- Work vector for DDASIK of length NEQ.
+C     YIC,YPIC  -- Work vectors for DDASIK, each of length NEQ.
+C     PWK       -- Work vector for DDASIK of length NEQ.
+C     WM,IWM    -- Real and integer arrays storing
+C                  matrix information for linear system
+C                  solvers, and various other information.
+C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
+C     UROUND    -- Unit roundoff.
+C     EPLI      -- convergence test constant.
+C                  See DDASPK prologue for more details.
+C     SQRTN     -- Square root of NEQ.
+C     RSQRTN    -- reciprical of square root of NEQ.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     RATEMX    -- Maximum convergence rate for which Newton iteration
+C                  is considered converging.
+C     JFLG      -- Flag showing whether a Jacobian routine is supplied.
+C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
+C                  violations in the proposed new approximate solution
+C                  will be checked for, and the maximum step length 
+C                  will be adjusted accordingly.
+C     ICNSTR    -- Integer array of length NEQ containing flags for
+C                  checking constraints.
+C     IERNLS    -- Error flag for nonlinear solver.
+C                   0   ==> nonlinear solver converged.
+C                   1,2 ==> recoverable error inside nonlinear solver.
+C                           1 => retry with current Y, YPRIME
+C                           2 => retry with original Y, YPRIME
+C                  -1   ==> unrecoverable error in nonlinear solver.
+C
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   RES, JACK, DNSIK, DCOPY
+C
+C***END PROLOGUE  DDASIK
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),ID(*),WT(*),ICNSTR(*)
+      DIMENSION SAVR(*),DELTA(*),R(*),YIC(*),YPIC(*),PWK(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      EXTERNAL RES, JACK, PSOL
+C
+      PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30)
+      PARAMETER (LMXNIT=32, LMXNJ=33)
+C
+C
+C     Perform initializations.
+C
+      LWP = IWM(LLOCWP)
+      LIWP = IWM(LLCIWP)
+      MXNIT = IWM(LMXNIT)
+      MXNJ = IWM(LMXNJ)
+      IERNLS = 0
+      NJ = 0
+      EPLIN = EPLI*EPCON
+C
+C     Call RES to initialize DELTA.
+C
+      IRES = 0
+      IWM(LNRE) = IWM(LNRE) + 1
+      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 370
+C
+C     Looping point for updating the preconditioner.
+C
+ 300  CONTINUE
+C
+C     Initialize all error flags to zero.
+C
+      IERPJ = 0
+      IRES = 0
+      IERNEW = 0
+C
+C     If a Jacobian routine was supplied, call it.
+C
+      IF (JFLG .EQ. 1 .AND. JSKIP .EQ. 0) THEN
+        NJ = NJ + 1
+        IWM(LNJE)=IWM(LNJE)+1
+        CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, R, H, CJ,
+     *     WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR)
+        IF (IRES .LT. 0 .OR. IERPJ .NE. 0) GO TO 370
+        ENDIF
+      JSKIP = 0
+C
+C     Call the nonlinear Newton solver for up to MXNIT iterations.
+C
+      CALL DNSIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,PSOL,WT,RPAR,IPAR,
+     *   SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,SQRTN,RSQRTN,
+     *   EPLIN,EPCON,RATEMX,MXNIT,STPTOL,ICNFLG,ICNSTR,IERNEW)
+C
+      IF (IERNEW .EQ. 1 .AND. NJ .LT. MXNJ .AND. JFLG .EQ. 1) THEN
+C
+C       Up to MXNIT iterations were done, the convergence rate is < 1,
+C       a Jacobian routine is supplied, and the number of JACK calls
+C       is less than MXNJ.  
+C       Copy the residual SAVR to DELTA, call JACK, and try again.
+C
+        CALL DCOPY (NEQ,  SAVR, 1, DELTA, 1)
+        GO TO 300
+        ENDIF
+C
+      IF (IERNEW .NE. 0) GO TO 380
+      RETURN
+C
+C
+C     Unsuccessful exits from nonlinear solver.
+C     Set IERNLS accordingly.
+C
+ 370  IERNLS = 2
+      IF (IRES .LE. -2) IERNLS = -1
+      RETURN
+C
+ 380  IERNLS = MIN(IERNEW,2)
+      RETURN
+C
+C----------------------- END OF SUBROUTINE DDASIK-----------------------
+      END
diff --git a/libcruft/daspk/ddaspk.f b/libcruft/daspk/ddaspk.f
new file mode 100644
index 0000000..a13dd87
--- /dev/null
+++ b/libcruft/daspk/ddaspk.f
@@ -0,0 +1,2360 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DDASPK (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
+     *   IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC, PSOL)
+C
+C***BEGIN PROLOGUE  DDASPK
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  910624   
+C***REVISION DATE  920929   (CJ in RES call, RES counter fix.)
+C***REVISION DATE  921215   (Warnings on poor iteration performance)
+C***REVISION DATE  921216   (NRMAX as optional input)
+C***REVISION DATE  930315   (Name change: DDINI to DDINIT)
+C***REVISION DATE  940822   (Replaced initial condition calculation)
+C***REVISION DATE  941101   (Added linesearch in I.C. calculations)
+C***REVISION DATE  941220   (Misc. corrections throughout)
+C***REVISION DATE  950125   (Added DINVWT routine)
+C***REVISION DATE  950714   (Misc. corrections throughout)
+C***REVISION DATE  950802   (Default NRMAX = 5, based on tests.)
+C***REVISION DATE  950808   (Optional error test added.)
+C***REVISION DATE  950814   (Added I.C. constraints and INFO(14))
+C***REVISION DATE  950828   (Various minor corrections.)
+C***REVISION DATE  951006   (Corrected WT scaling in DFNRMK.)
+C***REVISION DATE  960129   (Corrected RL bug in DLINSD, DLINSK.)
+C***REVISION DATE  960301   (Added NONNEG to SAVE statement.)
+C***CATEGORY NO.  I1A2
+C***KEYWORDS  DIFFERENTIAL/ALGEBRAIC, BACKWARD DIFFERENTIATION FORMULAS,
+C             IMPLICIT DIFFERENTIAL SYSTEMS, KRYLOV ITERATION
+C***AUTHORS   Linda R. Petzold, Peter N. Brown, Alan C. Hindmarsh, and
+C                  Clement W. Ulrich
+C             Center for Computational Sciences & Engineering, L-316
+C             Lawrence Livermore National Laboratory
+C             P.O. Box 808,
+C             Livermore, CA 94551
+C***PURPOSE  This code solves a system of differential/algebraic 
+C            equations of the form 
+C               G(t,y,y') = 0 , 
+C            using a combination of Backward Differentiation Formula 
+C            (BDF) methods and a choice of two linear system solution 
+C            methods: direct (dense or band) or Krylov (iterative).
+C            This version is in double precision.
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C *Usage:
+C
+C      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+C      INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR(*)
+C      DOUBLE PRECISION T, Y(*), YPRIME(*), TOUT, RTOL(*), ATOL(*),
+C         RWORK(LRW), RPAR(*)
+C      EXTERNAL  RES, JAC, PSOL
+C
+C      CALL DDASPK (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
+C     *   IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC, PSOL)
+C
+C  Quantities which may be altered by the code are:
+C     T, Y(*), YPRIME(*), INFO(*), RTOL, ATOL, IDID, RWORK(*), IWORK(*)
+C
+C
+C *Arguments:
+C
+C  RES:EXT          This is the name of a subroutine which you
+C                   provide to define the residual function G(t,y,y')
+C                   of the differential/algebraic system.
+C
+C  NEQ:IN           This is the number of equations in the system.
+C
+C  T:INOUT          This is the current value of the independent 
+C                   variable.
+C
+C  Y(*):INOUT       This array contains the solution components at T.
+C
+C  YPRIME(*):INOUT  This array contains the derivatives of the solution
+C                   components at T.
+C
+C  TOUT:IN          This is a point at which a solution is desired.
+C
+C  INFO(N):IN       This is an integer array used to communicate details
+C                   of how the solution is to be carried out, such as
+C                   tolerance type, matrix structure, step size and
+C                   order limits, and choice of nonlinear system method.
+C                   N must be at least 20.
+C
+C  RTOL,ATOL:INOUT  These quantities represent absolute and relative
+C                   error tolerances (on local error) which you provide
+C                   to indicate how accurately you wish the solution to
+C                   be computed.  You may choose them to be both scalars
+C                   or else both arrays of length NEQ.
+C
+C  IDID:OUT         This integer scalar is an indicator reporting what
+C                   the code did.  You must monitor this variable to
+C                   decide what action to take next.
+C
+C  RWORK:WORK       A real work array of length LRW which provides the
+C                   code with needed storage space.
+C
+C  LRW:IN           The length of RWORK.
+C
+C  IWORK:WORK       An integer work array of length LIW which provides
+C                   the code with needed storage space.
+C
+C  LIW:IN           The length of IWORK.
+C
+C  RPAR,IPAR:IN     These are real and integer parameter arrays which
+C                   you can use for communication between your calling
+C                   program and the RES, JAC, and PSOL subroutines.
+C
+C  JAC:EXT          This is the name of a subroutine which you may
+C                   provide (optionally) for calculating Jacobian 
+C                   (partial derivative) data involved in solving linear
+C                   systems within DDASPK.
+C
+C  PSOL:EXT         This is the name of a subroutine which you must
+C                   provide for solving linear systems if you selected
+C                   a Krylov method.  The purpose of PSOL is to solve
+C                   linear systems involving a left preconditioner P.
+C
+C *Overview
+C
+C  The DDASPK solver uses the backward differentiation formulas of
+C  orders one through five to solve a system of the form G(t,y,y') = 0
+C  for y = Y and y' = YPRIME.  Values for Y and YPRIME at the initial 
+C  time must be given as input.  These values should be consistent, 
+C  that is, if T, Y, YPRIME are the given initial values, they should 
+C  satisfy G(T,Y,YPRIME) = 0.  However, if consistent values are not
+C  known, in many cases you can have DDASPK solve for them -- see INFO(11).
+C  (This and other options are described in more detail below.)
+C
+C  Normally, DDASPK solves the system from T to TOUT.  It is easy to
+C  continue the solution to get results at additional TOUT.  This is
+C  the interval mode of operation.  Intermediate results can also be
+C  obtained easily by specifying INFO(3).
+C
+C  On each step taken by DDASPK, a sequence of nonlinear algebraic  
+C  systems arises.  These are solved by one of two types of
+C  methods:
+C    * a Newton iteration with a direct method for the linear
+C      systems involved (INFO(12) = 0), or
+C    * a Newton iteration with a preconditioned Krylov iterative 
+C      method for the linear systems involved (INFO(12) = 1).
+C
+C  The direct method choices are dense and band matrix solvers, 
+C  with either a user-supplied or an internal difference quotient 
+C  Jacobian matrix, as specified by INFO(5) and INFO(6).
+C  In the band case, INFO(6) = 1, you must supply half-bandwidths
+C  in IWORK(1) and IWORK(2).
+C
+C  The Krylov method is the Generalized Minimum Residual (GMRES) 
+C  method, in either complete or incomplete form, and with 
+C  scaling and preconditioning.  The method is implemented
+C  in an algorithm called SPIGMR.  Certain options in the Krylov 
+C  method case are specified by INFO(13) and INFO(15).
+C
+C  If the Krylov method is chosen, you may supply a pair of routines,
+C  JAC and PSOL, to apply preconditioning to the linear system.
+C  If the system is A*x = b, the matrix is A = dG/dY + CJ*dG/dYPRIME
+C  (of order NEQ).  This system can then be preconditioned in the form
+C  (P-inverse)*A*x = (P-inverse)*b, with left preconditioner P.
+C  (DDASPK does not allow right preconditioning.)
+C  Then the Krylov method is applied to this altered, but equivalent,
+C  linear system, hopefully with much better performance than without
+C  preconditioning.  (In addition, a diagonal scaling matrix based on
+C  the tolerances is also introduced into the altered system.)
+C
+C  The JAC routine evaluates any data needed for solving systems
+C  with coefficient matrix P, and PSOL carries out that solution.
+C  In any case, in order to improve convergence, you should try to
+C  make P approximate the matrix A as much as possible, while keeping
+C  the system P*x = b reasonably easy and inexpensive to solve for x,
+C  given a vector b.
+C
+C
+C *Description
+C
+C------INPUT - WHAT TO DO ON THE FIRST CALL TO DDASPK-------------------
+C
+C
+C  The first call of the code is defined to be the start of each new
+C  problem.  Read through the descriptions of all the following items,
+C  provide sufficient storage space for designated arrays, set
+C  appropriate variables for the initialization of the problem, and
+C  give information about how you want the problem to be solved.
+C
+C
+C  RES -- Provide a subroutine of the form
+C
+C             SUBROUTINE RES (T, Y, YPRIME, CJ, DELTA, IRES, RPAR, IPAR)
+C
+C         to define the system of differential/algebraic
+C         equations which is to be solved. For the given values
+C         of T, Y and YPRIME, the subroutine should return
+C         the residual of the differential/algebraic system
+C             DELTA = G(T,Y,YPRIME)
+C         DELTA is a vector of length NEQ which is output from RES.
+C
+C         Subroutine RES must not alter T, Y, YPRIME, or CJ.
+C         You must declare the name RES in an EXTERNAL
+C         statement in your program that calls DDASPK.
+C         You must dimension Y, YPRIME, and DELTA in RES.
+C
+C         The input argument CJ can be ignored, or used to rescale
+C         constraint equations in the system (see Ref. 2, p. 145).
+C         Note: In this respect, DDASPK is not downward-compatible
+C         with DDASSL, which does not have the RES argument CJ.
+C
+C         IRES is an integer flag which is always equal to zero
+C         on input.  Subroutine RES should alter IRES only if it
+C         encounters an illegal value of Y or a stop condition.
+C         Set IRES = -1 if an input value is illegal, and DDASPK
+C         will try to solve the problem without getting IRES = -1.
+C         If IRES = -2, DDASPK will return control to the calling
+C         program with IDID = -11.
+C
+C         RPAR and IPAR are real and integer parameter arrays which
+C         you can use for communication between your calling program
+C         and subroutine RES. They are not altered by DDASPK. If you
+C         do not need RPAR or IPAR, ignore these parameters by treat-
+C         ing them as dummy arguments. If you do choose to use them,
+C         dimension them in your calling program and in RES as arrays
+C         of appropriate length.
+C
+C  NEQ -- Set it to the number of equations in the system (NEQ .GE. 1).
+C
+C  T -- Set it to the initial point of the integration. (T must be
+C       a variable.)
+C
+C  Y(*) -- Set this array to the initial values of the NEQ solution
+C          components at the initial point.  You must dimension Y of
+C          length at least NEQ in your calling program.
+C
+C  YPRIME(*) -- Set this array to the initial values of the NEQ first
+C               derivatives of the solution components at the initial
+C               point.  You must dimension YPRIME at least NEQ in your
+C               calling program. 
+C
+C  TOUT - Set it to the first point at which a solution is desired.
+C         You cannot take TOUT = T.  Integration either forward in T
+C         (TOUT .GT. T) or backward in T (TOUT .LT. T) is permitted.
+C
+C         The code advances the solution from T to TOUT using step
+C         sizes which are automatically selected so as to achieve the
+C         desired accuracy.  If you wish, the code will return with the
+C         solution and its derivative at intermediate steps (the
+C         intermediate-output mode) so that you can monitor them,
+C         but you still must provide TOUT in accord with the basic
+C         aim of the code.
+C
+C         The first step taken by the code is a critical one because
+C         it must reflect how fast the solution changes near the
+C         initial point.  The code automatically selects an initial
+C         step size which is practically always suitable for the
+C         problem.  By using the fact that the code will not step past
+C         TOUT in the first step, you could, if necessary, restrict the
+C         length of the initial step.
+C
+C         For some problems it may not be permissible to integrate
+C         past a point TSTOP, because a discontinuity occurs there
+C         or the solution or its derivative is not defined beyond
+C         TSTOP.  When you have declared a TSTOP point (see INFO(4)
+C         and RWORK(1)), you have told the code not to integrate past
+C         TSTOP.  In this case any tout beyond TSTOP is invalid input.
+C
+C  INFO(*) - Use the INFO array to give the code more details about
+C            how you want your problem solved.  This array should be
+C            dimensioned of length 20, though DDASPK uses only the 
+C            first 15 entries.  You must respond to all of the following
+C            items, which are arranged as questions.  The simplest use
+C            of DDASPK corresponds to setting all entries of INFO to 0.
+C
+C       INFO(1) - This parameter enables the code to initialize itself.
+C              You must set it to indicate the start of every new 
+C              problem.
+C
+C          **** Is this the first call for this problem ...
+C                yes - set INFO(1) = 0
+C                 no - not applicable here.
+C                      See below for continuation calls.  ****
+C
+C       INFO(2) - How much accuracy you want of your solution
+C              is specified by the error tolerances RTOL and ATOL.
+C              The simplest use is to take them both to be scalars.
+C              To obtain more flexibility, they can both be arrays.
+C              The code must be told your choice.
+C
+C          **** Are both error tolerances RTOL, ATOL scalars ...
+C                yes - set INFO(2) = 0
+C                      and input scalars for both RTOL and ATOL
+C                 no - set INFO(2) = 1
+C                      and input arrays for both RTOL and ATOL ****
+C
+C       INFO(3) - The code integrates from T in the direction of TOUT
+C              by steps.  If you wish, it will return the computed
+C              solution and derivative at the next intermediate step
+C              (the intermediate-output mode) or TOUT, whichever comes
+C              first.  This is a good way to proceed if you want to
+C              see the behavior of the solution.  If you must have
+C              solutions at a great many specific TOUT points, this
+C              code will compute them efficiently.
+C
+C          **** Do you want the solution only at
+C               TOUT (and not at the next intermediate step) ...
+C                yes - set INFO(3) = 0
+C                 no - set INFO(3) = 1 ****
+C
+C       INFO(4) - To handle solutions at a great many specific
+C              values TOUT efficiently, this code may integrate past
+C              TOUT and interpolate to obtain the result at TOUT.
+C              Sometimes it is not possible to integrate beyond some
+C              point TSTOP because the equation changes there or it is
+C              not defined past TSTOP.  Then you must tell the code
+C              this stop condition.
+C
+C           **** Can the integration be carried out without any
+C                restrictions on the independent variable T ...
+C                 yes - set INFO(4) = 0
+C                  no - set INFO(4) = 1
+C                       and define the stopping point TSTOP by
+C                       setting RWORK(1) = TSTOP ****
+C
+C       INFO(5) - used only when INFO(12) = 0 (direct methods).
+C              To solve differential/algebraic systems you may wish
+C              to use a matrix of partial derivatives of the
+C              system of differential equations.  If you do not
+C              provide a subroutine to evaluate it analytically (see
+C              description of the item JAC in the call list), it will
+C              be approximated by numerical differencing in this code.
+C              Although it is less trouble for you to have the code
+C              compute partial derivatives by numerical differencing,
+C              the solution will be more reliable if you provide the
+C              derivatives via JAC.  Usually numerical differencing is
+C              more costly than evaluating derivatives in JAC, but
+C              sometimes it is not - this depends on your problem.
+C
+C           **** Do you want the code to evaluate the partial deriv-
+C                atives automatically by numerical differences ...
+C                 yes - set INFO(5) = 0
+C                  no - set INFO(5) = 1
+C                       and provide subroutine JAC for evaluating the
+C                       matrix of partial derivatives ****
+C
+C       INFO(6) - used only when INFO(12) = 0 (direct methods).
+C              DDASPK will perform much better if the matrix of
+C              partial derivatives, dG/dY + CJ*dG/dYPRIME (here CJ is
+C              a scalar determined by DDASPK), is banded and the code
+C              is told this.  In this case, the storage needed will be
+C              greatly reduced, numerical differencing will be performed
+C              much cheaper, and a number of important algorithms will
+C              execute much faster.  The differential equation is said 
+C              to have half-bandwidths ML (lower) and MU (upper) if 
+C              equation i involves only unknowns Y(j) with
+C                             i-ML .le. j .le. i+MU .
+C              For all i=1,2,...,NEQ.  Thus, ML and MU are the widths
+C              of the lower and upper parts of the band, respectively,
+C              with the main diagonal being excluded.  If you do not
+C              indicate that the equation has a banded matrix of partial
+C              derivatives the code works with a full matrix of NEQ**2
+C              elements (stored in the conventional way).  Computations
+C              with banded matrices cost less time and storage than with
+C              full matrices if  2*ML+MU .lt. NEQ.  If you tell the
+C              code that the matrix of partial derivatives has a banded
+C              structure and you want to provide subroutine JAC to
+C              compute the partial derivatives, then you must be careful
+C              to store the elements of the matrix in the special form
+C              indicated in the description of JAC.
+C
+C          **** Do you want to solve the problem using a full (dense)
+C               matrix (and not a special banded structure) ...
+C                yes - set INFO(6) = 0
+C                 no - set INFO(6) = 1
+C                       and provide the lower (ML) and upper (MU)
+C                       bandwidths by setting
+C                       IWORK(1)=ML
+C                       IWORK(2)=MU ****
+C
+C       INFO(7) - You can specify a maximum (absolute value of)
+C              stepsize, so that the code will avoid passing over very
+C              large regions.
+C
+C          ****  Do you want the code to decide on its own the maximum
+C                stepsize ...
+C                 yes - set INFO(7) = 0
+C                  no - set INFO(7) = 1
+C                       and define HMAX by setting
+C                       RWORK(2) = HMAX ****
+C
+C       INFO(8) -  Differential/algebraic problems may occasionally
+C              suffer from severe scaling difficulties on the first
+C              step.  If you know a great deal about the scaling of 
+C              your problem, you can help to alleviate this problem 
+C              by specifying an initial stepsize H0.
+C
+C          ****  Do you want the code to define its own initial
+C                stepsize ...
+C                 yes - set INFO(8) = 0
+C                  no - set INFO(8) = 1
+C                       and define H0 by setting
+C                       RWORK(3) = H0 ****
+C
+C       INFO(9) -  If storage is a severe problem, you can save some
+C              storage by restricting the maximum method order MAXORD.
+C              The default value is 5.  For each order decrease below 5,
+C              the code requires NEQ fewer locations, but it is likely 
+C              to be slower.  In any case, you must have 
+C              1 .le. MAXORD .le. 5.
+C          ****  Do you want the maximum order to default to 5 ...
+C                 yes - set INFO(9) = 0
+C                  no - set INFO(9) = 1
+C                       and define MAXORD by setting
+C                       IWORK(3) = MAXORD ****
+C
+C       INFO(10) - If you know that certain components of the
+C              solutions to your equations are always nonnegative
+C              (or nonpositive), it may help to set this
+C              parameter.  There are three options that are
+C              available:
+C              1.  To have constraint checking only in the initial
+C                  condition calculation.
+C              2.  To enforce nonnegativity in Y during the integration.
+C              3.  To enforce both options 1 and 2.
+C
+C              When selecting option 2 or 3, it is probably best to try the
+C              code without using this option first, and only use
+C              this option if that does not work very well.
+C
+C          ****  Do you want the code to solve the problem without
+C                invoking any special inequality constraints ...
+C                 yes - set INFO(10) = 0
+C                  no - set INFO(10) = 1 to have option 1 enforced 
+C                  no - set INFO(10) = 2 to have option 2 enforced
+C                  no - set INFO(10) = 3 to have option 3 enforced ****
+C
+C                  If you have specified INFO(10) = 1 or 3, then you
+C                  will also need to identify how each component of Y
+C                  in the initial condition calculation is constrained.
+C                  You must set:
+C                  IWORK(40+I) = +1 if Y(I) must be .GE. 0,
+C                  IWORK(40+I) = +2 if Y(I) must be .GT. 0,
+C                  IWORK(40+I) = -1 if Y(I) must be .LE. 0, while
+C                  IWORK(40+I) = -2 if Y(I) must be .LT. 0, while
+C                  IWORK(40+I) =  0 if Y(I) is not constrained.
+C
+C       INFO(11) - DDASPK normally requires the initial T, Y, and
+C              YPRIME to be consistent.  That is, you must have
+C              G(T,Y,YPRIME) = 0 at the initial T.  If you do not know
+C              the initial conditions precisely, in some cases
+C              DDASPK may be able to compute it.
+C
+C              Denoting the differential variables in Y by Y_d
+C              and the algebraic variables by Y_a, DDASPK can solve
+C              one of two initialization problems:
+C              1.  Given Y_d, calculate Y_a and Y'_d, or
+C              2.  Given Y', calculate Y.
+C              In either case, initial values for the given
+C              components are input, and initial guesses for
+C              the unknown components must also be provided as input.
+C
+C          ****  Are the initial T, Y, YPRIME consistent ...
+C
+C                 yes - set INFO(11) = 0
+C                  no - set INFO(11) = 1 to calculate option 1 above,
+C                    or set INFO(11) = 2 to calculate option 2 ****
+C
+C                  If you have specified INFO(11) = 1, then you
+C                  will also need to identify  which are the
+C                  differential and which are the algebraic
+C                  components (algebraic components are components
+C                  whose derivatives do not appear explicitly
+C                  in the function G(T,Y,YPRIME)).  You must set:
+C                  IWORK(LID+I) = +1 if Y(I) is a differential variable
+C                  IWORK(LID+I) = -1 if Y(I) is an algebraic variable,
+C                  where LID = 40 if INFO(10) = 0 or 2 and LID = 40+NEQ
+C                  if INFO(10) = 1 or 3.
+C
+C       INFO(12) - Except for the addition of the RES argument CJ,
+C              DDASPK by default is downward-compatible with DDASSL,
+C              which uses only direct (dense or band) methods to solve 
+C              the linear systems involved.  You must set INFO(12) to
+C              indicate whether you want the direct methods or the
+C              Krylov iterative method.
+C          ****   Do you want DDASPK to use standard direct methods
+C                 (dense or band) or the Krylov (iterative) method ...
+C                   direct methods - set INFO(12) = 0.
+C                   Krylov method  - set INFO(12) = 1,
+C                       and check the settings of INFO(13) and INFO(15).
+C
+C       INFO(13) - used when INFO(12) = 1 (Krylov methods).  
+C              DDASPK uses scalars MAXL, KMP, NRMAX, and EPLI for the
+C              iterative solution of linear systems.  INFO(13) allows 
+C              you to override the default values of these parameters.  
+C              These parameters and their defaults are as follows:
+C              MAXL = maximum number of iterations in the SPIGMR 
+C                 algorithm (MAXL .le. NEQ).  The default is 
+C                 MAXL = MIN(5,NEQ).
+C              KMP = number of vectors on which orthogonalization is 
+C                 done in the SPIGMR algorithm.  The default is 
+C                 KMP = MAXL, which corresponds to complete GMRES 
+C                 iteration, as opposed to the incomplete form.  
+C              NRMAX = maximum number of restarts of the SPIGMR 
+C                 algorithm per nonlinear iteration.  The default is
+C                 NRMAX = 5.
+C              EPLI = convergence test constant in SPIGMR algorithm.
+C                 The default is EPLI = 0.05.
+C              Note that the length of RWORK depends on both MAXL 
+C              and KMP.  See the definition of LRW below.
+C          ****   Are MAXL, KMP, and EPLI to be given their
+C                 default values ...
+C                  yes - set INFO(13) = 0
+C                   no - set INFO(13) = 1,
+C                        and set all of the following:
+C                        IWORK(24) = MAXL (1 .le. MAXL .le. NEQ)
+C                        IWORK(25) = KMP  (1 .le. KMP .le. MAXL)
+C                        IWORK(26) = NRMAX  (NRMAX .ge. 0)
+C                        RWORK(10) = EPLI (0 .lt. EPLI .lt. 1.0) ****
+C
+C        INFO(14) - used with INFO(11) > 0 (initial condition 
+C               calculation is requested).  In this case, you may
+C               request control to be returned to the calling program
+C               immediately after the initial condition calculation,
+C               before proceeding to the integration of the system
+C               (e.g. to examine the computed Y and YPRIME).
+C               If this is done, and if the initialization succeeded
+C               (IDID = 4), you should reset INFO(11) to 0 for the
+C               next call, to prevent the solver from repeating the 
+C               initialization (and to avoid an infinite loop). 
+C          ****   Do you want to proceed to the integration after
+C                 the initial condition calculation is done ...
+C                 yes - set INFO(14) = 0
+C                  no - set INFO(14) = 1                        ****
+C
+C        INFO(15) - used when INFO(12) = 1 (Krylov methods).
+C               When using preconditioning in the Krylov method,
+C               you must supply a subroutine, PSOL, which solves the
+C               associated linear systems using P.
+C               The usage of DDASPK is simpler if PSOL can carry out
+C               the solution without any prior calculation of data.
+C               However, if some partial derivative data is to be
+C               calculated in advance and used repeatedly in PSOL,
+C               then you must supply a JAC routine to do this,
+C               and set INFO(15) to indicate that JAC is to be called
+C               for this purpose.  For example, P might be an
+C               approximation to a part of the matrix A which can be
+C               calculated and LU-factored for repeated solutions of
+C               the preconditioner system.  The arrays WP and IWP
+C               (described under JAC and PSOL) can be used to
+C               communicate data between JAC and PSOL.
+C          ****   Does PSOL operate with no prior preparation ...
+C                 yes - set INFO(15) = 0 (no JAC routine)
+C                  no - set INFO(15) = 1
+C                       and supply a JAC routine to evaluate and
+C                       preprocess any required Jacobian data.  ****
+C
+C         INFO(16) - option to exclude algebraic variables from
+C               the error test.  
+C          ****   Do you wish to control errors locally on
+C                 all the variables...
+C                 yes - set INFO(16) = 0
+C                  no - set INFO(16) = 1
+C                       If you have specified INFO(16) = 1, then you
+C                       will also need to identify  which are the
+C                       differential and which are the algebraic
+C                       components (algebraic components are components
+C                       whose derivatives do not appear explicitly
+C                       in the function G(T,Y,YPRIME)).  You must set:
+C                       IWORK(LID+I) = +1 if Y(I) is a differential 
+C                                      variable, and
+C                       IWORK(LID+I) = -1 if Y(I) is an algebraic
+C                                      variable,
+C                       where LID = 40 if INFO(10) = 0 or 2 and 
+C                       LID = 40 + NEQ if INFO(10) = 1 or 3.
+C
+C       INFO(17) - used when INFO(11) > 0 (DDASPK is to do an 
+C              initial condition calculation).
+C              DDASPK uses several heuristic control quantities in the
+C              initial condition calculation.  They have default values,
+C              but can  also be set by the user using INFO(17).
+C              These parameters and their defaults are as follows:
+C              MXNIT  = maximum number of Newton iterations
+C                 per Jacobian or preconditioner evaluation.
+C                 The default is:
+C                 MXNIT =  5 in the direct case (INFO(12) = 0), and
+C                 MXNIT = 15 in the Krylov case (INFO(12) = 1).
+C              MXNJ   = maximum number of Jacobian or preconditioner
+C                 evaluations.  The default is:
+C                 MXNJ = 6 in the direct case (INFO(12) = 0), and
+C                 MXNJ = 2 in the Krylov case (INFO(12) = 1).
+C              MXNH   = maximum number of values of the artificial
+C                 stepsize parameter H to be tried if INFO(11) = 1.
+C                 The default is MXNH = 5.
+C                 NOTE: the maximum number of Newton iterations
+C                 allowed in all is MXNIT*MXNJ*MXNH if INFO(11) = 1,
+C                 and MXNIT*MXNJ if INFO(11) = 2.
+C              LSOFF  = flag to turn off the linesearch algorithm
+C                 (LSOFF = 0 means linesearch is on, LSOFF = 1 means
+C                 it is turned off).  The default is LSOFF = 0.
+C              STPTOL = minimum scaled step in linesearch algorithm.
+C                 The default is STPTOL = (unit roundoff)**(2/3).
+C              EPINIT = swing factor in the Newton iteration convergence
+C                 test.  The test is applied to the residual vector,
+C                 premultiplied by the approximate Jacobian (in the
+C                 direct case) or the preconditioner (in the Krylov
+C                 case).  For convergence, the weighted RMS norm of
+C                 this vector (scaled by the error weights) must be
+C                 less than EPINIT*EPCON, where EPCON = .33 is the
+C                 analogous test constant used in the time steps.
+C                 The default is EPINIT = .01.
+C          ****   Are the initial condition heuristic controls to be 
+C                 given their default values...
+C                  yes - set INFO(17) = 0
+C                   no - set INFO(17) = 1,
+C                        and set all of the following:
+C                        IWORK(32) = MXNIT (.GT. 0)
+C                        IWORK(33) = MXNJ (.GT. 0)
+C                        IWORK(34) = MXNH (.GT. 0)
+C                        IWORK(35) = LSOFF ( = 0 or 1)
+C                        RWORK(14) = STPTOL (.GT. 0.0)
+C                        RWORK(15) = EPINIT (.GT. 0.0)  ****
+C
+C         INFO(18) - option to get extra printing in initial condition 
+C                calculation.
+C          ****   Do you wish to have extra printing...
+C                 no  - set INFO(18) = 0
+C                 yes - set INFO(18) = 1 for minimal printing, or
+C                       set INFO(18) = 2 for full printing.
+C                       If you have specified INFO(18) .ge. 1, data
+C                       will be printed with the error handler routines.
+C                       To print to a non-default unit number L, include
+C                       the line  CALL XSETUN(L)  in your program.  ****
+C
+C   RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL)
+C               error tolerances to tell the code how accurately you
+C               want the solution to be computed.  They must be defined
+C               as variables because the code may change them.
+C               you have two choices --
+C                     Both RTOL and ATOL are scalars (INFO(2) = 0), or
+C                     both RTOL and ATOL are vectors (INFO(2) = 1).
+C               In either case all components must be non-negative.
+C
+C               The tolerances are used by the code in a local error
+C               test at each step which requires roughly that
+C                        abs(local error in Y(i)) .le. EWT(i) ,
+C               where EWT(i) = RTOL*abs(Y(i)) + ATOL is an error weight 
+C               quantity, for each vector component.
+C               (More specifically, a root-mean-square norm is used to
+C               measure the size of vectors, and the error test uses the
+C               magnitude of the solution at the beginning of the step.)
+C
+C               The true (global) error is the difference between the
+C               true solution of the initial value problem and the
+C               computed approximation.  Practically all present day
+C               codes, including this one, control the local error at
+C               each step and do not even attempt to control the global
+C               error directly.
+C
+C               Usually, but not always, the true accuracy of
+C               the computed Y is comparable to the error tolerances.
+C               This code will usually, but not always, deliver a more
+C               accurate solution if you reduce the tolerances and
+C               integrate again.  By comparing two such solutions you 
+C               can get a fairly reliable idea of the true error in the
+C               solution at the larger tolerances.
+C
+C               Setting ATOL = 0. results in a pure relative error test
+C               on that component.  Setting RTOL = 0. results in a pure
+C               absolute error test on that component.  A mixed test
+C               with non-zero RTOL and ATOL corresponds roughly to a
+C               relative error test when the solution component is
+C               much bigger than ATOL and to an absolute error test
+C               when the solution component is smaller than the
+C               threshold ATOL.
+C
+C               The code will not attempt to compute a solution at an
+C               accuracy unreasonable for the machine being used.  It
+C               will advise you if you ask for too much accuracy and
+C               inform you as to the maximum accuracy it believes
+C               possible.
+C
+C  RWORK(*) -- a real work array, which should be dimensioned in your
+C               calling program with a length equal to the value of
+C               LRW (or greater).
+C
+C  LRW -- Set it to the declared length of the RWORK array.  The
+C               minimum length depends on the options you have selected,
+C               given by a base value plus additional storage as described
+C               below.
+C
+C               If INFO(12) = 0 (standard direct method), the base value is
+C               base = 50 + max(MAXORD+4,7)*NEQ.
+C               The default value is MAXORD = 5 (see INFO(9)).  With the
+C               default MAXORD, base = 50 + 9*NEQ.
+C               Additional storage must be added to the base value for
+C               any or all of the following options:
+C                 if INFO(6) = 0 (dense matrix), add NEQ**2
+C                 if INFO(6) = 1 (banded matrix), then
+C                    if INFO(5) = 0, add (2*ML+MU+1)*NEQ + 2*(NEQ/(ML+MU+1)+1),
+C                    if INFO(5) = 1, add (2*ML+MU+1)*NEQ,
+C                 if INFO(16) = 1, add NEQ.
+C
+C              If INFO(12) = 1 (Krylov method), the base value is
+C              base = 50 + (MAXORD+5)*NEQ + (MAXL+3+MIN0(1,MAXL-KMP))*NEQ +
+C                      + (MAXL+3)*MAXL + 1 + LENWP.
+C              See PSOL for description of LENWP.  The default values are:
+C              MAXORD = 5 (see INFO(9)), MAXL = min(5,NEQ) and KMP = MAXL 
+C              (see INFO(13)).
+C              With the default values for MAXORD, MAXL and KMP,
+C              base = 91 + 18*NEQ + LENWP.
+C              Additional storage must be added to the base value for
+C              any or all of the following options:
+C                if INFO(16) = 1, add NEQ.
+C
+C
+C  IWORK(*) -- an integer work array, which should be dimensioned in
+C              your calling program with a length equal to the value
+C              of LIW (or greater).
+C
+C  LIW -- Set it to the declared length of the IWORK array.  The
+C             minimum length depends on the options you have selected,
+C             given by a base value plus additional storage as described
+C             below.
+C
+C             If INFO(12) = 0 (standard direct method), the base value is
+C             base = 40 + NEQ.
+C             IF INFO(10) = 1 or 3, add NEQ to the base value.
+C             If INFO(11) = 1 or INFO(16) =1, add NEQ to the base value.
+C
+C             If INFO(12) = 1 (Krylov method), the base value is
+C             base = 40 + LENIWP.
+C             See PSOL for description of LENIWP.
+C             IF INFO(10) = 1 or 3, add NEQ to the base value.
+C             If INFO(11) = 1 or INFO(16) = 1, add NEQ to the base value.
+C
+C
+C  RPAR, IPAR -- These are arrays of double precision and integer type,
+C             respectively, which are available for you to use
+C             for communication between your program that calls
+C             DDASPK and the RES subroutine (and the JAC and PSOL
+C             subroutines).  They are not altered by DDASPK.
+C             If you do not need RPAR or IPAR, ignore these
+C             parameters by treating them as dummy arguments.
+C             If you do choose to use them, dimension them in
+C             your calling program and in RES (and in JAC and PSOL)
+C             as arrays of appropriate length.
+C
+C  JAC -- This is the name of a routine that you may supply
+C         (optionally) that relates to the Jacobian matrix of the
+C         nonlinear system that the code must solve at each T step.
+C         The role of JAC (and its call sequence) depends on whether
+C         a direct (INFO(12) = 0) or Krylov (INFO(12) = 1) method 
+C         is selected.
+C
+C         **** INFO(12) = 0 (direct methods):
+C           If you are letting the code generate partial derivatives
+C           numerically (INFO(5) = 0), then JAC can be absent
+C           (or perhaps a dummy routine to satisfy the loader).
+C           Otherwise you must supply a JAC routine to compute
+C           the matrix A = dG/dY + CJ*dG/dYPRIME.  It must have
+C           the form
+C
+C           SUBROUTINE JAC (T, Y, YPRIME, PD, CJ, RPAR, IPAR)
+C
+C           The JAC routine must dimension Y, YPRIME, and PD (and RPAR
+C           and IPAR if used).  CJ is a scalar which is input to JAC.
+C           For the given values of T, Y, and YPRIME, the JAC routine
+C           must evaluate the nonzero elements of the matrix A, and 
+C           store these values in the array PD.  The elements of PD are 
+C           set to zero before each call to JAC, so that only nonzero
+C           elements need to be defined.
+C           The way you store the elements into the PD array depends
+C           on the structure of the matrix indicated by INFO(6).
+C           *** INFO(6) = 0 (full or dense matrix) ***
+C               Give PD a first dimension of NEQ.  When you evaluate the
+C               nonzero partial derivatives of equation i (i.e. of G(i))
+C               with respect to component j (of Y and YPRIME), you must
+C               store the element in PD according to
+C                  PD(i,j) = dG(i)/dY(j) + CJ*dG(i)/dYPRIME(j).
+C           *** INFO(6) = 1 (banded matrix with half-bandwidths ML, MU
+C                            as described under INFO(6)) ***
+C               Give PD a first dimension of 2*ML+MU+1.  When you 
+C               evaluate the nonzero partial derivatives of equation i 
+C               (i.e. of G(i)) with respect to component j (of Y and 
+C               YPRIME), you must store the element in PD according to 
+C                  IROW = i - j + ML + MU + 1
+C                  PD(IROW,j) = dG(i)/dY(j) + CJ*dG(i)/dYPRIME(j).
+C
+C          **** INFO(12) = 1 (Krylov method):
+C            If you are not calculating Jacobian data in advance for use
+C            in PSOL (INFO(15) = 0), JAC can be absent (or perhaps a
+C            dummy routine to satisfy the loader).  Otherwise, you may
+C            supply a JAC routine to compute and preprocess any parts of
+C            of the Jacobian matrix  A = dG/dY + CJ*dG/dYPRIME that are
+C            involved in the preconditioner matrix P.
+C            It is to have the form
+C
+C            SUBROUTINE JAC (RES, IRES, NEQ, T, Y, YPRIME, REWT, SAVR,
+C                            WK, H, CJ, WP, IWP, IER, RPAR, IPAR)
+C
+C           The JAC routine must dimension Y, YPRIME, REWT, SAVR, WK,
+C           and (if used) WP, IWP, RPAR, and IPAR.
+C           The Y, YPRIME, and SAVR arrays contain the current values
+C           of Y, YPRIME, and the residual G, respectively.  
+C           The array WK is work space of length NEQ.  
+C           H is the step size.  CJ is a scalar, input to JAC, that is
+C           normally proportional to 1/H.  REWT is an array of 
+C           reciprocal error weights, 1/EWT(i), where EWT(i) is
+C           RTOL*abs(Y(i)) + ATOL (unless you supplied routine DDAWTS
+C           instead), for use in JAC if needed.  For example, if JAC
+C           computes difference quotient approximations to partial
+C           derivatives, the REWT array may be useful in setting the
+C           increments used.  The JAC routine should do any
+C           factorization operations called for, in preparation for
+C           solving linear systems in PSOL.  The matrix P should
+C           be an approximation to the Jacobian,
+C           A = dG/dY + CJ*dG/dYPRIME.
+C
+C           WP and IWP are real and integer work arrays which you may
+C           use for communication between your JAC routine and your
+C           PSOL routine.  These may be used to store elements of the 
+C           preconditioner P, or related matrix data (such as factored
+C           forms).  They are not altered by DDASPK.
+C           If you do not need WP or IWP, ignore these parameters by
+C           treating them as dummy arguments.  If you do use them,
+C           dimension them appropriately in your JAC and PSOL routines.
+C           See the PSOL description for instructions on setting 
+C           the lengths of WP and IWP.
+C
+C           On return, JAC should set the error flag IER as follows..
+C             IER = 0    if JAC was successful,
+C             IER .ne. 0 if JAC was unsuccessful (e.g. if Y or YPRIME
+C                        was illegal, or a singular matrix is found).
+C           (If IER .ne. 0, a smaller stepsize will be tried.)
+C           IER = 0 on entry to JAC, so need be reset only on a failure.
+C           If RES is used within JAC, then a nonzero value of IRES will
+C           override any nonzero value of IER (see the RES description).
+C
+C         Regardless of the method type, subroutine JAC must not
+C         alter T, Y(*), YPRIME(*), H, CJ, or REWT(*).
+C         You must declare the name JAC in an EXTERNAL statement in
+C         your program that calls DDASPK.
+C
+C PSOL --  This is the name of a routine you must supply if you have
+C         selected a Krylov method (INFO(12) = 1) with preconditioning.
+C         In the direct case (INFO(12) = 0), PSOL can be absent 
+C         (a dummy routine may have to be supplied to satisfy the 
+C         loader).  Otherwise, you must provide a PSOL routine to 
+C         solve linear systems arising from preconditioning.
+C         When supplied with INFO(12) = 1, the PSOL routine is to 
+C         have the form
+C
+C         SUBROUTINE PSOL (NEQ, T, Y, YPRIME, SAVR, WK, CJ, WGHT,
+C                          WP, IWP, B, EPLIN, IER, RPAR, IPAR)
+C
+C         The PSOL routine must solve linear systems of the form 
+C         P*x = b where P is the left preconditioner matrix.
+C
+C         The right-hand side vector b is in the B array on input, and
+C         PSOL must return the solution vector x in B.
+C         The Y, YPRIME, and SAVR arrays contain the current values
+C         of Y, YPRIME, and the residual G, respectively.  
+C
+C         Work space required by JAC and/or PSOL, and space for data to
+C         be communicated from JAC to PSOL is made available in the form
+C         of arrays WP and IWP, which are parts of the RWORK and IWORK
+C         arrays, respectively.  The lengths of these real and integer
+C         work spaces WP and IWP must be supplied in LENWP and LENIWP,
+C         respectively, as follows..
+C           IWORK(27) = LENWP = length of real work space WP
+C           IWORK(28) = LENIWP = length of integer work space IWP.
+C
+C         WK is a work array of length NEQ for use by PSOL.
+C         CJ is a scalar, input to PSOL, that is normally proportional
+C         to 1/H (H = stepsize).  If the old value of CJ
+C         (at the time of the last JAC call) is needed, it must have
+C         been saved by JAC in WP.
+C
+C         WGHT is an array of weights, to be used if PSOL uses an
+C         iterative method and performs a convergence test.  (In terms
+C         of the argument REWT to JAC, WGHT is REWT/sqrt(NEQ).)
+C         If PSOL uses an iterative method, it should use EPLIN
+C         (a heuristic parameter) as the bound on the weighted norm of
+C         the residual for the computed solution.  Specifically, the
+C         residual vector R should satisfy
+C              SQRT (SUM ( (R(i)*WGHT(i))**2 ) ) .le. EPLIN
+C
+C         PSOL must not alter NEQ, T, Y, YPRIME, SAVR, CJ, WGHT, EPLIN.
+C
+C         On return, PSOL should set the error flag IER as follows..
+C           IER = 0 if PSOL was successful,
+C           IER .lt. 0 if an unrecoverable error occurred, meaning
+C                 control will be passed to the calling routine,
+C           IER .gt. 0 if a recoverable error occurred, meaning that
+C                 the step will be retried with the same step size
+C                 but with a call to JAC to update necessary data,
+C                 unless the Jacobian data is current, in which case
+C                 the step will be retried with a smaller step size.
+C           IER = 0 on entry to PSOL so need be reset only on a failure.
+C
+C         You must declare the name PSOL in an EXTERNAL statement in
+C         your program that calls DDASPK.
+C
+C
+C  OPTIONALLY REPLACEABLE SUBROUTINE:
+C
+C  DDASPK uses a weighted root-mean-square norm to measure the 
+C  size of various error vectors.  The weights used in this norm
+C  are set in the following subroutine:
+C
+C    SUBROUTINE DDAWTS (NEQ, IWT, RTOL, ATOL, Y, EWT, RPAR, IPAR)
+C    DIMENSION RTOL(*), ATOL(*), Y(*), EWT(*), RPAR(*), IPAR(*)
+C
+C  A DDAWTS routine has been included with DDASPK which sets the
+C  weights according to
+C    EWT(I) = RTOL*ABS(Y(I)) + ATOL
+C  in the case of scalar tolerances (IWT = 0) or
+C    EWT(I) = RTOL(I)*ABS(Y(I)) + ATOL(I)
+C  in the case of array tolerances (IWT = 1).  (IWT is INFO(2).)
+C  In some special cases, it may be appropriate for you to define
+C  your own error weights by writing a subroutine DDAWTS to be 
+C  called instead of the version supplied.  However, this should 
+C  be attempted only after careful thought and consideration. 
+C  If you supply this routine, you may use the tolerances and Y 
+C  as appropriate, but do not overwrite these variables.  You
+C  may also use RPAR and IPAR to communicate data as appropriate.
+C  ***Note: Aside from the values of the weights, the choice of 
+C  norm used in DDASPK (weighted root-mean-square) is not subject
+C  to replacement by the user.  In this respect, DDASPK is not
+C  downward-compatible with the original DDASSL solver (in which
+C  the norm routine was optionally user-replaceable).
+C
+C
+C------OUTPUT - AFTER ANY RETURN FROM DDASPK----------------------------
+C
+C  The principal aim of the code is to return a computed solution at
+C  T = TOUT, although it is also possible to obtain intermediate
+C  results along the way.  To find out whether the code achieved its
+C  goal or if the integration process was interrupted before the task
+C  was completed, you must check the IDID parameter.
+C
+C
+C   T -- The output value of T is the point to which the solution
+C        was successfully advanced.
+C
+C   Y(*) -- contains the computed solution approximation at T.
+C
+C   YPRIME(*) -- contains the computed derivative approximation at T.
+C
+C   IDID -- reports what the code did, described as follows:
+C
+C                     *** TASK COMPLETED ***
+C                Reported by positive values of IDID
+C
+C           IDID = 1 -- a step was successfully taken in the
+C                   intermediate-output mode.  The code has not
+C                   yet reached TOUT.
+C
+C           IDID = 2 -- the integration to TSTOP was successfully
+C                   completed (T = TSTOP) by stepping exactly to TSTOP.
+C
+C           IDID = 3 -- the integration to TOUT was successfully
+C                   completed (T = TOUT) by stepping past TOUT.
+C                   Y(*) and YPRIME(*) are obtained by interpolation.
+C
+C           IDID = 4 -- the initial condition calculation, with
+C                   INFO(11) > 0, was successful, and INFO(14) = 1.
+C                   No integration steps were taken, and the solution
+C                   is not considered to have been started.
+C
+C                    *** TASK INTERRUPTED ***
+C                Reported by negative values of IDID
+C
+C           IDID = -1 -- a large amount of work has been expended
+C                     (about 500 steps).
+C
+C           IDID = -2 -- the error tolerances are too stringent.
+C
+C           IDID = -3 -- the local error test cannot be satisfied
+C                     because you specified a zero component in ATOL
+C                     and the corresponding computed solution component
+C                     is zero.  Thus, a pure relative error test is
+C                     impossible for this component.
+C
+C           IDID = -5 -- there were repeated failures in the evaluation
+C                     or processing of the preconditioner (in JAC).
+C
+C           IDID = -6 -- DDASPK had repeated error test failures on the
+C                     last attempted step.
+C
+C           IDID = -7 -- the nonlinear system solver in the time integration
+C                     could not converge.
+C
+C           IDID = -8 -- the matrix of partial derivatives appears
+C                     to be singular (direct method).
+C
+C           IDID = -9 -- the nonlinear system solver in the time integration
+C                     failed to achieve convergence, and there were repeated 
+C                     error test failures in this step.
+C
+C           IDID =-10 -- the nonlinear system solver in the time integration 
+C                     failed to achieve convergence because IRES was equal 
+C                     to -1.
+C
+C           IDID =-11 -- IRES = -2 was encountered and control is
+C                     being returned to the calling program.
+C
+C           IDID =-12 -- DDASPK failed to compute the initial Y, YPRIME.
+C
+C           IDID =-13 -- unrecoverable error encountered inside user's
+C                     PSOL routine, and control is being returned to
+C                     the calling program.
+C
+C           IDID =-14 -- the Krylov linear system solver could not 
+C                     achieve convergence.
+C
+C           IDID =-15,..,-32 -- Not applicable for this code.
+C
+C                    *** TASK TERMINATED ***
+C                reported by the value of IDID=-33
+C
+C           IDID = -33 -- the code has encountered trouble from which
+C                   it cannot recover.  A message is printed
+C                   explaining the trouble and control is returned
+C                   to the calling program.  For example, this occurs
+C                   when invalid input is detected.
+C
+C   RTOL, ATOL -- these quantities remain unchanged except when
+C               IDID = -2.  In this case, the error tolerances have been
+C               increased by the code to values which are estimated to
+C               be appropriate for continuing the integration.  However,
+C               the reported solution at T was obtained using the input
+C               values of RTOL and ATOL.
+C
+C   RWORK, IWORK -- contain information which is usually of no interest
+C               to the user but necessary for subsequent calls. 
+C               However, you may be interested in the performance data
+C               listed below.  These quantities are accessed in RWORK 
+C               and IWORK but have internal mnemonic names, as follows..
+C
+C               RWORK(3)--contains H, the step size h to be attempted
+C                        on the next step.
+C
+C               RWORK(4)--contains TN, the current value of the
+C                        independent variable, i.e. the farthest point
+C                        integration has reached.  This will differ 
+C                        from T if interpolation has been performed 
+C                        (IDID = 3).
+C
+C               RWORK(7)--contains HOLD, the stepsize used on the last
+C                        successful step.  If INFO(11) = INFO(14) = 1,
+C                        this contains the value of H used in the
+C                        initial condition calculation.
+C
+C               IWORK(7)--contains K, the order of the method to be 
+C                        attempted on the next step.
+C
+C               IWORK(8)--contains KOLD, the order of the method used
+C                        on the last step.
+C
+C               IWORK(11)--contains NST, the number of steps (in T) 
+C                        taken so far.
+C
+C               IWORK(12)--contains NRE, the number of calls to RES 
+C                        so far.
+C
+C               IWORK(13)--contains NJE, the number of calls to JAC so
+C                        far (Jacobian or preconditioner evaluations).
+C
+C               IWORK(14)--contains NETF, the total number of error test
+C                        failures so far.
+C
+C               IWORK(15)--contains NCFN, the total number of nonlinear
+C                        convergence failures so far (includes counts
+C                        of singular iteration matrix or singular
+C                        preconditioners).
+C
+C               IWORK(16)--contains NCFL, the number of convergence
+C                        failures of the linear iteration so far.
+C
+C               IWORK(17)--contains LENIW, the length of IWORK actually
+C                        required.  This is defined on normal returns 
+C                        and on an illegal input return for
+C                        insufficient storage.
+C
+C               IWORK(18)--contains LENRW, the length of RWORK actually
+C                        required.  This is defined on normal returns 
+C                        and on an illegal input return for
+C                        insufficient storage.
+C
+C               IWORK(19)--contains NNI, the total number of nonlinear
+C                        iterations so far (each of which calls a
+C                        linear solver).
+C
+C               IWORK(20)--contains NLI, the total number of linear
+C                        (Krylov) iterations so far.
+C
+C               IWORK(21)--contains NPS, the number of PSOL calls so
+C                        far, for preconditioning solve operations or
+C                        for solutions with the user-supplied method.
+C
+C               Note: The various counters in IWORK do not include 
+C               counts during a call made with INFO(11) > 0 and
+C               INFO(14) = 1.
+C
+C
+C------INPUT - WHAT TO DO TO CONTINUE THE INTEGRATION  -----------------
+C              (CALLS AFTER THE FIRST)
+C
+C     This code is organized so that subsequent calls to continue the
+C     integration involve little (if any) additional effort on your
+C     part.  You must monitor the IDID parameter in order to determine
+C     what to do next.
+C
+C     Recalling that the principal task of the code is to integrate
+C     from T to TOUT (the interval mode), usually all you will need
+C     to do is specify a new TOUT upon reaching the current TOUT.
+C
+C     Do not alter any quantity not specifically permitted below.  In
+C     particular do not alter NEQ, T, Y(*), YPRIME(*), RWORK(*), 
+C     IWORK(*), or the differential equation in subroutine RES.  Any 
+C     such alteration constitutes a new problem and must be treated 
+C     as such, i.e. you must start afresh.
+C
+C     You cannot change from array to scalar error control or vice
+C     versa (INFO(2)), but you can change the size of the entries of
+C     RTOL or ATOL.  Increasing a tolerance makes the equation easier
+C     to integrate.  Decreasing a tolerance will make the equation
+C     harder to integrate and should generally be avoided.
+C
+C     You can switch from the intermediate-output mode to the
+C     interval mode (INFO(3)) or vice versa at any time.
+C
+C     If it has been necessary to prevent the integration from going
+C     past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
+C     code will not integrate to any TOUT beyond the currently
+C     specified TSTOP.  Once TSTOP has been reached, you must change
+C     the value of TSTOP or set INFO(4) = 0.  You may change INFO(4)
+C     or TSTOP at any time but you must supply the value of TSTOP in
+C     RWORK(1) whenever you set INFO(4) = 1.
+C
+C     Do not change INFO(5), INFO(6), INFO(12-17) or their associated
+C     IWORK/RWORK locations unless you are going to restart the code.
+C
+C                    *** FOLLOWING A COMPLETED TASK ***
+C
+C     If..
+C     IDID = 1, call the code again to continue the integration
+C                  another step in the direction of TOUT.
+C
+C     IDID = 2 or 3, define a new TOUT and call the code again.
+C                  TOUT must be different from T.  You cannot change
+C                  the direction of integration without restarting.
+C
+C     IDID = 4, reset INFO(11) = 0 and call the code again to begin
+C                  the integration.  (If you leave INFO(11) > 0 and
+C                  INFO(14) = 1, you may generate an infinite loop.)
+C                  In this situation, the next call to DASPK is 
+C                  considered to be the first call for the problem,
+C                  in that all initializations are done.
+C
+C                    *** FOLLOWING AN INTERRUPTED TASK ***
+C
+C     To show the code that you realize the task was interrupted and
+C     that you want to continue, you must take appropriate action and
+C     set INFO(1) = 1.
+C
+C     If..
+C     IDID = -1, the code has taken about 500 steps.  If you want to
+C                  continue, set INFO(1) = 1 and call the code again.
+C                  An additional 500 steps will be allowed.
+C
+C
+C     IDID = -2, the error tolerances RTOL, ATOL have been increased
+C                  to values the code estimates appropriate for
+C                  continuing.  You may want to change them yourself.
+C                  If you are sure you want to continue with relaxed
+C                  error tolerances, set INFO(1) = 1 and call the code
+C                  again.
+C
+C     IDID = -3, a solution component is zero and you set the
+C                  corresponding component of ATOL to zero.  If you
+C                  are sure you want to continue, you must first alter
+C                  the error criterion to use positive values of ATOL 
+C                  for those components corresponding to zero solution
+C                  components, then set INFO(1) = 1 and call the code
+C                  again.
+C
+C     IDID = -4  --- cannot occur with this code.
+C
+C     IDID = -5, your JAC routine failed with the Krylov method.  Check
+C                  for errors in JAC and restart the integration.
+C
+C     IDID = -6, repeated error test failures occurred on the last
+C                  attempted step in DDASPK.  A singularity in the
+C                  solution may be present.  If you are absolutely
+C                  certain you want to continue, you should restart
+C                  the integration.  (Provide initial values of Y and
+C                  YPRIME which are consistent.)
+C
+C     IDID = -7, repeated convergence test failures occurred on the last
+C                  attempted step in DDASPK.  An inaccurate or ill-
+C                  conditioned Jacobian or preconditioner may be the
+C                  problem.  If you are absolutely certain you want
+C                  to continue, you should restart the integration.
+C
+C
+C     IDID = -8, the matrix of partial derivatives is singular, with
+C                  the use of direct methods.  Some of your equations
+C                  may be redundant.  DDASPK cannot solve the problem
+C                  as stated.  It is possible that the redundant
+C                  equations could be removed, and then DDASPK could
+C                  solve the problem.  It is also possible that a
+C                  solution to your problem either does not exist
+C                  or is not unique.
+C
+C     IDID = -9, DDASPK had multiple convergence test failures, preceded
+C                  by multiple error test failures, on the last
+C                  attempted step.  It is possible that your problem is
+C                  ill-posed and cannot be solved using this code.  Or,
+C                  there may be a discontinuity or a singularity in the
+C                  solution.  If you are absolutely certain you want to
+C                  continue, you should restart the integration.
+C
+C     IDID = -10, DDASPK had multiple convergence test failures
+C                  because IRES was equal to -1.  If you are
+C                  absolutely certain you want to continue, you
+C                  should restart the integration.
+C
+C     IDID = -11, there was an unrecoverable error (IRES = -2) from RES
+C                  inside the nonlinear system solver.  Determine the
+C                  cause before trying again.
+C
+C     IDID = -12, DDASPK failed to compute the initial Y and YPRIME
+C                  vectors.  This could happen because the initial 
+C                  approximation to Y or YPRIME was not very good, or
+C                  because no consistent values of these vectors exist.
+C                  The problem could also be caused by an inaccurate or
+C                  singular iteration matrix, or a poor preconditioner.
+C
+C     IDID = -13, there was an unrecoverable error encountered inside 
+C                  your PSOL routine.  Determine the cause before 
+C                  trying again.
+C
+C     IDID = -14, the Krylov linear system solver failed to achieve
+C                  convergence.  This may be due to ill-conditioning
+C                  in the iteration matrix, or a singularity in the
+C                  preconditioner (if one is being used).
+C                  Another possibility is that there is a better
+C                  choice of Krylov parameters (see INFO(13)).
+C                  Possibly the failure is caused by redundant equations
+C                  in the system, or by inconsistent equations.
+C                  In that case, reformulate the system to make it
+C                  consistent and non-redundant.
+C
+C     IDID = -15,..,-32 --- Cannot occur with this code.
+C
+C                       *** FOLLOWING A TERMINATED TASK ***
+C
+C     If IDID = -33, you cannot continue the solution of this problem.
+C                  An attempt to do so will result in your run being
+C                  terminated.
+C
+C  ---------------------------------------------------------------------
+C
+C***REFERENCES
+C  1.  L. R. Petzold, A Description of DASSL: A Differential/Algebraic
+C      System Solver, in Scientific Computing, R. S. Stepleman et al.
+C      (Eds.), North-Holland, Amsterdam, 1983, pp. 65-68.
+C  2.  K. E. Brenan, S. L. Campbell, and L. R. Petzold, Numerical 
+C      Solution of Initial-Value Problems in Differential-Algebraic
+C      Equations, Elsevier, New York, 1989.
+C  3.  P. N. Brown and A. C. Hindmarsh, Reduced Storage Matrix Methods
+C      in Stiff ODE Systems, J. Applied Mathematics and Computation,
+C      31 (1989), pp. 40-91.
+C  4.  P. N. Brown, A. C. Hindmarsh, and L. R. Petzold, Using Krylov
+C      Methods in the Solution of Large-Scale Differential-Algebraic
+C      Systems, SIAM J. Sci. Comp., 15 (1994), pp. 1467-1488.
+C  5.  P. N. Brown, A. C. Hindmarsh, and L. R. Petzold, Consistent
+C      Initial Condition Calculation for Differential-Algebraic
+C      Systems, LLNL Report UCRL-JC-122175, August 1995; submitted to
+C      SIAM J. Sci. Comp.
+C
+C***ROUTINES CALLED
+C
+C   The following are all the subordinate routines used by DDASPK.
+C
+C   DDASIC computes consistent initial conditions.
+C   DYYPNW updates Y and YPRIME in linesearch for initial condition
+C          calculation.
+C   DDSTP  carries out one step of the integration.
+C   DCNSTR/DCNST0 check the current solution for constraint violations.
+C   DDAWTS sets error weight quantities.
+C   DINVWT tests and inverts the error weights.
+C   DDATRP performs interpolation to get an output solution.
+C   DDWNRM computes the weighted root-mean-square norm of a vector.
+C   D1MACH provides the unit roundoff of the computer.
+C   XERRWD/XSETF/XSETUN/IXSAV is a package to handle error messages. 
+C   DDASID nonlinear equation driver to initialize Y and YPRIME using
+C          direct linear system solver methods.  Interfaces to Newton
+C          solver (direct case).
+C   DNSID  solves the nonlinear system for unknown initial values by
+C          modified Newton iteration and direct linear system methods.
+C   DLINSD carries out linesearch algorithm for initial condition
+C          calculation (direct case).
+C   DFNRMD calculates weighted norm of preconditioned residual in
+C          initial condition calculation (direct case).
+C   DNEDD  nonlinear equation driver for direct linear system solver
+C          methods.  Interfaces to Newton solver (direct case).
+C   DMATD  assembles the iteration matrix (direct case).
+C   DNSD   solves the associated nonlinear system by modified
+C          Newton iteration and direct linear system methods.
+C   DSLVD  interfaces to linear system solver (direct case).
+C   DDASIK nonlinear equation driver to initialize Y and YPRIME using
+C          Krylov iterative linear system methods.  Interfaces to
+C          Newton solver (Krylov case).
+C   DNSIK  solves the nonlinear system for unknown initial values by
+C          Newton iteration and Krylov iterative linear system methods.
+C   DLINSK carries out linesearch algorithm for initial condition
+C          calculation (Krylov case).
+C   DFNRMK calculates weighted norm of preconditioned residual in
+C          initial condition calculation (Krylov case).
+C   DNEDK  nonlinear equation driver for iterative linear system solver
+C          methods.  Interfaces to Newton solver (Krylov case).
+C   DNSK   solves the associated nonlinear system by Inexact Newton
+C          iteration and (linear) Krylov iteration.
+C   DSLVK  interfaces to linear system solver (Krylov case).
+C   DSPIGM solves a linear system by SPIGMR algorithm.
+C   DATV   computes matrix-vector product in Krylov algorithm.
+C   DORTH  performs orthogonalization of Krylov basis vectors.
+C   DHEQR  performs QR factorization of Hessenberg matrix.
+C   DHELS  finds least-squares solution of Hessenberg linear system.
+C   DGETRF, DGETRS, DGBTRF, DGBTRS are LAPACK routines for solving 
+C          linear systems (dense or band direct methods).
+C   DAXPY, DCOPY, DDOT, DNRM2, DSCAL are Basic Linear Algebra (BLAS)
+C          routines.
+C
+C The routines called directly by DDASPK are:
+C   DCNST0, DDAWTS, DINVWT, D1MACH, DDWNRM, DDASIC, DDATRP, DDSTP,
+C   XERRWD
+C
+C***END PROLOGUE DDASPK
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      LOGICAL DONE, LAVL, LCFN, LCFL, LWARN
+      DIMENSION Y(*),YPRIME(*)
+      DIMENSION INFO(20)
+      DIMENSION RWORK(LRW),IWORK(LIW)
+      DIMENSION RTOL(*),ATOL(*)
+      DIMENSION RPAR(*),IPAR(*)
+      CHARACTER MSG*80
+      EXTERNAL  RES, JAC, PSOL, DDASID, DDASIK, DNEDD, DNEDK
+C
+C     Set pointers into IWORK.
+C
+      PARAMETER (LML=1, LMU=2, LMTYPE=4, 
+     *   LIWM=1, LMXORD=3, LJCALC=5, LPHASE=6, LK=7, LKOLD=8,
+     *   LNS=9, LNSTL=10, LNST=11, LNRE=12, LNJE=13, LETF=14, LNCFN=15,
+     *   LNCFL=16, LNIW=17, LNRW=18, LNNI=19, LNLI=20, LNPS=21,
+     *   LNPD=22, LMITER=23, LMAXL=24, LKMP=25, LNRMAX=26, LLNWP=27,
+     *   LLNIWP=28, LLOCWP=29, LLCIWP=30, LKPRIN=31,
+     *   LMXNIT=32, LMXNJ=33, LMXNH=34, LLSOFF=35, LICNS=41)
+C
+C     Set pointers into RWORK.
+C
+      PARAMETER (LTSTOP=1, LHMAX=2, LH=3, LTN=4, LCJ=5, LCJOLD=6,
+     *   LHOLD=7, LS=8, LROUND=9, LEPLI=10, LSQRN=11, LRSQRN=12,
+     *   LEPCON=13, LSTOL=14, LEPIN=15,
+     *   LALPHA=21, LBETA=27, LGAMMA=33, LPSI=39, LSIGMA=45, LDELTA=51)
+C
+      SAVE LID, LENID, NONNEG
+C
+C
+C***FIRST EXECUTABLE STATEMENT  DDASPK
+C
+C
+      IF(INFO(1).NE.0) GO TO 100
+C
+C-----------------------------------------------------------------------
+C     This block is executed for the initial call only.
+C     It contains checking of inputs and initializations.
+C-----------------------------------------------------------------------
+C
+C     First check INFO array to make sure all elements of INFO
+C     Are within the proper range.  (INFO(1) is checked later, because
+C     it must be tested on every call.) ITEMP holds the location
+C     within INFO which may be out of range.
+C
+      DO 10 I=2,9
+         ITEMP = I
+         IF (INFO(I) .NE. 0 .AND. INFO(I) .NE. 1) GO TO 701
+ 10      CONTINUE
+      ITEMP = 10
+      IF(INFO(10).LT.0 .OR. INFO(10).GT.3) GO TO 701
+      ITEMP = 11
+      IF(INFO(11).LT.0 .OR. INFO(11).GT.2) GO TO 701
+      DO 15 I=12,17
+         ITEMP = I
+         IF (INFO(I) .NE. 0 .AND. INFO(I) .NE. 1) GO TO 701
+ 15      CONTINUE
+      ITEMP = 18
+      IF(INFO(18).LT.0 .OR. INFO(18).GT.2) GO TO 701
+
+C
+C     Check NEQ to see if it is positive.
+C
+      IF (NEQ .LE. 0) GO TO 702
+C
+C     Check and compute maximum order.
+C
+      MXORD=5
+      IF (INFO(9) .NE. 0) THEN
+         MXORD=IWORK(LMXORD)
+         IF (MXORD .LT. 1 .OR. MXORD .GT. 5) GO TO 703
+         ENDIF
+      IWORK(LMXORD)=MXORD
+C
+C     Set and/or check inputs for constraint checking (INFO(10) .NE. 0).
+C     Set values for ICNFLG, NONNEG, and pointer LID.
+C
+      ICNFLG = 0
+      NONNEG = 0
+      LID = LICNS
+      IF (INFO(10) .EQ. 0) GO TO 20
+      IF (INFO(10) .EQ. 1) THEN
+         ICNFLG = 1
+         NONNEG = 0
+         LID = LICNS + NEQ
+      ELSEIF (INFO(10) .EQ. 2) THEN
+         ICNFLG = 0
+         NONNEG = 1
+      ELSE
+         ICNFLG = 1
+         NONNEG = 1
+         LID = LICNS + NEQ
+      ENDIF
+C
+ 20   CONTINUE
+C
+C     Set and/or check inputs for Krylov solver (INFO(12) .NE. 0).
+C     If indicated, set default values for MAXL, KMP, NRMAX, and EPLI.
+C     Otherwise, verify inputs required for iterative solver.
+C
+      IF (INFO(12) .EQ. 0) GO TO 25
+C
+      IWORK(LMITER) = INFO(12)
+      IF (INFO(13) .EQ. 0) THEN
+         IWORK(LMAXL) = MIN(5,NEQ)
+         IWORK(LKMP) = IWORK(LMAXL)
+         IWORK(LNRMAX) = 5
+         RWORK(LEPLI) = 0.05D0
+      ELSE
+         IF(IWORK(LMAXL) .LT. 1 .OR. IWORK(LMAXL) .GT. NEQ) GO TO 720
+         IF(IWORK(LKMP) .LT. 1 .OR. IWORK(LKMP) .GT. IWORK(LMAXL))
+     1      GO TO 721
+         IF(IWORK(LNRMAX) .LT. 0) GO TO 722
+         IF(RWORK(LEPLI).LE.0.0D0 .OR. RWORK(LEPLI).GE.1.0D0)GO TO 723
+         ENDIF
+C
+ 25   CONTINUE
+C
+C     Set and/or check controls for the initial condition calculation
+C     (INFO(11) .GT. 0).  If indicated, set default values.
+C     Otherwise, verify inputs required for iterative solver.
+C
+      IF (INFO(11) .EQ. 0) GO TO 30
+      IF (INFO(17) .EQ. 0) THEN
+        IWORK(LMXNIT) = 5
+        IF (INFO(12) .GT. 0) IWORK(LMXNIT) = 15
+        IWORK(LMXNJ) = 6
+        IF (INFO(12) .GT. 0) IWORK(LMXNJ) = 2
+        IWORK(LMXNH) = 5
+        IWORK(LLSOFF) = 0
+        RWORK(LEPIN) = 0.01D0
+      ELSE
+        IF (IWORK(LMXNIT) .LE. 0) GO TO 725
+        IF (IWORK(LMXNJ) .LE. 0) GO TO 725
+        IF (IWORK(LMXNH) .LE. 0) GO TO 725
+        LSOFF = IWORK(LLSOFF)
+        IF (LSOFF .LT. 0 .OR. LSOFF .GT. 1) GO TO 725
+        IF (RWORK(LEPIN) .LE. 0.0D0) GO TO 725
+        ENDIF
+C
+ 30   CONTINUE
+C
+C     Below is the computation and checking of the work array lengths
+C     LENIW and LENRW, using direct methods (INFO(12) = 0) or
+C     the Krylov methods (INFO(12) = 1).
+C
+      LENIC = 0
+      IF (INFO(10) .EQ. 1 .OR. INFO(10) .EQ. 3) LENIC = NEQ
+      LENID = 0
+      IF (INFO(11) .EQ. 1 .OR. INFO(16) .EQ. 1) LENID = NEQ
+      IF (INFO(12) .EQ. 0) THEN
+C
+C        Compute MTYPE, etc.  Check ML and MU.
+C
+         NCPHI = MAX(MXORD + 1, 4)
+         IF(INFO(6).EQ.0) THEN 
+            LENPD = NEQ**2
+            LENRW = 50 + (NCPHI+3)*NEQ + LENPD
+            IF(INFO(5).EQ.0) THEN
+               IWORK(LMTYPE)=2
+            ELSE
+               IWORK(LMTYPE)=1
+            ENDIF
+         ELSE
+            IF(IWORK(LML).LT.0.OR.IWORK(LML).GE.NEQ)GO TO 717
+            IF(IWORK(LMU).LT.0.OR.IWORK(LMU).GE.NEQ)GO TO 718
+            LENPD=(2*IWORK(LML)+IWORK(LMU)+1)*NEQ
+            IF(INFO(5).EQ.0) THEN
+               IWORK(LMTYPE)=5
+               MBAND=IWORK(LML)+IWORK(LMU)+1
+               MSAVE=(NEQ/MBAND)+1
+               LENRW = 50 + (NCPHI+3)*NEQ + LENPD + 2*MSAVE
+            ELSE
+               IWORK(LMTYPE)=4
+               LENRW = 50 + (NCPHI+3)*NEQ + LENPD
+            ENDIF
+         ENDIF
+C
+C        Compute LENIW, LENWP, LENIWP.
+C
+         LENIW = 40 + LENIC + LENID + NEQ
+         LENWP = 0
+         LENIWP = 0
+C
+      ELSE IF (INFO(12) .EQ. 1)  THEN
+         MAXL = IWORK(LMAXL)
+         LENWP = IWORK(LLNWP)
+         LENIWP = IWORK(LLNIWP)
+         LENPD = (MAXL+3+MIN0(1,MAXL-IWORK(LKMP)))*NEQ
+     1         + (MAXL+3)*MAXL + 1 + LENWP
+         LENRW = 50 + (IWORK(LMXORD)+5)*NEQ + LENPD
+         LENIW = 40 + LENIC + LENID + LENIWP
+C
+      ENDIF
+      IF(INFO(16) .NE. 0) LENRW = LENRW + NEQ
+C
+C     Check lengths of RWORK and IWORK.
+C
+      IWORK(LNIW)=LENIW
+      IWORK(LNRW)=LENRW
+      IWORK(LNPD)=LENPD
+      IWORK(LLOCWP) = LENPD-LENWP+1
+      IF(LRW.LT.LENRW)GO TO 704
+      IF(LIW.LT.LENIW)GO TO 705
+C
+C     Check ICNSTR for legality.
+C
+      IF (LENIC .GT. 0) THEN
+        DO 40 I = 1,NEQ
+          ICI = IWORK(LICNS-1+I)
+          IF (ICI .LT. -2 .OR. ICI .GT. 2) GO TO 726
+ 40       CONTINUE
+        ENDIF
+C
+C     Check Y for consistency with constraints.
+C
+      IF (LENIC .GT. 0) THEN
+        CALL DCNST0(NEQ,Y,IWORK(LICNS),IRET)
+        IF (IRET .NE. 0) GO TO 727
+        ENDIF
+C
+C     Check ID for legality.
+C
+      IF (LENID .GT. 0) THEN
+        DO 50 I = 1,NEQ
+          IDI = IWORK(LID-1+I)
+          IF (IDI .NE. 1 .AND. IDI .NE. -1) GO TO 724
+ 50       CONTINUE
+        ENDIF
+C
+C     Check to see that TOUT is different from T.
+C
+      IF(TOUT .EQ. T)GO TO 719
+C
+C     Check HMAX.
+C
+      IF(INFO(7) .NE. 0) THEN
+         HMAX = RWORK(LHMAX)
+         IF (HMAX .LE. 0.0D0) GO TO 710
+         ENDIF
+C
+C     Initialize counters and other flags.
+C
+      IWORK(LNST)=0
+      IWORK(LNRE)=0
+      IWORK(LNJE)=0
+      IWORK(LETF)=0
+      IWORK(LNCFN)=0
+      IWORK(LNNI)=0
+      IWORK(LNLI)=0
+      IWORK(LNPS)=0
+      IWORK(LNCFL)=0
+      IWORK(LKPRIN)=INFO(18)
+      IDID=1
+      GO TO 200
+C
+C-----------------------------------------------------------------------
+C     This block is for continuation calls only.
+C     Here we check INFO(1), and if the last step was interrupted,
+C     we check whether appropriate action was taken.
+C-----------------------------------------------------------------------
+C
+100   CONTINUE
+      IF(INFO(1).EQ.1)GO TO 110
+      ITEMP = 1
+      IF(INFO(1).NE.-1)GO TO 701
+C
+C     If we are here, the last step was interrupted by an error
+C     condition from DDSTP, and appropriate action was not taken.
+C     This is a fatal error.
+C
+      MSG = 'DASPK--  THE LAST STEP TERMINATED WITH A NEGATIVE'
+      CALL XERRWD(MSG,49,201,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  VALUE (=I1) OF IDID AND NO APPROPRIATE'
+      CALL XERRWD(MSG,47,202,0,1,IDID,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  ACTION WAS TAKEN. RUN TERMINATED'
+      CALL XERRWD(MSG,41,203,1,0,0,0,0,0.0D0,0.0D0)
+      RETURN
+110   CONTINUE
+C
+C-----------------------------------------------------------------------
+C     This block is executed on all calls.
+C
+C     Counters are saved for later checks of performance.
+C     Then the error tolerance parameters are checked, and the
+C     work array pointers are set.
+C-----------------------------------------------------------------------
+C
+200   CONTINUE
+C
+C     Save counters for use later.
+C
+      IWORK(LNSTL)=IWORK(LNST)
+      NLI0 = IWORK(LNLI)
+      NNI0 = IWORK(LNNI)
+      NCFN0 = IWORK(LNCFN)
+      NCFL0 = IWORK(LNCFL)
+      NWARN = 0
+C
+C     Check RTOL and ATOL.
+C
+      NZFLG = 0
+      RTOLI = RTOL(1)
+      ATOLI = ATOL(1)
+      DO 210 I=1,NEQ
+         IF (INFO(2) .EQ. 1) RTOLI = RTOL(I)
+         IF (INFO(2) .EQ. 1) ATOLI = ATOL(I)
+         IF (RTOLI .GT. 0.0D0 .OR. ATOLI .GT. 0.0D0) NZFLG = 1
+         IF (RTOLI .LT. 0.0D0) GO TO 706
+         IF (ATOLI .LT. 0.0D0) GO TO 707
+210      CONTINUE
+      IF (NZFLG .EQ. 0) GO TO 708
+C
+C     Set pointers to RWORK and IWORK segments.
+C     For direct methods, SAVR is not used.
+C
+      IWORK(LLCIWP) = LID + LENID
+      LSAVR = LDELTA
+      IF (INFO(12) .NE. 0) LSAVR = LDELTA + NEQ
+      LE = LSAVR + NEQ
+      LWT = LE + NEQ
+      LVT = LWT
+      IF (INFO(16) .NE. 0) LVT = LWT + NEQ
+      LPHI = LVT + NEQ
+      LWM = LPHI + (IWORK(LMXORD)+1)*NEQ
+      IF (INFO(1) .EQ. 1) GO TO 400
+C
+C-----------------------------------------------------------------------
+C     This block is executed on the initial call only.
+C     Set the initial step size, the error weight vector, and PHI.
+C     Compute unknown initial components of Y and YPRIME, if requested.
+C-----------------------------------------------------------------------
+C
+300   CONTINUE
+      TN=T
+      IDID=1
+C
+C     Set error weight array WT and altered weight array VT.
+C
+      CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
+      CALL DINVWT(NEQ,RWORK(LWT),IER)
+      IF (IER .NE. 0) GO TO 713
+      IF (INFO(16) .NE. 0) THEN
+        DO 305 I = 1, NEQ
+ 305      RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1)
+        ENDIF
+C
+C     Compute unit roundoff and HMIN.
+C
+      UROUND = D1MACH(4)
+      RWORK(LROUND) = UROUND
+      HMIN = 4.0D0*UROUND*MAX(ABS(T),ABS(TOUT))
+C
+C     Set/check STPTOL control for initial condition calculation.
+C     
+      IF (INFO(11) .NE. 0) THEN
+        IF( INFO(17) .EQ. 0) THEN
+          RWORK(LSTOL) = UROUND**.6667D0
+        ELSE
+          IF (RWORK(LSTOL) .LE. 0.0D0) GO TO 725
+          ENDIF
+        ENDIF
+C
+C     Compute EPCON and square root of NEQ and its reciprocal, used
+C     inside iterative solver.
+C
+      RWORK(LEPCON) = 0.33D0
+      FLOATN = NEQ
+      RWORK(LSQRN) = SQRT(FLOATN)
+      RWORK(LRSQRN) = 1.D0/RWORK(LSQRN)
+C
+C     Check initial interval to see that it is long enough.
+C
+      TDIST = ABS(TOUT - T)
+      IF(TDIST .LT. HMIN) GO TO 714
+C
+C     Check H0, if this was input.
+C
+      IF (INFO(8) .EQ. 0) GO TO 310
+         H0 = RWORK(LH)
+         IF ((TOUT - T)*H0 .LT. 0.0D0) GO TO 711
+         IF (H0 .EQ. 0.0D0) GO TO 712
+         GO TO 320
+310    CONTINUE
+C
+C     Compute initial stepsize, to be used by either
+C     DDSTP or DDASIC, depending on INFO(11).
+C
+      H0 = 0.001D0*TDIST
+      YPNORM = DDWNRM(NEQ,YPRIME,RWORK(LVT),RPAR,IPAR)
+      IF (YPNORM .GT. 0.5D0/H0) H0 = 0.5D0/YPNORM
+      H0 = SIGN(H0,TOUT-T)
+C
+C     Adjust H0 if necessary to meet HMAX bound.
+C
+320   IF (INFO(7) .EQ. 0) GO TO 330
+         RH = ABS(H0)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) H0 = H0/RH
+C
+C     Check against TSTOP, if applicable.
+C
+330   IF (INFO(4) .EQ. 0) GO TO 340
+         TSTOP = RWORK(LTSTOP)
+         IF ((TSTOP - T)*H0 .LT. 0.0D0) GO TO 715
+         IF ((T + H0 - TSTOP)*H0 .GT. 0.0D0) H0 = TSTOP - T
+         IF ((TSTOP - TOUT)*H0 .LT. 0.0D0) GO TO 709
+C
+340   IF (INFO(11) .EQ. 0) GO TO 370
+C
+C     Compute unknown components of initial Y and YPRIME, depending
+C     on INFO(11) and INFO(12).  INFO(12) represents the nonlinear
+C     solver type (direct/Krylov).  Pass the name of the specific 
+C     nonlinear solver, depending on INFO(12).  The location of the work
+C     arrays SAVR, YIC, YPIC, PWK also differ in the two cases.
+C
+      NWT = 1
+      EPCONI = RWORK(LEPIN)*RWORK(LEPCON)
+350   IF (INFO(12) .EQ. 0) THEN
+         LYIC = LPHI + 2*NEQ
+         LYPIC = LYIC + NEQ
+         LPWK = LYPIC
+         CALL DDASIC(TN,Y,YPRIME,NEQ,INFO(11),IWORK(LID),
+     *     RES,JAC,PSOL,H0,RWORK(LWT),NWT,IDID,RPAR,IPAR,
+     *     RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
+     *     RWORK(LYIC),RWORK(LYPIC),RWORK(LPWK),RWORK(LWM),IWORK(LIWM),
+     *     HMIN,RWORK(LROUND),RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
+     *     EPCONI,RWORK(LSTOL),INFO(15),ICNFLG,IWORK(LICNS),DDASID)
+      ELSE IF (INFO(12) .EQ. 1) THEN
+         LYIC = LWM
+         LYPIC = LYIC + NEQ
+         LPWK = LYPIC + NEQ
+         CALL DDASIC(TN,Y,YPRIME,NEQ,INFO(11),IWORK(LID),
+     *     RES,JAC,PSOL,H0,RWORK(LWT),NWT,IDID,RPAR,IPAR,
+     *     RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
+     *     RWORK(LYIC),RWORK(LYPIC),RWORK(LPWK),RWORK(LWM),IWORK(LIWM),
+     *     HMIN,RWORK(LROUND),RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
+     *     EPCONI,RWORK(LSTOL),INFO(15),ICNFLG,IWORK(LICNS),DDASIK)
+      ENDIF
+C
+      IF (IDID .LT. 0) GO TO 600
+C
+C     DDASIC was successful.  If this was the first call to DDASIC,
+C     update the WT array (with the current Y) and call it again.
+C
+      IF (NWT .EQ. 2) GO TO 355
+      NWT = 2
+      CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
+      CALL DINVWT(NEQ,RWORK(LWT),IER)
+      IF (IER .NE. 0) GO TO 713
+      GO TO 350
+C
+C     If INFO(14) = 1, return now with IDID = 4.
+C
+355   IF (INFO(14) .EQ. 1) THEN
+        IDID = 4
+        H = H0
+        IF (INFO(11) .EQ. 1) RWORK(LHOLD) = H0
+        GO TO 590
+      ENDIF
+C
+C     Update the WT and VT arrays one more time, with the new Y.
+C
+      CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
+      CALL DINVWT(NEQ,RWORK(LWT),IER)
+      IF (IER .NE. 0) GO TO 713
+      IF (INFO(16) .NE. 0) THEN
+        DO 357 I = 1, NEQ
+ 357      RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1)
+        ENDIF
+C
+C     Reset the initial stepsize to be used by DDSTP.
+C     Use H0, if this was input.  Otherwise, recompute H0,
+C     and adjust it if necessary to meet HMAX bound.
+C
+      IF (INFO(8) .NE. 0) THEN
+         H0 = RWORK(LH)
+         GO TO 360
+         ENDIF
+C
+      H0 = 0.001D0*TDIST
+      YPNORM = DDWNRM(NEQ,YPRIME,RWORK(LVT),RPAR,IPAR)
+      IF (YPNORM .GT. 0.5D0/H0) H0 = 0.5D0/YPNORM
+      H0 = SIGN(H0,TOUT-T)
+C
+360   IF (INFO(7) .NE. 0) THEN
+         RH = ABS(H0)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) H0 = H0/RH
+         ENDIF
+C
+C     Check against TSTOP, if applicable.
+C
+      IF (INFO(4) .NE. 0) THEN
+         TSTOP = RWORK(LTSTOP)
+         IF ((T + H0 - TSTOP)*H0 .GT. 0.0D0) H0 = TSTOP - T
+         ENDIF
+C
+C     Load H and RWORK(LH) with H0.
+C
+370   H = H0
+      RWORK(LH) = H
+C
+C     Load Y and H*YPRIME into PHI(*,1) and PHI(*,2).
+C
+      ITEMP = LPHI + NEQ
+      DO 380 I = 1,NEQ
+         RWORK(LPHI + I - 1) = Y(I)
+380      RWORK(ITEMP + I - 1) = H*YPRIME(I)
+C
+      GO TO 500
+C
+C-----------------------------------------------------------------------
+C     This block is for continuation calls only.
+C     Its purpose is to check stop conditions before taking a step.
+C     Adjust H if necessary to meet HMAX bound.
+C-----------------------------------------------------------------------
+C
+400   CONTINUE
+      UROUND=RWORK(LROUND)
+      DONE = .FALSE.
+      TN=RWORK(LTN)
+      H=RWORK(LH)
+      IF(INFO(7) .EQ. 0) GO TO 410
+         RH = ABS(H)/RWORK(LHMAX)
+         IF(RH .GT. 1.0D0) H = H/RH
+410   CONTINUE
+      IF(T .EQ. TOUT) GO TO 719
+      IF((T - TOUT)*H .GT. 0.0D0) GO TO 711
+      IF(INFO(4) .EQ. 1) GO TO 430
+      IF(INFO(3) .EQ. 1) GO TO 420
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 490
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+420   IF((TN-T)*H .LE. 0.0D0) GO TO 490
+      IF((TN - TOUT)*H .GT. 0.0D0) GO TO 425
+      CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TN
+      IDID = 1
+      DONE = .TRUE.
+      GO TO 490
+425   CONTINUE
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+430   IF(INFO(3) .EQ. 1) GO TO 440
+      TSTOP=RWORK(LTSTOP)
+      IF((TN-TSTOP)*H.GT.0.0D0) GO TO 715
+      IF((TSTOP-TOUT)*H.LT.0.0D0)GO TO 709
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 450
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *   RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+440   TSTOP = RWORK(LTSTOP)
+      IF((TN-TSTOP)*H .GT. 0.0D0) GO TO 715
+      IF((TSTOP-TOUT)*H .LT. 0.0D0) GO TO 709
+      IF((TN-T)*H .LE. 0.0D0) GO TO 450
+      IF((TN - TOUT)*H .GT. 0.0D0) GO TO 445
+      CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TN
+      IDID = 1
+      DONE = .TRUE.
+      GO TO 490
+445   CONTINUE
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+450   CONTINUE
+C
+C     Check whether we are within roundoff of TSTOP.
+C
+      IF(ABS(TN-TSTOP).GT.100.0D0*UROUND*
+     *   (ABS(TN)+ABS(H)))GO TO 460
+      CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      DONE = .TRUE.
+      GO TO 490
+460   TNEXT=TN+H
+      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 490
+      H=TSTOP-TN
+      RWORK(LH)=H
+C
+490   IF (DONE) GO TO 590
+C
+C-----------------------------------------------------------------------
+C     The next block contains the call to the one-step integrator DDSTP.
+C     This is a looping point for the integration steps.
+C     Check for too many steps.
+C     Check for poor Newton/Krylov performance.
+C     Update WT.  Check for too much accuracy requested.
+C     Compute minimum stepsize.
+C-----------------------------------------------------------------------
+C
+500   CONTINUE
+C
+C     Check for too many steps.
+C
+      IF((IWORK(LNST)-IWORK(LNSTL)).LT.500) GO TO 505
+           IDID=-1
+           GO TO 527
+C
+C Check for poor Newton/Krylov performance.
+C
+505   IF (INFO(12) .EQ. 0) GO TO 510
+      NSTD = IWORK(LNST) - IWORK(LNSTL)
+      NNID = IWORK(LNNI) - NNI0
+      IF (NSTD .LT. 10 .OR. NNID .EQ. 0) GO TO 510
+      AVLIN = REAL(IWORK(LNLI) - NLI0)/REAL(NNID)
+      RCFN = REAL(IWORK(LNCFN) - NCFN0)/REAL(NSTD)
+      RCFL = REAL(IWORK(LNCFL) - NCFL0)/REAL(NNID)
+      FMAXL = IWORK(LMAXL)
+      LAVL = AVLIN .GT. FMAXL
+      LCFN = RCFN .GT. 0.9D0
+      LCFL = RCFL .GT. 0.9D0
+      LWARN = LAVL .OR. LCFN .OR. LCFL
+      IF (.NOT.LWARN) GO TO 510
+      NWARN = NWARN + 1
+      IF (NWARN .GT. 10) GO TO 510
+      IF (LAVL) THEN
+        MSG = 'DASPK-- Warning. Poor iterative algorithm performance   '
+        CALL XERRWD (MSG, 56, 501, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+        MSG = '      at T = R1. Average no. of linear iterations = R2  '
+        CALL XERRWD (MSG, 56, 501, 0, 0, 0, 0, 2, TN, AVLIN)
+        ENDIF
+      IF (LCFN) THEN
+        MSG = 'DASPK-- Warning. Poor iterative algorithm performance   '
+        CALL XERRWD (MSG, 56, 502, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+        MSG = '      at T = R1. Nonlinear convergence failure rate = R2'
+        CALL XERRWD (MSG, 56, 502, 0, 0, 0, 0, 2, TN, RCFN)
+        ENDIF
+      IF (LCFL) THEN
+        MSG = 'DASPK-- Warning. Poor iterative algorithm performance   '
+        CALL XERRWD (MSG, 56, 503, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+        MSG = '      at T = R1. Linear convergence failure rate = R2   '
+        CALL XERRWD (MSG, 56, 503, 0, 0, 0, 0, 2, TN, RCFL)
+        ENDIF
+C
+C     Update WT and VT, if this is not the first call.
+C
+510   CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,RWORK(LPHI),RWORK(LWT),
+     *            RPAR,IPAR)
+      CALL DINVWT(NEQ,RWORK(LWT),IER)
+      IF (IER .NE. 0) THEN
+        IDID = -3
+        GO TO 527
+        ENDIF
+      IF (INFO(16) .NE. 0) THEN
+        DO 515 I = 1, NEQ
+ 515      RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1)
+        ENDIF
+C
+C     Test for too much accuracy requested.
+C
+      R = DDWNRM(NEQ,RWORK(LPHI),RWORK(LWT),RPAR,IPAR)*100.0D0*UROUND
+      IF (R .LE. 1.0D0) GO TO 525
+C
+C     Multiply RTOL and ATOL by R and return.
+C
+      IF(INFO(2).EQ.1)GO TO 523
+           RTOL(1)=R*RTOL(1)
+           ATOL(1)=R*ATOL(1)
+           IDID=-2
+           GO TO 527
+523   DO 524 I=1,NEQ
+           RTOL(I)=R*RTOL(I)
+524        ATOL(I)=R*ATOL(I)
+      IDID=-2
+      GO TO 527
+525   CONTINUE
+C
+C     Compute minimum stepsize.
+C
+      HMIN=4.0D0*UROUND*MAX(ABS(TN),ABS(TOUT))
+C
+C     Test H vs. HMAX
+      IF (INFO(7) .NE. 0) THEN
+         RH = ABS(H)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) H = H/RH
+         ENDIF
+C
+C     Call the one-step integrator.
+C     Note that INFO(12) represents the nonlinear solver type.
+C     Pass the required nonlinear solver, depending upon INFO(12).
+C
+      IF (INFO(12) .EQ. 0) THEN
+         CALL DDSTP(TN,Y,YPRIME,NEQ,
+     *      RES,JAC,PSOL,H,RWORK(LWT),RWORK(LVT),INFO(1),IDID,RPAR,IPAR,
+     *      RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
+     *      RWORK(LWM),IWORK(LIWM),
+     *      RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
+     *      RWORK(LPSI),RWORK(LSIGMA),
+     *      RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),RWORK(LS),HMIN,
+     *      RWORK(LROUND), RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
+     *      RWORK(LEPCON), IWORK(LPHASE),IWORK(LJCALC),INFO(15),
+     *      IWORK(LK), IWORK(LKOLD),IWORK(LNS),NONNEG,INFO(12),
+     *      DNEDD)
+      ELSE IF (INFO(12) .EQ. 1) THEN
+         CALL DDSTP(TN,Y,YPRIME,NEQ,
+     *      RES,JAC,PSOL,H,RWORK(LWT),RWORK(LVT),INFO(1),IDID,RPAR,IPAR,
+     *      RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
+     *      RWORK(LWM),IWORK(LIWM),
+     *      RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
+     *      RWORK(LPSI),RWORK(LSIGMA),
+     *      RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),RWORK(LS),HMIN,
+     *      RWORK(LROUND), RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
+     *      RWORK(LEPCON), IWORK(LPHASE),IWORK(LJCALC),INFO(15),
+     *      IWORK(LK), IWORK(LKOLD),IWORK(LNS),NONNEG,INFO(12),
+     *      DNEDK)
+      ENDIF
+C
+527   IF(IDID.LT.0)GO TO 600
+C
+C-----------------------------------------------------------------------
+C     This block handles the case of a successful return from DDSTP
+C     (IDID=1).  Test for stop conditions.
+C-----------------------------------------------------------------------
+C
+      IF(INFO(4).NE.0)GO TO 540
+           IF(INFO(3).NE.0)GO TO 530
+             IF((TN-TOUT)*H.LT.0.0D0)GO TO 500
+             CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+             IDID=3
+             T=TOUT
+             GO TO 580
+530          IF((TN-TOUT)*H.GE.0.0D0)GO TO 535
+             T=TN
+             IDID=1
+             GO TO 580
+535          CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+             IDID=3
+             T=TOUT
+             GO TO 580
+540   IF(INFO(3).NE.0)GO TO 550
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 542
+         CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *     IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+         T=TOUT
+         IDID=3
+         GO TO 580
+542   IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*
+     *   (ABS(TN)+ABS(H)))GO TO 545
+      TNEXT=TN+H
+      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 500
+      H=TSTOP-TN
+      GO TO 500
+545   CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
+     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      GO TO 580
+550   IF((TN-TOUT)*H.GE.0.0D0)GO TO 555
+      IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*(ABS(TN)+ABS(H)))GO TO 552
+      T=TN
+      IDID=1
+      GO TO 580
+552   CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
+     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      GO TO 580
+555   CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *   IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID=3
+580   CONTINUE
+C
+C-----------------------------------------------------------------------
+C     All successful returns from DDASPK are made from this block.
+C-----------------------------------------------------------------------
+C
+590   CONTINUE
+      RWORK(LTN)=TN
+      RWORK(LH)=H
+      RETURN
+C
+C-----------------------------------------------------------------------
+C     This block handles all unsuccessful returns other than for
+C     illegal input.
+C-----------------------------------------------------------------------
+C
+600   CONTINUE
+      ITEMP = -IDID
+      GO TO (610,620,630,700,655,640,650,660,670,675,
+     *  680,685,690,695), ITEMP
+C
+C     The maximum number of steps was taken before
+C     reaching tout.
+C
+610   MSG = 'DASPK--  AT CURRENT T (=R1)  500 STEPS'
+      CALL XERRWD(MSG,38,610,0,0,0,0,1,TN,0.0D0)
+      MSG = 'DASPK--  TAKEN ON THIS CALL BEFORE REACHING TOUT'
+      CALL XERRWD(MSG,48,611,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Too much accuracy for machine precision.
+C
+620   MSG = 'DASPK--  AT T (=R1) TOO MUCH ACCURACY REQUESTED'
+      CALL XERRWD(MSG,47,620,0,0,0,0,1,TN,0.0D0)
+      MSG = 'DASPK--  FOR PRECISION OF MACHINE. RTOL AND ATOL'
+      CALL XERRWD(MSG,48,621,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  WERE INCREASED TO APPROPRIATE VALUES'
+      CALL XERRWD(MSG,45,622,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     WT(I) .LE. 0.0D0 for some I (not at start of problem).
+C
+630   MSG = 'DASPK--  AT T (=R1) SOME ELEMENT OF WT'
+      CALL XERRWD(MSG,38,630,0,0,0,0,1,TN,0.0D0)
+      MSG = 'DASPK--  HAS BECOME .LE. 0.0'
+      CALL XERRWD(MSG,28,631,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Error test failed repeatedly or with H=HMIN.
+C
+640   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,640,0,0,0,0,2,TN,H)
+      MSG='DASPK--  ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN'
+      CALL XERRWD(MSG,57,641,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Nonlinear solver failed to converge repeatedly or with H=HMIN.
+C
+650   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,650,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  NONLINEAR SOLVER FAILED TO CONVERGE'
+      CALL XERRWD(MSG,44,651,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  REPEATEDLY OR WITH ABS(H)=HMIN'
+      CALL XERRWD(MSG,40,652,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     The preconditioner had repeated failures.
+C
+655   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,655,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  PRECONDITIONER HAD REPEATED FAILURES.'
+      CALL XERRWD(MSG,46,656,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     The iteration matrix is singular.
+C
+660   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,660,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  ITERATION MATRIX IS SINGULAR.'
+      CALL XERRWD(MSG,38,661,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Nonlinear system failure preceded by error test failures.
+C
+670   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,670,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  NONLINEAR SOLVER COULD NOT CONVERGE.'
+      CALL XERRWD(MSG,45,671,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  ALSO, THE ERROR TEST FAILED REPEATEDLY.'
+      CALL XERRWD(MSG,49,672,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Nonlinear system failure because IRES = -1.
+C
+675   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,675,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  NONLINEAR SYSTEM SOLVER COULD NOT CONVERGE'
+      CALL XERRWD(MSG,51,676,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  BECAUSE IRES WAS EQUAL TO MINUS ONE'
+      CALL XERRWD(MSG,44,677,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Failure because IRES = -2.
+C
+680   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2)'
+      CALL XERRWD(MSG,40,680,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  IRES WAS EQUAL TO MINUS TWO'
+      CALL XERRWD(MSG,36,681,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Failed to compute initial YPRIME.
+C
+685   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,685,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASPK--  INITIAL (Y,YPRIME) COULD NOT BE COMPUTED'
+      CALL XERRWD(MSG,49,686,0,0,0,0,2,TN,H0)
+      GO TO 700
+C
+C     Failure because IER was negative from PSOL.
+C
+690   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2)'
+      CALL XERRWD(MSG,40,690,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  IER WAS NEGATIVE FROM PSOL'
+      CALL XERRWD(MSG,35,691,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C     Failure because the linear system solver could not converge.
+C
+695   MSG = 'DASPK--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,695,0,0,0,0,2,TN,H)
+      MSG = 'DASPK--  LINEAR SYSTEM SOLVER COULD NOT CONVERGE.'
+      CALL XERRWD(MSG,50,696,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 700
+C
+C
+700   CONTINUE
+      INFO(1)=-1
+      T=TN
+      RWORK(LTN)=TN
+      RWORK(LH)=H
+      RETURN
+C
+C-----------------------------------------------------------------------
+C     This block handles all error returns due to illegal input,
+C     as detected before calling DDSTP.
+C     First the error message routine is called.  If this happens
+C     twice in succession, execution is terminated.
+C-----------------------------------------------------------------------
+C
+701   MSG = 'DASPK--  ELEMENT (=I1) OF INFO VECTOR IS NOT VALID'
+      CALL XERRWD(MSG,50,1,0,1,ITEMP,0,0,0.0D0,0.0D0)
+      GO TO 750
+702   MSG = 'DASPK--  NEQ (=I1) .LE. 0'
+      CALL XERRWD(MSG,25,2,0,1,NEQ,0,0,0.0D0,0.0D0)
+      GO TO 750
+703   MSG = 'DASPK--  MAXORD (=I1) NOT IN RANGE'
+      CALL XERRWD(MSG,34,3,0,1,MXORD,0,0,0.0D0,0.0D0)
+      GO TO 750
+704   MSG='DASPK--  RWORK LENGTH NEEDED, LENRW (=I1), EXCEEDS LRW (=I2)'
+      CALL XERRWD(MSG,60,4,0,2,LENRW,LRW,0,0.0D0,0.0D0)
+      GO TO 750
+705   MSG='DASPK--  IWORK LENGTH NEEDED, LENIW (=I1), EXCEEDS LIW (=I2)'
+      CALL XERRWD(MSG,60,5,0,2,LENIW,LIW,0,0.0D0,0.0D0)
+      GO TO 750
+706   MSG = 'DASPK--  SOME ELEMENT OF RTOL IS .LT. 0'
+      CALL XERRWD(MSG,39,6,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+707   MSG = 'DASPK--  SOME ELEMENT OF ATOL IS .LT. 0'
+      CALL XERRWD(MSG,39,7,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+708   MSG = 'DASPK--  ALL ELEMENTS OF RTOL AND ATOL ARE ZERO'
+      CALL XERRWD(MSG,47,8,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+709   MSG='DASPK--  INFO(4) = 1 AND TSTOP (=R1) BEHIND TOUT (=R2)'
+      CALL XERRWD(MSG,54,9,0,0,0,0,2,TSTOP,TOUT)
+      GO TO 750
+710   MSG = 'DASPK--  HMAX (=R1) .LT. 0.0'
+      CALL XERRWD(MSG,28,10,0,0,0,0,1,HMAX,0.0D0)
+      GO TO 750
+711   MSG = 'DASPK--  TOUT (=R1) BEHIND T (=R2)'
+      CALL XERRWD(MSG,34,11,0,0,0,0,2,TOUT,T)
+      GO TO 750
+712   MSG = 'DASPK--  INFO(8)=1 AND H0=0.0'
+      CALL XERRWD(MSG,29,12,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+713   MSG = 'DASPK--  SOME ELEMENT OF WT IS .LE. 0.0'
+      CALL XERRWD(MSG,39,13,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+714   MSG='DASPK-- TOUT (=R1) TOO CLOSE TO T (=R2) TO START INTEGRATION'
+      CALL XERRWD(MSG,60,14,0,0,0,0,2,TOUT,T)
+      GO TO 750
+715   MSG = 'DASPK--  INFO(4)=1 AND TSTOP (=R1) BEHIND T (=R2)'
+      CALL XERRWD(MSG,49,15,0,0,0,0,2,TSTOP,T)
+      GO TO 750
+717   MSG = 'DASPK--  ML (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ'
+      CALL XERRWD(MSG,52,17,0,1,IWORK(LML),0,0,0.0D0,0.0D0)
+      GO TO 750
+718   MSG = 'DASPK--  MU (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ'
+      CALL XERRWD(MSG,52,18,0,1,IWORK(LMU),0,0,0.0D0,0.0D0)
+      GO TO 750
+719   MSG = 'DASPK--  TOUT (=R1) IS EQUAL TO T (=R2)'
+      CALL XERRWD(MSG,39,19,0,0,0,0,2,TOUT,T)
+      GO TO 750
+720   MSG = 'DASPK--  MAXL (=I1) ILLEGAL. EITHER .LT. 1 OR .GT. NEQ'
+      CALL XERRWD(MSG,54,20,0,1,IWORK(LMAXL),0,0,0.0D0,0.0D0)
+      GO TO 750
+721   MSG = 'DASPK--  KMP (=I1) ILLEGAL. EITHER .LT. 1 OR .GT. MAXL'
+      CALL XERRWD(MSG,54,21,0,1,IWORK(LKMP),0,0,0.0D0,0.0D0)
+      GO TO 750
+722   MSG = 'DASPK--  NRMAX (=I1) ILLEGAL. .LT. 0'
+      CALL XERRWD(MSG,36,22,0,1,IWORK(LNRMAX),0,0,0.0D0,0.0D0)
+      GO TO 750
+723   MSG = 'DASPK--  EPLI (=R1) ILLEGAL. EITHER .LE. 0.D0 OR .GE. 1.D0'
+      CALL XERRWD(MSG,58,23,0,0,0,0,1,RWORK(LEPLI),0.0D0)
+      GO TO 750
+724   MSG = 'DASPK--  ILLEGAL IWORK VALUE FOR INFO(11) .NE. 0'
+      CALL XERRWD(MSG,48,24,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+725   MSG = 'DASPK--  ONE OF THE INPUTS FOR INFO(17) = 1 IS ILLEGAL'
+      CALL XERRWD(MSG,54,25,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+726   MSG = 'DASPK--  ILLEGAL IWORK VALUE FOR INFO(10) .NE. 0'
+      CALL XERRWD(MSG,48,26,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+727   MSG = 'DASPK--  Y(I) AND IWORK(40+I) (I=I1) INCONSISTENT'
+      CALL XERRWD(MSG,49,27,0,1,IRET,0,0,0.0D0,0.0D0)
+      GO TO 750
+750   IF(INFO(1).EQ.-1) GO TO 760
+      INFO(1)=-1
+      IDID=-33
+      RETURN
+760   MSG = 'DASPK--  REPEATED OCCURRENCES OF ILLEGAL INPUT'
+      CALL XERRWD(MSG,46,701,0,0,0,0,0,0.0D0,0.0D0)
+770   MSG = 'DASPK--  RUN TERMINATED. APPARENT INFINITE LOOP'
+      CALL XERRWD(MSG,47,702,1,0,0,0,0,0.0D0,0.0D0)
+      RETURN
+C
+C------END OF SUBROUTINE DDASPK-----------------------------------------
+      END
diff --git a/libcruft/daspk/ddstp.f b/libcruft/daspk/ddstp.f
new file mode 100644
index 0000000..27eb327
--- /dev/null
+++ b/libcruft/daspk/ddstp.f
@@ -0,0 +1,465 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DDSTP(X,Y,YPRIME,NEQ,RES,JAC,PSOL,H,WT,VT,
+     *  JSTART,IDID,RPAR,IPAR,PHI,SAVR,DELTA,E,WM,IWM,
+     *  ALPHA,BETA,GAMMA,PSI,SIGMA,CJ,CJOLD,HOLD,S,HMIN,UROUND,
+     *  EPLI,SQRTN,RSQRTN,EPCON,IPHASE,JCALC,JFLG,K,KOLD,NS,NONNEG,
+     *  NTYPE,NLS)
+C
+C***BEGIN PROLOGUE  DDSTP
+C***REFER TO  DDASPK
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  940909   (YYMMDD) (Reset PSI(1), PHI(*,2) at 690)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DDSTP solves a system of differential/algebraic equations of 
+C     the form G(X,Y,YPRIME) = 0, for one step (normally from X to X+H).
+C
+C     The methods used are modified divided difference, fixed leading 
+C     coefficient forms of backward differentiation formulas.  
+C     The code adjusts the stepsize and order to control the local error
+C     per step.
+C
+C
+C     The parameters represent
+C     X  --        Independent variable.
+C     Y  --        Solution vector at X.
+C     YPRIME --    Derivative of solution vector
+C                  after successful step.
+C     NEQ --       Number of equations to be integrated.
+C     RES --       External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     JAC --       External user-supplied routine to update
+C                  Jacobian or preconditioner information in the
+C                  nonlinear solver.  See JAC description in DDASPK
+C                  prologue.
+C     PSOL --      External user-supplied routine to solve
+C                  a linear system using preconditioning. 
+C                  (This is optional).  See PSOL in DDASPK prologue.
+C     H --         Appropriate step size for next step.
+C                  Normally determined by the code.
+C     WT --        Vector of weights for error criterion used in Newton test.
+C     VT --        Masked vector of weights used in error test.
+C     JSTART --    Integer variable set 0 for
+C                  first step, 1 otherwise.
+C     IDID --      Completion code returned from the nonlinear solver.
+C                  See IDID description in DDASPK prologue.
+C     RPAR,IPAR -- Real and integer parameter arrays that
+C                  are used for communication between the
+C                  calling program and external user routines.
+C                  They are not altered by DNSK
+C     PHI --       Array of divided differences used by
+C                  DDSTP. The length is NEQ*(K+1), where
+C                  K is the maximum order.
+C     SAVR --      Work vector for DDSTP of length NEQ.
+C     DELTA,E --   Work vectors for DDSTP of length NEQ.
+C     WM,IWM --    Real and integer arrays storing
+C                  information required by the linear solver.
+C
+C     The other parameters are information
+C     which is needed internally by DDSTP to
+C     continue from step to step.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   NLS, DDWNRM, DDATRP
+C
+C***END PROLOGUE  DDSTP
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*),VT(*)
+      DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*)
+      DIMENSION WM(*),IWM(*)
+      DIMENSION PSI(*),ALPHA(*),BETA(*),GAMMA(*),SIGMA(*)
+      DIMENSION RPAR(*),IPAR(*)
+      EXTERNAL  RES, JAC, PSOL, NLS
+C
+      PARAMETER (LMXORD=3)
+      PARAMETER (LNST=11, LETF=14, LCFN=15)
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 1.
+C     Initialize.  On the first call, set
+C     the order to 1 and initialize
+C     other variables.
+C-----------------------------------------------------------------------
+C
+C     Initializations for all calls
+C
+      XOLD=X
+      NCF=0
+      NEF=0
+      IF(JSTART .NE. 0) GO TO 120
+C
+C     If this is the first step, perform
+C     other initializations
+C
+      K=1
+      KOLD=0
+      HOLD=0.0D0
+      PSI(1)=H
+      CJ = 1.D0/H
+      IPHASE = 0
+      NS=0
+120   CONTINUE
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 2
+C     Compute coefficients of formulas for
+C     this step.
+C-----------------------------------------------------------------------
+200   CONTINUE
+      KP1=K+1
+      KP2=K+2
+      KM1=K-1
+      IF(H.NE.HOLD.OR.K .NE. KOLD) NS = 0
+      NS=MIN0(NS+1,KOLD+2)
+      NSP1=NS+1
+      IF(KP1 .LT. NS)GO TO 230
+C
+      BETA(1)=1.0D0
+      ALPHA(1)=1.0D0
+      TEMP1=H
+      GAMMA(1)=0.0D0
+      SIGMA(1)=1.0D0
+      DO 210 I=2,KP1
+         TEMP2=PSI(I-1)
+         PSI(I-1)=TEMP1
+         BETA(I)=BETA(I-1)*PSI(I-1)/TEMP2
+         TEMP1=TEMP2+H
+         ALPHA(I)=H/TEMP1
+         SIGMA(I)=(I-1)*SIGMA(I-1)*ALPHA(I)
+         GAMMA(I)=GAMMA(I-1)+ALPHA(I-1)/H
+210      CONTINUE
+      PSI(KP1)=TEMP1
+230   CONTINUE
+C
+C     Compute ALPHAS, ALPHA0
+C
+      ALPHAS = 0.0D0
+      ALPHA0 = 0.0D0
+      DO 240 I = 1,K
+        ALPHAS = ALPHAS - 1.0D0/I
+        ALPHA0 = ALPHA0 - ALPHA(I)
+240     CONTINUE
+C
+C     Compute leading coefficient CJ
+C
+      CJLAST = CJ
+      CJ = -ALPHAS/H
+C
+C     Compute variable stepsize error coefficient CK
+C
+      CK = ABS(ALPHA(KP1) + ALPHAS - ALPHA0)
+      CK = MAX(CK,ALPHA(KP1))
+C
+C     Change PHI to PHI STAR
+C
+      IF(KP1 .LT. NSP1) GO TO 280
+      DO 270 J=NSP1,KP1
+         DO 260 I=1,NEQ
+260         PHI(I,J)=BETA(J)*PHI(I,J)
+270      CONTINUE
+280   CONTINUE
+C
+C     Update time
+C
+      X=X+H
+C
+C     Initialize IDID to 1
+C
+      IDID = 1
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 3
+C     Call the nonlinear system solver to obtain the solution and
+C     derivative.
+C-----------------------------------------------------------------------
+C
+      CALL NLS(X,Y,YPRIME,NEQ,
+     *   RES,JAC,PSOL,H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA,
+     *   SAVR,DELTA,E,WM,IWM,CJ,CJOLD,CJLAST,S,
+     *   UROUND,EPLI,SQRTN,RSQRTN,EPCON,JCALC,JFLG,KP1,
+     *   NONNEG,NTYPE,IERNLS)
+C
+      IF(IERNLS .NE. 0)GO TO 600
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 4
+C     Estimate the errors at orders K,K-1,K-2
+C     as if constant stepsize was used. Estimate
+C     the local error at order K and test
+C     whether the current step is successful.
+C-----------------------------------------------------------------------
+C
+C     Estimate errors at orders K,K-1,K-2
+C
+      ENORM = DDWNRM(NEQ,E,VT,RPAR,IPAR)
+      ERK = SIGMA(K+1)*ENORM
+      TERK = (K+1)*ERK
+      EST = ERK
+      KNEW=K
+      IF(K .EQ. 1)GO TO 430
+      DO 405 I = 1,NEQ
+405     DELTA(I) = PHI(I,KP1) + E(I)
+      ERKM1=SIGMA(K)*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR)
+      TERKM1 = K*ERKM1
+      IF(K .GT. 2)GO TO 410
+      IF(TERKM1 .LE. 0.5*TERK)GO TO 420
+      GO TO 430
+410   CONTINUE
+      DO 415 I = 1,NEQ
+415     DELTA(I) = PHI(I,K) + DELTA(I)
+      ERKM2=SIGMA(K-1)*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR)
+      TERKM2 = (K-1)*ERKM2
+      IF(MAX(TERKM1,TERKM2).GT.TERK)GO TO 430
+C
+C     Lower the order
+C
+420   CONTINUE
+      KNEW=K-1
+      EST = ERKM1
+C
+C
+C     Calculate the local error for the current step
+C     to see if the step was successful
+C
+430   CONTINUE
+      ERR = CK * ENORM
+      IF(ERR .GT. 1.0D0)GO TO 600
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 5
+C     The step is successful. Determine
+C     the best order and stepsize for
+C     the next step. Update the differences
+C     for the next step.
+C-----------------------------------------------------------------------
+      IDID=1
+      IWM(LNST)=IWM(LNST)+1
+      KDIFF=K-KOLD
+      KOLD=K
+      HOLD=H
+C
+C
+C     Estimate the error at order K+1 unless
+C        already decided to lower order, or
+C        already using maximum order, or
+C        stepsize not constant, or
+C        order raised in previous step
+C
+      IF(KNEW.EQ.KM1.OR.K.EQ.IWM(LMXORD))IPHASE=1
+      IF(IPHASE .EQ. 0)GO TO 545
+      IF(KNEW.EQ.KM1)GO TO 540
+      IF(K.EQ.IWM(LMXORD)) GO TO 550
+      IF(KP1.GE.NS.OR.KDIFF.EQ.1)GO TO 550
+      DO 510 I=1,NEQ
+510      DELTA(I)=E(I)-PHI(I,KP2)
+      ERKP1 = (1.0D0/(K+2))*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR)
+      TERKP1 = (K+2)*ERKP1
+      IF(K.GT.1)GO TO 520
+      IF(TERKP1.GE.0.5D0*TERK)GO TO 550
+      GO TO 530
+520   IF(TERKM1.LE.MIN(TERK,TERKP1))GO TO 540
+      IF(TERKP1.GE.TERK.OR.K.EQ.IWM(LMXORD))GO TO 550
+C
+C     Raise order
+C
+530   K=KP1
+      EST = ERKP1
+      GO TO 550
+C
+C     Lower order
+C
+540   K=KM1
+      EST = ERKM1
+      GO TO 550
+C
+C     If IPHASE = 0, increase order by one and multiply stepsize by
+C     factor two
+C
+545   K = KP1
+      HNEW = H*2.0D0
+      H = HNEW
+      GO TO 575
+C
+C
+C     Determine the appropriate stepsize for
+C     the next step.
+C
+550   HNEW=H
+      TEMP2=K+1
+      R=(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
+      IF(R .LT. 2.0D0) GO TO 555
+      HNEW = 2.0D0*H
+      GO TO 560
+555   IF(R .GT. 1.0D0) GO TO 560
+      R = MAX(0.5D0,MIN(0.9D0,R))
+      HNEW = H*R
+560   H=HNEW
+C
+C
+C     Update differences for next step
+C
+575   CONTINUE
+      IF(KOLD.EQ.IWM(LMXORD))GO TO 585
+      DO 580 I=1,NEQ
+580      PHI(I,KP2)=E(I)
+585   CONTINUE
+      DO 590 I=1,NEQ
+590      PHI(I,KP1)=PHI(I,KP1)+E(I)
+      DO 595 J1=2,KP1
+         J=KP1-J1+1
+         DO 595 I=1,NEQ
+595      PHI(I,J)=PHI(I,J)+PHI(I,J+1)
+      JSTART = 1
+      RETURN
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 6
+C     The step is unsuccessful. Restore X,PSI,PHI
+C     Determine appropriate stepsize for
+C     continuing the integration, or exit with
+C     an error flag if there have been many
+C     failures.
+C-----------------------------------------------------------------------
+600   IPHASE = 1
+C
+C     Restore X,PHI,PSI
+C
+      X=XOLD
+      IF(KP1.LT.NSP1)GO TO 630
+      DO 620 J=NSP1,KP1
+         TEMP1=1.0D0/BETA(J)
+         DO 610 I=1,NEQ
+610         PHI(I,J)=TEMP1*PHI(I,J)
+620      CONTINUE
+630   CONTINUE
+      DO 640 I=2,KP1
+640      PSI(I-1)=PSI(I)-H
+C
+C
+C     Test whether failure is due to nonlinear solver
+C     or error test
+C
+      IF(IERNLS .EQ. 0)GO TO 660
+      IWM(LCFN)=IWM(LCFN)+1
+C
+C
+C     The nonlinear solver failed to converge.
+C     Determine the cause of the failure and take appropriate action.
+C     If IERNLS .LT. 0, then return.  Otherwise, reduce the stepsize
+C     and try again, unless too many failures have occurred.
+C
+      IF (IERNLS .LT. 0) GO TO 675
+      NCF = NCF + 1
+      R = 0.25D0
+      H = H*R
+      IF (NCF .LT. 10 .AND. ABS(H) .GE. HMIN) GO TO 690
+      IF (IDID .EQ. 1) IDID = -7
+      IF (NEF .GE. 3) IDID = -9
+      GO TO 675
+C
+C
+C     The nonlinear solver converged, and the cause
+C     of the failure was the error estimate
+C     exceeding the tolerance.
+C
+660   NEF=NEF+1
+      IWM(LETF)=IWM(LETF)+1
+      IF (NEF .GT. 1) GO TO 665
+C
+C     On first error test failure, keep current order or lower
+C     order by one.  Compute new stepsize based on differences
+C     of the solution.
+C
+      K = KNEW
+      TEMP2 = K + 1
+      R = 0.90D0*(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
+      R = MAX(0.25D0,MIN(0.9D0,R))
+      H = H*R
+      IF (ABS(H) .GE. HMIN) GO TO 690
+      IDID = -6
+      GO TO 675
+C
+C     On second error test failure, use the current order or
+C     decrease order by one.  Reduce the stepsize by a factor of
+C     one quarter.
+C
+665   IF (NEF .GT. 2) GO TO 670
+      K = KNEW
+      R = 0.25D0
+      H = R*H
+      IF (ABS(H) .GE. HMIN) GO TO 690
+      IDID = -6
+      GO TO 675
+C
+C     On third and subsequent error test failures, set the order to
+C     one, and reduce the stepsize by a factor of one quarter.
+C
+670   K = 1
+      R = 0.25D0
+      H = R*H
+      IF (ABS(H) .GE. HMIN) GO TO 690
+      IDID = -6
+      GO TO 675
+C
+C
+C
+C
+C     For all crashes, restore Y to its last value,
+C     interpolate to find YPRIME at last X, and return.
+C
+C     Before returning, verify that the user has not set
+C     IDID to a nonnegative value.  If the user has set IDID
+C     to a nonnegative value, then reset IDID to be -7, indicating
+C     a failure in the nonlinear system solver.
+C
+675   CONTINUE
+      CALL DDATRP(X,X,Y,YPRIME,NEQ,K,PHI,PSI)
+      JSTART = 1
+      IF (IDID .GE. 0) IDID = -7
+      RETURN
+C
+C
+C     Go back and try this step again.  
+C     If this is the first step, reset PSI(1) and rescale PHI(*,2).
+C
+690   IF (KOLD .EQ. 0) THEN
+        PSI(1) = H
+        DO 695 I = 1,NEQ
+695       PHI(I,2) = R*PHI(I,2)
+        ENDIF
+      GO TO 200
+C
+C------END OF SUBROUTINE DDSTP------------------------------------------
+      END
diff --git a/libcruft/daspk/ddwnrm.f b/libcruft/daspk/ddwnrm.f
new file mode 100644
index 0000000..ccd571f
--- /dev/null
+++ b/libcruft/daspk/ddwnrm.f
@@ -0,0 +1,37 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      DOUBLE PRECISION FUNCTION DDWNRM(NEQ,V,RWT,RPAR,IPAR)
+C
+C***BEGIN PROLOGUE  DDWNRM
+C***ROUTINES CALLED  (NONE)
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***END PROLOGUE  DDWNRM
+C-----------------------------------------------------------------------
+C     This function routine computes the weighted
+C     root-mean-square norm of the vector of length
+C     NEQ contained in the array V, with reciprocal weights
+C     contained in the array RWT of length NEQ.
+C        DDWNRM=SQRT((1/NEQ)*SUM(V(I)*RWT(I))**2)
+C-----------------------------------------------------------------------
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION V(*),RWT(*)
+      DIMENSION RPAR(*),IPAR(*)
+      DDWNRM = 0.0D0
+      VMAX = 0.0D0
+      DO 10 I = 1,NEQ
+        IF(ABS(V(I)*RWT(I)) .GT. VMAX) VMAX = ABS(V(I)*RWT(I))
+10    CONTINUE
+      IF(VMAX .LE. 0.0D0) GO TO 30
+      SUM = 0.0D0
+      DO 20 I = 1,NEQ
+20      SUM = SUM + ((V(I)*RWT(I))/VMAX)**2
+      DDWNRM = VMAX*SQRT(SUM/NEQ)
+30    CONTINUE
+      RETURN
+C
+C------END OF FUNCTION DDWNRM-------------------------------------------
+      END
diff --git a/libcruft/daspk/dfnrmd.f b/libcruft/daspk/dfnrmd.f
new file mode 100644
index 0000000..b3422c3
--- /dev/null
+++ b/libcruft/daspk/dfnrmd.f
@@ -0,0 +1,57 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DFNRMD (NEQ, Y, T, YPRIME, R, CJ, WT, RES, IRES,
+     *                   FNORM, WM, IWM, RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DFNRMD
+C***REFER TO  DLINSD
+C***DATE WRITTEN   941025   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DFNRMD calculates the scaled preconditioned norm of the nonlinear
+C     function used in the nonlinear iteration for obtaining consistent
+C     initial conditions.  Specifically, DFNRMD calculates the weighted
+C     root-mean-square norm of the vector (J-inverse)*G(T,Y,YPRIME),
+C     where J is the Jacobian matrix.
+C
+C     In addition to the parameters described in the calling program
+C     DLINSD, the parameters represent
+C
+C     R      -- Array of length NEQ that contains
+C               (J-inverse)*G(T,Y,YPRIME) on return.
+C     FNORM  -- Scalar containing the weighted norm of R on return.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   RES, DSLVD, DDWNRM
+C
+C***END PROLOGUE  DFNRMD
+C
+C
+      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+      EXTERNAL RES
+      DIMENSION Y(*), YPRIME(*), WT(*), R(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+C-----------------------------------------------------------------------
+C     Call RES routine.
+C-----------------------------------------------------------------------
+      IRES = 0
+      CALL RES(T,Y,YPRIME,CJ,R,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) RETURN
+C-----------------------------------------------------------------------
+C     Apply inverse of Jacobian to vector R.
+C-----------------------------------------------------------------------
+      CALL DSLVD(NEQ,R,WM,IWM)
+C-----------------------------------------------------------------------
+C     Calculate norm of R.
+C-----------------------------------------------------------------------
+      FNORM = DDWNRM(NEQ,R,WT,RPAR,IPAR)
+C
+      RETURN
+C----------------------- END OF SUBROUTINE DFNRMD ----------------------
+      END
diff --git a/libcruft/daspk/dfnrmk.f b/libcruft/daspk/dfnrmk.f
new file mode 100644
index 0000000..60aa795
--- /dev/null
+++ b/libcruft/daspk/dfnrmk.f
@@ -0,0 +1,70 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DFNRMK (NEQ, Y, T, YPRIME, SAVR, R, CJ, WT,
+     *                   SQRTN, RSQRTN, RES, IRES, PSOL, IRIN, IER,
+     *                   FNORM, EPLIN, WP, IWP, PWK, RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DFNRMK
+C***REFER TO  DLINSK
+C***DATE WRITTEN   940830   (YYMMDD)
+C***REVISION DATE  951006   (SQRTN, RSQRTN, and scaling of WT added.)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DFNRMK calculates the scaled preconditioned norm of the nonlinear
+C     function used in the nonlinear iteration for obtaining consistent
+C     initial conditions.  Specifically, DFNRMK calculates the weighted
+C     root-mean-square norm of the vector (P-inverse)*G(T,Y,YPRIME),
+C     where P is the preconditioner matrix.
+C
+C     In addition to the parameters described in the calling program
+C     DLINSK, the parameters represent
+C
+C     IRIN   -- Flag showing whether the current residual vector is
+C               input in SAVR.  1 means it is, 0 means it is not.
+C     R      -- Array of length NEQ that contains
+C               (P-inverse)*G(T,Y,YPRIME) on return.
+C     FNORM  -- Scalar containing the weighted norm of R on return.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   RES, DCOPY, DSCAL, PSOL, DDWNRM
+C
+C***END PROLOGUE  DFNRMK
+C
+C
+      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+      EXTERNAL RES, PSOL
+      DIMENSION Y(*), YPRIME(*), WT(*), SAVR(*), R(*), PWK(*)
+      DIMENSION WP(*), IWP(*), RPAR(*), IPAR(*)
+C-----------------------------------------------------------------------
+C     Call RES routine if IRIN = 0.
+C-----------------------------------------------------------------------
+      IF (IRIN .EQ. 0) THEN
+        IRES = 0
+        CALL RES (T, Y, YPRIME, CJ, SAVR, IRES, RPAR, IPAR)
+        IF (IRES .LT. 0) RETURN
+        ENDIF
+C-----------------------------------------------------------------------
+C     Apply inverse of left preconditioner to vector R.
+C     First scale WT array by 1/sqrt(N), and undo scaling afterward.
+C-----------------------------------------------------------------------
+      CALL DCOPY(NEQ, SAVR, 1, R, 1)
+      CALL DSCAL (NEQ, RSQRTN, WT, 1)
+      IER = 0
+      CALL PSOL (NEQ, T, Y, YPRIME, SAVR, PWK, CJ, WT, WP, IWP,
+     *           R, EPLIN, IER, RPAR, IPAR)
+      CALL DSCAL (NEQ, SQRTN, WT, 1)
+      IF (IER .NE. 0) RETURN
+C-----------------------------------------------------------------------
+C     Calculate norm of R.
+C-----------------------------------------------------------------------
+      FNORM = DDWNRM (NEQ, R, WT, RPAR, IPAR)
+C
+      RETURN
+C----------------------- END OF SUBROUTINE DFNRMK ----------------------
+      END
diff --git a/libcruft/daspk/dhels.f b/libcruft/daspk/dhels.f
new file mode 100644
index 0000000..7d58d33
--- /dev/null
+++ b/libcruft/daspk/dhels.f
@@ -0,0 +1,88 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DHELS (A, LDA, N, Q, B)
+C
+C***BEGIN PROLOGUE  DHELS
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C This is similar to the LINPACK routine DGESL except that
+C A is an upper Hessenberg matrix.
+C
+C     DHELS solves the least squares problem
+C
+C           MIN (B-A*X,B-A*X)
+C
+C     using the factors computed by DHEQR.
+C
+C     On entry
+C
+C        A       DOUBLE PRECISION (LDA, N)
+C                The output from DHEQR which contains the upper
+C                triangular factor R in the QR decomposition of A.
+C
+C        LDA     INTEGER
+C                The leading dimension of the array  A .
+C
+C        N       INTEGER
+C                A is originally an (N+1) by N matrix.
+C
+C        Q       DOUBLE PRECISION(2*N)
+C                The coefficients of the N givens rotations
+C                used in the QR factorization of A.
+C
+C        B       DOUBLE PRECISION(N+1)
+C                The right hand side vector.
+C
+C
+C     On return
+C
+C        B       The solution vector X.
+C
+C
+C     Modification of LINPACK.
+C     Peter Brown, Lawrence Livermore Natl. Lab.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   DAXPY 
+C
+C***END PROLOGUE  DHELS
+C
+      INTEGER LDA, N
+      DOUBLE PRECISION A(LDA,*), B(*), Q(*)
+      INTEGER IQ, K, KB, KP1
+      DOUBLE PRECISION C, S, T, T1, T2
+C
+C        Minimize (B-A*X,B-A*X).
+C        First form Q*B.
+C
+         DO 20 K = 1, N
+            KP1 = K + 1
+            IQ = 2*(K-1) + 1
+            C = Q(IQ)
+            S = Q(IQ+1)
+            T1 = B(K)
+            T2 = B(KP1)
+            B(K) = C*T1 - S*T2
+            B(KP1) = S*T1 + C*T2
+   20    CONTINUE
+C
+C        Now solve R*X = Q*B.
+C
+         DO 40 KB = 1, N
+            K = N + 1 - KB
+            B(K) = B(K)/A(K,K)
+            T = -B(K)
+            CALL DAXPY (K-1, T, A(1,K), 1, B(1), 1)
+   40    CONTINUE
+      RETURN
+C
+C------END OF SUBROUTINE DHELS------------------------------------------
+      END
diff --git a/libcruft/daspk/dheqr.f b/libcruft/daspk/dheqr.f
new file mode 100644
index 0000000..546ac2b
--- /dev/null
+++ b/libcruft/daspk/dheqr.f
@@ -0,0 +1,175 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DHEQR (A, LDA, N, Q, INFO, IJOB)
+C
+C***BEGIN PROLOGUE  DHEQR
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     This routine performs a QR decomposition of an upper
+C     Hessenberg matrix A.  There are two options available:
+C
+C          (1)  performing a fresh decomposition
+C          (2)  updating the QR factors by adding a row and A
+C               column to the matrix A.
+C
+C     DHEQR decomposes an upper Hessenberg matrix by using Givens
+C     rotations.
+C
+C     On entry
+C
+C        A       DOUBLE PRECISION(LDA, N)
+C                The matrix to be decomposed.
+C
+C        LDA     INTEGER
+C                The leading dimension of the array A.
+C
+C        N       INTEGER
+C                A is an (N+1) by N Hessenberg matrix.
+C
+C        IJOB    INTEGER
+C                = 1     Means that a fresh decomposition of the
+C                        matrix A is desired.
+C                .GE. 2  Means that the current decomposition of A
+C                        will be updated by the addition of a row
+C                        and a column.
+C     On return
+C
+C        A       The upper triangular matrix R.
+C                The factorization can be written Q*A = R, where
+C                Q is a product of Givens rotations and R is upper
+C                triangular.
+C
+C        Q       DOUBLE PRECISION(2*N)
+C                The factors C and S of each Givens rotation used
+C                in decomposing A.
+C
+C        INFO    INTEGER
+C                = 0  normal value.
+C                = K  If  A(K,K) .EQ. 0.0.  This is not an error
+C                     condition for this subroutine, but it does
+C                     indicate that DHELS will divide by zero
+C                     if called.
+C
+C     Modification of LINPACK.
+C     Peter Brown, Lawrence Livermore Natl. Lab.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED (NONE)
+C
+C***END PROLOGUE  DHEQR
+C
+      INTEGER LDA, N, INFO, IJOB
+      DOUBLE PRECISION A(LDA,*), Q(*)
+      INTEGER I, IQ, J, K, KM1, KP1, NM1
+      DOUBLE PRECISION C, S, T, T1, T2
+C
+      IF (IJOB .GT. 1) GO TO 70
+C-----------------------------------------------------------------------
+C A new factorization is desired.
+C-----------------------------------------------------------------------
+C
+C     QR decomposition without pivoting.
+C
+      INFO = 0
+      DO 60 K = 1, N
+         KM1 = K - 1
+         KP1 = K + 1
+C
+C           Compute Kth column of R.
+C           First, multiply the Kth column of A by the previous
+C           K-1 Givens rotations.
+C
+            IF (KM1 .LT. 1) GO TO 20
+            DO 10 J = 1, KM1
+              I = 2*(J-1) + 1
+              T1 = A(J,K)
+              T2 = A(J+1,K)
+              C = Q(I)
+              S = Q(I+1)
+              A(J,K) = C*T1 - S*T2
+              A(J+1,K) = S*T1 + C*T2
+   10         CONTINUE
+C
+C           Compute Givens components C and S.
+C
+   20       CONTINUE
+            IQ = 2*KM1 + 1
+            T1 = A(K,K)
+            T2 = A(KP1,K)
+            IF (T2 .NE. 0.0D0) GO TO 30
+              C = 1.0D0
+              S = 0.0D0
+              GO TO 50
+   30       CONTINUE
+            IF (ABS(T2) .LT. ABS(T1)) GO TO 40
+              T = T1/T2
+              S = -1.0D0/SQRT(1.0D0+T*T)
+              C = -S*T
+              GO TO 50
+   40       CONTINUE
+              T = T2/T1
+              C = 1.0D0/SQRT(1.0D0+T*T)
+              S = -C*T
+   50       CONTINUE
+            Q(IQ) = C
+            Q(IQ+1) = S
+            A(K,K) = C*T1 - S*T2
+            IF (A(K,K) .EQ. 0.0D0) INFO = K
+   60 CONTINUE
+      RETURN
+C-----------------------------------------------------------------------
+C The old factorization of A will be updated.  A row and a column
+C has been added to the matrix A.
+C N by N-1 is now the old size of the matrix.
+C-----------------------------------------------------------------------
+  70  CONTINUE
+      NM1 = N - 1
+C-----------------------------------------------------------------------
+C Multiply the new column by the N previous Givens rotations.
+C-----------------------------------------------------------------------
+      DO 100 K = 1,NM1
+        I = 2*(K-1) + 1
+        T1 = A(K,N)
+        T2 = A(K+1,N)
+        C = Q(I)
+        S = Q(I+1)
+        A(K,N) = C*T1 - S*T2
+        A(K+1,N) = S*T1 + C*T2
+ 100    CONTINUE
+C-----------------------------------------------------------------------
+C Complete update of decomposition by forming last Givens rotation,
+C and multiplying it times the column vector (A(N,N),A(NP1,N)).
+C-----------------------------------------------------------------------
+      INFO = 0
+      T1 = A(N,N)
+      T2 = A(N+1,N)
+      IF (T2 .NE. 0.0D0) GO TO 110
+        C = 1.0D0
+        S = 0.0D0
+        GO TO 130
+ 110  CONTINUE
+      IF (ABS(T2) .LT. ABS(T1)) GO TO 120
+        T = T1/T2
+        S = -1.0D0/SQRT(1.0D0+T*T)
+        C = -S*T
+        GO TO 130
+ 120  CONTINUE
+        T = T2/T1
+        C = 1.0D0/SQRT(1.0D0+T*T)
+        S = -C*T
+ 130  CONTINUE
+      IQ = 2*N - 1
+      Q(IQ) = C
+      Q(IQ+1) = S
+      A(N,N) = C*T1 - S*T2
+      IF (A(N,N) .EQ. 0.0D0) INFO = N
+      RETURN
+C
+C------END OF SUBROUTINE DHEQR------------------------------------------
+      END
diff --git a/libcruft/daspk/dinvwt.f b/libcruft/daspk/dinvwt.f
new file mode 100644
index 0000000..a7ab55d
--- /dev/null
+++ b/libcruft/daspk/dinvwt.f
@@ -0,0 +1,36 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DINVWT(NEQ,WT,IER)
+C
+C***BEGIN PROLOGUE  DINVWT
+C***REFER TO  DDASPK
+C***ROUTINES CALLED  (NONE)
+C***DATE WRITTEN   950125   (YYMMDD)
+C***END PROLOGUE  DINVWT
+C-----------------------------------------------------------------------
+C     This subroutine checks the error weight vector WT, of length NEQ,
+C     for components that are .le. 0, and if none are found, it
+C     inverts the WT(I) in place.  This replaces division operations
+C     with multiplications in all norm evaluations.
+C     IER is returned as 0 if all WT(I) were found positive,
+C     and the first I with WT(I) .le. 0.0 otherwise.
+C-----------------------------------------------------------------------
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION WT(*)
+C
+      DO 10 I = 1,NEQ
+        IF (WT(I) .LE. 0.0D0) GO TO 30
+ 10     CONTINUE
+      DO 20 I = 1,NEQ
+ 20     WT(I) = 1.0D0/WT(I)
+      IER = 0
+      RETURN
+C
+ 30   IER = I
+      RETURN
+C
+C------END OF SUBROUTINE DINVWT-----------------------------------------
+      END
diff --git a/libcruft/daspk/dlinsd.f b/libcruft/daspk/dlinsd.f
new file mode 100644
index 0000000..cb14b53
--- /dev/null
+++ b/libcruft/daspk/dlinsd.f
@@ -0,0 +1,182 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DLINSD (NEQ, Y, T, YPRIME, CJ, P, PNRM, WT, LSOFF,
+     *                   STPTOL, IRET, RES, IRES, WM, IWM,
+     *                   FNRM, ICOPT, ID, R, YNEW, YPNEW, ICNFLG,
+     *                   ICNSTR, RLX, RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DLINSD
+C***REFER TO  DNSID
+C***DATE WRITTEN   941025   (YYMMDD)
+C***REVISION DATE  941215   (YYMMDD)
+C***REVISION DATE  960129   Moved line RL = ONE to top block.
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DLINSD uses a linesearch algorithm to calculate a new (Y,YPRIME)
+C     pair (YNEW,YPNEW) such that 
+C
+C     f(YNEW,YPNEW) .le. (1 - 2*ALPHA*RL)*f(Y,YPRIME) ,
+C
+C     where 0 < RL <= 1.  Here, f(y,y') is defined as
+C
+C      f(y,y') = (1/2)*norm( (J-inverse)*G(t,y,y') )**2 ,
+C
+C     where norm() is the weighted RMS vector norm, G is the DAE
+C     system residual function, and J is the system iteration matrix
+C     (Jacobian).
+C
+C     In addition to the parameters defined elsewhere, we have
+C
+C     P       -- Approximate Newton step used in backtracking.
+C     PNRM    -- Weighted RMS norm of P.
+C     LSOFF   -- Flag showing whether the linesearch algorithm is
+C                to be invoked.  0 means do the linesearch, and
+C                1 means turn off linesearch.
+C     STPTOL  -- Tolerance used in calculating the minimum lambda
+C                value allowed.
+C     ICNFLG  -- Integer scalar.  If nonzero, then constraint violations
+C                in the proposed new approximate solution will be
+C                checked for, and the maximum step length will be
+C                adjusted accordingly.
+C     ICNSTR  -- Integer array of length NEQ containing flags for
+C                checking constraints.
+C     RLX     -- Real scalar restricting update size in DCNSTR.
+C     YNEW    -- Array of length NEQ used to hold the new Y in
+C                performing the linesearch.
+C     YPNEW   -- Array of length NEQ used to hold the new YPRIME in
+C                performing the linesearch.
+C     Y       -- Array of length NEQ containing the new Y (i.e.,=YNEW).
+C     YPRIME  -- Array of length NEQ containing the new YPRIME 
+C                (i.e.,=YPNEW).
+C     FNRM    -- Real scalar containing SQRT(2*f(Y,YPRIME)) for the
+C                current (Y,YPRIME) on input and output.
+C     R       -- Work array of length NEQ, containing the scaled 
+C                residual (J-inverse)*G(t,y,y') on return.
+C     IRET    -- Return flag.
+C                IRET=0 means that a satisfactory (Y,YPRIME) was found.
+C                IRET=1 means that the routine failed to find a new
+C                       (Y,YPRIME) that was sufficiently distinct from
+C                       the current (Y,YPRIME) pair.
+C                IRET=2 means IRES .ne. 0 from RES.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   DFNRMD, DYYPNW, DCOPY
+C
+C***END PROLOGUE  DLINSD
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      EXTERNAL  RES
+      DIMENSION Y(*), YPRIME(*), WT(*), R(*), ID(*)
+      DIMENSION WM(*), IWM(*)
+      DIMENSION YNEW(*), YPNEW(*), P(*), ICNSTR(*)
+      DIMENSION RPAR(*), IPAR(*)
+      CHARACTER MSG*80
+C
+      PARAMETER (LNRE=12, LKPRIN=31)
+C
+      SAVE ALPHA, ONE, TWO
+      DATA ALPHA/1.0D-4/, ONE/1.0D0/, TWO/2.0D0/
+C
+      KPRIN=IWM(LKPRIN)
+C
+      F1NRM = (FNRM*FNRM)/TWO
+      RATIO = ONE
+      IF (KPRIN .GE. 2) THEN
+        MSG = '------ IN ROUTINE DLINSD-- PNRM = (R1) )'
+        CALL XERRWD(MSG, 40, 901, 0, 0, 0, 0, 1, PNRM, 0.0D0)
+        ENDIF
+      TAU = PNRM
+      IVIO = 0
+      RL = ONE
+C-----------------------------------------------------------------------
+C Check for violations of the constraints, if any are imposed.
+C If any violations are found, the step vector P is rescaled, and the 
+C constraint check is repeated, until no violations are found.
+C-----------------------------------------------------------------------
+      IF (ICNFLG .NE. 0) THEN
+ 10      CONTINUE
+         CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
+         CALL DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR)
+         IF (IRET .EQ. 1) THEN
+            IVIO = 1
+            RATIO1 = TAU/PNRM
+            RATIO = RATIO*RATIO1
+            DO 20 I = 1,NEQ
+ 20           P(I) = P(I)*RATIO1
+            PNRM = TAU
+            IF (KPRIN .GE. 2) THEN
+              MSG = '------ CONSTRAINT VIOL., PNRM = (R1), INDEX = (I1)'
+              CALL XERRWD(MSG, 50, 902, 0, 1, IVAR, 0, 1, PNRM, 0.0D0)
+              ENDIF
+            IF (PNRM .LE. STPTOL) THEN
+              IRET = 1
+              RETURN
+              ENDIF
+            GO TO 10
+            ENDIF
+         ENDIF
+C
+      SLPI = (-TWO*F1NRM)*RATIO
+      RLMIN = STPTOL/PNRM
+      IF (LSOFF .EQ. 0 .AND. KPRIN .GE. 2) THEN
+        MSG = '------ MIN. LAMBDA = (R1)'
+        CALL XERRWD(MSG, 25, 903, 0, 0, 0, 0, 1, RLMIN, 0.0D0)
+        ENDIF
+C-----------------------------------------------------------------------
+C Begin iteration to find RL value satisfying alpha-condition.
+C If RL becomes less than RLMIN, then terminate with IRET = 1.
+C-----------------------------------------------------------------------
+ 100  CONTINUE
+      CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
+      CALL DFNRMD (NEQ, YNEW, T, YPNEW, R, CJ, WT, RES, IRES,
+     *              FNRMP, WM, IWM, RPAR, IPAR)
+      IWM(LNRE) = IWM(LNRE) + 1
+      IF (IRES .NE. 0) THEN
+        IRET = 2
+        RETURN
+        ENDIF
+      IF (LSOFF .EQ. 1) GO TO 150
+C
+      F1NRMP = FNRMP*FNRMP/TWO
+      IF (KPRIN .GE. 2) THEN
+        MSG = '------ LAMBDA = (R1)'
+        CALL XERRWD(MSG, 20, 904, 0, 0, 0, 0, 1, RL, 0.0D0)
+        MSG = '------ NORM(F1) = (R1),  NORM(F1NEW) = (R2)'
+        CALL XERRWD(MSG, 43, 905, 0, 0, 0, 0, 2, F1NRM, F1NRMP)
+        ENDIF
+      IF (F1NRMP .GT. F1NRM + ALPHA*SLPI*RL) GO TO 200
+C-----------------------------------------------------------------------
+C Alpha-condition is satisfied, or linesearch is turned off.
+C Copy YNEW,YPNEW to Y,YPRIME and return.
+C-----------------------------------------------------------------------
+ 150  IRET = 0
+      CALL DCOPY (NEQ, YNEW, 1, Y, 1)
+      CALL DCOPY (NEQ, YPNEW, 1, YPRIME, 1)
+      FNRM = FNRMP
+      IF (KPRIN .GE. 1) THEN
+        MSG = '------ LEAVING ROUTINE DLINSD, FNRM = (R1)'
+        CALL XERRWD(MSG, 42, 906, 0, 0, 0, 0, 1, FNRM, 0.0D0)
+        ENDIF
+      RETURN
+C-----------------------------------------------------------------------
+C Alpha-condition not satisfied.  Perform backtrack to compute new RL
+C value.  If no satisfactory YNEW,YPNEW can be found sufficiently 
+C distinct from Y,YPRIME, then return IRET = 1.
+C-----------------------------------------------------------------------
+ 200  CONTINUE
+      IF (RL .LT. RLMIN) THEN
+        IRET = 1
+        RETURN
+        ENDIF
+C
+      RL = RL/TWO
+      GO TO 100
+C
+C----------------------- END OF SUBROUTINE DLINSD ----------------------
+      END
diff --git a/libcruft/daspk/dlinsk.f b/libcruft/daspk/dlinsk.f
new file mode 100644
index 0000000..f2bbc51
--- /dev/null
+++ b/libcruft/daspk/dlinsk.f
@@ -0,0 +1,189 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DLINSK (NEQ, Y, T, YPRIME, SAVR, CJ, P, PNRM, WT,
+     *   SQRTN, RSQRTN, LSOFF, STPTOL, IRET, RES, IRES, PSOL, WM, IWM,
+     *   RHOK, FNRM, ICOPT, ID, WP, IWP, R, EPLIN, YNEW, YPNEW, PWK,
+     *   ICNFLG, ICNSTR, RLX, RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DLINSK
+C***REFER TO  DNSIK
+C***DATE WRITTEN   940830   (YYMMDD)
+C***REVISION DATE  951006   (Arguments SQRTN, RSQRTN added.)
+C***REVISION DATE  960129   Moved line RL = ONE to top block.
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DLINSK uses a linesearch algorithm to calculate a new (Y,YPRIME)
+C     pair (YNEW,YPNEW) such that 
+C
+C     f(YNEW,YPNEW) .le. (1 - 2*ALPHA*RL)*f(Y,YPRIME) + 
+C                          ALPHA*RL*RHOK*RHOK ,
+C
+C     where 0 < RL <= 1, and RHOK is the scaled preconditioned norm of
+C     the final residual vector in the Krylov iteration.  
+C     Here, f(y,y') is defined as
+C
+C      f(y,y') = (1/2)*norm( (P-inverse)*G(t,y,y') )**2 ,
+C
+C     where norm() is the weighted RMS vector norm, G is the DAE
+C     system residual function, and P is the preconditioner used
+C     in the Krylov iteration.
+C
+C     In addition to the parameters defined elsewhere, we have
+C
+C     SAVR    -- Work array of length NEQ, containing the residual
+C                vector G(t,y,y') on return.
+C     P       -- Approximate Newton step used in backtracking.
+C     PNRM    -- Weighted RMS norm of P.
+C     LSOFF   -- Flag showing whether the linesearch algorithm is
+C                to be invoked.  0 means do the linesearch, 
+C                1 means turn off linesearch.
+C     STPTOL  -- Tolerance used in calculating the minimum lambda
+C                value allowed.
+C     ICNFLG  -- Integer scalar.  If nonzero, then constraint violations
+C                in the proposed new approximate solution will be
+C                checked for, and the maximum step length will be
+C                adjusted accordingly.
+C     ICNSTR  -- Integer array of length NEQ containing flags for
+C                checking constraints.
+C     RHOK    -- Weighted norm of preconditioned Krylov residual.
+C     RLX     -- Real scalar restricting update size in DCNSTR.
+C     YNEW    -- Array of length NEQ used to hold the new Y in
+C                performing the linesearch.
+C     YPNEW   -- Array of length NEQ used to hold the new YPRIME in
+C                performing the linesearch.
+C     PWK     -- Work vector of length NEQ for use in PSOL.
+C     Y       -- Array of length NEQ containing the new Y (i.e.,=YNEW).
+C     YPRIME  -- Array of length NEQ containing the new YPRIME 
+C                (i.e.,=YPNEW).
+C     FNRM    -- Real scalar containing SQRT(2*f(Y,YPRIME)) for the
+C                current (Y,YPRIME) on input and output.
+C     R       -- Work space length NEQ for residual vector.
+C     IRET    -- Return flag.
+C                IRET=0 means that a satisfactory (Y,YPRIME) was found.
+C                IRET=1 means that the routine failed to find a new
+C                       (Y,YPRIME) that was sufficiently distinct from
+C                       the current (Y,YPRIME) pair.
+C                IRET=2 means a failure in RES or PSOL.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   DFNRMK, DYYPNW, DCOPY
+C
+C***END PROLOGUE  DLINSK
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      EXTERNAL  RES, PSOL
+      DIMENSION Y(*), YPRIME(*), P(*), WT(*), SAVR(*), R(*), ID(*)
+      DIMENSION WM(*), IWM(*), YNEW(*), YPNEW(*), PWK(*), ICNSTR(*)
+      DIMENSION WP(*), IWP(*), RPAR(*), IPAR(*)
+      CHARACTER MSG*80
+C
+      PARAMETER (LNRE=12, LNPS=21, LKPRIN=31)
+C
+      SAVE ALPHA, ONE, TWO
+      DATA ALPHA/1.0D-4/, ONE/1.0D0/, TWO/2.0D0/
+C
+      KPRIN=IWM(LKPRIN)
+      F1NRM = (FNRM*FNRM)/TWO
+      RATIO = ONE
+C
+      IF (KPRIN .GE. 2) THEN
+        MSG = '------ IN ROUTINE DLINSK-- PNRM = (R1) )'
+        CALL XERRWD(MSG, 40, 921, 0, 0, 0, 0, 1, PNRM, 0.0D0)
+        ENDIF
+      TAU = PNRM
+      IVIO = 0
+      RL = ONE
+C-----------------------------------------------------------------------
+C Check for violations of the constraints, if any are imposed.
+C If any violations are found, the step vector P is rescaled, and the 
+C constraint check is repeated, until no violations are found.
+C-----------------------------------------------------------------------
+      IF (ICNFLG .NE. 0) THEN
+ 10      CONTINUE
+         CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
+         CALL DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR)
+         IF (IRET .EQ. 1) THEN
+            IVIO = 1
+            RATIO1 = TAU/PNRM
+            RATIO = RATIO*RATIO1
+            DO 20 I = 1,NEQ
+ 20           P(I) = P(I)*RATIO1
+            PNRM = TAU
+            IF (KPRIN .GE. 2) THEN
+              MSG = '------ CONSTRAINT VIOL., PNRM = (R1), INDEX = (I1)'
+              CALL XERRWD(MSG, 50, 922, 0, 1, IVAR, 0, 1, PNRM, 0.0D0)
+              ENDIF
+            IF (PNRM .LE. STPTOL) THEN
+              IRET = 1
+              RETURN
+              ENDIF
+            GO TO 10
+            ENDIF
+         ENDIF
+C
+      SLPI = (-TWO*F1NRM + RHOK*RHOK)*RATIO
+      RLMIN = STPTOL/PNRM
+      IF (LSOFF .EQ. 0 .AND. KPRIN .GE. 2) THEN
+        MSG = '------ MIN. LAMBDA = (R1)'
+        CALL XERRWD(MSG, 25, 923, 0, 0, 0, 0, 1, RLMIN, 0.0D0)
+        ENDIF
+C-----------------------------------------------------------------------
+C Begin iteration to find RL value satisfying alpha-condition.
+C Update YNEW and YPNEW, then compute norm of new scaled residual and
+C perform alpha condition test.
+C-----------------------------------------------------------------------
+ 100  CONTINUE
+      CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
+      CALL DFNRMK (NEQ, YNEW, T, YPNEW, SAVR, R, CJ, WT, SQRTN, RSQRTN,
+     *  RES, IRES, PSOL, 0, IER, FNRMP, EPLIN, WP, IWP, PWK, RPAR, IPAR)
+      IWM(LNRE) = IWM(LNRE) + 1
+      IF (IRES .GE. 0) IWM(LNPS) = IWM(LNPS) + 1
+      IF (IRES .NE. 0 .OR. IER .NE. 0) THEN
+        IRET = 2
+        RETURN
+        ENDIF
+      IF (LSOFF .EQ. 1) GO TO 150
+C
+      F1NRMP = FNRMP*FNRMP/TWO
+      IF (KPRIN .GE. 2) THEN
+        MSG = '------ LAMBDA = (R1)'
+        CALL XERRWD(MSG, 20, 924, 0, 0, 0, 0, 1, RL, 0.0D0)
+        MSG = '------ NORM(F1) = (R1),  NORM(F1NEW) = (R2)'
+        CALL XERRWD(MSG, 43, 925, 0, 0, 0, 0, 2, F1NRM, F1NRMP)
+        ENDIF
+      IF (F1NRMP .GT. F1NRM + ALPHA*SLPI*RL) GO TO 200
+C-----------------------------------------------------------------------
+C Alpha-condition is satisfied, or linesearch is turned off.
+C Copy YNEW,YPNEW to Y,YPRIME and return.
+C-----------------------------------------------------------------------
+ 150  IRET = 0
+      CALL DCOPY(NEQ, YNEW, 1, Y, 1)
+      CALL DCOPY(NEQ, YPNEW, 1, YPRIME, 1)
+      FNRM = FNRMP
+      IF (KPRIN .GE. 1) THEN
+        MSG = '------ LEAVING ROUTINE DLINSK, FNRM = (R1)'
+        CALL XERRWD(MSG, 42, 926, 0, 0, 0, 0, 1, FNRM, 0.0D0)
+        ENDIF
+      RETURN
+C-----------------------------------------------------------------------
+C Alpha-condition not satisfied.  Perform backtrack to compute new RL
+C value.  If RL is less than RLMIN, i.e. no satisfactory YNEW,YPNEW can
+C be found sufficiently distinct from Y,YPRIME, then return IRET = 1.
+C-----------------------------------------------------------------------
+ 200  CONTINUE
+      IF (RL .LT. RLMIN) THEN
+        IRET = 1
+        RETURN
+        ENDIF
+C
+      RL = RL/TWO
+      GO TO 100
+C
+C----------------------- END OF SUBROUTINE DLINSK ----------------------
+      END
diff --git a/libcruft/daspk/dmatd.f b/libcruft/daspk/dmatd.f
new file mode 100644
index 0000000..ad238e8
--- /dev/null
+++ b/libcruft/daspk/dmatd.f
@@ -0,0 +1,183 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IER,EWT,E,
+     *                 WM,IWM,RES,IRES,UROUND,JACD,RPAR,IPAR)
+C
+C***BEGIN PROLOGUE  DMATD
+C***REFER TO  DDASPK
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  940701   (YYMMDD) (new LIPVT)
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     This routine computes the iteration matrix
+C     J = dG/dY+CJ*dG/dYPRIME (where G(X,Y,YPRIME)=0).
+C     Here J is computed by:
+C       the user-supplied routine JACD if IWM(MTYPE) is 1 or 4, or
+C       by numerical difference quotients if IWM(MTYPE) is 2 or 5.
+C
+C     The parameters have the following meanings.
+C     X        = Independent variable.
+C     Y        = Array containing predicted values.
+C     YPRIME   = Array containing predicted derivatives.
+C     DELTA    = Residual evaluated at (X,Y,YPRIME).
+C                (Used only if IWM(MTYPE)=2 or 5).
+C     CJ       = Scalar parameter defining iteration matrix.
+C     H        = Current stepsize in integration.
+C     IER      = Variable which is .NE. 0 if iteration matrix
+C                is singular, and 0 otherwise.
+C     EWT      = Vector of error weights for computing norms.
+C     E        = Work space (temporary) of length NEQ.
+C     WM       = Real work space for matrices.  On output
+C                it contains the LU decomposition
+C                of the iteration matrix.
+C     IWM      = Integer work space containing
+C                matrix information.
+C     RES      = External user-supplied subroutine
+C                to evaluate the residual.  See RES description
+C                in DDASPK prologue.
+C     IRES     = Flag which is equal to zero if no illegal values
+C                in RES, and less than zero otherwise.  (If IRES
+C                is less than zero, the matrix was not completed).
+C                In this case (if IRES .LT. 0), then IER = 0.
+C     UROUND   = The unit roundoff error of the machine being used.
+C     JACD     = Name of the external user-supplied routine
+C                to evaluate the iteration matrix.  (This routine
+C                is only used if IWM(MTYPE) is 1 or 4)
+C                See JAC description for the case INFO(12) = 0
+C                in DDASPK prologue.
+C     RPAR,IPAR= Real and integer parameter arrays that
+C                are used for communication between the
+C                calling program and external user routines.
+C                They are not altered by DMATD.
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   JACD, RES, DGETRF, DGBTRF
+C
+C***END PROLOGUE  DMATD
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),DELTA(*),EWT(*),E(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      EXTERNAL  RES, JACD
+C
+      PARAMETER (LML=1, LMU=2, LMTYPE=4, LNRE=12, LNPD=22, LLCIWP=30)
+C
+      LIPVT = IWM(LLCIWP)
+      IER = 0
+      MTYPE=IWM(LMTYPE)
+      GO TO (100,200,300,400,500),MTYPE
+C
+C
+C     Dense user-supplied matrix.
+C
+100   LENPD=IWM(LNPD)
+      DO 110 I=1,LENPD
+110      WM(I)=0.0D0
+      CALL JACD(X,Y,YPRIME,WM,CJ,RPAR,IPAR)
+      GO TO 230
+C
+C
+C     Dense finite-difference-generated matrix.
+C
+200   IRES=0
+      NROW=0
+      SQUR = SQRT(UROUND)
+      DO 210 I=1,NEQ
+         DEL=SQUR*MAX(ABS(Y(I)),ABS(H*YPRIME(I)),
+     *     ABS(1.D0/EWT(I)))
+         DEL=SIGN(DEL,H*YPRIME(I))
+         DEL=(Y(I)+DEL)-Y(I)
+         YSAVE=Y(I)
+         YPSAVE=YPRIME(I)
+         Y(I)=Y(I)+DEL
+         YPRIME(I)=YPRIME(I)+CJ*DEL
+         IWM(LNRE)=IWM(LNRE)+1
+         CALL RES(X,Y,YPRIME,CJ,E,IRES,RPAR,IPAR)
+         IF (IRES .LT. 0) RETURN
+         DELINV=1.0D0/DEL
+         DO 220 L=1,NEQ
+220        WM(NROW+L)=(E(L)-DELTA(L))*DELINV
+      NROW=NROW+NEQ
+      Y(I)=YSAVE
+      YPRIME(I)=YPSAVE
+210   CONTINUE
+C
+C
+C     Do dense-matrix LU decomposition on J.
+C
+230      CALL DGETRF( NEQ, NEQ, WM, NEQ, IWM(LIPVT), IER)
+      RETURN
+C
+C
+C     Dummy section for IWM(MTYPE)=3.
+C
+300   RETURN
+C
+C
+C     Banded user-supplied matrix.
+C
+400   LENPD=IWM(LNPD)
+      DO 410 I=1,LENPD
+410      WM(I)=0.0D0
+      CALL JACD(X,Y,YPRIME,WM,CJ,RPAR,IPAR)
+      MEBAND=2*IWM(LML)+IWM(LMU)+1
+      GO TO 550
+C
+C
+C     Banded finite-difference-generated matrix.
+C
+500   MBAND=IWM(LML)+IWM(LMU)+1
+      MBA=MIN0(MBAND,NEQ)
+      MEBAND=MBAND+IWM(LML)
+      MEB1=MEBAND-1
+      MSAVE=(NEQ/MBAND)+1
+      ISAVE=IWM(LNPD)
+      IPSAVE=ISAVE+MSAVE
+      IRES=0
+      SQUR=SQRT(UROUND)
+      DO 540 J=1,MBA
+        DO 510 N=J,NEQ,MBAND
+          K= (N-J)/MBAND + 1
+          WM(ISAVE+K)=Y(N)
+          WM(IPSAVE+K)=YPRIME(N)
+          DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),
+     *      ABS(1.D0/EWT(N)))
+          DEL=SIGN(DEL,H*YPRIME(N))
+          DEL=(Y(N)+DEL)-Y(N)
+          Y(N)=Y(N)+DEL
+510       YPRIME(N)=YPRIME(N)+CJ*DEL
+        IWM(LNRE)=IWM(LNRE)+1
+        CALL RES(X,Y,YPRIME,CJ,E,IRES,RPAR,IPAR)
+        IF (IRES .LT. 0) RETURN
+        DO 530 N=J,NEQ,MBAND
+          K= (N-J)/MBAND + 1
+          Y(N)=WM(ISAVE+K)
+          YPRIME(N)=WM(IPSAVE+K)
+          DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),
+     *      ABS(1.D0/EWT(N)))
+          DEL=SIGN(DEL,H*YPRIME(N))
+          DEL=(Y(N)+DEL)-Y(N)
+          DELINV=1.0D0/DEL
+          I1=MAX0(1,(N-IWM(LMU)))
+          I2=MIN0(NEQ,(N+IWM(LML)))
+          II=N*MEB1-IWM(LML)
+          DO 520 I=I1,I2
+520         WM(II+I)=(E(I)-DELTA(I))*DELINV
+530     CONTINUE
+540   CONTINUE
+C
+C
+C     Do LU decomposition of banded J.
+C
+550   CALL DGBTRF(NEQ, NEQ, IWM(LML), IWM(LMU), WM, MEBAND,
+     *     IWM(LIPVT), IER)
+      RETURN
+C
+C------END OF SUBROUTINE DMATD------------------------------------------
+      END
diff --git a/libcruft/daspk/dnedd.f b/libcruft/daspk/dnedd.f
new file mode 100644
index 0000000..dd2b53b
--- /dev/null
+++ b/libcruft/daspk/dnedd.f
@@ -0,0 +1,270 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DNEDD(X,Y,YPRIME,NEQ,RES,JACD,PDUM,H,WT,
+     *   JSTART,IDID,RPAR,IPAR,PHI,GAMMA,DUMSVR,DELTA,E,
+     *   WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,DUME,DUMS,DUMR,
+     *   EPCON,JCALC,JFDUM,KP1,NONNEG,NTYPE,IERNLS)
+C
+C***BEGIN PROLOGUE  DNEDD
+C***REFER TO  DDASPK
+C***DATE WRITTEN   891219   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DNEDD solves a nonlinear system of
+C     algebraic equations of the form
+C     G(X,Y,YPRIME) = 0 for the unknown Y.
+C
+C     The method used is a modified Newton scheme.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of unknowns.
+C     RES       -- External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     JACD      -- External user-supplied routine to evaluate the
+C                  Jacobian.  See JAC description for the case
+C                  INFO(12) = 0 in the DDASPK prologue.
+C     PDUM      -- Dummy argument.
+C     H         -- Appropriate step size for next step.
+C     WT        -- Vector of weights for error criterion.
+C     JSTART    -- Indicates first call to this routine.
+C                  If JSTART = 0, then this is the first call,
+C                  otherwise it is not.
+C     IDID      -- Completion flag, output by DNEDD.
+C                  See IDID description in DDASPK prologue.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     PHI       -- Array of divided differences used by
+C                  DNEDD.  The length is NEQ*(K+1),where
+C                  K is the maximum order.
+C     GAMMA     -- Array used to predict Y and YPRIME.  The length
+C                  is MAXORD+1 where MAXORD is the maximum order.
+C     DUMSVR    -- Dummy argument.
+C     DELTA     -- Work vector for NLS of length NEQ.
+C     E         -- Error accumulation vector for NLS of length NEQ.
+C     WM,IWM    -- Real and integer arrays storing
+C                  matrix information such as the matrix
+C                  of partial derivatives, permutation
+C                  vector, and various other information.
+C     CJ        -- Parameter always proportional to 1/H.
+C     CJOLD     -- Saves the value of CJ as of the last call to DMATD.
+C                  Accounts for changes in CJ needed to
+C                  decide whether to call DMATD.
+C     CJLAST    -- Previous value of CJ.
+C     S         -- A scalar determined by the approximate rate
+C                  of convergence of the Newton iteration and used
+C                  in the convergence test for the Newton iteration.
+C
+C                  If RATE is defined to be an estimate of the
+C                  rate of convergence of the Newton iteration,
+C                  then S = RATE/(1.D0-RATE).
+C
+C                  The closer RATE is to 0., the faster the Newton
+C                  iteration is converging; the closer RATE is to 1.,
+C                  the slower the Newton iteration is converging.
+C
+C                  On the first Newton iteration with an up-dated
+C                  preconditioner S = 100.D0, Thus the initial
+C                  RATE of convergence is approximately 1.
+C
+C                  S is preserved from call to call so that the rate
+C                  estimate from a previous step can be applied to
+C                  the current step.
+C     UROUND    -- Unit roundoff.
+C     DUME      -- Dummy argument.
+C     DUMS      -- Dummy argument.
+C     DUMR      -- Dummy argument.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     JCALC     -- Flag used to determine when to update
+C                  the Jacobian matrix.  In general:
+C
+C                  JCALC = -1 ==> Call the DMATD routine to update
+C                                 the Jacobian matrix.
+C                  JCALC =  0 ==> Jacobian matrix is up-to-date.
+C                  JCALC =  1 ==> Jacobian matrix is out-dated,
+C                                 but DMATD will not be called unless
+C                                 JCALC is set to -1.
+C     JFDUM     -- Dummy argument.
+C     KP1       -- The current order(K) + 1;  updated across calls.
+C     NONNEG    -- Flag to determine nonnegativity constraints.
+C     NTYPE     -- Identification code for the NLS routine.
+C                   0  ==> modified Newton; direct solver.
+C     IERNLS    -- Error flag for nonlinear solver.
+C                   0  ==> nonlinear solver converged.
+C                   1  ==> recoverable error inside nonlinear solver.
+C                  -1  ==> unrecoverable error inside nonlinear solver.
+C
+C     All variables with "DUM" in their names are dummy variables
+C     which are not used in this routine.
+C
+C     Following is a list and description of local variables which
+C     may not have an obvious usage.  They are listed in roughly the
+C     order they occur in this subroutine.
+C
+C     The following group of variables are passed as arguments to
+C     the Newton iteration solver.  They are explained in greater detail
+C     in DNSD:
+C        TOLNEW, MULDEL, MAXIT, IERNEW
+C
+C     IERTYP -- Flag which tells whether this subroutine is correct.
+C               0 ==> correct subroutine.
+C               1 ==> incorrect subroutine.
+C 
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   DDWNRM, RES, DMATD, DNSD
+C
+C***END PROLOGUE  DNEDD
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*)
+      DIMENSION DELTA(*),E(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      DIMENSION PHI(NEQ,*),GAMMA(*)
+      EXTERNAL  RES, JACD
+C
+      PARAMETER (LNRE=12, LNJE=13)
+C
+      SAVE MULDEL, MAXIT, XRATE
+      DATA MULDEL/1/, MAXIT/4/, XRATE/0.25D0/
+C
+C     Verify that this is the correct subroutine.
+C
+      IERTYP = 0
+      IF (NTYPE .NE. 0) THEN
+         IERTYP = 1
+         GO TO 380
+         ENDIF
+C
+C     If this is the first step, perform initializations.
+C
+      IF (JSTART .EQ. 0) THEN
+         CJOLD = CJ
+         JCALC = -1
+         ENDIF
+C
+C     Perform all other initializations.
+C
+      IERNLS = 0
+C
+C     Decide whether new Jacobian is needed.
+C
+      TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
+      TEMP2 = 1.0D0/TEMP1
+      IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
+      IF (CJ .NE. CJLAST) S = 100.D0
+C
+C-----------------------------------------------------------------------
+C     Entry point for updating the Jacobian with current
+C     stepsize.
+C-----------------------------------------------------------------------
+300   CONTINUE
+C
+C     Initialize all error flags to zero.
+C
+      IERJ = 0
+      IRES = 0
+      IERNEW = 0
+C
+C     Predict the solution and derivative and compute the tolerance
+C     for the Newton iteration.
+C
+      DO 310 I=1,NEQ
+         Y(I)=PHI(I,1)
+310      YPRIME(I)=0.0D0
+      DO 330 J=2,KP1
+         DO 320 I=1,NEQ
+            Y(I)=Y(I)+PHI(I,J)
+320         YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
+330   CONTINUE
+      PNORM = DDWNRM (NEQ,Y,WT,RPAR,IPAR)
+      TOLNEW = 100.D0*UROUND*PNORM
+C     
+C     Call RES to initialize DELTA.
+C
+      IWM(LNRE)=IWM(LNRE)+1
+      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 380
+C
+C     If indicated, reevaluate the iteration matrix 
+C     J = dG/dY + CJ*dG/dYPRIME (where G(X,Y,YPRIME)=0).
+C     Set JCALC to 0 as an indicator that this has been done.
+C
+      IF(JCALC .EQ. -1) THEN
+         IWM(LNJE)=IWM(LNJE)+1
+         JCALC=0
+         CALL DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IERJ,WT,E,WM,IWM,
+     *              RES,IRES,UROUND,JACD,RPAR,IPAR)
+         CJOLD=CJ
+         S = 100.D0
+         IF (IRES .LT. 0) GO TO 380
+         IF(IERJ .NE. 0)GO TO 380
+      ENDIF
+C
+C     Call the nonlinear Newton solver.
+C
+      TEMP1 = 2.0D0/(1.0D0 + CJ/CJOLD)
+      CALL DNSD(X,Y,YPRIME,NEQ,RES,PDUM,WT,RPAR,IPAR,DUMSVR,
+     *          DELTA,E,WM,IWM,CJ,DUMS,DUMR,DUME,EPCON,S,TEMP1,
+     *          TOLNEW,MULDEL,MAXIT,IRES,IDUM,IERNEW)
+C
+      IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN
+C
+C        The Newton iteration had a recoverable failure with an old
+C        iteration matrix.  Retry the step with a new iteration matrix.
+C
+         JCALC = -1
+         GO TO 300
+      ENDIF
+C
+      IF (IERNEW .NE. 0) GO TO 380
+C
+C     The Newton iteration has converged.  If nonnegativity of
+C     solution is required, set the solution nonnegative, if the
+C     perturbation to do it is small enough.  If the change is too
+C     large, then consider the corrector iteration to have failed.
+C
+375   IF(NONNEG .EQ. 0) GO TO 390
+      DO 377 I = 1,NEQ
+377      DELTA(I) = MIN(Y(I),0.0D0)
+      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF(DELNRM .GT. EPCON) GO TO 380
+      DO 378 I = 1,NEQ
+378      E(I) = E(I) - DELTA(I)
+      GO TO 390
+C
+C
+C     Exits from nonlinear solver.
+C     No convergence with current iteration
+C     matrix, or singular iteration matrix.
+C     Compute IERNLS and IDID accordingly.
+C
+380   CONTINUE
+      IF (IRES .LE. -2 .OR. IERTYP .NE. 0) THEN
+         IERNLS = -1
+         IF (IRES .LE. -2) IDID = -11
+         IF (IERTYP .NE. 0) IDID = -15
+      ELSE
+         IERNLS = 1
+         IF (IRES .LT. 0) IDID = -10
+         IF (IERJ .NE. 0) IDID = -8
+      ENDIF
+C
+390   JCALC = 1
+      RETURN
+C
+C------END OF SUBROUTINE DNEDD------------------------------------------
+      END
diff --git a/libcruft/daspk/dnedk.f b/libcruft/daspk/dnedk.f
new file mode 100644
index 0000000..6cfb435
--- /dev/null
+++ b/libcruft/daspk/dnedk.f
@@ -0,0 +1,275 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DNEDK(X,Y,YPRIME,NEQ,RES,JACK,PSOL,
+     *   H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA,SAVR,DELTA,E,
+     *   WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,EPLI,SQRTN,RSQRTN,
+     *   EPCON,JCALC,JFLG,KP1,NONNEG,NTYPE,IERNLS)
+C
+C***BEGIN PROLOGUE  DNEDK
+C***REFER TO  DDASPK
+C***DATE WRITTEN   891219   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  940701   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DNEDK solves a nonlinear system of
+C     algebraic equations of the form
+C     G(X,Y,YPRIME) = 0 for the unknown Y.
+C
+C     The method used is a matrix-free Newton scheme.
+C
+C     The parameters represent
+C     X         -- Independent variable.
+C     Y         -- Solution vector at x.
+C     YPRIME    -- Derivative of solution vector
+C                  after successful step.
+C     NEQ       -- Number of equations to be integrated.
+C     RES       -- External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     JACK     --  External user-supplied routine to update
+C                  the preconditioner.  (This is optional).
+C                  See JAC description for the case
+C                  INFO(12) = 1 in the DDASPK prologue.
+C     PSOL      -- External user-supplied routine to solve
+C                  a linear system using preconditioning. 
+C                  (This is optional).  See explanation inside DDASPK.
+C     H         -- Appropriate step size for this step.
+C     WT        -- Vector of weights for error criterion.
+C     JSTART    -- Indicates first call to this routine.
+C                  If JSTART = 0, then this is the first call,
+C                  otherwise it is not.
+C     IDID      -- Completion flag, output by DNEDK.
+C                  See IDID description in DDASPK prologue.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     PHI       -- Array of divided differences used by
+C                  DNEDK.  The length is NEQ*(K+1), where
+C                  K is the maximum order.
+C     GAMMA     -- Array used to predict Y and YPRIME.  The length
+C                  is K+1, where K is the maximum order.
+C     SAVR      -- Work vector for DNEDK of length NEQ.
+C     DELTA     -- Work vector for DNEDK of length NEQ.
+C     E         -- Error accumulation vector for DNEDK of length NEQ.
+C     WM,IWM    -- Real and integer arrays storing
+C                  matrix information for linear system
+C                  solvers, and various other information.
+C     CJ        -- Parameter always proportional to 1/H.
+C     CJOLD     -- Saves the value of CJ as of the last call to DITMD.
+C                  Accounts for changes in CJ needed to
+C                  decide whether to call DITMD.
+C     CJLAST    -- Previous value of CJ.
+C     S         -- A scalar determined by the approximate rate
+C                  of convergence of the Newton iteration and used
+C                  in the convergence test for the Newton iteration.
+C
+C                  If RATE is defined to be an estimate of the
+C                  rate of convergence of the Newton iteration,
+C                  then S = RATE/(1.D0-RATE).
+C
+C                  The closer RATE is to 0., the faster the Newton
+C                  iteration is converging; the closer RATE is to 1.,
+C                  the slower the Newton iteration is converging.
+C
+C                  On the first Newton iteration with an up-dated
+C                  preconditioner S = 100.D0, Thus the initial
+C                  RATE of convergence is approximately 1.
+C
+C                  S is preserved from call to call so that the rate
+C                  estimate from a previous step can be applied to
+C                  the current step.
+C     UROUND    -- Unit roundoff.
+C     EPLI      -- convergence test constant.
+C                  See DDASPK prologue for more details.
+C     SQRTN     -- Square root of NEQ.
+C     RSQRTN    -- reciprical of square root of NEQ.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     JCALC     -- Flag used to determine when to update
+C                  the Jacobian matrix.  In general:
+C
+C                  JCALC = -1 ==> Call the DITMD routine to update
+C                                 the Jacobian matrix.
+C                  JCALC =  0 ==> Jacobian matrix is up-to-date.
+C                  JCALC =  1 ==> Jacobian matrix is out-dated,
+C                                 but DITMD will not be called unless
+C                                 JCALC is set to -1.
+C     JFLG      -- Flag showing whether a Jacobian routine is supplied.
+C     KP1       -- The current order + 1;  updated across calls.
+C     NONNEG    -- Flag to determine nonnegativity constraints.
+C     NTYPE     -- Identification code for the DNEDK routine.
+C                   1 ==> modified Newton; iterative linear solver.
+C                   2 ==> modified Newton; user-supplied linear solver.
+C     IERNLS    -- Error flag for nonlinear solver.
+C                   0 ==> nonlinear solver converged.
+C                   1 ==> recoverable error inside non-linear solver.
+C                  -1 ==> unrecoverable error inside non-linear solver.
+C
+C     The following group of variables are passed as arguments to
+C     the Newton iteration solver.  They are explained in greater detail
+C     in DNSK:
+C        TOLNEW, MULDEL, MAXIT, IERNEW
+C
+C     IERTYP -- Flag which tells whether this subroutine is correct.
+C               0 ==> correct subroutine.
+C               1 ==> incorrect subroutine.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   RES, JACK, DDWNRM, DNSK
+C
+C***END PROLOGUE  DNEDK
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*)
+      DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*)
+      DIMENSION WM(*),IWM(*)
+      DIMENSION GAMMA(*),RPAR(*),IPAR(*)
+      EXTERNAL  RES, JACK, PSOL
+C
+      PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30)
+C
+      SAVE MULDEL, MAXIT, XRATE
+      DATA MULDEL/0/, MAXIT/4/, XRATE/0.25D0/
+C
+C     Verify that this is the correct subroutine.
+C
+      IERTYP = 0
+      IF (NTYPE .NE. 1) THEN
+         IERTYP = 1
+         GO TO 380
+         ENDIF
+C
+C     If this is the first step, perform initializations.
+C
+      IF (JSTART .EQ. 0) THEN
+         CJOLD = CJ
+         JCALC = -1
+         S = 100.D0
+         ENDIF
+C
+C     Perform all other initializations.
+C
+      IERNLS = 0
+      LWP = IWM(LLOCWP)
+      LIWP = IWM(LLCIWP)
+C
+C     Decide whether to update the preconditioner.
+C
+      IF (JFLG .NE. 0) THEN
+         TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
+         TEMP2 = 1.0D0/TEMP1
+         IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
+         IF (CJ .NE. CJLAST) S = 100.D0
+      ELSE
+         JCALC = 0
+         ENDIF
+C
+C     Looping point for updating preconditioner with current stepsize.
+C
+300   CONTINUE
+C
+C     Initialize all error flags to zero.
+C
+      IERPJ = 0
+      IRES = 0
+      IERSL = 0
+      IERNEW = 0
+C
+C     Predict the solution and derivative and compute the tolerance
+C     for the Newton iteration.
+C
+      DO 310 I=1,NEQ
+         Y(I)=PHI(I,1)
+310      YPRIME(I)=0.0D0
+      DO 330 J=2,KP1
+         DO 320 I=1,NEQ
+            Y(I)=Y(I)+PHI(I,J)
+320         YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
+330   CONTINUE
+      EPLIN = EPLI*EPCON
+      TOLNEW = EPLIN
+C
+C     Call RES to initialize DELTA.
+C
+      IWM(LNRE)=IWM(LNRE)+1
+      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 380
+C
+C
+C     If indicated, update the preconditioner.
+C     Set JCALC to 0 as an indicator that this has been done.
+C
+      IF(JCALC .EQ. -1)THEN
+         IWM(LNJE) = IWM(LNJE) + 1
+         JCALC=0
+         CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, E, H, CJ,
+     *      WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR)
+         CJOLD=CJ
+         S = 100.D0
+         IF (IRES .LT. 0)  GO TO 380
+         IF (IERPJ .NE. 0) GO TO 380
+      ENDIF
+C
+C     Call the nonlinear Newton solver.
+C
+      CALL DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR,SAVR,
+     *   DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON,
+     *   S,TEMP1,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW)
+C
+      IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN
+C
+C     The Newton iteration had a recoverable failure with an old
+C     preconditioner.  Retry the step with a new preconditioner.
+C
+         JCALC = -1
+         GO TO 300
+      ENDIF
+C
+      IF (IERNEW .NE. 0) GO TO 380
+C
+C     The Newton iteration has converged.  If nonnegativity of
+C     solution is required, set the solution nonnegative, if the
+C     perturbation to do it is small enough.  If the change is too
+C     large, then consider the corrector iteration to have failed.
+C
+      IF(NONNEG .EQ. 0) GO TO 390
+      DO 360 I = 1,NEQ
+ 360    DELTA(I) = MIN(Y(I),0.0D0)
+      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF(DELNRM .GT. EPCON) GO TO 380
+      DO 370 I = 1,NEQ
+ 370    E(I) = E(I) - DELTA(I)
+      GO TO 390
+C
+C
+C     Exits from nonlinear solver.
+C     No convergence with current preconditioner.
+C     Compute IERNLS and IDID accordingly.
+C
+380   CONTINUE
+      IF (IRES .LE. -2 .OR. IERSL .LT. 0 .OR. IERTYP .NE. 0) THEN
+         IERNLS = -1
+         IF (IRES .LE. -2) IDID = -11
+         IF (IERSL .LT. 0) IDID = -13
+         IF (IERTYP .NE. 0) IDID = -15
+      ELSE
+         IERNLS =  1
+         IF (IRES .EQ. -1) IDID = -10
+         IF (IERPJ .NE. 0) IDID = -5
+         IF (IERSL .GT. 0) IDID = -14
+      ENDIF
+C
+C
+390   JCALC = 1
+      RETURN
+C
+C------END OF SUBROUTINE DNEDK------------------------------------------
+      END
diff --git a/libcruft/daspk/dnsd.f b/libcruft/daspk/dnsd.f
new file mode 100644
index 0000000..88aa931
--- /dev/null
+++ b/libcruft/daspk/dnsd.f
@@ -0,0 +1,168 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DNSD(X,Y,YPRIME,NEQ,RES,PDUM,WT,RPAR,IPAR,
+     *   DUMSVR,DELTA,E,WM,IWM,CJ,DUMS,DUMR,DUME,EPCON,
+     *   S,CONFAC,TOLNEW,MULDEL,MAXIT,IRES,IDUM,IERNEW)
+C
+C***BEGIN PROLOGUE  DNSD
+C***REFER TO  DDASPK
+C***DATE WRITTEN   891219   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  950126   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DNSD solves a nonlinear system of
+C     algebraic equations of the form
+C     G(X,Y,YPRIME) = 0 for the unknown Y.
+C
+C     The method used is a modified Newton scheme.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of unknowns.
+C     RES       -- External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     PDUM      -- Dummy argument.
+C     WT        -- Vector of weights for error criterion.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     DUMSVR    -- Dummy argument.
+C     DELTA     -- Work vector for DNSD of length NEQ.
+C     E         -- Error accumulation vector for DNSD of length NEQ.
+C     WM,IWM    -- Real and integer arrays storing
+C                  matrix information such as the matrix
+C                  of partial derivatives, permutation
+C                  vector, and various other information.
+C     CJ        -- Parameter always proportional to 1/H (step size).
+C     DUMS      -- Dummy argument.
+C     DUMR      -- Dummy argument.
+C     DUME      -- Dummy argument.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     S         -- Used for error convergence tests.
+C                  In the Newton iteration: S = RATE/(1 - RATE),
+C                  where RATE is the estimated rate of convergence
+C                  of the Newton iteration.
+C                  The calling routine passes the initial value
+C                  of S to the Newton iteration.
+C     CONFAC    -- A residual scale factor to improve convergence.
+C     TOLNEW    -- Tolerance on the norm of Newton correction in
+C                  alternative Newton convergence test.
+C     MULDEL    -- A flag indicating whether or not to multiply
+C                  DELTA by CONFAC.
+C                  0  ==> do not scale DELTA by CONFAC.
+C                  1  ==> scale DELTA by CONFAC.
+C     MAXIT     -- Maximum allowed number of Newton iterations.
+C     IRES      -- Error flag returned from RES.  See RES description
+C                  in DDASPK prologue.  If IRES = -1, then IERNEW
+C                  will be set to 1.
+C                  If IRES < -1, then IERNEW will be set to -1.
+C     IDUM      -- Dummy argument.
+C     IERNEW    -- Error flag for Newton iteration.
+C                   0  ==> Newton iteration converged.
+C                   1  ==> recoverable error inside Newton iteration.
+C                  -1  ==> unrecoverable error inside Newton iteration.
+C
+C     All arguments with "DUM" in their names are dummy arguments
+C     which are not used in this routine.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   DSLVD, DDWNRM, RES
+C
+C***END PROLOGUE  DNSD
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*),DELTA(*),E(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      EXTERNAL  RES
+C
+      PARAMETER (LNRE=12, LNNI=19)
+C
+C     Initialize Newton counter M and accumulation vector E. 
+C
+      M = 0
+      DO 100 I=1,NEQ
+100     E(I)=0.0D0
+C
+C     Corrector loop.
+C
+300   CONTINUE
+      IWM(LNNI) = IWM(LNNI) + 1
+C
+C     If necessary, multiply residual by convergence factor.
+C
+      IF (MULDEL .EQ. 1) THEN
+         DO 320 I = 1,NEQ
+320        DELTA(I) = DELTA(I) * CONFAC
+        ENDIF
+C
+C     Compute a new iterate (back-substitution).
+C     Store the correction in DELTA.
+C
+      CALL DSLVD(NEQ,DELTA,WM,IWM)
+C
+C     Update Y, E, and YPRIME.
+C
+      DO 340 I=1,NEQ
+         Y(I)=Y(I)-DELTA(I)
+         E(I)=E(I)-DELTA(I)
+340      YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
+C
+C     Test for convergence of the iteration.
+C
+      DELNRM=DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF (DELNRM .LE. TOLNEW) GO TO 370
+      IF (M .EQ. 0) THEN
+        OLDNRM = DELNRM
+      ELSE
+        RATE = (DELNRM/OLDNRM)**(1.0D0/M)
+        IF (RATE .GT. 0.9D0) GO TO 380
+        S = RATE/(1.0D0 - RATE)
+      ENDIF
+      IF (S*DELNRM .LE. EPCON) GO TO 370
+C
+C     The corrector has not yet converged.
+C     Update M and test whether the
+C     maximum number of iterations have
+C     been tried.
+C
+      M=M+1
+      IF(M.GE.MAXIT) GO TO 380
+C
+C     Evaluate the residual,
+C     and go back to do another iteration.
+C
+      IWM(LNRE)=IWM(LNRE)+1
+      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 380
+      GO TO 300
+C
+C     The iteration has converged.
+C
+370   RETURN
+C
+C     The iteration has not converged.  Set IERNEW appropriately.
+C
+380   CONTINUE
+      IF (IRES .LE. -2 ) THEN
+         IERNEW = -1
+      ELSE
+         IERNEW = 1
+      ENDIF
+      RETURN
+C
+C
+C------END OF SUBROUTINE DNSD-------------------------------------------
+      END
diff --git a/libcruft/daspk/dnsid.f b/libcruft/daspk/dnsid.f
new file mode 100644
index 0000000..243f57a
--- /dev/null
+++ b/libcruft/daspk/dnsid.f
@@ -0,0 +1,157 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DNSID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,WT,RPAR,IPAR,
+     *   DELTA,R,YIC,YPIC,WM,IWM,CJ,EPCON,RATEMX,MAXIT,STPTOL,
+     *   ICNFLG,ICNSTR,IERNEW)
+C
+C***BEGIN PROLOGUE  DNSID
+C***REFER TO  DDASPK
+C***DATE WRITTEN   940701   (YYMMDD)
+C***REVISION DATE  950713   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DNSID solves a nonlinear system of algebraic equations of the
+C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME
+C     in the initial conditions.
+C
+C     The method used is a modified Newton scheme.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of unknowns.
+C     ICOPT     -- Initial condition option chosen (1 or 2).
+C     ID        -- Array of dimension NEQ, which must be initialized
+C                  if ICOPT = 1.  See DDASIC.
+C     RES       -- External user-supplied subroutine to evaluate the
+C                  residual.  See RES description in DDASPK prologue.
+C     WT        -- Vector of weights for error criterion.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     DELTA     -- Residual vector on entry, and work vector of
+C                  length NEQ for DNSID.
+C     WM,IWM    -- Real and integer arrays storing matrix information
+C                  such as the matrix of partial derivatives,
+C                  permutation vector, and various other information.
+C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
+C     R         -- Array of length NEQ used as workspace by the 
+C                  linesearch routine DLINSD.
+C     YIC,YPIC  -- Work vectors for DLINSD, each of length NEQ.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     RATEMX    -- Maximum convergence rate for which Newton iteration
+C                  is considered converging.
+C     MAXIT     -- Maximum allowed number of Newton iterations.
+C     STPTOL    -- Tolerance used in calculating the minimum lambda
+C                  value allowed.
+C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
+C                  violations in the proposed new approximate solution
+C                  will be checked for, and the maximum step length 
+C                  will be adjusted accordingly.
+C     ICNSTR    -- Integer array of length NEQ containing flags for
+C                  checking constraints.
+C     IERNEW    -- Error flag for Newton iteration.
+C                   0  ==> Newton iteration converged.
+C                   1  ==> failed to converge, but RATE .le. RATEMX.
+C                   2  ==> failed to converge, RATE .gt. RATEMX.
+C                   3  ==> other recoverable error (IRES = -1, or
+C                          linesearch failed).
+C                  -1  ==> unrecoverable error (IRES = -2).
+C
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   DSLVD, DDWNRM, DLINSD, DCOPY
+C
+C***END PROLOGUE  DNSID
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*),R(*)
+      DIMENSION ID(*),DELTA(*), YIC(*), YPIC(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      DIMENSION ICNSTR(*)
+      EXTERNAL  RES
+C
+      PARAMETER (LNNI=19, LLSOFF=35)
+C
+C
+C     Initializations.  M is the Newton iteration counter.
+C
+      LSOFF = IWM(LLSOFF)
+      M = 0
+      RATE = 1.0D0
+      RLX = 0.4D0
+C
+C     Compute a new step vector DELTA by back-substitution.
+C
+      CALL DSLVD (NEQ, DELTA, WM, IWM)
+C
+C     Get norm of DELTA.  Return now if norm(DELTA) .le. EPCON.
+C
+      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
+      FNRM = DELNRM
+      IF (FNRM .LE. EPCON) RETURN
+C
+C     Newton iteration loop.
+C
+ 300  CONTINUE
+      IWM(LNNI) = IWM(LNNI) + 1
+C
+C     Call linesearch routine for global strategy and set RATE
+C
+      OLDFNM = FNRM
+C
+      CALL DLINSD (NEQ, Y, X, YPRIME, CJ, DELTA, DELNRM, WT, LSOFF,
+     *             STPTOL, IRET, RES, IRES, WM, IWM, FNRM, ICOPT, ID,
+     *             R, YIC, YPIC, ICNFLG, ICNSTR, RLX, RPAR, IPAR)
+C
+      RATE = FNRM/OLDFNM
+C
+C     Check for error condition from linesearch.
+      IF (IRET .NE. 0) GO TO 390
+C
+C     Test for convergence of the iteration, and return or loop.
+C
+      IF (FNRM .LE. EPCON) RETURN
+C
+C     The iteration has not yet converged.  Update M.
+C     Test whether the maximum number of iterations have been tried.
+C
+      M = M + 1
+      IF (M .GE. MAXIT) GO TO 380
+C
+C     Copy the residual to DELTA and its norm to DELNRM, and loop for
+C     another iteration.
+C
+      CALL DCOPY (NEQ, R, 1, DELTA, 1)
+      DELNRM = FNRM      
+      GO TO 300
+C
+C     The maximum number of iterations was done.  Set IERNEW and return.
+C
+ 380  IF (RATE .LE. RATEMX) THEN
+         IERNEW = 1
+      ELSE
+         IERNEW = 2
+      ENDIF
+      RETURN
+C
+ 390  IF (IRES .LE. -2) THEN
+         IERNEW = -1
+      ELSE
+         IERNEW = 3
+      ENDIF
+      RETURN
+C
+C
+C------END OF SUBROUTINE DNSID------------------------------------------
+      END
diff --git a/libcruft/daspk/dnsik.f b/libcruft/daspk/dnsik.f
new file mode 100644
index 0000000..5aa9931
--- /dev/null
+++ b/libcruft/daspk/dnsik.f
@@ -0,0 +1,189 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DNSIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,PSOL,WT,RPAR,IPAR,
+     *   SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON,
+     *   RATEMX,MAXIT,STPTOL,ICNFLG,ICNSTR,IERNEW)
+C
+C***BEGIN PROLOGUE  DNSIK
+C***REFER TO  DDASPK
+C***DATE WRITTEN   940701   (YYMMDD)
+C***REVISION DATE  950714   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DNSIK solves a nonlinear system of algebraic equations of the
+C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in
+C     the initial conditions.
+C
+C     The method used is a Newton scheme combined with a linesearch
+C     algorithm, using Krylov iterative linear system methods.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of unknowns.
+C     ICOPT     -- Initial condition option chosen (1 or 2).
+C     ID        -- Array of dimension NEQ, which must be initialized
+C                  if ICOPT = 1.  See DDASIC.
+C     RES       -- External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     PSOL      -- External user-supplied routine to solve
+C                  a linear system using preconditioning. 
+C                  See explanation inside DDASPK.
+C     WT        -- Vector of weights for error criterion.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     SAVR      -- Work vector for DNSIK of length NEQ.
+C     DELTA     -- Residual vector on entry, and work vector of
+C                  length NEQ for DNSIK.
+C     R         -- Work vector for DNSIK of length NEQ.
+C     YIC,YPIC  -- Work vectors for DNSIK, each of length NEQ.
+C     PWK       -- Work vector for DNSIK of length NEQ.
+C     WM,IWM    -- Real and integer arrays storing
+C                  matrix information such as the matrix
+C                  of partial derivatives, permutation
+C                  vector, and various other information.
+C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
+C     SQRTN     -- Square root of NEQ.
+C     RSQRTN    -- reciprical of square root of NEQ.
+C     EPLIN     -- Tolerance for linear system solver.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     RATEMX    -- Maximum convergence rate for which Newton iteration
+C                  is considered converging.
+C     MAXIT     -- Maximum allowed number of Newton iterations.
+C     STPTOL    -- Tolerance used in calculating the minimum lambda
+C                  value allowed.
+C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
+C                  violations in the proposed new approximate solution
+C                  will be checked for, and the maximum step length
+C                  will be adjusted accordingly.
+C     ICNSTR    -- Integer array of length NEQ containing flags for
+C                  checking constraints.
+C     IERNEW    -- Error flag for Newton iteration.
+C                   0  ==> Newton iteration converged.
+C                   1  ==> failed to converge, but RATE .lt. 1.
+C                   2  ==> failed to converge, RATE .gt. RATEMX.
+C                   3  ==> other recoverable error.
+C                  -1  ==> unrecoverable error inside Newton iteration.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   DFNRMK, DSLVK, DDWNRM, DLINSK, DCOPY
+C
+C***END PROLOGUE  DNSIK
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*),ID(*),DELTA(*),R(*),SAVR(*)
+      DIMENSION YIC(*),YPIC(*),PWK(*),WM(*),IWM(*), RPAR(*),IPAR(*)
+      DIMENSION ICNSTR(*)
+      EXTERNAL RES, PSOL
+C
+      PARAMETER (LNNI=19, LNPS=21, LLOCWP=29, LLCIWP=30)
+      PARAMETER (LLSOFF=35, LSTOL=14)
+C
+C
+C     Initializations.  M is the Newton iteration counter.
+C
+      LSOFF = IWM(LLSOFF)
+      M = 0
+      RATE = 1.0D0
+      LWP = IWM(LLOCWP)
+      LIWP = IWM(LLCIWP)
+      RLX = 0.4D0
+C
+C     Save residual in SAVR.
+C
+      CALL DCOPY (NEQ, DELTA, 1, SAVR, 1)
+C
+C     Compute norm of (P-inverse)*(residual).
+C
+      CALL DFNRMK (NEQ, Y, X, YPRIME, SAVR, R, CJ, WT, SQRTN, RSQRTN,
+     *   RES, IRES, PSOL, 1, IER, FNRM, EPLIN, WM(LWP), IWM(LIWP),
+     *   PWK, RPAR, IPAR)
+      IWM(LNPS) = IWM(LNPS) + 1
+      IF (IER .NE. 0) THEN
+        IERNEW = 3
+        RETURN
+      ENDIF
+C
+C     Return now if residual norm is .le. EPCON.
+C
+      IF (FNRM .LE. EPCON) RETURN
+C
+C     Newton iteration loop.
+C
+300   CONTINUE
+      IWM(LNNI) = IWM(LNNI) + 1
+C
+C     Compute a new step vector DELTA.
+C
+      CALL DSLVK (NEQ, Y, X, YPRIME, SAVR, DELTA, WT, WM, IWM,
+     *   RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK,
+     *   RPAR, IPAR)
+      IF (IRES .NE. 0 .OR. IERSL .NE. 0) GO TO 390
+C
+C     Get norm of DELTA.  Return now if DELTA is zero.
+C
+      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF (DELNRM .EQ. 0.0D0) RETURN
+C
+C     Call linesearch routine for global strategy and set RATE.
+C
+      OLDFNM = FNRM
+C
+      CALL DLINSK (NEQ, Y, X, YPRIME, SAVR, CJ, DELTA, DELNRM, WT,
+     *   SQRTN, RSQRTN, LSOFF, STPTOL, IRET, RES, IRES, PSOL, WM, IWM,
+     *   RHOK, FNRM, ICOPT, ID, WM(LWP), IWM(LIWP), R, EPLIN, YIC, YPIC,
+     *   PWK, ICNFLG, ICNSTR, RLX, RPAR, IPAR)
+C
+      RATE = FNRM/OLDFNM
+C
+C     Check for error condition from linesearch.
+      IF (IRET .NE. 0) GO TO 390
+C
+C     Test for convergence of the iteration, and return or loop.
+C
+      IF (FNRM .LE. EPCON) RETURN
+C
+C     The iteration has not yet converged.  Update M.
+C     Test whether the maximum number of iterations have been tried.
+C
+      M=M+1
+      IF(M .GE. MAXIT) GO TO 380
+C
+C     Copy the residual SAVR to DELTA and loop for another iteration.
+C
+      CALL DCOPY (NEQ,  SAVR, 1, DELTA, 1)
+      GO TO 300
+C
+C     The maximum number of iterations was done.  Set IERNEW and return.
+C
+380   IF (RATE .LE. RATEMX) THEN
+         IERNEW = 1
+      ELSE
+         IERNEW = 2
+      ENDIF
+      RETURN
+C
+390   IF (IRES .LE. -2 .OR. IERSL .LT. 0) THEN
+         IERNEW = -1
+      ELSE
+         IERNEW = 3
+         IF (IRES .EQ. 0 .AND. IERSL .EQ. 1 .AND. M .GE. 2 
+     1       .AND. RATE .LT. 1.0D0) IERNEW = 1
+      ENDIF
+      RETURN
+C
+C
+C----------------------- END OF SUBROUTINE DNSIK------------------------
+      END
diff --git a/libcruft/daspk/dnsk.f b/libcruft/daspk/dnsk.f
new file mode 100644
index 0000000..23270a4
--- /dev/null
+++ b/libcruft/daspk/dnsk.f
@@ -0,0 +1,179 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR,
+     *   SAVR,DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON,
+     *   S,CONFAC,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW)
+C
+C***BEGIN PROLOGUE  DNSK
+C***REFER TO  DDASPK
+C***DATE WRITTEN   891219   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  950126   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DNSK solves a nonlinear system of
+C     algebraic equations of the form
+C     G(X,Y,YPRIME) = 0 for the unknown Y.
+C
+C     The method used is a modified Newton scheme.
+C
+C     The parameters represent
+C
+C     X         -- Independent variable.
+C     Y         -- Solution vector.
+C     YPRIME    -- Derivative of solution vector.
+C     NEQ       -- Number of unknowns.
+C     RES       -- External user-supplied subroutine
+C                  to evaluate the residual.  See RES description
+C                  in DDASPK prologue.
+C     PSOL      -- External user-supplied routine to solve
+C                  a linear system using preconditioning. 
+C                  See explanation inside DDASPK.
+C     WT        -- Vector of weights for error criterion.
+C     RPAR,IPAR -- Real and integer arrays used for communication
+C                  between the calling program and external user
+C                  routines.  They are not altered within DASPK.
+C     SAVR      -- Work vector for DNSK of length NEQ.
+C     DELTA     -- Work vector for DNSK of length NEQ.
+C     E         -- Error accumulation vector for DNSK of length NEQ.
+C     WM,IWM    -- Real and integer arrays storing
+C                  matrix information such as the matrix
+C                  of partial derivatives, permutation
+C                  vector, and various other information.
+C     CJ        -- Parameter always proportional to 1/H (step size).
+C     SQRTN     -- Square root of NEQ.
+C     RSQRTN    -- reciprical of square root of NEQ.
+C     EPLIN     -- Tolerance for linear system solver.
+C     EPCON     -- Tolerance to test for convergence of the Newton
+C                  iteration.
+C     S         -- Used for error convergence tests.
+C                  In the Newton iteration: S = RATE/(1.D0-RATE),
+C                  where RATE is the estimated rate of convergence
+C                  of the Newton iteration.
+C
+C                  The closer RATE is to 0., the faster the Newton
+C                  iteration is converging; the closer RATE is to 1.,
+C                  the slower the Newton iteration is converging.
+C
+C                  The calling routine sends the initial value
+C                  of S to the Newton iteration.
+C     CONFAC    -- A residual scale factor to improve convergence.
+C     TOLNEW    -- Tolerance on the norm of Newton correction in
+C                  alternative Newton convergence test.
+C     MULDEL    -- A flag indicating whether or not to multiply
+C                  DELTA by CONFAC.
+C                  0  ==> do not scale DELTA by CONFAC.
+C                  1  ==> scale DELTA by CONFAC.
+C     MAXIT     -- Maximum allowed number of Newton iterations.
+C     IRES      -- Error flag returned from RES.  See RES description
+C                  in DDASPK prologue.  If IRES = -1, then IERNEW
+C                  will be set to 1.
+C                  If IRES < -1, then IERNEW will be set to -1.
+C     IERSL     -- Error flag for linear system solver.
+C                  See IERSL description in subroutine DSLVK.
+C                  If IERSL = 1, then IERNEW will be set to 1.
+C                  If IERSL < 0, then IERNEW will be set to -1.
+C     IERNEW    -- Error flag for Newton iteration.
+C                   0  ==> Newton iteration converged.
+C                   1  ==> recoverable error inside Newton iteration.
+C                  -1  ==> unrecoverable error inside Newton iteration.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED
+C   RES, DSLVK, DDWNRM
+C
+C***END PROLOGUE  DNSK
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION Y(*),YPRIME(*),WT(*),DELTA(*),E(*),SAVR(*)
+      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
+      EXTERNAL  RES, PSOL
+C
+      PARAMETER (LNNI=19, LNRE=12)
+C
+C     Initialize Newton counter M and accumulation vector E.
+C
+      M = 0
+      DO 100 I=1,NEQ
+100     E(I) = 0.0D0
+C
+C     Corrector loop.
+C
+300   CONTINUE
+      IWM(LNNI) = IWM(LNNI) + 1
+C
+C     If necessary, multiply residual by convergence factor.
+C
+      IF (MULDEL .EQ. 1) THEN
+        DO 320 I = 1,NEQ
+320       DELTA(I) = DELTA(I) * CONFAC
+        ENDIF
+C
+C     Save residual in SAVR.
+C
+      DO 340 I = 1,NEQ
+340     SAVR(I) = DELTA(I)
+C
+C     Compute a new iterate.  Store the correction in DELTA.
+C
+      CALL DSLVK (NEQ, Y, X, YPRIME, SAVR, DELTA, WT, WM, IWM,
+     *   RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK,
+     *   RPAR, IPAR)
+      IF (IRES .NE. 0 .OR. IERSL .NE. 0) GO TO 380
+C
+C     Update Y, E, and YPRIME.
+C
+      DO 360 I=1,NEQ
+         Y(I) = Y(I) - DELTA(I)
+         E(I) = E(I) - DELTA(I)
+360      YPRIME(I) = YPRIME(I) - CJ*DELTA(I)
+C
+C     Test for convergence of the iteration.
+C
+      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF (DELNRM .LE. TOLNEW) GO TO 370
+      IF (M .EQ. 0) THEN
+        OLDNRM = DELNRM
+      ELSE
+        RATE = (DELNRM/OLDNRM)**(1.0D0/M)
+        IF (RATE .GT. 0.9D0) GO TO 380
+        S = RATE/(1.0D0 - RATE)
+      ENDIF
+      IF (S*DELNRM .LE. EPCON) GO TO 370
+C
+C     The corrector has not yet converged.  Update M and test whether
+C     the maximum number of iterations have been tried.
+C
+      M = M + 1
+      IF (M .GE. MAXIT) GO TO 380
+C
+C     Evaluate the residual, and go back to do another iteration.
+C
+      IWM(LNRE) = IWM(LNRE) + 1
+      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 380
+      GO TO 300
+C
+C     The iteration has converged.
+C
+370    RETURN
+C
+C     The iteration has not converged.  Set IERNEW appropriately.
+C
+380   CONTINUE
+      IF (IRES .LE. -2 .OR. IERSL .LT. 0) THEN
+         IERNEW = -1
+      ELSE
+         IERNEW = 1
+      ENDIF
+      RETURN
+C
+C
+C------END OF SUBROUTINE DNSK-------------------------------------------
+      END
diff --git a/libcruft/daspk/dorth.f b/libcruft/daspk/dorth.f
new file mode 100644
index 0000000..f1de3f9
--- /dev/null
+++ b/libcruft/daspk/dorth.f
@@ -0,0 +1,101 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DORTH (VNEW, V, HES, N, LL, LDHES, KMP, SNORMW)
+C
+C***BEGIN PROLOGUE  DORTH
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C This routine orthogonalizes the vector VNEW against the previous
+C KMP vectors in the V array.  It uses a modified Gram-Schmidt
+C orthogonalization procedure with conditional reorthogonalization.
+C
+C      On entry
+C
+C         VNEW = The vector of length N containing a scaled product
+C                OF The Jacobian and the vector V(*,LL).
+C
+C         V    = The N x LL array containing the previous LL
+C                orthogonal vectors V(*,1) to V(*,LL).
+C
+C         HES  = An LL x LL upper Hessenberg matrix containing,
+C                in HES(I,K), K.LT.LL, scaled inner products of
+C                A*V(*,K) and V(*,I).
+C
+C        LDHES = The leading dimension of the HES array.
+C
+C         N    = The order of the matrix A, and the length of VNEW.
+C
+C         LL   = The current order of the matrix HES.
+C
+C          KMP = The number of previous vectors the new vector VNEW
+C                must be made orthogonal to (KMP .LE. MAXL).
+C
+C
+C      On return
+C
+C         VNEW = The new vector orthogonal to V(*,I0),
+C                where I0 = MAX(1, LL-KMP+1).
+C
+C         HES  = Upper Hessenberg matrix with column LL filled in with
+C                scaled inner products of A*V(*,LL) and V(*,I).
+C
+C       SNORMW = L-2 norm of VNEW.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   DDOT, DNRM2, DAXPY 
+C
+C***END PROLOGUE  DORTH
+C
+      INTEGER N, LL, LDHES, KMP
+      DOUBLE PRECISION VNEW, V, HES, SNORMW
+      DIMENSION VNEW(*), V(N,*), HES(LDHES,*)
+      INTEGER I, I0
+      DOUBLE PRECISION ARG, DDOT, DNRM2, SUMDSQ, TEM, VNRM
+C
+C-----------------------------------------------------------------------
+C Get norm of unaltered VNEW for later use.
+C-----------------------------------------------------------------------
+      VNRM = DNRM2 (N, VNEW, 1)
+C-----------------------------------------------------------------------
+C Do Modified Gram-Schmidt on VNEW = A*V(LL).
+C Scaled inner products give new column of HES.
+C Projections of earlier vectors are subtracted from VNEW.
+C-----------------------------------------------------------------------
+      I0 = MAX0(1,LL-KMP+1)
+      DO 10 I = I0,LL
+        HES(I,LL) = DDOT (N, V(1,I), 1, VNEW, 1)
+        TEM = -HES(I,LL)
+        CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1)
+ 10     CONTINUE
+C-----------------------------------------------------------------------
+C Compute SNORMW = norm of VNEW.
+C If VNEW is small compared to its input value (in norm), then
+C Reorthogonalize VNEW to V(*,1) through V(*,LL).
+C Correct if relative correction exceeds 1000*(unit roundoff).
+C Finally, correct SNORMW using the dot products involved.
+C-----------------------------------------------------------------------
+      SNORMW = DNRM2 (N, VNEW, 1)
+      IF (VNRM + 0.001D0*SNORMW .NE. VNRM) RETURN
+      SUMDSQ = 0.0D0
+      DO 30 I = I0,LL
+        TEM = -DDOT (N, V(1,I), 1, VNEW, 1)
+        IF (HES(I,LL) + 0.001D0*TEM .EQ. HES(I,LL)) GO TO 30
+        HES(I,LL) = HES(I,LL) - TEM
+        CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1)
+        SUMDSQ = SUMDSQ + TEM**2
+ 30     CONTINUE
+      IF (SUMDSQ .EQ. 0.0D0) RETURN
+      ARG = MAX(0.0D0,SNORMW**2 - SUMDSQ)
+      SNORMW = SQRT(ARG)
+      RETURN
+C
+C------END OF SUBROUTINE DORTH------------------------------------------
+      END
diff --git a/libcruft/daspk/dslvd.f b/libcruft/daspk/dslvd.f
new file mode 100644
index 0000000..1b6f842
--- /dev/null
+++ b/libcruft/daspk/dslvd.f
@@ -0,0 +1,57 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DSLVD(NEQ,DELTA,WM,IWM)
+C
+C***BEGIN PROLOGUE  DSLVD
+C***REFER TO  DDASPK
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  940701   (YYMMDD) (new LIPVT)
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     This routine manages the solution of the linear
+C     system arising in the Newton iteration.
+C     Real matrix information and real temporary storage
+C     is stored in the array WM.
+C     Integer matrix information is stored in the array IWM.
+C     For a dense matrix, the LAPACK routine DGETRS is called.
+C     For a banded matrix, the LAPACK routine DGBTRS is called.
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   DGETRS, DGBTRS
+C
+C***END PROLOGUE  DSLVD
+C
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      DIMENSION DELTA(*),WM(*),IWM(*)
+C
+      PARAMETER (LML=1, LMU=2, LMTYPE=4, LLCIWP=30)
+C
+      LIPVT = IWM(LLCIWP)
+      MTYPE=IWM(LMTYPE)
+      GO TO(100,100,300,400,400),MTYPE
+C
+C     Dense matrix.
+C
+100   CALL DGETRS('N', NEQ, 1, WM, NEQ, IWM(LIPVT), DELTA, NEQ, INLPCK)
+      RETURN
+C
+C     Dummy section for MTYPE=3.
+C
+300   CONTINUE
+      RETURN
+C
+C     Banded matrix.
+C
+400   MEBAND=2*IWM(LML)+IWM(LMU)+1
+      CALL DGBTRS('N', NEQ, IWM(LML), IWM(LMU), 1, WM, MEBAND, 
+     *     IWM(LIPVT), DELTA, NEQ, INLPCK)
+      RETURN
+C
+C------END OF SUBROUTINE DSLVD------------------------------------------
+      END
diff --git a/libcruft/daspk/dslvk.f b/libcruft/daspk/dslvk.f
new file mode 100644
index 0000000..343e8dd
--- /dev/null
+++ b/libcruft/daspk/dslvk.f
@@ -0,0 +1,141 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DSLVK (NEQ, Y, TN, YPRIME, SAVR, X, EWT, WM, IWM,
+     *   RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK,
+     *   RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DSLVK
+C***REFER TO  DDASPK
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  940928   Removed MNEWT and added RHOK in call list.
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C DSLVK uses a restart algorithm and interfaces to DSPIGM for
+C the solution of the linear system arising from a Newton iteration.
+C
+C In addition to variables described elsewhere,
+C communication with DSLVK uses the following variables..
+C WM    = Real work space containing data for the algorithm
+C         (Krylov basis vectors, Hessenberg matrix, etc.).
+C IWM   = Integer work space containing data for the algorithm.
+C X     = The right-hand side vector on input, and the solution vector
+C         on output, of length NEQ.
+C IRES  = Error flag from RES.
+C IERSL = Output flag ..
+C         IERSL =  0 means no trouble occurred (or user RES routine
+C                    returned IRES < 0)
+C         IERSL =  1 means the iterative method failed to converge
+C                    (DSPIGM returned IFLAG > 0.)
+C         IERSL = -1 means there was a nonrecoverable error in the
+C                    iterative solver, and an error exit will occur.
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   DSCAL, DCOPY, DSPIGM
+C
+C***END PROLOGUE  DSLVK
+C
+      INTEGER NEQ, IWM, IRES, IERSL, IPAR
+      DOUBLE PRECISION Y, TN, YPRIME, SAVR, X, EWT, WM, CJ, EPLIN,
+     1   SQRTN, RSQRTN, RHOK, RPAR
+      DIMENSION Y(*), YPRIME(*), SAVR(*), X(*), EWT(*), 
+     1  WM(*), IWM(*), RPAR(*), IPAR(*)
+C
+      INTEGER IFLAG, IRST, NRSTS, NRMAX, LR, LDL, LHES, LGMR, LQ, LV,
+     1        LWK, LZ, MAXLP1, NPSL
+      INTEGER NLI, NPS, NCFL, NRE, MAXL, KMP, MITER
+      EXTERNAL  RES, PSOL
+C    
+      PARAMETER (LNRE=12, LNCFL=16, LNLI=20, LNPS=21) 
+      PARAMETER (LLOCWP=29, LLCIWP=30)
+      PARAMETER (LMITER=23, LMAXL=24, LKMP=25, LNRMAX=26)
+C
+C-----------------------------------------------------------------------
+C IRST is set to 1, to indicate restarting is in effect.
+C NRMAX is the maximum number of restarts.
+C-----------------------------------------------------------------------
+      DATA IRST/1/
+C
+      LIWP = IWM(LLCIWP)
+      NLI = IWM(LNLI)
+      NPS = IWM(LNPS)
+      NCFL = IWM(LNCFL)
+      NRE = IWM(LNRE)
+      LWP = IWM(LLOCWP)
+      MAXL = IWM(LMAXL) 
+      KMP = IWM(LKMP)
+      NRMAX = IWM(LNRMAX) 
+      MITER = IWM(LMITER)
+      IERSL = 0
+      IRES = 0
+C-----------------------------------------------------------------------
+C Use a restarting strategy to solve the linear system
+C P*X = -F.  Parse the work vector, and perform initializations.
+C Note that zero is the initial guess for X.
+C-----------------------------------------------------------------------
+      MAXLP1 = MAXL + 1
+      LV = 1
+      LR = LV + NEQ*MAXL
+      LHES = LR + NEQ + 1
+      LQ = LHES + MAXL*MAXLP1
+      LWK = LQ + 2*MAXL
+      LDL = LWK + MIN0(1,MAXL-KMP)*NEQ
+      LZ = LDL + NEQ
+      CALL DSCAL (NEQ, RSQRTN, EWT, 1)
+      CALL DCOPY (NEQ, X, 1, WM(LR), 1)
+      DO 110 I = 1,NEQ
+ 110     X(I) = 0.D0
+C-----------------------------------------------------------------------
+C Top of loop for the restart algorithm.  Initial pass approximates
+C X and sets up a transformed system to perform subsequent restarts
+C to update X.  NRSTS is initialized to -1, because restarting
+C does not occur until after the first pass.
+C Update NRSTS; conditionally copy DL to R; call the DSPIGM
+C algorithm to solve A*Z = R;  updated counters;  update X with
+C the residual solution.
+C Note:  if convergence is not achieved after NRMAX restarts,
+C then the linear solver is considered to have failed.
+C-----------------------------------------------------------------------
+      NRSTS = -1
+ 115  CONTINUE
+      NRSTS = NRSTS + 1
+      IF (NRSTS .GT. 0) CALL DCOPY (NEQ, WM(LDL), 1, WM(LR),1)
+      CALL DSPIGM (NEQ, TN, Y, YPRIME, SAVR, WM(LR), EWT, MAXL, MAXLP1,
+     1   KMP, EPLIN, CJ, RES, IRES, NRES, PSOL, NPSL, WM(LZ), WM(LV),
+     2   WM(LHES), WM(LQ), LGMR, WM(LWP), IWM(LIWP), WM(LWK),
+     3   WM(LDL), RHOK, IFLAG, IRST, NRSTS, RPAR, IPAR)
+      NLI = NLI + LGMR
+      NPS = NPS + NPSL
+      NRE = NRE + NRES
+      DO 120 I = 1,NEQ
+ 120     X(I) = X(I) + WM(LZ+I-1) 
+      IF ((IFLAG .EQ. 1) .AND. (NRSTS .LT. NRMAX) .AND. (IRES .EQ. 0))
+     1   GO TO 115
+C-----------------------------------------------------------------------
+C The restart scheme is finished.  Test IRES and IFLAG to see if
+C convergence was not achieved, and set flags accordingly.
+C-----------------------------------------------------------------------
+      IF (IRES .LT. 0) THEN
+         NCFL = NCFL + 1
+      ELSE IF (IFLAG .NE. 0) THEN
+         NCFL = NCFL + 1
+         IF (IFLAG .GT. 0) IERSL = 1 
+         IF (IFLAG .LT. 0) IERSL = -1 
+      ENDIF
+C-----------------------------------------------------------------------
+C Update IWM with counters, rescale EWT, and return.
+C-----------------------------------------------------------------------
+      IWM(LNLI)  = NLI
+      IWM(LNPS)  = NPS
+      IWM(LNCFL) = NCFL
+      IWM(LNRE)  = NRE
+      CALL DSCAL (NEQ, SQRTN, EWT, 1)
+      RETURN
+C
+C------END OF SUBROUTINE DSLVK------------------------------------------
+      END
diff --git a/libcruft/daspk/dspigm.f b/libcruft/daspk/dspigm.f
new file mode 100644
index 0000000..d1072d6
--- /dev/null
+++ b/libcruft/daspk/dspigm.f
@@ -0,0 +1,319 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DSPIGM (NEQ, TN, Y, YPRIME, SAVR, R, WGHT, MAXL,
+     *   MAXLP1, KMP, EPLIN, CJ, RES, IRES, NRE, PSOL, NPSL, Z, V,
+     *   HES, Q, LGMR, WP, IWP, WK, DL, RHOK, IFLAG, IRST, NRSTS,
+     *   RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DSPIGM
+C***DATE WRITTEN   890101   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***REVISION DATE  940927   Removed MNEWT and added RHOK in call list.
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C This routine solves the linear system A * Z = R using a scaled
+C preconditioned version of the generalized minimum residual method.
+C An initial guess of Z = 0 is assumed.
+C
+C      On entry
+C
+C          NEQ = Problem size, passed to PSOL.
+C
+C           TN = Current Value of T.
+C
+C            Y = Array Containing current dependent variable vector.
+C
+C       YPRIME = Array Containing current first derivative of Y.
+C
+C         SAVR = Array containing current value of G(T,Y,YPRIME).
+C
+C            R = The right hand side of the system A*Z = R.
+C                R is also used as work space when computing
+C                the final approximation and will therefore be
+C                destroyed.
+C                (R is the same as V(*,MAXL+1) in the call to DSPIGM.)
+C
+C         WGHT = The vector of length NEQ containing the nonzero
+C                elements of the diagonal scaling matrix.
+C
+C         MAXL = The maximum allowable order of the matrix H.
+C
+C       MAXLP1 = MAXL + 1, used for dynamic dimensioning of HES.
+C
+C          KMP = The number of previous vectors the new vector, VNEW,
+C                must be made orthogonal to.  (KMP .LE. MAXL.)
+C
+C        EPLIN = Tolerance on residuals R-A*Z in weighted rms norm.
+C
+C           CJ = Scalar proportional to current value of 
+C                1/(step size H).
+C
+C           WK = Real work array used by routine DATV and PSOL.
+C
+C           DL = Real work array used for calculation of the residual
+C                norm RHO when the method is incomplete (KMP.LT.MAXL)
+C                and/or when using restarting.
+C
+C           WP = Real work array used by preconditioner PSOL.
+C
+C          IWP = Integer work array used by preconditioner PSOL.
+C
+C         IRST = Method flag indicating if restarting is being
+C                performed.  IRST .GT. 0 means restarting is active,
+C                while IRST = 0 means restarting is not being used.
+C
+C        NRSTS = Counter for the number of restarts on the current
+C                call to DSPIGM.  If NRSTS .GT. 0, then the residual
+C                R is already scaled, and so scaling of R is not
+C                necessary.
+C
+C
+C      On Return
+C
+C         Z    = The final computed approximation to the solution
+C                of the system A*Z = R.
+C
+C         LGMR = The number of iterations performed and
+C                the current order of the upper Hessenberg
+C                matrix HES.
+C
+C         NRE  = The number of calls to RES (i.e. DATV)
+C
+C         NPSL = The number of calls to PSOL.
+C
+C         V    = The neq by (LGMR+1) array containing the LGMR
+C                orthogonal vectors V(*,1) to V(*,LGMR).
+C
+C         HES  = The upper triangular factor of the QR decomposition
+C                of the (LGMR+1) by LGMR upper Hessenberg matrix whose
+C                entries are the scaled inner-products of A*V(*,I)
+C                and V(*,K).
+C
+C         Q    = Real array of length 2*MAXL containing the components
+C                of the givens rotations used in the QR decomposition
+C                of HES.  It is loaded in DHEQR and used in DHELS.
+C
+C         IRES = Error flag from RES.
+C
+C           DL = Scaled preconditioned residual, 
+C                (D-inverse)*(P-inverse)*(R-A*Z). Only loaded when
+C                performing restarts of the Krylov iteration.
+C
+C         RHOK = Weighted norm of final preconditioned residual.
+C
+C        IFLAG = Integer error flag..
+C                0 Means convergence in LGMR iterations, LGMR.LE.MAXL.
+C                1 Means the convergence test did not pass in MAXL
+C                  iterations, but the new residual norm (RHO) is
+C                  .LT. the old residual norm (RNRM), and so Z is
+C                  computed.
+C                2 Means the convergence test did not pass in MAXL
+C                  iterations, new residual norm (RHO) .GE. old residual
+C                  norm (RNRM), and the initial guess, Z = 0, is
+C                  returned.
+C                3 Means there was a recoverable error in PSOL
+C                  caused by the preconditioner being out of date.
+C               -1 Means there was an unrecoverable error in PSOL.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED
+C   PSOL, DNRM2, DSCAL, DATV, DORTH, DHEQR, DCOPY, DHELS, DAXPY
+C
+C***END PROLOGUE  DSPIGM
+C
+      INTEGER NEQ,MAXL,MAXLP1,KMP,IRES,NRE,NPSL,LGMR,IWP,
+     1   IFLAG,IRST,NRSTS,IPAR
+      DOUBLE PRECISION TN,Y,YPRIME,SAVR,R,WGHT,EPLIN,CJ,Z,V,HES,Q,WP,WK,
+     1   DL,RHOK,RPAR
+      DIMENSION Y(*), YPRIME(*), SAVR(*), R(*), WGHT(*), Z(*),
+     1   V(NEQ,*), HES(MAXLP1,*), Q(*), WP(*), IWP(*), WK(*), DL(*),
+     2   RPAR(*), IPAR(*)
+      INTEGER I, IER, INFO, IP1, I2, J, K, LL, LLP1
+      DOUBLE PRECISION RNRM,C,DLNRM,PROD,RHO,S,SNORMW,DNRM2,TEM
+      EXTERNAL  RES, PSOL
+C
+      IER = 0
+      IFLAG = 0
+      LGMR = 0
+      NPSL = 0
+      NRE = 0
+C-----------------------------------------------------------------------
+C The initial guess for Z is 0.  The initial residual is therefore
+C the vector R.  Initialize Z to 0.
+C-----------------------------------------------------------------------
+      DO 10 I = 1,NEQ
+ 10     Z(I) = 0.0D0
+C-----------------------------------------------------------------------
+C Apply inverse of left preconditioner to vector R if NRSTS .EQ. 0.
+C Form V(*,1), the scaled preconditioned right hand side.
+C-----------------------------------------------------------------------
+      IF (NRSTS .EQ. 0) THEN
+         CALL PSOL (NEQ, TN, Y, YPRIME, SAVR, WK, CJ, WGHT, WP, IWP,
+     1      R, EPLIN, IER, RPAR, IPAR)
+         NPSL = 1
+         IF (IER .NE. 0) GO TO 300
+         DO 30 I = 1,NEQ
+ 30         V(I,1) = R(I)*WGHT(I)
+      ELSE
+         DO 35 I = 1,NEQ
+ 35         V(I,1) = R(I)
+      ENDIF
+C-----------------------------------------------------------------------
+C Calculate norm of scaled vector V(*,1) and normalize it
+C If, however, the norm of V(*,1) (i.e. the norm of the preconditioned
+C residual) is .le. EPLIN, then return with Z=0.
+C-----------------------------------------------------------------------
+      RNRM = DNRM2 (NEQ, V, 1)
+      IF (RNRM .LE. EPLIN) THEN
+        RHOK = RNRM
+        RETURN
+        ENDIF
+      TEM = 1.0D0/RNRM
+      CALL DSCAL (NEQ, TEM, V(1,1), 1)
+C-----------------------------------------------------------------------
+C Zero out the HES array.
+C-----------------------------------------------------------------------
+      DO 65 J = 1,MAXL
+        DO 60 I = 1,MAXLP1
+ 60       HES(I,J) = 0.0D0
+ 65     CONTINUE
+C-----------------------------------------------------------------------
+C Main loop to compute the vectors V(*,2) to V(*,MAXL).
+C The running product PROD is needed for the convergence test.
+C-----------------------------------------------------------------------
+      PROD = 1.0D0
+      DO 90 LL = 1,MAXL
+        LGMR = LL
+C-----------------------------------------------------------------------
+C Call routine DATV to compute VNEW = ABAR*V(LL), where ABAR is
+C the matrix A with scaling and inverse preconditioner factors applied.
+C Call routine DORTH to orthogonalize the new vector VNEW = V(*,LL+1).
+C call routine DHEQR to update the factors of HES.
+C-----------------------------------------------------------------------
+        CALL DATV (NEQ, Y, TN, YPRIME, SAVR, V(1,LL), WGHT, Z,
+     1     RES, IRES, PSOL, V(1,LL+1), WK, WP, IWP, CJ, EPLIN,
+     1     IER, NRE, NPSL, RPAR, IPAR)
+        IF (IRES .LT. 0) RETURN
+        IF (IER .NE. 0) GO TO 300
+        CALL DORTH (V(1,LL+1), V, HES, NEQ, LL, MAXLP1, KMP, SNORMW)
+        HES(LL+1,LL) = SNORMW
+        CALL DHEQR (HES, MAXLP1, LL, Q, INFO, LL)
+        IF (INFO .EQ. LL) GO TO 120
+C-----------------------------------------------------------------------
+C Update RHO, the estimate of the norm of the residual R - A*ZL.
+C If KMP .LT. MAXL, then the vectors V(*,1),...,V(*,LL+1) are not
+C necessarily orthogonal for LL .GT. KMP.  The vector DL must then
+C be computed, and its norm used in the calculation of RHO.
+C-----------------------------------------------------------------------
+        PROD = PROD*Q(2*LL)
+        RHO = ABS(PROD*RNRM)
+        IF ((LL.GT.KMP) .AND. (KMP.LT.MAXL)) THEN
+          IF (LL .EQ. KMP+1) THEN
+            CALL DCOPY (NEQ, V(1,1), 1, DL, 1)
+            DO 75 I = 1,KMP
+              IP1 = I + 1
+              I2 = I*2
+              S = Q(I2)
+              C = Q(I2-1)
+              DO 70 K = 1,NEQ
+ 70             DL(K) = S*DL(K) + C*V(K,IP1)
+ 75           CONTINUE
+            ENDIF
+          S = Q(2*LL)
+          C = Q(2*LL-1)/SNORMW
+          LLP1 = LL + 1
+          DO 80 K = 1,NEQ
+ 80         DL(K) = S*DL(K) + C*V(K,LLP1)
+          DLNRM = DNRM2 (NEQ, DL, 1)
+          RHO = RHO*DLNRM
+          ENDIF
+C-----------------------------------------------------------------------
+C Test for convergence.  If passed, compute approximation ZL.
+C If failed and LL .LT. MAXL, then continue iterating.
+C-----------------------------------------------------------------------
+        IF (RHO .LE. EPLIN) GO TO 200
+        IF (LL .EQ. MAXL) GO TO 100
+C-----------------------------------------------------------------------
+C Rescale so that the norm of V(1,LL+1) is one.
+C-----------------------------------------------------------------------
+        TEM = 1.0D0/SNORMW
+        CALL DSCAL (NEQ, TEM, V(1,LL+1), 1)
+ 90     CONTINUE
+ 100  CONTINUE
+      IF (RHO .LT. RNRM) GO TO 150
+ 120  CONTINUE
+      IFLAG = 2
+      DO 130 I = 1,NEQ
+ 130     Z(I) = 0.D0
+      RETURN
+ 150  IFLAG = 1
+C-----------------------------------------------------------------------
+C The tolerance was not met, but the residual norm was reduced.
+C If performing restarting (IRST .gt. 0) calculate the residual vector
+C RL and store it in the DL array.  If the incomplete version is 
+C being used (KMP .lt. MAXL) then DL has already been calculated.
+C-----------------------------------------------------------------------
+      IF (IRST .GT. 0) THEN
+         IF (KMP .EQ. MAXL) THEN
+C
+C           Calculate DL from the V(I)'s.
+C
+            CALL DCOPY (NEQ, V(1,1), 1, DL, 1)
+            MAXLM1 = MAXL - 1
+            DO 175 I = 1,MAXLM1
+               IP1 = I + 1
+               I2 = I*2
+               S = Q(I2)
+               C = Q(I2-1)
+               DO 170 K = 1,NEQ
+ 170              DL(K) = S*DL(K) + C*V(K,IP1)
+ 175        CONTINUE
+            S = Q(2*MAXL)
+            C = Q(2*MAXL-1)/SNORMW
+            DO 180 K = 1,NEQ
+ 180           DL(K) = S*DL(K) + C*V(K,MAXLP1)
+         ENDIF
+C
+C        Scale DL by RNRM*PROD to obtain the residual RL.
+C
+         TEM = RNRM*PROD
+         CALL DSCAL(NEQ, TEM, DL, 1)
+      ENDIF
+C-----------------------------------------------------------------------
+C Compute the approximation ZL to the solution.
+C Since the vector Z was used as work space, and the initial guess
+C of the Newton correction is zero, Z must be reset to zero.
+C-----------------------------------------------------------------------
+ 200  CONTINUE
+      LL = LGMR
+      LLP1 = LL + 1
+      DO 210 K = 1,LLP1
+ 210    R(K) = 0.0D0
+      R(1) = RNRM
+      CALL DHELS (HES, MAXLP1, LL, Q, R)
+      DO 220 K = 1,NEQ
+ 220    Z(K) = 0.0D0
+      DO 230 I = 1,LL
+        CALL DAXPY (NEQ, R(I), V(1,I), 1, Z, 1)
+ 230    CONTINUE
+      DO 240 I = 1,NEQ
+ 240    Z(I) = Z(I)/WGHT(I)
+C Load RHO into RHOK.
+      RHOK = RHO
+      RETURN
+C-----------------------------------------------------------------------
+C This block handles error returns forced by routine PSOL.
+C-----------------------------------------------------------------------
+ 300  CONTINUE
+      IF (IER .LT. 0) IFLAG = -1
+      IF (IER .GT. 0) IFLAG = 3
+C
+      RETURN
+C
+C------END OF SUBROUTINE DSPIGM-----------------------------------------
+      END
diff --git a/libcruft/daspk/dyypnw.f b/libcruft/daspk/dyypnw.f
new file mode 100644
index 0000000..9a277e2
--- /dev/null
+++ b/libcruft/daspk/dyypnw.f
@@ -0,0 +1,58 @@
+C Work performed under the auspices of the U.S. Department of Energy
+C by Lawrence Livermore National Laboratory under contract number 
+C W-7405-Eng-48.
+C
+      SUBROUTINE DYYPNW (NEQ, Y, YPRIME, CJ, RL, P, ICOPT, ID, 
+     *                   YNEW, YPNEW)
+C
+C***BEGIN PROLOGUE  DYYPNW
+C***REFER TO  DLINSK
+C***DATE WRITTEN   940830   (YYMMDD)
+C
+C
+C-----------------------------------------------------------------------
+C***DESCRIPTION
+C
+C     DYYPNW calculates the new (Y,YPRIME) pair needed in the
+C     linesearch algorithm based on the current lambda value.  It is
+C     called by DLINSK and DLINSD.  Based on the ICOPT and ID values,
+C     the corresponding entry in Y or YPRIME is updated.
+C
+C     In addition to the parameters described in the calling programs,
+C     the parameters represent
+C
+C     P      -- Array of length NEQ that contains the current
+C               approximate Newton step.
+C     RL     -- Scalar containing the current lambda value.
+C     YNEW   -- Array of length NEQ containing the updated Y vector.
+C     YPNEW  -- Array of length NEQ containing the updated YPRIME
+C               vector.
+C-----------------------------------------------------------------------
+C
+C***ROUTINES CALLED (NONE)
+C
+C***END PROLOGUE  DYYPNW
+C
+C
+      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+      DIMENSION Y(*), YPRIME(*), YNEW(*), YPNEW(*), ID(*), P(*)
+C
+      IF (ICOPT .EQ. 1) THEN
+         DO 10 I=1,NEQ
+            IF(ID(I) .LT. 0) THEN
+               YNEW(I) = Y(I) - RL*P(I)
+               YPNEW(I) = YPRIME(I)
+            ELSE
+               YNEW(I) = Y(I)
+               YPNEW(I) = YPRIME(I) - RL*CJ*P(I)
+            ENDIF
+ 10      CONTINUE
+      ELSE
+         DO 20 I = 1,NEQ
+            YNEW(I) = Y(I) - RL*P(I)
+            YPNEW(I) = YPRIME(I)
+ 20      CONTINUE
+      ENDIF
+      RETURN
+C----------------------- END OF SUBROUTINE DYYPNW ----------------------
+      END
diff --git a/libcruft/dasrt/Makefile.in b/libcruft/dasrt/Makefile.in
new file mode 100644
index 0000000..214967a
--- /dev/null
+++ b/libcruft/dasrt/Makefile.in
@@ -0,0 +1,33 @@
+# Makefile for octave's libcruft/dasrt directory
+#
+# Copyright (C) 2002, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = ddasrt.f drchek.f droots.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/dasrt/ddasrt.f b/libcruft/dasrt/ddasrt.f
new file mode 100644
index 0000000..d9c333d
--- /dev/null
+++ b/libcruft/dasrt/ddasrt.f
@@ -0,0 +1,1559 @@
+      SUBROUTINE DDASRT (RES,NEQ,T,Y,YPRIME,TOUT,
+     *  INFO,RTOL,ATOL,IDID,RWORK,LRW,IWORK,LIW,RPAR,IPAR,JAC,
+     *  G,NG,JROOT)
+C
+C***BEGIN PROLOGUE  DDASRT
+C***DATE WRITTEN   821001   (YYMMDD)
+C***REVISION DATE  910624   (YYMMDD)
+C***KEYWORDS  DIFFERENTIAL/ALGEBRAIC,BACKWARD DIFFERENTIATION FORMULAS
+C             IMPLICIT DIFFERENTIAL SYSTEMS
+C***AUTHOR  PETZOLD,LINDA R.,COMPUTING AND MATHEMATICS RESEARCH DIVISION
+C             LAWRENCE LIVERMORE NATIONAL LABORATORY
+C             L - 316, P.O. Box 808,
+C             LIVERMORE, CA.    94550
+C***PURPOSE  This code solves a system of differential/algebraic
+C            equations of the form F(T,Y,YPRIME) = 0.
+C***DESCRIPTION
+C
+C *Usage:
+C
+C      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+C      EXTERNAL RES, JAC, G
+C      INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR, NG,
+C     *   JROOT(NG)
+C      DOUBLE PRECISION T, Y(NEQ), YPRIME(NEQ), TOUT, RTOL, ATOL,
+C     *   RWORK(LRW), RPAR
+C
+C      CALL DDASRT (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
+C     *   IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
+C
+C
+C
+C *Arguments:
+C
+C  RES:EXT  This is a subroutine which you provide to define the
+C           differential/algebraic system.
+C
+C  NEQ:IN  This is the number of equations to be solved.
+C
+C  T:INOUT  This is the current value of the independent variable.
+C
+C  Y(*):INOUT  This array contains the solution components at T.
+C
+C  YPRIME(*):INOUT  This array contains the derivatives of the solution
+C                   components at T.
+C
+C  TOUT:IN  This is a point at which a solution is desired.
+C
+C  INFO(N):IN  The basic task of the code is to solve the system from T
+C              to TOUT and return an answer at TOUT.  INFO is an integer
+C              array which is used to communicate exactly how you want
+C              this task to be carried out.  N must be greater than or
+C              equal to 15.
+C
+C  RTOL,ATOL:INOUT  These quantities represent absolute and relative
+C                   error tolerances which you provide to indicate how
+C                   accurately you wish the solution to be computed.
+C                   You may choose them to be both scalars or else
+C                   both vectors.
+C
+C  IDID:OUT  This scalar quantity is an indicator reporting what the
+C            code did.  You must monitor this integer variable to decide
+C            what action to take next.
+C
+C  RWORK:WORK  A real work array of length LRW which provides the
+C               code with needed storage space.
+C
+C  LRW:IN  The length of RWORK.
+C
+C  IWORK:WORK  An integer work array of length LIW which probides the
+C               code with needed storage space.
+C
+C  LIW:IN  The length of IWORK.
+C
+C  RPAR,IPAR:IN  These are real and integer parameter arrays which
+C                you can use for communication between your calling
+C                program and the RES subroutine (and the JAC subroutine)
+C
+C  JAC:EXT  This is the name of a subroutine which you may choose to
+C           provide for defining a matrix of partial derivatives
+C           described below.
+C
+C  G  This is the name of the subroutine for defining
+C     constraint functions, G(T,Y), whose roots are desired
+C     during the integration.  This name must be declared
+C     external in the calling program.
+C
+C  NG  This is the number of constraint functions G(I).
+C      If there are none, set NG=0, and pass a dummy name
+C      for G.
+C
+C  JROOT  This is an integer array of length NG for output
+C         of root information.
+C
+C
+C *Description
+C
+C  QUANTITIES WHICH MAY BE ALTERED BY THE CODE ARE
+C     T,Y(*),YPRIME(*),INFO(1),RTOL,ATOL,
+C     IDID,RWORK(*) AND IWORK(*).
+C
+C  Subroutine DDASRT uses the backward differentiation formulas of
+C  orders one through five to solve a system of the above form for Y and
+C  YPRIME.  Values for Y and YPRIME at the initial time must be given as
+C  input.  These values must be consistent, (that is, if T,Y,YPRIME are
+C  the given initial values, they must satisfy F(T,Y,YPRIME) = 0.).  The
+C  subroutine solves the system from T to TOUT.
+C  It is easy to continue the solution to get results at additional
+C  TOUT.  This is the interval mode of operation.  Intermediate results
+C  can also be obtained easily by using the intermediate-output
+C  capability.  If DDASRT detects a sign-change in G(T,Y), then
+C  it will return the intermediate value of T and Y for which
+C  G(T,Y) = 0.
+C
+C  ---------INPUT-WHAT TO DO ON THE FIRST CALL TO DDASRT---------------
+C
+C
+C  The first call of the code is defined to be the start of each new
+C  problem. Read through the descriptions of all the following items,
+C  provide sufficient storage space for designated arrays, set
+C  appropriate variables for the initialization of the problem, and
+C  give information about how you want the problem to be solved.
+C
+C
+C  RES -- Provide a subroutine of the form
+C             SUBROUTINE RES(T,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
+C         to define the system of differential/algebraic
+C         equations which is to be solved. For the given values
+C         of T,Y and YPRIME, the subroutine should
+C         return the residual of the defferential/algebraic
+C         system
+C             DELTA = F(T,Y,YPRIME)
+C         (DELTA(*) is a vector of length NEQ which is
+C         output for RES.)
+C
+C         Subroutine RES must not alter T,Y or YPRIME.
+C         You must declare the name RES in an external
+C         statement in your program that calls DDASRT.
+C         You must dimension Y,YPRIME and DELTA in RES.
+C
+C         IRES is an integer flag which is always equal to
+C         zero on input. Subroutine RES should alter IRES
+C         only if it encounters an illegal value of Y or
+C         a stop condition. Set IRES = -1 if an input value
+C         is illegal, and DDASRT will try to solve the problem
+C         without getting IRES = -1. If IRES = -2, DDASRT
+C         will return control to the calling program
+C         with IDID = -11.
+C
+C         RPAR and IPAR are real and integer parameter arrays which
+C         you can use for communication between your calling program
+C         and subroutine RES. They are not altered by DDASRT. If you
+C         do not need RPAR or IPAR, ignore these parameters by treat-
+C         ing them as dummy arguments. If you do choose to use them,
+C         dimension them in your calling program and in RES as arrays
+C         of appropriate length.
+C
+C  NEQ -- Set it to the number of differential equations.
+C         (NEQ .GE. 1)
+C
+C  T -- Set it to the initial point of the integration.
+C       T must be defined as a variable.
+C
+C  Y(*) -- Set this vector to the initial values of the NEQ solution
+C          components at the initial point. You must dimension Y of
+C          length at least NEQ in your calling program.
+C
+C  YPRIME(*) -- Set this vector to the initial values of
+C               the NEQ first derivatives of the solution
+C               components at the initial point. You
+C               must dimension YPRIME at least NEQ
+C               in your calling program. If you do not
+C               know initial values of some of the solution
+C               components, see the explanation of INFO(11).
+C
+C  TOUT - Set it to the first point at which a solution
+C         is desired. You can not take TOUT = T.
+C         integration either forward in T (TOUT .GT. T) or
+C         backward in T (TOUT .LT. T) is permitted.
+C
+C         The code advances the solution from T to TOUT using
+C         step sizes which are automatically selected so as to
+C         achieve the desired accuracy. If you wish, the code will
+C         return with the solution and its derivative at
+C         intermediate steps (intermediate-output mode) so that
+C         you can monitor them, but you still must provide TOUT in
+C         accord with the basic aim of the code.
+C
+C         the first step taken by the code is a critical one
+C         because it must reflect how fast the solution changes near
+C         the initial point. The code automatically selects an
+C         initial step size which is practically always suitable for
+C         the problem. By using the fact that the code will not step
+C         past TOUT in the first step, you could, if necessary,
+C         restrict the length of the initial step size.
+C
+C         For some problems it may not be permissable to integrate
+C         past a point TSTOP because a discontinuity occurs there
+C         or the solution or its derivative is not defined beyond
+C         TSTOP. When you have declared a TSTOP point (SEE INFO(4)
+C         and RWORK(1)), you have told the code not to integrate
+C         past TSTOP. In this case any TOUT beyond TSTOP is invalid
+C         input.
+C
+C  INFO(*) - Use the INFO array to give the code more details about
+C            how you want your problem solved. This array should be
+C            dimensioned of length 15, though DDASRT uses
+C            only the first twelve entries. You must respond to all of
+C            the following items which are arranged as questions. The
+C            simplest use of the code corresponds to answering all
+C            questions as yes, i.e. setting all entries of INFO to 0.
+C
+C       INFO(1) - This parameter enables the code to initialize
+C              itself. You must set it to indicate the start of every
+C              new problem.
+C
+C          **** Is this the first call for this problem ...
+C                Yes - Set INFO(1) = 0
+C                 No - Not applicable here.
+C                      See below for continuation calls.  ****
+C
+C       INFO(2) - How much accuracy you want of your solution
+C              is specified by the error tolerances RTOL and ATOL.
+C              The simplest use is to take them both to be scalars.
+C              To obtain more flexibility, they can both be vectors.
+C              The code must be told your choice.
+C
+C          **** Are both error tolerances RTOL, ATOL scalars ...
+C                Yes - Set INFO(2) = 0
+C                      and input scalars for both RTOL and ATOL
+C                 No - Set INFO(2) = 1
+C                      and input arrays for both RTOL and ATOL ****
+C
+C       INFO(3) - The code integrates from T in the direction
+C              of TOUT by steps. If you wish, it will return the
+C              computed solution and derivative at the next
+C              intermediate step (the intermediate-output mode) or
+C              TOUT, whichever comes first. This is a good way to
+C              proceed if you want to see the behavior of the solution.
+C              If you must have solutions at a great many specific
+C              TOUT points, this code will compute them efficiently.
+C
+C          **** Do you want the solution only at
+C                TOUT (and not at the next intermediate step) ...
+C                 Yes - Set INFO(3) = 0
+C                  No - Set INFO(3) = 1 ****
+C
+C       INFO(4) - To handle solutions at a great many specific
+C              values TOUT efficiently, this code may integrate past
+C              TOUT and interpolate to obtain the result at TOUT.
+C              Sometimes it is not possible to integrate beyond some
+C              point TSTOP because the equation changes there or it is
+C              not defined past TSTOP. Then you must tell the code
+C              not to go past.
+C
+C           **** Can the integration be carried out without any
+C                restrictions on the independent variable T ...
+C                 Yes - Set INFO(4)=0
+C                  No - Set INFO(4)=1
+C                       and define the stopping point TSTOP by
+C                       setting RWORK(1)=TSTOP ****
+C
+C       INFO(5) - To solve differential/algebraic problems it is
+C              necessary to use a matrix of partial derivatives of the
+C              system of differential equations. If you do not
+C              provide a subroutine to evaluate it analytically (see
+C              description of the item JAC in the call list), it will
+C              be approximated by numerical differencing in this code.
+C              although it is less trouble for you to have the code
+C              compute partial derivatives by numerical differencing,
+C              the solution will be more reliable if you provide the
+C              derivatives via JAC. Sometimes numerical differencing
+C              is cheaper than evaluating derivatives in JAC and
+C              sometimes it is not - this depends on your problem.
+C
+C           **** Do you want the code to evaluate the partial
+C                derivatives automatically by numerical differences ...
+C                   Yes - Set INFO(5)=0
+C                    No - Set INFO(5)=1
+C                  and provide subroutine JAC for evaluating the
+C                  matrix of partial derivatives ****
+C
+C       INFO(6) - DDASRT will perform much better if the matrix of
+C              partial derivatives, DG/DY + CJ*DG/DYPRIME,
+C              (here CJ is a scalar determined by DDASRT)
+C              is banded and the code is told this. In this
+C              case, the storage needed will be greatly reduced,
+C              numerical differencing will be performed much cheaper,
+C              and a number of important algorithms will execute much
+C              faster. The differential equation is said to have
+C              half-bandwidths ML (lower) and MU (upper) if equation i
+C              involves only unknowns Y(J) with
+C                             I-ML .LE. J .LE. I+MU
+C              for all I=1,2,...,NEQ. Thus, ML and MU are the widths
+C              of the lower and upper parts of the band, respectively,
+C              with the main diagonal being excluded. If you do not
+C              indicate that the equation has a banded matrix of partial
+C              derivatives, the code works with a full matrix of NEQ**2
+C              elements (stored in the conventional way). Computations
+C              with banded matrices cost less time and storage than with
+C              full matrices if 2*ML+MU .LT. NEQ. If you tell the
+C              code that the matrix of partial derivatives has a banded
+C              structure and you want to provide subroutine JAC to
+C              compute the partial derivatives, then you must be careful
+C              to store the elements of the matrix in the special form
+C              indicated in the description of JAC.
+C
+C          **** Do you want to solve the problem using a full
+C               (dense) matrix (and not a special banded
+C               structure) ...
+C                Yes - Set INFO(6)=0
+C                 No - Set INFO(6)=1
+C                       and provide the lower (ML) and upper (MU)
+C                       bandwidths by setting
+C                       IWORK(1)=ML
+C                       IWORK(2)=MU ****
+C
+C
+C        INFO(7) -- You can specify a maximum (absolute value of)
+C              stepsize, so that the code
+C              will avoid passing over very
+C              large regions.
+C
+C          ****  Do you want the code to decide
+C                on its own maximum stepsize?
+C                Yes - Set INFO(7)=0
+C                 No - Set INFO(7)=1
+C                      and define HMAX by setting
+C                      RWORK(2)=HMAX ****
+C
+C        INFO(8) -- Differential/algebraic problems
+C              may occaisionally suffer from
+C              severe scaling difficulties on the
+C              first step. If you know a great deal
+C              about the scaling of your problem, you can
+C              help to alleviate this problem by
+C              specifying an initial stepsize H0.
+C
+C          ****  Do you want the code to define
+C                its own initial stepsize?
+C                Yes - Set INFO(8)=0
+C                 No - Set INFO(8)=1
+C                      and define H0 by setting
+C                      RWORK(3)=H0 ****
+C
+C        INFO(9) -- If storage is a severe problem,
+C              you can save some locations by
+C              restricting the maximum order MAXORD.
+C              the default value is 5. for each
+C              order decrease below 5, the code
+C              requires NEQ fewer locations, however
+C              it is likely to be slower. In any
+C              case, you must have 1 .LE. MAXORD .LE. 5
+C          ****  Do you want the maximum order to
+C                default to 5?
+C                Yes - Set INFO(9)=0
+C                 No - Set INFO(9)=1
+C                      and define MAXORD by setting
+C                      IWORK(3)=MAXORD ****
+C
+C        INFO(10) --If you know that the solutions to your equations
+C               will always be nonnegative, it may help to set this
+C               parameter. However, it is probably best to
+C               try the code without using this option first,
+C               and only to use this option if that doesn't
+C               work very well.
+C           ****  Do you want the code to solve the problem without
+C                 invoking any special nonnegativity constraints?
+C                  Yes - Set INFO(10)=0
+C                   No - Set INFO(10)=1
+C
+C        INFO(11) --DDASRT normally requires the initial T,
+C               Y, and YPRIME to be consistent. That is,
+C               you must have F(T,Y,YPRIME) = 0 at the initial
+C               time. If you do not know the initial
+C               derivative precisely, you can let DDASRT try
+C               to compute it.
+C          ****   Are the initial T, Y, YPRIME consistent?
+C                 Yes - Set INFO(11) = 0
+C                  No - Set INFO(11) = 1,
+C                       and set YPRIME to an initial approximation
+C                       to YPRIME.  (If you have no idea what
+C                       YPRIME should be, set it to zero. Note
+C                       that the initial Y should be such
+C                       that there must exist a YPRIME so that
+C                       F(T,Y,YPRIME) = 0.)
+C
+C        INFO(12) --Maximum number of steps.
+C          ****   Do you want to let DDASRT use the default limit for
+C                 the number of steps?
+C                 Yes - Set INFO(12) = 0
+C                  No - Set INFO(12) = 1,
+C                       and define the maximum number of steps
+C                       by setting IWORK(21)=MXSTEP
+C
+C   RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL
+C               error tolerances to tell the code how accurately you
+C               want the solution to be computed. They must be defined
+C               as variables because the code may change them. You
+C               have two choices --
+C                     Both RTOL and ATOL are scalars. (INFO(2)=0)
+C                     Both RTOL and ATOL are vectors. (INFO(2)=1)
+C               in either case all components must be non-negative.
+C
+C               The tolerances are used by the code in a local error
+C               test at each step which requires roughly that
+C                     ABS(LOCAL ERROR) .LE. RTOL*ABS(Y)+ATOL
+C               for each vector component.
+C               (More specifically, a root-mean-square norm is used to
+C               measure the size of vectors, and the error test uses the
+C               magnitude of the solution at the beginning of the step.)
+C
+C               The true (global) error is the difference between the
+C               true solution of the initial value problem and the
+C               computed approximation. Practically all present day
+C               codes, including this one, control the local error at
+C               each step and do not even attempt to control the global
+C               error directly.
+C               Usually, but not always, the true accuracy of the
+C               computed Y is comparable to the error tolerances. This
+C               code will usually, but not always, deliver a more
+C               accurate solution if you reduce the tolerances and
+C               integrate again. By comparing two such solutions you
+C               can get a fairly reliable idea of the true error in the
+C               solution at the bigger tolerances.
+C
+C               Setting ATOL=0. results in a pure relative error test on
+C               that component. Setting RTOL=0. results in a pure
+C               absolute error test on that component. A mixed test
+C               with non-zero RTOL and ATOL corresponds roughly to a
+C               relative error test when the solution component is much
+C               bigger than ATOL and to an absolute error test when the
+C               solution component is smaller than the threshhold ATOL.
+C
+C               The code will not attempt to compute a solution at an
+C               accuracy unreasonable for the machine being used. It
+C               will advise you if you ask for too much accuracy and
+C               inform you as to the maximum accuracy it believes
+C               possible.
+C
+C  RWORK(*) --  Dimension this real work array of length LRW in your
+C               calling program.
+C
+C  LRW -- Set it to the declared length of the RWORK array.
+C               You must have
+C                    LRW .GE. 50+(MAXORD+4)*NEQ+NEQ**2+3*NG
+C               for the full (dense) JACOBIAN case (when INFO(6)=0), or
+C                    LRW .GE. 50+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ+3*NG
+C               for the banded user-defined JACOBIAN case
+C               (when INFO(5)=1 and INFO(6)=1), or
+C                     LRW .GE. 50+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
+C                           +2*(NEQ/(ML+MU+1)+1)+3*NG
+C               for the banded finite-difference-generated JACOBIAN case
+C               (when INFO(5)=0 and INFO(6)=1)
+C
+C  IWORK(*) --  Dimension this integer work array of length LIW in
+C               your calling program.
+C
+C  LIW -- Set it to the declared length of the IWORK array.
+C               you must have LIW .GE. 21+NEQ
+C
+C  RPAR, IPAR -- These are parameter arrays, of real and integer
+C               type, respectively. You can use them for communication
+C               between your program that calls DDASRT and the
+C               RES subroutine (and the JAC subroutine). They are not
+C               altered by DDASRT. If you do not need RPAR or IPAR,
+C               ignore these parameters by treating them as dummy
+C               arguments. If you do choose to use them, dimension
+C               them in your calling program and in RES (and in JAC)
+C               as arrays of appropriate length.
+C
+C  JAC -- If you have set INFO(5)=0, you can ignore this parameter
+C               by treating it as a dummy argument. Otherwise, you must
+C               provide a subroutine of the form
+C               JAC(T,Y,YPRIME,PD,CJ,RPAR,IPAR)
+C               to define the matrix of partial derivatives
+C               PD=DG/DY+CJ*DG/DYPRIME
+C               CJ is a scalar which is input to JAC.
+C               For the given values of T,Y,YPRIME, the
+C               subroutine must evaluate the non-zero partial
+C               derivatives for each equation and each solution
+C               component, and store these values in the
+C               matrix PD. The elements of PD are set to zero
+C               before each call to JAC so only non-zero elements
+C               need to be defined.
+C
+C               Subroutine JAC must not alter T,Y,(*),YPRIME(*), or CJ.
+C               You must declare the name JAC in an
+C               EXTERNAL STATEMENT in your program that calls
+C               DDASRT. You must dimension Y, YPRIME and PD
+C               in JAC.
+C
+C               The way you must store the elements into the PD matrix
+C               depends on the structure of the matrix which you
+C               indicated by INFO(6).
+C               *** INFO(6)=0 -- Full (dense) matrix ***
+C                   Give PD a first dimension of NEQ.
+C                   When you evaluate the (non-zero) partial derivative
+C                   of equation I with respect to variable J, you must
+C                   store it in PD according to
+C                   PD(I,J) = * DF(I)/DY(J)+CJ*DF(I)/DYPRIME(J)*
+C               *** INFO(6)=1 -- Banded JACOBIAN with ML lower and MU
+C                   upper diagonal bands (refer to INFO(6) description
+C                   of ML and MU) ***
+C                   Give PD a first dimension of 2*ML+MU+1.
+C                   when you evaluate the (non-zero) partial derivative
+C                   of equation I with respect to variable J, you must
+C                   store it in PD according to
+C                   IROW = I - J + ML + MU + 1
+C                   PD(IROW,J) = *DF(I)/DY(J)+CJ*DF(I)/DYPRIME(J)*
+C               RPAR and IPAR are real and integer parameter arrays
+C               which you can use for communication between your calling
+C               program and your JACOBIAN subroutine JAC. They are not
+C               altered by DDASRT. If you do not need RPAR or IPAR,
+C               ignore these parameters by treating them as dummy
+C               arguments. If you do choose to use them, dimension
+C               them in your calling program and in JAC as arrays of
+C               appropriate length.
+C
+C  G -- This is the name of the subroutine for defining constraint
+C               functions, whose roots are desired during the
+C               integration.  It is to have the form
+C                   SUBROUTINE G(NEQ,T,Y,NG,GOUT,RPAR,IPAR)
+C                   DIMENSION Y(NEQ),GOUT(NG),
+C               where NEQ, T, Y and NG are INPUT, and the array GOUT is
+C               output.  NEQ, T, and Y have the same meaning as in the
+C               RES routine, and GOUT is an array of length NG.
+C               For I=1,...,NG, this routine is to load into GOUT(I)
+C               the value at (T,Y) of the I-th constraint function G(I).
+C               DDASRT will find roots of the G(I) of odd multiplicity
+C               (that is, sign changes) as they occur during
+C               the integration.  G must be declared EXTERNAL in the
+C               calling program.
+C
+C               CAUTION..because of numerical errors in the functions
+C               G(I) due to roundoff and integration error, DDASRT
+C               may return false roots, or return the same root at two
+C               or more nearly equal values of T.  If such false roots
+C               are suspected, the user should consider smaller error
+C               tolerances and/or higher precision in the evaluation of
+C               the G(I).
+C
+C               If a root of some G(I) defines the end of the problem,
+C               the input to DDASRT should nevertheless allow
+C               integration to a point slightly past that ROOT, so
+C               that DDASRT can locate the root by interpolation.
+C
+C  NG -- The number of constraint functions G(I).  If there are none,
+C               set NG = 0, and pass a dummy name for G.
+C
+C JROOT -- This is an integer array of length NG.  It is used only for
+C               output.  On a return where one or more roots have been
+C               found, JROOT(I)=1 If G(I) has a root at T,
+C               or JROOT(I)=0 if not.
+C
+C
+C
+C  OPTIONALLY REPLACEABLE NORM ROUTINE:
+C  DDASRT uses a weighted norm DDANRM to measure the size
+C  of vectors such as the estimated error in each step.
+C  A FUNCTION subprogram
+C    DOUBLE PRECISION FUNCTION DDANRM(NEQ,V,WT,RPAR,IPAR)
+C    DIMENSION V(NEQ),WT(NEQ)
+C  is used to define this norm. Here, V is the vector
+C  whose norm is to be computed, and WT is a vector of
+C  weights.  A DDANRM routine has been included with DDASRT
+C  which computes the weighted root-mean-square norm
+C  given by
+C    DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
+C  this norm is suitable for most problems. In some
+C  special cases, it may be more convenient and/or
+C  efficient to define your own norm by writing a function
+C  subprogram to be called instead of DDANRM. This should
+C  ,however, be attempted only after careful thought and
+C  consideration.
+C
+C
+C------OUTPUT-AFTER ANY RETURN FROM DDASRT----
+C
+C  The principal aim of the code is to return a computed solution at
+C  TOUT, although it is also possible to obtain intermediate results
+C  along the way. To find out whether the code achieved its goal
+C  or if the integration process was interrupted before the task was
+C  completed, you must check the IDID parameter.
+C
+C
+C   T -- The solution was successfully advanced to the
+C               output value of T.
+C
+C   Y(*) -- Contains the computed solution approximation at T.
+C
+C   YPRIME(*) -- Contains the computed derivative
+C               approximation at T.
+C
+C   IDID -- Reports what the code did.
+C
+C                     *** Task completed ***
+C                Reported by positive values of IDID
+C
+C           IDID = 1 -- A step was successfully taken in the
+C                   intermediate-output mode. The code has not
+C                   yet reached TOUT.
+C
+C           IDID = 2 -- The integration to TSTOP was successfully
+C                   completed (T=TSTOP) by stepping exactly to TSTOP.
+C
+C           IDID = 3 -- The integration to TOUT was successfully
+C                   completed (T=TOUT) by stepping past TOUT.
+C                   Y(*) is obtained by interpolation.
+C                   YPRIME(*) is obtained by interpolation.
+C
+C           IDID = 4 -- The integration was successfully completed
+C                   by finding one or more roots of G at T.
+C
+C                    *** Task interrupted ***
+C                Reported by negative values of IDID
+C
+C           IDID = -1 -- A large amount of work has been expended.
+C                   (About INFO(12) steps)
+C
+C           IDID = -2 -- The error tolerances are too stringent.
+C
+C           IDID = -3 -- The local error test cannot be satisfied
+C                   because you specified a zero component in ATOL
+C                   and the corresponding computed solution
+C                   component is zero. Thus, a pure relative error
+C                   test is impossible for this component.
+C
+C           IDID = -6 -- DDASRT had repeated error test
+C                   failures on the last attempted step.
+C
+C           IDID = -7 -- The corrector could not converge.
+C
+C           IDID = -8 -- The matrix of partial derivatives
+C                   is singular.
+C
+C           IDID = -9 -- The corrector could not converge.
+C                   there were repeated error test failures
+C                   in this step.
+C
+C           IDID =-10 -- The corrector could not converge
+C                   because IRES was equal to minus one.
+C
+C           IDID =-11 -- IRES equal to -2 was encountered
+C                   and control is being returned to the
+C                   calling program.
+C
+C           IDID =-12 -- DDASRT failed to compute the initial
+C                   YPRIME.
+C
+C
+C
+C           IDID = -13,..,-32 -- Not applicable for this code
+C
+C                    *** Task terminated ***
+C                Reported by the value of IDID=-33
+C
+C           IDID = -33 -- The code has encountered trouble from which
+C                   it cannot recover. A message is printed
+C                   explaining the trouble and control is returned
+C                   to the calling program. For example, this occurs
+C                   when invalid input is detected.
+C
+C   RTOL, ATOL -- These quantities remain unchanged except when
+C               IDID = -2. In this case, the error tolerances have been
+C               increased by the code to values which are estimated to
+C               be appropriate for continuing the integration. However,
+C               the reported solution at T was obtained using the input
+C               values of RTOL and ATOL.
+C
+C   RWORK, IWORK -- Contain information which is usually of no
+C               interest to the user but necessary for subsequent calls.
+C               However, you may find use for
+C
+C               RWORK(3)--Which contains the step size H to be
+C                       attempted on the next step.
+C
+C               RWORK(4)--Which contains the current value of the
+C                       independent variable, i.e., the farthest point
+C                       integration has reached. This will be different
+C                       from T only when interpolation has been
+C                       performed (IDID=3).
+C
+C               RWORK(7)--Which contains the stepsize used
+C                       on the last successful step.
+C
+C               IWORK(7)--Which contains the order of the method to
+C                       be attempted on the next step.
+C
+C               IWORK(8)--Which contains the order of the method used
+C                       on the last step.
+C
+C               IWORK(11)--Which contains the number of steps taken so
+C                        far.
+C
+C               IWORK(12)--Which contains the number of calls to RES
+C                        so far.
+C
+C               IWORK(13)--Which contains the number of evaluations of
+C                        the matrix of partial derivatives needed so
+C                        far.
+C
+C               IWORK(14)--Which contains the total number
+C                        of error test failures so far.
+C
+C               IWORK(15)--Which contains the total number
+C                        of convergence test failures so far.
+C                        (includes singular iteration matrix
+C                        failures.)
+C
+C               IWORK(16)--Which contains the total number of calls
+C                        to the constraint function g so far
+C
+C
+C
+C   INPUT -- What to do to continue the integration
+C            (calls after the first)                **
+C
+C     This code is organized so that subsequent calls to continue the
+C     integration involve little (if any) additional effort on your
+C     part. You must monitor the IDID parameter in order to determine
+C     what to do next.
+C
+C     Recalling that the principal task of the code is to integrate
+C     from T to TOUT (the interval mode), usually all you will need
+C     to do is specify a new TOUT upon reaching the current TOUT.
+C
+C     Do not alter any quantity not specifically permitted below,
+C     in particular do not alter NEQ,T,Y(*),YPRIME(*),RWORK(*),IWORK(*)
+C     or the differential equation in subroutine RES. Any such
+C     alteration constitutes a new problem and must be treated as such,
+C     i.e., you must start afresh.
+C
+C     You cannot change from vector to scalar error control or vice
+C     versa (INFO(2)), but you can change the size of the entries of
+C     RTOL, ATOL. Increasing a tolerance makes the equation easier
+C     to integrate. Decreasing a tolerance will make the equation
+C     harder to integrate and should generally be avoided.
+C
+C     You can switch from the intermediate-output mode to the
+C     interval mode (INFO(3)) or vice versa at any time.
+C
+C     If it has been necessary to prevent the integration from going
+C     past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
+C     code will not integrate to any TOUT beyond the currently
+C     specified TSTOP. Once TSTOP has been reached you must change
+C     the value of TSTOP or set INFO(4)=0. You may change INFO(4)
+C     or TSTOP at any time but you must supply the value of TSTOP in
+C     RWORK(1) whenever you set INFO(4)=1.
+C
+C     Do not change INFO(5), INFO(6), IWORK(1), or IWORK(2)
+C     unless you are going to restart the code.
+C
+C                    *** Following a completed task ***
+C     If
+C     IDID = 1, call the code again to continue the integration
+C                  another step in the direction of TOUT.
+C
+C     IDID = 2 or 3, define a new TOUT and call the code again.
+C                  TOUT must be different from T. You cannot change
+C                  the direction of integration without restarting.
+C
+C     IDID = 4, call the code again to continue the integration
+C                  another step in the direction of TOUT.  You may
+C                  change the functions in G after a return with IDID=4,
+C                  but the number of constraint functions NG must remain
+C                  the same.  If you wish to change
+C                  the functions in RES or in G, then you
+C                  must restart the code.
+C
+C                    *** Following an interrupted task ***
+C                  To show the code that you realize the task was
+C                  interrupted and that you want to continue, you
+C                  must take appropriate action and set INFO(1) = 1
+C     If
+C     IDID = -1, The code has reached the step iteration.
+C                  If you want to continue, set INFO(1) = 1 and
+C                  call the code again.  See also INFO(12).
+C
+C     IDID = -2, The error tolerances RTOL, ATOL have been
+C                  increased to values the code estimates appropriate
+C                  for continuing. You may want to change them
+C                  yourself. If you are sure you want to continue
+C                  with relaxed error tolerances, set INFO(1)=1 and
+C                  call the code again.
+C
+C     IDID = -3, A solution component is zero and you set the
+C                  corresponding component of ATOL to zero. If you
+C                  are sure you want to continue, you must first
+C                  alter the error criterion to use positive values
+C                  for those components of ATOL corresponding to zero
+C                  solution components, then set INFO(1)=1 and call
+C                  the code again.
+C
+C     IDID = -4,-5  --- Cannot occur with this code.
+C
+C     IDID = -6, Repeated error test failures occurred on the
+C                  last attempted step in DDASRT. A singularity in the
+C                  solution may be present. If you are absolutely
+C                  certain you want to continue, you should restart
+C                  the integration. (Provide initial values of Y and
+C                  YPRIME which are consistent)
+C
+C     IDID = -7, Repeated convergence test failures occurred
+C                  on the last attempted step in DDASRT. An inaccurate
+C                  or ill-conditioned JACOBIAN may be the problem. If
+C                  you are absolutely certain you want to continue, you
+C                  should restart the integration.
+C
+C     IDID = -8, The matrix of partial derivatives is singular.
+C                  Some of your equations may be redundant.
+C                  DDASRT cannot solve the problem as stated.
+C                  It is possible that the redundant equations
+C                  could be removed, and then DDASRT could
+C                  solve the problem. It is also possible
+C                  that a solution to your problem either
+C                  does not exist or is not unique.
+C
+C     IDID = -9, DDASRT had multiple convergence test
+C                  failures, preceeded by multiple error
+C                  test failures, on the last attempted step.
+C                  It is possible that your problem
+C                  is ill-posed, and cannot be solved
+C                  using this code. Or, there may be a
+C                  discontinuity or a singularity in the
+C                  solution. If you are absolutely certain
+C                  you want to continue, you should restart
+C                  the integration.
+C
+C    IDID =-10, DDASRT had multiple convergence test failures
+C                  because IRES was equal to minus one.
+C                  If you are absolutely certain you want
+C                  to continue, you should restart the
+C                  integration.
+C
+C    IDID =-11, IRES=-2 was encountered, and control is being
+C                  returned to the calling program.
+C
+C    IDID =-12, DDASRT failed to compute the initial YPRIME.
+C               This could happen because the initial
+C               approximation to YPRIME was not very good, or
+C               if a YPRIME consistent with the initial Y
+C               does not exist. The problem could also be caused
+C               by an inaccurate or singular iteration matrix.
+C
+C
+C
+C     IDID = -13,..,-32 --- Cannot occur with this code.
+C
+C                       *** Following a terminated task ***
+C     If IDID= -33, you cannot continue the solution of this
+C                  problem. An attempt to do so will result in your
+C                  run being terminated.
+C
+C  ---------------------------------------------------------------------
+C
+C***REFERENCE
+C      K. E. Brenan, S. L. Campbell, and L. R. Petzold, Numerical 
+C      Solution of Initial-Value Problems in Differential-Algebraic
+C      Equations, Elsevier, New York, 1989.
+C
+C***ROUTINES CALLED  DDASTP,DDAINI,DDANRM,DDAWTS,DDATRP,DRCHEK,DROOTS,
+C                    XERRWD,D1MACH
+C***END PROLOGUE  DDASRT
+C
+C**End
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      LOGICAL DONE
+      EXTERNAL RES, JAC, G
+      DIMENSION Y(*),YPRIME(*)
+      DIMENSION INFO(15)
+      DIMENSION RWORK(*),IWORK(*)
+      DIMENSION RTOL(*),ATOL(*)
+      DIMENSION RPAR(*),IPAR(*)
+      CHARACTER MSG*80
+C
+C     SET POINTERS INTO IWORK
+      PARAMETER (LML=1, LMU=2, LMXORD=3, LMTYPE=4, LNST=11,
+     *  LNRE=12, LNJE=13, LETF=14, LCTF=15, LNGE=16, LNPD=17,
+     *  LIRFND=18, LMXSTP=21, LIPVT=22, LJCALC=5, LPHASE=6, LK=7,
+     *  LKOLD=8, LNS=9, LNSTL=10, LIWM=1)
+C
+C     SET RELATIVE OFFSET INTO RWORK
+      PARAMETER (NPD=1)
+C
+C     SET POINTERS INTO RWORK
+      PARAMETER (LTSTOP=1, LHMAX=2, LH=3, LTN=4,
+     *  LCJ=5, LCJOLD=6, LHOLD=7, LS=8, LROUND=9,
+     *  LALPHA=11, LBETA=17, LGAMMA=23,
+     *  LPSI=29, LSIGMA=35, LT0=41, LTLAST=42, LALPHR=43, LX2=44,
+     *  LDELTA=51)
+C
+C***FIRST EXECUTABLE STATEMENT  DDASRT
+      IF(INFO(1).NE.0)GO TO 100
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS EXECUTED FOR THE INITIAL CALL ONLY.
+C     IT CONTAINS CHECKING OF INPUTS AND INITIALIZATIONS.
+C-----------------------------------------------------------------------
+C
+C     FIRST CHECK INFO ARRAY TO MAKE SURE ALL ELEMENTS OF INFO
+C     ARE EITHER ZERO OR ONE.
+      DO 10 I=2,12
+         IF(INFO(I).NE.0.AND.INFO(I).NE.1)GO TO 701
+10       CONTINUE
+C
+      IF(NEQ.LE.0)GO TO 702
+C
+C     CHECK AND COMPUTE MAXIMUM ORDER
+      MXORD=5
+      IF(INFO(9).EQ.0)GO TO 20
+         MXORD=IWORK(LMXORD)
+         IF(MXORD.LT.1.OR.MXORD.GT.5)GO TO 703
+20       IWORK(LMXORD)=MXORD
+C
+C     COMPUTE MTYPE,LENPD,LENRW.CHECK ML AND MU.
+      IF(INFO(6).NE.0)GO TO 40
+         LENPD=NEQ**2
+         LENRW=50+(IWORK(LMXORD)+4)*NEQ+LENPD+3*NG
+         IF(INFO(5).NE.0)GO TO 30
+            IWORK(LMTYPE)=2
+            GO TO 60
+30          IWORK(LMTYPE)=1
+            GO TO 60
+40    IF(IWORK(LML).LT.0.OR.IWORK(LML).GE.NEQ)GO TO 717
+      IF(IWORK(LMU).LT.0.OR.IWORK(LMU).GE.NEQ)GO TO 718
+      LENPD=(2*IWORK(LML)+IWORK(LMU)+1)*NEQ
+      IF(INFO(5).NE.0)GO TO 50
+         IWORK(LMTYPE)=5
+         MBAND=IWORK(LML)+IWORK(LMU)+1
+         MSAVE=(NEQ/MBAND)+1
+         LENRW=50+(IWORK(LMXORD)+4)*NEQ+LENPD+2*MSAVE+3*NG
+         GO TO 60
+50       IWORK(LMTYPE)=4
+         LENRW=50+(IWORK(LMXORD)+4)*NEQ+LENPD+3*NG
+C
+C     CHECK LENGTHS OF RWORK AND IWORK
+60    LENIW=21+NEQ
+      IWORK(LNPD)=LENPD
+      IF(LRW.LT.LENRW)GO TO 704
+      IF(LIW.LT.LENIW)GO TO 705
+C
+C     CHECK TO SEE THAT TOUT IS DIFFERENT FROM T
+C     Also check to see that NG is larger than 0.
+      IF(TOUT .EQ. T)GO TO 719
+      IF(NG .LT. 0) GO TO 730
+C
+C     CHECK HMAX
+      IF(INFO(7).EQ.0)GO TO 70
+         HMAX=RWORK(LHMAX)
+         IF(HMAX.LE.0.0D0)GO TO 710
+70    CONTINUE
+C
+C     CHECK AND COMPUTE MAXIMUM STEPS
+      MXSTP=500
+      IF(INFO(12).EQ.0)GO TO 80
+        MXSTP=IWORK(LMXSTP)
+        IF(MXSTP.LT.0)GO TO 716
+80      IWORK(LMXSTP)=MXSTP
+C
+C     INITIALIZE COUNTERS
+      IWORK(LNST)=0
+      IWORK(LNRE)=0
+      IWORK(LNJE)=0
+      IWORK(LNGE)=0
+C
+      IWORK(LNSTL)=0
+      IDID=1
+      GO TO 200
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS FOR CONTINUATION CALLS
+C     ONLY. HERE WE CHECK INFO(1),AND IF THE
+C     LAST STEP WAS INTERRUPTED WE CHECK WHETHER
+C     APPROPRIATE ACTION WAS TAKEN.
+C-----------------------------------------------------------------------
+C
+100   CONTINUE
+      IF(INFO(1).EQ.1)GO TO 110
+      IF(INFO(1).NE.-1)GO TO 701
+C     IF WE ARE HERE, THE LAST STEP WAS INTERRUPTED
+C     BY AN ERROR CONDITION FROM DDASTP,AND
+C     APPROPRIATE ACTION WAS NOT TAKEN. THIS
+C     IS A FATAL ERROR.
+      MSG = 'DASRT--  THE LAST STEP TERMINATED WITH A NEGATIVE'
+      CALL XERRWD(MSG,49,201,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASRT--  VALUE (=I1) OF IDID AND NO APPROPRIATE'
+      CALL XERRWD(MSG,47,202,0,1,IDID,0,0,0.0D0,0.0D0)
+      MSG = 'DASRT--  ACTION WAS TAKEN. RUN TERMINATED'
+      CALL XERRWD(MSG,41,203,1,0,0,0,0,0.0D0,0.0D0)
+      RETURN
+110   CONTINUE
+      IWORK(LNSTL)=IWORK(LNST)
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS EXECUTED ON ALL CALLS.
+C     THE ERROR TOLERANCE PARAMETERS ARE
+C     CHECKED, AND THE WORK ARRAY POINTERS
+C     ARE SET.
+C-----------------------------------------------------------------------
+C
+200   CONTINUE
+C     CHECK RTOL,ATOL
+      NZFLG=0
+      RTOLI=RTOL(1)
+      ATOLI=ATOL(1)
+      DO 210 I=1,NEQ
+         IF(INFO(2).EQ.1)RTOLI=RTOL(I)
+         IF(INFO(2).EQ.1)ATOLI=ATOL(I)
+         IF(RTOLI.GT.0.0D0.OR.ATOLI.GT.0.0D0)NZFLG=1
+         IF(RTOLI.LT.0.0D0)GO TO 706
+         IF(ATOLI.LT.0.0D0)GO TO 707
+210      CONTINUE
+      IF(NZFLG.EQ.0)GO TO 708
+C
+C     SET UP RWORK STORAGE.IWORK STORAGE IS FIXED
+C     IN DATA STATEMENT.
+      LG0=LDELTA+NEQ
+      LG1=LG0+NG
+      LGX=LG1+NG
+      LE=LGX+NG
+      LWT=LE+NEQ
+      LPHI=LWT+NEQ
+      LPD=LPHI+(IWORK(LMXORD)+1)*NEQ
+      LWM=LPD
+      NTEMP=NPD+IWORK(LNPD)
+      IF(INFO(1).EQ.1)GO TO 400
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS EXECUTED ON THE INITIAL CALL
+C     ONLY. SET THE INITIAL STEP SIZE, AND
+C     THE ERROR WEIGHT VECTOR, AND PHI.
+C     COMPUTE INITIAL YPRIME, IF NECESSARY.
+C-----------------------------------------------------------------------
+C
+300   CONTINUE
+      TN=T
+      IDID=1
+C
+C     SET ERROR WEIGHT VECTOR WT
+      CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
+      DO 305 I = 1,NEQ
+         IF(RWORK(LWT+I-1).LE.0.0D0) GO TO 713
+305      CONTINUE
+C
+C     COMPUTE UNIT ROUNDOFF AND HMIN
+      UROUND = D1MACH(4)
+      RWORK(LROUND) = UROUND
+      HMIN = 4.0D0*UROUND*DMAX1(DABS(T),DABS(TOUT))
+C
+C     CHECK INITIAL INTERVAL TO SEE THAT IT IS LONG ENOUGH
+      TDIST = DABS(TOUT - T)
+      IF(TDIST .LT. HMIN) GO TO 714
+C
+C     CHECK H0, IF THIS WAS INPUT
+      IF (INFO(8) .EQ. 0) GO TO 310
+         HO = RWORK(LH)
+         IF ((TOUT - T)*HO .LT. 0.0D0) GO TO 711
+         IF (HO .EQ. 0.0D0) GO TO 712
+         GO TO 320
+310    CONTINUE
+C
+C     COMPUTE INITIAL STEPSIZE, TO BE USED BY EITHER
+C     DDASTP OR DDAINI, DEPENDING ON INFO(11)
+      HO = 0.001D0*TDIST
+      YPNORM = DDANRM(NEQ,YPRIME,RWORK(LWT),RPAR,IPAR)
+      IF (YPNORM .GT. 0.5D0/HO) HO = 0.5D0/YPNORM
+      HO = DSIGN(HO,TOUT-T)
+C     ADJUST HO IF NECESSARY TO MEET HMAX BOUND
+320   IF (INFO(7) .EQ. 0) GO TO 330
+         RH = DABS(HO)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) HO = HO/RH
+C     COMPUTE TSTOP, IF APPLICABLE
+330   IF (INFO(4) .EQ. 0) GO TO 340
+         TSTOP = RWORK(LTSTOP)
+         IF ((TSTOP - T)*HO .LT. 0.0D0) GO TO 715
+         IF ((T + HO - TSTOP)*HO .GT. 0.0D0) HO = TSTOP - T
+         IF ((TSTOP - TOUT)*HO .LT. 0.0D0) GO TO 709
+C
+C     COMPUTE INITIAL DERIVATIVE, UPDATING TN AND Y, IF APPLICABLE
+340   IF (INFO(11) .EQ. 0) GO TO 350
+      CALL DDAINI(TN,Y,YPRIME,NEQ,
+     *  RES,JAC,HO,RWORK(LWT),IDID,RPAR,IPAR,
+     *  RWORK(LPHI),RWORK(LDELTA),RWORK(LE),
+     *  RWORK(LWM),IWORK(LIWM),HMIN,RWORK(LROUND),
+     *  INFO(10),NTEMP)
+      IF (IDID .LT. 0) GO TO 390
+C
+C     LOAD H WITH H0.  STORE H IN RWORK(LH)
+350   H = HO
+      RWORK(LH) = H
+C
+C     LOAD Y AND H*YPRIME INTO PHI(*,1) AND PHI(*,2)
+360   ITEMP = LPHI + NEQ
+      DO 370 I = 1,NEQ
+         RWORK(LPHI + I - 1) = Y(I)
+370      RWORK(ITEMP + I - 1) = H*YPRIME(I)
+C
+C     INITIALIZE T0 IN RWORK AND CHECK FOR A ZERO OF G NEAR THE
+C     INITIAL T.
+C
+      RWORK(LT0) = T
+      IWORK(LIRFND) = 0
+      RWORK(LPSI)=H
+      RWORK(LPSI+1)=2.0D0*H
+      IWORK(LKOLD)=1
+      IF(NG .EQ. 0) GO TO 390
+      CALL DRCHEK(1,G,NG,NEQ,T,TOUT,Y,RWORK(LE),RWORK(LPHI),
+     *  RWORK(LPSI),IWORK(LKOLD),RWORK(LG0),RWORK(LG1),
+     *  RWORK(LGX),JROOT,IRT,RWORK(LROUND),INFO(3),
+     *  RWORK,IWORK,RPAR,IPAR)
+      IF(IRT .NE. 0) GO TO 732
+C
+C     Check for a root in the interval (T0,TN], unless DDASRT
+C     did not have to initialize YPRIME.
+C
+      IF(NG .EQ. 0 .OR. INFO(11) .EQ. 0) GO TO 390
+      CALL DRCHEK(3,G,NG,NEQ,TN,TOUT,Y,RWORK(LE),RWORK(LPHI),
+     *  RWORK(LPSI),IWORK(LKOLD),RWORK(LG0),RWORK(LG1),
+     *  RWORK(LGX),JROOT,IRT,RWORK(LROUND),INFO(3),
+     *  RWORK,IWORK,RPAR,IPAR)
+      IF(IRT .NE. 1) GO TO 390
+      IWORK(LIRFND) = 1
+      IDID = 4
+      T = RWORK(LT0)
+      GO TO 580
+C
+390   GO TO 500
+C
+C-------------------------------------------------------
+C     THIS BLOCK IS FOR CONTINUATION CALLS ONLY. ITS
+C     PURPOSE IS TO CHECK STOP CONDITIONS BEFORE
+C     TAKING A STEP.
+C     ADJUST H IF NECESSARY TO MEET HMAX BOUND
+C-------------------------------------------------------
+C
+400   CONTINUE
+      UROUND=RWORK(LROUND)
+      DONE = .FALSE.
+      TN=RWORK(LTN)
+      H=RWORK(LH)
+      IF(NG .EQ. 0) GO TO 405
+C
+C     Check for a zero of G near TN.
+C
+      CALL DRCHEK(2,G,NG,NEQ,TN,TOUT,Y,RWORK(LE),RWORK(LPHI),
+     *  RWORK(LPSI),IWORK(LKOLD),RWORK(LG0),RWORK(LG1),
+     *  RWORK(LGX),JROOT,IRT,RWORK(LROUND),INFO(3),
+     *  RWORK,IWORK,RPAR,IPAR)
+      IF(IRT .NE. 1) GO TO 405
+      IWORK(LIRFND) = 1
+      IDID = 4
+      T = RWORK(LT0)
+      DONE = .TRUE.
+      GO TO 490
+C
+405   CONTINUE
+      IF(INFO(7) .EQ. 0) GO TO 410
+         RH = DABS(H)/RWORK(LHMAX)
+         IF(RH .GT. 1.0D0) H = H/RH
+410   CONTINUE
+      IF(T .EQ. TOUT) GO TO 719
+      IF((T - TOUT)*H .GT. 0.0D0) GO TO 711
+      IF(INFO(4) .EQ. 1) GO TO 430
+      IF(INFO(3) .EQ. 1) GO TO 420
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 490
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+420   IF((TN-T)*H .LE. 0.0D0) GO TO 490
+      IF((TN - TOUT)*H .GT. 0.0D0) GO TO 425
+      CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TN
+      IDID = 1
+      DONE = .TRUE.
+      GO TO 490
+425   CONTINUE
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+430   IF(INFO(3) .EQ. 1) GO TO 440
+      TSTOP=RWORK(LTSTOP)
+      IF((TN-TSTOP)*H.GT.0.0D0) GO TO 715
+      IF((TSTOP-TOUT)*H.LT.0.0D0)GO TO 709
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 450
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *   RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+440   TSTOP = RWORK(LTSTOP)
+      IF((TN-TSTOP)*H .GT. 0.0D0) GO TO 715
+      IF((TSTOP-TOUT)*H .LT. 0.0D0) GO TO 709
+      IF((TN-T)*H .LE. 0.0D0) GO TO 450
+      IF((TN - TOUT)*H .GT. 0.0D0) GO TO 445
+      CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TN
+      IDID = 1
+      DONE = .TRUE.
+      GO TO 490
+445   CONTINUE
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+450   CONTINUE
+C     CHECK WHETHER WE ARE WITH IN ROUNDOFF OF TSTOP
+      IF(DABS(TN-TSTOP).GT.100.0D0*UROUND*
+     *   (DABS(TN)+DABS(H)))GO TO 460
+      CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      DONE = .TRUE.
+      GO TO 490
+460   TNEXT=TN+H
+      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 490
+      H=TSTOP-TN
+      RWORK(LH)=H
+C
+490   IF (DONE) GO TO 590
+C
+C-------------------------------------------------------
+C     THE NEXT BLOCK CONTAINS THE CALL TO THE
+C     ONE-STEP INTEGRATOR DDASTP.
+C     THIS IS A LOOPING POINT FOR THE INTEGRATION STEPS.
+C     CHECK FOR TOO MANY STEPS.
+C     UPDATE WT.
+C     CHECK FOR TOO MUCH ACCURACY REQUESTED.
+C     COMPUTE MINIMUM STEPSIZE.
+C-------------------------------------------------------
+C
+500   CONTINUE
+C     CHECK FOR FAILURE TO COMPUTE INITIAL YPRIME
+      IF (IDID .EQ. -12) GO TO 527
+C
+C     CHECK FOR TOO MANY STEPS
+      IF((IWORK(LNST)-IWORK(LNSTL)).LT.IWORK(LMXSTP))
+     *   GO TO 510
+           IDID=-1
+           GO TO 527
+C
+C     UPDATE WT
+510   CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,RWORK(LPHI),
+     *  RWORK(LWT),RPAR,IPAR)
+      DO 520 I=1,NEQ
+         IF(RWORK(I+LWT-1).GT.0.0D0)GO TO 520
+           IDID=-3
+           GO TO 527
+520   CONTINUE
+C
+C     TEST FOR TOO MUCH ACCURACY REQUESTED.
+      R=DDANRM(NEQ,RWORK(LPHI),RWORK(LWT),RPAR,IPAR)*
+     *   100.0D0*UROUND
+      IF(R.LE.1.0D0)GO TO 525
+C     MULTIPLY RTOL AND ATOL BY R AND RETURN
+      IF(INFO(2).EQ.1)GO TO 523
+           RTOL(1)=R*RTOL(1)
+           ATOL(1)=R*ATOL(1)
+           IDID=-2
+           GO TO 527
+523   DO 524 I=1,NEQ
+           RTOL(I)=R*RTOL(I)
+524        ATOL(I)=R*ATOL(I)
+      IDID=-2
+      GO TO 527
+525   CONTINUE
+C
+C     COMPUTE MINIMUM STEPSIZE
+      HMIN=4.0D0*UROUND*DMAX1(DABS(TN),DABS(TOUT))
+C
+C     TEST H VS. HMAX
+      IF (INFO(7) .EQ. 0) GO TO 526
+         RH = ABS(H)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) H = H/RH
+526   CONTINUE     
+C
+      CALL DDASTP(TN,Y,YPRIME,NEQ,
+     *   RES,JAC,H,RWORK(LWT),INFO(1),IDID,RPAR,IPAR,
+     *   RWORK(LPHI),RWORK(LDELTA),RWORK(LE),
+     *   RWORK(LWM),IWORK(LIWM),
+     *   RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
+     *   RWORK(LPSI),RWORK(LSIGMA),
+     *   RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),
+     *   RWORK(LS),HMIN,RWORK(LROUND),
+     *   IWORK(LPHASE),IWORK(LJCALC),IWORK(LK),
+     *   IWORK(LKOLD),IWORK(LNS),INFO(10),NTEMP)
+527   IF(IDID.LT.0)GO TO 600
+C
+C--------------------------------------------------------
+C     THIS BLOCK HANDLES THE CASE OF A SUCCESSFUL RETURN
+C     FROM DDASTP (IDID=1).  TEST FOR STOP CONDITIONS.
+C--------------------------------------------------------
+C
+      IF(NG .EQ. 0) GO TO 529
+C
+C     Check for a zero of G near TN.
+C
+      CALL DRCHEK(3,G,NG,NEQ,TN,TOUT,Y,RWORK(LE),RWORK(LPHI),
+     *  RWORK(LPSI),IWORK(LKOLD),RWORK(LG0),RWORK(LG1),
+     *  RWORK(LGX),JROOT,IRT,RWORK(LROUND),INFO(3),
+     *  RWORK,IWORK,RPAR,IPAR)
+      IF(IRT .NE. 1) GO TO 529
+      IWORK(LIRFND) = 1
+      IDID = 4
+      T = RWORK(LT0)
+      GO TO 580
+C
+529   CONTINUE
+      IF(INFO(4).NE.0)GO TO 540
+           IF(INFO(3).NE.0)GO TO 530
+             IF((TN-TOUT)*H.LT.0.0D0)GO TO 500
+             CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+             IDID=3
+             T=TOUT
+             GO TO 580
+530          IF((TN-TOUT)*H.GE.0.0D0)GO TO 535
+             T=TN
+             IDID=1
+             GO TO 580
+535          CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+             IDID=3
+             T=TOUT
+             GO TO 580
+540   IF(INFO(3).NE.0)GO TO 550
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 542
+         CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *     IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+         T=TOUT
+         IDID=3
+         GO TO 580
+542   IF(DABS(TN-TSTOP).LE.100.0D0*UROUND*
+     *   (DABS(TN)+DABS(H)))GO TO 545
+      TNEXT=TN+H
+      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 500
+      H=TSTOP-TN
+      GO TO 500
+545   CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
+     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      GO TO 580
+550   IF((TN-TOUT)*H.GE.0.0D0)GO TO 555
+      IF(DABS(TN-TSTOP).LE.100.0D0*UROUND*(DABS(TN)+DABS(H)))GO TO 552
+      T=TN
+      IDID=1
+      GO TO 580
+552   CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
+     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      GO TO 580
+555   CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *   IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID=3
+580   CONTINUE
+C
+C--------------------------------------------------------
+C     ALL SUCCESSFUL RETURNS FROM DDASRT ARE MADE FROM
+C     THIS BLOCK.
+C--------------------------------------------------------
+C
+590   CONTINUE
+      RWORK(LTN)=TN
+      RWORK(LH)=H
+      RWORK(LTLAST) = T
+      RETURN
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK HANDLES ALL UNSUCCESSFUL
+C     RETURNS OTHER THAN FOR ILLEGAL INPUT.
+C-----------------------------------------------------------------------
+C
+600   CONTINUE
+      ITEMP=-IDID
+      GO TO (610,620,630,690,690,640,650,660,670,675,
+     *  680,685), ITEMP
+C
+C     THE MAXIMUM NUMBER OF STEPS WAS TAKEN BEFORE
+C     REACHING TOUT
+610   MSG = 'DASRT--  AT CURRENT T (=R1)  500 STEPS'
+      CALL XERRWD(MSG,38,610,0,0,0,0,1,TN,0.0D0)
+      MSG = 'DASRT--  TAKEN ON THIS CALL BEFORE REACHING TOUT'
+      CALL XERRWD(MSG,48,611,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     TOO MUCH ACCURACY FOR MACHINE PRECISION
+620   MSG = 'DASRT--  AT T (=R1) TOO MUCH ACCURACY REQUESTED'
+      CALL XERRWD(MSG,47,620,0,0,0,0,1,TN,0.0D0)
+      MSG = 'DASRT--  FOR PRECISION OF MACHINE. RTOL AND ATOL'
+      CALL XERRWD(MSG,48,621,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASRT--  WERE INCREASED TO APPROPRIATE VALUES'
+      CALL XERRWD(MSG,45,622,0,0,0,0,0,0.0D0,0.0D0)
+C
+      GO TO 690
+C     WT(I) .LE. 0.0D0 FOR SOME I (NOT AT START OF PROBLEM)
+630   MSG = 'DASRT--  AT T (=R1) SOME ELEMENT OF WT'
+      CALL XERRWD(MSG,38,630,0,0,0,0,1,TN,0.0D0)
+      MSG = 'DASRT--  HAS BECOME .LE. 0.0'
+      CALL XERRWD(MSG,28,631,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     ERROR TEST FAILED REPEATEDLY OR WITH H=HMIN
+640   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,640,0,0,0,0,2,TN,H)
+      MSG='DASRT--  ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN'
+      CALL XERRWD(MSG,57,641,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     CORRECTOR CONVERGENCE FAILED REPEATEDLY OR WITH H=HMIN
+650   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,650,0,0,0,0,2,TN,H)
+      MSG = 'DASRT--  CORRECTOR FAILED TO CONVERGE REPEATEDLY'
+      CALL XERRWD(MSG,48,651,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASRT--  OR WITH ABS(H)=HMIN'
+      CALL XERRWD(MSG,28,652,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     THE ITERATION MATRIX IS SINGULAR
+660   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,660,0,0,0,0,2,TN,H)
+      MSG = 'DASRT--  ITERATION MATRIX IS SINGULAR'
+      CALL XERRWD(MSG,37,661,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     CORRECTOR FAILURE PRECEEDED BY ERROR TEST FAILURES.
+670   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,670,0,0,0,0,2,TN,H)
+      MSG = 'DASRT--  CORRECTOR COULD NOT CONVERGE.  ALSO, THE'
+      CALL XERRWD(MSG,49,671,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASRT--  ERROR TEST FAILED REPEATEDLY.'
+      CALL XERRWD(MSG,38,672,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     CORRECTOR FAILURE BECAUSE IRES = -1
+675   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,675,0,0,0,0,2,TN,H)
+      MSG = 'DASRT--  CORRECTOR COULD NOT CONVERGE BECAUSE'
+      CALL XERRWD(MSG,45,676,0,0,0,0,0,0.0D0,0.0D0)
+      MSG = 'DASRT--  IRES WAS EQUAL TO MINUS ONE'
+      CALL XERRWD(MSG,36,677,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     FAILURE BECAUSE IRES = -2
+680   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2)'
+      CALL XERRWD(MSG,40,680,0,0,0,0,2,TN,H)
+      MSG = 'DASRT--  IRES WAS EQUAL TO MINUS TWO'
+      CALL XERRWD(MSG,36,681,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+C
+C     FAILED TO COMPUTE INITIAL YPRIME
+685   MSG = 'DASRT--  AT T (=R1) AND STEPSIZE H (=R2) THE'
+      CALL XERRWD(MSG,44,685,0,0,0,0,2,TN,HO)
+      MSG = 'DASRT--  INITIAL YPRIME COULD NOT BE COMPUTED'
+      CALL XERRWD(MSG,45,686,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 690
+690   CONTINUE
+      INFO(1)=-1
+      T=TN
+      RWORK(LTN)=TN
+      RWORK(LH)=H
+      RETURN
+C-----------------------------------------------------------------------
+C     THIS BLOCK HANDLES ALL ERROR RETURNS DUE
+C     TO ILLEGAL INPUT, AS DETECTED BEFORE CALLING
+C     DDASTP. FIRST THE ERROR MESSAGE ROUTINE IS
+C     CALLED. IF THIS HAPPENS TWICE IN
+C     SUCCESSION, EXECUTION IS TERMINATED
+C
+C-----------------------------------------------------------------------
+701   MSG = 'DASRT--  SOME ELEMENT OF INFO VECTOR IS NOT ZERO OR ONE'
+      CALL XERRWD(MSG,55,1,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+702   MSG = 'DASRT--  NEQ (=I1) .LE. 0'
+      CALL XERRWD(MSG,25,2,0,1,NEQ,0,0,0.0D0,0.0D0)
+      GO TO 750
+703   MSG = 'DASRT--  MAXORD (=I1) NOT IN RANGE'
+      CALL XERRWD(MSG,34,3,0,1,MXORD,0,0,0.0D0,0.0D0)
+      GO TO 750
+704   MSG='DASRT--  RWORK LENGTH NEEDED, LENRW (=I1), EXCEEDS LRW (=I2)'
+      CALL XERRWD(MSG,60,4,0,2,LENRW,LRW,0,0.0D0,0.0D0)
+      GO TO 750
+705   MSG='DASRT--  IWORK LENGTH NEEDED, LENIW (=I1), EXCEEDS LIW (=I2)'
+      CALL XERRWD(MSG,60,5,0,2,LENIW,LIW,0,0.0D0,0.0D0)
+      GO TO 750
+706   MSG = 'DASRT--  SOME ELEMENT OF RTOL IS .LT. 0'
+      CALL XERRWD(MSG,39,6,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+707   MSG = 'DASRT--  SOME ELEMENT OF ATOL IS .LT. 0'
+      CALL XERRWD(MSG,39,7,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+708   MSG = 'DASRT--  ALL ELEMENTS OF RTOL AND ATOL ARE ZERO'
+      CALL XERRWD(MSG,47,8,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+709   MSG='DASRT--  INFO(4) = 1 AND TSTOP (=R1) BEHIND TOUT (=R2)'
+      CALL XERRWD(MSG,54,9,0,0,0,0,2,TSTOP,TOUT)
+      GO TO 750
+710   MSG = 'DASRT--  HMAX (=R1) .LT. 0.0'
+      CALL XERRWD(MSG,28,10,0,0,0,0,1,HMAX,0.0D0)
+      GO TO 750
+711   MSG = 'DASRT--  TOUT (=R1) BEHIND T (=R2)'
+      CALL XERRWD(MSG,34,11,0,0,0,0,2,TOUT,T)
+      GO TO 750
+712   MSG = 'DASRT--  INFO(8)=1 AND H0=0.0'
+      CALL XERRWD(MSG,29,12,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+713   MSG = 'DASRT--  SOME ELEMENT OF WT IS .LE. 0.0'
+      CALL XERRWD(MSG,39,13,0,0,0,0,0,0.0D0,0.0D0)
+      GO TO 750
+714   MSG='DASRT-- TOUT (=R1) TOO CLOSE TO T (=R2) TO START INTEGRATION'
+      CALL XERRWD(MSG,60,14,0,0,0,0,2,TOUT,T)
+      GO TO 750
+715   MSG = 'DASRT--  INFO(4)=1 AND TSTOP (=R1) BEHIND T (=R2)'
+      CALL XERRWD(MSG,49,15,0,0,0,0,2,TSTOP,T)
+      GO TO 750
+716   MSG = 'DASRT--  INFO(12)=1 AND MXSTP (=I1) .LT. 0'
+      CALL XERRWD(MSG,42,16,0,1,IWORK(LMXSTP),0,0,0.0D0,0.0D0)
+      GO TO 750
+717   MSG = 'DASRT--  ML (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ'
+      CALL XERRWD(MSG,52,17,0,1,IWORK(LML),0,0,0.0D0,0.0D0)
+      GO TO 750
+718   MSG = 'DASRT--  MU (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ'
+      CALL XERRWD(MSG,52,18,0,1,IWORK(LMU),0,0,0.0D0,0.0D0)
+      GO TO 750
+719   MSG = 'DASRT--  TOUT (=R1) IS EQUAL TO T (=R2)'
+      CALL XERRWD(MSG,39,19,0,0,0,0,2,TOUT,T)
+      GO TO 750
+730   MSG = 'DASRT--  NG (=I1) .LT. 0'
+      CALL XERRWD(MSG,24,30,1,1,NG,0,0,0.0D0,0.0D0)
+      GO TO 750
+732   MSG = 'DASRT--  ONE OR MORE COMPONENTS OF G HAS A ROOT'
+      CALL XERRWD(MSG,47,32,1,0,0,0,0,0.0D0,0.0D0)
+      MSG = '         TOO NEAR TO THE INITIAL POINT'
+      CALL XERRWD(MSG,38,32,1,0,0,0,0,0.0D0,0.0D0)
+750   IF(INFO(1).EQ.-1) GO TO 760
+      INFO(1)=-1
+      IDID=-33
+      RETURN
+760   MSG = 'DASRT--  REPEATED OCCURRENCES OF ILLEGAL INPUT'
+      CALL XERRWD(MSG,46,801,0,0,0,0,0,0.0D0,0.0D0)
+770   MSG = 'DASRT--  RUN TERMINATED. APPARENT INFINITE LOOP'
+      CALL XERRWD(MSG,47,802,1,0,0,0,0,0.0D0,0.0D0)
+      RETURN
+C-----------END OF SUBROUTINE DDASRT------------------------------------
+      END
diff --git a/libcruft/dasrt/drchek.f b/libcruft/dasrt/drchek.f
new file mode 100644
index 0000000..673e348
--- /dev/null
+++ b/libcruft/dasrt/drchek.f
@@ -0,0 +1,172 @@
+      SUBROUTINE DRCHEK (JOB, G, NG, NEQ, TN, TOUT, Y, YP, PHI, PSI,
+     *  KOLD, G0, G1, GX, JROOT, IRT, UROUND, INFO3, RWORK, IWORK,
+     *  RPAR, IPAR)
+C
+C***BEGIN PROLOGUE  DRCHEK
+C***REFER TO DDASRT
+C***ROUTINES CALLED  DDATRP, DROOTS, DCOPY
+C***DATE WRITTEN   821001   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***END PROLOGUE  DRCHEK
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      PARAMETER (LNGE=16, LIRFND=18, LLAST=19, LIMAX=20,
+     *           LT0=41, LTLAST=42, LALPHR=43, LX2=44)
+      EXTERNAL G
+      INTEGER JOB, NG, NEQ, KOLD, JROOT, IRT, INFO3, IWORK, IPAR
+      DOUBLE PRECISION TN, TOUT, Y, YP, PHI, PSI, G0, G1, GX, UROUND,
+     *  RWORK, RPAR
+      DIMENSION  Y(*), YP(*), PHI(NEQ,*), PSI(*),
+     1  G0(*), G1(*), GX(*), JROOT(*), RWORK(*), IWORK(*)
+      INTEGER I, JFLAG
+      DOUBLE PRECISION H
+      DOUBLE PRECISION HMING, T1, TEMP1, TEMP2, X
+      LOGICAL ZROOT
+C-----------------------------------------------------------------------
+C THIS ROUTINE CHECKS FOR THE PRESENCE OF A ROOT IN THE
+C VICINITY OF THE CURRENT T, IN A MANNER DEPENDING ON THE
+C INPUT FLAG JOB.  IT CALLS SUBROUTINE DROOTS TO LOCATE THE ROOT
+C AS PRECISELY AS POSSIBLE.
+C
+C IN ADDITION TO VARIABLES DESCRIBED PREVIOUSLY, DRCHEK
+C USES THE FOLLOWING FOR COMMUNICATION..
+C JOB    = INTEGER FLAG INDICATING TYPE OF CALL..
+C          JOB = 1 MEANS THE PROBLEM IS BEING INITIALIZED, AND DRCHEK
+C                  IS TO LOOK FOR A ROOT AT OR VERY NEAR THE INITIAL T.
+C          JOB = 2 MEANS A CONTINUATION CALL TO THE SOLVER WAS JUST
+C                  MADE, AND DRCHEK IS TO CHECK FOR A ROOT IN THE
+C                  RELEVANT PART OF THE STEP LAST TAKEN.
+C          JOB = 3 MEANS A SUCCESSFUL STEP WAS JUST TAKEN, AND DRCHEK
+C                  IS TO LOOK FOR A ROOT IN THE INTERVAL OF THE STEP.
+C G0     = ARRAY OF LENGTH NG, CONTAINING THE VALUE OF G AT T = T0.
+C          G0 IS INPUT FOR JOB .GE. 2 AND ON OUTPUT IN ALL CASES.
+C G1,GX  = ARRAYS OF LENGTH NG FOR WORK SPACE.
+C IRT    = COMPLETION FLAG..
+C          IRT = 0  MEANS NO ROOT WAS FOUND.
+C          IRT = -1 MEANS JOB = 1 AND A ROOT WAS FOUND TOO NEAR TO T.
+C          IRT = 1  MEANS A LEGITIMATE ROOT WAS FOUND (JOB = 2 OR 3).
+C                   ON RETURN, T0 IS THE ROOT LOCATION, AND Y IS THE
+C                   CORRESPONDING SOLUTION VECTOR.
+C T0     = VALUE OF T AT ONE ENDPOINT OF INTERVAL OF INTEREST.  ONLY
+C          ROOTS BEYOND T0 IN THE DIRECTION OF INTEGRATION ARE SOUGHT.
+C          T0 IS INPUT IF JOB .GE. 2, AND OUTPUT IN ALL CASES.
+C          T0 IS UPDATED BY DRCHEK, WHETHER A ROOT IS FOUND OR NOT.
+C          STORED IN THE GLOBAL ARRAY RWORK.
+C TLAST  = LAST VALUE OF T RETURNED BY THE SOLVER (INPUT ONLY).
+C          STORED IN THE GLOBAL ARRAY RWORK.
+C TOUT   = FINAL OUTPUT TIME FOR THE SOLVER.
+C IRFND  = INPUT FLAG SHOWING WHETHER THE LAST STEP TAKEN HAD A ROOT.
+C          IRFND = 1 IF IT DID, = 0 IF NOT.
+C          STORED IN THE GLOBAL ARRAY IWORK.
+C INFO3  = COPY OF INFO(3) (INPUT ONLY).
+C-----------------------------------------------------------------------
+C     
+      H = PSI(1)
+      IRT = 0
+      DO 10 I = 1,NG
+ 10     JROOT(I) = 0
+      HMING = (DABS(TN) + DABS(H))*UROUND*100.0D0
+C
+      GO TO (100, 200, 300), JOB
+C
+C EVALUATE G AT INITIAL T (STORED IN RWORK(LT0)), AND CHECK FOR
+C ZERO VALUES.----------------------------------------------------------
+ 100  CONTINUE
+      CALL DDATRP(TN,RWORK(LT0),Y,YP,NEQ,KOLD,PHI,PSI)
+      CALL G (NEQ, RWORK(LT0), Y, NG, G0, RPAR, IPAR)
+      IWORK(LNGE) = 1
+      ZROOT = .FALSE.
+      DO 110 I = 1,NG
+ 110    IF (DABS(G0(I)) .LE. 0.0D0) ZROOT = .TRUE.
+      IF (.NOT. ZROOT) GO TO 190
+C G HAS A ZERO AT T.  LOOK AT G AT T + (SMALL INCREMENT). --------------
+      TEMP1 = DSIGN(HMING,H)
+      RWORK(LT0) = RWORK(LT0) + TEMP1
+      TEMP2 = TEMP1/H
+      DO 120 I = 1,NEQ
+ 120    Y(I) = Y(I) + TEMP2*PHI(I,2)
+      CALL G (NEQ, RWORK(LT0), Y, NG, G0, RPAR, IPAR)
+      IWORK(LNGE) = IWORK(LNGE) + 1
+      ZROOT = .FALSE.
+      DO 130 I = 1,NG
+ 130    IF (DABS(G0(I)) .LE. 0.0D0) ZROOT = .TRUE.
+      IF (.NOT. ZROOT) GO TO 190
+C G HAS A ZERO AT T AND ALSO CLOSE TO T.  TAKE ERROR RETURN. -----------
+      IRT = -1
+      RETURN
+C
+ 190  CONTINUE
+      RETURN
+C
+C
+ 200  CONTINUE
+      IF (IWORK(LIRFND) .EQ. 0) GO TO 260
+C IF A ROOT WAS FOUND ON THE PREVIOUS STEP, EVALUATE G0 = G(T0). -------
+      CALL DDATRP (TN, RWORK(LT0), Y, YP, NEQ, KOLD, PHI, PSI)
+      CALL G (NEQ, RWORK(LT0), Y, NG, G0, RPAR, IPAR)
+      IWORK(LNGE) = IWORK(LNGE) + 1
+      ZROOT = .FALSE.
+      DO 210 I = 1,NG
+ 210    IF (DABS(G0(I)) .LE. 0.0D0) ZROOT = .TRUE.
+      IF (.NOT. ZROOT) GO TO 260
+C G HAS A ZERO AT T0.  LOOK AT G AT T + (SMALL INCREMENT). -------------
+      TEMP1 = DSIGN(HMING,H)
+      RWORK(LT0) = RWORK(LT0) + TEMP1
+      IF ((RWORK(LT0) - TN)*H .LT. 0.0D0) GO TO 230
+      TEMP2 = TEMP1/H
+      DO 220 I = 1,NEQ
+ 220    Y(I) = Y(I) + TEMP2*PHI(I,2)
+      GO TO 240
+ 230  CALL DDATRP (TN, RWORK(LT0), Y, YP, NEQ, KOLD, PHI, PSI)
+ 240  CALL G (NEQ, RWORK(LT0), Y, NG, G0, RPAR, IPAR)
+      IWORK(LNGE) = IWORK(LNGE) + 1
+      ZROOT = .FALSE.
+      DO 250 I = 1,NG
+        IF (DABS(G0(I)) .GT. 0.0D0) GO TO 250
+        JROOT(I) = 1
+        ZROOT = .TRUE.
+ 250    CONTINUE
+      IF (.NOT. ZROOT) GO TO 260
+C G HAS A ZERO AT T0 AND ALSO CLOSE TO T0.  RETURN ROOT. ---------------
+      IRT = 1
+      RETURN
+C     HERE, G0 DOES NOT HAVE A ROOT
+C G0 HAS NO ZERO COMPONENTS.  PROCEED TO CHECK RELEVANT INTERVAL. ------
+ 260  IF (TN .EQ. RWORK(LTLAST)) GO TO 390
+C
+ 300  CONTINUE
+C SET T1 TO TN OR TOUT, WHICHEVER COMES FIRST, AND GET G AT T1. --------
+      IF (INFO3 .EQ. 1) GO TO 310
+      IF ((TOUT - TN)*H .GE. 0.0D0) GO TO 310
+      T1 = TOUT
+      IF ((T1 - RWORK(LT0))*H .LE. 0.0D0) GO TO 390
+      CALL DDATRP (TN, T1, Y, YP, NEQ, KOLD, PHI, PSI)
+      GO TO 330
+ 310  T1 = TN
+      DO 320 I = 1,NEQ
+ 320    Y(I) = PHI(I,1)
+ 330  CALL G (NEQ, T1, Y, NG, G1, RPAR, IPAR)
+      IWORK(LNGE) = IWORK(LNGE) + 1
+C CALL DROOTS TO SEARCH FOR ROOT IN INTERVAL FROM T0 TO T1. ------------
+      JFLAG = 0
+ 350  CONTINUE
+      CALL DROOTS (NG, HMING, JFLAG, RWORK(LT0), T1, G0, G1, GX, X,
+     *             JROOT, IWORK(LIMAX), IWORK(LLAST), RWORK(LALPHR),
+     *             RWORK(LX2))
+      IF (JFLAG .GT. 1) GO TO 360
+      CALL DDATRP (TN, X, Y, YP, NEQ, KOLD, PHI, PSI)
+      CALL G (NEQ, X, Y, NG, GX, RPAR, IPAR)
+      IWORK(LNGE) = IWORK(LNGE) + 1
+      GO TO 350
+ 360  RWORK(LT0) = X
+      CALL DCOPY (NG, GX, 1, G0, 1)
+      IF (JFLAG .EQ. 4) GO TO 390
+C FOUND A ROOT.  INTERPOLATE TO X AND RETURN. --------------------------
+      CALL DDATRP (TN, X, Y, YP, NEQ, KOLD, PHI, PSI)
+      IRT = 1
+      RETURN
+C
+ 390  CONTINUE
+      RETURN
+C---------------------- END OF SUBROUTINE DRCHEK -----------------------
+      END
diff --git a/libcruft/dasrt/droots.f b/libcruft/dasrt/droots.f
new file mode 100644
index 0000000..44b3fe0
--- /dev/null
+++ b/libcruft/dasrt/droots.f
@@ -0,0 +1,217 @@
+      SUBROUTINE DROOTS (NG, HMIN, JFLAG, X0, X1, G0, G1, GX, X, JROOT,
+     *                   IMAX, LAST, ALPHA, X2)
+C
+C***BEGIN PROLOGUE  DROOTS
+C***REFER TO DDASRT
+C***ROUTINES CALLED  DCOPY
+C***DATE WRITTEN   821001   (YYMMDD)
+C***REVISION DATE  900926   (YYMMDD)
+C***END PROLOGUE  DROOTS
+C
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      INTEGER NG, JFLAG, JROOT, IMAX, LAST
+      DOUBLE PRECISION HMIN, X0, X1, G0, G1, GX, X, ALPHA, X2
+      DIMENSION G0(NG), G1(NG), GX(NG), JROOT(NG)
+C-----------------------------------------------------------------------
+C THIS SUBROUTINE FINDS THE LEFTMOST ROOT OF A SET OF ARBITRARY
+C FUNCTIONS GI(X) (I = 1,...,NG) IN AN INTERVAL (X0,X1).  ONLY ROOTS
+C OF ODD MULTIPLICITY (I.E. CHANGES OF SIGN OF THE GI) ARE FOUND.
+C HERE THE SIGN OF X1 - X0 IS ARBITRARY, BUT IS CONSTANT FOR A GIVEN
+C PROBLEM, AND -LEFTMOST- MEANS NEAREST TO X0.
+C THE VALUES OF THE VECTOR-VALUED FUNCTION G(X) = (GI, I=1...NG)
+C ARE COMMUNICATED THROUGH THE CALL SEQUENCE OF DROOTS.
+C THE METHOD USED IS THE ILLINOIS ALGORITHM.
+C
+C REFERENCE..
+C KATHIE L. HIEBERT AND LAWRENCE F. SHAMPINE, IMPLICITLY DEFINED
+C OUTPUT POINTS FOR SOLUTIONS OF ODE-S, SANDIA REPORT SAND80-0180,
+C FEBRUARY, 1980.
+C
+C DESCRIPTION OF PARAMETERS.
+C
+C NG     = NUMBER OF FUNCTIONS GI, OR THE NUMBER OF COMPONENTS OF
+C          THE VECTOR VALUED FUNCTION G(X).  INPUT ONLY.
+C
+C HMIN   = RESOLUTION PARAMETER IN X.  INPUT ONLY.  WHEN A ROOT IS
+C          FOUND, IT IS LOCATED ONLY TO WITHIN AN ERROR OF HMIN IN X.
+C          TYPICALLY, HMIN SHOULD BE SET TO SOMETHING ON THE ORDER OF
+C               100 * UROUND * MAX(ABS(X0),ABS(X1)),
+C          WHERE UROUND IS THE UNIT ROUNDOFF OF THE MACHINE.
+C
+C JFLAG  = INTEGER FLAG FOR INPUT AND OUTPUT COMMUNICATION.
+C
+C          ON INPUT, SET JFLAG = 0 ON THE FIRST CALL FOR THE PROBLEM,
+C          AND LEAVE IT UNCHANGED UNTIL THE PROBLEM IS COMPLETED.
+C          (THE PROBLEM IS COMPLETED WHEN JFLAG .GE. 2 ON RETURN.)
+C
+C          ON OUTPUT, JFLAG HAS THE FOLLOWING VALUES AND MEANINGS..
+C          JFLAG = 1 MEANS DROOTS NEEDS A VALUE OF G(X).  SET GX = G(X)
+C                    AND CALL DROOTS AGAIN.
+C          JFLAG = 2 MEANS A ROOT HAS BEEN FOUND.  THE ROOT IS
+C                    AT X, AND GX CONTAINS G(X).  (ACTUALLY, X IS THE
+C                    RIGHTMOST APPROXIMATION TO THE ROOT ON AN INTERVAL
+C                    (X0,X1) OF SIZE HMIN OR LESS.)
+C          JFLAG = 3 MEANS X = X1 IS A ROOT, WITH ONE OR MORE OF THE GI
+C                    BEING ZERO AT X1 AND NO SIGN CHANGES IN (X0,X1).
+C                    GX CONTAINS G(X) ON OUTPUT.
+C          JFLAG = 4 MEANS NO ROOTS (OF ODD MULTIPLICITY) WERE
+C                    FOUND IN (X0,X1) (NO SIGN CHANGES).
+C
+C X0,X1  = ENDPOINTS OF THE INTERVAL WHERE ROOTS ARE SOUGHT.
+C          X1 AND X0 ARE INPUT WHEN JFLAG = 0 (FIRST CALL), AND
+C          MUST BE LEFT UNCHANGED BETWEEN CALLS UNTIL THE PROBLEM IS
+C          COMPLETED.  X0 AND X1 MUST BE DISTINCT, BUT X1 - X0 MAY BE
+C          OF EITHER SIGN.  HOWEVER, THE NOTION OF -LEFT- AND -RIGHT-
+C          WILL BE USED TO MEAN NEARER TO X0 OR X1, RESPECTIVELY.
+C          WHEN JFLAG .GE. 2 ON RETURN, X0 AND X1 ARE OUTPUT, AND
+C          ARE THE ENDPOINTS OF THE RELEVANT INTERVAL.
+C
+C G0,G1  = ARRAYS OF LENGTH NG CONTAINING THE VECTORS G(X0) AND G(X1),
+C          RESPECTIVELY.  WHEN JFLAG = 0, G0 AND G1 ARE INPUT AND
+C          NONE OF THE G0(I) SHOULD BE BE ZERO.
+C          WHEN JFLAG .GE. 2 ON RETURN, G0 AND G1 ARE OUTPUT.
+C
+C GX     = ARRAY OF LENGTH NG CONTAINING G(X).  GX IS INPUT
+C          WHEN JFLAG = 1, AND OUTPUT WHEN JFLAG .GE. 2.
+C
+C X      = INDEPENDENT VARIABLE VALUE.  OUTPUT ONLY.
+C          WHEN JFLAG = 1 ON OUTPUT, X IS THE POINT AT WHICH G(X)
+C          IS TO BE EVALUATED AND LOADED INTO GX.
+C          WHEN JFLAG = 2 OR 3, X IS THE ROOT.
+C          WHEN JFLAG = 4, X IS THE RIGHT ENDPOINT OF THE INTERVAL, X1.
+C
+C JROOT  = INTEGER ARRAY OF LENGTH NG.  OUTPUT ONLY.
+C          WHEN JFLAG = 2 OR 3, JROOT INDICATES WHICH COMPONENTS
+C          OF G(X) HAVE A ROOT AT X.  JROOT(I) IS 1 IF THE I-TH
+C          COMPONENT HAS A ROOT, AND JROOT(I) = 0 OTHERWISE.
+C
+C IMAX, LAST, ALPHA, X2 =
+C          BOOKKEEPING VARIABLES WHICH MUST BE SAVED FROM CALL
+C          TO CALL.  THEY ARE SAVED INSIDE THE CALLING ROUTINE,
+C          BUT THEY ARE USED ONLY WITHIN THIS ROUTINE.
+C-----------------------------------------------------------------------
+      INTEGER I, IMXOLD, NXLAST
+      DOUBLE PRECISION T2, TMAX, ZERO
+      LOGICAL ZROOT, SGNCHG, XROOT
+      DATA ZERO/0.0D0/
+C
+      IF (JFLAG .EQ. 1) GO TO 200
+C JFLAG .NE. 1.  CHECK FOR CHANGE IN SIGN OF G OR ZERO AT X1. ----------
+      IMAX = 0
+      TMAX = ZERO
+      ZROOT = .FALSE.
+      DO 120 I = 1,NG
+        IF (DABS(G1(I)) .GT. ZERO) GO TO 110
+        ZROOT = .TRUE.
+        GO TO 120
+C AT THIS POINT, G0(I) HAS BEEN CHECKED AND CANNOT BE ZERO. ------------
+ 110    IF (DSIGN(1.0D0,G0(I)) .EQ. DSIGN(1.0D0,G1(I))) GO TO 120
+          T2 = DABS(G1(I)/(G1(I)-G0(I)))
+          IF (T2 .LE. TMAX) GO TO 120
+            TMAX = T2
+            IMAX = I
+ 120    CONTINUE
+      IF (IMAX .GT. 0) GO TO 130
+      SGNCHG = .FALSE.
+      GO TO 140
+ 130  SGNCHG = .TRUE.
+ 140  IF (.NOT. SGNCHG) GO TO 400
+C THERE IS A SIGN CHANGE.  FIND THE FIRST ROOT IN THE INTERVAL. --------
+      XROOT = .FALSE.
+      NXLAST = 0
+      LAST = 1
+C
+C REPEAT UNTIL THE FIRST ROOT IN THE INTERVAL IS FOUND.  LOOP POINT. ---
+ 150  CONTINUE
+      IF (XROOT) GO TO 300
+      IF (NXLAST .EQ. LAST) GO TO 160
+      ALPHA = 1.0D0
+      GO TO 180
+ 160  IF (LAST .EQ. 0) GO TO 170
+      ALPHA = 0.5D0*ALPHA
+      GO TO 180
+ 170  ALPHA = 2.0D0*ALPHA
+ 180  X2 = X1 - (X1-X0)*G1(IMAX)/(G1(IMAX) - ALPHA*G0(IMAX))
+      IF ((DABS(X2-X0) .LT. HMIN) .AND.
+     1   (DABS(X1-X0) .GT. 10.0D0*HMIN)) X2 = X0 + 0.1D0*(X1-X0)
+      JFLAG = 1
+      X = X2
+C RETURN TO THE CALLING ROUTINE TO GET A VALUE OF GX = G(X). -----------
+      RETURN
+C CHECK TO SEE IN WHICH INTERVAL G CHANGES SIGN. -----------------------
+ 200  IMXOLD = IMAX
+      IMAX = 0
+      TMAX = ZERO
+      ZROOT = .FALSE.
+      DO 220 I = 1,NG
+        IF (DABS(GX(I)) .GT. ZERO) GO TO 210
+        ZROOT = .TRUE.
+        GO TO 220
+C NEITHER G0(I) NOR GX(I) CAN BE ZERO AT THIS POINT. -------------------
+ 210    IF (DSIGN(1.0D0,G0(I)) .EQ. DSIGN(1.0D0,GX(I))) GO TO 220
+          T2 = DABS(GX(I)/(GX(I) - G0(I)))
+          IF (T2 .LE. TMAX) GO TO 220
+            TMAX = T2
+            IMAX = I
+ 220    CONTINUE
+      IF (IMAX .GT. 0) GO TO 230
+      SGNCHG = .FALSE.
+      IMAX = IMXOLD
+      GO TO 240
+ 230  SGNCHG = .TRUE.
+ 240  NXLAST = LAST
+      IF (.NOT. SGNCHG) GO TO 250
+C SIGN CHANGE BETWEEN X0 AND X2, SO REPLACE X1 WITH X2. ----------------
+      X1 = X2
+      CALL DCOPY (NG, GX, 1, G1, 1)
+      LAST = 1
+      XROOT = .FALSE.
+      GO TO 270
+ 250  IF (.NOT. ZROOT) GO TO 260
+C ZERO VALUE AT X2 AND NO SIGN CHANGE IN (X0,X2), SO X2 IS A ROOT. -----
+      X1 = X2
+      CALL DCOPY (NG, GX, 1, G1, 1)
+      XROOT = .TRUE.
+      GO TO 270
+C NO SIGN CHANGE BETWEEN X0 AND X2.  REPLACE X0 WITH X2. ---------------
+ 260  CONTINUE
+      CALL DCOPY (NG, GX, 1, G0, 1)
+      X0 = X2
+      LAST = 0
+      XROOT = .FALSE.
+ 270  IF (DABS(X1-X0) .LE. HMIN) XROOT = .TRUE.
+      GO TO 150
+C
+C RETURN WITH X1 AS THE ROOT.  SET JROOT.  SET X = X1 AND GX = G1. -----
+ 300  JFLAG = 2
+      X = X1
+      CALL DCOPY (NG, G1, 1, GX, 1)
+      DO 320 I = 1,NG
+        JROOT(I) = 0
+        IF (DABS(G1(I)) .GT. ZERO) GO TO 310
+          JROOT(I) = 1
+          GO TO 320
+ 310    IF (DSIGN(1.0D0,G0(I)) .NE. DSIGN(1.0D0,G1(I))) JROOT(I) = 1
+ 320    CONTINUE
+      RETURN
+C
+C NO SIGN CHANGE IN THE INTERVAL.  CHECK FOR ZERO AT RIGHT ENDPOINT. ---
+ 400  IF (.NOT. ZROOT) GO TO 420
+C
+C ZERO VALUE AT X1 AND NO SIGN CHANGE IN (X0,X1).  RETURN JFLAG = 3. ---
+      X = X1
+      CALL DCOPY (NG, G1, 1, GX, 1)
+      DO 410 I = 1,NG
+        JROOT(I) = 0
+        IF (DABS(G1(I)) .LE. ZERO) JROOT (I) = 1
+ 410  CONTINUE
+      JFLAG = 3
+      RETURN
+C
+C NO SIGN CHANGES IN THIS INTERVAL.  SET X = X1, RETURN JFLAG = 4. -----
+ 420  CALL DCOPY (NG, G1, 1, GX, 1)
+      X = X1
+      JFLAG = 4
+      RETURN
+C---------------------- END OF SUBROUTINE DROOTS -----------------------
+      END
diff --git a/libcruft/dassl/Makefile.in b/libcruft/dassl/Makefile.in
new file mode 100644
index 0000000..94aa104
--- /dev/null
+++ b/libcruft/dassl/Makefile.in
@@ -0,0 +1,33 @@
+# Makefile for octave's libcruft/dassl directory
+#
+# Copyright (C) 1993, 1994, 1995, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = ddaini.f ddajac.f ddanrm.f ddaslv.f ddassl.f ddastp.f ddatrp.f ddawts.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/dassl/ddaini.f b/libcruft/dassl/ddaini.f
new file mode 100644
index 0000000..ea57d8c
--- /dev/null
+++ b/libcruft/dassl/ddaini.f
@@ -0,0 +1,257 @@
+      SUBROUTINE DDAINI (X, Y, YPRIME, NEQ, RES, JAC, H, WT, IDID, RPAR,
+     +   IPAR, PHI, DELTA, E, WM, IWM, HMIN, UROUND, NONNEG, NTEMP)
+C***BEGIN PROLOGUE  DDAINI
+C***SUBSIDIARY
+C***PURPOSE  Initialization routine for DDASSL.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDAINI-S, DDAINI-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------
+C     DDAINI TAKES ONE STEP OF SIZE H OR SMALLER
+C     WITH THE BACKWARD EULER METHOD, TO
+C     FIND YPRIME.  X AND Y ARE UPDATED TO BE CONSISTENT WITH THE
+C     NEW STEP.  A MODIFIED DAMPED NEWTON ITERATION IS USED TO
+C     SOLVE THE CORRECTOR ITERATION.
+C
+C     THE INITIAL GUESS FOR YPRIME IS USED IN THE
+C     PREDICTION, AND IN FORMING THE ITERATION
+C     MATRIX, BUT IS NOT INVOLVED IN THE
+C     ERROR TEST. THIS MAY HAVE TROUBLE
+C     CONVERGING IF THE INITIAL GUESS IS NO
+C     GOOD, OR IF G(X,Y,YPRIME) DEPENDS
+C     NONLINEARLY ON YPRIME.
+C
+C     THE PARAMETERS REPRESENT:
+C     X --         INDEPENDENT VARIABLE
+C     Y --         SOLUTION VECTOR AT X
+C     YPRIME --    DERIVATIVE OF SOLUTION VECTOR
+C     NEQ --       NUMBER OF EQUATIONS
+C     H --         STEPSIZE. IMDER MAY USE A STEPSIZE
+C                  SMALLER THAN H.
+C     WT --        VECTOR OF WEIGHTS FOR ERROR
+C                  CRITERION
+C     IDID --      COMPLETION CODE WITH THE FOLLOWING MEANINGS
+C                  IDID= 1 -- YPRIME WAS FOUND SUCCESSFULLY
+C                  IDID=-12 -- DDAINI FAILED TO FIND YPRIME
+C     RPAR,IPAR -- REAL AND INTEGER PARAMETER ARRAYS
+C                  THAT ARE NOT ALTERED BY DDAINI
+C     PHI --       WORK SPACE FOR DDAINI
+C     DELTA,E --   WORK SPACE FOR DDAINI
+C     WM,IWM --    REAL AND INTEGER ARRAYS STORING
+C                  MATRIX INFORMATION
+C
+C-----------------------------------------------------------------
+C***ROUTINES CALLED  DDAJAC, DDANRM, DDASLV
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C   901030  Minor corrections to declarations.  (FNF)
+C***END PROLOGUE  DDAINI
+C
+      INTEGER  NEQ, IDID, IPAR(*), IWM(*), NONNEG, NTEMP
+      DOUBLE PRECISION
+     *   X, Y(*), YPRIME(*), H, WT(*), RPAR(*), PHI(NEQ,*), DELTA(*),
+     *   E(*), WM(*), HMIN, UROUND
+      EXTERNAL  RES, JAC
+C
+      EXTERNAL  DDAJAC, DDANRM, DDASLV
+      DOUBLE PRECISION  DDANRM
+C
+      INTEGER  I, IER, IRES, JCALC, LNJE, LNRE, M, MAXIT, MJAC, NCF,
+     *   NEF, NSF
+      DOUBLE PRECISION
+     *   CJ, DAMP, DELNRM, ERR, OLDNRM, R, RATE, S, XOLD, YNORM
+      LOGICAL  CONVGD
+C
+      PARAMETER (LNRE=12)
+      PARAMETER (LNJE=13)
+C
+      DATA MAXIT/10/,MJAC/5/
+      DATA DAMP/0.75D0/
+C
+C
+C---------------------------------------------------
+C     BLOCK 1.
+C     INITIALIZATIONS.
+C---------------------------------------------------
+C
+C***FIRST EXECUTABLE STATEMENT  DDAINI
+      IDID=1
+      NEF=0
+      NCF=0
+      NSF=0
+      XOLD=X
+      YNORM=DDANRM(NEQ,Y,WT,RPAR,IPAR)
+C
+C     SAVE Y AND YPRIME IN PHI
+      DO 100 I=1,NEQ
+         PHI(I,1)=Y(I)
+100      PHI(I,2)=YPRIME(I)
+C
+C
+C----------------------------------------------------
+C     BLOCK 2.
+C     DO ONE BACKWARD EULER STEP.
+C----------------------------------------------------
+C
+C     SET UP FOR START OF CORRECTOR ITERATION
+200   CJ=1.0D0/H
+      X=X+H
+C
+C     PREDICT SOLUTION AND DERIVATIVE
+      DO 250 I=1,NEQ
+250     Y(I)=Y(I)+H*YPRIME(I)
+C
+      JCALC=-1
+      M=0
+      CONVGD=.TRUE.
+C
+C
+C     CORRECTOR LOOP.
+300   IWM(LNRE)=IWM(LNRE)+1
+      IRES=0
+C
+      CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
+      IF (IRES.LT.0) GO TO 430
+C
+C
+C     EVALUATE THE ITERATION MATRIX
+      IF (JCALC.NE.-1) GO TO 310
+      IWM(LNJE)=IWM(LNJE)+1
+      JCALC=0
+      CALL DDAJAC(NEQ,X,Y,YPRIME,DELTA,CJ,H,
+     *   IER,WT,E,WM,IWM,RES,IRES,
+     *   UROUND,JAC,RPAR,IPAR,NTEMP)
+C
+      S=1000000.D0
+      IF (IRES.LT.0) GO TO 430
+      IF (IER.NE.0) GO TO 430
+      NSF=0
+C
+C
+C
+C     MULTIPLY RESIDUAL BY DAMPING FACTOR
+310   CONTINUE
+      DO 320 I=1,NEQ
+320      DELTA(I)=DELTA(I)*DAMP
+C
+C     COMPUTE A NEW ITERATE (BACK SUBSTITUTION)
+C     STORE THE CORRECTION IN DELTA
+C
+      CALL DDASLV(NEQ,DELTA,WM,IWM)
+C
+C     UPDATE Y AND YPRIME
+      DO 330 I=1,NEQ
+         Y(I)=Y(I)-DELTA(I)
+330      YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
+C
+C     TEST FOR CONVERGENCE OF THE ITERATION.
+C
+      DELNRM=DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF (DELNRM.LE.100.D0*UROUND*YNORM)
+     *   GO TO 400
+C
+      IF (M.GT.0) GO TO 340
+         OLDNRM=DELNRM
+         GO TO 350
+C
+340   RATE=(DELNRM/OLDNRM)**(1.0D0/M)
+      IF (RATE.GT.0.90D0) GO TO 430
+      S=RATE/(1.0D0-RATE)
+C
+350   IF (S*DELNRM .LE. 0.33D0) GO TO 400
+C
+C
+C     THE CORRECTOR HAS NOT YET CONVERGED. UPDATE
+C     M AND AND TEST WHETHER THE MAXIMUM
+C     NUMBER OF ITERATIONS HAVE BEEN TRIED.
+C     EVERY MJAC ITERATIONS, GET A NEW
+C     ITERATION MATRIX.
+C
+      M=M+1
+      IF (M.GE.MAXIT) GO TO 430
+C
+      IF ((M/MJAC)*MJAC.EQ.M) JCALC=-1
+      GO TO 300
+C
+C
+C     THE ITERATION HAS CONVERGED.
+C     CHECK NONNEGATIVITY CONSTRAINTS
+400   IF (NONNEG.EQ.0) GO TO 450
+      DO 410 I=1,NEQ
+410      DELTA(I)=MIN(Y(I),0.0D0)
+C
+      DELNRM=DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF (DELNRM.GT.0.33D0) GO TO 430
+C
+      DO 420 I=1,NEQ
+         Y(I)=Y(I)-DELTA(I)
+420      YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
+      GO TO 450
+C
+C
+C     EXITS FROM CORRECTOR LOOP.
+430   CONVGD=.FALSE.
+450   IF (.NOT.CONVGD) GO TO 600
+C
+C
+C
+C-----------------------------------------------------
+C     BLOCK 3.
+C     THE CORRECTOR ITERATION CONVERGED.
+C     DO ERROR TEST.
+C-----------------------------------------------------
+C
+      DO 510 I=1,NEQ
+510      E(I)=Y(I)-PHI(I,1)
+      ERR=DDANRM(NEQ,E,WT,RPAR,IPAR)
+C
+      IF (ERR.LE.1.0D0) RETURN
+C
+C
+C
+C--------------------------------------------------------
+C     BLOCK 4.
+C     THE BACKWARD EULER STEP FAILED. RESTORE X, Y
+C     AND YPRIME TO THEIR ORIGINAL VALUES.
+C     REDUCE STEPSIZE AND TRY AGAIN, IF
+C     POSSIBLE.
+C---------------------------------------------------------
+C
+600   CONTINUE
+      X = XOLD
+      DO 610 I=1,NEQ
+         Y(I)=PHI(I,1)
+610      YPRIME(I)=PHI(I,2)
+C
+      IF (CONVGD) GO TO 640
+      IF (IER.EQ.0) GO TO 620
+         NSF=NSF+1
+         H=H*0.25D0
+         IF (NSF.LT.3.AND.ABS(H).GE.HMIN) GO TO 690
+         IDID=-12
+         RETURN
+620   IF (IRES.GT.-2) GO TO 630
+         IDID=-12
+         RETURN
+630   NCF=NCF+1
+      H=H*0.25D0
+      IF (NCF.LT.10.AND.ABS(H).GE.HMIN) GO TO 690
+         IDID=-12
+         RETURN
+C
+640   NEF=NEF+1
+      R=0.90D0/(2.0D0*ERR+0.0001D0)
+      R=MAX(0.1D0,MIN(0.5D0,R))
+      H=H*R
+      IF (ABS(H).GE.HMIN.AND.NEF.LT.10) GO TO 690
+         IDID=-12
+         RETURN
+690      GO TO 200
+C
+C-------------END OF SUBROUTINE DDAINI----------------------
+      END
diff --git a/libcruft/dassl/ddajac.f b/libcruft/dassl/ddajac.f
new file mode 100644
index 0000000..e3137c7
--- /dev/null
+++ b/libcruft/dassl/ddajac.f
@@ -0,0 +1,178 @@
+      SUBROUTINE DDAJAC (NEQ, X, Y, YPRIME, DELTA, CJ, H,
+     +   IER, WT, E, WM, IWM, RES, IRES, UROUND, JAC, RPAR,
+     +   IPAR, NTEMP)
+C***BEGIN PROLOGUE  DDAJAC
+C***SUBSIDIARY
+C***PURPOSE  Compute the iteration matrix for DDASSL and form the
+C            LU-decomposition.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDAJAC-S, DDAJAC-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------------
+C     THIS ROUTINE COMPUTES THE ITERATION MATRIX
+C     PD=DG/DY+CJ*DG/DYPRIME (WHERE G(X,Y,YPRIME)=0).
+C     HERE PD IS COMPUTED BY THE USER-SUPPLIED
+C     ROUTINE JAC IF IWM(MTYPE) IS 1 OR 4, AND
+C     IT IS COMPUTED BY NUMERICAL FINITE DIFFERENCING
+C     IF IWM(MTYPE)IS 2 OR 5
+C     THE PARAMETERS HAVE THE FOLLOWING MEANINGS.
+C     Y        = ARRAY CONTAINING PREDICTED VALUES
+C     YPRIME   = ARRAY CONTAINING PREDICTED DERIVATIVES
+C     DELTA    = RESIDUAL EVALUATED AT (X,Y,YPRIME)
+C                (USED ONLY IF IWM(MTYPE)=2 OR 5)
+C     CJ       = SCALAR PARAMETER DEFINING ITERATION MATRIX
+C     H        = CURRENT STEPSIZE IN INTEGRATION
+C     IER      = VARIABLE WHICH IS .NE. 0
+C                IF ITERATION MATRIX IS SINGULAR,
+C                AND 0 OTHERWISE.
+C     WT       = VECTOR OF WEIGHTS FOR COMPUTING NORMS
+C     E        = WORK SPACE (TEMPORARY) OF LENGTH NEQ
+C     WM       = REAL WORK SPACE FOR MATRICES. ON
+C                OUTPUT IT CONTAINS THE LU DECOMPOSITION
+C                OF THE ITERATION MATRIX.
+C     IWM      = INTEGER WORK SPACE CONTAINING
+C                MATRIX INFORMATION
+C     RES      = NAME OF THE EXTERNAL USER-SUPPLIED ROUTINE
+C                TO EVALUATE THE RESIDUAL FUNCTION G(X,Y,YPRIME)
+C     IRES     = FLAG WHICH IS EQUAL TO ZERO IF NO ILLEGAL VALUES
+C                IN RES, AND LESS THAN ZERO OTHERWISE.  (IF IRES
+C                IS LESS THAN ZERO, THE MATRIX WAS NOT COMPLETED)
+C                IN THIS CASE (IF IRES .LT. 0), THEN IER = 0.
+C     UROUND   = THE UNIT ROUNDOFF ERROR OF THE MACHINE BEING USED.
+C     JAC      = NAME OF THE EXTERNAL USER-SUPPLIED ROUTINE
+C                TO EVALUATE THE ITERATION MATRIX (THIS ROUTINE
+C                IS ONLY USED IF IWM(MTYPE) IS 1 OR 4)
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED  DGBTRF, DGETRF
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901010  Modified three MAX calls to be all on one line.  (FNF)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C   901101  Corrected PURPOSE.  (FNF)
+C   020204  Convert to use LAPACK
+C***END PROLOGUE  DDAJAC
+C
+      INTEGER  NEQ, IER, IWM(*), IRES, IPAR(*), NTEMP
+      DOUBLE PRECISION
+     *   X, Y(*), YPRIME(*), DELTA(*), CJ, H, WT(*), E(*), WM(*),
+     *   UROUND, RPAR(*)
+      EXTERNAL  RES, JAC
+C
+      EXTERNAL  DGBTRF, DGETRF
+C
+      INTEGER  I, I1, I2, II, IPSAVE, ISAVE, J, K, L, LENPD, LIPVT,
+     *   LML, LMTYPE, LMU, MBA, MBAND, MEB1, MEBAND, MSAVE, MTYPE, N,
+     *   NPD, NPDM1, NROW
+      DOUBLE PRECISION  DEL, DELINV, SQUR, YPSAVE, YSAVE
+C
+      PARAMETER (NPD=1)
+      PARAMETER (LML=1)
+      PARAMETER (LMU=2)
+      PARAMETER (LMTYPE=4)
+      PARAMETER (LIPVT=22)
+C
+C***FIRST EXECUTABLE STATEMENT  DDAJAC
+      IER = 0
+      NPDM1=NPD-1
+      MTYPE=IWM(LMTYPE)
+      GO TO (100,200,300,400,500),MTYPE
+C
+C
+C     DENSE USER-SUPPLIED MATRIX
+100   LENPD=NEQ*NEQ
+      DO 110 I=1,LENPD
+110      WM(NPDM1+I)=0.0D0
+      CALL JAC(X,Y,YPRIME,WM(NPD),CJ,RPAR,IPAR)
+      GO TO 230
+C
+C
+C     DENSE FINITE-DIFFERENCE-GENERATED MATRIX
+200   IRES=0
+      NROW=NPDM1
+      SQUR = SQRT(UROUND)
+      DO 210 I=1,NEQ
+         DEL=SQUR*MAX(ABS(Y(I)),ABS(H*YPRIME(I)),ABS(WT(I)))
+         DEL=SIGN(DEL,H*YPRIME(I))
+         DEL=(Y(I)+DEL)-Y(I)
+         YSAVE=Y(I)
+         YPSAVE=YPRIME(I)
+         Y(I)=Y(I)+DEL
+         YPRIME(I)=YPRIME(I)+CJ*DEL
+         CALL RES(X,Y,YPRIME,E,IRES,RPAR,IPAR)
+         IF (IRES .LT. 0) RETURN
+         DELINV=1.0D0/DEL
+         DO 220 L=1,NEQ
+220      WM(NROW+L)=(E(L)-DELTA(L))*DELINV
+      NROW=NROW+NEQ
+      Y(I)=YSAVE
+      YPRIME(I)=YPSAVE
+210   CONTINUE
+C
+C
+C     DO DENSE-MATRIX LU DECOMPOSITION ON PD
+230      CALL DGETRF( NEQ, NEQ, WM(NPD), NEQ, IWM(LIPVT), IER)
+      RETURN
+C
+C
+C     DUMMY SECTION FOR IWM(MTYPE)=3
+300   RETURN
+C
+C
+C     BANDED USER-SUPPLIED MATRIX
+400   LENPD=(2*IWM(LML)+IWM(LMU)+1)*NEQ
+      DO 410 I=1,LENPD
+410      WM(NPDM1+I)=0.0D0
+      CALL JAC(X,Y,YPRIME,WM(NPD),CJ,RPAR,IPAR)
+      MEBAND=2*IWM(LML)+IWM(LMU)+1
+      GO TO 550
+C
+C
+C     BANDED FINITE-DIFFERENCE-GENERATED MATRIX
+500   MBAND=IWM(LML)+IWM(LMU)+1
+      MBA=MIN(MBAND,NEQ)
+      MEBAND=MBAND+IWM(LML)
+      MEB1=MEBAND-1
+      MSAVE=(NEQ/MBAND)+1
+      ISAVE=NTEMP-1
+      IPSAVE=ISAVE+MSAVE
+      IRES=0
+      SQUR=SQRT(UROUND)
+      DO 540 J=1,MBA
+         DO 510 N=J,NEQ,MBAND
+          K= (N-J)/MBAND + 1
+          WM(ISAVE+K)=Y(N)
+          WM(IPSAVE+K)=YPRIME(N)
+          DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),ABS(WT(N)))
+          DEL=SIGN(DEL,H*YPRIME(N))
+          DEL=(Y(N)+DEL)-Y(N)
+          Y(N)=Y(N)+DEL
+510       YPRIME(N)=YPRIME(N)+CJ*DEL
+      CALL RES(X,Y,YPRIME,E,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) RETURN
+      DO 530 N=J,NEQ,MBAND
+          K= (N-J)/MBAND + 1
+          Y(N)=WM(ISAVE+K)
+          YPRIME(N)=WM(IPSAVE+K)
+          DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),ABS(WT(N)))
+          DEL=SIGN(DEL,H*YPRIME(N))
+          DEL=(Y(N)+DEL)-Y(N)
+          DELINV=1.0D0/DEL
+          I1=MAX(1,(N-IWM(LMU)))
+          I2=MIN(NEQ,(N+IWM(LML)))
+          II=N*MEB1-IWM(LML)+NPDM1
+          DO 520 I=I1,I2
+520         WM(II+I)=(E(I)-DELTA(I))*DELINV
+530      CONTINUE
+540   CONTINUE
+C
+C
+C     DO LU DECOMPOSITION OF BANDED PD
+550   CALL DGBTRF(NEQ, NEQ, IWM(LML), IWM(LMU), WM(NPD), MEBAND,
+     *     IWM(LIPVT), IER)
+      RETURN
+C------END OF SUBROUTINE DDAJAC------
+      END
diff --git a/libcruft/dassl/ddanrm.f b/libcruft/dassl/ddanrm.f
new file mode 100644
index 0000000..2f989af
--- /dev/null
+++ b/libcruft/dassl/ddanrm.f
@@ -0,0 +1,45 @@
+      DOUBLE PRECISION FUNCTION DDANRM (NEQ, V, WT, RPAR, IPAR)
+C***BEGIN PROLOGUE  DDANRM
+C***SUBSIDIARY
+C***PURPOSE  Compute vector norm for DDASSL.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDANRM-S, DDANRM-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------------
+C     THIS FUNCTION ROUTINE COMPUTES THE WEIGHTED
+C     ROOT-MEAN-SQUARE NORM OF THE VECTOR OF LENGTH
+C     NEQ CONTAINED IN THE ARRAY V,WITH WEIGHTS
+C     CONTAINED IN THE ARRAY WT OF LENGTH NEQ.
+C        DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C***END PROLOGUE  DDANRM
+C
+      INTEGER  NEQ, IPAR(*)
+      DOUBLE PRECISION  V(NEQ), WT(NEQ), RPAR(*)
+C
+      INTEGER  I
+      DOUBLE PRECISION  SUM, VMAX
+C
+C***FIRST EXECUTABLE STATEMENT  DDANRM
+      DDANRM = 0.0D0
+      VMAX = 0.0D0
+      DO 10 I = 1,NEQ
+        IF(ABS(V(I)/WT(I)) .GT. VMAX) VMAX = ABS(V(I)/WT(I))
+10      CONTINUE
+      IF(VMAX .LE. 0.0D0) GO TO 30
+      SUM = 0.0D0
+      DO 20 I = 1,NEQ
+20      SUM = SUM + ((V(I)/WT(I))/VMAX)**2
+      DDANRM = VMAX*SQRT(SUM/NEQ)
+30    CONTINUE
+      RETURN
+C------END OF FUNCTION DDANRM------
+      END
diff --git a/libcruft/dassl/ddaslv.f b/libcruft/dassl/ddaslv.f
new file mode 100644
index 0000000..0df24aa
--- /dev/null
+++ b/libcruft/dassl/ddaslv.f
@@ -0,0 +1,62 @@
+      SUBROUTINE DDASLV (NEQ, DELTA, WM, IWM)
+C***BEGIN PROLOGUE  DDASLV
+C***SUBSIDIARY
+C***PURPOSE  Linear system solver for DDASSL.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDASLV-S, DDASLV-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------------
+C     THIS ROUTINE MANAGES THE SOLUTION OF THE LINEAR
+C     SYSTEM ARISING IN THE NEWTON ITERATION.
+C     MATRICES AND REAL TEMPORARY STORAGE AND
+C     REAL INFORMATION ARE STORED IN THE ARRAY WM.
+C     INTEGER MATRIX INFORMATION IS STORED IN
+C     THE ARRAY IWM.
+C     FOR A DENSE MATRIX, THE LAPACK ROUTINE
+C     DGETRS IS CALLED.
+C     FOR A BANDED MATRIX,THE LAPACK ROUTINE
+C     DGBTRS IS CALLED.
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED  DGBTRS, DGETRF
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C   020204  Convert to use LAPACK
+C***END PROLOGUE  DDASLV
+C
+      INTEGER  NEQ, IWM(*)
+      DOUBLE PRECISION  DELTA(*), WM(*)
+C
+      EXTERNAL  DGBTRS, DGETRS
+C
+      INTEGER  LIPVT, LML, LMU, LMTYPE, MEBAND, MTYPE, NPD, INFO
+      PARAMETER (NPD=1)
+      PARAMETER (LML=1)
+      PARAMETER (LMU=2)
+      PARAMETER (LMTYPE=4)
+      PARAMETER (LIPVT=22)
+C
+C***FIRST EXECUTABLE STATEMENT  DDASLV
+      MTYPE=IWM(LMTYPE)
+      GO TO(100,100,300,400,400),MTYPE
+C
+C     DENSE MATRIX
+100   CALL DGETRS('N', NEQ, 1, WM(NPD), NEQ, IWM(LIPVT), DELTA, NEQ, 
+     *     INFO)
+      RETURN
+C
+C     DUMMY SECTION FOR MTYPE=3
+300   CONTINUE
+      RETURN
+C
+C     BANDED MATRIX
+400   MEBAND=2*IWM(LML)+IWM(LMU)+1
+      CALL DGBTRS ('N', NEQ, IWM(LML), IWM(LMU), 1, WM(NPD), MEBAND, 
+     *     IWM(LIPVT), DELTA, NEQ, INLPCK)
+      RETURN
+C------END OF SUBROUTINE DDASLV------
+      END
diff --git a/libcruft/dassl/ddassl.f b/libcruft/dassl/ddassl.f
new file mode 100644
index 0000000..0ed5c42
--- /dev/null
+++ b/libcruft/dassl/ddassl.f
@@ -0,0 +1,1617 @@
+      SUBROUTINE DDASSL (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
+     +   IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
+C***BEGIN PROLOGUE  DDASSL
+C***PURPOSE  This code solves a system of differential/algebraic
+C            equations of the form G(T,Y,YPRIME) = 0.
+C***LIBRARY   SLATEC (DASSL)
+C***CATEGORY  I1A2
+C***TYPE      DOUBLE PRECISION (SDASSL-S, DDASSL-D)
+C***KEYWORDS  DIFFERENTIAL/ALGEBRAIC, BACKWARD DIFFERENTIATION FORMULAS,
+C             IMPLICIT DIFFERENTIAL SYSTEMS
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C             COMPUTING AND MATHEMATICS RESEARCH DIVISION
+C             LAWRENCE LIVERMORE NATIONAL LABORATORY
+C             L - 316, P.O. BOX 808,
+C             LIVERMORE, CA.    94550
+C***DESCRIPTION
+C
+C *Usage:
+C
+C      EXTERNAL RES, JAC
+C      INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR
+C      DOUBLE PRECISION T, Y(NEQ), YPRIME(NEQ), TOUT, RTOL, ATOL,
+C     *   RWORK(LRW), RPAR
+C
+C      CALL DDASSL (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
+C     *   IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
+C
+C
+C *Arguments:
+C  (In the following, all real arrays should be type DOUBLE PRECISION.)
+C
+C  RES:EXT     This is a subroutine which you provide to define the
+C              differential/algebraic system.
+C
+C  NEQ:IN      This is the number of equations to be solved.
+C
+C  T:INOUT     This is the current value of the independent variable.
+C
+C  Y(*):INOUT  This array contains the solution components at T.
+C
+C  YPRIME(*):INOUT  This array contains the derivatives of the solution
+C              components at T.
+C
+C  TOUT:IN     This is a point at which a solution is desired.
+C
+C  INFO(N):IN  The basic task of the code is to solve the system from T
+C              to TOUT and return an answer at TOUT.  INFO is an integer
+C              array which is used to communicate exactly how you want
+C              this task to be carried out.  (See below for details.)
+C              N must be greater than or equal to 15.
+C
+C  RTOL,ATOL:INOUT  These quantities represent relative and absolute
+C              error tolerances which you provide to indicate how
+C              accurately you wish the solution to be computed.  You
+C              may choose them to be both scalars or else both vectors.
+C              Caution:  In Fortran 77, a scalar is not the same as an
+C                        array of length 1.  Some compilers may object
+C                        to using scalars for RTOL,ATOL.
+C
+C  IDID:OUT    This scalar quantity is an indicator reporting what the
+C              code did.  You must monitor this integer variable to
+C              decide  what action to take next.
+C
+C  RWORK:WORK  A real work array of length LRW which provides the
+C              code with needed storage space.
+C
+C  LRW:IN      The length of RWORK.  (See below for required length.)
+C
+C  IWORK:WORK  An integer work array of length LIW which probides the
+C              code with needed storage space.
+C
+C  LIW:IN      The length of IWORK.  (See below for required length.)
+C
+C  RPAR,IPAR:IN  These are real and integer parameter arrays which
+C              you can use for communication between your calling
+C              program and the RES subroutine (and the JAC subroutine)
+C
+C  JAC:EXT     This is the name of a subroutine which you may choose
+C              to provide for defining a matrix of partial derivatives
+C              described below.
+C
+C  Quantities which may be altered by DDASSL are:
+C     T, Y(*), YPRIME(*), INFO(1), RTOL, ATOL,
+C     IDID, RWORK(*) AND IWORK(*)
+C
+C *Description
+C
+C  Subroutine DDASSL uses the backward differentiation formulas of
+C  orders one through five to solve a system of the above form for Y and
+C  YPRIME.  Values for Y and YPRIME at the initial time must be given as
+C  input.  These values must be consistent, (that is, if T,Y,YPRIME are
+C  the given initial values, they must satisfy G(T,Y,YPRIME) = 0.).  The
+C  subroutine solves the system from T to TOUT.  It is easy to continue
+C  the solution to get results at additional TOUT.  This is the interval
+C  mode of operation.  Intermediate results can also be obtained easily
+C  by using the intermediate-output capability.
+C
+C  The following detailed description is divided into subsections:
+C    1. Input required for the first call to DDASSL.
+C    2. Output after any return from DDASSL.
+C    3. What to do to continue the integration.
+C    4. Error messages.
+C
+C
+C  -------- INPUT -- WHAT TO DO ON THE FIRST CALL TO DDASSL ------------
+C
+C  The first call of the code is defined to be the start of each new
+C  problem. Read through the descriptions of all the following items,
+C  provide sufficient storage space for designated arrays, set
+C  appropriate variables for the initialization of the problem, and
+C  give information about how you want the problem to be solved.
+C
+C
+C  RES -- Provide a subroutine of the form
+C             SUBROUTINE RES(T,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
+C         to define the system of differential/algebraic
+C         equations which is to be solved. For the given values
+C         of T,Y and YPRIME, the subroutine should
+C         return the residual of the defferential/algebraic
+C         system
+C             DELTA = G(T,Y,YPRIME)
+C         (DELTA(*) is a vector of length NEQ which is
+C         output for RES.)
+C
+C         Subroutine RES must not alter T,Y or YPRIME.
+C         You must declare the name RES in an external
+C         statement in your program that calls DDASSL.
+C         You must dimension Y,YPRIME and DELTA in RES.
+C
+C         IRES is an integer flag which is always equal to
+C         zero on input. Subroutine RES should alter IRES
+C         only if it encounters an illegal value of Y or
+C         a stop condition. Set IRES = -1 if an input value
+C         is illegal, and DDASSL will try to solve the problem
+C         without getting IRES = -1. If IRES = -2, DDASSL
+C         will return control to the calling program
+C         with IDID = -11.
+C
+C         RPAR and IPAR are real and integer parameter arrays which
+C         you can use for communication between your calling program
+C         and subroutine RES. They are not altered by DDASSL. If you
+C         do not need RPAR or IPAR, ignore these parameters by treat-
+C         ing them as dummy arguments. If you do choose to use them,
+C         dimension them in your calling program and in RES as arrays
+C         of appropriate length.
+C
+C  NEQ -- Set it to the number of differential equations.
+C         (NEQ .GE. 1)
+C
+C  T -- Set it to the initial point of the integration.
+C         T must be defined as a variable.
+C
+C  Y(*) -- Set this vector to the initial values of the NEQ solution
+C         components at the initial point. You must dimension Y of
+C         length at least NEQ in your calling program.
+C
+C  YPRIME(*) -- Set this vector to the initial values of the NEQ
+C         first derivatives of the solution components at the initial
+C         point.  You must dimension YPRIME at least NEQ in your
+C         calling program. If you do not know initial values of some
+C         of the solution components, see the explanation of INFO(11).
+C
+C  TOUT -- Set it to the first point at which a solution
+C         is desired. You can not take TOUT = T.
+C         integration either forward in T (TOUT .GT. T) or
+C         backward in T (TOUT .LT. T) is permitted.
+C
+C         The code advances the solution from T to TOUT using
+C         step sizes which are automatically selected so as to
+C         achieve the desired accuracy. If you wish, the code will
+C         return with the solution and its derivative at
+C         intermediate steps (intermediate-output mode) so that
+C         you can monitor them, but you still must provide TOUT in
+C         accord with the basic aim of the code.
+C
+C         The first step taken by the code is a critical one
+C         because it must reflect how fast the solution changes near
+C         the initial point. The code automatically selects an
+C         initial step size which is practically always suitable for
+C         the problem. By using the fact that the code will not step
+C         past TOUT in the first step, you could, if necessary,
+C         restrict the length of the initial step size.
+C
+C         For some problems it may not be permissible to integrate
+C         past a point TSTOP because a discontinuity occurs there
+C         or the solution or its derivative is not defined beyond
+C         TSTOP. When you have declared a TSTOP point (SEE INFO(4)
+C         and RWORK(1)), you have told the code not to integrate
+C         past TSTOP. In this case any TOUT beyond TSTOP is invalid
+C         input.
+C
+C  INFO(*) -- Use the INFO array to give the code more details about
+C         how you want your problem solved.  This array should be
+C         dimensioned of length 15, though DDASSL uses only the first
+C         eleven entries.  You must respond to all of the following
+C         items, which are arranged as questions.  The simplest use
+C         of the code corresponds to answering all questions as yes,
+C         i.e. setting all entries of INFO to 0.
+C
+C       INFO(1) - This parameter enables the code to initialize
+C              itself. You must set it to indicate the start of every
+C              new problem.
+C
+C          **** Is this the first call for this problem ...
+C                Yes - Set INFO(1) = 0
+C                 No - Not applicable here.
+C                      See below for continuation calls.  ****
+C
+C       INFO(2) - How much accuracy you want of your solution
+C              is specified by the error tolerances RTOL and ATOL.
+C              The simplest use is to take them both to be scalars.
+C              To obtain more flexibility, they can both be vectors.
+C              The code must be told your choice.
+C
+C          **** Are both error tolerances RTOL, ATOL scalars ...
+C                Yes - Set INFO(2) = 0
+C                      and input scalars for both RTOL and ATOL
+C                 No - Set INFO(2) = 1
+C                      and input arrays for both RTOL and ATOL ****
+C
+C       INFO(3) - The code integrates from T in the direction
+C              of TOUT by steps. If you wish, it will return the
+C              computed solution and derivative at the next
+C              intermediate step (the intermediate-output mode) or
+C              TOUT, whichever comes first. This is a good way to
+C              proceed if you want to see the behavior of the solution.
+C              If you must have solutions at a great many specific
+C              TOUT points, this code will compute them efficiently.
+C
+C          **** Do you want the solution only at
+C                TOUT (and not at the next intermediate step) ...
+C                 Yes - Set INFO(3) = 0
+C                  No - Set INFO(3) = 1 ****
+C
+C       INFO(4) - To handle solutions at a great many specific
+C              values TOUT efficiently, this code may integrate past
+C              TOUT and interpolate to obtain the result at TOUT.
+C              Sometimes it is not possible to integrate beyond some
+C              point TSTOP because the equation changes there or it is
+C              not defined past TSTOP. Then you must tell the code
+C              not to go past.
+C
+C           **** Can the integration be carried out without any
+C                restrictions on the independent variable T ...
+C                 Yes - Set INFO(4)=0
+C                  No - Set INFO(4)=1
+C                       and define the stopping point TSTOP by
+C                       setting RWORK(1)=TSTOP ****
+C
+C       INFO(5) - To solve differential/algebraic problems it is
+C              necessary to use a matrix of partial derivatives of the
+C              system of differential equations. If you do not
+C              provide a subroutine to evaluate it analytically (see
+C              description of the item JAC in the call list), it will
+C              be approximated by numerical differencing in this code.
+C              although it is less trouble for you to have the code
+C              compute partial derivatives by numerical differencing,
+C              the solution will be more reliable if you provide the
+C              derivatives via JAC. Sometimes numerical differencing
+C              is cheaper than evaluating derivatives in JAC and
+C              sometimes it is not - this depends on your problem.
+C
+C           **** Do you want the code to evaluate the partial
+C                derivatives automatically by numerical differences ...
+C                   Yes - Set INFO(5)=0
+C                    No - Set INFO(5)=1
+C                  and provide subroutine JAC for evaluating the
+C                  matrix of partial derivatives ****
+C
+C       INFO(6) - DDASSL will perform much better if the matrix of
+C              partial derivatives, DG/DY + CJ*DG/DYPRIME,
+C              (here CJ is a scalar determined by DDASSL)
+C              is banded and the code is told this. In this
+C              case, the storage needed will be greatly reduced,
+C              numerical differencing will be performed much cheaper,
+C              and a number of important algorithms will execute much
+C              faster. The differential equation is said to have
+C              half-bandwidths ML (lower) and MU (upper) if equation i
+C              involves only unknowns Y(J) with
+C                             I-ML .LE. J .LE. I+MU
+C              for all I=1,2,...,NEQ. Thus, ML and MU are the widths
+C              of the lower and upper parts of the band, respectively,
+C              with the main diagonal being excluded. If you do not
+C              indicate that the equation has a banded matrix of partial
+C              derivatives, the code works with a full matrix of NEQ**2
+C              elements (stored in the conventional way). Computations
+C              with banded matrices cost less time and storage than with
+C              full matrices if 2*ML+MU .LT. NEQ. If you tell the
+C              code that the matrix of partial derivatives has a banded
+C              structure and you want to provide subroutine JAC to
+C              compute the partial derivatives, then you must be careful
+C              to store the elements of the matrix in the special form
+C              indicated in the description of JAC.
+C
+C          **** Do you want to solve the problem using a full
+C               (dense) matrix (and not a special banded
+C               structure) ...
+C                Yes - Set INFO(6)=0
+C                 No - Set INFO(6)=1
+C                       and provide the lower (ML) and upper (MU)
+C                       bandwidths by setting
+C                       IWORK(1)=ML
+C                       IWORK(2)=MU ****
+C
+C
+C        INFO(7) -- You can specify a maximum (absolute value of)
+C              stepsize, so that the code
+C              will avoid passing over very
+C              large regions.
+C
+C          ****  Do you want the code to decide
+C                on its own maximum stepsize?
+C                Yes - Set INFO(7)=0
+C                 No - Set INFO(7)=1
+C                      and define HMAX by setting
+C                      RWORK(2)=HMAX ****
+C
+C        INFO(8) -- Differential/algebraic problems
+C              may occaisionally suffer from
+C              severe scaling difficulties on the
+C              first step. If you know a great deal
+C              about the scaling of your problem, you can
+C              help to alleviate this problem by
+C              specifying an initial stepsize HO.
+C
+C          ****  Do you want the code to define
+C                its own initial stepsize?
+C                Yes - Set INFO(8)=0
+C                 No - Set INFO(8)=1
+C                      and define HO by setting
+C                      RWORK(3)=HO ****
+C
+C        INFO(9) -- If storage is a severe problem,
+C              you can save some locations by
+C              restricting the maximum order MAXORD.
+C              the default value is 5. for each
+C              order decrease below 5, the code
+C              requires NEQ fewer locations, however
+C              it is likely to be slower. In any
+C              case, you must have 1 .LE. MAXORD .LE. 5
+C          ****  Do you want the maximum order to
+C                default to 5?
+C                Yes - Set INFO(9)=0
+C                 No - Set INFO(9)=1
+C                      and define MAXORD by setting
+C                      IWORK(3)=MAXORD ****
+C
+C        INFO(10) --If you know that the solutions to your equations
+C               will always be nonnegative, it may help to set this
+C               parameter. However, it is probably best to
+C               try the code without using this option first,
+C               and only to use this option if that doesn't
+C               work very well.
+C           ****  Do you want the code to solve the problem without
+C                 invoking any special nonnegativity constraints?
+C                  Yes - Set INFO(10)=0
+C                   No - Set INFO(10)=1
+C
+C        INFO(11) --DDASSL normally requires the initial T,
+C               Y, and YPRIME to be consistent. That is,
+C               you must have G(T,Y,YPRIME) = 0 at the initial
+C               time. If you do not know the initial
+C               derivative precisely, you can let DDASSL try
+C               to compute it.
+C          ****   Are the initialHE INITIAL T, Y, YPRIME consistent?
+C                 Yes - Set INFO(11) = 0
+C                  No - Set INFO(11) = 1,
+C                       and set YPRIME to an initial approximation
+C                       to YPRIME.  (If you have no idea what
+C                       YPRIME should be, set it to zero. Note
+C                       that the initial Y should be such
+C                       that there must exist a YPRIME so that
+C                       G(T,Y,YPRIME) = 0.)
+C
+C  RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL
+C         error tolerances to tell the code how accurately you
+C         want the solution to be computed.  They must be defined
+C         as variables because the code may change them.  You
+C         have two choices --
+C               Both RTOL and ATOL are scalars. (INFO(2)=0)
+C               Both RTOL and ATOL are vectors. (INFO(2)=1)
+C         in either case all components must be non-negative.
+C
+C         The tolerances are used by the code in a local error
+C         test at each step which requires roughly that
+C               ABS(LOCAL ERROR) .LE. RTOL*ABS(Y)+ATOL
+C         for each vector component.
+C         (More specifically, a root-mean-square norm is used to
+C         measure the size of vectors, and the error test uses the
+C         magnitude of the solution at the beginning of the step.)
+C
+C         The true (global) error is the difference between the
+C         true solution of the initial value problem and the
+C         computed approximation.  Practically all present day
+C         codes, including this one, control the local error at
+C         each step and do not even attempt to control the global
+C         error directly.
+C         Usually, but not always, the true accuracy of the
+C         computed Y is comparable to the error tolerances. This
+C         code will usually, but not always, deliver a more
+C         accurate solution if you reduce the tolerances and
+C         integrate again.  By comparing two such solutions you
+C         can get a fairly reliable idea of the true error in the
+C         solution at the bigger tolerances.
+C
+C         Setting ATOL=0. results in a pure relative error test on
+C         that component.  Setting RTOL=0. results in a pure
+C         absolute error test on that component.  A mixed test
+C         with non-zero RTOL and ATOL corresponds roughly to a
+C         relative error test when the solution component is much
+C         bigger than ATOL and to an absolute error test when the
+C         solution component is smaller than the threshhold ATOL.
+C
+C         The code will not attempt to compute a solution at an
+C         accuracy unreasonable for the machine being used.  It will
+C         advise you if you ask for too much accuracy and inform
+C         you as to the maximum accuracy it believes possible.
+C
+C  RWORK(*) --  Dimension this real work array of length LRW in your
+C         calling program.
+C
+C  LRW -- Set it to the declared length of the RWORK array.
+C               You must have
+C                    LRW .GE. 40+(MAXORD+4)*NEQ+NEQ**2
+C               for the full (dense) JACOBIAN case (when INFO(6)=0), or
+C                    LRW .GE. 40+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
+C               for the banded user-defined JACOBIAN case
+C               (when INFO(5)=1 and INFO(6)=1), or
+C                     LRW .GE. 40+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
+C                           +2*(NEQ/(ML+MU+1)+1)
+C               for the banded finite-difference-generated JACOBIAN case
+C               (when INFO(5)=0 and INFO(6)=1)
+C
+C  IWORK(*) --  Dimension this integer work array of length LIW in
+C         your calling program.
+C
+C  LIW -- Set it to the declared length of the IWORK array.
+C               You must have LIW .GE. 21+NEQ
+C
+C  RPAR, IPAR -- These are parameter arrays, of real and integer
+C         type, respectively.  You can use them for communication
+C         between your program that calls DDASSL and the
+C         RES subroutine (and the JAC subroutine).  They are not
+C         altered by DDASSL.  If you do not need RPAR or IPAR,
+C         ignore these parameters by treating them as dummy
+C         arguments.  If you do choose to use them, dimension
+C         them in your calling program and in RES (and in JAC)
+C         as arrays of appropriate length.
+C
+C  JAC -- If you have set INFO(5)=0, you can ignore this parameter
+C         by treating it as a dummy argument.  Otherwise, you must
+C         provide a subroutine of the form
+C             SUBROUTINE JAC(T,Y,YPRIME,PD,CJ,RPAR,IPAR)
+C         to define the matrix of partial derivatives
+C             PD=DG/DY+CJ*DG/DYPRIME
+C         CJ is a scalar which is input to JAC.
+C         For the given values of T,Y,YPRIME, the
+C         subroutine must evaluate the non-zero partial
+C         derivatives for each equation and each solution
+C         component, and store these values in the
+C         matrix PD.  The elements of PD are set to zero
+C         before each call to JAC so only non-zero elements
+C         need to be defined.
+C
+C         Subroutine JAC must not alter T,Y,(*),YPRIME(*), or CJ.
+C         You must declare the name JAC in an EXTERNAL statement in
+C         your program that calls DDASSL.  You must dimension Y,
+C         YPRIME and PD in JAC.
+C
+C         The way you must store the elements into the PD matrix
+C         depends on the structure of the matrix which you
+C         indicated by INFO(6).
+C               *** INFO(6)=0 -- Full (dense) matrix ***
+C                   Give PD a first dimension of NEQ.
+C                   When you evaluate the (non-zero) partial derivative
+C                   of equation I with respect to variable J, you must
+C                   store it in PD according to
+C                   PD(I,J) = "DG(I)/DY(J)+CJ*DG(I)/DYPRIME(J)"
+C               *** INFO(6)=1 -- Banded JACOBIAN with ML lower and MU
+C                   upper diagonal bands (refer to INFO(6) description
+C                   of ML and MU) ***
+C                   Give PD a first dimension of 2*ML+MU+1.
+C                   when you evaluate the (non-zero) partial derivative
+C                   of equation I with respect to variable J, you must
+C                   store it in PD according to
+C                   IROW = I - J + ML + MU + 1
+C                   PD(IROW,J) = "DG(I)/DY(J)+CJ*DG(I)/DYPRIME(J)"
+C
+C         RPAR and IPAR are real and integer parameter arrays
+C         which you can use for communication between your calling
+C         program and your JACOBIAN subroutine JAC. They are not
+C         altered by DDASSL. If you do not need RPAR or IPAR,
+C         ignore these parameters by treating them as dummy
+C         arguments. If you do choose to use them, dimension
+C         them in your calling program and in JAC as arrays of
+C         appropriate length.
+C
+C
+C  OPTIONALLY REPLACEABLE NORM ROUTINE:
+C
+C     DDASSL uses a weighted norm DDANRM to measure the size
+C     of vectors such as the estimated error in each step.
+C     A FUNCTION subprogram
+C       DOUBLE PRECISION FUNCTION DDANRM(NEQ,V,WT,RPAR,IPAR)
+C       DIMENSION V(NEQ),WT(NEQ)
+C     is used to define this norm. Here, V is the vector
+C     whose norm is to be computed, and WT is a vector of
+C     weights.  A DDANRM routine has been included with DDASSL
+C     which computes the weighted root-mean-square norm
+C     given by
+C       DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
+C     this norm is suitable for most problems. In some
+C     special cases, it may be more convenient and/or
+C     efficient to define your own norm by writing a function
+C     subprogram to be called instead of DDANRM. This should,
+C     however, be attempted only after careful thought and
+C     consideration.
+C
+C
+C  -------- OUTPUT -- AFTER ANY RETURN FROM DDASSL ---------------------
+C
+C  The principal aim of the code is to return a computed solution at
+C  TOUT, although it is also possible to obtain intermediate results
+C  along the way. To find out whether the code achieved its goal
+C  or if the integration process was interrupted before the task was
+C  completed, you must check the IDID parameter.
+C
+C
+C  T -- The solution was successfully advanced to the
+C               output value of T.
+C
+C  Y(*) -- Contains the computed solution approximation at T.
+C
+C  YPRIME(*) -- Contains the computed derivative
+C               approximation at T.
+C
+C  IDID -- Reports what the code did.
+C
+C                     *** Task completed ***
+C                Reported by positive values of IDID
+C
+C           IDID = 1 -- A step was successfully taken in the
+C                   intermediate-output mode. The code has not
+C                   yet reached TOUT.
+C
+C           IDID = 2 -- The integration to TSTOP was successfully
+C                   completed (T=TSTOP) by stepping exactly to TSTOP.
+C
+C           IDID = 3 -- The integration to TOUT was successfully
+C                   completed (T=TOUT) by stepping past TOUT.
+C                   Y(*) is obtained by interpolation.
+C                   YPRIME(*) is obtained by interpolation.
+C
+C                    *** Task interrupted ***
+C                Reported by negative values of IDID
+C
+C           IDID = -1 -- A large amount of work has been expended.
+C                   (About 500 steps)
+C
+C           IDID = -2 -- The error tolerances are too stringent.
+C
+C           IDID = -3 -- The local error test cannot be satisfied
+C                   because you specified a zero component in ATOL
+C                   and the corresponding computed solution
+C                   component is zero. Thus, a pure relative error
+C                   test is impossible for this component.
+C
+C           IDID = -6 -- DDASSL had repeated error test
+C                   failures on the last attempted step.
+C
+C           IDID = -7 -- The corrector could not converge.
+C
+C           IDID = -8 -- The matrix of partial derivatives
+C                   is singular.
+C
+C           IDID = -9 -- The corrector could not converge.
+C                   there were repeated error test failures
+C                   in this step.
+C
+C           IDID =-10 -- The corrector could not converge
+C                   because IRES was equal to minus one.
+C
+C           IDID =-11 -- IRES equal to -2 was encountered
+C                   and control is being returned to the
+C                   calling program.
+C
+C           IDID =-12 -- DDASSL failed to compute the initial
+C                   YPRIME.
+C
+C
+C
+C           IDID = -13,..,-32 -- Not applicable for this code
+C
+C                    *** Task terminated ***
+C                Reported by the value of IDID=-33
+C
+C           IDID = -33 -- The code has encountered trouble from which
+C                   it cannot recover. A message is printed
+C                   explaining the trouble and control is returned
+C                   to the calling program. For example, this occurs
+C                   when invalid input is detected.
+C
+C  RTOL, ATOL -- These quantities remain unchanged except when
+C               IDID = -2. In this case, the error tolerances have been
+C               increased by the code to values which are estimated to
+C               be appropriate for continuing the integration. However,
+C               the reported solution at T was obtained using the input
+C               values of RTOL and ATOL.
+C
+C  RWORK, IWORK -- Contain information which is usually of no
+C               interest to the user but necessary for subsequent calls.
+C               However, you may find use for
+C
+C               RWORK(3)--Which contains the step size H to be
+C                       attempted on the next step.
+C
+C               RWORK(4)--Which contains the current value of the
+C                       independent variable, i.e., the farthest point
+C                       integration has reached. This will be different
+C                       from T only when interpolation has been
+C                       performed (IDID=3).
+C
+C               RWORK(7)--Which contains the stepsize used
+C                       on the last successful step.
+C
+C               IWORK(7)--Which contains the order of the method to
+C                       be attempted on the next step.
+C
+C               IWORK(8)--Which contains the order of the method used
+C                       on the last step.
+C
+C               IWORK(11)--Which contains the number of steps taken so
+C                        far.
+C
+C               IWORK(12)--Which contains the number of calls to RES
+C                        so far.
+C
+C               IWORK(13)--Which contains the number of evaluations of
+C                        the matrix of partial derivatives needed so
+C                        far.
+C
+C               IWORK(14)--Which contains the total number
+C                        of error test failures so far.
+C
+C               IWORK(15)--Which contains the total number
+C                        of convergence test failures so far.
+C                        (includes singular iteration matrix
+C                        failures.)
+C
+C
+C  -------- INPUT -- WHAT TO DO TO CONTINUE THE INTEGRATION ------------
+C                    (CALLS AFTER THE FIRST)
+C
+C  This code is organized so that subsequent calls to continue the
+C  integration involve little (if any) additional effort on your
+C  part. You must monitor the IDID parameter in order to determine
+C  what to do next.
+C
+C  Recalling that the principal task of the code is to integrate
+C  from T to TOUT (the interval mode), usually all you will need
+C  to do is specify a new TOUT upon reaching the current TOUT.
+C
+C  Do not alter any quantity not specifically permitted below,
+C  in particular do not alter NEQ,T,Y(*),YPRIME(*),RWORK(*),IWORK(*)
+C  or the differential equation in subroutine RES. Any such
+C  alteration constitutes a new problem and must be treated as such,
+C  i.e., you must start afresh.
+C
+C  You cannot change from vector to scalar error control or vice
+C  versa (INFO(2)), but you can change the size of the entries of
+C  RTOL, ATOL. Increasing a tolerance makes the equation easier
+C  to integrate. Decreasing a tolerance will make the equation
+C  harder to integrate and should generally be avoided.
+C
+C  You can switch from the intermediate-output mode to the
+C  interval mode (INFO(3)) or vice versa at any time.
+C
+C  If it has been necessary to prevent the integration from going
+C  past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
+C  code will not integrate to any TOUT beyond the currently
+C  specified TSTOP. Once TSTOP has been reached you must change
+C  the value of TSTOP or set INFO(4)=0. You may change INFO(4)
+C  or TSTOP at any time but you must supply the value of TSTOP in
+C  RWORK(1) whenever you set INFO(4)=1.
+C
+C  Do not change INFO(5), INFO(6), IWORK(1), or IWORK(2)
+C  unless you are going to restart the code.
+C
+C                 *** Following a completed task ***
+C  If
+C     IDID = 1, call the code again to continue the integration
+C                  another step in the direction of TOUT.
+C
+C     IDID = 2 or 3, define a new TOUT and call the code again.
+C                  TOUT must be different from T. You cannot change
+C                  the direction of integration without restarting.
+C
+C                 *** Following an interrupted task ***
+C               To show the code that you realize the task was
+C               interrupted and that you want to continue, you
+C               must take appropriate action and set INFO(1) = 1
+C  If
+C    IDID = -1, The code has taken about 500 steps.
+C                  If you want to continue, set INFO(1) = 1 and
+C                  call the code again. An additional 500 steps
+C                  will be allowed.
+C
+C    IDID = -2, The error tolerances RTOL, ATOL have been
+C                  increased to values the code estimates appropriate
+C                  for continuing. You may want to change them
+C                  yourself. If you are sure you want to continue
+C                  with relaxed error tolerances, set INFO(1)=1 and
+C                  call the code again.
+C
+C    IDID = -3, A solution component is zero and you set the
+C                  corresponding component of ATOL to zero. If you
+C                  are sure you want to continue, you must first
+C                  alter the error criterion to use positive values
+C                  for those components of ATOL corresponding to zero
+C                  solution components, then set INFO(1)=1 and call
+C                  the code again.
+C
+C    IDID = -4,-5  --- Cannot occur with this code.
+C
+C    IDID = -6, Repeated error test failures occurred on the
+C                  last attempted step in DDASSL. A singularity in the
+C                  solution may be present. If you are absolutely
+C                  certain you want to continue, you should restart
+C                  the integration. (Provide initial values of Y and
+C                  YPRIME which are consistent)
+C
+C    IDID = -7, Repeated convergence test failures occurred
+C                  on the last attempted step in DDASSL. An inaccurate
+C                  or ill-conditioned JACOBIAN may be the problem. If
+C                  you are absolutely certain you want to continue, you
+C                  should restart the integration.
+C
+C    IDID = -8, The matrix of partial derivatives is singular.
+C                  Some of your equations may be redundant.
+C                  DDASSL cannot solve the problem as stated.
+C                  It is possible that the redundant equations
+C                  could be removed, and then DDASSL could
+C                  solve the problem. It is also possible
+C                  that a solution to your problem either
+C                  does not exist or is not unique.
+C
+C    IDID = -9, DDASSL had multiple convergence test
+C                  failures, preceeded by multiple error
+C                  test failures, on the last attempted step.
+C                  It is possible that your problem
+C                  is ill-posed, and cannot be solved
+C                  using this code. Or, there may be a
+C                  discontinuity or a singularity in the
+C                  solution. If you are absolutely certain
+C                  you want to continue, you should restart
+C                  the integration.
+C
+C    IDID =-10, DDASSL had multiple convergence test failures
+C                  because IRES was equal to minus one.
+C                  If you are absolutely certain you want
+C                  to continue, you should restart the
+C                  integration.
+C
+C    IDID =-11, IRES=-2 was encountered, and control is being
+C                  returned to the calling program.
+C
+C    IDID =-12, DDASSL failed to compute the initial YPRIME.
+C                  This could happen because the initial
+C                  approximation to YPRIME was not very good, or
+C                  if a YPRIME consistent with the initial Y
+C                  does not exist. The problem could also be caused
+C                  by an inaccurate or singular iteration matrix.
+C
+C    IDID = -13,..,-32  --- Cannot occur with this code.
+C
+C
+C                 *** Following a terminated task ***
+C
+C  If IDID= -33, you cannot continue the solution of this problem.
+C                  An attempt to do so will result in your
+C                  run being terminated.
+C
+C
+C  -------- ERROR MESSAGES ---------------------------------------------
+C
+C      The SLATEC error print routine XERMSG is called in the event of
+C   unsuccessful completion of a task.  Most of these are treated as
+C   "recoverable errors", which means that (unless the user has directed
+C   otherwise) control will be returned to the calling program for
+C   possible action after the message has been printed.
+C
+C   In the event of a negative value of IDID other than -33, an appro-
+C   priate message is printed and the "error number" printed by XERMSG
+C   is the value of IDID.  There are quite a number of illegal input
+C   errors that can lead to a returned value IDID=-33.  The conditions
+C   and their printed "error numbers" are as follows:
+C
+C   Error number       Condition
+C
+C        1       Some element of INFO vector is not zero or one.
+C        2       NEQ .le. 0
+C        3       MAXORD not in range.
+C        4       LRW is less than the required length for RWORK.
+C        5       LIW is less than the required length for IWORK.
+C        6       Some element of RTOL is .lt. 0
+C        7       Some element of ATOL is .lt. 0
+C        8       All elements of RTOL and ATOL are zero.
+C        9       INFO(4)=1 and TSTOP is behind TOUT.
+C       10       HMAX .lt. 0.0
+C       11       TOUT is behind T.
+C       12       INFO(8)=1 and H0=0.0
+C       13       Some element of WT is .le. 0.0
+C       14       TOUT is too close to T to start integration.
+C       15       INFO(4)=1 and TSTOP is behind T.
+C       16       --( Not used in this version )--
+C       17       ML illegal.  Either .lt. 0 or .gt. NEQ
+C       18       MU illegal.  Either .lt. 0 or .gt. NEQ
+C       19       TOUT = T.
+C
+C   If DDASSL is called again without any action taken to remove the
+C   cause of an unsuccessful return, XERMSG will be called with a fatal
+C   error flag, which will cause unconditional termination of the
+C   program.  There are two such fatal errors:
+C
+C   Error number -998:  The last step was terminated with a negative
+C       value of IDID other than -33, and no appropriate action was
+C       taken.
+C
+C   Error number -999:  The previous call was terminated because of
+C       illegal input (IDID=-33) and there is illegal input in the
+C       present call, as well.  (Suspect infinite loop.)
+C
+C  ---------------------------------------------------------------------
+C
+C***REFERENCES  A DESCRIPTION OF DASSL: A DIFFERENTIAL/ALGEBRAIC
+C                 SYSTEM SOLVER, L. R. PETZOLD, SAND82-8637,
+C                 SANDIA NATIONAL LABORATORIES, SEPTEMBER 1982.
+C***ROUTINES CALLED  D1MACH, DDAINI, DDANRM, DDASTP, DDATRP, DDAWTS,
+C                    XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   880387  Code changes made.  All common statements have been
+C           replaced by a DATA statement, which defines pointers into
+C           RWORK, and PARAMETER statements which define pointers
+C           into IWORK.  As well the documentation has gone through
+C           grammatical changes.
+C   881005  The prologue has been changed to mixed case.
+C           The subordinate routines had revision dates changed to
+C           this date, although the documentation for these routines
+C           is all upper case.  No code changes.
+C   890511  Code changes made.  The DATA statement in the declaration
+C           section of DDASSL was replaced with a PARAMETER
+C           statement.  Also the statement S = 100.D0 was removed
+C           from the top of the Newton iteration in DDASTP.
+C           The subordinate routines had revision dates changed to
+C           this date.
+C   890517  The revision date syntax was replaced with the revision
+C           history syntax.  Also the "DECK" comment was added to
+C           the top of all subroutines.  These changes are consistent
+C           with new SLATEC guidelines.
+C           The subordinate routines had revision dates changed to
+C           this date.  No code changes.
+C   891013  Code changes made.
+C           Removed all occurrances of FLOAT or DBLE.  All operations
+C           are now performed with "mixed-mode" arithmetic.
+C           Also, specific function names were replaced with generic
+C           function names to be consistent with new SLATEC guidelines.
+C           In particular:
+C              Replaced DSQRT with SQRT everywhere.
+C              Replaced DABS with ABS everywhere.
+C              Replaced DMIN1 with MIN everywhere.
+C              Replaced MIN0 with MIN everywhere.
+C              Replaced DMAX1 with MAX everywhere.
+C              Replaced MAX0 with MAX everywhere.
+C              Replaced DSIGN with SIGN everywhere.
+C           Also replaced REVISION DATE with REVISION HISTORY in all
+C           subordinate routines.
+C  901004  Miscellaneous changes to prologue to complete conversion
+C          to SLATEC 4.0 format.  No code changes.  (F.N.Fritsch)
+C  901009  Corrected GAMS classification code and converted subsidiary
+C          routines to 4.0 format.  No code changes.  (F.N.Fritsch)
+C  901010  Converted XERRWV calls to XERMSG calls.  (R.Clemens,AFWL)
+C  901019  Code changes made.
+C          Merged SLATEC 4.0 changes with previous changes made
+C          by C. Ulrich.  Below is a history of the changes made by
+C          C. Ulrich. (Changes in subsidiary routines are implied
+C          by this history)
+C          891228  Bug was found and repaired inside the DDASSL
+C                  and DDAINI routines.  DDAINI was incorrectly
+C                  returning the initial T with Y and YPRIME
+C                  computed at T+H.  The routine now returns T+H
+C                  rather than the initial T.
+C                  Cosmetic changes made to DDASTP.
+C          900904  Three modifications were made to fix a bug (inside
+C                  DDASSL) re interpolation for continuation calls and
+C                  cases where TN is very close to TSTOP:
+C
+C                  1) In testing for whether H is too large, just
+C                     compare H to (TSTOP - TN), rather than
+C                     (TSTOP - TN) * (1-4*UROUND), and set H to
+C                     TSTOP - TN.  This will force DDASTP to step
+C                     exactly to TSTOP under certain situations
+C                     (i.e. when H returned from DDASTP would otherwise
+C                     take TN beyond TSTOP).
+C
+C                  2) Inside the DDASTP loop, interpolate exactly to
+C                     TSTOP if TN is very close to TSTOP (rather than
+C                     interpolating to within roundoff of TSTOP).
+C
+C                  3) Modified IDID description for IDID = 2 to say that
+C                     the solution is returned by stepping exactly to
+C                     TSTOP, rather than TOUT.  (In some cases the
+C                     solution is actually obtained by extrapolating
+C                     over a distance near unit roundoff to TSTOP,
+C                     but this small distance is deemed acceptable in
+C                     these circumstances.)
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue, removed unreferenced labels,
+C           and improved XERMSG calls.  (FNF)
+C   901030  Added ERROR MESSAGES section and reworked other sections to
+C           be of more uniform format.  (FNF)
+C   910624  Fixed minor bug related to HMAX (five lines ending in
+C           statement 526 in DDASSL).   (LRP)
+C
+C***END PROLOGUE  DDASSL
+C
+C**End
+C
+C     Declare arguments.
+C
+      INTEGER  NEQ, INFO(15), IDID, LRW, IWORK(*), LIW, IPAR(*)
+      DOUBLE PRECISION
+     *   T, Y(*), YPRIME(*), TOUT, RTOL(*), ATOL(*), RWORK(*),
+     *   RPAR(*)
+      EXTERNAL  RES, JAC
+C
+C     Declare externals.
+C
+      EXTERNAL  D1MACH, DDAINI, DDANRM, DDASTP, DDATRP, DDAWTS, XERMSG
+      DOUBLE PRECISION  D1MACH, DDANRM
+C
+C     Declare local variables.
+C
+      INTEGER  I, ITEMP, LALPHA, LBETA, LCJ, LCJOLD, LCTF, LDELTA,
+     *   LENIW, LENPD, LENRW, LE, LETF, LGAMMA, LH, LHMAX, LHOLD,
+     *   LMXSTP, LIPVT,
+     *   LJCALC, LK, LKOLD, LIWM, LML, LMTYPE, LMU, LMXORD, LNJE, LNPD,
+     *   LNRE, LNS, LNST, LNSTL, LPD, LPHASE, LPHI, LPSI, LROUND, LS,
+     *   LSIGMA, LTN, LTSTOP, LWM, LWT, MBAND, MSAVE, MXORD, NPD, NTEMP,
+     *   NZFLG
+      DOUBLE PRECISION
+     *   ATOLI, H, HMAX, HMIN, HO, R, RH, RTOLI, TDIST, TN, TNEXT,
+     *   TSTOP, UROUND, YPNORM
+      LOGICAL  DONE
+C       Auxiliary variables for conversion of values to be included in
+C       error messages.
+      CHARACTER*8  XERN1, XERN2
+      CHARACTER*16 XERN3, XERN4
+C
+C     SET POINTERS INTO IWORK
+      PARAMETER (LML=1, LMU=2, LMXORD=3, LMTYPE=4, LNST=11,
+     *  LNRE=12, LNJE=13, LETF=14, LCTF=15, LNPD=16, LMXSTP=21,
+     *  LIPVT=22, LJCALC=5, LPHASE=6, LK=7, LKOLD=8,
+     *  LNS=9, LNSTL=10, LIWM=1)
+C
+C     SET RELATIVE OFFSET INTO RWORK
+      PARAMETER (NPD=1)
+C
+C     SET POINTERS INTO RWORK
+      PARAMETER (LTSTOP=1, LHMAX=2, LH=3, LTN=4,
+     *  LCJ=5, LCJOLD=6, LHOLD=7, LS=8, LROUND=9,
+     *  LALPHA=11, LBETA=17, LGAMMA=23,
+     *  LPSI=29, LSIGMA=35, LDELTA=41)
+C
+C***FIRST EXECUTABLE STATEMENT  DDASSL
+      IF(INFO(1).NE.0)GO TO 100
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS EXECUTED FOR THE INITIAL CALL ONLY.
+C     IT CONTAINS CHECKING OF INPUTS AND INITIALIZATIONS.
+C-----------------------------------------------------------------------
+C
+C     FIRST CHECK INFO ARRAY TO MAKE SURE ALL ELEMENTS OF INFO
+C     ARE EITHER ZERO OR ONE.
+      DO 10 I=2,11
+         IF(INFO(I).NE.0.AND.INFO(I).NE.1)GO TO 701
+10       CONTINUE
+C
+      IF(NEQ.LE.0)GO TO 702
+C
+C     CHECK AND COMPUTE MAXIMUM ORDER
+      MXORD=5
+      IF(INFO(9).EQ.0)GO TO 20
+         MXORD=IWORK(LMXORD)
+         IF(MXORD.LT.1.OR.MXORD.GT.5)GO TO 703
+20       IWORK(LMXORD)=MXORD
+C
+C     COMPUTE MTYPE,LENPD,LENRW.CHECK ML AND MU.
+      IF(INFO(6).NE.0)GO TO 40
+         LENPD=NEQ**2
+         LENRW=40+(IWORK(LMXORD)+4)*NEQ+LENPD
+         IF(INFO(5).NE.0)GO TO 30
+            IWORK(LMTYPE)=2
+            GO TO 60
+30          IWORK(LMTYPE)=1
+            GO TO 60
+40    IF(IWORK(LML).LT.0.OR.IWORK(LML).GE.NEQ)GO TO 717
+      IF(IWORK(LMU).LT.0.OR.IWORK(LMU).GE.NEQ)GO TO 718
+      LENPD=(2*IWORK(LML)+IWORK(LMU)+1)*NEQ
+      IF(INFO(5).NE.0)GO TO 50
+         IWORK(LMTYPE)=5
+         MBAND=IWORK(LML)+IWORK(LMU)+1
+         MSAVE=(NEQ/MBAND)+1
+         LENRW=40+(IWORK(LMXORD)+4)*NEQ+LENPD+2*MSAVE
+         GO TO 60
+50       IWORK(LMTYPE)=4
+         LENRW=40+(IWORK(LMXORD)+4)*NEQ+LENPD
+C
+C     CHECK LENGTHS OF RWORK AND IWORK
+60    LENIW=21+NEQ
+      IWORK(LNPD)=LENPD
+      IF(LRW.LT.LENRW)GO TO 704
+      IF(LIW.LT.LENIW)GO TO 705
+C
+C     CHECK TO SEE THAT TOUT IS DIFFERENT FROM T
+      IF(TOUT .EQ. T)GO TO 719
+C
+C     CHECK HMAX
+      IF(INFO(7).EQ.0)GO TO 70
+         HMAX=RWORK(LHMAX)
+         IF(HMAX.LE.0.0D0)GO TO 710
+70    CONTINUE
+C
+C     CHECK AND COMPUTE MAXIMUM STEPS
+      MXSTP=500
+      IF(INFO(12).EQ.0)GO TO 80
+        MXSTP=IWORK(LMXSTP)
+        IF(MXSTP.LT.0)GO TO 716
+80      IWORK(LMXSTP)=MXSTP
+C
+C     INITIALIZE COUNTERS
+      IWORK(LNST)=0
+      IWORK(LNRE)=0
+      IWORK(LNJE)=0
+C
+      IWORK(LNSTL)=0
+      IDID=1
+      GO TO 200
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS FOR CONTINUATION CALLS
+C     ONLY. HERE WE CHECK INFO(1),AND IF THE
+C     LAST STEP WAS INTERRUPTED WE CHECK WHETHER
+C     APPROPRIATE ACTION WAS TAKEN.
+C-----------------------------------------------------------------------
+C
+100   CONTINUE
+      IF(INFO(1).EQ.1)GO TO 110
+      IF(INFO(1).NE.-1)GO TO 701
+C
+C     IF WE ARE HERE, THE LAST STEP WAS INTERRUPTED
+C     BY AN ERROR CONDITION FROM DDASTP,AND
+C     APPROPRIATE ACTION WAS NOT TAKEN. THIS
+C     IS A FATAL ERROR.
+      WRITE (XERN1, '(I8)') IDID
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'THE LAST STEP TERMINATED WITH A NEGATIVE VALUE OF IDID = ' //
+     *   XERN1 // ' AND NO APPROPRIATE ACTION WAS TAKEN.  ' //
+     *   'RUN TERMINATED', -998, 2)
+      RETURN
+110   CONTINUE
+      IWORK(LNSTL)=IWORK(LNST)
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS EXECUTED ON ALL CALLS.
+C     THE ERROR TOLERANCE PARAMETERS ARE
+C     CHECKED, AND THE WORK ARRAY POINTERS
+C     ARE SET.
+C-----------------------------------------------------------------------
+C
+200   CONTINUE
+C     CHECK RTOL,ATOL
+      NZFLG=0
+      RTOLI=RTOL(1)
+      ATOLI=ATOL(1)
+      DO 210 I=1,NEQ
+         IF(INFO(2).EQ.1)RTOLI=RTOL(I)
+         IF(INFO(2).EQ.1)ATOLI=ATOL(I)
+         IF(RTOLI.GT.0.0D0.OR.ATOLI.GT.0.0D0)NZFLG=1
+         IF(RTOLI.LT.0.0D0)GO TO 706
+         IF(ATOLI.LT.0.0D0)GO TO 707
+210      CONTINUE
+      IF(NZFLG.EQ.0)GO TO 708
+C
+C     SET UP RWORK STORAGE.IWORK STORAGE IS FIXED
+C     IN DATA STATEMENT.
+      LE=LDELTA+NEQ
+      LWT=LE+NEQ
+      LPHI=LWT+NEQ
+      LPD=LPHI+(IWORK(LMXORD)+1)*NEQ
+      LWM=LPD
+      NTEMP=NPD+IWORK(LNPD)
+      IF(INFO(1).EQ.1)GO TO 400
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK IS EXECUTED ON THE INITIAL CALL
+C     ONLY. SET THE INITIAL STEP SIZE, AND
+C     THE ERROR WEIGHT VECTOR, AND PHI.
+C     COMPUTE INITIAL YPRIME, IF NECESSARY.
+C-----------------------------------------------------------------------
+C
+      TN=T
+      IDID=1
+C
+C     SET ERROR WEIGHT VECTOR WT
+      CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
+      DO 305 I = 1,NEQ
+         IF(RWORK(LWT+I-1).LE.0.0D0) GO TO 713
+305      CONTINUE
+C
+C     COMPUTE UNIT ROUNDOFF AND HMIN
+      UROUND = D1MACH(4)
+      RWORK(LROUND) = UROUND
+      HMIN = 4.0D0*UROUND*MAX(ABS(T),ABS(TOUT))
+C
+C     CHECK INITIAL INTERVAL TO SEE THAT IT IS LONG ENOUGH
+      TDIST = ABS(TOUT - T)
+      IF(TDIST .LT. HMIN) GO TO 714
+C
+C     CHECK HO, IF THIS WAS INPUT
+      IF (INFO(8) .EQ. 0) GO TO 310
+         HO = RWORK(LH)
+         IF ((TOUT - T)*HO .LT. 0.0D0) GO TO 711
+         IF (HO .EQ. 0.0D0) GO TO 712
+         GO TO 320
+310    CONTINUE
+C
+C     COMPUTE INITIAL STEPSIZE, TO BE USED BY EITHER
+C     DDASTP OR DDAINI, DEPENDING ON INFO(11)
+      HO = 0.001D0*TDIST
+      YPNORM = DDANRM(NEQ,YPRIME,RWORK(LWT),RPAR,IPAR)
+      IF (YPNORM .GT. 0.5D0/HO) HO = 0.5D0/YPNORM
+      HO = SIGN(HO,TOUT-T)
+C     ADJUST HO IF NECESSARY TO MEET HMAX BOUND
+320   IF (INFO(7) .EQ. 0) GO TO 330
+         RH = ABS(HO)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) HO = HO/RH
+C     COMPUTE TSTOP, IF APPLICABLE
+330   IF (INFO(4) .EQ. 0) GO TO 340
+         TSTOP = RWORK(LTSTOP)
+         IF ((TSTOP - T)*HO .LT. 0.0D0) GO TO 715
+         IF ((T + HO - TSTOP)*HO .GT. 0.0D0) HO = TSTOP - T
+         IF ((TSTOP - TOUT)*HO .LT. 0.0D0) GO TO 709
+C
+C     COMPUTE INITIAL DERIVATIVE, UPDATING TN AND Y, IF APPLICABLE
+340   IF (INFO(11) .EQ. 0) GO TO 350
+      CALL DDAINI(TN,Y,YPRIME,NEQ,
+     *  RES,JAC,HO,RWORK(LWT),IDID,RPAR,IPAR,
+     *  RWORK(LPHI),RWORK(LDELTA),RWORK(LE),
+     *  RWORK(LWM),IWORK(LIWM),HMIN,RWORK(LROUND),
+     *  INFO(10),NTEMP)
+      IF (IDID .LT. 0) GO TO 390
+C
+C     LOAD H WITH HO.  STORE H IN RWORK(LH)
+350   H = HO
+      RWORK(LH) = H
+C
+C     LOAD Y AND H*YPRIME INTO PHI(*,1) AND PHI(*,2)
+      ITEMP = LPHI + NEQ
+      DO 370 I = 1,NEQ
+         RWORK(LPHI + I - 1) = Y(I)
+370      RWORK(ITEMP + I - 1) = H*YPRIME(I)
+C
+390   GO TO 500
+C
+C-------------------------------------------------------
+C     THIS BLOCK IS FOR CONTINUATION CALLS ONLY. ITS
+C     PURPOSE IS TO CHECK STOP CONDITIONS BEFORE
+C     TAKING A STEP.
+C     ADJUST H IF NECESSARY TO MEET HMAX BOUND
+C-------------------------------------------------------
+C
+400   CONTINUE
+      UROUND=RWORK(LROUND)
+      DONE = .FALSE.
+      TN=RWORK(LTN)
+      H=RWORK(LH)
+      IF(INFO(7) .EQ. 0) GO TO 410
+         RH = ABS(H)/RWORK(LHMAX)
+         IF(RH .GT. 1.0D0) H = H/RH
+410   CONTINUE
+      IF(T .EQ. TOUT) GO TO 719
+      IF((T - TOUT)*H .GT. 0.0D0) GO TO 711
+      IF(INFO(4) .EQ. 1) GO TO 430
+      IF(INFO(3) .EQ. 1) GO TO 420
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 490
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+420   IF((TN-T)*H .LE. 0.0D0) GO TO 490
+      IF((TN - TOUT)*H .GT. 0.0D0) GO TO 425
+      CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TN
+      IDID = 1
+      DONE = .TRUE.
+      GO TO 490
+425   CONTINUE
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+430   IF(INFO(3) .EQ. 1) GO TO 440
+      TSTOP=RWORK(LTSTOP)
+      IF((TN-TSTOP)*H.GT.0.0D0) GO TO 715
+      IF((TSTOP-TOUT)*H.LT.0.0D0)GO TO 709
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 450
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *   RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+440   TSTOP = RWORK(LTSTOP)
+      IF((TN-TSTOP)*H .GT. 0.0D0) GO TO 715
+      IF((TSTOP-TOUT)*H .LT. 0.0D0) GO TO 709
+      IF((TN-T)*H .LE. 0.0D0) GO TO 450
+      IF((TN - TOUT)*H .GT. 0.0D0) GO TO 445
+      CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TN
+      IDID = 1
+      DONE = .TRUE.
+      GO TO 490
+445   CONTINUE
+      CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      T = TOUT
+      IDID = 3
+      DONE = .TRUE.
+      GO TO 490
+450   CONTINUE
+C     CHECK WHETHER WE ARE WITHIN ROUNDOFF OF TSTOP
+      IF(ABS(TN-TSTOP).GT.100.0D0*UROUND*
+     *   (ABS(TN)+ABS(H)))GO TO 460
+      CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,IWORK(LKOLD),
+     *  RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      DONE = .TRUE.
+      GO TO 490
+460   TNEXT=TN+H
+      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 490
+      H=TSTOP-TN
+      RWORK(LH)=H
+C
+490   IF (DONE) GO TO 580
+C
+C-------------------------------------------------------
+C     THE NEXT BLOCK CONTAINS THE CALL TO THE
+C     ONE-STEP INTEGRATOR DDASTP.
+C     THIS IS A LOOPING POINT FOR THE INTEGRATION STEPS.
+C     CHECK FOR TOO MANY STEPS.
+C     UPDATE WT.
+C     CHECK FOR TOO MUCH ACCURACY REQUESTED.
+C     COMPUTE MINIMUM STEPSIZE.
+C-------------------------------------------------------
+C
+500   CONTINUE
+C     CHECK FOR FAILURE TO COMPUTE INITIAL YPRIME
+      IF (IDID .EQ. -12) GO TO 527
+C
+C     CHECK FOR TOO MANY STEPS
+      IF((IWORK(LNST)-IWORK(LNSTL)).LT.IWORK(LMXSTP))
+     *   GO TO 510
+           IDID=-1
+           GO TO 527
+C
+C     UPDATE WT
+510   CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,RWORK(LPHI),
+     *  RWORK(LWT),RPAR,IPAR)
+      DO 520 I=1,NEQ
+         IF(RWORK(I+LWT-1).GT.0.0D0)GO TO 520
+           IDID=-3
+           GO TO 527
+520   CONTINUE
+C
+C     TEST FOR TOO MUCH ACCURACY REQUESTED.
+      R=DDANRM(NEQ,RWORK(LPHI),RWORK(LWT),RPAR,IPAR)*
+     *   100.0D0*UROUND
+      IF(R.LE.1.0D0)GO TO 525
+C     MULTIPLY RTOL AND ATOL BY R AND RETURN
+      IF(INFO(2).EQ.1)GO TO 523
+           RTOL(1)=R*RTOL(1)
+           ATOL(1)=R*ATOL(1)
+           IDID=-2
+           GO TO 527
+523   DO 524 I=1,NEQ
+           RTOL(I)=R*RTOL(I)
+524        ATOL(I)=R*ATOL(I)
+      IDID=-2
+      GO TO 527
+525   CONTINUE
+C
+C     COMPUTE MINIMUM STEPSIZE
+      HMIN=4.0D0*UROUND*MAX(ABS(TN),ABS(TOUT))
+C
+C     TEST H VS. HMAX
+      IF (INFO(7) .EQ. 0) GO TO 526
+         RH = ABS(H)/RWORK(LHMAX)
+         IF (RH .GT. 1.0D0) H = H/RH
+526   CONTINUE           
+C
+      CALL DDASTP(TN,Y,YPRIME,NEQ,
+     *   RES,JAC,H,RWORK(LWT),INFO(1),IDID,RPAR,IPAR,
+     *   RWORK(LPHI),RWORK(LDELTA),RWORK(LE),
+     *   RWORK(LWM),IWORK(LIWM),
+     *   RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
+     *   RWORK(LPSI),RWORK(LSIGMA),
+     *   RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),
+     *   RWORK(LS),HMIN,RWORK(LROUND),
+     *   IWORK(LPHASE),IWORK(LJCALC),IWORK(LK),
+     *   IWORK(LKOLD),IWORK(LNS),INFO(10),NTEMP)
+527   IF(IDID.LT.0)GO TO 600
+C
+C--------------------------------------------------------
+C     THIS BLOCK HANDLES THE CASE OF A SUCCESSFUL RETURN
+C     FROM DDASTP (IDID=1).  TEST FOR STOP CONDITIONS.
+C--------------------------------------------------------
+C
+      IF(INFO(4).NE.0)GO TO 540
+           IF(INFO(3).NE.0)GO TO 530
+             IF((TN-TOUT)*H.LT.0.0D0)GO TO 500
+             CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+             IDID=3
+             T=TOUT
+             GO TO 580
+530          IF((TN-TOUT)*H.GE.0.0D0)GO TO 535
+             T=TN
+             IDID=1
+             GO TO 580
+535          CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+             IDID=3
+             T=TOUT
+             GO TO 580
+540   IF(INFO(3).NE.0)GO TO 550
+      IF((TN-TOUT)*H.LT.0.0D0)GO TO 542
+         CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *     IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+         T=TOUT
+         IDID=3
+         GO TO 580
+542   IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*
+     *   (ABS(TN)+ABS(H)))GO TO 545
+      TNEXT=TN+H
+      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 500
+      H=TSTOP-TN
+      GO TO 500
+545   CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
+     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      GO TO 580
+550   IF((TN-TOUT)*H.GE.0.0D0)GO TO 555
+      IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*(ABS(TN)+ABS(H)))GO TO 552
+      T=TN
+      IDID=1
+      GO TO 580
+552   CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
+     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      IDID=2
+      T=TSTOP
+      GO TO 580
+555   CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
+     *   IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
+      T=TOUT
+      IDID=3
+      GO TO 580
+C
+C--------------------------------------------------------
+C     ALL SUCCESSFUL RETURNS FROM DDASSL ARE MADE FROM
+C     THIS BLOCK.
+C--------------------------------------------------------
+C
+580   CONTINUE
+      RWORK(LTN)=TN
+      RWORK(LH)=H
+      RETURN
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK HANDLES ALL UNSUCCESSFUL
+C     RETURNS OTHER THAN FOR ILLEGAL INPUT.
+C-----------------------------------------------------------------------
+C
+600   CONTINUE
+      ITEMP=-IDID
+      GO TO (610,620,630,690,690,640,650,660,670,675,
+     *  680,685), ITEMP
+C
+C     THE MAXIMUM NUMBER OF STEPS WAS TAKEN BEFORE
+C     REACHING TOUT
+610   WRITE (XERN3, '(1P,D15.6)') TN
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT CURRENT T = ' // XERN3 // ' 500 STEPS TAKEN ON THIS ' //
+     *   'CALL BEFORE REACHING TOUT', IDID, 1)
+      GO TO 690
+C
+C     TOO MUCH ACCURACY FOR MACHINE PRECISION
+620   WRITE (XERN3, '(1P,D15.6)') TN
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' TOO MUCH ACCURACY REQUESTED FOR ' //
+     *   'PRECISION OF MACHINE. RTOL AND ATOL WERE INCREASED TO ' //
+     *   'APPROPRIATE VALUES', IDID, 1)
+      GO TO 690
+C
+C     WT(I) .LE. 0.0 FOR SOME I (NOT AT START OF PROBLEM)
+630   WRITE (XERN3, '(1P,D15.6)') TN
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' SOME ELEMENT OF WT HAS BECOME .LE. ' //
+     *   '0.0', IDID, 1)
+      GO TO 690
+C
+C     ERROR TEST FAILED REPEATEDLY OR WITH H=HMIN
+640   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') H
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' THE ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN',
+     *   IDID, 1)
+      GO TO 690
+C
+C     CORRECTOR CONVERGENCE FAILED REPEATEDLY OR WITH H=HMIN
+650   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') H
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' THE CORRECTOR FAILED TO CONVERGE REPEATEDLY OR WITH ' //
+     *   'ABS(H)=HMIN', IDID, 1)
+      GO TO 690
+C
+C     THE ITERATION MATRIX IS SINGULAR
+660   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') H
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' THE ITERATION MATRIX IS SINGULAR', IDID, 1)
+      GO TO 690
+C
+C     CORRECTOR FAILURE PRECEEDED BY ERROR TEST FAILURES.
+670   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') H
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' THE CORRECTOR COULD NOT CONVERGE.  ALSO, THE ERROR TEST ' //
+     *   'FAILED REPEATEDLY.', IDID, 1)
+      GO TO 690
+C
+C     CORRECTOR FAILURE BECAUSE IRES = -1
+675   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') H
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' THE CORRECTOR COULD NOT CONVERGE BECAUSE IRES WAS EQUAL ' //
+     *   'TO MINUS ONE', IDID, 1)
+      GO TO 690
+C
+C     FAILURE BECAUSE IRES = -2
+680   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') H
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' IRES WAS EQUAL TO MINUS TWO', IDID, 1)
+      GO TO 690
+C
+C     FAILED TO COMPUTE INITIAL YPRIME
+685   WRITE (XERN3, '(1P,D15.6)') TN
+      WRITE (XERN4, '(1P,D15.6)') HO
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
+     *   ' THE INITIAL YPRIME COULD NOT BE COMPUTED', IDID, 1)
+      GO TO 690
+C
+690   CONTINUE
+      INFO(1)=-1
+      T=TN
+      RWORK(LTN)=TN
+      RWORK(LH)=H
+      RETURN
+C
+C-----------------------------------------------------------------------
+C     THIS BLOCK HANDLES ALL ERROR RETURNS DUE
+C     TO ILLEGAL INPUT, AS DETECTED BEFORE CALLING
+C     DDASTP. FIRST THE ERROR MESSAGE ROUTINE IS
+C     CALLED. IF THIS HAPPENS TWICE IN
+C     SUCCESSION, EXECUTION IS TERMINATED
+C
+C-----------------------------------------------------------------------
+701   CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'SOME ELEMENT OF INFO VECTOR IS NOT ZERO OR ONE', 1, 1)
+      GO TO 750
+C
+702   WRITE (XERN1, '(I8)') NEQ
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'NEQ = ' // XERN1 // ' .LE. 0', 2, 1)
+      GO TO 750
+C
+703   WRITE (XERN1, '(I8)') MXORD
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'MAXORD = ' // XERN1 // ' NOT IN RANGE', 3, 1)
+      GO TO 750
+C
+704   WRITE (XERN1, '(I8)') LENRW
+      WRITE (XERN2, '(I8)') LRW
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'RWORK LENGTH NEEDED, LENRW = ' // XERN1 //
+     *   ', EXCEEDS LRW = ' // XERN2, 4, 1)
+      GO TO 750
+C
+705   WRITE (XERN1, '(I8)') LENIW
+      WRITE (XERN2, '(I8)') LIW
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'IWORK LENGTH NEEDED, LENIW = ' // XERN1 //
+     *   ', EXCEEDS LIW = ' // XERN2, 5, 1)
+      GO TO 750
+C
+706   CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'SOME ELEMENT OF RTOL IS .LT. 0', 6, 1)
+      GO TO 750
+C
+707   CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'SOME ELEMENT OF ATOL IS .LT. 0', 7, 1)
+      GO TO 750
+C
+708   CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'ALL ELEMENTS OF RTOL AND ATOL ARE ZERO', 8, 1)
+      GO TO 750
+C
+709   WRITE (XERN3, '(1P,D15.6)') TSTOP
+      WRITE (XERN4, '(1P,D15.6)') TOUT
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'INFO(4) = 1 AND TSTOP = ' // XERN3 // ' BEHIND TOUT = ' //
+     *   XERN4, 9, 1)
+      GO TO 750
+C
+710   WRITE (XERN3, '(1P,D15.6)') HMAX
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'HMAX = ' // XERN3 // ' .LT. 0.0', 10, 1)
+      GO TO 750
+C
+711   WRITE (XERN3, '(1P,D15.6)') TOUT
+      WRITE (XERN4, '(1P,D15.6)') T
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'TOUT = ' // XERN3 // ' BEHIND T = ' // XERN4, 11, 1)
+      GO TO 750
+C
+712   CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'INFO(8)=1 AND H0=0.0', 12, 1)
+      GO TO 750
+C
+713   CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'SOME ELEMENT OF WT IS .LE. 0.0', 13, 1)
+      GO TO 750
+C
+714   WRITE (XERN3, '(1P,D15.6)') TOUT
+      WRITE (XERN4, '(1P,D15.6)') T
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'TOUT = ' // XERN3 // ' TOO CLOSE TO T = ' // XERN4 //
+     *   ' TO START INTEGRATION', 14, 1)
+      GO TO 750
+C
+715   WRITE (XERN3, '(1P,D15.6)') TSTOP
+      WRITE (XERN4, '(1P,D15.6)') T
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'INFO(4)=1 AND TSTOP = ' // XERN3 // ' BEHIND T = ' // XERN4,
+     *   15, 1)
+      GO TO 750
+C
+716   WRITE (XERN1, '(I8)') MXSTP
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'INFO(12)=1 AND MXSTP = ' // XERN1 // ' ILLEGAL.', 3, 1)
+      GO TO 750
+C
+717   WRITE (XERN1, '(I8)') IWORK(LML)
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'ML = ' // XERN1 // ' ILLEGAL.  EITHER .LT. 0 OR .GT. NEQ',
+     *   17, 1)
+      GO TO 750
+C
+718   WRITE (XERN1, '(I8)') IWORK(LMU)
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *   'MU = ' // XERN1 // ' ILLEGAL.  EITHER .LT. 0 OR .GT. NEQ',
+     *   18, 1)
+      GO TO 750
+C
+719   WRITE (XERN3, '(1P,D15.6)') TOUT
+      CALL XERMSG ('SLATEC', 'DDASSL',
+     *  'TOUT = T = ' // XERN3, 19, 1)
+      GO TO 750
+C
+750   IDID=-33
+      IF(INFO(1).EQ.-1) THEN
+         CALL XERMSG ('SLATEC', 'DDASSL',
+     *      'REPEATED OCCURRENCES OF ILLEGAL INPUT$$' //
+     *      'RUN TERMINATED. APPARENT INFINITE LOOP', -999, 2)
+      ENDIF
+C
+      INFO(1)=-1
+      RETURN
+C-----------END OF SUBROUTINE DDASSL------------------------------------
+      END
diff --git a/libcruft/dassl/ddastp.f b/libcruft/dassl/ddastp.f
new file mode 100644
index 0000000..33f653e
--- /dev/null
+++ b/libcruft/dassl/ddastp.f
@@ -0,0 +1,612 @@
+      SUBROUTINE DDASTP (X, Y, YPRIME, NEQ, RES, JAC, H, WT, JSTART,
+     +   IDID, RPAR, IPAR, PHI, DELTA, E, WM, IWM, ALPHA, BETA, GAMMA,
+     +   PSI, SIGMA, CJ, CJOLD, HOLD, S, HMIN, UROUND, IPHASE, JCALC,
+     +   K, KOLD, NS, NONNEG, NTEMP)
+C***BEGIN PROLOGUE  DDASTP
+C***SUBSIDIARY
+C***PURPOSE  Perform one step of the DDASSL integration.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDASTP-S, DDASTP-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------------
+C     DDASTP SOLVES A SYSTEM OF DIFFERENTIAL/
+C     ALGEBRAIC EQUATIONS OF THE FORM
+C     G(X,Y,YPRIME) = 0,  FOR ONE STEP (NORMALLY
+C     FROM X TO X+H).
+C
+C     THE METHODS USED ARE MODIFIED DIVIDED
+C     DIFFERENCE,FIXED LEADING COEFFICIENT
+C     FORMS OF BACKWARD DIFFERENTIATION
+C     FORMULAS. THE CODE ADJUSTS THE STEPSIZE
+C     AND ORDER TO CONTROL THE LOCAL ERROR PER
+C     STEP.
+C
+C
+C     THE PARAMETERS REPRESENT
+C     X  --        INDEPENDENT VARIABLE
+C     Y  --        SOLUTION VECTOR AT X
+C     YPRIME --    DERIVATIVE OF SOLUTION VECTOR
+C                  AFTER SUCCESSFUL STEP
+C     NEQ --       NUMBER OF EQUATIONS TO BE INTEGRATED
+C     RES --       EXTERNAL USER-SUPPLIED SUBROUTINE
+C                  TO EVALUATE THE RESIDUAL.  THE CALL IS
+C                  CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
+C                  X,Y,YPRIME ARE INPUT.  DELTA IS OUTPUT.
+C                  ON INPUT, IRES=0.  RES SHOULD ALTER IRES ONLY
+C                  IF IT ENCOUNTERS AN ILLEGAL VALUE OF Y OR A
+C                  STOP CONDITION.  SET IRES=-1 IF AN INPUT VALUE
+C                  OF Y IS ILLEGAL, AND DDASTP WILL TRY TO SOLVE
+C                  THE PROBLEM WITHOUT GETTING IRES = -1.  IF
+C                  IRES=-2, DDASTP RETURNS CONTROL TO THE CALLING
+C                  PROGRAM WITH IDID = -11.
+C     JAC --       EXTERNAL USER-SUPPLIED ROUTINE TO EVALUATE
+C                  THE ITERATION MATRIX (THIS IS OPTIONAL)
+C                  THE CALL IS OF THE FORM
+C                  CALL JAC(X,Y,YPRIME,PD,CJ,RPAR,IPAR)
+C                  PD IS THE MATRIX OF PARTIAL DERIVATIVES,
+C                  PD=DG/DY+CJ*DG/DYPRIME
+C     H --         APPROPRIATE STEP SIZE FOR NEXT STEP.
+C                  NORMALLY DETERMINED BY THE CODE
+C     WT --        VECTOR OF WEIGHTS FOR ERROR CRITERION.
+C     JSTART --    INTEGER VARIABLE SET 0 FOR
+C                  FIRST STEP, 1 OTHERWISE.
+C     IDID --      COMPLETION CODE WITH THE FOLLOWING MEANINGS:
+C                  IDID= 1 -- THE STEP WAS COMPLETED SUCCESSFULLY
+C                  IDID=-6 -- THE ERROR TEST FAILED REPEATEDLY
+C                  IDID=-7 -- THE CORRECTOR COULD NOT CONVERGE
+C                  IDID=-8 -- THE ITERATION MATRIX IS SINGULAR
+C                  IDID=-9 -- THE CORRECTOR COULD NOT CONVERGE.
+C                             THERE WERE REPEATED ERROR TEST
+C                             FAILURES ON THIS STEP.
+C                  IDID=-10-- THE CORRECTOR COULD NOT CONVERGE
+C                             BECAUSE IRES WAS EQUAL TO MINUS ONE
+C                  IDID=-11-- IRES EQUAL TO -2 WAS ENCOUNTERED,
+C                             AND CONTROL IS BEING RETURNED TO
+C                             THE CALLING PROGRAM
+C     RPAR,IPAR -- REAL AND INTEGER PARAMETER ARRAYS THAT
+C                  ARE USED FOR COMMUNICATION BETWEEN THE
+C                  CALLING PROGRAM AND EXTERNAL USER ROUTINES
+C                  THEY ARE NOT ALTERED BY DDASTP
+C     PHI --       ARRAY OF DIVIDED DIFFERENCES USED BY
+C                  DDASTP. THE LENGTH IS NEQ*(K+1),WHERE
+C                  K IS THE MAXIMUM ORDER
+C     DELTA,E --   WORK VECTORS FOR DDASTP OF LENGTH NEQ
+C     WM,IWM --    REAL AND INTEGER ARRAYS STORING
+C                  MATRIX INFORMATION SUCH AS THE MATRIX
+C                  OF PARTIAL DERIVATIVES,PERMUTATION
+C                  VECTOR,AND VARIOUS OTHER INFORMATION.
+C
+C     THE OTHER PARAMETERS ARE INFORMATION
+C     WHICH IS NEEDED INTERNALLY BY DDASTP TO
+C     CONTINUE FROM STEP TO STEP.
+C
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED  DDAJAC, DDANRM, DDASLV, DDATRP
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C***END PROLOGUE  DDASTP
+C
+      INTEGER  NEQ, JSTART, IDID, IPAR(*), IWM(*), IPHASE, JCALC, K,
+     *   KOLD, NS, NONNEG, NTEMP
+      DOUBLE PRECISION
+     *   X, Y(*), YPRIME(*), H, WT(*), RPAR(*), PHI(NEQ,*), DELTA(*),
+     *   E(*), WM(*), ALPHA(*), BETA(*), GAMMA(*), PSI(*), SIGMA(*), CJ,
+     *   CJOLD, HOLD, S, HMIN, UROUND
+      EXTERNAL  RES, JAC
+C
+      EXTERNAL  DDAJAC, DDANRM, DDASLV, DDATRP
+      DOUBLE PRECISION  DDANRM
+C
+      INTEGER  I, IER, IRES, J, J1, KDIFF, KM1, KNEW, KP1, KP2, LCTF,
+     *   LETF, LMXORD, LNJE, LNRE, LNST, M, MAXIT, NCF, NEF, NSF, NSP1
+      DOUBLE PRECISION
+     *   ALPHA0, ALPHAS, CJLAST, CK, DELNRM, ENORM, ERK, ERKM1,
+     *   ERKM2, ERKP1, ERR, EST, HNEW, OLDNRM, PNORM, R, RATE, TEMP1,
+     *   TEMP2, TERK, TERKM1, TERKM2, TERKP1, XOLD, XRATE
+      LOGICAL  CONVGD
+C
+      PARAMETER (LMXORD=3)
+      PARAMETER (LNST=11)
+      PARAMETER (LNRE=12)
+      PARAMETER (LNJE=13)
+      PARAMETER (LETF=14)
+      PARAMETER (LCTF=15)
+C
+      DATA MAXIT/4/
+      DATA XRATE/0.25D0/
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 1.
+C     INITIALIZE. ON THE FIRST CALL,SET
+C     THE ORDER TO 1 AND INITIALIZE
+C     OTHER VARIABLES.
+C-----------------------------------------------------------------------
+C
+C     INITIALIZATIONS FOR ALL CALLS
+C***FIRST EXECUTABLE STATEMENT  DDASTP
+      IDID=1
+      XOLD=X
+      NCF=0
+      NSF=0
+      NEF=0
+      IF(JSTART .NE. 0) GO TO 120
+C
+C     IF THIS IS THE FIRST STEP,PERFORM
+C     OTHER INITIALIZATIONS
+      IWM(LETF) = 0
+      IWM(LCTF) = 0
+      K=1
+      KOLD=0
+      HOLD=0.0D0
+      JSTART=1
+      PSI(1)=H
+      CJOLD = 1.0D0/H
+      CJ = CJOLD
+      S = 100.D0
+      JCALC = -1
+      DELNRM=1.0D0
+      IPHASE = 0
+      NS=0
+120   CONTINUE
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 2
+C     COMPUTE COEFFICIENTS OF FORMULAS FOR
+C     THIS STEP.
+C-----------------------------------------------------------------------
+200   CONTINUE
+      KP1=K+1
+      KP2=K+2
+      KM1=K-1
+      XOLD=X
+      IF(H.NE.HOLD.OR.K .NE. KOLD) NS = 0
+      NS=MIN(NS+1,KOLD+2)
+      NSP1=NS+1
+      IF(KP1 .LT. NS)GO TO 230
+C
+      BETA(1)=1.0D0
+      ALPHA(1)=1.0D0
+      TEMP1=H
+      GAMMA(1)=0.0D0
+      SIGMA(1)=1.0D0
+      DO 210 I=2,KP1
+         TEMP2=PSI(I-1)
+         PSI(I-1)=TEMP1
+         BETA(I)=BETA(I-1)*PSI(I-1)/TEMP2
+         TEMP1=TEMP2+H
+         ALPHA(I)=H/TEMP1
+         SIGMA(I)=(I-1)*SIGMA(I-1)*ALPHA(I)
+         GAMMA(I)=GAMMA(I-1)+ALPHA(I-1)/H
+210      CONTINUE
+      PSI(KP1)=TEMP1
+230   CONTINUE
+C
+C     COMPUTE ALPHAS, ALPHA0
+      ALPHAS = 0.0D0
+      ALPHA0 = 0.0D0
+      DO 240 I = 1,K
+        ALPHAS = ALPHAS - 1.0D0/I
+        ALPHA0 = ALPHA0 - ALPHA(I)
+240     CONTINUE
+C
+C     COMPUTE LEADING COEFFICIENT CJ
+      CJLAST = CJ
+      CJ = -ALPHAS/H
+C
+C     COMPUTE VARIABLE STEPSIZE ERROR COEFFICIENT CK
+      CK = ABS(ALPHA(KP1) + ALPHAS - ALPHA0)
+      CK = MAX(CK,ALPHA(KP1))
+C
+C     DECIDE WHETHER NEW JACOBIAN IS NEEDED
+      TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
+      TEMP2 = 1.0D0/TEMP1
+      IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
+      IF (CJ .NE. CJLAST) S = 100.D0
+C
+C     CHANGE PHI TO PHI STAR
+      IF(KP1 .LT. NSP1) GO TO 280
+      DO 270 J=NSP1,KP1
+         DO 260 I=1,NEQ
+260         PHI(I,J)=BETA(J)*PHI(I,J)
+270      CONTINUE
+280   CONTINUE
+C
+C     UPDATE TIME
+      X=X+H
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 3
+C     PREDICT THE SOLUTION AND DERIVATIVE,
+C     AND SOLVE THE CORRECTOR EQUATION
+C-----------------------------------------------------------------------
+C
+C     FIRST,PREDICT THE SOLUTION AND DERIVATIVE
+300   CONTINUE
+      DO 310 I=1,NEQ
+         Y(I)=PHI(I,1)
+310      YPRIME(I)=0.0D0
+      DO 330 J=2,KP1
+         DO 320 I=1,NEQ
+            Y(I)=Y(I)+PHI(I,J)
+320         YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
+330   CONTINUE
+      PNORM = DDANRM (NEQ,Y,WT,RPAR,IPAR)
+C
+C
+C
+C     SOLVE THE CORRECTOR EQUATION USING A
+C     MODIFIED NEWTON SCHEME.
+      CONVGD= .TRUE.
+      M=0
+      IWM(LNRE)=IWM(LNRE)+1
+      IRES = 0
+      CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 380
+C
+C
+C     IF INDICATED,REEVALUATE THE
+C     ITERATION MATRIX PD = DG/DY + CJ*DG/DYPRIME
+C     (WHERE G(X,Y,YPRIME)=0). SET
+C     JCALC TO 0 AS AN INDICATOR THAT
+C     THIS HAS BEEN DONE.
+      IF(JCALC .NE. -1)GO TO 340
+      IWM(LNJE)=IWM(LNJE)+1
+      JCALC=0
+      CALL DDAJAC(NEQ,X,Y,YPRIME,DELTA,CJ,H,
+     * IER,WT,E,WM,IWM,RES,IRES,UROUND,JAC,RPAR,
+     * IPAR,NTEMP)
+      CJOLD=CJ
+      S = 100.D0
+      IF (IRES .LT. 0) GO TO 380
+      IF(IER .NE. 0)GO TO 380
+      NSF=0
+C
+C
+C     INITIALIZE THE ERROR ACCUMULATION VECTOR E.
+340   CONTINUE
+      DO 345 I=1,NEQ
+345      E(I)=0.0D0
+C
+C
+C     CORRECTOR LOOP.
+350   CONTINUE
+C
+C     MULTIPLY RESIDUAL BY TEMP1 TO ACCELERATE CONVERGENCE
+      TEMP1 = 2.0D0/(1.0D0 + CJ/CJOLD)
+      DO 355 I = 1,NEQ
+355     DELTA(I) = DELTA(I) * TEMP1
+C
+C     COMPUTE A NEW ITERATE (BACK-SUBSTITUTION).
+C     STORE THE CORRECTION IN DELTA.
+      CALL DDASLV(NEQ,DELTA,WM,IWM)
+C
+C     UPDATE Y,E,AND YPRIME
+      DO 360 I=1,NEQ
+         Y(I)=Y(I)-DELTA(I)
+         E(I)=E(I)-DELTA(I)
+360      YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
+C
+C     TEST FOR CONVERGENCE OF THE ITERATION
+      DELNRM=DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF (DELNRM .LE. 100.D0*UROUND*PNORM) GO TO 375
+      IF (M .GT. 0) GO TO 365
+         OLDNRM = DELNRM
+         GO TO 367
+365   RATE = (DELNRM/OLDNRM)**(1.0D0/M)
+      IF (RATE .GT. 0.90D0) GO TO 370
+      S = RATE/(1.0D0 - RATE)
+367   IF (S*DELNRM .LE. 0.33D0) GO TO 375
+C
+C     THE CORRECTOR HAS NOT YET CONVERGED.
+C     UPDATE M AND TEST WHETHER THE
+C     MAXIMUM NUMBER OF ITERATIONS HAVE
+C     BEEN TRIED.
+      M=M+1
+      IF(M.GE.MAXIT)GO TO 370
+C
+C     EVALUATE THE RESIDUAL
+C     AND GO BACK TO DO ANOTHER ITERATION
+      IWM(LNRE)=IWM(LNRE)+1
+      IRES = 0
+      CALL RES(X,Y,YPRIME,DELTA,IRES,
+     *  RPAR,IPAR)
+      IF (IRES .LT. 0) GO TO 380
+      GO TO 350
+C
+C
+C     THE CORRECTOR FAILED TO CONVERGE IN MAXIT
+C     ITERATIONS. IF THE ITERATION MATRIX
+C     IS NOT CURRENT,RE-DO THE STEP WITH
+C     A NEW ITERATION MATRIX.
+370   CONTINUE
+      IF(JCALC.EQ.0)GO TO 380
+      JCALC=-1
+      GO TO 300
+C
+C
+C     THE ITERATION HAS CONVERGED.  IF NONNEGATIVITY OF SOLUTION IS
+C     REQUIRED, SET THE SOLUTION NONNEGATIVE, IF THE PERTURBATION
+C     TO DO IT IS SMALL ENOUGH.  IF THE CHANGE IS TOO LARGE, THEN
+C     CONSIDER THE CORRECTOR ITERATION TO HAVE FAILED.
+375   IF(NONNEG .EQ. 0) GO TO 390
+      DO 377 I = 1,NEQ
+377      DELTA(I) = MIN(Y(I),0.0D0)
+      DELNRM = DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      IF(DELNRM .GT. 0.33D0) GO TO 380
+      DO 378 I = 1,NEQ
+378      E(I) = E(I) - DELTA(I)
+      GO TO 390
+C
+C
+C     EXITS FROM BLOCK 3
+C     NO CONVERGENCE WITH CURRENT ITERATION
+C     MATRIX,OR SINGULAR ITERATION MATRIX
+380   CONVGD= .FALSE.
+390   JCALC = 1
+      IF(.NOT.CONVGD)GO TO 600
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 4
+C     ESTIMATE THE ERRORS AT ORDERS K,K-1,K-2
+C     AS IF CONSTANT STEPSIZE WAS USED. ESTIMATE
+C     THE LOCAL ERROR AT ORDER K AND TEST
+C     WHETHER THE CURRENT STEP IS SUCCESSFUL.
+C-----------------------------------------------------------------------
+C
+C     ESTIMATE ERRORS AT ORDERS K,K-1,K-2
+      ENORM = DDANRM(NEQ,E,WT,RPAR,IPAR)
+      ERK = SIGMA(K+1)*ENORM
+      TERK = (K+1)*ERK
+      EST = ERK
+      KNEW=K
+      IF(K .EQ. 1)GO TO 430
+      DO 405 I = 1,NEQ
+405     DELTA(I) = PHI(I,KP1) + E(I)
+      ERKM1=SIGMA(K)*DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      TERKM1 = K*ERKM1
+      IF(K .GT. 2)GO TO 410
+      IF(TERKM1 .LE. 0.5D0*TERK)GO TO 420
+      GO TO 430
+410   CONTINUE
+      DO 415 I = 1,NEQ
+415     DELTA(I) = PHI(I,K) + DELTA(I)
+      ERKM2=SIGMA(K-1)*DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      TERKM2 = (K-1)*ERKM2
+      IF(MAX(TERKM1,TERKM2).GT.TERK)GO TO 430
+C     LOWER THE ORDER
+420   CONTINUE
+      KNEW=K-1
+      EST = ERKM1
+C
+C
+C     CALCULATE THE LOCAL ERROR FOR THE CURRENT STEP
+C     TO SEE IF THE STEP WAS SUCCESSFUL
+430   CONTINUE
+      ERR = CK * ENORM
+      IF(ERR .GT. 1.0D0)GO TO 600
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 5
+C     THE STEP IS SUCCESSFUL. DETERMINE
+C     THE BEST ORDER AND STEPSIZE FOR
+C     THE NEXT STEP. UPDATE THE DIFFERENCES
+C     FOR THE NEXT STEP.
+C-----------------------------------------------------------------------
+      IDID=1
+      IWM(LNST)=IWM(LNST)+1
+      KDIFF=K-KOLD
+      KOLD=K
+      HOLD=H
+C
+C
+C     ESTIMATE THE ERROR AT ORDER K+1 UNLESS:
+C        ALREADY DECIDED TO LOWER ORDER, OR
+C        ALREADY USING MAXIMUM ORDER, OR
+C        STEPSIZE NOT CONSTANT, OR
+C        ORDER RAISED IN PREVIOUS STEP
+      IF(KNEW.EQ.KM1.OR.K.EQ.IWM(LMXORD))IPHASE=1
+      IF(IPHASE .EQ. 0)GO TO 545
+      IF(KNEW.EQ.KM1)GO TO 540
+      IF(K.EQ.IWM(LMXORD)) GO TO 550
+      IF(KP1.GE.NS.OR.KDIFF.EQ.1)GO TO 550
+      DO 510 I=1,NEQ
+510      DELTA(I)=E(I)-PHI(I,KP2)
+      ERKP1 = (1.0D0/(K+2))*DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
+      TERKP1 = (K+2)*ERKP1
+      IF(K.GT.1)GO TO 520
+      IF(TERKP1.GE.0.5D0*TERK)GO TO 550
+      GO TO 530
+520   IF(TERKM1.LE.MIN(TERK,TERKP1))GO TO 540
+      IF(TERKP1.GE.TERK.OR.K.EQ.IWM(LMXORD))GO TO 550
+C
+C     RAISE ORDER
+530   K=KP1
+      EST = ERKP1
+      GO TO 550
+C
+C     LOWER ORDER
+540   K=KM1
+      EST = ERKM1
+      GO TO 550
+C
+C     IF IPHASE = 0, INCREASE ORDER BY ONE AND MULTIPLY STEPSIZE BY
+C     FACTOR TWO
+545   K = KP1
+      HNEW = H*2.0D0
+      H = HNEW
+      GO TO 575
+C
+C
+C     DETERMINE THE APPROPRIATE STEPSIZE FOR
+C     THE NEXT STEP.
+550   HNEW=H
+      TEMP2=K+1
+      R=(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
+      IF(R .LT. 2.0D0) GO TO 555
+      HNEW = 2.0D0*H
+      GO TO 560
+555   IF(R .GT. 1.0D0) GO TO 560
+      R = MAX(0.5D0,MIN(0.9D0,R))
+      HNEW = H*R
+560   H=HNEW
+C
+C
+C     UPDATE DIFFERENCES FOR NEXT STEP
+575   CONTINUE
+      IF(KOLD.EQ.IWM(LMXORD))GO TO 585
+      DO 580 I=1,NEQ
+580      PHI(I,KP2)=E(I)
+585   CONTINUE
+      DO 590 I=1,NEQ
+590      PHI(I,KP1)=PHI(I,KP1)+E(I)
+      DO 595 J1=2,KP1
+         J=KP1-J1+1
+         DO 595 I=1,NEQ
+595      PHI(I,J)=PHI(I,J)+PHI(I,J+1)
+      RETURN
+C
+C
+C
+C
+C
+C-----------------------------------------------------------------------
+C     BLOCK 6
+C     THE STEP IS UNSUCCESSFUL. RESTORE X,PSI,PHI
+C     DETERMINE APPROPRIATE STEPSIZE FOR
+C     CONTINUING THE INTEGRATION, OR EXIT WITH
+C     AN ERROR FLAG IF THERE HAVE BEEN MANY
+C     FAILURES.
+C-----------------------------------------------------------------------
+600   IPHASE = 1
+C
+C     RESTORE X,PHI,PSI
+      X=XOLD
+      IF(KP1.LT.NSP1)GO TO 630
+      DO 620 J=NSP1,KP1
+         TEMP1=1.0D0/BETA(J)
+         DO 610 I=1,NEQ
+610         PHI(I,J)=TEMP1*PHI(I,J)
+620      CONTINUE
+630   CONTINUE
+      DO 640 I=2,KP1
+640      PSI(I-1)=PSI(I)-H
+C
+C
+C     TEST WHETHER FAILURE IS DUE TO CORRECTOR ITERATION
+C     OR ERROR TEST
+      IF(CONVGD)GO TO 660
+      IWM(LCTF)=IWM(LCTF)+1
+C
+C
+C     THE NEWTON ITERATION FAILED TO CONVERGE WITH
+C     A CURRENT ITERATION MATRIX.  DETERMINE THE CAUSE
+C     OF THE FAILURE AND TAKE APPROPRIATE ACTION.
+      IF(IER.EQ.0)GO TO 650
+C
+C     THE ITERATION MATRIX IS SINGULAR. REDUCE
+C     THE STEPSIZE BY A FACTOR OF 4. IF
+C     THIS HAPPENS THREE TIMES IN A ROW ON
+C     THE SAME STEP, RETURN WITH AN ERROR FLAG
+      NSF=NSF+1
+      R = 0.25D0
+      H=H*R
+      IF (NSF .LT. 3 .AND. ABS(H) .GE. HMIN) GO TO 690
+      IDID=-8
+      GO TO 675
+C
+C
+C     THE NEWTON ITERATION FAILED TO CONVERGE FOR A REASON
+C     OTHER THAN A SINGULAR ITERATION MATRIX.  IF IRES = -2, THEN
+C     RETURN.  OTHERWISE, REDUCE THE STEPSIZE AND TRY AGAIN, UNLESS
+C     TOO MANY FAILURES HAVE OCCURED.
+650   CONTINUE
+      IF (IRES .GT. -2) GO TO 655
+      IDID = -11
+      GO TO 675
+655   NCF = NCF + 1
+      R = 0.25D0
+      H = H*R
+      IF (NCF .LT. 10 .AND. ABS(H) .GE. HMIN) GO TO 690
+      IDID = -7
+      IF (IRES .LT. 0) IDID = -10
+      IF (NEF .GE. 3) IDID = -9
+      GO TO 675
+C
+C
+C     THE NEWTON SCHEME CONVERGED,AND THE CAUSE
+C     OF THE FAILURE WAS THE ERROR ESTIMATE
+C     EXCEEDING THE TOLERANCE.
+660   NEF=NEF+1
+      IWM(LETF)=IWM(LETF)+1
+      IF (NEF .GT. 1) GO TO 665
+C
+C     ON FIRST ERROR TEST FAILURE, KEEP CURRENT ORDER OR LOWER
+C     ORDER BY ONE.  COMPUTE NEW STEPSIZE BASED ON DIFFERENCES
+C     OF THE SOLUTION.
+      K = KNEW
+      TEMP2 = K + 1
+      R = 0.90D0*(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
+      R = MAX(0.25D0,MIN(0.9D0,R))
+      H = H*R
+      IF (ABS(H) .GE. HMIN) GO TO 690
+      IDID = -6
+      GO TO 675
+C
+C     ON SECOND ERROR TEST FAILURE, USE THE CURRENT ORDER OR
+C     DECREASE ORDER BY ONE.  REDUCE THE STEPSIZE BY A FACTOR OF
+C     FOUR.
+665   IF (NEF .GT. 2) GO TO 670
+      K = KNEW
+      H = 0.25D0*H
+      IF (ABS(H) .GE. HMIN) GO TO 690
+      IDID = -6
+      GO TO 675
+C
+C     ON THIRD AND SUBSEQUENT ERROR TEST FAILURES, SET THE ORDER TO
+C     ONE AND REDUCE THE STEPSIZE BY A FACTOR OF FOUR.
+670   K = 1
+      H = 0.25D0*H
+      IF (ABS(H) .GE. HMIN) GO TO 690
+      IDID = -6
+      GO TO 675
+C
+C
+C
+C
+C     FOR ALL CRASHES, RESTORE Y TO ITS LAST VALUE,
+C     INTERPOLATE TO FIND YPRIME AT LAST X, AND RETURN
+675   CONTINUE
+      CALL DDATRP(X,X,Y,YPRIME,NEQ,K,PHI,PSI)
+      RETURN
+C
+C
+C     GO BACK AND TRY THIS STEP AGAIN
+690   GO TO 200
+C
+C------END OF SUBROUTINE DDASTP------
+      END
diff --git a/libcruft/dassl/ddatrp.f b/libcruft/dassl/ddatrp.f
new file mode 100644
index 0000000..f48c317
--- /dev/null
+++ b/libcruft/dassl/ddatrp.f
@@ -0,0 +1,64 @@
+      SUBROUTINE DDATRP (X, XOUT, YOUT, YPOUT, NEQ, KOLD, PHI, PSI)
+C***BEGIN PROLOGUE  DDATRP
+C***SUBSIDIARY
+C***PURPOSE  Interpolation routine for DDASSL.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDATRP-S, DDATRP-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------------
+C     THE METHODS IN SUBROUTINE DDASTP USE POLYNOMIALS
+C     TO APPROXIMATE THE SOLUTION. DDATRP APPROXIMATES THE
+C     SOLUTION AND ITS DERIVATIVE AT TIME XOUT BY EVALUATING
+C     ONE OF THESE POLYNOMIALS,AND ITS DERIVATIVE,THERE.
+C     INFORMATION DEFINING THIS POLYNOMIAL IS PASSED FROM
+C     DDASTP, SO DDATRP CANNOT BE USED ALONE.
+C
+C     THE PARAMETERS ARE:
+C     X     THE CURRENT TIME IN THE INTEGRATION.
+C     XOUT  THE TIME AT WHICH THE SOLUTION IS DESIRED
+C     YOUT  THE INTERPOLATED APPROXIMATION TO Y AT XOUT
+C           (THIS IS OUTPUT)
+C     YPOUT THE INTERPOLATED APPROXIMATION TO YPRIME AT XOUT
+C           (THIS IS OUTPUT)
+C     NEQ   NUMBER OF EQUATIONS
+C     KOLD  ORDER USED ON LAST SUCCESSFUL STEP
+C     PHI   ARRAY OF SCALED DIVIDED DIFFERENCES OF Y
+C     PSI   ARRAY OF PAST STEPSIZE HISTORY
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C***END PROLOGUE  DDATRP
+C
+      INTEGER  NEQ, KOLD
+      DOUBLE PRECISION  X, XOUT, YOUT(*), YPOUT(*), PHI(NEQ,*), PSI(*)
+C
+      INTEGER  I, J, KOLDP1
+      DOUBLE PRECISION  C, D, GAMMA, TEMP1
+C
+C***FIRST EXECUTABLE STATEMENT  DDATRP
+      KOLDP1=KOLD+1
+      TEMP1=XOUT-X
+      DO 10 I=1,NEQ
+         YOUT(I)=PHI(I,1)
+10       YPOUT(I)=0.0D0
+      C=1.0D0
+      D=0.0D0
+      GAMMA=TEMP1/PSI(1)
+      DO 30 J=2,KOLDP1
+         D=D*GAMMA+C/PSI(J-1)
+         C=C*GAMMA
+         GAMMA=(TEMP1+PSI(J-1))/PSI(J)
+         DO 20 I=1,NEQ
+            YOUT(I)=YOUT(I)+C*PHI(I,J)
+20          YPOUT(I)=YPOUT(I)+D*PHI(I,J)
+30       CONTINUE
+      RETURN
+C
+C------END OF SUBROUTINE DDATRP------
+      END
diff --git a/libcruft/dassl/ddawts.f b/libcruft/dassl/ddawts.f
new file mode 100644
index 0000000..1406ac9
--- /dev/null
+++ b/libcruft/dassl/ddawts.f
@@ -0,0 +1,42 @@
+      SUBROUTINE DDAWTS (NEQ, IWT, RTOL, ATOL, Y, WT, RPAR, IPAR)
+C***BEGIN PROLOGUE  DDAWTS
+C***SUBSIDIARY
+C***PURPOSE  Set error weight vector for DDASSL.
+C***LIBRARY   SLATEC (DASSL)
+C***TYPE      DOUBLE PRECISION (SDAWTS-S, DDAWTS-D)
+C***AUTHOR  PETZOLD, LINDA R., (LLNL)
+C***DESCRIPTION
+C-----------------------------------------------------------------------
+C     THIS SUBROUTINE SETS THE ERROR WEIGHT VECTOR
+C     WT ACCORDING TO WT(I)=RTOL(I)*ABS(Y(I))+ATOL(I),
+C     I=1,-,N.
+C     RTOL AND ATOL ARE SCALARS IF IWT = 0,
+C     AND VECTORS IF IWT = 1.
+C-----------------------------------------------------------------------
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   830315  DATE WRITTEN
+C   901009  Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
+C   901019  Merged changes made by C. Ulrich with SLATEC 4.0 format.
+C   901026  Added explicit declarations for all variables and minor
+C           cosmetic changes to prologue.  (FNF)
+C***END PROLOGUE  DDAWTS
+C
+      INTEGER  NEQ, IWT, IPAR(*)
+      DOUBLE PRECISION  RTOL(*), ATOL(*), Y(*), WT(*), RPAR(*)
+C
+      INTEGER  I
+      DOUBLE PRECISION  ATOLI, RTOLI
+C
+C***FIRST EXECUTABLE STATEMENT  DDAWTS
+      RTOLI=RTOL(1)
+      ATOLI=ATOL(1)
+      DO 20 I=1,NEQ
+         IF (IWT .EQ.0) GO TO 10
+           RTOLI=RTOL(I)
+           ATOLI=ATOL(I)
+10         WT(I)=RTOLI*ABS(Y(I))+ATOLI
+20         CONTINUE
+      RETURN
+C-----------END OF SUBROUTINE DDAWTS------------------------------------
+      END
diff --git a/libcruft/fftpack/Makefile.in b/libcruft/fftpack/Makefile.in
new file mode 100644
index 0000000..cecb42d
--- /dev/null
+++ b/libcruft/fftpack/Makefile.in
@@ -0,0 +1,37 @@
+# Makefile for octave's libcruft/fftpack directory
+#
+# Copyright (C) 1993, 1994, 1995, 1997, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES) $(srcdir)/fftpack.doc
+
+FSRC = cfftb.f cfftb1.f cfftf.f cfftf1.f cffti.f cffti1.f passb.f \
+  passb2.f passb3.f passb4.f passb5.f passf.f passf2.f passf3.f \
+  passf4.f passf5.f zfftb.f zfftb1.f zfftf.f zfftf1.f zffti.f zffti1.f \
+  zpassb.f zpassb2.f zpassb3.f zpassb4.f zpassb5.f zpassf.f zpassf2.f \
+  zpassf3.f zpassf4.f zpassf5.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/fftpack/cfftb.f b/libcruft/fftpack/cfftb.f
new file mode 100644
index 0000000..1e370fc
--- /dev/null
+++ b/libcruft/fftpack/cfftb.f
@@ -0,0 +1,8 @@
+      subroutine cfftb (n,c,wsave)
+      dimension       c(*)       ,wsave(*)
+      if (n .eq. 1) return
+      iw1 = n+n+1
+      iw2 = iw1+n+n
+      call cfftb1 (n,c,wsave,wsave(iw1),wsave(iw2))
+      return
+      end
diff --git a/libcruft/fftpack/cfftb1.f b/libcruft/fftpack/cfftb1.f
new file mode 100644
index 0000000..02cafdf
--- /dev/null
+++ b/libcruft/fftpack/cfftb1.f
@@ -0,0 +1,61 @@
+      subroutine cfftb1 (n,c,ch,wa,ifac)
+      dimension       ch(*)      ,c(*)       ,wa(*)      ,ifac(*)
+      nf = ifac(2)
+      na = 0
+      l1 = 1
+      iw = 1
+      do 116 k1=1,nf
+         ip = ifac(k1+2)
+         l2 = ip*l1
+         ido = n/l2
+         idot = ido+ido
+         idl1 = idot*l1
+         if (ip .ne. 4) go to 103
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         if (na .ne. 0) go to 101
+         call passb4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
+         go to 102
+  101    call passb4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
+  102    na = 1-na
+         go to 115
+  103    if (ip .ne. 2) go to 106
+         if (na .ne. 0) go to 104
+         call passb2 (idot,l1,c,ch,wa(iw))
+         go to 105
+  104    call passb2 (idot,l1,ch,c,wa(iw))
+  105    na = 1-na
+         go to 115
+  106    if (ip .ne. 3) go to 109
+         ix2 = iw+idot
+         if (na .ne. 0) go to 107
+         call passb3 (idot,l1,c,ch,wa(iw),wa(ix2))
+         go to 108
+  107    call passb3 (idot,l1,ch,c,wa(iw),wa(ix2))
+  108    na = 1-na
+         go to 115
+  109    if (ip .ne. 5) go to 112
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         ix4 = ix3+idot
+         if (na .ne. 0) go to 110
+         call passb5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+         go to 111
+  110    call passb5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+  111    na = 1-na
+         go to 115
+  112    if (na .ne. 0) go to 113
+         call passb (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
+         go to 114
+  113    call passb (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
+  114    if (nac .ne. 0) na = 1-na
+  115    l1 = l2
+         iw = iw+(ip-1)*idot
+  116 continue
+      if (na .eq. 0) return
+      n2 = n+n
+      do 117 i=1,n2
+         c(i) = ch(i)
+  117 continue
+      return
+      end
diff --git a/libcruft/fftpack/cfftf.f b/libcruft/fftpack/cfftf.f
new file mode 100644
index 0000000..c74cd3d
--- /dev/null
+++ b/libcruft/fftpack/cfftf.f
@@ -0,0 +1,8 @@
+      subroutine cfftf (n,c,wsave)
+      dimension       c(*)       ,wsave(*)
+      if (n .eq. 1) return
+      iw1 = n+n+1
+      iw2 = iw1+n+n
+      call cfftf1 (n,c,wsave,wsave(iw1),wsave(iw2))
+      return
+      end
diff --git a/libcruft/fftpack/cfftf1.f b/libcruft/fftpack/cfftf1.f
new file mode 100644
index 0000000..5afc885
--- /dev/null
+++ b/libcruft/fftpack/cfftf1.f
@@ -0,0 +1,61 @@
+      subroutine cfftf1 (n,c,ch,wa,ifac)
+      dimension       ch(*)      ,c(*)       ,wa(*)      ,ifac(*)
+      nf = ifac(2)
+      na = 0
+      l1 = 1
+      iw = 1
+      do 116 k1=1,nf
+         ip = ifac(k1+2)
+         l2 = ip*l1
+         ido = n/l2
+         idot = ido+ido
+         idl1 = idot*l1
+         if (ip .ne. 4) go to 103
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         if (na .ne. 0) go to 101
+         call passf4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
+         go to 102
+  101    call passf4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
+  102    na = 1-na
+         go to 115
+  103    if (ip .ne. 2) go to 106
+         if (na .ne. 0) go to 104
+         call passf2 (idot,l1,c,ch,wa(iw))
+         go to 105
+  104    call passf2 (idot,l1,ch,c,wa(iw))
+  105    na = 1-na
+         go to 115
+  106    if (ip .ne. 3) go to 109
+         ix2 = iw+idot
+         if (na .ne. 0) go to 107
+         call passf3 (idot,l1,c,ch,wa(iw),wa(ix2))
+         go to 108
+  107    call passf3 (idot,l1,ch,c,wa(iw),wa(ix2))
+  108    na = 1-na
+         go to 115
+  109    if (ip .ne. 5) go to 112
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         ix4 = ix3+idot
+         if (na .ne. 0) go to 110
+         call passf5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+         go to 111
+  110    call passf5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+  111    na = 1-na
+         go to 115
+  112    if (na .ne. 0) go to 113
+         call passf (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
+         go to 114
+  113    call passf (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
+  114    if (nac .ne. 0) na = 1-na
+  115    l1 = l2
+         iw = iw+(ip-1)*idot
+  116 continue
+      if (na .eq. 0) return
+      n2 = n+n
+      do 117 i=1,n2
+         c(i) = ch(i)
+  117 continue
+      return
+      end
diff --git a/libcruft/fftpack/cffti.f b/libcruft/fftpack/cffti.f
new file mode 100644
index 0000000..42856d2
--- /dev/null
+++ b/libcruft/fftpack/cffti.f
@@ -0,0 +1,8 @@
+      subroutine cffti (n,wsave)
+      dimension       wsave(*)
+      if (n .eq. 1) return
+      iw1 = n+n+1
+      iw2 = iw1+n+n
+      call cffti1 (n,wsave(iw1),wsave(iw2))
+      return
+      end
diff --git a/libcruft/fftpack/cffti1.f b/libcruft/fftpack/cffti1.f
new file mode 100644
index 0000000..9ebaa25
--- /dev/null
+++ b/libcruft/fftpack/cffti1.f
@@ -0,0 +1,60 @@
+      subroutine cffti1 (n,wa,ifac)
+      dimension       wa(*)      ,ifac(*)    ,ntryh(4)
+      data ntryh(1),ntryh(2),ntryh(3),ntryh(4)/3,4,2,5/
+      nl = n
+      nf = 0
+      j = 0
+  101 j = j+1
+      if (j-4) 102,102,103
+  102 ntry = ntryh(j)
+      go to 104
+  103 ntry = ntry+2
+  104 nq = nl/ntry
+      nr = nl-ntry*nq
+      if (nr) 101,105,101
+  105 nf = nf+1
+      ifac(nf+2) = ntry
+      nl = nq
+      if (ntry .ne. 2) go to 107
+      if (nf .eq. 1) go to 107
+      do 106 i=2,nf
+         ib = nf-i+2
+         ifac(ib+2) = ifac(ib+1)
+  106 continue
+      ifac(3) = 2
+  107 if (nl .ne. 1) go to 104
+      ifac(1) = n
+      ifac(2) = nf
+      tpi = 6.28318530717959
+      argh = tpi/dble(n)
+      i = 2
+      l1 = 1
+      do 110 k1=1,nf
+         ip = ifac(k1+2)
+         ld = 0
+         l2 = l1*ip
+         ido = n/l2
+         idot = ido+ido+2
+         ipm = ip-1
+         do 109 j=1,ipm
+            i1 = i
+            wa(i-1) = 1.
+            wa(i) = 0.
+            ld = ld+l1
+            fi = 0.
+            argld = dble(ld)*argh
+            do 108 ii=4,idot,2
+               i = i+2
+               fi = fi+1.
+               arg = fi*argld
+               wa(i-1) = cos(arg)
+               wa(i) = sin(arg)
+  108       continue
+            if (ip .le. 5) go to 109
+            wa(i1-1) = wa(i-1)
+            wa(i1) = wa(i)
+  109    continue
+         l1 = l2
+  110 continue
+      return
+      end
diff --git a/libcruft/fftpack/fftpack.doc b/libcruft/fftpack/fftpack.doc
new file mode 100644
index 0000000..4a08e2e
--- /dev/null
+++ b/libcruft/fftpack/fftpack.doc
@@ -0,0 +1,866 @@
+
+                      FFTPACK
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+                  version 4  april 1985
+
+     a package of fortran subprograms for the fast fourier
+      transform of periodic and other symmetric sequences
+
+                         by
+
+                  paul n swarztrauber
+
+  national center for atmospheric research  boulder,colorado 80307
+
+   which is sponsored by the national science foundation
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+
+this package consists of programs which perform fast fourier
+transforms for both complex and real periodic sequences and
+certain other symmetric sequences that are listed below.
+
+1.   rffti     initialize  rfftf and rfftb
+2.   rfftf     forward transform of a real periodic sequence
+3.   rfftb     backward transform of a real coefficient array
+
+4.   ezffti    initialize ezfftf and ezfftb
+5.   ezfftf    a simplified real periodic forward transform
+6.   ezfftb    a simplified real periodic backward transform
+
+7.   sinti     initialize sint
+8.   sint      sine transform of a real odd sequence
+
+9.   costi     initialize cost
+10.  cost      cosine transform of a real even sequence
+
+11.  sinqi     initialize sinqf and sinqb
+12.  sinqf     forward sine transform with odd wave numbers
+13.  sinqb     unnormalized inverse of sinqf
+
+14.  cosqi     initialize cosqf and cosqb
+15.  cosqf     forward cosine transform with odd wave numbers
+16.  cosqb     unnormalized inverse of cosqf
+
+17.  cffti     initialize cfftf and cfftb
+18.  cfftf     forward transform of a complex periodic sequence
+19.  cfftb     unnormalized inverse of cfftf
+
+
+******************************************************************
+
+subroutine rffti(n,wsave)
+
+  ****************************************************************
+
+subroutine rffti initializes the array wsave which is used in
+both rfftf and rfftb. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the sequence to be transformed.
+
+output parameter
+
+wsave   a work array which must be dimensioned at least 2*n+15.
+        the same work array can be used for both rfftf and rfftb
+        as long as n remains unchanged. different wsave arrays
+        are required for different values of n. the contents of
+        wsave must not be changed between calls of rfftf or rfftb.
+
+******************************************************************
+
+subroutine rfftf(n,r,wsave)
+
+******************************************************************
+
+subroutine rfftf computes the fourier coefficients of a real
+perodic sequence (fourier analysis). the transform is defined
+below at output parameter r.
+
+input parameters
+
+n       the length of the array r to be transformed.  the method
+        is most efficient when n is a product of small primes.
+        n may change so long as different work arrays are provided
+
+r       a real array of length n which contains the sequence
+        to be transformed
+
+wsave   a work array which must be dimensioned at least 2*n+15.
+        in the program that calls rfftf. the wsave array must be
+        initialized by calling subroutine rffti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+        the same wsave array can be used by rfftf and rfftb.
+
+
+output parameters
+
+r       r(1) = the sum from i=1 to i=n of r(i)
+
+        if n is even set l =n/2   , if n is odd set l = (n+1)/2
+
+          then for k = 2,...,l
+
+             r(2*k-2) = the sum from i = 1 to i = n of
+
+                  r(i)*cos((k-1)*(i-1)*2*pi/n)
+
+             r(2*k-1) = the sum from i = 1 to i = n of
+
+                 -r(i)*sin((k-1)*(i-1)*2*pi/n)
+
+        if n is even
+
+             r(n) = the sum from i = 1 to i = n of
+
+                  (-1)**(i-1)*r(i)
+
+ *****  note
+             this transform is unnormalized since a call of rfftf
+             followed by a call of rfftb will multiply the input
+             sequence by n.
+
+wsave   contains results which must not be destroyed between
+        calls of rfftf or rfftb.
+
+
+******************************************************************
+
+subroutine rfftb(n,r,wsave)
+
+******************************************************************
+
+subroutine rfftb computes the real perodic sequence from its
+fourier coefficients (fourier synthesis). the transform is defined
+below at output parameter r.
+
+input parameters
+
+n       the length of the array r to be transformed.  the method
+        is most efficient when n is a product of small primes.
+        n may change so long as different work arrays are provided
+
+r       a real array of length n which contains the sequence
+        to be transformed
+
+wsave   a work array which must be dimensioned at least 2*n+15.
+        in the program that calls rfftb. the wsave array must be
+        initialized by calling subroutine rffti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+        the same wsave array can be used by rfftf and rfftb.
+
+
+output parameters
+
+r       for n even and for i = 1,...,n
+
+             r(i) = r(1)+(-1)**(i-1)*r(n)
+
+                  plus the sum from k=2 to k=n/2 of
+
+                   2.*r(2*k-2)*cos((k-1)*(i-1)*2*pi/n)
+
+                  -2.*r(2*k-1)*sin((k-1)*(i-1)*2*pi/n)
+
+        for n odd and for i = 1,...,n
+
+             r(i) = r(1) plus the sum from k=2 to k=(n+1)/2 of
+
+                  2.*r(2*k-2)*cos((k-1)*(i-1)*2*pi/n)
+
+                 -2.*r(2*k-1)*sin((k-1)*(i-1)*2*pi/n)
+
+ *****  note
+             this transform is unnormalized since a call of rfftf
+             followed by a call of rfftb will multiply the input
+             sequence by n.
+
+wsave   contains results which must not be destroyed between
+        calls of rfftb or rfftf.
+
+
+******************************************************************
+
+subroutine ezffti(n,wsave)
+
+******************************************************************
+
+subroutine ezffti initializes the array wsave which is used in
+both ezfftf and ezfftb. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the sequence to be transformed.
+
+output parameter
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        the same work array can be used for both ezfftf and ezfftb
+        as long as n remains unchanged. different wsave arrays
+        are required for different values of n.
+
+
+******************************************************************
+
+subroutine ezfftf(n,r,azero,a,b,wsave)
+
+******************************************************************
+
+subroutine ezfftf computes the fourier coefficients of a real
+perodic sequence (fourier analysis). the transform is defined
+below at output parameters azero,a and b. ezfftf is a simplified
+but slower version of rfftf.
+
+input parameters
+
+n       the length of the array r to be transformed.  the method
+        is must efficient when n is the product of small primes.
+
+r       a real array of length n which contains the sequence
+        to be transformed. r is not destroyed.
+
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        in the program that calls ezfftf. the wsave array must be
+        initialized by calling subroutine ezffti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+        the same wsave array can be used by ezfftf and ezfftb.
+
+output parameters
+
+azero   the sum from i=1 to i=n of r(i)/n
+
+a,b     for n even b(n/2)=0. and a(n/2) is the sum from i=1 to
+        i=n of (-1)**(i-1)*r(i)/n
+
+        for n even define kmax=n/2-1
+        for n odd  define kmax=(n-1)/2
+
+        then for  k=1,...,kmax
+
+             a(k) equals the sum from i=1 to i=n of
+
+                  2./n*r(i)*cos(k*(i-1)*2*pi/n)
+
+             b(k) equals the sum from i=1 to i=n of
+
+                  2./n*r(i)*sin(k*(i-1)*2*pi/n)
+
+
+******************************************************************
+
+subroutine ezfftb(n,r,azero,a,b,wsave)
+
+******************************************************************
+
+subroutine ezfftb computes a real perodic sequence from its
+fourier coefficients (fourier synthesis). the transform is
+defined below at output parameter r. ezfftb is a simplified
+but slower version of rfftb.
+
+input parameters
+
+n       the length of the output array r.  the method is most
+        efficient when n is the product of small primes.
+
+azero   the constant fourier coefficient
+
+a,b     arrays which contain the remaining fourier coefficients
+        these arrays are not destroyed.
+
+        the length of these arrays depends on whether n is even or
+        odd.
+
+        if n is even n/2    locations are required
+        if n is odd (n-1)/2 locations are required
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        in the program that calls ezfftb. the wsave array must be
+        initialized by calling subroutine ezffti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+        the same wsave array can be used by ezfftf and ezfftb.
+
+
+output parameters
+
+r       if n is even define kmax=n/2
+        if n is odd  define kmax=(n-1)/2
+
+        then for i=1,...,n
+
+             r(i)=azero plus the sum from k=1 to k=kmax of
+
+             a(k)*cos(k*(i-1)*2*pi/n)+b(k)*sin(k*(i-1)*2*pi/n)
+
+********************* complex notation **************************
+
+        for j=1,...,n
+
+        r(j) equals the sum from k=-kmax to k=kmax of
+
+             c(k)*exp(i*k*(j-1)*2*pi/n)
+
+        where
+
+             c(k) = .5*cmplx(a(k),-b(k))   for k=1,...,kmax
+
+             c(-k) = conjg(c(k))
+
+             c(0) = azero
+
+                  and i=sqrt(-1)
+
+*************** amplitude - phase notation ***********************
+
+        for i=1,...,n
+
+        r(i) equals azero plus the sum from k=1 to k=kmax of
+
+             alpha(k)*cos(k*(i-1)*2*pi/n+beta(k))
+
+        where
+
+             alpha(k) = sqrt(a(k)*a(k)+b(k)*b(k))
+
+             cos(beta(k))=a(k)/alpha(k)
+
+             sin(beta(k))=-b(k)/alpha(k)
+
+******************************************************************
+
+subroutine sinti(n,wsave)
+
+******************************************************************
+
+subroutine sinti initializes the array wsave which is used in
+subroutine sint. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the sequence to be transformed.  the method
+        is most efficient when n+1 is a product of small primes.
+
+output parameter
+
+wsave   a work array with at least int(2.5*n+15) locations.
+        different wsave arrays are required for different values
+        of n. the contents of wsave must not be changed between
+        calls of sint.
+
+******************************************************************
+
+subroutine sint(n,x,wsave)
+
+******************************************************************
+
+subroutine sint computes the discrete fourier sine transform
+of an odd sequence x(i). the transform is defined below at
+output parameter x.
+
+sint is the unnormalized inverse of itself since a call of sint
+followed by another call of sint will multiply the input sequence
+x by 2*(n+1).
+
+the array wsave which is used by subroutine sint must be
+initialized by calling subroutine sinti(n,wsave).
+
+input parameters
+
+n       the length of the sequence to be transformed.  the method
+        is most efficient when n+1 is the product of small primes.
+
+x       an array which contains the sequence to be transformed
+
+
+wsave   a work array with dimension at least int(2.5*n+15)
+        in the program that calls sint. the wsave array must be
+        initialized by calling subroutine sinti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+
+output parameters
+
+x       for i=1,...,n
+
+             x(i)= the sum from k=1 to k=n
+
+                  2*x(k)*sin(k*i*pi/(n+1))
+
+             a call of sint followed by another call of
+             sint will multiply the sequence x by 2*(n+1).
+             hence sint is the unnormalized inverse
+             of itself.
+
+wsave   contains initialization calculations which must not be
+        destroyed between calls of sint.
+
+******************************************************************
+
+subroutine costi(n,wsave)
+
+******************************************************************
+
+subroutine costi initializes the array wsave which is used in
+subroutine cost. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the sequence to be transformed.  the method
+        is most efficient when n-1 is a product of small primes.
+
+output parameter
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        different wsave arrays are required for different values
+        of n. the contents of wsave must not be changed between
+        calls of cost.
+
+******************************************************************
+
+subroutine cost(n,x,wsave)
+
+******************************************************************
+
+subroutine cost computes the discrete fourier cosine transform
+of an even sequence x(i). the transform is defined below at output
+parameter x.
+
+cost is the unnormalized inverse of itself since a call of cost
+followed by another call of cost will multiply the input sequence
+x by 2*(n-1). the transform is defined below at output parameter x
+
+the array wsave which is used by subroutine cost must be
+initialized by calling subroutine costi(n,wsave).
+
+input parameters
+
+n       the length of the sequence x. n must be greater than 1.
+        the method is most efficient when n-1 is a product of
+        small primes.
+
+x       an array which contains the sequence to be transformed
+
+wsave   a work array which must be dimensioned at least 3*n+15
+        in the program that calls cost. the wsave array must be
+        initialized by calling subroutine costi(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+
+output parameters
+
+x       for i=1,...,n
+
+            x(i) = x(1)+(-1)**(i-1)*x(n)
+
+             + the sum from k=2 to k=n-1
+
+                 2*x(k)*cos((k-1)*(i-1)*pi/(n-1))
+
+             a call of cost followed by another call of
+             cost will multiply the sequence x by 2*(n-1)
+             hence cost is the unnormalized inverse
+             of itself.
+
+wsave   contains initialization calculations which must not be
+        destroyed between calls of cost.
+
+******************************************************************
+
+subroutine sinqi(n,wsave)
+
+******************************************************************
+
+subroutine sinqi initializes the array wsave which is used in
+both sinqf and sinqb. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the sequence to be transformed. the method
+        is most efficient when n is a product of small primes.
+
+output parameter
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        the same work array can be used for both sinqf and sinqb
+        as long as n remains unchanged. different wsave arrays
+        are required for different values of n. the contents of
+        wsave must not be changed between calls of sinqf or sinqb.
+
+******************************************************************
+
+subroutine sinqf(n,x,wsave)
+
+******************************************************************
+
+subroutine sinqf computes the fast fourier transform of quarter
+wave data. that is , sinqf computes the coefficients in a sine
+series representation with only odd wave numbers. the transform
+is defined below at output parameter x.
+
+sinqb is the unnormalized inverse of sinqf since a call of sinqf
+followed by a call of sinqb will multiply the input sequence x
+by 4*n.
+
+the array wsave which is used by subroutine sinqf must be
+initialized by calling subroutine sinqi(n,wsave).
+
+
+input parameters
+
+n       the length of the array x to be transformed.  the method
+        is most efficient when n is a product of small primes.
+
+x       an array which contains the sequence to be transformed
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        in the program that calls sinqf. the wsave array must be
+        initialized by calling subroutine sinqi(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+
+output parameters
+
+x       for i=1,...,n
+
+             x(i) = (-1)**(i-1)*x(n)
+
+                + the sum from k=1 to k=n-1 of
+
+                2*x(k)*sin((2*i-1)*k*pi/(2*n))
+
+             a call of sinqf followed by a call of
+             sinqb will multiply the sequence x by 4*n.
+             therefore sinqb is the unnormalized inverse
+             of sinqf.
+
+wsave   contains initialization calculations which must not
+        be destroyed between calls of sinqf or sinqb.
+
+******************************************************************
+
+subroutine sinqb(n,x,wsave)
+
+******************************************************************
+
+subroutine sinqb computes the fast fourier transform of quarter
+wave data. that is , sinqb computes a sequence from its
+representation in terms of a sine series with odd wave numbers.
+the transform is defined below at output parameter x.
+
+sinqf is the unnormalized inverse of sinqb since a call of sinqb
+followed by a call of sinqf will multiply the input sequence x
+by 4*n.
+
+the array wsave which is used by subroutine sinqb must be
+initialized by calling subroutine sinqi(n,wsave).
+
+
+input parameters
+
+n       the length of the array x to be transformed.  the method
+        is most efficient when n is a product of small primes.
+
+x       an array which contains the sequence to be transformed
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        in the program that calls sinqb. the wsave array must be
+        initialized by calling subroutine sinqi(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+
+output parameters
+
+x       for i=1,...,n
+
+             x(i)= the sum from k=1 to k=n of
+
+               4*x(k)*sin((2k-1)*i*pi/(2*n))
+
+             a call of sinqb followed by a call of
+             sinqf will multiply the sequence x by 4*n.
+             therefore sinqf is the unnormalized inverse
+             of sinqb.
+
+wsave   contains initialization calculations which must not
+        be destroyed between calls of sinqb or sinqf.
+
+******************************************************************
+
+subroutine cosqi(n,wsave)
+
+******************************************************************
+
+subroutine cosqi initializes the array wsave which is used in
+both cosqf and cosqb. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the array to be transformed.  the method
+        is most efficient when n is a product of small primes.
+
+output parameter
+
+wsave   a work array which must be dimensioned at least 3*n+15.
+        the same work array can be used for both cosqf and cosqb
+        as long as n remains unchanged. different wsave arrays
+        are required for different values of n. the contents of
+        wsave must not be changed between calls of cosqf or cosqb.
+
+******************************************************************
+
+subroutine cosqf(n,x,wsave)
+
+******************************************************************
+
+subroutine cosqf computes the fast fourier transform of quarter
+wave data. that is , cosqf computes the coefficients in a cosine
+series representation with only odd wave numbers. the transform
+is defined below at output parameter x
+
+cosqf is the unnormalized inverse of cosqb since a call of cosqf
+followed by a call of cosqb will multiply the input sequence x
+by 4*n.
+
+the array wsave which is used by subroutine cosqf must be
+initialized by calling subroutine cosqi(n,wsave).
+
+
+input parameters
+
+n       the length of the array x to be transformed.  the method
+        is most efficient when n is a product of small primes.
+
+x       an array which contains the sequence to be transformed
+
+wsave   a work array which must be dimensioned at least 3*n+15
+        in the program that calls cosqf. the wsave array must be
+        initialized by calling subroutine cosqi(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+
+output parameters
+
+x       for i=1,...,n
+
+             x(i) = x(1) plus the sum from k=2 to k=n of
+
+                2*x(k)*cos((2*i-1)*(k-1)*pi/(2*n))
+
+             a call of cosqf followed by a call of
+             cosqb will multiply the sequence x by 4*n.
+             therefore cosqb is the unnormalized inverse
+             of cosqf.
+
+wsave   contains initialization calculations which must not
+        be destroyed between calls of cosqf or cosqb.
+
+******************************************************************
+
+subroutine cosqb(n,x,wsave)
+
+******************************************************************
+
+subroutine cosqb computes the fast fourier transform of quarter
+wave data. that is , cosqb computes a sequence from its
+representation in terms of a cosine series with odd wave numbers.
+the transform is defined below at output parameter x.
+
+cosqb is the unnormalized inverse of cosqf since a call of cosqb
+followed by a call of cosqf will multiply the input sequence x
+by 4*n.
+
+the array wsave which is used by subroutine cosqb must be
+initialized by calling subroutine cosqi(n,wsave).
+
+
+input parameters
+
+n       the length of the array x to be transformed.  the method
+        is most efficient when n is a product of small primes.
+
+x       an array which contains the sequence to be transformed
+
+wsave   a work array that must be dimensioned at least 3*n+15
+        in the program that calls cosqb. the wsave array must be
+        initialized by calling subroutine cosqi(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+
+output parameters
+
+x       for i=1,...,n
+
+             x(i)= the sum from k=1 to k=n of
+
+               4*x(k)*cos((2*k-1)*(i-1)*pi/(2*n))
+
+             a call of cosqb followed by a call of
+             cosqf will multiply the sequence x by 4*n.
+             therefore cosqf is the unnormalized inverse
+             of cosqb.
+
+wsave   contains initialization calculations which must not
+        be destroyed between calls of cosqb or cosqf.
+
+******************************************************************
+
+subroutine cffti(n,wsave)
+
+******************************************************************
+
+subroutine cffti initializes the array wsave which is used in
+both cfftf and cfftb. the prime factorization of n together with
+a tabulation of the trigonometric functions are computed and
+stored in wsave.
+
+input parameter
+
+n       the length of the sequence to be transformed
+
+output parameter
+
+wsave   a work array which must be dimensioned at least 4*n+15
+        the same work array can be used for both cfftf and cfftb
+        as long as n remains unchanged. different wsave arrays
+        are required for different values of n. the contents of
+        wsave must not be changed between calls of cfftf or cfftb.
+
+******************************************************************
+
+subroutine cfftf(n,c,wsave)
+
+******************************************************************
+
+subroutine cfftf computes the forward complex discrete fourier
+transform (the fourier analysis). equivalently , cfftf computes
+the fourier coefficients of a complex periodic sequence.
+the transform is defined below at output parameter c.
+
+the transform is not normalized. to obtain a normalized transform
+the output must be divided by n. otherwise a call of cfftf
+followed by a call of cfftb will multiply the sequence by n.
+
+the array wsave which is used by subroutine cfftf must be
+initialized by calling subroutine cffti(n,wsave).
+
+input parameters
+
+
+n      the length of the complex sequence c. the method is
+       more efficient when n is the product of small primes. n
+
+c      a complex array of length n which contains the sequence
+
+wsave   a real work array which must be dimensioned at least 4n+15
+        in the program that calls cfftf. the wsave array must be
+        initialized by calling subroutine cffti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+        the same wsave array can be used by cfftf and cfftb.
+
+output parameters
+
+c      for j=1,...,n
+
+           c(j)=the sum from k=1,...,n of
+
+                 c(k)*exp(-i*(j-1)*(k-1)*2*pi/n)
+
+                       where i=sqrt(-1)
+
+wsave   contains initialization calculations which must not be
+        destroyed between calls of subroutine cfftf or cfftb
+
+******************************************************************
+
+subroutine cfftb(n,c,wsave)
+
+******************************************************************
+
+subroutine cfftb computes the backward complex discrete fourier
+transform (the fourier synthesis). equivalently , cfftb computes
+a complex periodic sequence from its fourier coefficients.
+the transform is defined below at output parameter c.
+
+a call of cfftf followed by a call of cfftb will multiply the
+sequence by n.
+
+the array wsave which is used by subroutine cfftb must be
+initialized by calling subroutine cffti(n,wsave).
+
+input parameters
+
+
+n      the length of the complex sequence c. the method is
+       more efficient when n is the product of small primes.
+
+c      a complex array of length n which contains the sequence
+
+wsave   a real work array which must be dimensioned at least 4n+15
+        in the program that calls cfftb. the wsave array must be
+        initialized by calling subroutine cffti(n,wsave) and a
+        different wsave array must be used for each different
+        value of n. this initialization does not have to be
+        repeated so long as n remains unchanged thus subsequent
+        transforms can be obtained faster than the first.
+        the same wsave array can be used by cfftf and cfftb.
+
+output parameters
+
+c      for j=1,...,n
+
+           c(j)=the sum from k=1,...,n of
+
+                 c(k)*exp(i*(j-1)*(k-1)*2*pi/n)
+
+                       where i=sqrt(-1)
+
+wsave   contains initialization calculations which must not be
+        destroyed between calls of subroutine cfftf or cfftb
+
+
+
+["send index for vfftpk" describes a vectorized version of fftpack]
+
diff --git a/libcruft/fftpack/passb.f b/libcruft/fftpack/passb.f
new file mode 100644
index 0000000..dbb9426
--- /dev/null
+++ b/libcruft/fftpack/passb.f
@@ -0,0 +1,116 @@
+      subroutine passb (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
+      dimension       ch(ido,l1,ip)          ,cc(ido,ip,l1)          ,
+     1                c1(ido,l1,ip)          ,wa(1)      ,c2(idl1,ip),
+     2                ch2(idl1,ip)
+      idot = ido/2
+      nt = ip*idl1
+      ipp2 = ip+2
+      ipph = (ip+1)/2
+      idp = ip*ido
+c
+      if (ido .lt. l1) go to 106
+      do 103 j=2,ipph
+         jc = ipp2-j
+         do 102 k=1,l1
+            do 101 i=1,ido
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  101       continue
+  102    continue
+  103 continue
+      do 105 k=1,l1
+         do 104 i=1,ido
+            ch(i,k,1) = cc(i,1,k)
+  104    continue
+  105 continue
+      go to 112
+  106 do 109 j=2,ipph
+         jc = ipp2-j
+         do 108 i=1,ido
+            do 107 k=1,l1
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  107       continue
+  108    continue
+  109 continue
+      do 111 i=1,ido
+         do 110 k=1,l1
+            ch(i,k,1) = cc(i,1,k)
+  110    continue
+  111 continue
+  112 idl = 2-ido
+      inc = 0
+      do 116 l=2,ipph
+         lc = ipp2-l
+         idl = idl+ido
+         do 113 ik=1,idl1
+            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
+            c2(ik,lc) = wa(idl)*ch2(ik,ip)
+  113    continue
+         idlj = idl
+         inc = inc+ido
+         do 115 j=3,ipph
+            jc = ipp2-j
+            idlj = idlj+inc
+            if (idlj .gt. idp) idlj = idlj-idp
+            war = wa(idlj-1)
+            wai = wa(idlj)
+            do 114 ik=1,idl1
+               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
+               c2(ik,lc) = c2(ik,lc)+wai*ch2(ik,jc)
+  114       continue
+  115    continue
+  116 continue
+      do 118 j=2,ipph
+         do 117 ik=1,idl1
+            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
+  117    continue
+  118 continue
+      do 120 j=2,ipph
+         jc = ipp2-j
+         do 119 ik=2,idl1,2
+            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
+            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
+            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
+            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
+  119    continue
+  120 continue
+      nac = 1
+      if (ido .eq. 2) return
+      nac = 0
+      do 121 ik=1,idl1
+         c2(ik,1) = ch2(ik,1)
+  121 continue
+      do 123 j=2,ip
+         do 122 k=1,l1
+            c1(1,k,j) = ch(1,k,j)
+            c1(2,k,j) = ch(2,k,j)
+  122    continue
+  123 continue
+      if (idot .gt. l1) go to 127
+      idij = 0
+      do 126 j=2,ip
+         idij = idij+2
+         do 125 i=4,ido,2
+            idij = idij+2
+            do 124 k=1,l1
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
+  124       continue
+  125    continue
+  126 continue
+      return
+  127 idj = 2-ido
+      do 130 j=2,ip
+         idj = idj+ido
+         do 129 k=1,l1
+            idij = idj
+            do 128 i=4,ido,2
+               idij = idij+2
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
+  128       continue
+  129    continue
+  130 continue
+      return
+      end
diff --git a/libcruft/fftpack/passb2.f b/libcruft/fftpack/passb2.f
new file mode 100644
index 0000000..25cd0c0
--- /dev/null
+++ b/libcruft/fftpack/passb2.f
@@ -0,0 +1,23 @@
+      subroutine passb2 (ido,l1,cc,ch,wa1)
+      dimension       cc(ido,2,l1)           ,ch(ido,l1,2)           ,
+     1                wa1(1)
+      if (ido .gt. 2) go to 102
+      do 101 k=1,l1
+         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
+         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
+         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
+         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
+            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
+            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
+            ti2 = cc(i,1,k)-cc(i,2,k)
+            ch(i,k,2) = wa1(i-1)*ti2+wa1(i)*tr2
+            ch(i-1,k,2) = wa1(i-1)*tr2-wa1(i)*ti2
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passb3.f b/libcruft/fftpack/passb3.f
new file mode 100644
index 0000000..b38d98d
--- /dev/null
+++ b/libcruft/fftpack/passb3.f
@@ -0,0 +1,42 @@
+      subroutine passb3 (ido,l1,cc,ch,wa1,wa2)
+      dimension       cc(ido,3,l1)           ,ch(ido,l1,3)           ,
+     1                wa1(1)     ,wa2(1)
+      data taur,taui /-.5,.866025403784439/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         tr2 = cc(1,2,k)+cc(1,3,k)
+         cr2 = cc(1,1,k)+taur*tr2
+         ch(1,k,1) = cc(1,1,k)+tr2
+         ti2 = cc(2,2,k)+cc(2,3,k)
+         ci2 = cc(2,1,k)+taur*ti2
+         ch(2,k,1) = cc(2,1,k)+ti2
+         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
+         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
+         ch(1,k,2) = cr2-ci3
+         ch(1,k,3) = cr2+ci3
+         ch(2,k,2) = ci2+cr3
+         ch(2,k,3) = ci2-cr3
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
+            cr2 = cc(i-1,1,k)+taur*tr2
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2
+            ti2 = cc(i,2,k)+cc(i,3,k)
+            ci2 = cc(i,1,k)+taur*ti2
+            ch(i,k,1) = cc(i,1,k)+ti2
+            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
+            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
+            dr2 = cr2-ci3
+            dr3 = cr2+ci3
+            di2 = ci2+cr3
+            di3 = ci2-cr3
+            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
+            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
+            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
+            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passb4.f b/libcruft/fftpack/passb4.f
new file mode 100644
index 0000000..fa3de06
--- /dev/null
+++ b/libcruft/fftpack/passb4.f
@@ -0,0 +1,51 @@
+      subroutine passb4 (ido,l1,cc,ch,wa1,wa2,wa3)
+      dimension       cc(ido,4,l1)           ,ch(ido,l1,4)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti1 = cc(2,1,k)-cc(2,3,k)
+         ti2 = cc(2,1,k)+cc(2,3,k)
+         tr4 = cc(2,4,k)-cc(2,2,k)
+         ti3 = cc(2,2,k)+cc(2,4,k)
+         tr1 = cc(1,1,k)-cc(1,3,k)
+         tr2 = cc(1,1,k)+cc(1,3,k)
+         ti4 = cc(1,2,k)-cc(1,4,k)
+         tr3 = cc(1,2,k)+cc(1,4,k)
+         ch(1,k,1) = tr2+tr3
+         ch(1,k,3) = tr2-tr3
+         ch(2,k,1) = ti2+ti3
+         ch(2,k,3) = ti2-ti3
+         ch(1,k,2) = tr1+tr4
+         ch(1,k,4) = tr1-tr4
+         ch(2,k,2) = ti1+ti4
+         ch(2,k,4) = ti1-ti4
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti1 = cc(i,1,k)-cc(i,3,k)
+            ti2 = cc(i,1,k)+cc(i,3,k)
+            ti3 = cc(i,2,k)+cc(i,4,k)
+            tr4 = cc(i,4,k)-cc(i,2,k)
+            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
+            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
+            ti4 = cc(i-1,2,k)-cc(i-1,4,k)
+            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = tr2+tr3
+            cr3 = tr2-tr3
+            ch(i,k,1) = ti2+ti3
+            ci3 = ti2-ti3
+            cr2 = tr1+tr4
+            cr4 = tr1-tr4
+            ci2 = ti1+ti4
+            ci4 = ti1-ti4
+            ch(i-1,k,2) = wa1(i-1)*cr2-wa1(i)*ci2
+            ch(i,k,2) = wa1(i-1)*ci2+wa1(i)*cr2
+            ch(i-1,k,3) = wa2(i-1)*cr3-wa2(i)*ci3
+            ch(i,k,3) = wa2(i-1)*ci3+wa2(i)*cr3
+            ch(i-1,k,4) = wa3(i-1)*cr4-wa3(i)*ci4
+            ch(i,k,4) = wa3(i-1)*ci4+wa3(i)*cr4
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passb5.f b/libcruft/fftpack/passb5.f
new file mode 100644
index 0000000..820de33
--- /dev/null
+++ b/libcruft/fftpack/passb5.f
@@ -0,0 +1,75 @@
+      subroutine passb5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
+      dimension       cc(ido,5,l1)           ,ch(ido,l1,5)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)     ,wa4(1)
+      data tr11,ti11,tr12,ti12 /.309016994374947,.951056516295154,
+     1-.809016994374947,.587785252292473/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti5 = cc(2,2,k)-cc(2,5,k)
+         ti2 = cc(2,2,k)+cc(2,5,k)
+         ti4 = cc(2,3,k)-cc(2,4,k)
+         ti3 = cc(2,3,k)+cc(2,4,k)
+         tr5 = cc(1,2,k)-cc(1,5,k)
+         tr2 = cc(1,2,k)+cc(1,5,k)
+         tr4 = cc(1,3,k)-cc(1,4,k)
+         tr3 = cc(1,3,k)+cc(1,4,k)
+         ch(1,k,1) = cc(1,1,k)+tr2+tr3
+         ch(2,k,1) = cc(2,1,k)+ti2+ti3
+         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
+         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
+         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
+         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
+         cr5 = ti11*tr5+ti12*tr4
+         ci5 = ti11*ti5+ti12*ti4
+         cr4 = ti12*tr5-ti11*tr4
+         ci4 = ti12*ti5-ti11*ti4
+         ch(1,k,2) = cr2-ci5
+         ch(1,k,5) = cr2+ci5
+         ch(2,k,2) = ci2+cr5
+         ch(2,k,3) = ci3+cr4
+         ch(1,k,3) = cr3-ci4
+         ch(1,k,4) = cr3+ci4
+         ch(2,k,4) = ci3-cr4
+         ch(2,k,5) = ci2-cr5
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti5 = cc(i,2,k)-cc(i,5,k)
+            ti2 = cc(i,2,k)+cc(i,5,k)
+            ti4 = cc(i,3,k)-cc(i,4,k)
+            ti3 = cc(i,3,k)+cc(i,4,k)
+            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
+            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
+            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
+            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
+            ch(i,k,1) = cc(i,1,k)+ti2+ti3
+            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
+            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
+            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
+            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
+            cr5 = ti11*tr5+ti12*tr4
+            ci5 = ti11*ti5+ti12*ti4
+            cr4 = ti12*tr5-ti11*tr4
+            ci4 = ti12*ti5-ti11*ti4
+            dr3 = cr3-ci4
+            dr4 = cr3+ci4
+            di3 = ci3+cr4
+            di4 = ci3-cr4
+            dr5 = cr2+ci5
+            dr2 = cr2-ci5
+            di5 = ci2-cr5
+            di2 = ci2+cr5
+            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
+            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
+            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
+            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
+            ch(i-1,k,4) = wa3(i-1)*dr4-wa3(i)*di4
+            ch(i,k,4) = wa3(i-1)*di4+wa3(i)*dr4
+            ch(i-1,k,5) = wa4(i-1)*dr5-wa4(i)*di5
+            ch(i,k,5) = wa4(i-1)*di5+wa4(i)*dr5
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passf.f b/libcruft/fftpack/passf.f
new file mode 100644
index 0000000..eec7793
--- /dev/null
+++ b/libcruft/fftpack/passf.f
@@ -0,0 +1,116 @@
+      subroutine passf (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
+      dimension       ch(ido,l1,ip)          ,cc(ido,ip,l1)          ,
+     1                c1(ido,l1,ip)          ,wa(1)      ,c2(idl1,ip),
+     2                ch2(idl1,ip)
+      idot = ido/2
+      nt = ip*idl1
+      ipp2 = ip+2
+      ipph = (ip+1)/2
+      idp = ip*ido
+c
+      if (ido .lt. l1) go to 106
+      do 103 j=2,ipph
+         jc = ipp2-j
+         do 102 k=1,l1
+            do 101 i=1,ido
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  101       continue
+  102    continue
+  103 continue
+      do 105 k=1,l1
+         do 104 i=1,ido
+            ch(i,k,1) = cc(i,1,k)
+  104    continue
+  105 continue
+      go to 112
+  106 do 109 j=2,ipph
+         jc = ipp2-j
+         do 108 i=1,ido
+            do 107 k=1,l1
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  107       continue
+  108    continue
+  109 continue
+      do 111 i=1,ido
+         do 110 k=1,l1
+            ch(i,k,1) = cc(i,1,k)
+  110    continue
+  111 continue
+  112 idl = 2-ido
+      inc = 0
+      do 116 l=2,ipph
+         lc = ipp2-l
+         idl = idl+ido
+         do 113 ik=1,idl1
+            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
+            c2(ik,lc) = -wa(idl)*ch2(ik,ip)
+  113    continue
+         idlj = idl
+         inc = inc+ido
+         do 115 j=3,ipph
+            jc = ipp2-j
+            idlj = idlj+inc
+            if (idlj .gt. idp) idlj = idlj-idp
+            war = wa(idlj-1)
+            wai = wa(idlj)
+            do 114 ik=1,idl1
+               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
+               c2(ik,lc) = c2(ik,lc)-wai*ch2(ik,jc)
+  114       continue
+  115    continue
+  116 continue
+      do 118 j=2,ipph
+         do 117 ik=1,idl1
+            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
+  117    continue
+  118 continue
+      do 120 j=2,ipph
+         jc = ipp2-j
+         do 119 ik=2,idl1,2
+            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
+            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
+            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
+            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
+  119    continue
+  120 continue
+      nac = 1
+      if (ido .eq. 2) return
+      nac = 0
+      do 121 ik=1,idl1
+         c2(ik,1) = ch2(ik,1)
+  121 continue
+      do 123 j=2,ip
+         do 122 k=1,l1
+            c1(1,k,j) = ch(1,k,j)
+            c1(2,k,j) = ch(2,k,j)
+  122    continue
+  123 continue
+      if (idot .gt. l1) go to 127
+      idij = 0
+      do 126 j=2,ip
+         idij = idij+2
+         do 125 i=4,ido,2
+            idij = idij+2
+            do 124 k=1,l1
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
+  124       continue
+  125    continue
+  126 continue
+      return
+  127 idj = 2-ido
+      do 130 j=2,ip
+         idj = idj+ido
+         do 129 k=1,l1
+            idij = idj
+            do 128 i=4,ido,2
+               idij = idij+2
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
+  128       continue
+  129    continue
+  130 continue
+      return
+      end
diff --git a/libcruft/fftpack/passf2.f b/libcruft/fftpack/passf2.f
new file mode 100644
index 0000000..181b993
--- /dev/null
+++ b/libcruft/fftpack/passf2.f
@@ -0,0 +1,23 @@
+      subroutine passf2 (ido,l1,cc,ch,wa1)
+      dimension       cc(ido,2,l1)           ,ch(ido,l1,2)           ,
+     1                wa1(1)
+      if (ido .gt. 2) go to 102
+      do 101 k=1,l1
+         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
+         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
+         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
+         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
+            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
+            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
+            ti2 = cc(i,1,k)-cc(i,2,k)
+            ch(i,k,2) = wa1(i-1)*ti2-wa1(i)*tr2
+            ch(i-1,k,2) = wa1(i-1)*tr2+wa1(i)*ti2
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passf3.f b/libcruft/fftpack/passf3.f
new file mode 100644
index 0000000..154e50a
--- /dev/null
+++ b/libcruft/fftpack/passf3.f
@@ -0,0 +1,42 @@
+      subroutine passf3 (ido,l1,cc,ch,wa1,wa2)
+      dimension       cc(ido,3,l1)           ,ch(ido,l1,3)           ,
+     1                wa1(1)     ,wa2(1)
+      data taur,taui /-.5,-.866025403784439/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         tr2 = cc(1,2,k)+cc(1,3,k)
+         cr2 = cc(1,1,k)+taur*tr2
+         ch(1,k,1) = cc(1,1,k)+tr2
+         ti2 = cc(2,2,k)+cc(2,3,k)
+         ci2 = cc(2,1,k)+taur*ti2
+         ch(2,k,1) = cc(2,1,k)+ti2
+         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
+         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
+         ch(1,k,2) = cr2-ci3
+         ch(1,k,3) = cr2+ci3
+         ch(2,k,2) = ci2+cr3
+         ch(2,k,3) = ci2-cr3
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
+            cr2 = cc(i-1,1,k)+taur*tr2
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2
+            ti2 = cc(i,2,k)+cc(i,3,k)
+            ci2 = cc(i,1,k)+taur*ti2
+            ch(i,k,1) = cc(i,1,k)+ti2
+            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
+            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
+            dr2 = cr2-ci3
+            dr3 = cr2+ci3
+            di2 = ci2+cr3
+            di3 = ci2-cr3
+            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
+            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
+            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
+            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passf4.f b/libcruft/fftpack/passf4.f
new file mode 100644
index 0000000..2f6b468
--- /dev/null
+++ b/libcruft/fftpack/passf4.f
@@ -0,0 +1,51 @@
+      subroutine passf4 (ido,l1,cc,ch,wa1,wa2,wa3)
+      dimension       cc(ido,4,l1)           ,ch(ido,l1,4)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti1 = cc(2,1,k)-cc(2,3,k)
+         ti2 = cc(2,1,k)+cc(2,3,k)
+         tr4 = cc(2,2,k)-cc(2,4,k)
+         ti3 = cc(2,2,k)+cc(2,4,k)
+         tr1 = cc(1,1,k)-cc(1,3,k)
+         tr2 = cc(1,1,k)+cc(1,3,k)
+         ti4 = cc(1,4,k)-cc(1,2,k)
+         tr3 = cc(1,2,k)+cc(1,4,k)
+         ch(1,k,1) = tr2+tr3
+         ch(1,k,3) = tr2-tr3
+         ch(2,k,1) = ti2+ti3
+         ch(2,k,3) = ti2-ti3
+         ch(1,k,2) = tr1+tr4
+         ch(1,k,4) = tr1-tr4
+         ch(2,k,2) = ti1+ti4
+         ch(2,k,4) = ti1-ti4
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti1 = cc(i,1,k)-cc(i,3,k)
+            ti2 = cc(i,1,k)+cc(i,3,k)
+            ti3 = cc(i,2,k)+cc(i,4,k)
+            tr4 = cc(i,2,k)-cc(i,4,k)
+            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
+            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
+            ti4 = cc(i-1,4,k)-cc(i-1,2,k)
+            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = tr2+tr3
+            cr3 = tr2-tr3
+            ch(i,k,1) = ti2+ti3
+            ci3 = ti2-ti3
+            cr2 = tr1+tr4
+            cr4 = tr1-tr4
+            ci2 = ti1+ti4
+            ci4 = ti1-ti4
+            ch(i-1,k,2) = wa1(i-1)*cr2+wa1(i)*ci2
+            ch(i,k,2) = wa1(i-1)*ci2-wa1(i)*cr2
+            ch(i-1,k,3) = wa2(i-1)*cr3+wa2(i)*ci3
+            ch(i,k,3) = wa2(i-1)*ci3-wa2(i)*cr3
+            ch(i-1,k,4) = wa3(i-1)*cr4+wa3(i)*ci4
+            ch(i,k,4) = wa3(i-1)*ci4-wa3(i)*cr4
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/passf5.f b/libcruft/fftpack/passf5.f
new file mode 100644
index 0000000..4505bde
--- /dev/null
+++ b/libcruft/fftpack/passf5.f
@@ -0,0 +1,75 @@
+      subroutine passf5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
+      dimension       cc(ido,5,l1)           ,ch(ido,l1,5)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)     ,wa4(1)
+      data tr11,ti11,tr12,ti12 /.309016994374947,-.951056516295154,
+     1-.809016994374947,-.587785252292473/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti5 = cc(2,2,k)-cc(2,5,k)
+         ti2 = cc(2,2,k)+cc(2,5,k)
+         ti4 = cc(2,3,k)-cc(2,4,k)
+         ti3 = cc(2,3,k)+cc(2,4,k)
+         tr5 = cc(1,2,k)-cc(1,5,k)
+         tr2 = cc(1,2,k)+cc(1,5,k)
+         tr4 = cc(1,3,k)-cc(1,4,k)
+         tr3 = cc(1,3,k)+cc(1,4,k)
+         ch(1,k,1) = cc(1,1,k)+tr2+tr3
+         ch(2,k,1) = cc(2,1,k)+ti2+ti3
+         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
+         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
+         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
+         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
+         cr5 = ti11*tr5+ti12*tr4
+         ci5 = ti11*ti5+ti12*ti4
+         cr4 = ti12*tr5-ti11*tr4
+         ci4 = ti12*ti5-ti11*ti4
+         ch(1,k,2) = cr2-ci5
+         ch(1,k,5) = cr2+ci5
+         ch(2,k,2) = ci2+cr5
+         ch(2,k,3) = ci3+cr4
+         ch(1,k,3) = cr3-ci4
+         ch(1,k,4) = cr3+ci4
+         ch(2,k,4) = ci3-cr4
+         ch(2,k,5) = ci2-cr5
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti5 = cc(i,2,k)-cc(i,5,k)
+            ti2 = cc(i,2,k)+cc(i,5,k)
+            ti4 = cc(i,3,k)-cc(i,4,k)
+            ti3 = cc(i,3,k)+cc(i,4,k)
+            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
+            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
+            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
+            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
+            ch(i,k,1) = cc(i,1,k)+ti2+ti3
+            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
+            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
+            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
+            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
+            cr5 = ti11*tr5+ti12*tr4
+            ci5 = ti11*ti5+ti12*ti4
+            cr4 = ti12*tr5-ti11*tr4
+            ci4 = ti12*ti5-ti11*ti4
+            dr3 = cr3-ci4
+            dr4 = cr3+ci4
+            di3 = ci3+cr4
+            di4 = ci3-cr4
+            dr5 = cr2+ci5
+            dr2 = cr2-ci5
+            di5 = ci2-cr5
+            di2 = ci2+cr5
+            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
+            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
+            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
+            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
+            ch(i-1,k,4) = wa3(i-1)*dr4+wa3(i)*di4
+            ch(i,k,4) = wa3(i-1)*di4-wa3(i)*dr4
+            ch(i-1,k,5) = wa4(i-1)*dr5+wa4(i)*di5
+            ch(i,k,5) = wa4(i-1)*di5-wa4(i)*dr5
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zfftb.f b/libcruft/fftpack/zfftb.f
new file mode 100644
index 0000000..e65cf95
--- /dev/null
+++ b/libcruft/fftpack/zfftb.f
@@ -0,0 +1,9 @@
+      subroutine zfftb (n,c,wsave)
+      implicit double precision (a-h,o-z)
+      dimension       c(*)       ,wsave(*)
+      if (n .eq. 1) return
+      iw1 = n+n+1
+      iw2 = iw1+n+n
+      call zfftb1 (n,c,wsave,wsave(iw1),wsave(iw2))
+      return
+      end
diff --git a/libcruft/fftpack/zfftb1.f b/libcruft/fftpack/zfftb1.f
new file mode 100644
index 0000000..6f03f90
--- /dev/null
+++ b/libcruft/fftpack/zfftb1.f
@@ -0,0 +1,62 @@
+      subroutine zfftb1 (n,c,ch,wa,ifac)
+      implicit double precision (a-h,o-z)
+      dimension       ch(*)      ,c(*)       ,wa(*)      ,ifac(*)
+      nf = ifac(2)
+      na = 0
+      l1 = 1
+      iw = 1
+      do 116 k1=1,nf
+         ip = ifac(k1+2)
+         l2 = ip*l1
+         ido = n/l2
+         idot = ido+ido
+         idl1 = idot*l1
+         if (ip .ne. 4) go to 103
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         if (na .ne. 0) go to 101
+         call zpassb4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
+         go to 102
+  101    call zpassb4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
+  102    na = 1-na
+         go to 115
+  103    if (ip .ne. 2) go to 106
+         if (na .ne. 0) go to 104
+         call zpassb2 (idot,l1,c,ch,wa(iw))
+         go to 105
+  104    call zpassb2 (idot,l1,ch,c,wa(iw))
+  105    na = 1-na
+         go to 115
+  106    if (ip .ne. 3) go to 109
+         ix2 = iw+idot
+         if (na .ne. 0) go to 107
+         call zpassb3 (idot,l1,c,ch,wa(iw),wa(ix2))
+         go to 108
+  107    call zpassb3 (idot,l1,ch,c,wa(iw),wa(ix2))
+  108    na = 1-na
+         go to 115
+  109    if (ip .ne. 5) go to 112
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         ix4 = ix3+idot
+         if (na .ne. 0) go to 110
+         call zpassb5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+         go to 111
+  110    call zpassb5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+  111    na = 1-na
+         go to 115
+  112    if (na .ne. 0) go to 113
+         call zpassb (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
+         go to 114
+  113    call zpassb (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
+  114    if (nac .ne. 0) na = 1-na
+  115    l1 = l2
+         iw = iw+(ip-1)*idot
+  116 continue
+      if (na .eq. 0) return
+      n2 = n+n
+      do 117 i=1,n2
+         c(i) = ch(i)
+  117 continue
+      return
+      end
diff --git a/libcruft/fftpack/zfftf.f b/libcruft/fftpack/zfftf.f
new file mode 100644
index 0000000..2979f82
--- /dev/null
+++ b/libcruft/fftpack/zfftf.f
@@ -0,0 +1,9 @@
+      subroutine zfftf (n,c,wsave)
+      implicit double precision (a-h,o-z)
+      dimension       c(*)       ,wsave(*)
+      if (n .eq. 1) return
+      iw1 = n+n+1
+      iw2 = iw1+n+n
+      call zfftf1 (n,c,wsave,wsave(iw1),wsave(iw2))
+      return
+      end
diff --git a/libcruft/fftpack/zfftf1.f b/libcruft/fftpack/zfftf1.f
new file mode 100644
index 0000000..b889416
--- /dev/null
+++ b/libcruft/fftpack/zfftf1.f
@@ -0,0 +1,62 @@
+      subroutine zfftf1 (n,c,ch,wa,ifac)
+      implicit double precision (a-h,o-z)
+      dimension       ch(*)      ,c(*)       ,wa(*)      ,ifac(*)
+      nf = ifac(2)
+      na = 0
+      l1 = 1
+      iw = 1
+      do 116 k1=1,nf
+         ip = ifac(k1+2)
+         l2 = ip*l1
+         ido = n/l2
+         idot = ido+ido
+         idl1 = idot*l1
+         if (ip .ne. 4) go to 103
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         if (na .ne. 0) go to 101
+         call zpassf4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
+         go to 102
+  101    call zpassf4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
+  102    na = 1-na
+         go to 115
+  103    if (ip .ne. 2) go to 106
+         if (na .ne. 0) go to 104
+         call zpassf2 (idot,l1,c,ch,wa(iw))
+         go to 105
+  104    call zpassf2 (idot,l1,ch,c,wa(iw))
+  105    na = 1-na
+         go to 115
+  106    if (ip .ne. 3) go to 109
+         ix2 = iw+idot
+         if (na .ne. 0) go to 107
+         call zpassf3 (idot,l1,c,ch,wa(iw),wa(ix2))
+         go to 108
+  107    call zpassf3 (idot,l1,ch,c,wa(iw),wa(ix2))
+  108    na = 1-na
+         go to 115
+  109    if (ip .ne. 5) go to 112
+         ix2 = iw+idot
+         ix3 = ix2+idot
+         ix4 = ix3+idot
+         if (na .ne. 0) go to 110
+         call zpassf5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+         go to 111
+  110    call zpassf5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
+  111    na = 1-na
+         go to 115
+  112    if (na .ne. 0) go to 113
+         call zpassf (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
+         go to 114
+  113    call zpassf (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
+  114    if (nac .ne. 0) na = 1-na
+  115    l1 = l2
+         iw = iw+(ip-1)*idot
+  116 continue
+      if (na .eq. 0) return
+      n2 = n+n
+      do 117 i=1,n2
+         c(i) = ch(i)
+  117 continue
+      return
+      end
diff --git a/libcruft/fftpack/zffti.f b/libcruft/fftpack/zffti.f
new file mode 100644
index 0000000..ff9b77f
--- /dev/null
+++ b/libcruft/fftpack/zffti.f
@@ -0,0 +1,9 @@
+      subroutine zffti (n,wsave)
+      implicit double precision (a-h,o-z)
+      dimension       wsave(*)
+      if (n .eq. 1) return
+      iw1 = n+n+1
+      iw2 = iw1+n+n
+      call zffti1 (n,wsave(iw1),wsave(iw2))
+      return
+      end
diff --git a/libcruft/fftpack/zffti1.f b/libcruft/fftpack/zffti1.f
new file mode 100644
index 0000000..b26fde2
--- /dev/null
+++ b/libcruft/fftpack/zffti1.f
@@ -0,0 +1,61 @@
+      subroutine zffti1 (n,wa,ifac)
+      implicit double precision (a-h,o-z)
+      dimension       wa(*)      ,ifac(*)    ,ntryh(4)
+      data ntryh(1),ntryh(2),ntryh(3),ntryh(4)/3,4,2,5/
+      nl = n
+      nf = 0
+      j = 0
+  101 j = j+1
+      if (j-4) 102,102,103
+  102 ntry = ntryh(j)
+      go to 104
+  103 ntry = ntry+2
+  104 nq = nl/ntry
+      nr = nl-ntry*nq
+      if (nr) 101,105,101
+  105 nf = nf+1
+      ifac(nf+2) = ntry
+      nl = nq
+      if (ntry .ne. 2) go to 107
+      if (nf .eq. 1) go to 107
+      do 106 i=2,nf
+         ib = nf-i+2
+         ifac(ib+2) = ifac(ib+1)
+  106 continue
+      ifac(3) = 2
+  107 if (nl .ne. 1) go to 104
+      ifac(1) = n
+      ifac(2) = nf
+      tpi = 6.28318530717959d0
+      argh = tpi/dble(n)
+      i = 2
+      l1 = 1
+      do 110 k1=1,nf
+         ip = ifac(k1+2)
+         ld = 0
+         l2 = l1*ip
+         ido = n/l2
+         idot = ido+ido+2
+         ipm = ip-1
+         do 109 j=1,ipm
+            i1 = i
+            wa(i-1) = 1.
+            wa(i) = 0.
+            ld = ld+l1
+            fi = 0.
+            argld = dble(ld)*argh
+            do 108 ii=4,idot,2
+               i = i+2
+               fi = fi+1.
+               arg = fi*argld
+               wa(i-1) = cos(arg)
+               wa(i) = sin(arg)
+  108       continue
+            if (ip .le. 5) go to 109
+            wa(i1-1) = wa(i-1)
+            wa(i1) = wa(i)
+  109    continue
+         l1 = l2
+  110 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassb.f b/libcruft/fftpack/zpassb.f
new file mode 100644
index 0000000..8922358
--- /dev/null
+++ b/libcruft/fftpack/zpassb.f
@@ -0,0 +1,117 @@
+      subroutine zpassb (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
+      implicit double precision (a-h,o-z)
+      dimension       ch(ido,l1,ip)          ,cc(ido,ip,l1)          ,
+     1                c1(ido,l1,ip)          ,wa(1)      ,c2(idl1,ip),
+     2                ch2(idl1,ip)
+      idot = ido/2
+      nt = ip*idl1
+      ipp2 = ip+2
+      ipph = (ip+1)/2
+      idp = ip*ido
+c
+      if (ido .lt. l1) go to 106
+      do 103 j=2,ipph
+         jc = ipp2-j
+         do 102 k=1,l1
+            do 101 i=1,ido
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  101       continue
+  102    continue
+  103 continue
+      do 105 k=1,l1
+         do 104 i=1,ido
+            ch(i,k,1) = cc(i,1,k)
+  104    continue
+  105 continue
+      go to 112
+  106 do 109 j=2,ipph
+         jc = ipp2-j
+         do 108 i=1,ido
+            do 107 k=1,l1
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  107       continue
+  108    continue
+  109 continue
+      do 111 i=1,ido
+         do 110 k=1,l1
+            ch(i,k,1) = cc(i,1,k)
+  110    continue
+  111 continue
+  112 idl = 2-ido
+      inc = 0
+      do 116 l=2,ipph
+         lc = ipp2-l
+         idl = idl+ido
+         do 113 ik=1,idl1
+            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
+            c2(ik,lc) = wa(idl)*ch2(ik,ip)
+  113    continue
+         idlj = idl
+         inc = inc+ido
+         do 115 j=3,ipph
+            jc = ipp2-j
+            idlj = idlj+inc
+            if (idlj .gt. idp) idlj = idlj-idp
+            war = wa(idlj-1)
+            wai = wa(idlj)
+            do 114 ik=1,idl1
+               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
+               c2(ik,lc) = c2(ik,lc)+wai*ch2(ik,jc)
+  114       continue
+  115    continue
+  116 continue
+      do 118 j=2,ipph
+         do 117 ik=1,idl1
+            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
+  117    continue
+  118 continue
+      do 120 j=2,ipph
+         jc = ipp2-j
+         do 119 ik=2,idl1,2
+            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
+            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
+            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
+            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
+  119    continue
+  120 continue
+      nac = 1
+      if (ido .eq. 2) return
+      nac = 0
+      do 121 ik=1,idl1
+         c2(ik,1) = ch2(ik,1)
+  121 continue
+      do 123 j=2,ip
+         do 122 k=1,l1
+            c1(1,k,j) = ch(1,k,j)
+            c1(2,k,j) = ch(2,k,j)
+  122    continue
+  123 continue
+      if (idot .gt. l1) go to 127
+      idij = 0
+      do 126 j=2,ip
+         idij = idij+2
+         do 125 i=4,ido,2
+            idij = idij+2
+            do 124 k=1,l1
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
+  124       continue
+  125    continue
+  126 continue
+      return
+  127 idj = 2-ido
+      do 130 j=2,ip
+         idj = idj+ido
+         do 129 k=1,l1
+            idij = idj
+            do 128 i=4,ido,2
+               idij = idij+2
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
+  128       continue
+  129    continue
+  130 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassb2.f b/libcruft/fftpack/zpassb2.f
new file mode 100644
index 0000000..645c038
--- /dev/null
+++ b/libcruft/fftpack/zpassb2.f
@@ -0,0 +1,24 @@
+      subroutine zpassb2 (ido,l1,cc,ch,wa1)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,2,l1)           ,ch(ido,l1,2)           ,
+     1                wa1(1)
+      if (ido .gt. 2) go to 102
+      do 101 k=1,l1
+         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
+         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
+         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
+         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
+            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
+            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
+            ti2 = cc(i,1,k)-cc(i,2,k)
+            ch(i,k,2) = wa1(i-1)*ti2+wa1(i)*tr2
+            ch(i-1,k,2) = wa1(i-1)*tr2-wa1(i)*ti2
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassb3.f b/libcruft/fftpack/zpassb3.f
new file mode 100644
index 0000000..7e45cfb
--- /dev/null
+++ b/libcruft/fftpack/zpassb3.f
@@ -0,0 +1,43 @@
+      subroutine zpassb3 (ido,l1,cc,ch,wa1,wa2)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,3,l1)           ,ch(ido,l1,3)           ,
+     1                wa1(1)     ,wa2(1)
+      data taur,taui /-.5,.866025403784439d0/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         tr2 = cc(1,2,k)+cc(1,3,k)
+         cr2 = cc(1,1,k)+taur*tr2
+         ch(1,k,1) = cc(1,1,k)+tr2
+         ti2 = cc(2,2,k)+cc(2,3,k)
+         ci2 = cc(2,1,k)+taur*ti2
+         ch(2,k,1) = cc(2,1,k)+ti2
+         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
+         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
+         ch(1,k,2) = cr2-ci3
+         ch(1,k,3) = cr2+ci3
+         ch(2,k,2) = ci2+cr3
+         ch(2,k,3) = ci2-cr3
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
+            cr2 = cc(i-1,1,k)+taur*tr2
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2
+            ti2 = cc(i,2,k)+cc(i,3,k)
+            ci2 = cc(i,1,k)+taur*ti2
+            ch(i,k,1) = cc(i,1,k)+ti2
+            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
+            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
+            dr2 = cr2-ci3
+            dr3 = cr2+ci3
+            di2 = ci2+cr3
+            di3 = ci2-cr3
+            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
+            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
+            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
+            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassb4.f b/libcruft/fftpack/zpassb4.f
new file mode 100644
index 0000000..7cea396
--- /dev/null
+++ b/libcruft/fftpack/zpassb4.f
@@ -0,0 +1,52 @@
+      subroutine zpassb4 (ido,l1,cc,ch,wa1,wa2,wa3)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,4,l1)           ,ch(ido,l1,4)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti1 = cc(2,1,k)-cc(2,3,k)
+         ti2 = cc(2,1,k)+cc(2,3,k)
+         tr4 = cc(2,4,k)-cc(2,2,k)
+         ti3 = cc(2,2,k)+cc(2,4,k)
+         tr1 = cc(1,1,k)-cc(1,3,k)
+         tr2 = cc(1,1,k)+cc(1,3,k)
+         ti4 = cc(1,2,k)-cc(1,4,k)
+         tr3 = cc(1,2,k)+cc(1,4,k)
+         ch(1,k,1) = tr2+tr3
+         ch(1,k,3) = tr2-tr3
+         ch(2,k,1) = ti2+ti3
+         ch(2,k,3) = ti2-ti3
+         ch(1,k,2) = tr1+tr4
+         ch(1,k,4) = tr1-tr4
+         ch(2,k,2) = ti1+ti4
+         ch(2,k,4) = ti1-ti4
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti1 = cc(i,1,k)-cc(i,3,k)
+            ti2 = cc(i,1,k)+cc(i,3,k)
+            ti3 = cc(i,2,k)+cc(i,4,k)
+            tr4 = cc(i,4,k)-cc(i,2,k)
+            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
+            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
+            ti4 = cc(i-1,2,k)-cc(i-1,4,k)
+            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = tr2+tr3
+            cr3 = tr2-tr3
+            ch(i,k,1) = ti2+ti3
+            ci3 = ti2-ti3
+            cr2 = tr1+tr4
+            cr4 = tr1-tr4
+            ci2 = ti1+ti4
+            ci4 = ti1-ti4
+            ch(i-1,k,2) = wa1(i-1)*cr2-wa1(i)*ci2
+            ch(i,k,2) = wa1(i-1)*ci2+wa1(i)*cr2
+            ch(i-1,k,3) = wa2(i-1)*cr3-wa2(i)*ci3
+            ch(i,k,3) = wa2(i-1)*ci3+wa2(i)*cr3
+            ch(i-1,k,4) = wa3(i-1)*cr4-wa3(i)*ci4
+            ch(i,k,4) = wa3(i-1)*ci4+wa3(i)*cr4
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassb5.f b/libcruft/fftpack/zpassb5.f
new file mode 100644
index 0000000..621494c
--- /dev/null
+++ b/libcruft/fftpack/zpassb5.f
@@ -0,0 +1,76 @@
+      subroutine zpassb5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,5,l1)           ,ch(ido,l1,5)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)     ,wa4(1)
+      data tr11,ti11,tr12,ti12 /.309016994374947d0,.951056516295154d0,
+     1-.809016994374947d0,.587785252292473d0/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti5 = cc(2,2,k)-cc(2,5,k)
+         ti2 = cc(2,2,k)+cc(2,5,k)
+         ti4 = cc(2,3,k)-cc(2,4,k)
+         ti3 = cc(2,3,k)+cc(2,4,k)
+         tr5 = cc(1,2,k)-cc(1,5,k)
+         tr2 = cc(1,2,k)+cc(1,5,k)
+         tr4 = cc(1,3,k)-cc(1,4,k)
+         tr3 = cc(1,3,k)+cc(1,4,k)
+         ch(1,k,1) = cc(1,1,k)+tr2+tr3
+         ch(2,k,1) = cc(2,1,k)+ti2+ti3
+         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
+         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
+         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
+         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
+         cr5 = ti11*tr5+ti12*tr4
+         ci5 = ti11*ti5+ti12*ti4
+         cr4 = ti12*tr5-ti11*tr4
+         ci4 = ti12*ti5-ti11*ti4
+         ch(1,k,2) = cr2-ci5
+         ch(1,k,5) = cr2+ci5
+         ch(2,k,2) = ci2+cr5
+         ch(2,k,3) = ci3+cr4
+         ch(1,k,3) = cr3-ci4
+         ch(1,k,4) = cr3+ci4
+         ch(2,k,4) = ci3-cr4
+         ch(2,k,5) = ci2-cr5
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti5 = cc(i,2,k)-cc(i,5,k)
+            ti2 = cc(i,2,k)+cc(i,5,k)
+            ti4 = cc(i,3,k)-cc(i,4,k)
+            ti3 = cc(i,3,k)+cc(i,4,k)
+            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
+            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
+            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
+            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
+            ch(i,k,1) = cc(i,1,k)+ti2+ti3
+            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
+            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
+            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
+            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
+            cr5 = ti11*tr5+ti12*tr4
+            ci5 = ti11*ti5+ti12*ti4
+            cr4 = ti12*tr5-ti11*tr4
+            ci4 = ti12*ti5-ti11*ti4
+            dr3 = cr3-ci4
+            dr4 = cr3+ci4
+            di3 = ci3+cr4
+            di4 = ci3-cr4
+            dr5 = cr2+ci5
+            dr2 = cr2-ci5
+            di5 = ci2-cr5
+            di2 = ci2+cr5
+            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
+            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
+            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
+            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
+            ch(i-1,k,4) = wa3(i-1)*dr4-wa3(i)*di4
+            ch(i,k,4) = wa3(i-1)*di4+wa3(i)*dr4
+            ch(i-1,k,5) = wa4(i-1)*dr5-wa4(i)*di5
+            ch(i,k,5) = wa4(i-1)*di5+wa4(i)*dr5
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassf.f b/libcruft/fftpack/zpassf.f
new file mode 100644
index 0000000..6bcd1a3
--- /dev/null
+++ b/libcruft/fftpack/zpassf.f
@@ -0,0 +1,117 @@
+      subroutine zpassf (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
+      implicit double precision (a-h,o-z)
+      dimension       ch(ido,l1,ip)          ,cc(ido,ip,l1)          ,
+     1                c1(ido,l1,ip)          ,wa(1)      ,c2(idl1,ip),
+     2                ch2(idl1,ip)
+      idot = ido/2
+      nt = ip*idl1
+      ipp2 = ip+2
+      ipph = (ip+1)/2
+      idp = ip*ido
+c
+      if (ido .lt. l1) go to 106
+      do 103 j=2,ipph
+         jc = ipp2-j
+         do 102 k=1,l1
+            do 101 i=1,ido
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  101       continue
+  102    continue
+  103 continue
+      do 105 k=1,l1
+         do 104 i=1,ido
+            ch(i,k,1) = cc(i,1,k)
+  104    continue
+  105 continue
+      go to 112
+  106 do 109 j=2,ipph
+         jc = ipp2-j
+         do 108 i=1,ido
+            do 107 k=1,l1
+               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
+               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
+  107       continue
+  108    continue
+  109 continue
+      do 111 i=1,ido
+         do 110 k=1,l1
+            ch(i,k,1) = cc(i,1,k)
+  110    continue
+  111 continue
+  112 idl = 2-ido
+      inc = 0
+      do 116 l=2,ipph
+         lc = ipp2-l
+         idl = idl+ido
+         do 113 ik=1,idl1
+            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
+            c2(ik,lc) = -wa(idl)*ch2(ik,ip)
+  113    continue
+         idlj = idl
+         inc = inc+ido
+         do 115 j=3,ipph
+            jc = ipp2-j
+            idlj = idlj+inc
+            if (idlj .gt. idp) idlj = idlj-idp
+            war = wa(idlj-1)
+            wai = wa(idlj)
+            do 114 ik=1,idl1
+               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
+               c2(ik,lc) = c2(ik,lc)-wai*ch2(ik,jc)
+  114       continue
+  115    continue
+  116 continue
+      do 118 j=2,ipph
+         do 117 ik=1,idl1
+            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
+  117    continue
+  118 continue
+      do 120 j=2,ipph
+         jc = ipp2-j
+         do 119 ik=2,idl1,2
+            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
+            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
+            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
+            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
+  119    continue
+  120 continue
+      nac = 1
+      if (ido .eq. 2) return
+      nac = 0
+      do 121 ik=1,idl1
+         c2(ik,1) = ch2(ik,1)
+  121 continue
+      do 123 j=2,ip
+         do 122 k=1,l1
+            c1(1,k,j) = ch(1,k,j)
+            c1(2,k,j) = ch(2,k,j)
+  122    continue
+  123 continue
+      if (idot .gt. l1) go to 127
+      idij = 0
+      do 126 j=2,ip
+         idij = idij+2
+         do 125 i=4,ido,2
+            idij = idij+2
+            do 124 k=1,l1
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
+  124       continue
+  125    continue
+  126 continue
+      return
+  127 idj = 2-ido
+      do 130 j=2,ip
+         idj = idj+ido
+         do 129 k=1,l1
+            idij = idj
+            do 128 i=4,ido,2
+               idij = idij+2
+               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
+               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
+  128       continue
+  129    continue
+  130 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassf2.f b/libcruft/fftpack/zpassf2.f
new file mode 100644
index 0000000..75ac33d
--- /dev/null
+++ b/libcruft/fftpack/zpassf2.f
@@ -0,0 +1,24 @@
+      subroutine zpassf2 (ido,l1,cc,ch,wa1)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,2,l1)           ,ch(ido,l1,2)           ,
+     1                wa1(1)
+      if (ido .gt. 2) go to 102
+      do 101 k=1,l1
+         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
+         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
+         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
+         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
+            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
+            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
+            ti2 = cc(i,1,k)-cc(i,2,k)
+            ch(i,k,2) = wa1(i-1)*ti2-wa1(i)*tr2
+            ch(i-1,k,2) = wa1(i-1)*tr2+wa1(i)*ti2
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassf3.f b/libcruft/fftpack/zpassf3.f
new file mode 100644
index 0000000..67d6855
--- /dev/null
+++ b/libcruft/fftpack/zpassf3.f
@@ -0,0 +1,43 @@
+      subroutine zpassf3 (ido,l1,cc,ch,wa1,wa2)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,3,l1)           ,ch(ido,l1,3)           ,
+     1                wa1(1)     ,wa2(1)
+      data taur,taui /-.5d0,-.866025403784439d0/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         tr2 = cc(1,2,k)+cc(1,3,k)
+         cr2 = cc(1,1,k)+taur*tr2
+         ch(1,k,1) = cc(1,1,k)+tr2
+         ti2 = cc(2,2,k)+cc(2,3,k)
+         ci2 = cc(2,1,k)+taur*ti2
+         ch(2,k,1) = cc(2,1,k)+ti2
+         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
+         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
+         ch(1,k,2) = cr2-ci3
+         ch(1,k,3) = cr2+ci3
+         ch(2,k,2) = ci2+cr3
+         ch(2,k,3) = ci2-cr3
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
+            cr2 = cc(i-1,1,k)+taur*tr2
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2
+            ti2 = cc(i,2,k)+cc(i,3,k)
+            ci2 = cc(i,1,k)+taur*ti2
+            ch(i,k,1) = cc(i,1,k)+ti2
+            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
+            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
+            dr2 = cr2-ci3
+            dr3 = cr2+ci3
+            di2 = ci2+cr3
+            di3 = ci2-cr3
+            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
+            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
+            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
+            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassf4.f b/libcruft/fftpack/zpassf4.f
new file mode 100644
index 0000000..35cb553
--- /dev/null
+++ b/libcruft/fftpack/zpassf4.f
@@ -0,0 +1,52 @@
+      subroutine zpassf4 (ido,l1,cc,ch,wa1,wa2,wa3)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,4,l1)           ,ch(ido,l1,4)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti1 = cc(2,1,k)-cc(2,3,k)
+         ti2 = cc(2,1,k)+cc(2,3,k)
+         tr4 = cc(2,2,k)-cc(2,4,k)
+         ti3 = cc(2,2,k)+cc(2,4,k)
+         tr1 = cc(1,1,k)-cc(1,3,k)
+         tr2 = cc(1,1,k)+cc(1,3,k)
+         ti4 = cc(1,4,k)-cc(1,2,k)
+         tr3 = cc(1,2,k)+cc(1,4,k)
+         ch(1,k,1) = tr2+tr3
+         ch(1,k,3) = tr2-tr3
+         ch(2,k,1) = ti2+ti3
+         ch(2,k,3) = ti2-ti3
+         ch(1,k,2) = tr1+tr4
+         ch(1,k,4) = tr1-tr4
+         ch(2,k,2) = ti1+ti4
+         ch(2,k,4) = ti1-ti4
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti1 = cc(i,1,k)-cc(i,3,k)
+            ti2 = cc(i,1,k)+cc(i,3,k)
+            ti3 = cc(i,2,k)+cc(i,4,k)
+            tr4 = cc(i,2,k)-cc(i,4,k)
+            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
+            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
+            ti4 = cc(i-1,4,k)-cc(i-1,2,k)
+            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = tr2+tr3
+            cr3 = tr2-tr3
+            ch(i,k,1) = ti2+ti3
+            ci3 = ti2-ti3
+            cr2 = tr1+tr4
+            cr4 = tr1-tr4
+            ci2 = ti1+ti4
+            ci4 = ti1-ti4
+            ch(i-1,k,2) = wa1(i-1)*cr2+wa1(i)*ci2
+            ch(i,k,2) = wa1(i-1)*ci2-wa1(i)*cr2
+            ch(i-1,k,3) = wa2(i-1)*cr3+wa2(i)*ci3
+            ch(i,k,3) = wa2(i-1)*ci3-wa2(i)*cr3
+            ch(i-1,k,4) = wa3(i-1)*cr4+wa3(i)*ci4
+            ch(i,k,4) = wa3(i-1)*ci4-wa3(i)*cr4
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/fftpack/zpassf5.f b/libcruft/fftpack/zpassf5.f
new file mode 100644
index 0000000..1520806
--- /dev/null
+++ b/libcruft/fftpack/zpassf5.f
@@ -0,0 +1,76 @@
+      subroutine zpassf5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
+      implicit double precision (a-h,o-z)
+      dimension       cc(ido,5,l1)           ,ch(ido,l1,5)           ,
+     1                wa1(1)     ,wa2(1)     ,wa3(1)     ,wa4(1)
+      data tr11,ti11,tr12,ti12 /.309016994374947d0,-.951056516295154d0,
+     1-.809016994374947d0,-.587785252292473d0/
+      if (ido .ne. 2) go to 102
+      do 101 k=1,l1
+         ti5 = cc(2,2,k)-cc(2,5,k)
+         ti2 = cc(2,2,k)+cc(2,5,k)
+         ti4 = cc(2,3,k)-cc(2,4,k)
+         ti3 = cc(2,3,k)+cc(2,4,k)
+         tr5 = cc(1,2,k)-cc(1,5,k)
+         tr2 = cc(1,2,k)+cc(1,5,k)
+         tr4 = cc(1,3,k)-cc(1,4,k)
+         tr3 = cc(1,3,k)+cc(1,4,k)
+         ch(1,k,1) = cc(1,1,k)+tr2+tr3
+         ch(2,k,1) = cc(2,1,k)+ti2+ti3
+         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
+         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
+         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
+         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
+         cr5 = ti11*tr5+ti12*tr4
+         ci5 = ti11*ti5+ti12*ti4
+         cr4 = ti12*tr5-ti11*tr4
+         ci4 = ti12*ti5-ti11*ti4
+         ch(1,k,2) = cr2-ci5
+         ch(1,k,5) = cr2+ci5
+         ch(2,k,2) = ci2+cr5
+         ch(2,k,3) = ci3+cr4
+         ch(1,k,3) = cr3-ci4
+         ch(1,k,4) = cr3+ci4
+         ch(2,k,4) = ci3-cr4
+         ch(2,k,5) = ci2-cr5
+  101 continue
+      return
+  102 do 104 k=1,l1
+         do 103 i=2,ido,2
+            ti5 = cc(i,2,k)-cc(i,5,k)
+            ti2 = cc(i,2,k)+cc(i,5,k)
+            ti4 = cc(i,3,k)-cc(i,4,k)
+            ti3 = cc(i,3,k)+cc(i,4,k)
+            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
+            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
+            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
+            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
+            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
+            ch(i,k,1) = cc(i,1,k)+ti2+ti3
+            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
+            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
+            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
+            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
+            cr5 = ti11*tr5+ti12*tr4
+            ci5 = ti11*ti5+ti12*ti4
+            cr4 = ti12*tr5-ti11*tr4
+            ci4 = ti12*ti5-ti11*ti4
+            dr3 = cr3-ci4
+            dr4 = cr3+ci4
+            di3 = ci3+cr4
+            di4 = ci3-cr4
+            dr5 = cr2+ci5
+            dr2 = cr2-ci5
+            di5 = ci2-cr5
+            di2 = ci2+cr5
+            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
+            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
+            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
+            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
+            ch(i-1,k,4) = wa3(i-1)*dr4+wa3(i)*di4
+            ch(i,k,4) = wa3(i-1)*di4-wa3(i)*dr4
+            ch(i-1,k,5) = wa4(i-1)*dr5+wa4(i)*di5
+            ch(i,k,5) = wa4(i-1)*di5-wa4(i)*dr5
+  103    continue
+  104 continue
+      return
+      end
diff --git a/libcruft/lapack-xtra/Makefile.in b/libcruft/lapack-xtra/Makefile.in
new file mode 100644
index 0000000..ec4cc94
--- /dev/null
+++ b/libcruft/lapack-xtra/Makefile.in
@@ -0,0 +1,33 @@
+# Makefile for octave's libcruft/lapack-xtra directory
+#
+# Copyright (C) 2000, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = xclange.f xdlamch.f xdlange.f xilaenv.f xslamch.f xslange.f xzlange.f 
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/lapack-xtra/xclange.f b/libcruft/lapack-xtra/xclange.f
new file mode 100644
index 0000000..4736f37
--- /dev/null
+++ b/libcruft/lapack-xtra/xclange.f
@@ -0,0 +1,155 @@
+*** This subroutine includes all of the CLANGE function instead of
+*** simply wrapping it in a subroutine to avoid possible differences in
+*** the way complex values are returned by various Fortran compilers.
+*** For example, if we simply wrap the function and compile this file
+*** with gfortran and the library that provides CLANGE is compiled with
+*** a compiler that uses the g77 (f2c-compatible) calling convention for
+*** complex-valued functions, all hell will break loose.
+
+      SUBROUTINE XCLANGE ( NORM, M, N, A, LDA, WORK, VALUE )
+
+***   DOUBLE PRECISION FUNCTION CLANGE( NORM, M, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   WORK( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLANGE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  complex matrix A.
+*
+*  Description
+*  ===========
+*
+*  CLANGE returns the value
+*
+*     CLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in CLANGE as described
+*          above.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.  When M = 0,
+*          CLANGE is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.  When N = 0,
+*          CLANGE is set to zero.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The m by n matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, M
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, M
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, M
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, M
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL CLASSQ( M, A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+***   CLANGE = VALUE
+      RETURN
+*
+*     End of CLANGE
+*
+      END
diff --git a/libcruft/lapack-xtra/xdlamch.f b/libcruft/lapack-xtra/xdlamch.f
new file mode 100644
index 0000000..d7a857f
--- /dev/null
+++ b/libcruft/lapack-xtra/xdlamch.f
@@ -0,0 +1,6 @@
+      subroutine xdlamch (cmach, retval)
+      character cmach
+      double precision retval, dlamch
+      retval = dlamch (cmach)
+      return
+      end
diff --git a/libcruft/lapack-xtra/xdlange.f b/libcruft/lapack-xtra/xdlange.f
new file mode 100644
index 0000000..3487661
--- /dev/null
+++ b/libcruft/lapack-xtra/xdlange.f
@@ -0,0 +1,7 @@
+      subroutine xdlange (norm, m, n, a, lda, work, retval)
+      character norm
+      integer lda, m, n
+      double precision a (lda, *), work (*), dlange, retval
+      retval = dlange (norm, m, n, a, lda, work)
+      return
+      end
diff --git a/libcruft/lapack-xtra/xilaenv.f b/libcruft/lapack-xtra/xilaenv.f
new file mode 100644
index 0000000..7bb543a
--- /dev/null
+++ b/libcruft/lapack-xtra/xilaenv.f
@@ -0,0 +1,6 @@
+      subroutine xilaenv (ispec, name, opts, n1, n2, n3, n4, retval)
+      character*(*) name, opts
+      integer ilaenv, ispec, n1, n2, n3, n4, retval
+      retval = ilaenv (ispec, name, opts, n1, n2, n3, n4)
+      return
+      end
diff --git a/libcruft/lapack-xtra/xslamch.f b/libcruft/lapack-xtra/xslamch.f
new file mode 100644
index 0000000..73b4b4e
--- /dev/null
+++ b/libcruft/lapack-xtra/xslamch.f
@@ -0,0 +1,6 @@
+      subroutine xslamch (cmach, retval)
+      character cmach
+      real retval, slamch
+      retval = slamch (cmach)
+      return
+      end
diff --git a/libcruft/lapack-xtra/xslange.f b/libcruft/lapack-xtra/xslange.f
new file mode 100644
index 0000000..89cc677
--- /dev/null
+++ b/libcruft/lapack-xtra/xslange.f
@@ -0,0 +1,7 @@
+      subroutine xslange (norm, m, n, a, lda, work, retval)
+      character norm
+      integer lda, m, n
+      real a (lda, *), work (*), slange, retval
+      retval = slange (norm, m, n, a, lda, work)
+      return
+      end
diff --git a/libcruft/lapack-xtra/xzlange.f b/libcruft/lapack-xtra/xzlange.f
new file mode 100644
index 0000000..a96280e
--- /dev/null
+++ b/libcruft/lapack-xtra/xzlange.f
@@ -0,0 +1,155 @@
+*** This subroutine includes all of the ZLANGE function instead of
+*** simply wrapping it in a subroutine to avoid possible differences in
+*** the way complex values are returned by various Fortran compilers.
+*** For example, if we simply wrap the function and compile this file
+*** with gfortran and the library that provides ZLANGE is compiled with
+*** a compiler that uses the g77 (f2c-compatible) calling convention for
+*** complex-valued functions, all hell will break loose.
+
+      SUBROUTINE XZLANGE ( NORM, M, N, A, LDA, WORK, VALUE )
+
+***   DOUBLE PRECISION FUNCTION ZLANGE( NORM, M, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   WORK( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLANGE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  complex matrix A.
+*
+*  Description
+*  ===========
+*
+*  ZLANGE returns the value
+*
+*     ZLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in ZLANGE as described
+*          above.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.  When M = 0,
+*          ZLANGE is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.  When N = 0,
+*          ZLANGE is set to zero.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The m by n matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, M
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, M
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, M
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, M
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL ZLASSQ( M, A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+***   ZLANGE = VALUE
+      RETURN
+*
+*     End of ZLANGE
+*
+      END
diff --git a/libcruft/lapack/Makefile.in b/libcruft/lapack/Makefile.in
new file mode 100644
index 0000000..1563217
--- /dev/null
+++ b/libcruft/lapack/Makefile.in
@@ -0,0 +1,160 @@
+# Makefile for octave's libcruft/lapack directory
+#
+# Copyright (C) 1993, 1994, 1995, 2005, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = 	cbdsqr.f cgbcon.f cgbtf2.f cgbtrf.f cgbtrs.f cgbtrs.f \
+	cgebak.f cgebal.f cgebd2.f cgebrd.f cgecon.f cgecon.f \
+	cgeesx.f cgeev.f cgehd2.f cgehrd.f cgelq2.f cgelq2.f \
+	cgelqf.f cgelsd.f cgelss.f cgelsy.f cgeqp3.f cgeqp3.f \
+	cgeqpf.f cgeqr2.f cgeqrf.f cgesvd.f cgesv.f cgesv.f \
+	cgetf2.f cgetrf.f cgetri.f cgetrs.f cggbak.f cggbak.f \
+	cggbal.f cggev.f cgghrd.f cgtsv.f cgttrf.f cgttrf.f \
+	cgttrs.f cgtts2.f cheev.f chetd2.f chetrd.f chetrd.f \
+	chgeqz.f chseqr.f clabrd.f clacgv.f clacn2.f clacn2.f \
+	clacon.f clacpy.f cladiv.f clahqr.f clahr2.f clahr2.f \
+	clahrd.f claic1.f clals0.f clalsa.f clalsd.f clalsd.f \
+	clange.f clanhe.f clanhs.f clantr.f claqp2.f claqp2.f \
+	claqps.f claqr0.f claqr1.f claqr2.f claqr3.f claqr3.f \
+	claqr4.f claqr5.f clarfb.f clarf.f clarfg.f clarfg.f \
+	clarft.f clarfx.f clartg.f clarzb.f clarz.f clarz.f \
+	clarzt.f clascl.f claset.f clasr.f classq.f classq.f \
+	claswp.f clatbs.f clatrd.f clatrs.f clatrz.f clatrz.f \
+	clauu2.f clauum.f cpbcon.f cpbtf2.f cpbtrf.f cpbtrf.f \
+	cpbtrs.f cpocon.f cpotf2.f cpotrf.f cpotri.f cpotri.f \
+	cpotrs.f cptsv.f cpttrf.f cpttrs.f cptts2.f cptts2.f \
+	crot.f csrscl.f csteqr.f ctgevc.f ctrcon.f ctrcon.f \
+	ctrevc.f ctrexc.f ctrsen.f ctrsyl.f ctrti2.f ctrti2.f \
+	ctrtri.f ctrtrs.f ctzrzf.f cung2l.f cung2r.f cung2r.f \
+	cungbr.f cunghr.f cungl2.f cunglq.f cungql.f cungql.f \
+	cungqr.f cungtr.f cunm2r.f cunmbr.f cunml2.f cunml2.f \
+	cunmlq.f cunmqr.f cunmr3.f cunmrz.f dbdsqr.f dbdsqr.f \
+	dgbcon.f dgbtf2.f dgbtrf.f dgbtrs.f dgebak.f dgebak.f \
+	dgebal.f dgebd2.f dgebrd.f dgecon.f dgeesx.f dgeesx.f \
+	dgeev.f dgehd2.f dgehrd.f dgelq2.f dgelqf.f dgelqf.f \
+	dgelsd.f dgelss.f dgelsy.f dgeqp3.f dgeqpf.f dgeqpf.f \
+	dgeqr2.f dgeqrf.f dgesvd.f dgesv.f dgetf2.f dgetf2.f \
+	dgetrf.f dgetri.f dgetrs.f dggbak.f dggbal.f dggbal.f \
+	dggev.f dgghrd.f dgtsv.f dgttrf.f dgttrs.f dgttrs.f \
+	dgtts2.f dhgeqz.f dhseqr.f dlabad.f dlabrd.f dlabrd.f \
+	dlacn2.f dlacon.f dlacpy.f dladiv.f dlae2.f dlae2.f \
+	dlaed6.f dlaev2.f dlaexc.f dlag2.f dlahqr.f dlahqr.f \
+	dlahr2.f dlahrd.f dlaic1.f dlaln2.f dlals0.f dlals0.f \
+	dlalsa.f dlalsd.f dlamc1.f dlamc2.f dlamc3.f dlamc3.f \
+	dlamc4.f dlamc5.f dlamch.f dlamrg.f dlange.f dlange.f \
+	dlanhs.f dlanst.f dlansy.f dlantr.f dlanv2.f dlanv2.f \
+	dlapy2.f dlapy3.f dlaqp2.f dlaqps.f dlaqr0.f dlaqr0.f \
+	dlaqr1.f dlaqr2.f dlaqr3.f dlaqr4.f dlaqr5.f dlaqr5.f \
+	dlarfb.f dlarf.f dlarfg.f dlarft.f dlarfx.f dlarfx.f \
+	dlartg.f dlarzb.f dlarz.f dlarzt.f dlas2.f dlas2.f \
+	dlascl.f dlasd0.f dlasd1.f dlasd2.f dlasd3.f dlasd3.f \
+	dlasd4.f dlasd5.f dlasd6.f dlasd7.f dlasd8.f dlasd8.f \
+	dlasda.f dlasdq.f dlasdt.f dlaset.f dlasq1.f dlasq1.f \
+	dlasq2.f dlasq3.f dlasq4.f dlasq5.f dlasq6.f dlasq6.f \
+	dlasr.f dlasrt.f dlassq.f dlasv2.f dlaswp.f dlaswp.f \
+	dlasy2.f dlatbs.f dlatrd.f dlatrs.f dlatrz.f dlatrz.f \
+	dlauu2.f dlauum.f dlazq3.f dlazq4.f dorg2l.f dorg2l.f \
+	dorg2r.f dorgbr.f dorghr.f dorgl2.f dorglq.f dorglq.f \
+	dorgql.f dorgqr.f dorgtr.f dorm2r.f dormbr.f dormbr.f \
+	dorml2.f dormlq.f dormqr.f dormr3.f dormrz.f dormrz.f \
+	dpbcon.f dpbtf2.f dpbtrf.f dpbtrs.f dpocon.f dpocon.f \
+	dpotf2.f dpotrf.f dpotri.f dpotrs.f dptsv.f dptsv.f \
+	dpttrf.f dpttrs.f dptts2.f drscl.f dsteqr.f dsteqr.f \
+	dsterf.f dsyev.f dsytd2.f dsytrd.f dtgevc.f dtgevc.f \
+	dtrcon.f dtrevc.f dtrexc.f dtrsen.f dtrsyl.f dtrsyl.f \
+	dtrti2.f dtrtri.f dtrtrs.f dtzrzf.f dzsum1.f dzsum1.f \
+	icmax1.f ieeeck.f ilaenv.f iparmq.f izmax1.f izmax1.f \
+	sbdsqr.f scsum1.f sgbcon.f sgbtf2.f sgbtrf.f sgbtrf.f \
+	sgbtrs.f sgebak.f sgebal.f sgebd2.f sgebrd.f sgebrd.f \
+	sgecon.f sgeesx.f sgeev.f sgehd2.f sgehrd.f sgehrd.f \
+	sgelq2.f sgelqf.f sgelsd.f sgelss.f sgelsy.f sgelsy.f \
+	sgeqp3.f sgeqpf.f sgeqr2.f sgeqrf.f sgesvd.f sgesvd.f \
+	sgesv.f sgetf2.f sgetrf.f sgetri.f sgetrs.f sgetrs.f \
+	sggbak.f sggbal.f sggev.f sgghrd.f sgtsv.f sgtsv.f \
+	sgttrf.f sgttrs.f sgtts2.f shgeqz.f shseqr.f shseqr.f \
+	slabad.f slabrd.f slacn2.f slacon.f slacpy.f slacpy.f \
+	sladiv.f slae2.f slaed6.f slaev2.f slaexc.f slaexc.f \
+	slag2.f slahqr.f slahr2.f slahrd.f slaic1.f slaic1.f \
+	slaln2.f slals0.f slalsa.f slalsd.f slamc1.f slamc1.f \
+	slamc2.f slamc3.f slamc4.f slamc5.f slamch.f slamch.f \
+	slamrg.f slange.f slanhs.f slanst.f slansy.f slansy.f \
+	slantr.f slanv2.f slapy2.f slapy3.f slaqp2.f slaqp2.f \
+	slaqps.f slaqr0.f slaqr1.f slaqr2.f slaqr3.f slaqr3.f \
+	slaqr4.f slaqr5.f slarfb.f slarf.f slarfg.f slarfg.f \
+	slarft.f slarfx.f slartg.f slarzb.f slarz.f slarz.f \
+	slarzt.f slas2.f slascl.f slasd0.f slasd1.f slasd1.f \
+	slasd2.f slasd3.f slasd4.f slasd5.f slasd6.f slasd6.f \
+	slasd7.f slasd8.f slasda.f slasdq.f slasdt.f slasdt.f \
+	slaset.f slasq1.f slasq2.f slasq3.f slasq4.f slasq4.f \
+	slasq5.f slasq6.f slasr.f slasrt.f slassq.f slassq.f \
+	slasv2.f slaswp.f slasy2.f slatbs.f slatrd.f slatrd.f \
+	slatrs.f slatrz.f slauu2.f slauum.f slazq3.f slazq3.f \
+	slazq4.f sorg2l.f sorg2r.f sorgbr.f sorghr.f sorghr.f \
+	sorgl2.f sorglq.f sorgql.f sorgqr.f sorgtr.f sorgtr.f \
+	sorm2r.f sormbr.f sorml2.f sormlq.f sormqr.f sormqr.f \
+	sormr3.f sormrz.f spbcon.f spbtf2.f spbtrf.f spbtrf.f \
+	spbtrs.f spocon.f spotf2.f spotrf.f spotri.f spotri.f \
+	spotrs.f sptsv.f spttrf.f spttrs.f sptts2.f sptts2.f \
+	srscl.f ssteqr.f ssterf.f ssyev.f ssytd2.f ssytd2.f \
+	ssytrd.f stgevc.f strcon.f strevc.f strexc.f strexc.f \
+	strsen.f strsyl.f strti2.f strtri.f strtrs.f strtrs.f \
+	stzrzf.f zbdsqr.f zdrscl.f zgbcon.f zgbtf2.f zgbtf2.f \
+	zgbtrf.f zgbtrs.f zgebak.f zgebal.f zgebd2.f zgebd2.f \
+	zgebrd.f zgecon.f zgeesx.f zgeev.f zgehd2.f zgehd2.f \
+	zgehrd.f zgelq2.f zgelqf.f zgelsd.f zgelss.f zgelss.f \
+	zgelsy.f zgeqp3.f zgeqpf.f zgeqr2.f zgeqrf.f zgeqrf.f \
+	zgesvd.f zgesv.f zgetf2.f zgetrf.f zgetri.f zgetri.f \
+	zgetrs.f zggbak.f zggbal.f zggev.f zgghrd.f zgghrd.f \
+	zgtsv.f zgttrf.f zgttrs.f zgtts2.f zheev.f zheev.f \
+	zhetd2.f zhetrd.f zhgeqz.f zhseqr.f zlabrd.f zlabrd.f \
+	zlacgv.f zlacn2.f zlacon.f zlacpy.f zladiv.f zladiv.f \
+	zlahqr.f zlahr2.f zlahrd.f zlaic1.f zlals0.f zlals0.f \
+	zlalsa.f zlalsd.f zlange.f zlanhe.f zlanhs.f zlanhs.f \
+	zlantr.f zlaqp2.f zlaqps.f zlaqr0.f zlaqr1.f zlaqr1.f \
+	zlaqr2.f zlaqr3.f zlaqr4.f zlaqr5.f zlarfb.f zlarfb.f \
+	zlarf.f zlarfg.f zlarft.f zlarfx.f zlartg.f zlartg.f \
+	zlarzb.f zlarz.f zlarzt.f zlascl.f zlaset.f zlaset.f \
+	zlasr.f zlassq.f zlaswp.f zlatbs.f zlatrd.f zlatrd.f \
+	zlatrs.f zlatrz.f zlauu2.f zlauum.f zpbcon.f zpbcon.f \
+	zpbtf2.f zpbtrf.f zpbtrs.f zpocon.f zpotf2.f zpotf2.f \
+	zpotrf.f zpotri.f zpotrs.f zptsv.f zpttrf.f zpttrf.f \
+	zpttrs.f zptts2.f zrot.f zsteqr.f ztgevc.f ztgevc.f \
+	ztrcon.f ztrevc.f ztrexc.f ztrsen.f ztrsyl.f ztrsyl.f \
+	ztrti2.f ztrtri.f ztrtrs.f ztzrzf.f zung2l.f zung2l.f \
+	zung2r.f zungbr.f zunghr.f zungl2.f zunglq.f zunglq.f \
+	zungql.f zungqr.f zungtr.f zunm2r.f zunmbr.f zunmbr.f \
+	zunml2.f zunmlq.f zunmqr.f zunmr3.f zunmrz.f zunmrz.f \
+	chegs2.f chegst.f chegv.f dsygs2.f dsygst.f dsygv.f \
+	ssygs2.f ssygst.f ssygv.f zhegs2.f zhegst.f zhegv.f
+
+
+include $(TOPDIR)/Makeconf
+
+dlamc1.o pic/dlamc1.o: FFLAGS += $(F77_FLOAT_STORE_FLAG)
+slamc1.o pic/slamc1.o: FFLAGS += $(F77_FLOAT_STORE_FLAG)
+
+include ../Makerules
+
diff --git a/libcruft/lapack/cbdsqr.f b/libcruft/lapack/cbdsqr.f
new file mode 100644
index 0000000..cc03e13
--- /dev/null
+++ b/libcruft/lapack/cbdsqr.f
@@ -0,0 +1,742 @@
+      SUBROUTINE CBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
+     $                   LDU, C, LDC, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * ), RWORK( * )
+      COMPLEX            C( LDC, * ), U( LDU, * ), VT( LDVT, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CBDSQR computes the singular values and, optionally, the right and/or
+*  left singular vectors from the singular value decomposition (SVD) of
+*  a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
+*  zero-shift QR algorithm.  The SVD of B has the form
+*  
+*     B = Q * S * P**H
+*  
+*  where S is the diagonal matrix of singular values, Q is an orthogonal
+*  matrix of left singular vectors, and P is an orthogonal matrix of
+*  right singular vectors.  If left singular vectors are requested, this
+*  subroutine actually returns U*Q instead of Q, and, if right singular
+*  vectors are requested, this subroutine returns P**H*VT instead of
+*  P**H, for given complex input matrices U and VT.  When U and VT are
+*  the unitary matrices that reduce a general matrix A to bidiagonal
+*  form: A = U*B*VT, as computed by CGEBRD, then
+*  
+*     A = (U*Q) * S * (P**H*VT)
+*  
+*  is the SVD of A.  Optionally, the subroutine may also compute Q**H*C
+*  for a given complex input matrix C.
+*
+*  See "Computing  Small Singular Values of Bidiagonal Matrices With
+*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
+*  LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,
+*  no. 5, pp. 873-912, Sept 1990) and
+*  "Accurate singular values and differential qd algorithms," by
+*  B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics
+*  Department, University of California at Berkeley, July 1992
+*  for a detailed description of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  B is upper bidiagonal;
+*          = 'L':  B is lower bidiagonal.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B.  N >= 0.
+*
+*  NCVT    (input) INTEGER
+*          The number of columns of the matrix VT. NCVT >= 0.
+*
+*  NRU     (input) INTEGER
+*          The number of rows of the matrix U. NRU >= 0.
+*
+*  NCC     (input) INTEGER
+*          The number of columns of the matrix C. NCC >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the bidiagonal matrix B.
+*          On exit, if INFO=0, the singular values of B in decreasing
+*          order.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the N-1 offdiagonal elements of the bidiagonal
+*          matrix B.
+*          On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E
+*          will contain the diagonal and superdiagonal elements of a
+*          bidiagonal matrix orthogonally equivalent to the one given
+*          as input.
+*
+*  VT      (input/output) COMPLEX array, dimension (LDVT, NCVT)
+*          On entry, an N-by-NCVT matrix VT.
+*          On exit, VT is overwritten by P**H * VT.
+*          Not referenced if NCVT = 0.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.
+*          LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.
+*
+*  U       (input/output) COMPLEX array, dimension (LDU, N)
+*          On entry, an NRU-by-N matrix U.
+*          On exit, U is overwritten by U * Q.
+*          Not referenced if NRU = 0.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= max(1,NRU).
+*
+*  C       (input/output) COMPLEX array, dimension (LDC, NCC)
+*          On entry, an N-by-NCC matrix C.
+*          On exit, C is overwritten by Q**H * C.
+*          Not referenced if NCC = 0.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C.
+*          LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.
+*
+*  RWORK   (workspace) REAL array, dimension (2*N) 
+*          if NCVT = NRU = NCC = 0, (max(1, 4*N-4)) otherwise
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  If INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm did not converge; D and E contain the
+*                elements of a bidiagonal matrix which is orthogonally
+*                similar to the input matrix B;  if INFO = i, i
+*                elements of E have not converged to zero.
+*
+*  Internal Parameters
+*  ===================
+*
+*  TOLMUL  REAL, default = max(10,min(100,EPS**(-1/8)))
+*          TOLMUL controls the convergence criterion of the QR loop.
+*          If it is positive, TOLMUL*EPS is the desired relative
+*             precision in the computed singular values.
+*          If it is negative, abs(TOLMUL*EPS*sigma_max) is the
+*             desired absolute accuracy in the computed singular
+*             values (corresponds to relative accuracy
+*             abs(TOLMUL*EPS) in the largest singular value.
+*          abs(TOLMUL) should be between 1 and 1/EPS, and preferably
+*             between 10 (for fast convergence) and .1/EPS
+*             (for there to be some accuracy in the results).
+*          Default is to lose at either one eighth or 2 of the
+*             available decimal digits in each computed singular value
+*             (whichever is smaller).
+*
+*  MAXITR  INTEGER, default = 6
+*          MAXITR controls the maximum number of passes of the
+*          algorithm through its inner loop. The algorithms stops
+*          (and so fails to converge) if the number of passes
+*          through the inner loop exceeds MAXITR*N**2.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               NEGONE
+      PARAMETER          ( NEGONE = -1.0E0 )
+      REAL               HNDRTH
+      PARAMETER          ( HNDRTH = 0.01E0 )
+      REAL               TEN
+      PARAMETER          ( TEN = 10.0E0 )
+      REAL               HNDRD
+      PARAMETER          ( HNDRD = 100.0E0 )
+      REAL               MEIGTH
+      PARAMETER          ( MEIGTH = -0.125E0 )
+      INTEGER            MAXITR
+      PARAMETER          ( MAXITR = 6 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, ROTATE
+      INTEGER            I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
+     $                   NM12, NM13, OLDLL, OLDM
+      REAL               ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
+     $                   OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
+     $                   SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
+     $                   SN, THRESH, TOL, TOLMUL, UNFL
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH
+      EXTERNAL           LSAME, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASR, CSROT, CSSCAL, CSWAP, SLARTG, SLAS2,
+     $                   SLASQ1, SLASV2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      LOWER = LSAME( UPLO, 'L' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NCVT.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NCC.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
+     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
+         INFO = -9
+      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
+         INFO = -11
+      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
+     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CBDSQR', -INFO )
+         RETURN
+      END IF
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( N.EQ.1 )
+     $   GO TO 160
+*
+*     ROTATE is true if any singular vectors desired, false otherwise
+*
+      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
+*
+*     If no singular vectors desired, use qd algorithm
+*
+      IF( .NOT.ROTATE ) THEN
+         CALL SLASQ1( N, D, E, RWORK, INFO )
+         RETURN
+      END IF
+*
+      NM1 = N - 1
+      NM12 = NM1 + NM1
+      NM13 = NM12 + NM1
+      IDIR = 0
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'Epsilon' )
+      UNFL = SLAMCH( 'Safe minimum' )
+*
+*     If matrix lower bidiagonal, rotate to be upper bidiagonal
+*     by applying Givens rotations on the left
+*
+      IF( LOWER ) THEN
+         DO 10 I = 1, N - 1
+            CALL SLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            RWORK( I ) = CS
+            RWORK( NM1+I ) = SN
+   10    CONTINUE
+*
+*        Update singular vectors if desired
+*
+         IF( NRU.GT.0 )
+     $      CALL CLASR( 'R', 'V', 'F', NRU, N, RWORK( 1 ), RWORK( N ),
+     $                  U, LDU )
+         IF( NCC.GT.0 )
+     $      CALL CLASR( 'L', 'V', 'F', N, NCC, RWORK( 1 ), RWORK( N ),
+     $                  C, LDC )
+      END IF
+*
+*     Compute singular values to relative accuracy TOL
+*     (By setting TOL to be negative, algorithm will compute
+*     singular values to absolute accuracy ABS(TOL)*norm(input matrix))
+*
+      TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
+      TOL = TOLMUL*EPS
+*
+*     Compute approximate maximum, minimum singular values
+*
+      SMAX = ZERO
+      DO 20 I = 1, N
+         SMAX = MAX( SMAX, ABS( D( I ) ) )
+   20 CONTINUE
+      DO 30 I = 1, N - 1
+         SMAX = MAX( SMAX, ABS( E( I ) ) )
+   30 CONTINUE
+      SMINL = ZERO
+      IF( TOL.GE.ZERO ) THEN
+*
+*        Relative accuracy desired
+*
+         SMINOA = ABS( D( 1 ) )
+         IF( SMINOA.EQ.ZERO )
+     $      GO TO 50
+         MU = SMINOA
+         DO 40 I = 2, N
+            MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
+            SMINOA = MIN( SMINOA, MU )
+            IF( SMINOA.EQ.ZERO )
+     $         GO TO 50
+   40    CONTINUE
+   50    CONTINUE
+         SMINOA = SMINOA / SQRT( REAL( N ) )
+         THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
+      ELSE
+*
+*        Absolute accuracy desired
+*
+         THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
+      END IF
+*
+*     Prepare for main iteration loop for the singular values
+*     (MAXIT is the maximum number of passes through the inner
+*     loop permitted before nonconvergence signalled.)
+*
+      MAXIT = MAXITR*N*N
+      ITER = 0
+      OLDLL = -1
+      OLDM = -1
+*
+*     M points to last element of unconverged part of matrix
+*
+      M = N
+*
+*     Begin main iteration loop
+*
+   60 CONTINUE
+*
+*     Check for convergence or exceeding iteration count
+*
+      IF( M.LE.1 )
+     $   GO TO 160
+      IF( ITER.GT.MAXIT )
+     $   GO TO 200
+*
+*     Find diagonal block of matrix to work on
+*
+      IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
+     $   D( M ) = ZERO
+      SMAX = ABS( D( M ) )
+      SMIN = SMAX
+      DO 70 LLL = 1, M - 1
+         LL = M - LLL
+         ABSS = ABS( D( LL ) )
+         ABSE = ABS( E( LL ) )
+         IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
+     $      D( LL ) = ZERO
+         IF( ABSE.LE.THRESH )
+     $      GO TO 80
+         SMIN = MIN( SMIN, ABSS )
+         SMAX = MAX( SMAX, ABSS, ABSE )
+   70 CONTINUE
+      LL = 0
+      GO TO 90
+   80 CONTINUE
+      E( LL ) = ZERO
+*
+*     Matrix splits since E(LL) = 0
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        Convergence of bottom singular value, return to top of loop
+*
+         M = M - 1
+         GO TO 60
+      END IF
+   90 CONTINUE
+      LL = LL + 1
+*
+*     E(LL) through E(M-1) are nonzero, E(LL-1) is zero
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        2 by 2 block, handle separately
+*
+         CALL SLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
+     $                COSR, SINL, COSL )
+         D( M-1 ) = SIGMX
+         E( M-1 ) = ZERO
+         D( M ) = SIGMN
+*
+*        Compute singular vectors, if desired
+*
+         IF( NCVT.GT.0 )
+     $      CALL CSROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT,
+     $                  COSR, SINR )
+         IF( NRU.GT.0 )
+     $      CALL CSROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
+         IF( NCC.GT.0 )
+     $      CALL CSROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
+     $                  SINL )
+         M = M - 2
+         GO TO 60
+      END IF
+*
+*     If working on new submatrix, choose shift direction
+*     (from larger end diagonal element towards smaller)
+*
+      IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
+         IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
+*
+*           Chase bulge from top (big end) to bottom (small end)
+*
+            IDIR = 1
+         ELSE
+*
+*           Chase bulge from bottom (big end) to top (small end)
+*
+            IDIR = 2
+         END IF
+      END IF
+*
+*     Apply convergence tests
+*
+      IF( IDIR.EQ.1 ) THEN
+*
+*        Run convergence test in forward direction
+*        First apply standard test to bottom of matrix
+*
+         IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
+            E( M-1 ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion forward
+*
+            MU = ABS( D( LL ) )
+            SMINL = MU
+            DO 100 LLL = LL, M - 1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  100       CONTINUE
+         END IF
+*
+      ELSE
+*
+*        Run convergence test in backward direction
+*        First apply standard test to top of matrix
+*
+         IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
+            E( LL ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion backward
+*
+            MU = ABS( D( M ) )
+            SMINL = MU
+            DO 110 LLL = M - 1, LL, -1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  110       CONTINUE
+         END IF
+      END IF
+      OLDLL = LL
+      OLDM = M
+*
+*     Compute shift.  First, test if shifting would ruin relative
+*     accuracy, and if so set the shift to zero.
+*
+      IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
+     $    MAX( EPS, HNDRTH*TOL ) ) THEN
+*
+*        Use a zero shift to avoid loss of relative accuracy
+*
+         SHIFT = ZERO
+      ELSE
+*
+*        Compute the shift from 2-by-2 block at end of matrix
+*
+         IF( IDIR.EQ.1 ) THEN
+            SLL = ABS( D( LL ) )
+            CALL SLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
+         ELSE
+            SLL = ABS( D( M ) )
+            CALL SLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
+         END IF
+*
+*        Test if shift negligible, and if so set to zero
+*
+         IF( SLL.GT.ZERO ) THEN
+            IF( ( SHIFT / SLL )**2.LT.EPS )
+     $         SHIFT = ZERO
+         END IF
+      END IF
+*
+*     Increment iteration count
+*
+      ITER = ITER + M - LL
+*
+*     If SHIFT = 0, do simplified QR iteration
+*
+      IF( SHIFT.EQ.ZERO ) THEN
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 120 I = LL, M - 1
+               CALL SLARTG( D( I )*CS, E( I ), CS, SN, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = OLDSN*R
+               CALL SLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
+               RWORK( I-LL+1 ) = CS
+               RWORK( I-LL+1+NM1 ) = SN
+               RWORK( I-LL+1+NM12 ) = OLDCS
+               RWORK( I-LL+1+NM13 ) = OLDSN
+  120       CONTINUE
+            H = D( M )*CS
+            D( M ) = H*OLDCS
+            E( M-1 ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
+     $                     RWORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL CLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 130 I = M, LL + 1, -1
+               CALL SLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
+               IF( I.LT.M )
+     $            E( I ) = OLDSN*R
+               CALL SLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
+               RWORK( I-LL ) = CS
+               RWORK( I-LL+NM1 ) = -SN
+               RWORK( I-LL+NM12 ) = OLDCS
+               RWORK( I-LL+NM13 ) = -OLDSN
+  130       CONTINUE
+            H = D( LL )*CS
+            D( LL ) = H*OLDCS
+            E( LL ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL CLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
+     $                     RWORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
+     $                     RWORK( N ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+         END IF
+      ELSE
+*
+*        Use nonzero shift
+*
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( LL ) )-SHIFT )*
+     $          ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
+            G = E( LL )
+            DO 140 I = LL, M - 1
+               CALL SLARTG( F, G, COSR, SINR, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = R
+               F = COSR*D( I ) + SINR*E( I )
+               E( I ) = COSR*E( I ) - SINR*D( I )
+               G = SINR*D( I+1 )
+               D( I+1 ) = COSR*D( I+1 )
+               CALL SLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I ) + SINL*D( I+1 )
+               D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
+               IF( I.LT.M-1 ) THEN
+                  G = SINL*E( I+1 )
+                  E( I+1 ) = COSL*E( I+1 )
+               END IF
+               RWORK( I-LL+1 ) = COSR
+               RWORK( I-LL+1+NM1 ) = SINR
+               RWORK( I-LL+1+NM12 ) = COSL
+               RWORK( I-LL+1+NM13 ) = SINL
+  140       CONTINUE
+            E( M-1 ) = F
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
+     $                     RWORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL CLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
+     $          D( M ) )
+            G = E( M-1 )
+            DO 150 I = M, LL + 1, -1
+               CALL SLARTG( F, G, COSR, SINR, R )
+               IF( I.LT.M )
+     $            E( I ) = R
+               F = COSR*D( I ) + SINR*E( I-1 )
+               E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
+               G = SINR*D( I-1 )
+               D( I-1 ) = COSR*D( I-1 )
+               CALL SLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I-1 ) + SINL*D( I-1 )
+               D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
+               IF( I.GT.LL+1 ) THEN
+                  G = SINL*E( I-2 )
+                  E( I-2 ) = COSL*E( I-2 )
+               END IF
+               RWORK( I-LL ) = COSR
+               RWORK( I-LL+NM1 ) = -SINR
+               RWORK( I-LL+NM12 ) = COSL
+               RWORK( I-LL+NM13 ) = -SINL
+  150       CONTINUE
+            E( LL ) = F
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+*
+*           Update singular vectors if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL CLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
+     $                     RWORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL CLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
+     $                     RWORK( N ), C( LL, 1 ), LDC )
+         END IF
+      END IF
+*
+*     QR iteration finished, go back and check convergence
+*
+      GO TO 60
+*
+*     All singular values converged, so make them positive
+*
+  160 CONTINUE
+      DO 170 I = 1, N
+         IF( D( I ).LT.ZERO ) THEN
+            D( I ) = -D( I )
+*
+*           Change sign of singular vectors, if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL CSSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
+         END IF
+  170 CONTINUE
+*
+*     Sort the singular values into decreasing order (insertion sort on
+*     singular values, but only one transposition per singular vector)
+*
+      DO 190 I = 1, N - 1
+*
+*        Scan for smallest D(I)
+*
+         ISUB = 1
+         SMIN = D( 1 )
+         DO 180 J = 2, N + 1 - I
+            IF( D( J ).LE.SMIN ) THEN
+               ISUB = J
+               SMIN = D( J )
+            END IF
+  180    CONTINUE
+         IF( ISUB.NE.N+1-I ) THEN
+*
+*           Swap singular values and vectors
+*
+            D( ISUB ) = D( N+1-I )
+            D( N+1-I ) = SMIN
+            IF( NCVT.GT.0 )
+     $         CALL CSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
+     $                     LDVT )
+            IF( NRU.GT.0 )
+     $         CALL CSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
+            IF( NCC.GT.0 )
+     $         CALL CSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
+         END IF
+  190 CONTINUE
+      GO TO 220
+*
+*     Maximum number of iterations exceeded, failure to converge
+*
+  200 CONTINUE
+      INFO = 0
+      DO 210 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  210 CONTINUE
+  220 CONTINUE
+      RETURN
+*
+*     End of CBDSQR
+*
+      END
diff --git a/libcruft/lapack/cgbcon.f b/libcruft/lapack/cgbcon.f
new file mode 100644
index 0000000..c171763
--- /dev/null
+++ b/libcruft/lapack/cgbcon.f
@@ -0,0 +1,234 @@
+      SUBROUTINE CGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,
+     $                   WORK, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, KL, KU, LDAB, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               RWORK( * )
+      COMPLEX            AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGBCON estimates the reciprocal of the condition number of a complex
+*  general band matrix A, in either the 1-norm or the infinity-norm,
+*  using the LU factorization computed by CGBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input) COMPLEX array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by CGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  ANORM   (input) REAL
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, J, JP, KASE, KASE1, KD, LM
+      REAL               AINVNM, SCALE, SMLNUM
+      COMPLEX            T, ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SLAMCH
+      COMPLEX            CDOTC
+      EXTERNAL           LSAME, ICAMAX, SLAMCH, CDOTC
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CLACN2, CLATBS, CSRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.2*KL+KU+1 ) THEN
+         INFO = -6
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KD = KL + KU + 1
+      LNOTI = KL.GT.0
+      KASE = 0
+   10 CONTINUE
+      CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            IF( LNOTI ) THEN
+               DO 20 J = 1, N - 1
+                  LM = MIN( KL, N-J )
+                  JP = IPIV( J )
+                  T = WORK( JP )
+                  IF( JP.NE.J ) THEN
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+                  CALL CAXPY( LM, -T, AB( KD+1, J ), 1, WORK( J+1 ), 1 )
+   20          CONTINUE
+            END IF
+*
+*           Multiply by inv(U).
+*
+            CALL CLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KL+KU, AB, LDAB, WORK, SCALE, RWORK, INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL CLATBS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, KL+KU, AB, LDAB, WORK, SCALE, RWORK,
+     $                   INFO )
+*
+*           Multiply by inv(L').
+*
+            IF( LNOTI ) THEN
+               DO 30 J = N - 1, 1, -1
+                  LM = MIN( KL, N-J )
+                  WORK( J ) = WORK( J ) - CDOTC( LM, AB( KD+1, J ), 1,
+     $                        WORK( J+1 ), 1 )
+                  JP = IPIV( J )
+                  IF( JP.NE.J ) THEN
+                     T = WORK( JP )
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+   30          CONTINUE
+            END IF
+         END IF
+*
+*        Divide X by 1/SCALE if doing so will not cause overflow.
+*
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = ICAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 40
+            CALL CSRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of CGBCON
+*
+      END
diff --git a/libcruft/lapack/cgbtf2.f b/libcruft/lapack/cgbtf2.f
new file mode 100644
index 0000000..cb40ef7
--- /dev/null
+++ b/libcruft/lapack/cgbtf2.f
@@ -0,0 +1,202 @@
+      SUBROUTINE CGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGBTF2 computes an LU factorization of a complex m-by-n band matrix
+*  A using partial pivoting with row interchanges.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) COMPLEX array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U, because of fill-in resulting from the row
+*  interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, JP, JU, KM, KV
+*     ..
+*     .. External Functions ..
+      INTEGER            ICAMAX
+      EXTERNAL           ICAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGERU, CSCAL, CSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in.
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Gaussian elimination with partial pivoting
+*
+*     Set fill-in elements in columns KU+2 to KV to zero.
+*
+      DO 20 J = KU + 2, MIN( KV, N )
+         DO 10 I = KV - J + 2, KL
+            AB( I, J ) = ZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     JU is the index of the last column affected by the current stage
+*     of the factorization.
+*
+      JU = 1
+*
+      DO 40 J = 1, MIN( M, N )
+*
+*        Set fill-in elements in column J+KV to zero.
+*
+         IF( J+KV.LE.N ) THEN
+            DO 30 I = 1, KL
+               AB( I, J+KV ) = ZERO
+   30       CONTINUE
+         END IF
+*
+*        Find pivot and test for singularity. KM is the number of
+*        subdiagonal elements in the current column.
+*
+         KM = MIN( KL, M-J )
+         JP = ICAMAX( KM+1, AB( KV+1, J ), 1 )
+         IPIV( J ) = JP + J - 1
+         IF( AB( KV+JP, J ).NE.ZERO ) THEN
+            JU = MAX( JU, MIN( J+KU+JP-1, N ) )
+*
+*           Apply interchange to columns J to JU.
+*
+            IF( JP.NE.1 )
+     $         CALL CSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1,
+     $                     AB( KV+1, J ), LDAB-1 )
+            IF( KM.GT.0 ) THEN
+*
+*              Compute multipliers.
+*
+               CALL CSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 )
+*
+*              Update trailing submatrix within the band.
+*
+               IF( JU.GT.J )
+     $            CALL CGERU( KM, JU-J, -ONE, AB( KV+2, J ), 1,
+     $                        AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ),
+     $                        LDAB-1 )
+            END IF
+         ELSE
+*
+*           If pivot is zero, set INFO to the index of the pivot
+*           unless a zero pivot has already been found.
+*
+            IF( INFO.EQ.0 )
+     $         INFO = J
+         END IF
+   40 CONTINUE
+      RETURN
+*
+*     End of CGBTF2
+*
+      END
diff --git a/libcruft/lapack/cgbtrf.f b/libcruft/lapack/cgbtrf.f
new file mode 100644
index 0000000..88758b9
--- /dev/null
+++ b/libcruft/lapack/cgbtrf.f
@@ -0,0 +1,442 @@
+      SUBROUTINE CGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGBTRF computes an LU factorization of a complex m-by-n band matrix A
+*  using partial pivoting with row interchanges.
+*
+*  This is the blocked version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) COMPLEX array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U because of fill-in resulting from the row interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 64, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP,
+     $                   JU, K2, KM, KV, NB, NW
+      COMPLEX            TEMP
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            WORK13( LDWORK, NBMAX ),
+     $                   WORK31( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      INTEGER            ICAMAX, ILAENV
+      EXTERNAL           ICAMAX, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGBTF2, CGEMM, CGERU, CLASWP, CSCAL,
+     $                   CSWAP, CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'CGBTRF', ' ', M, N, KL, KU )
+*
+*     The block size must not exceed the limit set by the size of the
+*     local arrays WORK13 and WORK31.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KL ) THEN
+*
+*        Use unblocked code
+*
+         CALL CGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+*        Zero the superdiagonal elements of the work array WORK13
+*
+         DO 20 J = 1, NB
+            DO 10 I = 1, J - 1
+               WORK13( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Zero the subdiagonal elements of the work array WORK31
+*
+         DO 40 J = 1, NB
+            DO 30 I = J + 1, NB
+               WORK31( I, J ) = ZERO
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Gaussian elimination with partial pivoting
+*
+*        Set fill-in elements in columns KU+2 to KV to zero
+*
+         DO 60 J = KU + 2, MIN( KV, N )
+            DO 50 I = KV - J + 2, KL
+               AB( I, J ) = ZERO
+   50       CONTINUE
+   60    CONTINUE
+*
+*        JU is the index of the last column affected by the current
+*        stage of the factorization
+*
+         JU = 1
+*
+         DO 180 J = 1, MIN( M, N ), NB
+            JB = MIN( NB, MIN( M, N )-J+1 )
+*
+*           The active part of the matrix is partitioned
+*
+*              A11   A12   A13
+*              A21   A22   A23
+*              A31   A32   A33
+*
+*           Here A11, A21 and A31 denote the current block of JB columns
+*           which is about to be factorized. The number of rows in the
+*           partitioning are JB, I2, I3 respectively, and the numbers
+*           of columns are JB, J2, J3. The superdiagonal elements of A13
+*           and the subdiagonal elements of A31 lie outside the band.
+*
+            I2 = MIN( KL-JB, M-J-JB+1 )
+            I3 = MIN( JB, M-J-KL+1 )
+*
+*           J2 and J3 are computed after JU has been updated.
+*
+*           Factorize the current block of JB columns
+*
+            DO 80 JJ = J, J + JB - 1
+*
+*              Set fill-in elements in column JJ+KV to zero
+*
+               IF( JJ+KV.LE.N ) THEN
+                  DO 70 I = 1, KL
+                     AB( I, JJ+KV ) = ZERO
+   70             CONTINUE
+               END IF
+*
+*              Find pivot and test for singularity. KM is the number of
+*              subdiagonal elements in the current column.
+*
+               KM = MIN( KL, M-JJ )
+               JP = ICAMAX( KM+1, AB( KV+1, JJ ), 1 )
+               IPIV( JJ ) = JP + JJ - J
+               IF( AB( KV+JP, JJ ).NE.ZERO ) THEN
+                  JU = MAX( JU, MIN( JJ+KU+JP-1, N ) )
+                  IF( JP.NE.1 ) THEN
+*
+*                    Apply interchange to columns J to J+JB-1
+*
+                     IF( JP+JJ-1.LT.J+KL ) THEN
+*
+                        CALL CSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              AB( KV+JP+JJ-J, J ), LDAB-1 )
+                     ELSE
+*
+*                       The interchange affects columns J to JJ-1 of A31
+*                       which are stored in the work array WORK31
+*
+                        CALL CSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                        CALL CSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1,
+     $                              AB( KV+JP, JJ ), LDAB-1 )
+                     END IF
+                  END IF
+*
+*                 Compute multipliers
+*
+                  CALL CSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ),
+     $                        1 )
+*
+*                 Update trailing submatrix within the band and within
+*                 the current block. JM is the index of the last column
+*                 which needs to be updated.
+*
+                  JM = MIN( JU, J+JB-1 )
+                  IF( JM.GT.JJ )
+     $               CALL CGERU( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1,
+     $                           AB( KV, JJ+1 ), LDAB-1,
+     $                           AB( KV+1, JJ+1 ), LDAB-1 )
+               ELSE
+*
+*                 If pivot is zero, set INFO to the index of the pivot
+*                 unless a zero pivot has already been found.
+*
+                  IF( INFO.EQ.0 )
+     $               INFO = JJ
+               END IF
+*
+*              Copy current column of A31 into the work array WORK31
+*
+               NW = MIN( JJ-J+1, I3 )
+               IF( NW.GT.0 )
+     $            CALL CCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1,
+     $                        WORK31( 1, JJ-J+1 ), 1 )
+   80       CONTINUE
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply the row interchanges to the other blocks.
+*
+               J2 = MIN( JU-J+1, KV ) - JB
+               J3 = MAX( 0, JU-J-KV+1 )
+*
+*              Use CLASWP to apply the row interchanges to A12, A22, and
+*              A32.
+*
+               CALL CLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB,
+     $                      IPIV( J ), 1 )
+*
+*              Adjust the pivot indices.
+*
+               DO 90 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+   90          CONTINUE
+*
+*              Apply the row interchanges to A13, A23, and A33
+*              columnwise.
+*
+               K2 = J - 1 + JB + J2
+               DO 110 I = 1, J3
+                  JJ = K2 + I
+                  DO 100 II = J + I - 1, J + JB - 1
+                     IP = IPIV( II )
+                     IF( IP.NE.II ) THEN
+                        TEMP = AB( KV+1+II-JJ, JJ )
+                        AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ )
+                        AB( KV+1+IP-JJ, JJ ) = TEMP
+                     END IF
+  100             CONTINUE
+  110          CONTINUE
+*
+*              Update the relevant part of the trailing submatrix
+*
+               IF( J2.GT.0 ) THEN
+*
+*                 Update A12
+*
+                  CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J2, ONE, AB( KV+1, J ), LDAB-1,
+     $                        AB( KV+1-JB, J+JB ), LDAB-1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A22
+*
+                     CALL CGEMM( 'No transpose', 'No transpose', I2, J2,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+1, J+JB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A32
+*
+                     CALL CGEMM( 'No transpose', 'No transpose', I3, J2,
+     $                           JB, -ONE, WORK31, LDWORK,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+KL+1-JB, J+JB ), LDAB-1 )
+                  END IF
+               END IF
+*
+               IF( J3.GT.0 ) THEN
+*
+*                 Copy the lower triangle of A13 into the work array
+*                 WORK13
+*
+                  DO 130 JJ = 1, J3
+                     DO 120 II = JJ, JB
+                        WORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 )
+  120                CONTINUE
+  130             CONTINUE
+*
+*                 Update A13 in the work array
+*
+                  CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J3, ONE, AB( KV+1, J ), LDAB-1,
+     $                        WORK13, LDWORK )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A23
+*
+                     CALL CGEMM( 'No transpose', 'No transpose', I2, J3,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           WORK13, LDWORK, ONE, AB( 1+JB, J+KV ),
+     $                           LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A33
+*
+                     CALL CGEMM( 'No transpose', 'No transpose', I3, J3,
+     $                           JB, -ONE, WORK31, LDWORK, WORK13,
+     $                           LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 )
+                  END IF
+*
+*                 Copy the lower triangle of A13 back into place
+*
+                  DO 150 JJ = 1, J3
+                     DO 140 II = JJ, JB
+                        AB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ )
+  140                CONTINUE
+  150             CONTINUE
+               END IF
+            ELSE
+*
+*              Adjust the pivot indices.
+*
+               DO 160 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+  160          CONTINUE
+            END IF
+*
+*           Partially undo the interchanges in the current block to
+*           restore the upper triangular form of A31 and copy the upper
+*           triangle of A31 back into place
+*
+            DO 170 JJ = J + JB - 1, J, -1
+               JP = IPIV( JJ ) - JJ + 1
+               IF( JP.NE.1 ) THEN
+*
+*                 Apply interchange to columns J to JJ-1
+*
+                  IF( JP+JJ-1.LT.J+KL ) THEN
+*
+*                    The interchange does not affect A31
+*
+                     CALL CSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           AB( KV+JP+JJ-J, J ), LDAB-1 )
+                  ELSE
+*
+*                    The interchange does affect A31
+*
+                     CALL CSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                  END IF
+               END IF
+*
+*              Copy the current column of A31 back into place
+*
+               NW = MIN( I3, JJ-J+1 )
+               IF( NW.GT.0 )
+     $            CALL CCOPY( NW, WORK31( 1, JJ-J+1 ), 1,
+     $                        AB( KV+KL+1-JJ+J, JJ ), 1 )
+  170       CONTINUE
+  180    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CGBTRF
+*
+      END
diff --git a/libcruft/lapack/cgbtrs.f b/libcruft/lapack/cgbtrs.f
new file mode 100644
index 0000000..15d6b80
--- /dev/null
+++ b/libcruft/lapack/cgbtrs.f
@@ -0,0 +1,214 @@
+      SUBROUTINE CGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, KL, KU, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGBTRS solves a system of linear equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B
+*  with a general band matrix A using the LU factorization computed
+*  by CGBTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) COMPLEX array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by CGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, NOTRAN
+      INTEGER            I, J, KD, L, LM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CGERU, CLACGV, CSWAP, CTBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      KD = KU + KL + 1
+      LNOTI = KL.GT.0
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve  A*X = B.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+*        L is represented as a product of permutations and unit lower
+*        triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1),
+*        where each transformation L(i) is a rank-one modification of
+*        the identity matrix.
+*
+         IF( LNOTI ) THEN
+            DO 10 J = 1, N - 1
+               LM = MIN( KL, N-J )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL CSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+               CALL CGERU( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ),
+     $                     LDB, B( J+1, 1 ), LDB )
+   10       CONTINUE
+         END IF
+*
+         DO 20 I = 1, NRHS
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU,
+     $                  AB, LDAB, B( 1, I ), 1 )
+   20    CONTINUE
+*
+      ELSE IF( LSAME( TRANS, 'T' ) ) THEN
+*
+*        Solve A**T * X = B.
+*
+         DO 30 I = 1, NRHS
+*
+*           Solve U**T * X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB,
+     $                  LDAB, B( 1, I ), 1 )
+   30    CONTINUE
+*
+*        Solve L**T * X = B, overwriting B with X.
+*
+         IF( LNOTI ) THEN
+            DO 40 J = N - 1, 1, -1
+               LM = MIN( KL, N-J )
+               CALL CGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ),
+     $                     LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL CSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+   40       CONTINUE
+         END IF
+*
+      ELSE
+*
+*        Solve A**H * X = B.
+*
+         DO 50 I = 1, NRHS
+*
+*           Solve U**H * X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Upper', 'Conjugate transpose', 'Non-unit', N,
+     $                  KL+KU, AB, LDAB, B( 1, I ), 1 )
+   50    CONTINUE
+*
+*        Solve L**H * X = B, overwriting B with X.
+*
+         IF( LNOTI ) THEN
+            DO 60 J = N - 1, 1, -1
+               LM = MIN( KL, N-J )
+               CALL CLACGV( NRHS, B( J, 1 ), LDB )
+               CALL CGEMV( 'Conjugate transpose', LM, NRHS, -ONE,
+     $                     B( J+1, 1 ), LDB, AB( KD+1, J ), 1, ONE,
+     $                     B( J, 1 ), LDB )
+               CALL CLACGV( NRHS, B( J, 1 ), LDB )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL CSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+   60       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of CGBTRS
+*
+      END
diff --git a/libcruft/lapack/cgebak.f b/libcruft/lapack/cgebak.f
new file mode 100644
index 0000000..45e88aa
--- /dev/null
+++ b/libcruft/lapack/cgebak.f
@@ -0,0 +1,189 @@
+      SUBROUTINE CGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               SCALE( * )
+      COMPLEX            V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEBAK forms the right or left eigenvectors of a complex general
+*  matrix by backward transformation on the computed eigenvectors of the
+*  balanced matrix output by CGEBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N', do nothing, return immediately;
+*          = 'P', do backward transformation for permutation only;
+*          = 'S', do backward transformation for scaling only;
+*          = 'B', do backward transformations for both permutation and
+*                 scaling.
+*          JOB must be the same as the argument JOB supplied to CGEBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by CGEBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  SCALE   (input) REAL array, dimension (N)
+*          Details of the permutation and scaling factors, as returned
+*          by CGEBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) COMPLEX array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by CHSEIN or CTREVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, II, K
+      REAL               S
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL, CSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -7
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               S = SCALE( I )
+               CALL CSSCAL( M, S, V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               S = ONE / SCALE( I )
+               CALL CSSCAL( M, S, V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+*
+      END IF
+*
+*     Backward permutation
+*
+*     For  I = ILO-1 step -1 until 1,
+*              IHI+1 step 1 until N do --
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+         IF( RIGHTV ) THEN
+            DO 40 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 40
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL CSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 50 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 50
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 50
+               CALL CSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   50       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CGEBAK
+*
+      END
diff --git a/libcruft/lapack/cgebal.f b/libcruft/lapack/cgebal.f
new file mode 100644
index 0000000..12394ea
--- /dev/null
+++ b/libcruft/lapack/cgebal.f
@@ -0,0 +1,330 @@
+      SUBROUTINE CGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               SCALE( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEBAL balances a general complex matrix A.  This involves, first,
+*  permuting A by a similarity transformation to isolate eigenvalues
+*  in the first 1 to ILO-1 and last IHI+1 to N elements on the
+*  diagonal; and second, applying a diagonal similarity transformation
+*  to rows and columns ILO to IHI to make the rows and columns as
+*  close in norm as possible.  Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrix, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, SCALE(I) = 1.0
+*                  for i = 1,...,N;
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit,  A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  SCALE   (output) REAL array, dimension (N)
+*          Details of the permutations and scaling factors applied to
+*          A.  If P(j) is the index of the row and column interchanged
+*          with row and column j and D(j) is the scaling factor
+*          applied to row and column j, then
+*          SCALE(j) = P(j)    for j = 1,...,ILO-1
+*                   = D(j)    for j = ILO,...,IHI
+*                   = P(j)    for j = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The permutations consist of row and column interchanges which put
+*  the matrix in the form
+*
+*             ( T1   X   Y  )
+*     P A P = (  0   B   Z  )
+*             (  0   0   T2 )
+*
+*  where T1 and T2 are upper triangular matrices whose eigenvalues lie
+*  along the diagonal.  The column indices ILO and IHI mark the starting
+*  and ending columns of the submatrix B. Balancing consists of applying
+*  a diagonal similarity transformation inv(D) * B * D to make the
+*  1-norms of each row of B and its corresponding column nearly equal.
+*  The output matrix is
+*
+*     ( T1     X*D          Y    )
+*     (  0  inv(D)*B*D  inv(D)*Z ).
+*     (  0      0           T2   )
+*
+*  Information about the permutations P and the diagonal matrix D is
+*  returned in the vector SCALE.
+*
+*  This subroutine is based on the EISPACK routine CBAL.
+*
+*  Modified by Tzu-Yi Chen, Computer Science Division, University of
+*    California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      REAL               SCLFAC
+      PARAMETER          ( SCLFAC = 2.0E+0 )
+      REAL               FACTOR
+      PARAMETER          ( FACTOR = 0.95E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOCONV
+      INTEGER            I, ICA, IEXC, IRA, J, K, L, M
+      REAL               C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,
+     $                   SFMIN2
+      COMPLEX            CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ICAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL, CSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MAX, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEBAL', -INFO )
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+*
+      IF( N.EQ.0 )
+     $   GO TO 210
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         DO 10 I = 1, N
+            SCALE( I ) = ONE
+   10    CONTINUE
+         GO TO 210
+      END IF
+*
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 120
+*
+*     Permutation to isolate eigenvalues if possible
+*
+      GO TO 50
+*
+*     Row and column exchange.
+*
+   20 CONTINUE
+      SCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 30
+*
+      CALL CSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL CSWAP( N-K+1, A( J, K ), LDA, A( M, K ), LDA )
+*
+   30 CONTINUE
+      GO TO ( 40, 80 )IEXC
+*
+*     Search for rows isolating an eigenvalue and push them down.
+*
+   40 CONTINUE
+      IF( L.EQ.1 )
+     $   GO TO 210
+      L = L - 1
+*
+   50 CONTINUE
+      DO 70 J = L, 1, -1
+*
+         DO 60 I = 1, L
+            IF( I.EQ.J )
+     $         GO TO 60
+            IF( REAL( A( J, I ) ).NE.ZERO .OR. AIMAG( A( J, I ) ).NE.
+     $          ZERO )GO TO 70
+   60    CONTINUE
+*
+         M = L
+         IEXC = 1
+         GO TO 20
+   70 CONTINUE
+*
+      GO TO 90
+*
+*     Search for columns isolating an eigenvalue and push them left.
+*
+   80 CONTINUE
+      K = K + 1
+*
+   90 CONTINUE
+      DO 110 J = K, L
+*
+         DO 100 I = K, L
+            IF( I.EQ.J )
+     $         GO TO 100
+            IF( REAL( A( I, J ) ).NE.ZERO .OR. AIMAG( A( I, J ) ).NE.
+     $          ZERO )GO TO 110
+  100    CONTINUE
+*
+         M = K
+         IEXC = 2
+         GO TO 20
+  110 CONTINUE
+*
+  120 CONTINUE
+      DO 130 I = K, L
+         SCALE( I ) = ONE
+  130 CONTINUE
+*
+      IF( LSAME( JOB, 'P' ) )
+     $   GO TO 210
+*
+*     Balance the submatrix in rows K to L.
+*
+*     Iterative loop for norm reduction
+*
+      SFMIN1 = SLAMCH( 'S' ) / SLAMCH( 'P' )
+      SFMAX1 = ONE / SFMIN1
+      SFMIN2 = SFMIN1*SCLFAC
+      SFMAX2 = ONE / SFMIN2
+  140 CONTINUE
+      NOCONV = .FALSE.
+*
+      DO 200 I = K, L
+         C = ZERO
+         R = ZERO
+*
+         DO 150 J = K, L
+            IF( J.EQ.I )
+     $         GO TO 150
+            C = C + CABS1( A( J, I ) )
+            R = R + CABS1( A( I, J ) )
+  150    CONTINUE
+         ICA = ICAMAX( L, A( 1, I ), 1 )
+         CA = ABS( A( ICA, I ) )
+         IRA = ICAMAX( N-K+1, A( I, K ), LDA )
+         RA = ABS( A( I, IRA+K-1 ) )
+*
+*        Guard against zero C or R due to underflow.
+*
+         IF( C.EQ.ZERO .OR. R.EQ.ZERO )
+     $      GO TO 200
+         G = R / SCLFAC
+         F = ONE
+         S = C + R
+  160    CONTINUE
+         IF( C.GE.G .OR. MAX( F, C, CA ).GE.SFMAX2 .OR.
+     $       MIN( R, G, RA ).LE.SFMIN2 )GO TO 170
+         F = F*SCLFAC
+         C = C*SCLFAC
+         CA = CA*SCLFAC
+         R = R / SCLFAC
+         G = G / SCLFAC
+         RA = RA / SCLFAC
+         GO TO 160
+*
+  170    CONTINUE
+         G = C / SCLFAC
+  180    CONTINUE
+         IF( G.LT.R .OR. MAX( R, RA ).GE.SFMAX2 .OR.
+     $       MIN( F, C, G, CA ).LE.SFMIN2 )GO TO 190
+         F = F / SCLFAC
+         C = C / SCLFAC
+         G = G / SCLFAC
+         CA = CA / SCLFAC
+         R = R*SCLFAC
+         RA = RA*SCLFAC
+         GO TO 180
+*
+*        Now balance.
+*
+  190    CONTINUE
+         IF( ( C+R ).GE.FACTOR*S )
+     $      GO TO 200
+         IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THEN
+            IF( F*SCALE( I ).LE.SFMIN1 )
+     $         GO TO 200
+         END IF
+         IF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THEN
+            IF( SCALE( I ).GE.SFMAX1 / F )
+     $         GO TO 200
+         END IF
+         G = ONE / F
+         SCALE( I ) = SCALE( I )*F
+         NOCONV = .TRUE.
+*
+         CALL CSSCAL( N-K+1, G, A( I, K ), LDA )
+         CALL CSSCAL( L, F, A( 1, I ), 1 )
+*
+  200 CONTINUE
+*
+      IF( NOCONV )
+     $   GO TO 140
+*
+  210 CONTINUE
+      ILO = K
+      IHI = L
+*
+      RETURN
+*
+*     End of CGEBAL
+*
+      END
diff --git a/libcruft/lapack/cgebd2.f b/libcruft/lapack/cgebd2.f
new file mode 100644
index 0000000..8317128
--- /dev/null
+++ b/libcruft/lapack/cgebd2.f
@@ -0,0 +1,250 @@
+      SUBROUTINE CGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+      COMPLEX            A( LDA, * ), TAUP( * ), TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEBD2 reduces a complex general m by n matrix A to upper or lower
+*  real bidiagonal form B by a unitary transformation: Q' * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the unitary matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the unitary matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) REAL array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) COMPLEX array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix Q. See Further Details.
+*
+*  TAUP    (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix P. See Further Details.
+*
+*  WORK    (workspace) COMPLEX array, dimension (max(M,N))
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit 
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors; v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in
+*  A(i+1:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in
+*  A(i,i+2:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, v and u are complex vectors;
+*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);
+*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACGV, CLARF, CLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'CGEBD2', -INFO )
+         RETURN
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, N
+*
+*           Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+            ALPHA = A( I, I )
+            CALL CLARFG( M-I+1, ALPHA, A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = ALPHA
+            A( I, I ) = ONE
+*
+*           Apply H(i)' to A(i:m,i+1:n) from the left
+*
+            IF( I.LT.N )
+     $         CALL CLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
+     $                     CONJG( TAUQ( I ) ), A( I, I+1 ), LDA, WORK )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector G(i) to annihilate
+*              A(i,i+2:n)
+*
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+               ALPHA = A( I, I+1 )
+               CALL CLARFG( N-I, ALPHA, A( I, MIN( I+2, N ) ),
+     $                      LDA, TAUP( I ) )
+               E( I ) = ALPHA
+               A( I, I+1 ) = ONE
+*
+*              Apply G(i) to A(i+1:m,i+1:n) from the right
+*
+               CALL CLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA,
+     $                     TAUP( I ), A( I+1, I+1 ), LDA, WORK )
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+               A( I, I+1 ) = E( I )
+            ELSE
+               TAUP( I ) = ZERO
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, M
+*
+*           Generate elementary reflector G(i) to annihilate A(i,i+1:n)
+*
+            CALL CLACGV( N-I+1, A( I, I ), LDA )
+            ALPHA = A( I, I )
+            CALL CLARFG( N-I+1, ALPHA, A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = ALPHA
+            A( I, I ) = ONE
+*
+*           Apply G(i) to A(i+1:m,i:n) from the right
+*
+            IF( I.LT.M )
+     $         CALL CLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     TAUP( I ), A( I+1, I ), LDA, WORK )
+            CALL CLACGV( N-I+1, A( I, I ), LDA )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.M ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:m,i)
+*
+               ALPHA = A( I+1, I )
+               CALL CLARFG( M-I, ALPHA, A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = ALPHA
+               A( I+1, I ) = ONE
+*
+*              Apply H(i)' to A(i+1:m,i+1:n) from the left
+*
+               CALL CLARF( 'Left', M-I, N-I, A( I+1, I ), 1,
+     $                     CONJG( TAUQ( I ) ), A( I+1, I+1 ), LDA,
+     $                     WORK )
+               A( I+1, I ) = E( I )
+            ELSE
+               TAUQ( I ) = ZERO
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CGEBD2
+*
+      END
diff --git a/libcruft/lapack/cgebrd.f b/libcruft/lapack/cgebrd.f
new file mode 100644
index 0000000..4ee39f6
--- /dev/null
+++ b/libcruft/lapack/cgebrd.f
@@ -0,0 +1,269 @@
+      SUBROUTINE CGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+      COMPLEX            A( LDA, * ), TAUP( * ), TAUQ( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEBRD reduces a general complex M-by-N matrix A to upper or lower
+*  bidiagonal form B by a unitary transformation: Q**H * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the unitary matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the unitary matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) REAL array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) COMPLEX array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix Q. See Further Details.
+*
+*  TAUP    (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix P. See Further Details.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,M,N).
+*          For optimum performance LWORK >= (M+N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors; v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in
+*  A(i+1:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in
+*  A(i,i+2:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors; v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in
+*  A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LDWRKX, LDWRKY, LWKOPT, MINMN, NB,
+     $                   NBMIN, NX
+      REAL               WS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEBD2, CGEMM, CLABRD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, REAL
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MAX( 1, ILAENV( 1, 'CGEBRD', ' ', M, N, -1, -1 ) )
+      LWKOPT = ( M+N )*NB
+      WORK( 1 ) = REAL( LWKOPT )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'CGEBRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      MINMN = MIN( M, N )
+      IF( MINMN.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      WS = MAX( M, N )
+      LDWRKX = M
+      LDWRKY = N
+*
+      IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN
+*
+*        Set the crossover point NX.
+*
+         NX = MAX( NB, ILAENV( 3, 'CGEBRD', ' ', M, N, -1, -1 ) )
+*
+*        Determine when to switch from blocked to unblocked code.
+*
+         IF( NX.LT.MINMN ) THEN
+            WS = ( M+N )*NB
+            IF( LWORK.LT.WS ) THEN
+*
+*              Not enough work space for the optimal NB, consider using
+*              a smaller block size.
+*
+               NBMIN = ILAENV( 2, 'CGEBRD', ' ', M, N, -1, -1 )
+               IF( LWORK.GE.( M+N )*NBMIN ) THEN
+                  NB = LWORK / ( M+N )
+               ELSE
+                  NB = 1
+                  NX = MINMN
+               END IF
+            END IF
+         END IF
+      ELSE
+         NX = MINMN
+      END IF
+*
+      DO 30 I = 1, MINMN - NX, NB
+*
+*        Reduce rows and columns i:i+ib-1 to bidiagonal form and return
+*        the matrices X and Y which are needed to update the unreduced
+*        part of the matrix
+*
+         CALL CLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ),
+     $                TAUQ( I ), TAUP( I ), WORK, LDWRKX,
+     $                WORK( LDWRKX*NB+1 ), LDWRKY )
+*
+*        Update the trailing submatrix A(i+ib:m,i+ib:n), using
+*        an update of the form  A := A - V*Y' - X*U'
+*
+         CALL CGEMM( 'No transpose', 'Conjugate transpose', M-I-NB+1,
+     $               N-I-NB+1, NB, -ONE, A( I+NB, I ), LDA,
+     $               WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE,
+     $               A( I+NB, I+NB ), LDA )
+         CALL CGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1,
+     $               NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA,
+     $               ONE, A( I+NB, I+NB ), LDA )
+*
+*        Copy diagonal and off-diagonal elements of B back into A
+*
+         IF( M.GE.N ) THEN
+            DO 10 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J, J+1 ) = E( J )
+   10       CONTINUE
+         ELSE
+            DO 20 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J+1, J ) = E( J )
+   20       CONTINUE
+         END IF
+   30 CONTINUE
+*
+*     Use unblocked code to reduce the remainder of the matrix
+*
+      CALL CGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $             TAUQ( I ), TAUP( I ), WORK, IINFO )
+      WORK( 1 ) = WS
+      RETURN
+*
+*     End of CGEBRD
+*
+      END
diff --git a/libcruft/lapack/cgecon.f b/libcruft/lapack/cgecon.f
new file mode 100644
index 0000000..a4673e2
--- /dev/null
+++ b/libcruft/lapack/cgecon.f
@@ -0,0 +1,193 @@
+      SUBROUTINE CGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, LDA, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGECON estimates the reciprocal of the condition number of a general
+*  complex matrix A, in either the 1-norm or the infinity-norm, using
+*  the LU factorization computed by CGETRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by CGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) REAL
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      REAL               AINVNM, SCALE, SL, SMLNUM, SU
+      COMPLEX            ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ICAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACN2, CLATRS, CSRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MAX, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGECON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KASE = 0
+   10 CONTINUE
+      CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            CALL CLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A,
+     $                   LDA, WORK, SL, RWORK, INFO )
+*
+*           Multiply by inv(U).
+*
+            CALL CLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SU, RWORK( N+1 ), INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL CLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, A, LDA, WORK, SU, RWORK( N+1 ),
+     $                   INFO )
+*
+*           Multiply by inv(L').
+*
+            CALL CLATRS( 'Lower', 'Conjugate transpose', 'Unit', NORMIN,
+     $                   N, A, LDA, WORK, SL, RWORK, INFO )
+         END IF
+*
+*        Divide X by 1/(SL*SU) if doing so will not cause overflow.
+*
+         SCALE = SL*SU
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = ICAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL CSRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of CGECON
+*
+      END
diff --git a/libcruft/lapack/cgeesx.f b/libcruft/lapack/cgeesx.f
new file mode 100644
index 0000000..c0f1f7d
--- /dev/null
+++ b/libcruft/lapack/cgeesx.f
@@ -0,0 +1,384 @@
+      SUBROUTINE CGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM, W,
+     $                   VS, LDVS, RCONDE, RCONDV, WORK, LWORK, RWORK,
+     $                   BWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVS, SENSE, SORT
+      INTEGER            INFO, LDA, LDVS, LWORK, N, SDIM
+      REAL               RCONDE, RCONDV
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            BWORK( * )
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
+*     ..
+*     .. Function Arguments ..
+      LOGICAL            SELECT
+      EXTERNAL           SELECT
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEESX computes for an N-by-N complex nonsymmetric matrix A, the
+*  eigenvalues, the Schur form T, and, optionally, the matrix of Schur
+*  vectors Z.  This gives the Schur factorization A = Z*T*(Z**H).
+*
+*  Optionally, it also orders the eigenvalues on the diagonal of the
+*  Schur form so that selected eigenvalues are at the top left;
+*  computes a reciprocal condition number for the average of the
+*  selected eigenvalues (RCONDE); and computes a reciprocal condition
+*  number for the right invariant subspace corresponding to the
+*  selected eigenvalues (RCONDV).  The leading columns of Z form an
+*  orthonormal basis for this invariant subspace.
+*
+*  For further explanation of the reciprocal condition numbers RCONDE
+*  and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where
+*  these quantities are called s and sep respectively).
+*
+*  A complex matrix is in Schur form if it is upper triangular.
+*
+*  Arguments
+*  =========
+*
+*  JOBVS   (input) CHARACTER*1
+*          = 'N': Schur vectors are not computed;
+*          = 'V': Schur vectors are computed.
+*
+*  SORT    (input) CHARACTER*1
+*          Specifies whether or not to order the eigenvalues on the
+*          diagonal of the Schur form.
+*          = 'N': Eigenvalues are not ordered;
+*          = 'S': Eigenvalues are ordered (see SELECT).
+*
+*  SELECT  (external procedure) LOGICAL FUNCTION of one COMPLEX argument
+*          SELECT must be declared EXTERNAL in the calling subroutine.
+*          If SORT = 'S', SELECT is used to select eigenvalues to order
+*          to the top left of the Schur form.
+*          If SORT = 'N', SELECT is not referenced.
+*          An eigenvalue W(j) is selected if SELECT(W(j)) is true.
+*
+*  SENSE   (input) CHARACTER*1
+*          Determines which reciprocal condition numbers are computed.
+*          = 'N': None are computed;
+*          = 'E': Computed for average of selected eigenvalues only;
+*          = 'V': Computed for selected right invariant subspace only;
+*          = 'B': Computed for both.
+*          If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA, N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A is overwritten by its Schur form T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  SDIM    (output) INTEGER
+*          If SORT = 'N', SDIM = 0.
+*          If SORT = 'S', SDIM = number of eigenvalues for which
+*                         SELECT is true.
+*
+*  W       (output) COMPLEX array, dimension (N)
+*          W contains the computed eigenvalues, in the same order
+*          that they appear on the diagonal of the output Schur form T.
+*
+*  VS      (output) COMPLEX array, dimension (LDVS,N)
+*          If JOBVS = 'V', VS contains the unitary matrix Z of Schur
+*          vectors.
+*          If JOBVS = 'N', VS is not referenced.
+*
+*  LDVS    (input) INTEGER
+*          The leading dimension of the array VS.  LDVS >= 1, and if
+*          JOBVS = 'V', LDVS >= N.
+*
+*  RCONDE  (output) REAL
+*          If SENSE = 'E' or 'B', RCONDE contains the reciprocal
+*          condition number for the average of the selected eigenvalues.
+*          Not referenced if SENSE = 'N' or 'V'.
+*
+*  RCONDV  (output) REAL
+*          If SENSE = 'V' or 'B', RCONDV contains the reciprocal
+*          condition number for the selected right invariant subspace.
+*          Not referenced if SENSE = 'N' or 'E'.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,2*N).
+*          Also, if SENSE = 'E' or 'V' or 'B', LWORK >= 2*SDIM*(N-SDIM),
+*          where SDIM is the number of selected eigenvalues computed by
+*          this routine.  Note that 2*SDIM*(N-SDIM) <= N*N/2. Note also
+*          that an error is only returned if LWORK < max(1,2*N), but if
+*          SENSE = 'E' or 'V' or 'B' this may not be large enough.
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates upper bound on the optimal size of the
+*          array WORK, returns this value as the first entry of the WORK
+*          array, and no error message related to LWORK is issued by
+*          XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  BWORK   (workspace) LOGICAL array, dimension (N)
+*          Not referenced if SORT = 'N'.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*          > 0: if INFO = i, and i is
+*             <= N: the QR algorithm failed to compute all the
+*                   eigenvalues; elements 1:ILO-1 and i+1:N of W
+*                   contain those eigenvalues which have converged; if
+*                   JOBVS = 'V', VS contains the transformation which
+*                   reduces A to its partially converged Schur form.
+*             = N+1: the eigenvalues could not be reordered because some
+*                   eigenvalues were too close to separate (the problem
+*                   is very ill-conditioned);
+*             = N+2: after reordering, roundoff changed values of some
+*                   complex eigenvalues so that leading eigenvalues in
+*                   the Schur form no longer satisfy SELECT=.TRUE.  This
+*                   could also be caused by underflow due to scaling.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            SCALEA, WANTSB, WANTSE, WANTSN, WANTST,
+     $                   WANTSV, WANTVS
+      INTEGER            HSWORK, I, IBAL, ICOND, IERR, IEVAL, IHI, ILO,
+     $                   ITAU, IWRK, LWRK, MAXWRK, MINWRK
+      REAL               ANRM, BIGNUM, CSCALE, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEBAK, CGEBAL, CGEHRD, CHSEQR, CLACPY,
+     $                   CLASCL, CTRSEN, CUNGHR, SLABAD, SLASCL, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               CLANGE, SLAMCH
+      EXTERNAL           LSAME, ILAENV, CLANGE, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTVS = LSAME( JOBVS, 'V' )
+      WANTST = LSAME( SORT, 'S' )
+      WANTSN = LSAME( SENSE, 'N' )
+      WANTSE = LSAME( SENSE, 'E' )
+      WANTSV = LSAME( SENSE, 'V' )
+      WANTSB = LSAME( SENSE, 'B' )
+      IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
+     $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of real workspace needed at that point in the
+*       code, as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace to real
+*       workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by CHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.
+*       If SENSE = 'E', 'V' or 'B', then the amount of workspace needed
+*       depends on SDIM, which is computed by the routine CTRSEN later
+*       in the code.)
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            LWRK = 1
+         ELSE
+            MAXWRK = N + N*ILAENV( 1, 'CGEHRD', ' ', N, 1, N, 0 )
+            MINWRK = 2*N
+*
+            CALL CHSEQR( 'S', JOBVS, N, 1, N, A, LDA, W, VS, LDVS,
+     $             WORK, -1, IEVAL )
+            HSWORK = WORK( 1 )
+*
+            IF( .NOT.WANTVS ) THEN
+               MAXWRK = MAX( MAXWRK, HSWORK )
+            ELSE
+               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'CUNGHR',
+     $                       ' ', N, 1, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, HSWORK )
+            END IF
+            LWRK = MAXWRK
+            IF( .NOT.WANTSN )
+     $         LWRK = MAX( LWRK, ( N*N )/2 )
+         END IF
+         WORK( 1 ) = LWRK
+*
+         IF( LWORK.LT.MINWRK ) THEN
+            INFO = -15
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEESX', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         SDIM = 0
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = CLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL CLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*
+*     Permute the matrix to make it more nearly triangular
+*     (CWorkspace: none)
+*     (RWorkspace: need N)
+*
+      IBAL = 1
+      CALL CGEBAL( 'P', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (CWorkspace: need 2*N, prefer N+N*NB)
+*     (RWorkspace: none)
+*
+      ITAU = 1
+      IWRK = N + ITAU
+      CALL CGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVS ) THEN
+*
+*        Copy Householder vectors to VS
+*
+         CALL CLACPY( 'L', N, N, A, LDA, VS, LDVS )
+*
+*        Generate unitary matrix in VS
+*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+      END IF
+*
+      SDIM = 0
+*
+*     Perform QR iteration, accumulating Schur vectors in VS if desired
+*     (CWorkspace: need 1, prefer HSWORK (see comments) )
+*     (RWorkspace: none)
+*
+      IWRK = ITAU
+      CALL CHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, W, VS, LDVS,
+     $             WORK( IWRK ), LWORK-IWRK+1, IEVAL )
+      IF( IEVAL.GT.0 )
+     $   INFO = IEVAL
+*
+*     Sort eigenvalues if desired
+*
+      IF( WANTST .AND. INFO.EQ.0 ) THEN
+         IF( SCALEA )
+     $      CALL CLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, W, N, IERR )
+         DO 10 I = 1, N
+            BWORK( I ) = SELECT( W( I ) )
+   10    CONTINUE
+*
+*        Reorder eigenvalues, transform Schur vectors, and compute
+*        reciprocal condition numbers
+*        (CWorkspace: if SENSE is not 'N', need 2*SDIM*(N-SDIM)
+*                     otherwise, need none )
+*        (RWorkspace: none)
+*
+         CALL CTRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, W, SDIM,
+     $                RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,
+     $                ICOND )
+         IF( .NOT.WANTSN )
+     $      MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
+         IF( ICOND.EQ.-14 ) THEN
+*
+*           Not enough complex workspace
+*
+            INFO = -15
+         END IF
+      END IF
+*
+      IF( WANTVS ) THEN
+*
+*        Undo balancing
+*        (CWorkspace: none)
+*        (RWorkspace: need N)
+*
+         CALL CGEBAK( 'P', 'R', N, ILO, IHI, RWORK( IBAL ), N, VS, LDVS,
+     $                IERR )
+      END IF
+*
+      IF( SCALEA ) THEN
+*
+*        Undo scaling for the Schur form of A
+*
+         CALL CLASCL( 'U', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
+         CALL CCOPY( N, A, LDA+1, W, 1 )
+         IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THEN
+            DUM( 1 ) = RCONDV
+            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
+            RCONDV = DUM( 1 )
+         END IF
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of CGEESX
+*
+      END
diff --git a/libcruft/lapack/cgeev.f b/libcruft/lapack/cgeev.f
new file mode 100644
index 0000000..8a493c8
--- /dev/null
+++ b/libcruft/lapack/cgeev.f
@@ -0,0 +1,397 @@
+      SUBROUTINE CGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
+     $                  WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEEV computes for an N-by-N complex nonsymmetric matrix A, the
+*  eigenvalues and, optionally, the left and/or right eigenvectors.
+*
+*  The right eigenvector v(j) of A satisfies
+*                   A * v(j) = lambda(j) * v(j)
+*  where lambda(j) is its eigenvalue.
+*  The left eigenvector u(j) of A satisfies
+*                u(j)**H * A = lambda(j) * u(j)**H
+*  where u(j)**H denotes the conjugate transpose of u(j).
+*
+*  The computed eigenvectors are normalized to have Euclidean norm
+*  equal to 1 and largest component real.
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N': left eigenvectors of A are not computed;
+*          = 'V': left eigenvectors of are computed.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N': right eigenvectors of A are not computed;
+*          = 'V': right eigenvectors of A are computed.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  W       (output) COMPLEX array, dimension (N)
+*          W contains the computed eigenvalues.
+*
+*  VL      (output) COMPLEX array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
+*          after another in the columns of VL, in the same order
+*          as their eigenvalues.
+*          If JOBVL = 'N', VL is not referenced.
+*          u(j) = VL(:,j), the j-th column of VL.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1; if
+*          JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) COMPLEX array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
+*          after another in the columns of VR, in the same order
+*          as their eigenvalues.
+*          If JOBVR = 'N', VR is not referenced.
+*          v(j) = VR(:,j), the j-th column of VR.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1; if
+*          JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,2*N).
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = i, the QR algorithm failed to compute all the
+*                eigenvalues, and no eigenvectors have been computed;
+*                elements and i+1:N of W contain eigenvalues which have
+*                converged.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
+      CHARACTER          SIDE
+      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, IRWORK, ITAU,
+     $                   IWRK, K, MAXWRK, MINWRK, NOUT
+      REAL               ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
+      COMPLEX            TMP
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            SELECT( 1 )
+      REAL               DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEBAK, CGEBAL, CGEHRD, CHSEQR, CLACPY, CLASCL,
+     $                   CSCAL, CSSCAL, CTREVC, CUNGHR, SLABAD, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV, ISAMAX
+      REAL               CLANGE, SCNRM2, SLAMCH
+      EXTERNAL           LSAME, ILAENV, ISAMAX, CLANGE, SCNRM2, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          AIMAG, CMPLX, CONJG, MAX, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      WANTVL = LSAME( JOBVL, 'V' )
+      WANTVR = LSAME( JOBVR, 'V' )
+      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      END IF
+
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace to real
+*       workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by CHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            MAXWRK = 1
+         ELSE
+            MAXWRK = N + N*ILAENV( 1, 'CGEHRD', ' ', N, 1, N, 0 )
+            MINWRK = 2*N
+            IF( WANTVL ) THEN
+               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'CUNGHR',
+     $                       ' ', N, 1, N, -1 ) )
+               CALL CHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
+     $                WORK, -1, INFO )
+            ELSE IF( WANTVR ) THEN
+               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'CUNGHR',
+     $                       ' ', N, 1, N, -1 ) )
+               CALL CHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
+     $                WORK, -1, INFO )
+            ELSE
+               CALL CHSEQR( 'E', 'N', N, 1, N, A, LDA, W, VR, LDVR,
+     $                WORK, -1, INFO )
+            END IF
+            HSWORK = WORK( 1 )
+            MAXWRK = MAX( MAXWRK, HSWORK, MINWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = CLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL CLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*     Balance the matrix
+*     (CWorkspace: none)
+*     (RWorkspace: need N)
+*
+      IBAL = 1
+      CALL CGEBAL( 'B', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (CWorkspace: need 2*N, prefer N+N*NB)
+*     (RWorkspace: none)
+*
+      ITAU = 1
+      IWRK = ITAU + N
+      CALL CGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVL ) THEN
+*
+*        Want left eigenvectors
+*        Copy Householder vectors to VL
+*
+         SIDE = 'L'
+         CALL CLACPY( 'L', N, N, A, LDA, VL, LDVL )
+*
+*        Generate unitary matrix in VL
+*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VL
+*        (CWorkspace: need 1, prefer HSWORK (see comments) )
+*        (RWorkspace: none)
+*
+         IWRK = ITAU
+         CALL CHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VL, LDVL,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+         IF( WANTVR ) THEN
+*
+*           Want left and right eigenvectors
+*           Copy Schur vectors to VR
+*
+            SIDE = 'B'
+            CALL CLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
+         END IF
+*
+      ELSE IF( WANTVR ) THEN
+*
+*        Want right eigenvectors
+*        Copy Householder vectors to VR
+*
+         SIDE = 'R'
+         CALL CLACPY( 'L', N, N, A, LDA, VR, LDVR )
+*
+*        Generate unitary matrix in VR
+*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VR
+*        (CWorkspace: need 1, prefer HSWORK (see comments) )
+*        (RWorkspace: none)
+*
+         IWRK = ITAU
+         CALL CHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+      ELSE
+*
+*        Compute eigenvalues only
+*        (CWorkspace: need 1, prefer HSWORK (see comments) )
+*        (RWorkspace: none)
+*
+         IWRK = ITAU
+         CALL CHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, W, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+      END IF
+*
+*     If INFO > 0 from CHSEQR, then quit
+*
+      IF( INFO.GT.0 )
+     $   GO TO 50
+*
+      IF( WANTVL .OR. WANTVR ) THEN
+*
+*        Compute left and/or right eigenvectors
+*        (CWorkspace: need 2*N)
+*        (RWorkspace: need 2*N)
+*
+         IRWORK = IBAL + N
+         CALL CTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                N, NOUT, WORK( IWRK ), RWORK( IRWORK ), IERR )
+      END IF
+*
+      IF( WANTVL ) THEN
+*
+*        Undo balancing of left eigenvectors
+*        (CWorkspace: none)
+*        (RWorkspace: need N)
+*
+         CALL CGEBAK( 'B', 'L', N, ILO, IHI, RWORK( IBAL ), N, VL, LDVL,
+     $                IERR )
+*
+*        Normalize left eigenvectors and make largest component real
+*
+         DO 20 I = 1, N
+            SCL = ONE / SCNRM2( N, VL( 1, I ), 1 )
+            CALL CSSCAL( N, SCL, VL( 1, I ), 1 )
+            DO 10 K = 1, N
+               RWORK( IRWORK+K-1 ) = REAL( VL( K, I ) )**2 +
+     $                               AIMAG( VL( K, I ) )**2
+   10       CONTINUE
+            K = ISAMAX( N, RWORK( IRWORK ), 1 )
+            TMP = CONJG( VL( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
+            CALL CSCAL( N, TMP, VL( 1, I ), 1 )
+            VL( K, I ) = CMPLX( REAL( VL( K, I ) ), ZERO )
+   20    CONTINUE
+      END IF
+*
+      IF( WANTVR ) THEN
+*
+*        Undo balancing of right eigenvectors
+*        (CWorkspace: none)
+*        (RWorkspace: need N)
+*
+         CALL CGEBAK( 'B', 'R', N, ILO, IHI, RWORK( IBAL ), N, VR, LDVR,
+     $                IERR )
+*
+*        Normalize right eigenvectors and make largest component real
+*
+         DO 40 I = 1, N
+            SCL = ONE / SCNRM2( N, VR( 1, I ), 1 )
+            CALL CSSCAL( N, SCL, VR( 1, I ), 1 )
+            DO 30 K = 1, N
+               RWORK( IRWORK+K-1 ) = REAL( VR( K, I ) )**2 +
+     $                               AIMAG( VR( K, I ) )**2
+   30       CONTINUE
+            K = ISAMAX( N, RWORK( IRWORK ), 1 )
+            TMP = CONJG( VR( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
+            CALL CSCAL( N, TMP, VR( 1, I ), 1 )
+            VR( K, I ) = CMPLX( REAL( VR( K, I ) ), ZERO )
+   40    CONTINUE
+      END IF
+*
+*     Undo scaling if necessary
+*
+   50 CONTINUE
+      IF( SCALEA ) THEN
+         CALL CLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, W( INFO+1 ),
+     $                MAX( N-INFO, 1 ), IERR )
+         IF( INFO.GT.0 ) THEN
+            CALL CLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, W, N, IERR )
+         END IF
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of CGEEV
+*
+      END
diff --git a/libcruft/lapack/cgehd2.f b/libcruft/lapack/cgehd2.f
new file mode 100644
index 0000000..c3cb2b7
--- /dev/null
+++ b/libcruft/lapack/cgehd2.f
@@ -0,0 +1,148 @@
+      SUBROUTINE CGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEHD2 reduces a complex general matrix A to upper Hessenberg form H
+*  by a unitary similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to CGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= max(1,N).
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the n by n general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the unitary matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) COMPLEX array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARF, CLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEHD2', -INFO )
+         RETURN
+      END IF
+*
+      DO 10 I = ILO, IHI - 1
+*
+*        Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)
+*
+         ALPHA = A( I+1, I )
+         CALL CLARFG( IHI-I, ALPHA, A( MIN( I+2, N ), I ), 1, TAU( I ) )
+         A( I+1, I ) = ONE
+*
+*        Apply H(i) to A(1:ihi,i+1:ihi) from the right
+*
+         CALL CLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ),
+     $               A( 1, I+1 ), LDA, WORK )
+*
+*        Apply H(i)' to A(i+1:ihi,i+1:n) from the left
+*
+         CALL CLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1,
+     $               CONJG( TAU( I ) ), A( I+1, I+1 ), LDA, WORK )
+*
+         A( I+1, I ) = ALPHA
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of CGEHD2
+*
+      END
diff --git a/libcruft/lapack/cgehrd.f b/libcruft/lapack/cgehrd.f
new file mode 100644
index 0000000..48c48b4
--- /dev/null
+++ b/libcruft/lapack/cgehrd.f
@@ -0,0 +1,273 @@
+      SUBROUTINE CGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEHRD reduces a complex general matrix A to upper Hessenberg form H by
+*  an unitary similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to CGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the unitary matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to
+*          zero.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (LWORK)
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's CGEHRD
+*  subroutine incorporating improvements proposed by Quintana-Orti and
+*  Van de Geijn (2005). 
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ), 
+     $                     ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NH, NX
+      COMPLEX            EI
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            T( LDT, NBMAX )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CGEHD2, CGEMM, CLAHR2, CLARFB, CTRMM,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MIN( NBMAX, ILAENV( 1, 'CGEHRD', ' ', N, ILO, IHI, -1 ) )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEHRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero
+*
+      DO 10 I = 1, ILO - 1
+         TAU( I ) = ZERO
+   10 CONTINUE
+      DO 20 I = MAX( 1, IHI ), N - 1
+         TAU( I ) = ZERO
+   20 CONTINUE
+*
+*     Quick return if possible
+*
+      NH = IHI - ILO + 1
+      IF( NH.LE.1 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Determine the block size
+*
+      NB = MIN( NBMAX, ILAENV( 1, 'CGEHRD', ' ', N, ILO, IHI, -1 ) )
+      NBMIN = 2
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.NH ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code)
+*
+         NX = MAX( NB, ILAENV( 3, 'CGEHRD', ' ', N, ILO, IHI, -1 ) )
+         IF( NX.LT.NH ) THEN
+*
+*           Determine if workspace is large enough for blocked code
+*
+            IWS = N*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code
+*
+               NBMIN = MAX( 2, ILAENV( 2, 'CGEHRD', ' ', N, ILO, IHI,
+     $                 -1 ) )
+               IF( LWORK.GE.N*NBMIN ) THEN
+                  NB = LWORK / N
+               ELSE
+                  NB = 1
+               END IF
+            END IF
+         END IF
+      END IF
+      LDWORK = N
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN
+*
+*        Use unblocked code below
+*
+         I = ILO
+*
+      ELSE
+*
+*        Use blocked code
+*
+         DO 40 I = ILO, IHI - 1 - NX, NB
+            IB = MIN( NB, IHI-I )
+*
+*           Reduce columns i:i+ib-1 to Hessenberg form, returning the
+*           matrices V and T of the block reflector H = I - V*T*V'
+*           which performs the reduction, and also the matrix Y = A*V*T
+*
+            CALL CLAHR2( IHI, I, IB, A( 1, I ), LDA, TAU( I ), T, LDT,
+     $                   WORK, LDWORK )
+*
+*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the
+*           right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set
+*           to 1
+*
+            EI = A( I+IB, I+IB-1 )
+            A( I+IB, I+IB-1 ) = ONE
+            CALL CGEMM( 'No transpose', 'Conjugate transpose', 
+     $                  IHI, IHI-I-IB+1,
+     $                  IB, -ONE, WORK, LDWORK, A( I+IB, I ), LDA, ONE,
+     $                  A( 1, I+IB ), LDA )
+            A( I+IB, I+IB-1 ) = EI
+*
+*           Apply the block reflector H to A(1:i,i+1:i+ib-1) from the
+*           right
+*
+            CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                  'Unit', I, IB-1,
+     $                  ONE, A( I+1, I ), LDA, WORK, LDWORK )
+            DO 30 J = 0, IB-2
+               CALL CAXPY( I, -ONE, WORK( LDWORK*J+1 ), 1,
+     $                     A( 1, I+J+1 ), 1 )
+   30       CONTINUE
+*
+*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the
+*           left
+*
+            CALL CLARFB( 'Left', 'Conjugate transpose', 'Forward',
+     $                   'Columnwise',
+     $                   IHI-I, N-I-IB+1, IB, A( I+1, I ), LDA, T, LDT,
+     $                   A( I+1, I+IB ), LDA, WORK, LDWORK )
+   40    CONTINUE
+      END IF
+*
+*     Use unblocked code to reduce the rest of the matrix
+*
+      CALL CGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )
+      WORK( 1 ) = IWS
+*
+      RETURN
+*
+*     End of CGEHRD
+*
+      END
diff --git a/libcruft/lapack/cgelq2.f b/libcruft/lapack/cgelq2.f
new file mode 100644
index 0000000..745ecb9
--- /dev/null
+++ b/libcruft/lapack/cgelq2.f
@@ -0,0 +1,123 @@
+      SUBROUTINE CGELQ2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGELQ2 computes an LQ factorization of a complex m by n matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m by min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) COMPLEX array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k)' . . . H(2)' H(1)', where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; conjg(v(i+1:n)) is stored on exit in
+*  A(i,i+1:n), and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACGV, CLARF, CLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGELQ2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i,i+1:n)
+*
+         CALL CLACGV( N-I+1, A( I, I ), LDA )
+         ALPHA = A( I, I )
+         CALL CLARFG( N-I+1, ALPHA, A( I, MIN( I+1, N ) ), LDA,
+     $                TAU( I ) )
+         IF( I.LT.M ) THEN
+*
+*           Apply H(i) to A(i+1:m,i:n) from the right
+*
+            A( I, I ) = ONE
+            CALL CLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ),
+     $                  A( I+1, I ), LDA, WORK )
+         END IF
+         A( I, I ) = ALPHA
+         CALL CLACGV( N-I+1, A( I, I ), LDA )
+   10 CONTINUE
+      RETURN
+*
+*     End of CGELQ2
+*
+      END
diff --git a/libcruft/lapack/cgelqf.f b/libcruft/lapack/cgelqf.f
new file mode 100644
index 0000000..7f6bd73
--- /dev/null
+++ b/libcruft/lapack/cgelqf.f
@@ -0,0 +1,195 @@
+      SUBROUTINE CGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGELQF computes an LQ factorization of a complex M-by-N matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m-by-min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k)' . . . H(2)' H(1)', where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; conjg(v(i+1:n)) is stored on exit in
+*  A(i,i+1:n), and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGELQ2, CLARFB, CLARFT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+      LWKOPT = M*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGELQF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'CGELQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'CGELQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the LQ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL CGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL CLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i+ib:m,i:n) from the right
+*
+               CALL CLARFB( 'Right', 'No transpose', 'Forward',
+     $                      'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),
+     $                      LDA, WORK, LDWORK, A( I+IB, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL CGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CGELQF
+*
+      END
diff --git a/libcruft/lapack/cgelsd.f b/libcruft/lapack/cgelsd.f
new file mode 100644
index 0000000..25316b8
--- /dev/null
+++ b/libcruft/lapack/cgelsd.f
@@ -0,0 +1,567 @@
+      SUBROUTINE CGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, RWORK, IWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               RWORK( * ), S( * )
+      COMPLEX            A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGELSD computes the minimum-norm solution to a real linear least
+*  squares problem:
+*      minimize 2-norm(| b - A*x |)
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The problem is solved in three steps:
+*  (1) Reduce the coefficient matrix A to bidiagonal form with
+*      Householder tranformations, reducing the original problem
+*      into a "bidiagonal least squares problem" (BLS)
+*  (2) Solve the BLS using a divide and conquer approach.
+*  (3) Apply back all the Householder tranformations to solve
+*      the original least squares problem.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  The divide and conquer algorithm makes very mild assumptions about
+*  floating point arithmetic. It will work on machines with a guard
+*  digit in add/subtract, or on those binary machines without guard
+*  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
+*  Cray-2. It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution matrix X.
+*          If m >= n and RANK = n, the residual sum-of-squares for
+*          the solution in the i-th column is given by the sum of
+*          squares of the modulus of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M,N).
+*
+*  S       (output) REAL array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) REAL
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK must be at least 1.
+*          The exact minimum amount of workspace needed depends on M,
+*          N and NRHS. As long as LWORK is at least
+*              2 * N + N * NRHS
+*          if M is greater than or equal to N or
+*              2 * M + M * NRHS
+*          if M is less than N, the code will execute correctly.
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the array WORK and the
+*          minimum sizes of the arrays RWORK and IWORK, and returns
+*          these values as the first entries of the WORK, RWORK and
+*          IWORK arrays, and no error message related to LWORK is issued
+*          by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (MAX(1,LRWORK))
+*          LRWORK >=
+*             10*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS +
+*             (SMLSIZ+1)**2
+*          if M is greater than or equal to N or
+*             10*M + 2*M*SMLSIZ + 8*M*NLVL + 3*SMLSIZ*NRHS +
+*             (SMLSIZ+1)**2
+*          if M is less than N, the code will execute correctly.
+*          SMLSIZ is returned by ILAENV and is equal to the maximum
+*          size of the subproblems at the bottom of the computation
+*          tree (usually about 25), and
+*             NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
+*          On exit, if INFO = 0, RWORK(1) returns the minimum LRWORK.
+*
+*  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
+*          LIWORK >= max(1, 3*MINMN*NLVL + 11*MINMN),
+*          where MINMN = MIN( M,N ).
+*          On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0 )
+      COMPLEX            CZERO
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
+     $                   LDWORK, LIWORK, LRWORK, MAXMN, MAXWRK, MINMN,
+     $                   MINWRK, MM, MNTHR, NLVL, NRWORK, NWORK, SMLSIZ
+      REAL               ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEBRD, CGELQF, CGEQRF, CLACPY,
+     $                   CLALSD, CLASCL, CLASET, CUNMBR,
+     $                   CUNMLQ, CUNMQR, SLABAD, SLASCL,
+     $                   SLASET, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               CLANGE, SLAMCH
+      EXTERNAL           CLANGE, SLAMCH, ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, LOG, MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace.
+*     (Note: Comments in the code beginning "Workspace:" describe the
+*     minimal amount of workspace needed at that point in the code,
+*     as well as the preferred amount for good performance.
+*     NB refers to the optimal block size for the immediately
+*     following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         LIWORK = 1
+         LRWORK = 1
+         IF( MINMN.GT.0 ) THEN
+            SMLSIZ = ILAENV( 9, 'CGELSD', ' ', 0, 0, 0, 0 )
+            MNTHR = ILAENV( 6, 'CGELSD', ' ', M, N, NRHS, -1 )
+            NLVL = MAX( INT( LOG( REAL( MINMN ) / REAL( SMLSIZ + 1 ) ) /
+     $                  LOG( TWO ) ) + 1, 0 )
+            LIWORK = 3*MINMN*NLVL + 11*MINMN
+            MM = M
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns.
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N*ILAENV( 1, 'CGEQRF', ' ', M, N,
+     $                       -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, NRHS*ILAENV( 1, 'CUNMQR', 'LC', M,
+     $                       NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined.
+*
+               LRWORK = 10*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS +
+     $                  ( SMLSIZ + 1 )**2
+               MAXWRK = MAX( MAXWRK, 2*N + ( MM + N )*ILAENV( 1,
+     $                       'CGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + NRHS*ILAENV( 1, 'CUNMBR',
+     $                       'QLC', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'CUNMBR', 'PLN', N, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + N*NRHS )
+               MINWRK = MAX( 2*N + MM, 2*N + N*NRHS )
+            END IF
+            IF( N.GT.M ) THEN
+               LRWORK = 10*M + 2*M*SMLSIZ + 8*M*NLVL + 3*SMLSIZ*NRHS +
+     $                  ( SMLSIZ + 1 )**2
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                           than rows.
+*
+                  MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
+     $                          'CGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
+     $                          'CUNMBR', 'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + ( M - 1 )*ILAENV( 1,
+     $                          'CUNMLQ', 'LC', N, NRHS, M, -1 ) )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + M*NRHS )
+               ELSE
+*
+*                 Path 2 - underdetermined.
+*
+                  MAXWRK = 2*M + ( N + M )*ILAENV( 1, 'CGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 2*M + NRHS*ILAENV( 1, 'CUNMBR',
+     $                          'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 2*M + M*ILAENV( 1, 'CUNMBR',
+     $                          'PLN', N, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 2*M + M*NRHS )
+               END IF
+               MINWRK = MAX( 2*M + N, 2*M + M*NRHS )
+            END IF
+         END IF
+         MINWRK = MIN( MINWRK, MAXWRK )
+         WORK( 1 ) = MAXWRK
+         IWORK( 1 ) = LIWORK
+         RWORK( 1 ) = LRWORK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGELSD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters.
+*
+      EPS = SLAMCH( 'P' )
+      SFMIN = SLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max entry outside range [SMLNUM,BIGNUM].
+*
+      ANRM = CLANGE( 'M', M, N, A, LDA, RWORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL CLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         CALL SLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
+         RANK = 0
+         GO TO 10
+      END IF
+*
+*     Scale B if max entry outside range [SMLNUM,BIGNUM].
+*
+      BNRM = CLANGE( 'M', M, NRHS, B, LDB, RWORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM.
+*
+         CALL CLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL CLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     If M < N make sure B(M+1:N,:) = 0
+*
+      IF( M.LT.N )
+     $   CALL CLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB )
+*
+*     Overdetermined case.
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined.
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns
+*
+            MM = N
+            ITAU = 1
+            NWORK = ITAU + N
+*
+*           Compute A=Q*R.
+*           (RWorkspace: need N)
+*           (CWorkspace: need N, prefer N*NB)
+*
+            CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                   LWORK-NWORK+1, INFO )
+*
+*           Multiply B by transpose(Q).
+*           (RWorkspace: need N)
+*           (CWorkspace: need NRHS, prefer NRHS*NB)
+*
+            CALL CUNMQR( 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*           Zero out below R.
+*
+            IF( N.GT.1 ) THEN
+               CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                      LDA )
+            END IF
+         END IF
+*
+         ITAUQ = 1
+         ITAUP = ITAUQ + N
+         NWORK = ITAUP + N
+         IE = 1
+         NRWORK = IE + N
+*
+*        Bidiagonalize R in A.
+*        (RWorkspace: need N)
+*        (CWorkspace: need 2*N+MM, prefer 2*N+(MM+N)*NB)
+*
+         CALL CGEBRD( MM, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R.
+*        (CWorkspace: need 2*N+NRHS, prefer 2*N+NRHS*NB)
+*
+         CALL CUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL CLALSD( 'U', SMLSIZ, N, NRHS, S, RWORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), RWORK( NRWORK ),
+     $                IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of R.
+*
+         CALL CUNMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
+     $         MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm.
+*
+         LDWORK = M
+         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
+     $       M*LDA+M+M*NRHS ) )LDWORK = LDA
+         ITAU = 1
+         NWORK = M + 1
+*
+*        Compute A=L*Q.
+*        (CWorkspace: need 2*M, prefer M+M*NB)
+*
+         CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+         IL = NWORK
+*
+*        Copy L to WORK(IL), zeroing out above its diagonal.
+*
+         CALL CLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         ITAUQ = IL + LDWORK*M
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+         IE = 1
+         NRWORK = IE + M
+*
+*        Bidiagonalize L in WORK(IL).
+*        (RWorkspace: need M)
+*        (CWorkspace: need M*M+4*M, prefer M*M+4*M+2*M*NB)
+*
+         CALL CGEBRD( M, M, WORK( IL ), LDWORK, S, RWORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L.
+*        (CWorkspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
+*
+         CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL CLALSD( 'U', SMLSIZ, M, NRHS, S, RWORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), RWORK( NRWORK ),
+     $                IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of L.
+*
+         CALL CUNMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUP ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Zero out below first M rows of B.
+*
+         CALL CLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB )
+         NWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B.
+*        (CWorkspace: need NRHS, prefer NRHS*NB)
+*
+         CALL CUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases.
+*
+         ITAUQ = 1
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+         IE = 1
+         NRWORK = IE + M
+*
+*        Bidiagonalize A.
+*        (RWorkspace: need M)
+*        (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
+*
+         CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors.
+*        (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)
+*
+         CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL CLALSD( 'L', SMLSIZ, M, NRHS, S, RWORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), RWORK( NRWORK ),
+     $                IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of A.
+*
+         CALL CUNMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      END IF
+*
+*     Undo scaling.
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   10 CONTINUE
+      WORK( 1 ) = MAXWRK
+      IWORK( 1 ) = LIWORK
+      RWORK( 1 ) = LRWORK
+      RETURN
+*
+*     End of CGELSD
+*
+      END
diff --git a/libcruft/lapack/cgelss.f b/libcruft/lapack/cgelss.f
new file mode 100644
index 0000000..005f87d
--- /dev/null
+++ b/libcruft/lapack/cgelss.f
@@ -0,0 +1,634 @@
+      SUBROUTINE CGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * ), S( * )
+      COMPLEX            A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGELSS computes the minimum norm solution to a complex linear
+*  least squares problem:
+*
+*  Minimize 2-norm(| b - A*x |).
+*
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
+*  X.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the first min(m,n) rows of A are overwritten with
+*          its right singular vectors, stored rowwise.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution matrix X.
+*          If m >= n and RANK = n, the residual sum-of-squares for
+*          the solution in the i-th column is given by the sum of
+*          squares of the modulus of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M,N).
+*
+*  S       (output) REAL array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) REAL
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= 1, and also:
+*          LWORK >=  2*min(M,N) + max(M,N,NRHS)
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (5*min(M,N))
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            BL, CHUNK, I, IASCL, IBSCL, IE, IL, IRWORK,
+     $                   ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
+     $                   MAXWRK, MINMN, MINWRK, MM, MNTHR
+      REAL               ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            VDUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CBDSQR, CCOPY, CGEBRD, CGELQF, CGEMM, CGEMV,
+     $                   CGEQRF, CLACPY, CLASCL, CLASET, CSRSCL, CUNGBR,
+     $                   CUNMBR, CUNMLQ, CUNMQR, SLABAD, SLASCL, SLASET,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               CLANGE, SLAMCH
+      EXTERNAL           ILAENV, CLANGE, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace refers
+*       to real workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( MINMN.GT.0 ) THEN
+            MM = M
+            MNTHR = ILAENV( 6, 'CGELSS', ' ', M, N, NRHS, -1 )
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'CGEQRF', ' ', M,
+     $                       N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'CUNMQR', 'LC',
+     $                       M, NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined
+*
+               MAXWRK = MAX( MAXWRK, 2*N + ( MM + N )*ILAENV( 1,
+     $                       'CGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + NRHS*ILAENV( 1, 'CUNMBR',
+     $                       'QLC', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'CUNGBR', 'P', N, N, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, N*NRHS )
+               MINWRK = 2*N + MAX( NRHS, M )
+            END IF
+            IF( N.GT.M ) THEN
+               MINWRK = 2*M + MAX( NRHS, N )
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                 than rows
+*
+                  MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*M + 2*M*ILAENV( 1,
+     $                          'CGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*M + NRHS*ILAENV( 1,
+     $                          'CUNMBR', 'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*M + ( M - 1 )*ILAENV( 1,
+     $                          'CUNGBR', 'P', M, M, M, -1 ) )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'CUNMLQ',
+     $                          'LC', N, NRHS, M, -1 ) )
+               ELSE
+*
+*                 Path 2 - underdetermined
+*
+                  MAXWRK = 2*M + ( N + M )*ILAENV( 1, 'CGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 2*M + NRHS*ILAENV( 1, 'CUNMBR',
+     $                          'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 2*M + M*ILAENV( 1, 'CUNGBR',
+     $                          'P', M, N, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, N*NRHS )
+               END IF
+            END IF
+            MAXWRK = MAX( MINWRK, MAXWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
+     $      INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGELSS', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      EPS = SLAMCH( 'P' )
+      SFMIN = SLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = CLANGE( 'M', M, N, A, LDA, RWORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL CLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         CALL SLASET( 'F', MINMN, 1, ZERO, ZERO, S, MINMN )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = CLANGE( 'M', M, NRHS, B, LDB, RWORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL CLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL CLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Overdetermined case
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns
+*
+            MM = N
+            ITAU = 1
+            IWORK = ITAU + N
+*
+*           Compute A=Q*R
+*           (CWorkspace: need 2*N, prefer N+N*NB)
+*           (RWorkspace: none)
+*
+            CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                   LWORK-IWORK+1, INFO )
+*
+*           Multiply B by transpose(Q)
+*           (CWorkspace: need N+NRHS, prefer N+NRHS*NB)
+*           (RWorkspace: none)
+*
+            CALL CUNMQR( 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*           Zero out below R
+*
+            IF( N.GT.1 )
+     $         CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                      LDA )
+         END IF
+*
+         IE = 1
+         ITAUQ = 1
+         ITAUP = ITAUQ + N
+         IWORK = ITAUP + N
+*
+*        Bidiagonalize R in A
+*        (CWorkspace: need 2*N+MM, prefer 2*N+(MM+N)*NB)
+*        (RWorkspace: need N)
+*
+         CALL CGEBRD( MM, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R
+*        (CWorkspace: need 2*N+NRHS, prefer 2*N+NRHS*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in A
+*        (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IRWORK = IE + N
+*
+*        Perform bidiagonal QR iteration
+*          multiply B by transpose of left singular vectors
+*          compute right singular vectors in A
+*        (CWorkspace: none)
+*        (RWorkspace: need BDSPAC)
+*
+         CALL CBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, RWORK( IRWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 10 I = 1, N
+            IF( S( I ).GT.THR ) THEN
+               CALL CSRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL CLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            END IF
+   10    CONTINUE
+*
+*        Multiply B by right singular vectors
+*        (CWorkspace: need N, prefer N*NRHS)
+*        (RWorkspace: none)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL CGEMM( 'C', 'N', N, NRHS, N, CONE, A, LDA, B, LDB,
+     $                  CZERO, WORK, LDB )
+            CALL CLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 20 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL CGEMM( 'C', 'N', N, BL, N, CONE, A, LDA, B( 1, I ),
+     $                     LDB, CZERO, WORK, N )
+               CALL CLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB )
+   20       CONTINUE
+         ELSE
+            CALL CGEMV( 'C', N, N, CONE, A, LDA, B, 1, CZERO, WORK, 1 )
+            CALL CCOPY( N, WORK, 1, B, 1 )
+         END IF
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.3*M+M*M+MAX( M, NRHS, N-2*M ) )
+     $          THEN
+*
+*        Underdetermined case, M much less than N
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm
+*
+         LDWORK = M
+         IF( LWORK.GE.3*M+M*LDA+MAX( M, NRHS, N-2*M ) )
+     $      LDWORK = LDA
+         ITAU = 1
+         IWORK = M + 1
+*
+*        Compute A=L*Q
+*        (CWorkspace: need 2*M, prefer M+M*NB)
+*        (RWorkspace: none)
+*
+         CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+         IL = IWORK
+*
+*        Copy L to WORK(IL), zeroing out above it
+*
+         CALL CLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         IE = 1
+         ITAUQ = IL + LDWORK*M
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize L in WORK(IL)
+*        (CWorkspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*        (RWorkspace: need M)
+*
+         CALL CGEBRD( M, M, WORK( IL ), LDWORK, S, RWORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L
+*        (CWorkspace: need M*M+3*M+NRHS, prefer M*M+3*M+NRHS*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in WORK(IL)
+*        (CWorkspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IRWORK = IE + M
+*
+*        Perform bidiagonal QR iteration, computing right singular
+*        vectors of L in WORK(IL) and multiplying B by transpose of
+*        left singular vectors
+*        (CWorkspace: need M*M)
+*        (RWorkspace: need BDSPAC)
+*
+         CALL CBDSQR( 'U', M, M, 0, NRHS, S, RWORK( IE ), WORK( IL ),
+     $                LDWORK, A, LDA, B, LDB, RWORK( IRWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 30 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL CSRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL CLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            END IF
+   30    CONTINUE
+         IWORK = IL + M*LDWORK
+*
+*        Multiply B by right singular vectors of L in WORK(IL)
+*        (CWorkspace: need M*M+2*M, prefer M*M+M+M*NRHS)
+*        (RWorkspace: none)
+*
+         IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN
+            CALL CGEMM( 'C', 'N', M, NRHS, M, CONE, WORK( IL ), LDWORK,
+     $                  B, LDB, CZERO, WORK( IWORK ), LDB )
+            CALL CLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = ( LWORK-IWORK+1 ) / M
+            DO 40 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL CGEMM( 'C', 'N', M, BL, M, CONE, WORK( IL ), LDWORK,
+     $                     B( 1, I ), LDB, CZERO, WORK( IWORK ), M )
+               CALL CLACPY( 'G', M, BL, WORK( IWORK ), M, B( 1, I ),
+     $                      LDB )
+   40       CONTINUE
+         ELSE
+            CALL CGEMV( 'C', M, M, CONE, WORK( IL ), LDWORK, B( 1, 1 ),
+     $                  1, CZERO, WORK( IWORK ), 1 )
+            CALL CCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 )
+         END IF
+*
+*        Zero out below first M rows of B
+*
+         CALL CLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB )
+         IWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B
+*        (CWorkspace: need M+NRHS, prefer M+NHRS*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases
+*
+         IE = 1
+         ITAUQ = 1
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize A
+*        (CWorkspace: need 3*M, prefer 2*M+(M+N)*NB)
+*        (RWorkspace: need N)
+*
+         CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors
+*        (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors in A
+*        (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*        (RWorkspace: none)
+*
+         CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IRWORK = IE + M
+*
+*        Perform bidiagonal QR iteration,
+*           computing right singular vectors of A in A and
+*           multiplying B by transpose of left singular vectors
+*        (CWorkspace: none)
+*        (RWorkspace: need BDSPAC)
+*
+         CALL CBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, RWORK( IRWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 50 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL CSRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL CLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            END IF
+   50    CONTINUE
+*
+*        Multiply B by right singular vectors of A
+*        (CWorkspace: need N, prefer N*NRHS)
+*        (RWorkspace: none)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL CGEMM( 'C', 'N', N, NRHS, M, CONE, A, LDA, B, LDB,
+     $                  CZERO, WORK, LDB )
+            CALL CLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 60 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL CGEMM( 'C', 'N', N, BL, M, CONE, A, LDA, B( 1, I ),
+     $                     LDB, CZERO, WORK, N )
+               CALL CLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB )
+   60       CONTINUE
+         ELSE
+            CALL CGEMV( 'C', M, N, CONE, A, LDA, B, 1, CZERO, WORK, 1 )
+            CALL CCOPY( N, WORK, 1, B, 1 )
+         END IF
+      END IF
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+   70 CONTINUE
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of CGELSS
+*
+      END
diff --git a/libcruft/lapack/cgelsy.f b/libcruft/lapack/cgelsy.f
new file mode 100644
index 0000000..77ae7fa
--- /dev/null
+++ b/libcruft/lapack/cgelsy.f
@@ -0,0 +1,385 @@
+      SUBROUTINE CGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
+     $                   WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGELSY computes the minimum-norm solution to a complex linear least
+*  squares problem:
+*      minimize || A * X - B ||
+*  using a complete orthogonal factorization of A.  A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The routine first computes a QR factorization with column pivoting:
+*      A * P = Q * [ R11 R12 ]
+*                  [  0  R22 ]
+*  with R11 defined as the largest leading submatrix whose estimated
+*  condition number is less than 1/RCOND.  The order of R11, RANK,
+*  is the effective rank of A.
+*
+*  Then, R22 is considered to be negligible, and R12 is annihilated
+*  by unitary transformations from the right, arriving at the
+*  complete orthogonal factorization:
+*     A * P = Q * [ T11 0 ] * Z
+*                 [  0  0 ]
+*  The minimum-norm solution is then
+*     X = P * Z' [ inv(T11)*Q1'*B ]
+*                [        0       ]
+*  where Q1 consists of the first RANK columns of Q.
+*
+*  This routine is basically identical to the original xGELSX except
+*  three differences:
+*    o The permutation of matrix B (the right hand side) is faster and
+*      more simple.
+*    o The call to the subroutine xGEQPF has been substituted by the
+*      the call to the subroutine xGEQP3. This subroutine is a Blas-3
+*      version of the QR factorization with column pivoting.
+*    o Matrix B (the right hand side) is updated with Blas-3.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of
+*          columns of matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been overwritten by details of its
+*          complete orthogonal factorization.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,M,N).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of AP, otherwise column i is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  RCOND   (input) REAL
+*          RCOND is used to determine the effective rank of A, which
+*          is defined as the order of the largest leading triangular
+*          submatrix R11 in the QR factorization with pivoting of A,
+*          whose estimated condition number < 1/RCOND.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the order of the submatrix
+*          R11.  This is the same as the order of the submatrix T11
+*          in the complete orthogonal factorization of A.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          The unblocked strategy requires that:
+*            LWORK >= MN + MAX( 2*MN, N+1, MN+NRHS )
+*          where MN = min(M,N).
+*          The block algorithm requires that:
+*            LWORK >= MN + MAX( 2*MN, NB*(N+1), MN+MN*NB, MN+NB*NRHS )
+*          where NB is an upper bound on the blocksize returned
+*          by ILAENV for the routines CGEQP3, CTZRZF, CTZRQF, CUNMQR,
+*          and CUNMRZ.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*    E. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            IMAX, IMIN
+      PARAMETER          ( IMAX = 1, IMIN = 2 )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKOPT, MN,
+     $                   NB, NB1, NB2, NB3, NB4
+      REAL               ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
+     $                   SMLNUM, WSIZE
+      COMPLEX            C1, C2, S1, S2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEQP3, CLAIC1, CLASCL, CLASET, CTRSM,
+     $                   CTZRZF, CUNMQR, CUNMRZ, SLABAD, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               CLANGE, SLAMCH
+      EXTERNAL           CLANGE, ILAENV, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL, CMPLX
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M, N )
+      ISMIN = MN + 1
+      ISMAX = 2*MN + 1
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      NB1 = ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+      NB2 = ILAENV( 1, 'CGERQF', ' ', M, N, -1, -1 )
+      NB3 = ILAENV( 1, 'CUNMQR', ' ', M, N, NRHS, -1 )
+      NB4 = ILAENV( 1, 'CUNMRQ', ' ', M, N, NRHS, -1 )
+      NB = MAX( NB1, NB2, NB3, NB4 )
+      LWKOPT = MAX( 1, MN+2*N+NB*(N+1), 2*MN+NB*NRHS )
+      WORK( 1 ) = CMPLX( LWKOPT )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
+         INFO = -7
+      ELSE IF( LWORK.LT.( MN+MAX( 2*MN, N+1, MN+NRHS ) ) .AND.
+     $   .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGELSY', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( MIN( M, N, NRHS ).EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A, B if max entries outside range [SMLNUM,BIGNUM]
+*
+      ANRM = CLANGE( 'M', M, N, A, LDA, RWORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL CLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+      BNRM = CLANGE( 'M', M, NRHS, B, LDB, RWORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL CLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL CLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Compute QR factorization with column pivoting of A:
+*        A * P = Q * R
+*
+      CALL CGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
+     $             LWORK-MN, RWORK, INFO )
+      WSIZE = MN + REAL( WORK( MN+1 ) )
+*
+*     complex workspace: MN+NB*(N+1). real workspace 2*N.
+*     Details of Householder rotations stored in WORK(1:MN).
+*
+*     Determine RANK using incremental condition estimation
+*
+      WORK( ISMIN ) = CONE
+      WORK( ISMAX ) = CONE
+      SMAX = ABS( A( 1, 1 ) )
+      SMIN = SMAX
+      IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
+         RANK = 0
+         CALL CLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         GO TO 70
+      ELSE
+         RANK = 1
+      END IF
+*
+   10 CONTINUE
+      IF( RANK.LT.MN ) THEN
+         I = RANK + 1
+         CALL CLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
+     $                A( I, I ), SMINPR, S1, C1 )
+         CALL CLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
+     $                A( I, I ), SMAXPR, S2, C2 )
+*
+         IF( SMAXPR*RCOND.LE.SMINPR ) THEN
+            DO 20 I = 1, RANK
+               WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
+               WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
+   20       CONTINUE
+            WORK( ISMIN+RANK ) = C1
+            WORK( ISMAX+RANK ) = C2
+            SMIN = SMINPR
+            SMAX = SMAXPR
+            RANK = RANK + 1
+            GO TO 10
+         END IF
+      END IF
+*
+*     complex workspace: 3*MN.
+*
+*     Logically partition R = [ R11 R12 ]
+*                             [  0  R22 ]
+*     where R11 = R(1:RANK,1:RANK)
+*
+*     [R11,R12] = [ T11, 0 ] * Y
+*
+      IF( RANK.LT.N )
+     $   CALL CTZRZF( RANK, N, A, LDA, WORK( MN+1 ), WORK( 2*MN+1 ),
+     $                LWORK-2*MN, INFO )
+*
+*     complex workspace: 2*MN.
+*     Details of Householder rotations stored in WORK(MN+1:2*MN)
+*
+*     B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
+*
+      CALL CUNMQR( 'Left', 'Conjugate transpose', M, NRHS, MN, A, LDA,
+     $             WORK( 1 ), B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
+      WSIZE = MAX( WSIZE, 2*MN+REAL( WORK( 2*MN+1 ) ) )
+*
+*     complex workspace: 2*MN+NB*NRHS.
+*
+*     B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
+*
+      CALL CTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
+     $            NRHS, CONE, A, LDA, B, LDB )
+*
+      DO 40 J = 1, NRHS
+         DO 30 I = RANK + 1, N
+            B( I, J ) = CZERO
+   30    CONTINUE
+   40 CONTINUE
+*
+*     B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
+*
+      IF( RANK.LT.N ) THEN
+         CALL CUNMRZ( 'Left', 'Conjugate transpose', N, NRHS, RANK,
+     $                N-RANK, A, LDA, WORK( MN+1 ), B, LDB,
+     $                WORK( 2*MN+1 ), LWORK-2*MN, INFO )
+      END IF
+*
+*     complex workspace: 2*MN+NRHS.
+*
+*     B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
+*
+      DO 60 J = 1, NRHS
+         DO 50 I = 1, N
+            WORK( JPVT( I ) ) = B( I, J )
+   50    CONTINUE
+         CALL CCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )
+   60 CONTINUE
+*
+*     complex workspace: N.
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL CLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL CLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   70 CONTINUE
+      WORK( 1 ) = CMPLX( LWKOPT )
+*
+      RETURN
+*
+*     End of CGELSY
+*
+      END
diff --git a/libcruft/lapack/cgeqp3.f b/libcruft/lapack/cgeqp3.f
new file mode 100644
index 0000000..548123e
--- /dev/null
+++ b/libcruft/lapack/cgeqp3.f
@@ -0,0 +1,293 @@
+      SUBROUTINE CGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEQP3 computes a QR factorization with column pivoting of a
+*  matrix A:  A*P = Q*R  using Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper trapezoidal matrix R; the elements below
+*          the diagonal, together with the array TAU, represent the
+*          unitary matrix Q as a product of min(M,N) elementary
+*          reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(J).ne.0, the J-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(J)=0,
+*          the J-th column of A is a free column.
+*          On exit, if JPVT(J)=K, then the J-th column of A*P was the
+*          the K-th column of A.
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= N+1.
+*          For optimal performance LWORK >= ( N+1 )*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit.
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real/complex scalar, and v is a real/complex vector
+*  with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
+*  A(i+1:m,i), and tau in TAU(i).
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            INB, INBMIN, IXOVER
+      PARAMETER          ( INB = 1, INBMIN = 2, IXOVER = 3 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,
+     $                   NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEQRF, CLAQP2, CLAQPS, CSWAP, CUNMQR, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               SCNRM2
+      EXTERNAL           ILAENV, SCNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test input arguments
+*     ====================
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         MINMN = MIN( M, N )
+         IF( MINMN.EQ.0 ) THEN
+            IWS = 1
+            LWKOPT = 1
+         ELSE
+            IWS = N + 1
+            NB = ILAENV( INB, 'CGEQRF', ' ', M, N, -1, -1 )
+            LWKOPT = ( N + 1 )*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEQP3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( MINMN.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Move initial columns up front.
+*
+      NFXD = 1
+      DO 10 J = 1, N
+         IF( JPVT( J ).NE.0 ) THEN
+            IF( J.NE.NFXD ) THEN
+               CALL CSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
+               JPVT( J ) = JPVT( NFXD )
+               JPVT( NFXD ) = J
+            ELSE
+               JPVT( J ) = J
+            END IF
+            NFXD = NFXD + 1
+         ELSE
+            JPVT( J ) = J
+         END IF
+   10 CONTINUE
+      NFXD = NFXD - 1
+*
+*     Factorize fixed columns
+*     =======================
+*
+*     Compute the QR factorization of fixed columns and update
+*     remaining columns.
+*
+      IF( NFXD.GT.0 ) THEN
+         NA = MIN( M, NFXD )
+*CC      CALL CGEQR2( M, NA, A, LDA, TAU, WORK, INFO )
+         CALL CGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
+         IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         IF( NA.LT.N ) THEN
+*CC         CALL CUNM2R( 'Left', 'Conjugate Transpose', M, N-NA,
+*CC  $                   NA, A, LDA, TAU, A( 1, NA+1 ), LDA, WORK,
+*CC  $                   INFO )
+            CALL CUNMQR( 'Left', 'Conjugate Transpose', M, N-NA, NA, A,
+     $                   LDA, TAU, A( 1, NA+1 ), LDA, WORK, LWORK,
+     $                   INFO )
+            IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         END IF
+      END IF
+*
+*     Factorize free columns
+*     ======================
+*
+      IF( NFXD.LT.MINMN ) THEN
+*
+         SM = M - NFXD
+         SN = N - NFXD
+         SMINMN = MINMN - NFXD
+*
+*        Determine the block size.
+*
+         NB = ILAENV( INB, 'CGEQRF', ' ', SM, SN, -1, -1 )
+         NBMIN = 2
+         NX = 0
+*
+         IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
+*
+*           Determine when to cross over from blocked to unblocked code.
+*
+            NX = MAX( 0, ILAENV( IXOVER, 'CGEQRF', ' ', SM, SN, -1,
+     $           -1 ) )
+*
+*
+            IF( NX.LT.SMINMN ) THEN
+*
+*              Determine if workspace is large enough for blocked code.
+*
+               MINWS = ( SN+1 )*NB
+               IWS = MAX( IWS, MINWS )
+               IF( LWORK.LT.MINWS ) THEN
+*
+*                 Not enough workspace to use optimal NB: Reduce NB and
+*                 determine the minimum value of NB.
+*
+                  NB = LWORK / ( SN+1 )
+                  NBMIN = MAX( 2, ILAENV( INBMIN, 'CGEQRF', ' ', SM, SN,
+     $                    -1, -1 ) )
+*
+*
+               END IF
+            END IF
+         END IF
+*
+*        Initialize partial column norms. The first N elements of work
+*        store the exact column norms.
+*
+         DO 20 J = NFXD + 1, N
+            RWORK( J ) = SCNRM2( SM, A( NFXD+1, J ), 1 )
+            RWORK( N+J ) = RWORK( J )
+   20    CONTINUE
+*
+         IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
+     $       ( NX.LT.SMINMN ) ) THEN
+*
+*           Use blocked code initially.
+*
+            J = NFXD + 1
+*
+*           Compute factorization: while loop.
+*
+*
+            TOPBMN = MINMN - NX
+   30       CONTINUE
+            IF( J.LE.TOPBMN ) THEN
+               JB = MIN( NB, TOPBMN-J+1 )
+*
+*              Factorize JB columns among columns J:N.
+*
+               CALL CLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
+     $                      JPVT( J ), TAU( J ), RWORK( J ),
+     $                      RWORK( N+J ), WORK( 1 ), WORK( JB+1 ),
+     $                      N-J+1 )
+*
+               J = J + FJB
+               GO TO 30
+            END IF
+         ELSE
+            J = NFXD + 1
+         END IF
+*
+*        Use unblocked code to factor the last or only block.
+*
+*
+         IF( J.LE.MINMN )
+     $      CALL CLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
+     $                   TAU( J ), RWORK( J ), RWORK( N+J ), WORK( 1 ) )
+*
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CGEQP3
+*
+      END
diff --git a/libcruft/lapack/cgeqpf.f b/libcruft/lapack/cgeqpf.f
new file mode 100644
index 0000000..40fa83d
--- /dev/null
+++ b/libcruft/lapack/cgeqpf.f
@@ -0,0 +1,234 @@
+      SUBROUTINE CGEQPF( M, N, A, LDA, JPVT, TAU, WORK, RWORK, INFO )
+*
+*  -- LAPACK deprecated driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This routine is deprecated and has been replaced by routine CGEQP3.
+*
+*  CGEQPF computes a QR factorization with column pivoting of a
+*  complex M-by-N matrix A: A*P = Q*R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper triangular matrix R; the elements
+*          below the diagonal, together with the array TAU,
+*          represent the unitary matrix Q as a product of
+*          min(m,n) elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) COMPLEX array, dimension (N)
+*
+*  RWORK   (workspace) REAL array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(n)
+*
+*  Each H(i) has the form
+*
+*     H = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i).
+*
+*  The matrix P is represented in jpvt as follows: If
+*     jpvt(j) = i
+*  then the jth column of P is the ith canonical unit vector.
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MA, MN, PVT
+      REAL               TEMP, TEMP2, TOL3Z
+      COMPLEX            AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEQR2, CLARF, CLARFG, CSWAP, CUNM2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, CMPLX, CONJG, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SCNRM2, SLAMCH
+      EXTERNAL           ISAMAX, SCNRM2, SLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEQPF', -INFO )
+         RETURN
+      END IF
+*
+      MN = MIN( M, N )
+      TOL3Z = SQRT(SLAMCH('Epsilon'))
+*
+*     Move initial columns up front
+*
+      ITEMP = 1
+      DO 10 I = 1, N
+         IF( JPVT( I ).NE.0 ) THEN
+            IF( I.NE.ITEMP ) THEN
+               CALL CSWAP( M, A( 1, I ), 1, A( 1, ITEMP ), 1 )
+               JPVT( I ) = JPVT( ITEMP )
+               JPVT( ITEMP ) = I
+            ELSE
+               JPVT( I ) = I
+            END IF
+            ITEMP = ITEMP + 1
+         ELSE
+            JPVT( I ) = I
+         END IF
+   10 CONTINUE
+      ITEMP = ITEMP - 1
+*
+*     Compute the QR factorization and update remaining columns
+*
+      IF( ITEMP.GT.0 ) THEN
+         MA = MIN( ITEMP, M )
+         CALL CGEQR2( M, MA, A, LDA, TAU, WORK, INFO )
+         IF( MA.LT.N ) THEN
+            CALL CUNM2R( 'Left', 'Conjugate transpose', M, N-MA, MA, A,
+     $                   LDA, TAU, A( 1, MA+1 ), LDA, WORK, INFO )
+         END IF
+      END IF
+*
+      IF( ITEMP.LT.MN ) THEN
+*
+*        Initialize partial column norms. The first n elements of
+*        work store the exact column norms.
+*
+         DO 20 I = ITEMP + 1, N
+            RWORK( I ) = SCNRM2( M-ITEMP, A( ITEMP+1, I ), 1 )
+            RWORK( N+I ) = RWORK( I )
+   20    CONTINUE
+*
+*        Compute factorization
+*
+         DO 40 I = ITEMP + 1, MN
+*
+*           Determine ith pivot column and swap if necessary
+*
+            PVT = ( I-1 ) + ISAMAX( N-I+1, RWORK( I ), 1 )
+*
+            IF( PVT.NE.I ) THEN
+               CALL CSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+               ITEMP = JPVT( PVT )
+               JPVT( PVT ) = JPVT( I )
+               JPVT( I ) = ITEMP
+               RWORK( PVT ) = RWORK( I )
+               RWORK( N+PVT ) = RWORK( N+I )
+            END IF
+*
+*           Generate elementary reflector H(i)
+*
+            AII = A( I, I )
+            CALL CLARFG( M-I+1, AII, A( MIN( I+1, M ), I ), 1,
+     $                   TAU( I ) )
+            A( I, I ) = AII
+*
+            IF( I.LT.N ) THEN
+*
+*              Apply H(i) to A(i:m,i+1:n) from the left
+*
+               AII = A( I, I )
+               A( I, I ) = CMPLX( ONE )
+               CALL CLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
+     $                     CONJG( TAU( I ) ), A( I, I+1 ), LDA, WORK )
+               A( I, I ) = AII
+            END IF
+*
+*           Update partial column norms
+*
+            DO 30 J = I + 1, N
+               IF( RWORK( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*                 
+                  TEMP = ABS( A( I, J ) ) / RWORK( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( RWORK( J ) / RWORK( N+J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN 
+                     IF( M-I.GT.0 ) THEN
+                        RWORK( J ) = SCNRM2( M-I, A( I+1, J ), 1 )
+                        RWORK( N+J ) = RWORK( J )
+                     ELSE
+                        RWORK( J ) = ZERO
+                        RWORK( N+J ) = ZERO
+                     END IF
+                  ELSE
+                     RWORK( J ) = RWORK( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   30       CONTINUE
+*
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CGEQPF
+*
+      END
diff --git a/libcruft/lapack/cgeqr2.f b/libcruft/lapack/cgeqr2.f
new file mode 100644
index 0000000..58577ce
--- /dev/null
+++ b/libcruft/lapack/cgeqr2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE CGEQR2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEQR2 computes a QR factorization of a complex m by n matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(m,n) by n upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) COMPLEX array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARF, CLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEQR2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+         CALL CLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                TAU( I ) )
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i)' to A(i:m,i+1:n) from the left
+*
+            ALPHA = A( I, I )
+            A( I, I ) = ONE
+            CALL CLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
+     $                  CONJG( TAU( I ) ), A( I, I+1 ), LDA, WORK )
+            A( I, I ) = ALPHA
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of CGEQR2
+*
+      END
diff --git a/libcruft/lapack/cgeqrf.f b/libcruft/lapack/cgeqrf.f
new file mode 100644
index 0000000..6cd3282
--- /dev/null
+++ b/libcruft/lapack/cgeqrf.f
@@ -0,0 +1,196 @@
+      SUBROUTINE CGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGEQRF computes a QR factorization of a complex M-by-N matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(M,N)-by-N upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of min(m,n) elementary reflectors (see Further
+*          Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEQR2, CLARFB, CLARFT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGEQRF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'CGEQRF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'CGEQRF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the QR factorization of the current block
+*           A(i:m,i:i+ib-1)
+*
+            CALL CGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL CLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i:m,i+ib:n) from the left
+*
+               CALL CLARFB( 'Left', 'Conjugate transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL CGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CGEQRF
+*
+      END
diff --git a/libcruft/lapack/cgesv.f b/libcruft/lapack/cgesv.f
new file mode 100644
index 0000000..7b362dd
--- /dev/null
+++ b/libcruft/lapack/cgesv.f
@@ -0,0 +1,107 @@
+      SUBROUTINE CGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGESV computes the solution to a complex system of linear equations
+*     A * X = B,
+*  where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
+*
+*  The LU decomposition with partial pivoting and row interchanges is
+*  used to factor A as
+*     A = P * L * U,
+*  where P is a permutation matrix, L is unit lower triangular, and U is
+*  upper triangular.  The factored form of A is then used to solve the
+*  system of equations A * X = B.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of linear equations, i.e., the order of the
+*          matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the N-by-N coefficient matrix A.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices that define the permutation matrix P;
+*          row i of the matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS matrix of right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero.  The factorization
+*                has been completed, but the factor U is exactly
+*                singular, so the solution could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           CGETRF, CGETRS, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGESV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the LU factorization of A.
+*
+      CALL CGETRF( N, N, A, LDA, IPIV, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL CGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, B, LDB,
+     $                INFO )
+      END IF
+      RETURN
+*
+*     End of CGESV
+*
+      END
diff --git a/libcruft/lapack/cgesvd.f b/libcruft/lapack/cgesvd.f
new file mode 100644
index 0000000..9ba709f
--- /dev/null
+++ b/libcruft/lapack/cgesvd.f
@@ -0,0 +1,3602 @@
+      SUBROUTINE CGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBU, JOBVT
+      INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * ), S( * )
+      COMPLEX            A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGESVD computes the singular value decomposition (SVD) of a complex
+*  M-by-N matrix A, optionally computing the left and/or right singular
+*  vectors. The SVD is written
+*
+*       A = U * SIGMA * conjugate-transpose(V)
+*
+*  where SIGMA is an M-by-N matrix which is zero except for its
+*  min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
+*  V is an N-by-N unitary matrix.  The diagonal elements of SIGMA
+*  are the singular values of A; they are real and non-negative, and
+*  are returned in descending order.  The first min(m,n) columns of
+*  U and V are the left and right singular vectors of A.
+*
+*  Note that the routine returns V**H, not V.
+*
+*  Arguments
+*  =========
+*
+*  JOBU    (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix U:
+*          = 'A':  all M columns of U are returned in array U:
+*          = 'S':  the first min(m,n) columns of U (the left singular
+*                  vectors) are returned in the array U;
+*          = 'O':  the first min(m,n) columns of U (the left singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no columns of U (no left singular vectors) are
+*                  computed.
+*
+*  JOBVT   (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix
+*          V**H:
+*          = 'A':  all N rows of V**H are returned in the array VT;
+*          = 'S':  the first min(m,n) rows of V**H (the right singular
+*                  vectors) are returned in the array VT;
+*          = 'O':  the first min(m,n) rows of V**H (the right singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no rows of V**H (no right singular vectors) are
+*                  computed.
+*
+*          JOBVT and JOBU cannot both be 'O'.
+*
+*  M       (input) INTEGER
+*          The number of rows of the input matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the input matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit,
+*          if JOBU = 'O',  A is overwritten with the first min(m,n)
+*                          columns of U (the left singular vectors,
+*                          stored columnwise);
+*          if JOBVT = 'O', A is overwritten with the first min(m,n)
+*                          rows of V**H (the right singular vectors,
+*                          stored rowwise);
+*          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
+*                          are destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  S       (output) REAL array, dimension (min(M,N))
+*          The singular values of A, sorted so that S(i) >= S(i+1).
+*
+*  U       (output) COMPLEX array, dimension (LDU,UCOL)
+*          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
+*          If JOBU = 'A', U contains the M-by-M unitary matrix U;
+*          if JOBU = 'S', U contains the first min(m,n) columns of U
+*          (the left singular vectors, stored columnwise);
+*          if JOBU = 'N' or 'O', U is not referenced.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= 1; if
+*          JOBU = 'S' or 'A', LDU >= M.
+*
+*  VT      (output) COMPLEX array, dimension (LDVT,N)
+*          If JOBVT = 'A', VT contains the N-by-N unitary matrix
+*          V**H;
+*          if JOBVT = 'S', VT contains the first min(m,n) rows of
+*          V**H (the right singular vectors, stored rowwise);
+*          if JOBVT = 'N' or 'O', VT is not referenced.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.  LDVT >= 1; if
+*          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          LWORK >=  MAX(1,2*MIN(M,N)+MAX(M,N)).
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (5*min(M,N))
+*          On exit, if INFO > 0, RWORK(1:MIN(M,N)-1) contains the
+*          unconverged superdiagonal elements of an upper bidiagonal
+*          matrix B whose diagonal is in S (not necessarily sorted).
+*          B satisfies A = U * B * VT, so it has the same singular
+*          values as A, and singular vectors related by U and VT.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if CBDSQR did not converge, INFO specifies how many
+*                superdiagonals of an intermediate bidiagonal form B
+*                did not converge to zero. See the description of RWORK
+*                above for details.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E0, 0.0E0 ),
+     $                   CONE = ( 1.0E0, 0.0E0 ) )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
+     $                   WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
+      INTEGER            BLK, CHUNK, I, IE, IERR, IR, IRWORK, ISCL,
+     $                   ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
+     $                   MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
+     $                   NRVT, WRKBL
+      REAL               ANRM, BIGNUM, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 )
+      COMPLEX            CDUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CBDSQR, CGEBRD, CGELQF, CGEMM, CGEQRF, CLACPY,
+     $                   CLASCL, CLASET, CUNGBR, CUNGLQ, CUNGQR, CUNMBR,
+     $                   SLASCL, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               CLANGE, SLAMCH
+      EXTERNAL           LSAME, ILAENV, CLANGE, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      WNTUA = LSAME( JOBU, 'A' )
+      WNTUS = LSAME( JOBU, 'S' )
+      WNTUAS = WNTUA .OR. WNTUS
+      WNTUO = LSAME( JOBU, 'O' )
+      WNTUN = LSAME( JOBU, 'N' )
+      WNTVA = LSAME( JOBVT, 'A' )
+      WNTVS = LSAME( JOBVT, 'S' )
+      WNTVAS = WNTVA .OR. WNTVS
+      WNTVO = LSAME( JOBVT, 'O' )
+      WNTVN = LSAME( JOBVT, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
+     $         ( WNTVO .AND. WNTUO ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
+         INFO = -9
+      ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
+     $         ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace to
+*       real workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( M.GE.N .AND. MINMN.GT.0 ) THEN
+*
+*           Space needed for CBDSQR is BDSPAC = 5*N
+*
+            MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            IF( M.GE.MNTHR ) THEN
+               IF( WNTUN ) THEN
+*
+*                 Path 1 (M much larger than N, JOBU='N')
+*
+                  MAXWRK = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 2*N+2*N*
+     $                     ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  IF( WNTVO .OR. WNTVAS )
+     $               MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
+     $                        ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+                  MINWRK = 3*N
+               ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUS .AND. WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUS .AND. WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUS .AND. WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUA .AND. WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUA .AND. WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUA .AND. WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               END IF
+            ELSE
+*
+*              Path 10 (M at least N, but not much larger)
+*
+               MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTUS .OR. WNTUO )
+     $            MAXWRK = MAX( MAXWRK, 2*N+N*
+     $                     ILAENV( 1, 'CUNGBR', 'Q', M, N, N, -1 ) )
+               IF( WNTUA )
+     $            MAXWRK = MAX( MAXWRK, 2*N+M*
+     $                     ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
+               IF( .NOT.WNTVN )
+     $            MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
+     $                     ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+               MINWRK = 2*N + M
+            END IF
+         ELSE IF( MINMN.GT.0 ) THEN
+*
+*           Space needed for CBDSQR is BDSPAC = 5*M
+*
+            MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            IF( N.GE.MNTHR ) THEN
+               IF( WNTVN ) THEN
+*
+*                 Path 1t(N much larger than M, JOBVT='N')
+*
+                  MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 2*M+2*M*
+     $                     ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  IF( WNTUO .OR. WNTUAS )
+     $               MAXWRK = MAX( MAXWRK, 2*M+M*
+     $                        ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+                  MINWRK = 3*M
+               ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*                 Path 3t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVS .AND. WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVS .AND. WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVS .AND. WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVA .AND. WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVA .AND. WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVA .AND. WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               END IF
+            ELSE
+*
+*              Path 10t(N greater than M, but not much larger)
+*
+               MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTVS .OR. WNTVO )
+     $            MAXWRK = MAX( MAXWRK, 2*M+M*
+     $                     ILAENV( 1, 'CUNGBR', 'P', M, N, M, -1 ) )
+               IF( WNTVA )
+     $            MAXWRK = MAX( MAXWRK, 2*M+N*
+     $                     ILAENV( 1, 'CUNGBR', 'P', N, N, M, -1 ) )
+               IF( .NOT.WNTUN )
+     $            MAXWRK = MAX( MAXWRK, 2*M+( M-1 )*
+     $                     ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+               MINWRK = 2*M + N
+            END IF
+         END IF
+         MAXWRK = MAX( MINWRK, MAXWRK )
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGESVD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SQRT( SLAMCH( 'S' ) ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = CLANGE( 'M', M, N, A, LDA, DUM )
+      ISCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ISCL = 1
+         CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ISCL = 1
+         CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        A has at least as many rows as columns. If A has sufficiently
+*        more rows than columns, first reduce using the QR
+*        decomposition (if sufficient workspace available)
+*
+         IF( M.GE.MNTHR ) THEN
+*
+            IF( WNTUN ) THEN
+*
+*              Path 1 (M much larger than N, JOBU='N')
+*              No left singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + N
+*
+*              Compute A=Q*R
+*              (CWorkspace: need 2*N, prefer N+N*NB)
+*              (RWorkspace: need 0)
+*
+               CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out below R
+*
+               CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                      LDA )
+               IE = 1
+               ITAUQ = 1
+               ITAUP = ITAUQ + N
+               IWORK = ITAUP + N
+*
+*              Bidiagonalize R in A
+*              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*              (RWorkspace: need N)
+*
+               CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               NCVT = 0
+               IF( WNTVO .OR. WNTVAS ) THEN
+*
+*                 If right singular vectors desired, generate P'.
+*                 (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  NCVT = N
+               END IF
+               IRWORK = IE + N
+*
+*              Perform bidiagonal QR iteration, computing right
+*              singular vectors of A in A if desired
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'U', N, NCVT, 0, 0, S, RWORK( IE ), A, LDA,
+     $                      CDUM, 1, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+*              If right singular vectors desired in VT, copy them there
+*
+               IF( WNTVAS )
+     $            CALL CLACPY( 'F', N, N, A, LDA, VT, LDVT )
+*
+            ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*              Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*              N left singular vectors to be overwritten on A and
+*              no right singular vectors to be computed
+*
+               IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N, WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to WORK(IR) and zero out below it
+*
+                  CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
+                  CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                         WORK( IR+1 ), LDWRKR )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in WORK(IR)
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                 (RWorkspace: need N)
+*
+                  CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing R
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                 (RWorkspace: need 0)
+*
+                  CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR)
+*                 (CWorkspace: need N*N)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM, 1,
+     $                         WORK( IR ), LDWRKR, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need N*N+N, prefer N*N+M*N)
+*                 (RWorkspace: 0)
+*
+                  DO 10 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL CGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL CLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   10             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = 1
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize A
+*                 (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
+*                 (RWorkspace: N)
+*
+                  CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing A
+*                 (CWorkspace: need 3*N, prefer 2*N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A
+*                 (CWorkspace: need 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM, 1,
+     $                         A, LDA, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*              Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
+*              N left singular vectors to be overwritten on A and
+*              N right singular vectors to be computed in VT
+*
+               IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N and WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT, copying result to WORK(IR)
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                 (RWorkspace: need N)
+*
+                  CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL CLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
+*
+*                 Generate left vectors bidiagonalizing R in WORK(IR)
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (CWorkspace: need N*N+3*N-1, prefer N*N+2*N+(N-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR) and computing right
+*                 singular vectors of R in VT
+*                 (CWorkspace: need N*N)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
+     $                         LDVT, WORK( IR ), LDWRKR, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need N*N+N, prefer N*N+M*N)
+*                 (RWorkspace: 0)
+*
+                  DO 20 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL CGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL CLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   20             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (CWorkspace: need 2*N, prefer N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need 2*N, prefer N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT
+*                 (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                 (RWorkspace: N)
+*
+                  CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply Q in A by left vectors bidiagonalizing R
+*                 (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A and computing right
+*                 singular vectors of A in VT
+*                 (CWorkspace: 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
+     $                         LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
+     $                         INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUS ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*                 N left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left vectors bidiagonalizing R in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM,
+     $                            1, WORK( IR ), LDWRKR, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IR), storing result in U
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
+     $                           WORK( IR ), LDWRKR, CZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM,
+     $                            1, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+3*N ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (CWorkspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N,
+*                                 prefer 2*N*N+2*N+2*N*NB)
+*                    (RWorkspace: need   N)
+*
+                     CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N-1,
+*                                 prefer 2*N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (CWorkspace: need 2*N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, CZERO, U, LDU )
+*
+*                    Copy right singular vectors of R to A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing R in A
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), A,
+     $                            LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S'
+*                         or 'A')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need   N*N+3*N-1,
+*                                 prefer N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, CZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to VT, zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTUA ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*                 M left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 3*N ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N*N+N+M, prefer N*N+N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM,
+     $                            1, WORK( IR ), LDWRKR, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IR), storing result in A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
+     $                           WORK( IR ), LDWRKR, CZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N+M, prefer N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM,
+     $                            1, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+MAX( N+M, 3*N ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N,
+*                                 prefer 2*N*N+2*N+2*N*NB)
+*                    (RWorkspace: need   N)
+*
+                     CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N-1,
+*                                 prefer 2*N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (CWorkspace: need 2*N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, CZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+*                    Copy right singular vectors of R from WORK(IR) to A
+*
+                     CALL CLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N+M, prefer N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in A
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), A,
+     $                            LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S'
+*                         or 'A')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 3*N ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N*N+N+M, prefer N*N+N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need   N*N+3*N-1,
+*                                 prefer N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: need   0)
+*
+                     CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, CZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N+M, prefer N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R from A to VT, zeroing out below it
+*
+                     CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           M .LT. MNTHR
+*
+*           Path 10 (M at least N, but not much larger)
+*           Reduce to bidiagonal form without QR decomposition
+*
+            IE = 1
+            ITAUQ = 1
+            ITAUP = ITAUQ + N
+            IWORK = ITAUP + N
+*
+*           Bidiagonalize A
+*           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
+*           (RWorkspace: need N)
+*
+            CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (CWorkspace: need 2*N+NCU, prefer 2*N+NCU*NB)
+*              (RWorkspace: 0)
+*
+               CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
+               IF( WNTUS )
+     $            NCU = N
+               IF( WNTUA )
+     $            NCU = M
+               CALL CUNGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
+               CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
+*              (RWorkspace: 0)
+*
+               CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IRWORK = IE + N
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), A,
+     $                      LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            END IF
+*
+         END IF
+*
+      ELSE
+*
+*        A has more columns than rows. If A has sufficiently more
+*        columns than rows, first reduce using the LQ decomposition (if
+*        sufficient workspace available)
+*
+         IF( N.GE.MNTHR ) THEN
+*
+            IF( WNTVN ) THEN
+*
+*              Path 1t(N much larger than M, JOBVT='N')
+*              No right singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + M
+*
+*              Compute A=L*Q
+*              (CWorkspace: need 2*M, prefer M+M*NB)
+*              (RWorkspace: 0)
+*
+               CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out above L
+*
+               CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
+     $                      LDA )
+               IE = 1
+               ITAUQ = 1
+               ITAUP = ITAUQ + M
+               IWORK = ITAUP + M
+*
+*              Bidiagonalize L in A
+*              (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*              (RWorkspace: need M)
+*
+               CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               IF( WNTUO .OR. WNTUAS ) THEN
+*
+*                 If left singular vectors desired, generate Q
+*                 (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+               END IF
+               IRWORK = IE + M
+               NRU = 0
+               IF( WNTUO .OR. WNTUAS )
+     $            NRU = M
+*
+*              Perform bidiagonal QR iteration, computing left singular
+*              vectors of A in A if desired
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'U', M, 0, NRU, 0, S, RWORK( IE ), CDUM, 1,
+     $                      A, LDA, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+*              If left singular vectors desired in U, copy them there
+*
+               IF( WNTUAS )
+     $            CALL CLACPY( 'F', M, M, A, LDA, U, LDU )
+*
+            ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*              Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              no left singular vectors to be computed
+*
+               IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to WORK(IR) and zero out above it
+*
+                  CALL CLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
+                  CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                         WORK( IR+LDWRKR ), LDWRKR )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in WORK(IR)
+*                 (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL CGEBRD( M, M, WORK( IR ), LDWRKR, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing L
+*                 (CWorkspace: need M*M+3*M-1, prefer M*M+2*M+(M-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of L in WORK(IR)
+*                 (CWorkspace: need M*M)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
+     $                         WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need M*M+M, prefer M*M+M*N)
+*                 (RWorkspace: 0)
+*
+                  DO 30 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL CGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL CLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   30             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = 1
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize A
+*                 (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing A
+*                 (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of A in A
+*                 (CWorkspace: 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'L', M, N, 0, 0, S, RWORK( IE ), A, LDA,
+     $                         CDUM, 1, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*              Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              M left singular vectors to be computed in U
+*
+               IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing about above it
+*
+                  CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U, copying result to WORK(IR)
+*                 (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL CLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
+*
+*                 Generate right vectors bidiagonalizing L in WORK(IR)
+*                 (CWorkspace: need M*M+3*M-1, prefer M*M+2*M+(M-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of L in U, and computing right
+*                 singular vectors of L in WORK(IR)
+*                 (CWorkspace: need M*M)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                         WORK( IR ), LDWRKR, U, LDU, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need M*M+M, prefer M*M+M*N))
+*                 (RWorkspace: 0)
+*
+                  DO 40 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL CGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL CLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   40             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (CWorkspace: need 2*M, prefer M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing out above it
+*
+                  CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need 2*M, prefer M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U
+*                 (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply right vectors bidiagonalizing L by Q in A
+*                 (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
+     $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in U and computing right
+*                 singular vectors of A in A
+*                 (CWorkspace: 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), A, LDA,
+     $                         U, LDU, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVS ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing L in
+*                    WORK(IR)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in A, storing result in VT
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IR ),
+     $                           LDWRKR, A, LDA, CZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy result to VT
+*
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, N, 0, 0, S, RWORK( IE ), VT,
+     $                            LDVT, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+3*M ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out below it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*M*M+3*M,
+*                                 prefer 2*M*M+2*M+2*M*NB)
+*                    (RWorkspace: need   M)
+*
+                     CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need   2*M*M+3*M-1,
+*                                 prefer 2*M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (CWorkspace: need 2*M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, CZERO, VT, LDVT )
+*
+*                    Copy left singular vectors of L to A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors of L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in A and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, A, LDA, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need   M*M+3*M-1,
+*                                 prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, CZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            U( 1, 2 ), LDU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTVA ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 3*M ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M*M+M+N, prefer M*M+M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need   M*M+3*M-1,
+*                                 prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in VT, storing result in A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IR ),
+     $                           LDWRKR, VT, LDVT, CZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M+N, prefer M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, N, 0, 0, S, RWORK( IE ), VT,
+     $                            LDVT, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+MAX( N+M, 3*M ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*M*M+3*M,
+*                                 prefer 2*M*M+2*M+2*M*NB)
+*                    (RWorkspace: need   M)
+*
+                     CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need   2*M*M+3*M-1,
+*                                 prefer 2*M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (CWorkspace: need 2*M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, CZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy left singular vectors of A from WORK(IR) to A
+*
+                     CALL CLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M+N, prefer M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in A
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in A and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, A, LDA, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 3*M ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is M by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M*M+M+N, prefer M*M+M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, CZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M+N, prefer M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            U( 1, 2 ), LDU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           N .LT. MNTHR
+*
+*           Path 10t(N greater than M, but not much larger)
+*           Reduce to bidiagonal form without LQ decomposition
+*
+            IE = 1
+            ITAUQ = 1
+            ITAUP = ITAUQ + M
+            IWORK = ITAUP + M
+*
+*           Bidiagonalize A
+*           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
+*           (RWorkspace: M)
+*
+            CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (CWorkspace: need 3*M-1, prefer 2*M+(M-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
+               CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (CWorkspace: need 2*M+NRVT, prefer 2*M+NRVT*NB)
+*              (RWorkspace: 0)
+*
+               CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
+               IF( WNTVA )
+     $            NRVT = N
+               IF( WNTVS )
+     $            NRVT = M
+               CALL CUNGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*M-1, prefer 2*M+(M-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL CUNGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*              (RWorkspace: 0)
+*
+               CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IRWORK = IE + M
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), A,
+     $                      LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL CBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            END IF
+*
+         END IF
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ISCL.EQ.1 ) THEN
+         IF( ANRM.GT.BIGNUM )
+     $      CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
+     $      CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
+     $                   RWORK( IE ), MINMN, IERR )
+         IF( ANRM.LT.SMLNUM )
+     $      CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
+     $      CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
+     $                   RWORK( IE ), MINMN, IERR )
+      END IF
+*
+*     Return optimal workspace in WORK(1)
+*
+      WORK( 1 ) = MAXWRK
+*
+      RETURN
+*
+*     End of CGESVD
+*
+      END
diff --git a/libcruft/lapack/cgetf2.f b/libcruft/lapack/cgetf2.f
new file mode 100644
index 0000000..48b0d79
--- /dev/null
+++ b/libcruft/lapack/cgetf2.f
@@ -0,0 +1,148 @@
+      SUBROUTINE CGETF2( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGETF2 computes an LU factorization of a general m-by-n matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the m by n matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, U(k,k) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      REAL               SFMIN
+      INTEGER            I, J, JP
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      INTEGER            ICAMAX
+      EXTERNAL           SLAMCH, ICAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGERU, CSCAL, CSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGETF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Compute machine safe minimum
+*
+      SFMIN = SLAMCH('S') 
+*
+      DO 10 J = 1, MIN( M, N )
+*
+*        Find pivot and test for singularity.
+*
+         JP = J - 1 + ICAMAX( M-J+1, A( J, J ), 1 )
+         IPIV( J ) = JP
+         IF( A( JP, J ).NE.ZERO ) THEN
+*
+*           Apply the interchange to columns 1:N.
+*
+            IF( JP.NE.J )
+     $         CALL CSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA )
+*
+*           Compute elements J+1:M of J-th column.
+*
+            IF( J.LT.M ) THEN
+               IF( ABS(A( J, J )) .GE. SFMIN ) THEN
+                  CALL CSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 )
+               ELSE
+                  DO 20 I = 1, M-J
+                     A( J+I, J ) = A( J+I, J ) / A( J, J )
+   20             CONTINUE
+               END IF
+            END IF
+*
+         ELSE IF( INFO.EQ.0 ) THEN
+*
+            INFO = J
+         END IF
+*
+         IF( J.LT.MIN( M, N ) ) THEN
+*
+*           Update trailing submatrix.
+*
+            CALL CGERU( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ),
+     $                  LDA, A( J+1, J+1 ), LDA )
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of CGETF2
+*
+      END
diff --git a/libcruft/lapack/cgetrf.f b/libcruft/lapack/cgetrf.f
new file mode 100644
index 0000000..9c6fd5a
--- /dev/null
+++ b/libcruft/lapack/cgetrf.f
@@ -0,0 +1,159 @@
+      SUBROUTINE CGETRF( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGETRF computes an LU factorization of a general M-by-N matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IINFO, J, JB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CGETF2, CLASWP, CTRSM, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGETRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'CGETRF', ' ', M, N, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN
+*
+*        Use unblocked code.
+*
+         CALL CGETF2( M, N, A, LDA, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         DO 20 J = 1, MIN( M, N ), NB
+            JB = MIN( MIN( M, N )-J+1, NB )
+*
+*           Factor diagonal and subdiagonal blocks and test for exact
+*           singularity.
+*
+            CALL CGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+*
+*           Adjust INFO and the pivot indices.
+*
+            IF( INFO.EQ.0 .AND. IINFO.GT.0 )
+     $         INFO = IINFO + J - 1
+            DO 10 I = J, MIN( M, J+JB-1 )
+               IPIV( I ) = J - 1 + IPIV( I )
+   10       CONTINUE
+*
+*           Apply interchanges to columns 1:J-1.
+*
+            CALL CLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 )
+*
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply interchanges to columns J+JB:N.
+*
+               CALL CLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1,
+     $                      IPIV, 1 )
+*
+*              Compute block row of U.
+*
+               CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB,
+     $                     N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ),
+     $                     LDA )
+               IF( J+JB.LE.M ) THEN
+*
+*                 Update trailing submatrix.
+*
+                  CALL CGEMM( 'No transpose', 'No transpose', M-J-JB+1,
+     $                        N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA,
+     $                        A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ),
+     $                        LDA )
+               END IF
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CGETRF
+*
+      END
diff --git a/libcruft/lapack/cgetri.f b/libcruft/lapack/cgetri.f
new file mode 100644
index 0000000..86b3ad3
--- /dev/null
+++ b/libcruft/lapack/cgetri.f
@@ -0,0 +1,193 @@
+      SUBROUTINE CGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGETRI computes the inverse of a matrix using the LU factorization
+*  computed by CGETRF.
+*
+*  This method inverts U and then computes inv(A) by solving the system
+*  inv(A)*L = inv(U) for inv(A).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the factors L and U from the factorization
+*          A = P*L*U as computed by CGETRF.
+*          On exit, if INFO = 0, the inverse of the original matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from CGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, then WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimal performance LWORK >= N*NB, where NB is
+*          the optimal blocksize returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero; the matrix is
+*                singular and its inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CGEMV, CSWAP, CTRSM, CTRTRI, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NB = ILAENV( 1, 'CGETRI', ' ', N, -1, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -3
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGETRI', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form inv(U).  If INFO > 0 from CTRTRI, then U is singular,
+*     and the inverse is not computed.
+*
+      CALL CTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+      NBMIN = 2
+      LDWORK = N
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+         IWS = MAX( LDWORK*NB, 1 )
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'CGETRI', ' ', N, -1, -1, -1 ) )
+         END IF
+      ELSE
+         IWS = N
+      END IF
+*
+*     Solve the equation inv(A)*L = inv(U) for inv(A).
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         DO 20 J = N, 1, -1
+*
+*           Copy current column of L to WORK and replace with zeros.
+*
+            DO 10 I = J + 1, N
+               WORK( I ) = A( I, J )
+               A( I, J ) = ZERO
+   10       CONTINUE
+*
+*           Compute current column of inv(A).
+*
+            IF( J.LT.N )
+     $         CALL CGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),
+     $                     LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )
+   20    CONTINUE
+      ELSE
+*
+*        Use blocked code.
+*
+         NN = ( ( N-1 ) / NB )*NB + 1
+         DO 50 J = NN, 1, -NB
+            JB = MIN( NB, N-J+1 )
+*
+*           Copy current block column of L to WORK and replace with
+*           zeros.
+*
+            DO 40 JJ = J, J + JB - 1
+               DO 30 I = JJ + 1, N
+                  WORK( I+( JJ-J )*LDWORK ) = A( I, JJ )
+                  A( I, JJ ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+*
+*           Compute current block column of inv(A).
+*
+            IF( J+JB.LE.N )
+     $         CALL CGEMM( 'No transpose', 'No transpose', N, JB,
+     $                     N-J-JB+1, -ONE, A( 1, J+JB ), LDA,
+     $                     WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )
+            CALL CTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,
+     $                  ONE, WORK( J ), LDWORK, A( 1, J ), LDA )
+   50    CONTINUE
+      END IF
+*
+*     Apply column interchanges.
+*
+      DO 60 J = N - 1, 1, -1
+         JP = IPIV( J )
+         IF( JP.NE.J )
+     $      CALL CSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
+   60 CONTINUE
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CGETRI
+*
+      END
diff --git a/libcruft/lapack/cgetrs.f b/libcruft/lapack/cgetrs.f
new file mode 100644
index 0000000..0b58ad7
--- /dev/null
+++ b/libcruft/lapack/cgetrs.f
@@ -0,0 +1,149 @@
+      SUBROUTINE CGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGETRS solves a system of linear equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B
+*  with a general N-by-N matrix A using the LU factorization computed
+*  by CGETRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by CGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from CGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASWP, CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGETRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve A * X = B.
+*
+*        Apply row interchanges to the right hand sides.
+*
+         CALL CLASWP( NRHS, B, LDB, 1, N, IPIV, 1 )
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A**T * X = B  or A**H * X = B.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Upper', TRANS, 'Non-unit', N, NRHS, ONE,
+     $               A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Lower', TRANS, 'Unit', N, NRHS, ONE, A,
+     $               LDA, B, LDB )
+*
+*        Apply row interchanges to the solution vectors.
+*
+         CALL CLASWP( NRHS, B, LDB, 1, N, IPIV, -1 )
+      END IF
+*
+      RETURN
+*
+*     End of CGETRS
+*
+      END
diff --git a/libcruft/lapack/cggbak.f b/libcruft/lapack/cggbak.f
new file mode 100644
index 0000000..c0f6a8b
--- /dev/null
+++ b/libcruft/lapack/cggbak.f
@@ -0,0 +1,220 @@
+      SUBROUTINE CGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,
+     $                   LDV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               LSCALE( * ), RSCALE( * )
+      COMPLEX            V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGGBAK forms the right or left eigenvectors of a complex generalized
+*  eigenvalue problem A*x = lambda*B*x, by backward transformation on
+*  the computed eigenvectors of the balanced pair of matrices output by
+*  CGGBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N':  do nothing, return immediately;
+*          = 'P':  do backward transformation for permutation only;
+*          = 'S':  do backward transformation for scaling only;
+*          = 'B':  do backward transformations for both permutation and
+*                  scaling.
+*          JOB must be the same as the argument JOB supplied to CGGBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by CGGBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  LSCALE  (input) REAL array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the left side of A and B, as returned by CGGBAL.
+*
+*  RSCALE  (input) REAL array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the right side of A and B, as returned by CGGBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) COMPLEX array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by CTGEVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the matrix V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. Ward, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, K
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL, CSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( N.EQ.0 .AND. IHI.EQ.0 .AND. ILO.NE.1 ) THEN
+         INFO = -4
+      ELSE IF( N.GT.0 .AND. ( IHI.LT.ILO .OR. IHI.GT.MAX( 1, N ) ) )
+     $   THEN
+         INFO = -5
+      ELSE IF( N.EQ.0 .AND. ILO.EQ.1 .AND. IHI.NE.0 ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -8
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGGBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward transformation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               CALL CSSCAL( M, RSCALE( I ), V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+*        Backward transformation on left eigenvectors
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               CALL CSSCAL( M, LSCALE( I ), V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Backward permutation
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward permutation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 50
+            DO 40 I = ILO - 1, 1, -1
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL CSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+*
+   50       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 70
+            DO 60 I = IHI + 1, N
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 60
+               CALL CSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   60       CONTINUE
+         END IF
+*
+*        Backward permutation on left eigenvectors
+*
+   70    CONTINUE
+         IF( LEFTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 90
+            DO 80 I = ILO - 1, 1, -1
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 80
+               CALL CSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   80       CONTINUE
+*
+   90       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 110
+            DO 100 I = IHI + 1, N
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 100
+               CALL CSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+  100       CONTINUE
+         END IF
+      END IF
+*
+  110 CONTINUE
+*
+      RETURN
+*
+*     End of CGGBAK
+*
+      END
diff --git a/libcruft/lapack/cggbal.f b/libcruft/lapack/cggbal.f
new file mode 100644
index 0000000..42007d3
--- /dev/null
+++ b/libcruft/lapack/cggbal.f
@@ -0,0 +1,482 @@
+      SUBROUTINE CGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
+     $                   RSCALE, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      REAL               LSCALE( * ), RSCALE( * ), WORK( * )
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGGBAL balances a pair of general complex matrices (A,B).  This
+*  involves, first, permuting A and B by similarity transformations to
+*  isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
+*  elements on the diagonal; and second, applying a diagonal similarity
+*  transformation to rows and columns ILO to IHI to make the rows
+*  and columns as close in norm as possible. Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrices, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors in the
+*  generalized eigenvalue problem A*x = lambda*B*x.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A and B:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
+*                  and RSCALE(I) = 1.0 for i=1,...,N;
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit, A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,N)
+*          On entry, the input matrix B.
+*          On exit, B is overwritten by the balanced matrix.
+*          If JOB = 'N', B is not referenced.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 and B(i,j) = 0 if i > j and
+*          j = 1,...,ILO-1 or i = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  LSCALE  (output) REAL array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the left side of A and B.  If P(j) is the index of the
+*          row interchanged with row j, and D(j) is the scaling factor
+*          applied to row j, then
+*            LSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  RSCALE  (output) REAL array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the right side of A and B.  If P(j) is the index of the
+*          column interchanged with column j, and D(j) is the scaling
+*          factor applied to column j, then
+*            RSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  WORK    (workspace) REAL array, dimension (lwork)
+*          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
+*          at least 1 when JOB = 'N' or 'P'.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. WARD, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
+      REAL               THREE, SCLFAC
+      PARAMETER          ( THREE = 3.0E+0, SCLFAC = 1.0E+1 )
+      COMPLEX            CZERO
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
+     $                   K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
+     $                   M, NR, NRP2
+      REAL               ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
+     $                   COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
+     $                   SFMIN, SUM, T, TA, TB, TC
+      COMPLEX            CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SDOT, SLAMCH
+      EXTERNAL           LSAME, ICAMAX, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL, CSWAP, SAXPY, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, INT, LOG10, MAX, MIN, REAL, SIGN
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGGBAL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         ILO = 1
+         IHI = N
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         ILO = 1
+         IHI = N
+         LSCALE( 1 ) = ONE
+         RSCALE( 1 ) = ONE
+         RETURN
+      END IF
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         ILO = 1
+         IHI = N
+         DO 10 I = 1, N
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 190
+*
+      GO TO 30
+*
+*     Permute the matrices A and B to isolate the eigenvalues.
+*
+*     Find row with one nonzero in columns 1 through L
+*
+   20 CONTINUE
+      L = LM1
+      IF( L.NE.1 )
+     $   GO TO 30
+*
+      RSCALE( 1 ) = ONE
+      LSCALE( 1 ) = ONE
+      GO TO 190
+*
+   30 CONTINUE
+      LM1 = L - 1
+      DO 80 I = L, 1, -1
+         DO 40 J = 1, LM1
+            JP1 = J + 1
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 50
+   40    CONTINUE
+         J = L
+         GO TO 70
+*
+   50    CONTINUE
+         DO 60 J = JP1, L
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 80
+   60    CONTINUE
+         J = JP1 - 1
+*
+   70    CONTINUE
+         M = L
+         IFLOW = 1
+         GO TO 160
+   80 CONTINUE
+      GO TO 100
+*
+*     Find column with one nonzero in rows K through N
+*
+   90 CONTINUE
+      K = K + 1
+*
+  100 CONTINUE
+      DO 150 J = K, L
+         DO 110 I = K, LM1
+            IP1 = I + 1
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 120
+  110    CONTINUE
+         I = L
+         GO TO 140
+  120    CONTINUE
+         DO 130 I = IP1, L
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 150
+  130    CONTINUE
+         I = IP1 - 1
+  140    CONTINUE
+         M = K
+         IFLOW = 2
+         GO TO 160
+  150 CONTINUE
+      GO TO 190
+*
+*     Permute rows M and I
+*
+  160 CONTINUE
+      LSCALE( M ) = I
+      IF( I.EQ.M )
+     $   GO TO 170
+      CALL CSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
+      CALL CSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
+*
+*     Permute columns M and J
+*
+  170 CONTINUE
+      RSCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 180
+      CALL CSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL CSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
+*
+  180 CONTINUE
+      GO TO ( 20, 90 )IFLOW
+*
+  190 CONTINUE
+      ILO = K
+      IHI = L
+*
+      IF( LSAME( JOB, 'P' ) ) THEN
+         DO 195 I = ILO, IHI
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+  195    CONTINUE
+         RETURN
+      END IF
+*
+      IF( ILO.EQ.IHI )
+     $   RETURN
+*
+*     Balance the submatrix in rows ILO to IHI.
+*
+      NR = IHI - ILO + 1
+      DO 200 I = ILO, IHI
+         RSCALE( I ) = ZERO
+         LSCALE( I ) = ZERO
+*
+         WORK( I ) = ZERO
+         WORK( I+N ) = ZERO
+         WORK( I+2*N ) = ZERO
+         WORK( I+3*N ) = ZERO
+         WORK( I+4*N ) = ZERO
+         WORK( I+5*N ) = ZERO
+  200 CONTINUE
+*
+*     Compute right side vector in resulting linear equations
+*
+      BASL = LOG10( SCLFAC )
+      DO 240 I = ILO, IHI
+         DO 230 J = ILO, IHI
+            IF( A( I, J ).EQ.CZERO ) THEN
+               TA = ZERO
+               GO TO 210
+            END IF
+            TA = LOG10( CABS1( A( I, J ) ) ) / BASL
+*
+  210       CONTINUE
+            IF( B( I, J ).EQ.CZERO ) THEN
+               TB = ZERO
+               GO TO 220
+            END IF
+            TB = LOG10( CABS1( B( I, J ) ) ) / BASL
+*
+  220       CONTINUE
+            WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
+            WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
+  230    CONTINUE
+  240 CONTINUE
+*
+      COEF = ONE / REAL( 2*NR )
+      COEF2 = COEF*COEF
+      COEF5 = HALF*COEF2
+      NRP2 = NR + 2
+      BETA = ZERO
+      IT = 1
+*
+*     Start generalized conjugate gradient iteration
+*
+  250 CONTINUE
+*
+      GAMMA = SDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
+     $        SDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      EW = ZERO
+      EWC = ZERO
+      DO 260 I = ILO, IHI
+         EW = EW + WORK( I+4*N )
+         EWC = EWC + WORK( I+5*N )
+  260 CONTINUE
+*
+      GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
+      IF( GAMMA.EQ.ZERO )
+     $   GO TO 350
+      IF( IT.NE.1 )
+     $   BETA = GAMMA / PGAMMA
+      T = COEF5*( EWC-THREE*EW )
+      TC = COEF5*( EW-THREE*EWC )
+*
+      CALL SSCAL( NR, BETA, WORK( ILO ), 1 )
+      CALL SSCAL( NR, BETA, WORK( ILO+N ), 1 )
+*
+      CALL SAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
+      CALL SAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
+*
+      DO 270 I = ILO, IHI
+         WORK( I ) = WORK( I ) + TC
+         WORK( I+N ) = WORK( I+N ) + T
+  270 CONTINUE
+*
+*     Apply matrix to vector
+*
+      DO 300 I = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 290 J = ILO, IHI
+            IF( A( I, J ).EQ.CZERO )
+     $         GO TO 280
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  280       CONTINUE
+            IF( B( I, J ).EQ.CZERO )
+     $         GO TO 290
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  290    CONTINUE
+         WORK( I+2*N ) = REAL( KOUNT )*WORK( I+N ) + SUM
+  300 CONTINUE
+*
+      DO 330 J = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 320 I = ILO, IHI
+            IF( A( I, J ).EQ.CZERO )
+     $         GO TO 310
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  310       CONTINUE
+            IF( B( I, J ).EQ.CZERO )
+     $         GO TO 320
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  320    CONTINUE
+         WORK( J+3*N ) = REAL( KOUNT )*WORK( J ) + SUM
+  330 CONTINUE
+*
+      SUM = SDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
+     $      SDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
+      ALPHA = GAMMA / SUM
+*
+*     Determine correction to current iteration
+*
+      CMAX = ZERO
+      DO 340 I = ILO, IHI
+         COR = ALPHA*WORK( I+N )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         LSCALE( I ) = LSCALE( I ) + COR
+         COR = ALPHA*WORK( I )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         RSCALE( I ) = RSCALE( I ) + COR
+  340 CONTINUE
+      IF( CMAX.LT.HALF )
+     $   GO TO 350
+*
+      CALL SAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
+      CALL SAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      PGAMMA = GAMMA
+      IT = IT + 1
+      IF( IT.LE.NRP2 )
+     $   GO TO 250
+*
+*     End generalized conjugate gradient iteration
+*
+  350 CONTINUE
+      SFMIN = SLAMCH( 'S' )
+      SFMAX = ONE / SFMIN
+      LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
+      LSFMAX = INT( LOG10( SFMAX ) / BASL )
+      DO 360 I = ILO, IHI
+         IRAB = ICAMAX( N-ILO+1, A( I, ILO ), LDA )
+         RAB = ABS( A( I, IRAB+ILO-1 ) )
+         IRAB = ICAMAX( N-ILO+1, B( I, ILO ), LDB )
+         RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
+         LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
+         IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
+         IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
+         LSCALE( I ) = SCLFAC**IR
+         ICAB = ICAMAX( IHI, A( 1, I ), 1 )
+         CAB = ABS( A( ICAB, I ) )
+         ICAB = ICAMAX( IHI, B( 1, I ), 1 )
+         CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
+         LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
+         JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
+         JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
+         RSCALE( I ) = SCLFAC**JC
+  360 CONTINUE
+*
+*     Row scaling of matrices A and B
+*
+      DO 370 I = ILO, IHI
+         CALL CSSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
+         CALL CSSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
+  370 CONTINUE
+*
+*     Column scaling of matrices A and B
+*
+      DO 380 J = ILO, IHI
+         CALL CSSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
+         CALL CSSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
+  380 CONTINUE
+*
+      RETURN
+*
+*     End of CGGBAL
+*
+      END
diff --git a/libcruft/lapack/cggev.f b/libcruft/lapack/cggev.f
new file mode 100644
index 0000000..e6403e8
--- /dev/null
+++ b/libcruft/lapack/cggev.f
@@ -0,0 +1,454 @@
+      SUBROUTINE CGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
+     $                  VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), ALPHA( * ), B( LDB, * ),
+     $                   BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGGEV computes for a pair of N-by-N complex nonsymmetric matrices
+*  (A,B), the generalized eigenvalues, and optionally, the left and/or
+*  right generalized eigenvectors.
+*
+*  A generalized eigenvalue for a pair of matrices (A,B) is a scalar
+*  lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
+*  singular. It is usually represented as the pair (alpha,beta), as
+*  there is a reasonable interpretation for beta=0, and even for both
+*  being zero.
+*
+*  The right generalized eigenvector v(j) corresponding to the
+*  generalized eigenvalue lambda(j) of (A,B) satisfies
+*
+*               A * v(j) = lambda(j) * B * v(j).
+*
+*  The left generalized eigenvector u(j) corresponding to the
+*  generalized eigenvalues lambda(j) of (A,B) satisfies
+*
+*               u(j)**H * A = lambda(j) * u(j)**H * B
+*
+*  where u(j)**H is the conjugate-transpose of u(j).
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N':  do not compute the left generalized eigenvectors;
+*          = 'V':  compute the left generalized eigenvectors.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N':  do not compute the right generalized eigenvectors;
+*          = 'V':  compute the right generalized eigenvectors.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A, B, VL, and VR.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA, N)
+*          On entry, the matrix A in the pair (A,B).
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB, N)
+*          On entry, the matrix B in the pair (A,B).
+*          On exit, B has been overwritten.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of B.  LDB >= max(1,N).
+*
+*  ALPHA   (output) COMPLEX array, dimension (N)
+*  BETA    (output) COMPLEX array, dimension (N)
+*          On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the
+*          generalized eigenvalues.
+*
+*          Note: the quotients ALPHA(j)/BETA(j) may easily over- or
+*          underflow, and BETA(j) may even be zero.  Thus, the user
+*          should avoid naively computing the ratio alpha/beta.
+*          However, ALPHA will be always less than and usually
+*          comparable with norm(A) in magnitude, and BETA always less
+*          than and usually comparable with norm(B).
+*
+*  VL      (output) COMPLEX array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left generalized eigenvectors u(j) are
+*          stored one after another in the columns of VL, in the same
+*          order as their eigenvalues.
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part) + abs(imag. part) = 1.
+*          Not referenced if JOBVL = 'N'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the matrix VL. LDVL >= 1, and
+*          if JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) COMPLEX array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right generalized eigenvectors v(j) are
+*          stored one after another in the columns of VR, in the same
+*          order as their eigenvalues.
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part) + abs(imag. part) = 1.
+*          Not referenced if JOBVR = 'N'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the matrix VR. LDVR >= 1, and
+*          if JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,2*N).
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace/output) REAL array, dimension (8*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          =1,...,N:
+*                The QZ iteration failed.  No eigenvectors have been
+*                calculated, but ALPHA(j) and BETA(j) should be
+*                correct for j=INFO+1,...,N.
+*          > N:  =N+1: other then QZ iteration failed in SHGEQZ,
+*                =N+2: error return from STGEVC.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E0, 0.0E0 ),
+     $                   CONE = ( 1.0E0, 0.0E0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
+      CHARACTER          CHTEMP
+      INTEGER            ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
+     $                   IN, IRIGHT, IROWS, IRWRK, ITAU, IWRK, JC, JR,
+     $                   LWKMIN, LWKOPT
+      REAL               ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
+     $                   SMLNUM, TEMP
+      COMPLEX            X
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            LDUMMA( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEQRF, CGGBAK, CGGBAL, CGGHRD, CHGEQZ, CLACPY,
+     $                   CLASCL, CLASET, CTGEVC, CUNGQR, CUNMQR, SLABAD,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               CLANGE, SLAMCH
+      EXTERNAL           LSAME, ILAENV, CLANGE, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MAX, REAL, SQRT
+*     ..
+*     .. Statement Functions ..
+      REAL               ABS1
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode the input arguments
+*
+      IF( LSAME( JOBVL, 'N' ) ) THEN
+         IJOBVL = 1
+         ILVL = .FALSE.
+      ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
+         IJOBVL = 2
+         ILVL = .TRUE.
+      ELSE
+         IJOBVL = -1
+         ILVL = .FALSE.
+      END IF
+*
+      IF( LSAME( JOBVR, 'N' ) ) THEN
+         IJOBVR = 1
+         ILVR = .FALSE.
+      ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
+         IJOBVR = 2
+         ILVR = .TRUE.
+      ELSE
+         IJOBVR = -1
+         ILVR = .FALSE.
+      END IF
+      ILV = ILVL .OR. ILVR
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( IJOBVL.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( IJOBVR.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -11
+      ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -13
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV. The workspace is
+*       computed assuming ILO = 1 and IHI = N, the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         LWKMIN = MAX( 1, 2*N )
+         LWKOPT = MAX( 1, N + N*ILAENV( 1, 'CGEQRF', ' ', N, 1, N, 0 ) )
+         LWKOPT = MAX( LWKOPT, N +
+     $                 N*ILAENV( 1, 'CUNMQR', ' ', N, 1, N, 0 ) ) 
+         IF( ILVL ) THEN
+            LWKOPT = MAX( LWKOPT, N +
+     $                 N*ILAENV( 1, 'CUNGQR', ' ', N, 1, N, -1 ) )
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY )
+     $      INFO = -15
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGGEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'E' )*SLAMCH( 'B' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = CLANGE( 'M', N, N, A, LDA, RWORK )
+      ILASCL = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ANRMTO = SMLNUM
+         ILASCL = .TRUE.
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ANRMTO = BIGNUM
+         ILASCL = .TRUE.
+      END IF
+      IF( ILASCL )
+     $   CALL CLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = CLANGE( 'M', N, N, B, LDB, RWORK )
+      ILBSCL = .FALSE.
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+         BNRMTO = SMLNUM
+         ILBSCL = .TRUE.
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+         BNRMTO = BIGNUM
+         ILBSCL = .TRUE.
+      END IF
+      IF( ILBSCL )
+     $   CALL CLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
+*
+*     Permute the matrices A, B to isolate eigenvalues if possible
+*     (Real Workspace: need 6*N)
+*
+      ILEFT = 1
+      IRIGHT = N + 1
+      IRWRK = IRIGHT + N
+      CALL CGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
+     $             RWORK( IRIGHT ), RWORK( IRWRK ), IERR )
+*
+*     Reduce B to triangular form (QR decomposition of B)
+*     (Complex Workspace: need N, prefer N*NB)
+*
+      IROWS = IHI + 1 - ILO
+      IF( ILV ) THEN
+         ICOLS = N + 1 - ILO
+      ELSE
+         ICOLS = IROWS
+      END IF
+      ITAU = 1
+      IWRK = ITAU + IROWS
+      CALL CGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
+     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
+*
+*     Apply the orthogonal transformation to matrix A
+*     (Complex Workspace: need N, prefer N*NB)
+*
+      CALL CUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
+     $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
+     $             LWORK+1-IWRK, IERR )
+*
+*     Initialize VL
+*     (Complex Workspace: need N, prefer N*NB)
+*
+      IF( ILVL ) THEN
+         CALL CLASET( 'Full', N, N, CZERO, CONE, VL, LDVL )
+         IF( IROWS.GT.1 ) THEN
+            CALL CLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
+     $                   VL( ILO+1, ILO ), LDVL )
+         END IF
+         CALL CUNGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
+     $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
+      END IF
+*
+*     Initialize VR
+*
+      IF( ILVR )
+     $   CALL CLASET( 'Full', N, N, CZERO, CONE, VR, LDVR )
+*
+*     Reduce to generalized Hessenberg form
+*
+      IF( ILV ) THEN
+*
+*        Eigenvectors requested -- work on whole matrix.
+*
+         CALL CGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
+     $                LDVL, VR, LDVR, IERR )
+      ELSE
+         CALL CGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
+     $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
+      END IF
+*
+*     Perform QZ algorithm (Compute eigenvalues, and optionally, the
+*     Schur form and Schur vectors)
+*     (Complex Workspace: need N)
+*     (Real Workspace: need N)
+*
+      IWRK = ITAU
+      IF( ILV ) THEN
+         CHTEMP = 'S'
+      ELSE
+         CHTEMP = 'E'
+      END IF
+      CALL CHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
+     $             ALPHA, BETA, VL, LDVL, VR, LDVR, WORK( IWRK ),
+     $             LWORK+1-IWRK, RWORK( IRWRK ), IERR )
+      IF( IERR.NE.0 ) THEN
+         IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
+            INFO = IERR
+         ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
+            INFO = IERR - N
+         ELSE
+            INFO = N + 1
+         END IF
+         GO TO 70
+      END IF
+*
+*     Compute Eigenvectors
+*     (Real Workspace: need 2*N)
+*     (Complex Workspace: need 2*N)
+*
+      IF( ILV ) THEN
+         IF( ILVL ) THEN
+            IF( ILVR ) THEN
+               CHTEMP = 'B'
+            ELSE
+               CHTEMP = 'L'
+            END IF
+         ELSE
+            CHTEMP = 'R'
+         END IF
+*
+         CALL CTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
+     $                VR, LDVR, N, IN, WORK( IWRK ), RWORK( IRWRK ),
+     $                IERR )
+         IF( IERR.NE.0 ) THEN
+            INFO = N + 2
+            GO TO 70
+         END IF
+*
+*        Undo balancing on VL and VR and normalization
+*        (Workspace: none needed)
+*
+         IF( ILVL ) THEN
+            CALL CGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
+     $                   RWORK( IRIGHT ), N, VL, LDVL, IERR )
+            DO 30 JC = 1, N
+               TEMP = ZERO
+               DO 10 JR = 1, N
+                  TEMP = MAX( TEMP, ABS1( VL( JR, JC ) ) )
+   10          CONTINUE
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 30
+               TEMP = ONE / TEMP
+               DO 20 JR = 1, N
+                  VL( JR, JC ) = VL( JR, JC )*TEMP
+   20          CONTINUE
+   30       CONTINUE
+         END IF
+         IF( ILVR ) THEN
+            CALL CGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
+     $                   RWORK( IRIGHT ), N, VR, LDVR, IERR )
+            DO 60 JC = 1, N
+               TEMP = ZERO
+               DO 40 JR = 1, N
+                  TEMP = MAX( TEMP, ABS1( VR( JR, JC ) ) )
+   40          CONTINUE
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 60
+               TEMP = ONE / TEMP
+               DO 50 JR = 1, N
+                  VR( JR, JC ) = VR( JR, JC )*TEMP
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ILASCL )
+     $   CALL CLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
+*
+      IF( ILBSCL )
+     $   CALL CLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
+*
+   70 CONTINUE
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of CGGEV
+*
+      END
diff --git a/libcruft/lapack/cgghrd.f b/libcruft/lapack/cgghrd.f
new file mode 100644
index 0000000..9bc4ca1
--- /dev/null
+++ b/libcruft/lapack/cgghrd.f
@@ -0,0 +1,264 @@
+      SUBROUTINE CGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
+     $                   LDQ, Z, LDZ, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ
+      INTEGER            IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGGHRD reduces a pair of complex matrices (A,B) to generalized upper
+*  Hessenberg form using unitary transformations, where A is a
+*  general matrix and B is upper triangular.  The form of the generalized
+*  eigenvalue problem is
+*     A*x = lambda*B*x,
+*  and B is typically made upper triangular by computing its QR
+*  factorization and moving the unitary matrix Q to the left side
+*  of the equation.
+*
+*  This subroutine simultaneously reduces A to a Hessenberg matrix H:
+*     Q**H*A*Z = H
+*  and transforms B to another upper triangular matrix T:
+*     Q**H*B*Z = T
+*  in order to reduce the problem to its standard form
+*     H*y = lambda*T*y
+*  where y = Z**H*x.
+*
+*  The unitary matrices Q and Z are determined as products of Givens
+*  rotations.  They may either be formed explicitly, or they may be
+*  postmultiplied into input matrices Q1 and Z1, so that
+*       Q1 * A * Z1**H = (Q1*Q) * H * (Z1*Z)**H
+*       Q1 * B * Z1**H = (Q1*Q) * T * (Z1*Z)**H
+*  If Q1 is the unitary matrix from the QR factorization of B in the
+*  original equation A*x = lambda*B*x, then CGGHRD reduces the original
+*  problem to generalized Hessenberg form.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': do not compute Q;
+*          = 'I': Q is initialized to the unit matrix, and the
+*                 unitary matrix Q is returned;
+*          = 'V': Q must contain a unitary matrix Q1 on entry,
+*                 and the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': do not compute Q;
+*          = 'I': Q is initialized to the unit matrix, and the
+*                 unitary matrix Q is returned;
+*          = 'V': Q must contain a unitary matrix Q1 on entry,
+*                 and the product Q1*Q is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of A which are to be
+*          reduced.  It is assumed that A is already upper triangular
+*          in rows and columns 1:ILO-1 and IHI+1:N.  ILO and IHI are
+*          normally set by a previous call to CGGBAL; otherwise they
+*          should be set to 1 and N respectively.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA, N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          rest is set to zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB, N)
+*          On entry, the N-by-N upper triangular matrix B.
+*          On exit, the upper triangular matrix T = Q**H B Z.  The
+*          elements below the diagonal are set to zero.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  Q       (input/output) COMPLEX array, dimension (LDQ, N)
+*          On entry, if COMPQ = 'V', the unitary matrix Q1, typically
+*          from the QR factorization of B.
+*          On exit, if COMPQ='I', the unitary matrix Q, and if
+*          COMPQ = 'V', the product Q1*Q.
+*          Not referenced if COMPQ='N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
+*
+*  Z       (input/output) COMPLEX array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the unitary matrix Z1.
+*          On exit, if COMPZ='I', the unitary matrix Z, and if
+*          COMPZ = 'V', the product Z1*Z.
+*          Not referenced if COMPZ='N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.
+*          LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  This routine reduces A to Hessenberg and B to triangular form by
+*  an unblocked reduction, as described in _Matrix_Computations_,
+*  by Golub and van Loan (Johns Hopkins Press).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            CONE, CZERO
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ),
+     $                   CZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILQ, ILZ
+      INTEGER            ICOMPQ, ICOMPZ, JCOL, JROW
+      REAL               C
+      COMPLEX            CTEMP, S
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARTG, CLASET, CROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode COMPQ
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+*     Decode COMPZ
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ICOMPQ.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPZ.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THEN
+         INFO = -11
+      ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGGHRD', -INFO )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z if desired.
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL CLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL CLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Zero out lower triangle of B
+*
+      DO 20 JCOL = 1, N - 1
+         DO 10 JROW = JCOL + 1, N
+            B( JROW, JCOL ) = CZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     Reduce A and B
+*
+      DO 40 JCOL = ILO, IHI - 2
+*
+         DO 30 JROW = IHI, JCOL + 2, -1
+*
+*           Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)
+*
+            CTEMP = A( JROW-1, JCOL )
+            CALL CLARTG( CTEMP, A( JROW, JCOL ), C, S,
+     $                   A( JROW-1, JCOL ) )
+            A( JROW, JCOL ) = CZERO
+            CALL CROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,
+     $                 A( JROW, JCOL+1 ), LDA, C, S )
+            CALL CROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,
+     $                 B( JROW, JROW-1 ), LDB, C, S )
+            IF( ILQ )
+     $         CALL CROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C,
+     $                    CONJG( S ) )
+*
+*           Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)
+*
+            CTEMP = B( JROW, JROW )
+            CALL CLARTG( CTEMP, B( JROW, JROW-1 ), C, S,
+     $                   B( JROW, JROW ) )
+            B( JROW, JROW-1 ) = CZERO
+            CALL CROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )
+            CALL CROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,
+     $                 S )
+            IF( ILZ )
+     $         CALL CROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )
+   30    CONTINUE
+   40 CONTINUE
+*
+      RETURN
+*
+*     End of CGGHRD
+*
+      END
diff --git a/libcruft/lapack/cgtsv.f b/libcruft/lapack/cgtsv.f
new file mode 100644
index 0000000..cde1ce9
--- /dev/null
+++ b/libcruft/lapack/cgtsv.f
@@ -0,0 +1,173 @@
+      SUBROUTINE CGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            B( LDB, * ), D( * ), DL( * ), DU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGTSV  solves the equation
+*
+*     A*X = B,
+*
+*  where A is an N-by-N tridiagonal matrix, by Gaussian elimination with
+*  partial pivoting.
+*
+*  Note that the equation  A'*X = B  may be solved by interchanging the
+*  order of the arguments DU and DL.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input/output) COMPLEX array, dimension (N-1)
+*          On entry, DL must contain the (n-1) subdiagonal elements of
+*          A.
+*          On exit, DL is overwritten by the (n-2) elements of the
+*          second superdiagonal of the upper triangular matrix U from
+*          the LU factorization of A, in DL(1), ..., DL(n-2).
+*
+*  D       (input/output) COMPLEX array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*          On exit, D is overwritten by the n diagonal elements of U.
+*
+*  DU      (input/output) COMPLEX array, dimension (N-1)
+*          On entry, DU must contain the (n-1) superdiagonal elements
+*          of A.
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          superdiagonal of U.
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero, and the solution
+*                has not been computed.  The factorization has not been
+*                completed unless i = N.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J, K
+      COMPLEX            MULT, TEMP, ZDUM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MAX, REAL
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGTSV ', -INFO )
+         RETURN
+      END IF
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      DO 30 K = 1, N - 1
+         IF( DL( K ).EQ.ZERO ) THEN
+*
+*           Subdiagonal is zero, no elimination is required.
+*
+            IF( D( K ).EQ.ZERO ) THEN
+*
+*              Diagonal is zero: set INFO = K and return; a unique
+*              solution can not be found.
+*
+               INFO = K
+               RETURN
+            END IF
+         ELSE IF( CABS1( D( K ) ).GE.CABS1( DL( K ) ) ) THEN
+*
+*           No row interchange required
+*
+            MULT = DL( K ) / D( K )
+            D( K+1 ) = D( K+1 ) - MULT*DU( K )
+            DO 10 J = 1, NRHS
+               B( K+1, J ) = B( K+1, J ) - MULT*B( K, J )
+   10       CONTINUE
+            IF( K.LT.( N-1 ) )
+     $         DL( K ) = ZERO
+         ELSE
+*
+*           Interchange rows K and K+1
+*
+            MULT = D( K ) / DL( K )
+            D( K ) = DL( K )
+            TEMP = D( K+1 )
+            D( K+1 ) = DU( K ) - MULT*TEMP
+            IF( K.LT.( N-1 ) ) THEN
+               DL( K ) = DU( K+1 )
+               DU( K+1 ) = -MULT*DL( K )
+            END IF
+            DU( K ) = TEMP
+            DO 20 J = 1, NRHS
+               TEMP = B( K, J )
+               B( K, J ) = B( K+1, J )
+               B( K+1, J ) = TEMP - MULT*B( K+1, J )
+   20       CONTINUE
+         END IF
+   30 CONTINUE
+      IF( D( N ).EQ.ZERO ) THEN
+         INFO = N
+         RETURN
+      END IF
+*
+*     Back solve with the matrix U from the factorization.
+*
+      DO 50 J = 1, NRHS
+         B( N, J ) = B( N, J ) / D( N )
+         IF( N.GT.1 )
+     $      B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) / D( N-1 )
+         DO 40 K = N - 2, 1, -1
+            B( K, J ) = ( B( K, J )-DU( K )*B( K+1, J )-DL( K )*
+     $                  B( K+2, J ) ) / D( K )
+   40    CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of CGTSV
+*
+      END
diff --git a/libcruft/lapack/cgttrf.f b/libcruft/lapack/cgttrf.f
new file mode 100644
index 0000000..914e326
--- /dev/null
+++ b/libcruft/lapack/cgttrf.f
@@ -0,0 +1,174 @@
+      SUBROUTINE CGTTRF( N, DL, D, DU, DU2, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGTTRF computes an LU factorization of a complex tridiagonal matrix A
+*  using elimination with partial pivoting and row interchanges.
+*
+*  The factorization has the form
+*     A = L * U
+*  where L is a product of permutation and unit lower bidiagonal
+*  matrices and U is upper triangular with nonzeros in only the main
+*  diagonal and first two superdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  DL      (input/output) COMPLEX array, dimension (N-1)
+*          On entry, DL must contain the (n-1) sub-diagonal elements of
+*          A.
+*
+*          On exit, DL is overwritten by the (n-1) multipliers that
+*          define the matrix L from the LU factorization of A.
+*
+*  D       (input/output) COMPLEX array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*
+*          On exit, D is overwritten by the n diagonal elements of the
+*          upper triangular matrix U from the LU factorization of A.
+*
+*  DU      (input/output) COMPLEX array, dimension (N-1)
+*          On entry, DU must contain the (n-1) super-diagonal elements
+*          of A.
+*
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          super-diagonal of U.
+*
+*  DU2     (output) COMPLEX array, dimension (N-2)
+*          On exit, DU2 is overwritten by the (n-2) elements of the
+*          second super-diagonal of U.
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*          > 0:  if INFO = k, U(k,k) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            FACT, TEMP, ZDUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'CGTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Initialize IPIV(i) = i and DU2(i) = 0
+*
+      DO 10 I = 1, N
+         IPIV( I ) = I
+   10 CONTINUE
+      DO 20 I = 1, N - 2
+         DU2( I ) = ZERO
+   20 CONTINUE
+*
+      DO 30 I = 1, N - 2
+         IF( CABS1( D( I ) ).GE.CABS1( DL( I ) ) ) THEN
+*
+*           No row interchange required, eliminate DL(I)
+*
+            IF( CABS1( D( I ) ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+*
+*           Interchange rows I and I+1, eliminate DL(I)
+*
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            DU2( I ) = DU( I+1 )
+            DU( I+1 ) = -FACT*DU( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+   30 CONTINUE
+      IF( N.GT.1 ) THEN
+         I = N - 1
+         IF( CABS1( D( I ) ).GE.CABS1( DL( I ) ) ) THEN
+            IF( CABS1( D( I ) ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+      END IF
+*
+*     Check for a zero on the diagonal of U.
+*
+      DO 40 I = 1, N
+         IF( CABS1( D( I ) ).EQ.ZERO ) THEN
+            INFO = I
+            GO TO 50
+         END IF
+   40 CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of CGTTRF
+*
+      END
diff --git a/libcruft/lapack/cgttrs.f b/libcruft/lapack/cgttrs.f
new file mode 100644
index 0000000..2da12ac
--- /dev/null
+++ b/libcruft/lapack/cgttrs.f
@@ -0,0 +1,142 @@
+      SUBROUTINE CGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGTTRS solves one of the systems of equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by CGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) COMPLEX array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) COMPLEX array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) COMPLEX array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) COMPLEX array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+      INTEGER            ITRANS, J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGTTS2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      NOTRAN = ( TRANS.EQ.'N' .OR. TRANS.EQ.'n' )
+      IF( .NOT.NOTRAN .AND. .NOT.( TRANS.EQ.'T' .OR. TRANS.EQ.
+     $    't' ) .AND. .NOT.( TRANS.EQ.'C' .OR. TRANS.EQ.'c' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDB.LT.MAX( N, 1 ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CGTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Decode TRANS
+*
+      IF( NOTRAN ) THEN
+         ITRANS = 0
+      ELSE IF( TRANS.EQ.'T' .OR. TRANS.EQ.'t' ) THEN
+         ITRANS = 1
+      ELSE
+         ITRANS = 2
+      END IF
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'CGTTRS', TRANS, N, NRHS, -1, -1 ) )
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL CGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL CGTTS2( ITRANS, N, JB, DL, D, DU, DU2, IPIV, B( 1, J ),
+     $                   LDB )
+   10    CONTINUE
+      END IF
+*
+*     End of CGTTRS
+*
+      END
diff --git a/libcruft/lapack/cgtts2.f b/libcruft/lapack/cgtts2.f
new file mode 100644
index 0000000..840a919
--- /dev/null
+++ b/libcruft/lapack/cgtts2.f
@@ -0,0 +1,271 @@
+      SUBROUTINE CGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ITRANS, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CGTTS2 solves one of the systems of equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by CGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITRANS  (input) INTEGER
+*          Specifies the form of the system of equations.
+*          = 0:  A * X = B     (No transpose)
+*          = 1:  A**T * X = B  (Transpose)
+*          = 2:  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) COMPLEX array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) COMPLEX array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) COMPLEX array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) COMPLEX array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+      COMPLEX            TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( ITRANS.EQ.0 ) THEN
+*
+*        Solve A*X = B using the LU factorization of A,
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+   10       CONTINUE
+*
+*           Solve L*x = b.
+*
+            DO 20 I = 1, N - 1
+               IF( IPIV( I ).EQ.I ) THEN
+                  B( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )
+               ELSE
+                  TEMP = B( I, J )
+                  B( I, J ) = B( I+1, J )
+                  B( I+1, J ) = TEMP - DL( I )*B( I, J )
+               END IF
+   20       CONTINUE
+*
+*           Solve U*x = b.
+*
+            B( N, J ) = B( N, J ) / D( N )
+            IF( N.GT.1 )
+     $         B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                       D( N-1 )
+            DO 30 I = N - 2, 1, -1
+               B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                     B( I+2, J ) ) / D( I )
+   30       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 10
+            END IF
+         ELSE
+            DO 60 J = 1, NRHS
+*
+*           Solve L*x = b.
+*
+               DO 40 I = 1, N - 1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )
+                  ELSE
+                     TEMP = B( I, J )
+                     B( I, J ) = B( I+1, J )
+                     B( I+1, J ) = TEMP - DL( I )*B( I, J )
+                  END IF
+   40          CONTINUE
+*
+*           Solve U*x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               IF( N.GT.1 )
+     $            B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                          D( N-1 )
+               DO 50 I = N - 2, 1, -1
+                  B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                        B( I+2, J ) ) / D( I )
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      ELSE IF( ITRANS.EQ.1 ) THEN
+*
+*        Solve A**T * X = B.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+   70       CONTINUE
+*
+*           Solve U**T * x = b.
+*
+            B( 1, J ) = B( 1, J ) / D( 1 )
+            IF( N.GT.1 )
+     $         B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+            DO 80 I = 3, N
+               B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-DU2( I-2 )*
+     $                     B( I-2, J ) ) / D( I )
+   80       CONTINUE
+*
+*           Solve L**T * x = b.
+*
+            DO 90 I = N - 1, 1, -1
+               IF( IPIV( I ).EQ.I ) THEN
+                  B( I, J ) = B( I, J ) - DL( I )*B( I+1, J )
+               ELSE
+                  TEMP = B( I+1, J )
+                  B( I+1, J ) = B( I, J ) - DL( I )*TEMP
+                  B( I, J ) = TEMP
+               END IF
+   90       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 70
+            END IF
+         ELSE
+            DO 120 J = 1, NRHS
+*
+*           Solve U**T * x = b.
+*
+               B( 1, J ) = B( 1, J ) / D( 1 )
+               IF( N.GT.1 )
+     $            B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+               DO 100 I = 3, N
+                  B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-
+     $                        DU2( I-2 )*B( I-2, J ) ) / D( I )
+  100          CONTINUE
+*
+*           Solve L**T * x = b.
+*
+               DO 110 I = N - 1, 1, -1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I, J ) = B( I, J ) - DL( I )*B( I+1, J )
+                  ELSE
+                     TEMP = B( I+1, J )
+                     B( I+1, J ) = B( I, J ) - DL( I )*TEMP
+                     B( I, J ) = TEMP
+                  END IF
+  110          CONTINUE
+  120       CONTINUE
+         END IF
+      ELSE
+*
+*        Solve A**H * X = B.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+  130       CONTINUE
+*
+*           Solve U**H * x = b.
+*
+            B( 1, J ) = B( 1, J ) / CONJG( D( 1 ) )
+            IF( N.GT.1 )
+     $         B( 2, J ) = ( B( 2, J )-CONJG( DU( 1 ) )*B( 1, J ) ) /
+     $                     CONJG( D( 2 ) )
+            DO 140 I = 3, N
+               B( I, J ) = ( B( I, J )-CONJG( DU( I-1 ) )*B( I-1, J )-
+     $                     CONJG( DU2( I-2 ) )*B( I-2, J ) ) /
+     $                     CONJG( D( I ) )
+  140       CONTINUE
+*
+*           Solve L**H * x = b.
+*
+            DO 150 I = N - 1, 1, -1
+               IF( IPIV( I ).EQ.I ) THEN
+                  B( I, J ) = B( I, J ) - CONJG( DL( I ) )*B( I+1, J )
+               ELSE
+                  TEMP = B( I+1, J )
+                  B( I+1, J ) = B( I, J ) - CONJG( DL( I ) )*TEMP
+                  B( I, J ) = TEMP
+               END IF
+  150       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 130
+            END IF
+         ELSE
+            DO 180 J = 1, NRHS
+*
+*           Solve U**H * x = b.
+*
+               B( 1, J ) = B( 1, J ) / CONJG( D( 1 ) )
+               IF( N.GT.1 )
+     $            B( 2, J ) = ( B( 2, J )-CONJG( DU( 1 ) )*B( 1, J ) ) /
+     $                        CONJG( D( 2 ) )
+               DO 160 I = 3, N
+                  B( I, J ) = ( B( I, J )-CONJG( DU( I-1 ) )*
+     $                        B( I-1, J )-CONJG( DU2( I-2 ) )*
+     $                        B( I-2, J ) ) / CONJG( D( I ) )
+  160          CONTINUE
+*
+*           Solve L**H * x = b.
+*
+               DO 170 I = N - 1, 1, -1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I, J ) = B( I, J ) - CONJG( DL( I ) )*
+     $                           B( I+1, J )
+                  ELSE
+                     TEMP = B( I+1, J )
+                     B( I+1, J ) = B( I, J ) - CONJG( DL( I ) )*TEMP
+                     B( I, J ) = TEMP
+                  END IF
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+      END IF
+*
+*     End of CGTTS2
+*
+      END
diff --git a/libcruft/lapack/cheev.f b/libcruft/lapack/cheev.f
new file mode 100644
index 0000000..78fa34d
--- /dev/null
+++ b/libcruft/lapack/cheev.f
@@ -0,0 +1,218 @@
+      SUBROUTINE CHEEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK,
+     $                  INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * ), W( * )
+      COMPLEX            A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHEEV computes all eigenvalues and, optionally, eigenvectors of a
+*  complex Hermitian matrix A.
+*
+*  Arguments
+*  =========
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA, N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          orthonormal eigenvectors of the matrix A.
+*          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
+*          or the upper triangle (if UPLO='U') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  W       (output) REAL array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,2*N-1).
+*          For optimal efficiency, LWORK >= (NB+1)*N,
+*          where NB is the blocksize for CHETRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (max(1, 3*N-2))
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the algorithm failed to converge; i
+*                off-diagonal elements of an intermediate tridiagonal
+*                form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+      COMPLEX            CONE
+      PARAMETER          ( CONE = ( 1.0E0, 0.0E0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, LQUERY, WANTZ
+      INTEGER            IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
+     $                   LLWORK, LWKOPT, NB
+      REAL               ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
+     $                   SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               CLANHE, SLAMCH
+      EXTERNAL           ILAENV, LSAME, CLANHE, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CHETRD, CLASCL, CSTEQR, CUNGTR, SSCAL, SSTERF,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      LOWER = LSAME( UPLO, 'L' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'CHETRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( 1, ( NB+1 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, 2*N-1 ) .AND. .NOT.LQUERY )
+     $      INFO = -8
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHEEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         W( 1 ) = A( 1, 1 )
+         WORK( 1 ) = 1
+         IF( WANTZ )
+     $      A( 1, 1 ) = CONE
+         RETURN
+      END IF
+*
+*     Get machine constants.
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      EPS = SLAMCH( 'Precision' )
+      SMLNUM = SAFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      RMIN = SQRT( SMLNUM )
+      RMAX = SQRT( BIGNUM )
+*
+*     Scale matrix to allowable range, if necessary.
+*
+      ANRM = CLANHE( 'M', UPLO, N, A, LDA, RWORK )
+      ISCALE = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
+         ISCALE = 1
+         SIGMA = RMIN / ANRM
+      ELSE IF( ANRM.GT.RMAX ) THEN
+         ISCALE = 1
+         SIGMA = RMAX / ANRM
+      END IF
+      IF( ISCALE.EQ.1 )
+     $   CALL CLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
+*
+*     Call CHETRD to reduce Hermitian matrix to tridiagonal form.
+*
+      INDE = 1
+      INDTAU = 1
+      INDWRK = INDTAU + N
+      LLWORK = LWORK - INDWRK + 1
+      CALL CHETRD( UPLO, N, A, LDA, W, RWORK( INDE ), WORK( INDTAU ),
+     $             WORK( INDWRK ), LLWORK, IINFO )
+*
+*     For eigenvalues only, call SSTERF.  For eigenvectors, first call
+*     CUNGTR to generate the unitary matrix, then call CSTEQR.
+*
+      IF( .NOT.WANTZ ) THEN
+         CALL SSTERF( N, W, RWORK( INDE ), INFO )
+      ELSE
+         CALL CUNGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
+     $                LLWORK, IINFO )
+         INDWRK = INDE + N
+         CALL CSTEQR( JOBZ, N, W, RWORK( INDE ), A, LDA,
+     $                RWORK( INDWRK ), INFO )
+      END IF
+*
+*     If matrix was scaled, then rescale eigenvalues appropriately.
+*
+      IF( ISCALE.EQ.1 ) THEN
+         IF( INFO.EQ.0 ) THEN
+            IMAX = N
+         ELSE
+            IMAX = INFO - 1
+         END IF
+         CALL SSCAL( IMAX, ONE / SIGMA, W, 1 )
+      END IF
+*
+*     Set WORK(1) to optimal complex workspace size.
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of CHEEV
+*
+      END
diff --git a/libcruft/lapack/chegs2.f b/libcruft/lapack/chegs2.f
new file mode 100644
index 0000000..5bc7869
--- /dev/null
+++ b/libcruft/lapack/chegs2.f
@@ -0,0 +1,224 @@
+      SUBROUTINE CHEGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHEGS2 reduces a complex Hermitian-definite generalized
+*  eigenproblem to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U')*A*inv(U) or inv(L)*A*inv(L')
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U` or L'*A*L.
+*
+*  B must have been previously factorized as U'*U or L*L' by CPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U')*A*inv(U) or inv(L)*A*inv(L');
+*          = 2 or 3: compute U*A*U' or L'*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored, and how B has been factorized.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) COMPLEX array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by CPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, HALF
+      PARAMETER          ( ONE = 1.0E+0, HALF = 0.5E+0 )
+      COMPLEX            CONE
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K
+      REAL               AKK, BKK
+      COMPLEX            CT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CHER2, CLACGV, CSSCAL, CTRMV, CTRSV,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHEGS2', -INFO )
+         RETURN
+      END IF
+*
+      IF( ITYPE.EQ.1 ) THEN
+         IF( UPPER ) THEN
+*
+*           Compute inv(U')*A*inv(U)
+*
+            DO 10 K = 1, N
+*
+*              Update the upper triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL CSSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA )
+                  CT = -HALF*AKK
+                  CALL CLACGV( N-K, A( K, K+1 ), LDA )
+                  CALL CLACGV( N-K, B( K, K+1 ), LDB )
+                  CALL CAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL CHER2( UPLO, N-K, -CONE, A( K, K+1 ), LDA,
+     $                        B( K, K+1 ), LDB, A( K+1, K+1 ), LDA )
+                  CALL CAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL CLACGV( N-K, B( K, K+1 ), LDB )
+                  CALL CTRSV( UPLO, 'Conjugate transpose', 'Non-unit',
+     $                        N-K, B( K+1, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL CLACGV( N-K, A( K, K+1 ), LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute inv(L)*A*inv(L')
+*
+            DO 20 K = 1, N
+*
+*              Update the lower triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL CSSCAL( N-K, ONE / BKK, A( K+1, K ), 1 )
+                  CT = -HALF*AKK
+                  CALL CAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL CHER2( UPLO, N-K, -CONE, A( K+1, K ), 1,
+     $                        B( K+1, K ), 1, A( K+1, K+1 ), LDA )
+                  CALL CAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL CTRSV( UPLO, 'No transpose', 'Non-unit', N-K,
+     $                        B( K+1, K+1 ), LDB, A( K+1, K ), 1 )
+               END IF
+   20       CONTINUE
+         END IF
+      ELSE
+         IF( UPPER ) THEN
+*
+*           Compute U*A*U'
+*
+            DO 30 K = 1, N
+*
+*              Update the upper triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL CTRMV( UPLO, 'No transpose', 'Non-unit', K-1, B,
+     $                     LDB, A( 1, K ), 1 )
+               CT = HALF*AKK
+               CALL CAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL CHER2( UPLO, K-1, CONE, A( 1, K ), 1, B( 1, K ), 1,
+     $                     A, LDA )
+               CALL CAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL CSSCAL( K-1, BKK, A( 1, K ), 1 )
+               A( K, K ) = AKK*BKK**2
+   30       CONTINUE
+         ELSE
+*
+*           Compute L'*A*L
+*
+            DO 40 K = 1, N
+*
+*              Update the lower triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL CLACGV( K-1, A( K, 1 ), LDA )
+               CALL CTRMV( UPLO, 'Conjugate transpose', 'Non-unit', K-1,
+     $                     B, LDB, A( K, 1 ), LDA )
+               CT = HALF*AKK
+               CALL CLACGV( K-1, B( K, 1 ), LDB )
+               CALL CAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL CHER2( UPLO, K-1, CONE, A( K, 1 ), LDA, B( K, 1 ),
+     $                     LDB, A, LDA )
+               CALL CAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL CLACGV( K-1, B( K, 1 ), LDB )
+               CALL CSSCAL( K-1, BKK, A( K, 1 ), LDA )
+               CALL CLACGV( K-1, A( K, 1 ), LDA )
+               A( K, K ) = AKK*BKK**2
+   40       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of CHEGS2
+*
+      END
diff --git a/libcruft/lapack/chegst.f b/libcruft/lapack/chegst.f
new file mode 100644
index 0000000..f29d29e
--- /dev/null
+++ b/libcruft/lapack/chegst.f
@@ -0,0 +1,259 @@
+      SUBROUTINE CHEGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHEGST reduces a complex Hermitian-definite generalized
+*  eigenproblem to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U**H)*A*inv(U) or inv(L)*A*inv(L**H)
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U**H or L**H*A*L.
+*
+*  B must have been previously factorized as U**H*U or L*L**H by CPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U**H)*A*inv(U) or inv(L)*A*inv(L**H);
+*          = 2 or 3: compute U*A*U**H or L**H*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored and B is factored as
+*                  U**H*U;
+*          = 'L':  Lower triangle of A is stored and B is factored as
+*                  L*L**H.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) COMPLEX array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by CPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+      COMPLEX            CONE, HALF
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ),
+     $                   HALF = ( 0.5E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K, KB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CHEGS2, CHEMM, CHER2K, CTRMM, CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHEGST', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'CHEGST', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL CHEGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ITYPE.EQ.1 ) THEN
+            IF( UPPER ) THEN
+*
+*              Compute inv(U')*A*inv(U)
+*
+               DO 10 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(k:n,k:n)
+*
+                  CALL CHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL CTRSM( 'Left', UPLO, 'Conjugate transpose',
+     $                           'Non-unit', KB, N-K-KB+1, CONE,
+     $                           B( K, K ), LDB, A( K, K+KB ), LDA )
+                     CALL CHEMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB,
+     $                           CONE, A( K, K+KB ), LDA )
+                     CALL CHER2K( UPLO, 'Conjugate transpose', N-K-KB+1,
+     $                            KB, -CONE, A( K, K+KB ), LDA,
+     $                            B( K, K+KB ), LDB, ONE,
+     $                            A( K+KB, K+KB ), LDA )
+                     CALL CHEMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB,
+     $                           CONE, A( K, K+KB ), LDA )
+                     CALL CTRSM( 'Right', UPLO, 'No transpose',
+     $                           'Non-unit', KB, N-K-KB+1, CONE,
+     $                           B( K+KB, K+KB ), LDB, A( K, K+KB ),
+     $                           LDA )
+                  END IF
+   10          CONTINUE
+            ELSE
+*
+*              Compute inv(L)*A*inv(L')
+*
+               DO 20 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(k:n,k:n)
+*
+                  CALL CHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL CTRSM( 'Right', UPLO, 'Conjugate transpose',
+     $                           'Non-unit', N-K-KB+1, KB, CONE,
+     $                           B( K, K ), LDB, A( K+KB, K ), LDA )
+                     CALL CHEMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB,
+     $                           CONE, A( K+KB, K ), LDA )
+                     CALL CHER2K( UPLO, 'No transpose', N-K-KB+1, KB,
+     $                            -CONE, A( K+KB, K ), LDA,
+     $                            B( K+KB, K ), LDB, ONE,
+     $                            A( K+KB, K+KB ), LDA )
+                     CALL CHEMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB,
+     $                           CONE, A( K+KB, K ), LDA )
+                     CALL CTRSM( 'Left', UPLO, 'No transpose',
+     $                           'Non-unit', N-K-KB+1, KB, CONE,
+     $                           B( K+KB, K+KB ), LDB, A( K+KB, K ),
+     $                           LDA )
+                  END IF
+   20          CONTINUE
+            END IF
+         ELSE
+            IF( UPPER ) THEN
+*
+*              Compute U*A*U'
+*
+               DO 30 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL CTRMM( 'Left', UPLO, 'No transpose', 'Non-unit',
+     $                        K-1, KB, CONE, B, LDB, A( 1, K ), LDA )
+                  CALL CHEMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, CONE, A( 1, K ),
+     $                        LDA )
+                  CALL CHER2K( UPLO, 'No transpose', K-1, KB, CONE,
+     $                         A( 1, K ), LDA, B( 1, K ), LDB, ONE, A,
+     $                         LDA )
+                  CALL CHEMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, CONE, A( 1, K ),
+     $                        LDA )
+                  CALL CTRMM( 'Right', UPLO, 'Conjugate transpose',
+     $                        'Non-unit', K-1, KB, CONE, B( K, K ), LDB,
+     $                        A( 1, K ), LDA )
+                  CALL CHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   30          CONTINUE
+            ELSE
+*
+*              Compute L'*A*L
+*
+               DO 40 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL CTRMM( 'Right', UPLO, 'No transpose', 'Non-unit',
+     $                        KB, K-1, CONE, B, LDB, A( K, 1 ), LDA )
+                  CALL CHEMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, CONE, A( K, 1 ),
+     $                        LDA )
+                  CALL CHER2K( UPLO, 'Conjugate transpose', K-1, KB,
+     $                         CONE, A( K, 1 ), LDA, B( K, 1 ), LDB,
+     $                         ONE, A, LDA )
+                  CALL CHEMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, CONE, A( K, 1 ),
+     $                        LDA )
+                  CALL CTRMM( 'Left', UPLO, 'Conjugate transpose',
+     $                        'Non-unit', KB, K-1, CONE, B( K, K ), LDB,
+     $                        A( K, 1 ), LDA )
+                  CALL CHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of CHEGST
+*
+      END
diff --git a/libcruft/lapack/chegv.f b/libcruft/lapack/chegv.f
new file mode 100644
index 0000000..f68db72
--- /dev/null
+++ b/libcruft/lapack/chegv.f
@@ -0,0 +1,232 @@
+      SUBROUTINE CHEGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
+     $                  LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * ), W( * )
+      COMPLEX            A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHEGV computes all the eigenvalues, and optionally, the eigenvectors
+*  of a complex generalized Hermitian-definite eigenproblem, of the form
+*  A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.
+*  Here A and B are assumed to be Hermitian and B is also
+*  positive definite.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          Specifies the problem type to be solved:
+*          = 1:  A*x = (lambda)*B*x
+*          = 2:  A*B*x = (lambda)*x
+*          = 3:  B*A*x = (lambda)*x
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangles of A and B are stored;
+*          = 'L':  Lower triangles of A and B are stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA, N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          matrix Z of eigenvectors.  The eigenvectors are normalized
+*          as follows:
+*          if ITYPE = 1 or 2, Z**H*B*Z = I;
+*          if ITYPE = 3, Z**H*inv(B)*Z = I.
+*          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
+*          or the lower triangle (if UPLO='L') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB, N)
+*          On entry, the Hermitian positive definite matrix B.
+*          If UPLO = 'U', the leading N-by-N upper triangular part of B
+*          contains the upper triangular part of the matrix B.
+*          If UPLO = 'L', the leading N-by-N lower triangular part of B
+*          contains the lower triangular part of the matrix B.
+*
+*          On exit, if INFO <= N, the part of B containing the matrix is
+*          overwritten by the triangular factor U or L from the Cholesky
+*          factorization B = U**H*U or B = L*L**H.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  W       (output) REAL array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,2*N-1).
+*          For optimal efficiency, LWORK >= (NB+1)*N,
+*          where NB is the blocksize for CHETRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (max(1, 3*N-2))
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  CPOTRF or CHEEV returned an error code:
+*             <= N:  if INFO = i, CHEEV failed to converge;
+*                    i off-diagonal elements of an intermediate
+*                    tridiagonal form did not converge to zero;
+*             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
+*                    minor of order i of B is not positive definite.
+*                    The factorization of B could not be completed and
+*                    no eigenvalues or eigenvectors were computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER, WANTZ
+      CHARACTER          TRANS
+      INTEGER            LWKOPT, NB, NEIG
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CHEEV, CHEGST, CPOTRF, CTRMM, CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ. -1 )
+*
+      INFO = 0
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'CHETRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( 1, ( NB + 1 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, 2*N-1 ) .AND. .NOT.LQUERY ) THEN
+            INFO = -11
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHEGV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form a Cholesky factorization of B.
+*
+      CALL CPOTRF( UPLO, N, B, LDB, INFO )
+      IF( INFO.NE.0 ) THEN
+         INFO = N + INFO
+         RETURN
+      END IF
+*
+*     Transform problem to standard eigenvalue problem and solve.
+*
+      CALL CHEGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      CALL CHEEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, INFO )
+*
+      IF( WANTZ ) THEN
+*
+*        Backtransform eigenvectors to the original problem.
+*
+         NEIG = N
+         IF( INFO.GT.0 )
+     $      NEIG = INFO - 1
+         IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
+*
+*           For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
+*           backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'N'
+            ELSE
+               TRANS = 'C'
+            END IF
+*
+            CALL CTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+*
+         ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*           For B*A*x=(lambda)*x;
+*           backtransform eigenvectors: x = L*y or U'*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'C'
+            ELSE
+               TRANS = 'N'
+            END IF
+*
+            CALL CTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+         END IF
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of CHEGV
+*
+      END
diff --git a/libcruft/lapack/chetd2.f b/libcruft/lapack/chetd2.f
new file mode 100644
index 0000000..e1b51f2
--- /dev/null
+++ b/libcruft/lapack/chetd2.f
@@ -0,0 +1,258 @@
+      SUBROUTINE CHETD2( UPLO, N, A, LDA, D, E, TAU, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+      COMPLEX            A( LDA, * ), TAU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHETD2 reduces a complex Hermitian matrix A to real symmetric
+*  tridiagonal form T by a unitary similarity transformation:
+*  Q' * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the unitary
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the unitary matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) REAL array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) COMPLEX array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO, HALF
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   HALF = ( 0.5E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      COMPLEX            ALPHA, TAUI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CHEMV, CHER2, CLARFG, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX            CDOTC
+      EXTERNAL           LSAME, CDOTC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHETD2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A
+*
+         A( N, N ) = REAL( A( N, N ) )
+         DO 10 I = N - 1, 1, -1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(1:i-1,i+1)
+*
+            ALPHA = A( I, I+1 )
+            CALL CLARFG( I, ALPHA, A( 1, I+1 ), 1, TAUI )
+            E( I ) = ALPHA
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(1:i,1:i)
+*
+               A( I, I+1 ) = ONE
+*
+*              Compute  x := tau * A * v  storing x in TAU(1:i)
+*
+               CALL CHEMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO,
+     $                     TAU, 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*CDOTC( I, TAU, 1, A( 1, I+1 ), 1 )
+               CALL CAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL CHER2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A,
+     $                     LDA )
+*
+            ELSE
+               A( I, I ) = REAL( A( I, I ) )
+            END IF
+            A( I, I+1 ) = E( I )
+            D( I+1 ) = A( I+1, I+1 )
+            TAU( I ) = TAUI
+   10    CONTINUE
+         D( 1 ) = A( 1, 1 )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         A( 1, 1 ) = REAL( A( 1, 1 ) )
+         DO 20 I = 1, N - 1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(i+2:n,i)
+*
+            ALPHA = A( I+1, I )
+            CALL CLARFG( N-I, ALPHA, A( MIN( I+2, N ), I ), 1, TAUI )
+            E( I ) = ALPHA
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(i+1:n,i+1:n)
+*
+               A( I+1, I ) = ONE
+*
+*              Compute  x := tau * A * v  storing y in TAU(i:n-1)
+*
+               CALL CHEMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, TAU( I ), 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*CDOTC( N-I, TAU( I ), 1, A( I+1, I ),
+     $                 1 )
+               CALL CAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL CHER2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1,
+     $                     A( I+1, I+1 ), LDA )
+*
+            ELSE
+               A( I+1, I+1 ) = REAL( A( I+1, I+1 ) )
+            END IF
+            A( I+1, I ) = E( I )
+            D( I ) = A( I, I )
+            TAU( I ) = TAUI
+   20    CONTINUE
+         D( N ) = A( N, N )
+      END IF
+*
+      RETURN
+*
+*     End of CHETD2
+*
+      END
diff --git a/libcruft/lapack/chetrd.f b/libcruft/lapack/chetrd.f
new file mode 100644
index 0000000..a916657
--- /dev/null
+++ b/libcruft/lapack/chetrd.f
@@ -0,0 +1,296 @@
+      SUBROUTINE CHETRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHETRD reduces a complex Hermitian matrix A to real symmetric
+*  tridiagonal form T by a unitary similarity transformation:
+*  Q**H * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the unitary
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the unitary matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) REAL array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) COMPLEX array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= 1.
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+      COMPLEX            CONE
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CHER2K, CHETD2, CLATRD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.
+*
+         NB = ILAENV( 1, 'CHETRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = N*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHETRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NX = N
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code).
+*
+         NX = MAX( NB, ILAENV( 3, 'CHETRD', UPLO, N, -1, -1, -1 ) )
+         IF( NX.LT.N ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code by setting NX = N.
+*
+               NB = MAX( LWORK / LDWORK, 1 )
+               NBMIN = ILAENV( 2, 'CHETRD', UPLO, N, -1, -1, -1 )
+               IF( NB.LT.NBMIN )
+     $            NX = N
+            END IF
+         ELSE
+            NX = N
+         END IF
+      ELSE
+         NB = 1
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A.
+*        Columns 1:kk are handled by the unblocked method.
+*
+         KK = N - ( ( N-NX+NB-1 ) / NB )*NB
+         DO 20 I = N - NB + 1, KK + 1, -NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL CLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK,
+     $                   LDWORK )
+*
+*           Update the unreduced submatrix A(1:i-1,1:i-1), using an
+*           update of the form:  A := A - V*W' - W*V'
+*
+            CALL CHER2K( UPLO, 'No transpose', I-1, NB, -CONE,
+     $                   A( 1, I ), LDA, WORK, LDWORK, ONE, A, LDA )
+*
+*           Copy superdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 10 J = I, I + NB - 1
+               A( J-1, J ) = E( J-1 )
+               D( J ) = A( J, J )
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL CHETD2( UPLO, KK, A, LDA, D, E, TAU, IINFO )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         DO 40 I = 1, N - NX, NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL CLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ),
+     $                   TAU( I ), WORK, LDWORK )
+*
+*           Update the unreduced submatrix A(i+nb:n,i+nb:n), using
+*           an update of the form:  A := A - V*W' - W*V'
+*
+            CALL CHER2K( UPLO, 'No transpose', N-I-NB+1, NB, -CONE,
+     $                   A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE,
+     $                   A( I+NB, I+NB ), LDA )
+*
+*           Copy subdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 30 J = I, I + NB - 1
+               A( J+1, J ) = E( J )
+               D( J ) = A( J, J )
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL CHETD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $                TAU( I ), IINFO )
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CHETRD
+*
+      END
diff --git a/libcruft/lapack/chgeqz.f b/libcruft/lapack/chgeqz.f
new file mode 100644
index 0000000..9593179
--- /dev/null
+++ b/libcruft/lapack/chgeqz.f
@@ -0,0 +1,758 @@
+      SUBROUTINE CHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,
+     $                   ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK,
+     $                   RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ, JOB
+      INTEGER            IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            ALPHA( * ), BETA( * ), H( LDH, * ),
+     $                   Q( LDQ, * ), T( LDT, * ), WORK( * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CHGEQZ computes the eigenvalues of a complex matrix pair (H,T),
+*  where H is an upper Hessenberg matrix and T is upper triangular,
+*  using the single-shift QZ method.
+*  Matrix pairs of this type are produced by the reduction to
+*  generalized upper Hessenberg form of a complex matrix pair (A,B):
+*  
+*     A = Q1*H*Z1**H,  B = Q1*T*Z1**H,
+*  
+*  as computed by CGGHRD.
+*  
+*  If JOB='S', then the Hessenberg-triangular pair (H,T) is
+*  also reduced to generalized Schur form,
+*  
+*     H = Q*S*Z**H,  T = Q*P*Z**H,
+*  
+*  where Q and Z are unitary matrices and S and P are upper triangular.
+*  
+*  Optionally, the unitary matrix Q from the generalized Schur
+*  factorization may be postmultiplied into an input matrix Q1, and the
+*  unitary matrix Z may be postmultiplied into an input matrix Z1.
+*  If Q1 and Z1 are the unitary matrices from CGGHRD that reduced
+*  the matrix pair (A,B) to generalized Hessenberg form, then the output
+*  matrices Q1*Q and Z1*Z are the unitary factors from the generalized
+*  Schur factorization of (A,B):
+*  
+*     A = (Q1*Q)*S*(Z1*Z)**H,  B = (Q1*Q)*P*(Z1*Z)**H.
+*  
+*  To avoid overflow, eigenvalues of the matrix pair (H,T)
+*  (equivalently, of (A,B)) are computed as a pair of complex values
+*  (alpha,beta).  If beta is nonzero, lambda = alpha / beta is an
+*  eigenvalue of the generalized nonsymmetric eigenvalue problem (GNEP)
+*     A*x = lambda*B*x
+*  and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the
+*  alternate form of the GNEP
+*     mu*A*y = B*y.
+*  The values of alpha and beta for the i-th eigenvalue can be read
+*  directly from the generalized Schur form:  alpha = S(i,i),
+*  beta = P(i,i).
+*
+*  Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix
+*       Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),
+*       pp. 241--256.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          = 'E': Compute eigenvalues only;
+*          = 'S': Computer eigenvalues and the Schur form.
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': Left Schur vectors (Q) are not computed;
+*          = 'I': Q is initialized to the unit matrix and the matrix Q
+*                 of left Schur vectors of (H,T) is returned;
+*          = 'V': Q must contain a unitary matrix Q1 on entry and
+*                 the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': Right Schur vectors (Z) are not computed;
+*          = 'I': Q is initialized to the unit matrix and the matrix Z
+*                 of right Schur vectors of (H,T) is returned;
+*          = 'V': Z must contain a unitary matrix Z1 on entry and
+*                 the product Z1*Z is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices H, T, Q, and Z.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of H which are in
+*          Hessenberg form.  It is assumed that A is already upper
+*          triangular in rows and columns 1:ILO-1 and IHI+1:N.
+*          If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0.
+*
+*  H       (input/output) COMPLEX array, dimension (LDH, N)
+*          On entry, the N-by-N upper Hessenberg matrix H.
+*          On exit, if JOB = 'S', H contains the upper triangular
+*          matrix S from the generalized Schur factorization.
+*          If JOB = 'E', the diagonal of H matches that of S, but
+*          the rest of H is unspecified.
+*
+*  LDH     (input) INTEGER
+*          The leading dimension of the array H.  LDH >= max( 1, N ).
+*
+*  T       (input/output) COMPLEX array, dimension (LDT, N)
+*          On entry, the N-by-N upper triangular matrix T.
+*          On exit, if JOB = 'S', T contains the upper triangular
+*          matrix P from the generalized Schur factorization.
+*          If JOB = 'E', the diagonal of T matches that of P, but
+*          the rest of T is unspecified.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= max( 1, N ).
+*
+*  ALPHA   (output) COMPLEX array, dimension (N)
+*          The complex scalars alpha that define the eigenvalues of
+*          GNEP.  ALPHA(i) = S(i,i) in the generalized Schur
+*          factorization.
+*
+*  BETA    (output) COMPLEX array, dimension (N)
+*          The real non-negative scalars beta that define the
+*          eigenvalues of GNEP.  BETA(i) = P(i,i) in the generalized
+*          Schur factorization.
+*
+*          Together, the quantities alpha = ALPHA(j) and beta = BETA(j)
+*          represent the j-th eigenvalue of the matrix pair (A,B), in
+*          one of the forms lambda = alpha/beta or mu = beta/alpha.
+*          Since either lambda or mu may overflow, they should not,
+*          in general, be computed.
+*
+*  Q       (input/output) COMPLEX array, dimension (LDQ, N)
+*          On entry, if COMPZ = 'V', the unitary matrix Q1 used in the
+*          reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the unitary matrix of left Schur
+*          vectors of (H,T), and if COMPZ = 'V', the unitary matrix of
+*          left Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= 1.
+*          If COMPQ='V' or 'I', then LDQ >= N.
+*
+*  Z       (input/output) COMPLEX array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the unitary matrix Z1 used in the
+*          reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the unitary matrix of right Schur
+*          vectors of (H,T), and if COMPZ = 'V', the unitary matrix of
+*          right Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1.
+*          If COMPZ='V' or 'I', then LDZ >= N.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1,...,N: the QZ iteration did not converge.  (H,T) is not
+*                     in Schur form, but ALPHA(i) and BETA(i),
+*                     i=INFO+1,...,N should be correct.
+*          = N+1,...,2*N: the shift calculation failed.  (H,T) is not
+*                     in Schur form, but ALPHA(i) and BETA(i),
+*                     i=INFO-N+1,...,N should be correct.
+*
+*  Further Details
+*  ===============
+*
+*  We assume that complex ABS works as long as its value is less than
+*  overflow.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   CONE = ( 1.0E+0, 0.0E+0 ) )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      REAL               HALF
+      PARAMETER          ( HALF = 0.5E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILAZR2, ILAZRO, ILQ, ILSCHR, ILZ, LQUERY
+      INTEGER            ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,
+     $                   ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,
+     $                   JR, MAXIT
+      REAL               ABSB, ANORM, ASCALE, ATOL, BNORM, BSCALE, BTOL,
+     $                   C, SAFMIN, TEMP, TEMP2, TEMPR, ULP
+      COMPLEX            ABI22, AD11, AD12, AD21, AD22, CTEMP, CTEMP2,
+     $                   CTEMP3, ESHIFT, RTDISC, S, SHIFT, SIGNBC, T1,
+     $                   U12, X
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               CLANHS, SLAMCH
+      EXTERNAL           LSAME, CLANHS, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARTG, CLASET, CROT, CSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Statement Functions ..
+      REAL               ABS1
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode JOB, COMPQ, COMPZ
+*
+      IF( LSAME( JOB, 'E' ) ) THEN
+         ILSCHR = .FALSE.
+         ISCHUR = 1
+      ELSE IF( LSAME( JOB, 'S' ) ) THEN
+         ILSCHR = .TRUE.
+         ISCHUR = 2
+      ELSE
+         ISCHUR = 0
+      END IF
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Check Argument Values
+*
+      INFO = 0
+      WORK( 1 ) = MAX( 1, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( ISCHUR.EQ.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPQ.EQ.0 ) THEN
+         INFO = -2
+      ELSE IF( ICOMPZ.EQ.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -6
+      ELSE IF( LDH.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDT.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -14
+      ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THEN
+         INFO = -16
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -18
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CHGEQZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+c     WORK( 1 ) = CMPLX( 1 )
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = CMPLX( 1 )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL CLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL CLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
+*
+*     Machine Constants
+*
+      IN = IHI + 1 - ILO
+      SAFMIN = SLAMCH( 'S' )
+      ULP = SLAMCH( 'E' )*SLAMCH( 'B' )
+      ANORM = CLANHS( 'F', IN, H( ILO, ILO ), LDH, RWORK )
+      BNORM = CLANHS( 'F', IN, T( ILO, ILO ), LDT, RWORK )
+      ATOL = MAX( SAFMIN, ULP*ANORM )
+      BTOL = MAX( SAFMIN, ULP*BNORM )
+      ASCALE = ONE / MAX( SAFMIN, ANORM )
+      BSCALE = ONE / MAX( SAFMIN, BNORM )
+*
+*
+*     Set Eigenvalues IHI+1:N
+*
+      DO 10 J = IHI + 1, N
+         ABSB = ABS( T( J, J ) )
+         IF( ABSB.GT.SAFMIN ) THEN
+            SIGNBC = CONJG( T( J, J ) / ABSB )
+            T( J, J ) = ABSB
+            IF( ILSCHR ) THEN
+               CALL CSCAL( J-1, SIGNBC, T( 1, J ), 1 )
+               CALL CSCAL( J, SIGNBC, H( 1, J ), 1 )
+            ELSE
+               H( J, J ) = H( J, J )*SIGNBC
+            END IF
+            IF( ILZ )
+     $         CALL CSCAL( N, SIGNBC, Z( 1, J ), 1 )
+         ELSE
+            T( J, J ) = CZERO
+         END IF
+         ALPHA( J ) = H( J, J )
+         BETA( J ) = T( J, J )
+   10 CONTINUE
+*
+*     If IHI < ILO, skip QZ steps
+*
+      IF( IHI.LT.ILO )
+     $   GO TO 190
+*
+*     MAIN QZ ITERATION LOOP
+*
+*     Initialize dynamic indices
+*
+*     Eigenvalues ILAST+1:N have been found.
+*        Column operations modify rows IFRSTM:whatever
+*        Row operations modify columns whatever:ILASTM
+*
+*     If only eigenvalues are being computed, then
+*        IFRSTM is the row of the last splitting row above row ILAST;
+*        this is always at least ILO.
+*     IITER counts iterations since the last eigenvalue was found,
+*        to tell when to use an extraordinary shift.
+*     MAXIT is the maximum number of QZ sweeps allowed.
+*
+      ILAST = IHI
+      IF( ILSCHR ) THEN
+         IFRSTM = 1
+         ILASTM = N
+      ELSE
+         IFRSTM = ILO
+         ILASTM = IHI
+      END IF
+      IITER = 0
+      ESHIFT = CZERO
+      MAXIT = 30*( IHI-ILO+1 )
+*
+      DO 170 JITER = 1, MAXIT
+*
+*        Check for too many iterations.
+*
+         IF( JITER.GT.MAXIT )
+     $      GO TO 180
+*
+*        Split the matrix if possible.
+*
+*        Two tests:
+*           1: H(j,j-1)=0  or  j=ILO
+*           2: T(j,j)=0
+*
+*        Special case: j=ILAST
+*
+         IF( ILAST.EQ.ILO ) THEN
+            GO TO 60
+         ELSE
+            IF( ABS1( H( ILAST, ILAST-1 ) ).LE.ATOL ) THEN
+               H( ILAST, ILAST-1 ) = CZERO
+               GO TO 60
+            END IF
+         END IF
+*
+         IF( ABS( T( ILAST, ILAST ) ).LE.BTOL ) THEN
+            T( ILAST, ILAST ) = CZERO
+            GO TO 50
+         END IF
+*
+*        General case: j<ILAST
+*
+         DO 40 J = ILAST - 1, ILO, -1
+*
+*           Test 1: for H(j,j-1)=0 or j=ILO
+*
+            IF( J.EQ.ILO ) THEN
+               ILAZRO = .TRUE.
+            ELSE
+               IF( ABS1( H( J, J-1 ) ).LE.ATOL ) THEN
+                  H( J, J-1 ) = CZERO
+                  ILAZRO = .TRUE.
+               ELSE
+                  ILAZRO = .FALSE.
+               END IF
+            END IF
+*
+*           Test 2: for T(j,j)=0
+*
+            IF( ABS( T( J, J ) ).LT.BTOL ) THEN
+               T( J, J ) = CZERO
+*
+*              Test 1a: Check for 2 consecutive small subdiagonals in A
+*
+               ILAZR2 = .FALSE.
+               IF( .NOT.ILAZRO ) THEN
+                  IF( ABS1( H( J, J-1 ) )*( ASCALE*ABS1( H( J+1,
+     $                J ) ) ).LE.ABS1( H( J, J ) )*( ASCALE*ATOL ) )
+     $                ILAZR2 = .TRUE.
+               END IF
+*
+*              If both tests pass (1 & 2), i.e., the leading diagonal
+*              element of B in the block is zero, split a 1x1 block off
+*              at the top. (I.e., at the J-th row/column) The leading
+*              diagonal element of the remainder can also be zero, so
+*              this may have to be done repeatedly.
+*
+               IF( ILAZRO .OR. ILAZR2 ) THEN
+                  DO 20 JCH = J, ILAST - 1
+                     CTEMP = H( JCH, JCH )
+                     CALL CLARTG( CTEMP, H( JCH+1, JCH ), C, S,
+     $                            H( JCH, JCH ) )
+                     H( JCH+1, JCH ) = CZERO
+                     CALL CROT( ILASTM-JCH, H( JCH, JCH+1 ), LDH,
+     $                          H( JCH+1, JCH+1 ), LDH, C, S )
+                     CALL CROT( ILASTM-JCH, T( JCH, JCH+1 ), LDT,
+     $                          T( JCH+1, JCH+1 ), LDT, C, S )
+                     IF( ILQ )
+     $                  CALL CROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, CONJG( S ) )
+                     IF( ILAZR2 )
+     $                  H( JCH, JCH-1 ) = H( JCH, JCH-1 )*C
+                     ILAZR2 = .FALSE.
+                     IF( ABS1( T( JCH+1, JCH+1 ) ).GE.BTOL ) THEN
+                        IF( JCH+1.GE.ILAST ) THEN
+                           GO TO 60
+                        ELSE
+                           IFIRST = JCH + 1
+                           GO TO 70
+                        END IF
+                     END IF
+                     T( JCH+1, JCH+1 ) = CZERO
+   20             CONTINUE
+                  GO TO 50
+               ELSE
+*
+*                 Only test 2 passed -- chase the zero to T(ILAST,ILAST)
+*                 Then process as in the case T(ILAST,ILAST)=0
+*
+                  DO 30 JCH = J, ILAST - 1
+                     CTEMP = T( JCH, JCH+1 )
+                     CALL CLARTG( CTEMP, T( JCH+1, JCH+1 ), C, S,
+     $                            T( JCH, JCH+1 ) )
+                     T( JCH+1, JCH+1 ) = CZERO
+                     IF( JCH.LT.ILASTM-1 )
+     $                  CALL CROT( ILASTM-JCH-1, T( JCH, JCH+2 ), LDT,
+     $                             T( JCH+1, JCH+2 ), LDT, C, S )
+                     CALL CROT( ILASTM-JCH+2, H( JCH, JCH-1 ), LDH,
+     $                          H( JCH+1, JCH-1 ), LDH, C, S )
+                     IF( ILQ )
+     $                  CALL CROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, CONJG( S ) )
+                     CTEMP = H( JCH+1, JCH )
+                     CALL CLARTG( CTEMP, H( JCH+1, JCH-1 ), C, S,
+     $                            H( JCH+1, JCH ) )
+                     H( JCH+1, JCH-1 ) = CZERO
+                     CALL CROT( JCH+1-IFRSTM, H( IFRSTM, JCH ), 1,
+     $                          H( IFRSTM, JCH-1 ), 1, C, S )
+                     CALL CROT( JCH-IFRSTM, T( IFRSTM, JCH ), 1,
+     $                          T( IFRSTM, JCH-1 ), 1, C, S )
+                     IF( ILZ )
+     $                  CALL CROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,
+     $                             C, S )
+   30             CONTINUE
+                  GO TO 50
+               END IF
+            ELSE IF( ILAZRO ) THEN
+*
+*              Only test 1 passed -- work on J:ILAST
+*
+               IFIRST = J
+               GO TO 70
+            END IF
+*
+*           Neither test passed -- try next J
+*
+   40    CONTINUE
+*
+*        (Drop-through is "impossible")
+*
+         INFO = 2*N + 1
+         GO TO 210
+*
+*        T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a
+*        1x1 block.
+*
+   50    CONTINUE
+         CTEMP = H( ILAST, ILAST )
+         CALL CLARTG( CTEMP, H( ILAST, ILAST-1 ), C, S,
+     $                H( ILAST, ILAST ) )
+         H( ILAST, ILAST-1 ) = CZERO
+         CALL CROT( ILAST-IFRSTM, H( IFRSTM, ILAST ), 1,
+     $              H( IFRSTM, ILAST-1 ), 1, C, S )
+         CALL CROT( ILAST-IFRSTM, T( IFRSTM, ILAST ), 1,
+     $              T( IFRSTM, ILAST-1 ), 1, C, S )
+         IF( ILZ )
+     $      CALL CROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )
+*
+*        H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHA and BETA
+*
+   60    CONTINUE
+         ABSB = ABS( T( ILAST, ILAST ) )
+         IF( ABSB.GT.SAFMIN ) THEN
+            SIGNBC = CONJG( T( ILAST, ILAST ) / ABSB )
+            T( ILAST, ILAST ) = ABSB
+            IF( ILSCHR ) THEN
+               CALL CSCAL( ILAST-IFRSTM, SIGNBC, T( IFRSTM, ILAST ), 1 )
+               CALL CSCAL( ILAST+1-IFRSTM, SIGNBC, H( IFRSTM, ILAST ),
+     $                     1 )
+            ELSE
+               H( ILAST, ILAST ) = H( ILAST, ILAST )*SIGNBC
+            END IF
+            IF( ILZ )
+     $         CALL CSCAL( N, SIGNBC, Z( 1, ILAST ), 1 )
+         ELSE
+            T( ILAST, ILAST ) = CZERO
+         END IF
+         ALPHA( ILAST ) = H( ILAST, ILAST )
+         BETA( ILAST ) = T( ILAST, ILAST )
+*
+*        Go to next block -- exit if finished.
+*
+         ILAST = ILAST - 1
+         IF( ILAST.LT.ILO )
+     $      GO TO 190
+*
+*        Reset counters
+*
+         IITER = 0
+         ESHIFT = CZERO
+         IF( .NOT.ILSCHR ) THEN
+            ILASTM = ILAST
+            IF( IFRSTM.GT.ILAST )
+     $         IFRSTM = ILO
+         END IF
+         GO TO 160
+*
+*        QZ step
+*
+*        This iteration only involves rows/columns IFIRST:ILAST.  We
+*        assume IFIRST < ILAST, and that the diagonal of B is non-zero.
+*
+   70    CONTINUE
+         IITER = IITER + 1
+         IF( .NOT.ILSCHR ) THEN
+            IFRSTM = IFIRST
+         END IF
+*
+*        Compute the Shift.
+*
+*        At this point, IFIRST < ILAST, and the diagonal elements of
+*        T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in
+*        magnitude)
+*
+         IF( ( IITER / 10 )*10.NE.IITER ) THEN
+*
+*           The Wilkinson shift (AEP p.512), i.e., the eigenvalue of
+*           the bottom-right 2x2 block of A inv(B) which is nearest to
+*           the bottom-right element.
+*
+*           We factor B as U*D, where U has unit diagonals, and
+*           compute (A*inv(D))*inv(U).
+*
+            U12 = ( BSCALE*T( ILAST-1, ILAST ) ) /
+     $            ( BSCALE*T( ILAST, ILAST ) )
+            AD11 = ( ASCALE*H( ILAST-1, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD21 = ( ASCALE*H( ILAST, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD12 = ( ASCALE*H( ILAST-1, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            AD22 = ( ASCALE*H( ILAST, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            ABI22 = AD22 - U12*AD21
+*
+            T1 = HALF*( AD11+ABI22 )
+            RTDISC = SQRT( T1**2+AD12*AD21-AD11*AD22 )
+            TEMP = REAL( T1-ABI22 )*REAL( RTDISC ) +
+     $             AIMAG( T1-ABI22 )*AIMAG( RTDISC )
+            IF( TEMP.LE.ZERO ) THEN
+               SHIFT = T1 + RTDISC
+            ELSE
+               SHIFT = T1 - RTDISC
+            END IF
+         ELSE
+*
+*           Exceptional shift.  Chosen for no particularly good reason.
+*
+            ESHIFT = ESHIFT + CONJG( ( ASCALE*H( ILAST-1, ILAST ) ) /
+     $               ( BSCALE*T( ILAST-1, ILAST-1 ) ) )
+            SHIFT = ESHIFT
+         END IF
+*
+*        Now check for two consecutive small subdiagonals.
+*
+         DO 80 J = ILAST - 1, IFIRST + 1, -1
+            ISTART = J
+            CTEMP = ASCALE*H( J, J ) - SHIFT*( BSCALE*T( J, J ) )
+            TEMP = ABS1( CTEMP )
+            TEMP2 = ASCALE*ABS1( H( J+1, J ) )
+            TEMPR = MAX( TEMP, TEMP2 )
+            IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
+               TEMP = TEMP / TEMPR
+               TEMP2 = TEMP2 / TEMPR
+            END IF
+            IF( ABS1( H( J, J-1 ) )*TEMP2.LE.TEMP*ATOL )
+     $         GO TO 90
+   80    CONTINUE
+*
+         ISTART = IFIRST
+         CTEMP = ASCALE*H( IFIRST, IFIRST ) -
+     $           SHIFT*( BSCALE*T( IFIRST, IFIRST ) )
+   90    CONTINUE
+*
+*        Do an implicit-shift QZ sweep.
+*
+*        Initial Q
+*
+         CTEMP2 = ASCALE*H( ISTART+1, ISTART )
+         CALL CLARTG( CTEMP, CTEMP2, C, S, CTEMP3 )
+*
+*        Sweep
+*
+         DO 150 J = ISTART, ILAST - 1
+            IF( J.GT.ISTART ) THEN
+               CTEMP = H( J, J-1 )
+               CALL CLARTG( CTEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
+               H( J+1, J-1 ) = CZERO
+            END IF
+*
+            DO 100 JC = J, ILASTM
+               CTEMP = C*H( J, JC ) + S*H( J+1, JC )
+               H( J+1, JC ) = -CONJG( S )*H( J, JC ) + C*H( J+1, JC )
+               H( J, JC ) = CTEMP
+               CTEMP2 = C*T( J, JC ) + S*T( J+1, JC )
+               T( J+1, JC ) = -CONJG( S )*T( J, JC ) + C*T( J+1, JC )
+               T( J, JC ) = CTEMP2
+  100       CONTINUE
+            IF( ILQ ) THEN
+               DO 110 JR = 1, N
+                  CTEMP = C*Q( JR, J ) + CONJG( S )*Q( JR, J+1 )
+                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
+                  Q( JR, J ) = CTEMP
+  110          CONTINUE
+            END IF
+*
+            CTEMP = T( J+1, J+1 )
+            CALL CLARTG( CTEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
+            T( J+1, J ) = CZERO
+*
+            DO 120 JR = IFRSTM, MIN( J+2, ILAST )
+               CTEMP = C*H( JR, J+1 ) + S*H( JR, J )
+               H( JR, J ) = -CONJG( S )*H( JR, J+1 ) + C*H( JR, J )
+               H( JR, J+1 ) = CTEMP
+  120       CONTINUE
+            DO 130 JR = IFRSTM, J
+               CTEMP = C*T( JR, J+1 ) + S*T( JR, J )
+               T( JR, J ) = -CONJG( S )*T( JR, J+1 ) + C*T( JR, J )
+               T( JR, J+1 ) = CTEMP
+  130       CONTINUE
+            IF( ILZ ) THEN
+               DO 140 JR = 1, N
+                  CTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
+                  Z( JR, J ) = -CONJG( S )*Z( JR, J+1 ) + C*Z( JR, J )
+                  Z( JR, J+1 ) = CTEMP
+  140          CONTINUE
+            END IF
+  150    CONTINUE
+*
+  160    CONTINUE
+*
+  170 CONTINUE
+*
+*     Drop-through = non-convergence
+*
+  180 CONTINUE
+      INFO = ILAST
+      GO TO 210
+*
+*     Successful completion of all QZ steps
+*
+  190 CONTINUE
+*
+*     Set Eigenvalues 1:ILO-1
+*
+      DO 200 J = 1, ILO - 1
+         ABSB = ABS( T( J, J ) )
+         IF( ABSB.GT.SAFMIN ) THEN
+            SIGNBC = CONJG( T( J, J ) / ABSB )
+            T( J, J ) = ABSB
+            IF( ILSCHR ) THEN
+               CALL CSCAL( J-1, SIGNBC, T( 1, J ), 1 )
+               CALL CSCAL( J, SIGNBC, H( 1, J ), 1 )
+            ELSE
+               H( J, J ) = H( J, J )*SIGNBC
+            END IF
+            IF( ILZ )
+     $         CALL CSCAL( N, SIGNBC, Z( 1, J ), 1 )
+         ELSE
+            T( J, J ) = CZERO
+         END IF
+         ALPHA( J ) = H( J, J )
+         BETA( J ) = T( J, J )
+  200 CONTINUE
+*
+*     Normal Termination
+*
+      INFO = 0
+*
+*     Exit (other than argument error) -- return optimal workspace size
+*
+  210 CONTINUE
+      WORK( 1 ) = CMPLX( N )
+      RETURN
+*
+*     End of CHGEQZ
+*
+      END
diff --git a/libcruft/lapack/chseqr.f b/libcruft/lapack/chseqr.f
new file mode 100644
index 0000000..42977fd
--- /dev/null
+++ b/libcruft/lapack/chseqr.f
@@ -0,0 +1,395 @@
+      SUBROUTINE CHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, W, Z, LDZ,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDH, LDZ, LWORK, N
+      CHARACTER          COMPZ, JOB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*     Purpose
+*     =======
+*
+*     CHSEQR computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**H, where T is an upper triangular matrix (the
+*     Schur form), and Z is the unitary matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input unitary
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*H*(QZ)**H.
+*
+*     Arguments
+*     =========
+*
+*     JOB   (input) CHARACTER*1
+*           = 'E':  compute eigenvalues only;
+*           = 'S':  compute eigenvalues and the Schur form T.
+*
+*     COMPZ (input) CHARACTER*1
+*           = 'N':  no Schur vectors are computed;
+*           = 'I':  Z is initialized to the unit matrix and the matrix Z
+*                   of Schur vectors of H is returned;
+*           = 'V':  Z must contain an unitary matrix Q on entry, and
+*                   the product Q*Z is returned.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*           set by a previous call to CGEBAL, and then passed to CGEHRD
+*           when the matrix output by CGEBAL is reduced to Hessenberg
+*           form. Otherwise ILO and IHI should be set to 1 and N
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) COMPLEX array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and JOB = 'S', H contains the upper
+*           triangular matrix T from the Schur decomposition (the
+*           Schur form). If INFO = 0 and JOB = 'E', the contents of
+*           H are unspecified on exit.  (The output value of H when
+*           INFO.GT.0 is given under the description of INFO below.)
+*
+*           Unlike earlier versions of CHSEQR, this subroutine may
+*           explicitly H(i,j) = 0 for i.GT.j and j = 1, 2, ... ILO-1
+*           or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     W        (output) COMPLEX array, dimension (N)
+*           The computed eigenvalues. If JOB = 'S', the eigenvalues are
+*           stored in the same order as on the diagonal of the Schur
+*           form returned in H, with W(i) = H(i,i).
+*
+*     Z     (input/output) COMPLEX array, dimension (LDZ,N)
+*           If COMPZ = 'N', Z is not referenced.
+*           If COMPZ = 'I', on entry Z need not be set and on exit,
+*           if INFO = 0, Z contains the unitary matrix Z of the Schur
+*           vectors of H.  If COMPZ = 'V', on entry Z must contain an
+*           N-by-N matrix Q, which is assumed to be equal to the unit
+*           matrix except for the submatrix Z(ILO:IHI,ILO:IHI). On exit,
+*           if INFO = 0, Z contains Q*Z.
+*           Normally Q is the unitary matrix generated by CUNGHR
+*           after the call to CGEHRD which formed the Hessenberg matrix
+*           H. (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if COMPZ = 'I' or
+*           COMPZ = 'V', then LDZ.GE.MAX(1,N).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) COMPLEX array, dimension (LWORK)
+*           On exit, if INFO = 0, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then CHSEQR does a workspace query.
+*           In this case, CHSEQR checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .LT. 0:  if INFO = -i, the i-th argument had an illegal
+*                    value
+*           .GT. 0:  if INFO = i, CHSEQR failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and JOB = 'E', then on exit, the
+*                remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and JOB   = 'S', then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is a unitary matrix.  The final
+*                value of  H is upper Hessenberg and triangular in
+*                rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and COMPZ = 'V', then on exit
+*
+*                  (final value of Z)  =  (initial value of Z)*U
+*
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'I', then on exit
+*                      (final value of Z)  = U
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'N', then Z is not
+*                accessed.
+*
+*     ================================================================
+*             Default values supplied by
+*             ILAENV(ISPEC,'CHSEQR',JOB(:1)//COMPZ(:1),N,ILO,IHI,LWORK).
+*             It is suggested that these defaults be adjusted in order
+*             to attain best performance in each particular
+*             computational environment.
+*
+*            ISPEC=1:  The CLAHQR vs CLAQR0 crossover point.
+*                      Default: 75. (Must be at least 11.)
+*
+*            ISPEC=2:  Recommended deflation window size.
+*                      This depends on ILO, IHI and NS.  NS is the
+*                      number of simultaneous shifts returned
+*                      by ILAENV(ISPEC=4).  (See ISPEC=4 below.)
+*                      The default for (IHI-ILO+1).LE.500 is NS.
+*                      The default for (IHI-ILO+1).GT.500 is 3*NS/2.
+*
+*            ISPEC=3:  Nibble crossover point. (See ILAENV for
+*                      details.)  Default: 14% of deflation window
+*                      size.
+*
+*            ISPEC=4:  Number of simultaneous shifts, NS, in
+*                      a multi-shift QR iteration.
+*
+*                      If IHI-ILO+1 is ...
+*
+*                      greater than      ...but less    ... the
+*                      or equal to ...      than        default is
+*
+*                           1               30          NS -   2(+)
+*                          30               60          NS -   4(+)
+*                          60              150          NS =  10(+)
+*                         150              590          NS =  **
+*                         590             3000          NS =  64
+*                        3000             6000          NS = 128
+*                        6000             infinity      NS = 256
+*
+*                  (+)  By default some or all matrices of this order 
+*                       are passed to the implicit double shift routine
+*                       CLAHQR and NS is ignored.  See ISPEC=1 above 
+*                       and comments in IPARM for details.
+*
+*                       The asterisks (**) indicate an ad-hoc
+*                       function of N increasing from 10 to 64.
+*
+*            ISPEC=5:  Select structured matrix multiply.
+*                      (See ILAENV for details.) Default: 3.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    CLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== NL allocates some local workspace to help small matrices
+*     .    through a rare CLAHQR failure.  NL .GT. NTINY = 11 is
+*     .    required and NL .LE. NMIN = ILAENV(ISPEC=1,...) is recom-
+*     .    mended.  (The default value of NMIN is 75.)  Using NL = 49
+*     .    allows up to six simultaneous shifts and a 16-by-16
+*     .    deflation window.  ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            NL
+      PARAMETER          ( NL = 49 )
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               RZERO
+      PARAMETER          ( RZERO = 0.0e0 )
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            HL( NL, NL ), WORKL( NL )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            KBOT, NMIN
+      LOGICAL            INITZ, LQUERY, WANTT, WANTZ
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      LOGICAL            LSAME
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CLACPY, CLAHQR, CLAQR0, CLASET, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CMPLX, MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Decode and check the input parameters. ====
+*
+      WANTT = LSAME( JOB, 'S' )
+      INITZ = LSAME( COMPZ, 'I' )
+      WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )
+      WORK( 1 ) = CMPLX( REAL( MAX( 1, N ) ), RZERO )
+      LQUERY = LWORK.EQ.-1
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( LDH.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+*
+*        ==== Quick return in case of invalid argument. ====
+*
+         CALL XERBLA( 'CHSEQR', -INFO )
+         RETURN
+*
+      ELSE IF( N.EQ.0 ) THEN
+*
+*        ==== Quick return in case N = 0; nothing to do. ====
+*
+         RETURN
+*
+      ELSE IF( LQUERY ) THEN
+*
+*        ==== Quick return in case of a workspace query ====
+*
+         CALL CLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI, Z,
+     $                LDZ, WORK, LWORK, INFO )
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+         WORK( 1 ) = CMPLX( MAX( REAL( WORK( 1 ) ), REAL( MAX( 1,
+     $               N ) ) ), RZERO )
+         RETURN
+*
+      ELSE
+*
+*        ==== copy eigenvalues isolated by CGEBAL ====
+*
+         IF( ILO.GT.1 )
+     $      CALL CCOPY( ILO-1, H, LDH+1, W, 1 )
+         IF( IHI.LT.N )
+     $      CALL CCOPY( N-IHI, H( IHI+1, IHI+1 ), LDH+1, W( IHI+1 ), 1 )
+*
+*        ==== Initialize Z, if requested ====
+*
+         IF( INITZ )
+     $      CALL CLASET( 'A', N, N, ZERO, ONE, Z, LDZ )
+*
+*        ==== Quick return if possible ====
+*
+         IF( ILO.EQ.IHI ) THEN
+            W( ILO ) = H( ILO, ILO )
+            RETURN
+         END IF
+*
+*        ==== CLAHQR/CLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 1, 'CHSEQR', JOB( : 1 ) // COMPZ( : 1 ), N, ILO,
+     $          IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== CLAQR0 for big matrices; CLAHQR for small ones ====
+*
+         IF( N.GT.NMIN ) THEN
+            CALL CLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI,
+     $                   Z, LDZ, WORK, LWORK, INFO )
+         ELSE
+*
+*           ==== Small matrix ====
+*
+            CALL CLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI,
+     $                   Z, LDZ, INFO )
+*
+            IF( INFO.GT.0 ) THEN
+*
+*              ==== A rare CLAHQR failure!  CLAQR0 sometimes succeeds
+*              .    when CLAHQR fails. ====
+*
+               KBOT = INFO
+*
+               IF( N.GE.NL ) THEN
+*
+*                 ==== Larger matrices have enough subdiagonal scratch
+*                 .    space to call CLAQR0 directly. ====
+*
+                  CALL CLAQR0( WANTT, WANTZ, N, ILO, KBOT, H, LDH, W,
+     $                         ILO, IHI, Z, LDZ, WORK, LWORK, INFO )
+*
+               ELSE
+*
+*                 ==== Tiny matrices don't have enough subdiagonal
+*                 .    scratch space to benefit from CLAQR0.  Hence,
+*                 .    tiny matrices must be copied into a larger
+*                 .    array before calling CLAQR0. ====
+*
+                  CALL CLACPY( 'A', N, N, H, LDH, HL, NL )
+                  HL( N+1, N ) = ZERO
+                  CALL CLASET( 'A', NL, NL-N, ZERO, ZERO, HL( 1, N+1 ),
+     $                         NL )
+                  CALL CLAQR0( WANTT, WANTZ, NL, ILO, KBOT, HL, NL, W,
+     $                         ILO, IHI, Z, LDZ, WORKL, NL, INFO )
+                  IF( WANTT .OR. INFO.NE.0 )
+     $               CALL CLACPY( 'A', N, N, HL, NL, H, LDH )
+               END IF
+            END IF
+         END IF
+*
+*        ==== Clear out the trash, if necessary. ====
+*
+         IF( ( WANTT .OR. INFO.NE.0 ) .AND. N.GT.2 )
+     $      CALL CLASET( 'L', N-2, N-2, ZERO, ZERO, H( 3, 1 ), LDH )
+*
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+*
+         WORK( 1 ) = CMPLX( MAX( REAL( MAX( 1, N ) ),
+     $               REAL( WORK( 1 ) ) ), RZERO )
+      END IF
+*
+*     ==== End of CHSEQR ====
+*
+      END
diff --git a/libcruft/lapack/clabrd.f b/libcruft/lapack/clabrd.f
new file mode 100644
index 0000000..fd656f9
--- /dev/null
+++ b/libcruft/lapack/clabrd.f
@@ -0,0 +1,328 @@
+      SUBROUTINE CLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,
+     $                   LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, LDX, LDY, M, N, NB
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+      COMPLEX            A( LDA, * ), TAUP( * ), TAUQ( * ), X( LDX, * ),
+     $                   Y( LDY, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLABRD reduces the first NB rows and columns of a complex general
+*  m by n matrix A to upper or lower real bidiagonal form by a unitary
+*  transformation Q' * A * P, and returns the matrices X and Y which
+*  are needed to apply the transformation to the unreduced part of A.
+*
+*  If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower
+*  bidiagonal form.
+*
+*  This is an auxiliary routine called by CGEBRD
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of leading rows and columns of A to be reduced.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit, the first NB rows and columns of the matrix are
+*          overwritten; the rest of the array is unchanged.
+*          If m >= n, elements on and below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the unitary
+*            matrix Q as a product of elementary reflectors; and
+*            elements above the diagonal in the first NB rows, with the
+*            array TAUP, represent the unitary matrix P as a product
+*            of elementary reflectors.
+*          If m < n, elements below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the unitary
+*            matrix Q as a product of elementary reflectors, and
+*            elements on and above the diagonal in the first NB rows,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) REAL array, dimension (NB)
+*          The diagonal elements of the first NB rows and columns of
+*          the reduced matrix.  D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (NB)
+*          The off-diagonal elements of the first NB rows and columns of
+*          the reduced matrix.
+*
+*  TAUQ    (output) COMPLEX array dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix Q. See Further Details.
+*
+*  TAUP    (output) COMPLEX array, dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix P. See Further Details.
+*
+*  X       (output) COMPLEX array, dimension (LDX,NB)
+*          The m-by-nb matrix X required to update the unreduced part
+*          of A.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of the array X. LDX >= max(1,M).
+*
+*  Y       (output) COMPLEX array, dimension (LDY,NB)
+*          The n-by-nb matrix Y required to update the unreduced part
+*          of A.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*     Q = H(1) H(2) . . . H(nb)  and  P = G(1) G(2) . . . G(nb)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors.
+*
+*  If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in
+*  A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in
+*  A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The elements of the vectors v and u together form the m-by-nb matrix
+*  V and the nb-by-n matrix U' which are needed, with X and Y, to apply
+*  the transformation to the unreduced part of the matrix, using a block
+*  update of the form:  A := A - V*Y' - X*U'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with nb = 2:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  1   1   u1  u1  u1 )           (  1   u1  u1  u1  u1  u1 )
+*    (  v1  1   1   u2  u2 )           (  1   1   u2  u2  u2  u2 )
+*    (  v1  v2  a   a   a  )           (  v1  1   a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )
+*
+*  where a denotes an element of the original matrix which is unchanged,
+*  vi denotes an element of the vector defining H(i), and ui an element
+*  of the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CLACGV, CLARFG, CSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, NB
+*
+*           Update A(i:m,i)
+*
+            CALL CLACGV( I-1, Y( I, 1 ), LDY )
+            CALL CGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 )
+            CALL CLACGV( I-1, Y( I, 1 ), LDY )
+            CALL CGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ),
+     $                  LDX, A( 1, I ), 1, ONE, A( I, I ), 1 )
+*
+*           Generate reflection Q(i) to annihilate A(i+1:m,i)
+*
+            ALPHA = A( I, I )
+            CALL CLARFG( M-I+1, ALPHA, A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = ALPHA
+            IF( I.LT.N ) THEN
+               A( I, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL CGEMV( 'Conjugate transpose', M-I+1, N-I, ONE,
+     $                     A( I, I+1 ), LDA, A( I, I ), 1, ZERO,
+     $                     Y( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', M-I+1, I-1, ONE,
+     $                     A( I, 1 ), LDA, A( I, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', M-I+1, I-1, ONE,
+     $                     X( I, 1 ), LDX, A( I, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', I-1, N-I, -ONE,
+     $                     A( 1, I+1 ), LDA, Y( 1, I ), 1, ONE,
+     $                     Y( I+1, I ), 1 )
+               CALL CSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+*
+*              Update A(i,i+1:n)
+*
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+               CALL CLACGV( I, A( I, 1 ), LDA )
+               CALL CGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ),
+     $                     LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA )
+               CALL CLACGV( I, A( I, 1 ), LDA )
+               CALL CLACGV( I-1, X( I, 1 ), LDX )
+               CALL CGEMV( 'Conjugate transpose', I-1, N-I, -ONE,
+     $                     A( 1, I+1 ), LDA, X( I, 1 ), LDX, ONE,
+     $                     A( I, I+1 ), LDA )
+               CALL CLACGV( I-1, X( I, 1 ), LDX )
+*
+*              Generate reflection P(i) to annihilate A(i,i+2:n)
+*
+               ALPHA = A( I, I+1 )
+               CALL CLARFG( N-I, ALPHA, A( I, MIN( I+2, N ) ),
+     $                      LDA, TAUP( I ) )
+               E( I ) = ALPHA
+               A( I, I+1 ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL CGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', N-I, I, ONE,
+     $                     Y( I+1, 1 ), LDY, A( I, I+1 ), LDA, ZERO,
+     $                     X( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL CGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL CSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i,i:n)
+*
+            CALL CLACGV( N-I+1, A( I, I ), LDA )
+            CALL CLACGV( I-1, A( I, 1 ), LDA )
+            CALL CGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ),
+     $                  LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA )
+            CALL CLACGV( I-1, A( I, 1 ), LDA )
+            CALL CLACGV( I-1, X( I, 1 ), LDX )
+            CALL CGEMV( 'Conjugate transpose', I-1, N-I+1, -ONE,
+     $                  A( 1, I ), LDA, X( I, 1 ), LDX, ONE, A( I, I ),
+     $                  LDA )
+            CALL CLACGV( I-1, X( I, 1 ), LDX )
+*
+*           Generate reflection P(i) to annihilate A(i,i+1:n)
+*
+            ALPHA = A( I, I )
+            CALL CLARFG( N-I+1, ALPHA, A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = ALPHA
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL CGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', N-I+1, I-1, ONE,
+     $                     Y( I, 1 ), LDY, A( I, I ), LDA, ZERO,
+     $                     X( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL CGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL CSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+               CALL CLACGV( N-I+1, A( I, I ), LDA )
+*
+*              Update A(i+1:m,i)
+*
+               CALL CLACGV( I-1, Y( I, 1 ), LDY )
+               CALL CGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 )
+               CALL CLACGV( I-1, Y( I, 1 ), LDY )
+               CALL CGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ),
+     $                     LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 )
+*
+*              Generate reflection Q(i) to annihilate A(i+2:m,i)
+*
+               ALPHA = A( I+1, I )
+               CALL CLARFG( M-I, ALPHA, A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = ALPHA
+               A( I+1, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL CGEMV( 'Conjugate transpose', M-I, N-I, ONE,
+     $                     A( I+1, I+1 ), LDA, A( I+1, I ), 1, ZERO,
+     $                     Y( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', M-I, I-1, ONE,
+     $                     A( I+1, 1 ), LDA, A( I+1, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', M-I, I, ONE,
+     $                     X( I+1, 1 ), LDX, A( I+1, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', I, N-I, -ONE,
+     $                     A( 1, I+1 ), LDA, Y( 1, I ), 1, ONE,
+     $                     Y( I+1, I ), 1 )
+               CALL CSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+            ELSE
+               CALL CLACGV( N-I+1, A( I, I ), LDA )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CLABRD
+*
+      END
diff --git a/libcruft/lapack/clacgv.f b/libcruft/lapack/clacgv.f
new file mode 100644
index 0000000..342d179
--- /dev/null
+++ b/libcruft/lapack/clacgv.f
@@ -0,0 +1,60 @@
+      SUBROUTINE CLACGV( N, X, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLACGV conjugates a complex vector of length N.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The length of the vector X.  N >= 0.
+*
+*  X       (input/output) COMPLEX array, dimension
+*                         (1+(N-1)*abs(INCX))
+*          On entry, the vector of length N to be conjugated.
+*          On exit, X is overwritten with conjg(X).
+*
+*  INCX    (input) INTEGER
+*          The spacing between successive elements of X.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IOFF
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( INCX.EQ.1 ) THEN
+         DO 10 I = 1, N
+            X( I ) = CONJG( X( I ) )
+   10    CONTINUE
+      ELSE
+         IOFF = 1
+         IF( INCX.LT.0 )
+     $      IOFF = 1 - ( N-1 )*INCX
+         DO 20 I = 1, N
+            X( IOFF ) = CONJG( X( IOFF ) )
+            IOFF = IOFF + INCX
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CLACGV
+*
+      END
diff --git a/libcruft/lapack/clacn2.f b/libcruft/lapack/clacn2.f
new file mode 100644
index 0000000..319833b
--- /dev/null
+++ b/libcruft/lapack/clacn2.f
@@ -0,0 +1,221 @@
+      SUBROUTINE CLACN2( N, V, X, EST, KASE, ISAVE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      REAL               EST
+*     ..
+*     .. Array Arguments ..
+      INTEGER            ISAVE( 3 )
+      COMPLEX            V( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLACN2 estimates the 1-norm of a square, complex matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) COMPLEX array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) COMPLEX array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         where A' is the conjugate transpose of A, and CLACN2 must be
+*         re-called with all the other parameters unchanged.
+*
+*  EST    (input/output) REAL
+*         On entry with KASE = 1 or 2 and ISAVE(1) = 3, EST should be
+*         unchanged from the previous call to CLACN2.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to CLACN2, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from CLACN2, KASE will again be 0.
+*
+*  ISAVE  (input/output) INTEGER array, dimension (3)
+*         ISAVE is used to save variables between calls to SLACN2
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named CONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  Last modified:  April, 1999
+*
+*  This is a thread safe version of CLACON, which uses the array ISAVE
+*  in place of a SAVE statement, as follows:
+*
+*     CLACON     CLACN2
+*      JUMP     ISAVE(1)
+*      J        ISAVE(2)
+*      ITER     ISAVE(3)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER              ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      REAL                 ONE,         TWO
+      PARAMETER          ( ONE = 1.0E0, TWO = 2.0E0 )
+      COMPLEX              CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E0, 0.0E0 ),
+     $                            CONE = ( 1.0E0, 0.0E0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, JLAST
+      REAL               ABSXI, ALTSGN, ESTOLD, SAFMIN, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            ICMAX1
+      REAL               SCSUM1, SLAMCH
+      EXTERNAL           ICMAX1, SCSUM1, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = CMPLX( ONE / REAL( N ) )
+   10    CONTINUE
+         KASE = 1
+         ISAVE( 1 ) = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 90, 120 )ISAVE( 1 )
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 130
+      END IF
+      EST = SCSUM1( N, X, 1 )
+*
+      DO 30 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = CMPLX( REAL( X( I ) ) / ABSXI,
+     $               AIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   30 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 2
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   40 CONTINUE
+      ISAVE( 2 ) = ICMAX1( N, X, 1 )
+      ISAVE( 3 ) = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = CZERO
+   60 CONTINUE
+      X( ISAVE( 2 ) ) = CONE
+      KASE = 1
+      ISAVE( 1 ) = 3
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL CCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = SCSUM1( N, V, 1 )
+*
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 100
+*
+      DO 80 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = CMPLX( REAL( X( I ) ) / ABSXI,
+     $               AIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   80 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 4
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 4)
+*     X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   90 CONTINUE
+      JLAST = ISAVE( 2 )
+      ISAVE( 2 ) = ICMAX1( N, X, 1 )
+      IF( ( ABS( X( JLAST ) ).NE.ABS( X( ISAVE( 2 ) ) ) ) .AND.
+     $    ( ISAVE( 3 ).LT.ITMAX ) ) THEN
+         ISAVE( 3 ) = ISAVE( 3 ) + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  100 CONTINUE
+      ALTSGN = ONE
+      DO 110 I = 1, N
+         X( I ) = CMPLX( ALTSGN*( ONE + REAL( I-1 ) / REAL( N-1 ) ) )
+         ALTSGN = -ALTSGN
+  110 CONTINUE
+      KASE = 1
+      ISAVE( 1 ) = 5
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  120 CONTINUE
+      TEMP = TWO*( SCSUM1( N, X, 1 ) / REAL( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL CCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  130 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of CLACN2
+*
+      END
diff --git a/libcruft/lapack/clacon.f b/libcruft/lapack/clacon.f
new file mode 100644
index 0000000..2228701
--- /dev/null
+++ b/libcruft/lapack/clacon.f
@@ -0,0 +1,212 @@
+      SUBROUTINE CLACON( N, V, X, EST, KASE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      REAL               EST
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            V( N ), X( N )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLACON estimates the 1-norm of a square, complex matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) COMPLEX array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) COMPLEX array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         where A' is the conjugate transpose of A, and CLACON must be
+*         re-called with all the other parameters unchanged.
+*
+*  EST    (input/output) REAL
+*         On entry with KASE = 1 or 2 and JUMP = 3, EST should be
+*         unchanged from the previous call to CLACON.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to CLACON, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from CLACON, KASE will again be 0.
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named CONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  Last modified:  April, 1999
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      REAL               ONE, TWO
+      PARAMETER          ( ONE = 1.0E0, TWO = 2.0E0 )
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E0, 0.0E0 ),
+     $                   CONE = ( 1.0E0, 0.0E0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITER, J, JLAST, JUMP
+      REAL               ABSXI, ALTSGN, ESTOLD, SAFMIN, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            ICMAX1
+      REAL               SCSUM1, SLAMCH
+      EXTERNAL           ICMAX1, SCSUM1, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, REAL
+*     ..
+*     .. Save statement ..
+      SAVE
+*     ..
+*     .. Executable Statements ..
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = CMPLX( ONE / REAL( N ) )
+   10    CONTINUE
+         KASE = 1
+         JUMP = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 90, 120 )JUMP
+*
+*     ................ ENTRY   (JUMP = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 130
+      END IF
+      EST = SCSUM1( N, X, 1 )
+*
+      DO 30 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = CMPLX( REAL( X( I ) ) / ABSXI,
+     $               AIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   30 CONTINUE
+      KASE = 2
+      JUMP = 2
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   40 CONTINUE
+      J = ICMAX1( N, X, 1 )
+      ITER = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = CZERO
+   60 CONTINUE
+      X( J ) = CONE
+      KASE = 1
+      JUMP = 3
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL CCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = SCSUM1( N, V, 1 )
+*
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 100
+*
+      DO 80 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = CMPLX( REAL( X( I ) ) / ABSXI,
+     $               AIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   80 CONTINUE
+      KASE = 2
+      JUMP = 4
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 4)
+*     X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   90 CONTINUE
+      JLAST = J
+      J = ICMAX1( N, X, 1 )
+      IF( ( ABS( X( JLAST ) ).NE.ABS( X( J ) ) ) .AND.
+     $    ( ITER.LT.ITMAX ) ) THEN
+         ITER = ITER + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  100 CONTINUE
+      ALTSGN = ONE
+      DO 110 I = 1, N
+         X( I ) = CMPLX( ALTSGN*( ONE+REAL( I-1 ) / REAL( N-1 ) ) )
+         ALTSGN = -ALTSGN
+  110 CONTINUE
+      KASE = 1
+      JUMP = 5
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  120 CONTINUE
+      TEMP = TWO*( SCSUM1( N, X, 1 ) / REAL( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL CCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  130 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of CLACON
+*
+      END
diff --git a/libcruft/lapack/clacpy.f b/libcruft/lapack/clacpy.f
new file mode 100644
index 0000000..4af4a78
--- /dev/null
+++ b/libcruft/lapack/clacpy.f
@@ -0,0 +1,90 @@
+      SUBROUTINE CLACPY( UPLO, M, N, A, LDA, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDB, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLACPY copies all or part of a two-dimensional matrix A to another
+*  matrix B.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be copied to B.
+*          = 'U':      Upper triangular part
+*          = 'L':      Lower triangular part
+*          Otherwise:  All of the matrix A
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The m by n matrix A.  If UPLO = 'U', only the upper trapezium
+*          is accessed; if UPLO = 'L', only the lower trapezium is
+*          accessed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (output) COMPLEX array, dimension (LDB,N)
+*          On exit, B = A in the locations specified by UPLO.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( J, M )
+               B( I, J ) = A( I, J )
+   10       CONTINUE
+   20    CONTINUE
+*
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+         DO 40 J = 1, N
+            DO 30 I = J, M
+               B( I, J ) = A( I, J )
+   30       CONTINUE
+   40    CONTINUE
+*
+      ELSE
+         DO 60 J = 1, N
+            DO 50 I = 1, M
+               B( I, J ) = A( I, J )
+   50       CONTINUE
+   60    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLACPY
+*
+      END
diff --git a/libcruft/lapack/cladiv.f b/libcruft/lapack/cladiv.f
new file mode 100644
index 0000000..9819faa
--- /dev/null
+++ b/libcruft/lapack/cladiv.f
@@ -0,0 +1,46 @@
+      COMPLEX FUNCTION CLADIV( X, Y )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      COMPLEX            X, Y
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLADIV := X / Y, where X and Y are complex.  The computation of X / Y
+*  will not overflow on an intermediary step unless the results
+*  overflows.
+*
+*  Arguments
+*  =========
+*
+*  X       (input) COMPLEX
+*  Y       (input) COMPLEX
+*          The complex scalars X and Y.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL               ZI, ZR
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLADIV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          AIMAG, CMPLX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+      CALL SLADIV( REAL( X ), AIMAG( X ), REAL( Y ), AIMAG( Y ), ZR,
+     $             ZI )
+      CLADIV = CMPLX( ZR, ZI )
+*
+      RETURN
+*
+*     End of CLADIV
+*
+      END
diff --git a/libcruft/lapack/clahqr.f b/libcruft/lapack/clahqr.f
new file mode 100644
index 0000000..5541ec8
--- /dev/null
+++ b/libcruft/lapack/clahqr.f
@@ -0,0 +1,469 @@
+      SUBROUTINE CLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), W( * ), Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     CLAHQR is an auxiliary routine called by CHSEQR to update the
+*     eigenvalues and Schur decomposition already computed by CHSEQR, by
+*     dealing with the Hessenberg submatrix in rows and columns ILO to
+*     IHI.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H.  N >= 0.
+*
+*     ILO     (input) INTEGER
+*     IHI     (input) INTEGER
+*          It is assumed that H is already upper triangular in rows and
+*          columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless ILO = 1).
+*          CLAHQR works primarily with the Hessenberg submatrix in rows
+*          and columns ILO to IHI, but applies transformations to all of
+*          H if WANTT is .TRUE..
+*          1 <= ILO <= max(1,IHI); IHI <= N.
+*
+*     H       (input/output) COMPLEX array, dimension (LDH,N)
+*          On entry, the upper Hessenberg matrix H.
+*          On exit, if INFO is zero and if WANTT is .TRUE., then H
+*          is upper triangular in rows and columns ILO:IHI.  If INFO
+*          is zero and if WANTT is .FALSE., then the contents of H
+*          are unspecified on exit.  The output state of H in case
+*          INF is positive is below under the description of INFO.
+*
+*     LDH     (input) INTEGER
+*          The leading dimension of the array H. LDH >= max(1,N).
+*
+*     W       (output) COMPLEX array, dimension (N)
+*          The computed eigenvalues ILO to IHI are stored in the
+*          corresponding elements of W. If WANTT is .TRUE., the
+*          eigenvalues are stored in the same order as on the diagonal
+*          of the Schur form returned in H, with W(i) = H(i,i).
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE..
+*          1 <= ILOZ <= ILO; IHI <= IHIZ <= N.
+*
+*     Z       (input/output) COMPLEX array, dimension (LDZ,N)
+*          If WANTZ is .TRUE., on entry Z must contain the current
+*          matrix Z of transformations accumulated by CHSEQR, and on
+*          exit Z has been updated; transformations are applied only to
+*          the submatrix Z(ILOZ:IHIZ,ILO:IHI).
+*          If WANTZ is .FALSE., Z is not referenced.
+*
+*     LDZ     (input) INTEGER
+*          The leading dimension of the array Z. LDZ >= max(1,N).
+*
+*     INFO    (output) INTEGER
+*           =   0: successful exit
+*          .GT. 0: if INFO = i, CLAHQR failed to compute all the
+*                  eigenvalues ILO to IHI in a total of 30 iterations
+*                  per eigenvalue; elements i+1:ihi of W contain
+*                  those eigenvalues which have been successfully
+*                  computed.
+*
+*                  If INFO .GT. 0 and WANTT is .FALSE., then on exit,
+*                  the remaining unconverged eigenvalues are the
+*                  eigenvalues of the upper Hessenberg matrix
+*                  rows and columns ILO thorugh INFO of the final,
+*                  output value of H.
+*
+*                  If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*          (*)       (initial value of H)*U  = U*(final value of H)
+*                  where U is an orthognal matrix.    The final
+*                  value of H is upper Hessenberg and triangular in
+*                  rows and columns INFO+1 through IHI.
+*
+*                  If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*                      (final value of Z)  = (initial value of Z)*U
+*                  where U is the orthogonal matrix in (*)
+*                  (regardless of the value of WANTT.)
+*
+*     Further Details
+*     ===============
+*
+*     02-96 Based on modifications by
+*     David Day, Sandia National Laboratory, USA
+*
+*     12-04 Further modifications by
+*     Ralph Byers, University of Kansas, USA
+*
+*       This is a modified version of CLAHQR from LAPACK version 3.0.
+*       It is (1) more robust against overflow and underflow and
+*       (2) adopts the more conservative Ahues & Tisseur stopping
+*       criterion (LAWN 122, 1997).
+*
+*     =========================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 30 )
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               RZERO, RONE, HALF
+      PARAMETER          ( RZERO = 0.0e0, RONE = 1.0e0, HALF = 0.5e0 )
+      REAL               DAT1
+      PARAMETER          ( DAT1 = 3.0e0 / 4.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            CDUM, H11, H11S, H22, SC, SUM, T, T1, TEMP, U,
+     $                   V2, X, Y
+      REAL               AA, AB, BA, BB, H10, H21, RTEMP, S, SAFMAX,
+     $                   SAFMIN, SMLNUM, SX, T2, TST, ULP
+      INTEGER            I, I1, I2, ITS, J, JHI, JLO, K, L, M, NH, NZ
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            V( 2 )
+*     ..
+*     .. External Functions ..
+      COMPLEX            CLADIV
+      REAL               SLAMCH
+      EXTERNAL           CLADIV, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CLARFG, CSCAL, SLABAD
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CONJG, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( ILO.EQ.IHI ) THEN
+         W( ILO ) = H( ILO, ILO )
+         RETURN
+      END IF
+*
+*     ==== clear out the trash ====
+      DO 10 J = ILO, IHI - 3
+         H( J+2, J ) = ZERO
+         H( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( ILO.LE.IHI-2 )
+     $   H( IHI, IHI-2 ) = ZERO
+*     ==== ensure that subdiagonal entries are real ====
+      DO 20 I = ILO + 1, IHI
+         IF( AIMAG( H( I, I-1 ) ).NE.RZERO ) THEN
+*           ==== The following redundant normalization
+*           .    avoids problems with both gradual and
+*           .    sudden underflow in ABS(H(I,I-1)) ====
+            SC = H( I, I-1 ) / CABS1( H( I, I-1 ) )
+            SC = CONJG( SC ) / ABS( SC )
+            H( I, I-1 ) = ABS( H( I, I-1 ) )
+            IF( WANTT ) THEN
+               JLO = 1
+               JHI = N
+            ELSE
+               JLO = ILO
+               JHI = IHI
+            END IF
+            CALL CSCAL( JHI-I+1, SC, H( I, I ), LDH )
+            CALL CSCAL( MIN( JHI, I+1 )-JLO+1, CONJG( SC ), H( JLO, I ),
+     $                  1 )
+            IF( WANTZ )
+     $         CALL CSCAL( IHIZ-ILOZ+1, CONJG( SC ), Z( ILOZ, I ), 1 )
+         END IF
+   20 CONTINUE
+*
+      NH = IHI - ILO + 1
+      NZ = IHIZ - ILOZ + 1
+*
+*     Set machine-dependent constants for the stopping criterion.
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( NH ) / ULP )
+*
+*     I1 and I2 are the indices of the first row and last column of H
+*     to which transformations must be applied. If eigenvalues only are
+*     being computed, I1 and I2 are set inside the main loop.
+*
+      IF( WANTT ) THEN
+         I1 = 1
+         I2 = N
+      END IF
+*
+*     The main loop begins here. I is the loop index and decreases from
+*     IHI to ILO in steps of 1. Each iteration of the loop works
+*     with the active submatrix in rows and columns L to I.
+*     Eigenvalues I+1 to IHI have already converged. Either L = ILO, or
+*     H(L,L-1) is negligible so that the matrix splits.
+*
+      I = IHI
+   30 CONTINUE
+      IF( I.LT.ILO )
+     $   GO TO 150
+*
+*     Perform QR iterations on rows and columns ILO to I until a
+*     submatrix of order 1 splits off at the bottom because a
+*     subdiagonal element has become negligible.
+*
+      L = ILO
+      DO 130 ITS = 0, ITMAX
+*
+*        Look for a single small subdiagonal element.
+*
+         DO 40 K = I, L + 1, -1
+            IF( CABS1( H( K, K-1 ) ).LE.SMLNUM )
+     $         GO TO 50
+            TST = CABS1( H( K-1, K-1 ) ) + CABS1( H( K, K ) )
+            IF( TST.EQ.ZERO ) THEN
+               IF( K-2.GE.ILO )
+     $            TST = TST + ABS( REAL( H( K-1, K-2 ) ) )
+               IF( K+1.LE.IHI )
+     $            TST = TST + ABS( REAL( H( K+1, K ) ) )
+            END IF
+*           ==== The following is a conservative small subdiagonal
+*           .    deflation criterion due to Ahues & Tisseur (LAWN 122,
+*           .    1997). It has better mathematical foundation and
+*           .    improves accuracy in some examples.  ====
+            IF( ABS( REAL( H( K, K-1 ) ) ).LE.ULP*TST ) THEN
+               AB = MAX( CABS1( H( K, K-1 ) ), CABS1( H( K-1, K ) ) )
+               BA = MIN( CABS1( H( K, K-1 ) ), CABS1( H( K-1, K ) ) )
+               AA = MAX( CABS1( H( K, K ) ),
+     $              CABS1( H( K-1, K-1 )-H( K, K ) ) )
+               BB = MIN( CABS1( H( K, K ) ),
+     $              CABS1( H( K-1, K-1 )-H( K, K ) ) )
+               S = AA + AB
+               IF( BA*( AB / S ).LE.MAX( SMLNUM,
+     $             ULP*( BB*( AA / S ) ) ) )GO TO 50
+            END IF
+   40    CONTINUE
+   50    CONTINUE
+         L = K
+         IF( L.GT.ILO ) THEN
+*
+*           H(L,L-1) is negligible
+*
+            H( L, L-1 ) = ZERO
+         END IF
+*
+*        Exit from loop if a submatrix of order 1 has split off.
+*
+         IF( L.GE.I )
+     $      GO TO 140
+*
+*        Now the active submatrix is in rows and columns L to I. If
+*        eigenvalues only are being computed, only the active submatrix
+*        need be transformed.
+*
+         IF( .NOT.WANTT ) THEN
+            I1 = L
+            I2 = I
+         END IF
+*
+         IF( ITS.EQ.10 .OR. ITS.EQ.20 ) THEN
+*
+*           Exceptional shift.
+*
+            S = DAT1*ABS( REAL( H( I, I-1 ) ) )
+            T = S + H( I, I )
+         ELSE
+*
+*           Wilkinson's shift.
+*
+            T = H( I, I )
+            U = SQRT( H( I-1, I ) )*SQRT( H( I, I-1 ) )
+            S = CABS1( U )
+            IF( S.NE.RZERO ) THEN
+               X = HALF*( H( I-1, I-1 )-T )
+               SX = CABS1( X )
+               S = MAX( S, CABS1( X ) )
+               Y = S*SQRT( ( X / S )**2+( U / S )**2 )
+               IF( SX.GT.RZERO ) THEN
+                  IF( REAL( X / SX )*REAL( Y )+AIMAG( X / SX )*
+     $                AIMAG( Y ).LT.RZERO )Y = -Y
+               END IF
+               T = T - U*CLADIV( U, ( X+Y ) )
+            END IF
+         END IF
+*
+*        Look for two consecutive small subdiagonal elements.
+*
+         DO 60 M = I - 1, L + 1, -1
+*
+*           Determine the effect of starting the single-shift QR
+*           iteration at row M, and see if this would make H(M,M-1)
+*           negligible.
+*
+            H11 = H( M, M )
+            H22 = H( M+1, M+1 )
+            H11S = H11 - T
+            H21 = H( M+1, M )
+            S = CABS1( H11S ) + ABS( H21 )
+            H11S = H11S / S
+            H21 = H21 / S
+            V( 1 ) = H11S
+            V( 2 ) = H21
+            H10 = H( M, M-1 )
+            IF( ABS( H10 )*ABS( H21 ).LE.ULP*
+     $          ( CABS1( H11S )*( CABS1( H11 )+CABS1( H22 ) ) ) )
+     $          GO TO 70
+   60    CONTINUE
+         H11 = H( L, L )
+         H22 = H( L+1, L+1 )
+         H11S = H11 - T
+         H21 = H( L+1, L )
+         S = CABS1( H11S ) + ABS( H21 )
+         H11S = H11S / S
+         H21 = H21 / S
+         V( 1 ) = H11S
+         V( 2 ) = H21
+   70    CONTINUE
+*
+*        Single-shift QR step
+*
+         DO 120 K = M, I - 1
+*
+*           The first iteration of this loop determines a reflection G
+*           from the vector V and applies it from left and right to H,
+*           thus creating a nonzero bulge below the subdiagonal.
+*
+*           Each subsequent iteration determines a reflection G to
+*           restore the Hessenberg form in the (K-1)th column, and thus
+*           chases the bulge one step toward the bottom of the active
+*           submatrix.
+*
+*           V(2) is always real before the call to CLARFG, and hence
+*           after the call T2 ( = T1*V(2) ) is also real.
+*
+            IF( K.GT.M )
+     $         CALL CCOPY( 2, H( K, K-1 ), 1, V, 1 )
+            CALL CLARFG( 2, V( 1 ), V( 2 ), 1, T1 )
+            IF( K.GT.M ) THEN
+               H( K, K-1 ) = V( 1 )
+               H( K+1, K-1 ) = ZERO
+            END IF
+            V2 = V( 2 )
+            T2 = REAL( T1*V2 )
+*
+*           Apply G from the left to transform the rows of the matrix
+*           in columns K to I2.
+*
+            DO 80 J = K, I2
+               SUM = CONJG( T1 )*H( K, J ) + T2*H( K+1, J )
+               H( K, J ) = H( K, J ) - SUM
+               H( K+1, J ) = H( K+1, J ) - SUM*V2
+   80       CONTINUE
+*
+*           Apply G from the right to transform the columns of the
+*           matrix in rows I1 to min(K+2,I).
+*
+            DO 90 J = I1, MIN( K+2, I )
+               SUM = T1*H( J, K ) + T2*H( J, K+1 )
+               H( J, K ) = H( J, K ) - SUM
+               H( J, K+1 ) = H( J, K+1 ) - SUM*CONJG( V2 )
+   90       CONTINUE
+*
+            IF( WANTZ ) THEN
+*
+*              Accumulate transformations in the matrix Z
+*
+               DO 100 J = ILOZ, IHIZ
+                  SUM = T1*Z( J, K ) + T2*Z( J, K+1 )
+                  Z( J, K ) = Z( J, K ) - SUM
+                  Z( J, K+1 ) = Z( J, K+1 ) - SUM*CONJG( V2 )
+  100          CONTINUE
+            END IF
+*
+            IF( K.EQ.M .AND. M.GT.L ) THEN
+*
+*              If the QR step was started at row M > L because two
+*              consecutive small subdiagonals were found, then extra
+*              scaling must be performed to ensure that H(M,M-1) remains
+*              real.
+*
+               TEMP = ONE - T1
+               TEMP = TEMP / ABS( TEMP )
+               H( M+1, M ) = H( M+1, M )*CONJG( TEMP )
+               IF( M+2.LE.I )
+     $            H( M+2, M+1 ) = H( M+2, M+1 )*TEMP
+               DO 110 J = M, I
+                  IF( J.NE.M+1 ) THEN
+                     IF( I2.GT.J )
+     $                  CALL CSCAL( I2-J, TEMP, H( J, J+1 ), LDH )
+                     CALL CSCAL( J-I1, CONJG( TEMP ), H( I1, J ), 1 )
+                     IF( WANTZ ) THEN
+                        CALL CSCAL( NZ, CONJG( TEMP ), Z( ILOZ, J ), 1 )
+                     END IF
+                  END IF
+  110          CONTINUE
+            END IF
+  120    CONTINUE
+*
+*        Ensure that H(I,I-1) is real.
+*
+         TEMP = H( I, I-1 )
+         IF( AIMAG( TEMP ).NE.RZERO ) THEN
+            RTEMP = ABS( TEMP )
+            H( I, I-1 ) = RTEMP
+            TEMP = TEMP / RTEMP
+            IF( I2.GT.I )
+     $         CALL CSCAL( I2-I, CONJG( TEMP ), H( I, I+1 ), LDH )
+            CALL CSCAL( I-I1, TEMP, H( I1, I ), 1 )
+            IF( WANTZ ) THEN
+               CALL CSCAL( NZ, TEMP, Z( ILOZ, I ), 1 )
+            END IF
+         END IF
+*
+  130 CONTINUE
+*
+*     Failure to converge in remaining number of iterations
+*
+      INFO = I
+      RETURN
+*
+  140 CONTINUE
+*
+*     H(I,I-1) is negligible: one eigenvalue has converged.
+*
+      W( I ) = H( I, I )
+*
+*     return to start of the main loop with new value of I.
+*
+      I = L - 1
+      GO TO 30
+*
+  150 CONTINUE
+      RETURN
+*
+*     End of CLAHQR
+*
+      END
diff --git a/libcruft/lapack/clahr2.f b/libcruft/lapack/clahr2.f
new file mode 100644
index 0000000..fcb4921
--- /dev/null
+++ b/libcruft/lapack/clahr2.f
@@ -0,0 +1,240 @@
+      SUBROUTINE CLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAHR2 reduces the first NB columns of A complex general n-BY-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by an unitary similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an auxiliary routine called by CGEHRD.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*          K < N.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) COMPLEX array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) COMPLEX array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's CLAHRD
+*  incorporating improvements proposed by Quintana-Orti and Van de
+*  Gejin. Note that the entries of A(1:K,2:NB) differ from those
+*  returned by the original LAPACK routine. This function is
+*  not backward compatible with LAPACK3.0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ), 
+     $                     ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CCOPY, CGEMM, CGEMV, CLACPY,
+     $                   CLARFG, CSCAL, CTRMM, CTRMV, CLACGV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(K+1:N,I)
+*
+*           Update I-th column of A - Y * V'
+*
+            CALL CLACGV( I-1, A( K+I-1, 1 ), LDA ) 
+            CALL CGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, Y(K+1,1), LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( K+1, I ), 1 )
+            CALL CLACGV( I-1, A( K+I-1, 1 ), LDA ) 
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL CCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL CTRMV( 'Lower', 'Conjugate transpose', 'UNIT', 
+     $                  I-1, A( K+1, 1 ),
+     $                  LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL CGEMV( 'Conjugate transpose', N-K-I+1, I-1, 
+     $                  ONE, A( K+I, 1 ),
+     $                  LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL CTRMV( 'Upper', 'Conjugate transpose', 'NON-UNIT', 
+     $                  I-1, T, LDT,
+     $                  T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL CGEMV( 'NO TRANSPOSE', N-K-I+1, I-1, -ONE, 
+     $                  A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL CTRMV( 'Lower', 'NO TRANSPOSE', 
+     $                  'UNIT', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL CAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(I) to annihilate
+*        A(K+I+1:N,I)
+*
+         CALL CLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         EI = A( K+I, I )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(K+1:N,I)
+*
+         CALL CGEMV( 'NO TRANSPOSE', N-K, N-K-I+1, 
+     $               ONE, A( K+1, I+1 ),
+     $               LDA, A( K+I, I ), 1, ZERO, Y( K+1, I ), 1 )
+         CALL CGEMV( 'Conjugate transpose', N-K-I+1, I-1, 
+     $               ONE, A( K+I, 1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, T( 1, I ), 1 )
+         CALL CGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, 
+     $               Y( K+1, 1 ), LDY,
+     $               T( 1, I ), 1, ONE, Y( K+1, I ), 1 )
+         CALL CSCAL( N-K, TAU( I ), Y( K+1, I ), 1 )
+*
+*        Compute T(1:I,I)
+*
+         CALL CSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL CTRMV( 'Upper', 'No Transpose', 'NON-UNIT', 
+     $               I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+*     Compute Y(1:K,1:NB)
+*
+      CALL CLACPY( 'ALL', K, NB, A( 1, 2 ), LDA, Y, LDY )
+      CALL CTRMM( 'RIGHT', 'Lower', 'NO TRANSPOSE', 
+     $            'UNIT', K, NB,
+     $            ONE, A( K+1, 1 ), LDA, Y, LDY )
+      IF( N.GT.K+NB )
+     $   CALL CGEMM( 'NO TRANSPOSE', 'NO TRANSPOSE', K, 
+     $               NB, N-K-NB, ONE,
+     $               A( 1, 2+NB ), LDA, A( K+1+NB, 1 ), LDA, ONE, Y,
+     $               LDY )
+      CALL CTRMM( 'RIGHT', 'Upper', 'NO TRANSPOSE', 
+     $            'NON-UNIT', K, NB,
+     $            ONE, T, LDT, Y, LDY )
+*
+      RETURN
+*
+*     End of CLAHR2
+*
+      END
diff --git a/libcruft/lapack/clahrd.f b/libcruft/lapack/clahrd.f
new file mode 100644
index 0000000..f8252e8
--- /dev/null
+++ b/libcruft/lapack/clahrd.f
@@ -0,0 +1,213 @@
+      SUBROUTINE CLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAHRD reduces the first NB columns of a complex general n-by-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by a unitary similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an OBSOLETE auxiliary routine. 
+*  This routine will be 'deprecated' in a  future release.
+*  Please use the new routine CLAHR2 instead.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) COMPLEX array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) COMPLEX array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CCOPY, CGEMV, CLACGV, CLARFG, CSCAL,
+     $                   CTRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(1:n,i)
+*
+*           Compute i-th column of A - Y * V'
+*
+            CALL CLACGV( I-1, A( K+I-1, 1 ), LDA )
+            CALL CGEMV( 'No transpose', N, I-1, -ONE, Y, LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( 1, I ), 1 )
+            CALL CLACGV( I-1, A( K+I-1, 1 ), LDA )
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL CCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL CTRMV( 'Lower', 'Conjugate transpose', 'Unit', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL CGEMV( 'Conjugate transpose', N-K-I+1, I-1, ONE,
+     $                  A( K+I, 1 ), LDA, A( K+I, I ), 1, ONE,
+     $                  T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL CTRMV( 'Upper', 'Conjugate transpose', 'Non-unit', I-1,
+     $                  T, LDT, T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL CGEMV( 'No transpose', N-K-I+1, I-1, -ONE, A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL CTRMV( 'Lower', 'No transpose', 'Unit', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL CAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(i) to annihilate
+*        A(k+i+1:n,i)
+*
+         EI = A( K+I, I )
+         CALL CLARFG( N-K-I+1, EI, A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(1:n,i)
+*
+         CALL CGEMV( 'No transpose', N, N-K-I+1, ONE, A( 1, I+1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, Y( 1, I ), 1 )
+         CALL CGEMV( 'Conjugate transpose', N-K-I+1, I-1, ONE,
+     $               A( K+I, 1 ), LDA, A( K+I, I ), 1, ZERO, T( 1, I ),
+     $               1 )
+         CALL CGEMV( 'No transpose', N, I-1, -ONE, Y, LDY, T( 1, I ), 1,
+     $               ONE, Y( 1, I ), 1 )
+         CALL CSCAL( N, TAU( I ), Y( 1, I ), 1 )
+*
+*        Compute T(1:i,i)
+*
+         CALL CSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL CTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+      RETURN
+*
+*     End of CLAHRD
+*
+      END
diff --git a/libcruft/lapack/claic1.f b/libcruft/lapack/claic1.f
new file mode 100644
index 0000000..a19ccb7
--- /dev/null
+++ b/libcruft/lapack/claic1.f
@@ -0,0 +1,295 @@
+      SUBROUTINE CLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            J, JOB
+      REAL               SEST, SESTPR
+      COMPLEX            C, GAMMA, S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            W( J ), X( J )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAIC1 applies one step of incremental condition estimation in
+*  its simplest version:
+*
+*  Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
+*  lower triangular matrix L, such that
+*           twonorm(L*x) = sest
+*  Then CLAIC1 computes sestpr, s, c such that
+*  the vector
+*                  [ s*x ]
+*           xhat = [  c  ]
+*  is an approximate singular vector of
+*                  [ L     0  ]
+*           Lhat = [ w' gamma ]
+*  in the sense that
+*           twonorm(Lhat*xhat) = sestpr.
+*
+*  Depending on JOB, an estimate for the largest or smallest singular
+*  value is computed.
+*
+*  Note that [s c]' and sestpr**2 is an eigenpair of the system
+*
+*      diag(sest*sest, 0) + [alpha  gamma] * [ conjg(alpha) ]
+*                                            [ conjg(gamma) ]
+*
+*  where  alpha =  conjg(x)'*w.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) INTEGER
+*          = 1: an estimate for the largest singular value is computed.
+*          = 2: an estimate for the smallest singular value is computed.
+*
+*  J       (input) INTEGER
+*          Length of X and W
+*
+*  X       (input) COMPLEX array, dimension (J)
+*          The j-vector x.
+*
+*  SEST    (input) REAL
+*          Estimated singular value of j by j matrix L
+*
+*  W       (input) COMPLEX array, dimension (J)
+*          The j-vector w.
+*
+*  GAMMA   (input) COMPLEX
+*          The diagonal element gamma.
+*
+*  SESTPR  (output) REAL
+*          Estimated singular value of (j+1) by (j+1) matrix Lhat.
+*
+*  S       (output) COMPLEX
+*          Sine needed in forming xhat.
+*
+*  C       (output) COMPLEX
+*          Cosine needed in forming xhat.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 )
+      REAL               HALF, FOUR
+      PARAMETER          ( HALF = 0.5E0, FOUR = 4.0E0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               ABSALP, ABSEST, ABSGAM, B, EPS, NORMA, S1, S2,
+     $                   SCL, T, TEST, TMP, ZETA1, ZETA2
+      COMPLEX            ALPHA, COSINE, SINE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, CONJG, MAX, SQRT
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      COMPLEX            CDOTC
+      EXTERNAL           SLAMCH, CDOTC
+*     ..
+*     .. Executable Statements ..
+*
+      EPS = SLAMCH( 'Epsilon' )
+      ALPHA = CDOTC( J, X, 1, W, 1 )
+*
+      ABSALP = ABS( ALPHA )
+      ABSGAM = ABS( GAMMA )
+      ABSEST = ABS( SEST )
+*
+      IF( JOB.EQ.1 ) THEN
+*
+*        Estimating largest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            S1 = MAX( ABSGAM, ABSALP )
+            IF( S1.EQ.ZERO ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = ZERO
+            ELSE
+               S = ALPHA / S1
+               C = GAMMA / S1
+               TMP = SQRT( S*CONJG( S )+C*CONJG( C ) )
+               S = S / TMP
+               C = C / TMP
+               SESTPR = S1*TMP
+            END IF
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ONE
+            C = ZERO
+            TMP = MAX( ABSEST, ABSALP )
+            S1 = ABSEST / TMP
+            S2 = ABSALP / TMP
+            SESTPR = TMP*SQRT( S1*S1+S2*S2 )
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            ELSE
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = S2*SCL
+               S = ( ALPHA / S2 ) / SCL
+               C = ( GAMMA / S2 ) / SCL
+            ELSE
+               TMP = S2 / S1
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = S1*SCL
+               S = ( ALPHA / S1 ) / SCL
+               C = ( GAMMA / S1 ) / SCL
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ABSALP / ABSEST
+            ZETA2 = ABSGAM / ABSEST
+*
+            B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
+            C = ZETA1*ZETA1
+            IF( B.GT.ZERO ) THEN
+               T = C / ( B+SQRT( B*B+C ) )
+            ELSE
+               T = SQRT( B*B+C ) - B
+            END IF
+*
+            SINE = -( ALPHA / ABSEST ) / T
+            COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
+            TMP = SQRT( SINE*CONJG( SINE )+COSINE*CONJG( COSINE ) )
+            S = SINE / TMP
+            C = COSINE / TMP
+            SESTPR = SQRT( T+ONE )*ABSEST
+            RETURN
+         END IF
+*
+      ELSE IF( JOB.EQ.2 ) THEN
+*
+*        Estimating smallest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            SESTPR = ZERO
+            IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
+               SINE = ONE
+               COSINE = ZERO
+            ELSE
+               SINE = -CONJG( GAMMA )
+               COSINE = CONJG( ALPHA )
+            END IF
+            S1 = MAX( ABS( SINE ), ABS( COSINE ) )
+            S = SINE / S1
+            C = COSINE / S1
+            TMP = SQRT( S*CONJG( S )+C*CONJG( C ) )
+            S = S / TMP
+            C = C / TMP
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ZERO
+            C = ONE
+            SESTPR = ABSGAM
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            ELSE
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST*( TMP / SCL )
+               S = -( CONJG( GAMMA ) / S2 ) / SCL
+               C = ( CONJG( ALPHA ) / S2 ) / SCL
+            ELSE
+               TMP = S2 / S1
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST / SCL
+               S = -( CONJG( GAMMA ) / S1 ) / SCL
+               C = ( CONJG( ALPHA ) / S1 ) / SCL
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ABSALP / ABSEST
+            ZETA2 = ABSGAM / ABSEST
+*
+            NORMA = MAX( ONE+ZETA1*ZETA1+ZETA1*ZETA2,
+     $              ZETA1*ZETA2+ZETA2*ZETA2 )
+*
+*           See if root is closer to zero or to ONE
+*
+            TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
+            IF( TEST.GE.ZERO ) THEN
+*
+*              root is close to zero, compute directly
+*
+               B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
+               C = ZETA2*ZETA2
+               T = C / ( B+SQRT( ABS( B*B-C ) ) )
+               SINE = ( ALPHA / ABSEST ) / ( ONE-T )
+               COSINE = -( GAMMA / ABSEST ) / T
+               SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
+            ELSE
+*
+*              root is closer to ONE, shift by that amount
+*
+               B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
+               C = ZETA1*ZETA1
+               IF( B.GE.ZERO ) THEN
+                  T = -C / ( B+SQRT( B*B+C ) )
+               ELSE
+                  T = B - SQRT( B*B+C )
+               END IF
+               SINE = -( ALPHA / ABSEST ) / T
+               COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
+               SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
+            END IF
+            TMP = SQRT( SINE*CONJG( SINE )+COSINE*CONJG( COSINE ) )
+            S = SINE / TMP
+            C = COSINE / TMP
+            RETURN
+*
+         END IF
+      END IF
+      RETURN
+*
+*     End of CLAIC1
+*
+      END
diff --git a/libcruft/lapack/clals0.f b/libcruft/lapack/clals0.f
new file mode 100644
index 0000000..4786ea7
--- /dev/null
+++ b/libcruft/lapack/clals0.f
@@ -0,0 +1,433 @@
+      SUBROUTINE CLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
+     $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
+     $                   POLES, DIFL, DIFR, Z, K, C, S, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
+     $                   LDGNUM, NL, NR, NRHS, SQRE
+      REAL               C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), PERM( * )
+      REAL               DIFL( * ), DIFR( LDGNUM, * ),
+     $                   GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
+     $                   RWORK( * ), Z( * )
+      COMPLEX            B( LDB, * ), BX( LDBX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLALS0 applies back the multiplying factors of either the left or the
+*  right singular vector matrix of a diagonal matrix appended by a row
+*  to the right hand side matrix B in solving the least squares problem
+*  using the divide-and-conquer SVD approach.
+*
+*  For the left singular vector matrix, three types of orthogonal
+*  matrices are involved:
+*
+*  (1L) Givens rotations: the number of such rotations is GIVPTR; the
+*       pairs of columns/rows they were applied to are stored in GIVCOL;
+*       and the C- and S-values of these rotations are stored in GIVNUM.
+*
+*  (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
+*       row, and for J=2:N, PERM(J)-th row of B is to be moved to the
+*       J-th row.
+*
+*  (3L) The left singular vector matrix of the remaining matrix.
+*
+*  For the right singular vector matrix, four types of orthogonal
+*  matrices are involved:
+*
+*  (1R) The right singular vector matrix of the remaining matrix.
+*
+*  (2R) If SQRE = 1, one extra Givens rotation to generate the right
+*       null space.
+*
+*  (3R) The inverse transformation of (2L).
+*
+*  (4R) The inverse transformation of (1L).
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed in
+*         factored form:
+*         = 0: Left singular vector matrix.
+*         = 1: Right singular vector matrix.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block. NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block. NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) COMPLEX array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M. On output, B contains
+*         the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B. LDB must be at least
+*         max(1,MAX( M, N ) ).
+*
+*  BX     (workspace) COMPLEX array, dimension ( LDBX, NRHS )
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  PERM   (input) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) applied
+*         to the two blocks.
+*
+*  GIVPTR (input) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of rows/columns
+*         involved in a Givens rotation.
+*
+*  LDGCOL (input) INTEGER
+*         The leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (input) REAL array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value used in the
+*         corresponding Givens rotation.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of arrays DIFR, POLES and
+*         GIVNUM, must be at least K.
+*
+*  POLES  (input) REAL array, dimension ( LDGNUM, 2 )
+*         On entry, POLES(1:K, 1) contains the new singular
+*         values obtained from solving the secular equation, and
+*         POLES(1:K, 2) is an array containing the poles in the secular
+*         equation.
+*
+*  DIFL   (input) REAL array, dimension ( K ).
+*         On entry, DIFL(I) is the distance between I-th updated
+*         (undeflated) singular value and the I-th (undeflated) old
+*         singular value.
+*
+*  DIFR   (input) REAL array, dimension ( LDGNUM, 2 ).
+*         On entry, DIFR(I, 1) contains the distances between I-th
+*         updated (undeflated) singular value and the I+1-th
+*         (undeflated) old singular value. And DIFR(I, 2) is the
+*         normalizing factor for the I-th right singular vector.
+*
+*  Z      (input) REAL array, dimension ( K )
+*         Contain the components of the deflation-adjusted updating row
+*         vector.
+*
+*  K      (input) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  C      (input) REAL
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (input) REAL
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  RWORK  (workspace) REAL array, dimension
+*         ( K*(1+NRHS) + 2*NRHS )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO, NEGONE
+      PARAMETER          ( ONE = 1.0E0, ZERO = 0.0E0, NEGONE = -1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, JCOL, JROW, M, N, NLP1
+      REAL               DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CLACPY, CLASCL, CSROT, CSSCAL, SGEMV,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3, SNRM2
+      EXTERNAL           SLAMC3, SNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          AIMAG, CMPLX, MAX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      END IF
+*
+      N = NL + NR + 1
+*
+      IF( NRHS.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -7
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -9
+      ELSE IF( GIVPTR.LT.0 ) THEN
+         INFO = -11
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -13
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -15
+      ELSE IF( K.LT.1 ) THEN
+         INFO = -20
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLALS0', -INFO )
+         RETURN
+      END IF
+*
+      M = N + SQRE
+      NLP1 = NL + 1
+*
+      IF( ICOMPQ.EQ.0 ) THEN
+*
+*        Apply back orthogonal transformations from the left.
+*
+*        Step (1L): apply back the Givens rotations performed.
+*
+         DO 10 I = 1, GIVPTR
+            CALL CSROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                  GIVNUM( I, 1 ) )
+   10    CONTINUE
+*
+*        Step (2L): permute rows of B.
+*
+         CALL CCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
+         DO 20 I = 2, N
+            CALL CCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
+   20    CONTINUE
+*
+*        Step (3L): apply the inverse of the left singular vector
+*        matrix to BX.
+*
+         IF( K.EQ.1 ) THEN
+            CALL CCOPY( NRHS, BX, LDBX, B, LDB )
+            IF( Z( 1 ).LT.ZERO ) THEN
+               CALL CSSCAL( NRHS, NEGONE, B, LDB )
+            END IF
+         ELSE
+            DO 100 J = 1, K
+               DIFLJ = DIFL( J )
+               DJ = POLES( J, 1 )
+               DSIGJ = -POLES( J, 2 )
+               IF( J.LT.K ) THEN
+                  DIFRJ = -DIFR( J, 1 )
+                  DSIGJP = -POLES( J+1, 2 )
+               END IF
+               IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
+     $              THEN
+                  RWORK( J ) = ZERO
+               ELSE
+                  RWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
+     $                         ( POLES( J, 2 )+DJ )
+               END IF
+               DO 30 I = 1, J - 1
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                            ( SLAMC3( POLES( I, 2 ), DSIGJ )-
+     $                            DIFLJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   30          CONTINUE
+               DO 40 I = J + 1, K
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                            ( SLAMC3( POLES( I, 2 ), DSIGJP )+
+     $                            DIFRJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   40          CONTINUE
+               RWORK( 1 ) = NEGONE
+               TEMP = SNRM2( K, RWORK, 1 )
+*
+*              Since B and BX are complex, the following call to SGEMV
+*              is performed in two steps (real and imaginary parts).
+*
+*              CALL SGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
+*    $                     B( J, 1 ), LDB )
+*
+               I = K + NRHS*2
+               DO 60 JCOL = 1, NRHS
+                  DO 50 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = REAL( BX( JROW, JCOL ) )
+   50             CONTINUE
+   60          CONTINUE
+               CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
+               I = K + NRHS*2
+               DO 80 JCOL = 1, NRHS
+                  DO 70 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = AIMAG( BX( JROW, JCOL ) )
+   70             CONTINUE
+   80          CONTINUE
+               CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
+               DO 90 JCOL = 1, NRHS
+                  B( J, JCOL ) = CMPLX( RWORK( JCOL+K ),
+     $                           RWORK( JCOL+K+NRHS ) )
+   90          CONTINUE
+               CALL CLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
+     $                      LDB, INFO )
+  100       CONTINUE
+         END IF
+*
+*        Move the deflated rows of BX to B also.
+*
+         IF( K.LT.MAX( M, N ) )
+     $      CALL CLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
+     $                   B( K+1, 1 ), LDB )
+      ELSE
+*
+*        Apply back the right orthogonal transformations.
+*
+*        Step (1R): apply back the new right singular vector matrix
+*        to B.
+*
+         IF( K.EQ.1 ) THEN
+            CALL CCOPY( NRHS, B, LDB, BX, LDBX )
+         ELSE
+            DO 180 J = 1, K
+               DSIGJ = POLES( J, 2 )
+               IF( Z( J ).EQ.ZERO ) THEN
+                  RWORK( J ) = ZERO
+               ELSE
+                  RWORK( J ) = -Z( J ) / DIFL( J ) /
+     $                         ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
+               END IF
+               DO 110 I = 1, J - 1
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = Z( J ) / ( SLAMC3( DSIGJ, -POLES( I+1,
+     $                            2 ) )-DIFR( I, 1 ) ) /
+     $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+  110          CONTINUE
+               DO 120 I = J + 1, K
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = Z( J ) / ( SLAMC3( DSIGJ, -POLES( I,
+     $                            2 ) )-DIFL( I ) ) /
+     $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+  120          CONTINUE
+*
+*              Since B and BX are complex, the following call to SGEMV
+*              is performed in two steps (real and imaginary parts).
+*
+*              CALL SGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
+*    $                     BX( J, 1 ), LDBX )
+*
+               I = K + NRHS*2
+               DO 140 JCOL = 1, NRHS
+                  DO 130 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = REAL( B( JROW, JCOL ) )
+  130             CONTINUE
+  140          CONTINUE
+               CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
+               I = K + NRHS*2
+               DO 160 JCOL = 1, NRHS
+                  DO 150 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = AIMAG( B( JROW, JCOL ) )
+  150             CONTINUE
+  160          CONTINUE
+               CALL SGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
+               DO 170 JCOL = 1, NRHS
+                  BX( J, JCOL ) = CMPLX( RWORK( JCOL+K ),
+     $                            RWORK( JCOL+K+NRHS ) )
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+*
+*        Step (2R): if SQRE = 1, apply back the rotation that is
+*        related to the right null space of the subproblem.
+*
+         IF( SQRE.EQ.1 ) THEN
+            CALL CCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
+            CALL CSROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
+         END IF
+         IF( K.LT.MAX( M, N ) )
+     $      CALL CLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB,
+     $                   BX( K+1, 1 ), LDBX )
+*
+*        Step (3R): permute rows of B.
+*
+         CALL CCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
+         IF( SQRE.EQ.1 ) THEN
+            CALL CCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
+         END IF
+         DO 190 I = 2, N
+            CALL CCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
+  190    CONTINUE
+*
+*        Step (4R): apply back the Givens rotations performed.
+*
+         DO 200 I = GIVPTR, 1, -1
+            CALL CSROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                  -GIVNUM( I, 1 ) )
+  200    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLALS0
+*
+      END
diff --git a/libcruft/lapack/clalsa.f b/libcruft/lapack/clalsa.f
new file mode 100644
index 0000000..8938fac
--- /dev/null
+++ b/libcruft/lapack/clalsa.f
@@ -0,0 +1,503 @@
+      SUBROUTINE CLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,
+     $                   LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,
+     $                   GIVCOL, LDGCOL, PERM, GIVNUM, C, S, RWORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,
+     $                   SMLSIZ
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
+     $                   K( * ), PERM( LDGCOL, * )
+      REAL               C( * ), DIFL( LDU, * ), DIFR( LDU, * ),
+     $                   GIVNUM( LDU, * ), POLES( LDU, * ), RWORK( * ),
+     $                   S( * ), U( LDU, * ), VT( LDU, * ), Z( LDU, * )
+      COMPLEX            B( LDB, * ), BX( LDBX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLALSA is an itermediate step in solving the least squares problem
+*  by computing the SVD of the coefficient matrix in compact form (The
+*  singular vectors are computed as products of simple orthorgonal
+*  matrices.).
+*
+*  If ICOMPQ = 0, CLALSA applies the inverse of the left singular vector
+*  matrix of an upper bidiagonal matrix to the right hand side; and if
+*  ICOMPQ = 1, CLALSA applies the right singular vector matrix to the
+*  right hand side. The singular vector matrices were generated in
+*  compact form by CLALSA.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether the left or the right singular vector
+*         matrix is involved.
+*         = 0: Left singular vector matrix
+*         = 1: Right singular vector matrix
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The row and column dimensions of the upper bidiagonal matrix.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) COMPLEX array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M.
+*         On output, B contains the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,MAX( M, N ) ).
+*
+*  BX     (output) COMPLEX array, dimension ( LDBX, NRHS )
+*         On exit, the result of applying the left or right singular
+*         vector matrix to B.
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  U      (input) REAL array, dimension ( LDU, SMLSIZ ).
+*         On entry, U contains the left singular vector matrices of all
+*         subproblems at the bottom level.
+*
+*  LDU    (input) INTEGER, LDU = > N.
+*         The leading dimension of arrays U, VT, DIFL, DIFR,
+*         POLES, GIVNUM, and Z.
+*
+*  VT     (input) REAL array, dimension ( LDU, SMLSIZ+1 ).
+*         On entry, VT' contains the right singular vector matrices of
+*         all subproblems at the bottom level.
+*
+*  K      (input) INTEGER array, dimension ( N ).
+*
+*  DIFL   (input) REAL array, dimension ( LDU, NLVL ).
+*         where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.
+*
+*  DIFR   (input) REAL array, dimension ( LDU, 2 * NLVL ).
+*         On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record
+*         distances between singular values on the I-th level and
+*         singular values on the (I -1)-th level, and DIFR(*, 2 * I)
+*         record the normalizing factors of the right singular vectors
+*         matrices of subproblems on I-th level.
+*
+*  Z      (input) REAL array, dimension ( LDU, NLVL ).
+*         On entry, Z(1, I) contains the components of the deflation-
+*         adjusted updating row vector for subproblems on the I-th
+*         level.
+*
+*  POLES  (input) REAL array, dimension ( LDU, 2 * NLVL ).
+*         On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old
+*         singular values involved in the secular equations on the I-th
+*         level.
+*
+*  GIVPTR (input) INTEGER array, dimension ( N ).
+*         On entry, GIVPTR( I ) records the number of Givens
+*         rotations performed on the I-th problem on the computation
+*         tree.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ).
+*         On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the
+*         locations of Givens rotations performed on the I-th level on
+*         the computation tree.
+*
+*  LDGCOL (input) INTEGER, LDGCOL = > N.
+*         The leading dimension of arrays GIVCOL and PERM.
+*
+*  PERM   (input) INTEGER array, dimension ( LDGCOL, NLVL ).
+*         On entry, PERM(*, I) records permutations done on the I-th
+*         level of the computation tree.
+*
+*  GIVNUM (input) REAL array, dimension ( LDU, 2 * NLVL ).
+*         On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-
+*         values of Givens rotations performed on the I-th level on the
+*         computation tree.
+*
+*  C      (input) REAL array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         C( I ) contains the C-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  S      (input) REAL array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         S( I ) contains the S-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  RWORK  (workspace) REAL array, dimension at least
+*         max ( N, (SMLSZ+1)*NRHS*3 ).
+*
+*  IWORK  (workspace) INTEGER array.
+*         The dimension must be at least 3 * N
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IM1, INODE, J, JCOL, JIMAG, JREAL,
+     $                   JROW, LF, LL, LVL, LVL2, ND, NDB1, NDIML,
+     $                   NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQRE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CLALS0, SGEMM, SLASDT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          AIMAG, CMPLX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.SMLSIZ ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -6
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -19
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLALSA', -INFO )
+         RETURN
+      END IF
+*
+*     Book-keeping and  setting up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+*
+      CALL SLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     The following code applies back the left singular vector factors.
+*     For applying back the right singular vector factors, go to 170.
+*
+      IF( ICOMPQ.EQ.1 ) THEN
+         GO TO 170
+      END IF
+*
+*     The nodes on the bottom level of the tree were solved
+*     by SLASDQ. The corresponding left and right singular vector
+*     matrices are in explicit form. First apply back the left
+*     singular vector matrices.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 130 I = NDB1, ND
+*
+*        IC : center row of each node
+*        NL : number of rows of left  subproblem
+*        NR : number of rows of right subproblem
+*        NLF: starting row of the left   subproblem
+*        NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLF = IC - NL
+         NRF = IC + 1
+*
+*        Since B and BX are complex, the following call to SGEMM
+*        is performed in two steps (real and imaginary parts).
+*
+*        CALL SGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+*     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+*
+         J = NL*NRHS*2
+         DO 20 JCOL = 1, NRHS
+            DO 10 JROW = NLF, NLF + NL - 1
+               J = J + 1
+               RWORK( J ) = REAL( B( JROW, JCOL ) )
+   10       CONTINUE
+   20    CONTINUE
+         CALL SGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+     $               RWORK( 1+NL*NRHS*2 ), NL, ZERO, RWORK( 1 ), NL )
+         J = NL*NRHS*2
+         DO 40 JCOL = 1, NRHS
+            DO 30 JROW = NLF, NLF + NL - 1
+               J = J + 1
+               RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+   30       CONTINUE
+   40    CONTINUE
+         CALL SGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+     $               RWORK( 1+NL*NRHS*2 ), NL, ZERO, RWORK( 1+NL*NRHS ),
+     $               NL )
+         JREAL = 0
+         JIMAG = NL*NRHS
+         DO 60 JCOL = 1, NRHS
+            DO 50 JROW = NLF, NLF + NL - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+   50       CONTINUE
+   60    CONTINUE
+*
+*        Since B and BX are complex, the following call to SGEMM
+*        is performed in two steps (real and imaginary parts).
+*
+*        CALL SGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+*    $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+*
+         J = NR*NRHS*2
+         DO 80 JCOL = 1, NRHS
+            DO 70 JROW = NRF, NRF + NR - 1
+               J = J + 1
+               RWORK( J ) = REAL( B( JROW, JCOL ) )
+   70       CONTINUE
+   80    CONTINUE
+         CALL SGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+     $               RWORK( 1+NR*NRHS*2 ), NR, ZERO, RWORK( 1 ), NR )
+         J = NR*NRHS*2
+         DO 100 JCOL = 1, NRHS
+            DO 90 JROW = NRF, NRF + NR - 1
+               J = J + 1
+               RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+   90       CONTINUE
+  100    CONTINUE
+         CALL SGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+     $               RWORK( 1+NR*NRHS*2 ), NR, ZERO, RWORK( 1+NR*NRHS ),
+     $               NR )
+         JREAL = 0
+         JIMAG = NR*NRHS
+         DO 120 JCOL = 1, NRHS
+            DO 110 JROW = NRF, NRF + NR - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+  110       CONTINUE
+  120    CONTINUE
+*
+  130 CONTINUE
+*
+*     Next copy the rows of B that correspond to unchanged rows
+*     in the bidiagonal matrix to BX.
+*
+      DO 140 I = 1, ND
+         IC = IWORK( INODE+I-1 )
+         CALL CCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )
+  140 CONTINUE
+*
+*     Finally go through the left singular vector matrices of all
+*     the other subproblems bottom-up on the tree.
+*
+      J = 2**NLVL
+      SQRE = 0
+*
+      DO 160 LVL = NLVL, 1, -1
+         LVL2 = 2*LVL - 1
+*
+*        find the first node LF and last node LL on
+*        the current level LVL
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 150 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            J = J - 1
+            CALL CLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,
+     $                   B( NLF, 1 ), LDB, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), RWORK,
+     $                   INFO )
+  150    CONTINUE
+  160 CONTINUE
+      GO TO 330
+*
+*     ICOMPQ = 1: applying back the right singular vector factors.
+*
+  170 CONTINUE
+*
+*     First now go through the right singular vector matrices of all
+*     the tree nodes top-down.
+*
+      J = 0
+      DO 190 LVL = 1, NLVL
+         LVL2 = 2*LVL - 1
+*
+*        Find the first node LF and last node LL on
+*        the current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 180 I = LL, LF, -1
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            IF( I.EQ.LL ) THEN
+               SQRE = 0
+            ELSE
+               SQRE = 1
+            END IF
+            J = J + 1
+            CALL CLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,
+     $                   BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), RWORK,
+     $                   INFO )
+  180    CONTINUE
+  190 CONTINUE
+*
+*     The nodes on the bottom level of the tree were solved
+*     by SLASDQ. The corresponding right singular vector
+*     matrices are in explicit form. Apply them back.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 320 I = NDB1, ND
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLP1 = NL + 1
+         IF( I.EQ.ND ) THEN
+            NRP1 = NR
+         ELSE
+            NRP1 = NR + 1
+         END IF
+         NLF = IC - NL
+         NRF = IC + 1
+*
+*        Since B and BX are complex, the following call to SGEMM is
+*        performed in two steps (real and imaginary parts).
+*
+*        CALL SGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+*    $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+*
+         J = NLP1*NRHS*2
+         DO 210 JCOL = 1, NRHS
+            DO 200 JROW = NLF, NLF + NLP1 - 1
+               J = J + 1
+               RWORK( J ) = REAL( B( JROW, JCOL ) )
+  200       CONTINUE
+  210    CONTINUE
+         CALL SGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+     $               RWORK( 1+NLP1*NRHS*2 ), NLP1, ZERO, RWORK( 1 ),
+     $               NLP1 )
+         J = NLP1*NRHS*2
+         DO 230 JCOL = 1, NRHS
+            DO 220 JROW = NLF, NLF + NLP1 - 1
+               J = J + 1
+               RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+  220       CONTINUE
+  230    CONTINUE
+         CALL SGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+     $               RWORK( 1+NLP1*NRHS*2 ), NLP1, ZERO,
+     $               RWORK( 1+NLP1*NRHS ), NLP1 )
+         JREAL = 0
+         JIMAG = NLP1*NRHS
+         DO 250 JCOL = 1, NRHS
+            DO 240 JROW = NLF, NLF + NLP1 - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+  240       CONTINUE
+  250    CONTINUE
+*
+*        Since B and BX are complex, the following call to SGEMM is
+*        performed in two steps (real and imaginary parts).
+*
+*        CALL SGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+*    $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+*
+         J = NRP1*NRHS*2
+         DO 270 JCOL = 1, NRHS
+            DO 260 JROW = NRF, NRF + NRP1 - 1
+               J = J + 1
+               RWORK( J ) = REAL( B( JROW, JCOL ) )
+  260       CONTINUE
+  270    CONTINUE
+         CALL SGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+     $               RWORK( 1+NRP1*NRHS*2 ), NRP1, ZERO, RWORK( 1 ),
+     $               NRP1 )
+         J = NRP1*NRHS*2
+         DO 290 JCOL = 1, NRHS
+            DO 280 JROW = NRF, NRF + NRP1 - 1
+               J = J + 1
+               RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+  280       CONTINUE
+  290    CONTINUE
+         CALL SGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+     $               RWORK( 1+NRP1*NRHS*2 ), NRP1, ZERO,
+     $               RWORK( 1+NRP1*NRHS ), NRP1 )
+         JREAL = 0
+         JIMAG = NRP1*NRHS
+         DO 310 JCOL = 1, NRHS
+            DO 300 JROW = NRF, NRF + NRP1 - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+  300       CONTINUE
+  310    CONTINUE
+*
+  320 CONTINUE
+*
+  330 CONTINUE
+*
+      RETURN
+*
+*     End of CLALSA
+*
+      END
diff --git a/libcruft/lapack/clalsd.f b/libcruft/lapack/clalsd.f
new file mode 100644
index 0000000..01b7a31
--- /dev/null
+++ b/libcruft/lapack/clalsd.f
@@ -0,0 +1,596 @@
+      SUBROUTINE CLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
+     $                   RANK, WORK, RWORK, IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDB, N, NRHS, RANK, SMLSIZ
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               D( * ), E( * ), RWORK( * )
+      COMPLEX            B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLALSD uses the singular value decomposition of A to solve the least
+*  squares problem of finding X to minimize the Euclidean norm of each
+*  column of A*X-B, where A is N-by-N upper bidiagonal, and X and B
+*  are N-by-NRHS. The solution X overwrites B.
+*
+*  The singular values of A smaller than RCOND times the largest
+*  singular value are treated as zero in solving the least squares
+*  problem; in this case a minimum norm solution is returned.
+*  The actual singular values are returned in D in ascending order.
+*
+*  This code makes very mild assumptions about floating point
+*  arithmetic. It will work on machines with a guard digit in
+*  add/subtract, or on those binary machines without guard digits
+*  which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
+*  It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  UPLO   (input) CHARACTER*1
+*         = 'U': D and E define an upper bidiagonal matrix.
+*         = 'L': D and E define a  lower bidiagonal matrix.
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The dimension of the  bidiagonal matrix.  N >= 0.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B. NRHS must be at least 1.
+*
+*  D      (input/output) REAL array, dimension (N)
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix. On exit, if INFO = 0, D contains its singular values.
+*
+*  E      (input/output) REAL array, dimension (N-1)
+*         Contains the super-diagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  B      (input/output) COMPLEX array, dimension (LDB,NRHS)
+*         On input, B contains the right hand sides of the least
+*         squares problem. On output, B contains the solution X.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,N).
+*
+*  RCOND  (input) REAL
+*         The singular values of A less than or equal to RCOND times
+*         the largest singular value are treated as zero in solving
+*         the least squares problem. If RCOND is negative,
+*         machine precision is used instead.
+*         For example, if diag(S)*X=B were the least squares problem,
+*         where diag(S) is a diagonal matrix of singular values, the
+*         solution would be X(i) = B(i) / S(i) if S(i) is greater than
+*         RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to
+*         RCOND*max(S).
+*
+*  RANK   (output) INTEGER
+*         The number of singular values of A greater than RCOND times
+*         the largest singular value.
+*
+*  WORK   (workspace) COMPLEX array, dimension (N * NRHS).
+*
+*  RWORK  (workspace) REAL array, dimension at least
+*         (9*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS + (SMLSIZ+1)**2),
+*         where
+*         NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
+*
+*  IWORK  (workspace) INTEGER array, dimension (3*N*NLVL + 11*N).
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*         > 0:  The algorithm failed to compute an singular value while
+*               working on the submatrix lying in rows and columns
+*               INFO/(N+1) through MOD(INFO,N+1).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 )
+      COMPLEX            CZERO
+      PARAMETER          ( CZERO = ( 0.0E0, 0.0E0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
+     $                   GIVPTR, I, ICMPQ1, ICMPQ2, IRWB, IRWIB, IRWRB,
+     $                   IRWU, IRWVT, IRWWRK, IWK, J, JCOL, JIMAG,
+     $                   JREAL, JROW, K, NLVL, NM1, NRWORK, NSIZE, NSUB,
+     $                   PERM, POLES, S, SIZEI, SMLSZP, SQRE, ST, ST1,
+     $                   U, VT, Z
+      REAL               CS, EPS, ORGNRM, R, RCND, SN, TOL
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SLAMCH, SLANST
+      EXTERNAL           ISAMAX, SLAMCH, SLANST
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CLACPY, CLALSA, CLASCL, CLASET, CSROT,
+     $                   SGEMM, SLARTG, SLASCL, SLASDA, SLASDQ, SLASET,
+     $                   SLASRT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, INT, LOG, REAL, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLALSD', -INFO )
+         RETURN
+      END IF
+*
+      EPS = SLAMCH( 'Epsilon' )
+*
+*     Set up the tolerance.
+*
+      IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THEN
+         RCND = EPS
+      ELSE
+         RCND = RCOND
+      END IF
+*
+      RANK = 0
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+         IF( D( 1 ).EQ.ZERO ) THEN
+            CALL CLASET( 'A', 1, NRHS, CZERO, CZERO, B, LDB )
+         ELSE
+            RANK = 1
+            CALL CLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )
+            D( 1 ) = ABS( D( 1 ) )
+         END IF
+         RETURN
+      END IF
+*
+*     Rotate the matrix if it is lower bidiagonal.
+*
+      IF( UPLO.EQ.'L' ) THEN
+         DO 10 I = 1, N - 1
+            CALL SLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( NRHS.EQ.1 ) THEN
+               CALL CSROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )
+            ELSE
+               RWORK( I*2-1 ) = CS
+               RWORK( I*2 ) = SN
+            END IF
+   10    CONTINUE
+         IF( NRHS.GT.1 ) THEN
+            DO 30 I = 1, NRHS
+               DO 20 J = 1, N - 1
+                  CS = RWORK( J*2-1 )
+                  SN = RWORK( J*2 )
+                  CALL CSROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )
+   20          CONTINUE
+   30       CONTINUE
+         END IF
+      END IF
+*
+*     Scale.
+*
+      NM1 = N - 1
+      ORGNRM = SLANST( 'M', N, D, E )
+      IF( ORGNRM.EQ.ZERO ) THEN
+         CALL CLASET( 'A', N, NRHS, CZERO, CZERO, B, LDB )
+         RETURN
+      END IF
+*
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )
+*
+*     If N is smaller than the minimum divide size SMLSIZ, then solve
+*     the problem with another solver.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         IRWU = 1
+         IRWVT = IRWU + N*N
+         IRWWRK = IRWVT + N*N
+         IRWRB = IRWWRK
+         IRWIB = IRWRB + N*NRHS
+         IRWB = IRWIB + N*NRHS
+         CALL SLASET( 'A', N, N, ZERO, ONE, RWORK( IRWU ), N )
+         CALL SLASET( 'A', N, N, ZERO, ONE, RWORK( IRWVT ), N )
+         CALL SLASDQ( 'U', 0, N, N, N, 0, D, E, RWORK( IRWVT ), N,
+     $                RWORK( IRWU ), N, RWORK( IRWWRK ), 1,
+     $                RWORK( IRWWRK ), INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+*
+*        In the real version, B is passed to SLASDQ and multiplied
+*        internally by Q'. Here B is complex and that product is
+*        computed below in two steps (real and imaginary parts).
+*
+         J = IRWB - 1
+         DO 50 JCOL = 1, NRHS
+            DO 40 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = REAL( B( JROW, JCOL ) )
+   40       CONTINUE
+   50    CONTINUE
+         CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWU ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )
+         J = IRWB - 1
+         DO 70 JCOL = 1, NRHS
+            DO 60 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+   60       CONTINUE
+   70    CONTINUE
+         CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWU ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )
+         JREAL = IRWRB - 1
+         JIMAG = IRWIB - 1
+         DO 90 JCOL = 1, NRHS
+            DO 80 JROW = 1, N
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               B( JROW, JCOL ) = CMPLX( RWORK( JREAL ), RWORK( JIMAG ) )
+   80       CONTINUE
+   90    CONTINUE
+*
+         TOL = RCND*ABS( D( ISAMAX( N, D, 1 ) ) )
+         DO 100 I = 1, N
+            IF( D( I ).LE.TOL ) THEN
+               CALL CLASET( 'A', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            ELSE
+               CALL CLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),
+     $                      LDB, INFO )
+               RANK = RANK + 1
+            END IF
+  100    CONTINUE
+*
+*        Since B is complex, the following call to SGEMM is performed
+*        in two steps (real and imaginary parts). That is for V * B
+*        (in the real version of the code V' is stored in WORK).
+*
+*        CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,
+*    $               WORK( NWORK ), N )
+*
+         J = IRWB - 1
+         DO 120 JCOL = 1, NRHS
+            DO 110 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = REAL( B( JROW, JCOL ) )
+  110       CONTINUE
+  120    CONTINUE
+         CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )
+         J = IRWB - 1
+         DO 140 JCOL = 1, NRHS
+            DO 130 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+  130       CONTINUE
+  140    CONTINUE
+         CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )
+         JREAL = IRWRB - 1
+         JIMAG = IRWIB - 1
+         DO 160 JCOL = 1, NRHS
+            DO 150 JROW = 1, N
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               B( JROW, JCOL ) = CMPLX( RWORK( JREAL ), RWORK( JIMAG ) )
+  150       CONTINUE
+  160    CONTINUE
+*
+*        Unscale.
+*
+         CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+         CALL SLASRT( 'D', N, D, INFO )
+         CALL CLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+         RETURN
+      END IF
+*
+*     Book-keeping and setting up some constants.
+*
+      NLVL = INT( LOG( REAL( N ) / REAL( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1
+*
+      SMLSZP = SMLSIZ + 1
+*
+      U = 1
+      VT = 1 + SMLSIZ*N
+      DIFL = VT + SMLSZP*N
+      DIFR = DIFL + NLVL*N
+      Z = DIFR + NLVL*N*2
+      C = Z + NLVL*N
+      S = C + N
+      POLES = S + N
+      GIVNUM = POLES + 2*NLVL*N
+      NRWORK = GIVNUM + 2*NLVL*N
+      BX = 1
+*
+      IRWRB = NRWORK
+      IRWIB = IRWRB + SMLSIZ*NRHS
+      IRWB = IRWIB + SMLSIZ*NRHS
+*
+      SIZEI = 1 + N
+      K = SIZEI + N
+      GIVPTR = K + N
+      PERM = GIVPTR + N
+      GIVCOL = PERM + NLVL*N
+      IWK = GIVCOL + NLVL*N*2
+*
+      ST = 1
+      SQRE = 0
+      ICMPQ1 = 1
+      ICMPQ2 = 0
+      NSUB = 0
+*
+      DO 170 I = 1, N
+         IF( ABS( D( I ) ).LT.EPS ) THEN
+            D( I ) = SIGN( EPS, D( I ) )
+         END IF
+  170 CONTINUE
+*
+      DO 240 I = 1, NM1
+         IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
+            NSUB = NSUB + 1
+            IWORK( NSUB ) = ST
+*
+*           Subproblem found. First determine its size and then
+*           apply divide and conquer on it.
+*
+            IF( I.LT.NM1 ) THEN
+*
+*              A subproblem with E(I) small for I < NM1.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
+*
+*              A subproblem with E(NM1) not too small but I = NM1.
+*
+               NSIZE = N - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE
+*
+*              A subproblem with E(NM1) small. This implies an
+*              1-by-1 subproblem at D(N), which is not solved
+*              explicitly.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+               NSUB = NSUB + 1
+               IWORK( NSUB ) = N
+               IWORK( SIZEI+NSUB-1 ) = 1
+               CALL CCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )
+            END IF
+            ST1 = ST - 1
+            IF( NSIZE.EQ.1 ) THEN
+*
+*              This is a 1-by-1 subproblem and is not solved
+*              explicitly.
+*
+               CALL CCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )
+            ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+*
+*              This is a small subproblem and is solved by SLASDQ.
+*
+               CALL SLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
+     $                      RWORK( VT+ST1 ), N )
+               CALL SLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
+     $                      RWORK( U+ST1 ), N )
+               CALL SLASDQ( 'U', 0, NSIZE, NSIZE, NSIZE, 0, D( ST ),
+     $                      E( ST ), RWORK( VT+ST1 ), N, RWORK( U+ST1 ),
+     $                      N, RWORK( NRWORK ), 1, RWORK( NRWORK ),
+     $                      INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+*
+*              In the real version, B is passed to SLASDQ and multiplied
+*              internally by Q'. Here B is complex and that product is
+*              computed below in two steps (real and imaginary parts).
+*
+               J = IRWB - 1
+               DO 190 JCOL = 1, NRHS
+                  DO 180 JROW = ST, ST + NSIZE - 1
+                     J = J + 1
+                     RWORK( J ) = REAL( B( JROW, JCOL ) )
+  180             CONTINUE
+  190          CONTINUE
+               CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                     RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,
+     $                     ZERO, RWORK( IRWRB ), NSIZE )
+               J = IRWB - 1
+               DO 210 JCOL = 1, NRHS
+                  DO 200 JROW = ST, ST + NSIZE - 1
+                     J = J + 1
+                     RWORK( J ) = AIMAG( B( JROW, JCOL ) )
+  200             CONTINUE
+  210          CONTINUE
+               CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                     RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,
+     $                     ZERO, RWORK( IRWIB ), NSIZE )
+               JREAL = IRWRB - 1
+               JIMAG = IRWIB - 1
+               DO 230 JCOL = 1, NRHS
+                  DO 220 JROW = ST, ST + NSIZE - 1
+                     JREAL = JREAL + 1
+                     JIMAG = JIMAG + 1
+                     B( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
+     $                                 RWORK( JIMAG ) )
+  220             CONTINUE
+  230          CONTINUE
+*
+               CALL CLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,
+     $                      WORK( BX+ST1 ), N )
+            ELSE
+*
+*              A large problem. Solve it using divide and conquer.
+*
+               CALL SLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),
+     $                      E( ST ), RWORK( U+ST1 ), N, RWORK( VT+ST1 ),
+     $                      IWORK( K+ST1 ), RWORK( DIFL+ST1 ),
+     $                      RWORK( DIFR+ST1 ), RWORK( Z+ST1 ),
+     $                      RWORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),
+     $                      IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),
+     $                      RWORK( GIVNUM+ST1 ), RWORK( C+ST1 ),
+     $                      RWORK( S+ST1 ), RWORK( NRWORK ),
+     $                      IWORK( IWK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+               BXST = BX + ST1
+               CALL CLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),
+     $                      LDB, WORK( BXST ), N, RWORK( U+ST1 ), N,
+     $                      RWORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                      RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),
+     $                      RWORK( Z+ST1 ), RWORK( POLES+ST1 ),
+     $                      IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                      IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),
+     $                      RWORK( C+ST1 ), RWORK( S+ST1 ),
+     $                      RWORK( NRWORK ), IWORK( IWK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+            END IF
+            ST = I + 1
+         END IF
+  240 CONTINUE
+*
+*     Apply the singular values and treat the tiny ones as zero.
+*
+      TOL = RCND*ABS( D( ISAMAX( N, D, 1 ) ) )
+*
+      DO 250 I = 1, N
+*
+*        Some of the elements in D can be negative because 1-by-1
+*        subproblems were not solved explicitly.
+*
+         IF( ABS( D( I ) ).LE.TOL ) THEN
+            CALL CLASET( 'A', 1, NRHS, CZERO, CZERO, WORK( BX+I-1 ), N )
+         ELSE
+            RANK = RANK + 1
+            CALL CLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,
+     $                   WORK( BX+I-1 ), N, INFO )
+         END IF
+         D( I ) = ABS( D( I ) )
+  250 CONTINUE
+*
+*     Now apply back the right singular vectors.
+*
+      ICMPQ2 = 1
+      DO 320 I = 1, NSUB
+         ST = IWORK( I )
+         ST1 = ST - 1
+         NSIZE = IWORK( SIZEI+I-1 )
+         BXST = BX + ST1
+         IF( NSIZE.EQ.1 ) THEN
+            CALL CCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )
+         ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+*
+*           Since B and BX are complex, the following call to SGEMM
+*           is performed in two steps (real and imaginary parts).
+*
+*           CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+*    $                  RWORK( VT+ST1 ), N, RWORK( BXST ), N, ZERO,
+*    $                  B( ST, 1 ), LDB )
+*
+            J = BXST - N - 1
+            JREAL = IRWB - 1
+            DO 270 JCOL = 1, NRHS
+               J = J + N
+               DO 260 JROW = 1, NSIZE
+                  JREAL = JREAL + 1
+                  RWORK( JREAL ) = REAL( WORK( J+JROW ) )
+  260          CONTINUE
+  270       CONTINUE
+            CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                  RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,
+     $                  RWORK( IRWRB ), NSIZE )
+            J = BXST - N - 1
+            JIMAG = IRWB - 1
+            DO 290 JCOL = 1, NRHS
+               J = J + N
+               DO 280 JROW = 1, NSIZE
+                  JIMAG = JIMAG + 1
+                  RWORK( JIMAG ) = AIMAG( WORK( J+JROW ) )
+  280          CONTINUE
+  290       CONTINUE
+            CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                  RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,
+     $                  RWORK( IRWIB ), NSIZE )
+            JREAL = IRWRB - 1
+            JIMAG = IRWIB - 1
+            DO 310 JCOL = 1, NRHS
+               DO 300 JROW = ST, ST + NSIZE - 1
+                  JREAL = JREAL + 1
+                  JIMAG = JIMAG + 1
+                  B( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
+     $                              RWORK( JIMAG ) )
+  300          CONTINUE
+  310       CONTINUE
+         ELSE
+            CALL CLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,
+     $                   B( ST, 1 ), LDB, RWORK( U+ST1 ), N,
+     $                   RWORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                   RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),
+     $                   RWORK( Z+ST1 ), RWORK( POLES+ST1 ),
+     $                   IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                   IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),
+     $                   RWORK( C+ST1 ), RWORK( S+ST1 ),
+     $                   RWORK( NRWORK ), IWORK( IWK ), INFO )
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+         END IF
+  320 CONTINUE
+*
+*     Unscale and sort the singular values.
+*
+      CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+      CALL SLASRT( 'D', N, D, INFO )
+      CALL CLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+      RETURN
+*
+*     End of CLALSD
+*
+      END
diff --git a/libcruft/lapack/clange.f b/libcruft/lapack/clange.f
new file mode 100644
index 0000000..a08ec75
--- /dev/null
+++ b/libcruft/lapack/clange.f
@@ -0,0 +1,145 @@
+      REAL             FUNCTION CLANGE( NORM, M, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               WORK( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLANGE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  complex matrix A.
+*
+*  Description
+*  ===========
+*
+*  CLANGE returns the value
+*
+*     CLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in CLANGE as described
+*          above.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.  When M = 0,
+*          CLANGE is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.  When N = 0,
+*          CLANGE is set to zero.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The m by n matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, M
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, M
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, M
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, M
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL CLASSQ( M, A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      CLANGE = VALUE
+      RETURN
+*
+*     End of CLANGE
+*
+      END
diff --git a/libcruft/lapack/clanhe.f b/libcruft/lapack/clanhe.f
new file mode 100644
index 0000000..0215563
--- /dev/null
+++ b/libcruft/lapack/clanhe.f
@@ -0,0 +1,187 @@
+      REAL             FUNCTION CLANHE( NORM, UPLO, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM, UPLO
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               WORK( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLANHE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  complex hermitian matrix A.
+*
+*  Description
+*  ===========
+*
+*  CLANHE returns the value
+*
+*     CLANHE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in CLANHE as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          hermitian matrix A is to be referenced.
+*          = 'U':  Upper triangular part of A is referenced
+*          = 'L':  Lower triangular part of A is referenced
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, CLANHE is
+*          set to zero.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The hermitian matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of A contains the upper triangular part
+*          of the matrix A, and the strictly lower triangular part of A
+*          is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of A contains the lower triangular part of
+*          the matrix A, and the strictly upper triangular part of A is
+*          not referenced. Note that the imaginary parts of the diagonal
+*          elements need not be set and are assumed to be zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,
+*          WORK is not referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               ABSA, SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 20 J = 1, N
+               DO 10 I = 1, J - 1
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10          CONTINUE
+               VALUE = MAX( VALUE, ABS( REAL( A( J, J ) ) ) )
+   20       CONTINUE
+         ELSE
+            DO 40 J = 1, N
+               VALUE = MAX( VALUE, ABS( REAL( A( J, J ) ) ) )
+               DO 30 I = J + 1, N
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30          CONTINUE
+   40       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.
+     $         ( NORM.EQ.'1' ) ) THEN
+*
+*        Find normI(A) ( = norm1(A), since A is hermitian).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 60 J = 1, N
+               SUM = ZERO
+               DO 50 I = 1, J - 1
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   50          CONTINUE
+               WORK( J ) = SUM + ABS( REAL( A( J, J ) ) )
+   60       CONTINUE
+            DO 70 I = 1, N
+               VALUE = MAX( VALUE, WORK( I ) )
+   70       CONTINUE
+         ELSE
+            DO 80 I = 1, N
+               WORK( I ) = ZERO
+   80       CONTINUE
+            DO 100 J = 1, N
+               SUM = WORK( J ) + ABS( REAL( A( J, J ) ) )
+               DO 90 I = J + 1, N
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   90          CONTINUE
+               VALUE = MAX( VALUE, SUM )
+  100       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 2, N
+               CALL CLASSQ( J-1, A( 1, J ), 1, SCALE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 120 J = 1, N - 1
+               CALL CLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM )
+  120       CONTINUE
+         END IF
+         SUM = 2*SUM
+         DO 130 I = 1, N
+            IF( REAL( A( I, I ) ).NE.ZERO ) THEN
+               ABSA = ABS( REAL( A( I, I ) ) )
+               IF( SCALE.LT.ABSA ) THEN
+                  SUM = ONE + SUM*( SCALE / ABSA )**2
+                  SCALE = ABSA
+               ELSE
+                  SUM = SUM + ( ABSA / SCALE )**2
+               END IF
+            END IF
+  130    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      CLANHE = VALUE
+      RETURN
+*
+*     End of CLANHE
+*
+      END
diff --git a/libcruft/lapack/clanhs.f b/libcruft/lapack/clanhs.f
new file mode 100644
index 0000000..60d9d4d
--- /dev/null
+++ b/libcruft/lapack/clanhs.f
@@ -0,0 +1,142 @@
+      REAL             FUNCTION CLANHS( NORM, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               WORK( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLANHS  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  Hessenberg matrix A.
+*
+*  Description
+*  ===========
+*
+*  CLANHS returns the value
+*
+*     CLANHS = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in CLANHS as described
+*          above.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, CLANHS is
+*          set to zero.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The n by n upper Hessenberg matrix A; the part of A below the
+*          first sub-diagonal is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( N, J+1 )
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, MIN( N, J+1 )
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, N
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( N, J+1 )
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, N
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL CLASSQ( MIN( N, J+1 ), A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      CLANHS = VALUE
+      RETURN
+*
+*     End of CLANHS
+*
+      END
diff --git a/libcruft/lapack/clantr.f b/libcruft/lapack/clantr.f
new file mode 100644
index 0000000..f644d62
--- /dev/null
+++ b/libcruft/lapack/clantr.f
@@ -0,0 +1,277 @@
+      REAL             FUNCTION CLANTR( NORM, UPLO, DIAG, M, N, A, LDA,
+     $                 WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               WORK( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLANTR  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  trapezoidal or triangular matrix A.
+*
+*  Description
+*  ===========
+*
+*  CLANTR returns the value
+*
+*     CLANTR = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in CLANTR as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower trapezoidal.
+*          = 'U':  Upper trapezoidal
+*          = 'L':  Lower trapezoidal
+*          Note that A is triangular instead of trapezoidal if M = N.
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A has unit diagonal.
+*          = 'N':  Non-unit diagonal
+*          = 'U':  Unit diagonal
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0, and if
+*          UPLO = 'U', M <= N.  When M = 0, CLANTR is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0, and if
+*          UPLO = 'L', N <= M.  When N = 0, CLANTR is set to zero.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The trapezoidal matrix A (A is triangular if M = N).
+*          If UPLO = 'U', the leading m by n upper trapezoidal part of
+*          the array A contains the upper trapezoidal matrix, and the
+*          strictly lower triangular part of A is not referenced.
+*          If UPLO = 'L', the leading m by n lower trapezoidal part of
+*          the array A contains the lower trapezoidal matrix, and the
+*          strictly upper triangular part of A is not referenced.  Note
+*          that when DIAG = 'U', the diagonal elements of A are not
+*          referenced and are assumed to be one.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UDIAG
+      INTEGER            I, J
+      REAL               SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         IF( LSAME( DIAG, 'U' ) ) THEN
+            VALUE = ONE
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 20 J = 1, N
+                  DO 10 I = 1, MIN( M, J-1 )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40 J = 1, N
+                  DO 30 I = J + 1, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30             CONTINUE
+   40          CONTINUE
+            END IF
+         ELSE
+            VALUE = ZERO
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 60 J = 1, N
+                  DO 50 I = 1, MIN( M, J )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80 J = 1, N
+                  DO 70 I = J, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         UDIAG = LSAME( DIAG, 'U' )
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 1, N
+               IF( ( UDIAG ) .AND. ( J.LE.M ) ) THEN
+                  SUM = ONE
+                  DO 90 I = 1, J - 1
+                     SUM = SUM + ABS( A( I, J ) )
+   90             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 100 I = 1, MIN( M, J )
+                     SUM = SUM + ABS( A( I, J ) )
+  100             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 140 J = 1, N
+               IF( UDIAG ) THEN
+                  SUM = ONE
+                  DO 120 I = J + 1, M
+                     SUM = SUM + ABS( A( I, J ) )
+  120             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 130 I = J, M
+                     SUM = SUM + ABS( A( I, J ) )
+  130             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  140       CONTINUE
+         END IF
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 150 I = 1, M
+                  WORK( I ) = ONE
+  150          CONTINUE
+               DO 170 J = 1, N
+                  DO 160 I = 1, MIN( M, J-1 )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  160             CONTINUE
+  170          CONTINUE
+            ELSE
+               DO 180 I = 1, M
+                  WORK( I ) = ZERO
+  180          CONTINUE
+               DO 200 J = 1, N
+                  DO 190 I = 1, MIN( M, J )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  190             CONTINUE
+  200          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 210 I = 1, N
+                  WORK( I ) = ONE
+  210          CONTINUE
+               DO 220 I = N + 1, M
+                  WORK( I ) = ZERO
+  220          CONTINUE
+               DO 240 J = 1, N
+                  DO 230 I = J + 1, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  230             CONTINUE
+  240          CONTINUE
+            ELSE
+               DO 250 I = 1, M
+                  WORK( I ) = ZERO
+  250          CONTINUE
+               DO 270 J = 1, N
+                  DO 260 I = J, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  260             CONTINUE
+  270          CONTINUE
+            END IF
+         END IF
+         VALUE = ZERO
+         DO 280 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+  280    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 290 J = 2, N
+                  CALL CLASSQ( MIN( M, J-1 ), A( 1, J ), 1, SCALE, SUM )
+  290          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 300 J = 1, N
+                  CALL CLASSQ( MIN( M, J ), A( 1, J ), 1, SCALE, SUM )
+  300          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 310 J = 1, N
+                  CALL CLASSQ( M-J, A( MIN( M, J+1 ), J ), 1, SCALE,
+     $                         SUM )
+  310          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 320 J = 1, N
+                  CALL CLASSQ( M-J+1, A( J, J ), 1, SCALE, SUM )
+  320          CONTINUE
+            END IF
+         END IF
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      CLANTR = VALUE
+      RETURN
+*
+*     End of CLANTR
+*
+      END
diff --git a/libcruft/lapack/claqp2.f b/libcruft/lapack/claqp2.f
new file mode 100644
index 0000000..3e012a7
--- /dev/null
+++ b/libcruft/lapack/claqp2.f
@@ -0,0 +1,179 @@
+      SUBROUTINE CLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2,
+     $                   WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, M, N, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               VN1( * ), VN2( * )
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAQP2 computes a QR factorization with column pivoting of
+*  the block A(OFFSET+1:M,1:N).
+*  The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of the matrix A that must be pivoted
+*          but no factorized. OFFSET >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of block A(OFFSET+1:M,1:N) is 
+*          the triangular factor obtained; the elements in block
+*          A(OFFSET+1:M,1:N) below the diagonal, together with the
+*          array TAU, represent the orthogonal matrix Q as a product of
+*          elementary reflectors. Block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) COMPLEX array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) REAL array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) REAL array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  WORK    (workspace) COMPLEX array, dimension (N)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      COMPLEX            CONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0,
+     $                   CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MN, OFFPI, PVT
+      REAL               TEMP, TEMP2, TOL3Z
+      COMPLEX            AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARF, CLARFG, CSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, CONJG, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SCNRM2, SLAMCH
+      EXTERNAL           ISAMAX, SCNRM2, SLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M-OFFSET, N )
+      TOL3Z = SQRT(SLAMCH('Epsilon'))
+*
+*     Compute factorization.
+*
+      DO 20 I = 1, MN
+*
+         OFFPI = OFFSET + I
+*
+*        Determine ith pivot column and swap if necessary.
+*
+         PVT = ( I-1 ) + ISAMAX( N-I+1, VN1( I ), 1 )
+*
+         IF( PVT.NE.I ) THEN
+            CALL CSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( I )
+            JPVT( I ) = ITEMP
+            VN1( PVT ) = VN1( I )
+            VN2( PVT ) = VN2( I )
+         END IF
+*
+*        Generate elementary reflector H(i).
+*
+         IF( OFFPI.LT.M ) THEN
+            CALL CLARFG( M-OFFPI+1, A( OFFPI, I ), A( OFFPI+1, I ), 1,
+     $                   TAU( I ) )
+         ELSE
+            CALL CLARFG( 1, A( M, I ), A( M, I ), 1, TAU( I ) )
+         END IF
+*
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i)' to A(offset+i:m,i+1:n) from the left.
+*
+            AII = A( OFFPI, I )
+            A( OFFPI, I ) = CONE
+            CALL CLARF( 'Left', M-OFFPI+1, N-I, A( OFFPI, I ), 1,
+     $                  CONJG( TAU( I ) ), A( OFFPI, I+1 ), LDA,
+     $                  WORK( 1 ) )
+            A( OFFPI, I ) = AII
+         END IF
+*
+*        Update partial column norms.
+*
+         DO 10 J = I + 1, N
+            IF( VN1( J ).NE.ZERO ) THEN
+*
+*              NOTE: The following 4 lines follow from the analysis in
+*              Lapack Working Note 176.
+*
+               TEMP = ONE - ( ABS( A( OFFPI, J ) ) / VN1( J ) )**2
+               TEMP = MAX( TEMP, ZERO )
+               TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+               IF( TEMP2 .LE. TOL3Z ) THEN
+                  IF( OFFPI.LT.M ) THEN
+                     VN1( J ) = SCNRM2( M-OFFPI, A( OFFPI+1, J ), 1 )
+                     VN2( J ) = VN1( J )
+                  ELSE
+                     VN1( J ) = ZERO
+                     VN2( J ) = ZERO
+                  END IF
+               ELSE
+                  VN1( J ) = VN1( J )*SQRT( TEMP )
+               END IF
+            END IF
+   10    CONTINUE
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of CLAQP2
+*
+      END
diff --git a/libcruft/lapack/claqps.f b/libcruft/lapack/claqps.f
new file mode 100644
index 0000000..5d0e6c0
--- /dev/null
+++ b/libcruft/lapack/claqps.f
@@ -0,0 +1,271 @@
+      SUBROUTINE CLAQPS( M, N, OFFSET, NB, KB, A, LDA, JPVT, TAU, VN1,
+     $                   VN2, AUXV, F, LDF )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KB, LDA, LDF, M, N, NB, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               VN1( * ), VN2( * )
+      COMPLEX            A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAQPS computes a step of QR factorization with column pivoting
+*  of a complex M-by-N matrix A by using Blas-3.  It tries to factorize
+*  NB columns from A starting from the row OFFSET+1, and updates all
+*  of the matrix with Blas-3 xGEMM.
+*
+*  In some cases, due to catastrophic cancellations, it cannot
+*  factorize NB columns.  Hence, the actual number of factorized
+*  columns is returned in KB.
+*
+*  Block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of A that have been factorized in
+*          previous steps.
+*
+*  NB      (input) INTEGER
+*          The number of columns to factorize.
+*
+*  KB      (output) INTEGER
+*          The number of columns actually factorized.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, block A(OFFSET+1:M,1:KB) is the triangular
+*          factor obtained and block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*          The rest of the matrix, block A(OFFSET+1:M,KB+1:N) has
+*          been updated.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          JPVT(I) = K <==> Column K of the full matrix A has been
+*          permuted into position I in AP.
+*
+*  TAU     (output) COMPLEX array, dimension (KB)
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) REAL array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) REAL array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  AUXV    (input/output) COMPLEX array, dimension (NB)
+*          Auxiliar vector.
+*
+*  F       (input/output) COMPLEX array, dimension (LDF,NB)
+*          Matrix F' = L*Y'*A.
+*
+*  LDF     (input) INTEGER
+*          The leading dimension of the array F. LDF >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0,
+     $                   CZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            ITEMP, J, K, LASTRK, LSTICC, PVT, RK
+      REAL               TEMP, TEMP2, TOL3Z
+      COMPLEX            AKK
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CGEMV, CLARFG, CSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, CONJG, MAX, MIN, NINT, REAL, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SCNRM2, SLAMCH
+      EXTERNAL           ISAMAX, SCNRM2, SLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+      LASTRK = MIN( M, N+OFFSET )
+      LSTICC = 0
+      K = 0
+      TOL3Z = SQRT(SLAMCH('Epsilon'))
+*
+*     Beginning of while loop.
+*
+   10 CONTINUE
+      IF( ( K.LT.NB ) .AND. ( LSTICC.EQ.0 ) ) THEN
+         K = K + 1
+         RK = OFFSET + K
+*
+*        Determine ith pivot column and swap if necessary
+*
+         PVT = ( K-1 ) + ISAMAX( N-K+1, VN1( K ), 1 )
+         IF( PVT.NE.K ) THEN
+            CALL CSWAP( M, A( 1, PVT ), 1, A( 1, K ), 1 )
+            CALL CSWAP( K-1, F( PVT, 1 ), LDF, F( K, 1 ), LDF )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( K )
+            JPVT( K ) = ITEMP
+            VN1( PVT ) = VN1( K )
+            VN2( PVT ) = VN2( K )
+         END IF
+*
+*        Apply previous Householder reflectors to column K:
+*        A(RK:M,K) := A(RK:M,K) - A(RK:M,1:K-1)*F(K,1:K-1)'.
+*
+         IF( K.GT.1 ) THEN
+            DO 20 J = 1, K - 1
+               F( K, J ) = CONJG( F( K, J ) )
+   20       CONTINUE
+            CALL CGEMV( 'No transpose', M-RK+1, K-1, -CONE, A( RK, 1 ),
+     $                  LDA, F( K, 1 ), LDF, CONE, A( RK, K ), 1 )
+            DO 30 J = 1, K - 1
+               F( K, J ) = CONJG( F( K, J ) )
+   30       CONTINUE
+         END IF
+*
+*        Generate elementary reflector H(k).
+*
+         IF( RK.LT.M ) THEN
+            CALL CLARFG( M-RK+1, A( RK, K ), A( RK+1, K ), 1, TAU( K ) )
+         ELSE
+            CALL CLARFG( 1, A( RK, K ), A( RK, K ), 1, TAU( K ) )
+         END IF
+*
+         AKK = A( RK, K )
+         A( RK, K ) = CONE
+*
+*        Compute Kth column of F:
+*
+*        Compute  F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)'*A(RK:M,K).
+*
+         IF( K.LT.N ) THEN
+            CALL CGEMV( 'Conjugate transpose', M-RK+1, N-K, TAU( K ),
+     $                  A( RK, K+1 ), LDA, A( RK, K ), 1, CZERO,
+     $                  F( K+1, K ), 1 )
+         END IF
+*
+*        Padding F(1:K,K) with zeros.
+*
+         DO 40 J = 1, K
+            F( J, K ) = CZERO
+   40    CONTINUE
+*
+*        Incremental updating of F:
+*        F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)'
+*                    *A(RK:M,K).
+*
+         IF( K.GT.1 ) THEN
+            CALL CGEMV( 'Conjugate transpose', M-RK+1, K-1, -TAU( K ),
+     $                  A( RK, 1 ), LDA, A( RK, K ), 1, CZERO,
+     $                  AUXV( 1 ), 1 )
+*
+            CALL CGEMV( 'No transpose', N, K-1, CONE, F( 1, 1 ), LDF,
+     $                  AUXV( 1 ), 1, CONE, F( 1, K ), 1 )
+         END IF
+*
+*        Update the current row of A:
+*        A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)'.
+*
+         IF( K.LT.N ) THEN
+            CALL CGEMM( 'No transpose', 'Conjugate transpose', 1, N-K,
+     $                  K, -CONE, A( RK, 1 ), LDA, F( K+1, 1 ), LDF,
+     $                  CONE, A( RK, K+1 ), LDA )
+         END IF
+*
+*        Update partial column norms.
+*
+         IF( RK.LT.LASTRK ) THEN
+            DO 50 J = K + 1, N
+               IF( VN1( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*
+                  TEMP = ABS( A( RK, J ) ) / VN1( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN
+                     VN2( J ) = REAL( LSTICC )
+                     LSTICC = J
+                  ELSE
+                     VN1( J ) = VN1( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   50       CONTINUE
+         END IF
+*
+         A( RK, K ) = AKK
+*
+*        End of while loop.
+*
+         GO TO 10
+      END IF
+      KB = K
+      RK = OFFSET + KB
+*
+*     Apply the block reflector to the rest of the matrix:
+*     A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) -
+*                         A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)'.
+*
+      IF( KB.LT.MIN( N, M-OFFSET ) ) THEN
+         CALL CGEMM( 'No transpose', 'Conjugate transpose', M-RK, N-KB,
+     $               KB, -CONE, A( RK+1, 1 ), LDA, F( KB+1, 1 ), LDF,
+     $               CONE, A( RK+1, KB+1 ), LDA )
+      END IF
+*
+*     Recomputation of difficult columns.
+*
+   60 CONTINUE
+      IF( LSTICC.GT.0 ) THEN
+         ITEMP = NINT( VN2( LSTICC ) )
+         VN1( LSTICC ) = SCNRM2( M-RK, A( RK+1, LSTICC ), 1 )
+*
+*        NOTE: The computation of VN1( LSTICC ) relies on the fact that 
+*        SNRM2 does not fail on vectors with norm below the value of
+*        SQRT(DLAMCH('S')) 
+*
+         VN2( LSTICC ) = VN1( LSTICC )
+         LSTICC = ITEMP
+         GO TO 60
+      END IF
+*
+      RETURN
+*
+*     End of CLAQPS
+*
+      END
diff --git a/libcruft/lapack/claqr0.f b/libcruft/lapack/claqr0.f
new file mode 100644
index 0000000..e93f574
--- /dev/null
+++ b/libcruft/lapack/claqr0.f
@@ -0,0 +1,601 @@
+      SUBROUTINE CLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     CLAQR0 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**H, where T is an upper triangular matrix (the
+*     Schur form), and Z is the unitary matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input unitary
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*H*(QZ)**H.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to CGEBAL, and then passed to CGEHRD when the
+*           matrix output by CGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) COMPLEX array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H
+*           contains the upper triangular matrix T from the Schur
+*           decomposition (the Schur form). If INFO = 0 and WANT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     W        (output) COMPLEX array, dimension (N)
+*           The computed eigenvalues of H(ILO:IHI,ILO:IHI) are stored
+*           in W(ILO:IHI). If WANTT is .TRUE., then the eigenvalues are
+*           stored in the same order as on the diagonal of the Schur
+*           form returned in H, with W(i) = H(i,i).
+*
+*     Z     (input/output) COMPLEX array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) COMPLEX array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then CLAQR0 does a workspace query.
+*           In this case, CLAQR0 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, CLAQR0 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is a unitary matrix.  The final
+*                value of  H is upper Hessenberg and triangular in
+*                rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    CLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      REAL               WILK1
+      PARAMETER          ( WILK1 = 0.75e0 )
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            AA, BB, CC, CDUM, DD, DET, RTDISC, SWAP, TR2
+      REAL               S
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACPY, CLAHQR, CLAQR3, CLAQR4, CLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, INT, MAX, MIN, MOD, REAL,
+     $                   SQRT
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use CLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL CLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'CLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'CLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to CLAQR3 ====
+*
+         CALL CLAQR3( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, W, H, LDH, N, H, LDH, N, H,
+     $                LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(CLAQR5, CLAQR3) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = CMPLX( LWKOPT, 0 )
+            RETURN
+         END IF
+*
+*        ==== CLAHQR/CLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'CLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'CLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'CLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 70 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 80
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( CABS1( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      CABS1( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL CLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, W, H( KV, 1 ), LDH, NHO,
+     $                   H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH, WORK,
+     $                   LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if CLAQR3
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    CLAQR3 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, KS + 1, -2
+                     W( I ) = H( I, I ) + WILK1*CABS1( H( I, I-1 ) )
+                     W( I-1 ) = W( I )
+   30             CONTINUE
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use CLAQR4 or
+*                 .    CLAHQR on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL CLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     IF( NS.GT.NMIN ) THEN
+                        CALL CLAQR4( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, W( KS ), 1, 1,
+     $                               ZDUM, 1, WORK, LWORK, INF )
+                     ELSE
+                        CALL CLAHQR( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, W( KS ), 1, 1,
+     $                               ZDUM, 1, INF )
+                     END IF
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  Scale to avoid
+*                    .    overflows, underflows and subnormals.
+*                    .    (The scale factor S can not be zero,
+*                    .    because H(KBOT,KBOT-1) is nonzero.) ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        S = CABS1( H( KBOT-1, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT-1, KBOT ) ) +
+     $                      CABS1( H( KBOT, KBOT ) )
+                        AA = H( KBOT-1, KBOT-1 ) / S
+                        CC = H( KBOT, KBOT-1 ) / S
+                        BB = H( KBOT-1, KBOT ) / S
+                        DD = H( KBOT, KBOT ) / S
+                        TR2 = ( AA+DD ) / TWO
+                        DET = ( AA-TR2 )*( DD-TR2 ) - BB*CC
+                        RTDISC = SQRT( -DET )
+                        W( KBOT-1 ) = ( TR2+RTDISC )*S
+                        W( KBOT ) = ( TR2-RTDISC )*S
+*
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little) ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( CABS1( W( I ) ).LT.CABS1( W( I+1 ) ) )
+     $                          THEN
+                              SORTED = .false.
+                              SWAP = W( I )
+                              W( I ) = W( I+1 )
+                              W( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+*
+*              ==== If there are only two shifts, then use
+*              .    only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( CABS1( W( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                CABS1( W( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                     W( KBOT-1 ) = W( KBOT )
+                  ELSE
+                     W( KBOT ) = W( KBOT-1 )
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL CLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      W( KS ), H, LDH, ILOZ, IHIZ, Z, LDZ, WORK,
+     $                      3, H( KU, 1 ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                      NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   70    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   80    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = CMPLX( LWKOPT, 0 )
+*
+*     ==== End of CLAQR0 ====
+*
+      END
diff --git a/libcruft/lapack/claqr1.f b/libcruft/lapack/claqr1.f
new file mode 100644
index 0000000..c491268
--- /dev/null
+++ b/libcruft/lapack/claqr1.f
@@ -0,0 +1,97 @@
+      SUBROUTINE CLAQR1( N, H, LDH, S1, S2, V )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      COMPLEX            S1, S2
+      INTEGER            LDH, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), V( * )
+*     ..
+*
+*       Given a 2-by-2 or 3-by-3 matrix H, CLAQR1 sets v to a
+*       scalar multiple of the first column of the product
+*
+*       (*)  K = (H - s1*I)*(H - s2*I)
+*
+*       scaling to avoid overflows and most underflows.
+*
+*       This is useful for starting double implicit shift bulges
+*       in the QR algorithm.
+*
+*
+*       N      (input) integer
+*              Order of the matrix H. N must be either 2 or 3.
+*
+*       H      (input) COMPLEX array of dimension (LDH,N)
+*              The 2-by-2 or 3-by-3 matrix H in (*).
+*
+*       LDH    (input) integer
+*              The leading dimension of H as declared in
+*              the calling procedure.  LDH.GE.N
+*
+*       S1     (input) COMPLEX
+*       S2     S1 and S2 are the shifts defining K in (*) above.
+*
+*       V      (output) COMPLEX array of dimension N
+*              A scalar multiple of the first column of the
+*              matrix K in (*).
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ) )
+      REAL               RZERO
+      PARAMETER          ( RZERO = 0.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            CDUM
+      REAL               H21S, H31S, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+      IF( N.EQ.2 ) THEN
+         S = CABS1( H( 1, 1 )-S2 ) + CABS1( H( 2, 1 ) )
+         IF( S.EQ.RZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            V( 1 ) = H21S*H( 1, 2 ) + ( H( 1, 1 )-S1 )*
+     $               ( ( H( 1, 1 )-S2 ) / S )
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-S1-S2 )
+         END IF
+      ELSE
+         S = CABS1( H( 1, 1 )-S2 ) + CABS1( H( 2, 1 ) ) +
+     $       CABS1( H( 3, 1 ) )
+         IF( S.EQ.ZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+            V( 3 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            H31S = H( 3, 1 ) / S
+            V( 1 ) = ( H( 1, 1 )-S1 )*( ( H( 1, 1 )-S2 ) / S ) +
+     $               H( 1, 2 )*H21S + H( 1, 3 )*H31S
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-S1-S2 ) + H( 2, 3 )*H31S
+            V( 3 ) = H31S*( H( 1, 1 )+H( 3, 3 )-S1-S2 ) + H21S*H( 3, 2 )
+         END IF
+      END IF
+      END
diff --git a/libcruft/lapack/claqr2.f b/libcruft/lapack/claqr2.f
new file mode 100644
index 0000000..2bdea99
--- /dev/null
+++ b/libcruft/lapack/claqr2.f
@@ -0,0 +1,438 @@
+      SUBROUTINE CLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
+     $                   NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), SH( * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( * ), WV( LDWV, * ), Z( LDZ, * )
+*     ..
+*
+*     This subroutine is identical to CLAQR3 except that it avoids
+*     recursion by calling CLAHQR instead of CLAQR4.
+*
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an unitary similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an unitary similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the unitary matrix Z is updated so
+*          so that the unitary Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the unitary matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) COMPLEX array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by a unitary
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) COMPLEX array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the unitary
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SH      (output) COMPLEX array, dimension KBOT
+*          On output, approximate eigenvalues that may
+*          be used for shifts are stored in SH(KBOT-ND-NS+1)
+*          through SR(KBOT-ND).  Converged eigenvalues are
+*          stored in SH(KBOT-ND+1) through SH(KBOT).
+*
+*     V       (workspace) COMPLEX array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) COMPLEX array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) COMPLEX array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) COMPLEX array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; CLAQR2
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               RZERO, RONE
+      PARAMETER          ( RZERO = 0.0e0, RONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            BETA, CDUM, S, TAU
+      REAL               FOO, SAFMAX, SAFMIN, SMLNUM, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, KCOL, KLN,
+     $                   KNT, KROW, KWTOP, LTOP, LWK1, LWK2, LWKOPT
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEHRD, CGEMM, CLACPY, CLAHQR, CLARF,
+     $                   CLARFG, CLASET, CTREXC, CUNGHR, SLABAD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, INT, MAX, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to CGEHRD ====
+*
+         CALL CGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to CUNGHR ====
+*
+         CALL CUNGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = JW + MAX( LWK1, LWK2 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = CMPLX( LWKOPT, 0 )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SH( KWTOP ) = H( KWTOP, KWTOP )
+         NS = 1
+         ND = 0
+         IF( CABS1( S ).LE.MAX( SMLNUM, ULP*CABS1( H( KWTOP,
+     $       KWTOP ) ) ) ) THEN
+
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL CLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL CCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL CLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      CALL CLAHQR( .true., .true., JW, 1, JW, T, LDT, SH( KWTOP ), 1,
+     $             JW, V, LDV, INFQR )
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+      DO 10 KNT = INFQR + 1, JW
+*
+*        ==== Small spike tip deflation test ====
+*
+         FOO = CABS1( T( NS, NS ) )
+         IF( FOO.EQ.RZERO )
+     $      FOO = CABS1( S )
+         IF( CABS1( S )*CABS1( V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) )
+     $        THEN
+*
+*           ==== One more converged eigenvalue ====
+*
+            NS = NS - 1
+         ELSE
+*
+*           ==== One undflatable eigenvalue.  Move it up out of the
+*           .    way.   (CTREXC can not fail in this case.) ====
+*
+            IFST = NS
+            CALL CTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+            ILST = ILST + 1
+         END IF
+   10 CONTINUE
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting the diagonal of T improves accuracy for
+*        .    graded matrices.  ====
+*
+         DO 30 I = INFQR + 1, NS
+            IFST = I
+            DO 20 J = I + 1, NS
+               IF( CABS1( T( J, J ) ).GT.CABS1( T( IFST, IFST ) ) )
+     $            IFST = J
+   20       CONTINUE
+            ILST = I
+            IF( IFST.NE.ILST )
+     $         CALL CTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+   30    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      DO 40 I = INFQR + 1, JW
+         SH( KWTOP+I-1 ) = T( I, I )
+   40 CONTINUE
+*
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL CCOPY( NS, V, LDV, WORK, 1 )
+            DO 50 I = 1, NS
+               WORK( I ) = CONJG( WORK( I ) )
+   50       CONTINUE
+            BETA = WORK( 1 )
+            CALL CLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL CLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL CLARF( 'L', NS, JW, WORK, 1, CONJG( TAU ), T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL CLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL CLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL CGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*CONJG( V( 1, 1 ) )
+         CALL CLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL CCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  CUNGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL CUNGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL CGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL CLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 60 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL CGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL CLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   60    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 70 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL CGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL CLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   70       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 80 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL CGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL CLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   80       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = CMPLX( LWKOPT, 0 )
+*
+*     ==== End of CLAQR2 ====
+*
+      END
diff --git a/libcruft/lapack/claqr3.f b/libcruft/lapack/claqr3.f
new file mode 100644
index 0000000..7fbcdb4
--- /dev/null
+++ b/libcruft/lapack/claqr3.f
@@ -0,0 +1,448 @@
+      SUBROUTINE CLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
+     $                   NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), SH( * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( * ), WV( LDWV, * ), Z( LDZ, * )
+*     ..
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an unitary similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an unitary similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the unitary matrix Z is updated so
+*          so that the unitary Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the unitary matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) COMPLEX array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by a unitary
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) COMPLEX array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the unitary
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SH      (output) COMPLEX array, dimension KBOT
+*          On output, approximate eigenvalues that may
+*          be used for shifts are stored in SH(KBOT-ND-NS+1)
+*          through SR(KBOT-ND).  Converged eigenvalues are
+*          stored in SH(KBOT-ND+1) through SH(KBOT).
+*
+*     V       (workspace) COMPLEX array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) COMPLEX array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) COMPLEX array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) COMPLEX array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; CLAQR3
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               RZERO, RONE
+      PARAMETER          ( RZERO = 0.0e0, RONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            BETA, CDUM, S, TAU
+      REAL               FOO, SAFMAX, SAFMIN, SMLNUM, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, KCOL, KLN,
+     $                   KNT, KROW, KWTOP, LTOP, LWK1, LWK2, LWK3,
+     $                   LWKOPT, NMIN
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      INTEGER            ILAENV
+      EXTERNAL           SLAMCH, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEHRD, CGEMM, CLACPY, CLAHQR, CLAQR4,
+     $                   CLARF, CLARFG, CLASET, CTREXC, CUNGHR, SLABAD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, INT, MAX, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to CGEHRD ====
+*
+         CALL CGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to CUNGHR ====
+*
+         CALL CUNGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to CLAQR4 ====
+*
+         CALL CLAQR4( .true., .true., JW, 1, JW, T, LDT, SH, 1, JW, V,
+     $                LDV, WORK, -1, INFQR )
+         LWK3 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = MAX( JW+MAX( LWK1, LWK2 ), LWK3 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = CMPLX( LWKOPT, 0 )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SH( KWTOP ) = H( KWTOP, KWTOP )
+         NS = 1
+         ND = 0
+         IF( CABS1( S ).LE.MAX( SMLNUM, ULP*CABS1( H( KWTOP,
+     $       KWTOP ) ) ) ) THEN
+
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL CLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL CCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL CLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      NMIN = ILAENV( 12, 'CLAQR3', 'SV', JW, 1, JW, LWORK )
+      IF( JW.GT.NMIN ) THEN
+         CALL CLAQR4( .true., .true., JW, 1, JW, T, LDT, SH( KWTOP ), 1,
+     $                JW, V, LDV, WORK, LWORK, INFQR )
+      ELSE
+         CALL CLAHQR( .true., .true., JW, 1, JW, T, LDT, SH( KWTOP ), 1,
+     $                JW, V, LDV, INFQR )
+      END IF
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+      DO 10 KNT = INFQR + 1, JW
+*
+*        ==== Small spike tip deflation test ====
+*
+         FOO = CABS1( T( NS, NS ) )
+         IF( FOO.EQ.RZERO )
+     $      FOO = CABS1( S )
+         IF( CABS1( S )*CABS1( V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) )
+     $        THEN
+*
+*           ==== One more converged eigenvalue ====
+*
+            NS = NS - 1
+         ELSE
+*
+*           ==== One undflatable eigenvalue.  Move it up out of the
+*           .    way.   (CTREXC can not fail in this case.) ====
+*
+            IFST = NS
+            CALL CTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+            ILST = ILST + 1
+         END IF
+   10 CONTINUE
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting the diagonal of T improves accuracy for
+*        .    graded matrices.  ====
+*
+         DO 30 I = INFQR + 1, NS
+            IFST = I
+            DO 20 J = I + 1, NS
+               IF( CABS1( T( J, J ) ).GT.CABS1( T( IFST, IFST ) ) )
+     $            IFST = J
+   20       CONTINUE
+            ILST = I
+            IF( IFST.NE.ILST )
+     $         CALL CTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+   30    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      DO 40 I = INFQR + 1, JW
+         SH( KWTOP+I-1 ) = T( I, I )
+   40 CONTINUE
+*
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL CCOPY( NS, V, LDV, WORK, 1 )
+            DO 50 I = 1, NS
+               WORK( I ) = CONJG( WORK( I ) )
+   50       CONTINUE
+            BETA = WORK( 1 )
+            CALL CLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL CLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL CLARF( 'L', NS, JW, WORK, 1, CONJG( TAU ), T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL CLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL CLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL CGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*CONJG( V( 1, 1 ) )
+         CALL CLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL CCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  CUNGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL CUNGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL CGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL CLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 60 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL CGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL CLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   60    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 70 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL CGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL CLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   70       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 80 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL CGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL CLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   80       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = CMPLX( LWKOPT, 0 )
+*
+*     ==== End of CLAQR3 ====
+*
+      END
diff --git a/libcruft/lapack/claqr4.f b/libcruft/lapack/claqr4.f
new file mode 100644
index 0000000..7e4fe4d
--- /dev/null
+++ b/libcruft/lapack/claqr4.f
@@ -0,0 +1,602 @@
+      SUBROUTINE CLAQR4( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*
+*     This subroutine implements one level of recursion for CLAQR0.
+*     It is a complete implementation of the small bulge multi-shift
+*     QR algorithm.  It may be called by CLAQR0 and, for large enough
+*     deflation window size, it may be called by CLAQR3.  This
+*     subroutine is identical to CLAQR0 except that it calls CLAQR2
+*     instead of CLAQR3.
+*
+*     Purpose
+*     =======
+*
+*     CLAQR4 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**H, where T is an upper triangular matrix (the
+*     Schur form), and Z is the unitary matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input unitary
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*H*(QZ)**H.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to CGEBAL, and then passed to CGEHRD when the
+*           matrix output by CGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) COMPLEX array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H
+*           contains the upper triangular matrix T from the Schur
+*           decomposition (the Schur form). If INFO = 0 and WANT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     W        (output) COMPLEX array, dimension (N)
+*           The computed eigenvalues of H(ILO:IHI,ILO:IHI) are stored
+*           in W(ILO:IHI). If WANTT is .TRUE., then the eigenvalues are
+*           stored in the same order as on the diagonal of the Schur
+*           form returned in H, with W(i) = H(i,i).
+*
+*     Z     (input/output) COMPLEX array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) COMPLEX array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then CLAQR4 does a workspace query.
+*           In this case, CLAQR4 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, CLAQR4 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is a unitary matrix.  The final
+*                value of  H is upper Hessenberg and triangular in
+*                rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    CLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      REAL               WILK1
+      PARAMETER          ( WILK1 = 0.75e0 )
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            AA, BB, CC, CDUM, DD, DET, RTDISC, SWAP, TR2
+      REAL               S
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACPY, CLAHQR, CLAQR2, CLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, INT, MAX, MIN, MOD, REAL,
+     $                   SQRT
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use CLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL CLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'CLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'CLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to CLAQR2 ====
+*
+         CALL CLAQR2( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, W, H, LDH, N, H, LDH, N, H,
+     $                LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(CLAQR5, CLAQR2) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = CMPLX( LWKOPT, 0 )
+            RETURN
+         END IF
+*
+*        ==== CLAHQR/CLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'CLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'CLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'CLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 70 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 80
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( CABS1( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      CABS1( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL CLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, W, H( KV, 1 ), LDH, NHO,
+     $                   H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH, WORK,
+     $                   LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if CLAQR2
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    CLAQR2 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, KS + 1, -2
+                     W( I ) = H( I, I ) + WILK1*CABS1( H( I, I-1 ) )
+                     W( I-1 ) = W( I )
+   30             CONTINUE
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use CLAHQR
+*                 .    on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL CLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     CALL CLAHQR( .false., .false., NS, 1, NS,
+     $                            H( KT, 1 ), LDH, W( KS ), 1, 1, ZDUM,
+     $                            1, INF )
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  Scale to avoid
+*                    .    overflows, underflows and subnormals.
+*                    .    (The scale factor S can not be zero,
+*                    .    because H(KBOT,KBOT-1) is nonzero.) ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        S = CABS1( H( KBOT-1, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT-1, KBOT ) ) +
+     $                      CABS1( H( KBOT, KBOT ) )
+                        AA = H( KBOT-1, KBOT-1 ) / S
+                        CC = H( KBOT, KBOT-1 ) / S
+                        BB = H( KBOT-1, KBOT ) / S
+                        DD = H( KBOT, KBOT ) / S
+                        TR2 = ( AA+DD ) / TWO
+                        DET = ( AA-TR2 )*( DD-TR2 ) - BB*CC
+                        RTDISC = SQRT( -DET )
+                        W( KBOT-1 ) = ( TR2+RTDISC )*S
+                        W( KBOT ) = ( TR2-RTDISC )*S
+*
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little) ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( CABS1( W( I ) ).LT.CABS1( W( I+1 ) ) )
+     $                          THEN
+                              SORTED = .false.
+                              SWAP = W( I )
+                              W( I ) = W( I+1 )
+                              W( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+*
+*              ==== If there are only two shifts, then use
+*              .    only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( CABS1( W( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                CABS1( W( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                     W( KBOT-1 ) = W( KBOT )
+                  ELSE
+                     W( KBOT ) = W( KBOT-1 )
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL CLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      W( KS ), H, LDH, ILOZ, IHIZ, Z, LDZ, WORK,
+     $                      3, H( KU, 1 ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                      NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   70    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   80    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = CMPLX( LWKOPT, 0 )
+*
+*     ==== End of CLAQR4 ====
+*
+      END
diff --git a/libcruft/lapack/claqr5.f b/libcruft/lapack/claqr5.f
new file mode 100644
index 0000000..0fb2bbd
--- /dev/null
+++ b/libcruft/lapack/claqr5.f
@@ -0,0 +1,809 @@
+      SUBROUTINE CLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS, S,
+     $                   H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, LDU, NV,
+     $                   WV, LDWV, NH, WH, LDWH )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
+     $                   LDWH, LDWV, LDZ, N, NH, NSHFTS, NV
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            H( LDH, * ), S( * ), U( LDU, * ), V( LDV, * ),
+     $                   WH( LDWH, * ), WV( LDWV, * ), Z( LDZ, * )
+*     ..
+*
+*     This auxiliary subroutine called by CLAQR0 performs a
+*     single small-bulge multi-shift QR sweep.
+*
+*      WANTT  (input) logical scalar
+*             WANTT = .true. if the triangular Schur factor
+*             is being computed.  WANTT is set to .false. otherwise.
+*
+*      WANTZ  (input) logical scalar
+*             WANTZ = .true. if the unitary Schur factor is being
+*             computed.  WANTZ is set to .false. otherwise.
+*
+*      KACC22 (input) integer with value 0, 1, or 2.
+*             Specifies the computation mode of far-from-diagonal
+*             orthogonal updates.
+*        = 0: CLAQR5 does not accumulate reflections and does not
+*             use matrix-matrix multiply to update far-from-diagonal
+*             matrix entries.
+*        = 1: CLAQR5 accumulates reflections and uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries.
+*        = 2: CLAQR5 accumulates reflections, uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries,
+*             and takes advantage of 2-by-2 block structure during
+*             matrix multiplies.
+*
+*      N      (input) integer scalar
+*             N is the order of the Hessenberg matrix H upon which this
+*             subroutine operates.
+*
+*      KTOP   (input) integer scalar
+*      KBOT   (input) integer scalar
+*             These are the first and last rows and columns of an
+*             isolated diagonal block upon which the QR sweep is to be
+*             applied. It is assumed without a check that
+*                       either KTOP = 1  or   H(KTOP,KTOP-1) = 0
+*             and
+*                       either KBOT = N  or   H(KBOT+1,KBOT) = 0.
+*
+*      NSHFTS (input) integer scalar
+*             NSHFTS gives the number of simultaneous shifts.  NSHFTS
+*             must be positive and even.
+*
+*      S      (input) COMPLEX array of size (NSHFTS)
+*             S contains the shifts of origin that define the multi-
+*             shift QR sweep.
+*
+*      H      (input/output) COMPLEX array of size (LDH,N)
+*             On input H contains a Hessenberg matrix.  On output a
+*             multi-shift QR sweep with shifts SR(J)+i*SI(J) is applied
+*             to the isolated diagonal block in rows and columns KTOP
+*             through KBOT.
+*
+*      LDH    (input) integer scalar
+*             LDH is the leading dimension of H just as declared in the
+*             calling procedure.  LDH.GE.MAX(1,N).
+*
+*      ILOZ   (input) INTEGER
+*      IHIZ   (input) INTEGER
+*             Specify the rows of Z to which transformations must be
+*             applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N
+*
+*      Z      (input/output) COMPLEX array of size (LDZ,IHI)
+*             If WANTZ = .TRUE., then the QR Sweep unitary
+*             similarity transformation is accumulated into
+*             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*             If WANTZ = .FALSE., then Z is unreferenced.
+*
+*      LDZ    (input) integer scalar
+*             LDA is the leading dimension of Z just as declared in
+*             the calling procedure. LDZ.GE.N.
+*
+*      V      (workspace) COMPLEX array of size (LDV,NSHFTS/2)
+*
+*      LDV    (input) integer scalar
+*             LDV is the leading dimension of V as declared in the
+*             calling procedure.  LDV.GE.3.
+*
+*      U      (workspace) COMPLEX array of size
+*             (LDU,3*NSHFTS-3)
+*
+*      LDU    (input) integer scalar
+*             LDU is the leading dimension of U just as declared in the
+*             in the calling subroutine.  LDU.GE.3*NSHFTS-3.
+*
+*      NH     (input) integer scalar
+*             NH is the number of columns in array WH available for
+*             workspace. NH.GE.1.
+*
+*      WH     (workspace) COMPLEX array of size (LDWH,NH)
+*
+*      LDWH   (input) integer scalar
+*             Leading dimension of WH just as declared in the
+*             calling procedure.  LDWH.GE.3*NSHFTS-3.
+*
+*      NV     (input) integer scalar
+*             NV is the number of rows in WV agailable for workspace.
+*             NV.GE.1.
+*
+*      WV     (workspace) COMPLEX array of size
+*             (LDWV,3*NSHFTS-3)
+*
+*      LDWV   (input) integer scalar
+*             LDWV is the leading dimension of WV as declared in the
+*             in the calling subroutine.  LDWV.GE.NV.
+*
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ============================================================
+*     Reference:
+*
+*     K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*     Algorithm Part I: Maintaining Well Focused Shifts, and
+*     Level 3 Performance, SIAM Journal of Matrix Analysis,
+*     volume 23, pages 929--947, 2002.
+*
+*     ============================================================
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0e0, 0.0e0 ),
+     $                   ONE = ( 1.0e0, 0.0e0 ) )
+      REAL               RZERO, RONE
+      PARAMETER          ( RZERO = 0.0e0, RONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX            ALPHA, BETA, CDUM, REFSUM
+      REAL               H11, H12, H21, H22, SAFMAX, SAFMIN, SCL,
+     $                   SMLNUM, TST1, TST2, ULP
+      INTEGER            I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN,
+     $                   JROW, JTOP, K, K1, KDU, KMS, KNZ, KRCOL, KZS,
+     $                   M, M22, MBOT, MEND, MSTART, MTOP, NBMPS, NDCOL,
+     $                   NS, NU
+      LOGICAL            ACCUM, BLK22, BMP22
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+*
+      INTRINSIC          ABS, AIMAG, CONJG, MAX, MIN, MOD, REAL
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            VT( 3 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CLACPY, CLAQR1, CLARFG, CLASET, CTRMM,
+     $                   SLABAD
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== If there are no shifts, then there is nothing to do. ====
+*
+      IF( NSHFTS.LT.2 )
+     $   RETURN
+*
+*     ==== If the active block is empty or 1-by-1, then there
+*     .    is nothing to do. ====
+*
+      IF( KTOP.GE.KBOT )
+     $   RETURN
+*
+*     ==== NSHFTS is supposed to be even, but if is odd,
+*     .    then simply reduce it by one.  ====
+*
+      NS = NSHFTS - MOD( NSHFTS, 2 )
+*
+*     ==== Machine constants for deflation ====
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( N ) / ULP )
+*
+*     ==== Use accumulated reflections to update far-from-diagonal
+*     .    entries ? ====
+*
+      ACCUM = ( KACC22.EQ.1 ) .OR. ( KACC22.EQ.2 )
+*
+*     ==== If so, exploit the 2-by-2 block structure? ====
+*
+      BLK22 = ( NS.GT.2 ) .AND. ( KACC22.EQ.2 )
+*
+*     ==== clear trash ====
+*
+      IF( KTOP+2.LE.KBOT )
+     $   H( KTOP+2, KTOP ) = ZERO
+*
+*     ==== NBMPS = number of 2-shift bulges in the chain ====
+*
+      NBMPS = NS / 2
+*
+*     ==== KDU = width of slab ====
+*
+      KDU = 6*NBMPS - 3
+*
+*     ==== Create and chase chains of NBMPS bulges ====
+*
+      DO 210 INCOL = 3*( 1-NBMPS ) + KTOP - 1, KBOT - 2, 3*NBMPS - 2
+         NDCOL = INCOL + KDU
+         IF( ACCUM )
+     $      CALL CLASET( 'ALL', KDU, KDU, ZERO, ONE, U, LDU )
+*
+*        ==== Near-the-diagonal bulge chase.  The following loop
+*        .    performs the near-the-diagonal part of a small bulge
+*        .    multi-shift QR sweep.  Each 6*NBMPS-2 column diagonal
+*        .    chunk extends from column INCOL to column NDCOL
+*        .    (including both column INCOL and column NDCOL). The
+*        .    following loop chases a 3*NBMPS column long chain of
+*        .    NBMPS bulges 3*NBMPS-2 columns to the right.  (INCOL
+*        .    may be less than KTOP and and NDCOL may be greater than
+*        .    KBOT indicating phantom columns from which to chase
+*        .    bulges before they are actually introduced or to which
+*        .    to chase bulges beyond column KBOT.)  ====
+*
+         DO 140 KRCOL = INCOL, MIN( INCOL+3*NBMPS-3, KBOT-2 )
+*
+*           ==== Bulges number MTOP to MBOT are active double implicit
+*           .    shift bulges.  There may or may not also be small
+*           .    2-by-2 bulge, if there is room.  The inactive bulges
+*           .    (if any) must wait until the active bulges have moved
+*           .    down the diagonal to make room.  The phantom matrix
+*           .    paradigm described above helps keep track.  ====
+*
+            MTOP = MAX( 1, ( ( KTOP-1 )-KRCOL+2 ) / 3+1 )
+            MBOT = MIN( NBMPS, ( KBOT-KRCOL ) / 3 )
+            M22 = MBOT + 1
+            BMP22 = ( MBOT.LT.NBMPS ) .AND. ( KRCOL+3*( M22-1 ) ).EQ.
+     $              ( KBOT-2 )
+*
+*           ==== Generate reflections to chase the chain right
+*           .    one column.  (The minimum value of K is KTOP-1.) ====
+*
+            DO 10 M = MTOP, MBOT
+               K = KRCOL + 3*( M-1 )
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL CLAQR1( 3, H( KTOP, KTOP ), LDH, S( 2*M-1 ),
+     $                         S( 2*M ), V( 1, M ) )
+                  ALPHA = V( 1, M )
+                  CALL CLARFG( 3, ALPHA, V( 2, M ), 1, V( 1, M ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M ) = H( K+2, K )
+                  V( 3, M ) = H( K+3, K )
+                  CALL CLARFG( 3, BETA, V( 2, M ), 1, V( 1, M ) )
+*
+*                 ==== A Bulge may collapse because of vigilant
+*                 .    deflation or destructive underflow.  (The
+*                 .    initial bulge is always collapsed.) Use
+*                 .    the two-small-subdiagonals trick to try
+*                 .    to get it started again. If V(2,M).NE.0 and
+*                 .    V(3,M) = H(K+3,K+1) = H(K+3,K+2) = 0, then
+*                 .    this bulge is collapsing into a zero
+*                 .    subdiagonal.  It will be restarted next
+*                 .    trip through the loop.)
+*
+                  IF( V( 1, M ).NE.ZERO .AND.
+     $                ( V( 3, M ).NE.ZERO .OR. ( H( K+3,
+     $                K+1 ).EQ.ZERO .AND. H( K+3, K+2 ).EQ.ZERO ) ) )
+     $                 THEN
+*
+*                    ==== Typical case: not collapsed (yet). ====
+*
+                     H( K+1, K ) = BETA
+                     H( K+2, K ) = ZERO
+                     H( K+3, K ) = ZERO
+                  ELSE
+*
+*                    ==== Atypical case: collapsed.  Attempt to
+*                    .    reintroduce ignoring H(K+1,K).  If the
+*                    .    fill resulting from the new reflector
+*                    .    is too large, then abandon it.
+*                    .    Otherwise, use the new one. ====
+*
+                     CALL CLAQR1( 3, H( K+1, K+1 ), LDH, S( 2*M-1 ),
+     $                            S( 2*M ), VT )
+                     SCL = CABS1( VT( 1 ) ) + CABS1( VT( 2 ) ) +
+     $                     CABS1( VT( 3 ) )
+                     IF( SCL.NE.RZERO ) THEN
+                        VT( 1 ) = VT( 1 ) / SCL
+                        VT( 2 ) = VT( 2 ) / SCL
+                        VT( 3 ) = VT( 3 ) / SCL
+                     END IF
+*
+*                    ==== The following is the traditional and
+*                    .    conservative two-small-subdiagonals
+*                    .    test.  ====
+*                    .
+                     IF( CABS1( H( K+1, K ) )*
+     $                   ( CABS1( VT( 2 ) )+CABS1( VT( 3 ) ) ).GT.ULP*
+     $                   CABS1( VT( 1 ) )*( CABS1( H( K,
+     $                   K ) )+CABS1( H( K+1, K+1 ) )+CABS1( H( K+2,
+     $                   K+2 ) ) ) ) THEN
+*
+*                       ==== Starting a new bulge here would
+*                       .    create non-negligible fill.   If
+*                       .    the old reflector is diagonal (only
+*                       .    possible with underflows), then
+*                       .    change it to I.  Otherwise, use
+*                       .    it with trepidation. ====
+*
+                        IF( V( 2, M ).EQ.ZERO .AND. V( 3, M ).EQ.ZERO )
+     $                       THEN
+                           V( 1, M ) = ZERO
+                        ELSE
+                           H( K+1, K ) = BETA
+                           H( K+2, K ) = ZERO
+                           H( K+3, K ) = ZERO
+                        END IF
+                     ELSE
+*
+*                       ==== Stating a new bulge here would
+*                       .    create only negligible fill.
+*                       .    Replace the old reflector with
+*                       .    the new one. ====
+*
+                        ALPHA = VT( 1 )
+                        CALL CLARFG( 3, ALPHA, VT( 2 ), 1, VT( 1 ) )
+                        REFSUM = H( K+1, K ) +
+     $                           H( K+2, K )*CONJG( VT( 2 ) ) +
+     $                           H( K+3, K )*CONJG( VT( 3 ) )
+                        H( K+1, K ) = H( K+1, K ) -
+     $                                CONJG( VT( 1 ) )*REFSUM
+                        H( K+2, K ) = ZERO
+                        H( K+3, K ) = ZERO
+                        V( 1, M ) = VT( 1 )
+                        V( 2, M ) = VT( 2 )
+                        V( 3, M ) = VT( 3 )
+                     END IF
+                  END IF
+               END IF
+   10       CONTINUE
+*
+*           ==== Generate a 2-by-2 reflection, if needed. ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 ) THEN
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL CLAQR1( 2, H( K+1, K+1 ), LDH, S( 2*M22-1 ),
+     $                         S( 2*M22 ), V( 1, M22 ) )
+                  BETA = V( 1, M22 )
+                  CALL CLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M22 ) = H( K+2, K )
+                  CALL CLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+                  H( K+1, K ) = BETA
+                  H( K+2, K ) = ZERO
+               END IF
+            ELSE
+*
+*              ==== Initialize V(1,M22) here to avoid possible undefined
+*              .    variable problems later. ====
+*
+               V( 1, M22 ) = ZERO
+            END IF
+*
+*           ==== Multiply H by reflections from the left ====
+*
+            IF( ACCUM ) THEN
+               JBOT = MIN( NDCOL, KBOT )
+            ELSE IF( WANTT ) THEN
+               JBOT = N
+            ELSE
+               JBOT = KBOT
+            END IF
+            DO 30 J = MAX( KTOP, KRCOL ), JBOT
+               MEND = MIN( MBOT, ( J-KRCOL+2 ) / 3 )
+               DO 20 M = MTOP, MEND
+                  K = KRCOL + 3*( M-1 )
+                  REFSUM = CONJG( V( 1, M ) )*
+     $                     ( H( K+1, J )+CONJG( V( 2, M ) )*H( K+2, J )+
+     $                     CONJG( V( 3, M ) )*H( K+3, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M )
+                  H( K+3, J ) = H( K+3, J ) - REFSUM*V( 3, M )
+   20          CONTINUE
+   30       CONTINUE
+            IF( BMP22 ) THEN
+               K = KRCOL + 3*( M22-1 )
+               DO 40 J = MAX( K+1, KTOP ), JBOT
+                  REFSUM = CONJG( V( 1, M22 ) )*
+     $                     ( H( K+1, J )+CONJG( V( 2, M22 ) )*
+     $                     H( K+2, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M22 )
+   40          CONTINUE
+            END IF
+*
+*           ==== Multiply H by reflections from the right.
+*           .    Delay filling in the last row until the
+*           .    vigilant deflation check is complete. ====
+*
+            IF( ACCUM ) THEN
+               JTOP = MAX( KTOP, INCOL )
+            ELSE IF( WANTT ) THEN
+               JTOP = 1
+            ELSE
+               JTOP = KTOP
+            END IF
+            DO 80 M = MTOP, MBOT
+               IF( V( 1, M ).NE.ZERO ) THEN
+                  K = KRCOL + 3*( M-1 )
+                  DO 50 J = JTOP, MIN( KBOT, K+3 )
+                     REFSUM = V( 1, M )*( H( J, K+1 )+V( 2, M )*
+     $                        H( J, K+2 )+V( 3, M )*H( J, K+3 ) )
+                     H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                     H( J, K+2 ) = H( J, K+2 ) -
+     $                             REFSUM*CONJG( V( 2, M ) )
+                     H( J, K+3 ) = H( J, K+3 ) -
+     $                             REFSUM*CONJG( V( 3, M ) )
+   50             CONTINUE
+*
+                  IF( ACCUM ) THEN
+*
+*                    ==== Accumulate U. (If necessary, update Z later
+*                    .    with with an efficient matrix-matrix
+*                    .    multiply.) ====
+*
+                     KMS = K - INCOL
+                     DO 60 J = MAX( 1, KTOP-INCOL ), KDU
+                        REFSUM = V( 1, M )*( U( J, KMS+1 )+V( 2, M )*
+     $                           U( J, KMS+2 )+V( 3, M )*U( J, KMS+3 ) )
+                        U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                        U( J, KMS+2 ) = U( J, KMS+2 ) -
+     $                                  REFSUM*CONJG( V( 2, M ) )
+                        U( J, KMS+3 ) = U( J, KMS+3 ) -
+     $                                  REFSUM*CONJG( V( 3, M ) )
+   60                CONTINUE
+                  ELSE IF( WANTZ ) THEN
+*
+*                    ==== U is not accumulated, so update Z
+*                    .    now by multiplying by reflections
+*                    .    from the right. ====
+*
+                     DO 70 J = ILOZ, IHIZ
+                        REFSUM = V( 1, M )*( Z( J, K+1 )+V( 2, M )*
+     $                           Z( J, K+2 )+V( 3, M )*Z( J, K+3 ) )
+                        Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                        Z( J, K+2 ) = Z( J, K+2 ) -
+     $                                REFSUM*CONJG( V( 2, M ) )
+                        Z( J, K+3 ) = Z( J, K+3 ) -
+     $                                REFSUM*CONJG( V( 3, M ) )
+   70                CONTINUE
+                  END IF
+               END IF
+   80       CONTINUE
+*
+*           ==== Special case: 2-by-2 reflection (if needed) ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 .AND. ( V( 1, M22 ).NE.ZERO ) ) THEN
+               DO 90 J = JTOP, MIN( KBOT, K+3 )
+                  REFSUM = V( 1, M22 )*( H( J, K+1 )+V( 2, M22 )*
+     $                     H( J, K+2 ) )
+                  H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                  H( J, K+2 ) = H( J, K+2 ) -
+     $                          REFSUM*CONJG( V( 2, M22 ) )
+   90          CONTINUE
+*
+               IF( ACCUM ) THEN
+                  KMS = K - INCOL
+                  DO 100 J = MAX( 1, KTOP-INCOL ), KDU
+                     REFSUM = V( 1, M22 )*( U( J, KMS+1 )+V( 2, M22 )*
+     $                        U( J, KMS+2 ) )
+                     U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                     U( J, KMS+2 ) = U( J, KMS+2 ) -
+     $                               REFSUM*CONJG( V( 2, M22 ) )
+  100             CONTINUE
+               ELSE IF( WANTZ ) THEN
+                  DO 110 J = ILOZ, IHIZ
+                     REFSUM = V( 1, M22 )*( Z( J, K+1 )+V( 2, M22 )*
+     $                        Z( J, K+2 ) )
+                     Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                     Z( J, K+2 ) = Z( J, K+2 ) -
+     $                             REFSUM*CONJG( V( 2, M22 ) )
+  110             CONTINUE
+               END IF
+            END IF
+*
+*           ==== Vigilant deflation check ====
+*
+            MSTART = MTOP
+            IF( KRCOL+3*( MSTART-1 ).LT.KTOP )
+     $         MSTART = MSTART + 1
+            MEND = MBOT
+            IF( BMP22 )
+     $         MEND = MEND + 1
+            IF( KRCOL.EQ.KBOT-2 )
+     $         MEND = MEND + 1
+            DO 120 M = MSTART, MEND
+               K = MIN( KBOT-1, KRCOL+3*( M-1 ) )
+*
+*              ==== The following convergence test requires that
+*              .    the tradition small-compared-to-nearby-diagonals
+*              .    criterion and the Ahues & Tisseur (LAWN 122, 1997)
+*              .    criteria both be satisfied.  The latter improves
+*              .    accuracy in some examples. Falling back on an
+*              .    alternate convergence criterion when TST1 or TST2
+*              .    is zero (as done here) is traditional but probably
+*              .    unnecessary. ====
+*
+               IF( H( K+1, K ).NE.ZERO ) THEN
+                  TST1 = CABS1( H( K, K ) ) + CABS1( H( K+1, K+1 ) )
+                  IF( TST1.EQ.RZERO ) THEN
+                     IF( K.GE.KTOP+1 )
+     $                  TST1 = TST1 + CABS1( H( K, K-1 ) )
+                     IF( K.GE.KTOP+2 )
+     $                  TST1 = TST1 + CABS1( H( K, K-2 ) )
+                     IF( K.GE.KTOP+3 )
+     $                  TST1 = TST1 + CABS1( H( K, K-3 ) )
+                     IF( K.LE.KBOT-2 )
+     $                  TST1 = TST1 + CABS1( H( K+2, K+1 ) )
+                     IF( K.LE.KBOT-3 )
+     $                  TST1 = TST1 + CABS1( H( K+3, K+1 ) )
+                     IF( K.LE.KBOT-4 )
+     $                  TST1 = TST1 + CABS1( H( K+4, K+1 ) )
+                  END IF
+                  IF( CABS1( H( K+1, K ) ).LE.MAX( SMLNUM, ULP*TST1 ) )
+     $                 THEN
+                     H12 = MAX( CABS1( H( K+1, K ) ),
+     $                     CABS1( H( K, K+1 ) ) )
+                     H21 = MIN( CABS1( H( K+1, K ) ),
+     $                     CABS1( H( K, K+1 ) ) )
+                     H11 = MAX( CABS1( H( K+1, K+1 ) ),
+     $                     CABS1( H( K, K )-H( K+1, K+1 ) ) )
+                     H22 = MIN( CABS1( H( K+1, K+1 ) ),
+     $                     CABS1( H( K, K )-H( K+1, K+1 ) ) )
+                     SCL = H11 + H12
+                     TST2 = H22*( H11 / SCL )
+*
+                     IF( TST2.EQ.RZERO .OR. H21*( H12 / SCL ).LE.
+     $                   MAX( SMLNUM, ULP*TST2 ) )H( K+1, K ) = ZERO
+                  END IF
+               END IF
+  120       CONTINUE
+*
+*           ==== Fill in the last row of each bulge. ====
+*
+            MEND = MIN( NBMPS, ( KBOT-KRCOL-1 ) / 3 )
+            DO 130 M = MTOP, MEND
+               K = KRCOL + 3*( M-1 )
+               REFSUM = V( 1, M )*V( 3, M )*H( K+4, K+3 )
+               H( K+4, K+1 ) = -REFSUM
+               H( K+4, K+2 ) = -REFSUM*CONJG( V( 2, M ) )
+               H( K+4, K+3 ) = H( K+4, K+3 ) - REFSUM*CONJG( V( 3, M ) )
+  130       CONTINUE
+*
+*           ==== End of near-the-diagonal bulge chase. ====
+*
+  140    CONTINUE
+*
+*        ==== Use U (if accumulated) to update far-from-diagonal
+*        .    entries in H.  If required, use U to update Z as
+*        .    well. ====
+*
+         IF( ACCUM ) THEN
+            IF( WANTT ) THEN
+               JTOP = 1
+               JBOT = N
+            ELSE
+               JTOP = KTOP
+               JBOT = KBOT
+            END IF
+            IF( ( .NOT.BLK22 ) .OR. ( INCOL.LT.KTOP ) .OR.
+     $          ( NDCOL.GT.KBOT ) .OR. ( NS.LE.2 ) ) THEN
+*
+*              ==== Updates not exploiting the 2-by-2 block
+*              .    structure of U.  K1 and NU keep track of
+*              .    the location and size of U in the special
+*              .    cases of introducing bulges and chasing
+*              .    bulges off the bottom.  In these special
+*              .    cases and in case the number of shifts
+*              .    is NS = 2, there is no 2-by-2 block
+*              .    structure to exploit.  ====
+*
+               K1 = MAX( 1, KTOP-INCOL )
+               NU = ( KDU-MAX( 0, NDCOL-KBOT ) ) - K1 + 1
+*
+*              ==== Horizontal Multiply ====
+*
+               DO 150 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+                  CALL CGEMM( 'C', 'N', NU, JLEN, NU, ONE, U( K1, K1 ),
+     $                        LDU, H( INCOL+K1, JCOL ), LDH, ZERO, WH,
+     $                        LDWH )
+                  CALL CLACPY( 'ALL', NU, JLEN, WH, LDWH,
+     $                         H( INCOL+K1, JCOL ), LDH )
+  150          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 160 JROW = JTOP, MAX( KTOP, INCOL ) - 1, NV
+                  JLEN = MIN( NV, MAX( KTOP, INCOL )-JROW )
+                  CALL CGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                        H( JROW, INCOL+K1 ), LDH, U( K1, K1 ),
+     $                        LDU, ZERO, WV, LDWV )
+                  CALL CLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                         H( JROW, INCOL+K1 ), LDH )
+  160          CONTINUE
+*
+*              ==== Z multiply (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 170 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+                     CALL CGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                           Z( JROW, INCOL+K1 ), LDZ, U( K1, K1 ),
+     $                           LDU, ZERO, WV, LDWV )
+                     CALL CLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                            Z( JROW, INCOL+K1 ), LDZ )
+  170             CONTINUE
+               END IF
+            ELSE
+*
+*              ==== Updates exploiting U's 2-by-2 block structure.
+*              .    (I2, I4, J2, J4 are the last rows and columns
+*              .    of the blocks.) ====
+*
+               I2 = ( KDU+1 ) / 2
+               I4 = KDU
+               J2 = I4 - I2
+               J4 = KDU
+*
+*              ==== KZS and KNZ deal with the band of zeros
+*              .    along the diagonal of one of the triangular
+*              .    blocks. ====
+*
+               KZS = ( J4-J2 ) - ( NS+1 )
+               KNZ = NS + 1
+*
+*              ==== Horizontal multiply ====
+*
+               DO 180 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+*
+*                 ==== Copy bottom of H to top+KZS of scratch ====
+*                  (The first KZS rows get multiplied by zero.) ====
+*
+                  CALL CLACPY( 'ALL', KNZ, JLEN, H( INCOL+1+J2, JCOL ),
+     $                         LDH, WH( KZS+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL CLASET( 'ALL', KZS, JLEN, ZERO, ZERO, WH, LDWH )
+                  CALL CTRMM( 'L', 'U', 'C', 'N', KNZ, JLEN, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WH( KZS+1, 1 ),
+     $                        LDWH )
+*
+*                 ==== Multiply top of H by U11' ====
+*
+                  CALL CGEMM( 'C', 'N', I2, JLEN, J2, ONE, U, LDU,
+     $                        H( INCOL+1, JCOL ), LDH, ONE, WH, LDWH )
+*
+*                 ==== Copy top of H bottom of WH ====
+*
+                  CALL CLACPY( 'ALL', J2, JLEN, H( INCOL+1, JCOL ), LDH,
+     $                         WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL CTRMM( 'L', 'L', 'C', 'N', J2, JLEN, ONE,
+     $                        U( 1, I2+1 ), LDU, WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL CGEMM( 'C', 'N', I4-I2, JLEN, J4-J2, ONE,
+     $                        U( J2+1, I2+1 ), LDU,
+     $                        H( INCOL+1+J2, JCOL ), LDH, ONE,
+     $                        WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Copy it back ====
+*
+                  CALL CLACPY( 'ALL', KDU, JLEN, WH, LDWH,
+     $                         H( INCOL+1, JCOL ), LDH )
+  180          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 190 JROW = JTOP, MAX( INCOL, KTOP ) - 1, NV
+                  JLEN = MIN( NV, MAX( INCOL, KTOP )-JROW )
+*
+*                 ==== Copy right of H to scratch (the first KZS
+*                 .    columns get multiplied by zero) ====
+*
+                  CALL CLACPY( 'ALL', JLEN, KNZ, H( JROW, INCOL+1+J2 ),
+     $                         LDH, WV( 1, 1+KZS ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL CLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, LDWV )
+                  CALL CTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                        LDWV )
+*
+*                 ==== Multiply by U11 ====
+*
+                  CALL CGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                        H( JROW, INCOL+1 ), LDH, U, LDU, ONE, WV,
+     $                        LDWV )
+*
+*                 ==== Copy left of H to right of scratch ====
+*
+                  CALL CLACPY( 'ALL', JLEN, J2, H( JROW, INCOL+1 ), LDH,
+     $                         WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL CTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                        U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL CGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                        H( JROW, INCOL+1+J2 ), LDH,
+     $                        U( J2+1, I2+1 ), LDU, ONE, WV( 1, 1+I2 ),
+     $                        LDWV )
+*
+*                 ==== Copy it back ====
+*
+                  CALL CLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                         H( JROW, INCOL+1 ), LDH )
+  190          CONTINUE
+*
+*              ==== Multiply Z (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 200 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+*
+*                    ==== Copy right of Z to left of scratch (first
+*                    .     KZS columns get multiplied by zero) ====
+*
+                     CALL CLACPY( 'ALL', JLEN, KNZ,
+     $                            Z( JROW, INCOL+1+J2 ), LDZ,
+     $                            WV( 1, 1+KZS ), LDWV )
+*
+*                    ==== Multiply by U12 ====
+*
+                     CALL CLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV,
+     $                            LDWV )
+                     CALL CTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                           U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U11 ====
+*
+                     CALL CGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                           Z( JROW, INCOL+1 ), LDZ, U, LDU, ONE,
+     $                           WV, LDWV )
+*
+*                    ==== Copy left of Z to right of scratch ====
+*
+                     CALL CLACPY( 'ALL', JLEN, J2, Z( JROW, INCOL+1 ),
+     $                            LDZ, WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Multiply by U21 ====
+*
+                     CALL CTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                           U( 1, I2+1 ), LDU, WV( 1, 1+I2 ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U22 ====
+*
+                     CALL CGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                           Z( JROW, INCOL+1+J2 ), LDZ,
+     $                           U( J2+1, I2+1 ), LDU, ONE,
+     $                           WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Copy the result back to Z ====
+*
+                     CALL CLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                            Z( JROW, INCOL+1 ), LDZ )
+  200             CONTINUE
+               END IF
+            END IF
+         END IF
+  210 CONTINUE
+*
+*     ==== End of CLAQR5 ====
+*
+      END
diff --git a/libcruft/lapack/clarf.f b/libcruft/lapack/clarf.f
new file mode 100644
index 0000000..4db0b0b
--- /dev/null
+++ b/libcruft/lapack/clarf.f
@@ -0,0 +1,120 @@
+      SUBROUTINE CLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, LDC, M, N
+      COMPLEX            TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARF applies a complex elementary reflector H to a complex M-by-N
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a complex scalar and v is a complex vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*  To apply H' (the conjugate transpose of H), supply conjg(tau) instead
+*  tau.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) COMPLEX array, dimension
+*                     (1 + (M-1)*abs(INCV)) if SIDE = 'L'
+*                  or (1 + (N-1)*abs(INCV)) if SIDE = 'R'
+*          The vector v in the representation of H. V is not used if
+*          TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) COMPLEX
+*          The value tau in the representation of H.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CGERC
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C' * v
+*
+            CALL CGEMV( 'Conjugate transpose', M, N, ONE, C, LDC, V,
+     $                  INCV, ZERO, WORK, 1 )
+*
+*           C := C - v * w'
+*
+            CALL CGERC( M, N, -TAU, V, INCV, WORK, 1, C, LDC )
+         END IF
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C * v
+*
+            CALL CGEMV( 'No transpose', M, N, ONE, C, LDC, V, INCV,
+     $                  ZERO, WORK, 1 )
+*
+*           C := C - w * v'
+*
+            CALL CGERC( M, N, -TAU, WORK, 1, V, INCV, C, LDC )
+         END IF
+      END IF
+      RETURN
+*
+*     End of CLARF
+*
+      END
diff --git a/libcruft/lapack/clarfb.f b/libcruft/lapack/clarfb.f
new file mode 100644
index 0000000..3f69e8f
--- /dev/null
+++ b/libcruft/lapack/clarfb.f
@@ -0,0 +1,608 @@
+      SUBROUTINE CLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,
+     $                   T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARFB applies a complex block reflector H or its transpose H' to a
+*  complex M-by-N matrix C, from either the left or the right.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'C': apply H' (Conjugate transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  V       (input) COMPLEX array, dimension
+*                                (LDV,K) if STOREV = 'C'
+*                                (LDV,M) if STOREV = 'R' and SIDE = 'L'
+*                                (LDV,N) if STOREV = 'R' and SIDE = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);
+*          if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);
+*          if STOREV = 'R', LDV >= K.
+*
+*  T       (input) COMPLEX array, dimension (LDT,K)
+*          The triangular K-by-K matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEMM, CLACGV, CTRMM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'C'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( STOREV, 'C' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1 )    (first K rows)
+*                     ( V2 )
+*           where  V1  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C1'
+*
+               DO 10 J = 1, K
+                  CALL CCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL CLACGV( N, WORK( 1, J ), 1 )
+   10          CONTINUE
+*
+*              W := W * V1
+*
+               CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2
+*
+                  CALL CGEMM( 'Conjugate transpose', 'No transpose', N,
+     $                        K, M-K, ONE, C( K+1, 1 ), LDC,
+     $                        V( K+1, 1 ), LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2 * W'
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose',
+     $                        M-K, N, K, -ONE, V( K+1, 1 ), LDV, WORK,
+     $                        LDWORK, ONE, C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 30 J = 1, K
+                  DO 20 I = 1, N
+                     C( J, I ) = C( J, I ) - CONJG( WORK( I, J ) )
+   20             CONTINUE
+   30          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C1
+*
+               DO 40 J = 1, K
+                  CALL CCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40          CONTINUE
+*
+*              W := W * V1
+*
+               CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2
+*
+                  CALL CGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2'
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        N-K, K, -ONE, WORK, LDWORK, V( K+1, 1 ),
+     $                        LDV, ONE, C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 60 J = 1, K
+                  DO 50 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+   50             CONTINUE
+   60          CONTINUE
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1 )
+*                     ( V2 )    (last K rows)
+*           where  V2  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C2'
+*
+               DO 70 J = 1, K
+                  CALL CCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL CLACGV( N, WORK( 1, J ), 1 )
+   70          CONTINUE
+*
+*              W := W * V2
+*
+               CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1
+*
+                  CALL CGEMM( 'Conjugate transpose', 'No transpose', N,
+     $                        K, M-K, ONE, C, LDC, V, LDV, ONE, WORK,
+     $                        LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1 * W'
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose',
+     $                        M-K, N, K, -ONE, V, LDV, WORK, LDWORK,
+     $                        ONE, C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V( M-K+1, 1 ), LDV, WORK,
+     $                     LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 90 J = 1, K
+                  DO 80 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) -
+     $                               CONJG( WORK( I, J ) )
+   80             CONTINUE
+   90          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C2
+*
+               DO 100 J = 1, K
+                  CALL CCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  100          CONTINUE
+*
+*              W := W * V2
+*
+               CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1
+*
+                  CALL CGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1'
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        N-K, K, -ONE, WORK, LDWORK, V, LDV, ONE,
+     $                        C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V( N-K+1, 1 ), LDV, WORK,
+     $                     LDWORK )
+*
+*              C2 := C2 - W
+*
+               DO 120 J = 1, K
+                  DO 110 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  110             CONTINUE
+  120          CONTINUE
+            END IF
+         END IF
+*
+      ELSE IF( LSAME( STOREV, 'R' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1  V2 )    (V1: first K columns)
+*           where  V1  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C1'
+*
+               DO 130 J = 1, K
+                  CALL CCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL CLACGV( N, WORK( 1, J ), 1 )
+  130          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2'
+*
+                  CALL CGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', N, K, M-K, ONE,
+     $                        C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,
+     $                        WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2' * W'
+*
+                  CALL CGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', M-K, N, K, -ONE,
+     $                        V( 1, K+1 ), LDV, WORK, LDWORK, ONE,
+     $                        C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 150 J = 1, K
+                  DO 140 I = 1, N
+                     C( J, I ) = C( J, I ) - CONJG( WORK( I, J ) )
+  140             CONTINUE
+  150          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C1
+*
+               DO 160 J = 1, K
+                  CALL CCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+  160          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2'
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        K, N-K, ONE, C( 1, K+1 ), LDC,
+     $                        V( 1, K+1 ), LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2
+*
+                  CALL CGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE,
+     $                        C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 180 J = 1, K
+                  DO 170 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+  170             CONTINUE
+  180          CONTINUE
+*
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1  V2 )    (V2: last K columns)
+*           where  V2  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C2'
+*
+               DO 190 J = 1, K
+                  CALL CCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL CLACGV( N, WORK( 1, J ), 1 )
+  190          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V( 1, M-K+1 ), LDV, WORK,
+     $                     LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1'
+*
+                  CALL CGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', N, K, M-K, ONE, C,
+     $                        LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1' * W'
+*
+                  CALL CGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', M-K, N, K, -ONE, V,
+     $                        LDV, WORK, LDWORK, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 210 J = 1, K
+                  DO 200 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) -
+     $                               CONJG( WORK( I, J ) )
+  200             CONTINUE
+  210          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C2
+*
+               DO 220 J = 1, K
+                  CALL CCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  220          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V( 1, N-K+1 ), LDV, WORK,
+     $                     LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1'
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        K, N-K, ONE, C, LDC, V, LDV, ONE, WORK,
+     $                        LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1
+*
+                  CALL CGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 240 J = 1, K
+                  DO 230 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  230             CONTINUE
+  240          CONTINUE
+*
+            END IF
+*
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CLARFB
+*
+      END
diff --git a/libcruft/lapack/clarfg.f b/libcruft/lapack/clarfg.f
new file mode 100644
index 0000000..784798c
--- /dev/null
+++ b/libcruft/lapack/clarfg.f
@@ -0,0 +1,145 @@
+      SUBROUTINE CLARFG( N, ALPHA, X, INCX, TAU )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      COMPLEX            ALPHA, TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARFG generates a complex elementary reflector H of order n, such
+*  that
+*
+*        H' * ( alpha ) = ( beta ),   H' * H = I.
+*             (   x   )   (   0  )
+*
+*  where alpha and beta are scalars, with beta real, and x is an
+*  (n-1)-element complex vector. H is represented in the form
+*
+*        H = I - tau * ( 1 ) * ( 1 v' ) ,
+*                      ( v )
+*
+*  where tau is a complex scalar and v is a complex (n-1)-element
+*  vector. Note that H is not hermitian.
+*
+*  If the elements of x are all zero and alpha is real, then tau = 0
+*  and H is taken to be the unit matrix.
+*
+*  Otherwise  1 <= real(tau) <= 2  and  abs(tau-1) <= 1 .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the elementary reflector.
+*
+*  ALPHA   (input/output) COMPLEX
+*          On entry, the value alpha.
+*          On exit, it is overwritten with the value beta.
+*
+*  X       (input/output) COMPLEX array, dimension
+*                         (1+(N-2)*abs(INCX))
+*          On entry, the vector x.
+*          On exit, it is overwritten with the vector v.
+*
+*  INCX    (input) INTEGER
+*          The increment between elements of X. INCX > 0.
+*
+*  TAU     (output) COMPLEX
+*          The value tau.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J, KNT
+      REAL               ALPHI, ALPHR, BETA, RSAFMN, SAFMIN, XNORM
+*     ..
+*     .. External Functions ..
+      REAL               SCNRM2, SLAMCH, SLAPY3
+      COMPLEX            CLADIV
+      EXTERNAL           SCNRM2, SLAMCH, SLAPY3, CLADIV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, REAL, SIGN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSCAL, CSSCAL
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 ) THEN
+         TAU = ZERO
+         RETURN
+      END IF
+*
+      XNORM = SCNRM2( N-1, X, INCX )
+      ALPHR = REAL( ALPHA )
+      ALPHI = AIMAG( ALPHA )
+*
+      IF( XNORM.EQ.ZERO .AND. ALPHI.EQ.ZERO ) THEN
+*
+*        H  =  I
+*
+         TAU = ZERO
+      ELSE
+*
+*        general case
+*
+         BETA = -SIGN( SLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )
+         SAFMIN = SLAMCH( 'S' ) / SLAMCH( 'E' )
+         RSAFMN = ONE / SAFMIN
+*
+         IF( ABS( BETA ).LT.SAFMIN ) THEN
+*
+*           XNORM, BETA may be inaccurate; scale X and recompute them
+*
+            KNT = 0
+   10       CONTINUE
+            KNT = KNT + 1
+            CALL CSSCAL( N-1, RSAFMN, X, INCX )
+            BETA = BETA*RSAFMN
+            ALPHI = ALPHI*RSAFMN
+            ALPHR = ALPHR*RSAFMN
+            IF( ABS( BETA ).LT.SAFMIN )
+     $         GO TO 10
+*
+*           New BETA is at most 1, at least SAFMIN
+*
+            XNORM = SCNRM2( N-1, X, INCX )
+            ALPHA = CMPLX( ALPHR, ALPHI )
+            BETA = -SIGN( SLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )
+            TAU = CMPLX( ( BETA-ALPHR ) / BETA, -ALPHI / BETA )
+            ALPHA = CLADIV( CMPLX( ONE ), ALPHA-BETA )
+            CALL CSCAL( N-1, ALPHA, X, INCX )
+*
+*           If ALPHA is subnormal, it may lose relative accuracy
+*
+            ALPHA = BETA
+            DO 20 J = 1, KNT
+               ALPHA = ALPHA*SAFMIN
+   20       CONTINUE
+         ELSE
+            TAU = CMPLX( ( BETA-ALPHR ) / BETA, -ALPHI / BETA )
+            ALPHA = CLADIV( CMPLX( ONE ), ALPHA-BETA )
+            CALL CSCAL( N-1, ALPHA, X, INCX )
+            ALPHA = BETA
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CLARFG
+*
+      END
diff --git a/libcruft/lapack/clarft.f b/libcruft/lapack/clarft.f
new file mode 100644
index 0000000..25624f7
--- /dev/null
+++ b/libcruft/lapack/clarft.f
@@ -0,0 +1,224 @@
+      SUBROUTINE CLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARFT forms the triangular factor T of a complex block reflector H
+*  of order n, which is defined as a product of k elementary reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) COMPLEX array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) COMPLEX array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*               V = (  1       )                 V = (  1 v1 v1 v1 v1 )
+*                   ( v1  1    )                     (     1 v2 v2 v2 )
+*                   ( v1 v2  1 )                     (        1 v3 v3 )
+*                   ( v1 v2 v3 )
+*                   ( v1 v2 v3 )
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*               V = ( v1 v2 v3 )                 V = ( v1 v1  1       )
+*                   ( v1 v2 v3 )                     ( v2 v2 v2  1    )
+*                   (  1 v2 v3 )                     ( v3 v3 v3 v3  1 )
+*                   (     1 v3 )
+*                   (        1 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      COMPLEX            VII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CLACGV, CTRMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( LSAME( DIRECT, 'F' ) ) THEN
+         DO 20 I = 1, K
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 10 J = 1, I
+                  T( J, I ) = ZERO
+   10          CONTINUE
+            ELSE
+*
+*              general case
+*
+               VII = V( I, I )
+               V( I, I ) = ONE
+               IF( LSAME( STOREV, 'C' ) ) THEN
+*
+*                 T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i)
+*
+                  CALL CGEMV( 'Conjugate transpose', N-I+1, I-1,
+     $                        -TAU( I ), V( I, 1 ), LDV, V( I, I ), 1,
+     $                        ZERO, T( 1, I ), 1 )
+               ELSE
+*
+*                 T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)'
+*
+                  IF( I.LT.N )
+     $               CALL CLACGV( N-I, V( I, I+1 ), LDV )
+                  CALL CGEMV( 'No transpose', I-1, N-I+1, -TAU( I ),
+     $                        V( 1, I ), LDV, V( I, I ), LDV, ZERO,
+     $                        T( 1, I ), 1 )
+                  IF( I.LT.N )
+     $               CALL CLACGV( N-I, V( I, I+1 ), LDV )
+               END IF
+               V( I, I ) = VII
+*
+*              T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)
+*
+               CALL CTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,
+     $                     LDT, T( 1, I ), 1 )
+               T( I, I ) = TAU( I )
+            END IF
+   20    CONTINUE
+      ELSE
+         DO 40 I = K, 1, -1
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 30 J = I, K
+                  T( J, I ) = ZERO
+   30          CONTINUE
+            ELSE
+*
+*              general case
+*
+               IF( I.LT.K ) THEN
+                  IF( LSAME( STOREV, 'C' ) ) THEN
+                     VII = V( N-K+I, I )
+                     V( N-K+I, I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i)
+*
+                     CALL CGEMV( 'Conjugate transpose', N-K+I, K-I,
+     $                           -TAU( I ), V( 1, I+1 ), LDV, V( 1, I ),
+     $                           1, ZERO, T( I+1, I ), 1 )
+                     V( N-K+I, I ) = VII
+                  ELSE
+                     VII = V( I, N-K+I )
+                     V( I, N-K+I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)'
+*
+                     CALL CLACGV( N-K+I-1, V( I, 1 ), LDV )
+                     CALL CGEMV( 'No transpose', K-I, N-K+I, -TAU( I ),
+     $                           V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                           T( I+1, I ), 1 )
+                     CALL CLACGV( N-K+I-1, V( I, 1 ), LDV )
+                     V( I, N-K+I ) = VII
+                  END IF
+*
+*                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+                  CALL CTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                        T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+               END IF
+               T( I, I ) = TAU( I )
+            END IF
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CLARFT
+*
+      END
diff --git a/libcruft/lapack/clarfx.f b/libcruft/lapack/clarfx.f
new file mode 100644
index 0000000..8314836
--- /dev/null
+++ b/libcruft/lapack/clarfx.f
@@ -0,0 +1,640 @@
+      SUBROUTINE CLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            LDC, M, N
+      COMPLEX            TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARFX applies a complex elementary reflector H to a complex m by n
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a complex scalar and v is a complex vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix
+*
+*  This version uses inline code if H has order < 11.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) COMPLEX array, dimension (M) if SIDE = 'L'
+*                                        or (N) if SIDE = 'R'
+*          The vector v in the representation of H.
+*
+*  TAU     (input) COMPLEX
+*          The value tau in the representation of H.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDA >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension (N) if SIDE = 'L'
+*                                            or (M) if SIDE = 'R'
+*          WORK is not referenced if H has order < 11.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J
+      COMPLEX            SUM, T1, T10, T2, T3, T4, T5, T6, T7, T8, T9,
+     $                   V1, V10, V2, V3, V4, V5, V6, V7, V8, V9
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CGERC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( TAU.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C, where H has order m.
+*
+         GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,
+     $           170, 190 )M
+*
+*        Code for general M
+*
+*        w := C'*v
+*
+         CALL CGEMV( 'Conjugate transpose', M, N, ONE, C, LDC, V, 1,
+     $               ZERO, WORK, 1 )
+*
+*        C := C - tau * v * w'
+*
+         CALL CGERC( M, N, -TAU, V, 1, WORK, 1, C, LDC )
+         GO TO 410
+   10    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*CONJG( V( 1 ) )
+         DO 20 J = 1, N
+            C( 1, J ) = T1*C( 1, J )
+   20    CONTINUE
+         GO TO 410
+   30    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         DO 40 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+   40    CONTINUE
+         GO TO 410
+   50    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         DO 60 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+   60    CONTINUE
+         GO TO 410
+   70    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         DO 80 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+   80    CONTINUE
+         GO TO 410
+   90    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         V5 = CONJG( V( 5 ) )
+         T5 = TAU*CONJG( V5 )
+         DO 100 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+  100    CONTINUE
+         GO TO 410
+  110    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         V5 = CONJG( V( 5 ) )
+         T5 = TAU*CONJG( V5 )
+         V6 = CONJG( V( 6 ) )
+         T6 = TAU*CONJG( V6 )
+         DO 120 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+  120    CONTINUE
+         GO TO 410
+  130    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         V5 = CONJG( V( 5 ) )
+         T5 = TAU*CONJG( V5 )
+         V6 = CONJG( V( 6 ) )
+         T6 = TAU*CONJG( V6 )
+         V7 = CONJG( V( 7 ) )
+         T7 = TAU*CONJG( V7 )
+         DO 140 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+  140    CONTINUE
+         GO TO 410
+  150    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         V5 = CONJG( V( 5 ) )
+         T5 = TAU*CONJG( V5 )
+         V6 = CONJG( V( 6 ) )
+         T6 = TAU*CONJG( V6 )
+         V7 = CONJG( V( 7 ) )
+         T7 = TAU*CONJG( V7 )
+         V8 = CONJG( V( 8 ) )
+         T8 = TAU*CONJG( V8 )
+         DO 160 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+  160    CONTINUE
+         GO TO 410
+  170    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         V5 = CONJG( V( 5 ) )
+         T5 = TAU*CONJG( V5 )
+         V6 = CONJG( V( 6 ) )
+         T6 = TAU*CONJG( V6 )
+         V7 = CONJG( V( 7 ) )
+         T7 = TAU*CONJG( V7 )
+         V8 = CONJG( V( 8 ) )
+         T8 = TAU*CONJG( V8 )
+         V9 = CONJG( V( 9 ) )
+         T9 = TAU*CONJG( V9 )
+         DO 180 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+  180    CONTINUE
+         GO TO 410
+  190    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = CONJG( V( 1 ) )
+         T1 = TAU*CONJG( V1 )
+         V2 = CONJG( V( 2 ) )
+         T2 = TAU*CONJG( V2 )
+         V3 = CONJG( V( 3 ) )
+         T3 = TAU*CONJG( V3 )
+         V4 = CONJG( V( 4 ) )
+         T4 = TAU*CONJG( V4 )
+         V5 = CONJG( V( 5 ) )
+         T5 = TAU*CONJG( V5 )
+         V6 = CONJG( V( 6 ) )
+         T6 = TAU*CONJG( V6 )
+         V7 = CONJG( V( 7 ) )
+         T7 = TAU*CONJG( V7 )
+         V8 = CONJG( V( 8 ) )
+         T8 = TAU*CONJG( V8 )
+         V9 = CONJG( V( 9 ) )
+         T9 = TAU*CONJG( V9 )
+         V10 = CONJG( V( 10 ) )
+         T10 = TAU*CONJG( V10 )
+         DO 200 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J ) +
+     $            V10*C( 10, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+            C( 10, J ) = C( 10, J ) - SUM*T10
+  200    CONTINUE
+         GO TO 410
+      ELSE
+*
+*        Form  C * H, where H has order n.
+*
+         GO TO ( 210, 230, 250, 270, 290, 310, 330, 350,
+     $           370, 390 )N
+*
+*        Code for general N
+*
+*        w := C * v
+*
+         CALL CGEMV( 'No transpose', M, N, ONE, C, LDC, V, 1, ZERO,
+     $               WORK, 1 )
+*
+*        C := C - tau * w * v'
+*
+         CALL CGERC( M, N, -TAU, WORK, 1, V, 1, C, LDC )
+         GO TO 410
+  210    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*CONJG( V( 1 ) )
+         DO 220 J = 1, M
+            C( J, 1 ) = T1*C( J, 1 )
+  220    CONTINUE
+         GO TO 410
+  230    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         DO 240 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+  240    CONTINUE
+         GO TO 410
+  250    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         DO 260 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+  260    CONTINUE
+         GO TO 410
+  270    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         DO 280 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+  280    CONTINUE
+         GO TO 410
+  290    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*CONJG( V5 )
+         DO 300 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+  300    CONTINUE
+         GO TO 410
+  310    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*CONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*CONJG( V6 )
+         DO 320 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+  320    CONTINUE
+         GO TO 410
+  330    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*CONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*CONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*CONJG( V7 )
+         DO 340 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+  340    CONTINUE
+         GO TO 410
+  350    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*CONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*CONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*CONJG( V7 )
+         V8 = V( 8 )
+         T8 = TAU*CONJG( V8 )
+         DO 360 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+  360    CONTINUE
+         GO TO 410
+  370    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*CONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*CONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*CONJG( V7 )
+         V8 = V( 8 )
+         T8 = TAU*CONJG( V8 )
+         V9 = V( 9 )
+         T9 = TAU*CONJG( V9 )
+         DO 380 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+  380    CONTINUE
+         GO TO 410
+  390    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*CONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*CONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*CONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*CONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*CONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*CONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*CONJG( V7 )
+         V8 = V( 8 )
+         T8 = TAU*CONJG( V8 )
+         V9 = V( 9 )
+         T9 = TAU*CONJG( V9 )
+         V10 = V( 10 )
+         T10 = TAU*CONJG( V10 )
+         DO 400 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 ) +
+     $            V10*C( J, 10 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+            C( J, 10 ) = C( J, 10 ) - SUM*T10
+  400    CONTINUE
+         GO TO 410
+      END IF
+  410 RETURN
+*
+*     End of CLARFX
+*
+      END
diff --git a/libcruft/lapack/clartg.f b/libcruft/lapack/clartg.f
new file mode 100644
index 0000000..c521d33
--- /dev/null
+++ b/libcruft/lapack/clartg.f
@@ -0,0 +1,195 @@
+      SUBROUTINE CLARTG( F, G, CS, SN, R )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               CS
+      COMPLEX            F, G, R, SN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARTG generates a plane rotation so that
+*
+*     [  CS  SN  ]     [ F ]     [ R ]
+*     [  __      ]  .  [   ]  =  [   ]   where CS**2 + |SN|**2 = 1.
+*     [ -SN  CS  ]     [ G ]     [ 0 ]
+*
+*  This is a faster version of the BLAS1 routine CROTG, except for
+*  the following differences:
+*     F and G are unchanged on return.
+*     If G=0, then CS=1 and SN=0.
+*     If F=0, then CS=0 and SN is chosen so that R is real.
+*
+*  Arguments
+*  =========
+*
+*  F       (input) COMPLEX
+*          The first component of vector to be rotated.
+*
+*  G       (input) COMPLEX
+*          The second component of vector to be rotated.
+*
+*  CS      (output) REAL
+*          The cosine of the rotation.
+*
+*  SN      (output) COMPLEX
+*          The sine of the rotation.
+*
+*  R       (output) COMPLEX
+*          The nonzero component of the rotated vector.
+*
+*  Further Details
+*  ======= =======
+*
+*  3-5-96 - Modified with a new algorithm by W. Kahan and J. Demmel
+*
+*  This version has a few statements commented out for thread safety
+*  (machine parameters are computed on each entry). 10 feb 03, SJH.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               TWO, ONE, ZERO
+      PARAMETER          ( TWO = 2.0E+0, ONE = 1.0E+0, ZERO = 0.0E+0 )
+      COMPLEX            CZERO
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+*     LOGICAL            FIRST
+      INTEGER            COUNT, I
+      REAL               D, DI, DR, EPS, F2, F2S, G2, G2S, SAFMIN,
+     $                   SAFMN2, SAFMX2, SCALE
+      COMPLEX            FF, FS, GS
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLAPY2
+      EXTERNAL           SLAMCH, SLAPY2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, INT, LOG, MAX, REAL,
+     $                   SQRT
+*     ..
+*     .. Statement Functions ..
+      REAL               ABS1, ABSSQ
+*     ..
+*     .. Save statement ..
+*     SAVE               FIRST, SAFMX2, SAFMIN, SAFMN2
+*     ..
+*     .. Data statements ..
+*     DATA               FIRST / .TRUE. /
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( FF ) = MAX( ABS( REAL( FF ) ), ABS( AIMAG( FF ) ) )
+      ABSSQ( FF ) = REAL( FF )**2 + AIMAG( FF )**2
+*     ..
+*     .. Executable Statements ..
+*
+*     IF( FIRST ) THEN
+         SAFMIN = SLAMCH( 'S' )
+         EPS = SLAMCH( 'E' )
+         SAFMN2 = SLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
+     $            LOG( SLAMCH( 'B' ) ) / TWO )
+         SAFMX2 = ONE / SAFMN2
+*        FIRST = .FALSE.
+*     END IF
+      SCALE = MAX( ABS1( F ), ABS1( G ) )
+      FS = F
+      GS = G
+      COUNT = 0
+      IF( SCALE.GE.SAFMX2 ) THEN
+   10    CONTINUE
+         COUNT = COUNT + 1
+         FS = FS*SAFMN2
+         GS = GS*SAFMN2
+         SCALE = SCALE*SAFMN2
+         IF( SCALE.GE.SAFMX2 )
+     $      GO TO 10
+      ELSE IF( SCALE.LE.SAFMN2 ) THEN
+         IF( G.EQ.CZERO ) THEN
+            CS = ONE
+            SN = CZERO
+            R = F
+            RETURN
+         END IF
+   20    CONTINUE
+         COUNT = COUNT - 1
+         FS = FS*SAFMX2
+         GS = GS*SAFMX2
+         SCALE = SCALE*SAFMX2
+         IF( SCALE.LE.SAFMN2 )
+     $      GO TO 20
+      END IF
+      F2 = ABSSQ( FS )
+      G2 = ABSSQ( GS )
+      IF( F2.LE.MAX( G2, ONE )*SAFMIN ) THEN
+*
+*        This is a rare case: F is very small.
+*
+         IF( F.EQ.CZERO ) THEN
+            CS = ZERO
+            R = SLAPY2( REAL( G ), AIMAG( G ) )
+*           Do complex/real division explicitly with two real divisions
+            D = SLAPY2( REAL( GS ), AIMAG( GS ) )
+            SN = CMPLX( REAL( GS ) / D, -AIMAG( GS ) / D )
+            RETURN
+         END IF
+         F2S = SLAPY2( REAL( FS ), AIMAG( FS ) )
+*        G2 and G2S are accurate
+*        G2 is at least SAFMIN, and G2S is at least SAFMN2
+         G2S = SQRT( G2 )
+*        Error in CS from underflow in F2S is at most
+*        UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS
+*        If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN,
+*        and so CS .lt. sqrt(SAFMIN)
+*        If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN
+*        and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS)
+*        Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S
+         CS = F2S / G2S
+*        Make sure abs(FF) = 1
+*        Do complex/real division explicitly with 2 real divisions
+         IF( ABS1( F ).GT.ONE ) THEN
+            D = SLAPY2( REAL( F ), AIMAG( F ) )
+            FF = CMPLX( REAL( F ) / D, AIMAG( F ) / D )
+         ELSE
+            DR = SAFMX2*REAL( F )
+            DI = SAFMX2*AIMAG( F )
+            D = SLAPY2( DR, DI )
+            FF = CMPLX( DR / D, DI / D )
+         END IF
+         SN = FF*CMPLX( REAL( GS ) / G2S, -AIMAG( GS ) / G2S )
+         R = CS*F + SN*G
+      ELSE
+*
+*        This is the most common case.
+*        Neither F2 nor F2/G2 are less than SAFMIN
+*        F2S cannot overflow, and it is accurate
+*
+         F2S = SQRT( ONE+G2 / F2 )
+*        Do the F2S(real)*FS(complex) multiply with two real multiplies
+         R = CMPLX( F2S*REAL( FS ), F2S*AIMAG( FS ) )
+         CS = ONE / F2S
+         D = F2 + G2
+*        Do complex/real division explicitly with two real divisions
+         SN = CMPLX( REAL( R ) / D, AIMAG( R ) / D )
+         SN = SN*CONJG( GS )
+         IF( COUNT.NE.0 ) THEN
+            IF( COUNT.GT.0 ) THEN
+               DO 30 I = 1, COUNT
+                  R = R*SAFMX2
+   30          CONTINUE
+            ELSE
+               DO 40 I = 1, -COUNT
+                  R = R*SAFMN2
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of CLARTG
+*
+      END
diff --git a/libcruft/lapack/clarz.f b/libcruft/lapack/clarz.f
new file mode 100644
index 0000000..9bf7efb
--- /dev/null
+++ b/libcruft/lapack/clarz.f
@@ -0,0 +1,157 @@
+      SUBROUTINE CLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, L, LDC, M, N
+      COMPLEX            TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARZ applies a complex elementary reflector H to a complex
+*  M-by-N matrix C, from either the left or the right. H is represented
+*  in the form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a complex scalar and v is a complex vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*  To apply H' (the conjugate transpose of H), supply conjg(tau) instead
+*  tau.
+*
+*  H is a product of k elementary reflectors as returned by CTZRZF.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  L       (input) INTEGER
+*          The number of entries of the vector V containing
+*          the meaningful part of the Householder vectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) COMPLEX array, dimension (1+(L-1)*abs(INCV))
+*          The vector v in the representation of H as returned by
+*          CTZRZF. V is not used if TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) COMPLEX
+*          The value tau in the representation of H.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CCOPY, CGEMV, CGERC, CGERU, CLACGV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:n ) = conjg( C( 1, 1:n ) )
+*
+            CALL CCOPY( N, C, LDC, WORK, 1 )
+            CALL CLACGV( N, WORK, 1 )
+*
+*           w( 1:n ) = conjg( w( 1:n ) + C( m-l+1:m, 1:n )' * v( 1:l ) )
+*
+            CALL CGEMV( 'Conjugate transpose', L, N, ONE, C( M-L+1, 1 ),
+     $                  LDC, V, INCV, ONE, WORK, 1 )
+            CALL CLACGV( N, WORK, 1 )
+*
+*           C( 1, 1:n ) = C( 1, 1:n ) - tau * w( 1:n )
+*
+            CALL CAXPY( N, -TAU, WORK, 1, C, LDC )
+*
+*           C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                               tau * v( 1:l ) * conjg( w( 1:n )' )
+*
+            CALL CGERU( L, N, -TAU, V, INCV, WORK, 1, C( M-L+1, 1 ),
+     $                  LDC )
+         END IF
+*
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:m ) = C( 1:m, 1 )
+*
+            CALL CCOPY( M, C, 1, WORK, 1 )
+*
+*           w( 1:m ) = w( 1:m ) + C( 1:m, n-l+1:n, 1:n ) * v( 1:l )
+*
+            CALL CGEMV( 'No transpose', M, L, ONE, C( 1, N-L+1 ), LDC,
+     $                  V, INCV, ONE, WORK, 1 )
+*
+*           C( 1:m, 1 ) = C( 1:m, 1 ) - tau * w( 1:m )
+*
+            CALL CAXPY( M, -TAU, WORK, 1, C, 1 )
+*
+*           C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                               tau * w( 1:m ) * v( 1:l )'
+*
+            CALL CGERC( M, L, -TAU, WORK, 1, V, INCV, C( 1, N-L+1 ),
+     $                  LDC )
+*
+         END IF
+*
+      END IF
+*
+      RETURN
+*
+*     End of CLARZ
+*
+      END
diff --git a/libcruft/lapack/clarzb.f b/libcruft/lapack/clarzb.f
new file mode 100644
index 0000000..77e24ba
--- /dev/null
+++ b/libcruft/lapack/clarzb.f
@@ -0,0 +1,234 @@
+      SUBROUTINE CLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,
+     $                   LDV, T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, L, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARZB applies a complex block reflector H or its transpose H**H
+*  to a complex distributed M-by-N  C from the left or the right.
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'C': apply H' (Conjugate transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise                        (not supported yet)
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix V containing the
+*          meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) COMPLEX array, dimension (LDV,NV).
+*          If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.
+*
+*  T       (input) COMPLEX array, dimension (LDT,K)
+*          The triangular K-by-K matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEMM, CLACGV, CTRMM, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLARZB', -INFO )
+         RETURN
+      END IF
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'C'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C  or  H' * C
+*
+*        W( 1:n, 1:k ) = conjg( C( 1:k, 1:n )' )
+*
+         DO 10 J = 1, K
+            CALL CCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+   10    CONTINUE
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) + ...
+*                        conjg( C( m-l+1:m, 1:n )' ) * V( 1:k, 1:l )'
+*
+         IF( L.GT.0 )
+     $      CALL CGEMM( 'Transpose', 'Conjugate transpose', N, K, L,
+     $                  ONE, C( M-L+1, 1 ), LDC, V, LDV, ONE, WORK,
+     $                  LDWORK )
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) * T'  or  W( 1:m, 1:k ) * T
+*
+         CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+*
+*        C( 1:k, 1:n ) = C( 1:k, 1:n ) - conjg( W( 1:n, 1:k )' )
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, K
+               C( I, J ) = C( I, J ) - WORK( J, I )
+   20       CONTINUE
+   30    CONTINUE
+*
+*        C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                    conjg( V( 1:k, 1:l )' ) * conjg( W( 1:n, 1:k )' )
+*
+         IF( L.GT.0 )
+     $      CALL CGEMM( 'Transpose', 'Transpose', L, N, K, -ONE, V, LDV,
+     $                  WORK, LDWORK, ONE, C( M-L+1, 1 ), LDC )
+*
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form  C * H  or  C * H'
+*
+*        W( 1:m, 1:k ) = C( 1:m, 1:k )
+*
+         DO 40 J = 1, K
+            CALL CCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40    CONTINUE
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) + ...
+*                        C( 1:m, n-l+1:n ) * conjg( V( 1:k, 1:l )' )
+*
+         IF( L.GT.0 )
+     $      CALL CGEMM( 'No transpose', 'Transpose', M, K, L, ONE,
+     $                  C( 1, N-L+1 ), LDC, V, LDV, ONE, WORK, LDWORK )
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) * conjg( T )  or
+*                        W( 1:m, 1:k ) * conjg( T' )
+*
+         DO 50 J = 1, K
+            CALL CLACGV( K-J+1, T( J, J ), 1 )
+   50    CONTINUE
+         CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+         DO 60 J = 1, K
+            CALL CLACGV( K-J+1, T( J, J ), 1 )
+   60    CONTINUE
+*
+*        C( 1:m, 1:k ) = C( 1:m, 1:k ) - W( 1:m, 1:k )
+*
+         DO 80 J = 1, K
+            DO 70 I = 1, M
+               C( I, J ) = C( I, J ) - WORK( I, J )
+   70       CONTINUE
+   80    CONTINUE
+*
+*        C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                            W( 1:m, 1:k ) * conjg( V( 1:k, 1:l ) )
+*
+         DO 90 J = 1, L
+            CALL CLACGV( K, V( 1, J ), 1 )
+   90    CONTINUE
+         IF( L.GT.0 )
+     $      CALL CGEMM( 'No transpose', 'No transpose', M, L, K, -ONE,
+     $                  WORK, LDWORK, V, LDV, ONE, C( 1, N-L+1 ), LDC )
+         DO 100 J = 1, L
+            CALL CLACGV( K, V( 1, J ), 1 )
+  100    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of CLARZB
+*
+      END
diff --git a/libcruft/lapack/clarzt.f b/libcruft/lapack/clarzt.f
new file mode 100644
index 0000000..59260ca
--- /dev/null
+++ b/libcruft/lapack/clarzt.f
@@ -0,0 +1,186 @@
+      SUBROUTINE CLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLARZT forms the triangular factor T of a complex block reflector
+*  H of order > n, which is defined as a product of k elementary
+*  reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise                        (not supported yet)
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) COMPLEX array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) COMPLEX array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*                                              ______V_____
+*         ( v1 v2 v3 )                        /            \
+*         ( v1 v2 v3 )                      ( v1 v1 v1 v1 v1 . . . . 1 )
+*     V = ( v1 v2 v3 )                      ( v2 v2 v2 v2 v2 . . . 1   )
+*         ( v1 v2 v3 )                      ( v3 v3 v3 v3 v3 . . 1     )
+*         ( v1 v2 v3 )
+*            .  .  .
+*            .  .  .
+*            1  .  .
+*               1  .
+*                  1
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*                                                        ______V_____
+*            1                                          /            \
+*            .  1                           ( 1 . . . . v1 v1 v1 v1 v1 )
+*            .  .  1                        ( . 1 . . . v2 v2 v2 v2 v2 )
+*            .  .  .                        ( . . 1 . . v3 v3 v3 v3 v3 )
+*            .  .  .
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*     V = ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CLACGV, CTRMV, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -2
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLARZT', -INFO )
+         RETURN
+      END IF
+*
+      DO 20 I = K, 1, -1
+         IF( TAU( I ).EQ.ZERO ) THEN
+*
+*           H(i)  =  I
+*
+            DO 10 J = I, K
+               T( J, I ) = ZERO
+   10       CONTINUE
+         ELSE
+*
+*           general case
+*
+            IF( I.LT.K ) THEN
+*
+*              T(i+1:k,i) = - tau(i) * V(i+1:k,1:n) * V(i,1:n)'
+*
+               CALL CLACGV( N, V( I, 1 ), LDV )
+               CALL CGEMV( 'No transpose', K-I, N, -TAU( I ),
+     $                     V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                     T( I+1, I ), 1 )
+               CALL CLACGV( N, V( I, 1 ), LDV )
+*
+*              T(i+1:k,i) = T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+               CALL CTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                     T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+            END IF
+            T( I, I ) = TAU( I )
+         END IF
+   20 CONTINUE
+      RETURN
+*
+*     End of CLARZT
+*
+      END
diff --git a/libcruft/lapack/clascl.f b/libcruft/lapack/clascl.f
new file mode 100644
index 0000000..492e595
--- /dev/null
+++ b/libcruft/lapack/clascl.f
@@ -0,0 +1,267 @@
+      SUBROUTINE CLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TYPE
+      INTEGER            INFO, KL, KU, LDA, M, N
+      REAL               CFROM, CTO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLASCL multiplies the M by N complex matrix A by the real scalar
+*  CTO/CFROM.  This is done without over/underflow as long as the final
+*  result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
+*  A may be full, upper triangular, lower triangular, upper Hessenberg,
+*  or banded.
+*
+*  Arguments
+*  =========
+*
+*  TYPE    (input) CHARACTER*1
+*          TYPE indices the storage type of the input matrix.
+*          = 'G':  A is a full matrix.
+*          = 'L':  A is a lower triangular matrix.
+*          = 'U':  A is an upper triangular matrix.
+*          = 'H':  A is an upper Hessenberg matrix.
+*          = 'B':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the lower
+*                  half stored.
+*          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the upper
+*                  half stored.
+*          = 'Z':  A is a band matrix with lower bandwidth KL and upper
+*                  bandwidth KU.
+*
+*  KL      (input) INTEGER
+*          The lower bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  KU      (input) INTEGER
+*          The upper bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  CFROM   (input) REAL
+*  CTO     (input) REAL
+*          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
+*          without over/underflow if the final result CTO*A(I,J)/CFROM
+*          can be represented without over/underflow.  CFROM must be
+*          nonzero.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
+*          storage type.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  INFO    (output) INTEGER
+*          0  - successful exit
+*          <0 - if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      INTEGER            I, ITYPE, J, K1, K2, K3, K4
+      REAL               BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH
+      EXTERNAL           LSAME, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+*
+      IF( LSAME( TYPE, 'G' ) ) THEN
+         ITYPE = 0
+      ELSE IF( LSAME( TYPE, 'L' ) ) THEN
+         ITYPE = 1
+      ELSE IF( LSAME( TYPE, 'U' ) ) THEN
+         ITYPE = 2
+      ELSE IF( LSAME( TYPE, 'H' ) ) THEN
+         ITYPE = 3
+      ELSE IF( LSAME( TYPE, 'B' ) ) THEN
+         ITYPE = 4
+      ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
+         ITYPE = 5
+      ELSE IF( LSAME( TYPE, 'Z' ) ) THEN
+         ITYPE = 6
+      ELSE
+         ITYPE = -1
+      END IF
+*
+      IF( ITYPE.EQ.-1 ) THEN
+         INFO = -1
+      ELSE IF( CFROM.EQ.ZERO ) THEN
+         INFO = -4
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.
+     $         ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN
+         INFO = -7
+      ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -9
+      ELSE IF( ITYPE.GE.4 ) THEN
+         IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN
+            INFO = -2
+         ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.
+     $            ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )
+     $             THEN
+            INFO = -3
+         ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.
+     $            ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.
+     $            ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN
+            INFO = -9
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLASCL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. M.EQ.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+*
+      CFROMC = CFROM
+      CTOC = CTO
+*
+   10 CONTINUE
+      CFROM1 = CFROMC*SMLNUM
+      CTO1 = CTOC / BIGNUM
+      IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CFROMC = CFROM1
+      ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CTOC = CTO1
+      ELSE
+         MUL = CTOC / CFROMC
+         DONE = .TRUE.
+      END IF
+*
+      IF( ITYPE.EQ.0 ) THEN
+*
+*        Full matrix
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, M
+               A( I, J ) = A( I, J )*MUL
+   20       CONTINUE
+   30    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.1 ) THEN
+*
+*        Lower triangular matrix
+*
+         DO 50 J = 1, N
+            DO 40 I = J, M
+               A( I, J ) = A( I, J )*MUL
+   40       CONTINUE
+   50    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.2 ) THEN
+*
+*        Upper triangular matrix
+*
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( J, M )
+               A( I, J ) = A( I, J )*MUL
+   60       CONTINUE
+   70    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*        Upper Hessenberg matrix
+*
+         DO 90 J = 1, N
+            DO 80 I = 1, MIN( J+1, M )
+               A( I, J ) = A( I, J )*MUL
+   80       CONTINUE
+   90    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.4 ) THEN
+*
+*        Lower half of a symmetric band matrix
+*
+         K3 = KL + 1
+         K4 = N + 1
+         DO 110 J = 1, N
+            DO 100 I = 1, MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  100       CONTINUE
+  110    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.5 ) THEN
+*
+*        Upper half of a symmetric band matrix
+*
+         K1 = KU + 2
+         K3 = KU + 1
+         DO 130 J = 1, N
+            DO 120 I = MAX( K1-J, 1 ), K3
+               A( I, J ) = A( I, J )*MUL
+  120       CONTINUE
+  130    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.6 ) THEN
+*
+*        Band matrix
+*
+         K1 = KL + KU + 2
+         K2 = KL + 1
+         K3 = 2*KL + KU + 1
+         K4 = KL + KU + 1 + M
+         DO 150 J = 1, N
+            DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  140       CONTINUE
+  150    CONTINUE
+*
+      END IF
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of CLASCL
+*
+      END
diff --git a/libcruft/lapack/claset.f b/libcruft/lapack/claset.f
new file mode 100644
index 0000000..c47b7d7
--- /dev/null
+++ b/libcruft/lapack/claset.f
@@ -0,0 +1,114 @@
+      SUBROUTINE CLASET( UPLO, M, N, ALPHA, BETA, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, M, N
+      COMPLEX            ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLASET initializes a 2-D array A to BETA on the diagonal and
+*  ALPHA on the offdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be set.
+*          = 'U':      Upper triangular part is set. The lower triangle
+*                      is unchanged.
+*          = 'L':      Lower triangular part is set. The upper triangle
+*                      is unchanged.
+*          Otherwise:  All of the matrix A is set.
+*
+*  M       (input) INTEGER
+*          On entry, M specifies the number of rows of A.
+*
+*  N       (input) INTEGER
+*          On entry, N specifies the number of columns of A.
+*
+*  ALPHA   (input) COMPLEX
+*          All the offdiagonal array elements are set to ALPHA.
+*
+*  BETA    (input) COMPLEX
+*          All the diagonal array elements are set to BETA.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, A(i,j) = ALPHA, 1 <= i <= m, 1 <= j <= n, i.ne.j;
+*                   A(i,i) = BETA , 1 <= i <= min(m,n)
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Set the diagonal to BETA and the strictly upper triangular
+*        part of the array to ALPHA.
+*
+         DO 20 J = 2, N
+            DO 10 I = 1, MIN( J-1, M )
+               A( I, J ) = ALPHA
+   10       CONTINUE
+   20    CONTINUE
+         DO 30 I = 1, MIN( N, M )
+            A( I, I ) = BETA
+   30    CONTINUE
+*
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+*
+*        Set the diagonal to BETA and the strictly lower triangular
+*        part of the array to ALPHA.
+*
+         DO 50 J = 1, MIN( M, N )
+            DO 40 I = J + 1, M
+               A( I, J ) = ALPHA
+   40       CONTINUE
+   50    CONTINUE
+         DO 60 I = 1, MIN( N, M )
+            A( I, I ) = BETA
+   60    CONTINUE
+*
+      ELSE
+*
+*        Set the array to BETA on the diagonal and ALPHA on the
+*        offdiagonal.
+*
+         DO 80 J = 1, N
+            DO 70 I = 1, M
+               A( I, J ) = ALPHA
+   70       CONTINUE
+   80    CONTINUE
+         DO 90 I = 1, MIN( M, N )
+            A( I, I ) = BETA
+   90    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLASET
+*
+      END
diff --git a/libcruft/lapack/clasr.f b/libcruft/lapack/clasr.f
new file mode 100644
index 0000000..74e412c
--- /dev/null
+++ b/libcruft/lapack/clasr.f
@@ -0,0 +1,363 @@
+      SUBROUTINE CLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, PIVOT, SIDE
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               C( * ), S( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLASR applies a sequence of real plane rotations to a complex matrix
+*  A, from either the left or the right.
+*
+*  When SIDE = 'L', the transformation takes the form
+*
+*     A := P*A
+*
+*  and when SIDE = 'R', the transformation takes the form
+*
+*     A := A*P**T
+*
+*  where P is an orthogonal matrix consisting of a sequence of z plane
+*  rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',
+*  and P**T is the transpose of P.
+*  
+*  When DIRECT = 'F' (Forward sequence), then
+*  
+*     P = P(z-1) * ... * P(2) * P(1)
+*  
+*  and when DIRECT = 'B' (Backward sequence), then
+*  
+*     P = P(1) * P(2) * ... * P(z-1)
+*  
+*  where P(k) is a plane rotation matrix defined by the 2-by-2 rotation
+*  
+*     R(k) = (  c(k)  s(k) )
+*          = ( -s(k)  c(k) ).
+*  
+*  When PIVOT = 'V' (Variable pivot), the rotation is performed
+*  for the plane (k,k+1), i.e., P(k) has the form
+*  
+*     P(k) = (  1                                            )
+*            (       ...                                     )
+*            (              1                                )
+*            (                   c(k)  s(k)                  )
+*            (                  -s(k)  c(k)                  )
+*            (                                1              )
+*            (                                     ...       )
+*            (                                            1  )
+*  
+*  where R(k) appears as a rank-2 modification to the identity matrix in
+*  rows and columns k and k+1.
+*  
+*  When PIVOT = 'T' (Top pivot), the rotation is performed for the
+*  plane (1,k+1), so P(k) has the form
+*  
+*     P(k) = (  c(k)                    s(k)                 )
+*            (         1                                     )
+*            (              ...                              )
+*            (                     1                         )
+*            ( -s(k)                    c(k)                 )
+*            (                                 1             )
+*            (                                      ...      )
+*            (                                             1 )
+*  
+*  where R(k) appears in rows and columns 1 and k+1.
+*  
+*  Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is
+*  performed for the plane (k,z), giving P(k) the form
+*  
+*     P(k) = ( 1                                             )
+*            (      ...                                      )
+*            (             1                                 )
+*            (                  c(k)                    s(k) )
+*            (                         1                     )
+*            (                              ...              )
+*            (                                     1         )
+*            (                 -s(k)                    c(k) )
+*  
+*  where R(k) appears in rows and columns k and z.  The rotations are
+*  performed without ever forming P(k) explicitly.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          Specifies whether the plane rotation matrix P is applied to
+*          A on the left or the right.
+*          = 'L':  Left, compute A := P*A
+*          = 'R':  Right, compute A:= A*P**T
+*
+*  PIVOT   (input) CHARACTER*1
+*          Specifies the plane for which P(k) is a plane rotation
+*          matrix.
+*          = 'V':  Variable pivot, the plane (k,k+1)
+*          = 'T':  Top pivot, the plane (1,k+1)
+*          = 'B':  Bottom pivot, the plane (k,z)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies whether P is a forward or backward sequence of
+*          plane rotations.
+*          = 'F':  Forward, P = P(z-1)*...*P(2)*P(1)
+*          = 'B':  Backward, P = P(1)*P(2)*...*P(z-1)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  If m <= 1, an immediate
+*          return is effected.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  If n <= 1, an
+*          immediate return is effected.
+*
+*  C       (input) REAL array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The cosines c(k) of the plane rotations.
+*
+*  S       (input) REAL array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The sines s(k) of the plane rotations.  The 2-by-2 plane
+*          rotation part of the matrix P(k), R(k), has the form
+*          R(k) = (  c(k)  s(k) )
+*                 ( -s(k)  c(k) ).
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          The M-by-N matrix A.  On exit, A is overwritten by P*A if
+*          SIDE = 'R' or by A*P**T if SIDE = 'L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+      REAL               CTEMP, STEMP
+      COMPLEX            TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THEN
+         INFO = 1
+      ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT,
+     $         'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THEN
+         INFO = 2
+      ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) )
+     $          THEN
+         INFO = 3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = 4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLASR ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  P * A
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 20 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 10 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 40 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 30 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   30                CONTINUE
+                  END IF
+   40          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 60 J = 2, M
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 50 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 80 J = M, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 70 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   70                CONTINUE
+                  END IF
+   80          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 100 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 90 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+   90                CONTINUE
+                  END IF
+  100          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 120 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 110 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+  110                CONTINUE
+                  END IF
+  120          CONTINUE
+            END IF
+         END IF
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form A * P'
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 140 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 130 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  130                CONTINUE
+                  END IF
+  140          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 160 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 150 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  150                CONTINUE
+                  END IF
+  160          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 180 J = 2, N
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 170 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  170                CONTINUE
+                  END IF
+  180          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 200 J = N, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 190 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  190                CONTINUE
+                  END IF
+  200          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 220 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 210 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  210                CONTINUE
+                  END IF
+  220          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 240 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 230 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  230                CONTINUE
+                  END IF
+  240          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CLASR
+*
+      END
diff --git a/libcruft/lapack/classq.f b/libcruft/lapack/classq.f
new file mode 100644
index 0000000..f4b4120
--- /dev/null
+++ b/libcruft/lapack/classq.f
@@ -0,0 +1,101 @@
+      SUBROUTINE CLASSQ( N, X, INCX, SCALE, SUMSQ )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      REAL               SCALE, SUMSQ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLASSQ returns the values scl and ssq such that
+*
+*     ( scl**2 )*ssq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
+*
+*  where x( i ) = abs( X( 1 + ( i - 1 )*INCX ) ). The value of sumsq is
+*  assumed to be at least unity and the value of ssq will then satisfy
+*
+*     1.0 .le. ssq .le. ( sumsq + 2*n ).
+*
+*  scale is assumed to be non-negative and scl returns the value
+*
+*     scl = max( scale, abs( real( x( i ) ) ), abs( aimag( x( i ) ) ) ),
+*            i
+*
+*  scale and sumsq must be supplied in SCALE and SUMSQ respectively.
+*  SCALE and SUMSQ are overwritten by scl and ssq respectively.
+*
+*  The routine makes only one pass through the vector X.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements to be used from the vector X.
+*
+*  X       (input) COMPLEX array, dimension (N)
+*          The vector x as described above.
+*             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector X.
+*          INCX > 0.
+*
+*  SCALE   (input/output) REAL
+*          On entry, the value  scale  in the equation above.
+*          On exit, SCALE is overwritten with the value  scl .
+*
+*  SUMSQ   (input/output) REAL
+*          On entry, the value  sumsq  in the equation above.
+*          On exit, SUMSQ is overwritten with the value  ssq .
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IX
+      REAL               TEMP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, REAL
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.GT.0 ) THEN
+         DO 10 IX = 1, 1 + ( N-1 )*INCX, INCX
+            IF( REAL( X( IX ) ).NE.ZERO ) THEN
+               TEMP1 = ABS( REAL( X( IX ) ) )
+               IF( SCALE.LT.TEMP1 ) THEN
+                  SUMSQ = 1 + SUMSQ*( SCALE / TEMP1 )**2
+                  SCALE = TEMP1
+               ELSE
+                  SUMSQ = SUMSQ + ( TEMP1 / SCALE )**2
+               END IF
+            END IF
+            IF( AIMAG( X( IX ) ).NE.ZERO ) THEN
+               TEMP1 = ABS( AIMAG( X( IX ) ) )
+               IF( SCALE.LT.TEMP1 ) THEN
+                  SUMSQ = 1 + SUMSQ*( SCALE / TEMP1 )**2
+                  SCALE = TEMP1
+               ELSE
+                  SUMSQ = SUMSQ + ( TEMP1 / SCALE )**2
+               END IF
+            END IF
+   10    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLASSQ
+*
+      END
diff --git a/libcruft/lapack/claswp.f b/libcruft/lapack/claswp.f
new file mode 100644
index 0000000..0ea8f16
--- /dev/null
+++ b/libcruft/lapack/claswp.f
@@ -0,0 +1,119 @@
+      SUBROUTINE CLASWP( N, A, LDA, K1, K2, IPIV, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, K1, K2, LDA, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLASWP performs a series of row interchanges on the matrix A.
+*  One row interchange is initiated for each of rows K1 through K2 of A.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the matrix of column dimension N to which the row
+*          interchanges will be applied.
+*          On exit, the permuted matrix.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*
+*  K1      (input) INTEGER
+*          The first element of IPIV for which a row interchange will
+*          be done.
+*
+*  K2      (input) INTEGER
+*          The last element of IPIV for which a row interchange will
+*          be done.
+*
+*  IPIV    (input) INTEGER array, dimension (K2*abs(INCX))
+*          The vector of pivot indices.  Only the elements in positions
+*          K1 through K2 of IPIV are accessed.
+*          IPIV(K) = L implies rows K and L are to be interchanged.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of IPIV.  If IPIV
+*          is negative, the pivots are applied in reverse order.
+*
+*  Further Details
+*  ===============
+*
+*  Modified by
+*   R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, I1, I2, INC, IP, IX, IX0, J, K, N32
+      COMPLEX            TEMP
+*     ..
+*     .. Executable Statements ..
+*
+*     Interchange row I with row IPIV(I) for each of rows K1 through K2.
+*
+      IF( INCX.GT.0 ) THEN
+         IX0 = K1
+         I1 = K1
+         I2 = K2
+         INC = 1
+      ELSE IF( INCX.LT.0 ) THEN
+         IX0 = 1 + ( 1-K2 )*INCX
+         I1 = K2
+         I2 = K1
+         INC = -1
+      ELSE
+         RETURN
+      END IF
+*
+      N32 = ( N / 32 )*32
+      IF( N32.NE.0 ) THEN
+         DO 30 J = 1, N32, 32
+            IX = IX0
+            DO 20 I = I1, I2, INC
+               IP = IPIV( IX )
+               IF( IP.NE.I ) THEN
+                  DO 10 K = J, J + 31
+                     TEMP = A( I, K )
+                     A( I, K ) = A( IP, K )
+                     A( IP, K ) = TEMP
+   10             CONTINUE
+               END IF
+               IX = IX + INCX
+   20       CONTINUE
+   30    CONTINUE
+      END IF
+      IF( N32.NE.N ) THEN
+         N32 = N32 + 1
+         IX = IX0
+         DO 50 I = I1, I2, INC
+            IP = IPIV( IX )
+            IF( IP.NE.I ) THEN
+               DO 40 K = N32, N
+                  TEMP = A( I, K )
+                  A( I, K ) = A( IP, K )
+                  A( IP, K ) = TEMP
+   40          CONTINUE
+            END IF
+            IX = IX + INCX
+   50    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLASWP
+*
+      END
diff --git a/libcruft/lapack/clatbs.f b/libcruft/lapack/clatbs.f
new file mode 100644
index 0000000..aa48c9c
--- /dev/null
+++ b/libcruft/lapack/clatbs.f
@@ -0,0 +1,908 @@
+      SUBROUTINE CLATBS( UPLO, TRANS, DIAG, NORMIN, N, KD, AB, LDAB, X,
+     $                   SCALE, CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, KD, LDAB, N
+      REAL               SCALE
+*     ..
+*     .. Array Arguments ..
+      REAL               CNORM( * )
+      COMPLEX            AB( LDAB, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLATBS solves one of the triangular systems
+*
+*     A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b,
+*
+*  with scaling to prevent overflow, where A is an upper or lower
+*  triangular band matrix.  Here A' denotes the transpose of A, x and b
+*  are n-element vectors, and s is a scaling factor, usually less than
+*  or equal to 1, chosen so that the components of x will be less than
+*  the overflow threshold.  If the unscaled problem will not cause
+*  overflow, the Level 2 BLAS routine CTBSV is called.  If the matrix A
+*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a
+*  non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b     (No transpose)
+*          = 'T':  Solve A**T * x = s*b  (Transpose)
+*          = 'C':  Solve A**H * x = s*b  (Conjugate transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of subdiagonals or superdiagonals in the
+*          triangular matrix A.  KD >= 0.
+*
+*  AB      (input) COMPLEX array, dimension (LDAB,N)
+*          The upper or lower triangular band matrix A, stored in the
+*          first KD+1 rows of the array. The j-th column of A is stored
+*          in the j-th column of the array AB as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  X       (input/output) COMPLEX array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) REAL
+*          The scaling factor s for the triangular system
+*             A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) REAL array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, CTBSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine CTBSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A**T *x = b  or
+*  A**H *x = b.  The basic algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call CTBSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0,
+     $                   TWO = 2.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST, JLEN, MAIND
+      REAL               BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
+     $                   XBND, XJ, XMAX
+      COMPLEX            CSUMJ, TJJS, USCAL, ZDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX, ISAMAX
+      REAL               SCASUM, SLAMCH
+      COMPLEX            CDOTC, CDOTU, CLADIV
+      EXTERNAL           LSAME, ICAMAX, ISAMAX, SCASUM, SLAMCH, CDOTC,
+     $                   CDOTU, CLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CSSCAL, CTBSV, SLABAD, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1, CABS2
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+      CABS2( ZDUM ) = ABS( REAL( ZDUM ) / 2. ) +
+     $                ABS( AIMAG( ZDUM ) / 2. )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLATBS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM / SLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               JLEN = MIN( KD, J-1 )
+               CNORM( J ) = SCASUM( JLEN, AB( KD+1-JLEN, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N
+               JLEN = MIN( KD, N-J )
+               IF( JLEN.GT.0 ) THEN
+                  CNORM( J ) = SCASUM( JLEN, AB( 2, J ), 1 )
+               ELSE
+                  CNORM( J ) = ZERO
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM/2.
+*
+      IMAX = ISAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM*HALF ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = HALF / ( SMLNUM*TMAX )
+         CALL SSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine CTBSV can be used.
+*
+      XMAX = ZERO
+      DO 30 J = 1, N
+         XMAX = MAX( XMAX, CABS2( X( J ) ) )
+   30 CONTINUE
+      XBND = XMAX
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 60
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+               TJJS = AB( MAIND, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = G(j-1) / abs(A(j,j))
+*
+                  XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+*
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   40       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 50 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   50       CONTINUE
+         END IF
+   60    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A**T * x = b  or  A**H * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 90
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+               TJJS = AB( MAIND, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+                  IF( XJ.GT.TJJ )
+     $               XBND = XBND*( TJJ / XJ )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+   70       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 80 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   80       CONTINUE
+         END IF
+   90    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL CTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM*HALF ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = ( BIGNUM*HALF ) / XMAX
+            CALL CSSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         ELSE
+            XMAX = XMAX*TWO
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 110 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = CABS1( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = AB( MAIND, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 105
+               END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                           REC = ONE / XJ
+                           CALL CSSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = CLADIV( X( J ), TJJS )
+                     XJ = CABS1( X( J ) )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                           REC = REC / CNORM( J )
+                        END IF
+                        CALL CSSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = CLADIV( X( J ), TJJS )
+                     XJ = CABS1( X( J ) )
+                  ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                     DO 100 I = 1, N
+                        X( I ) = ZERO
+  100                CONTINUE
+                     X( J ) = ONE
+                     XJ = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  105          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL CSSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL CSSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(max(1,j-kd):j-1) := x(max(1,j-kd):j-1) -
+*                                             x(j)* A(max(1,j-kd):j-1,j)
+*
+                     JLEN = MIN( KD, J-1 )
+                     CALL CAXPY( JLEN, -X( J )*TSCAL,
+     $                           AB( KD+1-JLEN, J ), 1, X( J-JLEN ), 1 )
+                     I = ICAMAX( J-1, X, 1 )
+                     XMAX = CABS1( X( I ) )
+                  END IF
+               ELSE IF( J.LT.N ) THEN
+*
+*                 Compute the update
+*                    x(j+1:min(j+kd,n)) := x(j+1:min(j+kd,n)) -
+*                                          x(j) * A(j+1:min(j+kd,n),j)
+*
+                  JLEN = MIN( KD, N-J )
+                  IF( JLEN.GT.0 )
+     $               CALL CAXPY( JLEN, -X( J )*TSCAL, AB( 2, J ), 1,
+     $                           X( J+1 ), 1 )
+                  I = J + ICAMAX( N-J, X( J+1 ), 1 )
+                  XMAX = CABS1( X( I ) )
+               END IF
+  110       CONTINUE
+*
+         ELSE IF( LSAME( TRANS, 'T' ) ) THEN
+*
+*           Solve A**T * x = b
+*
+            DO 150 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                        REC = MIN( ONE, REC*TJJ )
+                        USCAL = CLADIV( USCAL, TJJS )
+                     END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL CSSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.CMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call CDOTU to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     CSUMJ = CDOTU( JLEN, AB( KD+1-JLEN, J ), 1,
+     $                       X( J-JLEN ), 1 )
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     IF( JLEN.GT.1 )
+     $                  CSUMJ = CDOTU( JLEN, AB( 2, J ), 1, X( J+1 ),
+     $                          1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     DO 120 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( AB( KD+I-JLEN, J )*USCAL )*
+     $                          X( J-JLEN-1+I )
+  120                CONTINUE
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     DO 130 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( AB( I+1, J )*USCAL )*X( J+I )
+  130                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.CMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 145
+                  END IF
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                        IF( TJJ.LT.ONE ) THEN
+                           IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                              REC = ONE / XJ
+                              CALL CSSCAL( N, REC, X, 1 )
+                              SCALE = SCALE*REC
+                              XMAX = XMAX*REC
+                           END IF
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                           REC = ( TJJ*BIGNUM ) / XJ
+                           CALL CSSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**T *x = 0.
+*
+                        DO 140 I = 1, N
+                           X( I ) = ZERO
+  140                   CONTINUE
+                        X( J ) = ONE
+                        SCALE = ZERO
+                        XMAX = ZERO
+                     END IF
+  145             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = CLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  150       CONTINUE
+*
+         ELSE
+*
+*           Solve A**H * x = b
+*
+            DO 190 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = CONJG( AB( MAIND, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                        REC = MIN( ONE, REC*TJJ )
+                        USCAL = CLADIV( USCAL, TJJS )
+                     END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL CSSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.CMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call CDOTC to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     CSUMJ = CDOTC( JLEN, AB( KD+1-JLEN, J ), 1,
+     $                       X( J-JLEN ), 1 )
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     IF( JLEN.GT.1 )
+     $                  CSUMJ = CDOTC( JLEN, AB( 2, J ), 1, X( J+1 ),
+     $                          1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     DO 160 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( CONJG( AB( KD+I-JLEN, J ) )*
+     $                          USCAL )*X( J-JLEN-1+I )
+  160                CONTINUE
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     DO 170 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( CONJG( AB( I+1, J ) )*USCAL )*
+     $                          X( J+I )
+  170                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.CMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJS = CONJG( AB( MAIND, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 185
+                  END IF
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                        IF( TJJ.LT.ONE ) THEN
+                           IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                              REC = ONE / XJ
+                              CALL CSSCAL( N, REC, X, 1 )
+                              SCALE = SCALE*REC
+                              XMAX = XMAX*REC
+                           END IF
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                           REC = ( TJJ*BIGNUM ) / XJ
+                           CALL CSSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**H *x = 0.
+*
+                        DO 180 I = 1, N
+                           X( I ) = ZERO
+  180                   CONTINUE
+                        X( J ) = ONE
+                        SCALE = ZERO
+                        XMAX = ZERO
+                     END IF
+  185             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = CLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  190       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of CLATBS
+*
+      END
diff --git a/libcruft/lapack/clatrd.f b/libcruft/lapack/clatrd.f
new file mode 100644
index 0000000..8856ec2
--- /dev/null
+++ b/libcruft/lapack/clatrd.f
@@ -0,0 +1,279 @@
+      SUBROUTINE CLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDW, N, NB
+*     ..
+*     .. Array Arguments ..
+      REAL               E( * )
+      COMPLEX            A( LDA, * ), TAU( * ), W( LDW, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLATRD reduces NB rows and columns of a complex Hermitian matrix A to
+*  Hermitian tridiagonal form by a unitary similarity
+*  transformation Q' * A * Q, and returns the matrices V and W which are
+*  needed to apply the transformation to the unreduced part of A.
+*
+*  If UPLO = 'U', CLATRD reduces the last NB rows and columns of a
+*  matrix, of which the upper triangle is supplied;
+*  if UPLO = 'L', CLATRD reduces the first NB rows and columns of a
+*  matrix, of which the lower triangle is supplied.
+*
+*  This is an auxiliary routine called by CHETRD.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored:
+*          = 'U': Upper triangular
+*          = 'L': Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of rows and columns to be reduced.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit:
+*          if UPLO = 'U', the last NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements above the diagonal
+*            with the array TAU, represent the unitary matrix Q as a
+*            product of elementary reflectors;
+*          if UPLO = 'L', the first NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements below the diagonal
+*            with the array TAU, represent the  unitary matrix Q as a
+*            product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  E       (output) REAL array, dimension (N-1)
+*          If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal
+*          elements of the last NB columns of the reduced matrix;
+*          if UPLO = 'L', E(1:nb) contains the subdiagonal elements of
+*          the first NB columns of the reduced matrix.
+*
+*  TAU     (output) COMPLEX array, dimension (N-1)
+*          The scalar factors of the elementary reflectors, stored in
+*          TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'.
+*          See Further Details.
+*
+*  W       (output) COMPLEX array, dimension (LDW,NB)
+*          The n-by-nb matrix W required to update the unreduced part
+*          of A.
+*
+*  LDW     (input) INTEGER
+*          The leading dimension of the array W. LDW >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n) H(n-1) . . . H(n-nb+1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i),
+*  and tau in TAU(i-1).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),
+*  and tau in TAU(i).
+*
+*  The elements of the vectors v together form the n-by-nb matrix V
+*  which is needed, with W, to apply the transformation to the unreduced
+*  part of the matrix, using a Hermitian rank-2k update of the form:
+*  A := A - V*W' - W*V'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5 and nb = 2:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  a   a   a   v4  v5 )              (  d                  )
+*    (      a   a   v4  v5 )              (  1   d              )
+*    (          a   1   v5 )              (  v1  1   a          )
+*    (              d   1  )              (  v1  v2  a   a      )
+*    (                  d  )              (  v1  v2  a   a   a  )
+*
+*  where d denotes a diagonal element of the reduced matrix, a denotes
+*  an element of the original matrix that is unchanged, and vi denotes
+*  an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE, HALF
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   HALF = ( 0.5E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IW
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CGEMV, CHEMV, CLACGV, CLARFG, CSCAL
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX            CDOTC
+      EXTERNAL           LSAME, CDOTC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Reduce last NB columns of upper triangle
+*
+         DO 10 I = N, N - NB + 1, -1
+            IW = I - N + NB
+            IF( I.LT.N ) THEN
+*
+*              Update A(1:i,i)
+*
+               A( I, I ) = REAL( A( I, I ) )
+               CALL CLACGV( N-I, W( I, IW+1 ), LDW )
+               CALL CGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 )
+               CALL CLACGV( N-I, W( I, IW+1 ), LDW )
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+               CALL CGEMV( 'No transpose', I, N-I, -ONE, W( 1, IW+1 ),
+     $                     LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 )
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+               A( I, I ) = REAL( A( I, I ) )
+            END IF
+            IF( I.GT.1 ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(1:i-2,i)
+*
+               ALPHA = A( I-1, I )
+               CALL CLARFG( I-1, ALPHA, A( 1, I ), 1, TAU( I-1 ) )
+               E( I-1 ) = ALPHA
+               A( I-1, I ) = ONE
+*
+*              Compute W(1:i-1,i)
+*
+               CALL CHEMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1,
+     $                     ZERO, W( 1, IW ), 1 )
+               IF( I.LT.N ) THEN
+                  CALL CGEMV( 'Conjugate transpose', I-1, N-I, ONE,
+     $                        W( 1, IW+1 ), LDW, A( 1, I ), 1, ZERO,
+     $                        W( I+1, IW ), 1 )
+                  CALL CGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+                  CALL CGEMV( 'Conjugate transpose', I-1, N-I, ONE,
+     $                        A( 1, I+1 ), LDA, A( 1, I ), 1, ZERO,
+     $                        W( I+1, IW ), 1 )
+                  CALL CGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+               END IF
+               CALL CSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 )
+               ALPHA = -HALF*TAU( I-1 )*CDOTC( I-1, W( 1, IW ), 1,
+     $                 A( 1, I ), 1 )
+               CALL CAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 )
+            END IF
+*
+   10    CONTINUE
+      ELSE
+*
+*        Reduce first NB columns of lower triangle
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i:n,i)
+*
+            A( I, I ) = REAL( A( I, I ) )
+            CALL CLACGV( I-1, W( I, 1 ), LDW )
+            CALL CGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 )
+            CALL CLACGV( I-1, W( I, 1 ), LDW )
+            CALL CLACGV( I-1, A( I, 1 ), LDA )
+            CALL CGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ),
+     $                  LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 )
+            CALL CLACGV( I-1, A( I, 1 ), LDA )
+            A( I, I ) = REAL( A( I, I ) )
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:n,i)
+*
+               ALPHA = A( I+1, I )
+               CALL CLARFG( N-I, ALPHA, A( MIN( I+2, N ), I ), 1,
+     $                      TAU( I ) )
+               E( I ) = ALPHA
+               A( I+1, I ) = ONE
+*
+*              Compute W(i+1:n,i)
+*
+               CALL CHEMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, W( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', N-I, I-1, ONE,
+     $                     W( I+1, 1 ), LDW, A( I+1, I ), 1, ZERO,
+     $                     W( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL CGEMV( 'Conjugate transpose', N-I, I-1, ONE,
+     $                     A( I+1, 1 ), LDA, A( I+1, I ), 1, ZERO,
+     $                     W( 1, I ), 1 )
+               CALL CGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, 1 ),
+     $                     LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL CSCAL( N-I, TAU( I ), W( I+1, I ), 1 )
+               ALPHA = -HALF*TAU( I )*CDOTC( N-I, W( I+1, I ), 1,
+     $                 A( I+1, I ), 1 )
+               CALL CAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), 1 )
+            END IF
+*
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLATRD
+*
+      END
diff --git a/libcruft/lapack/clatrs.f b/libcruft/lapack/clatrs.f
new file mode 100644
index 0000000..2a32eab
--- /dev/null
+++ b/libcruft/lapack/clatrs.f
@@ -0,0 +1,879 @@
+      SUBROUTINE CLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
+     $                   CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, LDA, N
+      REAL               SCALE
+*     ..
+*     .. Array Arguments ..
+      REAL               CNORM( * )
+      COMPLEX            A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLATRS solves one of the triangular systems
+*
+*     A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b,
+*
+*  with scaling to prevent overflow.  Here A is an upper or lower
+*  triangular matrix, A**T denotes the transpose of A, A**H denotes the
+*  conjugate transpose of A, x and b are n-element vectors, and s is a
+*  scaling factor, usually less than or equal to 1, chosen so that the
+*  components of x will be less than the overflow threshold.  If the
+*  unscaled problem will not cause overflow, the Level 2 BLAS routine
+*  CTRSV is called. If the matrix A is singular (A(j,j) = 0 for some j),
+*  then s is set to 0 and a non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b     (No transpose)
+*          = 'T':  Solve A**T * x = s*b  (Transpose)
+*          = 'C':  Solve A**H * x = s*b  (Conjugate transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max (1,N).
+*
+*  X       (input/output) COMPLEX array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) REAL
+*          The scaling factor s for the triangular system
+*             A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) REAL array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, CTRSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine CTRSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A**T *x = b  or
+*  A**H *x = b.  The basic algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call CTRSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0,
+     $                   TWO = 2.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST
+      REAL               BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
+     $                   XBND, XJ, XMAX
+      COMPLEX            CSUMJ, TJJS, USCAL, ZDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX, ISAMAX
+      REAL               SCASUM, SLAMCH
+      COMPLEX            CDOTC, CDOTU, CLADIV
+      EXTERNAL           LSAME, ICAMAX, ISAMAX, SCASUM, SLAMCH, CDOTC,
+     $                   CDOTU, CLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CAXPY, CSSCAL, CTRSV, SLABAD, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1, CABS2
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+      CABS2( ZDUM ) = ABS( REAL( ZDUM ) / 2. ) +
+     $                ABS( AIMAG( ZDUM ) / 2. )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLATRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM / SLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               CNORM( J ) = SCASUM( J-1, A( 1, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N - 1
+               CNORM( J ) = SCASUM( N-J, A( J+1, J ), 1 )
+   20       CONTINUE
+            CNORM( N ) = ZERO
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM/2.
+*
+      IMAX = ISAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM*HALF ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = HALF / ( SMLNUM*TMAX )
+         CALL SSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine CTRSV can be used.
+*
+      XMAX = ZERO
+      DO 30 J = 1, N
+         XMAX = MAX( XMAX, CABS2( X( J ) ) )
+   30 CONTINUE
+      XBND = XMAX
+*
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 60
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+               TJJS = A( J, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = G(j-1) / abs(A(j,j))
+*
+                  XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+*
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   40       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 50 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   50       CONTINUE
+         END IF
+   60    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A**T * x = b  or  A**H * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 90
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+               TJJS = A( J, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+                  IF( XJ.GT.TJJ )
+     $               XBND = XBND*( TJJ / XJ )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+   70       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 80 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   80       CONTINUE
+         END IF
+   90    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL CTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM*HALF ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = ( BIGNUM*HALF ) / XMAX
+            CALL CSSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         ELSE
+            XMAX = XMAX*TWO
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 110 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = CABS1( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = A( J, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 105
+               END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                           REC = ONE / XJ
+                           CALL CSSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = CLADIV( X( J ), TJJS )
+                     XJ = CABS1( X( J ) )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                           REC = REC / CNORM( J )
+                        END IF
+                        CALL CSSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = CLADIV( X( J ), TJJS )
+                     XJ = CABS1( X( J ) )
+                  ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                     DO 100 I = 1, N
+                        X( I ) = ZERO
+  100                CONTINUE
+                     X( J ) = ONE
+                     XJ = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  105          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL CSSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL CSSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
+*
+                     CALL CAXPY( J-1, -X( J )*TSCAL, A( 1, J ), 1, X,
+     $                           1 )
+                     I = ICAMAX( J-1, X, 1 )
+                     XMAX = CABS1( X( I ) )
+                  END IF
+               ELSE
+                  IF( J.LT.N ) THEN
+*
+*                    Compute the update
+*                       x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
+*
+                     CALL CAXPY( N-J, -X( J )*TSCAL, A( J+1, J ), 1,
+     $                           X( J+1 ), 1 )
+                     I = J + ICAMAX( N-J, X( J+1 ), 1 )
+                     XMAX = CABS1( X( I ) )
+                  END IF
+               END IF
+  110       CONTINUE
+*
+         ELSE IF( LSAME( TRANS, 'T' ) ) THEN
+*
+*           Solve A**T * x = b
+*
+            DO 150 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                        REC = MIN( ONE, REC*TJJ )
+                        USCAL = CLADIV( USCAL, TJJS )
+                     END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL CSSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.CMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call CDOTU to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     CSUMJ = CDOTU( J-1, A( 1, J ), 1, X, 1 )
+                  ELSE IF( J.LT.N ) THEN
+                     CSUMJ = CDOTU( N-J, A( J+1, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     DO 120 I = 1, J - 1
+                        CSUMJ = CSUMJ + ( A( I, J )*USCAL )*X( I )
+  120                CONTINUE
+                  ELSE IF( J.LT.N ) THEN
+                     DO 130 I = J + 1, N
+                        CSUMJ = CSUMJ + ( A( I, J )*USCAL )*X( I )
+  130                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.CMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 145
+                  END IF
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                        IF( TJJ.LT.ONE ) THEN
+                           IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                              REC = ONE / XJ
+                              CALL CSSCAL( N, REC, X, 1 )
+                              SCALE = SCALE*REC
+                              XMAX = XMAX*REC
+                           END IF
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                           REC = ( TJJ*BIGNUM ) / XJ
+                           CALL CSSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**T *x = 0.
+*
+                        DO 140 I = 1, N
+                           X( I ) = ZERO
+  140                   CONTINUE
+                        X( J ) = ONE
+                        SCALE = ZERO
+                        XMAX = ZERO
+                     END IF
+  145             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = CLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  150       CONTINUE
+*
+         ELSE
+*
+*           Solve A**H * x = b
+*
+            DO 190 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = CONJG( A( J, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                        REC = MIN( ONE, REC*TJJ )
+                        USCAL = CLADIV( USCAL, TJJS )
+                     END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL CSSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.CMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call CDOTC to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     CSUMJ = CDOTC( J-1, A( 1, J ), 1, X, 1 )
+                  ELSE IF( J.LT.N ) THEN
+                     CSUMJ = CDOTC( N-J, A( J+1, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     DO 160 I = 1, J - 1
+                        CSUMJ = CSUMJ + ( CONJG( A( I, J ) )*USCAL )*
+     $                          X( I )
+  160                CONTINUE
+                  ELSE IF( J.LT.N ) THEN
+                     DO 170 I = J + 1, N
+                        CSUMJ = CSUMJ + ( CONJG( A( I, J ) )*USCAL )*
+     $                          X( I )
+  170                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.CMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+                     TJJS = CONJG( A( J, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 185
+                  END IF
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJ = CABS1( TJJS )
+                     IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                        IF( TJJ.LT.ONE ) THEN
+                           IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                              REC = ONE / XJ
+                              CALL CSSCAL( N, REC, X, 1 )
+                              SCALE = SCALE*REC
+                              XMAX = XMAX*REC
+                           END IF
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                           REC = ( TJJ*BIGNUM ) / XJ
+                           CALL CSSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                        X( J ) = CLADIV( X( J ), TJJS )
+                     ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**H *x = 0.
+*
+                        DO 180 I = 1, N
+                           X( I ) = ZERO
+  180                   CONTINUE
+                        X( J ) = ONE
+                        SCALE = ZERO
+                        XMAX = ZERO
+                     END IF
+  185             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = CLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  190       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of CLATRS
+*
+      END
diff --git a/libcruft/lapack/clatrz.f b/libcruft/lapack/clatrz.f
new file mode 100644
index 0000000..829fa63
--- /dev/null
+++ b/libcruft/lapack/clatrz.f
@@ -0,0 +1,133 @@
+      SUBROUTINE CLATRZ( M, N, L, A, LDA, TAU, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            L, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLATRZ factors the M-by-(M+L) complex upper trapezoidal matrix
+*  [ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R  0 ) * Z by means
+*  of unitary transformations, where  Z is an (M+L)-by-(M+L) unitary
+*  matrix and, R and A1 are M-by-M upper triangular matrices.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing the
+*          meaningful part of the Householder vectors. N-M >= L >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements N-L+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          unitary matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) COMPLEX array, dimension (M)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an l element vector. tau and z( k )
+*  are chosen to annihilate the elements of the kth row of A2.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A2, such that the elements of z( k ) are
+*  in  a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A1.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX            ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACGV, CLARFG, CLARZ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      DO 20 I = M, 1, -1
+*
+*        Generate elementary reflector H(i) to annihilate
+*        [ A(i,i) A(i,n-l+1:n) ]
+*
+         CALL CLACGV( L, A( I, N-L+1 ), LDA )
+         ALPHA = CONJG( A( I, I ) )
+         CALL CLARFG( L+1, ALPHA, A( I, N-L+1 ), LDA, TAU( I ) )
+         TAU( I ) = CONJG( TAU( I ) )
+*
+*        Apply H(i) to A(1:i-1,i:n) from the right
+*
+         CALL CLARZ( 'Right', I-1, N-I+1, L, A( I, N-L+1 ), LDA,
+     $               CONJG( TAU( I ) ), A( 1, I ), LDA, WORK )
+         A( I, I ) = CONJG( ALPHA )
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of CLATRZ
+*
+      END
diff --git a/libcruft/lapack/clauu2.f b/libcruft/lapack/clauu2.f
new file mode 100644
index 0000000..50c66a7
--- /dev/null
+++ b/libcruft/lapack/clauu2.f
@@ -0,0 +1,143 @@
+      SUBROUTINE CLAUU2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAUU2 computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the unblocked form of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      REAL               AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX            CDOTC
+      EXTERNAL           LSAME, CDOTC
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CLACGV, CSSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CMPLX, MAX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLAUU2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the product U * U'.
+*
+         DO 10 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = AII*AII + REAL( CDOTC( N-I, A( I, I+1 ), LDA,
+     $                     A( I, I+1 ), LDA ) )
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+               CALL CGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, CMPLX( AII ),
+     $                     A( 1, I ), 1 )
+               CALL CLACGV( N-I, A( I, I+1 ), LDA )
+            ELSE
+               CALL CSSCAL( I, AII, A( 1, I ), 1 )
+            END IF
+   10    CONTINUE
+*
+      ELSE
+*
+*        Compute the product L' * L.
+*
+         DO 20 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = AII*AII + REAL( CDOTC( N-I, A( I+1, I ), 1,
+     $                     A( I+1, I ), 1 ) )
+               CALL CLACGV( I-1, A( I, 1 ), LDA )
+               CALL CGEMV( 'Conjugate transpose', N-I, I-1, ONE,
+     $                     A( I+1, 1 ), LDA, A( I+1, I ), 1,
+     $                     CMPLX( AII ), A( I, 1 ), LDA )
+               CALL CLACGV( I-1, A( I, 1 ), LDA )
+            ELSE
+               CALL CSSCAL( I, AII, A( I, 1 ), LDA )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CLAUU2
+*
+      END
diff --git a/libcruft/lapack/clauum.f b/libcruft/lapack/clauum.f
new file mode 100644
index 0000000..9bc3a99
--- /dev/null
+++ b/libcruft/lapack/clauum.f
@@ -0,0 +1,160 @@
+      SUBROUTINE CLAUUM( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CLAUUM computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the blocked form of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+      COMPLEX            CONE
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, IB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CHERK, CLAUU2, CTRMM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CLAUUM', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'CLAUUM', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL CLAUU2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute the product U * U'.
+*
+            DO 10 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Non-unit', I-1, IB, CONE, A( I, I ), LDA,
+     $                     A( 1, I ), LDA )
+               CALL CLAUU2( 'Upper', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose',
+     $                        I-1, IB, N-I-IB+1, CONE, A( 1, I+IB ),
+     $                        LDA, A( I, I+IB ), LDA, CONE, A( 1, I ),
+     $                        LDA )
+                  CALL CHERK( 'Upper', 'No transpose', IB, N-I-IB+1,
+     $                        ONE, A( I, I+IB ), LDA, ONE, A( I, I ),
+     $                        LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute the product L' * L.
+*
+            DO 20 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL CTRMM( 'Left', 'Lower', 'Conjugate transpose',
+     $                     'Non-unit', IB, I-1, CONE, A( I, I ), LDA,
+     $                     A( I, 1 ), LDA )
+               CALL CLAUU2( 'Lower', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL CGEMM( 'Conjugate transpose', 'No transpose', IB,
+     $                        I-1, N-I-IB+1, CONE, A( I+IB, I ), LDA,
+     $                        A( I+IB, 1 ), LDA, CONE, A( I, 1 ), LDA )
+                  CALL CHERK( 'Lower', 'Conjugate transpose', IB,
+     $                        N-I-IB+1, ONE, A( I+IB, I ), LDA, ONE,
+     $                        A( I, I ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CLAUUM
+*
+      END
diff --git a/libcruft/lapack/cpbcon.f b/libcruft/lapack/cpbcon.f
new file mode 100644
index 0000000..cbe8698
--- /dev/null
+++ b/libcruft/lapack/cpbcon.f
@@ -0,0 +1,198 @@
+      SUBROUTINE CPBCON( UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK,
+     $                   RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPBCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a complex Hermitian positive definite band matrix using
+*  the Cholesky factorization A = U**H*U or A = L*L**H computed by
+*  CPBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of sub-diagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input) COMPLEX array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  ANORM   (input) REAL
+*          The 1-norm (or infinity-norm) of the Hermitian band matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      REAL               AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+      COMPLEX            ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ICAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACN2, CLATBS, CSRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of the inverse.
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL CLATBS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, KD, AB, LDAB, WORK, SCALEL, RWORK,
+     $                   INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL CLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEU, RWORK, INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL CLATBS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEL, RWORK, INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL CLATBS( 'Lower', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, KD, AB, LDAB, WORK, SCALEU, RWORK,
+     $                   INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = ICAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL CSRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of CPBCON
+*
+      END
diff --git a/libcruft/lapack/cpbtf2.f b/libcruft/lapack/cpbtf2.f
new file mode 100644
index 0000000..4049b90
--- /dev/null
+++ b/libcruft/lapack/cpbtf2.f
@@ -0,0 +1,200 @@
+      SUBROUTINE CPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPBTF2 computes the Cholesky factorization of a complex Hermitian
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix, U' is the conjugate transpose
+*  of U, and L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of super-diagonals of the matrix A if UPLO = 'U',
+*          or the number of sub-diagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) COMPLEX array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the Hermitian band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U'*U or A = L*L' of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, KLD, KN
+      REAL               AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CHER, CLACGV, CSSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      KLD = MAX( 1, LDAB-1 )
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = REAL( AB( KD+1, J ) )
+            IF( AJJ.LE.ZERO ) THEN
+               AB( KD+1, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            AB( KD+1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of row J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL CSSCAL( KN, ONE / AJJ, AB( KD, J+1 ), KLD )
+               CALL CLACGV( KN, AB( KD, J+1 ), KLD )
+               CALL CHER( 'Upper', KN, -ONE, AB( KD, J+1 ), KLD,
+     $                    AB( KD+1, J+1 ), KLD )
+               CALL CLACGV( KN, AB( KD, J+1 ), KLD )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = REAL( AB( 1, J ) )
+            IF( AJJ.LE.ZERO ) THEN
+               AB( 1, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            AB( 1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of column J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL CSSCAL( KN, ONE / AJJ, AB( 2, J ), 1 )
+               CALL CHER( 'Lower', KN, -ONE, AB( 2, J ), 1,
+     $                    AB( 1, J+1 ), KLD )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+   30 CONTINUE
+      INFO = J
+      RETURN
+*
+*     End of CPBTF2
+*
+      END
diff --git a/libcruft/lapack/cpbtrf.f b/libcruft/lapack/cpbtrf.f
new file mode 100644
index 0000000..cee79d6
--- /dev/null
+++ b/libcruft/lapack/cpbtrf.f
@@ -0,0 +1,371 @@
+      SUBROUTINE CPBTRF( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPBTRF computes the Cholesky factorization of a complex Hermitian
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U**H * U,  if UPLO = 'U', or
+*     A = L  * L**H,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) COMPLEX array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the Hermitian band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U**H*U or A = L*L**H of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  Contributed by
+*  Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+      COMPLEX            CONE
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ) )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 32, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, IB, II, J, JJ, NB
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            WORK( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CHERK, CPBTF2, CPOTF2, CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ( .NOT.LSAME( UPLO, 'U' ) ) .AND.
+     $    ( .NOT.LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'CPBTRF', UPLO, N, KD, -1, -1 )
+*
+*     The block size must not exceed the semi-bandwidth KD, and must not
+*     exceed the limit set by the size of the local array WORK.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KD ) THEN
+*
+*        Use unblocked code
+*
+         CALL CPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*           Compute the Cholesky factorization of a Hermitian band
+*           matrix, given the upper triangle of the matrix in band
+*           storage.
+*
+*           Zero the upper triangle of the work array.
+*
+            DO 20 J = 1, NB
+               DO 10 I = 1, J - 1
+                  WORK( I, J ) = ZERO
+   10          CONTINUE
+   20       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 70 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL CPOTF2( UPLO, IB, AB( KD+1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11   A12   A13
+*                          A22   A23
+*                                A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A12, A22 and
+*                 A23 are empty if IB = KD. The upper triangle of A13
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A12
+*
+                     CALL CTRSM( 'Left', 'Upper', 'Conjugate transpose',
+     $                           'Non-unit', IB, I2, CONE,
+     $                           AB( KD+1, I ), LDAB-1,
+     $                           AB( KD+1-IB, I+IB ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL CHERK( 'Upper', 'Conjugate transpose', I2, IB,
+     $                           -ONE, AB( KD+1-IB, I+IB ), LDAB-1, ONE,
+     $                           AB( KD+1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the lower triangle of A13 into the work array.
+*
+                     DO 40 JJ = 1, I3
+                        DO 30 II = JJ, IB
+                           WORK( II, JJ ) = AB( II-JJ+1, JJ+I+KD-1 )
+   30                   CONTINUE
+   40                CONTINUE
+*
+*                    Update A13 (in the work array).
+*
+                     CALL CTRSM( 'Left', 'Upper', 'Conjugate transpose',
+     $                           'Non-unit', IB, I3, CONE,
+     $                           AB( KD+1, I ), LDAB-1, WORK, LDWORK )
+*
+*                    Update A23
+*
+                     IF( I2.GT.0 )
+     $                  CALL CGEMM( 'Conjugate transpose',
+     $                              'No transpose', I2, I3, IB, -CONE,
+     $                              AB( KD+1-IB, I+IB ), LDAB-1, WORK,
+     $                              LDWORK, CONE, AB( 1+IB, I+KD ),
+     $                              LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL CHERK( 'Upper', 'Conjugate transpose', I3, IB,
+     $                           -ONE, WORK, LDWORK, ONE,
+     $                           AB( KD+1, I+KD ), LDAB-1 )
+*
+*                    Copy the lower triangle of A13 back into place.
+*
+                     DO 60 JJ = 1, I3
+                        DO 50 II = JJ, IB
+                           AB( II-JJ+1, JJ+I+KD-1 ) = WORK( II, JJ )
+   50                   CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+   70       CONTINUE
+         ELSE
+*
+*           Compute the Cholesky factorization of a Hermitian band
+*           matrix, given the lower triangle of the matrix in band
+*           storage.
+*
+*           Zero the lower triangle of the work array.
+*
+            DO 90 J = 1, NB
+               DO 80 I = J + 1, NB
+                  WORK( I, J ) = ZERO
+   80          CONTINUE
+   90       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 140 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL CPOTF2( UPLO, IB, AB( 1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11
+*                    A21   A22
+*                    A31   A32   A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A21, A22 and
+*                 A32 are empty if IB = KD. The lower triangle of A31
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A21
+*
+                     CALL CTRSM( 'Right', 'Lower',
+     $                           'Conjugate transpose', 'Non-unit', I2,
+     $                           IB, CONE, AB( 1, I ), LDAB-1,
+     $                           AB( 1+IB, I ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL CHERK( 'Lower', 'No transpose', I2, IB, -ONE,
+     $                           AB( 1+IB, I ), LDAB-1, ONE,
+     $                           AB( 1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the upper triangle of A31 into the work array.
+*
+                     DO 110 JJ = 1, IB
+                        DO 100 II = 1, MIN( JJ, I3 )
+                           WORK( II, JJ ) = AB( KD+1-JJ+II, JJ+I-1 )
+  100                   CONTINUE
+  110                CONTINUE
+*
+*                    Update A31 (in the work array).
+*
+                     CALL CTRSM( 'Right', 'Lower',
+     $                           'Conjugate transpose', 'Non-unit', I3,
+     $                           IB, CONE, AB( 1, I ), LDAB-1, WORK,
+     $                           LDWORK )
+*
+*                    Update A32
+*
+                     IF( I2.GT.0 )
+     $                  CALL CGEMM( 'No transpose',
+     $                              'Conjugate transpose', I3, I2, IB,
+     $                              -CONE, WORK, LDWORK, AB( 1+IB, I ),
+     $                              LDAB-1, CONE, AB( 1+KD-IB, I+IB ),
+     $                              LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL CHERK( 'Lower', 'No transpose', I3, IB, -ONE,
+     $                           WORK, LDWORK, ONE, AB( 1, I+KD ),
+     $                           LDAB-1 )
+*
+*                    Copy the upper triangle of A31 back into place.
+*
+                     DO 130 JJ = 1, IB
+                        DO 120 II = 1, MIN( JJ, I3 )
+                           AB( KD+1-JJ+II, JJ+I-1 ) = WORK( II, JJ )
+  120                   CONTINUE
+  130                CONTINUE
+                  END IF
+               END IF
+  140       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+  150 CONTINUE
+      RETURN
+*
+*     End of CPBTRF
+*
+      END
diff --git a/libcruft/lapack/cpbtrs.f b/libcruft/lapack/cpbtrs.f
new file mode 100644
index 0000000..ca66fd1
--- /dev/null
+++ b/libcruft/lapack/cpbtrs.f
@@ -0,0 +1,145 @@
+      SUBROUTINE CPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPBTRS solves a system of linear equations A*X = B with a Hermitian
+*  positive definite band matrix A using the Cholesky factorization
+*  A = U**H*U or A = L*L**H computed by CPBTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) COMPLEX array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CTBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+         DO 10 J = 1, NRHS
+*
+*           Solve U'*X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Upper', 'Conjugate transpose', 'Non-unit', N,
+     $                  KD, AB, LDAB, B( 1, J ), 1 )
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Upper', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+         DO 20 J = 1, NRHS
+*
+*           Solve L*X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Lower', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+*
+*           Solve L'*X = B, overwriting B with X.
+*
+            CALL CTBSV( 'Lower', 'Conjugate transpose', 'Non-unit', N,
+     $                  KD, AB, LDAB, B( 1, J ), 1 )
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CPBTRS
+*
+      END
diff --git a/libcruft/lapack/cpocon.f b/libcruft/lapack/cpocon.f
new file mode 100644
index 0000000..d4b4c44
--- /dev/null
+++ b/libcruft/lapack/cpocon.f
@@ -0,0 +1,184 @@
+      SUBROUTINE CPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, RWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPOCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a complex Hermitian positive definite matrix using the
+*  Cholesky factorization A = U**H*U or A = L*L**H computed by CPOTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H, as computed by CPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) REAL
+*          The 1-norm (or infinity-norm) of the Hermitian matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      REAL               AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+      COMPLEX            ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ICAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACN2, CLATRS, CSRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MAX, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPOCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of inv(A).
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL CLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, A, LDA, WORK, SCALEL, RWORK, INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL CLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEU, RWORK, INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL CLATRS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEL, RWORK, INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL CLATRS( 'Lower', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, A, LDA, WORK, SCALEU, RWORK, INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = ICAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL CSRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of CPOCON
+*
+      END
diff --git a/libcruft/lapack/cpotf2.f b/libcruft/lapack/cpotf2.f
new file mode 100644
index 0000000..8edd89a
--- /dev/null
+++ b/libcruft/lapack/cpotf2.f
@@ -0,0 +1,174 @@
+      SUBROUTINE CPOTF2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPOTF2 computes the Cholesky factorization of a complex Hermitian
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U'*U  or A = L*L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+      COMPLEX            CONE
+      PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+      REAL               AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX            CDOTC
+      EXTERNAL           LSAME, CDOTC
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, CLACGV, CSSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPOTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = REAL( A( J, J ) ) - CDOTC( J-1, A( 1, J ), 1,
+     $            A( 1, J ), 1 )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of row J.
+*
+            IF( J.LT.N ) THEN
+               CALL CLACGV( J-1, A( 1, J ), 1 )
+               CALL CGEMV( 'Transpose', J-1, N-J, -CONE, A( 1, J+1 ),
+     $                     LDA, A( 1, J ), 1, CONE, A( J, J+1 ), LDA )
+               CALL CLACGV( J-1, A( 1, J ), 1 )
+               CALL CSSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = REAL( A( J, J ) ) - CDOTC( J-1, A( J, 1 ), LDA,
+     $            A( J, 1 ), LDA )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of column J.
+*
+            IF( J.LT.N ) THEN
+               CALL CLACGV( J-1, A( J, 1 ), LDA )
+               CALL CGEMV( 'No transpose', N-J, J-1, -CONE, A( J+1, 1 ),
+     $                     LDA, A( J, 1 ), LDA, CONE, A( J+1, J ), 1 )
+               CALL CLACGV( J-1, A( J, 1 ), LDA )
+               CALL CSSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = J
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of CPOTF2
+*
+      END
diff --git a/libcruft/lapack/cpotrf.f b/libcruft/lapack/cpotrf.f
new file mode 100644
index 0000000..f696527
--- /dev/null
+++ b/libcruft/lapack/cpotrf.f
@@ -0,0 +1,186 @@
+      SUBROUTINE CPOTRF( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPOTRF computes the Cholesky factorization of a complex Hermitian
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U**H * U,  if UPLO = 'U', or
+*     A = L  * L**H,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the block version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U**H*U or A = L*L**H.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      COMPLEX            CONE
+      PARAMETER          ( ONE = 1.0E+0, CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, JB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMM, CHERK, CPOTF2, CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPOTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'CPOTRF', UPLO, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         CALL CPOTF2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         IF( UPPER ) THEN
+*
+*           Compute the Cholesky factorization A = U'*U.
+*
+            DO 10 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL CHERK( 'Upper', 'Conjugate transpose', JB, J-1,
+     $                     -ONE, A( 1, J ), LDA, ONE, A( J, J ), LDA )
+               CALL CPOTF2( 'Upper', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block row.
+*
+                  CALL CGEMM( 'Conjugate transpose', 'No transpose', JB,
+     $                        N-J-JB+1, J-1, -CONE, A( 1, J ), LDA,
+     $                        A( 1, J+JB ), LDA, CONE, A( J, J+JB ),
+     $                        LDA )
+                  CALL CTRSM( 'Left', 'Upper', 'Conjugate transpose',
+     $                        'Non-unit', JB, N-J-JB+1, CONE, A( J, J ),
+     $                        LDA, A( J, J+JB ), LDA )
+               END IF
+   10       CONTINUE
+*
+         ELSE
+*
+*           Compute the Cholesky factorization A = L*L'.
+*
+            DO 20 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL CHERK( 'Lower', 'No transpose', JB, J-1, -ONE,
+     $                     A( J, 1 ), LDA, ONE, A( J, J ), LDA )
+               CALL CPOTF2( 'Lower', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block column.
+*
+                  CALL CGEMM( 'No transpose', 'Conjugate transpose',
+     $                        N-J-JB+1, JB, J-1, -CONE, A( J+JB, 1 ),
+     $                        LDA, A( J, 1 ), LDA, CONE, A( J+JB, J ),
+     $                        LDA )
+                  CALL CTRSM( 'Right', 'Lower', 'Conjugate transpose',
+     $                        'Non-unit', N-J-JB+1, JB, CONE, A( J, J ),
+     $                        LDA, A( J+JB, J ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = INFO + J - 1
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of CPOTRF
+*
+      END
diff --git a/libcruft/lapack/cpotri.f b/libcruft/lapack/cpotri.f
new file mode 100644
index 0000000..de48482
--- /dev/null
+++ b/libcruft/lapack/cpotri.f
@@ -0,0 +1,96 @@
+      SUBROUTINE CPOTRI( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPOTRI computes the inverse of a complex Hermitian positive definite
+*  matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
+*  computed by CPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the triangular factor U or L from the Cholesky
+*          factorization A = U**H*U or A = L*L**H, as computed by
+*          CPOTRF.
+*          On exit, the upper or lower triangle of the (Hermitian)
+*          inverse of A, overwriting the input factor U or L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the (i,i) element of the factor U or L is
+*                zero, and the inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLAUUM, CTRTRI, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPOTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Invert the triangular Cholesky factor U or L.
+*
+      CALL CTRTRI( UPLO, 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+*     Form inv(U)*inv(U)' or inv(L)'*inv(L).
+*
+      CALL CLAUUM( UPLO, N, A, LDA, INFO )
+*
+      RETURN
+*
+*     End of CPOTRI
+*
+      END
diff --git a/libcruft/lapack/cpotrs.f b/libcruft/lapack/cpotrs.f
new file mode 100644
index 0000000..3bfe126
--- /dev/null
+++ b/libcruft/lapack/cpotrs.f
@@ -0,0 +1,132 @@
+      SUBROUTINE CPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPOTRS solves a system of linear equations A*X = B with a Hermitian
+*  positive definite matrix A using the Cholesky factorization 
+*  A = U**H*U or A = L*L**H computed by CPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H, as computed by CPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPOTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Upper', 'Conjugate transpose', 'Non-unit',
+     $               N, NRHS, ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL CTRSM( 'Left', 'Lower', 'Conjugate transpose', 'Non-unit',
+     $               N, NRHS, ONE, A, LDA, B, LDB )
+      END IF
+*
+      RETURN
+*
+*     End of CPOTRS
+*
+      END
diff --git a/libcruft/lapack/cptsv.f b/libcruft/lapack/cptsv.f
new file mode 100644
index 0000000..dd2dbd5
--- /dev/null
+++ b/libcruft/lapack/cptsv.f
@@ -0,0 +1,100 @@
+      SUBROUTINE CPTSV( N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * )
+      COMPLEX            B( LDB, * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPTSV computes the solution to a complex system of linear equations
+*  A*X = B, where A is an N-by-N Hermitian positive definite tridiagonal
+*  matrix, and X and B are N-by-NRHS matrices.
+*
+*  A is factored as A = L*D*L**H, and the factored form of A is then
+*  used to solve the system of equations.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the factorization A = L*D*L**H.
+*
+*  E       (input/output) COMPLEX array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L**H factorization of
+*          A.  E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U**H*D*U factorization of A.
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the solution has not been
+*                computed.  The factorization has not been completed
+*                unless i = N.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           CPTTRF, CPTTRS, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPTSV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      CALL CPTTRF( N, D, E, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL CPTTRS( 'Lower', N, NRHS, D, E, B, LDB, INFO )
+      END IF
+      RETURN
+*
+*     End of CPTSV
+*
+      END
diff --git a/libcruft/lapack/cpttrf.f b/libcruft/lapack/cpttrf.f
new file mode 100644
index 0000000..e02daf9
--- /dev/null
+++ b/libcruft/lapack/cpttrf.f
@@ -0,0 +1,168 @@
+      SUBROUTINE CPTTRF( N, D, E, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * )
+      COMPLEX            E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPTTRF computes the L*D*L' factorization of a complex Hermitian
+*  positive definite tridiagonal matrix A.  The factorization may also
+*  be regarded as having the form A = U'*D*U.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the L*D*L' factorization of A.
+*
+*  E       (input/output) COMPLEX array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L' factorization of A.
+*          E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U'*D*U factorization of A.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite; if k < N, the factorization could not
+*               be completed, while if k = N, the factorization was
+*               completed, but D(N) <= 0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I4
+      REAL               EII, EIR, F, G
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          AIMAG, CMPLX, MOD, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'CPTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      I4 = MOD( N-1, 4 )
+      DO 10 I = 1, I4
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 20
+         END IF
+         EIR = REAL( E( I ) )
+         EII = AIMAG( E( I ) )
+         F = EIR / D( I )
+         G = EII / D( I )
+         E( I ) = CMPLX( F, G )
+         D( I+1 ) = D( I+1 ) - F*EIR - G*EII
+   10 CONTINUE
+*
+      DO 110 I = I4+1, N - 4, 4
+*
+*        Drop out of the loop if d(i) <= 0: the matrix is not positive
+*        definite.
+*
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 20
+         END IF
+*
+*        Solve for e(i) and d(i+1).
+*
+         EIR = REAL( E( I ) )
+         EII = AIMAG( E( I ) )
+         F = EIR / D( I )
+         G = EII / D( I )
+         E( I ) = CMPLX( F, G )
+         D( I+1 ) = D( I+1 ) - F*EIR - G*EII
+*
+         IF( D( I+1 ).LE.ZERO ) THEN
+            INFO = I+1
+            GO TO 20
+         END IF
+*
+*        Solve for e(i+1) and d(i+2).
+*
+         EIR = REAL( E( I+1 ) )
+         EII = AIMAG( E( I+1 ) )
+         F = EIR / D( I+1 )
+         G = EII / D( I+1 )
+         E( I+1 ) = CMPLX( F, G )
+         D( I+2 ) = D( I+2 ) - F*EIR - G*EII
+*
+         IF( D( I+2 ).LE.ZERO ) THEN
+            INFO = I+2
+            GO TO 20
+         END IF
+*
+*        Solve for e(i+2) and d(i+3).
+*
+         EIR = REAL( E( I+2 ) )
+         EII = AIMAG( E( I+2 ) )
+         F = EIR / D( I+2 )
+         G = EII / D( I+2 )
+         E( I+2 ) = CMPLX( F, G )
+         D( I+3 ) = D( I+3 ) - F*EIR - G*EII
+*
+         IF( D( I+3 ).LE.ZERO ) THEN
+            INFO = I+3
+            GO TO 20
+         END IF
+*
+*        Solve for e(i+3) and d(i+4).
+*
+         EIR = REAL( E( I+3 ) )
+         EII = AIMAG( E( I+3 ) )
+         F = EIR / D( I+3 )
+         G = EII / D( I+3 )
+         E( I+3 ) = CMPLX( F, G )
+         D( I+4 ) = D( I+4 ) - F*EIR - G*EII
+  110 CONTINUE
+*
+*     Check d(n) for positive definiteness.
+*
+      IF( D( N ).LE.ZERO )
+     $   INFO = N
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of CPTTRF
+*
+      END
diff --git a/libcruft/lapack/cpttrs.f b/libcruft/lapack/cpttrs.f
new file mode 100644
index 0000000..b875ffa
--- /dev/null
+++ b/libcruft/lapack/cpttrs.f
@@ -0,0 +1,135 @@
+      SUBROUTINE CPTTRS( UPLO, N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * )
+      COMPLEX            B( LDB, * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPTTRS solves a tridiagonal system of the form
+*     A * X = B
+*  using the factorization A = U'*D*U or A = L*D*L' computed by CPTTRF.
+*  D is a diagonal matrix specified in the vector D, U (or L) is a unit
+*  bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
+*  the vector E, and X and B are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the form of the factorization and whether the
+*          vector E is the superdiagonal of the upper bidiagonal factor
+*          U or the subdiagonal of the lower bidiagonal factor L.
+*          = 'U':  A = U'*D*U, E is the superdiagonal of U
+*          = 'L':  A = L*D*L', E is the subdiagonal of L
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) REAL array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          factorization A = U'*D*U or A = L*D*L'.
+*
+*  E       (input) COMPLEX array, dimension (N-1)
+*          If UPLO = 'U', the (n-1) superdiagonal elements of the unit
+*          bidiagonal factor U from the factorization A = U'*D*U.
+*          If UPLO = 'L', the (n-1) subdiagonal elements of the unit
+*          bidiagonal factor L from the factorization A = L*D*L'.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            IUPLO, J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CPTTS2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      UPPER = ( UPLO.EQ.'U' .OR. UPLO.EQ.'u' )
+      IF( .NOT.UPPER .AND. .NOT.( UPLO.EQ.'L' .OR. UPLO.EQ.'l' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CPTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'CPTTRS', UPLO, N, NRHS, -1, -1 ) )
+      END IF
+*
+*     Decode UPLO
+*
+      IF( UPPER ) THEN
+         IUPLO = 1
+      ELSE
+         IUPLO = 0
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL CPTTS2( IUPLO, N, NRHS, D, E, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL CPTTS2( IUPLO, N, JB, D, E, B( 1, J ), LDB )
+   10    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CPTTRS
+*
+      END
diff --git a/libcruft/lapack/cptts2.f b/libcruft/lapack/cptts2.f
new file mode 100644
index 0000000..95d835e
--- /dev/null
+++ b/libcruft/lapack/cptts2.f
@@ -0,0 +1,176 @@
+      SUBROUTINE CPTTS2( IUPLO, N, NRHS, D, E, B, LDB )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IUPLO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * )
+      COMPLEX            B( LDB, * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CPTTS2 solves a tridiagonal system of the form
+*     A * X = B
+*  using the factorization A = U'*D*U or A = L*D*L' computed by CPTTRF.
+*  D is a diagonal matrix specified in the vector D, U (or L) is a unit
+*  bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
+*  the vector E, and X and B are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  IUPLO   (input) INTEGER
+*          Specifies the form of the factorization and whether the
+*          vector E is the superdiagonal of the upper bidiagonal factor
+*          U or the subdiagonal of the lower bidiagonal factor L.
+*          = 1:  A = U'*D*U, E is the superdiagonal of U
+*          = 0:  A = L*D*L', E is the subdiagonal of L
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) REAL array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          factorization A = U'*D*U or A = L*D*L'.
+*
+*  E       (input) COMPLEX array, dimension (N-1)
+*          If IUPLO = 1, the (n-1) superdiagonal elements of the unit
+*          bidiagonal factor U from the factorization A = U'*D*U.
+*          If IUPLO = 0, the (n-1) subdiagonal elements of the unit
+*          bidiagonal factor L from the factorization A = L*D*L'.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 ) THEN
+         IF( N.EQ.1 )
+     $      CALL CSSCAL( NRHS, 1. / D( 1 ), B, LDB )
+         RETURN
+      END IF
+*
+      IF( IUPLO.EQ.1 ) THEN
+*
+*        Solve A * X = B using the factorization A = U'*D*U,
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.2 ) THEN
+            J = 1
+    5       CONTINUE
+*
+*           Solve U' * x = b.
+*
+            DO 10 I = 2, N
+               B( I, J ) = B( I, J ) - B( I-1, J )*CONJG( E( I-1 ) )
+   10       CONTINUE
+*
+*           Solve D * U * x = b.
+*
+            DO 20 I = 1, N
+               B( I, J ) = B( I, J ) / D( I )
+   20       CONTINUE
+            DO 30 I = N - 1, 1, -1
+               B( I, J ) = B( I, J ) - B( I+1, J )*E( I )
+   30       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 5
+            END IF
+         ELSE
+            DO 60 J = 1, NRHS
+*
+*              Solve U' * x = b.
+*
+               DO 40 I = 2, N
+                  B( I, J ) = B( I, J ) - B( I-1, J )*CONJG( E( I-1 ) )
+   40          CONTINUE
+*
+*              Solve D * U * x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               DO 50 I = N - 1, 1, -1
+                  B( I, J ) = B( I, J ) / D( I ) - B( I+1, J )*E( I )
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      ELSE
+*
+*        Solve A * X = B using the factorization A = L*D*L',
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.2 ) THEN
+            J = 1
+   65       CONTINUE
+*
+*           Solve L * x = b.
+*
+            DO 70 I = 2, N
+               B( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )
+   70       CONTINUE
+*
+*           Solve D * L' * x = b.
+*
+            DO 80 I = 1, N
+               B( I, J ) = B( I, J ) / D( I )
+   80       CONTINUE
+            DO 90 I = N - 1, 1, -1
+               B( I, J ) = B( I, J ) - B( I+1, J )*CONJG( E( I ) )
+   90       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 65
+            END IF
+         ELSE
+            DO 120 J = 1, NRHS
+*
+*              Solve L * x = b.
+*
+               DO 100 I = 2, N
+                  B( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )
+  100          CONTINUE
+*
+*              Solve D * L' * x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               DO 110 I = N - 1, 1, -1
+                  B( I, J ) = B( I, J ) / D( I ) -
+     $                        B( I+1, J )*CONJG( E( I ) )
+  110          CONTINUE
+  120       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CPTTS2
+*
+      END
diff --git a/libcruft/lapack/crot.f b/libcruft/lapack/crot.f
new file mode 100644
index 0000000..fe97369
--- /dev/null
+++ b/libcruft/lapack/crot.f
@@ -0,0 +1,91 @@
+      SUBROUTINE CROT( N, CX, INCX, CY, INCY, C, S )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, INCY, N
+      REAL               C
+      COMPLEX            S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            CX( * ), CY( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CROT   applies a plane rotation, where the cos (C) is real and the
+*  sin (S) is complex, and the vectors CX and CY are complex.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements in the vectors CX and CY.
+*
+*  CX      (input/output) COMPLEX array, dimension (N)
+*          On input, the vector X.
+*          On output, CX is overwritten with C*X + S*Y.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of CY.  INCX <> 0.
+*
+*  CY      (input/output) COMPLEX array, dimension (N)
+*          On input, the vector Y.
+*          On output, CY is overwritten with -CONJG(S)*X + C*Y.
+*
+*  INCY    (input) INTEGER
+*          The increment between successive values of CY.  INCX <> 0.
+*
+*  C       (input) REAL
+*  S       (input) COMPLEX
+*          C and S define a rotation
+*             [  C          S  ]
+*             [ -conjg(S)   C  ]
+*          where C*C + S*CONJG(S) = 1.0.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IX, IY
+      COMPLEX            STEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 .AND. INCY.EQ.1 )
+     $   GO TO 20
+*
+*     Code for unequal increments or equal increments not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF( INCX.LT.0 )
+     $   IX = ( -N+1 )*INCX + 1
+      IF( INCY.LT.0 )
+     $   IY = ( -N+1 )*INCY + 1
+      DO 10 I = 1, N
+         STEMP = C*CX( IX ) + S*CY( IY )
+         CY( IY ) = C*CY( IY ) - CONJG( S )*CX( IX )
+         CX( IX ) = STEMP
+         IX = IX + INCX
+         IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*     Code for both increments equal to 1
+*
+   20 CONTINUE
+      DO 30 I = 1, N
+         STEMP = C*CX( I ) + S*CY( I )
+         CY( I ) = C*CY( I ) - CONJG( S )*CX( I )
+         CX( I ) = STEMP
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/lapack/csrscl.f b/libcruft/lapack/csrscl.f
new file mode 100644
index 0000000..3e7345c
--- /dev/null
+++ b/libcruft/lapack/csrscl.f
@@ -0,0 +1,114 @@
+      SUBROUTINE CSRSCL( N, SA, SX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      REAL               SA
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            SX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CSRSCL multiplies an n-element complex vector x by the real scalar
+*  1/a.  This is done without overflow or underflow as long as
+*  the final result x/a does not overflow or underflow.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of components of the vector x.
+*
+*  SA      (input) REAL
+*          The scalar a which is used to divide each component of x.
+*          SA must be >= 0, or the subroutine will divide by zero.
+*
+*  SX      (input/output) COMPLEX array, dimension
+*                         (1+(N-1)*abs(INCX))
+*          The n-element vector x.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector SX.
+*          > 0:  SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i),     1< i<= n
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      REAL               BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL, SLABAD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Initialize the denominator to SA and the numerator to 1.
+*
+      CDEN = SA
+      CNUM = ONE
+*
+   10 CONTINUE
+      CDEN1 = CDEN*SMLNUM
+      CNUM1 = CNUM / BIGNUM
+      IF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN
+*
+*        Pre-multiply X by SMLNUM if CDEN is large compared to CNUM.
+*
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CDEN = CDEN1
+      ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN
+*
+*        Pre-multiply X by BIGNUM if CDEN is small compared to CNUM.
+*
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CNUM = CNUM1
+      ELSE
+*
+*        Multiply X by CNUM / CDEN and return.
+*
+         MUL = CNUM / CDEN
+         DONE = .TRUE.
+      END IF
+*
+*     Scale the vector X by MUL
+*
+      CALL CSSCAL( N, MUL, SX, INCX )
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of CSRSCL
+*
+      END
diff --git a/libcruft/lapack/csteqr.f b/libcruft/lapack/csteqr.f
new file mode 100644
index 0000000..6e130ea
--- /dev/null
+++ b/libcruft/lapack/csteqr.f
@@ -0,0 +1,503 @@
+      SUBROUTINE CSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPZ
+      INTEGER            INFO, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * ), WORK( * )
+      COMPLEX            Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CSTEQR computes all eigenvalues and, optionally, eigenvectors of a
+*  symmetric tridiagonal matrix using the implicit QL or QR method.
+*  The eigenvectors of a full or band complex Hermitian matrix can also
+*  be found if CHETRD or CHPTRD or CHBTRD has been used to reduce this
+*  matrix to tridiagonal form.
+*
+*  Arguments
+*  =========
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only.
+*          = 'V':  Compute eigenvalues and eigenvectors of the original
+*                  Hermitian matrix.  On entry, Z must contain the
+*                  unitary matrix used to reduce the original matrix
+*                  to tridiagonal form.
+*          = 'I':  Compute eigenvalues and eigenvectors of the
+*                  tridiagonal matrix.  Z is initialized to the identity
+*                  matrix.
+*
+*  N       (input) INTEGER
+*          The order of the matrix.  N >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the diagonal elements of the tridiagonal matrix.
+*          On exit, if INFO = 0, the eigenvalues in ascending order.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix.
+*          On exit, E has been destroyed.
+*
+*  Z       (input/output) COMPLEX array, dimension (LDZ, N)
+*          On entry, if  COMPZ = 'V', then Z contains the unitary
+*          matrix used in the reduction to tridiagonal form.
+*          On exit, if INFO = 0, then if COMPZ = 'V', Z contains the
+*          orthonormal eigenvectors of the original Hermitian matrix,
+*          and if COMPZ = 'I', Z contains the orthonormal eigenvectors
+*          of the symmetric tridiagonal matrix.
+*          If COMPZ = 'N', then Z is not referenced.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1, and if
+*          eigenvectors are desired, then  LDZ >= max(1,N).
+*
+*  WORK    (workspace) REAL array, dimension (max(1,2*N-2))
+*          If COMPZ = 'N', then WORK is not referenced.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm has failed to find all the eigenvalues in
+*                a total of 30*N iterations; if INFO = i, then i
+*                elements of E have not converged to zero; on exit, D
+*                and E contain the elements of a symmetric tridiagonal
+*                matrix which is unitarily similar to the original
+*                matrix.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO, THREE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
+     $                   THREE = 3.0E0 )
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E0, 0.0E0 ),
+     $                   CONE = ( 1.0E0, 0.0E0 ) )
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 30 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
+     $                   LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
+     $                   NM1, NMAXIT
+      REAL               ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
+     $                   S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH, SLANST, SLAPY2
+      EXTERNAL           LSAME, SLAMCH, SLANST, SLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLASET, CLASR, CSWAP, SLAE2, SLAEV2, SLARTG,
+     $                   SLASCL, SLASRT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ICOMPZ = 0
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ICOMPZ = 2
+      ELSE
+         ICOMPZ = -1
+      END IF
+      IF( ICOMPZ.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,
+     $         N ) ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CSTEQR', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( N.EQ.1 ) THEN
+         IF( ICOMPZ.EQ.2 )
+     $      Z( 1, 1 ) = CONE
+         RETURN
+      END IF
+*
+*     Determine the unit roundoff and over/underflow thresholds.
+*
+      EPS = SLAMCH( 'E' )
+      EPS2 = EPS**2
+      SAFMIN = SLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      SSFMAX = SQRT( SAFMAX ) / THREE
+      SSFMIN = SQRT( SAFMIN ) / EPS2
+*
+*     Compute the eigenvalues and eigenvectors of the tridiagonal
+*     matrix.
+*
+      IF( ICOMPZ.EQ.2 )
+     $   CALL CLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
+*
+      NMAXIT = N*MAXIT
+      JTOT = 0
+*
+*     Determine where the matrix splits and choose QL or QR iteration
+*     for each block, according to whether top or bottom diagonal
+*     element is smaller.
+*
+      L1 = 1
+      NM1 = N - 1
+*
+   10 CONTINUE
+      IF( L1.GT.N )
+     $   GO TO 160
+      IF( L1.GT.1 )
+     $   E( L1-1 ) = ZERO
+      IF( L1.LE.NM1 ) THEN
+         DO 20 M = L1, NM1
+            TST = ABS( E( M ) )
+            IF( TST.EQ.ZERO )
+     $         GO TO 30
+            IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
+     $          1 ) ) ) )*EPS ) THEN
+               E( M ) = ZERO
+               GO TO 30
+            END IF
+   20    CONTINUE
+      END IF
+      M = N
+*
+   30 CONTINUE
+      L = L1
+      LSV = L
+      LEND = M
+      LENDSV = LEND
+      L1 = M + 1
+      IF( LEND.EQ.L )
+     $   GO TO 10
+*
+*     Scale submatrix in rows and columns L to LEND
+*
+      ANORM = SLANST( 'I', LEND-L+1, D( L ), E( L ) )
+      ISCALE = 0
+      IF( ANORM.EQ.ZERO )
+     $   GO TO 10
+      IF( ANORM.GT.SSFMAX ) THEN
+         ISCALE = 1
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
+     $                INFO )
+      ELSE IF( ANORM.LT.SSFMIN ) THEN
+         ISCALE = 2
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
+     $                INFO )
+      END IF
+*
+*     Choose between QL and QR iteration
+*
+      IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
+         LEND = LSV
+         L = LENDSV
+      END IF
+*
+      IF( LEND.GT.L ) THEN
+*
+*        QL Iteration
+*
+*        Look for small subdiagonal element.
+*
+   40    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDM1 = LEND - 1
+            DO 50 M = L, LENDM1
+               TST = ABS( E( M ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+
+     $             SAFMIN )GO TO 60
+   50       CONTINUE
+         END IF
+*
+         M = LEND
+*
+   60    CONTINUE
+         IF( M.LT.LEND )
+     $      E( M ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 80
+*
+*        If remaining matrix is 2-by-2, use SLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L+1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL SLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )
+               WORK( L ) = C
+               WORK( N-1+L ) = S
+               CALL CLASR( 'R', 'V', 'B', N, 2, WORK( L ),
+     $                     WORK( N-1+L ), Z( 1, L ), LDZ )
+            ELSE
+               CALL SLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )
+            END IF
+            D( L ) = RT1
+            D( L+1 ) = RT2
+            E( L ) = ZERO
+            L = L + 2
+            IF( L.LE.LEND )
+     $         GO TO 40
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L+1 )-P ) / ( TWO*E( L ) )
+         R = SLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         MM1 = M - 1
+         DO 70 I = MM1, L, -1
+            F = S*E( I )
+            B = C*E( I )
+            CALL SLARTG( G, F, C, S, R )
+            IF( I.NE.M-1 )
+     $         E( I+1 ) = R
+            G = D( I+1 ) - P
+            R = ( D( I )-G )*S + TWO*C*B
+            P = S*R
+            D( I+1 ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = -S
+            END IF
+*
+   70    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = M - L + 1
+            CALL CLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),
+     $                  Z( 1, L ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( L ) = G
+         GO TO 40
+*
+*        Eigenvalue found.
+*
+   80    CONTINUE
+         D( L ) = P
+*
+         L = L + 1
+         IF( L.LE.LEND )
+     $      GO TO 40
+         GO TO 140
+*
+      ELSE
+*
+*        QR Iteration
+*
+*        Look for small superdiagonal element.
+*
+   90    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDP1 = LEND + 1
+            DO 100 M = L, LENDP1, -1
+               TST = ABS( E( M-1 ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+
+     $             SAFMIN )GO TO 110
+  100       CONTINUE
+         END IF
+*
+         M = LEND
+*
+  110    CONTINUE
+         IF( M.GT.LEND )
+     $      E( M-1 ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 130
+*
+*        If remaining matrix is 2-by-2, use SLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L-1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL SLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )
+               WORK( M ) = C
+               WORK( N-1+M ) = S
+               CALL CLASR( 'R', 'V', 'F', N, 2, WORK( M ),
+     $                     WORK( N-1+M ), Z( 1, L-1 ), LDZ )
+            ELSE
+               CALL SLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )
+            END IF
+            D( L-1 ) = RT1
+            D( L ) = RT2
+            E( L-1 ) = ZERO
+            L = L - 2
+            IF( L.GE.LEND )
+     $         GO TO 90
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )
+         R = SLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         LM1 = L - 1
+         DO 120 I = M, LM1
+            F = S*E( I )
+            B = C*E( I )
+            CALL SLARTG( G, F, C, S, R )
+            IF( I.NE.M )
+     $         E( I-1 ) = R
+            G = D( I ) - P
+            R = ( D( I+1 )-G )*S + TWO*C*B
+            P = S*R
+            D( I ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = S
+            END IF
+*
+  120    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = L - M + 1
+            CALL CLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),
+     $                  Z( 1, M ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( LM1 ) = G
+         GO TO 90
+*
+*        Eigenvalue found.
+*
+  130    CONTINUE
+         D( L ) = P
+*
+         L = L - 1
+         IF( L.GE.LEND )
+     $      GO TO 90
+         GO TO 140
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+  140 CONTINUE
+      IF( ISCALE.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL SLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      ELSE IF( ISCALE.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL SLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      END IF
+*
+*     Check for no convergence to an eigenvalue after a total
+*     of N*MAXIT iterations.
+*
+      IF( JTOT.EQ.NMAXIT ) THEN
+         DO 150 I = 1, N - 1
+            IF( E( I ).NE.ZERO )
+     $         INFO = INFO + 1
+  150    CONTINUE
+         RETURN
+      END IF
+      GO TO 10
+*
+*     Order eigenvalues and eigenvectors.
+*
+  160 CONTINUE
+      IF( ICOMPZ.EQ.0 ) THEN
+*
+*        Use Quick Sort
+*
+         CALL SLASRT( 'I', N, D, INFO )
+*
+      ELSE
+*
+*        Use Selection Sort to minimize swaps of eigenvectors
+*
+         DO 180 II = 2, N
+            I = II - 1
+            K = I
+            P = D( I )
+            DO 170 J = II, N
+               IF( D( J ).LT.P ) THEN
+                  K = J
+                  P = D( J )
+               END IF
+  170       CONTINUE
+            IF( K.NE.I ) THEN
+               D( K ) = D( I )
+               D( I ) = P
+               CALL CSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
+            END IF
+  180    CONTINUE
+      END IF
+      RETURN
+*
+*     End of CSTEQR
+*
+      END
diff --git a/libcruft/lapack/ctgevc.f b/libcruft/lapack/ctgevc.f
new file mode 100644
index 0000000..0f98a65
--- /dev/null
+++ b/libcruft/lapack/ctgevc.f
@@ -0,0 +1,633 @@
+      SUBROUTINE CTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
+     $                   LDVL, VR, LDVR, MM, M, WORK, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDP, LDS, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      REAL               RWORK( * )
+      COMPLEX            P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
+     $                   VR( LDVR, * ), WORK( * )
+*     ..
+*
+*
+*  Purpose
+*  =======
+*
+*  CTGEVC computes some or all of the right and/or left eigenvectors of
+*  a pair of complex matrices (S,P), where S and P are upper triangular.
+*  Matrix pairs of this type are produced by the generalized Schur
+*  factorization of a complex matrix pair (A,B):
+*  
+*     A = Q*S*Z**H,  B = Q*P*Z**H
+*  
+*  as computed by CGGHRD + CHGEQZ.
+*  
+*  The right eigenvector x and the left eigenvector y of (S,P)
+*  corresponding to an eigenvalue w are defined by:
+*  
+*     S*x = w*P*x,  (y**H)*S = w*(y**H)*P,
+*  
+*  where y**H denotes the conjugate tranpose of y.
+*  The eigenvalues are not input to this routine, but are computed
+*  directly from the diagonal elements of S and P.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of (S,P), or the products Z*X and/or Q*Y,
+*  where Z and Q are input matrices.
+*  If Q and Z are the unitary factors from the generalized Schur
+*  factorization of a matrix pair (A,B), then Z*X and Q*Y
+*  are the matrices of right and left eigenvectors of (A,B).
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R': compute right eigenvectors only;
+*          = 'L': compute left eigenvectors only;
+*          = 'B': compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A': compute all right and/or left eigenvectors;
+*          = 'B': compute all right and/or left eigenvectors,
+*                 backtransformed by the matrices in VR and/or VL;
+*          = 'S': compute selected right and/or left eigenvectors,
+*                 specified by the logical array SELECT.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          If HOWMNY='S', SELECT specifies the eigenvectors to be
+*          computed.  The eigenvector corresponding to the j-th
+*          eigenvalue is computed if SELECT(j) = .TRUE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrices S and P.  N >= 0.
+*
+*  S       (input) COMPLEX array, dimension (LDS,N)
+*          The upper triangular matrix S from a generalized Schur
+*          factorization, as computed by CHGEQZ.
+*
+*  LDS     (input) INTEGER
+*          The leading dimension of array S.  LDS >= max(1,N).
+*
+*  P       (input) COMPLEX array, dimension (LDP,N)
+*          The upper triangular matrix P from a generalized Schur
+*          factorization, as computed by CHGEQZ.  P must have real
+*          diagonal elements.
+*
+*  LDP     (input) INTEGER
+*          The leading dimension of array P.  LDP >= max(1,N).
+*
+*  VL      (input/output) COMPLEX array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the unitary matrix Q
+*          of left Schur vectors returned by CHGEQZ).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
+*                      SELECT, stored consecutively in the columns of
+*                      VL, in the same order as their eigenvalues.
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'l' or 'B' or 'b', LDVL >= N.
+*
+*  VR      (input/output) COMPLEX array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Q (usually the unitary matrix Z
+*          of right Schur vectors returned by CHGEQZ).
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
+*          if HOWMNY = 'B', the matrix Z*X;
+*          if HOWMNY = 'S', the right eigenvectors of (S,P) specified by
+*                      SELECT, stored consecutively in the columns of
+*                      VR, in the same order as their eigenvalues.
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B', LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
+*          is set to N.  Each selected eigenvector occupies one column.
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      COMPLEX            CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   CONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            COMPL, COMPR, ILALL, ILBACK, ILBBAD, ILCOMP,
+     $                   LSA, LSB
+      INTEGER            I, IBEG, IEIG, IEND, IHWMNY, IM, ISIDE, ISRC,
+     $                   J, JE, JR
+      REAL               ACOEFA, ACOEFF, ANORM, ASCALE, BCOEFA, BIG,
+     $                   BIGNUM, BNORM, BSCALE, DMIN, SAFMIN, SBETA,
+     $                   SCALE, SMALL, TEMP, ULP, XMAX
+      COMPLEX            BCOEFF, CA, CB, D, SALPHA, SUM, SUMA, SUMB, X
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH
+      COMPLEX            CLADIV
+      EXTERNAL           LSAME, SLAMCH, CLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CGEMV, SLABAD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               ABS1
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      IF( LSAME( HOWMNY, 'A' ) ) THEN
+         IHWMNY = 1
+         ILALL = .TRUE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
+         IHWMNY = 2
+         ILALL = .FALSE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
+         IHWMNY = 3
+         ILALL = .TRUE.
+         ILBACK = .TRUE.
+      ELSE
+         IHWMNY = -1
+      END IF
+*
+      IF( LSAME( SIDE, 'R' ) ) THEN
+         ISIDE = 1
+         COMPL = .FALSE.
+         COMPR = .TRUE.
+      ELSE IF( LSAME( SIDE, 'L' ) ) THEN
+         ISIDE = 2
+         COMPL = .TRUE.
+         COMPR = .FALSE.
+      ELSE IF( LSAME( SIDE, 'B' ) ) THEN
+         ISIDE = 3
+         COMPL = .TRUE.
+         COMPR = .TRUE.
+      ELSE
+         ISIDE = -1
+      END IF
+*
+      INFO = 0
+      IF( ISIDE.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( IHWMNY.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Count the number of eigenvectors
+*
+      IF( .NOT.ILALL ) THEN
+         IM = 0
+         DO 10 J = 1, N
+            IF( SELECT( J ) )
+     $         IM = IM + 1
+   10    CONTINUE
+      ELSE
+         IM = N
+      END IF
+*
+*     Check diagonal of B
+*
+      ILBBAD = .FALSE.
+      DO 20 J = 1, N
+         IF( AIMAG( P( J, J ) ).NE.ZERO )
+     $      ILBBAD = .TRUE.
+   20 CONTINUE
+*
+      IF( ILBBAD ) THEN
+         INFO = -7
+      ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
+         INFO = -10
+      ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
+         INFO = -12
+      ELSE IF( MM.LT.IM ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      M = IM
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Machine Constants
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      BIG = ONE / SAFMIN
+      CALL SLABAD( SAFMIN, BIG )
+      ULP = SLAMCH( 'Epsilon' )*SLAMCH( 'Base' )
+      SMALL = SAFMIN*N / ULP
+      BIG = ONE / SMALL
+      BIGNUM = ONE / ( SAFMIN*N )
+*
+*     Compute the 1-norm of each column of the strictly upper triangular
+*     part of A and B to check for possible overflow in the triangular
+*     solver.
+*
+      ANORM = ABS1( S( 1, 1 ) )
+      BNORM = ABS1( P( 1, 1 ) )
+      RWORK( 1 ) = ZERO
+      RWORK( N+1 ) = ZERO
+      DO 40 J = 2, N
+         RWORK( J ) = ZERO
+         RWORK( N+J ) = ZERO
+         DO 30 I = 1, J - 1
+            RWORK( J ) = RWORK( J ) + ABS1( S( I, J ) )
+            RWORK( N+J ) = RWORK( N+J ) + ABS1( P( I, J ) )
+   30    CONTINUE
+         ANORM = MAX( ANORM, RWORK( J )+ABS1( S( J, J ) ) )
+         BNORM = MAX( BNORM, RWORK( N+J )+ABS1( P( J, J ) ) )
+   40 CONTINUE
+*
+      ASCALE = ONE / MAX( ANORM, SAFMIN )
+      BSCALE = ONE / MAX( BNORM, SAFMIN )
+*
+*     Left eigenvectors
+*
+      IF( COMPL ) THEN
+         IEIG = 0
+*
+*        Main loop over eigenvalues
+*
+         DO 140 JE = 1, N
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( ILCOMP ) THEN
+               IEIG = IEIG + 1
+*
+               IF( ABS1( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( REAL( P( JE, JE ) ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- return unit eigenvector
+*
+                  DO 50 JR = 1, N
+                     VL( JR, IEIG ) = CZERO
+   50             CONTINUE
+                  VL( IEIG, IEIG ) = CONE
+                  GO TO 140
+               END IF
+*
+*              Non-singular eigenvalue:
+*              Compute coefficients  a  and  b  in
+*                   H
+*                 y  ( a A - b B ) = 0
+*
+               TEMP = ONE / MAX( ABS1( S( JE, JE ) )*ASCALE,
+     $                ABS( REAL( P( JE, JE ) ) )*BSCALE, SAFMIN )
+               SALPHA = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*REAL( P( JE, JE ) ) )*BSCALE
+               ACOEFF = SBETA*ASCALE
+               BCOEFF = SALPHA*BSCALE
+*
+*              Scale to avoid underflow
+*
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEFF ).LT.SMALL
+               LSB = ABS1( SALPHA ).GE.SAFMIN .AND. ABS1( BCOEFF ).LT.
+     $               SMALL
+*
+               SCALE = ONE
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS1( SALPHA ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEFF ),
+     $                    ABS1( BCOEFF ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEFF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEFF = SCALE*ACOEFF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFF = BSCALE*( SCALE*SALPHA )
+                  ELSE
+                     BCOEFF = SCALE*BCOEFF
+                  END IF
+               END IF
+*
+               ACOEFA = ABS( ACOEFF )
+               BCOEFA = ABS1( BCOEFF )
+               XMAX = ONE
+               DO 60 JR = 1, N
+                  WORK( JR ) = CZERO
+   60          CONTINUE
+               WORK( JE ) = CONE
+               DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*                                              H
+*              Triangular solve of  (a A - b B)  y = 0
+*
+*                                      H
+*              (rowwise in  (a A - b B) , or columnwise in a A - b B)
+*
+               DO 100 J = JE + 1, N
+*
+*                 Compute
+*                       j-1
+*                 SUM = sum  conjg( a*S(k,j) - b*P(k,j) )*x(k)
+*                       k=je
+*                 (Scale if necessary)
+*
+                  TEMP = ONE / XMAX
+                  IF( ACOEFA*RWORK( J )+BCOEFA*RWORK( N+J ).GT.BIGNUM*
+     $                TEMP ) THEN
+                     DO 70 JR = JE, J - 1
+                        WORK( JR ) = TEMP*WORK( JR )
+   70                CONTINUE
+                     XMAX = ONE
+                  END IF
+                  SUMA = CZERO
+                  SUMB = CZERO
+*
+                  DO 80 JR = JE, J - 1
+                     SUMA = SUMA + CONJG( S( JR, J ) )*WORK( JR )
+                     SUMB = SUMB + CONJG( P( JR, J ) )*WORK( JR )
+   80             CONTINUE
+                  SUM = ACOEFF*SUMA - CONJG( BCOEFF )*SUMB
+*
+*                 Form x(j) = - SUM / conjg( a*S(j,j) - b*P(j,j) )
+*
+*                 with scaling and perturbation of the denominator
+*
+                  D = CONJG( ACOEFF*S( J, J )-BCOEFF*P( J, J ) )
+                  IF( ABS1( D ).LE.DMIN )
+     $               D = CMPLX( DMIN )
+*
+                  IF( ABS1( D ).LT.ONE ) THEN
+                     IF( ABS1( SUM ).GE.BIGNUM*ABS1( D ) ) THEN
+                        TEMP = ONE / ABS1( SUM )
+                        DO 90 JR = JE, J - 1
+                           WORK( JR ) = TEMP*WORK( JR )
+   90                   CONTINUE
+                        XMAX = TEMP*XMAX
+                        SUM = TEMP*SUM
+                     END IF
+                  END IF
+                  WORK( J ) = CLADIV( -SUM, D )
+                  XMAX = MAX( XMAX, ABS1( WORK( J ) ) )
+  100          CONTINUE
+*
+*              Back transform eigenvector if HOWMNY='B'.
+*
+               IF( ILBACK ) THEN
+                  CALL CGEMV( 'N', N, N+1-JE, CONE, VL( 1, JE ), LDVL,
+     $                        WORK( JE ), 1, CZERO, WORK( N+1 ), 1 )
+                  ISRC = 2
+                  IBEG = 1
+               ELSE
+                  ISRC = 1
+                  IBEG = JE
+               END IF
+*
+*              Copy and scale eigenvector into column of VL
+*
+               XMAX = ZERO
+               DO 110 JR = IBEG, N
+                  XMAX = MAX( XMAX, ABS1( WORK( ( ISRC-1 )*N+JR ) ) )
+  110          CONTINUE
+*
+               IF( XMAX.GT.SAFMIN ) THEN
+                  TEMP = ONE / XMAX
+                  DO 120 JR = IBEG, N
+                     VL( JR, IEIG ) = TEMP*WORK( ( ISRC-1 )*N+JR )
+  120             CONTINUE
+               ELSE
+                  IBEG = N + 1
+               END IF
+*
+               DO 130 JR = 1, IBEG - 1
+                  VL( JR, IEIG ) = CZERO
+  130          CONTINUE
+*
+            END IF
+  140    CONTINUE
+      END IF
+*
+*     Right eigenvectors
+*
+      IF( COMPR ) THEN
+         IEIG = IM + 1
+*
+*        Main loop over eigenvalues
+*
+         DO 250 JE = N, 1, -1
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( ILCOMP ) THEN
+               IEIG = IEIG - 1
+*
+               IF( ABS1( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( REAL( P( JE, JE ) ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- return unit eigenvector
+*
+                  DO 150 JR = 1, N
+                     VR( JR, IEIG ) = CZERO
+  150             CONTINUE
+                  VR( IEIG, IEIG ) = CONE
+                  GO TO 250
+               END IF
+*
+*              Non-singular eigenvalue:
+*              Compute coefficients  a  and  b  in
+*
+*              ( a A - b B ) x  = 0
+*
+               TEMP = ONE / MAX( ABS1( S( JE, JE ) )*ASCALE,
+     $                ABS( REAL( P( JE, JE ) ) )*BSCALE, SAFMIN )
+               SALPHA = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*REAL( P( JE, JE ) ) )*BSCALE
+               ACOEFF = SBETA*ASCALE
+               BCOEFF = SALPHA*BSCALE
+*
+*              Scale to avoid underflow
+*
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEFF ).LT.SMALL
+               LSB = ABS1( SALPHA ).GE.SAFMIN .AND. ABS1( BCOEFF ).LT.
+     $               SMALL
+*
+               SCALE = ONE
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS1( SALPHA ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEFF ),
+     $                    ABS1( BCOEFF ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEFF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEFF = SCALE*ACOEFF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFF = BSCALE*( SCALE*SALPHA )
+                  ELSE
+                     BCOEFF = SCALE*BCOEFF
+                  END IF
+               END IF
+*
+               ACOEFA = ABS( ACOEFF )
+               BCOEFA = ABS1( BCOEFF )
+               XMAX = ONE
+               DO 160 JR = 1, N
+                  WORK( JR ) = CZERO
+  160          CONTINUE
+               WORK( JE ) = CONE
+               DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*              Triangular solve of  (a A - b B) x = 0  (columnwise)
+*
+*              WORK(1:j-1) contains sums w,
+*              WORK(j+1:JE) contains x
+*
+               DO 170 JR = 1, JE - 1
+                  WORK( JR ) = ACOEFF*S( JR, JE ) - BCOEFF*P( JR, JE )
+  170          CONTINUE
+               WORK( JE ) = CONE
+*
+               DO 210 J = JE - 1, 1, -1
+*
+*                 Form x(j) := - w(j) / d
+*                 with scaling and perturbation of the denominator
+*
+                  D = ACOEFF*S( J, J ) - BCOEFF*P( J, J )
+                  IF( ABS1( D ).LE.DMIN )
+     $               D = CMPLX( DMIN )
+*
+                  IF( ABS1( D ).LT.ONE ) THEN
+                     IF( ABS1( WORK( J ) ).GE.BIGNUM*ABS1( D ) ) THEN
+                        TEMP = ONE / ABS1( WORK( J ) )
+                        DO 180 JR = 1, JE
+                           WORK( JR ) = TEMP*WORK( JR )
+  180                   CONTINUE
+                     END IF
+                  END IF
+*
+                  WORK( J ) = CLADIV( -WORK( J ), D )
+*
+                  IF( J.GT.1 ) THEN
+*
+*                    w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
+*
+                     IF( ABS1( WORK( J ) ).GT.ONE ) THEN
+                        TEMP = ONE / ABS1( WORK( J ) )
+                        IF( ACOEFA*RWORK( J )+BCOEFA*RWORK( N+J ).GE.
+     $                      BIGNUM*TEMP ) THEN
+                           DO 190 JR = 1, JE
+                              WORK( JR ) = TEMP*WORK( JR )
+  190                      CONTINUE
+                        END IF
+                     END IF
+*
+                     CA = ACOEFF*WORK( J )
+                     CB = BCOEFF*WORK( J )
+                     DO 200 JR = 1, J - 1
+                        WORK( JR ) = WORK( JR ) + CA*S( JR, J ) -
+     $                               CB*P( JR, J )
+  200                CONTINUE
+                  END IF
+  210          CONTINUE
+*
+*              Back transform eigenvector if HOWMNY='B'.
+*
+               IF( ILBACK ) THEN
+                  CALL CGEMV( 'N', N, JE, CONE, VR, LDVR, WORK, 1,
+     $                        CZERO, WORK( N+1 ), 1 )
+                  ISRC = 2
+                  IEND = N
+               ELSE
+                  ISRC = 1
+                  IEND = JE
+               END IF
+*
+*              Copy and scale eigenvector into column of VR
+*
+               XMAX = ZERO
+               DO 220 JR = 1, IEND
+                  XMAX = MAX( XMAX, ABS1( WORK( ( ISRC-1 )*N+JR ) ) )
+  220          CONTINUE
+*
+               IF( XMAX.GT.SAFMIN ) THEN
+                  TEMP = ONE / XMAX
+                  DO 230 JR = 1, IEND
+                     VR( JR, IEIG ) = TEMP*WORK( ( ISRC-1 )*N+JR )
+  230             CONTINUE
+               ELSE
+                  IEND = 0
+               END IF
+*
+               DO 240 JR = IEND + 1, N
+                  VR( JR, IEIG ) = CZERO
+  240          CONTINUE
+*
+            END IF
+  250    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CTGEVC
+*
+      END
diff --git a/libcruft/lapack/ctrcon.f b/libcruft/lapack/ctrcon.f
new file mode 100644
index 0000000..388db1c
--- /dev/null
+++ b/libcruft/lapack/ctrcon.f
@@ -0,0 +1,204 @@
+      SUBROUTINE CTRCON( NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK,
+     $                   RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            INFO, LDA, N
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      REAL               RWORK( * )
+      COMPLEX            A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRCON estimates the reciprocal of the condition number of a
+*  triangular matrix A, in either the 1-norm or the infinity-norm.
+*
+*  The norm of A is computed and an estimate is obtained for
+*  norm(inv(A)), then the reciprocal of the condition number is
+*  computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, ONENRM, UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      REAL               AINVNM, ANORM, SCALE, SMLNUM, XNORM
+      COMPLEX            ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               CLANTR, SLAMCH
+      EXTERNAL           LSAME, ICAMAX, CLANTR, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACN2, CLATRS, CSRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, MAX, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTRCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      END IF
+*
+      RCOND = ZERO
+      SMLNUM = SLAMCH( 'Safe minimum' )*REAL( MAX( 1, N ) )
+*
+*     Compute the norm of the triangular matrix A.
+*
+      ANORM = CLANTR( NORM, UPLO, DIAG, N, N, A, LDA, RWORK )
+*
+*     Continue only if ANORM > 0.
+*
+      IF( ANORM.GT.ZERO ) THEN
+*
+*        Estimate the norm of the inverse of A.
+*
+         AINVNM = ZERO
+         NORMIN = 'N'
+         IF( ONENRM ) THEN
+            KASE1 = 1
+         ELSE
+            KASE1 = 2
+         END IF
+         KASE = 0
+   10    CONTINUE
+         CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.KASE1 ) THEN
+*
+*              Multiply by inv(A).
+*
+               CALL CLATRS( UPLO, 'No transpose', DIAG, NORMIN, N, A,
+     $                      LDA, WORK, SCALE, RWORK, INFO )
+            ELSE
+*
+*              Multiply by inv(A').
+*
+               CALL CLATRS( UPLO, 'Conjugate transpose', DIAG, NORMIN,
+     $                      N, A, LDA, WORK, SCALE, RWORK, INFO )
+            END IF
+            NORMIN = 'Y'
+*
+*           Multiply by 1/SCALE if doing so will not cause overflow.
+*
+            IF( SCALE.NE.ONE ) THEN
+               IX = ICAMAX( N, WORK, 1 )
+               XNORM = CABS1( WORK( IX ) )
+               IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )
+     $            GO TO 20
+               CALL CSRSCL( N, SCALE, WORK, 1 )
+            END IF
+            GO TO 10
+         END IF
+*
+*        Compute the estimate of the reciprocal condition number.
+*
+         IF( AINVNM.NE.ZERO )
+     $      RCOND = ( ONE / ANORM ) / AINVNM
+      END IF
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of CTRCON
+*
+      END
diff --git a/libcruft/lapack/ctrevc.f b/libcruft/lapack/ctrevc.f
new file mode 100644
index 0000000..bfc8011
--- /dev/null
+++ b/libcruft/lapack/ctrevc.f
@@ -0,0 +1,386 @@
+      SUBROUTINE CTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
+     $                   LDVR, MM, M, WORK, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      REAL               RWORK( * )
+      COMPLEX            T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTREVC computes some or all of the right and/or left eigenvectors of
+*  a complex upper triangular matrix T.
+*  Matrices of this type are produced by the Schur factorization of
+*  a complex general matrix:  A = Q*T*Q**H, as computed by CHSEQR.
+*  
+*  The right eigenvector x and the left eigenvector y of T corresponding
+*  to an eigenvalue w are defined by:
+*  
+*               T*x = w*x,     (y**H)*T = w*(y**H)
+*  
+*  where y**H denotes the conjugate transpose of the vector y.
+*  The eigenvalues are not input to this routine, but are read directly
+*  from the diagonal of T.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*  input matrix.  If Q is the unitary factor that reduces a matrix A to
+*  Schur form T, then Q*X and Q*Y are the matrices of right and left
+*  eigenvectors of A.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  compute right eigenvectors only;
+*          = 'L':  compute left eigenvectors only;
+*          = 'B':  compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A':  compute all right and/or left eigenvectors;
+*          = 'B':  compute all right and/or left eigenvectors,
+*                  backtransformed using the matrices supplied in
+*                  VR and/or VL;
+*          = 'S':  compute selected right and/or left eigenvectors,
+*                  as indicated by the logical array SELECT.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*          computed.
+*          The eigenvector corresponding to the j-th eigenvalue is
+*          computed if SELECT(j) = .TRUE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) COMPLEX array, dimension (LDT,N)
+*          The upper triangular matrix T.  T is modified, but restored
+*          on exit.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  VL      (input/output) COMPLEX array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*          Schur vectors returned by CHSEQR).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VL, in the same order as their
+*                           eigenvalues.
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'B', LDVL >= N.
+*
+*  VR      (input/output) COMPLEX array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*          Schur vectors returned by CHSEQR).
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*X;
+*          if HOWMNY = 'S', the right eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VR, in the same order as their
+*                           eigenvalues.
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B'; LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
+*          is set to N.  Each selected eigenvector occupies one
+*          column.
+*
+*  WORK    (workspace) COMPLEX array, dimension (2*N)
+*
+*  RWORK   (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The algorithm used in this program is basically backward (forward)
+*  substitution, with scaling to make the the code robust against
+*  possible overflow.
+*
+*  Each eigenvector is normalized so that the element of largest
+*  magnitude has magnitude 1; here the magnitude of a complex number
+*  (x,y) is taken to be |x| + |y|.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      COMPLEX            CMZERO, CMONE
+      PARAMETER          ( CMZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   CMONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, OVER, RIGHTV, SOMEV
+      INTEGER            I, II, IS, J, K, KI
+      REAL               OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
+      COMPLEX            CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ICAMAX
+      REAL               SCASUM, SLAMCH
+      EXTERNAL           LSAME, ICAMAX, SCASUM, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CCOPY, CGEMV, CLATRS, CSSCAL, SLABAD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, MAX, REAL
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV = LSAME( HOWMNY, 'A' )
+      OVER = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+*     Set M to the number of columns required to store the selected
+*     eigenvectors.
+*
+      IF( SOMEV ) THEN
+         M = 0
+         DO 10 J = 1, N
+            IF( SELECT( J ) )
+     $         M = M + 1
+   10    CONTINUE
+      ELSE
+         M = N
+      END IF
+*
+      INFO = 0
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE IF( MM.LT.M ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTREVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Set the constants to control overflow.
+*
+      UNFL = SLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL SLABAD( UNFL, OVFL )
+      ULP = SLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+*
+*     Store the diagonal elements of T in working array WORK.
+*
+      DO 20 I = 1, N
+         WORK( I+N ) = T( I, I )
+   20 CONTINUE
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      RWORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         RWORK( J ) = SCASUM( J-1, T( 1, J ), 1 )
+   30 CONTINUE
+*
+      IF( RIGHTV ) THEN
+*
+*        Compute right eigenvectors.
+*
+         IS = M
+         DO 80 KI = N, 1, -1
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 80
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+            WORK( 1 ) = CMONE
+*
+*           Form right-hand side.
+*
+            DO 40 K = 1, KI - 1
+               WORK( K ) = -T( K, KI )
+   40       CONTINUE
+*
+*           Solve the triangular system:
+*              (T(1:KI-1,1:KI-1) - T(KI,KI))*X = SCALE*WORK.
+*
+            DO 50 K = 1, KI - 1
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+   50       CONTINUE
+*
+            IF( KI.GT.1 ) THEN
+               CALL CLATRS( 'Upper', 'No transpose', 'Non-unit', 'Y',
+     $                      KI-1, T, LDT, WORK( 1 ), SCALE, RWORK,
+     $                      INFO )
+               WORK( KI ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VR and normalize.
+*
+            IF( .NOT.OVER ) THEN
+               CALL CCOPY( KI, WORK( 1 ), 1, VR( 1, IS ), 1 )
+*
+               II = ICAMAX( KI, VR( 1, IS ), 1 )
+               REMAX = ONE / CABS1( VR( II, IS ) )
+               CALL CSSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+               DO 60 K = KI + 1, N
+                  VR( K, IS ) = CMZERO
+   60          CONTINUE
+            ELSE
+               IF( KI.GT.1 )
+     $            CALL CGEMV( 'N', N, KI-1, CMONE, VR, LDVR, WORK( 1 ),
+     $                        1, CMPLX( SCALE ), VR( 1, KI ), 1 )
+*
+               II = ICAMAX( N, VR( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VR( II, KI ) )
+               CALL CSSCAL( N, REMAX, VR( 1, KI ), 1 )
+            END IF
+*
+*           Set back the original diagonal elements of T.
+*
+            DO 70 K = 1, KI - 1
+               T( K, K ) = WORK( K+N )
+   70       CONTINUE
+*
+            IS = IS - 1
+   80    CONTINUE
+      END IF
+*
+      IF( LEFTV ) THEN
+*
+*        Compute left eigenvectors.
+*
+         IS = 1
+         DO 130 KI = 1, N
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 130
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+            WORK( N ) = CMONE
+*
+*           Form right-hand side.
+*
+            DO 90 K = KI + 1, N
+               WORK( K ) = -CONJG( T( KI, K ) )
+   90       CONTINUE
+*
+*           Solve the triangular system:
+*              (T(KI+1:N,KI+1:N) - T(KI,KI))'*X = SCALE*WORK.
+*
+            DO 100 K = KI + 1, N
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+  100       CONTINUE
+*
+            IF( KI.LT.N ) THEN
+               CALL CLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                      'Y', N-KI, T( KI+1, KI+1 ), LDT,
+     $                      WORK( KI+1 ), SCALE, RWORK, INFO )
+               WORK( KI ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VL and normalize.
+*
+            IF( .NOT.OVER ) THEN
+               CALL CCOPY( N-KI+1, WORK( KI ), 1, VL( KI, IS ), 1 )
+*
+               II = ICAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+               REMAX = ONE / CABS1( VL( II, IS ) )
+               CALL CSSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+               DO 110 K = 1, KI - 1
+                  VL( K, IS ) = CMZERO
+  110          CONTINUE
+            ELSE
+               IF( KI.LT.N )
+     $            CALL CGEMV( 'N', N, N-KI, CMONE, VL( 1, KI+1 ), LDVL,
+     $                        WORK( KI+1 ), 1, CMPLX( SCALE ),
+     $                        VL( 1, KI ), 1 )
+*
+               II = ICAMAX( N, VL( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VL( II, KI ) )
+               CALL CSSCAL( N, REMAX, VL( 1, KI ), 1 )
+            END IF
+*
+*           Set back the original diagonal elements of T.
+*
+            DO 120 K = KI + 1, N
+               T( K, K ) = WORK( K+N )
+  120       CONTINUE
+*
+            IS = IS + 1
+  130    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CTREVC
+*
+      END
diff --git a/libcruft/lapack/ctrexc.f b/libcruft/lapack/ctrexc.f
new file mode 100644
index 0000000..c6a450d
--- /dev/null
+++ b/libcruft/lapack/ctrexc.f
@@ -0,0 +1,161 @@
+      SUBROUTINE CTREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ
+      INTEGER            IFST, ILST, INFO, LDQ, LDT, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            Q( LDQ, * ), T( LDT, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTREXC reorders the Schur factorization of a complex matrix
+*  A = Q*T*Q**H, so that the diagonal element of T with row index IFST
+*  is moved to row ILST.
+*
+*  The Schur form T is reordered by a unitary similarity transformation
+*  Z**H*T*Z, and optionally the matrix Q of Schur vectors is updated by
+*  postmultplying it with Z.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V':  update the matrix Q of Schur vectors;
+*          = 'N':  do not update Q.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) COMPLEX array, dimension (LDT,N)
+*          On entry, the upper triangular matrix T.
+*          On exit, the reordered upper triangular matrix.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) COMPLEX array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          unitary transformation matrix Z which reorders T.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= max(1,N).
+*
+*  IFST    (input) INTEGER
+*  ILST    (input) INTEGER
+*          Specify the reordering of the diagonal elements of T:
+*          The element with row index IFST is moved to row ILST by a
+*          sequence of transpositions between adjacent elements.
+*          1 <= IFST <= N; 1 <= ILST <= N.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            WANTQ
+      INTEGER            K, M1, M2, M3
+      REAL               CS
+      COMPLEX            SN, T11, T22, TEMP
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARTG, CROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters.
+*
+      INFO = 0
+      WANTQ = LSAME( COMPQ, 'V' )
+      IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -6
+      ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THEN
+         INFO = -7
+      ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTREXC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.1 .OR. IFST.EQ.ILST )
+     $   RETURN
+*
+      IF( IFST.LT.ILST ) THEN
+*
+*        Move the IFST-th diagonal element forward down the diagonal.
+*
+         M1 = 0
+         M2 = -1
+         M3 = 1
+      ELSE
+*
+*        Move the IFST-th diagonal element backward up the diagonal.
+*
+         M1 = -1
+         M2 = 0
+         M3 = -1
+      END IF
+*
+      DO 10 K = IFST + M1, ILST + M2, M3
+*
+*        Interchange the k-th and (k+1)-th diagonal elements.
+*
+         T11 = T( K, K )
+         T22 = T( K+1, K+1 )
+*
+*        Determine the transformation to perform the interchange.
+*
+         CALL CLARTG( T( K, K+1 ), T22-T11, CS, SN, TEMP )
+*
+*        Apply transformation to the matrix T.
+*
+         IF( K+2.LE.N )
+     $      CALL CROT( N-K-1, T( K, K+2 ), LDT, T( K+1, K+2 ), LDT, CS,
+     $                 SN )
+         CALL CROT( K-1, T( 1, K ), 1, T( 1, K+1 ), 1, CS, CONJG( SN ) )
+*
+         T( K, K ) = T22
+         T( K+1, K+1 ) = T11
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL CROT( N, Q( 1, K ), 1, Q( 1, K+1 ), 1, CS,
+     $                 CONJG( SN ) )
+         END IF
+*
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of CTREXC
+*
+      END
diff --git a/libcruft/lapack/ctrsen.f b/libcruft/lapack/ctrsen.f
new file mode 100644
index 0000000..085a651
--- /dev/null
+++ b/libcruft/lapack/ctrsen.f
@@ -0,0 +1,359 @@
+      SUBROUTINE CTRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, W, M, S,
+     $                   SEP, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, JOB
+      INTEGER            INFO, LDQ, LDT, LWORK, M, N
+      REAL               S, SEP
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      COMPLEX            Q( LDQ, * ), T( LDT, * ), W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRSEN reorders the Schur factorization of a complex matrix
+*  A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in
+*  the leading positions on the diagonal of the upper triangular matrix
+*  T, and the leading columns of Q form an orthonormal basis of the
+*  corresponding right invariant subspace.
+*
+*  Optionally the routine computes the reciprocal condition numbers of
+*  the cluster of eigenvalues and/or the invariant subspace.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies whether condition numbers are required for the
+*          cluster of eigenvalues (S) or the invariant subspace (SEP):
+*          = 'N': none;
+*          = 'E': for eigenvalues only (S);
+*          = 'V': for invariant subspace only (SEP);
+*          = 'B': for both eigenvalues and invariant subspace (S and
+*                 SEP).
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V': update the matrix Q of Schur vectors;
+*          = 'N': do not update Q.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          SELECT specifies the eigenvalues in the selected cluster. To
+*          select the j-th eigenvalue, SELECT(j) must be set to .TRUE..
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) COMPLEX array, dimension (LDT,N)
+*          On entry, the upper triangular matrix T.
+*          On exit, T is overwritten by the reordered matrix T, with the
+*          selected eigenvalues as the leading diagonal elements.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) COMPLEX array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          unitary transformation matrix which reorders T; the leading M
+*          columns of Q form an orthonormal basis for the specified
+*          invariant subspace.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= 1; and if COMPQ = 'V', LDQ >= N.
+*
+*  W       (output) COMPLEX array, dimension (N)
+*          The reordered eigenvalues of T, in the same order as they
+*          appear on the diagonal of T.
+*
+*  M       (output) INTEGER
+*          The dimension of the specified invariant subspace.
+*          0 <= M <= N.
+*
+*  S       (output) REAL
+*          If JOB = 'E' or 'B', S is a lower bound on the reciprocal
+*          condition number for the selected cluster of eigenvalues.
+*          S cannot underestimate the true reciprocal condition number
+*          by more than a factor of sqrt(N). If M = 0 or N, S = 1.
+*          If JOB = 'N' or 'V', S is not referenced.
+*
+*  SEP     (output) REAL
+*          If JOB = 'V' or 'B', SEP is the estimated reciprocal
+*          condition number of the specified invariant subspace. If
+*          M = 0 or N, SEP = norm(T).
+*          If JOB = 'N' or 'E', SEP is not referenced.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If JOB = 'N', LWORK >= 1;
+*          if JOB = 'E', LWORK = max(1,M*(N-M));
+*          if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  CTRSEN first collects the selected eigenvalues by computing a unitary
+*  transformation Z to move them to the top left corner of T. In other
+*  words, the selected eigenvalues are the eigenvalues of T11 in:
+*
+*                Z'*T*Z = ( T11 T12 ) n1
+*                         (  0  T22 ) n2
+*                            n1  n2
+*
+*  where N = n1+n2 and Z' means the conjugate transpose of Z. The first
+*  n1 columns of Z span the specified invariant subspace of T.
+*
+*  If T has been obtained from the Schur factorization of a matrix
+*  A = Q*T*Q', then the reordered Schur factorization of A is given by
+*  A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span the
+*  corresponding invariant subspace of A.
+*
+*  The reciprocal condition number of the average of the eigenvalues of
+*  T11 may be returned in S. S lies between 0 (very badly conditioned)
+*  and 1 (very well conditioned). It is computed as follows. First we
+*  compute R so that
+*
+*                         P = ( I  R ) n1
+*                             ( 0  0 ) n2
+*                               n1 n2
+*
+*  is the projector on the invariant subspace associated with T11.
+*  R is the solution of the Sylvester equation:
+*
+*                        T11*R - R*T22 = T12.
+*
+*  Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote
+*  the two-norm of M. Then S is computed as the lower bound
+*
+*                      (1 + F-norm(R)**2)**(-1/2)
+*
+*  on the reciprocal of 2-norm(P), the true reciprocal condition number.
+*  S cannot underestimate 1 / 2-norm(P) by more than a factor of
+*  sqrt(N).
+*
+*  An approximate error bound for the computed average of the
+*  eigenvalues of T11 is
+*
+*                         EPS * norm(T) / S
+*
+*  where EPS is the machine precision.
+*
+*  The reciprocal condition number of the right invariant subspace
+*  spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP.
+*  SEP is defined as the separation of T11 and T22:
+*
+*                     sep( T11, T22 ) = sigma-min( C )
+*
+*  where sigma-min(C) is the smallest singular value of the
+*  n1*n2-by-n1*n2 matrix
+*
+*     C  = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )
+*
+*  I(m) is an m by m identity matrix, and kprod denotes the Kronecker
+*  product. We estimate sigma-min(C) by the reciprocal of an estimate of
+*  the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C)
+*  cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2).
+*
+*  When SEP is small, small changes in T can cause large changes in
+*  the invariant subspace. An approximate bound on the maximum angular
+*  error in the computed right invariant subspace is
+*
+*                      EPS * norm(T) / SEP
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WANTBH, WANTQ, WANTS, WANTSP
+      INTEGER            IERR, K, KASE, KS, LWMIN, N1, N2, NN
+      REAL               EST, RNORM, SCALE
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+      REAL               RWORK( 1 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               CLANGE
+      EXTERNAL           LSAME, CLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACN2, CLACPY, CTREXC, CTRSYL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters.
+*
+      WANTBH = LSAME( JOB, 'B' )
+      WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
+      WANTSP = LSAME( JOB, 'V' ) .OR. WANTBH
+      WANTQ = LSAME( COMPQ, 'V' )
+*
+*     Set M to the number of selected eigenvalues.
+*
+      M = 0
+      DO 10 K = 1, N
+         IF( SELECT( K ) )
+     $      M = M + 1
+   10 CONTINUE
+*
+      N1 = M
+      N2 = N - M
+      NN = N1*N2
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      IF( WANTSP ) THEN
+         LWMIN = MAX( 1, 2*NN )
+      ELSE IF( LSAME( JOB, 'N' ) ) THEN
+         LWMIN = 1
+      ELSE IF( LSAME( JOB, 'E' ) ) THEN
+         LWMIN = MAX( 1, NN )
+      END IF
+*
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.WANTS .AND. .NOT.WANTSP )
+     $     THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
+         INFO = -14
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         WORK( 1 ) = LWMIN
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTRSEN', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.N .OR. M.EQ.0 ) THEN
+         IF( WANTS )
+     $      S = ONE
+         IF( WANTSP )
+     $      SEP = CLANGE( '1', N, N, T, LDT, RWORK )
+         GO TO 40
+      END IF
+*
+*     Collect the selected eigenvalues at the top left corner of T.
+*
+      KS = 0
+      DO 20 K = 1, N
+         IF( SELECT( K ) ) THEN
+            KS = KS + 1
+*
+*           Swap the K-th eigenvalue to position KS.
+*
+            IF( K.NE.KS )
+     $         CALL CTREXC( COMPQ, N, T, LDT, Q, LDQ, K, KS, IERR )
+         END IF
+   20 CONTINUE
+*
+      IF( WANTS ) THEN
+*
+*        Solve the Sylvester equation for R:
+*
+*           T11*R - R*T22 = scale*T12
+*
+         CALL CLACPY( 'F', N1, N2, T( 1, N1+1 ), LDT, WORK, N1 )
+         CALL CTRSYL( 'N', 'N', -1, N1, N2, T, LDT, T( N1+1, N1+1 ),
+     $                LDT, WORK, N1, SCALE, IERR )
+*
+*        Estimate the reciprocal of the condition number of the cluster
+*        of eigenvalues.
+*
+         RNORM = CLANGE( 'F', N1, N2, WORK, N1, RWORK )
+         IF( RNORM.EQ.ZERO ) THEN
+            S = ONE
+         ELSE
+            S = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*
+     $          SQRT( RNORM ) )
+         END IF
+      END IF
+*
+      IF( WANTSP ) THEN
+*
+*        Estimate sep(T11,T22).
+*
+         EST = ZERO
+         KASE = 0
+   30    CONTINUE
+         CALL CLACN2( NN, WORK( NN+1 ), WORK, EST, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.1 ) THEN
+*
+*              Solve T11*R - R*T22 = scale*X.
+*
+               CALL CTRSYL( 'N', 'N', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            ELSE
+*
+*              Solve T11'*R - R*T22' = scale*X.
+*
+               CALL CTRSYL( 'C', 'C', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            END IF
+            GO TO 30
+         END IF
+*
+         SEP = SCALE / EST
+      END IF
+*
+   40 CONTINUE
+*
+*     Copy reordered eigenvalues to W.
+*
+      DO 50 K = 1, N
+         W( K ) = T( K, K )
+   50 CONTINUE
+*
+      WORK( 1 ) = LWMIN
+*
+      RETURN
+*
+*     End of CTRSEN
+*
+      END
diff --git a/libcruft/lapack/ctrsyl.f b/libcruft/lapack/ctrsyl.f
new file mode 100644
index 0000000..6f0137e
--- /dev/null
+++ b/libcruft/lapack/ctrsyl.f
@@ -0,0 +1,365 @@
+      SUBROUTINE CTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
+     $                   LDC, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANA, TRANB
+      INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
+      REAL               SCALE
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRSYL solves the complex Sylvester matrix equation:
+*
+*     op(A)*X + X*op(B) = scale*C or
+*     op(A)*X - X*op(B) = scale*C,
+*
+*  where op(A) = A or A**H, and A and B are both upper triangular. A is
+*  M-by-M and B is N-by-N; the right hand side C and the solution X are
+*  M-by-N; and scale is an output scale factor, set <= 1 to avoid
+*  overflow in X.
+*
+*  Arguments
+*  =========
+*
+*  TRANA   (input) CHARACTER*1
+*          Specifies the option op(A):
+*          = 'N': op(A) = A    (No transpose)
+*          = 'C': op(A) = A**H (Conjugate transpose)
+*
+*  TRANB   (input) CHARACTER*1
+*          Specifies the option op(B):
+*          = 'N': op(B) = B    (No transpose)
+*          = 'C': op(B) = B**H (Conjugate transpose)
+*
+*  ISGN    (input) INTEGER
+*          Specifies the sign in the equation:
+*          = +1: solve op(A)*X + X*op(B) = scale*C
+*          = -1: solve op(A)*X - X*op(B) = scale*C
+*
+*  M       (input) INTEGER
+*          The order of the matrix A, and the number of rows in the
+*          matrices X and C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B, and the number of columns in the
+*          matrices X and C. N >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,M)
+*          The upper triangular matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input) COMPLEX array, dimension (LDB,N)
+*          The upper triangular matrix B.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N right hand side matrix C.
+*          On exit, C is overwritten by the solution matrix X.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M)
+*
+*  SCALE   (output) REAL
+*          The scale factor, scale, set <= 1 to avoid overflow in X.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1: A and B have common or very close eigenvalues; perturbed
+*               values were used to solve the equation (but the matrices
+*               A and B are unchanged).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRNA, NOTRNB
+      INTEGER            J, K, L
+      REAL               BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
+     $                   SMLNUM
+      COMPLEX            A11, SUML, SUMR, VEC, X11
+*     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               CLANGE, SLAMCH
+      COMPLEX            CDOTC, CDOTU, CLADIV
+      EXTERNAL           LSAME, CLANGE, SLAMCH, CDOTC, CDOTU, CLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSSCAL, SLABAD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test input parameters
+*
+      NOTRNA = LSAME( TRANA, 'N' )
+      NOTRNB = LSAME( TRANB, 'N' )
+*
+      INFO = 0
+      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTRSYL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Set constants to control overflow
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM*REAL( M*N ) / EPS
+      BIGNUM = ONE / SMLNUM
+      SMIN = MAX( SMLNUM, EPS*CLANGE( 'M', M, M, A, LDA, DUM ),
+     $       EPS*CLANGE( 'M', N, N, B, LDB, DUM ) )
+      SCALE = ONE
+      SGN = ISGN
+*
+      IF( NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-left corner column by column by
+*
+*            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                    M                        L-1
+*          R(K,L) = SUM [A(K,I)*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)].
+*                  I=K+1                      J=1
+*
+         DO 30 L = 1, N
+            DO 20 K = M, 1, -1
+*
+               SUML = CDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
+     $                C( MIN( K+1, M ), L ), 1 )
+               SUMR = CDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
+               VEC = C( K, L ) - ( SUML+SGN*SUMR )
+*
+               SCALOC = ONE
+               A11 = A( K, K ) + SGN*B( L, L )
+               DA11 = ABS( REAL( A11 ) ) + ABS( AIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( REAL( VEC ) ) + ABS( AIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+               X11 = CLADIV( VEC*CMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 10 J = 1, N
+                     CALL CSSCAL( M, SCALOC, C( 1, J ), 1 )
+   10             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+   20       CONTINUE
+   30    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A' *X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        upper-left corner column by column by
+*
+*            A'(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                   K-1                         L-1
+*          R(K,L) = SUM [A'(I,K)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)]
+*                   I=1                         J=1
+*
+         DO 60 L = 1, N
+            DO 50 K = 1, M
+*
+               SUML = CDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
+               SUMR = CDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
+               VEC = C( K, L ) - ( SUML+SGN*SUMR )
+*
+               SCALOC = ONE
+               A11 = CONJG( A( K, K ) ) + SGN*B( L, L )
+               DA11 = ABS( REAL( A11 ) ) + ABS( AIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( REAL( VEC ) ) + ABS( AIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+*
+               X11 = CLADIV( VEC*CMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 40 J = 1, N
+                     CALL CSSCAL( M, SCALOC, C( 1, J ), 1 )
+   40             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+   50       CONTINUE
+   60    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A'*X + ISGN*X*B' = C.
+*
+*        The (K,L)th block of X is determined starting from
+*        upper-right corner column by column by
+*
+*            A'(K,K)*X(K,L) + ISGN*X(K,L)*B'(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                    K-1
+*           R(K,L) = SUM [A'(I,K)*X(I,L)] +
+*                    I=1
+*                           N
+*                     ISGN*SUM [X(K,J)*B'(L,J)].
+*                          J=L+1
+*
+         DO 90 L = N, 1, -1
+            DO 80 K = 1, M
+*
+               SUML = CDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
+               SUMR = CDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
+     $                B( L, MIN( L+1, N ) ), LDB )
+               VEC = C( K, L ) - ( SUML+SGN*CONJG( SUMR ) )
+*
+               SCALOC = ONE
+               A11 = CONJG( A( K, K )+SGN*B( L, L ) )
+               DA11 = ABS( REAL( A11 ) ) + ABS( AIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( REAL( VEC ) ) + ABS( AIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+*
+               X11 = CLADIV( VEC*CMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 70 J = 1, N
+                     CALL CSSCAL( M, SCALOC, C( 1, J ), 1 )
+   70             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+   80       CONTINUE
+   90    CONTINUE
+*
+      ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B' = C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-left corner column by column by
+*
+*           A(K,K)*X(K,L) + ISGN*X(K,L)*B'(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                    M                          N
+*          R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B'(L,J)]
+*                  I=K+1                      J=L+1
+*
+         DO 120 L = N, 1, -1
+            DO 110 K = M, 1, -1
+*
+               SUML = CDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
+     $                C( MIN( K+1, M ), L ), 1 )
+               SUMR = CDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
+     $                B( L, MIN( L+1, N ) ), LDB )
+               VEC = C( K, L ) - ( SUML+SGN*CONJG( SUMR ) )
+*
+               SCALOC = ONE
+               A11 = A( K, K ) + SGN*CONJG( B( L, L ) )
+               DA11 = ABS( REAL( A11 ) ) + ABS( AIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( REAL( VEC ) ) + ABS( AIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+*
+               X11 = CLADIV( VEC*CMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 100 J = 1, N
+                     CALL CSSCAL( M, SCALOC, C( 1, J ), 1 )
+  100             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+  110       CONTINUE
+  120    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of CTRSYL
+*
+      END
diff --git a/libcruft/lapack/ctrti2.f b/libcruft/lapack/ctrti2.f
new file mode 100644
index 0000000..f9aa324
--- /dev/null
+++ b/libcruft/lapack/ctrti2.f
@@ -0,0 +1,146 @@
+      SUBROUTINE CTRTI2( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRTI2 computes the inverse of a complex upper or lower triangular
+*  matrix.
+*
+*  This is the Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading n by n upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J
+      COMPLEX            AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CSCAL, CTRMV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTRTI2', -INFO )
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Compute inverse of upper triangular matrix.
+*
+         DO 10 J = 1, N
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+*
+*           Compute elements 1:j-1 of j-th column.
+*
+            CALL CTRMV( 'Upper', 'No transpose', DIAG, J-1, A, LDA,
+     $                  A( 1, J ), 1 )
+            CALL CSCAL( J-1, AJJ, A( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Compute inverse of lower triangular matrix.
+*
+         DO 20 J = N, 1, -1
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+            IF( J.LT.N ) THEN
+*
+*              Compute elements j+1:n of j-th column.
+*
+               CALL CTRMV( 'Lower', 'No transpose', DIAG, N-J,
+     $                     A( J+1, J+1 ), LDA, A( J+1, J ), 1 )
+               CALL CSCAL( N-J, AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CTRTI2
+*
+      END
diff --git a/libcruft/lapack/ctrtri.f b/libcruft/lapack/ctrtri.f
new file mode 100644
index 0000000..ffd2f6f
--- /dev/null
+++ b/libcruft/lapack/ctrtri.f
@@ -0,0 +1,177 @@
+      SUBROUTINE CTRTRI( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRTRI computes the inverse of a complex upper or lower triangular
+*  matrix A.
+*
+*  This is the Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, A(i,i) is exactly zero.  The triangular
+*               matrix is singular and its inverse can not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J, JB, NB, NN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CTRMM, CTRSM, CTRTI2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTRTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity if non-unit.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+         INFO = 0
+      END IF
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'CTRTRI', UPLO // DIAG, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL CTRTI2( UPLO, DIAG, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute inverse of upper triangular matrix
+*
+            DO 20 J = 1, N, NB
+               JB = MIN( NB, N-J+1 )
+*
+*              Compute rows 1:j-1 of current block column
+*
+               CALL CTRMM( 'Left', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, ONE, A, LDA, A( 1, J ), LDA )
+               CALL CTRSM( 'Right', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, -ONE, A( J, J ), LDA, A( 1, J ), LDA )
+*
+*              Compute inverse of current diagonal block
+*
+               CALL CTRTI2( 'Upper', DIAG, JB, A( J, J ), LDA, INFO )
+   20       CONTINUE
+         ELSE
+*
+*           Compute inverse of lower triangular matrix
+*
+            NN = ( ( N-1 ) / NB )*NB + 1
+            DO 30 J = NN, 1, -NB
+               JB = MIN( NB, N-J+1 )
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute rows j+jb:n of current block column
+*
+                  CALL CTRMM( 'Left', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, ONE, A( J+JB, J+JB ), LDA,
+     $                        A( J+JB, J ), LDA )
+                  CALL CTRSM( 'Right', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, -ONE, A( J, J ), LDA,
+     $                        A( J+JB, J ), LDA )
+               END IF
+*
+*              Compute inverse of current diagonal block
+*
+               CALL CTRTI2( 'Lower', DIAG, JB, A( J, J ), LDA, INFO )
+   30       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRTRI
+*
+      END
diff --git a/libcruft/lapack/ctrtrs.f b/libcruft/lapack/ctrtrs.f
new file mode 100644
index 0000000..fbb45d5
--- /dev/null
+++ b/libcruft/lapack/ctrtrs.f
@@ -0,0 +1,148 @@
+      SUBROUTINE CTRTRS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, TRANS, UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTRTRS solves a triangular system of the form
+*
+*     A * X = B,  A**T * X = B,  or  A**H * X = B,
+*
+*  where A is a triangular matrix of order N, and B is an N-by-NRHS
+*  matrix.  A check is made to verify that A is nonsingular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, if INFO = 0, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, the i-th diagonal element of A is zero,
+*               indicating that the matrix is singular and the solutions
+*               X have not been computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.
+     $         LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTRTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+      END IF
+      INFO = 0
+*
+*     Solve A * x = b,  A**T * x = b,  or  A**H * x = b.
+*
+      CALL CTRSM( 'Left', UPLO, TRANS, DIAG, N, NRHS, ONE, A, LDA, B,
+     $            LDB )
+*
+      RETURN
+*
+*     End of CTRTRS
+*
+      END
diff --git a/libcruft/lapack/ctzrzf.f b/libcruft/lapack/ctzrzf.f
new file mode 100644
index 0000000..156b994
--- /dev/null
+++ b/libcruft/lapack/ctzrzf.f
@@ -0,0 +1,246 @@
+      SUBROUTINE CTZRZF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CTZRZF reduces the M-by-N ( M<=N ) complex upper trapezoidal matrix A
+*  to upper triangular form by means of unitary transformations.
+*
+*  The upper trapezoidal matrix A is factored as
+*
+*     A = ( R  0 ) * Z,
+*
+*  where Z is an N-by-N unitary matrix and R is an M-by-M upper
+*  triangular matrix.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= M.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements M+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          unitary matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an ( n - m ) element vector.
+*  tau and z( k ) are chosen to annihilate the elements of the kth row
+*  of X.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A, such that the elements of z( k ) are
+*  in  a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IWS, KI, KK, LDWORK, LWKOPT, M1, MU, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARZB, CLARZT, CLATRZ, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. M.EQ.N ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.
+*
+            NB = ILAENV( 1, 'CGERQF', ' ', M, N, -1, -1 )
+            LWKOPT = M*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+            INFO = -7
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTZRZF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 1
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.M ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'CGERQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.M ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'CGERQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.M .AND. NX.LT.M ) THEN
+*
+*        Use blocked code initially.
+*        The last kk rows are handled by the block method.
+*
+         M1 = MIN( M+1, N )
+         KI = ( ( M-NX-1 ) / NB )*NB
+         KK = MIN( M, KI+NB )
+*
+         DO 20 I = M - KK + KI + 1, M - KK + 1, -NB
+            IB = MIN( M-I+1, NB )
+*
+*           Compute the TZ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL CLATRZ( IB, N-I+1, N-M, A( I, I ), LDA, TAU( I ),
+     $                   WORK )
+            IF( I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL CLARZT( 'Backward', 'Rowwise', N-M, IB, A( I, M1 ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:i-1,i:n) from the right
+*
+               CALL CLARZB( 'Right', 'No transpose', 'Backward',
+     $                      'Rowwise', I-1, N-I+1, IB, N-M, A( I, M1 ),
+     $                      LDA, WORK, LDWORK, A( 1, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   20    CONTINUE
+         MU = I + NB - 1
+      ELSE
+         MU = M
+      END IF
+*
+*     Use unblocked code to factor the last or only block
+*
+      IF( MU.GT.0 )
+     $   CALL CLATRZ( MU, N, N-M, A, LDA, TAU, WORK )
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of CTZRZF
+*
+      END
diff --git a/libcruft/lapack/cung2l.f b/libcruft/lapack/cung2l.f
new file mode 100644
index 0000000..1a253d6
--- /dev/null
+++ b/libcruft/lapack/cung2l.f
@@ -0,0 +1,128 @@
+      SUBROUTINE CUNG2L( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNG2L generates an m by n complex matrix Q with orthonormal columns,
+*  which is defined as the last n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by CGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by CGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the m-by-n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEQLF.
+*
+*  WORK    (workspace) COMPLEX array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, II, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARF, CSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNG2L', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns 1:n-k to columns of the unit matrix
+*
+      DO 20 J = 1, N - K
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( M-N+J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = 1, K
+         II = N - K + I
+*
+*        Apply H(i) to A(1:m-k+i,1:n-k+i) from the left
+*
+         A( M-N+II, II ) = ONE
+         CALL CLARF( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), A,
+     $               LDA, WORK )
+         CALL CSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 )
+         A( M-N+II, II ) = ONE - TAU( I )
+*
+*        Set A(m-k+i+1:m,n-k+i) to zero
+*
+         DO 30 L = M - N + II + 1, M
+            A( L, II ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of CUNG2L
+*
+      END
diff --git a/libcruft/lapack/cung2r.f b/libcruft/lapack/cung2r.f
new file mode 100644
index 0000000..9edfe64
--- /dev/null
+++ b/libcruft/lapack/cung2r.f
@@ -0,0 +1,130 @@
+      SUBROUTINE CUNG2R( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNG2R generates an m by n complex matrix Q with orthonormal columns,
+*  which is defined as the first n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by CGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by CGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the m by n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEQRF.
+*
+*  WORK    (workspace) COMPLEX array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARF, CSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNG2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns k+1:n to columns of the unit matrix
+*
+      DO 20 J = K + 1, N
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i) to A(i:m,i:n) from the left
+*
+         IF( I.LT.N ) THEN
+            A( I, I ) = ONE
+            CALL CLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                  A( I, I+1 ), LDA, WORK )
+         END IF
+         IF( I.LT.M )
+     $      CALL CSCAL( M-I, -TAU( I ), A( I+1, I ), 1 )
+         A( I, I ) = ONE - TAU( I )
+*
+*        Set A(1:i-1,i) to zero
+*
+         DO 30 L = 1, I - 1
+            A( L, I ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of CUNG2R
+*
+      END
diff --git a/libcruft/lapack/cungbr.f b/libcruft/lapack/cungbr.f
new file mode 100644
index 0000000..8814e85
--- /dev/null
+++ b/libcruft/lapack/cungbr.f
@@ -0,0 +1,245 @@
+      SUBROUTINE CUNGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          VECT
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGBR generates one of the complex unitary matrices Q or P**H
+*  determined by CGEBRD when reducing a complex matrix A to bidiagonal
+*  form: A = Q * B * P**H.  Q and P**H are defined as products of
+*  elementary reflectors H(i) or G(i) respectively.
+*
+*  If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q
+*  is of order M:
+*  if m >= k, Q = H(1) H(2) . . . H(k) and CUNGBR returns the first n
+*  columns of Q, where m >= n >= k;
+*  if m < k, Q = H(1) H(2) . . . H(m-1) and CUNGBR returns Q as an
+*  M-by-M matrix.
+*
+*  If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**H
+*  is of order N:
+*  if k < n, P**H = G(k) . . . G(2) G(1) and CUNGBR returns the first m
+*  rows of P**H, where n >= m >= k;
+*  if k >= n, P**H = G(n-1) . . . G(2) G(1) and CUNGBR returns P**H as
+*  an N-by-N matrix.
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          Specifies whether the matrix Q or the matrix P**H is
+*          required, as defined in the transformation applied by CGEBRD:
+*          = 'Q':  generate Q;
+*          = 'P':  generate P**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q or P**H to be returned.
+*          M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q or P**H to be returned.
+*          N >= 0.
+*          If VECT = 'Q', M >= N >= min(M,K);
+*          if VECT = 'P', N >= M >= min(N,K).
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original M-by-K
+*          matrix reduced by CGEBRD.
+*          If VECT = 'P', the number of rows in the original K-by-N
+*          matrix reduced by CGEBRD.
+*          K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by CGEBRD.
+*          On exit, the M-by-N matrix Q or P**H.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= M.
+*
+*  TAU     (input) COMPLEX array, dimension
+*                                (min(M,K)) if VECT = 'Q'
+*                                (min(N,K)) if VECT = 'P'
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i), which determines Q or P**H, as
+*          returned by CGEBRD in its array argument TAUQ or TAUP.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,min(M,N)).
+*          For optimum performance LWORK >= min(M,N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WANTQ
+      INTEGER            I, IINFO, J, LWKOPT, MN, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CUNGLQ, CUNGQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTQ = LSAME( VECT, 'Q' )
+      MN = MIN( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M,
+     $         K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT.
+     $         MIN( N, K ) ) ) ) THEN
+         INFO = -3
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( WANTQ ) THEN
+            NB = ILAENV( 1, 'CUNGQR', ' ', M, N, K, -1 )
+         ELSE
+            NB = ILAENV( 1, 'CUNGLQ', ' ', M, N, K, -1 )
+         END IF
+         LWKOPT = MAX( 1, MN )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( WANTQ ) THEN
+*
+*        Form Q, determined by a call to CGEBRD to reduce an m-by-k
+*        matrix
+*
+         IF( M.GE.K ) THEN
+*
+*           If m >= k, assume m >= n >= k
+*
+            CALL CUNGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If m < k, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           column to the right, and set the first row and column of Q
+*           to those of the unit matrix
+*
+            DO 20 J = M, 2, -1
+               A( 1, J ) = ZERO
+               DO 10 I = J + 1, M
+                  A( I, J ) = A( I, J-1 )
+   10          CONTINUE
+   20       CONTINUE
+            A( 1, 1 ) = ONE
+            DO 30 I = 2, M
+               A( I, 1 ) = ZERO
+   30       CONTINUE
+            IF( M.GT.1 ) THEN
+*
+*              Form Q(2:m,2:m)
+*
+               CALL CUNGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      ELSE
+*
+*        Form P', determined by a call to CGEBRD to reduce a k-by-n
+*        matrix
+*
+         IF( K.LT.N ) THEN
+*
+*           If k < n, assume k <= m <= n
+*
+            CALL CUNGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If k >= n, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           row downward, and set the first row and column of P' to
+*           those of the unit matrix
+*
+            A( 1, 1 ) = ONE
+            DO 40 I = 2, N
+               A( I, 1 ) = ZERO
+   40       CONTINUE
+            DO 60 J = 2, N
+               DO 50 I = J - 1, 2, -1
+                  A( I, J ) = A( I-1, J )
+   50          CONTINUE
+               A( 1, J ) = ZERO
+   60       CONTINUE
+            IF( N.GT.1 ) THEN
+*
+*              Form P'(2:n,2:n)
+*
+               CALL CUNGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CUNGBR
+*
+      END
diff --git a/libcruft/lapack/cunghr.f b/libcruft/lapack/cunghr.f
new file mode 100644
index 0000000..d938d77
--- /dev/null
+++ b/libcruft/lapack/cunghr.f
@@ -0,0 +1,165 @@
+      SUBROUTINE CUNGHR( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGHR generates a complex unitary matrix Q which is defined as the
+*  product of IHI-ILO elementary reflectors of order N, as returned by
+*  CGEHRD:
+*
+*  Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI must have the same values as in the previous call
+*          of CGEHRD. Q is equal to the unit matrix except in the
+*          submatrix Q(ilo+1:ihi,ilo+1:ihi).
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by CGEHRD.
+*          On exit, the N-by-N unitary matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  TAU     (input) COMPLEX array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEHRD.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= IHI-ILO.
+*          For optimum performance LWORK >= (IHI-ILO)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LWKOPT, NB, NH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CUNGQR, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NH = IHI - ILO
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, NH ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'CUNGQR', ' ', NH, NH, NH, -1 )
+         LWKOPT = MAX( 1, NH )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGHR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Shift the vectors which define the elementary reflectors one
+*     column to the right, and set the first ilo and the last n-ihi
+*     rows and columns to those of the unit matrix
+*
+      DO 40 J = IHI, ILO + 1, -1
+         DO 10 I = 1, J - 1
+            A( I, J ) = ZERO
+   10    CONTINUE
+         DO 20 I = J + 1, IHI
+            A( I, J ) = A( I, J-1 )
+   20    CONTINUE
+         DO 30 I = IHI + 1, N
+            A( I, J ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      DO 60 J = 1, ILO
+         DO 50 I = 1, N
+            A( I, J ) = ZERO
+   50    CONTINUE
+         A( J, J ) = ONE
+   60 CONTINUE
+      DO 80 J = IHI + 1, N
+         DO 70 I = 1, N
+            A( I, J ) = ZERO
+   70    CONTINUE
+         A( J, J ) = ONE
+   80 CONTINUE
+*
+      IF( NH.GT.0 ) THEN
+*
+*        Generate Q(ilo+1:ihi,ilo+1:ihi)
+*
+         CALL CUNGQR( NH, NH, NH, A( ILO+1, ILO+1 ), LDA, TAU( ILO ),
+     $                WORK, LWORK, IINFO )
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CUNGHR
+*
+      END
diff --git a/libcruft/lapack/cungl2.f b/libcruft/lapack/cungl2.f
new file mode 100644
index 0000000..95ce84f
--- /dev/null
+++ b/libcruft/lapack/cungl2.f
@@ -0,0 +1,136 @@
+      SUBROUTINE CUNGL2( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGL2 generates an m-by-n complex matrix Q with orthonormal rows,
+*  which is defined as the first m rows of a product of k elementary
+*  reflectors of order n
+*
+*        Q  =  H(k)' . . . H(2)' H(1)'
+*
+*  as returned by CGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by CGELQF in the first k rows of its array argument A.
+*          On exit, the m by n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGELQF.
+*
+*  WORK    (workspace) COMPLEX array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ),
+     $                   ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACGV, CLARF, CSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGL2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 )
+     $   RETURN
+*
+      IF( K.LT.M ) THEN
+*
+*        Initialise rows k+1:m to rows of the unit matrix
+*
+         DO 20 J = 1, N
+            DO 10 L = K + 1, M
+               A( L, J ) = ZERO
+   10       CONTINUE
+            IF( J.GT.K .AND. J.LE.M )
+     $         A( J, J ) = ONE
+   20    CONTINUE
+      END IF
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i)' to A(i:m,i:n) from the right
+*
+         IF( I.LT.N ) THEN
+            CALL CLACGV( N-I, A( I, I+1 ), LDA )
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+               CALL CLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     CONJG( TAU( I ) ), A( I+1, I ), LDA, WORK )
+            END IF
+            CALL CSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA )
+            CALL CLACGV( N-I, A( I, I+1 ), LDA )
+         END IF
+         A( I, I ) = ONE - CONJG( TAU( I ) )
+*
+*        Set A(i,1:i-1,i) to zero
+*
+         DO 30 L = 1, I - 1
+            A( I, L ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of CUNGL2
+*
+      END
diff --git a/libcruft/lapack/cunglq.f b/libcruft/lapack/cunglq.f
new file mode 100644
index 0000000..ecd5b65
--- /dev/null
+++ b/libcruft/lapack/cunglq.f
@@ -0,0 +1,215 @@
+      SUBROUTINE CUNGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGLQ generates an M-by-N complex matrix Q with orthonormal rows,
+*  which is defined as the first M rows of a product of K elementary
+*  reflectors of order N
+*
+*        Q  =  H(k)' . . . H(2)' H(1)'
+*
+*  as returned by CGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by CGELQF in the first k rows of its array argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGELQF.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit;
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARFB, CLARFT, CUNGL2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'CUNGLQ', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, M )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'CUNGLQ', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'CUNGLQ', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk rows are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(kk+1:m,1:kk) to zero.
+*
+         DO 20 J = 1, KK
+            DO 10 I = KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.M )
+     $   CALL CUNGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL CLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i+ib:m,i:n) from the right
+*
+               CALL CLARFB( 'Right', 'Conjugate transpose', 'Forward',
+     $                      'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),
+     $                      LDA, WORK, LDWORK, A( I+IB, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H' to columns i:n of current block
+*
+            CALL CUNGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set columns 1:i-1 of current block to zero
+*
+            DO 40 J = 1, I - 1
+               DO 30 L = I, I + IB - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CUNGLQ
+*
+      END
diff --git a/libcruft/lapack/cungql.f b/libcruft/lapack/cungql.f
new file mode 100644
index 0000000..8825209
--- /dev/null
+++ b/libcruft/lapack/cungql.f
@@ -0,0 +1,222 @@
+      SUBROUTINE CUNGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGQL generates an M-by-N complex matrix Q with orthonormal columns,
+*  which is defined as the last N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by CGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by CGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEQLF.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT,
+     $                   NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARFB, CLARFT, CUNG2L, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+            NB = ILAENV( 1, 'CUNGQL', ' ', M, N, K, -1 )
+            LWKOPT = N*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGQL', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'CUNGQL', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'CUNGQL', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the first block.
+*        The last kk columns are handled by the block method.
+*
+         KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )
+*
+*        Set A(m-kk+1:m,1:n-kk) to zero.
+*
+         DO 20 J = 1, N - KK
+            DO 10 I = M - KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the first or only block.
+*
+      CALL CUNG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = K - KK + 1, K, NB
+            IB = MIN( NB, K-I+1 )
+            IF( N-K+I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL CLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,
+     $                      A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left
+*
+               CALL CLARFB( 'Left', 'No transpose', 'Backward',
+     $                      'Columnwise', M-K+I+IB-1, N-K+I-1, IB,
+     $                      A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows 1:m-k+i+ib-1 of current block
+*
+            CALL CUNG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA,
+     $                   TAU( I ), WORK, IINFO )
+*
+*           Set rows m-k+i+ib:m of current block to zero
+*
+            DO 40 J = N - K + I, N - K + I + IB - 1
+               DO 30 L = M - K + I + IB, M
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CUNGQL
+*
+      END
diff --git a/libcruft/lapack/cungqr.f b/libcruft/lapack/cungqr.f
new file mode 100644
index 0000000..b233728
--- /dev/null
+++ b/libcruft/lapack/cungqr.f
@@ -0,0 +1,216 @@
+      SUBROUTINE CUNGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGQR generates an M-by-N complex matrix Q with orthonormal columns,
+*  which is defined as the first N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by CGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by CGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEQRF.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARFB, CLARFT, CUNG2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'CUNGQR', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, N )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'CUNGQR', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'CUNGQR', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk columns are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(1:kk,kk+1:n) to zero.
+*
+         DO 20 J = KK + 1, N
+            DO 10 I = 1, KK
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.N )
+     $   CALL CUNG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL CLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i:m,i+ib:n) from the left
+*
+               CALL CLARFB( 'Left', 'No transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows i:m of current block
+*
+            CALL CUNG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set rows 1:i-1 of current block to zero
+*
+            DO 40 J = I, I + IB - 1
+               DO 30 L = 1, I - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of CUNGQR
+*
+      END
diff --git a/libcruft/lapack/cungtr.f b/libcruft/lapack/cungtr.f
new file mode 100644
index 0000000..4d42492
--- /dev/null
+++ b/libcruft/lapack/cungtr.f
@@ -0,0 +1,184 @@
+      SUBROUTINE CUNGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNGTR generates a complex unitary matrix Q which is defined as the
+*  product of n-1 elementary reflectors of order N, as returned by
+*  CHETRD:
+*
+*  if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),
+*
+*  if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U': Upper triangle of A contains elementary reflectors
+*                 from CHETRD;
+*          = 'L': Lower triangle of A contains elementary reflectors
+*                 from CHETRD.
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  A       (input/output) COMPLEX array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by CHETRD.
+*          On exit, the N-by-N unitary matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= N.
+*
+*  TAU     (input) COMPLEX array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CHETRD.
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= N-1.
+*          For optimum performance LWORK >= (N-1)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0E+0, 0.0E+0 ),
+     $                   ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, J, LWKOPT, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CUNGQL, CUNGQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF ( UPPER ) THEN
+           NB = ILAENV( 1, 'CUNGQL', ' ', N-1, N-1, N-1, -1 )
+         ELSE
+           NB = ILAENV( 1, 'CUNGQR', ' ', N-1, N-1, N-1, -1 )
+         END IF
+         LWKOPT = MAX( 1, N-1 )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNGTR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Q was determined by a call to CHETRD with UPLO = 'U'
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the left, and set the last row and column of Q to
+*        those of the unit matrix
+*
+         DO 20 J = 1, N - 1
+            DO 10 I = 1, J - 1
+               A( I, J ) = A( I, J+1 )
+   10       CONTINUE
+            A( N, J ) = ZERO
+   20    CONTINUE
+         DO 30 I = 1, N - 1
+            A( I, N ) = ZERO
+   30    CONTINUE
+         A( N, N ) = ONE
+*
+*        Generate Q(1:n-1,1:n-1)
+*
+         CALL CUNGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+      ELSE
+*
+*        Q was determined by a call to CHETRD with UPLO = 'L'.
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the right, and set the first row and column of Q to
+*        those of the unit matrix
+*
+         DO 50 J = N, 2, -1
+            A( 1, J ) = ZERO
+            DO 40 I = J + 1, N
+               A( I, J ) = A( I, J-1 )
+   40       CONTINUE
+   50    CONTINUE
+         A( 1, 1 ) = ONE
+         DO 60 I = 2, N
+            A( I, 1 ) = ZERO
+   60    CONTINUE
+         IF( N.GT.1 ) THEN
+*
+*           Generate Q(2:n,2:n)
+*
+            CALL CUNGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                   LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CUNGTR
+*
+      END
diff --git a/libcruft/lapack/cunm2r.f b/libcruft/lapack/cunm2r.f
new file mode 100644
index 0000000..d54a1b2
--- /dev/null
+++ b/libcruft/lapack/cunm2r.f
@@ -0,0 +1,201 @@
+      SUBROUTINE CUNM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNM2R overwrites the general complex m-by-n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'C', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'C',
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by CGEQRF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'C': apply Q' (Conjugate transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          CGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEQRF.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      COMPLEX            AII, TAUI
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNM2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         IF( NOTRAN ) THEN
+            TAUI = TAU( I )
+         ELSE
+            TAUI = CONJG( TAU( I ) )
+         END IF
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL CLARF( SIDE, MI, NI, A( I, I ), 1, TAUI, C( IC, JC ), LDC,
+     $               WORK )
+         A( I, I ) = AII
+   10 CONTINUE
+      RETURN
+*
+*     End of CUNM2R
+*
+      END
diff --git a/libcruft/lapack/cunmbr.f b/libcruft/lapack/cunmbr.f
new file mode 100644
index 0000000..6212f12
--- /dev/null
+++ b/libcruft/lapack/cunmbr.f
@@ -0,0 +1,289 @@
+      SUBROUTINE CUNMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,
+     $                   LDC, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS, VECT
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  If VECT = 'Q', CUNMBR overwrites the general complex M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  If VECT = 'P', CUNMBR overwrites the general complex M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      P * C          C * P
+*  TRANS = 'C':      P**H * C       C * P**H
+*
+*  Here Q and P**H are the unitary matrices determined by CGEBRD when
+*  reducing a complex matrix A to bidiagonal form: A = Q * B * P**H. Q
+*  and P**H are defined as products of elementary reflectors H(i) and
+*  G(i) respectively.
+*
+*  Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the
+*  order of the unitary matrix Q or P**H that is applied.
+*
+*  If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:
+*  if nq >= k, Q = H(1) H(2) . . . H(k);
+*  if nq < k, Q = H(1) H(2) . . . H(nq-1).
+*
+*  If VECT = 'P', A is assumed to have been a K-by-NQ matrix:
+*  if k < nq, P = G(1) G(2) . . . G(k);
+*  if k >= nq, P = G(1) G(2) . . . G(nq-1).
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          = 'Q': apply Q or Q**H;
+*          = 'P': apply P or P**H.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q, Q**H, P or P**H from the Left;
+*          = 'R': apply Q, Q**H, P or P**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q or P;
+*          = 'C':  Conjugate transpose, apply Q**H or P**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original
+*          matrix reduced by CGEBRD.
+*          If VECT = 'P', the number of rows in the original
+*          matrix reduced by CGEBRD.
+*          K >= 0.
+*
+*  A       (input) COMPLEX array, dimension
+*                                (LDA,min(nq,K)) if VECT = 'Q'
+*                                (LDA,nq)        if VECT = 'P'
+*          The vectors which define the elementary reflectors H(i) and
+*          G(i), whose products determine the matrices Q and P, as
+*          returned by CGEBRD.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If VECT = 'Q', LDA >= max(1,nq);
+*          if VECT = 'P', LDA >= max(1,min(nq,K)).
+*
+*  TAU     (input) COMPLEX array, dimension (min(nq,K))
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i) which determines Q or P, as returned
+*          by CGEBRD in the array argument TAUQ or TAUP.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q
+*          or P*C or P**H*C or C*P or C*P**H.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M);
+*          if N = 0 or M = 0, LWORK >= 1.
+*          For optimum performance LWORK >= max(1,N*NB) if SIDE = 'L',
+*          and LWORK >= max(1,M*NB) if SIDE = 'R', where NB is the
+*          optimal blocksize. (NB = 0 if M = 0 or N = 0.)
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            APPLYQ, LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CUNMLQ, CUNMQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      APPLYQ = LSAME( VECT, 'Q' )
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q or P and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         NW = 0
+      END IF
+      IF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR.
+     $         ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) )
+     $          THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -13
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( NW.GT.0 ) THEN
+            IF( APPLYQ ) THEN
+               IF( LEFT ) THEN
+                  NB = ILAENV( 1, 'CUNMQR', SIDE // TRANS, M-1, N, M-1,
+     $                         -1 )
+               ELSE
+                  NB = ILAENV( 1, 'CUNMQR', SIDE // TRANS, M, N-1, N-1,
+     $                         -1 )
+               END IF
+            ELSE
+               IF( LEFT ) THEN
+                  NB = ILAENV( 1, 'CUNMLQ', SIDE // TRANS, M-1, N, M-1,
+     $                         -1 )
+               ELSE
+                  NB = ILAENV( 1, 'CUNMLQ', SIDE // TRANS, M, N-1, N-1,
+     $                         -1 )
+               END IF
+            END IF
+            LWKOPT = MAX( 1, NW*NB )
+         ELSE
+            LWKOPT = 1
+         END IF
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNMBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+      IF( APPLYQ ) THEN
+*
+*        Apply Q
+*
+         IF( NQ.GE.K ) THEN
+*
+*           Q was determined by a call to CGEBRD with nq >= k
+*
+            CALL CUNMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           Q was determined by a call to CGEBRD with nq < k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL CUNMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,
+     $                   C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      ELSE
+*
+*        Apply P
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'C'
+         ELSE
+            TRANST = 'N'
+         END IF
+         IF( NQ.GT.K ) THEN
+*
+*           P was determined by a call to CGEBRD with nq > k
+*
+            CALL CUNMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           P was determined by a call to CGEBRD with nq <= k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL CUNMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA,
+     $                   TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CUNMBR
+*
+      END
diff --git a/libcruft/lapack/cunml2.f b/libcruft/lapack/cunml2.f
new file mode 100644
index 0000000..09a5ad0
--- /dev/null
+++ b/libcruft/lapack/cunml2.f
@@ -0,0 +1,205 @@
+      SUBROUTINE CUNML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNML2 overwrites the general complex m-by-n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'C', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'C',
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k)' . . . H(2)' H(1)'
+*
+*  as returned by CGELQF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'C': apply Q' (Conjugate transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          CGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGELQF.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX            ONE
+      PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      COMPLEX            AII, TAUI
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLACGV, CLARF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNML2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. NOTRAN .OR. .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         IF( NOTRAN ) THEN
+            TAUI = CONJG( TAU( I ) )
+         ELSE
+            TAUI = TAU( I )
+         END IF
+         IF( I.LT.NQ )
+     $      CALL CLACGV( NQ-I, A( I, I+1 ), LDA )
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL CLARF( SIDE, MI, NI, A( I, I ), LDA, TAUI, C( IC, JC ),
+     $               LDC, WORK )
+         A( I, I ) = AII
+         IF( I.LT.NQ )
+     $      CALL CLACGV( NQ-I, A( I, I+1 ), LDA )
+   10 CONTINUE
+      RETURN
+*
+*     End of CUNML2
+*
+      END
diff --git a/libcruft/lapack/cunmlq.f b/libcruft/lapack/cunmlq.f
new file mode 100644
index 0000000..cc2018d
--- /dev/null
+++ b/libcruft/lapack/cunmlq.f
@@ -0,0 +1,268 @@
+      SUBROUTINE CUNMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNMLQ overwrites the general complex M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k)' . . . H(2)' H(1)'
+*
+*  as returned by CGELQF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**H from the Left;
+*          = 'R': apply Q or Q**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'C':  Conjugate transpose, apply Q**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          CGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGELQF.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARFB, CLARFT, CUNML2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'CUNMLQ', SIDE // TRANS, M, N, K,
+     $             -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNMLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'CUNMLQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL CUNML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'C'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL CLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL CLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,
+     $                   A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK,
+     $                   LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CUNMLQ
+*
+      END
diff --git a/libcruft/lapack/cunmqr.f b/libcruft/lapack/cunmqr.f
new file mode 100644
index 0000000..152c4c5
--- /dev/null
+++ b/libcruft/lapack/cunmqr.f
@@ -0,0 +1,261 @@
+      SUBROUTINE CUNMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNMQR overwrites the general complex M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by CGEQRF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**H from the Left;
+*          = 'R': apply Q or Q**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'C':  Conjugate transpose, apply Q**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          CGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CGEQRF.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARFB, CLARFT, CUNM2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'CUNMQR', SIDE // TRANS, M, N, K,
+     $        -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNMQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'CUNMQR', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL CUNM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL CLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL CLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI,
+     $                   IB, A( I, I ), LDA, T, LDT, C( IC, JC ), LDC,
+     $                   WORK, LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of CUNMQR
+*
+      END
diff --git a/libcruft/lapack/cunmr3.f b/libcruft/lapack/cunmr3.f
new file mode 100644
index 0000000..3660fba
--- /dev/null
+++ b/libcruft/lapack/cunmr3.f
@@ -0,0 +1,212 @@
+      SUBROUTINE CUNMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNMR3 overwrites the general complex m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'C', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'C',
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by CTZRZF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'C': apply Q' (Conjugate transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) COMPLEX array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          CTZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CTZRZF.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JA, JC, MI, NI, NQ
+      COMPLEX            TAUI
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARZ, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNMR3', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JA = M - L + 1
+         JC = 1
+      ELSE
+         MI = M
+         JA = N - L + 1
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         IF( NOTRAN ) THEN
+            TAUI = TAU( I )
+         ELSE
+            TAUI = CONJG( TAU( I ) )
+         END IF
+         CALL CLARZ( SIDE, MI, NI, L, A( I, JA ), LDA, TAUI,
+     $               C( IC, JC ), LDC, WORK )
+*
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of CUNMR3
+*
+      END
diff --git a/libcruft/lapack/cunmrz.f b/libcruft/lapack/cunmrz.f
new file mode 100644
index 0000000..041043c
--- /dev/null
+++ b/libcruft/lapack/cunmrz.f
@@ -0,0 +1,297 @@
+      SUBROUTINE CUNMRZ( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  CUNMRZ overwrites the general complex M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by CTZRZF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**H from the Left;
+*          = 'R': apply Q or Q**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'C':  Conjugate transpose, apply Q**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) COMPLEX array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          CTZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by CTZRZF.
+*
+*  C       (input/output) COMPLEX array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JA, JC,
+     $                   LDWORK, LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      COMPLEX            T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           CLARZB, CLARZT, CUNMR3, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = MAX( 1, N )
+      ELSE
+         NQ = N
+         NW = MAX( 1, M )
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.  NB may be at most NBMAX, where
+*           NBMAX is used to define the local array T.
+*
+            NB = MIN( NBMAX, ILAENV( 1, 'CUNMRQ', SIDE // TRANS, M, N,
+     $                               K, -1 ) )
+            LWKOPT = NW*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CUNMRZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Determine the block size.  NB may be at most NBMAX, where NBMAX
+*     is used to define the local array T.
+*
+      NB = MIN( NBMAX, ILAENV( 1, 'CUNMRQ', SIDE // TRANS, M, N, K,
+     $     -1 ) )
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'CUNMRQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL CUNMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                WORK, IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+            JA = M - L + 1
+         ELSE
+            MI = M
+            IC = 1
+            JA = N - L + 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'C'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i+ib-1) . . . H(i+1) H(i)
+*
+            CALL CLARZT( 'Backward', 'Rowwise', L, IB, A( I, JA ), LDA,
+     $                   TAU( I ), T, LDT )
+*
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL CLARZB( SIDE, TRANST, 'Backward', 'Rowwise', MI, NI,
+     $                   IB, L, A( I, JA ), LDA, T, LDT, C( IC, JC ),
+     $                   LDC, WORK, LDWORK )
+   10    CONTINUE
+*
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of CUNMRZ
+*
+      END
diff --git a/libcruft/lapack/dbdsqr.f b/libcruft/lapack/dbdsqr.f
new file mode 100644
index 0000000..6024586
--- /dev/null
+++ b/libcruft/lapack/dbdsqr.f
@@ -0,0 +1,742 @@
+      SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
+     $                   LDU, C, LDC, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), D( * ), E( * ), U( LDU, * ),
+     $                   VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DBDSQR computes the singular values and, optionally, the right and/or
+*  left singular vectors from the singular value decomposition (SVD) of
+*  a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
+*  zero-shift QR algorithm.  The SVD of B has the form
+* 
+*     B = Q * S * P**T
+* 
+*  where S is the diagonal matrix of singular values, Q is an orthogonal
+*  matrix of left singular vectors, and P is an orthogonal matrix of
+*  right singular vectors.  If left singular vectors are requested, this
+*  subroutine actually returns U*Q instead of Q, and, if right singular
+*  vectors are requested, this subroutine returns P**T*VT instead of
+*  P**T, for given real input matrices U and VT.  When U and VT are the
+*  orthogonal matrices that reduce a general matrix A to bidiagonal
+*  form:  A = U*B*VT, as computed by DGEBRD, then
+*
+*     A = (U*Q) * S * (P**T*VT)
+*
+*  is the SVD of A.  Optionally, the subroutine may also compute Q**T*C
+*  for a given real input matrix C.
+*
+*  See "Computing  Small Singular Values of Bidiagonal Matrices With
+*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
+*  LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,
+*  no. 5, pp. 873-912, Sept 1990) and
+*  "Accurate singular values and differential qd algorithms," by
+*  B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics
+*  Department, University of California at Berkeley, July 1992
+*  for a detailed description of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  B is upper bidiagonal;
+*          = 'L':  B is lower bidiagonal.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B.  N >= 0.
+*
+*  NCVT    (input) INTEGER
+*          The number of columns of the matrix VT. NCVT >= 0.
+*
+*  NRU     (input) INTEGER
+*          The number of rows of the matrix U. NRU >= 0.
+*
+*  NCC     (input) INTEGER
+*          The number of columns of the matrix C. NCC >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the bidiagonal matrix B.
+*          On exit, if INFO=0, the singular values of B in decreasing
+*          order.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the N-1 offdiagonal elements of the bidiagonal
+*          matrix B. 
+*          On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E
+*          will contain the diagonal and superdiagonal elements of a
+*          bidiagonal matrix orthogonally equivalent to the one given
+*          as input.
+*
+*  VT      (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)
+*          On entry, an N-by-NCVT matrix VT.
+*          On exit, VT is overwritten by P**T * VT.
+*          Not referenced if NCVT = 0.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.
+*          LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.
+*
+*  U       (input/output) DOUBLE PRECISION array, dimension (LDU, N)
+*          On entry, an NRU-by-N matrix U.
+*          On exit, U is overwritten by U * Q.
+*          Not referenced if NRU = 0.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= max(1,NRU).
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)
+*          On entry, an N-by-NCC matrix C.
+*          On exit, C is overwritten by Q**T * C.
+*          Not referenced if NCC = 0.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C.
+*          LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (2*N)
+*          if NCVT = NRU = NCC = 0, (max(1, 4*N)) otherwise
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  If INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm did not converge; D and E contain the
+*                elements of a bidiagonal matrix which is orthogonally
+*                similar to the input matrix B;  if INFO = i, i
+*                elements of E have not converged to zero.
+*
+*  Internal Parameters
+*  ===================
+*
+*  TOLMUL  DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8)))
+*          TOLMUL controls the convergence criterion of the QR loop.
+*          If it is positive, TOLMUL*EPS is the desired relative
+*             precision in the computed singular values.
+*          If it is negative, abs(TOLMUL*EPS*sigma_max) is the
+*             desired absolute accuracy in the computed singular
+*             values (corresponds to relative accuracy
+*             abs(TOLMUL*EPS) in the largest singular value.
+*          abs(TOLMUL) should be between 1 and 1/EPS, and preferably
+*             between 10 (for fast convergence) and .1/EPS
+*             (for there to be some accuracy in the results).
+*          Default is to lose at either one eighth or 2 of the
+*             available decimal digits in each computed singular value
+*             (whichever is smaller).
+*
+*  MAXITR  INTEGER, default = 6
+*          MAXITR controls the maximum number of passes of the
+*          algorithm through its inner loop. The algorithms stops
+*          (and so fails to converge) if the number of passes
+*          through the inner loop exceeds MAXITR*N**2.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   NEGONE
+      PARAMETER          ( NEGONE = -1.0D0 )
+      DOUBLE PRECISION   HNDRTH
+      PARAMETER          ( HNDRTH = 0.01D0 )
+      DOUBLE PRECISION   TEN
+      PARAMETER          ( TEN = 10.0D0 )
+      DOUBLE PRECISION   HNDRD
+      PARAMETER          ( HNDRD = 100.0D0 )
+      DOUBLE PRECISION   MEIGTH
+      PARAMETER          ( MEIGTH = -0.125D0 )
+      INTEGER            MAXITR
+      PARAMETER          ( MAXITR = 6 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, ROTATE
+      INTEGER            I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
+     $                   NM12, NM13, OLDLL, OLDM
+      DOUBLE PRECISION   ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
+     $                   OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
+     $                   SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
+     $                   SN, THRESH, TOL, TOLMUL, UNFL
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARTG, DLAS2, DLASQ1, DLASR, DLASV2, DROT,
+     $                   DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      LOWER = LSAME( UPLO, 'L' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NCVT.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NCC.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
+     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
+         INFO = -9
+      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
+         INFO = -11
+      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
+     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DBDSQR', -INFO )
+         RETURN
+      END IF
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( N.EQ.1 )
+     $   GO TO 160
+*
+*     ROTATE is true if any singular vectors desired, false otherwise
+*
+      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
+*
+*     If no singular vectors desired, use qd algorithm
+*
+      IF( .NOT.ROTATE ) THEN
+         CALL DLASQ1( N, D, E, WORK, INFO )
+         RETURN
+      END IF
+*
+      NM1 = N - 1
+      NM12 = NM1 + NM1
+      NM13 = NM12 + NM1
+      IDIR = 0
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'Epsilon' )
+      UNFL = DLAMCH( 'Safe minimum' )
+*
+*     If matrix lower bidiagonal, rotate to be upper bidiagonal
+*     by applying Givens rotations on the left
+*
+      IF( LOWER ) THEN
+         DO 10 I = 1, N - 1
+            CALL DLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            WORK( I ) = CS
+            WORK( NM1+I ) = SN
+   10    CONTINUE
+*
+*        Update singular vectors if desired
+*
+         IF( NRU.GT.0 )
+     $      CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ), WORK( N ), U,
+     $                  LDU )
+         IF( NCC.GT.0 )
+     $      CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ), WORK( N ), C,
+     $                  LDC )
+      END IF
+*
+*     Compute singular values to relative accuracy TOL
+*     (By setting TOL to be negative, algorithm will compute
+*     singular values to absolute accuracy ABS(TOL)*norm(input matrix))
+*
+      TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
+      TOL = TOLMUL*EPS
+*
+*     Compute approximate maximum, minimum singular values
+*
+      SMAX = ZERO
+      DO 20 I = 1, N
+         SMAX = MAX( SMAX, ABS( D( I ) ) )
+   20 CONTINUE
+      DO 30 I = 1, N - 1
+         SMAX = MAX( SMAX, ABS( E( I ) ) )
+   30 CONTINUE
+      SMINL = ZERO
+      IF( TOL.GE.ZERO ) THEN
+*
+*        Relative accuracy desired
+*
+         SMINOA = ABS( D( 1 ) )
+         IF( SMINOA.EQ.ZERO )
+     $      GO TO 50
+         MU = SMINOA
+         DO 40 I = 2, N
+            MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
+            SMINOA = MIN( SMINOA, MU )
+            IF( SMINOA.EQ.ZERO )
+     $         GO TO 50
+   40    CONTINUE
+   50    CONTINUE
+         SMINOA = SMINOA / SQRT( DBLE( N ) )
+         THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
+      ELSE
+*
+*        Absolute accuracy desired
+*
+         THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
+      END IF
+*
+*     Prepare for main iteration loop for the singular values
+*     (MAXIT is the maximum number of passes through the inner
+*     loop permitted before nonconvergence signalled.)
+*
+      MAXIT = MAXITR*N*N
+      ITER = 0
+      OLDLL = -1
+      OLDM = -1
+*
+*     M points to last element of unconverged part of matrix
+*
+      M = N
+*
+*     Begin main iteration loop
+*
+   60 CONTINUE
+*
+*     Check for convergence or exceeding iteration count
+*
+      IF( M.LE.1 )
+     $   GO TO 160
+      IF( ITER.GT.MAXIT )
+     $   GO TO 200
+*
+*     Find diagonal block of matrix to work on
+*
+      IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
+     $   D( M ) = ZERO
+      SMAX = ABS( D( M ) )
+      SMIN = SMAX
+      DO 70 LLL = 1, M - 1
+         LL = M - LLL
+         ABSS = ABS( D( LL ) )
+         ABSE = ABS( E( LL ) )
+         IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
+     $      D( LL ) = ZERO
+         IF( ABSE.LE.THRESH )
+     $      GO TO 80
+         SMIN = MIN( SMIN, ABSS )
+         SMAX = MAX( SMAX, ABSS, ABSE )
+   70 CONTINUE
+      LL = 0
+      GO TO 90
+   80 CONTINUE
+      E( LL ) = ZERO
+*
+*     Matrix splits since E(LL) = 0
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        Convergence of bottom singular value, return to top of loop
+*
+         M = M - 1
+         GO TO 60
+      END IF
+   90 CONTINUE
+      LL = LL + 1
+*
+*     E(LL) through E(M-1) are nonzero, E(LL-1) is zero
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        2 by 2 block, handle separately
+*
+         CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
+     $                COSR, SINL, COSL )
+         D( M-1 ) = SIGMX
+         E( M-1 ) = ZERO
+         D( M ) = SIGMN
+*
+*        Compute singular vectors, if desired
+*
+         IF( NCVT.GT.0 )
+     $      CALL DROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, COSR,
+     $                 SINR )
+         IF( NRU.GT.0 )
+     $      CALL DROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
+         IF( NCC.GT.0 )
+     $      CALL DROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
+     $                 SINL )
+         M = M - 2
+         GO TO 60
+      END IF
+*
+*     If working on new submatrix, choose shift direction
+*     (from larger end diagonal element towards smaller)
+*
+      IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
+         IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
+*
+*           Chase bulge from top (big end) to bottom (small end)
+*
+            IDIR = 1
+         ELSE
+*
+*           Chase bulge from bottom (big end) to top (small end)
+*
+            IDIR = 2
+         END IF
+      END IF
+*
+*     Apply convergence tests
+*
+      IF( IDIR.EQ.1 ) THEN
+*
+*        Run convergence test in forward direction
+*        First apply standard test to bottom of matrix
+*
+         IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
+            E( M-1 ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion forward
+*
+            MU = ABS( D( LL ) )
+            SMINL = MU
+            DO 100 LLL = LL, M - 1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  100       CONTINUE
+         END IF
+*
+      ELSE
+*
+*        Run convergence test in backward direction
+*        First apply standard test to top of matrix
+*
+         IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
+            E( LL ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion backward
+*
+            MU = ABS( D( M ) )
+            SMINL = MU
+            DO 110 LLL = M - 1, LL, -1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  110       CONTINUE
+         END IF
+      END IF
+      OLDLL = LL
+      OLDM = M
+*
+*     Compute shift.  First, test if shifting would ruin relative
+*     accuracy, and if so set the shift to zero.
+*
+      IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
+     $    MAX( EPS, HNDRTH*TOL ) ) THEN
+*
+*        Use a zero shift to avoid loss of relative accuracy
+*
+         SHIFT = ZERO
+      ELSE
+*
+*        Compute the shift from 2-by-2 block at end of matrix
+*
+         IF( IDIR.EQ.1 ) THEN
+            SLL = ABS( D( LL ) )
+            CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
+         ELSE
+            SLL = ABS( D( M ) )
+            CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
+         END IF
+*
+*        Test if shift negligible, and if so set to zero
+*
+         IF( SLL.GT.ZERO ) THEN
+            IF( ( SHIFT / SLL )**2.LT.EPS )
+     $         SHIFT = ZERO
+         END IF
+      END IF
+*
+*     Increment iteration count
+*
+      ITER = ITER + M - LL
+*
+*     If SHIFT = 0, do simplified QR iteration
+*
+      IF( SHIFT.EQ.ZERO ) THEN
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 120 I = LL, M - 1
+               CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = OLDSN*R
+               CALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
+               WORK( I-LL+1 ) = CS
+               WORK( I-LL+1+NM1 ) = SN
+               WORK( I-LL+1+NM12 ) = OLDCS
+               WORK( I-LL+1+NM13 ) = OLDSN
+  120       CONTINUE
+            H = D( M )*CS
+            D( M ) = H*OLDCS
+            E( M-1 ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),
+     $                     WORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 130 I = M, LL + 1, -1
+               CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
+               IF( I.LT.M )
+     $            E( I ) = OLDSN*R
+               CALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
+               WORK( I-LL ) = CS
+               WORK( I-LL+NM1 ) = -SN
+               WORK( I-LL+NM12 ) = OLDCS
+               WORK( I-LL+NM13 ) = -OLDSN
+  130       CONTINUE
+            H = D( LL )*CS
+            D( LL ) = H*OLDCS
+            E( LL ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),
+     $                     WORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),
+     $                     WORK( N ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+         END IF
+      ELSE
+*
+*        Use nonzero shift
+*
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( LL ) )-SHIFT )*
+     $          ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
+            G = E( LL )
+            DO 140 I = LL, M - 1
+               CALL DLARTG( F, G, COSR, SINR, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = R
+               F = COSR*D( I ) + SINR*E( I )
+               E( I ) = COSR*E( I ) - SINR*D( I )
+               G = SINR*D( I+1 )
+               D( I+1 ) = COSR*D( I+1 )
+               CALL DLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I ) + SINL*D( I+1 )
+               D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
+               IF( I.LT.M-1 ) THEN
+                  G = SINL*E( I+1 )
+                  E( I+1 ) = COSL*E( I+1 )
+               END IF
+               WORK( I-LL+1 ) = COSR
+               WORK( I-LL+1+NM1 ) = SINR
+               WORK( I-LL+1+NM12 ) = COSL
+               WORK( I-LL+1+NM13 ) = SINL
+  140       CONTINUE
+            E( M-1 ) = F
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),
+     $                     WORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
+     $          D( M ) )
+            G = E( M-1 )
+            DO 150 I = M, LL + 1, -1
+               CALL DLARTG( F, G, COSR, SINR, R )
+               IF( I.LT.M )
+     $            E( I ) = R
+               F = COSR*D( I ) + SINR*E( I-1 )
+               E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
+               G = SINR*D( I-1 )
+               D( I-1 ) = COSR*D( I-1 )
+               CALL DLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I-1 ) + SINL*D( I-1 )
+               D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
+               IF( I.GT.LL+1 ) THEN
+                  G = SINL*E( I-2 )
+                  E( I-2 ) = COSL*E( I-2 )
+               END IF
+               WORK( I-LL ) = COSR
+               WORK( I-LL+NM1 ) = -SINR
+               WORK( I-LL+NM12 ) = COSL
+               WORK( I-LL+NM13 ) = -SINL
+  150       CONTINUE
+            E( LL ) = F
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+*
+*           Update singular vectors if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),
+     $                     WORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),
+     $                     WORK( N ), C( LL, 1 ), LDC )
+         END IF
+      END IF
+*
+*     QR iteration finished, go back and check convergence
+*
+      GO TO 60
+*
+*     All singular values converged, so make them positive
+*
+  160 CONTINUE
+      DO 170 I = 1, N
+         IF( D( I ).LT.ZERO ) THEN
+            D( I ) = -D( I )
+*
+*           Change sign of singular vectors, if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL DSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
+         END IF
+  170 CONTINUE
+*
+*     Sort the singular values into decreasing order (insertion sort on
+*     singular values, but only one transposition per singular vector)
+*
+      DO 190 I = 1, N - 1
+*
+*        Scan for smallest D(I)
+*
+         ISUB = 1
+         SMIN = D( 1 )
+         DO 180 J = 2, N + 1 - I
+            IF( D( J ).LE.SMIN ) THEN
+               ISUB = J
+               SMIN = D( J )
+            END IF
+  180    CONTINUE
+         IF( ISUB.NE.N+1-I ) THEN
+*
+*           Swap singular values and vectors
+*
+            D( ISUB ) = D( N+1-I )
+            D( N+1-I ) = SMIN
+            IF( NCVT.GT.0 )
+     $         CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
+     $                     LDVT )
+            IF( NRU.GT.0 )
+     $         CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
+            IF( NCC.GT.0 )
+     $         CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
+         END IF
+  190 CONTINUE
+      GO TO 220
+*
+*     Maximum number of iterations exceeded, failure to converge
+*
+  200 CONTINUE
+      INFO = 0
+      DO 210 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  210 CONTINUE
+  220 CONTINUE
+      RETURN
+*
+*     End of DBDSQR
+*
+      END
diff --git a/libcruft/lapack/dgbcon.f b/libcruft/lapack/dgbcon.f
new file mode 100644
index 0000000..b75d678
--- /dev/null
+++ b/libcruft/lapack/dgbcon.f
@@ -0,0 +1,226 @@
+      SUBROUTINE DGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,
+     $                   WORK, IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call DLACN2 in place of DLACON, 5 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, KL, KU, LDAB, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * ), IWORK( * )
+      DOUBLE PRECISION   AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGBCON estimates the reciprocal of the condition number of a real
+*  general band matrix A, in either the 1-norm or the infinity-norm,
+*  using the LU factorization computed by DGBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input) DOUBLE PRECISION array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by DGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, J, JP, KASE, KASE1, KD, LM
+      DOUBLE PRECISION   AINVNM, SCALE, SMLNUM, T
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DDOT, DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DLACN2, DLATBS, DRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.2*KL+KU+1 ) THEN
+         INFO = -6
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KD = KL + KU + 1
+      LNOTI = KL.GT.0
+      KASE = 0
+   10 CONTINUE
+      CALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            IF( LNOTI ) THEN
+               DO 20 J = 1, N - 1
+                  LM = MIN( KL, N-J )
+                  JP = IPIV( J )
+                  T = WORK( JP )
+                  IF( JP.NE.J ) THEN
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+                  CALL DAXPY( LM, -T, AB( KD+1, J ), 1, WORK( J+1 ), 1 )
+   20          CONTINUE
+            END IF
+*
+*           Multiply by inv(U).
+*
+            CALL DLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),
+     $                   INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL DLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,
+     $                   KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),
+     $                   INFO )
+*
+*           Multiply by inv(L').
+*
+            IF( LNOTI ) THEN
+               DO 30 J = N - 1, 1, -1
+                  LM = MIN( KL, N-J )
+                  WORK( J ) = WORK( J ) - DDOT( LM, AB( KD+1, J ), 1,
+     $                        WORK( J+1 ), 1 )
+                  JP = IPIV( J )
+                  IF( JP.NE.J ) THEN
+                     T = WORK( JP )
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+   30          CONTINUE
+            END IF
+         END IF
+*
+*        Divide X by 1/SCALE if doing so will not cause overflow.
+*
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = IDAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 40
+            CALL DRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of DGBCON
+*
+      END
diff --git a/libcruft/lapack/dgbtf2.f b/libcruft/lapack/dgbtf2.f
new file mode 100644
index 0000000..929829e
--- /dev/null
+++ b/libcruft/lapack/dgbtf2.f
@@ -0,0 +1,202 @@
+      SUBROUTINE DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGBTF2 computes an LU factorization of a real m-by-n band matrix A
+*  using partial pivoting with row interchanges.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U, because of fill-in resulting from the row
+*  interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, JP, JU, KM, KV
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      EXTERNAL           IDAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGER, DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in.
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Gaussian elimination with partial pivoting
+*
+*     Set fill-in elements in columns KU+2 to KV to zero.
+*
+      DO 20 J = KU + 2, MIN( KV, N )
+         DO 10 I = KV - J + 2, KL
+            AB( I, J ) = ZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     JU is the index of the last column affected by the current stage
+*     of the factorization.
+*
+      JU = 1
+*
+      DO 40 J = 1, MIN( M, N )
+*
+*        Set fill-in elements in column J+KV to zero.
+*
+         IF( J+KV.LE.N ) THEN
+            DO 30 I = 1, KL
+               AB( I, J+KV ) = ZERO
+   30       CONTINUE
+         END IF
+*
+*        Find pivot and test for singularity. KM is the number of
+*        subdiagonal elements in the current column.
+*
+         KM = MIN( KL, M-J )
+         JP = IDAMAX( KM+1, AB( KV+1, J ), 1 )
+         IPIV( J ) = JP + J - 1
+         IF( AB( KV+JP, J ).NE.ZERO ) THEN
+            JU = MAX( JU, MIN( J+KU+JP-1, N ) )
+*
+*           Apply interchange to columns J to JU.
+*
+            IF( JP.NE.1 )
+     $         CALL DSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1,
+     $                     AB( KV+1, J ), LDAB-1 )
+*
+            IF( KM.GT.0 ) THEN
+*
+*              Compute multipliers.
+*
+               CALL DSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 )
+*
+*              Update trailing submatrix within the band.
+*
+               IF( JU.GT.J )
+     $            CALL DGER( KM, JU-J, -ONE, AB( KV+2, J ), 1,
+     $                       AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ),
+     $                       LDAB-1 )
+            END IF
+         ELSE
+*
+*           If pivot is zero, set INFO to the index of the pivot
+*           unless a zero pivot has already been found.
+*
+            IF( INFO.EQ.0 )
+     $         INFO = J
+         END IF
+   40 CONTINUE
+      RETURN
+*
+*     End of DGBTF2
+*
+      END
diff --git a/libcruft/lapack/dgbtrf.f b/libcruft/lapack/dgbtrf.f
new file mode 100644
index 0000000..b22fc06
--- /dev/null
+++ b/libcruft/lapack/dgbtrf.f
@@ -0,0 +1,441 @@
+      SUBROUTINE DGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGBTRF computes an LU factorization of a real m-by-n band matrix A
+*  using partial pivoting with row interchanges.
+*
+*  This is the blocked version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U because of fill-in resulting from the row interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 64, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP,
+     $                   JU, K2, KM, KV, NB, NW
+      DOUBLE PRECISION   TEMP
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   WORK13( LDWORK, NBMAX ),
+     $                   WORK31( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX, ILAENV
+      EXTERNAL           IDAMAX, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGBTF2, DGEMM, DGER, DLASWP, DSCAL,
+     $                   DSWAP, DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'DGBTRF', ' ', M, N, KL, KU )
+*
+*     The block size must not exceed the limit set by the size of the
+*     local arrays WORK13 and WORK31.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KL ) THEN
+*
+*        Use unblocked code
+*
+         CALL DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+*        Zero the superdiagonal elements of the work array WORK13
+*
+         DO 20 J = 1, NB
+            DO 10 I = 1, J - 1
+               WORK13( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Zero the subdiagonal elements of the work array WORK31
+*
+         DO 40 J = 1, NB
+            DO 30 I = J + 1, NB
+               WORK31( I, J ) = ZERO
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Gaussian elimination with partial pivoting
+*
+*        Set fill-in elements in columns KU+2 to KV to zero
+*
+         DO 60 J = KU + 2, MIN( KV, N )
+            DO 50 I = KV - J + 2, KL
+               AB( I, J ) = ZERO
+   50       CONTINUE
+   60    CONTINUE
+*
+*        JU is the index of the last column affected by the current
+*        stage of the factorization
+*
+         JU = 1
+*
+         DO 180 J = 1, MIN( M, N ), NB
+            JB = MIN( NB, MIN( M, N )-J+1 )
+*
+*           The active part of the matrix is partitioned
+*
+*              A11   A12   A13
+*              A21   A22   A23
+*              A31   A32   A33
+*
+*           Here A11, A21 and A31 denote the current block of JB columns
+*           which is about to be factorized. The number of rows in the
+*           partitioning are JB, I2, I3 respectively, and the numbers
+*           of columns are JB, J2, J3. The superdiagonal elements of A13
+*           and the subdiagonal elements of A31 lie outside the band.
+*
+            I2 = MIN( KL-JB, M-J-JB+1 )
+            I3 = MIN( JB, M-J-KL+1 )
+*
+*           J2 and J3 are computed after JU has been updated.
+*
+*           Factorize the current block of JB columns
+*
+            DO 80 JJ = J, J + JB - 1
+*
+*              Set fill-in elements in column JJ+KV to zero
+*
+               IF( JJ+KV.LE.N ) THEN
+                  DO 70 I = 1, KL
+                     AB( I, JJ+KV ) = ZERO
+   70             CONTINUE
+               END IF
+*
+*              Find pivot and test for singularity. KM is the number of
+*              subdiagonal elements in the current column.
+*
+               KM = MIN( KL, M-JJ )
+               JP = IDAMAX( KM+1, AB( KV+1, JJ ), 1 )
+               IPIV( JJ ) = JP + JJ - J
+               IF( AB( KV+JP, JJ ).NE.ZERO ) THEN
+                  JU = MAX( JU, MIN( JJ+KU+JP-1, N ) )
+                  IF( JP.NE.1 ) THEN
+*
+*                    Apply interchange to columns J to J+JB-1
+*
+                     IF( JP+JJ-1.LT.J+KL ) THEN
+*
+                        CALL DSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              AB( KV+JP+JJ-J, J ), LDAB-1 )
+                     ELSE
+*
+*                       The interchange affects columns J to JJ-1 of A31
+*                       which are stored in the work array WORK31
+*
+                        CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                        CALL DSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1,
+     $                              AB( KV+JP, JJ ), LDAB-1 )
+                     END IF
+                  END IF
+*
+*                 Compute multipliers
+*
+                  CALL DSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ),
+     $                        1 )
+*
+*                 Update trailing submatrix within the band and within
+*                 the current block. JM is the index of the last column
+*                 which needs to be updated.
+*
+                  JM = MIN( JU, J+JB-1 )
+                  IF( JM.GT.JJ )
+     $               CALL DGER( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1,
+     $                          AB( KV, JJ+1 ), LDAB-1,
+     $                          AB( KV+1, JJ+1 ), LDAB-1 )
+               ELSE
+*
+*                 If pivot is zero, set INFO to the index of the pivot
+*                 unless a zero pivot has already been found.
+*
+                  IF( INFO.EQ.0 )
+     $               INFO = JJ
+               END IF
+*
+*              Copy current column of A31 into the work array WORK31
+*
+               NW = MIN( JJ-J+1, I3 )
+               IF( NW.GT.0 )
+     $            CALL DCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1,
+     $                        WORK31( 1, JJ-J+1 ), 1 )
+   80       CONTINUE
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply the row interchanges to the other blocks.
+*
+               J2 = MIN( JU-J+1, KV ) - JB
+               J3 = MAX( 0, JU-J-KV+1 )
+*
+*              Use DLASWP to apply the row interchanges to A12, A22, and
+*              A32.
+*
+               CALL DLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB,
+     $                      IPIV( J ), 1 )
+*
+*              Adjust the pivot indices.
+*
+               DO 90 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+   90          CONTINUE
+*
+*              Apply the row interchanges to A13, A23, and A33
+*              columnwise.
+*
+               K2 = J - 1 + JB + J2
+               DO 110 I = 1, J3
+                  JJ = K2 + I
+                  DO 100 II = J + I - 1, J + JB - 1
+                     IP = IPIV( II )
+                     IF( IP.NE.II ) THEN
+                        TEMP = AB( KV+1+II-JJ, JJ )
+                        AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ )
+                        AB( KV+1+IP-JJ, JJ ) = TEMP
+                     END IF
+  100             CONTINUE
+  110          CONTINUE
+*
+*              Update the relevant part of the trailing submatrix
+*
+               IF( J2.GT.0 ) THEN
+*
+*                 Update A12
+*
+                  CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J2, ONE, AB( KV+1, J ), LDAB-1,
+     $                        AB( KV+1-JB, J+JB ), LDAB-1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A22
+*
+                     CALL DGEMM( 'No transpose', 'No transpose', I2, J2,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+1, J+JB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A32
+*
+                     CALL DGEMM( 'No transpose', 'No transpose', I3, J2,
+     $                           JB, -ONE, WORK31, LDWORK,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+KL+1-JB, J+JB ), LDAB-1 )
+                  END IF
+               END IF
+*
+               IF( J3.GT.0 ) THEN
+*
+*                 Copy the lower triangle of A13 into the work array
+*                 WORK13
+*
+                  DO 130 JJ = 1, J3
+                     DO 120 II = JJ, JB
+                        WORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 )
+  120                CONTINUE
+  130             CONTINUE
+*
+*                 Update A13 in the work array
+*
+                  CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J3, ONE, AB( KV+1, J ), LDAB-1,
+     $                        WORK13, LDWORK )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A23
+*
+                     CALL DGEMM( 'No transpose', 'No transpose', I2, J3,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           WORK13, LDWORK, ONE, AB( 1+JB, J+KV ),
+     $                           LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A33
+*
+                     CALL DGEMM( 'No transpose', 'No transpose', I3, J3,
+     $                           JB, -ONE, WORK31, LDWORK, WORK13,
+     $                           LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 )
+                  END IF
+*
+*                 Copy the lower triangle of A13 back into place
+*
+                  DO 150 JJ = 1, J3
+                     DO 140 II = JJ, JB
+                        AB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ )
+  140                CONTINUE
+  150             CONTINUE
+               END IF
+            ELSE
+*
+*              Adjust the pivot indices.
+*
+               DO 160 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+  160          CONTINUE
+            END IF
+*
+*           Partially undo the interchanges in the current block to
+*           restore the upper triangular form of A31 and copy the upper
+*           triangle of A31 back into place
+*
+            DO 170 JJ = J + JB - 1, J, -1
+               JP = IPIV( JJ ) - JJ + 1
+               IF( JP.NE.1 ) THEN
+*
+*                 Apply interchange to columns J to JJ-1
+*
+                  IF( JP+JJ-1.LT.J+KL ) THEN
+*
+*                    The interchange does not affect A31
+*
+                     CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           AB( KV+JP+JJ-J, J ), LDAB-1 )
+                  ELSE
+*
+*                    The interchange does affect A31
+*
+                     CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                  END IF
+               END IF
+*
+*              Copy the current column of A31 back into place
+*
+               NW = MIN( I3, JJ-J+1 )
+               IF( NW.GT.0 )
+     $            CALL DCOPY( NW, WORK31( 1, JJ-J+1 ), 1,
+     $                        AB( KV+KL+1-JJ+J, JJ ), 1 )
+  170       CONTINUE
+  180    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DGBTRF
+*
+      END
diff --git a/libcruft/lapack/dgbtrs.f b/libcruft/lapack/dgbtrs.f
new file mode 100644
index 0000000..c7ade37
--- /dev/null
+++ b/libcruft/lapack/dgbtrs.f
@@ -0,0 +1,186 @@
+      SUBROUTINE DGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, KL, KU, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGBTRS solves a system of linear equations
+*     A * X = B  or  A' * X = B
+*  with a general band matrix A using the LU factorization computed
+*  by DGBTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A'* X = B  (Transpose)
+*          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) DOUBLE PRECISION array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by DGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, NOTRAN
+      INTEGER            I, J, KD, L, LM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DGER, DSWAP, DTBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      KD = KU + KL + 1
+      LNOTI = KL.GT.0
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve  A*X = B.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+*        L is represented as a product of permutations and unit lower
+*        triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1),
+*        where each transformation L(i) is a rank-one modification of
+*        the identity matrix.
+*
+         IF( LNOTI ) THEN
+            DO 10 J = 1, N - 1
+               LM = MIN( KL, N-J )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+               CALL DGER( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ),
+     $                    LDB, B( J+1, 1 ), LDB )
+   10       CONTINUE
+         END IF
+*
+         DO 20 I = 1, NRHS
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL DTBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU,
+     $                  AB, LDAB, B( 1, I ), 1 )
+   20    CONTINUE
+*
+      ELSE
+*
+*        Solve A'*X = B.
+*
+         DO 30 I = 1, NRHS
+*
+*           Solve U'*X = B, overwriting B with X.
+*
+            CALL DTBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB,
+     $                  LDAB, B( 1, I ), 1 )
+   30    CONTINUE
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         IF( LNOTI ) THEN
+            DO 40 J = N - 1, 1, -1
+               LM = MIN( KL, N-J )
+               CALL DGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ),
+     $                     LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+   40       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of DGBTRS
+*
+      END
diff --git a/libcruft/lapack/dgebak.f b/libcruft/lapack/dgebak.f
new file mode 100644
index 0000000..b8e9be5
--- /dev/null
+++ b/libcruft/lapack/dgebak.f
@@ -0,0 +1,188 @@
+      SUBROUTINE DGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   SCALE( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEBAK forms the right or left eigenvectors of a real general matrix
+*  by backward transformation on the computed eigenvectors of the
+*  balanced matrix output by DGEBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N', do nothing, return immediately;
+*          = 'P', do backward transformation for permutation only;
+*          = 'S', do backward transformation for scaling only;
+*          = 'B', do backward transformations for both permutation and
+*                 scaling.
+*          JOB must be the same as the argument JOB supplied to DGEBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by DGEBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  SCALE   (input) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutation and scaling factors, as returned
+*          by DGEBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) DOUBLE PRECISION array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by DHSEIN or DTREVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, II, K
+      DOUBLE PRECISION   S
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -7
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               S = SCALE( I )
+               CALL DSCAL( M, S, V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               S = ONE / SCALE( I )
+               CALL DSCAL( M, S, V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+*
+      END IF
+*
+*     Backward permutation
+*
+*     For  I = ILO-1 step -1 until 1,
+*              IHI+1 step 1 until N do --
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+         IF( RIGHTV ) THEN
+            DO 40 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 40
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 50 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 50
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 50
+               CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   50       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DGEBAK
+*
+      END
diff --git a/libcruft/lapack/dgebal.f b/libcruft/lapack/dgebal.f
new file mode 100644
index 0000000..1796577
--- /dev/null
+++ b/libcruft/lapack/dgebal.f
@@ -0,0 +1,322 @@
+      SUBROUTINE DGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), SCALE( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEBAL balances a general real matrix A.  This involves, first,
+*  permuting A by a similarity transformation to isolate eigenvalues
+*  in the first 1 to ILO-1 and last IHI+1 to N elements on the
+*  diagonal; and second, applying a diagonal similarity transformation
+*  to rows and columns ILO to IHI to make the rows and columns as
+*  close in norm as possible.  Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrix, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, SCALE(I) = 1.0
+*                  for i = 1,...,N;
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit,  A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  SCALE   (output) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and scaling factors applied to
+*          A.  If P(j) is the index of the row and column interchanged
+*          with row and column j and D(j) is the scaling factor
+*          applied to row and column j, then
+*          SCALE(j) = P(j)    for j = 1,...,ILO-1
+*                   = D(j)    for j = ILO,...,IHI
+*                   = P(j)    for j = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The permutations consist of row and column interchanges which put
+*  the matrix in the form
+*
+*             ( T1   X   Y  )
+*     P A P = (  0   B   Z  )
+*             (  0   0   T2 )
+*
+*  where T1 and T2 are upper triangular matrices whose eigenvalues lie
+*  along the diagonal.  The column indices ILO and IHI mark the starting
+*  and ending columns of the submatrix B. Balancing consists of applying
+*  a diagonal similarity transformation inv(D) * B * D to make the
+*  1-norms of each row of B and its corresponding column nearly equal.
+*  The output matrix is
+*
+*     ( T1     X*D          Y    )
+*     (  0  inv(D)*B*D  inv(D)*Z ).
+*     (  0      0           T2   )
+*
+*  Information about the permutations P and the diagonal matrix D is
+*  returned in the vector SCALE.
+*
+*  This subroutine is based on the EISPACK routine BALANC.
+*
+*  Modified by Tzu-Yi Chen, Computer Science Division, University of
+*    California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   SCLFAC
+      PARAMETER          ( SCLFAC = 2.0D+0 )
+      DOUBLE PRECISION   FACTOR
+      PARAMETER          ( FACTOR = 0.95D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOCONV
+      INTEGER            I, ICA, IEXC, IRA, J, K, L, M
+      DOUBLE PRECISION   C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,
+     $                   SFMIN2
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEBAL', -INFO )
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+*
+      IF( N.EQ.0 )
+     $   GO TO 210
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         DO 10 I = 1, N
+            SCALE( I ) = ONE
+   10    CONTINUE
+         GO TO 210
+      END IF
+*
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 120
+*
+*     Permutation to isolate eigenvalues if possible
+*
+      GO TO 50
+*
+*     Row and column exchange.
+*
+   20 CONTINUE
+      SCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 30
+*
+      CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL DSWAP( N-K+1, A( J, K ), LDA, A( M, K ), LDA )
+*
+   30 CONTINUE
+      GO TO ( 40, 80 )IEXC
+*
+*     Search for rows isolating an eigenvalue and push them down.
+*
+   40 CONTINUE
+      IF( L.EQ.1 )
+     $   GO TO 210
+      L = L - 1
+*
+   50 CONTINUE
+      DO 70 J = L, 1, -1
+*
+         DO 60 I = 1, L
+            IF( I.EQ.J )
+     $         GO TO 60
+            IF( A( J, I ).NE.ZERO )
+     $         GO TO 70
+   60    CONTINUE
+*
+         M = L
+         IEXC = 1
+         GO TO 20
+   70 CONTINUE
+*
+      GO TO 90
+*
+*     Search for columns isolating an eigenvalue and push them left.
+*
+   80 CONTINUE
+      K = K + 1
+*
+   90 CONTINUE
+      DO 110 J = K, L
+*
+         DO 100 I = K, L
+            IF( I.EQ.J )
+     $         GO TO 100
+            IF( A( I, J ).NE.ZERO )
+     $         GO TO 110
+  100    CONTINUE
+*
+         M = K
+         IEXC = 2
+         GO TO 20
+  110 CONTINUE
+*
+  120 CONTINUE
+      DO 130 I = K, L
+         SCALE( I ) = ONE
+  130 CONTINUE
+*
+      IF( LSAME( JOB, 'P' ) )
+     $   GO TO 210
+*
+*     Balance the submatrix in rows K to L.
+*
+*     Iterative loop for norm reduction
+*
+      SFMIN1 = DLAMCH( 'S' ) / DLAMCH( 'P' )
+      SFMAX1 = ONE / SFMIN1
+      SFMIN2 = SFMIN1*SCLFAC
+      SFMAX2 = ONE / SFMIN2
+  140 CONTINUE
+      NOCONV = .FALSE.
+*
+      DO 200 I = K, L
+         C = ZERO
+         R = ZERO
+*
+         DO 150 J = K, L
+            IF( J.EQ.I )
+     $         GO TO 150
+            C = C + ABS( A( J, I ) )
+            R = R + ABS( A( I, J ) )
+  150    CONTINUE
+         ICA = IDAMAX( L, A( 1, I ), 1 )
+         CA = ABS( A( ICA, I ) )
+         IRA = IDAMAX( N-K+1, A( I, K ), LDA )
+         RA = ABS( A( I, IRA+K-1 ) )
+*
+*        Guard against zero C or R due to underflow.
+*
+         IF( C.EQ.ZERO .OR. R.EQ.ZERO )
+     $      GO TO 200
+         G = R / SCLFAC
+         F = ONE
+         S = C + R
+  160    CONTINUE
+         IF( C.GE.G .OR. MAX( F, C, CA ).GE.SFMAX2 .OR.
+     $       MIN( R, G, RA ).LE.SFMIN2 )GO TO 170
+         F = F*SCLFAC
+         C = C*SCLFAC
+         CA = CA*SCLFAC
+         R = R / SCLFAC
+         G = G / SCLFAC
+         RA = RA / SCLFAC
+         GO TO 160
+*
+  170    CONTINUE
+         G = C / SCLFAC
+  180    CONTINUE
+         IF( G.LT.R .OR. MAX( R, RA ).GE.SFMAX2 .OR.
+     $       MIN( F, C, G, CA ).LE.SFMIN2 )GO TO 190
+         F = F / SCLFAC
+         C = C / SCLFAC
+         G = G / SCLFAC
+         CA = CA / SCLFAC
+         R = R*SCLFAC
+         RA = RA*SCLFAC
+         GO TO 180
+*
+*        Now balance.
+*
+  190    CONTINUE
+         IF( ( C+R ).GE.FACTOR*S )
+     $      GO TO 200
+         IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THEN
+            IF( F*SCALE( I ).LE.SFMIN1 )
+     $         GO TO 200
+         END IF
+         IF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THEN
+            IF( SCALE( I ).GE.SFMAX1 / F )
+     $         GO TO 200
+         END IF
+         G = ONE / F
+         SCALE( I ) = SCALE( I )*F
+         NOCONV = .TRUE.
+*
+         CALL DSCAL( N-K+1, G, A( I, K ), LDA )
+         CALL DSCAL( L, F, A( 1, I ), 1 )
+*
+  200 CONTINUE
+*
+      IF( NOCONV )
+     $   GO TO 140
+*
+  210 CONTINUE
+      ILO = K
+      IHI = L
+*
+      RETURN
+*
+*     End of DGEBAL
+*
+      END
diff --git a/libcruft/lapack/dgebd2.f b/libcruft/lapack/dgebd2.f
new file mode 100644
index 0000000..b9eb638
--- /dev/null
+++ b/libcruft/lapack/dgebd2.f
@@ -0,0 +1,239 @@
+      SUBROUTINE DGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), D( * ), E( * ), TAUP( * ),
+     $                   TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEBD2 reduces a real general m by n matrix A to upper or lower
+*  bidiagonal form B by an orthogonal transformation: Q' * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the orthogonal matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the orthogonal matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) DOUBLE PRECISION array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix Q. See Further Details.
+*
+*  TAUP    (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix P. See Further Details.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (max(M,N))
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit.
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);
+*  u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);
+*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'DGEBD2', -INFO )
+         RETURN
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, N
+*
+*           Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+            CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = A( I, I )
+            A( I, I ) = ONE
+*
+*           Apply H(i) to A(i:m,i+1:n) from the left
+*
+            IF( I.LT.N )
+     $         CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAUQ( I ),
+     $                     A( I, I+1 ), LDA, WORK )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector G(i) to annihilate
+*              A(i,i+2:n)
+*
+               CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),
+     $                      LDA, TAUP( I ) )
+               E( I ) = A( I, I+1 )
+               A( I, I+1 ) = ONE
+*
+*              Apply G(i) to A(i+1:m,i+1:n) from the right
+*
+               CALL DLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA,
+     $                     TAUP( I ), A( I+1, I+1 ), LDA, WORK )
+               A( I, I+1 ) = E( I )
+            ELSE
+               TAUP( I ) = ZERO
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, M
+*
+*           Generate elementary reflector G(i) to annihilate A(i,i+1:n)
+*
+            CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = A( I, I )
+            A( I, I ) = ONE
+*
+*           Apply G(i) to A(i+1:m,i:n) from the right
+*
+            IF( I.LT.M )
+     $         CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     TAUP( I ), A( I+1, I ), LDA, WORK )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.M ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:m,i)
+*
+               CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = A( I+1, I )
+               A( I+1, I ) = ONE
+*
+*              Apply H(i) to A(i+1:m,i+1:n) from the left
+*
+               CALL DLARF( 'Left', M-I, N-I, A( I+1, I ), 1, TAUQ( I ),
+     $                     A( I+1, I+1 ), LDA, WORK )
+               A( I+1, I ) = E( I )
+            ELSE
+               TAUQ( I ) = ZERO
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DGEBD2
+*
+      END
diff --git a/libcruft/lapack/dgebrd.f b/libcruft/lapack/dgebrd.f
new file mode 100644
index 0000000..6544715
--- /dev/null
+++ b/libcruft/lapack/dgebrd.f
@@ -0,0 +1,268 @@
+      SUBROUTINE DGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), D( * ), E( * ), TAUP( * ),
+     $                   TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEBRD reduces a general real M-by-N matrix A to upper or lower
+*  bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the orthogonal matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the orthogonal matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) DOUBLE PRECISION array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix Q. See Further Details.
+*
+*  TAUP    (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix P. See Further Details.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,M,N).
+*          For optimum performance LWORK >= (M+N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);
+*  u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);
+*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LDWRKX, LDWRKY, LWKOPT, MINMN, NB,
+     $                   NBMIN, NX
+      DOUBLE PRECISION   WS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEBD2, DGEMM, DLABRD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MAX( 1, ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 ) )
+      LWKOPT = ( M+N )*NB
+      WORK( 1 ) = DBLE( LWKOPT )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'DGEBRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      MINMN = MIN( M, N )
+      IF( MINMN.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      WS = MAX( M, N )
+      LDWRKX = M
+      LDWRKY = N
+*
+      IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN
+*
+*        Set the crossover point NX.
+*
+         NX = MAX( NB, ILAENV( 3, 'DGEBRD', ' ', M, N, -1, -1 ) )
+*
+*        Determine when to switch from blocked to unblocked code.
+*
+         IF( NX.LT.MINMN ) THEN
+            WS = ( M+N )*NB
+            IF( LWORK.LT.WS ) THEN
+*
+*              Not enough work space for the optimal NB, consider using
+*              a smaller block size.
+*
+               NBMIN = ILAENV( 2, 'DGEBRD', ' ', M, N, -1, -1 )
+               IF( LWORK.GE.( M+N )*NBMIN ) THEN
+                  NB = LWORK / ( M+N )
+               ELSE
+                  NB = 1
+                  NX = MINMN
+               END IF
+            END IF
+         END IF
+      ELSE
+         NX = MINMN
+      END IF
+*
+      DO 30 I = 1, MINMN - NX, NB
+*
+*        Reduce rows and columns i:i+nb-1 to bidiagonal form and return
+*        the matrices X and Y which are needed to update the unreduced
+*        part of the matrix
+*
+         CALL DLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ),
+     $                TAUQ( I ), TAUP( I ), WORK, LDWRKX,
+     $                WORK( LDWRKX*NB+1 ), LDWRKY )
+*
+*        Update the trailing submatrix A(i+nb:m,i+nb:n), using an update
+*        of the form  A := A - V*Y' - X*U'
+*
+         CALL DGEMM( 'No transpose', 'Transpose', M-I-NB+1, N-I-NB+1,
+     $               NB, -ONE, A( I+NB, I ), LDA,
+     $               WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE,
+     $               A( I+NB, I+NB ), LDA )
+         CALL DGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1,
+     $               NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA,
+     $               ONE, A( I+NB, I+NB ), LDA )
+*
+*        Copy diagonal and off-diagonal elements of B back into A
+*
+         IF( M.GE.N ) THEN
+            DO 10 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J, J+1 ) = E( J )
+   10       CONTINUE
+         ELSE
+            DO 20 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J+1, J ) = E( J )
+   20       CONTINUE
+         END IF
+   30 CONTINUE
+*
+*     Use unblocked code to reduce the remainder of the matrix
+*
+      CALL DGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $             TAUQ( I ), TAUP( I ), WORK, IINFO )
+      WORK( 1 ) = WS
+      RETURN
+*
+*     End of DGEBRD
+*
+      END
diff --git a/libcruft/lapack/dgecon.f b/libcruft/lapack/dgecon.f
new file mode 100644
index 0000000..807cafc
--- /dev/null
+++ b/libcruft/lapack/dgecon.f
@@ -0,0 +1,185 @@
+      SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call DLACN2 in place of DLACON, 5 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGECON estimates the reciprocal of the condition number of a general
+*  real matrix A, in either the 1-norm or the infinity-norm, using
+*  the LU factorization computed by DGETRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by DGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (4*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      DOUBLE PRECISION   AINVNM, SCALE, SL, SMLNUM, SU
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACN2, DLATRS, DRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGECON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KASE = 0
+   10 CONTINUE
+      CALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            CALL DLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A,
+     $                   LDA, WORK, SL, WORK( 2*N+1 ), INFO )
+*
+*           Multiply by inv(U).
+*
+            CALL DLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SU, WORK( 3*N+1 ), INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL DLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,
+     $                   LDA, WORK, SU, WORK( 3*N+1 ), INFO )
+*
+*           Multiply by inv(L').
+*
+            CALL DLATRS( 'Lower', 'Transpose', 'Unit', NORMIN, N, A,
+     $                   LDA, WORK, SL, WORK( 2*N+1 ), INFO )
+         END IF
+*
+*        Divide X by 1/(SL*SU) if doing so will not cause overflow.
+*
+         SCALE = SL*SU
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = IDAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL DRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of DGECON
+*
+      END
diff --git a/libcruft/lapack/dgeesx.f b/libcruft/lapack/dgeesx.f
new file mode 100644
index 0000000..deb30ab
--- /dev/null
+++ b/libcruft/lapack/dgeesx.f
@@ -0,0 +1,527 @@
+      SUBROUTINE DGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,
+     $                   WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
+     $                   IWORK, LIWORK, BWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVS, SENSE, SORT
+      INTEGER            INFO, LDA, LDVS, LIWORK, LWORK, N, SDIM
+      DOUBLE PRECISION   RCONDE, RCONDV
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            BWORK( * )
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
+     $                   WR( * )
+*     ..
+*     .. Function Arguments ..
+      LOGICAL            SELECT
+      EXTERNAL           SELECT
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEESX computes for an N-by-N real nonsymmetric matrix A, the
+*  eigenvalues, the real Schur form T, and, optionally, the matrix of
+*  Schur vectors Z.  This gives the Schur factorization A = Z*T*(Z**T).
+*
+*  Optionally, it also orders the eigenvalues on the diagonal of the
+*  real Schur form so that selected eigenvalues are at the top left;
+*  computes a reciprocal condition number for the average of the
+*  selected eigenvalues (RCONDE); and computes a reciprocal condition
+*  number for the right invariant subspace corresponding to the
+*  selected eigenvalues (RCONDV).  The leading columns of Z form an
+*  orthonormal basis for this invariant subspace.
+*
+*  For further explanation of the reciprocal condition numbers RCONDE
+*  and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where
+*  these quantities are called s and sep respectively).
+*
+*  A real matrix is in real Schur form if it is upper quasi-triangular
+*  with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in
+*  the form
+*            [  a  b  ]
+*            [  c  a  ]
+*
+*  where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
+*
+*  Arguments
+*  =========
+*
+*  JOBVS   (input) CHARACTER*1
+*          = 'N': Schur vectors are not computed;
+*          = 'V': Schur vectors are computed.
+*
+*  SORT    (input) CHARACTER*1
+*          Specifies whether or not to order the eigenvalues on the
+*          diagonal of the Schur form.
+*          = 'N': Eigenvalues are not ordered;
+*          = 'S': Eigenvalues are ordered (see SELECT).
+*
+*  SELECT  (external procedure) LOGICAL FUNCTION of two DOUBLE PRECISION arguments
+*          SELECT must be declared EXTERNAL in the calling subroutine.
+*          If SORT = 'S', SELECT is used to select eigenvalues to sort
+*          to the top left of the Schur form.
+*          If SORT = 'N', SELECT is not referenced.
+*          An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
+*          SELECT(WR(j),WI(j)) is true; i.e., if either one of a
+*          complex conjugate pair of eigenvalues is selected, then both
+*          are.  Note that a selected complex eigenvalue may no longer
+*          satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
+*          ordering may change the value of complex eigenvalues
+*          (especially if the eigenvalue is ill-conditioned); in this
+*          case INFO may be set to N+3 (see INFO below).
+*
+*  SENSE   (input) CHARACTER*1
+*          Determines which reciprocal condition numbers are computed.
+*          = 'N': None are computed;
+*          = 'E': Computed for average of selected eigenvalues only;
+*          = 'V': Computed for selected right invariant subspace only;
+*          = 'B': Computed for both.
+*          If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA, N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A is overwritten by its real Schur form T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  SDIM    (output) INTEGER
+*          If SORT = 'N', SDIM = 0.
+*          If SORT = 'S', SDIM = number of eigenvalues (after sorting)
+*                         for which SELECT is true. (Complex conjugate
+*                         pairs for which SELECT is true for either
+*                         eigenvalue count as 2.)
+*
+*  WR      (output) DOUBLE PRECISION array, dimension (N)
+*  WI      (output) DOUBLE PRECISION array, dimension (N)
+*          WR and WI contain the real and imaginary parts, respectively,
+*          of the computed eigenvalues, in the same order that they
+*          appear on the diagonal of the output Schur form T.  Complex
+*          conjugate pairs of eigenvalues appear consecutively with the
+*          eigenvalue having the positive imaginary part first.
+*
+*  VS      (output) DOUBLE PRECISION array, dimension (LDVS,N)
+*          If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
+*          vectors.
+*          If JOBVS = 'N', VS is not referenced.
+*
+*  LDVS    (input) INTEGER
+*          The leading dimension of the array VS.  LDVS >= 1, and if
+*          JOBVS = 'V', LDVS >= N.
+*
+*  RCONDE  (output) DOUBLE PRECISION
+*          If SENSE = 'E' or 'B', RCONDE contains the reciprocal
+*          condition number for the average of the selected eigenvalues.
+*          Not referenced if SENSE = 'N' or 'V'.
+*
+*  RCONDV  (output) DOUBLE PRECISION
+*          If SENSE = 'V' or 'B', RCONDV contains the reciprocal
+*          condition number for the selected right invariant subspace.
+*          Not referenced if SENSE = 'N' or 'E'.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,3*N).
+*          Also, if SENSE = 'E' or 'V' or 'B',
+*          LWORK >= N+2*SDIM*(N-SDIM), where SDIM is the number of
+*          selected eigenvalues computed by this routine.  Note that
+*          N+2*SDIM*(N-SDIM) <= N+N*N/2. Note also that an error is only
+*          returned if LWORK < max(1,3*N), but if SENSE = 'E' or 'V' or
+*          'B' this may not be large enough.
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates upper bounds on the optimal sizes of the
+*          arrays WORK and IWORK, returns these values as the first
+*          entries of the WORK and IWORK arrays, and no error messages
+*          related to LWORK or LIWORK are issued by XERBLA.
+*
+*  IWORK   (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
+*          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
+*
+*  LIWORK  (input) INTEGER
+*          The dimension of the array IWORK.
+*          LIWORK >= 1; if SENSE = 'V' or 'B', LIWORK >= SDIM*(N-SDIM).
+*          Note that SDIM*(N-SDIM) <= N*N/4. Note also that an error is
+*          only returned if LIWORK < 1, but if SENSE = 'V' or 'B' this
+*          may not be large enough.
+*
+*          If LIWORK = -1, then a workspace query is assumed; the
+*          routine only calculates upper bounds on the optimal sizes of
+*          the arrays WORK and IWORK, returns these values as the first
+*          entries of the WORK and IWORK arrays, and no error messages
+*          related to LWORK or LIWORK are issued by XERBLA.
+*
+*  BWORK   (workspace) LOGICAL array, dimension (N)
+*          Not referenced if SORT = 'N'.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*          > 0: if INFO = i, and i is
+*             <= N: the QR algorithm failed to compute all the
+*                   eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
+*                   contain those eigenvalues which have converged; if
+*                   JOBVS = 'V', VS contains the transformation which
+*                   reduces A to its partially converged Schur form.
+*             = N+1: the eigenvalues could not be reordered because some
+*                   eigenvalues were too close to separate (the problem
+*                   is very ill-conditioned);
+*             = N+2: after reordering, roundoff changed values of some
+*                   complex eigenvalues so that leading eigenvalues in
+*                   the Schur form no longer satisfy SELECT=.TRUE.  This
+*                   could also be caused by underflow due to scaling.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTSB,
+     $                   WANTSE, WANTSN, WANTST, WANTSV, WANTVS
+      INTEGER            HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
+     $                   IHI, ILO, INXT, IP, ITAU, IWRK, LIWRK, LWRK,
+     $                   MAXWRK, MINWRK
+      DOUBLE PRECISION   ANRM, BIGNUM, CSCALE, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,
+     $                   DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           LSAME, ILAENV, DLABAD, DLAMCH, DLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTVS = LSAME( JOBVS, 'V' )
+      WANTST = LSAME( SORT, 'S' )
+      WANTSN = LSAME( SENSE, 'N' )
+      WANTSE = LSAME( SENSE, 'E' )
+      WANTSV = LSAME( SENSE, 'V' )
+      WANTSB = LSAME( SENSE, 'B' )
+      LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
+      IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
+     $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
+         INFO = -12
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "RWorkspace:" describe the
+*       minimal amount of real workspace needed at that point in the
+*       code, as well as the preferred amount for good performance.
+*       IWorkspace refers to integer workspace.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by DHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.
+*       If SENSE = 'E', 'V' or 'B', then the amount of workspace needed
+*       depends on SDIM, which is computed by the routine DTRSEN later
+*       in the code.)
+*
+      IF( INFO.EQ.0 ) THEN
+         LIWRK = 1
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            LWRK = 1
+         ELSE
+            MAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
+            MINWRK = 3*N
+*
+            CALL DHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,
+     $             WORK, -1, IEVAL )
+            HSWORK = WORK( 1 )
+*
+            IF( .NOT.WANTVS ) THEN
+               MAXWRK = MAX( MAXWRK, N + HSWORK )
+            ELSE
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'DORGHR', ' ', N, 1, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + HSWORK )
+            END IF
+            LWRK = MAXWRK
+            IF( .NOT.WANTSN )
+     $         LWRK = MAX( LWRK, N + ( N*N )/2 )
+            IF( WANTSV .OR. WANTSB )
+     $         LIWRK = ( N*N )/4
+         END IF
+         IWORK( 1 ) = LIWRK
+         WORK( 1 ) = LWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -16
+         ELSE IF( LIWORK.LT.1 .AND. .NOT.LQUERY ) THEN
+            INFO = -18
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEESX', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         SDIM = 0
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*     Permute the matrix to make it more nearly triangular
+*     (RWorkspace: need N)
+*
+      IBAL = 1
+      CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (RWorkspace: need 3*N, prefer 2*N+N*NB)
+*
+      ITAU = N + IBAL
+      IWRK = N + ITAU
+      CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVS ) THEN
+*
+*        Copy Householder vectors to VS
+*
+         CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )
+*
+*        Generate orthogonal matrix in VS
+*        (RWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*
+         CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+      END IF
+*
+      SDIM = 0
+*
+*     Perform QR iteration, accumulating Schur vectors in VS if desired
+*     (RWorkspace: need N+1, prefer N+HSWORK (see comments) )
+*
+      IWRK = ITAU
+      CALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,
+     $             WORK( IWRK ), LWORK-IWRK+1, IEVAL )
+      IF( IEVAL.GT.0 )
+     $   INFO = IEVAL
+*
+*     Sort eigenvalues if desired
+*
+      IF( WANTST .AND. INFO.EQ.0 ) THEN
+         IF( SCALEA ) THEN
+            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )
+            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )
+         END IF
+         DO 10 I = 1, N
+            BWORK( I ) = SELECT( WR( I ), WI( I ) )
+   10    CONTINUE
+*
+*        Reorder eigenvalues, transform Schur vectors, and compute
+*        reciprocal condition numbers
+*        (RWorkspace: if SENSE is not 'N', need N+2*SDIM*(N-SDIM)
+*                     otherwise, need N )
+*        (IWorkspace: if SENSE is 'V' or 'B', need SDIM*(N-SDIM)
+*                     otherwise, need 0 )
+*
+         CALL DTRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,
+     $                SDIM, RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,
+     $                IWORK, LIWORK, ICOND )
+         IF( .NOT.WANTSN )
+     $      MAXWRK = MAX( MAXWRK, N+2*SDIM*( N-SDIM ) )
+         IF( ICOND.EQ.-15 ) THEN
+*
+*           Not enough real workspace
+*
+            INFO = -16
+         ELSE IF( ICOND.EQ.-17 ) THEN
+*
+*           Not enough integer workspace
+*
+            INFO = -18
+         ELSE IF( ICOND.GT.0 ) THEN
+*
+*           DTRSEN failed to reorder or to restore standard Schur form
+*
+            INFO = ICOND + N
+         END IF
+      END IF
+*
+      IF( WANTVS ) THEN
+*
+*        Undo balancing
+*        (RWorkspace: need N)
+*
+         CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,
+     $                IERR )
+      END IF
+*
+      IF( SCALEA ) THEN
+*
+*        Undo scaling for the Schur form of A
+*
+         CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
+         CALL DCOPY( N, A, LDA+1, WR, 1 )
+         IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THEN
+            DUM( 1 ) = RCONDV
+            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
+            RCONDV = DUM( 1 )
+         END IF
+         IF( CSCALE.EQ.SMLNUM ) THEN
+*
+*           If scaling back towards underflow, adjust WI if an
+*           offdiagonal element of a 2-by-2 block in the Schur form
+*           underflows.
+*
+            IF( IEVAL.GT.0 ) THEN
+               I1 = IEVAL + 1
+               I2 = IHI - 1
+               CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
+     $                      IERR )
+            ELSE IF( WANTST ) THEN
+               I1 = 1
+               I2 = N - 1
+            ELSE
+               I1 = ILO
+               I2 = IHI - 1
+            END IF
+            INXT = I1 - 1
+            DO 20 I = I1, I2
+               IF( I.LT.INXT )
+     $            GO TO 20
+               IF( WI( I ).EQ.ZERO ) THEN
+                  INXT = I + 1
+               ELSE
+                  IF( A( I+1, I ).EQ.ZERO ) THEN
+                     WI( I ) = ZERO
+                     WI( I+1 ) = ZERO
+                  ELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.
+     $                     ZERO ) THEN
+                     WI( I ) = ZERO
+                     WI( I+1 ) = ZERO
+                     IF( I.GT.1 )
+     $                  CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )
+                     IF( N.GT.I+1 )
+     $                  CALL DSWAP( N-I-1, A( I, I+2 ), LDA,
+     $                              A( I+1, I+2 ), LDA )
+                     CALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )
+                     A( I, I+1 ) = A( I+1, I )
+                     A( I+1, I ) = ZERO
+                  END IF
+                  INXT = I + 2
+               END IF
+   20       CONTINUE
+         END IF
+         CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,
+     $                WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )
+      END IF
+*
+      IF( WANTST .AND. INFO.EQ.0 ) THEN
+*
+*        Check if reordering successful
+*
+         LASTSL = .TRUE.
+         LST2SL = .TRUE.
+         SDIM = 0
+         IP = 0
+         DO 30 I = 1, N
+            CURSL = SELECT( WR( I ), WI( I ) )
+            IF( WI( I ).EQ.ZERO ) THEN
+               IF( CURSL )
+     $            SDIM = SDIM + 1
+               IP = 0
+               IF( CURSL .AND. .NOT.LASTSL )
+     $            INFO = N + 2
+            ELSE
+               IF( IP.EQ.1 ) THEN
+*
+*                 Last eigenvalue of conjugate pair
+*
+                  CURSL = CURSL .OR. LASTSL
+                  LASTSL = CURSL
+                  IF( CURSL )
+     $               SDIM = SDIM + 2
+                  IP = -1
+                  IF( CURSL .AND. .NOT.LST2SL )
+     $               INFO = N + 2
+               ELSE
+*
+*                 First eigenvalue of conjugate pair
+*
+                  IP = 1
+               END IF
+            END IF
+            LST2SL = LASTSL
+            LASTSL = CURSL
+   30    CONTINUE
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      IF( WANTSV .OR. WANTSB ) THEN
+         IWORK( 1 ) = MAX( 1, SDIM*( N-SDIM ) )
+      ELSE
+         IWORK( 1 ) = 1
+      END IF
+*
+      RETURN
+*
+*     End of DGEESX
+*
+      END
diff --git a/libcruft/lapack/dgeev.f b/libcruft/lapack/dgeev.f
new file mode 100644
index 0000000..50e08a9
--- /dev/null
+++ b/libcruft/lapack/dgeev.f
@@ -0,0 +1,423 @@
+      SUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
+     $                  LDVR, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WI( * ), WORK( * ), WR( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEEV computes for an N-by-N real nonsymmetric matrix A, the
+*  eigenvalues and, optionally, the left and/or right eigenvectors.
+*
+*  The right eigenvector v(j) of A satisfies
+*                   A * v(j) = lambda(j) * v(j)
+*  where lambda(j) is its eigenvalue.
+*  The left eigenvector u(j) of A satisfies
+*                u(j)**H * A = lambda(j) * u(j)**H
+*  where u(j)**H denotes the conjugate transpose of u(j).
+*
+*  The computed eigenvectors are normalized to have Euclidean norm
+*  equal to 1 and largest component real.
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N': left eigenvectors of A are not computed;
+*          = 'V': left eigenvectors of A are computed.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N': right eigenvectors of A are not computed;
+*          = 'V': right eigenvectors of A are computed.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  WR      (output) DOUBLE PRECISION array, dimension (N)
+*  WI      (output) DOUBLE PRECISION array, dimension (N)
+*          WR and WI contain the real and imaginary parts,
+*          respectively, of the computed eigenvalues.  Complex
+*          conjugate pairs of eigenvalues appear consecutively
+*          with the eigenvalue having the positive imaginary part
+*          first.
+*
+*  VL      (output) DOUBLE PRECISION array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
+*          after another in the columns of VL, in the same order
+*          as their eigenvalues.
+*          If JOBVL = 'N', VL is not referenced.
+*          If the j-th eigenvalue is real, then u(j) = VL(:,j),
+*          the j-th column of VL.
+*          If the j-th and (j+1)-st eigenvalues form a complex
+*          conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and
+*          u(j+1) = VL(:,j) - i*VL(:,j+1).
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1; if
+*          JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) DOUBLE PRECISION array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
+*          after another in the columns of VR, in the same order
+*          as their eigenvalues.
+*          If JOBVR = 'N', VR is not referenced.
+*          If the j-th eigenvalue is real, then v(j) = VR(:,j),
+*          the j-th column of VR.
+*          If the j-th and (j+1)-st eigenvalues form a complex
+*          conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and
+*          v(j+1) = VR(:,j) - i*VR(:,j+1).
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1; if
+*          JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,3*N), and
+*          if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N.  For good
+*          performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = i, the QR algorithm failed to compute all the
+*                eigenvalues, and no eigenvectors have been computed;
+*                elements i+1:N of WR and WI contain eigenvalues which
+*                have converged.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
+      CHARACTER          SIDE
+      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
+     $                   MAXWRK, MINWRK, NOUT
+      DOUBLE PRECISION   ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
+     $                   SN
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            SELECT( 1 )
+      DOUBLE PRECISION   DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,
+     $                   DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX, ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE, DLAPY2, DNRM2
+      EXTERNAL           LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,
+     $                   DNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      WANTVL = LSAME( JOBVL, 'V' )
+      WANTVR = LSAME( JOBVR, 'V' )
+      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -9
+      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by DHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            MAXWRK = 1
+         ELSE
+            MAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
+            IF( WANTVL ) THEN
+               MINWRK = 4*N
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'DORGHR', ' ', N, 1, N, -1 ) )
+               CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
+     $                WORK, -1, INFO )
+               HSWORK = WORK( 1 )
+               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               MAXWRK = MAX( MAXWRK, 4*N )
+            ELSE IF( WANTVR ) THEN
+               MINWRK = 4*N
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'DORGHR', ' ', N, 1, N, -1 ) )
+               CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
+     $                WORK, -1, INFO )
+               HSWORK = WORK( 1 )
+               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               MAXWRK = MAX( MAXWRK, 4*N )
+            ELSE 
+               MINWRK = 3*N
+               CALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,
+     $                WORK, -1, INFO )
+               HSWORK = WORK( 1 )
+               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+            END IF
+            MAXWRK = MAX( MAXWRK, MINWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*     Balance the matrix
+*     (Workspace: need N)
+*
+      IBAL = 1
+      CALL DGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (Workspace: need 3*N, prefer 2*N+N*NB)
+*
+      ITAU = IBAL + N
+      IWRK = ITAU + N
+      CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVL ) THEN
+*
+*        Want left eigenvectors
+*        Copy Householder vectors to VL
+*
+         SIDE = 'L'
+         CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )
+*
+*        Generate orthogonal matrix in VL
+*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*
+         CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VL
+*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
+*
+         IWRK = ITAU
+         CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+         IF( WANTVR ) THEN
+*
+*           Want left and right eigenvectors
+*           Copy Schur vectors to VR
+*
+            SIDE = 'B'
+            CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
+         END IF
+*
+      ELSE IF( WANTVR ) THEN
+*
+*        Want right eigenvectors
+*        Copy Householder vectors to VR
+*
+         SIDE = 'R'
+         CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )
+*
+*        Generate orthogonal matrix in VR
+*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*
+         CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VR
+*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
+*
+         IWRK = ITAU
+         CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+      ELSE
+*
+*        Compute eigenvalues only
+*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
+*
+         IWRK = ITAU
+         CALL DHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+      END IF
+*
+*     If INFO > 0 from DHSEQR, then quit
+*
+      IF( INFO.GT.0 )
+     $   GO TO 50
+*
+      IF( WANTVL .OR. WANTVR ) THEN
+*
+*        Compute left and/or right eigenvectors
+*        (Workspace: need 4*N)
+*
+         CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                N, NOUT, WORK( IWRK ), IERR )
+      END IF
+*
+      IF( WANTVL ) THEN
+*
+*        Undo balancing of left eigenvectors
+*        (Workspace: need N)
+*
+         CALL DGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,
+     $                IERR )
+*
+*        Normalize left eigenvectors and make largest component real
+*
+         DO 20 I = 1, N
+            IF( WI( I ).EQ.ZERO ) THEN
+               SCL = ONE / DNRM2( N, VL( 1, I ), 1 )
+               CALL DSCAL( N, SCL, VL( 1, I ), 1 )
+            ELSE IF( WI( I ).GT.ZERO ) THEN
+               SCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),
+     $               DNRM2( N, VL( 1, I+1 ), 1 ) )
+               CALL DSCAL( N, SCL, VL( 1, I ), 1 )
+               CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )
+               DO 10 K = 1, N
+                  WORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**2
+   10          CONTINUE
+               K = IDAMAX( N, WORK( IWRK ), 1 )
+               CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )
+               CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )
+               VL( K, I+1 ) = ZERO
+            END IF
+   20    CONTINUE
+      END IF
+*
+      IF( WANTVR ) THEN
+*
+*        Undo balancing of right eigenvectors
+*        (Workspace: need N)
+*
+         CALL DGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,
+     $                IERR )
+*
+*        Normalize right eigenvectors and make largest component real
+*
+         DO 40 I = 1, N
+            IF( WI( I ).EQ.ZERO ) THEN
+               SCL = ONE / DNRM2( N, VR( 1, I ), 1 )
+               CALL DSCAL( N, SCL, VR( 1, I ), 1 )
+            ELSE IF( WI( I ).GT.ZERO ) THEN
+               SCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),
+     $               DNRM2( N, VR( 1, I+1 ), 1 ) )
+               CALL DSCAL( N, SCL, VR( 1, I ), 1 )
+               CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )
+               DO 30 K = 1, N
+                  WORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**2
+   30          CONTINUE
+               K = IDAMAX( N, WORK( IWRK ), 1 )
+               CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )
+               CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )
+               VR( K, I+1 ) = ZERO
+            END IF
+   40    CONTINUE
+      END IF
+*
+*     Undo scaling if necessary
+*
+   50 CONTINUE
+      IF( SCALEA ) THEN
+         CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),
+     $                MAX( N-INFO, 1 ), IERR )
+         CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),
+     $                MAX( N-INFO, 1 ), IERR )
+         IF( INFO.GT.0 ) THEN
+            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,
+     $                   IERR )
+            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
+     $                   IERR )
+         END IF
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of DGEEV
+*
+      END
diff --git a/libcruft/lapack/dgehd2.f b/libcruft/lapack/dgehd2.f
new file mode 100644
index 0000000..28d1cc8
--- /dev/null
+++ b/libcruft/lapack/dgehd2.f
@@ -0,0 +1,149 @@
+      SUBROUTINE DGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEHD2 reduces a real general matrix A to upper Hessenberg form H by
+*  an orthogonal similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to DGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= max(1,N).
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the n by n general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the orthogonal matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEHD2', -INFO )
+         RETURN
+      END IF
+*
+      DO 10 I = ILO, IHI - 1
+*
+*        Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)
+*
+         CALL DLARFG( IHI-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,
+     $                TAU( I ) )
+         AII = A( I+1, I )
+         A( I+1, I ) = ONE
+*
+*        Apply H(i) to A(1:ihi,i+1:ihi) from the right
+*
+         CALL DLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ),
+     $               A( 1, I+1 ), LDA, WORK )
+*
+*        Apply H(i) to A(i+1:ihi,i+1:n) from the left
+*
+         CALL DLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1, TAU( I ),
+     $               A( I+1, I+1 ), LDA, WORK )
+*
+         A( I+1, I ) = AII
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of DGEHD2
+*
+      END
diff --git a/libcruft/lapack/dgehrd.f b/libcruft/lapack/dgehrd.f
new file mode 100644
index 0000000..339ee40
--- /dev/null
+++ b/libcruft/lapack/dgehrd.f
@@ -0,0 +1,273 @@
+      SUBROUTINE DGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION  A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEHRD reduces a real general matrix A to upper Hessenberg form H by
+*  an orthogonal similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to DGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the orthogonal matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to
+*          zero.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's DGEHRD
+*  subroutine incorporating improvements proposed by Quintana-Orti and
+*  Van de Geijn (2005). 
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+      DOUBLE PRECISION  ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, 
+     $                     ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NH, NX
+      DOUBLE PRECISION  EI
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION  T( LDT, NBMAX )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DGEHD2, DGEMM, DLAHR2, DLARFB, DTRMM,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MIN( NBMAX, ILAENV( 1, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEHRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero
+*
+      DO 10 I = 1, ILO - 1
+         TAU( I ) = ZERO
+   10 CONTINUE
+      DO 20 I = MAX( 1, IHI ), N - 1
+         TAU( I ) = ZERO
+   20 CONTINUE
+*
+*     Quick return if possible
+*
+      NH = IHI - ILO + 1
+      IF( NH.LE.1 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Determine the block size
+*
+      NB = MIN( NBMAX, ILAENV( 1, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )
+      NBMIN = 2
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.NH ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code)
+*
+         NX = MAX( NB, ILAENV( 3, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )
+         IF( NX.LT.NH ) THEN
+*
+*           Determine if workspace is large enough for blocked code
+*
+            IWS = N*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code
+*
+               NBMIN = MAX( 2, ILAENV( 2, 'DGEHRD', ' ', N, ILO, IHI,
+     $                 -1 ) )
+               IF( LWORK.GE.N*NBMIN ) THEN
+                  NB = LWORK / N
+               ELSE
+                  NB = 1
+               END IF
+            END IF
+         END IF
+      END IF
+      LDWORK = N
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN
+*
+*        Use unblocked code below
+*
+         I = ILO
+*
+      ELSE
+*
+*        Use blocked code
+*
+         DO 40 I = ILO, IHI - 1 - NX, NB
+            IB = MIN( NB, IHI-I )
+*
+*           Reduce columns i:i+ib-1 to Hessenberg form, returning the
+*           matrices V and T of the block reflector H = I - V*T*V'
+*           which performs the reduction, and also the matrix Y = A*V*T
+*
+            CALL DLAHR2( IHI, I, IB, A( 1, I ), LDA, TAU( I ), T, LDT,
+     $                   WORK, LDWORK )
+*
+*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the
+*           right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set
+*           to 1
+*
+            EI = A( I+IB, I+IB-1 )
+            A( I+IB, I+IB-1 ) = ONE
+            CALL DGEMM( 'No transpose', 'Transpose', 
+     $                  IHI, IHI-I-IB+1,
+     $                  IB, -ONE, WORK, LDWORK, A( I+IB, I ), LDA, ONE,
+     $                  A( 1, I+IB ), LDA )
+            A( I+IB, I+IB-1 ) = EI
+*
+*           Apply the block reflector H to A(1:i,i+1:i+ib-1) from the
+*           right
+*
+            CALL DTRMM( 'Right', 'Lower', 'Transpose',
+     $                  'Unit', I, IB-1,
+     $                  ONE, A( I+1, I ), LDA, WORK, LDWORK )
+            DO 30 J = 0, IB-2
+               CALL DAXPY( I, -ONE, WORK( LDWORK*J+1 ), 1,
+     $                     A( 1, I+J+1 ), 1 )
+   30       CONTINUE
+*
+*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the
+*           left
+*
+            CALL DLARFB( 'Left', 'Transpose', 'Forward',
+     $                   'Columnwise',
+     $                   IHI-I, N-I-IB+1, IB, A( I+1, I ), LDA, T, LDT,
+     $                   A( I+1, I+IB ), LDA, WORK, LDWORK )
+   40    CONTINUE
+      END IF
+*
+*     Use unblocked code to reduce the rest of the matrix
+*
+      CALL DGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )
+      WORK( 1 ) = IWS
+*
+      RETURN
+*
+*     End of DGEHRD
+*
+      END
diff --git a/libcruft/lapack/dgelq2.f b/libcruft/lapack/dgelq2.f
new file mode 100644
index 0000000..f354050
--- /dev/null
+++ b/libcruft/lapack/dgelq2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE DGELQ2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGELQ2 computes an LQ factorization of a real m by n matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m by min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k) . . . H(2) H(1), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGELQ2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i,i+1:n)
+*
+         CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,
+     $                TAU( I ) )
+         IF( I.LT.M ) THEN
+*
+*           Apply H(i) to A(i+1:m,i:n) from the right
+*
+            AII = A( I, I )
+            A( I, I ) = ONE
+            CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ),
+     $                  A( I+1, I ), LDA, WORK )
+            A( I, I ) = AII
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of DGELQ2
+*
+      END
diff --git a/libcruft/lapack/dgelqf.f b/libcruft/lapack/dgelqf.f
new file mode 100644
index 0000000..063a38b
--- /dev/null
+++ b/libcruft/lapack/dgelqf.f
@@ -0,0 +1,195 @@
+      SUBROUTINE DGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGELQF computes an LQ factorization of a real M-by-N matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m-by-min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k) . . . H(2) H(1), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGELQ2, DLARFB, DLARFT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+      LWKOPT = M*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGELQF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'DGELQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'DGELQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the LQ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL DGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i+ib:m,i:n) from the right
+*
+               CALL DLARFB( 'Right', 'No transpose', 'Forward',
+     $                      'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),
+     $                      LDA, WORK, LDWORK, A( I+IB, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL DGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DGELQF
+*
+      END
diff --git a/libcruft/lapack/dgelsd.f b/libcruft/lapack/dgelsd.f
new file mode 100644
index 0000000..123e5ea
--- /dev/null
+++ b/libcruft/lapack/dgelsd.f
@@ -0,0 +1,528 @@
+      SUBROUTINE DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, IWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGELSD computes the minimum-norm solution to a real linear least
+*  squares problem:
+*      minimize 2-norm(| b - A*x |)
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The problem is solved in three steps:
+*  (1) Reduce the coefficient matrix A to bidiagonal form with
+*      Householder transformations, reducing the original problem
+*      into a "bidiagonal least squares problem" (BLS)
+*  (2) Solve the BLS using a divide and conquer approach.
+*  (3) Apply back all the Householder tranformations to solve
+*      the original least squares problem.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  The divide and conquer algorithm makes very mild assumptions about
+*  floating point arithmetic. It will work on machines with a guard
+*  digit in add/subtract, or on those binary machines without guard
+*  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
+*  Cray-2. It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution
+*          matrix X.  If m >= n and RANK = n, the residual
+*          sum-of-squares for the solution in the i-th column is given
+*          by the sum of squares of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,max(M,N)).
+*
+*  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) DOUBLE PRECISION
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK must be at least 1.
+*          The exact minimum amount of workspace needed depends on M,
+*          N and NRHS. As long as LWORK is at least
+*              12*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2,
+*          if M is greater than or equal to N or
+*              12*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS + (SMLSIZ+1)**2,
+*          if M is less than N, the code will execute correctly.
+*          SMLSIZ is returned by ILAENV and is equal to the maximum
+*          size of the subproblems at the bottom of the computation
+*          tree (usually about 25), and
+*             NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
+*          LIWORK >= 3 * MINMN * NLVL + 11 * MINMN,
+*          where MINMN = MIN( M,N ).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
+     $                   LDWORK, MAXMN, MAXWRK, MINMN, MINWRK, MM,
+     $                   MNTHR, NLVL, NWORK, SMLSIZ, WLALSD
+      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEBRD, DGELQF, DGEQRF, DLABAD, DLACPY, DLALSD,
+     $                   DLASCL, DLASET, DORMBR, DORMLQ, DORMQR, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           ILAENV, DLAMCH, DLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, INT, LOG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      MNTHR = ILAENV( 6, 'DGELSD', ' ', M, N, NRHS, -1 )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+      SMLSIZ = ILAENV( 9, 'DGELSD', ' ', 0, 0, 0, 0 )
+*
+*     Compute workspace.
+*     (Note: Comments in the code beginning "Workspace:" describe the
+*     minimal amount of workspace needed at that point in the code,
+*     as well as the preferred amount for good performance.
+*     NB refers to the optimal block size for the immediately
+*     following subroutine, as returned by ILAENV.)
+*
+      MINWRK = 1
+      MINMN = MAX( 1, MINMN )
+      NLVL = MAX( INT( LOG( DBLE( MINMN ) / DBLE( SMLSIZ+1 ) ) /
+     $       LOG( TWO ) ) + 1, 0 )
+*
+      IF( INFO.EQ.0 ) THEN
+         MAXWRK = 0
+         MM = M
+         IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns.
+*
+            MM = N
+            MAXWRK = MAX( MAXWRK, N+N*ILAENV( 1, 'DGEQRF', ' ', M, N,
+     $               -1, -1 ) )
+            MAXWRK = MAX( MAXWRK, N+NRHS*
+     $               ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N, -1 ) )
+         END IF
+         IF( M.GE.N ) THEN
+*
+*           Path 1 - overdetermined or exactly determined.
+*
+            MAXWRK = MAX( MAXWRK, 3*N+( MM+N )*
+     $               ILAENV( 1, 'DGEBRD', ' ', MM, N, -1, -1 ) )
+            MAXWRK = MAX( MAXWRK, 3*N+NRHS*
+     $               ILAENV( 1, 'DORMBR', 'QLT', MM, NRHS, N, -1 ) )
+            MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
+     $               ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, N, -1 ) )
+            WLALSD = 9*N+2*N*SMLSIZ+8*N*NLVL+N*NRHS+(SMLSIZ+1)**2
+            MAXWRK = MAX( MAXWRK, 3*N+WLALSD )
+            MINWRK = MAX( 3*N+MM, 3*N+NRHS, 3*N+WLALSD )
+         END IF
+         IF( N.GT.M ) THEN
+            WLALSD = 9*M+2*M*SMLSIZ+8*M*NLVL+M*NRHS+(SMLSIZ+1)**2
+            IF( N.GE.MNTHR ) THEN
+*
+*              Path 2a - underdetermined, with many more columns
+*              than rows.
+*
+               MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+               MAXWRK = MAX( MAXWRK, M*M+4*M+2*M*
+     $                  ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, M*M+4*M+NRHS*
+     $                  ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, M, -1 ) )
+               MAXWRK = MAX( MAXWRK, M*M+4*M+( M-1 )*
+     $                  ILAENV( 1, 'DORMBR', 'PLN', M, NRHS, M, -1 ) )
+               IF( NRHS.GT.1 ) THEN
+                  MAXWRK = MAX( MAXWRK, M*M+M+M*NRHS )
+               ELSE
+                  MAXWRK = MAX( MAXWRK, M*M+2*M )
+               END IF
+               MAXWRK = MAX( MAXWRK, M+NRHS*
+     $                  ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M, -1 ) )
+               MAXWRK = MAX( MAXWRK, M*M+4*M+WLALSD )
+            ELSE
+*
+*              Path 2 - remaining underdetermined cases.
+*
+               MAXWRK = 3*M + ( N+M )*ILAENV( 1, 'DGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               MAXWRK = MAX( MAXWRK, 3*M+NRHS*
+     $                  ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*M+M*
+     $                  ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, M, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*M+WLALSD )
+            END IF
+            MINWRK = MAX( 3*M+NRHS, 3*M+M, 3*M+WLALSD )
+         END IF
+         MINWRK = MIN( MINWRK, MAXWRK )
+         WORK( 1 ) = MAXWRK
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGELSD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         GO TO 10
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters.
+*
+      EPS = DLAMCH( 'P' )
+      SFMIN = DLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max entry outside range [SMLNUM,BIGNUM].
+*
+      ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM.
+*
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
+         RANK = 0
+         GO TO 10
+      END IF
+*
+*     Scale B if max entry outside range [SMLNUM,BIGNUM].
+*
+      BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM.
+*
+         CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     If M < N make sure certain entries of B are zero.
+*
+      IF( M.LT.N )
+     $   CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
+*
+*     Overdetermined case.
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined.
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns.
+*
+            MM = N
+            ITAU = 1
+            NWORK = ITAU + N
+*
+*           Compute A=Q*R.
+*           (Workspace: need 2*N, prefer N+N*NB)
+*
+            CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                   LWORK-NWORK+1, INFO )
+*
+*           Multiply B by transpose(Q).
+*           (Workspace: need N+NRHS, prefer N+NRHS*NB)
+*
+            CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*           Zero out below R.
+*
+            IF( N.GT.1 ) THEN
+               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+            END IF
+         END IF
+*
+         IE = 1
+         ITAUQ = IE + N
+         ITAUP = ITAUQ + N
+         NWORK = ITAUP + N
+*
+*        Bidiagonalize R in A.
+*        (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)
+*
+         CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R.
+*        (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)
+*
+         CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL DLALSD( 'U', SMLSIZ, N, NRHS, S, WORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of R.
+*
+         CALL DORMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
+     $         MAX( M, 2*M-4, NRHS, N-3*M, WLALSD ) ) THEN
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm.
+*
+         LDWORK = M
+         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
+     $       M*LDA+M+M*NRHS, 4*M+M*LDA+WLALSD ) )LDWORK = LDA
+         ITAU = 1
+         NWORK = M + 1
+*
+*        Compute A=L*Q.
+*        (Workspace: need 2*M, prefer M+M*NB)
+*
+         CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+         IL = NWORK
+*
+*        Copy L to WORK(IL), zeroing out above its diagonal.
+*
+         CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         IE = IL + LDWORK*M
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+*
+*        Bidiagonalize L in WORK(IL).
+*        (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)
+*
+         CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L.
+*        (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
+*
+         CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL DLALSD( 'U', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of L.
+*
+         CALL DORMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUP ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Zero out below first M rows of B.
+*
+         CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
+         NWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B.
+*        (Workspace: need M+NRHS, prefer M+NRHS*NB)
+*
+         CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases.
+*
+         IE = 1
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+*
+*        Bidiagonalize A.
+*        (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+         CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors.
+*        (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)
+*
+         CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL DLALSD( 'L', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of A.
+*
+         CALL DORMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      END IF
+*
+*     Undo scaling.
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   10 CONTINUE
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of DGELSD
+*
+      END
diff --git a/libcruft/lapack/dgelss.f b/libcruft/lapack/dgelss.f
new file mode 100644
index 0000000..f024e13
--- /dev/null
+++ b/libcruft/lapack/dgelss.f
@@ -0,0 +1,617 @@
+      SUBROUTINE DGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGELSS computes the minimum norm solution to a real linear least
+*  squares problem:
+*
+*  Minimize 2-norm(| b - A*x |).
+*
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
+*  X.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the first min(m,n) rows of A are overwritten with
+*          its right singular vectors, stored rowwise.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution
+*          matrix X.  If m >= n and RANK = n, the residual
+*          sum-of-squares for the solution in the i-th column is given
+*          by the sum of squares of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,max(M,N)).
+*
+*  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) DOUBLE PRECISION
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= 1, and also:
+*          LWORK >= 3*min(M,N) + max( 2*min(M,N), max(M,N), NRHS )
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,
+     $                   ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
+     $                   MAXWRK, MINMN, MINWRK, MM, MNTHR
+      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   VDUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DBDSQR, DCOPY, DGEBRD, DGELQF, DGEMM, DGEMV,
+     $                   DGEQRF, DLABAD, DLACPY, DLASCL, DLASET, DORGBR,
+     $                   DORMBR, DORMLQ, DORMQR, DRSCL, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           ILAENV, DLAMCH, DLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( MINMN.GT.0 ) THEN
+            MM = M
+            MNTHR = ILAENV( 6, 'DGELSS', ' ', M, N, NRHS, -1 )
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'DGEQRF', ' ', M,
+     $                       N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'DORMQR', 'LT',
+     $                       M, NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined
+*
+*              Compute workspace needed for DBDSQR
+*
+               BDSPAC = MAX( 1, 5*N )
+               MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
+     $                       'DGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'DORMBR',
+     $                       'QLT', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
+     $                       'DORGBR', 'P', N, N, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, BDSPAC )
+               MAXWRK = MAX( MAXWRK, N*NRHS )
+               MINWRK = MAX( 3*N + MM, 3*N + NRHS, BDSPAC )
+               MAXWRK = MAX( MINWRK, MAXWRK )
+            END IF
+            IF( N.GT.M ) THEN
+*
+*              Compute workspace needed for DBDSQR
+*
+               BDSPAC = MAX( 1, 5*M )
+               MINWRK = MAX( 3*M+NRHS, 3*M+N, BDSPAC )
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                 than rows
+*
+                  MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
+     $                                  -1 )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
+     $                          'DGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
+     $                          'DORMBR', 'QLT', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M +
+     $                          ( M - 1 )*ILAENV( 1, 'DORGBR', 'P', M,
+     $                          M, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + M + BDSPAC )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'DORMLQ',
+     $                          'LT', N, NRHS, M, -1 ) )
+               ELSE
+*
+*                 Path 2 - underdetermined
+*
+                  MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'DGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'DORMBR',
+     $                          'QLT', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'DORGBR',
+     $                          'P', M, N, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, BDSPAC )
+                  MAXWRK = MAX( MAXWRK, N*NRHS )
+               END IF
+            END IF
+            MAXWRK = MAX( MINWRK, MAXWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
+     $      INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGELSS', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      EPS = DLAMCH( 'P' )
+      SFMIN = DLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Overdetermined case
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns
+*
+            MM = N
+            ITAU = 1
+            IWORK = ITAU + N
+*
+*           Compute A=Q*R
+*           (Workspace: need 2*N, prefer N+N*NB)
+*
+            CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                   LWORK-IWORK+1, INFO )
+*
+*           Multiply B by transpose(Q)
+*           (Workspace: need N+NRHS, prefer N+NRHS*NB)
+*
+            CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*           Zero out below R
+*
+            IF( N.GT.1 )
+     $         CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+         END IF
+*
+         IE = 1
+         ITAUQ = IE + N
+         ITAUP = ITAUQ + N
+         IWORK = ITAUP + N
+*
+*        Bidiagonalize R in A
+*        (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)
+*
+         CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R
+*        (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)
+*
+         CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in A
+*        (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+         CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IWORK = IE + N
+*
+*        Perform bidiagonal QR iteration
+*          multiply B by transpose of left singular vectors
+*          compute right singular vectors in A
+*        (Workspace: need BDSPAC)
+*
+         CALL DBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, WORK( IWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 10 I = 1, N
+            IF( S( I ).GT.THR ) THEN
+               CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            END IF
+   10    CONTINUE
+*
+*        Multiply B by right singular vectors
+*        (Workspace: need N, prefer N*NRHS)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, A, LDA, B, LDB, ZERO,
+     $                  WORK, LDB )
+            CALL DLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 20 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL DGEMM( 'T', 'N', N, BL, N, ONE, A, LDA, B( 1, I ),
+     $                     LDB, ZERO, WORK, N )
+               CALL DLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB )
+   20       CONTINUE
+         ELSE
+            CALL DGEMV( 'T', N, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )
+            CALL DCOPY( N, WORK, 1, B, 1 )
+         END IF
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
+     $         MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm
+*
+         LDWORK = M
+         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
+     $       M*LDA+M+M*NRHS ) )LDWORK = LDA
+         ITAU = 1
+         IWORK = M + 1
+*
+*        Compute A=L*Q
+*        (Workspace: need 2*M, prefer M+M*NB)
+*
+         CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+         IL = IWORK
+*
+*        Copy L to WORK(IL), zeroing out above it
+*
+         CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         IE = IL + LDWORK*M
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize L in WORK(IL)
+*        (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)
+*
+         CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L
+*        (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
+*
+         CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in WORK(IL)
+*        (Workspace: need M*M+5*M-1, prefer M*M+4*M+(M-1)*NB)
+*
+         CALL DORGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IWORK = IE + M
+*
+*        Perform bidiagonal QR iteration,
+*           computing right singular vectors of L in WORK(IL) and
+*           multiplying B by transpose of left singular vectors
+*        (Workspace: need M*M+M+BDSPAC)
+*
+         CALL DBDSQR( 'U', M, M, 0, NRHS, S, WORK( IE ), WORK( IL ),
+     $                LDWORK, A, LDA, B, LDB, WORK( IWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 30 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            END IF
+   30    CONTINUE
+         IWORK = IE
+*
+*        Multiply B by right singular vectors of L in WORK(IL)
+*        (Workspace: need M*M+2*M, prefer M*M+M+M*NRHS)
+*
+         IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN
+            CALL DGEMM( 'T', 'N', M, NRHS, M, ONE, WORK( IL ), LDWORK,
+     $                  B, LDB, ZERO, WORK( IWORK ), LDB )
+            CALL DLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = ( LWORK-IWORK+1 ) / M
+            DO 40 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL DGEMM( 'T', 'N', M, BL, M, ONE, WORK( IL ), LDWORK,
+     $                     B( 1, I ), LDB, ZERO, WORK( IWORK ), M )
+               CALL DLACPY( 'G', M, BL, WORK( IWORK ), M, B( 1, I ),
+     $                      LDB )
+   40       CONTINUE
+         ELSE
+            CALL DGEMV( 'T', M, M, ONE, WORK( IL ), LDWORK, B( 1, 1 ),
+     $                  1, ZERO, WORK( IWORK ), 1 )
+            CALL DCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 )
+         END IF
+*
+*        Zero out below first M rows of B
+*
+         CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
+         IWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B
+*        (Workspace: need M+NRHS, prefer M+NRHS*NB)
+*
+         CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases
+*
+         IE = 1
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize A
+*        (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+         CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors
+*        (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)
+*
+         CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors in A
+*        (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+         CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IWORK = IE + M
+*
+*        Perform bidiagonal QR iteration,
+*           computing right singular vectors of A in A and
+*           multiplying B by transpose of left singular vectors
+*        (Workspace: need BDSPAC)
+*
+         CALL DBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, WORK( IWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 50 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            END IF
+   50    CONTINUE
+*
+*        Multiply B by right singular vectors of A
+*        (Workspace: need N, prefer N*NRHS)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL DGEMM( 'T', 'N', N, NRHS, M, ONE, A, LDA, B, LDB, ZERO,
+     $                  WORK, LDB )
+            CALL DLACPY( 'F', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 60 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL DGEMM( 'T', 'N', N, BL, M, ONE, A, LDA, B( 1, I ),
+     $                     LDB, ZERO, WORK, N )
+               CALL DLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB )
+   60       CONTINUE
+         ELSE
+            CALL DGEMV( 'T', M, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )
+            CALL DCOPY( N, WORK, 1, B, 1 )
+         END IF
+      END IF
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   70 CONTINUE
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of DGELSS
+*
+      END
diff --git a/libcruft/lapack/dgelsy.f b/libcruft/lapack/dgelsy.f
new file mode 100644
index 0000000..4334650
--- /dev/null
+++ b/libcruft/lapack/dgelsy.f
@@ -0,0 +1,391 @@
+      SUBROUTINE DGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGELSY computes the minimum-norm solution to a real linear least
+*  squares problem:
+*      minimize || A * X - B ||
+*  using a complete orthogonal factorization of A.  A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The routine first computes a QR factorization with column pivoting:
+*      A * P = Q * [ R11 R12 ]
+*                  [  0  R22 ]
+*  with R11 defined as the largest leading submatrix whose estimated
+*  condition number is less than 1/RCOND.  The order of R11, RANK,
+*  is the effective rank of A.
+*
+*  Then, R22 is considered to be negligible, and R12 is annihilated
+*  by orthogonal transformations from the right, arriving at the
+*  complete orthogonal factorization:
+*     A * P = Q * [ T11 0 ] * Z
+*                 [  0  0 ]
+*  The minimum-norm solution is then
+*     X = P * Z' [ inv(T11)*Q1'*B ]
+*                [        0       ]
+*  where Q1 consists of the first RANK columns of Q.
+*
+*  This routine is basically identical to the original xGELSX except
+*  three differences:
+*    o The call to the subroutine xGEQPF has been substituted by the
+*      the call to the subroutine xGEQP3. This subroutine is a Blas-3
+*      version of the QR factorization with column pivoting.
+*    o Matrix B (the right hand side) is updated with Blas-3.
+*    o The permutation of matrix B (the right hand side) is faster and
+*      more simple.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of
+*          columns of matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been overwritten by details of its
+*          complete orthogonal factorization.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,M,N).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of AP, otherwise column i is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of AP
+*          was the k-th column of A.
+*
+*  RCOND   (input) DOUBLE PRECISION
+*          RCOND is used to determine the effective rank of A, which
+*          is defined as the order of the largest leading triangular
+*          submatrix R11 in the QR factorization with pivoting of A,
+*          whose estimated condition number < 1/RCOND.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the order of the submatrix
+*          R11.  This is the same as the order of the submatrix T11
+*          in the complete orthogonal factorization of A.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          The unblocked strategy requires that:
+*             LWORK >= MAX( MN+3*N+1, 2*MN+NRHS ),
+*          where MN = min( M, N ).
+*          The block algorithm requires that:
+*             LWORK >= MAX( MN+2*N+NB*(N+1), 2*MN+NB*NRHS ),
+*          where NB is an upper bound on the blocksize returned
+*          by ILAENV for the routines DGEQP3, DTZRZF, STZRQF, DORMQR,
+*          and DORMRZ.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: If INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*    E. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            IMAX, IMIN
+      PARAMETER          ( IMAX = 1, IMIN = 2 )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
+     $                   LWKOPT, MN, NB, NB1, NB2, NB3, NB4
+      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
+     $                   SMAXPR, SMIN, SMINPR, SMLNUM, WSIZE
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           ILAENV, DLAMCH, DLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEQP3, DLABAD, DLAIC1, DLASCL, DLASET,
+     $                   DORMQR, DORMRZ, DTRSM, DTZRZF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M, N )
+      ISMIN = MN + 1
+      ISMAX = 2*MN + 1
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Figure out optimal block size
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THEN
+            LWKMIN = 1
+            LWKOPT = 1
+         ELSE
+            NB1 = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+            NB2 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )
+            NB3 = ILAENV( 1, 'DORMQR', ' ', M, N, NRHS, -1 )
+            NB4 = ILAENV( 1, 'DORMRQ', ' ', M, N, NRHS, -1 )
+            NB = MAX( NB1, NB2, NB3, NB4 )
+            LWKMIN = MN + MAX( 2*MN, N + 1, MN + NRHS )
+            LWKOPT = MAX( LWKMIN,
+     $                    MN + 2*N + NB*( N + 1 ), 2*MN + NB*NRHS )
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGELSY', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A, B if max entries outside range [SMLNUM,BIGNUM]
+*
+      ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+      BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Compute QR factorization with column pivoting of A:
+*        A * P = Q * R
+*
+      CALL DGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
+     $             LWORK-MN, INFO )
+      WSIZE = MN + WORK( MN+1 )
+*
+*     workspace: MN+2*N+NB*(N+1).
+*     Details of Householder rotations stored in WORK(1:MN).
+*
+*     Determine RANK using incremental condition estimation
+*
+      WORK( ISMIN ) = ONE
+      WORK( ISMAX ) = ONE
+      SMAX = ABS( A( 1, 1 ) )
+      SMIN = SMAX
+      IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
+         RANK = 0
+         CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         GO TO 70
+      ELSE
+         RANK = 1
+      END IF
+*
+   10 CONTINUE
+      IF( RANK.LT.MN ) THEN
+         I = RANK + 1
+         CALL DLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
+     $                A( I, I ), SMINPR, S1, C1 )
+         CALL DLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
+     $                A( I, I ), SMAXPR, S2, C2 )
+*
+         IF( SMAXPR*RCOND.LE.SMINPR ) THEN
+            DO 20 I = 1, RANK
+               WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
+               WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
+   20       CONTINUE
+            WORK( ISMIN+RANK ) = C1
+            WORK( ISMAX+RANK ) = C2
+            SMIN = SMINPR
+            SMAX = SMAXPR
+            RANK = RANK + 1
+            GO TO 10
+         END IF
+      END IF
+*
+*     workspace: 3*MN.
+*
+*     Logically partition R = [ R11 R12 ]
+*                             [  0  R22 ]
+*     where R11 = R(1:RANK,1:RANK)
+*
+*     [R11,R12] = [ T11, 0 ] * Y
+*
+      IF( RANK.LT.N )
+     $   CALL DTZRZF( RANK, N, A, LDA, WORK( MN+1 ), WORK( 2*MN+1 ),
+     $                LWORK-2*MN, INFO )
+*
+*     workspace: 2*MN.
+*     Details of Householder rotations stored in WORK(MN+1:2*MN)
+*
+*     B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
+*
+      CALL DORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),
+     $             B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
+      WSIZE = MAX( WSIZE, 2*MN+WORK( 2*MN+1 ) )
+*
+*     workspace: 2*MN+NB*NRHS.
+*
+*     B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
+*
+      CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
+     $            NRHS, ONE, A, LDA, B, LDB )
+*
+      DO 40 J = 1, NRHS
+         DO 30 I = RANK + 1, N
+            B( I, J ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+*
+*     B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
+*
+      IF( RANK.LT.N ) THEN
+         CALL DORMRZ( 'Left', 'Transpose', N, NRHS, RANK, N-RANK, A,
+     $                LDA, WORK( MN+1 ), B, LDB, WORK( 2*MN+1 ),
+     $                LWORK-2*MN, INFO )
+      END IF
+*
+*     workspace: 2*MN+NRHS.
+*
+*     B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
+*
+      DO 60 J = 1, NRHS
+         DO 50 I = 1, N
+            WORK( JPVT( I ) ) = B( I, J )
+   50    CONTINUE
+         CALL DCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )
+   60 CONTINUE
+*
+*     workspace: N.
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   70 CONTINUE
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of DGELSY
+*
+      END
diff --git a/libcruft/lapack/dgeqp3.f b/libcruft/lapack/dgeqp3.f
new file mode 100644
index 0000000..d6bc537
--- /dev/null
+++ b/libcruft/lapack/dgeqp3.f
@@ -0,0 +1,287 @@
+      SUBROUTINE DGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEQP3 computes a QR factorization with column pivoting of a
+*  matrix A:  A*P = Q*R  using Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper trapezoidal matrix R; the elements below
+*          the diagonal, together with the array TAU, represent the
+*          orthogonal matrix Q as a product of min(M,N) elementary
+*          reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(J).ne.0, the J-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(J)=0,
+*          the J-th column of A is a free column.
+*          On exit, if JPVT(J)=K, then the J-th column of A*P was the
+*          the K-th column of A.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= 3*N+1.
+*          For optimal performance LWORK >= 2*N+( N+1 )*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit.
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real/complex scalar, and v is a real/complex vector
+*  with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
+*  A(i+1:m,i), and tau in TAU(i).
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            INB, INBMIN, IXOVER
+      PARAMETER          ( INB = 1, INBMIN = 2, IXOVER = 3 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,
+     $                   NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEQRF, DLAQP2, DLAQPS, DORMQR, DSWAP, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DNRM2
+      EXTERNAL           ILAENV, DNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test input arguments
+*     ====================
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         MINMN = MIN( M, N )
+         IF( MINMN.EQ.0 ) THEN
+            IWS = 1
+            LWKOPT = 1
+         ELSE
+            IWS = 3*N + 1
+            NB = ILAENV( INB, 'DGEQRF', ' ', M, N, -1, -1 )
+            LWKOPT = 2*N + ( N + 1 )*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEQP3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( MINMN.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Move initial columns up front.
+*
+      NFXD = 1
+      DO 10 J = 1, N
+         IF( JPVT( J ).NE.0 ) THEN
+            IF( J.NE.NFXD ) THEN
+               CALL DSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
+               JPVT( J ) = JPVT( NFXD )
+               JPVT( NFXD ) = J
+            ELSE
+               JPVT( J ) = J
+            END IF
+            NFXD = NFXD + 1
+         ELSE
+            JPVT( J ) = J
+         END IF
+   10 CONTINUE
+      NFXD = NFXD - 1
+*
+*     Factorize fixed columns
+*     =======================
+*
+*     Compute the QR factorization of fixed columns and update
+*     remaining columns.
+*
+      IF( NFXD.GT.0 ) THEN
+         NA = MIN( M, NFXD )
+*CC      CALL DGEQR2( M, NA, A, LDA, TAU, WORK, INFO )
+         CALL DGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
+         IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         IF( NA.LT.N ) THEN
+*CC         CALL DORM2R( 'Left', 'Transpose', M, N-NA, NA, A, LDA,
+*CC  $                   TAU, A( 1, NA+1 ), LDA, WORK, INFO )
+            CALL DORMQR( 'Left', 'Transpose', M, N-NA, NA, A, LDA, TAU,
+     $                   A( 1, NA+1 ), LDA, WORK, LWORK, INFO )
+            IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         END IF
+      END IF
+*
+*     Factorize free columns
+*     ======================
+*
+      IF( NFXD.LT.MINMN ) THEN
+*
+         SM = M - NFXD
+         SN = N - NFXD
+         SMINMN = MINMN - NFXD
+*
+*        Determine the block size.
+*
+         NB = ILAENV( INB, 'DGEQRF', ' ', SM, SN, -1, -1 )
+         NBMIN = 2
+         NX = 0
+*
+         IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
+*
+*           Determine when to cross over from blocked to unblocked code.
+*
+            NX = MAX( 0, ILAENV( IXOVER, 'DGEQRF', ' ', SM, SN, -1,
+     $           -1 ) )
+*
+*
+            IF( NX.LT.SMINMN ) THEN
+*
+*              Determine if workspace is large enough for blocked code.
+*
+               MINWS = 2*SN + ( SN+1 )*NB
+               IWS = MAX( IWS, MINWS )
+               IF( LWORK.LT.MINWS ) THEN
+*
+*                 Not enough workspace to use optimal NB: Reduce NB and
+*                 determine the minimum value of NB.
+*
+                  NB = ( LWORK-2*SN ) / ( SN+1 )
+                  NBMIN = MAX( 2, ILAENV( INBMIN, 'DGEQRF', ' ', SM, SN,
+     $                    -1, -1 ) )
+*
+*
+               END IF
+            END IF
+         END IF
+*
+*        Initialize partial column norms. The first N elements of work
+*        store the exact column norms.
+*
+         DO 20 J = NFXD + 1, N
+            WORK( J ) = DNRM2( SM, A( NFXD+1, J ), 1 )
+            WORK( N+J ) = WORK( J )
+   20    CONTINUE
+*
+         IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
+     $       ( NX.LT.SMINMN ) ) THEN
+*
+*           Use blocked code initially.
+*
+            J = NFXD + 1
+*
+*           Compute factorization: while loop.
+*
+*
+            TOPBMN = MINMN - NX
+   30       CONTINUE
+            IF( J.LE.TOPBMN ) THEN
+               JB = MIN( NB, TOPBMN-J+1 )
+*
+*              Factorize JB columns among columns J:N.
+*
+               CALL DLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
+     $                      JPVT( J ), TAU( J ), WORK( J ), WORK( N+J ),
+     $                      WORK( 2*N+1 ), WORK( 2*N+JB+1 ), N-J+1 )
+*
+               J = J + FJB
+               GO TO 30
+            END IF
+         ELSE
+            J = NFXD + 1
+         END IF
+*
+*        Use unblocked code to factor the last or only block.
+*
+*
+         IF( J.LE.MINMN )
+     $      CALL DLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
+     $                   TAU( J ), WORK( J ), WORK( N+J ),
+     $                   WORK( 2*N+1 ) )
+*
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DGEQP3
+*
+      END
diff --git a/libcruft/lapack/dgeqpf.f b/libcruft/lapack/dgeqpf.f
new file mode 100644
index 0000000..1b7acd6
--- /dev/null
+++ b/libcruft/lapack/dgeqpf.f
@@ -0,0 +1,231 @@
+      SUBROUTINE DGEQPF( M, N, A, LDA, JPVT, TAU, WORK, INFO )
+*
+*  -- LAPACK deprecated driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This routine is deprecated and has been replaced by routine DGEQP3.
+*
+*  DGEQPF computes a QR factorization with column pivoting of a
+*  real M-by-N matrix A: A*P = Q*R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper triangular matrix R; the elements
+*          below the diagonal, together with the array TAU,
+*          represent the orthogonal matrix Q as a product of
+*          min(m,n) elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(n)
+*
+*  Each H(i) has the form
+*
+*     H = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i).
+*
+*  The matrix P is represented in jpvt as follows: If
+*     jpvt(j) = i
+*  then the jth column of P is the ith canonical unit vector.
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MA, MN, PVT
+      DOUBLE PRECISION   AII, TEMP, TEMP2, TOL3Z
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEQR2, DLARF, DLARFG, DORM2R, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DNRM2
+      EXTERNAL           IDAMAX, DLAMCH, DNRM2
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEQPF', -INFO )
+         RETURN
+      END IF
+*
+      MN = MIN( M, N )
+      TOL3Z = SQRT(DLAMCH('Epsilon'))
+*
+*     Move initial columns up front
+*
+      ITEMP = 1
+      DO 10 I = 1, N
+         IF( JPVT( I ).NE.0 ) THEN
+            IF( I.NE.ITEMP ) THEN
+               CALL DSWAP( M, A( 1, I ), 1, A( 1, ITEMP ), 1 )
+               JPVT( I ) = JPVT( ITEMP )
+               JPVT( ITEMP ) = I
+            ELSE
+               JPVT( I ) = I
+            END IF
+            ITEMP = ITEMP + 1
+         ELSE
+            JPVT( I ) = I
+         END IF
+   10 CONTINUE
+      ITEMP = ITEMP - 1
+*
+*     Compute the QR factorization and update remaining columns
+*
+      IF( ITEMP.GT.0 ) THEN
+         MA = MIN( ITEMP, M )
+         CALL DGEQR2( M, MA, A, LDA, TAU, WORK, INFO )
+         IF( MA.LT.N ) THEN
+            CALL DORM2R( 'Left', 'Transpose', M, N-MA, MA, A, LDA, TAU,
+     $                   A( 1, MA+1 ), LDA, WORK, INFO )
+         END IF
+      END IF
+*
+      IF( ITEMP.LT.MN ) THEN
+*
+*        Initialize partial column norms. The first n elements of
+*        work store the exact column norms.
+*
+         DO 20 I = ITEMP + 1, N
+            WORK( I ) = DNRM2( M-ITEMP, A( ITEMP+1, I ), 1 )
+            WORK( N+I ) = WORK( I )
+   20    CONTINUE
+*
+*        Compute factorization
+*
+         DO 40 I = ITEMP + 1, MN
+*
+*           Determine ith pivot column and swap if necessary
+*
+            PVT = ( I-1 ) + IDAMAX( N-I+1, WORK( I ), 1 )
+*
+            IF( PVT.NE.I ) THEN
+               CALL DSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+               ITEMP = JPVT( PVT )
+               JPVT( PVT ) = JPVT( I )
+               JPVT( I ) = ITEMP
+               WORK( PVT ) = WORK( I )
+               WORK( N+PVT ) = WORK( N+I )
+            END IF
+*
+*           Generate elementary reflector H(i)
+*
+            IF( I.LT.M ) THEN
+               CALL DLARFG( M-I+1, A( I, I ), A( I+1, I ), 1, TAU( I ) )
+            ELSE
+               CALL DLARFG( 1, A( M, M ), A( M, M ), 1, TAU( M ) )
+            END IF
+*
+            IF( I.LT.N ) THEN
+*
+*              Apply H(i) to A(i:m,i+1:n) from the left
+*
+               AII = A( I, I )
+               A( I, I ) = ONE
+               CALL DLARF( 'LEFT', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                     A( I, I+1 ), LDA, WORK( 2*N+1 ) )
+               A( I, I ) = AII
+            END IF
+*
+*           Update partial column norms
+*
+            DO 30 J = I + 1, N
+               IF( WORK( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*                 
+                  TEMP = ABS( A( I, J ) ) / WORK( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( WORK( J ) / WORK( N+J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN 
+                     IF( M-I.GT.0 ) THEN
+                        WORK( J ) = DNRM2( M-I, A( I+1, J ), 1 )
+                        WORK( N+J ) = WORK( J )
+                     ELSE
+                        WORK( J ) = ZERO
+                        WORK( N+J ) = ZERO
+                     END IF
+                  ELSE
+                     WORK( J ) = WORK( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   30       CONTINUE
+*
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DGEQPF
+*
+      END
diff --git a/libcruft/lapack/dgeqr2.f b/libcruft/lapack/dgeqr2.f
new file mode 100644
index 0000000..9872a16
--- /dev/null
+++ b/libcruft/lapack/dgeqr2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE DGEQR2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEQR2 computes a QR factorization of a real m by n matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(m,n) by n upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEQR2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+         CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                TAU( I ) )
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i) to A(i:m,i+1:n) from the left
+*
+            AII = A( I, I )
+            A( I, I ) = ONE
+            CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                  A( I, I+1 ), LDA, WORK )
+            A( I, I ) = AII
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of DGEQR2
+*
+      END
diff --git a/libcruft/lapack/dgeqrf.f b/libcruft/lapack/dgeqrf.f
new file mode 100644
index 0000000..1e94059
--- /dev/null
+++ b/libcruft/lapack/dgeqrf.f
@@ -0,0 +1,196 @@
+      SUBROUTINE DGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGEQRF computes a QR factorization of a real M-by-N matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(M,N)-by-N upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of min(m,n) elementary reflectors (see Further
+*          Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEQR2, DLARFB, DLARFT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGEQRF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'DGEQRF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'DGEQRF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the QR factorization of the current block
+*           A(i:m,i:i+ib-1)
+*
+            CALL DGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i:m,i+ib:n) from the left
+*
+               CALL DLARFB( 'Left', 'Transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL DGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DGEQRF
+*
+      END
diff --git a/libcruft/lapack/dgesv.f b/libcruft/lapack/dgesv.f
new file mode 100644
index 0000000..220ef56
--- /dev/null
+++ b/libcruft/lapack/dgesv.f
@@ -0,0 +1,107 @@
+      SUBROUTINE DGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGESV computes the solution to a real system of linear equations
+*     A * X = B,
+*  where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
+*
+*  The LU decomposition with partial pivoting and row interchanges is
+*  used to factor A as
+*     A = P * L * U,
+*  where P is a permutation matrix, L is unit lower triangular, and U is
+*  upper triangular.  The factored form of A is then used to solve the
+*  system of equations A * X = B.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of linear equations, i.e., the order of the
+*          matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the N-by-N coefficient matrix A.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices that define the permutation matrix P;
+*          row i of the matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS matrix of right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero.  The factorization
+*                has been completed, but the factor U is exactly
+*                singular, so the solution could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           DGETRF, DGETRS, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGESV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the LU factorization of A.
+*
+      CALL DGETRF( N, N, A, LDA, IPIV, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL DGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, B, LDB,
+     $                INFO )
+      END IF
+      RETURN
+*
+*     End of DGESV
+*
+      END
diff --git a/libcruft/lapack/dgesvd.f b/libcruft/lapack/dgesvd.f
new file mode 100644
index 0000000..0b62ca1
--- /dev/null
+++ b/libcruft/lapack/dgesvd.f
@@ -0,0 +1,3401 @@
+      SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBU, JOBVT
+      INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), S( * ), U( LDU, * ),
+     $                   VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGESVD computes the singular value decomposition (SVD) of a real
+*  M-by-N matrix A, optionally computing the left and/or right singular
+*  vectors. The SVD is written
+*
+*       A = U * SIGMA * transpose(V)
+*
+*  where SIGMA is an M-by-N matrix which is zero except for its
+*  min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
+*  V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
+*  are the singular values of A; they are real and non-negative, and
+*  are returned in descending order.  The first min(m,n) columns of
+*  U and V are the left and right singular vectors of A.
+*
+*  Note that the routine returns V**T, not V.
+*
+*  Arguments
+*  =========
+*
+*  JOBU    (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix U:
+*          = 'A':  all M columns of U are returned in array U:
+*          = 'S':  the first min(m,n) columns of U (the left singular
+*                  vectors) are returned in the array U;
+*          = 'O':  the first min(m,n) columns of U (the left singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no columns of U (no left singular vectors) are
+*                  computed.
+*
+*  JOBVT   (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix
+*          V**T:
+*          = 'A':  all N rows of V**T are returned in the array VT;
+*          = 'S':  the first min(m,n) rows of V**T (the right singular
+*                  vectors) are returned in the array VT;
+*          = 'O':  the first min(m,n) rows of V**T (the right singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no rows of V**T (no right singular vectors) are
+*                  computed.
+*
+*          JOBVT and JOBU cannot both be 'O'.
+*
+*  M       (input) INTEGER
+*          The number of rows of the input matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the input matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit,
+*          if JOBU = 'O',  A is overwritten with the first min(m,n)
+*                          columns of U (the left singular vectors,
+*                          stored columnwise);
+*          if JOBVT = 'O', A is overwritten with the first min(m,n)
+*                          rows of V**T (the right singular vectors,
+*                          stored rowwise);
+*          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
+*                          are destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The singular values of A, sorted so that S(i) >= S(i+1).
+*
+*  U       (output) DOUBLE PRECISION array, dimension (LDU,UCOL)
+*          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
+*          If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
+*          if JOBU = 'S', U contains the first min(m,n) columns of U
+*          (the left singular vectors, stored columnwise);
+*          if JOBU = 'N' or 'O', U is not referenced.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= 1; if
+*          JOBU = 'S' or 'A', LDU >= M.
+*
+*  VT      (output) DOUBLE PRECISION array, dimension (LDVT,N)
+*          If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
+*          V**T;
+*          if JOBVT = 'S', VT contains the first min(m,n) rows of
+*          V**T (the right singular vectors, stored rowwise);
+*          if JOBVT = 'N' or 'O', VT is not referenced.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.  LDVT >= 1; if
+*          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
+*          if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
+*          superdiagonal elements of an upper bidiagonal matrix B
+*          whose diagonal is in S (not necessarily sorted). B
+*          satisfies A = U * B * VT, so it has the same singular values
+*          as A, and singular vectors related by U and VT.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if DBDSQR did not converge, INFO specifies how many
+*                superdiagonals of an intermediate bidiagonal form B
+*                did not converge to zero. See the description of WORK
+*                above for details.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
+     $                   WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
+      INTEGER            BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,
+     $                   ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
+     $                   MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
+     $                   NRVT, WRKBL
+      DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DBDSQR, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,
+     $                   DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           LSAME, ILAENV, DLAMCH, DLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      WNTUA = LSAME( JOBU, 'A' )
+      WNTUS = LSAME( JOBU, 'S' )
+      WNTUAS = WNTUA .OR. WNTUS
+      WNTUO = LSAME( JOBU, 'O' )
+      WNTUN = LSAME( JOBU, 'N' )
+      WNTVA = LSAME( JOBVT, 'A' )
+      WNTVS = LSAME( JOBVT, 'S' )
+      WNTVAS = WNTVA .OR. WNTVS
+      WNTVO = LSAME( JOBVT, 'O' )
+      WNTVN = LSAME( JOBVT, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
+     $         ( WNTVO .AND. WNTUO ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
+         INFO = -9
+      ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
+     $         ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( M.GE.N .AND. MINMN.GT.0 ) THEN
+*
+*           Compute space needed for DBDSQR
+*
+            MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            BDSPAC = 5*N
+            IF( M.GE.MNTHR ) THEN
+               IF( WNTUN ) THEN
+*
+*                 Path 1 (M much larger than N, JOBU='N')
+*
+                  MAXWRK = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 3*N+2*N*
+     $                     ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  IF( WNTVO .OR. WNTVAS )
+     $               MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
+     $                        ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = MAX( MAXWRK, BDSPAC )
+                  MINWRK = MAX( 4*N, BDSPAC )
+               ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUS .AND. WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUS .AND. WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUS .AND. WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUA .AND. WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUA .AND. WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUA .AND. WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               END IF
+            ELSE
+*
+*              Path 10 (M at least N, but not much larger)
+*
+               MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTUS .OR. WNTUO )
+     $            MAXWRK = MAX( MAXWRK, 3*N+N*
+     $                     ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 ) )
+               IF( WNTUA )
+     $            MAXWRK = MAX( MAXWRK, 3*N+M*
+     $                     ILAENV( 1, 'DORGBR', 'Q', M, M, N, -1 ) )
+               IF( .NOT.WNTVN )
+     $            MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
+     $                     ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, BDSPAC )
+               MINWRK = MAX( 3*N+M, BDSPAC )
+            END IF
+         ELSE IF( MINMN.GT.0 ) THEN
+*
+*           Compute space needed for DBDSQR
+*
+            MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            BDSPAC = 5*M
+            IF( N.GE.MNTHR ) THEN
+               IF( WNTVN ) THEN
+*
+*                 Path 1t(N much larger than M, JOBVT='N')
+*
+                  MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M+2*M*
+     $                     ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  IF( WNTUO .OR. WNTUAS )
+     $               MAXWRK = MAX( MAXWRK, 3*M+M*
+     $                        ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, BDSPAC )
+                  MINWRK = MAX( 4*M, BDSPAC )
+               ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*                 Path 3t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVS .AND. WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVS .AND. WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVS .AND. WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVA .AND. WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVA .AND. WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVA .AND. WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               END IF
+            ELSE
+*
+*              Path 10t(N greater than M, but not much larger)
+*
+               MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTVS .OR. WNTVO )
+     $            MAXWRK = MAX( MAXWRK, 3*M+M*
+     $                     ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) )
+               IF( WNTVA )
+     $            MAXWRK = MAX( MAXWRK, 3*M+N*
+     $                     ILAENV( 1, 'DORGBR', 'P', N, N, M, -1 ) )
+               IF( .NOT.WNTUN )
+     $            MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
+     $                     ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+               MAXWRK = MAX( MAXWRK, BDSPAC )
+               MINWRK = MAX( 3*M+N, BDSPAC )
+            END IF
+         END IF
+         MAXWRK = MAX( MAXWRK, MINWRK )
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGESVD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = DLANGE( 'M', M, N, A, LDA, DUM )
+      ISCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ISCL = 1
+         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ISCL = 1
+         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        A has at least as many rows as columns. If A has sufficiently
+*        more rows than columns, first reduce using the QR
+*        decomposition (if sufficient workspace available)
+*
+         IF( M.GE.MNTHR ) THEN
+*
+            IF( WNTUN ) THEN
+*
+*              Path 1 (M much larger than N, JOBU='N')
+*              No left singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + N
+*
+*              Compute A=Q*R
+*              (Workspace: need 2*N, prefer N+N*NB)
+*
+               CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out below R
+*
+               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+               IE = 1
+               ITAUQ = IE + N
+               ITAUP = ITAUQ + N
+               IWORK = ITAUP + N
+*
+*              Bidiagonalize R in A
+*              (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+               CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               NCVT = 0
+               IF( WNTVO .OR. WNTVAS ) THEN
+*
+*                 If right singular vectors desired, generate P'.
+*                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                  CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  NCVT = N
+               END IF
+               IWORK = IE + N
+*
+*              Perform bidiagonal QR iteration, computing right
+*              singular vectors of A in A if desired
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,
+     $                      DUM, 1, DUM, 1, WORK( IWORK ), INFO )
+*
+*              If right singular vectors desired in VT, copy them there
+*
+               IF( WNTVAS )
+     $            CALL DLACPY( 'F', N, N, A, LDA, VT, LDVT )
+*
+            ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*              Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*              N left singular vectors to be overwritten on A and
+*              no right singular vectors to be computed
+*
+               IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N, WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N-N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to WORK(IR) and zero out below it
+*
+                  CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
+                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
+     $                         LDWRKR )
+*
+*                 Generate Q in A
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in WORK(IR)
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                  CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing R
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                  CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR)
+*                 (Workspace: need N*N+BDSPAC)
+*
+                  CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,
+     $                         WORK( IR ), LDWRKR, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + N
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
+*
+                  DO 10 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   10             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize A
+*                 (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*
+                  CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing A
+*                 (Workspace: need 4*N, prefer 3*N+N*NB)
+*
+                  CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A
+*                 (Workspace: need BDSPAC)
+*
+                  CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,
+     $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*              Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
+*              N left singular vectors to be overwritten on A and
+*              N right singular vectors to be computed in VT
+*
+               IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N and WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N-N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT, copying result to WORK(IR)
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                  CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
+*
+*                 Generate left vectors bidiagonalizing R in WORK(IR)
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                  CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)
+*
+                  CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR) and computing right
+*                 singular vectors of R in VT
+*                 (Workspace: need N*N+BDSPAC)
+*
+                  CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,
+     $                         WORK( IR ), LDWRKR, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + N
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
+*
+                  DO 20 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   20             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (Workspace: need 2*N, prefer N+N*NB)
+*
+                  CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (Workspace: need 2*N, prefer N+N*NB)
+*
+                  CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT
+*                 (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                  CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply Q in A by left vectors bidiagonalizing R
+*                 (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                  CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                  CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A and computing right
+*                 singular vectors of A in VT
+*                 (Workspace: need BDSPAC)
+*
+                  CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,
+     $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUS ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*                 N left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left vectors bidiagonalizing R in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
+     $                            1, WORK( IR ), LDWRKR, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IR), storing result in U
+*                    (Workspace: need N*N)
+*
+                     CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
+     $                           WORK( IR ), LDWRKR, ZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
+     $                            1, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*
+                     CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*N*N+4*N,
+*                                prefer 2*N*N+3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
+*
+                     CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*N*N+4*N-1,
+*                                prefer 2*N*N+3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (Workspace: need 2*N*N+BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (Workspace: need N*N)
+*
+                     CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
+*
+*                    Copy right singular vectors of R to A
+*                    (Workspace: need N*N)
+*
+                     CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing R in A
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
+     $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S'
+*                         or 'A')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need N*N+4*N-1,
+*                                prefer N*N+3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (Workspace: need N*N)
+*
+                     CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to VT, zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTUA ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*                 M left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in U
+*                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*
+                     CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
+     $                            1, WORK( IR ), LDWRKR, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IR), storing result in A
+*                    (Workspace: need N*N)
+*
+                     CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
+     $                           WORK( IR ), LDWRKR, ZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N+M, prefer N+M*NB)
+*
+                     CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
+     $                            1, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
+*
+                     CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*N*N+4*N,
+*                                prefer 2*N*N+3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
+*
+                     CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*N*N+4*N-1,
+*                                prefer 2*N*N+3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (Workspace: need 2*N*N+BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (Workspace: need N*N)
+*
+                     CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+*                    Copy right singular vectors of R from WORK(IR) to A
+*
+                     CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N+M, prefer N+M*NB)
+*
+                     CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in A
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
+     $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S'
+*                         or 'A')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*
+                     CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need N*N+4*N-1,
+*                                prefer N*N+3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (Workspace: need N*N)
+*
+                     CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N+M, prefer N+M*NB)
+*
+                     CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R from A to VT, zeroing out below it
+*
+                     CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           M .LT. MNTHR
+*
+*           Path 10 (M at least N, but not much larger)
+*           Reduce to bidiagonal form without QR decomposition
+*
+            IE = 1
+            ITAUQ = IE + N
+            ITAUP = ITAUQ + N
+            IWORK = ITAUP + N
+*
+*           Bidiagonalize A
+*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*
+            CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)
+*
+               CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
+               IF( WNTUS )
+     $            NCU = N
+               IF( WNTUA )
+     $            NCU = M
+               CALL DORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+               CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
+               CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*N, prefer 3*N+N*NB)
+*
+               CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+               CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IWORK = IE + N
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
+     $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
+            END IF
+*
+         END IF
+*
+      ELSE
+*
+*        A has more columns than rows. If A has sufficiently more
+*        columns than rows, first reduce using the LQ decomposition (if
+*        sufficient workspace available)
+*
+         IF( N.GE.MNTHR ) THEN
+*
+            IF( WNTVN ) THEN
+*
+*              Path 1t(N much larger than M, JOBVT='N')
+*              No right singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + M
+*
+*              Compute A=L*Q
+*              (Workspace: need 2*M, prefer M+M*NB)
+*
+               CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out above L
+*
+               CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
+               IE = 1
+               ITAUQ = IE + M
+               ITAUP = ITAUQ + M
+               IWORK = ITAUP + M
+*
+*              Bidiagonalize L in A
+*              (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+               CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               IF( WNTUO .OR. WNTUAS ) THEN
+*
+*                 If left singular vectors desired, generate Q
+*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                  CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+               END IF
+               IWORK = IE + M
+               NRU = 0
+               IF( WNTUO .OR. WNTUAS )
+     $            NRU = M
+*
+*              Perform bidiagonal QR iteration, computing left singular
+*              vectors of A in A if desired
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,
+     $                      LDA, DUM, 1, WORK( IWORK ), INFO )
+*
+*              If left singular vectors desired in U, copy them there
+*
+               IF( WNTUAS )
+     $            CALL DLACPY( 'F', M, M, A, LDA, U, LDU )
+*
+            ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*              Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              no left singular vectors to be computed
+*
+               IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M-M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to WORK(IR) and zero out above it
+*
+                  CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
+                  CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                         WORK( IR+LDWRKR ), LDWRKR )
+*
+*                 Generate Q in A
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in WORK(IR)
+*                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                  CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing L
+*                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*
+                  CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of L in WORK(IR)
+*                 (Workspace: need M*M+BDSPAC)
+*
+                  CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
+     $                         WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + M
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (Workspace: need M*M+2*M, prefer M*M+M*N+M)
+*
+                  DO 30 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   30             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize A
+*                 (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+                  CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing A
+*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                  CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of A in A
+*                 (Workspace: need BDSPAC)
+*
+                  CALL DBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,
+     $                         DUM, 1, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*              Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              M left singular vectors to be computed in U
+*
+               IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M-M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing about above it
+*
+                  CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U, copying result to WORK(IR)
+*                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                  CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
+*
+*                 Generate right vectors bidiagonalizing L in WORK(IR)
+*                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*
+                  CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*
+                  CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of L in U, and computing right
+*                 singular vectors of L in WORK(IR)
+*                 (Workspace: need M*M+BDSPAC)
+*
+                  CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                         WORK( IR ), LDWRKR, U, LDU, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + M
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (Workspace: need M*M+2*M, prefer M*M+M*N+M))
+*
+                  DO 40 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   40             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (Workspace: need 2*M, prefer M+M*NB)
+*
+                  CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing out above it
+*
+                  CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (Workspace: need 2*M, prefer M+M*NB)
+*
+                  CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U
+*                 (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                  CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply right vectors bidiagonalizing L by Q in A
+*                 (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                  CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
+     $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                  CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in U and computing right
+*                 singular vectors of A in A
+*                 (Workspace: need BDSPAC)
+*
+                  CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,
+     $                         U, LDU, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVS ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing L in
+*                    WORK(IR)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in A, storing result in VT
+*                    (Workspace: need M*M)
+*
+                     CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
+     $                           LDWRKR, A, LDA, ZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy result to VT
+*
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
+     $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out below it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*
+                     CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*M*M+4*M,
+*                                prefer 2*M*M+3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*M*M+4*M-1,
+*                                prefer 2*M*M+3*M+(M-1)*NB)
+*
+                     CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (Workspace: need 2*M*M+BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (Workspace: need M*M)
+*
+                     CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
+*
+*                    Copy left singular vectors of L to A
+*                    (Workspace: need M*M)
+*
+                     CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors of L in A
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, compute left
+*                    singular vectors of A in A and compute right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need M*M+4*M-1,
+*                                prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (Workspace: need M*M)
+*
+                     CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                            LDU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTVA ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
+*
+                     CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need M*M+4*M-1,
+*                                prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in VT, storing result in A
+*                    (Workspace: need M*M)
+*
+                     CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
+     $                           LDWRKR, VT, LDVT, ZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M+N, prefer M+N*NB)
+*
+                     CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
+     $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
+*
+                     CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*M*M+4*M,
+*                                prefer 2*M*M+3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*M*M+4*M-1,
+*                                prefer 2*M*M+3*M+(M-1)*NB)
+*
+                     CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (Workspace: need 2*M*M+BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (Workspace: need M*M)
+*
+                     CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy left singular vectors of A from WORK(IR) to A
+*
+                     CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M+N, prefer M+N*NB)
+*
+                     CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in A
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in A and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is M by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
+*
+                     CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (Workspace: need M*M)
+*
+                     CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M+N, prefer M+N*NB)
+*
+                     CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                            LDU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           N .LT. MNTHR
+*
+*           Path 10t(N greater than M, but not much larger)
+*           Reduce to bidiagonal form without LQ decomposition
+*
+            IE = 1
+            ITAUQ = IE + M
+            ITAUP = ITAUQ + M
+            IWORK = ITAUP + M
+*
+*           Bidiagonalize A
+*           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+            CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
+*
+               CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
+               CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)
+*
+               CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
+               IF( WNTVA )
+     $            NRVT = N
+               IF( WNTVS )
+     $            NRVT = M
+               CALL DORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
+*
+               CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+               CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IWORK = IE + M
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
+     $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
+            END IF
+*
+         END IF
+*
+      END IF
+*
+*     If DBDSQR failed to converge, copy unconverged superdiagonals
+*     to WORK( 2:MINMN )
+*
+      IF( INFO.NE.0 ) THEN
+         IF( IE.GT.2 ) THEN
+            DO 50 I = 1, MINMN - 1
+               WORK( I+1 ) = WORK( I+IE-1 )
+   50       CONTINUE
+         END IF
+         IF( IE.LT.2 ) THEN
+            DO 60 I = MINMN - 1, 1, -1
+               WORK( I+1 ) = WORK( I+IE-1 )
+   60       CONTINUE
+         END IF
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ISCL.EQ.1 ) THEN
+         IF( ANRM.GT.BIGNUM )
+     $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
+     $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),
+     $                   MINMN, IERR )
+         IF( ANRM.LT.SMLNUM )
+     $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
+     $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),
+     $                   MINMN, IERR )
+      END IF
+*
+*     Return optimal workspace in WORK(1)
+*
+      WORK( 1 ) = MAXWRK
+*
+      RETURN
+*
+*     End of DGESVD
+*
+      END
diff --git a/libcruft/lapack/dgetf2.f b/libcruft/lapack/dgetf2.f
new file mode 100644
index 0000000..573b140
--- /dev/null
+++ b/libcruft/lapack/dgetf2.f
@@ -0,0 +1,147 @@
+      SUBROUTINE DGETF2( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGETF2 computes an LU factorization of a general m-by-n matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the m by n matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, U(k,k) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   SFMIN 
+      INTEGER            I, J, JP
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH      
+      INTEGER            IDAMAX
+      EXTERNAL           DLAMCH, IDAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGER, DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGETF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Compute machine safe minimum 
+* 
+      SFMIN = DLAMCH('S')  
+*
+      DO 10 J = 1, MIN( M, N )
+*
+*        Find pivot and test for singularity.
+*
+         JP = J - 1 + IDAMAX( M-J+1, A( J, J ), 1 )
+         IPIV( J ) = JP
+         IF( A( JP, J ).NE.ZERO ) THEN
+*
+*           Apply the interchange to columns 1:N.
+*
+            IF( JP.NE.J )
+     $         CALL DSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA )
+*
+*           Compute elements J+1:M of J-th column.
+*
+            IF( J.LT.M ) THEN 
+               IF( ABS(A( J, J )) .GE. SFMIN ) THEN 
+                  CALL DSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 ) 
+               ELSE 
+                 DO 20 I = 1, M-J 
+                    A( J+I, J ) = A( J+I, J ) / A( J, J ) 
+   20            CONTINUE 
+               END IF 
+            END IF 
+*
+         ELSE IF( INFO.EQ.0 ) THEN
+*
+            INFO = J
+         END IF
+*
+         IF( J.LT.MIN( M, N ) ) THEN
+*
+*           Update trailing submatrix.
+*
+            CALL DGER( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ), LDA,
+     $                 A( J+1, J+1 ), LDA )
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of DGETF2
+*
+      END
diff --git a/libcruft/lapack/dgetrf.f b/libcruft/lapack/dgetrf.f
new file mode 100644
index 0000000..c5b9df3
--- /dev/null
+++ b/libcruft/lapack/dgetrf.f
@@ -0,0 +1,159 @@
+      SUBROUTINE DGETRF( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGETRF computes an LU factorization of a general M-by-N matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IINFO, J, JB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DGETF2, DLASWP, DTRSM, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGETRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'DGETRF', ' ', M, N, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN
+*
+*        Use unblocked code.
+*
+         CALL DGETF2( M, N, A, LDA, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         DO 20 J = 1, MIN( M, N ), NB
+            JB = MIN( MIN( M, N )-J+1, NB )
+*
+*           Factor diagonal and subdiagonal blocks and test for exact
+*           singularity.
+*
+            CALL DGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+*
+*           Adjust INFO and the pivot indices.
+*
+            IF( INFO.EQ.0 .AND. IINFO.GT.0 )
+     $         INFO = IINFO + J - 1
+            DO 10 I = J, MIN( M, J+JB-1 )
+               IPIV( I ) = J - 1 + IPIV( I )
+   10       CONTINUE
+*
+*           Apply interchanges to columns 1:J-1.
+*
+            CALL DLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 )
+*
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply interchanges to columns J+JB:N.
+*
+               CALL DLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1,
+     $                      IPIV, 1 )
+*
+*              Compute block row of U.
+*
+               CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB,
+     $                     N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ),
+     $                     LDA )
+               IF( J+JB.LE.M ) THEN
+*
+*                 Update trailing submatrix.
+*
+                  CALL DGEMM( 'No transpose', 'No transpose', M-J-JB+1,
+     $                        N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA,
+     $                        A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ),
+     $                        LDA )
+               END IF
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DGETRF
+*
+      END
diff --git a/libcruft/lapack/dgetri.f b/libcruft/lapack/dgetri.f
new file mode 100644
index 0000000..9f1c118
--- /dev/null
+++ b/libcruft/lapack/dgetri.f
@@ -0,0 +1,192 @@
+      SUBROUTINE DGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGETRI computes the inverse of a matrix using the LU factorization
+*  computed by DGETRF.
+*
+*  This method inverts U and then computes inv(A) by solving the system
+*  inv(A)*L = inv(U) for inv(A).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the factors L and U from the factorization
+*          A = P*L*U as computed by DGETRF.
+*          On exit, if INFO = 0, the inverse of the original matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from DGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, then WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimal performance LWORK >= N*NB, where NB is
+*          the optimal blocksize returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero; the matrix is
+*                singular and its inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DGEMV, DSWAP, DTRSM, DTRTRI, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NB = ILAENV( 1, 'DGETRI', ' ', N, -1, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -3
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGETRI', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form inv(U).  If INFO > 0 from DTRTRI, then U is singular,
+*     and the inverse is not computed.
+*
+      CALL DTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+      NBMIN = 2
+      LDWORK = N
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+         IWS = MAX( LDWORK*NB, 1 )
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'DGETRI', ' ', N, -1, -1, -1 ) )
+         END IF
+      ELSE
+         IWS = N
+      END IF
+*
+*     Solve the equation inv(A)*L = inv(U) for inv(A).
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         DO 20 J = N, 1, -1
+*
+*           Copy current column of L to WORK and replace with zeros.
+*
+            DO 10 I = J + 1, N
+               WORK( I ) = A( I, J )
+               A( I, J ) = ZERO
+   10       CONTINUE
+*
+*           Compute current column of inv(A).
+*
+            IF( J.LT.N )
+     $         CALL DGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),
+     $                     LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )
+   20    CONTINUE
+      ELSE
+*
+*        Use blocked code.
+*
+         NN = ( ( N-1 ) / NB )*NB + 1
+         DO 50 J = NN, 1, -NB
+            JB = MIN( NB, N-J+1 )
+*
+*           Copy current block column of L to WORK and replace with
+*           zeros.
+*
+            DO 40 JJ = J, J + JB - 1
+               DO 30 I = JJ + 1, N
+                  WORK( I+( JJ-J )*LDWORK ) = A( I, JJ )
+                  A( I, JJ ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+*
+*           Compute current block column of inv(A).
+*
+            IF( J+JB.LE.N )
+     $         CALL DGEMM( 'No transpose', 'No transpose', N, JB,
+     $                     N-J-JB+1, -ONE, A( 1, J+JB ), LDA,
+     $                     WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )
+            CALL DTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,
+     $                  ONE, WORK( J ), LDWORK, A( 1, J ), LDA )
+   50    CONTINUE
+      END IF
+*
+*     Apply column interchanges.
+*
+      DO 60 J = N - 1, 1, -1
+         JP = IPIV( J )
+         IF( JP.NE.J )
+     $      CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
+   60 CONTINUE
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DGETRI
+*
+      END
diff --git a/libcruft/lapack/dgetrs.f b/libcruft/lapack/dgetrs.f
new file mode 100644
index 0000000..b7d17b0
--- /dev/null
+++ b/libcruft/lapack/dgetrs.f
@@ -0,0 +1,149 @@
+      SUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGETRS solves a system of linear equations
+*     A * X = B  or  A' * X = B
+*  with a general N-by-N matrix A using the LU factorization computed
+*  by DGETRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A'* X = B  (Transpose)
+*          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by DGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from DGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASWP, DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGETRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve A * X = B.
+*
+*        Apply row interchanges to the right hand sides.
+*
+         CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, 1 )
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A' * X = B.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Unit', N, NRHS, ONE,
+     $               A, LDA, B, LDB )
+*
+*        Apply row interchanges to the solution vectors.
+*
+         CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, -1 )
+      END IF
+*
+      RETURN
+*
+*     End of DGETRS
+*
+      END
diff --git a/libcruft/lapack/dggbak.f b/libcruft/lapack/dggbak.f
new file mode 100644
index 0000000..8ed9fbd
--- /dev/null
+++ b/libcruft/lapack/dggbak.f
@@ -0,0 +1,220 @@
+      SUBROUTINE DGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,
+     $                   LDV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   LSCALE( * ), RSCALE( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGGBAK forms the right or left eigenvectors of a real generalized
+*  eigenvalue problem A*x = lambda*B*x, by backward transformation on
+*  the computed eigenvectors of the balanced pair of matrices output by
+*  DGGBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N':  do nothing, return immediately;
+*          = 'P':  do backward transformation for permutation only;
+*          = 'S':  do backward transformation for scaling only;
+*          = 'B':  do backward transformations for both permutation and
+*                  scaling.
+*          JOB must be the same as the argument JOB supplied to DGGBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by DGGBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  LSCALE  (input) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the left side of A and B, as returned by DGGBAL.
+*
+*  RSCALE  (input) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the right side of A and B, as returned by DGGBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) DOUBLE PRECISION array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by DTGEVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the matrix V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. Ward, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, K
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( N.EQ.0 .AND. IHI.EQ.0 .AND. ILO.NE.1 ) THEN
+         INFO = -4
+      ELSE IF( N.GT.0 .AND. ( IHI.LT.ILO .OR. IHI.GT.MAX( 1, N ) ) )
+     $   THEN
+         INFO = -5
+      ELSE IF( N.EQ.0 .AND. ILO.EQ.1 .AND. IHI.NE.0 ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -8
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGGBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward transformation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               CALL DSCAL( M, RSCALE( I ), V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+*        Backward transformation on left eigenvectors
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               CALL DSCAL( M, LSCALE( I ), V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Backward permutation
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward permutation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 50
+*
+            DO 40 I = ILO - 1, 1, -1
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+*
+   50       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 70
+            DO 60 I = IHI + 1, N
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 60
+               CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   60       CONTINUE
+         END IF
+*
+*        Backward permutation on left eigenvectors
+*
+   70    CONTINUE
+         IF( LEFTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 90
+            DO 80 I = ILO - 1, 1, -1
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 80
+               CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   80       CONTINUE
+*
+   90       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 110
+            DO 100 I = IHI + 1, N
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 100
+               CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+  100       CONTINUE
+         END IF
+      END IF
+*
+  110 CONTINUE
+*
+      RETURN
+*
+*     End of DGGBAK
+*
+      END
diff --git a/libcruft/lapack/dggbal.f b/libcruft/lapack/dggbal.f
new file mode 100644
index 0000000..2034880
--- /dev/null
+++ b/libcruft/lapack/dggbal.f
@@ -0,0 +1,469 @@
+      SUBROUTINE DGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
+     $                   RSCALE, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), LSCALE( * ),
+     $                   RSCALE( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGGBAL balances a pair of general real matrices (A,B).  This
+*  involves, first, permuting A and B by similarity transformations to
+*  isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
+*  elements on the diagonal; and second, applying a diagonal similarity
+*  transformation to rows and columns ILO to IHI to make the rows
+*  and columns as close in norm as possible. Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrices, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors in the
+*  generalized eigenvalue problem A*x = lambda*B*x.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A and B:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
+*                  and RSCALE(I) = 1.0 for i = 1,...,N.
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit,  A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
+*          On entry, the input matrix B.
+*          On exit,  B is overwritten by the balanced matrix.
+*          If JOB = 'N', B is not referenced.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 and B(i,j) = 0 if i > j and
+*          j = 1,...,ILO-1 or i = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  LSCALE  (output) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the left side of A and B.  If P(j) is the index of the
+*          row interchanged with row j, and D(j)
+*          is the scaling factor applied to row j, then
+*            LSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  RSCALE  (output) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the right side of A and B.  If P(j) is the index of the
+*          column interchanged with column j, and D(j)
+*          is the scaling factor applied to column j, then
+*            LSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  WORK    (workspace) REAL array, dimension (lwork)
+*          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
+*          at least 1 when JOB = 'N' or 'P'.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. WARD, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   THREE, SCLFAC
+      PARAMETER          ( THREE = 3.0D+0, SCLFAC = 1.0D+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
+     $                   K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
+     $                   M, NR, NRP2
+      DOUBLE PRECISION   ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
+     $                   COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
+     $                   SFMIN, SUM, T, TA, TB, TC
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DDOT, DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DSCAL, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, INT, LOG10, MAX, MIN, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGGBAL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         ILO = 1
+         IHI = N
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         ILO = 1
+         IHI = N
+         LSCALE( 1 ) = ONE
+         RSCALE( 1 ) = ONE
+         RETURN
+      END IF
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         ILO = 1
+         IHI = N
+         DO 10 I = 1, N
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 190
+*
+      GO TO 30
+*
+*     Permute the matrices A and B to isolate the eigenvalues.
+*
+*     Find row with one nonzero in columns 1 through L
+*
+   20 CONTINUE
+      L = LM1
+      IF( L.NE.1 )
+     $   GO TO 30
+*
+      RSCALE( 1 ) = ONE
+      LSCALE( 1 ) = ONE
+      GO TO 190
+*
+   30 CONTINUE
+      LM1 = L - 1
+      DO 80 I = L, 1, -1
+         DO 40 J = 1, LM1
+            JP1 = J + 1
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 50
+   40    CONTINUE
+         J = L
+         GO TO 70
+*
+   50    CONTINUE
+         DO 60 J = JP1, L
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 80
+   60    CONTINUE
+         J = JP1 - 1
+*
+   70    CONTINUE
+         M = L
+         IFLOW = 1
+         GO TO 160
+   80 CONTINUE
+      GO TO 100
+*
+*     Find column with one nonzero in rows K through N
+*
+   90 CONTINUE
+      K = K + 1
+*
+  100 CONTINUE
+      DO 150 J = K, L
+         DO 110 I = K, LM1
+            IP1 = I + 1
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 120
+  110    CONTINUE
+         I = L
+         GO TO 140
+  120    CONTINUE
+         DO 130 I = IP1, L
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 150
+  130    CONTINUE
+         I = IP1 - 1
+  140    CONTINUE
+         M = K
+         IFLOW = 2
+         GO TO 160
+  150 CONTINUE
+      GO TO 190
+*
+*     Permute rows M and I
+*
+  160 CONTINUE
+      LSCALE( M ) = I
+      IF( I.EQ.M )
+     $   GO TO 170
+      CALL DSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
+      CALL DSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
+*
+*     Permute columns M and J
+*
+  170 CONTINUE
+      RSCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 180
+      CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL DSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
+*
+  180 CONTINUE
+      GO TO ( 20, 90 )IFLOW
+*
+  190 CONTINUE
+      ILO = K
+      IHI = L
+*
+      IF( LSAME( JOB, 'P' ) ) THEN
+         DO 195 I = ILO, IHI
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+  195    CONTINUE
+         RETURN
+      END IF
+*
+      IF( ILO.EQ.IHI )
+     $   RETURN
+*
+*     Balance the submatrix in rows ILO to IHI.
+*
+      NR = IHI - ILO + 1
+      DO 200 I = ILO, IHI
+         RSCALE( I ) = ZERO
+         LSCALE( I ) = ZERO
+*
+         WORK( I ) = ZERO
+         WORK( I+N ) = ZERO
+         WORK( I+2*N ) = ZERO
+         WORK( I+3*N ) = ZERO
+         WORK( I+4*N ) = ZERO
+         WORK( I+5*N ) = ZERO
+  200 CONTINUE
+*
+*     Compute right side vector in resulting linear equations
+*
+      BASL = LOG10( SCLFAC )
+      DO 240 I = ILO, IHI
+         DO 230 J = ILO, IHI
+            TB = B( I, J )
+            TA = A( I, J )
+            IF( TA.EQ.ZERO )
+     $         GO TO 210
+            TA = LOG10( ABS( TA ) ) / BASL
+  210       CONTINUE
+            IF( TB.EQ.ZERO )
+     $         GO TO 220
+            TB = LOG10( ABS( TB ) ) / BASL
+  220       CONTINUE
+            WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
+            WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
+  230    CONTINUE
+  240 CONTINUE
+*
+      COEF = ONE / DBLE( 2*NR )
+      COEF2 = COEF*COEF
+      COEF5 = HALF*COEF2
+      NRP2 = NR + 2
+      BETA = ZERO
+      IT = 1
+*
+*     Start generalized conjugate gradient iteration
+*
+  250 CONTINUE
+*
+      GAMMA = DDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
+     $        DDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      EW = ZERO
+      EWC = ZERO
+      DO 260 I = ILO, IHI
+         EW = EW + WORK( I+4*N )
+         EWC = EWC + WORK( I+5*N )
+  260 CONTINUE
+*
+      GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
+      IF( GAMMA.EQ.ZERO )
+     $   GO TO 350
+      IF( IT.NE.1 )
+     $   BETA = GAMMA / PGAMMA
+      T = COEF5*( EWC-THREE*EW )
+      TC = COEF5*( EW-THREE*EWC )
+*
+      CALL DSCAL( NR, BETA, WORK( ILO ), 1 )
+      CALL DSCAL( NR, BETA, WORK( ILO+N ), 1 )
+*
+      CALL DAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
+      CALL DAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
+*
+      DO 270 I = ILO, IHI
+         WORK( I ) = WORK( I ) + TC
+         WORK( I+N ) = WORK( I+N ) + T
+  270 CONTINUE
+*
+*     Apply matrix to vector
+*
+      DO 300 I = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 290 J = ILO, IHI
+            IF( A( I, J ).EQ.ZERO )
+     $         GO TO 280
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  280       CONTINUE
+            IF( B( I, J ).EQ.ZERO )
+     $         GO TO 290
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  290    CONTINUE
+         WORK( I+2*N ) = DBLE( KOUNT )*WORK( I+N ) + SUM
+  300 CONTINUE
+*
+      DO 330 J = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 320 I = ILO, IHI
+            IF( A( I, J ).EQ.ZERO )
+     $         GO TO 310
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  310       CONTINUE
+            IF( B( I, J ).EQ.ZERO )
+     $         GO TO 320
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  320    CONTINUE
+         WORK( J+3*N ) = DBLE( KOUNT )*WORK( J ) + SUM
+  330 CONTINUE
+*
+      SUM = DDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
+     $      DDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
+      ALPHA = GAMMA / SUM
+*
+*     Determine correction to current iteration
+*
+      CMAX = ZERO
+      DO 340 I = ILO, IHI
+         COR = ALPHA*WORK( I+N )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         LSCALE( I ) = LSCALE( I ) + COR
+         COR = ALPHA*WORK( I )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         RSCALE( I ) = RSCALE( I ) + COR
+  340 CONTINUE
+      IF( CMAX.LT.HALF )
+     $   GO TO 350
+*
+      CALL DAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
+      CALL DAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      PGAMMA = GAMMA
+      IT = IT + 1
+      IF( IT.LE.NRP2 )
+     $   GO TO 250
+*
+*     End generalized conjugate gradient iteration
+*
+  350 CONTINUE
+      SFMIN = DLAMCH( 'S' )
+      SFMAX = ONE / SFMIN
+      LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
+      LSFMAX = INT( LOG10( SFMAX ) / BASL )
+      DO 360 I = ILO, IHI
+         IRAB = IDAMAX( N-ILO+1, A( I, ILO ), LDA )
+         RAB = ABS( A( I, IRAB+ILO-1 ) )
+         IRAB = IDAMAX( N-ILO+1, B( I, ILO ), LDB )
+         RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
+         LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
+         IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
+         IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
+         LSCALE( I ) = SCLFAC**IR
+         ICAB = IDAMAX( IHI, A( 1, I ), 1 )
+         CAB = ABS( A( ICAB, I ) )
+         ICAB = IDAMAX( IHI, B( 1, I ), 1 )
+         CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
+         LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
+         JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
+         JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
+         RSCALE( I ) = SCLFAC**JC
+  360 CONTINUE
+*
+*     Row scaling of matrices A and B
+*
+      DO 370 I = ILO, IHI
+         CALL DSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
+         CALL DSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
+  370 CONTINUE
+*
+*     Column scaling of matrices A and B
+*
+      DO 380 J = ILO, IHI
+         CALL DSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
+         CALL DSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
+  380 CONTINUE
+*
+      RETURN
+*
+*     End of DGGBAL
+*
+      END
diff --git a/libcruft/lapack/dggev.f b/libcruft/lapack/dggev.f
new file mode 100644
index 0000000..4a204c3
--- /dev/null
+++ b/libcruft/lapack/dggev.f
@@ -0,0 +1,489 @@
+      SUBROUTINE DGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,
+     $                  BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
+     $                   B( LDB, * ), BETA( * ), VL( LDVL, * ),
+     $                   VR( LDVR, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGGEV computes for a pair of N-by-N real nonsymmetric matrices (A,B)
+*  the generalized eigenvalues, and optionally, the left and/or right
+*  generalized eigenvectors.
+*
+*  A generalized eigenvalue for a pair of matrices (A,B) is a scalar
+*  lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
+*  singular. It is usually represented as the pair (alpha,beta), as
+*  there is a reasonable interpretation for beta=0, and even for both
+*  being zero.
+*
+*  The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
+*  of (A,B) satisfies
+*
+*                   A * v(j) = lambda(j) * B * v(j).
+*
+*  The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
+*  of (A,B) satisfies
+*
+*                   u(j)**H * A  = lambda(j) * u(j)**H * B .
+*
+*  where u(j)**H is the conjugate-transpose of u(j).
+*
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N':  do not compute the left generalized eigenvectors;
+*          = 'V':  compute the left generalized eigenvectors.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N':  do not compute the right generalized eigenvectors;
+*          = 'V':  compute the right generalized eigenvectors.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A, B, VL, and VR.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA, N)
+*          On entry, the matrix A in the pair (A,B).
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of A.  LDA >= max(1,N).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB, N)
+*          On entry, the matrix B in the pair (A,B).
+*          On exit, B has been overwritten.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of B.  LDB >= max(1,N).
+*
+*  ALPHAR  (output) DOUBLE PRECISION array, dimension (N)
+*  ALPHAI  (output) DOUBLE PRECISION array, dimension (N)
+*  BETA    (output) DOUBLE PRECISION array, dimension (N)
+*          On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
+*          be the generalized eigenvalues.  If ALPHAI(j) is zero, then
+*          the j-th eigenvalue is real; if positive, then the j-th and
+*          (j+1)-st eigenvalues are a complex conjugate pair, with
+*          ALPHAI(j+1) negative.
+*
+*          Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
+*          may easily over- or underflow, and BETA(j) may even be zero.
+*          Thus, the user should avoid naively computing the ratio
+*          alpha/beta.  However, ALPHAR and ALPHAI will be always less
+*          than and usually comparable with norm(A) in magnitude, and
+*          BETA always less than and usually comparable with norm(B).
+*
+*  VL      (output) DOUBLE PRECISION array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
+*          after another in the columns of VL, in the same order as
+*          their eigenvalues. If the j-th eigenvalue is real, then
+*          u(j) = VL(:,j), the j-th column of VL. If the j-th and
+*          (j+1)-th eigenvalues form a complex conjugate pair, then
+*          u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part)+abs(imag. part)=1.
+*          Not referenced if JOBVL = 'N'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the matrix VL. LDVL >= 1, and
+*          if JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) DOUBLE PRECISION array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
+*          after another in the columns of VR, in the same order as
+*          their eigenvalues. If the j-th eigenvalue is real, then
+*          v(j) = VR(:,j), the j-th column of VR. If the j-th and
+*          (j+1)-th eigenvalues form a complex conjugate pair, then
+*          v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part)+abs(imag. part)=1.
+*          Not referenced if JOBVR = 'N'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the matrix VR. LDVR >= 1, and
+*          if JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,8*N).
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          = 1,...,N:
+*                The QZ iteration failed.  No eigenvectors have been
+*                calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
+*                should be correct for j=INFO+1,...,N.
+*          > N:  =N+1: other than QZ iteration failed in DHGEQZ.
+*                =N+2: error return from DTGEVC.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
+      CHARACTER          CHTEMP
+      INTEGER            ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
+     $                   IN, IRIGHT, IROWS, ITAU, IWRK, JC, JR, MAXWRK,
+     $                   MINWRK
+      DOUBLE PRECISION   ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
+     $                   SMLNUM, TEMP
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            LDUMMA( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,
+     $                   DLACPY,DLASCL, DLASET, DORGQR, DORMQR, DTGEVC,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           LSAME, ILAENV, DLAMCH, DLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode the input arguments
+*
+      IF( LSAME( JOBVL, 'N' ) ) THEN
+         IJOBVL = 1
+         ILVL = .FALSE.
+      ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
+         IJOBVL = 2
+         ILVL = .TRUE.
+      ELSE
+         IJOBVL = -1
+         ILVL = .FALSE.
+      END IF
+*
+      IF( LSAME( JOBVR, 'N' ) ) THEN
+         IJOBVR = 1
+         ILVR = .FALSE.
+      ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
+         IJOBVR = 2
+         ILVR = .TRUE.
+      ELSE
+         IJOBVR = -1
+         ILVR = .FALSE.
+      END IF
+      ILV = ILVL .OR. ILVR
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( IJOBVL.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( IJOBVR.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -12
+      ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -14
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV. The workspace is
+*       computed assuming ILO = 1 and IHI = N, the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = MAX( 1, 8*N )
+         MAXWRK = MAX( 1, N*( 7 +
+     $                 ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 ) ) )
+         MAXWRK = MAX( MAXWRK, N*( 7 +
+     $                 ILAENV( 1, 'DORMQR', ' ', N, 1, N, 0 ) ) )
+         IF( ILVL ) THEN
+            MAXWRK = MAX( MAXWRK, N*( 7 +
+     $                 ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) ) )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
+     $      INFO = -16
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGGEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
+      ILASCL = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ANRMTO = SMLNUM
+         ILASCL = .TRUE.
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ANRMTO = BIGNUM
+         ILASCL = .TRUE.
+      END IF
+      IF( ILASCL )
+     $   CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
+      ILBSCL = .FALSE.
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+         BNRMTO = SMLNUM
+         ILBSCL = .TRUE.
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+         BNRMTO = BIGNUM
+         ILBSCL = .TRUE.
+      END IF
+      IF( ILBSCL )
+     $   CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
+*
+*     Permute the matrices A, B to isolate eigenvalues if possible
+*     (Workspace: need 6*N)
+*
+      ILEFT = 1
+      IRIGHT = N + 1
+      IWRK = IRIGHT + N
+      CALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
+     $             WORK( IRIGHT ), WORK( IWRK ), IERR )
+*
+*     Reduce B to triangular form (QR decomposition of B)
+*     (Workspace: need N, prefer N*NB)
+*
+      IROWS = IHI + 1 - ILO
+      IF( ILV ) THEN
+         ICOLS = N + 1 - ILO
+      ELSE
+         ICOLS = IROWS
+      END IF
+      ITAU = IWRK
+      IWRK = ITAU + IROWS
+      CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
+     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
+*
+*     Apply the orthogonal transformation to matrix A
+*     (Workspace: need N, prefer N*NB)
+*
+      CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
+     $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
+     $             LWORK+1-IWRK, IERR )
+*
+*     Initialize VL
+*     (Workspace: need N, prefer N*NB)
+*
+      IF( ILVL ) THEN
+         CALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )
+         IF( IROWS.GT.1 ) THEN
+            CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
+     $                   VL( ILO+1, ILO ), LDVL )
+         END IF
+         CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
+     $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
+      END IF
+*
+*     Initialize VR
+*
+      IF( ILVR )
+     $   CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )
+*
+*     Reduce to generalized Hessenberg form
+*     (Workspace: none needed)
+*
+      IF( ILV ) THEN
+*
+*        Eigenvectors requested -- work on whole matrix.
+*
+         CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
+     $                LDVL, VR, LDVR, IERR )
+      ELSE
+         CALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
+     $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
+      END IF
+*
+*     Perform QZ algorithm (Compute eigenvalues, and optionally, the
+*     Schur forms and Schur vectors)
+*     (Workspace: need N)
+*
+      IWRK = ITAU
+      IF( ILV ) THEN
+         CHTEMP = 'S'
+      ELSE
+         CHTEMP = 'E'
+      END IF
+      CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
+     $             ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
+     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
+      IF( IERR.NE.0 ) THEN
+         IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
+            INFO = IERR
+         ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
+            INFO = IERR - N
+         ELSE
+            INFO = N + 1
+         END IF
+         GO TO 110
+      END IF
+*
+*     Compute Eigenvectors
+*     (Workspace: need 6*N)
+*
+      IF( ILV ) THEN
+         IF( ILVL ) THEN
+            IF( ILVR ) THEN
+               CHTEMP = 'B'
+            ELSE
+               CHTEMP = 'L'
+            END IF
+         ELSE
+            CHTEMP = 'R'
+         END IF
+         CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
+     $                VR, LDVR, N, IN, WORK( IWRK ), IERR )
+         IF( IERR.NE.0 ) THEN
+            INFO = N + 2
+            GO TO 110
+         END IF
+*
+*        Undo balancing on VL and VR and normalization
+*        (Workspace: none needed)
+*
+         IF( ILVL ) THEN
+            CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
+     $                   WORK( IRIGHT ), N, VL, LDVL, IERR )
+            DO 50 JC = 1, N
+               IF( ALPHAI( JC ).LT.ZERO )
+     $            GO TO 50
+               TEMP = ZERO
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 10 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
+   10             CONTINUE
+               ELSE
+                  DO 20 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
+     $                      ABS( VL( JR, JC+1 ) ) )
+   20             CONTINUE
+               END IF
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 50
+               TEMP = ONE / TEMP
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 30 JR = 1, N
+                     VL( JR, JC ) = VL( JR, JC )*TEMP
+   30             CONTINUE
+               ELSE
+                  DO 40 JR = 1, N
+                     VL( JR, JC ) = VL( JR, JC )*TEMP
+                     VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
+   40             CONTINUE
+               END IF
+   50       CONTINUE
+         END IF
+         IF( ILVR ) THEN
+            CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
+     $                   WORK( IRIGHT ), N, VR, LDVR, IERR )
+            DO 100 JC = 1, N
+               IF( ALPHAI( JC ).LT.ZERO )
+     $            GO TO 100
+               TEMP = ZERO
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 60 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
+   60             CONTINUE
+               ELSE
+                  DO 70 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
+     $                      ABS( VR( JR, JC+1 ) ) )
+   70             CONTINUE
+               END IF
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 100
+               TEMP = ONE / TEMP
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 80 JR = 1, N
+                     VR( JR, JC ) = VR( JR, JC )*TEMP
+   80             CONTINUE
+               ELSE
+                  DO 90 JR = 1, N
+                     VR( JR, JC ) = VR( JR, JC )*TEMP
+                     VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
+   90             CONTINUE
+               END IF
+  100       CONTINUE
+         END IF
+*
+*        End of eigenvector calculation
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ILASCL ) THEN
+         CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
+         CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
+      END IF
+*
+      IF( ILBSCL ) THEN
+         CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
+      END IF
+*
+  110 CONTINUE
+*
+      WORK( 1 ) = MAXWRK
+*
+      RETURN
+*
+*     End of DGGEV
+*
+      END
diff --git a/libcruft/lapack/dgghrd.f b/libcruft/lapack/dgghrd.f
new file mode 100644
index 0000000..6b8bbb0
--- /dev/null
+++ b/libcruft/lapack/dgghrd.f
@@ -0,0 +1,264 @@
+      SUBROUTINE DGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
+     $                   LDQ, Z, LDZ, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ
+      INTEGER            IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGGHRD reduces a pair of real matrices (A,B) to generalized upper
+*  Hessenberg form using orthogonal transformations, where A is a
+*  general matrix and B is upper triangular.  The form of the
+*  generalized eigenvalue problem is
+*     A*x = lambda*B*x,
+*  and B is typically made upper triangular by computing its QR
+*  factorization and moving the orthogonal matrix Q to the left side
+*  of the equation.
+*
+*  This subroutine simultaneously reduces A to a Hessenberg matrix H:
+*     Q**T*A*Z = H
+*  and transforms B to another upper triangular matrix T:
+*     Q**T*B*Z = T
+*  in order to reduce the problem to its standard form
+*     H*y = lambda*T*y
+*  where y = Z**T*x.
+*
+*  The orthogonal matrices Q and Z are determined as products of Givens
+*  rotations.  They may either be formed explicitly, or they may be
+*  postmultiplied into input matrices Q1 and Z1, so that
+*
+*       Q1 * A * Z1**T = (Q1*Q) * H * (Z1*Z)**T
+*
+*       Q1 * B * Z1**T = (Q1*Q) * T * (Z1*Z)**T
+*
+*  If Q1 is the orthogonal matrix from the QR factorization of B in the
+*  original equation A*x = lambda*B*x, then DGGHRD reduces the original
+*  problem to generalized Hessenberg form.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': do not compute Q;
+*          = 'I': Q is initialized to the unit matrix, and the
+*                 orthogonal matrix Q is returned;
+*          = 'V': Q must contain an orthogonal matrix Q1 on entry,
+*                 and the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': do not compute Z;
+*          = 'I': Z is initialized to the unit matrix, and the
+*                 orthogonal matrix Z is returned;
+*          = 'V': Z must contain an orthogonal matrix Z1 on entry,
+*                 and the product Z1*Z is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of A which are to be
+*          reduced.  It is assumed that A is already upper triangular
+*          in rows and columns 1:ILO-1 and IHI+1:N.  ILO and IHI are
+*          normally set by a previous call to SGGBAL; otherwise they
+*          should be set to 1 and N respectively.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA, N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          rest is set to zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB, N)
+*          On entry, the N-by-N upper triangular matrix B.
+*          On exit, the upper triangular matrix T = Q**T B Z.  The
+*          elements below the diagonal are set to zero.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  Q       (input/output) DOUBLE PRECISION array, dimension (LDQ, N)
+*          On entry, if COMPQ = 'V', the orthogonal matrix Q1,
+*          typically from the QR factorization of B.
+*          On exit, if COMPQ='I', the orthogonal matrix Q, and if
+*          COMPQ = 'V', the product Q1*Q.
+*          Not referenced if COMPQ='N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
+*
+*  Z       (input/output) DOUBLE PRECISION array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the orthogonal matrix Z1.
+*          On exit, if COMPZ='I', the orthogonal matrix Z, and if
+*          COMPZ = 'V', the product Z1*Z.
+*          Not referenced if COMPZ='N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.
+*          LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  This routine reduces A to Hessenberg and B to triangular form by
+*  an unblocked reduction, as described in _Matrix_Computations_,
+*  by Golub and Van Loan (Johns Hopkins Press.)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILQ, ILZ
+      INTEGER            ICOMPQ, ICOMPZ, JCOL, JROW
+      DOUBLE PRECISION   C, S, TEMP
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARTG, DLASET, DROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode COMPQ
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+*     Decode COMPZ
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ICOMPQ.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPZ.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THEN
+         INFO = -11
+      ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGGHRD', -INFO )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z if desired.
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Zero out lower triangle of B
+*
+      DO 20 JCOL = 1, N - 1
+         DO 10 JROW = JCOL + 1, N
+            B( JROW, JCOL ) = ZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     Reduce A and B
+*
+      DO 40 JCOL = ILO, IHI - 2
+*
+         DO 30 JROW = IHI, JCOL + 2, -1
+*
+*           Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)
+*
+            TEMP = A( JROW-1, JCOL )
+            CALL DLARTG( TEMP, A( JROW, JCOL ), C, S,
+     $                   A( JROW-1, JCOL ) )
+            A( JROW, JCOL ) = ZERO
+            CALL DROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,
+     $                 A( JROW, JCOL+1 ), LDA, C, S )
+            CALL DROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,
+     $                 B( JROW, JROW-1 ), LDB, C, S )
+            IF( ILQ )
+     $         CALL DROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C, S )
+*
+*           Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)
+*
+            TEMP = B( JROW, JROW )
+            CALL DLARTG( TEMP, B( JROW, JROW-1 ), C, S,
+     $                   B( JROW, JROW ) )
+            B( JROW, JROW-1 ) = ZERO
+            CALL DROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )
+            CALL DROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,
+     $                 S )
+            IF( ILZ )
+     $         CALL DROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )
+   30    CONTINUE
+   40 CONTINUE
+*
+      RETURN
+*
+*     End of DGGHRD
+*
+      END
diff --git a/libcruft/lapack/dgtsv.f b/libcruft/lapack/dgtsv.f
new file mode 100644
index 0000000..79c4b71
--- /dev/null
+++ b/libcruft/lapack/dgtsv.f
@@ -0,0 +1,262 @@
+      SUBROUTINE DGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   B( LDB, * ), D( * ), DL( * ), DU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGTSV  solves the equation
+*
+*     A*X = B,
+*
+*  where A is an n by n tridiagonal matrix, by Gaussian elimination with
+*  partial pivoting.
+*
+*  Note that the equation  A'*X = B  may be solved by interchanging the
+*  order of the arguments DU and DL.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, DL must contain the (n-1) sub-diagonal elements of
+*          A.
+*
+*          On exit, DL is overwritten by the (n-2) elements of the
+*          second super-diagonal of the upper triangular matrix U from
+*          the LU factorization of A, in DL(1), ..., DL(n-2).
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*
+*          On exit, D is overwritten by the n diagonal elements of U.
+*
+*  DU      (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, DU must contain the (n-1) super-diagonal elements
+*          of A.
+*
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          super-diagonal of U.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the N by NRHS matrix of right hand side matrix B.
+*          On exit, if INFO = 0, the N by NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, U(i,i) is exactly zero, and the solution
+*               has not been computed.  The factorization has not been
+*               completed unless i = N.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   FACT, TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGTSV ', -INFO )
+         RETURN
+      END IF
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( NRHS.EQ.1 ) THEN
+         DO 10 I = 1, N - 2
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+*
+*              No row interchange required
+*
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+               DL( I ) = ZERO
+            ELSE
+*
+*              Interchange rows I and I+1
+*
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DL( I ) = DU( I+1 )
+               DU( I+1 ) = -FACT*DL( I )
+               DU( I ) = TEMP
+               TEMP = B( I, 1 )
+               B( I, 1 ) = B( I+1, 1 )
+               B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )
+            END IF
+   10    CONTINUE
+         IF( N.GT.1 ) THEN
+            I = N - 1
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+            ELSE
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DU( I ) = TEMP
+               TEMP = B( I, 1 )
+               B( I, 1 ) = B( I+1, 1 )
+               B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )
+            END IF
+         END IF
+         IF( D( N ).EQ.ZERO ) THEN
+            INFO = N
+            RETURN
+         END IF
+      ELSE
+         DO 40 I = 1, N - 2
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+*
+*              No row interchange required
+*
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  DO 20 J = 1, NRHS
+                     B( I+1, J ) = B( I+1, J ) - FACT*B( I, J )
+   20             CONTINUE
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+               DL( I ) = ZERO
+            ELSE
+*
+*              Interchange rows I and I+1
+*
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DL( I ) = DU( I+1 )
+               DU( I+1 ) = -FACT*DL( I )
+               DU( I ) = TEMP
+               DO 30 J = 1, NRHS
+                  TEMP = B( I, J )
+                  B( I, J ) = B( I+1, J )
+                  B( I+1, J ) = TEMP - FACT*B( I+1, J )
+   30          CONTINUE
+            END IF
+   40    CONTINUE
+         IF( N.GT.1 ) THEN
+            I = N - 1
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  DO 50 J = 1, NRHS
+                     B( I+1, J ) = B( I+1, J ) - FACT*B( I, J )
+   50             CONTINUE
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+            ELSE
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DU( I ) = TEMP
+               DO 60 J = 1, NRHS
+                  TEMP = B( I, J )
+                  B( I, J ) = B( I+1, J )
+                  B( I+1, J ) = TEMP - FACT*B( I+1, J )
+   60          CONTINUE
+            END IF
+         END IF
+         IF( D( N ).EQ.ZERO ) THEN
+            INFO = N
+            RETURN
+         END IF
+      END IF
+*
+*     Back solve with the matrix U from the factorization.
+*
+      IF( NRHS.LE.2 ) THEN
+         J = 1
+   70    CONTINUE
+         B( N, J ) = B( N, J ) / D( N )
+         IF( N.GT.1 )
+     $      B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) / D( N-1 )
+         DO 80 I = N - 2, 1, -1
+            B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*
+     $                  B( I+2, J ) ) / D( I )
+   80    CONTINUE
+         IF( J.LT.NRHS ) THEN
+            J = J + 1
+            GO TO 70
+         END IF
+      ELSE
+         DO 100 J = 1, NRHS
+            B( N, J ) = B( N, J ) / D( N )
+            IF( N.GT.1 )
+     $         B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                       D( N-1 )
+            DO 90 I = N - 2, 1, -1
+               B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*
+     $                     B( I+2, J ) ) / D( I )
+   90       CONTINUE
+  100    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DGTSV
+*
+      END
diff --git a/libcruft/lapack/dgttrf.f b/libcruft/lapack/dgttrf.f
new file mode 100644
index 0000000..b39527e
--- /dev/null
+++ b/libcruft/lapack/dgttrf.f
@@ -0,0 +1,168 @@
+      SUBROUTINE DGTTRF( N, DL, D, DU, DU2, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGTTRF computes an LU factorization of a real tridiagonal matrix A
+*  using elimination with partial pivoting and row interchanges.
+*
+*  The factorization has the form
+*     A = L * U
+*  where L is a product of permutation and unit lower bidiagonal
+*  matrices and U is upper triangular with nonzeros in only the main
+*  diagonal and first two superdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  DL      (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, DL must contain the (n-1) sub-diagonal elements of
+*          A.
+*
+*          On exit, DL is overwritten by the (n-1) multipliers that
+*          define the matrix L from the LU factorization of A.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*
+*          On exit, D is overwritten by the n diagonal elements of the
+*          upper triangular matrix U from the LU factorization of A.
+*
+*  DU      (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, DU must contain the (n-1) super-diagonal elements
+*          of A.
+*
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          super-diagonal of U.
+*
+*  DU2     (output) DOUBLE PRECISION array, dimension (N-2)
+*          On exit, DU2 is overwritten by the (n-2) elements of the
+*          second super-diagonal of U.
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*          > 0:  if INFO = k, U(k,k) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      DOUBLE PRECISION   FACT, TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'DGTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Initialize IPIV(i) = i and DU2(I) = 0
+*
+      DO 10 I = 1, N
+         IPIV( I ) = I
+   10 CONTINUE
+      DO 20 I = 1, N - 2
+         DU2( I ) = ZERO
+   20 CONTINUE
+*
+      DO 30 I = 1, N - 2
+         IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+*
+*           No row interchange required, eliminate DL(I)
+*
+            IF( D( I ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+*
+*           Interchange rows I and I+1, eliminate DL(I)
+*
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            DU2( I ) = DU( I+1 )
+            DU( I+1 ) = -FACT*DU( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+   30 CONTINUE
+      IF( N.GT.1 ) THEN
+         I = N - 1
+         IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+            IF( D( I ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+      END IF
+*
+*     Check for a zero on the diagonal of U.
+*
+      DO 40 I = 1, N
+         IF( D( I ).EQ.ZERO ) THEN
+            INFO = I
+            GO TO 50
+         END IF
+   40 CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of DGTTRF
+*
+      END
diff --git a/libcruft/lapack/dgttrs.f b/libcruft/lapack/dgttrs.f
new file mode 100644
index 0000000..318d6a7
--- /dev/null
+++ b/libcruft/lapack/dgttrs.f
@@ -0,0 +1,140 @@
+      SUBROUTINE DGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGTTRS solves one of the systems of equations
+*     A*X = B  or  A'*X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by DGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A'* X = B  (Transpose)
+*          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) DOUBLE PRECISION array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+      INTEGER            ITRANS, J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGTTS2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      NOTRAN = ( TRANS.EQ.'N' .OR. TRANS.EQ.'n' )
+      IF( .NOT.NOTRAN .AND. .NOT.( TRANS.EQ.'T' .OR. TRANS.EQ.
+     $    't' ) .AND. .NOT.( TRANS.EQ.'C' .OR. TRANS.EQ.'c' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDB.LT.MAX( N, 1 ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DGTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Decode TRANS
+*
+      IF( NOTRAN ) THEN
+         ITRANS = 0
+      ELSE
+         ITRANS = 1
+      END IF
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'DGTTRS', TRANS, N, NRHS, -1, -1 ) )
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL DGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL DGTTS2( ITRANS, N, JB, DL, D, DU, DU2, IPIV, B( 1, J ),
+     $                   LDB )
+   10    CONTINUE
+      END IF
+*
+*     End of DGTTRS
+*
+      END
diff --git a/libcruft/lapack/dgtts2.f b/libcruft/lapack/dgtts2.f
new file mode 100644
index 0000000..4b123ab
--- /dev/null
+++ b/libcruft/lapack/dgtts2.f
@@ -0,0 +1,196 @@
+      SUBROUTINE DGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ITRANS, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DGTTS2 solves one of the systems of equations
+*     A*X = B  or  A'*X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by DGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITRANS  (input) INTEGER
+*          Specifies the form of the system of equations.
+*          = 0:  A * X = B  (No transpose)
+*          = 1:  A'* X = B  (Transpose)
+*          = 2:  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) DOUBLE PRECISION array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IP, J
+      DOUBLE PRECISION   TEMP
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( ITRANS.EQ.0 ) THEN
+*
+*        Solve A*X = B using the LU factorization of A,
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+   10       CONTINUE
+*
+*           Solve L*x = b.
+*
+            DO 20 I = 1, N - 1
+               IP = IPIV( I )
+               TEMP = B( I+1-IP+I, J ) - DL( I )*B( IP, J )
+               B( I, J ) = B( IP, J )
+               B( I+1, J ) = TEMP
+   20       CONTINUE
+*
+*           Solve U*x = b.
+*
+            B( N, J ) = B( N, J ) / D( N )
+            IF( N.GT.1 )
+     $         B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                       D( N-1 )
+            DO 30 I = N - 2, 1, -1
+               B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                     B( I+2, J ) ) / D( I )
+   30       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 10
+            END IF
+         ELSE
+            DO 60 J = 1, NRHS
+*
+*              Solve L*x = b.
+*
+               DO 40 I = 1, N - 1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )
+                  ELSE
+                     TEMP = B( I, J )
+                     B( I, J ) = B( I+1, J )
+                     B( I+1, J ) = TEMP - DL( I )*B( I, J )
+                  END IF
+   40          CONTINUE
+*
+*              Solve U*x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               IF( N.GT.1 )
+     $            B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                          D( N-1 )
+               DO 50 I = N - 2, 1, -1
+                  B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                        B( I+2, J ) ) / D( I )
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      ELSE
+*
+*        Solve A' * X = B.
+*
+         IF( NRHS.LE.1 ) THEN
+*
+*           Solve U'*x = b.
+*
+            J = 1
+   70       CONTINUE
+            B( 1, J ) = B( 1, J ) / D( 1 )
+            IF( N.GT.1 )
+     $         B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+            DO 80 I = 3, N
+               B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-DU2( I-2 )*
+     $                     B( I-2, J ) ) / D( I )
+   80       CONTINUE
+*
+*           Solve L'*x = b.
+*
+            DO 90 I = N - 1, 1, -1
+               IP = IPIV( I )
+               TEMP = B( I, J ) - DL( I )*B( I+1, J )
+               B( I, J ) = B( IP, J )
+               B( IP, J ) = TEMP
+   90       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 70
+            END IF
+*
+         ELSE
+            DO 120 J = 1, NRHS
+*
+*              Solve U'*x = b.
+*
+               B( 1, J ) = B( 1, J ) / D( 1 )
+               IF( N.GT.1 )
+     $            B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+               DO 100 I = 3, N
+                  B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-
+     $                        DU2( I-2 )*B( I-2, J ) ) / D( I )
+  100          CONTINUE
+               DO 110 I = N - 1, 1, -1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I, J ) = B( I, J ) - DL( I )*B( I+1, J )
+                  ELSE
+                     TEMP = B( I+1, J )
+                     B( I+1, J ) = B( I, J ) - DL( I )*TEMP
+                     B( I, J ) = TEMP
+                  END IF
+  110          CONTINUE
+  120       CONTINUE
+         END IF
+      END IF
+*
+*     End of DGTTS2
+*
+      END
diff --git a/libcruft/lapack/dhgeqz.f b/libcruft/lapack/dhgeqz.f
new file mode 100644
index 0000000..de137dc
--- /dev/null
+++ b/libcruft/lapack/dhgeqz.f
@@ -0,0 +1,1243 @@
+      SUBROUTINE DHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,
+     $                   ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,
+     $                   LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ, JOB
+      INTEGER            IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   ALPHAI( * ), ALPHAR( * ), BETA( * ),
+     $                   H( LDH, * ), Q( LDQ, * ), T( LDT, * ),
+     $                   WORK( * ), Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DHGEQZ computes the eigenvalues of a real matrix pair (H,T),
+*  where H is an upper Hessenberg matrix and T is upper triangular,
+*  using the double-shift QZ method.
+*  Matrix pairs of this type are produced by the reduction to
+*  generalized upper Hessenberg form of a real matrix pair (A,B):
+*
+*     A = Q1*H*Z1**T,  B = Q1*T*Z1**T,
+*
+*  as computed by DGGHRD.
+*
+*  If JOB='S', then the Hessenberg-triangular pair (H,T) is
+*  also reduced to generalized Schur form,
+*  
+*     H = Q*S*Z**T,  T = Q*P*Z**T,
+*  
+*  where Q and Z are orthogonal matrices, P is an upper triangular
+*  matrix, and S is a quasi-triangular matrix with 1-by-1 and 2-by-2
+*  diagonal blocks.
+*
+*  The 1-by-1 blocks correspond to real eigenvalues of the matrix pair
+*  (H,T) and the 2-by-2 blocks correspond to complex conjugate pairs of
+*  eigenvalues.
+*
+*  Additionally, the 2-by-2 upper triangular diagonal blocks of P
+*  corresponding to 2-by-2 blocks of S are reduced to positive diagonal
+*  form, i.e., if S(j+1,j) is non-zero, then P(j+1,j) = P(j,j+1) = 0,
+*  P(j,j) > 0, and P(j+1,j+1) > 0.
+*
+*  Optionally, the orthogonal matrix Q from the generalized Schur
+*  factorization may be postmultiplied into an input matrix Q1, and the
+*  orthogonal matrix Z may be postmultiplied into an input matrix Z1.
+*  If Q1 and Z1 are the orthogonal matrices from DGGHRD that reduced
+*  the matrix pair (A,B) to generalized upper Hessenberg form, then the
+*  output matrices Q1*Q and Z1*Z are the orthogonal factors from the
+*  generalized Schur factorization of (A,B):
+*
+*     A = (Q1*Q)*S*(Z1*Z)**T,  B = (Q1*Q)*P*(Z1*Z)**T.
+*  
+*  To avoid overflow, eigenvalues of the matrix pair (H,T) (equivalently,
+*  of (A,B)) are computed as a pair of values (alpha,beta), where alpha is
+*  complex and beta real.
+*  If beta is nonzero, lambda = alpha / beta is an eigenvalue of the
+*  generalized nonsymmetric eigenvalue problem (GNEP)
+*     A*x = lambda*B*x
+*  and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the
+*  alternate form of the GNEP
+*     mu*A*y = B*y.
+*  Real eigenvalues can be read directly from the generalized Schur
+*  form: 
+*    alpha = S(i,i), beta = P(i,i).
+*
+*  Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix
+*       Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),
+*       pp. 241--256.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          = 'E': Compute eigenvalues only;
+*          = 'S': Compute eigenvalues and the Schur form. 
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': Left Schur vectors (Q) are not computed;
+*          = 'I': Q is initialized to the unit matrix and the matrix Q
+*                 of left Schur vectors of (H,T) is returned;
+*          = 'V': Q must contain an orthogonal matrix Q1 on entry and
+*                 the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': Right Schur vectors (Z) are not computed;
+*          = 'I': Z is initialized to the unit matrix and the matrix Z
+*                 of right Schur vectors of (H,T) is returned;
+*          = 'V': Z must contain an orthogonal matrix Z1 on entry and
+*                 the product Z1*Z is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices H, T, Q, and Z.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of H which are in
+*          Hessenberg form.  It is assumed that A is already upper
+*          triangular in rows and columns 1:ILO-1 and IHI+1:N.
+*          If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0.
+*
+*  H       (input/output) DOUBLE PRECISION array, dimension (LDH, N)
+*          On entry, the N-by-N upper Hessenberg matrix H.
+*          On exit, if JOB = 'S', H contains the upper quasi-triangular
+*          matrix S from the generalized Schur factorization;
+*          2-by-2 diagonal blocks (corresponding to complex conjugate
+*          pairs of eigenvalues) are returned in standard form, with
+*          H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0.
+*          If JOB = 'E', the diagonal blocks of H match those of S, but
+*          the rest of H is unspecified.
+*
+*  LDH     (input) INTEGER
+*          The leading dimension of the array H.  LDH >= max( 1, N ).
+*
+*  T       (input/output) DOUBLE PRECISION array, dimension (LDT, N)
+*          On entry, the N-by-N upper triangular matrix T.
+*          On exit, if JOB = 'S', T contains the upper triangular
+*          matrix P from the generalized Schur factorization;
+*          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks of S
+*          are reduced to positive diagonal form, i.e., if H(j+1,j) is
+*          non-zero, then T(j+1,j) = T(j,j+1) = 0, T(j,j) > 0, and
+*          T(j+1,j+1) > 0.
+*          If JOB = 'E', the diagonal blocks of T match those of P, but
+*          the rest of T is unspecified.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= max( 1, N ).
+*
+*  ALPHAR  (output) DOUBLE PRECISION array, dimension (N)
+*          The real parts of each scalar alpha defining an eigenvalue
+*          of GNEP.
+*
+*  ALPHAI  (output) DOUBLE PRECISION array, dimension (N)
+*          The imaginary parts of each scalar alpha defining an
+*          eigenvalue of GNEP.
+*          If ALPHAI(j) is zero, then the j-th eigenvalue is real; if
+*          positive, then the j-th and (j+1)-st eigenvalues are a
+*          complex conjugate pair, with ALPHAI(j+1) = -ALPHAI(j).
+*
+*  BETA    (output) DOUBLE PRECISION array, dimension (N)
+*          The scalars beta that define the eigenvalues of GNEP.
+*          Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and
+*          beta = BETA(j) represent the j-th eigenvalue of the matrix
+*          pair (A,B), in one of the forms lambda = alpha/beta or
+*          mu = beta/alpha.  Since either lambda or mu may overflow,
+*          they should not, in general, be computed.
+*
+*  Q       (input/output) DOUBLE PRECISION array, dimension (LDQ, N)
+*          On entry, if COMPZ = 'V', the orthogonal matrix Q1 used in
+*          the reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the orthogonal matrix of left Schur
+*          vectors of (H,T), and if COMPZ = 'V', the orthogonal matrix
+*          of left Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= 1.
+*          If COMPQ='V' or 'I', then LDQ >= N.
+*
+*  Z       (input/output) DOUBLE PRECISION array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the orthogonal matrix Z1 used in
+*          the reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the orthogonal matrix of
+*          right Schur vectors of (H,T), and if COMPZ = 'V', the
+*          orthogonal matrix of right Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1.
+*          If COMPZ='V' or 'I', then LDZ >= N.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1,...,N: the QZ iteration did not converge.  (H,T) is not
+*                     in Schur form, but ALPHAR(i), ALPHAI(i), and
+*                     BETA(i), i=INFO+1,...,N should be correct.
+*          = N+1,...,2*N: the shift calculation failed.  (H,T) is not
+*                     in Schur form, but ALPHAR(i), ALPHAI(i), and
+*                     BETA(i), i=INFO-N+1,...,N should be correct.
+*
+*  Further Details
+*  ===============
+*
+*  Iteration counters:
+*
+*  JITER  -- counts iterations.
+*  IITER  -- counts iterations run since ILAST was last
+*            changed.  This is therefore reset only when a 1-by-1 or
+*            2-by-2 block deflates off the bottom.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+*    $                     SAFETY = 1.0E+0 )
+      DOUBLE PRECISION   HALF, ZERO, ONE, SAFETY
+      PARAMETER          ( HALF = 0.5D+0, ZERO = 0.0D+0, ONE = 1.0D+0,
+     $                   SAFETY = 1.0D+2 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILAZR2, ILAZRO, ILPIVT, ILQ, ILSCHR, ILZ,
+     $                   LQUERY
+      INTEGER            ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,
+     $                   ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,
+     $                   JR, MAXIT
+      DOUBLE PRECISION   A11, A12, A1I, A1R, A21, A22, A2I, A2R, AD11,
+     $                   AD11L, AD12, AD12L, AD21, AD21L, AD22, AD22L,
+     $                   AD32L, AN, ANORM, ASCALE, ATOL, B11, B1A, B1I,
+     $                   B1R, B22, B2A, B2I, B2R, BN, BNORM, BSCALE,
+     $                   BTOL, C, C11I, C11R, C12, C21, C22I, C22R, CL,
+     $                   CQ, CR, CZ, ESHIFT, S, S1, S1INV, S2, SAFMAX,
+     $                   SAFMIN, SCALE, SL, SQI, SQR, SR, SZI, SZR, T1,
+     $                   TAU, TEMP, TEMP2, TEMPI, TEMPR, U1, U12, U12L,
+     $                   U2, ULP, VS, W11, W12, W21, W22, WABS, WI, WR,
+     $                   WR2
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   V( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH, DLANHS, DLAPY2, DLAPY3
+      EXTERNAL           LSAME, DLAMCH, DLANHS, DLAPY2, DLAPY3
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAG2, DLARFG, DLARTG, DLASET, DLASV2, DROT,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode JOB, COMPQ, COMPZ
+*
+      IF( LSAME( JOB, 'E' ) ) THEN
+         ILSCHR = .FALSE.
+         ISCHUR = 1
+      ELSE IF( LSAME( JOB, 'S' ) ) THEN
+         ILSCHR = .TRUE.
+         ISCHUR = 2
+      ELSE
+         ISCHUR = 0
+      END IF
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Check Argument Values
+*
+      INFO = 0
+      WORK( 1 ) = MAX( 1, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( ISCHUR.EQ.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPQ.EQ.0 ) THEN
+         INFO = -2
+      ELSE IF( ICOMPZ.EQ.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -6
+      ELSE IF( LDH.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDT.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -15
+      ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THEN
+         INFO = -17
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -19
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DHGEQZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = DBLE( 1 )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
+*
+*     Machine Constants
+*
+      IN = IHI + 1 - ILO
+      SAFMIN = DLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      ULP = DLAMCH( 'E' )*DLAMCH( 'B' )
+      ANORM = DLANHS( 'F', IN, H( ILO, ILO ), LDH, WORK )
+      BNORM = DLANHS( 'F', IN, T( ILO, ILO ), LDT, WORK )
+      ATOL = MAX( SAFMIN, ULP*ANORM )
+      BTOL = MAX( SAFMIN, ULP*BNORM )
+      ASCALE = ONE / MAX( SAFMIN, ANORM )
+      BSCALE = ONE / MAX( SAFMIN, BNORM )
+*
+*     Set Eigenvalues IHI+1:N
+*
+      DO 30 J = IHI + 1, N
+         IF( T( J, J ).LT.ZERO ) THEN
+            IF( ILSCHR ) THEN
+               DO 10 JR = 1, J
+                  H( JR, J ) = -H( JR, J )
+                  T( JR, J ) = -T( JR, J )
+   10          CONTINUE
+            ELSE
+               H( J, J ) = -H( J, J )
+               T( J, J ) = -T( J, J )
+            END IF
+            IF( ILZ ) THEN
+               DO 20 JR = 1, N
+                  Z( JR, J ) = -Z( JR, J )
+   20          CONTINUE
+            END IF
+         END IF
+         ALPHAR( J ) = H( J, J )
+         ALPHAI( J ) = ZERO
+         BETA( J ) = T( J, J )
+   30 CONTINUE
+*
+*     If IHI < ILO, skip QZ steps
+*
+      IF( IHI.LT.ILO )
+     $   GO TO 380
+*
+*     MAIN QZ ITERATION LOOP
+*
+*     Initialize dynamic indices
+*
+*     Eigenvalues ILAST+1:N have been found.
+*        Column operations modify rows IFRSTM:whatever.
+*        Row operations modify columns whatever:ILASTM.
+*
+*     If only eigenvalues are being computed, then
+*        IFRSTM is the row of the last splitting row above row ILAST;
+*        this is always at least ILO.
+*     IITER counts iterations since the last eigenvalue was found,
+*        to tell when to use an extraordinary shift.
+*     MAXIT is the maximum number of QZ sweeps allowed.
+*
+      ILAST = IHI
+      IF( ILSCHR ) THEN
+         IFRSTM = 1
+         ILASTM = N
+      ELSE
+         IFRSTM = ILO
+         ILASTM = IHI
+      END IF
+      IITER = 0
+      ESHIFT = ZERO
+      MAXIT = 30*( IHI-ILO+1 )
+*
+      DO 360 JITER = 1, MAXIT
+*
+*        Split the matrix if possible.
+*
+*        Two tests:
+*           1: H(j,j-1)=0  or  j=ILO
+*           2: T(j,j)=0
+*
+         IF( ILAST.EQ.ILO ) THEN
+*
+*           Special case: j=ILAST
+*
+            GO TO 80
+         ELSE
+            IF( ABS( H( ILAST, ILAST-1 ) ).LE.ATOL ) THEN
+               H( ILAST, ILAST-1 ) = ZERO
+               GO TO 80
+            END IF
+         END IF
+*
+         IF( ABS( T( ILAST, ILAST ) ).LE.BTOL ) THEN
+            T( ILAST, ILAST ) = ZERO
+            GO TO 70
+         END IF
+*
+*        General case: j<ILAST
+*
+         DO 60 J = ILAST - 1, ILO, -1
+*
+*           Test 1: for H(j,j-1)=0 or j=ILO
+*
+            IF( J.EQ.ILO ) THEN
+               ILAZRO = .TRUE.
+            ELSE
+               IF( ABS( H( J, J-1 ) ).LE.ATOL ) THEN
+                  H( J, J-1 ) = ZERO
+                  ILAZRO = .TRUE.
+               ELSE
+                  ILAZRO = .FALSE.
+               END IF
+            END IF
+*
+*           Test 2: for T(j,j)=0
+*
+            IF( ABS( T( J, J ) ).LT.BTOL ) THEN
+               T( J, J ) = ZERO
+*
+*              Test 1a: Check for 2 consecutive small subdiagonals in A
+*
+               ILAZR2 = .FALSE.
+               IF( .NOT.ILAZRO ) THEN
+                  TEMP = ABS( H( J, J-1 ) )
+                  TEMP2 = ABS( H( J, J ) )
+                  TEMPR = MAX( TEMP, TEMP2 )
+                  IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
+                     TEMP = TEMP / TEMPR
+                     TEMP2 = TEMP2 / TEMPR
+                  END IF
+                  IF( TEMP*( ASCALE*ABS( H( J+1, J ) ) ).LE.TEMP2*
+     $                ( ASCALE*ATOL ) )ILAZR2 = .TRUE.
+               END IF
+*
+*              If both tests pass (1 & 2), i.e., the leading diagonal
+*              element of B in the block is zero, split a 1x1 block off
+*              at the top. (I.e., at the J-th row/column) The leading
+*              diagonal element of the remainder can also be zero, so
+*              this may have to be done repeatedly.
+*
+               IF( ILAZRO .OR. ILAZR2 ) THEN
+                  DO 40 JCH = J, ILAST - 1
+                     TEMP = H( JCH, JCH )
+                     CALL DLARTG( TEMP, H( JCH+1, JCH ), C, S,
+     $                            H( JCH, JCH ) )
+                     H( JCH+1, JCH ) = ZERO
+                     CALL DROT( ILASTM-JCH, H( JCH, JCH+1 ), LDH,
+     $                          H( JCH+1, JCH+1 ), LDH, C, S )
+                     CALL DROT( ILASTM-JCH, T( JCH, JCH+1 ), LDT,
+     $                          T( JCH+1, JCH+1 ), LDT, C, S )
+                     IF( ILQ )
+     $                  CALL DROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, S )
+                     IF( ILAZR2 )
+     $                  H( JCH, JCH-1 ) = H( JCH, JCH-1 )*C
+                     ILAZR2 = .FALSE.
+                     IF( ABS( T( JCH+1, JCH+1 ) ).GE.BTOL ) THEN
+                        IF( JCH+1.GE.ILAST ) THEN
+                           GO TO 80
+                        ELSE
+                           IFIRST = JCH + 1
+                           GO TO 110
+                        END IF
+                     END IF
+                     T( JCH+1, JCH+1 ) = ZERO
+   40             CONTINUE
+                  GO TO 70
+               ELSE
+*
+*                 Only test 2 passed -- chase the zero to T(ILAST,ILAST)
+*                 Then process as in the case T(ILAST,ILAST)=0
+*
+                  DO 50 JCH = J, ILAST - 1
+                     TEMP = T( JCH, JCH+1 )
+                     CALL DLARTG( TEMP, T( JCH+1, JCH+1 ), C, S,
+     $                            T( JCH, JCH+1 ) )
+                     T( JCH+1, JCH+1 ) = ZERO
+                     IF( JCH.LT.ILASTM-1 )
+     $                  CALL DROT( ILASTM-JCH-1, T( JCH, JCH+2 ), LDT,
+     $                             T( JCH+1, JCH+2 ), LDT, C, S )
+                     CALL DROT( ILASTM-JCH+2, H( JCH, JCH-1 ), LDH,
+     $                          H( JCH+1, JCH-1 ), LDH, C, S )
+                     IF( ILQ )
+     $                  CALL DROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, S )
+                     TEMP = H( JCH+1, JCH )
+                     CALL DLARTG( TEMP, H( JCH+1, JCH-1 ), C, S,
+     $                            H( JCH+1, JCH ) )
+                     H( JCH+1, JCH-1 ) = ZERO
+                     CALL DROT( JCH+1-IFRSTM, H( IFRSTM, JCH ), 1,
+     $                          H( IFRSTM, JCH-1 ), 1, C, S )
+                     CALL DROT( JCH-IFRSTM, T( IFRSTM, JCH ), 1,
+     $                          T( IFRSTM, JCH-1 ), 1, C, S )
+                     IF( ILZ )
+     $                  CALL DROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,
+     $                             C, S )
+   50             CONTINUE
+                  GO TO 70
+               END IF
+            ELSE IF( ILAZRO ) THEN
+*
+*              Only test 1 passed -- work on J:ILAST
+*
+               IFIRST = J
+               GO TO 110
+            END IF
+*
+*           Neither test passed -- try next J
+*
+   60    CONTINUE
+*
+*        (Drop-through is "impossible")
+*
+         INFO = N + 1
+         GO TO 420
+*
+*        T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a
+*        1x1 block.
+*
+   70    CONTINUE
+         TEMP = H( ILAST, ILAST )
+         CALL DLARTG( TEMP, H( ILAST, ILAST-1 ), C, S,
+     $                H( ILAST, ILAST ) )
+         H( ILAST, ILAST-1 ) = ZERO
+         CALL DROT( ILAST-IFRSTM, H( IFRSTM, ILAST ), 1,
+     $              H( IFRSTM, ILAST-1 ), 1, C, S )
+         CALL DROT( ILAST-IFRSTM, T( IFRSTM, ILAST ), 1,
+     $              T( IFRSTM, ILAST-1 ), 1, C, S )
+         IF( ILZ )
+     $      CALL DROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )
+*
+*        H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHAR, ALPHAI,
+*                              and BETA
+*
+   80    CONTINUE
+         IF( T( ILAST, ILAST ).LT.ZERO ) THEN
+            IF( ILSCHR ) THEN
+               DO 90 J = IFRSTM, ILAST
+                  H( J, ILAST ) = -H( J, ILAST )
+                  T( J, ILAST ) = -T( J, ILAST )
+   90          CONTINUE
+            ELSE
+               H( ILAST, ILAST ) = -H( ILAST, ILAST )
+               T( ILAST, ILAST ) = -T( ILAST, ILAST )
+            END IF
+            IF( ILZ ) THEN
+               DO 100 J = 1, N
+                  Z( J, ILAST ) = -Z( J, ILAST )
+  100          CONTINUE
+            END IF
+         END IF
+         ALPHAR( ILAST ) = H( ILAST, ILAST )
+         ALPHAI( ILAST ) = ZERO
+         BETA( ILAST ) = T( ILAST, ILAST )
+*
+*        Go to next block -- exit if finished.
+*
+         ILAST = ILAST - 1
+         IF( ILAST.LT.ILO )
+     $      GO TO 380
+*
+*        Reset counters
+*
+         IITER = 0
+         ESHIFT = ZERO
+         IF( .NOT.ILSCHR ) THEN
+            ILASTM = ILAST
+            IF( IFRSTM.GT.ILAST )
+     $         IFRSTM = ILO
+         END IF
+         GO TO 350
+*
+*        QZ step
+*
+*        This iteration only involves rows/columns IFIRST:ILAST. We
+*        assume IFIRST < ILAST, and that the diagonal of B is non-zero.
+*
+  110    CONTINUE
+         IITER = IITER + 1
+         IF( .NOT.ILSCHR ) THEN
+            IFRSTM = IFIRST
+         END IF
+*
+*        Compute single shifts.
+*
+*        At this point, IFIRST < ILAST, and the diagonal elements of
+*        T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in
+*        magnitude)
+*
+         IF( ( IITER / 10 )*10.EQ.IITER ) THEN
+*
+*           Exceptional shift.  Chosen for no particularly good reason.
+*           (Single shift only.)
+*
+            IF( ( DBLE( MAXIT )*SAFMIN )*ABS( H( ILAST-1, ILAST ) ).LT.
+     $          ABS( T( ILAST-1, ILAST-1 ) ) ) THEN
+               ESHIFT = ESHIFT + H( ILAST-1, ILAST ) /
+     $                  T( ILAST-1, ILAST-1 )
+            ELSE
+               ESHIFT = ESHIFT + ONE / ( SAFMIN*DBLE( MAXIT ) )
+            END IF
+            S1 = ONE
+            WR = ESHIFT
+*
+         ELSE
+*
+*           Shifts based on the generalized eigenvalues of the
+*           bottom-right 2x2 block of A and B. The first eigenvalue
+*           returned by DLAG2 is the Wilkinson shift (AEP p.512),
+*
+            CALL DLAG2( H( ILAST-1, ILAST-1 ), LDH,
+     $                  T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1,
+     $                  S2, WR, WR2, WI )
+*
+            TEMP = MAX( S1, SAFMIN*MAX( ONE, ABS( WR ), ABS( WI ) ) )
+            IF( WI.NE.ZERO )
+     $         GO TO 200
+         END IF
+*
+*        Fiddle with shift to avoid overflow
+*
+         TEMP = MIN( ASCALE, ONE )*( HALF*SAFMAX )
+         IF( S1.GT.TEMP ) THEN
+            SCALE = TEMP / S1
+         ELSE
+            SCALE = ONE
+         END IF
+*
+         TEMP = MIN( BSCALE, ONE )*( HALF*SAFMAX )
+         IF( ABS( WR ).GT.TEMP )
+     $      SCALE = MIN( SCALE, TEMP / ABS( WR ) )
+         S1 = SCALE*S1
+         WR = SCALE*WR
+*
+*        Now check for two consecutive small subdiagonals.
+*
+         DO 120 J = ILAST - 1, IFIRST + 1, -1
+            ISTART = J
+            TEMP = ABS( S1*H( J, J-1 ) )
+            TEMP2 = ABS( S1*H( J, J )-WR*T( J, J ) )
+            TEMPR = MAX( TEMP, TEMP2 )
+            IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
+               TEMP = TEMP / TEMPR
+               TEMP2 = TEMP2 / TEMPR
+            END IF
+            IF( ABS( ( ASCALE*H( J+1, J ) )*TEMP ).LE.( ASCALE*ATOL )*
+     $          TEMP2 )GO TO 130
+  120    CONTINUE
+*
+         ISTART = IFIRST
+  130    CONTINUE
+*
+*        Do an implicit single-shift QZ sweep.
+*
+*        Initial Q
+*
+         TEMP = S1*H( ISTART, ISTART ) - WR*T( ISTART, ISTART )
+         TEMP2 = S1*H( ISTART+1, ISTART )
+         CALL DLARTG( TEMP, TEMP2, C, S, TEMPR )
+*
+*        Sweep
+*
+         DO 190 J = ISTART, ILAST - 1
+            IF( J.GT.ISTART ) THEN
+               TEMP = H( J, J-1 )
+               CALL DLARTG( TEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
+               H( J+1, J-1 ) = ZERO
+            END IF
+*
+            DO 140 JC = J, ILASTM
+               TEMP = C*H( J, JC ) + S*H( J+1, JC )
+               H( J+1, JC ) = -S*H( J, JC ) + C*H( J+1, JC )
+               H( J, JC ) = TEMP
+               TEMP2 = C*T( J, JC ) + S*T( J+1, JC )
+               T( J+1, JC ) = -S*T( J, JC ) + C*T( J+1, JC )
+               T( J, JC ) = TEMP2
+  140       CONTINUE
+            IF( ILQ ) THEN
+               DO 150 JR = 1, N
+                  TEMP = C*Q( JR, J ) + S*Q( JR, J+1 )
+                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
+                  Q( JR, J ) = TEMP
+  150          CONTINUE
+            END IF
+*
+            TEMP = T( J+1, J+1 )
+            CALL DLARTG( TEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
+            T( J+1, J ) = ZERO
+*
+            DO 160 JR = IFRSTM, MIN( J+2, ILAST )
+               TEMP = C*H( JR, J+1 ) + S*H( JR, J )
+               H( JR, J ) = -S*H( JR, J+1 ) + C*H( JR, J )
+               H( JR, J+1 ) = TEMP
+  160       CONTINUE
+            DO 170 JR = IFRSTM, J
+               TEMP = C*T( JR, J+1 ) + S*T( JR, J )
+               T( JR, J ) = -S*T( JR, J+1 ) + C*T( JR, J )
+               T( JR, J+1 ) = TEMP
+  170       CONTINUE
+            IF( ILZ ) THEN
+               DO 180 JR = 1, N
+                  TEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
+                  Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )
+                  Z( JR, J+1 ) = TEMP
+  180          CONTINUE
+            END IF
+  190    CONTINUE
+*
+         GO TO 350
+*
+*        Use Francis double-shift
+*
+*        Note: the Francis double-shift should work with real shifts,
+*              but only if the block is at least 3x3.
+*              This code may break if this point is reached with
+*              a 2x2 block with real eigenvalues.
+*
+  200    CONTINUE
+         IF( IFIRST+1.EQ.ILAST ) THEN
+*
+*           Special case -- 2x2 block with complex eigenvectors
+*
+*           Step 1: Standardize, that is, rotate so that
+*
+*                       ( B11  0  )
+*                   B = (         )  with B11 non-negative.
+*                       (  0  B22 )
+*
+            CALL DLASV2( T( ILAST-1, ILAST-1 ), T( ILAST-1, ILAST ),
+     $                   T( ILAST, ILAST ), B22, B11, SR, CR, SL, CL )
+*
+            IF( B11.LT.ZERO ) THEN
+               CR = -CR
+               SR = -SR
+               B11 = -B11
+               B22 = -B22
+            END IF
+*
+            CALL DROT( ILASTM+1-IFIRST, H( ILAST-1, ILAST-1 ), LDH,
+     $                 H( ILAST, ILAST-1 ), LDH, CL, SL )
+            CALL DROT( ILAST+1-IFRSTM, H( IFRSTM, ILAST-1 ), 1,
+     $                 H( IFRSTM, ILAST ), 1, CR, SR )
+*
+            IF( ILAST.LT.ILASTM )
+     $         CALL DROT( ILASTM-ILAST, T( ILAST-1, ILAST+1 ), LDT,
+     $                    T( ILAST, ILAST+1 ), LDH, CL, SL )
+            IF( IFRSTM.LT.ILAST-1 )
+     $         CALL DROT( IFIRST-IFRSTM, T( IFRSTM, ILAST-1 ), 1,
+     $                    T( IFRSTM, ILAST ), 1, CR, SR )
+*
+            IF( ILQ )
+     $         CALL DROT( N, Q( 1, ILAST-1 ), 1, Q( 1, ILAST ), 1, CL,
+     $                    SL )
+            IF( ILZ )
+     $         CALL DROT( N, Z( 1, ILAST-1 ), 1, Z( 1, ILAST ), 1, CR,
+     $                    SR )
+*
+            T( ILAST-1, ILAST-1 ) = B11
+            T( ILAST-1, ILAST ) = ZERO
+            T( ILAST, ILAST-1 ) = ZERO
+            T( ILAST, ILAST ) = B22
+*
+*           If B22 is negative, negate column ILAST
+*
+            IF( B22.LT.ZERO ) THEN
+               DO 210 J = IFRSTM, ILAST
+                  H( J, ILAST ) = -H( J, ILAST )
+                  T( J, ILAST ) = -T( J, ILAST )
+  210          CONTINUE
+*
+               IF( ILZ ) THEN
+                  DO 220 J = 1, N
+                     Z( J, ILAST ) = -Z( J, ILAST )
+  220             CONTINUE
+               END IF
+            END IF
+*
+*           Step 2: Compute ALPHAR, ALPHAI, and BETA (see refs.)
+*
+*           Recompute shift
+*
+            CALL DLAG2( H( ILAST-1, ILAST-1 ), LDH,
+     $                  T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1,
+     $                  TEMP, WR, TEMP2, WI )
+*
+*           If standardization has perturbed the shift onto real line,
+*           do another (real single-shift) QR step.
+*
+            IF( WI.EQ.ZERO )
+     $         GO TO 350
+            S1INV = ONE / S1
+*
+*           Do EISPACK (QZVAL) computation of alpha and beta
+*
+            A11 = H( ILAST-1, ILAST-1 )
+            A21 = H( ILAST, ILAST-1 )
+            A12 = H( ILAST-1, ILAST )
+            A22 = H( ILAST, ILAST )
+*
+*           Compute complex Givens rotation on right
+*           (Assume some element of C = (sA - wB) > unfl )
+*                            __
+*           (sA - wB) ( CZ   -SZ )
+*                     ( SZ    CZ )
+*
+            C11R = S1*A11 - WR*B11
+            C11I = -WI*B11
+            C12 = S1*A12
+            C21 = S1*A21
+            C22R = S1*A22 - WR*B22
+            C22I = -WI*B22
+*
+            IF( ABS( C11R )+ABS( C11I )+ABS( C12 ).GT.ABS( C21 )+
+     $          ABS( C22R )+ABS( C22I ) ) THEN
+               T1 = DLAPY3( C12, C11R, C11I )
+               CZ = C12 / T1
+               SZR = -C11R / T1
+               SZI = -C11I / T1
+            ELSE
+               CZ = DLAPY2( C22R, C22I )
+               IF( CZ.LE.SAFMIN ) THEN
+                  CZ = ZERO
+                  SZR = ONE
+                  SZI = ZERO
+               ELSE
+                  TEMPR = C22R / CZ
+                  TEMPI = C22I / CZ
+                  T1 = DLAPY2( CZ, C21 )
+                  CZ = CZ / T1
+                  SZR = -C21*TEMPR / T1
+                  SZI = C21*TEMPI / T1
+               END IF
+            END IF
+*
+*           Compute Givens rotation on left
+*
+*           (  CQ   SQ )
+*           (  __      )  A or B
+*           ( -SQ   CQ )
+*
+            AN = ABS( A11 ) + ABS( A12 ) + ABS( A21 ) + ABS( A22 )
+            BN = ABS( B11 ) + ABS( B22 )
+            WABS = ABS( WR ) + ABS( WI )
+            IF( S1*AN.GT.WABS*BN ) THEN
+               CQ = CZ*B11
+               SQR = SZR*B22
+               SQI = -SZI*B22
+            ELSE
+               A1R = CZ*A11 + SZR*A12
+               A1I = SZI*A12
+               A2R = CZ*A21 + SZR*A22
+               A2I = SZI*A22
+               CQ = DLAPY2( A1R, A1I )
+               IF( CQ.LE.SAFMIN ) THEN
+                  CQ = ZERO
+                  SQR = ONE
+                  SQI = ZERO
+               ELSE
+                  TEMPR = A1R / CQ
+                  TEMPI = A1I / CQ
+                  SQR = TEMPR*A2R + TEMPI*A2I
+                  SQI = TEMPI*A2R - TEMPR*A2I
+               END IF
+            END IF
+            T1 = DLAPY3( CQ, SQR, SQI )
+            CQ = CQ / T1
+            SQR = SQR / T1
+            SQI = SQI / T1
+*
+*           Compute diagonal elements of QBZ
+*
+            TEMPR = SQR*SZR - SQI*SZI
+            TEMPI = SQR*SZI + SQI*SZR
+            B1R = CQ*CZ*B11 + TEMPR*B22
+            B1I = TEMPI*B22
+            B1A = DLAPY2( B1R, B1I )
+            B2R = CQ*CZ*B22 + TEMPR*B11
+            B2I = -TEMPI*B11
+            B2A = DLAPY2( B2R, B2I )
+*
+*           Normalize so beta > 0, and Im( alpha1 ) > 0
+*
+            BETA( ILAST-1 ) = B1A
+            BETA( ILAST ) = B2A
+            ALPHAR( ILAST-1 ) = ( WR*B1A )*S1INV
+            ALPHAI( ILAST-1 ) = ( WI*B1A )*S1INV
+            ALPHAR( ILAST ) = ( WR*B2A )*S1INV
+            ALPHAI( ILAST ) = -( WI*B2A )*S1INV
+*
+*           Step 3: Go to next block -- exit if finished.
+*
+            ILAST = IFIRST - 1
+            IF( ILAST.LT.ILO )
+     $         GO TO 380
+*
+*           Reset counters
+*
+            IITER = 0
+            ESHIFT = ZERO
+            IF( .NOT.ILSCHR ) THEN
+               ILASTM = ILAST
+               IF( IFRSTM.GT.ILAST )
+     $            IFRSTM = ILO
+            END IF
+            GO TO 350
+         ELSE
+*
+*           Usual case: 3x3 or larger block, using Francis implicit
+*                       double-shift
+*
+*                                    2
+*           Eigenvalue equation is  w  - c w + d = 0,
+*
+*                                         -1 2        -1
+*           so compute 1st column of  (A B  )  - c A B   + d
+*           using the formula in QZIT (from EISPACK)
+*
+*           We assume that the block is at least 3x3
+*
+            AD11 = ( ASCALE*H( ILAST-1, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD21 = ( ASCALE*H( ILAST, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD12 = ( ASCALE*H( ILAST-1, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            AD22 = ( ASCALE*H( ILAST, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            U12 = T( ILAST-1, ILAST ) / T( ILAST, ILAST )
+            AD11L = ( ASCALE*H( IFIRST, IFIRST ) ) /
+     $              ( BSCALE*T( IFIRST, IFIRST ) )
+            AD21L = ( ASCALE*H( IFIRST+1, IFIRST ) ) /
+     $              ( BSCALE*T( IFIRST, IFIRST ) )
+            AD12L = ( ASCALE*H( IFIRST, IFIRST+1 ) ) /
+     $              ( BSCALE*T( IFIRST+1, IFIRST+1 ) )
+            AD22L = ( ASCALE*H( IFIRST+1, IFIRST+1 ) ) /
+     $              ( BSCALE*T( IFIRST+1, IFIRST+1 ) )
+            AD32L = ( ASCALE*H( IFIRST+2, IFIRST+1 ) ) /
+     $              ( BSCALE*T( IFIRST+1, IFIRST+1 ) )
+            U12L = T( IFIRST, IFIRST+1 ) / T( IFIRST+1, IFIRST+1 )
+*
+            V( 1 ) = ( AD11-AD11L )*( AD22-AD11L ) - AD12*AD21 +
+     $               AD21*U12*AD11L + ( AD12L-AD11L*U12L )*AD21L
+            V( 2 ) = ( ( AD22L-AD11L )-AD21L*U12L-( AD11-AD11L )-
+     $               ( AD22-AD11L )+AD21*U12 )*AD21L
+            V( 3 ) = AD32L*AD21L
+*
+            ISTART = IFIRST
+*
+            CALL DLARFG( 3, V( 1 ), V( 2 ), 1, TAU )
+            V( 1 ) = ONE
+*
+*           Sweep
+*
+            DO 290 J = ISTART, ILAST - 2
+*
+*              All but last elements: use 3x3 Householder transforms.
+*
+*              Zero (j-1)st column of A
+*
+               IF( J.GT.ISTART ) THEN
+                  V( 1 ) = H( J, J-1 )
+                  V( 2 ) = H( J+1, J-1 )
+                  V( 3 ) = H( J+2, J-1 )
+*
+                  CALL DLARFG( 3, H( J, J-1 ), V( 2 ), 1, TAU )
+                  V( 1 ) = ONE
+                  H( J+1, J-1 ) = ZERO
+                  H( J+2, J-1 ) = ZERO
+               END IF
+*
+               DO 230 JC = J, ILASTM
+                  TEMP = TAU*( H( J, JC )+V( 2 )*H( J+1, JC )+V( 3 )*
+     $                   H( J+2, JC ) )
+                  H( J, JC ) = H( J, JC ) - TEMP
+                  H( J+1, JC ) = H( J+1, JC ) - TEMP*V( 2 )
+                  H( J+2, JC ) = H( J+2, JC ) - TEMP*V( 3 )
+                  TEMP2 = TAU*( T( J, JC )+V( 2 )*T( J+1, JC )+V( 3 )*
+     $                    T( J+2, JC ) )
+                  T( J, JC ) = T( J, JC ) - TEMP2
+                  T( J+1, JC ) = T( J+1, JC ) - TEMP2*V( 2 )
+                  T( J+2, JC ) = T( J+2, JC ) - TEMP2*V( 3 )
+  230          CONTINUE
+               IF( ILQ ) THEN
+                  DO 240 JR = 1, N
+                     TEMP = TAU*( Q( JR, J )+V( 2 )*Q( JR, J+1 )+V( 3 )*
+     $                      Q( JR, J+2 ) )
+                     Q( JR, J ) = Q( JR, J ) - TEMP
+                     Q( JR, J+1 ) = Q( JR, J+1 ) - TEMP*V( 2 )
+                     Q( JR, J+2 ) = Q( JR, J+2 ) - TEMP*V( 3 )
+  240             CONTINUE
+               END IF
+*
+*              Zero j-th column of B (see DLAGBC for details)
+*
+*              Swap rows to pivot
+*
+               ILPIVT = .FALSE.
+               TEMP = MAX( ABS( T( J+1, J+1 ) ), ABS( T( J+1, J+2 ) ) )
+               TEMP2 = MAX( ABS( T( J+2, J+1 ) ), ABS( T( J+2, J+2 ) ) )
+               IF( MAX( TEMP, TEMP2 ).LT.SAFMIN ) THEN
+                  SCALE = ZERO
+                  U1 = ONE
+                  U2 = ZERO
+                  GO TO 250
+               ELSE IF( TEMP.GE.TEMP2 ) THEN
+                  W11 = T( J+1, J+1 )
+                  W21 = T( J+2, J+1 )
+                  W12 = T( J+1, J+2 )
+                  W22 = T( J+2, J+2 )
+                  U1 = T( J+1, J )
+                  U2 = T( J+2, J )
+               ELSE
+                  W21 = T( J+1, J+1 )
+                  W11 = T( J+2, J+1 )
+                  W22 = T( J+1, J+2 )
+                  W12 = T( J+2, J+2 )
+                  U2 = T( J+1, J )
+                  U1 = T( J+2, J )
+               END IF
+*
+*              Swap columns if nec.
+*
+               IF( ABS( W12 ).GT.ABS( W11 ) ) THEN
+                  ILPIVT = .TRUE.
+                  TEMP = W12
+                  TEMP2 = W22
+                  W12 = W11
+                  W22 = W21
+                  W11 = TEMP
+                  W21 = TEMP2
+               END IF
+*
+*              LU-factor
+*
+               TEMP = W21 / W11
+               U2 = U2 - TEMP*U1
+               W22 = W22 - TEMP*W12
+               W21 = ZERO
+*
+*              Compute SCALE
+*
+               SCALE = ONE
+               IF( ABS( W22 ).LT.SAFMIN ) THEN
+                  SCALE = ZERO
+                  U2 = ONE
+                  U1 = -W12 / W11
+                  GO TO 250
+               END IF
+               IF( ABS( W22 ).LT.ABS( U2 ) )
+     $            SCALE = ABS( W22 / U2 )
+               IF( ABS( W11 ).LT.ABS( U1 ) )
+     $            SCALE = MIN( SCALE, ABS( W11 / U1 ) )
+*
+*              Solve
+*
+               U2 = ( SCALE*U2 ) / W22
+               U1 = ( SCALE*U1-W12*U2 ) / W11
+*
+  250          CONTINUE
+               IF( ILPIVT ) THEN
+                  TEMP = U2
+                  U2 = U1
+                  U1 = TEMP
+               END IF
+*
+*              Compute Householder Vector
+*
+               T1 = SQRT( SCALE**2+U1**2+U2**2 )
+               TAU = ONE + SCALE / T1
+               VS = -ONE / ( SCALE+T1 )
+               V( 1 ) = ONE
+               V( 2 ) = VS*U1
+               V( 3 ) = VS*U2
+*
+*              Apply transformations from the right.
+*
+               DO 260 JR = IFRSTM, MIN( J+3, ILAST )
+                  TEMP = TAU*( H( JR, J )+V( 2 )*H( JR, J+1 )+V( 3 )*
+     $                   H( JR, J+2 ) )
+                  H( JR, J ) = H( JR, J ) - TEMP
+                  H( JR, J+1 ) = H( JR, J+1 ) - TEMP*V( 2 )
+                  H( JR, J+2 ) = H( JR, J+2 ) - TEMP*V( 3 )
+  260          CONTINUE
+               DO 270 JR = IFRSTM, J + 2
+                  TEMP = TAU*( T( JR, J )+V( 2 )*T( JR, J+1 )+V( 3 )*
+     $                   T( JR, J+2 ) )
+                  T( JR, J ) = T( JR, J ) - TEMP
+                  T( JR, J+1 ) = T( JR, J+1 ) - TEMP*V( 2 )
+                  T( JR, J+2 ) = T( JR, J+2 ) - TEMP*V( 3 )
+  270          CONTINUE
+               IF( ILZ ) THEN
+                  DO 280 JR = 1, N
+                     TEMP = TAU*( Z( JR, J )+V( 2 )*Z( JR, J+1 )+V( 3 )*
+     $                      Z( JR, J+2 ) )
+                     Z( JR, J ) = Z( JR, J ) - TEMP
+                     Z( JR, J+1 ) = Z( JR, J+1 ) - TEMP*V( 2 )
+                     Z( JR, J+2 ) = Z( JR, J+2 ) - TEMP*V( 3 )
+  280             CONTINUE
+               END IF
+               T( J+1, J ) = ZERO
+               T( J+2, J ) = ZERO
+  290       CONTINUE
+*
+*           Last elements: Use Givens rotations
+*
+*           Rotations from the left
+*
+            J = ILAST - 1
+            TEMP = H( J, J-1 )
+            CALL DLARTG( TEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
+            H( J+1, J-1 ) = ZERO
+*
+            DO 300 JC = J, ILASTM
+               TEMP = C*H( J, JC ) + S*H( J+1, JC )
+               H( J+1, JC ) = -S*H( J, JC ) + C*H( J+1, JC )
+               H( J, JC ) = TEMP
+               TEMP2 = C*T( J, JC ) + S*T( J+1, JC )
+               T( J+1, JC ) = -S*T( J, JC ) + C*T( J+1, JC )
+               T( J, JC ) = TEMP2
+  300       CONTINUE
+            IF( ILQ ) THEN
+               DO 310 JR = 1, N
+                  TEMP = C*Q( JR, J ) + S*Q( JR, J+1 )
+                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
+                  Q( JR, J ) = TEMP
+  310          CONTINUE
+            END IF
+*
+*           Rotations from the right.
+*
+            TEMP = T( J+1, J+1 )
+            CALL DLARTG( TEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
+            T( J+1, J ) = ZERO
+*
+            DO 320 JR = IFRSTM, ILAST
+               TEMP = C*H( JR, J+1 ) + S*H( JR, J )
+               H( JR, J ) = -S*H( JR, J+1 ) + C*H( JR, J )
+               H( JR, J+1 ) = TEMP
+  320       CONTINUE
+            DO 330 JR = IFRSTM, ILAST - 1
+               TEMP = C*T( JR, J+1 ) + S*T( JR, J )
+               T( JR, J ) = -S*T( JR, J+1 ) + C*T( JR, J )
+               T( JR, J+1 ) = TEMP
+  330       CONTINUE
+            IF( ILZ ) THEN
+               DO 340 JR = 1, N
+                  TEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
+                  Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )
+                  Z( JR, J+1 ) = TEMP
+  340          CONTINUE
+            END IF
+*
+*           End of Double-Shift code
+*
+         END IF
+*
+         GO TO 350
+*
+*        End of iteration loop
+*
+  350    CONTINUE
+  360 CONTINUE
+*
+*     Drop-through = non-convergence
+*
+      INFO = ILAST
+      GO TO 420
+*
+*     Successful completion of all QZ steps
+*
+  380 CONTINUE
+*
+*     Set Eigenvalues 1:ILO-1
+*
+      DO 410 J = 1, ILO - 1
+         IF( T( J, J ).LT.ZERO ) THEN
+            IF( ILSCHR ) THEN
+               DO 390 JR = 1, J
+                  H( JR, J ) = -H( JR, J )
+                  T( JR, J ) = -T( JR, J )
+  390          CONTINUE
+            ELSE
+               H( J, J ) = -H( J, J )
+               T( J, J ) = -T( J, J )
+            END IF
+            IF( ILZ ) THEN
+               DO 400 JR = 1, N
+                  Z( JR, J ) = -Z( JR, J )
+  400          CONTINUE
+            END IF
+         END IF
+         ALPHAR( J ) = H( J, J )
+         ALPHAI( J ) = ZERO
+         BETA( J ) = T( J, J )
+  410 CONTINUE
+*
+*     Normal Termination
+*
+      INFO = 0
+*
+*     Exit (other than argument error) -- return optimal workspace size
+*
+  420 CONTINUE
+      WORK( 1 ) = DBLE( N )
+      RETURN
+*
+*     End of DHGEQZ
+*
+      END
diff --git a/libcruft/lapack/dhseqr.f b/libcruft/lapack/dhseqr.f
new file mode 100644
index 0000000..5b307fa
--- /dev/null
+++ b/libcruft/lapack/dhseqr.f
@@ -0,0 +1,407 @@
+      SUBROUTINE DHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,
+     $                   LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDH, LDZ, LWORK, N
+      CHARACTER          COMPZ, JOB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), WI( * ), WORK( * ), WR( * ),
+     $                   Z( LDZ, * )
+*     ..
+*     Purpose
+*     =======
+*
+*     DHSEQR computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**T, where T is an upper quasi-triangular matrix (the
+*     Schur form), and Z is the orthogonal matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input orthogonal
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
+*
+*     Arguments
+*     =========
+*
+*     JOB   (input) CHARACTER*1
+*           = 'E':  compute eigenvalues only;
+*           = 'S':  compute eigenvalues and the Schur form T.
+*
+*     COMPZ (input) CHARACTER*1
+*           = 'N':  no Schur vectors are computed;
+*           = 'I':  Z is initialized to the unit matrix and the matrix Z
+*                   of Schur vectors of H is returned;
+*           = 'V':  Z must contain an orthogonal matrix Q on entry, and
+*                   the product Q*Z is returned.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*           set by a previous call to DGEBAL, and then passed to DGEHRD
+*           when the matrix output by DGEBAL is reduced to Hessenberg
+*           form. Otherwise ILO and IHI should be set to 1 and N
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) DOUBLE PRECISION array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and JOB = 'S', then H contains the
+*           upper quasi-triangular matrix T from the Schur decomposition
+*           (the Schur form); 2-by-2 diagonal blocks (corresponding to
+*           complex conjugate pairs of eigenvalues) are returned in
+*           standard form, with H(i,i) = H(i+1,i+1) and
+*           H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and JOB = 'E', the
+*           contents of H are unspecified on exit.  (The output value of
+*           H when INFO.GT.0 is given under the description of INFO
+*           below.)
+*
+*           Unlike earlier versions of DHSEQR, this subroutine may
+*           explicitly H(i,j) = 0 for i.GT.j and j = 1, 2, ... ILO-1
+*           or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     WR    (output) DOUBLE PRECISION array, dimension (N)
+*     WI    (output) DOUBLE PRECISION array, dimension (N)
+*           The real and imaginary parts, respectively, of the computed
+*           eigenvalues. If two eigenvalues are computed as a complex
+*           conjugate pair, they are stored in consecutive elements of
+*           WR and WI, say the i-th and (i+1)th, with WI(i) .GT. 0 and
+*           WI(i+1) .LT. 0. If JOB = 'S', the eigenvalues are stored in
+*           the same order as on the diagonal of the Schur form returned
+*           in H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2
+*           diagonal block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and
+*           WI(i+1) = -WI(i).
+*
+*     Z     (input/output) DOUBLE PRECISION array, dimension (LDZ,N)
+*           If COMPZ = 'N', Z is not referenced.
+*           If COMPZ = 'I', on entry Z need not be set and on exit,
+*           if INFO = 0, Z contains the orthogonal matrix Z of the Schur
+*           vectors of H.  If COMPZ = 'V', on entry Z must contain an
+*           N-by-N matrix Q, which is assumed to be equal to the unit
+*           matrix except for the submatrix Z(ILO:IHI,ILO:IHI). On exit,
+*           if INFO = 0, Z contains Q*Z.
+*           Normally Q is the orthogonal matrix generated by DORGHR
+*           after the call to DGEHRD which formed the Hessenberg matrix
+*           H. (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if COMPZ = 'I' or
+*           COMPZ = 'V', then LDZ.GE.MAX(1,N).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
+*           On exit, if INFO = 0, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then DHSEQR does a workspace query.
+*           In this case, DHSEQR checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .LT. 0:  if INFO = -i, the i-th argument had an illegal
+*                    value
+*           .GT. 0:  if INFO = i, DHSEQR failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and JOB = 'E', then on exit, the
+*                remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and JOB   = 'S', then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is an orthogonal matrix.  The final
+*                value of H is upper Hessenberg and quasi-triangular
+*                in rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and COMPZ = 'V', then on exit
+*
+*                  (final value of Z)  =  (initial value of Z)*U
+*
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'I', then on exit
+*                      (final value of Z)  = U
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'N', then Z is not
+*                accessed.
+*
+*     ================================================================
+*             Default values supplied by
+*             ILAENV(ISPEC,'DHSEQR',JOB(:1)//COMPZ(:1),N,ILO,IHI,LWORK).
+*             It is suggested that these defaults be adjusted in order
+*             to attain best performance in each particular
+*             computational environment.
+*
+*            ISPEC=1:  The DLAHQR vs DLAQR0 crossover point.
+*                      Default: 75. (Must be at least 11.)
+*
+*            ISPEC=2:  Recommended deflation window size.
+*                      This depends on ILO, IHI and NS.  NS is the
+*                      number of simultaneous shifts returned
+*                      by ILAENV(ISPEC=4).  (See ISPEC=4 below.)
+*                      The default for (IHI-ILO+1).LE.500 is NS.
+*                      The default for (IHI-ILO+1).GT.500 is 3*NS/2.
+*
+*            ISPEC=3:  Nibble crossover point. (See ILAENV for
+*                      details.)  Default: 14% of deflation window
+*                      size.
+*
+*            ISPEC=4:  Number of simultaneous shifts, NS, in
+*                      a multi-shift QR iteration.
+*
+*                      If IHI-ILO+1 is ...
+*
+*                      greater than      ...but less    ... the
+*                      or equal to ...      than        default is
+*
+*                           1               30          NS -   2(+)
+*                          30               60          NS -   4(+)
+*                          60              150          NS =  10(+)
+*                         150              590          NS =  **
+*                         590             3000          NS =  64
+*                        3000             6000          NS = 128
+*                        6000             infinity      NS = 256
+*
+*                  (+)  By default some or all matrices of this order 
+*                       are passed to the implicit double shift routine
+*                       DLAHQR and NS is ignored.  See ISPEC=1 above 
+*                       and comments in IPARM for details.
+*
+*                       The asterisks (**) indicate an ad-hoc
+*                       function of N increasing from 10 to 64.
+*
+*            ISPEC=5:  Select structured matrix multiply.
+*                      (See ILAENV for details.) Default: 3.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    DLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== NL allocates some local workspace to help small matrices
+*     .    through a rare DLAHQR failure.  NL .GT. NTINY = 11 is
+*     .    required and NL .LE. NMIN = ILAENV(ISPEC=1,...) is recom-
+*     .    mended.  (The default value of NMIN is 75.)  Using NL = 49
+*     .    allows up to six simultaneous shifts and a 16-by-16
+*     .    deflation window.  ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            NL
+      PARAMETER          ( NL = 49 )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0 )
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   HL( NL, NL ), WORKL( NL )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, KBOT, NMIN
+      LOGICAL            INITZ, LQUERY, WANTT, WANTZ
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      LOGICAL            LSAME
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACPY, DLAHQR, DLAQR0, DLASET, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Decode and check the input parameters. ====
+*
+      WANTT = LSAME( JOB, 'S' )
+      INITZ = LSAME( COMPZ, 'I' )
+      WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )
+      WORK( 1 ) = DBLE( MAX( 1, N ) )
+      LQUERY = LWORK.EQ.-1
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( LDH.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -13
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+*
+*        ==== Quick return in case of invalid argument. ====
+*
+         CALL XERBLA( 'DHSEQR', -INFO )
+         RETURN
+*
+      ELSE IF( N.EQ.0 ) THEN
+*
+*        ==== Quick return in case N = 0; nothing to do. ====
+*
+         RETURN
+*
+      ELSE IF( LQUERY ) THEN
+*
+*        ==== Quick return in case of a workspace query ====
+*
+         CALL DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,
+     $                IHI, Z, LDZ, WORK, LWORK, INFO )
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+         WORK( 1 ) = MAX( DBLE( MAX( 1, N ) ), WORK( 1 ) )
+         RETURN
+*
+      ELSE
+*
+*        ==== copy eigenvalues isolated by DGEBAL ====
+*
+         DO 10 I = 1, ILO - 1
+            WR( I ) = H( I, I )
+            WI( I ) = ZERO
+   10    CONTINUE
+         DO 20 I = IHI + 1, N
+            WR( I ) = H( I, I )
+            WI( I ) = ZERO
+   20    CONTINUE
+*
+*        ==== Initialize Z, if requested ====
+*
+         IF( INITZ )
+     $      CALL DLASET( 'A', N, N, ZERO, ONE, Z, LDZ )
+*
+*        ==== Quick return if possible ====
+*
+         IF( ILO.EQ.IHI ) THEN
+            WR( ILO ) = H( ILO, ILO )
+            WI( ILO ) = ZERO
+            RETURN
+         END IF
+*
+*        ==== DLAHQR/DLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'DHSEQR', JOB( : 1 ) // COMPZ( : 1 ), N,
+     $          ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== DLAQR0 for big matrices; DLAHQR for small ones ====
+*
+         IF( N.GT.NMIN ) THEN
+            CALL DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,
+     $                   IHI, Z, LDZ, WORK, LWORK, INFO )
+         ELSE
+*
+*           ==== Small matrix ====
+*
+            CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,
+     $                   IHI, Z, LDZ, INFO )
+*
+            IF( INFO.GT.0 ) THEN
+*
+*              ==== A rare DLAHQR failure!  DLAQR0 sometimes succeeds
+*              .    when DLAHQR fails. ====
+*
+               KBOT = INFO
+*
+               IF( N.GE.NL ) THEN
+*
+*                 ==== Larger matrices have enough subdiagonal scratch
+*                 .    space to call DLAQR0 directly. ====
+*
+                  CALL DLAQR0( WANTT, WANTZ, N, ILO, KBOT, H, LDH, WR,
+     $                         WI, ILO, IHI, Z, LDZ, WORK, LWORK, INFO )
+*
+               ELSE
+*
+*                 ==== Tiny matrices don't have enough subdiagonal
+*                 .    scratch space to benefit from DLAQR0.  Hence,
+*                 .    tiny matrices must be copied into a larger
+*                 .    array before calling DLAQR0. ====
+*
+                  CALL DLACPY( 'A', N, N, H, LDH, HL, NL )
+                  HL( N+1, N ) = ZERO
+                  CALL DLASET( 'A', NL, NL-N, ZERO, ZERO, HL( 1, N+1 ),
+     $                         NL )
+                  CALL DLAQR0( WANTT, WANTZ, NL, ILO, KBOT, HL, NL, WR,
+     $                         WI, ILO, IHI, Z, LDZ, WORKL, NL, INFO )
+                  IF( WANTT .OR. INFO.NE.0 )
+     $               CALL DLACPY( 'A', N, N, HL, NL, H, LDH )
+               END IF
+            END IF
+         END IF
+*
+*        ==== Clear out the trash, if necessary. ====
+*
+         IF( ( WANTT .OR. INFO.NE.0 ) .AND. N.GT.2 )
+     $      CALL DLASET( 'L', N-2, N-2, ZERO, ZERO, H( 3, 1 ), LDH )
+*
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+*
+         WORK( 1 ) = MAX( DBLE( MAX( 1, N ) ), WORK( 1 ) )
+      END IF
+*
+*     ==== End of DHSEQR ====
+*
+      END
diff --git a/libcruft/lapack/dlabad.f b/libcruft/lapack/dlabad.f
new file mode 100644
index 0000000..05ff5d4
--- /dev/null
+++ b/libcruft/lapack/dlabad.f
@@ -0,0 +1,55 @@
+      SUBROUTINE DLABAD( SMALL, LARGE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   LARGE, SMALL
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLABAD takes as input the values computed by DLAMCH for underflow and
+*  overflow, and returns the square root of each of these values if the
+*  log of LARGE is sufficiently large.  This subroutine is intended to
+*  identify machines with a large exponent range, such as the Crays, and
+*  redefine the underflow and overflow limits to be the square roots of
+*  the values computed by DLAMCH.  This subroutine is needed because
+*  DLAMCH does not compensate for poor arithmetic in the upper half of
+*  the exponent range, as is found on a Cray.
+*
+*  Arguments
+*  =========
+*
+*  SMALL   (input/output) DOUBLE PRECISION
+*          On entry, the underflow threshold as computed by DLAMCH.
+*          On exit, if LOG10(LARGE) is sufficiently large, the square
+*          root of SMALL, otherwise unchanged.
+*
+*  LARGE   (input/output) DOUBLE PRECISION
+*          On entry, the overflow threshold as computed by DLAMCH.
+*          On exit, if LOG10(LARGE) is sufficiently large, the square
+*          root of LARGE, otherwise unchanged.
+*
+*  =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC          LOG10, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     If it looks like we're on a Cray, take the square root of
+*     SMALL and LARGE to avoid overflow and underflow problems.
+*
+      IF( LOG10( LARGE ).GT.2000.D0 ) THEN
+         SMALL = SQRT( SMALL )
+         LARGE = SQRT( LARGE )
+      END IF
+*
+      RETURN
+*
+*     End of DLABAD
+*
+      END
diff --git a/libcruft/lapack/dlabrd.f b/libcruft/lapack/dlabrd.f
new file mode 100644
index 0000000..196b130
--- /dev/null
+++ b/libcruft/lapack/dlabrd.f
@@ -0,0 +1,290 @@
+      SUBROUTINE DLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,
+     $                   LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, LDX, LDY, M, N, NB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), D( * ), E( * ), TAUP( * ),
+     $                   TAUQ( * ), X( LDX, * ), Y( LDY, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLABRD reduces the first NB rows and columns of a real general
+*  m by n matrix A to upper or lower bidiagonal form by an orthogonal
+*  transformation Q' * A * P, and returns the matrices X and Y which
+*  are needed to apply the transformation to the unreduced part of A.
+*
+*  If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower
+*  bidiagonal form.
+*
+*  This is an auxiliary routine called by DGEBRD
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of leading rows and columns of A to be reduced.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit, the first NB rows and columns of the matrix are
+*          overwritten; the rest of the array is unchanged.
+*          If m >= n, elements on and below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the orthogonal
+*            matrix Q as a product of elementary reflectors; and
+*            elements above the diagonal in the first NB rows, with the
+*            array TAUP, represent the orthogonal matrix P as a product
+*            of elementary reflectors.
+*          If m < n, elements below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the orthogonal
+*            matrix Q as a product of elementary reflectors, and
+*            elements on and above the diagonal in the first NB rows,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (NB)
+*          The diagonal elements of the first NB rows and columns of
+*          the reduced matrix.  D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (NB)
+*          The off-diagonal elements of the first NB rows and columns of
+*          the reduced matrix.
+*
+*  TAUQ    (output) DOUBLE PRECISION array dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix Q. See Further Details.
+*
+*  TAUP    (output) DOUBLE PRECISION array, dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix P. See Further Details.
+*
+*  X       (output) DOUBLE PRECISION array, dimension (LDX,NB)
+*          The m-by-nb matrix X required to update the unreduced part
+*          of A.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of the array X. LDX >= M.
+*
+*  Y       (output) DOUBLE PRECISION array, dimension (LDY,NB)
+*          The n-by-nb matrix Y required to update the unreduced part
+*          of A.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*     Q = H(1) H(2) . . . H(nb)  and  P = G(1) G(2) . . . G(nb)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors.
+*
+*  If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in
+*  A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in
+*  A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The elements of the vectors v and u together form the m-by-nb matrix
+*  V and the nb-by-n matrix U' which are needed, with X and Y, to apply
+*  the transformation to the unreduced part of the matrix, using a block
+*  update of the form:  A := A - V*Y' - X*U'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with nb = 2:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  1   1   u1  u1  u1 )           (  1   u1  u1  u1  u1  u1 )
+*    (  v1  1   1   u2  u2 )           (  1   1   u2  u2  u2  u2 )
+*    (  v1  v2  a   a   a  )           (  v1  1   a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )
+*
+*  where a denotes an element of the original matrix which is unchanged,
+*  vi denotes an element of the vector defining H(i), and ui an element
+*  of the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DLARFG, DSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, NB
+*
+*           Update A(i:m,i)
+*
+            CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 )
+            CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ),
+     $                  LDX, A( 1, I ), 1, ONE, A( I, I ), 1 )
+*
+*           Generate reflection Q(i) to annihilate A(i+1:m,i)
+*
+            CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL DGEMV( 'Transpose', M-I+1, N-I, ONE, A( I, I+1 ),
+     $                     LDA, A( I, I ), 1, ZERO, Y( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, A( I, 1 ), LDA,
+     $                     A( I, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, X( I, 1 ), LDX,
+     $                     A( I, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+*
+*              Update A(i,i+1:n)
+*
+               CALL DGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ),
+     $                     LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA )
+               CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, X( I, 1 ), LDX, ONE, A( I, I+1 ), LDA )
+*
+*              Generate reflection P(i) to annihilate A(i,i+2:n)
+*
+               CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),
+     $                      LDA, TAUP( I ) )
+               E( I ) = A( I, I+1 )
+               A( I, I+1 ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL DGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', N-I, I, ONE, Y( I+1, 1 ), LDY,
+     $                     A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL DGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i,i:n)
+*
+            CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ),
+     $                  LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA )
+            CALL DGEMV( 'Transpose', I-1, N-I+1, -ONE, A( 1, I ), LDA,
+     $                  X( I, 1 ), LDX, ONE, A( I, I ), LDA )
+*
+*           Generate reflection P(i) to annihilate A(i,i+1:n)
+*
+            CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = A( I, I )
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL DGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', N-I+1, I-1, ONE, Y( I, 1 ), LDY,
+     $                     A( I, I ), LDA, ZERO, X( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL DGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+*
+*              Update A(i+1:m,i)
+*
+               CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 )
+               CALL DGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ),
+     $                     LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 )
+*
+*              Generate reflection Q(i) to annihilate A(i+2:m,i)
+*
+               CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = A( I+1, I )
+               A( I+1, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL DGEMV( 'Transpose', M-I, N-I, ONE, A( I+1, I+1 ),
+     $                     LDA, A( I+1, I ), 1, ZERO, Y( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', M-I, I-1, ONE, A( I+1, 1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', M-I, I, ONE, X( I+1, 1 ), LDX,
+     $                     A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL DGEMV( 'Transpose', I, N-I, -ONE, A( 1, I+1 ), LDA,
+     $                     Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DLABRD
+*
+      END
diff --git a/libcruft/lapack/dlacn2.f b/libcruft/lapack/dlacn2.f
new file mode 100644
index 0000000..6705d25
--- /dev/null
+++ b/libcruft/lapack/dlacn2.f
@@ -0,0 +1,214 @@
+      SUBROUTINE DLACN2( N, V, X, ISGN, EST, KASE, ISAVE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      DOUBLE PRECISION   EST
+*     ..
+*     .. Array Arguments ..
+      INTEGER            ISGN( * ), ISAVE( 3 )
+      DOUBLE PRECISION   V( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLACN2 estimates the 1-norm of a square, real matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) DOUBLE PRECISION array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) DOUBLE PRECISION array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         and DLACN2 must be re-called with all the other parameters
+*         unchanged.
+*
+*  ISGN   (workspace) INTEGER array, dimension (N)
+*
+*  EST    (input/output) DOUBLE PRECISION
+*         On entry with KASE = 1 or 2 and ISAVE(1) = 3, EST should be
+*         unchanged from the previous call to DLACN2.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to DLACN2, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from DLACN2, KASE will again be 0.
+*
+*  ISAVE  (input/output) INTEGER array, dimension (3)
+*         ISAVE is used to save variables between calls to DLACN2
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named SONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  This is a thread safe version of DLACON, which uses the array ISAVE
+*  in place of a SAVE statement, as follows:
+*
+*     DLACON     DLACN2
+*      JUMP     ISAVE(1)
+*      J        ISAVE(2)
+*      ITER     ISAVE(3)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, JLAST
+      DOUBLE PRECISION   ALTSGN, ESTOLD, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DASUM
+      EXTERNAL           IDAMAX, DASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, NINT, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = ONE / DBLE( N )
+   10    CONTINUE
+         KASE = 1
+         ISAVE( 1 ) = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 110, 140 )ISAVE( 1 )
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 150
+      END IF
+      EST = DASUM( N, X, 1 )
+*
+      DO 30 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+   30 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 2
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+   40 CONTINUE
+      ISAVE( 2 ) = IDAMAX( N, X, 1 )
+      ISAVE( 3 ) = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = ZERO
+   60 CONTINUE
+      X( ISAVE( 2 ) ) = ONE
+      KASE = 1
+      ISAVE( 1 ) = 3
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL DCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = DASUM( N, V, 1 )
+      DO 80 I = 1, N
+         IF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )
+     $      GO TO 90
+   80 CONTINUE
+*     REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.
+      GO TO 120
+*
+   90 CONTINUE
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 120
+*
+      DO 100 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+  100 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 4
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 4)
+*     X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+  110 CONTINUE
+      JLAST = ISAVE( 2 )
+      ISAVE( 2 ) = IDAMAX( N, X, 1 )
+      IF( ( X( JLAST ).NE.ABS( X( ISAVE( 2 ) ) ) ) .AND.
+     $    ( ISAVE( 3 ).LT.ITMAX ) ) THEN
+         ISAVE( 3 ) = ISAVE( 3 ) + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  120 CONTINUE
+      ALTSGN = ONE
+      DO 130 I = 1, N
+         X( I ) = ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) )
+         ALTSGN = -ALTSGN
+  130 CONTINUE
+      KASE = 1
+      ISAVE( 1 ) = 5
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  140 CONTINUE
+      TEMP = TWO*( DASUM( N, X, 1 ) / DBLE( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL DCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  150 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of DLACN2
+*
+      END
diff --git a/libcruft/lapack/dlacon.f b/libcruft/lapack/dlacon.f
new file mode 100644
index 0000000..f113b03
--- /dev/null
+++ b/libcruft/lapack/dlacon.f
@@ -0,0 +1,205 @@
+      SUBROUTINE DLACON( N, V, X, ISGN, EST, KASE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      DOUBLE PRECISION   EST
+*     ..
+*     .. Array Arguments ..
+      INTEGER            ISGN( * )
+      DOUBLE PRECISION   V( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLACON estimates the 1-norm of a square, real matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) DOUBLE PRECISION array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) DOUBLE PRECISION array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         and DLACON must be re-called with all the other parameters
+*         unchanged.
+*
+*  ISGN   (workspace) INTEGER array, dimension (N)
+*
+*  EST    (input/output) DOUBLE PRECISION
+*         On entry with KASE = 1 or 2 and JUMP = 3, EST should be
+*         unchanged from the previous call to DLACON.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to DLACON, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from DLACON, KASE will again be 0.
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named SONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITER, J, JLAST, JUMP
+      DOUBLE PRECISION   ALTSGN, ESTOLD, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DASUM
+      EXTERNAL           IDAMAX, DASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, NINT, SIGN
+*     ..
+*     .. Save statement ..
+      SAVE
+*     ..
+*     .. Executable Statements ..
+*
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = ONE / DBLE( N )
+   10    CONTINUE
+         KASE = 1
+         JUMP = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 110, 140 )JUMP
+*
+*     ................ ENTRY   (JUMP = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 150
+      END IF
+      EST = DASUM( N, X, 1 )
+*
+      DO 30 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+   30 CONTINUE
+      KASE = 2
+      JUMP = 2
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+   40 CONTINUE
+      J = IDAMAX( N, X, 1 )
+      ITER = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = ZERO
+   60 CONTINUE
+      X( J ) = ONE
+      KASE = 1
+      JUMP = 3
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL DCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = DASUM( N, V, 1 )
+      DO 80 I = 1, N
+         IF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )
+     $      GO TO 90
+   80 CONTINUE
+*     REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.
+      GO TO 120
+*
+   90 CONTINUE
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 120
+*
+      DO 100 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+  100 CONTINUE
+      KASE = 2
+      JUMP = 4
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 4)
+*     X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+  110 CONTINUE
+      JLAST = J
+      J = IDAMAX( N, X, 1 )
+      IF( ( X( JLAST ).NE.ABS( X( J ) ) ) .AND. ( ITER.LT.ITMAX ) ) THEN
+         ITER = ITER + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  120 CONTINUE
+      ALTSGN = ONE
+      DO 130 I = 1, N
+         X( I ) = ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) )
+         ALTSGN = -ALTSGN
+  130 CONTINUE
+      KASE = 1
+      JUMP = 5
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  140 CONTINUE
+      TEMP = TWO*( DASUM( N, X, 1 ) / DBLE( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL DCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  150 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of DLACON
+*
+      END
diff --git a/libcruft/lapack/dlacpy.f b/libcruft/lapack/dlacpy.f
new file mode 100644
index 0000000..d72603a
--- /dev/null
+++ b/libcruft/lapack/dlacpy.f
@@ -0,0 +1,87 @@
+      SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDB, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLACPY copies all or part of a two-dimensional matrix A to another
+*  matrix B.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be copied to B.
+*          = 'U':      Upper triangular part
+*          = 'L':      Lower triangular part
+*          Otherwise:  All of the matrix A
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The m by n matrix A.  If UPLO = 'U', only the upper triangle
+*          or trapezoid is accessed; if UPLO = 'L', only the lower
+*          triangle or trapezoid is accessed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (output) DOUBLE PRECISION array, dimension (LDB,N)
+*          On exit, B = A in the locations specified by UPLO.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( J, M )
+               B( I, J ) = A( I, J )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+         DO 40 J = 1, N
+            DO 30 I = J, M
+               B( I, J ) = A( I, J )
+   30       CONTINUE
+   40    CONTINUE
+      ELSE
+         DO 60 J = 1, N
+            DO 50 I = 1, M
+               B( I, J ) = A( I, J )
+   50       CONTINUE
+   60    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DLACPY
+*
+      END
diff --git a/libcruft/lapack/dladiv.f b/libcruft/lapack/dladiv.f
new file mode 100644
index 0000000..b6a74d1
--- /dev/null
+++ b/libcruft/lapack/dladiv.f
@@ -0,0 +1,62 @@
+      SUBROUTINE DLADIV( A, B, C, D, P, Q )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   A, B, C, D, P, Q
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLADIV performs complex division in  real arithmetic
+*
+*                        a + i*b
+*             p + i*q = ---------
+*                        c + i*d
+*
+*  The algorithm is due to Robert L. Smith and can be found
+*  in D. Knuth, The art of Computer Programming, Vol.2, p.195
+*
+*  Arguments
+*  =========
+*
+*  A       (input) DOUBLE PRECISION
+*  B       (input) DOUBLE PRECISION
+*  C       (input) DOUBLE PRECISION
+*  D       (input) DOUBLE PRECISION
+*          The scalars a, b, c, and d in the above expression.
+*
+*  P       (output) DOUBLE PRECISION
+*  Q       (output) DOUBLE PRECISION
+*          The scalars p and q in the above expression.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION   E, F
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+      IF( ABS( D ).LT.ABS( C ) ) THEN
+         E = D / C
+         F = C + D*E
+         P = ( A+B*E ) / F
+         Q = ( B-A*E ) / F
+      ELSE
+         E = C / D
+         F = D + C*E
+         P = ( B+A*E ) / F
+         Q = ( -A+B*E ) / F
+      END IF
+*
+      RETURN
+*
+*     End of DLADIV
+*
+      END
diff --git a/libcruft/lapack/dlae2.f b/libcruft/lapack/dlae2.f
new file mode 100644
index 0000000..8e81c60
--- /dev/null
+++ b/libcruft/lapack/dlae2.f
@@ -0,0 +1,123 @@
+      SUBROUTINE DLAE2( A, B, C, RT1, RT2 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   A, B, C, RT1, RT2
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAE2  computes the eigenvalues of a 2-by-2 symmetric matrix
+*     [  A   B  ]
+*     [  B   C  ].
+*  On return, RT1 is the eigenvalue of larger absolute value, and RT2
+*  is the eigenvalue of smaller absolute value.
+*
+*  Arguments
+*  =========
+*
+*  A       (input) DOUBLE PRECISION
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  B       (input) DOUBLE PRECISION
+*          The (1,2) and (2,1) elements of the 2-by-2 matrix.
+*
+*  C       (input) DOUBLE PRECISION
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  RT1     (output) DOUBLE PRECISION
+*          The eigenvalue of larger absolute value.
+*
+*  RT2     (output) DOUBLE PRECISION
+*          The eigenvalue of smaller absolute value.
+*
+*  Further Details
+*  ===============
+*
+*  RT1 is accurate to a few ulps barring over/underflow.
+*
+*  RT2 may be inaccurate if there is massive cancellation in the
+*  determinant A*C-B*B; higher precision or correctly rounded or
+*  correctly truncated arithmetic would be needed to compute RT2
+*  accurately in all cases.
+*
+*  Overflow is possible only if RT1 is within a factor of 5 of overflow.
+*  Underflow is harmless if the input data is 0 or exceeds
+*     underflow_threshold / macheps.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D0 )
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   HALF
+      PARAMETER          ( HALF = 0.5D0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AB, ACMN, ACMX, ADF, DF, RT, SM, TB
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Compute the eigenvalues
+*
+      SM = A + C
+      DF = A - C
+      ADF = ABS( DF )
+      TB = B + B
+      AB = ABS( TB )
+      IF( ABS( A ).GT.ABS( C ) ) THEN
+         ACMX = A
+         ACMN = C
+      ELSE
+         ACMX = C
+         ACMN = A
+      END IF
+      IF( ADF.GT.AB ) THEN
+         RT = ADF*SQRT( ONE+( AB / ADF )**2 )
+      ELSE IF( ADF.LT.AB ) THEN
+         RT = AB*SQRT( ONE+( ADF / AB )**2 )
+      ELSE
+*
+*        Includes case AB=ADF=0
+*
+         RT = AB*SQRT( TWO )
+      END IF
+      IF( SM.LT.ZERO ) THEN
+         RT1 = HALF*( SM-RT )
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE IF( SM.GT.ZERO ) THEN
+         RT1 = HALF*( SM+RT )
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE
+*
+*        Includes case RT1 = RT2 = 0
+*
+         RT1 = HALF*RT
+         RT2 = -HALF*RT
+      END IF
+      RETURN
+*
+*     End of DLAE2
+*
+      END
diff --git a/libcruft/lapack/dlaed6.f b/libcruft/lapack/dlaed6.f
new file mode 100644
index 0000000..58a48b1
--- /dev/null
+++ b/libcruft/lapack/dlaed6.f
@@ -0,0 +1,327 @@
+      SUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     February 2007
+*
+*     .. Scalar Arguments ..
+      LOGICAL            ORGATI
+      INTEGER            INFO, KNITER
+      DOUBLE PRECISION   FINIT, RHO, TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( 3 ), Z( 3 )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAED6 computes the positive or negative root (closest to the origin)
+*  of
+*                   z(1)        z(2)        z(3)
+*  f(x) =   rho + --------- + ---------- + ---------
+*                  d(1)-x      d(2)-x      d(3)-x
+*
+*  It is assumed that
+*
+*        if ORGATI = .true. the root is between d(2) and d(3);
+*        otherwise it is between d(1) and d(2)
+*
+*  This routine will be called by DLAED4 when necessary. In most cases,
+*  the root sought is the smallest in magnitude, though it might not be
+*  in some extremely rare situations.
+*
+*  Arguments
+*  =========
+*
+*  KNITER       (input) INTEGER
+*               Refer to DLAED4 for its significance.
+*
+*  ORGATI       (input) LOGICAL
+*               If ORGATI is true, the needed root is between d(2) and
+*               d(3); otherwise it is between d(1) and d(2).  See
+*               DLAED4 for further details.
+*
+*  RHO          (input) DOUBLE PRECISION
+*               Refer to the equation f(x) above.
+*
+*  D            (input) DOUBLE PRECISION array, dimension (3)
+*               D satisfies d(1) < d(2) < d(3).
+*
+*  Z            (input) DOUBLE PRECISION array, dimension (3)
+*               Each of the elements in z must be positive.
+*
+*  FINIT        (input) DOUBLE PRECISION
+*               The value of f at 0. It is more accurate than the one
+*               evaluated inside this routine (if someone wants to do
+*               so).
+*
+*  TAU          (output) DOUBLE PRECISION
+*               The root of the equation f(x).
+*
+*  INFO         (output) INTEGER
+*               = 0: successful exit
+*               > 0: if INFO = 1, failure to converge
+*
+*  Further Details
+*  ===============
+*
+*  30/06/99: Based on contributions by
+*     Ren-Cang Li, Computer Science Division, University of California
+*     at Berkeley, USA
+*
+*  10/02/03: This version has a few statements commented out for thread
+*  safety (machine parameters are computed on each entry). SJH.
+*
+*  05/10/06: Modified from a new version of Ren-Cang Li, use
+*     Gragg-Thornton-Warner cubic convergent scheme for better stability.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 40 )
+      DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR, EIGHT
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
+     $                   THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0 )
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DSCALE( 3 ), ZSCALE( 3 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            SCALE
+      INTEGER            I, ITER, NITER
+      DOUBLE PRECISION   A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,
+     $                   FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,
+     $                   SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4, 
+     $                   LBD, UBD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, LOG, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+      IF( ORGATI ) THEN
+         LBD = D(2)
+         UBD = D(3)
+      ELSE
+         LBD = D(1)
+         UBD = D(2)
+      END IF
+      IF( FINIT .LT. ZERO )THEN
+         LBD = ZERO
+      ELSE
+         UBD = ZERO 
+      END IF
+*
+      NITER = 1
+      TAU = ZERO
+      IF( KNITER.EQ.2 ) THEN
+         IF( ORGATI ) THEN
+            TEMP = ( D( 3 )-D( 2 ) ) / TWO
+            C = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )
+            A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )
+            B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )
+         ELSE
+            TEMP = ( D( 1 )-D( 2 ) ) / TWO
+            C = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )
+            A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )
+            B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )
+         END IF
+         TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
+         A = A / TEMP
+         B = B / TEMP
+         C = C / TEMP
+         IF( C.EQ.ZERO ) THEN
+            TAU = B / A
+         ELSE IF( A.LE.ZERO ) THEN
+            TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+         ELSE
+            TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+         END IF
+         IF( TAU .LT. LBD .OR. TAU .GT. UBD )
+     $      TAU = ( LBD+UBD )/TWO
+         IF( D(1).EQ.TAU .OR. D(2).EQ.TAU .OR. D(3).EQ.TAU ) THEN
+            TAU = ZERO
+         ELSE
+            TEMP = FINIT + TAU*Z(1)/( D(1)*( D( 1 )-TAU ) ) +
+     $                     TAU*Z(2)/( D(2)*( D( 2 )-TAU ) ) +
+     $                     TAU*Z(3)/( D(3)*( D( 3 )-TAU ) )
+            IF( TEMP .LE. ZERO )THEN
+               LBD = TAU
+            ELSE
+               UBD = TAU
+            END IF
+            IF( ABS( FINIT ).LE.ABS( TEMP ) )
+     $         TAU = ZERO
+         END IF
+      END IF
+*
+*     get machine parameters for possible scaling to avoid overflow
+*
+*     modified by Sven: parameters SMALL1, SMINV1, SMALL2,
+*     SMINV2, EPS are not SAVEd anymore between one call to the
+*     others but recomputed at each call
+*
+      EPS = DLAMCH( 'Epsilon' )
+      BASE = DLAMCH( 'Base' )
+      SMALL1 = BASE**( INT( LOG( DLAMCH( 'SafMin' ) ) / LOG( BASE ) /
+     $         THREE ) )
+      SMINV1 = ONE / SMALL1
+      SMALL2 = SMALL1*SMALL1
+      SMINV2 = SMINV1*SMINV1
+*
+*     Determine if scaling of inputs necessary to avoid overflow
+*     when computing 1/TEMP**3
+*
+      IF( ORGATI ) THEN
+         TEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )
+      ELSE
+         TEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )
+      END IF
+      SCALE = .FALSE.
+      IF( TEMP.LE.SMALL1 ) THEN
+         SCALE = .TRUE.
+         IF( TEMP.LE.SMALL2 ) THEN
+*
+*        Scale up by power of radix nearest 1/SAFMIN**(2/3)
+*
+            SCLFAC = SMINV2
+            SCLINV = SMALL2
+         ELSE
+*
+*        Scale up by power of radix nearest 1/SAFMIN**(1/3)
+*
+            SCLFAC = SMINV1
+            SCLINV = SMALL1
+         END IF
+*
+*        Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)
+*
+         DO 10 I = 1, 3
+            DSCALE( I ) = D( I )*SCLFAC
+            ZSCALE( I ) = Z( I )*SCLFAC
+   10    CONTINUE
+         TAU = TAU*SCLFAC
+         LBD = LBD*SCLFAC
+         UBD = UBD*SCLFAC
+      ELSE
+*
+*        Copy D and Z to DSCALE and ZSCALE
+*
+         DO 20 I = 1, 3
+            DSCALE( I ) = D( I )
+            ZSCALE( I ) = Z( I )
+   20    CONTINUE
+      END IF
+*
+      FC = ZERO
+      DF = ZERO
+      DDF = ZERO
+      DO 30 I = 1, 3
+         TEMP = ONE / ( DSCALE( I )-TAU )
+         TEMP1 = ZSCALE( I )*TEMP
+         TEMP2 = TEMP1*TEMP
+         TEMP3 = TEMP2*TEMP
+         FC = FC + TEMP1 / DSCALE( I )
+         DF = DF + TEMP2
+         DDF = DDF + TEMP3
+   30 CONTINUE
+      F = FINIT + TAU*FC
+*
+      IF( ABS( F ).LE.ZERO )
+     $   GO TO 60
+      IF( F .LE. ZERO )THEN
+         LBD = TAU
+      ELSE
+         UBD = TAU
+      END IF
+*
+*        Iteration begins -- Use Gragg-Thornton-Warner cubic convergent
+*                            scheme
+*
+*     It is not hard to see that
+*
+*           1) Iterations will go up monotonically
+*              if FINIT < 0;
+*
+*           2) Iterations will go down monotonically
+*              if FINIT > 0.
+*
+      ITER = NITER + 1
+*
+      DO 50 NITER = ITER, MAXIT
+*
+         IF( ORGATI ) THEN
+            TEMP1 = DSCALE( 2 ) - TAU
+            TEMP2 = DSCALE( 3 ) - TAU
+         ELSE
+            TEMP1 = DSCALE( 1 ) - TAU
+            TEMP2 = DSCALE( 2 ) - TAU
+         END IF
+         A = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DF
+         B = TEMP1*TEMP2*F
+         C = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDF
+         TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
+         A = A / TEMP
+         B = B / TEMP
+         C = C / TEMP
+         IF( C.EQ.ZERO ) THEN
+            ETA = B / A
+         ELSE IF( A.LE.ZERO ) THEN
+            ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+         ELSE
+            ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+         END IF
+         IF( F*ETA.GE.ZERO ) THEN
+            ETA = -F / DF
+         END IF
+*
+         TAU = TAU + ETA
+         IF( TAU .LT. LBD .OR. TAU .GT. UBD )
+     $      TAU = ( LBD + UBD )/TWO 
+*
+         FC = ZERO
+         ERRETM = ZERO
+         DF = ZERO
+         DDF = ZERO
+         DO 40 I = 1, 3
+            TEMP = ONE / ( DSCALE( I )-TAU )
+            TEMP1 = ZSCALE( I )*TEMP
+            TEMP2 = TEMP1*TEMP
+            TEMP3 = TEMP2*TEMP
+            TEMP4 = TEMP1 / DSCALE( I )
+            FC = FC + TEMP4
+            ERRETM = ERRETM + ABS( TEMP4 )
+            DF = DF + TEMP2
+            DDF = DDF + TEMP3
+   40    CONTINUE
+         F = FINIT + TAU*FC
+         ERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +
+     $            ABS( TAU )*DF
+         IF( ABS( F ).LE.EPS*ERRETM )
+     $      GO TO 60
+         IF( F .LE. ZERO )THEN
+            LBD = TAU
+         ELSE
+            UBD = TAU
+         END IF
+   50 CONTINUE
+      INFO = 1
+   60 CONTINUE
+*
+*     Undo scaling
+*
+      IF( SCALE )
+     $   TAU = TAU*SCLINV
+      RETURN
+*
+*     End of DLAED6
+*
+      END
diff --git a/libcruft/lapack/dlaev2.f b/libcruft/lapack/dlaev2.f
new file mode 100644
index 0000000..49402fa
--- /dev/null
+++ b/libcruft/lapack/dlaev2.f
@@ -0,0 +1,169 @@
+      SUBROUTINE DLAEV2( A, B, C, RT1, RT2, CS1, SN1 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   A, B, C, CS1, RT1, RT2, SN1
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix
+*     [  A   B  ]
+*     [  B   C  ].
+*  On return, RT1 is the eigenvalue of larger absolute value, RT2 is the
+*  eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right
+*  eigenvector for RT1, giving the decomposition
+*
+*     [ CS1  SN1 ] [  A   B  ] [ CS1 -SN1 ]  =  [ RT1  0  ]
+*     [-SN1  CS1 ] [  B   C  ] [ SN1  CS1 ]     [  0  RT2 ].
+*
+*  Arguments
+*  =========
+*
+*  A       (input) DOUBLE PRECISION
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  B       (input) DOUBLE PRECISION
+*          The (1,2) element and the conjugate of the (2,1) element of
+*          the 2-by-2 matrix.
+*
+*  C       (input) DOUBLE PRECISION
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  RT1     (output) DOUBLE PRECISION
+*          The eigenvalue of larger absolute value.
+*
+*  RT2     (output) DOUBLE PRECISION
+*          The eigenvalue of smaller absolute value.
+*
+*  CS1     (output) DOUBLE PRECISION
+*  SN1     (output) DOUBLE PRECISION
+*          The vector (CS1, SN1) is a unit right eigenvector for RT1.
+*
+*  Further Details
+*  ===============
+*
+*  RT1 is accurate to a few ulps barring over/underflow.
+*
+*  RT2 may be inaccurate if there is massive cancellation in the
+*  determinant A*C-B*B; higher precision or correctly rounded or
+*  correctly truncated arithmetic would be needed to compute RT2
+*  accurately in all cases.
+*
+*  CS1 and SN1 are accurate to a few ulps barring over/underflow.
+*
+*  Overflow is possible only if RT1 is within a factor of 5 of overflow.
+*  Underflow is harmless if the input data is 0 or exceeds
+*     underflow_threshold / macheps.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D0 )
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   HALF
+      PARAMETER          ( HALF = 0.5D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            SGN1, SGN2
+      DOUBLE PRECISION   AB, ACMN, ACMX, ACS, ADF, CS, CT, DF, RT, SM,
+     $                   TB, TN
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Compute the eigenvalues
+*
+      SM = A + C
+      DF = A - C
+      ADF = ABS( DF )
+      TB = B + B
+      AB = ABS( TB )
+      IF( ABS( A ).GT.ABS( C ) ) THEN
+         ACMX = A
+         ACMN = C
+      ELSE
+         ACMX = C
+         ACMN = A
+      END IF
+      IF( ADF.GT.AB ) THEN
+         RT = ADF*SQRT( ONE+( AB / ADF )**2 )
+      ELSE IF( ADF.LT.AB ) THEN
+         RT = AB*SQRT( ONE+( ADF / AB )**2 )
+      ELSE
+*
+*        Includes case AB=ADF=0
+*
+         RT = AB*SQRT( TWO )
+      END IF
+      IF( SM.LT.ZERO ) THEN
+         RT1 = HALF*( SM-RT )
+         SGN1 = -1
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE IF( SM.GT.ZERO ) THEN
+         RT1 = HALF*( SM+RT )
+         SGN1 = 1
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE
+*
+*        Includes case RT1 = RT2 = 0
+*
+         RT1 = HALF*RT
+         RT2 = -HALF*RT
+         SGN1 = 1
+      END IF
+*
+*     Compute the eigenvector
+*
+      IF( DF.GE.ZERO ) THEN
+         CS = DF + RT
+         SGN2 = 1
+      ELSE
+         CS = DF - RT
+         SGN2 = -1
+      END IF
+      ACS = ABS( CS )
+      IF( ACS.GT.AB ) THEN
+         CT = -TB / CS
+         SN1 = ONE / SQRT( ONE+CT*CT )
+         CS1 = CT*SN1
+      ELSE
+         IF( AB.EQ.ZERO ) THEN
+            CS1 = ONE
+            SN1 = ZERO
+         ELSE
+            TN = -CS / TB
+            CS1 = ONE / SQRT( ONE+TN*TN )
+            SN1 = TN*CS1
+         END IF
+      END IF
+      IF( SGN1.EQ.SGN2 ) THEN
+         TN = CS1
+         CS1 = -SN1
+         SN1 = TN
+      END IF
+      RETURN
+*
+*     End of DLAEV2
+*
+      END
diff --git a/libcruft/lapack/dlaexc.f b/libcruft/lapack/dlaexc.f
new file mode 100644
index 0000000..18e7d24
--- /dev/null
+++ b/libcruft/lapack/dlaexc.f
@@ -0,0 +1,354 @@
+      SUBROUTINE DLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,
+     $                   INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            WANTQ
+      INTEGER            INFO, J1, LDQ, LDT, N, N1, N2
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Q( LDQ, * ), T( LDT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in
+*  an upper quasi-triangular matrix T by an orthogonal similarity
+*  transformation.
+*
+*  T must be in Schur canonical form, that is, block upper triangular
+*  with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block
+*  has its diagonal elemnts equal and its off-diagonal elements of
+*  opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  WANTQ   (input) LOGICAL
+*          = .TRUE. : accumulate the transformation in the matrix Q;
+*          = .FALSE.: do not accumulate the transformation.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) DOUBLE PRECISION array, dimension (LDT,N)
+*          On entry, the upper quasi-triangular matrix T, in Schur
+*          canonical form.
+*          On exit, the updated matrix T, again in Schur canonical form.
+*
+*  LDT     (input)  INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
+*          On entry, if WANTQ is .TRUE., the orthogonal matrix Q.
+*          On exit, if WANTQ is .TRUE., the updated matrix Q.
+*          If WANTQ is .FALSE., Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= 1; and if WANTQ is .TRUE., LDQ >= N.
+*
+*  J1      (input) INTEGER
+*          The index of the first row of the first block T11.
+*
+*  N1      (input) INTEGER
+*          The order of the first block T11. N1 = 0, 1 or 2.
+*
+*  N2      (input) INTEGER
+*          The order of the second block T22. N2 = 0, 1 or 2.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          = 1: the transformed matrix T would be too far from Schur
+*               form; the blocks are not swapped and T and Q are
+*               unchanged.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   TEN
+      PARAMETER          ( TEN = 1.0D+1 )
+      INTEGER            LDD, LDX
+      PARAMETER          ( LDD = 4, LDX = 2 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IERR, J2, J3, J4, K, ND
+      DOUBLE PRECISION   CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,
+     $                   T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,
+     $                   WR1, WR2, XNORM
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),
+     $                   X( LDX, 2 )
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLANGE
+      EXTERNAL           DLAMCH, DLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACPY, DLANV2, DLARFG, DLARFX, DLARTG, DLASY2,
+     $                   DROT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. N1.EQ.0 .OR. N2.EQ.0 )
+     $   RETURN
+      IF( J1+N1.GT.N )
+     $   RETURN
+*
+      J2 = J1 + 1
+      J3 = J1 + 2
+      J4 = J1 + 3
+*
+      IF( N1.EQ.1 .AND. N2.EQ.1 ) THEN
+*
+*        Swap two 1-by-1 blocks.
+*
+         T11 = T( J1, J1 )
+         T22 = T( J2, J2 )
+*
+*        Determine the transformation to perform the interchange.
+*
+         CALL DLARTG( T( J1, J2 ), T22-T11, CS, SN, TEMP )
+*
+*        Apply transformation to the matrix T.
+*
+         IF( J3.LE.N )
+     $      CALL DROT( N-J1-1, T( J1, J3 ), LDT, T( J2, J3 ), LDT, CS,
+     $                 SN )
+         CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )
+*
+         T( J1, J1 ) = T22
+         T( J2, J2 ) = T11
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )
+         END IF
+*
+      ELSE
+*
+*        Swapping involves at least one 2-by-2 block.
+*
+*        Copy the diagonal block of order N1+N2 to the local array D
+*        and compute its norm.
+*
+         ND = N1 + N2
+         CALL DLACPY( 'Full', ND, ND, T( J1, J1 ), LDT, D, LDD )
+         DNORM = DLANGE( 'Max', ND, ND, D, LDD, WORK )
+*
+*        Compute machine-dependent threshold for test for accepting
+*        swap.
+*
+         EPS = DLAMCH( 'P' )
+         SMLNUM = DLAMCH( 'S' ) / EPS
+         THRESH = MAX( TEN*EPS*DNORM, SMLNUM )
+*
+*        Solve T11*X - X*T22 = scale*T12 for X.
+*
+         CALL DLASY2( .FALSE., .FALSE., -1, N1, N2, D, LDD,
+     $                D( N1+1, N1+1 ), LDD, D( 1, N1+1 ), LDD, SCALE, X,
+     $                LDX, XNORM, IERR )
+*
+*        Swap the adjacent diagonal blocks.
+*
+         K = N1 + N1 + N2 - 3
+         GO TO ( 10, 20, 30 )K
+*
+   10    CONTINUE
+*
+*        N1 = 1, N2 = 2: generate elementary reflector H so that:
+*
+*        ( scale, X11, X12 ) H = ( 0, 0, * )
+*
+         U( 1 ) = SCALE
+         U( 2 ) = X( 1, 1 )
+         U( 3 ) = X( 1, 2 )
+         CALL DLARFG( 3, U( 3 ), U, 1, TAU )
+         U( 3 ) = ONE
+         T11 = T( J1, J1 )
+*
+*        Perform swap provisionally on diagonal block in D.
+*
+         CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )
+         CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )
+*
+*        Test whether to reject swap.
+*
+         IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 3,
+     $       3 )-T11 ) ).GT.THRESH )GO TO 50
+*
+*        Accept swap: apply transformation to the entire matrix T.
+*
+         CALL DLARFX( 'L', 3, N-J1+1, U, TAU, T( J1, J1 ), LDT, WORK )
+         CALL DLARFX( 'R', J2, 3, U, TAU, T( 1, J1 ), LDT, WORK )
+*
+         T( J3, J1 ) = ZERO
+         T( J3, J2 ) = ZERO
+         T( J3, J3 ) = T11
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )
+         END IF
+         GO TO 40
+*
+   20    CONTINUE
+*
+*        N1 = 2, N2 = 1: generate elementary reflector H so that:
+*
+*        H (  -X11 ) = ( * )
+*          (  -X21 ) = ( 0 )
+*          ( scale ) = ( 0 )
+*
+         U( 1 ) = -X( 1, 1 )
+         U( 2 ) = -X( 2, 1 )
+         U( 3 ) = SCALE
+         CALL DLARFG( 3, U( 1 ), U( 2 ), 1, TAU )
+         U( 1 ) = ONE
+         T33 = T( J3, J3 )
+*
+*        Perform swap provisionally on diagonal block in D.
+*
+         CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )
+         CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )
+*
+*        Test whether to reject swap.
+*
+         IF( MAX( ABS( D( 2, 1 ) ), ABS( D( 3, 1 ) ), ABS( D( 1,
+     $       1 )-T33 ) ).GT.THRESH )GO TO 50
+*
+*        Accept swap: apply transformation to the entire matrix T.
+*
+         CALL DLARFX( 'R', J3, 3, U, TAU, T( 1, J1 ), LDT, WORK )
+         CALL DLARFX( 'L', 3, N-J1, U, TAU, T( J1, J2 ), LDT, WORK )
+*
+         T( J1, J1 ) = T33
+         T( J2, J1 ) = ZERO
+         T( J3, J1 ) = ZERO
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )
+         END IF
+         GO TO 40
+*
+   30    CONTINUE
+*
+*        N1 = 2, N2 = 2: generate elementary reflectors H(1) and H(2) so
+*        that:
+*
+*        H(2) H(1) (  -X11  -X12 ) = (  *  * )
+*                  (  -X21  -X22 )   (  0  * )
+*                  ( scale    0  )   (  0  0 )
+*                  (    0  scale )   (  0  0 )
+*
+         U1( 1 ) = -X( 1, 1 )
+         U1( 2 ) = -X( 2, 1 )
+         U1( 3 ) = SCALE
+         CALL DLARFG( 3, U1( 1 ), U1( 2 ), 1, TAU1 )
+         U1( 1 ) = ONE
+*
+         TEMP = -TAU1*( X( 1, 2 )+U1( 2 )*X( 2, 2 ) )
+         U2( 1 ) = -TEMP*U1( 2 ) - X( 2, 2 )
+         U2( 2 ) = -TEMP*U1( 3 )
+         U2( 3 ) = SCALE
+         CALL DLARFG( 3, U2( 1 ), U2( 2 ), 1, TAU2 )
+         U2( 1 ) = ONE
+*
+*        Perform swap provisionally on diagonal block in D.
+*
+         CALL DLARFX( 'L', 3, 4, U1, TAU1, D, LDD, WORK )
+         CALL DLARFX( 'R', 4, 3, U1, TAU1, D, LDD, WORK )
+         CALL DLARFX( 'L', 3, 4, U2, TAU2, D( 2, 1 ), LDD, WORK )
+         CALL DLARFX( 'R', 4, 3, U2, TAU2, D( 1, 2 ), LDD, WORK )
+*
+*        Test whether to reject swap.
+*
+         IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 4, 1 ) ),
+     $       ABS( D( 4, 2 ) ) ).GT.THRESH )GO TO 50
+*
+*        Accept swap: apply transformation to the entire matrix T.
+*
+         CALL DLARFX( 'L', 3, N-J1+1, U1, TAU1, T( J1, J1 ), LDT, WORK )
+         CALL DLARFX( 'R', J4, 3, U1, TAU1, T( 1, J1 ), LDT, WORK )
+         CALL DLARFX( 'L', 3, N-J1+1, U2, TAU2, T( J2, J1 ), LDT, WORK )
+         CALL DLARFX( 'R', J4, 3, U2, TAU2, T( 1, J2 ), LDT, WORK )
+*
+         T( J3, J1 ) = ZERO
+         T( J3, J2 ) = ZERO
+         T( J4, J1 ) = ZERO
+         T( J4, J2 ) = ZERO
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL DLARFX( 'R', N, 3, U1, TAU1, Q( 1, J1 ), LDQ, WORK )
+            CALL DLARFX( 'R', N, 3, U2, TAU2, Q( 1, J2 ), LDQ, WORK )
+         END IF
+*
+   40    CONTINUE
+*
+         IF( N2.EQ.2 ) THEN
+*
+*           Standardize new 2-by-2 block T11
+*
+            CALL DLANV2( T( J1, J1 ), T( J1, J2 ), T( J2, J1 ),
+     $                   T( J2, J2 ), WR1, WI1, WR2, WI2, CS, SN )
+            CALL DROT( N-J1-1, T( J1, J1+2 ), LDT, T( J2, J1+2 ), LDT,
+     $                 CS, SN )
+            CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )
+            IF( WANTQ )
+     $         CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )
+         END IF
+*
+         IF( N1.EQ.2 ) THEN
+*
+*           Standardize new 2-by-2 block T22
+*
+            J3 = J1 + N2
+            J4 = J3 + 1
+            CALL DLANV2( T( J3, J3 ), T( J3, J4 ), T( J4, J3 ),
+     $                   T( J4, J4 ), WR1, WI1, WR2, WI2, CS, SN )
+            IF( J3+2.LE.N )
+     $         CALL DROT( N-J3-1, T( J3, J3+2 ), LDT, T( J4, J3+2 ),
+     $                    LDT, CS, SN )
+            CALL DROT( J3-1, T( 1, J3 ), 1, T( 1, J4 ), 1, CS, SN )
+            IF( WANTQ )
+     $         CALL DROT( N, Q( 1, J3 ), 1, Q( 1, J4 ), 1, CS, SN )
+         END IF
+*
+      END IF
+      RETURN
+*
+*     Exit with INFO = 1 if swap was rejected.
+*
+   50 CONTINUE
+      INFO = 1
+      RETURN
+*
+*     End of DLAEXC
+*
+      END
diff --git a/libcruft/lapack/dlag2.f b/libcruft/lapack/dlag2.f
new file mode 100644
index 0000000..e754203
--- /dev/null
+++ b/libcruft/lapack/dlag2.f
@@ -0,0 +1,300 @@
+      SUBROUTINE DLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,
+     $                  WR2, WI )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, LDB
+      DOUBLE PRECISION   SAFMIN, SCALE1, SCALE2, WI, WR1, WR2
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAG2 computes the eigenvalues of a 2 x 2 generalized eigenvalue
+*  problem  A - w B, with scaling as necessary to avoid over-/underflow.
+*
+*  The scaling factor "s" results in a modified eigenvalue equation
+*
+*      s A - w B
+*
+*  where  s  is a non-negative scaling factor chosen so that  w,  w B,
+*  and  s A  do not overflow and, if possible, do not underflow, either.
+*
+*  Arguments
+*  =========
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA, 2)
+*          On entry, the 2 x 2 matrix A.  It is assumed that its 1-norm
+*          is less than 1/SAFMIN.  Entries less than
+*          sqrt(SAFMIN)*norm(A) are subject to being treated as zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= 2.
+*
+*  B       (input) DOUBLE PRECISION array, dimension (LDB, 2)
+*          On entry, the 2 x 2 upper triangular matrix B.  It is
+*          assumed that the one-norm of B is less than 1/SAFMIN.  The
+*          diagonals should be at least sqrt(SAFMIN) times the largest
+*          element of B (in absolute value); if a diagonal is smaller
+*          than that, then  +/- sqrt(SAFMIN) will be used instead of
+*          that diagonal.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= 2.
+*
+*  SAFMIN  (input) DOUBLE PRECISION
+*          The smallest positive number s.t. 1/SAFMIN does not
+*          overflow.  (This should always be DLAMCH('S') -- it is an
+*          argument in order to avoid having to call DLAMCH frequently.)
+*
+*  SCALE1  (output) DOUBLE PRECISION
+*          A scaling factor used to avoid over-/underflow in the
+*          eigenvalue equation which defines the first eigenvalue.  If
+*          the eigenvalues are complex, then the eigenvalues are
+*          ( WR1  +/-  WI i ) / SCALE1  (which may lie outside the
+*          exponent range of the machine), SCALE1=SCALE2, and SCALE1
+*          will always be positive.  If the eigenvalues are real, then
+*          the first (real) eigenvalue is  WR1 / SCALE1 , but this may
+*          overflow or underflow, and in fact, SCALE1 may be zero or
+*          less than the underflow threshhold if the exact eigenvalue
+*          is sufficiently large.
+*
+*  SCALE2  (output) DOUBLE PRECISION
+*          A scaling factor used to avoid over-/underflow in the
+*          eigenvalue equation which defines the second eigenvalue.  If
+*          the eigenvalues are complex, then SCALE2=SCALE1.  If the
+*          eigenvalues are real, then the second (real) eigenvalue is
+*          WR2 / SCALE2 , but this may overflow or underflow, and in
+*          fact, SCALE2 may be zero or less than the underflow
+*          threshhold if the exact eigenvalue is sufficiently large.
+*
+*  WR1     (output) DOUBLE PRECISION
+*          If the eigenvalue is real, then WR1 is SCALE1 times the
+*          eigenvalue closest to the (2,2) element of A B**(-1).  If the
+*          eigenvalue is complex, then WR1=WR2 is SCALE1 times the real
+*          part of the eigenvalues.
+*
+*  WR2     (output) DOUBLE PRECISION
+*          If the eigenvalue is real, then WR2 is SCALE2 times the
+*          other eigenvalue.  If the eigenvalue is complex, then
+*          WR1=WR2 is SCALE1 times the real part of the eigenvalues.
+*
+*  WI      (output) DOUBLE PRECISION
+*          If the eigenvalue is real, then WI is zero.  If the
+*          eigenvalue is complex, then WI is SCALE1 times the imaginary
+*          part of the eigenvalues.  WI will always be non-negative.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
+      DOUBLE PRECISION   HALF
+      PARAMETER          ( HALF = ONE / TWO )
+      DOUBLE PRECISION   FUZZY1
+      PARAMETER          ( FUZZY1 = ONE+1.0D-5 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   A11, A12, A21, A22, ABI22, ANORM, AS11, AS12,
+     $                   AS22, ASCALE, B11, B12, B22, BINV11, BINV22,
+     $                   BMIN, BNORM, BSCALE, BSIZE, C1, C2, C3, C4, C5,
+     $                   DIFF, DISCR, PP, QQ, R, RTMAX, RTMIN, S1, S2,
+     $                   SAFMAX, SHIFT, SS, SUM, WABS, WBIG, WDET,
+     $                   WSCALE, WSIZE, WSMALL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      RTMIN = SQRT( SAFMIN )
+      RTMAX = ONE / RTMIN
+      SAFMAX = ONE / SAFMIN
+*
+*     Scale A
+*
+      ANORM = MAX( ABS( A( 1, 1 ) )+ABS( A( 2, 1 ) ),
+     $        ABS( A( 1, 2 ) )+ABS( A( 2, 2 ) ), SAFMIN )
+      ASCALE = ONE / ANORM
+      A11 = ASCALE*A( 1, 1 )
+      A21 = ASCALE*A( 2, 1 )
+      A12 = ASCALE*A( 1, 2 )
+      A22 = ASCALE*A( 2, 2 )
+*
+*     Perturb B if necessary to insure non-singularity
+*
+      B11 = B( 1, 1 )
+      B12 = B( 1, 2 )
+      B22 = B( 2, 2 )
+      BMIN = RTMIN*MAX( ABS( B11 ), ABS( B12 ), ABS( B22 ), RTMIN )
+      IF( ABS( B11 ).LT.BMIN )
+     $   B11 = SIGN( BMIN, B11 )
+      IF( ABS( B22 ).LT.BMIN )
+     $   B22 = SIGN( BMIN, B22 )
+*
+*     Scale B
+*
+      BNORM = MAX( ABS( B11 ), ABS( B12 )+ABS( B22 ), SAFMIN )
+      BSIZE = MAX( ABS( B11 ), ABS( B22 ) )
+      BSCALE = ONE / BSIZE
+      B11 = B11*BSCALE
+      B12 = B12*BSCALE
+      B22 = B22*BSCALE
+*
+*     Compute larger eigenvalue by method described by C. van Loan
+*
+*     ( AS is A shifted by -SHIFT*B )
+*
+      BINV11 = ONE / B11
+      BINV22 = ONE / B22
+      S1 = A11*BINV11
+      S2 = A22*BINV22
+      IF( ABS( S1 ).LE.ABS( S2 ) ) THEN
+         AS12 = A12 - S1*B12
+         AS22 = A22 - S1*B22
+         SS = A21*( BINV11*BINV22 )
+         ABI22 = AS22*BINV22 - SS*B12
+         PP = HALF*ABI22
+         SHIFT = S1
+      ELSE
+         AS12 = A12 - S2*B12
+         AS11 = A11 - S2*B11
+         SS = A21*( BINV11*BINV22 )
+         ABI22 = -SS*B12
+         PP = HALF*( AS11*BINV11+ABI22 )
+         SHIFT = S2
+      END IF
+      QQ = SS*AS12
+      IF( ABS( PP*RTMIN ).GE.ONE ) THEN
+         DISCR = ( RTMIN*PP )**2 + QQ*SAFMIN
+         R = SQRT( ABS( DISCR ) )*RTMAX
+      ELSE
+         IF( PP**2+ABS( QQ ).LE.SAFMIN ) THEN
+            DISCR = ( RTMAX*PP )**2 + QQ*SAFMAX
+            R = SQRT( ABS( DISCR ) )*RTMIN
+         ELSE
+            DISCR = PP**2 + QQ
+            R = SQRT( ABS( DISCR ) )
+         END IF
+      END IF
+*
+*     Note: the test of R in the following IF is to cover the case when
+*           DISCR is small and negative and is flushed to zero during
+*           the calculation of R.  On machines which have a consistent
+*           flush-to-zero threshhold and handle numbers above that
+*           threshhold correctly, it would not be necessary.
+*
+      IF( DISCR.GE.ZERO .OR. R.EQ.ZERO ) THEN
+         SUM = PP + SIGN( R, PP )
+         DIFF = PP - SIGN( R, PP )
+         WBIG = SHIFT + SUM
+*
+*        Compute smaller eigenvalue
+*
+         WSMALL = SHIFT + DIFF
+         IF( HALF*ABS( WBIG ).GT.MAX( ABS( WSMALL ), SAFMIN ) ) THEN
+            WDET = ( A11*A22-A12*A21 )*( BINV11*BINV22 )
+            WSMALL = WDET / WBIG
+         END IF
+*
+*        Choose (real) eigenvalue closest to 2,2 element of A*B**(-1)
+*        for WR1.
+*
+         IF( PP.GT.ABI22 ) THEN
+            WR1 = MIN( WBIG, WSMALL )
+            WR2 = MAX( WBIG, WSMALL )
+         ELSE
+            WR1 = MAX( WBIG, WSMALL )
+            WR2 = MIN( WBIG, WSMALL )
+         END IF
+         WI = ZERO
+      ELSE
+*
+*        Complex eigenvalues
+*
+         WR1 = SHIFT + PP
+         WR2 = WR1
+         WI = R
+      END IF
+*
+*     Further scaling to avoid underflow and overflow in computing
+*     SCALE1 and overflow in computing w*B.
+*
+*     This scale factor (WSCALE) is bounded from above using C1 and C2,
+*     and from below using C3 and C4.
+*        C1 implements the condition  s A  must never overflow.
+*        C2 implements the condition  w B  must never overflow.
+*        C3, with C2,
+*           implement the condition that s A - w B must never overflow.
+*        C4 implements the condition  s    should not underflow.
+*        C5 implements the condition  max(s,|w|) should be at least 2.
+*
+      C1 = BSIZE*( SAFMIN*MAX( ONE, ASCALE ) )
+      C2 = SAFMIN*MAX( ONE, BNORM )
+      C3 = BSIZE*SAFMIN
+      IF( ASCALE.LE.ONE .AND. BSIZE.LE.ONE ) THEN
+         C4 = MIN( ONE, ( ASCALE / SAFMIN )*BSIZE )
+      ELSE
+         C4 = ONE
+      END IF
+      IF( ASCALE.LE.ONE .OR. BSIZE.LE.ONE ) THEN
+         C5 = MIN( ONE, ASCALE*BSIZE )
+      ELSE
+         C5 = ONE
+      END IF
+*
+*     Scale first eigenvalue
+*
+      WABS = ABS( WR1 ) + ABS( WI )
+      WSIZE = MAX( SAFMIN, C1, FUZZY1*( WABS*C2+C3 ),
+     $        MIN( C4, HALF*MAX( WABS, C5 ) ) )
+      IF( WSIZE.NE.ONE ) THEN
+         WSCALE = ONE / WSIZE
+         IF( WSIZE.GT.ONE ) THEN
+            SCALE1 = ( MAX( ASCALE, BSIZE )*WSCALE )*
+     $               MIN( ASCALE, BSIZE )
+         ELSE
+            SCALE1 = ( MIN( ASCALE, BSIZE )*WSCALE )*
+     $               MAX( ASCALE, BSIZE )
+         END IF
+         WR1 = WR1*WSCALE
+         IF( WI.NE.ZERO ) THEN
+            WI = WI*WSCALE
+            WR2 = WR1
+            SCALE2 = SCALE1
+         END IF
+      ELSE
+         SCALE1 = ASCALE*BSIZE
+         SCALE2 = SCALE1
+      END IF
+*
+*     Scale second eigenvalue (if real)
+*
+      IF( WI.EQ.ZERO ) THEN
+         WSIZE = MAX( SAFMIN, C1, FUZZY1*( ABS( WR2 )*C2+C3 ),
+     $           MIN( C4, HALF*MAX( ABS( WR2 ), C5 ) ) )
+         IF( WSIZE.NE.ONE ) THEN
+            WSCALE = ONE / WSIZE
+            IF( WSIZE.GT.ONE ) THEN
+               SCALE2 = ( MAX( ASCALE, BSIZE )*WSCALE )*
+     $                  MIN( ASCALE, BSIZE )
+            ELSE
+               SCALE2 = ( MIN( ASCALE, BSIZE )*WSCALE )*
+     $                  MAX( ASCALE, BSIZE )
+            END IF
+            WR2 = WR2*WSCALE
+         ELSE
+            SCALE2 = ASCALE*BSIZE
+         END IF
+      END IF
+*
+*     End of DLAG2
+*
+      RETURN
+      END
diff --git a/libcruft/lapack/dlahqr.f b/libcruft/lapack/dlahqr.f
new file mode 100644
index 0000000..449a377
--- /dev/null
+++ b/libcruft/lapack/dlahqr.f
@@ -0,0 +1,501 @@
+      SUBROUTINE DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     DLAHQR is an auxiliary routine called by DHSEQR to update the
+*     eigenvalues and Schur decomposition already computed by DHSEQR, by
+*     dealing with the Hessenberg submatrix in rows and columns ILO to
+*     IHI.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H.  N >= 0.
+*
+*     ILO     (input) INTEGER
+*     IHI     (input) INTEGER
+*          It is assumed that H is already upper quasi-triangular in
+*          rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless
+*          ILO = 1). DLAHQR works primarily with the Hessenberg
+*          submatrix in rows and columns ILO to IHI, but applies
+*          transformations to all of H if WANTT is .TRUE..
+*          1 <= ILO <= max(1,IHI); IHI <= N.
+*
+*     H       (input/output) DOUBLE PRECISION array, dimension (LDH,N)
+*          On entry, the upper Hessenberg matrix H.
+*          On exit, if INFO is zero and if WANTT is .TRUE., H is upper
+*          quasi-triangular in rows and columns ILO:IHI, with any
+*          2-by-2 diagonal blocks in standard form. If INFO is zero
+*          and WANTT is .FALSE., the contents of H are unspecified on
+*          exit.  The output state of H if INFO is nonzero is given
+*          below under the description of INFO.
+*
+*     LDH     (input) INTEGER
+*          The leading dimension of the array H. LDH >= max(1,N).
+*
+*     WR      (output) DOUBLE PRECISION array, dimension (N)
+*     WI      (output) DOUBLE PRECISION array, dimension (N)
+*          The real and imaginary parts, respectively, of the computed
+*          eigenvalues ILO to IHI are stored in the corresponding
+*          elements of WR and WI. If two eigenvalues are computed as a
+*          complex conjugate pair, they are stored in consecutive
+*          elements of WR and WI, say the i-th and (i+1)th, with
+*          WI(i) > 0 and WI(i+1) < 0. If WANTT is .TRUE., the
+*          eigenvalues are stored in the same order as on the diagonal
+*          of the Schur form returned in H, with WR(i) = H(i,i), and, if
+*          H(i:i+1,i:i+1) is a 2-by-2 diagonal block,
+*          WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i).
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE..
+*          1 <= ILOZ <= ILO; IHI <= IHIZ <= N.
+*
+*     Z       (input/output) DOUBLE PRECISION array, dimension (LDZ,N)
+*          If WANTZ is .TRUE., on entry Z must contain the current
+*          matrix Z of transformations accumulated by DHSEQR, and on
+*          exit Z has been updated; transformations are applied only to
+*          the submatrix Z(ILOZ:IHIZ,ILO:IHI).
+*          If WANTZ is .FALSE., Z is not referenced.
+*
+*     LDZ     (input) INTEGER
+*          The leading dimension of the array Z. LDZ >= max(1,N).
+*
+*     INFO    (output) INTEGER
+*           =   0: successful exit
+*          .GT. 0: If INFO = i, DLAHQR failed to compute all the
+*                  eigenvalues ILO to IHI in a total of 30 iterations
+*                  per eigenvalue; elements i+1:ihi of WR and WI
+*                  contain those eigenvalues which have been
+*                  successfully computed.
+*
+*                  If INFO .GT. 0 and WANTT is .FALSE., then on exit,
+*                  the remaining unconverged eigenvalues are the
+*                  eigenvalues of the upper Hessenberg matrix rows
+*                  and columns ILO thorugh INFO of the final, output
+*                  value of H.
+*
+*                  If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*          (*)       (initial value of H)*U  = U*(final value of H)
+*                  where U is an orthognal matrix.    The final
+*                  value of H is upper Hessenberg and triangular in
+*                  rows and columns INFO+1 through IHI.
+*
+*                  If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*                      (final value of Z)  = (initial value of Z)*U
+*                  where U is the orthogonal matrix in (*)
+*                  (regardless of the value of WANTT.)
+*
+*     Further Details
+*     ===============
+*
+*     02-96 Based on modifications by
+*     David Day, Sandia National Laboratory, USA
+*
+*     12-04 Further modifications by
+*     Ralph Byers, University of Kansas, USA
+*
+*       This is a modified version of DLAHQR from LAPACK version 3.0.
+*       It is (1) more robust against overflow and underflow and
+*       (2) adopts the more conservative Ahues & Tisseur stopping
+*       criterion (LAWN 122, 1997).
+*
+*     =========================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 30 )
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0, TWO = 2.0d0 )
+      DOUBLE PRECISION   DAT1, DAT2
+      PARAMETER          ( DAT1 = 3.0d0 / 4.0d0, DAT2 = -0.4375d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AA, AB, BA, BB, CS, DET, H11, H12, H21, H21S,
+     $                   H22, RT1I, RT1R, RT2I, RT2R, RTDISC, S, SAFMAX,
+     $                   SAFMIN, SMLNUM, SN, SUM, T1, T2, T3, TR, TST,
+     $                   ULP, V2, V3
+      INTEGER            I, I1, I2, ITS, J, K, L, M, NH, NR, NZ
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   V( 3 )
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLABAD, DLANV2, DLARFG, DROT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( ILO.EQ.IHI ) THEN
+         WR( ILO ) = H( ILO, ILO )
+         WI( ILO ) = ZERO
+         RETURN
+      END IF
+*
+*     ==== clear out the trash ====
+      DO 10 J = ILO, IHI - 3
+         H( J+2, J ) = ZERO
+         H( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( ILO.LE.IHI-2 )
+     $   H( IHI, IHI-2 ) = ZERO
+*
+      NH = IHI - ILO + 1
+      NZ = IHIZ - ILOZ + 1
+*
+*     Set machine-dependent constants for the stopping criterion.
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( NH ) / ULP )
+*
+*     I1 and I2 are the indices of the first row and last column of H
+*     to which transformations must be applied. If eigenvalues only are
+*     being computed, I1 and I2 are set inside the main loop.
+*
+      IF( WANTT ) THEN
+         I1 = 1
+         I2 = N
+      END IF
+*
+*     The main loop begins here. I is the loop index and decreases from
+*     IHI to ILO in steps of 1 or 2. Each iteration of the loop works
+*     with the active submatrix in rows and columns L to I.
+*     Eigenvalues I+1 to IHI have already converged. Either L = ILO or
+*     H(L,L-1) is negligible so that the matrix splits.
+*
+      I = IHI
+   20 CONTINUE
+      L = ILO
+      IF( I.LT.ILO )
+     $   GO TO 160
+*
+*     Perform QR iterations on rows and columns ILO to I until a
+*     submatrix of order 1 or 2 splits off at the bottom because a
+*     subdiagonal element has become negligible.
+*
+      DO 140 ITS = 0, ITMAX
+*
+*        Look for a single small subdiagonal element.
+*
+         DO 30 K = I, L + 1, -1
+            IF( ABS( H( K, K-1 ) ).LE.SMLNUM )
+     $         GO TO 40
+            TST = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) )
+            IF( TST.EQ.ZERO ) THEN
+               IF( K-2.GE.ILO )
+     $            TST = TST + ABS( H( K-1, K-2 ) )
+               IF( K+1.LE.IHI )
+     $            TST = TST + ABS( H( K+1, K ) )
+            END IF
+*           ==== The following is a conservative small subdiagonal
+*           .    deflation  criterion due to Ahues & Tisseur (LAWN 122,
+*           .    1997). It has better mathematical foundation and
+*           .    improves accuracy in some cases.  ====
+            IF( ABS( H( K, K-1 ) ).LE.ULP*TST ) THEN
+               AB = MAX( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )
+               BA = MIN( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )
+               AA = MAX( ABS( H( K, K ) ),
+     $              ABS( H( K-1, K-1 )-H( K, K ) ) )
+               BB = MIN( ABS( H( K, K ) ),
+     $              ABS( H( K-1, K-1 )-H( K, K ) ) )
+               S = AA + AB
+               IF( BA*( AB / S ).LE.MAX( SMLNUM,
+     $             ULP*( BB*( AA / S ) ) ) )GO TO 40
+            END IF
+   30    CONTINUE
+   40    CONTINUE
+         L = K
+         IF( L.GT.ILO ) THEN
+*
+*           H(L,L-1) is negligible
+*
+            H( L, L-1 ) = ZERO
+         END IF
+*
+*        Exit from loop if a submatrix of order 1 or 2 has split off.
+*
+         IF( L.GE.I-1 )
+     $      GO TO 150
+*
+*        Now the active submatrix is in rows and columns L to I. If
+*        eigenvalues only are being computed, only the active submatrix
+*        need be transformed.
+*
+         IF( .NOT.WANTT ) THEN
+            I1 = L
+            I2 = I
+         END IF
+*
+         IF( ITS.EQ.10 .OR. ITS.EQ.20 ) THEN
+*
+*           Exceptional shift.
+*
+            H11 = DAT1*S + H( I, I )
+            H12 = DAT2*S
+            H21 = S
+            H22 = H11
+         ELSE
+*
+*           Prepare to use Francis' double shift
+*           (i.e. 2nd degree generalized Rayleigh quotient)
+*
+            H11 = H( I-1, I-1 )
+            H21 = H( I, I-1 )
+            H12 = H( I-1, I )
+            H22 = H( I, I )
+         END IF
+         S = ABS( H11 ) + ABS( H12 ) + ABS( H21 ) + ABS( H22 )
+         IF( S.EQ.ZERO ) THEN
+            RT1R = ZERO
+            RT1I = ZERO
+            RT2R = ZERO
+            RT2I = ZERO
+         ELSE
+            H11 = H11 / S
+            H21 = H21 / S
+            H12 = H12 / S
+            H22 = H22 / S
+            TR = ( H11+H22 ) / TWO
+            DET = ( H11-TR )*( H22-TR ) - H12*H21
+            RTDISC = SQRT( ABS( DET ) )
+            IF( DET.GE.ZERO ) THEN
+*
+*              ==== complex conjugate shifts ====
+*
+               RT1R = TR*S
+               RT2R = RT1R
+               RT1I = RTDISC*S
+               RT2I = -RT1I
+            ELSE
+*
+*              ==== real shifts (use only one of them)  ====
+*
+               RT1R = TR + RTDISC
+               RT2R = TR - RTDISC
+               IF( ABS( RT1R-H22 ).LE.ABS( RT2R-H22 ) ) THEN
+                  RT1R = RT1R*S
+                  RT2R = RT1R
+               ELSE
+                  RT2R = RT2R*S
+                  RT1R = RT2R
+               END IF
+               RT1I = ZERO
+               RT2I = ZERO
+            END IF
+         END IF
+*
+*        Look for two consecutive small subdiagonal elements.
+*
+         DO 50 M = I - 2, L, -1
+*           Determine the effect of starting the double-shift QR
+*           iteration at row M, and see if this would make H(M,M-1)
+*           negligible.  (The following uses scaling to avoid
+*           overflows and most underflows.)
+*
+            H21S = H( M+1, M )
+            S = ABS( H( M, M )-RT2R ) + ABS( RT2I ) + ABS( H21S )
+            H21S = H( M+1, M ) / S
+            V( 1 ) = H21S*H( M, M+1 ) + ( H( M, M )-RT1R )*
+     $               ( ( H( M, M )-RT2R ) / S ) - RT1I*( RT2I / S )
+            V( 2 ) = H21S*( H( M, M )+H( M+1, M+1 )-RT1R-RT2R )
+            V( 3 ) = H21S*H( M+2, M+1 )
+            S = ABS( V( 1 ) ) + ABS( V( 2 ) ) + ABS( V( 3 ) )
+            V( 1 ) = V( 1 ) / S
+            V( 2 ) = V( 2 ) / S
+            V( 3 ) = V( 3 ) / S
+            IF( M.EQ.L )
+     $         GO TO 60
+            IF( ABS( H( M, M-1 ) )*( ABS( V( 2 ) )+ABS( V( 3 ) ) ).LE.
+     $          ULP*ABS( V( 1 ) )*( ABS( H( M-1, M-1 ) )+ABS( H( M,
+     $          M ) )+ABS( H( M+1, M+1 ) ) ) )GO TO 60
+   50    CONTINUE
+   60    CONTINUE
+*
+*        Double-shift QR step
+*
+         DO 130 K = M, I - 1
+*
+*           The first iteration of this loop determines a reflection G
+*           from the vector V and applies it from left and right to H,
+*           thus creating a nonzero bulge below the subdiagonal.
+*
+*           Each subsequent iteration determines a reflection G to
+*           restore the Hessenberg form in the (K-1)th column, and thus
+*           chases the bulge one step toward the bottom of the active
+*           submatrix. NR is the order of G.
+*
+            NR = MIN( 3, I-K+1 )
+            IF( K.GT.M )
+     $         CALL DCOPY( NR, H( K, K-1 ), 1, V, 1 )
+            CALL DLARFG( NR, V( 1 ), V( 2 ), 1, T1 )
+            IF( K.GT.M ) THEN
+               H( K, K-1 ) = V( 1 )
+               H( K+1, K-1 ) = ZERO
+               IF( K.LT.I-1 )
+     $            H( K+2, K-1 ) = ZERO
+            ELSE IF( M.GT.L ) THEN
+               H( K, K-1 ) = -H( K, K-1 )
+            END IF
+            V2 = V( 2 )
+            T2 = T1*V2
+            IF( NR.EQ.3 ) THEN
+               V3 = V( 3 )
+               T3 = T1*V3
+*
+*              Apply G from the left to transform the rows of the matrix
+*              in columns K to I2.
+*
+               DO 70 J = K, I2
+                  SUM = H( K, J ) + V2*H( K+1, J ) + V3*H( K+2, J )
+                  H( K, J ) = H( K, J ) - SUM*T1
+                  H( K+1, J ) = H( K+1, J ) - SUM*T2
+                  H( K+2, J ) = H( K+2, J ) - SUM*T3
+   70          CONTINUE
+*
+*              Apply G from the right to transform the columns of the
+*              matrix in rows I1 to min(K+3,I).
+*
+               DO 80 J = I1, MIN( K+3, I )
+                  SUM = H( J, K ) + V2*H( J, K+1 ) + V3*H( J, K+2 )
+                  H( J, K ) = H( J, K ) - SUM*T1
+                  H( J, K+1 ) = H( J, K+1 ) - SUM*T2
+                  H( J, K+2 ) = H( J, K+2 ) - SUM*T3
+   80          CONTINUE
+*
+               IF( WANTZ ) THEN
+*
+*                 Accumulate transformations in the matrix Z
+*
+                  DO 90 J = ILOZ, IHIZ
+                     SUM = Z( J, K ) + V2*Z( J, K+1 ) + V3*Z( J, K+2 )
+                     Z( J, K ) = Z( J, K ) - SUM*T1
+                     Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2
+                     Z( J, K+2 ) = Z( J, K+2 ) - SUM*T3
+   90             CONTINUE
+               END IF
+            ELSE IF( NR.EQ.2 ) THEN
+*
+*              Apply G from the left to transform the rows of the matrix
+*              in columns K to I2.
+*
+               DO 100 J = K, I2
+                  SUM = H( K, J ) + V2*H( K+1, J )
+                  H( K, J ) = H( K, J ) - SUM*T1
+                  H( K+1, J ) = H( K+1, J ) - SUM*T2
+  100          CONTINUE
+*
+*              Apply G from the right to transform the columns of the
+*              matrix in rows I1 to min(K+3,I).
+*
+               DO 110 J = I1, I
+                  SUM = H( J, K ) + V2*H( J, K+1 )
+                  H( J, K ) = H( J, K ) - SUM*T1
+                  H( J, K+1 ) = H( J, K+1 ) - SUM*T2
+  110          CONTINUE
+*
+               IF( WANTZ ) THEN
+*
+*                 Accumulate transformations in the matrix Z
+*
+                  DO 120 J = ILOZ, IHIZ
+                     SUM = Z( J, K ) + V2*Z( J, K+1 )
+                     Z( J, K ) = Z( J, K ) - SUM*T1
+                     Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2
+  120             CONTINUE
+               END IF
+            END IF
+  130    CONTINUE
+*
+  140 CONTINUE
+*
+*     Failure to converge in remaining number of iterations
+*
+      INFO = I
+      RETURN
+*
+  150 CONTINUE
+*
+      IF( L.EQ.I ) THEN
+*
+*        H(I,I-1) is negligible: one eigenvalue has converged.
+*
+         WR( I ) = H( I, I )
+         WI( I ) = ZERO
+      ELSE IF( L.EQ.I-1 ) THEN
+*
+*        H(I-1,I-2) is negligible: a pair of eigenvalues have converged.
+*
+*        Transform the 2-by-2 submatrix to standard Schur form,
+*        and compute and store the eigenvalues.
+*
+         CALL DLANV2( H( I-1, I-1 ), H( I-1, I ), H( I, I-1 ),
+     $                H( I, I ), WR( I-1 ), WI( I-1 ), WR( I ), WI( I ),
+     $                CS, SN )
+*
+         IF( WANTT ) THEN
+*
+*           Apply the transformation to the rest of H.
+*
+            IF( I2.GT.I )
+     $         CALL DROT( I2-I, H( I-1, I+1 ), LDH, H( I, I+1 ), LDH,
+     $                    CS, SN )
+            CALL DROT( I-I1-1, H( I1, I-1 ), 1, H( I1, I ), 1, CS, SN )
+         END IF
+         IF( WANTZ ) THEN
+*
+*           Apply the transformation to Z.
+*
+            CALL DROT( NZ, Z( ILOZ, I-1 ), 1, Z( ILOZ, I ), 1, CS, SN )
+         END IF
+      END IF
+*
+*     return to start of the main loop with new value of I.
+*
+      I = L - 1
+      GO TO 20
+*
+  160 CONTINUE
+      RETURN
+*
+*     End of DLAHQR
+*
+      END
diff --git a/libcruft/lapack/dlahr2.f b/libcruft/lapack/dlahr2.f
new file mode 100644
index 0000000..6af7497
--- /dev/null
+++ b/libcruft/lapack/dlahr2.f
@@ -0,0 +1,238 @@
+      SUBROUTINE DLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION  A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAHR2 reduces the first NB columns of A real general n-BY-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by an orthogonal similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an auxiliary routine called by DGEHRD.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*          K < N.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) DOUBLE PRECISION array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) DOUBLE PRECISION array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's DLAHRD
+*  incorporating improvements proposed by Quintana-Orti and Van de
+*  Gejin. Note that the entries of A(1:K,2:NB) differ from those
+*  returned by the original LAPACK routine. This function is
+*  not backward compatible with LAPACK3.0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION  ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, 
+     $                     ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      DOUBLE PRECISION  EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DCOPY, DGEMM, DGEMV, DLACPY,
+     $                   DLARFG, DSCAL, DTRMM, DTRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(K+1:N,I)
+*
+*           Update I-th column of A - Y * V'
+*
+            CALL DGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, Y(K+1,1), LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( K+1, I ), 1 )
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL DCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL DTRMV( 'Lower', 'Transpose', 'UNIT', 
+     $                  I-1, A( K+1, 1 ),
+     $                  LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL DGEMV( 'Transpose', N-K-I+1, I-1, 
+     $                  ONE, A( K+I, 1 ),
+     $                  LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL DTRMV( 'Upper', 'Transpose', 'NON-UNIT', 
+     $                  I-1, T, LDT,
+     $                  T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL DGEMV( 'NO TRANSPOSE', N-K-I+1, I-1, -ONE, 
+     $                  A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL DTRMV( 'Lower', 'NO TRANSPOSE', 
+     $                  'UNIT', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL DAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(I) to annihilate
+*        A(K+I+1:N,I)
+*
+         CALL DLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         EI = A( K+I, I )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(K+1:N,I)
+*
+         CALL DGEMV( 'NO TRANSPOSE', N-K, N-K-I+1, 
+     $               ONE, A( K+1, I+1 ),
+     $               LDA, A( K+I, I ), 1, ZERO, Y( K+1, I ), 1 )
+         CALL DGEMV( 'Transpose', N-K-I+1, I-1, 
+     $               ONE, A( K+I, 1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, T( 1, I ), 1 )
+         CALL DGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, 
+     $               Y( K+1, 1 ), LDY,
+     $               T( 1, I ), 1, ONE, Y( K+1, I ), 1 )
+         CALL DSCAL( N-K, TAU( I ), Y( K+1, I ), 1 )
+*
+*        Compute T(1:I,I)
+*
+         CALL DSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL DTRMV( 'Upper', 'No Transpose', 'NON-UNIT', 
+     $               I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+*     Compute Y(1:K,1:NB)
+*
+      CALL DLACPY( 'ALL', K, NB, A( 1, 2 ), LDA, Y, LDY )
+      CALL DTRMM( 'RIGHT', 'Lower', 'NO TRANSPOSE', 
+     $            'UNIT', K, NB,
+     $            ONE, A( K+1, 1 ), LDA, Y, LDY )
+      IF( N.GT.K+NB )
+     $   CALL DGEMM( 'NO TRANSPOSE', 'NO TRANSPOSE', K, 
+     $               NB, N-K-NB, ONE,
+     $               A( 1, 2+NB ), LDA, A( K+1+NB, 1 ), LDA, ONE, Y,
+     $               LDY )
+      CALL DTRMM( 'RIGHT', 'Upper', 'NO TRANSPOSE', 
+     $            'NON-UNIT', K, NB,
+     $            ONE, T, LDT, Y, LDY )
+*
+      RETURN
+*
+*     End of DLAHR2
+*
+      END
diff --git a/libcruft/lapack/dlahrd.f b/libcruft/lapack/dlahrd.f
new file mode 100644
index 0000000..a04133d
--- /dev/null
+++ b/libcruft/lapack/dlahrd.f
@@ -0,0 +1,207 @@
+      SUBROUTINE DLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAHRD reduces the first NB columns of a real general n-by-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by an orthogonal similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an OBSOLETE auxiliary routine. 
+*  This routine will be 'deprecated' in a  future release.
+*  Please use the new routine DLAHR2 instead.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) DOUBLE PRECISION array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) DOUBLE PRECISION array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      DOUBLE PRECISION   EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DCOPY, DGEMV, DLARFG, DSCAL, DTRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(1:n,i)
+*
+*           Compute i-th column of A - Y * V'
+*
+            CALL DGEMV( 'No transpose', N, I-1, -ONE, Y, LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( 1, I ), 1 )
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL DCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL DTRMV( 'Lower', 'Transpose', 'Unit', I-1, A( K+1, 1 ),
+     $                  LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL DGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ),
+     $                  LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL DTRMV( 'Upper', 'Transpose', 'Non-unit', I-1, T, LDT,
+     $                  T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL DGEMV( 'No transpose', N-K-I+1, I-1, -ONE, A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL DTRMV( 'Lower', 'No transpose', 'Unit', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL DAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(i) to annihilate
+*        A(k+i+1:n,i)
+*
+         CALL DLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         EI = A( K+I, I )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(1:n,i)
+*
+         CALL DGEMV( 'No transpose', N, N-K-I+1, ONE, A( 1, I+1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, Y( 1, I ), 1 )
+         CALL DGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, T( 1, I ), 1 )
+         CALL DGEMV( 'No transpose', N, I-1, -ONE, Y, LDY, T( 1, I ), 1,
+     $               ONE, Y( 1, I ), 1 )
+         CALL DSCAL( N, TAU( I ), Y( 1, I ), 1 )
+*
+*        Compute T(1:i,i)
+*
+         CALL DSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+      RETURN
+*
+*     End of DLAHRD
+*
+      END
diff --git a/libcruft/lapack/dlaic1.f b/libcruft/lapack/dlaic1.f
new file mode 100644
index 0000000..44baece
--- /dev/null
+++ b/libcruft/lapack/dlaic1.f
@@ -0,0 +1,292 @@
+      SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            J, JOB
+      DOUBLE PRECISION   C, GAMMA, S, SEST, SESTPR
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   W( J ), X( J )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAIC1 applies one step of incremental condition estimation in
+*  its simplest version:
+*
+*  Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
+*  lower triangular matrix L, such that
+*           twonorm(L*x) = sest
+*  Then DLAIC1 computes sestpr, s, c such that
+*  the vector
+*                  [ s*x ]
+*           xhat = [  c  ]
+*  is an approximate singular vector of
+*                  [ L     0  ]
+*           Lhat = [ w' gamma ]
+*  in the sense that
+*           twonorm(Lhat*xhat) = sestpr.
+*
+*  Depending on JOB, an estimate for the largest or smallest singular
+*  value is computed.
+*
+*  Note that [s c]' and sestpr**2 is an eigenpair of the system
+*
+*      diag(sest*sest, 0) + [alpha  gamma] * [ alpha ]
+*                                            [ gamma ]
+*
+*  where  alpha =  x'*w.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) INTEGER
+*          = 1: an estimate for the largest singular value is computed.
+*          = 2: an estimate for the smallest singular value is computed.
+*
+*  J       (input) INTEGER
+*          Length of X and W
+*
+*  X       (input) DOUBLE PRECISION array, dimension (J)
+*          The j-vector x.
+*
+*  SEST    (input) DOUBLE PRECISION
+*          Estimated singular value of j by j matrix L
+*
+*  W       (input) DOUBLE PRECISION array, dimension (J)
+*          The j-vector w.
+*
+*  GAMMA   (input) DOUBLE PRECISION
+*          The diagonal element gamma.
+*
+*  SESTPR  (output) DOUBLE PRECISION
+*          Estimated singular value of (j+1) by (j+1) matrix Lhat.
+*
+*  S       (output) DOUBLE PRECISION
+*          Sine needed in forming xhat.
+*
+*  C       (output) DOUBLE PRECISION
+*          Cosine needed in forming xhat.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
+      DOUBLE PRECISION   HALF, FOUR
+      PARAMETER          ( HALF = 0.5D0, FOUR = 4.0D0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,
+     $                   NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SIGN, SQRT
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DDOT, DLAMCH
+      EXTERNAL           DDOT, DLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+      EPS = DLAMCH( 'Epsilon' )
+      ALPHA = DDOT( J, X, 1, W, 1 )
+*
+      ABSALP = ABS( ALPHA )
+      ABSGAM = ABS( GAMMA )
+      ABSEST = ABS( SEST )
+*
+      IF( JOB.EQ.1 ) THEN
+*
+*        Estimating largest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            S1 = MAX( ABSGAM, ABSALP )
+            IF( S1.EQ.ZERO ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = ZERO
+            ELSE
+               S = ALPHA / S1
+               C = GAMMA / S1
+               TMP = SQRT( S*S+C*C )
+               S = S / TMP
+               C = C / TMP
+               SESTPR = S1*TMP
+            END IF
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ONE
+            C = ZERO
+            TMP = MAX( ABSEST, ABSALP )
+            S1 = ABSEST / TMP
+            S2 = ABSALP / TMP
+            SESTPR = TMP*SQRT( S1*S1+S2*S2 )
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            ELSE
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               S = SQRT( ONE+TMP*TMP )
+               SESTPR = S2*S
+               C = ( GAMMA / S2 ) / S
+               S = SIGN( ONE, ALPHA ) / S
+            ELSE
+               TMP = S2 / S1
+               C = SQRT( ONE+TMP*TMP )
+               SESTPR = S1*C
+               S = ( ALPHA / S1 ) / C
+               C = SIGN( ONE, GAMMA ) / C
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ALPHA / ABSEST
+            ZETA2 = GAMMA / ABSEST
+*
+            B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
+            C = ZETA1*ZETA1
+            IF( B.GT.ZERO ) THEN
+               T = C / ( B+SQRT( B*B+C ) )
+            ELSE
+               T = SQRT( B*B+C ) - B
+            END IF
+*
+            SINE = -ZETA1 / T
+            COSINE = -ZETA2 / ( ONE+T )
+            TMP = SQRT( SINE*SINE+COSINE*COSINE )
+            S = SINE / TMP
+            C = COSINE / TMP
+            SESTPR = SQRT( T+ONE )*ABSEST
+            RETURN
+         END IF
+*
+      ELSE IF( JOB.EQ.2 ) THEN
+*
+*        Estimating smallest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            SESTPR = ZERO
+            IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
+               SINE = ONE
+               COSINE = ZERO
+            ELSE
+               SINE = -GAMMA
+               COSINE = ALPHA
+            END IF
+            S1 = MAX( ABS( SINE ), ABS( COSINE ) )
+            S = SINE / S1
+            C = COSINE / S1
+            TMP = SQRT( S*S+C*C )
+            S = S / TMP
+            C = C / TMP
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ZERO
+            C = ONE
+            SESTPR = ABSGAM
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            ELSE
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               C = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST*( TMP / C )
+               S = -( GAMMA / S2 ) / C
+               C = SIGN( ONE, ALPHA ) / C
+            ELSE
+               TMP = S2 / S1
+               S = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST / S
+               C = ( ALPHA / S1 ) / S
+               S = -SIGN( ONE, GAMMA ) / S
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ALPHA / ABSEST
+            ZETA2 = GAMMA / ABSEST
+*
+            NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),
+     $              ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )
+*
+*           See if root is closer to zero or to ONE
+*
+            TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
+            IF( TEST.GE.ZERO ) THEN
+*
+*              root is close to zero, compute directly
+*
+               B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
+               C = ZETA2*ZETA2
+               T = C / ( B+SQRT( ABS( B*B-C ) ) )
+               SINE = ZETA1 / ( ONE-T )
+               COSINE = -ZETA2 / T
+               SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
+            ELSE
+*
+*              root is closer to ONE, shift by that amount
+*
+               B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
+               C = ZETA1*ZETA1
+               IF( B.GE.ZERO ) THEN
+                  T = -C / ( B+SQRT( B*B+C ) )
+               ELSE
+                  T = B - SQRT( B*B+C )
+               END IF
+               SINE = -ZETA1 / T
+               COSINE = -ZETA2 / ( ONE+T )
+               SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
+            END IF
+            TMP = SQRT( SINE*SINE+COSINE*COSINE )
+            S = SINE / TMP
+            C = COSINE / TMP
+            RETURN
+*
+         END IF
+      END IF
+      RETURN
+*
+*     End of DLAIC1
+*
+      END
diff --git a/libcruft/lapack/dlaln2.f b/libcruft/lapack/dlaln2.f
new file mode 100644
index 0000000..7c99bdb
--- /dev/null
+++ b/libcruft/lapack/dlaln2.f
@@ -0,0 +1,507 @@
+      SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,
+     $                   LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            LTRANS
+      INTEGER            INFO, LDA, LDB, LDX, NA, NW
+      DOUBLE PRECISION   CA, D1, D2, SCALE, SMIN, WI, WR, XNORM
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), X( LDX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLALN2 solves a system of the form  (ca A - w D ) X = s B
+*  or (ca A' - w D) X = s B   with possible scaling ("s") and
+*  perturbation of A.  (A' means A-transpose.)
+*
+*  A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
+*  real diagonal matrix, w is a real or complex value, and X and B are
+*  NA x 1 matrices -- real if w is real, complex if w is complex.  NA
+*  may be 1 or 2.
+*
+*  If w is complex, X and B are represented as NA x 2 matrices,
+*  the first column of each being the real part and the second
+*  being the imaginary part.
+*
+*  "s" is a scaling factor (.LE. 1), computed by DLALN2, which is
+*  so chosen that X can be computed without overflow.  X is further
+*  scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
+*  than overflow.
+*
+*  If both singular values of (ca A - w D) are less than SMIN,
+*  SMIN*identity will be used instead of (ca A - w D).  If only one
+*  singular value is less than SMIN, one element of (ca A - w D) will be
+*  perturbed enough to make the smallest singular value roughly SMIN.
+*  If both singular values are at least SMIN, (ca A - w D) will not be
+*  perturbed.  In any case, the perturbation will be at most some small
+*  multiple of max( SMIN, ulp*norm(ca A - w D) ).  The singular values
+*  are computed by infinity-norm approximations, and thus will only be
+*  correct to a factor of 2 or so.
+*
+*  Note: all input quantities are assumed to be smaller than overflow
+*  by a reasonable factor.  (See BIGNUM.)
+*
+*  Arguments
+*  ==========
+*
+*  LTRANS  (input) LOGICAL
+*          =.TRUE.:  A-transpose will be used.
+*          =.FALSE.: A will be used (not transposed.)
+*
+*  NA      (input) INTEGER
+*          The size of the matrix A.  It may (only) be 1 or 2.
+*
+*  NW      (input) INTEGER
+*          1 if "w" is real, 2 if "w" is complex.  It may only be 1
+*          or 2.
+*
+*  SMIN    (input) DOUBLE PRECISION
+*          The desired lower bound on the singular values of A.  This
+*          should be a safe distance away from underflow or overflow,
+*          say, between (underflow/machine precision) and  (machine
+*          precision * overflow ).  (See BIGNUM and ULP.)
+*
+*  CA      (input) DOUBLE PRECISION
+*          The coefficient c, which A is multiplied by.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,NA)
+*          The NA x NA matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of A.  It must be at least NA.
+*
+*  D1      (input) DOUBLE PRECISION
+*          The 1,1 element in the diagonal matrix D.
+*
+*  D2      (input) DOUBLE PRECISION
+*          The 2,2 element in the diagonal matrix D.  Not used if NW=1.
+*
+*  B       (input) DOUBLE PRECISION array, dimension (LDB,NW)
+*          The NA x NW matrix B (right-hand side).  If NW=2 ("w" is
+*          complex), column 1 contains the real part of B and column 2
+*          contains the imaginary part.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of B.  It must be at least NA.
+*
+*  WR      (input) DOUBLE PRECISION
+*          The real part of the scalar "w".
+*
+*  WI      (input) DOUBLE PRECISION
+*          The imaginary part of the scalar "w".  Not used if NW=1.
+*
+*  X       (output) DOUBLE PRECISION array, dimension (LDX,NW)
+*          The NA x NW matrix X (unknowns), as computed by DLALN2.
+*          If NW=2 ("w" is complex), on exit, column 1 will contain
+*          the real part of X and column 2 will contain the imaginary
+*          part.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of X.  It must be at least NA.
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scale factor that B must be multiplied by to insure
+*          that overflow does not occur when computing X.  Thus,
+*          (ca A - w D) X  will be SCALE*B, not B (ignoring
+*          perturbations of A.)  It will be at most 1.
+*
+*  XNORM   (output) DOUBLE PRECISION
+*          The infinity-norm of X, when X is regarded as an NA x NW
+*          real matrix.
+*
+*  INFO    (output) INTEGER
+*          An error flag.  It will be set to zero if no error occurs,
+*          a negative number if an argument is in error, or a positive
+*          number if  ca A - w D  had to be perturbed.
+*          The possible values are:
+*          = 0: No error occurred, and (ca A - w D) did not have to be
+*                 perturbed.
+*          = 1: (ca A - w D) had to be perturbed to make its smallest
+*               (or only) singular value greater than SMIN.
+*          NOTE: In the interests of speed, this routine does not
+*                check the inputs for errors.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            ICMAX, J
+      DOUBLE PRECISION   BBND, BI1, BI2, BIGNUM, BNORM, BR1, BR2, CI21,
+     $                   CI22, CMAX, CNORM, CR21, CR22, CSI, CSR, LI21,
+     $                   LR21, SMINI, SMLNUM, TEMP, U22ABS, UI11, UI11R,
+     $                   UI12, UI12S, UI22, UR11, UR11R, UR12, UR12S,
+     $                   UR22, XI1, XI2, XR1, XR2
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            RSWAP( 4 ), ZSWAP( 4 )
+      INTEGER            IPIVOT( 4, 4 )
+      DOUBLE PRECISION   CI( 2, 2 ), CIV( 4 ), CR( 2, 2 ), CRV( 4 )
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLADIV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Equivalences ..
+      EQUIVALENCE        ( CI( 1, 1 ), CIV( 1 ) ),
+     $                   ( CR( 1, 1 ), CRV( 1 ) )
+*     ..
+*     .. Data statements ..
+      DATA               ZSWAP / .FALSE., .FALSE., .TRUE., .TRUE. /
+      DATA               RSWAP / .FALSE., .TRUE., .FALSE., .TRUE. /
+      DATA               IPIVOT / 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4,
+     $                   3, 2, 1 /
+*     ..
+*     .. Executable Statements ..
+*
+*     Compute BIGNUM
+*
+      SMLNUM = TWO*DLAMCH( 'Safe minimum' )
+      BIGNUM = ONE / SMLNUM
+      SMINI = MAX( SMIN, SMLNUM )
+*
+*     Don't check for input errors
+*
+      INFO = 0
+*
+*     Standard Initializations
+*
+      SCALE = ONE
+*
+      IF( NA.EQ.1 ) THEN
+*
+*        1 x 1  (i.e., scalar) system   C X = B
+*
+         IF( NW.EQ.1 ) THEN
+*
+*           Real 1x1 system.
+*
+*           C = ca A - w D
+*
+            CSR = CA*A( 1, 1 ) - WR*D1
+            CNORM = ABS( CSR )
+*
+*           If | C | < SMINI, use C = SMINI
+*
+            IF( CNORM.LT.SMINI ) THEN
+               CSR = SMINI
+               CNORM = SMINI
+               INFO = 1
+            END IF
+*
+*           Check scaling for  X = B / C
+*
+            BNORM = ABS( B( 1, 1 ) )
+            IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
+               IF( BNORM.GT.BIGNUM*CNORM )
+     $            SCALE = ONE / BNORM
+            END IF
+*
+*           Compute X
+*
+            X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / CSR
+            XNORM = ABS( X( 1, 1 ) )
+         ELSE
+*
+*           Complex 1x1 system (w is complex)
+*
+*           C = ca A - w D
+*
+            CSR = CA*A( 1, 1 ) - WR*D1
+            CSI = -WI*D1
+            CNORM = ABS( CSR ) + ABS( CSI )
+*
+*           If | C | < SMINI, use C = SMINI
+*
+            IF( CNORM.LT.SMINI ) THEN
+               CSR = SMINI
+               CSI = ZERO
+               CNORM = SMINI
+               INFO = 1
+            END IF
+*
+*           Check scaling for  X = B / C
+*
+            BNORM = ABS( B( 1, 1 ) ) + ABS( B( 1, 2 ) )
+            IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
+               IF( BNORM.GT.BIGNUM*CNORM )
+     $            SCALE = ONE / BNORM
+            END IF
+*
+*           Compute X
+*
+            CALL DLADIV( SCALE*B( 1, 1 ), SCALE*B( 1, 2 ), CSR, CSI,
+     $                   X( 1, 1 ), X( 1, 2 ) )
+            XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
+         END IF
+*
+      ELSE
+*
+*        2x2 System
+*
+*        Compute the real part of  C = ca A - w D  (or  ca A' - w D )
+*
+         CR( 1, 1 ) = CA*A( 1, 1 ) - WR*D1
+         CR( 2, 2 ) = CA*A( 2, 2 ) - WR*D2
+         IF( LTRANS ) THEN
+            CR( 1, 2 ) = CA*A( 2, 1 )
+            CR( 2, 1 ) = CA*A( 1, 2 )
+         ELSE
+            CR( 2, 1 ) = CA*A( 2, 1 )
+            CR( 1, 2 ) = CA*A( 1, 2 )
+         END IF
+*
+         IF( NW.EQ.1 ) THEN
+*
+*           Real 2x2 system  (w is real)
+*
+*           Find the largest element in C
+*
+            CMAX = ZERO
+            ICMAX = 0
+*
+            DO 10 J = 1, 4
+               IF( ABS( CRV( J ) ).GT.CMAX ) THEN
+                  CMAX = ABS( CRV( J ) )
+                  ICMAX = J
+               END IF
+   10       CONTINUE
+*
+*           If norm(C) < SMINI, use SMINI*identity.
+*
+            IF( CMAX.LT.SMINI ) THEN
+               BNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 2, 1 ) ) )
+               IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
+                  IF( BNORM.GT.BIGNUM*SMINI )
+     $               SCALE = ONE / BNORM
+               END IF
+               TEMP = SCALE / SMINI
+               X( 1, 1 ) = TEMP*B( 1, 1 )
+               X( 2, 1 ) = TEMP*B( 2, 1 )
+               XNORM = TEMP*BNORM
+               INFO = 1
+               RETURN
+            END IF
+*
+*           Gaussian elimination with complete pivoting.
+*
+            UR11 = CRV( ICMAX )
+            CR21 = CRV( IPIVOT( 2, ICMAX ) )
+            UR12 = CRV( IPIVOT( 3, ICMAX ) )
+            CR22 = CRV( IPIVOT( 4, ICMAX ) )
+            UR11R = ONE / UR11
+            LR21 = UR11R*CR21
+            UR22 = CR22 - UR12*LR21
+*
+*           If smaller pivot < SMINI, use SMINI
+*
+            IF( ABS( UR22 ).LT.SMINI ) THEN
+               UR22 = SMINI
+               INFO = 1
+            END IF
+            IF( RSWAP( ICMAX ) ) THEN
+               BR1 = B( 2, 1 )
+               BR2 = B( 1, 1 )
+            ELSE
+               BR1 = B( 1, 1 )
+               BR2 = B( 2, 1 )
+            END IF
+            BR2 = BR2 - LR21*BR1
+            BBND = MAX( ABS( BR1*( UR22*UR11R ) ), ABS( BR2 ) )
+            IF( BBND.GT.ONE .AND. ABS( UR22 ).LT.ONE ) THEN
+               IF( BBND.GE.BIGNUM*ABS( UR22 ) )
+     $            SCALE = ONE / BBND
+            END IF
+*
+            XR2 = ( BR2*SCALE ) / UR22
+            XR1 = ( SCALE*BR1 )*UR11R - XR2*( UR11R*UR12 )
+            IF( ZSWAP( ICMAX ) ) THEN
+               X( 1, 1 ) = XR2
+               X( 2, 1 ) = XR1
+            ELSE
+               X( 1, 1 ) = XR1
+               X( 2, 1 ) = XR2
+            END IF
+            XNORM = MAX( ABS( XR1 ), ABS( XR2 ) )
+*
+*           Further scaling if  norm(A) norm(X) > overflow
+*
+            IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
+               IF( XNORM.GT.BIGNUM / CMAX ) THEN
+                  TEMP = CMAX / BIGNUM
+                  X( 1, 1 ) = TEMP*X( 1, 1 )
+                  X( 2, 1 ) = TEMP*X( 2, 1 )
+                  XNORM = TEMP*XNORM
+                  SCALE = TEMP*SCALE
+               END IF
+            END IF
+         ELSE
+*
+*           Complex 2x2 system  (w is complex)
+*
+*           Find the largest element in C
+*
+            CI( 1, 1 ) = -WI*D1
+            CI( 2, 1 ) = ZERO
+            CI( 1, 2 ) = ZERO
+            CI( 2, 2 ) = -WI*D2
+            CMAX = ZERO
+            ICMAX = 0
+*
+            DO 20 J = 1, 4
+               IF( ABS( CRV( J ) )+ABS( CIV( J ) ).GT.CMAX ) THEN
+                  CMAX = ABS( CRV( J ) ) + ABS( CIV( J ) )
+                  ICMAX = J
+               END IF
+   20       CONTINUE
+*
+*           If norm(C) < SMINI, use SMINI*identity.
+*
+            IF( CMAX.LT.SMINI ) THEN
+               BNORM = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),
+     $                 ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )
+               IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
+                  IF( BNORM.GT.BIGNUM*SMINI )
+     $               SCALE = ONE / BNORM
+               END IF
+               TEMP = SCALE / SMINI
+               X( 1, 1 ) = TEMP*B( 1, 1 )
+               X( 2, 1 ) = TEMP*B( 2, 1 )
+               X( 1, 2 ) = TEMP*B( 1, 2 )
+               X( 2, 2 ) = TEMP*B( 2, 2 )
+               XNORM = TEMP*BNORM
+               INFO = 1
+               RETURN
+            END IF
+*
+*           Gaussian elimination with complete pivoting.
+*
+            UR11 = CRV( ICMAX )
+            UI11 = CIV( ICMAX )
+            CR21 = CRV( IPIVOT( 2, ICMAX ) )
+            CI21 = CIV( IPIVOT( 2, ICMAX ) )
+            UR12 = CRV( IPIVOT( 3, ICMAX ) )
+            UI12 = CIV( IPIVOT( 3, ICMAX ) )
+            CR22 = CRV( IPIVOT( 4, ICMAX ) )
+            CI22 = CIV( IPIVOT( 4, ICMAX ) )
+            IF( ICMAX.EQ.1 .OR. ICMAX.EQ.4 ) THEN
+*
+*              Code when off-diagonals of pivoted C are real
+*
+               IF( ABS( UR11 ).GT.ABS( UI11 ) ) THEN
+                  TEMP = UI11 / UR11
+                  UR11R = ONE / ( UR11*( ONE+TEMP**2 ) )
+                  UI11R = -TEMP*UR11R
+               ELSE
+                  TEMP = UR11 / UI11
+                  UI11R = -ONE / ( UI11*( ONE+TEMP**2 ) )
+                  UR11R = -TEMP*UI11R
+               END IF
+               LR21 = CR21*UR11R
+               LI21 = CR21*UI11R
+               UR12S = UR12*UR11R
+               UI12S = UR12*UI11R
+               UR22 = CR22 - UR12*LR21
+               UI22 = CI22 - UR12*LI21
+            ELSE
+*
+*              Code when diagonals of pivoted C are real
+*
+               UR11R = ONE / UR11
+               UI11R = ZERO
+               LR21 = CR21*UR11R
+               LI21 = CI21*UR11R
+               UR12S = UR12*UR11R
+               UI12S = UI12*UR11R
+               UR22 = CR22 - UR12*LR21 + UI12*LI21
+               UI22 = -UR12*LI21 - UI12*LR21
+            END IF
+            U22ABS = ABS( UR22 ) + ABS( UI22 )
+*
+*           If smaller pivot < SMINI, use SMINI
+*
+            IF( U22ABS.LT.SMINI ) THEN
+               UR22 = SMINI
+               UI22 = ZERO
+               INFO = 1
+            END IF
+            IF( RSWAP( ICMAX ) ) THEN
+               BR2 = B( 1, 1 )
+               BR1 = B( 2, 1 )
+               BI2 = B( 1, 2 )
+               BI1 = B( 2, 2 )
+            ELSE
+               BR1 = B( 1, 1 )
+               BR2 = B( 2, 1 )
+               BI1 = B( 1, 2 )
+               BI2 = B( 2, 2 )
+            END IF
+            BR2 = BR2 - LR21*BR1 + LI21*BI1
+            BI2 = BI2 - LI21*BR1 - LR21*BI1
+            BBND = MAX( ( ABS( BR1 )+ABS( BI1 ) )*
+     $             ( U22ABS*( ABS( UR11R )+ABS( UI11R ) ) ),
+     $             ABS( BR2 )+ABS( BI2 ) )
+            IF( BBND.GT.ONE .AND. U22ABS.LT.ONE ) THEN
+               IF( BBND.GE.BIGNUM*U22ABS ) THEN
+                  SCALE = ONE / BBND
+                  BR1 = SCALE*BR1
+                  BI1 = SCALE*BI1
+                  BR2 = SCALE*BR2
+                  BI2 = SCALE*BI2
+               END IF
+            END IF
+*
+            CALL DLADIV( BR2, BI2, UR22, UI22, XR2, XI2 )
+            XR1 = UR11R*BR1 - UI11R*BI1 - UR12S*XR2 + UI12S*XI2
+            XI1 = UI11R*BR1 + UR11R*BI1 - UI12S*XR2 - UR12S*XI2
+            IF( ZSWAP( ICMAX ) ) THEN
+               X( 1, 1 ) = XR2
+               X( 2, 1 ) = XR1
+               X( 1, 2 ) = XI2
+               X( 2, 2 ) = XI1
+            ELSE
+               X( 1, 1 ) = XR1
+               X( 2, 1 ) = XR2
+               X( 1, 2 ) = XI1
+               X( 2, 2 ) = XI2
+            END IF
+            XNORM = MAX( ABS( XR1 )+ABS( XI1 ), ABS( XR2 )+ABS( XI2 ) )
+*
+*           Further scaling if  norm(A) norm(X) > overflow
+*
+            IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
+               IF( XNORM.GT.BIGNUM / CMAX ) THEN
+                  TEMP = CMAX / BIGNUM
+                  X( 1, 1 ) = TEMP*X( 1, 1 )
+                  X( 2, 1 ) = TEMP*X( 2, 1 )
+                  X( 1, 2 ) = TEMP*X( 1, 2 )
+                  X( 2, 2 ) = TEMP*X( 2, 2 )
+                  XNORM = TEMP*XNORM
+                  SCALE = TEMP*SCALE
+               END IF
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DLALN2
+*
+      END
diff --git a/libcruft/lapack/dlals0.f b/libcruft/lapack/dlals0.f
new file mode 100644
index 0000000..ed81023
--- /dev/null
+++ b/libcruft/lapack/dlals0.f
@@ -0,0 +1,377 @@
+      SUBROUTINE DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
+     $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
+     $                   POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
+     $                   LDGNUM, NL, NR, NRHS, SQRE
+      DOUBLE PRECISION   C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), PERM( * )
+      DOUBLE PRECISION   B( LDB, * ), BX( LDBX, * ), DIFL( * ),
+     $                   DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),
+     $                   POLES( LDGNUM, * ), WORK( * ), Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLALS0 applies back the multiplying factors of either the left or the
+*  right singular vector matrix of a diagonal matrix appended by a row
+*  to the right hand side matrix B in solving the least squares problem
+*  using the divide-and-conquer SVD approach.
+*
+*  For the left singular vector matrix, three types of orthogonal
+*  matrices are involved:
+*
+*  (1L) Givens rotations: the number of such rotations is GIVPTR; the
+*       pairs of columns/rows they were applied to are stored in GIVCOL;
+*       and the C- and S-values of these rotations are stored in GIVNUM.
+*
+*  (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
+*       row, and for J=2:N, PERM(J)-th row of B is to be moved to the
+*       J-th row.
+*
+*  (3L) The left singular vector matrix of the remaining matrix.
+*
+*  For the right singular vector matrix, four types of orthogonal
+*  matrices are involved:
+*
+*  (1R) The right singular vector matrix of the remaining matrix.
+*
+*  (2R) If SQRE = 1, one extra Givens rotation to generate the right
+*       null space.
+*
+*  (3R) The inverse transformation of (2L).
+*
+*  (4R) The inverse transformation of (1L).
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed in
+*         factored form:
+*         = 0: Left singular vector matrix.
+*         = 1: Right singular vector matrix.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block. NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block. NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) DOUBLE PRECISION array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M. On output, B contains
+*         the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B. LDB must be at least
+*         max(1,MAX( M, N ) ).
+*
+*  BX     (workspace) DOUBLE PRECISION array, dimension ( LDBX, NRHS )
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  PERM   (input) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) applied
+*         to the two blocks.
+*
+*  GIVPTR (input) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of rows/columns
+*         involved in a Givens rotation.
+*
+*  LDGCOL (input) INTEGER
+*         The leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value used in the
+*         corresponding Givens rotation.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of arrays DIFR, POLES and
+*         GIVNUM, must be at least K.
+*
+*  POLES  (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         On entry, POLES(1:K, 1) contains the new singular
+*         values obtained from solving the secular equation, and
+*         POLES(1:K, 2) is an array containing the poles in the secular
+*         equation.
+*
+*  DIFL   (input) DOUBLE PRECISION array, dimension ( K ).
+*         On entry, DIFL(I) is the distance between I-th updated
+*         (undeflated) singular value and the I-th (undeflated) old
+*         singular value.
+*
+*  DIFR   (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ).
+*         On entry, DIFR(I, 1) contains the distances between I-th
+*         updated (undeflated) singular value and the I+1-th
+*         (undeflated) old singular value. And DIFR(I, 2) is the
+*         normalizing factor for the I-th right singular vector.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( K )
+*         Contain the components of the deflation-adjusted updating row
+*         vector.
+*
+*  K      (input) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  C      (input) DOUBLE PRECISION
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (input) DOUBLE PRECISION
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension ( K )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO, NEGONE
+      PARAMETER          ( ONE = 1.0D0, ZERO = 0.0D0, NEGONE = -1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, M, N, NLP1
+      DOUBLE PRECISION   DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEMV, DLACPY, DLASCL, DROT, DSCAL,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3, DNRM2
+      EXTERNAL           DLAMC3, DNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      END IF
+*
+      N = NL + NR + 1
+*
+      IF( NRHS.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -7
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -9
+      ELSE IF( GIVPTR.LT.0 ) THEN
+         INFO = -11
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -13
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -15
+      ELSE IF( K.LT.1 ) THEN
+         INFO = -20
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLALS0', -INFO )
+         RETURN
+      END IF
+*
+      M = N + SQRE
+      NLP1 = NL + 1
+*
+      IF( ICOMPQ.EQ.0 ) THEN
+*
+*        Apply back orthogonal transformations from the left.
+*
+*        Step (1L): apply back the Givens rotations performed.
+*
+         DO 10 I = 1, GIVPTR
+            CALL DROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                 B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                 GIVNUM( I, 1 ) )
+   10    CONTINUE
+*
+*        Step (2L): permute rows of B.
+*
+         CALL DCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
+         DO 20 I = 2, N
+            CALL DCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
+   20    CONTINUE
+*
+*        Step (3L): apply the inverse of the left singular vector
+*        matrix to BX.
+*
+         IF( K.EQ.1 ) THEN
+            CALL DCOPY( NRHS, BX, LDBX, B, LDB )
+            IF( Z( 1 ).LT.ZERO ) THEN
+               CALL DSCAL( NRHS, NEGONE, B, LDB )
+            END IF
+         ELSE
+            DO 50 J = 1, K
+               DIFLJ = DIFL( J )
+               DJ = POLES( J, 1 )
+               DSIGJ = -POLES( J, 2 )
+               IF( J.LT.K ) THEN
+                  DIFRJ = -DIFR( J, 1 )
+                  DSIGJP = -POLES( J+1, 2 )
+               END IF
+               IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
+     $              THEN
+                  WORK( J ) = ZERO
+               ELSE
+                  WORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
+     $                        ( POLES( J, 2 )+DJ )
+               END IF
+               DO 30 I = 1, J - 1
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                           ( DLAMC3( POLES( I, 2 ), DSIGJ )-
+     $                           DIFLJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   30          CONTINUE
+               DO 40 I = J + 1, K
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                           ( DLAMC3( POLES( I, 2 ), DSIGJP )+
+     $                           DIFRJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   40          CONTINUE
+               WORK( 1 ) = NEGONE
+               TEMP = DNRM2( K, WORK, 1 )
+               CALL DGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
+     $                     B( J, 1 ), LDB )
+               CALL DLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
+     $                      LDB, INFO )
+   50       CONTINUE
+         END IF
+*
+*        Move the deflated rows of BX to B also.
+*
+         IF( K.LT.MAX( M, N ) )
+     $      CALL DLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
+     $                   B( K+1, 1 ), LDB )
+      ELSE
+*
+*        Apply back the right orthogonal transformations.
+*
+*        Step (1R): apply back the new right singular vector matrix
+*        to B.
+*
+         IF( K.EQ.1 ) THEN
+            CALL DCOPY( NRHS, B, LDB, BX, LDBX )
+         ELSE
+            DO 80 J = 1, K
+               DSIGJ = POLES( J, 2 )
+               IF( Z( J ).EQ.ZERO ) THEN
+                  WORK( J ) = ZERO
+               ELSE
+                  WORK( J ) = -Z( J ) / DIFL( J ) /
+     $                        ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
+               END IF
+               DO 60 I = 1, J - 1
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I+1,
+     $                           2 ) )-DIFR( I, 1 ) ) /
+     $                           ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+   60          CONTINUE
+               DO 70 I = J + 1, K
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I,
+     $                           2 ) )-DIFL( I ) ) /
+     $                           ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+   70          CONTINUE
+               CALL DGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
+     $                     BX( J, 1 ), LDBX )
+   80       CONTINUE
+         END IF
+*
+*        Step (2R): if SQRE = 1, apply back the rotation that is
+*        related to the right null space of the subproblem.
+*
+         IF( SQRE.EQ.1 ) THEN
+            CALL DCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
+            CALL DROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
+         END IF
+         IF( K.LT.MAX( M, N ) )
+     $      CALL DLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),
+     $                   LDBX )
+*
+*        Step (3R): permute rows of B.
+*
+         CALL DCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
+         IF( SQRE.EQ.1 ) THEN
+            CALL DCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
+         END IF
+         DO 90 I = 2, N
+            CALL DCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
+   90    CONTINUE
+*
+*        Step (4R): apply back the Givens rotations performed.
+*
+         DO 100 I = GIVPTR, 1, -1
+            CALL DROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                 B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                 -GIVNUM( I, 1 ) )
+  100    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DLALS0
+*
+      END
diff --git a/libcruft/lapack/dlalsa.f b/libcruft/lapack/dlalsa.f
new file mode 100644
index 0000000..418320e
--- /dev/null
+++ b/libcruft/lapack/dlalsa.f
@@ -0,0 +1,362 @@
+      SUBROUTINE DLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,
+     $                   LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,
+     $                   GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,
+     $                   SMLSIZ
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
+     $                   K( * ), PERM( LDGCOL, * )
+      DOUBLE PRECISION   B( LDB, * ), BX( LDBX, * ), C( * ),
+     $                   DIFL( LDU, * ), DIFR( LDU, * ),
+     $                   GIVNUM( LDU, * ), POLES( LDU, * ), S( * ),
+     $                   U( LDU, * ), VT( LDU, * ), WORK( * ),
+     $                   Z( LDU, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLALSA is an itermediate step in solving the least squares problem
+*  by computing the SVD of the coefficient matrix in compact form (The
+*  singular vectors are computed as products of simple orthorgonal
+*  matrices.).
+*
+*  If ICOMPQ = 0, DLALSA applies the inverse of the left singular vector
+*  matrix of an upper bidiagonal matrix to the right hand side; and if
+*  ICOMPQ = 1, DLALSA applies the right singular vector matrix to the
+*  right hand side. The singular vector matrices were generated in
+*  compact form by DLALSA.
+*
+*  Arguments
+*  =========
+*
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether the left or the right singular vector
+*         matrix is involved.
+*         = 0: Left singular vector matrix
+*         = 1: Right singular vector matrix
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The row and column dimensions of the upper bidiagonal matrix.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) DOUBLE PRECISION array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M.
+*         On output, B contains the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,MAX( M, N ) ).
+*
+*  BX     (output) DOUBLE PRECISION array, dimension ( LDBX, NRHS )
+*         On exit, the result of applying the left or right singular
+*         vector matrix to B.
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  U      (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ ).
+*         On entry, U contains the left singular vector matrices of all
+*         subproblems at the bottom level.
+*
+*  LDU    (input) INTEGER, LDU = > N.
+*         The leading dimension of arrays U, VT, DIFL, DIFR,
+*         POLES, GIVNUM, and Z.
+*
+*  VT     (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ+1 ).
+*         On entry, VT' contains the right singular vector matrices of
+*         all subproblems at the bottom level.
+*
+*  K      (input) INTEGER array, dimension ( N ).
+*
+*  DIFL   (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ).
+*         where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.
+*
+*  DIFR   (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).
+*         On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record
+*         distances between singular values on the I-th level and
+*         singular values on the (I -1)-th level, and DIFR(*, 2 * I)
+*         record the normalizing factors of the right singular vectors
+*         matrices of subproblems on I-th level.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ).
+*         On entry, Z(1, I) contains the components of the deflation-
+*         adjusted updating row vector for subproblems on the I-th
+*         level.
+*
+*  POLES  (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).
+*         On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old
+*         singular values involved in the secular equations on the I-th
+*         level.
+*
+*  GIVPTR (input) INTEGER array, dimension ( N ).
+*         On entry, GIVPTR( I ) records the number of Givens
+*         rotations performed on the I-th problem on the computation
+*         tree.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ).
+*         On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the
+*         locations of Givens rotations performed on the I-th level on
+*         the computation tree.
+*
+*  LDGCOL (input) INTEGER, LDGCOL = > N.
+*         The leading dimension of arrays GIVCOL and PERM.
+*
+*  PERM   (input) INTEGER array, dimension ( LDGCOL, NLVL ).
+*         On entry, PERM(*, I) records permutations done on the I-th
+*         level of the computation tree.
+*
+*  GIVNUM (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).
+*         On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-
+*         values of Givens rotations performed on the I-th level on the
+*         computation tree.
+*
+*  C      (input) DOUBLE PRECISION array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         C( I ) contains the C-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  S      (input) DOUBLE PRECISION array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         S( I ) contains the S-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  WORK   (workspace) DOUBLE PRECISION array.
+*         The dimension must be at least N.
+*
+*  IWORK  (workspace) INTEGER array.
+*         The dimension must be at least 3 * N
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IM1, INODE, J, LF, LL, LVL, LVL2,
+     $                   ND, NDB1, NDIML, NDIMR, NL, NLF, NLP1, NLVL,
+     $                   NR, NRF, NRP1, SQRE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEMM, DLALS0, DLASDT, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.SMLSIZ ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -6
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -19
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLALSA', -INFO )
+         RETURN
+      END IF
+*
+*     Book-keeping and  setting up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+*
+      CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     The following code applies back the left singular vector factors.
+*     For applying back the right singular vector factors, go to 50.
+*
+      IF( ICOMPQ.EQ.1 ) THEN
+         GO TO 50
+      END IF
+*
+*     The nodes on the bottom level of the tree were solved
+*     by DLASDQ. The corresponding left and right singular vector
+*     matrices are in explicit form. First apply back the left
+*     singular vector matrices.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 10 I = NDB1, ND
+*
+*        IC : center row of each node
+*        NL : number of rows of left  subproblem
+*        NR : number of rows of right subproblem
+*        NLF: starting row of the left   subproblem
+*        NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLF = IC - NL
+         NRF = IC + 1
+         CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+         CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+     $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+   10 CONTINUE
+*
+*     Next copy the rows of B that correspond to unchanged rows
+*     in the bidiagonal matrix to BX.
+*
+      DO 20 I = 1, ND
+         IC = IWORK( INODE+I-1 )
+         CALL DCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )
+   20 CONTINUE
+*
+*     Finally go through the left singular vector matrices of all
+*     the other subproblems bottom-up on the tree.
+*
+      J = 2**NLVL
+      SQRE = 0
+*
+      DO 40 LVL = NLVL, 1, -1
+         LVL2 = 2*LVL - 1
+*
+*        find the first node LF and last node LL on
+*        the current level LVL
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 30 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            J = J - 1
+            CALL DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,
+     $                   B( NLF, 1 ), LDB, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,
+     $                   INFO )
+   30    CONTINUE
+   40 CONTINUE
+      GO TO 90
+*
+*     ICOMPQ = 1: applying back the right singular vector factors.
+*
+   50 CONTINUE
+*
+*     First now go through the right singular vector matrices of all
+*     the tree nodes top-down.
+*
+      J = 0
+      DO 70 LVL = 1, NLVL
+         LVL2 = 2*LVL - 1
+*
+*        Find the first node LF and last node LL on
+*        the current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 60 I = LL, LF, -1
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            IF( I.EQ.LL ) THEN
+               SQRE = 0
+            ELSE
+               SQRE = 1
+            END IF
+            J = J + 1
+            CALL DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,
+     $                   BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,
+     $                   INFO )
+   60    CONTINUE
+   70 CONTINUE
+*
+*     The nodes on the bottom level of the tree were solved
+*     by DLASDQ. The corresponding right singular vector
+*     matrices are in explicit form. Apply them back.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 80 I = NDB1, ND
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLP1 = NL + 1
+         IF( I.EQ.ND ) THEN
+            NRP1 = NR
+         ELSE
+            NRP1 = NR + 1
+         END IF
+         NLF = IC - NL
+         NRF = IC + 1
+         CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+         CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+     $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+   80 CONTINUE
+*
+   90 CONTINUE
+*
+      RETURN
+*
+*     End of DLALSA
+*
+      END
diff --git a/libcruft/lapack/dlalsd.f b/libcruft/lapack/dlalsd.f
new file mode 100644
index 0000000..f6a0c8b
--- /dev/null
+++ b/libcruft/lapack/dlalsd.f
@@ -0,0 +1,434 @@
+      SUBROUTINE DLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
+     $                   RANK, WORK, IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDB, N, NRHS, RANK, SMLSIZ
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   B( LDB, * ), D( * ), E( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLALSD uses the singular value decomposition of A to solve the least
+*  squares problem of finding X to minimize the Euclidean norm of each
+*  column of A*X-B, where A is N-by-N upper bidiagonal, and X and B
+*  are N-by-NRHS. The solution X overwrites B.
+*
+*  The singular values of A smaller than RCOND times the largest
+*  singular value are treated as zero in solving the least squares
+*  problem; in this case a minimum norm solution is returned.
+*  The actual singular values are returned in D in ascending order.
+*
+*  This code makes very mild assumptions about floating point
+*  arithmetic. It will work on machines with a guard digit in
+*  add/subtract, or on those binary machines without guard digits
+*  which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
+*  It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  UPLO   (input) CHARACTER*1
+*         = 'U': D and E define an upper bidiagonal matrix.
+*         = 'L': D and E define a  lower bidiagonal matrix.
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The dimension of the  bidiagonal matrix.  N >= 0.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B. NRHS must be at least 1.
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension (N)
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix. On exit, if INFO = 0, D contains its singular values.
+*
+*  E      (input/output) DOUBLE PRECISION array, dimension (N-1)
+*         Contains the super-diagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  B      (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*         On input, B contains the right hand sides of the least
+*         squares problem. On output, B contains the solution X.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,N).
+*
+*  RCOND  (input) DOUBLE PRECISION
+*         The singular values of A less than or equal to RCOND times
+*         the largest singular value are treated as zero in solving
+*         the least squares problem. If RCOND is negative,
+*         machine precision is used instead.
+*         For example, if diag(S)*X=B were the least squares problem,
+*         where diag(S) is a diagonal matrix of singular values, the
+*         solution would be X(i) = B(i) / S(i) if S(i) is greater than
+*         RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to
+*         RCOND*max(S).
+*
+*  RANK   (output) INTEGER
+*         The number of singular values of A greater than RCOND times
+*         the largest singular value.
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension at least
+*         (9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2),
+*         where NLVL = max(0, INT(log_2 (N/(SMLSIZ+1))) + 1).
+*
+*  IWORK  (workspace) INTEGER array, dimension at least
+*         (3*N*NLVL + 11*N)
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*         > 0:  The algorithm failed to compute an singular value while
+*               working on the submatrix lying in rows and columns
+*               INFO/(N+1) through MOD(INFO,N+1).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
+     $                   GIVPTR, I, ICMPQ1, ICMPQ2, IWK, J, K, NLVL,
+     $                   NM1, NSIZE, NSUB, NWORK, PERM, POLES, S, SIZEI,
+     $                   SMLSZP, SQRE, ST, ST1, U, VT, Z
+      DOUBLE PRECISION   CS, EPS, ORGNRM, R, RCND, SN, TOL
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DLANST
+      EXTERNAL           IDAMAX, DLAMCH, DLANST
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEMM, DLACPY, DLALSA, DLARTG, DLASCL,
+     $                   DLASDA, DLASDQ, DLASET, DLASRT, DROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, INT, LOG, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLALSD', -INFO )
+         RETURN
+      END IF
+*
+      EPS = DLAMCH( 'Epsilon' )
+*
+*     Set up the tolerance.
+*
+      IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THEN
+         RCND = EPS
+      ELSE
+         RCND = RCOND
+      END IF
+*
+      RANK = 0
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+         IF( D( 1 ).EQ.ZERO ) THEN
+            CALL DLASET( 'A', 1, NRHS, ZERO, ZERO, B, LDB )
+         ELSE
+            RANK = 1
+            CALL DLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )
+            D( 1 ) = ABS( D( 1 ) )
+         END IF
+         RETURN
+      END IF
+*
+*     Rotate the matrix if it is lower bidiagonal.
+*
+      IF( UPLO.EQ.'L' ) THEN
+         DO 10 I = 1, N - 1
+            CALL DLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( NRHS.EQ.1 ) THEN
+               CALL DROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )
+            ELSE
+               WORK( I*2-1 ) = CS
+               WORK( I*2 ) = SN
+            END IF
+   10    CONTINUE
+         IF( NRHS.GT.1 ) THEN
+            DO 30 I = 1, NRHS
+               DO 20 J = 1, N - 1
+                  CS = WORK( J*2-1 )
+                  SN = WORK( J*2 )
+                  CALL DROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )
+   20          CONTINUE
+   30       CONTINUE
+         END IF
+      END IF
+*
+*     Scale.
+*
+      NM1 = N - 1
+      ORGNRM = DLANST( 'M', N, D, E )
+      IF( ORGNRM.EQ.ZERO ) THEN
+         CALL DLASET( 'A', N, NRHS, ZERO, ZERO, B, LDB )
+         RETURN
+      END IF
+*
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )
+*
+*     If N is smaller than the minimum divide size SMLSIZ, then solve
+*     the problem with another solver.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         NWORK = 1 + N*N
+         CALL DLASET( 'A', N, N, ZERO, ONE, WORK, N )
+         CALL DLASDQ( 'U', 0, N, N, 0, NRHS, D, E, WORK, N, WORK, N, B,
+     $                LDB, WORK( NWORK ), INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         TOL = RCND*ABS( D( IDAMAX( N, D, 1 ) ) )
+         DO 40 I = 1, N
+            IF( D( I ).LE.TOL ) THEN
+               CALL DLASET( 'A', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            ELSE
+               CALL DLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),
+     $                      LDB, INFO )
+               RANK = RANK + 1
+            END IF
+   40    CONTINUE
+         CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,
+     $               WORK( NWORK ), N )
+         CALL DLACPY( 'A', N, NRHS, WORK( NWORK ), N, B, LDB )
+*
+*        Unscale.
+*
+         CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+         CALL DLASRT( 'D', N, D, INFO )
+         CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+         RETURN
+      END IF
+*
+*     Book-keeping and setting up some constants.
+*
+      NLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1
+*
+      SMLSZP = SMLSIZ + 1
+*
+      U = 1
+      VT = 1 + SMLSIZ*N
+      DIFL = VT + SMLSZP*N
+      DIFR = DIFL + NLVL*N
+      Z = DIFR + NLVL*N*2
+      C = Z + NLVL*N
+      S = C + N
+      POLES = S + N
+      GIVNUM = POLES + 2*NLVL*N
+      BX = GIVNUM + 2*NLVL*N
+      NWORK = BX + N*NRHS
+*
+      SIZEI = 1 + N
+      K = SIZEI + N
+      GIVPTR = K + N
+      PERM = GIVPTR + N
+      GIVCOL = PERM + NLVL*N
+      IWK = GIVCOL + NLVL*N*2
+*
+      ST = 1
+      SQRE = 0
+      ICMPQ1 = 1
+      ICMPQ2 = 0
+      NSUB = 0
+*
+      DO 50 I = 1, N
+         IF( ABS( D( I ) ).LT.EPS ) THEN
+            D( I ) = SIGN( EPS, D( I ) )
+         END IF
+   50 CONTINUE
+*
+      DO 60 I = 1, NM1
+         IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
+            NSUB = NSUB + 1
+            IWORK( NSUB ) = ST
+*
+*           Subproblem found. First determine its size and then
+*           apply divide and conquer on it.
+*
+            IF( I.LT.NM1 ) THEN
+*
+*              A subproblem with E(I) small for I < NM1.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
+*
+*              A subproblem with E(NM1) not too small but I = NM1.
+*
+               NSIZE = N - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE
+*
+*              A subproblem with E(NM1) small. This implies an
+*              1-by-1 subproblem at D(N), which is not solved
+*              explicitly.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+               NSUB = NSUB + 1
+               IWORK( NSUB ) = N
+               IWORK( SIZEI+NSUB-1 ) = 1
+               CALL DCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )
+            END IF
+            ST1 = ST - 1
+            IF( NSIZE.EQ.1 ) THEN
+*
+*              This is a 1-by-1 subproblem and is not solved
+*              explicitly.
+*
+               CALL DCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )
+            ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+*
+*              This is a small subproblem and is solved by DLASDQ.
+*
+               CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
+     $                      WORK( VT+ST1 ), N )
+               CALL DLASDQ( 'U', 0, NSIZE, NSIZE, 0, NRHS, D( ST ),
+     $                      E( ST ), WORK( VT+ST1 ), N, WORK( NWORK ),
+     $                      N, B( ST, 1 ), LDB, WORK( NWORK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+               CALL DLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,
+     $                      WORK( BX+ST1 ), N )
+            ELSE
+*
+*              A large problem. Solve it using divide and conquer.
+*
+               CALL DLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),
+     $                      E( ST ), WORK( U+ST1 ), N, WORK( VT+ST1 ),
+     $                      IWORK( K+ST1 ), WORK( DIFL+ST1 ),
+     $                      WORK( DIFR+ST1 ), WORK( Z+ST1 ),
+     $                      WORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),
+     $                      IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),
+     $                      WORK( GIVNUM+ST1 ), WORK( C+ST1 ),
+     $                      WORK( S+ST1 ), WORK( NWORK ), IWORK( IWK ),
+     $                      INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+               BXST = BX + ST1
+               CALL DLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),
+     $                      LDB, WORK( BXST ), N, WORK( U+ST1 ), N,
+     $                      WORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                      WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),
+     $                      WORK( Z+ST1 ), WORK( POLES+ST1 ),
+     $                      IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                      IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),
+     $                      WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),
+     $                      IWORK( IWK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+            END IF
+            ST = I + 1
+         END IF
+   60 CONTINUE
+*
+*     Apply the singular values and treat the tiny ones as zero.
+*
+      TOL = RCND*ABS( D( IDAMAX( N, D, 1 ) ) )
+*
+      DO 70 I = 1, N
+*
+*        Some of the elements in D can be negative because 1-by-1
+*        subproblems were not solved explicitly.
+*
+         IF( ABS( D( I ) ).LE.TOL ) THEN
+            CALL DLASET( 'A', 1, NRHS, ZERO, ZERO, WORK( BX+I-1 ), N )
+         ELSE
+            RANK = RANK + 1
+            CALL DLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,
+     $                   WORK( BX+I-1 ), N, INFO )
+         END IF
+         D( I ) = ABS( D( I ) )
+   70 CONTINUE
+*
+*     Now apply back the right singular vectors.
+*
+      ICMPQ2 = 1
+      DO 80 I = 1, NSUB
+         ST = IWORK( I )
+         ST1 = ST - 1
+         NSIZE = IWORK( SIZEI+I-1 )
+         BXST = BX + ST1
+         IF( NSIZE.EQ.1 ) THEN
+            CALL DCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )
+         ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+            CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                  WORK( VT+ST1 ), N, WORK( BXST ), N, ZERO,
+     $                  B( ST, 1 ), LDB )
+         ELSE
+            CALL DLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,
+     $                   B( ST, 1 ), LDB, WORK( U+ST1 ), N,
+     $                   WORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                   WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),
+     $                   WORK( Z+ST1 ), WORK( POLES+ST1 ),
+     $                   IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                   IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),
+     $                   WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),
+     $                   IWORK( IWK ), INFO )
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+         END IF
+   80 CONTINUE
+*
+*     Unscale and sort the singular values.
+*
+      CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+      CALL DLASRT( 'D', N, D, INFO )
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+      RETURN
+*
+*     End of DLALSD
+*
+      END
diff --git a/libcruft/lapack/dlamc1.f b/libcruft/lapack/dlamc1.f
new file mode 100644
index 0000000..aba3dd9
--- /dev/null
+++ b/libcruft/lapack/dlamc1.f
@@ -0,0 +1,183 @@
+      SUBROUTINE DLAMC1( BETA, T, RND, IEEE1 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE1, RND
+      INTEGER            BETA, T
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMC1 determines the machine parameters given by BETA, T, RND, and
+*  IEEE1.
+*
+*  Arguments
+*  =========
+*
+*  BETA    (output) INTEGER
+*          The base of the machine.
+*
+*  T       (output) INTEGER
+*          The number of ( BETA ) digits in the mantissa.
+*
+*  RND     (output) LOGICAL
+*          Specifies whether proper rounding  ( RND = .TRUE. )  or
+*          chopping  ( RND = .FALSE. )  occurs in addition. This may not
+*          be a reliable guide to the way in which the machine performs
+*          its arithmetic.
+*
+*  IEEE1   (output) LOGICAL
+*          Specifies whether rounding appears to be done in the IEEE
+*          'round to nearest' style.
+*
+*  Further Details
+*  ===============
+*
+*  The routine is based on the routine  ENVRON  by Malcolm and
+*  incorporates suggestions by Gentleman and Marovich. See
+*
+*     Malcolm M. A. (1972) Algorithms to reveal properties of
+*        floating-point arithmetic. Comms. of the ACM, 15, 949-951.
+*
+*     Gentleman W. M. and Marovich S. B. (1974) More on algorithms
+*        that reveal properties of floating point arithmetic units.
+*        Comms. of the ACM, 17, 276-277.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            FIRST, LIEEE1, LRND
+      INTEGER            LBETA, LT
+      DOUBLE PRECISION   A, B, C, F, ONE, QTR, SAVEC, T1, T2
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3
+      EXTERNAL           DLAMC3
+*     ..
+*     .. Save statement ..
+      SAVE               FIRST, LIEEE1, LBETA, LRND, LT
+*     ..
+*     .. Data statements ..
+      DATA               FIRST / .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+      IF( FIRST ) THEN
+         ONE = 1
+*
+*        LBETA,  LIEEE1,  LT and  LRND  are the  local values  of  BETA,
+*        IEEE1, T and RND.
+*
+*        Throughout this routine  we use the function  DLAMC3  to ensure
+*        that relevant values are  stored and not held in registers,  or
+*        are not affected by optimizers.
+*
+*        Compute  a = 2.0**m  with the  smallest positive integer m such
+*        that
+*
+*           fl( a + 1.0 ) = a.
+*
+         A = 1
+         C = 1
+*
+*+       WHILE( C.EQ.ONE )LOOP
+   10    CONTINUE
+         IF( C.EQ.ONE ) THEN
+            A = 2*A
+            C = DLAMC3( A, ONE )
+            C = DLAMC3( C, -A )
+            GO TO 10
+         END IF
+*+       END WHILE
+*
+*        Now compute  b = 2.0**m  with the smallest positive integer m
+*        such that
+*
+*           fl( a + b ) .gt. a.
+*
+         B = 1
+         C = DLAMC3( A, B )
+*
+*+       WHILE( C.EQ.A )LOOP
+   20    CONTINUE
+         IF( C.EQ.A ) THEN
+            B = 2*B
+            C = DLAMC3( A, B )
+            GO TO 20
+         END IF
+*+       END WHILE
+*
+*        Now compute the base.  a and c  are neighbouring floating point
+*        numbers  in the  interval  ( beta**t, beta**( t + 1 ) )  and so
+*        their difference is beta. Adding 0.25 to c is to ensure that it
+*        is truncated to beta and not ( beta - 1 ).
+*
+         QTR = ONE / 4
+         SAVEC = C
+         C = DLAMC3( C, -A )
+         LBETA = C + QTR
+*
+*        Now determine whether rounding or chopping occurs,  by adding a
+*        bit  less  than  beta/2  and a  bit  more  than  beta/2  to  a.
+*
+         B = LBETA
+         F = DLAMC3( B / 2, -B / 100 )
+         C = DLAMC3( F, A )
+         IF( C.EQ.A ) THEN
+            LRND = .TRUE.
+         ELSE
+            LRND = .FALSE.
+         END IF
+         F = DLAMC3( B / 2, B / 100 )
+         C = DLAMC3( F, A )
+         IF( ( LRND ) .AND. ( C.EQ.A ) )
+     $      LRND = .FALSE.
+*
+*        Try and decide whether rounding is done in the  IEEE  'round to
+*        nearest' style. B/2 is half a unit in the last place of the two
+*        numbers A and SAVEC. Furthermore, A is even, i.e. has last  bit
+*        zero, and SAVEC is odd. Thus adding B/2 to A should not  change
+*        A, but adding B/2 to SAVEC should change SAVEC.
+*
+         T1 = DLAMC3( B / 2, A )
+         T2 = DLAMC3( B / 2, SAVEC )
+         LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND
+*
+*        Now find  the  mantissa, t.  It should  be the  integer part of
+*        log to the base beta of a,  however it is safer to determine  t
+*        by powering.  So we find t as the smallest positive integer for
+*        which
+*
+*           fl( beta**t + 1.0 ) = 1.0.
+*
+         LT = 0
+         A = 1
+         C = 1
+*
+*+       WHILE( C.EQ.ONE )LOOP
+   30    CONTINUE
+         IF( C.EQ.ONE ) THEN
+            LT = LT + 1
+            A = A*LBETA
+            C = DLAMC3( A, ONE )
+            C = DLAMC3( C, -A )
+            GO TO 30
+         END IF
+*+       END WHILE
+*
+      END IF
+*
+      BETA = LBETA
+      T = LT
+      RND = LRND
+      IEEE1 = LIEEE1
+      FIRST = .FALSE.
+      RETURN
+*
+*     End of DLAMC1
+*
+      END
diff --git a/libcruft/lapack/dlamc2.f b/libcruft/lapack/dlamc2.f
new file mode 100644
index 0000000..74818be
--- /dev/null
+++ b/libcruft/lapack/dlamc2.f
@@ -0,0 +1,255 @@
+      SUBROUTINE DLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            RND
+      INTEGER            BETA, EMAX, EMIN, T
+      DOUBLE PRECISION   EPS, RMAX, RMIN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMC2 determines the machine parameters specified in its argument
+*  list.
+*
+*  Arguments
+*  =========
+*
+*  BETA    (output) INTEGER
+*          The base of the machine.
+*
+*  T       (output) INTEGER
+*          The number of ( BETA ) digits in the mantissa.
+*
+*  RND     (output) LOGICAL
+*          Specifies whether proper rounding  ( RND = .TRUE. )  or
+*          chopping  ( RND = .FALSE. )  occurs in addition. This may not
+*          be a reliable guide to the way in which the machine performs
+*          its arithmetic.
+*
+*  EPS     (output) DOUBLE PRECISION
+*          The smallest positive number such that
+*
+*             fl( 1.0 - EPS ) .LT. 1.0,
+*
+*          where fl denotes the computed value.
+*
+*  EMIN    (output) INTEGER
+*          The minimum exponent before (gradual) underflow occurs.
+*
+*  RMIN    (output) DOUBLE PRECISION
+*          The smallest normalized number for the machine, given by
+*          BASE**( EMIN - 1 ), where  BASE  is the floating point value
+*          of BETA.
+*
+*  EMAX    (output) INTEGER
+*          The maximum exponent before overflow occurs.
+*
+*  RMAX    (output) DOUBLE PRECISION
+*          The largest positive number for the machine, given by
+*          BASE**EMAX * ( 1 - EPS ), where  BASE  is the floating point
+*          value of BETA.
+*
+*  Further Details
+*  ===============
+*
+*  The computation of  EPS  is based on a routine PARANOIA by
+*  W. Kahan of the University of California at Berkeley.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            FIRST, IEEE, IWARN, LIEEE1, LRND
+      INTEGER            GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,
+     $                   NGNMIN, NGPMIN
+      DOUBLE PRECISION   A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,
+     $                   SIXTH, SMALL, THIRD, TWO, ZERO
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3
+      EXTERNAL           DLAMC3
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAMC1, DLAMC4, DLAMC5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Save statement ..
+      SAVE               FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,
+     $                   LRMIN, LT
+*     ..
+*     .. Data statements ..
+      DATA               FIRST / .TRUE. / , IWARN / .FALSE. /
+*     ..
+*     .. Executable Statements ..
+*
+      IF( FIRST ) THEN
+         ZERO = 0
+         ONE = 1
+         TWO = 2
+*
+*        LBETA, LT, LRND, LEPS, LEMIN and LRMIN  are the local values of
+*        BETA, T, RND, EPS, EMIN and RMIN.
+*
+*        Throughout this routine  we use the function  DLAMC3  to ensure
+*        that relevant values are stored  and not held in registers,  or
+*        are not affected by optimizers.
+*
+*        DLAMC1 returns the parameters  LBETA, LT, LRND and LIEEE1.
+*
+         CALL DLAMC1( LBETA, LT, LRND, LIEEE1 )
+*
+*        Start to find EPS.
+*
+         B = LBETA
+         A = B**( -LT )
+         LEPS = A
+*
+*        Try some tricks to see whether or not this is the correct  EPS.
+*
+         B = TWO / 3
+         HALF = ONE / 2
+         SIXTH = DLAMC3( B, -HALF )
+         THIRD = DLAMC3( SIXTH, SIXTH )
+         B = DLAMC3( THIRD, -HALF )
+         B = DLAMC3( B, SIXTH )
+         B = ABS( B )
+         IF( B.LT.LEPS )
+     $      B = LEPS
+*
+         LEPS = 1
+*
+*+       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP
+   10    CONTINUE
+         IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN
+            LEPS = B
+            C = DLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )
+            C = DLAMC3( HALF, -C )
+            B = DLAMC3( HALF, C )
+            C = DLAMC3( HALF, -B )
+            B = DLAMC3( HALF, C )
+            GO TO 10
+         END IF
+*+       END WHILE
+*
+         IF( A.LT.LEPS )
+     $      LEPS = A
+*
+*        Computation of EPS complete.
+*
+*        Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)).
+*        Keep dividing  A by BETA until (gradual) underflow occurs. This
+*        is detected when we cannot recover the previous A.
+*
+         RBASE = ONE / LBETA
+         SMALL = ONE
+         DO 20 I = 1, 3
+            SMALL = DLAMC3( SMALL*RBASE, ZERO )
+   20    CONTINUE
+         A = DLAMC3( ONE, SMALL )
+         CALL DLAMC4( NGPMIN, ONE, LBETA )
+         CALL DLAMC4( NGNMIN, -ONE, LBETA )
+         CALL DLAMC4( GPMIN, A, LBETA )
+         CALL DLAMC4( GNMIN, -A, LBETA )
+         IEEE = .FALSE.
+*
+         IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN
+            IF( NGPMIN.EQ.GPMIN ) THEN
+               LEMIN = NGPMIN
+*            ( Non twos-complement machines, no gradual underflow;
+*              e.g.,  VAX )
+            ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN
+               LEMIN = NGPMIN - 1 + LT
+               IEEE = .TRUE.
+*            ( Non twos-complement machines, with gradual underflow;
+*              e.g., IEEE standard followers )
+            ELSE
+               LEMIN = MIN( NGPMIN, GPMIN )
+*            ( A guess; no known machine )
+               IWARN = .TRUE.
+            END IF
+*
+         ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN
+            IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN
+               LEMIN = MAX( NGPMIN, NGNMIN )
+*            ( Twos-complement machines, no gradual underflow;
+*              e.g., CYBER 205 )
+            ELSE
+               LEMIN = MIN( NGPMIN, NGNMIN )
+*            ( A guess; no known machine )
+               IWARN = .TRUE.
+            END IF
+*
+         ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.
+     $            ( GPMIN.EQ.GNMIN ) ) THEN
+            IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN
+               LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT
+*            ( Twos-complement machines with gradual underflow;
+*              no known machine )
+            ELSE
+               LEMIN = MIN( NGPMIN, NGNMIN )
+*            ( A guess; no known machine )
+               IWARN = .TRUE.
+            END IF
+*
+         ELSE
+            LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )
+*         ( A guess; no known machine )
+            IWARN = .TRUE.
+         END IF
+         FIRST = .FALSE.
+***
+* Comment out this if block if EMIN is ok
+         IF( IWARN ) THEN
+            FIRST = .TRUE.
+            WRITE( 6, FMT = 9999 )LEMIN
+         END IF
+***
+*
+*        Assume IEEE arithmetic if we found denormalised  numbers above,
+*        or if arithmetic seems to round in the  IEEE style,  determined
+*        in routine DLAMC1. A true IEEE machine should have both  things
+*        true; however, faulty machines may have one or the other.
+*
+         IEEE = IEEE .OR. LIEEE1
+*
+*        Compute  RMIN by successive division by  BETA. We could compute
+*        RMIN as BASE**( EMIN - 1 ),  but some machines underflow during
+*        this computation.
+*
+         LRMIN = 1
+         DO 30 I = 1, 1 - LEMIN
+            LRMIN = DLAMC3( LRMIN*RBASE, ZERO )
+   30    CONTINUE
+*
+*        Finally, call DLAMC5 to compute EMAX and RMAX.
+*
+         CALL DLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX )
+      END IF
+*
+      BETA = LBETA
+      T = LT
+      RND = LRND
+      EPS = LEPS
+      EMIN = LEMIN
+      RMIN = LRMIN
+      EMAX = LEMAX
+      RMAX = LRMAX
+*
+      RETURN
+*
+ 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',
+     $      '  EMIN = ', I8, /
+     $      ' If, after inspection, the value EMIN looks',
+     $      ' acceptable please comment out ',
+     $      / ' the IF block as marked within the code of routine',
+     $      ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / )
+*
+*     End of DLAMC2
+*
+      END
diff --git a/libcruft/lapack/dlamc3.f b/libcruft/lapack/dlamc3.f
new file mode 100644
index 0000000..10d909a
--- /dev/null
+++ b/libcruft/lapack/dlamc3.f
@@ -0,0 +1,35 @@
+      DOUBLE PRECISION FUNCTION DLAMC3( A, B )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   A, B
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMC3  is intended to force  A  and  B  to be stored prior to doing
+*  the addition of  A  and  B ,  for use in situations where optimizers
+*  might hold one of these in a register.
+*
+*  Arguments
+*  =========
+*
+*  A       (input) DOUBLE PRECISION
+*  B       (input) DOUBLE PRECISION
+*          The values A and B.
+*
+* =====================================================================
+*
+*     .. Executable Statements ..
+*
+      DLAMC3 = A + B
+*
+      RETURN
+*
+*     End of DLAMC3
+*
+      END
diff --git a/libcruft/lapack/dlamc4.f b/libcruft/lapack/dlamc4.f
new file mode 100644
index 0000000..15e2158
--- /dev/null
+++ b/libcruft/lapack/dlamc4.f
@@ -0,0 +1,80 @@
+      SUBROUTINE DLAMC4( EMIN, START, BASE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            BASE, EMIN
+      DOUBLE PRECISION   START
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMC4 is a service routine for DLAMC2.
+*
+*  Arguments
+*  =========
+*
+*  EMIN    (output) INTEGER 
+*          The minimum exponent before (gradual) underflow, computed by
+*          setting A = START and dividing by BASE until the previous A
+*          can not be recovered.
+*
+*  START   (input) DOUBLE PRECISION
+*          The starting point for determining EMIN.
+*
+*  BASE    (input) INTEGER
+*          The base of the machine.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I
+      DOUBLE PRECISION   A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3
+      EXTERNAL           DLAMC3
+*     ..
+*     .. Executable Statements ..
+*
+      A = START
+      ONE = 1
+      RBASE = ONE / BASE
+      ZERO = 0
+      EMIN = 1
+      B1 = DLAMC3( A*RBASE, ZERO )
+      C1 = A
+      C2 = A
+      D1 = A
+      D2 = A
+*+    WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND.
+*    $       ( D1.EQ.A ).AND.( D2.EQ.A )      )LOOP
+   10 CONTINUE
+      IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND.
+     $    ( D2.EQ.A ) ) THEN
+         EMIN = EMIN - 1
+         A = B1
+         B1 = DLAMC3( A / BASE, ZERO )
+         C1 = DLAMC3( B1*BASE, ZERO )
+         D1 = ZERO
+         DO 20 I = 1, BASE
+            D1 = D1 + B1
+   20    CONTINUE
+         B2 = DLAMC3( A*RBASE, ZERO )
+         C2 = DLAMC3( B2 / RBASE, ZERO )
+         D2 = ZERO
+         DO 30 I = 1, BASE
+            D2 = D2 + B2
+   30    CONTINUE
+         GO TO 10
+      END IF
+*+    END WHILE
+*
+      RETURN
+*
+*     End of DLAMC4
+*
+      END
diff --git a/libcruft/lapack/dlamc5.f b/libcruft/lapack/dlamc5.f
new file mode 100644
index 0000000..3bac9a5
--- /dev/null
+++ b/libcruft/lapack/dlamc5.f
@@ -0,0 +1,158 @@
+      SUBROUTINE DLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            BETA, EMAX, EMIN, P
+      DOUBLE PRECISION   RMAX
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMC5 attempts to compute RMAX, the largest machine floating-point
+*  number, without overflow.  It assumes that EMAX + abs(EMIN) sum
+*  approximately to a power of 2.  It will fail on machines where this
+*  assumption does not hold, for example, the Cyber 205 (EMIN = -28625,
+*  EMAX = 28718).  It will also fail if the value supplied for EMIN is
+*  too large (i.e. too close to zero), probably with overflow.
+*
+*  Arguments
+*  =========
+*
+*  BETA    (input) INTEGER
+*          The base of floating-point arithmetic.
+*
+*  P       (input) INTEGER
+*          The number of base BETA digits in the mantissa of a
+*          floating-point value.
+*
+*  EMIN    (input) INTEGER
+*          The minimum exponent before (gradual) underflow.
+*
+*  IEEE    (input) LOGICAL
+*          A logical flag specifying whether or not the arithmetic
+*          system is thought to comply with the IEEE standard.
+*
+*  EMAX    (output) INTEGER
+*          The largest exponent before overflow
+*
+*  RMAX    (output) DOUBLE PRECISION
+*          The largest machine floating-point number.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP
+      DOUBLE PRECISION   OLDY, RECBAS, Y, Z
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3
+      EXTERNAL           DLAMC3
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MOD
+*     ..
+*     .. Executable Statements ..
+*
+*     First compute LEXP and UEXP, two powers of 2 that bound
+*     abs(EMIN). We then assume that EMAX + abs(EMIN) will sum
+*     approximately to the bound that is closest to abs(EMIN).
+*     (EMAX is the exponent of the required number RMAX).
+*
+      LEXP = 1
+      EXBITS = 1
+   10 CONTINUE
+      TRY = LEXP*2
+      IF( TRY.LE.( -EMIN ) ) THEN
+         LEXP = TRY
+         EXBITS = EXBITS + 1
+         GO TO 10
+      END IF
+      IF( LEXP.EQ.-EMIN ) THEN
+         UEXP = LEXP
+      ELSE
+         UEXP = TRY
+         EXBITS = EXBITS + 1
+      END IF
+*
+*     Now -LEXP is less than or equal to EMIN, and -UEXP is greater
+*     than or equal to EMIN. EXBITS is the number of bits needed to
+*     store the exponent.
+*
+      IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN
+         EXPSUM = 2*LEXP
+      ELSE
+         EXPSUM = 2*UEXP
+      END IF
+*
+*     EXPSUM is the exponent range, approximately equal to
+*     EMAX - EMIN + 1 .
+*
+      EMAX = EXPSUM + EMIN - 1
+      NBITS = 1 + EXBITS + P
+*
+*     NBITS is the total number of bits needed to store a
+*     floating-point number.
+*
+      IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN
+*
+*        Either there are an odd number of bits used to store a
+*        floating-point number, which is unlikely, or some bits are
+*        not used in the representation of numbers, which is possible,
+*        (e.g. Cray machines) or the mantissa has an implicit bit,
+*        (e.g. IEEE machines, Dec Vax machines), which is perhaps the
+*        most likely. We have to assume the last alternative.
+*        If this is true, then we need to reduce EMAX by one because
+*        there must be some way of representing zero in an implicit-bit
+*        system. On machines like Cray, we are reducing EMAX by one
+*        unnecessarily.
+*
+         EMAX = EMAX - 1
+      END IF
+*
+      IF( IEEE ) THEN
+*
+*        Assume we are on an IEEE machine which reserves one exponent
+*        for infinity and NaN.
+*
+         EMAX = EMAX - 1
+      END IF
+*
+*     Now create RMAX, the largest machine number, which should
+*     be equal to (1.0 - BETA**(-P)) * BETA**EMAX .
+*
+*     First compute 1.0 - BETA**(-P), being careful that the
+*     result is less than 1.0 .
+*
+      RECBAS = ONE / BETA
+      Z = BETA - ONE
+      Y = ZERO
+      DO 20 I = 1, P
+         Z = Z*RECBAS
+         IF( Y.LT.ONE )
+     $      OLDY = Y
+         Y = DLAMC3( Y, Z )
+   20 CONTINUE
+      IF( Y.GE.ONE )
+     $   Y = OLDY
+*
+*     Now multiply by BETA**EMAX to get RMAX.
+*
+      DO 30 I = 1, EMAX
+         Y = DLAMC3( Y*BETA, ZERO )
+   30 CONTINUE
+*
+      RMAX = Y
+      RETURN
+*
+*     End of DLAMC5
+*
+      END
diff --git a/libcruft/lapack/dlamch.f b/libcruft/lapack/dlamch.f
new file mode 100644
index 0000000..087f415
--- /dev/null
+++ b/libcruft/lapack/dlamch.f
@@ -0,0 +1,126 @@
+      DOUBLE PRECISION FUNCTION DLAMCH( CMACH )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          CMACH
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMCH determines double precision machine parameters.
+*
+*  Arguments
+*  =========
+*
+*  CMACH   (input) CHARACTER*1
+*          Specifies the value to be returned by DLAMCH:
+*          = 'E' or 'e',   DLAMCH := eps
+*          = 'S' or 's ,   DLAMCH := sfmin
+*          = 'B' or 'b',   DLAMCH := base
+*          = 'P' or 'p',   DLAMCH := eps*base
+*          = 'N' or 'n',   DLAMCH := t
+*          = 'R' or 'r',   DLAMCH := rnd
+*          = 'M' or 'm',   DLAMCH := emin
+*          = 'U' or 'u',   DLAMCH := rmin
+*          = 'L' or 'l',   DLAMCH := emax
+*          = 'O' or 'o',   DLAMCH := rmax
+*
+*          where
+*
+*          eps   = relative machine precision
+*          sfmin = safe minimum, such that 1/sfmin does not overflow
+*          base  = base of the machine
+*          prec  = eps*base
+*          t     = number of (base) digits in the mantissa
+*          rnd   = 1.0 when rounding occurs in addition, 0.0 otherwise
+*          emin  = minimum exponent before (gradual) underflow
+*          rmin  = underflow threshold - base**(emin-1)
+*          emax  = largest exponent before overflow
+*          rmax  = overflow threshold  - (base**emax)*(1-eps)
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            FIRST, LRND
+      INTEGER            BETA, IMAX, IMIN, IT
+      DOUBLE PRECISION   BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN,
+     $                   RND, SFMIN, SMALL, T
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAMC2
+*     ..
+*     .. Save statement ..
+      SAVE               FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN,
+     $                   EMAX, RMAX, PREC
+*     ..
+*     .. Data statements ..
+      DATA               FIRST / .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+      IF( FIRST ) THEN
+         CALL DLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX )
+         BASE = BETA
+         T = IT
+         IF( LRND ) THEN
+            RND = ONE
+            EPS = ( BASE**( 1-IT ) ) / 2
+         ELSE
+            RND = ZERO
+            EPS = BASE**( 1-IT )
+         END IF
+         PREC = EPS*BASE
+         EMIN = IMIN
+         EMAX = IMAX
+         SFMIN = RMIN
+         SMALL = ONE / RMAX
+         IF( SMALL.GE.SFMIN ) THEN
+*
+*           Use SMALL plus a bit, to avoid the possibility of rounding
+*           causing overflow when computing  1/sfmin.
+*
+            SFMIN = SMALL*( ONE+EPS )
+         END IF
+      END IF
+*
+      IF( LSAME( CMACH, 'E' ) ) THEN
+         RMACH = EPS
+      ELSE IF( LSAME( CMACH, 'S' ) ) THEN
+         RMACH = SFMIN
+      ELSE IF( LSAME( CMACH, 'B' ) ) THEN
+         RMACH = BASE
+      ELSE IF( LSAME( CMACH, 'P' ) ) THEN
+         RMACH = PREC
+      ELSE IF( LSAME( CMACH, 'N' ) ) THEN
+         RMACH = T
+      ELSE IF( LSAME( CMACH, 'R' ) ) THEN
+         RMACH = RND
+      ELSE IF( LSAME( CMACH, 'M' ) ) THEN
+         RMACH = EMIN
+      ELSE IF( LSAME( CMACH, 'U' ) ) THEN
+         RMACH = RMIN
+      ELSE IF( LSAME( CMACH, 'L' ) ) THEN
+         RMACH = EMAX
+      ELSE IF( LSAME( CMACH, 'O' ) ) THEN
+         RMACH = RMAX
+      END IF
+*
+      DLAMCH = RMACH
+      FIRST  = .FALSE.
+      RETURN
+*
+*     End of DLAMCH
+*
+      END
diff --git a/libcruft/lapack/dlamrg.f b/libcruft/lapack/dlamrg.f
new file mode 100644
index 0000000..db2bd4b
--- /dev/null
+++ b/libcruft/lapack/dlamrg.f
@@ -0,0 +1,103 @@
+      SUBROUTINE DLAMRG( N1, N2, A, DTRD1, DTRD2, INDEX )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            DTRD1, DTRD2, N1, N2
+*     ..
+*     .. Array Arguments ..
+      INTEGER            INDEX( * )
+      DOUBLE PRECISION   A( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAMRG will create a permutation list which will merge the elements
+*  of A (which is composed of two independently sorted sets) into a
+*  single set which is sorted in ascending order.
+*
+*  Arguments
+*  =========
+*
+*  N1     (input) INTEGER
+*  N2     (input) INTEGER
+*         These arguements contain the respective lengths of the two
+*         sorted lists to be merged.
+*
+*  A      (input) DOUBLE PRECISION array, dimension (N1+N2)
+*         The first N1 elements of A contain a list of numbers which
+*         are sorted in either ascending or descending order.  Likewise
+*         for the final N2 elements.
+*
+*  DTRD1  (input) INTEGER
+*  DTRD2  (input) INTEGER
+*         These are the strides to be taken through the array A.
+*         Allowable strides are 1 and -1.  They indicate whether a
+*         subset of A is sorted in ascending (DTRDx = 1) or descending
+*         (DTRDx = -1) order.
+*
+*  INDEX  (output) INTEGER array, dimension (N1+N2)
+*         On exit this array will contain a permutation such that
+*         if B( I ) = A( INDEX( I ) ) for I=1,N1+N2, then B will be
+*         sorted in ascending order.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IND1, IND2, N1SV, N2SV
+*     ..
+*     .. Executable Statements ..
+*
+      N1SV = N1
+      N2SV = N2
+      IF( DTRD1.GT.0 ) THEN
+         IND1 = 1
+      ELSE
+         IND1 = N1
+      END IF
+      IF( DTRD2.GT.0 ) THEN
+         IND2 = 1 + N1
+      ELSE
+         IND2 = N1 + N2
+      END IF
+      I = 1
+*     while ( (N1SV > 0) & (N2SV > 0) )
+   10 CONTINUE
+      IF( N1SV.GT.0 .AND. N2SV.GT.0 ) THEN
+         IF( A( IND1 ).LE.A( IND2 ) ) THEN
+            INDEX( I ) = IND1
+            I = I + 1
+            IND1 = IND1 + DTRD1
+            N1SV = N1SV - 1
+         ELSE
+            INDEX( I ) = IND2
+            I = I + 1
+            IND2 = IND2 + DTRD2
+            N2SV = N2SV - 1
+         END IF
+         GO TO 10
+      END IF
+*     end while
+      IF( N1SV.EQ.0 ) THEN
+         DO 20 N1SV = 1, N2SV
+            INDEX( I ) = IND2
+            I = I + 1
+            IND2 = IND2 + DTRD2
+   20    CONTINUE
+      ELSE
+*     N2SV .EQ. 0
+         DO 30 N2SV = 1, N1SV
+            INDEX( I ) = IND1
+            I = I + 1
+            IND1 = IND1 + DTRD1
+   30    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DLAMRG
+*
+      END
diff --git a/libcruft/lapack/dlange.f b/libcruft/lapack/dlange.f
new file mode 100644
index 0000000..fec96ac
--- /dev/null
+++ b/libcruft/lapack/dlange.f
@@ -0,0 +1,144 @@
+      DOUBLE PRECISION FUNCTION DLANGE( NORM, M, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLANGE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  real matrix A.
+*
+*  Description
+*  ===========
+*
+*  DLANGE returns the value
+*
+*     DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in DLANGE as described
+*          above.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.  When M = 0,
+*          DLANGE is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.  When N = 0,
+*          DLANGE is set to zero.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The m by n matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, M
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, M
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, M
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, M
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL DLASSQ( M, A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      DLANGE = VALUE
+      RETURN
+*
+*     End of DLANGE
+*
+      END
diff --git a/libcruft/lapack/dlanhs.f b/libcruft/lapack/dlanhs.f
new file mode 100644
index 0000000..76b87ee
--- /dev/null
+++ b/libcruft/lapack/dlanhs.f
@@ -0,0 +1,141 @@
+      DOUBLE PRECISION FUNCTION DLANHS( NORM, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLANHS  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  Hessenberg matrix A.
+*
+*  Description
+*  ===========
+*
+*  DLANHS returns the value
+*
+*     DLANHS = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in DLANHS as described
+*          above.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, DLANHS is
+*          set to zero.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The n by n upper Hessenberg matrix A; the part of A below the
+*          first sub-diagonal is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( N, J+1 )
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, MIN( N, J+1 )
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, N
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( N, J+1 )
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, N
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL DLASSQ( MIN( N, J+1 ), A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      DLANHS = VALUE
+      RETURN
+*
+*     End of DLANHS
+*
+      END
diff --git a/libcruft/lapack/dlanst.f b/libcruft/lapack/dlanst.f
new file mode 100644
index 0000000..2b12091
--- /dev/null
+++ b/libcruft/lapack/dlanst.f
@@ -0,0 +1,124 @@
+      DOUBLE PRECISION FUNCTION DLANST( NORM, N, D, E )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLANST  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  real symmetric tridiagonal matrix A.
+*
+*  Description
+*  ===========
+*
+*  DLANST returns the value
+*
+*     DLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in DLANST as described
+*          above.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, DLANST is
+*          set to zero.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The diagonal elements of A.
+*
+*  E       (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) sub-diagonal or super-diagonal elements of A.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      DOUBLE PRECISION   ANORM, SCALE, SUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 ) THEN
+         ANORM = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         ANORM = ABS( D( N ) )
+         DO 10 I = 1, N - 1
+            ANORM = MAX( ANORM, ABS( D( I ) ) )
+            ANORM = MAX( ANORM, ABS( E( I ) ) )
+   10    CONTINUE
+      ELSE IF( LSAME( NORM, 'O' ) .OR. NORM.EQ.'1' .OR.
+     $         LSAME( NORM, 'I' ) ) THEN
+*
+*        Find norm1(A).
+*
+         IF( N.EQ.1 ) THEN
+            ANORM = ABS( D( 1 ) )
+         ELSE
+            ANORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),
+     $              ABS( E( N-1 ) )+ABS( D( N ) ) )
+            DO 20 I = 2, N - 1
+               ANORM = MAX( ANORM, ABS( D( I ) )+ABS( E( I ) )+
+     $                 ABS( E( I-1 ) ) )
+   20       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         IF( N.GT.1 ) THEN
+            CALL DLASSQ( N-1, E, 1, SCALE, SUM )
+            SUM = 2*SUM
+         END IF
+         CALL DLASSQ( N, D, 1, SCALE, SUM )
+         ANORM = SCALE*SQRT( SUM )
+      END IF
+*
+      DLANST = ANORM
+      RETURN
+*
+*     End of DLANST
+*
+      END
diff --git a/libcruft/lapack/dlansy.f b/libcruft/lapack/dlansy.f
new file mode 100644
index 0000000..b6c727c
--- /dev/null
+++ b/libcruft/lapack/dlansy.f
@@ -0,0 +1,173 @@
+      DOUBLE PRECISION FUNCTION DLANSY( NORM, UPLO, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM, UPLO
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLANSY  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  real symmetric matrix A.
+*
+*  Description
+*  ===========
+*
+*  DLANSY returns the value
+*
+*     DLANSY = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in DLANSY as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is to be referenced.
+*          = 'U':  Upper triangular part of A is referenced
+*          = 'L':  Lower triangular part of A is referenced
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, DLANSY is
+*          set to zero.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The symmetric matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of A contains the upper triangular part
+*          of the matrix A, and the strictly lower triangular part of A
+*          is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of A contains the lower triangular part of
+*          the matrix A, and the strictly upper triangular part of A is
+*          not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,
+*          WORK is not referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   ABSA, SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 20 J = 1, N
+               DO 10 I = 1, J
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10          CONTINUE
+   20       CONTINUE
+         ELSE
+            DO 40 J = 1, N
+               DO 30 I = J, N
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30          CONTINUE
+   40       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.
+     $         ( NORM.EQ.'1' ) ) THEN
+*
+*        Find normI(A) ( = norm1(A), since A is symmetric).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 60 J = 1, N
+               SUM = ZERO
+               DO 50 I = 1, J - 1
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   50          CONTINUE
+               WORK( J ) = SUM + ABS( A( J, J ) )
+   60       CONTINUE
+            DO 70 I = 1, N
+               VALUE = MAX( VALUE, WORK( I ) )
+   70       CONTINUE
+         ELSE
+            DO 80 I = 1, N
+               WORK( I ) = ZERO
+   80       CONTINUE
+            DO 100 J = 1, N
+               SUM = WORK( J ) + ABS( A( J, J ) )
+               DO 90 I = J + 1, N
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   90          CONTINUE
+               VALUE = MAX( VALUE, SUM )
+  100       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 2, N
+               CALL DLASSQ( J-1, A( 1, J ), 1, SCALE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 120 J = 1, N - 1
+               CALL DLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM )
+  120       CONTINUE
+         END IF
+         SUM = 2*SUM
+         CALL DLASSQ( N, A, LDA+1, SCALE, SUM )
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      DLANSY = VALUE
+      RETURN
+*
+*     End of DLANSY
+*
+      END
diff --git a/libcruft/lapack/dlantr.f b/libcruft/lapack/dlantr.f
new file mode 100644
index 0000000..92debd3
--- /dev/null
+++ b/libcruft/lapack/dlantr.f
@@ -0,0 +1,276 @@
+      DOUBLE PRECISION FUNCTION DLANTR( NORM, UPLO, DIAG, M, N, A, LDA,
+     $                 WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLANTR  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  trapezoidal or triangular matrix A.
+*
+*  Description
+*  ===========
+*
+*  DLANTR returns the value
+*
+*     DLANTR = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in DLANTR as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower trapezoidal.
+*          = 'U':  Upper trapezoidal
+*          = 'L':  Lower trapezoidal
+*          Note that A is triangular instead of trapezoidal if M = N.
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A has unit diagonal.
+*          = 'N':  Non-unit diagonal
+*          = 'U':  Unit diagonal
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0, and if
+*          UPLO = 'U', M <= N.  When M = 0, DLANTR is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0, and if
+*          UPLO = 'L', N <= M.  When N = 0, DLANTR is set to zero.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The trapezoidal matrix A (A is triangular if M = N).
+*          If UPLO = 'U', the leading m by n upper trapezoidal part of
+*          the array A contains the upper trapezoidal matrix, and the
+*          strictly lower triangular part of A is not referenced.
+*          If UPLO = 'L', the leading m by n lower trapezoidal part of
+*          the array A contains the lower trapezoidal matrix, and the
+*          strictly upper triangular part of A is not referenced.  Note
+*          that when DIAG = 'U', the diagonal elements of A are not
+*          referenced and are assumed to be one.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UDIAG
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         IF( LSAME( DIAG, 'U' ) ) THEN
+            VALUE = ONE
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 20 J = 1, N
+                  DO 10 I = 1, MIN( M, J-1 )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40 J = 1, N
+                  DO 30 I = J + 1, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30             CONTINUE
+   40          CONTINUE
+            END IF
+         ELSE
+            VALUE = ZERO
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 60 J = 1, N
+                  DO 50 I = 1, MIN( M, J )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80 J = 1, N
+                  DO 70 I = J, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         UDIAG = LSAME( DIAG, 'U' )
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 1, N
+               IF( ( UDIAG ) .AND. ( J.LE.M ) ) THEN
+                  SUM = ONE
+                  DO 90 I = 1, J - 1
+                     SUM = SUM + ABS( A( I, J ) )
+   90             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 100 I = 1, MIN( M, J )
+                     SUM = SUM + ABS( A( I, J ) )
+  100             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 140 J = 1, N
+               IF( UDIAG ) THEN
+                  SUM = ONE
+                  DO 120 I = J + 1, M
+                     SUM = SUM + ABS( A( I, J ) )
+  120             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 130 I = J, M
+                     SUM = SUM + ABS( A( I, J ) )
+  130             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  140       CONTINUE
+         END IF
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 150 I = 1, M
+                  WORK( I ) = ONE
+  150          CONTINUE
+               DO 170 J = 1, N
+                  DO 160 I = 1, MIN( M, J-1 )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  160             CONTINUE
+  170          CONTINUE
+            ELSE
+               DO 180 I = 1, M
+                  WORK( I ) = ZERO
+  180          CONTINUE
+               DO 200 J = 1, N
+                  DO 190 I = 1, MIN( M, J )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  190             CONTINUE
+  200          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 210 I = 1, N
+                  WORK( I ) = ONE
+  210          CONTINUE
+               DO 220 I = N + 1, M
+                  WORK( I ) = ZERO
+  220          CONTINUE
+               DO 240 J = 1, N
+                  DO 230 I = J + 1, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  230             CONTINUE
+  240          CONTINUE
+            ELSE
+               DO 250 I = 1, M
+                  WORK( I ) = ZERO
+  250          CONTINUE
+               DO 270 J = 1, N
+                  DO 260 I = J, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  260             CONTINUE
+  270          CONTINUE
+            END IF
+         END IF
+         VALUE = ZERO
+         DO 280 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+  280    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 290 J = 2, N
+                  CALL DLASSQ( MIN( M, J-1 ), A( 1, J ), 1, SCALE, SUM )
+  290          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 300 J = 1, N
+                  CALL DLASSQ( MIN( M, J ), A( 1, J ), 1, SCALE, SUM )
+  300          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 310 J = 1, N
+                  CALL DLASSQ( M-J, A( MIN( M, J+1 ), J ), 1, SCALE,
+     $                         SUM )
+  310          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 320 J = 1, N
+                  CALL DLASSQ( M-J+1, A( J, J ), 1, SCALE, SUM )
+  320          CONTINUE
+            END IF
+         END IF
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      DLANTR = VALUE
+      RETURN
+*
+*     End of DLANTR
+*
+      END
diff --git a/libcruft/lapack/dlanv2.f b/libcruft/lapack/dlanv2.f
new file mode 100644
index 0000000..cef3f47
--- /dev/null
+++ b/libcruft/lapack/dlanv2.f
@@ -0,0 +1,205 @@
+      SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   A, B, C, CS, D, RT1I, RT1R, RT2I, RT2R, SN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric
+*  matrix in standard form:
+*
+*       [ A  B ] = [ CS -SN ] [ AA  BB ] [ CS  SN ]
+*       [ C  D ]   [ SN  CS ] [ CC  DD ] [-SN  CS ]
+*
+*  where either
+*  1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or
+*  2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex
+*  conjugate eigenvalues.
+*
+*  Arguments
+*  =========
+*
+*  A       (input/output) DOUBLE PRECISION
+*  B       (input/output) DOUBLE PRECISION
+*  C       (input/output) DOUBLE PRECISION
+*  D       (input/output) DOUBLE PRECISION
+*          On entry, the elements of the input matrix.
+*          On exit, they are overwritten by the elements of the
+*          standardised Schur form.
+*
+*  RT1R    (output) DOUBLE PRECISION
+*  RT1I    (output) DOUBLE PRECISION
+*  RT2R    (output) DOUBLE PRECISION
+*  RT2I    (output) DOUBLE PRECISION
+*          The real and imaginary parts of the eigenvalues. If the
+*          eigenvalues are a complex conjugate pair, RT1I > 0.
+*
+*  CS      (output) DOUBLE PRECISION
+*  SN      (output) DOUBLE PRECISION
+*          Parameters of the rotation matrix.
+*
+*  Further Details
+*  ===============
+*
+*  Modified by V. Sima, Research Institute for Informatics, Bucharest,
+*  Romania, to reduce the risk of cancellation errors,
+*  when computing real eigenvalues, and to ensure, if possible, that
+*  abs(RT1R) >= abs(RT2R).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   MULTPL
+      PARAMETER          ( MULTPL = 4.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AA, BB, BCMAX, BCMIS, CC, CS1, DD, EPS, P, SAB,
+     $                   SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLAPY2
+      EXTERNAL           DLAMCH, DLAPY2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      EPS = DLAMCH( 'P' )
+      IF( C.EQ.ZERO ) THEN
+         CS = ONE
+         SN = ZERO
+         GO TO 10
+*
+      ELSE IF( B.EQ.ZERO ) THEN
+*
+*        Swap rows and columns
+*
+         CS = ZERO
+         SN = ONE
+         TEMP = D
+         D = A
+         A = TEMP
+         B = -C
+         C = ZERO
+         GO TO 10
+      ELSE IF( ( A-D ).EQ.ZERO .AND. SIGN( ONE, B ).NE.SIGN( ONE, C ) )
+     $          THEN
+         CS = ONE
+         SN = ZERO
+         GO TO 10
+      ELSE
+*
+         TEMP = A - D
+         P = HALF*TEMP
+         BCMAX = MAX( ABS( B ), ABS( C ) )
+         BCMIS = MIN( ABS( B ), ABS( C ) )*SIGN( ONE, B )*SIGN( ONE, C )
+         SCALE = MAX( ABS( P ), BCMAX )
+         Z = ( P / SCALE )*P + ( BCMAX / SCALE )*BCMIS
+*
+*        If Z is of the order of the machine accuracy, postpone the
+*        decision on the nature of eigenvalues
+*
+         IF( Z.GE.MULTPL*EPS ) THEN
+*
+*           Real eigenvalues. Compute A and D.
+*
+            Z = P + SIGN( SQRT( SCALE )*SQRT( Z ), P )
+            A = D + Z
+            D = D - ( BCMAX / Z )*BCMIS
+*
+*           Compute B and the rotation matrix
+*
+            TAU = DLAPY2( C, Z )
+            CS = Z / TAU
+            SN = C / TAU
+            B = B - C
+            C = ZERO
+         ELSE
+*
+*           Complex eigenvalues, or real (almost) equal eigenvalues.
+*           Make diagonal elements equal.
+*
+            SIGMA = B + C
+            TAU = DLAPY2( SIGMA, TEMP )
+            CS = SQRT( HALF*( ONE+ABS( SIGMA ) / TAU ) )
+            SN = -( P / ( TAU*CS ) )*SIGN( ONE, SIGMA )
+*
+*           Compute [ AA  BB ] = [ A  B ] [ CS -SN ]
+*                   [ CC  DD ]   [ C  D ] [ SN  CS ]
+*
+            AA = A*CS + B*SN
+            BB = -A*SN + B*CS
+            CC = C*CS + D*SN
+            DD = -C*SN + D*CS
+*
+*           Compute [ A  B ] = [ CS  SN ] [ AA  BB ]
+*                   [ C  D ]   [-SN  CS ] [ CC  DD ]
+*
+            A = AA*CS + CC*SN
+            B = BB*CS + DD*SN
+            C = -AA*SN + CC*CS
+            D = -BB*SN + DD*CS
+*
+            TEMP = HALF*( A+D )
+            A = TEMP
+            D = TEMP
+*
+            IF( C.NE.ZERO ) THEN
+               IF( B.NE.ZERO ) THEN
+                  IF( SIGN( ONE, B ).EQ.SIGN( ONE, C ) ) THEN
+*
+*                    Real eigenvalues: reduce to upper triangular form
+*
+                     SAB = SQRT( ABS( B ) )
+                     SAC = SQRT( ABS( C ) )
+                     P = SIGN( SAB*SAC, C )
+                     TAU = ONE / SQRT( ABS( B+C ) )
+                     A = TEMP + P
+                     D = TEMP - P
+                     B = B - C
+                     C = ZERO
+                     CS1 = SAB*TAU
+                     SN1 = SAC*TAU
+                     TEMP = CS*CS1 - SN*SN1
+                     SN = CS*SN1 + SN*CS1
+                     CS = TEMP
+                  END IF
+               ELSE
+                  B = -C
+                  C = ZERO
+                  TEMP = CS
+                  CS = -SN
+                  SN = TEMP
+               END IF
+            END IF
+         END IF
+*
+      END IF
+*
+   10 CONTINUE
+*
+*     Store eigenvalues in (RT1R,RT1I) and (RT2R,RT2I).
+*
+      RT1R = A
+      RT2R = D
+      IF( C.EQ.ZERO ) THEN
+         RT1I = ZERO
+         RT2I = ZERO
+      ELSE
+         RT1I = SQRT( ABS( B ) )*SQRT( ABS( C ) )
+         RT2I = -RT1I
+      END IF
+      RETURN
+*
+*     End of DLANV2
+*
+      END
diff --git a/libcruft/lapack/dlapy2.f b/libcruft/lapack/dlapy2.f
new file mode 100644
index 0000000..98ef81b
--- /dev/null
+++ b/libcruft/lapack/dlapy2.f
@@ -0,0 +1,53 @@
+      DOUBLE PRECISION FUNCTION DLAPY2( X, Y )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   X, Y
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary
+*  overflow.
+*
+*  Arguments
+*  =========
+*
+*  X       (input) DOUBLE PRECISION
+*  Y       (input) DOUBLE PRECISION
+*          X and Y specify the values x and y.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   W, XABS, YABS, Z
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      XABS = ABS( X )
+      YABS = ABS( Y )
+      W = MAX( XABS, YABS )
+      Z = MIN( XABS, YABS )
+      IF( Z.EQ.ZERO ) THEN
+         DLAPY2 = W
+      ELSE
+         DLAPY2 = W*SQRT( ONE+( Z / W )**2 )
+      END IF
+      RETURN
+*
+*     End of DLAPY2
+*
+      END
diff --git a/libcruft/lapack/dlapy3.f b/libcruft/lapack/dlapy3.f
new file mode 100644
index 0000000..2b47bb4
--- /dev/null
+++ b/libcruft/lapack/dlapy3.f
@@ -0,0 +1,56 @@
+      DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   X, Y, Z
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause
+*  unnecessary overflow.
+*
+*  Arguments
+*  =========
+*
+*  X       (input) DOUBLE PRECISION
+*  Y       (input) DOUBLE PRECISION
+*  Z       (input) DOUBLE PRECISION
+*          X, Y and Z specify the values x, y and z.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   W, XABS, YABS, ZABS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      XABS = ABS( X )
+      YABS = ABS( Y )
+      ZABS = ABS( Z )
+      W = MAX( XABS, YABS, ZABS )
+      IF( W.EQ.ZERO ) THEN
+*     W can be zero for max(0,nan,0)
+*     adding all three entries together will make sure
+*     NaN will not disappear.
+         DLAPY3 =  XABS + YABS + ZABS
+      ELSE
+         DLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2+
+     $            ( ZABS / W )**2 )
+      END IF
+      RETURN
+*
+*     End of DLAPY3
+*
+      END
diff --git a/libcruft/lapack/dlaqp2.f b/libcruft/lapack/dlaqp2.f
new file mode 100644
index 0000000..5ce3b16
--- /dev/null
+++ b/libcruft/lapack/dlaqp2.f
@@ -0,0 +1,175 @@
+      SUBROUTINE DLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2,
+     $                   WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, M, N, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), VN1( * ), VN2( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAQP2 computes a QR factorization with column pivoting of
+*  the block A(OFFSET+1:M,1:N).
+*  The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of the matrix A that must be pivoted
+*          but no factorized. OFFSET >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of block A(OFFSET+1:M,1:N) is 
+*          the triangular factor obtained; the elements in block
+*          A(OFFSET+1:M,1:N) below the diagonal, together with the
+*          array TAU, represent the orthogonal matrix Q as a product of
+*          elementary reflectors. Block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MN, OFFPI, PVT
+      DOUBLE PRECISION   AII, TEMP, TEMP2, TOL3Z
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DLARFG, DSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DNRM2
+      EXTERNAL           IDAMAX, DLAMCH, DNRM2
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M-OFFSET, N )
+      TOL3Z = SQRT(DLAMCH('Epsilon'))
+*
+*     Compute factorization.
+*
+      DO 20 I = 1, MN
+*
+         OFFPI = OFFSET + I
+*
+*        Determine ith pivot column and swap if necessary.
+*
+         PVT = ( I-1 ) + IDAMAX( N-I+1, VN1( I ), 1 )
+*
+         IF( PVT.NE.I ) THEN
+            CALL DSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( I )
+            JPVT( I ) = ITEMP
+            VN1( PVT ) = VN1( I )
+            VN2( PVT ) = VN2( I )
+         END IF
+*
+*        Generate elementary reflector H(i).
+*
+         IF( OFFPI.LT.M ) THEN
+            CALL DLARFG( M-OFFPI+1, A( OFFPI, I ), A( OFFPI+1, I ), 1,
+     $                   TAU( I ) )
+         ELSE
+            CALL DLARFG( 1, A( M, I ), A( M, I ), 1, TAU( I ) )
+         END IF
+*
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i)' to A(offset+i:m,i+1:n) from the left.
+*
+            AII = A( OFFPI, I )
+            A( OFFPI, I ) = ONE
+            CALL DLARF( 'Left', M-OFFPI+1, N-I, A( OFFPI, I ), 1,
+     $                  TAU( I ), A( OFFPI, I+1 ), LDA, WORK( 1 ) )
+            A( OFFPI, I ) = AII
+         END IF
+*
+*        Update partial column norms.
+*
+         DO 10 J = I + 1, N
+            IF( VN1( J ).NE.ZERO ) THEN
+*
+*              NOTE: The following 4 lines follow from the analysis in
+*              Lapack Working Note 176.
+*
+               TEMP = ONE - ( ABS( A( OFFPI, J ) ) / VN1( J ) )**2
+               TEMP = MAX( TEMP, ZERO )
+               TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+               IF( TEMP2 .LE. TOL3Z ) THEN
+                  IF( OFFPI.LT.M ) THEN
+                     VN1( J ) = DNRM2( M-OFFPI, A( OFFPI+1, J ), 1 )
+                     VN2( J ) = VN1( J )
+                  ELSE
+                     VN1( J ) = ZERO
+                     VN2( J ) = ZERO
+                  END IF
+               ELSE
+                  VN1( J ) = VN1( J )*SQRT( TEMP )
+               END IF
+            END IF
+   10    CONTINUE
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of DLAQP2
+*
+      END
diff --git a/libcruft/lapack/dlaqps.f b/libcruft/lapack/dlaqps.f
new file mode 100644
index 0000000..94658d2
--- /dev/null
+++ b/libcruft/lapack/dlaqps.f
@@ -0,0 +1,259 @@
+      SUBROUTINE DLAQPS( M, N, OFFSET, NB, KB, A, LDA, JPVT, TAU, VN1,
+     $                   VN2, AUXV, F, LDF )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KB, LDA, LDF, M, N, NB, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * ),
+     $                   VN1( * ), VN2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAQPS computes a step of QR factorization with column pivoting
+*  of a real M-by-N matrix A by using Blas-3.  It tries to factorize
+*  NB columns from A starting from the row OFFSET+1, and updates all
+*  of the matrix with Blas-3 xGEMM.
+*
+*  In some cases, due to catastrophic cancellations, it cannot
+*  factorize NB columns.  Hence, the actual number of factorized
+*  columns is returned in KB.
+*
+*  Block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of A that have been factorized in
+*          previous steps.
+*
+*  NB      (input) INTEGER
+*          The number of columns to factorize.
+*
+*  KB      (output) INTEGER
+*          The number of columns actually factorized.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, block A(OFFSET+1:M,1:KB) is the triangular
+*          factor obtained and block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*          The rest of the matrix, block A(OFFSET+1:M,KB+1:N) has
+*          been updated.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          JPVT(I) = K <==> Column K of the full matrix A has been
+*          permuted into position I in AP.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (KB)
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  AUXV    (input/output) DOUBLE PRECISION array, dimension (NB)
+*          Auxiliar vector.
+*
+*  F       (input/output) DOUBLE PRECISION array, dimension (LDF,NB)
+*          Matrix F' = L*Y'*A.
+*
+*  LDF     (input) INTEGER
+*          The leading dimension of the array F. LDF >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            ITEMP, J, K, LASTRK, LSTICC, PVT, RK
+      DOUBLE PRECISION   AKK, TEMP, TEMP2, TOL3Z
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DGEMV, DLARFG, DSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN, NINT, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DNRM2
+      EXTERNAL           IDAMAX, DLAMCH, DNRM2
+*     ..
+*     .. Executable Statements ..
+*
+      LASTRK = MIN( M, N+OFFSET )
+      LSTICC = 0
+      K = 0
+      TOL3Z = SQRT(DLAMCH('Epsilon'))
+*
+*     Beginning of while loop.
+*
+   10 CONTINUE
+      IF( ( K.LT.NB ) .AND. ( LSTICC.EQ.0 ) ) THEN
+         K = K + 1
+         RK = OFFSET + K
+*
+*        Determine ith pivot column and swap if necessary
+*
+         PVT = ( K-1 ) + IDAMAX( N-K+1, VN1( K ), 1 )
+         IF( PVT.NE.K ) THEN
+            CALL DSWAP( M, A( 1, PVT ), 1, A( 1, K ), 1 )
+            CALL DSWAP( K-1, F( PVT, 1 ), LDF, F( K, 1 ), LDF )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( K )
+            JPVT( K ) = ITEMP
+            VN1( PVT ) = VN1( K )
+            VN2( PVT ) = VN2( K )
+         END IF
+*
+*        Apply previous Householder reflectors to column K:
+*        A(RK:M,K) := A(RK:M,K) - A(RK:M,1:K-1)*F(K,1:K-1)'.
+*
+         IF( K.GT.1 ) THEN
+            CALL DGEMV( 'No transpose', M-RK+1, K-1, -ONE, A( RK, 1 ),
+     $                  LDA, F( K, 1 ), LDF, ONE, A( RK, K ), 1 )
+         END IF
+*
+*        Generate elementary reflector H(k).
+*
+         IF( RK.LT.M ) THEN
+            CALL DLARFG( M-RK+1, A( RK, K ), A( RK+1, K ), 1, TAU( K ) )
+         ELSE
+            CALL DLARFG( 1, A( RK, K ), A( RK, K ), 1, TAU( K ) )
+         END IF
+*
+         AKK = A( RK, K )
+         A( RK, K ) = ONE
+*
+*        Compute Kth column of F:
+*
+*        Compute  F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)'*A(RK:M,K).
+*
+         IF( K.LT.N ) THEN
+            CALL DGEMV( 'Transpose', M-RK+1, N-K, TAU( K ),
+     $                  A( RK, K+1 ), LDA, A( RK, K ), 1, ZERO,
+     $                  F( K+1, K ), 1 )
+         END IF
+*
+*        Padding F(1:K,K) with zeros.
+*
+         DO 20 J = 1, K
+            F( J, K ) = ZERO
+   20    CONTINUE
+*
+*        Incremental updating of F:
+*        F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)'
+*                    *A(RK:M,K).
+*
+         IF( K.GT.1 ) THEN
+            CALL DGEMV( 'Transpose', M-RK+1, K-1, -TAU( K ), A( RK, 1 ),
+     $                  LDA, A( RK, K ), 1, ZERO, AUXV( 1 ), 1 )
+*
+            CALL DGEMV( 'No transpose', N, K-1, ONE, F( 1, 1 ), LDF,
+     $                  AUXV( 1 ), 1, ONE, F( 1, K ), 1 )
+         END IF
+*
+*        Update the current row of A:
+*        A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)'.
+*
+         IF( K.LT.N ) THEN
+            CALL DGEMV( 'No transpose', N-K, K, -ONE, F( K+1, 1 ), LDF,
+     $                  A( RK, 1 ), LDA, ONE, A( RK, K+1 ), LDA )
+         END IF
+*
+*        Update partial column norms.
+*
+         IF( RK.LT.LASTRK ) THEN
+            DO 30 J = K + 1, N
+               IF( VN1( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*
+                  TEMP = ABS( A( RK, J ) ) / VN1( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN
+                     VN2( J ) = DBLE( LSTICC )
+                     LSTICC = J
+                  ELSE
+                     VN1( J ) = VN1( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   30       CONTINUE
+         END IF
+*
+         A( RK, K ) = AKK
+*
+*        End of while loop.
+*
+         GO TO 10
+      END IF
+      KB = K
+      RK = OFFSET + KB
+*
+*     Apply the block reflector to the rest of the matrix:
+*     A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) -
+*                         A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)'.
+*
+      IF( KB.LT.MIN( N, M-OFFSET ) ) THEN
+         CALL DGEMM( 'No transpose', 'Transpose', M-RK, N-KB, KB, -ONE,
+     $               A( RK+1, 1 ), LDA, F( KB+1, 1 ), LDF, ONE,
+     $               A( RK+1, KB+1 ), LDA )
+      END IF
+*
+*     Recomputation of difficult columns.
+*
+   40 CONTINUE
+      IF( LSTICC.GT.0 ) THEN
+         ITEMP = NINT( VN2( LSTICC ) )
+         VN1( LSTICC ) = DNRM2( M-RK, A( RK+1, LSTICC ), 1 )
+*
+*        NOTE: The computation of VN1( LSTICC ) relies on the fact that 
+*        SNRM2 does not fail on vectors with norm below the value of
+*        SQRT(DLAMCH('S')) 
+*
+         VN2( LSTICC ) = VN1( LSTICC )
+         LSTICC = ITEMP
+         GO TO 40
+      END IF
+*
+      RETURN
+*
+*     End of DLAQPS
+*
+      END
diff --git a/libcruft/lapack/dlaqr0.f b/libcruft/lapack/dlaqr0.f
new file mode 100644
index 0000000..479da53
--- /dev/null
+++ b/libcruft/lapack/dlaqr0.f
@@ -0,0 +1,642 @@
+      SUBROUTINE DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), WI( * ), WORK( * ), WR( * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     DLAQR0 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**T, where T is an upper quasi-triangular matrix (the
+*     Schur form), and Z is the orthogonal matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input orthogonal
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to DGEBAL, and then passed to DGEHRD when the
+*           matrix output by DGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) DOUBLE PRECISION array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H contains
+*           the upper quasi-triangular matrix T from the Schur
+*           decomposition (the Schur form); 2-by-2 diagonal blocks
+*           (corresponding to complex conjugate pairs of eigenvalues)
+*           are returned in standard form, with H(i,i) = H(i+1,i+1)
+*           and H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and WANTT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     WR    (output) DOUBLE PRECISION array, dimension (IHI)
+*     WI    (output) DOUBLE PRECISION array, dimension (IHI)
+*           The real and imaginary parts, respectively, of the computed
+*           eigenvalues of H(ILO:IHI,ILO:IHI) are stored WR(ILO:IHI)
+*           and WI(ILO:IHI). If two eigenvalues are computed as a
+*           complex conjugate pair, they are stored in consecutive
+*           elements of WR and WI, say the i-th and (i+1)th, with
+*           WI(i) .GT. 0 and WI(i+1) .LT. 0. If WANTT is .TRUE., then
+*           the eigenvalues are stored in the same order as on the
+*           diagonal of the Schur form returned in H, with
+*           WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal
+*           block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and
+*           WI(i+1) = -WI(i).
+*
+*     ILOZ     (input) INTEGER
+*     IHIZ     (input) INTEGER
+*           Specify the rows of Z to which transformations must be
+*           applied if WANTZ is .TRUE..
+*           1 .LE. ILOZ .LE. ILO; IHI .LE. IHIZ .LE. N.
+*
+*     Z     (input/output) DOUBLE PRECISION array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) DOUBLE PRECISION array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then DLAQR0 does a workspace query.
+*           In this case, DLAQR0 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, DLAQR0 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is an orthogonal matrix.  The final
+*                value of H is upper Hessenberg and quasi-triangular
+*                in rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    DLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      DOUBLE PRECISION   WILK1, WILK2
+      PARAMETER          ( WILK1 = 0.75d0, WILK2 = -0.4375d0 )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AA, BB, CC, CS, DD, SN, SS, SWAP
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACPY, DLAHQR, DLANV2, DLAQR3, DLAQR4, DLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, INT, MAX, MIN, MOD
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use DLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to DLAQR3 ====
+*
+         CALL DLAQR3( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, WR, WI, H, LDH, N, H, LDH,
+     $                N, H, LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(DLAQR5, DLAQR3) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = DBLE( LWKOPT )
+            RETURN
+         END IF
+*
+*        ==== DLAHQR/DLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 80 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 90
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( ABS( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      ABS( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL DLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, WR, WI, H( KV, 1 ), LDH,
+     $                   NHO, H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                   WORK, LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if DLAQR3
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    DLAQR3 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, MAX( KS+1, KTOP+2 ), -2
+                     SS = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )
+                     AA = WILK1*SS + H( I, I )
+                     BB = SS
+                     CC = WILK2*SS
+                     DD = AA
+                     CALL DLANV2( AA, BB, CC, DD, WR( I-1 ), WI( I-1 ),
+     $                            WR( I ), WI( I ), CS, SN )
+   30             CONTINUE
+                  IF( KS.EQ.KTOP ) THEN
+                     WR( KS+1 ) = H( KS+1, KS+1 )
+                     WI( KS+1 ) = ZERO
+                     WR( KS ) = WR( KS+1 )
+                     WI( KS ) = WI( KS+1 )
+                  END IF
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use DLAQR4 or
+*                 .    DLAHQR on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL DLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     IF( NS.GT.NMIN ) THEN
+                        CALL DLAQR4( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, WR( KS ),
+     $                               WI( KS ), 1, 1, ZDUM, 1, WORK,
+     $                               LWORK, INF )
+                     ELSE
+                        CALL DLAHQR( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, WR( KS ),
+     $                               WI( KS ), 1, 1, ZDUM, 1, INF )
+                     END IF
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        AA = H( KBOT-1, KBOT-1 )
+                        CC = H( KBOT, KBOT-1 )
+                        BB = H( KBOT-1, KBOT )
+                        DD = H( KBOT, KBOT )
+                        CALL DLANV2( AA, BB, CC, DD, WR( KBOT-1 ),
+     $                               WI( KBOT-1 ), WR( KBOT ),
+     $                               WI( KBOT ), CS, SN )
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little)
+*                    .    Bubble sort keeps complex conjugate
+*                    .    pairs together. ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( ABS( WR( I ) )+ABS( WI( I ) ).LT.
+     $                         ABS( WR( I+1 ) )+ABS( WI( I+1 ) ) ) THEN
+                              SORTED = .false.
+*
+                              SWAP = WR( I )
+                              WR( I ) = WR( I+1 )
+                              WR( I+1 ) = SWAP
+*
+                              SWAP = WI( I )
+                              WI( I ) = WI( I+1 )
+                              WI( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+*
+*                 ==== Shuffle shifts into pairs of real shifts
+*                 .    and pairs of complex conjugate shifts
+*                 .    assuming complex conjugate shifts are
+*                 .    already adjacent to one another. (Yes,
+*                 .    they are.)  ====
+*
+                  DO 70 I = KBOT, KS + 2, -2
+                     IF( WI( I ).NE.-WI( I-1 ) ) THEN
+*
+                        SWAP = WR( I )
+                        WR( I ) = WR( I-1 )
+                        WR( I-1 ) = WR( I-2 )
+                        WR( I-2 ) = SWAP
+*
+                        SWAP = WI( I )
+                        WI( I ) = WI( I-1 )
+                        WI( I-1 ) = WI( I-2 )
+                        WI( I-2 ) = SWAP
+                     END IF
+   70             CONTINUE
+               END IF
+*
+*              ==== If there are only two shifts and both are
+*              .    real, then use only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( WI( KBOT ).EQ.ZERO ) THEN
+                     IF( ABS( WR( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                   ABS( WR( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                        WR( KBOT-1 ) = WR( KBOT )
+                     ELSE
+                        WR( KBOT ) = WR( KBOT-1 )
+                     END IF
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      WR( KS ), WI( KS ), H, LDH, ILOZ, IHIZ, Z,
+     $                      LDZ, WORK, 3, H( KU, 1 ), LDH, NVE,
+     $                      H( KWV, 1 ), LDH, NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   80    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   90    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = DBLE( LWKOPT )
+*
+*     ==== End of DLAQR0 ====
+*
+      END
diff --git a/libcruft/lapack/dlaqr1.f b/libcruft/lapack/dlaqr1.f
new file mode 100644
index 0000000..c80fe66
--- /dev/null
+++ b/libcruft/lapack/dlaqr1.f
@@ -0,0 +1,97 @@
+      SUBROUTINE DLAQR1( N, H, LDH, SR1, SI1, SR2, SI2, V )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   SI1, SI2, SR1, SR2
+      INTEGER            LDH, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), V( * )
+*     ..
+*
+*       Given a 2-by-2 or 3-by-3 matrix H, DLAQR1 sets v to a
+*       scalar multiple of the first column of the product
+*
+*       (*)  K = (H - (sr1 + i*si1)*I)*(H - (sr2 + i*si2)*I)
+*
+*       scaling to avoid overflows and most underflows. It
+*       is assumed that either
+*
+*               1) sr1 = sr2 and si1 = -si2
+*           or
+*               2) si1 = si2 = 0.
+*
+*       This is useful for starting double implicit shift bulges
+*       in the QR algorithm.
+*
+*
+*       N      (input) integer
+*              Order of the matrix H. N must be either 2 or 3.
+*
+*       H      (input) DOUBLE PRECISION array of dimension (LDH,N)
+*              The 2-by-2 or 3-by-3 matrix H in (*).
+*
+*       LDH    (input) integer
+*              The leading dimension of H as declared in
+*              the calling procedure.  LDH.GE.N
+*
+*       SR1    (input) DOUBLE PRECISION
+*       SI1    The shifts in (*).
+*       SR2
+*       SI2
+*
+*       V      (output) DOUBLE PRECISION array of dimension N
+*              A scalar multiple of the first column of the
+*              matrix K in (*).
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   H21S, H31S, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+      IF( N.EQ.2 ) THEN
+         S = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) )
+         IF( S.EQ.ZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            V( 1 ) = H21S*H( 1, 2 ) + ( H( 1, 1 )-SR1 )*
+     $               ( ( H( 1, 1 )-SR2 ) / S ) - SI1*( SI2 / S )
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 )
+         END IF
+      ELSE
+         S = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) ) +
+     $       ABS( H( 3, 1 ) )
+         IF( S.EQ.ZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+            V( 3 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            H31S = H( 3, 1 ) / S
+            V( 1 ) = ( H( 1, 1 )-SR1 )*( ( H( 1, 1 )-SR2 ) / S ) -
+     $               SI1*( SI2 / S ) + H( 1, 2 )*H21S + H( 1, 3 )*H31S
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 ) +
+     $               H( 2, 3 )*H31S
+            V( 3 ) = H31S*( H( 1, 1 )+H( 3, 3 )-SR1-SR2 ) +
+     $               H21S*H( 3, 2 )
+         END IF
+      END IF
+      END
diff --git a/libcruft/lapack/dlaqr2.f b/libcruft/lapack/dlaqr2.f
new file mode 100644
index 0000000..6ddb330
--- /dev/null
+++ b/libcruft/lapack/dlaqr2.f
@@ -0,0 +1,551 @@
+      SUBROUTINE DLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,
+     $                   LDT, NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),
+     $                   V( LDV, * ), WORK( * ), WV( LDWV, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     This subroutine is identical to DLAQR3 except that it avoids
+*     recursion by calling DLAHQR instead of DLAQR4.
+*
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an orthogonal similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an orthogonal similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the quasi-triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the orthogonal matrix Z is updated so
+*          so that the orthogonal Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the orthogonal matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) DOUBLE PRECISION array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by an orthogonal
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) DOUBLE PRECISION array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the orthogonal
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SR      (output) DOUBLE PRECISION array, dimension KBOT
+*     SI      (output) DOUBLE PRECISION array, dimension KBOT
+*          On output, the real and imaginary parts of approximate
+*          eigenvalues that may be used for shifts are stored in
+*          SR(KBOT-ND-NS+1) through SR(KBOT-ND) and
+*          SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.
+*          The real and imaginary parts of converged eigenvalues
+*          are stored in SR(KBOT-ND+1) through SR(KBOT) and
+*          SI(KBOT-ND+1) through SI(KBOT), respectively.
+*
+*     V       (workspace) DOUBLE PRECISION array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) DOUBLE PRECISION array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) DOUBLE PRECISION array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) DOUBLE PRECISION array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; DLAQR2
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,
+     $                   SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,
+     $                   KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2,
+     $                   LWKOPT
+      LOGICAL            BULGE, SORTED
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEHRD, DGEMM, DLABAD, DLACPY, DLAHQR,
+     $                   DLANV2, DLARF, DLARFG, DLASET, DORGHR, DTREXC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, INT, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to DGEHRD ====
+*
+         CALL DGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to DORGHR ====
+*
+         CALL DORGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = JW + MAX( LWK1, LWK2 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = DBLE( LWKOPT )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SR( KWTOP ) = H( KWTOP, KWTOP )
+         SI( KWTOP ) = ZERO
+         NS = 1
+         ND = 0
+         IF( ABS( S ).LE.MAX( SMLNUM, ULP*ABS( H( KWTOP, KWTOP ) ) ) )
+     $        THEN
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL DLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL DCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL DLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      CALL DLAHQR( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),
+     $             SI( KWTOP ), 1, JW, V, LDV, INFQR )
+*
+*     ==== DTREXC needs a clean margin near the diagonal ====
+*
+      DO 10 J = 1, JW - 3
+         T( J+2, J ) = ZERO
+         T( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( JW.GT.2 )
+     $   T( JW, JW-2 ) = ZERO
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+   20 CONTINUE
+      IF( ILST.LE.NS ) THEN
+         IF( NS.EQ.1 ) THEN
+            BULGE = .FALSE.
+         ELSE
+            BULGE = T( NS, NS-1 ).NE.ZERO
+         END IF
+*
+*        ==== Small spike tip test for deflation ====
+*
+         IF( .NOT.BULGE ) THEN
+*
+*           ==== Real eigenvalue ====
+*
+            FOO = ABS( T( NS, NS ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( ABS( S*V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 1
+            ELSE
+*
+*              ==== Undeflatable.   Move it up out of the way.
+*              .    (DTREXC can not fail in this case.) ====
+*
+               IFST = NS
+               CALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 1
+            END IF
+         ELSE
+*
+*           ==== Complex conjugate pair ====
+*
+            FOO = ABS( T( NS, NS ) ) + SQRT( ABS( T( NS, NS-1 ) ) )*
+     $            SQRT( ABS( T( NS-1, NS ) ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( MAX( ABS( S*V( 1, NS ) ), ABS( S*V( 1, NS-1 ) ) ).LE.
+     $          MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 2
+            ELSE
+*
+*              ==== Undflatable. Move them up out of the way.
+*              .    Fortunately, DTREXC does the right thing with
+*              .    ILST in case of a rare exchange failure. ====
+*
+               IFST = NS
+               CALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 2
+            END IF
+         END IF
+*
+*        ==== End deflation detection loop ====
+*
+         GO TO 20
+      END IF
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting diagonal blocks of T improves accuracy for
+*        .    graded matrices.  Bubble sort deals well with
+*        .    exchange failures. ====
+*
+         SORTED = .false.
+         I = NS + 1
+   30    CONTINUE
+         IF( SORTED )
+     $      GO TO 50
+         SORTED = .true.
+*
+         KEND = I - 1
+         I = INFQR + 1
+         IF( I.EQ.NS ) THEN
+            K = I + 1
+         ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+            K = I + 1
+         ELSE
+            K = I + 2
+         END IF
+   40    CONTINUE
+         IF( K.LE.KEND ) THEN
+            IF( K.EQ.I+1 ) THEN
+               EVI = ABS( T( I, I ) )
+            ELSE
+               EVI = ABS( T( I, I ) ) + SQRT( ABS( T( I+1, I ) ) )*
+     $               SQRT( ABS( T( I, I+1 ) ) )
+            END IF
+*
+            IF( K.EQ.KEND ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE IF( T( K+1, K ).EQ.ZERO ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE
+               EVK = ABS( T( K, K ) ) + SQRT( ABS( T( K+1, K ) ) )*
+     $               SQRT( ABS( T( K, K+1 ) ) )
+            END IF
+*
+            IF( EVI.GE.EVK ) THEN
+               I = K
+            ELSE
+               SORTED = .false.
+               IFST = I
+               ILST = K
+               CALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               IF( INFO.EQ.0 ) THEN
+                  I = ILST
+               ELSE
+                  I = K
+               END IF
+            END IF
+            IF( I.EQ.KEND ) THEN
+               K = I + 1
+            ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+               K = I + 1
+            ELSE
+               K = I + 2
+            END IF
+            GO TO 40
+         END IF
+         GO TO 30
+   50    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      I = JW
+   60 CONTINUE
+      IF( I.GE.INFQR+1 ) THEN
+         IF( I.EQ.INFQR+1 ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE IF( T( I, I-1 ).EQ.ZERO ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE
+            AA = T( I-1, I-1 )
+            CC = T( I, I-1 )
+            BB = T( I-1, I )
+            DD = T( I, I )
+            CALL DLANV2( AA, BB, CC, DD, SR( KWTOP+I-2 ),
+     $                   SI( KWTOP+I-2 ), SR( KWTOP+I-1 ),
+     $                   SI( KWTOP+I-1 ), CS, SN )
+            I = I - 2
+         END IF
+         GO TO 60
+      END IF
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL DCOPY( NS, V, LDV, WORK, 1 )
+            BETA = WORK( 1 )
+            CALL DLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL DLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL DLARF( 'L', NS, JW, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL DLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL DLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL DGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*V( 1, 1 )
+         CALL DLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL DCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  DORGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL DORGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL DGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL DLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 70 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL DLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   70    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 80 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL DGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL DLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   80       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 90 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL DLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   90       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = DBLE( LWKOPT )
+*
+*     ==== End of DLAQR2 ====
+*
+      END
diff --git a/libcruft/lapack/dlaqr3.f b/libcruft/lapack/dlaqr3.f
new file mode 100644
index 0000000..877b267
--- /dev/null
+++ b/libcruft/lapack/dlaqr3.f
@@ -0,0 +1,561 @@
+      SUBROUTINE DLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,
+     $                   LDT, NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),
+     $                   V( LDV, * ), WORK( * ), WV( LDWV, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an orthogonal similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an orthogonal similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the quasi-triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the orthogonal matrix Z is updated so
+*          so that the orthogonal Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the orthogonal matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) DOUBLE PRECISION array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by an orthogonal
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) DOUBLE PRECISION array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the orthogonal
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SR      (output) DOUBLE PRECISION array, dimension KBOT
+*     SI      (output) DOUBLE PRECISION array, dimension KBOT
+*          On output, the real and imaginary parts of approximate
+*          eigenvalues that may be used for shifts are stored in
+*          SR(KBOT-ND-NS+1) through SR(KBOT-ND) and
+*          SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.
+*          The real and imaginary parts of converged eigenvalues
+*          are stored in SR(KBOT-ND+1) through SR(KBOT) and
+*          SI(KBOT-ND+1) through SI(KBOT), respectively.
+*
+*     V       (workspace) DOUBLE PRECISION array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) DOUBLE PRECISION array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) DOUBLE PRECISION array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) DOUBLE PRECISION array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; DLAQR3
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,
+     $                   SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,
+     $                   KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2, LWK3,
+     $                   LWKOPT, NMIN
+      LOGICAL            BULGE, SORTED
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      INTEGER            ILAENV
+      EXTERNAL           DLAMCH, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEHRD, DGEMM, DLABAD, DLACPY, DLAHQR,
+     $                   DLANV2, DLAQR4, DLARF, DLARFG, DLASET, DORGHR,
+     $                   DTREXC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, INT, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to DGEHRD ====
+*
+         CALL DGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to DORGHR ====
+*
+         CALL DORGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to DLAQR4 ====
+*
+         CALL DLAQR4( .true., .true., JW, 1, JW, T, LDT, SR, SI, 1, JW,
+     $                V, LDV, WORK, -1, INFQR )
+         LWK3 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = MAX( JW+MAX( LWK1, LWK2 ), LWK3 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = DBLE( LWKOPT )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SR( KWTOP ) = H( KWTOP, KWTOP )
+         SI( KWTOP ) = ZERO
+         NS = 1
+         ND = 0
+         IF( ABS( S ).LE.MAX( SMLNUM, ULP*ABS( H( KWTOP, KWTOP ) ) ) )
+     $        THEN
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL DLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL DCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL DLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      NMIN = ILAENV( 12, 'DLAQR3', 'SV', JW, 1, JW, LWORK )
+      IF( JW.GT.NMIN ) THEN
+         CALL DLAQR4( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),
+     $                SI( KWTOP ), 1, JW, V, LDV, WORK, LWORK, INFQR )
+      ELSE
+         CALL DLAHQR( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),
+     $                SI( KWTOP ), 1, JW, V, LDV, INFQR )
+      END IF
+*
+*     ==== DTREXC needs a clean margin near the diagonal ====
+*
+      DO 10 J = 1, JW - 3
+         T( J+2, J ) = ZERO
+         T( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( JW.GT.2 )
+     $   T( JW, JW-2 ) = ZERO
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+   20 CONTINUE
+      IF( ILST.LE.NS ) THEN
+         IF( NS.EQ.1 ) THEN
+            BULGE = .FALSE.
+         ELSE
+            BULGE = T( NS, NS-1 ).NE.ZERO
+         END IF
+*
+*        ==== Small spike tip test for deflation ====
+*
+         IF( .NOT.BULGE ) THEN
+*
+*           ==== Real eigenvalue ====
+*
+            FOO = ABS( T( NS, NS ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( ABS( S*V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 1
+            ELSE
+*
+*              ==== Undeflatable.   Move it up out of the way.
+*              .    (DTREXC can not fail in this case.) ====
+*
+               IFST = NS
+               CALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 1
+            END IF
+         ELSE
+*
+*           ==== Complex conjugate pair ====
+*
+            FOO = ABS( T( NS, NS ) ) + SQRT( ABS( T( NS, NS-1 ) ) )*
+     $            SQRT( ABS( T( NS-1, NS ) ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( MAX( ABS( S*V( 1, NS ) ), ABS( S*V( 1, NS-1 ) ) ).LE.
+     $          MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 2
+            ELSE
+*
+*              ==== Undflatable. Move them up out of the way.
+*              .    Fortunately, DTREXC does the right thing with
+*              .    ILST in case of a rare exchange failure. ====
+*
+               IFST = NS
+               CALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 2
+            END IF
+         END IF
+*
+*        ==== End deflation detection loop ====
+*
+         GO TO 20
+      END IF
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting diagonal blocks of T improves accuracy for
+*        .    graded matrices.  Bubble sort deals well with
+*        .    exchange failures. ====
+*
+         SORTED = .false.
+         I = NS + 1
+   30    CONTINUE
+         IF( SORTED )
+     $      GO TO 50
+         SORTED = .true.
+*
+         KEND = I - 1
+         I = INFQR + 1
+         IF( I.EQ.NS ) THEN
+            K = I + 1
+         ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+            K = I + 1
+         ELSE
+            K = I + 2
+         END IF
+   40    CONTINUE
+         IF( K.LE.KEND ) THEN
+            IF( K.EQ.I+1 ) THEN
+               EVI = ABS( T( I, I ) )
+            ELSE
+               EVI = ABS( T( I, I ) ) + SQRT( ABS( T( I+1, I ) ) )*
+     $               SQRT( ABS( T( I, I+1 ) ) )
+            END IF
+*
+            IF( K.EQ.KEND ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE IF( T( K+1, K ).EQ.ZERO ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE
+               EVK = ABS( T( K, K ) ) + SQRT( ABS( T( K+1, K ) ) )*
+     $               SQRT( ABS( T( K, K+1 ) ) )
+            END IF
+*
+            IF( EVI.GE.EVK ) THEN
+               I = K
+            ELSE
+               SORTED = .false.
+               IFST = I
+               ILST = K
+               CALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               IF( INFO.EQ.0 ) THEN
+                  I = ILST
+               ELSE
+                  I = K
+               END IF
+            END IF
+            IF( I.EQ.KEND ) THEN
+               K = I + 1
+            ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+               K = I + 1
+            ELSE
+               K = I + 2
+            END IF
+            GO TO 40
+         END IF
+         GO TO 30
+   50    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      I = JW
+   60 CONTINUE
+      IF( I.GE.INFQR+1 ) THEN
+         IF( I.EQ.INFQR+1 ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE IF( T( I, I-1 ).EQ.ZERO ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE
+            AA = T( I-1, I-1 )
+            CC = T( I, I-1 )
+            BB = T( I-1, I )
+            DD = T( I, I )
+            CALL DLANV2( AA, BB, CC, DD, SR( KWTOP+I-2 ),
+     $                   SI( KWTOP+I-2 ), SR( KWTOP+I-1 ),
+     $                   SI( KWTOP+I-1 ), CS, SN )
+            I = I - 2
+         END IF
+         GO TO 60
+      END IF
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL DCOPY( NS, V, LDV, WORK, 1 )
+            BETA = WORK( 1 )
+            CALL DLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL DLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL DLARF( 'L', NS, JW, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL DLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL DLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL DGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*V( 1, 1 )
+         CALL DLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL DCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  DORGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL DORGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL DGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL DLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 70 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL DLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   70    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 80 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL DGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL DLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   80       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 90 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL DLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   90       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = DBLE( LWKOPT )
+*
+*     ==== End of DLAQR3 ====
+*
+      END
diff --git a/libcruft/lapack/dlaqr4.f b/libcruft/lapack/dlaqr4.f
new file mode 100644
index 0000000..8692e7f
--- /dev/null
+++ b/libcruft/lapack/dlaqr4.f
@@ -0,0 +1,640 @@
+      SUBROUTINE DLAQR4( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), WI( * ), WORK( * ), WR( * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     This subroutine implements one level of recursion for DLAQR0.
+*     It is a complete implementation of the small bulge multi-shift
+*     QR algorithm.  It may be called by DLAQR0 and, for large enough
+*     deflation window size, it may be called by DLAQR3.  This
+*     subroutine is identical to DLAQR0 except that it calls DLAQR2
+*     instead of DLAQR3.
+*
+*     Purpose
+*     =======
+*
+*     DLAQR4 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**T, where T is an upper quasi-triangular matrix (the
+*     Schur form), and Z is the orthogonal matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input orthogonal
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to DGEBAL, and then passed to DGEHRD when the
+*           matrix output by DGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) DOUBLE PRECISION array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H contains
+*           the upper quasi-triangular matrix T from the Schur
+*           decomposition (the Schur form); 2-by-2 diagonal blocks
+*           (corresponding to complex conjugate pairs of eigenvalues)
+*           are returned in standard form, with H(i,i) = H(i+1,i+1)
+*           and H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and WANTT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     WR    (output) DOUBLE PRECISION array, dimension (IHI)
+*     WI    (output) DOUBLE PRECISION array, dimension (IHI)
+*           The real and imaginary parts, respectively, of the computed
+*           eigenvalues of H(ILO:IHI,ILO:IHI) are stored WR(ILO:IHI)
+*           and WI(ILO:IHI). If two eigenvalues are computed as a
+*           complex conjugate pair, they are stored in consecutive
+*           elements of WR and WI, say the i-th and (i+1)th, with
+*           WI(i) .GT. 0 and WI(i+1) .LT. 0. If WANTT is .TRUE., then
+*           the eigenvalues are stored in the same order as on the
+*           diagonal of the Schur form returned in H, with
+*           WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal
+*           block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and
+*           WI(i+1) = -WI(i).
+*
+*     ILOZ     (input) INTEGER
+*     IHIZ     (input) INTEGER
+*           Specify the rows of Z to which transformations must be
+*           applied if WANTZ is .TRUE..
+*           1 .LE. ILOZ .LE. ILO; IHI .LE. IHIZ .LE. N.
+*
+*     Z     (input/output) DOUBLE PRECISION array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) DOUBLE PRECISION array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then DLAQR4 does a workspace query.
+*           In this case, DLAQR4 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, DLAQR4 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is an orthogonal matrix.  The final
+*                value of H is upper Hessenberg and quasi-triangular
+*                in rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    DLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      DOUBLE PRECISION   WILK1, WILK2
+      PARAMETER          ( WILK1 = 0.75d0, WILK2 = -0.4375d0 )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AA, BB, CC, CS, DD, SN, SS, SWAP
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACPY, DLAHQR, DLANV2, DLAQR2, DLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, INT, MAX, MIN, MOD
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use DLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to DLAQR2 ====
+*
+         CALL DLAQR2( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, WR, WI, H, LDH, N, H, LDH,
+     $                N, H, LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(DLAQR5, DLAQR2) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = DBLE( LWKOPT )
+            RETURN
+         END IF
+*
+*        ==== DLAHQR/DLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 80 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 90
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( ABS( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      ABS( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL DLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, WR, WI, H( KV, 1 ), LDH,
+     $                   NHO, H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                   WORK, LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if DLAQR2
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    DLAQR2 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, MAX( KS+1, KTOP+2 ), -2
+                     SS = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )
+                     AA = WILK1*SS + H( I, I )
+                     BB = SS
+                     CC = WILK2*SS
+                     DD = AA
+                     CALL DLANV2( AA, BB, CC, DD, WR( I-1 ), WI( I-1 ),
+     $                            WR( I ), WI( I ), CS, SN )
+   30             CONTINUE
+                  IF( KS.EQ.KTOP ) THEN
+                     WR( KS+1 ) = H( KS+1, KS+1 )
+                     WI( KS+1 ) = ZERO
+                     WR( KS ) = WR( KS+1 )
+                     WI( KS ) = WI( KS+1 )
+                  END IF
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use DLAHQR
+*                 .    on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL DLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     CALL DLAHQR( .false., .false., NS, 1, NS,
+     $                            H( KT, 1 ), LDH, WR( KS ), WI( KS ),
+     $                            1, 1, ZDUM, 1, INF )
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        AA = H( KBOT-1, KBOT-1 )
+                        CC = H( KBOT, KBOT-1 )
+                        BB = H( KBOT-1, KBOT )
+                        DD = H( KBOT, KBOT )
+                        CALL DLANV2( AA, BB, CC, DD, WR( KBOT-1 ),
+     $                               WI( KBOT-1 ), WR( KBOT ),
+     $                               WI( KBOT ), CS, SN )
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little)
+*                    .    Bubble sort keeps complex conjugate
+*                    .    pairs together. ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( ABS( WR( I ) )+ABS( WI( I ) ).LT.
+     $                         ABS( WR( I+1 ) )+ABS( WI( I+1 ) ) ) THEN
+                              SORTED = .false.
+*
+                              SWAP = WR( I )
+                              WR( I ) = WR( I+1 )
+                              WR( I+1 ) = SWAP
+*
+                              SWAP = WI( I )
+                              WI( I ) = WI( I+1 )
+                              WI( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+*
+*                 ==== Shuffle shifts into pairs of real shifts
+*                 .    and pairs of complex conjugate shifts
+*                 .    assuming complex conjugate shifts are
+*                 .    already adjacent to one another. (Yes,
+*                 .    they are.)  ====
+*
+                  DO 70 I = KBOT, KS + 2, -2
+                     IF( WI( I ).NE.-WI( I-1 ) ) THEN
+*
+                        SWAP = WR( I )
+                        WR( I ) = WR( I-1 )
+                        WR( I-1 ) = WR( I-2 )
+                        WR( I-2 ) = SWAP
+*
+                        SWAP = WI( I )
+                        WI( I ) = WI( I-1 )
+                        WI( I-1 ) = WI( I-2 )
+                        WI( I-2 ) = SWAP
+                     END IF
+   70             CONTINUE
+               END IF
+*
+*              ==== If there are only two shifts and both are
+*              .    real, then use only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( WI( KBOT ).EQ.ZERO ) THEN
+                     IF( ABS( WR( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                   ABS( WR( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                        WR( KBOT-1 ) = WR( KBOT )
+                     ELSE
+                        WR( KBOT ) = WR( KBOT-1 )
+                     END IF
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      WR( KS ), WI( KS ), H, LDH, ILOZ, IHIZ, Z,
+     $                      LDZ, WORK, 3, H( KU, 1 ), LDH, NVE,
+     $                      H( KWV, 1 ), LDH, NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   80    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   90    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = DBLE( LWKOPT )
+*
+*     ==== End of DLAQR4 ====
+*
+      END
diff --git a/libcruft/lapack/dlaqr5.f b/libcruft/lapack/dlaqr5.f
new file mode 100644
index 0000000..1785757
--- /dev/null
+++ b/libcruft/lapack/dlaqr5.f
@@ -0,0 +1,812 @@
+      SUBROUTINE DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS,
+     $                   SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,
+     $                   LDU, NV, WV, LDWV, NH, WH, LDWH )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
+     $                   LDWH, LDWV, LDZ, N, NH, NSHFTS, NV
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   H( LDH, * ), SI( * ), SR( * ), U( LDU, * ),
+     $                   V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     This auxiliary subroutine called by DLAQR0 performs a
+*     single small-bulge multi-shift QR sweep.
+*
+*      WANTT  (input) logical scalar
+*             WANTT = .true. if the quasi-triangular Schur factor
+*             is being computed.  WANTT is set to .false. otherwise.
+*
+*      WANTZ  (input) logical scalar
+*             WANTZ = .true. if the orthogonal Schur factor is being
+*             computed.  WANTZ is set to .false. otherwise.
+*
+*      KACC22 (input) integer with value 0, 1, or 2.
+*             Specifies the computation mode of far-from-diagonal
+*             orthogonal updates.
+*        = 0: DLAQR5 does not accumulate reflections and does not
+*             use matrix-matrix multiply to update far-from-diagonal
+*             matrix entries.
+*        = 1: DLAQR5 accumulates reflections and uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries.
+*        = 2: DLAQR5 accumulates reflections, uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries,
+*             and takes advantage of 2-by-2 block structure during
+*             matrix multiplies.
+*
+*      N      (input) integer scalar
+*             N is the order of the Hessenberg matrix H upon which this
+*             subroutine operates.
+*
+*      KTOP   (input) integer scalar
+*      KBOT   (input) integer scalar
+*             These are the first and last rows and columns of an
+*             isolated diagonal block upon which the QR sweep is to be
+*             applied. It is assumed without a check that
+*                       either KTOP = 1  or   H(KTOP,KTOP-1) = 0
+*             and
+*                       either KBOT = N  or   H(KBOT+1,KBOT) = 0.
+*
+*      NSHFTS (input) integer scalar
+*             NSHFTS gives the number of simultaneous shifts.  NSHFTS
+*             must be positive and even.
+*
+*      SR     (input) DOUBLE PRECISION array of size (NSHFTS)
+*      SI     (input) DOUBLE PRECISION array of size (NSHFTS)
+*             SR contains the real parts and SI contains the imaginary
+*             parts of the NSHFTS shifts of origin that define the
+*             multi-shift QR sweep.
+*
+*      H      (input/output) DOUBLE PRECISION array of size (LDH,N)
+*             On input H contains a Hessenberg matrix.  On output a
+*             multi-shift QR sweep with shifts SR(J)+i*SI(J) is applied
+*             to the isolated diagonal block in rows and columns KTOP
+*             through KBOT.
+*
+*      LDH    (input) integer scalar
+*             LDH is the leading dimension of H just as declared in the
+*             calling procedure.  LDH.GE.MAX(1,N).
+*
+*      ILOZ   (input) INTEGER
+*      IHIZ   (input) INTEGER
+*             Specify the rows of Z to which transformations must be
+*             applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N
+*
+*      Z      (input/output) DOUBLE PRECISION array of size (LDZ,IHI)
+*             If WANTZ = .TRUE., then the QR Sweep orthogonal
+*             similarity transformation is accumulated into
+*             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*             If WANTZ = .FALSE., then Z is unreferenced.
+*
+*      LDZ    (input) integer scalar
+*             LDA is the leading dimension of Z just as declared in
+*             the calling procedure. LDZ.GE.N.
+*
+*      V      (workspace) DOUBLE PRECISION array of size (LDV,NSHFTS/2)
+*
+*      LDV    (input) integer scalar
+*             LDV is the leading dimension of V as declared in the
+*             calling procedure.  LDV.GE.3.
+*
+*      U      (workspace) DOUBLE PRECISION array of size
+*             (LDU,3*NSHFTS-3)
+*
+*      LDU    (input) integer scalar
+*             LDU is the leading dimension of U just as declared in the
+*             in the calling subroutine.  LDU.GE.3*NSHFTS-3.
+*
+*      NH     (input) integer scalar
+*             NH is the number of columns in array WH available for
+*             workspace. NH.GE.1.
+*
+*      WH     (workspace) DOUBLE PRECISION array of size (LDWH,NH)
+*
+*      LDWH   (input) integer scalar
+*             Leading dimension of WH just as declared in the
+*             calling procedure.  LDWH.GE.3*NSHFTS-3.
+*
+*      NV     (input) integer scalar
+*             NV is the number of rows in WV agailable for workspace.
+*             NV.GE.1.
+*
+*      WV     (workspace) DOUBLE PRECISION array of size
+*             (LDWV,3*NSHFTS-3)
+*
+*      LDWV   (input) integer scalar
+*             LDWV is the leading dimension of WV as declared in the
+*             in the calling subroutine.  LDWV.GE.NV.
+*
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ============================================================
+*     Reference:
+*
+*     K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*     Algorithm Part I: Maintaining Well Focused Shifts, and
+*     Level 3 Performance, SIAM Journal of Matrix Analysis,
+*     volume 23, pages 929--947, 2002.
+*
+*     ============================================================
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0d0, ONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   ALPHA, BETA, H11, H12, H21, H22, REFSUM,
+     $                   SAFMAX, SAFMIN, SCL, SMLNUM, SWAP, TST1, TST2,
+     $                   ULP
+      INTEGER            I, I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN,
+     $                   JROW, JTOP, K, K1, KDU, KMS, KNZ, KRCOL, KZS,
+     $                   M, M22, MBOT, MEND, MSTART, MTOP, NBMPS, NDCOL,
+     $                   NS, NU
+      LOGICAL            ACCUM, BLK22, BMP22
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+*
+      INTRINSIC          ABS, DBLE, MAX, MIN, MOD
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   VT( 3 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DLABAD, DLACPY, DLAQR1, DLARFG, DLASET,
+     $                   DTRMM
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== If there are no shifts, then there is nothing to do. ====
+*
+      IF( NSHFTS.LT.2 )
+     $   RETURN
+*
+*     ==== If the active block is empty or 1-by-1, then there
+*     .    is nothing to do. ====
+*
+      IF( KTOP.GE.KBOT )
+     $   RETURN
+*
+*     ==== Shuffle shifts into pairs of real shifts and pairs
+*     .    of complex conjugate shifts assuming complex
+*     .    conjugate shifts are already adjacent to one
+*     .    another. ====
+*
+      DO 10 I = 1, NSHFTS - 2, 2
+         IF( SI( I ).NE.-SI( I+1 ) ) THEN
+*
+            SWAP = SR( I )
+            SR( I ) = SR( I+1 )
+            SR( I+1 ) = SR( I+2 )
+            SR( I+2 ) = SWAP
+*
+            SWAP = SI( I )
+            SI( I ) = SI( I+1 )
+            SI( I+1 ) = SI( I+2 )
+            SI( I+2 ) = SWAP
+         END IF
+   10 CONTINUE
+*
+*     ==== NSHFTS is supposed to be even, but if is odd,
+*     .    then simply reduce it by one.  The shuffle above
+*     .    ensures that the dropped shift is real and that
+*     .    the remaining shifts are paired. ====
+*
+      NS = NSHFTS - MOD( NSHFTS, 2 )
+*
+*     ==== Machine constants for deflation ====
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( N ) / ULP )
+*
+*     ==== Use accumulated reflections to update far-from-diagonal
+*     .    entries ? ====
+*
+      ACCUM = ( KACC22.EQ.1 ) .OR. ( KACC22.EQ.2 )
+*
+*     ==== If so, exploit the 2-by-2 block structure? ====
+*
+      BLK22 = ( NS.GT.2 ) .AND. ( KACC22.EQ.2 )
+*
+*     ==== clear trash ====
+*
+      IF( KTOP+2.LE.KBOT )
+     $   H( KTOP+2, KTOP ) = ZERO
+*
+*     ==== NBMPS = number of 2-shift bulges in the chain ====
+*
+      NBMPS = NS / 2
+*
+*     ==== KDU = width of slab ====
+*
+      KDU = 6*NBMPS - 3
+*
+*     ==== Create and chase chains of NBMPS bulges ====
+*
+      DO 220 INCOL = 3*( 1-NBMPS ) + KTOP - 1, KBOT - 2, 3*NBMPS - 2
+         NDCOL = INCOL + KDU
+         IF( ACCUM )
+     $      CALL DLASET( 'ALL', KDU, KDU, ZERO, ONE, U, LDU )
+*
+*        ==== Near-the-diagonal bulge chase.  The following loop
+*        .    performs the near-the-diagonal part of a small bulge
+*        .    multi-shift QR sweep.  Each 6*NBMPS-2 column diagonal
+*        .    chunk extends from column INCOL to column NDCOL
+*        .    (including both column INCOL and column NDCOL). The
+*        .    following loop chases a 3*NBMPS column long chain of
+*        .    NBMPS bulges 3*NBMPS-2 columns to the right.  (INCOL
+*        .    may be less than KTOP and and NDCOL may be greater than
+*        .    KBOT indicating phantom columns from which to chase
+*        .    bulges before they are actually introduced or to which
+*        .    to chase bulges beyond column KBOT.)  ====
+*
+         DO 150 KRCOL = INCOL, MIN( INCOL+3*NBMPS-3, KBOT-2 )
+*
+*           ==== Bulges number MTOP to MBOT are active double implicit
+*           .    shift bulges.  There may or may not also be small
+*           .    2-by-2 bulge, if there is room.  The inactive bulges
+*           .    (if any) must wait until the active bulges have moved
+*           .    down the diagonal to make room.  The phantom matrix
+*           .    paradigm described above helps keep track.  ====
+*
+            MTOP = MAX( 1, ( ( KTOP-1 )-KRCOL+2 ) / 3+1 )
+            MBOT = MIN( NBMPS, ( KBOT-KRCOL ) / 3 )
+            M22 = MBOT + 1
+            BMP22 = ( MBOT.LT.NBMPS ) .AND. ( KRCOL+3*( M22-1 ) ).EQ.
+     $              ( KBOT-2 )
+*
+*           ==== Generate reflections to chase the chain right
+*           .    one column.  (The minimum value of K is KTOP-1.) ====
+*
+            DO 20 M = MTOP, MBOT
+               K = KRCOL + 3*( M-1 )
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL DLAQR1( 3, H( KTOP, KTOP ), LDH, SR( 2*M-1 ),
+     $                         SI( 2*M-1 ), SR( 2*M ), SI( 2*M ),
+     $                         V( 1, M ) )
+                  ALPHA = V( 1, M )
+                  CALL DLARFG( 3, ALPHA, V( 2, M ), 1, V( 1, M ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M ) = H( K+2, K )
+                  V( 3, M ) = H( K+3, K )
+                  CALL DLARFG( 3, BETA, V( 2, M ), 1, V( 1, M ) )
+*
+*                 ==== A Bulge may collapse because of vigilant
+*                 .    deflation or destructive underflow.  (The
+*                 .    initial bulge is always collapsed.) Use
+*                 .    the two-small-subdiagonals trick to try
+*                 .    to get it started again. If V(2,M).NE.0 and
+*                 .    V(3,M) = H(K+3,K+1) = H(K+3,K+2) = 0, then
+*                 .    this bulge is collapsing into a zero
+*                 .    subdiagonal.  It will be restarted next
+*                 .    trip through the loop.)
+*
+                  IF( V( 1, M ).NE.ZERO .AND.
+     $                ( V( 3, M ).NE.ZERO .OR. ( H( K+3,
+     $                K+1 ).EQ.ZERO .AND. H( K+3, K+2 ).EQ.ZERO ) ) )
+     $                 THEN
+*
+*                    ==== Typical case: not collapsed (yet). ====
+*
+                     H( K+1, K ) = BETA
+                     H( K+2, K ) = ZERO
+                     H( K+3, K ) = ZERO
+                  ELSE
+*
+*                    ==== Atypical case: collapsed.  Attempt to
+*                    .    reintroduce ignoring H(K+1,K).  If the
+*                    .    fill resulting from the new reflector
+*                    .    is too large, then abandon it.
+*                    .    Otherwise, use the new one. ====
+*
+                     CALL DLAQR1( 3, H( K+1, K+1 ), LDH, SR( 2*M-1 ),
+     $                            SI( 2*M-1 ), SR( 2*M ), SI( 2*M ),
+     $                            VT )
+                     SCL = ABS( VT( 1 ) ) + ABS( VT( 2 ) ) +
+     $                     ABS( VT( 3 ) )
+                     IF( SCL.NE.ZERO ) THEN
+                        VT( 1 ) = VT( 1 ) / SCL
+                        VT( 2 ) = VT( 2 ) / SCL
+                        VT( 3 ) = VT( 3 ) / SCL
+                     END IF
+*
+*                    ==== The following is the traditional and
+*                    .    conservative two-small-subdiagonals
+*                    .    test.  ====
+*                    .
+                     IF( ABS( H( K+1, K ) )*( ABS( VT( 2 ) )+
+     $                   ABS( VT( 3 ) ) ).GT.ULP*ABS( VT( 1 ) )*
+     $                   ( ABS( H( K, K ) )+ABS( H( K+1,
+     $                   K+1 ) )+ABS( H( K+2, K+2 ) ) ) ) THEN
+*
+*                       ==== Starting a new bulge here would
+*                       .    create non-negligible fill.   If
+*                       .    the old reflector is diagonal (only
+*                       .    possible with underflows), then
+*                       .    change it to I.  Otherwise, use
+*                       .    it with trepidation. ====
+*
+                        IF( V( 2, M ).EQ.ZERO .AND. V( 3, M ).EQ.ZERO )
+     $                       THEN
+                           V( 1, M ) = ZERO
+                        ELSE
+                           H( K+1, K ) = BETA
+                           H( K+2, K ) = ZERO
+                           H( K+3, K ) = ZERO
+                        END IF
+                     ELSE
+*
+*                       ==== Stating a new bulge here would
+*                       .    create only negligible fill.
+*                       .    Replace the old reflector with
+*                       .    the new one. ====
+*
+                        ALPHA = VT( 1 )
+                        CALL DLARFG( 3, ALPHA, VT( 2 ), 1, VT( 1 ) )
+                        REFSUM = H( K+1, K ) + H( K+2, K )*VT( 2 ) +
+     $                           H( K+3, K )*VT( 3 )
+                        H( K+1, K ) = H( K+1, K ) - VT( 1 )*REFSUM
+                        H( K+2, K ) = ZERO
+                        H( K+3, K ) = ZERO
+                        V( 1, M ) = VT( 1 )
+                        V( 2, M ) = VT( 2 )
+                        V( 3, M ) = VT( 3 )
+                     END IF
+                  END IF
+               END IF
+   20       CONTINUE
+*
+*           ==== Generate a 2-by-2 reflection, if needed. ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 ) THEN
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL DLAQR1( 2, H( K+1, K+1 ), LDH, SR( 2*M22-1 ),
+     $                         SI( 2*M22-1 ), SR( 2*M22 ), SI( 2*M22 ),
+     $                         V( 1, M22 ) )
+                  BETA = V( 1, M22 )
+                  CALL DLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M22 ) = H( K+2, K )
+                  CALL DLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+                  H( K+1, K ) = BETA
+                  H( K+2, K ) = ZERO
+               END IF
+            ELSE
+*
+*              ==== Initialize V(1,M22) here to avoid possible undefined
+*              .    variable problems later. ====
+*
+               V( 1, M22 ) = ZERO
+            END IF
+*
+*           ==== Multiply H by reflections from the left ====
+*
+            IF( ACCUM ) THEN
+               JBOT = MIN( NDCOL, KBOT )
+            ELSE IF( WANTT ) THEN
+               JBOT = N
+            ELSE
+               JBOT = KBOT
+            END IF
+            DO 40 J = MAX( KTOP, KRCOL ), JBOT
+               MEND = MIN( MBOT, ( J-KRCOL+2 ) / 3 )
+               DO 30 M = MTOP, MEND
+                  K = KRCOL + 3*( M-1 )
+                  REFSUM = V( 1, M )*( H( K+1, J )+V( 2, M )*
+     $                     H( K+2, J )+V( 3, M )*H( K+3, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M )
+                  H( K+3, J ) = H( K+3, J ) - REFSUM*V( 3, M )
+   30          CONTINUE
+   40       CONTINUE
+            IF( BMP22 ) THEN
+               K = KRCOL + 3*( M22-1 )
+               DO 50 J = MAX( K+1, KTOP ), JBOT
+                  REFSUM = V( 1, M22 )*( H( K+1, J )+V( 2, M22 )*
+     $                     H( K+2, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M22 )
+   50          CONTINUE
+            END IF
+*
+*           ==== Multiply H by reflections from the right.
+*           .    Delay filling in the last row until the
+*           .    vigilant deflation check is complete. ====
+*
+            IF( ACCUM ) THEN
+               JTOP = MAX( KTOP, INCOL )
+            ELSE IF( WANTT ) THEN
+               JTOP = 1
+            ELSE
+               JTOP = KTOP
+            END IF
+            DO 90 M = MTOP, MBOT
+               IF( V( 1, M ).NE.ZERO ) THEN
+                  K = KRCOL + 3*( M-1 )
+                  DO 60 J = JTOP, MIN( KBOT, K+3 )
+                     REFSUM = V( 1, M )*( H( J, K+1 )+V( 2, M )*
+     $                        H( J, K+2 )+V( 3, M )*H( J, K+3 ) )
+                     H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                     H( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M )
+                     H( J, K+3 ) = H( J, K+3 ) - REFSUM*V( 3, M )
+   60             CONTINUE
+*
+                  IF( ACCUM ) THEN
+*
+*                    ==== Accumulate U. (If necessary, update Z later
+*                    .    with with an efficient matrix-matrix
+*                    .    multiply.) ====
+*
+                     KMS = K - INCOL
+                     DO 70 J = MAX( 1, KTOP-INCOL ), KDU
+                        REFSUM = V( 1, M )*( U( J, KMS+1 )+V( 2, M )*
+     $                           U( J, KMS+2 )+V( 3, M )*U( J, KMS+3 ) )
+                        U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                        U( J, KMS+2 ) = U( J, KMS+2 ) - REFSUM*V( 2, M )
+                        U( J, KMS+3 ) = U( J, KMS+3 ) - REFSUM*V( 3, M )
+   70                CONTINUE
+                  ELSE IF( WANTZ ) THEN
+*
+*                    ==== U is not accumulated, so update Z
+*                    .    now by multiplying by reflections
+*                    .    from the right. ====
+*
+                     DO 80 J = ILOZ, IHIZ
+                        REFSUM = V( 1, M )*( Z( J, K+1 )+V( 2, M )*
+     $                           Z( J, K+2 )+V( 3, M )*Z( J, K+3 ) )
+                        Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                        Z( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M )
+                        Z( J, K+3 ) = Z( J, K+3 ) - REFSUM*V( 3, M )
+   80                CONTINUE
+                  END IF
+               END IF
+   90       CONTINUE
+*
+*           ==== Special case: 2-by-2 reflection (if needed) ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 .AND. ( V( 1, M22 ).NE.ZERO ) ) THEN
+               DO 100 J = JTOP, MIN( KBOT, K+3 )
+                  REFSUM = V( 1, M22 )*( H( J, K+1 )+V( 2, M22 )*
+     $                     H( J, K+2 ) )
+                  H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                  H( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M22 )
+  100          CONTINUE
+*
+               IF( ACCUM ) THEN
+                  KMS = K - INCOL
+                  DO 110 J = MAX( 1, KTOP-INCOL ), KDU
+                     REFSUM = V( 1, M22 )*( U( J, KMS+1 )+V( 2, M22 )*
+     $                        U( J, KMS+2 ) )
+                     U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                     U( J, KMS+2 ) = U( J, KMS+2 ) - REFSUM*V( 2, M22 )
+  110             CONTINUE
+               ELSE IF( WANTZ ) THEN
+                  DO 120 J = ILOZ, IHIZ
+                     REFSUM = V( 1, M22 )*( Z( J, K+1 )+V( 2, M22 )*
+     $                        Z( J, K+2 ) )
+                     Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                     Z( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M22 )
+  120             CONTINUE
+               END IF
+            END IF
+*
+*           ==== Vigilant deflation check ====
+*
+            MSTART = MTOP
+            IF( KRCOL+3*( MSTART-1 ).LT.KTOP )
+     $         MSTART = MSTART + 1
+            MEND = MBOT
+            IF( BMP22 )
+     $         MEND = MEND + 1
+            IF( KRCOL.EQ.KBOT-2 )
+     $         MEND = MEND + 1
+            DO 130 M = MSTART, MEND
+               K = MIN( KBOT-1, KRCOL+3*( M-1 ) )
+*
+*              ==== The following convergence test requires that
+*              .    the tradition small-compared-to-nearby-diagonals
+*              .    criterion and the Ahues & Tisseur (LAWN 122, 1997)
+*              .    criteria both be satisfied.  The latter improves
+*              .    accuracy in some examples. Falling back on an
+*              .    alternate convergence criterion when TST1 or TST2
+*              .    is zero (as done here) is traditional but probably
+*              .    unnecessary. ====
+*
+               IF( H( K+1, K ).NE.ZERO ) THEN
+                  TST1 = ABS( H( K, K ) ) + ABS( H( K+1, K+1 ) )
+                  IF( TST1.EQ.ZERO ) THEN
+                     IF( K.GE.KTOP+1 )
+     $                  TST1 = TST1 + ABS( H( K, K-1 ) )
+                     IF( K.GE.KTOP+2 )
+     $                  TST1 = TST1 + ABS( H( K, K-2 ) )
+                     IF( K.GE.KTOP+3 )
+     $                  TST1 = TST1 + ABS( H( K, K-3 ) )
+                     IF( K.LE.KBOT-2 )
+     $                  TST1 = TST1 + ABS( H( K+2, K+1 ) )
+                     IF( K.LE.KBOT-3 )
+     $                  TST1 = TST1 + ABS( H( K+3, K+1 ) )
+                     IF( K.LE.KBOT-4 )
+     $                  TST1 = TST1 + ABS( H( K+4, K+1 ) )
+                  END IF
+                  IF( ABS( H( K+1, K ) ).LE.MAX( SMLNUM, ULP*TST1 ) )
+     $                 THEN
+                     H12 = MAX( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) )
+                     H21 = MIN( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) )
+                     H11 = MAX( ABS( H( K+1, K+1 ) ),
+     $                     ABS( H( K, K )-H( K+1, K+1 ) ) )
+                     H22 = MIN( ABS( H( K+1, K+1 ) ),
+     $                     ABS( H( K, K )-H( K+1, K+1 ) ) )
+                     SCL = H11 + H12
+                     TST2 = H22*( H11 / SCL )
+*
+                     IF( TST2.EQ.ZERO .OR. H21*( H12 / SCL ).LE.
+     $                   MAX( SMLNUM, ULP*TST2 ) )H( K+1, K ) = ZERO
+                  END IF
+               END IF
+  130       CONTINUE
+*
+*           ==== Fill in the last row of each bulge. ====
+*
+            MEND = MIN( NBMPS, ( KBOT-KRCOL-1 ) / 3 )
+            DO 140 M = MTOP, MEND
+               K = KRCOL + 3*( M-1 )
+               REFSUM = V( 1, M )*V( 3, M )*H( K+4, K+3 )
+               H( K+4, K+1 ) = -REFSUM
+               H( K+4, K+2 ) = -REFSUM*V( 2, M )
+               H( K+4, K+3 ) = H( K+4, K+3 ) - REFSUM*V( 3, M )
+  140       CONTINUE
+*
+*           ==== End of near-the-diagonal bulge chase. ====
+*
+  150    CONTINUE
+*
+*        ==== Use U (if accumulated) to update far-from-diagonal
+*        .    entries in H.  If required, use U to update Z as
+*        .    well. ====
+*
+         IF( ACCUM ) THEN
+            IF( WANTT ) THEN
+               JTOP = 1
+               JBOT = N
+            ELSE
+               JTOP = KTOP
+               JBOT = KBOT
+            END IF
+            IF( ( .NOT.BLK22 ) .OR. ( INCOL.LT.KTOP ) .OR.
+     $          ( NDCOL.GT.KBOT ) .OR. ( NS.LE.2 ) ) THEN
+*
+*              ==== Updates not exploiting the 2-by-2 block
+*              .    structure of U.  K1 and NU keep track of
+*              .    the location and size of U in the special
+*              .    cases of introducing bulges and chasing
+*              .    bulges off the bottom.  In these special
+*              .    cases and in case the number of shifts
+*              .    is NS = 2, there is no 2-by-2 block
+*              .    structure to exploit.  ====
+*
+               K1 = MAX( 1, KTOP-INCOL )
+               NU = ( KDU-MAX( 0, NDCOL-KBOT ) ) - K1 + 1
+*
+*              ==== Horizontal Multiply ====
+*
+               DO 160 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+                  CALL DGEMM( 'C', 'N', NU, JLEN, NU, ONE, U( K1, K1 ),
+     $                        LDU, H( INCOL+K1, JCOL ), LDH, ZERO, WH,
+     $                        LDWH )
+                  CALL DLACPY( 'ALL', NU, JLEN, WH, LDWH,
+     $                         H( INCOL+K1, JCOL ), LDH )
+  160          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 170 JROW = JTOP, MAX( KTOP, INCOL ) - 1, NV
+                  JLEN = MIN( NV, MAX( KTOP, INCOL )-JROW )
+                  CALL DGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                        H( JROW, INCOL+K1 ), LDH, U( K1, K1 ),
+     $                        LDU, ZERO, WV, LDWV )
+                  CALL DLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                         H( JROW, INCOL+K1 ), LDH )
+  170          CONTINUE
+*
+*              ==== Z multiply (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 180 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+                     CALL DGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                           Z( JROW, INCOL+K1 ), LDZ, U( K1, K1 ),
+     $                           LDU, ZERO, WV, LDWV )
+                     CALL DLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                            Z( JROW, INCOL+K1 ), LDZ )
+  180             CONTINUE
+               END IF
+            ELSE
+*
+*              ==== Updates exploiting U's 2-by-2 block structure.
+*              .    (I2, I4, J2, J4 are the last rows and columns
+*              .    of the blocks.) ====
+*
+               I2 = ( KDU+1 ) / 2
+               I4 = KDU
+               J2 = I4 - I2
+               J4 = KDU
+*
+*              ==== KZS and KNZ deal with the band of zeros
+*              .    along the diagonal of one of the triangular
+*              .    blocks. ====
+*
+               KZS = ( J4-J2 ) - ( NS+1 )
+               KNZ = NS + 1
+*
+*              ==== Horizontal multiply ====
+*
+               DO 190 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+*
+*                 ==== Copy bottom of H to top+KZS of scratch ====
+*                  (The first KZS rows get multiplied by zero.) ====
+*
+                  CALL DLACPY( 'ALL', KNZ, JLEN, H( INCOL+1+J2, JCOL ),
+     $                         LDH, WH( KZS+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL DLASET( 'ALL', KZS, JLEN, ZERO, ZERO, WH, LDWH )
+                  CALL DTRMM( 'L', 'U', 'C', 'N', KNZ, JLEN, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WH( KZS+1, 1 ),
+     $                        LDWH )
+*
+*                 ==== Multiply top of H by U11' ====
+*
+                  CALL DGEMM( 'C', 'N', I2, JLEN, J2, ONE, U, LDU,
+     $                        H( INCOL+1, JCOL ), LDH, ONE, WH, LDWH )
+*
+*                 ==== Copy top of H bottom of WH ====
+*
+                  CALL DLACPY( 'ALL', J2, JLEN, H( INCOL+1, JCOL ), LDH,
+     $                         WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL DTRMM( 'L', 'L', 'C', 'N', J2, JLEN, ONE,
+     $                        U( 1, I2+1 ), LDU, WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL DGEMM( 'C', 'N', I4-I2, JLEN, J4-J2, ONE,
+     $                        U( J2+1, I2+1 ), LDU,
+     $                        H( INCOL+1+J2, JCOL ), LDH, ONE,
+     $                        WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Copy it back ====
+*
+                  CALL DLACPY( 'ALL', KDU, JLEN, WH, LDWH,
+     $                         H( INCOL+1, JCOL ), LDH )
+  190          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 200 JROW = JTOP, MAX( INCOL, KTOP ) - 1, NV
+                  JLEN = MIN( NV, MAX( INCOL, KTOP )-JROW )
+*
+*                 ==== Copy right of H to scratch (the first KZS
+*                 .    columns get multiplied by zero) ====
+*
+                  CALL DLACPY( 'ALL', JLEN, KNZ, H( JROW, INCOL+1+J2 ),
+     $                         LDH, WV( 1, 1+KZS ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL DLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, LDWV )
+                  CALL DTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                        LDWV )
+*
+*                 ==== Multiply by U11 ====
+*
+                  CALL DGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                        H( JROW, INCOL+1 ), LDH, U, LDU, ONE, WV,
+     $                        LDWV )
+*
+*                 ==== Copy left of H to right of scratch ====
+*
+                  CALL DLACPY( 'ALL', JLEN, J2, H( JROW, INCOL+1 ), LDH,
+     $                         WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL DTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                        U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL DGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                        H( JROW, INCOL+1+J2 ), LDH,
+     $                        U( J2+1, I2+1 ), LDU, ONE, WV( 1, 1+I2 ),
+     $                        LDWV )
+*
+*                 ==== Copy it back ====
+*
+                  CALL DLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                         H( JROW, INCOL+1 ), LDH )
+  200          CONTINUE
+*
+*              ==== Multiply Z (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 210 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+*
+*                    ==== Copy right of Z to left of scratch (first
+*                    .     KZS columns get multiplied by zero) ====
+*
+                     CALL DLACPY( 'ALL', JLEN, KNZ,
+     $                            Z( JROW, INCOL+1+J2 ), LDZ,
+     $                            WV( 1, 1+KZS ), LDWV )
+*
+*                    ==== Multiply by U12 ====
+*
+                     CALL DLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV,
+     $                            LDWV )
+                     CALL DTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                           U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U11 ====
+*
+                     CALL DGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                           Z( JROW, INCOL+1 ), LDZ, U, LDU, ONE,
+     $                           WV, LDWV )
+*
+*                    ==== Copy left of Z to right of scratch ====
+*
+                     CALL DLACPY( 'ALL', JLEN, J2, Z( JROW, INCOL+1 ),
+     $                            LDZ, WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Multiply by U21 ====
+*
+                     CALL DTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                           U( 1, I2+1 ), LDU, WV( 1, 1+I2 ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U22 ====
+*
+                     CALL DGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                           Z( JROW, INCOL+1+J2 ), LDZ,
+     $                           U( J2+1, I2+1 ), LDU, ONE,
+     $                           WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Copy the result back to Z ====
+*
+                     CALL DLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                            Z( JROW, INCOL+1 ), LDZ )
+  210             CONTINUE
+               END IF
+            END IF
+         END IF
+  220 CONTINUE
+*
+*     ==== End of DLAQR5 ====
+*
+      END
diff --git a/libcruft/lapack/dlarf.f b/libcruft/lapack/dlarf.f
new file mode 100644
index 0000000..22edc89
--- /dev/null
+++ b/libcruft/lapack/dlarf.f
@@ -0,0 +1,115 @@
+      SUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, LDC, M, N
+      DOUBLE PRECISION   TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARF applies a real elementary reflector H to a real m by n matrix
+*  C, from either the left or the right. H is represented in the form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a real scalar and v is a real vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) DOUBLE PRECISION array, dimension
+*                     (1 + (M-1)*abs(INCV)) if SIDE = 'L'
+*                  or (1 + (N-1)*abs(INCV)) if SIDE = 'R'
+*          The vector v in the representation of H. V is not used if
+*          TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) DOUBLE PRECISION
+*          The value tau in the representation of H.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DGER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C' * v
+*
+            CALL DGEMV( 'Transpose', M, N, ONE, C, LDC, V, INCV, ZERO,
+     $                  WORK, 1 )
+*
+*           C := C - v * w'
+*
+            CALL DGER( M, N, -TAU, V, INCV, WORK, 1, C, LDC )
+         END IF
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C * v
+*
+            CALL DGEMV( 'No transpose', M, N, ONE, C, LDC, V, INCV,
+     $                  ZERO, WORK, 1 )
+*
+*           C := C - w * v'
+*
+            CALL DGER( M, N, -TAU, WORK, 1, V, INCV, C, LDC )
+         END IF
+      END IF
+      RETURN
+*
+*     End of DLARF
+*
+      END
diff --git a/libcruft/lapack/dlarfb.f b/libcruft/lapack/dlarfb.f
new file mode 100644
index 0000000..d442247
--- /dev/null
+++ b/libcruft/lapack/dlarfb.f
@@ -0,0 +1,587 @@
+      SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,
+     $                   T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARFB applies a real block reflector H or its transpose H' to a
+*  real m by n matrix C, from either the left or the right.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'T': apply H' (Transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  V       (input) DOUBLE PRECISION array, dimension
+*                                (LDV,K) if STOREV = 'C'
+*                                (LDV,M) if STOREV = 'R' and SIDE = 'L'
+*                                (LDV,N) if STOREV = 'R' and SIDE = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);
+*          if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);
+*          if STOREV = 'R', LDV >= K.
+*
+*  T       (input) DOUBLE PRECISION array, dimension (LDT,K)
+*          The triangular k by k matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDA >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEMM, DTRMM
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'T'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( STOREV, 'C' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1 )    (first K rows)
+*                     ( V2 )
+*           where  V1  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C1'
+*
+               DO 10 J = 1, K
+                  CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+   10          CONTINUE
+*
+*              W := W * V1
+*
+               CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2
+*
+                  CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K,
+     $                        ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2 * W'
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K,
+     $                        -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,
+     $                        C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 30 J = 1, K
+                  DO 20 I = 1, N
+                     C( J, I ) = C( J, I ) - WORK( I, J )
+   20             CONTINUE
+   30          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C1
+*
+               DO 40 J = 1, K
+                  CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40          CONTINUE
+*
+*              W := W * V1
+*
+               CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2
+*
+                  CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2'
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,
+     $                        C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 60 J = 1, K
+                  DO 50 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+   50             CONTINUE
+   60          CONTINUE
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1 )
+*                     ( V2 )    (last K rows)
+*           where  V2  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C2'
+*
+               DO 70 J = 1, K
+                  CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+   70          CONTINUE
+*
+*              W := W * V2
+*
+               CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1
+*
+                  CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1 * W'
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K,
+     $                        -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,
+     $                     ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 90 J = 1, K
+                  DO 80 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )
+   80             CONTINUE
+   90          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C2
+*
+               DO 100 J = 1, K
+                  CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  100          CONTINUE
+*
+*              W := W * V2
+*
+               CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1
+*
+                  CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1'
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,
+     $                     ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W
+*
+               DO 120 J = 1, K
+                  DO 110 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  110             CONTINUE
+  120          CONTINUE
+            END IF
+         END IF
+*
+      ELSE IF( LSAME( STOREV, 'R' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1  V2 )    (V1: first K columns)
+*           where  V1  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C1'
+*
+               DO 130 J = 1, K
+                  CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+  130          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2'
+*
+                  CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,
+     $                        C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,
+     $                        WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2' * W'
+*
+                  CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,
+     $                        V( 1, K+1 ), LDV, WORK, LDWORK, ONE,
+     $                        C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 150 J = 1, K
+                  DO 140 I = 1, N
+                     C( J, I ) = C( J, I ) - WORK( I, J )
+  140             CONTINUE
+  150          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C1
+*
+               DO 160 J = 1, K
+                  CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+  160          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2'
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K,
+     $                        ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2
+*
+                  CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE,
+     $                        C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 180 J = 1, K
+                  DO 170 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+  170             CONTINUE
+  180          CONTINUE
+*
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1  V2 )    (V2: last K columns)
+*           where  V2  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C2'
+*
+               DO 190 J = 1, K
+                  CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+  190          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,
+     $                     ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1'
+*
+                  CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,
+     $                        C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1' * W'
+*
+                  CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,
+     $                        V, LDV, WORK, LDWORK, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 210 J = 1, K
+                  DO 200 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )
+  200             CONTINUE
+  210          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C2
+*
+               DO 220 J = 1, K
+                  CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  220          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,
+     $                     ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1'
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1
+*
+                  CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 240 J = 1, K
+                  DO 230 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  230             CONTINUE
+  240          CONTINUE
+*
+            END IF
+*
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DLARFB
+*
+      END
diff --git a/libcruft/lapack/dlarfg.f b/libcruft/lapack/dlarfg.f
new file mode 100644
index 0000000..be98188
--- /dev/null
+++ b/libcruft/lapack/dlarfg.f
@@ -0,0 +1,137 @@
+      SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      DOUBLE PRECISION   ALPHA, TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARFG generates a real elementary reflector H of order n, such
+*  that
+*
+*        H * ( alpha ) = ( beta ),   H' * H = I.
+*            (   x   )   (   0  )
+*
+*  where alpha and beta are scalars, and x is an (n-1)-element real
+*  vector. H is represented in the form
+*
+*        H = I - tau * ( 1 ) * ( 1 v' ) ,
+*                      ( v )
+*
+*  where tau is a real scalar and v is a real (n-1)-element
+*  vector.
+*
+*  If the elements of x are all zero, then tau = 0 and H is taken to be
+*  the unit matrix.
+*
+*  Otherwise  1 <= tau <= 2.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the elementary reflector.
+*
+*  ALPHA   (input/output) DOUBLE PRECISION
+*          On entry, the value alpha.
+*          On exit, it is overwritten with the value beta.
+*
+*  X       (input/output) DOUBLE PRECISION array, dimension
+*                         (1+(N-2)*abs(INCX))
+*          On entry, the vector x.
+*          On exit, it is overwritten with the vector v.
+*
+*  INCX    (input) INTEGER
+*          The increment between elements of X. INCX > 0.
+*
+*  TAU     (output) DOUBLE PRECISION
+*          The value tau.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J, KNT
+      DOUBLE PRECISION   BETA, RSAFMN, SAFMIN, XNORM
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLAPY2, DNRM2
+      EXTERNAL           DLAMCH, DLAPY2, DNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.1 ) THEN
+         TAU = ZERO
+         RETURN
+      END IF
+*
+      XNORM = DNRM2( N-1, X, INCX )
+*
+      IF( XNORM.EQ.ZERO ) THEN
+*
+*        H  =  I
+*
+         TAU = ZERO
+      ELSE
+*
+*        general case
+*
+         BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )
+         SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' )
+         IF( ABS( BETA ).LT.SAFMIN ) THEN
+*
+*           XNORM, BETA may be inaccurate; scale X and recompute them
+*
+            RSAFMN = ONE / SAFMIN
+            KNT = 0
+   10       CONTINUE
+            KNT = KNT + 1
+            CALL DSCAL( N-1, RSAFMN, X, INCX )
+            BETA = BETA*RSAFMN
+            ALPHA = ALPHA*RSAFMN
+            IF( ABS( BETA ).LT.SAFMIN )
+     $         GO TO 10
+*
+*           New BETA is at most 1, at least SAFMIN
+*
+            XNORM = DNRM2( N-1, X, INCX )
+            BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )
+            TAU = ( BETA-ALPHA ) / BETA
+            CALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )
+*
+*           If ALPHA is subnormal, it may lose relative accuracy
+*
+            ALPHA = BETA
+            DO 20 J = 1, KNT
+               ALPHA = ALPHA*SAFMIN
+   20       CONTINUE
+         ELSE
+            TAU = ( BETA-ALPHA ) / BETA
+            CALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )
+            ALPHA = BETA
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DLARFG
+*
+      END
diff --git a/libcruft/lapack/dlarft.f b/libcruft/lapack/dlarft.f
new file mode 100644
index 0000000..2cd115f
--- /dev/null
+++ b/libcruft/lapack/dlarft.f
@@ -0,0 +1,217 @@
+      SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARFT forms the triangular factor T of a real block reflector H
+*  of order n, which is defined as a product of k elementary reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) DOUBLE PRECISION array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) DOUBLE PRECISION array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*               V = (  1       )                 V = (  1 v1 v1 v1 v1 )
+*                   ( v1  1    )                     (     1 v2 v2 v2 )
+*                   ( v1 v2  1 )                     (        1 v3 v3 )
+*                   ( v1 v2 v3 )
+*                   ( v1 v2 v3 )
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*               V = ( v1 v2 v3 )                 V = ( v1 v1  1       )
+*                   ( v1 v2 v3 )                     ( v2 v2 v2  1    )
+*                   (  1 v2 v3 )                     ( v3 v3 v3 v3  1 )
+*                   (     1 v3 )
+*                   (        1 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   VII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DTRMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( LSAME( DIRECT, 'F' ) ) THEN
+         DO 20 I = 1, K
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 10 J = 1, I
+                  T( J, I ) = ZERO
+   10          CONTINUE
+            ELSE
+*
+*              general case
+*
+               VII = V( I, I )
+               V( I, I ) = ONE
+               IF( LSAME( STOREV, 'C' ) ) THEN
+*
+*                 T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i)
+*
+                  CALL DGEMV( 'Transpose', N-I+1, I-1, -TAU( I ),
+     $                        V( I, 1 ), LDV, V( I, I ), 1, ZERO,
+     $                        T( 1, I ), 1 )
+               ELSE
+*
+*                 T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)'
+*
+                  CALL DGEMV( 'No transpose', I-1, N-I+1, -TAU( I ),
+     $                        V( 1, I ), LDV, V( I, I ), LDV, ZERO,
+     $                        T( 1, I ), 1 )
+               END IF
+               V( I, I ) = VII
+*
+*              T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)
+*
+               CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,
+     $                     LDT, T( 1, I ), 1 )
+               T( I, I ) = TAU( I )
+            END IF
+   20    CONTINUE
+      ELSE
+         DO 40 I = K, 1, -1
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 30 J = I, K
+                  T( J, I ) = ZERO
+   30          CONTINUE
+            ELSE
+*
+*              general case
+*
+               IF( I.LT.K ) THEN
+                  IF( LSAME( STOREV, 'C' ) ) THEN
+                     VII = V( N-K+I, I )
+                     V( N-K+I, I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i)
+*
+                     CALL DGEMV( 'Transpose', N-K+I, K-I, -TAU( I ),
+     $                           V( 1, I+1 ), LDV, V( 1, I ), 1, ZERO,
+     $                           T( I+1, I ), 1 )
+                     V( N-K+I, I ) = VII
+                  ELSE
+                     VII = V( I, N-K+I )
+                     V( I, N-K+I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)'
+*
+                     CALL DGEMV( 'No transpose', K-I, N-K+I, -TAU( I ),
+     $                           V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                           T( I+1, I ), 1 )
+                     V( I, N-K+I ) = VII
+                  END IF
+*
+*                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+                  CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                        T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+               END IF
+               T( I, I ) = TAU( I )
+            END IF
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DLARFT
+*
+      END
diff --git a/libcruft/lapack/dlarfx.f b/libcruft/lapack/dlarfx.f
new file mode 100644
index 0000000..cc4654e
--- /dev/null
+++ b/libcruft/lapack/dlarfx.f
@@ -0,0 +1,638 @@
+      SUBROUTINE DLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            LDC, M, N
+      DOUBLE PRECISION   TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARFX applies a real elementary reflector H to a real m by n
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a real scalar and v is a real vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix
+*
+*  This version uses inline code if H has order < 11.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) DOUBLE PRECISION array, dimension (M) if SIDE = 'L'
+*                                     or (N) if SIDE = 'R'
+*          The vector v in the representation of H.
+*
+*  TAU     (input) DOUBLE PRECISION
+*          The value tau in the representation of H.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDA >= (1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension
+*                      (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*          WORK is not referenced if H has order < 11.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J
+      DOUBLE PRECISION   SUM, T1, T10, T2, T3, T4, T5, T6, T7, T8, T9,
+     $                   V1, V10, V2, V3, V4, V5, V6, V7, V8, V9
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DGER
+*     ..
+*     .. Executable Statements ..
+*
+      IF( TAU.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C, where H has order m.
+*
+         GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,
+     $           170, 190 )M
+*
+*        Code for general M
+*
+*        w := C'*v
+*
+         CALL DGEMV( 'Transpose', M, N, ONE, C, LDC, V, 1, ZERO, WORK,
+     $               1 )
+*
+*        C := C - tau * v * w'
+*
+         CALL DGER( M, N, -TAU, V, 1, WORK, 1, C, LDC )
+         GO TO 410
+   10    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*V( 1 )
+         DO 20 J = 1, N
+            C( 1, J ) = T1*C( 1, J )
+   20    CONTINUE
+         GO TO 410
+   30    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         DO 40 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+   40    CONTINUE
+         GO TO 410
+   50    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         DO 60 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+   60    CONTINUE
+         GO TO 410
+   70    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         DO 80 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+   80    CONTINUE
+         GO TO 410
+   90    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         DO 100 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+  100    CONTINUE
+         GO TO 410
+  110    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         DO 120 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+  120    CONTINUE
+         GO TO 410
+  130    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         DO 140 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+  140    CONTINUE
+         GO TO 410
+  150    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         DO 160 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+  160    CONTINUE
+         GO TO 410
+  170    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         DO 180 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+  180    CONTINUE
+         GO TO 410
+  190    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         V10 = V( 10 )
+         T10 = TAU*V10
+         DO 200 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J ) +
+     $            V10*C( 10, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+            C( 10, J ) = C( 10, J ) - SUM*T10
+  200    CONTINUE
+         GO TO 410
+      ELSE
+*
+*        Form  C * H, where H has order n.
+*
+         GO TO ( 210, 230, 250, 270, 290, 310, 330, 350,
+     $           370, 390 )N
+*
+*        Code for general N
+*
+*        w := C * v
+*
+         CALL DGEMV( 'No transpose', M, N, ONE, C, LDC, V, 1, ZERO,
+     $               WORK, 1 )
+*
+*        C := C - tau * w * v'
+*
+         CALL DGER( M, N, -TAU, WORK, 1, V, 1, C, LDC )
+         GO TO 410
+  210    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*V( 1 )
+         DO 220 J = 1, M
+            C( J, 1 ) = T1*C( J, 1 )
+  220    CONTINUE
+         GO TO 410
+  230    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         DO 240 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+  240    CONTINUE
+         GO TO 410
+  250    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         DO 260 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+  260    CONTINUE
+         GO TO 410
+  270    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         DO 280 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+  280    CONTINUE
+         GO TO 410
+  290    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         DO 300 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+  300    CONTINUE
+         GO TO 410
+  310    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         DO 320 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+  320    CONTINUE
+         GO TO 410
+  330    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         DO 340 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+  340    CONTINUE
+         GO TO 410
+  350    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         DO 360 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+  360    CONTINUE
+         GO TO 410
+  370    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         DO 380 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+  380    CONTINUE
+         GO TO 410
+  390    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         V10 = V( 10 )
+         T10 = TAU*V10
+         DO 400 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 ) +
+     $            V10*C( J, 10 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+            C( J, 10 ) = C( J, 10 ) - SUM*T10
+  400    CONTINUE
+         GO TO 410
+      END IF
+  410 CONTINUE
+      RETURN
+*
+*     End of DLARFX
+*
+      END
diff --git a/libcruft/lapack/dlartg.f b/libcruft/lapack/dlartg.f
new file mode 100644
index 0000000..eb807c1
--- /dev/null
+++ b/libcruft/lapack/dlartg.f
@@ -0,0 +1,145 @@
+      SUBROUTINE DLARTG( F, G, CS, SN, R )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   CS, F, G, R, SN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARTG generate a plane rotation so that
+*
+*     [  CS  SN  ]  .  [ F ]  =  [ R ]   where CS**2 + SN**2 = 1.
+*     [ -SN  CS  ]     [ G ]     [ 0 ]
+*
+*  This is a slower, more accurate version of the BLAS1 routine DROTG,
+*  with the following other differences:
+*     F and G are unchanged on return.
+*     If G=0, then CS=1 and SN=0.
+*     If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any
+*        floating point operations (saves work in DBDSQR when
+*        there are zeros on the diagonal).
+*
+*  If F exceeds G in magnitude, CS will be positive.
+*
+*  Arguments
+*  =========
+*
+*  F       (input) DOUBLE PRECISION
+*          The first component of vector to be rotated.
+*
+*  G       (input) DOUBLE PRECISION
+*          The second component of vector to be rotated.
+*
+*  CS      (output) DOUBLE PRECISION
+*          The cosine of the rotation.
+*
+*  SN      (output) DOUBLE PRECISION
+*          The sine of the rotation.
+*
+*  R       (output) DOUBLE PRECISION
+*          The nonzero component of the rotated vector.
+*
+*  This version has a few statements commented out for thread safety
+*  (machine parameters are computed on each entry). 10 feb 03, SJH.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D0 )
+*     ..
+*     .. Local Scalars ..
+*     LOGICAL            FIRST
+      INTEGER            COUNT, I
+      DOUBLE PRECISION   EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, LOG, MAX, SQRT
+*     ..
+*     .. Save statement ..
+*     SAVE               FIRST, SAFMX2, SAFMIN, SAFMN2
+*     ..
+*     .. Data statements ..
+*     DATA               FIRST / .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+*     IF( FIRST ) THEN
+         SAFMIN = DLAMCH( 'S' )
+         EPS = DLAMCH( 'E' )
+         SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
+     $            LOG( DLAMCH( 'B' ) ) / TWO )
+         SAFMX2 = ONE / SAFMN2
+*        FIRST = .FALSE.
+*     END IF
+      IF( G.EQ.ZERO ) THEN
+         CS = ONE
+         SN = ZERO
+         R = F
+      ELSE IF( F.EQ.ZERO ) THEN
+         CS = ZERO
+         SN = ONE
+         R = G
+      ELSE
+         F1 = F
+         G1 = G
+         SCALE = MAX( ABS( F1 ), ABS( G1 ) )
+         IF( SCALE.GE.SAFMX2 ) THEN
+            COUNT = 0
+   10       CONTINUE
+            COUNT = COUNT + 1
+            F1 = F1*SAFMN2
+            G1 = G1*SAFMN2
+            SCALE = MAX( ABS( F1 ), ABS( G1 ) )
+            IF( SCALE.GE.SAFMX2 )
+     $         GO TO 10
+            R = SQRT( F1**2+G1**2 )
+            CS = F1 / R
+            SN = G1 / R
+            DO 20 I = 1, COUNT
+               R = R*SAFMX2
+   20       CONTINUE
+         ELSE IF( SCALE.LE.SAFMN2 ) THEN
+            COUNT = 0
+   30       CONTINUE
+            COUNT = COUNT + 1
+            F1 = F1*SAFMX2
+            G1 = G1*SAFMX2
+            SCALE = MAX( ABS( F1 ), ABS( G1 ) )
+            IF( SCALE.LE.SAFMN2 )
+     $         GO TO 30
+            R = SQRT( F1**2+G1**2 )
+            CS = F1 / R
+            SN = G1 / R
+            DO 40 I = 1, COUNT
+               R = R*SAFMN2
+   40       CONTINUE
+         ELSE
+            R = SQRT( F1**2+G1**2 )
+            CS = F1 / R
+            SN = G1 / R
+         END IF
+         IF( ABS( F ).GT.ABS( G ) .AND. CS.LT.ZERO ) THEN
+            CS = -CS
+            SN = -SN
+            R = -R
+         END IF
+      END IF
+      RETURN
+*
+*     End of DLARTG
+*
+      END
diff --git a/libcruft/lapack/dlarz.f b/libcruft/lapack/dlarz.f
new file mode 100644
index 0000000..b302fdc
--- /dev/null
+++ b/libcruft/lapack/dlarz.f
@@ -0,0 +1,152 @@
+      SUBROUTINE DLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, L, LDC, M, N
+      DOUBLE PRECISION   TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARZ applies a real elementary reflector H to a real M-by-N
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a real scalar and v is a real vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*
+*  H is a product of k elementary reflectors as returned by DTZRZF.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  L       (input) INTEGER
+*          The number of entries of the vector V containing
+*          the meaningful part of the Householder vectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) DOUBLE PRECISION array, dimension (1+(L-1)*abs(INCV))
+*          The vector v in the representation of H as returned by
+*          DTZRZF. V is not used if TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) DOUBLE PRECISION
+*          The value tau in the representation of H.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DCOPY, DGEMV, DGER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:n ) = C( 1, 1:n )
+*
+            CALL DCOPY( N, C, LDC, WORK, 1 )
+*
+*           w( 1:n ) = w( 1:n ) + C( m-l+1:m, 1:n )' * v( 1:l )
+*
+            CALL DGEMV( 'Transpose', L, N, ONE, C( M-L+1, 1 ), LDC, V,
+     $                  INCV, ONE, WORK, 1 )
+*
+*           C( 1, 1:n ) = C( 1, 1:n ) - tau * w( 1:n )
+*
+            CALL DAXPY( N, -TAU, WORK, 1, C, LDC )
+*
+*           C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                               tau * v( 1:l ) * w( 1:n )'
+*
+            CALL DGER( L, N, -TAU, V, INCV, WORK, 1, C( M-L+1, 1 ),
+     $                 LDC )
+         END IF
+*
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:m ) = C( 1:m, 1 )
+*
+            CALL DCOPY( M, C, 1, WORK, 1 )
+*
+*           w( 1:m ) = w( 1:m ) + C( 1:m, n-l+1:n, 1:n ) * v( 1:l )
+*
+            CALL DGEMV( 'No transpose', M, L, ONE, C( 1, N-L+1 ), LDC,
+     $                  V, INCV, ONE, WORK, 1 )
+*
+*           C( 1:m, 1 ) = C( 1:m, 1 ) - tau * w( 1:m )
+*
+            CALL DAXPY( M, -TAU, WORK, 1, C, 1 )
+*
+*           C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                               tau * w( 1:m ) * v( 1:l )'
+*
+            CALL DGER( M, L, -TAU, WORK, 1, V, INCV, C( 1, N-L+1 ),
+     $                 LDC )
+*
+         END IF
+*
+      END IF
+*
+      RETURN
+*
+*     End of DLARZ
+*
+      END
diff --git a/libcruft/lapack/dlarzb.f b/libcruft/lapack/dlarzb.f
new file mode 100644
index 0000000..ec59d8d
--- /dev/null
+++ b/libcruft/lapack/dlarzb.f
@@ -0,0 +1,220 @@
+      SUBROUTINE DLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,
+     $                   LDV, T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, L, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARZB applies a real block reflector H or its transpose H**T to
+*  a real distributed M-by-N  C from the left or the right.
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'C': apply H' (Transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise                        (not supported yet)
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix V containing the
+*          meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) DOUBLE PRECISION array, dimension (LDV,NV).
+*          If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.
+*
+*  T       (input) DOUBLE PRECISION array, dimension (LDT,K)
+*          The triangular K-by-K matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEMM, DTRMM, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLARZB', -INFO )
+         RETURN
+      END IF
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'T'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C  or  H' * C
+*
+*        W( 1:n, 1:k ) = C( 1:k, 1:n )'
+*
+         DO 10 J = 1, K
+            CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+   10    CONTINUE
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) + ...
+*                        C( m-l+1:m, 1:n )' * V( 1:k, 1:l )'
+*
+         IF( L.GT.0 )
+     $      CALL DGEMM( 'Transpose', 'Transpose', N, K, L, ONE,
+     $                  C( M-L+1, 1 ), LDC, V, LDV, ONE, WORK, LDWORK )
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) * T'  or  W( 1:m, 1:k ) * T
+*
+         CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+*
+*        C( 1:k, 1:n ) = C( 1:k, 1:n ) - W( 1:n, 1:k )'
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, K
+               C( I, J ) = C( I, J ) - WORK( J, I )
+   20       CONTINUE
+   30    CONTINUE
+*
+*        C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                            V( 1:k, 1:l )' * W( 1:n, 1:k )'
+*
+         IF( L.GT.0 )
+     $      CALL DGEMM( 'Transpose', 'Transpose', L, N, K, -ONE, V, LDV,
+     $                  WORK, LDWORK, ONE, C( M-L+1, 1 ), LDC )
+*
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form  C * H  or  C * H'
+*
+*        W( 1:m, 1:k ) = C( 1:m, 1:k )
+*
+         DO 40 J = 1, K
+            CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40    CONTINUE
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) + ...
+*                        C( 1:m, n-l+1:n ) * V( 1:k, 1:l )'
+*
+         IF( L.GT.0 )
+     $      CALL DGEMM( 'No transpose', 'Transpose', M, K, L, ONE,
+     $                  C( 1, N-L+1 ), LDC, V, LDV, ONE, WORK, LDWORK )
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) * T  or  W( 1:m, 1:k ) * T'
+*
+         CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+*
+*        C( 1:m, 1:k ) = C( 1:m, 1:k ) - W( 1:m, 1:k )
+*
+         DO 60 J = 1, K
+            DO 50 I = 1, M
+               C( I, J ) = C( I, J ) - WORK( I, J )
+   50       CONTINUE
+   60    CONTINUE
+*
+*        C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                            W( 1:m, 1:k ) * V( 1:k, 1:l )
+*
+         IF( L.GT.0 )
+     $      CALL DGEMM( 'No transpose', 'No transpose', M, L, K, -ONE,
+     $                  WORK, LDWORK, V, LDV, ONE, C( 1, N-L+1 ), LDC )
+*
+      END IF
+*
+      RETURN
+*
+*     End of DLARZB
+*
+      END
diff --git a/libcruft/lapack/dlarzt.f b/libcruft/lapack/dlarzt.f
new file mode 100644
index 0000000..d79636e
--- /dev/null
+++ b/libcruft/lapack/dlarzt.f
@@ -0,0 +1,184 @@
+      SUBROUTINE DLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLARZT forms the triangular factor T of a real block reflector
+*  H of order > n, which is defined as a product of k elementary
+*  reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise                        (not supported yet)
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) DOUBLE PRECISION array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) DOUBLE PRECISION array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*                                              ______V_____
+*         ( v1 v2 v3 )                        /            \
+*         ( v1 v2 v3 )                      ( v1 v1 v1 v1 v1 . . . . 1 )
+*     V = ( v1 v2 v3 )                      ( v2 v2 v2 v2 v2 . . . 1   )
+*         ( v1 v2 v3 )                      ( v3 v3 v3 v3 v3 . . 1     )
+*         ( v1 v2 v3 )
+*            .  .  .
+*            .  .  .
+*            1  .  .
+*               1  .
+*                  1
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*                                                        ______V_____
+*            1                                          /            \
+*            .  1                           ( 1 . . . . v1 v1 v1 v1 v1 )
+*            .  .  1                        ( . 1 . . . v2 v2 v2 v2 v2 )
+*            .  .  .                        ( . . 1 . . v3 v3 v3 v3 v3 )
+*            .  .  .
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*     V = ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DTRMV, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -2
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLARZT', -INFO )
+         RETURN
+      END IF
+*
+      DO 20 I = K, 1, -1
+         IF( TAU( I ).EQ.ZERO ) THEN
+*
+*           H(i)  =  I
+*
+            DO 10 J = I, K
+               T( J, I ) = ZERO
+   10       CONTINUE
+         ELSE
+*
+*           general case
+*
+            IF( I.LT.K ) THEN
+*
+*              T(i+1:k,i) = - tau(i) * V(i+1:k,1:n) * V(i,1:n)'
+*
+               CALL DGEMV( 'No transpose', K-I, N, -TAU( I ),
+     $                     V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                     T( I+1, I ), 1 )
+*
+*              T(i+1:k,i) = T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+               CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                     T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+            END IF
+            T( I, I ) = TAU( I )
+         END IF
+   20 CONTINUE
+      RETURN
+*
+*     End of DLARZT
+*
+      END
diff --git a/libcruft/lapack/dlas2.f b/libcruft/lapack/dlas2.f
new file mode 100644
index 0000000..e100a4d
--- /dev/null
+++ b/libcruft/lapack/dlas2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   F, G, H, SSMAX, SSMIN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAS2  computes the singular values of the 2-by-2 matrix
+*     [  F   G  ]
+*     [  0   H  ].
+*  On return, SSMIN is the smaller singular value and SSMAX is the
+*  larger singular value.
+*
+*  Arguments
+*  =========
+*
+*  F       (input) DOUBLE PRECISION
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  G       (input) DOUBLE PRECISION
+*          The (1,2) element of the 2-by-2 matrix.
+*
+*  H       (input) DOUBLE PRECISION
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  SSMIN   (output) DOUBLE PRECISION
+*          The smaller singular value.
+*
+*  SSMAX   (output) DOUBLE PRECISION
+*          The larger singular value.
+*
+*  Further Details
+*  ===============
+*
+*  Barring over/underflow, all output quantities are correct to within
+*  a few units in the last place (ulps), even in the absence of a guard
+*  digit in addition/subtraction.
+*
+*  In IEEE arithmetic, the code works correctly if one matrix element is
+*  infinite.
+*
+*  Overflow will not occur unless the largest singular value itself
+*  overflows, or is within a few ulps of overflow. (On machines with
+*  partial overflow, like the Cray, overflow may occur if the largest
+*  singular value is within a factor of 2 of overflow.)
+*
+*  Underflow is harmless if underflow is gradual. Otherwise, results
+*  may correspond to a matrix modified by perturbations of size near
+*  the underflow threshold.
+*
+*  ====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   AS, AT, AU, C, FA, FHMN, FHMX, GA, HA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      FA = ABS( F )
+      GA = ABS( G )
+      HA = ABS( H )
+      FHMN = MIN( FA, HA )
+      FHMX = MAX( FA, HA )
+      IF( FHMN.EQ.ZERO ) THEN
+         SSMIN = ZERO
+         IF( FHMX.EQ.ZERO ) THEN
+            SSMAX = GA
+         ELSE
+            SSMAX = MAX( FHMX, GA )*SQRT( ONE+
+     $              ( MIN( FHMX, GA ) / MAX( FHMX, GA ) )**2 )
+         END IF
+      ELSE
+         IF( GA.LT.FHMX ) THEN
+            AS = ONE + FHMN / FHMX
+            AT = ( FHMX-FHMN ) / FHMX
+            AU = ( GA / FHMX )**2
+            C = TWO / ( SQRT( AS*AS+AU )+SQRT( AT*AT+AU ) )
+            SSMIN = FHMN*C
+            SSMAX = FHMX / C
+         ELSE
+            AU = FHMX / GA
+            IF( AU.EQ.ZERO ) THEN
+*
+*              Avoid possible harmful underflow if exponent range
+*              asymmetric (true SSMIN may not underflow even if
+*              AU underflows)
+*
+               SSMIN = ( FHMN*FHMX ) / GA
+               SSMAX = GA
+            ELSE
+               AS = ONE + FHMN / FHMX
+               AT = ( FHMX-FHMN ) / FHMX
+               C = ONE / ( SQRT( ONE+( AS*AU )**2 )+
+     $             SQRT( ONE+( AT*AU )**2 ) )
+               SSMIN = ( FHMN*C )*AU
+               SSMIN = SSMIN + SSMIN
+               SSMAX = GA / ( C+C )
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of DLAS2
+*
+      END
diff --git a/libcruft/lapack/dlascl.f b/libcruft/lapack/dlascl.f
new file mode 100644
index 0000000..7a7a78f
--- /dev/null
+++ b/libcruft/lapack/dlascl.f
@@ -0,0 +1,267 @@
+      SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TYPE
+      INTEGER            INFO, KL, KU, LDA, M, N
+      DOUBLE PRECISION   CFROM, CTO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASCL multiplies the M by N real matrix A by the real scalar
+*  CTO/CFROM.  This is done without over/underflow as long as the final
+*  result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
+*  A may be full, upper triangular, lower triangular, upper Hessenberg,
+*  or banded.
+*
+*  Arguments
+*  =========
+*
+*  TYPE    (input) CHARACTER*1
+*          TYPE indices the storage type of the input matrix.
+*          = 'G':  A is a full matrix.
+*          = 'L':  A is a lower triangular matrix.
+*          = 'U':  A is an upper triangular matrix.
+*          = 'H':  A is an upper Hessenberg matrix.
+*          = 'B':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the lower
+*                  half stored.
+*          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the upper
+*                  half stored.
+*          = 'Z':  A is a band matrix with lower bandwidth KL and upper
+*                  bandwidth KU.
+*
+*  KL      (input) INTEGER
+*          The lower bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  KU      (input) INTEGER
+*          The upper bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  CFROM   (input) DOUBLE PRECISION
+*  CTO     (input) DOUBLE PRECISION
+*          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
+*          without over/underflow if the final result CTO*A(I,J)/CFROM
+*          can be represented without over/underflow.  CFROM must be
+*          nonzero.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
+*          storage type.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  INFO    (output) INTEGER
+*          0  - successful exit
+*          <0 - if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      INTEGER            I, ITYPE, J, K1, K2, K3, K4
+      DOUBLE PRECISION   BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+*
+      IF( LSAME( TYPE, 'G' ) ) THEN
+         ITYPE = 0
+      ELSE IF( LSAME( TYPE, 'L' ) ) THEN
+         ITYPE = 1
+      ELSE IF( LSAME( TYPE, 'U' ) ) THEN
+         ITYPE = 2
+      ELSE IF( LSAME( TYPE, 'H' ) ) THEN
+         ITYPE = 3
+      ELSE IF( LSAME( TYPE, 'B' ) ) THEN
+         ITYPE = 4
+      ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
+         ITYPE = 5
+      ELSE IF( LSAME( TYPE, 'Z' ) ) THEN
+         ITYPE = 6
+      ELSE
+         ITYPE = -1
+      END IF
+*
+      IF( ITYPE.EQ.-1 ) THEN
+         INFO = -1
+      ELSE IF( CFROM.EQ.ZERO ) THEN
+         INFO = -4
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.
+     $         ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN
+         INFO = -7
+      ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -9
+      ELSE IF( ITYPE.GE.4 ) THEN
+         IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN
+            INFO = -2
+         ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.
+     $            ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )
+     $             THEN
+            INFO = -3
+         ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.
+     $            ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.
+     $            ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN
+            INFO = -9
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASCL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. M.EQ.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+*
+      CFROMC = CFROM
+      CTOC = CTO
+*
+   10 CONTINUE
+      CFROM1 = CFROMC*SMLNUM
+      CTO1 = CTOC / BIGNUM
+      IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CFROMC = CFROM1
+      ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CTOC = CTO1
+      ELSE
+         MUL = CTOC / CFROMC
+         DONE = .TRUE.
+      END IF
+*
+      IF( ITYPE.EQ.0 ) THEN
+*
+*        Full matrix
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, M
+               A( I, J ) = A( I, J )*MUL
+   20       CONTINUE
+   30    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.1 ) THEN
+*
+*        Lower triangular matrix
+*
+         DO 50 J = 1, N
+            DO 40 I = J, M
+               A( I, J ) = A( I, J )*MUL
+   40       CONTINUE
+   50    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.2 ) THEN
+*
+*        Upper triangular matrix
+*
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( J, M )
+               A( I, J ) = A( I, J )*MUL
+   60       CONTINUE
+   70    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*        Upper Hessenberg matrix
+*
+         DO 90 J = 1, N
+            DO 80 I = 1, MIN( J+1, M )
+               A( I, J ) = A( I, J )*MUL
+   80       CONTINUE
+   90    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.4 ) THEN
+*
+*        Lower half of a symmetric band matrix
+*
+         K3 = KL + 1
+         K4 = N + 1
+         DO 110 J = 1, N
+            DO 100 I = 1, MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  100       CONTINUE
+  110    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.5 ) THEN
+*
+*        Upper half of a symmetric band matrix
+*
+         K1 = KU + 2
+         K3 = KU + 1
+         DO 130 J = 1, N
+            DO 120 I = MAX( K1-J, 1 ), K3
+               A( I, J ) = A( I, J )*MUL
+  120       CONTINUE
+  130    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.6 ) THEN
+*
+*        Band matrix
+*
+         K1 = KL + KU + 2
+         K2 = KL + 1
+         K3 = 2*KL + KU + 1
+         K4 = KL + KU + 1 + M
+         DO 150 J = 1, N
+            DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  140       CONTINUE
+  150    CONTINUE
+*
+      END IF
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of DLASCL
+*
+      END
diff --git a/libcruft/lapack/dlasd0.f b/libcruft/lapack/dlasd0.f
new file mode 100644
index 0000000..0fb5ccc
--- /dev/null
+++ b/libcruft/lapack/dlasd0.f
@@ -0,0 +1,230 @@
+      SUBROUTINE DLASD0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,
+     $                   WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDU, LDVT, N, SMLSIZ, SQRE
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Using a divide and conquer approach, DLASD0 computes the singular
+*  value decomposition (SVD) of a real upper bidiagonal N-by-M
+*  matrix B with diagonal D and offdiagonal E, where M = N + SQRE.
+*  The algorithm computes orthogonal matrices U and VT such that
+*  B = U * S * VT. The singular values S are overwritten on D.
+*
+*  A related subroutine, DLASDA, computes only the singular values,
+*  and optionally, the singular vectors in compact form.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         On entry, the row dimension of the upper bidiagonal matrix.
+*         This is also the dimension of the main diagonal array D.
+*
+*  SQRE   (input) INTEGER
+*         Specifies the column dimension of the bidiagonal matrix.
+*         = 0: The bidiagonal matrix has column dimension M = N;
+*         = 1: The bidiagonal matrix has column dimension M = N+1;
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension (N)
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix.
+*         On exit D, if INFO = 0, contains its singular values.
+*
+*  E      (input) DOUBLE PRECISION array, dimension (M-1)
+*         Contains the subdiagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  U      (output) DOUBLE PRECISION array, dimension at least (LDQ, N)
+*         On exit, U contains the left singular vectors.
+*
+*  LDU    (input) INTEGER
+*         On entry, leading dimension of U.
+*
+*  VT     (output) DOUBLE PRECISION array, dimension at least (LDVT, M)
+*         On exit, VT' contains the right singular vectors.
+*
+*  LDVT   (input) INTEGER
+*         On entry, leading dimension of VT.
+*
+*  SMLSIZ (input) INTEGER
+*         On entry, maximum size of the subproblems at the
+*         bottom of the computation tree.
+*
+*  IWORK  (workspace) INTEGER work array.
+*         Dimension must be at least (8 * N)
+*
+*  WORK   (workspace) DOUBLE PRECISION work array.
+*         Dimension must be at least (3 * M**2 + 2 * M)
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,
+     $                   J, LF, LL, LVL, M, NCC, ND, NDB1, NDIML, NDIMR,
+     $                   NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQREI
+      DOUBLE PRECISION   ALPHA, BETA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASD1, DLASDQ, DLASDT, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -2
+      END IF
+*
+      M = N + SQRE
+*
+      IF( LDU.LT.N ) THEN
+         INFO = -6
+      ELSE IF( LDVT.LT.M ) THEN
+         INFO = -8
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD0', -INFO )
+         RETURN
+      END IF
+*
+*     If the input matrix is too small, call DLASDQ to find the SVD.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         CALL DLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDVT, U, LDU, U,
+     $                LDU, WORK, INFO )
+         RETURN
+      END IF
+*
+*     Set up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+      IDXQ = NDIMR + N
+      IWK = IDXQ + N
+      CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     For the nodes on bottom level of the tree, solve
+*     their subproblems by DLASDQ.
+*
+      NDB1 = ( ND+1 ) / 2
+      NCC = 0
+      DO 30 I = NDB1, ND
+*
+*     IC : center row of each node
+*     NL : number of rows of left  subproblem
+*     NR : number of rows of right subproblem
+*     NLF: starting row of the left   subproblem
+*     NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NLP1 = NL + 1
+         NR = IWORK( NDIMR+I1 )
+         NRP1 = NR + 1
+         NLF = IC - NL
+         NRF = IC + 1
+         SQREI = 1
+         CALL DLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ), E( NLF ),
+     $                VT( NLF, NLF ), LDVT, U( NLF, NLF ), LDU,
+     $                U( NLF, NLF ), LDU, WORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         ITEMP = IDXQ + NLF - 2
+         DO 10 J = 1, NL
+            IWORK( ITEMP+J ) = J
+   10    CONTINUE
+         IF( I.EQ.ND ) THEN
+            SQREI = SQRE
+         ELSE
+            SQREI = 1
+         END IF
+         NRP1 = NR + SQREI
+         CALL DLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ), E( NRF ),
+     $                VT( NRF, NRF ), LDVT, U( NRF, NRF ), LDU,
+     $                U( NRF, NRF ), LDU, WORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         ITEMP = IDXQ + IC
+         DO 20 J = 1, NR
+            IWORK( ITEMP+J-1 ) = J
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Now conquer each subproblem bottom-up.
+*
+      DO 50 LVL = NLVL, 1, -1
+*
+*        Find the first node LF and last node LL on the
+*        current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 40 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            IF( ( SQRE.EQ.0 ) .AND. ( I.EQ.LL ) ) THEN
+               SQREI = SQRE
+            ELSE
+               SQREI = 1
+            END IF
+            IDXQC = IDXQ + NLF - 1
+            ALPHA = D( IC )
+            BETA = E( IC )
+            CALL DLASD1( NL, NR, SQREI, D( NLF ), ALPHA, BETA,
+     $                   U( NLF, NLF ), LDU, VT( NLF, NLF ), LDVT,
+     $                   IWORK( IDXQC ), IWORK( IWK ), WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+   40    CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of DLASD0
+*
+      END
diff --git a/libcruft/lapack/dlasd1.f b/libcruft/lapack/dlasd1.f
new file mode 100644
index 0000000..8b80ba1
--- /dev/null
+++ b/libcruft/lapack/dlasd1.f
@@ -0,0 +1,232 @@
+      SUBROUTINE DLASD1( NL, NR, SQRE, D, ALPHA, BETA, U, LDU, VT, LDVT,
+     $                   IDXQ, IWORK, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDU, LDVT, NL, NR, SQRE
+      DOUBLE PRECISION   ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IDXQ( * ), IWORK( * )
+      DOUBLE PRECISION   D( * ), U( LDU, * ), VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASD1 computes the SVD of an upper bidiagonal N-by-M matrix B,
+*  where N = NL + NR + 1 and M = N + SQRE. DLASD1 is called from DLASD0.
+*
+*  A related subroutine DLASD7 handles the case in which the singular
+*  values (and the singular vectors in factored form) are desired.
+*
+*  DLASD1 computes the SVD as follows:
+*
+*                ( D1(in)  0    0     0 )
+*    B = U(in) * (   Z1'   a   Z2'    b ) * VT(in)
+*                (   0     0   D2(in) 0 )
+*
+*      = U(out) * ( D(out) 0) * VT(out)
+*
+*  where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M
+*  with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
+*  elsewhere; and the entry b is empty if SQRE = 0.
+*
+*  The left singular vectors of the original matrix are stored in U, and
+*  the transpose of the right singular vectors are stored in VT, and the
+*  singular values are in D.  The algorithm consists of three stages:
+*
+*     The first stage consists of deflating the size of the problem
+*     when there are multiple singular values or when there are zeros in
+*     the Z vector.  For each such occurence the dimension of the
+*     secular equation problem is reduced by one.  This stage is
+*     performed by the routine DLASD2.
+*
+*     The second stage consists of calculating the updated
+*     singular values. This is done by finding the square roots of the
+*     roots of the secular equation via the routine DLASD4 (as called
+*     by DLASD3). This routine also calculates the singular vectors of
+*     the current problem.
+*
+*     The final stage consists of computing the updated singular vectors
+*     directly using the updated singular values.  The singular vectors
+*     for the current problem are multiplied with the singular vectors
+*     from the overall problem.
+*
+*  Arguments
+*  =========
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  D      (input/output) DOUBLE PRECISION array,
+*                        dimension (N = NL+NR+1).
+*         On entry D(1:NL,1:NL) contains the singular values of the
+*         upper block; and D(NL+2:N) contains the singular values of
+*         the lower block. On exit D(1:N) contains the singular values
+*         of the modified matrix.
+*
+*  ALPHA  (input/output) DOUBLE PRECISION
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input/output) DOUBLE PRECISION
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  U      (input/output) DOUBLE PRECISION array, dimension(LDU,N)
+*         On entry U(1:NL, 1:NL) contains the left singular vectors of
+*         the upper block; U(NL+2:N, NL+2:N) contains the left singular
+*         vectors of the lower block. On exit U contains the left
+*         singular vectors of the bidiagonal matrix.
+*
+*  LDU    (input) INTEGER
+*         The leading dimension of the array U.  LDU >= max( 1, N ).
+*
+*  VT     (input/output) DOUBLE PRECISION array, dimension(LDVT,M)
+*         where M = N + SQRE.
+*         On entry VT(1:NL+1, 1:NL+1)' contains the right singular
+*         vectors of the upper block; VT(NL+2:M, NL+2:M)' contains
+*         the right singular vectors of the lower block. On exit
+*         VT' contains the right singular vectors of the
+*         bidiagonal matrix.
+*
+*  LDVT   (input) INTEGER
+*         The leading dimension of the array VT.  LDVT >= max( 1, M ).
+*
+*  IDXQ  (output) INTEGER array, dimension(N)
+*         This contains the permutation which will reintegrate the
+*         subproblem just solved back into sorted order, i.e.
+*         D( IDXQ( I = 1, N ) ) will be in ascending order.
+*
+*  IWORK  (workspace) INTEGER array, dimension( 4 * N )
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension( 3*M**2 + 2*M )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+*
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            COLTYP, I, IDX, IDXC, IDXP, IQ, ISIGMA, IU2,
+     $                   IVT2, IZ, K, LDQ, LDU2, LDVT2, M, N, N1, N2
+      DOUBLE PRECISION   ORGNRM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAMRG, DLASCL, DLASD2, DLASD3, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( NL.LT.1 ) THEN
+         INFO = -1
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -3
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD1', -INFO )
+         RETURN
+      END IF
+*
+      N = NL + NR + 1
+      M = N + SQRE
+*
+*     The following values are for bookkeeping purposes only.  They are
+*     integer pointers which indicate the portion of the workspace
+*     used by a particular array in DLASD2 and DLASD3.
+*
+      LDU2 = N
+      LDVT2 = M
+*
+      IZ = 1
+      ISIGMA = IZ + M
+      IU2 = ISIGMA + N
+      IVT2 = IU2 + LDU2*N
+      IQ = IVT2 + LDVT2*M
+*
+      IDX = 1
+      IDXC = IDX + N
+      COLTYP = IDXC + N
+      IDXP = COLTYP + N
+*
+*     Scale.
+*
+      ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) )
+      D( NL+1 ) = ZERO
+      DO 10 I = 1, N
+         IF( ABS( D( I ) ).GT.ORGNRM ) THEN
+            ORGNRM = ABS( D( I ) )
+         END IF
+   10 CONTINUE
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      ALPHA = ALPHA / ORGNRM
+      BETA = BETA / ORGNRM
+*
+*     Deflate singular values.
+*
+      CALL DLASD2( NL, NR, SQRE, K, D, WORK( IZ ), ALPHA, BETA, U, LDU,
+     $             VT, LDVT, WORK( ISIGMA ), WORK( IU2 ), LDU2,
+     $             WORK( IVT2 ), LDVT2, IWORK( IDXP ), IWORK( IDX ),
+     $             IWORK( IDXC ), IDXQ, IWORK( COLTYP ), INFO )
+*
+*     Solve Secular Equation and update singular vectors.
+*
+      LDQ = K
+      CALL DLASD3( NL, NR, SQRE, K, D, WORK( IQ ), LDQ, WORK( ISIGMA ),
+     $             U, LDU, WORK( IU2 ), LDU2, VT, LDVT, WORK( IVT2 ),
+     $             LDVT2, IWORK( IDXC ), IWORK( COLTYP ), WORK( IZ ),
+     $             INFO )
+      IF( INFO.NE.0 ) THEN
+         RETURN
+      END IF
+*
+*     Unscale.
+*
+      CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+*
+*     Prepare the IDXQ sorting permutation.
+*
+      N1 = K
+      N2 = N - K
+      CALL DLAMRG( N1, N2, D, 1, -1, IDXQ )
+*
+      RETURN
+*
+*     End of DLASD1
+*
+      END
diff --git a/libcruft/lapack/dlasd2.f b/libcruft/lapack/dlasd2.f
new file mode 100644
index 0000000..f382de1
--- /dev/null
+++ b/libcruft/lapack/dlasd2.f
@@ -0,0 +1,512 @@
+      SUBROUTINE DLASD2( NL, NR, SQRE, K, D, Z, ALPHA, BETA, U, LDU, VT,
+     $                   LDVT, DSIGMA, U2, LDU2, VT2, LDVT2, IDXP, IDX,
+     $                   IDXC, IDXQ, COLTYP, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDU, LDU2, LDVT, LDVT2, NL, NR, SQRE
+      DOUBLE PRECISION   ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      INTEGER            COLTYP( * ), IDX( * ), IDXC( * ), IDXP( * ),
+     $                   IDXQ( * )
+      DOUBLE PRECISION   D( * ), DSIGMA( * ), U( LDU, * ),
+     $                   U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
+     $                   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASD2 merges the two sets of singular values together into a single
+*  sorted set.  Then it tries to deflate the size of the problem.
+*  There are two ways in which deflation can occur:  when two or more
+*  singular values are close together or if there is a tiny entry in the
+*  Z vector.  For each such occurrence the order of the related secular
+*  equation problem is reduced by one.
+*
+*  DLASD2 is called from DLASD1.
+*
+*  Arguments
+*  =========
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has N = NL + NR + 1 rows and
+*         M = N + SQRE >= N columns.
+*
+*  K      (output) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension(N)
+*         On entry D contains the singular values of the two submatrices
+*         to be combined.  On exit D contains the trailing (N-K) updated
+*         singular values (those which were deflated) sorted into
+*         increasing order.
+*
+*  Z      (output) DOUBLE PRECISION array, dimension(N)
+*         On exit Z contains the updating row vector in the secular
+*         equation.
+*
+*  ALPHA  (input) DOUBLE PRECISION
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input) DOUBLE PRECISION
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  U      (input/output) DOUBLE PRECISION array, dimension(LDU,N)
+*         On entry U contains the left singular vectors of two
+*         submatrices in the two square blocks with corners at (1,1),
+*         (NL, NL), and (NL+2, NL+2), (N,N).
+*         On exit U contains the trailing (N-K) updated left singular
+*         vectors (those which were deflated) in its last N-K columns.
+*
+*  LDU    (input) INTEGER
+*         The leading dimension of the array U.  LDU >= N.
+*
+*  VT     (input/output) DOUBLE PRECISION array, dimension(LDVT,M)
+*         On entry VT' contains the right singular vectors of two
+*         submatrices in the two square blocks with corners at (1,1),
+*         (NL+1, NL+1), and (NL+2, NL+2), (M,M).
+*         On exit VT' contains the trailing (N-K) updated right singular
+*         vectors (those which were deflated) in its last N-K columns.
+*         In case SQRE =1, the last row of VT spans the right null
+*         space.
+*
+*  LDVT   (input) INTEGER
+*         The leading dimension of the array VT.  LDVT >= M.
+*
+*  DSIGMA (output) DOUBLE PRECISION array, dimension (N)
+*         Contains a copy of the diagonal elements (K-1 singular values
+*         and one zero) in the secular equation.
+*
+*  U2     (output) DOUBLE PRECISION array, dimension(LDU2,N)
+*         Contains a copy of the first K-1 left singular vectors which
+*         will be used by DLASD3 in a matrix multiply (DGEMM) to solve
+*         for the new left singular vectors. U2 is arranged into four
+*         blocks. The first block contains a column with 1 at NL+1 and
+*         zero everywhere else; the second block contains non-zero
+*         entries only at and above NL; the third contains non-zero
+*         entries only below NL+1; and the fourth is dense.
+*
+*  LDU2   (input) INTEGER
+*         The leading dimension of the array U2.  LDU2 >= N.
+*
+*  VT2    (output) DOUBLE PRECISION array, dimension(LDVT2,N)
+*         VT2' contains a copy of the first K right singular vectors
+*         which will be used by DLASD3 in a matrix multiply (DGEMM) to
+*         solve for the new right singular vectors. VT2 is arranged into
+*         three blocks. The first block contains a row that corresponds
+*         to the special 0 diagonal element in SIGMA; the second block
+*         contains non-zeros only at and before NL +1; the third block
+*         contains non-zeros only at and after  NL +2.
+*
+*  LDVT2  (input) INTEGER
+*         The leading dimension of the array VT2.  LDVT2 >= M.
+*
+*  IDXP   (workspace) INTEGER array dimension(N)
+*         This will contain the permutation used to place deflated
+*         values of D at the end of the array. On output IDXP(2:K)
+*         points to the nondeflated D-values and IDXP(K+1:N)
+*         points to the deflated singular values.
+*
+*  IDX    (workspace) INTEGER array dimension(N)
+*         This will contain the permutation used to sort the contents of
+*         D into ascending order.
+*
+*  IDXC   (output) INTEGER array dimension(N)
+*         This will contain the permutation used to arrange the columns
+*         of the deflated U matrix into three groups:  the first group
+*         contains non-zero entries only at and above NL, the second
+*         contains non-zero entries only below NL+2, and the third is
+*         dense.
+*
+*  IDXQ   (input/output) INTEGER array dimension(N)
+*         This contains the permutation which separately sorts the two
+*         sub-problems in D into ascending order.  Note that entries in
+*         the first hlaf of this permutation must first be moved one
+*         position backward; and entries in the second half
+*         must first have NL+1 added to their values.
+*
+*  COLTYP (workspace/output) INTEGER array dimension(N)
+*         As workspace, this will contain a label which will indicate
+*         which of the following types a column in the U2 matrix or a
+*         row in the VT2 matrix is:
+*         1 : non-zero in the upper half only
+*         2 : non-zero in the lower half only
+*         3 : dense
+*         4 : deflated
+*
+*         On exit, it is an array of dimension 4, with COLTYP(I) being
+*         the dimension of the I-th type columns.
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO, EIGHT
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
+     $                   EIGHT = 8.0D+0 )
+*     ..
+*     .. Local Arrays ..
+      INTEGER            CTOT( 4 ), PSM( 4 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            CT, I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M,
+     $                   N, NLP1, NLP2
+      DOUBLE PRECISION   C, EPS, HLFTOL, S, TAU, TOL, Z1
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLAPY2
+      EXTERNAL           DLAMCH, DLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLACPY, DLAMRG, DLASET, DROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( NL.LT.1 ) THEN
+         INFO = -1
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THEN
+         INFO = -3
+      END IF
+*
+      N = NL + NR + 1
+      M = N + SQRE
+*
+      IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDVT.LT.M ) THEN
+         INFO = -12
+      ELSE IF( LDU2.LT.N ) THEN
+         INFO = -15
+      ELSE IF( LDVT2.LT.M ) THEN
+         INFO = -17
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD2', -INFO )
+         RETURN
+      END IF
+*
+      NLP1 = NL + 1
+      NLP2 = NL + 2
+*
+*     Generate the first part of the vector Z; and move the singular
+*     values in the first part of D one position backward.
+*
+      Z1 = ALPHA*VT( NLP1, NLP1 )
+      Z( 1 ) = Z1
+      DO 10 I = NL, 1, -1
+         Z( I+1 ) = ALPHA*VT( I, NLP1 )
+         D( I+1 ) = D( I )
+         IDXQ( I+1 ) = IDXQ( I ) + 1
+   10 CONTINUE
+*
+*     Generate the second part of the vector Z.
+*
+      DO 20 I = NLP2, M
+         Z( I ) = BETA*VT( I, NLP2 )
+   20 CONTINUE
+*
+*     Initialize some reference arrays.
+*
+      DO 30 I = 2, NLP1
+         COLTYP( I ) = 1
+   30 CONTINUE
+      DO 40 I = NLP2, N
+         COLTYP( I ) = 2
+   40 CONTINUE
+*
+*     Sort the singular values into increasing order
+*
+      DO 50 I = NLP2, N
+         IDXQ( I ) = IDXQ( I ) + NLP1
+   50 CONTINUE
+*
+*     DSIGMA, IDXC, IDXC, and the first column of U2
+*     are used as storage space.
+*
+      DO 60 I = 2, N
+         DSIGMA( I ) = D( IDXQ( I ) )
+         U2( I, 1 ) = Z( IDXQ( I ) )
+         IDXC( I ) = COLTYP( IDXQ( I ) )
+   60 CONTINUE
+*
+      CALL DLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )
+*
+      DO 70 I = 2, N
+         IDXI = 1 + IDX( I )
+         D( I ) = DSIGMA( IDXI )
+         Z( I ) = U2( IDXI, 1 )
+         COLTYP( I ) = IDXC( IDXI )
+   70 CONTINUE
+*
+*     Calculate the allowable deflation tolerance
+*
+      EPS = DLAMCH( 'Epsilon' )
+      TOL = MAX( ABS( ALPHA ), ABS( BETA ) )
+      TOL = EIGHT*EPS*MAX( ABS( D( N ) ), TOL )
+*
+*     There are 2 kinds of deflation -- first a value in the z-vector
+*     is small, second two (or more) singular values are very close
+*     together (their difference is small).
+*
+*     If the value in the z-vector is small, we simply permute the
+*     array so that the corresponding singular value is moved to the
+*     end.
+*
+*     If two values in the D-vector are close, we perform a two-sided
+*     rotation designed to make one of the corresponding z-vector
+*     entries zero, and then permute the array so that the deflated
+*     singular value is moved to the end.
+*
+*     If there are multiple singular values then the problem deflates.
+*     Here the number of equal singular values are found.  As each equal
+*     singular value is found, an elementary reflector is computed to
+*     rotate the corresponding singular subspace so that the
+*     corresponding components of Z are zero in this new basis.
+*
+      K = 1
+      K2 = N + 1
+      DO 80 J = 2, N
+         IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*           Deflate due to small z component.
+*
+            K2 = K2 - 1
+            IDXP( K2 ) = J
+            COLTYP( J ) = 4
+            IF( J.EQ.N )
+     $         GO TO 120
+         ELSE
+            JPREV = J
+            GO TO 90
+         END IF
+   80 CONTINUE
+   90 CONTINUE
+      J = JPREV
+  100 CONTINUE
+      J = J + 1
+      IF( J.GT.N )
+     $   GO TO 110
+      IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*        Deflate due to small z component.
+*
+         K2 = K2 - 1
+         IDXP( K2 ) = J
+         COLTYP( J ) = 4
+      ELSE
+*
+*        Check if singular values are close enough to allow deflation.
+*
+         IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN
+*
+*           Deflation is possible.
+*
+            S = Z( JPREV )
+            C = Z( J )
+*
+*           Find sqrt(a**2+b**2) without overflow or
+*           destructive underflow.
+*
+            TAU = DLAPY2( C, S )
+            C = C / TAU
+            S = -S / TAU
+            Z( J ) = TAU
+            Z( JPREV ) = ZERO
+*
+*           Apply back the Givens rotation to the left and right
+*           singular vector matrices.
+*
+            IDXJP = IDXQ( IDX( JPREV )+1 )
+            IDXJ = IDXQ( IDX( J )+1 )
+            IF( IDXJP.LE.NLP1 ) THEN
+               IDXJP = IDXJP - 1
+            END IF
+            IF( IDXJ.LE.NLP1 ) THEN
+               IDXJ = IDXJ - 1
+            END IF
+            CALL DROT( N, U( 1, IDXJP ), 1, U( 1, IDXJ ), 1, C, S )
+            CALL DROT( M, VT( IDXJP, 1 ), LDVT, VT( IDXJ, 1 ), LDVT, C,
+     $                 S )
+            IF( COLTYP( J ).NE.COLTYP( JPREV ) ) THEN
+               COLTYP( J ) = 3
+            END IF
+            COLTYP( JPREV ) = 4
+            K2 = K2 - 1
+            IDXP( K2 ) = JPREV
+            JPREV = J
+         ELSE
+            K = K + 1
+            U2( K, 1 ) = Z( JPREV )
+            DSIGMA( K ) = D( JPREV )
+            IDXP( K ) = JPREV
+            JPREV = J
+         END IF
+      END IF
+      GO TO 100
+  110 CONTINUE
+*
+*     Record the last singular value.
+*
+      K = K + 1
+      U2( K, 1 ) = Z( JPREV )
+      DSIGMA( K ) = D( JPREV )
+      IDXP( K ) = JPREV
+*
+  120 CONTINUE
+*
+*     Count up the total number of the various types of columns, then
+*     form a permutation which positions the four column types into
+*     four groups of uniform structure (although one or more of these
+*     groups may be empty).
+*
+      DO 130 J = 1, 4
+         CTOT( J ) = 0
+  130 CONTINUE
+      DO 140 J = 2, N
+         CT = COLTYP( J )
+         CTOT( CT ) = CTOT( CT ) + 1
+  140 CONTINUE
+*
+*     PSM(*) = Position in SubMatrix (of types 1 through 4)
+*
+      PSM( 1 ) = 2
+      PSM( 2 ) = 2 + CTOT( 1 )
+      PSM( 3 ) = PSM( 2 ) + CTOT( 2 )
+      PSM( 4 ) = PSM( 3 ) + CTOT( 3 )
+*
+*     Fill out the IDXC array so that the permutation which it induces
+*     will place all type-1 columns first, all type-2 columns next,
+*     then all type-3's, and finally all type-4's, starting from the
+*     second column. This applies similarly to the rows of VT.
+*
+      DO 150 J = 2, N
+         JP = IDXP( J )
+         CT = COLTYP( JP )
+         IDXC( PSM( CT ) ) = J
+         PSM( CT ) = PSM( CT ) + 1
+  150 CONTINUE
+*
+*     Sort the singular values and corresponding singular vectors into
+*     DSIGMA, U2, and VT2 respectively.  The singular values/vectors
+*     which were not deflated go into the first K slots of DSIGMA, U2,
+*     and VT2 respectively, while those which were deflated go into the
+*     last N - K slots, except that the first column/row will be treated
+*     separately.
+*
+      DO 160 J = 2, N
+         JP = IDXP( J )
+         DSIGMA( J ) = D( JP )
+         IDXJ = IDXQ( IDX( IDXP( IDXC( J ) ) )+1 )
+         IF( IDXJ.LE.NLP1 ) THEN
+            IDXJ = IDXJ - 1
+         END IF
+         CALL DCOPY( N, U( 1, IDXJ ), 1, U2( 1, J ), 1 )
+         CALL DCOPY( M, VT( IDXJ, 1 ), LDVT, VT2( J, 1 ), LDVT2 )
+  160 CONTINUE
+*
+*     Determine DSIGMA(1), DSIGMA(2) and Z(1)
+*
+      DSIGMA( 1 ) = ZERO
+      HLFTOL = TOL / TWO
+      IF( ABS( DSIGMA( 2 ) ).LE.HLFTOL )
+     $   DSIGMA( 2 ) = HLFTOL
+      IF( M.GT.N ) THEN
+         Z( 1 ) = DLAPY2( Z1, Z( M ) )
+         IF( Z( 1 ).LE.TOL ) THEN
+            C = ONE
+            S = ZERO
+            Z( 1 ) = TOL
+         ELSE
+            C = Z1 / Z( 1 )
+            S = Z( M ) / Z( 1 )
+         END IF
+      ELSE
+         IF( ABS( Z1 ).LE.TOL ) THEN
+            Z( 1 ) = TOL
+         ELSE
+            Z( 1 ) = Z1
+         END IF
+      END IF
+*
+*     Move the rest of the updating row to Z.
+*
+      CALL DCOPY( K-1, U2( 2, 1 ), 1, Z( 2 ), 1 )
+*
+*     Determine the first column of U2, the first row of VT2 and the
+*     last row of VT.
+*
+      CALL DLASET( 'A', N, 1, ZERO, ZERO, U2, LDU2 )
+      U2( NLP1, 1 ) = ONE
+      IF( M.GT.N ) THEN
+         DO 170 I = 1, NLP1
+            VT( M, I ) = -S*VT( NLP1, I )
+            VT2( 1, I ) = C*VT( NLP1, I )
+  170    CONTINUE
+         DO 180 I = NLP2, M
+            VT2( 1, I ) = S*VT( M, I )
+            VT( M, I ) = C*VT( M, I )
+  180    CONTINUE
+      ELSE
+         CALL DCOPY( M, VT( NLP1, 1 ), LDVT, VT2( 1, 1 ), LDVT2 )
+      END IF
+      IF( M.GT.N ) THEN
+         CALL DCOPY( M, VT( M, 1 ), LDVT, VT2( M, 1 ), LDVT2 )
+      END IF
+*
+*     The deflated singular values and their corresponding vectors go
+*     into the back of D, U, and V respectively.
+*
+      IF( N.GT.K ) THEN
+         CALL DCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 )
+         CALL DLACPY( 'A', N, N-K, U2( 1, K+1 ), LDU2, U( 1, K+1 ),
+     $                LDU )
+         CALL DLACPY( 'A', N-K, M, VT2( K+1, 1 ), LDVT2, VT( K+1, 1 ),
+     $                LDVT )
+      END IF
+*
+*     Copy CTOT into COLTYP for referencing in DLASD3.
+*
+      DO 190 J = 1, 4
+         COLTYP( J ) = CTOT( J )
+  190 CONTINUE
+*
+      RETURN
+*
+*     End of DLASD2
+*
+      END
diff --git a/libcruft/lapack/dlasd3.f b/libcruft/lapack/dlasd3.f
new file mode 100644
index 0000000..d412469
--- /dev/null
+++ b/libcruft/lapack/dlasd3.f
@@ -0,0 +1,358 @@
+      SUBROUTINE DLASD3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,
+     $                   LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,
+     $                   INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
+     $                   SQRE
+*     ..
+*     .. Array Arguments ..
+      INTEGER            CTOT( * ), IDXC( * )
+      DOUBLE PRECISION   D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
+     $                   U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
+     $                   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASD3 finds all the square roots of the roots of the secular
+*  equation, as defined by the values in D and Z.  It makes the
+*  appropriate calls to DLASD4 and then updates the singular
+*  vectors by matrix multiplication.
+*
+*  This code makes very mild assumptions about floating point
+*  arithmetic. It will work on machines with a guard digit in
+*  add/subtract, or on those binary machines without guard digits
+*  which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
+*  It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  DLASD3 is called from DLASD1.
+*
+*  Arguments
+*  =========
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has N = NL + NR + 1 rows and
+*         M = N + SQRE >= N columns.
+*
+*  K      (input) INTEGER
+*         The size of the secular equation, 1 =< K = < N.
+*
+*  D      (output) DOUBLE PRECISION array, dimension(K)
+*         On exit the square roots of the roots of the secular equation,
+*         in ascending order.
+*
+*  Q      (workspace) DOUBLE PRECISION array,
+*                     dimension at least (LDQ,K).
+*
+*  LDQ    (input) INTEGER
+*         The leading dimension of the array Q.  LDQ >= K.
+*
+*  DSIGMA (input) DOUBLE PRECISION array, dimension(K)
+*         The first K elements of this array contain the old roots
+*         of the deflated updating problem.  These are the poles
+*         of the secular equation.
+*
+*  U      (output) DOUBLE PRECISION array, dimension (LDU, N)
+*         The last N - K columns of this matrix contain the deflated
+*         left singular vectors.
+*
+*  LDU    (input) INTEGER
+*         The leading dimension of the array U.  LDU >= N.
+*
+*  U2     (input/output) DOUBLE PRECISION array, dimension (LDU2, N)
+*         The first K columns of this matrix contain the non-deflated
+*         left singular vectors for the split problem.
+*
+*  LDU2   (input) INTEGER
+*         The leading dimension of the array U2.  LDU2 >= N.
+*
+*  VT     (output) DOUBLE PRECISION array, dimension (LDVT, M)
+*         The last M - K columns of VT' contain the deflated
+*         right singular vectors.
+*
+*  LDVT   (input) INTEGER
+*         The leading dimension of the array VT.  LDVT >= N.
+*
+*  VT2    (input/output) DOUBLE PRECISION array, dimension (LDVT2, N)
+*         The first K columns of VT2' contain the non-deflated
+*         right singular vectors for the split problem.
+*
+*  LDVT2  (input) INTEGER
+*         The leading dimension of the array VT2.  LDVT2 >= N.
+*
+*  IDXC   (input) INTEGER array, dimension ( N )
+*         The permutation used to arrange the columns of U (and rows of
+*         VT) into three groups:  the first group contains non-zero
+*         entries only at and above (or before) NL +1; the second
+*         contains non-zero entries only at and below (or after) NL+2;
+*         and the third is dense. The first column of U and the row of
+*         VT are treated separately, however.
+*
+*         The rows of the singular vectors found by DLASD4
+*         must be likewise permuted before the matrix multiplies can
+*         take place.
+*
+*  CTOT   (input) INTEGER array, dimension ( 4 )
+*         A count of the total number of the various types of columns
+*         in U (or rows in VT), as described in IDXC. The fourth column
+*         type is any column which has been deflated.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension (K)
+*         The first K elements of this array contain the components
+*         of the deflation-adjusted updating row vector.
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*         > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO, NEGONE
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0,
+     $                   NEGONE = -1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1
+      DOUBLE PRECISION   RHO, TEMP
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3, DNRM2
+      EXTERNAL           DLAMC3, DNRM2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DGEMM, DLACPY, DLASCL, DLASD4, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( NL.LT.1 ) THEN
+         INFO = -1
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THEN
+         INFO = -3
+      END IF
+*
+      N = NL + NR + 1
+      M = N + SQRE
+      NLP1 = NL + 1
+      NLP2 = NL + 2
+*
+      IF( ( K.LT.1 ) .OR. ( K.GT.N ) ) THEN
+         INFO = -4
+      ELSE IF( LDQ.LT.K ) THEN
+         INFO = -7
+      ELSE IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDU2.LT.N ) THEN
+         INFO = -12
+      ELSE IF( LDVT.LT.M ) THEN
+         INFO = -14
+      ELSE IF( LDVT2.LT.M ) THEN
+         INFO = -16
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD3', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( K.EQ.1 ) THEN
+         D( 1 ) = ABS( Z( 1 ) )
+         CALL DCOPY( M, VT2( 1, 1 ), LDVT2, VT( 1, 1 ), LDVT )
+         IF( Z( 1 ).GT.ZERO ) THEN
+            CALL DCOPY( N, U2( 1, 1 ), 1, U( 1, 1 ), 1 )
+         ELSE
+            DO 10 I = 1, N
+               U( I, 1 ) = -U2( I, 1 )
+   10       CONTINUE
+         END IF
+         RETURN
+      END IF
+*
+*     Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
+*     be computed with high relative accuracy (barring over/underflow).
+*     This is a problem on machines without a guard digit in
+*     add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
+*     The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
+*     which on any of these machines zeros out the bottommost
+*     bit of DSIGMA(I) if it is 1; this makes the subsequent
+*     subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
+*     occurs. On binary machines with a guard digit (almost all
+*     machines) it does not change DSIGMA(I) at all. On hexadecimal
+*     and decimal machines with a guard digit, it slightly
+*     changes the bottommost bits of DSIGMA(I). It does not account
+*     for hexadecimal or decimal machines without guard digits
+*     (we know of none). We use a subroutine call to compute
+*     2*DSIGMA(I) to prevent optimizing compilers from eliminating
+*     this code.
+*
+      DO 20 I = 1, K
+         DSIGMA( I ) = DLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )
+   20 CONTINUE
+*
+*     Keep a copy of Z.
+*
+      CALL DCOPY( K, Z, 1, Q, 1 )
+*
+*     Normalize Z.
+*
+      RHO = DNRM2( K, Z, 1 )
+      CALL DLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )
+      RHO = RHO*RHO
+*
+*     Find the new singular values.
+*
+      DO 30 J = 1, K
+         CALL DLASD4( K, J, DSIGMA, Z, U( 1, J ), RHO, D( J ),
+     $                VT( 1, J ), INFO )
+*
+*        If the zero finder fails, the computation is terminated.
+*
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+   30 CONTINUE
+*
+*     Compute updated Z.
+*
+      DO 60 I = 1, K
+         Z( I ) = U( I, K )*VT( I, K )
+         DO 40 J = 1, I - 1
+            Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
+     $               ( DSIGMA( I )-DSIGMA( J ) ) /
+     $               ( DSIGMA( I )+DSIGMA( J ) ) )
+   40    CONTINUE
+         DO 50 J = I, K - 1
+            Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
+     $               ( DSIGMA( I )-DSIGMA( J+1 ) ) /
+     $               ( DSIGMA( I )+DSIGMA( J+1 ) ) )
+   50    CONTINUE
+         Z( I ) = SIGN( SQRT( ABS( Z( I ) ) ), Q( I, 1 ) )
+   60 CONTINUE
+*
+*     Compute left singular vectors of the modified diagonal matrix,
+*     and store related information for the right singular vectors.
+*
+      DO 90 I = 1, K
+         VT( 1, I ) = Z( 1 ) / U( 1, I ) / VT( 1, I )
+         U( 1, I ) = NEGONE
+         DO 70 J = 2, K
+            VT( J, I ) = Z( J ) / U( J, I ) / VT( J, I )
+            U( J, I ) = DSIGMA( J )*VT( J, I )
+   70    CONTINUE
+         TEMP = DNRM2( K, U( 1, I ), 1 )
+         Q( 1, I ) = U( 1, I ) / TEMP
+         DO 80 J = 2, K
+            JC = IDXC( J )
+            Q( J, I ) = U( JC, I ) / TEMP
+   80    CONTINUE
+   90 CONTINUE
+*
+*     Update the left singular vector matrix.
+*
+      IF( K.EQ.2 ) THEN
+         CALL DGEMM( 'N', 'N', N, K, K, ONE, U2, LDU2, Q, LDQ, ZERO, U,
+     $               LDU )
+         GO TO 100
+      END IF
+      IF( CTOT( 1 ).GT.0 ) THEN
+         CALL DGEMM( 'N', 'N', NL, K, CTOT( 1 ), ONE, U2( 1, 2 ), LDU2,
+     $               Q( 2, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
+         IF( CTOT( 3 ).GT.0 ) THEN
+            KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
+            CALL DGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
+     $                  LDU2, Q( KTEMP, 1 ), LDQ, ONE, U( 1, 1 ), LDU )
+         END IF
+      ELSE IF( CTOT( 3 ).GT.0 ) THEN
+         KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
+         CALL DGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
+     $               LDU2, Q( KTEMP, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
+      ELSE
+         CALL DLACPY( 'F', NL, K, U2, LDU2, U, LDU )
+      END IF
+      CALL DCOPY( K, Q( 1, 1 ), LDQ, U( NLP1, 1 ), LDU )
+      KTEMP = 2 + CTOT( 1 )
+      CTEMP = CTOT( 2 ) + CTOT( 3 )
+      CALL DGEMM( 'N', 'N', NR, K, CTEMP, ONE, U2( NLP2, KTEMP ), LDU2,
+     $            Q( KTEMP, 1 ), LDQ, ZERO, U( NLP2, 1 ), LDU )
+*
+*     Generate the right singular vectors.
+*
+  100 CONTINUE
+      DO 120 I = 1, K
+         TEMP = DNRM2( K, VT( 1, I ), 1 )
+         Q( I, 1 ) = VT( 1, I ) / TEMP
+         DO 110 J = 2, K
+            JC = IDXC( J )
+            Q( I, J ) = VT( JC, I ) / TEMP
+  110    CONTINUE
+  120 CONTINUE
+*
+*     Update the right singular vector matrix.
+*
+      IF( K.EQ.2 ) THEN
+         CALL DGEMM( 'N', 'N', K, M, K, ONE, Q, LDQ, VT2, LDVT2, ZERO,
+     $               VT, LDVT )
+         RETURN
+      END IF
+      KTEMP = 1 + CTOT( 1 )
+      CALL DGEMM( 'N', 'N', K, NLP1, KTEMP, ONE, Q( 1, 1 ), LDQ,
+     $            VT2( 1, 1 ), LDVT2, ZERO, VT( 1, 1 ), LDVT )
+      KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
+      IF( KTEMP.LE.LDVT2 )
+     $   CALL DGEMM( 'N', 'N', K, NLP1, CTOT( 3 ), ONE, Q( 1, KTEMP ),
+     $               LDQ, VT2( KTEMP, 1 ), LDVT2, ONE, VT( 1, 1 ),
+     $               LDVT )
+*
+      KTEMP = CTOT( 1 ) + 1
+      NRP1 = NR + SQRE
+      IF( KTEMP.GT.1 ) THEN
+         DO 130 I = 1, K
+            Q( I, KTEMP ) = Q( I, 1 )
+  130    CONTINUE
+         DO 140 I = NLP2, M
+            VT2( KTEMP, I ) = VT2( 1, I )
+  140    CONTINUE
+      END IF
+      CTEMP = 1 + CTOT( 2 ) + CTOT( 3 )
+      CALL DGEMM( 'N', 'N', K, NRP1, CTEMP, ONE, Q( 1, KTEMP ), LDQ,
+     $            VT2( KTEMP, NLP2 ), LDVT2, ZERO, VT( 1, NLP2 ), LDVT )
+*
+      RETURN
+*
+*     End of DLASD3
+*
+      END
diff --git a/libcruft/lapack/dlasd4.f b/libcruft/lapack/dlasd4.f
new file mode 100644
index 0000000..795639f
--- /dev/null
+++ b/libcruft/lapack/dlasd4.f
@@ -0,0 +1,890 @@
+      SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I, INFO, N
+      DOUBLE PRECISION   RHO, SIGMA
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), DELTA( * ), WORK( * ), Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This subroutine computes the square root of the I-th updated
+*  eigenvalue of a positive symmetric rank-one modification to
+*  a positive diagonal matrix whose entries are given as the squares
+*  of the corresponding entries in the array d, and that
+*
+*         0 <= D(i) < D(j)  for  i < j
+*
+*  and that RHO > 0. This is arranged by the calling routine, and is
+*  no loss in generality.  The rank-one modified system is thus
+*
+*         diag( D ) * diag( D ) +  RHO *  Z * Z_transpose.
+*
+*  where we assume the Euclidean norm of Z is 1.
+*
+*  The method consists of approximating the rational functions in the
+*  secular equation by simpler interpolating rational functions.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The length of all arrays.
+*
+*  I      (input) INTEGER
+*         The index of the eigenvalue to be computed.  1 <= I <= N.
+*
+*  D      (input) DOUBLE PRECISION array, dimension ( N )
+*         The original eigenvalues.  It is assumed that they are in
+*         order, 0 <= D(I) < D(J)  for I < J.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( N )
+*         The components of the updating vector.
+*
+*  DELTA  (output) DOUBLE PRECISION array, dimension ( N )
+*         If N .ne. 1, DELTA contains (D(j) - sigma_I) in its  j-th
+*         component.  If N = 1, then DELTA(1) = 1.  The vector DELTA
+*         contains the information necessary to construct the
+*         (singular) eigenvectors.
+*
+*  RHO    (input) DOUBLE PRECISION
+*         The scalar in the symmetric updating formula.
+*
+*  SIGMA  (output) DOUBLE PRECISION
+*         The computed sigma_I, the I-th updated eigenvalue.
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension ( N )
+*         If N .ne. 1, WORK contains (D(j) + sigma_I) in its  j-th
+*         component.  If N = 1, then WORK( 1 ) = 1.
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit
+*         > 0:  if INFO = 1, the updating process failed.
+*
+*  Internal Parameters
+*  ===================
+*
+*  Logical variable ORGATI (origin-at-i?) is used for distinguishing
+*  whether D(i) or D(i+1) is treated as the origin.
+*
+*            ORGATI = .true.    origin at i
+*            ORGATI = .false.   origin at i+1
+*
+*  Logical variable SWTCH3 (switch-for-3-poles?) is for noting
+*  if we are working with THREE poles!
+*
+*  MAXIT is the maximum number of iterations allowed for each
+*  eigenvalue.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ren-Cang Li, Computer Science Division, University of California
+*     at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 20 )
+      DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR, EIGHT, TEN
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
+     $                   THREE = 3.0D+0, FOUR = 4.0D+0, EIGHT = 8.0D+0,
+     $                   TEN = 10.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ORGATI, SWTCH, SWTCH3
+      INTEGER            II, IIM1, IIP1, IP1, ITER, J, NITER
+      DOUBLE PRECISION   A, B, C, DELSQ, DELSQ2, DPHI, DPSI, DTIIM,
+     $                   DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,
+     $                   ERRETM, ETA, PHI, PREW, PSI, RHOINV, SG2LB,
+     $                   SG2UB, TAU, TEMP, TEMP1, TEMP2, W
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DD( 3 ), ZZ( 3 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAED6, DLASD5
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Since this routine is called in an inner loop, we do no argument
+*     checking.
+*
+*     Quick return for N=1 and 2.
+*
+      INFO = 0
+      IF( N.EQ.1 ) THEN
+*
+*        Presumably, I=1 upon entry
+*
+         SIGMA = SQRT( D( 1 )*D( 1 )+RHO*Z( 1 )*Z( 1 ) )
+         DELTA( 1 ) = ONE
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+      IF( N.EQ.2 ) THEN
+         CALL DLASD5( I, D, Z, DELTA, RHO, SIGMA, WORK )
+         RETURN
+      END IF
+*
+*     Compute machine epsilon
+*
+      EPS = DLAMCH( 'Epsilon' )
+      RHOINV = ONE / RHO
+*
+*     The case I = N
+*
+      IF( I.EQ.N ) THEN
+*
+*        Initialize some basic variables
+*
+         II = N - 1
+         NITER = 1
+*
+*        Calculate initial guess
+*
+         TEMP = RHO / TWO
+*
+*        If ||Z||_2 is not one, then TEMP should be set to
+*        RHO * ||Z||_2^2 / TWO
+*
+         TEMP1 = TEMP / ( D( N )+SQRT( D( N )*D( N )+TEMP ) )
+         DO 10 J = 1, N
+            WORK( J ) = D( J ) + D( N ) + TEMP1
+            DELTA( J ) = ( D( J )-D( N ) ) - TEMP1
+   10    CONTINUE
+*
+         PSI = ZERO
+         DO 20 J = 1, N - 2
+            PSI = PSI + Z( J )*Z( J ) / ( DELTA( J )*WORK( J ) )
+   20    CONTINUE
+*
+         C = RHOINV + PSI
+         W = C + Z( II )*Z( II ) / ( DELTA( II )*WORK( II ) ) +
+     $       Z( N )*Z( N ) / ( DELTA( N )*WORK( N ) )
+*
+         IF( W.LE.ZERO ) THEN
+            TEMP1 = SQRT( D( N )*D( N )+RHO )
+            TEMP = Z( N-1 )*Z( N-1 ) / ( ( D( N-1 )+TEMP1 )*
+     $             ( D( N )-D( N-1 )+RHO / ( D( N )+TEMP1 ) ) ) +
+     $             Z( N )*Z( N ) / RHO
+*
+*           The following TAU is to approximate
+*           SIGMA_n^2 - D( N )*D( N )
+*
+            IF( C.LE.TEMP ) THEN
+               TAU = RHO
+            ELSE
+               DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
+               A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
+               B = Z( N )*Z( N )*DELSQ
+               IF( A.LT.ZERO ) THEN
+                  TAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
+               ELSE
+                  TAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
+               END IF
+            END IF
+*
+*           It can be proved that
+*               D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU <= D(N)^2+RHO
+*
+         ELSE
+            DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
+            A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
+            B = Z( N )*Z( N )*DELSQ
+*
+*           The following TAU is to approximate
+*           SIGMA_n^2 - D( N )*D( N )
+*
+            IF( A.LT.ZERO ) THEN
+               TAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
+            ELSE
+               TAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
+            END IF
+*
+*           It can be proved that
+*           D(N)^2 < D(N)^2+TAU < SIGMA(N)^2 < D(N)^2+RHO/2
+*
+         END IF
+*
+*        The following ETA is to approximate SIGMA_n - D( N )
+*
+         ETA = TAU / ( D( N )+SQRT( D( N )*D( N )+TAU ) )
+*
+         SIGMA = D( N ) + ETA
+         DO 30 J = 1, N
+            DELTA( J ) = ( D( J )-D( I ) ) - ETA
+            WORK( J ) = D( J ) + D( I ) + ETA
+   30    CONTINUE
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 40 J = 1, II
+            TEMP = Z( J ) / ( DELTA( J )*WORK( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+   40    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         TEMP = Z( N ) / ( DELTA( N )*WORK( N ) )
+         PHI = Z( N )*TEMP
+         DPHI = TEMP*TEMP
+         ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
+     $            ABS( TAU )*( DPSI+DPHI )
+*
+         W = RHOINV + PHI + PSI
+*
+*        Test for convergence
+*
+         IF( ABS( W ).LE.EPS*ERRETM ) THEN
+            GO TO 240
+         END IF
+*
+*        Calculate the new step
+*
+         NITER = NITER + 1
+         DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
+         DTNSQ = WORK( N )*DELTA( N )
+         C = W - DTNSQ1*DPSI - DTNSQ*DPHI
+         A = ( DTNSQ+DTNSQ1 )*W - DTNSQ*DTNSQ1*( DPSI+DPHI )
+         B = DTNSQ*DTNSQ1*W
+         IF( C.LT.ZERO )
+     $      C = ABS( C )
+         IF( C.EQ.ZERO ) THEN
+            ETA = RHO - SIGMA*SIGMA
+         ELSE IF( A.GE.ZERO ) THEN
+            ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+         ELSE
+            ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
+         END IF
+*
+*        Note, eta should be positive if w is negative, and
+*        eta should be negative otherwise. However,
+*        if for some reason caused by roundoff, eta*w > 0,
+*        we simply use one Newton step instead. This way
+*        will guarantee eta*w < 0.
+*
+         IF( W*ETA.GT.ZERO )
+     $      ETA = -W / ( DPSI+DPHI )
+         TEMP = ETA - DTNSQ
+         IF( TEMP.GT.RHO )
+     $      ETA = RHO + DTNSQ
+*
+         TAU = TAU + ETA
+         ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
+         DO 50 J = 1, N
+            DELTA( J ) = DELTA( J ) - ETA
+            WORK( J ) = WORK( J ) + ETA
+   50    CONTINUE
+*
+         SIGMA = SIGMA + ETA
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 60 J = 1, II
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+   60    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         TEMP = Z( N ) / ( WORK( N )*DELTA( N ) )
+         PHI = Z( N )*TEMP
+         DPHI = TEMP*TEMP
+         ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
+     $            ABS( TAU )*( DPSI+DPHI )
+*
+         W = RHOINV + PHI + PSI
+*
+*        Main loop to update the values of the array   DELTA
+*
+         ITER = NITER + 1
+*
+         DO 90 NITER = ITER, MAXIT
+*
+*           Test for convergence
+*
+            IF( ABS( W ).LE.EPS*ERRETM ) THEN
+               GO TO 240
+            END IF
+*
+*           Calculate the new step
+*
+            DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
+            DTNSQ = WORK( N )*DELTA( N )
+            C = W - DTNSQ1*DPSI - DTNSQ*DPHI
+            A = ( DTNSQ+DTNSQ1 )*W - DTNSQ1*DTNSQ*( DPSI+DPHI )
+            B = DTNSQ1*DTNSQ*W
+            IF( A.GE.ZERO ) THEN
+               ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+            ELSE
+               ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
+            END IF
+*
+*           Note, eta should be positive if w is negative, and
+*           eta should be negative otherwise. However,
+*           if for some reason caused by roundoff, eta*w > 0,
+*           we simply use one Newton step instead. This way
+*           will guarantee eta*w < 0.
+*
+            IF( W*ETA.GT.ZERO )
+     $         ETA = -W / ( DPSI+DPHI )
+            TEMP = ETA - DTNSQ
+            IF( TEMP.LE.ZERO )
+     $         ETA = ETA / TWO
+*
+            TAU = TAU + ETA
+            ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
+            DO 70 J = 1, N
+               DELTA( J ) = DELTA( J ) - ETA
+               WORK( J ) = WORK( J ) + ETA
+   70       CONTINUE
+*
+            SIGMA = SIGMA + ETA
+*
+*           Evaluate PSI and the derivative DPSI
+*
+            DPSI = ZERO
+            PSI = ZERO
+            ERRETM = ZERO
+            DO 80 J = 1, II
+               TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+               PSI = PSI + Z( J )*TEMP
+               DPSI = DPSI + TEMP*TEMP
+               ERRETM = ERRETM + PSI
+   80       CONTINUE
+            ERRETM = ABS( ERRETM )
+*
+*           Evaluate PHI and the derivative DPHI
+*
+            TEMP = Z( N ) / ( WORK( N )*DELTA( N ) )
+            PHI = Z( N )*TEMP
+            DPHI = TEMP*TEMP
+            ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
+     $               ABS( TAU )*( DPSI+DPHI )
+*
+            W = RHOINV + PHI + PSI
+   90    CONTINUE
+*
+*        Return with INFO = 1, NITER = MAXIT and not converged
+*
+         INFO = 1
+         GO TO 240
+*
+*        End for the case I = N
+*
+      ELSE
+*
+*        The case for I < N
+*
+         NITER = 1
+         IP1 = I + 1
+*
+*        Calculate initial guess
+*
+         DELSQ = ( D( IP1 )-D( I ) )*( D( IP1 )+D( I ) )
+         DELSQ2 = DELSQ / TWO
+         TEMP = DELSQ2 / ( D( I )+SQRT( D( I )*D( I )+DELSQ2 ) )
+         DO 100 J = 1, N
+            WORK( J ) = D( J ) + D( I ) + TEMP
+            DELTA( J ) = ( D( J )-D( I ) ) - TEMP
+  100    CONTINUE
+*
+         PSI = ZERO
+         DO 110 J = 1, I - 1
+            PSI = PSI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
+  110    CONTINUE
+*
+         PHI = ZERO
+         DO 120 J = N, I + 2, -1
+            PHI = PHI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
+  120    CONTINUE
+         C = RHOINV + PSI + PHI
+         W = C + Z( I )*Z( I ) / ( WORK( I )*DELTA( I ) ) +
+     $       Z( IP1 )*Z( IP1 ) / ( WORK( IP1 )*DELTA( IP1 ) )
+*
+         IF( W.GT.ZERO ) THEN
+*
+*           d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2
+*
+*           We choose d(i) as origin.
+*
+            ORGATI = .TRUE.
+            SG2LB = ZERO
+            SG2UB = DELSQ2
+            A = C*DELSQ + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )
+            B = Z( I )*Z( I )*DELSQ
+            IF( A.GT.ZERO ) THEN
+               TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+            ELSE
+               TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+            END IF
+*
+*           TAU now is an estimation of SIGMA^2 - D( I )^2. The
+*           following, however, is the corresponding estimation of
+*           SIGMA - D( I ).
+*
+            ETA = TAU / ( D( I )+SQRT( D( I )*D( I )+TAU ) )
+         ELSE
+*
+*           (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
+*
+*           We choose d(i+1) as origin.
+*
+            ORGATI = .FALSE.
+            SG2LB = -DELSQ2
+            SG2UB = ZERO
+            A = C*DELSQ - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )
+            B = Z( IP1 )*Z( IP1 )*DELSQ
+            IF( A.LT.ZERO ) THEN
+               TAU = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )
+            ELSE
+               TAU = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )
+            END IF
+*
+*           TAU now is an estimation of SIGMA^2 - D( IP1 )^2. The
+*           following, however, is the corresponding estimation of
+*           SIGMA - D( IP1 ).
+*
+            ETA = TAU / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+
+     $            TAU ) ) )
+         END IF
+*
+         IF( ORGATI ) THEN
+            II = I
+            SIGMA = D( I ) + ETA
+            DO 130 J = 1, N
+               WORK( J ) = D( J ) + D( I ) + ETA
+               DELTA( J ) = ( D( J )-D( I ) ) - ETA
+  130       CONTINUE
+         ELSE
+            II = I + 1
+            SIGMA = D( IP1 ) + ETA
+            DO 140 J = 1, N
+               WORK( J ) = D( J ) + D( IP1 ) + ETA
+               DELTA( J ) = ( D( J )-D( IP1 ) ) - ETA
+  140       CONTINUE
+         END IF
+         IIM1 = II - 1
+         IIP1 = II + 1
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 150 J = 1, IIM1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+  150    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         DPHI = ZERO
+         PHI = ZERO
+         DO 160 J = N, IIP1, -1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PHI = PHI + Z( J )*TEMP
+            DPHI = DPHI + TEMP*TEMP
+            ERRETM = ERRETM + PHI
+  160    CONTINUE
+*
+         W = RHOINV + PHI + PSI
+*
+*        W is the value of the secular function with
+*        its ii-th element removed.
+*
+         SWTCH3 = .FALSE.
+         IF( ORGATI ) THEN
+            IF( W.LT.ZERO )
+     $         SWTCH3 = .TRUE.
+         ELSE
+            IF( W.GT.ZERO )
+     $         SWTCH3 = .TRUE.
+         END IF
+         IF( II.EQ.1 .OR. II.EQ.N )
+     $      SWTCH3 = .FALSE.
+*
+         TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+         DW = DPSI + DPHI + TEMP*TEMP
+         TEMP = Z( II )*TEMP
+         W = W + TEMP
+         ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
+     $            THREE*ABS( TEMP ) + ABS( TAU )*DW
+*
+*        Test for convergence
+*
+         IF( ABS( W ).LE.EPS*ERRETM ) THEN
+            GO TO 240
+         END IF
+*
+         IF( W.LE.ZERO ) THEN
+            SG2LB = MAX( SG2LB, TAU )
+         ELSE
+            SG2UB = MIN( SG2UB, TAU )
+         END IF
+*
+*        Calculate the new step
+*
+         NITER = NITER + 1
+         IF( .NOT.SWTCH3 ) THEN
+            DTIPSQ = WORK( IP1 )*DELTA( IP1 )
+            DTISQ = WORK( I )*DELTA( I )
+            IF( ORGATI ) THEN
+               C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
+            ELSE
+               C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
+            END IF
+            A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
+            B = DTIPSQ*DTISQ*W
+            IF( C.EQ.ZERO ) THEN
+               IF( A.EQ.ZERO ) THEN
+                  IF( ORGATI ) THEN
+                     A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )
+                  ELSE
+                     A = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI )
+                  END IF
+               END IF
+               ETA = B / A
+            ELSE IF( A.LE.ZERO ) THEN
+               ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+            ELSE
+               ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+            END IF
+         ELSE
+*
+*           Interpolation using THREE most relevant poles
+*
+            DTIIM = WORK( IIM1 )*DELTA( IIM1 )
+            DTIIP = WORK( IIP1 )*DELTA( IIP1 )
+            TEMP = RHOINV + PSI + PHI
+            IF( ORGATI ) THEN
+               TEMP1 = Z( IIM1 ) / DTIIM
+               TEMP1 = TEMP1*TEMP1
+               C = ( TEMP - DTIIP*( DPSI+DPHI ) ) -
+     $             ( D( IIM1 )-D( IIP1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
+               ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
+               IF( DPSI.LT.TEMP1 ) THEN
+                  ZZ( 3 ) = DTIIP*DTIIP*DPHI
+               ELSE
+                  ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
+               END IF
+            ELSE
+               TEMP1 = Z( IIP1 ) / DTIIP
+               TEMP1 = TEMP1*TEMP1
+               C = ( TEMP - DTIIM*( DPSI+DPHI ) ) -
+     $             ( D( IIP1 )-D( IIM1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
+               IF( DPHI.LT.TEMP1 ) THEN
+                  ZZ( 1 ) = DTIIM*DTIIM*DPSI
+               ELSE
+                  ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
+               END IF
+               ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
+            END IF
+            ZZ( 2 ) = Z( II )*Z( II )
+            DD( 1 ) = DTIIM
+            DD( 2 ) = DELTA( II )*WORK( II )
+            DD( 3 ) = DTIIP
+            CALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
+            IF( INFO.NE.0 )
+     $         GO TO 240
+         END IF
+*
+*        Note, eta should be positive if w is negative, and
+*        eta should be negative otherwise. However,
+*        if for some reason caused by roundoff, eta*w > 0,
+*        we simply use one Newton step instead. This way
+*        will guarantee eta*w < 0.
+*
+         IF( W*ETA.GE.ZERO )
+     $      ETA = -W / DW
+         IF( ORGATI ) THEN
+            TEMP1 = WORK( I )*DELTA( I )
+            TEMP = ETA - TEMP1
+         ELSE
+            TEMP1 = WORK( IP1 )*DELTA( IP1 )
+            TEMP = ETA - TEMP1
+         END IF
+         IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
+            IF( W.LT.ZERO ) THEN
+               ETA = ( SG2UB-TAU ) / TWO
+            ELSE
+               ETA = ( SG2LB-TAU ) / TWO
+            END IF
+         END IF
+*
+         TAU = TAU + ETA
+         ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
+*
+         PREW = W
+*
+         SIGMA = SIGMA + ETA
+         DO 170 J = 1, N
+            WORK( J ) = WORK( J ) + ETA
+            DELTA( J ) = DELTA( J ) - ETA
+  170    CONTINUE
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 180 J = 1, IIM1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+  180    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         DPHI = ZERO
+         PHI = ZERO
+         DO 190 J = N, IIP1, -1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PHI = PHI + Z( J )*TEMP
+            DPHI = DPHI + TEMP*TEMP
+            ERRETM = ERRETM + PHI
+  190    CONTINUE
+*
+         TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+         DW = DPSI + DPHI + TEMP*TEMP
+         TEMP = Z( II )*TEMP
+         W = RHOINV + PHI + PSI + TEMP
+         ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
+     $            THREE*ABS( TEMP ) + ABS( TAU )*DW
+*
+         IF( W.LE.ZERO ) THEN
+            SG2LB = MAX( SG2LB, TAU )
+         ELSE
+            SG2UB = MIN( SG2UB, TAU )
+         END IF
+*
+         SWTCH = .FALSE.
+         IF( ORGATI ) THEN
+            IF( -W.GT.ABS( PREW ) / TEN )
+     $         SWTCH = .TRUE.
+         ELSE
+            IF( W.GT.ABS( PREW ) / TEN )
+     $         SWTCH = .TRUE.
+         END IF
+*
+*        Main loop to update the values of the array   DELTA and WORK
+*
+         ITER = NITER + 1
+*
+         DO 230 NITER = ITER, MAXIT
+*
+*           Test for convergence
+*
+            IF( ABS( W ).LE.EPS*ERRETM ) THEN
+               GO TO 240
+            END IF
+*
+*           Calculate the new step
+*
+            IF( .NOT.SWTCH3 ) THEN
+               DTIPSQ = WORK( IP1 )*DELTA( IP1 )
+               DTISQ = WORK( I )*DELTA( I )
+               IF( .NOT.SWTCH ) THEN
+                  IF( ORGATI ) THEN
+                     C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
+                  ELSE
+                     C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
+                  END IF
+               ELSE
+                  TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+                  IF( ORGATI ) THEN
+                     DPSI = DPSI + TEMP*TEMP
+                  ELSE
+                     DPHI = DPHI + TEMP*TEMP
+                  END IF
+                  C = W - DTISQ*DPSI - DTIPSQ*DPHI
+               END IF
+               A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
+               B = DTIPSQ*DTISQ*W
+               IF( C.EQ.ZERO ) THEN
+                  IF( A.EQ.ZERO ) THEN
+                     IF( .NOT.SWTCH ) THEN
+                        IF( ORGATI ) THEN
+                           A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*
+     $                         ( DPSI+DPHI )
+                        ELSE
+                           A = Z( IP1 )*Z( IP1 ) +
+     $                         DTISQ*DTISQ*( DPSI+DPHI )
+                        END IF
+                     ELSE
+                        A = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHI
+                     END IF
+                  END IF
+                  ETA = B / A
+               ELSE IF( A.LE.ZERO ) THEN
+                  ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+               ELSE
+                  ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+               END IF
+            ELSE
+*
+*              Interpolation using THREE most relevant poles
+*
+               DTIIM = WORK( IIM1 )*DELTA( IIM1 )
+               DTIIP = WORK( IIP1 )*DELTA( IIP1 )
+               TEMP = RHOINV + PSI + PHI
+               IF( SWTCH ) THEN
+                  C = TEMP - DTIIM*DPSI - DTIIP*DPHI
+                  ZZ( 1 ) = DTIIM*DTIIM*DPSI
+                  ZZ( 3 ) = DTIIP*DTIIP*DPHI
+               ELSE
+                  IF( ORGATI ) THEN
+                     TEMP1 = Z( IIM1 ) / DTIIM
+                     TEMP1 = TEMP1*TEMP1
+                     TEMP2 = ( D( IIM1 )-D( IIP1 ) )*
+     $                       ( D( IIM1 )+D( IIP1 ) )*TEMP1
+                     C = TEMP - DTIIP*( DPSI+DPHI ) - TEMP2
+                     ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
+                     IF( DPSI.LT.TEMP1 ) THEN
+                        ZZ( 3 ) = DTIIP*DTIIP*DPHI
+                     ELSE
+                        ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
+                     END IF
+                  ELSE
+                     TEMP1 = Z( IIP1 ) / DTIIP
+                     TEMP1 = TEMP1*TEMP1
+                     TEMP2 = ( D( IIP1 )-D( IIM1 ) )*
+     $                       ( D( IIM1 )+D( IIP1 ) )*TEMP1
+                     C = TEMP - DTIIM*( DPSI+DPHI ) - TEMP2
+                     IF( DPHI.LT.TEMP1 ) THEN
+                        ZZ( 1 ) = DTIIM*DTIIM*DPSI
+                     ELSE
+                        ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
+                     END IF
+                     ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
+                  END IF
+               END IF
+               DD( 1 ) = DTIIM
+               DD( 2 ) = DELTA( II )*WORK( II )
+               DD( 3 ) = DTIIP
+               CALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 240
+            END IF
+*
+*           Note, eta should be positive if w is negative, and
+*           eta should be negative otherwise. However,
+*           if for some reason caused by roundoff, eta*w > 0,
+*           we simply use one Newton step instead. This way
+*           will guarantee eta*w < 0.
+*
+            IF( W*ETA.GE.ZERO )
+     $         ETA = -W / DW
+            IF( ORGATI ) THEN
+               TEMP1 = WORK( I )*DELTA( I )
+               TEMP = ETA - TEMP1
+            ELSE
+               TEMP1 = WORK( IP1 )*DELTA( IP1 )
+               TEMP = ETA - TEMP1
+            END IF
+            IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
+               IF( W.LT.ZERO ) THEN
+                  ETA = ( SG2UB-TAU ) / TWO
+               ELSE
+                  ETA = ( SG2LB-TAU ) / TWO
+               END IF
+            END IF
+*
+            TAU = TAU + ETA
+            ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
+*
+            SIGMA = SIGMA + ETA
+            DO 200 J = 1, N
+               WORK( J ) = WORK( J ) + ETA
+               DELTA( J ) = DELTA( J ) - ETA
+  200       CONTINUE
+*
+            PREW = W
+*
+*           Evaluate PSI and the derivative DPSI
+*
+            DPSI = ZERO
+            PSI = ZERO
+            ERRETM = ZERO
+            DO 210 J = 1, IIM1
+               TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+               PSI = PSI + Z( J )*TEMP
+               DPSI = DPSI + TEMP*TEMP
+               ERRETM = ERRETM + PSI
+  210       CONTINUE
+            ERRETM = ABS( ERRETM )
+*
+*           Evaluate PHI and the derivative DPHI
+*
+            DPHI = ZERO
+            PHI = ZERO
+            DO 220 J = N, IIP1, -1
+               TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+               PHI = PHI + Z( J )*TEMP
+               DPHI = DPHI + TEMP*TEMP
+               ERRETM = ERRETM + PHI
+  220       CONTINUE
+*
+            TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+            DW = DPSI + DPHI + TEMP*TEMP
+            TEMP = Z( II )*TEMP
+            W = RHOINV + PHI + PSI + TEMP
+            ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
+     $               THREE*ABS( TEMP ) + ABS( TAU )*DW
+            IF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )
+     $         SWTCH = .NOT.SWTCH
+*
+            IF( W.LE.ZERO ) THEN
+               SG2LB = MAX( SG2LB, TAU )
+            ELSE
+               SG2UB = MIN( SG2UB, TAU )
+            END IF
+*
+  230    CONTINUE
+*
+*        Return with INFO = 1, NITER = MAXIT and not converged
+*
+         INFO = 1
+*
+      END IF
+*
+  240 CONTINUE
+      RETURN
+*
+*     End of DLASD4
+*
+      END
diff --git a/libcruft/lapack/dlasd5.f b/libcruft/lapack/dlasd5.f
new file mode 100644
index 0000000..93cb847
--- /dev/null
+++ b/libcruft/lapack/dlasd5.f
@@ -0,0 +1,163 @@
+      SUBROUTINE DLASD5( I, D, Z, DELTA, RHO, DSIGMA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I
+      DOUBLE PRECISION   DSIGMA, RHO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( 2 ), DELTA( 2 ), WORK( 2 ), Z( 2 )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This subroutine computes the square root of the I-th eigenvalue
+*  of a positive symmetric rank-one modification of a 2-by-2 diagonal
+*  matrix
+*
+*             diag( D ) * diag( D ) +  RHO *  Z * transpose(Z) .
+*
+*  The diagonal entries in the array D are assumed to satisfy
+*
+*             0 <= D(i) < D(j)  for  i < j .
+*
+*  We also assume RHO > 0 and that the Euclidean norm of the vector
+*  Z is one.
+*
+*  Arguments
+*  =========
+*
+*  I      (input) INTEGER
+*         The index of the eigenvalue to be computed.  I = 1 or I = 2.
+*
+*  D      (input) DOUBLE PRECISION array, dimension ( 2 )
+*         The original eigenvalues.  We assume 0 <= D(1) < D(2).
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( 2 )
+*         The components of the updating vector.
+*
+*  DELTA  (output) DOUBLE PRECISION array, dimension ( 2 )
+*         Contains (D(j) - sigma_I) in its  j-th component.
+*         The vector DELTA contains the information necessary
+*         to construct the eigenvectors.
+*
+*  RHO    (input) DOUBLE PRECISION
+*         The scalar in the symmetric updating formula.
+*
+*  DSIGMA (output) DOUBLE PRECISION
+*         The computed sigma_I, the I-th updated eigenvalue.
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension ( 2 )
+*         WORK contains (D(j) + sigma_I) in its  j-th component.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ren-Cang Li, Computer Science Division, University of California
+*     at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
+     $                   THREE = 3.0D+0, FOUR = 4.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   B, C, DEL, DELSQ, TAU, W
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      DEL = D( 2 ) - D( 1 )
+      DELSQ = DEL*( D( 2 )+D( 1 ) )
+      IF( I.EQ.1 ) THEN
+         W = ONE + FOUR*RHO*( Z( 2 )*Z( 2 ) / ( D( 1 )+THREE*D( 2 ) )-
+     $       Z( 1 )*Z( 1 ) / ( THREE*D( 1 )+D( 2 ) ) ) / DEL
+         IF( W.GT.ZERO ) THEN
+            B = DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )
+            C = RHO*Z( 1 )*Z( 1 )*DELSQ
+*
+*           B > ZERO, always
+*
+*           The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 )
+*
+            TAU = TWO*C / ( B+SQRT( ABS( B*B-FOUR*C ) ) )
+*
+*           The following TAU is DSIGMA - D( 1 )
+*
+            TAU = TAU / ( D( 1 )+SQRT( D( 1 )*D( 1 )+TAU ) )
+            DSIGMA = D( 1 ) + TAU
+            DELTA( 1 ) = -TAU
+            DELTA( 2 ) = DEL - TAU
+            WORK( 1 ) = TWO*D( 1 ) + TAU
+            WORK( 2 ) = ( D( 1 )+TAU ) + D( 2 )
+*           DELTA( 1 ) = -Z( 1 ) / TAU
+*           DELTA( 2 ) = Z( 2 ) / ( DEL-TAU )
+         ELSE
+            B = -DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )
+            C = RHO*Z( 2 )*Z( 2 )*DELSQ
+*
+*           The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
+*
+            IF( B.GT.ZERO ) THEN
+               TAU = -TWO*C / ( B+SQRT( B*B+FOUR*C ) )
+            ELSE
+               TAU = ( B-SQRT( B*B+FOUR*C ) ) / TWO
+            END IF
+*
+*           The following TAU is DSIGMA - D( 2 )
+*
+            TAU = TAU / ( D( 2 )+SQRT( ABS( D( 2 )*D( 2 )+TAU ) ) )
+            DSIGMA = D( 2 ) + TAU
+            DELTA( 1 ) = -( DEL+TAU )
+            DELTA( 2 ) = -TAU
+            WORK( 1 ) = D( 1 ) + TAU + D( 2 )
+            WORK( 2 ) = TWO*D( 2 ) + TAU
+*           DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
+*           DELTA( 2 ) = -Z( 2 ) / TAU
+         END IF
+*        TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
+*        DELTA( 1 ) = DELTA( 1 ) / TEMP
+*        DELTA( 2 ) = DELTA( 2 ) / TEMP
+      ELSE
+*
+*        Now I=2
+*
+         B = -DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )
+         C = RHO*Z( 2 )*Z( 2 )*DELSQ
+*
+*        The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
+*
+         IF( B.GT.ZERO ) THEN
+            TAU = ( B+SQRT( B*B+FOUR*C ) ) / TWO
+         ELSE
+            TAU = TWO*C / ( -B+SQRT( B*B+FOUR*C ) )
+         END IF
+*
+*        The following TAU is DSIGMA - D( 2 )
+*
+         TAU = TAU / ( D( 2 )+SQRT( D( 2 )*D( 2 )+TAU ) )
+         DSIGMA = D( 2 ) + TAU
+         DELTA( 1 ) = -( DEL+TAU )
+         DELTA( 2 ) = -TAU
+         WORK( 1 ) = D( 1 ) + TAU + D( 2 )
+         WORK( 2 ) = TWO*D( 2 ) + TAU
+*        DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
+*        DELTA( 2 ) = -Z( 2 ) / TAU
+*        TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
+*        DELTA( 1 ) = DELTA( 1 ) / TEMP
+*        DELTA( 2 ) = DELTA( 2 ) / TEMP
+      END IF
+      RETURN
+*
+*     End of DLASD5
+*
+      END
diff --git a/libcruft/lapack/dlasd6.f b/libcruft/lapack/dlasd6.f
new file mode 100644
index 0000000..622befa
--- /dev/null
+++ b/libcruft/lapack/dlasd6.f
@@ -0,0 +1,305 @@
+      SUBROUTINE DLASD6( ICOMPQ, NL, NR, SQRE, D, VF, VL, ALPHA, BETA,
+     $                   IDXQ, PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM,
+     $                   LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
+     $                   NR, SQRE
+      DOUBLE PRECISION   ALPHA, BETA, C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ),
+     $                   PERM( * )
+      DOUBLE PRECISION   D( * ), DIFL( * ), DIFR( * ),
+     $                   GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
+     $                   VF( * ), VL( * ), WORK( * ), Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASD6 computes the SVD of an updated upper bidiagonal matrix B
+*  obtained by merging two smaller ones by appending a row. This
+*  routine is used only for the problem which requires all singular
+*  values and optionally singular vector matrices in factored form.
+*  B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE.
+*  A related subroutine, DLASD1, handles the case in which all singular
+*  values and singular vectors of the bidiagonal matrix are desired.
+*
+*  DLASD6 computes the SVD as follows:
+*
+*                ( D1(in)  0    0     0 )
+*    B = U(in) * (   Z1'   a   Z2'    b ) * VT(in)
+*                (   0     0   D2(in) 0 )
+*
+*      = U(out) * ( D(out) 0) * VT(out)
+*
+*  where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M
+*  with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
+*  elsewhere; and the entry b is empty if SQRE = 0.
+*
+*  The singular values of B can be computed using D1, D2, the first
+*  components of all the right singular vectors of the lower block, and
+*  the last components of all the right singular vectors of the upper
+*  block. These components are stored and updated in VF and VL,
+*  respectively, in DLASD6. Hence U and VT are not explicitly
+*  referenced.
+*
+*  The singular values are stored in D. The algorithm consists of two
+*  stages:
+*
+*        The first stage consists of deflating the size of the problem
+*        when there are multiple singular values or if there is a zero
+*        in the Z vector. For each such occurence the dimension of the
+*        secular equation problem is reduced by one. This stage is
+*        performed by the routine DLASD7.
+*
+*        The second stage consists of calculating the updated
+*        singular values. This is done by finding the roots of the
+*        secular equation via the routine DLASD4 (as called by DLASD8).
+*        This routine also updates VF and VL and computes the distances
+*        between the updated singular values and the old singular
+*        values.
+*
+*  DLASD6 is called from DLASDA.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed in
+*         factored form:
+*         = 0: Compute singular values only.
+*         = 1: Compute singular vectors in factored form as well.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension ( NL+NR+1 ).
+*         On entry D(1:NL,1:NL) contains the singular values of the
+*         upper block, and D(NL+2:N) contains the singular values
+*         of the lower block. On exit D(1:N) contains the singular
+*         values of the modified matrix.
+*
+*  VF     (input/output) DOUBLE PRECISION array, dimension ( M )
+*         On entry, VF(1:NL+1) contains the first components of all
+*         right singular vectors of the upper block; and VF(NL+2:M)
+*         contains the first components of all right singular vectors
+*         of the lower block. On exit, VF contains the first components
+*         of all right singular vectors of the bidiagonal matrix.
+*
+*  VL     (input/output) DOUBLE PRECISION array, dimension ( M )
+*         On entry, VL(1:NL+1) contains the  last components of all
+*         right singular vectors of the upper block; and VL(NL+2:M)
+*         contains the last components of all right singular vectors of
+*         the lower block. On exit, VL contains the last components of
+*         all right singular vectors of the bidiagonal matrix.
+*
+*  ALPHA  (input/output) DOUBLE PRECISION
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input/output) DOUBLE PRECISION
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  IDXQ   (output) INTEGER array, dimension ( N )
+*         This contains the permutation which will reintegrate the
+*         subproblem just solved back into sorted order, i.e.
+*         D( IDXQ( I = 1, N ) ) will be in ascending order.
+*
+*  PERM   (output) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) to be applied
+*         to each block. Not referenced if ICOMPQ = 0.
+*
+*  GIVPTR (output) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem. Not referenced if ICOMPQ = 0.
+*
+*  GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of columns to take place
+*         in a Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGCOL (input) INTEGER
+*         leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value to be used in the
+*         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of GIVNUM and POLES, must be at least N.
+*
+*  POLES  (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         On exit, POLES(1,*) is an array containing the new singular
+*         values obtained from solving the secular equation, and
+*         POLES(2,*) is an array containing the poles in the secular
+*         equation. Not referenced if ICOMPQ = 0.
+*
+*  DIFL   (output) DOUBLE PRECISION array, dimension ( N )
+*         On exit, DIFL(I) is the distance between I-th updated
+*         (undeflated) singular value and the I-th (undeflated) old
+*         singular value.
+*
+*  DIFR   (output) DOUBLE PRECISION array,
+*                  dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and
+*                  dimension ( N ) if ICOMPQ = 0.
+*         On exit, DIFR(I, 1) is the distance between I-th updated
+*         (undeflated) singular value and the I+1-th (undeflated) old
+*         singular value.
+*
+*         If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
+*         normalizing factors for the right singular vector matrix.
+*
+*         See DLASD8 for details on DIFL and DIFR.
+*
+*  Z      (output) DOUBLE PRECISION array, dimension ( M )
+*         The first elements of this array contain the components
+*         of the deflation-adjusted updating row vector.
+*
+*  K      (output) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  C      (output) DOUBLE PRECISION
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (output) DOUBLE PRECISION
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension ( 4 * M )
+*
+*  IWORK  (workspace) INTEGER array, dimension ( 3 * N )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IDX, IDXC, IDXP, ISIGMA, IVFW, IVLW, IW, M,
+     $                   N, N1, N2
+      DOUBLE PRECISION   ORGNRM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLAMRG, DLASCL, DLASD7, DLASD8, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      N = NL + NR + 1
+      M = N + SQRE
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -14
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -16
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD6', -INFO )
+         RETURN
+      END IF
+*
+*     The following values are for bookkeeping purposes only.  They are
+*     integer pointers which indicate the portion of the workspace
+*     used by a particular array in DLASD7 and DLASD8.
+*
+      ISIGMA = 1
+      IW = ISIGMA + N
+      IVFW = IW + M
+      IVLW = IVFW + M
+*
+      IDX = 1
+      IDXC = IDX + N
+      IDXP = IDXC + N
+*
+*     Scale.
+*
+      ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) )
+      D( NL+1 ) = ZERO
+      DO 10 I = 1, N
+         IF( ABS( D( I ) ).GT.ORGNRM ) THEN
+            ORGNRM = ABS( D( I ) )
+         END IF
+   10 CONTINUE
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      ALPHA = ALPHA / ORGNRM
+      BETA = BETA / ORGNRM
+*
+*     Sort and Deflate singular values.
+*
+      CALL DLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, WORK( IW ), VF,
+     $             WORK( IVFW ), VL, WORK( IVLW ), ALPHA, BETA,
+     $             WORK( ISIGMA ), IWORK( IDX ), IWORK( IDXP ), IDXQ,
+     $             PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM, C, S,
+     $             INFO )
+*
+*     Solve Secular Equation, compute DIFL, DIFR, and update VF, VL.
+*
+      CALL DLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDGNUM,
+     $             WORK( ISIGMA ), WORK( IW ), INFO )
+*
+*     Save the poles if ICOMPQ = 1.
+*
+      IF( ICOMPQ.EQ.1 ) THEN
+         CALL DCOPY( K, D, 1, POLES( 1, 1 ), 1 )
+         CALL DCOPY( K, WORK( ISIGMA ), 1, POLES( 1, 2 ), 1 )
+      END IF
+*
+*     Unscale.
+*
+      CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+*
+*     Prepare the IDXQ sorting permutation.
+*
+      N1 = K
+      N2 = N - K
+      CALL DLAMRG( N1, N2, D, 1, -1, IDXQ )
+*
+      RETURN
+*
+*     End of DLASD6
+*
+      END
diff --git a/libcruft/lapack/dlasd7.f b/libcruft/lapack/dlasd7.f
new file mode 100644
index 0000000..27547aa
--- /dev/null
+++ b/libcruft/lapack/dlasd7.f
@@ -0,0 +1,444 @@
+      SUBROUTINE DLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, ZW, VF, VFW, VL,
+     $                   VLW, ALPHA, BETA, DSIGMA, IDX, IDXP, IDXQ,
+     $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
+     $                   C, S, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
+     $                   NR, SQRE
+      DOUBLE PRECISION   ALPHA, BETA, C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), IDX( * ), IDXP( * ),
+     $                   IDXQ( * ), PERM( * )
+      DOUBLE PRECISION   D( * ), DSIGMA( * ), GIVNUM( LDGNUM, * ),
+     $                   VF( * ), VFW( * ), VL( * ), VLW( * ), Z( * ),
+     $                   ZW( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASD7 merges the two sets of singular values together into a single
+*  sorted set. Then it tries to deflate the size of the problem. There
+*  are two ways in which deflation can occur:  when two or more singular
+*  values are close together or if there is a tiny entry in the Z
+*  vector. For each such occurrence the order of the related
+*  secular equation problem is reduced by one.
+*
+*  DLASD7 is called from DLASD6.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ  (input) INTEGER
+*          Specifies whether singular vectors are to be computed
+*          in compact form, as follows:
+*          = 0: Compute singular values only.
+*          = 1: Compute singular vectors of upper
+*               bidiagonal matrix in compact form.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block. NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block. NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has
+*         N = NL + NR + 1 rows and
+*         M = N + SQRE >= N columns.
+*
+*  K      (output) INTEGER
+*         Contains the dimension of the non-deflated matrix, this is
+*         the order of the related secular equation. 1 <= K <=N.
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension ( N )
+*         On entry D contains the singular values of the two submatrices
+*         to be combined. On exit D contains the trailing (N-K) updated
+*         singular values (those which were deflated) sorted into
+*         increasing order.
+*
+*  Z      (output) DOUBLE PRECISION array, dimension ( M )
+*         On exit Z contains the updating row vector in the secular
+*         equation.
+*
+*  ZW     (workspace) DOUBLE PRECISION array, dimension ( M )
+*         Workspace for Z.
+*
+*  VF     (input/output) DOUBLE PRECISION array, dimension ( M )
+*         On entry, VF(1:NL+1) contains the first components of all
+*         right singular vectors of the upper block; and VF(NL+2:M)
+*         contains the first components of all right singular vectors
+*         of the lower block. On exit, VF contains the first components
+*         of all right singular vectors of the bidiagonal matrix.
+*
+*  VFW    (workspace) DOUBLE PRECISION array, dimension ( M )
+*         Workspace for VF.
+*
+*  VL     (input/output) DOUBLE PRECISION array, dimension ( M )
+*         On entry, VL(1:NL+1) contains the  last components of all
+*         right singular vectors of the upper block; and VL(NL+2:M)
+*         contains the last components of all right singular vectors
+*         of the lower block. On exit, VL contains the last components
+*         of all right singular vectors of the bidiagonal matrix.
+*
+*  VLW    (workspace) DOUBLE PRECISION array, dimension ( M )
+*         Workspace for VL.
+*
+*  ALPHA  (input) DOUBLE PRECISION
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input) DOUBLE PRECISION
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  DSIGMA (output) DOUBLE PRECISION array, dimension ( N )
+*         Contains a copy of the diagonal elements (K-1 singular values
+*         and one zero) in the secular equation.
+*
+*  IDX    (workspace) INTEGER array, dimension ( N )
+*         This will contain the permutation used to sort the contents of
+*         D into ascending order.
+*
+*  IDXP   (workspace) INTEGER array, dimension ( N )
+*         This will contain the permutation used to place deflated
+*         values of D at the end of the array. On output IDXP(2:K)
+*         points to the nondeflated D-values and IDXP(K+1:N)
+*         points to the deflated singular values.
+*
+*  IDXQ   (input) INTEGER array, dimension ( N )
+*         This contains the permutation which separately sorts the two
+*         sub-problems in D into ascending order.  Note that entries in
+*         the first half of this permutation must first be moved one
+*         position backward; and entries in the second half
+*         must first have NL+1 added to their values.
+*
+*  PERM   (output) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) to be applied
+*         to each singular block. Not referenced if ICOMPQ = 0.
+*
+*  GIVPTR (output) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem. Not referenced if ICOMPQ = 0.
+*
+*  GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of columns to take place
+*         in a Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGCOL (input) INTEGER
+*         The leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value to be used in the
+*         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of GIVNUM, must be at least N.
+*
+*  C      (output) DOUBLE PRECISION
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (output) DOUBLE PRECISION
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO, EIGHT
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
+     $                   EIGHT = 8.0D+0 )
+*     ..
+*     .. Local Scalars ..
+*
+      INTEGER            I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M, N,
+     $                   NLP1, NLP2
+      DOUBLE PRECISION   EPS, HLFTOL, TAU, TOL, Z1
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLAMRG, DROT, XERBLA
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLAPY2
+      EXTERNAL           DLAMCH, DLAPY2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      N = NL + NR + 1
+      M = N + SQRE
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -22
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -24
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD7', -INFO )
+         RETURN
+      END IF
+*
+      NLP1 = NL + 1
+      NLP2 = NL + 2
+      IF( ICOMPQ.EQ.1 ) THEN
+         GIVPTR = 0
+      END IF
+*
+*     Generate the first part of the vector Z and move the singular
+*     values in the first part of D one position backward.
+*
+      Z1 = ALPHA*VL( NLP1 )
+      VL( NLP1 ) = ZERO
+      TAU = VF( NLP1 )
+      DO 10 I = NL, 1, -1
+         Z( I+1 ) = ALPHA*VL( I )
+         VL( I ) = ZERO
+         VF( I+1 ) = VF( I )
+         D( I+1 ) = D( I )
+         IDXQ( I+1 ) = IDXQ( I ) + 1
+   10 CONTINUE
+      VF( 1 ) = TAU
+*
+*     Generate the second part of the vector Z.
+*
+      DO 20 I = NLP2, M
+         Z( I ) = BETA*VF( I )
+         VF( I ) = ZERO
+   20 CONTINUE
+*
+*     Sort the singular values into increasing order
+*
+      DO 30 I = NLP2, N
+         IDXQ( I ) = IDXQ( I ) + NLP1
+   30 CONTINUE
+*
+*     DSIGMA, IDXC, IDXC, and ZW are used as storage space.
+*
+      DO 40 I = 2, N
+         DSIGMA( I ) = D( IDXQ( I ) )
+         ZW( I ) = Z( IDXQ( I ) )
+         VFW( I ) = VF( IDXQ( I ) )
+         VLW( I ) = VL( IDXQ( I ) )
+   40 CONTINUE
+*
+      CALL DLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )
+*
+      DO 50 I = 2, N
+         IDXI = 1 + IDX( I )
+         D( I ) = DSIGMA( IDXI )
+         Z( I ) = ZW( IDXI )
+         VF( I ) = VFW( IDXI )
+         VL( I ) = VLW( IDXI )
+   50 CONTINUE
+*
+*     Calculate the allowable deflation tolerence
+*
+      EPS = DLAMCH( 'Epsilon' )
+      TOL = MAX( ABS( ALPHA ), ABS( BETA ) )
+      TOL = EIGHT*EIGHT*EPS*MAX( ABS( D( N ) ), TOL )
+*
+*     There are 2 kinds of deflation -- first a value in the z-vector
+*     is small, second two (or more) singular values are very close
+*     together (their difference is small).
+*
+*     If the value in the z-vector is small, we simply permute the
+*     array so that the corresponding singular value is moved to the
+*     end.
+*
+*     If two values in the D-vector are close, we perform a two-sided
+*     rotation designed to make one of the corresponding z-vector
+*     entries zero, and then permute the array so that the deflated
+*     singular value is moved to the end.
+*
+*     If there are multiple singular values then the problem deflates.
+*     Here the number of equal singular values are found.  As each equal
+*     singular value is found, an elementary reflector is computed to
+*     rotate the corresponding singular subspace so that the
+*     corresponding components of Z are zero in this new basis.
+*
+      K = 1
+      K2 = N + 1
+      DO 60 J = 2, N
+         IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*           Deflate due to small z component.
+*
+            K2 = K2 - 1
+            IDXP( K2 ) = J
+            IF( J.EQ.N )
+     $         GO TO 100
+         ELSE
+            JPREV = J
+            GO TO 70
+         END IF
+   60 CONTINUE
+   70 CONTINUE
+      J = JPREV
+   80 CONTINUE
+      J = J + 1
+      IF( J.GT.N )
+     $   GO TO 90
+      IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*        Deflate due to small z component.
+*
+         K2 = K2 - 1
+         IDXP( K2 ) = J
+      ELSE
+*
+*        Check if singular values are close enough to allow deflation.
+*
+         IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN
+*
+*           Deflation is possible.
+*
+            S = Z( JPREV )
+            C = Z( J )
+*
+*           Find sqrt(a**2+b**2) without overflow or
+*           destructive underflow.
+*
+            TAU = DLAPY2( C, S )
+            Z( J ) = TAU
+            Z( JPREV ) = ZERO
+            C = C / TAU
+            S = -S / TAU
+*
+*           Record the appropriate Givens rotation
+*
+            IF( ICOMPQ.EQ.1 ) THEN
+               GIVPTR = GIVPTR + 1
+               IDXJP = IDXQ( IDX( JPREV )+1 )
+               IDXJ = IDXQ( IDX( J )+1 )
+               IF( IDXJP.LE.NLP1 ) THEN
+                  IDXJP = IDXJP - 1
+               END IF
+               IF( IDXJ.LE.NLP1 ) THEN
+                  IDXJ = IDXJ - 1
+               END IF
+               GIVCOL( GIVPTR, 2 ) = IDXJP
+               GIVCOL( GIVPTR, 1 ) = IDXJ
+               GIVNUM( GIVPTR, 2 ) = C
+               GIVNUM( GIVPTR, 1 ) = S
+            END IF
+            CALL DROT( 1, VF( JPREV ), 1, VF( J ), 1, C, S )
+            CALL DROT( 1, VL( JPREV ), 1, VL( J ), 1, C, S )
+            K2 = K2 - 1
+            IDXP( K2 ) = JPREV
+            JPREV = J
+         ELSE
+            K = K + 1
+            ZW( K ) = Z( JPREV )
+            DSIGMA( K ) = D( JPREV )
+            IDXP( K ) = JPREV
+            JPREV = J
+         END IF
+      END IF
+      GO TO 80
+   90 CONTINUE
+*
+*     Record the last singular value.
+*
+      K = K + 1
+      ZW( K ) = Z( JPREV )
+      DSIGMA( K ) = D( JPREV )
+      IDXP( K ) = JPREV
+*
+  100 CONTINUE
+*
+*     Sort the singular values into DSIGMA. The singular values which
+*     were not deflated go into the first K slots of DSIGMA, except
+*     that DSIGMA(1) is treated separately.
+*
+      DO 110 J = 2, N
+         JP = IDXP( J )
+         DSIGMA( J ) = D( JP )
+         VFW( J ) = VF( JP )
+         VLW( J ) = VL( JP )
+  110 CONTINUE
+      IF( ICOMPQ.EQ.1 ) THEN
+         DO 120 J = 2, N
+            JP = IDXP( J )
+            PERM( J ) = IDXQ( IDX( JP )+1 )
+            IF( PERM( J ).LE.NLP1 ) THEN
+               PERM( J ) = PERM( J ) - 1
+            END IF
+  120    CONTINUE
+      END IF
+*
+*     The deflated singular values go back into the last N - K slots of
+*     D.
+*
+      CALL DCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 )
+*
+*     Determine DSIGMA(1), DSIGMA(2), Z(1), VF(1), VL(1), VF(M), and
+*     VL(M).
+*
+      DSIGMA( 1 ) = ZERO
+      HLFTOL = TOL / TWO
+      IF( ABS( DSIGMA( 2 ) ).LE.HLFTOL )
+     $   DSIGMA( 2 ) = HLFTOL
+      IF( M.GT.N ) THEN
+         Z( 1 ) = DLAPY2( Z1, Z( M ) )
+         IF( Z( 1 ).LE.TOL ) THEN
+            C = ONE
+            S = ZERO
+            Z( 1 ) = TOL
+         ELSE
+            C = Z1 / Z( 1 )
+            S = -Z( M ) / Z( 1 )
+         END IF
+         CALL DROT( 1, VF( M ), 1, VF( 1 ), 1, C, S )
+         CALL DROT( 1, VL( M ), 1, VL( 1 ), 1, C, S )
+      ELSE
+         IF( ABS( Z1 ).LE.TOL ) THEN
+            Z( 1 ) = TOL
+         ELSE
+            Z( 1 ) = Z1
+         END IF
+      END IF
+*
+*     Restore Z, VF, and VL.
+*
+      CALL DCOPY( K-1, ZW( 2 ), 1, Z( 2 ), 1 )
+      CALL DCOPY( N-1, VFW( 2 ), 1, VF( 2 ), 1 )
+      CALL DCOPY( N-1, VLW( 2 ), 1, VL( 2 ), 1 )
+*
+      RETURN
+*
+*     End of DLASD7
+*
+      END
diff --git a/libcruft/lapack/dlasd8.f b/libcruft/lapack/dlasd8.f
new file mode 100644
index 0000000..4121519
--- /dev/null
+++ b/libcruft/lapack/dlasd8.f
@@ -0,0 +1,253 @@
+      SUBROUTINE DLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDDIFR,
+     $                   DSIGMA, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, K, LDDIFR
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), DIFL( * ), DIFR( LDDIFR, * ),
+     $                   DSIGMA( * ), VF( * ), VL( * ), WORK( * ),
+     $                   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASD8 finds the square roots of the roots of the secular equation,
+*  as defined by the values in DSIGMA and Z. It makes the appropriate
+*  calls to DLASD4, and stores, for each  element in D, the distance
+*  to its two nearest poles (elements in DSIGMA). It also updates
+*  the arrays VF and VL, the first and last components of all the
+*  right singular vectors of the original bidiagonal matrix.
+*
+*  DLASD8 is called from DLASD6.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ  (input) INTEGER
+*          Specifies whether singular vectors are to be computed in
+*          factored form in the calling routine:
+*          = 0: Compute singular values only.
+*          = 1: Compute singular vectors in factored form as well.
+*
+*  K       (input) INTEGER
+*          The number of terms in the rational function to be solved
+*          by DLASD4.  K >= 1.
+*
+*  D       (output) DOUBLE PRECISION array, dimension ( K )
+*          On output, D contains the updated singular values.
+*
+*  Z       (input) DOUBLE PRECISION array, dimension ( K )
+*          The first K elements of this array contain the components
+*          of the deflation-adjusted updating row vector.
+*
+*  VF      (input/output) DOUBLE PRECISION array, dimension ( K )
+*          On entry, VF contains  information passed through DBEDE8.
+*          On exit, VF contains the first K components of the first
+*          components of all right singular vectors of the bidiagonal
+*          matrix.
+*
+*  VL      (input/output) DOUBLE PRECISION array, dimension ( K )
+*          On entry, VL contains  information passed through DBEDE8.
+*          On exit, VL contains the first K components of the last
+*          components of all right singular vectors of the bidiagonal
+*          matrix.
+*
+*  DIFL    (output) DOUBLE PRECISION array, dimension ( K )
+*          On exit, DIFL(I) = D(I) - DSIGMA(I).
+*
+*  DIFR    (output) DOUBLE PRECISION array,
+*                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
+*                   dimension ( K ) if ICOMPQ = 0.
+*          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
+*          defined and will not be referenced.
+*
+*          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
+*          normalizing factors for the right singular vector matrix.
+*
+*  LDDIFR  (input) INTEGER
+*          The leading dimension of DIFR, must be at least K.
+*
+*  DSIGMA  (input) DOUBLE PRECISION array, dimension ( K )
+*          The first K elements of this array contain the old roots
+*          of the deflated updating problem.  These are the poles
+*          of the secular equation.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension at least 3 * K
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IWK1, IWK2, IWK2I, IWK3, IWK3I, J
+      DOUBLE PRECISION   DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, RHO, TEMP
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLASCL, DLASD4, DLASET, XERBLA
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DDOT, DLAMC3, DNRM2
+      EXTERNAL           DDOT, DLAMC3, DNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( K.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( LDDIFR.LT.K ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASD8', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( K.EQ.1 ) THEN
+         D( 1 ) = ABS( Z( 1 ) )
+         DIFL( 1 ) = D( 1 )
+         IF( ICOMPQ.EQ.1 ) THEN
+            DIFL( 2 ) = ONE
+            DIFR( 1, 2 ) = ONE
+         END IF
+         RETURN
+      END IF
+*
+*     Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
+*     be computed with high relative accuracy (barring over/underflow).
+*     This is a problem on machines without a guard digit in
+*     add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
+*     The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
+*     which on any of these machines zeros out the bottommost
+*     bit of DSIGMA(I) if it is 1; this makes the subsequent
+*     subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
+*     occurs. On binary machines with a guard digit (almost all
+*     machines) it does not change DSIGMA(I) at all. On hexadecimal
+*     and decimal machines with a guard digit, it slightly
+*     changes the bottommost bits of DSIGMA(I). It does not account
+*     for hexadecimal or decimal machines without guard digits
+*     (we know of none). We use a subroutine call to compute
+*     2*DSIGMA(I) to prevent optimizing compilers from eliminating
+*     this code.
+*
+      DO 10 I = 1, K
+         DSIGMA( I ) = DLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )
+   10 CONTINUE
+*
+*     Book keeping.
+*
+      IWK1 = 1
+      IWK2 = IWK1 + K
+      IWK3 = IWK2 + K
+      IWK2I = IWK2 - 1
+      IWK3I = IWK3 - 1
+*
+*     Normalize Z.
+*
+      RHO = DNRM2( K, Z, 1 )
+      CALL DLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )
+      RHO = RHO*RHO
+*
+*     Initialize WORK(IWK3).
+*
+      CALL DLASET( 'A', K, 1, ONE, ONE, WORK( IWK3 ), K )
+*
+*     Compute the updated singular values, the arrays DIFL, DIFR,
+*     and the updated Z.
+*
+      DO 40 J = 1, K
+         CALL DLASD4( K, J, DSIGMA, Z, WORK( IWK1 ), RHO, D( J ),
+     $                WORK( IWK2 ), INFO )
+*
+*        If the root finder fails, the computation is terminated.
+*
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         WORK( IWK3I+J ) = WORK( IWK3I+J )*WORK( J )*WORK( IWK2I+J )
+         DIFL( J ) = -WORK( J )
+         DIFR( J, 1 ) = -WORK( J+1 )
+         DO 20 I = 1, J - 1
+            WORK( IWK3I+I ) = WORK( IWK3I+I )*WORK( I )*
+     $                        WORK( IWK2I+I ) / ( DSIGMA( I )-
+     $                        DSIGMA( J ) ) / ( DSIGMA( I )+
+     $                        DSIGMA( J ) )
+   20    CONTINUE
+         DO 30 I = J + 1, K
+            WORK( IWK3I+I ) = WORK( IWK3I+I )*WORK( I )*
+     $                        WORK( IWK2I+I ) / ( DSIGMA( I )-
+     $                        DSIGMA( J ) ) / ( DSIGMA( I )+
+     $                        DSIGMA( J ) )
+   30    CONTINUE
+   40 CONTINUE
+*
+*     Compute updated Z.
+*
+      DO 50 I = 1, K
+         Z( I ) = SIGN( SQRT( ABS( WORK( IWK3I+I ) ) ), Z( I ) )
+   50 CONTINUE
+*
+*     Update VF and VL.
+*
+      DO 80 J = 1, K
+         DIFLJ = DIFL( J )
+         DJ = D( J )
+         DSIGJ = -DSIGMA( J )
+         IF( J.LT.K ) THEN
+            DIFRJ = -DIFR( J, 1 )
+            DSIGJP = -DSIGMA( J+1 )
+         END IF
+         WORK( J ) = -Z( J ) / DIFLJ / ( DSIGMA( J )+DJ )
+         DO 60 I = 1, J - 1
+            WORK( I ) = Z( I ) / ( DLAMC3( DSIGMA( I ), DSIGJ )-DIFLJ )
+     $                   / ( DSIGMA( I )+DJ )
+   60    CONTINUE
+         DO 70 I = J + 1, K
+            WORK( I ) = Z( I ) / ( DLAMC3( DSIGMA( I ), DSIGJP )+DIFRJ )
+     $                   / ( DSIGMA( I )+DJ )
+   70    CONTINUE
+         TEMP = DNRM2( K, WORK, 1 )
+         WORK( IWK2I+J ) = DDOT( K, WORK, 1, VF, 1 ) / TEMP
+         WORK( IWK3I+J ) = DDOT( K, WORK, 1, VL, 1 ) / TEMP
+         IF( ICOMPQ.EQ.1 ) THEN
+            DIFR( J, 2 ) = TEMP
+         END IF
+   80 CONTINUE
+*
+      CALL DCOPY( K, WORK( IWK2 ), 1, VF, 1 )
+      CALL DCOPY( K, WORK( IWK3 ), 1, VL, 1 )
+*
+      RETURN
+*
+*     End of DLASD8
+*
+      END
diff --git a/libcruft/lapack/dlasda.f b/libcruft/lapack/dlasda.f
new file mode 100644
index 0000000..fe8f33e
--- /dev/null
+++ b/libcruft/lapack/dlasda.f
@@ -0,0 +1,390 @@
+      SUBROUTINE DLASDA( ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT, K,
+     $                   DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL,
+     $                   PERM, GIVNUM, C, S, WORK, IWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
+     $                   K( * ), PERM( LDGCOL, * )
+      DOUBLE PRECISION   C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),
+     $                   E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),
+     $                   S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),
+     $                   Z( LDU, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Using a divide and conquer approach, DLASDA computes the singular
+*  value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
+*  B with diagonal D and offdiagonal E, where M = N + SQRE. The
+*  algorithm computes the singular values in the SVD B = U * S * VT.
+*  The orthogonal matrices U and VT are optionally computed in
+*  compact form.
+*
+*  A related subroutine, DLASD0, computes the singular values and
+*  the singular vectors in explicit form.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed
+*         in compact form, as follows
+*         = 0: Compute singular values only.
+*         = 1: Compute singular vectors of upper bidiagonal
+*              matrix in compact form.
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The row dimension of the upper bidiagonal matrix. This is
+*         also the dimension of the main diagonal array D.
+*
+*  SQRE   (input) INTEGER
+*         Specifies the column dimension of the bidiagonal matrix.
+*         = 0: The bidiagonal matrix has column dimension M = N;
+*         = 1: The bidiagonal matrix has column dimension M = N + 1.
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension ( N )
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix. On exit D, if INFO = 0, contains its singular values.
+*
+*  E      (input) DOUBLE PRECISION array, dimension ( M-1 )
+*         Contains the subdiagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  U      (output) DOUBLE PRECISION array,
+*         dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
+*         singular vector matrices of all subproblems at the bottom
+*         level.
+*
+*  LDU    (input) INTEGER, LDU = > N.
+*         The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
+*         GIVNUM, and Z.
+*
+*  VT     (output) DOUBLE PRECISION array,
+*         dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT' contains the right
+*         singular vector matrices of all subproblems at the bottom
+*         level.
+*
+*  K      (output) INTEGER array,
+*         dimension ( N ) if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
+*         If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
+*         secular equation on the computation tree.
+*
+*  DIFL   (output) DOUBLE PRECISION array, dimension ( LDU, NLVL ),
+*         where NLVL = floor(log_2 (N/SMLSIZ))).
+*
+*  DIFR   (output) DOUBLE PRECISION array,
+*                  dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
+*                  dimension ( N ) if ICOMPQ = 0.
+*         If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
+*         record distances between singular values on the I-th
+*         level and singular values on the (I -1)-th level, and
+*         DIFR(1:N, 2 * I ) contains the normalizing factors for
+*         the right singular vector matrix. See DLASD8 for details.
+*
+*  Z      (output) DOUBLE PRECISION array,
+*                  dimension ( LDU, NLVL ) if ICOMPQ = 1 and
+*                  dimension ( N ) if ICOMPQ = 0.
+*         The first K elements of Z(1, I) contain the components of
+*         the deflation-adjusted updating row vector for subproblems
+*         on the I-th level.
+*
+*  POLES  (output) DOUBLE PRECISION array,
+*         dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
+*         POLES(1, 2*I) contain  the new and old singular values
+*         involved in the secular equations on the I-th level.
+*
+*  GIVPTR (output) INTEGER array,
+*         dimension ( N ) if ICOMPQ = 1, and not referenced if
+*         ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
+*         the number of Givens rotations performed on the I-th
+*         problem on the computation tree.
+*
+*  GIVCOL (output) INTEGER array,
+*         dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
+*         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
+*         GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
+*         of Givens rotations performed on the I-th level on the
+*         computation tree.
+*
+*  LDGCOL (input) INTEGER, LDGCOL = > N.
+*         The leading dimension of arrays GIVCOL and PERM.
+*
+*  PERM   (output) INTEGER array,
+*         dimension ( LDGCOL, NLVL ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
+*         permutations done on the I-th level of the computation tree.
+*
+*  GIVNUM (output) DOUBLE PRECISION array,
+*         dimension ( LDU,  2 * NLVL ) if ICOMPQ = 1, and not
+*         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
+*         GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
+*         values of Givens rotations performed on the I-th level on
+*         the computation tree.
+*
+*  C      (output) DOUBLE PRECISION array,
+*         dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
+*         If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
+*         C( I ) contains the C-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  S      (output) DOUBLE PRECISION array, dimension ( N ) if
+*         ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
+*         and the I-th subproblem is not square, on exit, S( I )
+*         contains the S-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  WORK   (workspace) DOUBLE PRECISION array, dimension
+*         (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
+*
+*  IWORK  (workspace) INTEGER array.
+*         Dimension must be at least (7 * N).
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IDXQ, IDXQI, IM1, INODE, ITEMP, IWK,
+     $                   J, LF, LL, LVL, LVL2, M, NCC, ND, NDB1, NDIML,
+     $                   NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, NRU,
+     $                   NWORK1, NWORK2, SMLSZP, SQREI, VF, VFI, VL, VLI
+      DOUBLE PRECISION   ALPHA, BETA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLASD6, DLASDQ, DLASDT, DLASET, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      ELSE IF( LDU.LT.( N+SQRE ) ) THEN
+         INFO = -8
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -17
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASDA', -INFO )
+         RETURN
+      END IF
+*
+      M = N + SQRE
+*
+*     If the input matrix is too small, call DLASDQ to find the SVD.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         IF( ICOMPQ.EQ.0 ) THEN
+            CALL DLASDQ( 'U', SQRE, N, 0, 0, 0, D, E, VT, LDU, U, LDU,
+     $                   U, LDU, WORK, INFO )
+         ELSE
+            CALL DLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDU, U, LDU,
+     $                   U, LDU, WORK, INFO )
+         END IF
+         RETURN
+      END IF
+*
+*     Book-keeping and  set up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+      IDXQ = NDIMR + N
+      IWK = IDXQ + N
+*
+      NCC = 0
+      NRU = 0
+*
+      SMLSZP = SMLSIZ + 1
+      VF = 1
+      VL = VF + M
+      NWORK1 = VL + M
+      NWORK2 = NWORK1 + SMLSZP*SMLSZP
+*
+      CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     for the nodes on bottom level of the tree, solve
+*     their subproblems by DLASDQ.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 30 I = NDB1, ND
+*
+*        IC : center row of each node
+*        NL : number of rows of left  subproblem
+*        NR : number of rows of right subproblem
+*        NLF: starting row of the left   subproblem
+*        NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NLP1 = NL + 1
+         NR = IWORK( NDIMR+I1 )
+         NLF = IC - NL
+         NRF = IC + 1
+         IDXQI = IDXQ + NLF - 2
+         VFI = VF + NLF - 1
+         VLI = VL + NLF - 1
+         SQREI = 1
+         IF( ICOMPQ.EQ.0 ) THEN
+            CALL DLASET( 'A', NLP1, NLP1, ZERO, ONE, WORK( NWORK1 ),
+     $                   SMLSZP )
+            CALL DLASDQ( 'U', SQREI, NL, NLP1, NRU, NCC, D( NLF ),
+     $                   E( NLF ), WORK( NWORK1 ), SMLSZP,
+     $                   WORK( NWORK2 ), NL, WORK( NWORK2 ), NL,
+     $                   WORK( NWORK2 ), INFO )
+            ITEMP = NWORK1 + NL*SMLSZP
+            CALL DCOPY( NLP1, WORK( NWORK1 ), 1, WORK( VFI ), 1 )
+            CALL DCOPY( NLP1, WORK( ITEMP ), 1, WORK( VLI ), 1 )
+         ELSE
+            CALL DLASET( 'A', NL, NL, ZERO, ONE, U( NLF, 1 ), LDU )
+            CALL DLASET( 'A', NLP1, NLP1, ZERO, ONE, VT( NLF, 1 ), LDU )
+            CALL DLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ),
+     $                   E( NLF ), VT( NLF, 1 ), LDU, U( NLF, 1 ), LDU,
+     $                   U( NLF, 1 ), LDU, WORK( NWORK1 ), INFO )
+            CALL DCOPY( NLP1, VT( NLF, 1 ), 1, WORK( VFI ), 1 )
+            CALL DCOPY( NLP1, VT( NLF, NLP1 ), 1, WORK( VLI ), 1 )
+         END IF
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         DO 10 J = 1, NL
+            IWORK( IDXQI+J ) = J
+   10    CONTINUE
+         IF( ( I.EQ.ND ) .AND. ( SQRE.EQ.0 ) ) THEN
+            SQREI = 0
+         ELSE
+            SQREI = 1
+         END IF
+         IDXQI = IDXQI + NLP1
+         VFI = VFI + NLP1
+         VLI = VLI + NLP1
+         NRP1 = NR + SQREI
+         IF( ICOMPQ.EQ.0 ) THEN
+            CALL DLASET( 'A', NRP1, NRP1, ZERO, ONE, WORK( NWORK1 ),
+     $                   SMLSZP )
+            CALL DLASDQ( 'U', SQREI, NR, NRP1, NRU, NCC, D( NRF ),
+     $                   E( NRF ), WORK( NWORK1 ), SMLSZP,
+     $                   WORK( NWORK2 ), NR, WORK( NWORK2 ), NR,
+     $                   WORK( NWORK2 ), INFO )
+            ITEMP = NWORK1 + ( NRP1-1 )*SMLSZP
+            CALL DCOPY( NRP1, WORK( NWORK1 ), 1, WORK( VFI ), 1 )
+            CALL DCOPY( NRP1, WORK( ITEMP ), 1, WORK( VLI ), 1 )
+         ELSE
+            CALL DLASET( 'A', NR, NR, ZERO, ONE, U( NRF, 1 ), LDU )
+            CALL DLASET( 'A', NRP1, NRP1, ZERO, ONE, VT( NRF, 1 ), LDU )
+            CALL DLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ),
+     $                   E( NRF ), VT( NRF, 1 ), LDU, U( NRF, 1 ), LDU,
+     $                   U( NRF, 1 ), LDU, WORK( NWORK1 ), INFO )
+            CALL DCOPY( NRP1, VT( NRF, 1 ), 1, WORK( VFI ), 1 )
+            CALL DCOPY( NRP1, VT( NRF, NRP1 ), 1, WORK( VLI ), 1 )
+         END IF
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         DO 20 J = 1, NR
+            IWORK( IDXQI+J ) = J
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Now conquer each subproblem bottom-up.
+*
+      J = 2**NLVL
+      DO 50 LVL = NLVL, 1, -1
+         LVL2 = LVL*2 - 1
+*
+*        Find the first node LF and last node LL on
+*        the current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 40 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            IF( I.EQ.LL ) THEN
+               SQREI = SQRE
+            ELSE
+               SQREI = 1
+            END IF
+            VFI = VF + NLF - 1
+            VLI = VL + NLF - 1
+            IDXQI = IDXQ + NLF - 1
+            ALPHA = D( IC )
+            BETA = E( IC )
+            IF( ICOMPQ.EQ.0 ) THEN
+               CALL DLASD6( ICOMPQ, NL, NR, SQREI, D( NLF ),
+     $                      WORK( VFI ), WORK( VLI ), ALPHA, BETA,
+     $                      IWORK( IDXQI ), PERM, GIVPTR( 1 ), GIVCOL,
+     $                      LDGCOL, GIVNUM, LDU, POLES, DIFL, DIFR, Z,
+     $                      K( 1 ), C( 1 ), S( 1 ), WORK( NWORK1 ),
+     $                      IWORK( IWK ), INFO )
+            ELSE
+               J = J - 1
+               CALL DLASD6( ICOMPQ, NL, NR, SQREI, D( NLF ),
+     $                      WORK( VFI ), WORK( VLI ), ALPHA, BETA,
+     $                      IWORK( IDXQI ), PERM( NLF, LVL ),
+     $                      GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                      GIVNUM( NLF, LVL2 ), LDU,
+     $                      POLES( NLF, LVL2 ), DIFL( NLF, LVL ),
+     $                      DIFR( NLF, LVL2 ), Z( NLF, LVL ), K( J ),
+     $                      C( J ), S( J ), WORK( NWORK1 ),
+     $                      IWORK( IWK ), INFO )
+            END IF
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+   40    CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of DLASDA
+*
+      END
diff --git a/libcruft/lapack/dlasdq.f b/libcruft/lapack/dlasdq.f
new file mode 100644
index 0000000..08f7e8f
--- /dev/null
+++ b/libcruft/lapack/dlasdq.f
@@ -0,0 +1,316 @@
+      SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
+     $                   U, LDU, C, LDC, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( LDC, * ), D( * ), E( * ), U( LDU, * ),
+     $                   VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASDQ computes the singular value decomposition (SVD) of a real
+*  (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
+*  E, accumulating the transformations if desired. Letting B denote
+*  the input bidiagonal matrix, the algorithm computes orthogonal
+*  matrices Q and P such that B = Q * S * P' (P' denotes the transpose
+*  of P). The singular values S are overwritten on D.
+*
+*  The input matrix U  is changed to U  * Q  if desired.
+*  The input matrix VT is changed to P' * VT if desired.
+*  The input matrix C  is changed to Q' * C  if desired.
+*
+*  See "Computing  Small Singular Values of Bidiagonal Matrices With
+*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
+*  LAPACK Working Note #3, for a detailed description of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO  (input) CHARACTER*1
+*        On entry, UPLO specifies whether the input bidiagonal matrix
+*        is upper or lower bidiagonal, and wether it is square are
+*        not.
+*           UPLO = 'U' or 'u'   B is upper bidiagonal.
+*           UPLO = 'L' or 'l'   B is lower bidiagonal.
+*
+*  SQRE  (input) INTEGER
+*        = 0: then the input matrix is N-by-N.
+*        = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
+*             (N+1)-by-N if UPLU = 'L'.
+*
+*        The bidiagonal matrix has
+*        N = NL + NR + 1 rows and
+*        M = N + SQRE >= N columns.
+*
+*  N     (input) INTEGER
+*        On entry, N specifies the number of rows and columns
+*        in the matrix. N must be at least 0.
+*
+*  NCVT  (input) INTEGER
+*        On entry, NCVT specifies the number of columns of
+*        the matrix VT. NCVT must be at least 0.
+*
+*  NRU   (input) INTEGER
+*        On entry, NRU specifies the number of rows of
+*        the matrix U. NRU must be at least 0.
+*
+*  NCC   (input) INTEGER
+*        On entry, NCC specifies the number of columns of
+*        the matrix C. NCC must be at least 0.
+*
+*  D     (input/output) DOUBLE PRECISION array, dimension (N)
+*        On entry, D contains the diagonal entries of the
+*        bidiagonal matrix whose SVD is desired. On normal exit,
+*        D contains the singular values in ascending order.
+*
+*  E     (input/output) DOUBLE PRECISION array.
+*        dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
+*        On entry, the entries of E contain the offdiagonal entries
+*        of the bidiagonal matrix whose SVD is desired. On normal
+*        exit, E will contain 0. If the algorithm does not converge,
+*        D and E will contain the diagonal and superdiagonal entries
+*        of a bidiagonal matrix orthogonally equivalent to the one
+*        given as input.
+*
+*  VT    (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)
+*        On entry, contains a matrix which on exit has been
+*        premultiplied by P', dimension N-by-NCVT if SQRE = 0
+*        and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
+*
+*  LDVT  (input) INTEGER
+*        On entry, LDVT specifies the leading dimension of VT as
+*        declared in the calling (sub) program. LDVT must be at
+*        least 1. If NCVT is nonzero LDVT must also be at least N.
+*
+*  U     (input/output) DOUBLE PRECISION array, dimension (LDU, N)
+*        On entry, contains a  matrix which on exit has been
+*        postmultiplied by Q, dimension NRU-by-N if SQRE = 0
+*        and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
+*
+*  LDU   (input) INTEGER
+*        On entry, LDU  specifies the leading dimension of U as
+*        declared in the calling (sub) program. LDU must be at
+*        least max( 1, NRU ) .
+*
+*  C     (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)
+*        On entry, contains an N-by-NCC matrix which on exit
+*        has been premultiplied by Q'  dimension N-by-NCC if SQRE = 0
+*        and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
+*
+*  LDC   (input) INTEGER
+*        On entry, LDC  specifies the leading dimension of C as
+*        declared in the calling (sub) program. LDC must be at
+*        least 1. If NCC is nonzero, LDC must also be at least N.
+*
+*  WORK  (workspace) DOUBLE PRECISION array, dimension (4*N)
+*        Workspace. Only referenced if one of NCVT, NRU, or NCC is
+*        nonzero, and if N is at least 2.
+*
+*  INFO  (output) INTEGER
+*        On exit, a value of 0 indicates a successful exit.
+*        If INFO < 0, argument number -INFO is illegal.
+*        If INFO > 0, the algorithm did not converge, and INFO
+*        specifies how many superdiagonals did not converge.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ROTATE
+      INTEGER            I, ISUB, IUPLO, J, NP1, SQRE1
+      DOUBLE PRECISION   CS, R, SMIN, SN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DBDSQR, DLARTG, DLASR, DSWAP, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IUPLO = 0
+      IF( LSAME( UPLO, 'U' ) )
+     $   IUPLO = 1
+      IF( LSAME( UPLO, 'L' ) )
+     $   IUPLO = 2
+      IF( IUPLO.EQ.0 ) THEN
+         INFO = -1
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NCVT.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRU.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( NCC.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
+     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
+         INFO = -10
+      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
+         INFO = -12
+      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
+     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
+         INFO = -14
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASDQ', -INFO )
+         RETURN
+      END IF
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     ROTATE is true if any singular vectors desired, false otherwise
+*
+      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
+      NP1 = N + 1
+      SQRE1 = SQRE
+*
+*     If matrix non-square upper bidiagonal, rotate to be lower
+*     bidiagonal.  The rotations are on the right.
+*
+      IF( ( IUPLO.EQ.1 ) .AND. ( SQRE1.EQ.1 ) ) THEN
+         DO 10 I = 1, N - 1
+            CALL DLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( ROTATE ) THEN
+               WORK( I ) = CS
+               WORK( N+I ) = SN
+            END IF
+   10    CONTINUE
+         CALL DLARTG( D( N ), E( N ), CS, SN, R )
+         D( N ) = R
+         E( N ) = ZERO
+         IF( ROTATE ) THEN
+            WORK( N ) = CS
+            WORK( N+N ) = SN
+         END IF
+         IUPLO = 2
+         SQRE1 = 0
+*
+*        Update singular vectors if desired.
+*
+         IF( NCVT.GT.0 )
+     $      CALL DLASR( 'L', 'V', 'F', NP1, NCVT, WORK( 1 ),
+     $                  WORK( NP1 ), VT, LDVT )
+      END IF
+*
+*     If matrix lower bidiagonal, rotate to be upper bidiagonal
+*     by applying Givens rotations on the left.
+*
+      IF( IUPLO.EQ.2 ) THEN
+         DO 20 I = 1, N - 1
+            CALL DLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( ROTATE ) THEN
+               WORK( I ) = CS
+               WORK( N+I ) = SN
+            END IF
+   20    CONTINUE
+*
+*        If matrix (N+1)-by-N lower bidiagonal, one additional
+*        rotation is needed.
+*
+         IF( SQRE1.EQ.1 ) THEN
+            CALL DLARTG( D( N ), E( N ), CS, SN, R )
+            D( N ) = R
+            IF( ROTATE ) THEN
+               WORK( N ) = CS
+               WORK( N+N ) = SN
+            END IF
+         END IF
+*
+*        Update singular vectors if desired.
+*
+         IF( NRU.GT.0 ) THEN
+            IF( SQRE1.EQ.0 ) THEN
+               CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ),
+     $                     WORK( NP1 ), U, LDU )
+            ELSE
+               CALL DLASR( 'R', 'V', 'F', NRU, NP1, WORK( 1 ),
+     $                     WORK( NP1 ), U, LDU )
+            END IF
+         END IF
+         IF( NCC.GT.0 ) THEN
+            IF( SQRE1.EQ.0 ) THEN
+               CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ),
+     $                     WORK( NP1 ), C, LDC )
+            ELSE
+               CALL DLASR( 'L', 'V', 'F', NP1, NCC, WORK( 1 ),
+     $                     WORK( NP1 ), C, LDC )
+            END IF
+         END IF
+      END IF
+*
+*     Call DBDSQR to compute the SVD of the reduced real
+*     N-by-N upper bidiagonal matrix.
+*
+      CALL DBDSQR( 'U', N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C,
+     $             LDC, WORK, INFO )
+*
+*     Sort the singular values into ascending order (insertion sort on
+*     singular values, but only one transposition per singular vector)
+*
+      DO 40 I = 1, N
+*
+*        Scan for smallest D(I).
+*
+         ISUB = I
+         SMIN = D( I )
+         DO 30 J = I + 1, N
+            IF( D( J ).LT.SMIN ) THEN
+               ISUB = J
+               SMIN = D( J )
+            END IF
+   30    CONTINUE
+         IF( ISUB.NE.I ) THEN
+*
+*           Swap singular values and vectors.
+*
+            D( ISUB ) = D( I )
+            D( I ) = SMIN
+            IF( NCVT.GT.0 )
+     $         CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( I, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, I ), 1 )
+            IF( NCC.GT.0 )
+     $         CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( I, 1 ), LDC )
+         END IF
+   40 CONTINUE
+*
+      RETURN
+*
+*     End of DLASDQ
+*
+      END
diff --git a/libcruft/lapack/dlasdt.f b/libcruft/lapack/dlasdt.f
new file mode 100644
index 0000000..b2b8eee
--- /dev/null
+++ b/libcruft/lapack/dlasdt.f
@@ -0,0 +1,105 @@
+      SUBROUTINE DLASDT( N, LVL, ND, INODE, NDIML, NDIMR, MSUB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LVL, MSUB, N, ND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            INODE( * ), NDIML( * ), NDIMR( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASDT creates a tree of subproblems for bidiagonal divide and
+*  conquer.
+*
+*  Arguments
+*  =========
+*
+*   N      (input) INTEGER
+*          On entry, the number of diagonal elements of the
+*          bidiagonal matrix.
+*
+*   LVL    (output) INTEGER
+*          On exit, the number of levels on the computation tree.
+*
+*   ND     (output) INTEGER
+*          On exit, the number of nodes on the tree.
+*
+*   INODE  (output) INTEGER array, dimension ( N )
+*          On exit, centers of subproblems.
+*
+*   NDIML  (output) INTEGER array, dimension ( N )
+*          On exit, row dimensions of left children.
+*
+*   NDIMR  (output) INTEGER array, dimension ( N )
+*          On exit, row dimensions of right children.
+*
+*   MSUB   (input) INTEGER.
+*          On entry, the maximum row dimension each subproblem at the
+*          bottom of the tree can be of.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IL, IR, LLST, MAXN, NCRNT, NLVL
+      DOUBLE PRECISION   TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, INT, LOG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Find the number of levels on the tree.
+*
+      MAXN = MAX( 1, N )
+      TEMP = LOG( DBLE( MAXN ) / DBLE( MSUB+1 ) ) / LOG( TWO )
+      LVL = INT( TEMP ) + 1
+*
+      I = N / 2
+      INODE( 1 ) = I + 1
+      NDIML( 1 ) = I
+      NDIMR( 1 ) = N - I - 1
+      IL = 0
+      IR = 1
+      LLST = 1
+      DO 20 NLVL = 1, LVL - 1
+*
+*        Constructing the tree at (NLVL+1)-st level. The number of
+*        nodes created on this level is LLST * 2.
+*
+         DO 10 I = 0, LLST - 1
+            IL = IL + 2
+            IR = IR + 2
+            NCRNT = LLST + I
+            NDIML( IL ) = NDIML( NCRNT ) / 2
+            NDIMR( IL ) = NDIML( NCRNT ) - NDIML( IL ) - 1
+            INODE( IL ) = INODE( NCRNT ) - NDIMR( IL ) - 1
+            NDIML( IR ) = NDIMR( NCRNT ) / 2
+            NDIMR( IR ) = NDIMR( NCRNT ) - NDIML( IR ) - 1
+            INODE( IR ) = INODE( NCRNT ) + NDIML( IR ) + 1
+   10    CONTINUE
+         LLST = LLST*2
+   20 CONTINUE
+      ND = LLST*2 - 1
+*
+      RETURN
+*
+*     End of DLASDT
+*
+      END
diff --git a/libcruft/lapack/dlaset.f b/libcruft/lapack/dlaset.f
new file mode 100644
index 0000000..fc7bc2f
--- /dev/null
+++ b/libcruft/lapack/dlaset.f
@@ -0,0 +1,114 @@
+      SUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, M, N
+      DOUBLE PRECISION   ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASET initializes an m-by-n matrix A to BETA on the diagonal and
+*  ALPHA on the offdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be set.
+*          = 'U':      Upper triangular part is set; the strictly lower
+*                      triangular part of A is not changed.
+*          = 'L':      Lower triangular part is set; the strictly upper
+*                      triangular part of A is not changed.
+*          Otherwise:  All of the matrix A is set.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  ALPHA   (input) DOUBLE PRECISION
+*          The constant to which the offdiagonal elements are to be set.
+*
+*  BETA    (input) DOUBLE PRECISION
+*          The constant to which the diagonal elements are to be set.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On exit, the leading m-by-n submatrix of A is set as follows:
+*
+*          if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n,
+*          if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n,
+*          otherwise,     A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j,
+*
+*          and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Set the strictly upper triangular or trapezoidal part of the
+*        array to ALPHA.
+*
+         DO 20 J = 2, N
+            DO 10 I = 1, MIN( J-1, M )
+               A( I, J ) = ALPHA
+   10       CONTINUE
+   20    CONTINUE
+*
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+*
+*        Set the strictly lower triangular or trapezoidal part of the
+*        array to ALPHA.
+*
+         DO 40 J = 1, MIN( M, N )
+            DO 30 I = J + 1, M
+               A( I, J ) = ALPHA
+   30       CONTINUE
+   40    CONTINUE
+*
+      ELSE
+*
+*        Set the leading m-by-n submatrix to ALPHA.
+*
+         DO 60 J = 1, N
+            DO 50 I = 1, M
+               A( I, J ) = ALPHA
+   50       CONTINUE
+   60    CONTINUE
+      END IF
+*
+*     Set the first min(M,N) diagonal elements to BETA.
+*
+      DO 70 I = 1, MIN( M, N )
+         A( I, I ) = BETA
+   70 CONTINUE
+*
+      RETURN
+*
+*     End of DLASET
+*
+      END
diff --git a/libcruft/lapack/dlasq1.f b/libcruft/lapack/dlasq1.f
new file mode 100644
index 0000000..6f4c341
--- /dev/null
+++ b/libcruft/lapack/dlasq1.f
@@ -0,0 +1,148 @@
+      SUBROUTINE DLASQ1( N, D, E, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASQ1 computes the singular values of a real N-by-N bidiagonal
+*  matrix with diagonal D and off-diagonal E. The singular values
+*  are computed to high relative accuracy, in the absence of
+*  denormalization, underflow and overflow. The algorithm was first
+*  presented in
+*
+*  "Accurate singular values and differential qd algorithms" by K. V.
+*  Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230,
+*  1994,
+*
+*  and the present implementation is described in "An implementation of
+*  the dqds Algorithm (Positive Case)", LAPACK Working Note.
+*
+*  Arguments
+*  =========
+*
+*  N     (input) INTEGER
+*        The number of rows and columns in the matrix. N >= 0.
+*
+*  D     (input/output) DOUBLE PRECISION array, dimension (N)
+*        On entry, D contains the diagonal elements of the
+*        bidiagonal matrix whose SVD is desired. On normal exit,
+*        D contains the singular values in decreasing order.
+*
+*  E     (input/output) DOUBLE PRECISION array, dimension (N)
+*        On entry, elements E(1:N-1) contain the off-diagonal elements
+*        of the bidiagonal matrix whose SVD is desired.
+*        On exit, E is overwritten.
+*
+*  WORK  (workspace) DOUBLE PRECISION array, dimension (4*N)
+*
+*  INFO  (output) INTEGER
+*        = 0: successful exit
+*        < 0: if INFO = -i, the i-th argument had an illegal value
+*        > 0: the algorithm failed
+*             = 1, a split was marked by a positive value in E
+*             = 2, current block of Z not diagonalized after 30*N
+*                  iterations (in inner while loop)
+*             = 3, termination criterion of outer while loop not met 
+*                  (program created more than N unreduced blocks)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IINFO
+      DOUBLE PRECISION   EPS, SCALE, SAFMIN, SIGMN, SIGMX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DLAS2, DLASCL, DLASQ2, DLASRT, XERBLA
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -2
+         CALL XERBLA( 'DLASQ1', -INFO )
+         RETURN
+      ELSE IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+         D( 1 ) = ABS( D( 1 ) )
+         RETURN
+      ELSE IF( N.EQ.2 ) THEN
+         CALL DLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX )
+         D( 1 ) = SIGMX
+         D( 2 ) = SIGMN
+         RETURN
+      END IF
+*
+*     Estimate the largest singular value.
+*
+      SIGMX = ZERO
+      DO 10 I = 1, N - 1
+         D( I ) = ABS( D( I ) )
+         SIGMX = MAX( SIGMX, ABS( E( I ) ) )
+   10 CONTINUE
+      D( N ) = ABS( D( N ) )
+*
+*     Early return if SIGMX is zero (matrix is already diagonal).
+*
+      IF( SIGMX.EQ.ZERO ) THEN
+         CALL DLASRT( 'D', N, D, IINFO )
+         RETURN
+      END IF
+*
+      DO 20 I = 1, N
+         SIGMX = MAX( SIGMX, D( I ) )
+   20 CONTINUE
+*
+*     Copy D and E into WORK (in the Z format) and scale (squaring the
+*     input data makes scaling by a power of the radix pointless).
+*
+      EPS = DLAMCH( 'Precision' )
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      SCALE = SQRT( EPS / SAFMIN )
+      CALL DCOPY( N, D, 1, WORK( 1 ), 2 )
+      CALL DCOPY( N-1, E, 1, WORK( 2 ), 2 )
+      CALL DLASCL( 'G', 0, 0, SIGMX, SCALE, 2*N-1, 1, WORK, 2*N-1,
+     $             IINFO )
+*         
+*     Compute the q's and e's.
+*
+      DO 30 I = 1, 2*N - 1
+         WORK( I ) = WORK( I )**2
+   30 CONTINUE
+      WORK( 2*N ) = ZERO
+*
+      CALL DLASQ2( N, WORK, INFO )
+*
+      IF( INFO.EQ.0 ) THEN
+         DO 40 I = 1, N
+            D( I ) = SQRT( WORK( I ) )
+   40    CONTINUE
+         CALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO )
+      END IF
+*
+      RETURN
+*
+*     End of DLASQ1
+*
+      END
diff --git a/libcruft/lapack/dlasq2.f b/libcruft/lapack/dlasq2.f
new file mode 100644
index 0000000..b6b79ae
--- /dev/null
+++ b/libcruft/lapack/dlasq2.f
@@ -0,0 +1,448 @@
+      SUBROUTINE DLASQ2( N, Z, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call DLAZQ3 in place of DLASQ3, 13 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASQ2 computes all the eigenvalues of the symmetric positive 
+*  definite tridiagonal matrix associated with the qd array Z to high
+*  relative accuracy are computed to high relative accuracy, in the
+*  absence of denormalization, underflow and overflow.
+*
+*  To see the relation of Z to the tridiagonal matrix, let L be a
+*  unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and
+*  let U be an upper bidiagonal matrix with 1's above and diagonal
+*  Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the
+*  symmetric tridiagonal to which it is similar.
+*
+*  Note : DLASQ2 defines a logical variable, IEEE, which is true
+*  on machines which follow ieee-754 floating-point standard in their
+*  handling of infinities and NaNs, and false otherwise. This variable
+*  is passed to DLAZQ3.
+*
+*  Arguments
+*  =========
+*
+*  N     (input) INTEGER
+*        The number of rows and columns in the matrix. N >= 0.
+*
+*  Z     (workspace) DOUBLE PRECISION array, dimension ( 4*N )
+*        On entry Z holds the qd array. On exit, entries 1 to N hold
+*        the eigenvalues in decreasing order, Z( 2*N+1 ) holds the
+*        trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If
+*        N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 )
+*        holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of
+*        shifts that failed.
+*
+*  INFO  (output) INTEGER
+*        = 0: successful exit
+*        < 0: if the i-th argument is a scalar and had an illegal
+*             value, then INFO = -i, if the i-th argument is an
+*             array and the j-entry had an illegal value, then
+*             INFO = -(i*100+j)
+*        > 0: the algorithm failed
+*              = 1, a split was marked by a positive value in E
+*              = 2, current block of Z not diagonalized after 30*N
+*                   iterations (in inner while loop)
+*              = 3, termination criterion of outer while loop not met 
+*                   (program created more than N unreduced blocks)
+*
+*  Further Details
+*  ===============
+*  Local Variables: I0:N0 defines a current unreduced segment of Z.
+*  The shifts are accumulated in SIGMA. Iteration count is in ITER.
+*  Ping-pong is controlled by PP (alternates between 0 and 1).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   CBIAS
+      PARAMETER          ( CBIAS = 1.50D0 )
+      DOUBLE PRECISION   ZERO, HALF, ONE, TWO, FOUR, HUNDRD
+      PARAMETER          ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0,
+     $                     TWO = 2.0D0, FOUR = 4.0D0, HUNDRD = 100.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            IEEE
+      INTEGER            I0, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, K, 
+     $                   N0, NBIG, NDIV, NFAIL, PP, SPLT, TTYPE
+      DOUBLE PRECISION   D, DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, E,
+     $                   EMAX, EMIN, EPS, OLDEMN, QMAX, QMIN, S, SAFMIN,
+     $                   SIGMA, T, TAU, TEMP, TOL, TOL2, TRACE, ZMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAZQ3, DLASRT, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH, ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*      
+*     Test the input arguments.
+*     (in case DLASQ2 is not called by DLASQ1)
+*
+      INFO = 0
+      EPS = DLAMCH( 'Precision' )
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      TOL = EPS*HUNDRD
+      TOL2 = TOL**2
+*
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'DLASQ2', 1 )
+         RETURN
+      ELSE IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+*
+*        1-by-1 case.
+*
+         IF( Z( 1 ).LT.ZERO ) THEN
+            INFO = -201
+            CALL XERBLA( 'DLASQ2', 2 )
+         END IF
+         RETURN
+      ELSE IF( N.EQ.2 ) THEN
+*
+*        2-by-2 case.
+*
+         IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THEN
+            INFO = -2
+            CALL XERBLA( 'DLASQ2', 2 )
+            RETURN
+         ELSE IF( Z( 3 ).GT.Z( 1 ) ) THEN
+            D = Z( 3 )
+            Z( 3 ) = Z( 1 )
+            Z( 1 ) = D
+         END IF
+         Z( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 )
+         IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THEN
+            T = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) ) 
+            S = Z( 3 )*( Z( 2 ) / T )
+            IF( S.LE.T ) THEN
+               S = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) )
+            ELSE
+               S = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
+            END IF
+            T = Z( 1 ) + ( S+Z( 2 ) )
+            Z( 3 ) = Z( 3 )*( Z( 1 ) / T )
+            Z( 1 ) = T
+         END IF
+         Z( 2 ) = Z( 3 )
+         Z( 6 ) = Z( 2 ) + Z( 1 )
+         RETURN
+      END IF
+*
+*     Check for negative data and compute sums of q's and e's.
+*
+      Z( 2*N ) = ZERO
+      EMIN = Z( 2 )
+      QMAX = ZERO
+      ZMAX = ZERO
+      D = ZERO
+      E = ZERO
+*
+      DO 10 K = 1, 2*( N-1 ), 2
+         IF( Z( K ).LT.ZERO ) THEN
+            INFO = -( 200+K )
+            CALL XERBLA( 'DLASQ2', 2 )
+            RETURN
+         ELSE IF( Z( K+1 ).LT.ZERO ) THEN
+            INFO = -( 200+K+1 )
+            CALL XERBLA( 'DLASQ2', 2 )
+            RETURN
+         END IF
+         D = D + Z( K )
+         E = E + Z( K+1 )
+         QMAX = MAX( QMAX, Z( K ) )
+         EMIN = MIN( EMIN, Z( K+1 ) )
+         ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) )
+   10 CONTINUE
+      IF( Z( 2*N-1 ).LT.ZERO ) THEN
+         INFO = -( 200+2*N-1 )
+         CALL XERBLA( 'DLASQ2', 2 )
+         RETURN
+      END IF
+      D = D + Z( 2*N-1 )
+      QMAX = MAX( QMAX, Z( 2*N-1 ) )
+      ZMAX = MAX( QMAX, ZMAX )
+*
+*     Check for diagonality.
+*
+      IF( E.EQ.ZERO ) THEN
+         DO 20 K = 2, N
+            Z( K ) = Z( 2*K-1 )
+   20    CONTINUE
+         CALL DLASRT( 'D', N, Z, IINFO )
+         Z( 2*N-1 ) = D
+         RETURN
+      END IF
+*
+      TRACE = D + E
+*
+*     Check for zero data.
+*
+      IF( TRACE.EQ.ZERO ) THEN
+         Z( 2*N-1 ) = ZERO
+         RETURN
+      END IF
+*         
+*     Check whether the machine is IEEE conformable.
+*         
+      IEEE = ILAENV( 10, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND.
+     $       ILAENV( 11, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1      
+*         
+*     Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...).
+*
+      DO 30 K = 2*N, 2, -2
+         Z( 2*K ) = ZERO 
+         Z( 2*K-1 ) = Z( K ) 
+         Z( 2*K-2 ) = ZERO 
+         Z( 2*K-3 ) = Z( K-1 ) 
+   30 CONTINUE
+*
+      I0 = 1
+      N0 = N
+*
+*     Reverse the qd-array, if warranted.
+*
+      IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THEN
+         IPN4 = 4*( I0+N0 )
+         DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4
+            TEMP = Z( I4-3 )
+            Z( I4-3 ) = Z( IPN4-I4-3 )
+            Z( IPN4-I4-3 ) = TEMP
+            TEMP = Z( I4-1 )
+            Z( I4-1 ) = Z( IPN4-I4-5 )
+            Z( IPN4-I4-5 ) = TEMP
+   40    CONTINUE
+      END IF
+*
+*     Initial split checking via dqd and Li's test.
+*
+      PP = 0
+*
+      DO 80 K = 1, 2
+*
+         D = Z( 4*N0+PP-3 )
+         DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4
+            IF( Z( I4-1 ).LE.TOL2*D ) THEN
+               Z( I4-1 ) = -ZERO
+               D = Z( I4-3 )
+            ELSE
+               D = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) )
+            END IF
+   50    CONTINUE
+*
+*        dqd maps Z to ZZ plus Li's test.
+*
+         EMIN = Z( 4*I0+PP+1 )
+         D = Z( 4*I0+PP-3 )
+         DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4
+            Z( I4-2*PP-2 ) = D + Z( I4-1 )
+            IF( Z( I4-1 ).LE.TOL2*D ) THEN
+               Z( I4-1 ) = -ZERO
+               Z( I4-2*PP-2 ) = D
+               Z( I4-2*PP ) = ZERO
+               D = Z( I4+1 )
+            ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND.
+     $               SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THEN
+               TEMP = Z( I4+1 ) / Z( I4-2*PP-2 )
+               Z( I4-2*PP ) = Z( I4-1 )*TEMP
+               D = D*TEMP
+            ELSE
+               Z( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) )
+               D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) )
+            END IF
+            EMIN = MIN( EMIN, Z( I4-2*PP ) )
+   60    CONTINUE 
+         Z( 4*N0-PP-2 ) = D
+*
+*        Now find qmax.
+*
+         QMAX = Z( 4*I0-PP-2 )
+         DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4
+            QMAX = MAX( QMAX, Z( I4 ) )
+   70    CONTINUE
+*
+*        Prepare for the next iteration on K.
+*
+         PP = 1 - PP
+   80 CONTINUE
+*
+*     Initialise variables to pass to DLAZQ3
+*
+      TTYPE = 0
+      DMIN1 = ZERO
+      DMIN2 = ZERO
+      DN    = ZERO
+      DN1   = ZERO
+      DN2   = ZERO
+      TAU   = ZERO
+*
+      ITER = 2
+      NFAIL = 0
+      NDIV = 2*( N0-I0 )
+*
+      DO 140 IWHILA = 1, N + 1
+         IF( N0.LT.1 ) 
+     $      GO TO 150
+*
+*        While array unfinished do 
+*
+*        E(N0) holds the value of SIGMA when submatrix in I0:N0
+*        splits from the rest of the array, but is negated.
+*      
+         DESIG = ZERO
+         IF( N0.EQ.N ) THEN
+            SIGMA = ZERO
+         ELSE
+            SIGMA = -Z( 4*N0-1 )
+         END IF
+         IF( SIGMA.LT.ZERO ) THEN
+            INFO = 1
+            RETURN
+         END IF
+*
+*        Find last unreduced submatrix's top index I0, find QMAX and
+*        EMIN. Find Gershgorin-type bound if Q's much greater than E's.
+*
+         EMAX = ZERO 
+         IF( N0.GT.I0 ) THEN
+            EMIN = ABS( Z( 4*N0-5 ) )
+         ELSE
+            EMIN = ZERO
+         END IF
+         QMIN = Z( 4*N0-3 )
+         QMAX = QMIN
+         DO 90 I4 = 4*N0, 8, -4
+            IF( Z( I4-5 ).LE.ZERO )
+     $         GO TO 100
+            IF( QMIN.GE.FOUR*EMAX ) THEN
+               QMIN = MIN( QMIN, Z( I4-3 ) )
+               EMAX = MAX( EMAX, Z( I4-5 ) )
+            END IF
+            QMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) )
+            EMIN = MIN( EMIN, Z( I4-5 ) )
+   90    CONTINUE
+         I4 = 4 
+*
+  100    CONTINUE
+         I0 = I4 / 4
+*
+*        Store EMIN for passing to DLAZQ3.
+*
+         Z( 4*N0-1 ) = EMIN
+*
+*        Put -(initial shift) into DMIN.
+*
+         DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) )
+*
+*        Now I0:N0 is unreduced. PP = 0 for ping, PP = 1 for pong.
+*
+         PP = 0 
+*
+         NBIG = 30*( N0-I0+1 )
+         DO 120 IWHILB = 1, NBIG
+            IF( I0.GT.N0 ) 
+     $         GO TO 130
+*
+*           While submatrix unfinished take a good dqds step.
+*
+            CALL DLAZQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
+     $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
+     $                   DN2, TAU )
+*
+            PP = 1 - PP
+*
+*           When EMIN is very small check for splits.
+*
+            IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THEN
+               IF( Z( 4*N0 ).LE.TOL2*QMAX .OR.
+     $             Z( 4*N0-1 ).LE.TOL2*SIGMA ) THEN
+                  SPLT = I0 - 1
+                  QMAX = Z( 4*I0-3 )
+                  EMIN = Z( 4*I0-1 )
+                  OLDEMN = Z( 4*I0 )
+                  DO 110 I4 = 4*I0, 4*( N0-3 ), 4
+                     IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR.
+     $                   Z( I4-1 ).LE.TOL2*SIGMA ) THEN
+                        Z( I4-1 ) = -SIGMA
+                        SPLT = I4 / 4
+                        QMAX = ZERO
+                        EMIN = Z( I4+3 )
+                        OLDEMN = Z( I4+4 )
+                     ELSE
+                        QMAX = MAX( QMAX, Z( I4+1 ) )
+                        EMIN = MIN( EMIN, Z( I4-1 ) )
+                        OLDEMN = MIN( OLDEMN, Z( I4 ) )
+                     END IF
+  110             CONTINUE
+                  Z( 4*N0-1 ) = EMIN
+                  Z( 4*N0 ) = OLDEMN
+                  I0 = SPLT + 1
+               END IF
+            END IF
+*
+  120    CONTINUE
+*
+         INFO = 2
+         RETURN
+*
+*        end IWHILB
+*
+  130    CONTINUE
+*
+  140 CONTINUE
+*
+      INFO = 3
+      RETURN
+*
+*     end IWHILA   
+*
+  150 CONTINUE
+*      
+*     Move q's to the front.
+*      
+      DO 160 K = 2, N
+         Z( K ) = Z( 4*K-3 )
+  160 CONTINUE
+*      
+*     Sort and compute sum of eigenvalues.
+*
+      CALL DLASRT( 'D', N, Z, IINFO )
+*
+      E = ZERO
+      DO 170 K = N, 1, -1
+         E = E + Z( K )
+  170 CONTINUE
+*
+*     Store trace, sum(eigenvalues) and information on performance.
+*
+      Z( 2*N+1 ) = TRACE 
+      Z( 2*N+2 ) = E
+      Z( 2*N+3 ) = DBLE( ITER )
+      Z( 2*N+4 ) = DBLE( NDIV ) / DBLE( N**2 )
+      Z( 2*N+5 ) = HUNDRD*NFAIL / DBLE( ITER )
+      RETURN
+*
+*     End of DLASQ2
+*
+      END
diff --git a/libcruft/lapack/dlasq3.f b/libcruft/lapack/dlasq3.f
new file mode 100644
index 0000000..ce4055d
--- /dev/null
+++ b/libcruft/lapack/dlasq3.f
@@ -0,0 +1,295 @@
+      SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
+     $                   ITER, NDIV, IEEE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            I0, ITER, N0, NDIV, NFAIL, PP
+      DOUBLE PRECISION   DESIG, DMIN, QMAX, SIGMA
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.
+*  In case of failure it changes shifts, and tries again until output
+*  is positive.
+*
+*  Arguments
+*  =========
+*
+*  I0     (input) INTEGER
+*         First index.
+*
+*  N0     (input) INTEGER
+*         Last index.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( 4*N )
+*         Z holds the qd array.
+*
+*  PP     (input) INTEGER
+*         PP=0 for ping, PP=1 for pong.
+*
+*  DMIN   (output) DOUBLE PRECISION
+*         Minimum value of d.
+*
+*  SIGMA  (output) DOUBLE PRECISION
+*         Sum of shifts used in current segment.
+*
+*  DESIG  (input/output) DOUBLE PRECISION
+*         Lower order part of SIGMA
+*
+*  QMAX   (input) DOUBLE PRECISION
+*         Maximum value of q.
+*
+*  NFAIL  (output) INTEGER
+*         Number of times shift was too big.
+*
+*  ITER   (output) INTEGER
+*         Number of iterations.
+*
+*  NDIV   (output) INTEGER
+*         Number of divisions.
+*
+*  TTYPE  (output) INTEGER
+*         Shift type.
+*
+*  IEEE   (input) LOGICAL
+*         Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   CBIAS
+      PARAMETER          ( CBIAS = 1.50D0 )
+      DOUBLE PRECISION   ZERO, QURTR, HALF, ONE, TWO, HUNDRD
+      PARAMETER          ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
+     $                     ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IPN4, J4, N0IN, NN, TTYPE
+      DOUBLE PRECISION   DMIN1, DMIN2, DN, DN1, DN2, EPS, S, SAFMIN, T,
+     $                   TAU, TEMP, TOL, TOL2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASQ4, DLASQ5, DLASQ6
+*     ..
+*     .. External Function ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Save statement ..
+      SAVE               TTYPE
+      SAVE               DMIN1, DMIN2, DN, DN1, DN2, TAU
+*     ..
+*     .. Data statement ..
+      DATA               TTYPE / 0 /
+      DATA               DMIN1 / ZERO /, DMIN2 / ZERO /, DN / ZERO /,
+     $                   DN1 / ZERO /, DN2 / ZERO /, TAU / ZERO /
+*     ..
+*     .. Executable Statements ..
+*
+      N0IN = N0
+      EPS = DLAMCH( 'Precision' )
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      TOL = EPS*HUNDRD
+      TOL2 = TOL**2
+*
+*     Check for deflation.
+*
+   10 CONTINUE
+*
+      IF( N0.LT.I0 )
+     $   RETURN
+      IF( N0.EQ.I0 )
+     $   GO TO 20
+      NN = 4*N0 + PP
+      IF( N0.EQ.( I0+1 ) )
+     $   GO TO 40
+*
+*     Check whether E(N0-1) is negligible, 1 eigenvalue.
+*
+      IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
+     $    Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
+     $   GO TO 30
+*
+   20 CONTINUE
+*
+      Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
+      N0 = N0 - 1
+      GO TO 10
+*
+*     Check  whether E(N0-2) is negligible, 2 eigenvalues.
+*
+   30 CONTINUE
+*
+      IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
+     $    Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
+     $   GO TO 50
+*
+   40 CONTINUE
+*
+      IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
+         S = Z( NN-3 )
+         Z( NN-3 ) = Z( NN-7 )
+         Z( NN-7 ) = S
+      END IF
+      IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
+         T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
+         S = Z( NN-3 )*( Z( NN-5 ) / T )
+         IF( S.LE.T ) THEN
+            S = Z( NN-3 )*( Z( NN-5 ) /
+     $          ( T*( ONE+SQRT( ONE+S / T ) ) ) )
+         ELSE
+            S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
+         END IF
+         T = Z( NN-7 ) + ( S+Z( NN-5 ) )
+         Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
+         Z( NN-7 ) = T
+      END IF
+      Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
+      Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
+      N0 = N0 - 2
+      GO TO 10
+*
+   50 CONTINUE
+*
+*     Reverse the qd-array, if warranted.
+*
+      IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
+         IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
+            IPN4 = 4*( I0+N0 )
+            DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
+               TEMP = Z( J4-3 )
+               Z( J4-3 ) = Z( IPN4-J4-3 )
+               Z( IPN4-J4-3 ) = TEMP
+               TEMP = Z( J4-2 )
+               Z( J4-2 ) = Z( IPN4-J4-2 )
+               Z( IPN4-J4-2 ) = TEMP
+               TEMP = Z( J4-1 )
+               Z( J4-1 ) = Z( IPN4-J4-5 )
+               Z( IPN4-J4-5 ) = TEMP
+               TEMP = Z( J4 )
+               Z( J4 ) = Z( IPN4-J4-4 )
+               Z( IPN4-J4-4 ) = TEMP
+   60       CONTINUE
+            IF( N0-I0.LE.4 ) THEN
+               Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
+               Z( 4*N0-PP ) = Z( 4*I0-PP )
+            END IF
+            DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
+            Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
+     $                            Z( 4*I0+PP+3 ) )
+            Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
+     $                          Z( 4*I0-PP+4 ) )
+            QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
+            DMIN = -ZERO
+         END IF
+      END IF
+*
+      IF( DMIN.LT.ZERO .OR. SAFMIN*QMAX.LT.MIN( Z( 4*N0+PP-1 ),
+     $    Z( 4*N0+PP-9 ), DMIN2+Z( 4*N0-PP ) ) ) THEN
+*
+*        Choose a shift.
+*
+         CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
+     $                DN2, TAU, TTYPE )
+*
+*        Call dqds until DMIN > 0.
+*
+   80    CONTINUE
+*
+         CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
+     $                DN1, DN2, IEEE )
+*
+         NDIV = NDIV + ( N0-I0+2 )
+         ITER = ITER + 1
+*
+*        Check status.
+*
+         IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
+*
+*           Success.
+*
+            GO TO 100
+*
+         ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
+     $            Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
+     $            ABS( DN ).LT.TOL*SIGMA ) THEN
+*
+*           Convergence hidden by negative DN.
+*
+            Z( 4*( N0-1 )-PP+2 ) = ZERO
+            DMIN = ZERO
+            GO TO 100
+         ELSE IF( DMIN.LT.ZERO ) THEN
+*
+*           TAU too big. Select new TAU and try again.
+*
+            NFAIL = NFAIL + 1
+            IF( TTYPE.LT.-22 ) THEN
+*
+*              Failed twice. Play it safe.
+*
+               TAU = ZERO
+            ELSE IF( DMIN1.GT.ZERO ) THEN
+*
+*              Late failure. Gives excellent shift.
+*
+               TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
+               TTYPE = TTYPE - 11
+            ELSE
+*
+*              Early failure. Divide by 4.
+*
+               TAU = QURTR*TAU
+               TTYPE = TTYPE - 12
+            END IF
+            GO TO 80
+         ELSE IF( DMIN.NE.DMIN ) THEN
+*
+*           NaN.
+*
+            TAU = ZERO
+            GO TO 80
+         ELSE
+*
+*           Possible underflow. Play it safe.
+*
+            GO TO 90
+         END IF
+      END IF
+*
+*     Risk of underflow.
+*
+   90 CONTINUE
+      CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
+      NDIV = NDIV + ( N0-I0+2 )
+      ITER = ITER + 1
+      TAU = ZERO
+*
+  100 CONTINUE
+      IF( TAU.LT.SIGMA ) THEN
+         DESIG = DESIG + TAU
+         T = SIGMA + DESIG
+         DESIG = DESIG - ( T-SIGMA )
+      ELSE
+         T = SIGMA + TAU
+         DESIG = SIGMA - ( T-TAU ) + DESIG
+      END IF
+      SIGMA = T
+*
+      RETURN
+*
+*     End of DLASQ3
+*
+      END
diff --git a/libcruft/lapack/dlasq4.f b/libcruft/lapack/dlasq4.f
new file mode 100644
index 0000000..db2b6fe
--- /dev/null
+++ b/libcruft/lapack/dlasq4.f
@@ -0,0 +1,329 @@
+      SUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
+     $                   DN1, DN2, TAU, TTYPE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I0, N0, N0IN, PP, TTYPE
+      DOUBLE PRECISION   DMIN, DMIN1, DMIN2, DN, DN1, DN2, TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASQ4 computes an approximation TAU to the smallest eigenvalue 
+*  using values of d from the previous transform.
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) DOUBLE PRECISION array, dimension ( 4*N )
+*        Z holds the qd array.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  N0IN  (input) INTEGER
+*        The value of N0 at start of EIGTEST.
+*
+*  DMIN  (input) DOUBLE PRECISION
+*        Minimum value of d.
+*
+*  DMIN1 (input) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (input) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (input) DOUBLE PRECISION
+*        d(N)
+*
+*  DN1   (input) DOUBLE PRECISION
+*        d(N-1)
+*
+*  DN2   (input) DOUBLE PRECISION
+*        d(N-2)
+*
+*  TAU   (output) DOUBLE PRECISION
+*        This is the shift.
+*
+*  TTYPE (output) INTEGER
+*        Shift type.
+*
+*  Further Details
+*  ===============
+*  CNST1 = 9/16
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   CNST1, CNST2, CNST3
+      PARAMETER          ( CNST1 = 0.5630D0, CNST2 = 1.010D0,
+     $                   CNST3 = 1.050D0 )
+      DOUBLE PRECISION   QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRD
+      PARAMETER          ( QURTR = 0.250D0, THIRD = 0.3330D0,
+     $                   HALF = 0.50D0, ZERO = 0.0D0, ONE = 1.0D0,
+     $                   TWO = 2.0D0, HUNDRD = 100.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I4, NN, NP
+      DOUBLE PRECISION   A2, B1, B2, G, GAM, GAP1, GAP2, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Save statement ..
+      SAVE               G
+*     ..
+*     .. Data statement ..
+      DATA               G / ZERO /
+*     ..
+*     .. Executable Statements ..
+*
+*     A negative DMIN forces the shift to take that absolute value
+*     TTYPE records the type of shift.
+*
+      IF( DMIN.LE.ZERO ) THEN
+         TAU = -DMIN
+         TTYPE = -1
+         RETURN
+      END IF
+*       
+      NN = 4*N0 + PP
+      IF( N0IN.EQ.N0 ) THEN
+*
+*        No eigenvalues deflated.
+*
+         IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN
+*
+            B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )
+            B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )
+            A2 = Z( NN-7 ) + Z( NN-5 )
+*
+*           Cases 2 and 3.
+*
+            IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THEN
+               GAP2 = DMIN2 - A2 - DMIN2*QURTR
+               IF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THEN
+                  GAP1 = A2 - DN - ( B2 / GAP2 )*B2
+               ELSE
+                  GAP1 = A2 - DN - ( B1+B2 )
+               END IF
+               IF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THEN
+                  S = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )
+                  TTYPE = -2
+               ELSE
+                  S = ZERO
+                  IF( DN.GT.B1 )
+     $               S = DN - B1
+                  IF( A2.GT.( B1+B2 ) )
+     $               S = MIN( S, A2-( B1+B2 ) )
+                  S = MAX( S, THIRD*DMIN )
+                  TTYPE = -3
+               END IF
+            ELSE
+*
+*              Case 4.
+*
+               TTYPE = -4
+               S = QURTR*DMIN
+               IF( DMIN.EQ.DN ) THEN
+                  GAM = DN
+                  A2 = ZERO
+                  IF( Z( NN-5 ) .GT. Z( NN-7 ) )
+     $               RETURN
+                  B2 = Z( NN-5 ) / Z( NN-7 )
+                  NP = NN - 9
+               ELSE
+                  NP = NN - 2*PP
+                  B2 = Z( NP-2 )
+                  GAM = DN1
+                  IF( Z( NP-4 ) .GT. Z( NP-2 ) )
+     $               RETURN
+                  A2 = Z( NP-4 ) / Z( NP-2 )
+                  IF( Z( NN-9 ) .GT. Z( NN-11 ) )
+     $               RETURN
+                  B2 = Z( NN-9 ) / Z( NN-11 )
+                  NP = NN - 13
+               END IF
+*
+*              Approximate contribution to norm squared from I < NN-1.
+*
+               A2 = A2 + B2
+               DO 10 I4 = NP, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 20
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 20
+   10          CONTINUE
+   20          CONTINUE
+               A2 = CNST3*A2
+*
+*              Rayleigh quotient residual bound.
+*
+               IF( A2.LT.CNST1 )
+     $            S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+            END IF
+         ELSE IF( DMIN.EQ.DN2 ) THEN
+*
+*           Case 5.
+*
+            TTYPE = -5
+            S = QURTR*DMIN
+*
+*           Compute contribution to norm squared from I > NN-2.
+*
+            NP = NN - 2*PP
+            B1 = Z( NP-2 )
+            B2 = Z( NP-6 )
+            GAM = DN2
+            IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 )
+     $         RETURN
+            A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )
+*
+*           Approximate contribution to norm squared from I < NN-2.
+*
+            IF( N0-I0.GT.2 ) THEN
+               B2 = Z( NN-13 ) / Z( NN-15 )
+               A2 = A2 + B2
+               DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 40
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 40
+   30          CONTINUE
+   40          CONTINUE
+               A2 = CNST3*A2
+            END IF
+*
+            IF( A2.LT.CNST1 )
+     $         S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+         ELSE
+*
+*           Case 6, no information to guide us.
+*
+            IF( TTYPE.EQ.-6 ) THEN
+               G = G + THIRD*( ONE-G )
+            ELSE IF( TTYPE.EQ.-18 ) THEN
+               G = QURTR*THIRD
+            ELSE
+               G = QURTR
+            END IF
+            S = G*DMIN
+            TTYPE = -6
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+1 ) ) THEN
+*
+*        One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.
+*
+         IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN 
+*
+*           Cases 7 and 8.
+*
+            TTYPE = -7
+            S = THIRD*DMIN1
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 60
+            DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               A2 = B1
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*MAX( B1, A2 ).LT.B2 ) 
+     $            GO TO 60
+   50       CONTINUE
+   60       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN1 / ( ONE+B2**2 )
+            GAP2 = HALF*DMIN2 - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+               TTYPE = -8
+            END IF
+         ELSE
+*
+*           Case 9.
+*
+            S = QURTR*DMIN1
+            IF( DMIN1.EQ.DN1 )
+     $         S = HALF*DMIN1
+            TTYPE = -9
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+2 ) ) THEN
+*
+*        Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
+*
+*        Cases 10 and 11.
+*
+         IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THEN 
+            TTYPE = -10
+            S = THIRD*DMIN2
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 80
+            DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*B1.LT.B2 )
+     $            GO TO 80
+   70       CONTINUE
+   80       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN2 / ( ONE+B2**2 )
+            GAP2 = Z( NN-7 ) + Z( NN-9 ) -
+     $             SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+            END IF
+         ELSE
+            S = QURTR*DMIN2
+            TTYPE = -11
+         END IF
+      ELSE IF( N0IN.GT.( N0+2 ) ) THEN
+*
+*        Case 12, more than two eigenvalues deflated. No information.
+*
+         S = ZERO 
+         TTYPE = -12
+      END IF
+*
+      TAU = S
+      RETURN
+*
+*     End of DLASQ4
+*
+      END
diff --git a/libcruft/lapack/dlasq5.f b/libcruft/lapack/dlasq5.f
new file mode 100644
index 0000000..a006c99
--- /dev/null
+++ b/libcruft/lapack/dlasq5.f
@@ -0,0 +1,195 @@
+      SUBROUTINE DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
+     $                   DNM1, DNM2, IEEE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            I0, N0, PP
+      DOUBLE PRECISION   DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASQ5 computes one dqds transform in ping-pong form, one
+*  version for IEEE machines another for non IEEE machines.
+*
+*  Arguments
+*  =========
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) DOUBLE PRECISION array, dimension ( 4*N )
+*        Z holds the qd array. EMIN is stored in Z(4*N0) to avoid
+*        an extra argument.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  TAU   (input) DOUBLE PRECISION
+*        This is the shift.
+*
+*  DMIN  (output) DOUBLE PRECISION
+*        Minimum value of d.
+*
+*  DMIN1 (output) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (output) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (output) DOUBLE PRECISION
+*        d(N0), the last value of d.
+*
+*  DNM1  (output) DOUBLE PRECISION
+*        d(N0-1).
+*
+*  DNM2  (output) DOUBLE PRECISION
+*        d(N0-2).
+*
+*  IEEE  (input) LOGICAL
+*        Flag for IEEE or non IEEE arithmetic.
+*
+*  =====================================================================
+*
+*     .. Parameter ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J4, J4P2
+      DOUBLE PRECISION   D, EMIN, TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( ( N0-I0-1 ).LE.0 )
+     $   RETURN
+*
+      J4 = 4*I0 + PP - 3
+      EMIN = Z( J4+4 )
+      D = Z( J4 ) - TAU
+      DMIN = D
+      DMIN1 = -Z( J4 )
+*
+      IF( IEEE ) THEN
+*
+*        Code for IEEE arithmetic.
+*
+         IF( PP.EQ.0 ) THEN
+            DO 10 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-2 ) = D + Z( J4-1 )
+               TEMP = Z( J4+1 ) / Z( J4-2 )
+               D = D*TEMP - TAU
+               DMIN = MIN( DMIN, D )
+               Z( J4 ) = Z( J4-1 )*TEMP
+               EMIN = MIN( Z( J4 ), EMIN )
+   10       CONTINUE
+         ELSE
+            DO 20 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-3 ) = D + Z( J4 )
+               TEMP = Z( J4+2 ) / Z( J4-3 )
+               D = D*TEMP - TAU
+               DMIN = MIN( DMIN, D )
+               Z( J4-1 ) = Z( J4 )*TEMP
+               EMIN = MIN( Z( J4-1 ), EMIN )
+   20       CONTINUE
+         END IF
+*
+*        Unroll last two steps.
+*
+         DNM2 = D
+         DMIN2 = DMIN
+         J4 = 4*( N0-2 ) - PP
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM2 + Z( J4P2 )
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU
+         DMIN = MIN( DMIN, DNM1 )
+*
+         DMIN1 = DMIN
+         J4 = J4 + 4
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM1 + Z( J4P2 )
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU
+         DMIN = MIN( DMIN, DN )
+*
+      ELSE
+*
+*        Code for non IEEE arithmetic.
+*
+         IF( PP.EQ.0 ) THEN
+            DO 30 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-2 ) = D + Z( J4-1 )
+               IF( D.LT.ZERO ) THEN
+                  RETURN
+               ELSE
+                  Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )
+                  D = Z( J4+1 )*( D / Z( J4-2 ) ) - TAU
+               END IF
+               DMIN = MIN( DMIN, D )
+               EMIN = MIN( EMIN, Z( J4 ) )
+   30       CONTINUE
+         ELSE
+            DO 40 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-3 ) = D + Z( J4 )
+               IF( D.LT.ZERO ) THEN
+                  RETURN
+               ELSE
+                  Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )
+                  D = Z( J4+2 )*( D / Z( J4-3 ) ) - TAU
+               END IF
+               DMIN = MIN( DMIN, D )
+               EMIN = MIN( EMIN, Z( J4-1 ) )
+   40       CONTINUE
+         END IF
+*
+*        Unroll last two steps.
+*
+         DNM2 = D
+         DMIN2 = DMIN
+         J4 = 4*( N0-2 ) - PP
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM2 + Z( J4P2 )
+         IF( DNM2.LT.ZERO ) THEN
+            RETURN
+         ELSE
+            Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+            DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU
+         END IF
+         DMIN = MIN( DMIN, DNM1 )
+*
+         DMIN1 = DMIN
+         J4 = J4 + 4
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM1 + Z( J4P2 )
+         IF( DNM1.LT.ZERO ) THEN
+            RETURN
+         ELSE
+            Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+            DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU
+         END IF
+         DMIN = MIN( DMIN, DN )
+*
+      END IF
+*
+      Z( J4+2 ) = DN
+      Z( 4*N0-PP ) = EMIN
+      RETURN
+*
+*     End of DLASQ5
+*
+      END
diff --git a/libcruft/lapack/dlasq6.f b/libcruft/lapack/dlasq6.f
new file mode 100644
index 0000000..e7eb7d0
--- /dev/null
+++ b/libcruft/lapack/dlasq6.f
@@ -0,0 +1,175 @@
+      SUBROUTINE DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN,
+     $                   DNM1, DNM2 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I0, N0, PP
+      DOUBLE PRECISION   DMIN, DMIN1, DMIN2, DN, DNM1, DNM2
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASQ6 computes one dqd (shift equal to zero) transform in
+*  ping-pong form, with protection against underflow and overflow.
+*
+*  Arguments
+*  =========
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) DOUBLE PRECISION array, dimension ( 4*N )
+*        Z holds the qd array. EMIN is stored in Z(4*N0) to avoid
+*        an extra argument.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  DMIN  (output) DOUBLE PRECISION
+*        Minimum value of d.
+*
+*  DMIN1 (output) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (output) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (output) DOUBLE PRECISION
+*        d(N0), the last value of d.
+*
+*  DNM1  (output) DOUBLE PRECISION
+*        d(N0-1).
+*
+*  DNM2  (output) DOUBLE PRECISION
+*        d(N0-2).
+*
+*  =====================================================================
+*
+*     .. Parameter ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J4, J4P2
+      DOUBLE PRECISION   D, EMIN, SAFMIN, TEMP
+*     ..
+*     .. External Function ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( ( N0-I0-1 ).LE.0 )
+     $   RETURN
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      J4 = 4*I0 + PP - 3
+      EMIN = Z( J4+4 ) 
+      D = Z( J4 )
+      DMIN = D
+*
+      IF( PP.EQ.0 ) THEN
+         DO 10 J4 = 4*I0, 4*( N0-3 ), 4
+            Z( J4-2 ) = D + Z( J4-1 ) 
+            IF( Z( J4-2 ).EQ.ZERO ) THEN
+               Z( J4 ) = ZERO
+               D = Z( J4+1 )
+               DMIN = D
+               EMIN = ZERO
+            ELSE IF( SAFMIN*Z( J4+1 ).LT.Z( J4-2 ) .AND.
+     $               SAFMIN*Z( J4-2 ).LT.Z( J4+1 ) ) THEN
+               TEMP = Z( J4+1 ) / Z( J4-2 )
+               Z( J4 ) = Z( J4-1 )*TEMP
+               D = D*TEMP
+            ELSE 
+               Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )
+               D = Z( J4+1 )*( D / Z( J4-2 ) )
+            END IF
+            DMIN = MIN( DMIN, D )
+            EMIN = MIN( EMIN, Z( J4 ) )
+   10    CONTINUE
+      ELSE
+         DO 20 J4 = 4*I0, 4*( N0-3 ), 4
+            Z( J4-3 ) = D + Z( J4 ) 
+            IF( Z( J4-3 ).EQ.ZERO ) THEN
+               Z( J4-1 ) = ZERO
+               D = Z( J4+2 )
+               DMIN = D
+               EMIN = ZERO
+            ELSE IF( SAFMIN*Z( J4+2 ).LT.Z( J4-3 ) .AND.
+     $               SAFMIN*Z( J4-3 ).LT.Z( J4+2 ) ) THEN
+               TEMP = Z( J4+2 ) / Z( J4-3 )
+               Z( J4-1 ) = Z( J4 )*TEMP
+               D = D*TEMP
+            ELSE 
+               Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )
+               D = Z( J4+2 )*( D / Z( J4-3 ) )
+            END IF
+            DMIN = MIN( DMIN, D )
+            EMIN = MIN( EMIN, Z( J4-1 ) )
+   20    CONTINUE
+      END IF
+*
+*     Unroll last two steps. 
+*
+      DNM2 = D
+      DMIN2 = DMIN
+      J4 = 4*( N0-2 ) - PP
+      J4P2 = J4 + 2*PP - 1
+      Z( J4-2 ) = DNM2 + Z( J4P2 )
+      IF( Z( J4-2 ).EQ.ZERO ) THEN
+         Z( J4 ) = ZERO
+         DNM1 = Z( J4P2+2 )
+         DMIN = DNM1
+         EMIN = ZERO
+      ELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND.
+     $         SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THEN
+         TEMP = Z( J4P2+2 ) / Z( J4-2 )
+         Z( J4 ) = Z( J4P2 )*TEMP
+         DNM1 = DNM2*TEMP
+      ELSE
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) )
+      END IF
+      DMIN = MIN( DMIN, DNM1 )
+*
+      DMIN1 = DMIN
+      J4 = J4 + 4
+      J4P2 = J4 + 2*PP - 1
+      Z( J4-2 ) = DNM1 + Z( J4P2 )
+      IF( Z( J4-2 ).EQ.ZERO ) THEN
+         Z( J4 ) = ZERO
+         DN = Z( J4P2+2 )
+         DMIN = DN
+         EMIN = ZERO
+      ELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND.
+     $         SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THEN
+         TEMP = Z( J4P2+2 ) / Z( J4-2 )
+         Z( J4 ) = Z( J4P2 )*TEMP
+         DN = DNM1*TEMP
+      ELSE
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) )
+      END IF
+      DMIN = MIN( DMIN, DN )
+*
+      Z( J4+2 ) = DN
+      Z( 4*N0-PP ) = EMIN
+      RETURN
+*
+*     End of DLASQ6
+*
+      END
diff --git a/libcruft/lapack/dlasr.f b/libcruft/lapack/dlasr.f
new file mode 100644
index 0000000..7e54bfc
--- /dev/null
+++ b/libcruft/lapack/dlasr.f
@@ -0,0 +1,361 @@
+      SUBROUTINE DLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, PIVOT, SIDE
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( * ), S( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASR applies a sequence of plane rotations to a real matrix A,
+*  from either the left or the right.
+*  
+*  When SIDE = 'L', the transformation takes the form
+*  
+*     A := P*A
+*  
+*  and when SIDE = 'R', the transformation takes the form
+*  
+*     A := A*P**T
+*  
+*  where P is an orthogonal matrix consisting of a sequence of z plane
+*  rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',
+*  and P**T is the transpose of P.
+*  
+*  When DIRECT = 'F' (Forward sequence), then
+*  
+*     P = P(z-1) * ... * P(2) * P(1)
+*  
+*  and when DIRECT = 'B' (Backward sequence), then
+*  
+*     P = P(1) * P(2) * ... * P(z-1)
+*  
+*  where P(k) is a plane rotation matrix defined by the 2-by-2 rotation
+*  
+*     R(k) = (  c(k)  s(k) )
+*          = ( -s(k)  c(k) ).
+*  
+*  When PIVOT = 'V' (Variable pivot), the rotation is performed
+*  for the plane (k,k+1), i.e., P(k) has the form
+*  
+*     P(k) = (  1                                            )
+*            (       ...                                     )
+*            (              1                                )
+*            (                   c(k)  s(k)                  )
+*            (                  -s(k)  c(k)                  )
+*            (                                1              )
+*            (                                     ...       )
+*            (                                            1  )
+*  
+*  where R(k) appears as a rank-2 modification to the identity matrix in
+*  rows and columns k and k+1.
+*  
+*  When PIVOT = 'T' (Top pivot), the rotation is performed for the
+*  plane (1,k+1), so P(k) has the form
+*  
+*     P(k) = (  c(k)                    s(k)                 )
+*            (         1                                     )
+*            (              ...                              )
+*            (                     1                         )
+*            ( -s(k)                    c(k)                 )
+*            (                                 1             )
+*            (                                      ...      )
+*            (                                             1 )
+*  
+*  where R(k) appears in rows and columns 1 and k+1.
+*  
+*  Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is
+*  performed for the plane (k,z), giving P(k) the form
+*  
+*     P(k) = ( 1                                             )
+*            (      ...                                      )
+*            (             1                                 )
+*            (                  c(k)                    s(k) )
+*            (                         1                     )
+*            (                              ...              )
+*            (                                     1         )
+*            (                 -s(k)                    c(k) )
+*  
+*  where R(k) appears in rows and columns k and z.  The rotations are
+*  performed without ever forming P(k) explicitly.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          Specifies whether the plane rotation matrix P is applied to
+*          A on the left or the right.
+*          = 'L':  Left, compute A := P*A
+*          = 'R':  Right, compute A:= A*P**T
+*
+*  PIVOT   (input) CHARACTER*1
+*          Specifies the plane for which P(k) is a plane rotation
+*          matrix.
+*          = 'V':  Variable pivot, the plane (k,k+1)
+*          = 'T':  Top pivot, the plane (1,k+1)
+*          = 'B':  Bottom pivot, the plane (k,z)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies whether P is a forward or backward sequence of
+*          plane rotations.
+*          = 'F':  Forward, P = P(z-1)*...*P(2)*P(1)
+*          = 'B':  Backward, P = P(1)*P(2)*...*P(z-1)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  If m <= 1, an immediate
+*          return is effected.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  If n <= 1, an
+*          immediate return is effected.
+*
+*  C       (input) DOUBLE PRECISION array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The cosines c(k) of the plane rotations.
+*
+*  S       (input) DOUBLE PRECISION array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The sines s(k) of the plane rotations.  The 2-by-2 plane
+*          rotation part of the matrix P(k), R(k), has the form
+*          R(k) = (  c(k)  s(k) )
+*                 ( -s(k)  c(k) ).
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          The M-by-N matrix A.  On exit, A is overwritten by P*A if
+*          SIDE = 'R' or by A*P**T if SIDE = 'L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+      DOUBLE PRECISION   CTEMP, STEMP, TEMP
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THEN
+         INFO = 1
+      ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT,
+     $         'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THEN
+         INFO = 2
+      ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) )
+     $          THEN
+         INFO = 3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = 4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASR ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  P * A
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 20 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 10 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 40 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 30 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   30                CONTINUE
+                  END IF
+   40          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 60 J = 2, M
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 50 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 80 J = M, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 70 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   70                CONTINUE
+                  END IF
+   80          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 100 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 90 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+   90                CONTINUE
+                  END IF
+  100          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 120 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 110 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+  110                CONTINUE
+                  END IF
+  120          CONTINUE
+            END IF
+         END IF
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form A * P'
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 140 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 130 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  130                CONTINUE
+                  END IF
+  140          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 160 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 150 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  150                CONTINUE
+                  END IF
+  160          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 180 J = 2, N
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 170 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  170                CONTINUE
+                  END IF
+  180          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 200 J = N, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 190 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  190                CONTINUE
+                  END IF
+  200          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 220 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 210 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  210                CONTINUE
+                  END IF
+  220          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 240 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 230 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  230                CONTINUE
+                  END IF
+  240          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DLASR
+*
+      END
diff --git a/libcruft/lapack/dlasrt.f b/libcruft/lapack/dlasrt.f
new file mode 100644
index 0000000..37e0217
--- /dev/null
+++ b/libcruft/lapack/dlasrt.f
@@ -0,0 +1,243 @@
+      SUBROUTINE DLASRT( ID, N, D, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          ID
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Sort the numbers in D in increasing order (if ID = 'I') or
+*  in decreasing order (if ID = 'D' ).
+*
+*  Use Quick Sort, reverting to Insertion sort on arrays of
+*  size <= 20. Dimension of STACK limits N to about 2**32.
+*
+*  Arguments
+*  =========
+*
+*  ID      (input) CHARACTER*1
+*          = 'I': sort D in increasing order;
+*          = 'D': sort D in decreasing order.
+*
+*  N       (input) INTEGER
+*          The length of the array D.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the array to be sorted.
+*          On exit, D has been sorted into increasing order
+*          (D(1) <= ... <= D(N) ) or into decreasing order
+*          (D(1) >= ... >= D(N) ), depending on ID.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            SELECT
+      PARAMETER          ( SELECT = 20 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            DIR, ENDD, I, J, START, STKPNT
+      DOUBLE PRECISION   D1, D2, D3, DMNMX, TMP
+*     ..
+*     .. Local Arrays ..
+      INTEGER            STACK( 2, 32 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input paramters.
+*
+      INFO = 0
+      DIR = -1
+      IF( LSAME( ID, 'D' ) ) THEN
+         DIR = 0
+      ELSE IF( LSAME( ID, 'I' ) ) THEN
+         DIR = 1
+      END IF
+      IF( DIR.EQ.-1 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLASRT', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      STKPNT = 1
+      STACK( 1, 1 ) = 1
+      STACK( 2, 1 ) = N
+   10 CONTINUE
+      START = STACK( 1, STKPNT )
+      ENDD = STACK( 2, STKPNT )
+      STKPNT = STKPNT - 1
+      IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN
+*
+*        Do Insertion sort on D( START:ENDD )
+*
+         IF( DIR.EQ.0 ) THEN
+*
+*           Sort into decreasing order
+*
+            DO 30 I = START + 1, ENDD
+               DO 20 J = I, START + 1, -1
+                  IF( D( J ).GT.D( J-1 ) ) THEN
+                     DMNMX = D( J )
+                     D( J ) = D( J-1 )
+                     D( J-1 ) = DMNMX
+                  ELSE
+                     GO TO 30
+                  END IF
+   20          CONTINUE
+   30       CONTINUE
+*
+         ELSE
+*
+*           Sort into increasing order
+*
+            DO 50 I = START + 1, ENDD
+               DO 40 J = I, START + 1, -1
+                  IF( D( J ).LT.D( J-1 ) ) THEN
+                     DMNMX = D( J )
+                     D( J ) = D( J-1 )
+                     D( J-1 ) = DMNMX
+                  ELSE
+                     GO TO 50
+                  END IF
+   40          CONTINUE
+   50       CONTINUE
+*
+         END IF
+*
+      ELSE IF( ENDD-START.GT.SELECT ) THEN
+*
+*        Partition D( START:ENDD ) and stack parts, largest one first
+*
+*        Choose partition entry as median of 3
+*
+         D1 = D( START )
+         D2 = D( ENDD )
+         I = ( START+ENDD ) / 2
+         D3 = D( I )
+         IF( D1.LT.D2 ) THEN
+            IF( D3.LT.D1 ) THEN
+               DMNMX = D1
+            ELSE IF( D3.LT.D2 ) THEN
+               DMNMX = D3
+            ELSE
+               DMNMX = D2
+            END IF
+         ELSE
+            IF( D3.LT.D2 ) THEN
+               DMNMX = D2
+            ELSE IF( D3.LT.D1 ) THEN
+               DMNMX = D3
+            ELSE
+               DMNMX = D1
+            END IF
+         END IF
+*
+         IF( DIR.EQ.0 ) THEN
+*
+*           Sort into decreasing order
+*
+            I = START - 1
+            J = ENDD + 1
+   60       CONTINUE
+   70       CONTINUE
+            J = J - 1
+            IF( D( J ).LT.DMNMX )
+     $         GO TO 70
+   80       CONTINUE
+            I = I + 1
+            IF( D( I ).GT.DMNMX )
+     $         GO TO 80
+            IF( I.LT.J ) THEN
+               TMP = D( I )
+               D( I ) = D( J )
+               D( J ) = TMP
+               GO TO 60
+            END IF
+            IF( J-START.GT.ENDD-J-1 ) THEN
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+            ELSE
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+            END IF
+         ELSE
+*
+*           Sort into increasing order
+*
+            I = START - 1
+            J = ENDD + 1
+   90       CONTINUE
+  100       CONTINUE
+            J = J - 1
+            IF( D( J ).GT.DMNMX )
+     $         GO TO 100
+  110       CONTINUE
+            I = I + 1
+            IF( D( I ).LT.DMNMX )
+     $         GO TO 110
+            IF( I.LT.J ) THEN
+               TMP = D( I )
+               D( I ) = D( J )
+               D( J ) = TMP
+               GO TO 90
+            END IF
+            IF( J-START.GT.ENDD-J-1 ) THEN
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+            ELSE
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+            END IF
+         END IF
+      END IF
+      IF( STKPNT.GT.0 )
+     $   GO TO 10
+      RETURN
+*
+*     End of DLASRT
+*
+      END
diff --git a/libcruft/lapack/dlassq.f b/libcruft/lapack/dlassq.f
new file mode 100644
index 0000000..217e794
--- /dev/null
+++ b/libcruft/lapack/dlassq.f
@@ -0,0 +1,88 @@
+      SUBROUTINE DLASSQ( N, X, INCX, SCALE, SUMSQ )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      DOUBLE PRECISION   SCALE, SUMSQ
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASSQ  returns the values  scl  and  smsq  such that
+*
+*     ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
+*
+*  where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
+*  assumed to be non-negative and  scl  returns the value
+*
+*     scl = max( scale, abs( x( i ) ) ).
+*
+*  scale and sumsq must be supplied in SCALE and SUMSQ and
+*  scl and smsq are overwritten on SCALE and SUMSQ respectively.
+*
+*  The routine makes only one pass through the vector x.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements to be used from the vector X.
+*
+*  X       (input) DOUBLE PRECISION array, dimension (N)
+*          The vector for which a scaled sum of squares is computed.
+*             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector X.
+*          INCX > 0.
+*
+*  SCALE   (input/output) DOUBLE PRECISION
+*          On entry, the value  scale  in the equation above.
+*          On exit, SCALE is overwritten with  scl , the scaling factor
+*          for the sum of squares.
+*
+*  SUMSQ   (input/output) DOUBLE PRECISION
+*          On entry, the value  sumsq  in the equation above.
+*          On exit, SUMSQ is overwritten with  smsq , the basic sum of
+*          squares from which  scl  has been factored out.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IX
+      DOUBLE PRECISION   ABSXI
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.GT.0 ) THEN
+         DO 10 IX = 1, 1 + ( N-1 )*INCX, INCX
+            IF( X( IX ).NE.ZERO ) THEN
+               ABSXI = ABS( X( IX ) )
+               IF( SCALE.LT.ABSXI ) THEN
+                  SUMSQ = 1 + SUMSQ*( SCALE / ABSXI )**2
+                  SCALE = ABSXI
+               ELSE
+                  SUMSQ = SUMSQ + ( ABSXI / SCALE )**2
+               END IF
+            END IF
+   10    CONTINUE
+      END IF
+      RETURN
+*
+*     End of DLASSQ
+*
+      END
diff --git a/libcruft/lapack/dlasv2.f b/libcruft/lapack/dlasv2.f
new file mode 100644
index 0000000..4a00b25
--- /dev/null
+++ b/libcruft/lapack/dlasv2.f
@@ -0,0 +1,249 @@
+      SUBROUTINE DLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASV2 computes the singular value decomposition of a 2-by-2
+*  triangular matrix
+*     [  F   G  ]
+*     [  0   H  ].
+*  On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the
+*  smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and
+*  right singular vectors for abs(SSMAX), giving the decomposition
+*
+*     [ CSL  SNL ] [  F   G  ] [ CSR -SNR ]  =  [ SSMAX   0   ]
+*     [-SNL  CSL ] [  0   H  ] [ SNR  CSR ]     [  0    SSMIN ].
+*
+*  Arguments
+*  =========
+*
+*  F       (input) DOUBLE PRECISION
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  G       (input) DOUBLE PRECISION
+*          The (1,2) element of the 2-by-2 matrix.
+*
+*  H       (input) DOUBLE PRECISION
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  SSMIN   (output) DOUBLE PRECISION
+*          abs(SSMIN) is the smaller singular value.
+*
+*  SSMAX   (output) DOUBLE PRECISION
+*          abs(SSMAX) is the larger singular value.
+*
+*  SNL     (output) DOUBLE PRECISION
+*  CSL     (output) DOUBLE PRECISION
+*          The vector (CSL, SNL) is a unit left singular vector for the
+*          singular value abs(SSMAX).
+*
+*  SNR     (output) DOUBLE PRECISION
+*  CSR     (output) DOUBLE PRECISION
+*          The vector (CSR, SNR) is a unit right singular vector for the
+*          singular value abs(SSMAX).
+*
+*  Further Details
+*  ===============
+*
+*  Any input parameter may be aliased with any output parameter.
+*
+*  Barring over/underflow and assuming a guard digit in subtraction, all
+*  output quantities are correct to within a few units in the last
+*  place (ulps).
+*
+*  In IEEE arithmetic, the code works correctly if one matrix element is
+*  infinite.
+*
+*  Overflow will not occur unless the largest singular value itself
+*  overflows or is within a few ulps of overflow. (On machines with
+*  partial overflow, like the Cray, overflow may occur if the largest
+*  singular value is within a factor of 2 of overflow.)
+*
+*  Underflow is harmless if underflow is gradual. Otherwise, results
+*  may correspond to a matrix modified by perturbations of size near
+*  the underflow threshold.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   HALF
+      PARAMETER          ( HALF = 0.5D0 )
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0D0 )
+      DOUBLE PRECISION   FOUR
+      PARAMETER          ( FOUR = 4.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            GASMAL, SWAP
+      INTEGER            PMAX
+      DOUBLE PRECISION   A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M,
+     $                   MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+      FT = F
+      FA = ABS( FT )
+      HT = H
+      HA = ABS( H )
+*
+*     PMAX points to the maximum absolute element of matrix
+*       PMAX = 1 if F largest in absolute values
+*       PMAX = 2 if G largest in absolute values
+*       PMAX = 3 if H largest in absolute values
+*
+      PMAX = 1
+      SWAP = ( HA.GT.FA )
+      IF( SWAP ) THEN
+         PMAX = 3
+         TEMP = FT
+         FT = HT
+         HT = TEMP
+         TEMP = FA
+         FA = HA
+         HA = TEMP
+*
+*        Now FA .ge. HA
+*
+      END IF
+      GT = G
+      GA = ABS( GT )
+      IF( GA.EQ.ZERO ) THEN
+*
+*        Diagonal matrix
+*
+         SSMIN = HA
+         SSMAX = FA
+         CLT = ONE
+         CRT = ONE
+         SLT = ZERO
+         SRT = ZERO
+      ELSE
+         GASMAL = .TRUE.
+         IF( GA.GT.FA ) THEN
+            PMAX = 2
+            IF( ( FA / GA ).LT.DLAMCH( 'EPS' ) ) THEN
+*
+*              Case of very large GA
+*
+               GASMAL = .FALSE.
+               SSMAX = GA
+               IF( HA.GT.ONE ) THEN
+                  SSMIN = FA / ( GA / HA )
+               ELSE
+                  SSMIN = ( FA / GA )*HA
+               END IF
+               CLT = ONE
+               SLT = HT / GT
+               SRT = ONE
+               CRT = FT / GT
+            END IF
+         END IF
+         IF( GASMAL ) THEN
+*
+*           Normal case
+*
+            D = FA - HA
+            IF( D.EQ.FA ) THEN
+*
+*              Copes with infinite F or H
+*
+               L = ONE
+            ELSE
+               L = D / FA
+            END IF
+*
+*           Note that 0 .le. L .le. 1
+*
+            M = GT / FT
+*
+*           Note that abs(M) .le. 1/macheps
+*
+            T = TWO - L
+*
+*           Note that T .ge. 1
+*
+            MM = M*M
+            TT = T*T
+            S = SQRT( TT+MM )
+*
+*           Note that 1 .le. S .le. 1 + 1/macheps
+*
+            IF( L.EQ.ZERO ) THEN
+               R = ABS( M )
+            ELSE
+               R = SQRT( L*L+MM )
+            END IF
+*
+*           Note that 0 .le. R .le. 1 + 1/macheps
+*
+            A = HALF*( S+R )
+*
+*           Note that 1 .le. A .le. 1 + abs(M)
+*
+            SSMIN = HA / A
+            SSMAX = FA*A
+            IF( MM.EQ.ZERO ) THEN
+*
+*              Note that M is very tiny
+*
+               IF( L.EQ.ZERO ) THEN
+                  T = SIGN( TWO, FT )*SIGN( ONE, GT )
+               ELSE
+                  T = GT / SIGN( D, FT ) + M / T
+               END IF
+            ELSE
+               T = ( M / ( S+T )+M / ( R+L ) )*( ONE+A )
+            END IF
+            L = SQRT( T*T+FOUR )
+            CRT = TWO / L
+            SRT = T / L
+            CLT = ( CRT+SRT*M ) / A
+            SLT = ( HT / FT )*SRT / A
+         END IF
+      END IF
+      IF( SWAP ) THEN
+         CSL = SRT
+         SNL = CRT
+         CSR = SLT
+         SNR = CLT
+      ELSE
+         CSL = CLT
+         SNL = SLT
+         CSR = CRT
+         SNR = SRT
+      END IF
+*
+*     Correct signs of SSMAX and SSMIN
+*
+      IF( PMAX.EQ.1 )
+     $   TSIGN = SIGN( ONE, CSR )*SIGN( ONE, CSL )*SIGN( ONE, F )
+      IF( PMAX.EQ.2 )
+     $   TSIGN = SIGN( ONE, SNR )*SIGN( ONE, CSL )*SIGN( ONE, G )
+      IF( PMAX.EQ.3 )
+     $   TSIGN = SIGN( ONE, SNR )*SIGN( ONE, SNL )*SIGN( ONE, H )
+      SSMAX = SIGN( SSMAX, TSIGN )
+      SSMIN = SIGN( SSMIN, TSIGN*SIGN( ONE, F )*SIGN( ONE, H ) )
+      RETURN
+*
+*     End of DLASV2
+*
+      END
diff --git a/libcruft/lapack/dlaswp.f b/libcruft/lapack/dlaswp.f
new file mode 100644
index 0000000..a11a87e
--- /dev/null
+++ b/libcruft/lapack/dlaswp.f
@@ -0,0 +1,119 @@
+      SUBROUTINE DLASWP( N, A, LDA, K1, K2, IPIV, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, K1, K2, LDA, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASWP performs a series of row interchanges on the matrix A.
+*  One row interchange is initiated for each of rows K1 through K2 of A.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the matrix of column dimension N to which the row
+*          interchanges will be applied.
+*          On exit, the permuted matrix.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*
+*  K1      (input) INTEGER
+*          The first element of IPIV for which a row interchange will
+*          be done.
+*
+*  K2      (input) INTEGER
+*          The last element of IPIV for which a row interchange will
+*          be done.
+*
+*  IPIV    (input) INTEGER array, dimension (K2*abs(INCX))
+*          The vector of pivot indices.  Only the elements in positions
+*          K1 through K2 of IPIV are accessed.
+*          IPIV(K) = L implies rows K and L are to be interchanged.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of IPIV.  If IPIV
+*          is negative, the pivots are applied in reverse order.
+*
+*  Further Details
+*  ===============
+*
+*  Modified by
+*   R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, I1, I2, INC, IP, IX, IX0, J, K, N32
+      DOUBLE PRECISION   TEMP
+*     ..
+*     .. Executable Statements ..
+*
+*     Interchange row I with row IPIV(I) for each of rows K1 through K2.
+*
+      IF( INCX.GT.0 ) THEN
+         IX0 = K1
+         I1 = K1
+         I2 = K2
+         INC = 1
+      ELSE IF( INCX.LT.0 ) THEN
+         IX0 = 1 + ( 1-K2 )*INCX
+         I1 = K2
+         I2 = K1
+         INC = -1
+      ELSE
+         RETURN
+      END IF
+*
+      N32 = ( N / 32 )*32
+      IF( N32.NE.0 ) THEN
+         DO 30 J = 1, N32, 32
+            IX = IX0
+            DO 20 I = I1, I2, INC
+               IP = IPIV( IX )
+               IF( IP.NE.I ) THEN
+                  DO 10 K = J, J + 31
+                     TEMP = A( I, K )
+                     A( I, K ) = A( IP, K )
+                     A( IP, K ) = TEMP
+   10             CONTINUE
+               END IF
+               IX = IX + INCX
+   20       CONTINUE
+   30    CONTINUE
+      END IF
+      IF( N32.NE.N ) THEN
+         N32 = N32 + 1
+         IX = IX0
+         DO 50 I = I1, I2, INC
+            IP = IPIV( IX )
+            IF( IP.NE.I ) THEN
+               DO 40 K = N32, N
+                  TEMP = A( I, K )
+                  A( I, K ) = A( IP, K )
+                  A( IP, K ) = TEMP
+   40          CONTINUE
+            END IF
+            IX = IX + INCX
+   50    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DLASWP
+*
+      END
diff --git a/libcruft/lapack/dlasy2.f b/libcruft/lapack/dlasy2.f
new file mode 100644
index 0000000..3ff1207
--- /dev/null
+++ b/libcruft/lapack/dlasy2.f
@@ -0,0 +1,381 @@
+      SUBROUTINE DLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,
+     $                   LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            LTRANL, LTRANR
+      INTEGER            INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2
+      DOUBLE PRECISION   SCALE, XNORM
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),
+     $                   X( LDX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in
+*
+*         op(TL)*X + ISGN*X*op(TR) = SCALE*B,
+*
+*  where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or
+*  -1.  op(T) = T or T', where T' denotes the transpose of T.
+*
+*  Arguments
+*  =========
+*
+*  LTRANL  (input) LOGICAL
+*          On entry, LTRANL specifies the op(TL):
+*             = .FALSE., op(TL) = TL,
+*             = .TRUE., op(TL) = TL'.
+*
+*  LTRANR  (input) LOGICAL
+*          On entry, LTRANR specifies the op(TR):
+*            = .FALSE., op(TR) = TR,
+*            = .TRUE., op(TR) = TR'.
+*
+*  ISGN    (input) INTEGER
+*          On entry, ISGN specifies the sign of the equation
+*          as described before. ISGN may only be 1 or -1.
+*
+*  N1      (input) INTEGER
+*          On entry, N1 specifies the order of matrix TL.
+*          N1 may only be 0, 1 or 2.
+*
+*  N2      (input) INTEGER
+*          On entry, N2 specifies the order of matrix TR.
+*          N2 may only be 0, 1 or 2.
+*
+*  TL      (input) DOUBLE PRECISION array, dimension (LDTL,2)
+*          On entry, TL contains an N1 by N1 matrix.
+*
+*  LDTL    (input) INTEGER
+*          The leading dimension of the matrix TL. LDTL >= max(1,N1).
+*
+*  TR      (input) DOUBLE PRECISION array, dimension (LDTR,2)
+*          On entry, TR contains an N2 by N2 matrix.
+*
+*  LDTR    (input) INTEGER
+*          The leading dimension of the matrix TR. LDTR >= max(1,N2).
+*
+*  B       (input) DOUBLE PRECISION array, dimension (LDB,2)
+*          On entry, the N1 by N2 matrix B contains the right-hand
+*          side of the equation.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the matrix B. LDB >= max(1,N1).
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          On exit, SCALE contains the scale factor. SCALE is chosen
+*          less than or equal to 1 to prevent the solution overflowing.
+*
+*  X       (output) DOUBLE PRECISION array, dimension (LDX,2)
+*          On exit, X contains the N1 by N2 solution.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of the matrix X. LDX >= max(1,N1).
+*
+*  XNORM   (output) DOUBLE PRECISION
+*          On exit, XNORM is the infinity-norm of the solution.
+*
+*  INFO    (output) INTEGER
+*          On exit, INFO is set to
+*             0: successful exit.
+*             1: TL and TR have too close eigenvalues, so TL or
+*                TR is perturbed to get a nonsingular equation.
+*          NOTE: In the interests of speed, this routine does not
+*                check the inputs for errors.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   TWO, HALF, EIGHT
+      PARAMETER          ( TWO = 2.0D+0, HALF = 0.5D+0, EIGHT = 8.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            BSWAP, XSWAP
+      INTEGER            I, IP, IPIV, IPSV, J, JP, JPSV, K
+      DOUBLE PRECISION   BET, EPS, GAM, L21, SGN, SMIN, SMLNUM, TAU1,
+     $                   TEMP, U11, U12, U22, XMAX
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            BSWPIV( 4 ), XSWPIV( 4 )
+      INTEGER            JPIV( 4 ), LOCL21( 4 ), LOCU12( 4 ),
+     $                   LOCU22( 4 )
+      DOUBLE PRECISION   BTMP( 4 ), T16( 4, 4 ), TMP( 4 ), X2( 2 )
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           IDAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DCOPY, DSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Data statements ..
+      DATA               LOCU12 / 3, 4, 1, 2 / , LOCL21 / 2, 1, 4, 3 / ,
+     $                   LOCU22 / 4, 3, 2, 1 /
+      DATA               XSWPIV / .FALSE., .FALSE., .TRUE., .TRUE. /
+      DATA               BSWPIV / .FALSE., .TRUE., .FALSE., .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+*     Do not check the input parameters for errors
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N1.EQ.0 .OR. N2.EQ.0 )
+     $   RETURN
+*
+*     Set constants to control overflow
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' ) / EPS
+      SGN = ISGN
+*
+      K = N1 + N1 + N2 - 2
+      GO TO ( 10, 20, 30, 50 )K
+*
+*     1 by 1: TL11*X + SGN*X*TR11 = B11
+*
+   10 CONTINUE
+      TAU1 = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      BET = ABS( TAU1 )
+      IF( BET.LE.SMLNUM ) THEN
+         TAU1 = SMLNUM
+         BET = SMLNUM
+         INFO = 1
+      END IF
+*
+      SCALE = ONE
+      GAM = ABS( B( 1, 1 ) )
+      IF( SMLNUM*GAM.GT.BET )
+     $   SCALE = ONE / GAM
+*
+      X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / TAU1
+      XNORM = ABS( X( 1, 1 ) )
+      RETURN
+*
+*     1 by 2:
+*     TL11*[X11 X12] + ISGN*[X11 X12]*op[TR11 TR12]  = [B11 B12]
+*                                       [TR21 TR22]
+*
+   20 CONTINUE
+*
+      SMIN = MAX( EPS*MAX( ABS( TL( 1, 1 ) ), ABS( TR( 1, 1 ) ),
+     $       ABS( TR( 1, 2 ) ), ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) ),
+     $       SMLNUM )
+      TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      TMP( 4 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )
+      IF( LTRANR ) THEN
+         TMP( 2 ) = SGN*TR( 2, 1 )
+         TMP( 3 ) = SGN*TR( 1, 2 )
+      ELSE
+         TMP( 2 ) = SGN*TR( 1, 2 )
+         TMP( 3 ) = SGN*TR( 2, 1 )
+      END IF
+      BTMP( 1 ) = B( 1, 1 )
+      BTMP( 2 ) = B( 1, 2 )
+      GO TO 40
+*
+*     2 by 1:
+*          op[TL11 TL12]*[X11] + ISGN* [X11]*TR11  = [B11]
+*            [TL21 TL22] [X21]         [X21]         [B21]
+*
+   30 CONTINUE
+      SMIN = MAX( EPS*MAX( ABS( TR( 1, 1 ) ), ABS( TL( 1, 1 ) ),
+     $       ABS( TL( 1, 2 ) ), ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) ),
+     $       SMLNUM )
+      TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      TMP( 4 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )
+      IF( LTRANL ) THEN
+         TMP( 2 ) = TL( 1, 2 )
+         TMP( 3 ) = TL( 2, 1 )
+      ELSE
+         TMP( 2 ) = TL( 2, 1 )
+         TMP( 3 ) = TL( 1, 2 )
+      END IF
+      BTMP( 1 ) = B( 1, 1 )
+      BTMP( 2 ) = B( 2, 1 )
+   40 CONTINUE
+*
+*     Solve 2 by 2 system using complete pivoting.
+*     Set pivots less than SMIN to SMIN.
+*
+      IPIV = IDAMAX( 4, TMP, 1 )
+      U11 = TMP( IPIV )
+      IF( ABS( U11 ).LE.SMIN ) THEN
+         INFO = 1
+         U11 = SMIN
+      END IF
+      U12 = TMP( LOCU12( IPIV ) )
+      L21 = TMP( LOCL21( IPIV ) ) / U11
+      U22 = TMP( LOCU22( IPIV ) ) - U12*L21
+      XSWAP = XSWPIV( IPIV )
+      BSWAP = BSWPIV( IPIV )
+      IF( ABS( U22 ).LE.SMIN ) THEN
+         INFO = 1
+         U22 = SMIN
+      END IF
+      IF( BSWAP ) THEN
+         TEMP = BTMP( 2 )
+         BTMP( 2 ) = BTMP( 1 ) - L21*TEMP
+         BTMP( 1 ) = TEMP
+      ELSE
+         BTMP( 2 ) = BTMP( 2 ) - L21*BTMP( 1 )
+      END IF
+      SCALE = ONE
+      IF( ( TWO*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( U22 ) .OR.
+     $    ( TWO*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( U11 ) ) THEN
+         SCALE = HALF / MAX( ABS( BTMP( 1 ) ), ABS( BTMP( 2 ) ) )
+         BTMP( 1 ) = BTMP( 1 )*SCALE
+         BTMP( 2 ) = BTMP( 2 )*SCALE
+      END IF
+      X2( 2 ) = BTMP( 2 ) / U22
+      X2( 1 ) = BTMP( 1 ) / U11 - ( U12 / U11 )*X2( 2 )
+      IF( XSWAP ) THEN
+         TEMP = X2( 2 )
+         X2( 2 ) = X2( 1 )
+         X2( 1 ) = TEMP
+      END IF
+      X( 1, 1 ) = X2( 1 )
+      IF( N1.EQ.1 ) THEN
+         X( 1, 2 ) = X2( 2 )
+         XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
+      ELSE
+         X( 2, 1 ) = X2( 2 )
+         XNORM = MAX( ABS( X( 1, 1 ) ), ABS( X( 2, 1 ) ) )
+      END IF
+      RETURN
+*
+*     2 by 2:
+*     op[TL11 TL12]*[X11 X12] +ISGN* [X11 X12]*op[TR11 TR12] = [B11 B12]
+*       [TL21 TL22] [X21 X22]        [X21 X22]   [TR21 TR22]   [B21 B22]
+*
+*     Solve equivalent 4 by 4 system using complete pivoting.
+*     Set pivots less than SMIN to SMIN.
+*
+   50 CONTINUE
+      SMIN = MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),
+     $       ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )
+      SMIN = MAX( SMIN, ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),
+     $       ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )
+      SMIN = MAX( EPS*SMIN, SMLNUM )
+      BTMP( 1 ) = ZERO
+      CALL DCOPY( 16, BTMP, 0, T16, 1 )
+      T16( 1, 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      T16( 2, 2 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )
+      T16( 3, 3 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )
+      T16( 4, 4 ) = TL( 2, 2 ) + SGN*TR( 2, 2 )
+      IF( LTRANL ) THEN
+         T16( 1, 2 ) = TL( 2, 1 )
+         T16( 2, 1 ) = TL( 1, 2 )
+         T16( 3, 4 ) = TL( 2, 1 )
+         T16( 4, 3 ) = TL( 1, 2 )
+      ELSE
+         T16( 1, 2 ) = TL( 1, 2 )
+         T16( 2, 1 ) = TL( 2, 1 )
+         T16( 3, 4 ) = TL( 1, 2 )
+         T16( 4, 3 ) = TL( 2, 1 )
+      END IF
+      IF( LTRANR ) THEN
+         T16( 1, 3 ) = SGN*TR( 1, 2 )
+         T16( 2, 4 ) = SGN*TR( 1, 2 )
+         T16( 3, 1 ) = SGN*TR( 2, 1 )
+         T16( 4, 2 ) = SGN*TR( 2, 1 )
+      ELSE
+         T16( 1, 3 ) = SGN*TR( 2, 1 )
+         T16( 2, 4 ) = SGN*TR( 2, 1 )
+         T16( 3, 1 ) = SGN*TR( 1, 2 )
+         T16( 4, 2 ) = SGN*TR( 1, 2 )
+      END IF
+      BTMP( 1 ) = B( 1, 1 )
+      BTMP( 2 ) = B( 2, 1 )
+      BTMP( 3 ) = B( 1, 2 )
+      BTMP( 4 ) = B( 2, 2 )
+*
+*     Perform elimination
+*
+      DO 100 I = 1, 3
+         XMAX = ZERO
+         DO 70 IP = I, 4
+            DO 60 JP = I, 4
+               IF( ABS( T16( IP, JP ) ).GE.XMAX ) THEN
+                  XMAX = ABS( T16( IP, JP ) )
+                  IPSV = IP
+                  JPSV = JP
+               END IF
+   60       CONTINUE
+   70    CONTINUE
+         IF( IPSV.NE.I ) THEN
+            CALL DSWAP( 4, T16( IPSV, 1 ), 4, T16( I, 1 ), 4 )
+            TEMP = BTMP( I )
+            BTMP( I ) = BTMP( IPSV )
+            BTMP( IPSV ) = TEMP
+         END IF
+         IF( JPSV.NE.I )
+     $      CALL DSWAP( 4, T16( 1, JPSV ), 1, T16( 1, I ), 1 )
+         JPIV( I ) = JPSV
+         IF( ABS( T16( I, I ) ).LT.SMIN ) THEN
+            INFO = 1
+            T16( I, I ) = SMIN
+         END IF
+         DO 90 J = I + 1, 4
+            T16( J, I ) = T16( J, I ) / T16( I, I )
+            BTMP( J ) = BTMP( J ) - T16( J, I )*BTMP( I )
+            DO 80 K = I + 1, 4
+               T16( J, K ) = T16( J, K ) - T16( J, I )*T16( I, K )
+   80       CONTINUE
+   90    CONTINUE
+  100 CONTINUE
+      IF( ABS( T16( 4, 4 ) ).LT.SMIN )
+     $   T16( 4, 4 ) = SMIN
+      SCALE = ONE
+      IF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.
+     $    ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.
+     $    ( EIGHT*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T16( 3, 3 ) ) .OR.
+     $    ( EIGHT*SMLNUM )*ABS( BTMP( 4 ) ).GT.ABS( T16( 4, 4 ) ) ) THEN
+         SCALE = ( ONE / EIGHT ) / MAX( ABS( BTMP( 1 ) ),
+     $           ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ), ABS( BTMP( 4 ) ) )
+         BTMP( 1 ) = BTMP( 1 )*SCALE
+         BTMP( 2 ) = BTMP( 2 )*SCALE
+         BTMP( 3 ) = BTMP( 3 )*SCALE
+         BTMP( 4 ) = BTMP( 4 )*SCALE
+      END IF
+      DO 120 I = 1, 4
+         K = 5 - I
+         TEMP = ONE / T16( K, K )
+         TMP( K ) = BTMP( K )*TEMP
+         DO 110 J = K + 1, 4
+            TMP( K ) = TMP( K ) - ( TEMP*T16( K, J ) )*TMP( J )
+  110    CONTINUE
+  120 CONTINUE
+      DO 130 I = 1, 3
+         IF( JPIV( 4-I ).NE.4-I ) THEN
+            TEMP = TMP( 4-I )
+            TMP( 4-I ) = TMP( JPIV( 4-I ) )
+            TMP( JPIV( 4-I ) ) = TEMP
+         END IF
+  130 CONTINUE
+      X( 1, 1 ) = TMP( 1 )
+      X( 2, 1 ) = TMP( 2 )
+      X( 1, 2 ) = TMP( 3 )
+      X( 2, 2 ) = TMP( 4 )
+      XNORM = MAX( ABS( TMP( 1 ) )+ABS( TMP( 3 ) ),
+     $        ABS( TMP( 2 ) )+ABS( TMP( 4 ) ) )
+      RETURN
+*
+*     End of DLASY2
+*
+      END
diff --git a/libcruft/lapack/dlatbs.f b/libcruft/lapack/dlatbs.f
new file mode 100644
index 0000000..48d8c2e
--- /dev/null
+++ b/libcruft/lapack/dlatbs.f
@@ -0,0 +1,723 @@
+      SUBROUTINE DLATBS( UPLO, TRANS, DIAG, NORMIN, N, KD, AB, LDAB, X,
+     $                   SCALE, CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, KD, LDAB, N
+      DOUBLE PRECISION   SCALE
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   AB( LDAB, * ), CNORM( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLATBS solves one of the triangular systems
+*
+*     A *x = s*b  or  A'*x = s*b
+*
+*  with scaling to prevent overflow, where A is an upper or lower
+*  triangular band matrix.  Here A' denotes the transpose of A, x and b
+*  are n-element vectors, and s is a scaling factor, usually less than
+*  or equal to 1, chosen so that the components of x will be less than
+*  the overflow threshold.  If the unscaled problem will not cause
+*  overflow, the Level 2 BLAS routine DTBSV is called.  If the matrix A
+*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a
+*  non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b  (No transpose)
+*          = 'T':  Solve A'* x = s*b  (Transpose)
+*          = 'C':  Solve A'* x = s*b  (Conjugate transpose = Transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of subdiagonals or superdiagonals in the
+*          triangular matrix A.  KD >= 0.
+*
+*  AB      (input) DOUBLE PRECISION array, dimension (LDAB,N)
+*          The upper or lower triangular band matrix A, stored in the
+*          first KD+1 rows of the array. The j-th column of A is stored
+*          in the j-th column of the array AB as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  X       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scaling factor s for the triangular system
+*             A * x = s*b  or  A'* x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) DOUBLE PRECISION array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, DTBSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTBSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A'*x = b.  The basic
+*  algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call DTBSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST, JLEN, MAIND
+      DOUBLE PRECISION   BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,
+     $                   TMAX, TSCAL, USCAL, XBND, XJ, XMAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DASUM, DDOT, DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DASUM, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DSCAL, DTBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLATBS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               JLEN = MIN( KD, J-1 )
+               CNORM( J ) = DASUM( JLEN, AB( KD+1-JLEN, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N
+               JLEN = MIN( KD, N-J )
+               IF( JLEN.GT.0 ) THEN
+                  CNORM( J ) = DASUM( JLEN, AB( 2, J ), 1 )
+               ELSE
+                  CNORM( J ) = ZERO
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM.
+*
+      IMAX = IDAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = ONE / ( SMLNUM*TMAX )
+         CALL DSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine DTBSV can be used.
+*
+      J = IDAMAX( N, X, 1 )
+      XMAX = ABS( X( J ) )
+      XBND = XMAX
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 50
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 30 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              M(j) = G(j-1) / abs(A(j,j))
+*
+               TJJ = ABS( AB( MAIND, J ) )
+               XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   30       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   40       CONTINUE
+         END IF
+   50    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A' * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 80
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 60 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+*              M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+               TJJ = ABS( AB( MAIND, J ) )
+               IF( XJ.GT.TJJ )
+     $            XBND = XBND*( TJJ / XJ )
+   60       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   70       CONTINUE
+         END IF
+   80    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL DTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = BIGNUM / XMAX
+            CALL DSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 110 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = ABS( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = AB( MAIND, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 100
+               END IF
+               TJJ = ABS( TJJS )
+               IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                  IF( TJJ.LT.ONE ) THEN
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                        REC = ONE / XJ
+                        CALL DSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                  END IF
+                  X( J ) = X( J ) / TJJS
+                  XJ = ABS( X( J ) )
+               ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                  IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                     REC = ( TJJ*BIGNUM ) / XJ
+                     IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                        REC = REC / CNORM( J )
+                     END IF
+                     CALL DSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+                  X( J ) = X( J ) / TJJS
+                  XJ = ABS( X( J ) )
+               ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                  DO 90 I = 1, N
+                     X( I ) = ZERO
+   90             CONTINUE
+                  X( J ) = ONE
+                  XJ = ONE
+                  SCALE = ZERO
+                  XMAX = ZERO
+               END IF
+  100          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL DSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL DSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(max(1,j-kd):j-1) := x(max(1,j-kd):j-1) -
+*                                             x(j)* A(max(1,j-kd):j-1,j)
+*
+                     JLEN = MIN( KD, J-1 )
+                     CALL DAXPY( JLEN, -X( J )*TSCAL,
+     $                           AB( KD+1-JLEN, J ), 1, X( J-JLEN ), 1 )
+                     I = IDAMAX( J-1, X, 1 )
+                     XMAX = ABS( X( I ) )
+                  END IF
+               ELSE IF( J.LT.N ) THEN
+*
+*                 Compute the update
+*                    x(j+1:min(j+kd,n)) := x(j+1:min(j+kd,n)) -
+*                                          x(j) * A(j+1:min(j+kd,n),j)
+*
+                  JLEN = MIN( KD, N-J )
+                  IF( JLEN.GT.0 )
+     $               CALL DAXPY( JLEN, -X( J )*TSCAL, AB( 2, J ), 1,
+     $                           X( J+1 ), 1 )
+                  I = J + IDAMAX( N-J, X( J+1 ), 1 )
+                  XMAX = ABS( X( I ) )
+               END IF
+  110       CONTINUE
+*
+         ELSE
+*
+*           Solve A' * x = b
+*
+            DO 160 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = ABS( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                  TJJ = ABS( TJJS )
+                  IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                     REC = MIN( ONE, REC*TJJ )
+                     USCAL = USCAL / TJJS
+                  END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL DSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               SUMJ = ZERO
+               IF( USCAL.EQ.ONE ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call DDOT to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     SUMJ = DDOT( JLEN, AB( KD+1-JLEN, J ), 1,
+     $                      X( J-JLEN ), 1 )
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     IF( JLEN.GT.0 )
+     $                  SUMJ = DDOT( JLEN, AB( 2, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     DO 120 I = 1, JLEN
+                        SUMJ = SUMJ + ( AB( KD+I-JLEN, J )*USCAL )*
+     $                         X( J-JLEN-1+I )
+  120                CONTINUE
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     DO 130 I = 1, JLEN
+                        SUMJ = SUMJ + ( AB( I+1, J )*USCAL )*X( J+I )
+  130                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.TSCAL ) THEN
+*
+*                 Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - SUMJ
+                  XJ = ABS( X( J ) )
+                  IF( NOUNIT ) THEN
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 150
+                  END IF
+                  TJJ = ABS( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                           REC = ONE / XJ
+                           CALL DSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        CALL DSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                  ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0, and compute a solution to A'*x = 0.
+*
+                     DO 140 I = 1, N
+                        X( I ) = ZERO
+  140                CONTINUE
+                     X( J ) = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  150             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - sumj if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = X( J ) / TJJS - SUMJ
+               END IF
+               XMAX = MAX( XMAX, ABS( X( J ) ) )
+  160       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL DSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of DLATBS
+*
+      END
diff --git a/libcruft/lapack/dlatrd.f b/libcruft/lapack/dlatrd.f
new file mode 100644
index 0000000..27bf9b9
--- /dev/null
+++ b/libcruft/lapack/dlatrd.f
@@ -0,0 +1,258 @@
+      SUBROUTINE DLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDW, N, NB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), E( * ), TAU( * ), W( LDW, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLATRD reduces NB rows and columns of a real symmetric matrix A to
+*  symmetric tridiagonal form by an orthogonal similarity
+*  transformation Q' * A * Q, and returns the matrices V and W which are
+*  needed to apply the transformation to the unreduced part of A.
+*
+*  If UPLO = 'U', DLATRD reduces the last NB rows and columns of a
+*  matrix, of which the upper triangle is supplied;
+*  if UPLO = 'L', DLATRD reduces the first NB rows and columns of a
+*  matrix, of which the lower triangle is supplied.
+*
+*  This is an auxiliary routine called by DSYTRD.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored:
+*          = 'U': Upper triangular
+*          = 'L': Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of rows and columns to be reduced.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit:
+*          if UPLO = 'U', the last NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements above the diagonal
+*            with the array TAU, represent the orthogonal matrix Q as a
+*            product of elementary reflectors;
+*          if UPLO = 'L', the first NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements below the diagonal
+*            with the array TAU, represent the  orthogonal matrix Q as a
+*            product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= (1,N).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (N-1)
+*          If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal
+*          elements of the last NB columns of the reduced matrix;
+*          if UPLO = 'L', E(1:nb) contains the subdiagonal elements of
+*          the first NB columns of the reduced matrix.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (N-1)
+*          The scalar factors of the elementary reflectors, stored in
+*          TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'.
+*          See Further Details.
+*
+*  W       (output) DOUBLE PRECISION array, dimension (LDW,NB)
+*          The n-by-nb matrix W required to update the unreduced part
+*          of A.
+*
+*  LDW     (input) INTEGER
+*          The leading dimension of the array W. LDW >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n) H(n-1) . . . H(n-nb+1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i),
+*  and tau in TAU(i-1).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),
+*  and tau in TAU(i).
+*
+*  The elements of the vectors v together form the n-by-nb matrix V
+*  which is needed, with W, to apply the transformation to the unreduced
+*  part of the matrix, using a symmetric rank-2k update of the form:
+*  A := A - V*W' - W*V'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5 and nb = 2:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  a   a   a   v4  v5 )              (  d                  )
+*    (      a   a   v4  v5 )              (  1   d              )
+*    (          a   1   v5 )              (  v1  1   a          )
+*    (              d   1  )              (  v1  v2  a   a      )
+*    (                  d  )              (  v1  v2  a   a   a  )
+*
+*  where d denotes a diagonal element of the reduced matrix, a denotes
+*  an element of the original matrix that is unchanged, and vi denotes
+*  an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, HALF
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IW
+      DOUBLE PRECISION   ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DGEMV, DLARFG, DSCAL, DSYMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DDOT
+      EXTERNAL           LSAME, DDOT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Reduce last NB columns of upper triangle
+*
+         DO 10 I = N, N - NB + 1, -1
+            IW = I - N + NB
+            IF( I.LT.N ) THEN
+*
+*              Update A(1:i,i)
+*
+               CALL DGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', I, N-I, -ONE, W( 1, IW+1 ),
+     $                     LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 )
+            END IF
+            IF( I.GT.1 ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(1:i-2,i)
+*
+               CALL DLARFG( I-1, A( I-1, I ), A( 1, I ), 1, TAU( I-1 ) )
+               E( I-1 ) = A( I-1, I )
+               A( I-1, I ) = ONE
+*
+*              Compute W(1:i-1,i)
+*
+               CALL DSYMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1,
+     $                     ZERO, W( 1, IW ), 1 )
+               IF( I.LT.N ) THEN
+                  CALL DGEMV( 'Transpose', I-1, N-I, ONE, W( 1, IW+1 ),
+     $                        LDW, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )
+                  CALL DGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+                  CALL DGEMV( 'Transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                        LDA, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )
+                  CALL DGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+               END IF
+               CALL DSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 )
+               ALPHA = -HALF*TAU( I-1 )*DDOT( I-1, W( 1, IW ), 1,
+     $                 A( 1, I ), 1 )
+               CALL DAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 )
+            END IF
+*
+   10    CONTINUE
+      ELSE
+*
+*        Reduce first NB columns of lower triangle
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i:n,i)
+*
+            CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 )
+            CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ),
+     $                  LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 )
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:n,i)
+*
+               CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,
+     $                      TAU( I ) )
+               E( I ) = A( I+1, I )
+               A( I+1, I ) = ONE
+*
+*              Compute W(i+1:n,i)
+*
+               CALL DSYMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, W( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', N-I, I-1, ONE, W( I+1, 1 ), LDW,
+     $                     A( I+1, I ), 1, ZERO, W( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL DGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, W( 1, I ), 1 )
+               CALL DGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, 1 ),
+     $                     LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL DSCAL( N-I, TAU( I ), W( I+1, I ), 1 )
+               ALPHA = -HALF*TAU( I )*DDOT( N-I, W( I+1, I ), 1,
+     $                 A( I+1, I ), 1 )
+               CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), 1 )
+            END IF
+*
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DLATRD
+*
+      END
diff --git a/libcruft/lapack/dlatrs.f b/libcruft/lapack/dlatrs.f
new file mode 100644
index 0000000..bbd3a9e
--- /dev/null
+++ b/libcruft/lapack/dlatrs.f
@@ -0,0 +1,701 @@
+      SUBROUTINE DLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
+     $                   CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   SCALE
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), CNORM( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLATRS solves one of the triangular systems
+*
+*     A *x = s*b  or  A'*x = s*b
+*
+*  with scaling to prevent overflow.  Here A is an upper or lower
+*  triangular matrix, A' denotes the transpose of A, x and b are
+*  n-element vectors, and s is a scaling factor, usually less than
+*  or equal to 1, chosen so that the components of x will be less than
+*  the overflow threshold.  If the unscaled problem will not cause
+*  overflow, the Level 2 BLAS routine DTRSV is called.  If the matrix A
+*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a
+*  non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b  (No transpose)
+*          = 'T':  Solve A'* x = s*b  (Transpose)
+*          = 'C':  Solve A'* x = s*b  (Conjugate transpose = Transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max (1,N).
+*
+*  X       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scaling factor s for the triangular system
+*             A * x = s*b  or  A'* x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) DOUBLE PRECISION array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, DTRSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTRSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A'*x = b.  The basic
+*  algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call DTRSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST
+      DOUBLE PRECISION   BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,
+     $                   TMAX, TSCAL, USCAL, XBND, XJ, XMAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DASUM, DDOT, DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DASUM, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DSCAL, DTRSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLATRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               CNORM( J ) = DASUM( J-1, A( 1, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N - 1
+               CNORM( J ) = DASUM( N-J, A( J+1, J ), 1 )
+   20       CONTINUE
+            CNORM( N ) = ZERO
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM.
+*
+      IMAX = IDAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = ONE / ( SMLNUM*TMAX )
+         CALL DSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine DTRSV can be used.
+*
+      J = IDAMAX( N, X, 1 )
+      XMAX = ABS( X( J ) )
+      XBND = XMAX
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 50
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 30 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              M(j) = G(j-1) / abs(A(j,j))
+*
+               TJJ = ABS( A( J, J ) )
+               XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   30       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   40       CONTINUE
+         END IF
+   50    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A' * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 80
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 60 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+*              M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+               TJJ = ABS( A( J, J ) )
+               IF( XJ.GT.TJJ )
+     $            XBND = XBND*( TJJ / XJ )
+   60       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   70       CONTINUE
+         END IF
+   80    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL DTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = BIGNUM / XMAX
+            CALL DSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 110 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = ABS( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = A( J, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 100
+               END IF
+               TJJ = ABS( TJJS )
+               IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                  IF( TJJ.LT.ONE ) THEN
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                        REC = ONE / XJ
+                        CALL DSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                  END IF
+                  X( J ) = X( J ) / TJJS
+                  XJ = ABS( X( J ) )
+               ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                  IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                     REC = ( TJJ*BIGNUM ) / XJ
+                     IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                        REC = REC / CNORM( J )
+                     END IF
+                     CALL DSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+                  X( J ) = X( J ) / TJJS
+                  XJ = ABS( X( J ) )
+               ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                  DO 90 I = 1, N
+                     X( I ) = ZERO
+   90             CONTINUE
+                  X( J ) = ONE
+                  XJ = ONE
+                  SCALE = ZERO
+                  XMAX = ZERO
+               END IF
+  100          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL DSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL DSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
+*
+                     CALL DAXPY( J-1, -X( J )*TSCAL, A( 1, J ), 1, X,
+     $                           1 )
+                     I = IDAMAX( J-1, X, 1 )
+                     XMAX = ABS( X( I ) )
+                  END IF
+               ELSE
+                  IF( J.LT.N ) THEN
+*
+*                    Compute the update
+*                       x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
+*
+                     CALL DAXPY( N-J, -X( J )*TSCAL, A( J+1, J ), 1,
+     $                           X( J+1 ), 1 )
+                     I = J + IDAMAX( N-J, X( J+1 ), 1 )
+                     XMAX = ABS( X( I ) )
+                  END IF
+               END IF
+  110       CONTINUE
+*
+         ELSE
+*
+*           Solve A' * x = b
+*
+            DO 160 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = ABS( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                  TJJ = ABS( TJJS )
+                  IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                     REC = MIN( ONE, REC*TJJ )
+                     USCAL = USCAL / TJJS
+                  END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL DSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               SUMJ = ZERO
+               IF( USCAL.EQ.ONE ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call DDOT to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     SUMJ = DDOT( J-1, A( 1, J ), 1, X, 1 )
+                  ELSE IF( J.LT.N ) THEN
+                     SUMJ = DDOT( N-J, A( J+1, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     DO 120 I = 1, J - 1
+                        SUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )
+  120                CONTINUE
+                  ELSE IF( J.LT.N ) THEN
+                     DO 130 I = J + 1, N
+                        SUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )
+  130                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.TSCAL ) THEN
+*
+*                 Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - SUMJ
+                  XJ = ABS( X( J ) )
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 150
+                  END IF
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                  TJJ = ABS( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                           REC = ONE / XJ
+                           CALL DSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        CALL DSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                  ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0, and compute a solution to A'*x = 0.
+*
+                     DO 140 I = 1, N
+                        X( I ) = ZERO
+  140                CONTINUE
+                     X( J ) = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  150             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j)  - sumj if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = X( J ) / TJJS - SUMJ
+               END IF
+               XMAX = MAX( XMAX, ABS( X( J ) ) )
+  160       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL DSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of DLATRS
+*
+      END
diff --git a/libcruft/lapack/dlatrz.f b/libcruft/lapack/dlatrz.f
new file mode 100644
index 0000000..e1a2cf9
--- /dev/null
+++ b/libcruft/lapack/dlatrz.f
@@ -0,0 +1,127 @@
+      SUBROUTINE DLATRZ( M, N, L, A, LDA, TAU, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            L, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLATRZ factors the M-by-(M+L) real upper trapezoidal matrix
+*  [ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R  0 ) * Z, by means
+*  of orthogonal transformations.  Z is an (M+L)-by-(M+L) orthogonal
+*  matrix and, R and A1 are M-by-M upper triangular matrices.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing the
+*          meaningful part of the Householder vectors. N-M >= L >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements N-L+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          orthogonal matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (M)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an l element vector. tau and z( k )
+*  are chosen to annihilate the elements of the kth row of A2.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A2, such that the elements of z( k ) are
+*  in  a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A1.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARFG, DLARZ
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      DO 20 I = M, 1, -1
+*
+*        Generate elementary reflector H(i) to annihilate
+*        [ A(i,i) A(i,n-l+1:n) ]
+*
+         CALL DLARFG( L+1, A( I, I ), A( I, N-L+1 ), LDA, TAU( I ) )
+*
+*        Apply H(i) to A(1:i-1,i:n) from the right
+*
+         CALL DLARZ( 'Right', I-1, N-I+1, L, A( I, N-L+1 ), LDA,
+     $               TAU( I ), A( 1, I ), LDA, WORK )
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of DLATRZ
+*
+      END
diff --git a/libcruft/lapack/dlauu2.f b/libcruft/lapack/dlauu2.f
new file mode 100644
index 0000000..092bdda
--- /dev/null
+++ b/libcruft/lapack/dlauu2.f
@@ -0,0 +1,135 @@
+      SUBROUTINE DLAUU2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAUU2 computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the unblocked form of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DDOT
+      EXTERNAL           LSAME, DDOT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLAUU2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the product U * U'.
+*
+         DO 10 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = DDOT( N-I+1, A( I, I ), LDA, A( I, I ), LDA )
+               CALL DGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, AII, A( 1, I ), 1 )
+            ELSE
+               CALL DSCAL( I, AII, A( 1, I ), 1 )
+            END IF
+   10    CONTINUE
+*
+      ELSE
+*
+*        Compute the product L' * L.
+*
+         DO 20 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = DDOT( N-I+1, A( I, I ), 1, A( I, I ), 1 )
+               CALL DGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,
+     $                     A( I+1, I ), 1, AII, A( I, 1 ), LDA )
+            ELSE
+               CALL DSCAL( I, AII, A( I, 1 ), LDA )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DLAUU2
+*
+      END
diff --git a/libcruft/lapack/dlauum.f b/libcruft/lapack/dlauum.f
new file mode 100644
index 0000000..4857c52
--- /dev/null
+++ b/libcruft/lapack/dlauum.f
@@ -0,0 +1,155 @@
+      SUBROUTINE DLAUUM( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAUUM computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the blocked form of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, IB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DLAUU2, DSYRK, DTRMM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DLAUUM', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'DLAUUM', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL DLAUU2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute the product U * U'.
+*
+            DO 10 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Non-unit',
+     $                     I-1, IB, ONE, A( I, I ), LDA, A( 1, I ),
+     $                     LDA )
+               CALL DLAUU2( 'Upper', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL DGEMM( 'No transpose', 'Transpose', I-1, IB,
+     $                        N-I-IB+1, ONE, A( 1, I+IB ), LDA,
+     $                        A( I, I+IB ), LDA, ONE, A( 1, I ), LDA )
+                  CALL DSYRK( 'Upper', 'No transpose', IB, N-I-IB+1,
+     $                        ONE, A( I, I+IB ), LDA, ONE, A( I, I ),
+     $                        LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute the product L' * L.
+*
+            DO 20 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL DTRMM( 'Left', 'Lower', 'Transpose', 'Non-unit', IB,
+     $                     I-1, ONE, A( I, I ), LDA, A( I, 1 ), LDA )
+               CALL DLAUU2( 'Lower', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL DGEMM( 'Transpose', 'No transpose', IB, I-1,
+     $                        N-I-IB+1, ONE, A( I+IB, I ), LDA,
+     $                        A( I+IB, 1 ), LDA, ONE, A( I, 1 ), LDA )
+                  CALL DSYRK( 'Lower', 'Transpose', IB, N-I-IB+1, ONE,
+     $                        A( I+IB, I ), LDA, ONE, A( I, I ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DLAUUM
+*
+      END
diff --git a/libcruft/lapack/dlazq3.f b/libcruft/lapack/dlazq3.f
new file mode 100644
index 0000000..784248f
--- /dev/null
+++ b/libcruft/lapack/dlazq3.f
@@ -0,0 +1,302 @@
+      SUBROUTINE DLAZQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
+     $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
+     $                   DN2, TAU )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            I0, ITER, N0, NDIV, NFAIL, PP, TTYPE
+      DOUBLE PRECISION   DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, QMAX,
+     $                   SIGMA, TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAZQ3 checks for deflation, computes a shift (TAU) and calls dqds.
+*  In case of failure it changes shifts, and tries again until output
+*  is positive.
+*
+*  Arguments
+*  =========
+*
+*  I0     (input) INTEGER
+*         First index.
+*
+*  N0     (input) INTEGER
+*         Last index.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( 4*N )
+*         Z holds the qd array.
+*
+*  PP     (input) INTEGER
+*         PP=0 for ping, PP=1 for pong.
+*
+*  DMIN   (output) DOUBLE PRECISION
+*         Minimum value of d.
+*
+*  SIGMA  (output) DOUBLE PRECISION
+*         Sum of shifts used in current segment.
+*
+*  DESIG  (input/output) DOUBLE PRECISION
+*         Lower order part of SIGMA
+*
+*  QMAX   (input) DOUBLE PRECISION
+*         Maximum value of q.
+*
+*  NFAIL  (output) INTEGER
+*         Number of times shift was too big.
+*
+*  ITER   (output) INTEGER
+*         Number of iterations.
+*
+*  NDIV   (output) INTEGER
+*         Number of divisions.
+*
+*  IEEE   (input) LOGICAL
+*         Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).
+*
+*  TTYPE  (input/output) INTEGER
+*         Shift type.  TTYPE is passed as an argument in order to save
+*         its value between calls to DLAZQ3
+*
+*  DMIN1  (input/output) REAL
+*  DMIN2  (input/output) REAL
+*  DN     (input/output) REAL
+*  DN1    (input/output) REAL
+*  DN2    (input/output) REAL
+*  TAU    (input/output) REAL
+*         These are passed as arguments in order to save their values
+*         between calls to DLAZQ3
+*
+*  This is a thread safe version of DLASQ3, which passes TTYPE, DMIN1,
+*  DMIN2, DN, DN1. DN2 and TAU through the argument list in place of
+*  declaring them in a SAVE statment.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   CBIAS
+      PARAMETER          ( CBIAS = 1.50D0 )
+      DOUBLE PRECISION   ZERO, QURTR, HALF, ONE, TWO, HUNDRD
+      PARAMETER          ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
+     $                     ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IPN4, J4, N0IN, NN
+      DOUBLE PRECISION   EPS, G, S, SAFMIN, T, TEMP, TOL, TOL2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASQ5, DLASQ6, DLAZQ4
+*     ..
+*     .. External Function ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      N0IN   = N0
+      EPS    = DLAMCH( 'Precision' )
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      TOL    = EPS*HUNDRD
+      TOL2   = TOL**2
+      G      = ZERO
+*
+*     Check for deflation.
+*
+   10 CONTINUE
+*
+      IF( N0.LT.I0 )
+     $   RETURN
+      IF( N0.EQ.I0 )
+     $   GO TO 20
+      NN = 4*N0 + PP
+      IF( N0.EQ.( I0+1 ) )
+     $   GO TO 40
+*
+*     Check whether E(N0-1) is negligible, 1 eigenvalue.
+*
+      IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
+     $    Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
+     $   GO TO 30
+*
+   20 CONTINUE
+*
+      Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
+      N0 = N0 - 1
+      GO TO 10
+*
+*     Check  whether E(N0-2) is negligible, 2 eigenvalues.
+*
+   30 CONTINUE
+*
+      IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
+     $    Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
+     $   GO TO 50
+*
+   40 CONTINUE
+*
+      IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
+         S = Z( NN-3 )
+         Z( NN-3 ) = Z( NN-7 )
+         Z( NN-7 ) = S
+      END IF
+      IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
+         T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
+         S = Z( NN-3 )*( Z( NN-5 ) / T )
+         IF( S.LE.T ) THEN
+            S = Z( NN-3 )*( Z( NN-5 ) /
+     $          ( T*( ONE+SQRT( ONE+S / T ) ) ) )
+         ELSE
+            S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
+         END IF
+         T = Z( NN-7 ) + ( S+Z( NN-5 ) )
+         Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
+         Z( NN-7 ) = T
+      END IF
+      Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
+      Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
+      N0 = N0 - 2
+      GO TO 10
+*
+   50 CONTINUE
+*
+*     Reverse the qd-array, if warranted.
+*
+      IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
+         IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
+            IPN4 = 4*( I0+N0 )
+            DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
+               TEMP = Z( J4-3 )
+               Z( J4-3 ) = Z( IPN4-J4-3 )
+               Z( IPN4-J4-3 ) = TEMP
+               TEMP = Z( J4-2 )
+               Z( J4-2 ) = Z( IPN4-J4-2 )
+               Z( IPN4-J4-2 ) = TEMP
+               TEMP = Z( J4-1 )
+               Z( J4-1 ) = Z( IPN4-J4-5 )
+               Z( IPN4-J4-5 ) = TEMP
+               TEMP = Z( J4 )
+               Z( J4 ) = Z( IPN4-J4-4 )
+               Z( IPN4-J4-4 ) = TEMP
+   60       CONTINUE
+            IF( N0-I0.LE.4 ) THEN
+               Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
+               Z( 4*N0-PP ) = Z( 4*I0-PP )
+            END IF
+            DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
+            Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
+     $                            Z( 4*I0+PP+3 ) )
+            Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
+     $                          Z( 4*I0-PP+4 ) )
+            QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
+            DMIN = -ZERO
+         END IF
+      END IF
+*
+      IF( DMIN.LT.ZERO .OR. SAFMIN*QMAX.LT.MIN( Z( 4*N0+PP-1 ),
+     $    Z( 4*N0+PP-9 ), DMIN2+Z( 4*N0-PP ) ) ) THEN
+*
+*        Choose a shift.
+*
+         CALL DLAZQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
+     $                DN2, TAU, TTYPE, G )
+*
+*        Call dqds until DMIN > 0.
+*
+   80    CONTINUE
+*
+         CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
+     $                DN1, DN2, IEEE )
+*
+         NDIV = NDIV + ( N0-I0+2 )
+         ITER = ITER + 1
+*
+*        Check status.
+*
+         IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
+*
+*           Success.
+*
+            GO TO 100
+*
+         ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
+     $            Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
+     $            ABS( DN ).LT.TOL*SIGMA ) THEN
+*
+*           Convergence hidden by negative DN.
+*
+            Z( 4*( N0-1 )-PP+2 ) = ZERO
+            DMIN = ZERO
+            GO TO 100
+         ELSE IF( DMIN.LT.ZERO ) THEN
+*
+*           TAU too big. Select new TAU and try again.
+*
+            NFAIL = NFAIL + 1
+            IF( TTYPE.LT.-22 ) THEN
+*
+*              Failed twice. Play it safe.
+*
+               TAU = ZERO
+            ELSE IF( DMIN1.GT.ZERO ) THEN
+*
+*              Late failure. Gives excellent shift.
+*
+               TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
+               TTYPE = TTYPE - 11
+            ELSE
+*
+*              Early failure. Divide by 4.
+*
+               TAU = QURTR*TAU
+               TTYPE = TTYPE - 12
+            END IF
+            GO TO 80
+         ELSE IF( DMIN.NE.DMIN ) THEN
+*
+*           NaN.
+*
+            TAU = ZERO
+            GO TO 80
+         ELSE
+*
+*           Possible underflow. Play it safe.
+*
+            GO TO 90
+         END IF
+      END IF
+*
+*     Risk of underflow.
+*
+   90 CONTINUE
+      CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
+      NDIV = NDIV + ( N0-I0+2 )
+      ITER = ITER + 1
+      TAU = ZERO
+*
+  100 CONTINUE
+      IF( TAU.LT.SIGMA ) THEN
+         DESIG = DESIG + TAU
+         T = SIGMA + DESIG
+         DESIG = DESIG - ( T-SIGMA )
+      ELSE
+         T = SIGMA + TAU
+         DESIG = SIGMA - ( T-TAU ) + DESIG
+      END IF
+      SIGMA = T
+*
+      RETURN
+*
+*     End of DLAZQ3
+*
+      END
diff --git a/libcruft/lapack/dlazq4.f b/libcruft/lapack/dlazq4.f
new file mode 100644
index 0000000..7c257f8
--- /dev/null
+++ b/libcruft/lapack/dlazq4.f
@@ -0,0 +1,330 @@
+      SUBROUTINE DLAZQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
+     $                   DN1, DN2, TAU, TTYPE, G )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I0, N0, N0IN, PP, TTYPE
+      DOUBLE PRECISION   DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DLAZQ4 computes an approximation TAU to the smallest eigenvalue 
+*  using values of d from the previous transform.
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) DOUBLE PRECISION array, dimension ( 4*N )
+*        Z holds the qd array.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  N0IN  (input) INTEGER
+*        The value of N0 at start of EIGTEST.
+*
+*  DMIN  (input) DOUBLE PRECISION
+*        Minimum value of d.
+*
+*  DMIN1 (input) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (input) DOUBLE PRECISION
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (input) DOUBLE PRECISION
+*        d(N)
+*
+*  DN1   (input) DOUBLE PRECISION
+*        d(N-1)
+*
+*  DN2   (input) DOUBLE PRECISION
+*        d(N-2)
+*
+*  TAU   (output) DOUBLE PRECISION
+*        This is the shift.
+*
+*  TTYPE (output) INTEGER
+*        Shift type.
+*
+*  G     (input/output) DOUBLE PRECISION
+*        G is passed as an argument in order to save its value between
+*        calls to DLAZQ4
+*
+*  Further Details
+*  ===============
+*  CNST1 = 9/16
+*
+*  This is a thread safe version of DLASQ4, which passes G through the
+*  argument list in place of declaring G in a SAVE statment.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   CNST1, CNST2, CNST3
+      PARAMETER          ( CNST1 = 0.5630D0, CNST2 = 1.010D0,
+     $                   CNST3 = 1.050D0 )
+      DOUBLE PRECISION   QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRD
+      PARAMETER          ( QURTR = 0.250D0, THIRD = 0.3330D0,
+     $                   HALF = 0.50D0, ZERO = 0.0D0, ONE = 1.0D0,
+     $                   TWO = 2.0D0, HUNDRD = 100.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I4, NN, NP
+      DOUBLE PRECISION   A2, B1, B2, GAM, GAP1, GAP2, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     A negative DMIN forces the shift to take that absolute value
+*     TTYPE records the type of shift.
+*
+      IF( DMIN.LE.ZERO ) THEN
+         TAU = -DMIN
+         TTYPE = -1
+         RETURN
+      END IF
+*       
+      NN = 4*N0 + PP
+      IF( N0IN.EQ.N0 ) THEN
+*
+*        No eigenvalues deflated.
+*
+         IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN
+*
+            B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )
+            B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )
+            A2 = Z( NN-7 ) + Z( NN-5 )
+*
+*           Cases 2 and 3.
+*
+            IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THEN
+               GAP2 = DMIN2 - A2 - DMIN2*QURTR
+               IF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THEN
+                  GAP1 = A2 - DN - ( B2 / GAP2 )*B2
+               ELSE
+                  GAP1 = A2 - DN - ( B1+B2 )
+               END IF
+               IF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THEN
+                  S = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )
+                  TTYPE = -2
+               ELSE
+                  S = ZERO
+                  IF( DN.GT.B1 )
+     $               S = DN - B1
+                  IF( A2.GT.( B1+B2 ) )
+     $               S = MIN( S, A2-( B1+B2 ) )
+                  S = MAX( S, THIRD*DMIN )
+                  TTYPE = -3
+               END IF
+            ELSE
+*
+*              Case 4.
+*
+               TTYPE = -4
+               S = QURTR*DMIN
+               IF( DMIN.EQ.DN ) THEN
+                  GAM = DN
+                  A2 = ZERO
+                  IF( Z( NN-5 ) .GT. Z( NN-7 ) )
+     $               RETURN
+                  B2 = Z( NN-5 ) / Z( NN-7 )
+                  NP = NN - 9
+               ELSE
+                  NP = NN - 2*PP
+                  B2 = Z( NP-2 )
+                  GAM = DN1
+                  IF( Z( NP-4 ) .GT. Z( NP-2 ) )
+     $               RETURN
+                  A2 = Z( NP-4 ) / Z( NP-2 )
+                  IF( Z( NN-9 ) .GT. Z( NN-11 ) )
+     $               RETURN
+                  B2 = Z( NN-9 ) / Z( NN-11 )
+                  NP = NN - 13
+               END IF
+*
+*              Approximate contribution to norm squared from I < NN-1.
+*
+               A2 = A2 + B2
+               DO 10 I4 = NP, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 20
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 20
+   10          CONTINUE
+   20          CONTINUE
+               A2 = CNST3*A2
+*
+*              Rayleigh quotient residual bound.
+*
+               IF( A2.LT.CNST1 )
+     $            S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+            END IF
+         ELSE IF( DMIN.EQ.DN2 ) THEN
+*
+*           Case 5.
+*
+            TTYPE = -5
+            S = QURTR*DMIN
+*
+*           Compute contribution to norm squared from I > NN-2.
+*
+            NP = NN - 2*PP
+            B1 = Z( NP-2 )
+            B2 = Z( NP-6 )
+            GAM = DN2
+            IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 )
+     $         RETURN
+            A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )
+*
+*           Approximate contribution to norm squared from I < NN-2.
+*
+            IF( N0-I0.GT.2 ) THEN
+               B2 = Z( NN-13 ) / Z( NN-15 )
+               A2 = A2 + B2
+               DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 40
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 40
+   30          CONTINUE
+   40          CONTINUE
+               A2 = CNST3*A2
+            END IF
+*
+            IF( A2.LT.CNST1 )
+     $         S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+         ELSE
+*
+*           Case 6, no information to guide us.
+*
+            IF( TTYPE.EQ.-6 ) THEN
+               G = G + THIRD*( ONE-G )
+            ELSE IF( TTYPE.EQ.-18 ) THEN
+               G = QURTR*THIRD
+            ELSE
+               G = QURTR
+            END IF
+            S = G*DMIN
+            TTYPE = -6
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+1 ) ) THEN
+*
+*        One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.
+*
+         IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN 
+*
+*           Cases 7 and 8.
+*
+            TTYPE = -7
+            S = THIRD*DMIN1
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 60
+            DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               A2 = B1
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*MAX( B1, A2 ).LT.B2 ) 
+     $            GO TO 60
+   50       CONTINUE
+   60       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN1 / ( ONE+B2**2 )
+            GAP2 = HALF*DMIN2 - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+               TTYPE = -8
+            END IF
+         ELSE
+*
+*           Case 9.
+*
+            S = QURTR*DMIN1
+            IF( DMIN1.EQ.DN1 )
+     $         S = HALF*DMIN1
+            TTYPE = -9
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+2 ) ) THEN
+*
+*        Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
+*
+*        Cases 10 and 11.
+*
+         IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THEN 
+            TTYPE = -10
+            S = THIRD*DMIN2
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 80
+            DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*B1.LT.B2 )
+     $            GO TO 80
+   70       CONTINUE
+   80       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN2 / ( ONE+B2**2 )
+            GAP2 = Z( NN-7 ) + Z( NN-9 ) -
+     $             SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+            END IF
+         ELSE
+            S = QURTR*DMIN2
+            TTYPE = -11
+         END IF
+      ELSE IF( N0IN.GT.( N0+2 ) ) THEN
+*
+*        Case 12, more than two eigenvalues deflated. No information.
+*
+         S = ZERO 
+         TTYPE = -12
+      END IF
+*
+      TAU = S
+      RETURN
+*
+*     End of DLAZQ4
+*
+      END
diff --git a/libcruft/lapack/dorg2l.f b/libcruft/lapack/dorg2l.f
new file mode 100644
index 0000000..a20965f
--- /dev/null
+++ b/libcruft/lapack/dorg2l.f
@@ -0,0 +1,127 @@
+      SUBROUTINE DORG2L( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORG2L generates an m by n real matrix Q with orthonormal columns,
+*  which is defined as the last n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by DGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by DGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the m by n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEQLF.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, II, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORG2L', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns 1:n-k to columns of the unit matrix
+*
+      DO 20 J = 1, N - K
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( M-N+J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = 1, K
+         II = N - K + I
+*
+*        Apply H(i) to A(1:m-k+i,1:n-k+i) from the left
+*
+         A( M-N+II, II ) = ONE
+         CALL DLARF( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), A,
+     $               LDA, WORK )
+         CALL DSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 )
+         A( M-N+II, II ) = ONE - TAU( I )
+*
+*        Set A(m-k+i+1:m,n-k+i) to zero
+*
+         DO 30 L = M - N + II + 1, M
+            A( L, II ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of DORG2L
+*
+      END
diff --git a/libcruft/lapack/dorg2r.f b/libcruft/lapack/dorg2r.f
new file mode 100644
index 0000000..476e9f7
--- /dev/null
+++ b/libcruft/lapack/dorg2r.f
@@ -0,0 +1,129 @@
+      SUBROUTINE DORG2R( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORG2R generates an m by n real matrix Q with orthonormal columns,
+*  which is defined as the first n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by DGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by DGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the m-by-n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEQRF.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORG2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns k+1:n to columns of the unit matrix
+*
+      DO 20 J = K + 1, N
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i) to A(i:m,i:n) from the left
+*
+         IF( I.LT.N ) THEN
+            A( I, I ) = ONE
+            CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                  A( I, I+1 ), LDA, WORK )
+         END IF
+         IF( I.LT.M )
+     $      CALL DSCAL( M-I, -TAU( I ), A( I+1, I ), 1 )
+         A( I, I ) = ONE - TAU( I )
+*
+*        Set A(1:i-1,i) to zero
+*
+         DO 30 L = 1, I - 1
+            A( L, I ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of DORG2R
+*
+      END
diff --git a/libcruft/lapack/dorgbr.f b/libcruft/lapack/dorgbr.f
new file mode 100644
index 0000000..dc88299
--- /dev/null
+++ b/libcruft/lapack/dorgbr.f
@@ -0,0 +1,244 @@
+      SUBROUTINE DORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          VECT
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGBR generates one of the real orthogonal matrices Q or P**T
+*  determined by DGEBRD when reducing a real matrix A to bidiagonal
+*  form: A = Q * B * P**T.  Q and P**T are defined as products of
+*  elementary reflectors H(i) or G(i) respectively.
+*
+*  If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q
+*  is of order M:
+*  if m >= k, Q = H(1) H(2) . . . H(k) and DORGBR returns the first n
+*  columns of Q, where m >= n >= k;
+*  if m < k, Q = H(1) H(2) . . . H(m-1) and DORGBR returns Q as an
+*  M-by-M matrix.
+*
+*  If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T
+*  is of order N:
+*  if k < n, P**T = G(k) . . . G(2) G(1) and DORGBR returns the first m
+*  rows of P**T, where n >= m >= k;
+*  if k >= n, P**T = G(n-1) . . . G(2) G(1) and DORGBR returns P**T as
+*  an N-by-N matrix.
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          Specifies whether the matrix Q or the matrix P**T is
+*          required, as defined in the transformation applied by DGEBRD:
+*          = 'Q':  generate Q;
+*          = 'P':  generate P**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q or P**T to be returned.
+*          M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q or P**T to be returned.
+*          N >= 0.
+*          If VECT = 'Q', M >= N >= min(M,K);
+*          if VECT = 'P', N >= M >= min(N,K).
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original M-by-K
+*          matrix reduced by DGEBRD.
+*          If VECT = 'P', the number of rows in the original K-by-N
+*          matrix reduced by DGEBRD.
+*          K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by DGEBRD.
+*          On exit, the M-by-N matrix Q or P**T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension
+*                                (min(M,K)) if VECT = 'Q'
+*                                (min(N,K)) if VECT = 'P'
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i), which determines Q or P**T, as
+*          returned by DGEBRD in its array argument TAUQ or TAUP.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,min(M,N)).
+*          For optimum performance LWORK >= min(M,N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WANTQ
+      INTEGER            I, IINFO, J, LWKOPT, MN, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DORGLQ, DORGQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTQ = LSAME( VECT, 'Q' )
+      MN = MIN( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M,
+     $         K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT.
+     $         MIN( N, K ) ) ) ) THEN
+         INFO = -3
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( WANTQ ) THEN
+            NB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 )
+         ELSE
+            NB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 )
+         END IF
+         LWKOPT = MAX( 1, MN )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( WANTQ ) THEN
+*
+*        Form Q, determined by a call to DGEBRD to reduce an m-by-k
+*        matrix
+*
+         IF( M.GE.K ) THEN
+*
+*           If m >= k, assume m >= n >= k
+*
+            CALL DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If m < k, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           column to the right, and set the first row and column of Q
+*           to those of the unit matrix
+*
+            DO 20 J = M, 2, -1
+               A( 1, J ) = ZERO
+               DO 10 I = J + 1, M
+                  A( I, J ) = A( I, J-1 )
+   10          CONTINUE
+   20       CONTINUE
+            A( 1, 1 ) = ONE
+            DO 30 I = 2, M
+               A( I, 1 ) = ZERO
+   30       CONTINUE
+            IF( M.GT.1 ) THEN
+*
+*              Form Q(2:m,2:m)
+*
+               CALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      ELSE
+*
+*        Form P', determined by a call to DGEBRD to reduce a k-by-n
+*        matrix
+*
+         IF( K.LT.N ) THEN
+*
+*           If k < n, assume k <= m <= n
+*
+            CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If k >= n, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           row downward, and set the first row and column of P' to
+*           those of the unit matrix
+*
+            A( 1, 1 ) = ONE
+            DO 40 I = 2, N
+               A( I, 1 ) = ZERO
+   40       CONTINUE
+            DO 60 J = 2, N
+               DO 50 I = J - 1, 2, -1
+                  A( I, J ) = A( I-1, J )
+   50          CONTINUE
+               A( 1, J ) = ZERO
+   60       CONTINUE
+            IF( N.GT.1 ) THEN
+*
+*              Form P'(2:n,2:n)
+*
+               CALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DORGBR
+*
+      END
diff --git a/libcruft/lapack/dorghr.f b/libcruft/lapack/dorghr.f
new file mode 100644
index 0000000..1283aec
--- /dev/null
+++ b/libcruft/lapack/dorghr.f
@@ -0,0 +1,164 @@
+      SUBROUTINE DORGHR( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGHR generates a real orthogonal matrix Q which is defined as the
+*  product of IHI-ILO elementary reflectors of order N, as returned by
+*  DGEHRD:
+*
+*  Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI must have the same values as in the previous call
+*          of DGEHRD. Q is equal to the unit matrix except in the
+*          submatrix Q(ilo+1:ihi,ilo+1:ihi).
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by DGEHRD.
+*          On exit, the N-by-N orthogonal matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEHRD.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= IHI-ILO.
+*          For optimum performance LWORK >= (IHI-ILO)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LWKOPT, NB, NH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DORGQR, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NH = IHI - ILO
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, NH ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'DORGQR', ' ', NH, NH, NH, -1 )
+         LWKOPT = MAX( 1, NH )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGHR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Shift the vectors which define the elementary reflectors one
+*     column to the right, and set the first ilo and the last n-ihi
+*     rows and columns to those of the unit matrix
+*
+      DO 40 J = IHI, ILO + 1, -1
+         DO 10 I = 1, J - 1
+            A( I, J ) = ZERO
+   10    CONTINUE
+         DO 20 I = J + 1, IHI
+            A( I, J ) = A( I, J-1 )
+   20    CONTINUE
+         DO 30 I = IHI + 1, N
+            A( I, J ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      DO 60 J = 1, ILO
+         DO 50 I = 1, N
+            A( I, J ) = ZERO
+   50    CONTINUE
+         A( J, J ) = ONE
+   60 CONTINUE
+      DO 80 J = IHI + 1, N
+         DO 70 I = 1, N
+            A( I, J ) = ZERO
+   70    CONTINUE
+         A( J, J ) = ONE
+   80 CONTINUE
+*
+      IF( NH.GT.0 ) THEN
+*
+*        Generate Q(ilo+1:ihi,ilo+1:ihi)
+*
+         CALL DORGQR( NH, NH, NH, A( ILO+1, ILO+1 ), LDA, TAU( ILO ),
+     $                WORK, LWORK, IINFO )
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DORGHR
+*
+      END
diff --git a/libcruft/lapack/dorgl2.f b/libcruft/lapack/dorgl2.f
new file mode 100644
index 0000000..1e08344
--- /dev/null
+++ b/libcruft/lapack/dorgl2.f
@@ -0,0 +1,133 @@
+      SUBROUTINE DORGL2( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGL2 generates an m by n real matrix Q with orthonormal rows,
+*  which is defined as the first m rows of a product of k elementary
+*  reflectors of order n
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by DGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by DGELQF in the first k rows of its array argument A.
+*          On exit, the m-by-n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGELQF.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGL2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 )
+     $   RETURN
+*
+      IF( K.LT.M ) THEN
+*
+*        Initialise rows k+1:m to rows of the unit matrix
+*
+         DO 20 J = 1, N
+            DO 10 L = K + 1, M
+               A( L, J ) = ZERO
+   10       CONTINUE
+            IF( J.GT.K .AND. J.LE.M )
+     $         A( J, J ) = ONE
+   20    CONTINUE
+      END IF
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i) to A(i:m,i:n) from the right
+*
+         IF( I.LT.N ) THEN
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+               CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     TAU( I ), A( I+1, I ), LDA, WORK )
+            END IF
+            CALL DSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA )
+         END IF
+         A( I, I ) = ONE - TAU( I )
+*
+*        Set A(i,1:i-1) to zero
+*
+         DO 30 L = 1, I - 1
+            A( I, L ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of DORGL2
+*
+      END
diff --git a/libcruft/lapack/dorglq.f b/libcruft/lapack/dorglq.f
new file mode 100644
index 0000000..e4f58c9
--- /dev/null
+++ b/libcruft/lapack/dorglq.f
@@ -0,0 +1,215 @@
+      SUBROUTINE DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGLQ generates an M-by-N real matrix Q with orthonormal rows,
+*  which is defined as the first M rows of a product of K elementary
+*  reflectors of order N
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by DGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by DGELQF in the first k rows of its array argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGELQF.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARFB, DLARFT, DORGL2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, M )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'DORGLQ', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'DORGLQ', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk rows are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(kk+1:m,1:kk) to zero.
+*
+         DO 20 J = 1, KK
+            DO 10 I = KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.M )
+     $   CALL DORGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i+ib:m,i:n) from the right
+*
+               CALL DLARFB( 'Right', 'Transpose', 'Forward', 'Rowwise',
+     $                      M-I-IB+1, N-I+1, IB, A( I, I ), LDA, WORK,
+     $                      LDWORK, A( I+IB, I ), LDA, WORK( IB+1 ),
+     $                      LDWORK )
+            END IF
+*
+*           Apply H' to columns i:n of current block
+*
+            CALL DORGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set columns 1:i-1 of current block to zero
+*
+            DO 40 J = 1, I - 1
+               DO 30 L = I, I + IB - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DORGLQ
+*
+      END
diff --git a/libcruft/lapack/dorgql.f b/libcruft/lapack/dorgql.f
new file mode 100644
index 0000000..1c4896e
--- /dev/null
+++ b/libcruft/lapack/dorgql.f
@@ -0,0 +1,222 @@
+      SUBROUTINE DORGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGQL generates an M-by-N real matrix Q with orthonormal columns,
+*  which is defined as the last N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by DGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by DGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEQLF.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT,
+     $                   NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARFB, DLARFT, DORG2L, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+            NB = ILAENV( 1, 'DORGQL', ' ', M, N, K, -1 )
+            LWKOPT = N*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGQL', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'DORGQL', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'DORGQL', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the first block.
+*        The last kk columns are handled by the block method.
+*
+         KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )
+*
+*        Set A(m-kk+1:m,1:n-kk) to zero.
+*
+         DO 20 J = 1, N - KK
+            DO 10 I = M - KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the first or only block.
+*
+      CALL DORG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = K - KK + 1, K, NB
+            IB = MIN( NB, K-I+1 )
+            IF( N-K+I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL DLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,
+     $                      A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left
+*
+               CALL DLARFB( 'Left', 'No transpose', 'Backward',
+     $                      'Columnwise', M-K+I+IB-1, N-K+I-1, IB,
+     $                      A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows 1:m-k+i+ib-1 of current block
+*
+            CALL DORG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA,
+     $                   TAU( I ), WORK, IINFO )
+*
+*           Set rows m-k+i+ib:m of current block to zero
+*
+            DO 40 J = N - K + I, N - K + I + IB - 1
+               DO 30 L = M - K + I + IB, M
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DORGQL
+*
+      END
diff --git a/libcruft/lapack/dorgqr.f b/libcruft/lapack/dorgqr.f
new file mode 100644
index 0000000..4db0ef5
--- /dev/null
+++ b/libcruft/lapack/dorgqr.f
@@ -0,0 +1,216 @@
+      SUBROUTINE DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGQR generates an M-by-N real matrix Q with orthonormal columns,
+*  which is defined as the first N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by DGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by DGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEQRF.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARFB, DLARFT, DORG2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, N )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'DORGQR', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'DORGQR', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk columns are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(1:kk,kk+1:n) to zero.
+*
+         DO 20 J = KK + 1, N
+            DO 10 I = 1, KK
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.N )
+     $   CALL DORG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i:m,i+ib:n) from the left
+*
+               CALL DLARFB( 'Left', 'No transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows i:m of current block
+*
+            CALL DORG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set rows 1:i-1 of current block to zero
+*
+            DO 40 J = I, I + IB - 1
+               DO 30 L = 1, I - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of DORGQR
+*
+      END
diff --git a/libcruft/lapack/dorgtr.f b/libcruft/lapack/dorgtr.f
new file mode 100644
index 0000000..4c72d03
--- /dev/null
+++ b/libcruft/lapack/dorgtr.f
@@ -0,0 +1,183 @@
+      SUBROUTINE DORGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORGTR generates a real orthogonal matrix Q which is defined as the
+*  product of n-1 elementary reflectors of order N, as returned by
+*  DSYTRD:
+*
+*  if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),
+*
+*  if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U': Upper triangle of A contains elementary reflectors
+*                 from DSYTRD;
+*          = 'L': Lower triangle of A contains elementary reflectors
+*                 from DSYTRD.
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by DSYTRD.
+*          On exit, the N-by-N orthogonal matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DSYTRD.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N-1).
+*          For optimum performance LWORK >= (N-1)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, J, LWKOPT, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DORGQL, DORGQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( UPPER ) THEN
+            NB = ILAENV( 1, 'DORGQL', ' ', N-1, N-1, N-1, -1 )
+         ELSE
+            NB = ILAENV( 1, 'DORGQR', ' ', N-1, N-1, N-1, -1 )
+         END IF
+         LWKOPT = MAX( 1, N-1 )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORGTR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Q was determined by a call to DSYTRD with UPLO = 'U'
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the left, and set the last row and column of Q to
+*        those of the unit matrix
+*
+         DO 20 J = 1, N - 1
+            DO 10 I = 1, J - 1
+               A( I, J ) = A( I, J+1 )
+   10       CONTINUE
+            A( N, J ) = ZERO
+   20    CONTINUE
+         DO 30 I = 1, N - 1
+            A( I, N ) = ZERO
+   30    CONTINUE
+         A( N, N ) = ONE
+*
+*        Generate Q(1:n-1,1:n-1)
+*
+         CALL DORGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+      ELSE
+*
+*        Q was determined by a call to DSYTRD with UPLO = 'L'.
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the right, and set the first row and column of Q to
+*        those of the unit matrix
+*
+         DO 50 J = N, 2, -1
+            A( 1, J ) = ZERO
+            DO 40 I = J + 1, N
+               A( I, J ) = A( I, J-1 )
+   40       CONTINUE
+   50    CONTINUE
+         A( 1, 1 ) = ONE
+         DO 60 I = 2, N
+            A( I, 1 ) = ZERO
+   60    CONTINUE
+         IF( N.GT.1 ) THEN
+*
+*           Generate Q(2:n,2:n)
+*
+            CALL DORGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                   LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DORGTR
+*
+      END
diff --git a/libcruft/lapack/dorm2r.f b/libcruft/lapack/dorm2r.f
new file mode 100644
index 0000000..79c9ef3
--- /dev/null
+++ b/libcruft/lapack/dorm2r.f
@@ -0,0 +1,197 @@
+      SUBROUTINE DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORM2R overwrites the general real m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'T',
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by DGEQRF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'T': apply Q' (Transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          DGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEQRF.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORM2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. ( .NOT.LEFT .AND. NOTRAN ) )
+     $     THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i)
+*
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL DLARF( SIDE, MI, NI, A( I, I ), 1, TAU( I ), C( IC, JC ),
+     $               LDC, WORK )
+         A( I, I ) = AII
+   10 CONTINUE
+      RETURN
+*
+*     End of DORM2R
+*
+      END
diff --git a/libcruft/lapack/dormbr.f b/libcruft/lapack/dormbr.f
new file mode 100644
index 0000000..8066b89
--- /dev/null
+++ b/libcruft/lapack/dormbr.f
@@ -0,0 +1,281 @@
+      SUBROUTINE DORMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,
+     $                   LDC, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS, VECT
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  If VECT = 'Q', DORMBR overwrites the general real M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  If VECT = 'P', DORMBR overwrites the general real M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      P * C          C * P
+*  TRANS = 'T':      P**T * C       C * P**T
+*
+*  Here Q and P**T are the orthogonal matrices determined by DGEBRD when
+*  reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and
+*  P**T are defined as products of elementary reflectors H(i) and G(i)
+*  respectively.
+*
+*  Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the
+*  order of the orthogonal matrix Q or P**T that is applied.
+*
+*  If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:
+*  if nq >= k, Q = H(1) H(2) . . . H(k);
+*  if nq < k, Q = H(1) H(2) . . . H(nq-1).
+*
+*  If VECT = 'P', A is assumed to have been a K-by-NQ matrix:
+*  if k < nq, P = G(1) G(2) . . . G(k);
+*  if k >= nq, P = G(1) G(2) . . . G(nq-1).
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          = 'Q': apply Q or Q**T;
+*          = 'P': apply P or P**T.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q, Q**T, P or P**T from the Left;
+*          = 'R': apply Q, Q**T, P or P**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q  or P;
+*          = 'T':  Transpose, apply Q**T or P**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original
+*          matrix reduced by DGEBRD.
+*          If VECT = 'P', the number of rows in the original
+*          matrix reduced by DGEBRD.
+*          K >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension
+*                                (LDA,min(nq,K)) if VECT = 'Q'
+*                                (LDA,nq)        if VECT = 'P'
+*          The vectors which define the elementary reflectors H(i) and
+*          G(i), whose products determine the matrices Q and P, as
+*          returned by DGEBRD.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If VECT = 'Q', LDA >= max(1,nq);
+*          if VECT = 'P', LDA >= max(1,min(nq,K)).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (min(nq,K))
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i) which determines Q or P, as returned
+*          by DGEBRD in the array argument TAUQ or TAUP.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q
+*          or P*C or P**T*C or C*P or C*P**T.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            APPLYQ, LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DORMLQ, DORMQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      APPLYQ = LSAME( VECT, 'Q' )
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q or P and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR.
+     $         ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) )
+     $          THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -13
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( APPLYQ ) THEN
+            IF( LEFT ) THEN
+               NB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M-1, N, M-1,
+     $              -1 )
+            ELSE
+               NB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N-1, N-1,
+     $              -1 )
+            END IF
+         ELSE
+            IF( LEFT ) THEN
+               NB = ILAENV( 1, 'DORMLQ', SIDE // TRANS, M-1, N, M-1,
+     $              -1 )
+            ELSE
+               NB = ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N-1, N-1,
+     $              -1 )
+            END IF
+         END IF
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORMBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      WORK( 1 ) = 1
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+      IF( APPLYQ ) THEN
+*
+*        Apply Q
+*
+         IF( NQ.GE.K ) THEN
+*
+*           Q was determined by a call to DGEBRD with nq >= k
+*
+            CALL DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           Q was determined by a call to DGEBRD with nq < k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL DORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,
+     $                   C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      ELSE
+*
+*        Apply P
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'T'
+         ELSE
+            TRANST = 'N'
+         END IF
+         IF( NQ.GT.K ) THEN
+*
+*           P was determined by a call to DGEBRD with nq > k
+*
+            CALL DORMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           P was determined by a call to DGEBRD with nq <= k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL DORMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA,
+     $                   TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DORMBR
+*
+      END
diff --git a/libcruft/lapack/dorml2.f b/libcruft/lapack/dorml2.f
new file mode 100644
index 0000000..d3941c9
--- /dev/null
+++ b/libcruft/lapack/dorml2.f
@@ -0,0 +1,197 @@
+      SUBROUTINE DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORML2 overwrites the general real m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'T',
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k) . . . H(2) H(1)
+*
+*  as returned by DGELQF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'T': apply Q' (Transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          DGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGELQF.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORML2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) )
+     $     THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i)
+*
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL DLARF( SIDE, MI, NI, A( I, I ), LDA, TAU( I ),
+     $               C( IC, JC ), LDC, WORK )
+         A( I, I ) = AII
+   10 CONTINUE
+      RETURN
+*
+*     End of DORML2
+*
+      END
diff --git a/libcruft/lapack/dormlq.f b/libcruft/lapack/dormlq.f
new file mode 100644
index 0000000..f0c68ef
--- /dev/null
+++ b/libcruft/lapack/dormlq.f
@@ -0,0 +1,267 @@
+      SUBROUTINE DORMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORMLQ overwrites the general real M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k) . . . H(2) H(1)
+*
+*  as returned by DGELQF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**T from the Left;
+*          = 'R': apply Q or Q**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'T':  Transpose, apply Q**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          DGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGELQF.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARFB, DLARFT, DORML2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N, K,
+     $        -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORMLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'DORMLQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'T'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL DLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL DLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,
+     $                   A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK,
+     $                   LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DORMLQ
+*
+      END
diff --git a/libcruft/lapack/dormqr.f b/libcruft/lapack/dormqr.f
new file mode 100644
index 0000000..ee37269
--- /dev/null
+++ b/libcruft/lapack/dormqr.f
@@ -0,0 +1,260 @@
+      SUBROUTINE DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORMQR overwrites the general real M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**T from the Left;
+*          = 'R': apply Q or Q**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'T':  Transpose, apply Q**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          DGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DGEQRF.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARFB, DLARFT, DORM2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N, K,
+     $        -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORMQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'DORMQR', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL DLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL DLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI,
+     $                   IB, A( I, I ), LDA, T, LDT, C( IC, JC ), LDC,
+     $                   WORK, LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DORMQR
+*
+      END
diff --git a/libcruft/lapack/dormr3.f b/libcruft/lapack/dormr3.f
new file mode 100644
index 0000000..7bdcb85
--- /dev/null
+++ b/libcruft/lapack/dormr3.f
@@ -0,0 +1,206 @@
+      SUBROUTINE DORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORMR3 overwrites the general real m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'T',
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by DTZRZF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'T': apply Q' (Transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          DTZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DTZRZF.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JA, JC, MI, NI, NQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARZ, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORMR3', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JA = M - L + 1
+         JC = 1
+      ELSE
+         MI = M
+         JA = N - L + 1
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         CALL DLARZ( SIDE, MI, NI, L, A( I, JA ), LDA, TAU( I ),
+     $               C( IC, JC ), LDC, WORK )
+*
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of DORMR3
+*
+      END
diff --git a/libcruft/lapack/dormrz.f b/libcruft/lapack/dormrz.f
new file mode 100644
index 0000000..b69d9c6
--- /dev/null
+++ b/libcruft/lapack/dormrz.f
@@ -0,0 +1,293 @@
+      SUBROUTINE DORMRZ( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DORMRZ overwrites the general real M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by DTZRZF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**T from the Left;
+*          = 'R': apply Q or Q**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'T':  Transpose, apply Q**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          DTZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) DOUBLE PRECISION array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by DTZRZF.
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JA, JC,
+     $                   LDWORK, LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARZB, DLARZT, DORMR3, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = MAX( 1, N )
+      ELSE
+         NQ = N
+         NW = MAX( 1, M )
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.  NB may be at most NBMAX, where
+*           NBMAX is used to define the local array T.
+*
+            NB = MIN( NBMAX, ILAENV( 1, 'DORMRQ', SIDE // TRANS, M, N,
+     $                               K, -1 ) )
+            LWKOPT = NW*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DORMRZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'DORMRQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL DORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                WORK, IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+            JA = M - L + 1
+         ELSE
+            MI = M
+            IC = 1
+            JA = N - L + 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'T'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i+ib-1) . . . H(i+1) H(i)
+*
+            CALL DLARZT( 'Backward', 'Rowwise', L, IB, A( I, JA ), LDA,
+     $                   TAU( I ), T, LDT )
+*
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL DLARZB( SIDE, TRANST, 'Backward', 'Rowwise', MI, NI,
+     $                   IB, L, A( I, JA ), LDA, T, LDT, C( IC, JC ),
+     $                   LDC, WORK, LDWORK )
+   10    CONTINUE
+*
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of DORMRZ
+*
+      END
diff --git a/libcruft/lapack/dpbcon.f b/libcruft/lapack/dpbcon.f
new file mode 100644
index 0000000..ad5fa41
--- /dev/null
+++ b/libcruft/lapack/dpbcon.f
@@ -0,0 +1,192 @@
+      SUBROUTINE DPBCON( UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call DLACN2 in place of DLACON, 5 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPBCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a real symmetric positive definite band matrix using the
+*  Cholesky factorization A = U**T*U or A = L*L**T computed by DPBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input) DOUBLE PRECISION array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          The 1-norm (or infinity-norm) of the symmetric band matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      DOUBLE PRECISION   AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACN2, DLATBS, DRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of the inverse.
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL DLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEL, WORK( 2*N+1 ),
+     $                   INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL DLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEU, WORK( 2*N+1 ),
+     $                   INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL DLATBS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEL, WORK( 2*N+1 ),
+     $                   INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL DLATBS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEU, WORK( 2*N+1 ),
+     $                   INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = IDAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL DRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of DPBCON
+*
+      END
diff --git a/libcruft/lapack/dpbtf2.f b/libcruft/lapack/dpbtf2.f
new file mode 100644
index 0000000..8419f91
--- /dev/null
+++ b/libcruft/lapack/dpbtf2.f
@@ -0,0 +1,194 @@
+      SUBROUTINE DPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPBTF2 computes the Cholesky factorization of a real symmetric
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix, U' is the transpose of U, and
+*  L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of super-diagonals of the matrix A if UPLO = 'U',
+*          or the number of sub-diagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the symmetric band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U'*U or A = L*L' of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, KLD, KN
+      DOUBLE PRECISION   AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, DSYR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      KLD = MAX( 1, LDAB-1 )
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = AB( KD+1, J )
+            IF( AJJ.LE.ZERO )
+     $         GO TO 30
+            AJJ = SQRT( AJJ )
+            AB( KD+1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of row J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL DSCAL( KN, ONE / AJJ, AB( KD, J+1 ), KLD )
+               CALL DSYR( 'Upper', KN, -ONE, AB( KD, J+1 ), KLD,
+     $                    AB( KD+1, J+1 ), KLD )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = AB( 1, J )
+            IF( AJJ.LE.ZERO )
+     $         GO TO 30
+            AJJ = SQRT( AJJ )
+            AB( 1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of column J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL DSCAL( KN, ONE / AJJ, AB( 2, J ), 1 )
+               CALL DSYR( 'Lower', KN, -ONE, AB( 2, J ), 1,
+     $                    AB( 1, J+1 ), KLD )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+   30 CONTINUE
+      INFO = J
+      RETURN
+*
+*     End of DPBTF2
+*
+      END
diff --git a/libcruft/lapack/dpbtrf.f b/libcruft/lapack/dpbtrf.f
new file mode 100644
index 0000000..1aa19ef
--- /dev/null
+++ b/libcruft/lapack/dpbtrf.f
@@ -0,0 +1,364 @@
+      SUBROUTINE DPBTRF( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPBTRF computes the Cholesky factorization of a real symmetric
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U**T * U,  if UPLO = 'U', or
+*     A = L  * L**T,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the symmetric band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U**T*U or A = L*L**T of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  Contributed by
+*  Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 32, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, IB, II, J, JJ, NB
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   WORK( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DPBTF2, DPOTF2, DSYRK, DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ( .NOT.LSAME( UPLO, 'U' ) ) .AND.
+     $    ( .NOT.LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'DPBTRF', UPLO, N, KD, -1, -1 )
+*
+*     The block size must not exceed the semi-bandwidth KD, and must not
+*     exceed the limit set by the size of the local array WORK.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KD ) THEN
+*
+*        Use unblocked code
+*
+         CALL DPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*           Compute the Cholesky factorization of a symmetric band
+*           matrix, given the upper triangle of the matrix in band
+*           storage.
+*
+*           Zero the upper triangle of the work array.
+*
+            DO 20 J = 1, NB
+               DO 10 I = 1, J - 1
+                  WORK( I, J ) = ZERO
+   10          CONTINUE
+   20       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 70 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL DPOTF2( UPLO, IB, AB( KD+1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11   A12   A13
+*                          A22   A23
+*                                A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A12, A22 and
+*                 A23 are empty if IB = KD. The upper triangle of A13
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A12
+*
+                     CALL DTRSM( 'Left', 'Upper', 'Transpose',
+     $                           'Non-unit', IB, I2, ONE, AB( KD+1, I ),
+     $                           LDAB-1, AB( KD+1-IB, I+IB ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL DSYRK( 'Upper', 'Transpose', I2, IB, -ONE,
+     $                           AB( KD+1-IB, I+IB ), LDAB-1, ONE,
+     $                           AB( KD+1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the lower triangle of A13 into the work array.
+*
+                     DO 40 JJ = 1, I3
+                        DO 30 II = JJ, IB
+                           WORK( II, JJ ) = AB( II-JJ+1, JJ+I+KD-1 )
+   30                   CONTINUE
+   40                CONTINUE
+*
+*                    Update A13 (in the work array).
+*
+                     CALL DTRSM( 'Left', 'Upper', 'Transpose',
+     $                           'Non-unit', IB, I3, ONE, AB( KD+1, I ),
+     $                           LDAB-1, WORK, LDWORK )
+*
+*                    Update A23
+*
+                     IF( I2.GT.0 )
+     $                  CALL DGEMM( 'Transpose', 'No Transpose', I2, I3,
+     $                              IB, -ONE, AB( KD+1-IB, I+IB ),
+     $                              LDAB-1, WORK, LDWORK, ONE,
+     $                              AB( 1+IB, I+KD ), LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL DSYRK( 'Upper', 'Transpose', I3, IB, -ONE,
+     $                           WORK, LDWORK, ONE, AB( KD+1, I+KD ),
+     $                           LDAB-1 )
+*
+*                    Copy the lower triangle of A13 back into place.
+*
+                     DO 60 JJ = 1, I3
+                        DO 50 II = JJ, IB
+                           AB( II-JJ+1, JJ+I+KD-1 ) = WORK( II, JJ )
+   50                   CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+   70       CONTINUE
+         ELSE
+*
+*           Compute the Cholesky factorization of a symmetric band
+*           matrix, given the lower triangle of the matrix in band
+*           storage.
+*
+*           Zero the lower triangle of the work array.
+*
+            DO 90 J = 1, NB
+               DO 80 I = J + 1, NB
+                  WORK( I, J ) = ZERO
+   80          CONTINUE
+   90       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 140 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL DPOTF2( UPLO, IB, AB( 1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11
+*                    A21   A22
+*                    A31   A32   A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A21, A22 and
+*                 A32 are empty if IB = KD. The lower triangle of A31
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A21
+*
+                     CALL DTRSM( 'Right', 'Lower', 'Transpose',
+     $                           'Non-unit', I2, IB, ONE, AB( 1, I ),
+     $                           LDAB-1, AB( 1+IB, I ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL DSYRK( 'Lower', 'No Transpose', I2, IB, -ONE,
+     $                           AB( 1+IB, I ), LDAB-1, ONE,
+     $                           AB( 1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the upper triangle of A31 into the work array.
+*
+                     DO 110 JJ = 1, IB
+                        DO 100 II = 1, MIN( JJ, I3 )
+                           WORK( II, JJ ) = AB( KD+1-JJ+II, JJ+I-1 )
+  100                   CONTINUE
+  110                CONTINUE
+*
+*                    Update A31 (in the work array).
+*
+                     CALL DTRSM( 'Right', 'Lower', 'Transpose',
+     $                           'Non-unit', I3, IB, ONE, AB( 1, I ),
+     $                           LDAB-1, WORK, LDWORK )
+*
+*                    Update A32
+*
+                     IF( I2.GT.0 )
+     $                  CALL DGEMM( 'No transpose', 'Transpose', I3, I2,
+     $                              IB, -ONE, WORK, LDWORK,
+     $                              AB( 1+IB, I ), LDAB-1, ONE,
+     $                              AB( 1+KD-IB, I+IB ), LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL DSYRK( 'Lower', 'No Transpose', I3, IB, -ONE,
+     $                           WORK, LDWORK, ONE, AB( 1, I+KD ),
+     $                           LDAB-1 )
+*
+*                    Copy the upper triangle of A31 back into place.
+*
+                     DO 130 JJ = 1, IB
+                        DO 120 II = 1, MIN( JJ, I3 )
+                           AB( KD+1-JJ+II, JJ+I-1 ) = WORK( II, JJ )
+  120                   CONTINUE
+  130                CONTINUE
+                  END IF
+               END IF
+  140       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+  150 CONTINUE
+      RETURN
+*
+*     End of DPBTRF
+*
+      END
diff --git a/libcruft/lapack/dpbtrs.f b/libcruft/lapack/dpbtrs.f
new file mode 100644
index 0000000..76b086a
--- /dev/null
+++ b/libcruft/lapack/dpbtrs.f
@@ -0,0 +1,145 @@
+      SUBROUTINE DPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPBTRS solves a system of linear equations A*X = B with a symmetric
+*  positive definite band matrix A using the Cholesky factorization
+*  A = U**T*U or A = L*L**T computed by DPBTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) DOUBLE PRECISION array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DTBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+         DO 10 J = 1, NRHS
+*
+*           Solve U'*X = B, overwriting B with X.
+*
+            CALL DTBSV( 'Upper', 'Transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL DTBSV( 'Upper', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+         DO 20 J = 1, NRHS
+*
+*           Solve L*X = B, overwriting B with X.
+*
+            CALL DTBSV( 'Lower', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+*
+*           Solve L'*X = B, overwriting B with X.
+*
+            CALL DTBSV( 'Lower', 'Transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DPBTRS
+*
+      END
diff --git a/libcruft/lapack/dpocon.f b/libcruft/lapack/dpocon.f
new file mode 100644
index 0000000..c28af37
--- /dev/null
+++ b/libcruft/lapack/dpocon.f
@@ -0,0 +1,177 @@
+      SUBROUTINE DPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, IWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call DLACN2 in place of DLACON, 5 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPOCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a real symmetric positive definite matrix using the
+*  Cholesky factorization A = U**T*U or A = L*L**T computed by DPOTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T, as computed by DPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          The 1-norm (or infinity-norm) of the symmetric matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      DOUBLE PRECISION   AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACN2, DLATRS, DRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPOCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of inv(A).
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL DLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,
+     $                   LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL DLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL DLATRS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL DLATRS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N, A,
+     $                   LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = IDAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL DRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of DPOCON
+*
+      END
diff --git a/libcruft/lapack/dpotf2.f b/libcruft/lapack/dpotf2.f
new file mode 100644
index 0000000..b7d65e9
--- /dev/null
+++ b/libcruft/lapack/dpotf2.f
@@ -0,0 +1,167 @@
+      SUBROUTINE DPOTF2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPOTF2 computes the Cholesky factorization of a real symmetric
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U'*U  or A = L*L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+      DOUBLE PRECISION   AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DDOT
+      EXTERNAL           LSAME, DDOT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPOTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = A( J, J ) - DDOT( J-1, A( 1, J ), 1, A( 1, J ), 1 )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of row J.
+*
+            IF( J.LT.N ) THEN
+               CALL DGEMV( 'Transpose', J-1, N-J, -ONE, A( 1, J+1 ),
+     $                     LDA, A( 1, J ), 1, ONE, A( J, J+1 ), LDA )
+               CALL DSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = A( J, J ) - DDOT( J-1, A( J, 1 ), LDA, A( J, 1 ),
+     $            LDA )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of column J.
+*
+            IF( J.LT.N ) THEN
+               CALL DGEMV( 'No transpose', N-J, J-1, -ONE, A( J+1, 1 ),
+     $                     LDA, A( J, 1 ), LDA, ONE, A( J+1, J ), 1 )
+               CALL DSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = J
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of DPOTF2
+*
+      END
diff --git a/libcruft/lapack/dpotrf.f b/libcruft/lapack/dpotrf.f
new file mode 100644
index 0000000..8449df6
--- /dev/null
+++ b/libcruft/lapack/dpotrf.f
@@ -0,0 +1,183 @@
+      SUBROUTINE DPOTRF( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPOTRF computes the Cholesky factorization of a real symmetric
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U**T * U,  if UPLO = 'U', or
+*     A = L  * L**T,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the block version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U**T*U or A = L*L**T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, JB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DPOTF2, DSYRK, DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPOTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'DPOTRF', UPLO, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         CALL DPOTF2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         IF( UPPER ) THEN
+*
+*           Compute the Cholesky factorization A = U'*U.
+*
+            DO 10 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL DSYRK( 'Upper', 'Transpose', JB, J-1, -ONE,
+     $                     A( 1, J ), LDA, ONE, A( J, J ), LDA )
+               CALL DPOTF2( 'Upper', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block row.
+*
+                  CALL DGEMM( 'Transpose', 'No transpose', JB, N-J-JB+1,
+     $                        J-1, -ONE, A( 1, J ), LDA, A( 1, J+JB ),
+     $                        LDA, ONE, A( J, J+JB ), LDA )
+                  CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit',
+     $                        JB, N-J-JB+1, ONE, A( J, J ), LDA,
+     $                        A( J, J+JB ), LDA )
+               END IF
+   10       CONTINUE
+*
+         ELSE
+*
+*           Compute the Cholesky factorization A = L*L'.
+*
+            DO 20 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL DSYRK( 'Lower', 'No transpose', JB, J-1, -ONE,
+     $                     A( J, 1 ), LDA, ONE, A( J, J ), LDA )
+               CALL DPOTF2( 'Lower', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block column.
+*
+                  CALL DGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB,
+     $                        J-1, -ONE, A( J+JB, 1 ), LDA, A( J, 1 ),
+     $                        LDA, ONE, A( J+JB, J ), LDA )
+                  CALL DTRSM( 'Right', 'Lower', 'Transpose', 'Non-unit',
+     $                        N-J-JB+1, JB, ONE, A( J, J ), LDA,
+     $                        A( J+JB, J ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = INFO + J - 1
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of DPOTRF
+*
+      END
diff --git a/libcruft/lapack/dpotri.f b/libcruft/lapack/dpotri.f
new file mode 100644
index 0000000..7f7b1d0
--- /dev/null
+++ b/libcruft/lapack/dpotri.f
@@ -0,0 +1,96 @@
+      SUBROUTINE DPOTRI( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPOTRI computes the inverse of a real symmetric positive definite
+*  matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
+*  computed by DPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the triangular factor U or L from the Cholesky
+*          factorization A = U**T*U or A = L*L**T, as computed by
+*          DPOTRF.
+*          On exit, the upper or lower triangle of the (symmetric)
+*          inverse of A, overwriting the input factor U or L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the (i,i) element of the factor U or L is
+*                zero, and the inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAUUM, DTRTRI, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPOTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Invert the triangular Cholesky factor U or L.
+*
+      CALL DTRTRI( UPLO, 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+*     Form inv(U)*inv(U)' or inv(L)'*inv(L).
+*
+      CALL DLAUUM( UPLO, N, A, LDA, INFO )
+*
+      RETURN
+*
+*     End of DPOTRI
+*
+      END
diff --git a/libcruft/lapack/dpotrs.f b/libcruft/lapack/dpotrs.f
new file mode 100644
index 0000000..0273655
--- /dev/null
+++ b/libcruft/lapack/dpotrs.f
@@ -0,0 +1,132 @@
+      SUBROUTINE DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPOTRS solves a system of linear equations A*X = B with a symmetric
+*  positive definite matrix A using the Cholesky factorization
+*  A = U**T*U or A = L*L**T computed by DPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T, as computed by DPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPOTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Non-unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+      END IF
+*
+      RETURN
+*
+*     End of DPOTRS
+*
+      END
diff --git a/libcruft/lapack/dptsv.f b/libcruft/lapack/dptsv.f
new file mode 100644
index 0000000..dd5f0be
--- /dev/null
+++ b/libcruft/lapack/dptsv.f
@@ -0,0 +1,99 @@
+      SUBROUTINE DPTSV( N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   B( LDB, * ), D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPTSV computes the solution to a real system of linear equations
+*  A*X = B, where A is an N-by-N symmetric positive definite tridiagonal
+*  matrix, and X and B are N-by-NRHS matrices.
+*
+*  A is factored as A = L*D*L**T, and the factored form of A is then
+*  used to solve the system of equations.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the factorization A = L*D*L**T.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L**T factorization of
+*          A.  (E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U**T*D*U factorization of A.)
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the solution has not been
+*                computed.  The factorization has not been completed
+*                unless i = N.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           DPTTRF, DPTTRS, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPTSV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      CALL DPTTRF( N, D, E, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL DPTTRS( N, NRHS, D, E, B, LDB, INFO )
+      END IF
+      RETURN
+*
+*     End of DPTSV
+*
+      END
diff --git a/libcruft/lapack/dpttrf.f b/libcruft/lapack/dpttrf.f
new file mode 100644
index 0000000..7f774ee
--- /dev/null
+++ b/libcruft/lapack/dpttrf.f
@@ -0,0 +1,152 @@
+      SUBROUTINE DPTTRF( N, D, E, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPTTRF computes the L*D*L' factorization of a real symmetric
+*  positive definite tridiagonal matrix A.  The factorization may also
+*  be regarded as having the form A = U'*D*U.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the L*D*L' factorization of A.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L' factorization of A.
+*          E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U'*D*U factorization of A.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite; if k < N, the factorization could not
+*               be completed, while if k = N, the factorization was
+*               completed, but D(N) <= 0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I4
+      DOUBLE PRECISION   EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MOD
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'DPTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      I4 = MOD( N-1, 4 )
+      DO 10 I = 1, I4
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 30
+         END IF
+         EI = E( I )
+         E( I ) = EI / D( I )
+         D( I+1 ) = D( I+1 ) - E( I )*EI
+   10 CONTINUE
+*
+      DO 20 I = I4 + 1, N - 4, 4
+*
+*        Drop out of the loop if d(i) <= 0: the matrix is not positive
+*        definite.
+*
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 30
+         END IF
+*
+*        Solve for e(i) and d(i+1).
+*
+         EI = E( I )
+         E( I ) = EI / D( I )
+         D( I+1 ) = D( I+1 ) - E( I )*EI
+*
+         IF( D( I+1 ).LE.ZERO ) THEN
+            INFO = I + 1
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+1) and d(i+2).
+*
+         EI = E( I+1 )
+         E( I+1 ) = EI / D( I+1 )
+         D( I+2 ) = D( I+2 ) - E( I+1 )*EI
+*
+         IF( D( I+2 ).LE.ZERO ) THEN
+            INFO = I + 2
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+2) and d(i+3).
+*
+         EI = E( I+2 )
+         E( I+2 ) = EI / D( I+2 )
+         D( I+3 ) = D( I+3 ) - E( I+2 )*EI
+*
+         IF( D( I+3 ).LE.ZERO ) THEN
+            INFO = I + 3
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+3) and d(i+4).
+*
+         EI = E( I+3 )
+         E( I+3 ) = EI / D( I+3 )
+         D( I+4 ) = D( I+4 ) - E( I+3 )*EI
+   20 CONTINUE
+*
+*     Check d(n) for positive definiteness.
+*
+      IF( D( N ).LE.ZERO )
+     $   INFO = N
+*
+   30 CONTINUE
+      RETURN
+*
+*     End of DPTTRF
+*
+      END
diff --git a/libcruft/lapack/dpttrs.f b/libcruft/lapack/dpttrs.f
new file mode 100644
index 0000000..9a2a477
--- /dev/null
+++ b/libcruft/lapack/dpttrs.f
@@ -0,0 +1,114 @@
+      SUBROUTINE DPTTRS( N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   B( LDB, * ), D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPTTRS solves a tridiagonal system of the form
+*     A * X = B
+*  using the L*D*L' factorization of A computed by DPTTRF.  D is a
+*  diagonal matrix specified in the vector D, L is a unit bidiagonal
+*  matrix whose subdiagonal is specified in the vector E, and X and B
+*  are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          L*D*L' factorization of A.
+*
+*  E       (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) subdiagonal elements of the unit bidiagonal factor
+*          L from the L*D*L' factorization of A.  E can also be regarded
+*          as the superdiagonal of the unit bidiagonal factor U from the
+*          factorization A = U'*D*U.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DPTTS2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DPTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'DPTTRS', ' ', N, NRHS, -1, -1 ) )
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL DPTTS2( N, NRHS, D, E, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL DPTTS2( N, JB, D, E, B( 1, J ), LDB )
+   10    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DPTTRS
+*
+      END
diff --git a/libcruft/lapack/dptts2.f b/libcruft/lapack/dptts2.f
new file mode 100644
index 0000000..ce2337d
--- /dev/null
+++ b/libcruft/lapack/dptts2.f
@@ -0,0 +1,93 @@
+      SUBROUTINE DPTTS2( N, NRHS, D, E, B, LDB )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   B( LDB, * ), D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DPTTS2 solves a tridiagonal system of the form
+*     A * X = B
+*  using the L*D*L' factorization of A computed by DPTTRF.  D is a
+*  diagonal matrix specified in the vector D, L is a unit bidiagonal
+*  matrix whose subdiagonal is specified in the vector E, and X and B
+*  are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          L*D*L' factorization of A.
+*
+*  E       (input) DOUBLE PRECISION array, dimension (N-1)
+*          The (n-1) subdiagonal elements of the unit bidiagonal factor
+*          L from the L*D*L' factorization of A.  E can also be regarded
+*          as the superdiagonal of the unit bidiagonal factor U from the
+*          factorization A = U'*D*U.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 ) THEN
+         IF( N.EQ.1 )
+     $      CALL DSCAL( NRHS, 1.D0 / D( 1 ), B, LDB )
+         RETURN
+      END IF
+*
+*     Solve A * X = B using the factorization A = L*D*L',
+*     overwriting each right hand side vector with its solution.
+*
+      DO 30 J = 1, NRHS
+*
+*           Solve L * x = b.
+*
+         DO 10 I = 2, N
+            B( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )
+   10    CONTINUE
+*
+*           Solve D * L' * x = b.
+*
+         B( N, J ) = B( N, J ) / D( N )
+         DO 20 I = N - 1, 1, -1
+            B( I, J ) = B( I, J ) / D( I ) - B( I+1, J )*E( I )
+   20    CONTINUE
+   30 CONTINUE
+*
+      RETURN
+*
+*     End of DPTTS2
+*
+      END
diff --git a/libcruft/lapack/drscl.f b/libcruft/lapack/drscl.f
new file mode 100644
index 0000000..a13e96d
--- /dev/null
+++ b/libcruft/lapack/drscl.f
@@ -0,0 +1,114 @@
+      SUBROUTINE DRSCL( N, SA, SX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      DOUBLE PRECISION   SA
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   SX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DRSCL multiplies an n-element real vector x by the real scalar 1/a.
+*  This is done without overflow or underflow as long as
+*  the final result x/a does not overflow or underflow.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of components of the vector x.
+*
+*  SA      (input) DOUBLE PRECISION
+*          The scalar a which is used to divide each component of x.
+*          SA must be >= 0, or the subroutine will divide by zero.
+*
+*  SX      (input/output) DOUBLE PRECISION array, dimension
+*                         (1+(N-1)*abs(INCX))
+*          The n-element vector x.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector SX.
+*          > 0:  SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i),     1< i<= n
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      DOUBLE PRECISION   BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Initialize the denominator to SA and the numerator to 1.
+*
+      CDEN = SA
+      CNUM = ONE
+*
+   10 CONTINUE
+      CDEN1 = CDEN*SMLNUM
+      CNUM1 = CNUM / BIGNUM
+      IF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN
+*
+*        Pre-multiply X by SMLNUM if CDEN is large compared to CNUM.
+*
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CDEN = CDEN1
+      ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN
+*
+*        Pre-multiply X by BIGNUM if CDEN is small compared to CNUM.
+*
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CNUM = CNUM1
+      ELSE
+*
+*        Multiply X by CNUM / CDEN and return.
+*
+         MUL = CNUM / CDEN
+         DONE = .TRUE.
+      END IF
+*
+*     Scale the vector X by MUL
+*
+      CALL DSCAL( N, MUL, SX, INCX )
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of DRSCL
+*
+      END
diff --git a/libcruft/lapack/dsteqr.f b/libcruft/lapack/dsteqr.f
new file mode 100644
index 0000000..0afd795
--- /dev/null
+++ b/libcruft/lapack/dsteqr.f
@@ -0,0 +1,500 @@
+      SUBROUTINE DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPZ
+      INTEGER            INFO, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSTEQR computes all eigenvalues and, optionally, eigenvectors of a
+*  symmetric tridiagonal matrix using the implicit QL or QR method.
+*  The eigenvectors of a full or band symmetric matrix can also be found
+*  if DSYTRD or DSPTRD or DSBTRD has been used to reduce this matrix to
+*  tridiagonal form.
+*
+*  Arguments
+*  =========
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only.
+*          = 'V':  Compute eigenvalues and eigenvectors of the original
+*                  symmetric matrix.  On entry, Z must contain the
+*                  orthogonal matrix used to reduce the original matrix
+*                  to tridiagonal form.
+*          = 'I':  Compute eigenvalues and eigenvectors of the
+*                  tridiagonal matrix.  Z is initialized to the identity
+*                  matrix.
+*
+*  N       (input) INTEGER
+*          The order of the matrix.  N >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the diagonal elements of the tridiagonal matrix.
+*          On exit, if INFO = 0, the eigenvalues in ascending order.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix.
+*          On exit, E has been destroyed.
+*
+*  Z       (input/output) DOUBLE PRECISION array, dimension (LDZ, N)
+*          On entry, if  COMPZ = 'V', then Z contains the orthogonal
+*          matrix used in the reduction to tridiagonal form.
+*          On exit, if INFO = 0, then if  COMPZ = 'V', Z contains the
+*          orthonormal eigenvectors of the original symmetric matrix,
+*          and if COMPZ = 'I', Z contains the orthonormal eigenvectors
+*          of the symmetric tridiagonal matrix.
+*          If COMPZ = 'N', then Z is not referenced.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1, and if
+*          eigenvectors are desired, then  LDZ >= max(1,N).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (max(1,2*N-2))
+*          If COMPZ = 'N', then WORK is not referenced.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm has failed to find all the eigenvalues in
+*                a total of 30*N iterations; if INFO = i, then i
+*                elements of E have not converged to zero; on exit, D
+*                and E contain the elements of a symmetric tridiagonal
+*                matrix which is orthogonally similar to the original
+*                matrix.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
+     $                   THREE = 3.0D0 )
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 30 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
+     $                   LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
+     $                   NM1, NMAXIT
+      DOUBLE PRECISION   ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
+     $                   S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH, DLANST, DLAPY2
+      EXTERNAL           LSAME, DLAMCH, DLANST, DLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAE2, DLAEV2, DLARTG, DLASCL, DLASET, DLASR,
+     $                   DLASRT, DSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ICOMPZ = 0
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ICOMPZ = 2
+      ELSE
+         ICOMPZ = -1
+      END IF
+      IF( ICOMPZ.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,
+     $         N ) ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSTEQR', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( N.EQ.1 ) THEN
+         IF( ICOMPZ.EQ.2 )
+     $      Z( 1, 1 ) = ONE
+         RETURN
+      END IF
+*
+*     Determine the unit roundoff and over/underflow thresholds.
+*
+      EPS = DLAMCH( 'E' )
+      EPS2 = EPS**2
+      SAFMIN = DLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      SSFMAX = SQRT( SAFMAX ) / THREE
+      SSFMIN = SQRT( SAFMIN ) / EPS2
+*
+*     Compute the eigenvalues and eigenvectors of the tridiagonal
+*     matrix.
+*
+      IF( ICOMPZ.EQ.2 )
+     $   CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
+*
+      NMAXIT = N*MAXIT
+      JTOT = 0
+*
+*     Determine where the matrix splits and choose QL or QR iteration
+*     for each block, according to whether top or bottom diagonal
+*     element is smaller.
+*
+      L1 = 1
+      NM1 = N - 1
+*
+   10 CONTINUE
+      IF( L1.GT.N )
+     $   GO TO 160
+      IF( L1.GT.1 )
+     $   E( L1-1 ) = ZERO
+      IF( L1.LE.NM1 ) THEN
+         DO 20 M = L1, NM1
+            TST = ABS( E( M ) )
+            IF( TST.EQ.ZERO )
+     $         GO TO 30
+            IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
+     $          1 ) ) ) )*EPS ) THEN
+               E( M ) = ZERO
+               GO TO 30
+            END IF
+   20    CONTINUE
+      END IF
+      M = N
+*
+   30 CONTINUE
+      L = L1
+      LSV = L
+      LEND = M
+      LENDSV = LEND
+      L1 = M + 1
+      IF( LEND.EQ.L )
+     $   GO TO 10
+*
+*     Scale submatrix in rows and columns L to LEND
+*
+      ANORM = DLANST( 'I', LEND-L+1, D( L ), E( L ) )
+      ISCALE = 0
+      IF( ANORM.EQ.ZERO )
+     $   GO TO 10
+      IF( ANORM.GT.SSFMAX ) THEN
+         ISCALE = 1
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
+     $                INFO )
+      ELSE IF( ANORM.LT.SSFMIN ) THEN
+         ISCALE = 2
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
+     $                INFO )
+      END IF
+*
+*     Choose between QL and QR iteration
+*
+      IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
+         LEND = LSV
+         L = LENDSV
+      END IF
+*
+      IF( LEND.GT.L ) THEN
+*
+*        QL Iteration
+*
+*        Look for small subdiagonal element.
+*
+   40    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDM1 = LEND - 1
+            DO 50 M = L, LENDM1
+               TST = ABS( E( M ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+
+     $             SAFMIN )GO TO 60
+   50       CONTINUE
+         END IF
+*
+         M = LEND
+*
+   60    CONTINUE
+         IF( M.LT.LEND )
+     $      E( M ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 80
+*
+*        If remaining matrix is 2-by-2, use DLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L+1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL DLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )
+               WORK( L ) = C
+               WORK( N-1+L ) = S
+               CALL DLASR( 'R', 'V', 'B', N, 2, WORK( L ),
+     $                     WORK( N-1+L ), Z( 1, L ), LDZ )
+            ELSE
+               CALL DLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )
+            END IF
+            D( L ) = RT1
+            D( L+1 ) = RT2
+            E( L ) = ZERO
+            L = L + 2
+            IF( L.LE.LEND )
+     $         GO TO 40
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L+1 )-P ) / ( TWO*E( L ) )
+         R = DLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         MM1 = M - 1
+         DO 70 I = MM1, L, -1
+            F = S*E( I )
+            B = C*E( I )
+            CALL DLARTG( G, F, C, S, R )
+            IF( I.NE.M-1 )
+     $         E( I+1 ) = R
+            G = D( I+1 ) - P
+            R = ( D( I )-G )*S + TWO*C*B
+            P = S*R
+            D( I+1 ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = -S
+            END IF
+*
+   70    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = M - L + 1
+            CALL DLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),
+     $                  Z( 1, L ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( L ) = G
+         GO TO 40
+*
+*        Eigenvalue found.
+*
+   80    CONTINUE
+         D( L ) = P
+*
+         L = L + 1
+         IF( L.LE.LEND )
+     $      GO TO 40
+         GO TO 140
+*
+      ELSE
+*
+*        QR Iteration
+*
+*        Look for small superdiagonal element.
+*
+   90    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDP1 = LEND + 1
+            DO 100 M = L, LENDP1, -1
+               TST = ABS( E( M-1 ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+
+     $             SAFMIN )GO TO 110
+  100       CONTINUE
+         END IF
+*
+         M = LEND
+*
+  110    CONTINUE
+         IF( M.GT.LEND )
+     $      E( M-1 ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 130
+*
+*        If remaining matrix is 2-by-2, use DLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L-1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL DLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )
+               WORK( M ) = C
+               WORK( N-1+M ) = S
+               CALL DLASR( 'R', 'V', 'F', N, 2, WORK( M ),
+     $                     WORK( N-1+M ), Z( 1, L-1 ), LDZ )
+            ELSE
+               CALL DLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )
+            END IF
+            D( L-1 ) = RT1
+            D( L ) = RT2
+            E( L-1 ) = ZERO
+            L = L - 2
+            IF( L.GE.LEND )
+     $         GO TO 90
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )
+         R = DLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         LM1 = L - 1
+         DO 120 I = M, LM1
+            F = S*E( I )
+            B = C*E( I )
+            CALL DLARTG( G, F, C, S, R )
+            IF( I.NE.M )
+     $         E( I-1 ) = R
+            G = D( I ) - P
+            R = ( D( I+1 )-G )*S + TWO*C*B
+            P = S*R
+            D( I ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = S
+            END IF
+*
+  120    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = L - M + 1
+            CALL DLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),
+     $                  Z( 1, M ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( LM1 ) = G
+         GO TO 90
+*
+*        Eigenvalue found.
+*
+  130    CONTINUE
+         D( L ) = P
+*
+         L = L - 1
+         IF( L.GE.LEND )
+     $      GO TO 90
+         GO TO 140
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+  140 CONTINUE
+      IF( ISCALE.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      ELSE IF( ISCALE.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      END IF
+*
+*     Check for no convergence to an eigenvalue after a total
+*     of N*MAXIT iterations.
+*
+      IF( JTOT.LT.NMAXIT )
+     $   GO TO 10
+      DO 150 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  150 CONTINUE
+      GO TO 190
+*
+*     Order eigenvalues and eigenvectors.
+*
+  160 CONTINUE
+      IF( ICOMPZ.EQ.0 ) THEN
+*
+*        Use Quick Sort
+*
+         CALL DLASRT( 'I', N, D, INFO )
+*
+      ELSE
+*
+*        Use Selection Sort to minimize swaps of eigenvectors
+*
+         DO 180 II = 2, N
+            I = II - 1
+            K = I
+            P = D( I )
+            DO 170 J = II, N
+               IF( D( J ).LT.P ) THEN
+                  K = J
+                  P = D( J )
+               END IF
+  170       CONTINUE
+            IF( K.NE.I ) THEN
+               D( K ) = D( I )
+               D( I ) = P
+               CALL DSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
+            END IF
+  180    CONTINUE
+      END IF
+*
+  190 CONTINUE
+      RETURN
+*
+*     End of DSTEQR
+*
+      END
diff --git a/libcruft/lapack/dsterf.f b/libcruft/lapack/dsterf.f
new file mode 100644
index 0000000..c17ea23
--- /dev/null
+++ b/libcruft/lapack/dsterf.f
@@ -0,0 +1,364 @@
+      SUBROUTINE DSTERF( N, D, E, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSTERF computes all eigenvalues of a symmetric tridiagonal matrix
+*  using the Pal-Walker-Kahan variant of the QL or QR algorithm.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix.  N >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix.
+*          On exit, if INFO = 0, the eigenvalues in ascending order.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix.
+*          On exit, E has been destroyed.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm failed to find all of the eigenvalues in
+*                a total of 30*N iterations; if INFO = i, then i
+*                elements of E have not converged to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
+     $                   THREE = 3.0D0 )
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 30 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,
+     $                   NMAXIT
+      DOUBLE PRECISION   ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,
+     $                   OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,
+     $                   SIGMA, SSFMAX, SSFMIN
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLANST, DLAPY2
+      EXTERNAL           DLAMCH, DLANST, DLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAE2, DLASCL, DLASRT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'DSTERF', -INFO )
+         RETURN
+      END IF
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Determine the unit roundoff for this environment.
+*
+      EPS = DLAMCH( 'E' )
+      EPS2 = EPS**2
+      SAFMIN = DLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      SSFMAX = SQRT( SAFMAX ) / THREE
+      SSFMIN = SQRT( SAFMIN ) / EPS2
+*
+*     Compute the eigenvalues of the tridiagonal matrix.
+*
+      NMAXIT = N*MAXIT
+      SIGMA = ZERO
+      JTOT = 0
+*
+*     Determine where the matrix splits and choose QL or QR iteration
+*     for each block, according to whether top or bottom diagonal
+*     element is smaller.
+*
+      L1 = 1
+*
+   10 CONTINUE
+      IF( L1.GT.N )
+     $   GO TO 170
+      IF( L1.GT.1 )
+     $   E( L1-1 ) = ZERO
+      DO 20 M = L1, N - 1
+         IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
+     $       1 ) ) ) )*EPS ) THEN
+            E( M ) = ZERO
+            GO TO 30
+         END IF
+   20 CONTINUE
+      M = N
+*
+   30 CONTINUE
+      L = L1
+      LSV = L
+      LEND = M
+      LENDSV = LEND
+      L1 = M + 1
+      IF( LEND.EQ.L )
+     $   GO TO 10
+*
+*     Scale submatrix in rows and columns L to LEND
+*
+      ANORM = DLANST( 'I', LEND-L+1, D( L ), E( L ) )
+      ISCALE = 0
+      IF( ANORM.GT.SSFMAX ) THEN
+         ISCALE = 1
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
+     $                INFO )
+      ELSE IF( ANORM.LT.SSFMIN ) THEN
+         ISCALE = 2
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
+     $                INFO )
+      END IF
+*
+      DO 40 I = L, LEND - 1
+         E( I ) = E( I )**2
+   40 CONTINUE
+*
+*     Choose between QL and QR iteration
+*
+      IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
+         LEND = LSV
+         L = LENDSV
+      END IF
+*
+      IF( LEND.GE.L ) THEN
+*
+*        QL Iteration
+*
+*        Look for small subdiagonal element.
+*
+   50    CONTINUE
+         IF( L.NE.LEND ) THEN
+            DO 60 M = L, LEND - 1
+               IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) )
+     $            GO TO 70
+   60       CONTINUE
+         END IF
+         M = LEND
+*
+   70    CONTINUE
+         IF( M.LT.LEND )
+     $      E( M ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 90
+*
+*        If remaining matrix is 2 by 2, use DLAE2 to compute its
+*        eigenvalues.
+*
+         IF( M.EQ.L+1 ) THEN
+            RTE = SQRT( E( L ) )
+            CALL DLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )
+            D( L ) = RT1
+            D( L+1 ) = RT2
+            E( L ) = ZERO
+            L = L + 2
+            IF( L.LE.LEND )
+     $         GO TO 50
+            GO TO 150
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 150
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         RTE = SQRT( E( L ) )
+         SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )
+         R = DLAPY2( SIGMA, ONE )
+         SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
+*
+         C = ONE
+         S = ZERO
+         GAMMA = D( M ) - SIGMA
+         P = GAMMA*GAMMA
+*
+*        Inner loop
+*
+         DO 80 I = M - 1, L, -1
+            BB = E( I )
+            R = P + BB
+            IF( I.NE.M-1 )
+     $         E( I+1 ) = S*R
+            OLDC = C
+            C = P / R
+            S = BB / R
+            OLDGAM = GAMMA
+            ALPHA = D( I )
+            GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
+            D( I+1 ) = OLDGAM + ( ALPHA-GAMMA )
+            IF( C.NE.ZERO ) THEN
+               P = ( GAMMA*GAMMA ) / C
+            ELSE
+               P = OLDC*BB
+            END IF
+   80    CONTINUE
+*
+         E( L ) = S*P
+         D( L ) = SIGMA + GAMMA
+         GO TO 50
+*
+*        Eigenvalue found.
+*
+   90    CONTINUE
+         D( L ) = P
+*
+         L = L + 1
+         IF( L.LE.LEND )
+     $      GO TO 50
+         GO TO 150
+*
+      ELSE
+*
+*        QR Iteration
+*
+*        Look for small superdiagonal element.
+*
+  100    CONTINUE
+         DO 110 M = L, LEND + 1, -1
+            IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) )
+     $         GO TO 120
+  110    CONTINUE
+         M = LEND
+*
+  120    CONTINUE
+         IF( M.GT.LEND )
+     $      E( M-1 ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 140
+*
+*        If remaining matrix is 2 by 2, use DLAE2 to compute its
+*        eigenvalues.
+*
+         IF( M.EQ.L-1 ) THEN
+            RTE = SQRT( E( L-1 ) )
+            CALL DLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )
+            D( L ) = RT1
+            D( L-1 ) = RT2
+            E( L-1 ) = ZERO
+            L = L - 2
+            IF( L.GE.LEND )
+     $         GO TO 100
+            GO TO 150
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 150
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         RTE = SQRT( E( L-1 ) )
+         SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )
+         R = DLAPY2( SIGMA, ONE )
+         SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
+*
+         C = ONE
+         S = ZERO
+         GAMMA = D( M ) - SIGMA
+         P = GAMMA*GAMMA
+*
+*        Inner loop
+*
+         DO 130 I = M, L - 1
+            BB = E( I )
+            R = P + BB
+            IF( I.NE.M )
+     $         E( I-1 ) = S*R
+            OLDC = C
+            C = P / R
+            S = BB / R
+            OLDGAM = GAMMA
+            ALPHA = D( I+1 )
+            GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
+            D( I ) = OLDGAM + ( ALPHA-GAMMA )
+            IF( C.NE.ZERO ) THEN
+               P = ( GAMMA*GAMMA ) / C
+            ELSE
+               P = OLDC*BB
+            END IF
+  130    CONTINUE
+*
+         E( L-1 ) = S*P
+         D( L ) = SIGMA + GAMMA
+         GO TO 100
+*
+*        Eigenvalue found.
+*
+  140    CONTINUE
+         D( L ) = P
+*
+         L = L - 1
+         IF( L.GE.LEND )
+     $      GO TO 100
+         GO TO 150
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+  150 CONTINUE
+      IF( ISCALE.EQ.1 )
+     $   CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+      IF( ISCALE.EQ.2 )
+     $   CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+*
+*     Check for no convergence to an eigenvalue after a total
+*     of N*MAXIT iterations.
+*
+      IF( JTOT.LT.NMAXIT )
+     $   GO TO 10
+      DO 160 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  160 CONTINUE
+      GO TO 180
+*
+*     Sort eigenvalues in increasing order.
+*
+  170 CONTINUE
+      CALL DLASRT( 'I', N, D, INFO )
+*
+  180 CONTINUE
+      RETURN
+*
+*     End of DSTERF
+*
+      END
diff --git a/libcruft/lapack/dsyev.f b/libcruft/lapack/dsyev.f
new file mode 100644
index 0000000..d73600a
--- /dev/null
+++ b/libcruft/lapack/dsyev.f
@@ -0,0 +1,211 @@
+      SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYEV computes all eigenvalues and, optionally, eigenvectors of a
+*  real symmetric matrix A.
+*
+*  Arguments
+*  =========
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA, N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          orthonormal eigenvectors of the matrix A.
+*          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
+*          or the upper triangle (if UPLO='U') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  W       (output) DOUBLE PRECISION array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,3*N-1).
+*          For optimal efficiency, LWORK >= (NB+2)*N,
+*          where NB is the blocksize for DSYTRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the algorithm failed to converge; i
+*                off-diagonal elements of an intermediate tridiagonal
+*                form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, LQUERY, WANTZ
+      INTEGER            IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
+     $                   LLWORK, LWKOPT, NB
+      DOUBLE PRECISION   ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
+     $                   SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, DLANSY
+      EXTERNAL           LSAME, ILAENV, DLAMCH, DLANSY
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASCL, DORGTR, DSCAL, DSTEQR, DSTERF, DSYTRD,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      LOWER = LSAME( UPLO, 'L' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( 1, ( NB+2 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )
+     $      INFO = -8
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSYEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         W( 1 ) = A( 1, 1 )
+         WORK( 1 ) = 2
+         IF( WANTZ )
+     $      A( 1, 1 ) = ONE
+         RETURN
+      END IF
+*
+*     Get machine constants.
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      EPS = DLAMCH( 'Precision' )
+      SMLNUM = SAFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      RMIN = SQRT( SMLNUM )
+      RMAX = SQRT( BIGNUM )
+*
+*     Scale matrix to allowable range, if necessary.
+*
+      ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )
+      ISCALE = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
+         ISCALE = 1
+         SIGMA = RMIN / ANRM
+      ELSE IF( ANRM.GT.RMAX ) THEN
+         ISCALE = 1
+         SIGMA = RMAX / ANRM
+      END IF
+      IF( ISCALE.EQ.1 )
+     $   CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
+*
+*     Call DSYTRD to reduce symmetric matrix to tridiagonal form.
+*
+      INDE = 1
+      INDTAU = INDE + N
+      INDWRK = INDTAU + N
+      LLWORK = LWORK - INDWRK + 1
+      CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),
+     $             WORK( INDWRK ), LLWORK, IINFO )
+*
+*     For eigenvalues only, call DSTERF.  For eigenvectors, first call
+*     DORGTR to generate the orthogonal matrix, then call DSTEQR.
+*
+      IF( .NOT.WANTZ ) THEN
+         CALL DSTERF( N, W, WORK( INDE ), INFO )
+      ELSE
+         CALL DORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
+     $                LLWORK, IINFO )
+         CALL DSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),
+     $                INFO )
+      END IF
+*
+*     If matrix was scaled, then rescale eigenvalues appropriately.
+*
+      IF( ISCALE.EQ.1 ) THEN
+         IF( INFO.EQ.0 ) THEN
+            IMAX = N
+         ELSE
+            IMAX = INFO - 1
+         END IF
+         CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
+      END IF
+*
+*     Set WORK(1) to optimal workspace size.
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of DSYEV
+*
+      END
diff --git a/libcruft/lapack/dsygs2.f b/libcruft/lapack/dsygs2.f
new file mode 100644
index 0000000..2bdc475
--- /dev/null
+++ b/libcruft/lapack/dsygs2.f
@@ -0,0 +1,211 @@
+      SUBROUTINE DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYGS2 reduces a real symmetric-definite generalized eigenproblem
+*  to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U')*A*inv(U) or inv(L)*A*inv(L')
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U` or L'*A*L.
+*
+*  B must have been previously factorized as U'*U or L*L' by DPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U')*A*inv(U) or inv(L)*A*inv(L');
+*          = 2 or 3: compute U*A*U' or L'*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored, and how B has been factorized.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) DOUBLE PRECISION array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by DPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, HALF
+      PARAMETER          ( ONE = 1.0D0, HALF = 0.5D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K
+      DOUBLE PRECISION   AKK, BKK, CT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DSCAL, DSYR2, DTRMV, DTRSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSYGS2', -INFO )
+         RETURN
+      END IF
+*
+      IF( ITYPE.EQ.1 ) THEN
+         IF( UPPER ) THEN
+*
+*           Compute inv(U')*A*inv(U)
+*
+            DO 10 K = 1, N
+*
+*              Update the upper triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL DSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA )
+                  CT = -HALF*AKK
+                  CALL DAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL DSYR2( UPLO, N-K, -ONE, A( K, K+1 ), LDA,
+     $                        B( K, K+1 ), LDB, A( K+1, K+1 ), LDA )
+                  CALL DAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL DTRSV( UPLO, 'Transpose', 'Non-unit', N-K,
+     $                        B( K+1, K+1 ), LDB, A( K, K+1 ), LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute inv(L)*A*inv(L')
+*
+            DO 20 K = 1, N
+*
+*              Update the lower triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL DSCAL( N-K, ONE / BKK, A( K+1, K ), 1 )
+                  CT = -HALF*AKK
+                  CALL DAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL DSYR2( UPLO, N-K, -ONE, A( K+1, K ), 1,
+     $                        B( K+1, K ), 1, A( K+1, K+1 ), LDA )
+                  CALL DAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL DTRSV( UPLO, 'No transpose', 'Non-unit', N-K,
+     $                        B( K+1, K+1 ), LDB, A( K+1, K ), 1 )
+               END IF
+   20       CONTINUE
+         END IF
+      ELSE
+         IF( UPPER ) THEN
+*
+*           Compute U*A*U'
+*
+            DO 30 K = 1, N
+*
+*              Update the upper triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL DTRMV( UPLO, 'No transpose', 'Non-unit', K-1, B,
+     $                     LDB, A( 1, K ), 1 )
+               CT = HALF*AKK
+               CALL DAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL DSYR2( UPLO, K-1, ONE, A( 1, K ), 1, B( 1, K ), 1,
+     $                     A, LDA )
+               CALL DAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL DSCAL( K-1, BKK, A( 1, K ), 1 )
+               A( K, K ) = AKK*BKK**2
+   30       CONTINUE
+         ELSE
+*
+*           Compute L'*A*L
+*
+            DO 40 K = 1, N
+*
+*              Update the lower triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL DTRMV( UPLO, 'Transpose', 'Non-unit', K-1, B, LDB,
+     $                     A( K, 1 ), LDA )
+               CT = HALF*AKK
+               CALL DAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL DSYR2( UPLO, K-1, ONE, A( K, 1 ), LDA, B( K, 1 ),
+     $                     LDB, A, LDA )
+               CALL DAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL DSCAL( K-1, BKK, A( K, 1 ), LDA )
+               A( K, K ) = AKK*BKK**2
+   40       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of DSYGS2
+*
+      END
diff --git a/libcruft/lapack/dsygst.f b/libcruft/lapack/dsygst.f
new file mode 100644
index 0000000..093c793
--- /dev/null
+++ b/libcruft/lapack/dsygst.f
@@ -0,0 +1,249 @@
+      SUBROUTINE DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYGST reduces a real symmetric-definite generalized eigenproblem
+*  to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L.
+*
+*  B must have been previously factorized as U**T*U or L*L**T by DPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);
+*          = 2 or 3: compute U*A*U**T or L**T*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored and B is factored as
+*                  U**T*U;
+*          = 'L':  Lower triangle of A is stored and B is factored as
+*                  L*L**T.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) DOUBLE PRECISION array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by DPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, HALF
+      PARAMETER          ( ONE = 1.0D0, HALF = 0.5D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K, KB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSYGS2, DSYMM, DSYR2K, DTRMM, DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSYGST', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'DSYGST', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ITYPE.EQ.1 ) THEN
+            IF( UPPER ) THEN
+*
+*              Compute inv(U')*A*inv(U)
+*
+               DO 10 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(k:n,k:n)
+*
+                  CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL DTRSM( 'Left', UPLO, 'Transpose', 'Non-unit',
+     $                           KB, N-K-KB+1, ONE, B( K, K ), LDB,
+     $                           A( K, K+KB ), LDA )
+                     CALL DSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB, ONE,
+     $                           A( K, K+KB ), LDA )
+                     CALL DSYR2K( UPLO, 'Transpose', N-K-KB+1, KB, -ONE,
+     $                            A( K, K+KB ), LDA, B( K, K+KB ), LDB,
+     $                            ONE, A( K+KB, K+KB ), LDA )
+                     CALL DSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB, ONE,
+     $                           A( K, K+KB ), LDA )
+                     CALL DTRSM( 'Right', UPLO, 'No transpose',
+     $                           'Non-unit', KB, N-K-KB+1, ONE,
+     $                           B( K+KB, K+KB ), LDB, A( K, K+KB ),
+     $                           LDA )
+                  END IF
+   10          CONTINUE
+            ELSE
+*
+*              Compute inv(L)*A*inv(L')
+*
+               DO 20 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(k:n,k:n)
+*
+                  CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL DTRSM( 'Right', UPLO, 'Transpose', 'Non-unit',
+     $                           N-K-KB+1, KB, ONE, B( K, K ), LDB,
+     $                           A( K+KB, K ), LDA )
+                     CALL DSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB, ONE,
+     $                           A( K+KB, K ), LDA )
+                     CALL DSYR2K( UPLO, 'No transpose', N-K-KB+1, KB,
+     $                            -ONE, A( K+KB, K ), LDA, B( K+KB, K ),
+     $                            LDB, ONE, A( K+KB, K+KB ), LDA )
+                     CALL DSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB, ONE,
+     $                           A( K+KB, K ), LDA )
+                     CALL DTRSM( 'Left', UPLO, 'No transpose',
+     $                           'Non-unit', N-K-KB+1, KB, ONE,
+     $                           B( K+KB, K+KB ), LDB, A( K+KB, K ),
+     $                           LDA )
+                  END IF
+   20          CONTINUE
+            END IF
+         ELSE
+            IF( UPPER ) THEN
+*
+*              Compute U*A*U'
+*
+               DO 30 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL DTRMM( 'Left', UPLO, 'No transpose', 'Non-unit',
+     $                        K-1, KB, ONE, B, LDB, A( 1, K ), LDA )
+                  CALL DSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA )
+                  CALL DSYR2K( UPLO, 'No transpose', K-1, KB, ONE,
+     $                         A( 1, K ), LDA, B( 1, K ), LDB, ONE, A,
+     $                         LDA )
+                  CALL DSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA )
+                  CALL DTRMM( 'Right', UPLO, 'Transpose', 'Non-unit',
+     $                        K-1, KB, ONE, B( K, K ), LDB, A( 1, K ),
+     $                        LDA )
+                  CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   30          CONTINUE
+            ELSE
+*
+*              Compute L'*A*L
+*
+               DO 40 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL DTRMM( 'Right', UPLO, 'No transpose', 'Non-unit',
+     $                        KB, K-1, ONE, B, LDB, A( K, 1 ), LDA )
+                  CALL DSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA )
+                  CALL DSYR2K( UPLO, 'Transpose', K-1, KB, ONE,
+     $                         A( K, 1 ), LDA, B( K, 1 ), LDB, ONE, A,
+     $                         LDA )
+                  CALL DSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA )
+                  CALL DTRMM( 'Left', UPLO, 'Transpose', 'Non-unit', KB,
+     $                        K-1, ONE, B( K, K ), LDB, A( K, 1 ), LDA )
+                  CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of DSYGST
+*
+      END
diff --git a/libcruft/lapack/dsygv.f b/libcruft/lapack/dsygv.f
new file mode 100644
index 0000000..9ae8b73
--- /dev/null
+++ b/libcruft/lapack/dsygv.f
@@ -0,0 +1,229 @@
+      SUBROUTINE DSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
+     $                  LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYGV computes all the eigenvalues, and optionally, the eigenvectors
+*  of a real generalized symmetric-definite eigenproblem, of the form
+*  A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.
+*  Here A and B are assumed to be symmetric and B is also
+*  positive definite.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          Specifies the problem type to be solved:
+*          = 1:  A*x = (lambda)*B*x
+*          = 2:  A*B*x = (lambda)*x
+*          = 3:  B*A*x = (lambda)*x
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangles of A and B are stored;
+*          = 'L':  Lower triangles of A and B are stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA, N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          matrix Z of eigenvectors.  The eigenvectors are normalized
+*          as follows:
+*          if ITYPE = 1 or 2, Z**T*B*Z = I;
+*          if ITYPE = 3, Z**T*inv(B)*Z = I.
+*          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
+*          or the lower triangle (if UPLO='L') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB, N)
+*          On entry, the symmetric positive definite matrix B.
+*          If UPLO = 'U', the leading N-by-N upper triangular part of B
+*          contains the upper triangular part of the matrix B.
+*          If UPLO = 'L', the leading N-by-N lower triangular part of B
+*          contains the lower triangular part of the matrix B.
+*
+*          On exit, if INFO <= N, the part of B containing the matrix is
+*          overwritten by the triangular factor U or L from the Cholesky
+*          factorization B = U**T*U or B = L*L**T.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  W       (output) DOUBLE PRECISION array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,3*N-1).
+*          For optimal efficiency, LWORK >= (NB+2)*N,
+*          where NB is the blocksize for DSYTRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  DPOTRF or DSYEV returned an error code:
+*             <= N:  if INFO = i, DSYEV failed to converge;
+*                    i off-diagonal elements of an intermediate
+*                    tridiagonal form did not converge to zero;
+*             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
+*                    minor of order i of B is not positive definite.
+*                    The factorization of B could not be completed and
+*                    no eigenvalues or eigenvectors were computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER, WANTZ
+      CHARACTER          TRANS
+      INTEGER            LWKMIN, LWKOPT, NB, NEIG
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DPOTRF, DSYEV, DSYGST, DTRMM, DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         LWKMIN = MAX( 1, 3*N - 1 )
+         NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( LWKMIN, ( NB + 2 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -11
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSYGV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form a Cholesky factorization of B.
+*
+      CALL DPOTRF( UPLO, N, B, LDB, INFO )
+      IF( INFO.NE.0 ) THEN
+         INFO = N + INFO
+         RETURN
+      END IF
+*
+*     Transform problem to standard eigenvalue problem and solve.
+*
+      CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      CALL DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
+*
+      IF( WANTZ ) THEN
+*
+*        Backtransform eigenvectors to the original problem.
+*
+         NEIG = N
+         IF( INFO.GT.0 )
+     $      NEIG = INFO - 1
+         IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
+*
+*           For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
+*           backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'N'
+            ELSE
+               TRANS = 'T'
+            END IF
+*
+            CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+*
+         ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*           For B*A*x=(lambda)*x;
+*           backtransform eigenvectors: x = L*y or U'*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'T'
+            ELSE
+               TRANS = 'N'
+            END IF
+*
+            CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+         END IF
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DSYGV
+*
+      END
diff --git a/libcruft/lapack/dsytd2.f b/libcruft/lapack/dsytd2.f
new file mode 100644
index 0000000..c696818
--- /dev/null
+++ b/libcruft/lapack/dsytd2.f
@@ -0,0 +1,248 @@
+      SUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), D( * ), E( * ), TAU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal
+*  form T by an orthogonal similarity transformation: Q' * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the orthogonal
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the orthogonal matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO, HALF
+      PARAMETER          ( ONE = 1.0D0, ZERO = 0.0D0,
+     $                   HALF = 1.0D0 / 2.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      DOUBLE PRECISION   ALPHA, TAUI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DLARFG, DSYMV, DSYR2, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DDOT
+      EXTERNAL           LSAME, DDOT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSYTD2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A
+*
+         DO 10 I = N - 1, 1, -1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(1:i-1,i+1)
+*
+            CALL DLARFG( I, A( I, I+1 ), A( 1, I+1 ), 1, TAUI )
+            E( I ) = A( I, I+1 )
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(1:i,1:i)
+*
+               A( I, I+1 ) = ONE
+*
+*              Compute  x := tau * A * v  storing x in TAU(1:i)
+*
+               CALL DSYMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO,
+     $                     TAU, 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*DDOT( I, TAU, 1, A( 1, I+1 ), 1 )
+               CALL DAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL DSYR2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A,
+     $                     LDA )
+*
+               A( I, I+1 ) = E( I )
+            END IF
+            D( I+1 ) = A( I+1, I+1 )
+            TAU( I ) = TAUI
+   10    CONTINUE
+         D( 1 ) = A( 1, 1 )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         DO 20 I = 1, N - 1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(i+2:n,i)
+*
+            CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,
+     $                   TAUI )
+            E( I ) = A( I+1, I )
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(i+1:n,i+1:n)
+*
+               A( I+1, I ) = ONE
+*
+*              Compute  x := tau * A * v  storing y in TAU(i:n-1)
+*
+               CALL DSYMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, TAU( I ), 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*DDOT( N-I, TAU( I ), 1, A( I+1, I ),
+     $                 1 )
+               CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL DSYR2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1,
+     $                     A( I+1, I+1 ), LDA )
+*
+               A( I+1, I ) = E( I )
+            END IF
+            D( I ) = A( I, I )
+            TAU( I ) = TAUI
+   20    CONTINUE
+         D( N ) = A( N, N )
+      END IF
+*
+      RETURN
+*
+*     End of DSYTD2
+*
+      END
diff --git a/libcruft/lapack/dsytrd.f b/libcruft/lapack/dsytrd.f
new file mode 100644
index 0000000..569ee35
--- /dev/null
+++ b/libcruft/lapack/dsytrd.f
@@ -0,0 +1,294 @@
+      SUBROUTINE DSYTRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), D( * ), E( * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DSYTRD reduces a real symmetric matrix A to real symmetric
+*  tridiagonal form T by an orthogonal similarity transformation:
+*  Q**T * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the orthogonal
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the orthogonal matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= 1.
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLATRD, DSYR2K, DSYTD2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.
+*
+         NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = N*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DSYTRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NX = N
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code).
+*
+         NX = MAX( NB, ILAENV( 3, 'DSYTRD', UPLO, N, -1, -1, -1 ) )
+         IF( NX.LT.N ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code by setting NX = N.
+*
+               NB = MAX( LWORK / LDWORK, 1 )
+               NBMIN = ILAENV( 2, 'DSYTRD', UPLO, N, -1, -1, -1 )
+               IF( NB.LT.NBMIN )
+     $            NX = N
+            END IF
+         ELSE
+            NX = N
+         END IF
+      ELSE
+         NB = 1
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A.
+*        Columns 1:kk are handled by the unblocked method.
+*
+         KK = N - ( ( N-NX+NB-1 ) / NB )*NB
+         DO 20 I = N - NB + 1, KK + 1, -NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL DLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK,
+     $                   LDWORK )
+*
+*           Update the unreduced submatrix A(1:i-1,1:i-1), using an
+*           update of the form:  A := A - V*W' - W*V'
+*
+            CALL DSYR2K( UPLO, 'No transpose', I-1, NB, -ONE, A( 1, I ),
+     $                   LDA, WORK, LDWORK, ONE, A, LDA )
+*
+*           Copy superdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 10 J = I, I + NB - 1
+               A( J-1, J ) = E( J-1 )
+               D( J ) = A( J, J )
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL DSYTD2( UPLO, KK, A, LDA, D, E, TAU, IINFO )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         DO 40 I = 1, N - NX, NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL DLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ),
+     $                   TAU( I ), WORK, LDWORK )
+*
+*           Update the unreduced submatrix A(i+ib:n,i+ib:n), using
+*           an update of the form:  A := A - V*W' - W*V'
+*
+            CALL DSYR2K( UPLO, 'No transpose', N-I-NB+1, NB, -ONE,
+     $                   A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE,
+     $                   A( I+NB, I+NB ), LDA )
+*
+*           Copy subdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 30 J = I, I + NB - 1
+               A( J+1, J ) = E( J )
+               D( J ) = A( J, J )
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL DSYTD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $                TAU( I ), IINFO )
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of DSYTRD
+*
+      END
diff --git a/libcruft/lapack/dtgevc.f b/libcruft/lapack/dtgevc.f
new file mode 100644
index 0000000..091c3f6
--- /dev/null
+++ b/libcruft/lapack/dtgevc.f
@@ -0,0 +1,1147 @@
+      SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
+     $                   LDVL, VR, LDVR, MM, M, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDP, LDS, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      DOUBLE PRECISION   P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
+     $                   VR( LDVR, * ), WORK( * )
+*     ..
+*
+*
+*  Purpose
+*  =======
+*
+*  DTGEVC computes some or all of the right and/or left eigenvectors of
+*  a pair of real matrices (S,P), where S is a quasi-triangular matrix
+*  and P is upper triangular.  Matrix pairs of this type are produced by
+*  the generalized Schur factorization of a matrix pair (A,B):
+*
+*     A = Q*S*Z**T,  B = Q*P*Z**T
+*
+*  as computed by DGGHRD + DHGEQZ.
+*
+*  The right eigenvector x and the left eigenvector y of (S,P)
+*  corresponding to an eigenvalue w are defined by:
+*  
+*     S*x = w*P*x,  (y**H)*S = w*(y**H)*P,
+*  
+*  where y**H denotes the conjugate tranpose of y.
+*  The eigenvalues are not input to this routine, but are computed
+*  directly from the diagonal blocks of S and P.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of (S,P), or the products Z*X and/or Q*Y,
+*  where Z and Q are input matrices.
+*  If Q and Z are the orthogonal factors from the generalized Schur
+*  factorization of a matrix pair (A,B), then Z*X and Q*Y
+*  are the matrices of right and left eigenvectors of (A,B).
+* 
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R': compute right eigenvectors only;
+*          = 'L': compute left eigenvectors only;
+*          = 'B': compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A': compute all right and/or left eigenvectors;
+*          = 'B': compute all right and/or left eigenvectors,
+*                 backtransformed by the matrices in VR and/or VL;
+*          = 'S': compute selected right and/or left eigenvectors,
+*                 specified by the logical array SELECT.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          If HOWMNY='S', SELECT specifies the eigenvectors to be
+*          computed.  If w(j) is a real eigenvalue, the corresponding
+*          real eigenvector is computed if SELECT(j) is .TRUE..
+*          If w(j) and w(j+1) are the real and imaginary parts of a
+*          complex eigenvalue, the corresponding complex eigenvector
+*          is computed if either SELECT(j) or SELECT(j+1) is .TRUE.,
+*          and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is
+*          set to .FALSE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrices S and P.  N >= 0.
+*
+*  S       (input) DOUBLE PRECISION array, dimension (LDS,N)
+*          The upper quasi-triangular matrix S from a generalized Schur
+*          factorization, as computed by DHGEQZ.
+*
+*  LDS     (input) INTEGER
+*          The leading dimension of array S.  LDS >= max(1,N).
+*
+*  P       (input) DOUBLE PRECISION array, dimension (LDP,N)
+*          The upper triangular matrix P from a generalized Schur
+*          factorization, as computed by DHGEQZ.
+*          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks
+*          of S must be in positive diagonal form.
+*
+*  LDP     (input) INTEGER
+*          The leading dimension of array P.  LDP >= max(1,N).
+*
+*  VL      (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*          of left Schur vectors returned by DHGEQZ).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
+*                      SELECT, stored consecutively in the columns of
+*                      VL, in the same order as their eigenvalues.
+*
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part, and the second the imaginary part.
+*
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'B', LDVL >= N.
+*
+*  VR      (input/output) DOUBLE PRECISION array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Z (usually the orthogonal matrix Z
+*          of right Schur vectors returned by DHGEQZ).
+*
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
+*          if HOWMNY = 'B' or 'b', the matrix Z*X;
+*          if HOWMNY = 'S' or 's', the right eigenvectors of (S,P)
+*                      specified by SELECT, stored consecutively in the
+*                      columns of VR, in the same order as their
+*                      eigenvalues.
+*
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part and the second the imaginary part.
+*          
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B', LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
+*          is set to N.  Each selected real eigenvector occupies one
+*          column and each selected complex eigenvector occupies two
+*          columns.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (6*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the 2-by-2 block (INFO:INFO+1) does not have a complex
+*                eigenvalue.
+*
+*  Further Details
+*  ===============
+*
+*  Allocation of workspace:
+*  ---------- -- ---------
+*
+*     WORK( j ) = 1-norm of j-th column of A, above the diagonal
+*     WORK( N+j ) = 1-norm of j-th column of B, above the diagonal
+*     WORK( 2*N+1:3*N ) = real part of eigenvector
+*     WORK( 3*N+1:4*N ) = imaginary part of eigenvector
+*     WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector
+*     WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector
+*
+*  Rowwise vs. columnwise solution methods:
+*  ------- --  ---------- -------- -------
+*
+*  Finding a generalized eigenvector consists basically of solving the
+*  singular triangular system
+*
+*   (A - w B) x = 0     (for right) or:   (A - w B)**H y = 0  (for left)
+*
+*  Consider finding the i-th right eigenvector (assume all eigenvalues
+*  are real). The equation to be solved is:
+*       n                   i
+*  0 = sum  C(j,k) v(k)  = sum  C(j,k) v(k)     for j = i,. . .,1
+*      k=j                 k=j
+*
+*  where  C = (A - w B)  (The components v(i+1:n) are 0.)
+*
+*  The "rowwise" method is:
+*
+*  (1)  v(i) := 1
+*  for j = i-1,. . .,1:
+*                          i
+*      (2) compute  s = - sum C(j,k) v(k)   and
+*                        k=j+1
+*
+*      (3) v(j) := s / C(j,j)
+*
+*  Step 2 is sometimes called the "dot product" step, since it is an
+*  inner product between the j-th row and the portion of the eigenvector
+*  that has been computed so far.
+*
+*  The "columnwise" method consists basically in doing the sums
+*  for all the rows in parallel.  As each v(j) is computed, the
+*  contribution of v(j) times the j-th column of C is added to the
+*  partial sums.  Since FORTRAN arrays are stored columnwise, this has
+*  the advantage that at each step, the elements of C that are accessed
+*  are adjacent to one another, whereas with the rowwise method, the
+*  elements accessed at a step are spaced LDS (and LDP) words apart.
+*
+*  When finding left eigenvectors, the matrix in question is the
+*  transpose of the one in storage, so the rowwise method then
+*  actually accesses columns of A and B at each step, and so is the
+*  preferred method.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, SAFETY
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0,
+     $                   SAFETY = 1.0D+2 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            COMPL, COMPR, IL2BY2, ILABAD, ILALL, ILBACK,
+     $                   ILBBAD, ILCOMP, ILCPLX, LSA, LSB
+      INTEGER            I, IBEG, IEIG, IEND, IHWMNY, IINFO, IM, ISIDE,
+     $                   J, JA, JC, JE, JR, JW, NA, NW
+      DOUBLE PRECISION   ACOEF, ACOEFA, ANORM, ASCALE, BCOEFA, BCOEFI,
+     $                   BCOEFR, BIG, BIGNUM, BNORM, BSCALE, CIM2A,
+     $                   CIM2B, CIMAGA, CIMAGB, CRE2A, CRE2B, CREALA,
+     $                   CREALB, DMIN, SAFMIN, SALFAR, SBETA, SCALE,
+     $                   SMALL, TEMP, TEMP2, TEMP2I, TEMP2R, ULP, XMAX,
+     $                   XSCALE
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   BDIAG( 2 ), SUM( 2, 2 ), SUMS( 2, 2 ),
+     $                   SUMP( 2, 2 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, DLABAD, DLACPY, DLAG2, DLALN2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      IF( LSAME( HOWMNY, 'A' ) ) THEN
+         IHWMNY = 1
+         ILALL = .TRUE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
+         IHWMNY = 2
+         ILALL = .FALSE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
+         IHWMNY = 3
+         ILALL = .TRUE.
+         ILBACK = .TRUE.
+      ELSE
+         IHWMNY = -1
+         ILALL = .TRUE.
+      END IF
+*
+      IF( LSAME( SIDE, 'R' ) ) THEN
+         ISIDE = 1
+         COMPL = .FALSE.
+         COMPR = .TRUE.
+      ELSE IF( LSAME( SIDE, 'L' ) ) THEN
+         ISIDE = 2
+         COMPL = .TRUE.
+         COMPR = .FALSE.
+      ELSE IF( LSAME( SIDE, 'B' ) ) THEN
+         ISIDE = 3
+         COMPL = .TRUE.
+         COMPR = .TRUE.
+      ELSE
+         ISIDE = -1
+      END IF
+*
+      INFO = 0
+      IF( ISIDE.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( IHWMNY.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Count the number of eigenvectors to be computed
+*
+      IF( .NOT.ILALL ) THEN
+         IM = 0
+         ILCPLX = .FALSE.
+         DO 10 J = 1, N
+            IF( ILCPLX ) THEN
+               ILCPLX = .FALSE.
+               GO TO 10
+            END IF
+            IF( J.LT.N ) THEN
+               IF( S( J+1, J ).NE.ZERO )
+     $            ILCPLX = .TRUE.
+            END IF
+            IF( ILCPLX ) THEN
+               IF( SELECT( J ) .OR. SELECT( J+1 ) )
+     $            IM = IM + 2
+            ELSE
+               IF( SELECT( J ) )
+     $            IM = IM + 1
+            END IF
+   10    CONTINUE
+      ELSE
+         IM = N
+      END IF
+*
+*     Check 2-by-2 diagonal blocks of A, B
+*
+      ILABAD = .FALSE.
+      ILBBAD = .FALSE.
+      DO 20 J = 1, N - 1
+         IF( S( J+1, J ).NE.ZERO ) THEN
+            IF( P( J, J ).EQ.ZERO .OR. P( J+1, J+1 ).EQ.ZERO .OR.
+     $          P( J, J+1 ).NE.ZERO )ILBBAD = .TRUE.
+            IF( J.LT.N-1 ) THEN
+               IF( S( J+2, J+1 ).NE.ZERO )
+     $            ILABAD = .TRUE.
+            END IF
+         END IF
+   20 CONTINUE
+*
+      IF( ILABAD ) THEN
+         INFO = -5
+      ELSE IF( ILBBAD ) THEN
+         INFO = -7
+      ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
+         INFO = -10
+      ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
+         INFO = -12
+      ELSE IF( MM.LT.IM ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      M = IM
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Machine Constants
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      BIG = ONE / SAFMIN
+      CALL DLABAD( SAFMIN, BIG )
+      ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
+      SMALL = SAFMIN*N / ULP
+      BIG = ONE / SMALL
+      BIGNUM = ONE / ( SAFMIN*N )
+*
+*     Compute the 1-norm of each column of the strictly upper triangular
+*     part (i.e., excluding all elements belonging to the diagonal
+*     blocks) of A and B to check for possible overflow in the
+*     triangular solver.
+*
+      ANORM = ABS( S( 1, 1 ) )
+      IF( N.GT.1 )
+     $   ANORM = ANORM + ABS( S( 2, 1 ) )
+      BNORM = ABS( P( 1, 1 ) )
+      WORK( 1 ) = ZERO
+      WORK( N+1 ) = ZERO
+*
+      DO 50 J = 2, N
+         TEMP = ZERO
+         TEMP2 = ZERO
+         IF( S( J, J-1 ).EQ.ZERO ) THEN
+            IEND = J - 1
+         ELSE
+            IEND = J - 2
+         END IF
+         DO 30 I = 1, IEND
+            TEMP = TEMP + ABS( S( I, J ) )
+            TEMP2 = TEMP2 + ABS( P( I, J ) )
+   30    CONTINUE
+         WORK( J ) = TEMP
+         WORK( N+J ) = TEMP2
+         DO 40 I = IEND + 1, MIN( J+1, N )
+            TEMP = TEMP + ABS( S( I, J ) )
+            TEMP2 = TEMP2 + ABS( P( I, J ) )
+   40    CONTINUE
+         ANORM = MAX( ANORM, TEMP )
+         BNORM = MAX( BNORM, TEMP2 )
+   50 CONTINUE
+*
+      ASCALE = ONE / MAX( ANORM, SAFMIN )
+      BSCALE = ONE / MAX( BNORM, SAFMIN )
+*
+*     Left eigenvectors
+*
+      IF( COMPL ) THEN
+         IEIG = 0
+*
+*        Main loop over eigenvalues
+*
+         ILCPLX = .FALSE.
+         DO 220 JE = 1, N
+*
+*           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
+*           (b) this would be the second of a complex pair.
+*           Check for complex eigenvalue, so as to be sure of which
+*           entry(-ies) of SELECT to look at.
+*
+            IF( ILCPLX ) THEN
+               ILCPLX = .FALSE.
+               GO TO 220
+            END IF
+            NW = 1
+            IF( JE.LT.N ) THEN
+               IF( S( JE+1, JE ).NE.ZERO ) THEN
+                  ILCPLX = .TRUE.
+                  NW = 2
+               END IF
+            END IF
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE IF( ILCPLX ) THEN
+               ILCOMP = SELECT( JE ) .OR. SELECT( JE+1 )
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( .NOT.ILCOMP )
+     $         GO TO 220
+*
+*           Decide if (a) singular pencil, (b) real eigenvalue, or
+*           (c) complex eigenvalue.
+*
+            IF( .NOT.ILCPLX ) THEN
+               IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- return unit eigenvector
+*
+                  IEIG = IEIG + 1
+                  DO 60 JR = 1, N
+                     VL( JR, IEIG ) = ZERO
+   60             CONTINUE
+                  VL( IEIG, IEIG ) = ONE
+                  GO TO 220
+               END IF
+            END IF
+*
+*           Clear vector
+*
+            DO 70 JR = 1, NW*N
+               WORK( 2*N+JR ) = ZERO
+   70       CONTINUE
+*                                                 T
+*           Compute coefficients in  ( a A - b B )  y = 0
+*              a  is  ACOEF
+*              b  is  BCOEFR + i*BCOEFI
+*
+            IF( .NOT.ILCPLX ) THEN
+*
+*              Real eigenvalue
+*
+               TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
+     $                ABS( P( JE, JE ) )*BSCALE, SAFMIN )
+               SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*P( JE, JE ) )*BSCALE
+               ACOEF = SBETA*ASCALE
+               BCOEFR = SALFAR*BSCALE
+               BCOEFI = ZERO
+*
+*              Scale to avoid underflow
+*
+               SCALE = ONE
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
+               LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
+     $               SMALL
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),
+     $                    ABS( BCOEFR ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEF = SCALE*ACOEF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFR = BSCALE*( SCALE*SALFAR )
+                  ELSE
+                     BCOEFR = SCALE*BCOEFR
+                  END IF
+               END IF
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR )
+*
+*              First component is 1
+*
+               WORK( 2*N+JE ) = ONE
+               XMAX = ONE
+            ELSE
+*
+*              Complex eigenvalue
+*
+               CALL DLAG2( S( JE, JE ), LDS, P( JE, JE ), LDP,
+     $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
+     $                     BCOEFI )
+               BCOEFI = -BCOEFI
+               IF( BCOEFI.EQ.ZERO ) THEN
+                  INFO = JE
+                  RETURN
+               END IF
+*
+*              Scale to avoid over/underflow
+*
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               SCALE = ONE
+               IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
+     $            SCALE = ( SAFMIN / ULP ) / ACOEFA
+               IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
+     $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
+               IF( SAFMIN*ACOEFA.GT.ASCALE )
+     $            SCALE = ASCALE / ( SAFMIN*ACOEFA )
+               IF( SAFMIN*BCOEFA.GT.BSCALE )
+     $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
+               IF( SCALE.NE.ONE ) THEN
+                  ACOEF = SCALE*ACOEF
+                  ACOEFA = ABS( ACOEF )
+                  BCOEFR = SCALE*BCOEFR
+                  BCOEFI = SCALE*BCOEFI
+                  BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               END IF
+*
+*              Compute first two components of eigenvector
+*
+               TEMP = ACOEF*S( JE+1, JE )
+               TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
+               TEMP2I = -BCOEFI*P( JE, JE )
+               IF( ABS( TEMP ).GT.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
+                  WORK( 2*N+JE ) = ONE
+                  WORK( 3*N+JE ) = ZERO
+                  WORK( 2*N+JE+1 ) = -TEMP2R / TEMP
+                  WORK( 3*N+JE+1 ) = -TEMP2I / TEMP
+               ELSE
+                  WORK( 2*N+JE+1 ) = ONE
+                  WORK( 3*N+JE+1 ) = ZERO
+                  TEMP = ACOEF*S( JE, JE+1 )
+                  WORK( 2*N+JE ) = ( BCOEFR*P( JE+1, JE+1 )-ACOEF*
+     $                             S( JE+1, JE+1 ) ) / TEMP
+                  WORK( 3*N+JE ) = BCOEFI*P( JE+1, JE+1 ) / TEMP
+               END IF
+               XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
+     $                ABS( WORK( 2*N+JE+1 ) )+ABS( WORK( 3*N+JE+1 ) ) )
+            END IF
+*
+            DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*                                           T
+*           Triangular solve of  (a A - b B)  y = 0
+*
+*                                   T
+*           (rowwise in  (a A - b B) , or columnwise in (a A - b B) )
+*
+            IL2BY2 = .FALSE.
+*
+            DO 160 J = JE + NW, N
+               IF( IL2BY2 ) THEN
+                  IL2BY2 = .FALSE.
+                  GO TO 160
+               END IF
+*
+               NA = 1
+               BDIAG( 1 ) = P( J, J )
+               IF( J.LT.N ) THEN
+                  IF( S( J+1, J ).NE.ZERO ) THEN
+                     IL2BY2 = .TRUE.
+                     BDIAG( 2 ) = P( J+1, J+1 )
+                     NA = 2
+                  END IF
+               END IF
+*
+*              Check whether scaling is necessary for dot products
+*
+               XSCALE = ONE / MAX( ONE, XMAX )
+               TEMP = MAX( WORK( J ), WORK( N+J ),
+     $                ACOEFA*WORK( J )+BCOEFA*WORK( N+J ) )
+               IF( IL2BY2 )
+     $            TEMP = MAX( TEMP, WORK( J+1 ), WORK( N+J+1 ),
+     $                   ACOEFA*WORK( J+1 )+BCOEFA*WORK( N+J+1 ) )
+               IF( TEMP.GT.BIGNUM*XSCALE ) THEN
+                  DO 90 JW = 0, NW - 1
+                     DO 80 JR = JE, J - 1
+                        WORK( ( JW+2 )*N+JR ) = XSCALE*
+     $                     WORK( ( JW+2 )*N+JR )
+   80                CONTINUE
+   90             CONTINUE
+                  XMAX = XMAX*XSCALE
+               END IF
+*
+*              Compute dot products
+*
+*                    j-1
+*              SUM = sum  conjg( a*S(k,j) - b*P(k,j) )*x(k)
+*                    k=je
+*
+*              To reduce the op count, this is done as
+*
+*              _        j-1                  _        j-1
+*              a*conjg( sum  S(k,j)*x(k) ) - b*conjg( sum  P(k,j)*x(k) )
+*                       k=je                          k=je
+*
+*              which may cause underflow problems if A or B are close
+*              to underflow.  (E.g., less than SMALL.)
+*
+*
+*              A series of compiler directives to defeat vectorization
+*              for the next loop
+*
+*$PL$ CMCHAR=' '
+CDIR$          NEXTSCALAR
+C$DIR          SCALAR
+CDIR$          NEXT SCALAR
+CVD$L          NOVECTOR
+CDEC$          NOVECTOR
+CVD$           NOVECTOR
+*VDIR          NOVECTOR
+*VOCL          LOOP,SCALAR
+CIBM           PREFER SCALAR
+*$PL$ CMCHAR='*'
+*
+               DO 120 JW = 1, NW
+*
+*$PL$ CMCHAR=' '
+CDIR$             NEXTSCALAR
+C$DIR             SCALAR
+CDIR$             NEXT SCALAR
+CVD$L             NOVECTOR
+CDEC$             NOVECTOR
+CVD$              NOVECTOR
+*VDIR             NOVECTOR
+*VOCL             LOOP,SCALAR
+CIBM              PREFER SCALAR
+*$PL$ CMCHAR='*'
+*
+                  DO 110 JA = 1, NA
+                     SUMS( JA, JW ) = ZERO
+                     SUMP( JA, JW ) = ZERO
+*
+                     DO 100 JR = JE, J - 1
+                        SUMS( JA, JW ) = SUMS( JA, JW ) +
+     $                                   S( JR, J+JA-1 )*
+     $                                   WORK( ( JW+1 )*N+JR )
+                        SUMP( JA, JW ) = SUMP( JA, JW ) +
+     $                                   P( JR, J+JA-1 )*
+     $                                   WORK( ( JW+1 )*N+JR )
+  100                CONTINUE
+  110             CONTINUE
+  120          CONTINUE
+*
+*$PL$ CMCHAR=' '
+CDIR$          NEXTSCALAR
+C$DIR          SCALAR
+CDIR$          NEXT SCALAR
+CVD$L          NOVECTOR
+CDEC$          NOVECTOR
+CVD$           NOVECTOR
+*VDIR          NOVECTOR
+*VOCL          LOOP,SCALAR
+CIBM           PREFER SCALAR
+*$PL$ CMCHAR='*'
+*
+               DO 130 JA = 1, NA
+                  IF( ILCPLX ) THEN
+                     SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
+     $                              BCOEFR*SUMP( JA, 1 ) -
+     $                              BCOEFI*SUMP( JA, 2 )
+                     SUM( JA, 2 ) = -ACOEF*SUMS( JA, 2 ) +
+     $                              BCOEFR*SUMP( JA, 2 ) +
+     $                              BCOEFI*SUMP( JA, 1 )
+                  ELSE
+                     SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
+     $                              BCOEFR*SUMP( JA, 1 )
+                  END IF
+  130          CONTINUE
+*
+*                                  T
+*              Solve  ( a A - b B )  y = SUM(,)
+*              with scaling and perturbation of the denominator
+*
+               CALL DLALN2( .TRUE., NA, NW, DMIN, ACOEF, S( J, J ), LDS,
+     $                      BDIAG( 1 ), BDIAG( 2 ), SUM, 2, BCOEFR,
+     $                      BCOEFI, WORK( 2*N+J ), N, SCALE, TEMP,
+     $                      IINFO )
+               IF( SCALE.LT.ONE ) THEN
+                  DO 150 JW = 0, NW - 1
+                     DO 140 JR = JE, J - 1
+                        WORK( ( JW+2 )*N+JR ) = SCALE*
+     $                     WORK( ( JW+2 )*N+JR )
+  140                CONTINUE
+  150             CONTINUE
+                  XMAX = SCALE*XMAX
+               END IF
+               XMAX = MAX( XMAX, TEMP )
+  160       CONTINUE
+*
+*           Copy eigenvector to VL, back transforming if
+*           HOWMNY='B'.
+*
+            IEIG = IEIG + 1
+            IF( ILBACK ) THEN
+               DO 170 JW = 0, NW - 1
+                  CALL DGEMV( 'N', N, N+1-JE, ONE, VL( 1, JE ), LDVL,
+     $                        WORK( ( JW+2 )*N+JE ), 1, ZERO,
+     $                        WORK( ( JW+4 )*N+1 ), 1 )
+  170          CONTINUE
+               CALL DLACPY( ' ', N, NW, WORK( 4*N+1 ), N, VL( 1, JE ),
+     $                      LDVL )
+               IBEG = 1
+            ELSE
+               CALL DLACPY( ' ', N, NW, WORK( 2*N+1 ), N, VL( 1, IEIG ),
+     $                      LDVL )
+               IBEG = JE
+            END IF
+*
+*           Scale eigenvector
+*
+            XMAX = ZERO
+            IF( ILCPLX ) THEN
+               DO 180 J = IBEG, N
+                  XMAX = MAX( XMAX, ABS( VL( J, IEIG ) )+
+     $                   ABS( VL( J, IEIG+1 ) ) )
+  180          CONTINUE
+            ELSE
+               DO 190 J = IBEG, N
+                  XMAX = MAX( XMAX, ABS( VL( J, IEIG ) ) )
+  190          CONTINUE
+            END IF
+*
+            IF( XMAX.GT.SAFMIN ) THEN
+               XSCALE = ONE / XMAX
+*
+               DO 210 JW = 0, NW - 1
+                  DO 200 JR = IBEG, N
+                     VL( JR, IEIG+JW ) = XSCALE*VL( JR, IEIG+JW )
+  200             CONTINUE
+  210          CONTINUE
+            END IF
+            IEIG = IEIG + NW - 1
+*
+  220    CONTINUE
+      END IF
+*
+*     Right eigenvectors
+*
+      IF( COMPR ) THEN
+         IEIG = IM + 1
+*
+*        Main loop over eigenvalues
+*
+         ILCPLX = .FALSE.
+         DO 500 JE = N, 1, -1
+*
+*           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
+*           (b) this would be the second of a complex pair.
+*           Check for complex eigenvalue, so as to be sure of which
+*           entry(-ies) of SELECT to look at -- if complex, SELECT(JE)
+*           or SELECT(JE-1).
+*           If this is a complex pair, the 2-by-2 diagonal block
+*           corresponding to the eigenvalue is in rows/columns JE-1:JE
+*
+            IF( ILCPLX ) THEN
+               ILCPLX = .FALSE.
+               GO TO 500
+            END IF
+            NW = 1
+            IF( JE.GT.1 ) THEN
+               IF( S( JE, JE-1 ).NE.ZERO ) THEN
+                  ILCPLX = .TRUE.
+                  NW = 2
+               END IF
+            END IF
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE IF( ILCPLX ) THEN
+               ILCOMP = SELECT( JE ) .OR. SELECT( JE-1 )
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( .NOT.ILCOMP )
+     $         GO TO 500
+*
+*           Decide if (a) singular pencil, (b) real eigenvalue, or
+*           (c) complex eigenvalue.
+*
+            IF( .NOT.ILCPLX ) THEN
+               IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- unit eigenvector
+*
+                  IEIG = IEIG - 1
+                  DO 230 JR = 1, N
+                     VR( JR, IEIG ) = ZERO
+  230             CONTINUE
+                  VR( IEIG, IEIG ) = ONE
+                  GO TO 500
+               END IF
+            END IF
+*
+*           Clear vector
+*
+            DO 250 JW = 0, NW - 1
+               DO 240 JR = 1, N
+                  WORK( ( JW+2 )*N+JR ) = ZERO
+  240          CONTINUE
+  250       CONTINUE
+*
+*           Compute coefficients in  ( a A - b B ) x = 0
+*              a  is  ACOEF
+*              b  is  BCOEFR + i*BCOEFI
+*
+            IF( .NOT.ILCPLX ) THEN
+*
+*              Real eigenvalue
+*
+               TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
+     $                ABS( P( JE, JE ) )*BSCALE, SAFMIN )
+               SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*P( JE, JE ) )*BSCALE
+               ACOEF = SBETA*ASCALE
+               BCOEFR = SALFAR*BSCALE
+               BCOEFI = ZERO
+*
+*              Scale to avoid underflow
+*
+               SCALE = ONE
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
+               LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
+     $               SMALL
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),
+     $                    ABS( BCOEFR ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEF = SCALE*ACOEF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFR = BSCALE*( SCALE*SALFAR )
+                  ELSE
+                     BCOEFR = SCALE*BCOEFR
+                  END IF
+               END IF
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR )
+*
+*              First component is 1
+*
+               WORK( 2*N+JE ) = ONE
+               XMAX = ONE
+*
+*              Compute contribution from column JE of A and B to sum
+*              (See "Further Details", above.)
+*
+               DO 260 JR = 1, JE - 1
+                  WORK( 2*N+JR ) = BCOEFR*P( JR, JE ) -
+     $                             ACOEF*S( JR, JE )
+  260          CONTINUE
+            ELSE
+*
+*              Complex eigenvalue
+*
+               CALL DLAG2( S( JE-1, JE-1 ), LDS, P( JE-1, JE-1 ), LDP,
+     $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
+     $                     BCOEFI )
+               IF( BCOEFI.EQ.ZERO ) THEN
+                  INFO = JE - 1
+                  RETURN
+               END IF
+*
+*              Scale to avoid over/underflow
+*
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               SCALE = ONE
+               IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
+     $            SCALE = ( SAFMIN / ULP ) / ACOEFA
+               IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
+     $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
+               IF( SAFMIN*ACOEFA.GT.ASCALE )
+     $            SCALE = ASCALE / ( SAFMIN*ACOEFA )
+               IF( SAFMIN*BCOEFA.GT.BSCALE )
+     $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
+               IF( SCALE.NE.ONE ) THEN
+                  ACOEF = SCALE*ACOEF
+                  ACOEFA = ABS( ACOEF )
+                  BCOEFR = SCALE*BCOEFR
+                  BCOEFI = SCALE*BCOEFI
+                  BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               END IF
+*
+*              Compute first two components of eigenvector
+*              and contribution to sums
+*
+               TEMP = ACOEF*S( JE, JE-1 )
+               TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
+               TEMP2I = -BCOEFI*P( JE, JE )
+               IF( ABS( TEMP ).GE.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
+                  WORK( 2*N+JE ) = ONE
+                  WORK( 3*N+JE ) = ZERO
+                  WORK( 2*N+JE-1 ) = -TEMP2R / TEMP
+                  WORK( 3*N+JE-1 ) = -TEMP2I / TEMP
+               ELSE
+                  WORK( 2*N+JE-1 ) = ONE
+                  WORK( 3*N+JE-1 ) = ZERO
+                  TEMP = ACOEF*S( JE-1, JE )
+                  WORK( 2*N+JE ) = ( BCOEFR*P( JE-1, JE-1 )-ACOEF*
+     $                             S( JE-1, JE-1 ) ) / TEMP
+                  WORK( 3*N+JE ) = BCOEFI*P( JE-1, JE-1 ) / TEMP
+               END IF
+*
+               XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
+     $                ABS( WORK( 2*N+JE-1 ) )+ABS( WORK( 3*N+JE-1 ) ) )
+*
+*              Compute contribution from columns JE and JE-1
+*              of A and B to the sums.
+*
+               CREALA = ACOEF*WORK( 2*N+JE-1 )
+               CIMAGA = ACOEF*WORK( 3*N+JE-1 )
+               CREALB = BCOEFR*WORK( 2*N+JE-1 ) -
+     $                  BCOEFI*WORK( 3*N+JE-1 )
+               CIMAGB = BCOEFI*WORK( 2*N+JE-1 ) +
+     $                  BCOEFR*WORK( 3*N+JE-1 )
+               CRE2A = ACOEF*WORK( 2*N+JE )
+               CIM2A = ACOEF*WORK( 3*N+JE )
+               CRE2B = BCOEFR*WORK( 2*N+JE ) - BCOEFI*WORK( 3*N+JE )
+               CIM2B = BCOEFI*WORK( 2*N+JE ) + BCOEFR*WORK( 3*N+JE )
+               DO 270 JR = 1, JE - 2
+                  WORK( 2*N+JR ) = -CREALA*S( JR, JE-1 ) +
+     $                             CREALB*P( JR, JE-1 ) -
+     $                             CRE2A*S( JR, JE ) + CRE2B*P( JR, JE )
+                  WORK( 3*N+JR ) = -CIMAGA*S( JR, JE-1 ) +
+     $                             CIMAGB*P( JR, JE-1 ) -
+     $                             CIM2A*S( JR, JE ) + CIM2B*P( JR, JE )
+  270          CONTINUE
+            END IF
+*
+            DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*           Columnwise triangular solve of  (a A - b B)  x = 0
+*
+            IL2BY2 = .FALSE.
+            DO 370 J = JE - NW, 1, -1
+*
+*              If a 2-by-2 block, is in position j-1:j, wait until
+*              next iteration to process it (when it will be j:j+1)
+*
+               IF( .NOT.IL2BY2 .AND. J.GT.1 ) THEN
+                  IF( S( J, J-1 ).NE.ZERO ) THEN
+                     IL2BY2 = .TRUE.
+                     GO TO 370
+                  END IF
+               END IF
+               BDIAG( 1 ) = P( J, J )
+               IF( IL2BY2 ) THEN
+                  NA = 2
+                  BDIAG( 2 ) = P( J+1, J+1 )
+               ELSE
+                  NA = 1
+               END IF
+*
+*              Compute x(j) (and x(j+1), if 2-by-2 block)
+*
+               CALL DLALN2( .FALSE., NA, NW, DMIN, ACOEF, S( J, J ),
+     $                      LDS, BDIAG( 1 ), BDIAG( 2 ), WORK( 2*N+J ),
+     $                      N, BCOEFR, BCOEFI, SUM, 2, SCALE, TEMP,
+     $                      IINFO )
+               IF( SCALE.LT.ONE ) THEN
+*
+                  DO 290 JW = 0, NW - 1
+                     DO 280 JR = 1, JE
+                        WORK( ( JW+2 )*N+JR ) = SCALE*
+     $                     WORK( ( JW+2 )*N+JR )
+  280                CONTINUE
+  290             CONTINUE
+               END IF
+               XMAX = MAX( SCALE*XMAX, TEMP )
+*
+               DO 310 JW = 1, NW
+                  DO 300 JA = 1, NA
+                     WORK( ( JW+1 )*N+J+JA-1 ) = SUM( JA, JW )
+  300             CONTINUE
+  310          CONTINUE
+*
+*              w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
+*
+               IF( J.GT.1 ) THEN
+*
+*                 Check whether scaling is necessary for sum.
+*
+                  XSCALE = ONE / MAX( ONE, XMAX )
+                  TEMP = ACOEFA*WORK( J ) + BCOEFA*WORK( N+J )
+                  IF( IL2BY2 )
+     $               TEMP = MAX( TEMP, ACOEFA*WORK( J+1 )+BCOEFA*
+     $                      WORK( N+J+1 ) )
+                  TEMP = MAX( TEMP, ACOEFA, BCOEFA )
+                  IF( TEMP.GT.BIGNUM*XSCALE ) THEN
+*
+                     DO 330 JW = 0, NW - 1
+                        DO 320 JR = 1, JE
+                           WORK( ( JW+2 )*N+JR ) = XSCALE*
+     $                        WORK( ( JW+2 )*N+JR )
+  320                   CONTINUE
+  330                CONTINUE
+                     XMAX = XMAX*XSCALE
+                  END IF
+*
+*                 Compute the contributions of the off-diagonals of
+*                 column j (and j+1, if 2-by-2 block) of A and B to the
+*                 sums.
+*
+*
+                  DO 360 JA = 1, NA
+                     IF( ILCPLX ) THEN
+                        CREALA = ACOEF*WORK( 2*N+J+JA-1 )
+                        CIMAGA = ACOEF*WORK( 3*N+J+JA-1 )
+                        CREALB = BCOEFR*WORK( 2*N+J+JA-1 ) -
+     $                           BCOEFI*WORK( 3*N+J+JA-1 )
+                        CIMAGB = BCOEFI*WORK( 2*N+J+JA-1 ) +
+     $                           BCOEFR*WORK( 3*N+J+JA-1 )
+                        DO 340 JR = 1, J - 1
+                           WORK( 2*N+JR ) = WORK( 2*N+JR ) -
+     $                                      CREALA*S( JR, J+JA-1 ) +
+     $                                      CREALB*P( JR, J+JA-1 )
+                           WORK( 3*N+JR ) = WORK( 3*N+JR ) -
+     $                                      CIMAGA*S( JR, J+JA-1 ) +
+     $                                      CIMAGB*P( JR, J+JA-1 )
+  340                   CONTINUE
+                     ELSE
+                        CREALA = ACOEF*WORK( 2*N+J+JA-1 )
+                        CREALB = BCOEFR*WORK( 2*N+J+JA-1 )
+                        DO 350 JR = 1, J - 1
+                           WORK( 2*N+JR ) = WORK( 2*N+JR ) -
+     $                                      CREALA*S( JR, J+JA-1 ) +
+     $                                      CREALB*P( JR, J+JA-1 )
+  350                   CONTINUE
+                     END IF
+  360             CONTINUE
+               END IF
+*
+               IL2BY2 = .FALSE.
+  370       CONTINUE
+*
+*           Copy eigenvector to VR, back transforming if
+*           HOWMNY='B'.
+*
+            IEIG = IEIG - NW
+            IF( ILBACK ) THEN
+*
+               DO 410 JW = 0, NW - 1
+                  DO 380 JR = 1, N
+                     WORK( ( JW+4 )*N+JR ) = WORK( ( JW+2 )*N+1 )*
+     $                                       VR( JR, 1 )
+  380             CONTINUE
+*
+*                 A series of compiler directives to defeat
+*                 vectorization for the next loop
+*
+*
+                  DO 400 JC = 2, JE
+                     DO 390 JR = 1, N
+                        WORK( ( JW+4 )*N+JR ) = WORK( ( JW+4 )*N+JR ) +
+     $                     WORK( ( JW+2 )*N+JC )*VR( JR, JC )
+  390                CONTINUE
+  400             CONTINUE
+  410          CONTINUE
+*
+               DO 430 JW = 0, NW - 1
+                  DO 420 JR = 1, N
+                     VR( JR, IEIG+JW ) = WORK( ( JW+4 )*N+JR )
+  420             CONTINUE
+  430          CONTINUE
+*
+               IEND = N
+            ELSE
+               DO 450 JW = 0, NW - 1
+                  DO 440 JR = 1, N
+                     VR( JR, IEIG+JW ) = WORK( ( JW+2 )*N+JR )
+  440             CONTINUE
+  450          CONTINUE
+*
+               IEND = JE
+            END IF
+*
+*           Scale eigenvector
+*
+            XMAX = ZERO
+            IF( ILCPLX ) THEN
+               DO 460 J = 1, IEND
+                  XMAX = MAX( XMAX, ABS( VR( J, IEIG ) )+
+     $                   ABS( VR( J, IEIG+1 ) ) )
+  460          CONTINUE
+            ELSE
+               DO 470 J = 1, IEND
+                  XMAX = MAX( XMAX, ABS( VR( J, IEIG ) ) )
+  470          CONTINUE
+            END IF
+*
+            IF( XMAX.GT.SAFMIN ) THEN
+               XSCALE = ONE / XMAX
+               DO 490 JW = 0, NW - 1
+                  DO 480 JR = 1, IEND
+                     VR( JR, IEIG+JW ) = XSCALE*VR( JR, IEIG+JW )
+  480             CONTINUE
+  490          CONTINUE
+            END IF
+  500    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DTGEVC
+*
+      END
diff --git a/libcruft/lapack/dtrcon.f b/libcruft/lapack/dtrcon.f
new file mode 100644
index 0000000..23da592
--- /dev/null
+++ b/libcruft/lapack/dtrcon.f
@@ -0,0 +1,197 @@
+      SUBROUTINE DTRCON( NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call DLACN2 in place of DLACON, 5 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRCON estimates the reciprocal of the condition number of a
+*  triangular matrix A, in either the 1-norm or the infinity-norm.
+*
+*  The norm of A is computed and an estimate is obtained for
+*  norm(inv(A)), then the reciprocal of the condition number is
+*  computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, ONENRM, UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      DOUBLE PRECISION   AINVNM, ANORM, SCALE, SMLNUM, XNORM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DLANTR
+      EXTERNAL           LSAME, IDAMAX, DLAMCH, DLANTR
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACN2, DLATRS, DRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTRCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      END IF
+*
+      RCOND = ZERO
+      SMLNUM = DLAMCH( 'Safe minimum' )*DBLE( MAX( 1, N ) )
+*
+*     Compute the norm of the triangular matrix A.
+*
+      ANORM = DLANTR( NORM, UPLO, DIAG, N, N, A, LDA, WORK )
+*
+*     Continue only if ANORM > 0.
+*
+      IF( ANORM.GT.ZERO ) THEN
+*
+*        Estimate the norm of the inverse of A.
+*
+         AINVNM = ZERO
+         NORMIN = 'N'
+         IF( ONENRM ) THEN
+            KASE1 = 1
+         ELSE
+            KASE1 = 2
+         END IF
+         KASE = 0
+   10    CONTINUE
+         CALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.KASE1 ) THEN
+*
+*              Multiply by inv(A).
+*
+               CALL DLATRS( UPLO, 'No transpose', DIAG, NORMIN, N, A,
+     $                      LDA, WORK, SCALE, WORK( 2*N+1 ), INFO )
+            ELSE
+*
+*              Multiply by inv(A').
+*
+               CALL DLATRS( UPLO, 'Transpose', DIAG, NORMIN, N, A, LDA,
+     $                      WORK, SCALE, WORK( 2*N+1 ), INFO )
+            END IF
+            NORMIN = 'Y'
+*
+*           Multiply by 1/SCALE if doing so will not cause overflow.
+*
+            IF( SCALE.NE.ONE ) THEN
+               IX = IDAMAX( N, WORK, 1 )
+               XNORM = ABS( WORK( IX ) )
+               IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )
+     $            GO TO 20
+               CALL DRSCL( N, SCALE, WORK, 1 )
+            END IF
+            GO TO 10
+         END IF
+*
+*        Compute the estimate of the reciprocal condition number.
+*
+         IF( AINVNM.NE.ZERO )
+     $      RCOND = ( ONE / ANORM ) / AINVNM
+      END IF
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of DTRCON
+*
+      END
diff --git a/libcruft/lapack/dtrevc.f b/libcruft/lapack/dtrevc.f
new file mode 100644
index 0000000..a0215f0
--- /dev/null
+++ b/libcruft/lapack/dtrevc.f
@@ -0,0 +1,980 @@
+      SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
+     $                   LDVR, MM, M, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      DOUBLE PRECISION   T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTREVC computes some or all of the right and/or left eigenvectors of
+*  a real upper quasi-triangular matrix T.
+*  Matrices of this type are produced by the Schur factorization of
+*  a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
+*  
+*  The right eigenvector x and the left eigenvector y of T corresponding
+*  to an eigenvalue w are defined by:
+*  
+*     T*x = w*x,     (y**H)*T = w*(y**H)
+*  
+*  where y**H denotes the conjugate transpose of y.
+*  The eigenvalues are not input to this routine, but are read directly
+*  from the diagonal blocks of T.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*  input matrix.  If Q is the orthogonal factor that reduces a matrix
+*  A to Schur form T, then Q*X and Q*Y are the matrices of right and
+*  left eigenvectors of A.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  compute right eigenvectors only;
+*          = 'L':  compute left eigenvectors only;
+*          = 'B':  compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A':  compute all right and/or left eigenvectors;
+*          = 'B':  compute all right and/or left eigenvectors,
+*                  backtransformed by the matrices in VR and/or VL;
+*          = 'S':  compute selected right and/or left eigenvectors,
+*                  as indicated by the logical array SELECT.
+*
+*  SELECT  (input/output) LOGICAL array, dimension (N)
+*          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*          computed.
+*          If w(j) is a real eigenvalue, the corresponding real
+*          eigenvector is computed if SELECT(j) is .TRUE..
+*          If w(j) and w(j+1) are the real and imaginary parts of a
+*          complex eigenvalue, the corresponding complex eigenvector is
+*          computed if either SELECT(j) or SELECT(j+1) is .TRUE., and
+*          on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to
+*          .FALSE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input) DOUBLE PRECISION array, dimension (LDT,N)
+*          The upper quasi-triangular matrix T in Schur canonical form.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  VL      (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*          of Schur vectors returned by DHSEQR).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VL, in the same order as their
+*                           eigenvalues.
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part, and the second the imaginary part.
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'B', LDVL >= N.
+*
+*  VR      (input/output) DOUBLE PRECISION array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*          of Schur vectors returned by DHSEQR).
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*X;
+*          if HOWMNY = 'S', the right eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VR, in the same order as their
+*                           eigenvalues.
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part and the second the imaginary part.
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B', LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.
+*          If HOWMNY = 'A' or 'B', M is set to N.
+*          Each selected real eigenvector occupies one column and each
+*          selected complex eigenvector occupies two columns.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The algorithm used in this program is basically backward (forward)
+*  substitution, with scaling to make the the code robust against
+*  possible overflow.
+*
+*  Each eigenvector is normalized so that the element of largest
+*  magnitude has magnitude 1; here the magnitude of a complex number
+*  (x,y) is taken to be |x| + |y|.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEV
+      INTEGER            I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2
+      DOUBLE PRECISION   BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
+     $                   SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,
+     $                   XNORM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DDOT, DLAMCH
+      EXTERNAL           LSAME, IDAMAX, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DCOPY, DGEMV, DLALN2, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   X( 2, 2 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV = LSAME( HOWMNY, 'A' )
+      OVER = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+      INFO = 0
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE
+*
+*        Set M to the number of columns required to store the selected
+*        eigenvectors, standardize the array SELECT if necessary, and
+*        test MM.
+*
+         IF( SOMEV ) THEN
+            M = 0
+            PAIR = .FALSE.
+            DO 10 J = 1, N
+               IF( PAIR ) THEN
+                  PAIR = .FALSE.
+                  SELECT( J ) = .FALSE.
+               ELSE
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).EQ.ZERO ) THEN
+                        IF( SELECT( J ) )
+     $                     M = M + 1
+                     ELSE
+                        PAIR = .TRUE.
+                        IF( SELECT( J ) .OR. SELECT( J+1 ) ) THEN
+                           SELECT( J ) = .TRUE.
+                           M = M + 2
+                        END IF
+                     END IF
+                  ELSE
+                     IF( SELECT( N ) )
+     $                  M = M + 1
+                  END IF
+               END IF
+   10       CONTINUE
+         ELSE
+            M = N
+         END IF
+*
+         IF( MM.LT.M ) THEN
+            INFO = -11
+         END IF
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTREVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Set the constants to control overflow.
+*
+      UNFL = DLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL DLABAD( UNFL, OVFL )
+      ULP = DLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+      BIGNUM = ( ONE-ULP ) / SMLNUM
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      WORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         WORK( J ) = ZERO
+         DO 20 I = 1, J - 1
+            WORK( J ) = WORK( J ) + ABS( T( I, J ) )
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Index IP is used to specify the real or complex eigenvalue:
+*       IP = 0, real eigenvalue,
+*            1, first of conjugate complex pair: (wr,wi)
+*           -1, second of conjugate complex pair: (wr,wi)
+*
+      N2 = 2*N
+*
+      IF( RIGHTV ) THEN
+*
+*        Compute right eigenvectors.
+*
+         IP = 0
+         IS = M
+         DO 140 KI = N, 1, -1
+*
+            IF( IP.EQ.1 )
+     $         GO TO 130
+            IF( KI.EQ.1 )
+     $         GO TO 40
+            IF( T( KI, KI-1 ).EQ.ZERO )
+     $         GO TO 40
+            IP = -1
+*
+   40       CONTINUE
+            IF( SOMEV ) THEN
+               IF( IP.EQ.0 ) THEN
+                  IF( .NOT.SELECT( KI ) )
+     $               GO TO 130
+               ELSE
+                  IF( .NOT.SELECT( KI-1 ) )
+     $               GO TO 130
+               END IF
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI-1 ) ) )*
+     $              SQRT( ABS( T( KI-1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              Real right eigenvector
+*
+               WORK( KI+N ) = ONE
+*
+*              Form right-hand side
+*
+               DO 50 K = 1, KI - 1
+                  WORK( K+N ) = -T( K, KI )
+   50          CONTINUE
+*
+*              Solve the upper quasi-triangular system:
+*                 (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.
+*
+               JNXT = KI - 1
+               DO 60 J = KI - 1, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 60
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1 = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                     WORK( J+N ) = X( 1, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL DLALN2( .FALSE., 2, 1, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+N ), N, WR, ZERO, X, 2,
+     $                            SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(2,1) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 2, 1 ) = X( 2, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                     WORK( J-1+N ) = X( 1, 1 )
+                     WORK( J+N ) = X( 2, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+                  END IF
+   60          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS ), 1 )
+*
+                  II = IDAMAX( KI, VR( 1, IS ), 1 )
+                  REMAX = ONE / ABS( VR( II, IS ) )
+                  CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+                  DO 70 K = KI + 1, N
+                     VR( K, IS ) = ZERO
+   70             CONTINUE
+               ELSE
+                  IF( KI.GT.1 )
+     $               CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,
+     $                           WORK( 1+N ), 1, WORK( KI+N ),
+     $                           VR( 1, KI ), 1 )
+*
+                  II = IDAMAX( N, VR( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VR( II, KI ) )
+                  CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
+               END IF
+*
+            ELSE
+*
+*              Complex right eigenvector.
+*
+*              Initial solve
+*                [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.
+*                [ (T(KI,KI-1)   T(KI,KI)   )               ]
+*
+               IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THEN
+                  WORK( KI-1+N ) = ONE
+                  WORK( KI+N2 ) = WI / T( KI-1, KI )
+               ELSE
+                  WORK( KI-1+N ) = -WI / T( KI, KI-1 )
+                  WORK( KI+N2 ) = ONE
+               END IF
+               WORK( KI+N ) = ZERO
+               WORK( KI-1+N2 ) = ZERO
+*
+*              Form right-hand side
+*
+               DO 80 K = 1, KI - 2
+                  WORK( K+N ) = -WORK( KI-1+N )*T( K, KI-1 )
+                  WORK( K+N2 ) = -WORK( KI+N2 )*T( K, KI )
+   80          CONTINUE
+*
+*              Solve upper quasi-triangular system:
+*              (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)
+*
+               JNXT = KI - 2
+               DO 90 J = KI - 2, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 90
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1 = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR, WI,
+     $                            X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(1,2) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 1, 2 ) = X( 1, 2 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                        CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
+                     END IF
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+N2 ) = X( 1, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL DAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+N2 ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL DLALN2( .FALSE., 2, 2, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+N ), N, WR, WI, X, 2, SCALE,
+     $                            XNORM, IERR )
+*
+*                    Scale X to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           REC = ONE / XNORM
+                           X( 1, 1 ) = X( 1, 1 )*REC
+                           X( 1, 2 ) = X( 1, 2 )*REC
+                           X( 2, 1 ) = X( 2, 1 )*REC
+                           X( 2, 2 ) = X( 2, 2 )*REC
+                           SCALE = SCALE*REC
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                        CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
+                     END IF
+                     WORK( J-1+N ) = X( 1, 1 )
+                     WORK( J+N ) = X( 2, 1 )
+                     WORK( J-1+N2 ) = X( 1, 2 )
+                     WORK( J+N2 ) = X( 2, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL DAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+N2 ), 1 )
+                     CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+N2 ), 1 )
+                  END IF
+   90          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS-1 ), 1 )
+                  CALL DCOPY( KI, WORK( 1+N2 ), 1, VR( 1, IS ), 1 )
+*
+                  EMAX = ZERO
+                  DO 100 K = 1, KI
+                     EMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+
+     $                      ABS( VR( K, IS ) ) )
+  100             CONTINUE
+*
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )
+                  CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+                  DO 110 K = KI + 1, N
+                     VR( K, IS-1 ) = ZERO
+                     VR( K, IS ) = ZERO
+  110             CONTINUE
+*
+               ELSE
+*
+                  IF( KI.GT.2 ) THEN
+                     CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1+N ), 1, WORK( KI-1+N ),
+     $                           VR( 1, KI-1 ), 1 )
+                     CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1+N2 ), 1, WORK( KI+N2 ),
+     $                           VR( 1, KI ), 1 )
+                  ELSE
+                     CALL DSCAL( N, WORK( KI-1+N ), VR( 1, KI-1 ), 1 )
+                     CALL DSCAL( N, WORK( KI+N2 ), VR( 1, KI ), 1 )
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 120 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+
+     $                      ABS( VR( K, KI ) ) )
+  120             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )
+                  CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
+               END IF
+            END IF
+*
+            IS = IS - 1
+            IF( IP.NE.0 )
+     $         IS = IS - 1
+  130       CONTINUE
+            IF( IP.EQ.1 )
+     $         IP = 0
+            IF( IP.EQ.-1 )
+     $         IP = 1
+  140    CONTINUE
+      END IF
+*
+      IF( LEFTV ) THEN
+*
+*        Compute left eigenvectors.
+*
+         IP = 0
+         IS = 1
+         DO 260 KI = 1, N
+*
+            IF( IP.EQ.-1 )
+     $         GO TO 250
+            IF( KI.EQ.N )
+     $         GO TO 150
+            IF( T( KI+1, KI ).EQ.ZERO )
+     $         GO TO 150
+            IP = 1
+*
+  150       CONTINUE
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 250
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI+1 ) ) )*
+     $              SQRT( ABS( T( KI+1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              Real left eigenvector.
+*
+               WORK( KI+N ) = ONE
+*
+*              Form right-hand side
+*
+               DO 160 K = KI + 1, N
+                  WORK( K+N ) = -T( KI, K )
+  160          CONTINUE
+*
+*              Solve the quasi-triangular system:
+*                 (T(KI+1:N,KI+1:N) - WR)'*X = SCALE*WORK
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 1
+               DO 170 J = KI + 1, N
+                  IF( J.LT.JNXT )
+     $               GO TO 170
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             DDOT( J-KI-1, T( KI+1, J ), 1,
+     $                             WORK( KI+1+N ), 1 )
+*
+*                    Solve (T(J,J)-WR)'*X = WORK
+*
+                     CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                     WORK( J+N ) = X( 1, 1 )
+                     VMAX = MAX( ABS( WORK( J+N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             DDOT( J-KI-1, T( KI+1, J ), 1,
+     $                             WORK( KI+1+N ), 1 )
+*
+                     WORK( J+1+N ) = WORK( J+1+N ) -
+     $                               DDOT( J-KI-1, T( KI+1, J+1 ), 1,
+     $                               WORK( KI+1+N ), 1 )
+*
+*                    Solve
+*                      [T(J,J)-WR   T(J,J+1)     ]'* X = SCALE*( WORK1 )
+*                      [T(J+1,J)    T(J+1,J+1)-WR]             ( WORK2 )
+*
+                     CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+1+N ) = X( 2, 1 )
+*
+                     VMAX = MAX( ABS( WORK( J+N ) ),
+     $                      ABS( WORK( J+1+N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  170          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
+*
+                  II = IDAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+                  REMAX = ONE / ABS( VL( II, IS ) )
+                  CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+                  DO 180 K = 1, KI - 1
+                     VL( K, IS ) = ZERO
+  180             CONTINUE
+*
+               ELSE
+*
+                  IF( KI.LT.N )
+     $               CALL DGEMV( 'N', N, N-KI, ONE, VL( 1, KI+1 ), LDVL,
+     $                           WORK( KI+1+N ), 1, WORK( KI+N ),
+     $                           VL( 1, KI ), 1 )
+*
+                  II = IDAMAX( N, VL( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VL( II, KI ) )
+                  CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
+*
+               END IF
+*
+            ELSE
+*
+*              Complex left eigenvector.
+*
+*               Initial solve:
+*                 ((T(KI,KI)    T(KI,KI+1) )' - (WR - I* WI))*X = 0.
+*                 ((T(KI+1,KI) T(KI+1,KI+1))                )
+*
+               IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THEN
+                  WORK( KI+N ) = WI / T( KI, KI+1 )
+                  WORK( KI+1+N2 ) = ONE
+               ELSE
+                  WORK( KI+N ) = ONE
+                  WORK( KI+1+N2 ) = -WI / T( KI+1, KI )
+               END IF
+               WORK( KI+1+N ) = ZERO
+               WORK( KI+N2 ) = ZERO
+*
+*              Form right-hand side
+*
+               DO 190 K = KI + 2, N
+                  WORK( K+N ) = -WORK( KI+N )*T( KI, K )
+                  WORK( K+N2 ) = -WORK( KI+1+N2 )*T( KI+1, K )
+  190          CONTINUE
+*
+*              Solve complex quasi-triangular system:
+*              ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 2
+               DO 200 J = KI + 2, N
+                  IF( J.LT.JNXT )
+     $               GO TO 200
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when
+*                    forming the right-hand side elements.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                             WORK( KI+2+N ), 1 )
+                     WORK( J+N2 ) = WORK( J+N2 ) -
+     $                              DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                              WORK( KI+2+N2 ), 1 )
+*
+*                    Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2
+*
+                     CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                        CALL DSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )
+                     END IF
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+N2 ) = X( 1, 2 )
+                     VMAX = MAX( ABS( WORK( J+N ) ),
+     $                      ABS( WORK( J+N2 ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side elements.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                             WORK( KI+2+N ), 1 )
+*
+                     WORK( J+N2 ) = WORK( J+N2 ) -
+     $                              DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                              WORK( KI+2+N2 ), 1 )
+*
+                     WORK( J+1+N ) = WORK( J+1+N ) -
+     $                               DDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                               WORK( KI+2+N ), 1 )
+*
+                     WORK( J+1+N2 ) = WORK( J+1+N2 ) -
+     $                                DDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                                WORK( KI+2+N2 ), 1 )
+*
+*                    Solve 2-by-2 complex linear equation
+*                      ([T(j,j)   T(j,j+1)  ]'-(wr-i*wi)*I)*X = SCALE*B
+*                      ([T(j+1,j) T(j+1,j+1)]             )
+*
+                     CALL DLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                        CALL DSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )
+                     END IF
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+N2 ) = X( 1, 2 )
+                     WORK( J+1+N ) = X( 2, 1 )
+                     WORK( J+1+N2 ) = X( 2, 2 )
+                     VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),
+     $                      ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  200          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
+                  CALL DCOPY( N-KI+1, WORK( KI+N2 ), 1, VL( KI, IS+1 ),
+     $                        1 )
+*
+                  EMAX = ZERO
+                  DO 220 K = KI, N
+                     EMAX = MAX( EMAX, ABS( VL( K, IS ) )+
+     $                      ABS( VL( K, IS+1 ) ) )
+  220             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+                  CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )
+*
+                  DO 230 K = 1, KI - 1
+                     VL( K, IS ) = ZERO
+                     VL( K, IS+1 ) = ZERO
+  230             CONTINUE
+               ELSE
+                  IF( KI.LT.N-1 ) THEN
+                     CALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),
+     $                           LDVL, WORK( KI+2+N ), 1, WORK( KI+N ),
+     $                           VL( 1, KI ), 1 )
+                     CALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),
+     $                           LDVL, WORK( KI+2+N2 ), 1,
+     $                           WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
+                  ELSE
+                     CALL DSCAL( N, WORK( KI+N ), VL( 1, KI ), 1 )
+                     CALL DSCAL( N, WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 240 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VL( K, KI ) )+
+     $                      ABS( VL( K, KI+1 ) ) )
+  240             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
+                  CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )
+*
+               END IF
+*
+            END IF
+*
+            IS = IS + 1
+            IF( IP.NE.0 )
+     $         IS = IS + 1
+  250       CONTINUE
+            IF( IP.EQ.-1 )
+     $         IP = 0
+            IF( IP.EQ.1 )
+     $         IP = -1
+*
+  260    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of DTREVC
+*
+      END
diff --git a/libcruft/lapack/dtrexc.f b/libcruft/lapack/dtrexc.f
new file mode 100644
index 0000000..db9be75
--- /dev/null
+++ b/libcruft/lapack/dtrexc.f
@@ -0,0 +1,345 @@
+      SUBROUTINE DTREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, WORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ
+      INTEGER            IFST, ILST, INFO, LDQ, LDT, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   Q( LDQ, * ), T( LDT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTREXC reorders the real Schur factorization of a real matrix
+*  A = Q*T*Q**T, so that the diagonal block of T with row index IFST is
+*  moved to row ILST.
+*
+*  The real Schur form T is reordered by an orthogonal similarity
+*  transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors
+*  is updated by postmultiplying it with Z.
+*
+*  T must be in Schur canonical form (as returned by DHSEQR), that is,
+*  block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
+*  2-by-2 diagonal block has its diagonal elements equal and its
+*  off-diagonal elements of opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V':  update the matrix Q of Schur vectors;
+*          = 'N':  do not update Q.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) DOUBLE PRECISION array, dimension (LDT,N)
+*          On entry, the upper quasi-triangular matrix T, in Schur
+*          Schur canonical form.
+*          On exit, the reordered upper quasi-triangular matrix, again
+*          in Schur canonical form.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          orthogonal transformation matrix Z which reorders T.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= max(1,N).
+*
+*  IFST    (input/output) INTEGER
+*  ILST    (input/output) INTEGER
+*          Specify the reordering of the diagonal blocks of T.
+*          The block with row index IFST is moved to row ILST, by a
+*          sequence of transpositions between adjacent blocks.
+*          On exit, if IFST pointed on entry to the second row of a
+*          2-by-2 block, it is changed to point to the first row; ILST
+*          always points to the first row of the block in its final
+*          position (which may differ from its input value by +1 or -1).
+*          1 <= IFST <= N; 1 <= ILST <= N.
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          = 1:  two adjacent blocks were too close to swap (the problem
+*                is very ill-conditioned); T may have been partially
+*                reordered, and ILST points to the first row of the
+*                current position of the block being moved.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            WANTQ
+      INTEGER            HERE, NBF, NBL, NBNEXT
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAEXC, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input arguments.
+*
+      INFO = 0
+      WANTQ = LSAME( COMPQ, 'V' )
+      IF( .NOT.WANTQ .AND. .NOT.LSAME( COMPQ, 'N' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -6
+      ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THEN
+         INFO = -7
+      ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTREXC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Determine the first row of specified block
+*     and find out it is 1 by 1 or 2 by 2.
+*
+      IF( IFST.GT.1 ) THEN
+         IF( T( IFST, IFST-1 ).NE.ZERO )
+     $      IFST = IFST - 1
+      END IF
+      NBF = 1
+      IF( IFST.LT.N ) THEN
+         IF( T( IFST+1, IFST ).NE.ZERO )
+     $      NBF = 2
+      END IF
+*
+*     Determine the first row of the final block
+*     and find out it is 1 by 1 or 2 by 2.
+*
+      IF( ILST.GT.1 ) THEN
+         IF( T( ILST, ILST-1 ).NE.ZERO )
+     $      ILST = ILST - 1
+      END IF
+      NBL = 1
+      IF( ILST.LT.N ) THEN
+         IF( T( ILST+1, ILST ).NE.ZERO )
+     $      NBL = 2
+      END IF
+*
+      IF( IFST.EQ.ILST )
+     $   RETURN
+*
+      IF( IFST.LT.ILST ) THEN
+*
+*        Update ILST
+*
+         IF( NBF.EQ.2 .AND. NBL.EQ.1 )
+     $      ILST = ILST - 1
+         IF( NBF.EQ.1 .AND. NBL.EQ.2 )
+     $      ILST = ILST + 1
+*
+         HERE = IFST
+*
+   10    CONTINUE
+*
+*        Swap block with next one below
+*
+         IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN
+*
+*           Current block either 1 by 1 or 2 by 2
+*
+            NBNEXT = 1
+            IF( HERE+NBF+1.LE.N ) THEN
+               IF( T( HERE+NBF+1, HERE+NBF ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBF, NBNEXT,
+     $                   WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            HERE = HERE + NBNEXT
+*
+*           Test if 2 by 2 block breaks into two 1 by 1 blocks
+*
+            IF( NBF.EQ.2 ) THEN
+               IF( T( HERE+1, HERE ).EQ.ZERO )
+     $            NBF = 3
+            END IF
+*
+         ELSE
+*
+*           Current block consists of two 1 by 1 blocks each of which
+*           must be swapped individually
+*
+            NBNEXT = 1
+            IF( HERE+3.LE.N ) THEN
+               IF( T( HERE+3, HERE+2 ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, NBNEXT,
+     $                   WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            IF( NBNEXT.EQ.1 ) THEN
+*
+*              Swap two 1 by 1 blocks, no problems possible
+*
+               CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, NBNEXT,
+     $                      WORK, INFO )
+               HERE = HERE + 1
+            ELSE
+*
+*              Recompute NBNEXT in case 2 by 2 split
+*
+               IF( T( HERE+2, HERE+1 ).EQ.ZERO )
+     $            NBNEXT = 1
+               IF( NBNEXT.EQ.2 ) THEN
+*
+*                 2 by 2 Block did not split
+*
+                  CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1,
+     $                         NBNEXT, WORK, INFO )
+                  IF( INFO.NE.0 ) THEN
+                     ILST = HERE
+                     RETURN
+                  END IF
+                  HERE = HERE + 2
+               ELSE
+*
+*                 2 by 2 Block did split
+*
+                  CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,
+     $                         WORK, INFO )
+                  CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, 1,
+     $                         WORK, INFO )
+                  HERE = HERE + 2
+               END IF
+            END IF
+         END IF
+         IF( HERE.LT.ILST )
+     $      GO TO 10
+*
+      ELSE
+*
+         HERE = IFST
+   20    CONTINUE
+*
+*        Swap block with next one above
+*
+         IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN
+*
+*           Current block either 1 by 1 or 2 by 2
+*
+            NBNEXT = 1
+            IF( HERE.GE.3 ) THEN
+               IF( T( HERE-1, HERE-2 ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,
+     $                   NBF, WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            HERE = HERE - NBNEXT
+*
+*           Test if 2 by 2 block breaks into two 1 by 1 blocks
+*
+            IF( NBF.EQ.2 ) THEN
+               IF( T( HERE+1, HERE ).EQ.ZERO )
+     $            NBF = 3
+            END IF
+*
+         ELSE
+*
+*           Current block consists of two 1 by 1 blocks each of which
+*           must be swapped individually
+*
+            NBNEXT = 1
+            IF( HERE.GE.3 ) THEN
+               IF( T( HERE-1, HERE-2 ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,
+     $                   1, WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            IF( NBNEXT.EQ.1 ) THEN
+*
+*              Swap two 1 by 1 blocks, no problems possible
+*
+               CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBNEXT, 1,
+     $                      WORK, INFO )
+               HERE = HERE - 1
+            ELSE
+*
+*              Recompute NBNEXT in case 2 by 2 split
+*
+               IF( T( HERE, HERE-1 ).EQ.ZERO )
+     $            NBNEXT = 1
+               IF( NBNEXT.EQ.2 ) THEN
+*
+*                 2 by 2 Block did not split
+*
+                  CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 2, 1,
+     $                         WORK, INFO )
+                  IF( INFO.NE.0 ) THEN
+                     ILST = HERE
+                     RETURN
+                  END IF
+                  HERE = HERE - 2
+               ELSE
+*
+*                 2 by 2 Block did split
+*
+                  CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,
+     $                         WORK, INFO )
+                  CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 1, 1,
+     $                         WORK, INFO )
+                  HERE = HERE - 2
+               END IF
+            END IF
+         END IF
+         IF( HERE.GT.ILST )
+     $      GO TO 20
+      END IF
+      ILST = HERE
+*
+      RETURN
+*
+*     End of DTREXC
+*
+      END
diff --git a/libcruft/lapack/dtrsen.f b/libcruft/lapack/dtrsen.f
new file mode 100644
index 0000000..1d3ab03
--- /dev/null
+++ b/libcruft/lapack/dtrsen.f
@@ -0,0 +1,459 @@
+      SUBROUTINE DTRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI,
+     $                   M, S, SEP, WORK, LWORK, IWORK, LIWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, JOB
+      INTEGER            INFO, LDQ, LDT, LIWORK, LWORK, M, N
+      DOUBLE PRECISION   S, SEP
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   Q( LDQ, * ), T( LDT, * ), WI( * ), WORK( * ),
+     $                   WR( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRSEN reorders the real Schur factorization of a real matrix
+*  A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in
+*  the leading diagonal blocks of the upper quasi-triangular matrix T,
+*  and the leading columns of Q form an orthonormal basis of the
+*  corresponding right invariant subspace.
+*
+*  Optionally the routine computes the reciprocal condition numbers of
+*  the cluster of eigenvalues and/or the invariant subspace.
+*
+*  T must be in Schur canonical form (as returned by DHSEQR), that is,
+*  block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
+*  2-by-2 diagonal block has its diagonal elemnts equal and its
+*  off-diagonal elements of opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies whether condition numbers are required for the
+*          cluster of eigenvalues (S) or the invariant subspace (SEP):
+*          = 'N': none;
+*          = 'E': for eigenvalues only (S);
+*          = 'V': for invariant subspace only (SEP);
+*          = 'B': for both eigenvalues and invariant subspace (S and
+*                 SEP).
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V': update the matrix Q of Schur vectors;
+*          = 'N': do not update Q.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          SELECT specifies the eigenvalues in the selected cluster. To
+*          select a real eigenvalue w(j), SELECT(j) must be set to
+*          .TRUE.. To select a complex conjugate pair of eigenvalues
+*          w(j) and w(j+1), corresponding to a 2-by-2 diagonal block,
+*          either SELECT(j) or SELECT(j+1) or both must be set to
+*          .TRUE.; a complex conjugate pair of eigenvalues must be
+*          either both included in the cluster or both excluded.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) DOUBLE PRECISION array, dimension (LDT,N)
+*          On entry, the upper quasi-triangular matrix T, in Schur
+*          canonical form.
+*          On exit, T is overwritten by the reordered matrix T, again in
+*          Schur canonical form, with the selected eigenvalues in the
+*          leading diagonal blocks.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          orthogonal transformation matrix which reorders T; the
+*          leading M columns of Q form an orthonormal basis for the
+*          specified invariant subspace.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= 1; and if COMPQ = 'V', LDQ >= N.
+*
+*  WR      (output) DOUBLE PRECISION array, dimension (N)
+*  WI      (output) DOUBLE PRECISION array, dimension (N)
+*          The real and imaginary parts, respectively, of the reordered
+*          eigenvalues of T. The eigenvalues are stored in the same
+*          order as on the diagonal of T, with WR(i) = T(i,i) and, if
+*          T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0 and
+*          WI(i+1) = -WI(i). Note that if a complex eigenvalue is
+*          sufficiently ill-conditioned, then its value may differ
+*          significantly from its value before reordering.
+*
+*  M       (output) INTEGER
+*          The dimension of the specified invariant subspace.
+*          0 < = M <= N.
+*
+*  S       (output) DOUBLE PRECISION
+*          If JOB = 'E' or 'B', S is a lower bound on the reciprocal
+*          condition number for the selected cluster of eigenvalues.
+*          S cannot underestimate the true reciprocal condition number
+*          by more than a factor of sqrt(N). If M = 0 or N, S = 1.
+*          If JOB = 'N' or 'V', S is not referenced.
+*
+*  SEP     (output) DOUBLE PRECISION
+*          If JOB = 'V' or 'B', SEP is the estimated reciprocal
+*          condition number of the specified invariant subspace. If
+*          M = 0 or N, SEP = norm(T).
+*          If JOB = 'N' or 'E', SEP is not referenced.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If JOB = 'N', LWORK >= max(1,N);
+*          if JOB = 'E', LWORK >= max(1,M*(N-M));
+*          if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
+*          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
+*
+*  LIWORK  (input) INTEGER
+*          The dimension of the array IWORK.
+*          If JOB = 'N' or 'E', LIWORK >= 1;
+*          if JOB = 'V' or 'B', LIWORK >= max(1,M*(N-M)).
+*
+*          If LIWORK = -1, then a workspace query is assumed; the
+*          routine only calculates the optimal size of the IWORK array,
+*          returns this value as the first entry of the IWORK array, and
+*          no error message related to LIWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1: reordering of T failed because some eigenvalues are too
+*               close to separate (the problem is very ill-conditioned);
+*               T may have been partially reordered, and WR and WI
+*               contain the eigenvalues in the same order as in T; S and
+*               SEP (if requested) are set to zero.
+*
+*  Further Details
+*  ===============
+*
+*  DTRSEN first collects the selected eigenvalues by computing an
+*  orthogonal transformation Z to move them to the top left corner of T.
+*  In other words, the selected eigenvalues are the eigenvalues of T11
+*  in:
+*
+*                Z'*T*Z = ( T11 T12 ) n1
+*                         (  0  T22 ) n2
+*                            n1  n2
+*
+*  where N = n1+n2 and Z' means the transpose of Z. The first n1 columns
+*  of Z span the specified invariant subspace of T.
+*
+*  If T has been obtained from the real Schur factorization of a matrix
+*  A = Q*T*Q', then the reordered real Schur factorization of A is given
+*  by A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span
+*  the corresponding invariant subspace of A.
+*
+*  The reciprocal condition number of the average of the eigenvalues of
+*  T11 may be returned in S. S lies between 0 (very badly conditioned)
+*  and 1 (very well conditioned). It is computed as follows. First we
+*  compute R so that
+*
+*                         P = ( I  R ) n1
+*                             ( 0  0 ) n2
+*                               n1 n2
+*
+*  is the projector on the invariant subspace associated with T11.
+*  R is the solution of the Sylvester equation:
+*
+*                        T11*R - R*T22 = T12.
+*
+*  Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote
+*  the two-norm of M. Then S is computed as the lower bound
+*
+*                      (1 + F-norm(R)**2)**(-1/2)
+*
+*  on the reciprocal of 2-norm(P), the true reciprocal condition number.
+*  S cannot underestimate 1 / 2-norm(P) by more than a factor of
+*  sqrt(N).
+*
+*  An approximate error bound for the computed average of the
+*  eigenvalues of T11 is
+*
+*                         EPS * norm(T) / S
+*
+*  where EPS is the machine precision.
+*
+*  The reciprocal condition number of the right invariant subspace
+*  spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP.
+*  SEP is defined as the separation of T11 and T22:
+*
+*                     sep( T11, T22 ) = sigma-min( C )
+*
+*  where sigma-min(C) is the smallest singular value of the
+*  n1*n2-by-n1*n2 matrix
+*
+*     C  = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )
+*
+*  I(m) is an m by m identity matrix, and kprod denotes the Kronecker
+*  product. We estimate sigma-min(C) by the reciprocal of an estimate of
+*  the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C)
+*  cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2).
+*
+*  When SEP is small, small changes in T can cause large changes in
+*  the invariant subspace. An approximate bound on the maximum angular
+*  error in the computed right invariant subspace is
+*
+*                      EPS * norm(T) / SEP
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, PAIR, SWAP, WANTBH, WANTQ, WANTS,
+     $                   WANTSP
+      INTEGER            IERR, K, KASE, KK, KS, LIWMIN, LWMIN, N1, N2,
+     $                   NN
+      DOUBLE PRECISION   EST, RNORM, SCALE
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLANGE
+      EXTERNAL           LSAME, DLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLACN2, DLACPY, DTREXC, DTRSYL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      WANTBH = LSAME( JOB, 'B' )
+      WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
+      WANTSP = LSAME( JOB, 'V' ) .OR. WANTBH
+      WANTQ = LSAME( COMPQ, 'V' )
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.WANTS .AND. .NOT.WANTSP )
+     $     THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -8
+      ELSE
+*
+*        Set M to the dimension of the specified invariant subspace,
+*        and test LWORK and LIWORK.
+*
+         M = 0
+         PAIR = .FALSE.
+         DO 10 K = 1, N
+            IF( PAIR ) THEN
+               PAIR = .FALSE.
+            ELSE
+               IF( K.LT.N ) THEN
+                  IF( T( K+1, K ).EQ.ZERO ) THEN
+                     IF( SELECT( K ) )
+     $                  M = M + 1
+                  ELSE
+                     PAIR = .TRUE.
+                     IF( SELECT( K ) .OR. SELECT( K+1 ) )
+     $                  M = M + 2
+                  END IF
+               ELSE
+                  IF( SELECT( N ) )
+     $               M = M + 1
+               END IF
+            END IF
+   10    CONTINUE
+*
+         N1 = M
+         N2 = N - M
+         NN = N1*N2
+*
+         IF( WANTSP ) THEN
+            LWMIN = MAX( 1, 2*NN )
+            LIWMIN = MAX( 1, NN )
+         ELSE IF( LSAME( JOB, 'N' ) ) THEN
+            LWMIN = MAX( 1, N )
+            LIWMIN = 1
+         ELSE IF( LSAME( JOB, 'E' ) ) THEN
+            LWMIN = MAX( 1, NN )
+            LIWMIN = 1
+         END IF
+*
+         IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -15
+         ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -17
+         END IF
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         WORK( 1 ) = LWMIN
+         IWORK( 1 ) = LIWMIN
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTRSEN', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( M.EQ.N .OR. M.EQ.0 ) THEN
+         IF( WANTS )
+     $      S = ONE
+         IF( WANTSP )
+     $      SEP = DLANGE( '1', N, N, T, LDT, WORK )
+         GO TO 40
+      END IF
+*
+*     Collect the selected blocks at the top-left corner of T.
+*
+      KS = 0
+      PAIR = .FALSE.
+      DO 20 K = 1, N
+         IF( PAIR ) THEN
+            PAIR = .FALSE.
+         ELSE
+            SWAP = SELECT( K )
+            IF( K.LT.N ) THEN
+               IF( T( K+1, K ).NE.ZERO ) THEN
+                  PAIR = .TRUE.
+                  SWAP = SWAP .OR. SELECT( K+1 )
+               END IF
+            END IF
+            IF( SWAP ) THEN
+               KS = KS + 1
+*
+*              Swap the K-th block to position KS.
+*
+               IERR = 0
+               KK = K
+               IF( K.NE.KS )
+     $            CALL DTREXC( COMPQ, N, T, LDT, Q, LDQ, KK, KS, WORK,
+     $                         IERR )
+               IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN
+*
+*                 Blocks too close to swap: exit.
+*
+                  INFO = 1
+                  IF( WANTS )
+     $               S = ZERO
+                  IF( WANTSP )
+     $               SEP = ZERO
+                  GO TO 40
+               END IF
+               IF( PAIR )
+     $            KS = KS + 1
+            END IF
+         END IF
+   20 CONTINUE
+*
+      IF( WANTS ) THEN
+*
+*        Solve Sylvester equation for R:
+*
+*           T11*R - R*T22 = scale*T12
+*
+         CALL DLACPY( 'F', N1, N2, T( 1, N1+1 ), LDT, WORK, N1 )
+         CALL DTRSYL( 'N', 'N', -1, N1, N2, T, LDT, T( N1+1, N1+1 ),
+     $                LDT, WORK, N1, SCALE, IERR )
+*
+*        Estimate the reciprocal of the condition number of the cluster
+*        of eigenvalues.
+*
+         RNORM = DLANGE( 'F', N1, N2, WORK, N1, WORK )
+         IF( RNORM.EQ.ZERO ) THEN
+            S = ONE
+         ELSE
+            S = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*
+     $          SQRT( RNORM ) )
+         END IF
+      END IF
+*
+      IF( WANTSP ) THEN
+*
+*        Estimate sep(T11,T22).
+*
+         EST = ZERO
+         KASE = 0
+   30    CONTINUE
+         CALL DLACN2( NN, WORK( NN+1 ), WORK, IWORK, EST, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.1 ) THEN
+*
+*              Solve  T11*R - R*T22 = scale*X.
+*
+               CALL DTRSYL( 'N', 'N', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            ELSE
+*
+*              Solve  T11'*R - R*T22' = scale*X.
+*
+               CALL DTRSYL( 'T', 'T', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            END IF
+            GO TO 30
+         END IF
+*
+         SEP = SCALE / EST
+      END IF
+*
+   40 CONTINUE
+*
+*     Store the output eigenvalues in WR and WI.
+*
+      DO 50 K = 1, N
+         WR( K ) = T( K, K )
+         WI( K ) = ZERO
+   50 CONTINUE
+      DO 60 K = 1, N - 1
+         IF( T( K+1, K ).NE.ZERO ) THEN
+            WI( K ) = SQRT( ABS( T( K, K+1 ) ) )*
+     $                SQRT( ABS( T( K+1, K ) ) )
+            WI( K+1 ) = -WI( K )
+         END IF
+   60 CONTINUE
+*
+      WORK( 1 ) = LWMIN
+      IWORK( 1 ) = LIWMIN
+*
+      RETURN
+*
+*     End of DTRSEN
+*
+      END
diff --git a/libcruft/lapack/dtrsyl.f b/libcruft/lapack/dtrsyl.f
new file mode 100644
index 0000000..4c6c28e
--- /dev/null
+++ b/libcruft/lapack/dtrsyl.f
@@ -0,0 +1,913 @@
+      SUBROUTINE DTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
+     $                   LDC, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANA, TRANB
+      INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
+      DOUBLE PRECISION   SCALE
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRSYL solves the real Sylvester matrix equation:
+*
+*     op(A)*X + X*op(B) = scale*C or
+*     op(A)*X - X*op(B) = scale*C,
+*
+*  where op(A) = A or A**T, and  A and B are both upper quasi-
+*  triangular. A is M-by-M and B is N-by-N; the right hand side C and
+*  the solution X are M-by-N; and scale is an output scale factor, set
+*  <= 1 to avoid overflow in X.
+*
+*  A and B must be in Schur canonical form (as returned by DHSEQR), that
+*  is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
+*  each 2-by-2 diagonal block has its diagonal elements equal and its
+*  off-diagonal elements of opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  TRANA   (input) CHARACTER*1
+*          Specifies the option op(A):
+*          = 'N': op(A) = A    (No transpose)
+*          = 'T': op(A) = A**T (Transpose)
+*          = 'C': op(A) = A**H (Conjugate transpose = Transpose)
+*
+*  TRANB   (input) CHARACTER*1
+*          Specifies the option op(B):
+*          = 'N': op(B) = B    (No transpose)
+*          = 'T': op(B) = B**T (Transpose)
+*          = 'C': op(B) = B**H (Conjugate transpose = Transpose)
+*
+*  ISGN    (input) INTEGER
+*          Specifies the sign in the equation:
+*          = +1: solve op(A)*X + X*op(B) = scale*C
+*          = -1: solve op(A)*X - X*op(B) = scale*C
+*
+*  M       (input) INTEGER
+*          The order of the matrix A, and the number of rows in the
+*          matrices X and C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B, and the number of columns in the
+*          matrices X and C. N >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,M)
+*          The upper quasi-triangular matrix A, in Schur canonical form.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input) DOUBLE PRECISION array, dimension (LDB,N)
+*          The upper quasi-triangular matrix B, in Schur canonical form.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
+*          On entry, the M-by-N right hand side matrix C.
+*          On exit, C is overwritten by the solution matrix X.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M)
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scale factor, scale, set <= 1 to avoid overflow in X.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1: A and B have common or very close eigenvalues; perturbed
+*               values were used to solve the equation (but the matrices
+*               A and B are unchanged).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRNA, NOTRNB
+      INTEGER            IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXT
+      DOUBLE PRECISION   A11, BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
+     $                   SMLNUM, SUML, SUMR, XNORM
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 ), VEC( 2, 2 ), X( 2, 2 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DDOT, DLAMCH, DLANGE
+      EXTERNAL           LSAME, DDOT, DLAMCH, DLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, DLALN2, DLASY2, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test input parameters
+*
+      NOTRNA = LSAME( TRANA, 'N' )
+      NOTRNB = LSAME( TRANB, 'N' )
+*
+      INFO = 0
+      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND. .NOT.
+     $    LSAME( TRANA, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'T' ) .AND. .NOT.
+     $         LSAME( TRANB, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTRSYL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Set constants to control overflow
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM*DBLE( M*N ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+      SMIN = MAX( SMLNUM, EPS*DLANGE( 'M', M, M, A, LDA, DUM ),
+     $       EPS*DLANGE( 'M', N, N, B, LDB, DUM ) )
+*
+      SCALE = ONE
+      SGN = ISGN
+*
+      IF( NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-left corner column by column by
+*
+*         A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                  M                         L-1
+*        R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)].
+*                I=K+1                       J=1
+*
+*        Start column loop (index = L)
+*        L1 (L2) : column index of the first (first) row of X(K,L).
+*
+         LNEXT = 1
+         DO 60 L = 1, N
+            IF( L.LT.LNEXT )
+     $         GO TO 60
+            IF( L.EQ.N ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L+1, L ).NE.ZERO ) THEN
+                  L1 = L
+                  L2 = L + 1
+                  LNEXT = L + 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L + 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L).
+*
+            KNEXT = M
+            DO 50 K = M, 1, -1
+               IF( K.GT.KNEXT )
+     $            GO TO 50
+               IF( K.EQ.1 ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K, K-1 ).NE.ZERO ) THEN
+                     K1 = K - 1
+                     K2 = K
+                     KNEXT = K - 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K - 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 10 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   10                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 20 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   20                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L2 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 30 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   30                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLASY2( .FALSE., .FALSE., ISGN, 2, 2,
+     $                         A( K1, K1 ), LDA, B( L1, L1 ), LDB, VEC,
+     $                         2, SCALOC, X, 2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 40 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   40                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+   50       CONTINUE
+*
+   60    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A' *X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        upper-left corner column by column by
+*
+*          A(K,K)'*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                   K-1                        L-1
+*          R(K,L) = SUM [A(I,K)'*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)]
+*                   I=1                        J=1
+*
+*        Start column loop (index = L)
+*        L1 (L2): column index of the first (last) row of X(K,L)
+*
+         LNEXT = 1
+         DO 120 L = 1, N
+            IF( L.LT.LNEXT )
+     $         GO TO 120
+            IF( L.EQ.N ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L+1, L ).NE.ZERO ) THEN
+                  L1 = L
+                  L2 = L + 1
+                  LNEXT = L + 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L + 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L)
+*
+            KNEXT = 1
+            DO 110 K = 1, M
+               IF( K.LT.KNEXT )
+     $            GO TO 110
+               IF( K.EQ.M ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K+1, K ).NE.ZERO ) THEN
+                     K1 = K
+                     K2 = K + 1
+                     KNEXT = K + 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K + 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 70 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   70                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 80 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   80                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 90 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+   90                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
+                  SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLASY2( .TRUE., .FALSE., ISGN, 2, 2, A( K1, K1 ),
+     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
+     $                         2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 100 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  100                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+  110       CONTINUE
+  120    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A'*X + ISGN*X*B' = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        top-right corner column by column by
+*
+*           A(K,K)'*X(K,L) + ISGN*X(K,L)*B(L,L)' = C(K,L) - R(K,L)
+*
+*        Where
+*                     K-1                          N
+*            R(K,L) = SUM [A(I,K)'*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)'].
+*                     I=1                        J=L+1
+*
+*        Start column loop (index = L)
+*        L1 (L2): column index of the first (last) row of X(K,L)
+*
+         LNEXT = N
+         DO 180 L = N, 1, -1
+            IF( L.GT.LNEXT )
+     $         GO TO 180
+            IF( L.EQ.1 ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L, L-1 ).NE.ZERO ) THEN
+                  L1 = L - 1
+                  L2 = L
+                  LNEXT = L - 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L - 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L)
+*
+            KNEXT = 1
+            DO 170 K = 1, M
+               IF( K.LT.KNEXT )
+     $            GO TO 170
+               IF( K.EQ.M ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K+1, K ).NE.ZERO ) THEN
+                     K1 = K
+                     K2 = K + 1
+                     KNEXT = K + 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K + 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,
+     $                   B( L1, MIN( L1+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 130 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  130                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 140 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  140                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 150 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  150                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
+                  SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                   B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLASY2( .TRUE., .TRUE., ISGN, 2, 2, A( K1, K1 ),
+     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
+     $                         2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 160 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  160                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+  170       CONTINUE
+  180    CONTINUE
+*
+      ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B' = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-right corner column by column by
+*
+*            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L)' = C(K,L) - R(K,L)
+*
+*        Where
+*                      M                          N
+*            R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)'].
+*                    I=K+1                      J=L+1
+*
+*        Start column loop (index = L)
+*        L1 (L2): column index of the first (last) row of X(K,L)
+*
+         LNEXT = N
+         DO 240 L = N, 1, -1
+            IF( L.GT.LNEXT )
+     $         GO TO 240
+            IF( L.EQ.1 ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L, L-1 ).NE.ZERO ) THEN
+                  L1 = L - 1
+                  L2 = L
+                  LNEXT = L - 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L - 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L)
+*
+            KNEXT = M
+            DO 230 K = M, 1, -1
+               IF( K.GT.KNEXT )
+     $            GO TO 230
+               IF( K.EQ.1 ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K, K-1 ).NE.ZERO ) THEN
+                     K1 = K - 1
+                     K2 = K
+                     KNEXT = K - 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K - 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = DDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,
+     $                   B( L1, MIN( L1+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 190 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  190                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 200 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  200                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L2 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 210 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  210                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                   B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                   B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                   C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                   B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL DLASY2( .FALSE., .TRUE., ISGN, 2, 2, A( K1, K1 ),
+     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
+     $                         2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 220 J = 1, N
+                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
+  220                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+  230       CONTINUE
+  240    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of DTRSYL
+*
+      END
diff --git a/libcruft/lapack/dtrti2.f b/libcruft/lapack/dtrti2.f
new file mode 100644
index 0000000..e7ae764
--- /dev/null
+++ b/libcruft/lapack/dtrti2.f
@@ -0,0 +1,146 @@
+      SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRTI2 computes the inverse of a real upper or lower triangular
+*  matrix.
+*
+*  This is the Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading n by n upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J
+      DOUBLE PRECISION   AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, DTRMV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTRTI2', -INFO )
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Compute inverse of upper triangular matrix.
+*
+         DO 10 J = 1, N
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+*
+*           Compute elements 1:j-1 of j-th column.
+*
+            CALL DTRMV( 'Upper', 'No transpose', DIAG, J-1, A, LDA,
+     $                  A( 1, J ), 1 )
+            CALL DSCAL( J-1, AJJ, A( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Compute inverse of lower triangular matrix.
+*
+         DO 20 J = N, 1, -1
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+            IF( J.LT.N ) THEN
+*
+*              Compute elements j+1:n of j-th column.
+*
+               CALL DTRMV( 'Lower', 'No transpose', DIAG, N-J,
+     $                     A( J+1, J+1 ), LDA, A( J+1, J ), 1 )
+               CALL DSCAL( N-J, AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DTRTI2
+*
+      END
diff --git a/libcruft/lapack/dtrtri.f b/libcruft/lapack/dtrtri.f
new file mode 100644
index 0000000..375813c
--- /dev/null
+++ b/libcruft/lapack/dtrtri.f
@@ -0,0 +1,176 @@
+      SUBROUTINE DTRTRI( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRTRI computes the inverse of a real upper or lower triangular
+*  matrix A.
+*
+*  This is the Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, A(i,i) is exactly zero.  The triangular
+*               matrix is singular and its inverse can not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J, JB, NB, NN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DTRMM, DTRSM, DTRTI2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTRTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity if non-unit.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+         INFO = 0
+      END IF
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'DTRTRI', UPLO // DIAG, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL DTRTI2( UPLO, DIAG, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute inverse of upper triangular matrix
+*
+            DO 20 J = 1, N, NB
+               JB = MIN( NB, N-J+1 )
+*
+*              Compute rows 1:j-1 of current block column
+*
+               CALL DTRMM( 'Left', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, ONE, A, LDA, A( 1, J ), LDA )
+               CALL DTRSM( 'Right', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, -ONE, A( J, J ), LDA, A( 1, J ), LDA )
+*
+*              Compute inverse of current diagonal block
+*
+               CALL DTRTI2( 'Upper', DIAG, JB, A( J, J ), LDA, INFO )
+   20       CONTINUE
+         ELSE
+*
+*           Compute inverse of lower triangular matrix
+*
+            NN = ( ( N-1 ) / NB )*NB + 1
+            DO 30 J = NN, 1, -NB
+               JB = MIN( NB, N-J+1 )
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute rows j+jb:n of current block column
+*
+                  CALL DTRMM( 'Left', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, ONE, A( J+JB, J+JB ), LDA,
+     $                        A( J+JB, J ), LDA )
+                  CALL DTRSM( 'Right', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, -ONE, A( J, J ), LDA,
+     $                        A( J+JB, J ), LDA )
+               END IF
+*
+*              Compute inverse of current diagonal block
+*
+               CALL DTRTI2( 'Lower', DIAG, JB, A( J, J ), LDA, INFO )
+   30       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRTRI
+*
+      END
diff --git a/libcruft/lapack/dtrtrs.f b/libcruft/lapack/dtrtrs.f
new file mode 100644
index 0000000..139ea6d
--- /dev/null
+++ b/libcruft/lapack/dtrtrs.f
@@ -0,0 +1,147 @@
+      SUBROUTINE DTRTRS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, TRANS, UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTRTRS solves a triangular system of the form
+*
+*     A * X = B  or  A**T * X = B,
+*
+*  where A is a triangular matrix of order N, and B is an N-by-NRHS
+*  matrix.  A check is made to verify that A is nonsingular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose = Transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, if INFO = 0, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, the i-th diagonal element of A is zero,
+*               indicating that the matrix is singular and the solutions
+*               X have not been computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DTRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.
+     $         LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTRTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+      END IF
+      INFO = 0
+*
+*     Solve A * x = b  or  A' * x = b.
+*
+      CALL DTRSM( 'Left', UPLO, TRANS, DIAG, N, NRHS, ONE, A, LDA, B,
+     $            LDB )
+*
+      RETURN
+*
+*     End of DTRTRS
+*
+      END
diff --git a/libcruft/lapack/dtzrzf.f b/libcruft/lapack/dtzrzf.f
new file mode 100644
index 0000000..378eefe
--- /dev/null
+++ b/libcruft/lapack/dtzrzf.f
@@ -0,0 +1,244 @@
+      SUBROUTINE DTZRZF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DTZRZF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A
+*  to upper triangular form by means of orthogonal transformations.
+*
+*  The upper trapezoidal matrix A is factored as
+*
+*     A = ( R  0 ) * Z,
+*
+*  where Z is an N-by-N orthogonal matrix and R is an M-by-M upper
+*  triangular matrix.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= M.
+*
+*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements M+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          orthogonal matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) DOUBLE PRECISION array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an ( n - m ) element vector.
+*  tau and z( k ) are chosen to annihilate the elements of the kth row
+*  of X.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A, such that the elements of z( k ) are
+*  in  a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IWS, KI, KK, LDWORK, LWKOPT, M1, MU, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARZB, DLARZT, DLATRZ, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. M.EQ.N ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.
+*
+            NB = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )
+            LWKOPT = M*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+            INFO = -7
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTZRZF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 1
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.M ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'DGERQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.M ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'DGERQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.M .AND. NX.LT.M ) THEN
+*
+*        Use blocked code initially.
+*        The last kk rows are handled by the block method.
+*
+         M1 = MIN( M+1, N )
+         KI = ( ( M-NX-1 ) / NB )*NB
+         KK = MIN( M, KI+NB )
+*
+         DO 20 I = M - KK + KI + 1, M - KK + 1, -NB
+            IB = MIN( M-I+1, NB )
+*
+*           Compute the TZ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL DLATRZ( IB, N-I+1, N-M, A( I, I ), LDA, TAU( I ),
+     $                   WORK )
+            IF( I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL DLARZT( 'Backward', 'Rowwise', N-M, IB, A( I, M1 ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:i-1,i:n) from the right
+*
+               CALL DLARZB( 'Right', 'No transpose', 'Backward',
+     $                      'Rowwise', I-1, N-I+1, IB, N-M, A( I, M1 ),
+     $                      LDA, WORK, LDWORK, A( 1, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   20    CONTINUE
+         MU = I + NB - 1
+      ELSE
+         MU = M
+      END IF
+*
+*     Use unblocked code to factor the last or only block
+*
+      IF( MU.GT.0 )
+     $   CALL DLATRZ( MU, N, N-M, A, LDA, TAU, WORK )
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of DTZRZF
+*
+      END
diff --git a/libcruft/lapack/dzsum1.f b/libcruft/lapack/dzsum1.f
new file mode 100644
index 0000000..0b6c60e
--- /dev/null
+++ b/libcruft/lapack/dzsum1.f
@@ -0,0 +1,81 @@
+      DOUBLE PRECISION FUNCTION DZSUM1( N, CX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         CX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  DZSUM1 takes the sum of the absolute values of a complex
+*  vector and returns a double precision result.
+*
+*  Based on DZASUM from the Level 1 BLAS.
+*  The change is to use the 'genuine' absolute value.
+*
+*  Contributed by Nick Higham for use with ZLACON.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements in the vector CX.
+*
+*  CX      (input) COMPLEX*16 array, dimension (N)
+*          The vector whose elements will be summed.
+*
+*  INCX    (input) INTEGER
+*          The spacing between successive values of CX.  INCX > 0.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, NINCX
+      DOUBLE PRECISION   STEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+      DZSUM1 = 0.0D0
+      STEMP = 0.0D0
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 )
+     $   GO TO 20
+*
+*     CODE FOR INCREMENT NOT EQUAL TO 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1, NINCX, INCX
+*
+*        NEXT LINE MODIFIED.
+*
+         STEMP = STEMP + ABS( CX( I ) )
+   10 CONTINUE
+      DZSUM1 = STEMP
+      RETURN
+*
+*     CODE FOR INCREMENT EQUAL TO 1
+*
+   20 CONTINUE
+      DO 30 I = 1, N
+*
+*        NEXT LINE MODIFIED.
+*
+         STEMP = STEMP + ABS( CX( I ) )
+   30 CONTINUE
+      DZSUM1 = STEMP
+      RETURN
+*
+*     End of DZSUM1
+*
+      END
diff --git a/libcruft/lapack/icmax1.f b/libcruft/lapack/icmax1.f
new file mode 100644
index 0000000..ef36a0e
--- /dev/null
+++ b/libcruft/lapack/icmax1.f
@@ -0,0 +1,95 @@
+      INTEGER          FUNCTION ICMAX1( N, CX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            CX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ICMAX1 finds the index of the element whose real part has maximum
+*  absolute value.
+*
+*  Based on ICAMAX from Level 1 BLAS.
+*  The change is to use the 'genuine' absolute value.
+*
+*  Contributed by Nick Higham for use with CLACON.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements in the vector CX.
+*
+*  CX      (input) COMPLEX array, dimension (N)
+*          The vector whose elements will be summed.
+*
+*  INCX    (input) INTEGER
+*          The spacing between successive values of CX.  INCX >= 1.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IX
+      REAL               SMAX
+      COMPLEX            ZDUM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Statement Functions ..
+      REAL               CABS1
+*     ..
+*     .. Statement Function definitions ..
+*
+*     NEXT LINE IS THE ONLY MODIFICATION.
+      CABS1( ZDUM ) = ABS( ZDUM )
+*     ..
+*     .. Executable Statements ..
+*
+      ICMAX1 = 0
+      IF( N.LT.1 )
+     $   RETURN
+      ICMAX1 = 1
+      IF( N.EQ.1 )
+     $   RETURN
+      IF( INCX.EQ.1 )
+     $   GO TO 30
+*
+*     CODE FOR INCREMENT NOT EQUAL TO 1
+*
+      IX = 1
+      SMAX = CABS1( CX( 1 ) )
+      IX = IX + INCX
+      DO 20 I = 2, N
+         IF( CABS1( CX( IX ) ).LE.SMAX )
+     $      GO TO 10
+         ICMAX1 = I
+         SMAX = CABS1( CX( IX ) )
+   10    CONTINUE
+         IX = IX + INCX
+   20 CONTINUE
+      RETURN
+*
+*     CODE FOR INCREMENT EQUAL TO 1
+*
+   30 CONTINUE
+      SMAX = CABS1( CX( 1 ) )
+      DO 40 I = 2, N
+         IF( CABS1( CX( I ) ).LE.SMAX )
+     $      GO TO 40
+         ICMAX1 = I
+         SMAX = CABS1( CX( I ) )
+   40 CONTINUE
+      RETURN
+*
+*     End of ICMAX1
+*
+      END
diff --git a/libcruft/lapack/ieeeck.f b/libcruft/lapack/ieeeck.f
new file mode 100644
index 0000000..ac4aff8
--- /dev/null
+++ b/libcruft/lapack/ieeeck.f
@@ -0,0 +1,147 @@
+      INTEGER          FUNCTION IEEECK( ISPEC, ZERO, ONE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ISPEC
+      REAL               ONE, ZERO
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  IEEECK is called from the ILAENV to verify that Infinity and
+*  possibly NaN arithmetic is safe (i.e. will not trap).
+*
+*  Arguments
+*  =========
+*
+*  ISPEC   (input) INTEGER
+*          Specifies whether to test just for inifinity arithmetic
+*          or whether to test for infinity and NaN arithmetic.
+*          = 0: Verify infinity arithmetic only.
+*          = 1: Verify infinity and NaN arithmetic.
+*
+*  ZERO    (input) REAL
+*          Must contain the value 0.0
+*          This is passed to prevent the compiler from optimizing
+*          away this code.
+*
+*  ONE     (input) REAL
+*          Must contain the value 1.0
+*          This is passed to prevent the compiler from optimizing
+*          away this code.
+*
+*  RETURN VALUE:  INTEGER
+*          = 0:  Arithmetic failed to produce the correct answers
+*          = 1:  Arithmetic produced the correct answers
+*
+*     .. Local Scalars ..
+      REAL               NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF,
+     $                   NEGZRO, NEWZRO, POSINF
+*     ..
+*     .. Executable Statements ..
+      IEEECK = 1
+*
+      POSINF = ONE / ZERO
+      IF( POSINF.LE.ONE ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      NEGINF = -ONE / ZERO
+      IF( NEGINF.GE.ZERO ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      NEGZRO = ONE / ( NEGINF+ONE )
+      IF( NEGZRO.NE.ZERO ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      NEGINF = ONE / NEGZRO
+      IF( NEGINF.GE.ZERO ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      NEWZRO = NEGZRO + ZERO
+      IF( NEWZRO.NE.ZERO ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      POSINF = ONE / NEWZRO
+      IF( POSINF.LE.ONE ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      NEGINF = NEGINF*POSINF
+      IF( NEGINF.GE.ZERO ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      POSINF = POSINF*POSINF
+      IF( POSINF.LE.ONE ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+*
+*
+*
+*     Return if we were only asked to check infinity arithmetic
+*
+      IF( ISPEC.EQ.0 )
+     $   RETURN
+*
+      NAN1 = POSINF + NEGINF
+*
+      NAN2 = POSINF / NEGINF
+*
+      NAN3 = POSINF / POSINF
+*
+      NAN4 = POSINF*ZERO
+*
+      NAN5 = NEGINF*NEGZRO
+*
+      NAN6 = NAN5*0.0
+*
+      IF( NAN1.EQ.NAN1 ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      IF( NAN2.EQ.NAN2 ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      IF( NAN3.EQ.NAN3 ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      IF( NAN4.EQ.NAN4 ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      IF( NAN5.EQ.NAN5 ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      IF( NAN6.EQ.NAN6 ) THEN
+         IEEECK = 0
+         RETURN
+      END IF
+*
+      RETURN
+      END
diff --git a/libcruft/lapack/ilaenv.f b/libcruft/lapack/ilaenv.f
new file mode 100644
index 0000000..51147b6
--- /dev/null
+++ b/libcruft/lapack/ilaenv.f
@@ -0,0 +1,552 @@
+      INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 )
+*
+*  -- LAPACK auxiliary routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER*( * )    NAME, OPTS
+      INTEGER            ISPEC, N1, N2, N3, N4
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ILAENV is called from the LAPACK routines to choose problem-dependent
+*  parameters for the local environment.  See ISPEC for a description of
+*  the parameters.
+*
+*  ILAENV returns an INTEGER
+*  if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC
+*  if ILAENV < 0:  if ILAENV = -k, the k-th argument had an illegal value.
+*
+*  This version provides a set of parameters which should give good,
+*  but not optimal, performance on many of the currently available
+*  computers.  Users are encouraged to modify this subroutine to set
+*  the tuning parameters for their particular machine using the option
+*  and problem size information in the arguments.
+*
+*  This routine will not function correctly if it is converted to all
+*  lower case.  Converting it to all upper case is allowed.
+*
+*  Arguments
+*  =========
+*
+*  ISPEC   (input) INTEGER
+*          Specifies the parameter to be returned as the value of
+*          ILAENV.
+*          = 1: the optimal blocksize; if this value is 1, an unblocked
+*               algorithm will give the best performance.
+*          = 2: the minimum block size for which the block routine
+*               should be used; if the usable block size is less than
+*               this value, an unblocked routine should be used.
+*          = 3: the crossover point (in a block routine, for N less
+*               than this value, an unblocked routine should be used)
+*          = 4: the number of shifts, used in the nonsymmetric
+*               eigenvalue routines (DEPRECATED)
+*          = 5: the minimum column dimension for blocking to be used;
+*               rectangular blocks must have dimension at least k by m,
+*               where k is given by ILAENV(2,...) and m by ILAENV(5,...)
+*          = 6: the crossover point for the SVD (when reducing an m by n
+*               matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
+*               this value, a QR factorization is used first to reduce
+*               the matrix to a triangular form.)
+*          = 7: the number of processors
+*          = 8: the crossover point for the multishift QR method
+*               for nonsymmetric eigenvalue problems (DEPRECATED)
+*          = 9: maximum size of the subproblems at the bottom of the
+*               computation tree in the divide-and-conquer algorithm
+*               (used by xGELSD and xGESDD)
+*          =10: ieee NaN arithmetic can be trusted not to trap
+*          =11: infinity arithmetic can be trusted not to trap
+*          12 <= ISPEC <= 16:
+*               xHSEQR or one of its subroutines,
+*               see IPARMQ for detailed explanation
+*
+*  NAME    (input) CHARACTER*(*)
+*          The name of the calling subroutine, in either upper case or
+*          lower case.
+*
+*  OPTS    (input) CHARACTER*(*)
+*          The character options to the subroutine NAME, concatenated
+*          into a single character string.  For example, UPLO = 'U',
+*          TRANS = 'T', and DIAG = 'N' for a triangular routine would
+*          be specified as OPTS = 'UTN'.
+*
+*  N1      (input) INTEGER
+*  N2      (input) INTEGER
+*  N3      (input) INTEGER
+*  N4      (input) INTEGER
+*          Problem dimensions for the subroutine NAME; these may not all
+*          be required.
+*
+*  Further Details
+*  ===============
+*
+*  The following conventions have been used when calling ILAENV from the
+*  LAPACK routines:
+*  1)  OPTS is a concatenation of all of the character options to
+*      subroutine NAME, in the same order that they appear in the
+*      argument list for NAME, even if they are not used in determining
+*      the value of the parameter specified by ISPEC.
+*  2)  The problem dimensions N1, N2, N3, N4 are specified in the order
+*      that they appear in the argument list for NAME.  N1 is used
+*      first, N2 second, and so on, and unused problem dimensions are
+*      passed a value of -1.
+*  3)  The parameter value returned by ILAENV is checked for validity in
+*      the calling subroutine.  For example, ILAENV is used to retrieve
+*      the optimal blocksize for STRTRI as follows:
+*
+*      NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
+*      IF( NB.LE.1 ) NB = MAX( 1, N )
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IC, IZ, NB, NBMIN, NX
+      LOGICAL            CNAME, SNAME
+      CHARACTER          C1*1, C2*2, C4*2, C3*3, SUBNAM*6
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          CHAR, ICHAR, INT, MIN, REAL
+*     ..
+*     .. External Functions ..
+      INTEGER            IEEECK, IPARMQ
+      EXTERNAL           IEEECK, IPARMQ
+*     ..
+*     .. Executable Statements ..
+*
+      GO TO ( 10, 10, 10, 80, 90, 100, 110, 120,
+     $        130, 140, 150, 160, 160, 160, 160, 160 )ISPEC
+*
+*     Invalid value for ISPEC
+*
+      ILAENV = -1
+      RETURN
+*
+   10 CONTINUE
+*
+*     Convert NAME to upper case if the first character is lower case.
+*
+      ILAENV = 1
+      SUBNAM = NAME
+      IC = ICHAR( SUBNAM( 1: 1 ) )
+      IZ = ICHAR( 'Z' )
+      IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN
+*
+*        ASCII character set
+*
+         IF( IC.GE.97 .AND. IC.LE.122 ) THEN
+            SUBNAM( 1: 1 ) = CHAR( IC-32 )
+            DO 20 I = 2, 6
+               IC = ICHAR( SUBNAM( I: I ) )
+               IF( IC.GE.97 .AND. IC.LE.122 )
+     $            SUBNAM( I: I ) = CHAR( IC-32 )
+   20       CONTINUE
+         END IF
+*
+      ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN
+*
+*        EBCDIC character set
+*
+         IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.
+     $       ( IC.GE.145 .AND. IC.LE.153 ) .OR.
+     $       ( IC.GE.162 .AND. IC.LE.169 ) ) THEN
+            SUBNAM( 1: 1 ) = CHAR( IC+64 )
+            DO 30 I = 2, 6
+               IC = ICHAR( SUBNAM( I: I ) )
+               IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.
+     $             ( IC.GE.145 .AND. IC.LE.153 ) .OR.
+     $             ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I:
+     $             I ) = CHAR( IC+64 )
+   30       CONTINUE
+         END IF
+*
+      ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN
+*
+*        Prime machines:  ASCII+128
+*
+         IF( IC.GE.225 .AND. IC.LE.250 ) THEN
+            SUBNAM( 1: 1 ) = CHAR( IC-32 )
+            DO 40 I = 2, 6
+               IC = ICHAR( SUBNAM( I: I ) )
+               IF( IC.GE.225 .AND. IC.LE.250 )
+     $            SUBNAM( I: I ) = CHAR( IC-32 )
+   40       CONTINUE
+         END IF
+      END IF
+*
+      C1 = SUBNAM( 1: 1 )
+      SNAME = C1.EQ.'S' .OR. C1.EQ.'D'
+      CNAME = C1.EQ.'C' .OR. C1.EQ.'Z'
+      IF( .NOT.( CNAME .OR. SNAME ) )
+     $   RETURN
+      C2 = SUBNAM( 2: 3 )
+      C3 = SUBNAM( 4: 6 )
+      C4 = C3( 2: 3 )
+*
+      GO TO ( 50, 60, 70 )ISPEC
+*
+   50 CONTINUE
+*
+*     ISPEC = 1:  block size
+*
+*     In these examples, separate code is provided for setting NB for
+*     real and complex.  We assume that NB will take the same value in
+*     single or double precision.
+*
+      NB = 1
+*
+      IF( C2.EQ.'GE' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
+         ELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.
+     $            C3.EQ.'QLF' ) THEN
+            IF( SNAME ) THEN
+               NB = 32
+            ELSE
+               NB = 32
+            END IF
+         ELSE IF( C3.EQ.'HRD' ) THEN
+            IF( SNAME ) THEN
+               NB = 32
+            ELSE
+               NB = 32
+            END IF
+         ELSE IF( C3.EQ.'BRD' ) THEN
+            IF( SNAME ) THEN
+               NB = 32
+            ELSE
+               NB = 32
+            END IF
+         ELSE IF( C3.EQ.'TRI' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'PO' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'SY' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
+         ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN
+            NB = 32
+         ELSE IF( SNAME .AND. C3.EQ.'GST' ) THEN
+            NB = 64
+         END IF
+      ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            NB = 64
+         ELSE IF( C3.EQ.'TRD' ) THEN
+            NB = 32
+         ELSE IF( C3.EQ.'GST' ) THEN
+            NB = 64
+         END IF
+      ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
+         IF( C3( 1: 1 ).EQ.'G' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NB = 32
+            END IF
+         ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NB = 32
+            END IF
+         END IF
+      ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
+         IF( C3( 1: 1 ).EQ.'G' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NB = 32
+            END IF
+         ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NB = 32
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'GB' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            IF( SNAME ) THEN
+               IF( N4.LE.64 ) THEN
+                  NB = 1
+               ELSE
+                  NB = 32
+               END IF
+            ELSE
+               IF( N4.LE.64 ) THEN
+                  NB = 1
+               ELSE
+                  NB = 32
+               END IF
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'PB' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            IF( SNAME ) THEN
+               IF( N2.LE.64 ) THEN
+                  NB = 1
+               ELSE
+                  NB = 32
+               END IF
+            ELSE
+               IF( N2.LE.64 ) THEN
+                  NB = 1
+               ELSE
+                  NB = 32
+               END IF
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'TR' ) THEN
+         IF( C3.EQ.'TRI' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'LA' ) THEN
+         IF( C3.EQ.'UUM' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
+         END IF
+      ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN
+         IF( C3.EQ.'EBZ' ) THEN
+            NB = 1
+         END IF
+      END IF
+      ILAENV = NB
+      RETURN
+*
+   60 CONTINUE
+*
+*     ISPEC = 2:  minimum block size
+*
+      NBMIN = 2
+      IF( C2.EQ.'GE' ) THEN
+         IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.
+     $       'QLF' ) THEN
+            IF( SNAME ) THEN
+               NBMIN = 2
+            ELSE
+               NBMIN = 2
+            END IF
+         ELSE IF( C3.EQ.'HRD' ) THEN
+            IF( SNAME ) THEN
+               NBMIN = 2
+            ELSE
+               NBMIN = 2
+            END IF
+         ELSE IF( C3.EQ.'BRD' ) THEN
+            IF( SNAME ) THEN
+               NBMIN = 2
+            ELSE
+               NBMIN = 2
+            END IF
+         ELSE IF( C3.EQ.'TRI' ) THEN
+            IF( SNAME ) THEN
+               NBMIN = 2
+            ELSE
+               NBMIN = 2
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'SY' ) THEN
+         IF( C3.EQ.'TRF' ) THEN
+            IF( SNAME ) THEN
+               NBMIN = 8
+            ELSE
+               NBMIN = 8
+            END IF
+         ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN
+            NBMIN = 2
+         END IF
+      ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
+         IF( C3.EQ.'TRD' ) THEN
+            NBMIN = 2
+         END IF
+      ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
+         IF( C3( 1: 1 ).EQ.'G' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NBMIN = 2
+            END IF
+         ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NBMIN = 2
+            END IF
+         END IF
+      ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
+         IF( C3( 1: 1 ).EQ.'G' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NBMIN = 2
+            END IF
+         ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NBMIN = 2
+            END IF
+         END IF
+      END IF
+      ILAENV = NBMIN
+      RETURN
+*
+   70 CONTINUE
+*
+*     ISPEC = 3:  crossover point
+*
+      NX = 0
+      IF( C2.EQ.'GE' ) THEN
+         IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.
+     $       'QLF' ) THEN
+            IF( SNAME ) THEN
+               NX = 128
+            ELSE
+               NX = 128
+            END IF
+         ELSE IF( C3.EQ.'HRD' ) THEN
+            IF( SNAME ) THEN
+               NX = 128
+            ELSE
+               NX = 128
+            END IF
+         ELSE IF( C3.EQ.'BRD' ) THEN
+            IF( SNAME ) THEN
+               NX = 128
+            ELSE
+               NX = 128
+            END IF
+         END IF
+      ELSE IF( C2.EQ.'SY' ) THEN
+         IF( SNAME .AND. C3.EQ.'TRD' ) THEN
+            NX = 32
+         END IF
+      ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
+         IF( C3.EQ.'TRD' ) THEN
+            NX = 32
+         END IF
+      ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
+         IF( C3( 1: 1 ).EQ.'G' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NX = 128
+            END IF
+         END IF
+      ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
+         IF( C3( 1: 1 ).EQ.'G' ) THEN
+            IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
+     $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
+     $           THEN
+               NX = 128
+            END IF
+         END IF
+      END IF
+      ILAENV = NX
+      RETURN
+*
+   80 CONTINUE
+*
+*     ISPEC = 4:  number of shifts (used by xHSEQR)
+*
+      ILAENV = 6
+      RETURN
+*
+   90 CONTINUE
+*
+*     ISPEC = 5:  minimum column dimension (not used)
+*
+      ILAENV = 2
+      RETURN
+*
+  100 CONTINUE
+*
+*     ISPEC = 6:  crossover point for SVD (used by xGELSS and xGESVD)
+*
+      ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 )
+      RETURN
+*
+  110 CONTINUE
+*
+*     ISPEC = 7:  number of processors (not used)
+*
+      ILAENV = 1
+      RETURN
+*
+  120 CONTINUE
+*
+*     ISPEC = 8:  crossover point for multishift (used by xHSEQR)
+*
+      ILAENV = 50
+      RETURN
+*
+  130 CONTINUE
+*
+*     ISPEC = 9:  maximum size of the subproblems at the bottom of the
+*                 computation tree in the divide-and-conquer algorithm
+*                 (used by xGELSD and xGESDD)
+*
+      ILAENV = 25
+      RETURN
+*
+  140 CONTINUE
+*
+*     ISPEC = 10: ieee NaN arithmetic can be trusted not to trap
+*
+*     ILAENV = 0
+      ILAENV = 1
+      IF( ILAENV.EQ.1 ) THEN
+         ILAENV = IEEECK( 0, 0.0, 1.0 )
+      END IF
+      RETURN
+*
+  150 CONTINUE
+*
+*     ISPEC = 11: infinity arithmetic can be trusted not to trap
+*
+*     ILAENV = 0
+      ILAENV = 1
+      IF( ILAENV.EQ.1 ) THEN
+         ILAENV = IEEECK( 1, 0.0, 1.0 )
+      END IF
+      RETURN
+*
+  160 CONTINUE
+*
+*     12 <= ISPEC <= 16: xHSEQR or one of its subroutines. 
+*
+      ILAENV = IPARMQ( ISPEC, NAME, OPTS, N1, N2, N3, N4 )
+      RETURN
+*
+*     End of ILAENV
+*
+      END
diff --git a/libcruft/lapack/iparmq.f b/libcruft/lapack/iparmq.f
new file mode 100644
index 0000000..d9d0af3
--- /dev/null
+++ b/libcruft/lapack/iparmq.f
@@ -0,0 +1,253 @@
+      INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*     
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, ISPEC, LWORK, N
+      CHARACTER          NAME*( * ), OPTS*( * )
+*
+*  Purpose
+*  =======
+*
+*       This program sets problem and machine dependent parameters
+*       useful for xHSEQR and its subroutines. It is called whenever 
+*       ILAENV is called with 12 <= ISPEC <= 16
+*
+*  Arguments
+*  =========
+*
+*       ISPEC  (input) integer scalar
+*              ISPEC specifies which tunable parameter IPARMQ should
+*              return.
+*
+*              ISPEC=12: (INMIN)  Matrices of order nmin or less
+*                        are sent directly to xLAHQR, the implicit
+*                        double shift QR algorithm.  NMIN must be
+*                        at least 11.
+*
+*              ISPEC=13: (INWIN)  Size of the deflation window.
+*                        This is best set greater than or equal to
+*                        the number of simultaneous shifts NS.
+*                        Larger matrices benefit from larger deflation
+*                        windows.
+*
+*              ISPEC=14: (INIBL) Determines when to stop nibbling and
+*                        invest in an (expensive) multi-shift QR sweep.
+*                        If the aggressive early deflation subroutine
+*                        finds LD converged eigenvalues from an order
+*                        NW deflation window and LD.GT.(NW*NIBBLE)/100,
+*                        then the next QR sweep is skipped and early
+*                        deflation is applied immediately to the
+*                        remaining active diagonal block.  Setting
+*                        IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a
+*                        multi-shift QR sweep whenever early deflation
+*                        finds a converged eigenvalue.  Setting
+*                        IPARMQ(ISPEC=14) greater than or equal to 100
+*                        prevents TTQRE from skipping a multi-shift
+*                        QR sweep.
+*
+*              ISPEC=15: (NSHFTS) The number of simultaneous shifts in
+*                        a multi-shift QR iteration.
+*
+*              ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the
+*                        following meanings.
+*                        0:  During the multi-shift QR sweep,
+*                            xLAQR5 does not accumulate reflections and
+*                            does not use matrix-matrix multiply to
+*                            update the far-from-diagonal matrix
+*                            entries.
+*                        1:  During the multi-shift QR sweep,
+*                            xLAQR5 and/or xLAQRaccumulates reflections and uses
+*                            matrix-matrix multiply to update the
+*                            far-from-diagonal matrix entries.
+*                        2:  During the multi-shift QR sweep.
+*                            xLAQR5 accumulates reflections and takes
+*                            advantage of 2-by-2 block structure during
+*                            matrix-matrix multiplies.
+*                        (If xTRMM is slower than xGEMM, then
+*                        IPARMQ(ISPEC=16)=1 may be more efficient than
+*                        IPARMQ(ISPEC=16)=2 despite the greater level of
+*                        arithmetic work implied by the latter choice.)
+*
+*       NAME    (input) character string
+*               Name of the calling subroutine
+*
+*       OPTS    (input) character string
+*               This is a concatenation of the string arguments to
+*               TTQRE.
+*
+*       N       (input) integer scalar
+*               N is the order of the Hessenberg matrix H.
+*
+*       ILO     (input) INTEGER
+*       IHI     (input) INTEGER
+*               It is assumed that H is already upper triangular
+*               in rows and columns 1:ILO-1 and IHI+1:N.
+*
+*       LWORK   (input) integer scalar
+*               The amount of workspace available.
+*
+*  Further Details
+*  ===============
+*
+*       Little is known about how best to choose these parameters.
+*       It is possible to use different values of the parameters
+*       for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR.
+*
+*       It is probably best to choose different parameters for
+*       different matrices and different parameters at different
+*       times during the iteration, but this has not been
+*       implemented --- yet.
+*
+*
+*       The best choices of most of the parameters depend
+*       in an ill-understood way on the relative execution
+*       rate of xLAQR3 and xLAQR5 and on the nature of each
+*       particular eigenvalue problem.  Experiment may be the
+*       only practical way to determine which choices are most
+*       effective.
+*
+*       Following is a list of default values supplied by IPARMQ.
+*       These defaults may be adjusted in order to attain better
+*       performance in any particular computational environment.
+*
+*       IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point.
+*                        Default: 75. (Must be at least 11.)
+*
+*       IPARMQ(ISPEC=13) Recommended deflation window size.
+*                        This depends on ILO, IHI and NS, the
+*                        number of simultaneous shifts returned
+*                        by IPARMQ(ISPEC=15).  The default for
+*                        (IHI-ILO+1).LE.500 is NS.  The default
+*                        for (IHI-ILO+1).GT.500 is 3*NS/2.
+*
+*       IPARMQ(ISPEC=14) Nibble crossover point.  Default: 14.
+*
+*       IPARMQ(ISPEC=15) Number of simultaneous shifts, NS.
+*                        a multi-shift QR iteration.
+*
+*                        If IHI-ILO+1 is ...
+*
+*                        greater than      ...but less    ... the
+*                        or equal to ...      than        default is
+*
+*                                0               30       NS =   2+
+*                               30               60       NS =   4+
+*                               60              150       NS =  10
+*                              150              590       NS =  **
+*                              590             3000       NS =  64
+*                             3000             6000       NS = 128
+*                             6000             infinity   NS = 256
+*
+*                    (+)  By default matrices of this order are
+*                         passed to the implicit double shift routine
+*                         xLAHQR.  See IPARMQ(ISPEC=12) above.   These
+*                         values of NS are used only in case of a rare
+*                         xLAHQR failure.
+*
+*                    (**) The asterisks (**) indicate an ad-hoc
+*                         function increasing from 10 to 64.
+*
+*       IPARMQ(ISPEC=16) Select structured matrix multiply.
+*                        (See ISPEC=16 above for details.)
+*                        Default: 3.
+*
+*     ================================================================
+*     .. Parameters ..
+      INTEGER            INMIN, INWIN, INIBL, ISHFTS, IACC22
+      PARAMETER          ( INMIN = 12, INWIN = 13, INIBL = 14,
+     $                   ISHFTS = 15, IACC22 = 16 )
+      INTEGER            NMIN, K22MIN, KACMIN, NIBBLE, KNWSWP
+      PARAMETER          ( NMIN = 75, K22MIN = 14, KACMIN = 14,
+     $                   NIBBLE = 14, KNWSWP = 500 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            NH, NS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          LOG, MAX, MOD, NINT, REAL
+*     ..
+*     .. Executable Statements ..
+      IF( ( ISPEC.EQ.ISHFTS ) .OR. ( ISPEC.EQ.INWIN ) .OR.
+     $    ( ISPEC.EQ.IACC22 ) ) THEN
+*
+*        ==== Set the number simultaneous shifts ====
+*
+         NH = IHI - ILO + 1
+         NS = 2
+         IF( NH.GE.30 )
+     $      NS = 4
+         IF( NH.GE.60 )
+     $      NS = 10
+         IF( NH.GE.150 )
+     $      NS = MAX( 10, NH / NINT( LOG( REAL( NH ) ) / LOG( TWO ) ) )
+         IF( NH.GE.590 )
+     $      NS = 64
+         IF( NH.GE.3000 )
+     $      NS = 128
+         IF( NH.GE.6000 )
+     $      NS = 256
+         NS = MAX( 2, NS-MOD( NS, 2 ) )
+      END IF
+*
+      IF( ISPEC.EQ.INMIN ) THEN
+*
+*
+*        ===== Matrices of order smaller than NMIN get sent
+*        .     to xLAHQR, the classic double shift algorithm.
+*        .     This must be at least 11. ====
+*
+         IPARMQ = NMIN
+*
+      ELSE IF( ISPEC.EQ.INIBL ) THEN
+*
+*        ==== INIBL: skip a multi-shift qr iteration and
+*        .    whenever aggressive early deflation finds
+*        .    at least (NIBBLE*(window size)/100) deflations. ====
+*
+         IPARMQ = NIBBLE
+*
+      ELSE IF( ISPEC.EQ.ISHFTS ) THEN
+*
+*        ==== NSHFTS: The number of simultaneous shifts =====
+*
+         IPARMQ = NS
+*
+      ELSE IF( ISPEC.EQ.INWIN ) THEN
+*
+*        ==== NW: deflation window size.  ====
+*
+         IF( NH.LE.KNWSWP ) THEN
+            IPARMQ = NS
+         ELSE
+            IPARMQ = 3*NS / 2
+         END IF
+*
+      ELSE IF( ISPEC.EQ.IACC22 ) THEN
+*
+*        ==== IACC22: Whether to accumulate reflections
+*        .     before updating the far-from-diagonal elements
+*        .     and whether to use 2-by-2 block structure while
+*        .     doing it.  A small amount of work could be saved
+*        .     by making this choice dependent also upon the
+*        .     NH=IHI-ILO+1.
+*
+         IPARMQ = 0
+         IF( NS.GE.KACMIN )
+     $      IPARMQ = 1
+         IF( NS.GE.K22MIN )
+     $      IPARMQ = 2
+*
+      ELSE
+*        ===== invalid value of ispec =====
+         IPARMQ = -1
+*
+      END IF
+*
+*     ==== End of IPARMQ ====
+*
+      END
diff --git a/libcruft/lapack/izmax1.f b/libcruft/lapack/izmax1.f
new file mode 100644
index 0000000..7ebffee
--- /dev/null
+++ b/libcruft/lapack/izmax1.f
@@ -0,0 +1,95 @@
+      INTEGER          FUNCTION IZMAX1( N, CX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         CX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  IZMAX1 finds the index of the element whose real part has maximum
+*  absolute value.
+*
+*  Based on IZAMAX from Level 1 BLAS.
+*  The change is to use the 'genuine' absolute value.
+*
+*  Contributed by Nick Higham for use with ZLACON.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements in the vector CX.
+*
+*  CX      (input) COMPLEX*16 array, dimension (N)
+*          The vector whose elements will be summed.
+*
+*  INCX    (input) INTEGER
+*          The spacing between successive values of CX.  INCX >= 1.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IX
+      DOUBLE PRECISION   SMAX
+      COMPLEX*16         ZDUM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+*
+*     NEXT LINE IS THE ONLY MODIFICATION.
+      CABS1( ZDUM ) = ABS( ZDUM )
+*     ..
+*     .. Executable Statements ..
+*
+      IZMAX1 = 0
+      IF( N.LT.1 )
+     $   RETURN
+      IZMAX1 = 1
+      IF( N.EQ.1 )
+     $   RETURN
+      IF( INCX.EQ.1 )
+     $   GO TO 30
+*
+*     CODE FOR INCREMENT NOT EQUAL TO 1
+*
+      IX = 1
+      SMAX = CABS1( CX( 1 ) )
+      IX = IX + INCX
+      DO 20 I = 2, N
+         IF( CABS1( CX( IX ) ).LE.SMAX )
+     $      GO TO 10
+         IZMAX1 = I
+         SMAX = CABS1( CX( IX ) )
+   10    CONTINUE
+         IX = IX + INCX
+   20 CONTINUE
+      RETURN
+*
+*     CODE FOR INCREMENT EQUAL TO 1
+*
+   30 CONTINUE
+      SMAX = CABS1( CX( 1 ) )
+      DO 40 I = 2, N
+         IF( CABS1( CX( I ) ).LE.SMAX )
+     $      GO TO 40
+         IZMAX1 = I
+         SMAX = CABS1( CX( I ) )
+   40 CONTINUE
+      RETURN
+*
+*     End of IZMAX1
+*
+      END
diff --git a/libcruft/lapack/sbdsqr.f b/libcruft/lapack/sbdsqr.f
new file mode 100644
index 0000000..4033957
--- /dev/null
+++ b/libcruft/lapack/sbdsqr.f
@@ -0,0 +1,742 @@
+      SUBROUTINE SBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
+     $                   LDU, C, LDC, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), D( * ), E( * ), U( LDU, * ),
+     $                   VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SBDSQR computes the singular values and, optionally, the right and/or
+*  left singular vectors from the singular value decomposition (SVD) of
+*  a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
+*  zero-shift QR algorithm.  The SVD of B has the form
+*  
+*     B = Q * S * P**T
+*  
+*  where S is the diagonal matrix of singular values, Q is an orthogonal
+*  matrix of left singular vectors, and P is an orthogonal matrix of
+*  right singular vectors.  If left singular vectors are requested, this
+*  subroutine actually returns U*Q instead of Q, and, if right singular
+*  vectors are requested, this subroutine returns P**T*VT instead of
+*  P**T, for given real input matrices U and VT.  When U and VT are the
+*  orthogonal matrices that reduce a general matrix A to bidiagonal
+*  form:  A = U*B*VT, as computed by SGEBRD, then
+* 
+*     A = (U*Q) * S * (P**T*VT)
+* 
+*  is the SVD of A.  Optionally, the subroutine may also compute Q**T*C
+*  for a given real input matrix C.
+*
+*  See "Computing  Small Singular Values of Bidiagonal Matrices With
+*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
+*  LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,
+*  no. 5, pp. 873-912, Sept 1990) and
+*  "Accurate singular values and differential qd algorithms," by
+*  B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics
+*  Department, University of California at Berkeley, July 1992
+*  for a detailed description of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  B is upper bidiagonal;
+*          = 'L':  B is lower bidiagonal.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B.  N >= 0.
+*
+*  NCVT    (input) INTEGER
+*          The number of columns of the matrix VT. NCVT >= 0.
+*
+*  NRU     (input) INTEGER
+*          The number of rows of the matrix U. NRU >= 0.
+*
+*  NCC     (input) INTEGER
+*          The number of columns of the matrix C. NCC >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the bidiagonal matrix B.
+*          On exit, if INFO=0, the singular values of B in decreasing
+*          order.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the N-1 offdiagonal elements of the bidiagonal
+*          matrix B.
+*          On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E
+*          will contain the diagonal and superdiagonal elements of a
+*          bidiagonal matrix orthogonally equivalent to the one given
+*          as input.
+*
+*  VT      (input/output) REAL array, dimension (LDVT, NCVT)
+*          On entry, an N-by-NCVT matrix VT.
+*          On exit, VT is overwritten by P**T * VT.
+*          Not referenced if NCVT = 0.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.
+*          LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.
+*
+*  U       (input/output) REAL array, dimension (LDU, N)
+*          On entry, an NRU-by-N matrix U.
+*          On exit, U is overwritten by U * Q.
+*          Not referenced if NRU = 0.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= max(1,NRU).
+*
+*  C       (input/output) REAL array, dimension (LDC, NCC)
+*          On entry, an N-by-NCC matrix C.
+*          On exit, C is overwritten by Q**T * C.
+*          Not referenced if NCC = 0.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C.
+*          LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.
+*
+*  WORK    (workspace) REAL array, dimension (2*N)
+*          if NCVT = NRU = NCC = 0, (max(1, 4*N)) otherwise
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  If INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm did not converge; D and E contain the
+*                elements of a bidiagonal matrix which is orthogonally
+*                similar to the input matrix B;  if INFO = i, i
+*                elements of E have not converged to zero.
+*
+*  Internal Parameters
+*  ===================
+*
+*  TOLMUL  REAL, default = max(10,min(100,EPS**(-1/8)))
+*          TOLMUL controls the convergence criterion of the QR loop.
+*          If it is positive, TOLMUL*EPS is the desired relative
+*             precision in the computed singular values.
+*          If it is negative, abs(TOLMUL*EPS*sigma_max) is the
+*             desired absolute accuracy in the computed singular
+*             values (corresponds to relative accuracy
+*             abs(TOLMUL*EPS) in the largest singular value.
+*          abs(TOLMUL) should be between 1 and 1/EPS, and preferably
+*             between 10 (for fast convergence) and .1/EPS
+*             (for there to be some accuracy in the results).
+*          Default is to lose at either one eighth or 2 of the
+*             available decimal digits in each computed singular value
+*             (whichever is smaller).
+*
+*  MAXITR  INTEGER, default = 6
+*          MAXITR controls the maximum number of passes of the
+*          algorithm through its inner loop. The algorithms stops
+*          (and so fails to converge) if the number of passes
+*          through the inner loop exceeds MAXITR*N**2.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               NEGONE
+      PARAMETER          ( NEGONE = -1.0E0 )
+      REAL               HNDRTH
+      PARAMETER          ( HNDRTH = 0.01E0 )
+      REAL               TEN
+      PARAMETER          ( TEN = 10.0E0 )
+      REAL               HNDRD
+      PARAMETER          ( HNDRD = 100.0E0 )
+      REAL               MEIGTH
+      PARAMETER          ( MEIGTH = -0.125E0 )
+      INTEGER            MAXITR
+      PARAMETER          ( MAXITR = 6 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, ROTATE
+      INTEGER            I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
+     $                   NM12, NM13, OLDLL, OLDM
+      REAL               ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
+     $                   OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
+     $                   SINR, SLL, SMAX, SMIN, SMINL,  SMINOA,
+     $                   SN, THRESH, TOL, TOLMUL, UNFL
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH
+      EXTERNAL           LSAME, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARTG, SLAS2, SLASQ1, SLASR, SLASV2, SROT,
+     $                   SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      LOWER = LSAME( UPLO, 'L' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NCVT.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NCC.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
+     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
+         INFO = -9
+      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
+         INFO = -11
+      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
+     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SBDSQR', -INFO )
+         RETURN
+      END IF
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( N.EQ.1 )
+     $   GO TO 160
+*
+*     ROTATE is true if any singular vectors desired, false otherwise
+*
+      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
+*
+*     If no singular vectors desired, use qd algorithm
+*
+      IF( .NOT.ROTATE ) THEN
+         CALL SLASQ1( N, D, E, WORK, INFO )
+         RETURN
+      END IF
+*
+      NM1 = N - 1
+      NM12 = NM1 + NM1
+      NM13 = NM12 + NM1
+      IDIR = 0
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'Epsilon' )
+      UNFL = SLAMCH( 'Safe minimum' )
+*
+*     If matrix lower bidiagonal, rotate to be upper bidiagonal
+*     by applying Givens rotations on the left
+*
+      IF( LOWER ) THEN
+         DO 10 I = 1, N - 1
+            CALL SLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            WORK( I ) = CS
+            WORK( NM1+I ) = SN
+   10    CONTINUE
+*
+*        Update singular vectors if desired
+*
+         IF( NRU.GT.0 )
+     $      CALL SLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ), WORK( N ), U,
+     $                  LDU )
+         IF( NCC.GT.0 )
+     $      CALL SLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ), WORK( N ), C,
+     $                  LDC )
+      END IF
+*
+*     Compute singular values to relative accuracy TOL
+*     (By setting TOL to be negative, algorithm will compute
+*     singular values to absolute accuracy ABS(TOL)*norm(input matrix))
+*
+      TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
+      TOL = TOLMUL*EPS
+*
+*     Compute approximate maximum, minimum singular values
+*
+      SMAX = ZERO
+      DO 20 I = 1, N
+         SMAX = MAX( SMAX, ABS( D( I ) ) )
+   20 CONTINUE
+      DO 30 I = 1, N - 1
+         SMAX = MAX( SMAX, ABS( E( I ) ) )
+   30 CONTINUE
+      SMINL = ZERO
+      IF( TOL.GE.ZERO ) THEN
+*
+*        Relative accuracy desired
+*
+         SMINOA = ABS( D( 1 ) )
+         IF( SMINOA.EQ.ZERO )
+     $      GO TO 50
+         MU = SMINOA
+         DO 40 I = 2, N
+            MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
+            SMINOA = MIN( SMINOA, MU )
+            IF( SMINOA.EQ.ZERO )
+     $         GO TO 50
+   40    CONTINUE
+   50    CONTINUE
+         SMINOA = SMINOA / SQRT( REAL( N ) )
+         THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
+      ELSE
+*
+*        Absolute accuracy desired
+*
+         THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
+      END IF
+*
+*     Prepare for main iteration loop for the singular values
+*     (MAXIT is the maximum number of passes through the inner
+*     loop permitted before nonconvergence signalled.)
+*
+      MAXIT = MAXITR*N*N
+      ITER = 0
+      OLDLL = -1
+      OLDM = -1
+*
+*     M points to last element of unconverged part of matrix
+*
+      M = N
+*
+*     Begin main iteration loop
+*
+   60 CONTINUE
+*
+*     Check for convergence or exceeding iteration count
+*
+      IF( M.LE.1 )
+     $   GO TO 160
+      IF( ITER.GT.MAXIT )
+     $   GO TO 200
+*
+*     Find diagonal block of matrix to work on
+*
+      IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
+     $   D( M ) = ZERO
+      SMAX = ABS( D( M ) )
+      SMIN = SMAX
+      DO 70 LLL = 1, M - 1
+         LL = M - LLL
+         ABSS = ABS( D( LL ) )
+         ABSE = ABS( E( LL ) )
+         IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
+     $      D( LL ) = ZERO
+         IF( ABSE.LE.THRESH )
+     $      GO TO 80
+         SMIN = MIN( SMIN, ABSS )
+         SMAX = MAX( SMAX, ABSS, ABSE )
+   70 CONTINUE
+      LL = 0
+      GO TO 90
+   80 CONTINUE
+      E( LL ) = ZERO
+*
+*     Matrix splits since E(LL) = 0
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        Convergence of bottom singular value, return to top of loop
+*
+         M = M - 1
+         GO TO 60
+      END IF
+   90 CONTINUE
+      LL = LL + 1
+*
+*     E(LL) through E(M-1) are nonzero, E(LL-1) is zero
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        2 by 2 block, handle separately
+*
+         CALL SLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
+     $                COSR, SINL, COSL )
+         D( M-1 ) = SIGMX
+         E( M-1 ) = ZERO
+         D( M ) = SIGMN
+*
+*        Compute singular vectors, if desired
+*
+         IF( NCVT.GT.0 )
+     $      CALL SROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, COSR,
+     $                 SINR )
+         IF( NRU.GT.0 )
+     $      CALL SROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
+         IF( NCC.GT.0 )
+     $      CALL SROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
+     $                 SINL )
+         M = M - 2
+         GO TO 60
+      END IF
+*
+*     If working on new submatrix, choose shift direction
+*     (from larger end diagonal element towards smaller)
+*
+      IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
+         IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
+*
+*           Chase bulge from top (big end) to bottom (small end)
+*
+            IDIR = 1
+         ELSE
+*
+*           Chase bulge from bottom (big end) to top (small end)
+*
+            IDIR = 2
+         END IF
+      END IF
+*
+*     Apply convergence tests
+*
+      IF( IDIR.EQ.1 ) THEN
+*
+*        Run convergence test in forward direction
+*        First apply standard test to bottom of matrix
+*
+         IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
+            E( M-1 ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion forward
+*
+            MU = ABS( D( LL ) )
+            SMINL = MU
+            DO 100 LLL = LL, M - 1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  100       CONTINUE
+         END IF
+*
+      ELSE
+*
+*        Run convergence test in backward direction
+*        First apply standard test to top of matrix
+*
+         IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
+            E( LL ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion backward
+*
+            MU = ABS( D( M ) )
+            SMINL = MU
+            DO 110 LLL = M - 1, LL, -1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  110       CONTINUE
+         END IF
+      END IF
+      OLDLL = LL
+      OLDM = M
+*
+*     Compute shift.  First, test if shifting would ruin relative
+*     accuracy, and if so set the shift to zero.
+*
+      IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
+     $    MAX( EPS, HNDRTH*TOL ) ) THEN
+*
+*        Use a zero shift to avoid loss of relative accuracy
+*
+         SHIFT = ZERO
+      ELSE
+*
+*        Compute the shift from 2-by-2 block at end of matrix
+*
+         IF( IDIR.EQ.1 ) THEN
+            SLL = ABS( D( LL ) )
+            CALL SLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
+         ELSE
+            SLL = ABS( D( M ) )
+            CALL SLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
+         END IF
+*
+*        Test if shift negligible, and if so set to zero
+*
+         IF( SLL.GT.ZERO ) THEN
+            IF( ( SHIFT / SLL )**2.LT.EPS )
+     $         SHIFT = ZERO
+         END IF
+      END IF
+*
+*     Increment iteration count
+*
+      ITER = ITER + M - LL
+*
+*     If SHIFT = 0, do simplified QR iteration
+*
+      IF( SHIFT.EQ.ZERO ) THEN
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 120 I = LL, M - 1
+               CALL SLARTG( D( I )*CS, E( I ), CS, SN, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = OLDSN*R
+               CALL SLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
+               WORK( I-LL+1 ) = CS
+               WORK( I-LL+1+NM1 ) = SN
+               WORK( I-LL+1+NM12 ) = OLDCS
+               WORK( I-LL+1+NM13 ) = OLDSN
+  120       CONTINUE
+            H = D( M )*CS
+            D( M ) = H*OLDCS
+            E( M-1 ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),
+     $                     WORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL SLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 130 I = M, LL + 1, -1
+               CALL SLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
+               IF( I.LT.M )
+     $            E( I ) = OLDSN*R
+               CALL SLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
+               WORK( I-LL ) = CS
+               WORK( I-LL+NM1 ) = -SN
+               WORK( I-LL+NM12 ) = OLDCS
+               WORK( I-LL+NM13 ) = -OLDSN
+  130       CONTINUE
+            H = D( LL )*CS
+            D( LL ) = H*OLDCS
+            E( LL ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL SLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),
+     $                     WORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),
+     $                     WORK( N ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+         END IF
+      ELSE
+*
+*        Use nonzero shift
+*
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( LL ) )-SHIFT )*
+     $          ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
+            G = E( LL )
+            DO 140 I = LL, M - 1
+               CALL SLARTG( F, G, COSR, SINR, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = R
+               F = COSR*D( I ) + SINR*E( I )
+               E( I ) = COSR*E( I ) - SINR*D( I )
+               G = SINR*D( I+1 )
+               D( I+1 ) = COSR*D( I+1 )
+               CALL SLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I ) + SINL*D( I+1 )
+               D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
+               IF( I.LT.M-1 ) THEN
+                  G = SINL*E( I+1 )
+                  E( I+1 ) = COSL*E( I+1 )
+               END IF
+               WORK( I-LL+1 ) = COSR
+               WORK( I-LL+1+NM1 ) = SINR
+               WORK( I-LL+1+NM12 ) = COSL
+               WORK( I-LL+1+NM13 ) = SINL
+  140       CONTINUE
+            E( M-1 ) = F
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),
+     $                     WORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL SLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
+     $          D( M ) )
+            G = E( M-1 )
+            DO 150 I = M, LL + 1, -1
+               CALL SLARTG( F, G, COSR, SINR, R )
+               IF( I.LT.M )
+     $            E( I ) = R
+               F = COSR*D( I ) + SINR*E( I-1 )
+               E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
+               G = SINR*D( I-1 )
+               D( I-1 ) = COSR*D( I-1 )
+               CALL SLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I-1 ) + SINL*D( I-1 )
+               D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
+               IF( I.GT.LL+1 ) THEN
+                  G = SINL*E( I-2 )
+                  E( I-2 ) = COSL*E( I-2 )
+               END IF
+               WORK( I-LL ) = COSR
+               WORK( I-LL+NM1 ) = -SINR
+               WORK( I-LL+NM12 ) = COSL
+               WORK( I-LL+NM13 ) = -SINL
+  150       CONTINUE
+            E( LL ) = F
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+*
+*           Update singular vectors if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),
+     $                     WORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL SLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),
+     $                     WORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL SLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),
+     $                     WORK( N ), C( LL, 1 ), LDC )
+         END IF
+      END IF
+*
+*     QR iteration finished, go back and check convergence
+*
+      GO TO 60
+*
+*     All singular values converged, so make them positive
+*
+  160 CONTINUE
+      DO 170 I = 1, N
+         IF( D( I ).LT.ZERO ) THEN
+            D( I ) = -D( I )
+*
+*           Change sign of singular vectors, if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL SSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
+         END IF
+  170 CONTINUE
+*
+*     Sort the singular values into decreasing order (insertion sort on
+*     singular values, but only one transposition per singular vector)
+*
+      DO 190 I = 1, N - 1
+*
+*        Scan for smallest D(I)
+*
+         ISUB = 1
+         SMIN = D( 1 )
+         DO 180 J = 2, N + 1 - I
+            IF( D( J ).LE.SMIN ) THEN
+               ISUB = J
+               SMIN = D( J )
+            END IF
+  180    CONTINUE
+         IF( ISUB.NE.N+1-I ) THEN
+*
+*           Swap singular values and vectors
+*
+            D( ISUB ) = D( N+1-I )
+            D( N+1-I ) = SMIN
+            IF( NCVT.GT.0 )
+     $         CALL SSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
+     $                     LDVT )
+            IF( NRU.GT.0 )
+     $         CALL SSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
+            IF( NCC.GT.0 )
+     $         CALL SSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
+         END IF
+  190 CONTINUE
+      GO TO 220
+*
+*     Maximum number of iterations exceeded, failure to converge
+*
+  200 CONTINUE
+      INFO = 0
+      DO 210 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  210 CONTINUE
+  220 CONTINUE
+      RETURN
+*
+*     End of SBDSQR
+*
+      END
diff --git a/libcruft/lapack/scsum1.f b/libcruft/lapack/scsum1.f
new file mode 100644
index 0000000..ac7ef36
--- /dev/null
+++ b/libcruft/lapack/scsum1.f
@@ -0,0 +1,81 @@
+      REAL             FUNCTION SCSUM1( N, CX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX            CX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SCSUM1 takes the sum of the absolute values of a complex
+*  vector and returns a single precision result.
+*
+*  Based on SCASUM from the Level 1 BLAS.
+*  The change is to use the 'genuine' absolute value.
+*
+*  Contributed by Nick Higham for use with CLACON.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements in the vector CX.
+*
+*  CX      (input) COMPLEX array, dimension (N)
+*          The vector whose elements will be summed.
+*
+*  INCX    (input) INTEGER
+*          The spacing between successive values of CX.  INCX > 0.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, NINCX
+      REAL               STEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+      SCSUM1 = 0.0E0
+      STEMP = 0.0E0
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 )
+     $   GO TO 20
+*
+*     CODE FOR INCREMENT NOT EQUAL TO 1
+*
+      NINCX = N*INCX
+      DO 10 I = 1, NINCX, INCX
+*
+*        NEXT LINE MODIFIED.
+*
+         STEMP = STEMP + ABS( CX( I ) )
+   10 CONTINUE
+      SCSUM1 = STEMP
+      RETURN
+*
+*     CODE FOR INCREMENT EQUAL TO 1
+*
+   20 CONTINUE
+      DO 30 I = 1, N
+*
+*        NEXT LINE MODIFIED.
+*
+         STEMP = STEMP + ABS( CX( I ) )
+   30 CONTINUE
+      SCSUM1 = STEMP
+      RETURN
+*
+*     End of SCSUM1
+*
+      END
diff --git a/libcruft/lapack/sgbcon.f b/libcruft/lapack/sgbcon.f
new file mode 100644
index 0000000..ae688a2
--- /dev/null
+++ b/libcruft/lapack/sgbcon.f
@@ -0,0 +1,226 @@
+      SUBROUTINE SGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,
+     $                   WORK, IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, KL, KU, LDAB, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * ), IWORK( * )
+      REAL               AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGBCON estimates the reciprocal of the condition number of a real
+*  general band matrix A, in either the 1-norm or the infinity-norm,
+*  using the LU factorization computed by SGBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input) REAL array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by SGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  ANORM   (input) REAL
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) REAL array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, J, JP, KASE, KASE1, KD, LM
+      REAL               AINVNM, SCALE, SMLNUM, T
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SDOT, SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SLACN2, SLATBS, SRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.2*KL+KU+1 ) THEN
+         INFO = -6
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KD = KL + KU + 1
+      LNOTI = KL.GT.0
+      KASE = 0
+   10 CONTINUE
+      CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            IF( LNOTI ) THEN
+               DO 20 J = 1, N - 1
+                  LM = MIN( KL, N-J )
+                  JP = IPIV( J )
+                  T = WORK( JP )
+                  IF( JP.NE.J ) THEN
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+                  CALL SAXPY( LM, -T, AB( KD+1, J ), 1, WORK( J+1 ), 1 )
+   20          CONTINUE
+            END IF
+*
+*           Multiply by inv(U).
+*
+            CALL SLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),
+     $                   INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL SLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,
+     $                   KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),
+     $                   INFO )
+*
+*           Multiply by inv(L').
+*
+            IF( LNOTI ) THEN
+               DO 30 J = N - 1, 1, -1
+                  LM = MIN( KL, N-J )
+                  WORK( J ) = WORK( J ) - SDOT( LM, AB( KD+1, J ), 1,
+     $                        WORK( J+1 ), 1 )
+                  JP = IPIV( J )
+                  IF( JP.NE.J ) THEN
+                     T = WORK( JP )
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+   30          CONTINUE
+            END IF
+         END IF
+*
+*        Divide X by 1/SCALE if doing so will not cause overflow.
+*
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = ISAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 40
+            CALL SRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of SGBCON
+*
+      END
diff --git a/libcruft/lapack/sgbtf2.f b/libcruft/lapack/sgbtf2.f
new file mode 100644
index 0000000..041b19d
--- /dev/null
+++ b/libcruft/lapack/sgbtf2.f
@@ -0,0 +1,202 @@
+      SUBROUTINE SGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGBTF2 computes an LU factorization of a real m-by-n band matrix A
+*  using partial pivoting with row interchanges.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) REAL array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U, because of fill-in resulting from the row
+*  interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, JP, JU, KM, KV
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      EXTERNAL           ISAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGER, SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in.
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Gaussian elimination with partial pivoting
+*
+*     Set fill-in elements in columns KU+2 to KV to zero.
+*
+      DO 20 J = KU + 2, MIN( KV, N )
+         DO 10 I = KV - J + 2, KL
+            AB( I, J ) = ZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     JU is the index of the last column affected by the current stage
+*     of the factorization.
+*
+      JU = 1
+*
+      DO 40 J = 1, MIN( M, N )
+*
+*        Set fill-in elements in column J+KV to zero.
+*
+         IF( J+KV.LE.N ) THEN
+            DO 30 I = 1, KL
+               AB( I, J+KV ) = ZERO
+   30       CONTINUE
+         END IF
+*
+*        Find pivot and test for singularity. KM is the number of
+*        subdiagonal elements in the current column.
+*
+         KM = MIN( KL, M-J )
+         JP = ISAMAX( KM+1, AB( KV+1, J ), 1 )
+         IPIV( J ) = JP + J - 1
+         IF( AB( KV+JP, J ).NE.ZERO ) THEN
+            JU = MAX( JU, MIN( J+KU+JP-1, N ) )
+*
+*           Apply interchange to columns J to JU.
+*
+            IF( JP.NE.1 )
+     $         CALL SSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1,
+     $                     AB( KV+1, J ), LDAB-1 )
+*
+            IF( KM.GT.0 ) THEN
+*
+*              Compute multipliers.
+*
+               CALL SSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 )
+*
+*              Update trailing submatrix within the band.
+*
+               IF( JU.GT.J )
+     $            CALL SGER( KM, JU-J, -ONE, AB( KV+2, J ), 1,
+     $                       AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ),
+     $                       LDAB-1 )
+            END IF
+         ELSE
+*
+*           If pivot is zero, set INFO to the index of the pivot
+*           unless a zero pivot has already been found.
+*
+            IF( INFO.EQ.0 )
+     $         INFO = J
+         END IF
+   40 CONTINUE
+      RETURN
+*
+*     End of SGBTF2
+*
+      END
diff --git a/libcruft/lapack/sgbtrf.f b/libcruft/lapack/sgbtrf.f
new file mode 100644
index 0000000..b33ad4d
--- /dev/null
+++ b/libcruft/lapack/sgbtrf.f
@@ -0,0 +1,441 @@
+      SUBROUTINE SGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGBTRF computes an LU factorization of a real m-by-n band matrix A
+*  using partial pivoting with row interchanges.
+*
+*  This is the blocked version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) REAL array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U because of fill-in resulting from the row interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 64, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP,
+     $                   JU, K2, KM, KV, NB, NW
+      REAL               TEMP
+*     ..
+*     .. Local Arrays ..
+      REAL               WORK13( LDWORK, NBMAX ),
+     $                   WORK31( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV, ISAMAX
+      EXTERNAL           ILAENV, ISAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGBTF2, SGEMM, SGER, SLASWP, SSCAL,
+     $                   SSWAP, STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'SGBTRF', ' ', M, N, KL, KU )
+*
+*     The block size must not exceed the limit set by the size of the
+*     local arrays WORK13 and WORK31.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KL ) THEN
+*
+*        Use unblocked code
+*
+         CALL SGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+*        Zero the superdiagonal elements of the work array WORK13
+*
+         DO 20 J = 1, NB
+            DO 10 I = 1, J - 1
+               WORK13( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Zero the subdiagonal elements of the work array WORK31
+*
+         DO 40 J = 1, NB
+            DO 30 I = J + 1, NB
+               WORK31( I, J ) = ZERO
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Gaussian elimination with partial pivoting
+*
+*        Set fill-in elements in columns KU+2 to KV to zero
+*
+         DO 60 J = KU + 2, MIN( KV, N )
+            DO 50 I = KV - J + 2, KL
+               AB( I, J ) = ZERO
+   50       CONTINUE
+   60    CONTINUE
+*
+*        JU is the index of the last column affected by the current
+*        stage of the factorization
+*
+         JU = 1
+*
+         DO 180 J = 1, MIN( M, N ), NB
+            JB = MIN( NB, MIN( M, N )-J+1 )
+*
+*           The active part of the matrix is partitioned
+*
+*              A11   A12   A13
+*              A21   A22   A23
+*              A31   A32   A33
+*
+*           Here A11, A21 and A31 denote the current block of JB columns
+*           which is about to be factorized. The number of rows in the
+*           partitioning are JB, I2, I3 respectively, and the numbers
+*           of columns are JB, J2, J3. The superdiagonal elements of A13
+*           and the subdiagonal elements of A31 lie outside the band.
+*
+            I2 = MIN( KL-JB, M-J-JB+1 )
+            I3 = MIN( JB, M-J-KL+1 )
+*
+*           J2 and J3 are computed after JU has been updated.
+*
+*           Factorize the current block of JB columns
+*
+            DO 80 JJ = J, J + JB - 1
+*
+*              Set fill-in elements in column JJ+KV to zero
+*
+               IF( JJ+KV.LE.N ) THEN
+                  DO 70 I = 1, KL
+                     AB( I, JJ+KV ) = ZERO
+   70             CONTINUE
+               END IF
+*
+*              Find pivot and test for singularity. KM is the number of
+*              subdiagonal elements in the current column.
+*
+               KM = MIN( KL, M-JJ )
+               JP = ISAMAX( KM+1, AB( KV+1, JJ ), 1 )
+               IPIV( JJ ) = JP + JJ - J
+               IF( AB( KV+JP, JJ ).NE.ZERO ) THEN
+                  JU = MAX( JU, MIN( JJ+KU+JP-1, N ) )
+                  IF( JP.NE.1 ) THEN
+*
+*                    Apply interchange to columns J to J+JB-1
+*
+                     IF( JP+JJ-1.LT.J+KL ) THEN
+*
+                        CALL SSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              AB( KV+JP+JJ-J, J ), LDAB-1 )
+                     ELSE
+*
+*                       The interchange affects columns J to JJ-1 of A31
+*                       which are stored in the work array WORK31
+*
+                        CALL SSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                        CALL SSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1,
+     $                              AB( KV+JP, JJ ), LDAB-1 )
+                     END IF
+                  END IF
+*
+*                 Compute multipliers
+*
+                  CALL SSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ),
+     $                        1 )
+*
+*                 Update trailing submatrix within the band and within
+*                 the current block. JM is the index of the last column
+*                 which needs to be updated.
+*
+                  JM = MIN( JU, J+JB-1 )
+                  IF( JM.GT.JJ )
+     $               CALL SGER( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1,
+     $                          AB( KV, JJ+1 ), LDAB-1,
+     $                          AB( KV+1, JJ+1 ), LDAB-1 )
+               ELSE
+*
+*                 If pivot is zero, set INFO to the index of the pivot
+*                 unless a zero pivot has already been found.
+*
+                  IF( INFO.EQ.0 )
+     $               INFO = JJ
+               END IF
+*
+*              Copy current column of A31 into the work array WORK31
+*
+               NW = MIN( JJ-J+1, I3 )
+               IF( NW.GT.0 )
+     $            CALL SCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1,
+     $                        WORK31( 1, JJ-J+1 ), 1 )
+   80       CONTINUE
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply the row interchanges to the other blocks.
+*
+               J2 = MIN( JU-J+1, KV ) - JB
+               J3 = MAX( 0, JU-J-KV+1 )
+*
+*              Use SLASWP to apply the row interchanges to A12, A22, and
+*              A32.
+*
+               CALL SLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB,
+     $                      IPIV( J ), 1 )
+*
+*              Adjust the pivot indices.
+*
+               DO 90 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+   90          CONTINUE
+*
+*              Apply the row interchanges to A13, A23, and A33
+*              columnwise.
+*
+               K2 = J - 1 + JB + J2
+               DO 110 I = 1, J3
+                  JJ = K2 + I
+                  DO 100 II = J + I - 1, J + JB - 1
+                     IP = IPIV( II )
+                     IF( IP.NE.II ) THEN
+                        TEMP = AB( KV+1+II-JJ, JJ )
+                        AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ )
+                        AB( KV+1+IP-JJ, JJ ) = TEMP
+                     END IF
+  100             CONTINUE
+  110          CONTINUE
+*
+*              Update the relevant part of the trailing submatrix
+*
+               IF( J2.GT.0 ) THEN
+*
+*                 Update A12
+*
+                  CALL STRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J2, ONE, AB( KV+1, J ), LDAB-1,
+     $                        AB( KV+1-JB, J+JB ), LDAB-1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A22
+*
+                     CALL SGEMM( 'No transpose', 'No transpose', I2, J2,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+1, J+JB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A32
+*
+                     CALL SGEMM( 'No transpose', 'No transpose', I3, J2,
+     $                           JB, -ONE, WORK31, LDWORK,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+KL+1-JB, J+JB ), LDAB-1 )
+                  END IF
+               END IF
+*
+               IF( J3.GT.0 ) THEN
+*
+*                 Copy the lower triangle of A13 into the work array
+*                 WORK13
+*
+                  DO 130 JJ = 1, J3
+                     DO 120 II = JJ, JB
+                        WORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 )
+  120                CONTINUE
+  130             CONTINUE
+*
+*                 Update A13 in the work array
+*
+                  CALL STRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J3, ONE, AB( KV+1, J ), LDAB-1,
+     $                        WORK13, LDWORK )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A23
+*
+                     CALL SGEMM( 'No transpose', 'No transpose', I2, J3,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           WORK13, LDWORK, ONE, AB( 1+JB, J+KV ),
+     $                           LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A33
+*
+                     CALL SGEMM( 'No transpose', 'No transpose', I3, J3,
+     $                           JB, -ONE, WORK31, LDWORK, WORK13,
+     $                           LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 )
+                  END IF
+*
+*                 Copy the lower triangle of A13 back into place
+*
+                  DO 150 JJ = 1, J3
+                     DO 140 II = JJ, JB
+                        AB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ )
+  140                CONTINUE
+  150             CONTINUE
+               END IF
+            ELSE
+*
+*              Adjust the pivot indices.
+*
+               DO 160 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+  160          CONTINUE
+            END IF
+*
+*           Partially undo the interchanges in the current block to
+*           restore the upper triangular form of A31 and copy the upper
+*           triangle of A31 back into place
+*
+            DO 170 JJ = J + JB - 1, J, -1
+               JP = IPIV( JJ ) - JJ + 1
+               IF( JP.NE.1 ) THEN
+*
+*                 Apply interchange to columns J to JJ-1
+*
+                  IF( JP+JJ-1.LT.J+KL ) THEN
+*
+*                    The interchange does not affect A31
+*
+                     CALL SSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           AB( KV+JP+JJ-J, J ), LDAB-1 )
+                  ELSE
+*
+*                    The interchange does affect A31
+*
+                     CALL SSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                  END IF
+               END IF
+*
+*              Copy the current column of A31 back into place
+*
+               NW = MIN( I3, JJ-J+1 )
+               IF( NW.GT.0 )
+     $            CALL SCOPY( NW, WORK31( 1, JJ-J+1 ), 1,
+     $                        AB( KV+KL+1-JJ+J, JJ ), 1 )
+  170       CONTINUE
+  180    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SGBTRF
+*
+      END
diff --git a/libcruft/lapack/sgbtrs.f b/libcruft/lapack/sgbtrs.f
new file mode 100644
index 0000000..e6ea0a8
--- /dev/null
+++ b/libcruft/lapack/sgbtrs.f
@@ -0,0 +1,186 @@
+      SUBROUTINE SGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, KL, KU, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGBTRS solves a system of linear equations
+*     A * X = B  or  A' * X = B
+*  with a general band matrix A using the LU factorization computed
+*  by SGBTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A'* X = B  (Transpose)
+*          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) REAL array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by SGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, NOTRAN
+      INTEGER            I, J, KD, L, LM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SGER, SSWAP, STBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      KD = KU + KL + 1
+      LNOTI = KL.GT.0
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve  A*X = B.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+*        L is represented as a product of permutations and unit lower
+*        triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1),
+*        where each transformation L(i) is a rank-one modification of
+*        the identity matrix.
+*
+         IF( LNOTI ) THEN
+            DO 10 J = 1, N - 1
+               LM = MIN( KL, N-J )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL SSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+               CALL SGER( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ),
+     $                    LDB, B( J+1, 1 ), LDB )
+   10       CONTINUE
+         END IF
+*
+         DO 20 I = 1, NRHS
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL STBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU,
+     $                  AB, LDAB, B( 1, I ), 1 )
+   20    CONTINUE
+*
+      ELSE
+*
+*        Solve A'*X = B.
+*
+         DO 30 I = 1, NRHS
+*
+*           Solve U'*X = B, overwriting B with X.
+*
+            CALL STBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB,
+     $                  LDAB, B( 1, I ), 1 )
+   30    CONTINUE
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         IF( LNOTI ) THEN
+            DO 40 J = N - 1, 1, -1
+               LM = MIN( KL, N-J )
+               CALL SGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ),
+     $                     LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL SSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+   40       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of SGBTRS
+*
+      END
diff --git a/libcruft/lapack/sgebak.f b/libcruft/lapack/sgebak.f
new file mode 100644
index 0000000..467e5a9
--- /dev/null
+++ b/libcruft/lapack/sgebak.f
@@ -0,0 +1,188 @@
+      SUBROUTINE SGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               V( LDV, * ), SCALE( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEBAK forms the right or left eigenvectors of a real general matrix
+*  by backward transformation on the computed eigenvectors of the
+*  balanced matrix output by SGEBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N', do nothing, return immediately;
+*          = 'P', do backward transformation for permutation only;
+*          = 'S', do backward transformation for scaling only;
+*          = 'B', do backward transformations for both permutation and
+*                 scaling.
+*          JOB must be the same as the argument JOB supplied to SGEBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by SGEBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  SCALE   (input) REAL array, dimension (N)
+*          Details of the permutation and scaling factors, as returned
+*          by SGEBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) REAL array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by SHSEIN or STREVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, II, K
+      REAL               S
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -7
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               S = SCALE( I )
+               CALL SSCAL( M, S, V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               S = ONE / SCALE( I )
+               CALL SSCAL( M, S, V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+*
+      END IF
+*
+*     Backward permutation
+*
+*     For  I = ILO-1 step -1 until 1,
+*              IHI+1 step 1 until N do --
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+         IF( RIGHTV ) THEN
+            DO 40 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 40
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL SSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 50 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 50
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 50
+               CALL SSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   50       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of SGEBAK
+*
+      END
diff --git a/libcruft/lapack/sgebal.f b/libcruft/lapack/sgebal.f
new file mode 100644
index 0000000..ba9fd17
--- /dev/null
+++ b/libcruft/lapack/sgebal.f
@@ -0,0 +1,322 @@
+      SUBROUTINE SGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), SCALE( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEBAL balances a general real matrix A.  This involves, first,
+*  permuting A by a similarity transformation to isolate eigenvalues
+*  in the first 1 to ILO-1 and last IHI+1 to N elements on the
+*  diagonal; and second, applying a diagonal similarity transformation
+*  to rows and columns ILO to IHI to make the rows and columns as
+*  close in norm as possible.  Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrix, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, SCALE(I) = 1.0
+*                  for i = 1,...,N;
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit,  A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  SCALE   (output) REAL array, dimension (N)
+*          Details of the permutations and scaling factors applied to
+*          A.  If P(j) is the index of the row and column interchanged
+*          with row and column j and D(j) is the scaling factor
+*          applied to row and column j, then
+*          SCALE(j) = P(j)    for j = 1,...,ILO-1
+*                   = D(j)    for j = ILO,...,IHI
+*                   = P(j)    for j = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The permutations consist of row and column interchanges which put
+*  the matrix in the form
+*
+*             ( T1   X   Y  )
+*     P A P = (  0   B   Z  )
+*             (  0   0   T2 )
+*
+*  where T1 and T2 are upper triangular matrices whose eigenvalues lie
+*  along the diagonal.  The column indices ILO and IHI mark the starting
+*  and ending columns of the submatrix B. Balancing consists of applying
+*  a diagonal similarity transformation inv(D) * B * D to make the
+*  1-norms of each row of B and its corresponding column nearly equal.
+*  The output matrix is
+*
+*     ( T1     X*D          Y    )
+*     (  0  inv(D)*B*D  inv(D)*Z ).
+*     (  0      0           T2   )
+*
+*  Information about the permutations P and the diagonal matrix D is
+*  returned in the vector SCALE.
+*
+*  This subroutine is based on the EISPACK routine BALANC.
+*
+*  Modified by Tzu-Yi Chen, Computer Science Division, University of
+*    California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      REAL               SCLFAC
+      PARAMETER          ( SCLFAC = 2.0E+0 )
+      REAL               FACTOR
+      PARAMETER          ( FACTOR = 0.95E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOCONV
+      INTEGER            I, ICA, IEXC, IRA, J, K, L, M
+      REAL               C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,
+     $                   SFMIN2
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEBAL', -INFO )
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+*
+      IF( N.EQ.0 )
+     $   GO TO 210
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         DO 10 I = 1, N
+            SCALE( I ) = ONE
+   10    CONTINUE
+         GO TO 210
+      END IF
+*
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 120
+*
+*     Permutation to isolate eigenvalues if possible
+*
+      GO TO 50
+*
+*     Row and column exchange.
+*
+   20 CONTINUE
+      SCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 30
+*
+      CALL SSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL SSWAP( N-K+1, A( J, K ), LDA, A( M, K ), LDA )
+*
+   30 CONTINUE
+      GO TO ( 40, 80 )IEXC
+*
+*     Search for rows isolating an eigenvalue and push them down.
+*
+   40 CONTINUE
+      IF( L.EQ.1 )
+     $   GO TO 210
+      L = L - 1
+*
+   50 CONTINUE
+      DO 70 J = L, 1, -1
+*
+         DO 60 I = 1, L
+            IF( I.EQ.J )
+     $         GO TO 60
+            IF( A( J, I ).NE.ZERO )
+     $         GO TO 70
+   60    CONTINUE
+*
+         M = L
+         IEXC = 1
+         GO TO 20
+   70 CONTINUE
+*
+      GO TO 90
+*
+*     Search for columns isolating an eigenvalue and push them left.
+*
+   80 CONTINUE
+      K = K + 1
+*
+   90 CONTINUE
+      DO 110 J = K, L
+*
+         DO 100 I = K, L
+            IF( I.EQ.J )
+     $         GO TO 100
+            IF( A( I, J ).NE.ZERO )
+     $         GO TO 110
+  100    CONTINUE
+*
+         M = K
+         IEXC = 2
+         GO TO 20
+  110 CONTINUE
+*
+  120 CONTINUE
+      DO 130 I = K, L
+         SCALE( I ) = ONE
+  130 CONTINUE
+*
+      IF( LSAME( JOB, 'P' ) )
+     $   GO TO 210
+*
+*     Balance the submatrix in rows K to L.
+*
+*     Iterative loop for norm reduction
+*
+      SFMIN1 = SLAMCH( 'S' ) / SLAMCH( 'P' )
+      SFMAX1 = ONE / SFMIN1
+      SFMIN2 = SFMIN1*SCLFAC
+      SFMAX2 = ONE / SFMIN2
+  140 CONTINUE
+      NOCONV = .FALSE.
+*
+      DO 200 I = K, L
+         C = ZERO
+         R = ZERO
+*
+         DO 150 J = K, L
+            IF( J.EQ.I )
+     $         GO TO 150
+            C = C + ABS( A( J, I ) )
+            R = R + ABS( A( I, J ) )
+  150    CONTINUE
+         ICA = ISAMAX( L, A( 1, I ), 1 )
+         CA = ABS( A( ICA, I ) )
+         IRA = ISAMAX( N-K+1, A( I, K ), LDA )
+         RA = ABS( A( I, IRA+K-1 ) )
+*
+*        Guard against zero C or R due to underflow.
+*
+         IF( C.EQ.ZERO .OR. R.EQ.ZERO )
+     $      GO TO 200
+         G = R / SCLFAC
+         F = ONE
+         S = C + R
+  160    CONTINUE
+         IF( C.GE.G .OR. MAX( F, C, CA ).GE.SFMAX2 .OR.
+     $       MIN( R, G, RA ).LE.SFMIN2 )GO TO 170
+         F = F*SCLFAC
+         C = C*SCLFAC
+         CA = CA*SCLFAC
+         R = R / SCLFAC
+         G = G / SCLFAC
+         RA = RA / SCLFAC
+         GO TO 160
+*
+  170    CONTINUE
+         G = C / SCLFAC
+  180    CONTINUE
+         IF( G.LT.R .OR. MAX( R, RA ).GE.SFMAX2 .OR.
+     $       MIN( F, C, G, CA ).LE.SFMIN2 )GO TO 190
+         F = F / SCLFAC
+         C = C / SCLFAC
+         G = G / SCLFAC
+         CA = CA / SCLFAC
+         R = R*SCLFAC
+         RA = RA*SCLFAC
+         GO TO 180
+*
+*        Now balance.
+*
+  190    CONTINUE
+         IF( ( C+R ).GE.FACTOR*S )
+     $      GO TO 200
+         IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THEN
+            IF( F*SCALE( I ).LE.SFMIN1 )
+     $         GO TO 200
+         END IF
+         IF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THEN
+            IF( SCALE( I ).GE.SFMAX1 / F )
+     $         GO TO 200
+         END IF
+         G = ONE / F
+         SCALE( I ) = SCALE( I )*F
+         NOCONV = .TRUE.
+*
+         CALL SSCAL( N-K+1, G, A( I, K ), LDA )
+         CALL SSCAL( L, F, A( 1, I ), 1 )
+*
+  200 CONTINUE
+*
+      IF( NOCONV )
+     $   GO TO 140
+*
+  210 CONTINUE
+      ILO = K
+      IHI = L
+*
+      RETURN
+*
+*     End of SGEBAL
+*
+      END
diff --git a/libcruft/lapack/sgebd2.f b/libcruft/lapack/sgebd2.f
new file mode 100644
index 0000000..7c46c16
--- /dev/null
+++ b/libcruft/lapack/sgebd2.f
@@ -0,0 +1,239 @@
+      SUBROUTINE SGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), D( * ), E( * ), TAUP( * ),
+     $                   TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEBD2 reduces a real general m by n matrix A to upper or lower
+*  bidiagonal form B by an orthogonal transformation: Q' * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the orthogonal matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the orthogonal matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) REAL array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) REAL array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix Q. See Further Details.
+*
+*  TAUP    (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix P. See Further Details.
+*
+*  WORK    (workspace) REAL array, dimension (max(M,N))
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit.
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);
+*  u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);
+*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'SGEBD2', -INFO )
+         RETURN
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, N
+*
+*           Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+            CALL SLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = A( I, I )
+            A( I, I ) = ONE
+*
+*           Apply H(i) to A(i:m,i+1:n) from the left
+*
+            IF( I.LT.N )
+     $         CALL SLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAUQ( I ),
+     $                     A( I, I+1 ), LDA, WORK )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector G(i) to annihilate
+*              A(i,i+2:n)
+*
+               CALL SLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),
+     $                      LDA, TAUP( I ) )
+               E( I ) = A( I, I+1 )
+               A( I, I+1 ) = ONE
+*
+*              Apply G(i) to A(i+1:m,i+1:n) from the right
+*
+               CALL SLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA,
+     $                     TAUP( I ), A( I+1, I+1 ), LDA, WORK )
+               A( I, I+1 ) = E( I )
+            ELSE
+               TAUP( I ) = ZERO
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, M
+*
+*           Generate elementary reflector G(i) to annihilate A(i,i+1:n)
+*
+            CALL SLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = A( I, I )
+            A( I, I ) = ONE
+*
+*           Apply G(i) to A(i+1:m,i:n) from the right
+*
+            IF( I.LT.M )
+     $         CALL SLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     TAUP( I ), A( I+1, I ), LDA, WORK )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.M ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:m,i)
+*
+               CALL SLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = A( I+1, I )
+               A( I+1, I ) = ONE
+*
+*              Apply H(i) to A(i+1:m,i+1:n) from the left
+*
+               CALL SLARF( 'Left', M-I, N-I, A( I+1, I ), 1, TAUQ( I ),
+     $                     A( I+1, I+1 ), LDA, WORK )
+               A( I+1, I ) = E( I )
+            ELSE
+               TAUQ( I ) = ZERO
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SGEBD2
+*
+      END
diff --git a/libcruft/lapack/sgebrd.f b/libcruft/lapack/sgebrd.f
new file mode 100644
index 0000000..a45aaba
--- /dev/null
+++ b/libcruft/lapack/sgebrd.f
@@ -0,0 +1,268 @@
+      SUBROUTINE SGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), D( * ), E( * ), TAUP( * ),
+     $                   TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEBRD reduces a general real M-by-N matrix A to upper or lower
+*  bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the orthogonal matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the orthogonal matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) REAL array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) REAL array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix Q. See Further Details.
+*
+*  TAUP    (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix P. See Further Details.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,M,N).
+*          For optimum performance LWORK >= (M+N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit 
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);
+*  u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors;
+*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);
+*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LDWRKX, LDWRKY, LWKOPT, MINMN, NB,
+     $                   NBMIN, NX
+      REAL               WS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEBD2, SGEMM, SLABRD, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, REAL
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MAX( 1, ILAENV( 1, 'SGEBRD', ' ', M, N, -1, -1 ) )
+      LWKOPT = ( M+N )*NB
+      WORK( 1 ) = REAL( LWKOPT )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'SGEBRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      MINMN = MIN( M, N )
+      IF( MINMN.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      WS = MAX( M, N )
+      LDWRKX = M
+      LDWRKY = N
+*
+      IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN
+*
+*        Set the crossover point NX.
+*
+         NX = MAX( NB, ILAENV( 3, 'SGEBRD', ' ', M, N, -1, -1 ) )
+*
+*        Determine when to switch from blocked to unblocked code.
+*
+         IF( NX.LT.MINMN ) THEN
+            WS = ( M+N )*NB
+            IF( LWORK.LT.WS ) THEN
+*
+*              Not enough work space for the optimal NB, consider using
+*              a smaller block size.
+*
+               NBMIN = ILAENV( 2, 'SGEBRD', ' ', M, N, -1, -1 )
+               IF( LWORK.GE.( M+N )*NBMIN ) THEN
+                  NB = LWORK / ( M+N )
+               ELSE
+                  NB = 1
+                  NX = MINMN
+               END IF
+            END IF
+         END IF
+      ELSE
+         NX = MINMN
+      END IF
+*
+      DO 30 I = 1, MINMN - NX, NB
+*
+*        Reduce rows and columns i:i+nb-1 to bidiagonal form and return
+*        the matrices X and Y which are needed to update the unreduced
+*        part of the matrix
+*
+         CALL SLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ),
+     $                TAUQ( I ), TAUP( I ), WORK, LDWRKX,
+     $                WORK( LDWRKX*NB+1 ), LDWRKY )
+*
+*        Update the trailing submatrix A(i+nb:m,i+nb:n), using an update
+*        of the form  A := A - V*Y' - X*U'
+*
+         CALL SGEMM( 'No transpose', 'Transpose', M-I-NB+1, N-I-NB+1,
+     $               NB, -ONE, A( I+NB, I ), LDA,
+     $               WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE,
+     $               A( I+NB, I+NB ), LDA )
+         CALL SGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1,
+     $               NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA,
+     $               ONE, A( I+NB, I+NB ), LDA )
+*
+*        Copy diagonal and off-diagonal elements of B back into A
+*
+         IF( M.GE.N ) THEN
+            DO 10 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J, J+1 ) = E( J )
+   10       CONTINUE
+         ELSE
+            DO 20 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J+1, J ) = E( J )
+   20       CONTINUE
+         END IF
+   30 CONTINUE
+*
+*     Use unblocked code to reduce the remainder of the matrix
+*
+      CALL SGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $             TAUQ( I ), TAUP( I ), WORK, IINFO )
+      WORK( 1 ) = WS
+      RETURN
+*
+*     End of SGEBRD
+*
+      END
diff --git a/libcruft/lapack/sgecon.f b/libcruft/lapack/sgecon.f
new file mode 100644
index 0000000..3cce165
--- /dev/null
+++ b/libcruft/lapack/sgecon.f
@@ -0,0 +1,185 @@
+      SUBROUTINE SGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, LDA, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGECON estimates the reciprocal of the condition number of a general
+*  real matrix A, in either the 1-norm or the infinity-norm, using
+*  the LU factorization computed by SGETRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by SGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) REAL
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) REAL array, dimension (4*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      REAL               AINVNM, SCALE, SL, SMLNUM, SU
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACN2, SLATRS, SRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGECON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KASE = 0
+   10 CONTINUE
+      CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            CALL SLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A,
+     $                   LDA, WORK, SL, WORK( 2*N+1 ), INFO )
+*
+*           Multiply by inv(U).
+*
+            CALL SLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SU, WORK( 3*N+1 ), INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL SLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,
+     $                   LDA, WORK, SU, WORK( 3*N+1 ), INFO )
+*
+*           Multiply by inv(L').
+*
+            CALL SLATRS( 'Lower', 'Transpose', 'Unit', NORMIN, N, A,
+     $                   LDA, WORK, SL, WORK( 2*N+1 ), INFO )
+         END IF
+*
+*        Divide X by 1/(SL*SU) if doing so will not cause overflow.
+*
+         SCALE = SL*SU
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = ISAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL SRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of SGECON
+*
+      END
diff --git a/libcruft/lapack/sgeesx.f b/libcruft/lapack/sgeesx.f
new file mode 100644
index 0000000..a6f7899
--- /dev/null
+++ b/libcruft/lapack/sgeesx.f
@@ -0,0 +1,527 @@
+      SUBROUTINE SGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,
+     $                   WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
+     $                   IWORK, LIWORK, BWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVS, SENSE, SORT
+      INTEGER            INFO, LDA, LDVS, LIWORK, LWORK, N, SDIM
+      REAL               RCONDE, RCONDV
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            BWORK( * )
+      INTEGER            IWORK( * )
+      REAL               A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
+     $                   WR( * )
+*     ..
+*     .. Function Arguments ..
+      LOGICAL            SELECT
+      EXTERNAL           SELECT
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEESX computes for an N-by-N real nonsymmetric matrix A, the
+*  eigenvalues, the real Schur form T, and, optionally, the matrix of
+*  Schur vectors Z.  This gives the Schur factorization A = Z*T*(Z**T).
+*
+*  Optionally, it also orders the eigenvalues on the diagonal of the
+*  real Schur form so that selected eigenvalues are at the top left;
+*  computes a reciprocal condition number for the average of the
+*  selected eigenvalues (RCONDE); and computes a reciprocal condition
+*  number for the right invariant subspace corresponding to the
+*  selected eigenvalues (RCONDV).  The leading columns of Z form an
+*  orthonormal basis for this invariant subspace.
+*
+*  For further explanation of the reciprocal condition numbers RCONDE
+*  and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where
+*  these quantities are called s and sep respectively).
+*
+*  A real matrix is in real Schur form if it is upper quasi-triangular
+*  with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in
+*  the form
+*            [  a  b  ]
+*            [  c  a  ]
+*
+*  where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
+*
+*  Arguments
+*  =========
+*
+*  JOBVS   (input) CHARACTER*1
+*          = 'N': Schur vectors are not computed;
+*          = 'V': Schur vectors are computed.
+*
+*  SORT    (input) CHARACTER*1
+*          Specifies whether or not to order the eigenvalues on the
+*          diagonal of the Schur form.
+*          = 'N': Eigenvalues are not ordered;
+*          = 'S': Eigenvalues are ordered (see SELECT).
+*
+*  SELECT  (external procedure) LOGICAL FUNCTION of two REAL arguments
+*          SELECT must be declared EXTERNAL in the calling subroutine.
+*          If SORT = 'S', SELECT is used to select eigenvalues to sort
+*          to the top left of the Schur form.
+*          If SORT = 'N', SELECT is not referenced.
+*          An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
+*          SELECT(WR(j),WI(j)) is true; i.e., if either one of a
+*          complex conjugate pair of eigenvalues is selected, then both
+*          are.  Note that a selected complex eigenvalue may no longer
+*          satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
+*          ordering may change the value of complex eigenvalues
+*          (especially if the eigenvalue is ill-conditioned); in this
+*          case INFO may be set to N+3 (see INFO below).
+*
+*  SENSE   (input) CHARACTER*1
+*          Determines which reciprocal condition numbers are computed.
+*          = 'N': None are computed;
+*          = 'E': Computed for average of selected eigenvalues only;
+*          = 'V': Computed for selected right invariant subspace only;
+*          = 'B': Computed for both.
+*          If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA, N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A is overwritten by its real Schur form T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  SDIM    (output) INTEGER
+*          If SORT = 'N', SDIM = 0.
+*          If SORT = 'S', SDIM = number of eigenvalues (after sorting)
+*                         for which SELECT is true. (Complex conjugate
+*                         pairs for which SELECT is true for either
+*                         eigenvalue count as 2.)
+*
+*  WR      (output) REAL array, dimension (N)
+*  WI      (output) REAL array, dimension (N)
+*          WR and WI contain the real and imaginary parts, respectively,
+*          of the computed eigenvalues, in the same order that they
+*          appear on the diagonal of the output Schur form T.  Complex
+*          conjugate pairs of eigenvalues appear consecutively with the
+*          eigenvalue having the positive imaginary part first.
+*
+*  VS      (output) REAL array, dimension (LDVS,N)
+*          If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
+*          vectors.
+*          If JOBVS = 'N', VS is not referenced.
+*
+*  LDVS    (input) INTEGER
+*          The leading dimension of the array VS.  LDVS >= 1, and if
+*          JOBVS = 'V', LDVS >= N.
+*
+*  RCONDE  (output) REAL
+*          If SENSE = 'E' or 'B', RCONDE contains the reciprocal
+*          condition number for the average of the selected eigenvalues.
+*          Not referenced if SENSE = 'N' or 'V'.
+*
+*  RCONDV  (output) REAL
+*          If SENSE = 'V' or 'B', RCONDV contains the reciprocal
+*          condition number for the selected right invariant subspace.
+*          Not referenced if SENSE = 'N' or 'E'.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,3*N).
+*          Also, if SENSE = 'E' or 'V' or 'B',
+*          LWORK >= N+2*SDIM*(N-SDIM), where SDIM is the number of
+*          selected eigenvalues computed by this routine.  Note that
+*          N+2*SDIM*(N-SDIM) <= N+N*N/2. Note also that an error is only
+*          returned if LWORK < max(1,3*N), but if SENSE = 'E' or 'V' or
+*          'B' this may not be large enough.
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates upper bounds on the optimal sizes of the
+*          arrays WORK and IWORK, returns these values as the first
+*          entries of the WORK and IWORK arrays, and no error messages
+*          related to LWORK or LIWORK are issued by XERBLA.
+*
+*  IWORK   (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
+*          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
+*
+*  LIWORK  (input) INTEGER
+*          The dimension of the array IWORK.
+*          LIWORK >= 1; if SENSE = 'V' or 'B', LIWORK >= SDIM*(N-SDIM).
+*          Note that SDIM*(N-SDIM) <= N*N/4. Note also that an error is
+*          only returned if LIWORK < 1, but if SENSE = 'V' or 'B' this
+*          may not be large enough.
+*
+*          If LIWORK = -1, then a workspace query is assumed; the
+*          routine only calculates upper bounds on the optimal sizes of
+*          the arrays WORK and IWORK, returns these values as the first
+*          entries of the WORK and IWORK arrays, and no error messages
+*          related to LWORK or LIWORK are issued by XERBLA.
+*
+*  BWORK   (workspace) LOGICAL array, dimension (N)
+*          Not referenced if SORT = 'N'.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*          > 0: if INFO = i, and i is
+*             <= N: the QR algorithm failed to compute all the
+*                   eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
+*                   contain those eigenvalues which have converged; if
+*                   JOBVS = 'V', VS contains the transformation which
+*                   reduces A to its partially converged Schur form.
+*             = N+1: the eigenvalues could not be reordered because some
+*                   eigenvalues were too close to separate (the problem
+*                   is very ill-conditioned);
+*             = N+2: after reordering, roundoff changed values of some
+*                   complex eigenvalues so that leading eigenvalues in
+*                   the Schur form no longer satisfy SELECT=.TRUE.  This
+*                   could also be caused by underflow due to scaling.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTSB,
+     $                   WANTSE, WANTSN, WANTST, WANTSV, WANTVS
+      INTEGER            HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
+     $                   IHI, ILO, INXT, IP, ITAU, IWRK, LWRK, LIWRK,
+     $                   MAXWRK, MINWRK
+      REAL               ANRM, BIGNUM, CSCALE, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD,
+     $                   SLACPY, SLASCL, SORGHR, SSWAP, STRSEN, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           LSAME, ILAENV, SLAMCH, SLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTVS = LSAME( JOBVS, 'V' )
+      WANTST = LSAME( SORT, 'S' )
+      WANTSN = LSAME( SENSE, 'N' )
+      WANTSE = LSAME( SENSE, 'E' )
+      WANTSV = LSAME( SENSE, 'V' )
+      WANTSB = LSAME( SENSE, 'B' )
+      LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
+      IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
+     $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
+         INFO = -12
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "RWorkspace:" describe the
+*       minimal amount of real workspace needed at that point in the
+*       code, as well as the preferred amount for good performance.
+*       IWorkspace refers to integer workspace.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by SHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.
+*       If SENSE = 'E', 'V' or 'B', then the amount of workspace needed
+*       depends on SDIM, which is computed by the routine STRSEN later
+*       in the code.)
+*
+      IF( INFO.EQ.0 ) THEN
+         LIWRK = 1
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            LWRK = 1
+         ELSE
+            MAXWRK = 2*N + N*ILAENV( 1, 'SGEHRD', ' ', N, 1, N, 0 )
+            MINWRK = 3*N
+*
+            CALL SHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,
+     $             WORK, -1, IEVAL )
+            HSWORK = WORK( 1 )
+*
+            IF( .NOT.WANTVS ) THEN
+               MAXWRK = MAX( MAXWRK, N + HSWORK )
+            ELSE
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'SORGHR', ' ', N, 1, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + HSWORK )
+            END IF
+            LWRK = MAXWRK
+            IF( .NOT.WANTSN )
+     $         LWRK = MAX( LWRK, N + ( N*N )/2 )
+            IF( WANTSV .OR. WANTSB )
+     $         LIWRK = ( N*N )/4
+         END IF
+         IWORK( 1 ) = LIWRK
+         WORK( 1 ) = LWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -16
+         ELSE IF( LIWORK.LT.1 .AND. .NOT.LQUERY ) THEN
+            INFO = -18
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEESX', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         SDIM = 0
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = SLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL SLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*     Permute the matrix to make it more nearly triangular
+*     (RWorkspace: need N)
+*
+      IBAL = 1
+      CALL SGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (RWorkspace: need 3*N, prefer 2*N+N*NB)
+*
+      ITAU = N + IBAL
+      IWRK = N + ITAU
+      CALL SGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVS ) THEN
+*
+*        Copy Householder vectors to VS
+*
+         CALL SLACPY( 'L', N, N, A, LDA, VS, LDVS )
+*
+*        Generate orthogonal matrix in VS
+*        (RWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*
+         CALL SORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+      END IF
+*
+      SDIM = 0
+*
+*     Perform QR iteration, accumulating Schur vectors in VS if desired
+*     (RWorkspace: need N+1, prefer N+HSWORK (see comments) )
+*
+      IWRK = ITAU
+      CALL SHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,
+     $             WORK( IWRK ), LWORK-IWRK+1, IEVAL )
+      IF( IEVAL.GT.0 )
+     $   INFO = IEVAL
+*
+*     Sort eigenvalues if desired
+*
+      IF( WANTST .AND. INFO.EQ.0 ) THEN
+         IF( SCALEA ) THEN
+            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )
+            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )
+         END IF
+         DO 10 I = 1, N
+            BWORK( I ) = SELECT( WR( I ), WI( I ) )
+   10    CONTINUE
+*
+*        Reorder eigenvalues, transform Schur vectors, and compute
+*        reciprocal condition numbers
+*        (RWorkspace: if SENSE is not 'N', need N+2*SDIM*(N-SDIM)
+*                     otherwise, need N )
+*        (IWorkspace: if SENSE is 'V' or 'B', need SDIM*(N-SDIM)
+*                     otherwise, need 0 )
+*
+         CALL STRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,
+     $                SDIM, RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,
+     $                IWORK, LIWORK, ICOND )
+         IF( .NOT.WANTSN )
+     $      MAXWRK = MAX( MAXWRK, N+2*SDIM*( N-SDIM ) )
+         IF( ICOND.EQ.-15 ) THEN
+*
+*           Not enough real workspace
+*
+            INFO = -16
+         ELSE IF( ICOND.EQ.-17 ) THEN
+*
+*           Not enough integer workspace
+*
+            INFO = -18
+         ELSE IF( ICOND.GT.0 ) THEN
+*
+*           STRSEN failed to reorder or to restore standard Schur form
+*
+            INFO = ICOND + N
+         END IF
+      END IF
+*
+      IF( WANTVS ) THEN
+*
+*        Undo balancing
+*        (RWorkspace: need N)
+*
+         CALL SGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,
+     $                IERR )
+      END IF
+*
+      IF( SCALEA ) THEN
+*
+*        Undo scaling for the Schur form of A
+*
+         CALL SLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
+         CALL SCOPY( N, A, LDA+1, WR, 1 )
+         IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THEN
+            DUM( 1 ) = RCONDV
+            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
+            RCONDV = DUM( 1 )
+         END IF
+         IF( CSCALE.EQ.SMLNUM ) THEN
+*
+*           If scaling back towards underflow, adjust WI if an
+*           offdiagonal element of a 2-by-2 block in the Schur form
+*           underflows.
+*
+            IF( IEVAL.GT.0 ) THEN
+               I1 = IEVAL + 1
+               I2 = IHI - 1
+               CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
+     $                      IERR )
+            ELSE IF( WANTST ) THEN
+               I1 = 1
+               I2 = N - 1
+            ELSE
+               I1 = ILO
+               I2 = IHI - 1
+            END IF
+            INXT = I1 - 1
+            DO 20 I = I1, I2
+               IF( I.LT.INXT )
+     $            GO TO 20
+               IF( WI( I ).EQ.ZERO ) THEN
+                  INXT = I + 1
+               ELSE
+                  IF( A( I+1, I ).EQ.ZERO ) THEN
+                     WI( I ) = ZERO
+                     WI( I+1 ) = ZERO
+                  ELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.
+     $                     ZERO ) THEN
+                     WI( I ) = ZERO
+                     WI( I+1 ) = ZERO
+                     IF( I.GT.1 )
+     $                  CALL SSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )
+                     IF( N.GT.I+1 )
+     $                  CALL SSWAP( N-I-1, A( I, I+2 ), LDA,
+     $                              A( I+1, I+2 ), LDA )
+                     CALL SSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )
+                     A( I, I+1 ) = A( I+1, I )
+                     A( I+1, I ) = ZERO
+                  END IF
+                  INXT = I + 2
+               END IF
+   20       CONTINUE
+         END IF
+         CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,
+     $                WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )
+      END IF
+*
+      IF( WANTST .AND. INFO.EQ.0 ) THEN
+*
+*        Check if reordering successful
+*
+         LASTSL = .TRUE.
+         LST2SL = .TRUE.
+         SDIM = 0
+         IP = 0
+         DO 30 I = 1, N
+            CURSL = SELECT( WR( I ), WI( I ) )
+            IF( WI( I ).EQ.ZERO ) THEN
+               IF( CURSL )
+     $            SDIM = SDIM + 1
+               IP = 0
+               IF( CURSL .AND. .NOT.LASTSL )
+     $            INFO = N + 2
+            ELSE
+               IF( IP.EQ.1 ) THEN
+*
+*                 Last eigenvalue of conjugate pair
+*
+                  CURSL = CURSL .OR. LASTSL
+                  LASTSL = CURSL
+                  IF( CURSL )
+     $               SDIM = SDIM + 2
+                  IP = -1
+                  IF( CURSL .AND. .NOT.LST2SL )
+     $               INFO = N + 2
+               ELSE
+*
+*                 First eigenvalue of conjugate pair
+*
+                  IP = 1
+               END IF
+            END IF
+            LST2SL = LASTSL
+            LASTSL = CURSL
+   30    CONTINUE
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      IF( WANTSV .OR. WANTSB ) THEN
+         IWORK( 1 ) = SDIM*(N-SDIM)
+      ELSE
+         IWORK( 1 ) = 1
+      END IF
+*
+      RETURN
+*
+*     End of SGEESX
+*
+      END
diff --git a/libcruft/lapack/sgeev.f b/libcruft/lapack/sgeev.f
new file mode 100644
index 0000000..7af086a
--- /dev/null
+++ b/libcruft/lapack/sgeev.f
@@ -0,0 +1,423 @@
+      SUBROUTINE SGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
+     $                  LDVR, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WI( * ), WORK( * ), WR( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEEV computes for an N-by-N real nonsymmetric matrix A, the
+*  eigenvalues and, optionally, the left and/or right eigenvectors.
+*
+*  The right eigenvector v(j) of A satisfies
+*                   A * v(j) = lambda(j) * v(j)
+*  where lambda(j) is its eigenvalue.
+*  The left eigenvector u(j) of A satisfies
+*                u(j)**H * A = lambda(j) * u(j)**H
+*  where u(j)**H denotes the conjugate transpose of u(j).
+*
+*  The computed eigenvectors are normalized to have Euclidean norm
+*  equal to 1 and largest component real.
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N': left eigenvectors of A are not computed;
+*          = 'V': left eigenvectors of A are computed.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N': right eigenvectors of A are not computed;
+*          = 'V': right eigenvectors of A are computed.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  WR      (output) REAL array, dimension (N)
+*  WI      (output) REAL array, dimension (N)
+*          WR and WI contain the real and imaginary parts,
+*          respectively, of the computed eigenvalues.  Complex
+*          conjugate pairs of eigenvalues appear consecutively
+*          with the eigenvalue having the positive imaginary part
+*          first.
+*
+*  VL      (output) REAL array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
+*          after another in the columns of VL, in the same order
+*          as their eigenvalues.
+*          If JOBVL = 'N', VL is not referenced.
+*          If the j-th eigenvalue is real, then u(j) = VL(:,j),
+*          the j-th column of VL.
+*          If the j-th and (j+1)-st eigenvalues form a complex
+*          conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and
+*          u(j+1) = VL(:,j) - i*VL(:,j+1).
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1; if
+*          JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) REAL array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
+*          after another in the columns of VR, in the same order
+*          as their eigenvalues.
+*          If JOBVR = 'N', VR is not referenced.
+*          If the j-th eigenvalue is real, then v(j) = VR(:,j),
+*          the j-th column of VR.
+*          If the j-th and (j+1)-st eigenvalues form a complex
+*          conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and
+*          v(j+1) = VR(:,j) - i*VR(:,j+1).
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1; if
+*          JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,3*N), and
+*          if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N.  For good
+*          performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = i, the QR algorithm failed to compute all the
+*                eigenvalues, and no eigenvectors have been computed;
+*                elements i+1:N of WR and WI contain eigenvalues which
+*                have converged.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
+      CHARACTER          SIDE
+      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
+     $                   MAXWRK, MINWRK, NOUT
+      REAL               ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
+     $                   SN
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            SELECT( 1 )
+      REAL               DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD, SLACPY,
+     $                   SLARTG, SLASCL, SORGHR, SROT, SSCAL, STREVC,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV, ISAMAX
+      REAL               SLAMCH, SLANGE, SLAPY2, SNRM2
+      EXTERNAL           LSAME, ILAENV, ISAMAX, SLAMCH, SLANGE, SLAPY2,
+     $                   SNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      WANTVL = LSAME( JOBVL, 'V' )
+      WANTVR = LSAME( JOBVR, 'V' )
+      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -9
+      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by SHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            MAXWRK = 1
+         ELSE
+            MAXWRK = 2*N + N*ILAENV( 1, 'SGEHRD', ' ', N, 1, N, 0 )
+            IF( WANTVL ) THEN
+               MINWRK = 4*N
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'SORGHR', ' ', N, 1, N, -1 ) )
+               CALL SHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
+     $                WORK, -1, INFO )
+               HSWORK = WORK( 1 )
+               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               MAXWRK = MAX( MAXWRK, 4*N )
+            ELSE IF( WANTVR ) THEN
+               MINWRK = 4*N
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'SORGHR', ' ', N, 1, N, -1 ) )
+               CALL SHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
+     $                WORK, -1, INFO )
+               HSWORK = WORK( 1 )
+               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               MAXWRK = MAX( MAXWRK, 4*N )
+            ELSE 
+               MINWRK = 3*N
+               CALL SHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,
+     $                WORK, -1, INFO )
+               HSWORK = WORK( 1 )
+               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+            END IF
+            MAXWRK = MAX( MAXWRK, MINWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = SLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL SLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*     Balance the matrix
+*     (Workspace: need N)
+*
+      IBAL = 1
+      CALL SGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (Workspace: need 3*N, prefer 2*N+N*NB)
+*
+      ITAU = IBAL + N
+      IWRK = ITAU + N
+      CALL SGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVL ) THEN
+*
+*        Want left eigenvectors
+*        Copy Householder vectors to VL
+*
+         SIDE = 'L'
+         CALL SLACPY( 'L', N, N, A, LDA, VL, LDVL )
+*
+*        Generate orthogonal matrix in VL
+*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*
+         CALL SORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VL
+*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
+*
+         IWRK = ITAU
+         CALL SHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+         IF( WANTVR ) THEN
+*
+*           Want left and right eigenvectors
+*           Copy Schur vectors to VR
+*
+            SIDE = 'B'
+            CALL SLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
+         END IF
+*
+      ELSE IF( WANTVR ) THEN
+*
+*        Want right eigenvectors
+*        Copy Householder vectors to VR
+*
+         SIDE = 'R'
+         CALL SLACPY( 'L', N, N, A, LDA, VR, LDVR )
+*
+*        Generate orthogonal matrix in VR
+*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*
+         CALL SORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VR
+*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
+*
+         IWRK = ITAU
+         CALL SHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+      ELSE
+*
+*        Compute eigenvalues only
+*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
+*
+         IWRK = ITAU
+         CALL SHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+      END IF
+*
+*     If INFO > 0 from SHSEQR, then quit
+*
+      IF( INFO.GT.0 )
+     $   GO TO 50
+*
+      IF( WANTVL .OR. WANTVR ) THEN
+*
+*        Compute left and/or right eigenvectors
+*        (Workspace: need 4*N)
+*
+         CALL STREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                N, NOUT, WORK( IWRK ), IERR )
+      END IF
+*
+      IF( WANTVL ) THEN
+*
+*        Undo balancing of left eigenvectors
+*        (Workspace: need N)
+*
+         CALL SGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,
+     $                IERR )
+*
+*        Normalize left eigenvectors and make largest component real
+*
+         DO 20 I = 1, N
+            IF( WI( I ).EQ.ZERO ) THEN
+               SCL = ONE / SNRM2( N, VL( 1, I ), 1 )
+               CALL SSCAL( N, SCL, VL( 1, I ), 1 )
+            ELSE IF( WI( I ).GT.ZERO ) THEN
+               SCL = ONE / SLAPY2( SNRM2( N, VL( 1, I ), 1 ),
+     $               SNRM2( N, VL( 1, I+1 ), 1 ) )
+               CALL SSCAL( N, SCL, VL( 1, I ), 1 )
+               CALL SSCAL( N, SCL, VL( 1, I+1 ), 1 )
+               DO 10 K = 1, N
+                  WORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**2
+   10          CONTINUE
+               K = ISAMAX( N, WORK( IWRK ), 1 )
+               CALL SLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )
+               CALL SROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )
+               VL( K, I+1 ) = ZERO
+            END IF
+   20    CONTINUE
+      END IF
+*
+      IF( WANTVR ) THEN
+*
+*        Undo balancing of right eigenvectors
+*        (Workspace: need N)
+*
+         CALL SGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,
+     $                IERR )
+*
+*        Normalize right eigenvectors and make largest component real
+*
+         DO 40 I = 1, N
+            IF( WI( I ).EQ.ZERO ) THEN
+               SCL = ONE / SNRM2( N, VR( 1, I ), 1 )
+               CALL SSCAL( N, SCL, VR( 1, I ), 1 )
+            ELSE IF( WI( I ).GT.ZERO ) THEN
+               SCL = ONE / SLAPY2( SNRM2( N, VR( 1, I ), 1 ),
+     $               SNRM2( N, VR( 1, I+1 ), 1 ) )
+               CALL SSCAL( N, SCL, VR( 1, I ), 1 )
+               CALL SSCAL( N, SCL, VR( 1, I+1 ), 1 )
+               DO 30 K = 1, N
+                  WORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**2
+   30          CONTINUE
+               K = ISAMAX( N, WORK( IWRK ), 1 )
+               CALL SLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )
+               CALL SROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )
+               VR( K, I+1 ) = ZERO
+            END IF
+   40    CONTINUE
+      END IF
+*
+*     Undo scaling if necessary
+*
+   50 CONTINUE
+      IF( SCALEA ) THEN
+         CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),
+     $                MAX( N-INFO, 1 ), IERR )
+         CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),
+     $                MAX( N-INFO, 1 ), IERR )
+         IF( INFO.GT.0 ) THEN
+            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,
+     $                   IERR )
+            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
+     $                   IERR )
+         END IF
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of SGEEV
+*
+      END
diff --git a/libcruft/lapack/sgehd2.f b/libcruft/lapack/sgehd2.f
new file mode 100644
index 0000000..95a154e
--- /dev/null
+++ b/libcruft/lapack/sgehd2.f
@@ -0,0 +1,149 @@
+      SUBROUTINE SGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEHD2 reduces a real general matrix A to upper Hessenberg form H by
+*  an orthogonal similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to SGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= max(1,N).
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the n by n general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the orthogonal matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) REAL array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      REAL               AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEHD2', -INFO )
+         RETURN
+      END IF
+*
+      DO 10 I = ILO, IHI - 1
+*
+*        Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)
+*
+         CALL SLARFG( IHI-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,
+     $                TAU( I ) )
+         AII = A( I+1, I )
+         A( I+1, I ) = ONE
+*
+*        Apply H(i) to A(1:ihi,i+1:ihi) from the right
+*
+         CALL SLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ),
+     $               A( 1, I+1 ), LDA, WORK )
+*
+*        Apply H(i) to A(i+1:ihi,i+1:n) from the left
+*
+         CALL SLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1, TAU( I ),
+     $               A( I+1, I+1 ), LDA, WORK )
+*
+         A( I+1, I ) = AII
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of SGEHD2
+*
+      END
diff --git a/libcruft/lapack/sgehrd.f b/libcruft/lapack/sgehrd.f
new file mode 100644
index 0000000..c5fe911
--- /dev/null
+++ b/libcruft/lapack/sgehrd.f
@@ -0,0 +1,273 @@
+      SUBROUTINE SGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL              A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEHRD reduces a real general matrix A to upper Hessenberg form H by
+*  an orthogonal similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to SGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the orthogonal matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) REAL array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to
+*          zero.
+*
+*  WORK    (workspace/output) REAL array, dimension (LWORK)
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's SGEHRD
+*  subroutine incorporating improvements proposed by Quintana-Orti and
+*  Van de Geijn (2005). 
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+      REAL              ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, 
+     $                     ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NH, NX
+      REAL              EI
+*     ..
+*     .. Local Arrays ..
+      REAL              T( LDT, NBMAX )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SGEHD2, SGEMM, SLAHR2, SLARFB, STRMM,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MIN( NBMAX, ILAENV( 1, 'SGEHRD', ' ', N, ILO, IHI, -1 ) )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEHRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero
+*
+      DO 10 I = 1, ILO - 1
+         TAU( I ) = ZERO
+   10 CONTINUE
+      DO 20 I = MAX( 1, IHI ), N - 1
+         TAU( I ) = ZERO
+   20 CONTINUE
+*
+*     Quick return if possible
+*
+      NH = IHI - ILO + 1
+      IF( NH.LE.1 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Determine the block size
+*
+      NB = MIN( NBMAX, ILAENV( 1, 'SGEHRD', ' ', N, ILO, IHI, -1 ) )
+      NBMIN = 2
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.NH ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code)
+*
+         NX = MAX( NB, ILAENV( 3, 'SGEHRD', ' ', N, ILO, IHI, -1 ) )
+         IF( NX.LT.NH ) THEN
+*
+*           Determine if workspace is large enough for blocked code
+*
+            IWS = N*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code
+*
+               NBMIN = MAX( 2, ILAENV( 2, 'SGEHRD', ' ', N, ILO, IHI,
+     $                 -1 ) )
+               IF( LWORK.GE.N*NBMIN ) THEN
+                  NB = LWORK / N
+               ELSE
+                  NB = 1
+               END IF
+            END IF
+         END IF
+      END IF
+      LDWORK = N
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN
+*
+*        Use unblocked code below
+*
+         I = ILO
+*
+      ELSE
+*
+*        Use blocked code
+*
+         DO 40 I = ILO, IHI - 1 - NX, NB
+            IB = MIN( NB, IHI-I )
+*
+*           Reduce columns i:i+ib-1 to Hessenberg form, returning the
+*           matrices V and T of the block reflector H = I - V*T*V'
+*           which performs the reduction, and also the matrix Y = A*V*T
+*
+            CALL SLAHR2( IHI, I, IB, A( 1, I ), LDA, TAU( I ), T, LDT,
+     $                   WORK, LDWORK )
+*
+*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the
+*           right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set
+*           to 1
+*
+            EI = A( I+IB, I+IB-1 )
+            A( I+IB, I+IB-1 ) = ONE
+            CALL SGEMM( 'No transpose', 'Transpose', 
+     $                  IHI, IHI-I-IB+1,
+     $                  IB, -ONE, WORK, LDWORK, A( I+IB, I ), LDA, ONE,
+     $                  A( 1, I+IB ), LDA )
+            A( I+IB, I+IB-1 ) = EI
+*
+*           Apply the block reflector H to A(1:i,i+1:i+ib-1) from the
+*           right
+*
+            CALL STRMM( 'Right', 'Lower', 'Transpose',
+     $                  'Unit', I, IB-1,
+     $                  ONE, A( I+1, I ), LDA, WORK, LDWORK )
+            DO 30 J = 0, IB-2
+               CALL SAXPY( I, -ONE, WORK( LDWORK*J+1 ), 1,
+     $                     A( 1, I+J+1 ), 1 )
+   30       CONTINUE
+*
+*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the
+*           left
+*
+            CALL SLARFB( 'Left', 'Transpose', 'Forward',
+     $                   'Columnwise',
+     $                   IHI-I, N-I-IB+1, IB, A( I+1, I ), LDA, T, LDT,
+     $                   A( I+1, I+IB ), LDA, WORK, LDWORK )
+   40    CONTINUE
+      END IF
+*
+*     Use unblocked code to reduce the rest of the matrix
+*
+      CALL SGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )
+      WORK( 1 ) = IWS
+*
+      RETURN
+*
+*     End of SGEHRD
+*
+      END
diff --git a/libcruft/lapack/sgelq2.f b/libcruft/lapack/sgelq2.f
new file mode 100644
index 0000000..0af4b60
--- /dev/null
+++ b/libcruft/lapack/sgelq2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE SGELQ2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGELQ2 computes an LQ factorization of a real m by n matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m by min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) REAL array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k) . . . H(2) H(1), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      REAL               AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGELQ2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i,i+1:n)
+*
+         CALL SLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,
+     $                TAU( I ) )
+         IF( I.LT.M ) THEN
+*
+*           Apply H(i) to A(i+1:m,i:n) from the right
+*
+            AII = A( I, I )
+            A( I, I ) = ONE
+            CALL SLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ),
+     $                  A( I+1, I ), LDA, WORK )
+            A( I, I ) = AII
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of SGELQ2
+*
+      END
diff --git a/libcruft/lapack/sgelqf.f b/libcruft/lapack/sgelqf.f
new file mode 100644
index 0000000..c197524
--- /dev/null
+++ b/libcruft/lapack/sgelqf.f
@@ -0,0 +1,195 @@
+      SUBROUTINE SGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGELQF computes an LQ factorization of a real M-by-N matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m-by-min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k) . . . H(2) H(1), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGELQ2, SLARFB, SLARFT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+      LWKOPT = M*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGELQF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'SGELQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'SGELQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the LQ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL SGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL SLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i+ib:m,i:n) from the right
+*
+               CALL SLARFB( 'Right', 'No transpose', 'Forward',
+     $                      'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),
+     $                      LDA, WORK, LDWORK, A( I+IB, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL SGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SGELQF
+*
+      END
diff --git a/libcruft/lapack/sgelsd.f b/libcruft/lapack/sgelsd.f
new file mode 100644
index 0000000..851e00b
--- /dev/null
+++ b/libcruft/lapack/sgelsd.f
@@ -0,0 +1,538 @@
+      SUBROUTINE SGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND,
+     $                   RANK, WORK, LWORK, IWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGELSD computes the minimum-norm solution to a real linear least
+*  squares problem:
+*      minimize 2-norm(| b - A*x |)
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The problem is solved in three steps:
+*  (1) Reduce the coefficient matrix A to bidiagonal form with
+*      Householder transformations, reducing the original problem
+*      into a "bidiagonal least squares problem" (BLS)
+*  (2) Solve the BLS using a divide and conquer approach.
+*  (3) Apply back all the Householder tranformations to solve
+*      the original least squares problem.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  The divide and conquer algorithm makes very mild assumptions about
+*  floating point arithmetic. It will work on machines with a guard
+*  digit in add/subtract, or on those binary machines without guard
+*  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
+*  Cray-2. It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution
+*          matrix X.  If m >= n and RANK = n, the residual
+*          sum-of-squares for the solution in the i-th column is given
+*          by the sum of squares of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,max(M,N)).
+*
+*  S       (output) REAL array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) REAL
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK must be at least 1.
+*          The exact minimum amount of workspace needed depends on M,
+*          N and NRHS. As long as LWORK is at least
+*              12*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2,
+*          if M is greater than or equal to N or
+*              12*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS + (SMLSIZ+1)**2,
+*          if M is less than N, the code will execute correctly.
+*          SMLSIZ is returned by ILAENV and is equal to the maximum
+*          size of the subproblems at the bottom of the computation
+*          tree (usually about 25), and
+*             NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the array WORK and the
+*          minimum size of the array IWORK, and returns these values as
+*          the first entries of the WORK and IWORK arrays, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
+*          LIWORK >= max(1, 3*MINMN*NLVL + 11*MINMN),
+*          where MINMN = MIN( M,N ).
+*          On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
+     $                   LDWORK, LIWORK, MAXMN, MAXWRK, MINMN, MINWRK,
+     $                   MM, MNTHR, NLVL, NWORK, SMLSIZ, WLALSD
+      REAL               ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEBRD, SGELQF, SGEQRF, SLABAD, SLACPY, SLALSD,
+     $                   SLASCL, SLASET, SORMBR, SORMLQ, SORMQR, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           SLAMCH, SLANGE, ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, LOG, MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace.
+*     (Note: Comments in the code beginning "Workspace:" describe the
+*     minimal amount of workspace needed at that point in the code,
+*     as well as the preferred amount for good performance.
+*     NB refers to the optimal block size for the immediately
+*     following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         LIWORK = 1
+         IF( MINMN.GT.0 ) THEN
+            SMLSIZ = ILAENV( 9, 'SGELSD', ' ', 0, 0, 0, 0 )
+            MNTHR = ILAENV( 6, 'SGELSD', ' ', M, N, NRHS, -1 )
+            NLVL = MAX( INT( LOG( REAL( MINMN ) / REAL( SMLSIZ + 1 ) ) /
+     $                  LOG( TWO ) ) + 1, 0 )
+            LIWORK = 3*MINMN*NLVL + 11*MINMN
+            MM = M
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns.
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'SGEQRF', ' ', M,
+     $                       N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'SORMQR', 'LT',
+     $                       M, NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined.
+*
+               MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
+     $                       'SGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'SORMBR',
+     $                       'QLT', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
+     $                       'SORMBR', 'PLN', N, NRHS, N, -1 ) )
+               WLALSD = 9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS +
+     $                  ( SMLSIZ + 1 )**2
+               MAXWRK = MAX( MAXWRK, 3*N + WLALSD )
+               MINWRK = MAX( 3*N + MM, 3*N + NRHS, 3*N + WLALSD )
+            END IF
+            IF( N.GT.M ) THEN
+               WLALSD = 9*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS +
+     $                  ( SMLSIZ + 1 )**2
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                           than rows.
+*
+                  MAXWRK = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1,
+     $                                  -1 )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
+     $                          'SGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
+     $                          'SORMBR', 'QLT', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + ( M - 1 )*ILAENV( 1,
+     $                          'SORMBR', 'PLN', M, NRHS, M, -1 ) )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'SORMLQ',
+     $                          'LT', N, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + WLALSD )
+               ELSE
+*
+*                 Path 2 - remaining underdetermined cases.
+*
+                  MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'SGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'SORMBR',
+     $                          'QLT', M, NRHS, N, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'SORMBR',
+     $                          'PLN', N, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + WLALSD )
+               END IF
+               MINWRK = MAX( 3*M + NRHS, 3*M + M, 3*M + WLALSD )
+            END IF
+         END IF
+         MINWRK = MIN( MINWRK, MAXWRK )
+         WORK( 1 ) = MAXWRK
+         IWORK( 1 ) = LIWORK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGELSD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters.
+*
+      EPS = SLAMCH( 'P' )
+      SFMIN = SLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max entry outside range [SMLNUM,BIGNUM].
+*
+      ANRM = SLANGE( 'M', M, N, A, LDA, WORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM.
+*
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL SLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         CALL SLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
+         RANK = 0
+         GO TO 10
+      END IF
+*
+*     Scale B if max entry outside range [SMLNUM,BIGNUM].
+*
+      BNRM = SLANGE( 'M', M, NRHS, B, LDB, WORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM.
+*
+         CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     If M < N make sure certain entries of B are zero.
+*
+      IF( M.LT.N )
+     $   CALL SLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
+*
+*     Overdetermined case.
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined.
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns.
+*
+            MM = N
+            ITAU = 1
+            NWORK = ITAU + N
+*
+*           Compute A=Q*R.
+*           (Workspace: need 2*N, prefer N+N*NB)
+*
+            CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                   LWORK-NWORK+1, INFO )
+*
+*           Multiply B by transpose(Q).
+*           (Workspace: need N+NRHS, prefer N+NRHS*NB)
+*
+            CALL SORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*           Zero out below R.
+*
+            IF( N.GT.1 ) THEN
+               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+            END IF
+         END IF
+*
+         IE = 1
+         ITAUQ = IE + N
+         ITAUP = ITAUQ + N
+         NWORK = ITAUP + N
+*
+*        Bidiagonalize R in A.
+*        (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)
+*
+         CALL SGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R.
+*        (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)
+*
+         CALL SORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL SLALSD( 'U', SMLSIZ, N, NRHS, S, WORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of R.
+*
+         CALL SORMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
+     $         MAX( M, 2*M-4, NRHS, N-3*M, WLALSD ) ) THEN
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm.
+*
+         LDWORK = M
+         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
+     $       M*LDA+M+M*NRHS, 4*M+M*LDA+WLALSD ) )LDWORK = LDA
+         ITAU = 1
+         NWORK = M + 1
+*
+*        Compute A=L*Q.
+*        (Workspace: need 2*M, prefer M+M*NB)
+*
+         CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+         IL = NWORK
+*
+*        Copy L to WORK(IL), zeroing out above its diagonal.
+*
+         CALL SLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         IE = IL + LDWORK*M
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+*
+*        Bidiagonalize L in WORK(IL).
+*        (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)
+*
+         CALL SGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L.
+*        (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
+*
+         CALL SORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL SLALSD( 'U', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of L.
+*
+         CALL SORMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUP ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Zero out below first M rows of B.
+*
+         CALL SLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
+         NWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B.
+*        (Workspace: need M+NRHS, prefer M+NRHS*NB)
+*
+         CALL SORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases.
+*
+         IE = 1
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+*
+*        Bidiagonalize A.
+*        (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+         CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors.
+*        (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)
+*
+         CALL SORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL SLALSD( 'L', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of A.
+*
+         CALL SORMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      END IF
+*
+*     Undo scaling.
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   10 CONTINUE
+      WORK( 1 ) = MAXWRK
+      IWORK( 1 ) = LIWORK
+      RETURN
+*
+*     End of SGELSD
+*
+      END
diff --git a/libcruft/lapack/sgelss.f b/libcruft/lapack/sgelss.f
new file mode 100644
index 0000000..33e5977
--- /dev/null
+++ b/libcruft/lapack/sgelss.f
@@ -0,0 +1,617 @@
+      SUBROUTINE SGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGELSS computes the minimum norm solution to a real linear least
+*  squares problem:
+*
+*  Minimize 2-norm(| b - A*x |).
+*
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
+*  X.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the first min(m,n) rows of A are overwritten with
+*          its right singular vectors, stored rowwise.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution
+*          matrix X.  If m >= n and RANK = n, the residual
+*          sum-of-squares for the solution in the i-th column is given
+*          by the sum of squares of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,max(M,N)).
+*
+*  S       (output) REAL array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) REAL
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= 1, and also:
+*          LWORK >= 3*min(M,N) + max( 2*min(M,N), max(M,N), NRHS )
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,
+     $                   ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
+     $                   MAXWRK, MINMN, MINWRK, MM, MNTHR
+      REAL               ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
+*     ..
+*     .. Local Arrays ..
+      REAL               VDUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SBDSQR, SCOPY, SGEBRD, SGELQF, SGEMM, SGEMV,
+     $                   SGEQRF, SLABAD, SLACPY, SLASCL, SLASET, SORGBR,
+     $                   SORMBR, SORMLQ, SORMQR, SRSCL, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           ILAENV, SLAMCH, SLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( MINMN.GT.0 ) THEN
+            MM = M
+            MNTHR = ILAENV( 6, 'SGELSS', ' ', M, N, NRHS, -1 )
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'SGEQRF', ' ', M,
+     $                       N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'SORMQR', 'LT',
+     $                       M, NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined
+*
+*              Compute workspace needed for SBDSQR
+*
+               BDSPAC = MAX( 1, 5*N )
+               MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
+     $                       'SGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'SORMBR',
+     $                       'QLT', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
+     $                       'SORGBR', 'P', N, N, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, BDSPAC )
+               MAXWRK = MAX( MAXWRK, N*NRHS )
+               MINWRK = MAX( 3*N + MM, 3*N + NRHS, BDSPAC )
+               MAXWRK = MAX( MINWRK, MAXWRK )
+            END IF
+            IF( N.GT.M ) THEN
+*
+*              Compute workspace needed for SBDSQR
+*
+               BDSPAC = MAX( 1, 5*M )
+               MINWRK = MAX( 3*M+NRHS, 3*M+N, BDSPAC )
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                 than rows
+*
+                  MAXWRK = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1,
+     $                                  -1 )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
+     $                          'SGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
+     $                          'SORMBR', 'QLT', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M +
+     $                          ( M - 1 )*ILAENV( 1, 'SORGBR', 'P', M,
+     $                          M, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + M + BDSPAC )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'SORMLQ',
+     $                          'LT', N, NRHS, M, -1 ) )
+               ELSE
+*
+*                 Path 2 - underdetermined
+*
+                  MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'SGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'SORMBR',
+     $                          'QLT', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'SORGBR',
+     $                          'P', M, N, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, BDSPAC )
+                  MAXWRK = MAX( MAXWRK, N*NRHS )
+               END IF
+            END IF
+            MAXWRK = MAX( MINWRK, MAXWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
+     $      INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGELSS', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      EPS = SLAMCH( 'P' )
+      SFMIN = SLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = SLANGE( 'M', M, N, A, LDA, WORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL SLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         CALL SLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = SLANGE( 'M', M, NRHS, B, LDB, WORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Overdetermined case
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns
+*
+            MM = N
+            ITAU = 1
+            IWORK = ITAU + N
+*
+*           Compute A=Q*R
+*           (Workspace: need 2*N, prefer N+N*NB)
+*
+            CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                   LWORK-IWORK+1, INFO )
+*
+*           Multiply B by transpose(Q)
+*           (Workspace: need N+NRHS, prefer N+NRHS*NB)
+*
+            CALL SORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*           Zero out below R
+*
+            IF( N.GT.1 )
+     $         CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+         END IF
+*
+         IE = 1
+         ITAUQ = IE + N
+         ITAUP = ITAUQ + N
+         IWORK = ITAUP + N
+*
+*        Bidiagonalize R in A
+*        (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)
+*
+         CALL SGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R
+*        (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)
+*
+         CALL SORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in A
+*        (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+         CALL SORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IWORK = IE + N
+*
+*        Perform bidiagonal QR iteration
+*          multiply B by transpose of left singular vectors
+*          compute right singular vectors in A
+*        (Workspace: need BDSPAC)
+*
+         CALL SBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, WORK( IWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 10 I = 1, N
+            IF( S( I ).GT.THR ) THEN
+               CALL SRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL SLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            END IF
+   10    CONTINUE
+*
+*        Multiply B by right singular vectors
+*        (Workspace: need N, prefer N*NRHS)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, A, LDA, B, LDB, ZERO,
+     $                  WORK, LDB )
+            CALL SLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 20 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL SGEMM( 'T', 'N', N, BL, N, ONE, A, LDA, B( 1, I ),
+     $                     LDB, ZERO, WORK, N )
+               CALL SLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB )
+   20       CONTINUE
+         ELSE
+            CALL SGEMV( 'T', N, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )
+            CALL SCOPY( N, WORK, 1, B, 1 )
+         END IF
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
+     $         MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm
+*
+         LDWORK = M
+         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
+     $       M*LDA+M+M*NRHS ) )LDWORK = LDA
+         ITAU = 1
+         IWORK = M + 1
+*
+*        Compute A=L*Q
+*        (Workspace: need 2*M, prefer M+M*NB)
+*
+         CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+         IL = IWORK
+*
+*        Copy L to WORK(IL), zeroing out above it
+*
+         CALL SLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         IE = IL + LDWORK*M
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize L in WORK(IL)
+*        (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)
+*
+         CALL SGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L
+*        (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
+*
+         CALL SORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in WORK(IL)
+*        (Workspace: need M*M+5*M-1, prefer M*M+4*M+(M-1)*NB)
+*
+         CALL SORGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IWORK = IE + M
+*
+*        Perform bidiagonal QR iteration,
+*           computing right singular vectors of L in WORK(IL) and
+*           multiplying B by transpose of left singular vectors
+*        (Workspace: need M*M+M+BDSPAC)
+*
+         CALL SBDSQR( 'U', M, M, 0, NRHS, S, WORK( IE ), WORK( IL ),
+     $                LDWORK, A, LDA, B, LDB, WORK( IWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 30 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL SRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL SLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            END IF
+   30    CONTINUE
+         IWORK = IE
+*
+*        Multiply B by right singular vectors of L in WORK(IL)
+*        (Workspace: need M*M+2*M, prefer M*M+M+M*NRHS)
+*
+         IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN
+            CALL SGEMM( 'T', 'N', M, NRHS, M, ONE, WORK( IL ), LDWORK,
+     $                  B, LDB, ZERO, WORK( IWORK ), LDB )
+            CALL SLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = ( LWORK-IWORK+1 ) / M
+            DO 40 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL SGEMM( 'T', 'N', M, BL, M, ONE, WORK( IL ), LDWORK,
+     $                     B( 1, I ), LDB, ZERO, WORK( IWORK ), M )
+               CALL SLACPY( 'G', M, BL, WORK( IWORK ), M, B( 1, I ),
+     $                      LDB )
+   40       CONTINUE
+         ELSE
+            CALL SGEMV( 'T', M, M, ONE, WORK( IL ), LDWORK, B( 1, 1 ),
+     $                  1, ZERO, WORK( IWORK ), 1 )
+            CALL SCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 )
+         END IF
+*
+*        Zero out below first M rows of B
+*
+         CALL SLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
+         IWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B
+*        (Workspace: need M+NRHS, prefer M+NRHS*NB)
+*
+         CALL SORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases
+*
+         IE = 1
+         ITAUQ = IE + M
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize A
+*        (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+         CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors
+*        (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)
+*
+         CALL SORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors in A
+*        (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+         CALL SORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IWORK = IE + M
+*
+*        Perform bidiagonal QR iteration,
+*           computing right singular vectors of A in A and
+*           multiplying B by transpose of left singular vectors
+*        (Workspace: need BDSPAC)
+*
+         CALL SBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, WORK( IWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 50 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL SRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL SLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            END IF
+   50    CONTINUE
+*
+*        Multiply B by right singular vectors of A
+*        (Workspace: need N, prefer N*NRHS)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL SGEMM( 'T', 'N', N, NRHS, M, ONE, A, LDA, B, LDB, ZERO,
+     $                  WORK, LDB )
+            CALL SLACPY( 'F', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 60 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL SGEMM( 'T', 'N', N, BL, M, ONE, A, LDA, B( 1, I ),
+     $                     LDB, ZERO, WORK, N )
+               CALL SLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB )
+   60       CONTINUE
+         ELSE
+            CALL SGEMV( 'T', M, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )
+            CALL SCOPY( N, WORK, 1, B, 1 )
+         END IF
+      END IF
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   70 CONTINUE
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of SGELSS
+*
+      END
diff --git a/libcruft/lapack/sgelsy.f b/libcruft/lapack/sgelsy.f
new file mode 100644
index 0000000..a7d3d8a
--- /dev/null
+++ b/libcruft/lapack/sgelsy.f
@@ -0,0 +1,391 @@
+      SUBROUTINE SGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGELSY computes the minimum-norm solution to a real linear least
+*  squares problem:
+*      minimize || A * X - B ||
+*  using a complete orthogonal factorization of A.  A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The routine first computes a QR factorization with column pivoting:
+*      A * P = Q * [ R11 R12 ]
+*                  [  0  R22 ]
+*  with R11 defined as the largest leading submatrix whose estimated
+*  condition number is less than 1/RCOND.  The order of R11, RANK,
+*  is the effective rank of A.
+*
+*  Then, R22 is considered to be negligible, and R12 is annihilated
+*  by orthogonal transformations from the right, arriving at the
+*  complete orthogonal factorization:
+*     A * P = Q * [ T11 0 ] * Z
+*                 [  0  0 ]
+*  The minimum-norm solution is then
+*     X = P * Z' [ inv(T11)*Q1'*B ]
+*                [        0       ]
+*  where Q1 consists of the first RANK columns of Q.
+*
+*  This routine is basically identical to the original xGELSX except
+*  three differences:
+*    o The call to the subroutine xGEQPF has been substituted by the
+*      the call to the subroutine xGEQP3. This subroutine is a Blas-3
+*      version of the QR factorization with column pivoting.
+*    o Matrix B (the right hand side) is updated with Blas-3.
+*    o The permutation of matrix B (the right hand side) is faster and
+*      more simple.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of
+*          columns of matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been overwritten by details of its
+*          complete orthogonal factorization.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,M,N).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of AP, otherwise column i is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of AP
+*          was the k-th column of A.
+*
+*  RCOND   (input) REAL
+*          RCOND is used to determine the effective rank of A, which
+*          is defined as the order of the largest leading triangular
+*          submatrix R11 in the QR factorization with pivoting of A,
+*          whose estimated condition number < 1/RCOND.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the order of the submatrix
+*          R11.  This is the same as the order of the submatrix T11
+*          in the complete orthogonal factorization of A.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          The unblocked strategy requires that:
+*             LWORK >= MAX( MN+3*N+1, 2*MN+NRHS ),
+*          where MN = min( M, N ).
+*          The block algorithm requires that:
+*             LWORK >= MAX( MN+2*N+NB*(N+1), 2*MN+NB*NRHS ),
+*          where NB is an upper bound on the blocksize returned
+*          by ILAENV for the routines SGEQP3, STZRZF, STZRQF, SORMQR,
+*          and SORMRZ.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: If INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*    E. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            IMAX, IMIN
+      PARAMETER          ( IMAX = 1, IMIN = 2 )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
+     $                   LWKOPT, MN, NB, NB1, NB2, NB3, NB4
+      REAL               ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
+     $                   SMAXPR, SMIN, SMINPR, SMLNUM, WSIZE
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           ILAENV, SLAMCH, SLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEQP3, SLABAD, SLAIC1, SLASCL, SLASET,
+     $                   SORMQR, SORMRZ, STRSM, STZRZF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M, N )
+      ISMIN = MN + 1
+      ISMAX = 2*MN + 1
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Figure out optimal block size
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THEN
+            LWKMIN = 1
+            LWKOPT = 1
+         ELSE
+            NB1 = ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+            NB2 = ILAENV( 1, 'SGERQF', ' ', M, N, -1, -1 )
+            NB3 = ILAENV( 1, 'SORMQR', ' ', M, N, NRHS, -1 )
+            NB4 = ILAENV( 1, 'SORMRQ', ' ', M, N, NRHS, -1 )
+            NB = MAX( NB1, NB2, NB3, NB4 )
+            LWKMIN = MN + MAX( 2*MN, N + 1, MN + NRHS )
+            LWKOPT = MAX( LWKMIN,
+     $                    MN + 2*N + NB*( N + 1 ), 2*MN + NB*NRHS )
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGELSY', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A, B if max entries outside range [SMLNUM,BIGNUM]
+*
+      ANRM = SLANGE( 'M', M, N, A, LDA, WORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL SLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+      BNRM = SLANGE( 'M', M, NRHS, B, LDB, WORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Compute QR factorization with column pivoting of A:
+*        A * P = Q * R
+*
+      CALL SGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
+     $             LWORK-MN, INFO )
+      WSIZE = MN + WORK( MN+1 )
+*
+*     workspace: MN+2*N+NB*(N+1).
+*     Details of Householder rotations stored in WORK(1:MN).
+*
+*     Determine RANK using incremental condition estimation
+*
+      WORK( ISMIN ) = ONE
+      WORK( ISMAX ) = ONE
+      SMAX = ABS( A( 1, 1 ) )
+      SMIN = SMAX
+      IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
+         RANK = 0
+         CALL SLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
+         GO TO 70
+      ELSE
+         RANK = 1
+      END IF
+*
+   10 CONTINUE
+      IF( RANK.LT.MN ) THEN
+         I = RANK + 1
+         CALL SLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
+     $                A( I, I ), SMINPR, S1, C1 )
+         CALL SLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
+     $                A( I, I ), SMAXPR, S2, C2 )
+*
+         IF( SMAXPR*RCOND.LE.SMINPR ) THEN
+            DO 20 I = 1, RANK
+               WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
+               WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
+   20       CONTINUE
+            WORK( ISMIN+RANK ) = C1
+            WORK( ISMAX+RANK ) = C2
+            SMIN = SMINPR
+            SMAX = SMAXPR
+            RANK = RANK + 1
+            GO TO 10
+         END IF
+      END IF
+*
+*     workspace: 3*MN.
+*
+*     Logically partition R = [ R11 R12 ]
+*                             [  0  R22 ]
+*     where R11 = R(1:RANK,1:RANK)
+*
+*     [R11,R12] = [ T11, 0 ] * Y
+*
+      IF( RANK.LT.N )
+     $   CALL STZRZF( RANK, N, A, LDA, WORK( MN+1 ), WORK( 2*MN+1 ),
+     $                LWORK-2*MN, INFO )
+*
+*     workspace: 2*MN.
+*     Details of Householder rotations stored in WORK(MN+1:2*MN)
+*
+*     B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
+*
+      CALL SORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),
+     $             B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
+      WSIZE = MAX( WSIZE, 2*MN+WORK( 2*MN+1 ) )
+*
+*     workspace: 2*MN+NB*NRHS.
+*
+*     B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
+*
+      CALL STRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
+     $            NRHS, ONE, A, LDA, B, LDB )
+*
+      DO 40 J = 1, NRHS
+         DO 30 I = RANK + 1, N
+            B( I, J ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+*
+*     B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
+*
+      IF( RANK.LT.N ) THEN
+         CALL SORMRZ( 'Left', 'Transpose', N, NRHS, RANK, N-RANK, A,
+     $                LDA, WORK( MN+1 ), B, LDB, WORK( 2*MN+1 ),
+     $                LWORK-2*MN, INFO )
+      END IF
+*
+*     workspace: 2*MN+NRHS.
+*
+*     B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
+*
+      DO 60 J = 1, NRHS
+         DO 50 I = 1, N
+            WORK( JPVT( I ) ) = B( I, J )
+   50    CONTINUE
+         CALL SCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )
+   60 CONTINUE
+*
+*     workspace: N.
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL SLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   70 CONTINUE
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of SGELSY
+*
+      END
diff --git a/libcruft/lapack/sgeqp3.f b/libcruft/lapack/sgeqp3.f
new file mode 100644
index 0000000..0c0d9b8
--- /dev/null
+++ b/libcruft/lapack/sgeqp3.f
@@ -0,0 +1,284 @@
+      SUBROUTINE SGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEQP3 computes a QR factorization with column pivoting of a
+*  matrix A:  A*P = Q*R  using Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper trapezoidal matrix R; the elements below
+*          the diagonal, together with the array TAU, represent the
+*          orthogonal matrix Q as a product of min(M,N) elementary
+*          reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(J).ne.0, the J-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(J)=0,
+*          the J-th column of A is a free column.
+*          On exit, if JPVT(J)=K, then the J-th column of A*P was the
+*          the K-th column of A.
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= 3*N+1.
+*          For optimal performance LWORK >= 2*N+( N+1 )*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit.
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real/complex scalar, and v is a real/complex vector
+*  with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
+*  A(i+1:m,i), and tau in TAU(i).
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            INB, INBMIN, IXOVER
+      PARAMETER          ( INB = 1, INBMIN = 2, IXOVER = 3 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,
+     $                   NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEQRF, SLAQP2, SLAQPS, SORMQR, SSWAP, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               SNRM2
+      EXTERNAL           ILAENV, SNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         MINMN = MIN( M, N )
+         IF( MINMN.EQ.0 ) THEN
+            IWS = 1
+            LWKOPT = 1
+         ELSE
+            IWS = 3*N + 1
+            NB = ILAENV( INB, 'SGEQRF', ' ', M, N, -1, -1 )
+            LWKOPT = 2*N + ( N + 1 )*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEQP3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( MINMN.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Move initial columns up front.
+*
+      NFXD = 1
+      DO 10 J = 1, N
+         IF( JPVT( J ).NE.0 ) THEN
+            IF( J.NE.NFXD ) THEN
+               CALL SSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
+               JPVT( J ) = JPVT( NFXD )
+               JPVT( NFXD ) = J
+            ELSE
+               JPVT( J ) = J
+            END IF
+            NFXD = NFXD + 1
+         ELSE
+            JPVT( J ) = J
+         END IF
+   10 CONTINUE
+      NFXD = NFXD - 1
+*
+*     Factorize fixed columns
+*     =======================
+*
+*     Compute the QR factorization of fixed columns and update
+*     remaining columns.
+*
+      IF( NFXD.GT.0 ) THEN
+         NA = MIN( M, NFXD )
+*CC      CALL SGEQR2( M, NA, A, LDA, TAU, WORK, INFO )
+         CALL SGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
+         IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         IF( NA.LT.N ) THEN
+*CC         CALL SORM2R( 'Left', 'Transpose', M, N-NA, NA, A, LDA,
+*CC  $                   TAU, A( 1, NA+1 ), LDA, WORK, INFO )
+            CALL SORMQR( 'Left', 'Transpose', M, N-NA, NA, A, LDA, TAU,
+     $                   A( 1, NA+1 ), LDA, WORK, LWORK, INFO )
+            IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         END IF
+      END IF
+*
+*     Factorize free columns
+*     ======================
+*
+      IF( NFXD.LT.MINMN ) THEN
+*
+         SM = M - NFXD
+         SN = N - NFXD
+         SMINMN = MINMN - NFXD
+*
+*        Determine the block size.
+*
+         NB = ILAENV( INB, 'SGEQRF', ' ', SM, SN, -1, -1 )
+         NBMIN = 2
+         NX = 0
+*
+         IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
+*
+*           Determine when to cross over from blocked to unblocked code.
+*
+            NX = MAX( 0, ILAENV( IXOVER, 'SGEQRF', ' ', SM, SN, -1,
+     $           -1 ) )
+*
+*
+            IF( NX.LT.SMINMN ) THEN
+*
+*              Determine if workspace is large enough for blocked code.
+*
+               MINWS = 2*SN + ( SN+1 )*NB
+               IWS = MAX( IWS, MINWS )
+               IF( LWORK.LT.MINWS ) THEN
+*
+*                 Not enough workspace to use optimal NB: Reduce NB and
+*                 determine the minimum value of NB.
+*
+                  NB = ( LWORK-2*SN ) / ( SN+1 )
+                  NBMIN = MAX( 2, ILAENV( INBMIN, 'SGEQRF', ' ', SM, SN,
+     $                    -1, -1 ) )
+*
+*
+               END IF
+            END IF
+         END IF
+*
+*        Initialize partial column norms. The first N elements of work
+*        store the exact column norms.
+*
+         DO 20 J = NFXD + 1, N
+            WORK( J ) = SNRM2( SM, A( NFXD+1, J ), 1 )
+            WORK( N+J ) = WORK( J )
+   20    CONTINUE
+*
+         IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
+     $       ( NX.LT.SMINMN ) ) THEN
+*
+*           Use blocked code initially.
+*
+            J = NFXD + 1
+*
+*           Compute factorization: while loop.
+*
+*
+            TOPBMN = MINMN - NX
+   30       CONTINUE
+            IF( J.LE.TOPBMN ) THEN
+               JB = MIN( NB, TOPBMN-J+1 )
+*
+*              Factorize JB columns among columns J:N.
+*
+               CALL SLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
+     $                      JPVT( J ), TAU( J ), WORK( J ), WORK( N+J ),
+     $                      WORK( 2*N+1 ), WORK( 2*N+JB+1 ), N-J+1 )
+*
+               J = J + FJB
+               GO TO 30
+            END IF
+         ELSE
+            J = NFXD + 1
+         END IF
+*
+*        Use unblocked code to factor the last or only block.
+*
+*
+         IF( J.LE.MINMN )
+     $      CALL SLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
+     $                   TAU( J ), WORK( J ), WORK( N+J ),
+     $                   WORK( 2*N+1 ) )
+*
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SGEQP3
+*
+      END
diff --git a/libcruft/lapack/sgeqpf.f b/libcruft/lapack/sgeqpf.f
new file mode 100644
index 0000000..8a323d5
--- /dev/null
+++ b/libcruft/lapack/sgeqpf.f
@@ -0,0 +1,231 @@
+      SUBROUTINE SGEQPF( M, N, A, LDA, JPVT, TAU, WORK, INFO )
+*
+*  -- LAPACK deprecated driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This routine is deprecated and has been replaced by routine SGEQP3.
+*
+*  SGEQPF computes a QR factorization with column pivoting of a
+*  real M-by-N matrix A: A*P = Q*R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper triangular matrix R; the elements
+*          below the diagonal, together with the array TAU,
+*          represent the orthogonal matrix Q as a product of
+*          min(m,n) elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) REAL array, dimension (3*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(n)
+*
+*  Each H(i) has the form
+*
+*     H = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i).
+*
+*  The matrix P is represented in jpvt as follows: If
+*     jpvt(j) = i
+*  then the jth column of P is the ith canonical unit vector.
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MA, MN, PVT
+      REAL               AII, TEMP, TEMP2, TOL3Z
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEQR2, SLARF, SLARFG, SORM2R, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SLAMCH, SNRM2
+      EXTERNAL           ISAMAX, SLAMCH, SNRM2
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEQPF', -INFO )
+         RETURN
+      END IF
+*
+      MN = MIN( M, N )
+      TOL3Z = SQRT(SLAMCH('Epsilon'))
+*
+*     Move initial columns up front
+*
+      ITEMP = 1
+      DO 10 I = 1, N
+         IF( JPVT( I ).NE.0 ) THEN
+            IF( I.NE.ITEMP ) THEN
+               CALL SSWAP( M, A( 1, I ), 1, A( 1, ITEMP ), 1 )
+               JPVT( I ) = JPVT( ITEMP )
+               JPVT( ITEMP ) = I
+            ELSE
+               JPVT( I ) = I
+            END IF
+            ITEMP = ITEMP + 1
+         ELSE
+            JPVT( I ) = I
+         END IF
+   10 CONTINUE
+      ITEMP = ITEMP - 1
+*
+*     Compute the QR factorization and update remaining columns
+*
+      IF( ITEMP.GT.0 ) THEN
+         MA = MIN( ITEMP, M )
+         CALL SGEQR2( M, MA, A, LDA, TAU, WORK, INFO )
+         IF( MA.LT.N ) THEN
+            CALL SORM2R( 'Left', 'Transpose', M, N-MA, MA, A, LDA, TAU,
+     $                   A( 1, MA+1 ), LDA, WORK, INFO )
+         END IF
+      END IF
+*
+      IF( ITEMP.LT.MN ) THEN
+*
+*        Initialize partial column norms. The first n elements of
+*        work store the exact column norms.
+*
+         DO 20 I = ITEMP + 1, N
+            WORK( I ) = SNRM2( M-ITEMP, A( ITEMP+1, I ), 1 )
+            WORK( N+I ) = WORK( I )
+   20    CONTINUE
+*
+*        Compute factorization
+*
+         DO 40 I = ITEMP + 1, MN
+*
+*           Determine ith pivot column and swap if necessary
+*
+            PVT = ( I-1 ) + ISAMAX( N-I+1, WORK( I ), 1 )
+*
+            IF( PVT.NE.I ) THEN
+               CALL SSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+               ITEMP = JPVT( PVT )
+               JPVT( PVT ) = JPVT( I )
+               JPVT( I ) = ITEMP
+               WORK( PVT ) = WORK( I )
+               WORK( N+PVT ) = WORK( N+I )
+            END IF
+*
+*           Generate elementary reflector H(i)
+*
+            IF( I.LT.M ) THEN
+               CALL SLARFG( M-I+1, A( I, I ), A( I+1, I ), 1, TAU( I ) )
+            ELSE
+               CALL SLARFG( 1, A( M, M ), A( M, M ), 1, TAU( M ) )
+            END IF
+*
+            IF( I.LT.N ) THEN
+*
+*              Apply H(i) to A(i:m,i+1:n) from the left
+*
+               AII = A( I, I )
+               A( I, I ) = ONE
+               CALL SLARF( 'LEFT', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                     A( I, I+1 ), LDA, WORK( 2*N+1 ) )
+               A( I, I ) = AII
+            END IF
+*
+*           Update partial column norms
+*
+            DO 30 J = I + 1, N
+               IF( WORK( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*                 
+                  TEMP = ABS( A( I, J ) ) / WORK( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( WORK( J ) / WORK( N+J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN 
+                     IF( M-I.GT.0 ) THEN
+                        WORK( J ) = SNRM2( M-I, A( I+1, J ), 1 )
+                        WORK( N+J ) = WORK( J )
+                     ELSE
+                        WORK( J ) = ZERO
+                        WORK( N+J ) = ZERO
+                     END IF
+                  ELSE
+                     WORK( J ) = WORK( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   30       CONTINUE
+*
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SGEQPF
+*
+      END
diff --git a/libcruft/lapack/sgeqr2.f b/libcruft/lapack/sgeqr2.f
new file mode 100644
index 0000000..7b27a5a
--- /dev/null
+++ b/libcruft/lapack/sgeqr2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE SGEQR2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEQR2 computes a QR factorization of a real m by n matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(m,n) by n upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      REAL               AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SLARFG, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEQR2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+         CALL SLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                TAU( I ) )
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i) to A(i:m,i+1:n) from the left
+*
+            AII = A( I, I )
+            A( I, I ) = ONE
+            CALL SLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                  A( I, I+1 ), LDA, WORK )
+            A( I, I ) = AII
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of SGEQR2
+*
+      END
diff --git a/libcruft/lapack/sgeqrf.f b/libcruft/lapack/sgeqrf.f
new file mode 100644
index 0000000..ae52700
--- /dev/null
+++ b/libcruft/lapack/sgeqrf.f
@@ -0,0 +1,196 @@
+      SUBROUTINE SGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGEQRF computes a QR factorization of a real M-by-N matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(M,N)-by-N upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the orthogonal matrix Q as a
+*          product of min(m,n) elementary reflectors (see Further
+*          Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is 
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEQR2, SLARFB, SLARFT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGEQRF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'SGEQRF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'SGEQRF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the QR factorization of the current block
+*           A(i:m,i:i+ib-1)
+*
+            CALL SGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL SLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i:m,i+ib:n) from the left
+*
+               CALL SLARFB( 'Left', 'Transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL SGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SGEQRF
+*
+      END
diff --git a/libcruft/lapack/sgesv.f b/libcruft/lapack/sgesv.f
new file mode 100644
index 0000000..acb2f91
--- /dev/null
+++ b/libcruft/lapack/sgesv.f
@@ -0,0 +1,107 @@
+      SUBROUTINE SGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGESV computes the solution to a real system of linear equations
+*     A * X = B,
+*  where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
+*
+*  The LU decomposition with partial pivoting and row interchanges is
+*  used to factor A as
+*     A = P * L * U,
+*  where P is a permutation matrix, L is unit lower triangular, and U is
+*  upper triangular.  The factored form of A is then used to solve the
+*  system of equations A * X = B.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of linear equations, i.e., the order of the
+*          matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the N-by-N coefficient matrix A.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices that define the permutation matrix P;
+*          row i of the matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS matrix of right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero.  The factorization
+*                has been completed, but the factor U is exactly
+*                singular, so the solution could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           SGETRF, SGETRS, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGESV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the LU factorization of A.
+*
+      CALL SGETRF( N, N, A, LDA, IPIV, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL SGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, B, LDB,
+     $                INFO )
+      END IF
+      RETURN
+*
+*     End of SGESV
+*
+      END
diff --git a/libcruft/lapack/sgesvd.f b/libcruft/lapack/sgesvd.f
new file mode 100644
index 0000000..6217d03
--- /dev/null
+++ b/libcruft/lapack/sgesvd.f
@@ -0,0 +1,3402 @@
+      SUBROUTINE SGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBU, JOBVT
+      INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), S( * ), U( LDU, * ),
+     $                   VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGESVD computes the singular value decomposition (SVD) of a real
+*  M-by-N matrix A, optionally computing the left and/or right singular
+*  vectors. The SVD is written
+*
+*       A = U * SIGMA * transpose(V)
+*
+*  where SIGMA is an M-by-N matrix which is zero except for its
+*  min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
+*  V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
+*  are the singular values of A; they are real and non-negative, and
+*  are returned in descending order.  The first min(m,n) columns of
+*  U and V are the left and right singular vectors of A.
+*
+*  Note that the routine returns V**T, not V.
+*
+*  Arguments
+*  =========
+*
+*  JOBU    (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix U:
+*          = 'A':  all M columns of U are returned in array U:
+*          = 'S':  the first min(m,n) columns of U (the left singular
+*                  vectors) are returned in the array U;
+*          = 'O':  the first min(m,n) columns of U (the left singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no columns of U (no left singular vectors) are
+*                  computed.
+*
+*  JOBVT   (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix
+*          V**T:
+*          = 'A':  all N rows of V**T are returned in the array VT;
+*          = 'S':  the first min(m,n) rows of V**T (the right singular
+*                  vectors) are returned in the array VT;
+*          = 'O':  the first min(m,n) rows of V**T (the right singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no rows of V**T (no right singular vectors) are
+*                  computed.
+*
+*          JOBVT and JOBU cannot both be 'O'.
+*
+*  M       (input) INTEGER
+*          The number of rows of the input matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the input matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit,
+*          if JOBU = 'O',  A is overwritten with the first min(m,n)
+*                          columns of U (the left singular vectors,
+*                          stored columnwise);
+*          if JOBVT = 'O', A is overwritten with the first min(m,n)
+*                          rows of V**T (the right singular vectors,
+*                          stored rowwise);
+*          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
+*                          are destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  S       (output) REAL array, dimension (min(M,N))
+*          The singular values of A, sorted so that S(i) >= S(i+1).
+*
+*  U       (output) REAL array, dimension (LDU,UCOL)
+*          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
+*          If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
+*          if JOBU = 'S', U contains the first min(m,n) columns of U
+*          (the left singular vectors, stored columnwise);
+*          if JOBU = 'N' or 'O', U is not referenced.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= 1; if
+*          JOBU = 'S' or 'A', LDU >= M.
+*
+*  VT      (output) REAL array, dimension (LDVT,N)
+*          If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
+*          V**T;
+*          if JOBVT = 'S', VT contains the first min(m,n) rows of
+*          V**T (the right singular vectors, stored rowwise);
+*          if JOBVT = 'N' or 'O', VT is not referenced.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.  LDVT >= 1; if
+*          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
+*          if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
+*          superdiagonal elements of an upper bidiagonal matrix B
+*          whose diagonal is in S (not necessarily sorted). B
+*          satisfies A = U * B * VT, so it has the same singular values
+*          as A, and singular vectors related by U and VT.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if SBDSQR did not converge, INFO specifies how many
+*                superdiagonals of an intermediate bidiagonal form B
+*                did not converge to zero. See the description of WORK
+*                above for details.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
+     $                   WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
+      INTEGER            BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,
+     $                   ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
+     $                   MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
+     $                   NRVT, WRKBL
+      REAL               ANRM, BIGNUM, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SBDSQR, SGEBRD, SGELQF, SGEMM, SGEQRF, SLACPY,
+     $                   SLASCL, SLASET, SORGBR, SORGLQ, SORGQR, SORMBR,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           LSAME, ILAENV, SLAMCH, SLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      WNTUA = LSAME( JOBU, 'A' )
+      WNTUS = LSAME( JOBU, 'S' )
+      WNTUAS = WNTUA .OR. WNTUS
+      WNTUO = LSAME( JOBU, 'O' )
+      WNTUN = LSAME( JOBU, 'N' )
+      WNTVA = LSAME( JOBVT, 'A' )
+      WNTVS = LSAME( JOBVT, 'S' )
+      WNTVAS = WNTVA .OR. WNTVS
+      WNTVO = LSAME( JOBVT, 'O' )
+      WNTVN = LSAME( JOBVT, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
+     $         ( WNTVO .AND. WNTUO ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
+         INFO = -9
+      ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
+     $         ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( M.GE.N .AND. MINMN.GT.0 ) THEN
+*
+*           Compute space needed for SBDSQR
+*
+            MNTHR = ILAENV( 6, 'SGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            BDSPAC = 5*N
+            IF( M.GE.MNTHR ) THEN
+               IF( WNTUN ) THEN
+*
+*                 Path 1 (M much larger than N, JOBU='N')
+*
+                  MAXWRK = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 3*N+2*N*
+     $                     ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  IF( WNTVO .OR. WNTVAS )
+     $               MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
+     $                        ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = MAX( MAXWRK, BDSPAC )
+                  MINWRK = MAX( 4*N, BDSPAC )
+               ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUS .AND. WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUS .AND. WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUS .AND. WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUA .AND. WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUA .AND. WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               ELSE IF( WNTUA .AND. WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+2*N*
+     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+N*
+     $                    ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*N+( N-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = MAX( 3*N+M, BDSPAC )
+               END IF
+            ELSE
+*
+*              Path 10 (M at least N, but not much larger)
+*
+               MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'SGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTUS .OR. WNTUO )
+     $            MAXWRK = MAX( MAXWRK, 3*N+N*
+     $                     ILAENV( 1, 'SORGBR', 'Q', M, N, N, -1 ) )
+               IF( WNTUA )
+     $            MAXWRK = MAX( MAXWRK, 3*N+M*
+     $                     ILAENV( 1, 'SORGBR', 'Q', M, M, N, -1 ) )
+               IF( .NOT.WNTVN )
+     $            MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
+     $                     ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, BDSPAC )
+               MINWRK = MAX( 3*N+M, BDSPAC )
+            END IF
+         ELSE IF( MINMN.GT.0 ) THEN
+*
+*           Compute space needed for SBDSQR
+*
+            MNTHR = ILAENV( 6, 'SGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            BDSPAC = 5*M
+            IF( N.GE.MNTHR ) THEN
+               IF( WNTVN ) THEN
+*
+*                 Path 1t(N much larger than M, JOBVT='N')
+*
+                  MAXWRK = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M+2*M*
+     $                     ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  IF( WNTUO .OR. WNTUAS )
+     $               MAXWRK = MAX( MAXWRK, 3*M+M*
+     $                        ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, BDSPAC )
+                  MINWRK = MAX( 4*M, BDSPAC )
+               ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*                 Path 3t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVS .AND. WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVS .AND. WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MAXWRK = MAX( MAXWRK, MINWRK )
+               ELSE IF( WNTVS .AND. WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVA .AND. WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVA .AND. WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               ELSE IF( WNTVA .AND. WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+2*M*
+     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+( M-1 )*
+     $                    ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 3*M+M*
+     $                    ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, BDSPAC )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = MAX( 3*M+N, BDSPAC )
+               END IF
+            ELSE
+*
+*              Path 10t(N greater than M, but not much larger)
+*
+               MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'SGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTVS .OR. WNTVO )
+     $            MAXWRK = MAX( MAXWRK, 3*M+M*
+     $                     ILAENV( 1, 'SORGBR', 'P', M, N, M, -1 ) )
+               IF( WNTVA )
+     $            MAXWRK = MAX( MAXWRK, 3*M+N*
+     $                     ILAENV( 1, 'SORGBR', 'P', N, N, M, -1 ) )
+               IF( .NOT.WNTUN )
+     $            MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
+     $                     ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+               MAXWRK = MAX( MAXWRK, BDSPAC )
+               MINWRK = MAX( 3*M+N, BDSPAC )
+            END IF
+         END IF
+         MAXWRK = MAX( MAXWRK, MINWRK )
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGESVD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SQRT( SLAMCH( 'S' ) ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = SLANGE( 'M', M, N, A, LDA, DUM )
+      ISCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ISCL = 1
+         CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ISCL = 1
+         CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        A has at least as many rows as columns. If A has sufficiently
+*        more rows than columns, first reduce using the QR
+*        decomposition (if sufficient workspace available)
+*
+         IF( M.GE.MNTHR ) THEN
+*
+            IF( WNTUN ) THEN
+*
+*              Path 1 (M much larger than N, JOBU='N')
+*              No left singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + N
+*
+*              Compute A=Q*R
+*              (Workspace: need 2*N, prefer N+N*NB)
+*
+               CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out below R
+*
+               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+               IE = 1
+               ITAUQ = IE + N
+               ITAUP = ITAUQ + N
+               IWORK = ITAUP + N
+*
+*              Bidiagonalize R in A
+*              (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+               CALL SGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               NCVT = 0
+               IF( WNTVO .OR. WNTVAS ) THEN
+*
+*                 If right singular vectors desired, generate P'.
+*                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                  CALL SORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  NCVT = N
+               END IF
+               IWORK = IE + N
+*
+*              Perform bidiagonal QR iteration, computing right
+*              singular vectors of A in A if desired
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,
+     $                      DUM, 1, DUM, 1, WORK( IWORK ), INFO )
+*
+*              If right singular vectors desired in VT, copy them there
+*
+               IF( WNTVAS )
+     $            CALL SLACPY( 'F', N, N, A, LDA, VT, LDVT )
+*
+            ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*              Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*              N left singular vectors to be overwritten on A and
+*              no right singular vectors to be computed
+*
+               IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N, WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N-N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to WORK(IR) and zero out below it
+*
+                  CALL SLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
+                  CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
+     $                         LDWRKR )
+*
+*                 Generate Q in A
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in WORK(IR)
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                  CALL SGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing R
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                  CALL SORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR)
+*                 (Workspace: need N*N+BDSPAC)
+*
+                  CALL SBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,
+     $                         WORK( IR ), LDWRKR, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + N
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
+*
+                  DO 10 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL SGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL SLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   10             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize A
+*                 (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*
+                  CALL SGEBRD( M, N, A, LDA, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing A
+*                 (Workspace: need 4*N, prefer 3*N+N*NB)
+*
+                  CALL SORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A
+*                 (Workspace: need BDSPAC)
+*
+                  CALL SBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,
+     $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*              Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
+*              N left singular vectors to be overwritten on A and
+*              N right singular vectors to be computed in VT
+*
+               IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N and WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N-N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL SLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                  CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT, copying result to WORK(IR)
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                  CALL SGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL SLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
+*
+*                 Generate left vectors bidiagonalizing R in WORK(IR)
+*                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                  CALL SORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)
+*
+                  CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR) and computing right
+*                 singular vectors of R in VT
+*                 (Workspace: need N*N+BDSPAC)
+*
+                  CALL SBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,
+     $                         WORK( IR ), LDWRKR, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + N
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
+*
+                  DO 20 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL SGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL SLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   20             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (Workspace: need 2*N, prefer N+N*NB)
+*
+                  CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL SLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (Workspace: need 2*N, prefer N+N*NB)
+*
+                  CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + N
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT
+*                 (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                  CALL SGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply Q in A by left vectors bidiagonalizing R
+*                 (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                  CALL SORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                  CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A and computing right
+*                 singular vectors of A in VT
+*                 (Workspace: need BDSPAC)
+*
+                  CALL SBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,
+     $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUS ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*                 N left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left vectors bidiagonalizing R in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL SORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
+     $                            1, WORK( IR ), LDWRKR, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IR), storing result in U
+*                    (Workspace: need N*N)
+*
+                     CALL SGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
+     $                           WORK( IR ), LDWRKR, ZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SORGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL SORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
+     $                            1, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*
+                     CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*N*N+4*N,
+*                                prefer 2*N*N+3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
+*
+                     CALL SORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*N*N+4*N-1,
+*                                prefer 2*N*N+3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (Workspace: need 2*N*N+BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (Workspace: need N*N)
+*
+                     CALL SGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
+*
+*                    Copy right singular vectors of R to A
+*                    (Workspace: need N*N)
+*
+                     CALL SLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SORGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL SORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing R in A
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
+     $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S'
+*                         or 'A')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL SORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need N*N+4*N-1,
+*                                prefer N*N+3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (Workspace: need N*N)
+*
+                     CALL SGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SORGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to VT, zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL SORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTUA ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*                 M left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in U
+*                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*
+                     CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL SORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
+     $                            1, WORK( IR ), LDWRKR, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IR), storing result in A
+*                    (Workspace: need N*N)
+*
+                     CALL SGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
+     $                           WORK( IR ), LDWRKR, ZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL SLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N+M, prefer N+M*NB)
+*
+                     CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL SORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
+     $                            1, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
+*
+                     CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*N*N+4*N,
+*                                prefer 2*N*N+3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
+*
+                     CALL SORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*N*N+4*N-1,
+*                                prefer 2*N*N+3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (Workspace: need 2*N*N+BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (Workspace: need N*N)
+*
+                     CALL SGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL SLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+*                    Copy right singular vectors of R from WORK(IR) to A
+*
+                     CALL SLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N+M, prefer N+M*NB)
+*
+                     CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                            LDA )
+*
+*                    Bidiagonalize R in A
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL SORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in A
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
+     $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S'
+*                         or 'A')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*
+                     CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*
+                     CALL SORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need N*N+4*N-1,
+*                                prefer N*N+3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (Workspace: need N*N+BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (Workspace: need N*N)
+*
+                     CALL SGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL SLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (Workspace: need 2*N, prefer N+N*NB)
+*
+                     CALL SGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (Workspace: need N+M, prefer N+M*NB)
+*
+                     CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R from A to VT, zeroing out below it
+*
+                     CALL SLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = ITAU
+                     ITAUQ = IE + N
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*
+                     CALL SGEBRD( N, N, VT, LDVT, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*
+                     CALL SORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+                     CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           M .LT. MNTHR
+*
+*           Path 10 (M at least N, but not much larger)
+*           Reduce to bidiagonal form without QR decomposition
+*
+            IE = 1
+            ITAUQ = IE + N
+            ITAUP = ITAUQ + N
+            IWORK = ITAUP + N
+*
+*           Bidiagonalize A
+*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*
+            CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)
+*
+               CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
+               IF( WNTUS )
+     $            NCU = N
+               IF( WNTUA )
+     $            NCU = M
+               CALL SORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+               CALL SLACPY( 'U', N, N, A, LDA, VT, LDVT )
+               CALL SORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*N, prefer 3*N+N*NB)
+*
+               CALL SORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*
+               CALL SORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IWORK = IE + N
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
+     $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
+            END IF
+*
+         END IF
+*
+      ELSE
+*
+*        A has more columns than rows. If A has sufficiently more
+*        columns than rows, first reduce using the LQ decomposition (if
+*        sufficient workspace available)
+*
+         IF( N.GE.MNTHR ) THEN
+*
+            IF( WNTVN ) THEN
+*
+*              Path 1t(N much larger than M, JOBVT='N')
+*              No right singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + M
+*
+*              Compute A=L*Q
+*              (Workspace: need 2*M, prefer M+M*NB)
+*
+               CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out above L
+*
+               CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
+               IE = 1
+               ITAUQ = IE + M
+               ITAUP = ITAUQ + M
+               IWORK = ITAUP + M
+*
+*              Bidiagonalize L in A
+*              (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+               CALL SGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               IF( WNTUO .OR. WNTUAS ) THEN
+*
+*                 If left singular vectors desired, generate Q
+*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                  CALL SORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+               END IF
+               IWORK = IE + M
+               NRU = 0
+               IF( WNTUO .OR. WNTUAS )
+     $            NRU = M
+*
+*              Perform bidiagonal QR iteration, computing left singular
+*              vectors of A in A if desired
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,
+     $                      LDA, DUM, 1, WORK( IWORK ), INFO )
+*
+*              If left singular vectors desired in U, copy them there
+*
+               IF( WNTUAS )
+     $            CALL SLACPY( 'F', M, M, A, LDA, U, LDU )
+*
+            ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*              Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              no left singular vectors to be computed
+*
+               IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M-M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to WORK(IR) and zero out above it
+*
+                  CALL SLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
+                  CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                         WORK( IR+LDWRKR ), LDWRKR )
+*
+*                 Generate Q in A
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in WORK(IR)
+*                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                  CALL SGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing L
+*                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*
+                  CALL SORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of L in WORK(IR)
+*                 (Workspace: need M*M+BDSPAC)
+*
+                  CALL SBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
+     $                         WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + M
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (Workspace: need M*M+2*M, prefer M*M+M*N+M)
+*
+                  DO 30 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL SGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL SLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   30             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize A
+*                 (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+                  CALL SGEBRD( M, N, A, LDA, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing A
+*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                  CALL SORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of A in A
+*                 (Workspace: need BDSPAC)
+*
+                  CALL SBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,
+     $                         DUM, 1, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*              Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              M left singular vectors to be computed in U
+*
+               IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M-M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing about above it
+*
+                  CALL SLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                  CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U, copying result to WORK(IR)
+*                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                  CALL SGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL SLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
+*
+*                 Generate right vectors bidiagonalizing L in WORK(IR)
+*                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*
+                  CALL SORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*
+                  CALL SORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of L in U, and computing right
+*                 singular vectors of L in WORK(IR)
+*                 (Workspace: need M*M+BDSPAC)
+*
+                  CALL SBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                         WORK( IR ), LDWRKR, U, LDU, DUM, 1,
+     $                         WORK( IWORK ), INFO )
+                  IU = IE + M
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (Workspace: need M*M+2*M, prefer M*M+M*N+M))
+*
+                  DO 40 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL SGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, ZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL SLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   40             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (Workspace: need 2*M, prefer M+M*NB)
+*
+                  CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing out above it
+*
+                  CALL SLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (Workspace: need 2*M, prefer M+M*NB)
+*
+                  CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = ITAU
+                  ITAUQ = IE + M
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U
+*                 (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                  CALL SGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply right vectors bidiagonalizing L by Q in A
+*                 (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                  CALL SORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
+     $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                  CALL SORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in U and computing right
+*                 singular vectors of A in A
+*                 (Workspace: need BDSPAC)
+*
+                  CALL SBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,
+     $                         U, LDU, DUM, 1, WORK( IWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVS ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing L in
+*                    WORK(IR)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL SORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in A, storing result in VT
+*                    (Workspace: need M*M)
+*
+                     CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
+     $                           LDWRKR, A, LDA, ZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy result to VT
+*
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL SORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
+     $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out below it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*
+                     CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*M*M+4*M,
+*                                prefer 2*M*M+3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*M*M+4*M-1,
+*                                prefer 2*M*M+3*M+(M-1)*NB)
+*
+                     CALL SORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (Workspace: need 2*M*M+BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (Workspace: need M*M)
+*
+                     CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
+*
+*                    Copy left singular vectors of L to A
+*                    (Workspace: need M*M)
+*
+                     CALL SLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL SORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors of L in A
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, compute left
+*                    singular vectors of A in A and compute right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need M*M+4*M-1,
+*                                prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL SORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (Workspace: need M*M)
+*
+                     CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                            LDU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL SORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTVA ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
+*
+                     CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need M*M+4*M-1,
+*                                prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL SORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
+     $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in VT, storing result in A
+*                    (Workspace: need M*M)
+*
+                     CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
+     $                           LDWRKR, VT, LDVT, ZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL SLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M+N, prefer M+N*NB)
+*
+                     CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL SORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
+     $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
+*
+                     CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (Workspace: need 2*M*M+4*M,
+*                                prefer 2*M*M+3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need 2*M*M+4*M-1,
+*                                prefer 2*M*M+3*M+(M-1)*NB)
+*
+                     CALL SORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (Workspace: need 2*M*M+BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (Workspace: need M*M)
+*
+                     CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL SLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy left singular vectors of A from WORK(IR) to A
+*
+                     CALL SLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M+N, prefer M+N*NB)
+*
+                     CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
+     $                            LDA )
+*
+*                    Bidiagonalize L in A
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, A, LDA, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL SORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in A
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in A and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is M by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
+*
+                     CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            WORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
+*
+                     CALL SORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (Workspace: need M*M+BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
+     $                            WORK( IWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (Workspace: need M*M)
+*
+                     CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL SLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (Workspace: need 2*M, prefer M+M*NB)
+*
+                     CALL SGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (Workspace: need M+N, prefer M+N*NB)
+*
+                     CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL SLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL SLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
+     $                            LDU )
+                     IE = ITAU
+                     ITAUQ = IE + M
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*
+                     CALL SGEBRD( M, M, U, LDU, S, WORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*
+                     CALL SORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+                     CALL SORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (Workspace: need BDSPAC)
+*
+                     CALL SBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
+     $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           N .LT. MNTHR
+*
+*           Path 10t(N greater than M, but not much larger)
+*           Reduce to bidiagonal form without LQ decomposition
+*
+            IE = 1
+            ITAUQ = IE + M
+            ITAUP = ITAUQ + M
+            IWORK = ITAUP + M
+*
+*           Bidiagonalize A
+*           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*
+            CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
+*
+               CALL SLACPY( 'L', M, M, A, LDA, U, LDU )
+               CALL SORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)
+*
+               CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
+               IF( WNTVA )
+     $            NRVT = N
+               IF( WNTVS )
+     $            NRVT = M
+               CALL SORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
+*
+               CALL SORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (Workspace: need 4*M, prefer 3*M+M*NB)
+*
+               CALL SORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IWORK = IE + M
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
+     $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (Workspace: need BDSPAC)
+*
+               CALL SBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
+     $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
+            END IF
+*
+         END IF
+*
+      END IF
+*
+*     If SBDSQR failed to converge, copy unconverged superdiagonals
+*     to WORK( 2:MINMN )
+*
+      IF( INFO.NE.0 ) THEN
+         IF( IE.GT.2 ) THEN
+            DO 50 I = 1, MINMN - 1
+               WORK( I+1 ) = WORK( I+IE-1 )
+   50       CONTINUE
+         END IF
+         IF( IE.LT.2 ) THEN
+            DO 60 I = MINMN - 1, 1, -1
+               WORK( I+1 ) = WORK( I+IE-1 )
+   60       CONTINUE
+         END IF
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ISCL.EQ.1 ) THEN
+         IF( ANRM.GT.BIGNUM )
+     $      CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
+     $      CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),
+     $                   MINMN, IERR )
+         IF( ANRM.LT.SMLNUM )
+     $      CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
+     $      CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),
+     $                   MINMN, IERR )
+      END IF
+*
+*     Return optimal workspace in WORK(1)
+*
+      WORK( 1 ) = MAXWRK
+*
+      RETURN
+*
+*     End of SGESVD
+*
+      END
diff --git a/libcruft/lapack/sgetf2.f b/libcruft/lapack/sgetf2.f
new file mode 100644
index 0000000..d5a045d
--- /dev/null
+++ b/libcruft/lapack/sgetf2.f
@@ -0,0 +1,147 @@
+      SUBROUTINE SGETF2( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGETF2 computes an LU factorization of a general m-by-n matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the m by n matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, U(k,k) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               SFMIN
+      INTEGER            I, J, JP
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      INTEGER            ISAMAX
+      EXTERNAL           SLAMCH, ISAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGER, SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGETF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Compute machine safe minimum 
+* 
+      SFMIN = SLAMCH('S')
+*
+      DO 10 J = 1, MIN( M, N )
+*
+*        Find pivot and test for singularity.
+*
+         JP = J - 1 + ISAMAX( M-J+1, A( J, J ), 1 )
+         IPIV( J ) = JP
+         IF( A( JP, J ).NE.ZERO ) THEN
+*
+*           Apply the interchange to columns 1:N.
+*
+            IF( JP.NE.J )
+     $         CALL SSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA )
+*
+*           Compute elements J+1:M of J-th column.
+*
+            IF( J.LT.M ) THEN 
+               IF( ABS(A( J, J )) .GE. SFMIN ) THEN 
+                  CALL SSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 ) 
+               ELSE 
+                 DO 20 I = 1, M-J 
+                    A( J+I, J ) = A( J+I, J ) / A( J, J ) 
+   20            CONTINUE 
+               END IF 
+            END IF 
+*
+         ELSE IF( INFO.EQ.0 ) THEN
+*
+            INFO = J
+         END IF
+*
+         IF( J.LT.MIN( M, N ) ) THEN
+*
+*           Update trailing submatrix.
+*
+            CALL SGER( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ), LDA,
+     $                 A( J+1, J+1 ), LDA )
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of SGETF2
+*
+      END
diff --git a/libcruft/lapack/sgetrf.f b/libcruft/lapack/sgetrf.f
new file mode 100644
index 0000000..7f3c90a
--- /dev/null
+++ b/libcruft/lapack/sgetrf.f
@@ -0,0 +1,159 @@
+      SUBROUTINE SGETRF( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGETRF computes an LU factorization of a general M-by-N matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IINFO, J, JB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SGETF2, SLASWP, STRSM, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGETRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'SGETRF', ' ', M, N, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN
+*
+*        Use unblocked code.
+*
+         CALL SGETF2( M, N, A, LDA, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         DO 20 J = 1, MIN( M, N ), NB
+            JB = MIN( MIN( M, N )-J+1, NB )
+*
+*           Factor diagonal and subdiagonal blocks and test for exact
+*           singularity.
+*
+            CALL SGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+*
+*           Adjust INFO and the pivot indices.
+*
+            IF( INFO.EQ.0 .AND. IINFO.GT.0 )
+     $         INFO = IINFO + J - 1
+            DO 10 I = J, MIN( M, J+JB-1 )
+               IPIV( I ) = J - 1 + IPIV( I )
+   10       CONTINUE
+*
+*           Apply interchanges to columns 1:J-1.
+*
+            CALL SLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 )
+*
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply interchanges to columns J+JB:N.
+*
+               CALL SLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1,
+     $                      IPIV, 1 )
+*
+*              Compute block row of U.
+*
+               CALL STRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB,
+     $                     N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ),
+     $                     LDA )
+               IF( J+JB.LE.M ) THEN
+*
+*                 Update trailing submatrix.
+*
+                  CALL SGEMM( 'No transpose', 'No transpose', M-J-JB+1,
+     $                        N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA,
+     $                        A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ),
+     $                        LDA )
+               END IF
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SGETRF
+*
+      END
diff --git a/libcruft/lapack/sgetri.f b/libcruft/lapack/sgetri.f
new file mode 100644
index 0000000..3eb1f34
--- /dev/null
+++ b/libcruft/lapack/sgetri.f
@@ -0,0 +1,192 @@
+      SUBROUTINE SGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGETRI computes the inverse of a matrix using the LU factorization
+*  computed by SGETRF.
+*
+*  This method inverts U and then computes inv(A) by solving the system
+*  inv(A)*L = inv(U) for inv(A).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the factors L and U from the factorization
+*          A = P*L*U as computed by SGETRF.
+*          On exit, if INFO = 0, the inverse of the original matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from SGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, then WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimal performance LWORK >= N*NB, where NB is
+*          the optimal blocksize returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero; the matrix is
+*                singular and its inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SGEMV, SSWAP, STRSM, STRTRI, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NB = ILAENV( 1, 'SGETRI', ' ', N, -1, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -3
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGETRI', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form inv(U).  If INFO > 0 from STRTRI, then U is singular,
+*     and the inverse is not computed.
+*
+      CALL STRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+      NBMIN = 2
+      LDWORK = N
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+         IWS = MAX( LDWORK*NB, 1 )
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'SGETRI', ' ', N, -1, -1, -1 ) )
+         END IF
+      ELSE
+         IWS = N
+      END IF
+*
+*     Solve the equation inv(A)*L = inv(U) for inv(A).
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         DO 20 J = N, 1, -1
+*
+*           Copy current column of L to WORK and replace with zeros.
+*
+            DO 10 I = J + 1, N
+               WORK( I ) = A( I, J )
+               A( I, J ) = ZERO
+   10       CONTINUE
+*
+*           Compute current column of inv(A).
+*
+            IF( J.LT.N )
+     $         CALL SGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),
+     $                     LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )
+   20    CONTINUE
+      ELSE
+*
+*        Use blocked code.
+*
+         NN = ( ( N-1 ) / NB )*NB + 1
+         DO 50 J = NN, 1, -NB
+            JB = MIN( NB, N-J+1 )
+*
+*           Copy current block column of L to WORK and replace with
+*           zeros.
+*
+            DO 40 JJ = J, J + JB - 1
+               DO 30 I = JJ + 1, N
+                  WORK( I+( JJ-J )*LDWORK ) = A( I, JJ )
+                  A( I, JJ ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+*
+*           Compute current block column of inv(A).
+*
+            IF( J+JB.LE.N )
+     $         CALL SGEMM( 'No transpose', 'No transpose', N, JB,
+     $                     N-J-JB+1, -ONE, A( 1, J+JB ), LDA,
+     $                     WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )
+            CALL STRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,
+     $                  ONE, WORK( J ), LDWORK, A( 1, J ), LDA )
+   50    CONTINUE
+      END IF
+*
+*     Apply column interchanges.
+*
+      DO 60 J = N - 1, 1, -1
+         JP = IPIV( J )
+         IF( JP.NE.J )
+     $      CALL SSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
+   60 CONTINUE
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SGETRI
+*
+      END
diff --git a/libcruft/lapack/sgetrs.f b/libcruft/lapack/sgetrs.f
new file mode 100644
index 0000000..3c82cf8
--- /dev/null
+++ b/libcruft/lapack/sgetrs.f
@@ -0,0 +1,149 @@
+      SUBROUTINE SGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGETRS solves a system of linear equations
+*     A * X = B  or  A' * X = B
+*  with a general N-by-N matrix A using the LU factorization computed
+*  by SGETRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A'* X = B  (Transpose)
+*          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by SGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from SGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASWP, STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGETRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve A * X = B.
+*
+*        Apply row interchanges to the right hand sides.
+*
+         CALL SLASWP( NRHS, B, LDB, 1, N, IPIV, 1 )
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A' * X = B.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Lower', 'Transpose', 'Unit', N, NRHS, ONE,
+     $               A, LDA, B, LDB )
+*
+*        Apply row interchanges to the solution vectors.
+*
+         CALL SLASWP( NRHS, B, LDB, 1, N, IPIV, -1 )
+      END IF
+*
+      RETURN
+*
+*     End of SGETRS
+*
+      END
diff --git a/libcruft/lapack/sggbak.f b/libcruft/lapack/sggbak.f
new file mode 100644
index 0000000..fddd264
--- /dev/null
+++ b/libcruft/lapack/sggbak.f
@@ -0,0 +1,220 @@
+      SUBROUTINE SGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,
+     $                   LDV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               LSCALE( * ), RSCALE( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGGBAK forms the right or left eigenvectors of a real generalized
+*  eigenvalue problem A*x = lambda*B*x, by backward transformation on
+*  the computed eigenvectors of the balanced pair of matrices output by
+*  SGGBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N':  do nothing, return immediately;
+*          = 'P':  do backward transformation for permutation only;
+*          = 'S':  do backward transformation for scaling only;
+*          = 'B':  do backward transformations for both permutation and
+*                  scaling.
+*          JOB must be the same as the argument JOB supplied to SGGBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by SGGBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  LSCALE  (input) REAL array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the left side of A and B, as returned by SGGBAL.
+*
+*  RSCALE  (input) REAL array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the right side of A and B, as returned by SGGBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) REAL array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by STGEVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the matrix V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. Ward, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, K
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( N.EQ.0 .AND. IHI.EQ.0 .AND. ILO.NE.1 ) THEN
+         INFO = -4
+      ELSE IF( N.GT.0 .AND. ( IHI.LT.ILO .OR. IHI.GT.MAX( 1, N ) ) )
+     $   THEN
+         INFO = -5
+      ELSE IF( N.EQ.0 .AND. ILO.EQ.1 .AND. IHI.NE.0 ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -8
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGGBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward transformation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               CALL SSCAL( M, RSCALE( I ), V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+*        Backward transformation on left eigenvectors
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               CALL SSCAL( M, LSCALE( I ), V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Backward permutation
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward permutation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 50
+*
+            DO 40 I = ILO - 1, 1, -1
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL SSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+*
+   50       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 70
+            DO 60 I = IHI + 1, N
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 60
+               CALL SSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   60       CONTINUE
+         END IF
+*
+*        Backward permutation on left eigenvectors
+*
+   70    CONTINUE
+         IF( LEFTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 90
+            DO 80 I = ILO - 1, 1, -1
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 80
+               CALL SSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   80       CONTINUE
+*
+   90       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 110
+            DO 100 I = IHI + 1, N
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 100
+               CALL SSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+  100       CONTINUE
+         END IF
+      END IF
+*
+  110 CONTINUE
+*
+      RETURN
+*
+*     End of SGGBAK
+*
+      END
diff --git a/libcruft/lapack/sggbal.f b/libcruft/lapack/sggbal.f
new file mode 100644
index 0000000..9c82f37
--- /dev/null
+++ b/libcruft/lapack/sggbal.f
@@ -0,0 +1,469 @@
+      SUBROUTINE SGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
+     $                   RSCALE, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * ), LSCALE( * ),
+     $                   RSCALE( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGGBAL balances a pair of general real matrices (A,B).  This
+*  involves, first, permuting A and B by similarity transformations to
+*  isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
+*  elements on the diagonal; and second, applying a diagonal similarity
+*  transformation to rows and columns ILO to IHI to make the rows
+*  and columns as close in norm as possible. Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrices, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors in the
+*  generalized eigenvalue problem A*x = lambda*B*x.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A and B:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
+*                  and RSCALE(I) = 1.0 for i = 1,...,N.
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit,  A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  B       (input/output) REAL array, dimension (LDB,N)
+*          On entry, the input matrix B.
+*          On exit,  B is overwritten by the balanced matrix.
+*          If JOB = 'N', B is not referenced.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 and B(i,j) = 0 if i > j and
+*          j = 1,...,ILO-1 or i = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  LSCALE  (output) REAL array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the left side of A and B.  If P(j) is the index of the
+*          row interchanged with row j, and D(j)
+*          is the scaling factor applied to row j, then
+*            LSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  RSCALE  (output) REAL array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the right side of A and B.  If P(j) is the index of the
+*          column interchanged with column j, and D(j)
+*          is the scaling factor applied to column j, then
+*            LSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  WORK    (workspace) REAL array, dimension (lwork)
+*          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
+*          at least 1 when JOB = 'N' or 'P'.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. WARD, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
+      REAL               THREE, SCLFAC
+      PARAMETER          ( THREE = 3.0E+0, SCLFAC = 1.0E+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
+     $                   K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
+     $                   M, NR, NRP2
+      REAL               ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
+     $                   COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
+     $                   SFMIN, SUM, T, TA, TB, TC
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SDOT, SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SSCAL, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, LOG10, MAX, MIN, REAL, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGGBAL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         ILO = 1
+         IHI = N
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         ILO = 1
+         IHI = N
+         LSCALE( 1 ) = ONE
+         RSCALE( 1 ) = ONE
+         RETURN
+      END IF
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         ILO = 1
+         IHI = N
+         DO 10 I = 1, N
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 190
+*
+      GO TO 30
+*
+*     Permute the matrices A and B to isolate the eigenvalues.
+*
+*     Find row with one nonzero in columns 1 through L
+*
+   20 CONTINUE
+      L = LM1
+      IF( L.NE.1 )
+     $   GO TO 30
+*
+      RSCALE( 1 ) = ONE
+      LSCALE( 1 ) = ONE
+      GO TO 190
+*
+   30 CONTINUE
+      LM1 = L - 1
+      DO 80 I = L, 1, -1
+         DO 40 J = 1, LM1
+            JP1 = J + 1
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 50
+   40    CONTINUE
+         J = L
+         GO TO 70
+*
+   50    CONTINUE
+         DO 60 J = JP1, L
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 80
+   60    CONTINUE
+         J = JP1 - 1
+*
+   70    CONTINUE
+         M = L
+         IFLOW = 1
+         GO TO 160
+   80 CONTINUE
+      GO TO 100
+*
+*     Find column with one nonzero in rows K through N
+*
+   90 CONTINUE
+      K = K + 1
+*
+  100 CONTINUE
+      DO 150 J = K, L
+         DO 110 I = K, LM1
+            IP1 = I + 1
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 120
+  110    CONTINUE
+         I = L
+         GO TO 140
+  120    CONTINUE
+         DO 130 I = IP1, L
+            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
+     $         GO TO 150
+  130    CONTINUE
+         I = IP1 - 1
+  140    CONTINUE
+         M = K
+         IFLOW = 2
+         GO TO 160
+  150 CONTINUE
+      GO TO 190
+*
+*     Permute rows M and I
+*
+  160 CONTINUE
+      LSCALE( M ) = I
+      IF( I.EQ.M )
+     $   GO TO 170
+      CALL SSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
+      CALL SSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
+*
+*     Permute columns M and J
+*
+  170 CONTINUE
+      RSCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 180
+      CALL SSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL SSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
+*
+  180 CONTINUE
+      GO TO ( 20, 90 )IFLOW
+*
+  190 CONTINUE
+      ILO = K
+      IHI = L
+*
+      IF( LSAME( JOB, 'P' ) ) THEN
+         DO 195 I = ILO, IHI
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+  195    CONTINUE
+         RETURN
+      END IF
+*
+      IF( ILO.EQ.IHI )
+     $   RETURN
+*
+*     Balance the submatrix in rows ILO to IHI.
+*
+      NR = IHI - ILO + 1
+      DO 200 I = ILO, IHI
+         RSCALE( I ) = ZERO
+         LSCALE( I ) = ZERO
+*
+         WORK( I ) = ZERO
+         WORK( I+N ) = ZERO
+         WORK( I+2*N ) = ZERO
+         WORK( I+3*N ) = ZERO
+         WORK( I+4*N ) = ZERO
+         WORK( I+5*N ) = ZERO
+  200 CONTINUE
+*
+*     Compute right side vector in resulting linear equations
+*
+      BASL = LOG10( SCLFAC )
+      DO 240 I = ILO, IHI
+         DO 230 J = ILO, IHI
+            TB = B( I, J )
+            TA = A( I, J )
+            IF( TA.EQ.ZERO )
+     $         GO TO 210
+            TA = LOG10( ABS( TA ) ) / BASL
+  210       CONTINUE
+            IF( TB.EQ.ZERO )
+     $         GO TO 220
+            TB = LOG10( ABS( TB ) ) / BASL
+  220       CONTINUE
+            WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
+            WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
+  230    CONTINUE
+  240 CONTINUE
+*
+      COEF = ONE / REAL( 2*NR )
+      COEF2 = COEF*COEF
+      COEF5 = HALF*COEF2
+      NRP2 = NR + 2
+      BETA = ZERO
+      IT = 1
+*
+*     Start generalized conjugate gradient iteration
+*
+  250 CONTINUE
+*
+      GAMMA = SDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
+     $        SDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      EW = ZERO
+      EWC = ZERO
+      DO 260 I = ILO, IHI
+         EW = EW + WORK( I+4*N )
+         EWC = EWC + WORK( I+5*N )
+  260 CONTINUE
+*
+      GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
+      IF( GAMMA.EQ.ZERO )
+     $   GO TO 350
+      IF( IT.NE.1 )
+     $   BETA = GAMMA / PGAMMA
+      T = COEF5*( EWC-THREE*EW )
+      TC = COEF5*( EW-THREE*EWC )
+*
+      CALL SSCAL( NR, BETA, WORK( ILO ), 1 )
+      CALL SSCAL( NR, BETA, WORK( ILO+N ), 1 )
+*
+      CALL SAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
+      CALL SAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
+*
+      DO 270 I = ILO, IHI
+         WORK( I ) = WORK( I ) + TC
+         WORK( I+N ) = WORK( I+N ) + T
+  270 CONTINUE
+*
+*     Apply matrix to vector
+*
+      DO 300 I = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 290 J = ILO, IHI
+            IF( A( I, J ).EQ.ZERO )
+     $         GO TO 280
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  280       CONTINUE
+            IF( B( I, J ).EQ.ZERO )
+     $         GO TO 290
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  290    CONTINUE
+         WORK( I+2*N ) = REAL( KOUNT )*WORK( I+N ) + SUM
+  300 CONTINUE
+*
+      DO 330 J = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 320 I = ILO, IHI
+            IF( A( I, J ).EQ.ZERO )
+     $         GO TO 310
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  310       CONTINUE
+            IF( B( I, J ).EQ.ZERO )
+     $         GO TO 320
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  320    CONTINUE
+         WORK( J+3*N ) = REAL( KOUNT )*WORK( J ) + SUM
+  330 CONTINUE
+*
+      SUM = SDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
+     $      SDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
+      ALPHA = GAMMA / SUM
+*
+*     Determine correction to current iteration
+*
+      CMAX = ZERO
+      DO 340 I = ILO, IHI
+         COR = ALPHA*WORK( I+N )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         LSCALE( I ) = LSCALE( I ) + COR
+         COR = ALPHA*WORK( I )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         RSCALE( I ) = RSCALE( I ) + COR
+  340 CONTINUE
+      IF( CMAX.LT.HALF )
+     $   GO TO 350
+*
+      CALL SAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
+      CALL SAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      PGAMMA = GAMMA
+      IT = IT + 1
+      IF( IT.LE.NRP2 )
+     $   GO TO 250
+*
+*     End generalized conjugate gradient iteration
+*
+  350 CONTINUE
+      SFMIN = SLAMCH( 'S' )
+      SFMAX = ONE / SFMIN
+      LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
+      LSFMAX = INT( LOG10( SFMAX ) / BASL )
+      DO 360 I = ILO, IHI
+         IRAB = ISAMAX( N-ILO+1, A( I, ILO ), LDA )
+         RAB = ABS( A( I, IRAB+ILO-1 ) )
+         IRAB = ISAMAX( N-ILO+1, B( I, ILO ), LDB )
+         RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
+         LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
+         IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
+         IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
+         LSCALE( I ) = SCLFAC**IR
+         ICAB = ISAMAX( IHI, A( 1, I ), 1 )
+         CAB = ABS( A( ICAB, I ) )
+         ICAB = ISAMAX( IHI, B( 1, I ), 1 )
+         CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
+         LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
+         JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
+         JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
+         RSCALE( I ) = SCLFAC**JC
+  360 CONTINUE
+*
+*     Row scaling of matrices A and B
+*
+      DO 370 I = ILO, IHI
+         CALL SSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
+         CALL SSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
+  370 CONTINUE
+*
+*     Column scaling of matrices A and B
+*
+      DO 380 J = ILO, IHI
+         CALL SSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
+         CALL SSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
+  380 CONTINUE
+*
+      RETURN
+*
+*     End of SGGBAL
+*
+      END
diff --git a/libcruft/lapack/sggev.f b/libcruft/lapack/sggev.f
new file mode 100644
index 0000000..59dbe21
--- /dev/null
+++ b/libcruft/lapack/sggev.f
@@ -0,0 +1,489 @@
+      SUBROUTINE SGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,
+     $                  BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
+     $                   B( LDB, * ), BETA( * ), VL( LDVL, * ),
+     $                   VR( LDVR, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGGEV computes for a pair of N-by-N real nonsymmetric matrices (A,B)
+*  the generalized eigenvalues, and optionally, the left and/or right
+*  generalized eigenvectors.
+*
+*  A generalized eigenvalue for a pair of matrices (A,B) is a scalar
+*  lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
+*  singular. It is usually represented as the pair (alpha,beta), as
+*  there is a reasonable interpretation for beta=0, and even for both
+*  being zero.
+*
+*  The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
+*  of (A,B) satisfies
+*
+*                   A * v(j) = lambda(j) * B * v(j).
+*
+*  The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
+*  of (A,B) satisfies
+*
+*                   u(j)**H * A  = lambda(j) * u(j)**H * B .
+*
+*  where u(j)**H is the conjugate-transpose of u(j).
+*
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N':  do not compute the left generalized eigenvectors;
+*          = 'V':  compute the left generalized eigenvectors.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N':  do not compute the right generalized eigenvectors;
+*          = 'V':  compute the right generalized eigenvectors.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A, B, VL, and VR.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA, N)
+*          On entry, the matrix A in the pair (A,B).
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of A.  LDA >= max(1,N).
+*
+*  B       (input/output) REAL array, dimension (LDB, N)
+*          On entry, the matrix B in the pair (A,B).
+*          On exit, B has been overwritten.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of B.  LDB >= max(1,N).
+*
+*  ALPHAR  (output) REAL array, dimension (N)
+*  ALPHAI  (output) REAL array, dimension (N)
+*  BETA    (output) REAL array, dimension (N)
+*          On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
+*          be the generalized eigenvalues.  If ALPHAI(j) is zero, then
+*          the j-th eigenvalue is real; if positive, then the j-th and
+*          (j+1)-st eigenvalues are a complex conjugate pair, with
+*          ALPHAI(j+1) negative.
+*
+*          Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
+*          may easily over- or underflow, and BETA(j) may even be zero.
+*          Thus, the user should avoid naively computing the ratio
+*          alpha/beta.  However, ALPHAR and ALPHAI will be always less
+*          than and usually comparable with norm(A) in magnitude, and
+*          BETA always less than and usually comparable with norm(B).
+*
+*  VL      (output) REAL array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
+*          after another in the columns of VL, in the same order as
+*          their eigenvalues. If the j-th eigenvalue is real, then
+*          u(j) = VL(:,j), the j-th column of VL. If the j-th and
+*          (j+1)-th eigenvalues form a complex conjugate pair, then
+*          u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part)+abs(imag. part)=1.
+*          Not referenced if JOBVL = 'N'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the matrix VL. LDVL >= 1, and
+*          if JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) REAL array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
+*          after another in the columns of VR, in the same order as
+*          their eigenvalues. If the j-th eigenvalue is real, then
+*          v(j) = VR(:,j), the j-th column of VR. If the j-th and
+*          (j+1)-th eigenvalues form a complex conjugate pair, then
+*          v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part)+abs(imag. part)=1.
+*          Not referenced if JOBVR = 'N'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the matrix VR. LDVR >= 1, and
+*          if JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,8*N).
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          = 1,...,N:
+*                The QZ iteration failed.  No eigenvectors have been
+*                calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
+*                should be correct for j=INFO+1,...,N.
+*          > N:  =N+1: other than QZ iteration failed in SHGEQZ.
+*                =N+2: error return from STGEVC.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
+      CHARACTER          CHTEMP
+      INTEGER            ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
+     $                   IN, IRIGHT, IROWS, ITAU, IWRK, JC, JR, MAXWRK,
+     $                   MINWRK
+      REAL               ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
+     $                   SMLNUM, TEMP
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            LDUMMA( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ, SLABAD,
+     $                   SLACPY, SLASCL, SLASET, SORGQR, SORMQR, STGEVC,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           LSAME, ILAENV, SLAMCH, SLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode the input arguments
+*
+      IF( LSAME( JOBVL, 'N' ) ) THEN
+         IJOBVL = 1
+         ILVL = .FALSE.
+      ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
+         IJOBVL = 2
+         ILVL = .TRUE.
+      ELSE
+         IJOBVL = -1
+         ILVL = .FALSE.
+      END IF
+*
+      IF( LSAME( JOBVR, 'N' ) ) THEN
+         IJOBVR = 1
+         ILVR = .FALSE.
+      ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
+         IJOBVR = 2
+         ILVR = .TRUE.
+      ELSE
+         IJOBVR = -1
+         ILVR = .FALSE.
+      END IF
+      ILV = ILVL .OR. ILVR
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( IJOBVL.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( IJOBVR.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -12
+      ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -14
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV. The workspace is
+*       computed assuming ILO = 1 and IHI = N, the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = MAX( 1, 8*N )
+         MAXWRK = MAX( 1, N*( 7 +
+     $                 ILAENV( 1, 'SGEQRF', ' ', N, 1, N, 0 ) ) )
+         MAXWRK = MAX( MAXWRK, N*( 7 +
+     $                 ILAENV( 1, 'SORMQR', ' ', N, 1, N, 0 ) ) )
+         IF( ILVL ) THEN
+            MAXWRK = MAX( MAXWRK, N*( 7 +
+     $                 ILAENV( 1, 'SORGQR', ' ', N, 1, N, -1 ) ) )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
+     $      INFO = -16
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGGEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = SLANGE( 'M', N, N, A, LDA, WORK )
+      ILASCL = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ANRMTO = SMLNUM
+         ILASCL = .TRUE.
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ANRMTO = BIGNUM
+         ILASCL = .TRUE.
+      END IF
+      IF( ILASCL )
+     $   CALL SLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = SLANGE( 'M', N, N, B, LDB, WORK )
+      ILBSCL = .FALSE.
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+         BNRMTO = SMLNUM
+         ILBSCL = .TRUE.
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+         BNRMTO = BIGNUM
+         ILBSCL = .TRUE.
+      END IF
+      IF( ILBSCL )
+     $   CALL SLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
+*
+*     Permute the matrices A, B to isolate eigenvalues if possible
+*     (Workspace: need 6*N)
+*
+      ILEFT = 1
+      IRIGHT = N + 1
+      IWRK = IRIGHT + N
+      CALL SGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
+     $             WORK( IRIGHT ), WORK( IWRK ), IERR )
+*
+*     Reduce B to triangular form (QR decomposition of B)
+*     (Workspace: need N, prefer N*NB)
+*
+      IROWS = IHI + 1 - ILO
+      IF( ILV ) THEN
+         ICOLS = N + 1 - ILO
+      ELSE
+         ICOLS = IROWS
+      END IF
+      ITAU = IWRK
+      IWRK = ITAU + IROWS
+      CALL SGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
+     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
+*
+*     Apply the orthogonal transformation to matrix A
+*     (Workspace: need N, prefer N*NB)
+*
+      CALL SORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
+     $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
+     $             LWORK+1-IWRK, IERR )
+*
+*     Initialize VL
+*     (Workspace: need N, prefer N*NB)
+*
+      IF( ILVL ) THEN
+         CALL SLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )
+         IF( IROWS.GT.1 ) THEN
+            CALL SLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
+     $                   VL( ILO+1, ILO ), LDVL )
+         END IF
+         CALL SORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
+     $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
+      END IF
+*
+*     Initialize VR
+*
+      IF( ILVR )
+     $   CALL SLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )
+*
+*     Reduce to generalized Hessenberg form
+*     (Workspace: none needed)
+*
+      IF( ILV ) THEN
+*
+*        Eigenvectors requested -- work on whole matrix.
+*
+         CALL SGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
+     $                LDVL, VR, LDVR, IERR )
+      ELSE
+         CALL SGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
+     $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
+      END IF
+*
+*     Perform QZ algorithm (Compute eigenvalues, and optionally, the
+*     Schur forms and Schur vectors)
+*     (Workspace: need N)
+*
+      IWRK = ITAU
+      IF( ILV ) THEN
+         CHTEMP = 'S'
+      ELSE
+         CHTEMP = 'E'
+      END IF
+      CALL SHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
+     $             ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
+     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
+      IF( IERR.NE.0 ) THEN
+         IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
+            INFO = IERR
+         ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
+            INFO = IERR - N
+         ELSE
+            INFO = N + 1
+         END IF
+         GO TO 110
+      END IF
+*
+*     Compute Eigenvectors
+*     (Workspace: need 6*N)
+*
+      IF( ILV ) THEN
+         IF( ILVL ) THEN
+            IF( ILVR ) THEN
+               CHTEMP = 'B'
+            ELSE
+               CHTEMP = 'L'
+            END IF
+         ELSE
+            CHTEMP = 'R'
+         END IF
+         CALL STGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
+     $                VR, LDVR, N, IN, WORK( IWRK ), IERR )
+         IF( IERR.NE.0 ) THEN
+            INFO = N + 2
+            GO TO 110
+         END IF
+*
+*        Undo balancing on VL and VR and normalization
+*        (Workspace: none needed)
+*
+         IF( ILVL ) THEN
+            CALL SGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
+     $                   WORK( IRIGHT ), N, VL, LDVL, IERR )
+            DO 50 JC = 1, N
+               IF( ALPHAI( JC ).LT.ZERO )
+     $            GO TO 50
+               TEMP = ZERO
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 10 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
+   10             CONTINUE
+               ELSE
+                  DO 20 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
+     $                      ABS( VL( JR, JC+1 ) ) )
+   20             CONTINUE
+               END IF
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 50
+               TEMP = ONE / TEMP
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 30 JR = 1, N
+                     VL( JR, JC ) = VL( JR, JC )*TEMP
+   30             CONTINUE
+               ELSE
+                  DO 40 JR = 1, N
+                     VL( JR, JC ) = VL( JR, JC )*TEMP
+                     VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
+   40             CONTINUE
+               END IF
+   50       CONTINUE
+         END IF
+         IF( ILVR ) THEN
+            CALL SGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
+     $                   WORK( IRIGHT ), N, VR, LDVR, IERR )
+            DO 100 JC = 1, N
+               IF( ALPHAI( JC ).LT.ZERO )
+     $            GO TO 100
+               TEMP = ZERO
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 60 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
+   60             CONTINUE
+               ELSE
+                  DO 70 JR = 1, N
+                     TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
+     $                      ABS( VR( JR, JC+1 ) ) )
+   70             CONTINUE
+               END IF
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 100
+               TEMP = ONE / TEMP
+               IF( ALPHAI( JC ).EQ.ZERO ) THEN
+                  DO 80 JR = 1, N
+                     VR( JR, JC ) = VR( JR, JC )*TEMP
+   80             CONTINUE
+               ELSE
+                  DO 90 JR = 1, N
+                     VR( JR, JC ) = VR( JR, JC )*TEMP
+                     VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
+   90             CONTINUE
+               END IF
+  100       CONTINUE
+         END IF
+*
+*        End of eigenvector calculation
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ILASCL ) THEN
+         CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
+         CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
+      END IF
+*
+      IF( ILBSCL ) THEN
+         CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
+      END IF
+*
+  110 CONTINUE
+*
+      WORK( 1 ) = MAXWRK
+*
+      RETURN
+*
+*     End of SGGEV
+*
+      END
diff --git a/libcruft/lapack/sgghrd.f b/libcruft/lapack/sgghrd.f
new file mode 100644
index 0000000..db7c1e6
--- /dev/null
+++ b/libcruft/lapack/sgghrd.f
@@ -0,0 +1,264 @@
+      SUBROUTINE SGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
+     $                   LDQ, Z, LDZ, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ
+      INTEGER            IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGGHRD reduces a pair of real matrices (A,B) to generalized upper
+*  Hessenberg form using orthogonal transformations, where A is a
+*  general matrix and B is upper triangular.  The form of the
+*  generalized eigenvalue problem is
+*     A*x = lambda*B*x,
+*  and B is typically made upper triangular by computing its QR
+*  factorization and moving the orthogonal matrix Q to the left side
+*  of the equation.
+*
+*  This subroutine simultaneously reduces A to a Hessenberg matrix H:
+*     Q**T*A*Z = H
+*  and transforms B to another upper triangular matrix T:
+*     Q**T*B*Z = T
+*  in order to reduce the problem to its standard form
+*     H*y = lambda*T*y
+*  where y = Z**T*x.
+*
+*  The orthogonal matrices Q and Z are determined as products of Givens
+*  rotations.  They may either be formed explicitly, or they may be
+*  postmultiplied into input matrices Q1 and Z1, so that
+*
+*       Q1 * A * Z1**T = (Q1*Q) * H * (Z1*Z)**T
+*
+*       Q1 * B * Z1**T = (Q1*Q) * T * (Z1*Z)**T
+*
+*  If Q1 is the orthogonal matrix from the QR factorization of B in the
+*  original equation A*x = lambda*B*x, then SGGHRD reduces the original
+*  problem to generalized Hessenberg form.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': do not compute Q;
+*          = 'I': Q is initialized to the unit matrix, and the
+*                 orthogonal matrix Q is returned;
+*          = 'V': Q must contain an orthogonal matrix Q1 on entry,
+*                 and the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': do not compute Z;
+*          = 'I': Z is initialized to the unit matrix, and the
+*                 orthogonal matrix Z is returned;
+*          = 'V': Z must contain an orthogonal matrix Z1 on entry,
+*                 and the product Z1*Z is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of A which are to be
+*          reduced.  It is assumed that A is already upper triangular
+*          in rows and columns 1:ILO-1 and IHI+1:N.  ILO and IHI are
+*          normally set by a previous call to SGGBAL; otherwise they
+*          should be set to 1 and N respectively.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) REAL array, dimension (LDA, N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          rest is set to zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) REAL array, dimension (LDB, N)
+*          On entry, the N-by-N upper triangular matrix B.
+*          On exit, the upper triangular matrix T = Q**T B Z.  The
+*          elements below the diagonal are set to zero.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  Q       (input/output) REAL array, dimension (LDQ, N)
+*          On entry, if COMPQ = 'V', the orthogonal matrix Q1,
+*          typically from the QR factorization of B.
+*          On exit, if COMPQ='I', the orthogonal matrix Q, and if
+*          COMPQ = 'V', the product Q1*Q.
+*          Not referenced if COMPQ='N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
+*
+*  Z       (input/output) REAL array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the orthogonal matrix Z1.
+*          On exit, if COMPZ='I', the orthogonal matrix Z, and if
+*          COMPZ = 'V', the product Z1*Z.
+*          Not referenced if COMPZ='N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.
+*          LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  This routine reduces A to Hessenberg and B to triangular form by
+*  an unblocked reduction, as described in _Matrix_Computations_,
+*  by Golub and Van Loan (Johns Hopkins Press.)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILQ, ILZ
+      INTEGER            ICOMPQ, ICOMPZ, JCOL, JROW
+      REAL               C, S, TEMP
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARTG, SLASET, SROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode COMPQ
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+*     Decode COMPZ
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ICOMPQ.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPZ.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THEN
+         INFO = -11
+      ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGGHRD', -INFO )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z if desired.
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL SLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL SLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Zero out lower triangle of B
+*
+      DO 20 JCOL = 1, N - 1
+         DO 10 JROW = JCOL + 1, N
+            B( JROW, JCOL ) = ZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     Reduce A and B
+*
+      DO 40 JCOL = ILO, IHI - 2
+*
+         DO 30 JROW = IHI, JCOL + 2, -1
+*
+*           Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)
+*
+            TEMP = A( JROW-1, JCOL )
+            CALL SLARTG( TEMP, A( JROW, JCOL ), C, S,
+     $                   A( JROW-1, JCOL ) )
+            A( JROW, JCOL ) = ZERO
+            CALL SROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,
+     $                 A( JROW, JCOL+1 ), LDA, C, S )
+            CALL SROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,
+     $                 B( JROW, JROW-1 ), LDB, C, S )
+            IF( ILQ )
+     $         CALL SROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C, S )
+*
+*           Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)
+*
+            TEMP = B( JROW, JROW )
+            CALL SLARTG( TEMP, B( JROW, JROW-1 ), C, S,
+     $                   B( JROW, JROW ) )
+            B( JROW, JROW-1 ) = ZERO
+            CALL SROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )
+            CALL SROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,
+     $                 S )
+            IF( ILZ )
+     $         CALL SROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )
+   30    CONTINUE
+   40 CONTINUE
+*
+      RETURN
+*
+*     End of SGGHRD
+*
+      END
diff --git a/libcruft/lapack/sgtsv.f b/libcruft/lapack/sgtsv.f
new file mode 100644
index 0000000..d43066b
--- /dev/null
+++ b/libcruft/lapack/sgtsv.f
@@ -0,0 +1,262 @@
+      SUBROUTINE SGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               B( LDB, * ), D( * ), DL( * ), DU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGTSV  solves the equation
+*
+*     A*X = B,
+*
+*  where A is an n by n tridiagonal matrix, by Gaussian elimination with
+*  partial pivoting.
+*
+*  Note that the equation  A'*X = B  may be solved by interchanging the
+*  order of the arguments DU and DL.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input/output) REAL array, dimension (N-1)
+*          On entry, DL must contain the (n-1) sub-diagonal elements of
+*          A.
+*
+*          On exit, DL is overwritten by the (n-2) elements of the
+*          second super-diagonal of the upper triangular matrix U from
+*          the LU factorization of A, in DL(1), ..., DL(n-2).
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*
+*          On exit, D is overwritten by the n diagonal elements of U.
+*
+*  DU      (input/output) REAL array, dimension (N-1)
+*          On entry, DU must contain the (n-1) super-diagonal elements
+*          of A.
+*
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          super-diagonal of U.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the N by NRHS matrix of right hand side matrix B.
+*          On exit, if INFO = 0, the N by NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, U(i,i) is exactly zero, and the solution
+*               has not been computed.  The factorization has not been
+*               completed unless i = N.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               FACT, TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGTSV ', -INFO )
+         RETURN
+      END IF
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( NRHS.EQ.1 ) THEN
+         DO 10 I = 1, N - 2
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+*
+*              No row interchange required
+*
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+               DL( I ) = ZERO
+            ELSE
+*
+*              Interchange rows I and I+1
+*
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DL( I ) = DU( I+1 )
+               DU( I+1 ) = -FACT*DL( I )
+               DU( I ) = TEMP
+               TEMP = B( I, 1 )
+               B( I, 1 ) = B( I+1, 1 )
+               B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )
+            END IF
+   10    CONTINUE
+         IF( N.GT.1 ) THEN
+            I = N - 1
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+            ELSE
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DU( I ) = TEMP
+               TEMP = B( I, 1 )
+               B( I, 1 ) = B( I+1, 1 )
+               B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )
+            END IF
+         END IF
+         IF( D( N ).EQ.ZERO ) THEN
+            INFO = N
+            RETURN
+         END IF
+      ELSE
+         DO 40 I = 1, N - 2
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+*
+*              No row interchange required
+*
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  DO 20 J = 1, NRHS
+                     B( I+1, J ) = B( I+1, J ) - FACT*B( I, J )
+   20             CONTINUE
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+               DL( I ) = ZERO
+            ELSE
+*
+*              Interchange rows I and I+1
+*
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DL( I ) = DU( I+1 )
+               DU( I+1 ) = -FACT*DL( I )
+               DU( I ) = TEMP
+               DO 30 J = 1, NRHS
+                  TEMP = B( I, J )
+                  B( I, J ) = B( I+1, J )
+                  B( I+1, J ) = TEMP - FACT*B( I+1, J )
+   30          CONTINUE
+            END IF
+   40    CONTINUE
+         IF( N.GT.1 ) THEN
+            I = N - 1
+            IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+               IF( D( I ).NE.ZERO ) THEN
+                  FACT = DL( I ) / D( I )
+                  D( I+1 ) = D( I+1 ) - FACT*DU( I )
+                  DO 50 J = 1, NRHS
+                     B( I+1, J ) = B( I+1, J ) - FACT*B( I, J )
+   50             CONTINUE
+               ELSE
+                  INFO = I
+                  RETURN
+               END IF
+            ELSE
+               FACT = D( I ) / DL( I )
+               D( I ) = DL( I )
+               TEMP = D( I+1 )
+               D( I+1 ) = DU( I ) - FACT*TEMP
+               DU( I ) = TEMP
+               DO 60 J = 1, NRHS
+                  TEMP = B( I, J )
+                  B( I, J ) = B( I+1, J )
+                  B( I+1, J ) = TEMP - FACT*B( I+1, J )
+   60          CONTINUE
+            END IF
+         END IF
+         IF( D( N ).EQ.ZERO ) THEN
+            INFO = N
+            RETURN
+         END IF
+      END IF
+*
+*     Back solve with the matrix U from the factorization.
+*
+      IF( NRHS.LE.2 ) THEN
+         J = 1
+   70    CONTINUE
+         B( N, J ) = B( N, J ) / D( N )
+         IF( N.GT.1 )
+     $      B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) / D( N-1 )
+         DO 80 I = N - 2, 1, -1
+            B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*
+     $                  B( I+2, J ) ) / D( I )
+   80    CONTINUE
+         IF( J.LT.NRHS ) THEN
+            J = J + 1
+            GO TO 70
+         END IF
+      ELSE
+         DO 100 J = 1, NRHS
+            B( N, J ) = B( N, J ) / D( N )
+            IF( N.GT.1 )
+     $         B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                       D( N-1 )
+            DO 90 I = N - 2, 1, -1
+               B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*
+     $                     B( I+2, J ) ) / D( I )
+   90       CONTINUE
+  100    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SGTSV
+*
+      END
diff --git a/libcruft/lapack/sgttrf.f b/libcruft/lapack/sgttrf.f
new file mode 100644
index 0000000..9ee59bc
--- /dev/null
+++ b/libcruft/lapack/sgttrf.f
@@ -0,0 +1,168 @@
+      SUBROUTINE SGTTRF( N, DL, D, DU, DU2, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGTTRF computes an LU factorization of a real tridiagonal matrix A
+*  using elimination with partial pivoting and row interchanges.
+*
+*  The factorization has the form
+*     A = L * U
+*  where L is a product of permutation and unit lower bidiagonal
+*  matrices and U is upper triangular with nonzeros in only the main
+*  diagonal and first two superdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  DL      (input/output) REAL array, dimension (N-1)
+*          On entry, DL must contain the (n-1) sub-diagonal elements of
+*          A.
+*
+*          On exit, DL is overwritten by the (n-1) multipliers that
+*          define the matrix L from the LU factorization of A.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*
+*          On exit, D is overwritten by the n diagonal elements of the
+*          upper triangular matrix U from the LU factorization of A.
+*
+*  DU      (input/output) REAL array, dimension (N-1)
+*          On entry, DU must contain the (n-1) super-diagonal elements
+*          of A.
+*
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          super-diagonal of U.
+*
+*  DU2     (output) REAL array, dimension (N-2)
+*          On exit, DU2 is overwritten by the (n-2) elements of the
+*          second super-diagonal of U.
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*          > 0:  if INFO = k, U(k,k) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      REAL               FACT, TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'SGTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Initialize IPIV(i) = i and DU2(I) = 0
+*
+      DO 10 I = 1, N
+         IPIV( I ) = I
+   10 CONTINUE
+      DO 20 I = 1, N - 2
+         DU2( I ) = ZERO
+   20 CONTINUE
+*
+      DO 30 I = 1, N - 2
+         IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+*
+*           No row interchange required, eliminate DL(I)
+*
+            IF( D( I ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+*
+*           Interchange rows I and I+1, eliminate DL(I)
+*
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            DU2( I ) = DU( I+1 )
+            DU( I+1 ) = -FACT*DU( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+   30 CONTINUE
+      IF( N.GT.1 ) THEN
+         I = N - 1
+         IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN
+            IF( D( I ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+      END IF
+*
+*     Check for a zero on the diagonal of U.
+*
+      DO 40 I = 1, N
+         IF( D( I ).EQ.ZERO ) THEN
+            INFO = I
+            GO TO 50
+         END IF
+   40 CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of SGTTRF
+*
+      END
diff --git a/libcruft/lapack/sgttrs.f b/libcruft/lapack/sgttrs.f
new file mode 100644
index 0000000..e45c487
--- /dev/null
+++ b/libcruft/lapack/sgttrs.f
@@ -0,0 +1,140 @@
+      SUBROUTINE SGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGTTRS solves one of the systems of equations
+*     A*X = B  or  A'*X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by SGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A'* X = B  (Transpose)
+*          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) REAL array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) REAL array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) REAL array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) REAL array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+      INTEGER            ITRANS, J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGTTS2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      NOTRAN = ( TRANS.EQ.'N' .OR. TRANS.EQ.'n' )
+      IF( .NOT.NOTRAN .AND. .NOT.( TRANS.EQ.'T' .OR. TRANS.EQ.
+     $    't' ) .AND. .NOT.( TRANS.EQ.'C' .OR. TRANS.EQ.'c' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDB.LT.MAX( N, 1 ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SGTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Decode TRANS
+*
+      IF( NOTRAN ) THEN
+         ITRANS = 0
+      ELSE
+         ITRANS = 1
+      END IF
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'SGTTRS', TRANS, N, NRHS, -1, -1 ) )
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL SGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL SGTTS2( ITRANS, N, JB, DL, D, DU, DU2, IPIV, B( 1, J ),
+     $                   LDB )
+   10    CONTINUE
+      END IF
+*
+*     End of SGTTRS
+*
+      END
diff --git a/libcruft/lapack/sgtts2.f b/libcruft/lapack/sgtts2.f
new file mode 100644
index 0000000..95448fd
--- /dev/null
+++ b/libcruft/lapack/sgtts2.f
@@ -0,0 +1,196 @@
+      SUBROUTINE SGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ITRANS, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SGTTS2 solves one of the systems of equations
+*     A*X = B  or  A'*X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by SGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITRANS  (input) INTEGER
+*          Specifies the form of the system of equations.
+*          = 0:  A * X = B  (No transpose)
+*          = 1:  A'* X = B  (Transpose)
+*          = 2:  A'* X = B  (Conjugate transpose = Transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) REAL array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) REAL array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) REAL array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) REAL array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IP, J
+      REAL               TEMP
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( ITRANS.EQ.0 ) THEN
+*
+*        Solve A*X = B using the LU factorization of A,
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+   10       CONTINUE
+*
+*           Solve L*x = b.
+*
+            DO 20 I = 1, N - 1
+               IP = IPIV( I )
+               TEMP = B( I+1-IP+I, J ) - DL( I )*B( IP, J )
+               B( I, J ) = B( IP, J )
+               B( I+1, J ) = TEMP
+   20       CONTINUE
+*
+*           Solve U*x = b.
+*
+            B( N, J ) = B( N, J ) / D( N )
+            IF( N.GT.1 )
+     $         B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                       D( N-1 )
+            DO 30 I = N - 2, 1, -1
+               B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                     B( I+2, J ) ) / D( I )
+   30       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 10
+            END IF
+         ELSE
+            DO 60 J = 1, NRHS
+*
+*              Solve L*x = b.
+*
+               DO 40 I = 1, N - 1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )
+                  ELSE
+                     TEMP = B( I, J )
+                     B( I, J ) = B( I+1, J )
+                     B( I+1, J ) = TEMP - DL( I )*B( I, J )
+                  END IF
+   40          CONTINUE
+*
+*              Solve U*x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               IF( N.GT.1 )
+     $            B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                          D( N-1 )
+               DO 50 I = N - 2, 1, -1
+                  B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                        B( I+2, J ) ) / D( I )
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      ELSE
+*
+*        Solve A' * X = B.
+*
+         IF( NRHS.LE.1 ) THEN
+*
+*           Solve U'*x = b.
+*
+            J = 1
+   70       CONTINUE
+            B( 1, J ) = B( 1, J ) / D( 1 )
+            IF( N.GT.1 )
+     $         B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+            DO 80 I = 3, N
+               B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-DU2( I-2 )*
+     $                     B( I-2, J ) ) / D( I )
+   80       CONTINUE
+*
+*           Solve L'*x = b.
+*
+            DO 90 I = N - 1, 1, -1
+               IP = IPIV( I )
+               TEMP = B( I, J ) - DL( I )*B( I+1, J )
+               B( I, J ) = B( IP, J )
+               B( IP, J ) = TEMP
+   90       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 70
+            END IF
+*
+         ELSE
+            DO 120 J = 1, NRHS
+*
+*              Solve U'*x = b.
+*
+               B( 1, J ) = B( 1, J ) / D( 1 )
+               IF( N.GT.1 )
+     $            B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+               DO 100 I = 3, N
+                  B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-
+     $                        DU2( I-2 )*B( I-2, J ) ) / D( I )
+  100          CONTINUE
+               DO 110 I = N - 1, 1, -1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I, J ) = B( I, J ) - DL( I )*B( I+1, J )
+                  ELSE
+                     TEMP = B( I+1, J )
+                     B( I+1, J ) = B( I, J ) - DL( I )*TEMP
+                     B( I, J ) = TEMP
+                  END IF
+  110          CONTINUE
+  120       CONTINUE
+         END IF
+      END IF
+*
+*     End of SGTTS2
+*
+      END
diff --git a/libcruft/lapack/shgeqz.f b/libcruft/lapack/shgeqz.f
new file mode 100644
index 0000000..2f02b6d
--- /dev/null
+++ b/libcruft/lapack/shgeqz.f
@@ -0,0 +1,1243 @@
+      SUBROUTINE SHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,
+     $                   ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,
+     $                   LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ, JOB
+      INTEGER            IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               ALPHAI( * ), ALPHAR( * ), BETA( * ),
+     $                   H( LDH, * ), Q( LDQ, * ), T( LDT, * ),
+     $                   WORK( * ), Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SHGEQZ computes the eigenvalues of a real matrix pair (H,T),
+*  where H is an upper Hessenberg matrix and T is upper triangular,
+*  using the double-shift QZ method.
+*  Matrix pairs of this type are produced by the reduction to
+*  generalized upper Hessenberg form of a real matrix pair (A,B):
+*
+*     A = Q1*H*Z1**T,  B = Q1*T*Z1**T,
+*
+*  as computed by SGGHRD.
+*
+*  If JOB='S', then the Hessenberg-triangular pair (H,T) is
+*  also reduced to generalized Schur form,
+*  
+*     H = Q*S*Z**T,  T = Q*P*Z**T,
+*  
+*  where Q and Z are orthogonal matrices, P is an upper triangular
+*  matrix, and S is a quasi-triangular matrix with 1-by-1 and 2-by-2
+*  diagonal blocks.
+*
+*  The 1-by-1 blocks correspond to real eigenvalues of the matrix pair
+*  (H,T) and the 2-by-2 blocks correspond to complex conjugate pairs of
+*  eigenvalues.
+*
+*  Additionally, the 2-by-2 upper triangular diagonal blocks of P
+*  corresponding to 2-by-2 blocks of S are reduced to positive diagonal
+*  form, i.e., if S(j+1,j) is non-zero, then P(j+1,j) = P(j,j+1) = 0,
+*  P(j,j) > 0, and P(j+1,j+1) > 0.
+*
+*  Optionally, the orthogonal matrix Q from the generalized Schur
+*  factorization may be postmultiplied into an input matrix Q1, and the
+*  orthogonal matrix Z may be postmultiplied into an input matrix Z1.
+*  If Q1 and Z1 are the orthogonal matrices from SGGHRD that reduced
+*  the matrix pair (A,B) to generalized upper Hessenberg form, then the
+*  output matrices Q1*Q and Z1*Z are the orthogonal factors from the
+*  generalized Schur factorization of (A,B):
+*
+*     A = (Q1*Q)*S*(Z1*Z)**T,  B = (Q1*Q)*P*(Z1*Z)**T.
+*  
+*  To avoid overflow, eigenvalues of the matrix pair (H,T) (equivalently,
+*  of (A,B)) are computed as a pair of values (alpha,beta), where alpha is
+*  complex and beta real.
+*  If beta is nonzero, lambda = alpha / beta is an eigenvalue of the
+*  generalized nonsymmetric eigenvalue problem (GNEP)
+*     A*x = lambda*B*x
+*  and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the
+*  alternate form of the GNEP
+*     mu*A*y = B*y.
+*  Real eigenvalues can be read directly from the generalized Schur
+*  form: 
+*    alpha = S(i,i), beta = P(i,i).
+*
+*  Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix
+*       Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),
+*       pp. 241--256.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          = 'E': Compute eigenvalues only;
+*          = 'S': Compute eigenvalues and the Schur form. 
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': Left Schur vectors (Q) are not computed;
+*          = 'I': Q is initialized to the unit matrix and the matrix Q
+*                 of left Schur vectors of (H,T) is returned;
+*          = 'V': Q must contain an orthogonal matrix Q1 on entry and
+*                 the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': Right Schur vectors (Z) are not computed;
+*          = 'I': Z is initialized to the unit matrix and the matrix Z
+*                 of right Schur vectors of (H,T) is returned;
+*          = 'V': Z must contain an orthogonal matrix Z1 on entry and
+*                 the product Z1*Z is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices H, T, Q, and Z.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of H which are in
+*          Hessenberg form.  It is assumed that A is already upper
+*          triangular in rows and columns 1:ILO-1 and IHI+1:N.
+*          If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0.
+*
+*  H       (input/output) REAL array, dimension (LDH, N)
+*          On entry, the N-by-N upper Hessenberg matrix H.
+*          On exit, if JOB = 'S', H contains the upper quasi-triangular
+*          matrix S from the generalized Schur factorization;
+*          2-by-2 diagonal blocks (corresponding to complex conjugate
+*          pairs of eigenvalues) are returned in standard form, with
+*          H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0.
+*          If JOB = 'E', the diagonal blocks of H match those of S, but
+*          the rest of H is unspecified.
+*
+*  LDH     (input) INTEGER
+*          The leading dimension of the array H.  LDH >= max( 1, N ).
+*
+*  T       (input/output) REAL array, dimension (LDT, N)
+*          On entry, the N-by-N upper triangular matrix T.
+*          On exit, if JOB = 'S', T contains the upper triangular
+*          matrix P from the generalized Schur factorization;
+*          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks of S
+*          are reduced to positive diagonal form, i.e., if H(j+1,j) is
+*          non-zero, then T(j+1,j) = T(j,j+1) = 0, T(j,j) > 0, and
+*          T(j+1,j+1) > 0.
+*          If JOB = 'E', the diagonal blocks of T match those of P, but
+*          the rest of T is unspecified.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= max( 1, N ).
+*
+*  ALPHAR  (output) REAL array, dimension (N)
+*          The real parts of each scalar alpha defining an eigenvalue
+*          of GNEP.
+*
+*  ALPHAI  (output) REAL array, dimension (N)
+*          The imaginary parts of each scalar alpha defining an
+*          eigenvalue of GNEP.
+*          If ALPHAI(j) is zero, then the j-th eigenvalue is real; if
+*          positive, then the j-th and (j+1)-st eigenvalues are a
+*          complex conjugate pair, with ALPHAI(j+1) = -ALPHAI(j).
+*
+*  BETA    (output) REAL array, dimension (N)
+*          The scalars beta that define the eigenvalues of GNEP.
+*          Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and
+*          beta = BETA(j) represent the j-th eigenvalue of the matrix
+*          pair (A,B), in one of the forms lambda = alpha/beta or
+*          mu = beta/alpha.  Since either lambda or mu may overflow,
+*          they should not, in general, be computed.
+*
+*  Q       (input/output) REAL array, dimension (LDQ, N)
+*          On entry, if COMPZ = 'V', the orthogonal matrix Q1 used in
+*          the reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the orthogonal matrix of left Schur
+*          vectors of (H,T), and if COMPZ = 'V', the orthogonal matrix
+*          of left Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= 1.
+*          If COMPQ='V' or 'I', then LDQ >= N.
+*
+*  Z       (input/output) REAL array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the orthogonal matrix Z1 used in
+*          the reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the orthogonal matrix of
+*          right Schur vectors of (H,T), and if COMPZ = 'V', the
+*          orthogonal matrix of right Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1.
+*          If COMPZ='V' or 'I', then LDZ >= N.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1,...,N: the QZ iteration did not converge.  (H,T) is not
+*                     in Schur form, but ALPHAR(i), ALPHAI(i), and
+*                     BETA(i), i=INFO+1,...,N should be correct.
+*          = N+1,...,2*N: the shift calculation failed.  (H,T) is not
+*                     in Schur form, but ALPHAR(i), ALPHAI(i), and
+*                     BETA(i), i=INFO-N+1,...,N should be correct.
+*
+*  Further Details
+*  ===============
+*
+*  Iteration counters:
+*
+*  JITER  -- counts iterations.
+*  IITER  -- counts iterations run since ILAST was last
+*            changed.  This is therefore reset only when a 1-by-1 or
+*            2-by-2 block deflates off the bottom.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+*    $                     SAFETY = 1.0E+0 )
+      REAL               HALF, ZERO, ONE, SAFETY
+      PARAMETER          ( HALF = 0.5E+0, ZERO = 0.0E+0, ONE = 1.0E+0,
+     $                   SAFETY = 1.0E+2 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILAZR2, ILAZRO, ILPIVT, ILQ, ILSCHR, ILZ,
+     $                   LQUERY
+      INTEGER            ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,
+     $                   ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,
+     $                   JR, MAXIT
+      REAL               A11, A12, A1I, A1R, A21, A22, A2I, A2R, AD11,
+     $                   AD11L, AD12, AD12L, AD21, AD21L, AD22, AD22L,
+     $                   AD32L, AN, ANORM, ASCALE, ATOL, B11, B1A, B1I,
+     $                   B1R, B22, B2A, B2I, B2R, BN, BNORM, BSCALE,
+     $                   BTOL, C, C11I, C11R, C12, C21, C22I, C22R, CL,
+     $                   CQ, CR, CZ, ESHIFT, S, S1, S1INV, S2, SAFMAX,
+     $                   SAFMIN, SCALE, SL, SQI, SQR, SR, SZI, SZR, T1,
+     $                   TAU, TEMP, TEMP2, TEMPI, TEMPR, U1, U12, U12L,
+     $                   U2, ULP, VS, W11, W12, W21, W22, WABS, WI, WR,
+     $                   WR2
+*     ..
+*     .. Local Arrays ..
+      REAL               V( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH, SLANHS, SLAPY2, SLAPY3
+      EXTERNAL           LSAME, SLAMCH, SLANHS, SLAPY2, SLAPY3
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAG2, SLARFG, SLARTG, SLASET, SLASV2, SROT,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode JOB, COMPQ, COMPZ
+*
+      IF( LSAME( JOB, 'E' ) ) THEN
+         ILSCHR = .FALSE.
+         ISCHUR = 1
+      ELSE IF( LSAME( JOB, 'S' ) ) THEN
+         ILSCHR = .TRUE.
+         ISCHUR = 2
+      ELSE
+         ISCHUR = 0
+      END IF
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Check Argument Values
+*
+      INFO = 0
+      WORK( 1 ) = MAX( 1, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( ISCHUR.EQ.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPQ.EQ.0 ) THEN
+         INFO = -2
+      ELSE IF( ICOMPZ.EQ.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -6
+      ELSE IF( LDH.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDT.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -15
+      ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THEN
+         INFO = -17
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -19
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SHGEQZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = REAL( 1 )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL SLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL SLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
+*
+*     Machine Constants
+*
+      IN = IHI + 1 - ILO
+      SAFMIN = SLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      ULP = SLAMCH( 'E' )*SLAMCH( 'B' )
+      ANORM = SLANHS( 'F', IN, H( ILO, ILO ), LDH, WORK )
+      BNORM = SLANHS( 'F', IN, T( ILO, ILO ), LDT, WORK )
+      ATOL = MAX( SAFMIN, ULP*ANORM )
+      BTOL = MAX( SAFMIN, ULP*BNORM )
+      ASCALE = ONE / MAX( SAFMIN, ANORM )
+      BSCALE = ONE / MAX( SAFMIN, BNORM )
+*
+*     Set Eigenvalues IHI+1:N
+*
+      DO 30 J = IHI + 1, N
+         IF( T( J, J ).LT.ZERO ) THEN
+            IF( ILSCHR ) THEN
+               DO 10 JR = 1, J
+                  H( JR, J ) = -H( JR, J )
+                  T( JR, J ) = -T( JR, J )
+   10          CONTINUE
+            ELSE
+               H( J, J ) = -H( J, J )
+               T( J, J ) = -T( J, J )
+            END IF
+            IF( ILZ ) THEN
+               DO 20 JR = 1, N
+                  Z( JR, J ) = -Z( JR, J )
+   20          CONTINUE
+            END IF
+         END IF
+         ALPHAR( J ) = H( J, J )
+         ALPHAI( J ) = ZERO
+         BETA( J ) = T( J, J )
+   30 CONTINUE
+*
+*     If IHI < ILO, skip QZ steps
+*
+      IF( IHI.LT.ILO )
+     $   GO TO 380
+*
+*     MAIN QZ ITERATION LOOP
+*
+*     Initialize dynamic indices
+*
+*     Eigenvalues ILAST+1:N have been found.
+*        Column operations modify rows IFRSTM:whatever.
+*        Row operations modify columns whatever:ILASTM.
+*
+*     If only eigenvalues are being computed, then
+*        IFRSTM is the row of the last splitting row above row ILAST;
+*        this is always at least ILO.
+*     IITER counts iterations since the last eigenvalue was found,
+*        to tell when to use an extraordinary shift.
+*     MAXIT is the maximum number of QZ sweeps allowed.
+*
+      ILAST = IHI
+      IF( ILSCHR ) THEN
+         IFRSTM = 1
+         ILASTM = N
+      ELSE
+         IFRSTM = ILO
+         ILASTM = IHI
+      END IF
+      IITER = 0
+      ESHIFT = ZERO
+      MAXIT = 30*( IHI-ILO+1 )
+*
+      DO 360 JITER = 1, MAXIT
+*
+*        Split the matrix if possible.
+*
+*        Two tests:
+*           1: H(j,j-1)=0  or  j=ILO
+*           2: T(j,j)=0
+*
+         IF( ILAST.EQ.ILO ) THEN
+*
+*           Special case: j=ILAST
+*
+            GO TO 80
+         ELSE
+            IF( ABS( H( ILAST, ILAST-1 ) ).LE.ATOL ) THEN
+               H( ILAST, ILAST-1 ) = ZERO
+               GO TO 80
+            END IF
+         END IF
+*
+         IF( ABS( T( ILAST, ILAST ) ).LE.BTOL ) THEN
+            T( ILAST, ILAST ) = ZERO
+            GO TO 70
+         END IF
+*
+*        General case: j<ILAST
+*
+         DO 60 J = ILAST - 1, ILO, -1
+*
+*           Test 1: for H(j,j-1)=0 or j=ILO
+*
+            IF( J.EQ.ILO ) THEN
+               ILAZRO = .TRUE.
+            ELSE
+               IF( ABS( H( J, J-1 ) ).LE.ATOL ) THEN
+                  H( J, J-1 ) = ZERO
+                  ILAZRO = .TRUE.
+               ELSE
+                  ILAZRO = .FALSE.
+               END IF
+            END IF
+*
+*           Test 2: for T(j,j)=0
+*
+            IF( ABS( T( J, J ) ).LT.BTOL ) THEN
+               T( J, J ) = ZERO
+*
+*              Test 1a: Check for 2 consecutive small subdiagonals in A
+*
+               ILAZR2 = .FALSE.
+               IF( .NOT.ILAZRO ) THEN
+                  TEMP = ABS( H( J, J-1 ) )
+                  TEMP2 = ABS( H( J, J ) )
+                  TEMPR = MAX( TEMP, TEMP2 )
+                  IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
+                     TEMP = TEMP / TEMPR
+                     TEMP2 = TEMP2 / TEMPR
+                  END IF
+                  IF( TEMP*( ASCALE*ABS( H( J+1, J ) ) ).LE.TEMP2*
+     $                ( ASCALE*ATOL ) )ILAZR2 = .TRUE.
+               END IF
+*
+*              If both tests pass (1 & 2), i.e., the leading diagonal
+*              element of B in the block is zero, split a 1x1 block off
+*              at the top. (I.e., at the J-th row/column) The leading
+*              diagonal element of the remainder can also be zero, so
+*              this may have to be done repeatedly.
+*
+               IF( ILAZRO .OR. ILAZR2 ) THEN
+                  DO 40 JCH = J, ILAST - 1
+                     TEMP = H( JCH, JCH )
+                     CALL SLARTG( TEMP, H( JCH+1, JCH ), C, S,
+     $                            H( JCH, JCH ) )
+                     H( JCH+1, JCH ) = ZERO
+                     CALL SROT( ILASTM-JCH, H( JCH, JCH+1 ), LDH,
+     $                          H( JCH+1, JCH+1 ), LDH, C, S )
+                     CALL SROT( ILASTM-JCH, T( JCH, JCH+1 ), LDT,
+     $                          T( JCH+1, JCH+1 ), LDT, C, S )
+                     IF( ILQ )
+     $                  CALL SROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, S )
+                     IF( ILAZR2 )
+     $                  H( JCH, JCH-1 ) = H( JCH, JCH-1 )*C
+                     ILAZR2 = .FALSE.
+                     IF( ABS( T( JCH+1, JCH+1 ) ).GE.BTOL ) THEN
+                        IF( JCH+1.GE.ILAST ) THEN
+                           GO TO 80
+                        ELSE
+                           IFIRST = JCH + 1
+                           GO TO 110
+                        END IF
+                     END IF
+                     T( JCH+1, JCH+1 ) = ZERO
+   40             CONTINUE
+                  GO TO 70
+               ELSE
+*
+*                 Only test 2 passed -- chase the zero to T(ILAST,ILAST)
+*                 Then process as in the case T(ILAST,ILAST)=0
+*
+                  DO 50 JCH = J, ILAST - 1
+                     TEMP = T( JCH, JCH+1 )
+                     CALL SLARTG( TEMP, T( JCH+1, JCH+1 ), C, S,
+     $                            T( JCH, JCH+1 ) )
+                     T( JCH+1, JCH+1 ) = ZERO
+                     IF( JCH.LT.ILASTM-1 )
+     $                  CALL SROT( ILASTM-JCH-1, T( JCH, JCH+2 ), LDT,
+     $                             T( JCH+1, JCH+2 ), LDT, C, S )
+                     CALL SROT( ILASTM-JCH+2, H( JCH, JCH-1 ), LDH,
+     $                          H( JCH+1, JCH-1 ), LDH, C, S )
+                     IF( ILQ )
+     $                  CALL SROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, S )
+                     TEMP = H( JCH+1, JCH )
+                     CALL SLARTG( TEMP, H( JCH+1, JCH-1 ), C, S,
+     $                            H( JCH+1, JCH ) )
+                     H( JCH+1, JCH-1 ) = ZERO
+                     CALL SROT( JCH+1-IFRSTM, H( IFRSTM, JCH ), 1,
+     $                          H( IFRSTM, JCH-1 ), 1, C, S )
+                     CALL SROT( JCH-IFRSTM, T( IFRSTM, JCH ), 1,
+     $                          T( IFRSTM, JCH-1 ), 1, C, S )
+                     IF( ILZ )
+     $                  CALL SROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,
+     $                             C, S )
+   50             CONTINUE
+                  GO TO 70
+               END IF
+            ELSE IF( ILAZRO ) THEN
+*
+*              Only test 1 passed -- work on J:ILAST
+*
+               IFIRST = J
+               GO TO 110
+            END IF
+*
+*           Neither test passed -- try next J
+*
+   60    CONTINUE
+*
+*        (Drop-through is "impossible")
+*
+         INFO = N + 1
+         GO TO 420
+*
+*        T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a
+*        1x1 block.
+*
+   70    CONTINUE
+         TEMP = H( ILAST, ILAST )
+         CALL SLARTG( TEMP, H( ILAST, ILAST-1 ), C, S,
+     $                H( ILAST, ILAST ) )
+         H( ILAST, ILAST-1 ) = ZERO
+         CALL SROT( ILAST-IFRSTM, H( IFRSTM, ILAST ), 1,
+     $              H( IFRSTM, ILAST-1 ), 1, C, S )
+         CALL SROT( ILAST-IFRSTM, T( IFRSTM, ILAST ), 1,
+     $              T( IFRSTM, ILAST-1 ), 1, C, S )
+         IF( ILZ )
+     $      CALL SROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )
+*
+*        H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHAR, ALPHAI,
+*                              and BETA
+*
+   80    CONTINUE
+         IF( T( ILAST, ILAST ).LT.ZERO ) THEN
+            IF( ILSCHR ) THEN
+               DO 90 J = IFRSTM, ILAST
+                  H( J, ILAST ) = -H( J, ILAST )
+                  T( J, ILAST ) = -T( J, ILAST )
+   90          CONTINUE
+            ELSE
+               H( ILAST, ILAST ) = -H( ILAST, ILAST )
+               T( ILAST, ILAST ) = -T( ILAST, ILAST )
+            END IF
+            IF( ILZ ) THEN
+               DO 100 J = 1, N
+                  Z( J, ILAST ) = -Z( J, ILAST )
+  100          CONTINUE
+            END IF
+         END IF
+         ALPHAR( ILAST ) = H( ILAST, ILAST )
+         ALPHAI( ILAST ) = ZERO
+         BETA( ILAST ) = T( ILAST, ILAST )
+*
+*        Go to next block -- exit if finished.
+*
+         ILAST = ILAST - 1
+         IF( ILAST.LT.ILO )
+     $      GO TO 380
+*
+*        Reset counters
+*
+         IITER = 0
+         ESHIFT = ZERO
+         IF( .NOT.ILSCHR ) THEN
+            ILASTM = ILAST
+            IF( IFRSTM.GT.ILAST )
+     $         IFRSTM = ILO
+         END IF
+         GO TO 350
+*
+*        QZ step
+*
+*        This iteration only involves rows/columns IFIRST:ILAST. We
+*        assume IFIRST < ILAST, and that the diagonal of B is non-zero.
+*
+  110    CONTINUE
+         IITER = IITER + 1
+         IF( .NOT.ILSCHR ) THEN
+            IFRSTM = IFIRST
+         END IF
+*
+*        Compute single shifts.
+*
+*        At this point, IFIRST < ILAST, and the diagonal elements of
+*        T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in
+*        magnitude)
+*
+         IF( ( IITER / 10 )*10.EQ.IITER ) THEN
+*
+*           Exceptional shift.  Chosen for no particularly good reason.
+*           (Single shift only.)
+*
+            IF( ( REAL( MAXIT )*SAFMIN )*ABS( H( ILAST-1, ILAST ) ).LT.
+     $          ABS( T( ILAST-1, ILAST-1 ) ) ) THEN
+               ESHIFT = ESHIFT + H( ILAST-1, ILAST ) /
+     $                  T( ILAST-1, ILAST-1 )
+            ELSE
+               ESHIFT = ESHIFT + ONE / ( SAFMIN*REAL( MAXIT ) )
+            END IF
+            S1 = ONE
+            WR = ESHIFT
+*
+         ELSE
+*
+*           Shifts based on the generalized eigenvalues of the
+*           bottom-right 2x2 block of A and B. The first eigenvalue
+*           returned by SLAG2 is the Wilkinson shift (AEP p.512),
+*
+            CALL SLAG2( H( ILAST-1, ILAST-1 ), LDH,
+     $                  T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1,
+     $                  S2, WR, WR2, WI )
+*
+            TEMP = MAX( S1, SAFMIN*MAX( ONE, ABS( WR ), ABS( WI ) ) )
+            IF( WI.NE.ZERO )
+     $         GO TO 200
+         END IF
+*
+*        Fiddle with shift to avoid overflow
+*
+         TEMP = MIN( ASCALE, ONE )*( HALF*SAFMAX )
+         IF( S1.GT.TEMP ) THEN
+            SCALE = TEMP / S1
+         ELSE
+            SCALE = ONE
+         END IF
+*
+         TEMP = MIN( BSCALE, ONE )*( HALF*SAFMAX )
+         IF( ABS( WR ).GT.TEMP )
+     $      SCALE = MIN( SCALE, TEMP / ABS( WR ) )
+         S1 = SCALE*S1
+         WR = SCALE*WR
+*
+*        Now check for two consecutive small subdiagonals.
+*
+         DO 120 J = ILAST - 1, IFIRST + 1, -1
+            ISTART = J
+            TEMP = ABS( S1*H( J, J-1 ) )
+            TEMP2 = ABS( S1*H( J, J )-WR*T( J, J ) )
+            TEMPR = MAX( TEMP, TEMP2 )
+            IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
+               TEMP = TEMP / TEMPR
+               TEMP2 = TEMP2 / TEMPR
+            END IF
+            IF( ABS( ( ASCALE*H( J+1, J ) )*TEMP ).LE.( ASCALE*ATOL )*
+     $          TEMP2 )GO TO 130
+  120    CONTINUE
+*
+         ISTART = IFIRST
+  130    CONTINUE
+*
+*        Do an implicit single-shift QZ sweep.
+*
+*        Initial Q
+*
+         TEMP = S1*H( ISTART, ISTART ) - WR*T( ISTART, ISTART )
+         TEMP2 = S1*H( ISTART+1, ISTART )
+         CALL SLARTG( TEMP, TEMP2, C, S, TEMPR )
+*
+*        Sweep
+*
+         DO 190 J = ISTART, ILAST - 1
+            IF( J.GT.ISTART ) THEN
+               TEMP = H( J, J-1 )
+               CALL SLARTG( TEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
+               H( J+1, J-1 ) = ZERO
+            END IF
+*
+            DO 140 JC = J, ILASTM
+               TEMP = C*H( J, JC ) + S*H( J+1, JC )
+               H( J+1, JC ) = -S*H( J, JC ) + C*H( J+1, JC )
+               H( J, JC ) = TEMP
+               TEMP2 = C*T( J, JC ) + S*T( J+1, JC )
+               T( J+1, JC ) = -S*T( J, JC ) + C*T( J+1, JC )
+               T( J, JC ) = TEMP2
+  140       CONTINUE
+            IF( ILQ ) THEN
+               DO 150 JR = 1, N
+                  TEMP = C*Q( JR, J ) + S*Q( JR, J+1 )
+                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
+                  Q( JR, J ) = TEMP
+  150          CONTINUE
+            END IF
+*
+            TEMP = T( J+1, J+1 )
+            CALL SLARTG( TEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
+            T( J+1, J ) = ZERO
+*
+            DO 160 JR = IFRSTM, MIN( J+2, ILAST )
+               TEMP = C*H( JR, J+1 ) + S*H( JR, J )
+               H( JR, J ) = -S*H( JR, J+1 ) + C*H( JR, J )
+               H( JR, J+1 ) = TEMP
+  160       CONTINUE
+            DO 170 JR = IFRSTM, J
+               TEMP = C*T( JR, J+1 ) + S*T( JR, J )
+               T( JR, J ) = -S*T( JR, J+1 ) + C*T( JR, J )
+               T( JR, J+1 ) = TEMP
+  170       CONTINUE
+            IF( ILZ ) THEN
+               DO 180 JR = 1, N
+                  TEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
+                  Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )
+                  Z( JR, J+1 ) = TEMP
+  180          CONTINUE
+            END IF
+  190    CONTINUE
+*
+         GO TO 350
+*
+*        Use Francis double-shift
+*
+*        Note: the Francis double-shift should work with real shifts,
+*              but only if the block is at least 3x3.
+*              This code may break if this point is reached with
+*              a 2x2 block with real eigenvalues.
+*
+  200    CONTINUE
+         IF( IFIRST+1.EQ.ILAST ) THEN
+*
+*           Special case -- 2x2 block with complex eigenvectors
+*
+*           Step 1: Standardize, that is, rotate so that
+*
+*                       ( B11  0  )
+*                   B = (         )  with B11 non-negative.
+*                       (  0  B22 )
+*
+            CALL SLASV2( T( ILAST-1, ILAST-1 ), T( ILAST-1, ILAST ),
+     $                   T( ILAST, ILAST ), B22, B11, SR, CR, SL, CL )
+*
+            IF( B11.LT.ZERO ) THEN
+               CR = -CR
+               SR = -SR
+               B11 = -B11
+               B22 = -B22
+            END IF
+*
+            CALL SROT( ILASTM+1-IFIRST, H( ILAST-1, ILAST-1 ), LDH,
+     $                 H( ILAST, ILAST-1 ), LDH, CL, SL )
+            CALL SROT( ILAST+1-IFRSTM, H( IFRSTM, ILAST-1 ), 1,
+     $                 H( IFRSTM, ILAST ), 1, CR, SR )
+*
+            IF( ILAST.LT.ILASTM )
+     $         CALL SROT( ILASTM-ILAST, T( ILAST-1, ILAST+1 ), LDT,
+     $                    T( ILAST, ILAST+1 ), LDH, CL, SL )
+            IF( IFRSTM.LT.ILAST-1 )
+     $         CALL SROT( IFIRST-IFRSTM, T( IFRSTM, ILAST-1 ), 1,
+     $                    T( IFRSTM, ILAST ), 1, CR, SR )
+*
+            IF( ILQ )
+     $         CALL SROT( N, Q( 1, ILAST-1 ), 1, Q( 1, ILAST ), 1, CL,
+     $                    SL )
+            IF( ILZ )
+     $         CALL SROT( N, Z( 1, ILAST-1 ), 1, Z( 1, ILAST ), 1, CR,
+     $                    SR )
+*
+            T( ILAST-1, ILAST-1 ) = B11
+            T( ILAST-1, ILAST ) = ZERO
+            T( ILAST, ILAST-1 ) = ZERO
+            T( ILAST, ILAST ) = B22
+*
+*           If B22 is negative, negate column ILAST
+*
+            IF( B22.LT.ZERO ) THEN
+               DO 210 J = IFRSTM, ILAST
+                  H( J, ILAST ) = -H( J, ILAST )
+                  T( J, ILAST ) = -T( J, ILAST )
+  210          CONTINUE
+*
+               IF( ILZ ) THEN
+                  DO 220 J = 1, N
+                     Z( J, ILAST ) = -Z( J, ILAST )
+  220             CONTINUE
+               END IF
+            END IF
+*
+*           Step 2: Compute ALPHAR, ALPHAI, and BETA (see refs.)
+*
+*           Recompute shift
+*
+            CALL SLAG2( H( ILAST-1, ILAST-1 ), LDH,
+     $                  T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1,
+     $                  TEMP, WR, TEMP2, WI )
+*
+*           If standardization has perturbed the shift onto real line,
+*           do another (real single-shift) QR step.
+*
+            IF( WI.EQ.ZERO )
+     $         GO TO 350
+            S1INV = ONE / S1
+*
+*           Do EISPACK (QZVAL) computation of alpha and beta
+*
+            A11 = H( ILAST-1, ILAST-1 )
+            A21 = H( ILAST, ILAST-1 )
+            A12 = H( ILAST-1, ILAST )
+            A22 = H( ILAST, ILAST )
+*
+*           Compute complex Givens rotation on right
+*           (Assume some element of C = (sA - wB) > unfl )
+*                            __
+*           (sA - wB) ( CZ   -SZ )
+*                     ( SZ    CZ )
+*
+            C11R = S1*A11 - WR*B11
+            C11I = -WI*B11
+            C12 = S1*A12
+            C21 = S1*A21
+            C22R = S1*A22 - WR*B22
+            C22I = -WI*B22
+*
+            IF( ABS( C11R )+ABS( C11I )+ABS( C12 ).GT.ABS( C21 )+
+     $          ABS( C22R )+ABS( C22I ) ) THEN
+               T1 = SLAPY3( C12, C11R, C11I )
+               CZ = C12 / T1
+               SZR = -C11R / T1
+               SZI = -C11I / T1
+            ELSE
+               CZ = SLAPY2( C22R, C22I )
+               IF( CZ.LE.SAFMIN ) THEN
+                  CZ = ZERO
+                  SZR = ONE
+                  SZI = ZERO
+               ELSE
+                  TEMPR = C22R / CZ
+                  TEMPI = C22I / CZ
+                  T1 = SLAPY2( CZ, C21 )
+                  CZ = CZ / T1
+                  SZR = -C21*TEMPR / T1
+                  SZI = C21*TEMPI / T1
+               END IF
+            END IF
+*
+*           Compute Givens rotation on left
+*
+*           (  CQ   SQ )
+*           (  __      )  A or B
+*           ( -SQ   CQ )
+*
+            AN = ABS( A11 ) + ABS( A12 ) + ABS( A21 ) + ABS( A22 )
+            BN = ABS( B11 ) + ABS( B22 )
+            WABS = ABS( WR ) + ABS( WI )
+            IF( S1*AN.GT.WABS*BN ) THEN
+               CQ = CZ*B11
+               SQR = SZR*B22
+               SQI = -SZI*B22
+            ELSE
+               A1R = CZ*A11 + SZR*A12
+               A1I = SZI*A12
+               A2R = CZ*A21 + SZR*A22
+               A2I = SZI*A22
+               CQ = SLAPY2( A1R, A1I )
+               IF( CQ.LE.SAFMIN ) THEN
+                  CQ = ZERO
+                  SQR = ONE
+                  SQI = ZERO
+               ELSE
+                  TEMPR = A1R / CQ
+                  TEMPI = A1I / CQ
+                  SQR = TEMPR*A2R + TEMPI*A2I
+                  SQI = TEMPI*A2R - TEMPR*A2I
+               END IF
+            END IF
+            T1 = SLAPY3( CQ, SQR, SQI )
+            CQ = CQ / T1
+            SQR = SQR / T1
+            SQI = SQI / T1
+*
+*           Compute diagonal elements of QBZ
+*
+            TEMPR = SQR*SZR - SQI*SZI
+            TEMPI = SQR*SZI + SQI*SZR
+            B1R = CQ*CZ*B11 + TEMPR*B22
+            B1I = TEMPI*B22
+            B1A = SLAPY2( B1R, B1I )
+            B2R = CQ*CZ*B22 + TEMPR*B11
+            B2I = -TEMPI*B11
+            B2A = SLAPY2( B2R, B2I )
+*
+*           Normalize so beta > 0, and Im( alpha1 ) > 0
+*
+            BETA( ILAST-1 ) = B1A
+            BETA( ILAST ) = B2A
+            ALPHAR( ILAST-1 ) = ( WR*B1A )*S1INV
+            ALPHAI( ILAST-1 ) = ( WI*B1A )*S1INV
+            ALPHAR( ILAST ) = ( WR*B2A )*S1INV
+            ALPHAI( ILAST ) = -( WI*B2A )*S1INV
+*
+*           Step 3: Go to next block -- exit if finished.
+*
+            ILAST = IFIRST - 1
+            IF( ILAST.LT.ILO )
+     $         GO TO 380
+*
+*           Reset counters
+*
+            IITER = 0
+            ESHIFT = ZERO
+            IF( .NOT.ILSCHR ) THEN
+               ILASTM = ILAST
+               IF( IFRSTM.GT.ILAST )
+     $            IFRSTM = ILO
+            END IF
+            GO TO 350
+         ELSE
+*
+*           Usual case: 3x3 or larger block, using Francis implicit
+*                       double-shift
+*
+*                                    2
+*           Eigenvalue equation is  w  - c w + d = 0,
+*
+*                                         -1 2        -1
+*           so compute 1st column of  (A B  )  - c A B   + d
+*           using the formula in QZIT (from EISPACK)
+*
+*           We assume that the block is at least 3x3
+*
+            AD11 = ( ASCALE*H( ILAST-1, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD21 = ( ASCALE*H( ILAST, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD12 = ( ASCALE*H( ILAST-1, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            AD22 = ( ASCALE*H( ILAST, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            U12 = T( ILAST-1, ILAST ) / T( ILAST, ILAST )
+            AD11L = ( ASCALE*H( IFIRST, IFIRST ) ) /
+     $              ( BSCALE*T( IFIRST, IFIRST ) )
+            AD21L = ( ASCALE*H( IFIRST+1, IFIRST ) ) /
+     $              ( BSCALE*T( IFIRST, IFIRST ) )
+            AD12L = ( ASCALE*H( IFIRST, IFIRST+1 ) ) /
+     $              ( BSCALE*T( IFIRST+1, IFIRST+1 ) )
+            AD22L = ( ASCALE*H( IFIRST+1, IFIRST+1 ) ) /
+     $              ( BSCALE*T( IFIRST+1, IFIRST+1 ) )
+            AD32L = ( ASCALE*H( IFIRST+2, IFIRST+1 ) ) /
+     $              ( BSCALE*T( IFIRST+1, IFIRST+1 ) )
+            U12L = T( IFIRST, IFIRST+1 ) / T( IFIRST+1, IFIRST+1 )
+*
+            V( 1 ) = ( AD11-AD11L )*( AD22-AD11L ) - AD12*AD21 +
+     $               AD21*U12*AD11L + ( AD12L-AD11L*U12L )*AD21L
+            V( 2 ) = ( ( AD22L-AD11L )-AD21L*U12L-( AD11-AD11L )-
+     $               ( AD22-AD11L )+AD21*U12 )*AD21L
+            V( 3 ) = AD32L*AD21L
+*
+            ISTART = IFIRST
+*
+            CALL SLARFG( 3, V( 1 ), V( 2 ), 1, TAU )
+            V( 1 ) = ONE
+*
+*           Sweep
+*
+            DO 290 J = ISTART, ILAST - 2
+*
+*              All but last elements: use 3x3 Householder transforms.
+*
+*              Zero (j-1)st column of A
+*
+               IF( J.GT.ISTART ) THEN
+                  V( 1 ) = H( J, J-1 )
+                  V( 2 ) = H( J+1, J-1 )
+                  V( 3 ) = H( J+2, J-1 )
+*
+                  CALL SLARFG( 3, H( J, J-1 ), V( 2 ), 1, TAU )
+                  V( 1 ) = ONE
+                  H( J+1, J-1 ) = ZERO
+                  H( J+2, J-1 ) = ZERO
+               END IF
+*
+               DO 230 JC = J, ILASTM
+                  TEMP = TAU*( H( J, JC )+V( 2 )*H( J+1, JC )+V( 3 )*
+     $                   H( J+2, JC ) )
+                  H( J, JC ) = H( J, JC ) - TEMP
+                  H( J+1, JC ) = H( J+1, JC ) - TEMP*V( 2 )
+                  H( J+2, JC ) = H( J+2, JC ) - TEMP*V( 3 )
+                  TEMP2 = TAU*( T( J, JC )+V( 2 )*T( J+1, JC )+V( 3 )*
+     $                    T( J+2, JC ) )
+                  T( J, JC ) = T( J, JC ) - TEMP2
+                  T( J+1, JC ) = T( J+1, JC ) - TEMP2*V( 2 )
+                  T( J+2, JC ) = T( J+2, JC ) - TEMP2*V( 3 )
+  230          CONTINUE
+               IF( ILQ ) THEN
+                  DO 240 JR = 1, N
+                     TEMP = TAU*( Q( JR, J )+V( 2 )*Q( JR, J+1 )+V( 3 )*
+     $                      Q( JR, J+2 ) )
+                     Q( JR, J ) = Q( JR, J ) - TEMP
+                     Q( JR, J+1 ) = Q( JR, J+1 ) - TEMP*V( 2 )
+                     Q( JR, J+2 ) = Q( JR, J+2 ) - TEMP*V( 3 )
+  240             CONTINUE
+               END IF
+*
+*              Zero j-th column of B (see SLAGBC for details)
+*
+*              Swap rows to pivot
+*
+               ILPIVT = .FALSE.
+               TEMP = MAX( ABS( T( J+1, J+1 ) ), ABS( T( J+1, J+2 ) ) )
+               TEMP2 = MAX( ABS( T( J+2, J+1 ) ), ABS( T( J+2, J+2 ) ) )
+               IF( MAX( TEMP, TEMP2 ).LT.SAFMIN ) THEN
+                  SCALE = ZERO
+                  U1 = ONE
+                  U2 = ZERO
+                  GO TO 250
+               ELSE IF( TEMP.GE.TEMP2 ) THEN
+                  W11 = T( J+1, J+1 )
+                  W21 = T( J+2, J+1 )
+                  W12 = T( J+1, J+2 )
+                  W22 = T( J+2, J+2 )
+                  U1 = T( J+1, J )
+                  U2 = T( J+2, J )
+               ELSE
+                  W21 = T( J+1, J+1 )
+                  W11 = T( J+2, J+1 )
+                  W22 = T( J+1, J+2 )
+                  W12 = T( J+2, J+2 )
+                  U2 = T( J+1, J )
+                  U1 = T( J+2, J )
+               END IF
+*
+*              Swap columns if nec.
+*
+               IF( ABS( W12 ).GT.ABS( W11 ) ) THEN
+                  ILPIVT = .TRUE.
+                  TEMP = W12
+                  TEMP2 = W22
+                  W12 = W11
+                  W22 = W21
+                  W11 = TEMP
+                  W21 = TEMP2
+               END IF
+*
+*              LU-factor
+*
+               TEMP = W21 / W11
+               U2 = U2 - TEMP*U1
+               W22 = W22 - TEMP*W12
+               W21 = ZERO
+*
+*              Compute SCALE
+*
+               SCALE = ONE
+               IF( ABS( W22 ).LT.SAFMIN ) THEN
+                  SCALE = ZERO
+                  U2 = ONE
+                  U1 = -W12 / W11
+                  GO TO 250
+               END IF
+               IF( ABS( W22 ).LT.ABS( U2 ) )
+     $            SCALE = ABS( W22 / U2 )
+               IF( ABS( W11 ).LT.ABS( U1 ) )
+     $            SCALE = MIN( SCALE, ABS( W11 / U1 ) )
+*
+*              Solve
+*
+               U2 = ( SCALE*U2 ) / W22
+               U1 = ( SCALE*U1-W12*U2 ) / W11
+*
+  250          CONTINUE
+               IF( ILPIVT ) THEN
+                  TEMP = U2
+                  U2 = U1
+                  U1 = TEMP
+               END IF
+*
+*              Compute Householder Vector
+*
+               T1 = SQRT( SCALE**2+U1**2+U2**2 )
+               TAU = ONE + SCALE / T1
+               VS = -ONE / ( SCALE+T1 )
+               V( 1 ) = ONE
+               V( 2 ) = VS*U1
+               V( 3 ) = VS*U2
+*
+*              Apply transformations from the right.
+*
+               DO 260 JR = IFRSTM, MIN( J+3, ILAST )
+                  TEMP = TAU*( H( JR, J )+V( 2 )*H( JR, J+1 )+V( 3 )*
+     $                   H( JR, J+2 ) )
+                  H( JR, J ) = H( JR, J ) - TEMP
+                  H( JR, J+1 ) = H( JR, J+1 ) - TEMP*V( 2 )
+                  H( JR, J+2 ) = H( JR, J+2 ) - TEMP*V( 3 )
+  260          CONTINUE
+               DO 270 JR = IFRSTM, J + 2
+                  TEMP = TAU*( T( JR, J )+V( 2 )*T( JR, J+1 )+V( 3 )*
+     $                   T( JR, J+2 ) )
+                  T( JR, J ) = T( JR, J ) - TEMP
+                  T( JR, J+1 ) = T( JR, J+1 ) - TEMP*V( 2 )
+                  T( JR, J+2 ) = T( JR, J+2 ) - TEMP*V( 3 )
+  270          CONTINUE
+               IF( ILZ ) THEN
+                  DO 280 JR = 1, N
+                     TEMP = TAU*( Z( JR, J )+V( 2 )*Z( JR, J+1 )+V( 3 )*
+     $                      Z( JR, J+2 ) )
+                     Z( JR, J ) = Z( JR, J ) - TEMP
+                     Z( JR, J+1 ) = Z( JR, J+1 ) - TEMP*V( 2 )
+                     Z( JR, J+2 ) = Z( JR, J+2 ) - TEMP*V( 3 )
+  280             CONTINUE
+               END IF
+               T( J+1, J ) = ZERO
+               T( J+2, J ) = ZERO
+  290       CONTINUE
+*
+*           Last elements: Use Givens rotations
+*
+*           Rotations from the left
+*
+            J = ILAST - 1
+            TEMP = H( J, J-1 )
+            CALL SLARTG( TEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
+            H( J+1, J-1 ) = ZERO
+*
+            DO 300 JC = J, ILASTM
+               TEMP = C*H( J, JC ) + S*H( J+1, JC )
+               H( J+1, JC ) = -S*H( J, JC ) + C*H( J+1, JC )
+               H( J, JC ) = TEMP
+               TEMP2 = C*T( J, JC ) + S*T( J+1, JC )
+               T( J+1, JC ) = -S*T( J, JC ) + C*T( J+1, JC )
+               T( J, JC ) = TEMP2
+  300       CONTINUE
+            IF( ILQ ) THEN
+               DO 310 JR = 1, N
+                  TEMP = C*Q( JR, J ) + S*Q( JR, J+1 )
+                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
+                  Q( JR, J ) = TEMP
+  310          CONTINUE
+            END IF
+*
+*           Rotations from the right.
+*
+            TEMP = T( J+1, J+1 )
+            CALL SLARTG( TEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
+            T( J+1, J ) = ZERO
+*
+            DO 320 JR = IFRSTM, ILAST
+               TEMP = C*H( JR, J+1 ) + S*H( JR, J )
+               H( JR, J ) = -S*H( JR, J+1 ) + C*H( JR, J )
+               H( JR, J+1 ) = TEMP
+  320       CONTINUE
+            DO 330 JR = IFRSTM, ILAST - 1
+               TEMP = C*T( JR, J+1 ) + S*T( JR, J )
+               T( JR, J ) = -S*T( JR, J+1 ) + C*T( JR, J )
+               T( JR, J+1 ) = TEMP
+  330       CONTINUE
+            IF( ILZ ) THEN
+               DO 340 JR = 1, N
+                  TEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
+                  Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )
+                  Z( JR, J+1 ) = TEMP
+  340          CONTINUE
+            END IF
+*
+*           End of Double-Shift code
+*
+         END IF
+*
+         GO TO 350
+*
+*        End of iteration loop
+*
+  350    CONTINUE
+  360 CONTINUE
+*
+*     Drop-through = non-convergence
+*
+      INFO = ILAST
+      GO TO 420
+*
+*     Successful completion of all QZ steps
+*
+  380 CONTINUE
+*
+*     Set Eigenvalues 1:ILO-1
+*
+      DO 410 J = 1, ILO - 1
+         IF( T( J, J ).LT.ZERO ) THEN
+            IF( ILSCHR ) THEN
+               DO 390 JR = 1, J
+                  H( JR, J ) = -H( JR, J )
+                  T( JR, J ) = -T( JR, J )
+  390          CONTINUE
+            ELSE
+               H( J, J ) = -H( J, J )
+               T( J, J ) = -T( J, J )
+            END IF
+            IF( ILZ ) THEN
+               DO 400 JR = 1, N
+                  Z( JR, J ) = -Z( JR, J )
+  400          CONTINUE
+            END IF
+         END IF
+         ALPHAR( J ) = H( J, J )
+         ALPHAI( J ) = ZERO
+         BETA( J ) = T( J, J )
+  410 CONTINUE
+*
+*     Normal Termination
+*
+      INFO = 0
+*
+*     Exit (other than argument error) -- return optimal workspace size
+*
+  420 CONTINUE
+      WORK( 1 ) = REAL( N )
+      RETURN
+*
+*     End of SHGEQZ
+*
+      END
diff --git a/libcruft/lapack/shseqr.f b/libcruft/lapack/shseqr.f
new file mode 100644
index 0000000..5f5ee19
--- /dev/null
+++ b/libcruft/lapack/shseqr.f
@@ -0,0 +1,407 @@
+      SUBROUTINE SHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,
+     $                   LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDH, LDZ, LWORK, N
+      CHARACTER          COMPZ, JOB
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), WI( * ), WORK( * ), WR( * ),
+     $                   Z( LDZ, * )
+*     ..
+*     Purpose
+*     =======
+*
+*     SHSEQR computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**T, where T is an upper quasi-triangular matrix (the
+*     Schur form), and Z is the orthogonal matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input orthogonal
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
+*
+*     Arguments
+*     =========
+*
+*     JOB   (input) CHARACTER*1
+*           = 'E':  compute eigenvalues only;
+*           = 'S':  compute eigenvalues and the Schur form T.
+*
+*     COMPZ (input) CHARACTER*1
+*           = 'N':  no Schur vectors are computed;
+*           = 'I':  Z is initialized to the unit matrix and the matrix Z
+*                   of Schur vectors of H is returned;
+*           = 'V':  Z must contain an orthogonal matrix Q on entry, and
+*                   the product Q*Z is returned.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*           set by a previous call to SGEBAL, and then passed to SGEHRD
+*           when the matrix output by SGEBAL is reduced to Hessenberg
+*           form. Otherwise ILO and IHI should be set to 1 and N
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) REAL array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and JOB = 'S', then H contains the
+*           upper quasi-triangular matrix T from the Schur decomposition
+*           (the Schur form); 2-by-2 diagonal blocks (corresponding to
+*           complex conjugate pairs of eigenvalues) are returned in
+*           standard form, with H(i,i) = H(i+1,i+1) and
+*           H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and JOB = 'E', the
+*           contents of H are unspecified on exit.  (The output value of
+*           H when INFO.GT.0 is given under the description of INFO
+*           below.)
+*
+*           Unlike earlier versions of SHSEQR, this subroutine may
+*           explicitly H(i,j) = 0 for i.GT.j and j = 1, 2, ... ILO-1
+*           or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     WR    (output) REAL array, dimension (N)
+*     WI    (output) REAL array, dimension (N)
+*           The real and imaginary parts, respectively, of the computed
+*           eigenvalues. If two eigenvalues are computed as a complex
+*           conjugate pair, they are stored in consecutive elements of
+*           WR and WI, say the i-th and (i+1)th, with WI(i) .GT. 0 and
+*           WI(i+1) .LT. 0. If JOB = 'S', the eigenvalues are stored in
+*           the same order as on the diagonal of the Schur form returned
+*           in H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2
+*           diagonal block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and
+*           WI(i+1) = -WI(i).
+*
+*     Z     (input/output) REAL array, dimension (LDZ,N)
+*           If COMPZ = 'N', Z is not referenced.
+*           If COMPZ = 'I', on entry Z need not be set and on exit,
+*           if INFO = 0, Z contains the orthogonal matrix Z of the Schur
+*           vectors of H.  If COMPZ = 'V', on entry Z must contain an
+*           N-by-N matrix Q, which is assumed to be equal to the unit
+*           matrix except for the submatrix Z(ILO:IHI,ILO:IHI). On exit,
+*           if INFO = 0, Z contains Q*Z.
+*           Normally Q is the orthogonal matrix generated by SORGHR
+*           after the call to SGEHRD which formed the Hessenberg matrix
+*           H. (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if COMPZ = 'I' or
+*           COMPZ = 'V', then LDZ.GE.MAX(1,N).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) REAL array, dimension (LWORK)
+*           On exit, if INFO = 0, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then SHSEQR does a workspace query.
+*           In this case, SHSEQR checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .LT. 0:  if INFO = -i, the i-th argument had an illegal
+*                    value
+*           .GT. 0:  if INFO = i, SHSEQR failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and JOB = 'E', then on exit, the
+*                remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and JOB   = 'S', then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is an orthogonal matrix.  The final
+*                value of H is upper Hessenberg and quasi-triangular
+*                in rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and COMPZ = 'V', then on exit
+*
+*                  (final value of Z)  =  (initial value of Z)*U
+*
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'I', then on exit
+*                      (final value of Z)  = U
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'N', then Z is not
+*                accessed.
+*
+*     ================================================================
+*             Default values supplied by
+*             ILAENV(ISPEC,'SHSEQR',JOB(:1)//COMPZ(:1),N,ILO,IHI,LWORK).
+*             It is suggested that these defaults be adjusted in order
+*             to attain best performance in each particular
+*             computational environment.
+*
+*            ISPEC=1:  The SLAHQR vs SLAQR0 crossover point.
+*                      Default: 75. (Must be at least 11.)
+*
+*            ISPEC=2:  Recommended deflation window size.
+*                      This depends on ILO, IHI and NS.  NS is the
+*                      number of simultaneous shifts returned
+*                      by ILAENV(ISPEC=4).  (See ISPEC=4 below.)
+*                      The default for (IHI-ILO+1).LE.500 is NS.
+*                      The default for (IHI-ILO+1).GT.500 is 3*NS/2.
+*
+*            ISPEC=3:  Nibble crossover point. (See ILAENV for
+*                      details.)  Default: 14% of deflation window
+*                      size.
+*
+*            ISPEC=4:  Number of simultaneous shifts, NS, in
+*                      a multi-shift QR iteration.
+*
+*                      If IHI-ILO+1 is ...
+*
+*                      greater than      ...but less    ... the
+*                      or equal to ...      than        default is
+*
+*                           1               30          NS -   2(+)
+*                          30               60          NS -   4(+)
+*                          60              150          NS =  10(+)
+*                         150              590          NS =  **
+*                         590             3000          NS =  64
+*                        3000             6000          NS = 128
+*                        6000             infinity      NS = 256
+*
+*                  (+)  By default some or all matrices of this order 
+*                       are passed to the implicit double shift routine
+*                       SLAHQR and NS is ignored.  See ISPEC=1 above 
+*                       and comments in IPARM for details.
+*
+*                       The asterisks (**) indicate an ad-hoc
+*                       function of N increasing from 10 to 64.
+*
+*            ISPEC=5:  Select structured matrix multiply.
+*                      (See ILAENV for details.) Default: 3.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    SLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== NL allocates some local workspace to help small matrices
+*     .    through a rare SLAHQR failure.  NL .GT. NTINY = 11 is
+*     .    required and NL .LE. NMIN = ILAENV(ISPEC=1,...) is recom-
+*     .    mended.  (The default value of NMIN is 75.)  Using NL = 49
+*     .    allows up to six simultaneous shifts and a 16-by-16
+*     .    deflation window.  ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            NL
+      PARAMETER          ( NL = 49 )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0 )
+*     ..
+*     .. Local Arrays ..
+      REAL               HL( NL, NL ), WORKL( NL )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, KBOT, NMIN
+      LOGICAL            INITZ, LQUERY, WANTT, WANTZ
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      LOGICAL            LSAME
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACPY, SLAHQR, SLAQR0, SLASET, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Decode and check the input parameters. ====
+*
+      WANTT = LSAME( JOB, 'S' )
+      INITZ = LSAME( COMPZ, 'I' )
+      WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )
+      WORK( 1 ) = REAL( MAX( 1, N ) )
+      LQUERY = LWORK.EQ.-1
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( LDH.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -13
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+*
+*        ==== Quick return in case of invalid argument. ====
+*
+         CALL XERBLA( 'SHSEQR', -INFO )
+         RETURN
+*
+      ELSE IF( N.EQ.0 ) THEN
+*
+*        ==== Quick return in case N = 0; nothing to do. ====
+*
+         RETURN
+*
+      ELSE IF( LQUERY ) THEN
+*
+*        ==== Quick return in case of a workspace query ====
+*
+         CALL SLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,
+     $                IHI, Z, LDZ, WORK, LWORK, INFO )
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+         WORK( 1 ) = MAX( REAL( MAX( 1, N ) ), WORK( 1 ) )
+         RETURN
+*
+      ELSE
+*
+*        ==== copy eigenvalues isolated by SGEBAL ====
+*
+         DO 10 I = 1, ILO - 1
+            WR( I ) = H( I, I )
+            WI( I ) = ZERO
+   10    CONTINUE
+         DO 20 I = IHI + 1, N
+            WR( I ) = H( I, I )
+            WI( I ) = ZERO
+   20    CONTINUE
+*
+*        ==== Initialize Z, if requested ====
+*
+         IF( INITZ )
+     $      CALL SLASET( 'A', N, N, ZERO, ONE, Z, LDZ )
+*
+*        ==== Quick return if possible ====
+*
+         IF( ILO.EQ.IHI ) THEN
+            WR( ILO ) = H( ILO, ILO )
+            WI( ILO ) = ZERO
+            RETURN
+         END IF
+*
+*        ==== SLAHQR/SLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 1, 'SHSEQR', JOB( : 1 ) // COMPZ( : 1 ), N, ILO,
+     $          IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== SLAQR0 for big matrices; SLAHQR for small ones ====
+*
+         IF( N.GT.NMIN ) THEN
+            CALL SLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,
+     $                   IHI, Z, LDZ, WORK, LWORK, INFO )
+         ELSE
+*
+*           ==== Small matrix ====
+*
+            CALL SLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,
+     $                   IHI, Z, LDZ, INFO )
+*
+            IF( INFO.GT.0 ) THEN
+*
+*              ==== A rare SLAHQR failure!  SLAQR0 sometimes succeeds
+*              .    when SLAHQR fails. ====
+*
+               KBOT = INFO
+*
+               IF( N.GE.NL ) THEN
+*
+*                 ==== Larger matrices have enough subdiagonal scratch
+*                 .    space to call SLAQR0 directly. ====
+*
+                  CALL SLAQR0( WANTT, WANTZ, N, ILO, KBOT, H, LDH, WR,
+     $                         WI, ILO, IHI, Z, LDZ, WORK, LWORK, INFO )
+*
+               ELSE
+*
+*                 ==== Tiny matrices don't have enough subdiagonal
+*                 .    scratch space to benefit from SLAQR0.  Hence,
+*                 .    tiny matrices must be copied into a larger
+*                 .    array before calling SLAQR0. ====
+*
+                  CALL SLACPY( 'A', N, N, H, LDH, HL, NL )
+                  HL( N+1, N ) = ZERO
+                  CALL SLASET( 'A', NL, NL-N, ZERO, ZERO, HL( 1, N+1 ),
+     $                         NL )
+                  CALL SLAQR0( WANTT, WANTZ, NL, ILO, KBOT, HL, NL, WR,
+     $                         WI, ILO, IHI, Z, LDZ, WORKL, NL, INFO )
+                  IF( WANTT .OR. INFO.NE.0 )
+     $               CALL SLACPY( 'A', N, N, HL, NL, H, LDH )
+               END IF
+            END IF
+         END IF
+*
+*        ==== Clear out the trash, if necessary. ====
+*
+         IF( ( WANTT .OR. INFO.NE.0 ) .AND. N.GT.2 )
+     $      CALL SLASET( 'L', N-2, N-2, ZERO, ZERO, H( 3, 1 ), LDH )
+*
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+*
+         WORK( 1 ) = MAX( REAL( MAX( 1, N ) ), WORK( 1 ) )
+      END IF
+*
+*     ==== End of SHSEQR ====
+*
+      END
diff --git a/libcruft/lapack/slabad.f b/libcruft/lapack/slabad.f
new file mode 100644
index 0000000..6de6a31
--- /dev/null
+++ b/libcruft/lapack/slabad.f
@@ -0,0 +1,55 @@
+      SUBROUTINE SLABAD( SMALL, LARGE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               LARGE, SMALL
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLABAD takes as input the values computed by SLAMCH for underflow and
+*  overflow, and returns the square root of each of these values if the
+*  log of LARGE is sufficiently large.  This subroutine is intended to
+*  identify machines with a large exponent range, such as the Crays, and
+*  redefine the underflow and overflow limits to be the square roots of
+*  the values computed by SLAMCH.  This subroutine is needed because
+*  SLAMCH does not compensate for poor arithmetic in the upper half of
+*  the exponent range, as is found on a Cray.
+*
+*  Arguments
+*  =========
+*
+*  SMALL   (input/output) REAL
+*          On entry, the underflow threshold as computed by SLAMCH.
+*          On exit, if LOG10(LARGE) is sufficiently large, the square
+*          root of SMALL, otherwise unchanged.
+*
+*  LARGE   (input/output) REAL
+*          On entry, the overflow threshold as computed by SLAMCH.
+*          On exit, if LOG10(LARGE) is sufficiently large, the square
+*          root of LARGE, otherwise unchanged.
+*
+*  =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC          LOG10, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     If it looks like we're on a Cray, take the square root of
+*     SMALL and LARGE to avoid overflow and underflow problems.
+*
+      IF( LOG10( LARGE ).GT.2000. ) THEN
+         SMALL = SQRT( SMALL )
+         LARGE = SQRT( LARGE )
+      END IF
+*
+      RETURN
+*
+*     End of SLABAD
+*
+      END
diff --git a/libcruft/lapack/slabrd.f b/libcruft/lapack/slabrd.f
new file mode 100644
index 0000000..c11b23e
--- /dev/null
+++ b/libcruft/lapack/slabrd.f
@@ -0,0 +1,290 @@
+      SUBROUTINE SLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,
+     $                   LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, LDX, LDY, M, N, NB
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), D( * ), E( * ), TAUP( * ),
+     $                   TAUQ( * ), X( LDX, * ), Y( LDY, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLABRD reduces the first NB rows and columns of a real general
+*  m by n matrix A to upper or lower bidiagonal form by an orthogonal
+*  transformation Q' * A * P, and returns the matrices X and Y which
+*  are needed to apply the transformation to the unreduced part of A.
+*
+*  If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower
+*  bidiagonal form.
+*
+*  This is an auxiliary routine called by SGEBRD
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of leading rows and columns of A to be reduced.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit, the first NB rows and columns of the matrix are
+*          overwritten; the rest of the array is unchanged.
+*          If m >= n, elements on and below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the orthogonal
+*            matrix Q as a product of elementary reflectors; and
+*            elements above the diagonal in the first NB rows, with the
+*            array TAUP, represent the orthogonal matrix P as a product
+*            of elementary reflectors.
+*          If m < n, elements below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the orthogonal
+*            matrix Q as a product of elementary reflectors, and
+*            elements on and above the diagonal in the first NB rows,
+*            with the array TAUP, represent the orthogonal matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) REAL array, dimension (NB)
+*          The diagonal elements of the first NB rows and columns of
+*          the reduced matrix.  D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (NB)
+*          The off-diagonal elements of the first NB rows and columns of
+*          the reduced matrix.
+*
+*  TAUQ    (output) REAL array dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix Q. See Further Details.
+*
+*  TAUP    (output) REAL array, dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the orthogonal matrix P. See Further Details.
+*
+*  X       (output) REAL array, dimension (LDX,NB)
+*          The m-by-nb matrix X required to update the unreduced part
+*          of A.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of the array X. LDX >= M.
+*
+*  Y       (output) REAL array, dimension (LDY,NB)
+*          The n-by-nb matrix Y required to update the unreduced part
+*          of A.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*     Q = H(1) H(2) . . . H(nb)  and  P = G(1) G(2) . . . G(nb)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are real scalars, and v and u are real vectors.
+*
+*  If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in
+*  A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in
+*  A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The elements of the vectors v and u together form the m-by-nb matrix
+*  V and the nb-by-n matrix U' which are needed, with X and Y, to apply
+*  the transformation to the unreduced part of the matrix, using a block
+*  update of the form:  A := A - V*Y' - X*U'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with nb = 2:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  1   1   u1  u1  u1 )           (  1   u1  u1  u1  u1  u1 )
+*    (  v1  1   1   u2  u2 )           (  1   1   u2  u2  u2  u2 )
+*    (  v1  v2  a   a   a  )           (  v1  1   a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )
+*
+*  where a denotes an element of the original matrix which is unchanged,
+*  vi denotes an element of the vector defining H(i), and ui an element
+*  of the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SLARFG, SSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, NB
+*
+*           Update A(i:m,i)
+*
+            CALL SGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 )
+            CALL SGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ),
+     $                  LDX, A( 1, I ), 1, ONE, A( I, I ), 1 )
+*
+*           Generate reflection Q(i) to annihilate A(i+1:m,i)
+*
+            CALL SLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL SGEMV( 'Transpose', M-I+1, N-I, ONE, A( I, I+1 ),
+     $                     LDA, A( I, I ), 1, ZERO, Y( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', M-I+1, I-1, ONE, A( I, 1 ), LDA,
+     $                     A( I, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', M-I+1, I-1, ONE, X( I, 1 ), LDX,
+     $                     A( I, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL SGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL SSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+*
+*              Update A(i,i+1:n)
+*
+               CALL SGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ),
+     $                     LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA )
+               CALL SGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, X( I, 1 ), LDX, ONE, A( I, I+1 ), LDA )
+*
+*              Generate reflection P(i) to annihilate A(i,i+2:n)
+*
+               CALL SLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),
+     $                      LDA, TAUP( I ) )
+               E( I ) = A( I, I+1 )
+               A( I, I+1 ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL SGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', N-I, I, ONE, Y( I+1, 1 ), LDY,
+     $                     A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL SGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL SSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i,i:n)
+*
+            CALL SGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ),
+     $                  LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA )
+            CALL SGEMV( 'Transpose', I-1, N-I+1, -ONE, A( 1, I ), LDA,
+     $                  X( I, 1 ), LDX, ONE, A( I, I ), LDA )
+*
+*           Generate reflection P(i) to annihilate A(i,i+1:n)
+*
+            CALL SLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = A( I, I )
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL SGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', N-I+1, I-1, ONE, Y( I, 1 ), LDY,
+     $                     A( I, I ), LDA, ZERO, X( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL SGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL SSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+*
+*              Update A(i+1:m,i)
+*
+               CALL SGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 )
+               CALL SGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ),
+     $                     LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 )
+*
+*              Generate reflection Q(i) to annihilate A(i+2:m,i)
+*
+               CALL SLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = A( I+1, I )
+               A( I+1, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL SGEMV( 'Transpose', M-I, N-I, ONE, A( I+1, I+1 ),
+     $                     LDA, A( I+1, I ), 1, ZERO, Y( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', M-I, I-1, ONE, A( I+1, 1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', M-I, I, ONE, X( I+1, 1 ), LDX,
+     $                     A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )
+               CALL SGEMV( 'Transpose', I, N-I, -ONE, A( 1, I+1 ), LDA,
+     $                     Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL SSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SLABRD
+*
+      END
diff --git a/libcruft/lapack/slacn2.f b/libcruft/lapack/slacn2.f
new file mode 100644
index 0000000..7ee6a41
--- /dev/null
+++ b/libcruft/lapack/slacn2.f
@@ -0,0 +1,214 @@
+      SUBROUTINE SLACN2( N, V, X, ISGN, EST, KASE, ISAVE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      REAL               EST
+*     ..
+*     .. Array Arguments ..
+      INTEGER            ISGN( * ), ISAVE( 3 )
+      REAL               V( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLACN2 estimates the 1-norm of a square, real matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) REAL array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) REAL array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         and SLACN2 must be re-called with all the other parameters
+*         unchanged.
+*
+*  ISGN   (workspace) INTEGER array, dimension (N)
+*
+*  EST    (input/output) REAL
+*         On entry with KASE = 1 or 2 and ISAVE(1) = 3, EST should be
+*         unchanged from the previous call to SLACN2.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to SLACN2, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from SLACN2, KASE will again be 0.
+*
+*  ISAVE  (input/output) INTEGER array, dimension (3)
+*         ISAVE is used to save variables between calls to SLACN2
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named SONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  This is a thread safe version of SLACON, which uses the array ISAVE
+*  in place of a SAVE statement, as follows:
+*
+*     SLACON     SLACN2
+*      JUMP     ISAVE(1)
+*      J        ISAVE(2)
+*      ITER     ISAVE(3)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, JLAST
+      REAL               ALTSGN, ESTOLD, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SASUM
+      EXTERNAL           ISAMAX, SASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, NINT, REAL, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = ONE / REAL( N )
+   10    CONTINUE
+         KASE = 1
+         ISAVE( 1 ) = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 110, 140 )ISAVE( 1 )
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 150
+      END IF
+      EST = SASUM( N, X, 1 )
+*
+      DO 30 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+   30 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 2
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+   40 CONTINUE
+      ISAVE( 2 ) = ISAMAX( N, X, 1 )
+      ISAVE( 3 ) = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = ZERO
+   60 CONTINUE
+      X( ISAVE( 2 ) ) = ONE
+      KASE = 1
+      ISAVE( 1 ) = 3
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL SCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = SASUM( N, V, 1 )
+      DO 80 I = 1, N
+         IF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )
+     $      GO TO 90
+   80 CONTINUE
+*     REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.
+      GO TO 120
+*
+   90 CONTINUE
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 120
+*
+      DO 100 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+  100 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 4
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 4)
+*     X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+  110 CONTINUE
+      JLAST = ISAVE( 2 )
+      ISAVE( 2 ) = ISAMAX( N, X, 1 )
+      IF( ( X( JLAST ).NE.ABS( X( ISAVE( 2 ) ) ) ) .AND.
+     $    ( ISAVE( 3 ).LT.ITMAX ) ) THEN
+         ISAVE( 3 ) = ISAVE( 3 ) + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  120 CONTINUE
+      ALTSGN = ONE
+      DO 130 I = 1, N
+         X( I ) = ALTSGN*( ONE+REAL( I-1 ) / REAL( N-1 ) )
+         ALTSGN = -ALTSGN
+  130 CONTINUE
+      KASE = 1
+      ISAVE( 1 ) = 5
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  140 CONTINUE
+      TEMP = TWO*( SASUM( N, X, 1 ) / REAL( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL SCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  150 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of SLACN2
+*
+      END
diff --git a/libcruft/lapack/slacon.f b/libcruft/lapack/slacon.f
new file mode 100644
index 0000000..1d50b5f
--- /dev/null
+++ b/libcruft/lapack/slacon.f
@@ -0,0 +1,205 @@
+      SUBROUTINE SLACON( N, V, X, ISGN, EST, KASE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      REAL               EST
+*     ..
+*     .. Array Arguments ..
+      INTEGER            ISGN( * )
+      REAL               V( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLACON estimates the 1-norm of a square, real matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) REAL array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) REAL array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         and SLACON must be re-called with all the other parameters
+*         unchanged.
+*
+*  ISGN   (workspace) INTEGER array, dimension (N)
+*
+*  EST    (input/output) REAL
+*         On entry with KASE = 1 or 2 and JUMP = 3, EST should be
+*         unchanged from the previous call to SLACON.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to SLACON, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from SLACON, KASE will again be 0.
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named SONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITER, J, JLAST, JUMP
+      REAL               ALTSGN, ESTOLD, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SASUM
+      EXTERNAL           ISAMAX, SASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, NINT, REAL, SIGN
+*     ..
+*     .. Save statement ..
+      SAVE
+*     ..
+*     .. Executable Statements ..
+*
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = ONE / REAL( N )
+   10    CONTINUE
+         KASE = 1
+         JUMP = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 110, 140 )JUMP
+*
+*     ................ ENTRY   (JUMP = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 150
+      END IF
+      EST = SASUM( N, X, 1 )
+*
+      DO 30 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+   30 CONTINUE
+      KASE = 2
+      JUMP = 2
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+   40 CONTINUE
+      J = ISAMAX( N, X, 1 )
+      ITER = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = ZERO
+   60 CONTINUE
+      X( J ) = ONE
+      KASE = 1
+      JUMP = 3
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL SCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = SASUM( N, V, 1 )
+      DO 80 I = 1, N
+         IF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )
+     $      GO TO 90
+   80 CONTINUE
+*     REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.
+      GO TO 120
+*
+   90 CONTINUE
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 120
+*
+      DO 100 I = 1, N
+         X( I ) = SIGN( ONE, X( I ) )
+         ISGN( I ) = NINT( X( I ) )
+  100 CONTINUE
+      KASE = 2
+      JUMP = 4
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 4)
+*     X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.
+*
+  110 CONTINUE
+      JLAST = J
+      J = ISAMAX( N, X, 1 )
+      IF( ( X( JLAST ).NE.ABS( X( J ) ) ) .AND. ( ITER.LT.ITMAX ) ) THEN
+         ITER = ITER + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  120 CONTINUE
+      ALTSGN = ONE
+      DO 130 I = 1, N
+         X( I ) = ALTSGN*( ONE+REAL( I-1 ) / REAL( N-1 ) )
+         ALTSGN = -ALTSGN
+  130 CONTINUE
+      KASE = 1
+      JUMP = 5
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  140 CONTINUE
+      TEMP = TWO*( SASUM( N, X, 1 ) / REAL( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL SCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  150 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of SLACON
+*
+      END
diff --git a/libcruft/lapack/slacpy.f b/libcruft/lapack/slacpy.f
new file mode 100644
index 0000000..993705d
--- /dev/null
+++ b/libcruft/lapack/slacpy.f
@@ -0,0 +1,87 @@
+      SUBROUTINE SLACPY( UPLO, M, N, A, LDA, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDB, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLACPY copies all or part of a two-dimensional matrix A to another
+*  matrix B.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be copied to B.
+*          = 'U':      Upper triangular part
+*          = 'L':      Lower triangular part
+*          Otherwise:  All of the matrix A
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The m by n matrix A.  If UPLO = 'U', only the upper triangle
+*          or trapezoid is accessed; if UPLO = 'L', only the lower
+*          triangle or trapezoid is accessed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (output) REAL array, dimension (LDB,N)
+*          On exit, B = A in the locations specified by UPLO.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( J, M )
+               B( I, J ) = A( I, J )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+         DO 40 J = 1, N
+            DO 30 I = J, M
+               B( I, J ) = A( I, J )
+   30       CONTINUE
+   40    CONTINUE
+      ELSE
+         DO 60 J = 1, N
+            DO 50 I = 1, M
+               B( I, J ) = A( I, J )
+   50       CONTINUE
+   60    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SLACPY
+*
+      END
diff --git a/libcruft/lapack/sladiv.f b/libcruft/lapack/sladiv.f
new file mode 100644
index 0000000..f487d55
--- /dev/null
+++ b/libcruft/lapack/sladiv.f
@@ -0,0 +1,62 @@
+      SUBROUTINE SLADIV( A, B, C, D, P, Q )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               A, B, C, D, P, Q
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLADIV performs complex division in  real arithmetic
+*
+*                        a + i*b
+*             p + i*q = ---------
+*                        c + i*d
+*
+*  The algorithm is due to Robert L. Smith and can be found
+*  in D. Knuth, The art of Computer Programming, Vol.2, p.195
+*
+*  Arguments
+*  =========
+*
+*  A       (input) REAL
+*  B       (input) REAL
+*  C       (input) REAL
+*  D       (input) REAL
+*          The scalars a, b, c, and d in the above expression.
+*
+*  P       (output) REAL
+*  Q       (output) REAL
+*          The scalars p and q in the above expression.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL               E, F
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+      IF( ABS( D ).LT.ABS( C ) ) THEN
+         E = D / C
+         F = C + D*E
+         P = ( A+B*E ) / F
+         Q = ( B-A*E ) / F
+      ELSE
+         E = C / D
+         F = D + C*E
+         P = ( B+A*E ) / F
+         Q = ( -A+B*E ) / F
+      END IF
+*
+      RETURN
+*
+*     End of SLADIV
+*
+      END
diff --git a/libcruft/lapack/slae2.f b/libcruft/lapack/slae2.f
new file mode 100644
index 0000000..beb4595
--- /dev/null
+++ b/libcruft/lapack/slae2.f
@@ -0,0 +1,123 @@
+      SUBROUTINE SLAE2( A, B, C, RT1, RT2 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               A, B, C, RT1, RT2
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAE2  computes the eigenvalues of a 2-by-2 symmetric matrix
+*     [  A   B  ]
+*     [  B   C  ].
+*  On return, RT1 is the eigenvalue of larger absolute value, and RT2
+*  is the eigenvalue of smaller absolute value.
+*
+*  Arguments
+*  =========
+*
+*  A       (input) REAL
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  B       (input) REAL
+*          The (1,2) and (2,1) elements of the 2-by-2 matrix.
+*
+*  C       (input) REAL
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  RT1     (output) REAL
+*          The eigenvalue of larger absolute value.
+*
+*  RT2     (output) REAL
+*          The eigenvalue of smaller absolute value.
+*
+*  Further Details
+*  ===============
+*
+*  RT1 is accurate to a few ulps barring over/underflow.
+*
+*  RT2 may be inaccurate if there is massive cancellation in the
+*  determinant A*C-B*B; higher precision or correctly rounded or
+*  correctly truncated arithmetic would be needed to compute RT2
+*  accurately in all cases.
+*
+*  Overflow is possible only if RT1 is within a factor of 5 of overflow.
+*  Underflow is harmless if the input data is 0 or exceeds
+*     underflow_threshold / macheps.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E0 )
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               HALF
+      PARAMETER          ( HALF = 0.5E0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AB, ACMN, ACMX, ADF, DF, RT, SM, TB
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Compute the eigenvalues
+*
+      SM = A + C
+      DF = A - C
+      ADF = ABS( DF )
+      TB = B + B
+      AB = ABS( TB )
+      IF( ABS( A ).GT.ABS( C ) ) THEN
+         ACMX = A
+         ACMN = C
+      ELSE
+         ACMX = C
+         ACMN = A
+      END IF
+      IF( ADF.GT.AB ) THEN
+         RT = ADF*SQRT( ONE+( AB / ADF )**2 )
+      ELSE IF( ADF.LT.AB ) THEN
+         RT = AB*SQRT( ONE+( ADF / AB )**2 )
+      ELSE
+*
+*        Includes case AB=ADF=0
+*
+         RT = AB*SQRT( TWO )
+      END IF
+      IF( SM.LT.ZERO ) THEN
+         RT1 = HALF*( SM-RT )
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE IF( SM.GT.ZERO ) THEN
+         RT1 = HALF*( SM+RT )
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE
+*
+*        Includes case RT1 = RT2 = 0
+*
+         RT1 = HALF*RT
+         RT2 = -HALF*RT
+      END IF
+      RETURN
+*
+*     End of SLAE2
+*
+      END
diff --git a/libcruft/lapack/slaed6.f b/libcruft/lapack/slaed6.f
new file mode 100644
index 0000000..0346462
--- /dev/null
+++ b/libcruft/lapack/slaed6.f
@@ -0,0 +1,327 @@
+      SUBROUTINE SLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     February 2007
+*
+*     .. Scalar Arguments ..
+      LOGICAL            ORGATI
+      INTEGER            INFO, KNITER
+      REAL               FINIT, RHO, TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               D( 3 ), Z( 3 )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAED6 computes the positive or negative root (closest to the origin)
+*  of
+*                   z(1)        z(2)        z(3)
+*  f(x) =   rho + --------- + ---------- + ---------
+*                  d(1)-x      d(2)-x      d(3)-x
+*
+*  It is assumed that
+*
+*        if ORGATI = .true. the root is between d(2) and d(3);
+*        otherwise it is between d(1) and d(2)
+*
+*  This routine will be called by SLAED4 when necessary. In most cases,
+*  the root sought is the smallest in magnitude, though it might not be
+*  in some extremely rare situations.
+*
+*  Arguments
+*  =========
+*
+*  KNITER       (input) INTEGER
+*               Refer to SLAED4 for its significance.
+*
+*  ORGATI       (input) LOGICAL
+*               If ORGATI is true, the needed root is between d(2) and
+*               d(3); otherwise it is between d(1) and d(2).  See
+*               SLAED4 for further details.
+*
+*  RHO          (input) REAL            
+*               Refer to the equation f(x) above.
+*
+*  D            (input) REAL array, dimension (3)
+*               D satisfies d(1) < d(2) < d(3).
+*
+*  Z            (input) REAL array, dimension (3)
+*               Each of the elements in z must be positive.
+*
+*  FINIT        (input) REAL            
+*               The value of f at 0. It is more accurate than the one
+*               evaluated inside this routine (if someone wants to do
+*               so).
+*
+*  TAU          (output) REAL            
+*               The root of the equation f(x).
+*
+*  INFO         (output) INTEGER
+*               = 0: successful exit
+*               > 0: if INFO = 1, failure to converge
+*
+*  Further Details
+*  ===============
+*
+*  30/06/99: Based on contributions by
+*     Ren-Cang Li, Computer Science Division, University of California
+*     at Berkeley, USA
+*
+*  10/02/03: This version has a few statements commented out for thread safety
+*     (machine parameters are computed on each entry). SJH.
+*
+*  05/10/06: Modified from a new version of Ren-Cang Li, use
+*     Gragg-Thornton-Warner cubic convergent scheme for better stability.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 40 )
+      REAL               ZERO, ONE, TWO, THREE, FOUR, EIGHT
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
+     $                   THREE = 3.0E0, FOUR = 4.0E0, EIGHT = 8.0E0 )
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Local Arrays ..
+      REAL               DSCALE( 3 ), ZSCALE( 3 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            SCALE
+      INTEGER            I, ITER, NITER
+      REAL               A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,
+     $                   FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,
+     $                   SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4, 
+     $                   LBD, UBD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, LOG, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+      IF( ORGATI ) THEN
+         LBD = D(2)
+         UBD = D(3)
+      ELSE
+         LBD = D(1)
+         UBD = D(2)
+      END IF
+      IF( FINIT .LT. ZERO )THEN
+         LBD = ZERO
+      ELSE
+         UBD = ZERO 
+      END IF
+*
+      NITER = 1
+      TAU = ZERO
+      IF( KNITER.EQ.2 ) THEN
+         IF( ORGATI ) THEN
+            TEMP = ( D( 3 )-D( 2 ) ) / TWO
+            C = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )
+            A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )
+            B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )
+         ELSE
+            TEMP = ( D( 1 )-D( 2 ) ) / TWO
+            C = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )
+            A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )
+            B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )
+         END IF
+         TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
+         A = A / TEMP
+         B = B / TEMP
+         C = C / TEMP
+         IF( C.EQ.ZERO ) THEN
+            TAU = B / A
+         ELSE IF( A.LE.ZERO ) THEN
+            TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+         ELSE
+            TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+         END IF
+         IF( TAU .LT. LBD .OR. TAU .GT. UBD )
+     $      TAU = ( LBD+UBD )/TWO
+         IF( D(1).EQ.TAU .OR. D(2).EQ.TAU .OR. D(3).EQ.TAU ) THEN
+            TAU = ZERO
+         ELSE
+            TEMP = FINIT + TAU*Z(1)/( D(1)*( D( 1 )-TAU ) ) +
+     $                     TAU*Z(2)/( D(2)*( D( 2 )-TAU ) ) +
+     $                     TAU*Z(3)/( D(3)*( D( 3 )-TAU ) )
+            IF( TEMP .LE. ZERO )THEN
+               LBD = TAU
+            ELSE
+               UBD = TAU
+            END IF
+            IF( ABS( FINIT ).LE.ABS( TEMP ) )
+     $         TAU = ZERO
+         END IF
+      END IF
+*
+*     get machine parameters for possible scaling to avoid overflow
+*
+*     modified by Sven: parameters SMALL1, SMINV1, SMALL2,
+*     SMINV2, EPS are not SAVEd anymore between one call to the
+*     others but recomputed at each call
+*
+      EPS = SLAMCH( 'Epsilon' )
+      BASE = SLAMCH( 'Base' )
+      SMALL1 = BASE**( INT( LOG( SLAMCH( 'SafMin' ) ) / LOG( BASE ) /
+     $         THREE ) )
+      SMINV1 = ONE / SMALL1
+      SMALL2 = SMALL1*SMALL1
+      SMINV2 = SMINV1*SMINV1
+*
+*     Determine if scaling of inputs necessary to avoid overflow
+*     when computing 1/TEMP**3
+*
+      IF( ORGATI ) THEN
+         TEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )
+      ELSE
+         TEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )
+      END IF
+      SCALE = .FALSE.
+      IF( TEMP.LE.SMALL1 ) THEN
+         SCALE = .TRUE.
+         IF( TEMP.LE.SMALL2 ) THEN
+*
+*        Scale up by power of radix nearest 1/SAFMIN**(2/3)
+*
+            SCLFAC = SMINV2
+            SCLINV = SMALL2
+         ELSE
+*
+*        Scale up by power of radix nearest 1/SAFMIN**(1/3)
+*
+            SCLFAC = SMINV1
+            SCLINV = SMALL1
+         END IF
+*
+*        Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)
+*
+         DO 10 I = 1, 3
+            DSCALE( I ) = D( I )*SCLFAC
+            ZSCALE( I ) = Z( I )*SCLFAC
+   10    CONTINUE
+         TAU = TAU*SCLFAC
+         LBD = LBD*SCLFAC
+         UBD = UBD*SCLFAC
+      ELSE
+*
+*        Copy D and Z to DSCALE and ZSCALE
+*
+         DO 20 I = 1, 3
+            DSCALE( I ) = D( I )
+            ZSCALE( I ) = Z( I )
+   20    CONTINUE
+      END IF
+*
+      FC = ZERO
+      DF = ZERO
+      DDF = ZERO
+      DO 30 I = 1, 3
+         TEMP = ONE / ( DSCALE( I )-TAU )
+         TEMP1 = ZSCALE( I )*TEMP
+         TEMP2 = TEMP1*TEMP
+         TEMP3 = TEMP2*TEMP
+         FC = FC + TEMP1 / DSCALE( I )
+         DF = DF + TEMP2
+         DDF = DDF + TEMP3
+   30 CONTINUE
+      F = FINIT + TAU*FC
+*
+      IF( ABS( F ).LE.ZERO )
+     $   GO TO 60
+      IF( F .LE. ZERO )THEN
+         LBD = TAU
+      ELSE
+         UBD = TAU
+      END IF
+*
+*        Iteration begins -- Use Gragg-Thornton-Warner cubic convergent
+*                            scheme
+*
+*     It is not hard to see that
+*
+*           1) Iterations will go up monotonically
+*              if FINIT < 0;
+*
+*           2) Iterations will go down monotonically
+*              if FINIT > 0.
+*
+      ITER = NITER + 1
+*
+      DO 50 NITER = ITER, MAXIT
+*
+         IF( ORGATI ) THEN
+            TEMP1 = DSCALE( 2 ) - TAU
+            TEMP2 = DSCALE( 3 ) - TAU
+         ELSE
+            TEMP1 = DSCALE( 1 ) - TAU
+            TEMP2 = DSCALE( 2 ) - TAU
+         END IF
+         A = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DF
+         B = TEMP1*TEMP2*F
+         C = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDF
+         TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
+         A = A / TEMP
+         B = B / TEMP
+         C = C / TEMP
+         IF( C.EQ.ZERO ) THEN
+            ETA = B / A
+         ELSE IF( A.LE.ZERO ) THEN
+            ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+         ELSE
+            ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+         END IF
+         IF( F*ETA.GE.ZERO ) THEN
+            ETA = -F / DF
+         END IF
+*
+         TAU = TAU + ETA
+         IF( TAU .LT. LBD .OR. TAU .GT. UBD )
+     $      TAU = ( LBD + UBD )/TWO 
+*
+         FC = ZERO
+         ERRETM = ZERO
+         DF = ZERO
+         DDF = ZERO
+         DO 40 I = 1, 3
+            TEMP = ONE / ( DSCALE( I )-TAU )
+            TEMP1 = ZSCALE( I )*TEMP
+            TEMP2 = TEMP1*TEMP
+            TEMP3 = TEMP2*TEMP
+            TEMP4 = TEMP1 / DSCALE( I )
+            FC = FC + TEMP4
+            ERRETM = ERRETM + ABS( TEMP4 )
+            DF = DF + TEMP2
+            DDF = DDF + TEMP3
+   40    CONTINUE
+         F = FINIT + TAU*FC
+         ERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +
+     $            ABS( TAU )*DF
+         IF( ABS( F ).LE.EPS*ERRETM )
+     $      GO TO 60
+         IF( F .LE. ZERO )THEN
+            LBD = TAU
+         ELSE
+            UBD = TAU
+         END IF
+   50 CONTINUE
+      INFO = 1
+   60 CONTINUE
+*
+*     Undo scaling
+*
+      IF( SCALE )
+     $   TAU = TAU*SCLINV
+      RETURN
+*
+*     End of SLAED6
+*
+      END
diff --git a/libcruft/lapack/slaev2.f b/libcruft/lapack/slaev2.f
new file mode 100644
index 0000000..965cf60
--- /dev/null
+++ b/libcruft/lapack/slaev2.f
@@ -0,0 +1,169 @@
+      SUBROUTINE SLAEV2( A, B, C, RT1, RT2, CS1, SN1 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               A, B, C, CS1, RT1, RT2, SN1
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix
+*     [  A   B  ]
+*     [  B   C  ].
+*  On return, RT1 is the eigenvalue of larger absolute value, RT2 is the
+*  eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right
+*  eigenvector for RT1, giving the decomposition
+*
+*     [ CS1  SN1 ] [  A   B  ] [ CS1 -SN1 ]  =  [ RT1  0  ]
+*     [-SN1  CS1 ] [  B   C  ] [ SN1  CS1 ]     [  0  RT2 ].
+*
+*  Arguments
+*  =========
+*
+*  A       (input) REAL
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  B       (input) REAL
+*          The (1,2) element and the conjugate of the (2,1) element of
+*          the 2-by-2 matrix.
+*
+*  C       (input) REAL
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  RT1     (output) REAL
+*          The eigenvalue of larger absolute value.
+*
+*  RT2     (output) REAL
+*          The eigenvalue of smaller absolute value.
+*
+*  CS1     (output) REAL
+*  SN1     (output) REAL
+*          The vector (CS1, SN1) is a unit right eigenvector for RT1.
+*
+*  Further Details
+*  ===============
+*
+*  RT1 is accurate to a few ulps barring over/underflow.
+*
+*  RT2 may be inaccurate if there is massive cancellation in the
+*  determinant A*C-B*B; higher precision or correctly rounded or
+*  correctly truncated arithmetic would be needed to compute RT2
+*  accurately in all cases.
+*
+*  CS1 and SN1 are accurate to a few ulps barring over/underflow.
+*
+*  Overflow is possible only if RT1 is within a factor of 5 of overflow.
+*  Underflow is harmless if the input data is 0 or exceeds
+*     underflow_threshold / macheps.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E0 )
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               HALF
+      PARAMETER          ( HALF = 0.5E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            SGN1, SGN2
+      REAL               AB, ACMN, ACMX, ACS, ADF, CS, CT, DF, RT, SM,
+     $                   TB, TN
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Compute the eigenvalues
+*
+      SM = A + C
+      DF = A - C
+      ADF = ABS( DF )
+      TB = B + B
+      AB = ABS( TB )
+      IF( ABS( A ).GT.ABS( C ) ) THEN
+         ACMX = A
+         ACMN = C
+      ELSE
+         ACMX = C
+         ACMN = A
+      END IF
+      IF( ADF.GT.AB ) THEN
+         RT = ADF*SQRT( ONE+( AB / ADF )**2 )
+      ELSE IF( ADF.LT.AB ) THEN
+         RT = AB*SQRT( ONE+( ADF / AB )**2 )
+      ELSE
+*
+*        Includes case AB=ADF=0
+*
+         RT = AB*SQRT( TWO )
+      END IF
+      IF( SM.LT.ZERO ) THEN
+         RT1 = HALF*( SM-RT )
+         SGN1 = -1
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE IF( SM.GT.ZERO ) THEN
+         RT1 = HALF*( SM+RT )
+         SGN1 = 1
+*
+*        Order of execution important.
+*        To get fully accurate smaller eigenvalue,
+*        next line needs to be executed in higher precision.
+*
+         RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B
+      ELSE
+*
+*        Includes case RT1 = RT2 = 0
+*
+         RT1 = HALF*RT
+         RT2 = -HALF*RT
+         SGN1 = 1
+      END IF
+*
+*     Compute the eigenvector
+*
+      IF( DF.GE.ZERO ) THEN
+         CS = DF + RT
+         SGN2 = 1
+      ELSE
+         CS = DF - RT
+         SGN2 = -1
+      END IF
+      ACS = ABS( CS )
+      IF( ACS.GT.AB ) THEN
+         CT = -TB / CS
+         SN1 = ONE / SQRT( ONE+CT*CT )
+         CS1 = CT*SN1
+      ELSE
+         IF( AB.EQ.ZERO ) THEN
+            CS1 = ONE
+            SN1 = ZERO
+         ELSE
+            TN = -CS / TB
+            CS1 = ONE / SQRT( ONE+TN*TN )
+            SN1 = TN*CS1
+         END IF
+      END IF
+      IF( SGN1.EQ.SGN2 ) THEN
+         TN = CS1
+         CS1 = -SN1
+         SN1 = TN
+      END IF
+      RETURN
+*
+*     End of SLAEV2
+*
+      END
diff --git a/libcruft/lapack/slaexc.f b/libcruft/lapack/slaexc.f
new file mode 100644
index 0000000..bbc1679
--- /dev/null
+++ b/libcruft/lapack/slaexc.f
@@ -0,0 +1,353 @@
+      SUBROUTINE SLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,
+     $                   INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            WANTQ
+      INTEGER            INFO, J1, LDQ, LDT, N, N1, N2
+*     ..
+*     .. Array Arguments ..
+      REAL               Q( LDQ, * ), T( LDT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in
+*  an upper quasi-triangular matrix T by an orthogonal similarity
+*  transformation.
+*
+*  T must be in Schur canonical form, that is, block upper triangular
+*  with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block
+*  has its diagonal elemnts equal and its off-diagonal elements of
+*  opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  WANTQ   (input) LOGICAL
+*          = .TRUE. : accumulate the transformation in the matrix Q;
+*          = .FALSE.: do not accumulate the transformation.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) REAL array, dimension (LDT,N)
+*          On entry, the upper quasi-triangular matrix T, in Schur
+*          canonical form.
+*          On exit, the updated matrix T, again in Schur canonical form.
+*
+*  LDT     (input)  INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) REAL array, dimension (LDQ,N)
+*          On entry, if WANTQ is .TRUE., the orthogonal matrix Q.
+*          On exit, if WANTQ is .TRUE., the updated matrix Q.
+*          If WANTQ is .FALSE., Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= 1; and if WANTQ is .TRUE., LDQ >= N.
+*
+*  J1      (input) INTEGER
+*          The index of the first row of the first block T11.
+*
+*  N1      (input) INTEGER
+*          The order of the first block T11. N1 = 0, 1 or 2.
+*
+*  N2      (input) INTEGER
+*          The order of the second block T22. N2 = 0, 1 or 2.
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          = 1: the transformed matrix T would be too far from Schur
+*               form; the blocks are not swapped and T and Q are
+*               unchanged.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      REAL               TEN
+      PARAMETER          ( TEN = 1.0E+1 )
+      INTEGER            LDD, LDX
+      PARAMETER          ( LDD = 4, LDX = 2 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IERR, J2, J3, J4, K, ND
+      REAL               CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,
+     $                   T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,
+     $                   WR1, WR2, XNORM
+*     ..
+*     .. Local Arrays ..
+      REAL               D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),
+     $                   X( LDX, 2 )
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLANGE
+      EXTERNAL           SLAMCH, SLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACPY, SLANV2, SLARFG, SLARFX, SLARTG, SLASY2,
+     $                   SROT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. N1.EQ.0 .OR. N2.EQ.0 )
+     $   RETURN
+      IF( J1+N1.GT.N )
+     $   RETURN
+*
+      J2 = J1 + 1
+      J3 = J1 + 2
+      J4 = J1 + 3
+*
+      IF( N1.EQ.1 .AND. N2.EQ.1 ) THEN
+*
+*        Swap two 1-by-1 blocks.
+*
+         T11 = T( J1, J1 )
+         T22 = T( J2, J2 )
+*
+*        Determine the transformation to perform the interchange.
+*
+         CALL SLARTG( T( J1, J2 ), T22-T11, CS, SN, TEMP )
+*
+*        Apply transformation to the matrix T.
+*
+         IF( J3.LE.N )
+     $      CALL SROT( N-J1-1, T( J1, J3 ), LDT, T( J2, J3 ), LDT, CS,
+     $                 SN )
+         CALL SROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )
+*
+         T( J1, J1 ) = T22
+         T( J2, J2 ) = T11
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL SROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )
+         END IF
+*
+      ELSE
+*
+*        Swapping involves at least one 2-by-2 block.
+*
+*        Copy the diagonal block of order N1+N2 to the local array D
+*        and compute its norm.
+*
+         ND = N1 + N2
+         CALL SLACPY( 'Full', ND, ND, T( J1, J1 ), LDT, D, LDD )
+         DNORM = SLANGE( 'Max', ND, ND, D, LDD, WORK )
+*
+*        Compute machine-dependent threshold for test for accepting
+*        swap.
+*
+         EPS = SLAMCH( 'P' )
+         SMLNUM = SLAMCH( 'S' ) / EPS
+         THRESH = MAX( TEN*EPS*DNORM, SMLNUM )
+*
+*        Solve T11*X - X*T22 = scale*T12 for X.
+*
+         CALL SLASY2( .FALSE., .FALSE., -1, N1, N2, D, LDD,
+     $                D( N1+1, N1+1 ), LDD, D( 1, N1+1 ), LDD, SCALE, X,
+     $                LDX, XNORM, IERR )
+*
+*        Swap the adjacent diagonal blocks.
+*
+         K = N1 + N1 + N2 - 3
+         GO TO ( 10, 20, 30 )K
+*
+   10    CONTINUE
+*
+*        N1 = 1, N2 = 2: generate elementary reflector H so that:
+*
+*        ( scale, X11, X12 ) H = ( 0, 0, * )
+*
+         U( 1 ) = SCALE
+         U( 2 ) = X( 1, 1 )
+         U( 3 ) = X( 1, 2 )
+         CALL SLARFG( 3, U( 3 ), U, 1, TAU )
+         U( 3 ) = ONE
+         T11 = T( J1, J1 )
+*
+*        Perform swap provisionally on diagonal block in D.
+*
+         CALL SLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )
+         CALL SLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )
+*
+*        Test whether to reject swap.
+*
+         IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 3,
+     $       3 )-T11 ) ).GT.THRESH )GO TO 50
+*
+*        Accept swap: apply transformation to the entire matrix T.
+*
+         CALL SLARFX( 'L', 3, N-J1+1, U, TAU, T( J1, J1 ), LDT, WORK )
+         CALL SLARFX( 'R', J2, 3, U, TAU, T( 1, J1 ), LDT, WORK )
+*
+         T( J3, J1 ) = ZERO
+         T( J3, J2 ) = ZERO
+         T( J3, J3 ) = T11
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL SLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )
+         END IF
+         GO TO 40
+*
+   20    CONTINUE
+*
+*        N1 = 2, N2 = 1: generate elementary reflector H so that:
+*
+*        H (  -X11 ) = ( * )
+*          (  -X21 ) = ( 0 )
+*          ( scale ) = ( 0 )
+*
+         U( 1 ) = -X( 1, 1 )
+         U( 2 ) = -X( 2, 1 )
+         U( 3 ) = SCALE
+         CALL SLARFG( 3, U( 1 ), U( 2 ), 1, TAU )
+         U( 1 ) = ONE
+         T33 = T( J3, J3 )
+*
+*        Perform swap provisionally on diagonal block in D.
+*
+         CALL SLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )
+         CALL SLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )
+*
+*        Test whether to reject swap.
+*
+         IF( MAX( ABS( D( 2, 1 ) ), ABS( D( 3, 1 ) ), ABS( D( 1,
+     $       1 )-T33 ) ).GT.THRESH )GO TO 50
+*
+*        Accept swap: apply transformation to the entire matrix T.
+*
+         CALL SLARFX( 'R', J3, 3, U, TAU, T( 1, J1 ), LDT, WORK )
+         CALL SLARFX( 'L', 3, N-J1, U, TAU, T( J1, J2 ), LDT, WORK )
+*
+         T( J1, J1 ) = T33
+         T( J2, J1 ) = ZERO
+         T( J3, J1 ) = ZERO
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL SLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )
+         END IF
+         GO TO 40
+*
+   30    CONTINUE
+*
+*        N1 = 2, N2 = 2: generate elementary reflectors H(1) and H(2) so
+*        that:
+*
+*        H(2) H(1) (  -X11  -X12 ) = (  *  * )
+*                  (  -X21  -X22 )   (  0  * )
+*                  ( scale    0  )   (  0  0 )
+*                  (    0  scale )   (  0  0 )
+*
+         U1( 1 ) = -X( 1, 1 )
+         U1( 2 ) = -X( 2, 1 )
+         U1( 3 ) = SCALE
+         CALL SLARFG( 3, U1( 1 ), U1( 2 ), 1, TAU1 )
+         U1( 1 ) = ONE
+*
+         TEMP = -TAU1*( X( 1, 2 )+U1( 2 )*X( 2, 2 ) )
+         U2( 1 ) = -TEMP*U1( 2 ) - X( 2, 2 )
+         U2( 2 ) = -TEMP*U1( 3 )
+         U2( 3 ) = SCALE
+         CALL SLARFG( 3, U2( 1 ), U2( 2 ), 1, TAU2 )
+         U2( 1 ) = ONE
+*
+*        Perform swap provisionally on diagonal block in D.
+*
+         CALL SLARFX( 'L', 3, 4, U1, TAU1, D, LDD, WORK )
+         CALL SLARFX( 'R', 4, 3, U1, TAU1, D, LDD, WORK )
+         CALL SLARFX( 'L', 3, 4, U2, TAU2, D( 2, 1 ), LDD, WORK )
+         CALL SLARFX( 'R', 4, 3, U2, TAU2, D( 1, 2 ), LDD, WORK )
+*
+*        Test whether to reject swap.
+*
+         IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 4, 1 ) ),
+     $       ABS( D( 4, 2 ) ) ).GT.THRESH )GO TO 50
+*
+*        Accept swap: apply transformation to the entire matrix T.
+*
+         CALL SLARFX( 'L', 3, N-J1+1, U1, TAU1, T( J1, J1 ), LDT, WORK )
+         CALL SLARFX( 'R', J4, 3, U1, TAU1, T( 1, J1 ), LDT, WORK )
+         CALL SLARFX( 'L', 3, N-J1+1, U2, TAU2, T( J2, J1 ), LDT, WORK )
+         CALL SLARFX( 'R', J4, 3, U2, TAU2, T( 1, J2 ), LDT, WORK )
+*
+         T( J3, J1 ) = ZERO
+         T( J3, J2 ) = ZERO
+         T( J4, J1 ) = ZERO
+         T( J4, J2 ) = ZERO
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL SLARFX( 'R', N, 3, U1, TAU1, Q( 1, J1 ), LDQ, WORK )
+            CALL SLARFX( 'R', N, 3, U2, TAU2, Q( 1, J2 ), LDQ, WORK )
+         END IF
+*
+   40    CONTINUE
+*
+         IF( N2.EQ.2 ) THEN
+*
+*           Standardize new 2-by-2 block T11
+*
+            CALL SLANV2( T( J1, J1 ), T( J1, J2 ), T( J2, J1 ),
+     $                   T( J2, J2 ), WR1, WI1, WR2, WI2, CS, SN )
+            CALL SROT( N-J1-1, T( J1, J1+2 ), LDT, T( J2, J1+2 ), LDT,
+     $                 CS, SN )
+            CALL SROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )
+            IF( WANTQ )
+     $         CALL SROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )
+         END IF
+*
+         IF( N1.EQ.2 ) THEN
+*
+*           Standardize new 2-by-2 block T22
+*
+            J3 = J1 + N2
+            J4 = J3 + 1
+            CALL SLANV2( T( J3, J3 ), T( J3, J4 ), T( J4, J3 ),
+     $                   T( J4, J4 ), WR1, WI1, WR2, WI2, CS, SN )
+            IF( J3+2.LE.N )
+     $         CALL SROT( N-J3-1, T( J3, J3+2 ), LDT, T( J4, J3+2 ),
+     $                    LDT, CS, SN )
+            CALL SROT( J3-1, T( 1, J3 ), 1, T( 1, J4 ), 1, CS, SN )
+            IF( WANTQ )
+     $         CALL SROT( N, Q( 1, J3 ), 1, Q( 1, J4 ), 1, CS, SN )
+         END IF
+*
+      END IF
+      RETURN
+*
+*     Exit with INFO = 1 if swap was rejected.
+*
+   50 INFO = 1
+      RETURN
+*
+*     End of SLAEXC
+*
+      END
diff --git a/libcruft/lapack/slag2.f b/libcruft/lapack/slag2.f
new file mode 100644
index 0000000..94f6fd6
--- /dev/null
+++ b/libcruft/lapack/slag2.f
@@ -0,0 +1,300 @@
+      SUBROUTINE SLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,
+     $                  WR2, WI )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, LDB
+      REAL               SAFMIN, SCALE1, SCALE2, WI, WR1, WR2
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAG2 computes the eigenvalues of a 2 x 2 generalized eigenvalue
+*  problem  A - w B, with scaling as necessary to avoid over-/underflow.
+*
+*  The scaling factor "s" results in a modified eigenvalue equation
+*
+*      s A - w B
+*
+*  where  s  is a non-negative scaling factor chosen so that  w,  w B,
+*  and  s A  do not overflow and, if possible, do not underflow, either.
+*
+*  Arguments
+*  =========
+*
+*  A       (input) REAL array, dimension (LDA, 2)
+*          On entry, the 2 x 2 matrix A.  It is assumed that its 1-norm
+*          is less than 1/SAFMIN.  Entries less than
+*          sqrt(SAFMIN)*norm(A) are subject to being treated as zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= 2.
+*
+*  B       (input) REAL array, dimension (LDB, 2)
+*          On entry, the 2 x 2 upper triangular matrix B.  It is
+*          assumed that the one-norm of B is less than 1/SAFMIN.  The
+*          diagonals should be at least sqrt(SAFMIN) times the largest
+*          element of B (in absolute value); if a diagonal is smaller
+*          than that, then  +/- sqrt(SAFMIN) will be used instead of
+*          that diagonal.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= 2.
+*
+*  SAFMIN  (input) REAL
+*          The smallest positive number s.t. 1/SAFMIN does not
+*          overflow.  (This should always be SLAMCH('S') -- it is an
+*          argument in order to avoid having to call SLAMCH frequently.)
+*
+*  SCALE1  (output) REAL
+*          A scaling factor used to avoid over-/underflow in the
+*          eigenvalue equation which defines the first eigenvalue.  If
+*          the eigenvalues are complex, then the eigenvalues are
+*          ( WR1  +/-  WI i ) / SCALE1  (which may lie outside the
+*          exponent range of the machine), SCALE1=SCALE2, and SCALE1
+*          will always be positive.  If the eigenvalues are real, then
+*          the first (real) eigenvalue is  WR1 / SCALE1 , but this may
+*          overflow or underflow, and in fact, SCALE1 may be zero or
+*          less than the underflow threshhold if the exact eigenvalue
+*          is sufficiently large.
+*
+*  SCALE2  (output) REAL
+*          A scaling factor used to avoid over-/underflow in the
+*          eigenvalue equation which defines the second eigenvalue.  If
+*          the eigenvalues are complex, then SCALE2=SCALE1.  If the
+*          eigenvalues are real, then the second (real) eigenvalue is
+*          WR2 / SCALE2 , but this may overflow or underflow, and in
+*          fact, SCALE2 may be zero or less than the underflow
+*          threshhold if the exact eigenvalue is sufficiently large.
+*
+*  WR1     (output) REAL
+*          If the eigenvalue is real, then WR1 is SCALE1 times the
+*          eigenvalue closest to the (2,2) element of A B**(-1).  If the
+*          eigenvalue is complex, then WR1=WR2 is SCALE1 times the real
+*          part of the eigenvalues.
+*
+*  WR2     (output) REAL
+*          If the eigenvalue is real, then WR2 is SCALE2 times the
+*          other eigenvalue.  If the eigenvalue is complex, then
+*          WR1=WR2 is SCALE1 times the real part of the eigenvalues.
+*
+*  WI      (output) REAL
+*          If the eigenvalue is real, then WI is zero.  If the
+*          eigenvalue is complex, then WI is SCALE1 times the imaginary
+*          part of the eigenvalues.  WI will always be non-negative.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0 )
+      REAL               HALF
+      PARAMETER          ( HALF = ONE / TWO )
+      REAL               FUZZY1
+      PARAMETER          ( FUZZY1 = ONE+1.0E-5 )
+*     ..
+*     .. Local Scalars ..
+      REAL               A11, A12, A21, A22, ABI22, ANORM, AS11, AS12,
+     $                   AS22, ASCALE, B11, B12, B22, BINV11, BINV22,
+     $                   BMIN, BNORM, BSCALE, BSIZE, C1, C2, C3, C4, C5,
+     $                   DIFF, DISCR, PP, QQ, R, RTMAX, RTMIN, S1, S2,
+     $                   SAFMAX, SHIFT, SS, SUM, WABS, WBIG, WDET,
+     $                   WSCALE, WSIZE, WSMALL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      RTMIN = SQRT( SAFMIN )
+      RTMAX = ONE / RTMIN
+      SAFMAX = ONE / SAFMIN
+*
+*     Scale A
+*
+      ANORM = MAX( ABS( A( 1, 1 ) )+ABS( A( 2, 1 ) ),
+     $        ABS( A( 1, 2 ) )+ABS( A( 2, 2 ) ), SAFMIN )
+      ASCALE = ONE / ANORM
+      A11 = ASCALE*A( 1, 1 )
+      A21 = ASCALE*A( 2, 1 )
+      A12 = ASCALE*A( 1, 2 )
+      A22 = ASCALE*A( 2, 2 )
+*
+*     Perturb B if necessary to insure non-singularity
+*
+      B11 = B( 1, 1 )
+      B12 = B( 1, 2 )
+      B22 = B( 2, 2 )
+      BMIN = RTMIN*MAX( ABS( B11 ), ABS( B12 ), ABS( B22 ), RTMIN )
+      IF( ABS( B11 ).LT.BMIN )
+     $   B11 = SIGN( BMIN, B11 )
+      IF( ABS( B22 ).LT.BMIN )
+     $   B22 = SIGN( BMIN, B22 )
+*
+*     Scale B
+*
+      BNORM = MAX( ABS( B11 ), ABS( B12 )+ABS( B22 ), SAFMIN )
+      BSIZE = MAX( ABS( B11 ), ABS( B22 ) )
+      BSCALE = ONE / BSIZE
+      B11 = B11*BSCALE
+      B12 = B12*BSCALE
+      B22 = B22*BSCALE
+*
+*     Compute larger eigenvalue by method described by C. van Loan
+*
+*     ( AS is A shifted by -SHIFT*B )
+*
+      BINV11 = ONE / B11
+      BINV22 = ONE / B22
+      S1 = A11*BINV11
+      S2 = A22*BINV22
+      IF( ABS( S1 ).LE.ABS( S2 ) ) THEN
+         AS12 = A12 - S1*B12
+         AS22 = A22 - S1*B22
+         SS = A21*( BINV11*BINV22 )
+         ABI22 = AS22*BINV22 - SS*B12
+         PP = HALF*ABI22
+         SHIFT = S1
+      ELSE
+         AS12 = A12 - S2*B12
+         AS11 = A11 - S2*B11
+         SS = A21*( BINV11*BINV22 )
+         ABI22 = -SS*B12
+         PP = HALF*( AS11*BINV11+ABI22 )
+         SHIFT = S2
+      END IF
+      QQ = SS*AS12
+      IF( ABS( PP*RTMIN ).GE.ONE ) THEN
+         DISCR = ( RTMIN*PP )**2 + QQ*SAFMIN
+         R = SQRT( ABS( DISCR ) )*RTMAX
+      ELSE
+         IF( PP**2+ABS( QQ ).LE.SAFMIN ) THEN
+            DISCR = ( RTMAX*PP )**2 + QQ*SAFMAX
+            R = SQRT( ABS( DISCR ) )*RTMIN
+         ELSE
+            DISCR = PP**2 + QQ
+            R = SQRT( ABS( DISCR ) )
+         END IF
+      END IF
+*
+*     Note: the test of R in the following IF is to cover the case when
+*           DISCR is small and negative and is flushed to zero during
+*           the calculation of R.  On machines which have a consistent
+*           flush-to-zero threshhold and handle numbers above that
+*           threshhold correctly, it would not be necessary.
+*
+      IF( DISCR.GE.ZERO .OR. R.EQ.ZERO ) THEN
+         SUM = PP + SIGN( R, PP )
+         DIFF = PP - SIGN( R, PP )
+         WBIG = SHIFT + SUM
+*
+*        Compute smaller eigenvalue
+*
+         WSMALL = SHIFT + DIFF
+         IF( HALF*ABS( WBIG ).GT.MAX( ABS( WSMALL ), SAFMIN ) ) THEN
+            WDET = ( A11*A22-A12*A21 )*( BINV11*BINV22 )
+            WSMALL = WDET / WBIG
+         END IF
+*
+*        Choose (real) eigenvalue closest to 2,2 element of A*B**(-1)
+*        for WR1.
+*
+         IF( PP.GT.ABI22 ) THEN
+            WR1 = MIN( WBIG, WSMALL )
+            WR2 = MAX( WBIG, WSMALL )
+         ELSE
+            WR1 = MAX( WBIG, WSMALL )
+            WR2 = MIN( WBIG, WSMALL )
+         END IF
+         WI = ZERO
+      ELSE
+*
+*        Complex eigenvalues
+*
+         WR1 = SHIFT + PP
+         WR2 = WR1
+         WI = R
+      END IF
+*
+*     Further scaling to avoid underflow and overflow in computing
+*     SCALE1 and overflow in computing w*B.
+*
+*     This scale factor (WSCALE) is bounded from above using C1 and C2,
+*     and from below using C3 and C4.
+*        C1 implements the condition  s A  must never overflow.
+*        C2 implements the condition  w B  must never overflow.
+*        C3, with C2,
+*           implement the condition that s A - w B must never overflow.
+*        C4 implements the condition  s    should not underflow.
+*        C5 implements the condition  max(s,|w|) should be at least 2.
+*
+      C1 = BSIZE*( SAFMIN*MAX( ONE, ASCALE ) )
+      C2 = SAFMIN*MAX( ONE, BNORM )
+      C3 = BSIZE*SAFMIN
+      IF( ASCALE.LE.ONE .AND. BSIZE.LE.ONE ) THEN
+         C4 = MIN( ONE, ( ASCALE / SAFMIN )*BSIZE )
+      ELSE
+         C4 = ONE
+      END IF
+      IF( ASCALE.LE.ONE .OR. BSIZE.LE.ONE ) THEN
+         C5 = MIN( ONE, ASCALE*BSIZE )
+      ELSE
+         C5 = ONE
+      END IF
+*
+*     Scale first eigenvalue
+*
+      WABS = ABS( WR1 ) + ABS( WI )
+      WSIZE = MAX( SAFMIN, C1, FUZZY1*( WABS*C2+C3 ),
+     $        MIN( C4, HALF*MAX( WABS, C5 ) ) )
+      IF( WSIZE.NE.ONE ) THEN
+         WSCALE = ONE / WSIZE
+         IF( WSIZE.GT.ONE ) THEN
+            SCALE1 = ( MAX( ASCALE, BSIZE )*WSCALE )*
+     $               MIN( ASCALE, BSIZE )
+         ELSE
+            SCALE1 = ( MIN( ASCALE, BSIZE )*WSCALE )*
+     $               MAX( ASCALE, BSIZE )
+         END IF
+         WR1 = WR1*WSCALE
+         IF( WI.NE.ZERO ) THEN
+            WI = WI*WSCALE
+            WR2 = WR1
+            SCALE2 = SCALE1
+         END IF
+      ELSE
+         SCALE1 = ASCALE*BSIZE
+         SCALE2 = SCALE1
+      END IF
+*
+*     Scale second eigenvalue (if real)
+*
+      IF( WI.EQ.ZERO ) THEN
+         WSIZE = MAX( SAFMIN, C1, FUZZY1*( ABS( WR2 )*C2+C3 ),
+     $           MIN( C4, HALF*MAX( ABS( WR2 ), C5 ) ) )
+         IF( WSIZE.NE.ONE ) THEN
+            WSCALE = ONE / WSIZE
+            IF( WSIZE.GT.ONE ) THEN
+               SCALE2 = ( MAX( ASCALE, BSIZE )*WSCALE )*
+     $                  MIN( ASCALE, BSIZE )
+            ELSE
+               SCALE2 = ( MIN( ASCALE, BSIZE )*WSCALE )*
+     $                  MAX( ASCALE, BSIZE )
+            END IF
+            WR2 = WR2*WSCALE
+         ELSE
+            SCALE2 = ASCALE*BSIZE
+         END IF
+      END IF
+*
+*     End of SLAG2
+*
+      RETURN
+      END
diff --git a/libcruft/lapack/slahqr.f b/libcruft/lapack/slahqr.f
new file mode 100644
index 0000000..e125970
--- /dev/null
+++ b/libcruft/lapack/slahqr.f
@@ -0,0 +1,501 @@
+      SUBROUTINE SLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     SLAHQR is an auxiliary routine called by SHSEQR to update the
+*     eigenvalues and Schur decomposition already computed by SHSEQR, by
+*     dealing with the Hessenberg submatrix in rows and columns ILO to
+*     IHI.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H.  N >= 0.
+*
+*     ILO     (input) INTEGER
+*     IHI     (input) INTEGER
+*          It is assumed that H is already upper quasi-triangular in
+*          rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless
+*          ILO = 1). SLAHQR works primarily with the Hessenberg
+*          submatrix in rows and columns ILO to IHI, but applies
+*          transformations to all of H if WANTT is .TRUE..
+*          1 <= ILO <= max(1,IHI); IHI <= N.
+*
+*     H       (input/output) REAL array, dimension (LDH,N)
+*          On entry, the upper Hessenberg matrix H.
+*          On exit, if INFO is zero and if WANTT is .TRUE., H is upper
+*          quasi-triangular in rows and columns ILO:IHI, with any
+*          2-by-2 diagonal blocks in standard form. If INFO is zero
+*          and WANTT is .FALSE., the contents of H are unspecified on
+*          exit.  The output state of H if INFO is nonzero is given
+*          below under the description of INFO.
+*
+*     LDH     (input) INTEGER
+*          The leading dimension of the array H. LDH >= max(1,N).
+*
+*     WR      (output) REAL array, dimension (N)
+*     WI      (output) REAL array, dimension (N)
+*          The real and imaginary parts, respectively, of the computed
+*          eigenvalues ILO to IHI are stored in the corresponding
+*          elements of WR and WI. If two eigenvalues are computed as a
+*          complex conjugate pair, they are stored in consecutive
+*          elements of WR and WI, say the i-th and (i+1)th, with
+*          WI(i) > 0 and WI(i+1) < 0. If WANTT is .TRUE., the
+*          eigenvalues are stored in the same order as on the diagonal
+*          of the Schur form returned in H, with WR(i) = H(i,i), and, if
+*          H(i:i+1,i:i+1) is a 2-by-2 diagonal block,
+*          WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i).
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE..
+*          1 <= ILOZ <= ILO; IHI <= IHIZ <= N.
+*
+*     Z       (input/output) REAL array, dimension (LDZ,N)
+*          If WANTZ is .TRUE., on entry Z must contain the current
+*          matrix Z of transformations accumulated by SHSEQR, and on
+*          exit Z has been updated; transformations are applied only to
+*          the submatrix Z(ILOZ:IHIZ,ILO:IHI).
+*          If WANTZ is .FALSE., Z is not referenced.
+*
+*     LDZ     (input) INTEGER
+*          The leading dimension of the array Z. LDZ >= max(1,N).
+*
+*     INFO    (output) INTEGER
+*           =   0: successful exit
+*          .GT. 0: If INFO = i, SLAHQR failed to compute all the
+*                  eigenvalues ILO to IHI in a total of 30 iterations
+*                  per eigenvalue; elements i+1:ihi of WR and WI
+*                  contain those eigenvalues which have been
+*                  successfully computed.
+*
+*                  If INFO .GT. 0 and WANTT is .FALSE., then on exit,
+*                  the remaining unconverged eigenvalues are the
+*                  eigenvalues of the upper Hessenberg matrix rows
+*                  and columns ILO thorugh INFO of the final, output
+*                  value of H.
+*
+*                  If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*          (*)       (initial value of H)*U  = U*(final value of H)
+*                  where U is an orthognal matrix.    The final
+*                  value of H is upper Hessenberg and triangular in
+*                  rows and columns INFO+1 through IHI.
+*
+*                  If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*                      (final value of Z)  = (initial value of Z)*U
+*                  where U is the orthogonal matrix in (*)
+*                  (regardless of the value of WANTT.)
+*
+*     Further Details
+*     ===============
+*
+*     02-96 Based on modifications by
+*     David Day, Sandia National Laboratory, USA
+*
+*     12-04 Further modifications by
+*     Ralph Byers, University of Kansas, USA
+*
+*       This is a modified version of SLAHQR from LAPACK version 3.0.
+*       It is (1) more robust against overflow and underflow and
+*       (2) adopts the more conservative Ahues & Tisseur stopping
+*       criterion (LAWN 122, 1997).
+*
+*     =========================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 30 )
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0, TWO = 2.0e0 )
+      REAL               DAT1, DAT2
+      PARAMETER          ( DAT1 = 3.0e0 / 4.0e0, DAT2 = -0.4375e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AA, AB, BA, BB, CS, DET, H11, H12, H21, H21S,
+     $                   H22, RT1I, RT1R, RT2I, RT2R, RTDISC, S, SAFMAX,
+     $                   SAFMIN, SMLNUM, SN, SUM, T1, T2, T3, TR, TST,
+     $                   ULP, V2, V3
+      INTEGER            I, I1, I2, ITS, J, K, L, M, NH, NR, NZ
+*     ..
+*     .. Local Arrays ..
+      REAL               V( 3 )
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLABAD, SLANV2, SLARFG, SROT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( ILO.EQ.IHI ) THEN
+         WR( ILO ) = H( ILO, ILO )
+         WI( ILO ) = ZERO
+         RETURN
+      END IF
+*
+*     ==== clear out the trash ====
+      DO 10 J = ILO, IHI - 3
+         H( J+2, J ) = ZERO
+         H( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( ILO.LE.IHI-2 )
+     $   H( IHI, IHI-2 ) = ZERO
+*
+      NH = IHI - ILO + 1
+      NZ = IHIZ - ILOZ + 1
+*
+*     Set machine-dependent constants for the stopping criterion.
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( NH ) / ULP )
+*
+*     I1 and I2 are the indices of the first row and last column of H
+*     to which transformations must be applied. If eigenvalues only are
+*     being computed, I1 and I2 are set inside the main loop.
+*
+      IF( WANTT ) THEN
+         I1 = 1
+         I2 = N
+      END IF
+*
+*     The main loop begins here. I is the loop index and decreases from
+*     IHI to ILO in steps of 1 or 2. Each iteration of the loop works
+*     with the active submatrix in rows and columns L to I.
+*     Eigenvalues I+1 to IHI have already converged. Either L = ILO or
+*     H(L,L-1) is negligible so that the matrix splits.
+*
+      I = IHI
+   20 CONTINUE
+      L = ILO
+      IF( I.LT.ILO )
+     $   GO TO 160
+*
+*     Perform QR iterations on rows and columns ILO to I until a
+*     submatrix of order 1 or 2 splits off at the bottom because a
+*     subdiagonal element has become negligible.
+*
+      DO 140 ITS = 0, ITMAX
+*
+*        Look for a single small subdiagonal element.
+*
+         DO 30 K = I, L + 1, -1
+            IF( ABS( H( K, K-1 ) ).LE.SMLNUM )
+     $         GO TO 40
+            TST = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) )
+            IF( TST.EQ.ZERO ) THEN
+               IF( K-2.GE.ILO )
+     $            TST = TST + ABS( H( K-1, K-2 ) )
+               IF( K+1.LE.IHI )
+     $            TST = TST + ABS( H( K+1, K ) )
+            END IF
+*           ==== The following is a conservative small subdiagonal
+*           .    deflation  criterion due to Ahues & Tisseur (LAWN 122,
+*           .    1997). It has better mathematical foundation and
+*           .    improves accuracy in some cases.  ====
+            IF( ABS( H( K, K-1 ) ).LE.ULP*TST ) THEN
+               AB = MAX( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )
+               BA = MIN( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )
+               AA = MAX( ABS( H( K, K ) ),
+     $              ABS( H( K-1, K-1 )-H( K, K ) ) )
+               BB = MIN( ABS( H( K, K ) ),
+     $              ABS( H( K-1, K-1 )-H( K, K ) ) )
+               S = AA + AB
+               IF( BA*( AB / S ).LE.MAX( SMLNUM,
+     $             ULP*( BB*( AA / S ) ) ) )GO TO 40
+            END IF
+   30    CONTINUE
+   40    CONTINUE
+         L = K
+         IF( L.GT.ILO ) THEN
+*
+*           H(L,L-1) is negligible
+*
+            H( L, L-1 ) = ZERO
+         END IF
+*
+*        Exit from loop if a submatrix of order 1 or 2 has split off.
+*
+         IF( L.GE.I-1 )
+     $      GO TO 150
+*
+*        Now the active submatrix is in rows and columns L to I. If
+*        eigenvalues only are being computed, only the active submatrix
+*        need be transformed.
+*
+         IF( .NOT.WANTT ) THEN
+            I1 = L
+            I2 = I
+         END IF
+*
+         IF( ITS.EQ.10 .OR. ITS.EQ.20 ) THEN
+*
+*           Exceptional shift.
+*
+            H11 = DAT1*S + H( I, I )
+            H12 = DAT2*S
+            H21 = S
+            H22 = H11
+         ELSE
+*
+*           Prepare to use Francis' double shift
+*           (i.e. 2nd degree generalized Rayleigh quotient)
+*
+            H11 = H( I-1, I-1 )
+            H21 = H( I, I-1 )
+            H12 = H( I-1, I )
+            H22 = H( I, I )
+         END IF
+         S = ABS( H11 ) + ABS( H12 ) + ABS( H21 ) + ABS( H22 )
+         IF( S.EQ.ZERO ) THEN
+            RT1R = ZERO
+            RT1I = ZERO
+            RT2R = ZERO
+            RT2I = ZERO
+         ELSE
+            H11 = H11 / S
+            H21 = H21 / S
+            H12 = H12 / S
+            H22 = H22 / S
+            TR = ( H11+H22 ) / TWO
+            DET = ( H11-TR )*( H22-TR ) - H12*H21
+            RTDISC = SQRT( ABS( DET ) )
+            IF( DET.GE.ZERO ) THEN
+*
+*              ==== complex conjugate shifts ====
+*
+               RT1R = TR*S
+               RT2R = RT1R
+               RT1I = RTDISC*S
+               RT2I = -RT1I
+            ELSE
+*
+*              ==== real shifts (use only one of them)  ====
+*
+               RT1R = TR + RTDISC
+               RT2R = TR - RTDISC
+               IF( ABS( RT1R-H22 ).LE.ABS( RT2R-H22 ) ) THEN
+                  RT1R = RT1R*S
+                  RT2R = RT1R
+               ELSE
+                  RT2R = RT2R*S
+                  RT1R = RT2R
+               END IF
+               RT1I = ZERO
+               RT2I = ZERO
+            END IF
+         END IF
+*
+*        Look for two consecutive small subdiagonal elements.
+*
+         DO 50 M = I - 2, L, -1
+*           Determine the effect of starting the double-shift QR
+*           iteration at row M, and see if this would make H(M,M-1)
+*           negligible.  (The following uses scaling to avoid
+*           overflows and most underflows.)
+*
+            H21S = H( M+1, M )
+            S = ABS( H( M, M )-RT2R ) + ABS( RT2I ) + ABS( H21S )
+            H21S = H( M+1, M ) / S
+            V( 1 ) = H21S*H( M, M+1 ) + ( H( M, M )-RT1R )*
+     $               ( ( H( M, M )-RT2R ) / S ) - RT1I*( RT2I / S )
+            V( 2 ) = H21S*( H( M, M )+H( M+1, M+1 )-RT1R-RT2R )
+            V( 3 ) = H21S*H( M+2, M+1 )
+            S = ABS( V( 1 ) ) + ABS( V( 2 ) ) + ABS( V( 3 ) )
+            V( 1 ) = V( 1 ) / S
+            V( 2 ) = V( 2 ) / S
+            V( 3 ) = V( 3 ) / S
+            IF( M.EQ.L )
+     $         GO TO 60
+            IF( ABS( H( M, M-1 ) )*( ABS( V( 2 ) )+ABS( V( 3 ) ) ).LE.
+     $          ULP*ABS( V( 1 ) )*( ABS( H( M-1, M-1 ) )+ABS( H( M,
+     $          M ) )+ABS( H( M+1, M+1 ) ) ) )GO TO 60
+   50    CONTINUE
+   60    CONTINUE
+*
+*        Double-shift QR step
+*
+         DO 130 K = M, I - 1
+*
+*           The first iteration of this loop determines a reflection G
+*           from the vector V and applies it from left and right to H,
+*           thus creating a nonzero bulge below the subdiagonal.
+*
+*           Each subsequent iteration determines a reflection G to
+*           restore the Hessenberg form in the (K-1)th column, and thus
+*           chases the bulge one step toward the bottom of the active
+*           submatrix. NR is the order of G.
+*
+            NR = MIN( 3, I-K+1 )
+            IF( K.GT.M )
+     $         CALL SCOPY( NR, H( K, K-1 ), 1, V, 1 )
+            CALL SLARFG( NR, V( 1 ), V( 2 ), 1, T1 )
+            IF( K.GT.M ) THEN
+               H( K, K-1 ) = V( 1 )
+               H( K+1, K-1 ) = ZERO
+               IF( K.LT.I-1 )
+     $            H( K+2, K-1 ) = ZERO
+            ELSE IF( M.GT.L ) THEN
+               H( K, K-1 ) = -H( K, K-1 )
+            END IF
+            V2 = V( 2 )
+            T2 = T1*V2
+            IF( NR.EQ.3 ) THEN
+               V3 = V( 3 )
+               T3 = T1*V3
+*
+*              Apply G from the left to transform the rows of the matrix
+*              in columns K to I2.
+*
+               DO 70 J = K, I2
+                  SUM = H( K, J ) + V2*H( K+1, J ) + V3*H( K+2, J )
+                  H( K, J ) = H( K, J ) - SUM*T1
+                  H( K+1, J ) = H( K+1, J ) - SUM*T2
+                  H( K+2, J ) = H( K+2, J ) - SUM*T3
+   70          CONTINUE
+*
+*              Apply G from the right to transform the columns of the
+*              matrix in rows I1 to min(K+3,I).
+*
+               DO 80 J = I1, MIN( K+3, I )
+                  SUM = H( J, K ) + V2*H( J, K+1 ) + V3*H( J, K+2 )
+                  H( J, K ) = H( J, K ) - SUM*T1
+                  H( J, K+1 ) = H( J, K+1 ) - SUM*T2
+                  H( J, K+2 ) = H( J, K+2 ) - SUM*T3
+   80          CONTINUE
+*
+               IF( WANTZ ) THEN
+*
+*                 Accumulate transformations in the matrix Z
+*
+                  DO 90 J = ILOZ, IHIZ
+                     SUM = Z( J, K ) + V2*Z( J, K+1 ) + V3*Z( J, K+2 )
+                     Z( J, K ) = Z( J, K ) - SUM*T1
+                     Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2
+                     Z( J, K+2 ) = Z( J, K+2 ) - SUM*T3
+   90             CONTINUE
+               END IF
+            ELSE IF( NR.EQ.2 ) THEN
+*
+*              Apply G from the left to transform the rows of the matrix
+*              in columns K to I2.
+*
+               DO 100 J = K, I2
+                  SUM = H( K, J ) + V2*H( K+1, J )
+                  H( K, J ) = H( K, J ) - SUM*T1
+                  H( K+1, J ) = H( K+1, J ) - SUM*T2
+  100          CONTINUE
+*
+*              Apply G from the right to transform the columns of the
+*              matrix in rows I1 to min(K+3,I).
+*
+               DO 110 J = I1, I
+                  SUM = H( J, K ) + V2*H( J, K+1 )
+                  H( J, K ) = H( J, K ) - SUM*T1
+                  H( J, K+1 ) = H( J, K+1 ) - SUM*T2
+  110          CONTINUE
+*
+               IF( WANTZ ) THEN
+*
+*                 Accumulate transformations in the matrix Z
+*
+                  DO 120 J = ILOZ, IHIZ
+                     SUM = Z( J, K ) + V2*Z( J, K+1 )
+                     Z( J, K ) = Z( J, K ) - SUM*T1
+                     Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2
+  120             CONTINUE
+               END IF
+            END IF
+  130    CONTINUE
+*
+  140 CONTINUE
+*
+*     Failure to converge in remaining number of iterations
+*
+      INFO = I
+      RETURN
+*
+  150 CONTINUE
+*
+      IF( L.EQ.I ) THEN
+*
+*        H(I,I-1) is negligible: one eigenvalue has converged.
+*
+         WR( I ) = H( I, I )
+         WI( I ) = ZERO
+      ELSE IF( L.EQ.I-1 ) THEN
+*
+*        H(I-1,I-2) is negligible: a pair of eigenvalues have converged.
+*
+*        Transform the 2-by-2 submatrix to standard Schur form,
+*        and compute and store the eigenvalues.
+*
+         CALL SLANV2( H( I-1, I-1 ), H( I-1, I ), H( I, I-1 ),
+     $                H( I, I ), WR( I-1 ), WI( I-1 ), WR( I ), WI( I ),
+     $                CS, SN )
+*
+         IF( WANTT ) THEN
+*
+*           Apply the transformation to the rest of H.
+*
+            IF( I2.GT.I )
+     $         CALL SROT( I2-I, H( I-1, I+1 ), LDH, H( I, I+1 ), LDH,
+     $                    CS, SN )
+            CALL SROT( I-I1-1, H( I1, I-1 ), 1, H( I1, I ), 1, CS, SN )
+         END IF
+         IF( WANTZ ) THEN
+*
+*           Apply the transformation to Z.
+*
+            CALL SROT( NZ, Z( ILOZ, I-1 ), 1, Z( ILOZ, I ), 1, CS, SN )
+         END IF
+      END IF
+*
+*     return to start of the main loop with new value of I.
+*
+      I = L - 1
+      GO TO 20
+*
+  160 CONTINUE
+      RETURN
+*
+*     End of SLAHQR
+*
+      END
diff --git a/libcruft/lapack/slahr2.f b/libcruft/lapack/slahr2.f
new file mode 100644
index 0000000..4f8bf2a
--- /dev/null
+++ b/libcruft/lapack/slahr2.f
@@ -0,0 +1,238 @@
+      SUBROUTINE SLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      REAL              A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAHR2 reduces the first NB columns of A real general n-BY-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by an orthogonal similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an auxiliary routine called by SGEHRD.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*          K < N.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) REAL array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) REAL array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) REAL array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) REAL array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's SLAHRD
+*  incorporating improvements proposed by Quintana-Orti and Van de
+*  Gejin. Note that the entries of A(1:K,2:NB) differ from those
+*  returned by the original LAPACK routine. This function is
+*  not backward compatible with LAPACK3.0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL              ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, 
+     $                     ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      REAL              EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SCOPY, SGEMM, SGEMV, SLACPY,
+     $                   SLARFG, SSCAL, STRMM, STRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(K+1:N,I)
+*
+*           Update I-th column of A - Y * V'
+*
+            CALL SGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, Y(K+1,1), LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( K+1, I ), 1 )
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL SCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL STRMV( 'Lower', 'Transpose', 'UNIT', 
+     $                  I-1, A( K+1, 1 ),
+     $                  LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL SGEMV( 'Transpose', N-K-I+1, I-1, 
+     $                  ONE, A( K+I, 1 ),
+     $                  LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL STRMV( 'Upper', 'Transpose', 'NON-UNIT', 
+     $                  I-1, T, LDT,
+     $                  T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL SGEMV( 'NO TRANSPOSE', N-K-I+1, I-1, -ONE, 
+     $                  A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL STRMV( 'Lower', 'NO TRANSPOSE', 
+     $                  'UNIT', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL SAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(I) to annihilate
+*        A(K+I+1:N,I)
+*
+         CALL SLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         EI = A( K+I, I )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(K+1:N,I)
+*
+         CALL SGEMV( 'NO TRANSPOSE', N-K, N-K-I+1, 
+     $               ONE, A( K+1, I+1 ),
+     $               LDA, A( K+I, I ), 1, ZERO, Y( K+1, I ), 1 )
+         CALL SGEMV( 'Transpose', N-K-I+1, I-1, 
+     $               ONE, A( K+I, 1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, T( 1, I ), 1 )
+         CALL SGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, 
+     $               Y( K+1, 1 ), LDY,
+     $               T( 1, I ), 1, ONE, Y( K+1, I ), 1 )
+         CALL SSCAL( N-K, TAU( I ), Y( K+1, I ), 1 )
+*
+*        Compute T(1:I,I)
+*
+         CALL SSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL STRMV( 'Upper', 'No Transpose', 'NON-UNIT', 
+     $               I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+*     Compute Y(1:K,1:NB)
+*
+      CALL SLACPY( 'ALL', K, NB, A( 1, 2 ), LDA, Y, LDY )
+      CALL STRMM( 'RIGHT', 'Lower', 'NO TRANSPOSE', 
+     $            'UNIT', K, NB,
+     $            ONE, A( K+1, 1 ), LDA, Y, LDY )
+      IF( N.GT.K+NB )
+     $   CALL SGEMM( 'NO TRANSPOSE', 'NO TRANSPOSE', K, 
+     $               NB, N-K-NB, ONE,
+     $               A( 1, 2+NB ), LDA, A( K+1+NB, 1 ), LDA, ONE, Y,
+     $               LDY )
+      CALL STRMM( 'RIGHT', 'Upper', 'NO TRANSPOSE', 
+     $            'NON-UNIT', K, NB,
+     $            ONE, T, LDT, Y, LDY )
+*
+      RETURN
+*
+*     End of SLAHR2
+*
+      END
diff --git a/libcruft/lapack/slahrd.f b/libcruft/lapack/slahrd.f
new file mode 100644
index 0000000..b5163a7
--- /dev/null
+++ b/libcruft/lapack/slahrd.f
@@ -0,0 +1,207 @@
+      SUBROUTINE SLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAHRD reduces the first NB columns of a real general n-by-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by an orthogonal similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an OBSOLETE auxiliary routine. 
+*  This routine will be 'deprecated' in a  future release.
+*  Please use the new routine SLAHR2 instead.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) REAL array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) REAL array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) REAL array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) REAL array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      REAL               EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SCOPY, SGEMV, SLARFG, SSCAL, STRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(1:n,i)
+*
+*           Compute i-th column of A - Y * V'
+*
+            CALL SGEMV( 'No transpose', N, I-1, -ONE, Y, LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( 1, I ), 1 )
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL SCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL STRMV( 'Lower', 'Transpose', 'Unit', I-1, A( K+1, 1 ),
+     $                  LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL SGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ),
+     $                  LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL STRMV( 'Upper', 'Transpose', 'Non-unit', I-1, T, LDT,
+     $                  T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL SGEMV( 'No transpose', N-K-I+1, I-1, -ONE, A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL STRMV( 'Lower', 'No transpose', 'Unit', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL SAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(i) to annihilate
+*        A(k+i+1:n,i)
+*
+         CALL SLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         EI = A( K+I, I )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(1:n,i)
+*
+         CALL SGEMV( 'No transpose', N, N-K-I+1, ONE, A( 1, I+1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, Y( 1, I ), 1 )
+         CALL SGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, T( 1, I ), 1 )
+         CALL SGEMV( 'No transpose', N, I-1, -ONE, Y, LDY, T( 1, I ), 1,
+     $               ONE, Y( 1, I ), 1 )
+         CALL SSCAL( N, TAU( I ), Y( 1, I ), 1 )
+*
+*        Compute T(1:i,i)
+*
+         CALL SSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL STRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+      RETURN
+*
+*     End of SLAHRD
+*
+      END
diff --git a/libcruft/lapack/slaic1.f b/libcruft/lapack/slaic1.f
new file mode 100644
index 0000000..78f161f
--- /dev/null
+++ b/libcruft/lapack/slaic1.f
@@ -0,0 +1,292 @@
+      SUBROUTINE SLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            J, JOB
+      REAL               C, GAMMA, S, SEST, SESTPR
+*     ..
+*     .. Array Arguments ..
+      REAL               W( J ), X( J )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAIC1 applies one step of incremental condition estimation in
+*  its simplest version:
+*
+*  Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
+*  lower triangular matrix L, such that
+*           twonorm(L*x) = sest
+*  Then SLAIC1 computes sestpr, s, c such that
+*  the vector
+*                  [ s*x ]
+*           xhat = [  c  ]
+*  is an approximate singular vector of
+*                  [ L     0  ]
+*           Lhat = [ w' gamma ]
+*  in the sense that
+*           twonorm(Lhat*xhat) = sestpr.
+*
+*  Depending on JOB, an estimate for the largest or smallest singular
+*  value is computed.
+*
+*  Note that [s c]' and sestpr**2 is an eigenpair of the system
+*
+*      diag(sest*sest, 0) + [alpha  gamma] * [ alpha ]
+*                                            [ gamma ]
+*
+*  where  alpha =  x'*w.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) INTEGER
+*          = 1: an estimate for the largest singular value is computed.
+*          = 2: an estimate for the smallest singular value is computed.
+*
+*  J       (input) INTEGER
+*          Length of X and W
+*
+*  X       (input) REAL array, dimension (J)
+*          The j-vector x.
+*
+*  SEST    (input) REAL
+*          Estimated singular value of j by j matrix L
+*
+*  W       (input) REAL array, dimension (J)
+*          The j-vector w.
+*
+*  GAMMA   (input) REAL
+*          The diagonal element gamma.
+*
+*  SESTPR  (output) REAL
+*          Estimated singular value of (j+1) by (j+1) matrix Lhat.
+*
+*  S       (output) REAL
+*          Sine needed in forming xhat.
+*
+*  C       (output) REAL
+*          Cosine needed in forming xhat.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 )
+      REAL               HALF, FOUR
+      PARAMETER          ( HALF = 0.5E0, FOUR = 4.0E0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,
+     $                   NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SIGN, SQRT
+*     ..
+*     .. External Functions ..
+      REAL               SDOT, SLAMCH
+      EXTERNAL           SDOT, SLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+      EPS = SLAMCH( 'Epsilon' )
+      ALPHA = SDOT( J, X, 1, W, 1 )
+*
+      ABSALP = ABS( ALPHA )
+      ABSGAM = ABS( GAMMA )
+      ABSEST = ABS( SEST )
+*
+      IF( JOB.EQ.1 ) THEN
+*
+*        Estimating largest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            S1 = MAX( ABSGAM, ABSALP )
+            IF( S1.EQ.ZERO ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = ZERO
+            ELSE
+               S = ALPHA / S1
+               C = GAMMA / S1
+               TMP = SQRT( S*S+C*C )
+               S = S / TMP
+               C = C / TMP
+               SESTPR = S1*TMP
+            END IF
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ONE
+            C = ZERO
+            TMP = MAX( ABSEST, ABSALP )
+            S1 = ABSEST / TMP
+            S2 = ABSALP / TMP
+            SESTPR = TMP*SQRT( S1*S1+S2*S2 )
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            ELSE
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               S = SQRT( ONE+TMP*TMP )
+               SESTPR = S2*S
+               C = ( GAMMA / S2 ) / S
+               S = SIGN( ONE, ALPHA ) / S
+            ELSE
+               TMP = S2 / S1
+               C = SQRT( ONE+TMP*TMP )
+               SESTPR = S1*C
+               S = ( ALPHA / S1 ) / C
+               C = SIGN( ONE, GAMMA ) / C
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ALPHA / ABSEST
+            ZETA2 = GAMMA / ABSEST
+*
+            B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
+            C = ZETA1*ZETA1
+            IF( B.GT.ZERO ) THEN
+               T = C / ( B+SQRT( B*B+C ) )
+            ELSE
+               T = SQRT( B*B+C ) - B
+            END IF
+*
+            SINE = -ZETA1 / T
+            COSINE = -ZETA2 / ( ONE+T )
+            TMP = SQRT( SINE*SINE+COSINE*COSINE )
+            S = SINE / TMP
+            C = COSINE / TMP
+            SESTPR = SQRT( T+ONE )*ABSEST
+            RETURN
+         END IF
+*
+      ELSE IF( JOB.EQ.2 ) THEN
+*
+*        Estimating smallest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            SESTPR = ZERO
+            IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
+               SINE = ONE
+               COSINE = ZERO
+            ELSE
+               SINE = -GAMMA
+               COSINE = ALPHA
+            END IF
+            S1 = MAX( ABS( SINE ), ABS( COSINE ) )
+            S = SINE / S1
+            C = COSINE / S1
+            TMP = SQRT( S*S+C*C )
+            S = S / TMP
+            C = C / TMP
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ZERO
+            C = ONE
+            SESTPR = ABSGAM
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            ELSE
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               C = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST*( TMP / C )
+               S = -( GAMMA / S2 ) / C
+               C = SIGN( ONE, ALPHA ) / C
+            ELSE
+               TMP = S2 / S1
+               S = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST / S
+               C = ( ALPHA / S1 ) / S
+               S = -SIGN( ONE, GAMMA ) / S
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ALPHA / ABSEST
+            ZETA2 = GAMMA / ABSEST
+*
+            NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),
+     $              ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )
+*
+*           See if root is closer to zero or to ONE
+*
+            TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
+            IF( TEST.GE.ZERO ) THEN
+*
+*              root is close to zero, compute directly
+*
+               B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
+               C = ZETA2*ZETA2
+               T = C / ( B+SQRT( ABS( B*B-C ) ) )
+               SINE = ZETA1 / ( ONE-T )
+               COSINE = -ZETA2 / T
+               SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
+            ELSE
+*
+*              root is closer to ONE, shift by that amount
+*
+               B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
+               C = ZETA1*ZETA1
+               IF( B.GE.ZERO ) THEN
+                  T = -C / ( B+SQRT( B*B+C ) )
+               ELSE
+                  T = B - SQRT( B*B+C )
+               END IF
+               SINE = -ZETA1 / T
+               COSINE = -ZETA2 / ( ONE+T )
+               SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
+            END IF
+            TMP = SQRT( SINE*SINE+COSINE*COSINE )
+            S = SINE / TMP
+            C = COSINE / TMP
+            RETURN
+*
+         END IF
+      END IF
+      RETURN
+*
+*     End of SLAIC1
+*
+      END
diff --git a/libcruft/lapack/slaln2.f b/libcruft/lapack/slaln2.f
new file mode 100644
index 0000000..3742280
--- /dev/null
+++ b/libcruft/lapack/slaln2.f
@@ -0,0 +1,507 @@
+      SUBROUTINE SLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,
+     $                   LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            LTRANS
+      INTEGER            INFO, LDA, LDB, LDX, NA, NW
+      REAL               CA, D1, D2, SCALE, SMIN, WI, WR, XNORM
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * ), X( LDX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLALN2 solves a system of the form  (ca A - w D ) X = s B
+*  or (ca A' - w D) X = s B   with possible scaling ("s") and
+*  perturbation of A.  (A' means A-transpose.)
+*
+*  A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
+*  real diagonal matrix, w is a real or complex value, and X and B are
+*  NA x 1 matrices -- real if w is real, complex if w is complex.  NA
+*  may be 1 or 2.
+*
+*  If w is complex, X and B are represented as NA x 2 matrices,
+*  the first column of each being the real part and the second
+*  being the imaginary part.
+*
+*  "s" is a scaling factor (.LE. 1), computed by SLALN2, which is
+*  so chosen that X can be computed without overflow.  X is further
+*  scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
+*  than overflow.
+*
+*  If both singular values of (ca A - w D) are less than SMIN,
+*  SMIN*identity will be used instead of (ca A - w D).  If only one
+*  singular value is less than SMIN, one element of (ca A - w D) will be
+*  perturbed enough to make the smallest singular value roughly SMIN.
+*  If both singular values are at least SMIN, (ca A - w D) will not be
+*  perturbed.  In any case, the perturbation will be at most some small
+*  multiple of max( SMIN, ulp*norm(ca A - w D) ).  The singular values
+*  are computed by infinity-norm approximations, and thus will only be
+*  correct to a factor of 2 or so.
+*
+*  Note: all input quantities are assumed to be smaller than overflow
+*  by a reasonable factor.  (See BIGNUM.)
+*
+*  Arguments
+*  ==========
+*
+*  LTRANS  (input) LOGICAL
+*          =.TRUE.:  A-transpose will be used.
+*          =.FALSE.: A will be used (not transposed.)
+*
+*  NA      (input) INTEGER
+*          The size of the matrix A.  It may (only) be 1 or 2.
+*
+*  NW      (input) INTEGER
+*          1 if "w" is real, 2 if "w" is complex.  It may only be 1
+*          or 2.
+*
+*  SMIN    (input) REAL
+*          The desired lower bound on the singular values of A.  This
+*          should be a safe distance away from underflow or overflow,
+*          say, between (underflow/machine precision) and  (machine
+*          precision * overflow ).  (See BIGNUM and ULP.)
+*
+*  CA      (input) REAL
+*          The coefficient c, which A is multiplied by.
+*
+*  A       (input) REAL array, dimension (LDA,NA)
+*          The NA x NA matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of A.  It must be at least NA.
+*
+*  D1      (input) REAL
+*          The 1,1 element in the diagonal matrix D.
+*
+*  D2      (input) REAL
+*          The 2,2 element in the diagonal matrix D.  Not used if NW=1.
+*
+*  B       (input) REAL array, dimension (LDB,NW)
+*          The NA x NW matrix B (right-hand side).  If NW=2 ("w" is
+*          complex), column 1 contains the real part of B and column 2
+*          contains the imaginary part.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of B.  It must be at least NA.
+*
+*  WR      (input) REAL
+*          The real part of the scalar "w".
+*
+*  WI      (input) REAL
+*          The imaginary part of the scalar "w".  Not used if NW=1.
+*
+*  X       (output) REAL array, dimension (LDX,NW)
+*          The NA x NW matrix X (unknowns), as computed by SLALN2.
+*          If NW=2 ("w" is complex), on exit, column 1 will contain
+*          the real part of X and column 2 will contain the imaginary
+*          part.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of X.  It must be at least NA.
+*
+*  SCALE   (output) REAL
+*          The scale factor that B must be multiplied by to insure
+*          that overflow does not occur when computing X.  Thus,
+*          (ca A - w D) X  will be SCALE*B, not B (ignoring
+*          perturbations of A.)  It will be at most 1.
+*
+*  XNORM   (output) REAL
+*          The infinity-norm of X, when X is regarded as an NA x NW
+*          real matrix.
+*
+*  INFO    (output) INTEGER
+*          An error flag.  It will be set to zero if no error occurs,
+*          a negative number if an argument is in error, or a positive
+*          number if  ca A - w D  had to be perturbed.
+*          The possible values are:
+*          = 0: No error occurred, and (ca A - w D) did not have to be
+*                 perturbed.
+*          = 1: (ca A - w D) had to be perturbed to make its smallest
+*               (or only) singular value greater than SMIN.
+*          NOTE: In the interests of speed, this routine does not
+*                check the inputs for errors.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            ICMAX, J
+      REAL               BBND, BI1, BI2, BIGNUM, BNORM, BR1, BR2, CI21,
+     $                   CI22, CMAX, CNORM, CR21, CR22, CSI, CSR, LI21,
+     $                   LR21, SMINI, SMLNUM, TEMP, U22ABS, UI11, UI11R,
+     $                   UI12, UI12S, UI22, UR11, UR11R, UR12, UR12S,
+     $                   UR22, XI1, XI2, XR1, XR2
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            CSWAP( 4 ), RSWAP( 4 )
+      INTEGER            IPIVOT( 4, 4 )
+      REAL               CI( 2, 2 ), CIV( 4 ), CR( 2, 2 ), CRV( 4 )
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLADIV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Equivalences ..
+      EQUIVALENCE        ( CI( 1, 1 ), CIV( 1 ) ),
+     $                   ( CR( 1, 1 ), CRV( 1 ) )
+*     ..
+*     .. Data statements ..
+      DATA               CSWAP / .FALSE., .FALSE., .TRUE., .TRUE. /
+      DATA               RSWAP / .FALSE., .TRUE., .FALSE., .TRUE. /
+      DATA               IPIVOT / 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4,
+     $                   3, 2, 1 /
+*     ..
+*     .. Executable Statements ..
+*
+*     Compute BIGNUM
+*
+      SMLNUM = TWO*SLAMCH( 'Safe minimum' )
+      BIGNUM = ONE / SMLNUM
+      SMINI = MAX( SMIN, SMLNUM )
+*
+*     Don't check for input errors
+*
+      INFO = 0
+*
+*     Standard Initializations
+*
+      SCALE = ONE
+*
+      IF( NA.EQ.1 ) THEN
+*
+*        1 x 1  (i.e., scalar) system   C X = B
+*
+         IF( NW.EQ.1 ) THEN
+*
+*           Real 1x1 system.
+*
+*           C = ca A - w D
+*
+            CSR = CA*A( 1, 1 ) - WR*D1
+            CNORM = ABS( CSR )
+*
+*           If | C | < SMINI, use C = SMINI
+*
+            IF( CNORM.LT.SMINI ) THEN
+               CSR = SMINI
+               CNORM = SMINI
+               INFO = 1
+            END IF
+*
+*           Check scaling for  X = B / C
+*
+            BNORM = ABS( B( 1, 1 ) )
+            IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
+               IF( BNORM.GT.BIGNUM*CNORM )
+     $            SCALE = ONE / BNORM
+            END IF
+*
+*           Compute X
+*
+            X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / CSR
+            XNORM = ABS( X( 1, 1 ) )
+         ELSE
+*
+*           Complex 1x1 system (w is complex)
+*
+*           C = ca A - w D
+*
+            CSR = CA*A( 1, 1 ) - WR*D1
+            CSI = -WI*D1
+            CNORM = ABS( CSR ) + ABS( CSI )
+*
+*           If | C | < SMINI, use C = SMINI
+*
+            IF( CNORM.LT.SMINI ) THEN
+               CSR = SMINI
+               CSI = ZERO
+               CNORM = SMINI
+               INFO = 1
+            END IF
+*
+*           Check scaling for  X = B / C
+*
+            BNORM = ABS( B( 1, 1 ) ) + ABS( B( 1, 2 ) )
+            IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
+               IF( BNORM.GT.BIGNUM*CNORM )
+     $            SCALE = ONE / BNORM
+            END IF
+*
+*           Compute X
+*
+            CALL SLADIV( SCALE*B( 1, 1 ), SCALE*B( 1, 2 ), CSR, CSI,
+     $                   X( 1, 1 ), X( 1, 2 ) )
+            XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
+         END IF
+*
+      ELSE
+*
+*        2x2 System
+*
+*        Compute the real part of  C = ca A - w D  (or  ca A' - w D )
+*
+         CR( 1, 1 ) = CA*A( 1, 1 ) - WR*D1
+         CR( 2, 2 ) = CA*A( 2, 2 ) - WR*D2
+         IF( LTRANS ) THEN
+            CR( 1, 2 ) = CA*A( 2, 1 )
+            CR( 2, 1 ) = CA*A( 1, 2 )
+         ELSE
+            CR( 2, 1 ) = CA*A( 2, 1 )
+            CR( 1, 2 ) = CA*A( 1, 2 )
+         END IF
+*
+         IF( NW.EQ.1 ) THEN
+*
+*           Real 2x2 system  (w is real)
+*
+*           Find the largest element in C
+*
+            CMAX = ZERO
+            ICMAX = 0
+*
+            DO 10 J = 1, 4
+               IF( ABS( CRV( J ) ).GT.CMAX ) THEN
+                  CMAX = ABS( CRV( J ) )
+                  ICMAX = J
+               END IF
+   10       CONTINUE
+*
+*           If norm(C) < SMINI, use SMINI*identity.
+*
+            IF( CMAX.LT.SMINI ) THEN
+               BNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 2, 1 ) ) )
+               IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
+                  IF( BNORM.GT.BIGNUM*SMINI )
+     $               SCALE = ONE / BNORM
+               END IF
+               TEMP = SCALE / SMINI
+               X( 1, 1 ) = TEMP*B( 1, 1 )
+               X( 2, 1 ) = TEMP*B( 2, 1 )
+               XNORM = TEMP*BNORM
+               INFO = 1
+               RETURN
+            END IF
+*
+*           Gaussian elimination with complete pivoting.
+*
+            UR11 = CRV( ICMAX )
+            CR21 = CRV( IPIVOT( 2, ICMAX ) )
+            UR12 = CRV( IPIVOT( 3, ICMAX ) )
+            CR22 = CRV( IPIVOT( 4, ICMAX ) )
+            UR11R = ONE / UR11
+            LR21 = UR11R*CR21
+            UR22 = CR22 - UR12*LR21
+*
+*           If smaller pivot < SMINI, use SMINI
+*
+            IF( ABS( UR22 ).LT.SMINI ) THEN
+               UR22 = SMINI
+               INFO = 1
+            END IF
+            IF( RSWAP( ICMAX ) ) THEN
+               BR1 = B( 2, 1 )
+               BR2 = B( 1, 1 )
+            ELSE
+               BR1 = B( 1, 1 )
+               BR2 = B( 2, 1 )
+            END IF
+            BR2 = BR2 - LR21*BR1
+            BBND = MAX( ABS( BR1*( UR22*UR11R ) ), ABS( BR2 ) )
+            IF( BBND.GT.ONE .AND. ABS( UR22 ).LT.ONE ) THEN
+               IF( BBND.GE.BIGNUM*ABS( UR22 ) )
+     $            SCALE = ONE / BBND
+            END IF
+*
+            XR2 = ( BR2*SCALE ) / UR22
+            XR1 = ( SCALE*BR1 )*UR11R - XR2*( UR11R*UR12 )
+            IF( CSWAP( ICMAX ) ) THEN
+               X( 1, 1 ) = XR2
+               X( 2, 1 ) = XR1
+            ELSE
+               X( 1, 1 ) = XR1
+               X( 2, 1 ) = XR2
+            END IF
+            XNORM = MAX( ABS( XR1 ), ABS( XR2 ) )
+*
+*           Further scaling if  norm(A) norm(X) > overflow
+*
+            IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
+               IF( XNORM.GT.BIGNUM / CMAX ) THEN
+                  TEMP = CMAX / BIGNUM
+                  X( 1, 1 ) = TEMP*X( 1, 1 )
+                  X( 2, 1 ) = TEMP*X( 2, 1 )
+                  XNORM = TEMP*XNORM
+                  SCALE = TEMP*SCALE
+               END IF
+            END IF
+         ELSE
+*
+*           Complex 2x2 system  (w is complex)
+*
+*           Find the largest element in C
+*
+            CI( 1, 1 ) = -WI*D1
+            CI( 2, 1 ) = ZERO
+            CI( 1, 2 ) = ZERO
+            CI( 2, 2 ) = -WI*D2
+            CMAX = ZERO
+            ICMAX = 0
+*
+            DO 20 J = 1, 4
+               IF( ABS( CRV( J ) )+ABS( CIV( J ) ).GT.CMAX ) THEN
+                  CMAX = ABS( CRV( J ) ) + ABS( CIV( J ) )
+                  ICMAX = J
+               END IF
+   20       CONTINUE
+*
+*           If norm(C) < SMINI, use SMINI*identity.
+*
+            IF( CMAX.LT.SMINI ) THEN
+               BNORM = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),
+     $                 ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )
+               IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
+                  IF( BNORM.GT.BIGNUM*SMINI )
+     $               SCALE = ONE / BNORM
+               END IF
+               TEMP = SCALE / SMINI
+               X( 1, 1 ) = TEMP*B( 1, 1 )
+               X( 2, 1 ) = TEMP*B( 2, 1 )
+               X( 1, 2 ) = TEMP*B( 1, 2 )
+               X( 2, 2 ) = TEMP*B( 2, 2 )
+               XNORM = TEMP*BNORM
+               INFO = 1
+               RETURN
+            END IF
+*
+*           Gaussian elimination with complete pivoting.
+*
+            UR11 = CRV( ICMAX )
+            UI11 = CIV( ICMAX )
+            CR21 = CRV( IPIVOT( 2, ICMAX ) )
+            CI21 = CIV( IPIVOT( 2, ICMAX ) )
+            UR12 = CRV( IPIVOT( 3, ICMAX ) )
+            UI12 = CIV( IPIVOT( 3, ICMAX ) )
+            CR22 = CRV( IPIVOT( 4, ICMAX ) )
+            CI22 = CIV( IPIVOT( 4, ICMAX ) )
+            IF( ICMAX.EQ.1 .OR. ICMAX.EQ.4 ) THEN
+*
+*              Code when off-diagonals of pivoted C are real
+*
+               IF( ABS( UR11 ).GT.ABS( UI11 ) ) THEN
+                  TEMP = UI11 / UR11
+                  UR11R = ONE / ( UR11*( ONE+TEMP**2 ) )
+                  UI11R = -TEMP*UR11R
+               ELSE
+                  TEMP = UR11 / UI11
+                  UI11R = -ONE / ( UI11*( ONE+TEMP**2 ) )
+                  UR11R = -TEMP*UI11R
+               END IF
+               LR21 = CR21*UR11R
+               LI21 = CR21*UI11R
+               UR12S = UR12*UR11R
+               UI12S = UR12*UI11R
+               UR22 = CR22 - UR12*LR21
+               UI22 = CI22 - UR12*LI21
+            ELSE
+*
+*              Code when diagonals of pivoted C are real
+*
+               UR11R = ONE / UR11
+               UI11R = ZERO
+               LR21 = CR21*UR11R
+               LI21 = CI21*UR11R
+               UR12S = UR12*UR11R
+               UI12S = UI12*UR11R
+               UR22 = CR22 - UR12*LR21 + UI12*LI21
+               UI22 = -UR12*LI21 - UI12*LR21
+            END IF
+            U22ABS = ABS( UR22 ) + ABS( UI22 )
+*
+*           If smaller pivot < SMINI, use SMINI
+*
+            IF( U22ABS.LT.SMINI ) THEN
+               UR22 = SMINI
+               UI22 = ZERO
+               INFO = 1
+            END IF
+            IF( RSWAP( ICMAX ) ) THEN
+               BR2 = B( 1, 1 )
+               BR1 = B( 2, 1 )
+               BI2 = B( 1, 2 )
+               BI1 = B( 2, 2 )
+            ELSE
+               BR1 = B( 1, 1 )
+               BR2 = B( 2, 1 )
+               BI1 = B( 1, 2 )
+               BI2 = B( 2, 2 )
+            END IF
+            BR2 = BR2 - LR21*BR1 + LI21*BI1
+            BI2 = BI2 - LI21*BR1 - LR21*BI1
+            BBND = MAX( ( ABS( BR1 )+ABS( BI1 ) )*
+     $             ( U22ABS*( ABS( UR11R )+ABS( UI11R ) ) ),
+     $             ABS( BR2 )+ABS( BI2 ) )
+            IF( BBND.GT.ONE .AND. U22ABS.LT.ONE ) THEN
+               IF( BBND.GE.BIGNUM*U22ABS ) THEN
+                  SCALE = ONE / BBND
+                  BR1 = SCALE*BR1
+                  BI1 = SCALE*BI1
+                  BR2 = SCALE*BR2
+                  BI2 = SCALE*BI2
+               END IF
+            END IF
+*
+            CALL SLADIV( BR2, BI2, UR22, UI22, XR2, XI2 )
+            XR1 = UR11R*BR1 - UI11R*BI1 - UR12S*XR2 + UI12S*XI2
+            XI1 = UI11R*BR1 + UR11R*BI1 - UI12S*XR2 - UR12S*XI2
+            IF( CSWAP( ICMAX ) ) THEN
+               X( 1, 1 ) = XR2
+               X( 2, 1 ) = XR1
+               X( 1, 2 ) = XI2
+               X( 2, 2 ) = XI1
+            ELSE
+               X( 1, 1 ) = XR1
+               X( 2, 1 ) = XR2
+               X( 1, 2 ) = XI1
+               X( 2, 2 ) = XI2
+            END IF
+            XNORM = MAX( ABS( XR1 )+ABS( XI1 ), ABS( XR2 )+ABS( XI2 ) )
+*
+*           Further scaling if  norm(A) norm(X) > overflow
+*
+            IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
+               IF( XNORM.GT.BIGNUM / CMAX ) THEN
+                  TEMP = CMAX / BIGNUM
+                  X( 1, 1 ) = TEMP*X( 1, 1 )
+                  X( 2, 1 ) = TEMP*X( 2, 1 )
+                  X( 1, 2 ) = TEMP*X( 1, 2 )
+                  X( 2, 2 ) = TEMP*X( 2, 2 )
+                  XNORM = TEMP*XNORM
+                  SCALE = TEMP*SCALE
+               END IF
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of SLALN2
+*
+      END
diff --git a/libcruft/lapack/slals0.f b/libcruft/lapack/slals0.f
new file mode 100644
index 0000000..336a026
--- /dev/null
+++ b/libcruft/lapack/slals0.f
@@ -0,0 +1,377 @@
+      SUBROUTINE SLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
+     $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
+     $                   POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
+     $                   LDGNUM, NL, NR, NRHS, SQRE
+      REAL               C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), PERM( * )
+      REAL               B( LDB, * ), BX( LDBX, * ), DIFL( * ),
+     $                   DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),
+     $                   POLES( LDGNUM, * ), WORK( * ), Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLALS0 applies back the multiplying factors of either the left or the
+*  right singular vector matrix of a diagonal matrix appended by a row
+*  to the right hand side matrix B in solving the least squares problem
+*  using the divide-and-conquer SVD approach.
+*
+*  For the left singular vector matrix, three types of orthogonal
+*  matrices are involved:
+*
+*  (1L) Givens rotations: the number of such rotations is GIVPTR; the
+*       pairs of columns/rows they were applied to are stored in GIVCOL;
+*       and the C- and S-values of these rotations are stored in GIVNUM.
+*
+*  (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
+*       row, and for J=2:N, PERM(J)-th row of B is to be moved to the
+*       J-th row.
+*
+*  (3L) The left singular vector matrix of the remaining matrix.
+*
+*  For the right singular vector matrix, four types of orthogonal
+*  matrices are involved:
+*
+*  (1R) The right singular vector matrix of the remaining matrix.
+*
+*  (2R) If SQRE = 1, one extra Givens rotation to generate the right
+*       null space.
+*
+*  (3R) The inverse transformation of (2L).
+*
+*  (4R) The inverse transformation of (1L).
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed in
+*         factored form:
+*         = 0: Left singular vector matrix.
+*         = 1: Right singular vector matrix.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block. NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block. NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) REAL array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M. On output, B contains
+*         the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B. LDB must be at least
+*         max(1,MAX( M, N ) ).
+*
+*  BX     (workspace) REAL array, dimension ( LDBX, NRHS )
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  PERM   (input) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) applied
+*         to the two blocks.
+*
+*  GIVPTR (input) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of rows/columns
+*         involved in a Givens rotation.
+*
+*  LDGCOL (input) INTEGER
+*         The leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (input) REAL array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value used in the
+*         corresponding Givens rotation.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of arrays DIFR, POLES and
+*         GIVNUM, must be at least K.
+*
+*  POLES  (input) REAL array, dimension ( LDGNUM, 2 )
+*         On entry, POLES(1:K, 1) contains the new singular
+*         values obtained from solving the secular equation, and
+*         POLES(1:K, 2) is an array containing the poles in the secular
+*         equation.
+*
+*  DIFL   (input) REAL array, dimension ( K ).
+*         On entry, DIFL(I) is the distance between I-th updated
+*         (undeflated) singular value and the I-th (undeflated) old
+*         singular value.
+*
+*  DIFR   (input) REAL array, dimension ( LDGNUM, 2 ).
+*         On entry, DIFR(I, 1) contains the distances between I-th
+*         updated (undeflated) singular value and the I+1-th
+*         (undeflated) old singular value. And DIFR(I, 2) is the
+*         normalizing factor for the I-th right singular vector.
+*
+*  Z      (input) REAL array, dimension ( K )
+*         Contain the components of the deflation-adjusted updating row
+*         vector.
+*
+*  K      (input) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  C      (input) REAL
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (input) REAL
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  WORK   (workspace) REAL array, dimension ( K )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO, NEGONE
+      PARAMETER          ( ONE = 1.0E0, ZERO = 0.0E0, NEGONE = -1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, M, N, NLP1
+      REAL               DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEMV, SLACPY, SLASCL, SROT, SSCAL,
+     $                   XERBLA
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3, SNRM2
+      EXTERNAL           SLAMC3, SNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      END IF
+*
+      N = NL + NR + 1
+*
+      IF( NRHS.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -7
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -9
+      ELSE IF( GIVPTR.LT.0 ) THEN
+         INFO = -11
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -13
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -15
+      ELSE IF( K.LT.1 ) THEN
+         INFO = -20
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLALS0', -INFO )
+         RETURN
+      END IF
+*
+      M = N + SQRE
+      NLP1 = NL + 1
+*
+      IF( ICOMPQ.EQ.0 ) THEN
+*
+*        Apply back orthogonal transformations from the left.
+*
+*        Step (1L): apply back the Givens rotations performed.
+*
+         DO 10 I = 1, GIVPTR
+            CALL SROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                 B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                 GIVNUM( I, 1 ) )
+   10    CONTINUE
+*
+*        Step (2L): permute rows of B.
+*
+         CALL SCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
+         DO 20 I = 2, N
+            CALL SCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
+   20    CONTINUE
+*
+*        Step (3L): apply the inverse of the left singular vector
+*        matrix to BX.
+*
+         IF( K.EQ.1 ) THEN
+            CALL SCOPY( NRHS, BX, LDBX, B, LDB )
+            IF( Z( 1 ).LT.ZERO ) THEN
+               CALL SSCAL( NRHS, NEGONE, B, LDB )
+            END IF
+         ELSE
+            DO 50 J = 1, K
+               DIFLJ = DIFL( J )
+               DJ = POLES( J, 1 )
+               DSIGJ = -POLES( J, 2 )
+               IF( J.LT.K ) THEN
+                  DIFRJ = -DIFR( J, 1 )
+                  DSIGJP = -POLES( J+1, 2 )
+               END IF
+               IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
+     $              THEN
+                  WORK( J ) = ZERO
+               ELSE
+                  WORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
+     $                        ( POLES( J, 2 )+DJ )
+               END IF
+               DO 30 I = 1, J - 1
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                           ( SLAMC3( POLES( I, 2 ), DSIGJ )-
+     $                           DIFLJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   30          CONTINUE
+               DO 40 I = J + 1, K
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                           ( SLAMC3( POLES( I, 2 ), DSIGJP )+
+     $                           DIFRJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   40          CONTINUE
+               WORK( 1 ) = NEGONE
+               TEMP = SNRM2( K, WORK, 1 )
+               CALL SGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
+     $                     B( J, 1 ), LDB )
+               CALL SLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
+     $                      LDB, INFO )
+   50       CONTINUE
+         END IF
+*
+*        Move the deflated rows of BX to B also.
+*
+         IF( K.LT.MAX( M, N ) )
+     $      CALL SLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
+     $                   B( K+1, 1 ), LDB )
+      ELSE
+*
+*        Apply back the right orthogonal transformations.
+*
+*        Step (1R): apply back the new right singular vector matrix
+*        to B.
+*
+         IF( K.EQ.1 ) THEN
+            CALL SCOPY( NRHS, B, LDB, BX, LDBX )
+         ELSE
+            DO 80 J = 1, K
+               DSIGJ = POLES( J, 2 )
+               IF( Z( J ).EQ.ZERO ) THEN
+                  WORK( J ) = ZERO
+               ELSE
+                  WORK( J ) = -Z( J ) / DIFL( J ) /
+     $                        ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
+               END IF
+               DO 60 I = 1, J - 1
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = Z( J ) / ( SLAMC3( DSIGJ, -POLES( I+1,
+     $                           2 ) )-DIFR( I, 1 ) ) /
+     $                           ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+   60          CONTINUE
+               DO 70 I = J + 1, K
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     WORK( I ) = ZERO
+                  ELSE
+                     WORK( I ) = Z( J ) / ( SLAMC3( DSIGJ, -POLES( I,
+     $                           2 ) )-DIFL( I ) ) /
+     $                           ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+   70          CONTINUE
+               CALL SGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
+     $                     BX( J, 1 ), LDBX )
+   80       CONTINUE
+         END IF
+*
+*        Step (2R): if SQRE = 1, apply back the rotation that is
+*        related to the right null space of the subproblem.
+*
+         IF( SQRE.EQ.1 ) THEN
+            CALL SCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
+            CALL SROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
+         END IF
+         IF( K.LT.MAX( M, N ) )
+     $      CALL SLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),
+     $                   LDBX )
+*
+*        Step (3R): permute rows of B.
+*
+         CALL SCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
+         IF( SQRE.EQ.1 ) THEN
+            CALL SCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
+         END IF
+         DO 90 I = 2, N
+            CALL SCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
+   90    CONTINUE
+*
+*        Step (4R): apply back the Givens rotations performed.
+*
+         DO 100 I = GIVPTR, 1, -1
+            CALL SROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                 B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                 -GIVNUM( I, 1 ) )
+  100    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SLALS0
+*
+      END
diff --git a/libcruft/lapack/slalsa.f b/libcruft/lapack/slalsa.f
new file mode 100644
index 0000000..3dd606b
--- /dev/null
+++ b/libcruft/lapack/slalsa.f
@@ -0,0 +1,362 @@
+      SUBROUTINE SLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,
+     $                   LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,
+     $                   GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,
+     $                   SMLSIZ
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
+     $                   K( * ), PERM( LDGCOL, * )
+      REAL               B( LDB, * ), BX( LDBX, * ), C( * ),
+     $                   DIFL( LDU, * ), DIFR( LDU, * ),
+     $                   GIVNUM( LDU, * ), POLES( LDU, * ), S( * ),
+     $                   U( LDU, * ), VT( LDU, * ), WORK( * ),
+     $                   Z( LDU, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLALSA is an itermediate step in solving the least squares problem
+*  by computing the SVD of the coefficient matrix in compact form (The
+*  singular vectors are computed as products of simple orthorgonal
+*  matrices.).
+*
+*  If ICOMPQ = 0, SLALSA applies the inverse of the left singular vector
+*  matrix of an upper bidiagonal matrix to the right hand side; and if
+*  ICOMPQ = 1, SLALSA applies the right singular vector matrix to the
+*  right hand side. The singular vector matrices were generated in
+*  compact form by SLALSA.
+*
+*  Arguments
+*  =========
+*
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether the left or the right singular vector
+*         matrix is involved.
+*         = 0: Left singular vector matrix
+*         = 1: Right singular vector matrix
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The row and column dimensions of the upper bidiagonal matrix.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) REAL array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M.
+*         On output, B contains the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,MAX( M, N ) ).
+*
+*  BX     (output) REAL array, dimension ( LDBX, NRHS )
+*         On exit, the result of applying the left or right singular
+*         vector matrix to B.
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  U      (input) REAL array, dimension ( LDU, SMLSIZ ).
+*         On entry, U contains the left singular vector matrices of all
+*         subproblems at the bottom level.
+*
+*  LDU    (input) INTEGER, LDU = > N.
+*         The leading dimension of arrays U, VT, DIFL, DIFR,
+*         POLES, GIVNUM, and Z.
+*
+*  VT     (input) REAL array, dimension ( LDU, SMLSIZ+1 ).
+*         On entry, VT' contains the right singular vector matrices of
+*         all subproblems at the bottom level.
+*
+*  K      (input) INTEGER array, dimension ( N ).
+*
+*  DIFL   (input) REAL array, dimension ( LDU, NLVL ).
+*         where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.
+*
+*  DIFR   (input) REAL array, dimension ( LDU, 2 * NLVL ).
+*         On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record
+*         distances between singular values on the I-th level and
+*         singular values on the (I -1)-th level, and DIFR(*, 2 * I)
+*         record the normalizing factors of the right singular vectors
+*         matrices of subproblems on I-th level.
+*
+*  Z      (input) REAL array, dimension ( LDU, NLVL ).
+*         On entry, Z(1, I) contains the components of the deflation-
+*         adjusted updating row vector for subproblems on the I-th
+*         level.
+*
+*  POLES  (input) REAL array, dimension ( LDU, 2 * NLVL ).
+*         On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old
+*         singular values involved in the secular equations on the I-th
+*         level.
+*
+*  GIVPTR (input) INTEGER array, dimension ( N ).
+*         On entry, GIVPTR( I ) records the number of Givens
+*         rotations performed on the I-th problem on the computation
+*         tree.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ).
+*         On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the
+*         locations of Givens rotations performed on the I-th level on
+*         the computation tree.
+*
+*  LDGCOL (input) INTEGER, LDGCOL = > N.
+*         The leading dimension of arrays GIVCOL and PERM.
+*
+*  PERM   (input) INTEGER array, dimension ( LDGCOL, NLVL ).
+*         On entry, PERM(*, I) records permutations done on the I-th
+*         level of the computation tree.
+*
+*  GIVNUM (input) REAL array, dimension ( LDU, 2 * NLVL ).
+*         On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-
+*         values of Givens rotations performed on the I-th level on the
+*         computation tree.
+*
+*  C      (input) REAL array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         C( I ) contains the C-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  S      (input) REAL array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         S( I ) contains the S-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  WORK   (workspace) REAL array.
+*         The dimension must be at least N.
+*
+*  IWORK  (workspace) INTEGER array.
+*         The dimension must be at least 3 * N
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IM1, INODE, J, LF, LL, LVL, LVL2,
+     $                   ND, NDB1, NDIML, NDIMR, NL, NLF, NLP1, NLVL,
+     $                   NR, NRF, NRP1, SQRE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEMM, SLALS0, SLASDT, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.SMLSIZ ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -6
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -19
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLALSA', -INFO )
+         RETURN
+      END IF
+*
+*     Book-keeping and  setting up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+*
+      CALL SLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     The following code applies back the left singular vector factors.
+*     For applying back the right singular vector factors, go to 50.
+*
+      IF( ICOMPQ.EQ.1 ) THEN
+         GO TO 50
+      END IF
+*
+*     The nodes on the bottom level of the tree were solved
+*     by SLASDQ. The corresponding left and right singular vector
+*     matrices are in explicit form. First apply back the left
+*     singular vector matrices.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 10 I = NDB1, ND
+*
+*        IC : center row of each node
+*        NL : number of rows of left  subproblem
+*        NR : number of rows of right subproblem
+*        NLF: starting row of the left   subproblem
+*        NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLF = IC - NL
+         NRF = IC + 1
+         CALL SGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+         CALL SGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+     $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+   10 CONTINUE
+*
+*     Next copy the rows of B that correspond to unchanged rows
+*     in the bidiagonal matrix to BX.
+*
+      DO 20 I = 1, ND
+         IC = IWORK( INODE+I-1 )
+         CALL SCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )
+   20 CONTINUE
+*
+*     Finally go through the left singular vector matrices of all
+*     the other subproblems bottom-up on the tree.
+*
+      J = 2**NLVL
+      SQRE = 0
+*
+      DO 40 LVL = NLVL, 1, -1
+         LVL2 = 2*LVL - 1
+*
+*        find the first node LF and last node LL on
+*        the current level LVL
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 30 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            J = J - 1
+            CALL SLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,
+     $                   B( NLF, 1 ), LDB, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,
+     $                   INFO )
+   30    CONTINUE
+   40 CONTINUE
+      GO TO 90
+*
+*     ICOMPQ = 1: applying back the right singular vector factors.
+*
+   50 CONTINUE
+*
+*     First now go through the right singular vector matrices of all
+*     the tree nodes top-down.
+*
+      J = 0
+      DO 70 LVL = 1, NLVL
+         LVL2 = 2*LVL - 1
+*
+*        Find the first node LF and last node LL on
+*        the current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 60 I = LL, LF, -1
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            IF( I.EQ.LL ) THEN
+               SQRE = 0
+            ELSE
+               SQRE = 1
+            END IF
+            J = J + 1
+            CALL SLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,
+     $                   BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,
+     $                   INFO )
+   60    CONTINUE
+   70 CONTINUE
+*
+*     The nodes on the bottom level of the tree were solved
+*     by SLASDQ. The corresponding right singular vector
+*     matrices are in explicit form. Apply them back.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 80 I = NDB1, ND
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLP1 = NL + 1
+         IF( I.EQ.ND ) THEN
+            NRP1 = NR
+         ELSE
+            NRP1 = NR + 1
+         END IF
+         NLF = IC - NL
+         NRF = IC + 1
+         CALL SGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+         CALL SGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+     $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+   80 CONTINUE
+*
+   90 CONTINUE
+*
+      RETURN
+*
+*     End of SLALSA
+*
+      END
diff --git a/libcruft/lapack/slalsd.f b/libcruft/lapack/slalsd.f
new file mode 100644
index 0000000..49e0ac2
--- /dev/null
+++ b/libcruft/lapack/slalsd.f
@@ -0,0 +1,434 @@
+      SUBROUTINE SLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
+     $                   RANK, WORK, IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDB, N, NRHS, RANK, SMLSIZ
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               B( LDB, * ), D( * ), E( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLALSD uses the singular value decomposition of A to solve the least
+*  squares problem of finding X to minimize the Euclidean norm of each
+*  column of A*X-B, where A is N-by-N upper bidiagonal, and X and B
+*  are N-by-NRHS. The solution X overwrites B.
+*
+*  The singular values of A smaller than RCOND times the largest
+*  singular value are treated as zero in solving the least squares
+*  problem; in this case a minimum norm solution is returned.
+*  The actual singular values are returned in D in ascending order.
+*
+*  This code makes very mild assumptions about floating point
+*  arithmetic. It will work on machines with a guard digit in
+*  add/subtract, or on those binary machines without guard digits
+*  which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
+*  It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  UPLO   (input) CHARACTER*1
+*         = 'U': D and E define an upper bidiagonal matrix.
+*         = 'L': D and E define a  lower bidiagonal matrix.
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The dimension of the  bidiagonal matrix.  N >= 0.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B. NRHS must be at least 1.
+*
+*  D      (input/output) REAL array, dimension (N)
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix. On exit, if INFO = 0, D contains its singular values.
+*
+*  E      (input/output) REAL array, dimension (N-1)
+*         Contains the super-diagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  B      (input/output) REAL array, dimension (LDB,NRHS)
+*         On input, B contains the right hand sides of the least
+*         squares problem. On output, B contains the solution X.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,N).
+*
+*  RCOND  (input) REAL
+*         The singular values of A less than or equal to RCOND times
+*         the largest singular value are treated as zero in solving
+*         the least squares problem. If RCOND is negative,
+*         machine precision is used instead.
+*         For example, if diag(S)*X=B were the least squares problem,
+*         where diag(S) is a diagonal matrix of singular values, the
+*         solution would be X(i) = B(i) / S(i) if S(i) is greater than
+*         RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to
+*         RCOND*max(S).
+*
+*  RANK   (output) INTEGER
+*         The number of singular values of A greater than RCOND times
+*         the largest singular value.
+*
+*  WORK   (workspace) REAL array, dimension at least
+*         (9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2),
+*         where NLVL = max(0, INT(log_2 (N/(SMLSIZ+1))) + 1).
+*
+*  IWORK  (workspace) INTEGER array, dimension at least
+*         (3*N*NLVL + 11*N)
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*         > 0:  The algorithm failed to compute an singular value while
+*               working on the submatrix lying in rows and columns
+*               INFO/(N+1) through MOD(INFO,N+1).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
+     $                   GIVPTR, I, ICMPQ1, ICMPQ2, IWK, J, K, NLVL,
+     $                   NM1, NSIZE, NSUB, NWORK, PERM, POLES, S, SIZEI,
+     $                   SMLSZP, SQRE, ST, ST1, U, VT, Z
+      REAL               CS, EPS, ORGNRM, R, RCND, SN, TOL
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SLAMCH, SLANST
+      EXTERNAL           ISAMAX, SLAMCH, SLANST
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEMM, SLACPY, SLALSA, SLARTG, SLASCL,
+     $                   SLASDA, SLASDQ, SLASET, SLASRT, SROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, LOG, REAL, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLALSD', -INFO )
+         RETURN
+      END IF
+*
+      EPS = SLAMCH( 'Epsilon' )
+*
+*     Set up the tolerance.
+*
+      IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THEN
+         RCND = EPS
+      ELSE
+         RCND = RCOND
+      END IF
+*
+      RANK = 0
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+         IF( D( 1 ).EQ.ZERO ) THEN
+            CALL SLASET( 'A', 1, NRHS, ZERO, ZERO, B, LDB )
+         ELSE
+            RANK = 1
+            CALL SLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )
+            D( 1 ) = ABS( D( 1 ) )
+         END IF
+         RETURN
+      END IF
+*
+*     Rotate the matrix if it is lower bidiagonal.
+*
+      IF( UPLO.EQ.'L' ) THEN
+         DO 10 I = 1, N - 1
+            CALL SLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( NRHS.EQ.1 ) THEN
+               CALL SROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )
+            ELSE
+               WORK( I*2-1 ) = CS
+               WORK( I*2 ) = SN
+            END IF
+   10    CONTINUE
+         IF( NRHS.GT.1 ) THEN
+            DO 30 I = 1, NRHS
+               DO 20 J = 1, N - 1
+                  CS = WORK( J*2-1 )
+                  SN = WORK( J*2 )
+                  CALL SROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )
+   20          CONTINUE
+   30       CONTINUE
+         END IF
+      END IF
+*
+*     Scale.
+*
+      NM1 = N - 1
+      ORGNRM = SLANST( 'M', N, D, E )
+      IF( ORGNRM.EQ.ZERO ) THEN
+         CALL SLASET( 'A', N, NRHS, ZERO, ZERO, B, LDB )
+         RETURN
+      END IF
+*
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )
+*
+*     If N is smaller than the minimum divide size SMLSIZ, then solve
+*     the problem with another solver.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         NWORK = 1 + N*N
+         CALL SLASET( 'A', N, N, ZERO, ONE, WORK, N )
+         CALL SLASDQ( 'U', 0, N, N, 0, NRHS, D, E, WORK, N, WORK, N, B,
+     $                LDB, WORK( NWORK ), INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         TOL = RCND*ABS( D( ISAMAX( N, D, 1 ) ) )
+         DO 40 I = 1, N
+            IF( D( I ).LE.TOL ) THEN
+               CALL SLASET( 'A', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
+            ELSE
+               CALL SLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),
+     $                      LDB, INFO )
+               RANK = RANK + 1
+            END IF
+   40    CONTINUE
+         CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,
+     $               WORK( NWORK ), N )
+         CALL SLACPY( 'A', N, NRHS, WORK( NWORK ), N, B, LDB )
+*
+*        Unscale.
+*
+         CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+         CALL SLASRT( 'D', N, D, INFO )
+         CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+         RETURN
+      END IF
+*
+*     Book-keeping and setting up some constants.
+*
+      NLVL = INT( LOG( REAL( N ) / REAL( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1
+*
+      SMLSZP = SMLSIZ + 1
+*
+      U = 1
+      VT = 1 + SMLSIZ*N
+      DIFL = VT + SMLSZP*N
+      DIFR = DIFL + NLVL*N
+      Z = DIFR + NLVL*N*2
+      C = Z + NLVL*N
+      S = C + N
+      POLES = S + N
+      GIVNUM = POLES + 2*NLVL*N
+      BX = GIVNUM + 2*NLVL*N
+      NWORK = BX + N*NRHS
+*
+      SIZEI = 1 + N
+      K = SIZEI + N
+      GIVPTR = K + N
+      PERM = GIVPTR + N
+      GIVCOL = PERM + NLVL*N
+      IWK = GIVCOL + NLVL*N*2
+*
+      ST = 1
+      SQRE = 0
+      ICMPQ1 = 1
+      ICMPQ2 = 0
+      NSUB = 0
+*
+      DO 50 I = 1, N
+         IF( ABS( D( I ) ).LT.EPS ) THEN
+            D( I ) = SIGN( EPS, D( I ) )
+         END IF
+   50 CONTINUE
+*
+      DO 60 I = 1, NM1
+         IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
+            NSUB = NSUB + 1
+            IWORK( NSUB ) = ST
+*
+*           Subproblem found. First determine its size and then
+*           apply divide and conquer on it.
+*
+            IF( I.LT.NM1 ) THEN
+*
+*              A subproblem with E(I) small for I < NM1.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
+*
+*              A subproblem with E(NM1) not too small but I = NM1.
+*
+               NSIZE = N - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE
+*
+*              A subproblem with E(NM1) small. This implies an
+*              1-by-1 subproblem at D(N), which is not solved
+*              explicitly.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+               NSUB = NSUB + 1
+               IWORK( NSUB ) = N
+               IWORK( SIZEI+NSUB-1 ) = 1
+               CALL SCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )
+            END IF
+            ST1 = ST - 1
+            IF( NSIZE.EQ.1 ) THEN
+*
+*              This is a 1-by-1 subproblem and is not solved
+*              explicitly.
+*
+               CALL SCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )
+            ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+*
+*              This is a small subproblem and is solved by SLASDQ.
+*
+               CALL SLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
+     $                      WORK( VT+ST1 ), N )
+               CALL SLASDQ( 'U', 0, NSIZE, NSIZE, 0, NRHS, D( ST ),
+     $                      E( ST ), WORK( VT+ST1 ), N, WORK( NWORK ),
+     $                      N, B( ST, 1 ), LDB, WORK( NWORK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+               CALL SLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,
+     $                      WORK( BX+ST1 ), N )
+            ELSE
+*
+*              A large problem. Solve it using divide and conquer.
+*
+               CALL SLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),
+     $                      E( ST ), WORK( U+ST1 ), N, WORK( VT+ST1 ),
+     $                      IWORK( K+ST1 ), WORK( DIFL+ST1 ),
+     $                      WORK( DIFR+ST1 ), WORK( Z+ST1 ),
+     $                      WORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),
+     $                      IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),
+     $                      WORK( GIVNUM+ST1 ), WORK( C+ST1 ),
+     $                      WORK( S+ST1 ), WORK( NWORK ), IWORK( IWK ),
+     $                      INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+               BXST = BX + ST1
+               CALL SLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),
+     $                      LDB, WORK( BXST ), N, WORK( U+ST1 ), N,
+     $                      WORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                      WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),
+     $                      WORK( Z+ST1 ), WORK( POLES+ST1 ),
+     $                      IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                      IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),
+     $                      WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),
+     $                      IWORK( IWK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+            END IF
+            ST = I + 1
+         END IF
+   60 CONTINUE
+*
+*     Apply the singular values and treat the tiny ones as zero.
+*
+      TOL = RCND*ABS( D( ISAMAX( N, D, 1 ) ) )
+*
+      DO 70 I = 1, N
+*
+*        Some of the elements in D can be negative because 1-by-1
+*        subproblems were not solved explicitly.
+*
+         IF( ABS( D( I ) ).LE.TOL ) THEN
+            CALL SLASET( 'A', 1, NRHS, ZERO, ZERO, WORK( BX+I-1 ), N )
+         ELSE
+            RANK = RANK + 1
+            CALL SLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,
+     $                   WORK( BX+I-1 ), N, INFO )
+         END IF
+         D( I ) = ABS( D( I ) )
+   70 CONTINUE
+*
+*     Now apply back the right singular vectors.
+*
+      ICMPQ2 = 1
+      DO 80 I = 1, NSUB
+         ST = IWORK( I )
+         ST1 = ST - 1
+         NSIZE = IWORK( SIZEI+I-1 )
+         BXST = BX + ST1
+         IF( NSIZE.EQ.1 ) THEN
+            CALL SCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )
+         ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+            CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                  WORK( VT+ST1 ), N, WORK( BXST ), N, ZERO,
+     $                  B( ST, 1 ), LDB )
+         ELSE
+            CALL SLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,
+     $                   B( ST, 1 ), LDB, WORK( U+ST1 ), N,
+     $                   WORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                   WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),
+     $                   WORK( Z+ST1 ), WORK( POLES+ST1 ),
+     $                   IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                   IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),
+     $                   WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),
+     $                   IWORK( IWK ), INFO )
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+         END IF
+   80 CONTINUE
+*
+*     Unscale and sort the singular values.
+*
+      CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+      CALL SLASRT( 'D', N, D, INFO )
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+      RETURN
+*
+*     End of SLALSD
+*
+      END
diff --git a/libcruft/lapack/slamc1.f b/libcruft/lapack/slamc1.f
new file mode 100644
index 0000000..8d84fe4
--- /dev/null
+++ b/libcruft/lapack/slamc1.f
@@ -0,0 +1,183 @@
+      SUBROUTINE SLAMC1( BETA, T, RND, IEEE1 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE1, RND
+      INTEGER            BETA, T
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMC1 determines the machine parameters given by BETA, T, RND, and
+*  IEEE1.
+*
+*  Arguments
+*  =========
+*
+*  BETA    (output) INTEGER
+*          The base of the machine.
+*
+*  T       (output) INTEGER
+*          The number of ( BETA ) digits in the mantissa.
+*
+*  RND     (output) LOGICAL
+*          Specifies whether proper rounding  ( RND = .TRUE. )  or
+*          chopping  ( RND = .FALSE. )  occurs in addition. This may not
+*          be a reliable guide to the way in which the machine performs
+*          its arithmetic.
+*
+*  IEEE1   (output) LOGICAL
+*          Specifies whether rounding appears to be done in the IEEE
+*          'round to nearest' style.
+*
+*  Further Details
+*  ===============
+*
+*  The routine is based on the routine  ENVRON  by Malcolm and
+*  incorporates suggestions by Gentleman and Marovich. See
+*
+*     Malcolm M. A. (1972) Algorithms to reveal properties of
+*        floating-point arithmetic. Comms. of the ACM, 15, 949-951.
+*
+*     Gentleman W. M. and Marovich S. B. (1974) More on algorithms
+*        that reveal properties of floating point arithmetic units.
+*        Comms. of the ACM, 17, 276-277.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            FIRST, LIEEE1, LRND
+      INTEGER            LBETA, LT
+      REAL               A, B, C, F, ONE, QTR, SAVEC, T1, T2
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3
+      EXTERNAL           SLAMC3
+*     ..
+*     .. Save statement ..
+      SAVE               FIRST, LIEEE1, LBETA, LRND, LT
+*     ..
+*     .. Data statements ..
+      DATA               FIRST / .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+      IF( FIRST ) THEN
+         ONE = 1
+*
+*        LBETA,  LIEEE1,  LT and  LRND  are the  local values  of  BETA,
+*        IEEE1, T and RND.
+*
+*        Throughout this routine  we use the function  SLAMC3  to ensure
+*        that relevant values are  stored and not held in registers,  or
+*        are not affected by optimizers.
+*
+*        Compute  a = 2.0**m  with the  smallest positive integer m such
+*        that
+*
+*           fl( a + 1.0 ) = a.
+*
+         A = 1
+         C = 1
+*
+*+       WHILE( C.EQ.ONE )LOOP
+   10    CONTINUE
+         IF( C.EQ.ONE ) THEN
+            A = 2*A
+            C = SLAMC3( A, ONE )
+            C = SLAMC3( C, -A )
+            GO TO 10
+         END IF
+*+       END WHILE
+*
+*        Now compute  b = 2.0**m  with the smallest positive integer m
+*        such that
+*
+*           fl( a + b ) .gt. a.
+*
+         B = 1
+         C = SLAMC3( A, B )
+*
+*+       WHILE( C.EQ.A )LOOP
+   20    CONTINUE
+         IF( C.EQ.A ) THEN
+            B = 2*B
+            C = SLAMC3( A, B )
+            GO TO 20
+         END IF
+*+       END WHILE
+*
+*        Now compute the base.  a and c  are neighbouring floating point
+*        numbers  in the  interval  ( beta**t, beta**( t + 1 ) )  and so
+*        their difference is beta. Adding 0.25 to c is to ensure that it
+*        is truncated to beta and not ( beta - 1 ).
+*
+         QTR = ONE / 4
+         SAVEC = C
+         C = SLAMC3( C, -A )
+         LBETA = C + QTR
+*
+*        Now determine whether rounding or chopping occurs,  by adding a
+*        bit  less  than  beta/2  and a  bit  more  than  beta/2  to  a.
+*
+         B = LBETA
+         F = SLAMC3( B / 2, -B / 100 )
+         C = SLAMC3( F, A )
+         IF( C.EQ.A ) THEN
+            LRND = .TRUE.
+         ELSE
+            LRND = .FALSE.
+         END IF
+         F = SLAMC3( B / 2, B / 100 )
+         C = SLAMC3( F, A )
+         IF( ( LRND ) .AND. ( C.EQ.A ) )
+     $      LRND = .FALSE.
+*
+*        Try and decide whether rounding is done in the  IEEE  'round to
+*        nearest' style. B/2 is half a unit in the last place of the two
+*        numbers A and SAVEC. Furthermore, A is even, i.e. has last  bit
+*        zero, and SAVEC is odd. Thus adding B/2 to A should not  change
+*        A, but adding B/2 to SAVEC should change SAVEC.
+*
+         T1 = SLAMC3( B / 2, A )
+         T2 = SLAMC3( B / 2, SAVEC )
+         LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND
+*
+*        Now find  the  mantissa, t.  It should  be the  integer part of
+*        log to the base beta of a,  however it is safer to determine  t
+*        by powering.  So we find t as the smallest positive integer for
+*        which
+*
+*           fl( beta**t + 1.0 ) = 1.0.
+*
+         LT = 0
+         A = 1
+         C = 1
+*
+*+       WHILE( C.EQ.ONE )LOOP
+   30    CONTINUE
+         IF( C.EQ.ONE ) THEN
+            LT = LT + 1
+            A = A*LBETA
+            C = SLAMC3( A, ONE )
+            C = SLAMC3( C, -A )
+            GO TO 30
+         END IF
+*+       END WHILE
+*
+      END IF
+*
+      BETA = LBETA
+      T = LT
+      RND = LRND
+      IEEE1 = LIEEE1
+      FIRST = .FALSE.
+      RETURN
+*
+*     End of SLAMC1
+*
+      END
diff --git a/libcruft/lapack/slamc2.f b/libcruft/lapack/slamc2.f
new file mode 100644
index 0000000..a448c8e
--- /dev/null
+++ b/libcruft/lapack/slamc2.f
@@ -0,0 +1,255 @@
+      SUBROUTINE SLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            RND
+      INTEGER            BETA, EMAX, EMIN, T
+      REAL               EPS, RMAX, RMIN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMC2 determines the machine parameters specified in its argument
+*  list.
+*
+*  Arguments
+*  =========
+*
+*  BETA    (output) INTEGER
+*          The base of the machine.
+*
+*  T       (output) INTEGER
+*          The number of ( BETA ) digits in the mantissa.
+*
+*  RND     (output) LOGICAL
+*          Specifies whether proper rounding  ( RND = .TRUE. )  or
+*          chopping  ( RND = .FALSE. )  occurs in addition. This may not
+*          be a reliable guide to the way in which the machine performs
+*          its arithmetic.
+*
+*  EPS     (output) REAL
+*          The smallest positive number such that
+*
+*             fl( 1.0 - EPS ) .LT. 1.0,
+*
+*          where fl denotes the computed value.
+*
+*  EMIN    (output) INTEGER
+*          The minimum exponent before (gradual) underflow occurs.
+*
+*  RMIN    (output) REAL
+*          The smallest normalized number for the machine, given by
+*          BASE**( EMIN - 1 ), where  BASE  is the floating point value
+*          of BETA.
+*
+*  EMAX    (output) INTEGER
+*          The maximum exponent before overflow occurs.
+*
+*  RMAX    (output) REAL
+*          The largest positive number for the machine, given by
+*          BASE**EMAX * ( 1 - EPS ), where  BASE  is the floating point
+*          value of BETA.
+*
+*  Further Details
+*  ===============
+*
+*  The computation of  EPS  is based on a routine PARANOIA by
+*  W. Kahan of the University of California at Berkeley.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            FIRST, IEEE, IWARN, LIEEE1, LRND
+      INTEGER            GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,
+     $                   NGNMIN, NGPMIN
+      REAL               A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,
+     $                   SIXTH, SMALL, THIRD, TWO, ZERO
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3
+      EXTERNAL           SLAMC3
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAMC1, SLAMC4, SLAMC5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Save statement ..
+      SAVE               FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,
+     $                   LRMIN, LT
+*     ..
+*     .. Data statements ..
+      DATA               FIRST / .TRUE. / , IWARN / .FALSE. /
+*     ..
+*     .. Executable Statements ..
+*
+      IF( FIRST ) THEN
+         ZERO = 0
+         ONE = 1
+         TWO = 2
+*
+*        LBETA, LT, LRND, LEPS, LEMIN and LRMIN  are the local values of
+*        BETA, T, RND, EPS, EMIN and RMIN.
+*
+*        Throughout this routine  we use the function  SLAMC3  to ensure
+*        that relevant values are stored  and not held in registers,  or
+*        are not affected by optimizers.
+*
+*        SLAMC1 returns the parameters  LBETA, LT, LRND and LIEEE1.
+*
+         CALL SLAMC1( LBETA, LT, LRND, LIEEE1 )
+*
+*        Start to find EPS.
+*
+         B = LBETA
+         A = B**( -LT )
+         LEPS = A
+*
+*        Try some tricks to see whether or not this is the correct  EPS.
+*
+         B = TWO / 3
+         HALF = ONE / 2
+         SIXTH = SLAMC3( B, -HALF )
+         THIRD = SLAMC3( SIXTH, SIXTH )
+         B = SLAMC3( THIRD, -HALF )
+         B = SLAMC3( B, SIXTH )
+         B = ABS( B )
+         IF( B.LT.LEPS )
+     $      B = LEPS
+*
+         LEPS = 1
+*
+*+       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP
+   10    CONTINUE
+         IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN
+            LEPS = B
+            C = SLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )
+            C = SLAMC3( HALF, -C )
+            B = SLAMC3( HALF, C )
+            C = SLAMC3( HALF, -B )
+            B = SLAMC3( HALF, C )
+            GO TO 10
+         END IF
+*+       END WHILE
+*
+         IF( A.LT.LEPS )
+     $      LEPS = A
+*
+*        Computation of EPS complete.
+*
+*        Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)).
+*        Keep dividing  A by BETA until (gradual) underflow occurs. This
+*        is detected when we cannot recover the previous A.
+*
+         RBASE = ONE / LBETA
+         SMALL = ONE
+         DO 20 I = 1, 3
+            SMALL = SLAMC3( SMALL*RBASE, ZERO )
+   20    CONTINUE
+         A = SLAMC3( ONE, SMALL )
+         CALL SLAMC4( NGPMIN, ONE, LBETA )
+         CALL SLAMC4( NGNMIN, -ONE, LBETA )
+         CALL SLAMC4( GPMIN, A, LBETA )
+         CALL SLAMC4( GNMIN, -A, LBETA )
+         IEEE = .FALSE.
+*
+         IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN
+            IF( NGPMIN.EQ.GPMIN ) THEN
+               LEMIN = NGPMIN
+*            ( Non twos-complement machines, no gradual underflow;
+*              e.g.,  VAX )
+            ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN
+               LEMIN = NGPMIN - 1 + LT
+               IEEE = .TRUE.
+*            ( Non twos-complement machines, with gradual underflow;
+*              e.g., IEEE standard followers )
+            ELSE
+               LEMIN = MIN( NGPMIN, GPMIN )
+*            ( A guess; no known machine )
+               IWARN = .TRUE.
+            END IF
+*
+         ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN
+            IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN
+               LEMIN = MAX( NGPMIN, NGNMIN )
+*            ( Twos-complement machines, no gradual underflow;
+*              e.g., CYBER 205 )
+            ELSE
+               LEMIN = MIN( NGPMIN, NGNMIN )
+*            ( A guess; no known machine )
+               IWARN = .TRUE.
+            END IF
+*
+         ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.
+     $            ( GPMIN.EQ.GNMIN ) ) THEN
+            IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN
+               LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT
+*            ( Twos-complement machines with gradual underflow;
+*              no known machine )
+            ELSE
+               LEMIN = MIN( NGPMIN, NGNMIN )
+*            ( A guess; no known machine )
+               IWARN = .TRUE.
+            END IF
+*
+         ELSE
+            LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )
+*         ( A guess; no known machine )
+            IWARN = .TRUE.
+         END IF
+         FIRST = .FALSE.
+***
+* Comment out this if block if EMIN is ok
+         IF( IWARN ) THEN
+            FIRST = .TRUE.
+            WRITE( 6, FMT = 9999 )LEMIN
+         END IF
+***
+*
+*        Assume IEEE arithmetic if we found denormalised  numbers above,
+*        or if arithmetic seems to round in the  IEEE style,  determined
+*        in routine SLAMC1. A true IEEE machine should have both  things
+*        true; however, faulty machines may have one or the other.
+*
+         IEEE = IEEE .OR. LIEEE1
+*
+*        Compute  RMIN by successive division by  BETA. We could compute
+*        RMIN as BASE**( EMIN - 1 ),  but some machines underflow during
+*        this computation.
+*
+         LRMIN = 1
+         DO 30 I = 1, 1 - LEMIN
+            LRMIN = SLAMC3( LRMIN*RBASE, ZERO )
+   30    CONTINUE
+*
+*        Finally, call SLAMC5 to compute EMAX and RMAX.
+*
+         CALL SLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX )
+      END IF
+*
+      BETA = LBETA
+      T = LT
+      RND = LRND
+      EPS = LEPS
+      EMIN = LEMIN
+      RMIN = LRMIN
+      EMAX = LEMAX
+      RMAX = LRMAX
+*
+      RETURN
+*
+ 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',
+     $      '  EMIN = ', I8, /
+     $      ' If, after inspection, the value EMIN looks',
+     $      ' acceptable please comment out ',
+     $      / ' the IF block as marked within the code of routine',
+     $      ' SLAMC2,', / ' otherwise supply EMIN explicitly.', / )
+*
+*     End of SLAMC2
+*
+      END
diff --git a/libcruft/lapack/slamc3.f b/libcruft/lapack/slamc3.f
new file mode 100644
index 0000000..d623d14
--- /dev/null
+++ b/libcruft/lapack/slamc3.f
@@ -0,0 +1,35 @@
+      REAL             FUNCTION SLAMC3( A, B )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               A, B
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMC3  is intended to force  A  and  B  to be stored prior to doing
+*  the addition of  A  and  B ,  for use in situations where optimizers
+*  might hold one of these in a register.
+*
+*  Arguments
+*  =========
+*
+*  A       (input) REAL
+*  B       (input) REAL
+*          The values A and B.
+*
+* =====================================================================
+*
+*     .. Executable Statements ..
+*
+      SLAMC3 = A + B
+*
+      RETURN
+*
+*     End of SLAMC3
+*
+      END
diff --git a/libcruft/lapack/slamc4.f b/libcruft/lapack/slamc4.f
new file mode 100644
index 0000000..745d3b9
--- /dev/null
+++ b/libcruft/lapack/slamc4.f
@@ -0,0 +1,81 @@
+      SUBROUTINE SLAMC4( EMIN, START, BASE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            BASE
+      INTEGER            EMIN
+      REAL               START
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMC4 is a service routine for SLAMC2.
+*
+*  Arguments
+*  =========
+*
+*  EMIN    (output) INTEGER 
+*          The minimum exponent before (gradual) underflow, computed by
+*          setting A = START and dividing by BASE until the previous A
+*          can not be recovered.
+*
+*  START   (input) REAL
+*          The starting point for determining EMIN.
+*
+*  BASE    (input) INTEGER
+*          The base of the machine.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I
+      REAL               A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3
+      EXTERNAL           SLAMC3
+*     ..
+*     .. Executable Statements ..
+*
+      A = START
+      ONE = 1
+      RBASE = ONE / BASE
+      ZERO = 0
+      EMIN = 1
+      B1 = SLAMC3( A*RBASE, ZERO )
+      C1 = A
+      C2 = A
+      D1 = A
+      D2 = A
+*+    WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND.
+*    $       ( D1.EQ.A ).AND.( D2.EQ.A )      )LOOP
+   10 CONTINUE
+      IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND.
+     $    ( D2.EQ.A ) ) THEN
+         EMIN = EMIN - 1
+         A = B1
+         B1 = SLAMC3( A / BASE, ZERO )
+         C1 = SLAMC3( B1*BASE, ZERO )
+         D1 = ZERO
+         DO 20 I = 1, BASE
+            D1 = D1 + B1
+   20    CONTINUE
+         B2 = SLAMC3( A*RBASE, ZERO )
+         C2 = SLAMC3( B2 / RBASE, ZERO )
+         D2 = ZERO
+         DO 30 I = 1, BASE
+            D2 = D2 + B2
+   30    CONTINUE
+         GO TO 10
+      END IF
+*+    END WHILE
+*
+      RETURN
+*
+*     End of SLAMC4
+*
+      END
diff --git a/libcruft/lapack/slamc5.f b/libcruft/lapack/slamc5.f
new file mode 100644
index 0000000..58f18f7
--- /dev/null
+++ b/libcruft/lapack/slamc5.f
@@ -0,0 +1,158 @@
+      SUBROUTINE SLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            BETA, EMAX, EMIN, P
+      REAL               RMAX
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMC5 attempts to compute RMAX, the largest machine floating-point
+*  number, without overflow.  It assumes that EMAX + abs(EMIN) sum
+*  approximately to a power of 2.  It will fail on machines where this
+*  assumption does not hold, for example, the Cyber 205 (EMIN = -28625,
+*  EMAX = 28718).  It will also fail if the value supplied for EMIN is
+*  too large (i.e. too close to zero), probably with overflow.
+*
+*  Arguments
+*  =========
+*
+*  BETA    (input) INTEGER
+*          The base of floating-point arithmetic.
+*
+*  P       (input) INTEGER
+*          The number of base BETA digits in the mantissa of a
+*          floating-point value.
+*
+*  EMIN    (input) INTEGER
+*          The minimum exponent before (gradual) underflow.
+*
+*  IEEE    (input) LOGICAL
+*          A logical flag specifying whether or not the arithmetic
+*          system is thought to comply with the IEEE standard.
+*
+*  EMAX    (output) INTEGER
+*          The largest exponent before overflow
+*
+*  RMAX    (output) REAL
+*          The largest machine floating-point number.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP
+      REAL               OLDY, RECBAS, Y, Z
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3
+      EXTERNAL           SLAMC3
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MOD
+*     ..
+*     .. Executable Statements ..
+*
+*     First compute LEXP and UEXP, two powers of 2 that bound
+*     abs(EMIN). We then assume that EMAX + abs(EMIN) will sum
+*     approximately to the bound that is closest to abs(EMIN).
+*     (EMAX is the exponent of the required number RMAX).
+*
+      LEXP = 1
+      EXBITS = 1
+   10 CONTINUE
+      TRY = LEXP*2
+      IF( TRY.LE.( -EMIN ) ) THEN
+         LEXP = TRY
+         EXBITS = EXBITS + 1
+         GO TO 10
+      END IF
+      IF( LEXP.EQ.-EMIN ) THEN
+         UEXP = LEXP
+      ELSE
+         UEXP = TRY
+         EXBITS = EXBITS + 1
+      END IF
+*
+*     Now -LEXP is less than or equal to EMIN, and -UEXP is greater
+*     than or equal to EMIN. EXBITS is the number of bits needed to
+*     store the exponent.
+*
+      IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN
+         EXPSUM = 2*LEXP
+      ELSE
+         EXPSUM = 2*UEXP
+      END IF
+*
+*     EXPSUM is the exponent range, approximately equal to
+*     EMAX - EMIN + 1 .
+*
+      EMAX = EXPSUM + EMIN - 1
+      NBITS = 1 + EXBITS + P
+*
+*     NBITS is the total number of bits needed to store a
+*     floating-point number.
+*
+      IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN
+*
+*        Either there are an odd number of bits used to store a
+*        floating-point number, which is unlikely, or some bits are
+*        not used in the representation of numbers, which is possible,
+*        (e.g. Cray machines) or the mantissa has an implicit bit,
+*        (e.g. IEEE machines, Dec Vax machines), which is perhaps the
+*        most likely. We have to assume the last alternative.
+*        If this is true, then we need to reduce EMAX by one because
+*        there must be some way of representing zero in an implicit-bit
+*        system. On machines like Cray, we are reducing EMAX by one
+*        unnecessarily.
+*
+         EMAX = EMAX - 1
+      END IF
+*
+      IF( IEEE ) THEN
+*
+*        Assume we are on an IEEE machine which reserves one exponent
+*        for infinity and NaN.
+*
+         EMAX = EMAX - 1
+      END IF
+*
+*     Now create RMAX, the largest machine number, which should
+*     be equal to (1.0 - BETA**(-P)) * BETA**EMAX .
+*
+*     First compute 1.0 - BETA**(-P), being careful that the
+*     result is less than 1.0 .
+*
+      RECBAS = ONE / BETA
+      Z = BETA - ONE
+      Y = ZERO
+      DO 20 I = 1, P
+         Z = Z*RECBAS
+         IF( Y.LT.ONE )
+     $      OLDY = Y
+         Y = SLAMC3( Y, Z )
+   20 CONTINUE
+      IF( Y.GE.ONE )
+     $   Y = OLDY
+*
+*     Now multiply by BETA**EMAX to get RMAX.
+*
+      DO 30 I = 1, EMAX
+         Y = SLAMC3( Y*BETA, ZERO )
+   30 CONTINUE
+*
+      RMAX = Y
+      RETURN
+*
+*     End of SLAMC5
+*
+      END
diff --git a/libcruft/lapack/slamch.f b/libcruft/lapack/slamch.f
new file mode 100644
index 0000000..077ec20
--- /dev/null
+++ b/libcruft/lapack/slamch.f
@@ -0,0 +1,126 @@
+      REAL             FUNCTION SLAMCH( CMACH )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          CMACH
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMCH determines single precision machine parameters.
+*
+*  Arguments
+*  =========
+*
+*  CMACH   (input) CHARACTER*1
+*          Specifies the value to be returned by SLAMCH:
+*          = 'E' or 'e',   SLAMCH := eps
+*          = 'S' or 's ,   SLAMCH := sfmin
+*          = 'B' or 'b',   SLAMCH := base
+*          = 'P' or 'p',   SLAMCH := eps*base
+*          = 'N' or 'n',   SLAMCH := t
+*          = 'R' or 'r',   SLAMCH := rnd
+*          = 'M' or 'm',   SLAMCH := emin
+*          = 'U' or 'u',   SLAMCH := rmin
+*          = 'L' or 'l',   SLAMCH := emax
+*          = 'O' or 'o',   SLAMCH := rmax
+*
+*          where
+*
+*          eps   = relative machine precision
+*          sfmin = safe minimum, such that 1/sfmin does not overflow
+*          base  = base of the machine
+*          prec  = eps*base
+*          t     = number of (base) digits in the mantissa
+*          rnd   = 1.0 when rounding occurs in addition, 0.0 otherwise
+*          emin  = minimum exponent before (gradual) underflow
+*          rmin  = underflow threshold - base**(emin-1)
+*          emax  = largest exponent before overflow
+*          rmax  = overflow threshold  - (base**emax)*(1-eps)
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            FIRST, LRND
+      INTEGER            BETA, IMAX, IMIN, IT
+      REAL               BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN,
+     $                   RND, SFMIN, SMALL, T
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAMC2
+*     ..
+*     .. Save statement ..
+      SAVE               FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN,
+     $                   EMAX, RMAX, PREC
+*     ..
+*     .. Data statements ..
+      DATA               FIRST / .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+      IF( FIRST ) THEN
+         CALL SLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX )
+         BASE = BETA
+         T = IT
+         IF( LRND ) THEN
+            RND = ONE
+            EPS = ( BASE**( 1-IT ) ) / 2
+         ELSE
+            RND = ZERO
+            EPS = BASE**( 1-IT )
+         END IF
+         PREC = EPS*BASE
+         EMIN = IMIN
+         EMAX = IMAX
+         SFMIN = RMIN
+         SMALL = ONE / RMAX
+         IF( SMALL.GE.SFMIN ) THEN
+*
+*           Use SMALL plus a bit, to avoid the possibility of rounding
+*           causing overflow when computing  1/sfmin.
+*
+            SFMIN = SMALL*( ONE+EPS )
+         END IF
+      END IF
+*
+      IF( LSAME( CMACH, 'E' ) ) THEN
+         RMACH = EPS
+      ELSE IF( LSAME( CMACH, 'S' ) ) THEN
+         RMACH = SFMIN
+      ELSE IF( LSAME( CMACH, 'B' ) ) THEN
+         RMACH = BASE
+      ELSE IF( LSAME( CMACH, 'P' ) ) THEN
+         RMACH = PREC
+      ELSE IF( LSAME( CMACH, 'N' ) ) THEN
+         RMACH = T
+      ELSE IF( LSAME( CMACH, 'R' ) ) THEN
+         RMACH = RND
+      ELSE IF( LSAME( CMACH, 'M' ) ) THEN
+         RMACH = EMIN
+      ELSE IF( LSAME( CMACH, 'U' ) ) THEN
+         RMACH = RMIN
+      ELSE IF( LSAME( CMACH, 'L' ) ) THEN
+         RMACH = EMAX
+      ELSE IF( LSAME( CMACH, 'O' ) ) THEN
+         RMACH = RMAX
+      END IF
+*
+      SLAMCH = RMACH
+      FIRST  = .FALSE.
+      RETURN
+*
+*     End of SLAMCH
+*
+      END
diff --git a/libcruft/lapack/slamrg.f b/libcruft/lapack/slamrg.f
new file mode 100644
index 0000000..a2b554a
--- /dev/null
+++ b/libcruft/lapack/slamrg.f
@@ -0,0 +1,103 @@
+      SUBROUTINE SLAMRG( N1, N2, A, STRD1, STRD2, INDEX )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            N1, N2, STRD1, STRD2
+*     ..
+*     .. Array Arguments ..
+      INTEGER            INDEX( * )
+      REAL               A( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAMRG will create a permutation list which will merge the elements
+*  of A (which is composed of two independently sorted sets) into a
+*  single set which is sorted in ascending order.
+*
+*  Arguments
+*  =========
+*
+*  N1     (input) INTEGER
+*  N2     (input) INTEGER
+*         These arguements contain the respective lengths of the two
+*         sorted lists to be merged.
+*
+*  A      (input) REAL array, dimension (N1+N2)
+*         The first N1 elements of A contain a list of numbers which
+*         are sorted in either ascending or descending order.  Likewise
+*         for the final N2 elements.
+*
+*  STRD1  (input) INTEGER
+*  STRD2  (input) INTEGER
+*         These are the strides to be taken through the array A.
+*         Allowable strides are 1 and -1.  They indicate whether a
+*         subset of A is sorted in ascending (STRDx = 1) or descending
+*         (STRDx = -1) order.
+*
+*  INDEX  (output) INTEGER array, dimension (N1+N2)
+*         On exit this array will contain a permutation such that
+*         if B( I ) = A( INDEX( I ) ) for I=1,N1+N2, then B will be
+*         sorted in ascending order.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IND1, IND2, N1SV, N2SV
+*     ..
+*     .. Executable Statements ..
+*
+      N1SV = N1
+      N2SV = N2
+      IF( STRD1.GT.0 ) THEN
+         IND1 = 1
+      ELSE
+         IND1 = N1
+      END IF
+      IF( STRD2.GT.0 ) THEN
+         IND2 = 1 + N1
+      ELSE
+         IND2 = N1 + N2
+      END IF
+      I = 1
+*     while ( (N1SV > 0) & (N2SV > 0) )
+   10 CONTINUE
+      IF( N1SV.GT.0 .AND. N2SV.GT.0 ) THEN
+         IF( A( IND1 ).LE.A( IND2 ) ) THEN
+            INDEX( I ) = IND1
+            I = I + 1
+            IND1 = IND1 + STRD1
+            N1SV = N1SV - 1
+         ELSE
+            INDEX( I ) = IND2
+            I = I + 1
+            IND2 = IND2 + STRD2
+            N2SV = N2SV - 1
+         END IF
+         GO TO 10
+      END IF
+*     end while
+      IF( N1SV.EQ.0 ) THEN
+         DO 20 N1SV = 1, N2SV
+            INDEX( I ) = IND2
+            I = I + 1
+            IND2 = IND2 + STRD2
+   20    CONTINUE
+      ELSE
+*     N2SV .EQ. 0
+         DO 30 N2SV = 1, N1SV
+            INDEX( I ) = IND1
+            I = I + 1
+            IND1 = IND1 + STRD1
+   30    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SLAMRG
+*
+      END
diff --git a/libcruft/lapack/slange.f b/libcruft/lapack/slange.f
new file mode 100644
index 0000000..c7c122e
--- /dev/null
+++ b/libcruft/lapack/slange.f
@@ -0,0 +1,144 @@
+      REAL             FUNCTION SLANGE( NORM, M, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLANGE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  real matrix A.
+*
+*  Description
+*  ===========
+*
+*  SLANGE returns the value
+*
+*     SLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in SLANGE as described
+*          above.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.  When M = 0,
+*          SLANGE is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.  When N = 0,
+*          SLANGE is set to zero.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The m by n matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, M
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, M
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, M
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, M
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL SLASSQ( M, A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      SLANGE = VALUE
+      RETURN
+*
+*     End of SLANGE
+*
+      END
diff --git a/libcruft/lapack/slanhs.f b/libcruft/lapack/slanhs.f
new file mode 100644
index 0000000..6c3e370
--- /dev/null
+++ b/libcruft/lapack/slanhs.f
@@ -0,0 +1,141 @@
+      REAL             FUNCTION SLANHS( NORM, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLANHS  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  Hessenberg matrix A.
+*
+*  Description
+*  ===========
+*
+*  SLANHS returns the value
+*
+*     SLANHS = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in SLANHS as described
+*          above.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, SLANHS is
+*          set to zero.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The n by n upper Hessenberg matrix A; the part of A below the
+*          first sub-diagonal is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( N, J+1 )
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, MIN( N, J+1 )
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, N
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( N, J+1 )
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, N
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL SLASSQ( MIN( N, J+1 ), A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      SLANHS = VALUE
+      RETURN
+*
+*     End of SLANHS
+*
+      END
diff --git a/libcruft/lapack/slanst.f b/libcruft/lapack/slanst.f
new file mode 100644
index 0000000..836752e
--- /dev/null
+++ b/libcruft/lapack/slanst.f
@@ -0,0 +1,124 @@
+      REAL             FUNCTION SLANST( NORM, N, D, E )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLANST  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  real symmetric tridiagonal matrix A.
+*
+*  Description
+*  ===========
+*
+*  SLANST returns the value
+*
+*     SLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in SLANST as described
+*          above.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, SLANST is
+*          set to zero.
+*
+*  D       (input) REAL array, dimension (N)
+*          The diagonal elements of A.
+*
+*  E       (input) REAL array, dimension (N-1)
+*          The (n-1) sub-diagonal or super-diagonal elements of A.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      REAL               ANORM, SCALE, SUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 ) THEN
+         ANORM = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         ANORM = ABS( D( N ) )
+         DO 10 I = 1, N - 1
+            ANORM = MAX( ANORM, ABS( D( I ) ) )
+            ANORM = MAX( ANORM, ABS( E( I ) ) )
+   10    CONTINUE
+      ELSE IF( LSAME( NORM, 'O' ) .OR. NORM.EQ.'1' .OR.
+     $         LSAME( NORM, 'I' ) ) THEN
+*
+*        Find norm1(A).
+*
+         IF( N.EQ.1 ) THEN
+            ANORM = ABS( D( 1 ) )
+         ELSE
+            ANORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),
+     $              ABS( E( N-1 ) )+ABS( D( N ) ) )
+            DO 20 I = 2, N - 1
+               ANORM = MAX( ANORM, ABS( D( I ) )+ABS( E( I ) )+
+     $                 ABS( E( I-1 ) ) )
+   20       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         IF( N.GT.1 ) THEN
+            CALL SLASSQ( N-1, E, 1, SCALE, SUM )
+            SUM = 2*SUM
+         END IF
+         CALL SLASSQ( N, D, 1, SCALE, SUM )
+         ANORM = SCALE*SQRT( SUM )
+      END IF
+*
+      SLANST = ANORM
+      RETURN
+*
+*     End of SLANST
+*
+      END
diff --git a/libcruft/lapack/slansy.f b/libcruft/lapack/slansy.f
new file mode 100644
index 0000000..ae26030
--- /dev/null
+++ b/libcruft/lapack/slansy.f
@@ -0,0 +1,173 @@
+      REAL             FUNCTION SLANSY( NORM, UPLO, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM, UPLO
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLANSY  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  real symmetric matrix A.
+*
+*  Description
+*  ===========
+*
+*  SLANSY returns the value
+*
+*     SLANSY = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in SLANSY as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is to be referenced.
+*          = 'U':  Upper triangular part of A is referenced
+*          = 'L':  Lower triangular part of A is referenced
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, SLANSY is
+*          set to zero.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The symmetric matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of A contains the upper triangular part
+*          of the matrix A, and the strictly lower triangular part of A
+*          is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of A contains the lower triangular part of
+*          the matrix A, and the strictly upper triangular part of A is
+*          not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,
+*          WORK is not referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               ABSA, SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 20 J = 1, N
+               DO 10 I = 1, J
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10          CONTINUE
+   20       CONTINUE
+         ELSE
+            DO 40 J = 1, N
+               DO 30 I = J, N
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30          CONTINUE
+   40       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.
+     $         ( NORM.EQ.'1' ) ) THEN
+*
+*        Find normI(A) ( = norm1(A), since A is symmetric).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 60 J = 1, N
+               SUM = ZERO
+               DO 50 I = 1, J - 1
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   50          CONTINUE
+               WORK( J ) = SUM + ABS( A( J, J ) )
+   60       CONTINUE
+            DO 70 I = 1, N
+               VALUE = MAX( VALUE, WORK( I ) )
+   70       CONTINUE
+         ELSE
+            DO 80 I = 1, N
+               WORK( I ) = ZERO
+   80       CONTINUE
+            DO 100 J = 1, N
+               SUM = WORK( J ) + ABS( A( J, J ) )
+               DO 90 I = J + 1, N
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   90          CONTINUE
+               VALUE = MAX( VALUE, SUM )
+  100       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 2, N
+               CALL SLASSQ( J-1, A( 1, J ), 1, SCALE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 120 J = 1, N - 1
+               CALL SLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM )
+  120       CONTINUE
+         END IF
+         SUM = 2*SUM
+         CALL SLASSQ( N, A, LDA+1, SCALE, SUM )
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      SLANSY = VALUE
+      RETURN
+*
+*     End of SLANSY
+*
+      END
diff --git a/libcruft/lapack/slantr.f b/libcruft/lapack/slantr.f
new file mode 100644
index 0000000..8573310
--- /dev/null
+++ b/libcruft/lapack/slantr.f
@@ -0,0 +1,276 @@
+      REAL             FUNCTION SLANTR( NORM, UPLO, DIAG, M, N, A, LDA,
+     $                 WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLANTR  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  trapezoidal or triangular matrix A.
+*
+*  Description
+*  ===========
+*
+*  SLANTR returns the value
+*
+*     SLANTR = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in SLANTR as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower trapezoidal.
+*          = 'U':  Upper trapezoidal
+*          = 'L':  Lower trapezoidal
+*          Note that A is triangular instead of trapezoidal if M = N.
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A has unit diagonal.
+*          = 'N':  Non-unit diagonal
+*          = 'U':  Unit diagonal
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0, and if
+*          UPLO = 'U', M <= N.  When M = 0, SLANTR is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0, and if
+*          UPLO = 'L', N <= M.  When N = 0, SLANTR is set to zero.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The trapezoidal matrix A (A is triangular if M = N).
+*          If UPLO = 'U', the leading m by n upper trapezoidal part of
+*          the array A contains the upper trapezoidal matrix, and the
+*          strictly lower triangular part of A is not referenced.
+*          If UPLO = 'L', the leading m by n lower trapezoidal part of
+*          the array A contains the lower trapezoidal matrix, and the
+*          strictly upper triangular part of A is not referenced.  Note
+*          that when DIAG = 'U', the diagonal elements of A are not
+*          referenced and are assumed to be one.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) REAL array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UDIAG
+      INTEGER            I, J
+      REAL               SCALE, SUM, VALUE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASSQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         IF( LSAME( DIAG, 'U' ) ) THEN
+            VALUE = ONE
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 20 J = 1, N
+                  DO 10 I = 1, MIN( M, J-1 )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40 J = 1, N
+                  DO 30 I = J + 1, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30             CONTINUE
+   40          CONTINUE
+            END IF
+         ELSE
+            VALUE = ZERO
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 60 J = 1, N
+                  DO 50 I = 1, MIN( M, J )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80 J = 1, N
+                  DO 70 I = J, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         UDIAG = LSAME( DIAG, 'U' )
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 1, N
+               IF( ( UDIAG ) .AND. ( J.LE.M ) ) THEN
+                  SUM = ONE
+                  DO 90 I = 1, J - 1
+                     SUM = SUM + ABS( A( I, J ) )
+   90             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 100 I = 1, MIN( M, J )
+                     SUM = SUM + ABS( A( I, J ) )
+  100             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 140 J = 1, N
+               IF( UDIAG ) THEN
+                  SUM = ONE
+                  DO 120 I = J + 1, M
+                     SUM = SUM + ABS( A( I, J ) )
+  120             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 130 I = J, M
+                     SUM = SUM + ABS( A( I, J ) )
+  130             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  140       CONTINUE
+         END IF
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 150 I = 1, M
+                  WORK( I ) = ONE
+  150          CONTINUE
+               DO 170 J = 1, N
+                  DO 160 I = 1, MIN( M, J-1 )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  160             CONTINUE
+  170          CONTINUE
+            ELSE
+               DO 180 I = 1, M
+                  WORK( I ) = ZERO
+  180          CONTINUE
+               DO 200 J = 1, N
+                  DO 190 I = 1, MIN( M, J )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  190             CONTINUE
+  200          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 210 I = 1, N
+                  WORK( I ) = ONE
+  210          CONTINUE
+               DO 220 I = N + 1, M
+                  WORK( I ) = ZERO
+  220          CONTINUE
+               DO 240 J = 1, N
+                  DO 230 I = J + 1, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  230             CONTINUE
+  240          CONTINUE
+            ELSE
+               DO 250 I = 1, M
+                  WORK( I ) = ZERO
+  250          CONTINUE
+               DO 270 J = 1, N
+                  DO 260 I = J, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  260             CONTINUE
+  270          CONTINUE
+            END IF
+         END IF
+         VALUE = ZERO
+         DO 280 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+  280    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 290 J = 2, N
+                  CALL SLASSQ( MIN( M, J-1 ), A( 1, J ), 1, SCALE, SUM )
+  290          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 300 J = 1, N
+                  CALL SLASSQ( MIN( M, J ), A( 1, J ), 1, SCALE, SUM )
+  300          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 310 J = 1, N
+                  CALL SLASSQ( M-J, A( MIN( M, J+1 ), J ), 1, SCALE,
+     $                         SUM )
+  310          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 320 J = 1, N
+                  CALL SLASSQ( M-J+1, A( J, J ), 1, SCALE, SUM )
+  320          CONTINUE
+            END IF
+         END IF
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      SLANTR = VALUE
+      RETURN
+*
+*     End of SLANTR
+*
+      END
diff --git a/libcruft/lapack/slanv2.f b/libcruft/lapack/slanv2.f
new file mode 100644
index 0000000..c301a2c
--- /dev/null
+++ b/libcruft/lapack/slanv2.f
@@ -0,0 +1,205 @@
+      SUBROUTINE SLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               A, B, C, CS, D, RT1I, RT1R, RT2I, RT2R, SN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric
+*  matrix in standard form:
+*
+*       [ A  B ] = [ CS -SN ] [ AA  BB ] [ CS  SN ]
+*       [ C  D ]   [ SN  CS ] [ CC  DD ] [-SN  CS ]
+*
+*  where either
+*  1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or
+*  2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex
+*  conjugate eigenvalues.
+*
+*  Arguments
+*  =========
+*
+*  A       (input/output) REAL            
+*  B       (input/output) REAL            
+*  C       (input/output) REAL            
+*  D       (input/output) REAL            
+*          On entry, the elements of the input matrix.
+*          On exit, they are overwritten by the elements of the
+*          standardised Schur form.
+*
+*  RT1R    (output) REAL 
+*  RT1I    (output) REAL            
+*  RT2R    (output) REAL            
+*  RT2I    (output) REAL            
+*          The real and imaginary parts of the eigenvalues. If the
+*          eigenvalues are a complex conjugate pair, RT1I > 0.
+*
+*  CS      (output) REAL            
+*  SN      (output) REAL            
+*          Parameters of the rotation matrix.
+*
+*  Further Details
+*  ===============
+*
+*  Modified by V. Sima, Research Institute for Informatics, Bucharest,
+*  Romania, to reduce the risk of cancellation errors,
+*  when computing real eigenvalues, and to ensure, if possible, that
+*  abs(RT1R) >= abs(RT2R).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
+      REAL               MULTPL
+      PARAMETER          ( MULTPL = 4.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AA, BB, BCMAX, BCMIS, CC, CS1, DD, EPS, P, SAB,
+     $                   SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLAPY2
+      EXTERNAL           SLAMCH, SLAPY2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      EPS = SLAMCH( 'P' )
+      IF( C.EQ.ZERO ) THEN
+         CS = ONE
+         SN = ZERO
+         GO TO 10
+*
+      ELSE IF( B.EQ.ZERO ) THEN
+*
+*        Swap rows and columns
+*
+         CS = ZERO
+         SN = ONE
+         TEMP = D
+         D = A
+         A = TEMP
+         B = -C
+         C = ZERO
+         GO TO 10
+      ELSE IF( (A-D).EQ.ZERO .AND. SIGN( ONE, B ).NE.
+     $   SIGN( ONE, C ) ) THEN
+         CS = ONE
+         SN = ZERO
+         GO TO 10
+      ELSE
+*
+         TEMP = A - D
+         P = HALF*TEMP
+         BCMAX = MAX( ABS( B ), ABS( C ) )
+         BCMIS = MIN( ABS( B ), ABS( C ) )*SIGN( ONE, B )*SIGN( ONE, C )
+         SCALE = MAX( ABS( P ), BCMAX )
+         Z = ( P / SCALE )*P + ( BCMAX / SCALE )*BCMIS
+*
+*        If Z is of the order of the machine accuracy, postpone the
+*        decision on the nature of eigenvalues
+*
+         IF( Z.GE.MULTPL*EPS ) THEN
+*
+*           Real eigenvalues. Compute A and D.
+*
+            Z = P + SIGN( SQRT( SCALE )*SQRT( Z ), P )
+            A = D + Z
+            D = D - ( BCMAX / Z )*BCMIS
+*
+*           Compute B and the rotation matrix
+*
+            TAU = SLAPY2( C, Z )
+            CS = Z / TAU
+            SN = C / TAU
+            B = B - C
+            C = ZERO
+         ELSE
+*
+*           Complex eigenvalues, or real (almost) equal eigenvalues.
+*           Make diagonal elements equal.
+*
+            SIGMA = B + C
+            TAU = SLAPY2( SIGMA, TEMP )
+            CS = SQRT( HALF*( ONE+ABS( SIGMA ) / TAU ) )
+            SN = -( P / ( TAU*CS ) )*SIGN( ONE, SIGMA )
+*
+*           Compute [ AA  BB ] = [ A  B ] [ CS -SN ]
+*                   [ CC  DD ]   [ C  D ] [ SN  CS ]
+*
+            AA = A*CS + B*SN
+            BB = -A*SN + B*CS
+            CC = C*CS + D*SN
+            DD = -C*SN + D*CS
+*
+*           Compute [ A  B ] = [ CS  SN ] [ AA  BB ]
+*                   [ C  D ]   [-SN  CS ] [ CC  DD ]
+*
+            A = AA*CS + CC*SN
+            B = BB*CS + DD*SN
+            C = -AA*SN + CC*CS
+            D = -BB*SN + DD*CS
+*
+            TEMP = HALF*( A+D )
+            A = TEMP
+            D = TEMP
+*
+            IF( C.NE.ZERO ) THEN
+               IF( B.NE.ZERO ) THEN
+                  IF( SIGN( ONE, B ).EQ.SIGN( ONE, C ) ) THEN
+*
+*                    Real eigenvalues: reduce to upper triangular form
+*
+                     SAB = SQRT( ABS( B ) )
+                     SAC = SQRT( ABS( C ) )
+                     P = SIGN( SAB*SAC, C )
+                     TAU = ONE / SQRT( ABS( B+C ) )
+                     A = TEMP + P
+                     D = TEMP - P
+                     B = B - C
+                     C = ZERO
+                     CS1 = SAB*TAU
+                     SN1 = SAC*TAU
+                     TEMP = CS*CS1 - SN*SN1
+                     SN = CS*SN1 + SN*CS1
+                     CS = TEMP
+                  END IF
+               ELSE
+                  B = -C
+                  C = ZERO
+                  TEMP = CS
+                  CS = -SN
+                  SN = TEMP
+               END IF
+            END IF
+         END IF
+*
+      END IF
+*
+   10 CONTINUE
+*
+*     Store eigenvalues in (RT1R,RT1I) and (RT2R,RT2I).
+*
+      RT1R = A
+      RT2R = D
+      IF( C.EQ.ZERO ) THEN
+         RT1I = ZERO
+         RT2I = ZERO
+      ELSE
+         RT1I = SQRT( ABS( B ) )*SQRT( ABS( C ) )
+         RT2I = -RT1I
+      END IF
+      RETURN
+*
+*     End of SLANV2
+*
+      END
diff --git a/libcruft/lapack/slapy2.f b/libcruft/lapack/slapy2.f
new file mode 100644
index 0000000..0eac04f
--- /dev/null
+++ b/libcruft/lapack/slapy2.f
@@ -0,0 +1,53 @@
+      REAL             FUNCTION SLAPY2( X, Y )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               X, Y
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary
+*  overflow.
+*
+*  Arguments
+*  =========
+*
+*  X       (input) REAL
+*  Y       (input) REAL
+*          X and Y specify the values x and y.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               W, XABS, YABS, Z
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      XABS = ABS( X )
+      YABS = ABS( Y )
+      W = MAX( XABS, YABS )
+      Z = MIN( XABS, YABS )
+      IF( Z.EQ.ZERO ) THEN
+         SLAPY2 = W
+      ELSE
+         SLAPY2 = W*SQRT( ONE+( Z / W )**2 )
+      END IF
+      RETURN
+*
+*     End of SLAPY2
+*
+      END
diff --git a/libcruft/lapack/slapy3.f b/libcruft/lapack/slapy3.f
new file mode 100644
index 0000000..f5db385
--- /dev/null
+++ b/libcruft/lapack/slapy3.f
@@ -0,0 +1,56 @@
+      REAL             FUNCTION SLAPY3( X, Y, Z )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               X, Y, Z
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause
+*  unnecessary overflow.
+*
+*  Arguments
+*  =========
+*
+*  X       (input) REAL
+*  Y       (input) REAL
+*  Z       (input) REAL
+*          X, Y and Z specify the values x, y and z.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               W, XABS, YABS, ZABS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      XABS = ABS( X )
+      YABS = ABS( Y )
+      ZABS = ABS( Z )
+      W = MAX( XABS, YABS, ZABS )
+      IF( W.EQ.ZERO ) THEN
+*     W can be zero for max(0,nan,0)
+*     adding all three entries together will make sure
+*     NaN will not disappear.
+         SLAPY3 =  XABS + YABS + ZABS
+      ELSE
+         SLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2+
+     $            ( ZABS / W )**2 )
+      END IF
+      RETURN
+*
+*     End of SLAPY3
+*
+      END
diff --git a/libcruft/lapack/slaqp2.f b/libcruft/lapack/slaqp2.f
new file mode 100644
index 0000000..ce47cb6
--- /dev/null
+++ b/libcruft/lapack/slaqp2.f
@@ -0,0 +1,175 @@
+      SUBROUTINE SLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2,
+     $                   WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, M, N, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               A( LDA, * ), TAU( * ), VN1( * ), VN2( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAQP2 computes a QR factorization with column pivoting of
+*  the block A(OFFSET+1:M,1:N).
+*  The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of the matrix A that must be pivoted
+*          but no factorized. OFFSET >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of block A(OFFSET+1:M,1:N) is 
+*          the triangular factor obtained; the elements in block 
+*          A(OFFSET+1:M,1:N) below the diagonal, together with the 
+*          array TAU, represent the orthogonal matrix Q as a product of
+*          elementary reflectors. Block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) REAL array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) REAL array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) REAL array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MN, OFFPI, PVT
+      REAL               AII, TEMP, TEMP2, TOL3Z
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SLARFG, SSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SLAMCH, SNRM2
+      EXTERNAL           ISAMAX, SLAMCH, SNRM2
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M-OFFSET, N )
+      TOL3Z = SQRT(SLAMCH('Epsilon'))
+*
+*     Compute factorization.
+*
+      DO 20 I = 1, MN
+*
+         OFFPI = OFFSET + I
+*
+*        Determine ith pivot column and swap if necessary.
+*
+         PVT = ( I-1 ) + ISAMAX( N-I+1, VN1( I ), 1 )
+*
+         IF( PVT.NE.I ) THEN
+            CALL SSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( I )
+            JPVT( I ) = ITEMP
+            VN1( PVT ) = VN1( I )
+            VN2( PVT ) = VN2( I )
+         END IF
+*
+*        Generate elementary reflector H(i).
+*
+         IF( OFFPI.LT.M ) THEN
+            CALL SLARFG( M-OFFPI+1, A( OFFPI, I ), A( OFFPI+1, I ), 1,
+     $                   TAU( I ) )
+         ELSE
+            CALL SLARFG( 1, A( M, I ), A( M, I ), 1, TAU( I ) )
+         END IF
+*
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i)' to A(offset+i:m,i+1:n) from the left.
+*
+            AII = A( OFFPI, I )
+            A( OFFPI, I ) = ONE
+            CALL SLARF( 'Left', M-OFFPI+1, N-I, A( OFFPI, I ), 1,
+     $                  TAU( I ), A( OFFPI, I+1 ), LDA, WORK( 1 ) )
+            A( OFFPI, I ) = AII
+         END IF
+*
+*        Update partial column norms.
+*
+         DO 10 J = I + 1, N
+            IF( VN1( J ).NE.ZERO ) THEN
+*
+*              NOTE: The following 4 lines follow from the analysis in
+*              Lapack Working Note 176.
+*
+               TEMP = ONE - ( ABS( A( OFFPI, J ) ) / VN1( J ) )**2
+               TEMP = MAX( TEMP, ZERO )
+               TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+               IF( TEMP2 .LE. TOL3Z ) THEN
+                  IF( OFFPI.LT.M ) THEN
+                     VN1( J ) = SNRM2( M-OFFPI, A( OFFPI+1, J ), 1 )
+                     VN2( J ) = VN1( J )
+                  ELSE
+                     VN1( J ) = ZERO
+                     VN2( J ) = ZERO
+                  END IF
+               ELSE
+                  VN1( J ) = VN1( J )*SQRT( TEMP )
+               END IF
+            END IF
+   10    CONTINUE
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of SLAQP2
+*
+      END
diff --git a/libcruft/lapack/slaqps.f b/libcruft/lapack/slaqps.f
new file mode 100644
index 0000000..7085e21
--- /dev/null
+++ b/libcruft/lapack/slaqps.f
@@ -0,0 +1,259 @@
+      SUBROUTINE SLAQPS( M, N, OFFSET, NB, KB, A, LDA, JPVT, TAU, VN1,
+     $                   VN2, AUXV, F, LDF )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KB, LDA, LDF, M, N, NB, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      REAL               A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * ),
+     $                   VN1( * ), VN2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAQPS computes a step of QR factorization with column pivoting
+*  of a real M-by-N matrix A by using Blas-3.  It tries to factorize
+*  NB columns from A starting from the row OFFSET+1, and updates all
+*  of the matrix with Blas-3 xGEMM.
+*
+*  In some cases, due to catastrophic cancellations, it cannot
+*  factorize NB columns.  Hence, the actual number of factorized
+*  columns is returned in KB.
+*
+*  Block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of A that have been factorized in
+*          previous steps.
+*
+*  NB      (input) INTEGER
+*          The number of columns to factorize.
+*
+*  KB      (output) INTEGER
+*          The number of columns actually factorized.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, block A(OFFSET+1:M,1:KB) is the triangular
+*          factor obtained and block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*          The rest of the matrix, block A(OFFSET+1:M,KB+1:N) has
+*          been updated.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          JPVT(I) = K <==> Column K of the full matrix A has been
+*          permuted into position I in AP.
+*
+*  TAU     (output) REAL array, dimension (KB)
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) REAL array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) REAL array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  AUXV    (input/output) REAL array, dimension (NB)
+*          Auxiliar vector.
+*
+*  F       (input/output) REAL array, dimension (LDF,NB)
+*          Matrix F' = L*Y'*A.
+*
+*  LDF     (input) INTEGER
+*          The leading dimension of the array F. LDF >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            ITEMP, J, K, LASTRK, LSTICC, PVT, RK
+      REAL               AKK, TEMP, TEMP2, TOL3Z
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SGEMV, SLARFG, SSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, NINT, REAL, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SLAMCH, SNRM2
+      EXTERNAL           ISAMAX, SLAMCH, SNRM2
+*     ..
+*     .. Executable Statements ..
+*
+      LASTRK = MIN( M, N+OFFSET )
+      LSTICC = 0
+      K = 0
+      TOL3Z = SQRT(SLAMCH('Epsilon'))
+*
+*     Beginning of while loop.
+*
+   10 CONTINUE
+      IF( ( K.LT.NB ) .AND. ( LSTICC.EQ.0 ) ) THEN
+         K = K + 1
+         RK = OFFSET + K
+*
+*        Determine ith pivot column and swap if necessary
+*
+         PVT = ( K-1 ) + ISAMAX( N-K+1, VN1( K ), 1 )
+         IF( PVT.NE.K ) THEN
+            CALL SSWAP( M, A( 1, PVT ), 1, A( 1, K ), 1 )
+            CALL SSWAP( K-1, F( PVT, 1 ), LDF, F( K, 1 ), LDF )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( K )
+            JPVT( K ) = ITEMP
+            VN1( PVT ) = VN1( K )
+            VN2( PVT ) = VN2( K )
+         END IF
+*
+*        Apply previous Householder reflectors to column K:
+*        A(RK:M,K) := A(RK:M,K) - A(RK:M,1:K-1)*F(K,1:K-1)'.
+*
+         IF( K.GT.1 ) THEN
+            CALL SGEMV( 'No transpose', M-RK+1, K-1, -ONE, A( RK, 1 ),
+     $                  LDA, F( K, 1 ), LDF, ONE, A( RK, K ), 1 )
+         END IF
+*
+*        Generate elementary reflector H(k).
+*
+         IF( RK.LT.M ) THEN
+            CALL SLARFG( M-RK+1, A( RK, K ), A( RK+1, K ), 1, TAU( K ) )
+         ELSE
+            CALL SLARFG( 1, A( RK, K ), A( RK, K ), 1, TAU( K ) )
+         END IF
+*
+         AKK = A( RK, K )
+         A( RK, K ) = ONE
+*
+*        Compute Kth column of F:
+*
+*        Compute  F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)'*A(RK:M,K).
+*
+         IF( K.LT.N ) THEN
+            CALL SGEMV( 'Transpose', M-RK+1, N-K, TAU( K ),
+     $                  A( RK, K+1 ), LDA, A( RK, K ), 1, ZERO,
+     $                  F( K+1, K ), 1 )
+         END IF
+*
+*        Padding F(1:K,K) with zeros.
+*
+         DO 20 J = 1, K
+            F( J, K ) = ZERO
+   20    CONTINUE
+*
+*        Incremental updating of F:
+*        F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)'
+*                    *A(RK:M,K).
+*
+         IF( K.GT.1 ) THEN
+            CALL SGEMV( 'Transpose', M-RK+1, K-1, -TAU( K ), A( RK, 1 ),
+     $                  LDA, A( RK, K ), 1, ZERO, AUXV( 1 ), 1 )
+*
+            CALL SGEMV( 'No transpose', N, K-1, ONE, F( 1, 1 ), LDF,
+     $                  AUXV( 1 ), 1, ONE, F( 1, K ), 1 )
+         END IF
+*
+*        Update the current row of A:
+*        A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)'.
+*
+         IF( K.LT.N ) THEN
+            CALL SGEMV( 'No transpose', N-K, K, -ONE, F( K+1, 1 ), LDF,
+     $                  A( RK, 1 ), LDA, ONE, A( RK, K+1 ), LDA )
+         END IF
+*
+*        Update partial column norms.
+*
+         IF( RK.LT.LASTRK ) THEN
+            DO 30 J = K + 1, N
+               IF( VN1( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*
+                  TEMP = ABS( A( RK, J ) ) / VN1( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN
+                     VN2( J ) = REAL( LSTICC )
+                     LSTICC = J
+                  ELSE
+                     VN1( J ) = VN1( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   30       CONTINUE
+         END IF
+*
+         A( RK, K ) = AKK
+*
+*        End of while loop.
+*
+         GO TO 10
+      END IF
+      KB = K
+      RK = OFFSET + KB
+*
+*     Apply the block reflector to the rest of the matrix:
+*     A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) -
+*                         A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)'.
+*
+      IF( KB.LT.MIN( N, M-OFFSET ) ) THEN
+         CALL SGEMM( 'No transpose', 'Transpose', M-RK, N-KB, KB, -ONE,
+     $               A( RK+1, 1 ), LDA, F( KB+1, 1 ), LDF, ONE,
+     $               A( RK+1, KB+1 ), LDA )
+      END IF
+*
+*     Recomputation of difficult columns.
+*
+   40 CONTINUE
+      IF( LSTICC.GT.0 ) THEN
+         ITEMP = NINT( VN2( LSTICC ) )
+         VN1( LSTICC ) = SNRM2( M-RK, A( RK+1, LSTICC ), 1 )
+*
+*        NOTE: The computation of VN1( LSTICC ) relies on the fact that 
+*        SNRM2 does not fail on vectors with norm below the value of
+*        SQRT(DLAMCH('S')) 
+*
+         VN2( LSTICC ) = VN1( LSTICC )
+         LSTICC = ITEMP
+         GO TO 40
+      END IF
+*
+      RETURN
+*
+*     End of SLAQPS
+*
+      END
diff --git a/libcruft/lapack/slaqr0.f b/libcruft/lapack/slaqr0.f
new file mode 100644
index 0000000..c79d2f2
--- /dev/null
+++ b/libcruft/lapack/slaqr0.f
@@ -0,0 +1,640 @@
+      SUBROUTINE SLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), WI( * ), WORK( * ), WR( * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     SLAQR0 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**T, where T is an upper quasi-triangular matrix (the
+*     Schur form), and Z is the orthogonal matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input orthogonal
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to SGEBAL, and then passed to SGEHRD when the
+*           matrix output by SGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) REAL array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H contains
+*           the upper quasi-triangular matrix T from the Schur
+*           decomposition (the Schur form); 2-by-2 diagonal blocks
+*           (corresponding to complex conjugate pairs of eigenvalues)
+*           are returned in standard form, with H(i,i) = H(i+1,i+1)
+*           and H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and WANTT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     WR    (output) REAL array, dimension (IHI)
+*     WI    (output) REAL array, dimension (IHI)
+*           The real and imaginary parts, respectively, of the computed
+*           eigenvalues of H(ILO:IHI,ILO:IHI) are stored WR(ILO:IHI)
+*           and WI(ILO:IHI). If two eigenvalues are computed as a
+*           complex conjugate pair, they are stored in consecutive
+*           elements of WR and WI, say the i-th and (i+1)th, with
+*           WI(i) .GT. 0 and WI(i+1) .LT. 0. If WANTT is .TRUE., then
+*           the eigenvalues are stored in the same order as on the
+*           diagonal of the Schur form returned in H, with
+*           WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal
+*           block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and
+*           WI(i+1) = -WI(i).
+*
+*     ILOZ     (input) INTEGER
+*     IHIZ     (input) INTEGER
+*           Specify the rows of Z to which transformations must be
+*           applied if WANTZ is .TRUE..
+*           1 .LE. ILOZ .LE. ILO; IHI .LE. IHIZ .LE. N.
+*
+*     Z     (input/output) REAL array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) REAL array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then SLAQR0 does a workspace query.
+*           In this case, SLAQR0 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, SLAQR0 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is an orthogonal matrix.  The final
+*                value of H is upper Hessenberg and quasi-triangular
+*                in rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    SLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      REAL               WILK1, WILK2
+      PARAMETER          ( WILK1 = 0.75e0, WILK2 = -0.4375e0 )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AA, BB, CC, CS, DD, SN, SS, SWAP
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      REAL               ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACPY, SLAHQR, SLANV2, SLAQR3, SLAQR4, SLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, MAX, MIN, MOD, REAL
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use SLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL SLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'SLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'SLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to SLAQR3 ====
+*
+         CALL SLAQR3( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, WR, WI, H, LDH, N, H, LDH,
+     $                N, H, LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(SLAQR5, SLAQR3) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = REAL( LWKOPT )
+            RETURN
+         END IF
+*
+*        ==== SLAHQR/SLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'SLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'SLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'SLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 80 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 90
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( ABS( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      ABS( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL SLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, WR, WI, H( KV, 1 ), LDH,
+     $                   NHO, H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                   WORK, LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if SLAQR3
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    SLAQR3 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, MAX( KS+1, KTOP+2 ), -2
+                     SS = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )
+                     AA = WILK1*SS + H( I, I )
+                     BB = SS
+                     CC = WILK2*SS
+                     DD = AA
+                     CALL SLANV2( AA, BB, CC, DD, WR( I-1 ), WI( I-1 ),
+     $                            WR( I ), WI( I ), CS, SN )
+   30             CONTINUE
+                  IF( KS.EQ.KTOP ) THEN
+                     WR( KS+1 ) = H( KS+1, KS+1 )
+                     WI( KS+1 ) = ZERO
+                     WR( KS ) = WR( KS+1 )
+                     WI( KS ) = WI( KS+1 )
+                  END IF
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use SLAQR4 or
+*                 .    SLAHQR on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL SLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     IF( NS.GT.NMIN ) THEN
+                        CALL SLAQR4( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, WR( KS ),
+     $                               WI( KS ), 1, 1, ZDUM, 1, WORK,
+     $                               LWORK, INF )
+                     ELSE
+                        CALL SLAHQR( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, WR( KS ),
+     $                               WI( KS ), 1, 1, ZDUM, 1, INF )
+                     END IF
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        AA = H( KBOT-1, KBOT-1 )
+                        CC = H( KBOT, KBOT-1 )
+                        BB = H( KBOT-1, KBOT )
+                        DD = H( KBOT, KBOT )
+                        CALL SLANV2( AA, BB, CC, DD, WR( KBOT-1 ),
+     $                               WI( KBOT-1 ), WR( KBOT ),
+     $                               WI( KBOT ), CS, SN )
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little)
+*                    .    Bubble sort keeps complex conjugate
+*                    .    pairs together. ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( ABS( WR( I ) )+ABS( WI( I ) ).LT.
+     $                         ABS( WR( I+1 ) )+ABS( WI( I+1 ) ) ) THEN
+                              SORTED = .false.
+*
+                              SWAP = WR( I )
+                              WR( I ) = WR( I+1 )
+                              WR( I+1 ) = SWAP
+*
+                              SWAP = WI( I )
+                              WI( I ) = WI( I+1 )
+                              WI( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+*
+*                 ==== Shuffle shifts into pairs of real shifts
+*                 .    and pairs of complex conjugate shifts
+*                 .    assuming complex conjugate shifts are
+*                 .    already adjacent to one another. (Yes,
+*                 .    they are.)  ====
+*
+                  DO 70 I = KBOT, KS + 2, -2
+                     IF( WI( I ).NE.-WI( I-1 ) ) THEN
+*
+                        SWAP = WR( I )
+                        WR( I ) = WR( I-1 )
+                        WR( I-1 ) = WR( I-2 )
+                        WR( I-2 ) = SWAP
+*
+                        SWAP = WI( I )
+                        WI( I ) = WI( I-1 )
+                        WI( I-1 ) = WI( I-2 )
+                        WI( I-2 ) = SWAP
+                     END IF
+   70             CONTINUE
+               END IF
+*
+*              ==== If there are only two shifts and both are
+*              .    real, then use only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( WI( KBOT ).EQ.ZERO ) THEN
+                     IF( ABS( WR( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                   ABS( WR( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                        WR( KBOT-1 ) = WR( KBOT )
+                     ELSE
+                        WR( KBOT ) = WR( KBOT-1 )
+                     END IF
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL SLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      WR( KS ), WI( KS ), H, LDH, ILOZ, IHIZ, Z,
+     $                      LDZ, WORK, 3, H( KU, 1 ), LDH, NVE,
+     $                      H( KWV, 1 ), LDH, NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   80    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   90    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = REAL( LWKOPT )
+*
+*     ==== End of SLAQR0 ====
+*
+      END
diff --git a/libcruft/lapack/slaqr1.f b/libcruft/lapack/slaqr1.f
new file mode 100644
index 0000000..c7bdaa0
--- /dev/null
+++ b/libcruft/lapack/slaqr1.f
@@ -0,0 +1,97 @@
+      SUBROUTINE SLAQR1( N, H, LDH, SR1, SI1, SR2, SI2, V )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               SI1, SI2, SR1, SR2
+      INTEGER            LDH, N
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), V( * )
+*     ..
+*
+*       Given a 2-by-2 or 3-by-3 matrix H, SLAQR1 sets v to a
+*       scalar multiple of the first column of the product
+*
+*       (*)  K = (H - (sr1 + i*si1)*I)*(H - (sr2 + i*si2)*I)
+*
+*       scaling to avoid overflows and most underflows. It
+*       is assumed that either
+*
+*               1) sr1 = sr2 and si1 = -si2
+*           or
+*               2) si1 = si2 = 0.
+*
+*       This is useful for starting double implicit shift bulges
+*       in the QR algorithm.
+*
+*
+*       N      (input) integer
+*              Order of the matrix H. N must be either 2 or 3.
+*
+*       H      (input) REAL array of dimension (LDH,N)
+*              The 2-by-2 or 3-by-3 matrix H in (*).
+*
+*       LDH    (input) integer
+*              The leading dimension of H as declared in
+*              the calling procedure.  LDH.GE.N
+*
+*       SR1    (input) REAL
+*       SI1    The shifts in (*).
+*       SR2
+*       SI2
+*
+*       V      (output) REAL array of dimension N
+*              A scalar multiple of the first column of the
+*              matrix K in (*).
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               H21S, H31S, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+      IF( N.EQ.2 ) THEN
+         S = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) )
+         IF( S.EQ.ZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            V( 1 ) = H21S*H( 1, 2 ) + ( H( 1, 1 )-SR1 )*
+     $               ( ( H( 1, 1 )-SR2 ) / S ) - SI1*( SI2 / S )
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 )
+         END IF
+      ELSE
+         S = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) ) +
+     $       ABS( H( 3, 1 ) )
+         IF( S.EQ.ZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+            V( 3 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            H31S = H( 3, 1 ) / S
+            V( 1 ) = ( H( 1, 1 )-SR1 )*( ( H( 1, 1 )-SR2 ) / S ) -
+     $               SI1*( SI2 / S ) + H( 1, 2 )*H21S + H( 1, 3 )*H31S
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 ) +
+     $               H( 2, 3 )*H31S
+            V( 3 ) = H31S*( H( 1, 1 )+H( 3, 3 )-SR1-SR2 ) +
+     $               H21S*H( 3, 2 )
+         END IF
+      END IF
+      END
diff --git a/libcruft/lapack/slaqr2.f b/libcruft/lapack/slaqr2.f
new file mode 100644
index 0000000..beeaee6
--- /dev/null
+++ b/libcruft/lapack/slaqr2.f
@@ -0,0 +1,551 @@
+      SUBROUTINE SLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,
+     $                   LDT, NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),
+     $                   V( LDV, * ), WORK( * ), WV( LDWV, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     This subroutine is identical to SLAQR3 except that it avoids
+*     recursion by calling SLAHQR instead of SLAQR4.
+*
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an orthogonal similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an orthogonal similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the quasi-triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the orthogonal matrix Z is updated so
+*          so that the orthogonal Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the orthogonal matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) REAL array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by an orthogonal
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) REAL array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the orthogonal
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SR      (output) REAL array, dimension KBOT
+*     SI      (output) REAL array, dimension KBOT
+*          On output, the real and imaginary parts of approximate
+*          eigenvalues that may be used for shifts are stored in
+*          SR(KBOT-ND-NS+1) through SR(KBOT-ND) and
+*          SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.
+*          The real and imaginary parts of converged eigenvalues
+*          are stored in SR(KBOT-ND+1) through SR(KBOT) and
+*          SI(KBOT-ND+1) through SI(KBOT), respectively.
+*
+*     V       (workspace) REAL array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) REAL array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) REAL array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) REAL array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; SLAQR2
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,
+     $                   SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,
+     $                   KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2,
+     $                   LWKOPT
+      LOGICAL            BULGE, SORTED
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEHRD, SGEMM, SLABAD, SLACPY, SLAHQR,
+     $                   SLANV2, SLARF, SLARFG, SLASET, SORGHR, STREXC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to SGEHRD ====
+*
+         CALL SGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to SORGHR ====
+*
+         CALL SORGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = JW + MAX( LWK1, LWK2 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = REAL( LWKOPT )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SR( KWTOP ) = H( KWTOP, KWTOP )
+         SI( KWTOP ) = ZERO
+         NS = 1
+         ND = 0
+         IF( ABS( S ).LE.MAX( SMLNUM, ULP*ABS( H( KWTOP, KWTOP ) ) ) )
+     $        THEN
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL SLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL SCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL SLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      CALL SLAHQR( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),
+     $             SI( KWTOP ), 1, JW, V, LDV, INFQR )
+*
+*     ==== STREXC needs a clean margin near the diagonal ====
+*
+      DO 10 J = 1, JW - 3
+         T( J+2, J ) = ZERO
+         T( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( JW.GT.2 )
+     $   T( JW, JW-2 ) = ZERO
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+   20 CONTINUE
+      IF( ILST.LE.NS ) THEN
+         IF( NS.EQ.1 ) THEN
+            BULGE = .FALSE.
+         ELSE
+            BULGE = T( NS, NS-1 ).NE.ZERO
+         END IF
+*
+*        ==== Small spike tip test for deflation ====
+*
+         IF( .NOT.BULGE ) THEN
+*
+*           ==== Real eigenvalue ====
+*
+            FOO = ABS( T( NS, NS ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( ABS( S*V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 1
+            ELSE
+*
+*              ==== Undeflatable.   Move it up out of the way.
+*              .    (STREXC can not fail in this case.) ====
+*
+               IFST = NS
+               CALL STREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 1
+            END IF
+         ELSE
+*
+*           ==== Complex conjugate pair ====
+*
+            FOO = ABS( T( NS, NS ) ) + SQRT( ABS( T( NS, NS-1 ) ) )*
+     $            SQRT( ABS( T( NS-1, NS ) ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( MAX( ABS( S*V( 1, NS ) ), ABS( S*V( 1, NS-1 ) ) ).LE.
+     $          MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 2
+            ELSE
+*
+*              ==== Undflatable. Move them up out of the way.
+*              .    Fortunately, STREXC does the right thing with
+*              .    ILST in case of a rare exchange failure. ====
+*
+               IFST = NS
+               CALL STREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 2
+            END IF
+         END IF
+*
+*        ==== End deflation detection loop ====
+*
+         GO TO 20
+      END IF
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting diagonal blocks of T improves accuracy for
+*        .    graded matrices.  Bubble sort deals well with
+*        .    exchange failures. ====
+*
+         SORTED = .false.
+         I = NS + 1
+   30    CONTINUE
+         IF( SORTED )
+     $      GO TO 50
+         SORTED = .true.
+*
+         KEND = I - 1
+         I = INFQR + 1
+         IF( I.EQ.NS ) THEN
+            K = I + 1
+         ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+            K = I + 1
+         ELSE
+            K = I + 2
+         END IF
+   40    CONTINUE
+         IF( K.LE.KEND ) THEN
+            IF( K.EQ.I+1 ) THEN
+               EVI = ABS( T( I, I ) )
+            ELSE
+               EVI = ABS( T( I, I ) ) + SQRT( ABS( T( I+1, I ) ) )*
+     $               SQRT( ABS( T( I, I+1 ) ) )
+            END IF
+*
+            IF( K.EQ.KEND ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE IF( T( K+1, K ).EQ.ZERO ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE
+               EVK = ABS( T( K, K ) ) + SQRT( ABS( T( K+1, K ) ) )*
+     $               SQRT( ABS( T( K, K+1 ) ) )
+            END IF
+*
+            IF( EVI.GE.EVK ) THEN
+               I = K
+            ELSE
+               SORTED = .false.
+               IFST = I
+               ILST = K
+               CALL STREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               IF( INFO.EQ.0 ) THEN
+                  I = ILST
+               ELSE
+                  I = K
+               END IF
+            END IF
+            IF( I.EQ.KEND ) THEN
+               K = I + 1
+            ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+               K = I + 1
+            ELSE
+               K = I + 2
+            END IF
+            GO TO 40
+         END IF
+         GO TO 30
+   50    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      I = JW
+   60 CONTINUE
+      IF( I.GE.INFQR+1 ) THEN
+         IF( I.EQ.INFQR+1 ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE IF( T( I, I-1 ).EQ.ZERO ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE
+            AA = T( I-1, I-1 )
+            CC = T( I, I-1 )
+            BB = T( I-1, I )
+            DD = T( I, I )
+            CALL SLANV2( AA, BB, CC, DD, SR( KWTOP+I-2 ),
+     $                   SI( KWTOP+I-2 ), SR( KWTOP+I-1 ),
+     $                   SI( KWTOP+I-1 ), CS, SN )
+            I = I - 2
+         END IF
+         GO TO 60
+      END IF
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL SCOPY( NS, V, LDV, WORK, 1 )
+            BETA = WORK( 1 )
+            CALL SLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL SLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL SLARF( 'L', NS, JW, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL SLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL SLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL SGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*V( 1, 1 )
+         CALL SLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL SCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  SORGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL SORGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL SGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL SLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 70 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL SGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL SLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   70    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 80 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL SGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL SLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   80       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 90 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL SGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL SLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   90       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = REAL( LWKOPT )
+*
+*     ==== End of SLAQR2 ====
+*
+      END
diff --git a/libcruft/lapack/slaqr3.f b/libcruft/lapack/slaqr3.f
new file mode 100644
index 0000000..33b05d7
--- /dev/null
+++ b/libcruft/lapack/slaqr3.f
@@ -0,0 +1,561 @@
+      SUBROUTINE SLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,
+     $                   LDT, NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),
+     $                   V( LDV, * ), WORK( * ), WV( LDWV, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an orthogonal similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an orthogonal similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the quasi-triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the orthogonal matrix Z is updated so
+*          so that the orthogonal Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the orthogonal matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) REAL array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by an orthogonal
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) REAL array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the orthogonal
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SR      (output) REAL array, dimension KBOT
+*     SI      (output) REAL array, dimension KBOT
+*          On output, the real and imaginary parts of approximate
+*          eigenvalues that may be used for shifts are stored in
+*          SR(KBOT-ND-NS+1) through SR(KBOT-ND) and
+*          SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.
+*          The real and imaginary parts of converged eigenvalues
+*          are stored in SR(KBOT-ND+1) through SR(KBOT) and
+*          SI(KBOT-ND+1) through SI(KBOT), respectively.
+*
+*     V       (workspace) REAL array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) REAL array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) REAL array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) REAL array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; SLAQR3
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,
+     $                   SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,
+     $                   KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2, LWK3,
+     $                   LWKOPT, NMIN
+      LOGICAL            BULGE, SORTED
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      INTEGER            ILAENV
+      EXTERNAL           SLAMCH, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEHRD, SGEMM, SLABAD, SLACPY, SLAHQR,
+     $                   SLANV2, SLAQR4, SLARF, SLARFG, SLASET, SORGHR,
+     $                   STREXC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to SGEHRD ====
+*
+         CALL SGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to SORGHR ====
+*
+         CALL SORGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to SLAQR4 ====
+*
+         CALL SLAQR4( .true., .true., JW, 1, JW, T, LDT, SR, SI, 1, JW,
+     $                V, LDV, WORK, -1, INFQR )
+         LWK3 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = MAX( JW+MAX( LWK1, LWK2 ), LWK3 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = REAL( LWKOPT )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SR( KWTOP ) = H( KWTOP, KWTOP )
+         SI( KWTOP ) = ZERO
+         NS = 1
+         ND = 0
+         IF( ABS( S ).LE.MAX( SMLNUM, ULP*ABS( H( KWTOP, KWTOP ) ) ) )
+     $        THEN
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL SLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL SCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL SLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      NMIN = ILAENV( 12, 'SLAQR3', 'SV', JW, 1, JW, LWORK )
+      IF( JW.GT.NMIN ) THEN
+         CALL SLAQR4( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),
+     $                SI( KWTOP ), 1, JW, V, LDV, WORK, LWORK, INFQR )
+      ELSE
+         CALL SLAHQR( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),
+     $                SI( KWTOP ), 1, JW, V, LDV, INFQR )
+      END IF
+*
+*     ==== STREXC needs a clean margin near the diagonal ====
+*
+      DO 10 J = 1, JW - 3
+         T( J+2, J ) = ZERO
+         T( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( JW.GT.2 )
+     $   T( JW, JW-2 ) = ZERO
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+   20 CONTINUE
+      IF( ILST.LE.NS ) THEN
+         IF( NS.EQ.1 ) THEN
+            BULGE = .FALSE.
+         ELSE
+            BULGE = T( NS, NS-1 ).NE.ZERO
+         END IF
+*
+*        ==== Small spike tip test for deflation ====
+*
+         IF( .NOT.BULGE ) THEN
+*
+*           ==== Real eigenvalue ====
+*
+            FOO = ABS( T( NS, NS ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( ABS( S*V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 1
+            ELSE
+*
+*              ==== Undeflatable.   Move it up out of the way.
+*              .    (STREXC can not fail in this case.) ====
+*
+               IFST = NS
+               CALL STREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 1
+            END IF
+         ELSE
+*
+*           ==== Complex conjugate pair ====
+*
+            FOO = ABS( T( NS, NS ) ) + SQRT( ABS( T( NS, NS-1 ) ) )*
+     $            SQRT( ABS( T( NS-1, NS ) ) )
+            IF( FOO.EQ.ZERO )
+     $         FOO = ABS( S )
+            IF( MAX( ABS( S*V( 1, NS ) ), ABS( S*V( 1, NS-1 ) ) ).LE.
+     $          MAX( SMLNUM, ULP*FOO ) ) THEN
+*
+*              ==== Deflatable ====
+*
+               NS = NS - 2
+            ELSE
+*
+*              ==== Undflatable. Move them up out of the way.
+*              .    Fortunately, STREXC does the right thing with
+*              .    ILST in case of a rare exchange failure. ====
+*
+               IFST = NS
+               CALL STREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               ILST = ILST + 2
+            END IF
+         END IF
+*
+*        ==== End deflation detection loop ====
+*
+         GO TO 20
+      END IF
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting diagonal blocks of T improves accuracy for
+*        .    graded matrices.  Bubble sort deals well with
+*        .    exchange failures. ====
+*
+         SORTED = .false.
+         I = NS + 1
+   30    CONTINUE
+         IF( SORTED )
+     $      GO TO 50
+         SORTED = .true.
+*
+         KEND = I - 1
+         I = INFQR + 1
+         IF( I.EQ.NS ) THEN
+            K = I + 1
+         ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+            K = I + 1
+         ELSE
+            K = I + 2
+         END IF
+   40    CONTINUE
+         IF( K.LE.KEND ) THEN
+            IF( K.EQ.I+1 ) THEN
+               EVI = ABS( T( I, I ) )
+            ELSE
+               EVI = ABS( T( I, I ) ) + SQRT( ABS( T( I+1, I ) ) )*
+     $               SQRT( ABS( T( I, I+1 ) ) )
+            END IF
+*
+            IF( K.EQ.KEND ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE IF( T( K+1, K ).EQ.ZERO ) THEN
+               EVK = ABS( T( K, K ) )
+            ELSE
+               EVK = ABS( T( K, K ) ) + SQRT( ABS( T( K+1, K ) ) )*
+     $               SQRT( ABS( T( K, K+1 ) ) )
+            END IF
+*
+            IF( EVI.GE.EVK ) THEN
+               I = K
+            ELSE
+               SORTED = .false.
+               IFST = I
+               ILST = K
+               CALL STREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,
+     $                      INFO )
+               IF( INFO.EQ.0 ) THEN
+                  I = ILST
+               ELSE
+                  I = K
+               END IF
+            END IF
+            IF( I.EQ.KEND ) THEN
+               K = I + 1
+            ELSE IF( T( I+1, I ).EQ.ZERO ) THEN
+               K = I + 1
+            ELSE
+               K = I + 2
+            END IF
+            GO TO 40
+         END IF
+         GO TO 30
+   50    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      I = JW
+   60 CONTINUE
+      IF( I.GE.INFQR+1 ) THEN
+         IF( I.EQ.INFQR+1 ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE IF( T( I, I-1 ).EQ.ZERO ) THEN
+            SR( KWTOP+I-1 ) = T( I, I )
+            SI( KWTOP+I-1 ) = ZERO
+            I = I - 1
+         ELSE
+            AA = T( I-1, I-1 )
+            CC = T( I, I-1 )
+            BB = T( I-1, I )
+            DD = T( I, I )
+            CALL SLANV2( AA, BB, CC, DD, SR( KWTOP+I-2 ),
+     $                   SI( KWTOP+I-2 ), SR( KWTOP+I-1 ),
+     $                   SI( KWTOP+I-1 ), CS, SN )
+            I = I - 2
+         END IF
+         GO TO 60
+      END IF
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL SCOPY( NS, V, LDV, WORK, 1 )
+            BETA = WORK( 1 )
+            CALL SLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL SLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL SLARF( 'L', NS, JW, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL SLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL SLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL SGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*V( 1, 1 )
+         CALL SLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL SCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  SORGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL SORGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL SGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL SLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 70 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL SGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL SLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   70    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 80 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL SGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL SLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   80       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 90 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL SGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL SLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   90       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = REAL( LWKOPT )
+*
+*     ==== End of SLAQR3 ====
+*
+      END
diff --git a/libcruft/lapack/slaqr4.f b/libcruft/lapack/slaqr4.f
new file mode 100644
index 0000000..306d152
--- /dev/null
+++ b/libcruft/lapack/slaqr4.f
@@ -0,0 +1,640 @@
+      SUBROUTINE SLAQR4( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), WI( * ), WORK( * ), WR( * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     This subroutine implements one level of recursion for SLAQR0.
+*     It is a complete implementation of the small bulge multi-shift
+*     QR algorithm.  It may be called by SLAQR0 and, for large enough
+*     deflation window size, it may be called by SLAQR3.  This
+*     subroutine is identical to SLAQR0 except that it calls SLAQR2
+*     instead of SLAQR3.
+*
+*     Purpose
+*     =======
+*
+*     SLAQR4 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**T, where T is an upper quasi-triangular matrix (the
+*     Schur form), and Z is the orthogonal matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input orthogonal
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to SGEBAL, and then passed to SGEHRD when the
+*           matrix output by SGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) REAL array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H contains
+*           the upper quasi-triangular matrix T from the Schur
+*           decomposition (the Schur form); 2-by-2 diagonal blocks
+*           (corresponding to complex conjugate pairs of eigenvalues)
+*           are returned in standard form, with H(i,i) = H(i+1,i+1)
+*           and H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and WANTT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     WR    (output) REAL array, dimension (IHI)
+*     WI    (output) REAL array, dimension (IHI)
+*           The real and imaginary parts, respectively, of the computed
+*           eigenvalues of H(ILO:IHI,ILO:IHI) are stored WR(ILO:IHI)
+*           and WI(ILO:IHI). If two eigenvalues are computed as a
+*           complex conjugate pair, they are stored in consecutive
+*           elements of WR and WI, say the i-th and (i+1)th, with
+*           WI(i) .GT. 0 and WI(i+1) .LT. 0. If WANTT is .TRUE., then
+*           the eigenvalues are stored in the same order as on the
+*           diagonal of the Schur form returned in H, with
+*           WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal
+*           block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and
+*           WI(i+1) = -WI(i).
+*
+*     ILOZ     (input) INTEGER
+*     IHIZ     (input) INTEGER
+*           Specify the rows of Z to which transformations must be
+*           applied if WANTZ is .TRUE..
+*           1 .LE. ILOZ .LE. ILO; IHI .LE. IHIZ .LE. N.
+*
+*     Z     (input/output) REAL array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) REAL array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then SLAQR4 does a workspace query.
+*           In this case, SLAQR4 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, SLAQR4 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is an orthogonal matrix.  The final
+*                value of H is upper Hessenberg and quasi-triangular
+*                in rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the orthogonal matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    SLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      REAL               WILK1, WILK2
+      PARAMETER          ( WILK1 = 0.75e0, WILK2 = -0.4375e0 )
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AA, BB, CC, CS, DD, SN, SS, SWAP
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      REAL               ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACPY, SLAHQR, SLANV2, SLAQR2, SLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, MAX, MIN, MOD, REAL
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use SLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL SLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
+     $                   ILOZ, IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'SLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'SLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to SLAQR2 ====
+*
+         CALL SLAQR2( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, WR, WI, H, LDH, N, H, LDH,
+     $                N, H, LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(SLAQR5, SLAQR2) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = REAL( LWKOPT )
+            RETURN
+         END IF
+*
+*        ==== SLAHQR/SLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'SLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'SLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'SLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 80 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 90
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( ABS( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      ABS( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL SLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, WR, WI, H( KV, 1 ), LDH,
+     $                   NHO, H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                   WORK, LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if SLAQR2
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    SLAQR2 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, MAX( KS+1, KTOP+2 ), -2
+                     SS = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )
+                     AA = WILK1*SS + H( I, I )
+                     BB = SS
+                     CC = WILK2*SS
+                     DD = AA
+                     CALL SLANV2( AA, BB, CC, DD, WR( I-1 ), WI( I-1 ),
+     $                            WR( I ), WI( I ), CS, SN )
+   30             CONTINUE
+                  IF( KS.EQ.KTOP ) THEN
+                     WR( KS+1 ) = H( KS+1, KS+1 )
+                     WI( KS+1 ) = ZERO
+                     WR( KS ) = WR( KS+1 )
+                     WI( KS ) = WI( KS+1 )
+                  END IF
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use SLAHQR
+*                 .    on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL SLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     CALL SLAHQR( .false., .false., NS, 1, NS,
+     $                            H( KT, 1 ), LDH, WR( KS ), WI( KS ),
+     $                            1, 1, ZDUM, 1, INF )
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        AA = H( KBOT-1, KBOT-1 )
+                        CC = H( KBOT, KBOT-1 )
+                        BB = H( KBOT-1, KBOT )
+                        DD = H( KBOT, KBOT )
+                        CALL SLANV2( AA, BB, CC, DD, WR( KBOT-1 ),
+     $                               WI( KBOT-1 ), WR( KBOT ),
+     $                               WI( KBOT ), CS, SN )
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little)
+*                    .    Bubble sort keeps complex conjugate
+*                    .    pairs together. ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( ABS( WR( I ) )+ABS( WI( I ) ).LT.
+     $                         ABS( WR( I+1 ) )+ABS( WI( I+1 ) ) ) THEN
+                              SORTED = .false.
+*
+                              SWAP = WR( I )
+                              WR( I ) = WR( I+1 )
+                              WR( I+1 ) = SWAP
+*
+                              SWAP = WI( I )
+                              WI( I ) = WI( I+1 )
+                              WI( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+*
+*                 ==== Shuffle shifts into pairs of real shifts
+*                 .    and pairs of complex conjugate shifts
+*                 .    assuming complex conjugate shifts are
+*                 .    already adjacent to one another. (Yes,
+*                 .    they are.)  ====
+*
+                  DO 70 I = KBOT, KS + 2, -2
+                     IF( WI( I ).NE.-WI( I-1 ) ) THEN
+*
+                        SWAP = WR( I )
+                        WR( I ) = WR( I-1 )
+                        WR( I-1 ) = WR( I-2 )
+                        WR( I-2 ) = SWAP
+*
+                        SWAP = WI( I )
+                        WI( I ) = WI( I-1 )
+                        WI( I-1 ) = WI( I-2 )
+                        WI( I-2 ) = SWAP
+                     END IF
+   70             CONTINUE
+               END IF
+*
+*              ==== If there are only two shifts and both are
+*              .    real, then use only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( WI( KBOT ).EQ.ZERO ) THEN
+                     IF( ABS( WR( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                   ABS( WR( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                        WR( KBOT-1 ) = WR( KBOT )
+                     ELSE
+                        WR( KBOT ) = WR( KBOT-1 )
+                     END IF
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL SLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      WR( KS ), WI( KS ), H, LDH, ILOZ, IHIZ, Z,
+     $                      LDZ, WORK, 3, H( KU, 1 ), LDH, NVE,
+     $                      H( KWV, 1 ), LDH, NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   80    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   90    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = REAL( LWKOPT )
+*
+*     ==== End of SLAQR4 ====
+*
+      END
diff --git a/libcruft/lapack/slaqr5.f b/libcruft/lapack/slaqr5.f
new file mode 100644
index 0000000..8b144bb
--- /dev/null
+++ b/libcruft/lapack/slaqr5.f
@@ -0,0 +1,812 @@
+      SUBROUTINE SLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS,
+     $                   SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,
+     $                   LDU, NV, WV, LDWV, NH, WH, LDWH )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
+     $                   LDWH, LDWV, LDZ, N, NH, NSHFTS, NV
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      REAL               H( LDH, * ), SI( * ), SR( * ), U( LDU, * ),
+     $                   V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*     This auxiliary subroutine called by SLAQR0 performs a
+*     single small-bulge multi-shift QR sweep.
+*
+*      WANTT  (input) logical scalar
+*             WANTT = .true. if the quasi-triangular Schur factor
+*             is being computed.  WANTT is set to .false. otherwise.
+*
+*      WANTZ  (input) logical scalar
+*             WANTZ = .true. if the orthogonal Schur factor is being
+*             computed.  WANTZ is set to .false. otherwise.
+*
+*      KACC22 (input) integer with value 0, 1, or 2.
+*             Specifies the computation mode of far-from-diagonal
+*             orthogonal updates.
+*        = 0: SLAQR5 does not accumulate reflections and does not
+*             use matrix-matrix multiply to update far-from-diagonal
+*             matrix entries.
+*        = 1: SLAQR5 accumulates reflections and uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries.
+*        = 2: SLAQR5 accumulates reflections, uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries,
+*             and takes advantage of 2-by-2 block structure during
+*             matrix multiplies.
+*
+*      N      (input) integer scalar
+*             N is the order of the Hessenberg matrix H upon which this
+*             subroutine operates.
+*
+*      KTOP   (input) integer scalar
+*      KBOT   (input) integer scalar
+*             These are the first and last rows and columns of an
+*             isolated diagonal block upon which the QR sweep is to be
+*             applied. It is assumed without a check that
+*                       either KTOP = 1  or   H(KTOP,KTOP-1) = 0
+*             and
+*                       either KBOT = N  or   H(KBOT+1,KBOT) = 0.
+*
+*      NSHFTS (input) integer scalar
+*             NSHFTS gives the number of simultaneous shifts.  NSHFTS
+*             must be positive and even.
+*
+*      SR     (input) REAL array of size (NSHFTS)
+*      SI     (input) REAL array of size (NSHFTS)
+*             SR contains the real parts and SI contains the imaginary
+*             parts of the NSHFTS shifts of origin that define the
+*             multi-shift QR sweep.
+*
+*      H      (input/output) REAL array of size (LDH,N)
+*             On input H contains a Hessenberg matrix.  On output a
+*             multi-shift QR sweep with shifts SR(J)+i*SI(J) is applied
+*             to the isolated diagonal block in rows and columns KTOP
+*             through KBOT.
+*
+*      LDH    (input) integer scalar
+*             LDH is the leading dimension of H just as declared in the
+*             calling procedure.  LDH.GE.MAX(1,N).
+*
+*      ILOZ   (input) INTEGER
+*      IHIZ   (input) INTEGER
+*             Specify the rows of Z to which transformations must be
+*             applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N
+*
+*      Z      (input/output) REAL array of size (LDZ,IHI)
+*             If WANTZ = .TRUE., then the QR Sweep orthogonal
+*             similarity transformation is accumulated into
+*             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*             If WANTZ = .FALSE., then Z is unreferenced.
+*
+*      LDZ    (input) integer scalar
+*             LDA is the leading dimension of Z just as declared in
+*             the calling procedure. LDZ.GE.N.
+*
+*      V      (workspace) REAL array of size (LDV,NSHFTS/2)
+*
+*      LDV    (input) integer scalar
+*             LDV is the leading dimension of V as declared in the
+*             calling procedure.  LDV.GE.3.
+*
+*      U      (workspace) REAL array of size
+*             (LDU,3*NSHFTS-3)
+*
+*      LDU    (input) integer scalar
+*             LDU is the leading dimension of U just as declared in the
+*             in the calling subroutine.  LDU.GE.3*NSHFTS-3.
+*
+*      NH     (input) integer scalar
+*             NH is the number of columns in array WH available for
+*             workspace. NH.GE.1.
+*
+*      WH     (workspace) REAL array of size (LDWH,NH)
+*
+*      LDWH   (input) integer scalar
+*             Leading dimension of WH just as declared in the
+*             calling procedure.  LDWH.GE.3*NSHFTS-3.
+*
+*      NV     (input) integer scalar
+*             NV is the number of rows in WV agailable for workspace.
+*             NV.GE.1.
+*
+*      WV     (workspace) REAL array of size
+*             (LDWV,3*NSHFTS-3)
+*
+*      LDWV   (input) integer scalar
+*             LDWV is the leading dimension of WV as declared in the
+*             in the calling subroutine.  LDWV.GE.NV.
+*
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ============================================================
+*     Reference:
+*
+*     K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*     Algorithm Part I: Maintaining Well Focused Shifts, and
+*     Level 3 Performance, SIAM Journal of Matrix Analysis,
+*     volume 23, pages 929--947, 2002.
+*
+*     ============================================================
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0e0, ONE = 1.0e0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               ALPHA, BETA, H11, H12, H21, H22, REFSUM,
+     $                   SAFMAX, SAFMIN, SCL, SMLNUM, SWAP, TST1, TST2,
+     $                   ULP
+      INTEGER            I, I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN,
+     $                   JROW, JTOP, K, K1, KDU, KMS, KNZ, KRCOL, KZS,
+     $                   M, M22, MBOT, MEND, MSTART, MTOP, NBMPS, NDCOL,
+     $                   NS, NU
+      LOGICAL            ACCUM, BLK22, BMP22
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+*
+      INTRINSIC          ABS, MAX, MIN, MOD, REAL
+*     ..
+*     .. Local Arrays ..
+      REAL               VT( 3 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SLABAD, SLACPY, SLAQR1, SLARFG, SLASET,
+     $                   STRMM
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== If there are no shifts, then there is nothing to do. ====
+*
+      IF( NSHFTS.LT.2 )
+     $   RETURN
+*
+*     ==== If the active block is empty or 1-by-1, then there
+*     .    is nothing to do. ====
+*
+      IF( KTOP.GE.KBOT )
+     $   RETURN
+*
+*     ==== Shuffle shifts into pairs of real shifts and pairs
+*     .    of complex conjugate shifts assuming complex
+*     .    conjugate shifts are already adjacent to one
+*     .    another. ====
+*
+      DO 10 I = 1, NSHFTS - 2, 2
+         IF( SI( I ).NE.-SI( I+1 ) ) THEN
+*
+            SWAP = SR( I )
+            SR( I ) = SR( I+1 )
+            SR( I+1 ) = SR( I+2 )
+            SR( I+2 ) = SWAP
+*
+            SWAP = SI( I )
+            SI( I ) = SI( I+1 )
+            SI( I+1 ) = SI( I+2 )
+            SI( I+2 ) = SWAP
+         END IF
+   10 CONTINUE
+*
+*     ==== NSHFTS is supposed to be even, but if is odd,
+*     .    then simply reduce it by one.  The shuffle above
+*     .    ensures that the dropped shift is real and that
+*     .    the remaining shifts are paired. ====
+*
+      NS = NSHFTS - MOD( NSHFTS, 2 )
+*
+*     ==== Machine constants for deflation ====
+*
+      SAFMIN = SLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = ONE / SAFMIN
+      CALL SLABAD( SAFMIN, SAFMAX )
+      ULP = SLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( REAL( N ) / ULP )
+*
+*     ==== Use accumulated reflections to update far-from-diagonal
+*     .    entries ? ====
+*
+      ACCUM = ( KACC22.EQ.1 ) .OR. ( KACC22.EQ.2 )
+*
+*     ==== If so, exploit the 2-by-2 block structure? ====
+*
+      BLK22 = ( NS.GT.2 ) .AND. ( KACC22.EQ.2 )
+*
+*     ==== clear trash ====
+*
+      IF( KTOP+2.LE.KBOT )
+     $   H( KTOP+2, KTOP ) = ZERO
+*
+*     ==== NBMPS = number of 2-shift bulges in the chain ====
+*
+      NBMPS = NS / 2
+*
+*     ==== KDU = width of slab ====
+*
+      KDU = 6*NBMPS - 3
+*
+*     ==== Create and chase chains of NBMPS bulges ====
+*
+      DO 220 INCOL = 3*( 1-NBMPS ) + KTOP - 1, KBOT - 2, 3*NBMPS - 2
+         NDCOL = INCOL + KDU
+         IF( ACCUM )
+     $      CALL SLASET( 'ALL', KDU, KDU, ZERO, ONE, U, LDU )
+*
+*        ==== Near-the-diagonal bulge chase.  The following loop
+*        .    performs the near-the-diagonal part of a small bulge
+*        .    multi-shift QR sweep.  Each 6*NBMPS-2 column diagonal
+*        .    chunk extends from column INCOL to column NDCOL
+*        .    (including both column INCOL and column NDCOL). The
+*        .    following loop chases a 3*NBMPS column long chain of
+*        .    NBMPS bulges 3*NBMPS-2 columns to the right.  (INCOL
+*        .    may be less than KTOP and and NDCOL may be greater than
+*        .    KBOT indicating phantom columns from which to chase
+*        .    bulges before they are actually introduced or to which
+*        .    to chase bulges beyond column KBOT.)  ====
+*
+         DO 150 KRCOL = INCOL, MIN( INCOL+3*NBMPS-3, KBOT-2 )
+*
+*           ==== Bulges number MTOP to MBOT are active double implicit
+*           .    shift bulges.  There may or may not also be small
+*           .    2-by-2 bulge, if there is room.  The inactive bulges
+*           .    (if any) must wait until the active bulges have moved
+*           .    down the diagonal to make room.  The phantom matrix
+*           .    paradigm described above helps keep track.  ====
+*
+            MTOP = MAX( 1, ( ( KTOP-1 )-KRCOL+2 ) / 3+1 )
+            MBOT = MIN( NBMPS, ( KBOT-KRCOL ) / 3 )
+            M22 = MBOT + 1
+            BMP22 = ( MBOT.LT.NBMPS ) .AND. ( KRCOL+3*( M22-1 ) ).EQ.
+     $              ( KBOT-2 )
+*
+*           ==== Generate reflections to chase the chain right
+*           .    one column.  (The minimum value of K is KTOP-1.) ====
+*
+            DO 20 M = MTOP, MBOT
+               K = KRCOL + 3*( M-1 )
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL SLAQR1( 3, H( KTOP, KTOP ), LDH, SR( 2*M-1 ),
+     $                         SI( 2*M-1 ), SR( 2*M ), SI( 2*M ),
+     $                         V( 1, M ) )
+                  ALPHA = V( 1, M )
+                  CALL SLARFG( 3, ALPHA, V( 2, M ), 1, V( 1, M ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M ) = H( K+2, K )
+                  V( 3, M ) = H( K+3, K )
+                  CALL SLARFG( 3, BETA, V( 2, M ), 1, V( 1, M ) )
+*
+*                 ==== A Bulge may collapse because of vigilant
+*                 .    deflation or destructive underflow.  (The
+*                 .    initial bulge is always collapsed.) Use
+*                 .    the two-small-subdiagonals trick to try
+*                 .    to get it started again. If V(2,M).NE.0 and
+*                 .    V(3,M) = H(K+3,K+1) = H(K+3,K+2) = 0, then
+*                 .    this bulge is collapsing into a zero
+*                 .    subdiagonal.  It will be restarted next
+*                 .    trip through the loop.)
+*
+                  IF( V( 1, M ).NE.ZERO .AND.
+     $                ( V( 3, M ).NE.ZERO .OR. ( H( K+3,
+     $                K+1 ).EQ.ZERO .AND. H( K+3, K+2 ).EQ.ZERO ) ) )
+     $                 THEN
+*
+*                    ==== Typical case: not collapsed (yet). ====
+*
+                     H( K+1, K ) = BETA
+                     H( K+2, K ) = ZERO
+                     H( K+3, K ) = ZERO
+                  ELSE
+*
+*                    ==== Atypical case: collapsed.  Attempt to
+*                    .    reintroduce ignoring H(K+1,K).  If the
+*                    .    fill resulting from the new reflector
+*                    .    is too large, then abandon it.
+*                    .    Otherwise, use the new one. ====
+*
+                     CALL SLAQR1( 3, H( K+1, K+1 ), LDH, SR( 2*M-1 ),
+     $                            SI( 2*M-1 ), SR( 2*M ), SI( 2*M ),
+     $                            VT )
+                     SCL = ABS( VT( 1 ) ) + ABS( VT( 2 ) ) +
+     $                     ABS( VT( 3 ) )
+                     IF( SCL.NE.ZERO ) THEN
+                        VT( 1 ) = VT( 1 ) / SCL
+                        VT( 2 ) = VT( 2 ) / SCL
+                        VT( 3 ) = VT( 3 ) / SCL
+                     END IF
+*
+*                    ==== The following is the traditional and
+*                    .    conservative two-small-subdiagonals
+*                    .    test.  ====
+*                    .
+                     IF( ABS( H( K+1, K ) )*( ABS( VT( 2 ) )+
+     $                   ABS( VT( 3 ) ) ).GT.ULP*ABS( VT( 1 ) )*
+     $                   ( ABS( H( K, K ) )+ABS( H( K+1,
+     $                   K+1 ) )+ABS( H( K+2, K+2 ) ) ) ) THEN
+*
+*                       ==== Starting a new bulge here would
+*                       .    create non-negligible fill.   If
+*                       .    the old reflector is diagonal (only
+*                       .    possible with underflows), then
+*                       .    change it to I.  Otherwise, use
+*                       .    it with trepidation. ====
+*
+                        IF( V( 2, M ).EQ.ZERO .AND. V( 3, M ).EQ.ZERO )
+     $                       THEN
+                           V( 1, M ) = ZERO
+                        ELSE
+                           H( K+1, K ) = BETA
+                           H( K+2, K ) = ZERO
+                           H( K+3, K ) = ZERO
+                        END IF
+                     ELSE
+*
+*                       ==== Stating a new bulge here would
+*                       .    create only negligible fill.
+*                       .    Replace the old reflector with
+*                       .    the new one. ====
+*
+                        ALPHA = VT( 1 )
+                        CALL SLARFG( 3, ALPHA, VT( 2 ), 1, VT( 1 ) )
+                        REFSUM = H( K+1, K ) + H( K+2, K )*VT( 2 ) +
+     $                           H( K+3, K )*VT( 3 )
+                        H( K+1, K ) = H( K+1, K ) - VT( 1 )*REFSUM
+                        H( K+2, K ) = ZERO
+                        H( K+3, K ) = ZERO
+                        V( 1, M ) = VT( 1 )
+                        V( 2, M ) = VT( 2 )
+                        V( 3, M ) = VT( 3 )
+                     END IF
+                  END IF
+               END IF
+   20       CONTINUE
+*
+*           ==== Generate a 2-by-2 reflection, if needed. ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 ) THEN
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL SLAQR1( 2, H( K+1, K+1 ), LDH, SR( 2*M22-1 ),
+     $                         SI( 2*M22-1 ), SR( 2*M22 ), SI( 2*M22 ),
+     $                         V( 1, M22 ) )
+                  BETA = V( 1, M22 )
+                  CALL SLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M22 ) = H( K+2, K )
+                  CALL SLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+                  H( K+1, K ) = BETA
+                  H( K+2, K ) = ZERO
+               END IF
+            ELSE
+*
+*              ==== Initialize V(1,M22) here to avoid possible undefined
+*              .    variable problems later. ====
+*
+               V( 1, M22 ) = ZERO
+            END IF
+*
+*           ==== Multiply H by reflections from the left ====
+*
+            IF( ACCUM ) THEN
+               JBOT = MIN( NDCOL, KBOT )
+            ELSE IF( WANTT ) THEN
+               JBOT = N
+            ELSE
+               JBOT = KBOT
+            END IF
+            DO 40 J = MAX( KTOP, KRCOL ), JBOT
+               MEND = MIN( MBOT, ( J-KRCOL+2 ) / 3 )
+               DO 30 M = MTOP, MEND
+                  K = KRCOL + 3*( M-1 )
+                  REFSUM = V( 1, M )*( H( K+1, J )+V( 2, M )*
+     $                     H( K+2, J )+V( 3, M )*H( K+3, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M )
+                  H( K+3, J ) = H( K+3, J ) - REFSUM*V( 3, M )
+   30          CONTINUE
+   40       CONTINUE
+            IF( BMP22 ) THEN
+               K = KRCOL + 3*( M22-1 )
+               DO 50 J = MAX( K+1, KTOP ), JBOT
+                  REFSUM = V( 1, M22 )*( H( K+1, J )+V( 2, M22 )*
+     $                     H( K+2, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M22 )
+   50          CONTINUE
+            END IF
+*
+*           ==== Multiply H by reflections from the right.
+*           .    Delay filling in the last row until the
+*           .    vigilant deflation check is complete. ====
+*
+            IF( ACCUM ) THEN
+               JTOP = MAX( KTOP, INCOL )
+            ELSE IF( WANTT ) THEN
+               JTOP = 1
+            ELSE
+               JTOP = KTOP
+            END IF
+            DO 90 M = MTOP, MBOT
+               IF( V( 1, M ).NE.ZERO ) THEN
+                  K = KRCOL + 3*( M-1 )
+                  DO 60 J = JTOP, MIN( KBOT, K+3 )
+                     REFSUM = V( 1, M )*( H( J, K+1 )+V( 2, M )*
+     $                        H( J, K+2 )+V( 3, M )*H( J, K+3 ) )
+                     H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                     H( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M )
+                     H( J, K+3 ) = H( J, K+3 ) - REFSUM*V( 3, M )
+   60             CONTINUE
+*
+                  IF( ACCUM ) THEN
+*
+*                    ==== Accumulate U. (If necessary, update Z later
+*                    .    with with an efficient matrix-matrix
+*                    .    multiply.) ====
+*
+                     KMS = K - INCOL
+                     DO 70 J = MAX( 1, KTOP-INCOL ), KDU
+                        REFSUM = V( 1, M )*( U( J, KMS+1 )+V( 2, M )*
+     $                           U( J, KMS+2 )+V( 3, M )*U( J, KMS+3 ) )
+                        U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                        U( J, KMS+2 ) = U( J, KMS+2 ) - REFSUM*V( 2, M )
+                        U( J, KMS+3 ) = U( J, KMS+3 ) - REFSUM*V( 3, M )
+   70                CONTINUE
+                  ELSE IF( WANTZ ) THEN
+*
+*                    ==== U is not accumulated, so update Z
+*                    .    now by multiplying by reflections
+*                    .    from the right. ====
+*
+                     DO 80 J = ILOZ, IHIZ
+                        REFSUM = V( 1, M )*( Z( J, K+1 )+V( 2, M )*
+     $                           Z( J, K+2 )+V( 3, M )*Z( J, K+3 ) )
+                        Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                        Z( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M )
+                        Z( J, K+3 ) = Z( J, K+3 ) - REFSUM*V( 3, M )
+   80                CONTINUE
+                  END IF
+               END IF
+   90       CONTINUE
+*
+*           ==== Special case: 2-by-2 reflection (if needed) ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 .AND. ( V( 1, M22 ).NE.ZERO ) ) THEN
+               DO 100 J = JTOP, MIN( KBOT, K+3 )
+                  REFSUM = V( 1, M22 )*( H( J, K+1 )+V( 2, M22 )*
+     $                     H( J, K+2 ) )
+                  H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                  H( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M22 )
+  100          CONTINUE
+*
+               IF( ACCUM ) THEN
+                  KMS = K - INCOL
+                  DO 110 J = MAX( 1, KTOP-INCOL ), KDU
+                     REFSUM = V( 1, M22 )*( U( J, KMS+1 )+V( 2, M22 )*
+     $                        U( J, KMS+2 ) )
+                     U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                     U( J, KMS+2 ) = U( J, KMS+2 ) - REFSUM*V( 2, M22 )
+  110             CONTINUE
+               ELSE IF( WANTZ ) THEN
+                  DO 120 J = ILOZ, IHIZ
+                     REFSUM = V( 1, M22 )*( Z( J, K+1 )+V( 2, M22 )*
+     $                        Z( J, K+2 ) )
+                     Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                     Z( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M22 )
+  120             CONTINUE
+               END IF
+            END IF
+*
+*           ==== Vigilant deflation check ====
+*
+            MSTART = MTOP
+            IF( KRCOL+3*( MSTART-1 ).LT.KTOP )
+     $         MSTART = MSTART + 1
+            MEND = MBOT
+            IF( BMP22 )
+     $         MEND = MEND + 1
+            IF( KRCOL.EQ.KBOT-2 )
+     $         MEND = MEND + 1
+            DO 130 M = MSTART, MEND
+               K = MIN( KBOT-1, KRCOL+3*( M-1 ) )
+*
+*              ==== The following convergence test requires that
+*              .    the tradition small-compared-to-nearby-diagonals
+*              .    criterion and the Ahues & Tisseur (LAWN 122, 1997)
+*              .    criteria both be satisfied.  The latter improves
+*              .    accuracy in some examples. Falling back on an
+*              .    alternate convergence criterion when TST1 or TST2
+*              .    is zero (as done here) is traditional but probably 
+*              .    unnecessary. ====
+*
+               IF( H( K+1, K ).NE.ZERO ) THEN
+                  TST1 = ABS( H( K, K ) ) + ABS( H( K+1, K+1 ) )
+                  IF( TST1.EQ.ZERO ) THEN
+                     IF( K.GE.KTOP+1 )
+     $                  TST1 = TST1 + ABS( H( K, K-1 ) )
+                     IF( K.GE.KTOP+2 )
+     $                  TST1 = TST1 + ABS( H( K, K-2 ) )
+                     IF( K.GE.KTOP+3 )
+     $                  TST1 = TST1 + ABS( H( K, K-3 ) )
+                     IF( K.LE.KBOT-2 )
+     $                  TST1 = TST1 + ABS( H( K+2, K+1 ) )
+                     IF( K.LE.KBOT-3 )
+     $                  TST1 = TST1 + ABS( H( K+3, K+1 ) )
+                     IF( K.LE.KBOT-4 )
+     $                  TST1 = TST1 + ABS( H( K+4, K+1 ) )
+                  END IF
+                  IF( ABS( H( K+1, K ) ).LE.MAX( SMLNUM, ULP*TST1 ) )
+     $                 THEN
+                     H12 = MAX( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) )
+                     H21 = MIN( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) )
+                     H11 = MAX( ABS( H( K+1, K+1 ) ),
+     $                     ABS( H( K, K )-H( K+1, K+1 ) ) )
+                     H22 = MIN( ABS( H( K+1, K+1 ) ),
+     $                     ABS( H( K, K )-H( K+1, K+1 ) ) )
+                     SCL = H11 + H12
+                     TST2 = H22*( H11 / SCL )
+*
+                     IF( TST2.EQ.ZERO .OR. H21*( H12 / SCL ).LE.
+     $                   MAX( SMLNUM, ULP*TST2 ) )H( K+1, K ) = ZERO
+                  END IF
+               END IF
+  130       CONTINUE
+*
+*           ==== Fill in the last row of each bulge. ====
+*
+            MEND = MIN( NBMPS, ( KBOT-KRCOL-1 ) / 3 )
+            DO 140 M = MTOP, MEND
+               K = KRCOL + 3*( M-1 )
+               REFSUM = V( 1, M )*V( 3, M )*H( K+4, K+3 )
+               H( K+4, K+1 ) = -REFSUM
+               H( K+4, K+2 ) = -REFSUM*V( 2, M )
+               H( K+4, K+3 ) = H( K+4, K+3 ) - REFSUM*V( 3, M )
+  140       CONTINUE
+*
+*           ==== End of near-the-diagonal bulge chase. ====
+*
+  150    CONTINUE
+*
+*        ==== Use U (if accumulated) to update far-from-diagonal
+*        .    entries in H.  If required, use U to update Z as
+*        .    well. ====
+*
+         IF( ACCUM ) THEN
+            IF( WANTT ) THEN
+               JTOP = 1
+               JBOT = N
+            ELSE
+               JTOP = KTOP
+               JBOT = KBOT
+            END IF
+            IF( ( .NOT.BLK22 ) .OR. ( INCOL.LT.KTOP ) .OR.
+     $          ( NDCOL.GT.KBOT ) .OR. ( NS.LE.2 ) ) THEN
+*
+*              ==== Updates not exploiting the 2-by-2 block
+*              .    structure of U.  K1 and NU keep track of
+*              .    the location and size of U in the special
+*              .    cases of introducing bulges and chasing
+*              .    bulges off the bottom.  In these special
+*              .    cases and in case the number of shifts
+*              .    is NS = 2, there is no 2-by-2 block
+*              .    structure to exploit.  ====
+*
+               K1 = MAX( 1, KTOP-INCOL )
+               NU = ( KDU-MAX( 0, NDCOL-KBOT ) ) - K1 + 1
+*
+*              ==== Horizontal Multiply ====
+*
+               DO 160 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+                  CALL SGEMM( 'C', 'N', NU, JLEN, NU, ONE, U( K1, K1 ),
+     $                        LDU, H( INCOL+K1, JCOL ), LDH, ZERO, WH,
+     $                        LDWH )
+                  CALL SLACPY( 'ALL', NU, JLEN, WH, LDWH,
+     $                         H( INCOL+K1, JCOL ), LDH )
+  160          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 170 JROW = JTOP, MAX( KTOP, INCOL ) - 1, NV
+                  JLEN = MIN( NV, MAX( KTOP, INCOL )-JROW )
+                  CALL SGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                        H( JROW, INCOL+K1 ), LDH, U( K1, K1 ),
+     $                        LDU, ZERO, WV, LDWV )
+                  CALL SLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                         H( JROW, INCOL+K1 ), LDH )
+  170          CONTINUE
+*
+*              ==== Z multiply (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 180 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+                     CALL SGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                           Z( JROW, INCOL+K1 ), LDZ, U( K1, K1 ),
+     $                           LDU, ZERO, WV, LDWV )
+                     CALL SLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                            Z( JROW, INCOL+K1 ), LDZ )
+  180             CONTINUE
+               END IF
+            ELSE
+*
+*              ==== Updates exploiting U's 2-by-2 block structure.
+*              .    (I2, I4, J2, J4 are the last rows and columns
+*              .    of the blocks.) ====
+*
+               I2 = ( KDU+1 ) / 2
+               I4 = KDU
+               J2 = I4 - I2
+               J4 = KDU
+*
+*              ==== KZS and KNZ deal with the band of zeros
+*              .    along the diagonal of one of the triangular
+*              .    blocks. ====
+*
+               KZS = ( J4-J2 ) - ( NS+1 )
+               KNZ = NS + 1
+*
+*              ==== Horizontal multiply ====
+*
+               DO 190 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+*
+*                 ==== Copy bottom of H to top+KZS of scratch ====
+*                  (The first KZS rows get multiplied by zero.) ====
+*
+                  CALL SLACPY( 'ALL', KNZ, JLEN, H( INCOL+1+J2, JCOL ),
+     $                         LDH, WH( KZS+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL SLASET( 'ALL', KZS, JLEN, ZERO, ZERO, WH, LDWH )
+                  CALL STRMM( 'L', 'U', 'C', 'N', KNZ, JLEN, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WH( KZS+1, 1 ),
+     $                        LDWH )
+*
+*                 ==== Multiply top of H by U11' ====
+*
+                  CALL SGEMM( 'C', 'N', I2, JLEN, J2, ONE, U, LDU,
+     $                        H( INCOL+1, JCOL ), LDH, ONE, WH, LDWH )
+*
+*                 ==== Copy top of H bottom of WH ====
+*
+                  CALL SLACPY( 'ALL', J2, JLEN, H( INCOL+1, JCOL ), LDH,
+     $                         WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL STRMM( 'L', 'L', 'C', 'N', J2, JLEN, ONE,
+     $                        U( 1, I2+1 ), LDU, WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL SGEMM( 'C', 'N', I4-I2, JLEN, J4-J2, ONE,
+     $                        U( J2+1, I2+1 ), LDU,
+     $                        H( INCOL+1+J2, JCOL ), LDH, ONE,
+     $                        WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Copy it back ====
+*
+                  CALL SLACPY( 'ALL', KDU, JLEN, WH, LDWH,
+     $                         H( INCOL+1, JCOL ), LDH )
+  190          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 200 JROW = JTOP, MAX( INCOL, KTOP ) - 1, NV
+                  JLEN = MIN( NV, MAX( INCOL, KTOP )-JROW )
+*
+*                 ==== Copy right of H to scratch (the first KZS
+*                 .    columns get multiplied by zero) ====
+*
+                  CALL SLACPY( 'ALL', JLEN, KNZ, H( JROW, INCOL+1+J2 ),
+     $                         LDH, WV( 1, 1+KZS ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL SLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, LDWV )
+                  CALL STRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                        LDWV )
+*
+*                 ==== Multiply by U11 ====
+*
+                  CALL SGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                        H( JROW, INCOL+1 ), LDH, U, LDU, ONE, WV,
+     $                        LDWV )
+*
+*                 ==== Copy left of H to right of scratch ====
+*
+                  CALL SLACPY( 'ALL', JLEN, J2, H( JROW, INCOL+1 ), LDH,
+     $                         WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL STRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                        U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL SGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                        H( JROW, INCOL+1+J2 ), LDH,
+     $                        U( J2+1, I2+1 ), LDU, ONE, WV( 1, 1+I2 ),
+     $                        LDWV )
+*
+*                 ==== Copy it back ====
+*
+                  CALL SLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                         H( JROW, INCOL+1 ), LDH )
+  200          CONTINUE
+*
+*              ==== Multiply Z (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 210 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+*
+*                    ==== Copy right of Z to left of scratch (first
+*                    .     KZS columns get multiplied by zero) ====
+*
+                     CALL SLACPY( 'ALL', JLEN, KNZ,
+     $                            Z( JROW, INCOL+1+J2 ), LDZ,
+     $                            WV( 1, 1+KZS ), LDWV )
+*
+*                    ==== Multiply by U12 ====
+*
+                     CALL SLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV,
+     $                            LDWV )
+                     CALL STRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                           U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U11 ====
+*
+                     CALL SGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                           Z( JROW, INCOL+1 ), LDZ, U, LDU, ONE,
+     $                           WV, LDWV )
+*
+*                    ==== Copy left of Z to right of scratch ====
+*
+                     CALL SLACPY( 'ALL', JLEN, J2, Z( JROW, INCOL+1 ),
+     $                            LDZ, WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Multiply by U21 ====
+*
+                     CALL STRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                           U( 1, I2+1 ), LDU, WV( 1, 1+I2 ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U22 ====
+*
+                     CALL SGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                           Z( JROW, INCOL+1+J2 ), LDZ,
+     $                           U( J2+1, I2+1 ), LDU, ONE,
+     $                           WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Copy the result back to Z ====
+*
+                     CALL SLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                            Z( JROW, INCOL+1 ), LDZ )
+  210             CONTINUE
+               END IF
+            END IF
+         END IF
+  220 CONTINUE
+*
+*     ==== End of SLAQR5 ====
+*
+      END
diff --git a/libcruft/lapack/slarf.f b/libcruft/lapack/slarf.f
new file mode 100644
index 0000000..f40bd0d
--- /dev/null
+++ b/libcruft/lapack/slarf.f
@@ -0,0 +1,115 @@
+      SUBROUTINE SLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, LDC, M, N
+      REAL               TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARF applies a real elementary reflector H to a real m by n matrix
+*  C, from either the left or the right. H is represented in the form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a real scalar and v is a real vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) REAL array, dimension
+*                     (1 + (M-1)*abs(INCV)) if SIDE = 'L'
+*                  or (1 + (N-1)*abs(INCV)) if SIDE = 'R'
+*          The vector v in the representation of H. V is not used if
+*          TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) REAL
+*          The value tau in the representation of H.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SGER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C' * v
+*
+            CALL SGEMV( 'Transpose', M, N, ONE, C, LDC, V, INCV, ZERO,
+     $                  WORK, 1 )
+*
+*           C := C - v * w'
+*
+            CALL SGER( M, N, -TAU, V, INCV, WORK, 1, C, LDC )
+         END IF
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C * v
+*
+            CALL SGEMV( 'No transpose', M, N, ONE, C, LDC, V, INCV,
+     $                  ZERO, WORK, 1 )
+*
+*           C := C - w * v'
+*
+            CALL SGER( M, N, -TAU, WORK, 1, V, INCV, C, LDC )
+         END IF
+      END IF
+      RETURN
+*
+*     End of SLARF
+*
+      END
diff --git a/libcruft/lapack/slarfb.f b/libcruft/lapack/slarfb.f
new file mode 100644
index 0000000..6179ddf
--- /dev/null
+++ b/libcruft/lapack/slarfb.f
@@ -0,0 +1,587 @@
+      SUBROUTINE SLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,
+     $                   T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARFB applies a real block reflector H or its transpose H' to a
+*  real m by n matrix C, from either the left or the right.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'T': apply H' (Transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  V       (input) REAL array, dimension
+*                                (LDV,K) if STOREV = 'C'
+*                                (LDV,M) if STOREV = 'R' and SIDE = 'L'
+*                                (LDV,N) if STOREV = 'R' and SIDE = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);
+*          if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);
+*          if STOREV = 'R', LDV >= K.
+*
+*  T       (input) REAL array, dimension (LDT,K)
+*          The triangular k by k matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDA >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEMM, STRMM
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'T'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( STOREV, 'C' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1 )    (first K rows)
+*                     ( V2 )
+*           where  V1  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C1'
+*
+               DO 10 J = 1, K
+                  CALL SCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+   10          CONTINUE
+*
+*              W := W * V1
+*
+               CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2
+*
+                  CALL SGEMM( 'Transpose', 'No transpose', N, K, M-K,
+     $                        ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL STRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2 * W'
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', M-K, N, K,
+     $                        -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,
+     $                        C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 30 J = 1, K
+                  DO 20 I = 1, N
+                     C( J, I ) = C( J, I ) - WORK( I, J )
+   20             CONTINUE
+   30          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C1
+*
+               DO 40 J = 1, K
+                  CALL SCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40          CONTINUE
+*
+*              W := W * V1
+*
+               CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2
+*
+                  CALL SGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL STRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2'
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,
+     $                        C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 60 J = 1, K
+                  DO 50 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+   50             CONTINUE
+   60          CONTINUE
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1 )
+*                     ( V2 )    (last K rows)
+*           where  V2  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C2'
+*
+               DO 70 J = 1, K
+                  CALL SCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+   70          CONTINUE
+*
+*              W := W * V2
+*
+               CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1
+*
+                  CALL SGEMM( 'Transpose', 'No transpose', N, K, M-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL STRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1 * W'
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', M-K, N, K,
+     $                        -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,
+     $                     ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 90 J = 1, K
+                  DO 80 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )
+   80             CONTINUE
+   90          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C2
+*
+               DO 100 J = 1, K
+                  CALL SCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  100          CONTINUE
+*
+*              W := W * V2
+*
+               CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1
+*
+                  CALL SGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL STRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1'
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,
+     $                     ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W
+*
+               DO 120 J = 1, K
+                  DO 110 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  110             CONTINUE
+  120          CONTINUE
+            END IF
+         END IF
+*
+      ELSE IF( LSAME( STOREV, 'R' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1  V2 )    (V1: first K columns)
+*           where  V1  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C1'
+*
+               DO 130 J = 1, K
+                  CALL SCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+  130          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2'
+*
+                  CALL SGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,
+     $                        C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,
+     $                        WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL STRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2' * W'
+*
+                  CALL SGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,
+     $                        V( 1, K+1 ), LDV, WORK, LDWORK, ONE,
+     $                        C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 150 J = 1, K
+                  DO 140 I = 1, N
+                     C( J, I ) = C( J, I ) - WORK( I, J )
+  140             CONTINUE
+  150          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C1
+*
+               DO 160 J = 1, K
+                  CALL SCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+  160          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,
+     $                     ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2'
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', M, K, N-K,
+     $                        ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL STRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2
+*
+                  CALL SGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE,
+     $                        C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 180 J = 1, K
+                  DO 170 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+  170             CONTINUE
+  180          CONTINUE
+*
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1  V2 )    (V2: last K columns)
+*           where  V2  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C2'
+*
+               DO 190 J = 1, K
+                  CALL SCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+  190          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,
+     $                     ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1'
+*
+                  CALL SGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,
+     $                        C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL STRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1' * W'
+*
+                  CALL SGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,
+     $                        V, LDV, WORK, LDWORK, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 210 J = 1, K
+                  DO 200 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )
+  200             CONTINUE
+  210          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C2
+*
+               DO 220 J = 1, K
+                  CALL SCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  220          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,
+     $                     ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1'
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', M, K, N-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL STRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1
+*
+                  CALL SGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 240 J = 1, K
+                  DO 230 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  230             CONTINUE
+  240          CONTINUE
+*
+            END IF
+*
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of SLARFB
+*
+      END
diff --git a/libcruft/lapack/slarfg.f b/libcruft/lapack/slarfg.f
new file mode 100644
index 0000000..86675a9
--- /dev/null
+++ b/libcruft/lapack/slarfg.f
@@ -0,0 +1,137 @@
+      SUBROUTINE SLARFG( N, ALPHA, X, INCX, TAU )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      REAL               ALPHA, TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARFG generates a real elementary reflector H of order n, such
+*  that
+*
+*        H * ( alpha ) = ( beta ),   H' * H = I.
+*            (   x   )   (   0  )
+*
+*  where alpha and beta are scalars, and x is an (n-1)-element real
+*  vector. H is represented in the form
+*
+*        H = I - tau * ( 1 ) * ( 1 v' ) ,
+*                      ( v )
+*
+*  where tau is a real scalar and v is a real (n-1)-element
+*  vector.
+*
+*  If the elements of x are all zero, then tau = 0 and H is taken to be
+*  the unit matrix.
+*
+*  Otherwise  1 <= tau <= 2.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the elementary reflector.
+*
+*  ALPHA   (input/output) REAL
+*          On entry, the value alpha.
+*          On exit, it is overwritten with the value beta.
+*
+*  X       (input/output) REAL array, dimension
+*                         (1+(N-2)*abs(INCX))
+*          On entry, the vector x.
+*          On exit, it is overwritten with the vector v.
+*
+*  INCX    (input) INTEGER
+*          The increment between elements of X. INCX > 0.
+*
+*  TAU     (output) REAL
+*          The value tau.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J, KNT
+      REAL               BETA, RSAFMN, SAFMIN, XNORM
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLAPY2, SNRM2
+      EXTERNAL           SLAMCH, SLAPY2, SNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.1 ) THEN
+         TAU = ZERO
+         RETURN
+      END IF
+*
+      XNORM = SNRM2( N-1, X, INCX )
+*
+      IF( XNORM.EQ.ZERO ) THEN
+*
+*        H  =  I
+*
+         TAU = ZERO
+      ELSE
+*
+*        general case
+*
+         BETA = -SIGN( SLAPY2( ALPHA, XNORM ), ALPHA )
+         SAFMIN = SLAMCH( 'S' ) / SLAMCH( 'E' )
+         IF( ABS( BETA ).LT.SAFMIN ) THEN
+*
+*           XNORM, BETA may be inaccurate; scale X and recompute them
+*
+            RSAFMN = ONE / SAFMIN
+            KNT = 0
+   10       CONTINUE
+            KNT = KNT + 1
+            CALL SSCAL( N-1, RSAFMN, X, INCX )
+            BETA = BETA*RSAFMN
+            ALPHA = ALPHA*RSAFMN
+            IF( ABS( BETA ).LT.SAFMIN )
+     $         GO TO 10
+*
+*           New BETA is at most 1, at least SAFMIN
+*
+            XNORM = SNRM2( N-1, X, INCX )
+            BETA = -SIGN( SLAPY2( ALPHA, XNORM ), ALPHA )
+            TAU = ( BETA-ALPHA ) / BETA
+            CALL SSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )
+*
+*           If ALPHA is subnormal, it may lose relative accuracy
+*
+            ALPHA = BETA
+            DO 20 J = 1, KNT
+               ALPHA = ALPHA*SAFMIN
+   20       CONTINUE
+         ELSE
+            TAU = ( BETA-ALPHA ) / BETA
+            CALL SSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )
+            ALPHA = BETA
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of SLARFG
+*
+      END
diff --git a/libcruft/lapack/slarft.f b/libcruft/lapack/slarft.f
new file mode 100644
index 0000000..cd1ca19
--- /dev/null
+++ b/libcruft/lapack/slarft.f
@@ -0,0 +1,217 @@
+      SUBROUTINE SLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      REAL               T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARFT forms the triangular factor T of a real block reflector H
+*  of order n, which is defined as a product of k elementary reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) REAL array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) REAL array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*               V = (  1       )                 V = (  1 v1 v1 v1 v1 )
+*                   ( v1  1    )                     (     1 v2 v2 v2 )
+*                   ( v1 v2  1 )                     (        1 v3 v3 )
+*                   ( v1 v2 v3 )
+*                   ( v1 v2 v3 )
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*               V = ( v1 v2 v3 )                 V = ( v1 v1  1       )
+*                   ( v1 v2 v3 )                     ( v2 v2 v2  1    )
+*                   (  1 v2 v3 )                     ( v3 v3 v3 v3  1 )
+*                   (     1 v3 )
+*                   (        1 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      REAL               VII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, STRMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( LSAME( DIRECT, 'F' ) ) THEN
+         DO 20 I = 1, K
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 10 J = 1, I
+                  T( J, I ) = ZERO
+   10          CONTINUE
+            ELSE
+*
+*              general case
+*
+               VII = V( I, I )
+               V( I, I ) = ONE
+               IF( LSAME( STOREV, 'C' ) ) THEN
+*
+*                 T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i)
+*
+                  CALL SGEMV( 'Transpose', N-I+1, I-1, -TAU( I ),
+     $                        V( I, 1 ), LDV, V( I, I ), 1, ZERO,
+     $                        T( 1, I ), 1 )
+               ELSE
+*
+*                 T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)'
+*
+                  CALL SGEMV( 'No transpose', I-1, N-I+1, -TAU( I ),
+     $                        V( 1, I ), LDV, V( I, I ), LDV, ZERO,
+     $                        T( 1, I ), 1 )
+               END IF
+               V( I, I ) = VII
+*
+*              T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)
+*
+               CALL STRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,
+     $                     LDT, T( 1, I ), 1 )
+               T( I, I ) = TAU( I )
+            END IF
+   20    CONTINUE
+      ELSE
+         DO 40 I = K, 1, -1
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 30 J = I, K
+                  T( J, I ) = ZERO
+   30          CONTINUE
+            ELSE
+*
+*              general case
+*
+               IF( I.LT.K ) THEN
+                  IF( LSAME( STOREV, 'C' ) ) THEN
+                     VII = V( N-K+I, I )
+                     V( N-K+I, I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i)
+*
+                     CALL SGEMV( 'Transpose', N-K+I, K-I, -TAU( I ),
+     $                           V( 1, I+1 ), LDV, V( 1, I ), 1, ZERO,
+     $                           T( I+1, I ), 1 )
+                     V( N-K+I, I ) = VII
+                  ELSE
+                     VII = V( I, N-K+I )
+                     V( I, N-K+I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)'
+*
+                     CALL SGEMV( 'No transpose', K-I, N-K+I, -TAU( I ),
+     $                           V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                           T( I+1, I ), 1 )
+                     V( I, N-K+I ) = VII
+                  END IF
+*
+*                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+                  CALL STRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                        T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+               END IF
+               T( I, I ) = TAU( I )
+            END IF
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SLARFT
+*
+      END
diff --git a/libcruft/lapack/slarfx.f b/libcruft/lapack/slarfx.f
new file mode 100644
index 0000000..6dd164f
--- /dev/null
+++ b/libcruft/lapack/slarfx.f
@@ -0,0 +1,637 @@
+      SUBROUTINE SLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            LDC, M, N
+      REAL               TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARFX applies a real elementary reflector H to a real m by n
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a real scalar and v is a real vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix
+*
+*  This version uses inline code if H has order < 11.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) REAL array, dimension (M) if SIDE = 'L'
+*                                     or (N) if SIDE = 'R'
+*          The vector v in the representation of H.
+*
+*  TAU     (input) REAL
+*          The value tau in the representation of H.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDA >= (1,M).
+*
+*  WORK    (workspace) REAL array, dimension
+*                      (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*          WORK is not referenced if H has order < 11.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J
+      REAL               SUM, T1, T10, T2, T3, T4, T5, T6, T7, T8, T9,
+     $                   V1, V10, V2, V3, V4, V5, V6, V7, V8, V9
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SGER
+*     ..
+*     .. Executable Statements ..
+*
+      IF( TAU.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C, where H has order m.
+*
+         GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,
+     $           170, 190 )M
+*
+*        Code for general M
+*
+*        w := C'*v
+*
+         CALL SGEMV( 'Transpose', M, N, ONE, C, LDC, V, 1, ZERO, WORK,
+     $               1 )
+*
+*        C := C - tau * v * w'
+*
+         CALL SGER( M, N, -TAU, V, 1, WORK, 1, C, LDC )
+         GO TO 410
+   10    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*V( 1 )
+         DO 20 J = 1, N
+            C( 1, J ) = T1*C( 1, J )
+   20    CONTINUE
+         GO TO 410
+   30    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         DO 40 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+   40    CONTINUE
+         GO TO 410
+   50    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         DO 60 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+   60    CONTINUE
+         GO TO 410
+   70    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         DO 80 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+   80    CONTINUE
+         GO TO 410
+   90    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         DO 100 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+  100    CONTINUE
+         GO TO 410
+  110    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         DO 120 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+  120    CONTINUE
+         GO TO 410
+  130    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         DO 140 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+  140    CONTINUE
+         GO TO 410
+  150    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         DO 160 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+  160    CONTINUE
+         GO TO 410
+  170    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         DO 180 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+  180    CONTINUE
+         GO TO 410
+  190    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         V10 = V( 10 )
+         T10 = TAU*V10
+         DO 200 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J ) +
+     $            V10*C( 10, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+            C( 10, J ) = C( 10, J ) - SUM*T10
+  200    CONTINUE
+         GO TO 410
+      ELSE
+*
+*        Form  C * H, where H has order n.
+*
+         GO TO ( 210, 230, 250, 270, 290, 310, 330, 350,
+     $           370, 390 )N
+*
+*        Code for general N
+*
+*        w := C * v
+*
+         CALL SGEMV( 'No transpose', M, N, ONE, C, LDC, V, 1, ZERO,
+     $               WORK, 1 )
+*
+*        C := C - tau * w * v'
+*
+         CALL SGER( M, N, -TAU, WORK, 1, V, 1, C, LDC )
+         GO TO 410
+  210    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*V( 1 )
+         DO 220 J = 1, M
+            C( J, 1 ) = T1*C( J, 1 )
+  220    CONTINUE
+         GO TO 410
+  230    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         DO 240 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+  240    CONTINUE
+         GO TO 410
+  250    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         DO 260 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+  260    CONTINUE
+         GO TO 410
+  270    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         DO 280 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+  280    CONTINUE
+         GO TO 410
+  290    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         DO 300 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+  300    CONTINUE
+         GO TO 410
+  310    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         DO 320 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+  320    CONTINUE
+         GO TO 410
+  330    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         DO 340 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+  340    CONTINUE
+         GO TO 410
+  350    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         DO 360 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+  360    CONTINUE
+         GO TO 410
+  370    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         DO 380 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+  380    CONTINUE
+         GO TO 410
+  390    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*V1
+         V2 = V( 2 )
+         T2 = TAU*V2
+         V3 = V( 3 )
+         T3 = TAU*V3
+         V4 = V( 4 )
+         T4 = TAU*V4
+         V5 = V( 5 )
+         T5 = TAU*V5
+         V6 = V( 6 )
+         T6 = TAU*V6
+         V7 = V( 7 )
+         T7 = TAU*V7
+         V8 = V( 8 )
+         T8 = TAU*V8
+         V9 = V( 9 )
+         T9 = TAU*V9
+         V10 = V( 10 )
+         T10 = TAU*V10
+         DO 400 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 ) +
+     $            V10*C( J, 10 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+            C( J, 10 ) = C( J, 10 ) - SUM*T10
+  400    CONTINUE
+         GO TO 410
+      END IF
+  410 RETURN
+*
+*     End of SLARFX
+*
+      END
diff --git a/libcruft/lapack/slartg.f b/libcruft/lapack/slartg.f
new file mode 100644
index 0000000..4388075
--- /dev/null
+++ b/libcruft/lapack/slartg.f
@@ -0,0 +1,145 @@
+      SUBROUTINE SLARTG( F, G, CS, SN, R )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               CS, F, G, R, SN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARTG generate a plane rotation so that
+*
+*     [  CS  SN  ]  .  [ F ]  =  [ R ]   where CS**2 + SN**2 = 1.
+*     [ -SN  CS  ]     [ G ]     [ 0 ]
+*
+*  This is a slower, more accurate version of the BLAS1 routine SROTG,
+*  with the following other differences:
+*     F and G are unchanged on return.
+*     If G=0, then CS=1 and SN=0.
+*     If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any
+*        floating point operations (saves work in SBDSQR when
+*        there are zeros on the diagonal).
+*
+*  If F exceeds G in magnitude, CS will be positive.
+*
+*  Arguments
+*  =========
+*
+*  F       (input) REAL
+*          The first component of vector to be rotated.
+*
+*  G       (input) REAL
+*          The second component of vector to be rotated.
+*
+*  CS      (output) REAL
+*          The cosine of the rotation.
+*
+*  SN      (output) REAL
+*          The sine of the rotation.
+*
+*  R       (output) REAL
+*          The nonzero component of the rotated vector.
+*
+*  This version has a few statements commented out for thread safety
+*  (machine parameters are computed on each entry). 10 feb 03, SJH.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E0 )
+*     ..
+*     .. Local Scalars ..
+*     LOGICAL            FIRST
+      INTEGER            COUNT, I
+      REAL               EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, INT, LOG, MAX, SQRT
+*     ..
+*     .. Save statement ..
+*     SAVE               FIRST, SAFMX2, SAFMIN, SAFMN2
+*     ..
+*     .. Data statements ..
+*     DATA               FIRST / .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+*     IF( FIRST ) THEN
+         SAFMIN = SLAMCH( 'S' )
+         EPS = SLAMCH( 'E' )
+         SAFMN2 = SLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
+     $            LOG( SLAMCH( 'B' ) ) / TWO )
+         SAFMX2 = ONE / SAFMN2
+*        FIRST = .FALSE.
+*     END IF
+      IF( G.EQ.ZERO ) THEN
+         CS = ONE
+         SN = ZERO
+         R = F
+      ELSE IF( F.EQ.ZERO ) THEN
+         CS = ZERO
+         SN = ONE
+         R = G
+      ELSE
+         F1 = F
+         G1 = G
+         SCALE = MAX( ABS( F1 ), ABS( G1 ) )
+         IF( SCALE.GE.SAFMX2 ) THEN
+            COUNT = 0
+   10       CONTINUE
+            COUNT = COUNT + 1
+            F1 = F1*SAFMN2
+            G1 = G1*SAFMN2
+            SCALE = MAX( ABS( F1 ), ABS( G1 ) )
+            IF( SCALE.GE.SAFMX2 )
+     $         GO TO 10
+            R = SQRT( F1**2+G1**2 )
+            CS = F1 / R
+            SN = G1 / R
+            DO 20 I = 1, COUNT
+               R = R*SAFMX2
+   20       CONTINUE
+         ELSE IF( SCALE.LE.SAFMN2 ) THEN
+            COUNT = 0
+   30       CONTINUE
+            COUNT = COUNT + 1
+            F1 = F1*SAFMX2
+            G1 = G1*SAFMX2
+            SCALE = MAX( ABS( F1 ), ABS( G1 ) )
+            IF( SCALE.LE.SAFMN2 )
+     $         GO TO 30
+            R = SQRT( F1**2+G1**2 )
+            CS = F1 / R
+            SN = G1 / R
+            DO 40 I = 1, COUNT
+               R = R*SAFMN2
+   40       CONTINUE
+         ELSE
+            R = SQRT( F1**2+G1**2 )
+            CS = F1 / R
+            SN = G1 / R
+         END IF
+         IF( ABS( F ).GT.ABS( G ) .AND. CS.LT.ZERO ) THEN
+            CS = -CS
+            SN = -SN
+            R = -R
+         END IF
+      END IF
+      RETURN
+*
+*     End of SLARTG
+*
+      END
diff --git a/libcruft/lapack/slarz.f b/libcruft/lapack/slarz.f
new file mode 100644
index 0000000..1c7d948
--- /dev/null
+++ b/libcruft/lapack/slarz.f
@@ -0,0 +1,152 @@
+      SUBROUTINE SLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, L, LDC, M, N
+      REAL               TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARZ applies a real elementary reflector H to a real M-by-N
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a real scalar and v is a real vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*
+*  H is a product of k elementary reflectors as returned by STZRZF.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  L       (input) INTEGER
+*          The number of entries of the vector V containing
+*          the meaningful part of the Householder vectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) REAL array, dimension (1+(L-1)*abs(INCV))
+*          The vector v in the representation of H as returned by
+*          STZRZF. V is not used if TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) REAL
+*          The value tau in the representation of H.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SCOPY, SGEMV, SGER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:n ) = C( 1, 1:n )
+*
+            CALL SCOPY( N, C, LDC, WORK, 1 )
+*
+*           w( 1:n ) = w( 1:n ) + C( m-l+1:m, 1:n )' * v( 1:l )
+*
+            CALL SGEMV( 'Transpose', L, N, ONE, C( M-L+1, 1 ), LDC, V,
+     $                  INCV, ONE, WORK, 1 )
+*
+*           C( 1, 1:n ) = C( 1, 1:n ) - tau * w( 1:n )
+*
+            CALL SAXPY( N, -TAU, WORK, 1, C, LDC )
+*
+*           C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                               tau * v( 1:l ) * w( 1:n )'
+*
+            CALL SGER( L, N, -TAU, V, INCV, WORK, 1, C( M-L+1, 1 ),
+     $                 LDC )
+         END IF
+*
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:m ) = C( 1:m, 1 )
+*
+            CALL SCOPY( M, C, 1, WORK, 1 )
+*
+*           w( 1:m ) = w( 1:m ) + C( 1:m, n-l+1:n, 1:n ) * v( 1:l )
+*
+            CALL SGEMV( 'No transpose', M, L, ONE, C( 1, N-L+1 ), LDC,
+     $                  V, INCV, ONE, WORK, 1 )
+*
+*           C( 1:m, 1 ) = C( 1:m, 1 ) - tau * w( 1:m )
+*
+            CALL SAXPY( M, -TAU, WORK, 1, C, 1 )
+*
+*           C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                               tau * w( 1:m ) * v( 1:l )'
+*
+            CALL SGER( M, L, -TAU, WORK, 1, V, INCV, C( 1, N-L+1 ),
+     $                 LDC )
+*
+         END IF
+*
+      END IF
+*
+      RETURN
+*
+*     End of SLARZ
+*
+      END
diff --git a/libcruft/lapack/slarzb.f b/libcruft/lapack/slarzb.f
new file mode 100644
index 0000000..5d55e75
--- /dev/null
+++ b/libcruft/lapack/slarzb.f
@@ -0,0 +1,220 @@
+      SUBROUTINE SLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,
+     $                   LDV, T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, L, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARZB applies a real block reflector H or its transpose H**T to
+*  a real distributed M-by-N  C from the left or the right.
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'C': apply H' (Transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise                        (not supported yet)
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix V containing the
+*          meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) REAL array, dimension (LDV,NV).
+*          If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.
+*
+*  T       (input) REAL array, dimension (LDT,K)
+*          The triangular K-by-K matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEMM, STRMM, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLARZB', -INFO )
+         RETURN
+      END IF
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'T'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C  or  H' * C
+*
+*        W( 1:n, 1:k ) = C( 1:k, 1:n )'
+*
+         DO 10 J = 1, K
+            CALL SCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+   10    CONTINUE
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) + ...
+*                        C( m-l+1:m, 1:n )' * V( 1:k, 1:l )'
+*
+         IF( L.GT.0 )
+     $      CALL SGEMM( 'Transpose', 'Transpose', N, K, L, ONE,
+     $                  C( M-L+1, 1 ), LDC, V, LDV, ONE, WORK, LDWORK )
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) * T'  or  W( 1:m, 1:k ) * T
+*
+         CALL STRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+*
+*        C( 1:k, 1:n ) = C( 1:k, 1:n ) - W( 1:n, 1:k )'
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, K
+               C( I, J ) = C( I, J ) - WORK( J, I )
+   20       CONTINUE
+   30    CONTINUE
+*
+*        C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                            V( 1:k, 1:l )' * W( 1:n, 1:k )'
+*
+         IF( L.GT.0 )
+     $      CALL SGEMM( 'Transpose', 'Transpose', L, N, K, -ONE, V, LDV,
+     $                  WORK, LDWORK, ONE, C( M-L+1, 1 ), LDC )
+*
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form  C * H  or  C * H'
+*
+*        W( 1:m, 1:k ) = C( 1:m, 1:k )
+*
+         DO 40 J = 1, K
+            CALL SCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40    CONTINUE
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) + ...
+*                        C( 1:m, n-l+1:n ) * V( 1:k, 1:l )'
+*
+         IF( L.GT.0 )
+     $      CALL SGEMM( 'No transpose', 'Transpose', M, K, L, ONE,
+     $                  C( 1, N-L+1 ), LDC, V, LDV, ONE, WORK, LDWORK )
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) * T  or  W( 1:m, 1:k ) * T'
+*
+         CALL STRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+*
+*        C( 1:m, 1:k ) = C( 1:m, 1:k ) - W( 1:m, 1:k )
+*
+         DO 60 J = 1, K
+            DO 50 I = 1, M
+               C( I, J ) = C( I, J ) - WORK( I, J )
+   50       CONTINUE
+   60    CONTINUE
+*
+*        C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                            W( 1:m, 1:k ) * V( 1:k, 1:l )
+*
+         IF( L.GT.0 )
+     $      CALL SGEMM( 'No transpose', 'No transpose', M, L, K, -ONE,
+     $                  WORK, LDWORK, V, LDV, ONE, C( 1, N-L+1 ), LDC )
+*
+      END IF
+*
+      RETURN
+*
+*     End of SLARZB
+*
+      END
diff --git a/libcruft/lapack/slarzt.f b/libcruft/lapack/slarzt.f
new file mode 100644
index 0000000..1b29aa3
--- /dev/null
+++ b/libcruft/lapack/slarzt.f
@@ -0,0 +1,184 @@
+      SUBROUTINE SLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      REAL               T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLARZT forms the triangular factor T of a real block reflector
+*  H of order > n, which is defined as a product of k elementary
+*  reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise                        (not supported yet)
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) REAL array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) REAL array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*                                              ______V_____
+*         ( v1 v2 v3 )                        /            \
+*         ( v1 v2 v3 )                      ( v1 v1 v1 v1 v1 . . . . 1 )
+*     V = ( v1 v2 v3 )                      ( v2 v2 v2 v2 v2 . . . 1   )
+*         ( v1 v2 v3 )                      ( v3 v3 v3 v3 v3 . . 1     )
+*         ( v1 v2 v3 )
+*            .  .  .
+*            .  .  .
+*            1  .  .
+*               1  .
+*                  1
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*                                                        ______V_____
+*            1                                          /            \
+*            .  1                           ( 1 . . . . v1 v1 v1 v1 v1 )
+*            .  .  1                        ( . 1 . . . v2 v2 v2 v2 v2 )
+*            .  .  .                        ( . . 1 . . v3 v3 v3 v3 v3 )
+*            .  .  .
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*     V = ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, STRMV, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -2
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLARZT', -INFO )
+         RETURN
+      END IF
+*
+      DO 20 I = K, 1, -1
+         IF( TAU( I ).EQ.ZERO ) THEN
+*
+*           H(i)  =  I
+*
+            DO 10 J = I, K
+               T( J, I ) = ZERO
+   10       CONTINUE
+         ELSE
+*
+*           general case
+*
+            IF( I.LT.K ) THEN
+*
+*              T(i+1:k,i) = - tau(i) * V(i+1:k,1:n) * V(i,1:n)'
+*
+               CALL SGEMV( 'No transpose', K-I, N, -TAU( I ),
+     $                     V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                     T( I+1, I ), 1 )
+*
+*              T(i+1:k,i) = T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+               CALL STRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                     T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+            END IF
+            T( I, I ) = TAU( I )
+         END IF
+   20 CONTINUE
+      RETURN
+*
+*     End of SLARZT
+*
+      END
diff --git a/libcruft/lapack/slas2.f b/libcruft/lapack/slas2.f
new file mode 100644
index 0000000..6e3ab07
--- /dev/null
+++ b/libcruft/lapack/slas2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE SLAS2( F, G, H, SSMIN, SSMAX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               F, G, H, SSMAX, SSMIN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAS2  computes the singular values of the 2-by-2 matrix
+*     [  F   G  ]
+*     [  0   H  ].
+*  On return, SSMIN is the smaller singular value and SSMAX is the
+*  larger singular value.
+*
+*  Arguments
+*  =========
+*
+*  F       (input) REAL
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  G       (input) REAL
+*          The (1,2) element of the 2-by-2 matrix.
+*
+*  H       (input) REAL
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  SSMIN   (output) REAL
+*          The smaller singular value.
+*
+*  SSMAX   (output) REAL
+*          The larger singular value.
+*
+*  Further Details
+*  ===============
+*
+*  Barring over/underflow, all output quantities are correct to within
+*  a few units in the last place (ulps), even in the absence of a guard
+*  digit in addition/subtraction.
+*
+*  In IEEE arithmetic, the code works correctly if one matrix element is
+*  infinite.
+*
+*  Overflow will not occur unless the largest singular value itself
+*  overflows, or is within a few ulps of overflow. (On machines with
+*  partial overflow, like the Cray, overflow may occur if the largest
+*  singular value is within a factor of 2 of overflow.)
+*
+*  Underflow is harmless if underflow is gradual. Otherwise, results
+*  may correspond to a matrix modified by perturbations of size near
+*  the underflow threshold.
+*
+*  ====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               AS, AT, AU, C, FA, FHMN, FHMX, GA, HA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      FA = ABS( F )
+      GA = ABS( G )
+      HA = ABS( H )
+      FHMN = MIN( FA, HA )
+      FHMX = MAX( FA, HA )
+      IF( FHMN.EQ.ZERO ) THEN
+         SSMIN = ZERO
+         IF( FHMX.EQ.ZERO ) THEN
+            SSMAX = GA
+         ELSE
+            SSMAX = MAX( FHMX, GA )*SQRT( ONE+
+     $              ( MIN( FHMX, GA ) / MAX( FHMX, GA ) )**2 )
+         END IF
+      ELSE
+         IF( GA.LT.FHMX ) THEN
+            AS = ONE + FHMN / FHMX
+            AT = ( FHMX-FHMN ) / FHMX
+            AU = ( GA / FHMX )**2
+            C = TWO / ( SQRT( AS*AS+AU )+SQRT( AT*AT+AU ) )
+            SSMIN = FHMN*C
+            SSMAX = FHMX / C
+         ELSE
+            AU = FHMX / GA
+            IF( AU.EQ.ZERO ) THEN
+*
+*              Avoid possible harmful underflow if exponent range
+*              asymmetric (true SSMIN may not underflow even if
+*              AU underflows)
+*
+               SSMIN = ( FHMN*FHMX ) / GA
+               SSMAX = GA
+            ELSE
+               AS = ONE + FHMN / FHMX
+               AT = ( FHMX-FHMN ) / FHMX
+               C = ONE / ( SQRT( ONE+( AS*AU )**2 )+
+     $             SQRT( ONE+( AT*AU )**2 ) )
+               SSMIN = ( FHMN*C )*AU
+               SSMIN = SSMIN + SSMIN
+               SSMAX = GA / ( C+C )
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of SLAS2
+*
+      END
diff --git a/libcruft/lapack/slascl.f b/libcruft/lapack/slascl.f
new file mode 100644
index 0000000..ff19806
--- /dev/null
+++ b/libcruft/lapack/slascl.f
@@ -0,0 +1,267 @@
+      SUBROUTINE SLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TYPE
+      INTEGER            INFO, KL, KU, LDA, M, N
+      REAL               CFROM, CTO
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASCL multiplies the M by N real matrix A by the real scalar
+*  CTO/CFROM.  This is done without over/underflow as long as the final
+*  result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
+*  A may be full, upper triangular, lower triangular, upper Hessenberg,
+*  or banded.
+*
+*  Arguments
+*  =========
+*
+*  TYPE    (input) CHARACTER*1
+*          TYPE indices the storage type of the input matrix.
+*          = 'G':  A is a full matrix.
+*          = 'L':  A is a lower triangular matrix.
+*          = 'U':  A is an upper triangular matrix.
+*          = 'H':  A is an upper Hessenberg matrix.
+*          = 'B':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the lower
+*                  half stored.
+*          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the upper
+*                  half stored.
+*          = 'Z':  A is a band matrix with lower bandwidth KL and upper
+*                  bandwidth KU.
+*
+*  KL      (input) INTEGER
+*          The lower bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  KU      (input) INTEGER
+*          The upper bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  CFROM   (input) REAL
+*  CTO     (input) REAL
+*          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
+*          without over/underflow if the final result CTO*A(I,J)/CFROM
+*          can be represented without over/underflow.  CFROM must be
+*          nonzero.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
+*          storage type.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  INFO    (output) INTEGER
+*          0  - successful exit
+*          <0 - if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      INTEGER            I, ITYPE, J, K1, K2, K3, K4
+      REAL               BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH
+      EXTERNAL           LSAME, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+*
+      IF( LSAME( TYPE, 'G' ) ) THEN
+         ITYPE = 0
+      ELSE IF( LSAME( TYPE, 'L' ) ) THEN
+         ITYPE = 1
+      ELSE IF( LSAME( TYPE, 'U' ) ) THEN
+         ITYPE = 2
+      ELSE IF( LSAME( TYPE, 'H' ) ) THEN
+         ITYPE = 3
+      ELSE IF( LSAME( TYPE, 'B' ) ) THEN
+         ITYPE = 4
+      ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
+         ITYPE = 5
+      ELSE IF( LSAME( TYPE, 'Z' ) ) THEN
+         ITYPE = 6
+      ELSE
+         ITYPE = -1
+      END IF
+*
+      IF( ITYPE.EQ.-1 ) THEN
+         INFO = -1
+      ELSE IF( CFROM.EQ.ZERO ) THEN
+         INFO = -4
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.
+     $         ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN
+         INFO = -7
+      ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -9
+      ELSE IF( ITYPE.GE.4 ) THEN
+         IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN
+            INFO = -2
+         ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.
+     $            ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )
+     $             THEN
+            INFO = -3
+         ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.
+     $            ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.
+     $            ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN
+            INFO = -9
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASCL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. M.EQ.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+*
+      CFROMC = CFROM
+      CTOC = CTO
+*
+   10 CONTINUE
+      CFROM1 = CFROMC*SMLNUM
+      CTO1 = CTOC / BIGNUM
+      IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CFROMC = CFROM1
+      ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CTOC = CTO1
+      ELSE
+         MUL = CTOC / CFROMC
+         DONE = .TRUE.
+      END IF
+*
+      IF( ITYPE.EQ.0 ) THEN
+*
+*        Full matrix
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, M
+               A( I, J ) = A( I, J )*MUL
+   20       CONTINUE
+   30    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.1 ) THEN
+*
+*        Lower triangular matrix
+*
+         DO 50 J = 1, N
+            DO 40 I = J, M
+               A( I, J ) = A( I, J )*MUL
+   40       CONTINUE
+   50    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.2 ) THEN
+*
+*        Upper triangular matrix
+*
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( J, M )
+               A( I, J ) = A( I, J )*MUL
+   60       CONTINUE
+   70    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*        Upper Hessenberg matrix
+*
+         DO 90 J = 1, N
+            DO 80 I = 1, MIN( J+1, M )
+               A( I, J ) = A( I, J )*MUL
+   80       CONTINUE
+   90    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.4 ) THEN
+*
+*        Lower half of a symmetric band matrix
+*
+         K3 = KL + 1
+         K4 = N + 1
+         DO 110 J = 1, N
+            DO 100 I = 1, MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  100       CONTINUE
+  110    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.5 ) THEN
+*
+*        Upper half of a symmetric band matrix
+*
+         K1 = KU + 2
+         K3 = KU + 1
+         DO 130 J = 1, N
+            DO 120 I = MAX( K1-J, 1 ), K3
+               A( I, J ) = A( I, J )*MUL
+  120       CONTINUE
+  130    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.6 ) THEN
+*
+*        Band matrix
+*
+         K1 = KL + KU + 2
+         K2 = KL + 1
+         K3 = 2*KL + KU + 1
+         K4 = KL + KU + 1 + M
+         DO 150 J = 1, N
+            DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  140       CONTINUE
+  150    CONTINUE
+*
+      END IF
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of SLASCL
+*
+      END
diff --git a/libcruft/lapack/slasd0.f b/libcruft/lapack/slasd0.f
new file mode 100644
index 0000000..996d25c
--- /dev/null
+++ b/libcruft/lapack/slasd0.f
@@ -0,0 +1,228 @@
+      SUBROUTINE SLASD0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,
+     $                   WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDU, LDVT, N, SMLSIZ, SQRE
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Using a divide and conquer approach, SLASD0 computes the singular
+*  value decomposition (SVD) of a real upper bidiagonal N-by-M
+*  matrix B with diagonal D and offdiagonal E, where M = N + SQRE.
+*  The algorithm computes orthogonal matrices U and VT such that
+*  B = U * S * VT. The singular values S are overwritten on D.
+*
+*  A related subroutine, SLASDA, computes only the singular values,
+*  and optionally, the singular vectors in compact form.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         On entry, the row dimension of the upper bidiagonal matrix.
+*         This is also the dimension of the main diagonal array D.
+*
+*  SQRE   (input) INTEGER
+*         Specifies the column dimension of the bidiagonal matrix.
+*         = 0: The bidiagonal matrix has column dimension M = N;
+*         = 1: The bidiagonal matrix has column dimension M = N+1;
+*
+*  D      (input/output) REAL array, dimension (N)
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix.
+*         On exit D, if INFO = 0, contains its singular values.
+*
+*  E      (input) REAL array, dimension (M-1)
+*         Contains the subdiagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  U      (output) REAL array, dimension at least (LDQ, N)
+*         On exit, U contains the left singular vectors.
+*
+*  LDU    (input) INTEGER
+*         On entry, leading dimension of U.
+*
+*  VT     (output) REAL array, dimension at least (LDVT, M)
+*         On exit, VT' contains the right singular vectors.
+*
+*  LDVT   (input) INTEGER
+*         On entry, leading dimension of VT.
+*
+*  SMLSIZ (input) INTEGER
+*         On entry, maximum size of the subproblems at the
+*         bottom of the computation tree.
+*
+*  IWORK  (workspace) INTEGER array, dimension (8*N)
+*
+*  WORK   (workspace) REAL array, dimension (3*M**2+2*M)
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,
+     $                   J, LF, LL, LVL, M, NCC, ND, NDB1, NDIML, NDIMR,
+     $                   NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQREI
+      REAL               ALPHA, BETA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASD1, SLASDQ, SLASDT, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -2
+      END IF
+*
+      M = N + SQRE
+*
+      IF( LDU.LT.N ) THEN
+         INFO = -6
+      ELSE IF( LDVT.LT.M ) THEN
+         INFO = -8
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD0', -INFO )
+         RETURN
+      END IF
+*
+*     If the input matrix is too small, call SLASDQ to find the SVD.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         CALL SLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDVT, U, LDU, U,
+     $                LDU, WORK, INFO )
+         RETURN
+      END IF
+*
+*     Set up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+      IDXQ = NDIMR + N
+      IWK = IDXQ + N
+      CALL SLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     For the nodes on bottom level of the tree, solve
+*     their subproblems by SLASDQ.
+*
+      NDB1 = ( ND+1 ) / 2
+      NCC = 0
+      DO 30 I = NDB1, ND
+*
+*     IC : center row of each node
+*     NL : number of rows of left  subproblem
+*     NR : number of rows of right subproblem
+*     NLF: starting row of the left   subproblem
+*     NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NLP1 = NL + 1
+         NR = IWORK( NDIMR+I1 )
+         NRP1 = NR + 1
+         NLF = IC - NL
+         NRF = IC + 1
+         SQREI = 1
+         CALL SLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ), E( NLF ),
+     $                VT( NLF, NLF ), LDVT, U( NLF, NLF ), LDU,
+     $                U( NLF, NLF ), LDU, WORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         ITEMP = IDXQ + NLF - 2
+         DO 10 J = 1, NL
+            IWORK( ITEMP+J ) = J
+   10    CONTINUE
+         IF( I.EQ.ND ) THEN
+            SQREI = SQRE
+         ELSE
+            SQREI = 1
+         END IF
+         NRP1 = NR + SQREI
+         CALL SLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ), E( NRF ),
+     $                VT( NRF, NRF ), LDVT, U( NRF, NRF ), LDU,
+     $                U( NRF, NRF ), LDU, WORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         ITEMP = IDXQ + IC
+         DO 20 J = 1, NR
+            IWORK( ITEMP+J-1 ) = J
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Now conquer each subproblem bottom-up.
+*
+      DO 50 LVL = NLVL, 1, -1
+*
+*        Find the first node LF and last node LL on the
+*        current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 40 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            IF( ( SQRE.EQ.0 ) .AND. ( I.EQ.LL ) ) THEN
+               SQREI = SQRE
+            ELSE
+               SQREI = 1
+            END IF
+            IDXQC = IDXQ + NLF - 1
+            ALPHA = D( IC )
+            BETA = E( IC )
+            CALL SLASD1( NL, NR, SQREI, D( NLF ), ALPHA, BETA,
+     $                   U( NLF, NLF ), LDU, VT( NLF, NLF ), LDVT,
+     $                   IWORK( IDXQC ), IWORK( IWK ), WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+   40    CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of SLASD0
+*
+      END
diff --git a/libcruft/lapack/slasd1.f b/libcruft/lapack/slasd1.f
new file mode 100644
index 0000000..86cddee
--- /dev/null
+++ b/libcruft/lapack/slasd1.f
@@ -0,0 +1,232 @@
+      SUBROUTINE SLASD1( NL, NR, SQRE, D, ALPHA, BETA, U, LDU, VT, LDVT,
+     $                   IDXQ, IWORK, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDU, LDVT, NL, NR, SQRE
+      REAL               ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IDXQ( * ), IWORK( * )
+      REAL               D( * ), U( LDU, * ), VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASD1 computes the SVD of an upper bidiagonal N-by-M matrix B,
+*  where N = NL + NR + 1 and M = N + SQRE. SLASD1 is called from SLASD0.
+*
+*  A related subroutine SLASD7 handles the case in which the singular
+*  values (and the singular vectors in factored form) are desired.
+*
+*  SLASD1 computes the SVD as follows:
+*
+*                ( D1(in)  0    0     0 )
+*    B = U(in) * (   Z1'   a   Z2'    b ) * VT(in)
+*                (   0     0   D2(in) 0 )
+*
+*      = U(out) * ( D(out) 0) * VT(out)
+*
+*  where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M
+*  with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
+*  elsewhere; and the entry b is empty if SQRE = 0.
+*
+*  The left singular vectors of the original matrix are stored in U, and
+*  the transpose of the right singular vectors are stored in VT, and the
+*  singular values are in D.  The algorithm consists of three stages:
+*
+*     The first stage consists of deflating the size of the problem
+*     when there are multiple singular values or when there are zeros in
+*     the Z vector.  For each such occurence the dimension of the
+*     secular equation problem is reduced by one.  This stage is
+*     performed by the routine SLASD2.
+*
+*     The second stage consists of calculating the updated
+*     singular values. This is done by finding the square roots of the
+*     roots of the secular equation via the routine SLASD4 (as called
+*     by SLASD3). This routine also calculates the singular vectors of
+*     the current problem.
+*
+*     The final stage consists of computing the updated singular vectors
+*     directly using the updated singular values.  The singular vectors
+*     for the current problem are multiplied with the singular vectors
+*     from the overall problem.
+*
+*  Arguments
+*  =========
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  D      (input/output) REAL array, dimension (NL+NR+1).
+*         N = NL+NR+1
+*         On entry D(1:NL,1:NL) contains the singular values of the
+*         upper block; and D(NL+2:N) contains the singular values of
+*         the lower block. On exit D(1:N) contains the singular values
+*         of the modified matrix.
+*
+*  ALPHA  (input/output) REAL
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input/output) REAL
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  U      (input/output) REAL array, dimension (LDU,N)
+*         On entry U(1:NL, 1:NL) contains the left singular vectors of
+*         the upper block; U(NL+2:N, NL+2:N) contains the left singular
+*         vectors of the lower block. On exit U contains the left
+*         singular vectors of the bidiagonal matrix.
+*
+*  LDU    (input) INTEGER
+*         The leading dimension of the array U.  LDU >= max( 1, N ).
+*
+*  VT     (input/output) REAL array, dimension (LDVT,M)
+*         where M = N + SQRE.
+*         On entry VT(1:NL+1, 1:NL+1)' contains the right singular
+*         vectors of the upper block; VT(NL+2:M, NL+2:M)' contains
+*         the right singular vectors of the lower block. On exit
+*         VT' contains the right singular vectors of the
+*         bidiagonal matrix.
+*
+*  LDVT   (input) INTEGER
+*         The leading dimension of the array VT.  LDVT >= max( 1, M ).
+*
+*  IDXQ  (output) INTEGER array, dimension (N)
+*         This contains the permutation which will reintegrate the
+*         subproblem just solved back into sorted order, i.e.
+*         D( IDXQ( I = 1, N ) ) will be in ascending order.
+*
+*  IWORK  (workspace) INTEGER array, dimension (4*N)
+*
+*  WORK   (workspace) REAL array, dimension (3*M**2+2*M)
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+*
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            COLTYP, I, IDX, IDXC, IDXP, IQ, ISIGMA, IU2,
+     $                   IVT2, IZ, K, LDQ, LDU2, LDVT2, M, N, N1, N2
+      REAL               ORGNRM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAMRG, SLASCL, SLASD2, SLASD3, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( NL.LT.1 ) THEN
+         INFO = -1
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -3
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD1', -INFO )
+         RETURN
+      END IF
+*
+      N = NL + NR + 1
+      M = N + SQRE
+*
+*     The following values are for bookkeeping purposes only.  They are
+*     integer pointers which indicate the portion of the workspace
+*     used by a particular array in SLASD2 and SLASD3.
+*
+      LDU2 = N
+      LDVT2 = M
+*
+      IZ = 1
+      ISIGMA = IZ + M
+      IU2 = ISIGMA + N
+      IVT2 = IU2 + LDU2*N
+      IQ = IVT2 + LDVT2*M
+*
+      IDX = 1
+      IDXC = IDX + N
+      COLTYP = IDXC + N
+      IDXP = COLTYP + N
+*
+*     Scale.
+*
+      ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) )
+      D( NL+1 ) = ZERO
+      DO 10 I = 1, N
+         IF( ABS( D( I ) ).GT.ORGNRM ) THEN
+            ORGNRM = ABS( D( I ) )
+         END IF
+   10 CONTINUE
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      ALPHA = ALPHA / ORGNRM
+      BETA = BETA / ORGNRM
+*
+*     Deflate singular values.
+*
+      CALL SLASD2( NL, NR, SQRE, K, D, WORK( IZ ), ALPHA, BETA, U, LDU,
+     $             VT, LDVT, WORK( ISIGMA ), WORK( IU2 ), LDU2,
+     $             WORK( IVT2 ), LDVT2, IWORK( IDXP ), IWORK( IDX ),
+     $             IWORK( IDXC ), IDXQ, IWORK( COLTYP ), INFO )
+*
+*     Solve Secular Equation and update singular vectors.
+*
+      LDQ = K
+      CALL SLASD3( NL, NR, SQRE, K, D, WORK( IQ ), LDQ, WORK( ISIGMA ),
+     $             U, LDU, WORK( IU2 ), LDU2, VT, LDVT, WORK( IVT2 ),
+     $             LDVT2, IWORK( IDXC ), IWORK( COLTYP ), WORK( IZ ),
+     $             INFO )
+      IF( INFO.NE.0 ) THEN
+         RETURN
+      END IF
+*
+*     Unscale.
+*
+      CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+*
+*     Prepare the IDXQ sorting permutation.
+*
+      N1 = K
+      N2 = N - K
+      CALL SLAMRG( N1, N2, D, 1, -1, IDXQ )
+*
+      RETURN
+*
+*     End of SLASD1
+*
+      END
diff --git a/libcruft/lapack/slasd2.f b/libcruft/lapack/slasd2.f
new file mode 100644
index 0000000..f7e8048
--- /dev/null
+++ b/libcruft/lapack/slasd2.f
@@ -0,0 +1,512 @@
+      SUBROUTINE SLASD2( NL, NR, SQRE, K, D, Z, ALPHA, BETA, U, LDU, VT,
+     $                   LDVT, DSIGMA, U2, LDU2, VT2, LDVT2, IDXP, IDX,
+     $                   IDXC, IDXQ, COLTYP, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDU, LDU2, LDVT, LDVT2, NL, NR, SQRE
+      REAL               ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      INTEGER            COLTYP( * ), IDX( * ), IDXC( * ), IDXP( * ),
+     $                   IDXQ( * )
+      REAL               D( * ), DSIGMA( * ), U( LDU, * ),
+     $                   U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
+     $                   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASD2 merges the two sets of singular values together into a single
+*  sorted set.  Then it tries to deflate the size of the problem.
+*  There are two ways in which deflation can occur:  when two or more
+*  singular values are close together or if there is a tiny entry in the
+*  Z vector.  For each such occurrence the order of the related secular
+*  equation problem is reduced by one.
+*
+*  SLASD2 is called from SLASD1.
+*
+*  Arguments
+*  =========
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has N = NL + NR + 1 rows and
+*         M = N + SQRE >= N columns.
+*
+*  K      (output) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  D      (input/output) REAL array, dimension (N)
+*         On entry D contains the singular values of the two submatrices
+*         to be combined.  On exit D contains the trailing (N-K) updated
+*         singular values (those which were deflated) sorted into
+*         increasing order.
+*
+*  Z      (output) REAL array, dimension (N)
+*         On exit Z contains the updating row vector in the secular
+*         equation.
+*
+*  ALPHA  (input) REAL
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input) REAL
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  U      (input/output) REAL array, dimension (LDU,N)
+*         On entry U contains the left singular vectors of two
+*         submatrices in the two square blocks with corners at (1,1),
+*         (NL, NL), and (NL+2, NL+2), (N,N).
+*         On exit U contains the trailing (N-K) updated left singular
+*         vectors (those which were deflated) in its last N-K columns.
+*
+*  LDU    (input) INTEGER
+*         The leading dimension of the array U.  LDU >= N.
+*
+*  VT     (input/output) REAL array, dimension (LDVT,M)
+*         On entry VT' contains the right singular vectors of two
+*         submatrices in the two square blocks with corners at (1,1),
+*         (NL+1, NL+1), and (NL+2, NL+2), (M,M).
+*         On exit VT' contains the trailing (N-K) updated right singular
+*         vectors (those which were deflated) in its last N-K columns.
+*         In case SQRE =1, the last row of VT spans the right null
+*         space.
+*
+*  LDVT   (input) INTEGER
+*         The leading dimension of the array VT.  LDVT >= M.
+*
+*  DSIGMA (output) REAL array, dimension (N)
+*         Contains a copy of the diagonal elements (K-1 singular values
+*         and one zero) in the secular equation.
+*
+*  U2     (output) REAL array, dimension (LDU2,N)
+*         Contains a copy of the first K-1 left singular vectors which
+*         will be used by SLASD3 in a matrix multiply (SGEMM) to solve
+*         for the new left singular vectors. U2 is arranged into four
+*         blocks. The first block contains a column with 1 at NL+1 and
+*         zero everywhere else; the second block contains non-zero
+*         entries only at and above NL; the third contains non-zero
+*         entries only below NL+1; and the fourth is dense.
+*
+*  LDU2   (input) INTEGER
+*         The leading dimension of the array U2.  LDU2 >= N.
+*
+*  VT2    (output) REAL array, dimension (LDVT2,N)
+*         VT2' contains a copy of the first K right singular vectors
+*         which will be used by SLASD3 in a matrix multiply (SGEMM) to
+*         solve for the new right singular vectors. VT2 is arranged into
+*         three blocks. The first block contains a row that corresponds
+*         to the special 0 diagonal element in SIGMA; the second block
+*         contains non-zeros only at and before NL +1; the third block
+*         contains non-zeros only at and after  NL +2.
+*
+*  LDVT2  (input) INTEGER
+*         The leading dimension of the array VT2.  LDVT2 >= M.
+*
+*  IDXP   (workspace) INTEGER array, dimension (N)
+*         This will contain the permutation used to place deflated
+*         values of D at the end of the array. On output IDXP(2:K)
+*         points to the nondeflated D-values and IDXP(K+1:N)
+*         points to the deflated singular values.
+*
+*  IDX    (workspace) INTEGER array, dimension (N)
+*         This will contain the permutation used to sort the contents of
+*         D into ascending order.
+*
+*  IDXC   (output) INTEGER array, dimension (N)
+*         This will contain the permutation used to arrange the columns
+*         of the deflated U matrix into three groups:  the first group
+*         contains non-zero entries only at and above NL, the second
+*         contains non-zero entries only below NL+2, and the third is
+*         dense.
+*
+*  IDXQ   (input/output) INTEGER array, dimension (N)
+*         This contains the permutation which separately sorts the two
+*         sub-problems in D into ascending order.  Note that entries in
+*         the first hlaf of this permutation must first be moved one
+*         position backward; and entries in the second half
+*         must first have NL+1 added to their values.
+*
+*  COLTYP (workspace/output) INTEGER array, dimension (N)
+*         As workspace, this will contain a label which will indicate
+*         which of the following types a column in the U2 matrix or a
+*         row in the VT2 matrix is:
+*         1 : non-zero in the upper half only
+*         2 : non-zero in the lower half only
+*         3 : dense
+*         4 : deflated
+*
+*         On exit, it is an array of dimension 4, with COLTYP(I) being
+*         the dimension of the I-th type columns.
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO, EIGHT
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0,
+     $                   EIGHT = 8.0E+0 )
+*     ..
+*     .. Local Arrays ..
+      INTEGER            CTOT( 4 ), PSM( 4 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            CT, I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M,
+     $                   N, NLP1, NLP2
+      REAL               C, EPS, HLFTOL, S, TAU, TOL, Z1
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLAPY2
+      EXTERNAL           SLAMCH, SLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLACPY, SLAMRG, SLASET, SROT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( NL.LT.1 ) THEN
+         INFO = -1
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THEN
+         INFO = -3
+      END IF
+*
+      N = NL + NR + 1
+      M = N + SQRE
+*
+      IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDVT.LT.M ) THEN
+         INFO = -12
+      ELSE IF( LDU2.LT.N ) THEN
+         INFO = -15
+      ELSE IF( LDVT2.LT.M ) THEN
+         INFO = -17
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD2', -INFO )
+         RETURN
+      END IF
+*
+      NLP1 = NL + 1
+      NLP2 = NL + 2
+*
+*     Generate the first part of the vector Z; and move the singular
+*     values in the first part of D one position backward.
+*
+      Z1 = ALPHA*VT( NLP1, NLP1 )
+      Z( 1 ) = Z1
+      DO 10 I = NL, 1, -1
+         Z( I+1 ) = ALPHA*VT( I, NLP1 )
+         D( I+1 ) = D( I )
+         IDXQ( I+1 ) = IDXQ( I ) + 1
+   10 CONTINUE
+*
+*     Generate the second part of the vector Z.
+*
+      DO 20 I = NLP2, M
+         Z( I ) = BETA*VT( I, NLP2 )
+   20 CONTINUE
+*
+*     Initialize some reference arrays.
+*
+      DO 30 I = 2, NLP1
+         COLTYP( I ) = 1
+   30 CONTINUE
+      DO 40 I = NLP2, N
+         COLTYP( I ) = 2
+   40 CONTINUE
+*
+*     Sort the singular values into increasing order
+*
+      DO 50 I = NLP2, N
+         IDXQ( I ) = IDXQ( I ) + NLP1
+   50 CONTINUE
+*
+*     DSIGMA, IDXC, IDXC, and the first column of U2
+*     are used as storage space.
+*
+      DO 60 I = 2, N
+         DSIGMA( I ) = D( IDXQ( I ) )
+         U2( I, 1 ) = Z( IDXQ( I ) )
+         IDXC( I ) = COLTYP( IDXQ( I ) )
+   60 CONTINUE
+*
+      CALL SLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )
+*
+      DO 70 I = 2, N
+         IDXI = 1 + IDX( I )
+         D( I ) = DSIGMA( IDXI )
+         Z( I ) = U2( IDXI, 1 )
+         COLTYP( I ) = IDXC( IDXI )
+   70 CONTINUE
+*
+*     Calculate the allowable deflation tolerance
+*
+      EPS = SLAMCH( 'Epsilon' )
+      TOL = MAX( ABS( ALPHA ), ABS( BETA ) )
+      TOL = EIGHT*EPS*MAX( ABS( D( N ) ), TOL )
+*
+*     There are 2 kinds of deflation -- first a value in the z-vector
+*     is small, second two (or more) singular values are very close
+*     together (their difference is small).
+*
+*     If the value in the z-vector is small, we simply permute the
+*     array so that the corresponding singular value is moved to the
+*     end.
+*
+*     If two values in the D-vector are close, we perform a two-sided
+*     rotation designed to make one of the corresponding z-vector
+*     entries zero, and then permute the array so that the deflated
+*     singular value is moved to the end.
+*
+*     If there are multiple singular values then the problem deflates.
+*     Here the number of equal singular values are found.  As each equal
+*     singular value is found, an elementary reflector is computed to
+*     rotate the corresponding singular subspace so that the
+*     corresponding components of Z are zero in this new basis.
+*
+      K = 1
+      K2 = N + 1
+      DO 80 J = 2, N
+         IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*           Deflate due to small z component.
+*
+            K2 = K2 - 1
+            IDXP( K2 ) = J
+            COLTYP( J ) = 4
+            IF( J.EQ.N )
+     $         GO TO 120
+         ELSE
+            JPREV = J
+            GO TO 90
+         END IF
+   80 CONTINUE
+   90 CONTINUE
+      J = JPREV
+  100 CONTINUE
+      J = J + 1
+      IF( J.GT.N )
+     $   GO TO 110
+      IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*        Deflate due to small z component.
+*
+         K2 = K2 - 1
+         IDXP( K2 ) = J
+         COLTYP( J ) = 4
+      ELSE
+*
+*        Check if singular values are close enough to allow deflation.
+*
+         IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN
+*
+*           Deflation is possible.
+*
+            S = Z( JPREV )
+            C = Z( J )
+*
+*           Find sqrt(a**2+b**2) without overflow or
+*           destructive underflow.
+*
+            TAU = SLAPY2( C, S )
+            C = C / TAU
+            S = -S / TAU
+            Z( J ) = TAU
+            Z( JPREV ) = ZERO
+*
+*           Apply back the Givens rotation to the left and right
+*           singular vector matrices.
+*
+            IDXJP = IDXQ( IDX( JPREV )+1 )
+            IDXJ = IDXQ( IDX( J )+1 )
+            IF( IDXJP.LE.NLP1 ) THEN
+               IDXJP = IDXJP - 1
+            END IF
+            IF( IDXJ.LE.NLP1 ) THEN
+               IDXJ = IDXJ - 1
+            END IF
+            CALL SROT( N, U( 1, IDXJP ), 1, U( 1, IDXJ ), 1, C, S )
+            CALL SROT( M, VT( IDXJP, 1 ), LDVT, VT( IDXJ, 1 ), LDVT, C,
+     $                 S )
+            IF( COLTYP( J ).NE.COLTYP( JPREV ) ) THEN
+               COLTYP( J ) = 3
+            END IF
+            COLTYP( JPREV ) = 4
+            K2 = K2 - 1
+            IDXP( K2 ) = JPREV
+            JPREV = J
+         ELSE
+            K = K + 1
+            U2( K, 1 ) = Z( JPREV )
+            DSIGMA( K ) = D( JPREV )
+            IDXP( K ) = JPREV
+            JPREV = J
+         END IF
+      END IF
+      GO TO 100
+  110 CONTINUE
+*
+*     Record the last singular value.
+*
+      K = K + 1
+      U2( K, 1 ) = Z( JPREV )
+      DSIGMA( K ) = D( JPREV )
+      IDXP( K ) = JPREV
+*
+  120 CONTINUE
+*
+*     Count up the total number of the various types of columns, then
+*     form a permutation which positions the four column types into
+*     four groups of uniform structure (although one or more of these
+*     groups may be empty).
+*
+      DO 130 J = 1, 4
+         CTOT( J ) = 0
+  130 CONTINUE
+      DO 140 J = 2, N
+         CT = COLTYP( J )
+         CTOT( CT ) = CTOT( CT ) + 1
+  140 CONTINUE
+*
+*     PSM(*) = Position in SubMatrix (of types 1 through 4)
+*
+      PSM( 1 ) = 2
+      PSM( 2 ) = 2 + CTOT( 1 )
+      PSM( 3 ) = PSM( 2 ) + CTOT( 2 )
+      PSM( 4 ) = PSM( 3 ) + CTOT( 3 )
+*
+*     Fill out the IDXC array so that the permutation which it induces
+*     will place all type-1 columns first, all type-2 columns next,
+*     then all type-3's, and finally all type-4's, starting from the
+*     second column. This applies similarly to the rows of VT.
+*
+      DO 150 J = 2, N
+         JP = IDXP( J )
+         CT = COLTYP( JP )
+         IDXC( PSM( CT ) ) = J
+         PSM( CT ) = PSM( CT ) + 1
+  150 CONTINUE
+*
+*     Sort the singular values and corresponding singular vectors into
+*     DSIGMA, U2, and VT2 respectively.  The singular values/vectors
+*     which were not deflated go into the first K slots of DSIGMA, U2,
+*     and VT2 respectively, while those which were deflated go into the
+*     last N - K slots, except that the first column/row will be treated
+*     separately.
+*
+      DO 160 J = 2, N
+         JP = IDXP( J )
+         DSIGMA( J ) = D( JP )
+         IDXJ = IDXQ( IDX( IDXP( IDXC( J ) ) )+1 )
+         IF( IDXJ.LE.NLP1 ) THEN
+            IDXJ = IDXJ - 1
+         END IF
+         CALL SCOPY( N, U( 1, IDXJ ), 1, U2( 1, J ), 1 )
+         CALL SCOPY( M, VT( IDXJ, 1 ), LDVT, VT2( J, 1 ), LDVT2 )
+  160 CONTINUE
+*
+*     Determine DSIGMA(1), DSIGMA(2) and Z(1)
+*
+      DSIGMA( 1 ) = ZERO
+      HLFTOL = TOL / TWO
+      IF( ABS( DSIGMA( 2 ) ).LE.HLFTOL )
+     $   DSIGMA( 2 ) = HLFTOL
+      IF( M.GT.N ) THEN
+         Z( 1 ) = SLAPY2( Z1, Z( M ) )
+         IF( Z( 1 ).LE.TOL ) THEN
+            C = ONE
+            S = ZERO
+            Z( 1 ) = TOL
+         ELSE
+            C = Z1 / Z( 1 )
+            S = Z( M ) / Z( 1 )
+         END IF
+      ELSE
+         IF( ABS( Z1 ).LE.TOL ) THEN
+            Z( 1 ) = TOL
+         ELSE
+            Z( 1 ) = Z1
+         END IF
+      END IF
+*
+*     Move the rest of the updating row to Z.
+*
+      CALL SCOPY( K-1, U2( 2, 1 ), 1, Z( 2 ), 1 )
+*
+*     Determine the first column of U2, the first row of VT2 and the
+*     last row of VT.
+*
+      CALL SLASET( 'A', N, 1, ZERO, ZERO, U2, LDU2 )
+      U2( NLP1, 1 ) = ONE
+      IF( M.GT.N ) THEN
+         DO 170 I = 1, NLP1
+            VT( M, I ) = -S*VT( NLP1, I )
+            VT2( 1, I ) = C*VT( NLP1, I )
+  170    CONTINUE
+         DO 180 I = NLP2, M
+            VT2( 1, I ) = S*VT( M, I )
+            VT( M, I ) = C*VT( M, I )
+  180    CONTINUE
+      ELSE
+         CALL SCOPY( M, VT( NLP1, 1 ), LDVT, VT2( 1, 1 ), LDVT2 )
+      END IF
+      IF( M.GT.N ) THEN
+         CALL SCOPY( M, VT( M, 1 ), LDVT, VT2( M, 1 ), LDVT2 )
+      END IF
+*
+*     The deflated singular values and their corresponding vectors go
+*     into the back of D, U, and V respectively.
+*
+      IF( N.GT.K ) THEN
+         CALL SCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 )
+         CALL SLACPY( 'A', N, N-K, U2( 1, K+1 ), LDU2, U( 1, K+1 ),
+     $                LDU )
+         CALL SLACPY( 'A', N-K, M, VT2( K+1, 1 ), LDVT2, VT( K+1, 1 ),
+     $                LDVT )
+      END IF
+*
+*     Copy CTOT into COLTYP for referencing in SLASD3.
+*
+      DO 190 J = 1, 4
+         COLTYP( J ) = CTOT( J )
+  190 CONTINUE
+*
+      RETURN
+*
+*     End of SLASD2
+*
+      END
diff --git a/libcruft/lapack/slasd3.f b/libcruft/lapack/slasd3.f
new file mode 100644
index 0000000..77cf6d3
--- /dev/null
+++ b/libcruft/lapack/slasd3.f
@@ -0,0 +1,358 @@
+      SUBROUTINE SLASD3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,
+     $                   LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,
+     $                   INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
+     $                   SQRE
+*     ..
+*     .. Array Arguments ..
+      INTEGER            CTOT( * ), IDXC( * )
+      REAL               D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
+     $                   U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
+     $                   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASD3 finds all the square roots of the roots of the secular
+*  equation, as defined by the values in D and Z.  It makes the
+*  appropriate calls to SLASD4 and then updates the singular
+*  vectors by matrix multiplication.
+*
+*  This code makes very mild assumptions about floating point
+*  arithmetic. It will work on machines with a guard digit in
+*  add/subtract, or on those binary machines without guard digits
+*  which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
+*  It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  SLASD3 is called from SLASD1.
+*
+*  Arguments
+*  =========
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has N = NL + NR + 1 rows and
+*         M = N + SQRE >= N columns.
+*
+*  K      (input) INTEGER
+*         The size of the secular equation, 1 =< K = < N.
+*
+*  D      (output) REAL array, dimension(K)
+*         On exit the square roots of the roots of the secular equation,
+*         in ascending order.
+*
+*  Q      (workspace) REAL array,
+*                     dimension at least (LDQ,K).
+*
+*  LDQ    (input) INTEGER
+*         The leading dimension of the array Q.  LDQ >= K.
+*
+*  DSIGMA (input/output) REAL array, dimension(K)
+*         The first K elements of this array contain the old roots
+*         of the deflated updating problem.  These are the poles
+*         of the secular equation.
+*
+*  U      (output) REAL array, dimension (LDU, N)
+*         The last N - K columns of this matrix contain the deflated
+*         left singular vectors.
+*
+*  LDU    (input) INTEGER
+*         The leading dimension of the array U.  LDU >= N.
+*
+*  U2     (input) REAL array, dimension (LDU2, N)
+*         The first K columns of this matrix contain the non-deflated
+*         left singular vectors for the split problem.
+*
+*  LDU2   (input) INTEGER
+*         The leading dimension of the array U2.  LDU2 >= N.
+*
+*  VT     (output) REAL array, dimension (LDVT, M)
+*         The last M - K columns of VT' contain the deflated
+*         right singular vectors.
+*
+*  LDVT   (input) INTEGER
+*         The leading dimension of the array VT.  LDVT >= N.
+*
+*  VT2    (input/output) REAL array, dimension (LDVT2, N)
+*         The first K columns of VT2' contain the non-deflated
+*         right singular vectors for the split problem.
+*
+*  LDVT2  (input) INTEGER
+*         The leading dimension of the array VT2.  LDVT2 >= N.
+*
+*  IDXC   (input) INTEGER array, dimension (N)
+*         The permutation used to arrange the columns of U (and rows of
+*         VT) into three groups:  the first group contains non-zero
+*         entries only at and above (or before) NL +1; the second
+*         contains non-zero entries only at and below (or after) NL+2;
+*         and the third is dense. The first column of U and the row of
+*         VT are treated separately, however.
+*
+*         The rows of the singular vectors found by SLASD4
+*         must be likewise permuted before the matrix multiplies can
+*         take place.
+*
+*  CTOT   (input) INTEGER array, dimension (4)
+*         A count of the total number of the various types of columns
+*         in U (or rows in VT), as described in IDXC. The fourth column
+*         type is any column which has been deflated.
+*
+*  Z      (input/output) REAL array, dimension (K)
+*         The first K elements of this array contain the components
+*         of the deflation-adjusted updating row vector.
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*         > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO, NEGONE
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0,
+     $                     NEGONE = -1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1
+      REAL               RHO, TEMP
+*     ..
+*     .. External Functions ..
+      REAL               SLAMC3, SNRM2
+      EXTERNAL           SLAMC3, SNRM2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SGEMM, SLACPY, SLASCL, SLASD4, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( NL.LT.1 ) THEN
+         INFO = -1
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THEN
+         INFO = -3
+      END IF
+*
+      N = NL + NR + 1
+      M = N + SQRE
+      NLP1 = NL + 1
+      NLP2 = NL + 2
+*
+      IF( ( K.LT.1 ) .OR. ( K.GT.N ) ) THEN
+         INFO = -4
+      ELSE IF( LDQ.LT.K ) THEN
+         INFO = -7
+      ELSE IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDU2.LT.N ) THEN
+         INFO = -12
+      ELSE IF( LDVT.LT.M ) THEN
+         INFO = -14
+      ELSE IF( LDVT2.LT.M ) THEN
+         INFO = -16
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD3', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( K.EQ.1 ) THEN
+         D( 1 ) = ABS( Z( 1 ) )
+         CALL SCOPY( M, VT2( 1, 1 ), LDVT2, VT( 1, 1 ), LDVT )
+         IF( Z( 1 ).GT.ZERO ) THEN
+            CALL SCOPY( N, U2( 1, 1 ), 1, U( 1, 1 ), 1 )
+         ELSE
+            DO 10 I = 1, N
+               U( I, 1 ) = -U2( I, 1 )
+   10       CONTINUE
+         END IF
+         RETURN
+      END IF
+*
+*     Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
+*     be computed with high relative accuracy (barring over/underflow).
+*     This is a problem on machines without a guard digit in
+*     add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
+*     The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
+*     which on any of these machines zeros out the bottommost
+*     bit of DSIGMA(I) if it is 1; this makes the subsequent
+*     subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
+*     occurs. On binary machines with a guard digit (almost all
+*     machines) it does not change DSIGMA(I) at all. On hexadecimal
+*     and decimal machines with a guard digit, it slightly
+*     changes the bottommost bits of DSIGMA(I). It does not account
+*     for hexadecimal or decimal machines without guard digits
+*     (we know of none). We use a subroutine call to compute
+*     2*DSIGMA(I) to prevent optimizing compilers from eliminating
+*     this code.
+*
+      DO 20 I = 1, K
+         DSIGMA( I ) = SLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )
+   20 CONTINUE
+*
+*     Keep a copy of Z.
+*
+      CALL SCOPY( K, Z, 1, Q, 1 )
+*
+*     Normalize Z.
+*
+      RHO = SNRM2( K, Z, 1 )
+      CALL SLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )
+      RHO = RHO*RHO
+*
+*     Find the new singular values.
+*
+      DO 30 J = 1, K
+         CALL SLASD4( K, J, DSIGMA, Z, U( 1, J ), RHO, D( J ),
+     $                VT( 1, J ), INFO )
+*
+*        If the zero finder fails, the computation is terminated.
+*
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+   30 CONTINUE
+*
+*     Compute updated Z.
+*
+      DO 60 I = 1, K
+         Z( I ) = U( I, K )*VT( I, K )
+         DO 40 J = 1, I - 1
+            Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
+     $               ( DSIGMA( I )-DSIGMA( J ) ) /
+     $               ( DSIGMA( I )+DSIGMA( J ) ) )
+   40    CONTINUE
+         DO 50 J = I, K - 1
+            Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
+     $               ( DSIGMA( I )-DSIGMA( J+1 ) ) /
+     $               ( DSIGMA( I )+DSIGMA( J+1 ) ) )
+   50    CONTINUE
+         Z( I ) = SIGN( SQRT( ABS( Z( I ) ) ), Q( I, 1 ) )
+   60 CONTINUE
+*
+*     Compute left singular vectors of the modified diagonal matrix,
+*     and store related information for the right singular vectors.
+*
+      DO 90 I = 1, K
+         VT( 1, I ) = Z( 1 ) / U( 1, I ) / VT( 1, I )
+         U( 1, I ) = NEGONE
+         DO 70 J = 2, K
+            VT( J, I ) = Z( J ) / U( J, I ) / VT( J, I )
+            U( J, I ) = DSIGMA( J )*VT( J, I )
+   70    CONTINUE
+         TEMP = SNRM2( K, U( 1, I ), 1 )
+         Q( 1, I ) = U( 1, I ) / TEMP
+         DO 80 J = 2, K
+            JC = IDXC( J )
+            Q( J, I ) = U( JC, I ) / TEMP
+   80    CONTINUE
+   90 CONTINUE
+*
+*     Update the left singular vector matrix.
+*
+      IF( K.EQ.2 ) THEN
+         CALL SGEMM( 'N', 'N', N, K, K, ONE, U2, LDU2, Q, LDQ, ZERO, U,
+     $               LDU )
+         GO TO 100
+      END IF
+      IF( CTOT( 1 ).GT.0 ) THEN
+         CALL SGEMM( 'N', 'N', NL, K, CTOT( 1 ), ONE, U2( 1, 2 ), LDU2,
+     $               Q( 2, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
+         IF( CTOT( 3 ).GT.0 ) THEN
+            KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
+            CALL SGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
+     $                  LDU2, Q( KTEMP, 1 ), LDQ, ONE, U( 1, 1 ), LDU )
+         END IF
+      ELSE IF( CTOT( 3 ).GT.0 ) THEN
+         KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
+         CALL SGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
+     $               LDU2, Q( KTEMP, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
+      ELSE
+         CALL SLACPY( 'F', NL, K, U2, LDU2, U, LDU )
+      END IF
+      CALL SCOPY( K, Q( 1, 1 ), LDQ, U( NLP1, 1 ), LDU )
+      KTEMP = 2 + CTOT( 1 )
+      CTEMP = CTOT( 2 ) + CTOT( 3 )
+      CALL SGEMM( 'N', 'N', NR, K, CTEMP, ONE, U2( NLP2, KTEMP ), LDU2,
+     $            Q( KTEMP, 1 ), LDQ, ZERO, U( NLP2, 1 ), LDU )
+*
+*     Generate the right singular vectors.
+*
+  100 CONTINUE
+      DO 120 I = 1, K
+         TEMP = SNRM2( K, VT( 1, I ), 1 )
+         Q( I, 1 ) = VT( 1, I ) / TEMP
+         DO 110 J = 2, K
+            JC = IDXC( J )
+            Q( I, J ) = VT( JC, I ) / TEMP
+  110    CONTINUE
+  120 CONTINUE
+*
+*     Update the right singular vector matrix.
+*
+      IF( K.EQ.2 ) THEN
+         CALL SGEMM( 'N', 'N', K, M, K, ONE, Q, LDQ, VT2, LDVT2, ZERO,
+     $               VT, LDVT )
+         RETURN
+      END IF
+      KTEMP = 1 + CTOT( 1 )
+      CALL SGEMM( 'N', 'N', K, NLP1, KTEMP, ONE, Q( 1, 1 ), LDQ,
+     $            VT2( 1, 1 ), LDVT2, ZERO, VT( 1, 1 ), LDVT )
+      KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
+      IF( KTEMP.LE.LDVT2 )
+     $   CALL SGEMM( 'N', 'N', K, NLP1, CTOT( 3 ), ONE, Q( 1, KTEMP ),
+     $               LDQ, VT2( KTEMP, 1 ), LDVT2, ONE, VT( 1, 1 ),
+     $               LDVT )
+*
+      KTEMP = CTOT( 1 ) + 1
+      NRP1 = NR + SQRE
+      IF( KTEMP.GT.1 ) THEN
+         DO 130 I = 1, K
+            Q( I, KTEMP ) = Q( I, 1 )
+  130    CONTINUE
+         DO 140 I = NLP2, M
+            VT2( KTEMP, I ) = VT2( 1, I )
+  140    CONTINUE
+      END IF
+      CTEMP = 1 + CTOT( 2 ) + CTOT( 3 )
+      CALL SGEMM( 'N', 'N', K, NRP1, CTEMP, ONE, Q( 1, KTEMP ), LDQ,
+     $            VT2( KTEMP, NLP2 ), LDVT2, ZERO, VT( 1, NLP2 ), LDVT )
+*
+      RETURN
+*
+*     End of SLASD3
+*
+      END
diff --git a/libcruft/lapack/slasd4.f b/libcruft/lapack/slasd4.f
new file mode 100644
index 0000000..0cd7e42
--- /dev/null
+++ b/libcruft/lapack/slasd4.f
@@ -0,0 +1,890 @@
+      SUBROUTINE SLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I, INFO, N
+      REAL               RHO, SIGMA
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), DELTA( * ), WORK( * ), Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This subroutine computes the square root of the I-th updated
+*  eigenvalue of a positive symmetric rank-one modification to
+*  a positive diagonal matrix whose entries are given as the squares
+*  of the corresponding entries in the array d, and that
+*
+*         0 <= D(i) < D(j)  for  i < j
+*
+*  and that RHO > 0. This is arranged by the calling routine, and is
+*  no loss in generality.  The rank-one modified system is thus
+*
+*         diag( D ) * diag( D ) +  RHO *  Z * Z_transpose.
+*
+*  where we assume the Euclidean norm of Z is 1.
+*
+*  The method consists of approximating the rational functions in the
+*  secular equation by simpler interpolating rational functions.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The length of all arrays.
+*
+*  I      (input) INTEGER
+*         The index of the eigenvalue to be computed.  1 <= I <= N.
+*
+*  D      (input) REAL array, dimension ( N )
+*         The original eigenvalues.  It is assumed that they are in
+*         order, 0 <= D(I) < D(J)  for I < J.
+*
+*  Z      (input) REAL array, dimension (N)
+*         The components of the updating vector.
+*
+*  DELTA  (output) REAL array, dimension (N)
+*         If N .ne. 1, DELTA contains (D(j) - sigma_I) in its  j-th
+*         component.  If N = 1, then DELTA(1) = 1.  The vector DELTA
+*         contains the information necessary to construct the
+*         (singular) eigenvectors.
+*
+*  RHO    (input) REAL
+*         The scalar in the symmetric updating formula.
+*
+*  SIGMA  (output) REAL
+*         The computed sigma_I, the I-th updated eigenvalue.
+*
+*  WORK   (workspace) REAL array, dimension (N)
+*         If N .ne. 1, WORK contains (D(j) + sigma_I) in its  j-th
+*         component.  If N = 1, then WORK( 1 ) = 1.
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit
+*         > 0:  if INFO = 1, the updating process failed.
+*
+*  Internal Parameters
+*  ===================
+*
+*  Logical variable ORGATI (origin-at-i?) is used for distinguishing
+*  whether D(i) or D(i+1) is treated as the origin.
+*
+*            ORGATI = .true.    origin at i
+*            ORGATI = .false.   origin at i+1
+*
+*  Logical variable SWTCH3 (switch-for-3-poles?) is for noting
+*  if we are working with THREE poles!
+*
+*  MAXIT is the maximum number of iterations allowed for each
+*  eigenvalue.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ren-Cang Li, Computer Science Division, University of California
+*     at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 20 )
+      REAL               ZERO, ONE, TWO, THREE, FOUR, EIGHT, TEN
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0,
+     $                   THREE = 3.0E+0, FOUR = 4.0E+0, EIGHT = 8.0E+0,
+     $                   TEN = 10.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ORGATI, SWTCH, SWTCH3
+      INTEGER            II, IIM1, IIP1, IP1, ITER, J, NITER
+      REAL               A, B, C, DELSQ, DELSQ2, DPHI, DPSI, DTIIM,
+     $                   DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,
+     $                   ERRETM, ETA, PHI, PREW, PSI, RHOINV, SG2LB,
+     $                   SG2UB, TAU, TEMP, TEMP1, TEMP2, W
+*     ..
+*     .. Local Arrays ..
+      REAL               DD( 3 ), ZZ( 3 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAED6, SLASD5
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Since this routine is called in an inner loop, we do no argument
+*     checking.
+*
+*     Quick return for N=1 and 2.
+*
+      INFO = 0
+      IF( N.EQ.1 ) THEN
+*
+*        Presumably, I=1 upon entry
+*
+         SIGMA = SQRT( D( 1 )*D( 1 )+RHO*Z( 1 )*Z( 1 ) )
+         DELTA( 1 ) = ONE
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+      IF( N.EQ.2 ) THEN
+         CALL SLASD5( I, D, Z, DELTA, RHO, SIGMA, WORK )
+         RETURN
+      END IF
+*
+*     Compute machine epsilon
+*
+      EPS = SLAMCH( 'Epsilon' )
+      RHOINV = ONE / RHO
+*
+*     The case I = N
+*
+      IF( I.EQ.N ) THEN
+*
+*        Initialize some basic variables
+*
+         II = N - 1
+         NITER = 1
+*
+*        Calculate initial guess
+*
+         TEMP = RHO / TWO
+*
+*        If ||Z||_2 is not one, then TEMP should be set to
+*        RHO * ||Z||_2^2 / TWO
+*
+         TEMP1 = TEMP / ( D( N )+SQRT( D( N )*D( N )+TEMP ) )
+         DO 10 J = 1, N
+            WORK( J ) = D( J ) + D( N ) + TEMP1
+            DELTA( J ) = ( D( J )-D( N ) ) - TEMP1
+   10    CONTINUE
+*
+         PSI = ZERO
+         DO 20 J = 1, N - 2
+            PSI = PSI + Z( J )*Z( J ) / ( DELTA( J )*WORK( J ) )
+   20    CONTINUE
+*
+         C = RHOINV + PSI
+         W = C + Z( II )*Z( II ) / ( DELTA( II )*WORK( II ) ) +
+     $       Z( N )*Z( N ) / ( DELTA( N )*WORK( N ) )
+*
+         IF( W.LE.ZERO ) THEN
+            TEMP1 = SQRT( D( N )*D( N )+RHO )
+            TEMP = Z( N-1 )*Z( N-1 ) / ( ( D( N-1 )+TEMP1 )*
+     $             ( D( N )-D( N-1 )+RHO / ( D( N )+TEMP1 ) ) ) +
+     $             Z( N )*Z( N ) / RHO
+*
+*           The following TAU is to approximate
+*           SIGMA_n^2 - D( N )*D( N )
+*
+            IF( C.LE.TEMP ) THEN
+               TAU = RHO
+            ELSE
+               DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
+               A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
+               B = Z( N )*Z( N )*DELSQ
+               IF( A.LT.ZERO ) THEN
+                  TAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
+               ELSE
+                  TAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
+               END IF
+            END IF
+*
+*           It can be proved that
+*               D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU <= D(N)^2+RHO
+*
+         ELSE
+            DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
+            A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
+            B = Z( N )*Z( N )*DELSQ
+*
+*           The following TAU is to approximate
+*           SIGMA_n^2 - D( N )*D( N )
+*
+            IF( A.LT.ZERO ) THEN
+               TAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
+            ELSE
+               TAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
+            END IF
+*
+*           It can be proved that
+*           D(N)^2 < D(N)^2+TAU < SIGMA(N)^2 < D(N)^2+RHO/2
+*
+         END IF
+*
+*        The following ETA is to approximate SIGMA_n - D( N )
+*
+         ETA = TAU / ( D( N )+SQRT( D( N )*D( N )+TAU ) )
+*
+         SIGMA = D( N ) + ETA
+         DO 30 J = 1, N
+            DELTA( J ) = ( D( J )-D( I ) ) - ETA
+            WORK( J ) = D( J ) + D( I ) + ETA
+   30    CONTINUE
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 40 J = 1, II
+            TEMP = Z( J ) / ( DELTA( J )*WORK( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+   40    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         TEMP = Z( N ) / ( DELTA( N )*WORK( N ) )
+         PHI = Z( N )*TEMP
+         DPHI = TEMP*TEMP
+         ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
+     $            ABS( TAU )*( DPSI+DPHI )
+*
+         W = RHOINV + PHI + PSI
+*
+*        Test for convergence
+*
+         IF( ABS( W ).LE.EPS*ERRETM ) THEN
+            GO TO 240
+         END IF
+*
+*        Calculate the new step
+*
+         NITER = NITER + 1
+         DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
+         DTNSQ = WORK( N )*DELTA( N )
+         C = W - DTNSQ1*DPSI - DTNSQ*DPHI
+         A = ( DTNSQ+DTNSQ1 )*W - DTNSQ*DTNSQ1*( DPSI+DPHI )
+         B = DTNSQ*DTNSQ1*W
+         IF( C.LT.ZERO )
+     $      C = ABS( C )
+         IF( C.EQ.ZERO ) THEN
+            ETA = RHO - SIGMA*SIGMA
+         ELSE IF( A.GE.ZERO ) THEN
+            ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+         ELSE
+            ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
+         END IF
+*
+*        Note, eta should be positive if w is negative, and
+*        eta should be negative otherwise. However,
+*        if for some reason caused by roundoff, eta*w > 0,
+*        we simply use one Newton step instead. This way
+*        will guarantee eta*w < 0.
+*
+         IF( W*ETA.GT.ZERO )
+     $      ETA = -W / ( DPSI+DPHI )
+         TEMP = ETA - DTNSQ
+         IF( TEMP.GT.RHO )
+     $      ETA = RHO + DTNSQ
+*
+         TAU = TAU + ETA
+         ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
+         DO 50 J = 1, N
+            DELTA( J ) = DELTA( J ) - ETA
+            WORK( J ) = WORK( J ) + ETA
+   50    CONTINUE
+*
+         SIGMA = SIGMA + ETA
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 60 J = 1, II
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+   60    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         TEMP = Z( N ) / ( WORK( N )*DELTA( N ) )
+         PHI = Z( N )*TEMP
+         DPHI = TEMP*TEMP
+         ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
+     $            ABS( TAU )*( DPSI+DPHI )
+*
+         W = RHOINV + PHI + PSI
+*
+*        Main loop to update the values of the array   DELTA
+*
+         ITER = NITER + 1
+*
+         DO 90 NITER = ITER, MAXIT
+*
+*           Test for convergence
+*
+            IF( ABS( W ).LE.EPS*ERRETM ) THEN
+               GO TO 240
+            END IF
+*
+*           Calculate the new step
+*
+            DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
+            DTNSQ = WORK( N )*DELTA( N )
+            C = W - DTNSQ1*DPSI - DTNSQ*DPHI
+            A = ( DTNSQ+DTNSQ1 )*W - DTNSQ1*DTNSQ*( DPSI+DPHI )
+            B = DTNSQ1*DTNSQ*W
+            IF( A.GE.ZERO ) THEN
+               ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+            ELSE
+               ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
+            END IF
+*
+*           Note, eta should be positive if w is negative, and
+*           eta should be negative otherwise. However,
+*           if for some reason caused by roundoff, eta*w > 0,
+*           we simply use one Newton step instead. This way
+*           will guarantee eta*w < 0.
+*
+            IF( W*ETA.GT.ZERO )
+     $         ETA = -W / ( DPSI+DPHI )
+            TEMP = ETA - DTNSQ
+            IF( TEMP.LE.ZERO )
+     $         ETA = ETA / TWO
+*
+            TAU = TAU + ETA
+            ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
+            DO 70 J = 1, N
+               DELTA( J ) = DELTA( J ) - ETA
+               WORK( J ) = WORK( J ) + ETA
+   70       CONTINUE
+*
+            SIGMA = SIGMA + ETA
+*
+*           Evaluate PSI and the derivative DPSI
+*
+            DPSI = ZERO
+            PSI = ZERO
+            ERRETM = ZERO
+            DO 80 J = 1, II
+               TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+               PSI = PSI + Z( J )*TEMP
+               DPSI = DPSI + TEMP*TEMP
+               ERRETM = ERRETM + PSI
+   80       CONTINUE
+            ERRETM = ABS( ERRETM )
+*
+*           Evaluate PHI and the derivative DPHI
+*
+            TEMP = Z( N ) / ( WORK( N )*DELTA( N ) )
+            PHI = Z( N )*TEMP
+            DPHI = TEMP*TEMP
+            ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
+     $               ABS( TAU )*( DPSI+DPHI )
+*
+            W = RHOINV + PHI + PSI
+   90    CONTINUE
+*
+*        Return with INFO = 1, NITER = MAXIT and not converged
+*
+         INFO = 1
+         GO TO 240
+*
+*        End for the case I = N
+*
+      ELSE
+*
+*        The case for I < N
+*
+         NITER = 1
+         IP1 = I + 1
+*
+*        Calculate initial guess
+*
+         DELSQ = ( D( IP1 )-D( I ) )*( D( IP1 )+D( I ) )
+         DELSQ2 = DELSQ / TWO
+         TEMP = DELSQ2 / ( D( I )+SQRT( D( I )*D( I )+DELSQ2 ) )
+         DO 100 J = 1, N
+            WORK( J ) = D( J ) + D( I ) + TEMP
+            DELTA( J ) = ( D( J )-D( I ) ) - TEMP
+  100    CONTINUE
+*
+         PSI = ZERO
+         DO 110 J = 1, I - 1
+            PSI = PSI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
+  110    CONTINUE
+*
+         PHI = ZERO
+         DO 120 J = N, I + 2, -1
+            PHI = PHI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
+  120    CONTINUE
+         C = RHOINV + PSI + PHI
+         W = C + Z( I )*Z( I ) / ( WORK( I )*DELTA( I ) ) +
+     $       Z( IP1 )*Z( IP1 ) / ( WORK( IP1 )*DELTA( IP1 ) )
+*
+         IF( W.GT.ZERO ) THEN
+*
+*           d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2
+*
+*           We choose d(i) as origin.
+*
+            ORGATI = .TRUE.
+            SG2LB = ZERO
+            SG2UB = DELSQ2
+            A = C*DELSQ + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )
+            B = Z( I )*Z( I )*DELSQ
+            IF( A.GT.ZERO ) THEN
+               TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+            ELSE
+               TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+            END IF
+*
+*           TAU now is an estimation of SIGMA^2 - D( I )^2. The
+*           following, however, is the corresponding estimation of
+*           SIGMA - D( I ).
+*
+            ETA = TAU / ( D( I )+SQRT( D( I )*D( I )+TAU ) )
+         ELSE
+*
+*           (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
+*
+*           We choose d(i+1) as origin.
+*
+            ORGATI = .FALSE.
+            SG2LB = -DELSQ2
+            SG2UB = ZERO
+            A = C*DELSQ - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )
+            B = Z( IP1 )*Z( IP1 )*DELSQ
+            IF( A.LT.ZERO ) THEN
+               TAU = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )
+            ELSE
+               TAU = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )
+            END IF
+*
+*           TAU now is an estimation of SIGMA^2 - D( IP1 )^2. The
+*           following, however, is the corresponding estimation of
+*           SIGMA - D( IP1 ).
+*
+            ETA = TAU / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+
+     $            TAU ) ) )
+         END IF
+*
+         IF( ORGATI ) THEN
+            II = I
+            SIGMA = D( I ) + ETA
+            DO 130 J = 1, N
+               WORK( J ) = D( J ) + D( I ) + ETA
+               DELTA( J ) = ( D( J )-D( I ) ) - ETA
+  130       CONTINUE
+         ELSE
+            II = I + 1
+            SIGMA = D( IP1 ) + ETA
+            DO 140 J = 1, N
+               WORK( J ) = D( J ) + D( IP1 ) + ETA
+               DELTA( J ) = ( D( J )-D( IP1 ) ) - ETA
+  140       CONTINUE
+         END IF
+         IIM1 = II - 1
+         IIP1 = II + 1
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 150 J = 1, IIM1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+  150    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         DPHI = ZERO
+         PHI = ZERO
+         DO 160 J = N, IIP1, -1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PHI = PHI + Z( J )*TEMP
+            DPHI = DPHI + TEMP*TEMP
+            ERRETM = ERRETM + PHI
+  160    CONTINUE
+*
+         W = RHOINV + PHI + PSI
+*
+*        W is the value of the secular function with
+*        its ii-th element removed.
+*
+         SWTCH3 = .FALSE.
+         IF( ORGATI ) THEN
+            IF( W.LT.ZERO )
+     $         SWTCH3 = .TRUE.
+         ELSE
+            IF( W.GT.ZERO )
+     $         SWTCH3 = .TRUE.
+         END IF
+         IF( II.EQ.1 .OR. II.EQ.N )
+     $      SWTCH3 = .FALSE.
+*
+         TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+         DW = DPSI + DPHI + TEMP*TEMP
+         TEMP = Z( II )*TEMP
+         W = W + TEMP
+         ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
+     $            THREE*ABS( TEMP ) + ABS( TAU )*DW
+*
+*        Test for convergence
+*
+         IF( ABS( W ).LE.EPS*ERRETM ) THEN
+            GO TO 240
+         END IF
+*
+         IF( W.LE.ZERO ) THEN
+            SG2LB = MAX( SG2LB, TAU )
+         ELSE
+            SG2UB = MIN( SG2UB, TAU )
+         END IF
+*
+*        Calculate the new step
+*
+         NITER = NITER + 1
+         IF( .NOT.SWTCH3 ) THEN
+            DTIPSQ = WORK( IP1 )*DELTA( IP1 )
+            DTISQ = WORK( I )*DELTA( I )
+            IF( ORGATI ) THEN
+               C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
+            ELSE
+               C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
+            END IF
+            A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
+            B = DTIPSQ*DTISQ*W
+            IF( C.EQ.ZERO ) THEN
+               IF( A.EQ.ZERO ) THEN
+                  IF( ORGATI ) THEN
+                     A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )
+                  ELSE
+                     A = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI )
+                  END IF
+               END IF
+               ETA = B / A
+            ELSE IF( A.LE.ZERO ) THEN
+               ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+            ELSE
+               ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+            END IF
+         ELSE
+*
+*           Interpolation using THREE most relevant poles
+*
+            DTIIM = WORK( IIM1 )*DELTA( IIM1 )
+            DTIIP = WORK( IIP1 )*DELTA( IIP1 )
+            TEMP = RHOINV + PSI + PHI
+            IF( ORGATI ) THEN
+               TEMP1 = Z( IIM1 ) / DTIIM
+               TEMP1 = TEMP1*TEMP1
+               C = ( TEMP - DTIIP*( DPSI+DPHI ) ) -
+     $             ( D( IIM1 )-D( IIP1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
+               ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
+               IF( DPSI.LT.TEMP1 ) THEN
+                  ZZ( 3 ) = DTIIP*DTIIP*DPHI
+               ELSE
+                  ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
+               END IF
+            ELSE
+               TEMP1 = Z( IIP1 ) / DTIIP
+               TEMP1 = TEMP1*TEMP1
+               C = ( TEMP - DTIIM*( DPSI+DPHI ) ) -
+     $             ( D( IIP1 )-D( IIM1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
+               IF( DPHI.LT.TEMP1 ) THEN
+                  ZZ( 1 ) = DTIIM*DTIIM*DPSI
+               ELSE
+                  ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
+               END IF
+               ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
+            END IF
+            ZZ( 2 ) = Z( II )*Z( II )
+            DD( 1 ) = DTIIM
+            DD( 2 ) = DELTA( II )*WORK( II )
+            DD( 3 ) = DTIIP
+            CALL SLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
+            IF( INFO.NE.0 )
+     $         GO TO 240
+         END IF
+*
+*        Note, eta should be positive if w is negative, and
+*        eta should be negative otherwise. However,
+*        if for some reason caused by roundoff, eta*w > 0,
+*        we simply use one Newton step instead. This way
+*        will guarantee eta*w < 0.
+*
+         IF( W*ETA.GE.ZERO )
+     $      ETA = -W / DW
+         IF( ORGATI ) THEN
+            TEMP1 = WORK( I )*DELTA( I )
+            TEMP = ETA - TEMP1
+         ELSE
+            TEMP1 = WORK( IP1 )*DELTA( IP1 )
+            TEMP = ETA - TEMP1
+         END IF
+         IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
+            IF( W.LT.ZERO ) THEN
+               ETA = ( SG2UB-TAU ) / TWO
+            ELSE
+               ETA = ( SG2LB-TAU ) / TWO
+            END IF
+         END IF
+*
+         TAU = TAU + ETA
+         ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
+*
+         PREW = W
+*
+         SIGMA = SIGMA + ETA
+         DO 170 J = 1, N
+            WORK( J ) = WORK( J ) + ETA
+            DELTA( J ) = DELTA( J ) - ETA
+  170    CONTINUE
+*
+*        Evaluate PSI and the derivative DPSI
+*
+         DPSI = ZERO
+         PSI = ZERO
+         ERRETM = ZERO
+         DO 180 J = 1, IIM1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PSI = PSI + Z( J )*TEMP
+            DPSI = DPSI + TEMP*TEMP
+            ERRETM = ERRETM + PSI
+  180    CONTINUE
+         ERRETM = ABS( ERRETM )
+*
+*        Evaluate PHI and the derivative DPHI
+*
+         DPHI = ZERO
+         PHI = ZERO
+         DO 190 J = N, IIP1, -1
+            TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+            PHI = PHI + Z( J )*TEMP
+            DPHI = DPHI + TEMP*TEMP
+            ERRETM = ERRETM + PHI
+  190    CONTINUE
+*
+         TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+         DW = DPSI + DPHI + TEMP*TEMP
+         TEMP = Z( II )*TEMP
+         W = RHOINV + PHI + PSI + TEMP
+         ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
+     $            THREE*ABS( TEMP ) + ABS( TAU )*DW
+*
+         IF( W.LE.ZERO ) THEN
+            SG2LB = MAX( SG2LB, TAU )
+         ELSE
+            SG2UB = MIN( SG2UB, TAU )
+         END IF
+*
+         SWTCH = .FALSE.
+         IF( ORGATI ) THEN
+            IF( -W.GT.ABS( PREW ) / TEN )
+     $         SWTCH = .TRUE.
+         ELSE
+            IF( W.GT.ABS( PREW ) / TEN )
+     $         SWTCH = .TRUE.
+         END IF
+*
+*        Main loop to update the values of the array   DELTA and WORK
+*
+         ITER = NITER + 1
+*
+         DO 230 NITER = ITER, MAXIT
+*
+*           Test for convergence
+*
+            IF( ABS( W ).LE.EPS*ERRETM ) THEN
+               GO TO 240
+            END IF
+*
+*           Calculate the new step
+*
+            IF( .NOT.SWTCH3 ) THEN
+               DTIPSQ = WORK( IP1 )*DELTA( IP1 )
+               DTISQ = WORK( I )*DELTA( I )
+               IF( .NOT.SWTCH ) THEN
+                  IF( ORGATI ) THEN
+                     C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
+                  ELSE
+                     C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
+                  END IF
+               ELSE
+                  TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+                  IF( ORGATI ) THEN
+                     DPSI = DPSI + TEMP*TEMP
+                  ELSE
+                     DPHI = DPHI + TEMP*TEMP
+                  END IF
+                  C = W - DTISQ*DPSI - DTIPSQ*DPHI
+               END IF
+               A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
+               B = DTIPSQ*DTISQ*W
+               IF( C.EQ.ZERO ) THEN
+                  IF( A.EQ.ZERO ) THEN
+                     IF( .NOT.SWTCH ) THEN
+                        IF( ORGATI ) THEN
+                           A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*
+     $                         ( DPSI+DPHI )
+                        ELSE
+                           A = Z( IP1 )*Z( IP1 ) +
+     $                         DTISQ*DTISQ*( DPSI+DPHI )
+                        END IF
+                     ELSE
+                        A = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHI
+                     END IF
+                  END IF
+                  ETA = B / A
+               ELSE IF( A.LE.ZERO ) THEN
+                  ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
+               ELSE
+                  ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
+               END IF
+            ELSE
+*
+*              Interpolation using THREE most relevant poles
+*
+               DTIIM = WORK( IIM1 )*DELTA( IIM1 )
+               DTIIP = WORK( IIP1 )*DELTA( IIP1 )
+               TEMP = RHOINV + PSI + PHI
+               IF( SWTCH ) THEN
+                  C = TEMP - DTIIM*DPSI - DTIIP*DPHI
+                  ZZ( 1 ) = DTIIM*DTIIM*DPSI
+                  ZZ( 3 ) = DTIIP*DTIIP*DPHI
+               ELSE
+                  IF( ORGATI ) THEN
+                     TEMP1 = Z( IIM1 ) / DTIIM
+                     TEMP1 = TEMP1*TEMP1
+                     TEMP2 = ( D( IIM1 )-D( IIP1 ) )*
+     $                       ( D( IIM1 )+D( IIP1 ) )*TEMP1
+                     C = TEMP - DTIIP*( DPSI+DPHI ) - TEMP2
+                     ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
+                     IF( DPSI.LT.TEMP1 ) THEN
+                        ZZ( 3 ) = DTIIP*DTIIP*DPHI
+                     ELSE
+                        ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
+                     END IF
+                  ELSE
+                     TEMP1 = Z( IIP1 ) / DTIIP
+                     TEMP1 = TEMP1*TEMP1
+                     TEMP2 = ( D( IIP1 )-D( IIM1 ) )*
+     $                       ( D( IIM1 )+D( IIP1 ) )*TEMP1
+                     C = TEMP - DTIIM*( DPSI+DPHI ) - TEMP2
+                     IF( DPHI.LT.TEMP1 ) THEN
+                        ZZ( 1 ) = DTIIM*DTIIM*DPSI
+                     ELSE
+                        ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
+                     END IF
+                     ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
+                  END IF
+               END IF
+               DD( 1 ) = DTIIM
+               DD( 2 ) = DELTA( II )*WORK( II )
+               DD( 3 ) = DTIIP
+               CALL SLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 240
+            END IF
+*
+*           Note, eta should be positive if w is negative, and
+*           eta should be negative otherwise. However,
+*           if for some reason caused by roundoff, eta*w > 0,
+*           we simply use one Newton step instead. This way
+*           will guarantee eta*w < 0.
+*
+            IF( W*ETA.GE.ZERO )
+     $         ETA = -W / DW
+            IF( ORGATI ) THEN
+               TEMP1 = WORK( I )*DELTA( I )
+               TEMP = ETA - TEMP1
+            ELSE
+               TEMP1 = WORK( IP1 )*DELTA( IP1 )
+               TEMP = ETA - TEMP1
+            END IF
+            IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
+               IF( W.LT.ZERO ) THEN
+                  ETA = ( SG2UB-TAU ) / TWO
+               ELSE
+                  ETA = ( SG2LB-TAU ) / TWO
+               END IF
+            END IF
+*
+            TAU = TAU + ETA
+            ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
+*
+            SIGMA = SIGMA + ETA
+            DO 200 J = 1, N
+               WORK( J ) = WORK( J ) + ETA
+               DELTA( J ) = DELTA( J ) - ETA
+  200       CONTINUE
+*
+            PREW = W
+*
+*           Evaluate PSI and the derivative DPSI
+*
+            DPSI = ZERO
+            PSI = ZERO
+            ERRETM = ZERO
+            DO 210 J = 1, IIM1
+               TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+               PSI = PSI + Z( J )*TEMP
+               DPSI = DPSI + TEMP*TEMP
+               ERRETM = ERRETM + PSI
+  210       CONTINUE
+            ERRETM = ABS( ERRETM )
+*
+*           Evaluate PHI and the derivative DPHI
+*
+            DPHI = ZERO
+            PHI = ZERO
+            DO 220 J = N, IIP1, -1
+               TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
+               PHI = PHI + Z( J )*TEMP
+               DPHI = DPHI + TEMP*TEMP
+               ERRETM = ERRETM + PHI
+  220       CONTINUE
+*
+            TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
+            DW = DPSI + DPHI + TEMP*TEMP
+            TEMP = Z( II )*TEMP
+            W = RHOINV + PHI + PSI + TEMP
+            ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
+     $               THREE*ABS( TEMP ) + ABS( TAU )*DW
+            IF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )
+     $         SWTCH = .NOT.SWTCH
+*
+            IF( W.LE.ZERO ) THEN
+               SG2LB = MAX( SG2LB, TAU )
+            ELSE
+               SG2UB = MIN( SG2UB, TAU )
+            END IF
+*
+  230    CONTINUE
+*
+*        Return with INFO = 1, NITER = MAXIT and not converged
+*
+         INFO = 1
+*
+      END IF
+*
+  240 CONTINUE
+      RETURN
+*
+*     End of SLASD4
+*
+      END
diff --git a/libcruft/lapack/slasd5.f b/libcruft/lapack/slasd5.f
new file mode 100644
index 0000000..4442f2f
--- /dev/null
+++ b/libcruft/lapack/slasd5.f
@@ -0,0 +1,163 @@
+      SUBROUTINE SLASD5( I, D, Z, DELTA, RHO, DSIGMA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I
+      REAL               DSIGMA, RHO
+*     ..
+*     .. Array Arguments ..
+      REAL               D( 2 ), DELTA( 2 ), WORK( 2 ), Z( 2 )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This subroutine computes the square root of the I-th eigenvalue
+*  of a positive symmetric rank-one modification of a 2-by-2 diagonal
+*  matrix
+*
+*             diag( D ) * diag( D ) +  RHO *  Z * transpose(Z) .
+*
+*  The diagonal entries in the array D are assumed to satisfy
+*
+*             0 <= D(i) < D(j)  for  i < j .
+*
+*  We also assume RHO > 0 and that the Euclidean norm of the vector
+*  Z is one.
+*
+*  Arguments
+*  =========
+*
+*  I      (input) INTEGER
+*         The index of the eigenvalue to be computed.  I = 1 or I = 2.
+*
+*  D      (input) REAL array, dimension (2)
+*         The original eigenvalues.  We assume 0 <= D(1) < D(2).
+*
+*  Z      (input) REAL array, dimension (2)
+*         The components of the updating vector.
+*
+*  DELTA  (output) REAL array, dimension (2)
+*         Contains (D(j) - sigma_I) in its  j-th component.
+*         The vector DELTA contains the information necessary
+*         to construct the eigenvectors.
+*
+*  RHO    (input) REAL
+*         The scalar in the symmetric updating formula.
+*
+*  DSIGMA (output) REAL
+*         The computed sigma_I, the I-th updated eigenvalue.
+*
+*  WORK   (workspace) REAL array, dimension (2)
+*         WORK contains (D(j) + sigma_I) in its  j-th component.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ren-Cang Li, Computer Science Division, University of California
+*     at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO, THREE, FOUR
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0,
+     $                   THREE = 3.0E+0, FOUR = 4.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      REAL               B, C, DEL, DELSQ, TAU, W
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      DEL = D( 2 ) - D( 1 )
+      DELSQ = DEL*( D( 2 )+D( 1 ) )
+      IF( I.EQ.1 ) THEN
+         W = ONE + FOUR*RHO*( Z( 2 )*Z( 2 ) / ( D( 1 )+THREE*D( 2 ) )-
+     $       Z( 1 )*Z( 1 ) / ( THREE*D( 1 )+D( 2 ) ) ) / DEL
+         IF( W.GT.ZERO ) THEN
+            B = DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )
+            C = RHO*Z( 1 )*Z( 1 )*DELSQ
+*
+*           B > ZERO, always
+*
+*           The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 )
+*
+            TAU = TWO*C / ( B+SQRT( ABS( B*B-FOUR*C ) ) )
+*
+*           The following TAU is DSIGMA - D( 1 )
+*
+            TAU = TAU / ( D( 1 )+SQRT( D( 1 )*D( 1 )+TAU ) )
+            DSIGMA = D( 1 ) + TAU
+            DELTA( 1 ) = -TAU
+            DELTA( 2 ) = DEL - TAU
+            WORK( 1 ) = TWO*D( 1 ) + TAU
+            WORK( 2 ) = ( D( 1 )+TAU ) + D( 2 )
+*           DELTA( 1 ) = -Z( 1 ) / TAU
+*           DELTA( 2 ) = Z( 2 ) / ( DEL-TAU )
+         ELSE
+            B = -DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )
+            C = RHO*Z( 2 )*Z( 2 )*DELSQ
+*
+*           The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
+*
+            IF( B.GT.ZERO ) THEN
+               TAU = -TWO*C / ( B+SQRT( B*B+FOUR*C ) )
+            ELSE
+               TAU = ( B-SQRT( B*B+FOUR*C ) ) / TWO
+            END IF
+*
+*           The following TAU is DSIGMA - D( 2 )
+*
+            TAU = TAU / ( D( 2 )+SQRT( ABS( D( 2 )*D( 2 )+TAU ) ) )
+            DSIGMA = D( 2 ) + TAU
+            DELTA( 1 ) = -( DEL+TAU )
+            DELTA( 2 ) = -TAU
+            WORK( 1 ) = D( 1 ) + TAU + D( 2 )
+            WORK( 2 ) = TWO*D( 2 ) + TAU
+*           DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
+*           DELTA( 2 ) = -Z( 2 ) / TAU
+         END IF
+*        TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
+*        DELTA( 1 ) = DELTA( 1 ) / TEMP
+*        DELTA( 2 ) = DELTA( 2 ) / TEMP
+      ELSE
+*
+*        Now I=2
+*
+         B = -DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )
+         C = RHO*Z( 2 )*Z( 2 )*DELSQ
+*
+*        The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
+*
+         IF( B.GT.ZERO ) THEN
+            TAU = ( B+SQRT( B*B+FOUR*C ) ) / TWO
+         ELSE
+            TAU = TWO*C / ( -B+SQRT( B*B+FOUR*C ) )
+         END IF
+*
+*        The following TAU is DSIGMA - D( 2 )
+*
+         TAU = TAU / ( D( 2 )+SQRT( D( 2 )*D( 2 )+TAU ) )
+         DSIGMA = D( 2 ) + TAU
+         DELTA( 1 ) = -( DEL+TAU )
+         DELTA( 2 ) = -TAU
+         WORK( 1 ) = D( 1 ) + TAU + D( 2 )
+         WORK( 2 ) = TWO*D( 2 ) + TAU
+*        DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
+*        DELTA( 2 ) = -Z( 2 ) / TAU
+*        TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
+*        DELTA( 1 ) = DELTA( 1 ) / TEMP
+*        DELTA( 2 ) = DELTA( 2 ) / TEMP
+      END IF
+      RETURN
+*
+*     End of SLASD5
+*
+      END
diff --git a/libcruft/lapack/slasd6.f b/libcruft/lapack/slasd6.f
new file mode 100644
index 0000000..c211aae
--- /dev/null
+++ b/libcruft/lapack/slasd6.f
@@ -0,0 +1,305 @@
+      SUBROUTINE SLASD6( ICOMPQ, NL, NR, SQRE, D, VF, VL, ALPHA, BETA,
+     $                   IDXQ, PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM,
+     $                   LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
+     $                   NR, SQRE
+      REAL               ALPHA, BETA, C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ),
+     $                   PERM( * )
+      REAL               D( * ), DIFL( * ), DIFR( * ),
+     $                   GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
+     $                   VF( * ), VL( * ), WORK( * ), Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASD6 computes the SVD of an updated upper bidiagonal matrix B
+*  obtained by merging two smaller ones by appending a row. This
+*  routine is used only for the problem which requires all singular
+*  values and optionally singular vector matrices in factored form.
+*  B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE.
+*  A related subroutine, SLASD1, handles the case in which all singular
+*  values and singular vectors of the bidiagonal matrix are desired.
+*
+*  SLASD6 computes the SVD as follows:
+*
+*                ( D1(in)  0    0     0 )
+*    B = U(in) * (   Z1'   a   Z2'    b ) * VT(in)
+*                (   0     0   D2(in) 0 )
+*
+*      = U(out) * ( D(out) 0) * VT(out)
+*
+*  where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M
+*  with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
+*  elsewhere; and the entry b is empty if SQRE = 0.
+*
+*  The singular values of B can be computed using D1, D2, the first
+*  components of all the right singular vectors of the lower block, and
+*  the last components of all the right singular vectors of the upper
+*  block. These components are stored and updated in VF and VL,
+*  respectively, in SLASD6. Hence U and VT are not explicitly
+*  referenced.
+*
+*  The singular values are stored in D. The algorithm consists of two
+*  stages:
+*
+*        The first stage consists of deflating the size of the problem
+*        when there are multiple singular values or if there is a zero
+*        in the Z vector. For each such occurence the dimension of the
+*        secular equation problem is reduced by one. This stage is
+*        performed by the routine SLASD7.
+*
+*        The second stage consists of calculating the updated
+*        singular values. This is done by finding the roots of the
+*        secular equation via the routine SLASD4 (as called by SLASD8).
+*        This routine also updates VF and VL and computes the distances
+*        between the updated singular values and the old singular
+*        values.
+*
+*  SLASD6 is called from SLASDA.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed in
+*         factored form:
+*         = 0: Compute singular values only.
+*         = 1: Compute singular vectors in factored form as well.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block.  NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block.  NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  D      (input/output) REAL array, dimension (NL+NR+1).
+*         On entry D(1:NL,1:NL) contains the singular values of the
+*         upper block, and D(NL+2:N) contains the singular values
+*         of the lower block. On exit D(1:N) contains the singular
+*         values of the modified matrix.
+*
+*  VF     (input/output) REAL array, dimension (M)
+*         On entry, VF(1:NL+1) contains the first components of all
+*         right singular vectors of the upper block; and VF(NL+2:M)
+*         contains the first components of all right singular vectors
+*         of the lower block. On exit, VF contains the first components
+*         of all right singular vectors of the bidiagonal matrix.
+*
+*  VL     (input/output) REAL array, dimension (M)
+*         On entry, VL(1:NL+1) contains the  last components of all
+*         right singular vectors of the upper block; and VL(NL+2:M)
+*         contains the last components of all right singular vectors of
+*         the lower block. On exit, VL contains the last components of
+*         all right singular vectors of the bidiagonal matrix.
+*
+*  ALPHA  (input/output) REAL
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input/output) REAL
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  IDXQ   (output) INTEGER array, dimension (N)
+*         This contains the permutation which will reintegrate the
+*         subproblem just solved back into sorted order, i.e.
+*         D( IDXQ( I = 1, N ) ) will be in ascending order.
+*
+*  PERM   (output) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) to be applied
+*         to each block. Not referenced if ICOMPQ = 0.
+*
+*  GIVPTR (output) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem. Not referenced if ICOMPQ = 0.
+*
+*  GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of columns to take place
+*         in a Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGCOL (input) INTEGER
+*         leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (output) REAL array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value to be used in the
+*         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of GIVNUM and POLES, must be at least N.
+*
+*  POLES  (output) REAL array, dimension ( LDGNUM, 2 )
+*         On exit, POLES(1,*) is an array containing the new singular
+*         values obtained from solving the secular equation, and
+*         POLES(2,*) is an array containing the poles in the secular
+*         equation. Not referenced if ICOMPQ = 0.
+*
+*  DIFL   (output) REAL array, dimension ( N )
+*         On exit, DIFL(I) is the distance between I-th updated
+*         (undeflated) singular value and the I-th (undeflated) old
+*         singular value.
+*
+*  DIFR   (output) REAL array,
+*                  dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and
+*                  dimension ( N ) if ICOMPQ = 0.
+*         On exit, DIFR(I, 1) is the distance between I-th updated
+*         (undeflated) singular value and the I+1-th (undeflated) old
+*         singular value.
+*
+*         If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
+*         normalizing factors for the right singular vector matrix.
+*
+*         See SLASD8 for details on DIFL and DIFR.
+*
+*  Z      (output) REAL array, dimension ( M )
+*         The first elements of this array contain the components
+*         of the deflation-adjusted updating row vector.
+*
+*  K      (output) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  C      (output) REAL
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (output) REAL
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  WORK   (workspace) REAL array, dimension ( 4 * M )
+*
+*  IWORK  (workspace) INTEGER array, dimension ( 3 * N )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IDX, IDXC, IDXP, ISIGMA, IVFW, IVLW, IW, M,
+     $                   N, N1, N2
+      REAL               ORGNRM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLAMRG, SLASCL, SLASD7, SLASD8, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      N = NL + NR + 1
+      M = N + SQRE
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -14
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -16
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD6', -INFO )
+         RETURN
+      END IF
+*
+*     The following values are for bookkeeping purposes only.  They are
+*     integer pointers which indicate the portion of the workspace
+*     used by a particular array in SLASD7 and SLASD8.
+*
+      ISIGMA = 1
+      IW = ISIGMA + N
+      IVFW = IW + M
+      IVLW = IVFW + M
+*
+      IDX = 1
+      IDXC = IDX + N
+      IDXP = IDXC + N
+*
+*     Scale.
+*
+      ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) )
+      D( NL+1 ) = ZERO
+      DO 10 I = 1, N
+         IF( ABS( D( I ) ).GT.ORGNRM ) THEN
+            ORGNRM = ABS( D( I ) )
+         END IF
+   10 CONTINUE
+      CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      ALPHA = ALPHA / ORGNRM
+      BETA = BETA / ORGNRM
+*
+*     Sort and Deflate singular values.
+*
+      CALL SLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, WORK( IW ), VF,
+     $             WORK( IVFW ), VL, WORK( IVLW ), ALPHA, BETA,
+     $             WORK( ISIGMA ), IWORK( IDX ), IWORK( IDXP ), IDXQ,
+     $             PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM, C, S,
+     $             INFO )
+*
+*     Solve Secular Equation, compute DIFL, DIFR, and update VF, VL.
+*
+      CALL SLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDGNUM,
+     $             WORK( ISIGMA ), WORK( IW ), INFO )
+*
+*     Save the poles if ICOMPQ = 1.
+*
+      IF( ICOMPQ.EQ.1 ) THEN
+         CALL SCOPY( K, D, 1, POLES( 1, 1 ), 1 )
+         CALL SCOPY( K, WORK( ISIGMA ), 1, POLES( 1, 2 ), 1 )
+      END IF
+*
+*     Unscale.
+*
+      CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+*
+*     Prepare the IDXQ sorting permutation.
+*
+      N1 = K
+      N2 = N - K
+      CALL SLAMRG( N1, N2, D, 1, -1, IDXQ )
+*
+      RETURN
+*
+*     End of SLASD6
+*
+      END
diff --git a/libcruft/lapack/slasd7.f b/libcruft/lapack/slasd7.f
new file mode 100644
index 0000000..a8e67b3
--- /dev/null
+++ b/libcruft/lapack/slasd7.f
@@ -0,0 +1,444 @@
+      SUBROUTINE SLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, ZW, VF, VFW, VL,
+     $                   VLW, ALPHA, BETA, DSIGMA, IDX, IDXP, IDXQ,
+     $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
+     $                   C, S, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
+     $                   NR, SQRE
+      REAL               ALPHA, BETA, C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), IDX( * ), IDXP( * ),
+     $                   IDXQ( * ), PERM( * )
+      REAL               D( * ), DSIGMA( * ), GIVNUM( LDGNUM, * ),
+     $                   VF( * ), VFW( * ), VL( * ), VLW( * ), Z( * ),
+     $                   ZW( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASD7 merges the two sets of singular values together into a single
+*  sorted set. Then it tries to deflate the size of the problem. There
+*  are two ways in which deflation can occur:  when two or more singular
+*  values are close together or if there is a tiny entry in the Z
+*  vector. For each such occurrence the order of the related
+*  secular equation problem is reduced by one.
+*
+*  SLASD7 is called from SLASD6.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ  (input) INTEGER
+*          Specifies whether singular vectors are to be computed
+*          in compact form, as follows:
+*          = 0: Compute singular values only.
+*          = 1: Compute singular vectors of upper
+*               bidiagonal matrix in compact form.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block. NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block. NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has
+*         N = NL + NR + 1 rows and
+*         M = N + SQRE >= N columns.
+*
+*  K      (output) INTEGER
+*         Contains the dimension of the non-deflated matrix, this is
+*         the order of the related secular equation. 1 <= K <=N.
+*
+*  D      (input/output) REAL array, dimension ( N )
+*         On entry D contains the singular values of the two submatrices
+*         to be combined. On exit D contains the trailing (N-K) updated
+*         singular values (those which were deflated) sorted into
+*         increasing order.
+*
+*  Z      (output) REAL array, dimension ( M )
+*         On exit Z contains the updating row vector in the secular
+*         equation.
+*
+*  ZW     (workspace) REAL array, dimension ( M )
+*         Workspace for Z.
+*
+*  VF     (input/output) REAL array, dimension ( M )
+*         On entry, VF(1:NL+1) contains the first components of all
+*         right singular vectors of the upper block; and VF(NL+2:M)
+*         contains the first components of all right singular vectors
+*         of the lower block. On exit, VF contains the first components
+*         of all right singular vectors of the bidiagonal matrix.
+*
+*  VFW    (workspace) REAL array, dimension ( M )
+*         Workspace for VF.
+*
+*  VL     (input/output) REAL array, dimension ( M )
+*         On entry, VL(1:NL+1) contains the  last components of all
+*         right singular vectors of the upper block; and VL(NL+2:M)
+*         contains the last components of all right singular vectors
+*         of the lower block. On exit, VL contains the last components
+*         of all right singular vectors of the bidiagonal matrix.
+*
+*  VLW    (workspace) REAL array, dimension ( M )
+*         Workspace for VL.
+*
+*  ALPHA  (input) REAL
+*         Contains the diagonal element associated with the added row.
+*
+*  BETA   (input) REAL
+*         Contains the off-diagonal element associated with the added
+*         row.
+*
+*  DSIGMA (output) REAL array, dimension ( N )
+*         Contains a copy of the diagonal elements (K-1 singular values
+*         and one zero) in the secular equation.
+*
+*  IDX    (workspace) INTEGER array, dimension ( N )
+*         This will contain the permutation used to sort the contents of
+*         D into ascending order.
+*
+*  IDXP   (workspace) INTEGER array, dimension ( N )
+*         This will contain the permutation used to place deflated
+*         values of D at the end of the array. On output IDXP(2:K)
+*         points to the nondeflated D-values and IDXP(K+1:N)
+*         points to the deflated singular values.
+*
+*  IDXQ   (input) INTEGER array, dimension ( N )
+*         This contains the permutation which separately sorts the two
+*         sub-problems in D into ascending order.  Note that entries in
+*         the first half of this permutation must first be moved one
+*         position backward; and entries in the second half
+*         must first have NL+1 added to their values.
+*
+*  PERM   (output) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) to be applied
+*         to each singular block. Not referenced if ICOMPQ = 0.
+*
+*  GIVPTR (output) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem. Not referenced if ICOMPQ = 0.
+*
+*  GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of columns to take place
+*         in a Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGCOL (input) INTEGER
+*         The leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (output) REAL array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value to be used in the
+*         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of GIVNUM, must be at least N.
+*
+*  C      (output) REAL
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (output) REAL
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO, EIGHT
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0,
+     $                   EIGHT = 8.0E+0 )
+*     ..
+*     .. Local Scalars ..
+*
+      INTEGER            I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M, N,
+     $                   NLP1, NLP2
+      REAL               EPS, HLFTOL, TAU, TOL, Z1
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLAMRG, SROT, XERBLA
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLAPY2
+      EXTERNAL           SLAMCH, SLAPY2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      N = NL + NR + 1
+      M = N + SQRE
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -22
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -24
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD7', -INFO )
+         RETURN
+      END IF
+*
+      NLP1 = NL + 1
+      NLP2 = NL + 2
+      IF( ICOMPQ.EQ.1 ) THEN
+         GIVPTR = 0
+      END IF
+*
+*     Generate the first part of the vector Z and move the singular
+*     values in the first part of D one position backward.
+*
+      Z1 = ALPHA*VL( NLP1 )
+      VL( NLP1 ) = ZERO
+      TAU = VF( NLP1 )
+      DO 10 I = NL, 1, -1
+         Z( I+1 ) = ALPHA*VL( I )
+         VL( I ) = ZERO
+         VF( I+1 ) = VF( I )
+         D( I+1 ) = D( I )
+         IDXQ( I+1 ) = IDXQ( I ) + 1
+   10 CONTINUE
+      VF( 1 ) = TAU
+*
+*     Generate the second part of the vector Z.
+*
+      DO 20 I = NLP2, M
+         Z( I ) = BETA*VF( I )
+         VF( I ) = ZERO
+   20 CONTINUE
+*
+*     Sort the singular values into increasing order
+*
+      DO 30 I = NLP2, N
+         IDXQ( I ) = IDXQ( I ) + NLP1
+   30 CONTINUE
+*
+*     DSIGMA, IDXC, IDXC, and ZW are used as storage space.
+*
+      DO 40 I = 2, N
+         DSIGMA( I ) = D( IDXQ( I ) )
+         ZW( I ) = Z( IDXQ( I ) )
+         VFW( I ) = VF( IDXQ( I ) )
+         VLW( I ) = VL( IDXQ( I ) )
+   40 CONTINUE
+*
+      CALL SLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )
+*
+      DO 50 I = 2, N
+         IDXI = 1 + IDX( I )
+         D( I ) = DSIGMA( IDXI )
+         Z( I ) = ZW( IDXI )
+         VF( I ) = VFW( IDXI )
+         VL( I ) = VLW( IDXI )
+   50 CONTINUE
+*
+*     Calculate the allowable deflation tolerence
+*
+      EPS = SLAMCH( 'Epsilon' )
+      TOL = MAX( ABS( ALPHA ), ABS( BETA ) )
+      TOL = EIGHT*EIGHT*EPS*MAX( ABS( D( N ) ), TOL )
+*
+*     There are 2 kinds of deflation -- first a value in the z-vector
+*     is small, second two (or more) singular values are very close
+*     together (their difference is small).
+*
+*     If the value in the z-vector is small, we simply permute the
+*     array so that the corresponding singular value is moved to the
+*     end.
+*
+*     If two values in the D-vector are close, we perform a two-sided
+*     rotation designed to make one of the corresponding z-vector
+*     entries zero, and then permute the array so that the deflated
+*     singular value is moved to the end.
+*
+*     If there are multiple singular values then the problem deflates.
+*     Here the number of equal singular values are found.  As each equal
+*     singular value is found, an elementary reflector is computed to
+*     rotate the corresponding singular subspace so that the
+*     corresponding components of Z are zero in this new basis.
+*
+      K = 1
+      K2 = N + 1
+      DO 60 J = 2, N
+         IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*           Deflate due to small z component.
+*
+            K2 = K2 - 1
+            IDXP( K2 ) = J
+            IF( J.EQ.N )
+     $         GO TO 100
+         ELSE
+            JPREV = J
+            GO TO 70
+         END IF
+   60 CONTINUE
+   70 CONTINUE
+      J = JPREV
+   80 CONTINUE
+      J = J + 1
+      IF( J.GT.N )
+     $   GO TO 90
+      IF( ABS( Z( J ) ).LE.TOL ) THEN
+*
+*        Deflate due to small z component.
+*
+         K2 = K2 - 1
+         IDXP( K2 ) = J
+      ELSE
+*
+*        Check if singular values are close enough to allow deflation.
+*
+         IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN
+*
+*           Deflation is possible.
+*
+            S = Z( JPREV )
+            C = Z( J )
+*
+*           Find sqrt(a**2+b**2) without overflow or
+*           destructive underflow.
+*
+            TAU = SLAPY2( C, S )
+            Z( J ) = TAU
+            Z( JPREV ) = ZERO
+            C = C / TAU
+            S = -S / TAU
+*
+*           Record the appropriate Givens rotation
+*
+            IF( ICOMPQ.EQ.1 ) THEN
+               GIVPTR = GIVPTR + 1
+               IDXJP = IDXQ( IDX( JPREV )+1 )
+               IDXJ = IDXQ( IDX( J )+1 )
+               IF( IDXJP.LE.NLP1 ) THEN
+                  IDXJP = IDXJP - 1
+               END IF
+               IF( IDXJ.LE.NLP1 ) THEN
+                  IDXJ = IDXJ - 1
+               END IF
+               GIVCOL( GIVPTR, 2 ) = IDXJP
+               GIVCOL( GIVPTR, 1 ) = IDXJ
+               GIVNUM( GIVPTR, 2 ) = C
+               GIVNUM( GIVPTR, 1 ) = S
+            END IF
+            CALL SROT( 1, VF( JPREV ), 1, VF( J ), 1, C, S )
+            CALL SROT( 1, VL( JPREV ), 1, VL( J ), 1, C, S )
+            K2 = K2 - 1
+            IDXP( K2 ) = JPREV
+            JPREV = J
+         ELSE
+            K = K + 1
+            ZW( K ) = Z( JPREV )
+            DSIGMA( K ) = D( JPREV )
+            IDXP( K ) = JPREV
+            JPREV = J
+         END IF
+      END IF
+      GO TO 80
+   90 CONTINUE
+*
+*     Record the last singular value.
+*
+      K = K + 1
+      ZW( K ) = Z( JPREV )
+      DSIGMA( K ) = D( JPREV )
+      IDXP( K ) = JPREV
+*
+  100 CONTINUE
+*
+*     Sort the singular values into DSIGMA. The singular values which
+*     were not deflated go into the first K slots of DSIGMA, except
+*     that DSIGMA(1) is treated separately.
+*
+      DO 110 J = 2, N
+         JP = IDXP( J )
+         DSIGMA( J ) = D( JP )
+         VFW( J ) = VF( JP )
+         VLW( J ) = VL( JP )
+  110 CONTINUE
+      IF( ICOMPQ.EQ.1 ) THEN
+         DO 120 J = 2, N
+            JP = IDXP( J )
+            PERM( J ) = IDXQ( IDX( JP )+1 )
+            IF( PERM( J ).LE.NLP1 ) THEN
+               PERM( J ) = PERM( J ) - 1
+            END IF
+  120    CONTINUE
+      END IF
+*
+*     The deflated singular values go back into the last N - K slots of
+*     D.
+*
+      CALL SCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 )
+*
+*     Determine DSIGMA(1), DSIGMA(2), Z(1), VF(1), VL(1), VF(M), and
+*     VL(M).
+*
+      DSIGMA( 1 ) = ZERO
+      HLFTOL = TOL / TWO
+      IF( ABS( DSIGMA( 2 ) ).LE.HLFTOL )
+     $   DSIGMA( 2 ) = HLFTOL
+      IF( M.GT.N ) THEN
+         Z( 1 ) = SLAPY2( Z1, Z( M ) )
+         IF( Z( 1 ).LE.TOL ) THEN
+            C = ONE
+            S = ZERO
+            Z( 1 ) = TOL
+         ELSE
+            C = Z1 / Z( 1 )
+            S = -Z( M ) / Z( 1 )
+         END IF
+         CALL SROT( 1, VF( M ), 1, VF( 1 ), 1, C, S )
+         CALL SROT( 1, VL( M ), 1, VL( 1 ), 1, C, S )
+      ELSE
+         IF( ABS( Z1 ).LE.TOL ) THEN
+            Z( 1 ) = TOL
+         ELSE
+            Z( 1 ) = Z1
+         END IF
+      END IF
+*
+*     Restore Z, VF, and VL.
+*
+      CALL SCOPY( K-1, ZW( 2 ), 1, Z( 2 ), 1 )
+      CALL SCOPY( N-1, VFW( 2 ), 1, VF( 2 ), 1 )
+      CALL SCOPY( N-1, VLW( 2 ), 1, VL( 2 ), 1 )
+*
+      RETURN
+*
+*     End of SLASD7
+*
+      END
diff --git a/libcruft/lapack/slasd8.f b/libcruft/lapack/slasd8.f
new file mode 100644
index 0000000..b32ffa2
--- /dev/null
+++ b/libcruft/lapack/slasd8.f
@@ -0,0 +1,253 @@
+      SUBROUTINE SLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDDIFR,
+     $                   DSIGMA, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, K, LDDIFR
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), DIFL( * ), DIFR( LDDIFR, * ),
+     $                   DSIGMA( * ), VF( * ), VL( * ), WORK( * ),
+     $                   Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASD8 finds the square roots of the roots of the secular equation,
+*  as defined by the values in DSIGMA and Z. It makes the appropriate
+*  calls to SLASD4, and stores, for each  element in D, the distance
+*  to its two nearest poles (elements in DSIGMA). It also updates
+*  the arrays VF and VL, the first and last components of all the
+*  right singular vectors of the original bidiagonal matrix.
+*
+*  SLASD8 is called from SLASD6.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ  (input) INTEGER
+*          Specifies whether singular vectors are to be computed in
+*          factored form in the calling routine:
+*          = 0: Compute singular values only.
+*          = 1: Compute singular vectors in factored form as well.
+*
+*  K       (input) INTEGER
+*          The number of terms in the rational function to be solved
+*          by SLASD4.  K >= 1.
+*
+*  D       (output) REAL array, dimension ( K )
+*          On output, D contains the updated singular values.
+*
+*  Z       (input) REAL array, dimension ( K )
+*          The first K elements of this array contain the components
+*          of the deflation-adjusted updating row vector.
+*
+*  VF      (input/output) REAL array, dimension ( K )
+*          On entry, VF contains  information passed through DBEDE8.
+*          On exit, VF contains the first K components of the first
+*          components of all right singular vectors of the bidiagonal
+*          matrix.
+*
+*  VL      (input/output) REAL array, dimension ( K )
+*          On entry, VL contains  information passed through DBEDE8.
+*          On exit, VL contains the first K components of the last
+*          components of all right singular vectors of the bidiagonal
+*          matrix.
+*
+*  DIFL    (output) REAL array, dimension ( K )
+*          On exit, DIFL(I) = D(I) - DSIGMA(I).
+*
+*  DIFR    (output) REAL array,
+*                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
+*                   dimension ( K ) if ICOMPQ = 0.
+*          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
+*          defined and will not be referenced.
+*
+*          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
+*          normalizing factors for the right singular vector matrix.
+*
+*  LDDIFR  (input) INTEGER
+*          The leading dimension of DIFR, must be at least K.
+*
+*  DSIGMA  (input) REAL array, dimension ( K )
+*          The first K elements of this array contain the old roots
+*          of the deflated updating problem.  These are the poles
+*          of the secular equation.
+*
+*  WORK    (workspace) REAL array, dimension at least 3 * K
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IWK1, IWK2, IWK2I, IWK3, IWK3I, J
+      REAL               DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, RHO, TEMP
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLASCL, SLASD4, SLASET, XERBLA
+*     ..
+*     .. External Functions ..
+      REAL               SDOT, SLAMC3, SNRM2
+      EXTERNAL           SDOT, SLAMC3, SNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( K.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( LDDIFR.LT.K ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASD8', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( K.EQ.1 ) THEN
+         D( 1 ) = ABS( Z( 1 ) )
+         DIFL( 1 ) = D( 1 )
+         IF( ICOMPQ.EQ.1 ) THEN
+            DIFL( 2 ) = ONE
+            DIFR( 1, 2 ) = ONE
+         END IF
+         RETURN
+      END IF
+*
+*     Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
+*     be computed with high relative accuracy (barring over/underflow).
+*     This is a problem on machines without a guard digit in
+*     add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
+*     The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
+*     which on any of these machines zeros out the bottommost
+*     bit of DSIGMA(I) if it is 1; this makes the subsequent
+*     subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
+*     occurs. On binary machines with a guard digit (almost all
+*     machines) it does not change DSIGMA(I) at all. On hexadecimal
+*     and decimal machines with a guard digit, it slightly
+*     changes the bottommost bits of DSIGMA(I). It does not account
+*     for hexadecimal or decimal machines without guard digits
+*     (we know of none). We use a subroutine call to compute
+*     2*DSIGMA(I) to prevent optimizing compilers from eliminating
+*     this code.
+*
+      DO 10 I = 1, K
+         DSIGMA( I ) = SLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )
+   10 CONTINUE
+*
+*     Book keeping.
+*
+      IWK1 = 1
+      IWK2 = IWK1 + K
+      IWK3 = IWK2 + K
+      IWK2I = IWK2 - 1
+      IWK3I = IWK3 - 1
+*
+*     Normalize Z.
+*
+      RHO = SNRM2( K, Z, 1 )
+      CALL SLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )
+      RHO = RHO*RHO
+*
+*     Initialize WORK(IWK3).
+*
+      CALL SLASET( 'A', K, 1, ONE, ONE, WORK( IWK3 ), K )
+*
+*     Compute the updated singular values, the arrays DIFL, DIFR,
+*     and the updated Z.
+*
+      DO 40 J = 1, K
+         CALL SLASD4( K, J, DSIGMA, Z, WORK( IWK1 ), RHO, D( J ),
+     $                WORK( IWK2 ), INFO )
+*
+*        If the root finder fails, the computation is terminated.
+*
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         WORK( IWK3I+J ) = WORK( IWK3I+J )*WORK( J )*WORK( IWK2I+J )
+         DIFL( J ) = -WORK( J )
+         DIFR( J, 1 ) = -WORK( J+1 )
+         DO 20 I = 1, J - 1
+            WORK( IWK3I+I ) = WORK( IWK3I+I )*WORK( I )*
+     $                        WORK( IWK2I+I ) / ( DSIGMA( I )-
+     $                        DSIGMA( J ) ) / ( DSIGMA( I )+
+     $                        DSIGMA( J ) )
+   20    CONTINUE
+         DO 30 I = J + 1, K
+            WORK( IWK3I+I ) = WORK( IWK3I+I )*WORK( I )*
+     $                        WORK( IWK2I+I ) / ( DSIGMA( I )-
+     $                        DSIGMA( J ) ) / ( DSIGMA( I )+
+     $                        DSIGMA( J ) )
+   30    CONTINUE
+   40 CONTINUE
+*
+*     Compute updated Z.
+*
+      DO 50 I = 1, K
+         Z( I ) = SIGN( SQRT( ABS( WORK( IWK3I+I ) ) ), Z( I ) )
+   50 CONTINUE
+*
+*     Update VF and VL.
+*
+      DO 80 J = 1, K
+         DIFLJ = DIFL( J )
+         DJ = D( J )
+         DSIGJ = -DSIGMA( J )
+         IF( J.LT.K ) THEN
+            DIFRJ = -DIFR( J, 1 )
+            DSIGJP = -DSIGMA( J+1 )
+         END IF
+         WORK( J ) = -Z( J ) / DIFLJ / ( DSIGMA( J )+DJ )
+         DO 60 I = 1, J - 1
+            WORK( I ) = Z( I ) / ( SLAMC3( DSIGMA( I ), DSIGJ )-DIFLJ )
+     $                   / ( DSIGMA( I )+DJ )
+   60    CONTINUE
+         DO 70 I = J + 1, K
+            WORK( I ) = Z( I ) / ( SLAMC3( DSIGMA( I ), DSIGJP )+DIFRJ )
+     $                   / ( DSIGMA( I )+DJ )
+   70    CONTINUE
+         TEMP = SNRM2( K, WORK, 1 )
+         WORK( IWK2I+J ) = SDOT( K, WORK, 1, VF, 1 ) / TEMP
+         WORK( IWK3I+J ) = SDOT( K, WORK, 1, VL, 1 ) / TEMP
+         IF( ICOMPQ.EQ.1 ) THEN
+            DIFR( J, 2 ) = TEMP
+         END IF
+   80 CONTINUE
+*
+      CALL SCOPY( K, WORK( IWK2 ), 1, VF, 1 )
+      CALL SCOPY( K, WORK( IWK3 ), 1, VL, 1 )
+*
+      RETURN
+*
+*     End of SLASD8
+*
+      END
diff --git a/libcruft/lapack/slasda.f b/libcruft/lapack/slasda.f
new file mode 100644
index 0000000..5092f92
--- /dev/null
+++ b/libcruft/lapack/slasda.f
@@ -0,0 +1,389 @@
+      SUBROUTINE SLASDA( ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT, K,
+     $                   DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL,
+     $                   PERM, GIVNUM, C, S, WORK, IWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
+     $                   K( * ), PERM( LDGCOL, * )
+      REAL               C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),
+     $                   E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),
+     $                   S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),
+     $                   Z( LDU, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Using a divide and conquer approach, SLASDA computes the singular
+*  value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
+*  B with diagonal D and offdiagonal E, where M = N + SQRE. The
+*  algorithm computes the singular values in the SVD B = U * S * VT.
+*  The orthogonal matrices U and VT are optionally computed in
+*  compact form.
+*
+*  A related subroutine, SLASD0, computes the singular values and
+*  the singular vectors in explicit form.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed
+*         in compact form, as follows
+*         = 0: Compute singular values only.
+*         = 1: Compute singular vectors of upper bidiagonal
+*              matrix in compact form.
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The row dimension of the upper bidiagonal matrix. This is
+*         also the dimension of the main diagonal array D.
+*
+*  SQRE   (input) INTEGER
+*         Specifies the column dimension of the bidiagonal matrix.
+*         = 0: The bidiagonal matrix has column dimension M = N;
+*         = 1: The bidiagonal matrix has column dimension M = N + 1.
+*
+*  D      (input/output) REAL array, dimension ( N )
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix. On exit D, if INFO = 0, contains its singular values.
+*
+*  E      (input) REAL array, dimension ( M-1 )
+*         Contains the subdiagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  U      (output) REAL array,
+*         dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
+*         singular vector matrices of all subproblems at the bottom
+*         level.
+*
+*  LDU    (input) INTEGER, LDU = > N.
+*         The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
+*         GIVNUM, and Z.
+*
+*  VT     (output) REAL array,
+*         dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT' contains the right
+*         singular vector matrices of all subproblems at the bottom
+*         level.
+*
+*  K      (output) INTEGER array, dimension ( N ) 
+*         if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
+*         If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
+*         secular equation on the computation tree.
+*
+*  DIFL   (output) REAL array, dimension ( LDU, NLVL ),
+*         where NLVL = floor(log_2 (N/SMLSIZ))).
+*
+*  DIFR   (output) REAL array,
+*                  dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
+*                  dimension ( N ) if ICOMPQ = 0.
+*         If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
+*         record distances between singular values on the I-th
+*         level and singular values on the (I -1)-th level, and
+*         DIFR(1:N, 2 * I ) contains the normalizing factors for
+*         the right singular vector matrix. See SLASD8 for details.
+*
+*  Z      (output) REAL array,
+*                  dimension ( LDU, NLVL ) if ICOMPQ = 1 and
+*                  dimension ( N ) if ICOMPQ = 0.
+*         The first K elements of Z(1, I) contain the components of
+*         the deflation-adjusted updating row vector for subproblems
+*         on the I-th level.
+*
+*  POLES  (output) REAL array,
+*         dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
+*         POLES(1, 2*I) contain  the new and old singular values
+*         involved in the secular equations on the I-th level.
+*
+*  GIVPTR (output) INTEGER array,
+*         dimension ( N ) if ICOMPQ = 1, and not referenced if
+*         ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
+*         the number of Givens rotations performed on the I-th
+*         problem on the computation tree.
+*
+*  GIVCOL (output) INTEGER array,
+*         dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
+*         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
+*         GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
+*         of Givens rotations performed on the I-th level on the
+*         computation tree.
+*
+*  LDGCOL (input) INTEGER, LDGCOL = > N.
+*         The leading dimension of arrays GIVCOL and PERM.
+*
+*  PERM   (output) INTEGER array, dimension ( LDGCOL, NLVL ) 
+*         if ICOMPQ = 1, and not referenced
+*         if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
+*         permutations done on the I-th level of the computation tree.
+*
+*  GIVNUM (output) REAL array,
+*         dimension ( LDU,  2 * NLVL ) if ICOMPQ = 1, and not
+*         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
+*         GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
+*         values of Givens rotations performed on the I-th level on
+*         the computation tree.
+*
+*  C      (output) REAL array,
+*         dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
+*         If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
+*         C( I ) contains the C-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  S      (output) REAL array, dimension ( N ) if
+*         ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
+*         and the I-th subproblem is not square, on exit, S( I )
+*         contains the S-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  WORK   (workspace) REAL array, dimension
+*         (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
+*
+*  IWORK  (workspace) INTEGER array, dimension (7*N).
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = 1, an singular value did not converge
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IDXQ, IDXQI, IM1, INODE, ITEMP, IWK,
+     $                   J, LF, LL, LVL, LVL2, M, NCC, ND, NDB1, NDIML,
+     $                   NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, NRU,
+     $                   NWORK1, NWORK2, SMLSZP, SQREI, VF, VFI, VL, VLI
+      REAL               ALPHA, BETA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLASD6, SLASDQ, SLASDT, SLASET, XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      ELSE IF( LDU.LT.( N+SQRE ) ) THEN
+         INFO = -8
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -17
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASDA', -INFO )
+         RETURN
+      END IF
+*
+      M = N + SQRE
+*
+*     If the input matrix is too small, call SLASDQ to find the SVD.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         IF( ICOMPQ.EQ.0 ) THEN
+            CALL SLASDQ( 'U', SQRE, N, 0, 0, 0, D, E, VT, LDU, U, LDU,
+     $                   U, LDU, WORK, INFO )
+         ELSE
+            CALL SLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDU, U, LDU,
+     $                   U, LDU, WORK, INFO )
+         END IF
+         RETURN
+      END IF
+*
+*     Book-keeping and  set up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+      IDXQ = NDIMR + N
+      IWK = IDXQ + N
+*
+      NCC = 0
+      NRU = 0
+*
+      SMLSZP = SMLSIZ + 1
+      VF = 1
+      VL = VF + M
+      NWORK1 = VL + M
+      NWORK2 = NWORK1 + SMLSZP*SMLSZP
+*
+      CALL SLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     for the nodes on bottom level of the tree, solve
+*     their subproblems by SLASDQ.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 30 I = NDB1, ND
+*
+*        IC : center row of each node
+*        NL : number of rows of left  subproblem
+*        NR : number of rows of right subproblem
+*        NLF: starting row of the left   subproblem
+*        NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NLP1 = NL + 1
+         NR = IWORK( NDIMR+I1 )
+         NLF = IC - NL
+         NRF = IC + 1
+         IDXQI = IDXQ + NLF - 2
+         VFI = VF + NLF - 1
+         VLI = VL + NLF - 1
+         SQREI = 1
+         IF( ICOMPQ.EQ.0 ) THEN
+            CALL SLASET( 'A', NLP1, NLP1, ZERO, ONE, WORK( NWORK1 ),
+     $                   SMLSZP )
+            CALL SLASDQ( 'U', SQREI, NL, NLP1, NRU, NCC, D( NLF ),
+     $                   E( NLF ), WORK( NWORK1 ), SMLSZP,
+     $                   WORK( NWORK2 ), NL, WORK( NWORK2 ), NL,
+     $                   WORK( NWORK2 ), INFO )
+            ITEMP = NWORK1 + NL*SMLSZP
+            CALL SCOPY( NLP1, WORK( NWORK1 ), 1, WORK( VFI ), 1 )
+            CALL SCOPY( NLP1, WORK( ITEMP ), 1, WORK( VLI ), 1 )
+         ELSE
+            CALL SLASET( 'A', NL, NL, ZERO, ONE, U( NLF, 1 ), LDU )
+            CALL SLASET( 'A', NLP1, NLP1, ZERO, ONE, VT( NLF, 1 ), LDU )
+            CALL SLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ),
+     $                   E( NLF ), VT( NLF, 1 ), LDU, U( NLF, 1 ), LDU,
+     $                   U( NLF, 1 ), LDU, WORK( NWORK1 ), INFO )
+            CALL SCOPY( NLP1, VT( NLF, 1 ), 1, WORK( VFI ), 1 )
+            CALL SCOPY( NLP1, VT( NLF, NLP1 ), 1, WORK( VLI ), 1 )
+         END IF
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         DO 10 J = 1, NL
+            IWORK( IDXQI+J ) = J
+   10    CONTINUE
+         IF( ( I.EQ.ND ) .AND. ( SQRE.EQ.0 ) ) THEN
+            SQREI = 0
+         ELSE
+            SQREI = 1
+         END IF
+         IDXQI = IDXQI + NLP1
+         VFI = VFI + NLP1
+         VLI = VLI + NLP1
+         NRP1 = NR + SQREI
+         IF( ICOMPQ.EQ.0 ) THEN
+            CALL SLASET( 'A', NRP1, NRP1, ZERO, ONE, WORK( NWORK1 ),
+     $                   SMLSZP )
+            CALL SLASDQ( 'U', SQREI, NR, NRP1, NRU, NCC, D( NRF ),
+     $                   E( NRF ), WORK( NWORK1 ), SMLSZP,
+     $                   WORK( NWORK2 ), NR, WORK( NWORK2 ), NR,
+     $                   WORK( NWORK2 ), INFO )
+            ITEMP = NWORK1 + ( NRP1-1 )*SMLSZP
+            CALL SCOPY( NRP1, WORK( NWORK1 ), 1, WORK( VFI ), 1 )
+            CALL SCOPY( NRP1, WORK( ITEMP ), 1, WORK( VLI ), 1 )
+         ELSE
+            CALL SLASET( 'A', NR, NR, ZERO, ONE, U( NRF, 1 ), LDU )
+            CALL SLASET( 'A', NRP1, NRP1, ZERO, ONE, VT( NRF, 1 ), LDU )
+            CALL SLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ),
+     $                   E( NRF ), VT( NRF, 1 ), LDU, U( NRF, 1 ), LDU,
+     $                   U( NRF, 1 ), LDU, WORK( NWORK1 ), INFO )
+            CALL SCOPY( NRP1, VT( NRF, 1 ), 1, WORK( VFI ), 1 )
+            CALL SCOPY( NRP1, VT( NRF, NRP1 ), 1, WORK( VLI ), 1 )
+         END IF
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+         DO 20 J = 1, NR
+            IWORK( IDXQI+J ) = J
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Now conquer each subproblem bottom-up.
+*
+      J = 2**NLVL
+      DO 50 LVL = NLVL, 1, -1
+         LVL2 = LVL*2 - 1
+*
+*        Find the first node LF and last node LL on
+*        the current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 40 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            IF( I.EQ.LL ) THEN
+               SQREI = SQRE
+            ELSE
+               SQREI = 1
+            END IF
+            VFI = VF + NLF - 1
+            VLI = VL + NLF - 1
+            IDXQI = IDXQ + NLF - 1
+            ALPHA = D( IC )
+            BETA = E( IC )
+            IF( ICOMPQ.EQ.0 ) THEN
+               CALL SLASD6( ICOMPQ, NL, NR, SQREI, D( NLF ),
+     $                      WORK( VFI ), WORK( VLI ), ALPHA, BETA,
+     $                      IWORK( IDXQI ), PERM, GIVPTR( 1 ), GIVCOL,
+     $                      LDGCOL, GIVNUM, LDU, POLES, DIFL, DIFR, Z,
+     $                      K( 1 ), C( 1 ), S( 1 ), WORK( NWORK1 ),
+     $                      IWORK( IWK ), INFO )
+            ELSE
+               J = J - 1
+               CALL SLASD6( ICOMPQ, NL, NR, SQREI, D( NLF ),
+     $                      WORK( VFI ), WORK( VLI ), ALPHA, BETA,
+     $                      IWORK( IDXQI ), PERM( NLF, LVL ),
+     $                      GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                      GIVNUM( NLF, LVL2 ), LDU,
+     $                      POLES( NLF, LVL2 ), DIFL( NLF, LVL ),
+     $                      DIFR( NLF, LVL2 ), Z( NLF, LVL ), K( J ),
+     $                      C( J ), S( J ), WORK( NWORK1 ),
+     $                      IWORK( IWK ), INFO )
+            END IF
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+   40    CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of SLASDA
+*
+      END
diff --git a/libcruft/lapack/slasdq.f b/libcruft/lapack/slasdq.f
new file mode 100644
index 0000000..596cf67
--- /dev/null
+++ b/libcruft/lapack/slasdq.f
@@ -0,0 +1,316 @@
+      SUBROUTINE SLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
+     $                   U, LDU, C, LDC, WORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
+*     ..
+*     .. Array Arguments ..
+      REAL               C( LDC, * ), D( * ), E( * ), U( LDU, * ),
+     $                   VT( LDVT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASDQ computes the singular value decomposition (SVD) of a real
+*  (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
+*  E, accumulating the transformations if desired. Letting B denote
+*  the input bidiagonal matrix, the algorithm computes orthogonal
+*  matrices Q and P such that B = Q * S * P' (P' denotes the transpose
+*  of P). The singular values S are overwritten on D.
+*
+*  The input matrix U  is changed to U  * Q  if desired.
+*  The input matrix VT is changed to P' * VT if desired.
+*  The input matrix C  is changed to Q' * C  if desired.
+*
+*  See "Computing  Small Singular Values of Bidiagonal Matrices With
+*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
+*  LAPACK Working Note #3, for a detailed description of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO  (input) CHARACTER*1
+*        On entry, UPLO specifies whether the input bidiagonal matrix
+*        is upper or lower bidiagonal, and wether it is square are
+*        not.
+*           UPLO = 'U' or 'u'   B is upper bidiagonal.
+*           UPLO = 'L' or 'l'   B is lower bidiagonal.
+*
+*  SQRE  (input) INTEGER
+*        = 0: then the input matrix is N-by-N.
+*        = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
+*             (N+1)-by-N if UPLU = 'L'.
+*
+*        The bidiagonal matrix has
+*        N = NL + NR + 1 rows and
+*        M = N + SQRE >= N columns.
+*
+*  N     (input) INTEGER
+*        On entry, N specifies the number of rows and columns
+*        in the matrix. N must be at least 0.
+*
+*  NCVT  (input) INTEGER
+*        On entry, NCVT specifies the number of columns of
+*        the matrix VT. NCVT must be at least 0.
+*
+*  NRU   (input) INTEGER
+*        On entry, NRU specifies the number of rows of
+*        the matrix U. NRU must be at least 0.
+*
+*  NCC   (input) INTEGER
+*        On entry, NCC specifies the number of columns of
+*        the matrix C. NCC must be at least 0.
+*
+*  D     (input/output) REAL array, dimension (N)
+*        On entry, D contains the diagonal entries of the
+*        bidiagonal matrix whose SVD is desired. On normal exit,
+*        D contains the singular values in ascending order.
+*
+*  E     (input/output) REAL array.
+*        dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
+*        On entry, the entries of E contain the offdiagonal entries
+*        of the bidiagonal matrix whose SVD is desired. On normal
+*        exit, E will contain 0. If the algorithm does not converge,
+*        D and E will contain the diagonal and superdiagonal entries
+*        of a bidiagonal matrix orthogonally equivalent to the one
+*        given as input.
+*
+*  VT    (input/output) REAL array, dimension (LDVT, NCVT)
+*        On entry, contains a matrix which on exit has been
+*        premultiplied by P', dimension N-by-NCVT if SQRE = 0
+*        and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
+*
+*  LDVT  (input) INTEGER
+*        On entry, LDVT specifies the leading dimension of VT as
+*        declared in the calling (sub) program. LDVT must be at
+*        least 1. If NCVT is nonzero LDVT must also be at least N.
+*
+*  U     (input/output) REAL array, dimension (LDU, N)
+*        On entry, contains a  matrix which on exit has been
+*        postmultiplied by Q, dimension NRU-by-N if SQRE = 0
+*        and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
+*
+*  LDU   (input) INTEGER
+*        On entry, LDU  specifies the leading dimension of U as
+*        declared in the calling (sub) program. LDU must be at
+*        least max( 1, NRU ) .
+*
+*  C     (input/output) REAL array, dimension (LDC, NCC)
+*        On entry, contains an N-by-NCC matrix which on exit
+*        has been premultiplied by Q'  dimension N-by-NCC if SQRE = 0
+*        and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
+*
+*  LDC   (input) INTEGER
+*        On entry, LDC  specifies the leading dimension of C as
+*        declared in the calling (sub) program. LDC must be at
+*        least 1. If NCC is nonzero, LDC must also be at least N.
+*
+*  WORK  (workspace) REAL array, dimension (4*N)
+*        Workspace. Only referenced if one of NCVT, NRU, or NCC is
+*        nonzero, and if N is at least 2.
+*
+*  INFO  (output) INTEGER
+*        On exit, a value of 0 indicates a successful exit.
+*        If INFO < 0, argument number -INFO is illegal.
+*        If INFO > 0, the algorithm did not converge, and INFO
+*        specifies how many superdiagonals did not converge.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ROTATE
+      INTEGER            I, ISUB, IUPLO, J, NP1, SQRE1
+      REAL               CS, R, SMIN, SN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SBDSQR, SLARTG, SLASR, SSWAP, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IUPLO = 0
+      IF( LSAME( UPLO, 'U' ) )
+     $   IUPLO = 1
+      IF( LSAME( UPLO, 'L' ) )
+     $   IUPLO = 2
+      IF( IUPLO.EQ.0 ) THEN
+         INFO = -1
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NCVT.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRU.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( NCC.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
+     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
+         INFO = -10
+      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
+         INFO = -12
+      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
+     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
+         INFO = -14
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASDQ', -INFO )
+         RETURN
+      END IF
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     ROTATE is true if any singular vectors desired, false otherwise
+*
+      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
+      NP1 = N + 1
+      SQRE1 = SQRE
+*
+*     If matrix non-square upper bidiagonal, rotate to be lower
+*     bidiagonal.  The rotations are on the right.
+*
+      IF( ( IUPLO.EQ.1 ) .AND. ( SQRE1.EQ.1 ) ) THEN
+         DO 10 I = 1, N - 1
+            CALL SLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( ROTATE ) THEN
+               WORK( I ) = CS
+               WORK( N+I ) = SN
+            END IF
+   10    CONTINUE
+         CALL SLARTG( D( N ), E( N ), CS, SN, R )
+         D( N ) = R
+         E( N ) = ZERO
+         IF( ROTATE ) THEN
+            WORK( N ) = CS
+            WORK( N+N ) = SN
+         END IF
+         IUPLO = 2
+         SQRE1 = 0
+*
+*        Update singular vectors if desired.
+*
+         IF( NCVT.GT.0 )
+     $      CALL SLASR( 'L', 'V', 'F', NP1, NCVT, WORK( 1 ),
+     $                  WORK( NP1 ), VT, LDVT )
+      END IF
+*
+*     If matrix lower bidiagonal, rotate to be upper bidiagonal
+*     by applying Givens rotations on the left.
+*
+      IF( IUPLO.EQ.2 ) THEN
+         DO 20 I = 1, N - 1
+            CALL SLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( ROTATE ) THEN
+               WORK( I ) = CS
+               WORK( N+I ) = SN
+            END IF
+   20    CONTINUE
+*
+*        If matrix (N+1)-by-N lower bidiagonal, one additional
+*        rotation is needed.
+*
+         IF( SQRE1.EQ.1 ) THEN
+            CALL SLARTG( D( N ), E( N ), CS, SN, R )
+            D( N ) = R
+            IF( ROTATE ) THEN
+               WORK( N ) = CS
+               WORK( N+N ) = SN
+            END IF
+         END IF
+*
+*        Update singular vectors if desired.
+*
+         IF( NRU.GT.0 ) THEN
+            IF( SQRE1.EQ.0 ) THEN
+               CALL SLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ),
+     $                     WORK( NP1 ), U, LDU )
+            ELSE
+               CALL SLASR( 'R', 'V', 'F', NRU, NP1, WORK( 1 ),
+     $                     WORK( NP1 ), U, LDU )
+            END IF
+         END IF
+         IF( NCC.GT.0 ) THEN
+            IF( SQRE1.EQ.0 ) THEN
+               CALL SLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ),
+     $                     WORK( NP1 ), C, LDC )
+            ELSE
+               CALL SLASR( 'L', 'V', 'F', NP1, NCC, WORK( 1 ),
+     $                     WORK( NP1 ), C, LDC )
+            END IF
+         END IF
+      END IF
+*
+*     Call SBDSQR to compute the SVD of the reduced real
+*     N-by-N upper bidiagonal matrix.
+*
+      CALL SBDSQR( 'U', N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C,
+     $             LDC, WORK, INFO )
+*
+*     Sort the singular values into ascending order (insertion sort on
+*     singular values, but only one transposition per singular vector)
+*
+      DO 40 I = 1, N
+*
+*        Scan for smallest D(I).
+*
+         ISUB = I
+         SMIN = D( I )
+         DO 30 J = I + 1, N
+            IF( D( J ).LT.SMIN ) THEN
+               ISUB = J
+               SMIN = D( J )
+            END IF
+   30    CONTINUE
+         IF( ISUB.NE.I ) THEN
+*
+*           Swap singular values and vectors.
+*
+            D( ISUB ) = D( I )
+            D( I ) = SMIN
+            IF( NCVT.GT.0 )
+     $         CALL SSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( I, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL SSWAP( NRU, U( 1, ISUB ), 1, U( 1, I ), 1 )
+            IF( NCC.GT.0 )
+     $         CALL SSWAP( NCC, C( ISUB, 1 ), LDC, C( I, 1 ), LDC )
+         END IF
+   40 CONTINUE
+*
+      RETURN
+*
+*     End of SLASDQ
+*
+      END
diff --git a/libcruft/lapack/slasdt.f b/libcruft/lapack/slasdt.f
new file mode 100644
index 0000000..335935c
--- /dev/null
+++ b/libcruft/lapack/slasdt.f
@@ -0,0 +1,105 @@
+      SUBROUTINE SLASDT( N, LVL, ND, INODE, NDIML, NDIMR, MSUB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LVL, MSUB, N, ND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            INODE( * ), NDIML( * ), NDIMR( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASDT creates a tree of subproblems for bidiagonal divide and
+*  conquer.
+*
+*  Arguments
+*  =========
+*
+*   N      (input) INTEGER
+*          On entry, the number of diagonal elements of the
+*          bidiagonal matrix.
+*
+*   LVL    (output) INTEGER
+*          On exit, the number of levels on the computation tree.
+*
+*   ND     (output) INTEGER
+*          On exit, the number of nodes on the tree.
+*
+*   INODE  (output) INTEGER array, dimension ( N )
+*          On exit, centers of subproblems.
+*
+*   NDIML  (output) INTEGER array, dimension ( N )
+*          On exit, row dimensions of left children.
+*
+*   NDIMR  (output) INTEGER array, dimension ( N )
+*          On exit, row dimensions of right children.
+*
+*   MSUB   (input) INTEGER.
+*          On entry, the maximum row dimension each subproblem at the
+*          bottom of the tree can be of.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Huan Ren, Computer Science Division, University of
+*     California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IL, IR, LLST, MAXN, NCRNT, NLVL
+      REAL               TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, LOG, MAX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Find the number of levels on the tree.
+*
+      MAXN = MAX( 1, N )
+      TEMP = LOG( REAL( MAXN ) / REAL( MSUB+1 ) ) / LOG( TWO )
+      LVL = INT( TEMP ) + 1
+*
+      I = N / 2
+      INODE( 1 ) = I + 1
+      NDIML( 1 ) = I
+      NDIMR( 1 ) = N - I - 1
+      IL = 0
+      IR = 1
+      LLST = 1
+      DO 20 NLVL = 1, LVL - 1
+*
+*        Constructing the tree at (NLVL+1)-st level. The number of
+*        nodes created on this level is LLST * 2.
+*
+         DO 10 I = 0, LLST - 1
+            IL = IL + 2
+            IR = IR + 2
+            NCRNT = LLST + I
+            NDIML( IL ) = NDIML( NCRNT ) / 2
+            NDIMR( IL ) = NDIML( NCRNT ) - NDIML( IL ) - 1
+            INODE( IL ) = INODE( NCRNT ) - NDIMR( IL ) - 1
+            NDIML( IR ) = NDIMR( NCRNT ) / 2
+            NDIMR( IR ) = NDIMR( NCRNT ) - NDIML( IR ) - 1
+            INODE( IR ) = INODE( NCRNT ) + NDIML( IR ) + 1
+   10    CONTINUE
+         LLST = LLST*2
+   20 CONTINUE
+      ND = LLST*2 - 1
+*
+      RETURN
+*
+*     End of SLASDT
+*
+      END
diff --git a/libcruft/lapack/slaset.f b/libcruft/lapack/slaset.f
new file mode 100644
index 0000000..7acc0ca
--- /dev/null
+++ b/libcruft/lapack/slaset.f
@@ -0,0 +1,114 @@
+      SUBROUTINE SLASET( UPLO, M, N, ALPHA, BETA, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, M, N
+      REAL               ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASET initializes an m-by-n matrix A to BETA on the diagonal and
+*  ALPHA on the offdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be set.
+*          = 'U':      Upper triangular part is set; the strictly lower
+*                      triangular part of A is not changed.
+*          = 'L':      Lower triangular part is set; the strictly upper
+*                      triangular part of A is not changed.
+*          Otherwise:  All of the matrix A is set.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  ALPHA   (input) REAL
+*          The constant to which the offdiagonal elements are to be set.
+*
+*  BETA    (input) REAL
+*          The constant to which the diagonal elements are to be set.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On exit, the leading m-by-n submatrix of A is set as follows:
+*
+*          if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n,
+*          if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n,
+*          otherwise,     A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j,
+*
+*          and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Set the strictly upper triangular or trapezoidal part of the
+*        array to ALPHA.
+*
+         DO 20 J = 2, N
+            DO 10 I = 1, MIN( J-1, M )
+               A( I, J ) = ALPHA
+   10       CONTINUE
+   20    CONTINUE
+*
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+*
+*        Set the strictly lower triangular or trapezoidal part of the
+*        array to ALPHA.
+*
+         DO 40 J = 1, MIN( M, N )
+            DO 30 I = J + 1, M
+               A( I, J ) = ALPHA
+   30       CONTINUE
+   40    CONTINUE
+*
+      ELSE
+*
+*        Set the leading m-by-n submatrix to ALPHA.
+*
+         DO 60 J = 1, N
+            DO 50 I = 1, M
+               A( I, J ) = ALPHA
+   50       CONTINUE
+   60    CONTINUE
+      END IF
+*
+*     Set the first min(M,N) diagonal elements to BETA.
+*
+      DO 70 I = 1, MIN( M, N )
+         A( I, I ) = BETA
+   70 CONTINUE
+*
+      RETURN
+*
+*     End of SLASET
+*
+      END
diff --git a/libcruft/lapack/slasq1.f b/libcruft/lapack/slasq1.f
new file mode 100644
index 0000000..bc8a2f1
--- /dev/null
+++ b/libcruft/lapack/slasq1.f
@@ -0,0 +1,148 @@
+      SUBROUTINE SLASQ1( N, D, E, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASQ1 computes the singular values of a real N-by-N bidiagonal
+*  matrix with diagonal D and off-diagonal E. The singular values
+*  are computed to high relative accuracy, in the absence of
+*  denormalization, underflow and overflow. The algorithm was first
+*  presented in
+*
+*  "Accurate singular values and differential qd algorithms" by K. V.
+*  Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230,
+*  1994,
+*
+*  and the present implementation is described in "An implementation of
+*  the dqds Algorithm (Positive Case)", LAPACK Working Note.
+*
+*  Arguments
+*  =========
+*
+*  N     (input) INTEGER
+*        The number of rows and columns in the matrix. N >= 0.
+*
+*  D     (input/output) REAL array, dimension (N)
+*        On entry, D contains the diagonal elements of the
+*        bidiagonal matrix whose SVD is desired. On normal exit,
+*        D contains the singular values in decreasing order.
+*
+*  E     (input/output) REAL array, dimension (N)
+*        On entry, elements E(1:N-1) contain the off-diagonal elements
+*        of the bidiagonal matrix whose SVD is desired.
+*        On exit, E is overwritten.
+*
+*  WORK  (workspace) REAL array, dimension (4*N)
+*
+*  INFO  (output) INTEGER
+*        = 0: successful exit
+*        < 0: if INFO = -i, the i-th argument had an illegal value
+*        > 0: the algorithm failed
+*             = 1, a split was marked by a positive value in E
+*             = 2, current block of Z not diagonalized after 30*N
+*                  iterations (in inner while loop)
+*             = 3, termination criterion of outer while loop not met 
+*                  (program created more than N unreduced blocks)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IINFO
+      REAL               EPS, SCALE, SAFMIN, SIGMN, SIGMX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SLAS2, SLASCL, SLASQ2, SLASRT, XERBLA
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -2
+         CALL XERBLA( 'SLASQ1', -INFO )
+         RETURN
+      ELSE IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+         D( 1 ) = ABS( D( 1 ) )
+         RETURN
+      ELSE IF( N.EQ.2 ) THEN
+         CALL SLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX )
+         D( 1 ) = SIGMX
+         D( 2 ) = SIGMN
+         RETURN
+      END IF
+*
+*     Estimate the largest singular value.
+*
+      SIGMX = ZERO
+      DO 10 I = 1, N - 1
+         D( I ) = ABS( D( I ) )
+         SIGMX = MAX( SIGMX, ABS( E( I ) ) )
+   10 CONTINUE
+      D( N ) = ABS( D( N ) )
+*
+*     Early return if SIGMX is zero (matrix is already diagonal).
+*
+      IF( SIGMX.EQ.ZERO ) THEN
+         CALL SLASRT( 'D', N, D, IINFO )
+         RETURN
+      END IF
+*
+      DO 20 I = 1, N
+         SIGMX = MAX( SIGMX, D( I ) )
+   20 CONTINUE
+*
+*     Copy D and E into WORK (in the Z format) and scale (squaring the
+*     input data makes scaling by a power of the radix pointless).
+*
+      EPS = SLAMCH( 'Precision' )
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      SCALE = SQRT( EPS / SAFMIN )
+      CALL SCOPY( N, D, 1, WORK( 1 ), 2 )
+      CALL SCOPY( N-1, E, 1, WORK( 2 ), 2 )
+      CALL SLASCL( 'G', 0, 0, SIGMX, SCALE, 2*N-1, 1, WORK, 2*N-1,
+     $             IINFO )
+*         
+*     Compute the q's and e's.
+*
+      DO 30 I = 1, 2*N - 1
+         WORK( I ) = WORK( I )**2
+   30 CONTINUE
+      WORK( 2*N ) = ZERO
+*
+      CALL SLASQ2( N, WORK, INFO )
+*
+      IF( INFO.EQ.0 ) THEN
+         DO 40 I = 1, N
+            D( I ) = SQRT( WORK( I ) )
+   40    CONTINUE
+         CALL SLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO )
+      END IF
+*
+      RETURN
+*
+*     End of SLASQ1
+*
+      END
diff --git a/libcruft/lapack/slasq2.f b/libcruft/lapack/slasq2.f
new file mode 100644
index 0000000..9fd6fa0
--- /dev/null
+++ b/libcruft/lapack/slasq2.f
@@ -0,0 +1,448 @@
+      SUBROUTINE SLASQ2( N, Z, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLAZQ3 in place of SLASQ3, 13 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASQ2 computes all the eigenvalues of the symmetric positive 
+*  definite tridiagonal matrix associated with the qd array Z to high
+*  relative accuracy are computed to high relative accuracy, in the
+*  absence of denormalization, underflow and overflow.
+*
+*  To see the relation of Z to the tridiagonal matrix, let L be a
+*  unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and
+*  let U be an upper bidiagonal matrix with 1's above and diagonal
+*  Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the
+*  symmetric tridiagonal to which it is similar.
+*
+*  Note : SLASQ2 defines a logical variable, IEEE, which is true
+*  on machines which follow ieee-754 floating-point standard in their
+*  handling of infinities and NaNs, and false otherwise. This variable
+*  is passed to SLAZQ3.
+*
+*  Arguments
+*  =========
+*
+*  N     (input) INTEGER
+*        The number of rows and columns in the matrix. N >= 0.
+*
+*  Z     (workspace) REAL array, dimension (4*N)
+*        On entry Z holds the qd array. On exit, entries 1 to N hold
+*        the eigenvalues in decreasing order, Z( 2*N+1 ) holds the
+*        trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If
+*        N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 )
+*        holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of
+*        shifts that failed.
+*
+*  INFO  (output) INTEGER
+*        = 0: successful exit
+*        < 0: if the i-th argument is a scalar and had an illegal
+*             value, then INFO = -i, if the i-th argument is an
+*             array and the j-entry had an illegal value, then
+*             INFO = -(i*100+j)
+*        > 0: the algorithm failed
+*              = 1, a split was marked by a positive value in E
+*              = 2, current block of Z not diagonalized after 30*N
+*                   iterations (in inner while loop)
+*              = 3, termination criterion of outer while loop not met 
+*                   (program created more than N unreduced blocks)
+*
+*  Further Details
+*  ===============
+*  Local Variables: I0:N0 defines a current unreduced segment of Z.
+*  The shifts are accumulated in SIGMA. Iteration count is in ITER.
+*  Ping-pong is controlled by PP (alternates between 0 and 1).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               CBIAS
+      PARAMETER          ( CBIAS = 1.50E0 )
+      REAL               ZERO, HALF, ONE, TWO, FOUR, HUNDRD
+      PARAMETER          ( ZERO = 0.0E0, HALF = 0.5E0, ONE = 1.0E0,
+     $                     TWO = 2.0E0, FOUR = 4.0E0, HUNDRD = 100.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            IEEE
+      INTEGER            I0, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, K, 
+     $                   N0, NBIG, NDIV, NFAIL, PP, SPLT, TTYPE
+      REAL               D, DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, E,
+     $                   EMAX, EMIN, EPS, OLDEMN, QMAX, QMIN, S, SAFMIN,
+     $                   SIGMA, T, TAU, TEMP, TOL, TOL2, TRACE, ZMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAZQ3, SLASRT, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      REAL               SLAMCH
+      EXTERNAL           ILAENV, SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL, SQRT
+*     ..
+*     .. Executable Statements ..
+*      
+*     Test the input arguments.
+*     (in case SLASQ2 is not called by SLASQ1)
+*
+      INFO = 0
+      EPS = SLAMCH( 'Precision' )
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      TOL = EPS*HUNDRD
+      TOL2 = TOL**2
+*
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'SLASQ2', 1 )
+         RETURN
+      ELSE IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+*
+*        1-by-1 case.
+*
+         IF( Z( 1 ).LT.ZERO ) THEN
+            INFO = -201
+            CALL XERBLA( 'SLASQ2', 2 )
+         END IF
+         RETURN
+      ELSE IF( N.EQ.2 ) THEN
+*
+*        2-by-2 case.
+*
+         IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THEN
+            INFO = -2
+            CALL XERBLA( 'SLASQ2', 2 )
+            RETURN
+         ELSE IF( Z( 3 ).GT.Z( 1 ) ) THEN
+            D = Z( 3 )
+            Z( 3 ) = Z( 1 )
+            Z( 1 ) = D
+         END IF
+         Z( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 )
+         IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THEN
+            T = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) ) 
+            S = Z( 3 )*( Z( 2 ) / T )
+            IF( S.LE.T ) THEN
+               S = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) )
+            ELSE
+               S = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
+            END IF
+            T = Z( 1 ) + ( S+Z( 2 ) )
+            Z( 3 ) = Z( 3 )*( Z( 1 ) / T )
+            Z( 1 ) = T
+         END IF
+         Z( 2 ) = Z( 3 )
+         Z( 6 ) = Z( 2 ) + Z( 1 )
+         RETURN
+      END IF
+*
+*     Check for negative data and compute sums of q's and e's.
+*
+      Z( 2*N ) = ZERO
+      EMIN = Z( 2 )
+      QMAX = ZERO
+      ZMAX = ZERO
+      D = ZERO
+      E = ZERO
+*
+      DO 10 K = 1, 2*( N-1 ), 2
+         IF( Z( K ).LT.ZERO ) THEN
+            INFO = -( 200+K )
+            CALL XERBLA( 'SLASQ2', 2 )
+            RETURN
+         ELSE IF( Z( K+1 ).LT.ZERO ) THEN
+            INFO = -( 200+K+1 )
+            CALL XERBLA( 'SLASQ2', 2 )
+            RETURN
+         END IF
+         D = D + Z( K )
+         E = E + Z( K+1 )
+         QMAX = MAX( QMAX, Z( K ) )
+         EMIN = MIN( EMIN, Z( K+1 ) )
+         ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) )
+   10 CONTINUE
+      IF( Z( 2*N-1 ).LT.ZERO ) THEN
+         INFO = -( 200+2*N-1 )
+         CALL XERBLA( 'SLASQ2', 2 )
+         RETURN
+      END IF
+      D = D + Z( 2*N-1 )
+      QMAX = MAX( QMAX, Z( 2*N-1 ) )
+      ZMAX = MAX( QMAX, ZMAX )
+*
+*     Check for diagonality.
+*
+      IF( E.EQ.ZERO ) THEN
+         DO 20 K = 2, N
+            Z( K ) = Z( 2*K-1 )
+   20    CONTINUE
+         CALL SLASRT( 'D', N, Z, IINFO )
+         Z( 2*N-1 ) = D
+         RETURN
+      END IF
+*
+      TRACE = D + E
+*
+*     Check for zero data.
+*
+      IF( TRACE.EQ.ZERO ) THEN
+         Z( 2*N-1 ) = ZERO
+         RETURN
+      END IF
+*         
+*     Check whether the machine is IEEE conformable.
+*         
+      IEEE = ILAENV( 10, 'SLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND.
+     $       ILAENV( 11, 'SLASQ2', 'N', 1, 2, 3, 4 ).EQ.1      
+*         
+*     Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...).
+*
+      DO 30 K = 2*N, 2, -2
+         Z( 2*K ) = ZERO 
+         Z( 2*K-1 ) = Z( K ) 
+         Z( 2*K-2 ) = ZERO 
+         Z( 2*K-3 ) = Z( K-1 ) 
+   30 CONTINUE
+*
+      I0 = 1
+      N0 = N
+*
+*     Reverse the qd-array, if warranted.
+*
+      IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THEN
+         IPN4 = 4*( I0+N0 )
+         DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4
+            TEMP = Z( I4-3 )
+            Z( I4-3 ) = Z( IPN4-I4-3 )
+            Z( IPN4-I4-3 ) = TEMP
+            TEMP = Z( I4-1 )
+            Z( I4-1 ) = Z( IPN4-I4-5 )
+            Z( IPN4-I4-5 ) = TEMP
+   40    CONTINUE
+      END IF
+*
+*     Initial split checking via dqd and Li's test.
+*
+      PP = 0
+*
+      DO 80 K = 1, 2
+*
+         D = Z( 4*N0+PP-3 )
+         DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4
+            IF( Z( I4-1 ).LE.TOL2*D ) THEN
+               Z( I4-1 ) = -ZERO
+               D = Z( I4-3 )
+            ELSE
+               D = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) )
+            END IF
+   50    CONTINUE
+*
+*        dqd maps Z to ZZ plus Li's test.
+*
+         EMIN = Z( 4*I0+PP+1 )
+         D = Z( 4*I0+PP-3 )
+         DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4
+            Z( I4-2*PP-2 ) = D + Z( I4-1 )
+            IF( Z( I4-1 ).LE.TOL2*D ) THEN
+               Z( I4-1 ) = -ZERO
+               Z( I4-2*PP-2 ) = D
+               Z( I4-2*PP ) = ZERO
+               D = Z( I4+1 )
+            ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND.
+     $               SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THEN
+               TEMP = Z( I4+1 ) / Z( I4-2*PP-2 )
+               Z( I4-2*PP ) = Z( I4-1 )*TEMP
+               D = D*TEMP
+            ELSE
+               Z( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) )
+               D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) )
+            END IF
+            EMIN = MIN( EMIN, Z( I4-2*PP ) )
+   60    CONTINUE 
+         Z( 4*N0-PP-2 ) = D
+*
+*        Now find qmax.
+*
+         QMAX = Z( 4*I0-PP-2 )
+         DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4
+            QMAX = MAX( QMAX, Z( I4 ) )
+   70    CONTINUE
+*
+*        Prepare for the next iteration on K.
+*
+         PP = 1 - PP
+   80 CONTINUE
+*
+*     Initialise variables to pass to SLAZQ3
+*
+      TTYPE = 0
+      DMIN1 = ZERO
+      DMIN2 = ZERO
+      DN    = ZERO
+      DN1   = ZERO
+      DN2   = ZERO
+      TAU   = ZERO
+*
+      ITER = 2
+      NFAIL = 0
+      NDIV = 2*( N0-I0 )
+*
+      DO 140 IWHILA = 1, N + 1
+         IF( N0.LT.1 ) 
+     $      GO TO 150
+*
+*        While array unfinished do 
+*
+*        E(N0) holds the value of SIGMA when submatrix in I0:N0
+*        splits from the rest of the array, but is negated.
+*      
+         DESIG = ZERO
+         IF( N0.EQ.N ) THEN
+            SIGMA = ZERO
+         ELSE
+            SIGMA = -Z( 4*N0-1 )
+         END IF
+         IF( SIGMA.LT.ZERO ) THEN
+            INFO = 1
+            RETURN
+         END IF
+*
+*        Find last unreduced submatrix's top index I0, find QMAX and
+*        EMIN. Find Gershgorin-type bound if Q's much greater than E's.
+*
+         EMAX = ZERO 
+         IF( N0.GT.I0 ) THEN
+            EMIN = ABS( Z( 4*N0-5 ) )
+         ELSE
+            EMIN = ZERO
+         END IF
+         QMIN = Z( 4*N0-3 )
+         QMAX = QMIN
+         DO 90 I4 = 4*N0, 8, -4
+            IF( Z( I4-5 ).LE.ZERO )
+     $         GO TO 100
+            IF( QMIN.GE.FOUR*EMAX ) THEN
+               QMIN = MIN( QMIN, Z( I4-3 ) )
+               EMAX = MAX( EMAX, Z( I4-5 ) )
+            END IF
+            QMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) )
+            EMIN = MIN( EMIN, Z( I4-5 ) )
+   90    CONTINUE
+         I4 = 4 
+*
+  100    CONTINUE
+         I0 = I4 / 4
+*
+*        Store EMIN for passing to SLAZQ3.
+*
+         Z( 4*N0-1 ) = EMIN
+*
+*        Put -(initial shift) into DMIN.
+*
+         DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) )
+*
+*        Now I0:N0 is unreduced. PP = 0 for ping, PP = 1 for pong.
+*
+         PP = 0 
+*
+         NBIG = 30*( N0-I0+1 )
+         DO 120 IWHILB = 1, NBIG
+            IF( I0.GT.N0 ) 
+     $         GO TO 130
+*
+*           While submatrix unfinished take a good dqds step.
+*
+            CALL SLAZQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
+     $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
+     $                   DN2, TAU )
+*
+            PP = 1 - PP
+*
+*           When EMIN is very small check for splits.
+*
+            IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THEN
+               IF( Z( 4*N0 ).LE.TOL2*QMAX .OR.
+     $             Z( 4*N0-1 ).LE.TOL2*SIGMA ) THEN
+                  SPLT = I0 - 1
+                  QMAX = Z( 4*I0-3 )
+                  EMIN = Z( 4*I0-1 )
+                  OLDEMN = Z( 4*I0 )
+                  DO 110 I4 = 4*I0, 4*( N0-3 ), 4
+                     IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR.
+     $                   Z( I4-1 ).LE.TOL2*SIGMA ) THEN
+                        Z( I4-1 ) = -SIGMA
+                        SPLT = I4 / 4
+                        QMAX = ZERO
+                        EMIN = Z( I4+3 )
+                        OLDEMN = Z( I4+4 )
+                     ELSE
+                        QMAX = MAX( QMAX, Z( I4+1 ) )
+                        EMIN = MIN( EMIN, Z( I4-1 ) )
+                        OLDEMN = MIN( OLDEMN, Z( I4 ) )
+                     END IF
+  110             CONTINUE
+                  Z( 4*N0-1 ) = EMIN
+                  Z( 4*N0 ) = OLDEMN
+                  I0 = SPLT + 1
+               END IF
+            END IF
+*
+  120    CONTINUE
+*
+         INFO = 2
+         RETURN
+*
+*        end IWHILB
+*
+  130    CONTINUE
+*
+  140 CONTINUE
+*
+      INFO = 3
+      RETURN
+*
+*     end IWHILA   
+*
+  150 CONTINUE
+*      
+*     Move q's to the front.
+*      
+      DO 160 K = 2, N
+         Z( K ) = Z( 4*K-3 )
+  160 CONTINUE
+*      
+*     Sort and compute sum of eigenvalues.
+*
+      CALL SLASRT( 'D', N, Z, IINFO )
+*
+      E = ZERO
+      DO 170 K = N, 1, -1
+         E = E + Z( K )
+  170 CONTINUE
+*
+*     Store trace, sum(eigenvalues) and information on performance.
+*
+      Z( 2*N+1 ) = TRACE 
+      Z( 2*N+2 ) = E
+      Z( 2*N+3 ) = REAL( ITER )
+      Z( 2*N+4 ) = REAL( NDIV ) / REAL( N**2 )
+      Z( 2*N+5 ) = HUNDRD*NFAIL / REAL( ITER )
+      RETURN
+*
+*     End of SLASQ2
+*
+      END
diff --git a/libcruft/lapack/slasq3.f b/libcruft/lapack/slasq3.f
new file mode 100644
index 0000000..e72dde3
--- /dev/null
+++ b/libcruft/lapack/slasq3.f
@@ -0,0 +1,295 @@
+      SUBROUTINE SLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
+     $                   ITER, NDIV, IEEE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            I0, ITER, N0, NDIV, NFAIL, PP
+      REAL               DESIG, DMIN, QMAX, SIGMA
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.
+*  In case of failure it changes shifts, and tries again until output
+*  is positive.
+*
+*  Arguments
+*  =========
+*
+*  I0     (input) INTEGER
+*         First index.
+*
+*  N0     (input) INTEGER
+*         Last index.
+*
+*  Z      (input) REAL array, dimension ( 4*N )
+*         Z holds the qd array.
+*
+*  PP     (input) INTEGER
+*         PP=0 for ping, PP=1 for pong.
+*
+*  DMIN   (output) REAL
+*         Minimum value of d.
+*
+*  SIGMA  (output) REAL
+*         Sum of shifts used in current segment.
+*
+*  DESIG  (input/output) REAL
+*         Lower order part of SIGMA
+*
+*  QMAX   (input) REAL
+*         Maximum value of q.
+*
+*  NFAIL  (output) INTEGER
+*         Number of times shift was too big.
+*
+*  ITER   (output) INTEGER
+*         Number of iterations.
+*
+*  NDIV   (output) INTEGER
+*         Number of divisions.
+*
+*  TTYPE  (output) INTEGER
+*         Shift type.
+*
+*  IEEE   (input) LOGICAL
+*         Flag for IEEE or non IEEE arithmetic (passed to SLASQ5).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               CBIAS
+      PARAMETER          ( CBIAS = 1.50E0 )
+      REAL               ZERO, QURTR, HALF, ONE, TWO, HUNDRD
+      PARAMETER          ( ZERO = 0.0E0, QURTR = 0.250E0, HALF = 0.5E0,
+     $                     ONE = 1.0E0, TWO = 2.0E0, HUNDRD = 100.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IPN4, J4, N0IN, NN, TTYPE
+      REAL               DMIN1, DMIN2, DN, DN1, DN2, EPS, S, SAFMIN, T,
+     $                   TAU, TEMP, TOL, TOL2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASQ4, SLASQ5, SLASQ6
+*     ..
+*     .. External Function ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Save statement ..
+      SAVE               TTYPE
+      SAVE               DMIN1, DMIN2, DN, DN1, DN2, TAU
+*     ..
+*     .. Data statement ..
+      DATA               TTYPE / 0 /
+      DATA               DMIN1 / ZERO /, DMIN2 / ZERO /, DN / ZERO /,
+     $                   DN1 / ZERO /, DN2 / ZERO /, TAU / ZERO /
+*     ..
+*     .. Executable Statements ..
+*
+      N0IN = N0
+      EPS = SLAMCH( 'Precision' )
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      TOL = EPS*HUNDRD
+      TOL2 = TOL**2
+*
+*     Check for deflation.
+*
+   10 CONTINUE
+*
+      IF( N0.LT.I0 )
+     $   RETURN
+      IF( N0.EQ.I0 )
+     $   GO TO 20
+      NN = 4*N0 + PP
+      IF( N0.EQ.( I0+1 ) )
+     $   GO TO 40
+*
+*     Check whether E(N0-1) is negligible, 1 eigenvalue.
+*
+      IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
+     $    Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
+     $   GO TO 30
+*
+   20 CONTINUE
+*
+      Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
+      N0 = N0 - 1
+      GO TO 10
+*
+*     Check  whether E(N0-2) is negligible, 2 eigenvalues.
+*
+   30 CONTINUE
+*
+      IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
+     $    Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
+     $   GO TO 50
+*
+   40 CONTINUE
+*
+      IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
+         S = Z( NN-3 )
+         Z( NN-3 ) = Z( NN-7 )
+         Z( NN-7 ) = S
+      END IF
+      IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
+         T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
+         S = Z( NN-3 )*( Z( NN-5 ) / T )
+         IF( S.LE.T ) THEN
+            S = Z( NN-3 )*( Z( NN-5 ) /
+     $          ( T*( ONE+SQRT( ONE+S / T ) ) ) )
+         ELSE
+            S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
+         END IF
+         T = Z( NN-7 ) + ( S+Z( NN-5 ) )
+         Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
+         Z( NN-7 ) = T
+      END IF
+      Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
+      Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
+      N0 = N0 - 2
+      GO TO 10
+*
+   50 CONTINUE
+*
+*     Reverse the qd-array, if warranted.
+*
+      IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
+         IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
+            IPN4 = 4*( I0+N0 )
+            DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
+               TEMP = Z( J4-3 )
+               Z( J4-3 ) = Z( IPN4-J4-3 )
+               Z( IPN4-J4-3 ) = TEMP
+               TEMP = Z( J4-2 )
+               Z( J4-2 ) = Z( IPN4-J4-2 )
+               Z( IPN4-J4-2 ) = TEMP
+               TEMP = Z( J4-1 )
+               Z( J4-1 ) = Z( IPN4-J4-5 )
+               Z( IPN4-J4-5 ) = TEMP
+               TEMP = Z( J4 )
+               Z( J4 ) = Z( IPN4-J4-4 )
+               Z( IPN4-J4-4 ) = TEMP
+   60       CONTINUE
+            IF( N0-I0.LE.4 ) THEN
+               Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
+               Z( 4*N0-PP ) = Z( 4*I0-PP )
+            END IF
+            DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
+            Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
+     $                            Z( 4*I0+PP+3 ) )
+            Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
+     $                          Z( 4*I0-PP+4 ) )
+            QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
+            DMIN = -ZERO
+         END IF
+      END IF
+*
+      IF( DMIN.LT.ZERO .OR. SAFMIN*QMAX.LT.MIN( Z( 4*N0+PP-1 ),
+     $    Z( 4*N0+PP-9 ), DMIN2+Z( 4*N0-PP ) ) ) THEN
+*
+*        Choose a shift.
+*
+         CALL SLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
+     $                DN2, TAU, TTYPE )
+*
+*        Call dqds until DMIN > 0.
+*
+   80    CONTINUE
+*
+         CALL SLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
+     $                DN1, DN2, IEEE )
+*
+         NDIV = NDIV + ( N0-I0+2 )
+         ITER = ITER + 1
+*
+*        Check status.
+*
+         IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
+*
+*           Success.
+*
+            GO TO 100
+*
+         ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
+     $            Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
+     $            ABS( DN ).LT.TOL*SIGMA ) THEN
+*
+*           Convergence hidden by negative DN.
+*
+            Z( 4*( N0-1 )-PP+2 ) = ZERO
+            DMIN = ZERO
+            GO TO 100
+         ELSE IF( DMIN.LT.ZERO ) THEN
+*
+*           TAU too big. Select new TAU and try again.
+*
+            NFAIL = NFAIL + 1
+            IF( TTYPE.LT.-22 ) THEN
+*
+*              Failed twice. Play it safe.
+*
+               TAU = ZERO
+            ELSE IF( DMIN1.GT.ZERO ) THEN
+*
+*              Late failure. Gives excellent shift.
+*
+               TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
+               TTYPE = TTYPE - 11
+            ELSE
+*
+*              Early failure. Divide by 4.
+*
+               TAU = QURTR*TAU
+               TTYPE = TTYPE - 12
+            END IF
+            GO TO 80
+         ELSE IF( DMIN.NE.DMIN ) THEN
+*
+*           NaN.
+*
+            TAU = ZERO
+            GO TO 80
+         ELSE
+*
+*           Possible underflow. Play it safe.
+*
+            GO TO 90
+         END IF
+      END IF
+*
+*     Risk of underflow.
+*
+   90 CONTINUE
+      CALL SLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
+      NDIV = NDIV + ( N0-I0+2 )
+      ITER = ITER + 1
+      TAU = ZERO
+*
+  100 CONTINUE
+      IF( TAU.LT.SIGMA ) THEN
+         DESIG = DESIG + TAU
+         T = SIGMA + DESIG
+         DESIG = DESIG - ( T-SIGMA )
+      ELSE
+         T = SIGMA + TAU
+         DESIG = SIGMA - ( T-TAU ) + DESIG
+      END IF
+      SIGMA = T
+*
+      RETURN
+*
+*     End of SLASQ3
+*
+      END
diff --git a/libcruft/lapack/slasq4.f b/libcruft/lapack/slasq4.f
new file mode 100644
index 0000000..1c4bc62
--- /dev/null
+++ b/libcruft/lapack/slasq4.f
@@ -0,0 +1,329 @@
+      SUBROUTINE SLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
+     $                   DN1, DN2, TAU, TTYPE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I0, N0, N0IN, PP, TTYPE
+      REAL               DMIN, DMIN1, DMIN2, DN, DN1, DN2, TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASQ4 computes an approximation TAU to the smallest eigenvalue 
+*  using values of d from the previous transform.
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) REAL array, dimension ( 4*N )
+*        Z holds the qd array.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  N0IN  (input) INTEGER
+*        The value of N0 at start of EIGTEST.
+*
+*  DMIN  (input) REAL
+*        Minimum value of d.
+*
+*  DMIN1 (input) REAL
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (input) REAL
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (input) REAL
+*        d(N)
+*
+*  DN1   (input) REAL
+*        d(N-1)
+*
+*  DN2   (input) REAL
+*        d(N-2)
+*
+*  TAU   (output) REAL
+*        This is the shift.
+*
+*  TTYPE (output) INTEGER
+*        Shift type.
+*
+*  Further Details
+*  ===============
+*  CNST1 = 9/16
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               CNST1, CNST2, CNST3
+      PARAMETER          ( CNST1 = 0.5630E0, CNST2 = 1.010E0,
+     $                   CNST3 = 1.050E0 )
+      REAL               QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRD
+      PARAMETER          ( QURTR = 0.250E0, THIRD = 0.3330E0,
+     $                   HALF = 0.50E0, ZERO = 0.0E0, ONE = 1.0E0,
+     $                   TWO = 2.0E0, HUNDRD = 100.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I4, NN, NP
+      REAL               A2, B1, B2, G, GAM, GAP1, GAP2, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Save statement ..
+      SAVE               G
+*     ..
+*     .. Data statement ..
+      DATA               G / ZERO /
+*     ..
+*     .. Executable Statements ..
+*
+*     A negative DMIN forces the shift to take that absolute value
+*     TTYPE records the type of shift.
+*
+      IF( DMIN.LE.ZERO ) THEN
+         TAU = -DMIN
+         TTYPE = -1
+         RETURN
+      END IF
+*       
+      NN = 4*N0 + PP
+      IF( N0IN.EQ.N0 ) THEN
+*
+*        No eigenvalues deflated.
+*
+         IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN
+*
+            B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )
+            B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )
+            A2 = Z( NN-7 ) + Z( NN-5 )
+*
+*           Cases 2 and 3.
+*
+            IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THEN
+               GAP2 = DMIN2 - A2 - DMIN2*QURTR
+               IF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THEN
+                  GAP1 = A2 - DN - ( B2 / GAP2 )*B2
+               ELSE
+                  GAP1 = A2 - DN - ( B1+B2 )
+               END IF
+               IF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THEN
+                  S = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )
+                  TTYPE = -2
+               ELSE
+                  S = ZERO
+                  IF( DN.GT.B1 )
+     $               S = DN - B1
+                  IF( A2.GT.( B1+B2 ) )
+     $               S = MIN( S, A2-( B1+B2 ) )
+                  S = MAX( S, THIRD*DMIN )
+                  TTYPE = -3
+               END IF
+            ELSE
+*
+*              Case 4.
+*
+               TTYPE = -4
+               S = QURTR*DMIN
+               IF( DMIN.EQ.DN ) THEN
+                  GAM = DN
+                  A2 = ZERO
+                  IF( Z( NN-5 ) .GT. Z( NN-7 ) )
+     $               RETURN
+                  B2 = Z( NN-5 ) / Z( NN-7 )
+                  NP = NN - 9
+               ELSE
+                  NP = NN - 2*PP
+                  B2 = Z( NP-2 )
+                  GAM = DN1
+                  IF( Z( NP-4 ) .GT. Z( NP-2 ) )
+     $               RETURN
+                  A2 = Z( NP-4 ) / Z( NP-2 )
+                  IF( Z( NN-9 ) .GT. Z( NN-11 ) )
+     $               RETURN
+                  B2 = Z( NN-9 ) / Z( NN-11 )
+                  NP = NN - 13
+               END IF
+*
+*              Approximate contribution to norm squared from I < NN-1.
+*
+               A2 = A2 + B2
+               DO 10 I4 = NP, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 20
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 20
+   10          CONTINUE
+   20          CONTINUE
+               A2 = CNST3*A2
+*
+*              Rayleigh quotient residual bound.
+*
+               IF( A2.LT.CNST1 )
+     $            S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+            END IF
+         ELSE IF( DMIN.EQ.DN2 ) THEN
+*
+*           Case 5.
+*
+            TTYPE = -5
+            S = QURTR*DMIN
+*
+*           Compute contribution to norm squared from I > NN-2.
+*
+            NP = NN - 2*PP
+            B1 = Z( NP-2 )
+            B2 = Z( NP-6 )
+            GAM = DN2
+            IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 )
+     $         RETURN
+            A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )
+*
+*           Approximate contribution to norm squared from I < NN-2.
+*
+            IF( N0-I0.GT.2 ) THEN
+               B2 = Z( NN-13 ) / Z( NN-15 )
+               A2 = A2 + B2
+               DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 40
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 40
+   30          CONTINUE
+   40          CONTINUE
+               A2 = CNST3*A2
+            END IF
+*
+            IF( A2.LT.CNST1 )
+     $         S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+         ELSE
+*
+*           Case 6, no information to guide us.
+*
+            IF( TTYPE.EQ.-6 ) THEN
+               G = G + THIRD*( ONE-G )
+            ELSE IF( TTYPE.EQ.-18 ) THEN
+               G = QURTR*THIRD
+            ELSE
+               G = QURTR
+            END IF
+            S = G*DMIN
+            TTYPE = -6
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+1 ) ) THEN
+*
+*        One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.
+*
+         IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN 
+*
+*           Cases 7 and 8.
+*
+            TTYPE = -7
+            S = THIRD*DMIN1
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 60
+            DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               A2 = B1
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*MAX( B1, A2 ).LT.B2 ) 
+     $            GO TO 60
+   50       CONTINUE
+   60       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN1 / ( ONE+B2**2 )
+            GAP2 = HALF*DMIN2 - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+               TTYPE = -8
+            END IF
+         ELSE
+*
+*           Case 9.
+*
+            S = QURTR*DMIN1
+            IF( DMIN1.EQ.DN1 )
+     $         S = HALF*DMIN1
+            TTYPE = -9
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+2 ) ) THEN
+*
+*        Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
+*
+*        Cases 10 and 11.
+*
+         IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THEN 
+            TTYPE = -10
+            S = THIRD*DMIN2
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 80
+            DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*B1.LT.B2 )
+     $            GO TO 80
+   70       CONTINUE
+   80       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN2 / ( ONE+B2**2 )
+            GAP2 = Z( NN-7 ) + Z( NN-9 ) -
+     $             SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+            END IF
+         ELSE
+            S = QURTR*DMIN2
+            TTYPE = -11
+         END IF
+      ELSE IF( N0IN.GT.( N0+2 ) ) THEN
+*
+*        Case 12, more than two eigenvalues deflated. No information.
+*
+         S = ZERO 
+         TTYPE = -12
+      END IF
+*
+      TAU = S
+      RETURN
+*
+*     End of SLASQ4
+*
+      END
diff --git a/libcruft/lapack/slasq5.f b/libcruft/lapack/slasq5.f
new file mode 100644
index 0000000..6466958
--- /dev/null
+++ b/libcruft/lapack/slasq5.f
@@ -0,0 +1,195 @@
+      SUBROUTINE SLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
+     $                   DNM1, DNM2, IEEE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            I0, N0, PP
+      REAL               DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASQ5 computes one dqds transform in ping-pong form, one
+*  version for IEEE machines another for non IEEE machines.
+*
+*  Arguments
+*  =========
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) REAL array, dimension ( 4*N )
+*        Z holds the qd array. EMIN is stored in Z(4*N0) to avoid
+*        an extra argument.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  TAU   (input) REAL
+*        This is the shift.
+*
+*  DMIN  (output) REAL
+*        Minimum value of d.
+*
+*  DMIN1 (output) REAL
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (output) REAL
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (output) REAL
+*        d(N0), the last value of d.
+*
+*  DNM1  (output) REAL
+*        d(N0-1).
+*
+*  DNM2  (output) REAL
+*        d(N0-2).
+*
+*  IEEE  (input) LOGICAL
+*        Flag for IEEE or non IEEE arithmetic.
+*
+*  =====================================================================
+*
+*     .. Parameter ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J4, J4P2
+      REAL               D, EMIN, TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( ( N0-I0-1 ).LE.0 )
+     $   RETURN
+*
+      J4 = 4*I0 + PP - 3
+      EMIN = Z( J4+4 )
+      D = Z( J4 ) - TAU
+      DMIN = D
+      DMIN1 = -Z( J4 )
+*
+      IF( IEEE ) THEN
+*
+*        Code for IEEE arithmetic.
+*
+         IF( PP.EQ.0 ) THEN
+            DO 10 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-2 ) = D + Z( J4-1 )
+               TEMP = Z( J4+1 ) / Z( J4-2 )
+               D = D*TEMP - TAU
+               DMIN = MIN( DMIN, D )
+               Z( J4 ) = Z( J4-1 )*TEMP
+               EMIN = MIN( Z( J4 ), EMIN )
+   10       CONTINUE
+         ELSE
+            DO 20 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-3 ) = D + Z( J4 )
+               TEMP = Z( J4+2 ) / Z( J4-3 )
+               D = D*TEMP - TAU
+               DMIN = MIN( DMIN, D )
+               Z( J4-1 ) = Z( J4 )*TEMP
+               EMIN = MIN( Z( J4-1 ), EMIN )
+   20       CONTINUE
+         END IF
+*
+*        Unroll last two steps.
+*
+         DNM2 = D
+         DMIN2 = DMIN
+         J4 = 4*( N0-2 ) - PP
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM2 + Z( J4P2 )
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU
+         DMIN = MIN( DMIN, DNM1 )
+*
+         DMIN1 = DMIN
+         J4 = J4 + 4
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM1 + Z( J4P2 )
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU
+         DMIN = MIN( DMIN, DN )
+*
+      ELSE
+*
+*        Code for non IEEE arithmetic.
+*
+         IF( PP.EQ.0 ) THEN
+            DO 30 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-2 ) = D + Z( J4-1 )
+               IF( D.LT.ZERO ) THEN
+                  RETURN
+               ELSE
+                  Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )
+                  D = Z( J4+1 )*( D / Z( J4-2 ) ) - TAU
+               END IF
+               DMIN = MIN( DMIN, D )
+               EMIN = MIN( EMIN, Z( J4 ) )
+   30       CONTINUE
+         ELSE
+            DO 40 J4 = 4*I0, 4*( N0-3 ), 4
+               Z( J4-3 ) = D + Z( J4 )
+               IF( D.LT.ZERO ) THEN
+                  RETURN
+               ELSE
+                  Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )
+                  D = Z( J4+2 )*( D / Z( J4-3 ) ) - TAU
+               END IF
+               DMIN = MIN( DMIN, D )
+               EMIN = MIN( EMIN, Z( J4-1 ) )
+   40       CONTINUE
+         END IF
+*
+*        Unroll last two steps.
+*
+         DNM2 = D
+         DMIN2 = DMIN
+         J4 = 4*( N0-2 ) - PP
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM2 + Z( J4P2 )
+         IF( DNM2.LT.ZERO ) THEN
+            RETURN
+         ELSE
+            Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+            DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU
+         END IF
+         DMIN = MIN( DMIN, DNM1 )
+*
+         DMIN1 = DMIN
+         J4 = J4 + 4
+         J4P2 = J4 + 2*PP - 1
+         Z( J4-2 ) = DNM1 + Z( J4P2 )
+         IF( DNM1.LT.ZERO ) THEN
+            RETURN
+         ELSE
+            Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+            DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU
+         END IF
+         DMIN = MIN( DMIN, DN )
+*
+      END IF
+*
+      Z( J4+2 ) = DN
+      Z( 4*N0-PP ) = EMIN
+      RETURN
+*
+*     End of SLASQ5
+*
+      END
diff --git a/libcruft/lapack/slasq6.f b/libcruft/lapack/slasq6.f
new file mode 100644
index 0000000..f09d8cf
--- /dev/null
+++ b/libcruft/lapack/slasq6.f
@@ -0,0 +1,175 @@
+      SUBROUTINE SLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN,
+     $                   DNM1, DNM2 )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I0, N0, PP
+      REAL               DMIN, DMIN1, DMIN2, DN, DNM1, DNM2
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASQ6 computes one dqd (shift equal to zero) transform in
+*  ping-pong form, with protection against underflow and overflow.
+*
+*  Arguments
+*  =========
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) REAL array, dimension ( 4*N )
+*        Z holds the qd array. EMIN is stored in Z(4*N0) to avoid
+*        an extra argument.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  DMIN  (output) REAL
+*        Minimum value of d.
+*
+*  DMIN1 (output) REAL
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (output) REAL
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (output) REAL
+*        d(N0), the last value of d.
+*
+*  DNM1  (output) REAL
+*        d(N0-1).
+*
+*  DNM2  (output) REAL
+*        d(N0-2).
+*
+*  =====================================================================
+*
+*     .. Parameter ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J4, J4P2
+      REAL               D, EMIN, SAFMIN, TEMP
+*     ..
+*     .. External Function ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( ( N0-I0-1 ).LE.0 )
+     $   RETURN
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      J4 = 4*I0 + PP - 3
+      EMIN = Z( J4+4 ) 
+      D = Z( J4 )
+      DMIN = D
+*
+      IF( PP.EQ.0 ) THEN
+         DO 10 J4 = 4*I0, 4*( N0-3 ), 4
+            Z( J4-2 ) = D + Z( J4-1 ) 
+            IF( Z( J4-2 ).EQ.ZERO ) THEN
+               Z( J4 ) = ZERO
+               D = Z( J4+1 )
+               DMIN = D
+               EMIN = ZERO
+            ELSE IF( SAFMIN*Z( J4+1 ).LT.Z( J4-2 ) .AND.
+     $               SAFMIN*Z( J4-2 ).LT.Z( J4+1 ) ) THEN
+               TEMP = Z( J4+1 ) / Z( J4-2 )
+               Z( J4 ) = Z( J4-1 )*TEMP
+               D = D*TEMP
+            ELSE 
+               Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )
+               D = Z( J4+1 )*( D / Z( J4-2 ) )
+            END IF
+            DMIN = MIN( DMIN, D )
+            EMIN = MIN( EMIN, Z( J4 ) )
+   10    CONTINUE
+      ELSE
+         DO 20 J4 = 4*I0, 4*( N0-3 ), 4
+            Z( J4-3 ) = D + Z( J4 ) 
+            IF( Z( J4-3 ).EQ.ZERO ) THEN
+               Z( J4-1 ) = ZERO
+               D = Z( J4+2 )
+               DMIN = D
+               EMIN = ZERO
+            ELSE IF( SAFMIN*Z( J4+2 ).LT.Z( J4-3 ) .AND.
+     $               SAFMIN*Z( J4-3 ).LT.Z( J4+2 ) ) THEN
+               TEMP = Z( J4+2 ) / Z( J4-3 )
+               Z( J4-1 ) = Z( J4 )*TEMP
+               D = D*TEMP
+            ELSE 
+               Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )
+               D = Z( J4+2 )*( D / Z( J4-3 ) )
+            END IF
+            DMIN = MIN( DMIN, D )
+            EMIN = MIN( EMIN, Z( J4-1 ) )
+   20    CONTINUE
+      END IF
+*
+*     Unroll last two steps. 
+*
+      DNM2 = D
+      DMIN2 = DMIN
+      J4 = 4*( N0-2 ) - PP
+      J4P2 = J4 + 2*PP - 1
+      Z( J4-2 ) = DNM2 + Z( J4P2 )
+      IF( Z( J4-2 ).EQ.ZERO ) THEN
+         Z( J4 ) = ZERO
+         DNM1 = Z( J4P2+2 )
+         DMIN = DNM1
+         EMIN = ZERO
+      ELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND.
+     $         SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THEN
+         TEMP = Z( J4P2+2 ) / Z( J4-2 )
+         Z( J4 ) = Z( J4P2 )*TEMP
+         DNM1 = DNM2*TEMP
+      ELSE
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) )
+      END IF
+      DMIN = MIN( DMIN, DNM1 )
+*
+      DMIN1 = DMIN
+      J4 = J4 + 4
+      J4P2 = J4 + 2*PP - 1
+      Z( J4-2 ) = DNM1 + Z( J4P2 )
+      IF( Z( J4-2 ).EQ.ZERO ) THEN
+         Z( J4 ) = ZERO
+         DN = Z( J4P2+2 )
+         DMIN = DN
+         EMIN = ZERO
+      ELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND.
+     $         SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THEN
+         TEMP = Z( J4P2+2 ) / Z( J4-2 )
+         Z( J4 ) = Z( J4P2 )*TEMP
+         DN = DNM1*TEMP
+      ELSE
+         Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )
+         DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) )
+      END IF
+      DMIN = MIN( DMIN, DN )
+*
+      Z( J4+2 ) = DN
+      Z( 4*N0-PP ) = EMIN
+      RETURN
+*
+*     End of SLASQ6
+*
+      END
diff --git a/libcruft/lapack/slasr.f b/libcruft/lapack/slasr.f
new file mode 100644
index 0000000..651d9a4
--- /dev/null
+++ b/libcruft/lapack/slasr.f
@@ -0,0 +1,361 @@
+      SUBROUTINE SLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, PIVOT, SIDE
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( * ), S( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASR applies a sequence of plane rotations to a real matrix A,
+*  from either the left or the right.
+*  
+*  When SIDE = 'L', the transformation takes the form
+*  
+*     A := P*A
+*  
+*  and when SIDE = 'R', the transformation takes the form
+*  
+*     A := A*P**T
+*  
+*  where P is an orthogonal matrix consisting of a sequence of z plane
+*  rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',
+*  and P**T is the transpose of P.
+*  
+*  When DIRECT = 'F' (Forward sequence), then
+*  
+*     P = P(z-1) * ... * P(2) * P(1)
+*  
+*  and when DIRECT = 'B' (Backward sequence), then
+*  
+*     P = P(1) * P(2) * ... * P(z-1)
+*  
+*  where P(k) is a plane rotation matrix defined by the 2-by-2 rotation
+*  
+*     R(k) = (  c(k)  s(k) )
+*          = ( -s(k)  c(k) ).
+*  
+*  When PIVOT = 'V' (Variable pivot), the rotation is performed
+*  for the plane (k,k+1), i.e., P(k) has the form
+*  
+*     P(k) = (  1                                            )
+*            (       ...                                     )
+*            (              1                                )
+*            (                   c(k)  s(k)                  )
+*            (                  -s(k)  c(k)                  )
+*            (                                1              )
+*            (                                     ...       )
+*            (                                            1  )
+*  
+*  where R(k) appears as a rank-2 modification to the identity matrix in
+*  rows and columns k and k+1.
+*  
+*  When PIVOT = 'T' (Top pivot), the rotation is performed for the
+*  plane (1,k+1), so P(k) has the form
+*  
+*     P(k) = (  c(k)                    s(k)                 )
+*            (         1                                     )
+*            (              ...                              )
+*            (                     1                         )
+*            ( -s(k)                    c(k)                 )
+*            (                                 1             )
+*            (                                      ...      )
+*            (                                             1 )
+*  
+*  where R(k) appears in rows and columns 1 and k+1.
+*  
+*  Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is
+*  performed for the plane (k,z), giving P(k) the form
+*  
+*     P(k) = ( 1                                             )
+*            (      ...                                      )
+*            (             1                                 )
+*            (                  c(k)                    s(k) )
+*            (                         1                     )
+*            (                              ...              )
+*            (                                     1         )
+*            (                 -s(k)                    c(k) )
+*  
+*  where R(k) appears in rows and columns k and z.  The rotations are
+*  performed without ever forming P(k) explicitly.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          Specifies whether the plane rotation matrix P is applied to
+*          A on the left or the right.
+*          = 'L':  Left, compute A := P*A
+*          = 'R':  Right, compute A:= A*P**T
+*
+*  PIVOT   (input) CHARACTER*1
+*          Specifies the plane for which P(k) is a plane rotation
+*          matrix.
+*          = 'V':  Variable pivot, the plane (k,k+1)
+*          = 'T':  Top pivot, the plane (1,k+1)
+*          = 'B':  Bottom pivot, the plane (k,z)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies whether P is a forward or backward sequence of
+*          plane rotations.
+*          = 'F':  Forward, P = P(z-1)*...*P(2)*P(1)
+*          = 'B':  Backward, P = P(1)*P(2)*...*P(z-1)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  If m <= 1, an immediate
+*          return is effected.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  If n <= 1, an
+*          immediate return is effected.
+*
+*  C       (input) REAL array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The cosines c(k) of the plane rotations.
+*
+*  S       (input) REAL array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The sines s(k) of the plane rotations.  The 2-by-2 plane
+*          rotation part of the matrix P(k), R(k), has the form
+*          R(k) = (  c(k)  s(k) )
+*                 ( -s(k)  c(k) ).
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          The M-by-N matrix A.  On exit, A is overwritten by P*A if
+*          SIDE = 'R' or by A*P**T if SIDE = 'L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+      REAL               CTEMP, STEMP, TEMP
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THEN
+         INFO = 1
+      ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT,
+     $         'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THEN
+         INFO = 2
+      ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) )
+     $          THEN
+         INFO = 3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = 4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASR ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  P * A
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 20 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 10 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 40 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 30 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   30                CONTINUE
+                  END IF
+   40          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 60 J = 2, M
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 50 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 80 J = M, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 70 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   70                CONTINUE
+                  END IF
+   80          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 100 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 90 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+   90                CONTINUE
+                  END IF
+  100          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 120 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 110 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+  110                CONTINUE
+                  END IF
+  120          CONTINUE
+            END IF
+         END IF
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form A * P'
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 140 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 130 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  130                CONTINUE
+                  END IF
+  140          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 160 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 150 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  150                CONTINUE
+                  END IF
+  160          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 180 J = 2, N
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 170 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  170                CONTINUE
+                  END IF
+  180          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 200 J = N, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 190 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  190                CONTINUE
+                  END IF
+  200          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 220 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 210 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  210                CONTINUE
+                  END IF
+  220          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 240 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 230 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  230                CONTINUE
+                  END IF
+  240          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of SLASR
+*
+      END
diff --git a/libcruft/lapack/slasrt.f b/libcruft/lapack/slasrt.f
new file mode 100644
index 0000000..a6188c0
--- /dev/null
+++ b/libcruft/lapack/slasrt.f
@@ -0,0 +1,243 @@
+      SUBROUTINE SLASRT( ID, N, D, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          ID
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  Sort the numbers in D in increasing order (if ID = 'I') or
+*  in decreasing order (if ID = 'D' ).
+*
+*  Use Quick Sort, reverting to Insertion sort on arrays of
+*  size <= 20. Dimension of STACK limits N to about 2**32.
+*
+*  Arguments
+*  =========
+*
+*  ID      (input) CHARACTER*1
+*          = 'I': sort D in increasing order;
+*          = 'D': sort D in decreasing order.
+*
+*  N       (input) INTEGER
+*          The length of the array D.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the array to be sorted.
+*          On exit, D has been sorted into increasing order
+*          (D(1) <= ... <= D(N) ) or into decreasing order
+*          (D(1) >= ... >= D(N) ), depending on ID.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            SELECT
+      PARAMETER          ( SELECT = 20 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            DIR, ENDD, I, J, START, STKPNT
+      REAL               D1, D2, D3, DMNMX, TMP
+*     ..
+*     .. Local Arrays ..
+      INTEGER            STACK( 2, 32 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input paramters.
+*
+      INFO = 0
+      DIR = -1
+      IF( LSAME( ID, 'D' ) ) THEN
+         DIR = 0
+      ELSE IF( LSAME( ID, 'I' ) ) THEN
+         DIR = 1
+      END IF
+      IF( DIR.EQ.-1 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLASRT', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      STKPNT = 1
+      STACK( 1, 1 ) = 1
+      STACK( 2, 1 ) = N
+   10 CONTINUE
+      START = STACK( 1, STKPNT )
+      ENDD = STACK( 2, STKPNT )
+      STKPNT = STKPNT - 1
+      IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN
+*
+*        Do Insertion sort on D( START:ENDD )
+*
+         IF( DIR.EQ.0 ) THEN
+*
+*           Sort into decreasing order
+*
+            DO 30 I = START + 1, ENDD
+               DO 20 J = I, START + 1, -1
+                  IF( D( J ).GT.D( J-1 ) ) THEN
+                     DMNMX = D( J )
+                     D( J ) = D( J-1 )
+                     D( J-1 ) = DMNMX
+                  ELSE
+                     GO TO 30
+                  END IF
+   20          CONTINUE
+   30       CONTINUE
+*
+         ELSE
+*
+*           Sort into increasing order
+*
+            DO 50 I = START + 1, ENDD
+               DO 40 J = I, START + 1, -1
+                  IF( D( J ).LT.D( J-1 ) ) THEN
+                     DMNMX = D( J )
+                     D( J ) = D( J-1 )
+                     D( J-1 ) = DMNMX
+                  ELSE
+                     GO TO 50
+                  END IF
+   40          CONTINUE
+   50       CONTINUE
+*
+         END IF
+*
+      ELSE IF( ENDD-START.GT.SELECT ) THEN
+*
+*        Partition D( START:ENDD ) and stack parts, largest one first
+*
+*        Choose partition entry as median of 3
+*
+         D1 = D( START )
+         D2 = D( ENDD )
+         I = ( START+ENDD ) / 2
+         D3 = D( I )
+         IF( D1.LT.D2 ) THEN
+            IF( D3.LT.D1 ) THEN
+               DMNMX = D1
+            ELSE IF( D3.LT.D2 ) THEN
+               DMNMX = D3
+            ELSE
+               DMNMX = D2
+            END IF
+         ELSE
+            IF( D3.LT.D2 ) THEN
+               DMNMX = D2
+            ELSE IF( D3.LT.D1 ) THEN
+               DMNMX = D3
+            ELSE
+               DMNMX = D1
+            END IF
+         END IF
+*
+         IF( DIR.EQ.0 ) THEN
+*
+*           Sort into decreasing order
+*
+            I = START - 1
+            J = ENDD + 1
+   60       CONTINUE
+   70       CONTINUE
+            J = J - 1
+            IF( D( J ).LT.DMNMX )
+     $         GO TO 70
+   80       CONTINUE
+            I = I + 1
+            IF( D( I ).GT.DMNMX )
+     $         GO TO 80
+            IF( I.LT.J ) THEN
+               TMP = D( I )
+               D( I ) = D( J )
+               D( J ) = TMP
+               GO TO 60
+            END IF
+            IF( J-START.GT.ENDD-J-1 ) THEN
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+            ELSE
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+            END IF
+         ELSE
+*
+*           Sort into increasing order
+*
+            I = START - 1
+            J = ENDD + 1
+   90       CONTINUE
+  100       CONTINUE
+            J = J - 1
+            IF( D( J ).GT.DMNMX )
+     $         GO TO 100
+  110       CONTINUE
+            I = I + 1
+            IF( D( I ).LT.DMNMX )
+     $         GO TO 110
+            IF( I.LT.J ) THEN
+               TMP = D( I )
+               D( I ) = D( J )
+               D( J ) = TMP
+               GO TO 90
+            END IF
+            IF( J-START.GT.ENDD-J-1 ) THEN
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+            ELSE
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = J + 1
+               STACK( 2, STKPNT ) = ENDD
+               STKPNT = STKPNT + 1
+               STACK( 1, STKPNT ) = START
+               STACK( 2, STKPNT ) = J
+            END IF
+         END IF
+      END IF
+      IF( STKPNT.GT.0 )
+     $   GO TO 10
+      RETURN
+*
+*     End of SLASRT
+*
+      END
diff --git a/libcruft/lapack/slassq.f b/libcruft/lapack/slassq.f
new file mode 100644
index 0000000..e69b3a8
--- /dev/null
+++ b/libcruft/lapack/slassq.f
@@ -0,0 +1,88 @@
+      SUBROUTINE SLASSQ( N, X, INCX, SCALE, SUMSQ )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      REAL               SCALE, SUMSQ
+*     ..
+*     .. Array Arguments ..
+      REAL               X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASSQ  returns the values  scl  and  smsq  such that
+*
+*     ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
+*
+*  where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
+*  assumed to be non-negative and  scl  returns the value
+*
+*     scl = max( scale, abs( x( i ) ) ).
+*
+*  scale and sumsq must be supplied in SCALE and SUMSQ and
+*  scl and smsq are overwritten on SCALE and SUMSQ respectively.
+*
+*  The routine makes only one pass through the vector x.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements to be used from the vector X.
+*
+*  X       (input) REAL array, dimension (N)
+*          The vector for which a scaled sum of squares is computed.
+*             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector X.
+*          INCX > 0.
+*
+*  SCALE   (input/output) REAL
+*          On entry, the value  scale  in the equation above.
+*          On exit, SCALE is overwritten with  scl , the scaling factor
+*          for the sum of squares.
+*
+*  SUMSQ   (input/output) REAL
+*          On entry, the value  sumsq  in the equation above.
+*          On exit, SUMSQ is overwritten with  smsq , the basic sum of
+*          squares from which  scl  has been factored out.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IX
+      REAL               ABSXI
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.GT.0 ) THEN
+         DO 10 IX = 1, 1 + ( N-1 )*INCX, INCX
+            IF( X( IX ).NE.ZERO ) THEN
+               ABSXI = ABS( X( IX ) )
+               IF( SCALE.LT.ABSXI ) THEN
+                  SUMSQ = 1 + SUMSQ*( SCALE / ABSXI )**2
+                  SCALE = ABSXI
+               ELSE
+                  SUMSQ = SUMSQ + ( ABSXI / SCALE )**2
+               END IF
+            END IF
+   10    CONTINUE
+      END IF
+      RETURN
+*
+*     End of SLASSQ
+*
+      END
diff --git a/libcruft/lapack/slasv2.f b/libcruft/lapack/slasv2.f
new file mode 100644
index 0000000..a871730
--- /dev/null
+++ b/libcruft/lapack/slasv2.f
@@ -0,0 +1,249 @@
+      SUBROUTINE SLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      REAL               CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASV2 computes the singular value decomposition of a 2-by-2
+*  triangular matrix
+*     [  F   G  ]
+*     [  0   H  ].
+*  On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the
+*  smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and
+*  right singular vectors for abs(SSMAX), giving the decomposition
+*
+*     [ CSL  SNL ] [  F   G  ] [ CSR -SNR ]  =  [ SSMAX   0   ]
+*     [-SNL  CSL ] [  0   H  ] [ SNR  CSR ]     [  0    SSMIN ].
+*
+*  Arguments
+*  =========
+*
+*  F       (input) REAL
+*          The (1,1) element of the 2-by-2 matrix.
+*
+*  G       (input) REAL
+*          The (1,2) element of the 2-by-2 matrix.
+*
+*  H       (input) REAL
+*          The (2,2) element of the 2-by-2 matrix.
+*
+*  SSMIN   (output) REAL
+*          abs(SSMIN) is the smaller singular value.
+*
+*  SSMAX   (output) REAL
+*          abs(SSMAX) is the larger singular value.
+*
+*  SNL     (output) REAL
+*  CSL     (output) REAL
+*          The vector (CSL, SNL) is a unit left singular vector for the
+*          singular value abs(SSMAX).
+*
+*  SNR     (output) REAL
+*  CSR     (output) REAL
+*          The vector (CSR, SNR) is a unit right singular vector for the
+*          singular value abs(SSMAX).
+*
+*  Further Details
+*  ===============
+*
+*  Any input parameter may be aliased with any output parameter.
+*
+*  Barring over/underflow and assuming a guard digit in subtraction, all
+*  output quantities are correct to within a few units in the last
+*  place (ulps).
+*
+*  In IEEE arithmetic, the code works correctly if one matrix element is
+*  infinite.
+*
+*  Overflow will not occur unless the largest singular value itself
+*  overflows or is within a few ulps of overflow. (On machines with
+*  partial overflow, like the Cray, overflow may occur if the largest
+*  singular value is within a factor of 2 of overflow.)
+*
+*  Underflow is harmless if underflow is gradual. Otherwise, results
+*  may correspond to a matrix modified by perturbations of size near
+*  the underflow threshold.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E0 )
+      REAL               HALF
+      PARAMETER          ( HALF = 0.5E0 )
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E0 )
+      REAL               TWO
+      PARAMETER          ( TWO = 2.0E0 )
+      REAL               FOUR
+      PARAMETER          ( FOUR = 4.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            GASMAL, SWAP
+      INTEGER            PMAX
+      REAL               A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M,
+     $                   MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Executable Statements ..
+*
+      FT = F
+      FA = ABS( FT )
+      HT = H
+      HA = ABS( H )
+*
+*     PMAX points to the maximum absolute element of matrix
+*       PMAX = 1 if F largest in absolute values
+*       PMAX = 2 if G largest in absolute values
+*       PMAX = 3 if H largest in absolute values
+*
+      PMAX = 1
+      SWAP = ( HA.GT.FA )
+      IF( SWAP ) THEN
+         PMAX = 3
+         TEMP = FT
+         FT = HT
+         HT = TEMP
+         TEMP = FA
+         FA = HA
+         HA = TEMP
+*
+*        Now FA .ge. HA
+*
+      END IF
+      GT = G
+      GA = ABS( GT )
+      IF( GA.EQ.ZERO ) THEN
+*
+*        Diagonal matrix
+*
+         SSMIN = HA
+         SSMAX = FA
+         CLT = ONE
+         CRT = ONE
+         SLT = ZERO
+         SRT = ZERO
+      ELSE
+         GASMAL = .TRUE.
+         IF( GA.GT.FA ) THEN
+            PMAX = 2
+            IF( ( FA / GA ).LT.SLAMCH( 'EPS' ) ) THEN
+*
+*              Case of very large GA
+*
+               GASMAL = .FALSE.
+               SSMAX = GA
+               IF( HA.GT.ONE ) THEN
+                  SSMIN = FA / ( GA / HA )
+               ELSE
+                  SSMIN = ( FA / GA )*HA
+               END IF
+               CLT = ONE
+               SLT = HT / GT
+               SRT = ONE
+               CRT = FT / GT
+            END IF
+         END IF
+         IF( GASMAL ) THEN
+*
+*           Normal case
+*
+            D = FA - HA
+            IF( D.EQ.FA ) THEN
+*
+*              Copes with infinite F or H
+*
+               L = ONE
+            ELSE
+               L = D / FA
+            END IF
+*
+*           Note that 0 .le. L .le. 1
+*
+            M = GT / FT
+*
+*           Note that abs(M) .le. 1/macheps
+*
+            T = TWO - L
+*
+*           Note that T .ge. 1
+*
+            MM = M*M
+            TT = T*T
+            S = SQRT( TT+MM )
+*
+*           Note that 1 .le. S .le. 1 + 1/macheps
+*
+            IF( L.EQ.ZERO ) THEN
+               R = ABS( M )
+            ELSE
+               R = SQRT( L*L+MM )
+            END IF
+*
+*           Note that 0 .le. R .le. 1 + 1/macheps
+*
+            A = HALF*( S+R )
+*
+*           Note that 1 .le. A .le. 1 + abs(M)
+*
+            SSMIN = HA / A
+            SSMAX = FA*A
+            IF( MM.EQ.ZERO ) THEN
+*
+*              Note that M is very tiny
+*
+               IF( L.EQ.ZERO ) THEN
+                  T = SIGN( TWO, FT )*SIGN( ONE, GT )
+               ELSE
+                  T = GT / SIGN( D, FT ) + M / T
+               END IF
+            ELSE
+               T = ( M / ( S+T )+M / ( R+L ) )*( ONE+A )
+            END IF
+            L = SQRT( T*T+FOUR )
+            CRT = TWO / L
+            SRT = T / L
+            CLT = ( CRT+SRT*M ) / A
+            SLT = ( HT / FT )*SRT / A
+         END IF
+      END IF
+      IF( SWAP ) THEN
+         CSL = SRT
+         SNL = CRT
+         CSR = SLT
+         SNR = CLT
+      ELSE
+         CSL = CLT
+         SNL = SLT
+         CSR = CRT
+         SNR = SRT
+      END IF
+*
+*     Correct signs of SSMAX and SSMIN
+*
+      IF( PMAX.EQ.1 )
+     $   TSIGN = SIGN( ONE, CSR )*SIGN( ONE, CSL )*SIGN( ONE, F )
+      IF( PMAX.EQ.2 )
+     $   TSIGN = SIGN( ONE, SNR )*SIGN( ONE, CSL )*SIGN( ONE, G )
+      IF( PMAX.EQ.3 )
+     $   TSIGN = SIGN( ONE, SNR )*SIGN( ONE, SNL )*SIGN( ONE, H )
+      SSMAX = SIGN( SSMAX, TSIGN )
+      SSMIN = SIGN( SSMIN, TSIGN*SIGN( ONE, F )*SIGN( ONE, H ) )
+      RETURN
+*
+*     End of SLASV2
+*
+      END
diff --git a/libcruft/lapack/slaswp.f b/libcruft/lapack/slaswp.f
new file mode 100644
index 0000000..8b79fb7
--- /dev/null
+++ b/libcruft/lapack/slaswp.f
@@ -0,0 +1,119 @@
+      SUBROUTINE SLASWP( N, A, LDA, K1, K2, IPIV, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, K1, K2, LDA, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASWP performs a series of row interchanges on the matrix A.
+*  One row interchange is initiated for each of rows K1 through K2 of A.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the matrix of column dimension N to which the row
+*          interchanges will be applied.
+*          On exit, the permuted matrix.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*
+*  K1      (input) INTEGER
+*          The first element of IPIV for which a row interchange will
+*          be done.
+*
+*  K2      (input) INTEGER
+*          The last element of IPIV for which a row interchange will
+*          be done.
+*
+*  IPIV    (input) INTEGER array, dimension (K2*abs(INCX))
+*          The vector of pivot indices.  Only the elements in positions
+*          K1 through K2 of IPIV are accessed.
+*          IPIV(K) = L implies rows K and L are to be interchanged.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of IPIV.  If IPIV
+*          is negative, the pivots are applied in reverse order.
+*
+*  Further Details
+*  ===============
+*
+*  Modified by
+*   R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, I1, I2, INC, IP, IX, IX0, J, K, N32
+      REAL               TEMP
+*     ..
+*     .. Executable Statements ..
+*
+*     Interchange row I with row IPIV(I) for each of rows K1 through K2.
+*
+      IF( INCX.GT.0 ) THEN
+         IX0 = K1
+         I1 = K1
+         I2 = K2
+         INC = 1
+      ELSE IF( INCX.LT.0 ) THEN
+         IX0 = 1 + ( 1-K2 )*INCX
+         I1 = K2
+         I2 = K1
+         INC = -1
+      ELSE
+         RETURN
+      END IF
+*
+      N32 = ( N / 32 )*32
+      IF( N32.NE.0 ) THEN
+         DO 30 J = 1, N32, 32
+            IX = IX0
+            DO 20 I = I1, I2, INC
+               IP = IPIV( IX )
+               IF( IP.NE.I ) THEN
+                  DO 10 K = J, J + 31
+                     TEMP = A( I, K )
+                     A( I, K ) = A( IP, K )
+                     A( IP, K ) = TEMP
+   10             CONTINUE
+               END IF
+               IX = IX + INCX
+   20       CONTINUE
+   30    CONTINUE
+      END IF
+      IF( N32.NE.N ) THEN
+         N32 = N32 + 1
+         IX = IX0
+         DO 50 I = I1, I2, INC
+            IP = IPIV( IX )
+            IF( IP.NE.I ) THEN
+               DO 40 K = N32, N
+                  TEMP = A( I, K )
+                  A( I, K ) = A( IP, K )
+                  A( IP, K ) = TEMP
+   40          CONTINUE
+            END IF
+            IX = IX + INCX
+   50    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SLASWP
+*
+      END
diff --git a/libcruft/lapack/slasy2.f b/libcruft/lapack/slasy2.f
new file mode 100644
index 0000000..fb88a08
--- /dev/null
+++ b/libcruft/lapack/slasy2.f
@@ -0,0 +1,381 @@
+      SUBROUTINE SLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,
+     $                   LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            LTRANL, LTRANR
+      INTEGER            INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2
+      REAL               SCALE, XNORM
+*     ..
+*     .. Array Arguments ..
+      REAL               B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),
+     $                   X( LDX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in
+*
+*         op(TL)*X + ISGN*X*op(TR) = SCALE*B,
+*
+*  where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or
+*  -1.  op(T) = T or T', where T' denotes the transpose of T.
+*
+*  Arguments
+*  =========
+*
+*  LTRANL  (input) LOGICAL
+*          On entry, LTRANL specifies the op(TL):
+*             = .FALSE., op(TL) = TL,
+*             = .TRUE., op(TL) = TL'.
+*
+*  LTRANR  (input) LOGICAL
+*          On entry, LTRANR specifies the op(TR):
+*            = .FALSE., op(TR) = TR,
+*            = .TRUE., op(TR) = TR'.
+*
+*  ISGN    (input) INTEGER
+*          On entry, ISGN specifies the sign of the equation
+*          as described before. ISGN may only be 1 or -1.
+*
+*  N1      (input) INTEGER
+*          On entry, N1 specifies the order of matrix TL.
+*          N1 may only be 0, 1 or 2.
+*
+*  N2      (input) INTEGER
+*          On entry, N2 specifies the order of matrix TR.
+*          N2 may only be 0, 1 or 2.
+*
+*  TL      (input) REAL array, dimension (LDTL,2)
+*          On entry, TL contains an N1 by N1 matrix.
+*
+*  LDTL    (input) INTEGER
+*          The leading dimension of the matrix TL. LDTL >= max(1,N1).
+*
+*  TR      (input) REAL array, dimension (LDTR,2)
+*          On entry, TR contains an N2 by N2 matrix.
+*
+*  LDTR    (input) INTEGER
+*          The leading dimension of the matrix TR. LDTR >= max(1,N2).
+*
+*  B       (input) REAL array, dimension (LDB,2)
+*          On entry, the N1 by N2 matrix B contains the right-hand
+*          side of the equation.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the matrix B. LDB >= max(1,N1).
+*
+*  SCALE   (output) REAL
+*          On exit, SCALE contains the scale factor. SCALE is chosen
+*          less than or equal to 1 to prevent the solution overflowing.
+*
+*  X       (output) REAL array, dimension (LDX,2)
+*          On exit, X contains the N1 by N2 solution.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of the matrix X. LDX >= max(1,N1).
+*
+*  XNORM   (output) REAL
+*          On exit, XNORM is the infinity-norm of the solution.
+*
+*  INFO    (output) INTEGER
+*          On exit, INFO is set to
+*             0: successful exit.
+*             1: TL and TR have too close eigenvalues, so TL or
+*                TR is perturbed to get a nonsingular equation.
+*          NOTE: In the interests of speed, this routine does not
+*                check the inputs for errors.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      REAL               TWO, HALF, EIGHT
+      PARAMETER          ( TWO = 2.0E+0, HALF = 0.5E+0, EIGHT = 8.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            BSWAP, XSWAP
+      INTEGER            I, IP, IPIV, IPSV, J, JP, JPSV, K
+      REAL               BET, EPS, GAM, L21, SGN, SMIN, SMLNUM, TAU1,
+     $                   TEMP, U11, U12, U22, XMAX
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            BSWPIV( 4 ), XSWPIV( 4 )
+      INTEGER            JPIV( 4 ), LOCL21( 4 ), LOCU12( 4 ),
+     $                   LOCU22( 4 )
+      REAL               BTMP( 4 ), T16( 4, 4 ), TMP( 4 ), X2( 2 )
+*     ..
+*     .. External Functions ..
+      INTEGER            ISAMAX
+      REAL               SLAMCH
+      EXTERNAL           ISAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SCOPY, SSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Data statements ..
+      DATA               LOCU12 / 3, 4, 1, 2 / , LOCL21 / 2, 1, 4, 3 / ,
+     $                   LOCU22 / 4, 3, 2, 1 /
+      DATA               XSWPIV / .FALSE., .FALSE., .TRUE., .TRUE. /
+      DATA               BSWPIV / .FALSE., .TRUE., .FALSE., .TRUE. /
+*     ..
+*     .. Executable Statements ..
+*
+*     Do not check the input parameters for errors
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N1.EQ.0 .OR. N2.EQ.0 )
+     $   RETURN
+*
+*     Set constants to control overflow
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' ) / EPS
+      SGN = ISGN
+*
+      K = N1 + N1 + N2 - 2
+      GO TO ( 10, 20, 30, 50 )K
+*
+*     1 by 1: TL11*X + SGN*X*TR11 = B11
+*
+   10 CONTINUE
+      TAU1 = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      BET = ABS( TAU1 )
+      IF( BET.LE.SMLNUM ) THEN
+         TAU1 = SMLNUM
+         BET = SMLNUM
+         INFO = 1
+      END IF
+*
+      SCALE = ONE
+      GAM = ABS( B( 1, 1 ) )
+      IF( SMLNUM*GAM.GT.BET )
+     $   SCALE = ONE / GAM
+*
+      X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / TAU1
+      XNORM = ABS( X( 1, 1 ) )
+      RETURN
+*
+*     1 by 2:
+*     TL11*[X11 X12] + ISGN*[X11 X12]*op[TR11 TR12]  = [B11 B12]
+*                                       [TR21 TR22]
+*
+   20 CONTINUE
+*
+      SMIN = MAX( EPS*MAX( ABS( TL( 1, 1 ) ), ABS( TR( 1, 1 ) ),
+     $       ABS( TR( 1, 2 ) ), ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) ),
+     $       SMLNUM )
+      TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      TMP( 4 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )
+      IF( LTRANR ) THEN
+         TMP( 2 ) = SGN*TR( 2, 1 )
+         TMP( 3 ) = SGN*TR( 1, 2 )
+      ELSE
+         TMP( 2 ) = SGN*TR( 1, 2 )
+         TMP( 3 ) = SGN*TR( 2, 1 )
+      END IF
+      BTMP( 1 ) = B( 1, 1 )
+      BTMP( 2 ) = B( 1, 2 )
+      GO TO 40
+*
+*     2 by 1:
+*          op[TL11 TL12]*[X11] + ISGN* [X11]*TR11  = [B11]
+*            [TL21 TL22] [X21]         [X21]         [B21]
+*
+   30 CONTINUE
+      SMIN = MAX( EPS*MAX( ABS( TR( 1, 1 ) ), ABS( TL( 1, 1 ) ),
+     $       ABS( TL( 1, 2 ) ), ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) ),
+     $       SMLNUM )
+      TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      TMP( 4 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )
+      IF( LTRANL ) THEN
+         TMP( 2 ) = TL( 1, 2 )
+         TMP( 3 ) = TL( 2, 1 )
+      ELSE
+         TMP( 2 ) = TL( 2, 1 )
+         TMP( 3 ) = TL( 1, 2 )
+      END IF
+      BTMP( 1 ) = B( 1, 1 )
+      BTMP( 2 ) = B( 2, 1 )
+   40 CONTINUE
+*
+*     Solve 2 by 2 system using complete pivoting.
+*     Set pivots less than SMIN to SMIN.
+*
+      IPIV = ISAMAX( 4, TMP, 1 )
+      U11 = TMP( IPIV )
+      IF( ABS( U11 ).LE.SMIN ) THEN
+         INFO = 1
+         U11 = SMIN
+      END IF
+      U12 = TMP( LOCU12( IPIV ) )
+      L21 = TMP( LOCL21( IPIV ) ) / U11
+      U22 = TMP( LOCU22( IPIV ) ) - U12*L21
+      XSWAP = XSWPIV( IPIV )
+      BSWAP = BSWPIV( IPIV )
+      IF( ABS( U22 ).LE.SMIN ) THEN
+         INFO = 1
+         U22 = SMIN
+      END IF
+      IF( BSWAP ) THEN
+         TEMP = BTMP( 2 )
+         BTMP( 2 ) = BTMP( 1 ) - L21*TEMP
+         BTMP( 1 ) = TEMP
+      ELSE
+         BTMP( 2 ) = BTMP( 2 ) - L21*BTMP( 1 )
+      END IF
+      SCALE = ONE
+      IF( ( TWO*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( U22 ) .OR.
+     $    ( TWO*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( U11 ) ) THEN
+         SCALE = HALF / MAX( ABS( BTMP( 1 ) ), ABS( BTMP( 2 ) ) )
+         BTMP( 1 ) = BTMP( 1 )*SCALE
+         BTMP( 2 ) = BTMP( 2 )*SCALE
+      END IF
+      X2( 2 ) = BTMP( 2 ) / U22
+      X2( 1 ) = BTMP( 1 ) / U11 - ( U12 / U11 )*X2( 2 )
+      IF( XSWAP ) THEN
+         TEMP = X2( 2 )
+         X2( 2 ) = X2( 1 )
+         X2( 1 ) = TEMP
+      END IF
+      X( 1, 1 ) = X2( 1 )
+      IF( N1.EQ.1 ) THEN
+         X( 1, 2 ) = X2( 2 )
+         XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
+      ELSE
+         X( 2, 1 ) = X2( 2 )
+         XNORM = MAX( ABS( X( 1, 1 ) ), ABS( X( 2, 1 ) ) )
+      END IF
+      RETURN
+*
+*     2 by 2:
+*     op[TL11 TL12]*[X11 X12] +ISGN* [X11 X12]*op[TR11 TR12] = [B11 B12]
+*       [TL21 TL22] [X21 X22]        [X21 X22]   [TR21 TR22]   [B21 B22]
+*
+*     Solve equivalent 4 by 4 system using complete pivoting.
+*     Set pivots less than SMIN to SMIN.
+*
+   50 CONTINUE
+      SMIN = MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),
+     $       ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )
+      SMIN = MAX( SMIN, ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),
+     $       ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )
+      SMIN = MAX( EPS*SMIN, SMLNUM )
+      BTMP( 1 ) = ZERO
+      CALL SCOPY( 16, BTMP, 0, T16, 1 )
+      T16( 1, 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
+      T16( 2, 2 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )
+      T16( 3, 3 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )
+      T16( 4, 4 ) = TL( 2, 2 ) + SGN*TR( 2, 2 )
+      IF( LTRANL ) THEN
+         T16( 1, 2 ) = TL( 2, 1 )
+         T16( 2, 1 ) = TL( 1, 2 )
+         T16( 3, 4 ) = TL( 2, 1 )
+         T16( 4, 3 ) = TL( 1, 2 )
+      ELSE
+         T16( 1, 2 ) = TL( 1, 2 )
+         T16( 2, 1 ) = TL( 2, 1 )
+         T16( 3, 4 ) = TL( 1, 2 )
+         T16( 4, 3 ) = TL( 2, 1 )
+      END IF
+      IF( LTRANR ) THEN
+         T16( 1, 3 ) = SGN*TR( 1, 2 )
+         T16( 2, 4 ) = SGN*TR( 1, 2 )
+         T16( 3, 1 ) = SGN*TR( 2, 1 )
+         T16( 4, 2 ) = SGN*TR( 2, 1 )
+      ELSE
+         T16( 1, 3 ) = SGN*TR( 2, 1 )
+         T16( 2, 4 ) = SGN*TR( 2, 1 )
+         T16( 3, 1 ) = SGN*TR( 1, 2 )
+         T16( 4, 2 ) = SGN*TR( 1, 2 )
+      END IF
+      BTMP( 1 ) = B( 1, 1 )
+      BTMP( 2 ) = B( 2, 1 )
+      BTMP( 3 ) = B( 1, 2 )
+      BTMP( 4 ) = B( 2, 2 )
+*
+*     Perform elimination
+*
+      DO 100 I = 1, 3
+         XMAX = ZERO
+         DO 70 IP = I, 4
+            DO 60 JP = I, 4
+               IF( ABS( T16( IP, JP ) ).GE.XMAX ) THEN
+                  XMAX = ABS( T16( IP, JP ) )
+                  IPSV = IP
+                  JPSV = JP
+               END IF
+   60       CONTINUE
+   70    CONTINUE
+         IF( IPSV.NE.I ) THEN
+            CALL SSWAP( 4, T16( IPSV, 1 ), 4, T16( I, 1 ), 4 )
+            TEMP = BTMP( I )
+            BTMP( I ) = BTMP( IPSV )
+            BTMP( IPSV ) = TEMP
+         END IF
+         IF( JPSV.NE.I )
+     $      CALL SSWAP( 4, T16( 1, JPSV ), 1, T16( 1, I ), 1 )
+         JPIV( I ) = JPSV
+         IF( ABS( T16( I, I ) ).LT.SMIN ) THEN
+            INFO = 1
+            T16( I, I ) = SMIN
+         END IF
+         DO 90 J = I + 1, 4
+            T16( J, I ) = T16( J, I ) / T16( I, I )
+            BTMP( J ) = BTMP( J ) - T16( J, I )*BTMP( I )
+            DO 80 K = I + 1, 4
+               T16( J, K ) = T16( J, K ) - T16( J, I )*T16( I, K )
+   80       CONTINUE
+   90    CONTINUE
+  100 CONTINUE
+      IF( ABS( T16( 4, 4 ) ).LT.SMIN )
+     $   T16( 4, 4 ) = SMIN
+      SCALE = ONE
+      IF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.
+     $    ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.
+     $    ( EIGHT*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T16( 3, 3 ) ) .OR.
+     $    ( EIGHT*SMLNUM )*ABS( BTMP( 4 ) ).GT.ABS( T16( 4, 4 ) ) ) THEN
+         SCALE = ( ONE / EIGHT ) / MAX( ABS( BTMP( 1 ) ),
+     $           ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ), ABS( BTMP( 4 ) ) )
+         BTMP( 1 ) = BTMP( 1 )*SCALE
+         BTMP( 2 ) = BTMP( 2 )*SCALE
+         BTMP( 3 ) = BTMP( 3 )*SCALE
+         BTMP( 4 ) = BTMP( 4 )*SCALE
+      END IF
+      DO 120 I = 1, 4
+         K = 5 - I
+         TEMP = ONE / T16( K, K )
+         TMP( K ) = BTMP( K )*TEMP
+         DO 110 J = K + 1, 4
+            TMP( K ) = TMP( K ) - ( TEMP*T16( K, J ) )*TMP( J )
+  110    CONTINUE
+  120 CONTINUE
+      DO 130 I = 1, 3
+         IF( JPIV( 4-I ).NE.4-I ) THEN
+            TEMP = TMP( 4-I )
+            TMP( 4-I ) = TMP( JPIV( 4-I ) )
+            TMP( JPIV( 4-I ) ) = TEMP
+         END IF
+  130 CONTINUE
+      X( 1, 1 ) = TMP( 1 )
+      X( 2, 1 ) = TMP( 2 )
+      X( 1, 2 ) = TMP( 3 )
+      X( 2, 2 ) = TMP( 4 )
+      XNORM = MAX( ABS( TMP( 1 ) )+ABS( TMP( 3 ) ),
+     $        ABS( TMP( 2 ) )+ABS( TMP( 4 ) ) )
+      RETURN
+*
+*     End of SLASY2
+*
+      END
diff --git a/libcruft/lapack/slatbs.f b/libcruft/lapack/slatbs.f
new file mode 100644
index 0000000..04c425b
--- /dev/null
+++ b/libcruft/lapack/slatbs.f
@@ -0,0 +1,723 @@
+      SUBROUTINE SLATBS( UPLO, TRANS, DIAG, NORMIN, N, KD, AB, LDAB, X,
+     $                   SCALE, CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, KD, LDAB, N
+      REAL               SCALE
+*     ..
+*     .. Array Arguments ..
+      REAL               AB( LDAB, * ), CNORM( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLATBS solves one of the triangular systems
+*
+*     A *x = s*b  or  A'*x = s*b
+*
+*  with scaling to prevent overflow, where A is an upper or lower
+*  triangular band matrix.  Here A' denotes the transpose of A, x and b
+*  are n-element vectors, and s is a scaling factor, usually less than
+*  or equal to 1, chosen so that the components of x will be less than
+*  the overflow threshold.  If the unscaled problem will not cause
+*  overflow, the Level 2 BLAS routine STBSV is called.  If the matrix A
+*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a
+*  non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b  (No transpose)
+*          = 'T':  Solve A'* x = s*b  (Transpose)
+*          = 'C':  Solve A'* x = s*b  (Conjugate transpose = Transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of subdiagonals or superdiagonals in the
+*          triangular matrix A.  KD >= 0.
+*
+*  AB      (input) REAL array, dimension (LDAB,N)
+*          The upper or lower triangular band matrix A, stored in the
+*          first KD+1 rows of the array. The j-th column of A is stored
+*          in the j-th column of the array AB as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  X       (input/output) REAL array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) REAL
+*          The scaling factor s for the triangular system
+*             A * x = s*b  or  A'* x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) REAL array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, STBSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine STBSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A'*x = b.  The basic
+*  algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call STBSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST, JLEN, MAIND
+      REAL               BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,
+     $                   TMAX, TSCAL, USCAL, XBND, XJ, XMAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SASUM, SDOT, SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SASUM, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SSCAL, STBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLATBS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = SLAMCH( 'Safe minimum' ) / SLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               JLEN = MIN( KD, J-1 )
+               CNORM( J ) = SASUM( JLEN, AB( KD+1-JLEN, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N
+               JLEN = MIN( KD, N-J )
+               IF( JLEN.GT.0 ) THEN
+                  CNORM( J ) = SASUM( JLEN, AB( 2, J ), 1 )
+               ELSE
+                  CNORM( J ) = ZERO
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM.
+*
+      IMAX = ISAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = ONE / ( SMLNUM*TMAX )
+         CALL SSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine STBSV can be used.
+*
+      J = ISAMAX( N, X, 1 )
+      XMAX = ABS( X( J ) )
+      XBND = XMAX
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 50
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 30 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              M(j) = G(j-1) / abs(A(j,j))
+*
+               TJJ = ABS( AB( MAIND, J ) )
+               XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   30       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   40       CONTINUE
+         END IF
+   50    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A' * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 80
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 60 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+*              M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+               TJJ = ABS( AB( MAIND, J ) )
+               IF( XJ.GT.TJJ )
+     $            XBND = XBND*( TJJ / XJ )
+   60       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   70       CONTINUE
+         END IF
+   80    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL STBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = BIGNUM / XMAX
+            CALL SSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 100 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = ABS( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = AB( MAIND, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 95
+               END IF
+                  TJJ = ABS( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                           REC = ONE / XJ
+                           CALL SSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                     XJ = ABS( X( J ) )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                           REC = REC / CNORM( J )
+                        END IF
+                        CALL SSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                     XJ = ABS( X( J ) )
+                  ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                     DO 90 I = 1, N
+                        X( I ) = ZERO
+   90                CONTINUE
+                     X( J ) = ONE
+                     XJ = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+   95          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL SSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL SSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(max(1,j-kd):j-1) := x(max(1,j-kd):j-1) -
+*                                             x(j)* A(max(1,j-kd):j-1,j)
+*
+                     JLEN = MIN( KD, J-1 )
+                     CALL SAXPY( JLEN, -X( J )*TSCAL,
+     $                           AB( KD+1-JLEN, J ), 1, X( J-JLEN ), 1 )
+                     I = ISAMAX( J-1, X, 1 )
+                     XMAX = ABS( X( I ) )
+                  END IF
+               ELSE IF( J.LT.N ) THEN
+*
+*                 Compute the update
+*                    x(j+1:min(j+kd,n)) := x(j+1:min(j+kd,n)) -
+*                                          x(j) * A(j+1:min(j+kd,n),j)
+*
+                  JLEN = MIN( KD, N-J )
+                  IF( JLEN.GT.0 )
+     $               CALL SAXPY( JLEN, -X( J )*TSCAL, AB( 2, J ), 1,
+     $                           X( J+1 ), 1 )
+                  I = J + ISAMAX( N-J, X( J+1 ), 1 )
+                  XMAX = ABS( X( I ) )
+               END IF
+  100       CONTINUE
+*
+         ELSE
+*
+*           Solve A' * x = b
+*
+            DO 140 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = ABS( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                     TJJ = ABS( TJJS )
+                     IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                        REC = MIN( ONE, REC*TJJ )
+                        USCAL = USCAL / TJJS
+                     END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL SSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               SUMJ = ZERO
+               IF( USCAL.EQ.ONE ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call SDOT to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     SUMJ = SDOT( JLEN, AB( KD+1-JLEN, J ), 1,
+     $                      X( J-JLEN ), 1 )
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     IF( JLEN.GT.0 )
+     $                  SUMJ = SDOT( JLEN, AB( 2, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     DO 110 I = 1, JLEN
+                        SUMJ = SUMJ + ( AB( KD+I-JLEN, J )*USCAL )*
+     $                         X( J-JLEN-1+I )
+  110                CONTINUE
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     DO 120 I = 1, JLEN
+                        SUMJ = SUMJ + ( AB( I+1, J )*USCAL )*X( J+I )
+  120                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.TSCAL ) THEN
+*
+*                 Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - SUMJ
+                  XJ = ABS( X( J ) )
+                  IF( NOUNIT ) THEN
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 135
+                  END IF
+                     TJJ = ABS( TJJS )
+                     IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                        IF( TJJ.LT.ONE ) THEN
+                           IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                              REC = ONE / XJ
+                              CALL SSCAL( N, REC, X, 1 )
+                              SCALE = SCALE*REC
+                              XMAX = XMAX*REC
+                           END IF
+                        END IF
+                        X( J ) = X( J ) / TJJS
+                     ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                           REC = ( TJJ*BIGNUM ) / XJ
+                           CALL SSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                        X( J ) = X( J ) / TJJS
+                     ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0, and compute a solution to A'*x = 0.
+*
+                        DO 130 I = 1, N
+                           X( I ) = ZERO
+  130                   CONTINUE
+                        X( J ) = ONE
+                        SCALE = ZERO
+                        XMAX = ZERO
+                     END IF
+  135             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - sumj if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = X( J ) / TJJS - SUMJ
+               END IF
+               XMAX = MAX( XMAX, ABS( X( J ) ) )
+  140       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of SLATBS
+*
+      END
diff --git a/libcruft/lapack/slatrd.f b/libcruft/lapack/slatrd.f
new file mode 100644
index 0000000..befc85f
--- /dev/null
+++ b/libcruft/lapack/slatrd.f
@@ -0,0 +1,258 @@
+      SUBROUTINE SLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDW, N, NB
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), E( * ), TAU( * ), W( LDW, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLATRD reduces NB rows and columns of a real symmetric matrix A to
+*  symmetric tridiagonal form by an orthogonal similarity
+*  transformation Q' * A * Q, and returns the matrices V and W which are
+*  needed to apply the transformation to the unreduced part of A.
+*
+*  If UPLO = 'U', SLATRD reduces the last NB rows and columns of a
+*  matrix, of which the upper triangle is supplied;
+*  if UPLO = 'L', SLATRD reduces the first NB rows and columns of a
+*  matrix, of which the lower triangle is supplied.
+*
+*  This is an auxiliary routine called by SSYTRD.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored:
+*          = 'U': Upper triangular
+*          = 'L': Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of rows and columns to be reduced.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit:
+*          if UPLO = 'U', the last NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements above the diagonal
+*            with the array TAU, represent the orthogonal matrix Q as a
+*            product of elementary reflectors;
+*          if UPLO = 'L', the first NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements below the diagonal
+*            with the array TAU, represent the  orthogonal matrix Q as a
+*            product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= (1,N).
+*
+*  E       (output) REAL array, dimension (N-1)
+*          If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal
+*          elements of the last NB columns of the reduced matrix;
+*          if UPLO = 'L', E(1:nb) contains the subdiagonal elements of
+*          the first NB columns of the reduced matrix.
+*
+*  TAU     (output) REAL array, dimension (N-1)
+*          The scalar factors of the elementary reflectors, stored in
+*          TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'.
+*          See Further Details.
+*
+*  W       (output) REAL array, dimension (LDW,NB)
+*          The n-by-nb matrix W required to update the unreduced part
+*          of A.
+*
+*  LDW     (input) INTEGER
+*          The leading dimension of the array W. LDW >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n) H(n-1) . . . H(n-nb+1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i),
+*  and tau in TAU(i-1).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),
+*  and tau in TAU(i).
+*
+*  The elements of the vectors v together form the n-by-nb matrix V
+*  which is needed, with W, to apply the transformation to the unreduced
+*  part of the matrix, using a symmetric rank-2k update of the form:
+*  A := A - V*W' - W*V'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5 and nb = 2:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  a   a   a   v4  v5 )              (  d                  )
+*    (      a   a   v4  v5 )              (  1   d              )
+*    (          a   1   v5 )              (  v1  1   a          )
+*    (              d   1  )              (  v1  v2  a   a      )
+*    (                  d  )              (  v1  v2  a   a   a  )
+*
+*  where d denotes a diagonal element of the reduced matrix, a denotes
+*  an element of the original matrix that is unchanged, and vi denotes
+*  an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, HALF
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, HALF = 0.5E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IW
+      REAL               ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SGEMV, SLARFG, SSCAL, SSYMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SDOT
+      EXTERNAL           LSAME, SDOT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Reduce last NB columns of upper triangle
+*
+         DO 10 I = N, N - NB + 1, -1
+            IW = I - N + NB
+            IF( I.LT.N ) THEN
+*
+*              Update A(1:i,i)
+*
+               CALL SGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', I, N-I, -ONE, W( 1, IW+1 ),
+     $                     LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 )
+            END IF
+            IF( I.GT.1 ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(1:i-2,i)
+*
+               CALL SLARFG( I-1, A( I-1, I ), A( 1, I ), 1, TAU( I-1 ) )
+               E( I-1 ) = A( I-1, I )
+               A( I-1, I ) = ONE
+*
+*              Compute W(1:i-1,i)
+*
+               CALL SSYMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1,
+     $                     ZERO, W( 1, IW ), 1 )
+               IF( I.LT.N ) THEN
+                  CALL SGEMV( 'Transpose', I-1, N-I, ONE, W( 1, IW+1 ),
+     $                        LDW, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )
+                  CALL SGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+                  CALL SGEMV( 'Transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                        LDA, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )
+                  CALL SGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+               END IF
+               CALL SSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 )
+               ALPHA = -HALF*TAU( I-1 )*SDOT( I-1, W( 1, IW ), 1,
+     $                 A( 1, I ), 1 )
+               CALL SAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 )
+            END IF
+*
+   10    CONTINUE
+      ELSE
+*
+*        Reduce first NB columns of lower triangle
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i:n,i)
+*
+            CALL SGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 )
+            CALL SGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ),
+     $                  LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 )
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:n,i)
+*
+               CALL SLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,
+     $                      TAU( I ) )
+               E( I ) = A( I+1, I )
+               A( I+1, I ) = ONE
+*
+*              Compute W(i+1:n,i)
+*
+               CALL SSYMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, W( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', N-I, I-1, ONE, W( I+1, 1 ), LDW,
+     $                     A( I+1, I ), 1, ZERO, W( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL SGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, W( 1, I ), 1 )
+               CALL SGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, 1 ),
+     $                     LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL SSCAL( N-I, TAU( I ), W( I+1, I ), 1 )
+               ALPHA = -HALF*TAU( I )*SDOT( N-I, W( I+1, I ), 1,
+     $                 A( I+1, I ), 1 )
+               CALL SAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), 1 )
+            END IF
+*
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SLATRD
+*
+      END
diff --git a/libcruft/lapack/slatrs.f b/libcruft/lapack/slatrs.f
new file mode 100644
index 0000000..c065ae2
--- /dev/null
+++ b/libcruft/lapack/slatrs.f
@@ -0,0 +1,701 @@
+      SUBROUTINE SLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
+     $                   CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, LDA, N
+      REAL               SCALE
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), CNORM( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLATRS solves one of the triangular systems
+*
+*     A *x = s*b  or  A'*x = s*b
+*
+*  with scaling to prevent overflow.  Here A is an upper or lower
+*  triangular matrix, A' denotes the transpose of A, x and b are
+*  n-element vectors, and s is a scaling factor, usually less than
+*  or equal to 1, chosen so that the components of x will be less than
+*  the overflow threshold.  If the unscaled problem will not cause
+*  overflow, the Level 2 BLAS routine STRSV is called.  If the matrix A
+*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a
+*  non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b  (No transpose)
+*          = 'T':  Solve A'* x = s*b  (Transpose)
+*          = 'C':  Solve A'* x = s*b  (Conjugate transpose = Transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max (1,N).
+*
+*  X       (input/output) REAL array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) REAL
+*          The scaling factor s for the triangular system
+*             A * x = s*b  or  A'* x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) REAL array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, STRSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine STRSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A'*x = b.  The basic
+*  algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call STRSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST
+      REAL               BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,
+     $                   TMAX, TSCAL, USCAL, XBND, XJ, XMAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SASUM, SDOT, SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SASUM, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SSCAL, STRSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLATRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = SLAMCH( 'Safe minimum' ) / SLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               CNORM( J ) = SASUM( J-1, A( 1, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N - 1
+               CNORM( J ) = SASUM( N-J, A( J+1, J ), 1 )
+   20       CONTINUE
+            CNORM( N ) = ZERO
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM.
+*
+      IMAX = ISAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = ONE / ( SMLNUM*TMAX )
+         CALL SSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine STRSV can be used.
+*
+      J = ISAMAX( N, X, 1 )
+      XMAX = ABS( X( J ) )
+      XBND = XMAX
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 50
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 30 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              M(j) = G(j-1) / abs(A(j,j))
+*
+               TJJ = ABS( A( J, J ) )
+               XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   30       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 50
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   40       CONTINUE
+         END IF
+   50    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A' * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 80
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = ONE / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 60 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+*              M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+               TJJ = ABS( A( J, J ) )
+               IF( XJ.GT.TJJ )
+     $            XBND = XBND*( TJJ / XJ )
+   60       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 80
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   70       CONTINUE
+         END IF
+   80    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL STRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = BIGNUM / XMAX
+            CALL SSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 100 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = ABS( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = A( J, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 95
+               END IF
+                  TJJ = ABS( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                           REC = ONE / XJ
+                           CALL SSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                     XJ = ABS( X( J ) )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                           REC = REC / CNORM( J )
+                        END IF
+                        CALL SSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = X( J ) / TJJS
+                     XJ = ABS( X( J ) )
+                  ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                     DO 90 I = 1, N
+                        X( I ) = ZERO
+   90                CONTINUE
+                     X( J ) = ONE
+                     XJ = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+   95          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL SSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL SSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
+*
+                     CALL SAXPY( J-1, -X( J )*TSCAL, A( 1, J ), 1, X,
+     $                           1 )
+                     I = ISAMAX( J-1, X, 1 )
+                     XMAX = ABS( X( I ) )
+                  END IF
+               ELSE
+                  IF( J.LT.N ) THEN
+*
+*                    Compute the update
+*                       x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
+*
+                     CALL SAXPY( N-J, -X( J )*TSCAL, A( J+1, J ), 1,
+     $                           X( J+1 ), 1 )
+                     I = J + ISAMAX( N-J, X( J+1 ), 1 )
+                     XMAX = ABS( X( I ) )
+                  END IF
+               END IF
+  100       CONTINUE
+*
+         ELSE
+*
+*           Solve A' * x = b
+*
+            DO 140 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = ABS( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                     TJJ = ABS( TJJS )
+                     IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                        REC = MIN( ONE, REC*TJJ )
+                        USCAL = USCAL / TJJS
+                     END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL SSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               SUMJ = ZERO
+               IF( USCAL.EQ.ONE ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call SDOT to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     SUMJ = SDOT( J-1, A( 1, J ), 1, X, 1 )
+                  ELSE IF( J.LT.N ) THEN
+                     SUMJ = SDOT( N-J, A( J+1, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     DO 110 I = 1, J - 1
+                        SUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )
+  110                CONTINUE
+                  ELSE IF( J.LT.N ) THEN
+                     DO 120 I = J + 1, N
+                        SUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )
+  120                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.TSCAL ) THEN
+*
+*                 Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - SUMJ
+                  XJ = ABS( X( J ) )
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 135
+                  END IF
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJ = ABS( TJJS )
+                     IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                        IF( TJJ.LT.ONE ) THEN
+                           IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                              REC = ONE / XJ
+                              CALL SSCAL( N, REC, X, 1 )
+                              SCALE = SCALE*REC
+                              XMAX = XMAX*REC
+                           END IF
+                        END IF
+                        X( J ) = X( J ) / TJJS
+                     ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                           REC = ( TJJ*BIGNUM ) / XJ
+                           CALL SSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                        X( J ) = X( J ) / TJJS
+                     ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0, and compute a solution to A'*x = 0.
+*
+                        DO 130 I = 1, N
+                           X( I ) = ZERO
+  130                   CONTINUE
+                        X( J ) = ONE
+                        SCALE = ZERO
+                        XMAX = ZERO
+                     END IF
+  135             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j)  - sumj if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = X( J ) / TJJS - SUMJ
+               END IF
+               XMAX = MAX( XMAX, ABS( X( J ) ) )
+  140       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of SLATRS
+*
+      END
diff --git a/libcruft/lapack/slatrz.f b/libcruft/lapack/slatrz.f
new file mode 100644
index 0000000..779ba53
--- /dev/null
+++ b/libcruft/lapack/slatrz.f
@@ -0,0 +1,127 @@
+      SUBROUTINE SLATRZ( M, N, L, A, LDA, TAU, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            L, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLATRZ factors the M-by-(M+L) real upper trapezoidal matrix
+*  [ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R  0 ) * Z, by means
+*  of orthogonal transformations.  Z is an (M+L)-by-(M+L) orthogonal
+*  matrix and, R and A1 are M-by-M upper triangular matrices.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing the
+*          meaningful part of the Householder vectors. N-M >= L >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements N-L+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          orthogonal matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) REAL array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) REAL array, dimension (M)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an l element vector. tau and z( k )
+*  are chosen to annihilate the elements of the kth row of A2.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A2, such that the elements of z( k ) are
+*  in  a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A1.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARFG, SLARZ
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      DO 20 I = M, 1, -1
+*
+*        Generate elementary reflector H(i) to annihilate
+*        [ A(i,i) A(i,n-l+1:n) ]
+*
+         CALL SLARFG( L+1, A( I, I ), A( I, N-L+1 ), LDA, TAU( I ) )
+*
+*        Apply H(i) to A(1:i-1,i:n) from the right
+*
+         CALL SLARZ( 'Right', I-1, N-I+1, L, A( I, N-L+1 ), LDA,
+     $               TAU( I ), A( 1, I ), LDA, WORK )
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of SLATRZ
+*
+      END
diff --git a/libcruft/lapack/slauu2.f b/libcruft/lapack/slauu2.f
new file mode 100644
index 0000000..569c946
--- /dev/null
+++ b/libcruft/lapack/slauu2.f
@@ -0,0 +1,135 @@
+      SUBROUTINE SLAUU2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAUU2 computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the unblocked form of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      REAL               AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SDOT
+      EXTERNAL           LSAME, SDOT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLAUU2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the product U * U'.
+*
+         DO 10 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = SDOT( N-I+1, A( I, I ), LDA, A( I, I ), LDA )
+               CALL SGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, AII, A( 1, I ), 1 )
+            ELSE
+               CALL SSCAL( I, AII, A( 1, I ), 1 )
+            END IF
+   10    CONTINUE
+*
+      ELSE
+*
+*        Compute the product L' * L.
+*
+         DO 20 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = SDOT( N-I+1, A( I, I ), 1, A( I, I ), 1 )
+               CALL SGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,
+     $                     A( I+1, I ), 1, AII, A( I, 1 ), LDA )
+            ELSE
+               CALL SSCAL( I, AII, A( I, 1 ), LDA )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SLAUU2
+*
+      END
diff --git a/libcruft/lapack/slauum.f b/libcruft/lapack/slauum.f
new file mode 100644
index 0000000..d3bf1ef
--- /dev/null
+++ b/libcruft/lapack/slauum.f
@@ -0,0 +1,155 @@
+      SUBROUTINE SLAUUM( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAUUM computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the blocked form of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, IB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SLAUU2, SSYRK, STRMM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SLAUUM', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'SLAUUM', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL SLAUU2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute the product U * U'.
+*
+            DO 10 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL STRMM( 'Right', 'Upper', 'Transpose', 'Non-unit',
+     $                     I-1, IB, ONE, A( I, I ), LDA, A( 1, I ),
+     $                     LDA )
+               CALL SLAUU2( 'Upper', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL SGEMM( 'No transpose', 'Transpose', I-1, IB,
+     $                        N-I-IB+1, ONE, A( 1, I+IB ), LDA,
+     $                        A( I, I+IB ), LDA, ONE, A( 1, I ), LDA )
+                  CALL SSYRK( 'Upper', 'No transpose', IB, N-I-IB+1,
+     $                        ONE, A( I, I+IB ), LDA, ONE, A( I, I ),
+     $                        LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute the product L' * L.
+*
+            DO 20 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL STRMM( 'Left', 'Lower', 'Transpose', 'Non-unit', IB,
+     $                     I-1, ONE, A( I, I ), LDA, A( I, 1 ), LDA )
+               CALL SLAUU2( 'Lower', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL SGEMM( 'Transpose', 'No transpose', IB, I-1,
+     $                        N-I-IB+1, ONE, A( I+IB, I ), LDA,
+     $                        A( I+IB, 1 ), LDA, ONE, A( I, 1 ), LDA )
+                  CALL SSYRK( 'Lower', 'Transpose', IB, N-I-IB+1, ONE,
+     $                        A( I+IB, I ), LDA, ONE, A( I, I ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of SLAUUM
+*
+      END
diff --git a/libcruft/lapack/slazq3.f b/libcruft/lapack/slazq3.f
new file mode 100644
index 0000000..8249a8c
--- /dev/null
+++ b/libcruft/lapack/slazq3.f
@@ -0,0 +1,302 @@
+      SUBROUTINE SLAZQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
+     $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
+     $                   DN2, TAU )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      LOGICAL            IEEE
+      INTEGER            I0, ITER, N0, NDIV, NFAIL, PP, TTYPE
+      REAL               DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, QMAX,
+     $                   SIGMA, TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAZQ3 checks for deflation, computes a shift (TAU) and calls dqds.
+*  In case of failure it changes shifts, and tries again until output
+*  is positive.
+*
+*  Arguments
+*  =========
+*
+*  I0     (input) INTEGER
+*         First index.
+*
+*  N0     (input) INTEGER
+*         Last index.
+*
+*  Z      (input) REAL array, dimension ( 4*N )
+*         Z holds the qd array.
+*
+*  PP     (input) INTEGER
+*         PP=0 for ping, PP=1 for pong.
+*
+*  DMIN   (output) REAL
+*         Minimum value of d.
+*
+*  SIGMA  (output) REAL
+*         Sum of shifts used in current segment.
+*
+*  DESIG  (input/output) REAL
+*         Lower order part of SIGMA
+*
+*  QMAX   (input) REAL
+*         Maximum value of q.
+*
+*  NFAIL  (output) INTEGER
+*         Number of times shift was too big.
+*
+*  ITER   (output) INTEGER
+*         Number of iterations.
+*
+*  NDIV   (output) INTEGER
+*         Number of divisions.
+*
+*  IEEE   (input) LOGICAL
+*         Flag for IEEE or non IEEE arithmetic (passed to SLASQ5).
+*
+*  TTYPE  (input/output) INTEGER
+*         Shift type.  TTYPE is passed as an argument in order to save
+*         its value between calls to SLAZQ3
+*
+*  DMIN1  (input/output) REAL
+*  DMIN2  (input/output) REAL
+*  DN     (input/output) REAL
+*  DN1    (input/output) REAL
+*  DN2    (input/output) REAL
+*  TAU    (input/output) REAL
+*         These are passed as arguments in order to save their values
+*         between calls to SLAZQ3
+*
+*  This is a thread safe version of SLASQ3, which passes TTYPE, DMIN1,
+*  DMIN2, DN, DN1. DN2 and TAU through the argument list in place of
+*  declaring them in a SAVE statment.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               CBIAS
+      PARAMETER          ( CBIAS = 1.50E0 )
+      REAL               ZERO, QURTR, HALF, ONE, TWO, HUNDRD
+      PARAMETER          ( ZERO = 0.0E0, QURTR = 0.250E0, HALF = 0.5E0,
+     $                     ONE = 1.0E0, TWO = 2.0E0, HUNDRD = 100.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IPN4, J4, N0IN, NN
+      REAL               EPS, G, S, SAFMIN, T, TEMP, TOL, TOL2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASQ5, SLASQ6, SLAZQ4
+*     ..
+*     .. External Function ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      N0IN   = N0
+      EPS    = SLAMCH( 'Precision' )
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      TOL    = EPS*HUNDRD
+      TOL2   = TOL**2
+      G      = ZERO
+*
+*     Check for deflation.
+*
+   10 CONTINUE
+*
+      IF( N0.LT.I0 )
+     $   RETURN
+      IF( N0.EQ.I0 )
+     $   GO TO 20
+      NN = 4*N0 + PP
+      IF( N0.EQ.( I0+1 ) )
+     $   GO TO 40
+*
+*     Check whether E(N0-1) is negligible, 1 eigenvalue.
+*
+      IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
+     $    Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
+     $   GO TO 30
+*
+   20 CONTINUE
+*
+      Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
+      N0 = N0 - 1
+      GO TO 10
+*
+*     Check  whether E(N0-2) is negligible, 2 eigenvalues.
+*
+   30 CONTINUE
+*
+      IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
+     $    Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
+     $   GO TO 50
+*
+   40 CONTINUE
+*
+      IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
+         S = Z( NN-3 )
+         Z( NN-3 ) = Z( NN-7 )
+         Z( NN-7 ) = S
+      END IF
+      IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
+         T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
+         S = Z( NN-3 )*( Z( NN-5 ) / T )
+         IF( S.LE.T ) THEN
+            S = Z( NN-3 )*( Z( NN-5 ) /
+     $          ( T*( ONE+SQRT( ONE+S / T ) ) ) )
+         ELSE
+            S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
+         END IF
+         T = Z( NN-7 ) + ( S+Z( NN-5 ) )
+         Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
+         Z( NN-7 ) = T
+      END IF
+      Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
+      Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
+      N0 = N0 - 2
+      GO TO 10
+*
+   50 CONTINUE
+*
+*     Reverse the qd-array, if warranted.
+*
+      IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
+         IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
+            IPN4 = 4*( I0+N0 )
+            DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
+               TEMP = Z( J4-3 )
+               Z( J4-3 ) = Z( IPN4-J4-3 )
+               Z( IPN4-J4-3 ) = TEMP
+               TEMP = Z( J4-2 )
+               Z( J4-2 ) = Z( IPN4-J4-2 )
+               Z( IPN4-J4-2 ) = TEMP
+               TEMP = Z( J4-1 )
+               Z( J4-1 ) = Z( IPN4-J4-5 )
+               Z( IPN4-J4-5 ) = TEMP
+               TEMP = Z( J4 )
+               Z( J4 ) = Z( IPN4-J4-4 )
+               Z( IPN4-J4-4 ) = TEMP
+   60       CONTINUE
+            IF( N0-I0.LE.4 ) THEN
+               Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
+               Z( 4*N0-PP ) = Z( 4*I0-PP )
+            END IF
+            DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
+            Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
+     $                            Z( 4*I0+PP+3 ) )
+            Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
+     $                          Z( 4*I0-PP+4 ) )
+            QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
+            DMIN = -ZERO
+         END IF
+      END IF
+*
+      IF( DMIN.LT.ZERO .OR. SAFMIN*QMAX.LT.MIN( Z( 4*N0+PP-1 ),
+     $    Z( 4*N0+PP-9 ), DMIN2+Z( 4*N0-PP ) ) ) THEN
+*
+*        Choose a shift.
+*
+         CALL SLAZQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
+     $                DN2, TAU, TTYPE, G )
+*
+*        Call dqds until DMIN > 0.
+*
+   80    CONTINUE
+*
+         CALL SLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
+     $                DN1, DN2, IEEE )
+*
+         NDIV = NDIV + ( N0-I0+2 )
+         ITER = ITER + 1
+*
+*        Check status.
+*
+         IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
+*
+*           Success.
+*
+            GO TO 100
+*
+         ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
+     $            Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
+     $            ABS( DN ).LT.TOL*SIGMA ) THEN
+*
+*           Convergence hidden by negative DN.
+*
+            Z( 4*( N0-1 )-PP+2 ) = ZERO
+            DMIN = ZERO
+            GO TO 100
+         ELSE IF( DMIN.LT.ZERO ) THEN
+*
+*           TAU too big. Select new TAU and try again.
+*
+            NFAIL = NFAIL + 1
+            IF( TTYPE.LT.-22 ) THEN
+*
+*              Failed twice. Play it safe.
+*
+               TAU = ZERO
+            ELSE IF( DMIN1.GT.ZERO ) THEN
+*
+*              Late failure. Gives excellent shift.
+*
+               TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
+               TTYPE = TTYPE - 11
+            ELSE
+*
+*              Early failure. Divide by 4.
+*
+               TAU = QURTR*TAU
+               TTYPE = TTYPE - 12
+            END IF
+            GO TO 80
+         ELSE IF( DMIN.NE.DMIN ) THEN
+*
+*           NaN.
+*
+            TAU = ZERO
+            GO TO 80
+         ELSE
+*
+*           Possible underflow. Play it safe.
+*
+            GO TO 90
+         END IF
+      END IF
+*
+*     Risk of underflow.
+*
+   90 CONTINUE
+      CALL SLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
+      NDIV = NDIV + ( N0-I0+2 )
+      ITER = ITER + 1
+      TAU = ZERO
+*
+  100 CONTINUE
+      IF( TAU.LT.SIGMA ) THEN
+         DESIG = DESIG + TAU
+         T = SIGMA + DESIG
+         DESIG = DESIG - ( T-SIGMA )
+      ELSE
+         T = SIGMA + TAU
+         DESIG = SIGMA - ( T-TAU ) + DESIG
+      END IF
+      SIGMA = T
+*
+      RETURN
+*
+*     End of SLAZQ3
+*
+      END
diff --git a/libcruft/lapack/slazq4.f b/libcruft/lapack/slazq4.f
new file mode 100644
index 0000000..54c362c
--- /dev/null
+++ b/libcruft/lapack/slazq4.f
@@ -0,0 +1,330 @@
+      SUBROUTINE SLAZQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
+     $                   DN1, DN2, TAU, TTYPE, G )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            I0, N0, N0IN, PP, TTYPE
+      REAL               DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU
+*     ..
+*     .. Array Arguments ..
+      REAL               Z( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SLAZQ4 computes an approximation TAU to the smallest eigenvalue 
+*  using values of d from the previous transform.
+*
+*  I0    (input) INTEGER
+*        First index.
+*
+*  N0    (input) INTEGER
+*        Last index.
+*
+*  Z     (input) REAL array, dimension ( 4*N )
+*        Z holds the qd array.
+*
+*  PP    (input) INTEGER
+*        PP=0 for ping, PP=1 for pong.
+*
+*  N0IN  (input) INTEGER
+*        The value of N0 at start of EIGTEST.
+*
+*  DMIN  (input) REAL
+*        Minimum value of d.
+*
+*  DMIN1 (input) REAL
+*        Minimum value of d, excluding D( N0 ).
+*
+*  DMIN2 (input) REAL
+*        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
+*
+*  DN    (input) REAL
+*        d(N)
+*
+*  DN1   (input) REAL
+*        d(N-1)
+*
+*  DN2   (input) REAL
+*        d(N-2)
+*
+*  TAU   (output) REAL
+*        This is the shift.
+*
+*  TTYPE (output) INTEGER
+*        Shift type.
+*
+*  G     (input/output) REAL
+*        G is passed as an argument in order to save its value between
+*        calls to SLAZQ4
+*
+*  Further Details
+*  ===============
+*  CNST1 = 9/16
+*
+*  This is a thread safe version of SLASQ4, which passes G through the
+*  argument list in place of declaring G in a SAVE statment.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               CNST1, CNST2, CNST3
+      PARAMETER          ( CNST1 = 0.5630E0, CNST2 = 1.010E0,
+     $                   CNST3 = 1.050E0 )
+      REAL               QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRD
+      PARAMETER          ( QURTR = 0.250E0, THIRD = 0.3330E0,
+     $                   HALF = 0.50E0, ZERO = 0.0E0, ONE = 1.0E0,
+     $                   TWO = 2.0E0, HUNDRD = 100.0E0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I4, NN, NP
+      REAL               A2, B1, B2, GAM, GAP1, GAP2, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     A negative DMIN forces the shift to take that absolute value
+*     TTYPE records the type of shift.
+*
+      IF( DMIN.LE.ZERO ) THEN
+         TAU = -DMIN
+         TTYPE = -1
+         RETURN
+      END IF
+*       
+      NN = 4*N0 + PP
+      IF( N0IN.EQ.N0 ) THEN
+*
+*        No eigenvalues deflated.
+*
+         IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN
+*
+            B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )
+            B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )
+            A2 = Z( NN-7 ) + Z( NN-5 )
+*
+*           Cases 2 and 3.
+*
+            IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THEN
+               GAP2 = DMIN2 - A2 - DMIN2*QURTR
+               IF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THEN
+                  GAP1 = A2 - DN - ( B2 / GAP2 )*B2
+               ELSE
+                  GAP1 = A2 - DN - ( B1+B2 )
+               END IF
+               IF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THEN
+                  S = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )
+                  TTYPE = -2
+               ELSE
+                  S = ZERO
+                  IF( DN.GT.B1 )
+     $               S = DN - B1
+                  IF( A2.GT.( B1+B2 ) )
+     $               S = MIN( S, A2-( B1+B2 ) )
+                  S = MAX( S, THIRD*DMIN )
+                  TTYPE = -3
+               END IF
+            ELSE
+*
+*              Case 4.
+*
+               TTYPE = -4
+               S = QURTR*DMIN
+               IF( DMIN.EQ.DN ) THEN
+                  GAM = DN
+                  A2 = ZERO
+                  IF( Z( NN-5 ) .GT. Z( NN-7 ) )
+     $               RETURN
+                  B2 = Z( NN-5 ) / Z( NN-7 )
+                  NP = NN - 9
+               ELSE
+                  NP = NN - 2*PP
+                  B2 = Z( NP-2 )
+                  GAM = DN1
+                  IF( Z( NP-4 ) .GT. Z( NP-2 ) )
+     $               RETURN
+                  A2 = Z( NP-4 ) / Z( NP-2 )
+                  IF( Z( NN-9 ) .GT. Z( NN-11 ) )
+     $               RETURN
+                  B2 = Z( NN-9 ) / Z( NN-11 )
+                  NP = NN - 13
+               END IF
+*
+*              Approximate contribution to norm squared from I < NN-1.
+*
+               A2 = A2 + B2
+               DO 10 I4 = NP, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 20
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 20
+   10          CONTINUE
+   20          CONTINUE
+               A2 = CNST3*A2
+*
+*              Rayleigh quotient residual bound.
+*
+               IF( A2.LT.CNST1 )
+     $            S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+            END IF
+         ELSE IF( DMIN.EQ.DN2 ) THEN
+*
+*           Case 5.
+*
+            TTYPE = -5
+            S = QURTR*DMIN
+*
+*           Compute contribution to norm squared from I > NN-2.
+*
+            NP = NN - 2*PP
+            B1 = Z( NP-2 )
+            B2 = Z( NP-6 )
+            GAM = DN2
+            IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 )
+     $         RETURN
+            A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )
+*
+*           Approximate contribution to norm squared from I < NN-2.
+*
+            IF( N0-I0.GT.2 ) THEN
+               B2 = Z( NN-13 ) / Z( NN-15 )
+               A2 = A2 + B2
+               DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4
+                  IF( B2.EQ.ZERO )
+     $               GO TO 40
+                  B1 = B2
+                  IF( Z( I4 ) .GT. Z( I4-2 ) )
+     $               RETURN
+                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
+                  A2 = A2 + B2
+                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) 
+     $               GO TO 40
+   30          CONTINUE
+   40          CONTINUE
+               A2 = CNST3*A2
+            END IF
+*
+            IF( A2.LT.CNST1 )
+     $         S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
+         ELSE
+*
+*           Case 6, no information to guide us.
+*
+            IF( TTYPE.EQ.-6 ) THEN
+               G = G + THIRD*( ONE-G )
+            ELSE IF( TTYPE.EQ.-18 ) THEN
+               G = QURTR*THIRD
+            ELSE
+               G = QURTR
+            END IF
+            S = G*DMIN
+            TTYPE = -6
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+1 ) ) THEN
+*
+*        One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.
+*
+         IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN 
+*
+*           Cases 7 and 8.
+*
+            TTYPE = -7
+            S = THIRD*DMIN1
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 60
+            DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               A2 = B1
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*MAX( B1, A2 ).LT.B2 ) 
+     $            GO TO 60
+   50       CONTINUE
+   60       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN1 / ( ONE+B2**2 )
+            GAP2 = HALF*DMIN2 - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+               TTYPE = -8
+            END IF
+         ELSE
+*
+*           Case 9.
+*
+            S = QURTR*DMIN1
+            IF( DMIN1.EQ.DN1 )
+     $         S = HALF*DMIN1
+            TTYPE = -9
+         END IF
+*
+      ELSE IF( N0IN.EQ.( N0+2 ) ) THEN
+*
+*        Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
+*
+*        Cases 10 and 11.
+*
+         IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THEN 
+            TTYPE = -10
+            S = THIRD*DMIN2
+            IF( Z( NN-5 ).GT.Z( NN-7 ) )
+     $         RETURN
+            B1 = Z( NN-5 ) / Z( NN-7 )
+            B2 = B1
+            IF( B2.EQ.ZERO )
+     $         GO TO 80
+            DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
+               IF( Z( I4 ).GT.Z( I4-2 ) )
+     $            RETURN
+               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
+               B2 = B2 + B1
+               IF( HUNDRD*B1.LT.B2 )
+     $            GO TO 80
+   70       CONTINUE
+   80       CONTINUE
+            B2 = SQRT( CNST3*B2 )
+            A2 = DMIN2 / ( ONE+B2**2 )
+            GAP2 = Z( NN-7 ) + Z( NN-9 ) -
+     $             SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2
+            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
+               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
+            ELSE 
+               S = MAX( S, A2*( ONE-CNST2*B2 ) )
+            END IF
+         ELSE
+            S = QURTR*DMIN2
+            TTYPE = -11
+         END IF
+      ELSE IF( N0IN.GT.( N0+2 ) ) THEN
+*
+*        Case 12, more than two eigenvalues deflated. No information.
+*
+         S = ZERO 
+         TTYPE = -12
+      END IF
+*
+      TAU = S
+      RETURN
+*
+*     End of SLAZQ4
+*
+      END
diff --git a/libcruft/lapack/sorg2l.f b/libcruft/lapack/sorg2l.f
new file mode 100644
index 0000000..e277ffb
--- /dev/null
+++ b/libcruft/lapack/sorg2l.f
@@ -0,0 +1,127 @@
+      SUBROUTINE SORG2L( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORG2L generates an m by n real matrix Q with orthonormal columns,
+*  which is defined as the last n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by SGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by SGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the m by n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEQLF.
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, II, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORG2L', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns 1:n-k to columns of the unit matrix
+*
+      DO 20 J = 1, N - K
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( M-N+J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = 1, K
+         II = N - K + I
+*
+*        Apply H(i) to A(1:m-k+i,1:n-k+i) from the left
+*
+         A( M-N+II, II ) = ONE
+         CALL SLARF( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), A,
+     $               LDA, WORK )
+         CALL SSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 )
+         A( M-N+II, II ) = ONE - TAU( I )
+*
+*        Set A(m-k+i+1:m,n-k+i) to zero
+*
+         DO 30 L = M - N + II + 1, M
+            A( L, II ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of SORG2L
+*
+      END
diff --git a/libcruft/lapack/sorg2r.f b/libcruft/lapack/sorg2r.f
new file mode 100644
index 0000000..dcb1246
--- /dev/null
+++ b/libcruft/lapack/sorg2r.f
@@ -0,0 +1,129 @@
+      SUBROUTINE SORG2R( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORG2R generates an m by n real matrix Q with orthonormal columns,
+*  which is defined as the first n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by SGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by SGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the m-by-n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEQRF.
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORG2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns k+1:n to columns of the unit matrix
+*
+      DO 20 J = K + 1, N
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i) to A(i:m,i:n) from the left
+*
+         IF( I.LT.N ) THEN
+            A( I, I ) = ONE
+            CALL SLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                  A( I, I+1 ), LDA, WORK )
+         END IF
+         IF( I.LT.M )
+     $      CALL SSCAL( M-I, -TAU( I ), A( I+1, I ), 1 )
+         A( I, I ) = ONE - TAU( I )
+*
+*        Set A(1:i-1,i) to zero
+*
+         DO 30 L = 1, I - 1
+            A( L, I ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of SORG2R
+*
+      END
diff --git a/libcruft/lapack/sorgbr.f b/libcruft/lapack/sorgbr.f
new file mode 100644
index 0000000..3dd3afc
--- /dev/null
+++ b/libcruft/lapack/sorgbr.f
@@ -0,0 +1,244 @@
+      SUBROUTINE SORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          VECT
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGBR generates one of the real orthogonal matrices Q or P**T
+*  determined by SGEBRD when reducing a real matrix A to bidiagonal
+*  form: A = Q * B * P**T.  Q and P**T are defined as products of
+*  elementary reflectors H(i) or G(i) respectively.
+*
+*  If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q
+*  is of order M:
+*  if m >= k, Q = H(1) H(2) . . . H(k) and SORGBR returns the first n
+*  columns of Q, where m >= n >= k;
+*  if m < k, Q = H(1) H(2) . . . H(m-1) and SORGBR returns Q as an
+*  M-by-M matrix.
+*
+*  If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T
+*  is of order N:
+*  if k < n, P**T = G(k) . . . G(2) G(1) and SORGBR returns the first m
+*  rows of P**T, where n >= m >= k;
+*  if k >= n, P**T = G(n-1) . . . G(2) G(1) and SORGBR returns P**T as
+*  an N-by-N matrix.
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          Specifies whether the matrix Q or the matrix P**T is
+*          required, as defined in the transformation applied by SGEBRD:
+*          = 'Q':  generate Q;
+*          = 'P':  generate P**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q or P**T to be returned.
+*          M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q or P**T to be returned.
+*          N >= 0.
+*          If VECT = 'Q', M >= N >= min(M,K);
+*          if VECT = 'P', N >= M >= min(N,K).
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original M-by-K
+*          matrix reduced by SGEBRD.
+*          If VECT = 'P', the number of rows in the original K-by-N
+*          matrix reduced by SGEBRD.
+*          K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by SGEBRD.
+*          On exit, the M-by-N matrix Q or P**T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension
+*                                (min(M,K)) if VECT = 'Q'
+*                                (min(N,K)) if VECT = 'P'
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i), which determines Q or P**T, as
+*          returned by SGEBRD in its array argument TAUQ or TAUP.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,min(M,N)).
+*          For optimum performance LWORK >= min(M,N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WANTQ
+      INTEGER            I, IINFO, J, LWKOPT, MN, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SORGLQ, SORGQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTQ = LSAME( VECT, 'Q' )
+      MN = MIN( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M,
+     $         K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT.
+     $         MIN( N, K ) ) ) ) THEN
+         INFO = -3
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( WANTQ ) THEN
+            NB = ILAENV( 1, 'SORGQR', ' ', M, N, K, -1 )
+         ELSE
+            NB = ILAENV( 1, 'SORGLQ', ' ', M, N, K, -1 )
+         END IF
+         LWKOPT = MAX( 1, MN )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( WANTQ ) THEN
+*
+*        Form Q, determined by a call to SGEBRD to reduce an m-by-k
+*        matrix
+*
+         IF( M.GE.K ) THEN
+*
+*           If m >= k, assume m >= n >= k
+*
+            CALL SORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If m < k, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           column to the right, and set the first row and column of Q
+*           to those of the unit matrix
+*
+            DO 20 J = M, 2, -1
+               A( 1, J ) = ZERO
+               DO 10 I = J + 1, M
+                  A( I, J ) = A( I, J-1 )
+   10          CONTINUE
+   20       CONTINUE
+            A( 1, 1 ) = ONE
+            DO 30 I = 2, M
+               A( I, 1 ) = ZERO
+   30       CONTINUE
+            IF( M.GT.1 ) THEN
+*
+*              Form Q(2:m,2:m)
+*
+               CALL SORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      ELSE
+*
+*        Form P', determined by a call to SGEBRD to reduce a k-by-n
+*        matrix
+*
+         IF( K.LT.N ) THEN
+*
+*           If k < n, assume k <= m <= n
+*
+            CALL SORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If k >= n, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           row downward, and set the first row and column of P' to
+*           those of the unit matrix
+*
+            A( 1, 1 ) = ONE
+            DO 40 I = 2, N
+               A( I, 1 ) = ZERO
+   40       CONTINUE
+            DO 60 J = 2, N
+               DO 50 I = J - 1, 2, -1
+                  A( I, J ) = A( I-1, J )
+   50          CONTINUE
+               A( 1, J ) = ZERO
+   60       CONTINUE
+            IF( N.GT.1 ) THEN
+*
+*              Form P'(2:n,2:n)
+*
+               CALL SORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SORGBR
+*
+      END
diff --git a/libcruft/lapack/sorghr.f b/libcruft/lapack/sorghr.f
new file mode 100644
index 0000000..9f06120
--- /dev/null
+++ b/libcruft/lapack/sorghr.f
@@ -0,0 +1,164 @@
+      SUBROUTINE SORGHR( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGHR generates a real orthogonal matrix Q which is defined as the
+*  product of IHI-ILO elementary reflectors of order N, as returned by
+*  SGEHRD:
+*
+*  Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI must have the same values as in the previous call
+*          of SGEHRD. Q is equal to the unit matrix except in the
+*          submatrix Q(ilo+1:ihi,ilo+1:ihi).
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by SGEHRD.
+*          On exit, the N-by-N orthogonal matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  TAU     (input) REAL array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEHRD.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= IHI-ILO.
+*          For optimum performance LWORK >= (IHI-ILO)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LWKOPT, NB, NH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SORGQR, XERBLA
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV 
+      EXTERNAL           ILAENV 
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NH = IHI - ILO
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, NH ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'SORGQR', ' ', NH, NH, NH, -1 )
+         LWKOPT = MAX( 1, NH )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGHR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Shift the vectors which define the elementary reflectors one
+*     column to the right, and set the first ilo and the last n-ihi
+*     rows and columns to those of the unit matrix
+*
+      DO 40 J = IHI, ILO + 1, -1
+         DO 10 I = 1, J - 1
+            A( I, J ) = ZERO
+   10    CONTINUE
+         DO 20 I = J + 1, IHI
+            A( I, J ) = A( I, J-1 )
+   20    CONTINUE
+         DO 30 I = IHI + 1, N
+            A( I, J ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      DO 60 J = 1, ILO
+         DO 50 I = 1, N
+            A( I, J ) = ZERO
+   50    CONTINUE
+         A( J, J ) = ONE
+   60 CONTINUE
+      DO 80 J = IHI + 1, N
+         DO 70 I = 1, N
+            A( I, J ) = ZERO
+   70    CONTINUE
+         A( J, J ) = ONE
+   80 CONTINUE
+*
+      IF( NH.GT.0 ) THEN
+*
+*        Generate Q(ilo+1:ihi,ilo+1:ihi)
+*
+         CALL SORGQR( NH, NH, NH, A( ILO+1, ILO+1 ), LDA, TAU( ILO ),
+     $                WORK, LWORK, IINFO )
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SORGHR
+*
+      END
diff --git a/libcruft/lapack/sorgl2.f b/libcruft/lapack/sorgl2.f
new file mode 100644
index 0000000..5727f0c
--- /dev/null
+++ b/libcruft/lapack/sorgl2.f
@@ -0,0 +1,133 @@
+      SUBROUTINE SORGL2( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGL2 generates an m by n real matrix Q with orthonormal rows,
+*  which is defined as the first m rows of a product of k elementary
+*  reflectors of order n
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by SGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by SGELQF in the first k rows of its array argument A.
+*          On exit, the m-by-n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGELQF.
+*
+*  WORK    (workspace) REAL array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGL2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 )
+     $   RETURN
+*
+      IF( K.LT.M ) THEN
+*
+*        Initialise rows k+1:m to rows of the unit matrix
+*
+         DO 20 J = 1, N
+            DO 10 L = K + 1, M
+               A( L, J ) = ZERO
+   10       CONTINUE
+            IF( J.GT.K .AND. J.LE.M )
+     $         A( J, J ) = ONE
+   20    CONTINUE
+      END IF
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i) to A(i:m,i:n) from the right
+*
+         IF( I.LT.N ) THEN
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+               CALL SLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     TAU( I ), A( I+1, I ), LDA, WORK )
+            END IF
+            CALL SSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA )
+         END IF
+         A( I, I ) = ONE - TAU( I )
+*
+*        Set A(i,1:i-1) to zero
+*
+         DO 30 L = 1, I - 1
+            A( I, L ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of SORGL2
+*
+      END
diff --git a/libcruft/lapack/sorglq.f b/libcruft/lapack/sorglq.f
new file mode 100644
index 0000000..0977a3f
--- /dev/null
+++ b/libcruft/lapack/sorglq.f
@@ -0,0 +1,215 @@
+      SUBROUTINE SORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGLQ generates an M-by-N real matrix Q with orthonormal rows,
+*  which is defined as the first M rows of a product of K elementary
+*  reflectors of order N
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by SGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by SGELQF in the first k rows of its array argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGELQF.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARFB, SLARFT, SORGL2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'SORGLQ', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, M )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'SORGLQ', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'SORGLQ', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk rows are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(kk+1:m,1:kk) to zero.
+*
+         DO 20 J = 1, KK
+            DO 10 I = KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.M )
+     $   CALL SORGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL SLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i+ib:m,i:n) from the right
+*
+               CALL SLARFB( 'Right', 'Transpose', 'Forward', 'Rowwise',
+     $                      M-I-IB+1, N-I+1, IB, A( I, I ), LDA, WORK,
+     $                      LDWORK, A( I+IB, I ), LDA, WORK( IB+1 ),
+     $                      LDWORK )
+            END IF
+*
+*           Apply H' to columns i:n of current block
+*
+            CALL SORGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set columns 1:i-1 of current block to zero
+*
+            DO 40 J = 1, I - 1
+               DO 30 L = I, I + IB - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SORGLQ
+*
+      END
diff --git a/libcruft/lapack/sorgql.f b/libcruft/lapack/sorgql.f
new file mode 100644
index 0000000..ea33ba7
--- /dev/null
+++ b/libcruft/lapack/sorgql.f
@@ -0,0 +1,222 @@
+      SUBROUTINE SORGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGQL generates an M-by-N real matrix Q with orthonormal columns,
+*  which is defined as the last N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by SGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by SGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEQLF.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT,
+     $                   NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARFB, SLARFT, SORG2L, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+            NB = ILAENV( 1, 'SORGQL', ' ', M, N, K, -1 )
+            LWKOPT = N*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGQL', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'SORGQL', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'SORGQL', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the first block.
+*        The last kk columns are handled by the block method.
+*
+         KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )
+*
+*        Set A(m-kk+1:m,1:n-kk) to zero.
+*
+         DO 20 J = 1, N - KK
+            DO 10 I = M - KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the first or only block.
+*
+      CALL SORG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = K - KK + 1, K, NB
+            IB = MIN( NB, K-I+1 )
+            IF( N-K+I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL SLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,
+     $                      A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left
+*
+               CALL SLARFB( 'Left', 'No transpose', 'Backward',
+     $                      'Columnwise', M-K+I+IB-1, N-K+I-1, IB,
+     $                      A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows 1:m-k+i+ib-1 of current block
+*
+            CALL SORG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA,
+     $                   TAU( I ), WORK, IINFO )
+*
+*           Set rows m-k+i+ib:m of current block to zero
+*
+            DO 40 J = N - K + I, N - K + I + IB - 1
+               DO 30 L = M - K + I + IB, M
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SORGQL
+*
+      END
diff --git a/libcruft/lapack/sorgqr.f b/libcruft/lapack/sorgqr.f
new file mode 100644
index 0000000..1cc1b53
--- /dev/null
+++ b/libcruft/lapack/sorgqr.f
@@ -0,0 +1,216 @@
+      SUBROUTINE SORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGQR generates an M-by-N real matrix Q with orthonormal columns,
+*  which is defined as the first N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by SGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by SGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEQRF.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARFB, SLARFT, SORG2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'SORGQR', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, N )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'SORGQR', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'SORGQR', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk columns are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(1:kk,kk+1:n) to zero.
+*
+         DO 20 J = KK + 1, N
+            DO 10 I = 1, KK
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.N )
+     $   CALL SORG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL SLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i:m,i+ib:n) from the left
+*
+               CALL SLARFB( 'Left', 'No transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows i:m of current block
+*
+            CALL SORG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set rows 1:i-1 of current block to zero
+*
+            DO 40 J = I, I + IB - 1
+               DO 30 L = 1, I - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of SORGQR
+*
+      END
diff --git a/libcruft/lapack/sorgtr.f b/libcruft/lapack/sorgtr.f
new file mode 100644
index 0000000..52a43be
--- /dev/null
+++ b/libcruft/lapack/sorgtr.f
@@ -0,0 +1,183 @@
+      SUBROUTINE SORGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORGTR generates a real orthogonal matrix Q which is defined as the
+*  product of n-1 elementary reflectors of order N, as returned by
+*  SSYTRD:
+*
+*  if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),
+*
+*  if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U': Upper triangle of A contains elementary reflectors
+*                 from SSYTRD;
+*          = 'L': Lower triangle of A contains elementary reflectors
+*                 from SSYTRD.
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by SSYTRD.
+*          On exit, the N-by-N orthogonal matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  TAU     (input) REAL array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SSYTRD.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N-1).
+*          For optimum performance LWORK >= (N-1)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, J, LWKOPT, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SORGQL, SORGQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF ( UPPER ) THEN
+           NB = ILAENV( 1, 'SORGQL', ' ', N-1, N-1, N-1, -1 )
+         ELSE
+           NB = ILAENV( 1, 'SORGQR', ' ', N-1, N-1, N-1, -1 )
+         END IF
+         LWKOPT = MAX( 1, N-1 )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*    
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORGTR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Q was determined by a call to SSYTRD with UPLO = 'U'
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the left, and set the last row and column of Q to
+*        those of the unit matrix
+*
+         DO 20 J = 1, N - 1
+            DO 10 I = 1, J - 1
+               A( I, J ) = A( I, J+1 )
+   10       CONTINUE
+            A( N, J ) = ZERO
+   20    CONTINUE
+         DO 30 I = 1, N - 1
+            A( I, N ) = ZERO
+   30    CONTINUE
+         A( N, N ) = ONE
+*
+*        Generate Q(1:n-1,1:n-1)
+*
+         CALL SORGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+      ELSE
+*
+*        Q was determined by a call to SSYTRD with UPLO = 'L'.
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the right, and set the first row and column of Q to
+*        those of the unit matrix
+*
+         DO 50 J = N, 2, -1
+            A( 1, J ) = ZERO
+            DO 40 I = J + 1, N
+               A( I, J ) = A( I, J-1 )
+   40       CONTINUE
+   50    CONTINUE
+         A( 1, 1 ) = ONE
+         DO 60 I = 2, N
+            A( I, 1 ) = ZERO
+   60    CONTINUE
+         IF( N.GT.1 ) THEN
+*
+*           Generate Q(2:n,2:n)
+*
+            CALL SORGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                   LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SORGTR
+*
+      END
diff --git a/libcruft/lapack/sorm2r.f b/libcruft/lapack/sorm2r.f
new file mode 100644
index 0000000..be0947c
--- /dev/null
+++ b/libcruft/lapack/sorm2r.f
@@ -0,0 +1,197 @@
+      SUBROUTINE SORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORM2R overwrites the general real m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'T',
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by SGEQRF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'T': apply Q' (Transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          SGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEQRF.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      REAL               AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORM2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. ( .NOT.LEFT .AND. NOTRAN ) )
+     $     THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i)
+*
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL SLARF( SIDE, MI, NI, A( I, I ), 1, TAU( I ), C( IC, JC ),
+     $               LDC, WORK )
+         A( I, I ) = AII
+   10 CONTINUE
+      RETURN
+*
+*     End of SORM2R
+*
+      END
diff --git a/libcruft/lapack/sormbr.f b/libcruft/lapack/sormbr.f
new file mode 100644
index 0000000..2a0052a
--- /dev/null
+++ b/libcruft/lapack/sormbr.f
@@ -0,0 +1,282 @@
+      SUBROUTINE SORMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,
+     $                   LDC, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS, VECT
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  If VECT = 'Q', SORMBR overwrites the general real M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  If VECT = 'P', SORMBR overwrites the general real M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      P * C          C * P
+*  TRANS = 'T':      P**T * C       C * P**T
+*
+*  Here Q and P**T are the orthogonal matrices determined by SGEBRD when
+*  reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and
+*  P**T are defined as products of elementary reflectors H(i) and G(i)
+*  respectively.
+*
+*  Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the
+*  order of the orthogonal matrix Q or P**T that is applied.
+*
+*  If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:
+*  if nq >= k, Q = H(1) H(2) . . . H(k);
+*  if nq < k, Q = H(1) H(2) . . . H(nq-1).
+*
+*  If VECT = 'P', A is assumed to have been a K-by-NQ matrix:
+*  if k < nq, P = G(1) G(2) . . . G(k);
+*  if k >= nq, P = G(1) G(2) . . . G(nq-1).
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          = 'Q': apply Q or Q**T;
+*          = 'P': apply P or P**T.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q, Q**T, P or P**T from the Left;
+*          = 'R': apply Q, Q**T, P or P**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q  or P;
+*          = 'T':  Transpose, apply Q**T or P**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original
+*          matrix reduced by SGEBRD.
+*          If VECT = 'P', the number of rows in the original
+*          matrix reduced by SGEBRD.
+*          K >= 0.
+*
+*  A       (input) REAL array, dimension
+*                                (LDA,min(nq,K)) if VECT = 'Q'
+*                                (LDA,nq)        if VECT = 'P'
+*          The vectors which define the elementary reflectors H(i) and
+*          G(i), whose products determine the matrices Q and P, as
+*          returned by SGEBRD.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If VECT = 'Q', LDA >= max(1,nq);
+*          if VECT = 'P', LDA >= max(1,min(nq,K)).
+*
+*  TAU     (input) REAL array, dimension (min(nq,K))
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i) which determines Q or P, as returned
+*          by SGEBRD in the array argument TAUQ or TAUP.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q
+*          or P*C or P**T*C or C*P or C*P**T.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            APPLYQ, LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SORMLQ, SORMQR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      APPLYQ = LSAME( VECT, 'Q' )
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q or P and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR.
+     $         ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) )
+     $          THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -13
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( APPLYQ ) THEN
+            IF( LEFT ) THEN
+               NB = ILAENV( 1, 'SORMQR', SIDE // TRANS, M-1, N, M-1,
+     $                      -1 )
+            ELSE
+               NB = ILAENV( 1, 'SORMQR', SIDE // TRANS, M, N-1, N-1,
+     $                      -1 )
+            END IF   
+         ELSE
+            IF( LEFT ) THEN
+               NB = ILAENV( 1, 'SORMLQ', SIDE // TRANS, M-1, N, M-1,
+     $                      -1 ) 
+            ELSE
+               NB = ILAENV( 1, 'SORMLQ', SIDE // TRANS, M, N-1, N-1,
+     $                      -1 )
+            END IF
+         END IF
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT 
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORMBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      WORK( 1 ) = 1
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+      IF( APPLYQ ) THEN
+*
+*        Apply Q
+*
+         IF( NQ.GE.K ) THEN
+*
+*           Q was determined by a call to SGEBRD with nq >= k
+*
+            CALL SORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           Q was determined by a call to SGEBRD with nq < k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL SORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,
+     $                   C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      ELSE
+*
+*        Apply P
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'T'
+         ELSE
+            TRANST = 'N'
+         END IF
+         IF( NQ.GT.K ) THEN
+*
+*           P was determined by a call to SGEBRD with nq > k
+*
+            CALL SORMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           P was determined by a call to SGEBRD with nq <= k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL SORMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA,
+     $                   TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SORMBR
+*
+      END
diff --git a/libcruft/lapack/sorml2.f b/libcruft/lapack/sorml2.f
new file mode 100644
index 0000000..3ec71cb
--- /dev/null
+++ b/libcruft/lapack/sorml2.f
@@ -0,0 +1,197 @@
+      SUBROUTINE SORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORML2 overwrites the general real m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'T',
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k) . . . H(2) H(1)
+*
+*  as returned by SGELQF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'T': apply Q' (Transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) REAL array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          SGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGELQF.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      REAL               AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARF, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORML2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) )
+     $     THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i)
+*
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL SLARF( SIDE, MI, NI, A( I, I ), LDA, TAU( I ),
+     $               C( IC, JC ), LDC, WORK )
+         A( I, I ) = AII
+   10 CONTINUE
+      RETURN
+*
+*     End of SORML2
+*
+      END
diff --git a/libcruft/lapack/sormlq.f b/libcruft/lapack/sormlq.f
new file mode 100644
index 0000000..b8457b3
--- /dev/null
+++ b/libcruft/lapack/sormlq.f
@@ -0,0 +1,268 @@
+      SUBROUTINE SORMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORMLQ overwrites the general real M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k) . . . H(2) H(1)
+*
+*  as returned by SGELQF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**T from the Left;
+*          = 'R': apply Q or Q**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'T':  Transpose, apply Q**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) REAL array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          SGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGELQF.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      REAL               T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARFB, SLARFT, SORML2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'SORMLQ', SIDE // TRANS, M, N, K,
+     $             -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF 
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORMLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'SORMLQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL SORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'T'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL SLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL SLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,
+     $                   A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK,
+     $                   LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SORMLQ
+*
+      END
diff --git a/libcruft/lapack/sormqr.f b/libcruft/lapack/sormqr.f
new file mode 100644
index 0000000..a5df0ce
--- /dev/null
+++ b/libcruft/lapack/sormqr.f
@@ -0,0 +1,261 @@
+      SUBROUTINE SORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORMQR overwrites the general real M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by SGEQRF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**T from the Left;
+*          = 'R': apply Q or Q**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'T':  Transpose, apply Q**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          SGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by SGEQRF.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      REAL               T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARFB, SLARFT, SORM2R, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'SORMQR', SIDE // TRANS, M, N, K,
+     $        -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORMQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'SORMQR', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL SORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL SLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL SLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI,
+     $                   IB, A( I, I ), LDA, T, LDT, C( IC, JC ), LDC,
+     $                   WORK, LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SORMQR
+*
+      END
diff --git a/libcruft/lapack/sormr3.f b/libcruft/lapack/sormr3.f
new file mode 100644
index 0000000..fd1cfbf
--- /dev/null
+++ b/libcruft/lapack/sormr3.f
@@ -0,0 +1,206 @@
+      SUBROUTINE SORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORMR3 overwrites the general real m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'T',
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by STZRZF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'T': apply Q' (Transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) REAL array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          STZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by STZRZF.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) REAL array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JA, JC, MI, NI, NQ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARZ, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORMR3', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JA = M - L + 1
+         JC = 1
+      ELSE
+         MI = M
+         JA = N - L + 1
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         CALL SLARZ( SIDE, MI, NI, L, A( I, JA ), LDA, TAU( I ),
+     $               C( IC, JC ), LDC, WORK )
+*
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of SORMR3
+*
+      END
diff --git a/libcruft/lapack/sormrz.f b/libcruft/lapack/sormrz.f
new file mode 100644
index 0000000..4a29bed
--- /dev/null
+++ b/libcruft/lapack/sormrz.f
@@ -0,0 +1,292 @@
+      SUBROUTINE SORMRZ( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SORMRZ overwrites the general real M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'T':      Q**T * C       C * Q**T
+*
+*  where Q is a real orthogonal matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by STZRZF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**T from the Left;
+*          = 'R': apply Q or Q**T from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'T':  Transpose, apply Q**T.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) REAL array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          STZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) REAL array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by STZRZF.
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JA, JC,
+     $                   LDWORK, LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      REAL               T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARZB, SLARZT, SORMR3, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = MAX( 1, N )
+      ELSE
+         NQ = N
+         NW = MAX( 1, M )
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.  NB may be at most NBMAX, where
+*           NBMAX is used to define the local array T.
+*
+            NB = MIN( NBMAX, ILAENV( 1, 'SORMRQ', SIDE // TRANS, M, N,
+     $                               K, -1 ) )
+            LWKOPT = NW*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SORMRZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'SORMRQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL SORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                WORK, IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+            JA = M - L + 1
+         ELSE
+            MI = M
+            IC = 1
+            JA = N - L + 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'T'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i+ib-1) . . . H(i+1) H(i)
+*
+            CALL SLARZT( 'Backward', 'Rowwise', L, IB, A( I, JA ), LDA,
+     $                   TAU( I ), T, LDT )
+*
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL SLARZB( SIDE, TRANST, 'Backward', 'Rowwise', MI, NI,
+     $                   IB, L, A( I, JA ), LDA, T, LDT, C( IC, JC ),
+     $                   LDC, WORK, LDWORK )
+   10    CONTINUE
+*
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of SORMRZ
+*
+      END
diff --git a/libcruft/lapack/spbcon.f b/libcruft/lapack/spbcon.f
new file mode 100644
index 0000000..be1de06
--- /dev/null
+++ b/libcruft/lapack/spbcon.f
@@ -0,0 +1,192 @@
+      SUBROUTINE SPBCON( UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPBCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a real symmetric positive definite band matrix using the
+*  Cholesky factorization A = U**T*U or A = L*L**T computed by SPBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input) REAL array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  ANORM   (input) REAL
+*          The 1-norm (or infinity-norm) of the symmetric band matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) REAL array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      REAL               AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACN2, SLATBS, SRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of the inverse.
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL SLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEL, WORK( 2*N+1 ),
+     $                   INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL SLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEU, WORK( 2*N+1 ),
+     $                   INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL SLATBS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEL, WORK( 2*N+1 ),
+     $                   INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL SLATBS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEU, WORK( 2*N+1 ),
+     $                   INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = ISAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL SRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of SPBCON
+*
+      END
diff --git a/libcruft/lapack/spbtf2.f b/libcruft/lapack/spbtf2.f
new file mode 100644
index 0000000..a5c223c
--- /dev/null
+++ b/libcruft/lapack/spbtf2.f
@@ -0,0 +1,194 @@
+      SUBROUTINE SPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      REAL               AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPBTF2 computes the Cholesky factorization of a real symmetric
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix, U' is the transpose of U, and
+*  L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of super-diagonals of the matrix A if UPLO = 'U',
+*          or the number of sub-diagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) REAL array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the symmetric band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U'*U or A = L*L' of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, KLD, KN
+      REAL               AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL, SSYR, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      KLD = MAX( 1, LDAB-1 )
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = AB( KD+1, J )
+            IF( AJJ.LE.ZERO )
+     $         GO TO 30
+            AJJ = SQRT( AJJ )
+            AB( KD+1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of row J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL SSCAL( KN, ONE / AJJ, AB( KD, J+1 ), KLD )
+               CALL SSYR( 'Upper', KN, -ONE, AB( KD, J+1 ), KLD,
+     $                    AB( KD+1, J+1 ), KLD )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = AB( 1, J )
+            IF( AJJ.LE.ZERO )
+     $         GO TO 30
+            AJJ = SQRT( AJJ )
+            AB( 1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of column J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL SSCAL( KN, ONE / AJJ, AB( 2, J ), 1 )
+               CALL SSYR( 'Lower', KN, -ONE, AB( 2, J ), 1,
+     $                    AB( 1, J+1 ), KLD )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+   30 CONTINUE
+      INFO = J
+      RETURN
+*
+*     End of SPBTF2
+*
+      END
diff --git a/libcruft/lapack/spbtrf.f b/libcruft/lapack/spbtrf.f
new file mode 100644
index 0000000..a50f663
--- /dev/null
+++ b/libcruft/lapack/spbtrf.f
@@ -0,0 +1,364 @@
+      SUBROUTINE SPBTRF( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      REAL               AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPBTRF computes the Cholesky factorization of a real symmetric
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U**T * U,  if UPLO = 'U', or
+*     A = L  * L**T,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) REAL array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the symmetric band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U**T*U or A = L*L**T of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  Contributed by
+*  Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 32, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, IB, II, J, JJ, NB
+*     ..
+*     .. Local Arrays ..
+      REAL               WORK( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SPBTF2, SPOTF2, SSYRK, STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ( .NOT.LSAME( UPLO, 'U' ) ) .AND.
+     $    ( .NOT.LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'SPBTRF', UPLO, N, KD, -1, -1 )
+*
+*     The block size must not exceed the semi-bandwidth KD, and must not
+*     exceed the limit set by the size of the local array WORK.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KD ) THEN
+*
+*        Use unblocked code
+*
+         CALL SPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*           Compute the Cholesky factorization of a symmetric band
+*           matrix, given the upper triangle of the matrix in band
+*           storage.
+*
+*           Zero the upper triangle of the work array.
+*
+            DO 20 J = 1, NB
+               DO 10 I = 1, J - 1
+                  WORK( I, J ) = ZERO
+   10          CONTINUE
+   20       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 70 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL SPOTF2( UPLO, IB, AB( KD+1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11   A12   A13
+*                          A22   A23
+*                                A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A12, A22 and
+*                 A23 are empty if IB = KD. The upper triangle of A13
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A12
+*
+                     CALL STRSM( 'Left', 'Upper', 'Transpose',
+     $                           'Non-unit', IB, I2, ONE, AB( KD+1, I ),
+     $                           LDAB-1, AB( KD+1-IB, I+IB ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL SSYRK( 'Upper', 'Transpose', I2, IB, -ONE,
+     $                           AB( KD+1-IB, I+IB ), LDAB-1, ONE,
+     $                           AB( KD+1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the lower triangle of A13 into the work array.
+*
+                     DO 40 JJ = 1, I3
+                        DO 30 II = JJ, IB
+                           WORK( II, JJ ) = AB( II-JJ+1, JJ+I+KD-1 )
+   30                   CONTINUE
+   40                CONTINUE
+*
+*                    Update A13 (in the work array).
+*
+                     CALL STRSM( 'Left', 'Upper', 'Transpose',
+     $                           'Non-unit', IB, I3, ONE, AB( KD+1, I ),
+     $                           LDAB-1, WORK, LDWORK )
+*
+*                    Update A23
+*
+                     IF( I2.GT.0 )
+     $                  CALL SGEMM( 'Transpose', 'No Transpose', I2, I3,
+     $                              IB, -ONE, AB( KD+1-IB, I+IB ),
+     $                              LDAB-1, WORK, LDWORK, ONE,
+     $                              AB( 1+IB, I+KD ), LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL SSYRK( 'Upper', 'Transpose', I3, IB, -ONE,
+     $                           WORK, LDWORK, ONE, AB( KD+1, I+KD ),
+     $                           LDAB-1 )
+*
+*                    Copy the lower triangle of A13 back into place.
+*
+                     DO 60 JJ = 1, I3
+                        DO 50 II = JJ, IB
+                           AB( II-JJ+1, JJ+I+KD-1 ) = WORK( II, JJ )
+   50                   CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+   70       CONTINUE
+         ELSE
+*
+*           Compute the Cholesky factorization of a symmetric band
+*           matrix, given the lower triangle of the matrix in band
+*           storage.
+*
+*           Zero the lower triangle of the work array.
+*
+            DO 90 J = 1, NB
+               DO 80 I = J + 1, NB
+                  WORK( I, J ) = ZERO
+   80          CONTINUE
+   90       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 140 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL SPOTF2( UPLO, IB, AB( 1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11
+*                    A21   A22
+*                    A31   A32   A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A21, A22 and
+*                 A32 are empty if IB = KD. The lower triangle of A31
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A21
+*
+                     CALL STRSM( 'Right', 'Lower', 'Transpose',
+     $                           'Non-unit', I2, IB, ONE, AB( 1, I ),
+     $                           LDAB-1, AB( 1+IB, I ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL SSYRK( 'Lower', 'No Transpose', I2, IB, -ONE,
+     $                           AB( 1+IB, I ), LDAB-1, ONE,
+     $                           AB( 1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the upper triangle of A31 into the work array.
+*
+                     DO 110 JJ = 1, IB
+                        DO 100 II = 1, MIN( JJ, I3 )
+                           WORK( II, JJ ) = AB( KD+1-JJ+II, JJ+I-1 )
+  100                   CONTINUE
+  110                CONTINUE
+*
+*                    Update A31 (in the work array).
+*
+                     CALL STRSM( 'Right', 'Lower', 'Transpose',
+     $                           'Non-unit', I3, IB, ONE, AB( 1, I ),
+     $                           LDAB-1, WORK, LDWORK )
+*
+*                    Update A32
+*
+                     IF( I2.GT.0 )
+     $                  CALL SGEMM( 'No transpose', 'Transpose', I3, I2,
+     $                              IB, -ONE, WORK, LDWORK,
+     $                              AB( 1+IB, I ), LDAB-1, ONE,
+     $                              AB( 1+KD-IB, I+IB ), LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL SSYRK( 'Lower', 'No Transpose', I3, IB, -ONE,
+     $                           WORK, LDWORK, ONE, AB( 1, I+KD ),
+     $                           LDAB-1 )
+*
+*                    Copy the upper triangle of A31 back into place.
+*
+                     DO 130 JJ = 1, IB
+                        DO 120 II = 1, MIN( JJ, I3 )
+                           AB( KD+1-JJ+II, JJ+I-1 ) = WORK( II, JJ )
+  120                   CONTINUE
+  130                CONTINUE
+                  END IF
+               END IF
+  140       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+  150 CONTINUE
+      RETURN
+*
+*     End of SPBTRF
+*
+      END
diff --git a/libcruft/lapack/spbtrs.f b/libcruft/lapack/spbtrs.f
new file mode 100644
index 0000000..2238477
--- /dev/null
+++ b/libcruft/lapack/spbtrs.f
@@ -0,0 +1,145 @@
+      SUBROUTINE SPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPBTRS solves a system of linear equations A*X = B with a symmetric
+*  positive definite band matrix A using the Cholesky factorization
+*  A = U**T*U or A = L*L**T computed by SPBTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) REAL array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           STBSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+         DO 10 J = 1, NRHS
+*
+*           Solve U'*X = B, overwriting B with X.
+*
+            CALL STBSV( 'Upper', 'Transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL STBSV( 'Upper', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+         DO 20 J = 1, NRHS
+*
+*           Solve L*X = B, overwriting B with X.
+*
+            CALL STBSV( 'Lower', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+*
+*           Solve L'*X = B, overwriting B with X.
+*
+            CALL STBSV( 'Lower', 'Transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SPBTRS
+*
+      END
diff --git a/libcruft/lapack/spocon.f b/libcruft/lapack/spocon.f
new file mode 100644
index 0000000..dacba22
--- /dev/null
+++ b/libcruft/lapack/spocon.f
@@ -0,0 +1,177 @@
+      SUBROUTINE SPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, IWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+      REAL               ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPOCON estimates the reciprocal of the condition number (in the 
+*  1-norm) of a real symmetric positive definite matrix using the
+*  Cholesky factorization A = U**T*U or A = L*L**T computed by SPOTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T, as computed by SPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) REAL
+*          The 1-norm (or infinity-norm) of the symmetric matrix A.
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) REAL array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      REAL               AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACN2, SLATRS, SRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPOCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = SLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of inv(A).
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL SLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,
+     $                   LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL SLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL SLATRS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL SLATRS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N, A,
+     $                   LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = ISAMAX( N, WORK, 1 )
+            IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL SRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of SPOCON
+*
+      END
diff --git a/libcruft/lapack/spotf2.f b/libcruft/lapack/spotf2.f
new file mode 100644
index 0000000..247ccb0
--- /dev/null
+++ b/libcruft/lapack/spotf2.f
@@ -0,0 +1,167 @@
+      SUBROUTINE SPOTF2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPOTF2 computes the Cholesky factorization of a real symmetric
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U'*U  or A = L*L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+      REAL               AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SDOT
+      EXTERNAL           LSAME, SDOT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPOTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = A( J, J ) - SDOT( J-1, A( 1, J ), 1, A( 1, J ), 1 )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of row J.
+*
+            IF( J.LT.N ) THEN
+               CALL SGEMV( 'Transpose', J-1, N-J, -ONE, A( 1, J+1 ),
+     $                     LDA, A( 1, J ), 1, ONE, A( J, J+1 ), LDA )
+               CALL SSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = A( J, J ) - SDOT( J-1, A( J, 1 ), LDA, A( J, 1 ),
+     $            LDA )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of column J.
+*
+            IF( J.LT.N ) THEN
+               CALL SGEMV( 'No transpose', N-J, J-1, -ONE, A( J+1, 1 ),
+     $                     LDA, A( J, 1 ), LDA, ONE, A( J+1, J ), 1 )
+               CALL SSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = J
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of SPOTF2
+*
+      END
diff --git a/libcruft/lapack/spotrf.f b/libcruft/lapack/spotrf.f
new file mode 100644
index 0000000..396fdb0
--- /dev/null
+++ b/libcruft/lapack/spotrf.f
@@ -0,0 +1,183 @@
+      SUBROUTINE SPOTRF( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPOTRF computes the Cholesky factorization of a real symmetric
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U**T * U,  if UPLO = 'U', or
+*     A = L  * L**T,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the block version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U**T*U or A = L*L**T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, JB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMM, SPOTF2, SSYRK, STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPOTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'SPOTRF', UPLO, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         CALL SPOTF2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         IF( UPPER ) THEN
+*
+*           Compute the Cholesky factorization A = U'*U.
+*
+            DO 10 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL SSYRK( 'Upper', 'Transpose', JB, J-1, -ONE,
+     $                     A( 1, J ), LDA, ONE, A( J, J ), LDA )
+               CALL SPOTF2( 'Upper', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block row.
+*
+                  CALL SGEMM( 'Transpose', 'No transpose', JB, N-J-JB+1,
+     $                        J-1, -ONE, A( 1, J ), LDA, A( 1, J+JB ),
+     $                        LDA, ONE, A( J, J+JB ), LDA )
+                  CALL STRSM( 'Left', 'Upper', 'Transpose', 'Non-unit',
+     $                        JB, N-J-JB+1, ONE, A( J, J ), LDA,
+     $                        A( J, J+JB ), LDA )
+               END IF
+   10       CONTINUE
+*
+         ELSE
+*
+*           Compute the Cholesky factorization A = L*L'.
+*
+            DO 20 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL SSYRK( 'Lower', 'No transpose', JB, J-1, -ONE,
+     $                     A( J, 1 ), LDA, ONE, A( J, J ), LDA )
+               CALL SPOTF2( 'Lower', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block column.
+*
+                  CALL SGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB,
+     $                        J-1, -ONE, A( J+JB, 1 ), LDA, A( J, 1 ),
+     $                        LDA, ONE, A( J+JB, J ), LDA )
+                  CALL STRSM( 'Right', 'Lower', 'Transpose', 'Non-unit',
+     $                        N-J-JB+1, JB, ONE, A( J, J ), LDA,
+     $                        A( J+JB, J ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = INFO + J - 1
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of SPOTRF
+*
+      END
diff --git a/libcruft/lapack/spotri.f b/libcruft/lapack/spotri.f
new file mode 100644
index 0000000..75fefa2
--- /dev/null
+++ b/libcruft/lapack/spotri.f
@@ -0,0 +1,96 @@
+      SUBROUTINE SPOTRI( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPOTRI computes the inverse of a real symmetric positive definite
+*  matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
+*  computed by SPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the triangular factor U or L from the Cholesky
+*          factorization A = U**T*U or A = L*L**T, as computed by
+*          SPOTRF.
+*          On exit, the upper or lower triangle of the (symmetric)
+*          inverse of A, overwriting the input factor U or L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the (i,i) element of the factor U or L is
+*                zero, and the inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAUUM, STRTRI, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPOTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Invert the triangular Cholesky factor U or L.
+*
+      CALL STRTRI( UPLO, 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+*     Form inv(U)*inv(U)' or inv(L)'*inv(L).
+*
+      CALL SLAUUM( UPLO, N, A, LDA, INFO )
+*
+      RETURN
+*
+*     End of SPOTRI
+*
+      END
diff --git a/libcruft/lapack/spotrs.f b/libcruft/lapack/spotrs.f
new file mode 100644
index 0000000..27d449c
--- /dev/null
+++ b/libcruft/lapack/spotrs.f
@@ -0,0 +1,132 @@
+      SUBROUTINE SPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPOTRS solves a system of linear equations A*X = B with a symmetric
+*  positive definite matrix A using the Cholesky factorization
+*  A = U**T*U or A = L*L**T computed by SPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**T*U or A = L*L**T, as computed by SPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPOTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Lower', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL STRSM( 'Left', 'Lower', 'Transpose', 'Non-unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+      END IF
+*
+      RETURN
+*
+*     End of SPOTRS
+*
+      END
diff --git a/libcruft/lapack/sptsv.f b/libcruft/lapack/sptsv.f
new file mode 100644
index 0000000..6c3c515
--- /dev/null
+++ b/libcruft/lapack/sptsv.f
@@ -0,0 +1,99 @@
+      SUBROUTINE SPTSV( N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               B( LDB, * ), D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPTSV computes the solution to a real system of linear equations
+*  A*X = B, where A is an N-by-N symmetric positive definite tridiagonal
+*  matrix, and X and B are N-by-NRHS matrices.
+*
+*  A is factored as A = L*D*L**T, and the factored form of A is then
+*  used to solve the system of equations.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the factorization A = L*D*L**T.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L**T factorization of
+*          A.  (E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U**T*D*U factorization of A.)
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the solution has not been
+*                computed.  The factorization has not been completed
+*                unless i = N.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           SPTTRF, SPTTRS, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPTSV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      CALL SPTTRF( N, D, E, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL SPTTRS( N, NRHS, D, E, B, LDB, INFO )
+      END IF
+      RETURN
+*
+*     End of SPTSV
+*
+      END
diff --git a/libcruft/lapack/spttrf.f b/libcruft/lapack/spttrf.f
new file mode 100644
index 0000000..cb3df35
--- /dev/null
+++ b/libcruft/lapack/spttrf.f
@@ -0,0 +1,152 @@
+      SUBROUTINE SPTTRF( N, D, E, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPTTRF computes the L*D*L' factorization of a real symmetric
+*  positive definite tridiagonal matrix A.  The factorization may also
+*  be regarded as having the form A = U'*D*U.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the L*D*L' factorization of A.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L' factorization of A.
+*          E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U'*D*U factorization of A.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite; if k < N, the factorization could not
+*               be completed, while if k = N, the factorization was
+*               completed, but D(N) <= 0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I4
+      REAL               EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MOD
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'SPTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      I4 = MOD( N-1, 4 )
+      DO 10 I = 1, I4
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 30
+         END IF
+         EI = E( I )
+         E( I ) = EI / D( I )
+         D( I+1 ) = D( I+1 ) - E( I )*EI
+   10 CONTINUE
+*
+      DO 20 I = I4 + 1, N - 4, 4
+*
+*        Drop out of the loop if d(i) <= 0: the matrix is not positive
+*        definite.
+*
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 30
+         END IF
+*
+*        Solve for e(i) and d(i+1).
+*
+         EI = E( I )
+         E( I ) = EI / D( I )
+         D( I+1 ) = D( I+1 ) - E( I )*EI
+*
+         IF( D( I+1 ).LE.ZERO ) THEN
+            INFO = I + 1
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+1) and d(i+2).
+*
+         EI = E( I+1 )
+         E( I+1 ) = EI / D( I+1 )
+         D( I+2 ) = D( I+2 ) - E( I+1 )*EI
+*
+         IF( D( I+2 ).LE.ZERO ) THEN
+            INFO = I + 2
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+2) and d(i+3).
+*
+         EI = E( I+2 )
+         E( I+2 ) = EI / D( I+2 )
+         D( I+3 ) = D( I+3 ) - E( I+2 )*EI
+*
+         IF( D( I+3 ).LE.ZERO ) THEN
+            INFO = I + 3
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+3) and d(i+4).
+*
+         EI = E( I+3 )
+         E( I+3 ) = EI / D( I+3 )
+         D( I+4 ) = D( I+4 ) - E( I+3 )*EI
+   20 CONTINUE
+*
+*     Check d(n) for positive definiteness.
+*
+      IF( D( N ).LE.ZERO )
+     $   INFO = N
+*
+   30 CONTINUE
+      RETURN
+*
+*     End of SPTTRF
+*
+      END
diff --git a/libcruft/lapack/spttrs.f b/libcruft/lapack/spttrs.f
new file mode 100644
index 0000000..569e233
--- /dev/null
+++ b/libcruft/lapack/spttrs.f
@@ -0,0 +1,114 @@
+      SUBROUTINE SPTTRS( N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               B( LDB, * ), D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPTTRS solves a tridiagonal system of the form
+*     A * X = B
+*  using the L*D*L' factorization of A computed by SPTTRF.  D is a
+*  diagonal matrix specified in the vector D, L is a unit bidiagonal
+*  matrix whose subdiagonal is specified in the vector E, and X and B
+*  are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) REAL array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          L*D*L' factorization of A.
+*
+*  E       (input) REAL array, dimension (N-1)
+*          The (n-1) subdiagonal elements of the unit bidiagonal factor
+*          L from the L*D*L' factorization of A.  E can also be regarded
+*          as the superdiagonal of the unit bidiagonal factor U from the
+*          factorization A = U'*D*U.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SPTTS2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SPTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'SPTTRS', ' ', N, NRHS, -1, -1 ) )
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL SPTTS2( N, NRHS, D, E, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL SPTTS2( N, JB, D, E, B( 1, J ), LDB )
+   10    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SPTTRS
+*
+      END
diff --git a/libcruft/lapack/sptts2.f b/libcruft/lapack/sptts2.f
new file mode 100644
index 0000000..cf81cc3
--- /dev/null
+++ b/libcruft/lapack/sptts2.f
@@ -0,0 +1,93 @@
+      SUBROUTINE SPTTS2( N, NRHS, D, E, B, LDB )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               B( LDB, * ), D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SPTTS2 solves a tridiagonal system of the form
+*     A * X = B
+*  using the L*D*L' factorization of A computed by SPTTRF.  D is a
+*  diagonal matrix specified in the vector D, L is a unit bidiagonal
+*  matrix whose subdiagonal is specified in the vector E, and X and B
+*  are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) REAL array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          L*D*L' factorization of A.
+*
+*  E       (input) REAL array, dimension (N-1)
+*          The (n-1) subdiagonal elements of the unit bidiagonal factor
+*          L from the L*D*L' factorization of A.  E can also be regarded
+*          as the superdiagonal of the unit bidiagonal factor U from the
+*          factorization A = U'*D*U.
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 ) THEN
+         IF( N.EQ.1 )
+     $      CALL SSCAL( NRHS, 1. / D( 1 ), B, LDB )
+         RETURN
+      END IF
+*
+*     Solve A * X = B using the factorization A = L*D*L',
+*     overwriting each right hand side vector with its solution.
+*
+      DO 30 J = 1, NRHS
+*
+*           Solve L * x = b.
+*
+         DO 10 I = 2, N
+            B( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )
+   10    CONTINUE
+*
+*           Solve D * L' * x = b.
+*
+         B( N, J ) = B( N, J ) / D( N )
+         DO 20 I = N - 1, 1, -1
+            B( I, J ) = B( I, J ) / D( I ) - B( I+1, J )*E( I )
+   20    CONTINUE
+   30 CONTINUE
+*
+      RETURN
+*
+*     End of SPTTS2
+*
+      END
diff --git a/libcruft/lapack/srscl.f b/libcruft/lapack/srscl.f
new file mode 100644
index 0000000..d40646a
--- /dev/null
+++ b/libcruft/lapack/srscl.f
@@ -0,0 +1,114 @@
+      SUBROUTINE SRSCL( N, SA, SX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      REAL               SA
+*     ..
+*     .. Array Arguments ..
+      REAL               SX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SRSCL multiplies an n-element real vector x by the real scalar 1/a.
+*  This is done without overflow or underflow as long as
+*  the final result x/a does not overflow or underflow.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of components of the vector x.
+*
+*  SA      (input) REAL
+*          The scalar a which is used to divide each component of x.
+*          SA must be >= 0, or the subroutine will divide by zero.
+*
+*  SX      (input/output) REAL array, dimension
+*                         (1+(N-1)*abs(INCX))
+*          The n-element vector x.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector SX.
+*          > 0:  SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i),     1< i<= n
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      REAL               BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH
+      EXTERNAL           SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLABAD, SSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+*
+*     Initialize the denominator to SA and the numerator to 1.
+*
+      CDEN = SA
+      CNUM = ONE
+*
+   10 CONTINUE
+      CDEN1 = CDEN*SMLNUM
+      CNUM1 = CNUM / BIGNUM
+      IF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN
+*
+*        Pre-multiply X by SMLNUM if CDEN is large compared to CNUM.
+*
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CDEN = CDEN1
+      ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN
+*
+*        Pre-multiply X by BIGNUM if CDEN is small compared to CNUM.
+*
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CNUM = CNUM1
+      ELSE
+*
+*        Multiply X by CNUM / CDEN and return.
+*
+         MUL = CNUM / CDEN
+         DONE = .TRUE.
+      END IF
+*
+*     Scale the vector X by MUL
+*
+      CALL SSCAL( N, MUL, SX, INCX )
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of SRSCL
+*
+      END
diff --git a/libcruft/lapack/ssteqr.f b/libcruft/lapack/ssteqr.f
new file mode 100644
index 0000000..15a2d35
--- /dev/null
+++ b/libcruft/lapack/ssteqr.f
@@ -0,0 +1,500 @@
+      SUBROUTINE SSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPZ
+      INTEGER            INFO, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSTEQR computes all eigenvalues and, optionally, eigenvectors of a
+*  symmetric tridiagonal matrix using the implicit QL or QR method.
+*  The eigenvectors of a full or band symmetric matrix can also be found
+*  if SSYTRD or SSPTRD or SSBTRD has been used to reduce this matrix to
+*  tridiagonal form.
+*
+*  Arguments
+*  =========
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only.
+*          = 'V':  Compute eigenvalues and eigenvectors of the original
+*                  symmetric matrix.  On entry, Z must contain the
+*                  orthogonal matrix used to reduce the original matrix
+*                  to tridiagonal form.
+*          = 'I':  Compute eigenvalues and eigenvectors of the
+*                  tridiagonal matrix.  Z is initialized to the identity
+*                  matrix.
+*
+*  N       (input) INTEGER
+*          The order of the matrix.  N >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the diagonal elements of the tridiagonal matrix.
+*          On exit, if INFO = 0, the eigenvalues in ascending order.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix.
+*          On exit, E has been destroyed.
+*
+*  Z       (input/output) REAL array, dimension (LDZ, N)
+*          On entry, if  COMPZ = 'V', then Z contains the orthogonal
+*          matrix used in the reduction to tridiagonal form.
+*          On exit, if INFO = 0, then if  COMPZ = 'V', Z contains the
+*          orthonormal eigenvectors of the original symmetric matrix,
+*          and if COMPZ = 'I', Z contains the orthonormal eigenvectors
+*          of the symmetric tridiagonal matrix.
+*          If COMPZ = 'N', then Z is not referenced.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1, and if
+*          eigenvectors are desired, then  LDZ >= max(1,N).
+*
+*  WORK    (workspace) REAL array, dimension (max(1,2*N-2))
+*          If COMPZ = 'N', then WORK is not referenced.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm has failed to find all the eigenvalues in
+*                a total of 30*N iterations; if INFO = i, then i
+*                elements of E have not converged to zero; on exit, D
+*                and E contain the elements of a symmetric tridiagonal
+*                matrix which is orthogonally similar to the original
+*                matrix.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO, THREE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
+     $                   THREE = 3.0E0 )
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 30 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
+     $                   LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
+     $                   NM1, NMAXIT
+      REAL               ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
+     $                   S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH, SLANST, SLAPY2
+      EXTERNAL           LSAME, SLAMCH, SLANST, SLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAE2, SLAEV2, SLARTG, SLASCL, SLASET, SLASR,
+     $                   SLASRT, SSWAP, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ICOMPZ = 0
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ICOMPZ = 2
+      ELSE
+         ICOMPZ = -1
+      END IF
+      IF( ICOMPZ.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,
+     $         N ) ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSTEQR', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( N.EQ.1 ) THEN
+         IF( ICOMPZ.EQ.2 )
+     $      Z( 1, 1 ) = ONE
+         RETURN
+      END IF
+*
+*     Determine the unit roundoff and over/underflow thresholds.
+*
+      EPS = SLAMCH( 'E' )
+      EPS2 = EPS**2
+      SAFMIN = SLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      SSFMAX = SQRT( SAFMAX ) / THREE
+      SSFMIN = SQRT( SAFMIN ) / EPS2
+*
+*     Compute the eigenvalues and eigenvectors of the tridiagonal
+*     matrix.
+*
+      IF( ICOMPZ.EQ.2 )
+     $   CALL SLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
+*
+      NMAXIT = N*MAXIT
+      JTOT = 0
+*
+*     Determine where the matrix splits and choose QL or QR iteration
+*     for each block, according to whether top or bottom diagonal
+*     element is smaller.
+*
+      L1 = 1
+      NM1 = N - 1
+*
+   10 CONTINUE
+      IF( L1.GT.N )
+     $   GO TO 160
+      IF( L1.GT.1 )
+     $   E( L1-1 ) = ZERO
+      IF( L1.LE.NM1 ) THEN
+         DO 20 M = L1, NM1
+            TST = ABS( E( M ) )
+            IF( TST.EQ.ZERO )
+     $         GO TO 30
+            IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
+     $          1 ) ) ) )*EPS ) THEN
+               E( M ) = ZERO
+               GO TO 30
+            END IF
+   20    CONTINUE
+      END IF
+      M = N
+*
+   30 CONTINUE
+      L = L1
+      LSV = L
+      LEND = M
+      LENDSV = LEND
+      L1 = M + 1
+      IF( LEND.EQ.L )
+     $   GO TO 10
+*
+*     Scale submatrix in rows and columns L to LEND
+*
+      ANORM = SLANST( 'I', LEND-L+1, D( L ), E( L ) )
+      ISCALE = 0
+      IF( ANORM.EQ.ZERO )
+     $   GO TO 10
+      IF( ANORM.GT.SSFMAX ) THEN
+         ISCALE = 1
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
+     $                INFO )
+      ELSE IF( ANORM.LT.SSFMIN ) THEN
+         ISCALE = 2
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
+     $                INFO )
+      END IF
+*
+*     Choose between QL and QR iteration
+*
+      IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
+         LEND = LSV
+         L = LENDSV
+      END IF
+*
+      IF( LEND.GT.L ) THEN
+*
+*        QL Iteration
+*
+*        Look for small subdiagonal element.
+*
+   40    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDM1 = LEND - 1
+            DO 50 M = L, LENDM1
+               TST = ABS( E( M ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+
+     $             SAFMIN )GO TO 60
+   50       CONTINUE
+         END IF
+*
+         M = LEND
+*
+   60    CONTINUE
+         IF( M.LT.LEND )
+     $      E( M ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 80
+*
+*        If remaining matrix is 2-by-2, use SLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L+1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL SLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )
+               WORK( L ) = C
+               WORK( N-1+L ) = S
+               CALL SLASR( 'R', 'V', 'B', N, 2, WORK( L ),
+     $                     WORK( N-1+L ), Z( 1, L ), LDZ )
+            ELSE
+               CALL SLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )
+            END IF
+            D( L ) = RT1
+            D( L+1 ) = RT2
+            E( L ) = ZERO
+            L = L + 2
+            IF( L.LE.LEND )
+     $         GO TO 40
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L+1 )-P ) / ( TWO*E( L ) )
+         R = SLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         MM1 = M - 1
+         DO 70 I = MM1, L, -1
+            F = S*E( I )
+            B = C*E( I )
+            CALL SLARTG( G, F, C, S, R )
+            IF( I.NE.M-1 )
+     $         E( I+1 ) = R
+            G = D( I+1 ) - P
+            R = ( D( I )-G )*S + TWO*C*B
+            P = S*R
+            D( I+1 ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = -S
+            END IF
+*
+   70    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = M - L + 1
+            CALL SLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),
+     $                  Z( 1, L ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( L ) = G
+         GO TO 40
+*
+*        Eigenvalue found.
+*
+   80    CONTINUE
+         D( L ) = P
+*
+         L = L + 1
+         IF( L.LE.LEND )
+     $      GO TO 40
+         GO TO 140
+*
+      ELSE
+*
+*        QR Iteration
+*
+*        Look for small superdiagonal element.
+*
+   90    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDP1 = LEND + 1
+            DO 100 M = L, LENDP1, -1
+               TST = ABS( E( M-1 ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+
+     $             SAFMIN )GO TO 110
+  100       CONTINUE
+         END IF
+*
+         M = LEND
+*
+  110    CONTINUE
+         IF( M.GT.LEND )
+     $      E( M-1 ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 130
+*
+*        If remaining matrix is 2-by-2, use SLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L-1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL SLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )
+               WORK( M ) = C
+               WORK( N-1+M ) = S
+               CALL SLASR( 'R', 'V', 'F', N, 2, WORK( M ),
+     $                     WORK( N-1+M ), Z( 1, L-1 ), LDZ )
+            ELSE
+               CALL SLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )
+            END IF
+            D( L-1 ) = RT1
+            D( L ) = RT2
+            E( L-1 ) = ZERO
+            L = L - 2
+            IF( L.GE.LEND )
+     $         GO TO 90
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )
+         R = SLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         LM1 = L - 1
+         DO 120 I = M, LM1
+            F = S*E( I )
+            B = C*E( I )
+            CALL SLARTG( G, F, C, S, R )
+            IF( I.NE.M )
+     $         E( I-1 ) = R
+            G = D( I ) - P
+            R = ( D( I+1 )-G )*S + TWO*C*B
+            P = S*R
+            D( I ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = S
+            END IF
+*
+  120    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = L - M + 1
+            CALL SLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),
+     $                  Z( 1, M ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( LM1 ) = G
+         GO TO 90
+*
+*        Eigenvalue found.
+*
+  130    CONTINUE
+         D( L ) = P
+*
+         L = L - 1
+         IF( L.GE.LEND )
+     $      GO TO 90
+         GO TO 140
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+  140 CONTINUE
+      IF( ISCALE.EQ.1 ) THEN
+         CALL SLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL SLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      ELSE IF( ISCALE.EQ.2 ) THEN
+         CALL SLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL SLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      END IF
+*
+*     Check for no convergence to an eigenvalue after a total
+*     of N*MAXIT iterations.
+*
+      IF( JTOT.LT.NMAXIT )
+     $   GO TO 10
+      DO 150 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  150 CONTINUE
+      GO TO 190
+*
+*     Order eigenvalues and eigenvectors.
+*
+  160 CONTINUE
+      IF( ICOMPZ.EQ.0 ) THEN
+*
+*        Use Quick Sort
+*
+         CALL SLASRT( 'I', N, D, INFO )
+*
+      ELSE
+*
+*        Use Selection Sort to minimize swaps of eigenvectors
+*
+         DO 180 II = 2, N
+            I = II - 1
+            K = I
+            P = D( I )
+            DO 170 J = II, N
+               IF( D( J ).LT.P ) THEN
+                  K = J
+                  P = D( J )
+               END IF
+  170       CONTINUE
+            IF( K.NE.I ) THEN
+               D( K ) = D( I )
+               D( I ) = P
+               CALL SSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
+            END IF
+  180    CONTINUE
+      END IF
+*
+  190 CONTINUE
+      RETURN
+*
+*     End of SSTEQR
+*
+      END
diff --git a/libcruft/lapack/ssterf.f b/libcruft/lapack/ssterf.f
new file mode 100644
index 0000000..f56d56e
--- /dev/null
+++ b/libcruft/lapack/ssterf.f
@@ -0,0 +1,364 @@
+      SUBROUTINE SSTERF( N, D, E, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      REAL               D( * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSTERF computes all eigenvalues of a symmetric tridiagonal matrix
+*  using the Pal-Walker-Kahan variant of the QL or QR algorithm.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix.  N >= 0.
+*
+*  D       (input/output) REAL array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix.
+*          On exit, if INFO = 0, the eigenvalues in ascending order.
+*
+*  E       (input/output) REAL array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix.
+*          On exit, E has been destroyed.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm failed to find all of the eigenvalues in
+*                a total of 30*N iterations; if INFO = i, then i
+*                elements of E have not converged to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, TWO, THREE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
+     $                   THREE = 3.0E0 )
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 30 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,
+     $                   NMAXIT
+      REAL               ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,
+     $                   OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,
+     $                   SIGMA, SSFMAX, SSFMIN
+*     ..
+*     .. External Functions ..
+      REAL               SLAMCH, SLANST, SLAPY2
+      EXTERNAL           SLAMCH, SLANST, SLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAE2, SLASCL, SLASRT, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'SSTERF', -INFO )
+         RETURN
+      END IF
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Determine the unit roundoff for this environment.
+*
+      EPS = SLAMCH( 'E' )
+      EPS2 = EPS**2
+      SAFMIN = SLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      SSFMAX = SQRT( SAFMAX ) / THREE
+      SSFMIN = SQRT( SAFMIN ) / EPS2
+*
+*     Compute the eigenvalues of the tridiagonal matrix.
+*
+      NMAXIT = N*MAXIT
+      SIGMA = ZERO
+      JTOT = 0
+*
+*     Determine where the matrix splits and choose QL or QR iteration
+*     for each block, according to whether top or bottom diagonal
+*     element is smaller.
+*
+      L1 = 1
+*
+   10 CONTINUE
+      IF( L1.GT.N )
+     $   GO TO 170
+      IF( L1.GT.1 )
+     $   E( L1-1 ) = ZERO
+      DO 20 M = L1, N - 1
+         IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*
+     $       SQRT( ABS( D( M+1 ) ) ) )*EPS ) THEN
+            E( M ) = ZERO
+            GO TO 30
+         END IF
+   20 CONTINUE
+      M = N
+*
+   30 CONTINUE
+      L = L1
+      LSV = L
+      LEND = M
+      LENDSV = LEND
+      L1 = M + 1
+      IF( LEND.EQ.L )
+     $   GO TO 10
+*
+*     Scale submatrix in rows and columns L to LEND
+*
+      ANORM = SLANST( 'I', LEND-L+1, D( L ), E( L ) )
+      ISCALE = 0
+      IF( ANORM.GT.SSFMAX ) THEN
+         ISCALE = 1
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
+     $                INFO )
+      ELSE IF( ANORM.LT.SSFMIN ) THEN
+         ISCALE = 2
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
+     $                INFO )
+      END IF
+*
+      DO 40 I = L, LEND - 1
+         E( I ) = E( I )**2
+   40 CONTINUE
+*
+*     Choose between QL and QR iteration
+*
+      IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
+         LEND = LSV
+         L = LENDSV
+      END IF
+*
+      IF( LEND.GE.L ) THEN
+*
+*        QL Iteration
+*
+*        Look for small subdiagonal element.
+*
+   50    CONTINUE
+         IF( L.NE.LEND ) THEN
+            DO 60 M = L, LEND - 1
+               IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) )
+     $            GO TO 70
+   60       CONTINUE
+         END IF
+         M = LEND
+*
+   70    CONTINUE
+         IF( M.LT.LEND )
+     $      E( M ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 90
+*
+*        If remaining matrix is 2 by 2, use SLAE2 to compute its
+*        eigenvalues.
+*
+         IF( M.EQ.L+1 ) THEN
+            RTE = SQRT( E( L ) )
+            CALL SLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )
+            D( L ) = RT1
+            D( L+1 ) = RT2
+            E( L ) = ZERO
+            L = L + 2
+            IF( L.LE.LEND )
+     $         GO TO 50
+            GO TO 150
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 150
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         RTE = SQRT( E( L ) )
+         SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )
+         R = SLAPY2( SIGMA, ONE )
+         SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
+*
+         C = ONE
+         S = ZERO
+         GAMMA = D( M ) - SIGMA
+         P = GAMMA*GAMMA
+*
+*        Inner loop
+*
+         DO 80 I = M - 1, L, -1
+            BB = E( I )
+            R = P + BB
+            IF( I.NE.M-1 )
+     $         E( I+1 ) = S*R
+            OLDC = C
+            C = P / R
+            S = BB / R
+            OLDGAM = GAMMA
+            ALPHA = D( I )
+            GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
+            D( I+1 ) = OLDGAM + ( ALPHA-GAMMA )
+            IF( C.NE.ZERO ) THEN
+               P = ( GAMMA*GAMMA ) / C
+            ELSE
+               P = OLDC*BB
+            END IF
+   80    CONTINUE
+*
+         E( L ) = S*P
+         D( L ) = SIGMA + GAMMA
+         GO TO 50
+*
+*        Eigenvalue found.
+*
+   90    CONTINUE
+         D( L ) = P
+*
+         L = L + 1
+         IF( L.LE.LEND )
+     $      GO TO 50
+         GO TO 150
+*
+      ELSE
+*
+*        QR Iteration
+*
+*        Look for small superdiagonal element.
+*
+  100    CONTINUE
+         DO 110 M = L, LEND + 1, -1
+            IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) )
+     $         GO TO 120
+  110    CONTINUE
+         M = LEND
+*
+  120    CONTINUE
+         IF( M.GT.LEND )
+     $      E( M-1 ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 140
+*
+*        If remaining matrix is 2 by 2, use SLAE2 to compute its
+*        eigenvalues.
+*
+         IF( M.EQ.L-1 ) THEN
+            RTE = SQRT( E( L-1 ) )
+            CALL SLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )
+            D( L ) = RT1
+            D( L-1 ) = RT2
+            E( L-1 ) = ZERO
+            L = L - 2
+            IF( L.GE.LEND )
+     $         GO TO 100
+            GO TO 150
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 150
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         RTE = SQRT( E( L-1 ) )
+         SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )
+         R = SLAPY2( SIGMA, ONE )
+         SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
+*
+         C = ONE
+         S = ZERO
+         GAMMA = D( M ) - SIGMA
+         P = GAMMA*GAMMA
+*
+*        Inner loop
+*
+         DO 130 I = M, L - 1
+            BB = E( I )
+            R = P + BB
+            IF( I.NE.M )
+     $         E( I-1 ) = S*R
+            OLDC = C
+            C = P / R
+            S = BB / R
+            OLDGAM = GAMMA
+            ALPHA = D( I+1 )
+            GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
+            D( I ) = OLDGAM + ( ALPHA-GAMMA )
+            IF( C.NE.ZERO ) THEN
+               P = ( GAMMA*GAMMA ) / C
+            ELSE
+               P = OLDC*BB
+            END IF
+  130    CONTINUE
+*
+         E( L-1 ) = S*P
+         D( L ) = SIGMA + GAMMA
+         GO TO 100
+*
+*        Eigenvalue found.
+*
+  140    CONTINUE
+         D( L ) = P
+*
+         L = L - 1
+         IF( L.GE.LEND )
+     $      GO TO 100
+         GO TO 150
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+  150 CONTINUE
+      IF( ISCALE.EQ.1 )
+     $   CALL SLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+      IF( ISCALE.EQ.2 )
+     $   CALL SLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+*
+*     Check for no convergence to an eigenvalue after a total
+*     of N*MAXIT iterations.
+*
+      IF( JTOT.LT.NMAXIT )
+     $   GO TO 10
+      DO 160 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  160 CONTINUE
+      GO TO 180
+*
+*     Sort eigenvalues in increasing order.
+*
+  170 CONTINUE
+      CALL SLASRT( 'I', N, D, INFO )
+*
+  180 CONTINUE
+      RETURN
+*
+*     End of SSTERF
+*
+      END
diff --git a/libcruft/lapack/ssyev.f b/libcruft/lapack/ssyev.f
new file mode 100644
index 0000000..0e671c9
--- /dev/null
+++ b/libcruft/lapack/ssyev.f
@@ -0,0 +1,211 @@
+      SUBROUTINE SSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYEV computes all eigenvalues and, optionally, eigenvectors of a
+*  real symmetric matrix A.
+*
+*  Arguments
+*  =========
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA, N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          orthonormal eigenvectors of the matrix A.
+*          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
+*          or the upper triangle (if UPLO='U') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  W       (output) REAL array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,3*N-1).
+*          For optimal efficiency, LWORK >= (NB+2)*N,
+*          where NB is the blocksize for SSYTRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the algorithm failed to converge; i
+*                off-diagonal elements of an intermediate tridiagonal
+*                form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, LQUERY, WANTZ
+      INTEGER            IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
+     $                   LLWORK, LWKOPT, NB
+      REAL               ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
+     $                   SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      REAL               SLAMCH, SLANSY
+      EXTERNAL           ILAENV, LSAME, SLAMCH, SLANSY
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLASCL, SORGTR, SSCAL, SSTEQR, SSTERF, SSYTRD,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      LOWER = LSAME( UPLO, 'L' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'SSYTRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( 1, ( NB+2 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )
+     $      INFO = -8
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSYEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         W( 1 ) = A( 1, 1 )
+         WORK( 1 ) = 2
+         IF( WANTZ )
+     $      A( 1, 1 ) = ONE
+         RETURN
+      END IF
+*
+*     Get machine constants.
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      EPS = SLAMCH( 'Precision' )
+      SMLNUM = SAFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      RMIN = SQRT( SMLNUM )
+      RMAX = SQRT( BIGNUM )
+*
+*     Scale matrix to allowable range, if necessary.
+*
+      ANRM = SLANSY( 'M', UPLO, N, A, LDA, WORK )
+      ISCALE = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
+         ISCALE = 1
+         SIGMA = RMIN / ANRM
+      ELSE IF( ANRM.GT.RMAX ) THEN
+         ISCALE = 1
+         SIGMA = RMAX / ANRM
+      END IF
+      IF( ISCALE.EQ.1 )
+     $   CALL SLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
+*
+*     Call SSYTRD to reduce symmetric matrix to tridiagonal form.
+*
+      INDE = 1
+      INDTAU = INDE + N
+      INDWRK = INDTAU + N
+      LLWORK = LWORK - INDWRK + 1
+      CALL SSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),
+     $             WORK( INDWRK ), LLWORK, IINFO )
+*
+*     For eigenvalues only, call SSTERF.  For eigenvectors, first call
+*     SORGTR to generate the orthogonal matrix, then call SSTEQR.
+*
+      IF( .NOT.WANTZ ) THEN
+         CALL SSTERF( N, W, WORK( INDE ), INFO )
+      ELSE
+         CALL SORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
+     $                LLWORK, IINFO )
+         CALL SSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),
+     $                INFO )
+      END IF
+*
+*     If matrix was scaled, then rescale eigenvalues appropriately.
+*
+      IF( ISCALE.EQ.1 ) THEN
+         IF( INFO.EQ.0 ) THEN
+            IMAX = N
+         ELSE
+            IMAX = INFO - 1
+         END IF
+         CALL SSCAL( IMAX, ONE / SIGMA, W, 1 )
+      END IF
+*
+*     Set WORK(1) to optimal workspace size.
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of SSYEV
+*
+      END
diff --git a/libcruft/lapack/ssygs2.f b/libcruft/lapack/ssygs2.f
new file mode 100644
index 0000000..0f8deeb
--- /dev/null
+++ b/libcruft/lapack/ssygs2.f
@@ -0,0 +1,211 @@
+      SUBROUTINE SSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYGS2 reduces a real symmetric-definite generalized eigenproblem
+*  to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U')*A*inv(U) or inv(L)*A*inv(L')
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U` or L'*A*L.
+*
+*  B must have been previously factorized as U'*U or L*L' by SPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U')*A*inv(U) or inv(L)*A*inv(L');
+*          = 2 or 3: compute U*A*U' or L'*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored, and how B has been factorized.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) REAL array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by SPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, HALF
+      PARAMETER          ( ONE = 1.0, HALF = 0.5 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K
+      REAL               AKK, BKK, CT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SSCAL, SSYR2, STRMV, STRSV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSYGS2', -INFO )
+         RETURN
+      END IF
+*
+      IF( ITYPE.EQ.1 ) THEN
+         IF( UPPER ) THEN
+*
+*           Compute inv(U')*A*inv(U)
+*
+            DO 10 K = 1, N
+*
+*              Update the upper triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL SSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA )
+                  CT = -HALF*AKK
+                  CALL SAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL SSYR2( UPLO, N-K, -ONE, A( K, K+1 ), LDA,
+     $                        B( K, K+1 ), LDB, A( K+1, K+1 ), LDA )
+                  CALL SAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL STRSV( UPLO, 'Transpose', 'Non-unit', N-K,
+     $                        B( K+1, K+1 ), LDB, A( K, K+1 ), LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute inv(L)*A*inv(L')
+*
+            DO 20 K = 1, N
+*
+*              Update the lower triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL SSCAL( N-K, ONE / BKK, A( K+1, K ), 1 )
+                  CT = -HALF*AKK
+                  CALL SAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL SSYR2( UPLO, N-K, -ONE, A( K+1, K ), 1,
+     $                        B( K+1, K ), 1, A( K+1, K+1 ), LDA )
+                  CALL SAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL STRSV( UPLO, 'No transpose', 'Non-unit', N-K,
+     $                        B( K+1, K+1 ), LDB, A( K+1, K ), 1 )
+               END IF
+   20       CONTINUE
+         END IF
+      ELSE
+         IF( UPPER ) THEN
+*
+*           Compute U*A*U'
+*
+            DO 30 K = 1, N
+*
+*              Update the upper triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL STRMV( UPLO, 'No transpose', 'Non-unit', K-1, B,
+     $                     LDB, A( 1, K ), 1 )
+               CT = HALF*AKK
+               CALL SAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL SSYR2( UPLO, K-1, ONE, A( 1, K ), 1, B( 1, K ), 1,
+     $                     A, LDA )
+               CALL SAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL SSCAL( K-1, BKK, A( 1, K ), 1 )
+               A( K, K ) = AKK*BKK**2
+   30       CONTINUE
+         ELSE
+*
+*           Compute L'*A*L
+*
+            DO 40 K = 1, N
+*
+*              Update the lower triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL STRMV( UPLO, 'Transpose', 'Non-unit', K-1, B, LDB,
+     $                     A( K, 1 ), LDA )
+               CT = HALF*AKK
+               CALL SAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL SSYR2( UPLO, K-1, ONE, A( K, 1 ), LDA, B( K, 1 ),
+     $                     LDB, A, LDA )
+               CALL SAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL SSCAL( K-1, BKK, A( K, 1 ), LDA )
+               A( K, K ) = AKK*BKK**2
+   40       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of SSYGS2
+*
+      END
diff --git a/libcruft/lapack/ssygst.f b/libcruft/lapack/ssygst.f
new file mode 100644
index 0000000..16060c0
--- /dev/null
+++ b/libcruft/lapack/ssygst.f
@@ -0,0 +1,249 @@
+      SUBROUTINE SSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYGST reduces a real symmetric-definite generalized eigenproblem
+*  to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L.
+*
+*  B must have been previously factorized as U**T*U or L*L**T by SPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);
+*          = 2 or 3: compute U*A*U**T or L**T*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored and B is factored as
+*                  U**T*U;
+*          = 'L':  Lower triangle of A is stored and B is factored as
+*                  L*L**T.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) REAL array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by SPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, HALF
+      PARAMETER          ( ONE = 1.0, HALF = 0.5 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K, KB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSYGS2, SSYMM, SSYR2K, STRMM, STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSYGST', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'SSYGST', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL SSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ITYPE.EQ.1 ) THEN
+            IF( UPPER ) THEN
+*
+*              Compute inv(U')*A*inv(U)
+*
+               DO 10 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(k:n,k:n)
+*
+                  CALL SSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL STRSM( 'Left', UPLO, 'Transpose', 'Non-unit',
+     $                           KB, N-K-KB+1, ONE, B( K, K ), LDB,
+     $                           A( K, K+KB ), LDA )
+                     CALL SSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB, ONE,
+     $                           A( K, K+KB ), LDA )
+                     CALL SSYR2K( UPLO, 'Transpose', N-K-KB+1, KB, -ONE,
+     $                            A( K, K+KB ), LDA, B( K, K+KB ), LDB,
+     $                            ONE, A( K+KB, K+KB ), LDA )
+                     CALL SSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB, ONE,
+     $                           A( K, K+KB ), LDA )
+                     CALL STRSM( 'Right', UPLO, 'No transpose',
+     $                           'Non-unit', KB, N-K-KB+1, ONE,
+     $                           B( K+KB, K+KB ), LDB, A( K, K+KB ),
+     $                           LDA )
+                  END IF
+   10          CONTINUE
+            ELSE
+*
+*              Compute inv(L)*A*inv(L')
+*
+               DO 20 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(k:n,k:n)
+*
+                  CALL SSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL STRSM( 'Right', UPLO, 'Transpose', 'Non-unit',
+     $                           N-K-KB+1, KB, ONE, B( K, K ), LDB,
+     $                           A( K+KB, K ), LDA )
+                     CALL SSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB, ONE,
+     $                           A( K+KB, K ), LDA )
+                     CALL SSYR2K( UPLO, 'No transpose', N-K-KB+1, KB,
+     $                            -ONE, A( K+KB, K ), LDA, B( K+KB, K ),
+     $                            LDB, ONE, A( K+KB, K+KB ), LDA )
+                     CALL SSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB, ONE,
+     $                           A( K+KB, K ), LDA )
+                     CALL STRSM( 'Left', UPLO, 'No transpose',
+     $                           'Non-unit', N-K-KB+1, KB, ONE,
+     $                           B( K+KB, K+KB ), LDB, A( K+KB, K ),
+     $                           LDA )
+                  END IF
+   20          CONTINUE
+            END IF
+         ELSE
+            IF( UPPER ) THEN
+*
+*              Compute U*A*U'
+*
+               DO 30 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL STRMM( 'Left', UPLO, 'No transpose', 'Non-unit',
+     $                        K-1, KB, ONE, B, LDB, A( 1, K ), LDA )
+                  CALL SSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA )
+                  CALL SSYR2K( UPLO, 'No transpose', K-1, KB, ONE,
+     $                         A( 1, K ), LDA, B( 1, K ), LDB, ONE, A,
+     $                         LDA )
+                  CALL SSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA )
+                  CALL STRMM( 'Right', UPLO, 'Transpose', 'Non-unit',
+     $                        K-1, KB, ONE, B( K, K ), LDB, A( 1, K ),
+     $                        LDA )
+                  CALL SSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   30          CONTINUE
+            ELSE
+*
+*              Compute L'*A*L
+*
+               DO 40 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL STRMM( 'Right', UPLO, 'No transpose', 'Non-unit',
+     $                        KB, K-1, ONE, B, LDB, A( K, 1 ), LDA )
+                  CALL SSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA )
+                  CALL SSYR2K( UPLO, 'Transpose', K-1, KB, ONE,
+     $                         A( K, 1 ), LDA, B( K, 1 ), LDB, ONE, A,
+     $                         LDA )
+                  CALL SSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA )
+                  CALL STRMM( 'Left', UPLO, 'Transpose', 'Non-unit', KB,
+     $                        K-1, ONE, B( K, K ), LDB, A( K, 1 ), LDA )
+                  CALL SSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of SSYGST
+*
+      END
diff --git a/libcruft/lapack/ssygv.f b/libcruft/lapack/ssygv.f
new file mode 100644
index 0000000..adc73de
--- /dev/null
+++ b/libcruft/lapack/ssygv.f
@@ -0,0 +1,229 @@
+      SUBROUTINE SSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
+     $                  LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * ), W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYGV computes all the eigenvalues, and optionally, the eigenvectors
+*  of a real generalized symmetric-definite eigenproblem, of the form
+*  A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.
+*  Here A and B are assumed to be symmetric and B is also
+*  positive definite.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          Specifies the problem type to be solved:
+*          = 1:  A*x = (lambda)*B*x
+*          = 2:  A*B*x = (lambda)*x
+*          = 3:  B*A*x = (lambda)*x
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangles of A and B are stored;
+*          = 'L':  Lower triangles of A and B are stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA, N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          matrix Z of eigenvectors.  The eigenvectors are normalized
+*          as follows:
+*          if ITYPE = 1 or 2, Z**T*B*Z = I;
+*          if ITYPE = 3, Z**T*inv(B)*Z = I.
+*          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
+*          or the lower triangle (if UPLO='L') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) REAL array, dimension (LDB, N)
+*          On entry, the symmetric positive definite matrix B.
+*          If UPLO = 'U', the leading N-by-N upper triangular part of B
+*          contains the upper triangular part of the matrix B.
+*          If UPLO = 'L', the leading N-by-N lower triangular part of B
+*          contains the lower triangular part of the matrix B.
+*
+*          On exit, if INFO <= N, the part of B containing the matrix is
+*          overwritten by the triangular factor U or L from the Cholesky
+*          factorization B = U**T*U or B = L*L**T.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  W       (output) REAL array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,3*N-1).
+*          For optimal efficiency, LWORK >= (NB+2)*N,
+*          where NB is the blocksize for SSYTRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  SPOTRF or SSYEV returned an error code:
+*             <= N:  if INFO = i, SSYEV failed to converge;
+*                    i off-diagonal elements of an intermediate
+*                    tridiagonal form did not converge to zero;
+*             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
+*                    minor of order i of B is not positive definite.
+*                    The factorization of B could not be completed and
+*                    no eigenvalues or eigenvectors were computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER, WANTZ
+      CHARACTER          TRANS
+      INTEGER            LWKMIN, LWKOPT, NB, NEIG
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SPOTRF, SSYEV, SSYGST, STRMM, STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         LWKMIN = MAX( 1, 3*N - 1 )
+         NB = ILAENV( 1, 'SSYTRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( LWKMIN, ( NB + 2 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -11
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSYGV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form a Cholesky factorization of B.
+*
+      CALL SPOTRF( UPLO, N, B, LDB, INFO )
+      IF( INFO.NE.0 ) THEN
+         INFO = N + INFO
+         RETURN
+      END IF
+*
+*     Transform problem to standard eigenvalue problem and solve.
+*
+      CALL SSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      CALL SSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
+*
+      IF( WANTZ ) THEN
+*
+*        Backtransform eigenvectors to the original problem.
+*
+         NEIG = N
+         IF( INFO.GT.0 )
+     $      NEIG = INFO - 1
+         IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
+*
+*           For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
+*           backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'N'
+            ELSE
+               TRANS = 'T'
+            END IF
+*
+            CALL STRSM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+*
+         ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*           For B*A*x=(lambda)*x;
+*           backtransform eigenvectors: x = L*y or U'*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'T'
+            ELSE
+               TRANS = 'N'
+            END IF
+*
+            CALL STRMM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+         END IF
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SSYGV
+*
+      END
diff --git a/libcruft/lapack/ssytd2.f b/libcruft/lapack/ssytd2.f
new file mode 100644
index 0000000..697b2ba
--- /dev/null
+++ b/libcruft/lapack/ssytd2.f
@@ -0,0 +1,247 @@
+      SUBROUTINE SSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), D( * ), E( * ), TAU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal
+*  form T by an orthogonal similarity transformation: Q' * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          symmetric matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the orthogonal
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the orthogonal matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) REAL array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) REAL array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO, HALF
+      PARAMETER          ( ONE = 1.0, ZERO = 0.0, HALF = 1.0 / 2.0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      REAL               ALPHA, TAUI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SLARFG, SSYMV, SSYR2, XERBLA
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SDOT
+      EXTERNAL           LSAME, SDOT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSYTD2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A
+*
+         DO 10 I = N - 1, 1, -1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(1:i-1,i+1)
+*
+            CALL SLARFG( I, A( I, I+1 ), A( 1, I+1 ), 1, TAUI )
+            E( I ) = A( I, I+1 )
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(1:i,1:i)
+*
+               A( I, I+1 ) = ONE
+*
+*              Compute  x := tau * A * v  storing x in TAU(1:i)
+*
+               CALL SSYMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO,
+     $                     TAU, 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*SDOT( I, TAU, 1, A( 1, I+1 ), 1 )
+               CALL SAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL SSYR2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A,
+     $                     LDA )
+*
+               A( I, I+1 ) = E( I )
+            END IF
+            D( I+1 ) = A( I+1, I+1 )
+            TAU( I ) = TAUI
+   10    CONTINUE
+         D( 1 ) = A( 1, 1 )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         DO 20 I = 1, N - 1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(i+2:n,i)
+*
+            CALL SLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,
+     $                   TAUI )
+            E( I ) = A( I+1, I )
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(i+1:n,i+1:n)
+*
+               A( I+1, I ) = ONE
+*
+*              Compute  x := tau * A * v  storing y in TAU(i:n-1)
+*
+               CALL SSYMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, TAU( I ), 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*SDOT( N-I, TAU( I ), 1, A( I+1, I ),
+     $                 1 )
+               CALL SAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL SSYR2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1,
+     $                     A( I+1, I+1 ), LDA )
+*
+               A( I+1, I ) = E( I )
+            END IF
+            D( I ) = A( I, I )
+            TAU( I ) = TAUI
+   20    CONTINUE
+         D( N ) = A( N, N )
+      END IF
+*
+      RETURN
+*
+*     End of SSYTD2
+*
+      END
diff --git a/libcruft/lapack/ssytrd.f b/libcruft/lapack/ssytrd.f
new file mode 100644
index 0000000..57a2523
--- /dev/null
+++ b/libcruft/lapack/ssytrd.f
@@ -0,0 +1,294 @@
+      SUBROUTINE SSYTRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), D( * ), E( * ), TAU( * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  SSYTRD reduces a real symmetric matrix A to real symmetric
+*  tridiagonal form T by an orthogonal similarity transformation:
+*  Q**T * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the orthogonal
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the orthogonal matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) REAL array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) REAL array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) REAL array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= 1.
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real scalar, and v is a real vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLATRD, SSYR2K, SSYTD2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.
+*
+         NB = ILAENV( 1, 'SSYTRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = N*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'SSYTRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NX = N
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code).
+*
+         NX = MAX( NB, ILAENV( 3, 'SSYTRD', UPLO, N, -1, -1, -1 ) )
+         IF( NX.LT.N ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code by setting NX = N.
+*
+               NB = MAX( LWORK / LDWORK, 1 )
+               NBMIN = ILAENV( 2, 'SSYTRD', UPLO, N, -1, -1, -1 )
+               IF( NB.LT.NBMIN )
+     $            NX = N
+            END IF
+         ELSE
+            NX = N
+         END IF
+      ELSE
+         NB = 1
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A.
+*        Columns 1:kk are handled by the unblocked method.
+*
+         KK = N - ( ( N-NX+NB-1 ) / NB )*NB
+         DO 20 I = N - NB + 1, KK + 1, -NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL SLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK,
+     $                   LDWORK )
+*
+*           Update the unreduced submatrix A(1:i-1,1:i-1), using an
+*           update of the form:  A := A - V*W' - W*V'
+*
+            CALL SSYR2K( UPLO, 'No transpose', I-1, NB, -ONE, A( 1, I ),
+     $                   LDA, WORK, LDWORK, ONE, A, LDA )
+*
+*           Copy superdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 10 J = I, I + NB - 1
+               A( J-1, J ) = E( J-1 )
+               D( J ) = A( J, J )
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL SSYTD2( UPLO, KK, A, LDA, D, E, TAU, IINFO )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         DO 40 I = 1, N - NX, NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL SLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ),
+     $                   TAU( I ), WORK, LDWORK )
+*
+*           Update the unreduced submatrix A(i+ib:n,i+ib:n), using
+*           an update of the form:  A := A - V*W' - W*V'
+*
+            CALL SSYR2K( UPLO, 'No transpose', N-I-NB+1, NB, -ONE,
+     $                   A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE,
+     $                   A( I+NB, I+NB ), LDA )
+*
+*           Copy subdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 30 J = I, I + NB - 1
+               A( J+1, J ) = E( J )
+               D( J ) = A( J, J )
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL SSYTD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $                TAU( I ), IINFO )
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of SSYTRD
+*
+      END
diff --git a/libcruft/lapack/stgevc.f b/libcruft/lapack/stgevc.f
new file mode 100644
index 0000000..3045c12
--- /dev/null
+++ b/libcruft/lapack/stgevc.f
@@ -0,0 +1,1147 @@
+      SUBROUTINE STGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
+     $                   LDVL, VR, LDVR, MM, M, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDP, LDS, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      REAL               P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
+     $                   VR( LDVR, * ), WORK( * )
+*     ..
+*
+*
+*  Purpose
+*  =======
+*
+*  STGEVC computes some or all of the right and/or left eigenvectors of
+*  a pair of real matrices (S,P), where S is a quasi-triangular matrix
+*  and P is upper triangular.  Matrix pairs of this type are produced by
+*  the generalized Schur factorization of a matrix pair (A,B):
+*
+*     A = Q*S*Z**T,  B = Q*P*Z**T
+*
+*  as computed by SGGHRD + SHGEQZ.
+*
+*  The right eigenvector x and the left eigenvector y of (S,P)
+*  corresponding to an eigenvalue w are defined by:
+*  
+*     S*x = w*P*x,  (y**H)*S = w*(y**H)*P,
+*  
+*  where y**H denotes the conjugate tranpose of y.
+*  The eigenvalues are not input to this routine, but are computed
+*  directly from the diagonal blocks of S and P.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of (S,P), or the products Z*X and/or Q*Y,
+*  where Z and Q are input matrices.
+*  If Q and Z are the orthogonal factors from the generalized Schur
+*  factorization of a matrix pair (A,B), then Z*X and Q*Y
+*  are the matrices of right and left eigenvectors of (A,B).
+* 
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R': compute right eigenvectors only;
+*          = 'L': compute left eigenvectors only;
+*          = 'B': compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A': compute all right and/or left eigenvectors;
+*          = 'B': compute all right and/or left eigenvectors,
+*                 backtransformed by the matrices in VR and/or VL;
+*          = 'S': compute selected right and/or left eigenvectors,
+*                 specified by the logical array SELECT.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          If HOWMNY='S', SELECT specifies the eigenvectors to be
+*          computed.  If w(j) is a real eigenvalue, the corresponding
+*          real eigenvector is computed if SELECT(j) is .TRUE..
+*          If w(j) and w(j+1) are the real and imaginary parts of a
+*          complex eigenvalue, the corresponding complex eigenvector
+*          is computed if either SELECT(j) or SELECT(j+1) is .TRUE.,
+*          and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is
+*          set to .FALSE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrices S and P.  N >= 0.
+*
+*  S       (input) REAL array, dimension (LDS,N)
+*          The upper quasi-triangular matrix S from a generalized Schur
+*          factorization, as computed by SHGEQZ.
+*
+*  LDS     (input) INTEGER
+*          The leading dimension of array S.  LDS >= max(1,N).
+*
+*  P       (input) REAL array, dimension (LDP,N)
+*          The upper triangular matrix P from a generalized Schur
+*          factorization, as computed by SHGEQZ.
+*          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks
+*          of S must be in positive diagonal form.
+*
+*  LDP     (input) INTEGER
+*          The leading dimension of array P.  LDP >= max(1,N).
+*
+*  VL      (input/output) REAL array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*          of left Schur vectors returned by SHGEQZ).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
+*                      SELECT, stored consecutively in the columns of
+*                      VL, in the same order as their eigenvalues.
+*
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part, and the second the imaginary part.
+*
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'B', LDVL >= N.
+*
+*  VR      (input/output) REAL array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Z (usually the orthogonal matrix Z
+*          of right Schur vectors returned by SHGEQZ).
+*
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
+*          if HOWMNY = 'B' or 'b', the matrix Z*X;
+*          if HOWMNY = 'S' or 's', the right eigenvectors of (S,P)
+*                      specified by SELECT, stored consecutively in the
+*                      columns of VR, in the same order as their
+*                      eigenvalues.
+*
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part and the second the imaginary part.
+*          
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B', LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
+*          is set to N.  Each selected real eigenvector occupies one
+*          column and each selected complex eigenvector occupies two
+*          columns.
+*
+*  WORK    (workspace) REAL array, dimension (6*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the 2-by-2 block (INFO:INFO+1) does not have a complex
+*                eigenvalue.
+*
+*  Further Details
+*  ===============
+*
+*  Allocation of workspace:
+*  ---------- -- ---------
+*
+*     WORK( j ) = 1-norm of j-th column of A, above the diagonal
+*     WORK( N+j ) = 1-norm of j-th column of B, above the diagonal
+*     WORK( 2*N+1:3*N ) = real part of eigenvector
+*     WORK( 3*N+1:4*N ) = imaginary part of eigenvector
+*     WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector
+*     WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector
+*
+*  Rowwise vs. columnwise solution methods:
+*  ------- --  ---------- -------- -------
+*
+*  Finding a generalized eigenvector consists basically of solving the
+*  singular triangular system
+*
+*   (A - w B) x = 0     (for right) or:   (A - w B)**H y = 0  (for left)
+*
+*  Consider finding the i-th right eigenvector (assume all eigenvalues
+*  are real). The equation to be solved is:
+*       n                   i
+*  0 = sum  C(j,k) v(k)  = sum  C(j,k) v(k)     for j = i,. . .,1
+*      k=j                 k=j
+*
+*  where  C = (A - w B)  (The components v(i+1:n) are 0.)
+*
+*  The "rowwise" method is:
+*
+*  (1)  v(i) := 1
+*  for j = i-1,. . .,1:
+*                          i
+*      (2) compute  s = - sum C(j,k) v(k)   and
+*                        k=j+1
+*
+*      (3) v(j) := s / C(j,j)
+*
+*  Step 2 is sometimes called the "dot product" step, since it is an
+*  inner product between the j-th row and the portion of the eigenvector
+*  that has been computed so far.
+*
+*  The "columnwise" method consists basically in doing the sums
+*  for all the rows in parallel.  As each v(j) is computed, the
+*  contribution of v(j) times the j-th column of C is added to the
+*  partial sums.  Since FORTRAN arrays are stored columnwise, this has
+*  the advantage that at each step, the elements of C that are accessed
+*  are adjacent to one another, whereas with the rowwise method, the
+*  elements accessed at a step are spaced LDS (and LDP) words apart.
+*
+*  When finding left eigenvectors, the matrix in question is the
+*  transpose of the one in storage, so the rowwise method then
+*  actually accesses columns of A and B at each step, and so is the
+*  preferred method.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE, SAFETY
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0,
+     $                   SAFETY = 1.0E+2 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            COMPL, COMPR, IL2BY2, ILABAD, ILALL, ILBACK,
+     $                   ILBBAD, ILCOMP, ILCPLX, LSA, LSB
+      INTEGER            I, IBEG, IEIG, IEND, IHWMNY, IINFO, IM, ISIDE,
+     $                   J, JA, JC, JE, JR, JW, NA, NW
+      REAL               ACOEF, ACOEFA, ANORM, ASCALE, BCOEFA, BCOEFI,
+     $                   BCOEFR, BIG, BIGNUM, BNORM, BSCALE, CIM2A,
+     $                   CIM2B, CIMAGA, CIMAGB, CRE2A, CRE2B, CREALA,
+     $                   CREALB, DMIN, SAFMIN, SALFAR, SBETA, SCALE,
+     $                   SMALL, TEMP, TEMP2, TEMP2I, TEMP2R, ULP, XMAX,
+     $                   XSCALE
+*     ..
+*     .. Local Arrays ..
+      REAL               BDIAG( 2 ), SUM( 2, 2 ), SUMS( 2, 2 ),
+     $                   SUMP( 2, 2 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLAMCH
+      EXTERNAL           LSAME, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SGEMV, SLABAD, SLACPY, SLAG2, SLALN2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      IF( LSAME( HOWMNY, 'A' ) ) THEN
+         IHWMNY = 1
+         ILALL = .TRUE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
+         IHWMNY = 2
+         ILALL = .FALSE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
+         IHWMNY = 3
+         ILALL = .TRUE.
+         ILBACK = .TRUE.
+      ELSE
+         IHWMNY = -1
+         ILALL = .TRUE.
+      END IF
+*
+      IF( LSAME( SIDE, 'R' ) ) THEN
+         ISIDE = 1
+         COMPL = .FALSE.
+         COMPR = .TRUE.
+      ELSE IF( LSAME( SIDE, 'L' ) ) THEN
+         ISIDE = 2
+         COMPL = .TRUE.
+         COMPR = .FALSE.
+      ELSE IF( LSAME( SIDE, 'B' ) ) THEN
+         ISIDE = 3
+         COMPL = .TRUE.
+         COMPR = .TRUE.
+      ELSE
+         ISIDE = -1
+      END IF
+*
+      INFO = 0
+      IF( ISIDE.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( IHWMNY.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Count the number of eigenvectors to be computed
+*
+      IF( .NOT.ILALL ) THEN
+         IM = 0
+         ILCPLX = .FALSE.
+         DO 10 J = 1, N
+            IF( ILCPLX ) THEN
+               ILCPLX = .FALSE.
+               GO TO 10
+            END IF
+            IF( J.LT.N ) THEN
+               IF( S( J+1, J ).NE.ZERO )
+     $            ILCPLX = .TRUE.
+            END IF
+            IF( ILCPLX ) THEN
+               IF( SELECT( J ) .OR. SELECT( J+1 ) )
+     $            IM = IM + 2
+            ELSE
+               IF( SELECT( J ) )
+     $            IM = IM + 1
+            END IF
+   10    CONTINUE
+      ELSE
+         IM = N
+      END IF
+*
+*     Check 2-by-2 diagonal blocks of A, B
+*
+      ILABAD = .FALSE.
+      ILBBAD = .FALSE.
+      DO 20 J = 1, N - 1
+         IF( S( J+1, J ).NE.ZERO ) THEN
+            IF( P( J, J ).EQ.ZERO .OR. P( J+1, J+1 ).EQ.ZERO .OR.
+     $          P( J, J+1 ).NE.ZERO )ILBBAD = .TRUE.
+            IF( J.LT.N-1 ) THEN
+               IF( S( J+2, J+1 ).NE.ZERO )
+     $            ILABAD = .TRUE.
+            END IF
+         END IF
+   20 CONTINUE
+*
+      IF( ILABAD ) THEN
+         INFO = -5
+      ELSE IF( ILBBAD ) THEN
+         INFO = -7
+      ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
+         INFO = -10
+      ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
+         INFO = -12
+      ELSE IF( MM.LT.IM ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      M = IM
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Machine Constants
+*
+      SAFMIN = SLAMCH( 'Safe minimum' )
+      BIG = ONE / SAFMIN
+      CALL SLABAD( SAFMIN, BIG )
+      ULP = SLAMCH( 'Epsilon' )*SLAMCH( 'Base' )
+      SMALL = SAFMIN*N / ULP
+      BIG = ONE / SMALL
+      BIGNUM = ONE / ( SAFMIN*N )
+*
+*     Compute the 1-norm of each column of the strictly upper triangular
+*     part (i.e., excluding all elements belonging to the diagonal
+*     blocks) of A and B to check for possible overflow in the
+*     triangular solver.
+*
+      ANORM = ABS( S( 1, 1 ) )
+      IF( N.GT.1 )
+     $   ANORM = ANORM + ABS( S( 2, 1 ) )
+      BNORM = ABS( P( 1, 1 ) )
+      WORK( 1 ) = ZERO
+      WORK( N+1 ) = ZERO
+*
+      DO 50 J = 2, N
+         TEMP = ZERO
+         TEMP2 = ZERO
+         IF( S( J, J-1 ).EQ.ZERO ) THEN
+            IEND = J - 1
+         ELSE
+            IEND = J - 2
+         END IF
+         DO 30 I = 1, IEND
+            TEMP = TEMP + ABS( S( I, J ) )
+            TEMP2 = TEMP2 + ABS( P( I, J ) )
+   30    CONTINUE
+         WORK( J ) = TEMP
+         WORK( N+J ) = TEMP2
+         DO 40 I = IEND + 1, MIN( J+1, N )
+            TEMP = TEMP + ABS( S( I, J ) )
+            TEMP2 = TEMP2 + ABS( P( I, J ) )
+   40    CONTINUE
+         ANORM = MAX( ANORM, TEMP )
+         BNORM = MAX( BNORM, TEMP2 )
+   50 CONTINUE
+*
+      ASCALE = ONE / MAX( ANORM, SAFMIN )
+      BSCALE = ONE / MAX( BNORM, SAFMIN )
+*
+*     Left eigenvectors
+*
+      IF( COMPL ) THEN
+         IEIG = 0
+*
+*        Main loop over eigenvalues
+*
+         ILCPLX = .FALSE.
+         DO 220 JE = 1, N
+*
+*           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
+*           (b) this would be the second of a complex pair.
+*           Check for complex eigenvalue, so as to be sure of which
+*           entry(-ies) of SELECT to look at.
+*
+            IF( ILCPLX ) THEN
+               ILCPLX = .FALSE.
+               GO TO 220
+            END IF
+            NW = 1
+            IF( JE.LT.N ) THEN
+               IF( S( JE+1, JE ).NE.ZERO ) THEN
+                  ILCPLX = .TRUE.
+                  NW = 2
+               END IF
+            END IF
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE IF( ILCPLX ) THEN
+               ILCOMP = SELECT( JE ) .OR. SELECT( JE+1 )
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( .NOT.ILCOMP )
+     $         GO TO 220
+*
+*           Decide if (a) singular pencil, (b) real eigenvalue, or
+*           (c) complex eigenvalue.
+*
+            IF( .NOT.ILCPLX ) THEN
+               IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- return unit eigenvector
+*
+                  IEIG = IEIG + 1
+                  DO 60 JR = 1, N
+                     VL( JR, IEIG ) = ZERO
+   60             CONTINUE
+                  VL( IEIG, IEIG ) = ONE
+                  GO TO 220
+               END IF
+            END IF
+*
+*           Clear vector
+*
+            DO 70 JR = 1, NW*N
+               WORK( 2*N+JR ) = ZERO
+   70       CONTINUE
+*                                                 T
+*           Compute coefficients in  ( a A - b B )  y = 0
+*              a  is  ACOEF
+*              b  is  BCOEFR + i*BCOEFI
+*
+            IF( .NOT.ILCPLX ) THEN
+*
+*              Real eigenvalue
+*
+               TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
+     $                ABS( P( JE, JE ) )*BSCALE, SAFMIN )
+               SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*P( JE, JE ) )*BSCALE
+               ACOEF = SBETA*ASCALE
+               BCOEFR = SALFAR*BSCALE
+               BCOEFI = ZERO
+*
+*              Scale to avoid underflow
+*
+               SCALE = ONE
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
+               LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
+     $               SMALL
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),
+     $                    ABS( BCOEFR ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEF = SCALE*ACOEF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFR = BSCALE*( SCALE*SALFAR )
+                  ELSE
+                     BCOEFR = SCALE*BCOEFR
+                  END IF
+               END IF
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR )
+*
+*              First component is 1
+*
+               WORK( 2*N+JE ) = ONE
+               XMAX = ONE
+            ELSE
+*
+*              Complex eigenvalue
+*
+               CALL SLAG2( S( JE, JE ), LDS, P( JE, JE ), LDP,
+     $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
+     $                     BCOEFI )
+               BCOEFI = -BCOEFI
+               IF( BCOEFI.EQ.ZERO ) THEN
+                  INFO = JE
+                  RETURN
+               END IF
+*
+*              Scale to avoid over/underflow
+*
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               SCALE = ONE
+               IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
+     $            SCALE = ( SAFMIN / ULP ) / ACOEFA
+               IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
+     $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
+               IF( SAFMIN*ACOEFA.GT.ASCALE )
+     $            SCALE = ASCALE / ( SAFMIN*ACOEFA )
+               IF( SAFMIN*BCOEFA.GT.BSCALE )
+     $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
+               IF( SCALE.NE.ONE ) THEN
+                  ACOEF = SCALE*ACOEF
+                  ACOEFA = ABS( ACOEF )
+                  BCOEFR = SCALE*BCOEFR
+                  BCOEFI = SCALE*BCOEFI
+                  BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               END IF
+*
+*              Compute first two components of eigenvector
+*
+               TEMP = ACOEF*S( JE+1, JE )
+               TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
+               TEMP2I = -BCOEFI*P( JE, JE )
+               IF( ABS( TEMP ).GT.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
+                  WORK( 2*N+JE ) = ONE
+                  WORK( 3*N+JE ) = ZERO
+                  WORK( 2*N+JE+1 ) = -TEMP2R / TEMP
+                  WORK( 3*N+JE+1 ) = -TEMP2I / TEMP
+               ELSE
+                  WORK( 2*N+JE+1 ) = ONE
+                  WORK( 3*N+JE+1 ) = ZERO
+                  TEMP = ACOEF*S( JE, JE+1 )
+                  WORK( 2*N+JE ) = ( BCOEFR*P( JE+1, JE+1 )-ACOEF*
+     $                             S( JE+1, JE+1 ) ) / TEMP
+                  WORK( 3*N+JE ) = BCOEFI*P( JE+1, JE+1 ) / TEMP
+               END IF
+               XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
+     $                ABS( WORK( 2*N+JE+1 ) )+ABS( WORK( 3*N+JE+1 ) ) )
+            END IF
+*
+            DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*                                           T
+*           Triangular solve of  (a A - b B)  y = 0
+*
+*                                   T
+*           (rowwise in  (a A - b B) , or columnwise in (a A - b B) )
+*
+            IL2BY2 = .FALSE.
+*
+            DO 160 J = JE + NW, N
+               IF( IL2BY2 ) THEN
+                  IL2BY2 = .FALSE.
+                  GO TO 160
+               END IF
+*
+               NA = 1
+               BDIAG( 1 ) = P( J, J )
+               IF( J.LT.N ) THEN
+                  IF( S( J+1, J ).NE.ZERO ) THEN
+                     IL2BY2 = .TRUE.
+                     BDIAG( 2 ) = P( J+1, J+1 )
+                     NA = 2
+                  END IF
+               END IF
+*
+*              Check whether scaling is necessary for dot products
+*
+               XSCALE = ONE / MAX( ONE, XMAX )
+               TEMP = MAX( WORK( J ), WORK( N+J ),
+     $                ACOEFA*WORK( J )+BCOEFA*WORK( N+J ) )
+               IF( IL2BY2 )
+     $            TEMP = MAX( TEMP, WORK( J+1 ), WORK( N+J+1 ),
+     $                   ACOEFA*WORK( J+1 )+BCOEFA*WORK( N+J+1 ) )
+               IF( TEMP.GT.BIGNUM*XSCALE ) THEN
+                  DO 90 JW = 0, NW - 1
+                     DO 80 JR = JE, J - 1
+                        WORK( ( JW+2 )*N+JR ) = XSCALE*
+     $                     WORK( ( JW+2 )*N+JR )
+   80                CONTINUE
+   90             CONTINUE
+                  XMAX = XMAX*XSCALE
+               END IF
+*
+*              Compute dot products
+*
+*                    j-1
+*              SUM = sum  conjg( a*S(k,j) - b*P(k,j) )*x(k)
+*                    k=je
+*
+*              To reduce the op count, this is done as
+*
+*              _        j-1                  _        j-1
+*              a*conjg( sum  S(k,j)*x(k) ) - b*conjg( sum  P(k,j)*x(k) )
+*                       k=je                          k=je
+*
+*              which may cause underflow problems if A or B are close
+*              to underflow.  (E.g., less than SMALL.)
+*
+*
+*              A series of compiler directives to defeat vectorization
+*              for the next loop
+*
+*$PL$ CMCHAR=' '
+CDIR$          NEXTSCALAR
+C$DIR          SCALAR
+CDIR$          NEXT SCALAR
+CVD$L          NOVECTOR
+CDEC$          NOVECTOR
+CVD$           NOVECTOR
+*VDIR          NOVECTOR
+*VOCL          LOOP,SCALAR
+CIBM           PREFER SCALAR
+*$PL$ CMCHAR='*'
+*
+               DO 120 JW = 1, NW
+*
+*$PL$ CMCHAR=' '
+CDIR$             NEXTSCALAR
+C$DIR             SCALAR
+CDIR$             NEXT SCALAR
+CVD$L             NOVECTOR
+CDEC$             NOVECTOR
+CVD$              NOVECTOR
+*VDIR             NOVECTOR
+*VOCL             LOOP,SCALAR
+CIBM              PREFER SCALAR
+*$PL$ CMCHAR='*'
+*
+                  DO 110 JA = 1, NA
+                     SUMS( JA, JW ) = ZERO
+                     SUMP( JA, JW ) = ZERO
+*
+                     DO 100 JR = JE, J - 1
+                        SUMS( JA, JW ) = SUMS( JA, JW ) +
+     $                                   S( JR, J+JA-1 )*
+     $                                   WORK( ( JW+1 )*N+JR )
+                        SUMP( JA, JW ) = SUMP( JA, JW ) +
+     $                                   P( JR, J+JA-1 )*
+     $                                   WORK( ( JW+1 )*N+JR )
+  100                CONTINUE
+  110             CONTINUE
+  120          CONTINUE
+*
+*$PL$ CMCHAR=' '
+CDIR$          NEXTSCALAR
+C$DIR          SCALAR
+CDIR$          NEXT SCALAR
+CVD$L          NOVECTOR
+CDEC$          NOVECTOR
+CVD$           NOVECTOR
+*VDIR          NOVECTOR
+*VOCL          LOOP,SCALAR
+CIBM           PREFER SCALAR
+*$PL$ CMCHAR='*'
+*
+               DO 130 JA = 1, NA
+                  IF( ILCPLX ) THEN
+                     SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
+     $                              BCOEFR*SUMP( JA, 1 ) -
+     $                              BCOEFI*SUMP( JA, 2 )
+                     SUM( JA, 2 ) = -ACOEF*SUMS( JA, 2 ) +
+     $                              BCOEFR*SUMP( JA, 2 ) +
+     $                              BCOEFI*SUMP( JA, 1 )
+                  ELSE
+                     SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
+     $                              BCOEFR*SUMP( JA, 1 )
+                  END IF
+  130          CONTINUE
+*
+*                                  T
+*              Solve  ( a A - b B )  y = SUM(,)
+*              with scaling and perturbation of the denominator
+*
+               CALL SLALN2( .TRUE., NA, NW, DMIN, ACOEF, S( J, J ), LDS,
+     $                      BDIAG( 1 ), BDIAG( 2 ), SUM, 2, BCOEFR,
+     $                      BCOEFI, WORK( 2*N+J ), N, SCALE, TEMP,
+     $                      IINFO )
+               IF( SCALE.LT.ONE ) THEN
+                  DO 150 JW = 0, NW - 1
+                     DO 140 JR = JE, J - 1
+                        WORK( ( JW+2 )*N+JR ) = SCALE*
+     $                     WORK( ( JW+2 )*N+JR )
+  140                CONTINUE
+  150             CONTINUE
+                  XMAX = SCALE*XMAX
+               END IF
+               XMAX = MAX( XMAX, TEMP )
+  160       CONTINUE
+*
+*           Copy eigenvector to VL, back transforming if
+*           HOWMNY='B'.
+*
+            IEIG = IEIG + 1
+            IF( ILBACK ) THEN
+               DO 170 JW = 0, NW - 1
+                  CALL SGEMV( 'N', N, N+1-JE, ONE, VL( 1, JE ), LDVL,
+     $                        WORK( ( JW+2 )*N+JE ), 1, ZERO,
+     $                        WORK( ( JW+4 )*N+1 ), 1 )
+  170          CONTINUE
+               CALL SLACPY( ' ', N, NW, WORK( 4*N+1 ), N, VL( 1, JE ),
+     $                      LDVL )
+               IBEG = 1
+            ELSE
+               CALL SLACPY( ' ', N, NW, WORK( 2*N+1 ), N, VL( 1, IEIG ),
+     $                      LDVL )
+               IBEG = JE
+            END IF
+*
+*           Scale eigenvector
+*
+            XMAX = ZERO
+            IF( ILCPLX ) THEN
+               DO 180 J = IBEG, N
+                  XMAX = MAX( XMAX, ABS( VL( J, IEIG ) )+
+     $                   ABS( VL( J, IEIG+1 ) ) )
+  180          CONTINUE
+            ELSE
+               DO 190 J = IBEG, N
+                  XMAX = MAX( XMAX, ABS( VL( J, IEIG ) ) )
+  190          CONTINUE
+            END IF
+*
+            IF( XMAX.GT.SAFMIN ) THEN
+               XSCALE = ONE / XMAX
+*
+               DO 210 JW = 0, NW - 1
+                  DO 200 JR = IBEG, N
+                     VL( JR, IEIG+JW ) = XSCALE*VL( JR, IEIG+JW )
+  200             CONTINUE
+  210          CONTINUE
+            END IF
+            IEIG = IEIG + NW - 1
+*
+  220    CONTINUE
+      END IF
+*
+*     Right eigenvectors
+*
+      IF( COMPR ) THEN
+         IEIG = IM + 1
+*
+*        Main loop over eigenvalues
+*
+         ILCPLX = .FALSE.
+         DO 500 JE = N, 1, -1
+*
+*           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
+*           (b) this would be the second of a complex pair.
+*           Check for complex eigenvalue, so as to be sure of which
+*           entry(-ies) of SELECT to look at -- if complex, SELECT(JE)
+*           or SELECT(JE-1).
+*           If this is a complex pair, the 2-by-2 diagonal block
+*           corresponding to the eigenvalue is in rows/columns JE-1:JE
+*
+            IF( ILCPLX ) THEN
+               ILCPLX = .FALSE.
+               GO TO 500
+            END IF
+            NW = 1
+            IF( JE.GT.1 ) THEN
+               IF( S( JE, JE-1 ).NE.ZERO ) THEN
+                  ILCPLX = .TRUE.
+                  NW = 2
+               END IF
+            END IF
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE IF( ILCPLX ) THEN
+               ILCOMP = SELECT( JE ) .OR. SELECT( JE-1 )
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( .NOT.ILCOMP )
+     $         GO TO 500
+*
+*           Decide if (a) singular pencil, (b) real eigenvalue, or
+*           (c) complex eigenvalue.
+*
+            IF( .NOT.ILCPLX ) THEN
+               IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- unit eigenvector
+*
+                  IEIG = IEIG - 1
+                  DO 230 JR = 1, N
+                     VR( JR, IEIG ) = ZERO
+  230             CONTINUE
+                  VR( IEIG, IEIG ) = ONE
+                  GO TO 500
+               END IF
+            END IF
+*
+*           Clear vector
+*
+            DO 250 JW = 0, NW - 1
+               DO 240 JR = 1, N
+                  WORK( ( JW+2 )*N+JR ) = ZERO
+  240          CONTINUE
+  250       CONTINUE
+*
+*           Compute coefficients in  ( a A - b B ) x = 0
+*              a  is  ACOEF
+*              b  is  BCOEFR + i*BCOEFI
+*
+            IF( .NOT.ILCPLX ) THEN
+*
+*              Real eigenvalue
+*
+               TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
+     $                ABS( P( JE, JE ) )*BSCALE, SAFMIN )
+               SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*P( JE, JE ) )*BSCALE
+               ACOEF = SBETA*ASCALE
+               BCOEFR = SALFAR*BSCALE
+               BCOEFI = ZERO
+*
+*              Scale to avoid underflow
+*
+               SCALE = ONE
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
+               LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
+     $               SMALL
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),
+     $                    ABS( BCOEFR ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEF = SCALE*ACOEF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFR = BSCALE*( SCALE*SALFAR )
+                  ELSE
+                     BCOEFR = SCALE*BCOEFR
+                  END IF
+               END IF
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR )
+*
+*              First component is 1
+*
+               WORK( 2*N+JE ) = ONE
+               XMAX = ONE
+*
+*              Compute contribution from column JE of A and B to sum
+*              (See "Further Details", above.)
+*
+               DO 260 JR = 1, JE - 1
+                  WORK( 2*N+JR ) = BCOEFR*P( JR, JE ) -
+     $                             ACOEF*S( JR, JE )
+  260          CONTINUE
+            ELSE
+*
+*              Complex eigenvalue
+*
+               CALL SLAG2( S( JE-1, JE-1 ), LDS, P( JE-1, JE-1 ), LDP,
+     $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
+     $                     BCOEFI )
+               IF( BCOEFI.EQ.ZERO ) THEN
+                  INFO = JE - 1
+                  RETURN
+               END IF
+*
+*              Scale to avoid over/underflow
+*
+               ACOEFA = ABS( ACOEF )
+               BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               SCALE = ONE
+               IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
+     $            SCALE = ( SAFMIN / ULP ) / ACOEFA
+               IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
+     $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
+               IF( SAFMIN*ACOEFA.GT.ASCALE )
+     $            SCALE = ASCALE / ( SAFMIN*ACOEFA )
+               IF( SAFMIN*BCOEFA.GT.BSCALE )
+     $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
+               IF( SCALE.NE.ONE ) THEN
+                  ACOEF = SCALE*ACOEF
+                  ACOEFA = ABS( ACOEF )
+                  BCOEFR = SCALE*BCOEFR
+                  BCOEFI = SCALE*BCOEFI
+                  BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
+               END IF
+*
+*              Compute first two components of eigenvector
+*              and contribution to sums
+*
+               TEMP = ACOEF*S( JE, JE-1 )
+               TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
+               TEMP2I = -BCOEFI*P( JE, JE )
+               IF( ABS( TEMP ).GE.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
+                  WORK( 2*N+JE ) = ONE
+                  WORK( 3*N+JE ) = ZERO
+                  WORK( 2*N+JE-1 ) = -TEMP2R / TEMP
+                  WORK( 3*N+JE-1 ) = -TEMP2I / TEMP
+               ELSE
+                  WORK( 2*N+JE-1 ) = ONE
+                  WORK( 3*N+JE-1 ) = ZERO
+                  TEMP = ACOEF*S( JE-1, JE )
+                  WORK( 2*N+JE ) = ( BCOEFR*P( JE-1, JE-1 )-ACOEF*
+     $                             S( JE-1, JE-1 ) ) / TEMP
+                  WORK( 3*N+JE ) = BCOEFI*P( JE-1, JE-1 ) / TEMP
+               END IF
+*
+               XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
+     $                ABS( WORK( 2*N+JE-1 ) )+ABS( WORK( 3*N+JE-1 ) ) )
+*
+*              Compute contribution from columns JE and JE-1
+*              of A and B to the sums.
+*
+               CREALA = ACOEF*WORK( 2*N+JE-1 )
+               CIMAGA = ACOEF*WORK( 3*N+JE-1 )
+               CREALB = BCOEFR*WORK( 2*N+JE-1 ) -
+     $                  BCOEFI*WORK( 3*N+JE-1 )
+               CIMAGB = BCOEFI*WORK( 2*N+JE-1 ) +
+     $                  BCOEFR*WORK( 3*N+JE-1 )
+               CRE2A = ACOEF*WORK( 2*N+JE )
+               CIM2A = ACOEF*WORK( 3*N+JE )
+               CRE2B = BCOEFR*WORK( 2*N+JE ) - BCOEFI*WORK( 3*N+JE )
+               CIM2B = BCOEFI*WORK( 2*N+JE ) + BCOEFR*WORK( 3*N+JE )
+               DO 270 JR = 1, JE - 2
+                  WORK( 2*N+JR ) = -CREALA*S( JR, JE-1 ) +
+     $                             CREALB*P( JR, JE-1 ) -
+     $                             CRE2A*S( JR, JE ) + CRE2B*P( JR, JE )
+                  WORK( 3*N+JR ) = -CIMAGA*S( JR, JE-1 ) +
+     $                             CIMAGB*P( JR, JE-1 ) -
+     $                             CIM2A*S( JR, JE ) + CIM2B*P( JR, JE )
+  270          CONTINUE
+            END IF
+*
+            DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*           Columnwise triangular solve of  (a A - b B)  x = 0
+*
+            IL2BY2 = .FALSE.
+            DO 370 J = JE - NW, 1, -1
+*
+*              If a 2-by-2 block, is in position j-1:j, wait until
+*              next iteration to process it (when it will be j:j+1)
+*
+               IF( .NOT.IL2BY2 .AND. J.GT.1 ) THEN
+                  IF( S( J, J-1 ).NE.ZERO ) THEN
+                     IL2BY2 = .TRUE.
+                     GO TO 370
+                  END IF
+               END IF
+               BDIAG( 1 ) = P( J, J )
+               IF( IL2BY2 ) THEN
+                  NA = 2
+                  BDIAG( 2 ) = P( J+1, J+1 )
+               ELSE
+                  NA = 1
+               END IF
+*
+*              Compute x(j) (and x(j+1), if 2-by-2 block)
+*
+               CALL SLALN2( .FALSE., NA, NW, DMIN, ACOEF, S( J, J ),
+     $                      LDS, BDIAG( 1 ), BDIAG( 2 ), WORK( 2*N+J ),
+     $                      N, BCOEFR, BCOEFI, SUM, 2, SCALE, TEMP,
+     $                      IINFO )
+               IF( SCALE.LT.ONE ) THEN
+*
+                  DO 290 JW = 0, NW - 1
+                     DO 280 JR = 1, JE
+                        WORK( ( JW+2 )*N+JR ) = SCALE*
+     $                     WORK( ( JW+2 )*N+JR )
+  280                CONTINUE
+  290             CONTINUE
+               END IF
+               XMAX = MAX( SCALE*XMAX, TEMP )
+*
+               DO 310 JW = 1, NW
+                  DO 300 JA = 1, NA
+                     WORK( ( JW+1 )*N+J+JA-1 ) = SUM( JA, JW )
+  300             CONTINUE
+  310          CONTINUE
+*
+*              w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
+*
+               IF( J.GT.1 ) THEN
+*
+*                 Check whether scaling is necessary for sum.
+*
+                  XSCALE = ONE / MAX( ONE, XMAX )
+                  TEMP = ACOEFA*WORK( J ) + BCOEFA*WORK( N+J )
+                  IF( IL2BY2 )
+     $               TEMP = MAX( TEMP, ACOEFA*WORK( J+1 )+BCOEFA*
+     $                      WORK( N+J+1 ) )
+                  TEMP = MAX( TEMP, ACOEFA, BCOEFA )
+                  IF( TEMP.GT.BIGNUM*XSCALE ) THEN
+*
+                     DO 330 JW = 0, NW - 1
+                        DO 320 JR = 1, JE
+                           WORK( ( JW+2 )*N+JR ) = XSCALE*
+     $                        WORK( ( JW+2 )*N+JR )
+  320                   CONTINUE
+  330                CONTINUE
+                     XMAX = XMAX*XSCALE
+                  END IF
+*
+*                 Compute the contributions of the off-diagonals of
+*                 column j (and j+1, if 2-by-2 block) of A and B to the
+*                 sums.
+*
+*
+                  DO 360 JA = 1, NA
+                     IF( ILCPLX ) THEN
+                        CREALA = ACOEF*WORK( 2*N+J+JA-1 )
+                        CIMAGA = ACOEF*WORK( 3*N+J+JA-1 )
+                        CREALB = BCOEFR*WORK( 2*N+J+JA-1 ) -
+     $                           BCOEFI*WORK( 3*N+J+JA-1 )
+                        CIMAGB = BCOEFI*WORK( 2*N+J+JA-1 ) +
+     $                           BCOEFR*WORK( 3*N+J+JA-1 )
+                        DO 340 JR = 1, J - 1
+                           WORK( 2*N+JR ) = WORK( 2*N+JR ) -
+     $                                      CREALA*S( JR, J+JA-1 ) +
+     $                                      CREALB*P( JR, J+JA-1 )
+                           WORK( 3*N+JR ) = WORK( 3*N+JR ) -
+     $                                      CIMAGA*S( JR, J+JA-1 ) +
+     $                                      CIMAGB*P( JR, J+JA-1 )
+  340                   CONTINUE
+                     ELSE
+                        CREALA = ACOEF*WORK( 2*N+J+JA-1 )
+                        CREALB = BCOEFR*WORK( 2*N+J+JA-1 )
+                        DO 350 JR = 1, J - 1
+                           WORK( 2*N+JR ) = WORK( 2*N+JR ) -
+     $                                      CREALA*S( JR, J+JA-1 ) +
+     $                                      CREALB*P( JR, J+JA-1 )
+  350                   CONTINUE
+                     END IF
+  360             CONTINUE
+               END IF
+*
+               IL2BY2 = .FALSE.
+  370       CONTINUE
+*
+*           Copy eigenvector to VR, back transforming if
+*           HOWMNY='B'.
+*
+            IEIG = IEIG - NW
+            IF( ILBACK ) THEN
+*
+               DO 410 JW = 0, NW - 1
+                  DO 380 JR = 1, N
+                     WORK( ( JW+4 )*N+JR ) = WORK( ( JW+2 )*N+1 )*
+     $                                       VR( JR, 1 )
+  380             CONTINUE
+*
+*                 A series of compiler directives to defeat
+*                 vectorization for the next loop
+*
+*
+                  DO 400 JC = 2, JE
+                     DO 390 JR = 1, N
+                        WORK( ( JW+4 )*N+JR ) = WORK( ( JW+4 )*N+JR ) +
+     $                     WORK( ( JW+2 )*N+JC )*VR( JR, JC )
+  390                CONTINUE
+  400             CONTINUE
+  410          CONTINUE
+*
+               DO 430 JW = 0, NW - 1
+                  DO 420 JR = 1, N
+                     VR( JR, IEIG+JW ) = WORK( ( JW+4 )*N+JR )
+  420             CONTINUE
+  430          CONTINUE
+*
+               IEND = N
+            ELSE
+               DO 450 JW = 0, NW - 1
+                  DO 440 JR = 1, N
+                     VR( JR, IEIG+JW ) = WORK( ( JW+2 )*N+JR )
+  440             CONTINUE
+  450          CONTINUE
+*
+               IEND = JE
+            END IF
+*
+*           Scale eigenvector
+*
+            XMAX = ZERO
+            IF( ILCPLX ) THEN
+               DO 460 J = 1, IEND
+                  XMAX = MAX( XMAX, ABS( VR( J, IEIG ) )+
+     $                   ABS( VR( J, IEIG+1 ) ) )
+  460          CONTINUE
+            ELSE
+               DO 470 J = 1, IEND
+                  XMAX = MAX( XMAX, ABS( VR( J, IEIG ) ) )
+  470          CONTINUE
+            END IF
+*
+            IF( XMAX.GT.SAFMIN ) THEN
+               XSCALE = ONE / XMAX
+               DO 490 JW = 0, NW - 1
+                  DO 480 JR = 1, IEND
+                     VR( JR, IEIG+JW ) = XSCALE*VR( JR, IEIG+JW )
+  480             CONTINUE
+  490          CONTINUE
+            END IF
+  500    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of STGEVC
+*
+      END
diff --git a/libcruft/lapack/strcon.f b/libcruft/lapack/strcon.f
new file mode 100644
index 0000000..c2b088b
--- /dev/null
+++ b/libcruft/lapack/strcon.f
@@ -0,0 +1,197 @@
+      SUBROUTINE STRCON( NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            INFO, LDA, N
+      REAL               RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      REAL               A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRCON estimates the reciprocal of the condition number of a
+*  triangular matrix A, in either the 1-norm or the infinity-norm.
+*
+*  The norm of A is computed and an estimate is obtained for
+*  norm(inv(A)), then the reciprocal of the condition number is
+*  computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  RCOND   (output) REAL
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) REAL array, dimension (3*N)
+*
+*  IWORK   (workspace) INTEGER array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, ONENRM, UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      REAL               AINVNM, ANORM, SCALE, SMLNUM, XNORM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SLAMCH, SLANTR
+      EXTERNAL           LSAME, ISAMAX, SLAMCH, SLANTR
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACN2, SLATRS, SRSCL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STRCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      END IF
+*
+      RCOND = ZERO
+      SMLNUM = SLAMCH( 'Safe minimum' )*REAL( MAX( 1, N ) )
+*
+*     Compute the norm of the triangular matrix A.
+*
+      ANORM = SLANTR( NORM, UPLO, DIAG, N, N, A, LDA, WORK )
+*
+*     Continue only if ANORM > 0.
+*
+      IF( ANORM.GT.ZERO ) THEN
+*
+*        Estimate the norm of the inverse of A.
+*
+         AINVNM = ZERO
+         NORMIN = 'N'
+         IF( ONENRM ) THEN
+            KASE1 = 1
+         ELSE
+            KASE1 = 2
+         END IF
+         KASE = 0
+   10    CONTINUE
+         CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.KASE1 ) THEN
+*
+*              Multiply by inv(A).
+*
+               CALL SLATRS( UPLO, 'No transpose', DIAG, NORMIN, N, A,
+     $                      LDA, WORK, SCALE, WORK( 2*N+1 ), INFO )
+            ELSE
+*
+*              Multiply by inv(A').
+*
+               CALL SLATRS( UPLO, 'Transpose', DIAG, NORMIN, N, A, LDA,
+     $                      WORK, SCALE, WORK( 2*N+1 ), INFO )
+            END IF
+            NORMIN = 'Y'
+*
+*           Multiply by 1/SCALE if doing so will not cause overflow.
+*
+            IF( SCALE.NE.ONE ) THEN
+               IX = ISAMAX( N, WORK, 1 )
+               XNORM = ABS( WORK( IX ) )
+               IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )
+     $            GO TO 20
+               CALL SRSCL( N, SCALE, WORK, 1 )
+            END IF
+            GO TO 10
+         END IF
+*
+*        Compute the estimate of the reciprocal condition number.
+*
+         IF( AINVNM.NE.ZERO )
+     $      RCOND = ( ONE / ANORM ) / AINVNM
+      END IF
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of STRCON
+*
+      END
diff --git a/libcruft/lapack/strevc.f b/libcruft/lapack/strevc.f
new file mode 100644
index 0000000..77e73cc
--- /dev/null
+++ b/libcruft/lapack/strevc.f
@@ -0,0 +1,981 @@
+      SUBROUTINE STREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
+     $                   LDVR, MM, M, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      REAL               T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STREVC computes some or all of the right and/or left eigenvectors of
+*  a real upper quasi-triangular matrix T.
+*  Matrices of this type are produced by the Schur factorization of
+*  a real general matrix:  A = Q*T*Q**T, as computed by SHSEQR.
+*  
+*  The right eigenvector x and the left eigenvector y of T corresponding
+*  to an eigenvalue w are defined by:
+*  
+*     T*x = w*x,     (y**H)*T = w*(y**H)
+*  
+*  where y**H denotes the conjugate transpose of y.
+*  The eigenvalues are not input to this routine, but are read directly
+*  from the diagonal blocks of T.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*  input matrix.  If Q is the orthogonal factor that reduces a matrix
+*  A to Schur form T, then Q*X and Q*Y are the matrices of right and
+*  left eigenvectors of A.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  compute right eigenvectors only;
+*          = 'L':  compute left eigenvectors only;
+*          = 'B':  compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A':  compute all right and/or left eigenvectors;
+*          = 'B':  compute all right and/or left eigenvectors,
+*                  backtransformed by the matrices in VR and/or VL;
+*          = 'S':  compute selected right and/or left eigenvectors,
+*                  as indicated by the logical array SELECT.
+*
+*  SELECT  (input/output) LOGICAL array, dimension (N)
+*          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*          computed.
+*          If w(j) is a real eigenvalue, the corresponding real
+*          eigenvector is computed if SELECT(j) is .TRUE..
+*          If w(j) and w(j+1) are the real and imaginary parts of a
+*          complex eigenvalue, the corresponding complex eigenvector is
+*          computed if either SELECT(j) or SELECT(j+1) is .TRUE., and
+*          on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to
+*          .FALSE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input) REAL array, dimension (LDT,N)
+*          The upper quasi-triangular matrix T in Schur canonical form.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  VL      (input/output) REAL array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*          of Schur vectors returned by SHSEQR).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VL, in the same order as their
+*                           eigenvalues.
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part, and the second the imaginary part.
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'B', LDVL >= N.
+*
+*  VR      (input/output) REAL array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*          of Schur vectors returned by SHSEQR).
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*X;
+*          if HOWMNY = 'S', the right eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VR, in the same order as their
+*                           eigenvalues.
+*          A complex eigenvector corresponding to a complex eigenvalue
+*          is stored in two consecutive columns, the first holding the
+*          real part and the second the imaginary part.
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B', LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.
+*          If HOWMNY = 'A' or 'B', M is set to N.
+*          Each selected real eigenvector occupies one column and each
+*          selected complex eigenvector occupies two columns.
+*
+*  WORK    (workspace) REAL array, dimension (3*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The algorithm used in this program is basically backward (forward)
+*  substitution, with scaling to make the the code robust against
+*  possible overflow.
+*
+*  Each eigenvector is normalized so that the element of largest
+*  magnitude has magnitude 1; here the magnitude of a complex number
+*  (x,y) is taken to be |x| + |y|.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEV
+      INTEGER            I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2
+      REAL               BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
+     $                   SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,
+     $                   XNORM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX
+      REAL               SDOT, SLAMCH
+      EXTERNAL           LSAME, ISAMAX, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SCOPY, SGEMV, SLABAD, SLALN2, SSCAL,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Local Arrays ..
+      REAL               X( 2, 2 )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV = LSAME( HOWMNY, 'A' )
+      OVER = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+      INFO = 0
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE
+*
+*        Set M to the number of columns required to store the selected
+*        eigenvectors, standardize the array SELECT if necessary, and
+*        test MM.
+*
+         IF( SOMEV ) THEN
+            M = 0
+            PAIR = .FALSE.
+            DO 10 J = 1, N
+               IF( PAIR ) THEN
+                  PAIR = .FALSE.
+                  SELECT( J ) = .FALSE.
+               ELSE
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).EQ.ZERO ) THEN
+                        IF( SELECT( J ) )
+     $                     M = M + 1
+                     ELSE
+                        PAIR = .TRUE.
+                        IF( SELECT( J ) .OR. SELECT( J+1 ) ) THEN
+                           SELECT( J ) = .TRUE.
+                           M = M + 2
+                        END IF
+                     END IF
+                  ELSE
+                     IF( SELECT( N ) )
+     $                  M = M + 1
+                  END IF
+               END IF
+   10       CONTINUE
+         ELSE
+            M = N
+         END IF
+*
+         IF( MM.LT.M ) THEN
+            INFO = -11
+         END IF
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STREVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Set the constants to control overflow.
+*
+      UNFL = SLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL SLABAD( UNFL, OVFL )
+      ULP = SLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+      BIGNUM = ( ONE-ULP ) / SMLNUM
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      WORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         WORK( J ) = ZERO
+         DO 20 I = 1, J - 1
+            WORK( J ) = WORK( J ) + ABS( T( I, J ) )
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Index IP is used to specify the real or complex eigenvalue:
+*       IP = 0, real eigenvalue,
+*            1, first of conjugate complex pair: (wr,wi)
+*           -1, second of conjugate complex pair: (wr,wi)
+*
+      N2 = 2*N
+*
+      IF( RIGHTV ) THEN
+*
+*        Compute right eigenvectors.
+*
+         IP = 0
+         IS = M
+         DO 140 KI = N, 1, -1
+*
+            IF( IP.EQ.1 )
+     $         GO TO 130
+            IF( KI.EQ.1 )
+     $         GO TO 40
+            IF( T( KI, KI-1 ).EQ.ZERO )
+     $         GO TO 40
+            IP = -1
+*
+   40       CONTINUE
+            IF( SOMEV ) THEN
+               IF( IP.EQ.0 ) THEN
+                  IF( .NOT.SELECT( KI ) )
+     $               GO TO 130
+               ELSE
+                  IF( .NOT.SELECT( KI-1 ) )
+     $               GO TO 130
+               END IF
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI-1 ) ) )*
+     $              SQRT( ABS( T( KI-1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              Real right eigenvector
+*
+               WORK( KI+N ) = ONE
+*
+*              Form right-hand side
+*
+               DO 50 K = 1, KI - 1
+                  WORK( K+N ) = -T( K, KI )
+   50          CONTINUE
+*
+*              Solve the upper quasi-triangular system:
+*                 (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.
+*
+               JNXT = KI - 1
+               DO 60 J = KI - 1, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 60
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1 = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL SLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                     WORK( J+N ) = X( 1, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL SAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL SLALN2( .FALSE., 2, 1, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+N ), N, WR, ZERO, X, 2,
+     $                            SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(2,1) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 2, 1 ) = X( 2, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                     WORK( J-1+N ) = X( 1, 1 )
+                     WORK( J+N ) = X( 2, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL SAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL SAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+                  END IF
+   60          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL SCOPY( KI, WORK( 1+N ), 1, VR( 1, IS ), 1 )
+*
+                  II = ISAMAX( KI, VR( 1, IS ), 1 )
+                  REMAX = ONE / ABS( VR( II, IS ) )
+                  CALL SSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+                  DO 70 K = KI + 1, N
+                     VR( K, IS ) = ZERO
+   70             CONTINUE
+               ELSE
+                  IF( KI.GT.1 )
+     $               CALL SGEMV( 'N', N, KI-1, ONE, VR, LDVR,
+     $                           WORK( 1+N ), 1, WORK( KI+N ),
+     $                           VR( 1, KI ), 1 )
+*
+                  II = ISAMAX( N, VR( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VR( II, KI ) )
+                  CALL SSCAL( N, REMAX, VR( 1, KI ), 1 )
+               END IF
+*
+            ELSE
+*
+*              Complex right eigenvector.
+*
+*              Initial solve
+*                [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.
+*                [ (T(KI,KI-1)   T(KI,KI)   )               ]
+*
+               IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THEN
+                  WORK( KI-1+N ) = ONE
+                  WORK( KI+N2 ) = WI / T( KI-1, KI )
+               ELSE
+                  WORK( KI-1+N ) = -WI / T( KI, KI-1 )
+                  WORK( KI+N2 ) = ONE
+               END IF
+               WORK( KI+N ) = ZERO
+               WORK( KI-1+N2 ) = ZERO
+*
+*              Form right-hand side
+*
+               DO 80 K = 1, KI - 2
+                  WORK( K+N ) = -WORK( KI-1+N )*T( K, KI-1 )
+                  WORK( K+N2 ) = -WORK( KI+N2 )*T( K, KI )
+   80          CONTINUE
+*
+*              Solve upper quasi-triangular system:
+*              (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)
+*
+               JNXT = KI - 2
+               DO 90 J = KI - 2, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 90
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1 = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL SLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR, WI,
+     $                            X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(1,2) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 1, 2 ) = X( 1, 2 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                        CALL SSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
+                     END IF
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+N2 ) = X( 1, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL SAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL SAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+N2 ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL SLALN2( .FALSE., 2, 2, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+N ), N, WR, WI, X, 2, SCALE,
+     $                            XNORM, IERR )
+*
+*                    Scale X to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           REC = ONE / XNORM
+                           X( 1, 1 ) = X( 1, 1 )*REC
+                           X( 1, 2 ) = X( 1, 2 )*REC
+                           X( 2, 1 ) = X( 2, 1 )*REC
+                           X( 2, 2 ) = X( 2, 2 )*REC
+                           SCALE = SCALE*REC
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( KI, SCALE, WORK( 1+N ), 1 )
+                        CALL SSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
+                     END IF
+                     WORK( J-1+N ) = X( 1, 1 )
+                     WORK( J+N ) = X( 2, 1 )
+                     WORK( J-1+N2 ) = X( 1, 2 )
+                     WORK( J+N2 ) = X( 2, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL SAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL SAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+N ), 1 )
+                     CALL SAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+N2 ), 1 )
+                     CALL SAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+N2 ), 1 )
+                  END IF
+   90          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL SCOPY( KI, WORK( 1+N ), 1, VR( 1, IS-1 ), 1 )
+                  CALL SCOPY( KI, WORK( 1+N2 ), 1, VR( 1, IS ), 1 )
+*
+                  EMAX = ZERO
+                  DO 100 K = 1, KI
+                     EMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+
+     $                      ABS( VR( K, IS ) ) )
+  100             CONTINUE
+*
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )
+                  CALL SSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+                  DO 110 K = KI + 1, N
+                     VR( K, IS-1 ) = ZERO
+                     VR( K, IS ) = ZERO
+  110             CONTINUE
+*
+               ELSE
+*
+                  IF( KI.GT.2 ) THEN
+                     CALL SGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1+N ), 1, WORK( KI-1+N ),
+     $                           VR( 1, KI-1 ), 1 )
+                     CALL SGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1+N2 ), 1, WORK( KI+N2 ),
+     $                           VR( 1, KI ), 1 )
+                  ELSE
+                     CALL SSCAL( N, WORK( KI-1+N ), VR( 1, KI-1 ), 1 )
+                     CALL SSCAL( N, WORK( KI+N2 ), VR( 1, KI ), 1 )
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 120 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+
+     $                      ABS( VR( K, KI ) ) )
+  120             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( N, REMAX, VR( 1, KI-1 ), 1 )
+                  CALL SSCAL( N, REMAX, VR( 1, KI ), 1 )
+               END IF
+            END IF
+*
+            IS = IS - 1
+            IF( IP.NE.0 )
+     $         IS = IS - 1
+  130       CONTINUE
+            IF( IP.EQ.1 )
+     $         IP = 0
+            IF( IP.EQ.-1 )
+     $         IP = 1
+  140    CONTINUE
+      END IF
+*
+      IF( LEFTV ) THEN
+*
+*        Compute left eigenvectors.
+*
+         IP = 0
+         IS = 1
+         DO 260 KI = 1, N
+*
+            IF( IP.EQ.-1 )
+     $         GO TO 250
+            IF( KI.EQ.N )
+     $         GO TO 150
+            IF( T( KI+1, KI ).EQ.ZERO )
+     $         GO TO 150
+            IP = 1
+*
+  150       CONTINUE
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 250
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI+1 ) ) )*
+     $              SQRT( ABS( T( KI+1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              Real left eigenvector.
+*
+               WORK( KI+N ) = ONE
+*
+*              Form right-hand side
+*
+               DO 160 K = KI + 1, N
+                  WORK( K+N ) = -T( KI, K )
+  160          CONTINUE
+*
+*              Solve the quasi-triangular system:
+*                 (T(KI+1:N,KI+1:N) - WR)'*X = SCALE*WORK
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 1
+               DO 170 J = KI + 1, N
+                  IF( J.LT.JNXT )
+     $               GO TO 170
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             SDOT( J-KI-1, T( KI+1, J ), 1,
+     $                             WORK( KI+1+N ), 1 )
+*
+*                    Solve (T(J,J)-WR)'*X = WORK
+*
+                     CALL SLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                     WORK( J+N ) = X( 1, 1 )
+                     VMAX = MAX( ABS( WORK( J+N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             SDOT( J-KI-1, T( KI+1, J ), 1,
+     $                             WORK( KI+1+N ), 1 )
+*
+                     WORK( J+1+N ) = WORK( J+1+N ) -
+     $                               SDOT( J-KI-1, T( KI+1, J+1 ), 1,
+     $                               WORK( KI+1+N ), 1 )
+*
+*                    Solve
+*                      [T(J,J)-WR   T(J,J+1)     ]'* X = SCALE*( WORK1 )
+*                      [T(J+1,J)    T(J+1,J+1)-WR]             ( WORK2 )
+*
+                     CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+1+N ) = X( 2, 1 )
+*
+                     VMAX = MAX( ABS( WORK( J+N ) ),
+     $                      ABS( WORK( J+1+N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  170          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL SCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
+*
+                  II = ISAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+                  REMAX = ONE / ABS( VL( II, IS ) )
+                  CALL SSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+                  DO 180 K = 1, KI - 1
+                     VL( K, IS ) = ZERO
+  180             CONTINUE
+*
+               ELSE
+*
+                  IF( KI.LT.N )
+     $               CALL SGEMV( 'N', N, N-KI, ONE, VL( 1, KI+1 ), LDVL,
+     $                           WORK( KI+1+N ), 1, WORK( KI+N ),
+     $                           VL( 1, KI ), 1 )
+*
+                  II = ISAMAX( N, VL( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VL( II, KI ) )
+                  CALL SSCAL( N, REMAX, VL( 1, KI ), 1 )
+*
+               END IF
+*
+            ELSE
+*
+*              Complex left eigenvector.
+*
+*               Initial solve:
+*                 ((T(KI,KI)    T(KI,KI+1) )' - (WR - I* WI))*X = 0.
+*                 ((T(KI+1,KI) T(KI+1,KI+1))                )
+*
+               IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THEN
+                  WORK( KI+N ) = WI / T( KI, KI+1 )
+                  WORK( KI+1+N2 ) = ONE
+               ELSE
+                  WORK( KI+N ) = ONE
+                  WORK( KI+1+N2 ) = -WI / T( KI+1, KI )
+               END IF
+               WORK( KI+1+N ) = ZERO
+               WORK( KI+N2 ) = ZERO
+*
+*              Form right-hand side
+*
+               DO 190 K = KI + 2, N
+                  WORK( K+N ) = -WORK( KI+N )*T( KI, K )
+                  WORK( K+N2 ) = -WORK( KI+1+N2 )*T( KI+1, K )
+  190          CONTINUE
+*
+*              Solve complex quasi-triangular system:
+*              ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 2
+               DO 200 J = KI + 2, N
+                  IF( J.LT.JNXT )
+     $               GO TO 200
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when
+*                    forming the right-hand side elements.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                             WORK( KI+2+N ), 1 )
+                     WORK( J+N2 ) = WORK( J+N2 ) -
+     $                              SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                              WORK( KI+2+N2 ), 1 )
+*
+*                    Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2
+*
+                     CALL SLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                        CALL SSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )
+                     END IF
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+N2 ) = X( 1, 2 )
+                     VMAX = MAX( ABS( WORK( J+N ) ),
+     $                      ABS( WORK( J+N2 ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side elements.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+N ) = WORK( J+N ) -
+     $                             SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                             WORK( KI+2+N ), 1 )
+*
+                     WORK( J+N2 ) = WORK( J+N2 ) -
+     $                              SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                              WORK( KI+2+N2 ), 1 )
+*
+                     WORK( J+1+N ) = WORK( J+1+N ) -
+     $                               SDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                               WORK( KI+2+N ), 1 )
+*
+                     WORK( J+1+N2 ) = WORK( J+1+N2 ) -
+     $                                SDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                                WORK( KI+2+N2 ), 1 )
+*
+*                    Solve 2-by-2 complex linear equation
+*                      ([T(j,j)   T(j,j+1)  ]'-(wr-i*wi)*I)*X = SCALE*B
+*                      ([T(j+1,j) T(j+1,j+1)]             )
+*
+                     CALL SLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )
+                        CALL SSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )
+                     END IF
+                     WORK( J+N ) = X( 1, 1 )
+                     WORK( J+N2 ) = X( 1, 2 )
+                     WORK( J+1+N ) = X( 2, 1 )
+                     WORK( J+1+N2 ) = X( 2, 2 )
+                     VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),
+     $                      ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  200          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+                  CALL SCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
+                  CALL SCOPY( N-KI+1, WORK( KI+N2 ), 1, VL( KI, IS+1 ),
+     $                        1 )
+*
+                  EMAX = ZERO
+                  DO 220 K = KI, N
+                     EMAX = MAX( EMAX, ABS( VL( K, IS ) )+
+     $                      ABS( VL( K, IS+1 ) ) )
+  220             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+                  CALL SSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )
+*
+                  DO 230 K = 1, KI - 1
+                     VL( K, IS ) = ZERO
+                     VL( K, IS+1 ) = ZERO
+  230             CONTINUE
+               ELSE
+                  IF( KI.LT.N-1 ) THEN
+                     CALL SGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),
+     $                           LDVL, WORK( KI+2+N ), 1, WORK( KI+N ),
+     $                           VL( 1, KI ), 1 )
+                     CALL SGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),
+     $                           LDVL, WORK( KI+2+N2 ), 1,
+     $                           WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
+                  ELSE
+                     CALL SSCAL( N, WORK( KI+N ), VL( 1, KI ), 1 )
+                     CALL SSCAL( N, WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 240 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VL( K, KI ) )+
+     $                      ABS( VL( K, KI+1 ) ) )
+  240             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( N, REMAX, VL( 1, KI ), 1 )
+                  CALL SSCAL( N, REMAX, VL( 1, KI+1 ), 1 )
+*
+               END IF
+*
+            END IF
+*
+            IS = IS + 1
+            IF( IP.NE.0 )
+     $         IS = IS + 1
+  250       CONTINUE
+            IF( IP.EQ.-1 )
+     $         IP = 0
+            IF( IP.EQ.1 )
+     $         IP = -1
+*
+  260    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of STREVC
+*
+      END
diff --git a/libcruft/lapack/strexc.f b/libcruft/lapack/strexc.f
new file mode 100644
index 0000000..7db8820
--- /dev/null
+++ b/libcruft/lapack/strexc.f
@@ -0,0 +1,345 @@
+      SUBROUTINE STREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, WORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ
+      INTEGER            IFST, ILST, INFO, LDQ, LDT, N
+*     ..
+*     .. Array Arguments ..
+      REAL               Q( LDQ, * ), T( LDT, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STREXC reorders the real Schur factorization of a real matrix
+*  A = Q*T*Q**T, so that the diagonal block of T with row index IFST is
+*  moved to row ILST.
+*
+*  The real Schur form T is reordered by an orthogonal similarity
+*  transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors
+*  is updated by postmultiplying it with Z.
+*
+*  T must be in Schur canonical form (as returned by SHSEQR), that is,
+*  block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
+*  2-by-2 diagonal block has its diagonal elements equal and its
+*  off-diagonal elements of opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V':  update the matrix Q of Schur vectors;
+*          = 'N':  do not update Q.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) REAL array, dimension (LDT,N)
+*          On entry, the upper quasi-triangular matrix T, in Schur
+*          Schur canonical form.
+*          On exit, the reordered upper quasi-triangular matrix, again
+*          in Schur canonical form.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) REAL array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          orthogonal transformation matrix Z which reorders T.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= max(1,N).
+*
+*  IFST    (input/output) INTEGER
+*  ILST    (input/output) INTEGER
+*          Specify the reordering of the diagonal blocks of T.
+*          The block with row index IFST is moved to row ILST, by a
+*          sequence of transpositions between adjacent blocks.
+*          On exit, if IFST pointed on entry to the second row of a
+*          2-by-2 block, it is changed to point to the first row; ILST
+*          always points to the first row of the block in its final
+*          position (which may differ from its input value by +1 or -1).
+*          1 <= IFST <= N; 1 <= ILST <= N.
+*
+*  WORK    (workspace) REAL array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          = 1:  two adjacent blocks were too close to swap (the problem
+*                is very ill-conditioned); T may have been partially
+*                reordered, and ILST points to the first row of the
+*                current position of the block being moved.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            WANTQ
+      INTEGER            HERE, NBF, NBL, NBNEXT
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLAEXC, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input arguments.
+*
+      INFO = 0
+      WANTQ = LSAME( COMPQ, 'V' )
+      IF( .NOT.WANTQ .AND. .NOT.LSAME( COMPQ, 'N' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -6
+      ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THEN
+         INFO = -7
+      ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STREXC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Determine the first row of specified block
+*     and find out it is 1 by 1 or 2 by 2.
+*
+      IF( IFST.GT.1 ) THEN
+         IF( T( IFST, IFST-1 ).NE.ZERO )
+     $      IFST = IFST - 1
+      END IF
+      NBF = 1
+      IF( IFST.LT.N ) THEN
+         IF( T( IFST+1, IFST ).NE.ZERO )
+     $      NBF = 2
+      END IF
+*
+*     Determine the first row of the final block
+*     and find out it is 1 by 1 or 2 by 2.
+*
+      IF( ILST.GT.1 ) THEN
+         IF( T( ILST, ILST-1 ).NE.ZERO )
+     $      ILST = ILST - 1
+      END IF
+      NBL = 1
+      IF( ILST.LT.N ) THEN
+         IF( T( ILST+1, ILST ).NE.ZERO )
+     $      NBL = 2
+      END IF
+*
+      IF( IFST.EQ.ILST )
+     $   RETURN
+*
+      IF( IFST.LT.ILST ) THEN
+*
+*        Update ILST
+*
+         IF( NBF.EQ.2 .AND. NBL.EQ.1 )
+     $      ILST = ILST - 1
+         IF( NBF.EQ.1 .AND. NBL.EQ.2 )
+     $      ILST = ILST + 1
+*
+         HERE = IFST
+*
+   10    CONTINUE
+*
+*        Swap block with next one below
+*
+         IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN
+*
+*           Current block either 1 by 1 or 2 by 2
+*
+            NBNEXT = 1
+            IF( HERE+NBF+1.LE.N ) THEN
+               IF( T( HERE+NBF+1, HERE+NBF ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBF, NBNEXT,
+     $                   WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            HERE = HERE + NBNEXT
+*
+*           Test if 2 by 2 block breaks into two 1 by 1 blocks
+*
+            IF( NBF.EQ.2 ) THEN
+               IF( T( HERE+1, HERE ).EQ.ZERO )
+     $            NBF = 3
+            END IF
+*
+         ELSE
+*
+*           Current block consists of two 1 by 1 blocks each of which
+*           must be swapped individually
+*
+            NBNEXT = 1
+            IF( HERE+3.LE.N ) THEN
+               IF( T( HERE+3, HERE+2 ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, NBNEXT,
+     $                   WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            IF( NBNEXT.EQ.1 ) THEN
+*
+*              Swap two 1 by 1 blocks, no problems possible
+*
+               CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, NBNEXT,
+     $                      WORK, INFO )
+               HERE = HERE + 1
+            ELSE
+*
+*              Recompute NBNEXT in case 2 by 2 split
+*
+               IF( T( HERE+2, HERE+1 ).EQ.ZERO )
+     $            NBNEXT = 1
+               IF( NBNEXT.EQ.2 ) THEN
+*
+*                 2 by 2 Block did not split
+*
+                  CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1,
+     $                         NBNEXT, WORK, INFO )
+                  IF( INFO.NE.0 ) THEN
+                     ILST = HERE
+                     RETURN
+                  END IF
+                  HERE = HERE + 2
+               ELSE
+*
+*                 2 by 2 Block did split
+*
+                  CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,
+     $                         WORK, INFO )
+                  CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, 1,
+     $                         WORK, INFO )
+                  HERE = HERE + 2
+               END IF
+            END IF
+         END IF
+         IF( HERE.LT.ILST )
+     $      GO TO 10
+*
+      ELSE
+*
+         HERE = IFST
+   20    CONTINUE
+*
+*        Swap block with next one above
+*
+         IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN
+*
+*           Current block either 1 by 1 or 2 by 2
+*
+            NBNEXT = 1
+            IF( HERE.GE.3 ) THEN
+               IF( T( HERE-1, HERE-2 ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,
+     $                   NBF, WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            HERE = HERE - NBNEXT
+*
+*           Test if 2 by 2 block breaks into two 1 by 1 blocks
+*
+            IF( NBF.EQ.2 ) THEN
+               IF( T( HERE+1, HERE ).EQ.ZERO )
+     $            NBF = 3
+            END IF
+*
+         ELSE
+*
+*           Current block consists of two 1 by 1 blocks each of which
+*           must be swapped individually
+*
+            NBNEXT = 1
+            IF( HERE.GE.3 ) THEN
+               IF( T( HERE-1, HERE-2 ).NE.ZERO )
+     $            NBNEXT = 2
+            END IF
+            CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,
+     $                   1, WORK, INFO )
+            IF( INFO.NE.0 ) THEN
+               ILST = HERE
+               RETURN
+            END IF
+            IF( NBNEXT.EQ.1 ) THEN
+*
+*              Swap two 1 by 1 blocks, no problems possible
+*
+               CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBNEXT, 1,
+     $                      WORK, INFO )
+               HERE = HERE - 1
+            ELSE
+*
+*              Recompute NBNEXT in case 2 by 2 split
+*
+               IF( T( HERE, HERE-1 ).EQ.ZERO )
+     $            NBNEXT = 1
+               IF( NBNEXT.EQ.2 ) THEN
+*
+*                 2 by 2 Block did not split
+*
+                  CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 2, 1,
+     $                         WORK, INFO )
+                  IF( INFO.NE.0 ) THEN
+                     ILST = HERE
+                     RETURN
+                  END IF
+                  HERE = HERE - 2
+               ELSE
+*
+*                 2 by 2 Block did split
+*
+                  CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,
+     $                         WORK, INFO )
+                  CALL SLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 1, 1,
+     $                         WORK, INFO )
+                  HERE = HERE - 2
+               END IF
+            END IF
+         END IF
+         IF( HERE.GT.ILST )
+     $      GO TO 20
+      END IF
+      ILST = HERE
+*
+      RETURN
+*
+*     End of STREXC
+*
+      END
diff --git a/libcruft/lapack/strsen.f b/libcruft/lapack/strsen.f
new file mode 100644
index 0000000..249220a
--- /dev/null
+++ b/libcruft/lapack/strsen.f
@@ -0,0 +1,461 @@
+      SUBROUTINE STRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI,
+     $                   M, S, SEP, WORK, LWORK, IWORK, LIWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, JOB
+      INTEGER            INFO, LDQ, LDT, LIWORK, LWORK, M, N
+      REAL               S, SEP
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      INTEGER            IWORK( * )
+      REAL               Q( LDQ, * ), T( LDT, * ), WI( * ), WORK( * ),
+     $                   WR( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRSEN reorders the real Schur factorization of a real matrix
+*  A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in
+*  the leading diagonal blocks of the upper quasi-triangular matrix T,
+*  and the leading columns of Q form an orthonormal basis of the
+*  corresponding right invariant subspace.
+*
+*  Optionally the routine computes the reciprocal condition numbers of
+*  the cluster of eigenvalues and/or the invariant subspace.
+*
+*  T must be in Schur canonical form (as returned by SHSEQR), that is,
+*  block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
+*  2-by-2 diagonal block has its diagonal elemnts equal and its
+*  off-diagonal elements of opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies whether condition numbers are required for the
+*          cluster of eigenvalues (S) or the invariant subspace (SEP):
+*          = 'N': none;
+*          = 'E': for eigenvalues only (S);
+*          = 'V': for invariant subspace only (SEP);
+*          = 'B': for both eigenvalues and invariant subspace (S and
+*                 SEP).
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V': update the matrix Q of Schur vectors;
+*          = 'N': do not update Q.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          SELECT specifies the eigenvalues in the selected cluster. To
+*          select a real eigenvalue w(j), SELECT(j) must be set to
+*          .TRUE.. To select a complex conjugate pair of eigenvalues
+*          w(j) and w(j+1), corresponding to a 2-by-2 diagonal block,
+*          either SELECT(j) or SELECT(j+1) or both must be set to
+*          .TRUE.; a complex conjugate pair of eigenvalues must be
+*          either both included in the cluster or both excluded.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) REAL array, dimension (LDT,N)
+*          On entry, the upper quasi-triangular matrix T, in Schur
+*          canonical form.
+*          On exit, T is overwritten by the reordered matrix T, again in
+*          Schur canonical form, with the selected eigenvalues in the
+*          leading diagonal blocks.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) REAL array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          orthogonal transformation matrix which reorders T; the
+*          leading M columns of Q form an orthonormal basis for the
+*          specified invariant subspace.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= 1; and if COMPQ = 'V', LDQ >= N.
+*
+*  WR      (output) REAL array, dimension (N)
+*  WI      (output) REAL array, dimension (N)
+*          The real and imaginary parts, respectively, of the reordered
+*          eigenvalues of T. The eigenvalues are stored in the same
+*          order as on the diagonal of T, with WR(i) = T(i,i) and, if
+*          T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0 and
+*          WI(i+1) = -WI(i). Note that if a complex eigenvalue is
+*          sufficiently ill-conditioned, then its value may differ
+*          significantly from its value before reordering.
+*
+*  M       (output) INTEGER
+*          The dimension of the specified invariant subspace.
+*          0 < = M <= N.
+*
+*  S       (output) REAL
+*          If JOB = 'E' or 'B', S is a lower bound on the reciprocal
+*          condition number for the selected cluster of eigenvalues.
+*          S cannot underestimate the true reciprocal condition number
+*          by more than a factor of sqrt(N). If M = 0 or N, S = 1.
+*          If JOB = 'N' or 'V', S is not referenced.
+*
+*  SEP     (output) REAL
+*          If JOB = 'V' or 'B', SEP is the estimated reciprocal
+*          condition number of the specified invariant subspace. If
+*          M = 0 or N, SEP = norm(T).
+*          If JOB = 'N' or 'E', SEP is not referenced.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If JOB = 'N', LWORK >= max(1,N);
+*          if JOB = 'E', LWORK >= max(1,M*(N-M));
+*          if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
+*          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
+*
+*  LIWORK  (input) INTEGER
+*          The dimension of the array IWORK.
+*          If JOB = 'N' or 'E', LIWORK >= 1;
+*          if JOB = 'V' or 'B', LIWORK >= max(1,M*(N-M)).
+*
+*          If LIWORK = -1, then a workspace query is assumed; the
+*          routine only calculates the optimal size of the IWORK array,
+*          returns this value as the first entry of the IWORK array, and
+*          no error message related to LIWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1: reordering of T failed because some eigenvalues are too
+*               close to separate (the problem is very ill-conditioned);
+*               T may have been partially reordered, and WR and WI
+*               contain the eigenvalues in the same order as in T; S and
+*               SEP (if requested) are set to zero.
+*
+*  Further Details
+*  ===============
+*
+*  STRSEN first collects the selected eigenvalues by computing an
+*  orthogonal transformation Z to move them to the top left corner of T.
+*  In other words, the selected eigenvalues are the eigenvalues of T11
+*  in:
+*
+*                Z'*T*Z = ( T11 T12 ) n1
+*                         (  0  T22 ) n2
+*                            n1  n2
+*
+*  where N = n1+n2 and Z' means the transpose of Z. The first n1 columns
+*  of Z span the specified invariant subspace of T.
+*
+*  If T has been obtained from the real Schur factorization of a matrix
+*  A = Q*T*Q', then the reordered real Schur factorization of A is given
+*  by A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span
+*  the corresponding invariant subspace of A.
+*
+*  The reciprocal condition number of the average of the eigenvalues of
+*  T11 may be returned in S. S lies between 0 (very badly conditioned)
+*  and 1 (very well conditioned). It is computed as follows. First we
+*  compute R so that
+*
+*                         P = ( I  R ) n1
+*                             ( 0  0 ) n2
+*                               n1 n2
+*
+*  is the projector on the invariant subspace associated with T11.
+*  R is the solution of the Sylvester equation:
+*
+*                        T11*R - R*T22 = T12.
+*
+*  Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote
+*  the two-norm of M. Then S is computed as the lower bound
+*
+*                      (1 + F-norm(R)**2)**(-1/2)
+*
+*  on the reciprocal of 2-norm(P), the true reciprocal condition number.
+*  S cannot underestimate 1 / 2-norm(P) by more than a factor of
+*  sqrt(N).
+*
+*  An approximate error bound for the computed average of the
+*  eigenvalues of T11 is
+*
+*                         EPS * norm(T) / S
+*
+*  where EPS is the machine precision.
+*
+*  The reciprocal condition number of the right invariant subspace
+*  spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP.
+*  SEP is defined as the separation of T11 and T22:
+*
+*                     sep( T11, T22 ) = sigma-min( C )
+*
+*  where sigma-min(C) is the smallest singular value of the
+*  n1*n2-by-n1*n2 matrix
+*
+*     C  = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )
+*
+*  I(m) is an m by m identity matrix, and kprod denotes the Kronecker
+*  product. We estimate sigma-min(C) by the reciprocal of an estimate of
+*  the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C)
+*  cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2).
+*
+*  When SEP is small, small changes in T can cause large changes in
+*  the invariant subspace. An approximate bound on the maximum angular
+*  error in the computed right invariant subspace is
+*
+*                      EPS * norm(T) / SEP
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, PAIR, SWAP, WANTBH, WANTQ, WANTS,
+     $                    WANTSP
+      INTEGER            IERR, K, KASE, KK, KS, LIWMIN, LWMIN, N1, N2,
+     $                   NN
+      REAL               EST, RNORM, SCALE
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SLANGE
+      EXTERNAL           LSAME, SLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLACN2, SLACPY, STREXC, STRSYL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      WANTBH = LSAME( JOB, 'B' )
+      WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
+      WANTSP = LSAME( JOB, 'V' ) .OR. WANTBH
+      WANTQ = LSAME( COMPQ, 'V' )
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.WANTS .AND. .NOT.WANTSP )
+     $     THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -8
+      ELSE
+*
+*        Set M to the dimension of the specified invariant subspace,
+*        and test LWORK and LIWORK.
+*
+         M = 0
+         PAIR = .FALSE.
+         DO 10 K = 1, N
+            IF( PAIR ) THEN
+               PAIR = .FALSE.
+            ELSE
+               IF( K.LT.N ) THEN
+                  IF( T( K+1, K ).EQ.ZERO ) THEN
+                     IF( SELECT( K ) )
+     $                  M = M + 1
+                  ELSE
+                     PAIR = .TRUE.
+                     IF( SELECT( K ) .OR. SELECT( K+1 ) )
+     $                  M = M + 2
+                  END IF
+               ELSE
+                  IF( SELECT( N ) )
+     $               M = M + 1
+               END IF
+            END IF
+   10    CONTINUE
+*
+         N1 = M
+         N2 = N - M
+         NN = N1*N2
+*
+         IF(  WANTSP ) THEN
+            LWMIN = MAX( 1, 2*NN )
+            LIWMIN = MAX( 1, NN )
+         ELSE IF( LSAME( JOB, 'N' ) ) THEN
+            LWMIN = MAX( 1, N )
+            LIWMIN = 1
+         ELSE IF( LSAME( JOB, 'E' ) ) THEN
+            LWMIN = MAX( 1, NN )
+            LIWMIN = 1
+         END IF
+*
+         IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -15
+         ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
+            INFO = -17
+         END IF
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         WORK( 1 ) = LWMIN
+         IWORK( 1 ) = LIWMIN
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STRSEN', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( M.EQ.N .OR. M.EQ.0 ) THEN
+         IF( WANTS )
+     $      S = ONE
+         IF( WANTSP )
+     $      SEP = SLANGE( '1', N, N, T, LDT, WORK )
+         GO TO 40
+      END IF
+*
+*     Collect the selected blocks at the top-left corner of T.
+*
+      KS = 0
+      PAIR = .FALSE.
+      DO 20 K = 1, N
+         IF( PAIR ) THEN
+            PAIR = .FALSE.
+         ELSE
+            SWAP = SELECT( K )
+            IF( K.LT.N ) THEN
+               IF( T( K+1, K ).NE.ZERO ) THEN
+                  PAIR = .TRUE.
+                  SWAP = SWAP .OR. SELECT( K+1 )
+               END IF
+            END IF
+            IF( SWAP ) THEN
+               KS = KS + 1
+*
+*              Swap the K-th block to position KS.
+*
+               IERR = 0
+               KK = K
+               IF( K.NE.KS )
+     $            CALL STREXC( COMPQ, N, T, LDT, Q, LDQ, KK, KS, WORK,
+     $                         IERR )
+               IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN
+*
+*                 Blocks too close to swap: exit.
+*
+                  INFO = 1
+                  IF( WANTS )
+     $               S = ZERO
+                  IF( WANTSP )
+     $               SEP = ZERO
+                  GO TO 40
+               END IF
+               IF( PAIR )
+     $            KS = KS + 1
+            END IF
+         END IF
+   20 CONTINUE
+*
+      IF( WANTS ) THEN
+*
+*        Solve Sylvester equation for R:
+*
+*           T11*R - R*T22 = scale*T12
+*
+         CALL SLACPY( 'F', N1, N2, T( 1, N1+1 ), LDT, WORK, N1 )
+         CALL STRSYL( 'N', 'N', -1, N1, N2, T, LDT, T( N1+1, N1+1 ),
+     $                LDT, WORK, N1, SCALE, IERR )
+*
+*        Estimate the reciprocal of the condition number of the cluster
+*        of eigenvalues.
+*
+         RNORM = SLANGE( 'F', N1, N2, WORK, N1, WORK )
+         IF( RNORM.EQ.ZERO ) THEN
+            S = ONE
+         ELSE
+            S = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*
+     $          SQRT( RNORM ) )
+         END IF
+      END IF
+*
+      IF( WANTSP ) THEN
+*
+*        Estimate sep(T11,T22).
+*
+         EST = ZERO
+         KASE = 0
+   30    CONTINUE
+         CALL SLACN2( NN, WORK( NN+1 ), WORK, IWORK, EST, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.1 ) THEN
+*
+*              Solve  T11*R - R*T22 = scale*X.
+*
+               CALL STRSYL( 'N', 'N', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            ELSE
+*
+*              Solve  T11'*R - R*T22' = scale*X.
+*
+               CALL STRSYL( 'T', 'T', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            END IF
+            GO TO 30
+         END IF
+*
+         SEP = SCALE / EST
+      END IF
+*
+   40 CONTINUE
+*
+*     Store the output eigenvalues in WR and WI.
+*
+      DO 50 K = 1, N
+         WR( K ) = T( K, K )
+         WI( K ) = ZERO
+   50 CONTINUE
+      DO 60 K = 1, N - 1
+         IF( T( K+1, K ).NE.ZERO ) THEN
+            WI( K ) = SQRT( ABS( T( K, K+1 ) ) )*
+     $                SQRT( ABS( T( K+1, K ) ) )
+            WI( K+1 ) = -WI( K )
+         END IF
+   60 CONTINUE
+*
+      WORK( 1 ) = LWMIN
+      IWORK( 1 ) = LIWMIN
+*
+      RETURN
+*
+*     End of STRSEN
+*
+      END
diff --git a/libcruft/lapack/strsyl.f b/libcruft/lapack/strsyl.f
new file mode 100644
index 0000000..e9c5ee7
--- /dev/null
+++ b/libcruft/lapack/strsyl.f
@@ -0,0 +1,913 @@
+      SUBROUTINE STRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
+     $                   LDC, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANA, TRANB
+      INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
+      REAL               SCALE
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRSYL solves the real Sylvester matrix equation:
+*
+*     op(A)*X + X*op(B) = scale*C or
+*     op(A)*X - X*op(B) = scale*C,
+*
+*  where op(A) = A or A**T, and  A and B are both upper quasi-
+*  triangular. A is M-by-M and B is N-by-N; the right hand side C and
+*  the solution X are M-by-N; and scale is an output scale factor, set
+*  <= 1 to avoid overflow in X.
+*
+*  A and B must be in Schur canonical form (as returned by SHSEQR), that
+*  is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
+*  each 2-by-2 diagonal block has its diagonal elements equal and its
+*  off-diagonal elements of opposite sign.
+*
+*  Arguments
+*  =========
+*
+*  TRANA   (input) CHARACTER*1
+*          Specifies the option op(A):
+*          = 'N': op(A) = A    (No transpose)
+*          = 'T': op(A) = A**T (Transpose)
+*          = 'C': op(A) = A**H (Conjugate transpose = Transpose)
+*
+*  TRANB   (input) CHARACTER*1
+*          Specifies the option op(B):
+*          = 'N': op(B) = B    (No transpose)
+*          = 'T': op(B) = B**T (Transpose)
+*          = 'C': op(B) = B**H (Conjugate transpose = Transpose)
+*
+*  ISGN    (input) INTEGER
+*          Specifies the sign in the equation:
+*          = +1: solve op(A)*X + X*op(B) = scale*C
+*          = -1: solve op(A)*X - X*op(B) = scale*C
+*
+*  M       (input) INTEGER
+*          The order of the matrix A, and the number of rows in the
+*          matrices X and C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B, and the number of columns in the
+*          matrices X and C. N >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,M)
+*          The upper quasi-triangular matrix A, in Schur canonical form.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input) REAL array, dimension (LDB,N)
+*          The upper quasi-triangular matrix B, in Schur canonical form.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  C       (input/output) REAL array, dimension (LDC,N)
+*          On entry, the M-by-N right hand side matrix C.
+*          On exit, C is overwritten by the solution matrix X.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M)
+*
+*  SCALE   (output) REAL
+*          The scale factor, scale, set <= 1 to avoid overflow in X.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1: A and B have common or very close eigenvalues; perturbed
+*               values were used to solve the equation (but the matrices
+*               A and B are unchanged).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRNA, NOTRNB
+      INTEGER            IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXT
+      REAL               A11, BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
+     $                   SMLNUM, SUML, SUMR, XNORM
+*     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 ), VEC( 2, 2 ), X( 2, 2 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      REAL               SDOT, SLAMCH, SLANGE
+      EXTERNAL           LSAME, SDOT, SLAMCH, SLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLABAD, SLALN2, SLASY2, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, REAL
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test input parameters
+*
+      NOTRNA = LSAME( TRANA, 'N' )
+      NOTRNB = LSAME( TRANB, 'N' )
+*
+      INFO = 0
+      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND. .NOT.
+     $    LSAME( TRANA, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'T' ) .AND. .NOT.
+     $         LSAME( TRANB, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STRSYL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Set constants to control overflow
+*
+      EPS = SLAMCH( 'P' )
+      SMLNUM = SLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL SLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM*REAL( M*N ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+      SMIN = MAX( SMLNUM, EPS*SLANGE( 'M', M, M, A, LDA, DUM ),
+     $       EPS*SLANGE( 'M', N, N, B, LDB, DUM ) )
+*
+      SCALE = ONE
+      SGN = ISGN
+*
+      IF( NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-left corner column by column by
+*
+*         A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                  M                         L-1
+*        R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)].
+*                I=K+1                       J=1
+*
+*        Start column loop (index = L)
+*        L1 (L2) : column index of the first (first) row of X(K,L).
+*
+         LNEXT = 1
+         DO 70 L = 1, N
+            IF( L.LT.LNEXT )
+     $         GO TO 70
+            IF( L.EQ.N ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L+1, L ).NE.ZERO ) THEN
+                  L1 = L
+                  L2 = L + 1
+                  LNEXT = L + 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L + 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L).
+*
+            KNEXT = M
+            DO 60 K = M, 1, -1
+               IF( K.GT.KNEXT )
+     $            GO TO 60
+               IF( K.EQ.1 ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K, K-1 ).NE.ZERO ) THEN
+                     K1 = K - 1
+                     K2 = K
+                     KNEXT = K - 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K - 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = SDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                         C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 10 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+   10                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 20 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+   20                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = SDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                         C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = SDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                         C( MIN( K1+1, M ), L2 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 40 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+   40                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = SDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLASY2( .FALSE., .FALSE., ISGN, 2, 2,
+     $                         A( K1, K1 ), LDA, B( L1, L1 ), LDB, VEC,
+     $                         2, SCALOC, X, 2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 50 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+   50                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+   60       CONTINUE
+*
+   70    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A' *X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        upper-left corner column by column by
+*
+*          A(K,K)'*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                   K-1                        L-1
+*          R(K,L) = SUM [A(I,K)'*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)]
+*                   I=1                        J=1
+*
+*        Start column loop (index = L)
+*        L1 (L2): column index of the first (last) row of X(K,L)
+*
+         LNEXT = 1
+         DO 130 L = 1, N
+            IF( L.LT.LNEXT )
+     $         GO TO 130
+            IF( L.EQ.N ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L+1, L ).NE.ZERO ) THEN
+                  L1 = L
+                  L2 = L + 1
+                  LNEXT = L + 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L + 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L)
+*
+            KNEXT = 1
+            DO 120 K = 1, M
+               IF( K.LT.KNEXT )
+     $            GO TO 120
+               IF( K.EQ.M ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K+1, K ).NE.ZERO ) THEN
+                     K1 = K
+                     K2 = K + 1
+                     KNEXT = K + 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K + 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 80 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+   80                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 90 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+   90                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 100 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  100                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = SDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
+                  SUMR = SDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLASY2( .TRUE., .FALSE., ISGN, 2, 2, A( K1, K1 ),
+     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
+     $                         2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 110 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  110                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+  120       CONTINUE
+  130    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A'*X + ISGN*X*B' = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        top-right corner column by column by
+*
+*           A(K,K)'*X(K,L) + ISGN*X(K,L)*B(L,L)' = C(K,L) - R(K,L)
+*
+*        Where
+*                     K-1                          N
+*            R(K,L) = SUM [A(I,K)'*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)'].
+*                     I=1                        J=L+1
+*
+*        Start column loop (index = L)
+*        L1 (L2): column index of the first (last) row of X(K,L)
+*
+         LNEXT = N
+         DO 190 L = N, 1, -1
+            IF( L.GT.LNEXT )
+     $         GO TO 190
+            IF( L.EQ.1 ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L, L-1 ).NE.ZERO ) THEN
+                  L1 = L - 1
+                  L2 = L
+                  LNEXT = L - 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L - 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L)
+*
+            KNEXT = 1
+            DO 180 K = 1, M
+               IF( K.LT.KNEXT )
+     $            GO TO 180
+               IF( K.EQ.M ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K+1, K ).NE.ZERO ) THEN
+                     K1 = K
+                     K2 = K + 1
+                     KNEXT = K + 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K + 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,
+     $                         B( L1, MIN( L1+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 140 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  140                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 150 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  150                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL SLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 160 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  160                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
+                  SUMR = SDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                         B( L2, MIN(L2+1, N ) ), LDB )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLASY2( .TRUE., .TRUE., ISGN, 2, 2, A( K1, K1 ),
+     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
+     $                         2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 170 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  170                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+  180       CONTINUE
+  190    CONTINUE
+*
+      ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B' = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-right corner column by column by
+*
+*            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L)' = C(K,L) - R(K,L)
+*
+*        Where
+*                      M                          N
+*            R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)'].
+*                    I=K+1                      J=L+1
+*
+*        Start column loop (index = L)
+*        L1 (L2): column index of the first (last) row of X(K,L)
+*
+         LNEXT = N
+         DO 250 L = N, 1, -1
+            IF( L.GT.LNEXT )
+     $         GO TO 250
+            IF( L.EQ.1 ) THEN
+               L1 = L
+               L2 = L
+            ELSE
+               IF( B( L, L-1 ).NE.ZERO ) THEN
+                  L1 = L - 1
+                  L2 = L
+                  LNEXT = L - 2
+               ELSE
+                  L1 = L
+                  L2 = L
+                  LNEXT = L - 1
+               END IF
+            END IF
+*
+*           Start row loop (index = K)
+*           K1 (K2): row index of the first (last) row of X(K,L)
+*
+            KNEXT = M
+            DO 240 K = M, 1, -1
+               IF( K.GT.KNEXT )
+     $            GO TO 240
+               IF( K.EQ.1 ) THEN
+                  K1 = K
+                  K2 = K
+               ELSE
+                  IF( A( K, K-1 ).NE.ZERO ) THEN
+                     K1 = K - 1
+                     K2 = K
+                     KNEXT = K - 2
+                  ELSE
+                     K1 = K
+                     K2 = K
+                     KNEXT = K - 1
+                  END IF
+               END IF
+*
+               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
+                  SUML = SDOT( M-K1, A( K1, MIN(K1+1, M ) ), LDA,
+     $                   C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = SDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,
+     $                         B( L1, MIN( L1+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+                  SCALOC = ONE
+*
+                  A11 = A( K1, K1 ) + SGN*B( L1, L1 )
+                  DA11 = ABS( A11 )
+                  IF( DA11.LE.SMIN ) THEN
+                     A11 = SMIN
+                     DA11 = SMIN
+                     INFO = 1
+                  END IF
+                  DB = ABS( VEC( 1, 1 ) )
+                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                     IF( DB.GT.BIGNUM*DA11 )
+     $                  SCALOC = ONE / DB
+                  END IF
+                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 200 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  200                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+*
+               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),
+     $                         LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 210 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  210                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K2, L1 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
+*
+                  SUML = SDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                         C( MIN( K1+1, M ), L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )
+*
+                  SUML = SDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,
+     $                         C( MIN( K1+1, M ), L2 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )
+*
+                  CALL SLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),
+     $                         LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),
+     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 220 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  220                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 2, 1 )
+*
+               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
+*
+                  SUML = SDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = SDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,
+     $                         B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L1 ), 1 )
+                  SUMR = SDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                         B( L1, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )
+*
+                  SUML = SDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,
+     $                         C( MIN( K2+1, M ), L2 ), 1 )
+                  SUMR = SDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,
+     $                         B( L2, MIN( L2+1, N ) ), LDB )
+                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )
+*
+                  CALL SLASY2( .FALSE., .TRUE., ISGN, 2, 2, A( K1, K1 ),
+     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
+     $                         2, XNORM, IERR )
+                  IF( IERR.NE.0 )
+     $               INFO = 1
+*
+                  IF( SCALOC.NE.ONE ) THEN
+                     DO 230 J = 1, N
+                        CALL SSCAL( M, SCALOC, C( 1, J ), 1 )
+  230                CONTINUE
+                     SCALE = SCALE*SCALOC
+                  END IF
+                  C( K1, L1 ) = X( 1, 1 )
+                  C( K1, L2 ) = X( 1, 2 )
+                  C( K2, L1 ) = X( 2, 1 )
+                  C( K2, L2 ) = X( 2, 2 )
+               END IF
+*
+  240       CONTINUE
+  250    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of STRSYL
+*
+      END
diff --git a/libcruft/lapack/strti2.f b/libcruft/lapack/strti2.f
new file mode 100644
index 0000000..79ca5c8
--- /dev/null
+++ b/libcruft/lapack/strti2.f
@@ -0,0 +1,146 @@
+      SUBROUTINE STRTI2( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRTI2 computes the inverse of a real upper or lower triangular
+*  matrix.
+*
+*  This is the Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading n by n upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE
+      PARAMETER          ( ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J
+      REAL               AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SSCAL, STRMV, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STRTI2', -INFO )
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Compute inverse of upper triangular matrix.
+*
+         DO 10 J = 1, N
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+*
+*           Compute elements 1:j-1 of j-th column.
+*
+            CALL STRMV( 'Upper', 'No transpose', DIAG, J-1, A, LDA,
+     $                  A( 1, J ), 1 )
+            CALL SSCAL( J-1, AJJ, A( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Compute inverse of lower triangular matrix.
+*
+         DO 20 J = N, 1, -1
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+            IF( J.LT.N ) THEN
+*
+*              Compute elements j+1:n of j-th column.
+*
+               CALL STRMV( 'Lower', 'No transpose', DIAG, N-J,
+     $                     A( J+1, J+1 ), LDA, A( J+1, J ), 1 )
+               CALL SSCAL( N-J, AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of STRTI2
+*
+      END
diff --git a/libcruft/lapack/strtri.f b/libcruft/lapack/strtri.f
new file mode 100644
index 0000000..3bda8ac
--- /dev/null
+++ b/libcruft/lapack/strtri.f
@@ -0,0 +1,176 @@
+      SUBROUTINE STRTRI( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRTRI computes the inverse of a real upper or lower triangular
+*  matrix A.
+*
+*  This is the Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, A(i,i) is exactly zero.  The triangular
+*               matrix is singular and its inverse can not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ONE, ZERO
+      PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J, JB, NB, NN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           STRMM, STRSM, STRTI2, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STRTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity if non-unit.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+         INFO = 0
+      END IF
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL STRTI2( UPLO, DIAG, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute inverse of upper triangular matrix
+*
+            DO 20 J = 1, N, NB
+               JB = MIN( NB, N-J+1 )
+*
+*              Compute rows 1:j-1 of current block column
+*
+               CALL STRMM( 'Left', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, ONE, A, LDA, A( 1, J ), LDA )
+               CALL STRSM( 'Right', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, -ONE, A( J, J ), LDA, A( 1, J ), LDA )
+*
+*              Compute inverse of current diagonal block
+*
+               CALL STRTI2( 'Upper', DIAG, JB, A( J, J ), LDA, INFO )
+   20       CONTINUE
+         ELSE
+*
+*           Compute inverse of lower triangular matrix
+*
+            NN = ( ( N-1 ) / NB )*NB + 1
+            DO 30 J = NN, 1, -NB
+               JB = MIN( NB, N-J+1 )
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute rows j+jb:n of current block column
+*
+                  CALL STRMM( 'Left', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, ONE, A( J+JB, J+JB ), LDA,
+     $                        A( J+JB, J ), LDA )
+                  CALL STRSM( 'Right', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, -ONE, A( J, J ), LDA,
+     $                        A( J+JB, J ), LDA )
+               END IF
+*
+*              Compute inverse of current diagonal block
+*
+               CALL STRTI2( 'Lower', DIAG, JB, A( J, J ), LDA, INFO )
+   30       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRTRI
+*
+      END
diff --git a/libcruft/lapack/strtrs.f b/libcruft/lapack/strtrs.f
new file mode 100644
index 0000000..df36982
--- /dev/null
+++ b/libcruft/lapack/strtrs.f
@@ -0,0 +1,147 @@
+      SUBROUTINE STRTRS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, TRANS, UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STRTRS solves a triangular system of the form
+*
+*     A * X = B  or  A**T * X = B,
+*
+*  where A is a triangular matrix of order N, and B is an N-by-NRHS
+*  matrix.  A check is made to verify that A is nonsingular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B  (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose = Transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) REAL array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) REAL array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, if INFO = 0, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, the i-th diagonal element of A is zero,
+*               indicating that the matrix is singular and the solutions
+*               X have not been computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           STRSM, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.
+     $         LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STRTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+      END IF
+      INFO = 0
+*
+*     Solve A * x = b  or  A' * x = b.
+*
+      CALL STRSM( 'Left', UPLO, TRANS, DIAG, N, NRHS, ONE, A, LDA, B,
+     $            LDB )
+*
+      RETURN
+*
+*     End of STRTRS
+*
+      END
diff --git a/libcruft/lapack/stzrzf.f b/libcruft/lapack/stzrzf.f
new file mode 100644
index 0000000..33459c5
--- /dev/null
+++ b/libcruft/lapack/stzrzf.f
@@ -0,0 +1,244 @@
+      SUBROUTINE STZRZF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      REAL               A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  STZRZF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A
+*  to upper triangular form by means of orthogonal transformations.
+*
+*  The upper trapezoidal matrix A is factored as
+*
+*     A = ( R  0 ) * Z,
+*
+*  where Z is an N-by-N orthogonal matrix and R is an M-by-M upper
+*  triangular matrix.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= M.
+*
+*  A       (input/output) REAL array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements M+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          orthogonal matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) REAL array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an ( n - m ) element vector.
+*  tau and z( k ) are chosen to annihilate the elements of the kth row
+*  of X.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A, such that the elements of z( k ) are
+*  in  a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL               ZERO
+      PARAMETER          ( ZERO = 0.0E+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IWS, KI, KK, LDWORK, LWKOPT, M1, MU, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SLARZB, SLARZT, SLATRZ, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. M.EQ.N ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.
+*
+            NB = ILAENV( 1, 'SGERQF', ' ', M, N, -1, -1 )
+            LWKOPT = M*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+            INFO = -7
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STZRZF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 1
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.M ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'SGERQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.M ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'SGERQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.M .AND. NX.LT.M ) THEN
+*
+*        Use blocked code initially.
+*        The last kk rows are handled by the block method.
+*
+         M1 = MIN( M+1, N )
+         KI = ( ( M-NX-1 ) / NB )*NB
+         KK = MIN( M, KI+NB )
+*
+         DO 20 I = M - KK + KI + 1, M - KK + 1, -NB
+            IB = MIN( M-I+1, NB )
+*
+*           Compute the TZ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL SLATRZ( IB, N-I+1, N-M, A( I, I ), LDA, TAU( I ),
+     $                   WORK )
+            IF( I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL SLARZT( 'Backward', 'Rowwise', N-M, IB, A( I, M1 ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:i-1,i:n) from the right
+*
+               CALL SLARZB( 'Right', 'No transpose', 'Backward',
+     $                      'Rowwise', I-1, N-I+1, IB, N-M, A( I, M1 ),
+     $                      LDA, WORK, LDWORK, A( 1, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   20    CONTINUE
+         MU = I + NB - 1
+      ELSE
+         MU = M
+      END IF
+*
+*     Use unblocked code to factor the last or only block
+*
+      IF( MU.GT.0 )
+     $   CALL SLATRZ( MU, N, N-M, A, LDA, TAU, WORK )
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of STZRZF
+*
+      END
diff --git a/libcruft/lapack/zbdsqr.f b/libcruft/lapack/zbdsqr.f
new file mode 100644
index 0000000..f9086be
--- /dev/null
+++ b/libcruft/lapack/zbdsqr.f
@@ -0,0 +1,742 @@
+      SUBROUTINE ZBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
+     $                   LDU, C, LDC, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * ), RWORK( * )
+      COMPLEX*16         C( LDC, * ), U( LDU, * ), VT( LDVT, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZBDSQR computes the singular values and, optionally, the right and/or
+*  left singular vectors from the singular value decomposition (SVD) of
+*  a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
+*  zero-shift QR algorithm.  The SVD of B has the form
+* 
+*     B = Q * S * P**H
+* 
+*  where S is the diagonal matrix of singular values, Q is an orthogonal
+*  matrix of left singular vectors, and P is an orthogonal matrix of
+*  right singular vectors.  If left singular vectors are requested, this
+*  subroutine actually returns U*Q instead of Q, and, if right singular
+*  vectors are requested, this subroutine returns P**H*VT instead of
+*  P**H, for given complex input matrices U and VT.  When U and VT are
+*  the unitary matrices that reduce a general matrix A to bidiagonal
+*  form: A = U*B*VT, as computed by ZGEBRD, then
+* 
+*     A = (U*Q) * S * (P**H*VT)
+* 
+*  is the SVD of A.  Optionally, the subroutine may also compute Q**H*C
+*  for a given complex input matrix C.
+*
+*  See "Computing  Small Singular Values of Bidiagonal Matrices With
+*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
+*  LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,
+*  no. 5, pp. 873-912, Sept 1990) and
+*  "Accurate singular values and differential qd algorithms," by
+*  B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics
+*  Department, University of California at Berkeley, July 1992
+*  for a detailed description of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  B is upper bidiagonal;
+*          = 'L':  B is lower bidiagonal.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B.  N >= 0.
+*
+*  NCVT    (input) INTEGER
+*          The number of columns of the matrix VT. NCVT >= 0.
+*
+*  NRU     (input) INTEGER
+*          The number of rows of the matrix U. NRU >= 0.
+*
+*  NCC     (input) INTEGER
+*          The number of columns of the matrix C. NCC >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the bidiagonal matrix B.
+*          On exit, if INFO=0, the singular values of B in decreasing
+*          order.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the N-1 offdiagonal elements of the bidiagonal
+*          matrix B.
+*          On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E
+*          will contain the diagonal and superdiagonal elements of a
+*          bidiagonal matrix orthogonally equivalent to the one given
+*          as input.
+*
+*  VT      (input/output) COMPLEX*16 array, dimension (LDVT, NCVT)
+*          On entry, an N-by-NCVT matrix VT.
+*          On exit, VT is overwritten by P**H * VT.
+*          Not referenced if NCVT = 0.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.
+*          LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.
+*
+*  U       (input/output) COMPLEX*16 array, dimension (LDU, N)
+*          On entry, an NRU-by-N matrix U.
+*          On exit, U is overwritten by U * Q.
+*          Not referenced if NRU = 0.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= max(1,NRU).
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC, NCC)
+*          On entry, an N-by-NCC matrix C.
+*          On exit, C is overwritten by Q**H * C.
+*          Not referenced if NCC = 0.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C.
+*          LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*          if NCVT = NRU = NCC = 0, (max(1, 4*N-4)) otherwise
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  If INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm did not converge; D and E contain the
+*                elements of a bidiagonal matrix which is orthogonally
+*                similar to the input matrix B;  if INFO = i, i
+*                elements of E have not converged to zero.
+*
+*  Internal Parameters
+*  ===================
+*
+*  TOLMUL  DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8)))
+*          TOLMUL controls the convergence criterion of the QR loop.
+*          If it is positive, TOLMUL*EPS is the desired relative
+*             precision in the computed singular values.
+*          If it is negative, abs(TOLMUL*EPS*sigma_max) is the
+*             desired absolute accuracy in the computed singular
+*             values (corresponds to relative accuracy
+*             abs(TOLMUL*EPS) in the largest singular value.
+*          abs(TOLMUL) should be between 1 and 1/EPS, and preferably
+*             between 10 (for fast convergence) and .1/EPS
+*             (for there to be some accuracy in the results).
+*          Default is to lose at either one eighth or 2 of the
+*             available decimal digits in each computed singular value
+*             (whichever is smaller).
+*
+*  MAXITR  INTEGER, default = 6
+*          MAXITR controls the maximum number of passes of the
+*          algorithm through its inner loop. The algorithms stops
+*          (and so fails to converge) if the number of passes
+*          through the inner loop exceeds MAXITR*N**2.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D0 )
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D0 )
+      DOUBLE PRECISION   NEGONE
+      PARAMETER          ( NEGONE = -1.0D0 )
+      DOUBLE PRECISION   HNDRTH
+      PARAMETER          ( HNDRTH = 0.01D0 )
+      DOUBLE PRECISION   TEN
+      PARAMETER          ( TEN = 10.0D0 )
+      DOUBLE PRECISION   HNDRD
+      PARAMETER          ( HNDRD = 100.0D0 )
+      DOUBLE PRECISION   MEIGTH
+      PARAMETER          ( MEIGTH = -0.125D0 )
+      INTEGER            MAXITR
+      PARAMETER          ( MAXITR = 6 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, ROTATE
+      INTEGER            I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
+     $                   NM12, NM13, OLDLL, OLDM
+      DOUBLE PRECISION   ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
+     $                   OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
+     $                   SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
+     $                   SN, THRESH, TOL, TOLMUL, UNFL
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLARTG, DLAS2, DLASQ1, DLASV2, XERBLA, ZDROT,
+     $                   ZDSCAL, ZLASR, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, MIN, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      LOWER = LSAME( UPLO, 'L' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NCVT.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NCC.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
+     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
+         INFO = -9
+      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
+         INFO = -11
+      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
+     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZBDSQR', -INFO )
+         RETURN
+      END IF
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( N.EQ.1 )
+     $   GO TO 160
+*
+*     ROTATE is true if any singular vectors desired, false otherwise
+*
+      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
+*
+*     If no singular vectors desired, use qd algorithm
+*
+      IF( .NOT.ROTATE ) THEN
+         CALL DLASQ1( N, D, E, RWORK, INFO )
+         RETURN
+      END IF
+*
+      NM1 = N - 1
+      NM12 = NM1 + NM1
+      NM13 = NM12 + NM1
+      IDIR = 0
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'Epsilon' )
+      UNFL = DLAMCH( 'Safe minimum' )
+*
+*     If matrix lower bidiagonal, rotate to be upper bidiagonal
+*     by applying Givens rotations on the left
+*
+      IF( LOWER ) THEN
+         DO 10 I = 1, N - 1
+            CALL DLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            RWORK( I ) = CS
+            RWORK( NM1+I ) = SN
+   10    CONTINUE
+*
+*        Update singular vectors if desired
+*
+         IF( NRU.GT.0 )
+     $      CALL ZLASR( 'R', 'V', 'F', NRU, N, RWORK( 1 ), RWORK( N ),
+     $                  U, LDU )
+         IF( NCC.GT.0 )
+     $      CALL ZLASR( 'L', 'V', 'F', N, NCC, RWORK( 1 ), RWORK( N ),
+     $                  C, LDC )
+      END IF
+*
+*     Compute singular values to relative accuracy TOL
+*     (By setting TOL to be negative, algorithm will compute
+*     singular values to absolute accuracy ABS(TOL)*norm(input matrix))
+*
+      TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
+      TOL = TOLMUL*EPS
+*
+*     Compute approximate maximum, minimum singular values
+*
+      SMAX = ZERO
+      DO 20 I = 1, N
+         SMAX = MAX( SMAX, ABS( D( I ) ) )
+   20 CONTINUE
+      DO 30 I = 1, N - 1
+         SMAX = MAX( SMAX, ABS( E( I ) ) )
+   30 CONTINUE
+      SMINL = ZERO
+      IF( TOL.GE.ZERO ) THEN
+*
+*        Relative accuracy desired
+*
+         SMINOA = ABS( D( 1 ) )
+         IF( SMINOA.EQ.ZERO )
+     $      GO TO 50
+         MU = SMINOA
+         DO 40 I = 2, N
+            MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
+            SMINOA = MIN( SMINOA, MU )
+            IF( SMINOA.EQ.ZERO )
+     $         GO TO 50
+   40    CONTINUE
+   50    CONTINUE
+         SMINOA = SMINOA / SQRT( DBLE( N ) )
+         THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
+      ELSE
+*
+*        Absolute accuracy desired
+*
+         THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
+      END IF
+*
+*     Prepare for main iteration loop for the singular values
+*     (MAXIT is the maximum number of passes through the inner
+*     loop permitted before nonconvergence signalled.)
+*
+      MAXIT = MAXITR*N*N
+      ITER = 0
+      OLDLL = -1
+      OLDM = -1
+*
+*     M points to last element of unconverged part of matrix
+*
+      M = N
+*
+*     Begin main iteration loop
+*
+   60 CONTINUE
+*
+*     Check for convergence or exceeding iteration count
+*
+      IF( M.LE.1 )
+     $   GO TO 160
+      IF( ITER.GT.MAXIT )
+     $   GO TO 200
+*
+*     Find diagonal block of matrix to work on
+*
+      IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
+     $   D( M ) = ZERO
+      SMAX = ABS( D( M ) )
+      SMIN = SMAX
+      DO 70 LLL = 1, M - 1
+         LL = M - LLL
+         ABSS = ABS( D( LL ) )
+         ABSE = ABS( E( LL ) )
+         IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
+     $      D( LL ) = ZERO
+         IF( ABSE.LE.THRESH )
+     $      GO TO 80
+         SMIN = MIN( SMIN, ABSS )
+         SMAX = MAX( SMAX, ABSS, ABSE )
+   70 CONTINUE
+      LL = 0
+      GO TO 90
+   80 CONTINUE
+      E( LL ) = ZERO
+*
+*     Matrix splits since E(LL) = 0
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        Convergence of bottom singular value, return to top of loop
+*
+         M = M - 1
+         GO TO 60
+      END IF
+   90 CONTINUE
+      LL = LL + 1
+*
+*     E(LL) through E(M-1) are nonzero, E(LL-1) is zero
+*
+      IF( LL.EQ.M-1 ) THEN
+*
+*        2 by 2 block, handle separately
+*
+         CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
+     $                COSR, SINL, COSL )
+         D( M-1 ) = SIGMX
+         E( M-1 ) = ZERO
+         D( M ) = SIGMN
+*
+*        Compute singular vectors, if desired
+*
+         IF( NCVT.GT.0 )
+     $      CALL ZDROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT,
+     $                  COSR, SINR )
+         IF( NRU.GT.0 )
+     $      CALL ZDROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
+         IF( NCC.GT.0 )
+     $      CALL ZDROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
+     $                  SINL )
+         M = M - 2
+         GO TO 60
+      END IF
+*
+*     If working on new submatrix, choose shift direction
+*     (from larger end diagonal element towards smaller)
+*
+      IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
+         IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
+*
+*           Chase bulge from top (big end) to bottom (small end)
+*
+            IDIR = 1
+         ELSE
+*
+*           Chase bulge from bottom (big end) to top (small end)
+*
+            IDIR = 2
+         END IF
+      END IF
+*
+*     Apply convergence tests
+*
+      IF( IDIR.EQ.1 ) THEN
+*
+*        Run convergence test in forward direction
+*        First apply standard test to bottom of matrix
+*
+         IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
+            E( M-1 ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion forward
+*
+            MU = ABS( D( LL ) )
+            SMINL = MU
+            DO 100 LLL = LL, M - 1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  100       CONTINUE
+         END IF
+*
+      ELSE
+*
+*        Run convergence test in backward direction
+*        First apply standard test to top of matrix
+*
+         IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
+     $       ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
+            E( LL ) = ZERO
+            GO TO 60
+         END IF
+*
+         IF( TOL.GE.ZERO ) THEN
+*
+*           If relative accuracy desired,
+*           apply convergence criterion backward
+*
+            MU = ABS( D( M ) )
+            SMINL = MU
+            DO 110 LLL = M - 1, LL, -1
+               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
+                  E( LLL ) = ZERO
+                  GO TO 60
+               END IF
+               MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
+               SMINL = MIN( SMINL, MU )
+  110       CONTINUE
+         END IF
+      END IF
+      OLDLL = LL
+      OLDM = M
+*
+*     Compute shift.  First, test if shifting would ruin relative
+*     accuracy, and if so set the shift to zero.
+*
+      IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
+     $    MAX( EPS, HNDRTH*TOL ) ) THEN
+*
+*        Use a zero shift to avoid loss of relative accuracy
+*
+         SHIFT = ZERO
+      ELSE
+*
+*        Compute the shift from 2-by-2 block at end of matrix
+*
+         IF( IDIR.EQ.1 ) THEN
+            SLL = ABS( D( LL ) )
+            CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
+         ELSE
+            SLL = ABS( D( M ) )
+            CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
+         END IF
+*
+*        Test if shift negligible, and if so set to zero
+*
+         IF( SLL.GT.ZERO ) THEN
+            IF( ( SHIFT / SLL )**2.LT.EPS )
+     $         SHIFT = ZERO
+         END IF
+      END IF
+*
+*     Increment iteration count
+*
+      ITER = ITER + M - LL
+*
+*     If SHIFT = 0, do simplified QR iteration
+*
+      IF( SHIFT.EQ.ZERO ) THEN
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 120 I = LL, M - 1
+               CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = OLDSN*R
+               CALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
+               RWORK( I-LL+1 ) = CS
+               RWORK( I-LL+1+NM1 ) = SN
+               RWORK( I-LL+1+NM12 ) = OLDCS
+               RWORK( I-LL+1+NM13 ) = OLDSN
+  120       CONTINUE
+            H = D( M )*CS
+            D( M ) = H*OLDCS
+            E( M-1 ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
+     $                     RWORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL ZLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            CS = ONE
+            OLDCS = ONE
+            DO 130 I = M, LL + 1, -1
+               CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
+               IF( I.LT.M )
+     $            E( I ) = OLDSN*R
+               CALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
+               RWORK( I-LL ) = CS
+               RWORK( I-LL+NM1 ) = -SN
+               RWORK( I-LL+NM12 ) = OLDCS
+               RWORK( I-LL+NM13 ) = -OLDSN
+  130       CONTINUE
+            H = D( LL )*CS
+            D( LL ) = H*OLDCS
+            E( LL ) = H*OLDSN
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL ZLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
+     $                     RWORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
+     $                     RWORK( N ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+         END IF
+      ELSE
+*
+*        Use nonzero shift
+*
+         IF( IDIR.EQ.1 ) THEN
+*
+*           Chase bulge from top to bottom
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( LL ) )-SHIFT )*
+     $          ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
+            G = E( LL )
+            DO 140 I = LL, M - 1
+               CALL DLARTG( F, G, COSR, SINR, R )
+               IF( I.GT.LL )
+     $            E( I-1 ) = R
+               F = COSR*D( I ) + SINR*E( I )
+               E( I ) = COSR*E( I ) - SINR*D( I )
+               G = SINR*D( I+1 )
+               D( I+1 ) = COSR*D( I+1 )
+               CALL DLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I ) + SINL*D( I+1 )
+               D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
+               IF( I.LT.M-1 ) THEN
+                  G = SINL*E( I+1 )
+                  E( I+1 ) = COSL*E( I+1 )
+               END IF
+               RWORK( I-LL+1 ) = COSR
+               RWORK( I-LL+1+NM1 ) = SINR
+               RWORK( I-LL+1+NM12 ) = COSL
+               RWORK( I-LL+1+NM13 ) = SINL
+  140       CONTINUE
+            E( M-1 ) = F
+*
+*           Update singular vectors
+*
+            IF( NCVT.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
+     $                     RWORK( N ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL ZLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), C( LL, 1 ), LDC )
+*
+*           Test convergence
+*
+            IF( ABS( E( M-1 ) ).LE.THRESH )
+     $         E( M-1 ) = ZERO
+*
+         ELSE
+*
+*           Chase bulge from bottom to top
+*           Save cosines and sines for later singular vector updates
+*
+            F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
+     $          D( M ) )
+            G = E( M-1 )
+            DO 150 I = M, LL + 1, -1
+               CALL DLARTG( F, G, COSR, SINR, R )
+               IF( I.LT.M )
+     $            E( I ) = R
+               F = COSR*D( I ) + SINR*E( I-1 )
+               E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
+               G = SINR*D( I-1 )
+               D( I-1 ) = COSR*D( I-1 )
+               CALL DLARTG( F, G, COSL, SINL, R )
+               D( I ) = R
+               F = COSL*E( I-1 ) + SINL*D( I-1 )
+               D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
+               IF( I.GT.LL+1 ) THEN
+                  G = SINL*E( I-2 )
+                  E( I-2 ) = COSL*E( I-2 )
+               END IF
+               RWORK( I-LL ) = COSR
+               RWORK( I-LL+NM1 ) = -SINR
+               RWORK( I-LL+NM12 ) = COSL
+               RWORK( I-LL+NM13 ) = -SINL
+  150       CONTINUE
+            E( LL ) = F
+*
+*           Test convergence
+*
+            IF( ABS( E( LL ) ).LE.THRESH )
+     $         E( LL ) = ZERO
+*
+*           Update singular vectors if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
+     $                     RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
+            IF( NRU.GT.0 )
+     $         CALL ZLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
+     $                     RWORK( N ), U( 1, LL ), LDU )
+            IF( NCC.GT.0 )
+     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
+     $                     RWORK( N ), C( LL, 1 ), LDC )
+         END IF
+      END IF
+*
+*     QR iteration finished, go back and check convergence
+*
+      GO TO 60
+*
+*     All singular values converged, so make them positive
+*
+  160 CONTINUE
+      DO 170 I = 1, N
+         IF( D( I ).LT.ZERO ) THEN
+            D( I ) = -D( I )
+*
+*           Change sign of singular vectors, if desired
+*
+            IF( NCVT.GT.0 )
+     $         CALL ZDSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
+         END IF
+  170 CONTINUE
+*
+*     Sort the singular values into decreasing order (insertion sort on
+*     singular values, but only one transposition per singular vector)
+*
+      DO 190 I = 1, N - 1
+*
+*        Scan for smallest D(I)
+*
+         ISUB = 1
+         SMIN = D( 1 )
+         DO 180 J = 2, N + 1 - I
+            IF( D( J ).LE.SMIN ) THEN
+               ISUB = J
+               SMIN = D( J )
+            END IF
+  180    CONTINUE
+         IF( ISUB.NE.N+1-I ) THEN
+*
+*           Swap singular values and vectors
+*
+            D( ISUB ) = D( N+1-I )
+            D( N+1-I ) = SMIN
+            IF( NCVT.GT.0 )
+     $         CALL ZSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
+     $                     LDVT )
+            IF( NRU.GT.0 )
+     $         CALL ZSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
+            IF( NCC.GT.0 )
+     $         CALL ZSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
+         END IF
+  190 CONTINUE
+      GO TO 220
+*
+*     Maximum number of iterations exceeded, failure to converge
+*
+  200 CONTINUE
+      INFO = 0
+      DO 210 I = 1, N - 1
+         IF( E( I ).NE.ZERO )
+     $      INFO = INFO + 1
+  210 CONTINUE
+  220 CONTINUE
+      RETURN
+*
+*     End of ZBDSQR
+*
+      END
diff --git a/libcruft/lapack/zdrscl.f b/libcruft/lapack/zdrscl.f
new file mode 100644
index 0000000..11686d0
--- /dev/null
+++ b/libcruft/lapack/zdrscl.f
@@ -0,0 +1,114 @@
+      SUBROUTINE ZDRSCL( N, SA, SX, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      DOUBLE PRECISION   SA
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         SX( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZDRSCL multiplies an n-element complex vector x by the real scalar
+*  1/a.  This is done without overflow or underflow as long as
+*  the final result x/a does not overflow or underflow.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of components of the vector x.
+*
+*  SA      (input) DOUBLE PRECISION
+*          The scalar a which is used to divide each component of x.
+*          SA must be >= 0, or the subroutine will divide by zero.
+*
+*  SX      (input/output) COMPLEX*16 array, dimension
+*                         (1+(N-1)*abs(INCX))
+*          The n-element vector x.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector SX.
+*          > 0:  SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i),     1< i<= n
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      DOUBLE PRECISION   BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, ZDSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Initialize the denominator to SA and the numerator to 1.
+*
+      CDEN = SA
+      CNUM = ONE
+*
+   10 CONTINUE
+      CDEN1 = CDEN*SMLNUM
+      CNUM1 = CNUM / BIGNUM
+      IF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN
+*
+*        Pre-multiply X by SMLNUM if CDEN is large compared to CNUM.
+*
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CDEN = CDEN1
+      ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN
+*
+*        Pre-multiply X by BIGNUM if CDEN is small compared to CNUM.
+*
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CNUM = CNUM1
+      ELSE
+*
+*        Multiply X by CNUM / CDEN and return.
+*
+         MUL = CNUM / CDEN
+         DONE = .TRUE.
+      END IF
+*
+*     Scale the vector X by MUL
+*
+      CALL ZDSCAL( N, MUL, SX, INCX )
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of ZDRSCL
+*
+      END
diff --git a/libcruft/lapack/zgbcon.f b/libcruft/lapack/zgbcon.f
new file mode 100644
index 0000000..b99cfe2
--- /dev/null
+++ b/libcruft/lapack/zgbcon.f
@@ -0,0 +1,234 @@
+      SUBROUTINE ZGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,
+     $                   WORK, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, KL, KU, LDAB, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGBCON estimates the reciprocal of the condition number of a complex
+*  general band matrix A, in either the 1-norm or the infinity-norm,
+*  using the LU factorization computed by ZGBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input) COMPLEX*16 array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by ZGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, J, JP, KASE, KASE1, KD, LM
+      DOUBLE PRECISION   AINVNM, SCALE, SMLNUM
+      COMPLEX*16         T, ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH
+      COMPLEX*16         ZDOTC
+      EXTERNAL           LSAME, IZAMAX, DLAMCH, ZDOTC
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZAXPY, ZDRSCL, ZLACN2, ZLATBS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.2*KL+KU+1 ) THEN
+         INFO = -6
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KD = KL + KU + 1
+      LNOTI = KL.GT.0
+      KASE = 0
+   10 CONTINUE
+      CALL ZLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            IF( LNOTI ) THEN
+               DO 20 J = 1, N - 1
+                  LM = MIN( KL, N-J )
+                  JP = IPIV( J )
+                  T = WORK( JP )
+                  IF( JP.NE.J ) THEN
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+                  CALL ZAXPY( LM, -T, AB( KD+1, J ), 1, WORK( J+1 ), 1 )
+   20          CONTINUE
+            END IF
+*
+*           Multiply by inv(U).
+*
+            CALL ZLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KL+KU, AB, LDAB, WORK, SCALE, RWORK, INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL ZLATBS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, KL+KU, AB, LDAB, WORK, SCALE, RWORK,
+     $                   INFO )
+*
+*           Multiply by inv(L').
+*
+            IF( LNOTI ) THEN
+               DO 30 J = N - 1, 1, -1
+                  LM = MIN( KL, N-J )
+                  WORK( J ) = WORK( J ) - ZDOTC( LM, AB( KD+1, J ), 1,
+     $                        WORK( J+1 ), 1 )
+                  JP = IPIV( J )
+                  IF( JP.NE.J ) THEN
+                     T = WORK( JP )
+                     WORK( JP ) = WORK( J )
+                     WORK( J ) = T
+                  END IF
+   30          CONTINUE
+            END IF
+         END IF
+*
+*        Divide X by 1/SCALE if doing so will not cause overflow.
+*
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = IZAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 40
+            CALL ZDRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of ZGBCON
+*
+      END
diff --git a/libcruft/lapack/zgbtf2.f b/libcruft/lapack/zgbtf2.f
new file mode 100644
index 0000000..e722d54
--- /dev/null
+++ b/libcruft/lapack/zgbtf2.f
@@ -0,0 +1,202 @@
+      SUBROUTINE ZGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGBTF2 computes an LU factorization of a complex m-by-n band matrix
+*  A using partial pivoting with row interchanges.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) COMPLEX*16 array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U, because of fill-in resulting from the row
+*  interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, JP, JU, KM, KV
+*     ..
+*     .. External Functions ..
+      INTEGER            IZAMAX
+      EXTERNAL           IZAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGERU, ZSCAL, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in.
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Gaussian elimination with partial pivoting
+*
+*     Set fill-in elements in columns KU+2 to KV to zero.
+*
+      DO 20 J = KU + 2, MIN( KV, N )
+         DO 10 I = KV - J + 2, KL
+            AB( I, J ) = ZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     JU is the index of the last column affected by the current stage
+*     of the factorization.
+*
+      JU = 1
+*
+      DO 40 J = 1, MIN( M, N )
+*
+*        Set fill-in elements in column J+KV to zero.
+*
+         IF( J+KV.LE.N ) THEN
+            DO 30 I = 1, KL
+               AB( I, J+KV ) = ZERO
+   30       CONTINUE
+         END IF
+*
+*        Find pivot and test for singularity. KM is the number of
+*        subdiagonal elements in the current column.
+*
+         KM = MIN( KL, M-J )
+         JP = IZAMAX( KM+1, AB( KV+1, J ), 1 )
+         IPIV( J ) = JP + J - 1
+         IF( AB( KV+JP, J ).NE.ZERO ) THEN
+            JU = MAX( JU, MIN( J+KU+JP-1, N ) )
+*
+*           Apply interchange to columns J to JU.
+*
+            IF( JP.NE.1 )
+     $         CALL ZSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1,
+     $                     AB( KV+1, J ), LDAB-1 )
+            IF( KM.GT.0 ) THEN
+*
+*              Compute multipliers.
+*
+               CALL ZSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 )
+*
+*              Update trailing submatrix within the band.
+*
+               IF( JU.GT.J )
+     $            CALL ZGERU( KM, JU-J, -ONE, AB( KV+2, J ), 1,
+     $                        AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ),
+     $                        LDAB-1 )
+            END IF
+         ELSE
+*
+*           If pivot is zero, set INFO to the index of the pivot
+*           unless a zero pivot has already been found.
+*
+            IF( INFO.EQ.0 )
+     $         INFO = J
+         END IF
+   40 CONTINUE
+      RETURN
+*
+*     End of ZGBTF2
+*
+      END
diff --git a/libcruft/lapack/zgbtrf.f b/libcruft/lapack/zgbtrf.f
new file mode 100644
index 0000000..3d6f21a
--- /dev/null
+++ b/libcruft/lapack/zgbtrf.f
@@ -0,0 +1,442 @@
+      SUBROUTINE ZGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, KL, KU, LDAB, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGBTRF computes an LU factorization of a complex m-by-n band matrix A
+*  using partial pivoting with row interchanges.
+*
+*  This is the blocked version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  AB      (input/output) COMPLEX*16 array, dimension (LDAB,N)
+*          On entry, the matrix A in band storage, in rows KL+1 to
+*          2*KL+KU+1; rows 1 to KL of the array need not be set.
+*          The j-th column of A is stored in the j-th column of the
+*          array AB as follows:
+*          AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)
+*
+*          On exit, details of the factorization: U is stored as an
+*          upper triangular band matrix with KL+KU superdiagonals in
+*          rows 1 to KL+KU+1, and the multipliers used during the
+*          factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
+*          See below for further details.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = +i, U(i,i) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  M = N = 6, KL = 2, KU = 1:
+*
+*  On entry:                       On exit:
+*
+*      *    *    *    +    +    +       *    *    *   u14  u25  u36
+*      *    *    +    +    +    +       *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*     a21  a32  a43  a54  a65   *      m21  m32  m43  m54  m65   *
+*     a31  a42  a53  a64   *    *      m31  m42  m53  m64   *    *
+*
+*  Array elements marked * are not used by the routine; elements marked
+*  + need not be set on entry, but are required by the routine to store
+*  elements of U because of fill-in resulting from the row interchanges.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 64, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP,
+     $                   JU, K2, KM, KV, NB, NW
+      COMPLEX*16         TEMP
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         WORK13( LDWORK, NBMAX ),
+     $                   WORK31( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV, IZAMAX
+      EXTERNAL           ILAENV, IZAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZCOPY, ZGBTF2, ZGEMM, ZGERU, ZLASWP,
+     $                   ZSCAL, ZSWAP, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     KV is the number of superdiagonals in the factor U, allowing for
+*     fill-in
+*
+      KV = KU + KL
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KL+KV+1 ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'ZGBTRF', ' ', M, N, KL, KU )
+*
+*     The block size must not exceed the limit set by the size of the
+*     local arrays WORK13 and WORK31.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KL ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+*        Zero the superdiagonal elements of the work array WORK13
+*
+         DO 20 J = 1, NB
+            DO 10 I = 1, J - 1
+               WORK13( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Zero the subdiagonal elements of the work array WORK31
+*
+         DO 40 J = 1, NB
+            DO 30 I = J + 1, NB
+               WORK31( I, J ) = ZERO
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Gaussian elimination with partial pivoting
+*
+*        Set fill-in elements in columns KU+2 to KV to zero
+*
+         DO 60 J = KU + 2, MIN( KV, N )
+            DO 50 I = KV - J + 2, KL
+               AB( I, J ) = ZERO
+   50       CONTINUE
+   60    CONTINUE
+*
+*        JU is the index of the last column affected by the current
+*        stage of the factorization
+*
+         JU = 1
+*
+         DO 180 J = 1, MIN( M, N ), NB
+            JB = MIN( NB, MIN( M, N )-J+1 )
+*
+*           The active part of the matrix is partitioned
+*
+*              A11   A12   A13
+*              A21   A22   A23
+*              A31   A32   A33
+*
+*           Here A11, A21 and A31 denote the current block of JB columns
+*           which is about to be factorized. The number of rows in the
+*           partitioning are JB, I2, I3 respectively, and the numbers
+*           of columns are JB, J2, J3. The superdiagonal elements of A13
+*           and the subdiagonal elements of A31 lie outside the band.
+*
+            I2 = MIN( KL-JB, M-J-JB+1 )
+            I3 = MIN( JB, M-J-KL+1 )
+*
+*           J2 and J3 are computed after JU has been updated.
+*
+*           Factorize the current block of JB columns
+*
+            DO 80 JJ = J, J + JB - 1
+*
+*              Set fill-in elements in column JJ+KV to zero
+*
+               IF( JJ+KV.LE.N ) THEN
+                  DO 70 I = 1, KL
+                     AB( I, JJ+KV ) = ZERO
+   70             CONTINUE
+               END IF
+*
+*              Find pivot and test for singularity. KM is the number of
+*              subdiagonal elements in the current column.
+*
+               KM = MIN( KL, M-JJ )
+               JP = IZAMAX( KM+1, AB( KV+1, JJ ), 1 )
+               IPIV( JJ ) = JP + JJ - J
+               IF( AB( KV+JP, JJ ).NE.ZERO ) THEN
+                  JU = MAX( JU, MIN( JJ+KU+JP-1, N ) )
+                  IF( JP.NE.1 ) THEN
+*
+*                    Apply interchange to columns J to J+JB-1
+*
+                     IF( JP+JJ-1.LT.J+KL ) THEN
+*
+                        CALL ZSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              AB( KV+JP+JJ-J, J ), LDAB-1 )
+                     ELSE
+*
+*                       The interchange affects columns J to JJ-1 of A31
+*                       which are stored in the work array WORK31
+*
+                        CALL ZSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                              WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                        CALL ZSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1,
+     $                              AB( KV+JP, JJ ), LDAB-1 )
+                     END IF
+                  END IF
+*
+*                 Compute multipliers
+*
+                  CALL ZSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ),
+     $                        1 )
+*
+*                 Update trailing submatrix within the band and within
+*                 the current block. JM is the index of the last column
+*                 which needs to be updated.
+*
+                  JM = MIN( JU, J+JB-1 )
+                  IF( JM.GT.JJ )
+     $               CALL ZGERU( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1,
+     $                           AB( KV, JJ+1 ), LDAB-1,
+     $                           AB( KV+1, JJ+1 ), LDAB-1 )
+               ELSE
+*
+*                 If pivot is zero, set INFO to the index of the pivot
+*                 unless a zero pivot has already been found.
+*
+                  IF( INFO.EQ.0 )
+     $               INFO = JJ
+               END IF
+*
+*              Copy current column of A31 into the work array WORK31
+*
+               NW = MIN( JJ-J+1, I3 )
+               IF( NW.GT.0 )
+     $            CALL ZCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1,
+     $                        WORK31( 1, JJ-J+1 ), 1 )
+   80       CONTINUE
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply the row interchanges to the other blocks.
+*
+               J2 = MIN( JU-J+1, KV ) - JB
+               J3 = MAX( 0, JU-J-KV+1 )
+*
+*              Use ZLASWP to apply the row interchanges to A12, A22, and
+*              A32.
+*
+               CALL ZLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB,
+     $                      IPIV( J ), 1 )
+*
+*              Adjust the pivot indices.
+*
+               DO 90 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+   90          CONTINUE
+*
+*              Apply the row interchanges to A13, A23, and A33
+*              columnwise.
+*
+               K2 = J - 1 + JB + J2
+               DO 110 I = 1, J3
+                  JJ = K2 + I
+                  DO 100 II = J + I - 1, J + JB - 1
+                     IP = IPIV( II )
+                     IF( IP.NE.II ) THEN
+                        TEMP = AB( KV+1+II-JJ, JJ )
+                        AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ )
+                        AB( KV+1+IP-JJ, JJ ) = TEMP
+                     END IF
+  100             CONTINUE
+  110          CONTINUE
+*
+*              Update the relevant part of the trailing submatrix
+*
+               IF( J2.GT.0 ) THEN
+*
+*                 Update A12
+*
+                  CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J2, ONE, AB( KV+1, J ), LDAB-1,
+     $                        AB( KV+1-JB, J+JB ), LDAB-1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A22
+*
+                     CALL ZGEMM( 'No transpose', 'No transpose', I2, J2,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+1, J+JB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A32
+*
+                     CALL ZGEMM( 'No transpose', 'No transpose', I3, J2,
+     $                           JB, -ONE, WORK31, LDWORK,
+     $                           AB( KV+1-JB, J+JB ), LDAB-1, ONE,
+     $                           AB( KV+KL+1-JB, J+JB ), LDAB-1 )
+                  END IF
+               END IF
+*
+               IF( J3.GT.0 ) THEN
+*
+*                 Copy the lower triangle of A13 into the work array
+*                 WORK13
+*
+                  DO 130 JJ = 1, J3
+                     DO 120 II = JJ, JB
+                        WORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 )
+  120                CONTINUE
+  130             CONTINUE
+*
+*                 Update A13 in the work array
+*
+                  CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Unit',
+     $                        JB, J3, ONE, AB( KV+1, J ), LDAB-1,
+     $                        WORK13, LDWORK )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A23
+*
+                     CALL ZGEMM( 'No transpose', 'No transpose', I2, J3,
+     $                           JB, -ONE, AB( KV+1+JB, J ), LDAB-1,
+     $                           WORK13, LDWORK, ONE, AB( 1+JB, J+KV ),
+     $                           LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Update A33
+*
+                     CALL ZGEMM( 'No transpose', 'No transpose', I3, J3,
+     $                           JB, -ONE, WORK31, LDWORK, WORK13,
+     $                           LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 )
+                  END IF
+*
+*                 Copy the lower triangle of A13 back into place
+*
+                  DO 150 JJ = 1, J3
+                     DO 140 II = JJ, JB
+                        AB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ )
+  140                CONTINUE
+  150             CONTINUE
+               END IF
+            ELSE
+*
+*              Adjust the pivot indices.
+*
+               DO 160 I = J, J + JB - 1
+                  IPIV( I ) = IPIV( I ) + J - 1
+  160          CONTINUE
+            END IF
+*
+*           Partially undo the interchanges in the current block to
+*           restore the upper triangular form of A31 and copy the upper
+*           triangle of A31 back into place
+*
+            DO 170 JJ = J + JB - 1, J, -1
+               JP = IPIV( JJ ) - JJ + 1
+               IF( JP.NE.1 ) THEN
+*
+*                 Apply interchange to columns J to JJ-1
+*
+                  IF( JP+JJ-1.LT.J+KL ) THEN
+*
+*                    The interchange does not affect A31
+*
+                     CALL ZSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           AB( KV+JP+JJ-J, J ), LDAB-1 )
+                  ELSE
+*
+*                    The interchange does affect A31
+*
+                     CALL ZSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,
+     $                           WORK31( JP+JJ-J-KL, 1 ), LDWORK )
+                  END IF
+               END IF
+*
+*              Copy the current column of A31 back into place
+*
+               NW = MIN( I3, JJ-J+1 )
+               IF( NW.GT.0 )
+     $            CALL ZCOPY( NW, WORK31( 1, JJ-J+1 ), 1,
+     $                        AB( KV+KL+1-JJ+J, JJ ), 1 )
+  170       CONTINUE
+  180    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZGBTRF
+*
+      END
diff --git a/libcruft/lapack/zgbtrs.f b/libcruft/lapack/zgbtrs.f
new file mode 100644
index 0000000..bd61a86
--- /dev/null
+++ b/libcruft/lapack/zgbtrs.f
@@ -0,0 +1,214 @@
+      SUBROUTINE ZGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, KL, KU, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGBTRS solves a system of linear equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B
+*  with a general band matrix A using the LU factorization computed
+*  by ZGBTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KL      (input) INTEGER
+*          The number of subdiagonals within the band of A.  KL >= 0.
+*
+*  KU      (input) INTEGER
+*          The number of superdiagonals within the band of A.  KU >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) COMPLEX*16 array, dimension (LDAB,N)
+*          Details of the LU factorization of the band matrix A, as
+*          computed by ZGBTRF.  U is stored as an upper triangular band
+*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
+*          the multipliers used during the factorization are stored in
+*          rows KL+KU+2 to 2*KL+KU+1.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= 2*KL+KU+1.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= N, row i of the matrix was
+*          interchanged with row IPIV(i).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LNOTI, NOTRAN
+      INTEGER            I, J, KD, L, LM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMV, ZGERU, ZLACGV, ZSWAP, ZTBSV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KL.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( KU.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      KD = KU + KL + 1
+      LNOTI = KL.GT.0
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve  A*X = B.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+*        L is represented as a product of permutations and unit lower
+*        triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1),
+*        where each transformation L(i) is a rank-one modification of
+*        the identity matrix.
+*
+         IF( LNOTI ) THEN
+            DO 10 J = 1, N - 1
+               LM = MIN( KL, N-J )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL ZSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+               CALL ZGERU( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ),
+     $                     LDB, B( J+1, 1 ), LDB )
+   10       CONTINUE
+         END IF
+*
+         DO 20 I = 1, NRHS
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU,
+     $                  AB, LDAB, B( 1, I ), 1 )
+   20    CONTINUE
+*
+      ELSE IF( LSAME( TRANS, 'T' ) ) THEN
+*
+*        Solve A**T * X = B.
+*
+         DO 30 I = 1, NRHS
+*
+*           Solve U**T * X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB,
+     $                  LDAB, B( 1, I ), 1 )
+   30    CONTINUE
+*
+*        Solve L**T * X = B, overwriting B with X.
+*
+         IF( LNOTI ) THEN
+            DO 40 J = N - 1, 1, -1
+               LM = MIN( KL, N-J )
+               CALL ZGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ),
+     $                     LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL ZSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+   40       CONTINUE
+         END IF
+*
+      ELSE
+*
+*        Solve A**H * X = B.
+*
+         DO 50 I = 1, NRHS
+*
+*           Solve U**H * X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Upper', 'Conjugate transpose', 'Non-unit', N,
+     $                  KL+KU, AB, LDAB, B( 1, I ), 1 )
+   50    CONTINUE
+*
+*        Solve L**H * X = B, overwriting B with X.
+*
+         IF( LNOTI ) THEN
+            DO 60 J = N - 1, 1, -1
+               LM = MIN( KL, N-J )
+               CALL ZLACGV( NRHS, B( J, 1 ), LDB )
+               CALL ZGEMV( 'Conjugate transpose', LM, NRHS, -ONE,
+     $                     B( J+1, 1 ), LDB, AB( KD+1, J ), 1, ONE,
+     $                     B( J, 1 ), LDB )
+               CALL ZLACGV( NRHS, B( J, 1 ), LDB )
+               L = IPIV( J )
+               IF( L.NE.J )
+     $            CALL ZSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )
+   60       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of ZGBTRS
+*
+      END
diff --git a/libcruft/lapack/zgebak.f b/libcruft/lapack/zgebak.f
new file mode 100644
index 0000000..1023601
--- /dev/null
+++ b/libcruft/lapack/zgebak.f
@@ -0,0 +1,189 @@
+      SUBROUTINE ZGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   SCALE( * )
+      COMPLEX*16         V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEBAK forms the right or left eigenvectors of a complex general
+*  matrix by backward transformation on the computed eigenvectors of the
+*  balanced matrix output by ZGEBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N', do nothing, return immediately;
+*          = 'P', do backward transformation for permutation only;
+*          = 'S', do backward transformation for scaling only;
+*          = 'B', do backward transformations for both permutation and
+*                 scaling.
+*          JOB must be the same as the argument JOB supplied to ZGEBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by ZGEBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  SCALE   (input) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutation and scaling factors, as returned
+*          by ZGEBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) COMPLEX*16 array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by ZHSEIN or ZTREVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, II, K
+      DOUBLE PRECISION   S
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDSCAL, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -7
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               S = SCALE( I )
+               CALL ZDSCAL( M, S, V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               S = ONE / SCALE( I )
+               CALL ZDSCAL( M, S, V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+*
+      END IF
+*
+*     Backward permutation
+*
+*     For  I = ILO-1 step -1 until 1,
+*              IHI+1 step 1 until N do --
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+         IF( RIGHTV ) THEN
+            DO 40 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 40
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL ZSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+         END IF
+*
+         IF( LEFTV ) THEN
+            DO 50 II = 1, N
+               I = II
+               IF( I.GE.ILO .AND. I.LE.IHI )
+     $            GO TO 50
+               IF( I.LT.ILO )
+     $            I = ILO - II
+               K = SCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 50
+               CALL ZSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   50       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZGEBAK
+*
+      END
diff --git a/libcruft/lapack/zgebal.f b/libcruft/lapack/zgebal.f
new file mode 100644
index 0000000..67ac2e1
--- /dev/null
+++ b/libcruft/lapack/zgebal.f
@@ -0,0 +1,330 @@
+      SUBROUTINE ZGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   SCALE( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEBAL balances a general complex matrix A.  This involves, first,
+*  permuting A by a similarity transformation to isolate eigenvalues
+*  in the first 1 to ILO-1 and last IHI+1 to N elements on the
+*  diagonal; and second, applying a diagonal similarity transformation
+*  to rows and columns ILO to IHI to make the rows and columns as
+*  close in norm as possible.  Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrix, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, SCALE(I) = 1.0
+*                  for i = 1,...,N;
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit,  A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  SCALE   (output) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and scaling factors applied to
+*          A.  If P(j) is the index of the row and column interchanged
+*          with row and column j and D(j) is the scaling factor
+*          applied to row and column j, then
+*          SCALE(j) = P(j)    for j = 1,...,ILO-1
+*                   = D(j)    for j = ILO,...,IHI
+*                   = P(j)    for j = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The permutations consist of row and column interchanges which put
+*  the matrix in the form
+*
+*             ( T1   X   Y  )
+*     P A P = (  0   B   Z  )
+*             (  0   0   T2 )
+*
+*  where T1 and T2 are upper triangular matrices whose eigenvalues lie
+*  along the diagonal.  The column indices ILO and IHI mark the starting
+*  and ending columns of the submatrix B. Balancing consists of applying
+*  a diagonal similarity transformation inv(D) * B * D to make the
+*  1-norms of each row of B and its corresponding column nearly equal.
+*  The output matrix is
+*
+*     ( T1     X*D          Y    )
+*     (  0  inv(D)*B*D  inv(D)*Z ).
+*     (  0      0           T2   )
+*
+*  Information about the permutations P and the diagonal matrix D is
+*  returned in the vector SCALE.
+*
+*  This subroutine is based on the EISPACK routine CBAL.
+*
+*  Modified by Tzu-Yi Chen, Computer Science Division, University of
+*    California at Berkeley, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   SCLFAC
+      PARAMETER          ( SCLFAC = 2.0D+0 )
+      DOUBLE PRECISION   FACTOR
+      PARAMETER          ( FACTOR = 0.95D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOCONV
+      INTEGER            I, ICA, IEXC, IRA, J, K, L, M
+      DOUBLE PRECISION   C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,
+     $                   SFMIN2
+      COMPLEX*16         CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IZAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDSCAL, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MAX, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEBAL', -INFO )
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+*
+      IF( N.EQ.0 )
+     $   GO TO 210
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         DO 10 I = 1, N
+            SCALE( I ) = ONE
+   10    CONTINUE
+         GO TO 210
+      END IF
+*
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 120
+*
+*     Permutation to isolate eigenvalues if possible
+*
+      GO TO 50
+*
+*     Row and column exchange.
+*
+   20 CONTINUE
+      SCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 30
+*
+      CALL ZSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL ZSWAP( N-K+1, A( J, K ), LDA, A( M, K ), LDA )
+*
+   30 CONTINUE
+      GO TO ( 40, 80 )IEXC
+*
+*     Search for rows isolating an eigenvalue and push them down.
+*
+   40 CONTINUE
+      IF( L.EQ.1 )
+     $   GO TO 210
+      L = L - 1
+*
+   50 CONTINUE
+      DO 70 J = L, 1, -1
+*
+         DO 60 I = 1, L
+            IF( I.EQ.J )
+     $         GO TO 60
+            IF( DBLE( A( J, I ) ).NE.ZERO .OR. DIMAG( A( J, I ) ).NE.
+     $          ZERO )GO TO 70
+   60    CONTINUE
+*
+         M = L
+         IEXC = 1
+         GO TO 20
+   70 CONTINUE
+*
+      GO TO 90
+*
+*     Search for columns isolating an eigenvalue and push them left.
+*
+   80 CONTINUE
+      K = K + 1
+*
+   90 CONTINUE
+      DO 110 J = K, L
+*
+         DO 100 I = K, L
+            IF( I.EQ.J )
+     $         GO TO 100
+            IF( DBLE( A( I, J ) ).NE.ZERO .OR. DIMAG( A( I, J ) ).NE.
+     $          ZERO )GO TO 110
+  100    CONTINUE
+*
+         M = K
+         IEXC = 2
+         GO TO 20
+  110 CONTINUE
+*
+  120 CONTINUE
+      DO 130 I = K, L
+         SCALE( I ) = ONE
+  130 CONTINUE
+*
+      IF( LSAME( JOB, 'P' ) )
+     $   GO TO 210
+*
+*     Balance the submatrix in rows K to L.
+*
+*     Iterative loop for norm reduction
+*
+      SFMIN1 = DLAMCH( 'S' ) / DLAMCH( 'P' )
+      SFMAX1 = ONE / SFMIN1
+      SFMIN2 = SFMIN1*SCLFAC
+      SFMAX2 = ONE / SFMIN2
+  140 CONTINUE
+      NOCONV = .FALSE.
+*
+      DO 200 I = K, L
+         C = ZERO
+         R = ZERO
+*
+         DO 150 J = K, L
+            IF( J.EQ.I )
+     $         GO TO 150
+            C = C + CABS1( A( J, I ) )
+            R = R + CABS1( A( I, J ) )
+  150    CONTINUE
+         ICA = IZAMAX( L, A( 1, I ), 1 )
+         CA = ABS( A( ICA, I ) )
+         IRA = IZAMAX( N-K+1, A( I, K ), LDA )
+         RA = ABS( A( I, IRA+K-1 ) )
+*
+*        Guard against zero C or R due to underflow.
+*
+         IF( C.EQ.ZERO .OR. R.EQ.ZERO )
+     $      GO TO 200
+         G = R / SCLFAC
+         F = ONE
+         S = C + R
+  160    CONTINUE
+         IF( C.GE.G .OR. MAX( F, C, CA ).GE.SFMAX2 .OR.
+     $       MIN( R, G, RA ).LE.SFMIN2 )GO TO 170
+         F = F*SCLFAC
+         C = C*SCLFAC
+         CA = CA*SCLFAC
+         R = R / SCLFAC
+         G = G / SCLFAC
+         RA = RA / SCLFAC
+         GO TO 160
+*
+  170    CONTINUE
+         G = C / SCLFAC
+  180    CONTINUE
+         IF( G.LT.R .OR. MAX( R, RA ).GE.SFMAX2 .OR.
+     $       MIN( F, C, G, CA ).LE.SFMIN2 )GO TO 190
+         F = F / SCLFAC
+         C = C / SCLFAC
+         G = G / SCLFAC
+         CA = CA / SCLFAC
+         R = R*SCLFAC
+         RA = RA*SCLFAC
+         GO TO 180
+*
+*        Now balance.
+*
+  190    CONTINUE
+         IF( ( C+R ).GE.FACTOR*S )
+     $      GO TO 200
+         IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THEN
+            IF( F*SCALE( I ).LE.SFMIN1 )
+     $         GO TO 200
+         END IF
+         IF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THEN
+            IF( SCALE( I ).GE.SFMAX1 / F )
+     $         GO TO 200
+         END IF
+         G = ONE / F
+         SCALE( I ) = SCALE( I )*F
+         NOCONV = .TRUE.
+*
+         CALL ZDSCAL( N-K+1, G, A( I, K ), LDA )
+         CALL ZDSCAL( L, F, A( 1, I ), 1 )
+*
+  200 CONTINUE
+*
+      IF( NOCONV )
+     $   GO TO 140
+*
+  210 CONTINUE
+      ILO = K
+      IHI = L
+*
+      RETURN
+*
+*     End of ZGEBAL
+*
+      END
diff --git a/libcruft/lapack/zgebd2.f b/libcruft/lapack/zgebd2.f
new file mode 100644
index 0000000..5ba52e8
--- /dev/null
+++ b/libcruft/lapack/zgebd2.f
@@ -0,0 +1,250 @@
+      SUBROUTINE ZGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+      COMPLEX*16         A( LDA, * ), TAUP( * ), TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEBD2 reduces a complex general m by n matrix A to upper or lower
+*  real bidiagonal form B by a unitary transformation: Q' * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the unitary matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the unitary matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) COMPLEX*16 array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix Q. See Further Details.
+*
+*  TAUP    (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix P. See Further Details.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (max(M,N))
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors; v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in
+*  A(i+1:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in
+*  A(i,i+2:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, v and u are complex vectors;
+*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);
+*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);
+*  tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLACGV, ZLARF, ZLARFG
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'ZGEBD2', -INFO )
+         RETURN
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, N
+*
+*           Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+            ALPHA = A( I, I )
+            CALL ZLARFG( M-I+1, ALPHA, A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = ALPHA
+            A( I, I ) = ONE
+*
+*           Apply H(i)' to A(i:m,i+1:n) from the left
+*
+            IF( I.LT.N )
+     $         CALL ZLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
+     $                     DCONJG( TAUQ( I ) ), A( I, I+1 ), LDA, WORK )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector G(i) to annihilate
+*              A(i,i+2:n)
+*
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+               ALPHA = A( I, I+1 )
+               CALL ZLARFG( N-I, ALPHA, A( I, MIN( I+2, N ) ), LDA,
+     $                      TAUP( I ) )
+               E( I ) = ALPHA
+               A( I, I+1 ) = ONE
+*
+*              Apply G(i) to A(i+1:m,i+1:n) from the right
+*
+               CALL ZLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA,
+     $                     TAUP( I ), A( I+1, I+1 ), LDA, WORK )
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+               A( I, I+1 ) = E( I )
+            ELSE
+               TAUP( I ) = ZERO
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, M
+*
+*           Generate elementary reflector G(i) to annihilate A(i,i+1:n)
+*
+            CALL ZLACGV( N-I+1, A( I, I ), LDA )
+            ALPHA = A( I, I )
+            CALL ZLARFG( N-I+1, ALPHA, A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = ALPHA
+            A( I, I ) = ONE
+*
+*           Apply G(i) to A(i+1:m,i:n) from the right
+*
+            IF( I.LT.M )
+     $         CALL ZLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     TAUP( I ), A( I+1, I ), LDA, WORK )
+            CALL ZLACGV( N-I+1, A( I, I ), LDA )
+            A( I, I ) = D( I )
+*
+            IF( I.LT.M ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:m,i)
+*
+               ALPHA = A( I+1, I )
+               CALL ZLARFG( M-I, ALPHA, A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = ALPHA
+               A( I+1, I ) = ONE
+*
+*              Apply H(i)' to A(i+1:m,i+1:n) from the left
+*
+               CALL ZLARF( 'Left', M-I, N-I, A( I+1, I ), 1,
+     $                     DCONJG( TAUQ( I ) ), A( I+1, I+1 ), LDA,
+     $                     WORK )
+               A( I+1, I ) = E( I )
+            ELSE
+               TAUQ( I ) = ZERO
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZGEBD2
+*
+      END
diff --git a/libcruft/lapack/zgebrd.f b/libcruft/lapack/zgebrd.f
new file mode 100644
index 0000000..4f97bd7
--- /dev/null
+++ b/libcruft/lapack/zgebrd.f
@@ -0,0 +1,268 @@
+      SUBROUTINE ZGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+      COMPLEX*16         A( LDA, * ), TAUP( * ), TAUQ( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEBRD reduces a general complex M-by-N matrix A to upper or lower
+*  bidiagonal form B by a unitary transformation: Q**H * A * P = B.
+*
+*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N general matrix to be reduced.
+*          On exit,
+*          if m >= n, the diagonal and the first superdiagonal are
+*            overwritten with the upper bidiagonal matrix B; the
+*            elements below the diagonal, with the array TAUQ, represent
+*            the unitary matrix Q as a product of elementary
+*            reflectors, and the elements above the first superdiagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors;
+*          if m < n, the diagonal and the first subdiagonal are
+*            overwritten with the lower bidiagonal matrix B; the
+*            elements below the first subdiagonal, with the array TAUQ,
+*            represent the unitary matrix Q as a product of
+*            elementary reflectors, and the elements above the diagonal,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The diagonal elements of the bidiagonal matrix B:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (min(M,N)-1)
+*          The off-diagonal elements of the bidiagonal matrix B:
+*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
+*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
+*
+*  TAUQ    (output) COMPLEX*16 array dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix Q. See Further Details.
+*
+*  TAUP    (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix P. See Further Details.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,M,N).
+*          For optimum performance LWORK >= (M+N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*  If m >= n,
+*
+*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors; v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in
+*  A(i+1:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in
+*  A(i,i+2:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n,
+*
+*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors; v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in
+*  A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The contents of A on exit are illustrated by the following examples:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 )
+*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 )
+*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 )
+*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 )
+*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 )
+*    (  v1  v2  v3  v4  v5 )
+*
+*  where d and e denote diagonal and off-diagonal elements of B, vi
+*  denotes an element of the vector defining H(i), and ui an element of
+*  the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LDWRKX, LDWRKY, LWKOPT, MINMN, NB,
+     $                   NBMIN, NX
+      DOUBLE PRECISION   WS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEBD2, ZGEMM, ZLABRD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MAX( 1, ILAENV( 1, 'ZGEBRD', ' ', M, N, -1, -1 ) )
+      LWKOPT = ( M+N )*NB
+      WORK( 1 ) = DBLE( LWKOPT )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.LT.0 ) THEN
+         CALL XERBLA( 'ZGEBRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      MINMN = MIN( M, N )
+      IF( MINMN.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      WS = MAX( M, N )
+      LDWRKX = M
+      LDWRKY = N
+*
+      IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN
+*
+*        Set the crossover point NX.
+*
+         NX = MAX( NB, ILAENV( 3, 'ZGEBRD', ' ', M, N, -1, -1 ) )
+*
+*        Determine when to switch from blocked to unblocked code.
+*
+         IF( NX.LT.MINMN ) THEN
+            WS = ( M+N )*NB
+            IF( LWORK.LT.WS ) THEN
+*
+*              Not enough work space for the optimal NB, consider using
+*              a smaller block size.
+*
+               NBMIN = ILAENV( 2, 'ZGEBRD', ' ', M, N, -1, -1 )
+               IF( LWORK.GE.( M+N )*NBMIN ) THEN
+                  NB = LWORK / ( M+N )
+               ELSE
+                  NB = 1
+                  NX = MINMN
+               END IF
+            END IF
+         END IF
+      ELSE
+         NX = MINMN
+      END IF
+*
+      DO 30 I = 1, MINMN - NX, NB
+*
+*        Reduce rows and columns i:i+ib-1 to bidiagonal form and return
+*        the matrices X and Y which are needed to update the unreduced
+*        part of the matrix
+*
+         CALL ZLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ),
+     $                TAUQ( I ), TAUP( I ), WORK, LDWRKX,
+     $                WORK( LDWRKX*NB+1 ), LDWRKY )
+*
+*        Update the trailing submatrix A(i+ib:m,i+ib:n), using
+*        an update of the form  A := A - V*Y' - X*U'
+*
+         CALL ZGEMM( 'No transpose', 'Conjugate transpose', M-I-NB+1,
+     $               N-I-NB+1, NB, -ONE, A( I+NB, I ), LDA,
+     $               WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE,
+     $               A( I+NB, I+NB ), LDA )
+         CALL ZGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1,
+     $               NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA,
+     $               ONE, A( I+NB, I+NB ), LDA )
+*
+*        Copy diagonal and off-diagonal elements of B back into A
+*
+         IF( M.GE.N ) THEN
+            DO 10 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J, J+1 ) = E( J )
+   10       CONTINUE
+         ELSE
+            DO 20 J = I, I + NB - 1
+               A( J, J ) = D( J )
+               A( J+1, J ) = E( J )
+   20       CONTINUE
+         END IF
+   30 CONTINUE
+*
+*     Use unblocked code to reduce the remainder of the matrix
+*
+      CALL ZGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $             TAUQ( I ), TAUP( I ), WORK, IINFO )
+      WORK( 1 ) = WS
+      RETURN
+*
+*     End of ZGEBRD
+*
+      END
diff --git a/libcruft/lapack/zgecon.f b/libcruft/lapack/zgecon.f
new file mode 100644
index 0000000..cfaaca3
--- /dev/null
+++ b/libcruft/lapack/zgecon.f
@@ -0,0 +1,193 @@
+      SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGECON estimates the reciprocal of the condition number of a general
+*  complex matrix A, in either the 1-norm or the infinity-norm, using
+*  the LU factorization computed by ZGETRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by ZGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          If NORM = '1' or 'O', the 1-norm of the original matrix A.
+*          If NORM = 'I', the infinity-norm of the original matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ONENRM
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      DOUBLE PRECISION   AINVNM, SCALE, SL, SMLNUM, SU
+      COMPLEX*16         ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IZAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDRSCL, ZLACN2, ZLATRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MAX
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGECON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the norm of inv(A).
+*
+      AINVNM = ZERO
+      NORMIN = 'N'
+      IF( ONENRM ) THEN
+         KASE1 = 1
+      ELSE
+         KASE1 = 2
+      END IF
+      KASE = 0
+   10 CONTINUE
+      CALL ZLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( KASE.EQ.KASE1 ) THEN
+*
+*           Multiply by inv(L).
+*
+            CALL ZLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A,
+     $                   LDA, WORK, SL, RWORK, INFO )
+*
+*           Multiply by inv(U).
+*
+            CALL ZLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SU, RWORK( N+1 ), INFO )
+         ELSE
+*
+*           Multiply by inv(U').
+*
+            CALL ZLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, A, LDA, WORK, SU, RWORK( N+1 ),
+     $                   INFO )
+*
+*           Multiply by inv(L').
+*
+            CALL ZLATRS( 'Lower', 'Conjugate transpose', 'Unit', NORMIN,
+     $                   N, A, LDA, WORK, SL, RWORK, INFO )
+         END IF
+*
+*        Divide X by 1/(SL*SU) if doing so will not cause overflow.
+*
+         SCALE = SL*SU
+         NORMIN = 'Y'
+         IF( SCALE.NE.ONE ) THEN
+            IX = IZAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL ZDRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of ZGECON
+*
+      END
diff --git a/libcruft/lapack/zgeesx.f b/libcruft/lapack/zgeesx.f
new file mode 100644
index 0000000..b7567c3
--- /dev/null
+++ b/libcruft/lapack/zgeesx.f
@@ -0,0 +1,384 @@
+      SUBROUTINE ZGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM, W,
+     $                   VS, LDVS, RCONDE, RCONDV, WORK, LWORK, RWORK,
+     $                   BWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVS, SENSE, SORT
+      INTEGER            INFO, LDA, LDVS, LWORK, N, SDIM
+      DOUBLE PRECISION   RCONDE, RCONDV
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            BWORK( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
+*     ..
+*     .. Function Arguments ..
+      LOGICAL            SELECT
+      EXTERNAL           SELECT
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEESX computes for an N-by-N complex nonsymmetric matrix A, the
+*  eigenvalues, the Schur form T, and, optionally, the matrix of Schur
+*  vectors Z.  This gives the Schur factorization A = Z*T*(Z**H).
+*
+*  Optionally, it also orders the eigenvalues on the diagonal of the
+*  Schur form so that selected eigenvalues are at the top left;
+*  computes a reciprocal condition number for the average of the
+*  selected eigenvalues (RCONDE); and computes a reciprocal condition
+*  number for the right invariant subspace corresponding to the
+*  selected eigenvalues (RCONDV).  The leading columns of Z form an
+*  orthonormal basis for this invariant subspace.
+*
+*  For further explanation of the reciprocal condition numbers RCONDE
+*  and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where
+*  these quantities are called s and sep respectively).
+*
+*  A complex matrix is in Schur form if it is upper triangular.
+*
+*  Arguments
+*  =========
+*
+*  JOBVS   (input) CHARACTER*1
+*          = 'N': Schur vectors are not computed;
+*          = 'V': Schur vectors are computed.
+*
+*  SORT    (input) CHARACTER*1
+*          Specifies whether or not to order the eigenvalues on the
+*          diagonal of the Schur form.
+*          = 'N': Eigenvalues are not ordered;
+*          = 'S': Eigenvalues are ordered (see SELECT).
+*
+*  SELECT  (external procedure) LOGICAL FUNCTION of one COMPLEX*16 argument
+*          SELECT must be declared EXTERNAL in the calling subroutine.
+*          If SORT = 'S', SELECT is used to select eigenvalues to order
+*          to the top left of the Schur form.
+*          If SORT = 'N', SELECT is not referenced.
+*          An eigenvalue W(j) is selected if SELECT(W(j)) is true.
+*
+*  SENSE   (input) CHARACTER*1
+*          Determines which reciprocal condition numbers are computed.
+*          = 'N': None are computed;
+*          = 'E': Computed for average of selected eigenvalues only;
+*          = 'V': Computed for selected right invariant subspace only;
+*          = 'B': Computed for both.
+*          If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA, N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A is overwritten by its Schur form T.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  SDIM    (output) INTEGER
+*          If SORT = 'N', SDIM = 0.
+*          If SORT = 'S', SDIM = number of eigenvalues for which
+*                         SELECT is true.
+*
+*  W       (output) COMPLEX*16 array, dimension (N)
+*          W contains the computed eigenvalues, in the same order
+*          that they appear on the diagonal of the output Schur form T.
+*
+*  VS      (output) COMPLEX*16 array, dimension (LDVS,N)
+*          If JOBVS = 'V', VS contains the unitary matrix Z of Schur
+*          vectors.
+*          If JOBVS = 'N', VS is not referenced.
+*
+*  LDVS    (input) INTEGER
+*          The leading dimension of the array VS.  LDVS >= 1, and if
+*          JOBVS = 'V', LDVS >= N.
+*
+*  RCONDE  (output) DOUBLE PRECISION
+*          If SENSE = 'E' or 'B', RCONDE contains the reciprocal
+*          condition number for the average of the selected eigenvalues.
+*          Not referenced if SENSE = 'N' or 'V'.
+*
+*  RCONDV  (output) DOUBLE PRECISION
+*          If SENSE = 'V' or 'B', RCONDV contains the reciprocal
+*          condition number for the selected right invariant subspace.
+*          Not referenced if SENSE = 'N' or 'E'.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,2*N).
+*          Also, if SENSE = 'E' or 'V' or 'B', LWORK >= 2*SDIM*(N-SDIM),
+*          where SDIM is the number of selected eigenvalues computed by
+*          this routine.  Note that 2*SDIM*(N-SDIM) <= N*N/2. Note also
+*          that an error is only returned if LWORK < max(1,2*N), but if
+*          SENSE = 'E' or 'V' or 'B' this may not be large enough.
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates upper bound on the optimal size of the
+*          array WORK, returns this value as the first entry of the WORK
+*          array, and no error message related to LWORK is issued by
+*          XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  BWORK   (workspace) LOGICAL array, dimension (N)
+*          Not referenced if SORT = 'N'.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*          > 0: if INFO = i, and i is
+*             <= N: the QR algorithm failed to compute all the
+*                   eigenvalues; elements 1:ILO-1 and i+1:N of W
+*                   contain those eigenvalues which have converged; if
+*                   JOBVS = 'V', VS contains the transformation which
+*                   reduces A to its partially converged Schur form.
+*             = N+1: the eigenvalues could not be reordered because some
+*                   eigenvalues were too close to separate (the problem
+*                   is very ill-conditioned);
+*             = N+2: after reordering, roundoff changed values of some
+*                   complex eigenvalues so that leading eigenvalues in
+*                   the Schur form no longer satisfy SELECT=.TRUE.  This
+*                   could also be caused by underflow due to scaling.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            SCALEA, WANTSB, WANTSE, WANTSN, WANTST, WANTSV,
+     $                   WANTVS
+      INTEGER            HSWORK, I, IBAL, ICOND, IERR, IEVAL, IHI, ILO,
+     $                   ITAU, IWRK, LWRK, MAXWRK, MINWRK
+      DOUBLE PRECISION   ANRM, BIGNUM, CSCALE, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, DLASCL, XERBLA, ZCOPY, ZGEBAK, ZGEBAL,
+     $                   ZGEHRD, ZHSEQR, ZLACPY, ZLASCL, ZTRSEN, ZUNGHR
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTVS = LSAME( JOBVS, 'V' )
+      WANTST = LSAME( SORT, 'S' )
+      WANTSN = LSAME( SENSE, 'N' )
+      WANTSE = LSAME( SENSE, 'E' )
+      WANTSV = LSAME( SENSE, 'V' )
+      WANTSB = LSAME( SENSE, 'B' )
+      IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
+     $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of real workspace needed at that point in the
+*       code, as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace to real
+*       workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by ZHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.
+*       If SENSE = 'E', 'V' or 'B', then the amount of workspace needed
+*       depends on SDIM, which is computed by the routine ZTRSEN later
+*       in the code.)
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            LWRK = 1
+         ELSE
+            MAXWRK = N + N*ILAENV( 1, 'ZGEHRD', ' ', N, 1, N, 0 )
+            MINWRK = 2*N
+*
+            CALL ZHSEQR( 'S', JOBVS, N, 1, N, A, LDA, W, VS, LDVS,
+     $             WORK, -1, IEVAL )
+            HSWORK = WORK( 1 )
+*
+            IF( .NOT.WANTVS ) THEN
+               MAXWRK = MAX( MAXWRK, HSWORK )
+            ELSE
+               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
+     $                       ' ', N, 1, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, HSWORK )
+            END IF
+            LWRK = MAXWRK
+            IF( .NOT.WANTSN )
+     $         LWRK = MAX( LWRK, ( N*N )/2 )
+         END IF
+         WORK( 1 ) = LWRK
+*
+         IF( LWORK.LT.MINWRK ) THEN
+            INFO = -15
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEESX', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         SDIM = 0
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = ZLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL ZLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*
+*     Permute the matrix to make it more nearly triangular
+*     (CWorkspace: none)
+*     (RWorkspace: need N)
+*
+      IBAL = 1
+      CALL ZGEBAL( 'P', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (CWorkspace: need 2*N, prefer N+N*NB)
+*     (RWorkspace: none)
+*
+      ITAU = 1
+      IWRK = N + ITAU
+      CALL ZGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVS ) THEN
+*
+*        Copy Householder vectors to VS
+*
+         CALL ZLACPY( 'L', N, N, A, LDA, VS, LDVS )
+*
+*        Generate unitary matrix in VS
+*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+      END IF
+*
+      SDIM = 0
+*
+*     Perform QR iteration, accumulating Schur vectors in VS if desired
+*     (CWorkspace: need 1, prefer HSWORK (see comments) )
+*     (RWorkspace: none)
+*
+      IWRK = ITAU
+      CALL ZHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, W, VS, LDVS,
+     $             WORK( IWRK ), LWORK-IWRK+1, IEVAL )
+      IF( IEVAL.GT.0 )
+     $   INFO = IEVAL
+*
+*     Sort eigenvalues if desired
+*
+      IF( WANTST .AND. INFO.EQ.0 ) THEN
+         IF( SCALEA )
+     $      CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, W, N, IERR )
+         DO 10 I = 1, N
+            BWORK( I ) = SELECT( W( I ) )
+   10    CONTINUE
+*
+*        Reorder eigenvalues, transform Schur vectors, and compute
+*        reciprocal condition numbers
+*        (CWorkspace: if SENSE is not 'N', need 2*SDIM*(N-SDIM)
+*                     otherwise, need none )
+*        (RWorkspace: none)
+*
+         CALL ZTRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, W, SDIM,
+     $                RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,
+     $                ICOND )
+         IF( .NOT.WANTSN )
+     $      MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
+         IF( ICOND.EQ.-14 ) THEN
+*
+*           Not enough complex workspace
+*
+            INFO = -15
+         END IF
+      END IF
+*
+      IF( WANTVS ) THEN
+*
+*        Undo balancing
+*        (CWorkspace: none)
+*        (RWorkspace: need N)
+*
+         CALL ZGEBAK( 'P', 'R', N, ILO, IHI, RWORK( IBAL ), N, VS, LDVS,
+     $                IERR )
+      END IF
+*
+      IF( SCALEA ) THEN
+*
+*        Undo scaling for the Schur form of A
+*
+         CALL ZLASCL( 'U', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
+         CALL ZCOPY( N, A, LDA+1, W, 1 )
+         IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THEN
+            DUM( 1 ) = RCONDV
+            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
+            RCONDV = DUM( 1 )
+         END IF
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of ZGEESX
+*
+      END
diff --git a/libcruft/lapack/zgeev.f b/libcruft/lapack/zgeev.f
new file mode 100644
index 0000000..0fa6630
--- /dev/null
+++ b/libcruft/lapack/zgeev.f
@@ -0,0 +1,396 @@
+      SUBROUTINE ZGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
+     $                  WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEEV computes for an N-by-N complex nonsymmetric matrix A, the
+*  eigenvalues and, optionally, the left and/or right eigenvectors.
+*
+*  The right eigenvector v(j) of A satisfies
+*                   A * v(j) = lambda(j) * v(j)
+*  where lambda(j) is its eigenvalue.
+*  The left eigenvector u(j) of A satisfies
+*                u(j)**H * A = lambda(j) * u(j)**H
+*  where u(j)**H denotes the conjugate transpose of u(j).
+*
+*  The computed eigenvectors are normalized to have Euclidean norm
+*  equal to 1 and largest component real.
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N': left eigenvectors of A are not computed;
+*          = 'V': left eigenvectors of are computed.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N': right eigenvectors of A are not computed;
+*          = 'V': right eigenvectors of A are computed.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A. N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the N-by-N matrix A.
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  W       (output) COMPLEX*16 array, dimension (N)
+*          W contains the computed eigenvalues.
+*
+*  VL      (output) COMPLEX*16 array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
+*          after another in the columns of VL, in the same order
+*          as their eigenvalues.
+*          If JOBVL = 'N', VL is not referenced.
+*          u(j) = VL(:,j), the j-th column of VL.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1; if
+*          JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) COMPLEX*16 array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
+*          after another in the columns of VR, in the same order
+*          as their eigenvalues.
+*          If JOBVR = 'N', VR is not referenced.
+*          v(j) = VR(:,j), the j-th column of VR.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1; if
+*          JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,2*N).
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if INFO = i, the QR algorithm failed to compute all the
+*                eigenvalues, and no eigenvectors have been computed;
+*                elements and i+1:N of W contain eigenvalues which have
+*                converged.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
+      CHARACTER          SIDE
+      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, IRWORK, ITAU,
+     $                   IWRK, K, MAXWRK, MINWRK, NOUT
+      DOUBLE PRECISION   ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
+      COMPLEX*16         TMP
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            SELECT( 1 )
+      DOUBLE PRECISION   DUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, XERBLA, ZDSCAL, ZGEBAK, ZGEBAL, ZGEHRD,
+     $                   ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC, ZUNGHR
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX, ILAENV
+      DOUBLE PRECISION   DLAMCH, DZNRM2, ZLANGE
+      EXTERNAL           LSAME, IDAMAX, ILAENV, DLAMCH, DZNRM2, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, DCONJG, DIMAG, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      WANTVL = LSAME( JOBVL, 'V' )
+      WANTVR = LSAME( JOBVR, 'V' )
+      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace to real
+*       workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.
+*       HSWORK refers to the workspace preferred by ZHSEQR, as
+*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
+*       the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            MINWRK = 1
+            MAXWRK = 1
+         ELSE
+            MAXWRK = N + N*ILAENV( 1, 'ZGEHRD', ' ', N, 1, N, 0 )
+            MINWRK = 2*N
+            IF( WANTVL ) THEN
+               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
+     $                       ' ', N, 1, N, -1 ) )
+               CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
+     $                WORK, -1, INFO )
+            ELSE IF( WANTVR ) THEN
+               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
+     $                       ' ', N, 1, N, -1 ) )
+               CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
+     $                WORK, -1, INFO )
+            ELSE
+               CALL ZHSEQR( 'E', 'N', N, 1, N, A, LDA, W, VR, LDVR,
+     $                WORK, -1, INFO )
+            END IF
+            HSWORK = WORK( 1 )
+            MAXWRK = MAX( MAXWRK, HSWORK, MINWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = ZLANGE( 'M', N, N, A, LDA, DUM )
+      SCALEA = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = SMLNUM
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         SCALEA = .TRUE.
+         CSCALE = BIGNUM
+      END IF
+      IF( SCALEA )
+     $   CALL ZLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
+*
+*     Balance the matrix
+*     (CWorkspace: none)
+*     (RWorkspace: need N)
+*
+      IBAL = 1
+      CALL ZGEBAL( 'B', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
+*
+*     Reduce to upper Hessenberg form
+*     (CWorkspace: need 2*N, prefer N+N*NB)
+*     (RWorkspace: none)
+*
+      ITAU = 1
+      IWRK = ITAU + N
+      CALL ZGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
+     $             LWORK-IWRK+1, IERR )
+*
+      IF( WANTVL ) THEN
+*
+*        Want left eigenvectors
+*        Copy Householder vectors to VL
+*
+         SIDE = 'L'
+         CALL ZLACPY( 'L', N, N, A, LDA, VL, LDVL )
+*
+*        Generate unitary matrix in VL
+*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VL
+*        (CWorkspace: need 1, prefer HSWORK (see comments) )
+*        (RWorkspace: none)
+*
+         IWRK = ITAU
+         CALL ZHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VL, LDVL,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+         IF( WANTVR ) THEN
+*
+*           Want left and right eigenvectors
+*           Copy Schur vectors to VR
+*
+            SIDE = 'B'
+            CALL ZLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
+         END IF
+*
+      ELSE IF( WANTVR ) THEN
+*
+*        Want right eigenvectors
+*        Copy Householder vectors to VR
+*
+         SIDE = 'R'
+         CALL ZLACPY( 'L', N, N, A, LDA, VR, LDVR )
+*
+*        Generate unitary matrix in VR
+*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
+     $                LWORK-IWRK+1, IERR )
+*
+*        Perform QR iteration, accumulating Schur vectors in VR
+*        (CWorkspace: need 1, prefer HSWORK (see comments) )
+*        (RWorkspace: none)
+*
+         IWRK = ITAU
+         CALL ZHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+*
+      ELSE
+*
+*        Compute eigenvalues only
+*        (CWorkspace: need 1, prefer HSWORK (see comments) )
+*        (RWorkspace: none)
+*
+         IWRK = ITAU
+         CALL ZHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, W, VR, LDVR,
+     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
+      END IF
+*
+*     If INFO > 0 from ZHSEQR, then quit
+*
+      IF( INFO.GT.0 )
+     $   GO TO 50
+*
+      IF( WANTVL .OR. WANTVR ) THEN
+*
+*        Compute left and/or right eigenvectors
+*        (CWorkspace: need 2*N)
+*        (RWorkspace: need 2*N)
+*
+         IRWORK = IBAL + N
+         CALL ZTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                N, NOUT, WORK( IWRK ), RWORK( IRWORK ), IERR )
+      END IF
+*
+      IF( WANTVL ) THEN
+*
+*        Undo balancing of left eigenvectors
+*        (CWorkspace: none)
+*        (RWorkspace: need N)
+*
+         CALL ZGEBAK( 'B', 'L', N, ILO, IHI, RWORK( IBAL ), N, VL, LDVL,
+     $                IERR )
+*
+*        Normalize left eigenvectors and make largest component real
+*
+         DO 20 I = 1, N
+            SCL = ONE / DZNRM2( N, VL( 1, I ), 1 )
+            CALL ZDSCAL( N, SCL, VL( 1, I ), 1 )
+            DO 10 K = 1, N
+               RWORK( IRWORK+K-1 ) = DBLE( VL( K, I ) )**2 +
+     $                               DIMAG( VL( K, I ) )**2
+   10       CONTINUE
+            K = IDAMAX( N, RWORK( IRWORK ), 1 )
+            TMP = DCONJG( VL( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
+            CALL ZSCAL( N, TMP, VL( 1, I ), 1 )
+            VL( K, I ) = DCMPLX( DBLE( VL( K, I ) ), ZERO )
+   20    CONTINUE
+      END IF
+*
+      IF( WANTVR ) THEN
+*
+*        Undo balancing of right eigenvectors
+*        (CWorkspace: none)
+*        (RWorkspace: need N)
+*
+         CALL ZGEBAK( 'B', 'R', N, ILO, IHI, RWORK( IBAL ), N, VR, LDVR,
+     $                IERR )
+*
+*        Normalize right eigenvectors and make largest component real
+*
+         DO 40 I = 1, N
+            SCL = ONE / DZNRM2( N, VR( 1, I ), 1 )
+            CALL ZDSCAL( N, SCL, VR( 1, I ), 1 )
+            DO 30 K = 1, N
+               RWORK( IRWORK+K-1 ) = DBLE( VR( K, I ) )**2 +
+     $                               DIMAG( VR( K, I ) )**2
+   30       CONTINUE
+            K = IDAMAX( N, RWORK( IRWORK ), 1 )
+            TMP = DCONJG( VR( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
+            CALL ZSCAL( N, TMP, VR( 1, I ), 1 )
+            VR( K, I ) = DCMPLX( DBLE( VR( K, I ) ), ZERO )
+   40    CONTINUE
+      END IF
+*
+*     Undo scaling if necessary
+*
+   50 CONTINUE
+      IF( SCALEA ) THEN
+         CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, W( INFO+1 ),
+     $                MAX( N-INFO, 1 ), IERR )
+         IF( INFO.GT.0 ) THEN
+            CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, W, N, IERR )
+         END IF
+      END IF
+*
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of ZGEEV
+*
+      END
diff --git a/libcruft/lapack/zgehd2.f b/libcruft/lapack/zgehd2.f
new file mode 100644
index 0000000..c73f420
--- /dev/null
+++ b/libcruft/lapack/zgehd2.f
@@ -0,0 +1,148 @@
+      SUBROUTINE ZGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEHD2 reduces a complex general matrix A to upper Hessenberg form H
+*  by a unitary similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to ZGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= max(1,N).
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the n by n general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the unitary matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARF, ZLARFG
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEHD2', -INFO )
+         RETURN
+      END IF
+*
+      DO 10 I = ILO, IHI - 1
+*
+*        Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)
+*
+         ALPHA = A( I+1, I )
+         CALL ZLARFG( IHI-I, ALPHA, A( MIN( I+2, N ), I ), 1, TAU( I ) )
+         A( I+1, I ) = ONE
+*
+*        Apply H(i) to A(1:ihi,i+1:ihi) from the right
+*
+         CALL ZLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ),
+     $               A( 1, I+1 ), LDA, WORK )
+*
+*        Apply H(i)' to A(i+1:ihi,i+1:n) from the left
+*
+         CALL ZLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1,
+     $               DCONJG( TAU( I ) ), A( I+1, I+1 ), LDA, WORK )
+*
+         A( I+1, I ) = ALPHA
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of ZGEHD2
+*
+      END
diff --git a/libcruft/lapack/zgehrd.f b/libcruft/lapack/zgehrd.f
new file mode 100644
index 0000000..83c1aa3
--- /dev/null
+++ b/libcruft/lapack/zgehrd.f
@@ -0,0 +1,273 @@
+      SUBROUTINE ZGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16        A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEHRD reduces a complex general matrix A to upper Hessenberg form H by
+*  an unitary similarity transformation:  Q' * A * Q = H .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          It is assumed that A is already upper triangular in rows
+*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*          set by a previous call to ZGEBAL; otherwise they should be
+*          set to 1 and N respectively. See Further Details.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          elements below the first subdiagonal, with the array TAU,
+*          represent the unitary matrix Q as a product of elementary
+*          reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to
+*          zero.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (LWORK)
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of (ihi-ilo) elementary
+*  reflectors
+*
+*     Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
+*  exit in A(i+2:ihi,i), and tau in TAU(i).
+*
+*  The contents of A are illustrated by the following example, with
+*  n = 7, ilo = 2 and ihi = 6:
+*
+*  on entry,                        on exit,
+*
+*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
+*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
+*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
+*  (                         a )    (                          a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's ZGEHRD
+*  subroutine incorporating improvements proposed by Quintana-Orti and
+*  Van de Geijn (2005). 
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+      COMPLEX*16        ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ), 
+     $                     ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NH, NX
+      COMPLEX*16        EI
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16        T( LDT, NBMAX )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZAXPY, ZGEHD2, ZGEMM, ZLAHR2, ZLARFB, ZTRMM,
+     $                   XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      NB = MIN( NBMAX, ILAENV( 1, 'ZGEHRD', ' ', N, ILO, IHI, -1 ) )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEHRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero
+*
+      DO 10 I = 1, ILO - 1
+         TAU( I ) = ZERO
+   10 CONTINUE
+      DO 20 I = MAX( 1, IHI ), N - 1
+         TAU( I ) = ZERO
+   20 CONTINUE
+*
+*     Quick return if possible
+*
+      NH = IHI - ILO + 1
+      IF( NH.LE.1 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Determine the block size
+*
+      NB = MIN( NBMAX, ILAENV( 1, 'ZGEHRD', ' ', N, ILO, IHI, -1 ) )
+      NBMIN = 2
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.NH ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code)
+*
+         NX = MAX( NB, ILAENV( 3, 'ZGEHRD', ' ', N, ILO, IHI, -1 ) )
+         IF( NX.LT.NH ) THEN
+*
+*           Determine if workspace is large enough for blocked code
+*
+            IWS = N*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code
+*
+               NBMIN = MAX( 2, ILAENV( 2, 'ZGEHRD', ' ', N, ILO, IHI,
+     $                 -1 ) )
+               IF( LWORK.GE.N*NBMIN ) THEN
+                  NB = LWORK / N
+               ELSE
+                  NB = 1
+               END IF
+            END IF
+         END IF
+      END IF
+      LDWORK = N
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN
+*
+*        Use unblocked code below
+*
+         I = ILO
+*
+      ELSE
+*
+*        Use blocked code
+*
+         DO 40 I = ILO, IHI - 1 - NX, NB
+            IB = MIN( NB, IHI-I )
+*
+*           Reduce columns i:i+ib-1 to Hessenberg form, returning the
+*           matrices V and T of the block reflector H = I - V*T*V'
+*           which performs the reduction, and also the matrix Y = A*V*T
+*
+            CALL ZLAHR2( IHI, I, IB, A( 1, I ), LDA, TAU( I ), T, LDT,
+     $                   WORK, LDWORK )
+*
+*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the
+*           right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set
+*           to 1
+*
+            EI = A( I+IB, I+IB-1 )
+            A( I+IB, I+IB-1 ) = ONE
+            CALL ZGEMM( 'No transpose', 'Conjugate transpose', 
+     $                  IHI, IHI-I-IB+1,
+     $                  IB, -ONE, WORK, LDWORK, A( I+IB, I ), LDA, ONE,
+     $                  A( 1, I+IB ), LDA )
+            A( I+IB, I+IB-1 ) = EI
+*
+*           Apply the block reflector H to A(1:i,i+1:i+ib-1) from the
+*           right
+*
+            CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                  'Unit', I, IB-1,
+     $                  ONE, A( I+1, I ), LDA, WORK, LDWORK )
+            DO 30 J = 0, IB-2
+               CALL ZAXPY( I, -ONE, WORK( LDWORK*J+1 ), 1,
+     $                     A( 1, I+J+1 ), 1 )
+   30       CONTINUE
+*
+*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the
+*           left
+*
+            CALL ZLARFB( 'Left', 'Conjugate transpose', 'Forward',
+     $                   'Columnwise',
+     $                   IHI-I, N-I-IB+1, IB, A( I+1, I ), LDA, T, LDT,
+     $                   A( I+1, I+IB ), LDA, WORK, LDWORK )
+   40    CONTINUE
+      END IF
+*
+*     Use unblocked code to reduce the rest of the matrix
+*
+      CALL ZGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )
+      WORK( 1 ) = IWS
+*
+      RETURN
+*
+*     End of ZGEHRD
+*
+      END
diff --git a/libcruft/lapack/zgelq2.f b/libcruft/lapack/zgelq2.f
new file mode 100644
index 0000000..dc387af
--- /dev/null
+++ b/libcruft/lapack/zgelq2.f
@@ -0,0 +1,123 @@
+      SUBROUTINE ZGELQ2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGELQ2 computes an LQ factorization of a complex m by n matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m by min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k)' . . . H(2)' H(1)', where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; conjg(v(i+1:n)) is stored on exit in
+*  A(i,i+1:n), and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLACGV, ZLARF, ZLARFG
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGELQ2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i,i+1:n)
+*
+         CALL ZLACGV( N-I+1, A( I, I ), LDA )
+         ALPHA = A( I, I )
+         CALL ZLARFG( N-I+1, ALPHA, A( I, MIN( I+1, N ) ), LDA,
+     $                TAU( I ) )
+         IF( I.LT.M ) THEN
+*
+*           Apply H(i) to A(i+1:m,i:n) from the right
+*
+            A( I, I ) = ONE
+            CALL ZLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ),
+     $                  A( I+1, I ), LDA, WORK )
+         END IF
+         A( I, I ) = ALPHA
+         CALL ZLACGV( N-I+1, A( I, I ), LDA )
+   10 CONTINUE
+      RETURN
+*
+*     End of ZGELQ2
+*
+      END
diff --git a/libcruft/lapack/zgelqf.f b/libcruft/lapack/zgelqf.f
new file mode 100644
index 0000000..5dac50d
--- /dev/null
+++ b/libcruft/lapack/zgelqf.f
@@ -0,0 +1,195 @@
+      SUBROUTINE ZGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGELQF computes an LQ factorization of a complex M-by-N matrix A:
+*  A = L * Q.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and below the diagonal of the array
+*          contain the m-by-min(m,n) lower trapezoidal matrix L (L is
+*          lower triangular if m <= n); the elements above the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(k)' . . . H(2)' H(1)', where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; conjg(v(i+1:n)) is stored on exit in
+*  A(i,i+1:n), and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGELQ2, ZLARFB, ZLARFT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+      LWKOPT = M*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGELQF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'ZGELQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'ZGELQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the LQ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL ZGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL ZLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i+ib:m,i:n) from the right
+*
+               CALL ZLARFB( 'Right', 'No transpose', 'Forward',
+     $                      'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),
+     $                      LDA, WORK, LDWORK, A( I+IB, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL ZGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZGELQF
+*
+      END
diff --git a/libcruft/lapack/zgelsd.f b/libcruft/lapack/zgelsd.f
new file mode 100644
index 0000000..4a68402
--- /dev/null
+++ b/libcruft/lapack/zgelsd.f
@@ -0,0 +1,566 @@
+      SUBROUTINE ZGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, RWORK, IWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   RWORK( * ), S( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGELSD computes the minimum-norm solution to a real linear least
+*  squares problem:
+*      minimize 2-norm(| b - A*x |)
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The problem is solved in three steps:
+*  (1) Reduce the coefficient matrix A to bidiagonal form with
+*      Householder tranformations, reducing the original problem
+*      into a "bidiagonal least squares problem" (BLS)
+*  (2) Solve the BLS using a divide and conquer approach.
+*  (3) Apply back all the Householder tranformations to solve
+*      the original least squares problem.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  The divide and conquer algorithm makes very mild assumptions about
+*  floating point arithmetic. It will work on machines with a guard
+*  digit in add/subtract, or on those binary machines without guard
+*  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
+*  Cray-2. It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution matrix X.
+*          If m >= n and RANK = n, the residual sum-of-squares for
+*          the solution in the i-th column is given by the sum of
+*          squares of the modulus of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M,N).
+*
+*  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) DOUBLE PRECISION
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK must be at least 1.
+*          The exact minimum amount of workspace needed depends on M,
+*          N and NRHS. As long as LWORK is at least
+*              2*N + N*NRHS
+*          if M is greater than or equal to N or
+*              2*M + M*NRHS
+*          if M is less than N, the code will execute correctly.
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the array WORK and the
+*          minimum sizes of the arrays RWORK and IWORK, and returns
+*          these values as the first entries of the WORK, RWORK and
+*          IWORK arrays, and no error message related to LWORK is issued
+*          by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
+*          LRWORK >=
+*              10*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS +
+*             (SMLSIZ+1)**2
+*          if M is greater than or equal to N or
+*             10*M + 2*M*SMLSIZ + 8*M*NLVL + 3*SMLSIZ*NRHS +
+*             (SMLSIZ+1)**2
+*          if M is less than N, the code will execute correctly.
+*          SMLSIZ is returned by ILAENV and is equal to the maximum
+*          size of the subproblems at the bottom of the computation
+*          tree (usually about 25), and
+*             NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
+*          On exit, if INFO = 0, RWORK(1) returns the minimum LRWORK.
+*
+*  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
+*          LIWORK >= max(1, 3*MINMN*NLVL + 11*MINMN),
+*          where MINMN = MIN( M,N ).
+*          On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
+      COMPLEX*16         CZERO
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
+     $                   LDWORK, LIWORK, LRWORK, MAXMN, MAXWRK, MINMN,
+     $                   MINWRK, MM, MNTHR, NLVL, NRWORK, NWORK, SMLSIZ
+      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, DLASCL, DLASET, XERBLA, ZGEBRD, ZGELQF,
+     $                   ZGEQRF, ZLACPY, ZLALSD, ZLASCL, ZLASET, ZUNMBR,
+     $                   ZUNMLQ, ZUNMQR
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      EXTERNAL           ILAENV, DLAMCH, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, LOG, MAX, MIN, DBLE
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace.
+*     (Note: Comments in the code beginning "Workspace:" describe the
+*     minimal amount of workspace needed at that point in the code,
+*     as well as the preferred amount for good performance.
+*     NB refers to the optimal block size for the immediately
+*     following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         LIWORK = 1
+         LRWORK = 1
+         IF( MINMN.GT.0 ) THEN
+            SMLSIZ = ILAENV( 9, 'ZGELSD', ' ', 0, 0, 0, 0 )
+            MNTHR = ILAENV( 6, 'ZGELSD', ' ', M, N, NRHS, -1 )
+            NLVL = MAX( INT( LOG( DBLE( MINMN ) / DBLE( SMLSIZ + 1 ) ) /
+     $                  LOG( TWO ) ) + 1, 0 )
+            LIWORK = 3*MINMN*NLVL + 11*MINMN
+            MM = M
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns.
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N*ILAENV( 1, 'ZGEQRF', ' ', M, N,
+     $                       -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, NRHS*ILAENV( 1, 'ZUNMQR', 'LC', M,
+     $                       NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined.
+*
+               LRWORK = 10*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS +
+     $                  ( SMLSIZ + 1 )**2
+               MAXWRK = MAX( MAXWRK, 2*N + ( MM + N )*ILAENV( 1,
+     $                       'ZGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + NRHS*ILAENV( 1, 'ZUNMBR',
+     $                       'QLC', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'ZUNMBR', 'PLN', N, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + N*NRHS )
+               MINWRK = MAX( 2*N + MM, 2*N + N*NRHS )
+            END IF
+            IF( N.GT.M ) THEN
+               LRWORK = 10*M + 2*M*SMLSIZ + 8*M*NLVL + 3*SMLSIZ*NRHS +
+     $                  ( SMLSIZ + 1 )**2
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                           than rows.
+*
+                  MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
+     $                          'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
+     $                          'ZUNMBR', 'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + ( M - 1 )*ILAENV( 1,
+     $                          'ZUNMLQ', 'LC', N, NRHS, M, -1 ) )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M*M + 4*M + M*NRHS )
+               ELSE
+*
+*                 Path 2 - underdetermined.
+*
+                  MAXWRK = 2*M + ( N + M )*ILAENV( 1, 'ZGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 2*M + NRHS*ILAENV( 1, 'ZUNMBR',
+     $                          'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 2*M + M*ILAENV( 1, 'ZUNMBR',
+     $                          'PLN', N, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 2*M + M*NRHS )
+               END IF
+               MINWRK = MAX( 2*M + N, 2*M + M*NRHS )
+            END IF
+         END IF
+         MINWRK = MIN( MINWRK, MAXWRK )
+         WORK( 1 ) = MAXWRK
+         IWORK( 1 ) = LIWORK
+         RWORK( 1 ) = LRWORK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -12
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGELSD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters.
+*
+      EPS = DLAMCH( 'P' )
+      SFMIN = DLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max entry outside range [SMLNUM,BIGNUM].
+*
+      ANRM = ZLANGE( 'M', M, N, A, LDA, RWORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL ZLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
+         RANK = 0
+         GO TO 10
+      END IF
+*
+*     Scale B if max entry outside range [SMLNUM,BIGNUM].
+*
+      BNRM = ZLANGE( 'M', M, NRHS, B, LDB, RWORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM.
+*
+         CALL ZLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM.
+*
+         CALL ZLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     If M < N make sure B(M+1:N,:) = 0
+*
+      IF( M.LT.N )
+     $   CALL ZLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB )
+*
+*     Overdetermined case.
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined.
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns
+*
+            MM = N
+            ITAU = 1
+            NWORK = ITAU + N
+*
+*           Compute A=Q*R.
+*           (RWorkspace: need N)
+*           (CWorkspace: need N, prefer N*NB)
+*
+            CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                   LWORK-NWORK+1, INFO )
+*
+*           Multiply B by transpose(Q).
+*           (RWorkspace: need N)
+*           (CWorkspace: need NRHS, prefer NRHS*NB)
+*
+            CALL ZUNMQR( 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*           Zero out below R.
+*
+            IF( N.GT.1 ) THEN
+               CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                      LDA )
+            END IF
+         END IF
+*
+         ITAUQ = 1
+         ITAUP = ITAUQ + N
+         NWORK = ITAUP + N
+         IE = 1
+         NRWORK = IE + N
+*
+*        Bidiagonalize R in A.
+*        (RWorkspace: need N)
+*        (CWorkspace: need 2*N+MM, prefer 2*N+(MM+N)*NB)
+*
+         CALL ZGEBRD( MM, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R.
+*        (CWorkspace: need 2*N+NRHS, prefer 2*N+NRHS*NB)
+*
+         CALL ZUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL ZLALSD( 'U', SMLSIZ, N, NRHS, S, RWORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), RWORK( NRWORK ),
+     $                IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of R.
+*
+         CALL ZUNMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
+     $         MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm.
+*
+         LDWORK = M
+         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
+     $       M*LDA+M+M*NRHS ) )LDWORK = LDA
+         ITAU = 1
+         NWORK = M + 1
+*
+*        Compute A=L*Q.
+*        (CWorkspace: need 2*M, prefer M+M*NB)
+*
+         CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+         IL = NWORK
+*
+*        Copy L to WORK(IL), zeroing out above its diagonal.
+*
+         CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         ITAUQ = IL + LDWORK*M
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+         IE = 1
+         NRWORK = IE + M
+*
+*        Bidiagonalize L in WORK(IL).
+*        (RWorkspace: need M)
+*        (CWorkspace: need M*M+4*M, prefer M*M+4*M+2*M*NB)
+*
+         CALL ZGEBRD( M, M, WORK( IL ), LDWORK, S, RWORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L.
+*        (CWorkspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
+*
+         CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL ZLALSD( 'U', SMLSIZ, M, NRHS, S, RWORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), RWORK( NRWORK ),
+     $                IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of L.
+*
+         CALL ZUNMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUP ), B, LDB, WORK( NWORK ),
+     $                LWORK-NWORK+1, INFO )
+*
+*        Zero out below first M rows of B.
+*
+         CALL ZLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB )
+         NWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B.
+*        (CWorkspace: need NRHS, prefer NRHS*NB)
+*
+         CALL ZUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases.
+*
+         ITAUQ = 1
+         ITAUP = ITAUQ + M
+         NWORK = ITAUP + M
+         IE = 1
+         NRWORK = IE + M
+*
+*        Bidiagonalize A.
+*        (RWorkspace: need M)
+*        (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
+*
+         CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors.
+*        (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)
+*
+         CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+*        Solve the bidiagonal least squares problem.
+*
+         CALL ZLALSD( 'L', SMLSIZ, M, NRHS, S, RWORK( IE ), B, LDB,
+     $                RCOND, RANK, WORK( NWORK ), RWORK( NRWORK ),
+     $                IWORK, INFO )
+         IF( INFO.NE.0 ) THEN
+            GO TO 10
+         END IF
+*
+*        Multiply B by right bidiagonalizing vectors of A.
+*
+         CALL ZUNMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),
+     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
+*
+      END IF
+*
+*     Undo scaling.
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   10 CONTINUE
+      WORK( 1 ) = MAXWRK
+      IWORK( 1 ) = LIWORK
+      RWORK( 1 ) = LRWORK
+      RETURN
+*
+*     End of ZGELSD
+*
+      END
diff --git a/libcruft/lapack/zgelss.f b/libcruft/lapack/zgelss.f
new file mode 100644
index 0000000..7ea253a
--- /dev/null
+++ b/libcruft/lapack/zgelss.f
@@ -0,0 +1,634 @@
+      SUBROUTINE ZGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
+     $                   WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * ), S( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGELSS computes the minimum norm solution to a complex linear
+*  least squares problem:
+*
+*  Minimize 2-norm(| b - A*x |).
+*
+*  using the singular value decomposition (SVD) of A. A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
+*  X.
+*
+*  The effective rank of A is determined by treating as zero those
+*  singular values which are less than RCOND times the largest singular
+*  value.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the first min(m,n) rows of A are overwritten with
+*          its right singular vectors, stored rowwise.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, B is overwritten by the N-by-NRHS solution matrix X.
+*          If m >= n and RANK = n, the residual sum-of-squares for
+*          the solution in the i-th column is given by the sum of
+*          squares of the modulus of elements n+1:m in that column.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M,N).
+*
+*  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The singular values of A in decreasing order.
+*          The condition number of A in the 2-norm = S(1)/S(min(m,n)).
+*
+*  RCOND   (input) DOUBLE PRECISION
+*          RCOND is used to determine the effective rank of A.
+*          Singular values S(i) <= RCOND*S(1) are treated as zero.
+*          If RCOND < 0, machine precision is used instead.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the number of singular values
+*          which are greater than RCOND*S(1).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= 1, and also:
+*          LWORK >=  2*min(M,N) + max(M,N,NRHS)
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (5*min(M,N))
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  the algorithm for computing the SVD failed to converge;
+*                if INFO = i, i off-diagonal elements of an intermediate
+*                bidiagonal form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            BL, CHUNK, I, IASCL, IBSCL, IE, IL, IRWORK,
+     $                   ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
+     $                   MAXWRK, MINMN, MINWRK, MM, MNTHR
+      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         VDUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, DLASCL, DLASET, XERBLA, ZBDSQR, ZCOPY,
+     $                   ZDRSCL, ZGEBRD, ZGELQF, ZGEMM, ZGEMV, ZGEQRF,
+     $                   ZLACPY, ZLASCL, ZLASET, ZUNGBR, ZUNMBR, ZUNMLQ,
+     $                   ZUNMQR
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      EXTERNAL           ILAENV, DLAMCH, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      MAXMN = MAX( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
+         INFO = -7
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace refers
+*       to real workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( MINMN.GT.0 ) THEN
+            MM = M
+            MNTHR = ILAENV( 6, 'ZGELSS', ' ', M, N, NRHS, -1 )
+            IF( M.GE.N .AND. M.GE.MNTHR ) THEN
+*
+*              Path 1a - overdetermined, with many more rows than
+*                        columns
+*
+               MM = N
+               MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'ZGEQRF', ' ', M,
+     $                       N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'ZUNMQR', 'LC',
+     $                       M, NRHS, N, -1 ) )
+            END IF
+            IF( M.GE.N ) THEN
+*
+*              Path 1 - overdetermined or exactly determined
+*
+               MAXWRK = MAX( MAXWRK, 2*N + ( MM + N )*ILAENV( 1,
+     $                       'ZGEBRD', ' ', MM, N, -1, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + NRHS*ILAENV( 1, 'ZUNMBR',
+     $                       'QLC', MM, NRHS, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
+     $                       'ZUNGBR', 'P', N, N, N, -1 ) )
+               MAXWRK = MAX( MAXWRK, N*NRHS )
+               MINWRK = 2*N + MAX( NRHS, M )
+            END IF
+            IF( N.GT.M ) THEN
+               MINWRK = 2*M + MAX( NRHS, N )
+               IF( N.GE.MNTHR ) THEN
+*
+*                 Path 2a - underdetermined, with many more columns
+*                 than rows
+*
+                  MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*M + 2*M*ILAENV( 1,
+     $                          'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*M + NRHS*ILAENV( 1,
+     $                          'ZUNMBR', 'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 3*M + M*M + ( M - 1 )*ILAENV( 1,
+     $                          'ZUNGBR', 'P', M, M, M, -1 ) )
+                  IF( NRHS.GT.1 ) THEN
+                     MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
+                  ELSE
+                     MAXWRK = MAX( MAXWRK, M*M + 2*M )
+                  END IF
+                  MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'ZUNMLQ',
+     $                          'LC', N, NRHS, M, -1 ) )
+               ELSE
+*
+*                 Path 2 - underdetermined
+*
+                  MAXWRK = 2*M + ( N + M )*ILAENV( 1, 'ZGEBRD', ' ', M,
+     $                     N, -1, -1 )
+                  MAXWRK = MAX( MAXWRK, 2*M + NRHS*ILAENV( 1, 'ZUNMBR',
+     $                          'QLC', M, NRHS, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, 2*M + M*ILAENV( 1, 'ZUNGBR',
+     $                          'P', M, N, M, -1 ) )
+                  MAXWRK = MAX( MAXWRK, N*NRHS )
+               END IF
+            END IF
+            MAXWRK = MAX( MINWRK, MAXWRK )
+         END IF
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
+     $      INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGELSS', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      EPS = DLAMCH( 'P' )
+      SFMIN = DLAMCH( 'S' )
+      SMLNUM = SFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = ZLANGE( 'M', M, N, A, LDA, RWORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL ZLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, MINMN )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = ZLANGE( 'M', M, NRHS, B, LDB, RWORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL ZLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL ZLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Overdetermined case
+*
+      IF( M.GE.N ) THEN
+*
+*        Path 1 - overdetermined or exactly determined
+*
+         MM = M
+         IF( M.GE.MNTHR ) THEN
+*
+*           Path 1a - overdetermined, with many more rows than columns
+*
+            MM = N
+            ITAU = 1
+            IWORK = ITAU + N
+*
+*           Compute A=Q*R
+*           (CWorkspace: need 2*N, prefer N+N*NB)
+*           (RWorkspace: none)
+*
+            CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                   LWORK-IWORK+1, INFO )
+*
+*           Multiply B by transpose(Q)
+*           (CWorkspace: need N+NRHS, prefer N+NRHS*NB)
+*           (RWorkspace: none)
+*
+            CALL ZUNMQR( 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAU ), B,
+     $                   LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*           Zero out below R
+*
+            IF( N.GT.1 )
+     $         CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                      LDA )
+         END IF
+*
+         IE = 1
+         ITAUQ = 1
+         ITAUP = ITAUQ + N
+         IWORK = ITAUP + N
+*
+*        Bidiagonalize R in A
+*        (CWorkspace: need 2*N+MM, prefer 2*N+(MM+N)*NB)
+*        (RWorkspace: need N)
+*
+         CALL ZGEBRD( MM, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of R
+*        (CWorkspace: need 2*N+NRHS, prefer 2*N+NRHS*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in A
+*        (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IRWORK = IE + N
+*
+*        Perform bidiagonal QR iteration
+*          multiply B by transpose of left singular vectors
+*          compute right singular vectors in A
+*        (CWorkspace: none)
+*        (RWorkspace: need BDSPAC)
+*
+         CALL ZBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, RWORK( IRWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 10 I = 1, N
+            IF( S( I ).GT.THR ) THEN
+               CALL ZDRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL ZLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            END IF
+   10    CONTINUE
+*
+*        Multiply B by right singular vectors
+*        (CWorkspace: need N, prefer N*NRHS)
+*        (RWorkspace: none)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL ZGEMM( 'C', 'N', N, NRHS, N, CONE, A, LDA, B, LDB,
+     $                  CZERO, WORK, LDB )
+            CALL ZLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 20 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL ZGEMM( 'C', 'N', N, BL, N, CONE, A, LDA, B( 1, I ),
+     $                     LDB, CZERO, WORK, N )
+               CALL ZLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB )
+   20       CONTINUE
+         ELSE
+            CALL ZGEMV( 'C', N, N, CONE, A, LDA, B, 1, CZERO, WORK, 1 )
+            CALL ZCOPY( N, WORK, 1, B, 1 )
+         END IF
+*
+      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.3*M+M*M+MAX( M, NRHS, N-2*M ) )
+     $          THEN
+*
+*        Underdetermined case, M much less than N
+*
+*        Path 2a - underdetermined, with many more columns than rows
+*        and sufficient workspace for an efficient algorithm
+*
+         LDWORK = M
+         IF( LWORK.GE.3*M+M*LDA+MAX( M, NRHS, N-2*M ) )
+     $      LDWORK = LDA
+         ITAU = 1
+         IWORK = M + 1
+*
+*        Compute A=L*Q
+*        (CWorkspace: need 2*M, prefer M+M*NB)
+*        (RWorkspace: none)
+*
+         CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+         IL = IWORK
+*
+*        Copy L to WORK(IL), zeroing out above it
+*
+         CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
+         CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, WORK( IL+LDWORK ),
+     $                LDWORK )
+         IE = 1
+         ITAUQ = IL + LDWORK*M
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize L in WORK(IL)
+*        (CWorkspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*        (RWorkspace: need M)
+*
+         CALL ZGEBRD( M, M, WORK( IL ), LDWORK, S, RWORK( IE ),
+     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors of L
+*        (CWorkspace: need M*M+3*M+NRHS, prefer M*M+3*M+NRHS*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, M, WORK( IL ), LDWORK,
+     $                WORK( ITAUQ ), B, LDB, WORK( IWORK ),
+     $                LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors of R in WORK(IL)
+*        (CWorkspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IRWORK = IE + M
+*
+*        Perform bidiagonal QR iteration, computing right singular
+*        vectors of L in WORK(IL) and multiplying B by transpose of
+*        left singular vectors
+*        (CWorkspace: need M*M)
+*        (RWorkspace: need BDSPAC)
+*
+         CALL ZBDSQR( 'U', M, M, 0, NRHS, S, RWORK( IE ), WORK( IL ),
+     $                LDWORK, A, LDA, B, LDB, RWORK( IRWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 30 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL ZDRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL ZLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            END IF
+   30    CONTINUE
+         IWORK = IL + M*LDWORK
+*
+*        Multiply B by right singular vectors of L in WORK(IL)
+*        (CWorkspace: need M*M+2*M, prefer M*M+M+M*NRHS)
+*        (RWorkspace: none)
+*
+         IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN
+            CALL ZGEMM( 'C', 'N', M, NRHS, M, CONE, WORK( IL ), LDWORK,
+     $                  B, LDB, CZERO, WORK( IWORK ), LDB )
+            CALL ZLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = ( LWORK-IWORK+1 ) / M
+            DO 40 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL ZGEMM( 'C', 'N', M, BL, M, CONE, WORK( IL ), LDWORK,
+     $                     B( 1, I ), LDB, CZERO, WORK( IWORK ), M )
+               CALL ZLACPY( 'G', M, BL, WORK( IWORK ), M, B( 1, I ),
+     $                      LDB )
+   40       CONTINUE
+         ELSE
+            CALL ZGEMV( 'C', M, M, CONE, WORK( IL ), LDWORK, B( 1, 1 ),
+     $                  1, CZERO, WORK( IWORK ), 1 )
+            CALL ZCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 )
+         END IF
+*
+*        Zero out below first M rows of B
+*
+         CALL ZLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB )
+         IWORK = ITAU + M
+*
+*        Multiply transpose(Q) by B
+*        (CWorkspace: need M+NRHS, prefer M+NHRS*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, WORK( ITAU ), B,
+     $                LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+      ELSE
+*
+*        Path 2 - remaining underdetermined cases
+*
+         IE = 1
+         ITAUQ = 1
+         ITAUP = ITAUQ + M
+         IWORK = ITAUP + M
+*
+*        Bidiagonalize A
+*        (CWorkspace: need 3*M, prefer 2*M+(M+N)*NB)
+*        (RWorkspace: need N)
+*
+         CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                INFO )
+*
+*        Multiply B by transpose of left bidiagonalizing vectors
+*        (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAUQ ),
+     $                B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
+*
+*        Generate right bidiagonalizing vectors in A
+*        (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*        (RWorkspace: none)
+*
+         CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                WORK( IWORK ), LWORK-IWORK+1, INFO )
+         IRWORK = IE + M
+*
+*        Perform bidiagonal QR iteration,
+*           computing right singular vectors of A in A and
+*           multiplying B by transpose of left singular vectors
+*        (CWorkspace: none)
+*        (RWorkspace: need BDSPAC)
+*
+         CALL ZBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+     $                1, B, LDB, RWORK( IRWORK ), INFO )
+         IF( INFO.NE.0 )
+     $      GO TO 70
+*
+*        Multiply B by reciprocals of singular values
+*
+         THR = MAX( RCOND*S( 1 ), SFMIN )
+         IF( RCOND.LT.ZERO )
+     $      THR = MAX( EPS*S( 1 ), SFMIN )
+         RANK = 0
+         DO 50 I = 1, M
+            IF( S( I ).GT.THR ) THEN
+               CALL ZDRSCL( NRHS, S( I ), B( I, 1 ), LDB )
+               RANK = RANK + 1
+            ELSE
+               CALL ZLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            END IF
+   50    CONTINUE
+*
+*        Multiply B by right singular vectors of A
+*        (CWorkspace: need N, prefer N*NRHS)
+*        (RWorkspace: none)
+*
+         IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
+            CALL ZGEMM( 'C', 'N', N, NRHS, M, CONE, A, LDA, B, LDB,
+     $                  CZERO, WORK, LDB )
+            CALL ZLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
+         ELSE IF( NRHS.GT.1 ) THEN
+            CHUNK = LWORK / N
+            DO 60 I = 1, NRHS, CHUNK
+               BL = MIN( NRHS-I+1, CHUNK )
+               CALL ZGEMM( 'C', 'N', N, BL, M, CONE, A, LDA, B( 1, I ),
+     $                     LDB, CZERO, WORK, N )
+               CALL ZLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB )
+   60       CONTINUE
+         ELSE
+            CALL ZGEMV( 'C', M, N, CONE, A, LDA, B, 1, CZERO, WORK, 1 )
+            CALL ZCOPY( N, WORK, 1, B, 1 )
+         END IF
+      END IF
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+   70 CONTINUE
+      WORK( 1 ) = MAXWRK
+      RETURN
+*
+*     End of ZGELSS
+*
+      END
diff --git a/libcruft/lapack/zgelsy.f b/libcruft/lapack/zgelsy.f
new file mode 100644
index 0000000..684cf2c
--- /dev/null
+++ b/libcruft/lapack/zgelsy.f
@@ -0,0 +1,385 @@
+      SUBROUTINE ZGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
+     $                   WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGELSY computes the minimum-norm solution to a complex linear least
+*  squares problem:
+*      minimize || A * X - B ||
+*  using a complete orthogonal factorization of A.  A is an M-by-N
+*  matrix which may be rank-deficient.
+*
+*  Several right hand side vectors b and solution vectors x can be
+*  handled in a single call; they are stored as the columns of the
+*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
+*  matrix X.
+*
+*  The routine first computes a QR factorization with column pivoting:
+*      A * P = Q * [ R11 R12 ]
+*                  [  0  R22 ]
+*  with R11 defined as the largest leading submatrix whose estimated
+*  condition number is less than 1/RCOND.  The order of R11, RANK,
+*  is the effective rank of A.
+*
+*  Then, R22 is considered to be negligible, and R12 is annihilated
+*  by unitary transformations from the right, arriving at the
+*  complete orthogonal factorization:
+*     A * P = Q * [ T11 0 ] * Z
+*                 [  0  0 ]
+*  The minimum-norm solution is then
+*     X = P * Z' [ inv(T11)*Q1'*B ]
+*                [        0       ]
+*  where Q1 consists of the first RANK columns of Q.
+*
+*  This routine is basically identical to the original xGELSX except
+*  three differences:
+*    o The permutation of matrix B (the right hand side) is faster and
+*      more simple.
+*    o The call to the subroutine xGEQPF has been substituted by the
+*      the call to the subroutine xGEQP3. This subroutine is a Blas-3
+*      version of the QR factorization with column pivoting.
+*    o Matrix B (the right hand side) is updated with Blas-3.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of
+*          columns of matrices B and X. NRHS >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, A has been overwritten by details of its
+*          complete orthogonal factorization.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the M-by-NRHS right hand side matrix B.
+*          On exit, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,M,N).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of AP, otherwise column i is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  RCOND   (input) DOUBLE PRECISION
+*          RCOND is used to determine the effective rank of A, which
+*          is defined as the order of the largest leading triangular
+*          submatrix R11 in the QR factorization with pivoting of A,
+*          whose estimated condition number < 1/RCOND.
+*
+*  RANK    (output) INTEGER
+*          The effective rank of A, i.e., the order of the submatrix
+*          R11.  This is the same as the order of the submatrix T11
+*          in the complete orthogonal factorization of A.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          The unblocked strategy requires that:
+*            LWORK >= MN + MAX( 2*MN, N+1, MN+NRHS )
+*          where MN = min(M,N).
+*          The block algorithm requires that:
+*            LWORK >= MN + MAX( 2*MN, NB*(N+1), MN+MN*NB, MN+NB*NRHS )
+*          where NB is an upper bound on the blocksize returned
+*          by ILAENV for the routines ZGEQP3, ZTZRZF, CTZRQF, ZUNMQR,
+*          and ZUNMRZ.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*    E. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            IMAX, IMIN
+      PARAMETER          ( IMAX = 1, IMIN = 2 )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKOPT, MN,
+     $                   NB, NB1, NB2, NB3, NB4
+      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
+     $                   SMLNUM, WSIZE
+      COMPLEX*16         C1, C2, S1, S2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, XERBLA, ZCOPY, ZGEQP3, ZLAIC1, ZLASCL,
+     $                   ZLASET, ZTRSM, ZTZRZF, ZUNMQR, ZUNMRZ
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      EXTERNAL           ILAENV, DLAMCH, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M, N )
+      ISMIN = MN + 1
+      ISMAX = 2*MN + 1
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      NB1 = ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+      NB2 = ILAENV( 1, 'ZGERQF', ' ', M, N, -1, -1 )
+      NB3 = ILAENV( 1, 'ZUNMQR', ' ', M, N, NRHS, -1 )
+      NB4 = ILAENV( 1, 'ZUNMRQ', ' ', M, N, NRHS, -1 )
+      NB = MAX( NB1, NB2, NB3, NB4 )
+      LWKOPT = MAX( 1, MN+2*N+NB*( N+1 ), 2*MN+NB*NRHS )
+      WORK( 1 ) = DCMPLX( LWKOPT )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
+         INFO = -7
+      ELSE IF( LWORK.LT.( MN+MAX( 2*MN, N+1, MN+NRHS ) ) .AND. .NOT.
+     $         LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGELSY', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( MIN( M, N, NRHS ).EQ.0 ) THEN
+         RANK = 0
+         RETURN
+      END IF
+*
+*     Get machine parameters
+*
+      SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+*
+*     Scale A, B if max entries outside range [SMLNUM,BIGNUM]
+*
+      ANRM = ZLANGE( 'M', M, N, A, LDA, RWORK )
+      IASCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
+         IASCL = 1
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
+         IASCL = 2
+      ELSE IF( ANRM.EQ.ZERO ) THEN
+*
+*        Matrix all zero. Return zero solution.
+*
+         CALL ZLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         RANK = 0
+         GO TO 70
+      END IF
+*
+      BNRM = ZLANGE( 'M', M, NRHS, B, LDB, RWORK )
+      IBSCL = 0
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+*
+*        Scale matrix norm up to SMLNUM
+*
+         CALL ZLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 1
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+*
+*        Scale matrix norm down to BIGNUM
+*
+         CALL ZLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
+         IBSCL = 2
+      END IF
+*
+*     Compute QR factorization with column pivoting of A:
+*        A * P = Q * R
+*
+      CALL ZGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
+     $             LWORK-MN, RWORK, INFO )
+      WSIZE = MN + DBLE( WORK( MN+1 ) )
+*
+*     complex workspace: MN+NB*(N+1). real workspace 2*N.
+*     Details of Householder rotations stored in WORK(1:MN).
+*
+*     Determine RANK using incremental condition estimation
+*
+      WORK( ISMIN ) = CONE
+      WORK( ISMAX ) = CONE
+      SMAX = ABS( A( 1, 1 ) )
+      SMIN = SMAX
+      IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
+         RANK = 0
+         CALL ZLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
+         GO TO 70
+      ELSE
+         RANK = 1
+      END IF
+*
+   10 CONTINUE
+      IF( RANK.LT.MN ) THEN
+         I = RANK + 1
+         CALL ZLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
+     $                A( I, I ), SMINPR, S1, C1 )
+         CALL ZLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
+     $                A( I, I ), SMAXPR, S2, C2 )
+*
+         IF( SMAXPR*RCOND.LE.SMINPR ) THEN
+            DO 20 I = 1, RANK
+               WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
+               WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
+   20       CONTINUE
+            WORK( ISMIN+RANK ) = C1
+            WORK( ISMAX+RANK ) = C2
+            SMIN = SMINPR
+            SMAX = SMAXPR
+            RANK = RANK + 1
+            GO TO 10
+         END IF
+      END IF
+*
+*     complex workspace: 3*MN.
+*
+*     Logically partition R = [ R11 R12 ]
+*                             [  0  R22 ]
+*     where R11 = R(1:RANK,1:RANK)
+*
+*     [R11,R12] = [ T11, 0 ] * Y
+*
+      IF( RANK.LT.N )
+     $   CALL ZTZRZF( RANK, N, A, LDA, WORK( MN+1 ), WORK( 2*MN+1 ),
+     $                LWORK-2*MN, INFO )
+*
+*     complex workspace: 2*MN.
+*     Details of Householder rotations stored in WORK(MN+1:2*MN)
+*
+*     B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
+*
+      CALL ZUNMQR( 'Left', 'Conjugate transpose', M, NRHS, MN, A, LDA,
+     $             WORK( 1 ), B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
+      WSIZE = MAX( WSIZE, 2*MN+DBLE( WORK( 2*MN+1 ) ) )
+*
+*     complex workspace: 2*MN+NB*NRHS.
+*
+*     B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
+*
+      CALL ZTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
+     $            NRHS, CONE, A, LDA, B, LDB )
+*
+      DO 40 J = 1, NRHS
+         DO 30 I = RANK + 1, N
+            B( I, J ) = CZERO
+   30    CONTINUE
+   40 CONTINUE
+*
+*     B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
+*
+      IF( RANK.LT.N ) THEN
+         CALL ZUNMRZ( 'Left', 'Conjugate transpose', N, NRHS, RANK,
+     $                N-RANK, A, LDA, WORK( MN+1 ), B, LDB,
+     $                WORK( 2*MN+1 ), LWORK-2*MN, INFO )
+      END IF
+*
+*     complex workspace: 2*MN+NRHS.
+*
+*     B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
+*
+      DO 60 J = 1, NRHS
+         DO 50 I = 1, N
+            WORK( JPVT( I ) ) = B( I, J )
+   50    CONTINUE
+         CALL ZCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )
+   60 CONTINUE
+*
+*     complex workspace: N.
+*
+*     Undo scaling
+*
+      IF( IASCL.EQ.1 ) THEN
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
+         CALL ZLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      ELSE IF( IASCL.EQ.2 ) THEN
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
+         CALL ZLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
+     $                INFO )
+      END IF
+      IF( IBSCL.EQ.1 ) THEN
+         CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
+      ELSE IF( IBSCL.EQ.2 ) THEN
+         CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
+      END IF
+*
+   70 CONTINUE
+      WORK( 1 ) = DCMPLX( LWKOPT )
+*
+      RETURN
+*
+*     End of ZGELSY
+*
+      END
diff --git a/libcruft/lapack/zgeqp3.f b/libcruft/lapack/zgeqp3.f
new file mode 100644
index 0000000..32bf336
--- /dev/null
+++ b/libcruft/lapack/zgeqp3.f
@@ -0,0 +1,293 @@
+      SUBROUTINE ZGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEQP3 computes a QR factorization with column pivoting of a
+*  matrix A:  A*P = Q*R  using Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper trapezoidal matrix R; the elements below
+*          the diagonal, together with the array TAU, represent the
+*          unitary matrix Q as a product of min(M,N) elementary
+*          reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(J).ne.0, the J-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(J)=0,
+*          the J-th column of A is a free column.
+*          On exit, if JPVT(J)=K, then the J-th column of A*P was the
+*          the K-th column of A.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= N+1.
+*          For optimal performance LWORK >= ( N+1 )*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit.
+*          < 0: if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a real/complex scalar, and v is a real/complex vector
+*  with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
+*  A(i+1:m,i), and tau in TAU(i).
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            INB, INBMIN, IXOVER
+      PARAMETER          ( INB = 1, INBMIN = 2, IXOVER = 3 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,
+     $                   NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEQRF, ZLAQP2, ZLAQPS, ZSWAP, ZUNMQR
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DZNRM2
+      EXTERNAL           ILAENV, DZNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          INT, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test input arguments
+*     ====================
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         MINMN = MIN( M, N )
+         IF( MINMN.EQ.0 ) THEN
+            IWS = 1
+            LWKOPT = 1
+         ELSE
+            IWS = N + 1
+            NB = ILAENV( INB, 'ZGEQRF', ' ', M, N, -1, -1 )
+            LWKOPT = ( N + 1 )*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEQP3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( MINMN.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Move initial columns up front.
+*
+      NFXD = 1
+      DO 10 J = 1, N
+         IF( JPVT( J ).NE.0 ) THEN
+            IF( J.NE.NFXD ) THEN
+               CALL ZSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
+               JPVT( J ) = JPVT( NFXD )
+               JPVT( NFXD ) = J
+            ELSE
+               JPVT( J ) = J
+            END IF
+            NFXD = NFXD + 1
+         ELSE
+            JPVT( J ) = J
+         END IF
+   10 CONTINUE
+      NFXD = NFXD - 1
+*
+*     Factorize fixed columns
+*     =======================
+*
+*     Compute the QR factorization of fixed columns and update
+*     remaining columns.
+*
+      IF( NFXD.GT.0 ) THEN
+         NA = MIN( M, NFXD )
+*CC      CALL ZGEQR2( M, NA, A, LDA, TAU, WORK, INFO )
+         CALL ZGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
+         IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         IF( NA.LT.N ) THEN
+*CC         CALL ZUNM2R( 'Left', 'Conjugate Transpose', M, N-NA,
+*CC  $                   NA, A, LDA, TAU, A( 1, NA+1 ), LDA, WORK,
+*CC  $                   INFO )
+            CALL ZUNMQR( 'Left', 'Conjugate Transpose', M, N-NA, NA, A,
+     $                   LDA, TAU, A( 1, NA+1 ), LDA, WORK, LWORK,
+     $                   INFO )
+            IWS = MAX( IWS, INT( WORK( 1 ) ) )
+         END IF
+      END IF
+*
+*     Factorize free columns
+*     ======================
+*
+      IF( NFXD.LT.MINMN ) THEN
+*
+         SM = M - NFXD
+         SN = N - NFXD
+         SMINMN = MINMN - NFXD
+*
+*        Determine the block size.
+*
+         NB = ILAENV( INB, 'ZGEQRF', ' ', SM, SN, -1, -1 )
+         NBMIN = 2
+         NX = 0
+*
+         IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
+*
+*           Determine when to cross over from blocked to unblocked code.
+*
+            NX = MAX( 0, ILAENV( IXOVER, 'ZGEQRF', ' ', SM, SN, -1,
+     $           -1 ) )
+*
+*
+            IF( NX.LT.SMINMN ) THEN
+*
+*              Determine if workspace is large enough for blocked code.
+*
+               MINWS = ( SN+1 )*NB
+               IWS = MAX( IWS, MINWS )
+               IF( LWORK.LT.MINWS ) THEN
+*
+*                 Not enough workspace to use optimal NB: Reduce NB and
+*                 determine the minimum value of NB.
+*
+                  NB = LWORK / ( SN+1 )
+                  NBMIN = MAX( 2, ILAENV( INBMIN, 'ZGEQRF', ' ', SM, SN,
+     $                    -1, -1 ) )
+*
+*
+               END IF
+            END IF
+         END IF
+*
+*        Initialize partial column norms. The first N elements of work
+*        store the exact column norms.
+*
+         DO 20 J = NFXD + 1, N
+            RWORK( J ) = DZNRM2( SM, A( NFXD+1, J ), 1 )
+            RWORK( N+J ) = RWORK( J )
+   20    CONTINUE
+*
+         IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
+     $       ( NX.LT.SMINMN ) ) THEN
+*
+*           Use blocked code initially.
+*
+            J = NFXD + 1
+*
+*           Compute factorization: while loop.
+*
+*
+            TOPBMN = MINMN - NX
+   30       CONTINUE
+            IF( J.LE.TOPBMN ) THEN
+               JB = MIN( NB, TOPBMN-J+1 )
+*
+*              Factorize JB columns among columns J:N.
+*
+               CALL ZLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
+     $                      JPVT( J ), TAU( J ), RWORK( J ),
+     $                      RWORK( N+J ), WORK( 1 ), WORK( JB+1 ),
+     $                      N-J+1 )
+*
+               J = J + FJB
+               GO TO 30
+            END IF
+         ELSE
+            J = NFXD + 1
+         END IF
+*
+*        Use unblocked code to factor the last or only block.
+*
+*
+         IF( J.LE.MINMN )
+     $      CALL ZLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
+     $                   TAU( J ), RWORK( J ), RWORK( N+J ), WORK( 1 ) )
+*
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZGEQP3
+*
+      END
diff --git a/libcruft/lapack/zgeqpf.f b/libcruft/lapack/zgeqpf.f
new file mode 100644
index 0000000..6d4f86f
--- /dev/null
+++ b/libcruft/lapack/zgeqpf.f
@@ -0,0 +1,234 @@
+      SUBROUTINE ZGEQPF( M, N, A, LDA, JPVT, TAU, WORK, RWORK, INFO )
+*
+*  -- LAPACK deprecated driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  This routine is deprecated and has been replaced by routine ZGEQP3.
+*
+*  ZGEQPF computes a QR factorization with column pivoting of a
+*  complex M-by-N matrix A: A*P = Q*R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of the array contains the
+*          min(M,N)-by-N upper triangular matrix R; the elements
+*          below the diagonal, together with the array TAU,
+*          represent the unitary matrix Q as a product of
+*          min(m,n) elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(n)
+*
+*  Each H(i) has the form
+*
+*     H = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i).
+*
+*  The matrix P is represented in jpvt as follows: If
+*     jpvt(j) = i
+*  then the jth column of P is the ith canonical unit vector.
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MA, MN, PVT
+      DOUBLE PRECISION   TEMP, TEMP2, TOL3Z
+      COMPLEX*16         AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEQR2, ZLARF, ZLARFG, ZSWAP, ZUNM2R
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DCMPLX, DCONJG, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DZNRM2
+      EXTERNAL           IDAMAX, DLAMCH, DZNRM2
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEQPF', -INFO )
+         RETURN
+      END IF
+*
+      MN = MIN( M, N )
+      TOL3Z = SQRT(DLAMCH('Epsilon'))
+*
+*     Move initial columns up front
+*
+      ITEMP = 1
+      DO 10 I = 1, N
+         IF( JPVT( I ).NE.0 ) THEN
+            IF( I.NE.ITEMP ) THEN
+               CALL ZSWAP( M, A( 1, I ), 1, A( 1, ITEMP ), 1 )
+               JPVT( I ) = JPVT( ITEMP )
+               JPVT( ITEMP ) = I
+            ELSE
+               JPVT( I ) = I
+            END IF
+            ITEMP = ITEMP + 1
+         ELSE
+            JPVT( I ) = I
+         END IF
+   10 CONTINUE
+      ITEMP = ITEMP - 1
+*
+*     Compute the QR factorization and update remaining columns
+*
+      IF( ITEMP.GT.0 ) THEN
+         MA = MIN( ITEMP, M )
+         CALL ZGEQR2( M, MA, A, LDA, TAU, WORK, INFO )
+         IF( MA.LT.N ) THEN
+            CALL ZUNM2R( 'Left', 'Conjugate transpose', M, N-MA, MA, A,
+     $                   LDA, TAU, A( 1, MA+1 ), LDA, WORK, INFO )
+         END IF
+      END IF
+*
+      IF( ITEMP.LT.MN ) THEN
+*
+*        Initialize partial column norms. The first n elements of
+*        work store the exact column norms.
+*
+         DO 20 I = ITEMP + 1, N
+            RWORK( I ) = DZNRM2( M-ITEMP, A( ITEMP+1, I ), 1 )
+            RWORK( N+I ) = RWORK( I )
+   20    CONTINUE
+*
+*        Compute factorization
+*
+         DO 40 I = ITEMP + 1, MN
+*
+*           Determine ith pivot column and swap if necessary
+*
+            PVT = ( I-1 ) + IDAMAX( N-I+1, RWORK( I ), 1 )
+*
+            IF( PVT.NE.I ) THEN
+               CALL ZSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+               ITEMP = JPVT( PVT )
+               JPVT( PVT ) = JPVT( I )
+               JPVT( I ) = ITEMP
+               RWORK( PVT ) = RWORK( I )
+               RWORK( N+PVT ) = RWORK( N+I )
+            END IF
+*
+*           Generate elementary reflector H(i)
+*
+            AII = A( I, I )
+            CALL ZLARFG( M-I+1, AII, A( MIN( I+1, M ), I ), 1,
+     $                   TAU( I ) )
+            A( I, I ) = AII
+*
+            IF( I.LT.N ) THEN
+*
+*              Apply H(i) to A(i:m,i+1:n) from the left
+*
+               AII = A( I, I )
+               A( I, I ) = DCMPLX( ONE )
+               CALL ZLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
+     $                     DCONJG( TAU( I ) ), A( I, I+1 ), LDA, WORK )
+               A( I, I ) = AII
+            END IF
+*
+*           Update partial column norms
+*
+            DO 30 J = I + 1, N
+               IF( RWORK( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*                 
+                  TEMP = ABS( A( I, J ) ) / RWORK( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( RWORK( J ) / RWORK( N+J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN 
+                     IF( M-I.GT.0 ) THEN
+                        RWORK( J ) = DZNRM2( M-I, A( I+1, J ), 1 )
+                        RWORK( N+J ) = RWORK( J )
+                     ELSE
+                        RWORK( J ) = ZERO
+                        RWORK( N+J ) = ZERO
+                     END IF
+                  ELSE
+                     RWORK( J ) = RWORK( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   30       CONTINUE
+*
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZGEQPF
+*
+      END
diff --git a/libcruft/lapack/zgeqr2.f b/libcruft/lapack/zgeqr2.f
new file mode 100644
index 0000000..962ab58
--- /dev/null
+++ b/libcruft/lapack/zgeqr2.f
@@ -0,0 +1,121 @@
+      SUBROUTINE ZGEQR2( M, N, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEQR2 computes a QR factorization of a complex m by n matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(m,n) by n upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of elementary reflectors (see Further Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, K
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARF, ZLARFG
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEQR2', -INFO )
+         RETURN
+      END IF
+*
+      K = MIN( M, N )
+*
+      DO 10 I = 1, K
+*
+*        Generate elementary reflector H(i) to annihilate A(i+1:m,i)
+*
+         CALL ZLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,
+     $                TAU( I ) )
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i)' to A(i:m,i+1:n) from the left
+*
+            ALPHA = A( I, I )
+            A( I, I ) = ONE
+            CALL ZLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
+     $                  DCONJG( TAU( I ) ), A( I, I+1 ), LDA, WORK )
+            A( I, I ) = ALPHA
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of ZGEQR2
+*
+      END
diff --git a/libcruft/lapack/zgeqrf.f b/libcruft/lapack/zgeqrf.f
new file mode 100644
index 0000000..d11c924
--- /dev/null
+++ b/libcruft/lapack/zgeqrf.f
@@ -0,0 +1,196 @@
+      SUBROUTINE ZGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGEQRF computes a QR factorization of a complex M-by-N matrix A:
+*  A = Q * R.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the elements on and above the diagonal of the array
+*          contain the min(M,N)-by-N upper trapezoidal matrix R (R is
+*          upper triangular if m >= n); the elements below the diagonal,
+*          with the array TAU, represent the unitary matrix Q as a
+*          product of min(m,n) elementary reflectors (see Further
+*          Details).
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(k), where k = min(m,n).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),
+*  and tau in TAU(i).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEQR2, ZLARFB, ZLARFT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGEQRF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      K = MIN( M, N )
+      IF( K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'ZGEQRF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'ZGEQRF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code initially
+*
+         DO 10 I = 1, K - NX, NB
+            IB = MIN( K-I+1, NB )
+*
+*           Compute the QR factorization of the current block
+*           A(i:m,i:i+ib-1)
+*
+            CALL ZGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL ZLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i:m,i+ib:n) from the left
+*
+               CALL ZLARFB( 'Left', 'Conjugate transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+   10    CONTINUE
+      ELSE
+         I = 1
+      END IF
+*
+*     Use unblocked code to factor the last or only block.
+*
+      IF( I.LE.K )
+     $   CALL ZGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,
+     $                IINFO )
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZGEQRF
+*
+      END
diff --git a/libcruft/lapack/zgesv.f b/libcruft/lapack/zgesv.f
new file mode 100644
index 0000000..b5f61f8
--- /dev/null
+++ b/libcruft/lapack/zgesv.f
@@ -0,0 +1,107 @@
+      SUBROUTINE ZGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGESV computes the solution to a complex system of linear equations
+*     A * X = B,
+*  where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
+*
+*  The LU decomposition with partial pivoting and row interchanges is
+*  used to factor A as
+*     A = P * L * U,
+*  where P is a permutation matrix, L is unit lower triangular, and U is
+*  upper triangular.  The factored form of A is then used to solve the
+*  system of equations A * X = B.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of linear equations, i.e., the order of the
+*          matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the N-by-N coefficient matrix A.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices that define the permutation matrix P;
+*          row i of the matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS matrix of right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero.  The factorization
+*                has been completed, but the factor U is exactly
+*                singular, so the solution could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGETRF, ZGETRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGESV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the LU factorization of A.
+*
+      CALL ZGETRF( N, N, A, LDA, IPIV, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL ZGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, B, LDB,
+     $                INFO )
+      END IF
+      RETURN
+*
+*     End of ZGESV
+*
+      END
diff --git a/libcruft/lapack/zgesvd.f b/libcruft/lapack/zgesvd.f
new file mode 100644
index 0000000..7b238d8
--- /dev/null
+++ b/libcruft/lapack/zgesvd.f
@@ -0,0 +1,3602 @@
+      SUBROUTINE ZGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBU, JOBVT
+      INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * ), S( * )
+      COMPLEX*16         A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGESVD computes the singular value decomposition (SVD) of a complex
+*  M-by-N matrix A, optionally computing the left and/or right singular
+*  vectors. The SVD is written
+*
+*       A = U * SIGMA * conjugate-transpose(V)
+*
+*  where SIGMA is an M-by-N matrix which is zero except for its
+*  min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
+*  V is an N-by-N unitary matrix.  The diagonal elements of SIGMA
+*  are the singular values of A; they are real and non-negative, and
+*  are returned in descending order.  The first min(m,n) columns of
+*  U and V are the left and right singular vectors of A.
+*
+*  Note that the routine returns V**H, not V.
+*
+*  Arguments
+*  =========
+*
+*  JOBU    (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix U:
+*          = 'A':  all M columns of U are returned in array U:
+*          = 'S':  the first min(m,n) columns of U (the left singular
+*                  vectors) are returned in the array U;
+*          = 'O':  the first min(m,n) columns of U (the left singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no columns of U (no left singular vectors) are
+*                  computed.
+*
+*  JOBVT   (input) CHARACTER*1
+*          Specifies options for computing all or part of the matrix
+*          V**H:
+*          = 'A':  all N rows of V**H are returned in the array VT;
+*          = 'S':  the first min(m,n) rows of V**H (the right singular
+*                  vectors) are returned in the array VT;
+*          = 'O':  the first min(m,n) rows of V**H (the right singular
+*                  vectors) are overwritten on the array A;
+*          = 'N':  no rows of V**H (no right singular vectors) are
+*                  computed.
+*
+*          JOBVT and JOBU cannot both be 'O'.
+*
+*  M       (input) INTEGER
+*          The number of rows of the input matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the input matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit,
+*          if JOBU = 'O',  A is overwritten with the first min(m,n)
+*                          columns of U (the left singular vectors,
+*                          stored columnwise);
+*          if JOBVT = 'O', A is overwritten with the first min(m,n)
+*                          rows of V**H (the right singular vectors,
+*                          stored rowwise);
+*          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
+*                          are destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
+*          The singular values of A, sorted so that S(i) >= S(i+1).
+*
+*  U       (output) COMPLEX*16 array, dimension (LDU,UCOL)
+*          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
+*          If JOBU = 'A', U contains the M-by-M unitary matrix U;
+*          if JOBU = 'S', U contains the first min(m,n) columns of U
+*          (the left singular vectors, stored columnwise);
+*          if JOBU = 'N' or 'O', U is not referenced.
+*
+*  LDU     (input) INTEGER
+*          The leading dimension of the array U.  LDU >= 1; if
+*          JOBU = 'S' or 'A', LDU >= M.
+*
+*  VT      (output) COMPLEX*16 array, dimension (LDVT,N)
+*          If JOBVT = 'A', VT contains the N-by-N unitary matrix
+*          V**H;
+*          if JOBVT = 'S', VT contains the first min(m,n) rows of
+*          V**H (the right singular vectors, stored rowwise);
+*          if JOBVT = 'N' or 'O', VT is not referenced.
+*
+*  LDVT    (input) INTEGER
+*          The leading dimension of the array VT.  LDVT >= 1; if
+*          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          LWORK >=  MAX(1,2*MIN(M,N)+MAX(M,N)).
+*          For good performance, LWORK should generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (5*min(M,N))
+*          On exit, if INFO > 0, RWORK(1:MIN(M,N)-1) contains the
+*          unconverged superdiagonal elements of an upper bidiagonal
+*          matrix B whose diagonal is in S (not necessarily sorted).
+*          B satisfies A = U * B * VT, so it has the same singular
+*          values as A, and singular vectors related by U and VT.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          > 0:  if ZBDSQR did not converge, INFO specifies how many
+*                superdiagonals of an intermediate bidiagonal form B
+*                did not converge to zero. See the description of RWORK
+*                above for details.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
+     $                   CONE = ( 1.0D0, 0.0D0 ) )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
+     $                   WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
+      INTEGER            BLK, CHUNK, I, IE, IERR, IR, IRWORK, ISCL,
+     $                   ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
+     $                   MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
+     $                   NRVT, WRKBL
+      DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 )
+      COMPLEX*16         CDUM( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLASCL, XERBLA, ZBDSQR, ZGEBRD, ZGELQF, ZGEMM,
+     $                   ZGEQRF, ZLACPY, ZLASCL, ZLASET, ZUNGBR, ZUNGLQ,
+     $                   ZUNGQR, ZUNMBR
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      MINMN = MIN( M, N )
+      WNTUA = LSAME( JOBU, 'A' )
+      WNTUS = LSAME( JOBU, 'S' )
+      WNTUAS = WNTUA .OR. WNTUS
+      WNTUO = LSAME( JOBU, 'O' )
+      WNTUN = LSAME( JOBU, 'N' )
+      WNTVA = LSAME( JOBVT, 'A' )
+      WNTVS = LSAME( JOBVT, 'S' )
+      WNTVAS = WNTVA .OR. WNTVS
+      WNTVO = LSAME( JOBVT, 'O' )
+      WNTVN = LSAME( JOBVT, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
+     $         ( WNTVO .AND. WNTUO ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
+         INFO = -9
+      ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
+     $         ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
+         INFO = -11
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       CWorkspace refers to complex workspace, and RWorkspace to
+*       real workspace. NB refers to the optimal block size for the
+*       immediately following subroutine, as returned by ILAENV.)
+*
+      IF( INFO.EQ.0 ) THEN
+         MINWRK = 1
+         MAXWRK = 1
+         IF( M.GE.N .AND. MINMN.GT.0 ) THEN
+*
+*           Space needed for ZBDSQR is BDSPAC = 5*N
+*
+            MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            IF( M.GE.MNTHR ) THEN
+               IF( WNTUN ) THEN
+*
+*                 Path 1 (M much larger than N, JOBU='N')
+*
+                  MAXWRK = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 2*N+2*N*
+     $                     ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  IF( WNTVO .OR. WNTVAS )
+     $               MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
+     $                        ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+                  MINWRK = 3*N
+               ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUS .AND. WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUS .AND. WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUS .AND. WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUA .AND. WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUA .AND. WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = 2*N*N + WRKBL
+                  MINWRK = 2*N + M
+               ELSE IF( WNTUA .AND. WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
+*                 'A')
+*
+                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
+     $                    M, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+2*N*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+N*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*N+( N-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+                  MAXWRK = N*N + WRKBL
+                  MINWRK = 2*N + M
+               END IF
+            ELSE
+*
+*              Path 10 (M at least N, but not much larger)
+*
+               MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTUS .OR. WNTUO )
+     $            MAXWRK = MAX( MAXWRK, 2*N+N*
+     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
+               IF( WNTUA )
+     $            MAXWRK = MAX( MAXWRK, 2*N+M*
+     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
+               IF( .NOT.WNTVN )
+     $            MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
+     $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+               MINWRK = 2*N + M
+            END IF
+         ELSE IF( MINMN.GT.0 ) THEN
+*
+*           Space needed for ZBDSQR is BDSPAC = 5*M
+*
+            MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
+            IF( N.GE.MNTHR ) THEN
+               IF( WNTVN ) THEN
+*
+*                 Path 1t(N much larger than M, JOBVT='N')
+*
+                  MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
+     $                     -1 )
+                  MAXWRK = MAX( MAXWRK, 2*M+2*M*
+     $                     ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  IF( WNTUO .OR. WNTUAS )
+     $               MAXWRK = MAX( MAXWRK, 2*M+M*
+     $                        ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+                  MINWRK = 3*M
+               ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*                 Path 3t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='O')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVS .AND. WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVS .AND. WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVS .AND. WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='S')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVA .AND. WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVA .AND. WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = 2*M*M + WRKBL
+                  MINWRK = 2*M + N
+               ELSE IF( WNTVA .AND. WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                 JOBVT='A')
+*
+                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
+                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
+     $                    N, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+2*M*
+     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+( M-1 )*
+     $                    ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+                  WRKBL = MAX( WRKBL, 2*M+M*
+     $                    ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+                  MAXWRK = M*M + WRKBL
+                  MINWRK = 2*M + N
+               END IF
+            ELSE
+*
+*              Path 10t(N greater than M, but not much larger)
+*
+               MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
+     $                  -1, -1 )
+               IF( WNTVS .OR. WNTVO )
+     $            MAXWRK = MAX( MAXWRK, 2*M+M*
+     $                     ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
+               IF( WNTVA )
+     $            MAXWRK = MAX( MAXWRK, 2*M+N*
+     $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, M, -1 ) )
+               IF( .NOT.WNTUN )
+     $            MAXWRK = MAX( MAXWRK, 2*M+( M-1 )*
+     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+               MINWRK = 2*M + N
+            END IF
+         END IF
+         MAXWRK = MAX( MAXWRK, MINWRK )
+         WORK( 1 ) = MAXWRK
+*
+         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGESVD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = ZLANGE( 'M', M, N, A, LDA, DUM )
+      ISCL = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ISCL = 1
+         CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ISCL = 1
+         CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
+      END IF
+*
+      IF( M.GE.N ) THEN
+*
+*        A has at least as many rows as columns. If A has sufficiently
+*        more rows than columns, first reduce using the QR
+*        decomposition (if sufficient workspace available)
+*
+         IF( M.GE.MNTHR ) THEN
+*
+            IF( WNTUN ) THEN
+*
+*              Path 1 (M much larger than N, JOBU='N')
+*              No left singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + N
+*
+*              Compute A=Q*R
+*              (CWorkspace: need 2*N, prefer N+N*NB)
+*              (RWorkspace: need 0)
+*
+               CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out below R
+*
+               CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                      LDA )
+               IE = 1
+               ITAUQ = 1
+               ITAUP = ITAUQ + N
+               IWORK = ITAUP + N
+*
+*              Bidiagonalize R in A
+*              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*              (RWorkspace: need N)
+*
+               CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               NCVT = 0
+               IF( WNTVO .OR. WNTVAS ) THEN
+*
+*                 If right singular vectors desired, generate P'.
+*                 (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  NCVT = N
+               END IF
+               IRWORK = IE + N
+*
+*              Perform bidiagonal QR iteration, computing right
+*              singular vectors of A in A if desired
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'U', N, NCVT, 0, 0, S, RWORK( IE ), A, LDA,
+     $                      CDUM, 1, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+*              If right singular vectors desired in VT, copy them there
+*
+               IF( WNTVAS )
+     $            CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
+*
+            ELSE IF( WNTUO .AND. WNTVN ) THEN
+*
+*              Path 2 (M much larger than N, JOBU='O', JOBVT='N')
+*              N left singular vectors to be overwritten on A and
+*              no right singular vectors to be computed
+*
+               IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N, WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N, WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to WORK(IR) and zero out below it
+*
+                  CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
+                  CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                         WORK( IR+1 ), LDWRKR )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in WORK(IR)
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                 (RWorkspace: need N)
+*
+                  CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing R
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                 (RWorkspace: need 0)
+*
+                  CALL ZUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR)
+*                 (CWorkspace: need N*N)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM, 1,
+     $                         WORK( IR ), LDWRKR, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need N*N+N, prefer N*N+M*N)
+*                 (RWorkspace: 0)
+*
+                  DO 10 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL ZGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   10             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = 1
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize A
+*                 (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
+*                 (RWorkspace: N)
+*
+                  CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing A
+*                 (CWorkspace: need 3*N, prefer 2*N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A
+*                 (CWorkspace: need 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM, 1,
+     $                         A, LDA, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUO .AND. WNTVAS ) THEN
+*
+*              Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
+*              N left singular vectors to be overwritten on A and
+*              N right singular vectors to be computed in VT
+*
+               IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+N*N ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                     LDWRKU = LDA
+                     LDWRKR = N
+                  ELSE
+*
+*                    WORK(IU) is LDWRKU by N and WORK(IR) is N by N
+*
+                     LDWRKU = ( LWORK-N*N ) / N
+                     LDWRKR = N
+                  END IF
+                  ITAU = IR + LDWRKR*N
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT, copying result to WORK(IR)
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                 (RWorkspace: need N)
+*
+                  CALL ZGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL ZLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
+*
+*                 Generate left vectors bidiagonalizing R in WORK(IR)
+*                 (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUQ ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (CWorkspace: need N*N+3*N-1, prefer N*N+2*N+(N-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of R in WORK(IR) and computing right
+*                 singular vectors of R in VT
+*                 (CWorkspace: need N*N)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
+     $                         LDVT, WORK( IR ), LDWRKR, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply Q in A by left singular vectors of R in
+*                 WORK(IR), storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need N*N+N, prefer N*N+M*N)
+*                 (RWorkspace: 0)
+*
+                  DO 20 I = 1, M, LDWRKU
+                     CHUNK = MIN( M-I+1, LDWRKU )
+                     CALL ZGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
+     $                           LDA, WORK( IR ), LDWRKR, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
+     $                            A( I, 1 ), LDA )
+   20             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + N
+*
+*                 Compute A=Q*R
+*                 (CWorkspace: need 2*N, prefer N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy R to VT, zeroing out below it
+*
+                  CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                  IF( N.GT.1 )
+     $               CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            VT( 2, 1 ), LDVT )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need 2*N, prefer N+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + N
+                  IWORK = ITAUP + N
+*
+*                 Bidiagonalize R in VT
+*                 (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                 (RWorkspace: N)
+*
+                  CALL ZGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply Q in A by left vectors bidiagonalizing R
+*                 (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing R in VT
+*                 (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + N
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in A and computing right
+*                 singular vectors of A in VT
+*                 (CWorkspace: 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
+     $                         LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
+     $                         INFO )
+*
+               END IF
+*
+            ELSE IF( WNTUS ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
+*                 N left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left vectors bidiagonalizing R in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM,
+     $                            1, WORK( IR ), LDWRKR, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IR), storing result in U
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
+     $                           WORK( IR ), LDWRKR, CZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM,
+     $                            1, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+3*N ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (CWorkspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N,
+*                                 prefer 2*N*N+2*N+2*N*NB)
+*                    (RWorkspace: need   N)
+*
+                     CALL ZGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N-1,
+*                                 prefer 2*N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (CWorkspace: need 2*N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, N, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, CZERO, U, LDU )
+*
+*                    Copy right singular vectors of R to A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left vectors bidiagonalizing R
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing R in A
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), A,
+     $                            LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 6 (M much larger than N, JOBU='S', JOBVT='S'
+*                         or 'A')
+*                 N left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+3*N ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need   N*N+3*N-1,
+*                                 prefer N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in A by left singular vectors of R in
+*                    WORK(IU), storing result in U
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
+     $                           WORK( IU ), LDWRKU, CZERO, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, N, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to VT, zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTUA ) THEN
+*
+               IF( WNTVN ) THEN
+*
+*                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
+*                 M left singular vectors to be computed in U and
+*                 no right singular vectors to be computed
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 3*N ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IR) is LDA by N
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is N by N
+*
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Copy R to WORK(IR), zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IR+1 ), LDWRKR )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N*N+N+M, prefer N*N+N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IR)
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM,
+     $                            1, WORK( IR ), LDWRKR, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IR), storing result in A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
+     $                           WORK( IR ), LDWRKR, CZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N+M, prefer N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM,
+     $                            1, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVO ) THEN
+*
+*                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*N*N+MAX( N+M, 3*N ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+*
+*                       WORK(IU) is LDA by N and WORK(IR) is N by N
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     ELSE
+*
+*                       WORK(IU) is N by N and WORK(IR) is N by N
+*
+                        LDWRKU = N
+                        IR = IU + LDWRKU*N
+                        LDWRKR = N
+                     END IF
+                     ITAU = IR + LDWRKR*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N,
+*                                 prefer 2*N*N+2*N+2*N*NB)
+*                    (RWorkspace: need   N)
+*
+                     CALL ZGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', N, N, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need   2*N*N+3*N-1,
+*                                 prefer 2*N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in WORK(IR)
+*                    (CWorkspace: need 2*N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, N, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, WORK( IU ),
+     $                            LDWRKU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, CZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+*                    Copy right singular vectors of R from WORK(IR) to A
+*
+                     CALL ZLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N+M, prefer N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Zero out below R in A
+*
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            A( 2, 1 ), LDA )
+*
+*                    Bidiagonalize R in A
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in A
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in A
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in A
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), A,
+     $                            LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTVAS ) THEN
+*
+*                 Path 9 (M much larger than N, JOBU='A', JOBVT='S'
+*                         or 'A')
+*                 M left singular vectors to be computed in U and
+*                 N right singular vectors to be computed in VT
+*
+                  IF( LWORK.GE.N*N+MAX( N+M, 3*N ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*N ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is N by N
+*
+                        LDWRKU = N
+                     END IF
+                     ITAU = IU + LDWRKU*N
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N*N+N+M, prefer N*N+N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R to WORK(IU), zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                            WORK( IU+1 ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in WORK(IU), copying result to VT
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
+     $                            LDVT )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need   N*N+3*N-1,
+*                                 prefer N*N+2*N+(N-1)*NB)
+*                    (RWorkspace: need   0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of R in WORK(IU) and computing
+*                    right singular vectors of R in VT
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
+     $                            LDVT, WORK( IU ), LDWRKU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply Q in U by left singular vectors of R in
+*                    WORK(IU), storing result in A
+*                    (CWorkspace: need N*N)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
+     $                           WORK( IU ), LDWRKU, CZERO, A, LDA )
+*
+*                    Copy left singular vectors of A from A to U
+*
+                     CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + N
+*
+*                    Compute A=Q*R, copying result to U
+*                    (CWorkspace: need 2*N, prefer N+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+*
+*                    Generate Q in U
+*                    (CWorkspace: need N+M, prefer N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy R from A to VT, zeroing out below it
+*
+                     CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
+                     IF( N.GT.1 )
+     $                  CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               VT( 2, 1 ), LDVT )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + N
+                     IWORK = ITAUP + N
+*
+*                    Bidiagonalize R in VT
+*                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
+*                    (RWorkspace: need N)
+*
+                     CALL ZGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply Q in U by left bidiagonalizing vectors
+*                    in VT
+*                    (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
+     $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in VT
+*                    (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + N
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           M .LT. MNTHR
+*
+*           Path 10 (M at least N, but not much larger)
+*           Reduce to bidiagonal form without QR decomposition
+*
+            IE = 1
+            ITAUQ = 1
+            ITAUP = ITAUQ + N
+            IWORK = ITAUP + N
+*
+*           Bidiagonalize A
+*           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
+*           (RWorkspace: need N)
+*
+            CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (CWorkspace: need 2*N+NCU, prefer 2*N+NCU*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
+               IF( WNTUS )
+     $            NCU = N
+               IF( WNTUA )
+     $            NCU = M
+               CALL ZUNGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
+               CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IRWORK = IE + N
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), A,
+     $                      LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            END IF
+*
+         END IF
+*
+      ELSE
+*
+*        A has more columns than rows. If A has sufficiently more
+*        columns than rows, first reduce using the LQ decomposition (if
+*        sufficient workspace available)
+*
+         IF( N.GE.MNTHR ) THEN
+*
+            IF( WNTVN ) THEN
+*
+*              Path 1t(N much larger than M, JOBVT='N')
+*              No right singular vectors to be computed
+*
+               ITAU = 1
+               IWORK = ITAU + M
+*
+*              Compute A=L*Q
+*              (CWorkspace: need 2*M, prefer M+M*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
+     $                      LWORK-IWORK+1, IERR )
+*
+*              Zero out above L
+*
+               CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
+     $                      LDA )
+               IE = 1
+               ITAUQ = 1
+               ITAUP = ITAUQ + M
+               IWORK = ITAUP + M
+*
+*              Bidiagonalize L in A
+*              (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*              (RWorkspace: need M)
+*
+               CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                      IERR )
+               IF( WNTUO .OR. WNTUAS ) THEN
+*
+*                 If left singular vectors desired, generate Q
+*                 (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+               END IF
+               IRWORK = IE + M
+               NRU = 0
+               IF( WNTUO .OR. WNTUAS )
+     $            NRU = M
+*
+*              Perform bidiagonal QR iteration, computing left singular
+*              vectors of A in A if desired
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'U', M, 0, NRU, 0, S, RWORK( IE ), CDUM, 1,
+     $                      A, LDA, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+*              If left singular vectors desired in U, copy them there
+*
+               IF( WNTUAS )
+     $            CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
+*
+            ELSE IF( WNTVO .AND. WNTUN ) THEN
+*
+*              Path 2t(N much larger than M, JOBU='N', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              no left singular vectors to be computed
+*
+               IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to WORK(IR) and zero out above it
+*
+                  CALL ZLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
+                  CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                         WORK( IR+LDWRKR ), LDWRKR )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in WORK(IR)
+*                 (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL ZGEBRD( M, M, WORK( IR ), LDWRKR, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing L
+*                 (CWorkspace: need M*M+3*M-1, prefer M*M+2*M+(M-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of L in WORK(IR)
+*                 (CWorkspace: need M*M)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
+     $                         WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need M*M+M, prefer M*M+M*N)
+*                 (RWorkspace: 0)
+*
+                  DO 30 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL ZGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL ZLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   30             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  IE = 1
+                  ITAUQ = 1
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize A
+*                 (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Generate right vectors bidiagonalizing A
+*                 (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing right
+*                 singular vectors of A in A
+*                 (CWorkspace: 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'L', M, N, 0, 0, S, RWORK( IE ), A, LDA,
+     $                         CDUM, 1, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVO .AND. WNTUAS ) THEN
+*
+*              Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
+*              M right singular vectors to be overwritten on A and
+*              M left singular vectors to be computed in U
+*
+               IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                 Sufficient workspace for a fast algorithm
+*
+                  IR = 1
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = LDA
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+M*M ) THEN
+*
+*                    WORK(IU) is LDA by N and WORK(IR) is M by M
+*
+                     LDWRKU = LDA
+                     CHUNK = N
+                     LDWRKR = M
+                  ELSE
+*
+*                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
+*
+                     LDWRKU = M
+                     CHUNK = ( LWORK-M*M ) / M
+                     LDWRKR = M
+                  END IF
+                  ITAU = IR + LDWRKR*M
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing about above it
+*
+                  CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U, copying result to WORK(IR)
+*                 (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL ZGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  CALL ZLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
+*
+*                 Generate right vectors bidiagonalizing L in WORK(IR)
+*                 (CWorkspace: need M*M+3*M-1, prefer M*M+2*M+(M-1)*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                         WORK( ITAUP ), WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of L in U, and computing right
+*                 singular vectors of L in WORK(IR)
+*                 (CWorkspace: need M*M)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                         WORK( IR ), LDWRKR, U, LDU, CDUM, 1,
+     $                         RWORK( IRWORK ), INFO )
+                  IU = ITAUQ
+*
+*                 Multiply right singular vectors of L in WORK(IR) by Q
+*                 in A, storing result in WORK(IU) and copying to A
+*                 (CWorkspace: need M*M+M, prefer M*M+M*N))
+*                 (RWorkspace: 0)
+*
+                  DO 40 I = 1, N, CHUNK
+                     BLK = MIN( N-I+1, CHUNK )
+                     CALL ZGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IR ),
+     $                           LDWRKR, A( 1, I ), LDA, CZERO,
+     $                           WORK( IU ), LDWRKU )
+                     CALL ZLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
+     $                            A( 1, I ), LDA )
+   40             CONTINUE
+*
+               ELSE
+*
+*                 Insufficient workspace for a fast algorithm
+*
+                  ITAU = 1
+                  IWORK = ITAU + M
+*
+*                 Compute A=L*Q
+*                 (CWorkspace: need 2*M, prefer M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Copy L to U, zeroing out above it
+*
+                  CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
+                  CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, U( 1, 2 ),
+     $                         LDU )
+*
+*                 Generate Q in A
+*                 (CWorkspace: need 2*M, prefer M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IE = 1
+                  ITAUQ = ITAU
+                  ITAUP = ITAUQ + M
+                  IWORK = ITAUP + M
+*
+*                 Bidiagonalize L in U
+*                 (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                 (RWorkspace: need M)
+*
+                  CALL ZGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                         WORK( ITAUQ ), WORK( ITAUP ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                 Multiply right vectors bidiagonalizing L by Q in A
+*                 (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
+     $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
+     $                         LWORK-IWORK+1, IERR )
+*
+*                 Generate left vectors bidiagonalizing L in U
+*                 (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                 (RWorkspace: 0)
+*
+                  CALL ZUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
+                  IRWORK = IE + M
+*
+*                 Perform bidiagonal QR iteration, computing left
+*                 singular vectors of A in U and computing right
+*                 singular vectors of A in A
+*                 (CWorkspace: 0)
+*                 (RWorkspace: need BDSPAC)
+*
+                  CALL ZBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), A, LDA,
+     $                         U, LDU, CDUM, 1, RWORK( IRWORK ), INFO )
+*
+               END IF
+*
+            ELSE IF( WNTVS ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right vectors bidiagonalizing L in
+*                    WORK(IR)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in A, storing result in VT
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IR ),
+     $                           LDWRKR, A, LDA, CZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy result to VT
+*
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, N, 0, 0, S, RWORK( IE ), VT,
+     $                            LDVT, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+3*M ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out below it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*M*M+3*M,
+*                                 prefer 2*M*M+2*M+2*M*NB)
+*                    (RWorkspace: need   M)
+*
+                     CALL ZGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need   2*M*M+3*M-1,
+*                                 prefer 2*M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (CWorkspace: need 2*M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, CZERO, VT, LDVT )
+*
+*                    Copy left singular vectors of L to A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right vectors bidiagonalizing L by Q in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors of L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in A and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, A, LDA, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 6t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='S')
+*                 M right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+3*M ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by N
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+*
+*                    Generate Q in A
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need   M*M+3*M-1,
+*                                 prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in A, storing result in VT
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, A, LDA, CZERO, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            U( 1, 2 ), LDU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            ELSE IF( WNTVA ) THEN
+*
+               IF( WNTUN ) THEN
+*
+*                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 no left singular vectors to be computed
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 3*M ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IR = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IR) is LDA by M
+*
+                        LDWRKR = LDA
+                     ELSE
+*
+*                       WORK(IR) is M by M
+*
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy L to WORK(IR), zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, WORK( IR ),
+     $                            LDWRKR )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IR+LDWRKR ), LDWRKR )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M*M+M+N, prefer M*M+M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IR)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, WORK( IR ), LDWRKR, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need   M*M+3*M-1,
+*                                 prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of L in WORK(IR)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
+     $                            WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IR) by
+*                    Q in VT, storing result in A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IR ),
+     $                           LDWRKR, VT, LDVT, CZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M+N, prefer M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, N, 0, 0, S, RWORK( IE ), VT,
+     $                            LDVT, CDUM, 1, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUO ) THEN
+*
+*                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be overwritten on A
+*
+                  IF( LWORK.GE.2*M*M+MAX( N+M, 3*M ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = LDA
+                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+*
+*                       WORK(IU) is LDA by M and WORK(IR) is M by M
+*
+                        LDWRKU = LDA
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     ELSE
+*
+*                       WORK(IU) is M by M and WORK(IR) is M by M
+*
+                        LDWRKU = M
+                        IR = IU + LDWRKU*M
+                        LDWRKR = M
+                     END IF
+                     ITAU = IR + LDWRKR*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to
+*                    WORK(IR)
+*                    (CWorkspace: need   2*M*M+3*M,
+*                                 prefer 2*M*M+2*M+2*M*NB)
+*                    (RWorkspace: need   M)
+*
+                     CALL ZGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, M, WORK( IU ), LDWRKU,
+     $                            WORK( IR ), LDWRKR )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need   2*M*M+3*M-1,
+*                                 prefer 2*M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in WORK(IR)
+*                    (CWorkspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
+     $                            WORK( ITAUQ ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in WORK(IR) and computing
+*                    right singular vectors of L in WORK(IU)
+*                    (CWorkspace: need 2*M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, WORK( IR ),
+     $                            LDWRKR, CDUM, 1, RWORK( IRWORK ),
+     $                            INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, CZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+*                    Copy left singular vectors of A from WORK(IR) to A
+*
+                     CALL ZLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
+     $                            LDA )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M+N, prefer M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Zero out above L in A
+*
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            A( 1, 2 ), LDA )
+*
+*                    Bidiagonalize L in A
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in A by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in A
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in A and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, A, LDA, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               ELSE IF( WNTUAS ) THEN
+*
+*                 Path 9t(N much larger than M, JOBU='S' or 'A',
+*                         JOBVT='A')
+*                 N right singular vectors to be computed in VT and
+*                 M left singular vectors to be computed in U
+*
+                  IF( LWORK.GE.M*M+MAX( N+M, 3*M ) ) THEN
+*
+*                    Sufficient workspace for a fast algorithm
+*
+                     IU = 1
+                     IF( LWORK.GE.WRKBL+LDA*M ) THEN
+*
+*                       WORK(IU) is LDA by M
+*
+                        LDWRKU = LDA
+                     ELSE
+*
+*                       WORK(IU) is M by M
+*
+                        LDWRKU = M
+                     END IF
+                     ITAU = IU + LDWRKU*M
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M*M+M+N, prefer M*M+M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to WORK(IU), zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, WORK( IU ),
+     $                            LDWRKU )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            WORK( IU+LDWRKU ), LDWRKU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in WORK(IU), copying result to U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, WORK( IU ), LDWRKU, S,
+     $                            RWORK( IE ), WORK( ITAUQ ),
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
+     $                            LDU )
+*
+*                    Generate right bidiagonalizing vectors in WORK(IU)
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+(M-1)*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
+     $                            WORK( ITAUP ), WORK( IWORK ),
+     $                            LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of L in U and computing right
+*                    singular vectors of L in WORK(IU)
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
+     $                            WORK( IU ), LDWRKU, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+*                    Multiply right singular vectors of L in WORK(IU) by
+*                    Q in VT, storing result in A
+*                    (CWorkspace: need M*M)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
+     $                           LDWRKU, VT, LDVT, CZERO, A, LDA )
+*
+*                    Copy right singular vectors of A from A to VT
+*
+                     CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
+*
+                  ELSE
+*
+*                    Insufficient workspace for a fast algorithm
+*
+                     ITAU = 1
+                     IWORK = ITAU + M
+*
+*                    Compute A=L*Q, copying result to VT
+*                    (CWorkspace: need 2*M, prefer M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZGELQF( M, N, A, LDA, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+*
+*                    Generate Q in VT
+*                    (CWorkspace: need M+N, prefer M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Copy L to U, zeroing out above it
+*
+                     CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
+                     CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
+     $                            U( 1, 2 ), LDU )
+                     IE = 1
+                     ITAUQ = ITAU
+                     ITAUP = ITAUQ + M
+                     IWORK = ITAUP + M
+*
+*                    Bidiagonalize L in U
+*                    (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
+*                    (RWorkspace: need M)
+*
+                     CALL ZGEBRD( M, M, U, LDU, S, RWORK( IE ),
+     $                            WORK( ITAUQ ), WORK( ITAUP ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Multiply right bidiagonalizing vectors in U by Q
+*                    in VT
+*                    (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
+     $                            WORK( ITAUP ), VT, LDVT,
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+*
+*                    Generate left bidiagonalizing vectors in U
+*                    (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*                    (RWorkspace: 0)
+*
+                     CALL ZUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
+     $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
+                     IRWORK = IE + M
+*
+*                    Perform bidiagonal QR iteration, computing left
+*                    singular vectors of A in U and computing right
+*                    singular vectors of A in VT
+*                    (CWorkspace: 0)
+*                    (RWorkspace: need BDSPAC)
+*
+                     CALL ZBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
+     $                            LDVT, U, LDU, CDUM, 1,
+     $                            RWORK( IRWORK ), INFO )
+*
+                  END IF
+*
+               END IF
+*
+            END IF
+*
+         ELSE
+*
+*           N .LT. MNTHR
+*
+*           Path 10t(N greater than M, but not much larger)
+*           Reduce to bidiagonal form without LQ decomposition
+*
+            IE = 1
+            ITAUQ = 1
+            ITAUP = ITAUQ + M
+            IWORK = ITAUP + M
+*
+*           Bidiagonalize A
+*           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
+*           (RWorkspace: M)
+*
+            CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
+     $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
+     $                   IERR )
+            IF( WNTUAS ) THEN
+*
+*              If left singular vectors desired in U, copy result to U
+*              and generate left bidiagonalizing vectors in U
+*              (CWorkspace: need 3*M-1, prefer 2*M+(M-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
+               CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVAS ) THEN
+*
+*              If right singular vectors desired in VT, copy result to
+*              VT and generate right bidiagonalizing vectors in VT
+*              (CWorkspace: need 2*M+NRVT, prefer 2*M+NRVT*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
+               IF( WNTVA )
+     $            NRVT = N
+               IF( WNTVS )
+     $            NRVT = M
+               CALL ZUNGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTUO ) THEN
+*
+*              If left singular vectors desired in A, generate left
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*M-1, prefer 2*M+(M-1)*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZUNGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IF( WNTVO ) THEN
+*
+*              If right singular vectors desired in A, generate right
+*              bidiagonalizing vectors in A
+*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
+*              (RWorkspace: 0)
+*
+               CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
+     $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
+            END IF
+            IRWORK = IE + M
+            IF( WNTUAS .OR. WNTUO )
+     $         NRU = M
+            IF( WNTUN )
+     $         NRU = 0
+            IF( WNTVAS .OR. WNTVO )
+     $         NCVT = N
+            IF( WNTVN )
+     $         NCVT = 0
+            IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in U and computing right singular
+*              vectors in A
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), A,
+     $                      LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            ELSE
+*
+*              Perform bidiagonal QR iteration, if desired, computing
+*              left singular vectors in A and computing right singular
+*              vectors in VT
+*              (CWorkspace: 0)
+*              (RWorkspace: need BDSPAC)
+*
+               CALL ZBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), VT,
+     $                      LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
+     $                      INFO )
+            END IF
+*
+         END IF
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ISCL.EQ.1 ) THEN
+         IF( ANRM.GT.BIGNUM )
+     $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
+     $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
+     $                   RWORK( IE ), MINMN, IERR )
+         IF( ANRM.LT.SMLNUM )
+     $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
+     $                   IERR )
+         IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
+     $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
+     $                   RWORK( IE ), MINMN, IERR )
+      END IF
+*
+*     Return optimal workspace in WORK(1)
+*
+      WORK( 1 ) = MAXWRK
+*
+      RETURN
+*
+*     End of ZGESVD
+*
+      END
diff --git a/libcruft/lapack/zgetf2.f b/libcruft/lapack/zgetf2.f
new file mode 100644
index 0000000..a2dc183
--- /dev/null
+++ b/libcruft/lapack/zgetf2.f
@@ -0,0 +1,148 @@
+      SUBROUTINE ZGETF2( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGETF2 computes an LU factorization of a general m-by-n matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the m by n matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, U(k,k) is exactly zero. The factorization
+*               has been completed, but the factor U is exactly
+*               singular, and division by zero will occur if it is used
+*               to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   SFMIN
+      INTEGER            I, J, JP
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      INTEGER            IZAMAX
+      EXTERNAL           DLAMCH, IZAMAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGERU, ZSCAL, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGETF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Compute machine safe minimum
+*
+      SFMIN = DLAMCH('S') 
+*
+      DO 10 J = 1, MIN( M, N )
+*
+*        Find pivot and test for singularity.
+*
+         JP = J - 1 + IZAMAX( M-J+1, A( J, J ), 1 )
+         IPIV( J ) = JP
+         IF( A( JP, J ).NE.ZERO ) THEN
+*
+*           Apply the interchange to columns 1:N.
+*
+            IF( JP.NE.J )
+     $         CALL ZSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA )
+*
+*           Compute elements J+1:M of J-th column.
+*
+            IF( J.LT.M ) THEN
+               IF( ABS(A( J, J )) .GE. SFMIN ) THEN
+                  CALL ZSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 )
+               ELSE
+                  DO 20 I = 1, M-J
+                     A( J+I, J ) = A( J+I, J ) / A( J, J )
+   20             CONTINUE
+               END IF
+            END IF
+*
+         ELSE IF( INFO.EQ.0 ) THEN
+*
+            INFO = J
+         END IF
+*
+         IF( J.LT.MIN( M, N ) ) THEN
+*
+*           Update trailing submatrix.
+*
+            CALL ZGERU( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ),
+     $                  LDA, A( J+1, J+1 ), LDA )
+         END IF
+   10 CONTINUE
+      RETURN
+*
+*     End of ZGETF2
+*
+      END
diff --git a/libcruft/lapack/zgetrf.f b/libcruft/lapack/zgetrf.f
new file mode 100644
index 0000000..9c7bfbb
--- /dev/null
+++ b/libcruft/lapack/zgetrf.f
@@ -0,0 +1,159 @@
+      SUBROUTINE ZGETRF( M, N, A, LDA, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGETRF computes an LU factorization of a general M-by-N matrix A
+*  using partial pivoting with row interchanges.
+*
+*  The factorization has the form
+*     A = P * L * U
+*  where P is a permutation matrix, L is lower triangular with unit
+*  diagonal elements (lower trapezoidal if m > n), and U is upper
+*  triangular (upper trapezoidal if m < n).
+*
+*  This is the right-looking Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix to be factored.
+*          On exit, the factors L and U from the factorization
+*          A = P*L*U; the unit diagonal elements of L are not stored.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  IPIV    (output) INTEGER array, dimension (min(M,N))
+*          The pivot indices; for 1 <= i <= min(M,N), row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IINFO, J, JB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMM, ZGETF2, ZLASWP, ZTRSM
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGETRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'ZGETRF', ' ', M, N, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN
+*
+*        Use unblocked code.
+*
+         CALL ZGETF2( M, N, A, LDA, IPIV, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         DO 20 J = 1, MIN( M, N ), NB
+            JB = MIN( MIN( M, N )-J+1, NB )
+*
+*           Factor diagonal and subdiagonal blocks and test for exact
+*           singularity.
+*
+            CALL ZGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+*
+*           Adjust INFO and the pivot indices.
+*
+            IF( INFO.EQ.0 .AND. IINFO.GT.0 )
+     $         INFO = IINFO + J - 1
+            DO 10 I = J, MIN( M, J+JB-1 )
+               IPIV( I ) = J - 1 + IPIV( I )
+   10       CONTINUE
+*
+*           Apply interchanges to columns 1:J-1.
+*
+            CALL ZLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 )
+*
+            IF( J+JB.LE.N ) THEN
+*
+*              Apply interchanges to columns J+JB:N.
+*
+               CALL ZLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1,
+     $                      IPIV, 1 )
+*
+*              Compute block row of U.
+*
+               CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB,
+     $                     N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ),
+     $                     LDA )
+               IF( J+JB.LE.M ) THEN
+*
+*                 Update trailing submatrix.
+*
+                  CALL ZGEMM( 'No transpose', 'No transpose', M-J-JB+1,
+     $                        N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA,
+     $                        A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ),
+     $                        LDA )
+               END IF
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZGETRF
+*
+      END
diff --git a/libcruft/lapack/zgetri.f b/libcruft/lapack/zgetri.f
new file mode 100644
index 0000000..685518e
--- /dev/null
+++ b/libcruft/lapack/zgetri.f
@@ -0,0 +1,193 @@
+      SUBROUTINE ZGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGETRI computes the inverse of a matrix using the LU factorization
+*  computed by ZGETRF.
+*
+*  This method inverts U and then computes inv(A) by solving the system
+*  inv(A)*L = inv(U) for inv(A).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the factors L and U from the factorization
+*          A = P*L*U as computed by ZGETRF.
+*          On exit, if INFO = 0, the inverse of the original matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from ZGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO=0, then WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*          For optimal performance LWORK >= N*NB, where NB is
+*          the optimal blocksize returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero; the matrix is
+*                singular and its inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMM, ZGEMV, ZSWAP, ZTRSM, ZTRTRI
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NB = ILAENV( 1, 'ZGETRI', ' ', N, -1, -1, -1 )
+      LWKOPT = N*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -3
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGETRI', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form inv(U).  If INFO > 0 from ZTRTRI, then U is singular,
+*     and the inverse is not computed.
+*
+      CALL ZTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+      NBMIN = 2
+      LDWORK = N
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+         IWS = MAX( LDWORK*NB, 1 )
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'ZGETRI', ' ', N, -1, -1, -1 ) )
+         END IF
+      ELSE
+         IWS = N
+      END IF
+*
+*     Solve the equation inv(A)*L = inv(U) for inv(A).
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         DO 20 J = N, 1, -1
+*
+*           Copy current column of L to WORK and replace with zeros.
+*
+            DO 10 I = J + 1, N
+               WORK( I ) = A( I, J )
+               A( I, J ) = ZERO
+   10       CONTINUE
+*
+*           Compute current column of inv(A).
+*
+            IF( J.LT.N )
+     $         CALL ZGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),
+     $                     LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )
+   20    CONTINUE
+      ELSE
+*
+*        Use blocked code.
+*
+         NN = ( ( N-1 ) / NB )*NB + 1
+         DO 50 J = NN, 1, -NB
+            JB = MIN( NB, N-J+1 )
+*
+*           Copy current block column of L to WORK and replace with
+*           zeros.
+*
+            DO 40 JJ = J, J + JB - 1
+               DO 30 I = JJ + 1, N
+                  WORK( I+( JJ-J )*LDWORK ) = A( I, JJ )
+                  A( I, JJ ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+*
+*           Compute current block column of inv(A).
+*
+            IF( J+JB.LE.N )
+     $         CALL ZGEMM( 'No transpose', 'No transpose', N, JB,
+     $                     N-J-JB+1, -ONE, A( 1, J+JB ), LDA,
+     $                     WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )
+            CALL ZTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,
+     $                  ONE, WORK( J ), LDWORK, A( 1, J ), LDA )
+   50    CONTINUE
+      END IF
+*
+*     Apply column interchanges.
+*
+      DO 60 J = N - 1, 1, -1
+         JP = IPIV( J )
+         IF( JP.NE.J )
+     $      CALL ZSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
+   60 CONTINUE
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZGETRI
+*
+      END
diff --git a/libcruft/lapack/zgetrs.f b/libcruft/lapack/zgetrs.f
new file mode 100644
index 0000000..e32549c
--- /dev/null
+++ b/libcruft/lapack/zgetrs.f
@@ -0,0 +1,149 @@
+      SUBROUTINE ZGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGETRS solves a system of linear equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B
+*  with a general N-by-N matrix A using the LU factorization computed
+*  by ZGETRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The factors L and U from the factorization A = P*L*U
+*          as computed by ZGETRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices from ZGETRF; for 1<=i<=N, row i of the
+*          matrix was interchanged with row IPIV(i).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLASWP, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOTRAN = LSAME( TRANS, 'N' )
+      IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $    LSAME( TRANS, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGETRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( NOTRAN ) THEN
+*
+*        Solve A * X = B.
+*
+*        Apply row interchanges to the right hand sides.
+*
+         CALL ZLASWP( NRHS, B, LDB, 1, N, IPIV, 1 )
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS,
+     $               ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A**T * X = B  or A**H * X = B.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Upper', TRANS, 'Non-unit', N, NRHS, ONE,
+     $               A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Lower', TRANS, 'Unit', N, NRHS, ONE, A,
+     $               LDA, B, LDB )
+*
+*        Apply row interchanges to the solution vectors.
+*
+         CALL ZLASWP( NRHS, B, LDB, 1, N, IPIV, -1 )
+      END IF
+*
+      RETURN
+*
+*     End of ZGETRS
+*
+      END
diff --git a/libcruft/lapack/zggbak.f b/libcruft/lapack/zggbak.f
new file mode 100644
index 0000000..ad6dd03
--- /dev/null
+++ b/libcruft/lapack/zggbak.f
@@ -0,0 +1,220 @@
+      SUBROUTINE ZGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,
+     $                   LDV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB, SIDE
+      INTEGER            IHI, ILO, INFO, LDV, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   LSCALE( * ), RSCALE( * )
+      COMPLEX*16         V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGGBAK forms the right or left eigenvectors of a complex generalized
+*  eigenvalue problem A*x = lambda*B*x, by backward transformation on
+*  the computed eigenvectors of the balanced pair of matrices output by
+*  ZGGBAL.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the type of backward transformation required:
+*          = 'N':  do nothing, return immediately;
+*          = 'P':  do backward transformation for permutation only;
+*          = 'S':  do backward transformation for scaling only;
+*          = 'B':  do backward transformations for both permutation and
+*                  scaling.
+*          JOB must be the same as the argument JOB supplied to ZGGBAL.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  V contains right eigenvectors;
+*          = 'L':  V contains left eigenvectors.
+*
+*  N       (input) INTEGER
+*          The number of rows of the matrix V.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          The integers ILO and IHI determined by ZGGBAL.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  LSCALE  (input) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the left side of A and B, as returned by ZGGBAL.
+*
+*  RSCALE  (input) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and/or scaling factors applied
+*          to the right side of A and B, as returned by ZGGBAL.
+*
+*  M       (input) INTEGER
+*          The number of columns of the matrix V.  M >= 0.
+*
+*  V       (input/output) COMPLEX*16 array, dimension (LDV,M)
+*          On entry, the matrix of right or left eigenvectors to be
+*          transformed, as returned by ZTGEVC.
+*          On exit, V is overwritten by the transformed eigenvectors.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the matrix V. LDV >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. Ward, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFTV, RIGHTV
+      INTEGER            I, K
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDSCAL, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      RIGHTV = LSAME( SIDE, 'R' )
+      LEFTV = LSAME( SIDE, 'L' )
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( N.EQ.0 .AND. IHI.EQ.0 .AND. ILO.NE.1 ) THEN
+         INFO = -4
+      ELSE IF( N.GT.0 .AND. ( IHI.LT.ILO .OR. IHI.GT.MAX( 1, N ) ) )
+     $   THEN
+         INFO = -5
+      ELSE IF( N.EQ.0 .AND. ILO.EQ.1 .AND. IHI.NE.0 ) THEN
+         INFO = -5
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -8
+      ELSE IF( LDV.LT.MAX( 1, N ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGGBAK', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( M.EQ.0 )
+     $   RETURN
+      IF( LSAME( JOB, 'N' ) )
+     $   RETURN
+*
+      IF( ILO.EQ.IHI )
+     $   GO TO 30
+*
+*     Backward balance
+*
+      IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward transformation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            DO 10 I = ILO, IHI
+               CALL ZDSCAL( M, RSCALE( I ), V( I, 1 ), LDV )
+   10       CONTINUE
+         END IF
+*
+*        Backward transformation on left eigenvectors
+*
+         IF( LEFTV ) THEN
+            DO 20 I = ILO, IHI
+               CALL ZDSCAL( M, LSCALE( I ), V( I, 1 ), LDV )
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Backward permutation
+*
+   30 CONTINUE
+      IF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN
+*
+*        Backward permutation on right eigenvectors
+*
+         IF( RIGHTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 50
+            DO 40 I = ILO - 1, 1, -1
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 40
+               CALL ZSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   40       CONTINUE
+*
+   50       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 70
+            DO 60 I = IHI + 1, N
+               K = RSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 60
+               CALL ZSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   60       CONTINUE
+         END IF
+*
+*        Backward permutation on left eigenvectors
+*
+   70    CONTINUE
+         IF( LEFTV ) THEN
+            IF( ILO.EQ.1 )
+     $         GO TO 90
+            DO 80 I = ILO - 1, 1, -1
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 80
+               CALL ZSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+   80       CONTINUE
+*
+   90       CONTINUE
+            IF( IHI.EQ.N )
+     $         GO TO 110
+            DO 100 I = IHI + 1, N
+               K = LSCALE( I )
+               IF( K.EQ.I )
+     $            GO TO 100
+               CALL ZSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )
+  100       CONTINUE
+         END IF
+      END IF
+*
+  110 CONTINUE
+*
+      RETURN
+*
+*     End of ZGGBAK
+*
+      END
diff --git a/libcruft/lapack/zggbal.f b/libcruft/lapack/zggbal.f
new file mode 100644
index 0000000..b75ae45
--- /dev/null
+++ b/libcruft/lapack/zggbal.f
@@ -0,0 +1,482 @@
+      SUBROUTINE ZGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
+     $                   RSCALE, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOB
+      INTEGER            IHI, ILO, INFO, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   LSCALE( * ), RSCALE( * ), WORK( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGGBAL balances a pair of general complex matrices (A,B).  This
+*  involves, first, permuting A and B by similarity transformations to
+*  isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
+*  elements on the diagonal; and second, applying a diagonal similarity
+*  transformation to rows and columns ILO to IHI to make the rows
+*  and columns as close in norm as possible. Both steps are optional.
+*
+*  Balancing may reduce the 1-norm of the matrices, and improve the
+*  accuracy of the computed eigenvalues and/or eigenvectors in the
+*  generalized eigenvalue problem A*x = lambda*B*x.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies the operations to be performed on A and B:
+*          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
+*                  and RSCALE(I) = 1.0 for i=1,...,N;
+*          = 'P':  permute only;
+*          = 'S':  scale only;
+*          = 'B':  both permute and scale.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the input matrix A.
+*          On exit, A is overwritten by the balanced matrix.
+*          If JOB = 'N', A is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,N)
+*          On entry, the input matrix B.
+*          On exit, B is overwritten by the balanced matrix.
+*          If JOB = 'N', B is not referenced.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  ILO     (output) INTEGER
+*  IHI     (output) INTEGER
+*          ILO and IHI are set to integers such that on exit
+*          A(i,j) = 0 and B(i,j) = 0 if i > j and
+*          j = 1,...,ILO-1 or i = IHI+1,...,N.
+*          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
+*
+*  LSCALE  (output) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the left side of A and B.  If P(j) is the index of the
+*          row interchanged with row j, and D(j) is the scaling factor
+*          applied to row j, then
+*            LSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  RSCALE  (output) DOUBLE PRECISION array, dimension (N)
+*          Details of the permutations and scaling factors applied
+*          to the right side of A and B.  If P(j) is the index of the
+*          column interchanged with column j, and D(j) is the scaling
+*          factor applied to column j, then
+*            RSCALE(j) = P(j)    for J = 1,...,ILO-1
+*                      = D(j)    for J = ILO,...,IHI
+*                      = P(j)    for J = IHI+1,...,N.
+*          The order in which the interchanges are made is N to IHI+1,
+*          then 1 to ILO-1.
+*
+*  WORK    (workspace) REAL array, dimension (lwork)
+*          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
+*          at least 1 when JOB = 'N' or 'P'.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  See R.C. WARD, Balancing the generalized eigenvalue problem,
+*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   THREE, SCLFAC
+      PARAMETER          ( THREE = 3.0D+0, SCLFAC = 1.0D+1 )
+      COMPLEX*16         CZERO
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
+     $                   K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
+     $                   M, NR, NRP2
+      DOUBLE PRECISION   ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
+     $                   COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
+     $                   SFMIN, SUM, T, TA, TB, TC
+      COMPLEX*16         CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DDOT, DLAMCH
+      EXTERNAL           LSAME, IZAMAX, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DSCAL, XERBLA, ZDSCAL, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, INT, LOG10, MAX, MIN, SIGN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
+     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGGBAL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         ILO = 1
+         IHI = N
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         ILO = 1
+         IHI = N
+         LSCALE( 1 ) = ONE
+         RSCALE( 1 ) = ONE
+         RETURN
+      END IF
+*
+      IF( LSAME( JOB, 'N' ) ) THEN
+         ILO = 1
+         IHI = N
+         DO 10 I = 1, N
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      K = 1
+      L = N
+      IF( LSAME( JOB, 'S' ) )
+     $   GO TO 190
+*
+      GO TO 30
+*
+*     Permute the matrices A and B to isolate the eigenvalues.
+*
+*     Find row with one nonzero in columns 1 through L
+*
+   20 CONTINUE
+      L = LM1
+      IF( L.NE.1 )
+     $   GO TO 30
+*
+      RSCALE( 1 ) = 1
+      LSCALE( 1 ) = 1
+      GO TO 190
+*
+   30 CONTINUE
+      LM1 = L - 1
+      DO 80 I = L, 1, -1
+         DO 40 J = 1, LM1
+            JP1 = J + 1
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 50
+   40    CONTINUE
+         J = L
+         GO TO 70
+*
+   50    CONTINUE
+         DO 60 J = JP1, L
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 80
+   60    CONTINUE
+         J = JP1 - 1
+*
+   70    CONTINUE
+         M = L
+         IFLOW = 1
+         GO TO 160
+   80 CONTINUE
+      GO TO 100
+*
+*     Find column with one nonzero in rows K through N
+*
+   90 CONTINUE
+      K = K + 1
+*
+  100 CONTINUE
+      DO 150 J = K, L
+         DO 110 I = K, LM1
+            IP1 = I + 1
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 120
+  110    CONTINUE
+         I = L
+         GO TO 140
+  120    CONTINUE
+         DO 130 I = IP1, L
+            IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
+     $         GO TO 150
+  130    CONTINUE
+         I = IP1 - 1
+  140    CONTINUE
+         M = K
+         IFLOW = 2
+         GO TO 160
+  150 CONTINUE
+      GO TO 190
+*
+*     Permute rows M and I
+*
+  160 CONTINUE
+      LSCALE( M ) = I
+      IF( I.EQ.M )
+     $   GO TO 170
+      CALL ZSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
+      CALL ZSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
+*
+*     Permute columns M and J
+*
+  170 CONTINUE
+      RSCALE( M ) = J
+      IF( J.EQ.M )
+     $   GO TO 180
+      CALL ZSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
+      CALL ZSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
+*
+  180 CONTINUE
+      GO TO ( 20, 90 )IFLOW
+*
+  190 CONTINUE
+      ILO = K
+      IHI = L
+*
+      IF( LSAME( JOB, 'P' ) ) THEN
+         DO 195 I = ILO, IHI
+            LSCALE( I ) = ONE
+            RSCALE( I ) = ONE
+  195    CONTINUE
+         RETURN
+      END IF
+*
+      IF( ILO.EQ.IHI )
+     $   RETURN
+*
+*     Balance the submatrix in rows ILO to IHI.
+*
+      NR = IHI - ILO + 1
+      DO 200 I = ILO, IHI
+         RSCALE( I ) = ZERO
+         LSCALE( I ) = ZERO
+*
+         WORK( I ) = ZERO
+         WORK( I+N ) = ZERO
+         WORK( I+2*N ) = ZERO
+         WORK( I+3*N ) = ZERO
+         WORK( I+4*N ) = ZERO
+         WORK( I+5*N ) = ZERO
+  200 CONTINUE
+*
+*     Compute right side vector in resulting linear equations
+*
+      BASL = LOG10( SCLFAC )
+      DO 240 I = ILO, IHI
+         DO 230 J = ILO, IHI
+            IF( A( I, J ).EQ.CZERO ) THEN
+               TA = ZERO
+               GO TO 210
+            END IF
+            TA = LOG10( CABS1( A( I, J ) ) ) / BASL
+*
+  210       CONTINUE
+            IF( B( I, J ).EQ.CZERO ) THEN
+               TB = ZERO
+               GO TO 220
+            END IF
+            TB = LOG10( CABS1( B( I, J ) ) ) / BASL
+*
+  220       CONTINUE
+            WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
+            WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
+  230    CONTINUE
+  240 CONTINUE
+*
+      COEF = ONE / DBLE( 2*NR )
+      COEF2 = COEF*COEF
+      COEF5 = HALF*COEF2
+      NRP2 = NR + 2
+      BETA = ZERO
+      IT = 1
+*
+*     Start generalized conjugate gradient iteration
+*
+  250 CONTINUE
+*
+      GAMMA = DDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
+     $        DDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      EW = ZERO
+      EWC = ZERO
+      DO 260 I = ILO, IHI
+         EW = EW + WORK( I+4*N )
+         EWC = EWC + WORK( I+5*N )
+  260 CONTINUE
+*
+      GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
+      IF( GAMMA.EQ.ZERO )
+     $   GO TO 350
+      IF( IT.NE.1 )
+     $   BETA = GAMMA / PGAMMA
+      T = COEF5*( EWC-THREE*EW )
+      TC = COEF5*( EW-THREE*EWC )
+*
+      CALL DSCAL( NR, BETA, WORK( ILO ), 1 )
+      CALL DSCAL( NR, BETA, WORK( ILO+N ), 1 )
+*
+      CALL DAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
+      CALL DAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
+*
+      DO 270 I = ILO, IHI
+         WORK( I ) = WORK( I ) + TC
+         WORK( I+N ) = WORK( I+N ) + T
+  270 CONTINUE
+*
+*     Apply matrix to vector
+*
+      DO 300 I = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 290 J = ILO, IHI
+            IF( A( I, J ).EQ.CZERO )
+     $         GO TO 280
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  280       CONTINUE
+            IF( B( I, J ).EQ.CZERO )
+     $         GO TO 290
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( J )
+  290    CONTINUE
+         WORK( I+2*N ) = DBLE( KOUNT )*WORK( I+N ) + SUM
+  300 CONTINUE
+*
+      DO 330 J = ILO, IHI
+         KOUNT = 0
+         SUM = ZERO
+         DO 320 I = ILO, IHI
+            IF( A( I, J ).EQ.CZERO )
+     $         GO TO 310
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  310       CONTINUE
+            IF( B( I, J ).EQ.CZERO )
+     $         GO TO 320
+            KOUNT = KOUNT + 1
+            SUM = SUM + WORK( I+N )
+  320    CONTINUE
+         WORK( J+3*N ) = DBLE( KOUNT )*WORK( J ) + SUM
+  330 CONTINUE
+*
+      SUM = DDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
+     $      DDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
+      ALPHA = GAMMA / SUM
+*
+*     Determine correction to current iteration
+*
+      CMAX = ZERO
+      DO 340 I = ILO, IHI
+         COR = ALPHA*WORK( I+N )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         LSCALE( I ) = LSCALE( I ) + COR
+         COR = ALPHA*WORK( I )
+         IF( ABS( COR ).GT.CMAX )
+     $      CMAX = ABS( COR )
+         RSCALE( I ) = RSCALE( I ) + COR
+  340 CONTINUE
+      IF( CMAX.LT.HALF )
+     $   GO TO 350
+*
+      CALL DAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
+      CALL DAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
+*
+      PGAMMA = GAMMA
+      IT = IT + 1
+      IF( IT.LE.NRP2 )
+     $   GO TO 250
+*
+*     End generalized conjugate gradient iteration
+*
+  350 CONTINUE
+      SFMIN = DLAMCH( 'S' )
+      SFMAX = ONE / SFMIN
+      LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
+      LSFMAX = INT( LOG10( SFMAX ) / BASL )
+      DO 360 I = ILO, IHI
+         IRAB = IZAMAX( N-ILO+1, A( I, ILO ), LDA )
+         RAB = ABS( A( I, IRAB+ILO-1 ) )
+         IRAB = IZAMAX( N-ILO+1, B( I, ILO ), LDB )
+         RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
+         LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
+         IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
+         IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
+         LSCALE( I ) = SCLFAC**IR
+         ICAB = IZAMAX( IHI, A( 1, I ), 1 )
+         CAB = ABS( A( ICAB, I ) )
+         ICAB = IZAMAX( IHI, B( 1, I ), 1 )
+         CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
+         LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
+         JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
+         JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
+         RSCALE( I ) = SCLFAC**JC
+  360 CONTINUE
+*
+*     Row scaling of matrices A and B
+*
+      DO 370 I = ILO, IHI
+         CALL ZDSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
+         CALL ZDSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
+  370 CONTINUE
+*
+*     Column scaling of matrices A and B
+*
+      DO 380 J = ILO, IHI
+         CALL ZDSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
+         CALL ZDSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
+  380 CONTINUE
+*
+      RETURN
+*
+*     End of ZGGBAL
+*
+      END
diff --git a/libcruft/lapack/zggev.f b/libcruft/lapack/zggev.f
new file mode 100644
index 0000000..94fb3dc
--- /dev/null
+++ b/libcruft/lapack/zggev.f
@@ -0,0 +1,454 @@
+      SUBROUTINE ZGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
+     $                  VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBVL, JOBVR
+      INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
+     $                   BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGGEV computes for a pair of N-by-N complex nonsymmetric matrices
+*  (A,B), the generalized eigenvalues, and optionally, the left and/or
+*  right generalized eigenvectors.
+*
+*  A generalized eigenvalue for a pair of matrices (A,B) is a scalar
+*  lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
+*  singular. It is usually represented as the pair (alpha,beta), as
+*  there is a reasonable interpretation for beta=0, and even for both
+*  being zero.
+*
+*  The right generalized eigenvector v(j) corresponding to the
+*  generalized eigenvalue lambda(j) of (A,B) satisfies
+*
+*               A * v(j) = lambda(j) * B * v(j).
+*
+*  The left generalized eigenvector u(j) corresponding to the
+*  generalized eigenvalues lambda(j) of (A,B) satisfies
+*
+*               u(j)**H * A = lambda(j) * u(j)**H * B
+*
+*  where u(j)**H is the conjugate-transpose of u(j).
+*
+*  Arguments
+*  =========
+*
+*  JOBVL   (input) CHARACTER*1
+*          = 'N':  do not compute the left generalized eigenvectors;
+*          = 'V':  compute the left generalized eigenvectors.
+*
+*  JOBVR   (input) CHARACTER*1
+*          = 'N':  do not compute the right generalized eigenvectors;
+*          = 'V':  compute the right generalized eigenvectors.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A, B, VL, and VR.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA, N)
+*          On entry, the matrix A in the pair (A,B).
+*          On exit, A has been overwritten.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB, N)
+*          On entry, the matrix B in the pair (A,B).
+*          On exit, B has been overwritten.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of B.  LDB >= max(1,N).
+*
+*  ALPHA   (output) COMPLEX*16 array, dimension (N)
+*  BETA    (output) COMPLEX*16 array, dimension (N)
+*          On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the
+*          generalized eigenvalues.
+*
+*          Note: the quotients ALPHA(j)/BETA(j) may easily over- or
+*          underflow, and BETA(j) may even be zero.  Thus, the user
+*          should avoid naively computing the ratio alpha/beta.
+*          However, ALPHA will be always less than and usually
+*          comparable with norm(A) in magnitude, and BETA always less
+*          than and usually comparable with norm(B).
+*
+*  VL      (output) COMPLEX*16 array, dimension (LDVL,N)
+*          If JOBVL = 'V', the left generalized eigenvectors u(j) are
+*          stored one after another in the columns of VL, in the same
+*          order as their eigenvalues.
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part) + abs(imag. part) = 1.
+*          Not referenced if JOBVL = 'N'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the matrix VL. LDVL >= 1, and
+*          if JOBVL = 'V', LDVL >= N.
+*
+*  VR      (output) COMPLEX*16 array, dimension (LDVR,N)
+*          If JOBVR = 'V', the right generalized eigenvectors v(j) are
+*          stored one after another in the columns of VR, in the same
+*          order as their eigenvalues.
+*          Each eigenvector is scaled so the largest component has
+*          abs(real part) + abs(imag. part) = 1.
+*          Not referenced if JOBVR = 'N'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the matrix VR. LDVR >= 1, and
+*          if JOBVR = 'V', LDVR >= N.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,2*N).
+*          For good performance, LWORK must generally be larger.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace/output) DOUBLE PRECISION array, dimension (8*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*          =1,...,N:
+*                The QZ iteration failed.  No eigenvectors have been
+*                calculated, but ALPHA(j) and BETA(j) should be
+*                correct for j=INFO+1,...,N.
+*          > N:  =N+1: other then QZ iteration failed in DHGEQZ,
+*                =N+2: error return from DTGEVC.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
+     $                   CONE = ( 1.0D0, 0.0D0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
+      CHARACTER          CHTEMP
+      INTEGER            ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
+     $                   IN, IRIGHT, IROWS, IRWRK, ITAU, IWRK, JC, JR,
+     $                   LWKMIN, LWKOPT
+      DOUBLE PRECISION   ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
+     $                   SMLNUM, TEMP
+      COMPLEX*16         X
+*     ..
+*     .. Local Arrays ..
+      LOGICAL            LDUMMA( 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD,
+     $                   ZHGEQZ, ZLACPY, ZLASCL, ZLASET, ZTGEVC, ZUNGQR,
+     $                   ZUNMQR
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MAX, SQRT
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   ABS1
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode the input arguments
+*
+      IF( LSAME( JOBVL, 'N' ) ) THEN
+         IJOBVL = 1
+         ILVL = .FALSE.
+      ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
+         IJOBVL = 2
+         ILVL = .TRUE.
+      ELSE
+         IJOBVL = -1
+         ILVL = .FALSE.
+      END IF
+*
+      IF( LSAME( JOBVR, 'N' ) ) THEN
+         IJOBVR = 1
+         ILVR = .FALSE.
+      ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
+         IJOBVR = 2
+         ILVR = .TRUE.
+      ELSE
+         IJOBVR = -1
+         ILVR = .FALSE.
+      END IF
+      ILV = ILVL .OR. ILVR
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( IJOBVL.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( IJOBVR.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
+         INFO = -11
+      ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
+         INFO = -13
+      END IF
+*
+*     Compute workspace
+*      (Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace needed at that point in the code,
+*       as well as the preferred amount for good performance.
+*       NB refers to the optimal block size for the immediately
+*       following subroutine, as returned by ILAENV. The workspace is
+*       computed assuming ILO = 1 and IHI = N, the worst case.)
+*
+      IF( INFO.EQ.0 ) THEN
+         LWKMIN = MAX( 1, 2*N )
+         LWKOPT = MAX( 1, N + N*ILAENV( 1, 'ZGEQRF', ' ', N, 1, N, 0 ) )
+         LWKOPT = MAX( LWKOPT, N +
+     $                 N*ILAENV( 1, 'ZUNMQR', ' ', N, 1, N, 0 ) )
+         IF( ILVL ) THEN
+            LWKOPT = MAX( LWKOPT, N +
+     $                    N*ILAENV( 1, 'ZUNGQR', ' ', N, 1, N, -1 ) )
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY )
+     $      INFO = -15
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGGEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Get machine constants
+*
+      EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SQRT( SMLNUM ) / EPS
+      BIGNUM = ONE / SMLNUM
+*
+*     Scale A if max element outside range [SMLNUM,BIGNUM]
+*
+      ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
+      ILASCL = .FALSE.
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
+         ANRMTO = SMLNUM
+         ILASCL = .TRUE.
+      ELSE IF( ANRM.GT.BIGNUM ) THEN
+         ANRMTO = BIGNUM
+         ILASCL = .TRUE.
+      END IF
+      IF( ILASCL )
+     $   CALL ZLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
+*
+*     Scale B if max element outside range [SMLNUM,BIGNUM]
+*
+      BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
+      ILBSCL = .FALSE.
+      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
+         BNRMTO = SMLNUM
+         ILBSCL = .TRUE.
+      ELSE IF( BNRM.GT.BIGNUM ) THEN
+         BNRMTO = BIGNUM
+         ILBSCL = .TRUE.
+      END IF
+      IF( ILBSCL )
+     $   CALL ZLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
+*
+*     Permute the matrices A, B to isolate eigenvalues if possible
+*     (Real Workspace: need 6*N)
+*
+      ILEFT = 1
+      IRIGHT = N + 1
+      IRWRK = IRIGHT + N
+      CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
+     $             RWORK( IRIGHT ), RWORK( IRWRK ), IERR )
+*
+*     Reduce B to triangular form (QR decomposition of B)
+*     (Complex Workspace: need N, prefer N*NB)
+*
+      IROWS = IHI + 1 - ILO
+      IF( ILV ) THEN
+         ICOLS = N + 1 - ILO
+      ELSE
+         ICOLS = IROWS
+      END IF
+      ITAU = 1
+      IWRK = ITAU + IROWS
+      CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
+     $             WORK( IWRK ), LWORK+1-IWRK, IERR )
+*
+*     Apply the orthogonal transformation to matrix A
+*     (Complex Workspace: need N, prefer N*NB)
+*
+      CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
+     $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
+     $             LWORK+1-IWRK, IERR )
+*
+*     Initialize VL
+*     (Complex Workspace: need N, prefer N*NB)
+*
+      IF( ILVL ) THEN
+         CALL ZLASET( 'Full', N, N, CZERO, CONE, VL, LDVL )
+         IF( IROWS.GT.1 ) THEN
+            CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
+     $                   VL( ILO+1, ILO ), LDVL )
+         END IF
+         CALL ZUNGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
+     $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
+      END IF
+*
+*     Initialize VR
+*
+      IF( ILVR )
+     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, VR, LDVR )
+*
+*     Reduce to generalized Hessenberg form
+*
+      IF( ILV ) THEN
+*
+*        Eigenvectors requested -- work on whole matrix.
+*
+         CALL ZGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
+     $                LDVL, VR, LDVR, IERR )
+      ELSE
+         CALL ZGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
+     $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
+      END IF
+*
+*     Perform QZ algorithm (Compute eigenvalues, and optionally, the
+*     Schur form and Schur vectors)
+*     (Complex Workspace: need N)
+*     (Real Workspace: need N)
+*
+      IWRK = ITAU
+      IF( ILV ) THEN
+         CHTEMP = 'S'
+      ELSE
+         CHTEMP = 'E'
+      END IF
+      CALL ZHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
+     $             ALPHA, BETA, VL, LDVL, VR, LDVR, WORK( IWRK ),
+     $             LWORK+1-IWRK, RWORK( IRWRK ), IERR )
+      IF( IERR.NE.0 ) THEN
+         IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
+            INFO = IERR
+         ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
+            INFO = IERR - N
+         ELSE
+            INFO = N + 1
+         END IF
+         GO TO 70
+      END IF
+*
+*     Compute Eigenvectors
+*     (Real Workspace: need 2*N)
+*     (Complex Workspace: need 2*N)
+*
+      IF( ILV ) THEN
+         IF( ILVL ) THEN
+            IF( ILVR ) THEN
+               CHTEMP = 'B'
+            ELSE
+               CHTEMP = 'L'
+            END IF
+         ELSE
+            CHTEMP = 'R'
+         END IF
+*
+         CALL ZTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
+     $                VR, LDVR, N, IN, WORK( IWRK ), RWORK( IRWRK ),
+     $                IERR )
+         IF( IERR.NE.0 ) THEN
+            INFO = N + 2
+            GO TO 70
+         END IF
+*
+*        Undo balancing on VL and VR and normalization
+*        (Workspace: none needed)
+*
+         IF( ILVL ) THEN
+            CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
+     $                   RWORK( IRIGHT ), N, VL, LDVL, IERR )
+            DO 30 JC = 1, N
+               TEMP = ZERO
+               DO 10 JR = 1, N
+                  TEMP = MAX( TEMP, ABS1( VL( JR, JC ) ) )
+   10          CONTINUE
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 30
+               TEMP = ONE / TEMP
+               DO 20 JR = 1, N
+                  VL( JR, JC ) = VL( JR, JC )*TEMP
+   20          CONTINUE
+   30       CONTINUE
+         END IF
+         IF( ILVR ) THEN
+            CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
+     $                   RWORK( IRIGHT ), N, VR, LDVR, IERR )
+            DO 60 JC = 1, N
+               TEMP = ZERO
+               DO 40 JR = 1, N
+                  TEMP = MAX( TEMP, ABS1( VR( JR, JC ) ) )
+   40          CONTINUE
+               IF( TEMP.LT.SMLNUM )
+     $            GO TO 60
+               TEMP = ONE / TEMP
+               DO 50 JR = 1, N
+                  VR( JR, JC ) = VR( JR, JC )*TEMP
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      END IF
+*
+*     Undo scaling if necessary
+*
+      IF( ILASCL )
+     $   CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
+*
+      IF( ILBSCL )
+     $   CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
+*
+   70 CONTINUE
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of ZGGEV
+*
+      END
diff --git a/libcruft/lapack/zgghrd.f b/libcruft/lapack/zgghrd.f
new file mode 100644
index 0000000..652c09d
--- /dev/null
+++ b/libcruft/lapack/zgghrd.f
@@ -0,0 +1,264 @@
+      SUBROUTINE ZGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
+     $                   LDQ, Z, LDZ, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ
+      INTEGER            IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGGHRD reduces a pair of complex matrices (A,B) to generalized upper
+*  Hessenberg form using unitary transformations, where A is a
+*  general matrix and B is upper triangular.  The form of the
+*  generalized eigenvalue problem is
+*     A*x = lambda*B*x,
+*  and B is typically made upper triangular by computing its QR
+*  factorization and moving the unitary matrix Q to the left side
+*  of the equation.
+*
+*  This subroutine simultaneously reduces A to a Hessenberg matrix H:
+*     Q**H*A*Z = H
+*  and transforms B to another upper triangular matrix T:
+*     Q**H*B*Z = T
+*  in order to reduce the problem to its standard form
+*     H*y = lambda*T*y
+*  where y = Z**H*x.
+*
+*  The unitary matrices Q and Z are determined as products of Givens
+*  rotations.  They may either be formed explicitly, or they may be
+*  postmultiplied into input matrices Q1 and Z1, so that
+*       Q1 * A * Z1**H = (Q1*Q) * H * (Z1*Z)**H
+*       Q1 * B * Z1**H = (Q1*Q) * T * (Z1*Z)**H
+*  If Q1 is the unitary matrix from the QR factorization of B in the
+*  original equation A*x = lambda*B*x, then ZGGHRD reduces the original
+*  problem to generalized Hessenberg form.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': do not compute Q;
+*          = 'I': Q is initialized to the unit matrix, and the
+*                 unitary matrix Q is returned;
+*          = 'V': Q must contain a unitary matrix Q1 on entry,
+*                 and the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': do not compute Q;
+*          = 'I': Q is initialized to the unit matrix, and the
+*                 unitary matrix Q is returned;
+*          = 'V': Q must contain a unitary matrix Q1 on entry,
+*                 and the product Q1*Q is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of A which are to be
+*          reduced.  It is assumed that A is already upper triangular
+*          in rows and columns 1:ILO-1 and IHI+1:N.  ILO and IHI are
+*          normally set by a previous call to ZGGBAL; otherwise they
+*          should be set to 1 and N respectively.
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA, N)
+*          On entry, the N-by-N general matrix to be reduced.
+*          On exit, the upper triangle and the first subdiagonal of A
+*          are overwritten with the upper Hessenberg matrix H, and the
+*          rest is set to zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB, N)
+*          On entry, the N-by-N upper triangular matrix B.
+*          On exit, the upper triangular matrix T = Q**H B Z.  The
+*          elements below the diagonal are set to zero.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  Q       (input/output) COMPLEX*16 array, dimension (LDQ, N)
+*          On entry, if COMPQ = 'V', the unitary matrix Q1, typically
+*          from the QR factorization of B.
+*          On exit, if COMPQ='I', the unitary matrix Q, and if
+*          COMPQ = 'V', the product Q1*Q.
+*          Not referenced if COMPQ='N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
+*
+*  Z       (input/output) COMPLEX*16 array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the unitary matrix Z1.
+*          On exit, if COMPZ='I', the unitary matrix Z, and if
+*          COMPZ = 'V', the product Z1*Z.
+*          Not referenced if COMPZ='N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.
+*          LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  This routine reduces A to Hessenberg and B to triangular form by
+*  an unblocked reduction, as described in _Matrix_Computations_,
+*  by Golub and van Loan (Johns Hopkins Press).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         CONE, CZERO
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ),
+     $                   CZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILQ, ILZ
+      INTEGER            ICOMPQ, ICOMPZ, JCOL, JROW
+      DOUBLE PRECISION   C
+      COMPLEX*16         CTEMP, S
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARTG, ZLASET, ZROT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode COMPQ
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+*     Decode COMPZ
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ICOMPQ.LE.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPZ.LE.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THEN
+         INFO = -11
+      ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGGHRD', -INFO )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z if desired.
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+*     Zero out lower triangle of B
+*
+      DO 20 JCOL = 1, N - 1
+         DO 10 JROW = JCOL + 1, N
+            B( JROW, JCOL ) = CZERO
+   10    CONTINUE
+   20 CONTINUE
+*
+*     Reduce A and B
+*
+      DO 40 JCOL = ILO, IHI - 2
+*
+         DO 30 JROW = IHI, JCOL + 2, -1
+*
+*           Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)
+*
+            CTEMP = A( JROW-1, JCOL )
+            CALL ZLARTG( CTEMP, A( JROW, JCOL ), C, S,
+     $                   A( JROW-1, JCOL ) )
+            A( JROW, JCOL ) = CZERO
+            CALL ZROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,
+     $                 A( JROW, JCOL+1 ), LDA, C, S )
+            CALL ZROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,
+     $                 B( JROW, JROW-1 ), LDB, C, S )
+            IF( ILQ )
+     $         CALL ZROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C,
+     $                    DCONJG( S ) )
+*
+*           Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)
+*
+            CTEMP = B( JROW, JROW )
+            CALL ZLARTG( CTEMP, B( JROW, JROW-1 ), C, S,
+     $                   B( JROW, JROW ) )
+            B( JROW, JROW-1 ) = CZERO
+            CALL ZROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )
+            CALL ZROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,
+     $                 S )
+            IF( ILZ )
+     $         CALL ZROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )
+   30    CONTINUE
+   40 CONTINUE
+*
+      RETURN
+*
+*     End of ZGGHRD
+*
+      END
diff --git a/libcruft/lapack/zgtsv.f b/libcruft/lapack/zgtsv.f
new file mode 100644
index 0000000..ea466b3
--- /dev/null
+++ b/libcruft/lapack/zgtsv.f
@@ -0,0 +1,173 @@
+      SUBROUTINE ZGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         B( LDB, * ), D( * ), DL( * ), DU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGTSV  solves the equation
+*
+*     A*X = B,
+*
+*  where A is an N-by-N tridiagonal matrix, by Gaussian elimination with
+*  partial pivoting.
+*
+*  Note that the equation  A'*X = B  may be solved by interchanging the
+*  order of the arguments DU and DL.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input/output) COMPLEX*16 array, dimension (N-1)
+*          On entry, DL must contain the (n-1) subdiagonal elements of
+*          A.
+*          On exit, DL is overwritten by the (n-2) elements of the
+*          second superdiagonal of the upper triangular matrix U from
+*          the LU factorization of A, in DL(1), ..., DL(n-2).
+*
+*  D       (input/output) COMPLEX*16 array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*          On exit, D is overwritten by the n diagonal elements of U.
+*
+*  DU      (input/output) COMPLEX*16 array, dimension (N-1)
+*          On entry, DU must contain the (n-1) superdiagonal elements
+*          of A.
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          superdiagonal of U.
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the N-by-NRHS right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, U(i,i) is exactly zero, and the solution
+*                has not been computed.  The factorization has not been
+*                completed unless i = N.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J, K
+      COMPLEX*16         MULT, TEMP, ZDUM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MAX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGTSV ', -INFO )
+         RETURN
+      END IF
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      DO 30 K = 1, N - 1
+         IF( DL( K ).EQ.ZERO ) THEN
+*
+*           Subdiagonal is zero, no elimination is required.
+*
+            IF( D( K ).EQ.ZERO ) THEN
+*
+*              Diagonal is zero: set INFO = K and return; a unique
+*              solution can not be found.
+*
+               INFO = K
+               RETURN
+            END IF
+         ELSE IF( CABS1( D( K ) ).GE.CABS1( DL( K ) ) ) THEN
+*
+*           No row interchange required
+*
+            MULT = DL( K ) / D( K )
+            D( K+1 ) = D( K+1 ) - MULT*DU( K )
+            DO 10 J = 1, NRHS
+               B( K+1, J ) = B( K+1, J ) - MULT*B( K, J )
+   10       CONTINUE
+            IF( K.LT.( N-1 ) )
+     $         DL( K ) = ZERO
+         ELSE
+*
+*           Interchange rows K and K+1
+*
+            MULT = D( K ) / DL( K )
+            D( K ) = DL( K )
+            TEMP = D( K+1 )
+            D( K+1 ) = DU( K ) - MULT*TEMP
+            IF( K.LT.( N-1 ) ) THEN
+               DL( K ) = DU( K+1 )
+               DU( K+1 ) = -MULT*DL( K )
+            END IF
+            DU( K ) = TEMP
+            DO 20 J = 1, NRHS
+               TEMP = B( K, J )
+               B( K, J ) = B( K+1, J )
+               B( K+1, J ) = TEMP - MULT*B( K+1, J )
+   20       CONTINUE
+         END IF
+   30 CONTINUE
+      IF( D( N ).EQ.ZERO ) THEN
+         INFO = N
+         RETURN
+      END IF
+*
+*     Back solve with the matrix U from the factorization.
+*
+      DO 50 J = 1, NRHS
+         B( N, J ) = B( N, J ) / D( N )
+         IF( N.GT.1 )
+     $      B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) / D( N-1 )
+         DO 40 K = N - 2, 1, -1
+            B( K, J ) = ( B( K, J )-DU( K )*B( K+1, J )-DL( K )*
+     $                  B( K+2, J ) ) / D( K )
+   40    CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of ZGTSV
+*
+      END
diff --git a/libcruft/lapack/zgttrf.f b/libcruft/lapack/zgttrf.f
new file mode 100644
index 0000000..2d2c1aa
--- /dev/null
+++ b/libcruft/lapack/zgttrf.f
@@ -0,0 +1,174 @@
+      SUBROUTINE ZGTTRF( N, DL, D, DU, DU2, IPIV, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGTTRF computes an LU factorization of a complex tridiagonal matrix A
+*  using elimination with partial pivoting and row interchanges.
+*
+*  The factorization has the form
+*     A = L * U
+*  where L is a product of permutation and unit lower bidiagonal
+*  matrices and U is upper triangular with nonzeros in only the main
+*  diagonal and first two superdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  DL      (input/output) COMPLEX*16 array, dimension (N-1)
+*          On entry, DL must contain the (n-1) sub-diagonal elements of
+*          A.
+*
+*          On exit, DL is overwritten by the (n-1) multipliers that
+*          define the matrix L from the LU factorization of A.
+*
+*  D       (input/output) COMPLEX*16 array, dimension (N)
+*          On entry, D must contain the diagonal elements of A.
+*
+*          On exit, D is overwritten by the n diagonal elements of the
+*          upper triangular matrix U from the LU factorization of A.
+*
+*  DU      (input/output) COMPLEX*16 array, dimension (N-1)
+*          On entry, DU must contain the (n-1) super-diagonal elements
+*          of A.
+*
+*          On exit, DU is overwritten by the (n-1) elements of the first
+*          super-diagonal of U.
+*
+*  DU2     (output) COMPLEX*16 array, dimension (N-2)
+*          On exit, DU2 is overwritten by the (n-2) elements of the
+*          second super-diagonal of U.
+*
+*  IPIV    (output) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*          > 0:  if INFO = k, U(k,k) is exactly zero. The factorization
+*                has been completed, but the factor U is exactly
+*                singular, and division by zero will occur if it is used
+*                to solve a system of equations.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16         FACT, TEMP, ZDUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'ZGTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Initialize IPIV(i) = i and DU2(i) = 0
+*
+      DO 10 I = 1, N
+         IPIV( I ) = I
+   10 CONTINUE
+      DO 20 I = 1, N - 2
+         DU2( I ) = ZERO
+   20 CONTINUE
+*
+      DO 30 I = 1, N - 2
+         IF( CABS1( D( I ) ).GE.CABS1( DL( I ) ) ) THEN
+*
+*           No row interchange required, eliminate DL(I)
+*
+            IF( CABS1( D( I ) ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+*
+*           Interchange rows I and I+1, eliminate DL(I)
+*
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            DU2( I ) = DU( I+1 )
+            DU( I+1 ) = -FACT*DU( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+   30 CONTINUE
+      IF( N.GT.1 ) THEN
+         I = N - 1
+         IF( CABS1( D( I ) ).GE.CABS1( DL( I ) ) ) THEN
+            IF( CABS1( D( I ) ).NE.ZERO ) THEN
+               FACT = DL( I ) / D( I )
+               DL( I ) = FACT
+               D( I+1 ) = D( I+1 ) - FACT*DU( I )
+            END IF
+         ELSE
+            FACT = D( I ) / DL( I )
+            D( I ) = DL( I )
+            DL( I ) = FACT
+            TEMP = DU( I )
+            DU( I ) = D( I+1 )
+            D( I+1 ) = TEMP - FACT*D( I+1 )
+            IPIV( I ) = I + 1
+         END IF
+      END IF
+*
+*     Check for a zero on the diagonal of U.
+*
+      DO 40 I = 1, N
+         IF( CABS1( D( I ) ).EQ.ZERO ) THEN
+            INFO = I
+            GO TO 50
+         END IF
+   40 CONTINUE
+   50 CONTINUE
+*
+      RETURN
+*
+*     End of ZGTTRF
+*
+      END
diff --git a/libcruft/lapack/zgttrs.f b/libcruft/lapack/zgttrs.f
new file mode 100644
index 0000000..60e71f5
--- /dev/null
+++ b/libcruft/lapack/zgttrs.f
@@ -0,0 +1,142 @@
+      SUBROUTINE ZGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANS
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGTTRS solves one of the systems of equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by ZGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations.
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) COMPLEX*16 array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) COMPLEX*16 array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) COMPLEX*16 array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) COMPLEX*16 array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN
+      INTEGER            ITRANS, J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGTTS2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      NOTRAN = ( TRANS.EQ.'N' .OR. TRANS.EQ.'n' )
+      IF( .NOT.NOTRAN .AND. .NOT.( TRANS.EQ.'T' .OR. TRANS.EQ.
+     $    't' ) .AND. .NOT.( TRANS.EQ.'C' .OR. TRANS.EQ.'c' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDB.LT.MAX( N, 1 ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZGTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Decode TRANS
+*
+      IF( NOTRAN ) THEN
+         ITRANS = 0
+      ELSE IF( TRANS.EQ.'T' .OR. TRANS.EQ.'t' ) THEN
+         ITRANS = 1
+      ELSE
+         ITRANS = 2
+      END IF
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'ZGTTRS', TRANS, N, NRHS, -1, -1 ) )
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL ZGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL ZGTTS2( ITRANS, N, JB, DL, D, DU, DU2, IPIV, B( 1, J ),
+     $                   LDB )
+   10    CONTINUE
+      END IF
+*
+*     End of ZGTTRS
+*
+      END
diff --git a/libcruft/lapack/zgtts2.f b/libcruft/lapack/zgtts2.f
new file mode 100644
index 0000000..da6073d
--- /dev/null
+++ b/libcruft/lapack/zgtts2.f
@@ -0,0 +1,271 @@
+      SUBROUTINE ZGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ITRANS, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZGTTS2 solves one of the systems of equations
+*     A * X = B,  A**T * X = B,  or  A**H * X = B,
+*  with a tridiagonal matrix A using the LU factorization computed
+*  by ZGTTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITRANS  (input) INTEGER
+*          Specifies the form of the system of equations.
+*          = 0:  A * X = B     (No transpose)
+*          = 1:  A**T * X = B  (Transpose)
+*          = 2:  A**H * X = B  (Conjugate transpose)
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  DL      (input) COMPLEX*16 array, dimension (N-1)
+*          The (n-1) multipliers that define the matrix L from the
+*          LU factorization of A.
+*
+*  D       (input) COMPLEX*16 array, dimension (N)
+*          The n diagonal elements of the upper triangular matrix U from
+*          the LU factorization of A.
+*
+*  DU      (input) COMPLEX*16 array, dimension (N-1)
+*          The (n-1) elements of the first super-diagonal of U.
+*
+*  DU2     (input) COMPLEX*16 array, dimension (N-2)
+*          The (n-2) elements of the second super-diagonal of U.
+*
+*  IPIV    (input) INTEGER array, dimension (N)
+*          The pivot indices; for 1 <= i <= n, row i of the matrix was
+*          interchanged with row IPIV(i).  IPIV(i) will always be either
+*          i or i+1; IPIV(i) = i indicates a row interchange was not
+*          required.
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the matrix of right hand side vectors B.
+*          On exit, B is overwritten by the solution vectors X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+      COMPLEX*16         TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( ITRANS.EQ.0 ) THEN
+*
+*        Solve A*X = B using the LU factorization of A,
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+   10       CONTINUE
+*
+*           Solve L*x = b.
+*
+            DO 20 I = 1, N - 1
+               IF( IPIV( I ).EQ.I ) THEN
+                  B( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )
+               ELSE
+                  TEMP = B( I, J )
+                  B( I, J ) = B( I+1, J )
+                  B( I+1, J ) = TEMP - DL( I )*B( I, J )
+               END IF
+   20       CONTINUE
+*
+*           Solve U*x = b.
+*
+            B( N, J ) = B( N, J ) / D( N )
+            IF( N.GT.1 )
+     $         B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                       D( N-1 )
+            DO 30 I = N - 2, 1, -1
+               B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                     B( I+2, J ) ) / D( I )
+   30       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 10
+            END IF
+         ELSE
+            DO 60 J = 1, NRHS
+*
+*           Solve L*x = b.
+*
+               DO 40 I = 1, N - 1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )
+                  ELSE
+                     TEMP = B( I, J )
+                     B( I, J ) = B( I+1, J )
+                     B( I+1, J ) = TEMP - DL( I )*B( I, J )
+                  END IF
+   40          CONTINUE
+*
+*           Solve U*x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               IF( N.GT.1 )
+     $            B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /
+     $                          D( N-1 )
+               DO 50 I = N - 2, 1, -1
+                  B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*
+     $                        B( I+2, J ) ) / D( I )
+   50          CONTINUE
+   60       CONTINUE
+         END IF
+      ELSE IF( ITRANS.EQ.1 ) THEN
+*
+*        Solve A**T * X = B.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+   70       CONTINUE
+*
+*           Solve U**T * x = b.
+*
+            B( 1, J ) = B( 1, J ) / D( 1 )
+            IF( N.GT.1 )
+     $         B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+            DO 80 I = 3, N
+               B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-DU2( I-2 )*
+     $                     B( I-2, J ) ) / D( I )
+   80       CONTINUE
+*
+*           Solve L**T * x = b.
+*
+            DO 90 I = N - 1, 1, -1
+               IF( IPIV( I ).EQ.I ) THEN
+                  B( I, J ) = B( I, J ) - DL( I )*B( I+1, J )
+               ELSE
+                  TEMP = B( I+1, J )
+                  B( I+1, J ) = B( I, J ) - DL( I )*TEMP
+                  B( I, J ) = TEMP
+               END IF
+   90       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 70
+            END IF
+         ELSE
+            DO 120 J = 1, NRHS
+*
+*           Solve U**T * x = b.
+*
+               B( 1, J ) = B( 1, J ) / D( 1 )
+               IF( N.GT.1 )
+     $            B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )
+               DO 100 I = 3, N
+                  B( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-
+     $                        DU2( I-2 )*B( I-2, J ) ) / D( I )
+  100          CONTINUE
+*
+*           Solve L**T * x = b.
+*
+               DO 110 I = N - 1, 1, -1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I, J ) = B( I, J ) - DL( I )*B( I+1, J )
+                  ELSE
+                     TEMP = B( I+1, J )
+                     B( I+1, J ) = B( I, J ) - DL( I )*TEMP
+                     B( I, J ) = TEMP
+                  END IF
+  110          CONTINUE
+  120       CONTINUE
+         END IF
+      ELSE
+*
+*        Solve A**H * X = B.
+*
+         IF( NRHS.LE.1 ) THEN
+            J = 1
+  130       CONTINUE
+*
+*           Solve U**H * x = b.
+*
+            B( 1, J ) = B( 1, J ) / DCONJG( D( 1 ) )
+            IF( N.GT.1 )
+     $         B( 2, J ) = ( B( 2, J )-DCONJG( DU( 1 ) )*B( 1, J ) ) /
+     $                     DCONJG( D( 2 ) )
+            DO 140 I = 3, N
+               B( I, J ) = ( B( I, J )-DCONJG( DU( I-1 ) )*B( I-1, J )-
+     $                     DCONJG( DU2( I-2 ) )*B( I-2, J ) ) /
+     $                     DCONJG( D( I ) )
+  140       CONTINUE
+*
+*           Solve L**H * x = b.
+*
+            DO 150 I = N - 1, 1, -1
+               IF( IPIV( I ).EQ.I ) THEN
+                  B( I, J ) = B( I, J ) - DCONJG( DL( I ) )*B( I+1, J )
+               ELSE
+                  TEMP = B( I+1, J )
+                  B( I+1, J ) = B( I, J ) - DCONJG( DL( I ) )*TEMP
+                  B( I, J ) = TEMP
+               END IF
+  150       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 130
+            END IF
+         ELSE
+            DO 180 J = 1, NRHS
+*
+*           Solve U**H * x = b.
+*
+               B( 1, J ) = B( 1, J ) / DCONJG( D( 1 ) )
+               IF( N.GT.1 )
+     $            B( 2, J ) = ( B( 2, J )-DCONJG( DU( 1 ) )*B( 1, J ) )
+     $                         / DCONJG( D( 2 ) )
+               DO 160 I = 3, N
+                  B( I, J ) = ( B( I, J )-DCONJG( DU( I-1 ) )*
+     $                        B( I-1, J )-DCONJG( DU2( I-2 ) )*
+     $                        B( I-2, J ) ) / DCONJG( D( I ) )
+  160          CONTINUE
+*
+*           Solve L**H * x = b.
+*
+               DO 170 I = N - 1, 1, -1
+                  IF( IPIV( I ).EQ.I ) THEN
+                     B( I, J ) = B( I, J ) - DCONJG( DL( I ) )*
+     $                           B( I+1, J )
+                  ELSE
+                     TEMP = B( I+1, J )
+                     B( I+1, J ) = B( I, J ) - DCONJG( DL( I ) )*TEMP
+                     B( I, J ) = TEMP
+                  END IF
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+      END IF
+*
+*     End of ZGTTS2
+*
+      END
diff --git a/libcruft/lapack/zheev.f b/libcruft/lapack/zheev.f
new file mode 100644
index 0000000..324d161
--- /dev/null
+++ b/libcruft/lapack/zheev.f
@@ -0,0 +1,218 @@
+      SUBROUTINE ZHEEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK,
+     $                  INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * ), W( * )
+      COMPLEX*16         A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHEEV computes all eigenvalues and, optionally, eigenvectors of a
+*  complex Hermitian matrix A.
+*
+*  Arguments
+*  =========
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA, N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          orthonormal eigenvectors of the matrix A.
+*          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
+*          or the upper triangle (if UPLO='U') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  W       (output) DOUBLE PRECISION array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,2*N-1).
+*          For optimal efficiency, LWORK >= (NB+1)*N,
+*          where NB is the blocksize for ZHETRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (max(1, 3*N-2))
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the algorithm failed to converge; i
+*                off-diagonal elements of an intermediate tridiagonal
+*                form did not converge to zero.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+      COMPLEX*16         CONE
+      PARAMETER          ( CONE = ( 1.0D0, 0.0D0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LOWER, LQUERY, WANTZ
+      INTEGER            IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
+     $                   LLWORK, LWKOPT, NB
+      DOUBLE PRECISION   ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
+     $                   SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      DOUBLE PRECISION   DLAMCH, ZLANHE
+      EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANHE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, DSTERF, XERBLA, ZHETRD, ZLASCL, ZSTEQR,
+     $                   ZUNGTR
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      LOWER = LSAME( UPLO, 'L' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'ZHETRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( 1, ( NB+1 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, 2*N-1 ) .AND. .NOT.LQUERY )
+     $      INFO = -8
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHEEV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+      IF( N.EQ.1 ) THEN
+         W( 1 ) = A( 1, 1 )
+         WORK( 1 ) = 1
+         IF( WANTZ )
+     $      A( 1, 1 ) = CONE
+         RETURN
+      END IF
+*
+*     Get machine constants.
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      EPS = DLAMCH( 'Precision' )
+      SMLNUM = SAFMIN / EPS
+      BIGNUM = ONE / SMLNUM
+      RMIN = SQRT( SMLNUM )
+      RMAX = SQRT( BIGNUM )
+*
+*     Scale matrix to allowable range, if necessary.
+*
+      ANRM = ZLANHE( 'M', UPLO, N, A, LDA, RWORK )
+      ISCALE = 0
+      IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
+         ISCALE = 1
+         SIGMA = RMIN / ANRM
+      ELSE IF( ANRM.GT.RMAX ) THEN
+         ISCALE = 1
+         SIGMA = RMAX / ANRM
+      END IF
+      IF( ISCALE.EQ.1 )
+     $   CALL ZLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
+*
+*     Call ZHETRD to reduce Hermitian matrix to tridiagonal form.
+*
+      INDE = 1
+      INDTAU = 1
+      INDWRK = INDTAU + N
+      LLWORK = LWORK - INDWRK + 1
+      CALL ZHETRD( UPLO, N, A, LDA, W, RWORK( INDE ), WORK( INDTAU ),
+     $             WORK( INDWRK ), LLWORK, IINFO )
+*
+*     For eigenvalues only, call DSTERF.  For eigenvectors, first call
+*     ZUNGTR to generate the unitary matrix, then call ZSTEQR.
+*
+      IF( .NOT.WANTZ ) THEN
+         CALL DSTERF( N, W, RWORK( INDE ), INFO )
+      ELSE
+         CALL ZUNGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
+     $                LLWORK, IINFO )
+         INDWRK = INDE + N
+         CALL ZSTEQR( JOBZ, N, W, RWORK( INDE ), A, LDA,
+     $                RWORK( INDWRK ), INFO )
+      END IF
+*
+*     If matrix was scaled, then rescale eigenvalues appropriately.
+*
+      IF( ISCALE.EQ.1 ) THEN
+         IF( INFO.EQ.0 ) THEN
+            IMAX = N
+         ELSE
+            IMAX = INFO - 1
+         END IF
+         CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
+      END IF
+*
+*     Set WORK(1) to optimal complex workspace size.
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of ZHEEV
+*
+      END
diff --git a/libcruft/lapack/zhegs2.f b/libcruft/lapack/zhegs2.f
new file mode 100644
index 0000000..3b2141d
--- /dev/null
+++ b/libcruft/lapack/zhegs2.f
@@ -0,0 +1,224 @@
+      SUBROUTINE ZHEGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHEGS2 reduces a complex Hermitian-definite generalized
+*  eigenproblem to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U')*A*inv(U) or inv(L)*A*inv(L')
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U` or L'*A*L.
+*
+*  B must have been previously factorized as U'*U or L*L' by ZPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U')*A*inv(U) or inv(L)*A*inv(L');
+*          = 2 or 3: compute U*A*U' or L'*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored, and how B has been factorized.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) COMPLEX*16 array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by ZPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, HALF
+      PARAMETER          ( ONE = 1.0D+0, HALF = 0.5D+0 )
+      COMPLEX*16         CONE
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K
+      DOUBLE PRECISION   AKK, BKK
+      COMPLEX*16         CT
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZAXPY, ZDSCAL, ZHER2, ZLACGV, ZTRMV,
+     $                   ZTRSV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHEGS2', -INFO )
+         RETURN
+      END IF
+*
+      IF( ITYPE.EQ.1 ) THEN
+         IF( UPPER ) THEN
+*
+*           Compute inv(U')*A*inv(U)
+*
+            DO 10 K = 1, N
+*
+*              Update the upper triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL ZDSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA )
+                  CT = -HALF*AKK
+                  CALL ZLACGV( N-K, A( K, K+1 ), LDA )
+                  CALL ZLACGV( N-K, B( K, K+1 ), LDB )
+                  CALL ZAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL ZHER2( UPLO, N-K, -CONE, A( K, K+1 ), LDA,
+     $                        B( K, K+1 ), LDB, A( K+1, K+1 ), LDA )
+                  CALL ZAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL ZLACGV( N-K, B( K, K+1 ), LDB )
+                  CALL ZTRSV( UPLO, 'Conjugate transpose', 'Non-unit',
+     $                        N-K, B( K+1, K+1 ), LDB, A( K, K+1 ),
+     $                        LDA )
+                  CALL ZLACGV( N-K, A( K, K+1 ), LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute inv(L)*A*inv(L')
+*
+            DO 20 K = 1, N
+*
+*              Update the lower triangle of A(k:n,k:n)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               AKK = AKK / BKK**2
+               A( K, K ) = AKK
+               IF( K.LT.N ) THEN
+                  CALL ZDSCAL( N-K, ONE / BKK, A( K+1, K ), 1 )
+                  CT = -HALF*AKK
+                  CALL ZAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL ZHER2( UPLO, N-K, -CONE, A( K+1, K ), 1,
+     $                        B( K+1, K ), 1, A( K+1, K+1 ), LDA )
+                  CALL ZAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
+                  CALL ZTRSV( UPLO, 'No transpose', 'Non-unit', N-K,
+     $                        B( K+1, K+1 ), LDB, A( K+1, K ), 1 )
+               END IF
+   20       CONTINUE
+         END IF
+      ELSE
+         IF( UPPER ) THEN
+*
+*           Compute U*A*U'
+*
+            DO 30 K = 1, N
+*
+*              Update the upper triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL ZTRMV( UPLO, 'No transpose', 'Non-unit', K-1, B,
+     $                     LDB, A( 1, K ), 1 )
+               CT = HALF*AKK
+               CALL ZAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL ZHER2( UPLO, K-1, CONE, A( 1, K ), 1, B( 1, K ), 1,
+     $                     A, LDA )
+               CALL ZAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
+               CALL ZDSCAL( K-1, BKK, A( 1, K ), 1 )
+               A( K, K ) = AKK*BKK**2
+   30       CONTINUE
+         ELSE
+*
+*           Compute L'*A*L
+*
+            DO 40 K = 1, N
+*
+*              Update the lower triangle of A(1:k,1:k)
+*
+               AKK = A( K, K )
+               BKK = B( K, K )
+               CALL ZLACGV( K-1, A( K, 1 ), LDA )
+               CALL ZTRMV( UPLO, 'Conjugate transpose', 'Non-unit', K-1,
+     $                     B, LDB, A( K, 1 ), LDA )
+               CT = HALF*AKK
+               CALL ZLACGV( K-1, B( K, 1 ), LDB )
+               CALL ZAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL ZHER2( UPLO, K-1, CONE, A( K, 1 ), LDA, B( K, 1 ),
+     $                     LDB, A, LDA )
+               CALL ZAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
+               CALL ZLACGV( K-1, B( K, 1 ), LDB )
+               CALL ZDSCAL( K-1, BKK, A( K, 1 ), LDA )
+               CALL ZLACGV( K-1, A( K, 1 ), LDA )
+               A( K, K ) = AKK*BKK**2
+   40       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+*     End of ZHEGS2
+*
+      END
diff --git a/libcruft/lapack/zhegst.f b/libcruft/lapack/zhegst.f
new file mode 100644
index 0000000..0d50d36
--- /dev/null
+++ b/libcruft/lapack/zhegst.f
@@ -0,0 +1,259 @@
+      SUBROUTINE ZHEGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHEGST reduces a complex Hermitian-definite generalized
+*  eigenproblem to standard form.
+*
+*  If ITYPE = 1, the problem is A*x = lambda*B*x,
+*  and A is overwritten by inv(U**H)*A*inv(U) or inv(L)*A*inv(L**H)
+*
+*  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
+*  B*A*x = lambda*x, and A is overwritten by U*A*U**H or L**H*A*L.
+*
+*  B must have been previously factorized as U**H*U or L*L**H by ZPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          = 1: compute inv(U**H)*A*inv(U) or inv(L)*A*inv(L**H);
+*          = 2 or 3: compute U*A*U**H or L**H*A*L.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored and B is factored as
+*                  U**H*U;
+*          = 'L':  Lower triangle of A is stored and B is factored as
+*                  L*L**H.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the transformed matrix, stored in the
+*          same format as A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input) COMPLEX*16 array, dimension (LDB,N)
+*          The triangular factor from the Cholesky factorization of B,
+*          as returned by ZPOTRF.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+      COMPLEX*16         CONE, HALF
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ),
+     $                   HALF = ( 0.5D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            K, KB, NB
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZHEGS2, ZHEMM, ZHER2K, ZTRMM, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHEGST', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'ZHEGST', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZHEGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ITYPE.EQ.1 ) THEN
+            IF( UPPER ) THEN
+*
+*              Compute inv(U')*A*inv(U)
+*
+               DO 10 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(k:n,k:n)
+*
+                  CALL ZHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL ZTRSM( 'Left', UPLO, 'Conjugate transpose',
+     $                           'Non-unit', KB, N-K-KB+1, CONE,
+     $                           B( K, K ), LDB, A( K, K+KB ), LDA )
+                     CALL ZHEMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB,
+     $                           CONE, A( K, K+KB ), LDA )
+                     CALL ZHER2K( UPLO, 'Conjugate transpose', N-K-KB+1,
+     $                            KB, -CONE, A( K, K+KB ), LDA,
+     $                            B( K, K+KB ), LDB, ONE,
+     $                            A( K+KB, K+KB ), LDA )
+                     CALL ZHEMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,
+     $                           A( K, K ), LDA, B( K, K+KB ), LDB,
+     $                           CONE, A( K, K+KB ), LDA )
+                     CALL ZTRSM( 'Right', UPLO, 'No transpose',
+     $                           'Non-unit', KB, N-K-KB+1, CONE,
+     $                           B( K+KB, K+KB ), LDB, A( K, K+KB ),
+     $                           LDA )
+                  END IF
+   10          CONTINUE
+            ELSE
+*
+*              Compute inv(L)*A*inv(L')
+*
+               DO 20 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(k:n,k:n)
+*
+                  CALL ZHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+                  IF( K+KB.LE.N ) THEN
+                     CALL ZTRSM( 'Right', UPLO, 'Conjugate transpose',
+     $                           'Non-unit', N-K-KB+1, KB, CONE,
+     $                           B( K, K ), LDB, A( K+KB, K ), LDA )
+                     CALL ZHEMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB,
+     $                           CONE, A( K+KB, K ), LDA )
+                     CALL ZHER2K( UPLO, 'No transpose', N-K-KB+1, KB,
+     $                            -CONE, A( K+KB, K ), LDA,
+     $                            B( K+KB, K ), LDB, ONE,
+     $                            A( K+KB, K+KB ), LDA )
+                     CALL ZHEMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,
+     $                           A( K, K ), LDA, B( K+KB, K ), LDB,
+     $                           CONE, A( K+KB, K ), LDA )
+                     CALL ZTRSM( 'Left', UPLO, 'No transpose',
+     $                           'Non-unit', N-K-KB+1, KB, CONE,
+     $                           B( K+KB, K+KB ), LDB, A( K+KB, K ),
+     $                           LDA )
+                  END IF
+   20          CONTINUE
+            END IF
+         ELSE
+            IF( UPPER ) THEN
+*
+*              Compute U*A*U'
+*
+               DO 30 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the upper triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL ZTRMM( 'Left', UPLO, 'No transpose', 'Non-unit',
+     $                        K-1, KB, CONE, B, LDB, A( 1, K ), LDA )
+                  CALL ZHEMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, CONE, A( 1, K ),
+     $                        LDA )
+                  CALL ZHER2K( UPLO, 'No transpose', K-1, KB, CONE,
+     $                         A( 1, K ), LDA, B( 1, K ), LDB, ONE, A,
+     $                         LDA )
+                  CALL ZHEMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),
+     $                        LDA, B( 1, K ), LDB, CONE, A( 1, K ),
+     $                        LDA )
+                  CALL ZTRMM( 'Right', UPLO, 'Conjugate transpose',
+     $                        'Non-unit', K-1, KB, CONE, B( K, K ), LDB,
+     $                        A( 1, K ), LDA )
+                  CALL ZHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   30          CONTINUE
+            ELSE
+*
+*              Compute L'*A*L
+*
+               DO 40 K = 1, N, NB
+                  KB = MIN( N-K+1, NB )
+*
+*                 Update the lower triangle of A(1:k+kb-1,1:k+kb-1)
+*
+                  CALL ZTRMM( 'Right', UPLO, 'No transpose', 'Non-unit',
+     $                        KB, K-1, CONE, B, LDB, A( K, 1 ), LDA )
+                  CALL ZHEMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, CONE, A( K, 1 ),
+     $                        LDA )
+                  CALL ZHER2K( UPLO, 'Conjugate transpose', K-1, KB,
+     $                         CONE, A( K, 1 ), LDA, B( K, 1 ), LDB,
+     $                         ONE, A, LDA )
+                  CALL ZHEMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),
+     $                        LDA, B( K, 1 ), LDB, CONE, A( K, 1 ),
+     $                        LDA )
+                  CALL ZTRMM( 'Left', UPLO, 'Conjugate transpose',
+     $                        'Non-unit', KB, K-1, CONE, B( K, K ), LDB,
+     $                        A( K, 1 ), LDA )
+                  CALL ZHEGS2( ITYPE, UPLO, KB, A( K, K ), LDA,
+     $                         B( K, K ), LDB, INFO )
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of ZHEGST
+*
+      END
diff --git a/libcruft/lapack/zhegv.f b/libcruft/lapack/zhegv.f
new file mode 100644
index 0000000..ded1b58
--- /dev/null
+++ b/libcruft/lapack/zhegv.f
@@ -0,0 +1,232 @@
+      SUBROUTINE ZHEGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
+     $                  LWORK, RWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          JOBZ, UPLO
+      INTEGER            INFO, ITYPE, LDA, LDB, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * ), W( * )
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHEGV computes all the eigenvalues, and optionally, the eigenvectors
+*  of a complex generalized Hermitian-definite eigenproblem, of the form
+*  A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.
+*  Here A and B are assumed to be Hermitian and B is also
+*  positive definite.
+*
+*  Arguments
+*  =========
+*
+*  ITYPE   (input) INTEGER
+*          Specifies the problem type to be solved:
+*          = 1:  A*x = (lambda)*B*x
+*          = 2:  A*B*x = (lambda)*x
+*          = 3:  B*A*x = (lambda)*x
+*
+*  JOBZ    (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only;
+*          = 'V':  Compute eigenvalues and eigenvectors.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangles of A and B are stored;
+*          = 'L':  Lower triangles of A and B are stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrices A and B.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA, N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of A contains the
+*          upper triangular part of the matrix A.  If UPLO = 'L',
+*          the leading N-by-N lower triangular part of A contains
+*          the lower triangular part of the matrix A.
+*
+*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
+*          matrix Z of eigenvectors.  The eigenvectors are normalized
+*          as follows:
+*          if ITYPE = 1 or 2, Z**H*B*Z = I;
+*          if ITYPE = 3, Z**H*inv(B)*Z = I.
+*          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
+*          or the lower triangle (if UPLO='L') of A, including the
+*          diagonal, is destroyed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB, N)
+*          On entry, the Hermitian positive definite matrix B.
+*          If UPLO = 'U', the leading N-by-N upper triangular part of B
+*          contains the upper triangular part of the matrix B.
+*          If UPLO = 'L', the leading N-by-N lower triangular part of B
+*          contains the lower triangular part of the matrix B.
+*
+*          On exit, if INFO <= N, the part of B containing the matrix is
+*          overwritten by the triangular factor U or L from the Cholesky
+*          factorization B = U**H*U or B = L*L**H.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  W       (output) DOUBLE PRECISION array, dimension (N)
+*          If INFO = 0, the eigenvalues in ascending order.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The length of the array WORK.  LWORK >= max(1,2*N-1).
+*          For optimal efficiency, LWORK >= (NB+1)*N,
+*          where NB is the blocksize for ZHETRD returned by ILAENV.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (max(1, 3*N-2))
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  ZPOTRF or ZHEEV returned an error code:
+*             <= N:  if INFO = i, ZHEEV failed to converge;
+*                    i off-diagonal elements of an intermediate
+*                    tridiagonal form did not converge to zero;
+*             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
+*                    minor of order i of B is not positive definite.
+*                    The factorization of B could not be completed and
+*                    no eigenvalues or eigenvectors were computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER, WANTZ
+      CHARACTER          TRANS
+      INTEGER            LWKOPT, NB, NEIG
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZHEEV, ZHEGST, ZPOTRF, ZTRMM, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      WANTZ = LSAME( JOBZ, 'V' )
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      INFO = 0
+      IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
+         INFO = -1
+      ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'ZHETRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = MAX( 1, ( NB + 1 )*N )
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, 2*N - 1 ) .AND. .NOT.LQUERY ) THEN
+            INFO = -11
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHEGV ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Form a Cholesky factorization of B.
+*
+      CALL ZPOTRF( UPLO, N, B, LDB, INFO )
+      IF( INFO.NE.0 ) THEN
+         INFO = N + INFO
+         RETURN
+      END IF
+*
+*     Transform problem to standard eigenvalue problem and solve.
+*
+      CALL ZHEGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
+      CALL ZHEEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, INFO )
+*
+      IF( WANTZ ) THEN
+*
+*        Backtransform eigenvectors to the original problem.
+*
+         NEIG = N
+         IF( INFO.GT.0 )
+     $      NEIG = INFO - 1
+         IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
+*
+*           For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
+*           backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'N'
+            ELSE
+               TRANS = 'C'
+            END IF
+*
+            CALL ZTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+*
+         ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*           For B*A*x=(lambda)*x;
+*           backtransform eigenvectors: x = L*y or U'*y
+*
+            IF( UPPER ) THEN
+               TRANS = 'C'
+            ELSE
+               TRANS = 'N'
+            END IF
+*
+            CALL ZTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
+     $                  B, LDB, A, LDA )
+         END IF
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of ZHEGV
+*
+      END
diff --git a/libcruft/lapack/zhetd2.f b/libcruft/lapack/zhetd2.f
new file mode 100644
index 0000000..24b0a1d
--- /dev/null
+++ b/libcruft/lapack/zhetd2.f
@@ -0,0 +1,258 @@
+      SUBROUTINE ZHETD2( UPLO, N, A, LDA, D, E, TAU, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+      COMPLEX*16         A( LDA, * ), TAU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHETD2 reduces a complex Hermitian matrix A to real symmetric
+*  tridiagonal form T by a unitary similarity transformation:
+*  Q' * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the unitary
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the unitary matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO, HALF
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   HALF = ( 0.5D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      COMPLEX*16         ALPHA, TAUI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZAXPY, ZHEMV, ZHER2, ZLARFG
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX*16         ZDOTC
+      EXTERNAL           LSAME, ZDOTC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHETD2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A
+*
+         A( N, N ) = DBLE( A( N, N ) )
+         DO 10 I = N - 1, 1, -1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(1:i-1,i+1)
+*
+            ALPHA = A( I, I+1 )
+            CALL ZLARFG( I, ALPHA, A( 1, I+1 ), 1, TAUI )
+            E( I ) = ALPHA
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(1:i,1:i)
+*
+               A( I, I+1 ) = ONE
+*
+*              Compute  x := tau * A * v  storing x in TAU(1:i)
+*
+               CALL ZHEMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO,
+     $                     TAU, 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*ZDOTC( I, TAU, 1, A( 1, I+1 ), 1 )
+               CALL ZAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL ZHER2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A,
+     $                     LDA )
+*
+            ELSE
+               A( I, I ) = DBLE( A( I, I ) )
+            END IF
+            A( I, I+1 ) = E( I )
+            D( I+1 ) = A( I+1, I+1 )
+            TAU( I ) = TAUI
+   10    CONTINUE
+         D( 1 ) = A( 1, 1 )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         A( 1, 1 ) = DBLE( A( 1, 1 ) )
+         DO 20 I = 1, N - 1
+*
+*           Generate elementary reflector H(i) = I - tau * v * v'
+*           to annihilate A(i+2:n,i)
+*
+            ALPHA = A( I+1, I )
+            CALL ZLARFG( N-I, ALPHA, A( MIN( I+2, N ), I ), 1, TAUI )
+            E( I ) = ALPHA
+*
+            IF( TAUI.NE.ZERO ) THEN
+*
+*              Apply H(i) from both sides to A(i+1:n,i+1:n)
+*
+               A( I+1, I ) = ONE
+*
+*              Compute  x := tau * A * v  storing y in TAU(i:n-1)
+*
+               CALL ZHEMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, TAU( I ), 1 )
+*
+*              Compute  w := x - 1/2 * tau * (x'*v) * v
+*
+               ALPHA = -HALF*TAUI*ZDOTC( N-I, TAU( I ), 1, A( I+1, I ),
+     $                 1 )
+               CALL ZAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )
+*
+*              Apply the transformation as a rank-2 update:
+*                 A := A - v * w' - w * v'
+*
+               CALL ZHER2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1,
+     $                     A( I+1, I+1 ), LDA )
+*
+            ELSE
+               A( I+1, I+1 ) = DBLE( A( I+1, I+1 ) )
+            END IF
+            A( I+1, I ) = E( I )
+            D( I ) = A( I, I )
+            TAU( I ) = TAUI
+   20    CONTINUE
+         D( N ) = A( N, N )
+      END IF
+*
+      RETURN
+*
+*     End of ZHETD2
+*
+      END
diff --git a/libcruft/lapack/zhetrd.f b/libcruft/lapack/zhetrd.f
new file mode 100644
index 0000000..fb0cd0b
--- /dev/null
+++ b/libcruft/lapack/zhetrd.f
@@ -0,0 +1,296 @@
+      SUBROUTINE ZHETRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHETRD reduces a complex Hermitian matrix A to real symmetric
+*  tridiagonal form T by a unitary similarity transformation:
+*  Q**H * A * Q = T.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit, if UPLO = 'U', the diagonal and first superdiagonal
+*          of A are overwritten by the corresponding elements of the
+*          tridiagonal matrix T, and the elements above the first
+*          superdiagonal, with the array TAU, represent the unitary
+*          matrix Q as a product of elementary reflectors; if UPLO
+*          = 'L', the diagonal and first subdiagonal of A are over-
+*          written by the corresponding elements of the tridiagonal
+*          matrix T, and the elements below the first subdiagonal, with
+*          the array TAU, represent the unitary matrix Q as a product
+*          of elementary reflectors. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (N)
+*          The diagonal elements of the tridiagonal matrix T:
+*          D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (N-1)
+*          The off-diagonal elements of the tridiagonal matrix T:
+*          E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (N-1)
+*          The scalar factors of the elementary reflectors (see Further
+*          Details).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= 1.
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n-1) . . . H(2) H(1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
+*  A(1:i-1,i+1), and tau in TAU(i).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(n-1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
+*  and tau in TAU(i).
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  d   e   v2  v3  v4 )              (  d                  )
+*    (      d   e   v3  v4 )              (  e   d              )
+*    (          d   e   v4 )              (  v1  e   d          )
+*    (              d   e  )              (  v1  v2  e   d      )
+*    (                  d  )              (  v1  v2  v3  e   d  )
+*
+*  where d and e denote diagonal and off-diagonal elements of T, and vi
+*  denotes an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+      COMPLEX*16         CONE
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZHER2K, ZHETD2, ZLATRD
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.
+*
+         NB = ILAENV( 1, 'ZHETRD', UPLO, N, -1, -1, -1 )
+         LWKOPT = N*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHETRD', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NX = N
+      IWS = 1
+      IF( NB.GT.1 .AND. NB.LT.N ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code
+*        (last block is always handled by unblocked code).
+*
+         NX = MAX( NB, ILAENV( 3, 'ZHETRD', UPLO, N, -1, -1, -1 ) )
+         IF( NX.LT.N ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  determine the
+*              minimum value of NB, and reduce NB or force use of
+*              unblocked code by setting NX = N.
+*
+               NB = MAX( LWORK / LDWORK, 1 )
+               NBMIN = ILAENV( 2, 'ZHETRD', UPLO, N, -1, -1, -1 )
+               IF( NB.LT.NBMIN )
+     $            NX = N
+            END IF
+         ELSE
+            NX = N
+         END IF
+      ELSE
+         NB = 1
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Reduce the upper triangle of A.
+*        Columns 1:kk are handled by the unblocked method.
+*
+         KK = N - ( ( N-NX+NB-1 ) / NB )*NB
+         DO 20 I = N - NB + 1, KK + 1, -NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL ZLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK,
+     $                   LDWORK )
+*
+*           Update the unreduced submatrix A(1:i-1,1:i-1), using an
+*           update of the form:  A := A - V*W' - W*V'
+*
+            CALL ZHER2K( UPLO, 'No transpose', I-1, NB, -CONE,
+     $                   A( 1, I ), LDA, WORK, LDWORK, ONE, A, LDA )
+*
+*           Copy superdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 10 J = I, I + NB - 1
+               A( J-1, J ) = E( J-1 )
+               D( J ) = A( J, J )
+   10       CONTINUE
+   20    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL ZHETD2( UPLO, KK, A, LDA, D, E, TAU, IINFO )
+      ELSE
+*
+*        Reduce the lower triangle of A
+*
+         DO 40 I = 1, N - NX, NB
+*
+*           Reduce columns i:i+nb-1 to tridiagonal form and form the
+*           matrix W which is needed to update the unreduced part of
+*           the matrix
+*
+            CALL ZLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ),
+     $                   TAU( I ), WORK, LDWORK )
+*
+*           Update the unreduced submatrix A(i+nb:n,i+nb:n), using
+*           an update of the form:  A := A - V*W' - W*V'
+*
+            CALL ZHER2K( UPLO, 'No transpose', N-I-NB+1, NB, -CONE,
+     $                   A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE,
+     $                   A( I+NB, I+NB ), LDA )
+*
+*           Copy subdiagonal elements back into A, and diagonal
+*           elements into D
+*
+            DO 30 J = I, I + NB - 1
+               A( J+1, J ) = E( J )
+               D( J ) = A( J, J )
+   30       CONTINUE
+   40    CONTINUE
+*
+*        Use unblocked code to reduce the last or only block
+*
+         CALL ZHETD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ),
+     $                TAU( I ), IINFO )
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZHETRD
+*
+      END
diff --git a/libcruft/lapack/zhgeqz.f b/libcruft/lapack/zhgeqz.f
new file mode 100644
index 0000000..6a9403b
--- /dev/null
+++ b/libcruft/lapack/zhgeqz.f
@@ -0,0 +1,759 @@
+      SUBROUTINE ZHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,
+     $                   ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK,
+     $                   RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, COMPZ, JOB
+      INTEGER            IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         ALPHA( * ), BETA( * ), H( LDH, * ),
+     $                   Q( LDQ, * ), T( LDT, * ), WORK( * ),
+     $                   Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZHGEQZ computes the eigenvalues of a complex matrix pair (H,T),
+*  where H is an upper Hessenberg matrix and T is upper triangular,
+*  using the single-shift QZ method.
+*  Matrix pairs of this type are produced by the reduction to
+*  generalized upper Hessenberg form of a complex matrix pair (A,B):
+*  
+*     A = Q1*H*Z1**H,  B = Q1*T*Z1**H,
+*  
+*  as computed by ZGGHRD.
+*  
+*  If JOB='S', then the Hessenberg-triangular pair (H,T) is
+*  also reduced to generalized Schur form,
+*  
+*     H = Q*S*Z**H,  T = Q*P*Z**H,
+*  
+*  where Q and Z are unitary matrices and S and P are upper triangular.
+*  
+*  Optionally, the unitary matrix Q from the generalized Schur
+*  factorization may be postmultiplied into an input matrix Q1, and the
+*  unitary matrix Z may be postmultiplied into an input matrix Z1.
+*  If Q1 and Z1 are the unitary matrices from ZGGHRD that reduced
+*  the matrix pair (A,B) to generalized Hessenberg form, then the output
+*  matrices Q1*Q and Z1*Z are the unitary factors from the generalized
+*  Schur factorization of (A,B):
+*  
+*     A = (Q1*Q)*S*(Z1*Z)**H,  B = (Q1*Q)*P*(Z1*Z)**H.
+*  
+*  To avoid overflow, eigenvalues of the matrix pair (H,T)
+*  (equivalently, of (A,B)) are computed as a pair of complex values
+*  (alpha,beta).  If beta is nonzero, lambda = alpha / beta is an
+*  eigenvalue of the generalized nonsymmetric eigenvalue problem (GNEP)
+*     A*x = lambda*B*x
+*  and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the
+*  alternate form of the GNEP
+*     mu*A*y = B*y.
+*  The values of alpha and beta for the i-th eigenvalue can be read
+*  directly from the generalized Schur form:  alpha = S(i,i),
+*  beta = P(i,i).
+*
+*  Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix
+*       Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),
+*       pp. 241--256.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          = 'E': Compute eigenvalues only;
+*          = 'S': Computer eigenvalues and the Schur form.
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'N': Left Schur vectors (Q) are not computed;
+*          = 'I': Q is initialized to the unit matrix and the matrix Q
+*                 of left Schur vectors of (H,T) is returned;
+*          = 'V': Q must contain a unitary matrix Q1 on entry and
+*                 the product Q1*Q is returned.
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N': Right Schur vectors (Z) are not computed;
+*          = 'I': Q is initialized to the unit matrix and the matrix Z
+*                 of right Schur vectors of (H,T) is returned;
+*          = 'V': Z must contain a unitary matrix Z1 on entry and
+*                 the product Z1*Z is returned.
+*
+*  N       (input) INTEGER
+*          The order of the matrices H, T, Q, and Z.  N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI mark the rows and columns of H which are in
+*          Hessenberg form.  It is assumed that A is already upper
+*          triangular in rows and columns 1:ILO-1 and IHI+1:N.
+*          If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0.
+*
+*  H       (input/output) COMPLEX*16 array, dimension (LDH, N)
+*          On entry, the N-by-N upper Hessenberg matrix H.
+*          On exit, if JOB = 'S', H contains the upper triangular
+*          matrix S from the generalized Schur factorization.
+*          If JOB = 'E', the diagonal of H matches that of S, but
+*          the rest of H is unspecified.
+*
+*  LDH     (input) INTEGER
+*          The leading dimension of the array H.  LDH >= max( 1, N ).
+*
+*  T       (input/output) COMPLEX*16 array, dimension (LDT, N)
+*          On entry, the N-by-N upper triangular matrix T.
+*          On exit, if JOB = 'S', T contains the upper triangular
+*          matrix P from the generalized Schur factorization.
+*          If JOB = 'E', the diagonal of T matches that of P, but
+*          the rest of T is unspecified.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= max( 1, N ).
+*
+*  ALPHA   (output) COMPLEX*16 array, dimension (N)
+*          The complex scalars alpha that define the eigenvalues of
+*          GNEP.  ALPHA(i) = S(i,i) in the generalized Schur
+*          factorization.
+*
+*  BETA    (output) COMPLEX*16 array, dimension (N)
+*          The real non-negative scalars beta that define the
+*          eigenvalues of GNEP.  BETA(i) = P(i,i) in the generalized
+*          Schur factorization.
+*
+*          Together, the quantities alpha = ALPHA(j) and beta = BETA(j)
+*          represent the j-th eigenvalue of the matrix pair (A,B), in
+*          one of the forms lambda = alpha/beta or mu = beta/alpha.
+*          Since either lambda or mu may overflow, they should not,
+*          in general, be computed.
+*
+*  Q       (input/output) COMPLEX*16 array, dimension (LDQ, N)
+*          On entry, if COMPZ = 'V', the unitary matrix Q1 used in the
+*          reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the unitary matrix of left Schur
+*          vectors of (H,T), and if COMPZ = 'V', the unitary matrix of
+*          left Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= 1.
+*          If COMPQ='V' or 'I', then LDQ >= N.
+*
+*  Z       (input/output) COMPLEX*16 array, dimension (LDZ, N)
+*          On entry, if COMPZ = 'V', the unitary matrix Z1 used in the
+*          reduction of (A,B) to generalized Hessenberg form.
+*          On exit, if COMPZ = 'I', the unitary matrix of right Schur
+*          vectors of (H,T), and if COMPZ = 'V', the unitary matrix of
+*          right Schur vectors of (A,B).
+*          Not referenced if COMPZ = 'N'.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1.
+*          If COMPZ='V' or 'I', then LDZ >= N.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,N).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1,...,N: the QZ iteration did not converge.  (H,T) is not
+*                     in Schur form, but ALPHA(i) and BETA(i),
+*                     i=INFO+1,...,N should be correct.
+*          = N+1,...,2*N: the shift calculation failed.  (H,T) is not
+*                     in Schur form, but ALPHA(i) and BETA(i),
+*                     i=INFO-N+1,...,N should be correct.
+*
+*  Further Details
+*  ===============
+*
+*  We assume that complex ABS works as long as its value is less than
+*  overflow.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      DOUBLE PRECISION   HALF
+      PARAMETER          ( HALF = 0.5D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ILAZR2, ILAZRO, ILQ, ILSCHR, ILZ, LQUERY
+      INTEGER            ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,
+     $                   ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,
+     $                   JR, MAXIT
+      DOUBLE PRECISION   ABSB, ANORM, ASCALE, ATOL, BNORM, BSCALE, BTOL,
+     $                   C, SAFMIN, TEMP, TEMP2, TEMPR, ULP
+      COMPLEX*16         ABI22, AD11, AD12, AD21, AD22, CTEMP, CTEMP2,
+     $                   CTEMP3, ESHIFT, RTDISC, S, SHIFT, SIGNBC, T1,
+     $                   U12, X
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH, ZLANHS
+      EXTERNAL           LSAME, DLAMCH, ZLANHS
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARTG, ZLASET, ZROT, ZSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN,
+     $                   SQRT
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   ABS1
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode JOB, COMPQ, COMPZ
+*
+      IF( LSAME( JOB, 'E' ) ) THEN
+         ILSCHR = .FALSE.
+         ISCHUR = 1
+      ELSE IF( LSAME( JOB, 'S' ) ) THEN
+         ILSCHR = .TRUE.
+         ISCHUR = 2
+      ELSE
+         ISCHUR = 0
+      END IF
+*
+      IF( LSAME( COMPQ, 'N' ) ) THEN
+         ILQ = .FALSE.
+         ICOMPQ = 1
+      ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 2
+      ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
+         ILQ = .TRUE.
+         ICOMPQ = 3
+      ELSE
+         ICOMPQ = 0
+      END IF
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ILZ = .FALSE.
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 2
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ILZ = .TRUE.
+         ICOMPZ = 3
+      ELSE
+         ICOMPZ = 0
+      END IF
+*
+*     Check Argument Values
+*
+      INFO = 0
+      WORK( 1 ) = MAX( 1, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( ISCHUR.EQ.0 ) THEN
+         INFO = -1
+      ELSE IF( ICOMPQ.EQ.0 ) THEN
+         INFO = -2
+      ELSE IF( ICOMPZ.EQ.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( ILO.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
+         INFO = -6
+      ELSE IF( LDH.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDT.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -14
+      ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THEN
+         INFO = -16
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -18
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZHGEQZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+*     WORK( 1 ) = CMPLX( 1 )
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = DCMPLX( 1 )
+         RETURN
+      END IF
+*
+*     Initialize Q and Z
+*
+      IF( ICOMPQ.EQ.3 )
+     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
+      IF( ICOMPZ.EQ.3 )
+     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
+*
+*     Machine Constants
+*
+      IN = IHI + 1 - ILO
+      SAFMIN = DLAMCH( 'S' )
+      ULP = DLAMCH( 'E' )*DLAMCH( 'B' )
+      ANORM = ZLANHS( 'F', IN, H( ILO, ILO ), LDH, RWORK )
+      BNORM = ZLANHS( 'F', IN, T( ILO, ILO ), LDT, RWORK )
+      ATOL = MAX( SAFMIN, ULP*ANORM )
+      BTOL = MAX( SAFMIN, ULP*BNORM )
+      ASCALE = ONE / MAX( SAFMIN, ANORM )
+      BSCALE = ONE / MAX( SAFMIN, BNORM )
+*
+*
+*     Set Eigenvalues IHI+1:N
+*
+      DO 10 J = IHI + 1, N
+         ABSB = ABS( T( J, J ) )
+         IF( ABSB.GT.SAFMIN ) THEN
+            SIGNBC = DCONJG( T( J, J ) / ABSB )
+            T( J, J ) = ABSB
+            IF( ILSCHR ) THEN
+               CALL ZSCAL( J-1, SIGNBC, T( 1, J ), 1 )
+               CALL ZSCAL( J, SIGNBC, H( 1, J ), 1 )
+            ELSE
+               H( J, J ) = H( J, J )*SIGNBC
+            END IF
+            IF( ILZ )
+     $         CALL ZSCAL( N, SIGNBC, Z( 1, J ), 1 )
+         ELSE
+            T( J, J ) = CZERO
+         END IF
+         ALPHA( J ) = H( J, J )
+         BETA( J ) = T( J, J )
+   10 CONTINUE
+*
+*     If IHI < ILO, skip QZ steps
+*
+      IF( IHI.LT.ILO )
+     $   GO TO 190
+*
+*     MAIN QZ ITERATION LOOP
+*
+*     Initialize dynamic indices
+*
+*     Eigenvalues ILAST+1:N have been found.
+*        Column operations modify rows IFRSTM:whatever
+*        Row operations modify columns whatever:ILASTM
+*
+*     If only eigenvalues are being computed, then
+*        IFRSTM is the row of the last splitting row above row ILAST;
+*        this is always at least ILO.
+*     IITER counts iterations since the last eigenvalue was found,
+*        to tell when to use an extraordinary shift.
+*     MAXIT is the maximum number of QZ sweeps allowed.
+*
+      ILAST = IHI
+      IF( ILSCHR ) THEN
+         IFRSTM = 1
+         ILASTM = N
+      ELSE
+         IFRSTM = ILO
+         ILASTM = IHI
+      END IF
+      IITER = 0
+      ESHIFT = CZERO
+      MAXIT = 30*( IHI-ILO+1 )
+*
+      DO 170 JITER = 1, MAXIT
+*
+*        Check for too many iterations.
+*
+         IF( JITER.GT.MAXIT )
+     $      GO TO 180
+*
+*        Split the matrix if possible.
+*
+*        Two tests:
+*           1: H(j,j-1)=0  or  j=ILO
+*           2: T(j,j)=0
+*
+*        Special case: j=ILAST
+*
+         IF( ILAST.EQ.ILO ) THEN
+            GO TO 60
+         ELSE
+            IF( ABS1( H( ILAST, ILAST-1 ) ).LE.ATOL ) THEN
+               H( ILAST, ILAST-1 ) = CZERO
+               GO TO 60
+            END IF
+         END IF
+*
+         IF( ABS( T( ILAST, ILAST ) ).LE.BTOL ) THEN
+            T( ILAST, ILAST ) = CZERO
+            GO TO 50
+         END IF
+*
+*        General case: j<ILAST
+*
+         DO 40 J = ILAST - 1, ILO, -1
+*
+*           Test 1: for H(j,j-1)=0 or j=ILO
+*
+            IF( J.EQ.ILO ) THEN
+               ILAZRO = .TRUE.
+            ELSE
+               IF( ABS1( H( J, J-1 ) ).LE.ATOL ) THEN
+                  H( J, J-1 ) = CZERO
+                  ILAZRO = .TRUE.
+               ELSE
+                  ILAZRO = .FALSE.
+               END IF
+            END IF
+*
+*           Test 2: for T(j,j)=0
+*
+            IF( ABS( T( J, J ) ).LT.BTOL ) THEN
+               T( J, J ) = CZERO
+*
+*              Test 1a: Check for 2 consecutive small subdiagonals in A
+*
+               ILAZR2 = .FALSE.
+               IF( .NOT.ILAZRO ) THEN
+                  IF( ABS1( H( J, J-1 ) )*( ASCALE*ABS1( H( J+1,
+     $                J ) ) ).LE.ABS1( H( J, J ) )*( ASCALE*ATOL ) )
+     $                ILAZR2 = .TRUE.
+               END IF
+*
+*              If both tests pass (1 & 2), i.e., the leading diagonal
+*              element of B in the block is zero, split a 1x1 block off
+*              at the top. (I.e., at the J-th row/column) The leading
+*              diagonal element of the remainder can also be zero, so
+*              this may have to be done repeatedly.
+*
+               IF( ILAZRO .OR. ILAZR2 ) THEN
+                  DO 20 JCH = J, ILAST - 1
+                     CTEMP = H( JCH, JCH )
+                     CALL ZLARTG( CTEMP, H( JCH+1, JCH ), C, S,
+     $                            H( JCH, JCH ) )
+                     H( JCH+1, JCH ) = CZERO
+                     CALL ZROT( ILASTM-JCH, H( JCH, JCH+1 ), LDH,
+     $                          H( JCH+1, JCH+1 ), LDH, C, S )
+                     CALL ZROT( ILASTM-JCH, T( JCH, JCH+1 ), LDT,
+     $                          T( JCH+1, JCH+1 ), LDT, C, S )
+                     IF( ILQ )
+     $                  CALL ZROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, DCONJG( S ) )
+                     IF( ILAZR2 )
+     $                  H( JCH, JCH-1 ) = H( JCH, JCH-1 )*C
+                     ILAZR2 = .FALSE.
+                     IF( ABS1( T( JCH+1, JCH+1 ) ).GE.BTOL ) THEN
+                        IF( JCH+1.GE.ILAST ) THEN
+                           GO TO 60
+                        ELSE
+                           IFIRST = JCH + 1
+                           GO TO 70
+                        END IF
+                     END IF
+                     T( JCH+1, JCH+1 ) = CZERO
+   20             CONTINUE
+                  GO TO 50
+               ELSE
+*
+*                 Only test 2 passed -- chase the zero to T(ILAST,ILAST)
+*                 Then process as in the case T(ILAST,ILAST)=0
+*
+                  DO 30 JCH = J, ILAST - 1
+                     CTEMP = T( JCH, JCH+1 )
+                     CALL ZLARTG( CTEMP, T( JCH+1, JCH+1 ), C, S,
+     $                            T( JCH, JCH+1 ) )
+                     T( JCH+1, JCH+1 ) = CZERO
+                     IF( JCH.LT.ILASTM-1 )
+     $                  CALL ZROT( ILASTM-JCH-1, T( JCH, JCH+2 ), LDT,
+     $                             T( JCH+1, JCH+2 ), LDT, C, S )
+                     CALL ZROT( ILASTM-JCH+2, H( JCH, JCH-1 ), LDH,
+     $                          H( JCH+1, JCH-1 ), LDH, C, S )
+                     IF( ILQ )
+     $                  CALL ZROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
+     $                             C, DCONJG( S ) )
+                     CTEMP = H( JCH+1, JCH )
+                     CALL ZLARTG( CTEMP, H( JCH+1, JCH-1 ), C, S,
+     $                            H( JCH+1, JCH ) )
+                     H( JCH+1, JCH-1 ) = CZERO
+                     CALL ZROT( JCH+1-IFRSTM, H( IFRSTM, JCH ), 1,
+     $                          H( IFRSTM, JCH-1 ), 1, C, S )
+                     CALL ZROT( JCH-IFRSTM, T( IFRSTM, JCH ), 1,
+     $                          T( IFRSTM, JCH-1 ), 1, C, S )
+                     IF( ILZ )
+     $                  CALL ZROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,
+     $                             C, S )
+   30             CONTINUE
+                  GO TO 50
+               END IF
+            ELSE IF( ILAZRO ) THEN
+*
+*              Only test 1 passed -- work on J:ILAST
+*
+               IFIRST = J
+               GO TO 70
+            END IF
+*
+*           Neither test passed -- try next J
+*
+   40    CONTINUE
+*
+*        (Drop-through is "impossible")
+*
+         INFO = 2*N + 1
+         GO TO 210
+*
+*        T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a
+*        1x1 block.
+*
+   50    CONTINUE
+         CTEMP = H( ILAST, ILAST )
+         CALL ZLARTG( CTEMP, H( ILAST, ILAST-1 ), C, S,
+     $                H( ILAST, ILAST ) )
+         H( ILAST, ILAST-1 ) = CZERO
+         CALL ZROT( ILAST-IFRSTM, H( IFRSTM, ILAST ), 1,
+     $              H( IFRSTM, ILAST-1 ), 1, C, S )
+         CALL ZROT( ILAST-IFRSTM, T( IFRSTM, ILAST ), 1,
+     $              T( IFRSTM, ILAST-1 ), 1, C, S )
+         IF( ILZ )
+     $      CALL ZROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )
+*
+*        H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHA and BETA
+*
+   60    CONTINUE
+         ABSB = ABS( T( ILAST, ILAST ) )
+         IF( ABSB.GT.SAFMIN ) THEN
+            SIGNBC = DCONJG( T( ILAST, ILAST ) / ABSB )
+            T( ILAST, ILAST ) = ABSB
+            IF( ILSCHR ) THEN
+               CALL ZSCAL( ILAST-IFRSTM, SIGNBC, T( IFRSTM, ILAST ), 1 )
+               CALL ZSCAL( ILAST+1-IFRSTM, SIGNBC, H( IFRSTM, ILAST ),
+     $                     1 )
+            ELSE
+               H( ILAST, ILAST ) = H( ILAST, ILAST )*SIGNBC
+            END IF
+            IF( ILZ )
+     $         CALL ZSCAL( N, SIGNBC, Z( 1, ILAST ), 1 )
+         ELSE
+            T( ILAST, ILAST ) = CZERO
+         END IF
+         ALPHA( ILAST ) = H( ILAST, ILAST )
+         BETA( ILAST ) = T( ILAST, ILAST )
+*
+*        Go to next block -- exit if finished.
+*
+         ILAST = ILAST - 1
+         IF( ILAST.LT.ILO )
+     $      GO TO 190
+*
+*        Reset counters
+*
+         IITER = 0
+         ESHIFT = CZERO
+         IF( .NOT.ILSCHR ) THEN
+            ILASTM = ILAST
+            IF( IFRSTM.GT.ILAST )
+     $         IFRSTM = ILO
+         END IF
+         GO TO 160
+*
+*        QZ step
+*
+*        This iteration only involves rows/columns IFIRST:ILAST.  We
+*        assume IFIRST < ILAST, and that the diagonal of B is non-zero.
+*
+   70    CONTINUE
+         IITER = IITER + 1
+         IF( .NOT.ILSCHR ) THEN
+            IFRSTM = IFIRST
+         END IF
+*
+*        Compute the Shift.
+*
+*        At this point, IFIRST < ILAST, and the diagonal elements of
+*        T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in
+*        magnitude)
+*
+         IF( ( IITER / 10 )*10.NE.IITER ) THEN
+*
+*           The Wilkinson shift (AEP p.512), i.e., the eigenvalue of
+*           the bottom-right 2x2 block of A inv(B) which is nearest to
+*           the bottom-right element.
+*
+*           We factor B as U*D, where U has unit diagonals, and
+*           compute (A*inv(D))*inv(U).
+*
+            U12 = ( BSCALE*T( ILAST-1, ILAST ) ) /
+     $            ( BSCALE*T( ILAST, ILAST ) )
+            AD11 = ( ASCALE*H( ILAST-1, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD21 = ( ASCALE*H( ILAST, ILAST-1 ) ) /
+     $             ( BSCALE*T( ILAST-1, ILAST-1 ) )
+            AD12 = ( ASCALE*H( ILAST-1, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            AD22 = ( ASCALE*H( ILAST, ILAST ) ) /
+     $             ( BSCALE*T( ILAST, ILAST ) )
+            ABI22 = AD22 - U12*AD21
+*
+            T1 = HALF*( AD11+ABI22 )
+            RTDISC = SQRT( T1**2+AD12*AD21-AD11*AD22 )
+            TEMP = DBLE( T1-ABI22 )*DBLE( RTDISC ) +
+     $             DIMAG( T1-ABI22 )*DIMAG( RTDISC )
+            IF( TEMP.LE.ZERO ) THEN
+               SHIFT = T1 + RTDISC
+            ELSE
+               SHIFT = T1 - RTDISC
+            END IF
+         ELSE
+*
+*           Exceptional shift.  Chosen for no particularly good reason.
+*
+            ESHIFT = ESHIFT + DCONJG( ( ASCALE*H( ILAST-1, ILAST ) ) /
+     $               ( BSCALE*T( ILAST-1, ILAST-1 ) ) )
+            SHIFT = ESHIFT
+         END IF
+*
+*        Now check for two consecutive small subdiagonals.
+*
+         DO 80 J = ILAST - 1, IFIRST + 1, -1
+            ISTART = J
+            CTEMP = ASCALE*H( J, J ) - SHIFT*( BSCALE*T( J, J ) )
+            TEMP = ABS1( CTEMP )
+            TEMP2 = ASCALE*ABS1( H( J+1, J ) )
+            TEMPR = MAX( TEMP, TEMP2 )
+            IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
+               TEMP = TEMP / TEMPR
+               TEMP2 = TEMP2 / TEMPR
+            END IF
+            IF( ABS1( H( J, J-1 ) )*TEMP2.LE.TEMP*ATOL )
+     $         GO TO 90
+   80    CONTINUE
+*
+         ISTART = IFIRST
+         CTEMP = ASCALE*H( IFIRST, IFIRST ) -
+     $           SHIFT*( BSCALE*T( IFIRST, IFIRST ) )
+   90    CONTINUE
+*
+*        Do an implicit-shift QZ sweep.
+*
+*        Initial Q
+*
+         CTEMP2 = ASCALE*H( ISTART+1, ISTART )
+         CALL ZLARTG( CTEMP, CTEMP2, C, S, CTEMP3 )
+*
+*        Sweep
+*
+         DO 150 J = ISTART, ILAST - 1
+            IF( J.GT.ISTART ) THEN
+               CTEMP = H( J, J-1 )
+               CALL ZLARTG( CTEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
+               H( J+1, J-1 ) = CZERO
+            END IF
+*
+            DO 100 JC = J, ILASTM
+               CTEMP = C*H( J, JC ) + S*H( J+1, JC )
+               H( J+1, JC ) = -DCONJG( S )*H( J, JC ) + C*H( J+1, JC )
+               H( J, JC ) = CTEMP
+               CTEMP2 = C*T( J, JC ) + S*T( J+1, JC )
+               T( J+1, JC ) = -DCONJG( S )*T( J, JC ) + C*T( J+1, JC )
+               T( J, JC ) = CTEMP2
+  100       CONTINUE
+            IF( ILQ ) THEN
+               DO 110 JR = 1, N
+                  CTEMP = C*Q( JR, J ) + DCONJG( S )*Q( JR, J+1 )
+                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
+                  Q( JR, J ) = CTEMP
+  110          CONTINUE
+            END IF
+*
+            CTEMP = T( J+1, J+1 )
+            CALL ZLARTG( CTEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
+            T( J+1, J ) = CZERO
+*
+            DO 120 JR = IFRSTM, MIN( J+2, ILAST )
+               CTEMP = C*H( JR, J+1 ) + S*H( JR, J )
+               H( JR, J ) = -DCONJG( S )*H( JR, J+1 ) + C*H( JR, J )
+               H( JR, J+1 ) = CTEMP
+  120       CONTINUE
+            DO 130 JR = IFRSTM, J
+               CTEMP = C*T( JR, J+1 ) + S*T( JR, J )
+               T( JR, J ) = -DCONJG( S )*T( JR, J+1 ) + C*T( JR, J )
+               T( JR, J+1 ) = CTEMP
+  130       CONTINUE
+            IF( ILZ ) THEN
+               DO 140 JR = 1, N
+                  CTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
+                  Z( JR, J ) = -DCONJG( S )*Z( JR, J+1 ) + C*Z( JR, J )
+                  Z( JR, J+1 ) = CTEMP
+  140          CONTINUE
+            END IF
+  150    CONTINUE
+*
+  160    CONTINUE
+*
+  170 CONTINUE
+*
+*     Drop-through = non-convergence
+*
+  180 CONTINUE
+      INFO = ILAST
+      GO TO 210
+*
+*     Successful completion of all QZ steps
+*
+  190 CONTINUE
+*
+*     Set Eigenvalues 1:ILO-1
+*
+      DO 200 J = 1, ILO - 1
+         ABSB = ABS( T( J, J ) )
+         IF( ABSB.GT.SAFMIN ) THEN
+            SIGNBC = DCONJG( T( J, J ) / ABSB )
+            T( J, J ) = ABSB
+            IF( ILSCHR ) THEN
+               CALL ZSCAL( J-1, SIGNBC, T( 1, J ), 1 )
+               CALL ZSCAL( J, SIGNBC, H( 1, J ), 1 )
+            ELSE
+               H( J, J ) = H( J, J )*SIGNBC
+            END IF
+            IF( ILZ )
+     $         CALL ZSCAL( N, SIGNBC, Z( 1, J ), 1 )
+         ELSE
+            T( J, J ) = CZERO
+         END IF
+         ALPHA( J ) = H( J, J )
+         BETA( J ) = T( J, J )
+  200 CONTINUE
+*
+*     Normal Termination
+*
+      INFO = 0
+*
+*     Exit (other than argument error) -- return optimal workspace size
+*
+  210 CONTINUE
+      WORK( 1 ) = DCMPLX( N )
+      RETURN
+*
+*     End of ZHGEQZ
+*
+      END
diff --git a/libcruft/lapack/zhseqr.f b/libcruft/lapack/zhseqr.f
new file mode 100644
index 0000000..fb721da
--- /dev/null
+++ b/libcruft/lapack/zhseqr.f
@@ -0,0 +1,395 @@
+      SUBROUTINE ZHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, W, Z, LDZ,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK driver routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDH, LDZ, LWORK, N
+      CHARACTER          COMPZ, JOB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*     Purpose
+*     =======
+*
+*     ZHSEQR computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**H, where T is an upper triangular matrix (the
+*     Schur form), and Z is the unitary matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input unitary
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*H*(QZ)**H.
+*
+*     Arguments
+*     =========
+*
+*     JOB   (input) CHARACTER*1
+*           = 'E':  compute eigenvalues only;
+*           = 'S':  compute eigenvalues and the Schur form T.
+*
+*     COMPZ (input) CHARACTER*1
+*           = 'N':  no Schur vectors are computed;
+*           = 'I':  Z is initialized to the unit matrix and the matrix Z
+*                   of Schur vectors of H is returned;
+*           = 'V':  Z must contain an unitary matrix Q on entry, and
+*                   the product Q*Z is returned.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
+*           set by a previous call to ZGEBAL, and then passed to ZGEHRD
+*           when the matrix output by ZGEBAL is reduced to Hessenberg
+*           form. Otherwise ILO and IHI should be set to 1 and N
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) COMPLEX*16 array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and JOB = 'S', H contains the upper
+*           triangular matrix T from the Schur decomposition (the
+*           Schur form). If INFO = 0 and JOB = 'E', the contents of
+*           H are unspecified on exit.  (The output value of H when
+*           INFO.GT.0 is given under the description of INFO below.)
+*
+*           Unlike earlier versions of ZHSEQR, this subroutine may
+*           explicitly H(i,j) = 0 for i.GT.j and j = 1, 2, ... ILO-1
+*           or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     W        (output) COMPLEX*16 array, dimension (N)
+*           The computed eigenvalues. If JOB = 'S', the eigenvalues are
+*           stored in the same order as on the diagonal of the Schur
+*           form returned in H, with W(i) = H(i,i).
+*
+*     Z     (input/output) COMPLEX*16 array, dimension (LDZ,N)
+*           If COMPZ = 'N', Z is not referenced.
+*           If COMPZ = 'I', on entry Z need not be set and on exit,
+*           if INFO = 0, Z contains the unitary matrix Z of the Schur
+*           vectors of H.  If COMPZ = 'V', on entry Z must contain an
+*           N-by-N matrix Q, which is assumed to be equal to the unit
+*           matrix except for the submatrix Z(ILO:IHI,ILO:IHI). On exit,
+*           if INFO = 0, Z contains Q*Z.
+*           Normally Q is the unitary matrix generated by ZUNGHR
+*           after the call to ZGEHRD which formed the Hessenberg matrix
+*           H. (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if COMPZ = 'I' or
+*           COMPZ = 'V', then LDZ.GE.MAX(1,N).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) COMPLEX*16 array, dimension (LWORK)
+*           On exit, if INFO = 0, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then ZHSEQR does a workspace query.
+*           In this case, ZHSEQR checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .LT. 0:  if INFO = -i, the i-th argument had an illegal
+*                    value
+*           .GT. 0:  if INFO = i, ZHSEQR failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and JOB = 'E', then on exit, the
+*                remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and JOB   = 'S', then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is a unitary matrix.  The final
+*                value of  H is upper Hessenberg and triangular in
+*                rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and COMPZ = 'V', then on exit
+*
+*                  (final value of Z)  =  (initial value of Z)*U
+*
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'I', then on exit
+*                      (final value of Z)  = U
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of JOB.)
+*
+*                If INFO .GT. 0 and COMPZ = 'N', then Z is not
+*                accessed.
+*
+*     ================================================================
+*             Default values supplied by
+*             ILAENV(ISPEC,'ZHSEQR',JOB(:1)//COMPZ(:1),N,ILO,IHI,LWORK).
+*             It is suggested that these defaults be adjusted in order
+*             to attain best performance in each particular
+*             computational environment.
+*
+*            ISPEC=1:  The ZLAHQR vs ZLAQR0 crossover point.
+*                      Default: 75. (Must be at least 11.)
+*
+*            ISPEC=2:  Recommended deflation window size.
+*                      This depends on ILO, IHI and NS.  NS is the
+*                      number of simultaneous shifts returned
+*                      by ILAENV(ISPEC=4).  (See ISPEC=4 below.)
+*                      The default for (IHI-ILO+1).LE.500 is NS.
+*                      The default for (IHI-ILO+1).GT.500 is 3*NS/2.
+*
+*            ISPEC=3:  Nibble crossover point. (See ILAENV for
+*                      details.)  Default: 14% of deflation window
+*                      size.
+*
+*            ISPEC=4:  Number of simultaneous shifts, NS, in
+*                      a multi-shift QR iteration.
+*
+*                      If IHI-ILO+1 is ...
+*
+*                      greater than      ...but less    ... the
+*                      or equal to ...      than        default is
+*
+*                           1               30          NS -   2(+)
+*                          30               60          NS -   4(+)
+*                          60              150          NS =  10(+)
+*                         150              590          NS =  **
+*                         590             3000          NS =  64
+*                        3000             6000          NS = 128
+*                        6000             infinity      NS = 256
+*
+*                  (+)  By default some or all matrices of this order 
+*                       are passed to the implicit double shift routine
+*                       ZLAHQR and NS is ignored.  See ISPEC=1 above 
+*                       and comments in IPARM for details.
+*
+*                       The asterisks (**) indicate an ad-hoc
+*                       function of N increasing from 10 to 64.
+*
+*            ISPEC=5:  Select structured matrix multiply.
+*                      (See ILAENV for details.) Default: 3.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    ZLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== NL allocates some local workspace to help small matrices
+*     .    through a rare ZLAHQR failure.  NL .GT. NTINY = 11 is
+*     .    required and NL .LE. NMIN = ILAENV(ISPEC=1,...) is recom-
+*     .    mended.  (The default value of NMIN is 75.)  Using NL = 49
+*     .    allows up to six simultaneous shifts and a 16-by-16
+*     .    deflation window.  ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            NL
+      PARAMETER          ( NL = 49 )
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   RZERO
+      PARAMETER          ( RZERO = 0.0d0 )
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         HL( NL, NL ), WORKL( NL )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            KBOT, NMIN
+      LOGICAL            INITZ, LQUERY, WANTT, WANTZ
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      LOGICAL            LSAME
+      EXTERNAL           ILAENV, LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZCOPY, ZLACPY, ZLAHQR, ZLAQR0, ZLASET
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Decode and check the input parameters. ====
+*
+      WANTT = LSAME( JOB, 'S' )
+      INITZ = LSAME( COMPZ, 'I' )
+      WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )
+      WORK( 1 ) = DCMPLX( DBLE( MAX( 1, N ) ), RZERO )
+      LQUERY = LWORK.EQ.-1
+*
+      INFO = 0
+      IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -5
+      ELSE IF( LDH.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+*
+*        ==== Quick return in case of invalid argument. ====
+*
+         CALL XERBLA( 'ZHSEQR', -INFO )
+         RETURN
+*
+      ELSE IF( N.EQ.0 ) THEN
+*
+*        ==== Quick return in case N = 0; nothing to do. ====
+*
+         RETURN
+*
+      ELSE IF( LQUERY ) THEN
+*
+*        ==== Quick return in case of a workspace query ====
+*
+         CALL ZLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI, Z,
+     $                LDZ, WORK, LWORK, INFO )
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+         WORK( 1 ) = DCMPLX( MAX( DBLE( WORK( 1 ) ), DBLE( MAX( 1,
+     $               N ) ) ), RZERO )
+         RETURN
+*
+      ELSE
+*
+*        ==== copy eigenvalues isolated by ZGEBAL ====
+*
+         IF( ILO.GT.1 )
+     $      CALL ZCOPY( ILO-1, H, LDH+1, W, 1 )
+         IF( IHI.LT.N )
+     $      CALL ZCOPY( N-IHI, H( IHI+1, IHI+1 ), LDH+1, W( IHI+1 ), 1 )
+*
+*        ==== Initialize Z, if requested ====
+*
+         IF( INITZ )
+     $      CALL ZLASET( 'A', N, N, ZERO, ONE, Z, LDZ )
+*
+*        ==== Quick return if possible ====
+*
+         IF( ILO.EQ.IHI ) THEN
+            W( ILO ) = H( ILO, ILO )
+            RETURN
+         END IF
+*
+*        ==== ZLAHQR/ZLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 1, 'ZHSEQR', JOB( : 1 ) // COMPZ( : 1 ), N, ILO,
+     $          IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== ZLAQR0 for big matrices; ZLAHQR for small ones ====
+*
+         IF( N.GT.NMIN ) THEN
+            CALL ZLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI,
+     $                   Z, LDZ, WORK, LWORK, INFO )
+         ELSE
+*
+*           ==== Small matrix ====
+*
+            CALL ZLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI,
+     $                   Z, LDZ, INFO )
+*
+            IF( INFO.GT.0 ) THEN
+*
+*              ==== A rare ZLAHQR failure!  ZLAQR0 sometimes succeeds
+*              .    when ZLAHQR fails. ====
+*
+               KBOT = INFO
+*
+               IF( N.GE.NL ) THEN
+*
+*                 ==== Larger matrices have enough subdiagonal scratch
+*                 .    space to call ZLAQR0 directly. ====
+*
+                  CALL ZLAQR0( WANTT, WANTZ, N, ILO, KBOT, H, LDH, W,
+     $                         ILO, IHI, Z, LDZ, WORK, LWORK, INFO )
+*
+               ELSE
+*
+*                 ==== Tiny matrices don't have enough subdiagonal
+*                 .    scratch space to benefit from ZLAQR0.  Hence,
+*                 .    tiny matrices must be copied into a larger
+*                 .    array before calling ZLAQR0. ====
+*
+                  CALL ZLACPY( 'A', N, N, H, LDH, HL, NL )
+                  HL( N+1, N ) = ZERO
+                  CALL ZLASET( 'A', NL, NL-N, ZERO, ZERO, HL( 1, N+1 ),
+     $                         NL )
+                  CALL ZLAQR0( WANTT, WANTZ, NL, ILO, KBOT, HL, NL, W,
+     $                         ILO, IHI, Z, LDZ, WORKL, NL, INFO )
+                  IF( WANTT .OR. INFO.NE.0 )
+     $               CALL ZLACPY( 'A', N, N, HL, NL, H, LDH )
+               END IF
+            END IF
+         END IF
+*
+*        ==== Clear out the trash, if necessary. ====
+*
+         IF( ( WANTT .OR. INFO.NE.0 ) .AND. N.GT.2 )
+     $      CALL ZLASET( 'L', N-2, N-2, ZERO, ZERO, H( 3, 1 ), LDH )
+*
+*        ==== Ensure reported workspace size is backward-compatible with
+*        .    previous LAPACK versions. ====
+*
+         WORK( 1 ) = DCMPLX( MAX( DBLE( MAX( 1, N ) ),
+     $               DBLE( WORK( 1 ) ) ), RZERO )
+      END IF
+*
+*     ==== End of ZHSEQR ====
+*
+      END
diff --git a/libcruft/lapack/zlabrd.f b/libcruft/lapack/zlabrd.f
new file mode 100644
index 0000000..fb482c8
--- /dev/null
+++ b/libcruft/lapack/zlabrd.f
@@ -0,0 +1,328 @@
+      SUBROUTINE ZLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,
+     $                   LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, LDX, LDY, M, N, NB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * )
+      COMPLEX*16         A( LDA, * ), TAUP( * ), TAUQ( * ), X( LDX, * ),
+     $                   Y( LDY, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLABRD reduces the first NB rows and columns of a complex general
+*  m by n matrix A to upper or lower real bidiagonal form by a unitary
+*  transformation Q' * A * P, and returns the matrices X and Y which
+*  are needed to apply the transformation to the unreduced part of A.
+*
+*  If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower
+*  bidiagonal form.
+*
+*  This is an auxiliary routine called by ZGEBRD
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows in the matrix A.
+*
+*  N       (input) INTEGER
+*          The number of columns in the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of leading rows and columns of A to be reduced.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the m by n general matrix to be reduced.
+*          On exit, the first NB rows and columns of the matrix are
+*          overwritten; the rest of the array is unchanged.
+*          If m >= n, elements on and below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the unitary
+*            matrix Q as a product of elementary reflectors; and
+*            elements above the diagonal in the first NB rows, with the
+*            array TAUP, represent the unitary matrix P as a product
+*            of elementary reflectors.
+*          If m < n, elements below the diagonal in the first NB
+*            columns, with the array TAUQ, represent the unitary
+*            matrix Q as a product of elementary reflectors, and
+*            elements on and above the diagonal in the first NB rows,
+*            with the array TAUP, represent the unitary matrix P as
+*            a product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  D       (output) DOUBLE PRECISION array, dimension (NB)
+*          The diagonal elements of the first NB rows and columns of
+*          the reduced matrix.  D(i) = A(i,i).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (NB)
+*          The off-diagonal elements of the first NB rows and columns of
+*          the reduced matrix.
+*
+*  TAUQ    (output) COMPLEX*16 array dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix Q. See Further Details.
+*
+*  TAUP    (output) COMPLEX*16 array, dimension (NB)
+*          The scalar factors of the elementary reflectors which
+*          represent the unitary matrix P. See Further Details.
+*
+*  X       (output) COMPLEX*16 array, dimension (LDX,NB)
+*          The m-by-nb matrix X required to update the unreduced part
+*          of A.
+*
+*  LDX     (input) INTEGER
+*          The leading dimension of the array X. LDX >= max(1,M).
+*
+*  Y       (output) COMPLEX*16 array, dimension (LDY,NB)
+*          The n-by-nb matrix Y required to update the unreduced part
+*          of A.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  The matrices Q and P are represented as products of elementary
+*  reflectors:
+*
+*     Q = H(1) H(2) . . . H(nb)  and  P = G(1) G(2) . . . G(nb)
+*
+*  Each H(i) and G(i) has the form:
+*
+*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u'
+*
+*  where tauq and taup are complex scalars, and v and u are complex
+*  vectors.
+*
+*  If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in
+*  A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in
+*  A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in
+*  A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).
+*
+*  The elements of the vectors v and u together form the m-by-nb matrix
+*  V and the nb-by-n matrix U' which are needed, with X and Y, to apply
+*  the transformation to the unreduced part of the matrix, using a block
+*  update of the form:  A := A - V*Y' - X*U'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with nb = 2:
+*
+*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n):
+*
+*    (  1   1   u1  u1  u1 )           (  1   u1  u1  u1  u1  u1 )
+*    (  v1  1   1   u2  u2 )           (  1   1   u2  u2  u2  u2 )
+*    (  v1  v2  a   a   a  )           (  v1  1   a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )           (  v1  v2  a   a   a   a  )
+*    (  v1  v2  a   a   a  )
+*
+*  where a denotes an element of the original matrix which is unchanged,
+*  vi denotes an element of the vector defining H(i), and ui an element
+*  of the vector defining G(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZGEMV, ZLACGV, ZLARFG, ZSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( M.GE.N ) THEN
+*
+*        Reduce to upper bidiagonal form
+*
+         DO 10 I = 1, NB
+*
+*           Update A(i:m,i)
+*
+            CALL ZLACGV( I-1, Y( I, 1 ), LDY )
+            CALL ZGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 )
+            CALL ZLACGV( I-1, Y( I, 1 ), LDY )
+            CALL ZGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ),
+     $                  LDX, A( 1, I ), 1, ONE, A( I, I ), 1 )
+*
+*           Generate reflection Q(i) to annihilate A(i+1:m,i)
+*
+            ALPHA = A( I, I )
+            CALL ZLARFG( M-I+1, ALPHA, A( MIN( I+1, M ), I ), 1,
+     $                   TAUQ( I ) )
+            D( I ) = ALPHA
+            IF( I.LT.N ) THEN
+               A( I, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL ZGEMV( 'Conjugate transpose', M-I+1, N-I, ONE,
+     $                     A( I, I+1 ), LDA, A( I, I ), 1, ZERO,
+     $                     Y( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', M-I+1, I-1, ONE,
+     $                     A( I, 1 ), LDA, A( I, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', M-I+1, I-1, ONE,
+     $                     X( I, 1 ), LDX, A( I, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', I-1, N-I, -ONE,
+     $                     A( 1, I+1 ), LDA, Y( 1, I ), 1, ONE,
+     $                     Y( I+1, I ), 1 )
+               CALL ZSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+*
+*              Update A(i,i+1:n)
+*
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+               CALL ZLACGV( I, A( I, 1 ), LDA )
+               CALL ZGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ),
+     $                     LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA )
+               CALL ZLACGV( I, A( I, 1 ), LDA )
+               CALL ZLACGV( I-1, X( I, 1 ), LDX )
+               CALL ZGEMV( 'Conjugate transpose', I-1, N-I, -ONE,
+     $                     A( 1, I+1 ), LDA, X( I, 1 ), LDX, ONE,
+     $                     A( I, I+1 ), LDA )
+               CALL ZLACGV( I-1, X( I, 1 ), LDX )
+*
+*              Generate reflection P(i) to annihilate A(i,i+2:n)
+*
+               ALPHA = A( I, I+1 )
+               CALL ZLARFG( N-I, ALPHA, A( I, MIN( I+2, N ) ), LDA,
+     $                      TAUP( I ) )
+               E( I ) = ALPHA
+               A( I, I+1 ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL ZGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', N-I, I, ONE,
+     $                     Y( I+1, 1 ), LDY, A( I, I+1 ), LDA, ZERO,
+     $                     X( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL ZGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL ZSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Reduce to lower bidiagonal form
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i,i:n)
+*
+            CALL ZLACGV( N-I+1, A( I, I ), LDA )
+            CALL ZLACGV( I-1, A( I, 1 ), LDA )
+            CALL ZGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ),
+     $                  LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA )
+            CALL ZLACGV( I-1, A( I, 1 ), LDA )
+            CALL ZLACGV( I-1, X( I, 1 ), LDX )
+            CALL ZGEMV( 'Conjugate transpose', I-1, N-I+1, -ONE,
+     $                  A( 1, I ), LDA, X( I, 1 ), LDX, ONE, A( I, I ),
+     $                  LDA )
+            CALL ZLACGV( I-1, X( I, 1 ), LDX )
+*
+*           Generate reflection P(i) to annihilate A(i,i+1:n)
+*
+            ALPHA = A( I, I )
+            CALL ZLARFG( N-I+1, ALPHA, A( I, MIN( I+1, N ) ), LDA,
+     $                   TAUP( I ) )
+            D( I ) = ALPHA
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+*
+*              Compute X(i+1:m,i)
+*
+               CALL ZGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', N-I+1, I-1, ONE,
+     $                     Y( I, 1 ), LDY, A( I, I ), LDA, ZERO,
+     $                     X( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL ZGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ),
+     $                     LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),
+     $                     LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )
+               CALL ZSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )
+               CALL ZLACGV( N-I+1, A( I, I ), LDA )
+*
+*              Update A(i+1:m,i)
+*
+               CALL ZLACGV( I-1, Y( I, 1 ), LDY )
+               CALL ZGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 )
+               CALL ZLACGV( I-1, Y( I, 1 ), LDY )
+               CALL ZGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ),
+     $                     LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 )
+*
+*              Generate reflection Q(i) to annihilate A(i+2:m,i)
+*
+               ALPHA = A( I+1, I )
+               CALL ZLARFG( M-I, ALPHA, A( MIN( I+2, M ), I ), 1,
+     $                      TAUQ( I ) )
+               E( I ) = ALPHA
+               A( I+1, I ) = ONE
+*
+*              Compute Y(i+1:n,i)
+*
+               CALL ZGEMV( 'Conjugate transpose', M-I, N-I, ONE,
+     $                     A( I+1, I+1 ), LDA, A( I+1, I ), 1, ZERO,
+     $                     Y( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', M-I, I-1, ONE,
+     $                     A( I+1, 1 ), LDA, A( I+1, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),
+     $                     LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', M-I, I, ONE,
+     $                     X( I+1, 1 ), LDX, A( I+1, I ), 1, ZERO,
+     $                     Y( 1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', I, N-I, -ONE,
+     $                     A( 1, I+1 ), LDA, Y( 1, I ), 1, ONE,
+     $                     Y( I+1, I ), 1 )
+               CALL ZSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )
+            ELSE
+               CALL ZLACGV( N-I+1, A( I, I ), LDA )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZLABRD
+*
+      END
diff --git a/libcruft/lapack/zlacgv.f b/libcruft/lapack/zlacgv.f
new file mode 100644
index 0000000..0033e30
--- /dev/null
+++ b/libcruft/lapack/zlacgv.f
@@ -0,0 +1,60 @@
+      SUBROUTINE ZLACGV( N, X, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLACGV conjugates a complex vector of length N.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The length of the vector X.  N >= 0.
+*
+*  X       (input/output) COMPLEX*16 array, dimension
+*                         (1+(N-1)*abs(INCX))
+*          On entry, the vector of length N to be conjugated.
+*          On exit, X is overwritten with conjg(X).
+*
+*  INCX    (input) INTEGER
+*          The spacing between successive elements of X.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IOFF
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( INCX.EQ.1 ) THEN
+         DO 10 I = 1, N
+            X( I ) = DCONJG( X( I ) )
+   10    CONTINUE
+      ELSE
+         IOFF = 1
+         IF( INCX.LT.0 )
+     $      IOFF = 1 - ( N-1 )*INCX
+         DO 20 I = 1, N
+            X( IOFF ) = DCONJG( X( IOFF ) )
+            IOFF = IOFF + INCX
+   20    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZLACGV
+*
+      END
diff --git a/libcruft/lapack/zlacn2.f b/libcruft/lapack/zlacn2.f
new file mode 100644
index 0000000..99f7ae3
--- /dev/null
+++ b/libcruft/lapack/zlacn2.f
@@ -0,0 +1,221 @@
+      SUBROUTINE ZLACN2( N, V, X, EST, KASE, ISAVE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      DOUBLE PRECISION   EST
+*     ..
+*     .. Array Arguments ..
+      INTEGER            ISAVE( 3 )
+      COMPLEX*16         V( * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLACN2 estimates the 1-norm of a square, complex matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) COMPLEX*16 array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) COMPLEX*16 array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         where A' is the conjugate transpose of A, and ZLACN2 must be
+*         re-called with all the other parameters unchanged.
+*
+*  EST    (input/output) DOUBLE PRECISION
+*         On entry with KASE = 1 or 2 and ISAVE(1) = 3, EST should be
+*         unchanged from the previous call to ZLACN2.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to ZLACN2, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from ZLACN2, KASE will again be 0.
+*
+*  ISAVE  (input/output) INTEGER array, dimension (3)
+*         ISAVE is used to save variables between calls to ZLACN2
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named CONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  Last modified:  April, 1999
+*
+*  This is a thread safe version of ZLACON, which uses the array ISAVE
+*  in place of a SAVE statement, as follows:
+*
+*     ZLACON     ZLACN2
+*      JUMP     ISAVE(1)
+*      J        ISAVE(2)
+*      ITER     ISAVE(3)
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER              ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      DOUBLE PRECISION     ONE,         TWO
+      PARAMETER          ( ONE = 1.0D0, TWO = 2.0D0 )
+      COMPLEX*16           CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
+     $                            CONE = ( 1.0D0, 0.0D0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, JLAST
+      DOUBLE PRECISION   ABSXI, ALTSGN, ESTOLD, SAFMIN, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            IZMAX1
+      DOUBLE PRECISION   DLAMCH, DZSUM1
+      EXTERNAL           IZMAX1, DLAMCH, DZSUM1
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DIMAG
+*     ..
+*     .. Executable Statements ..
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = DCMPLX( ONE / DBLE( N ) )
+   10    CONTINUE
+         KASE = 1
+         ISAVE( 1 ) = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 90, 120 )ISAVE( 1 )
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 130
+      END IF
+      EST = DZSUM1( N, X, 1 )
+*
+      DO 30 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = DCMPLX( DBLE( X( I ) ) / ABSXI,
+     $               DIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   30 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 2
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   40 CONTINUE
+      ISAVE( 2 ) = IZMAX1( N, X, 1 )
+      ISAVE( 3 ) = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = CZERO
+   60 CONTINUE
+      X( ISAVE( 2 ) ) = CONE
+      KASE = 1
+      ISAVE( 1 ) = 3
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL ZCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = DZSUM1( N, V, 1 )
+*
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 100
+*
+      DO 80 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = DCMPLX( DBLE( X( I ) ) / ABSXI,
+     $               DIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   80 CONTINUE
+      KASE = 2
+      ISAVE( 1 ) = 4
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 4)
+*     X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   90 CONTINUE
+      JLAST = ISAVE( 2 )
+      ISAVE( 2 ) = IZMAX1( N, X, 1 )
+      IF( ( ABS( X( JLAST ) ).NE.ABS( X( ISAVE( 2 ) ) ) ) .AND.
+     $    ( ISAVE( 3 ).LT.ITMAX ) ) THEN
+         ISAVE( 3 ) = ISAVE( 3 ) + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  100 CONTINUE
+      ALTSGN = ONE
+      DO 110 I = 1, N
+         X( I ) = DCMPLX( ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) ) )
+         ALTSGN = -ALTSGN
+  110 CONTINUE
+      KASE = 1
+      ISAVE( 1 ) = 5
+      RETURN
+*
+*     ................ ENTRY   (ISAVE( 1 ) = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  120 CONTINUE
+      TEMP = TWO*( DZSUM1( N, X, 1 ) / DBLE( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL ZCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  130 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of ZLACN2
+*
+      END
diff --git a/libcruft/lapack/zlacon.f b/libcruft/lapack/zlacon.f
new file mode 100644
index 0000000..5773ef9
--- /dev/null
+++ b/libcruft/lapack/zlacon.f
@@ -0,0 +1,212 @@
+      SUBROUTINE ZLACON( N, V, X, EST, KASE )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KASE, N
+      DOUBLE PRECISION   EST
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         V( N ), X( N )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLACON estimates the 1-norm of a square, complex matrix A.
+*  Reverse communication is used for evaluating matrix-vector products.
+*
+*  Arguments
+*  =========
+*
+*  N      (input) INTEGER
+*         The order of the matrix.  N >= 1.
+*
+*  V      (workspace) COMPLEX*16 array, dimension (N)
+*         On the final return, V = A*W,  where  EST = norm(V)/norm(W)
+*         (W is not returned).
+*
+*  X      (input/output) COMPLEX*16 array, dimension (N)
+*         On an intermediate return, X should be overwritten by
+*               A * X,   if KASE=1,
+*               A' * X,  if KASE=2,
+*         where A' is the conjugate transpose of A, and ZLACON must be
+*         re-called with all the other parameters unchanged.
+*
+*  EST    (input/output) DOUBLE PRECISION
+*         On entry with KASE = 1 or 2 and JUMP = 3, EST should be
+*         unchanged from the previous call to ZLACON.
+*         On exit, EST is an estimate (a lower bound) for norm(A). 
+*
+*  KASE   (input/output) INTEGER
+*         On the initial call to ZLACON, KASE should be 0.
+*         On an intermediate return, KASE will be 1 or 2, indicating
+*         whether X should be overwritten by A * X  or A' * X.
+*         On the final return from ZLACON, KASE will again be 0.
+*
+*  Further Details
+*  ======= =======
+*
+*  Contributed by Nick Higham, University of Manchester.
+*  Originally named CONEST, dated March 16, 1988.
+*
+*  Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of
+*  a real or complex matrix, with applications to condition estimation",
+*  ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.
+*
+*  Last modified:  April, 1999
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 5 )
+      DOUBLE PRECISION   ONE, TWO
+      PARAMETER          ( ONE = 1.0D0, TWO = 2.0D0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
+     $                   CONE = ( 1.0D0, 0.0D0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITER, J, JLAST, JUMP
+      DOUBLE PRECISION   ABSXI, ALTSGN, ESTOLD, SAFMIN, TEMP
+*     ..
+*     .. External Functions ..
+      INTEGER            IZMAX1
+      DOUBLE PRECISION   DLAMCH, DZSUM1
+      EXTERNAL           IZMAX1, DLAMCH, DZSUM1
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZCOPY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DIMAG
+*     ..
+*     .. Save statement ..
+      SAVE
+*     ..
+*     .. Executable Statements ..
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      IF( KASE.EQ.0 ) THEN
+         DO 10 I = 1, N
+            X( I ) = DCMPLX( ONE / DBLE( N ) )
+   10    CONTINUE
+         KASE = 1
+         JUMP = 1
+         RETURN
+      END IF
+*
+      GO TO ( 20, 40, 70, 90, 120 )JUMP
+*
+*     ................ ENTRY   (JUMP = 1)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY A*X.
+*
+   20 CONTINUE
+      IF( N.EQ.1 ) THEN
+         V( 1 ) = X( 1 )
+         EST = ABS( V( 1 ) )
+*        ... QUIT
+         GO TO 130
+      END IF
+      EST = DZSUM1( N, X, 1 )
+*
+      DO 30 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = DCMPLX( DBLE( X( I ) ) / ABSXI,
+     $               DIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   30 CONTINUE
+      KASE = 2
+      JUMP = 2
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 2)
+*     FIRST ITERATION.  X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   40 CONTINUE
+      J = IZMAX1( N, X, 1 )
+      ITER = 2
+*
+*     MAIN LOOP - ITERATIONS 2,3,...,ITMAX.
+*
+   50 CONTINUE
+      DO 60 I = 1, N
+         X( I ) = CZERO
+   60 CONTINUE
+      X( J ) = CONE
+      KASE = 1
+      JUMP = 3
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 3)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+   70 CONTINUE
+      CALL ZCOPY( N, X, 1, V, 1 )
+      ESTOLD = EST
+      EST = DZSUM1( N, V, 1 )
+*
+*     TEST FOR CYCLING.
+      IF( EST.LE.ESTOLD )
+     $   GO TO 100
+*
+      DO 80 I = 1, N
+         ABSXI = ABS( X( I ) )
+         IF( ABSXI.GT.SAFMIN ) THEN
+            X( I ) = DCMPLX( DBLE( X( I ) ) / ABSXI,
+     $               DIMAG( X( I ) ) / ABSXI )
+         ELSE
+            X( I ) = CONE
+         END IF
+   80 CONTINUE
+      KASE = 2
+      JUMP = 4
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 4)
+*     X HAS BEEN OVERWRITTEN BY CTRANS(A)*X.
+*
+   90 CONTINUE
+      JLAST = J
+      J = IZMAX1( N, X, 1 )
+      IF( ( ABS( X( JLAST ) ).NE.ABS( X( J ) ) ) .AND.
+     $    ( ITER.LT.ITMAX ) ) THEN
+         ITER = ITER + 1
+         GO TO 50
+      END IF
+*
+*     ITERATION COMPLETE.  FINAL STAGE.
+*
+  100 CONTINUE
+      ALTSGN = ONE
+      DO 110 I = 1, N
+         X( I ) = DCMPLX( ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) ) )
+         ALTSGN = -ALTSGN
+  110 CONTINUE
+      KASE = 1
+      JUMP = 5
+      RETURN
+*
+*     ................ ENTRY   (JUMP = 5)
+*     X HAS BEEN OVERWRITTEN BY A*X.
+*
+  120 CONTINUE
+      TEMP = TWO*( DZSUM1( N, X, 1 ) / DBLE( 3*N ) )
+      IF( TEMP.GT.EST ) THEN
+         CALL ZCOPY( N, X, 1, V, 1 )
+         EST = TEMP
+      END IF
+*
+  130 CONTINUE
+      KASE = 0
+      RETURN
+*
+*     End of ZLACON
+*
+      END
diff --git a/libcruft/lapack/zlacpy.f b/libcruft/lapack/zlacpy.f
new file mode 100644
index 0000000..8878311
--- /dev/null
+++ b/libcruft/lapack/zlacpy.f
@@ -0,0 +1,90 @@
+      SUBROUTINE ZLACPY( UPLO, M, N, A, LDA, B, LDB )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDB, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLACPY copies all or part of a two-dimensional matrix A to another
+*  matrix B.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be copied to B.
+*          = 'U':      Upper triangular part
+*          = 'L':      Lower triangular part
+*          Otherwise:  All of the matrix A
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The m by n matrix A.  If UPLO = 'U', only the upper trapezium
+*          is accessed; if UPLO = 'L', only the lower trapezium is
+*          accessed.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  B       (output) COMPLEX*16 array, dimension (LDB,N)
+*          On exit, B = A in the locations specified by UPLO.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( J, M )
+               B( I, J ) = A( I, J )
+   10       CONTINUE
+   20    CONTINUE
+*
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+         DO 40 J = 1, N
+            DO 30 I = J, M
+               B( I, J ) = A( I, J )
+   30       CONTINUE
+   40    CONTINUE
+*
+      ELSE
+         DO 60 J = 1, N
+            DO 50 I = 1, M
+               B( I, J ) = A( I, J )
+   50       CONTINUE
+   60    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLACPY
+*
+      END
diff --git a/libcruft/lapack/zladiv.f b/libcruft/lapack/zladiv.f
new file mode 100644
index 0000000..4a12055
--- /dev/null
+++ b/libcruft/lapack/zladiv.f
@@ -0,0 +1,46 @@
+      COMPLEX*16     FUNCTION ZLADIV( X, Y )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16         X, Y
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLADIV := X / Y, where X and Y are complex.  The computation of X / Y
+*  will not overflow on an intermediary step unless the results
+*  overflows.
+*
+*  Arguments
+*  =========
+*
+*  X       (input) COMPLEX*16
+*  Y       (input) COMPLEX*16
+*          The complex scalars X and Y.
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION   ZI, ZR
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLADIV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, DIMAG
+*     ..
+*     .. Executable Statements ..
+*
+      CALL DLADIV( DBLE( X ), DIMAG( X ), DBLE( Y ), DIMAG( Y ), ZR,
+     $             ZI )
+      ZLADIV = DCMPLX( ZR, ZI )
+*
+      RETURN
+*
+*     End of ZLADIV
+*
+      END
diff --git a/libcruft/lapack/zlahqr.f b/libcruft/lapack/zlahqr.f
new file mode 100644
index 0000000..9ce9be1
--- /dev/null
+++ b/libcruft/lapack/zlahqr.f
@@ -0,0 +1,470 @@
+      SUBROUTINE ZLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), W( * ), Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     ZLAHQR is an auxiliary routine called by CHSEQR to update the
+*     eigenvalues and Schur decomposition already computed by CHSEQR, by
+*     dealing with the Hessenberg submatrix in rows and columns ILO to
+*     IHI.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H.  N >= 0.
+*
+*     ILO     (input) INTEGER
+*     IHI     (input) INTEGER
+*          It is assumed that H is already upper triangular in rows and
+*          columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless ILO = 1).
+*          ZLAHQR works primarily with the Hessenberg submatrix in rows
+*          and columns ILO to IHI, but applies transformations to all of
+*          H if WANTT is .TRUE..
+*          1 <= ILO <= max(1,IHI); IHI <= N.
+*
+*     H       (input/output) COMPLEX*16 array, dimension (LDH,N)
+*          On entry, the upper Hessenberg matrix H.
+*          On exit, if INFO is zero and if WANTT is .TRUE., then H
+*          is upper triangular in rows and columns ILO:IHI.  If INFO
+*          is zero and if WANTT is .FALSE., then the contents of H
+*          are unspecified on exit.  The output state of H in case
+*          INF is positive is below under the description of INFO.
+*
+*     LDH     (input) INTEGER
+*          The leading dimension of the array H. LDH >= max(1,N).
+*
+*     W       (output) COMPLEX*16 array, dimension (N)
+*          The computed eigenvalues ILO to IHI are stored in the
+*          corresponding elements of W. If WANTT is .TRUE., the
+*          eigenvalues are stored in the same order as on the diagonal
+*          of the Schur form returned in H, with W(i) = H(i,i).
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE..
+*          1 <= ILOZ <= ILO; IHI <= IHIZ <= N.
+*
+*     Z       (input/output) COMPLEX*16 array, dimension (LDZ,N)
+*          If WANTZ is .TRUE., on entry Z must contain the current
+*          matrix Z of transformations accumulated by CHSEQR, and on
+*          exit Z has been updated; transformations are applied only to
+*          the submatrix Z(ILOZ:IHIZ,ILO:IHI).
+*          If WANTZ is .FALSE., Z is not referenced.
+*
+*     LDZ     (input) INTEGER
+*          The leading dimension of the array Z. LDZ >= max(1,N).
+*
+*     INFO    (output) INTEGER
+*           =   0: successful exit
+*          .GT. 0: if INFO = i, ZLAHQR failed to compute all the
+*                  eigenvalues ILO to IHI in a total of 30 iterations
+*                  per eigenvalue; elements i+1:ihi of W contain
+*                  those eigenvalues which have been successfully
+*                  computed.
+*
+*                  If INFO .GT. 0 and WANTT is .FALSE., then on exit,
+*                  the remaining unconverged eigenvalues are the
+*                  eigenvalues of the upper Hessenberg matrix
+*                  rows and columns ILO thorugh INFO of the final,
+*                  output value of H.
+*
+*                  If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*          (*)       (initial value of H)*U  = U*(final value of H)
+*                  where U is an orthognal matrix.    The final
+*                  value of H is upper Hessenberg and triangular in
+*                  rows and columns INFO+1 through IHI.
+*
+*                  If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*                      (final value of Z)  = (initial value of Z)*U
+*                  where U is the orthogonal matrix in (*)
+*                  (regardless of the value of WANTT.)
+*
+*     Further Details
+*     ===============
+*
+*     02-96 Based on modifications by
+*     David Day, Sandia National Laboratory, USA
+*
+*     12-04 Further modifications by
+*     Ralph Byers, University of Kansas, USA
+*
+*       This is a modified version of ZLAHQR from LAPACK version 3.0.
+*       It is (1) more robust against overflow and underflow and
+*       (2) adopts the more conservative Ahues & Tisseur stopping
+*       criterion (LAWN 122, 1997).
+*
+*     =========================================================
+*
+*     .. Parameters ..
+      INTEGER            ITMAX
+      PARAMETER          ( ITMAX = 30 )
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   RZERO, RONE, HALF
+      PARAMETER          ( RZERO = 0.0d0, RONE = 1.0d0, HALF = 0.5d0 )
+      DOUBLE PRECISION   DAT1
+      PARAMETER          ( DAT1 = 3.0d0 / 4.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         CDUM, H11, H11S, H22, SC, SUM, T, T1, TEMP, U,
+     $                   V2, X, Y
+      DOUBLE PRECISION   AA, AB, BA, BB, H10, H21, RTEMP, S, SAFMAX,
+     $                   SAFMIN, SMLNUM, SX, T2, TST, ULP
+      INTEGER            I, I1, I2, ITS, J, JHI, JLO, K, L, M, NH, NZ
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         V( 2 )
+*     ..
+*     .. External Functions ..
+      COMPLEX*16         ZLADIV
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           ZLADIV, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, ZCOPY, ZLARFG, ZSCAL
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCONJG, DIMAG, MAX, MIN, SQRT
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+      IF( ILO.EQ.IHI ) THEN
+         W( ILO ) = H( ILO, ILO )
+         RETURN
+      END IF
+*
+*     ==== clear out the trash ====
+      DO 10 J = ILO, IHI - 3
+         H( J+2, J ) = ZERO
+         H( J+3, J ) = ZERO
+   10 CONTINUE
+      IF( ILO.LE.IHI-2 )
+     $   H( IHI, IHI-2 ) = ZERO
+*     ==== ensure that subdiagonal entries are real ====
+      DO 20 I = ILO + 1, IHI
+         IF( DIMAG( H( I, I-1 ) ).NE.RZERO ) THEN
+*           ==== The following redundant normalization
+*           .    avoids problems with both gradual and
+*           .    sudden underflow in ABS(H(I,I-1)) ====
+            SC = H( I, I-1 ) / CABS1( H( I, I-1 ) )
+            SC = DCONJG( SC ) / ABS( SC )
+            H( I, I-1 ) = ABS( H( I, I-1 ) )
+            IF( WANTT ) THEN
+               JLO = 1
+               JHI = N
+            ELSE
+               JLO = ILO
+               JHI = IHI
+            END IF
+            CALL ZSCAL( JHI-I+1, SC, H( I, I ), LDH )
+            CALL ZSCAL( MIN( JHI, I+1 )-JLO+1, DCONJG( SC ),
+     $                  H( JLO, I ), 1 )
+            IF( WANTZ )
+     $         CALL ZSCAL( IHIZ-ILOZ+1, DCONJG( SC ), Z( ILOZ, I ), 1 )
+         END IF
+   20 CONTINUE
+*
+      NH = IHI - ILO + 1
+      NZ = IHIZ - ILOZ + 1
+*
+*     Set machine-dependent constants for the stopping criterion.
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( NH ) / ULP )
+*
+*     I1 and I2 are the indices of the first row and last column of H
+*     to which transformations must be applied. If eigenvalues only are
+*     being computed, I1 and I2 are set inside the main loop.
+*
+      IF( WANTT ) THEN
+         I1 = 1
+         I2 = N
+      END IF
+*
+*     The main loop begins here. I is the loop index and decreases from
+*     IHI to ILO in steps of 1. Each iteration of the loop works
+*     with the active submatrix in rows and columns L to I.
+*     Eigenvalues I+1 to IHI have already converged. Either L = ILO, or
+*     H(L,L-1) is negligible so that the matrix splits.
+*
+      I = IHI
+   30 CONTINUE
+      IF( I.LT.ILO )
+     $   GO TO 150
+*
+*     Perform QR iterations on rows and columns ILO to I until a
+*     submatrix of order 1 splits off at the bottom because a
+*     subdiagonal element has become negligible.
+*
+      L = ILO
+      DO 130 ITS = 0, ITMAX
+*
+*        Look for a single small subdiagonal element.
+*
+         DO 40 K = I, L + 1, -1
+            IF( CABS1( H( K, K-1 ) ).LE.SMLNUM )
+     $         GO TO 50
+            TST = CABS1( H( K-1, K-1 ) ) + CABS1( H( K, K ) )
+            IF( TST.EQ.ZERO ) THEN
+               IF( K-2.GE.ILO )
+     $            TST = TST + ABS( DBLE( H( K-1, K-2 ) ) )
+               IF( K+1.LE.IHI )
+     $            TST = TST + ABS( DBLE( H( K+1, K ) ) )
+            END IF
+*           ==== The following is a conservative small subdiagonal
+*           .    deflation criterion due to Ahues & Tisseur (LAWN 122,
+*           .    1997). It has better mathematical foundation and
+*           .    improves accuracy in some examples.  ====
+            IF( ABS( DBLE( H( K, K-1 ) ) ).LE.ULP*TST ) THEN
+               AB = MAX( CABS1( H( K, K-1 ) ), CABS1( H( K-1, K ) ) )
+               BA = MIN( CABS1( H( K, K-1 ) ), CABS1( H( K-1, K ) ) )
+               AA = MAX( CABS1( H( K, K ) ),
+     $              CABS1( H( K-1, K-1 )-H( K, K ) ) )
+               BB = MIN( CABS1( H( K, K ) ),
+     $              CABS1( H( K-1, K-1 )-H( K, K ) ) )
+               S = AA + AB
+               IF( BA*( AB / S ).LE.MAX( SMLNUM,
+     $             ULP*( BB*( AA / S ) ) ) )GO TO 50
+            END IF
+   40    CONTINUE
+   50    CONTINUE
+         L = K
+         IF( L.GT.ILO ) THEN
+*
+*           H(L,L-1) is negligible
+*
+            H( L, L-1 ) = ZERO
+         END IF
+*
+*        Exit from loop if a submatrix of order 1 has split off.
+*
+         IF( L.GE.I )
+     $      GO TO 140
+*
+*        Now the active submatrix is in rows and columns L to I. If
+*        eigenvalues only are being computed, only the active submatrix
+*        need be transformed.
+*
+         IF( .NOT.WANTT ) THEN
+            I1 = L
+            I2 = I
+         END IF
+*
+         IF( ITS.EQ.10 .OR. ITS.EQ.20 ) THEN
+*
+*           Exceptional shift.
+*
+            S = DAT1*ABS( DBLE( H( I, I-1 ) ) )
+            T = S + H( I, I )
+         ELSE
+*
+*           Wilkinson's shift.
+*
+            T = H( I, I )
+            U = SQRT( H( I-1, I ) )*SQRT( H( I, I-1 ) )
+            S = CABS1( U )
+            IF( S.NE.RZERO ) THEN
+               X = HALF*( H( I-1, I-1 )-T )
+               SX = CABS1( X )
+               S = MAX( S, CABS1( X ) )
+               Y = S*SQRT( ( X / S )**2+( U / S )**2 )
+               IF( SX.GT.RZERO ) THEN
+                  IF( DBLE( X / SX )*DBLE( Y )+DIMAG( X / SX )*
+     $                DIMAG( Y ).LT.RZERO )Y = -Y
+               END IF
+               T = T - U*ZLADIV( U, ( X+Y ) )
+            END IF
+         END IF
+*
+*        Look for two consecutive small subdiagonal elements.
+*
+         DO 60 M = I - 1, L + 1, -1
+*
+*           Determine the effect of starting the single-shift QR
+*           iteration at row M, and see if this would make H(M,M-1)
+*           negligible.
+*
+            H11 = H( M, M )
+            H22 = H( M+1, M+1 )
+            H11S = H11 - T
+            H21 = H( M+1, M )
+            S = CABS1( H11S ) + ABS( H21 )
+            H11S = H11S / S
+            H21 = H21 / S
+            V( 1 ) = H11S
+            V( 2 ) = H21
+            H10 = H( M, M-1 )
+            IF( ABS( H10 )*ABS( H21 ).LE.ULP*
+     $          ( CABS1( H11S )*( CABS1( H11 )+CABS1( H22 ) ) ) )
+     $          GO TO 70
+   60    CONTINUE
+         H11 = H( L, L )
+         H22 = H( L+1, L+1 )
+         H11S = H11 - T
+         H21 = H( L+1, L )
+         S = CABS1( H11S ) + ABS( H21 )
+         H11S = H11S / S
+         H21 = H21 / S
+         V( 1 ) = H11S
+         V( 2 ) = H21
+   70    CONTINUE
+*
+*        Single-shift QR step
+*
+         DO 120 K = M, I - 1
+*
+*           The first iteration of this loop determines a reflection G
+*           from the vector V and applies it from left and right to H,
+*           thus creating a nonzero bulge below the subdiagonal.
+*
+*           Each subsequent iteration determines a reflection G to
+*           restore the Hessenberg form in the (K-1)th column, and thus
+*           chases the bulge one step toward the bottom of the active
+*           submatrix.
+*
+*           V(2) is always real before the call to ZLARFG, and hence
+*           after the call T2 ( = T1*V(2) ) is also real.
+*
+            IF( K.GT.M )
+     $         CALL ZCOPY( 2, H( K, K-1 ), 1, V, 1 )
+            CALL ZLARFG( 2, V( 1 ), V( 2 ), 1, T1 )
+            IF( K.GT.M ) THEN
+               H( K, K-1 ) = V( 1 )
+               H( K+1, K-1 ) = ZERO
+            END IF
+            V2 = V( 2 )
+            T2 = DBLE( T1*V2 )
+*
+*           Apply G from the left to transform the rows of the matrix
+*           in columns K to I2.
+*
+            DO 80 J = K, I2
+               SUM = DCONJG( T1 )*H( K, J ) + T2*H( K+1, J )
+               H( K, J ) = H( K, J ) - SUM
+               H( K+1, J ) = H( K+1, J ) - SUM*V2
+   80       CONTINUE
+*
+*           Apply G from the right to transform the columns of the
+*           matrix in rows I1 to min(K+2,I).
+*
+            DO 90 J = I1, MIN( K+2, I )
+               SUM = T1*H( J, K ) + T2*H( J, K+1 )
+               H( J, K ) = H( J, K ) - SUM
+               H( J, K+1 ) = H( J, K+1 ) - SUM*DCONJG( V2 )
+   90       CONTINUE
+*
+            IF( WANTZ ) THEN
+*
+*              Accumulate transformations in the matrix Z
+*
+               DO 100 J = ILOZ, IHIZ
+                  SUM = T1*Z( J, K ) + T2*Z( J, K+1 )
+                  Z( J, K ) = Z( J, K ) - SUM
+                  Z( J, K+1 ) = Z( J, K+1 ) - SUM*DCONJG( V2 )
+  100          CONTINUE
+            END IF
+*
+            IF( K.EQ.M .AND. M.GT.L ) THEN
+*
+*              If the QR step was started at row M > L because two
+*              consecutive small subdiagonals were found, then extra
+*              scaling must be performed to ensure that H(M,M-1) remains
+*              real.
+*
+               TEMP = ONE - T1
+               TEMP = TEMP / ABS( TEMP )
+               H( M+1, M ) = H( M+1, M )*DCONJG( TEMP )
+               IF( M+2.LE.I )
+     $            H( M+2, M+1 ) = H( M+2, M+1 )*TEMP
+               DO 110 J = M, I
+                  IF( J.NE.M+1 ) THEN
+                     IF( I2.GT.J )
+     $                  CALL ZSCAL( I2-J, TEMP, H( J, J+1 ), LDH )
+                     CALL ZSCAL( J-I1, DCONJG( TEMP ), H( I1, J ), 1 )
+                     IF( WANTZ ) THEN
+                        CALL ZSCAL( NZ, DCONJG( TEMP ), Z( ILOZ, J ),
+     $                              1 )
+                     END IF
+                  END IF
+  110          CONTINUE
+            END IF
+  120    CONTINUE
+*
+*        Ensure that H(I,I-1) is real.
+*
+         TEMP = H( I, I-1 )
+         IF( DIMAG( TEMP ).NE.RZERO ) THEN
+            RTEMP = ABS( TEMP )
+            H( I, I-1 ) = RTEMP
+            TEMP = TEMP / RTEMP
+            IF( I2.GT.I )
+     $         CALL ZSCAL( I2-I, DCONJG( TEMP ), H( I, I+1 ), LDH )
+            CALL ZSCAL( I-I1, TEMP, H( I1, I ), 1 )
+            IF( WANTZ ) THEN
+               CALL ZSCAL( NZ, TEMP, Z( ILOZ, I ), 1 )
+            END IF
+         END IF
+*
+  130 CONTINUE
+*
+*     Failure to converge in remaining number of iterations
+*
+      INFO = I
+      RETURN
+*
+  140 CONTINUE
+*
+*     H(I,I-1) is negligible: one eigenvalue has converged.
+*
+      W( I ) = H( I, I )
+*
+*     return to start of the main loop with new value of I.
+*
+      I = L - 1
+      GO TO 30
+*
+  150 CONTINUE
+      RETURN
+*
+*     End of ZLAHQR
+*
+      END
diff --git a/libcruft/lapack/zlahr2.f b/libcruft/lapack/zlahr2.f
new file mode 100644
index 0000000..f3cb551
--- /dev/null
+++ b/libcruft/lapack/zlahr2.f
@@ -0,0 +1,240 @@
+      SUBROUTINE ZLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16        A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAHR2 reduces the first NB columns of A complex general n-BY-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by an unitary similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an auxiliary routine called by ZGEHRD.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*          K < N.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) COMPLEX*16 array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) COMPLEX*16 array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= N.
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( a   a   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  This file is a slight modification of LAPACK-3.0's ZLAHRD
+*  incorporating improvements proposed by Quintana-Orti and Van de
+*  Gejin. Note that the entries of A(1:K,2:NB) differ from those
+*  returned by the original LAPACK routine. This function is
+*  not backward compatible with LAPACK3.0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16        ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ), 
+     $                     ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16        EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZAXPY, ZCOPY, ZGEMM, ZGEMV, ZLACPY,
+     $                   ZLARFG, ZSCAL, ZTRMM, ZTRMV, ZLACGV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(K+1:N,I)
+*
+*           Update I-th column of A - Y * V'
+*
+            CALL ZLACGV( I-1, A( K+I-1, 1 ), LDA ) 
+            CALL ZGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, Y(K+1,1), LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( K+1, I ), 1 )
+            CALL ZLACGV( I-1, A( K+I-1, 1 ), LDA ) 
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL ZCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL ZTRMV( 'Lower', 'Conjugate transpose', 'UNIT', 
+     $                  I-1, A( K+1, 1 ),
+     $                  LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL ZGEMV( 'Conjugate transpose', N-K-I+1, I-1, 
+     $                  ONE, A( K+I, 1 ),
+     $                  LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL ZTRMV( 'Upper', 'Conjugate transpose', 'NON-UNIT', 
+     $                  I-1, T, LDT,
+     $                  T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL ZGEMV( 'NO TRANSPOSE', N-K-I+1, I-1, -ONE, 
+     $                  A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL ZTRMV( 'Lower', 'NO TRANSPOSE', 
+     $                  'UNIT', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL ZAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(I) to annihilate
+*        A(K+I+1:N,I)
+*
+         CALL ZLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         EI = A( K+I, I )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(K+1:N,I)
+*
+         CALL ZGEMV( 'NO TRANSPOSE', N-K, N-K-I+1, 
+     $               ONE, A( K+1, I+1 ),
+     $               LDA, A( K+I, I ), 1, ZERO, Y( K+1, I ), 1 )
+         CALL ZGEMV( 'Conjugate transpose', N-K-I+1, I-1, 
+     $               ONE, A( K+I, 1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, T( 1, I ), 1 )
+         CALL ZGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, 
+     $               Y( K+1, 1 ), LDY,
+     $               T( 1, I ), 1, ONE, Y( K+1, I ), 1 )
+         CALL ZSCAL( N-K, TAU( I ), Y( K+1, I ), 1 )
+*
+*        Compute T(1:I,I)
+*
+         CALL ZSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL ZTRMV( 'Upper', 'No Transpose', 'NON-UNIT', 
+     $               I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+*     Compute Y(1:K,1:NB)
+*
+      CALL ZLACPY( 'ALL', K, NB, A( 1, 2 ), LDA, Y, LDY )
+      CALL ZTRMM( 'RIGHT', 'Lower', 'NO TRANSPOSE', 
+     $            'UNIT', K, NB,
+     $            ONE, A( K+1, 1 ), LDA, Y, LDY )
+      IF( N.GT.K+NB )
+     $   CALL ZGEMM( 'NO TRANSPOSE', 'NO TRANSPOSE', K, 
+     $               NB, N-K-NB, ONE,
+     $               A( 1, 2+NB ), LDA, A( K+1+NB, 1 ), LDA, ONE, Y,
+     $               LDY )
+      CALL ZTRMM( 'RIGHT', 'Upper', 'NO TRANSPOSE', 
+     $            'NON-UNIT', K, NB,
+     $            ONE, T, LDT, Y, LDY )
+*
+      RETURN
+*
+*     End of ZLAHR2
+*
+      END
diff --git a/libcruft/lapack/zlahrd.f b/libcruft/lapack/zlahrd.f
new file mode 100644
index 0000000..e7eb9de
--- /dev/null
+++ b/libcruft/lapack/zlahrd.f
@@ -0,0 +1,213 @@
+      SUBROUTINE ZLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            K, LDA, LDT, LDY, N, NB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), T( LDT, NB ), TAU( NB ),
+     $                   Y( LDY, NB )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAHRD reduces the first NB columns of a complex general n-by-(n-k+1)
+*  matrix A so that elements below the k-th subdiagonal are zero. The
+*  reduction is performed by a unitary similarity transformation
+*  Q' * A * Q. The routine returns the matrices V and T which determine
+*  Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.
+*
+*  This is an OBSOLETE auxiliary routine. 
+*  This routine will be 'deprecated' in a  future release.
+*  Please use the new routine ZLAHR2 instead.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  K       (input) INTEGER
+*          The offset for the reduction. Elements below the k-th
+*          subdiagonal in the first NB columns are reduced to zero.
+*
+*  NB      (input) INTEGER
+*          The number of columns to be reduced.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N-K+1)
+*          On entry, the n-by-(n-k+1) general matrix A.
+*          On exit, the elements on and above the k-th subdiagonal in
+*          the first NB columns are overwritten with the corresponding
+*          elements of the reduced matrix; the elements below the k-th
+*          subdiagonal, with the array TAU, represent the matrix Q as a
+*          product of elementary reflectors. The other columns of A are
+*          unchanged. See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (NB)
+*          The scalar factors of the elementary reflectors. See Further
+*          Details.
+*
+*  T       (output) COMPLEX*16 array, dimension (LDT,NB)
+*          The upper triangular matrix T.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T.  LDT >= NB.
+*
+*  Y       (output) COMPLEX*16 array, dimension (LDY,NB)
+*          The n-by-nb matrix Y.
+*
+*  LDY     (input) INTEGER
+*          The leading dimension of the array Y. LDY >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  The matrix Q is represented as a product of nb elementary reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in
+*  A(i+k+1:n,i), and tau in TAU(i).
+*
+*  The elements of the vectors v together form the (n-k+1)-by-nb matrix
+*  V which is needed, with T and Y, to apply the transformation to the
+*  unreduced part of the matrix, using an update of the form:
+*  A := (I - V*T*V') * (A - Y*V').
+*
+*  The contents of A on exit are illustrated by the following example
+*  with n = 7, k = 3 and nb = 2:
+*
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( a   h   a   a   a )
+*     ( h   h   a   a   a )
+*     ( v1  h   a   a   a )
+*     ( v1  v2  a   a   a )
+*     ( v1  v2  a   a   a )
+*
+*  where a denotes an element of the original matrix A, h denotes a
+*  modified element of the upper Hessenberg matrix H, and vi denotes an
+*  element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16         EI
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZAXPY, ZCOPY, ZGEMV, ZLACGV, ZLARFG, ZSCAL,
+     $                   ZTRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 )
+     $   RETURN
+*
+      DO 10 I = 1, NB
+         IF( I.GT.1 ) THEN
+*
+*           Update A(1:n,i)
+*
+*           Compute i-th column of A - Y * V'
+*
+            CALL ZLACGV( I-1, A( K+I-1, 1 ), LDA )
+            CALL ZGEMV( 'No transpose', N, I-1, -ONE, Y, LDY,
+     $                  A( K+I-1, 1 ), LDA, ONE, A( 1, I ), 1 )
+            CALL ZLACGV( I-1, A( K+I-1, 1 ), LDA )
+*
+*           Apply I - V * T' * V' to this column (call it b) from the
+*           left, using the last column of T as workspace
+*
+*           Let  V = ( V1 )   and   b = ( b1 )   (first I-1 rows)
+*                    ( V2 )             ( b2 )
+*
+*           where V1 is unit lower triangular
+*
+*           w := V1' * b1
+*
+            CALL ZCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )
+            CALL ZTRMV( 'Lower', 'Conjugate transpose', 'Unit', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+*
+*           w := w + V2'*b2
+*
+            CALL ZGEMV( 'Conjugate transpose', N-K-I+1, I-1, ONE,
+     $                  A( K+I, 1 ), LDA, A( K+I, I ), 1, ONE,
+     $                  T( 1, NB ), 1 )
+*
+*           w := T'*w
+*
+            CALL ZTRMV( 'Upper', 'Conjugate transpose', 'Non-unit', I-1,
+     $                  T, LDT, T( 1, NB ), 1 )
+*
+*           b2 := b2 - V2*w
+*
+            CALL ZGEMV( 'No transpose', N-K-I+1, I-1, -ONE, A( K+I, 1 ),
+     $                  LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )
+*
+*           b1 := b1 - V1*w
+*
+            CALL ZTRMV( 'Lower', 'No transpose', 'Unit', I-1,
+     $                  A( K+1, 1 ), LDA, T( 1, NB ), 1 )
+            CALL ZAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )
+*
+            A( K+I-1, I-1 ) = EI
+         END IF
+*
+*        Generate the elementary reflector H(i) to annihilate
+*        A(k+i+1:n,i)
+*
+         EI = A( K+I, I )
+         CALL ZLARFG( N-K-I+1, EI, A( MIN( K+I+1, N ), I ), 1,
+     $                TAU( I ) )
+         A( K+I, I ) = ONE
+*
+*        Compute  Y(1:n,i)
+*
+         CALL ZGEMV( 'No transpose', N, N-K-I+1, ONE, A( 1, I+1 ), LDA,
+     $               A( K+I, I ), 1, ZERO, Y( 1, I ), 1 )
+         CALL ZGEMV( 'Conjugate transpose', N-K-I+1, I-1, ONE,
+     $               A( K+I, 1 ), LDA, A( K+I, I ), 1, ZERO, T( 1, I ),
+     $               1 )
+         CALL ZGEMV( 'No transpose', N, I-1, -ONE, Y, LDY, T( 1, I ), 1,
+     $               ONE, Y( 1, I ), 1 )
+         CALL ZSCAL( N, TAU( I ), Y( 1, I ), 1 )
+*
+*        Compute T(1:i,i)
+*
+         CALL ZSCAL( I-1, -TAU( I ), T( 1, I ), 1 )
+         CALL ZTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, LDT,
+     $               T( 1, I ), 1 )
+         T( I, I ) = TAU( I )
+*
+   10 CONTINUE
+      A( K+NB, NB ) = EI
+*
+      RETURN
+*
+*     End of ZLAHRD
+*
+      END
diff --git a/libcruft/lapack/zlaic1.f b/libcruft/lapack/zlaic1.f
new file mode 100644
index 0000000..589f088
--- /dev/null
+++ b/libcruft/lapack/zlaic1.f
@@ -0,0 +1,295 @@
+      SUBROUTINE ZLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            J, JOB
+      DOUBLE PRECISION   SEST, SESTPR
+      COMPLEX*16         C, GAMMA, S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         W( J ), X( J )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAIC1 applies one step of incremental condition estimation in
+*  its simplest version:
+*
+*  Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
+*  lower triangular matrix L, such that
+*           twonorm(L*x) = sest
+*  Then ZLAIC1 computes sestpr, s, c such that
+*  the vector
+*                  [ s*x ]
+*           xhat = [  c  ]
+*  is an approximate singular vector of
+*                  [ L     0  ]
+*           Lhat = [ w' gamma ]
+*  in the sense that
+*           twonorm(Lhat*xhat) = sestpr.
+*
+*  Depending on JOB, an estimate for the largest or smallest singular
+*  value is computed.
+*
+*  Note that [s c]' and sestpr**2 is an eigenpair of the system
+*
+*      diag(sest*sest, 0) + [alpha  gamma] * [ conjg(alpha) ]
+*                                            [ conjg(gamma) ]
+*
+*  where  alpha =  conjg(x)'*w.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) INTEGER
+*          = 1: an estimate for the largest singular value is computed.
+*          = 2: an estimate for the smallest singular value is computed.
+*
+*  J       (input) INTEGER
+*          Length of X and W
+*
+*  X       (input) COMPLEX*16 array, dimension (J)
+*          The j-vector x.
+*
+*  SEST    (input) DOUBLE PRECISION
+*          Estimated singular value of j by j matrix L
+*
+*  W       (input) COMPLEX*16 array, dimension (J)
+*          The j-vector w.
+*
+*  GAMMA   (input) COMPLEX*16
+*          The diagonal element gamma.
+*
+*  SESTPR  (output) DOUBLE PRECISION
+*          Estimated singular value of (j+1) by (j+1) matrix Lhat.
+*
+*  S       (output) COMPLEX*16
+*          Sine needed in forming xhat.
+*
+*  C       (output) COMPLEX*16
+*          Cosine needed in forming xhat.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
+      DOUBLE PRECISION   HALF, FOUR
+      PARAMETER          ( HALF = 0.5D0, FOUR = 4.0D0 )
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION   ABSALP, ABSEST, ABSGAM, B, EPS, NORMA, S1, S2,
+     $                   SCL, T, TEST, TMP, ZETA1, ZETA2
+      COMPLEX*16         ALPHA, COSINE, SINE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DCONJG, MAX, SQRT
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      COMPLEX*16         ZDOTC
+      EXTERNAL           DLAMCH, ZDOTC
+*     ..
+*     .. Executable Statements ..
+*
+      EPS = DLAMCH( 'Epsilon' )
+      ALPHA = ZDOTC( J, X, 1, W, 1 )
+*
+      ABSALP = ABS( ALPHA )
+      ABSGAM = ABS( GAMMA )
+      ABSEST = ABS( SEST )
+*
+      IF( JOB.EQ.1 ) THEN
+*
+*        Estimating largest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            S1 = MAX( ABSGAM, ABSALP )
+            IF( S1.EQ.ZERO ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = ZERO
+            ELSE
+               S = ALPHA / S1
+               C = GAMMA / S1
+               TMP = SQRT( S*DCONJG( S )+C*DCONJG( C ) )
+               S = S / TMP
+               C = C / TMP
+               SESTPR = S1*TMP
+            END IF
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ONE
+            C = ZERO
+            TMP = MAX( ABSEST, ABSALP )
+            S1 = ABSEST / TMP
+            S2 = ABSALP / TMP
+            SESTPR = TMP*SQRT( S1*S1+S2*S2 )
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            ELSE
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = S2*SCL
+               S = ( ALPHA / S2 ) / SCL
+               C = ( GAMMA / S2 ) / SCL
+            ELSE
+               TMP = S2 / S1
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = S1*SCL
+               S = ( ALPHA / S1 ) / SCL
+               C = ( GAMMA / S1 ) / SCL
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ABSALP / ABSEST
+            ZETA2 = ABSGAM / ABSEST
+*
+            B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
+            C = ZETA1*ZETA1
+            IF( B.GT.ZERO ) THEN
+               T = C / ( B+SQRT( B*B+C ) )
+            ELSE
+               T = SQRT( B*B+C ) - B
+            END IF
+*
+            SINE = -( ALPHA / ABSEST ) / T
+            COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
+            TMP = SQRT( SINE*DCONJG( SINE )+COSINE*DCONJG( COSINE ) )
+            S = SINE / TMP
+            C = COSINE / TMP
+            SESTPR = SQRT( T+ONE )*ABSEST
+            RETURN
+         END IF
+*
+      ELSE IF( JOB.EQ.2 ) THEN
+*
+*        Estimating smallest singular value
+*
+*        special cases
+*
+         IF( SEST.EQ.ZERO ) THEN
+            SESTPR = ZERO
+            IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
+               SINE = ONE
+               COSINE = ZERO
+            ELSE
+               SINE = -DCONJG( GAMMA )
+               COSINE = DCONJG( ALPHA )
+            END IF
+            S1 = MAX( ABS( SINE ), ABS( COSINE ) )
+            S = SINE / S1
+            C = COSINE / S1
+            TMP = SQRT( S*DCONJG( S )+C*DCONJG( C ) )
+            S = S / TMP
+            C = C / TMP
+            RETURN
+         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
+            S = ZERO
+            C = ONE
+            SESTPR = ABSGAM
+            RETURN
+         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
+            S1 = ABSGAM
+            S2 = ABSEST
+            IF( S1.LE.S2 ) THEN
+               S = ZERO
+               C = ONE
+               SESTPR = S1
+            ELSE
+               S = ONE
+               C = ZERO
+               SESTPR = S2
+            END IF
+            RETURN
+         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
+            S1 = ABSGAM
+            S2 = ABSALP
+            IF( S1.LE.S2 ) THEN
+               TMP = S1 / S2
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST*( TMP / SCL )
+               S = -( DCONJG( GAMMA ) / S2 ) / SCL
+               C = ( DCONJG( ALPHA ) / S2 ) / SCL
+            ELSE
+               TMP = S2 / S1
+               SCL = SQRT( ONE+TMP*TMP )
+               SESTPR = ABSEST / SCL
+               S = -( DCONJG( GAMMA ) / S1 ) / SCL
+               C = ( DCONJG( ALPHA ) / S1 ) / SCL
+            END IF
+            RETURN
+         ELSE
+*
+*           normal case
+*
+            ZETA1 = ABSALP / ABSEST
+            ZETA2 = ABSGAM / ABSEST
+*
+            NORMA = MAX( ONE+ZETA1*ZETA1+ZETA1*ZETA2,
+     $              ZETA1*ZETA2+ZETA2*ZETA2 )
+*
+*           See if root is closer to zero or to ONE
+*
+            TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
+            IF( TEST.GE.ZERO ) THEN
+*
+*              root is close to zero, compute directly
+*
+               B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
+               C = ZETA2*ZETA2
+               T = C / ( B+SQRT( ABS( B*B-C ) ) )
+               SINE = ( ALPHA / ABSEST ) / ( ONE-T )
+               COSINE = -( GAMMA / ABSEST ) / T
+               SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
+            ELSE
+*
+*              root is closer to ONE, shift by that amount
+*
+               B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
+               C = ZETA1*ZETA1
+               IF( B.GE.ZERO ) THEN
+                  T = -C / ( B+SQRT( B*B+C ) )
+               ELSE
+                  T = B - SQRT( B*B+C )
+               END IF
+               SINE = -( ALPHA / ABSEST ) / T
+               COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
+               SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
+            END IF
+            TMP = SQRT( SINE*DCONJG( SINE )+COSINE*DCONJG( COSINE ) )
+            S = SINE / TMP
+            C = COSINE / TMP
+            RETURN
+*
+         END IF
+      END IF
+      RETURN
+*
+*     End of ZLAIC1
+*
+      END
diff --git a/libcruft/lapack/zlals0.f b/libcruft/lapack/zlals0.f
new file mode 100644
index 0000000..9d41961
--- /dev/null
+++ b/libcruft/lapack/zlals0.f
@@ -0,0 +1,433 @@
+      SUBROUTINE ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
+     $                   PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
+     $                   POLES, DIFL, DIFR, Z, K, C, S, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
+     $                   LDGNUM, NL, NR, NRHS, SQRE
+      DOUBLE PRECISION   C, S
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), PERM( * )
+      DOUBLE PRECISION   DIFL( * ), DIFR( LDGNUM, * ),
+     $                   GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
+     $                   RWORK( * ), Z( * )
+      COMPLEX*16         B( LDB, * ), BX( LDBX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLALS0 applies back the multiplying factors of either the left or the
+*  right singular vector matrix of a diagonal matrix appended by a row
+*  to the right hand side matrix B in solving the least squares problem
+*  using the divide-and-conquer SVD approach.
+*
+*  For the left singular vector matrix, three types of orthogonal
+*  matrices are involved:
+*
+*  (1L) Givens rotations: the number of such rotations is GIVPTR; the
+*       pairs of columns/rows they were applied to are stored in GIVCOL;
+*       and the C- and S-values of these rotations are stored in GIVNUM.
+*
+*  (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
+*       row, and for J=2:N, PERM(J)-th row of B is to be moved to the
+*       J-th row.
+*
+*  (3L) The left singular vector matrix of the remaining matrix.
+*
+*  For the right singular vector matrix, four types of orthogonal
+*  matrices are involved:
+*
+*  (1R) The right singular vector matrix of the remaining matrix.
+*
+*  (2R) If SQRE = 1, one extra Givens rotation to generate the right
+*       null space.
+*
+*  (3R) The inverse transformation of (2L).
+*
+*  (4R) The inverse transformation of (1L).
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether singular vectors are to be computed in
+*         factored form:
+*         = 0: Left singular vector matrix.
+*         = 1: Right singular vector matrix.
+*
+*  NL     (input) INTEGER
+*         The row dimension of the upper block. NL >= 1.
+*
+*  NR     (input) INTEGER
+*         The row dimension of the lower block. NR >= 1.
+*
+*  SQRE   (input) INTEGER
+*         = 0: the lower block is an NR-by-NR square matrix.
+*         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
+*
+*         The bidiagonal matrix has row dimension N = NL + NR + 1,
+*         and column dimension M = N + SQRE.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) COMPLEX*16 array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M. On output, B contains
+*         the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B. LDB must be at least
+*         max(1,MAX( M, N ) ).
+*
+*  BX     (workspace) COMPLEX*16 array, dimension ( LDBX, NRHS )
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  PERM   (input) INTEGER array, dimension ( N )
+*         The permutations (from deflation and sorting) applied
+*         to the two blocks.
+*
+*  GIVPTR (input) INTEGER
+*         The number of Givens rotations which took place in this
+*         subproblem.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )
+*         Each pair of numbers indicates a pair of rows/columns
+*         involved in a Givens rotation.
+*
+*  LDGCOL (input) INTEGER
+*         The leading dimension of GIVCOL, must be at least N.
+*
+*  GIVNUM (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         Each number indicates the C or S value used in the
+*         corresponding Givens rotation.
+*
+*  LDGNUM (input) INTEGER
+*         The leading dimension of arrays DIFR, POLES and
+*         GIVNUM, must be at least K.
+*
+*  POLES  (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
+*         On entry, POLES(1:K, 1) contains the new singular
+*         values obtained from solving the secular equation, and
+*         POLES(1:K, 2) is an array containing the poles in the secular
+*         equation.
+*
+*  DIFL   (input) DOUBLE PRECISION array, dimension ( K ).
+*         On entry, DIFL(I) is the distance between I-th updated
+*         (undeflated) singular value and the I-th (undeflated) old
+*         singular value.
+*
+*  DIFR   (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ).
+*         On entry, DIFR(I, 1) contains the distances between I-th
+*         updated (undeflated) singular value and the I+1-th
+*         (undeflated) old singular value. And DIFR(I, 2) is the
+*         normalizing factor for the I-th right singular vector.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( K )
+*         Contain the components of the deflation-adjusted updating row
+*         vector.
+*
+*  K      (input) INTEGER
+*         Contains the dimension of the non-deflated matrix,
+*         This is the order of the related secular equation. 1 <= K <=N.
+*
+*  C      (input) DOUBLE PRECISION
+*         C contains garbage if SQRE =0 and the C-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  S      (input) DOUBLE PRECISION
+*         S contains garbage if SQRE =0 and the S-value of a Givens
+*         rotation related to the right null space if SQRE = 1.
+*
+*  RWORK  (workspace) DOUBLE PRECISION array, dimension
+*         ( K*(1+NRHS) + 2*NRHS )
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO, NEGONE
+      PARAMETER          ( ONE = 1.0D0, ZERO = 0.0D0, NEGONE = -1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, JCOL, JROW, M, N, NLP1
+      DOUBLE PRECISION   DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMV, XERBLA, ZCOPY, ZDROT, ZDSCAL, ZLACPY,
+     $                   ZLASCL
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMC3, DNRM2
+      EXTERNAL           DLAMC3, DNRM2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, DIMAG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( NL.LT.1 ) THEN
+         INFO = -2
+      ELSE IF( NR.LT.1 ) THEN
+         INFO = -3
+      ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
+         INFO = -4
+      END IF
+*
+      N = NL + NR + 1
+*
+      IF( NRHS.LT.1 ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -7
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -9
+      ELSE IF( GIVPTR.LT.0 ) THEN
+         INFO = -11
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -13
+      ELSE IF( LDGNUM.LT.N ) THEN
+         INFO = -15
+      ELSE IF( K.LT.1 ) THEN
+         INFO = -20
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLALS0', -INFO )
+         RETURN
+      END IF
+*
+      M = N + SQRE
+      NLP1 = NL + 1
+*
+      IF( ICOMPQ.EQ.0 ) THEN
+*
+*        Apply back orthogonal transformations from the left.
+*
+*        Step (1L): apply back the Givens rotations performed.
+*
+         DO 10 I = 1, GIVPTR
+            CALL ZDROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                  GIVNUM( I, 1 ) )
+   10    CONTINUE
+*
+*        Step (2L): permute rows of B.
+*
+         CALL ZCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
+         DO 20 I = 2, N
+            CALL ZCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
+   20    CONTINUE
+*
+*        Step (3L): apply the inverse of the left singular vector
+*        matrix to BX.
+*
+         IF( K.EQ.1 ) THEN
+            CALL ZCOPY( NRHS, BX, LDBX, B, LDB )
+            IF( Z( 1 ).LT.ZERO ) THEN
+               CALL ZDSCAL( NRHS, NEGONE, B, LDB )
+            END IF
+         ELSE
+            DO 100 J = 1, K
+               DIFLJ = DIFL( J )
+               DJ = POLES( J, 1 )
+               DSIGJ = -POLES( J, 2 )
+               IF( J.LT.K ) THEN
+                  DIFRJ = -DIFR( J, 1 )
+                  DSIGJP = -POLES( J+1, 2 )
+               END IF
+               IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
+     $              THEN
+                  RWORK( J ) = ZERO
+               ELSE
+                  RWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
+     $                         ( POLES( J, 2 )+DJ )
+               END IF
+               DO 30 I = 1, J - 1
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                            ( DLAMC3( POLES( I, 2 ), DSIGJ )-
+     $                            DIFLJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   30          CONTINUE
+               DO 40 I = J + 1, K
+                  IF( ( Z( I ).EQ.ZERO ) .OR.
+     $                ( POLES( I, 2 ).EQ.ZERO ) ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = POLES( I, 2 )*Z( I ) /
+     $                            ( DLAMC3( POLES( I, 2 ), DSIGJP )+
+     $                            DIFRJ ) / ( POLES( I, 2 )+DJ )
+                  END IF
+   40          CONTINUE
+               RWORK( 1 ) = NEGONE
+               TEMP = DNRM2( K, RWORK, 1 )
+*
+*              Since B and BX are complex, the following call to DGEMV
+*              is performed in two steps (real and imaginary parts).
+*
+*              CALL DGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
+*    $                     B( J, 1 ), LDB )
+*
+               I = K + NRHS*2
+               DO 60 JCOL = 1, NRHS
+                  DO 50 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = DBLE( BX( JROW, JCOL ) )
+   50             CONTINUE
+   60          CONTINUE
+               CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
+               I = K + NRHS*2
+               DO 80 JCOL = 1, NRHS
+                  DO 70 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = DIMAG( BX( JROW, JCOL ) )
+   70             CONTINUE
+   80          CONTINUE
+               CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
+               DO 90 JCOL = 1, NRHS
+                  B( J, JCOL ) = DCMPLX( RWORK( JCOL+K ),
+     $                           RWORK( JCOL+K+NRHS ) )
+   90          CONTINUE
+               CALL ZLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
+     $                      LDB, INFO )
+  100       CONTINUE
+         END IF
+*
+*        Move the deflated rows of BX to B also.
+*
+         IF( K.LT.MAX( M, N ) )
+     $      CALL ZLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
+     $                   B( K+1, 1 ), LDB )
+      ELSE
+*
+*        Apply back the right orthogonal transformations.
+*
+*        Step (1R): apply back the new right singular vector matrix
+*        to B.
+*
+         IF( K.EQ.1 ) THEN
+            CALL ZCOPY( NRHS, B, LDB, BX, LDBX )
+         ELSE
+            DO 180 J = 1, K
+               DSIGJ = POLES( J, 2 )
+               IF( Z( J ).EQ.ZERO ) THEN
+                  RWORK( J ) = ZERO
+               ELSE
+                  RWORK( J ) = -Z( J ) / DIFL( J ) /
+     $                         ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
+               END IF
+               DO 110 I = 1, J - 1
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I+1,
+     $                            2 ) )-DIFR( I, 1 ) ) /
+     $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+  110          CONTINUE
+               DO 120 I = J + 1, K
+                  IF( Z( J ).EQ.ZERO ) THEN
+                     RWORK( I ) = ZERO
+                  ELSE
+                     RWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I,
+     $                            2 ) )-DIFL( I ) ) /
+     $                            ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
+                  END IF
+  120          CONTINUE
+*
+*              Since B and BX are complex, the following call to DGEMV
+*              is performed in two steps (real and imaginary parts).
+*
+*              CALL DGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
+*    $                     BX( J, 1 ), LDBX )
+*
+               I = K + NRHS*2
+               DO 140 JCOL = 1, NRHS
+                  DO 130 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = DBLE( B( JROW, JCOL ) )
+  130             CONTINUE
+  140          CONTINUE
+               CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
+               I = K + NRHS*2
+               DO 160 JCOL = 1, NRHS
+                  DO 150 JROW = 1, K
+                     I = I + 1
+                     RWORK( I ) = DIMAG( B( JROW, JCOL ) )
+  150             CONTINUE
+  160          CONTINUE
+               CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
+     $                     RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
+               DO 170 JCOL = 1, NRHS
+                  BX( J, JCOL ) = DCMPLX( RWORK( JCOL+K ),
+     $                            RWORK( JCOL+K+NRHS ) )
+  170          CONTINUE
+  180       CONTINUE
+         END IF
+*
+*        Step (2R): if SQRE = 1, apply back the rotation that is
+*        related to the right null space of the subproblem.
+*
+         IF( SQRE.EQ.1 ) THEN
+            CALL ZCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
+            CALL ZDROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
+         END IF
+         IF( K.LT.MAX( M, N ) )
+     $      CALL ZLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),
+     $                   LDBX )
+*
+*        Step (3R): permute rows of B.
+*
+         CALL ZCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
+         IF( SQRE.EQ.1 ) THEN
+            CALL ZCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
+         END IF
+         DO 190 I = 2, N
+            CALL ZCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
+  190    CONTINUE
+*
+*        Step (4R): apply back the Givens rotations performed.
+*
+         DO 200 I = GIVPTR, 1, -1
+            CALL ZDROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
+     $                  B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
+     $                  -GIVNUM( I, 1 ) )
+  200    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLALS0
+*
+      END
diff --git a/libcruft/lapack/zlalsa.f b/libcruft/lapack/zlalsa.f
new file mode 100644
index 0000000..a1516bc
--- /dev/null
+++ b/libcruft/lapack/zlalsa.f
@@ -0,0 +1,503 @@
+      SUBROUTINE ZLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,
+     $                   LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,
+     $                   GIVCOL, LDGCOL, PERM, GIVNUM, C, S, RWORK,
+     $                   IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,
+     $                   SMLSIZ
+*     ..
+*     .. Array Arguments ..
+      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
+     $                   K( * ), PERM( LDGCOL, * )
+      DOUBLE PRECISION   C( * ), DIFL( LDU, * ), DIFR( LDU, * ),
+     $                   GIVNUM( LDU, * ), POLES( LDU, * ), RWORK( * ),
+     $                   S( * ), U( LDU, * ), VT( LDU, * ), Z( LDU, * )
+      COMPLEX*16         B( LDB, * ), BX( LDBX, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLALSA is an itermediate step in solving the least squares problem
+*  by computing the SVD of the coefficient matrix in compact form (The
+*  singular vectors are computed as products of simple orthorgonal
+*  matrices.).
+*
+*  If ICOMPQ = 0, ZLALSA applies the inverse of the left singular vector
+*  matrix of an upper bidiagonal matrix to the right hand side; and if
+*  ICOMPQ = 1, ZLALSA applies the right singular vector matrix to the
+*  right hand side. The singular vector matrices were generated in
+*  compact form by ZLALSA.
+*
+*  Arguments
+*  =========
+*
+*  ICOMPQ (input) INTEGER
+*         Specifies whether the left or the right singular vector
+*         matrix is involved.
+*         = 0: Left singular vector matrix
+*         = 1: Right singular vector matrix
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The row and column dimensions of the upper bidiagonal matrix.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B and BX. NRHS must be at least 1.
+*
+*  B      (input/output) COMPLEX*16 array, dimension ( LDB, NRHS )
+*         On input, B contains the right hand sides of the least
+*         squares problem in rows 1 through M.
+*         On output, B contains the solution X in rows 1 through N.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,MAX( M, N ) ).
+*
+*  BX     (output) COMPLEX*16 array, dimension ( LDBX, NRHS )
+*         On exit, the result of applying the left or right singular
+*         vector matrix to B.
+*
+*  LDBX   (input) INTEGER
+*         The leading dimension of BX.
+*
+*  U      (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ ).
+*         On entry, U contains the left singular vector matrices of all
+*         subproblems at the bottom level.
+*
+*  LDU    (input) INTEGER, LDU = > N.
+*         The leading dimension of arrays U, VT, DIFL, DIFR,
+*         POLES, GIVNUM, and Z.
+*
+*  VT     (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ+1 ).
+*         On entry, VT' contains the right singular vector matrices of
+*         all subproblems at the bottom level.
+*
+*  K      (input) INTEGER array, dimension ( N ).
+*
+*  DIFL   (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ).
+*         where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.
+*
+*  DIFR   (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).
+*         On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record
+*         distances between singular values on the I-th level and
+*         singular values on the (I -1)-th level, and DIFR(*, 2 * I)
+*         record the normalizing factors of the right singular vectors
+*         matrices of subproblems on I-th level.
+*
+*  Z      (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ).
+*         On entry, Z(1, I) contains the components of the deflation-
+*         adjusted updating row vector for subproblems on the I-th
+*         level.
+*
+*  POLES  (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).
+*         On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old
+*         singular values involved in the secular equations on the I-th
+*         level.
+*
+*  GIVPTR (input) INTEGER array, dimension ( N ).
+*         On entry, GIVPTR( I ) records the number of Givens
+*         rotations performed on the I-th problem on the computation
+*         tree.
+*
+*  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ).
+*         On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the
+*         locations of Givens rotations performed on the I-th level on
+*         the computation tree.
+*
+*  LDGCOL (input) INTEGER, LDGCOL = > N.
+*         The leading dimension of arrays GIVCOL and PERM.
+*
+*  PERM   (input) INTEGER array, dimension ( LDGCOL, NLVL ).
+*         On entry, PERM(*, I) records permutations done on the I-th
+*         level of the computation tree.
+*
+*  GIVNUM (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).
+*         On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-
+*         values of Givens rotations performed on the I-th level on the
+*         computation tree.
+*
+*  C      (input) DOUBLE PRECISION array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         C( I ) contains the C-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  S      (input) DOUBLE PRECISION array, dimension ( N ).
+*         On entry, if the I-th subproblem is not square,
+*         S( I ) contains the S-value of a Givens rotation related to
+*         the right null space of the I-th subproblem.
+*
+*  RWORK  (workspace) DOUBLE PRECISION array, dimension at least
+*         max ( N, (SMLSZ+1)*NRHS*3 ).
+*
+*  IWORK  (workspace) INTEGER array.
+*         The dimension must be at least 3 * N
+*
+*  INFO   (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I1, IC, IM1, INODE, J, JCOL, JIMAG, JREAL,
+     $                   JROW, LF, LL, LVL, LVL2, ND, NDB1, NDIML,
+     $                   NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQRE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DLASDT, XERBLA, ZCOPY, ZLALS0
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, DIMAG
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
+         INFO = -1
+      ELSE IF( SMLSIZ.LT.3 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.SMLSIZ ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( LDB.LT.N ) THEN
+         INFO = -6
+      ELSE IF( LDBX.LT.N ) THEN
+         INFO = -8
+      ELSE IF( LDU.LT.N ) THEN
+         INFO = -10
+      ELSE IF( LDGCOL.LT.N ) THEN
+         INFO = -19
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLALSA', -INFO )
+         RETURN
+      END IF
+*
+*     Book-keeping and  setting up the computation tree.
+*
+      INODE = 1
+      NDIML = INODE + N
+      NDIMR = NDIML + N
+*
+      CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
+     $             IWORK( NDIMR ), SMLSIZ )
+*
+*     The following code applies back the left singular vector factors.
+*     For applying back the right singular vector factors, go to 170.
+*
+      IF( ICOMPQ.EQ.1 ) THEN
+         GO TO 170
+      END IF
+*
+*     The nodes on the bottom level of the tree were solved
+*     by DLASDQ. The corresponding left and right singular vector
+*     matrices are in explicit form. First apply back the left
+*     singular vector matrices.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 130 I = NDB1, ND
+*
+*        IC : center row of each node
+*        NL : number of rows of left  subproblem
+*        NR : number of rows of right subproblem
+*        NLF: starting row of the left   subproblem
+*        NRF: starting row of the right  subproblem
+*
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLF = IC - NL
+         NRF = IC + 1
+*
+*        Since B and BX are complex, the following call to DGEMM
+*        is performed in two steps (real and imaginary parts).
+*
+*        CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+*     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+*
+         J = NL*NRHS*2
+         DO 20 JCOL = 1, NRHS
+            DO 10 JROW = NLF, NLF + NL - 1
+               J = J + 1
+               RWORK( J ) = DBLE( B( JROW, JCOL ) )
+   10       CONTINUE
+   20    CONTINUE
+         CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+     $               RWORK( 1+NL*NRHS*2 ), NL, ZERO, RWORK( 1 ), NL )
+         J = NL*NRHS*2
+         DO 40 JCOL = 1, NRHS
+            DO 30 JROW = NLF, NLF + NL - 1
+               J = J + 1
+               RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+   30       CONTINUE
+   40    CONTINUE
+         CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,
+     $               RWORK( 1+NL*NRHS*2 ), NL, ZERO, RWORK( 1+NL*NRHS ),
+     $               NL )
+         JREAL = 0
+         JIMAG = NL*NRHS
+         DO 60 JCOL = 1, NRHS
+            DO 50 JROW = NLF, NLF + NL - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+   50       CONTINUE
+   60    CONTINUE
+*
+*        Since B and BX are complex, the following call to DGEMM
+*        is performed in two steps (real and imaginary parts).
+*
+*        CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+*    $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+*
+         J = NR*NRHS*2
+         DO 80 JCOL = 1, NRHS
+            DO 70 JROW = NRF, NRF + NR - 1
+               J = J + 1
+               RWORK( J ) = DBLE( B( JROW, JCOL ) )
+   70       CONTINUE
+   80    CONTINUE
+         CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+     $               RWORK( 1+NR*NRHS*2 ), NR, ZERO, RWORK( 1 ), NR )
+         J = NR*NRHS*2
+         DO 100 JCOL = 1, NRHS
+            DO 90 JROW = NRF, NRF + NR - 1
+               J = J + 1
+               RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+   90       CONTINUE
+  100    CONTINUE
+         CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,
+     $               RWORK( 1+NR*NRHS*2 ), NR, ZERO, RWORK( 1+NR*NRHS ),
+     $               NR )
+         JREAL = 0
+         JIMAG = NR*NRHS
+         DO 120 JCOL = 1, NRHS
+            DO 110 JROW = NRF, NRF + NR - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+  110       CONTINUE
+  120    CONTINUE
+*
+  130 CONTINUE
+*
+*     Next copy the rows of B that correspond to unchanged rows
+*     in the bidiagonal matrix to BX.
+*
+      DO 140 I = 1, ND
+         IC = IWORK( INODE+I-1 )
+         CALL ZCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )
+  140 CONTINUE
+*
+*     Finally go through the left singular vector matrices of all
+*     the other subproblems bottom-up on the tree.
+*
+      J = 2**NLVL
+      SQRE = 0
+*
+      DO 160 LVL = NLVL, 1, -1
+         LVL2 = 2*LVL - 1
+*
+*        find the first node LF and last node LL on
+*        the current level LVL
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 150 I = LF, LL
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            J = J - 1
+            CALL ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,
+     $                   B( NLF, 1 ), LDB, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), RWORK,
+     $                   INFO )
+  150    CONTINUE
+  160 CONTINUE
+      GO TO 330
+*
+*     ICOMPQ = 1: applying back the right singular vector factors.
+*
+  170 CONTINUE
+*
+*     First now go through the right singular vector matrices of all
+*     the tree nodes top-down.
+*
+      J = 0
+      DO 190 LVL = 1, NLVL
+         LVL2 = 2*LVL - 1
+*
+*        Find the first node LF and last node LL on
+*        the current level LVL.
+*
+         IF( LVL.EQ.1 ) THEN
+            LF = 1
+            LL = 1
+         ELSE
+            LF = 2**( LVL-1 )
+            LL = 2*LF - 1
+         END IF
+         DO 180 I = LL, LF, -1
+            IM1 = I - 1
+            IC = IWORK( INODE+IM1 )
+            NL = IWORK( NDIML+IM1 )
+            NR = IWORK( NDIMR+IM1 )
+            NLF = IC - NL
+            NRF = IC + 1
+            IF( I.EQ.LL ) THEN
+               SQRE = 0
+            ELSE
+               SQRE = 1
+            END IF
+            J = J + 1
+            CALL ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,
+     $                   BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),
+     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,
+     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),
+     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),
+     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), RWORK,
+     $                   INFO )
+  180    CONTINUE
+  190 CONTINUE
+*
+*     The nodes on the bottom level of the tree were solved
+*     by DLASDQ. The corresponding right singular vector
+*     matrices are in explicit form. Apply them back.
+*
+      NDB1 = ( ND+1 ) / 2
+      DO 320 I = NDB1, ND
+         I1 = I - 1
+         IC = IWORK( INODE+I1 )
+         NL = IWORK( NDIML+I1 )
+         NR = IWORK( NDIMR+I1 )
+         NLP1 = NL + 1
+         IF( I.EQ.ND ) THEN
+            NRP1 = NR
+         ELSE
+            NRP1 = NR + 1
+         END IF
+         NLF = IC - NL
+         NRF = IC + 1
+*
+*        Since B and BX are complex, the following call to DGEMM is
+*        performed in two steps (real and imaginary parts).
+*
+*        CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+*    $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )
+*
+         J = NLP1*NRHS*2
+         DO 210 JCOL = 1, NRHS
+            DO 200 JROW = NLF, NLF + NLP1 - 1
+               J = J + 1
+               RWORK( J ) = DBLE( B( JROW, JCOL ) )
+  200       CONTINUE
+  210    CONTINUE
+         CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+     $               RWORK( 1+NLP1*NRHS*2 ), NLP1, ZERO, RWORK( 1 ),
+     $               NLP1 )
+         J = NLP1*NRHS*2
+         DO 230 JCOL = 1, NRHS
+            DO 220 JROW = NLF, NLF + NLP1 - 1
+               J = J + 1
+               RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+  220       CONTINUE
+  230    CONTINUE
+         CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,
+     $               RWORK( 1+NLP1*NRHS*2 ), NLP1, ZERO,
+     $               RWORK( 1+NLP1*NRHS ), NLP1 )
+         JREAL = 0
+         JIMAG = NLP1*NRHS
+         DO 250 JCOL = 1, NRHS
+            DO 240 JROW = NLF, NLF + NLP1 - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+  240       CONTINUE
+  250    CONTINUE
+*
+*        Since B and BX are complex, the following call to DGEMM is
+*        performed in two steps (real and imaginary parts).
+*
+*        CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+*    $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )
+*
+         J = NRP1*NRHS*2
+         DO 270 JCOL = 1, NRHS
+            DO 260 JROW = NRF, NRF + NRP1 - 1
+               J = J + 1
+               RWORK( J ) = DBLE( B( JROW, JCOL ) )
+  260       CONTINUE
+  270    CONTINUE
+         CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+     $               RWORK( 1+NRP1*NRHS*2 ), NRP1, ZERO, RWORK( 1 ),
+     $               NRP1 )
+         J = NRP1*NRHS*2
+         DO 290 JCOL = 1, NRHS
+            DO 280 JROW = NRF, NRF + NRP1 - 1
+               J = J + 1
+               RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+  280       CONTINUE
+  290    CONTINUE
+         CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,
+     $               RWORK( 1+NRP1*NRHS*2 ), NRP1, ZERO,
+     $               RWORK( 1+NRP1*NRHS ), NRP1 )
+         JREAL = 0
+         JIMAG = NRP1*NRHS
+         DO 310 JCOL = 1, NRHS
+            DO 300 JROW = NRF, NRF + NRP1 - 1
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                            RWORK( JIMAG ) )
+  300       CONTINUE
+  310    CONTINUE
+*
+  320 CONTINUE
+*
+  330 CONTINUE
+*
+      RETURN
+*
+*     End of ZLALSA
+*
+      END
diff --git a/libcruft/lapack/zlalsd.f b/libcruft/lapack/zlalsd.f
new file mode 100644
index 0000000..8f01f7b
--- /dev/null
+++ b/libcruft/lapack/zlalsd.f
@@ -0,0 +1,600 @@
+      SUBROUTINE ZLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
+     $                   RANK, WORK, RWORK, IWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDB, N, NRHS, RANK, SMLSIZ
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IWORK( * )
+      DOUBLE PRECISION   D( * ), E( * ), RWORK( * )
+      COMPLEX*16         B( LDB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLALSD uses the singular value decomposition of A to solve the least
+*  squares problem of finding X to minimize the Euclidean norm of each
+*  column of A*X-B, where A is N-by-N upper bidiagonal, and X and B
+*  are N-by-NRHS. The solution X overwrites B.
+*
+*  The singular values of A smaller than RCOND times the largest
+*  singular value are treated as zero in solving the least squares
+*  problem; in this case a minimum norm solution is returned.
+*  The actual singular values are returned in D in ascending order.
+*
+*  This code makes very mild assumptions about floating point
+*  arithmetic. It will work on machines with a guard digit in
+*  add/subtract, or on those binary machines without guard digits
+*  which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
+*  It could conceivably fail on hexadecimal or decimal machines
+*  without guard digits, but we know of none.
+*
+*  Arguments
+*  =========
+*
+*  UPLO   (input) CHARACTER*1
+*         = 'U': D and E define an upper bidiagonal matrix.
+*         = 'L': D and E define a  lower bidiagonal matrix.
+*
+*  SMLSIZ (input) INTEGER
+*         The maximum size of the subproblems at the bottom of the
+*         computation tree.
+*
+*  N      (input) INTEGER
+*         The dimension of the  bidiagonal matrix.  N >= 0.
+*
+*  NRHS   (input) INTEGER
+*         The number of columns of B. NRHS must be at least 1.
+*
+*  D      (input/output) DOUBLE PRECISION array, dimension (N)
+*         On entry D contains the main diagonal of the bidiagonal
+*         matrix. On exit, if INFO = 0, D contains its singular values.
+*
+*  E      (input/output) DOUBLE PRECISION array, dimension (N-1)
+*         Contains the super-diagonal entries of the bidiagonal matrix.
+*         On exit, E has been destroyed.
+*
+*  B      (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*         On input, B contains the right hand sides of the least
+*         squares problem. On output, B contains the solution X.
+*
+*  LDB    (input) INTEGER
+*         The leading dimension of B in the calling subprogram.
+*         LDB must be at least max(1,N).
+*
+*  RCOND  (input) DOUBLE PRECISION
+*         The singular values of A less than or equal to RCOND times
+*         the largest singular value are treated as zero in solving
+*         the least squares problem. If RCOND is negative,
+*         machine precision is used instead.
+*         For example, if diag(S)*X=B were the least squares problem,
+*         where diag(S) is a diagonal matrix of singular values, the
+*         solution would be X(i) = B(i) / S(i) if S(i) is greater than
+*         RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to
+*         RCOND*max(S).
+*
+*  RANK   (output) INTEGER
+*         The number of singular values of A greater than RCOND times
+*         the largest singular value.
+*
+*  WORK   (workspace) COMPLEX*16 array, dimension at least
+*         (N * NRHS).
+*
+*  RWORK  (workspace) DOUBLE PRECISION array, dimension at least
+*         (9*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS + (SMLSIZ+1)**2),
+*         where
+*         NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
+*
+*  IWORK  (workspace) INTEGER array, dimension at least
+*         (3*N*NLVL + 11*N).
+*
+*  INFO   (output) INTEGER
+*         = 0:  successful exit.
+*         < 0:  if INFO = -i, the i-th argument had an illegal value.
+*         > 0:  The algorithm failed to compute an singular value while
+*               working on the submatrix lying in rows and columns
+*               INFO/(N+1) through MOD(INFO,N+1).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*     Ming Gu and Ren-Cang Li, Computer Science Division, University of
+*       California at Berkeley, USA
+*     Osni Marques, LBNL/NERSC, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
+      COMPLEX*16         CZERO
+      PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
+     $                   GIVPTR, I, ICMPQ1, ICMPQ2, IRWB, IRWIB, IRWRB,
+     $                   IRWU, IRWVT, IRWWRK, IWK, J, JCOL, JIMAG,
+     $                   JREAL, JROW, K, NLVL, NM1, NRWORK, NSIZE, NSUB,
+     $                   PERM, POLES, S, SIZEI, SMLSZP, SQRE, ST, ST1,
+     $                   U, VT, Z
+      DOUBLE PRECISION   CS, EPS, ORGNRM, RCND, R, SN, TOL
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DLANST
+      EXTERNAL           IDAMAX, DLAMCH, DLANST
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DGEMM, DLARTG, DLASCL, DLASDA, DLASDQ, DLASET,
+     $                   DLASRT, XERBLA, ZCOPY, ZDROT, ZLACPY, ZLALSA,
+     $                   ZLASCL, ZLASET
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DIMAG, INT, LOG, SIGN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.1 ) THEN
+         INFO = -4
+      ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLALSD', -INFO )
+         RETURN
+      END IF
+*
+      EPS = DLAMCH( 'Epsilon' )
+*
+*     Set up the tolerance.
+*
+      IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THEN
+         RCND = EPS
+      ELSE
+         RCND = RCOND
+      END IF
+*
+      RANK = 0
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 ) THEN
+         RETURN
+      ELSE IF( N.EQ.1 ) THEN
+         IF( D( 1 ).EQ.ZERO ) THEN
+            CALL ZLASET( 'A', 1, NRHS, CZERO, CZERO, B, LDB )
+         ELSE
+            RANK = 1
+            CALL ZLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )
+            D( 1 ) = ABS( D( 1 ) )
+         END IF
+         RETURN
+      END IF
+*
+*     Rotate the matrix if it is lower bidiagonal.
+*
+      IF( UPLO.EQ.'L' ) THEN
+         DO 10 I = 1, N - 1
+            CALL DLARTG( D( I ), E( I ), CS, SN, R )
+            D( I ) = R
+            E( I ) = SN*D( I+1 )
+            D( I+1 ) = CS*D( I+1 )
+            IF( NRHS.EQ.1 ) THEN
+               CALL ZDROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )
+            ELSE
+               RWORK( I*2-1 ) = CS
+               RWORK( I*2 ) = SN
+            END IF
+   10    CONTINUE
+         IF( NRHS.GT.1 ) THEN
+            DO 30 I = 1, NRHS
+               DO 20 J = 1, N - 1
+                  CS = RWORK( J*2-1 )
+                  SN = RWORK( J*2 )
+                  CALL ZDROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )
+   20          CONTINUE
+   30       CONTINUE
+         END IF
+      END IF
+*
+*     Scale.
+*
+      NM1 = N - 1
+      ORGNRM = DLANST( 'M', N, D, E )
+      IF( ORGNRM.EQ.ZERO ) THEN
+         CALL ZLASET( 'A', N, NRHS, CZERO, CZERO, B, LDB )
+         RETURN
+      END IF
+*
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
+      CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )
+*
+*     If N is smaller than the minimum divide size SMLSIZ, then solve
+*     the problem with another solver.
+*
+      IF( N.LE.SMLSIZ ) THEN
+         IRWU = 1
+         IRWVT = IRWU + N*N
+         IRWWRK = IRWVT + N*N
+         IRWRB = IRWWRK
+         IRWIB = IRWRB + N*NRHS
+         IRWB = IRWIB + N*NRHS
+         CALL DLASET( 'A', N, N, ZERO, ONE, RWORK( IRWU ), N )
+         CALL DLASET( 'A', N, N, ZERO, ONE, RWORK( IRWVT ), N )
+         CALL DLASDQ( 'U', 0, N, N, N, 0, D, E, RWORK( IRWVT ), N,
+     $                RWORK( IRWU ), N, RWORK( IRWWRK ), 1,
+     $                RWORK( IRWWRK ), INFO )
+         IF( INFO.NE.0 ) THEN
+            RETURN
+         END IF
+*
+*        In the real version, B is passed to DLASDQ and multiplied
+*        internally by Q'. Here B is complex and that product is
+*        computed below in two steps (real and imaginary parts).
+*
+         J = IRWB - 1
+         DO 50 JCOL = 1, NRHS
+            DO 40 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = DBLE( B( JROW, JCOL ) )
+   40       CONTINUE
+   50    CONTINUE
+         CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWU ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )
+         J = IRWB - 1
+         DO 70 JCOL = 1, NRHS
+            DO 60 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+   60       CONTINUE
+   70    CONTINUE
+         CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWU ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )
+         JREAL = IRWRB - 1
+         JIMAG = IRWIB - 1
+         DO 90 JCOL = 1, NRHS
+            DO 80 JROW = 1, N
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                           RWORK( JIMAG ) )
+   80       CONTINUE
+   90    CONTINUE
+*
+         TOL = RCND*ABS( D( IDAMAX( N, D, 1 ) ) )
+         DO 100 I = 1, N
+            IF( D( I ).LE.TOL ) THEN
+               CALL ZLASET( 'A', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
+            ELSE
+               CALL ZLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),
+     $                      LDB, INFO )
+               RANK = RANK + 1
+            END IF
+  100    CONTINUE
+*
+*        Since B is complex, the following call to DGEMM is performed
+*        in two steps (real and imaginary parts). That is for V * B
+*        (in the real version of the code V' is stored in WORK).
+*
+*        CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,
+*    $               WORK( NWORK ), N )
+*
+         J = IRWB - 1
+         DO 120 JCOL = 1, NRHS
+            DO 110 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = DBLE( B( JROW, JCOL ) )
+  110       CONTINUE
+  120    CONTINUE
+         CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )
+         J = IRWB - 1
+         DO 140 JCOL = 1, NRHS
+            DO 130 JROW = 1, N
+               J = J + 1
+               RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+  130       CONTINUE
+  140    CONTINUE
+         CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,
+     $               RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )
+         JREAL = IRWRB - 1
+         JIMAG = IRWIB - 1
+         DO 160 JCOL = 1, NRHS
+            DO 150 JROW = 1, N
+               JREAL = JREAL + 1
+               JIMAG = JIMAG + 1
+               B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                           RWORK( JIMAG ) )
+  150       CONTINUE
+  160    CONTINUE
+*
+*        Unscale.
+*
+         CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+         CALL DLASRT( 'D', N, D, INFO )
+         CALL ZLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+         RETURN
+      END IF
+*
+*     Book-keeping and setting up some constants.
+*
+      NLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1
+*
+      SMLSZP = SMLSIZ + 1
+*
+      U = 1
+      VT = 1 + SMLSIZ*N
+      DIFL = VT + SMLSZP*N
+      DIFR = DIFL + NLVL*N
+      Z = DIFR + NLVL*N*2
+      C = Z + NLVL*N
+      S = C + N
+      POLES = S + N
+      GIVNUM = POLES + 2*NLVL*N
+      NRWORK = GIVNUM + 2*NLVL*N
+      BX = 1
+*
+      IRWRB = NRWORK
+      IRWIB = IRWRB + SMLSIZ*NRHS
+      IRWB = IRWIB + SMLSIZ*NRHS
+*
+      SIZEI = 1 + N
+      K = SIZEI + N
+      GIVPTR = K + N
+      PERM = GIVPTR + N
+      GIVCOL = PERM + NLVL*N
+      IWK = GIVCOL + NLVL*N*2
+*
+      ST = 1
+      SQRE = 0
+      ICMPQ1 = 1
+      ICMPQ2 = 0
+      NSUB = 0
+*
+      DO 170 I = 1, N
+         IF( ABS( D( I ) ).LT.EPS ) THEN
+            D( I ) = SIGN( EPS, D( I ) )
+         END IF
+  170 CONTINUE
+*
+      DO 240 I = 1, NM1
+         IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
+            NSUB = NSUB + 1
+            IWORK( NSUB ) = ST
+*
+*           Subproblem found. First determine its size and then
+*           apply divide and conquer on it.
+*
+            IF( I.LT.NM1 ) THEN
+*
+*              A subproblem with E(I) small for I < NM1.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
+*
+*              A subproblem with E(NM1) not too small but I = NM1.
+*
+               NSIZE = N - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+            ELSE
+*
+*              A subproblem with E(NM1) small. This implies an
+*              1-by-1 subproblem at D(N), which is not solved
+*              explicitly.
+*
+               NSIZE = I - ST + 1
+               IWORK( SIZEI+NSUB-1 ) = NSIZE
+               NSUB = NSUB + 1
+               IWORK( NSUB ) = N
+               IWORK( SIZEI+NSUB-1 ) = 1
+               CALL ZCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )
+            END IF
+            ST1 = ST - 1
+            IF( NSIZE.EQ.1 ) THEN
+*
+*              This is a 1-by-1 subproblem and is not solved
+*              explicitly.
+*
+               CALL ZCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )
+            ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+*
+*              This is a small subproblem and is solved by DLASDQ.
+*
+               CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
+     $                      RWORK( VT+ST1 ), N )
+               CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
+     $                      RWORK( U+ST1 ), N )
+               CALL DLASDQ( 'U', 0, NSIZE, NSIZE, NSIZE, 0, D( ST ),
+     $                      E( ST ), RWORK( VT+ST1 ), N, RWORK( U+ST1 ),
+     $                      N, RWORK( NRWORK ), 1, RWORK( NRWORK ),
+     $                      INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+*
+*              In the real version, B is passed to DLASDQ and multiplied
+*              internally by Q'. Here B is complex and that product is
+*              computed below in two steps (real and imaginary parts).
+*
+               J = IRWB - 1
+               DO 190 JCOL = 1, NRHS
+                  DO 180 JROW = ST, ST + NSIZE - 1
+                     J = J + 1
+                     RWORK( J ) = DBLE( B( JROW, JCOL ) )
+  180             CONTINUE
+  190          CONTINUE
+               CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                     RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,
+     $                     ZERO, RWORK( IRWRB ), NSIZE )
+               J = IRWB - 1
+               DO 210 JCOL = 1, NRHS
+                  DO 200 JROW = ST, ST + NSIZE - 1
+                     J = J + 1
+                     RWORK( J ) = DIMAG( B( JROW, JCOL ) )
+  200             CONTINUE
+  210          CONTINUE
+               CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                     RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,
+     $                     ZERO, RWORK( IRWIB ), NSIZE )
+               JREAL = IRWRB - 1
+               JIMAG = IRWIB - 1
+               DO 230 JCOL = 1, NRHS
+                  DO 220 JROW = ST, ST + NSIZE - 1
+                     JREAL = JREAL + 1
+                     JIMAG = JIMAG + 1
+                     B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                                 RWORK( JIMAG ) )
+  220             CONTINUE
+  230          CONTINUE
+*
+               CALL ZLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,
+     $                      WORK( BX+ST1 ), N )
+            ELSE
+*
+*              A large problem. Solve it using divide and conquer.
+*
+               CALL DLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),
+     $                      E( ST ), RWORK( U+ST1 ), N, RWORK( VT+ST1 ),
+     $                      IWORK( K+ST1 ), RWORK( DIFL+ST1 ),
+     $                      RWORK( DIFR+ST1 ), RWORK( Z+ST1 ),
+     $                      RWORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),
+     $                      IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),
+     $                      RWORK( GIVNUM+ST1 ), RWORK( C+ST1 ),
+     $                      RWORK( S+ST1 ), RWORK( NRWORK ),
+     $                      IWORK( IWK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+               BXST = BX + ST1
+               CALL ZLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),
+     $                      LDB, WORK( BXST ), N, RWORK( U+ST1 ), N,
+     $                      RWORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                      RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),
+     $                      RWORK( Z+ST1 ), RWORK( POLES+ST1 ),
+     $                      IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                      IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),
+     $                      RWORK( C+ST1 ), RWORK( S+ST1 ),
+     $                      RWORK( NRWORK ), IWORK( IWK ), INFO )
+               IF( INFO.NE.0 ) THEN
+                  RETURN
+               END IF
+            END IF
+            ST = I + 1
+         END IF
+  240 CONTINUE
+*
+*     Apply the singular values and treat the tiny ones as zero.
+*
+      TOL = RCND*ABS( D( IDAMAX( N, D, 1 ) ) )
+*
+      DO 250 I = 1, N
+*
+*        Some of the elements in D can be negative because 1-by-1
+*        subproblems were not solved explicitly.
+*
+         IF( ABS( D( I ) ).LE.TOL ) THEN
+            CALL ZLASET( 'A', 1, NRHS, CZERO, CZERO, WORK( BX+I-1 ), N )
+         ELSE
+            RANK = RANK + 1
+            CALL ZLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,
+     $                   WORK( BX+I-1 ), N, INFO )
+         END IF
+         D( I ) = ABS( D( I ) )
+  250 CONTINUE
+*
+*     Now apply back the right singular vectors.
+*
+      ICMPQ2 = 1
+      DO 320 I = 1, NSUB
+         ST = IWORK( I )
+         ST1 = ST - 1
+         NSIZE = IWORK( SIZEI+I-1 )
+         BXST = BX + ST1
+         IF( NSIZE.EQ.1 ) THEN
+            CALL ZCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )
+         ELSE IF( NSIZE.LE.SMLSIZ ) THEN
+*
+*           Since B and BX are complex, the following call to DGEMM
+*           is performed in two steps (real and imaginary parts).
+*
+*           CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+*    $                  RWORK( VT+ST1 ), N, RWORK( BXST ), N, ZERO,
+*    $                  B( ST, 1 ), LDB )
+*
+            J = BXST - N - 1
+            JREAL = IRWB - 1
+            DO 270 JCOL = 1, NRHS
+               J = J + N
+               DO 260 JROW = 1, NSIZE
+                  JREAL = JREAL + 1
+                  RWORK( JREAL ) = DBLE( WORK( J+JROW ) )
+  260          CONTINUE
+  270       CONTINUE
+            CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                  RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,
+     $                  RWORK( IRWRB ), NSIZE )
+            J = BXST - N - 1
+            JIMAG = IRWB - 1
+            DO 290 JCOL = 1, NRHS
+               J = J + N
+               DO 280 JROW = 1, NSIZE
+                  JIMAG = JIMAG + 1
+                  RWORK( JIMAG ) = DIMAG( WORK( J+JROW ) )
+  280          CONTINUE
+  290       CONTINUE
+            CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
+     $                  RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,
+     $                  RWORK( IRWIB ), NSIZE )
+            JREAL = IRWRB - 1
+            JIMAG = IRWIB - 1
+            DO 310 JCOL = 1, NRHS
+               DO 300 JROW = ST, ST + NSIZE - 1
+                  JREAL = JREAL + 1
+                  JIMAG = JIMAG + 1
+                  B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),
+     $                              RWORK( JIMAG ) )
+  300          CONTINUE
+  310       CONTINUE
+         ELSE
+            CALL ZLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,
+     $                   B( ST, 1 ), LDB, RWORK( U+ST1 ), N,
+     $                   RWORK( VT+ST1 ), IWORK( K+ST1 ),
+     $                   RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),
+     $                   RWORK( Z+ST1 ), RWORK( POLES+ST1 ),
+     $                   IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
+     $                   IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),
+     $                   RWORK( C+ST1 ), RWORK( S+ST1 ),
+     $                   RWORK( NRWORK ), IWORK( IWK ), INFO )
+            IF( INFO.NE.0 ) THEN
+               RETURN
+            END IF
+         END IF
+  320 CONTINUE
+*
+*     Unscale and sort the singular values.
+*
+      CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
+      CALL DLASRT( 'D', N, D, INFO )
+      CALL ZLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
+*
+      RETURN
+*
+*     End of ZLALSD
+*
+      END
diff --git a/libcruft/lapack/zlange.f b/libcruft/lapack/zlange.f
new file mode 100644
index 0000000..36cecbd
--- /dev/null
+++ b/libcruft/lapack/zlange.f
@@ -0,0 +1,145 @@
+      DOUBLE PRECISION FUNCTION ZLANGE( NORM, M, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   WORK( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLANGE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  complex matrix A.
+*
+*  Description
+*  ===========
+*
+*  ZLANGE returns the value
+*
+*     ZLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in ZLANGE as described
+*          above.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.  When M = 0,
+*          ZLANGE is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.  When N = 0,
+*          ZLANGE is set to zero.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The m by n matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, M
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, M
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, M
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, M
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL ZLASSQ( M, A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      ZLANGE = VALUE
+      RETURN
+*
+*     End of ZLANGE
+*
+      END
diff --git a/libcruft/lapack/zlanhe.f b/libcruft/lapack/zlanhe.f
new file mode 100644
index 0000000..86e57fc
--- /dev/null
+++ b/libcruft/lapack/zlanhe.f
@@ -0,0 +1,187 @@
+      DOUBLE PRECISION FUNCTION ZLANHE( NORM, UPLO, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM, UPLO
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   WORK( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLANHE  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  complex hermitian matrix A.
+*
+*  Description
+*  ===========
+*
+*  ZLANHE returns the value
+*
+*     ZLANHE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in ZLANHE as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          hermitian matrix A is to be referenced.
+*          = 'U':  Upper triangular part of A is referenced
+*          = 'L':  Lower triangular part of A is referenced
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, ZLANHE is
+*          set to zero.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The hermitian matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of A contains the upper triangular part
+*          of the matrix A, and the strictly lower triangular part of A
+*          is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of A contains the lower triangular part of
+*          the matrix A, and the strictly upper triangular part of A is
+*          not referenced. Note that the imaginary parts of the diagonal
+*          elements need not be set and are assumed to be zero.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,
+*          WORK is not referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   ABSA, SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 20 J = 1, N
+               DO 10 I = 1, J - 1
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10          CONTINUE
+               VALUE = MAX( VALUE, ABS( DBLE( A( J, J ) ) ) )
+   20       CONTINUE
+         ELSE
+            DO 40 J = 1, N
+               VALUE = MAX( VALUE, ABS( DBLE( A( J, J ) ) ) )
+               DO 30 I = J + 1, N
+                  VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30          CONTINUE
+   40       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.
+     $         ( NORM.EQ.'1' ) ) THEN
+*
+*        Find normI(A) ( = norm1(A), since A is hermitian).
+*
+         VALUE = ZERO
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 60 J = 1, N
+               SUM = ZERO
+               DO 50 I = 1, J - 1
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   50          CONTINUE
+               WORK( J ) = SUM + ABS( DBLE( A( J, J ) ) )
+   60       CONTINUE
+            DO 70 I = 1, N
+               VALUE = MAX( VALUE, WORK( I ) )
+   70       CONTINUE
+         ELSE
+            DO 80 I = 1, N
+               WORK( I ) = ZERO
+   80       CONTINUE
+            DO 100 J = 1, N
+               SUM = WORK( J ) + ABS( DBLE( A( J, J ) ) )
+               DO 90 I = J + 1, N
+                  ABSA = ABS( A( I, J ) )
+                  SUM = SUM + ABSA
+                  WORK( I ) = WORK( I ) + ABSA
+   90          CONTINUE
+               VALUE = MAX( VALUE, SUM )
+  100       CONTINUE
+         END IF
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 2, N
+               CALL ZLASSQ( J-1, A( 1, J ), 1, SCALE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 120 J = 1, N - 1
+               CALL ZLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM )
+  120       CONTINUE
+         END IF
+         SUM = 2*SUM
+         DO 130 I = 1, N
+            IF( DBLE( A( I, I ) ).NE.ZERO ) THEN
+               ABSA = ABS( DBLE( A( I, I ) ) )
+               IF( SCALE.LT.ABSA ) THEN
+                  SUM = ONE + SUM*( SCALE / ABSA )**2
+                  SCALE = ABSA
+               ELSE
+                  SUM = SUM + ( ABSA / SCALE )**2
+               END IF
+            END IF
+  130    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      ZLANHE = VALUE
+      RETURN
+*
+*     End of ZLANHE
+*
+      END
diff --git a/libcruft/lapack/zlanhs.f b/libcruft/lapack/zlanhs.f
new file mode 100644
index 0000000..d7b187a
--- /dev/null
+++ b/libcruft/lapack/zlanhs.f
@@ -0,0 +1,142 @@
+      DOUBLE PRECISION FUNCTION ZLANHS( NORM, N, A, LDA, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          NORM
+      INTEGER            LDA, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   WORK( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLANHS  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  Hessenberg matrix A.
+*
+*  Description
+*  ===========
+*
+*  ZLANHS returns the value
+*
+*     ZLANHS = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in ZLANHS as described
+*          above.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.  When N = 0, ZLANHS is
+*          set to zero.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The n by n upper Hessenberg matrix A; the part of A below the
+*          first sub-diagonal is not referenced.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(N,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= N when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         VALUE = ZERO
+         DO 20 J = 1, N
+            DO 10 I = 1, MIN( N, J+1 )
+               VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10       CONTINUE
+   20    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         DO 40 J = 1, N
+            SUM = ZERO
+            DO 30 I = 1, MIN( N, J+1 )
+               SUM = SUM + ABS( A( I, J ) )
+   30       CONTINUE
+            VALUE = MAX( VALUE, SUM )
+   40    CONTINUE
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         DO 50 I = 1, N
+            WORK( I ) = ZERO
+   50    CONTINUE
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( N, J+1 )
+               WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+   60       CONTINUE
+   70    CONTINUE
+         VALUE = ZERO
+         DO 80 I = 1, N
+            VALUE = MAX( VALUE, WORK( I ) )
+   80    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         SCALE = ZERO
+         SUM = ONE
+         DO 90 J = 1, N
+            CALL ZLASSQ( MIN( N, J+1 ), A( 1, J ), 1, SCALE, SUM )
+   90    CONTINUE
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      ZLANHS = VALUE
+      RETURN
+*
+*     End of ZLANHS
+*
+      END
diff --git a/libcruft/lapack/zlantr.f b/libcruft/lapack/zlantr.f
new file mode 100644
index 0000000..f2f37ca
--- /dev/null
+++ b/libcruft/lapack/zlantr.f
@@ -0,0 +1,277 @@
+      DOUBLE PRECISION FUNCTION ZLANTR( NORM, UPLO, DIAG, M, N, A, LDA,
+     $                 WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   WORK( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLANTR  returns the value of the one norm,  or the Frobenius norm, or
+*  the  infinity norm,  or the  element of  largest absolute value  of a
+*  trapezoidal or triangular matrix A.
+*
+*  Description
+*  ===========
+*
+*  ZLANTR returns the value
+*
+*     ZLANTR = ( max(abs(A(i,j))), NORM = 'M' or 'm'
+*              (
+*              ( norm1(A),         NORM = '1', 'O' or 'o'
+*              (
+*              ( normI(A),         NORM = 'I' or 'i'
+*              (
+*              ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
+*
+*  where  norm1  denotes the  one norm of a matrix (maximum column sum),
+*  normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
+*  normF  denotes the  Frobenius norm of a matrix (square root of sum of
+*  squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies the value to be returned in ZLANTR as described
+*          above.
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower trapezoidal.
+*          = 'U':  Upper trapezoidal
+*          = 'L':  Lower trapezoidal
+*          Note that A is triangular instead of trapezoidal if M = N.
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A has unit diagonal.
+*          = 'N':  Non-unit diagonal
+*          = 'U':  Unit diagonal
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0, and if
+*          UPLO = 'U', M <= N.  When M = 0, ZLANTR is set to zero.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0, and if
+*          UPLO = 'L', N <= M.  When N = 0, ZLANTR is set to zero.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The trapezoidal matrix A (A is triangular if M = N).
+*          If UPLO = 'U', the leading m by n upper trapezoidal part of
+*          the array A contains the upper trapezoidal matrix, and the
+*          strictly lower triangular part of A is not referenced.
+*          If UPLO = 'L', the leading m by n lower trapezoidal part of
+*          the array A contains the lower trapezoidal matrix, and the
+*          strictly upper triangular part of A is not referenced.  Note
+*          that when DIAG = 'U', the diagonal elements of A are not
+*          referenced and are assumed to be one.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(M,1).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)),
+*          where LWORK >= M when NORM = 'I'; otherwise, WORK is not
+*          referenced.
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UDIAG
+      INTEGER            I, J
+      DOUBLE PRECISION   SCALE, SUM, VALUE
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLASSQ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+      IF( MIN( M, N ).EQ.0 ) THEN
+         VALUE = ZERO
+      ELSE IF( LSAME( NORM, 'M' ) ) THEN
+*
+*        Find max(abs(A(i,j))).
+*
+         IF( LSAME( DIAG, 'U' ) ) THEN
+            VALUE = ONE
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 20 J = 1, N
+                  DO 10 I = 1, MIN( M, J-1 )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   10             CONTINUE
+   20          CONTINUE
+            ELSE
+               DO 40 J = 1, N
+                  DO 30 I = J + 1, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   30             CONTINUE
+   40          CONTINUE
+            END IF
+         ELSE
+            VALUE = ZERO
+            IF( LSAME( UPLO, 'U' ) ) THEN
+               DO 60 J = 1, N
+                  DO 50 I = 1, MIN( M, J )
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   50             CONTINUE
+   60          CONTINUE
+            ELSE
+               DO 80 J = 1, N
+                  DO 70 I = J, M
+                     VALUE = MAX( VALUE, ABS( A( I, J ) ) )
+   70             CONTINUE
+   80          CONTINUE
+            END IF
+         END IF
+      ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN
+*
+*        Find norm1(A).
+*
+         VALUE = ZERO
+         UDIAG = LSAME( DIAG, 'U' )
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            DO 110 J = 1, N
+               IF( ( UDIAG ) .AND. ( J.LE.M ) ) THEN
+                  SUM = ONE
+                  DO 90 I = 1, J - 1
+                     SUM = SUM + ABS( A( I, J ) )
+   90             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 100 I = 1, MIN( M, J )
+                     SUM = SUM + ABS( A( I, J ) )
+  100             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  110       CONTINUE
+         ELSE
+            DO 140 J = 1, N
+               IF( UDIAG ) THEN
+                  SUM = ONE
+                  DO 120 I = J + 1, M
+                     SUM = SUM + ABS( A( I, J ) )
+  120             CONTINUE
+               ELSE
+                  SUM = ZERO
+                  DO 130 I = J, M
+                     SUM = SUM + ABS( A( I, J ) )
+  130             CONTINUE
+               END IF
+               VALUE = MAX( VALUE, SUM )
+  140       CONTINUE
+         END IF
+      ELSE IF( LSAME( NORM, 'I' ) ) THEN
+*
+*        Find normI(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 150 I = 1, M
+                  WORK( I ) = ONE
+  150          CONTINUE
+               DO 170 J = 1, N
+                  DO 160 I = 1, MIN( M, J-1 )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  160             CONTINUE
+  170          CONTINUE
+            ELSE
+               DO 180 I = 1, M
+                  WORK( I ) = ZERO
+  180          CONTINUE
+               DO 200 J = 1, N
+                  DO 190 I = 1, MIN( M, J )
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  190             CONTINUE
+  200          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               DO 210 I = 1, N
+                  WORK( I ) = ONE
+  210          CONTINUE
+               DO 220 I = N + 1, M
+                  WORK( I ) = ZERO
+  220          CONTINUE
+               DO 240 J = 1, N
+                  DO 230 I = J + 1, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  230             CONTINUE
+  240          CONTINUE
+            ELSE
+               DO 250 I = 1, M
+                  WORK( I ) = ZERO
+  250          CONTINUE
+               DO 270 J = 1, N
+                  DO 260 I = J, M
+                     WORK( I ) = WORK( I ) + ABS( A( I, J ) )
+  260             CONTINUE
+  270          CONTINUE
+            END IF
+         END IF
+         VALUE = ZERO
+         DO 280 I = 1, M
+            VALUE = MAX( VALUE, WORK( I ) )
+  280    CONTINUE
+      ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN
+*
+*        Find normF(A).
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 290 J = 2, N
+                  CALL ZLASSQ( MIN( M, J-1 ), A( 1, J ), 1, SCALE, SUM )
+  290          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 300 J = 1, N
+                  CALL ZLASSQ( MIN( M, J ), A( 1, J ), 1, SCALE, SUM )
+  300          CONTINUE
+            END IF
+         ELSE
+            IF( LSAME( DIAG, 'U' ) ) THEN
+               SCALE = ONE
+               SUM = MIN( M, N )
+               DO 310 J = 1, N
+                  CALL ZLASSQ( M-J, A( MIN( M, J+1 ), J ), 1, SCALE,
+     $                         SUM )
+  310          CONTINUE
+            ELSE
+               SCALE = ZERO
+               SUM = ONE
+               DO 320 J = 1, N
+                  CALL ZLASSQ( M-J+1, A( J, J ), 1, SCALE, SUM )
+  320          CONTINUE
+            END IF
+         END IF
+         VALUE = SCALE*SQRT( SUM )
+      END IF
+*
+      ZLANTR = VALUE
+      RETURN
+*
+*     End of ZLANTR
+*
+      END
diff --git a/libcruft/lapack/zlaqp2.f b/libcruft/lapack/zlaqp2.f
new file mode 100644
index 0000000..46f6d95
--- /dev/null
+++ b/libcruft/lapack/zlaqp2.f
@@ -0,0 +1,179 @@
+      SUBROUTINE ZLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2,
+     $                   WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            LDA, M, N, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   VN1( * ), VN2( * )
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAQP2 computes a QR factorization with column pivoting of
+*  the block A(OFFSET+1:M,1:N).
+*  The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0.
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of the matrix A that must be pivoted
+*          but no factorized. OFFSET >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, the upper triangle of block A(OFFSET+1:M,1:N) is
+*          the triangular factor obtained; the elements in block
+*          A(OFFSET+1:M,1:N) below the diagonal, together with the
+*          array TAU, represent the orthogonal matrix Q as a product of
+*          elementary reflectors. Block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
+*          to the front of A*P (a leading column); if JPVT(i) = 0,
+*          the i-th column of A is a free column.
+*          On exit, if JPVT(i) = k, then the i-th column of A*P
+*          was the k-th column of A.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (min(M,N))
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  Partial column norm updating strategy modified by
+*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics,
+*    University of Zagreb, Croatia.
+*    June 2006.
+*  For more details see LAPACK Working Note 176.
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      COMPLEX*16         CONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0,
+     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ITEMP, J, MN, OFFPI, PVT
+      DOUBLE PRECISION   TEMP, TEMP2, TOL3Z
+      COMPLEX*16         AII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLARF, ZLARFG, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DCONJG, MAX, MIN, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DZNRM2
+      EXTERNAL           IDAMAX, DLAMCH, DZNRM2
+*     ..
+*     .. Executable Statements ..
+*
+      MN = MIN( M-OFFSET, N )
+      TOL3Z = SQRT(DLAMCH('Epsilon'))
+*
+*     Compute factorization.
+*
+      DO 20 I = 1, MN
+*
+         OFFPI = OFFSET + I
+*
+*        Determine ith pivot column and swap if necessary.
+*
+         PVT = ( I-1 ) + IDAMAX( N-I+1, VN1( I ), 1 )
+*
+         IF( PVT.NE.I ) THEN
+            CALL ZSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( I )
+            JPVT( I ) = ITEMP
+            VN1( PVT ) = VN1( I )
+            VN2( PVT ) = VN2( I )
+         END IF
+*
+*        Generate elementary reflector H(i).
+*
+         IF( OFFPI.LT.M ) THEN
+            CALL ZLARFG( M-OFFPI+1, A( OFFPI, I ), A( OFFPI+1, I ), 1,
+     $                   TAU( I ) )
+         ELSE
+            CALL ZLARFG( 1, A( M, I ), A( M, I ), 1, TAU( I ) )
+         END IF
+*
+         IF( I.LT.N ) THEN
+*
+*           Apply H(i)' to A(offset+i:m,i+1:n) from the left.
+*
+            AII = A( OFFPI, I )
+            A( OFFPI, I ) = CONE
+            CALL ZLARF( 'Left', M-OFFPI+1, N-I, A( OFFPI, I ), 1,
+     $                  DCONJG( TAU( I ) ), A( OFFPI, I+1 ), LDA,
+     $                  WORK( 1 ) )
+            A( OFFPI, I ) = AII
+         END IF
+*
+*        Update partial column norms.
+*
+         DO 10 J = I + 1, N
+            IF( VN1( J ).NE.ZERO ) THEN
+*
+*              NOTE: The following 4 lines follow from the analysis in
+*              Lapack Working Note 176.
+*
+               TEMP = ONE - ( ABS( A( OFFPI, J ) ) / VN1( J ) )**2
+               TEMP = MAX( TEMP, ZERO )
+               TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+               IF( TEMP2 .LE. TOL3Z ) THEN
+                  IF( OFFPI.LT.M ) THEN
+                     VN1( J ) = DZNRM2( M-OFFPI, A( OFFPI+1, J ), 1 )
+                     VN2( J ) = VN1( J )
+                  ELSE
+                     VN1( J ) = ZERO
+                     VN2( J ) = ZERO
+                  END IF
+               ELSE
+                  VN1( J ) = VN1( J )*SQRT( TEMP )
+               END IF
+            END IF
+   10    CONTINUE
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of ZLAQP2
+*
+      END
diff --git a/libcruft/lapack/zlaqps.f b/libcruft/lapack/zlaqps.f
new file mode 100644
index 0000000..4041450
--- /dev/null
+++ b/libcruft/lapack/zlaqps.f
@@ -0,0 +1,266 @@
+      SUBROUTINE ZLAQPS( M, N, OFFSET, NB, KB, A, LDA, JPVT, TAU, VN1,
+     $                   VN2, AUXV, F, LDF )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            KB, LDA, LDF, M, N, NB, OFFSET
+*     ..
+*     .. Array Arguments ..
+      INTEGER            JPVT( * )
+      DOUBLE PRECISION   VN1( * ), VN2( * )
+      COMPLEX*16         A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAQPS computes a step of QR factorization with column pivoting
+*  of a complex M-by-N matrix A by using Blas-3.  It tries to factorize
+*  NB columns from A starting from the row OFFSET+1, and updates all
+*  of the matrix with Blas-3 xGEMM.
+*
+*  In some cases, due to catastrophic cancellations, it cannot
+*  factorize NB columns.  Hence, the actual number of factorized
+*  columns is returned in KB.
+*
+*  Block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A. N >= 0
+*
+*  OFFSET  (input) INTEGER
+*          The number of rows of A that have been factorized in
+*          previous steps.
+*
+*  NB      (input) INTEGER
+*          The number of columns to factorize.
+*
+*  KB      (output) INTEGER
+*          The number of columns actually factorized.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the M-by-N matrix A.
+*          On exit, block A(OFFSET+1:M,1:KB) is the triangular
+*          factor obtained and block A(1:OFFSET,1:N) has been
+*          accordingly pivoted, but no factorized.
+*          The rest of the matrix, block A(OFFSET+1:M,KB+1:N) has
+*          been updated.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  JPVT    (input/output) INTEGER array, dimension (N)
+*          JPVT(I) = K <==> Column K of the full matrix A has been
+*          permuted into position I in AP.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (KB)
+*          The scalar factors of the elementary reflectors.
+*
+*  VN1     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the partial column norms.
+*
+*  VN2     (input/output) DOUBLE PRECISION array, dimension (N)
+*          The vector with the exact column norms.
+*
+*  AUXV    (input/output) COMPLEX*16 array, dimension (NB)
+*          Auxiliar vector.
+*
+*  F       (input/output) COMPLEX*16 array, dimension (LDF,NB)
+*          Matrix F' = L*Y'*A.
+*
+*  LDF     (input) INTEGER
+*          The leading dimension of the array F. LDF >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
+*    X. Sun, Computer Science Dept., Duke University, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0,
+     $                   CZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            ITEMP, J, K, LASTRK, LSTICC, PVT, RK
+      DOUBLE PRECISION   TEMP, TEMP2, TOL3Z
+      COMPLEX*16         AKK
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZGEMM, ZGEMV, ZLARFG, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCONJG, MAX, MIN, NINT, SQRT
+*     ..
+*     .. External Functions ..
+      INTEGER            IDAMAX
+      DOUBLE PRECISION   DLAMCH, DZNRM2
+      EXTERNAL           IDAMAX, DLAMCH, DZNRM2
+*     ..
+*     .. Executable Statements ..
+*
+      LASTRK = MIN( M, N+OFFSET )
+      LSTICC = 0
+      K = 0
+      TOL3Z = SQRT(DLAMCH('Epsilon'))
+*
+*     Beginning of while loop.
+*
+   10 CONTINUE
+      IF( ( K.LT.NB ) .AND. ( LSTICC.EQ.0 ) ) THEN
+         K = K + 1
+         RK = OFFSET + K
+*
+*        Determine ith pivot column and swap if necessary
+*
+         PVT = ( K-1 ) + IDAMAX( N-K+1, VN1( K ), 1 )
+         IF( PVT.NE.K ) THEN
+            CALL ZSWAP( M, A( 1, PVT ), 1, A( 1, K ), 1 )
+            CALL ZSWAP( K-1, F( PVT, 1 ), LDF, F( K, 1 ), LDF )
+            ITEMP = JPVT( PVT )
+            JPVT( PVT ) = JPVT( K )
+            JPVT( K ) = ITEMP
+            VN1( PVT ) = VN1( K )
+            VN2( PVT ) = VN2( K )
+         END IF
+*
+*        Apply previous Householder reflectors to column K:
+*        A(RK:M,K) := A(RK:M,K) - A(RK:M,1:K-1)*F(K,1:K-1)'.
+*
+         IF( K.GT.1 ) THEN
+            DO 20 J = 1, K - 1
+               F( K, J ) = DCONJG( F( K, J ) )
+   20       CONTINUE
+            CALL ZGEMV( 'No transpose', M-RK+1, K-1, -CONE, A( RK, 1 ),
+     $                  LDA, F( K, 1 ), LDF, CONE, A( RK, K ), 1 )
+            DO 30 J = 1, K - 1
+               F( K, J ) = DCONJG( F( K, J ) )
+   30       CONTINUE
+         END IF
+*
+*        Generate elementary reflector H(k).
+*
+         IF( RK.LT.M ) THEN
+            CALL ZLARFG( M-RK+1, A( RK, K ), A( RK+1, K ), 1, TAU( K ) )
+         ELSE
+            CALL ZLARFG( 1, A( RK, K ), A( RK, K ), 1, TAU( K ) )
+         END IF
+*
+         AKK = A( RK, K )
+         A( RK, K ) = CONE
+*
+*        Compute Kth column of F:
+*
+*        Compute  F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)'*A(RK:M,K).
+*
+         IF( K.LT.N ) THEN
+            CALL ZGEMV( 'Conjugate transpose', M-RK+1, N-K, TAU( K ),
+     $                  A( RK, K+1 ), LDA, A( RK, K ), 1, CZERO,
+     $                  F( K+1, K ), 1 )
+         END IF
+*
+*        Padding F(1:K,K) with zeros.
+*
+         DO 40 J = 1, K
+            F( J, K ) = CZERO
+   40    CONTINUE
+*
+*        Incremental updating of F:
+*        F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)'
+*                    *A(RK:M,K).
+*
+         IF( K.GT.1 ) THEN
+            CALL ZGEMV( 'Conjugate transpose', M-RK+1, K-1, -TAU( K ),
+     $                  A( RK, 1 ), LDA, A( RK, K ), 1, CZERO,
+     $                  AUXV( 1 ), 1 )
+*
+            CALL ZGEMV( 'No transpose', N, K-1, CONE, F( 1, 1 ), LDF,
+     $                  AUXV( 1 ), 1, CONE, F( 1, K ), 1 )
+         END IF
+*
+*        Update the current row of A:
+*        A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)'.
+*
+         IF( K.LT.N ) THEN
+            CALL ZGEMM( 'No transpose', 'Conjugate transpose', 1, N-K,
+     $                  K, -CONE, A( RK, 1 ), LDA, F( K+1, 1 ), LDF,
+     $                  CONE, A( RK, K+1 ), LDA )
+         END IF
+*
+*        Update partial column norms.
+*
+         IF( RK.LT.LASTRK ) THEN
+            DO 50 J = K + 1, N
+               IF( VN1( J ).NE.ZERO ) THEN
+*
+*                 NOTE: The following 4 lines follow from the analysis in
+*                 Lapack Working Note 176.
+*
+                  TEMP = ABS( A( RK, J ) ) / VN1( J )
+                  TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
+                  TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
+                  IF( TEMP2 .LE. TOL3Z ) THEN
+                     VN2( J ) = DBLE( LSTICC )
+                     LSTICC = J
+                  ELSE
+                     VN1( J ) = VN1( J )*SQRT( TEMP )
+                  END IF
+               END IF
+   50       CONTINUE
+         END IF
+*
+         A( RK, K ) = AKK
+*
+*        End of while loop.
+*
+         GO TO 10
+      END IF
+      KB = K
+      RK = OFFSET + KB
+*
+*     Apply the block reflector to the rest of the matrix:
+*     A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) -
+*                         A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)'.
+*
+      IF( KB.LT.MIN( N, M-OFFSET ) ) THEN
+         CALL ZGEMM( 'No transpose', 'Conjugate transpose', M-RK, N-KB,
+     $               KB, -CONE, A( RK+1, 1 ), LDA, F( KB+1, 1 ), LDF,
+     $               CONE, A( RK+1, KB+1 ), LDA )
+      END IF
+*
+*     Recomputation of difficult columns.
+*
+   60 CONTINUE
+      IF( LSTICC.GT.0 ) THEN
+         ITEMP = NINT( VN2( LSTICC ) )
+         VN1( LSTICC ) = DZNRM2( M-RK, A( RK+1, LSTICC ), 1 )
+*
+*        NOTE: The computation of VN1( LSTICC ) relies on the fact that 
+*        SNRM2 does not fail on vectors with norm below the value of
+*        SQRT(DLAMCH('S')) 
+*
+         VN2( LSTICC ) = VN1( LSTICC )
+         LSTICC = ITEMP
+         GO TO 60
+      END IF
+*
+      RETURN
+*
+*     End of ZLAQPS
+*
+      END
diff --git a/libcruft/lapack/zlaqr0.f b/libcruft/lapack/zlaqr0.f
new file mode 100644
index 0000000..2a35a72
--- /dev/null
+++ b/libcruft/lapack/zlaqr0.f
@@ -0,0 +1,601 @@
+      SUBROUTINE ZLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*
+*     Purpose
+*     =======
+*
+*     ZLAQR0 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**H, where T is an upper triangular matrix (the
+*     Schur form), and Z is the unitary matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input unitary
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*H*(QZ)**H.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to ZGEBAL, and then passed to ZGEHRD when the
+*           matrix output by ZGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) COMPLEX*16 array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H
+*           contains the upper triangular matrix T from the Schur
+*           decomposition (the Schur form). If INFO = 0 and WANT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     W        (output) COMPLEX*16 array, dimension (N)
+*           The computed eigenvalues of H(ILO:IHI,ILO:IHI) are stored
+*           in W(ILO:IHI). If WANTT is .TRUE., then the eigenvalues are
+*           stored in the same order as on the diagonal of the Schur
+*           form returned in H, with W(i) = H(i,i).
+*
+*     Z     (input/output) COMPLEX*16 array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) COMPLEX*16 array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then ZLAQR0 does a workspace query.
+*           In this case, ZLAQR0 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, ZLAQR0 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is a unitary matrix.  The final
+*                value of  H is upper Hessenberg and triangular in
+*                rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    ZLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      DOUBLE PRECISION   WILK1
+      PARAMETER          ( WILK1 = 0.75d0 )
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         AA, BB, CC, CDUM, DD, DET, RTDISC, SWAP, TR2
+      DOUBLE PRECISION   S
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLACPY, ZLAHQR, ZLAQR3, ZLAQR4, ZLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DIMAG, INT, MAX, MIN, MOD,
+     $                   SQRT
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use ZLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL ZLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'ZLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'ZLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to ZLAQR3 ====
+*
+         CALL ZLAQR3( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, W, H, LDH, N, H, LDH, N, H,
+     $                LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(ZLAQR5, ZLAQR3) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+            RETURN
+         END IF
+*
+*        ==== ZLAHQR/ZLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'ZLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'ZLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'ZLAQR0', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 70 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 80
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( CABS1( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      CABS1( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL ZLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, W, H( KV, 1 ), LDH, NHO,
+     $                   H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH, WORK,
+     $                   LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if ZLAQR3
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    ZLAQR3 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, KS + 1, -2
+                     W( I ) = H( I, I ) + WILK1*CABS1( H( I, I-1 ) )
+                     W( I-1 ) = W( I )
+   30             CONTINUE
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use ZLAQR4 or
+*                 .    ZLAHQR on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL ZLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     IF( NS.GT.NMIN ) THEN
+                        CALL ZLAQR4( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, W( KS ), 1, 1,
+     $                               ZDUM, 1, WORK, LWORK, INF )
+                     ELSE
+                        CALL ZLAHQR( .false., .false., NS, 1, NS,
+     $                               H( KT, 1 ), LDH, W( KS ), 1, 1,
+     $                               ZDUM, 1, INF )
+                     END IF
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  Scale to avoid
+*                    .    overflows, underflows and subnormals.
+*                    .    (The scale factor S can not be zero,
+*                    .    because H(KBOT,KBOT-1) is nonzero.) ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        S = CABS1( H( KBOT-1, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT-1, KBOT ) ) +
+     $                      CABS1( H( KBOT, KBOT ) )
+                        AA = H( KBOT-1, KBOT-1 ) / S
+                        CC = H( KBOT, KBOT-1 ) / S
+                        BB = H( KBOT-1, KBOT ) / S
+                        DD = H( KBOT, KBOT ) / S
+                        TR2 = ( AA+DD ) / TWO
+                        DET = ( AA-TR2 )*( DD-TR2 ) - BB*CC
+                        RTDISC = SQRT( -DET )
+                        W( KBOT-1 ) = ( TR2+RTDISC )*S
+                        W( KBOT ) = ( TR2-RTDISC )*S
+*
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little) ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( CABS1( W( I ) ).LT.CABS1( W( I+1 ) ) )
+     $                          THEN
+                              SORTED = .false.
+                              SWAP = W( I )
+                              W( I ) = W( I+1 )
+                              W( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+*
+*              ==== If there are only two shifts, then use
+*              .    only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( CABS1( W( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                CABS1( W( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                     W( KBOT-1 ) = W( KBOT )
+                  ELSE
+                     W( KBOT ) = W( KBOT-1 )
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL ZLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      W( KS ), H, LDH, ILOZ, IHIZ, Z, LDZ, WORK,
+     $                      3, H( KU, 1 ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                      NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   70    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   80    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+*
+*     ==== End of ZLAQR0 ====
+*
+      END
diff --git a/libcruft/lapack/zlaqr1.f b/libcruft/lapack/zlaqr1.f
new file mode 100644
index 0000000..b8c1c3d
--- /dev/null
+++ b/libcruft/lapack/zlaqr1.f
@@ -0,0 +1,97 @@
+      SUBROUTINE ZLAQR1( N, H, LDH, S1, S2, V )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16         S1, S2
+      INTEGER            LDH, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), V( * )
+*     ..
+*
+*       Given a 2-by-2 or 3-by-3 matrix H, ZLAQR1 sets v to a
+*       scalar multiple of the first column of the product
+*
+*       (*)  K = (H - s1*I)*(H - s2*I)
+*
+*       scaling to avoid overflows and most underflows.
+*
+*       This is useful for starting double implicit shift bulges
+*       in the QR algorithm.
+*
+*
+*       N      (input) integer
+*              Order of the matrix H. N must be either 2 or 3.
+*
+*       H      (input) COMPLEX*16 array of dimension (LDH,N)
+*              The 2-by-2 or 3-by-3 matrix H in (*).
+*
+*       LDH    (input) integer
+*              The leading dimension of H as declared in
+*              the calling procedure.  LDH.GE.N
+*
+*       S1     (input) COMPLEX*16
+*       S2     S1 and S2 are the shifts defining K in (*) above.
+*
+*       V      (output) COMPLEX*16 array of dimension N
+*              A scalar multiple of the first column of the
+*              matrix K in (*).
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   RZERO
+      PARAMETER          ( RZERO = 0.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         CDUM
+      DOUBLE PRECISION   H21S, H31S, S
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+      IF( N.EQ.2 ) THEN
+         S = CABS1( H( 1, 1 )-S2 ) + CABS1( H( 2, 1 ) )
+         IF( S.EQ.RZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            V( 1 ) = H21S*H( 1, 2 ) + ( H( 1, 1 )-S1 )*
+     $               ( ( H( 1, 1 )-S2 ) / S )
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-S1-S2 )
+         END IF
+      ELSE
+         S = CABS1( H( 1, 1 )-S2 ) + CABS1( H( 2, 1 ) ) +
+     $       CABS1( H( 3, 1 ) )
+         IF( S.EQ.ZERO ) THEN
+            V( 1 ) = ZERO
+            V( 2 ) = ZERO
+            V( 3 ) = ZERO
+         ELSE
+            H21S = H( 2, 1 ) / S
+            H31S = H( 3, 1 ) / S
+            V( 1 ) = ( H( 1, 1 )-S1 )*( ( H( 1, 1 )-S2 ) / S ) +
+     $               H( 1, 2 )*H21S + H( 1, 3 )*H31S
+            V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-S1-S2 ) + H( 2, 3 )*H31S
+            V( 3 ) = H31S*( H( 1, 1 )+H( 3, 3 )-S1-S2 ) + H21S*H( 3, 2 )
+         END IF
+      END IF
+      END
diff --git a/libcruft/lapack/zlaqr2.f b/libcruft/lapack/zlaqr2.f
new file mode 100644
index 0000000..0add51a
--- /dev/null
+++ b/libcruft/lapack/zlaqr2.f
@@ -0,0 +1,437 @@
+      SUBROUTINE ZLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
+     $                   NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), SH( * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( * ), WV( LDWV, * ), Z( LDZ, * )
+*     ..
+*
+*     This subroutine is identical to ZLAQR3 except that it avoids
+*     recursion by calling ZLAHQR instead of ZLAQR4.
+*
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an unitary similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an unitary similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the unitary matrix Z is updated so
+*          so that the unitary Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the unitary matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) COMPLEX*16 array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by a unitary
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) COMPLEX*16 array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the unitary
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SH      (output) COMPLEX*16 array, dimension KBOT
+*          On output, approximate eigenvalues that may
+*          be used for shifts are stored in SH(KBOT-ND-NS+1)
+*          through SR(KBOT-ND).  Converged eigenvalues are
+*          stored in SH(KBOT-ND+1) through SH(KBOT).
+*
+*     V       (workspace) COMPLEX*16 array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) COMPLEX*16 array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) COMPLEX*16 array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) COMPLEX*16 array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; ZLAQR2
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   RZERO, RONE
+      PARAMETER          ( RZERO = 0.0d0, RONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         BETA, CDUM, S, TAU
+      DOUBLE PRECISION   FOO, SAFMAX, SAFMIN, SMLNUM, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, KCOL, KLN,
+     $                   KNT, KROW, KWTOP, LTOP, LWK1, LWK2, LWKOPT
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, ZCOPY, ZGEHRD, ZGEMM, ZLACPY, ZLAHQR,
+     $                   ZLARF, ZLARFG, ZLASET, ZTREXC, ZUNGHR
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, INT, MAX, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to ZGEHRD ====
+*
+         CALL ZGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to ZUNGHR ====
+*
+         CALL ZUNGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = JW + MAX( LWK1, LWK2 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SH( KWTOP ) = H( KWTOP, KWTOP )
+         NS = 1
+         ND = 0
+         IF( CABS1( S ).LE.MAX( SMLNUM, ULP*CABS1( H( KWTOP,
+     $       KWTOP ) ) ) ) THEN
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL ZLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL ZCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL ZLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      CALL ZLAHQR( .true., .true., JW, 1, JW, T, LDT, SH( KWTOP ), 1,
+     $             JW, V, LDV, INFQR )
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+      DO 10 KNT = INFQR + 1, JW
+*
+*        ==== Small spike tip deflation test ====
+*
+         FOO = CABS1( T( NS, NS ) )
+         IF( FOO.EQ.RZERO )
+     $      FOO = CABS1( S )
+         IF( CABS1( S )*CABS1( V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) )
+     $        THEN
+*
+*           ==== One more converged eigenvalue ====
+*
+            NS = NS - 1
+         ELSE
+*
+*           ==== One undflatable eigenvalue.  Move it up out of the
+*           .    way.   (ZTREXC can not fail in this case.) ====
+*
+            IFST = NS
+            CALL ZTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+            ILST = ILST + 1
+         END IF
+   10 CONTINUE
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting the diagonal of T improves accuracy for
+*        .    graded matrices.  ====
+*
+         DO 30 I = INFQR + 1, NS
+            IFST = I
+            DO 20 J = I + 1, NS
+               IF( CABS1( T( J, J ) ).GT.CABS1( T( IFST, IFST ) ) )
+     $            IFST = J
+   20       CONTINUE
+            ILST = I
+            IF( IFST.NE.ILST )
+     $         CALL ZTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+   30    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      DO 40 I = INFQR + 1, JW
+         SH( KWTOP+I-1 ) = T( I, I )
+   40 CONTINUE
+*
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL ZCOPY( NS, V, LDV, WORK, 1 )
+            DO 50 I = 1, NS
+               WORK( I ) = DCONJG( WORK( I ) )
+   50       CONTINUE
+            BETA = WORK( 1 )
+            CALL ZLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL ZLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL ZLARF( 'L', NS, JW, WORK, 1, DCONJG( TAU ), T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL ZLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL ZLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL ZGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*DCONJG( V( 1, 1 ) )
+         CALL ZLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL ZCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  ZUNGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL ZUNGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL ZGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL ZLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 60 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL ZGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL ZLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   60    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 70 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL ZGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL ZLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   70       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 80 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL ZGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL ZLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   80       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+*
+*     ==== End of ZLAQR2 ====
+*
+      END
diff --git a/libcruft/lapack/zlaqr3.f b/libcruft/lapack/zlaqr3.f
new file mode 100644
index 0000000..e9bf393
--- /dev/null
+++ b/libcruft/lapack/zlaqr3.f
@@ -0,0 +1,448 @@
+      SUBROUTINE ZLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
+     $                   NV, WV, LDWV, WORK, LWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
+     $                   LDZ, LWORK, N, ND, NH, NS, NV, NW
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), SH( * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( * ), WV( LDWV, * ), Z( LDZ, * )
+*     ..
+*
+*     ******************************************************************
+*     Aggressive early deflation:
+*
+*     This subroutine accepts as input an upper Hessenberg matrix
+*     H and performs an unitary similarity transformation
+*     designed to detect and deflate fully converged eigenvalues from
+*     a trailing principal submatrix.  On output H has been over-
+*     written by a new Hessenberg matrix that is a perturbation of
+*     an unitary similarity transformation of H.  It is to be
+*     hoped that the final version of H has many zero subdiagonal
+*     entries.
+*
+*     ******************************************************************
+*     WANTT   (input) LOGICAL
+*          If .TRUE., then the Hessenberg matrix H is fully updated
+*          so that the triangular Schur factor may be
+*          computed (in cooperation with the calling subroutine).
+*          If .FALSE., then only enough of H is updated to preserve
+*          the eigenvalues.
+*
+*     WANTZ   (input) LOGICAL
+*          If .TRUE., then the unitary matrix Z is updated so
+*          so that the unitary Schur factor may be computed
+*          (in cooperation with the calling subroutine).
+*          If .FALSE., then Z is not referenced.
+*
+*     N       (input) INTEGER
+*          The order of the matrix H and (if WANTZ is .TRUE.) the
+*          order of the unitary matrix Z.
+*
+*     KTOP    (input) INTEGER
+*          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
+*          KBOT and KTOP together determine an isolated block
+*          along the diagonal of the Hessenberg matrix.
+*
+*     KBOT    (input) INTEGER
+*          It is assumed without a check that either
+*          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
+*          determine an isolated block along the diagonal of the
+*          Hessenberg matrix.
+*
+*     NW      (input) INTEGER
+*          Deflation window size.  1 .LE. NW .LE. (KBOT-KTOP+1).
+*
+*     H       (input/output) COMPLEX*16 array, dimension (LDH,N)
+*          On input the initial N-by-N section of H stores the
+*          Hessenberg matrix undergoing aggressive early deflation.
+*          On output H has been transformed by a unitary
+*          similarity transformation, perturbed, and the returned
+*          to Hessenberg form that (it is to be hoped) has some
+*          zero subdiagonal entries.
+*
+*     LDH     (input) integer
+*          Leading dimension of H just as declared in the calling
+*          subroutine.  N .LE. LDH
+*
+*     ILOZ    (input) INTEGER
+*     IHIZ    (input) INTEGER
+*          Specify the rows of Z to which transformations must be
+*          applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.
+*
+*     Z       (input/output) COMPLEX*16 array, dimension (LDZ,IHI)
+*          IF WANTZ is .TRUE., then on output, the unitary
+*          similarity transformation mentioned above has been
+*          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*          If WANTZ is .FALSE., then Z is unreferenced.
+*
+*     LDZ     (input) integer
+*          The leading dimension of Z just as declared in the
+*          calling subroutine.  1 .LE. LDZ.
+*
+*     NS      (output) integer
+*          The number of unconverged (ie approximate) eigenvalues
+*          returned in SR and SI that may be used as shifts by the
+*          calling subroutine.
+*
+*     ND      (output) integer
+*          The number of converged eigenvalues uncovered by this
+*          subroutine.
+*
+*     SH      (output) COMPLEX*16 array, dimension KBOT
+*          On output, approximate eigenvalues that may
+*          be used for shifts are stored in SH(KBOT-ND-NS+1)
+*          through SR(KBOT-ND).  Converged eigenvalues are
+*          stored in SH(KBOT-ND+1) through SH(KBOT).
+*
+*     V       (workspace) COMPLEX*16 array, dimension (LDV,NW)
+*          An NW-by-NW work array.
+*
+*     LDV     (input) integer scalar
+*          The leading dimension of V just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     NH      (input) integer scalar
+*          The number of columns of T.  NH.GE.NW.
+*
+*     T       (workspace) COMPLEX*16 array, dimension (LDT,NW)
+*
+*     LDT     (input) integer
+*          The leading dimension of T just as declared in the
+*          calling subroutine.  NW .LE. LDT
+*
+*     NV      (input) integer
+*          The number of rows of work array WV available for
+*          workspace.  NV.GE.NW.
+*
+*     WV      (workspace) COMPLEX*16 array, dimension (LDWV,NW)
+*
+*     LDWV    (input) integer
+*          The leading dimension of W just as declared in the
+*          calling subroutine.  NW .LE. LDV
+*
+*     WORK    (workspace) COMPLEX*16 array, dimension LWORK.
+*          On exit, WORK(1) is set to an estimate of the optimal value
+*          of LWORK for the given values of N, NW, KTOP and KBOT.
+*
+*     LWORK   (input) integer
+*          The dimension of the work array WORK.  LWORK = 2*NW
+*          suffices, but greater efficiency may result from larger
+*          values of LWORK.
+*
+*          If LWORK = -1, then a workspace query is assumed; ZLAQR3
+*          only estimates the optimal workspace size for the given
+*          values of N, NW, KTOP and KBOT.  The estimate is returned
+*          in WORK(1).  No error message related to LWORK is issued
+*          by XERBLA.  Neither H nor Z are accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ==================================================================
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   RZERO, RONE
+      PARAMETER          ( RZERO = 0.0d0, RONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         BETA, CDUM, S, TAU
+      DOUBLE PRECISION   FOO, SAFMAX, SAFMIN, SMLNUM, ULP
+      INTEGER            I, IFST, ILST, INFO, INFQR, J, JW, KCOL, KLN,
+     $                   KNT, KROW, KWTOP, LTOP, LWK1, LWK2, LWK3,
+     $                   LWKOPT, NMIN
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      INTEGER            ILAENV
+      EXTERNAL           DLAMCH, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, ZCOPY, ZGEHRD, ZGEMM, ZLACPY, ZLAHQR,
+     $                   ZLAQR4, ZLARF, ZLARFG, ZLASET, ZTREXC, ZUNGHR
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, INT, MAX, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== Estimate optimal workspace. ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      IF( JW.LE.2 ) THEN
+         LWKOPT = 1
+      ELSE
+*
+*        ==== Workspace query call to ZGEHRD ====
+*
+         CALL ZGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK1 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to ZUNGHR ====
+*
+         CALL ZUNGHR( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )
+         LWK2 = INT( WORK( 1 ) )
+*
+*        ==== Workspace query call to ZLAQR4 ====
+*
+         CALL ZLAQR4( .true., .true., JW, 1, JW, T, LDT, SH, 1, JW, V,
+     $                LDV, WORK, -1, INFQR )
+         LWK3 = INT( WORK( 1 ) )
+*
+*        ==== Optimal workspace ====
+*
+         LWKOPT = MAX( JW+MAX( LWK1, LWK2 ), LWK3 )
+      END IF
+*
+*     ==== Quick return in case of workspace query. ====
+*
+      IF( LWORK.EQ.-1 ) THEN
+         WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+         RETURN
+      END IF
+*
+*     ==== Nothing to do ...
+*     ... for an empty active block ... ====
+      NS = 0
+      ND = 0
+      IF( KTOP.GT.KBOT )
+     $   RETURN
+*     ... nor for an empty deflation window. ====
+      IF( NW.LT.1 )
+     $   RETURN
+*
+*     ==== Machine constants ====
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( N ) / ULP )
+*
+*     ==== Setup deflation window ====
+*
+      JW = MIN( NW, KBOT-KTOP+1 )
+      KWTOP = KBOT - JW + 1
+      IF( KWTOP.EQ.KTOP ) THEN
+         S = ZERO
+      ELSE
+         S = H( KWTOP, KWTOP-1 )
+      END IF
+*
+      IF( KBOT.EQ.KWTOP ) THEN
+*
+*        ==== 1-by-1 deflation window: not much to do ====
+*
+         SH( KWTOP ) = H( KWTOP, KWTOP )
+         NS = 1
+         ND = 0
+         IF( CABS1( S ).LE.MAX( SMLNUM, ULP*CABS1( H( KWTOP,
+     $       KWTOP ) ) ) ) THEN
+
+            NS = 0
+            ND = 1
+            IF( KWTOP.GT.KTOP )
+     $         H( KWTOP, KWTOP-1 ) = ZERO
+         END IF
+         RETURN
+      END IF
+*
+*     ==== Convert to spike-triangular form.  (In case of a
+*     .    rare QR failure, this routine continues to do
+*     .    aggressive early deflation using that part of
+*     .    the deflation window that converged using INFQR
+*     .    here and there to keep track.) ====
+*
+      CALL ZLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )
+      CALL ZCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )
+*
+      CALL ZLASET( 'A', JW, JW, ZERO, ONE, V, LDV )
+      NMIN = ILAENV( 12, 'ZLAQR3', 'SV', JW, 1, JW, LWORK )
+      IF( JW.GT.NMIN ) THEN
+         CALL ZLAQR4( .true., .true., JW, 1, JW, T, LDT, SH( KWTOP ), 1,
+     $                JW, V, LDV, WORK, LWORK, INFQR )
+      ELSE
+         CALL ZLAHQR( .true., .true., JW, 1, JW, T, LDT, SH( KWTOP ), 1,
+     $                JW, V, LDV, INFQR )
+      END IF
+*
+*     ==== Deflation detection loop ====
+*
+      NS = JW
+      ILST = INFQR + 1
+      DO 10 KNT = INFQR + 1, JW
+*
+*        ==== Small spike tip deflation test ====
+*
+         FOO = CABS1( T( NS, NS ) )
+         IF( FOO.EQ.RZERO )
+     $      FOO = CABS1( S )
+         IF( CABS1( S )*CABS1( V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) )
+     $        THEN
+*
+*           ==== One more converged eigenvalue ====
+*
+            NS = NS - 1
+         ELSE
+*
+*           ==== One undflatable eigenvalue.  Move it up out of the
+*           .    way.   (ZTREXC can not fail in this case.) ====
+*
+            IFST = NS
+            CALL ZTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+            ILST = ILST + 1
+         END IF
+   10 CONTINUE
+*
+*        ==== Return to Hessenberg form ====
+*
+      IF( NS.EQ.0 )
+     $   S = ZERO
+*
+      IF( NS.LT.JW ) THEN
+*
+*        ==== sorting the diagonal of T improves accuracy for
+*        .    graded matrices.  ====
+*
+         DO 30 I = INFQR + 1, NS
+            IFST = I
+            DO 20 J = I + 1, NS
+               IF( CABS1( T( J, J ) ).GT.CABS1( T( IFST, IFST ) ) )
+     $            IFST = J
+   20       CONTINUE
+            ILST = I
+            IF( IFST.NE.ILST )
+     $         CALL ZTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, INFO )
+   30    CONTINUE
+      END IF
+*
+*     ==== Restore shift/eigenvalue array from T ====
+*
+      DO 40 I = INFQR + 1, JW
+         SH( KWTOP+I-1 ) = T( I, I )
+   40 CONTINUE
+*
+*
+      IF( NS.LT.JW .OR. S.EQ.ZERO ) THEN
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+*
+*           ==== Reflect spike back into lower triangle ====
+*
+            CALL ZCOPY( NS, V, LDV, WORK, 1 )
+            DO 50 I = 1, NS
+               WORK( I ) = DCONJG( WORK( I ) )
+   50       CONTINUE
+            BETA = WORK( 1 )
+            CALL ZLARFG( NS, BETA, WORK( 2 ), 1, TAU )
+            WORK( 1 ) = ONE
+*
+            CALL ZLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )
+*
+            CALL ZLARF( 'L', NS, JW, WORK, 1, DCONJG( TAU ), T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL ZLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,
+     $                  WORK( JW+1 ) )
+            CALL ZLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,
+     $                  WORK( JW+1 ) )
+*
+            CALL ZGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+         END IF
+*
+*        ==== Copy updated reduced window into place ====
+*
+         IF( KWTOP.GT.1 )
+     $      H( KWTOP, KWTOP-1 ) = S*DCONJG( V( 1, 1 ) )
+         CALL ZLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )
+         CALL ZCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),
+     $               LDH+1 )
+*
+*        ==== Accumulate orthogonal matrix in order update
+*        .    H and Z, if requested.  (A modified version
+*        .    of  ZUNGHR that accumulates block Householder
+*        .    transformations into V directly might be
+*        .    marginally more efficient than the following.) ====
+*
+         IF( NS.GT.1 .AND. S.NE.ZERO ) THEN
+            CALL ZUNGHR( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),
+     $                   LWORK-JW, INFO )
+            CALL ZGEMM( 'N', 'N', JW, NS, NS, ONE, V, LDV, T, LDT, ZERO,
+     $                  WV, LDWV )
+            CALL ZLACPY( 'A', JW, NS, WV, LDWV, V, LDV )
+         END IF
+*
+*        ==== Update vertical slab in H ====
+*
+         IF( WANTT ) THEN
+            LTOP = 1
+         ELSE
+            LTOP = KTOP
+         END IF
+         DO 60 KROW = LTOP, KWTOP - 1, NV
+            KLN = MIN( NV, KWTOP-KROW )
+            CALL ZGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),
+     $                  LDH, V, LDV, ZERO, WV, LDWV )
+            CALL ZLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )
+   60    CONTINUE
+*
+*        ==== Update horizontal slab in H ====
+*
+         IF( WANTT ) THEN
+            DO 70 KCOL = KBOT + 1, N, NH
+               KLN = MIN( NH, N-KCOL+1 )
+               CALL ZGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,
+     $                     H( KWTOP, KCOL ), LDH, ZERO, T, LDT )
+               CALL ZLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),
+     $                      LDH )
+   70       CONTINUE
+         END IF
+*
+*        ==== Update vertical slab in Z ====
+*
+         IF( WANTZ ) THEN
+            DO 80 KROW = ILOZ, IHIZ, NV
+               KLN = MIN( NV, IHIZ-KROW+1 )
+               CALL ZGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),
+     $                     LDZ, V, LDV, ZERO, WV, LDWV )
+               CALL ZLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),
+     $                      LDZ )
+   80       CONTINUE
+         END IF
+      END IF
+*
+*     ==== Return the number of deflations ... ====
+*
+      ND = JW - NS
+*
+*     ==== ... and the number of shifts. (Subtracting
+*     .    INFQR from the spike length takes care
+*     .    of the case of a rare QR failure while
+*     .    calculating eigenvalues of the deflation
+*     .    window.)  ====
+*
+      NS = NS - INFQR
+*
+*      ==== Return optimal workspace. ====
+*
+      WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+*
+*     ==== End of ZLAQR3 ====
+*
+      END
diff --git a/libcruft/lapack/zlaqr4.f b/libcruft/lapack/zlaqr4.f
new file mode 100644
index 0000000..eef7f00
--- /dev/null
+++ b/libcruft/lapack/zlaqr4.f
@@ -0,0 +1,602 @@
+      SUBROUTINE ZLAQR4( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, WORK, LWORK, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )
+*     ..
+*
+*     This subroutine implements one level of recursion for ZLAQR0.
+*     It is a complete implementation of the small bulge multi-shift
+*     QR algorithm.  It may be called by ZLAQR0 and, for large enough
+*     deflation window size, it may be called by ZLAQR3.  This
+*     subroutine is identical to ZLAQR0 except that it calls ZLAQR2
+*     instead of ZLAQR3.
+*
+*     Purpose
+*     =======
+*
+*     ZLAQR4 computes the eigenvalues of a Hessenberg matrix H
+*     and, optionally, the matrices T and Z from the Schur decomposition
+*     H = Z T Z**H, where T is an upper triangular matrix (the
+*     Schur form), and Z is the unitary matrix of Schur vectors.
+*
+*     Optionally Z may be postmultiplied into an input unitary
+*     matrix Q so that this routine can give the Schur factorization
+*     of a matrix A which has been reduced to the Hessenberg form H
+*     by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*H*(QZ)**H.
+*
+*     Arguments
+*     =========
+*
+*     WANTT   (input) LOGICAL
+*          = .TRUE. : the full Schur form T is required;
+*          = .FALSE.: only eigenvalues are required.
+*
+*     WANTZ   (input) LOGICAL
+*          = .TRUE. : the matrix of Schur vectors Z is required;
+*          = .FALSE.: Schur vectors are not required.
+*
+*     N     (input) INTEGER
+*           The order of the matrix H.  N .GE. 0.
+*
+*     ILO   (input) INTEGER
+*     IHI   (input) INTEGER
+*           It is assumed that H is already upper triangular in rows
+*           and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,
+*           H(ILO,ILO-1) is zero. ILO and IHI are normally set by a
+*           previous call to ZGEBAL, and then passed to ZGEHRD when the
+*           matrix output by ZGEBAL is reduced to Hessenberg form.
+*           Otherwise, ILO and IHI should be set to 1 and N,
+*           respectively.  If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.
+*           If N = 0, then ILO = 1 and IHI = 0.
+*
+*     H     (input/output) COMPLEX*16 array, dimension (LDH,N)
+*           On entry, the upper Hessenberg matrix H.
+*           On exit, if INFO = 0 and WANTT is .TRUE., then H
+*           contains the upper triangular matrix T from the Schur
+*           decomposition (the Schur form). If INFO = 0 and WANT is
+*           .FALSE., then the contents of H are unspecified on exit.
+*           (The output value of H when INFO.GT.0 is given under the
+*           description of INFO below.)
+*
+*           This subroutine may explicitly set H(i,j) = 0 for i.GT.j and
+*           j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.
+*
+*     LDH   (input) INTEGER
+*           The leading dimension of the array H. LDH .GE. max(1,N).
+*
+*     W        (output) COMPLEX*16 array, dimension (N)
+*           The computed eigenvalues of H(ILO:IHI,ILO:IHI) are stored
+*           in W(ILO:IHI). If WANTT is .TRUE., then the eigenvalues are
+*           stored in the same order as on the diagonal of the Schur
+*           form returned in H, with W(i) = H(i,i).
+*
+*     Z     (input/output) COMPLEX*16 array, dimension (LDZ,IHI)
+*           If WANTZ is .FALSE., then Z is not referenced.
+*           If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is
+*           replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the
+*           orthogonal Schur factor of H(ILO:IHI,ILO:IHI).
+*           (The output value of Z when INFO.GT.0 is given under
+*           the description of INFO below.)
+*
+*     LDZ   (input) INTEGER
+*           The leading dimension of the array Z.  if WANTZ is .TRUE.
+*           then LDZ.GE.MAX(1,IHIZ).  Otherwize, LDZ.GE.1.
+*
+*     WORK  (workspace/output) COMPLEX*16 array, dimension LWORK
+*           On exit, if LWORK = -1, WORK(1) returns an estimate of
+*           the optimal value for LWORK.
+*
+*     LWORK (input) INTEGER
+*           The dimension of the array WORK.  LWORK .GE. max(1,N)
+*           is sufficient, but LWORK typically as large as 6*N may
+*           be required for optimal performance.  A workspace query
+*           to determine the optimal workspace size is recommended.
+*
+*           If LWORK = -1, then ZLAQR4 does a workspace query.
+*           In this case, ZLAQR4 checks the input parameters and
+*           estimates the optimal workspace size for the given
+*           values of N, ILO and IHI.  The estimate is returned
+*           in WORK(1).  No error message related to LWORK is
+*           issued by XERBLA.  Neither H nor Z are accessed.
+*
+*
+*     INFO  (output) INTEGER
+*             =  0:  successful exit
+*           .GT. 0:  if INFO = i, ZLAQR4 failed to compute all of
+*                the eigenvalues.  Elements 1:ilo-1 and i+1:n of WR
+*                and WI contain those eigenvalues which have been
+*                successfully computed.  (Failures are rare.)
+*
+*                If INFO .GT. 0 and WANT is .FALSE., then on exit,
+*                the remaining unconverged eigenvalues are the eigen-
+*                values of the upper Hessenberg matrix rows and
+*                columns ILO through INFO of the final, output
+*                value of H.
+*
+*                If INFO .GT. 0 and WANTT is .TRUE., then on exit
+*
+*           (*)  (initial value of H)*U  = U*(final value of H)
+*
+*                where U is a unitary matrix.  The final
+*                value of  H is upper Hessenberg and triangular in
+*                rows and columns INFO+1 through IHI.
+*
+*                If INFO .GT. 0 and WANTZ is .TRUE., then on exit
+*
+*                  (final value of Z(ILO:IHI,ILOZ:IHIZ)
+*                   =  (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U
+*
+*                where U is the unitary matrix in (*) (regard-
+*                less of the value of WANTT.)
+*
+*                If INFO .GT. 0 and WANTZ is .FALSE., then Z is not
+*                accessed.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*     ================================================================
+*     References:
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part I: Maintaining Well Focused Shifts, and Level 3
+*       Performance, SIAM Journal of Matrix Analysis, volume 23, pages
+*       929--947, 2002.
+*
+*       K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*       Algorithm Part II: Aggressive Early Deflation, SIAM Journal
+*       of Matrix Analysis, volume 23, pages 948--973, 2002.
+*
+*     ================================================================
+*     .. Parameters ..
+*
+*     ==== Matrices of order NTINY or smaller must be processed by
+*     .    ZLAHQR because of insufficient subdiagonal scratch space.
+*     .    (This is a hard limit.) ====
+*
+*     ==== Exceptional deflation windows:  try to cure rare
+*     .    slow convergence by increasing the size of the
+*     .    deflation window after KEXNW iterations. =====
+*
+*     ==== Exceptional shifts: try to cure rare slow convergence
+*     .    with ad-hoc exceptional shifts every KEXSH iterations.
+*     .    The constants WILK1 and WILK2 are used to form the
+*     .    exceptional shifts. ====
+*
+      INTEGER            NTINY
+      PARAMETER          ( NTINY = 11 )
+      INTEGER            KEXNW, KEXSH
+      PARAMETER          ( KEXNW = 5, KEXSH = 6 )
+      DOUBLE PRECISION   WILK1
+      PARAMETER          ( WILK1 = 0.75d0 )
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   TWO
+      PARAMETER          ( TWO = 2.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         AA, BB, CC, CDUM, DD, DET, RTDISC, SWAP, TR2
+      DOUBLE PRECISION   S
+      INTEGER            I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,
+     $                   KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,
+     $                   LWKOPT, NDFL, NH, NHO, NIBBLE, NMIN, NS, NSMAX,
+     $                   NSR, NVE, NW, NWMAX, NWR
+      LOGICAL            NWINC, SORTED
+      CHARACTER          JBCMPZ*2
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         ZDUM( 1, 1 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLACPY, ZLAHQR, ZLAQR2, ZLAQR5
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DIMAG, INT, MAX, MIN, MOD,
+     $                   SQRT
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+      INFO = 0
+*
+*     ==== Quick return for N = 0: nothing to do. ====
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = ONE
+         RETURN
+      END IF
+*
+*     ==== Set up job flags for ILAENV. ====
+*
+      IF( WANTT ) THEN
+         JBCMPZ( 1: 1 ) = 'S'
+      ELSE
+         JBCMPZ( 1: 1 ) = 'E'
+      END IF
+      IF( WANTZ ) THEN
+         JBCMPZ( 2: 2 ) = 'V'
+      ELSE
+         JBCMPZ( 2: 2 ) = 'N'
+      END IF
+*
+*     ==== Tiny matrices must use ZLAHQR. ====
+*
+      IF( N.LE.NTINY ) THEN
+*
+*        ==== Estimate optimal workspace. ====
+*
+         LWKOPT = 1
+         IF( LWORK.NE.-1 )
+     $      CALL ZLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILOZ,
+     $                   IHIZ, Z, LDZ, INFO )
+      ELSE
+*
+*        ==== Use small bulge multi-shift QR with aggressive early
+*        .    deflation on larger-than-tiny matrices. ====
+*
+*        ==== Hope for the best. ====
+*
+         INFO = 0
+*
+*        ==== NWR = recommended deflation window size.  At this
+*        .    point,  N .GT. NTINY = 11, so there is enough
+*        .    subdiagonal workspace for NWR.GE.2 as required.
+*        .    (In fact, there is enough subdiagonal space for
+*        .    NWR.GE.3.) ====
+*
+         NWR = ILAENV( 13, 'ZLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NWR = MAX( 2, NWR )
+         NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )
+         NW = NWR
+*
+*        ==== NSR = recommended number of simultaneous shifts.
+*        .    At this point N .GT. NTINY = 11, so there is at
+*        .    enough subdiagonal workspace for NSR to be even
+*        .    and greater than or equal to two as required. ====
+*
+         NSR = ILAENV( 15, 'ZLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )
+         NSR = MAX( 2, NSR-MOD( NSR, 2 ) )
+*
+*        ==== Estimate optimal workspace ====
+*
+*        ==== Workspace query call to ZLAQR2 ====
+*
+         CALL ZLAQR2( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,
+     $                IHIZ, Z, LDZ, LS, LD, W, H, LDH, N, H, LDH, N, H,
+     $                LDH, WORK, -1 )
+*
+*        ==== Optimal workspace = MAX(ZLAQR5, ZLAQR2) ====
+*
+         LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )
+*
+*        ==== Quick return in case of workspace query. ====
+*
+         IF( LWORK.EQ.-1 ) THEN
+            WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+            RETURN
+         END IF
+*
+*        ==== ZLAHQR/ZLAQR0 crossover point ====
+*
+         NMIN = ILAENV( 12, 'ZLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NMIN = MAX( NTINY, NMIN )
+*
+*        ==== Nibble crossover point ====
+*
+         NIBBLE = ILAENV( 14, 'ZLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         NIBBLE = MAX( 0, NIBBLE )
+*
+*        ==== Accumulate reflections during ttswp?  Use block
+*        .    2-by-2 structure during matrix-matrix multiply? ====
+*
+         KACC22 = ILAENV( 16, 'ZLAQR4', JBCMPZ, N, ILO, IHI, LWORK )
+         KACC22 = MAX( 0, KACC22 )
+         KACC22 = MIN( 2, KACC22 )
+*
+*        ==== NWMAX = the largest possible deflation window for
+*        .    which there is sufficient workspace. ====
+*
+         NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )
+*
+*        ==== NSMAX = the Largest number of simultaneous shifts
+*        .    for which there is sufficient workspace. ====
+*
+         NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )
+         NSMAX = NSMAX - MOD( NSMAX, 2 )
+*
+*        ==== NDFL: an iteration count restarted at deflation. ====
+*
+         NDFL = 1
+*
+*        ==== ITMAX = iteration limit ====
+*
+         ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )
+*
+*        ==== Last row and column in the active block ====
+*
+         KBOT = IHI
+*
+*        ==== Main Loop ====
+*
+         DO 70 IT = 1, ITMAX
+*
+*           ==== Done when KBOT falls below ILO ====
+*
+            IF( KBOT.LT.ILO )
+     $         GO TO 80
+*
+*           ==== Locate active block ====
+*
+            DO 10 K = KBOT, ILO + 1, -1
+               IF( H( K, K-1 ).EQ.ZERO )
+     $            GO TO 20
+   10       CONTINUE
+            K = ILO
+   20       CONTINUE
+            KTOP = K
+*
+*           ==== Select deflation window size ====
+*
+            NH = KBOT - KTOP + 1
+            IF( NDFL.LT.KEXNW .OR. NH.LT.NW ) THEN
+*
+*              ==== Typical deflation window.  If possible and
+*              .    advisable, nibble the entire active block.
+*              .    If not, use size NWR or NWR+1 depending upon
+*              .    which has the smaller corresponding subdiagonal
+*              .    entry (a heuristic). ====
+*
+               NWINC = .TRUE.
+               IF( NH.LE.MIN( NMIN, NWMAX ) ) THEN
+                  NW = NH
+               ELSE
+                  NW = MIN( NWR, NH, NWMAX )
+                  IF( NW.LT.NWMAX ) THEN
+                     IF( NW.GE.NH-1 ) THEN
+                        NW = NH
+                     ELSE
+                        KWTOP = KBOT - NW + 1
+                        IF( CABS1( H( KWTOP, KWTOP-1 ) ).GT.
+     $                      CABS1( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1
+                     END IF
+                  END IF
+               END IF
+            ELSE
+*
+*              ==== Exceptional deflation window.  If there have
+*              .    been no deflations in KEXNW or more iterations,
+*              .    then vary the deflation window size.   At first,
+*              .    because, larger windows are, in general, more
+*              .    powerful than smaller ones, rapidly increase the
+*              .    window up to the maximum reasonable and possible.
+*              .    Then maybe try a slightly smaller window.  ====
+*
+               IF( NWINC .AND. NW.LT.MIN( NWMAX, NH ) ) THEN
+                  NW = MIN( NWMAX, NH, 2*NW )
+               ELSE
+                  NWINC = .FALSE.
+                  IF( NW.EQ.NH .AND. NH.GT.2 )
+     $               NW = NH - 1
+               END IF
+            END IF
+*
+*           ==== Aggressive early deflation:
+*           .    split workspace under the subdiagonal into
+*           .      - an nw-by-nw work array V in the lower
+*           .        left-hand-corner,
+*           .      - an NW-by-at-least-NW-but-more-is-better
+*           .        (NW-by-NHO) horizontal work array along
+*           .        the bottom edge,
+*           .      - an at-least-NW-but-more-is-better (NHV-by-NW)
+*           .        vertical work array along the left-hand-edge.
+*           .        ====
+*
+            KV = N - NW + 1
+            KT = NW + 1
+            NHO = ( N-NW-1 ) - KT + 1
+            KWV = NW + 2
+            NVE = ( N-NW ) - KWV + 1
+*
+*           ==== Aggressive early deflation ====
+*
+            CALL ZLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
+     $                   IHIZ, Z, LDZ, LS, LD, W, H( KV, 1 ), LDH, NHO,
+     $                   H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH, WORK,
+     $                   LWORK )
+*
+*           ==== Adjust KBOT accounting for new deflations. ====
+*
+            KBOT = KBOT - LD
+*
+*           ==== KS points to the shifts. ====
+*
+            KS = KBOT - LS + 1
+*
+*           ==== Skip an expensive QR sweep if there is a (partly
+*           .    heuristic) reason to expect that many eigenvalues
+*           .    will deflate without it.  Here, the QR sweep is
+*           .    skipped if many eigenvalues have just been deflated
+*           .    or if the remaining active block is small.
+*
+            IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-
+     $          KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN
+*
+*              ==== NS = nominal number of simultaneous shifts.
+*              .    This may be lowered (slightly) if ZLAQR2
+*              .    did not provide that many shifts. ====
+*
+               NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )
+               NS = NS - MOD( NS, 2 )
+*
+*              ==== If there have been no deflations
+*              .    in a multiple of KEXSH iterations,
+*              .    then try exceptional shifts.
+*              .    Otherwise use shifts provided by
+*              .    ZLAQR2 above or from the eigenvalues
+*              .    of a trailing principal submatrix. ====
+*
+               IF( MOD( NDFL, KEXSH ).EQ.0 ) THEN
+                  KS = KBOT - NS + 1
+                  DO 30 I = KBOT, KS + 1, -2
+                     W( I ) = H( I, I ) + WILK1*CABS1( H( I, I-1 ) )
+                     W( I-1 ) = W( I )
+   30             CONTINUE
+               ELSE
+*
+*                 ==== Got NS/2 or fewer shifts? Use ZLAHQR
+*                 .    on a trailing principal submatrix to
+*                 .    get more. (Since NS.LE.NSMAX.LE.(N+6)/9,
+*                 .    there is enough space below the subdiagonal
+*                 .    to fit an NS-by-NS scratch array.) ====
+*
+                  IF( KBOT-KS+1.LE.NS / 2 ) THEN
+                     KS = KBOT - NS + 1
+                     KT = N - NS + 1
+                     CALL ZLACPY( 'A', NS, NS, H( KS, KS ), LDH,
+     $                            H( KT, 1 ), LDH )
+                     CALL ZLAHQR( .false., .false., NS, 1, NS,
+     $                            H( KT, 1 ), LDH, W( KS ), 1, 1, ZDUM,
+     $                            1, INF )
+                     KS = KS + INF
+*
+*                    ==== In case of a rare QR failure use
+*                    .    eigenvalues of the trailing 2-by-2
+*                    .    principal submatrix.  Scale to avoid
+*                    .    overflows, underflows and subnormals.
+*                    .    (The scale factor S can not be zero,
+*                    .    because H(KBOT,KBOT-1) is nonzero.) ====
+*
+                     IF( KS.GE.KBOT ) THEN
+                        S = CABS1( H( KBOT-1, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT, KBOT-1 ) ) +
+     $                      CABS1( H( KBOT-1, KBOT ) ) +
+     $                      CABS1( H( KBOT, KBOT ) )
+                        AA = H( KBOT-1, KBOT-1 ) / S
+                        CC = H( KBOT, KBOT-1 ) / S
+                        BB = H( KBOT-1, KBOT ) / S
+                        DD = H( KBOT, KBOT ) / S
+                        TR2 = ( AA+DD ) / TWO
+                        DET = ( AA-TR2 )*( DD-TR2 ) - BB*CC
+                        RTDISC = SQRT( -DET )
+                        W( KBOT-1 ) = ( TR2+RTDISC )*S
+                        W( KBOT ) = ( TR2-RTDISC )*S
+*
+                        KS = KBOT - 1
+                     END IF
+                  END IF
+*
+                  IF( KBOT-KS+1.GT.NS ) THEN
+*
+*                    ==== Sort the shifts (Helps a little) ====
+*
+                     SORTED = .false.
+                     DO 50 K = KBOT, KS + 1, -1
+                        IF( SORTED )
+     $                     GO TO 60
+                        SORTED = .true.
+                        DO 40 I = KS, K - 1
+                           IF( CABS1( W( I ) ).LT.CABS1( W( I+1 ) ) )
+     $                          THEN
+                              SORTED = .false.
+                              SWAP = W( I )
+                              W( I ) = W( I+1 )
+                              W( I+1 ) = SWAP
+                           END IF
+   40                   CONTINUE
+   50                CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+*
+*              ==== If there are only two shifts, then use
+*              .    only one.  ====
+*
+               IF( KBOT-KS+1.EQ.2 ) THEN
+                  IF( CABS1( W( KBOT )-H( KBOT, KBOT ) ).LT.
+     $                CABS1( W( KBOT-1 )-H( KBOT, KBOT ) ) ) THEN
+                     W( KBOT-1 ) = W( KBOT )
+                  ELSE
+                     W( KBOT ) = W( KBOT-1 )
+                  END IF
+               END IF
+*
+*              ==== Use up to NS of the the smallest magnatiude
+*              .    shifts.  If there aren't NS shifts available,
+*              .    then use them all, possibly dropping one to
+*              .    make the number of shifts even. ====
+*
+               NS = MIN( NS, KBOT-KS+1 )
+               NS = NS - MOD( NS, 2 )
+               KS = KBOT - NS + 1
+*
+*              ==== Small-bulge multi-shift QR sweep:
+*              .    split workspace under the subdiagonal into
+*              .    - a KDU-by-KDU work array U in the lower
+*              .      left-hand-corner,
+*              .    - a KDU-by-at-least-KDU-but-more-is-better
+*              .      (KDU-by-NHo) horizontal work array WH along
+*              .      the bottom edge,
+*              .    - and an at-least-KDU-but-more-is-better-by-KDU
+*              .      (NVE-by-KDU) vertical work WV arrow along
+*              .      the left-hand-edge. ====
+*
+               KDU = 3*NS - 3
+               KU = N - KDU + 1
+               KWH = KDU + 1
+               NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1
+               KWV = KDU + 4
+               NVE = N - KDU - KWV + 1
+*
+*              ==== Small-bulge multi-shift QR sweep ====
+*
+               CALL ZLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,
+     $                      W( KS ), H, LDH, ILOZ, IHIZ, Z, LDZ, WORK,
+     $                      3, H( KU, 1 ), LDH, NVE, H( KWV, 1 ), LDH,
+     $                      NHO, H( KU, KWH ), LDH )
+            END IF
+*
+*           ==== Note progress (or the lack of it). ====
+*
+            IF( LD.GT.0 ) THEN
+               NDFL = 1
+            ELSE
+               NDFL = NDFL + 1
+            END IF
+*
+*           ==== End of main loop ====
+   70    CONTINUE
+*
+*        ==== Iteration limit exceeded.  Set INFO to show where
+*        .    the problem occurred and exit. ====
+*
+         INFO = KBOT
+   80    CONTINUE
+      END IF
+*
+*     ==== Return the optimal value of LWORK. ====
+*
+      WORK( 1 ) = DCMPLX( LWKOPT, 0 )
+*
+*     ==== End of ZLAQR4 ====
+*
+      END
diff --git a/libcruft/lapack/zlaqr5.f b/libcruft/lapack/zlaqr5.f
new file mode 100644
index 0000000..fa8de7b
--- /dev/null
+++ b/libcruft/lapack/zlaqr5.f
@@ -0,0 +1,809 @@
+      SUBROUTINE ZLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS, S,
+     $                   H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, LDU, NV,
+     $                   WV, LDWV, NH, WH, LDWH )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
+     $                   LDWH, LDWV, LDZ, N, NH, NSHFTS, NV
+      LOGICAL            WANTT, WANTZ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         H( LDH, * ), S( * ), U( LDU, * ), V( LDV, * ),
+     $                   WH( LDWH, * ), WV( LDWV, * ), Z( LDZ, * )
+*     ..
+*
+*     This auxiliary subroutine called by ZLAQR0 performs a
+*     single small-bulge multi-shift QR sweep.
+*
+*      WANTT  (input) logical scalar
+*             WANTT = .true. if the triangular Schur factor
+*             is being computed.  WANTT is set to .false. otherwise.
+*
+*      WANTZ  (input) logical scalar
+*             WANTZ = .true. if the unitary Schur factor is being
+*             computed.  WANTZ is set to .false. otherwise.
+*
+*      KACC22 (input) integer with value 0, 1, or 2.
+*             Specifies the computation mode of far-from-diagonal
+*             orthogonal updates.
+*        = 0: ZLAQR5 does not accumulate reflections and does not
+*             use matrix-matrix multiply to update far-from-diagonal
+*             matrix entries.
+*        = 1: ZLAQR5 accumulates reflections and uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries.
+*        = 2: ZLAQR5 accumulates reflections, uses matrix-matrix
+*             multiply to update the far-from-diagonal matrix entries,
+*             and takes advantage of 2-by-2 block structure during
+*             matrix multiplies.
+*
+*      N      (input) integer scalar
+*             N is the order of the Hessenberg matrix H upon which this
+*             subroutine operates.
+*
+*      KTOP   (input) integer scalar
+*      KBOT   (input) integer scalar
+*             These are the first and last rows and columns of an
+*             isolated diagonal block upon which the QR sweep is to be
+*             applied. It is assumed without a check that
+*                       either KTOP = 1  or   H(KTOP,KTOP-1) = 0
+*             and
+*                       either KBOT = N  or   H(KBOT+1,KBOT) = 0.
+*
+*      NSHFTS (input) integer scalar
+*             NSHFTS gives the number of simultaneous shifts.  NSHFTS
+*             must be positive and even.
+*
+*      S      (input) COMPLEX*16 array of size (NSHFTS)
+*             S contains the shifts of origin that define the multi-
+*             shift QR sweep.
+*
+*      H      (input/output) COMPLEX*16 array of size (LDH,N)
+*             On input H contains a Hessenberg matrix.  On output a
+*             multi-shift QR sweep with shifts SR(J)+i*SI(J) is applied
+*             to the isolated diagonal block in rows and columns KTOP
+*             through KBOT.
+*
+*      LDH    (input) integer scalar
+*             LDH is the leading dimension of H just as declared in the
+*             calling procedure.  LDH.GE.MAX(1,N).
+*
+*      ILOZ   (input) INTEGER
+*      IHIZ   (input) INTEGER
+*             Specify the rows of Z to which transformations must be
+*             applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N
+*
+*      Z      (input/output) COMPLEX*16 array of size (LDZ,IHI)
+*             If WANTZ = .TRUE., then the QR Sweep unitary
+*             similarity transformation is accumulated into
+*             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*             If WANTZ = .FALSE., then Z is unreferenced.
+*
+*      LDZ    (input) integer scalar
+*             LDA is the leading dimension of Z just as declared in
+*             the calling procedure. LDZ.GE.N.
+*
+*      V      (workspace) COMPLEX*16 array of size (LDV,NSHFTS/2)
+*
+*      LDV    (input) integer scalar
+*             LDV is the leading dimension of V as declared in the
+*             calling procedure.  LDV.GE.3.
+*
+*      U      (workspace) COMPLEX*16 array of size
+*             (LDU,3*NSHFTS-3)
+*
+*      LDU    (input) integer scalar
+*             LDU is the leading dimension of U just as declared in the
+*             in the calling subroutine.  LDU.GE.3*NSHFTS-3.
+*
+*      NH     (input) integer scalar
+*             NH is the number of columns in array WH available for
+*             workspace. NH.GE.1.
+*
+*      WH     (workspace) COMPLEX*16 array of size (LDWH,NH)
+*
+*      LDWH   (input) integer scalar
+*             Leading dimension of WH just as declared in the
+*             calling procedure.  LDWH.GE.3*NSHFTS-3.
+*
+*      NV     (input) integer scalar
+*             NV is the number of rows in WV agailable for workspace.
+*             NV.GE.1.
+*
+*      WV     (workspace) COMPLEX*16 array of size
+*             (LDWV,3*NSHFTS-3)
+*
+*      LDWV   (input) integer scalar
+*             LDWV is the leading dimension of WV as declared in the
+*             in the calling subroutine.  LDWV.GE.NV.
+*
+*     ================================================================
+*     Based on contributions by
+*        Karen Braman and Ralph Byers, Department of Mathematics,
+*        University of Kansas, USA
+*
+*      ============================================================
+*      Reference:
+*
+*      K. Braman, R. Byers and R. Mathias, The Multi-Shift QR
+*      Algorithm Part I: Maintaining Well Focused Shifts, and
+*      Level 3 Performance, SIAM Journal of Matrix Analysis,
+*      volume 23, pages 929--947, 2002.
+*
+*      ============================================================
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0d0, 0.0d0 ),
+     $                   ONE = ( 1.0d0, 0.0d0 ) )
+      DOUBLE PRECISION   RZERO, RONE
+      PARAMETER          ( RZERO = 0.0d0, RONE = 1.0d0 )
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16         ALPHA, BETA, CDUM, REFSUM
+      DOUBLE PRECISION   H11, H12, H21, H22, SAFMAX, SAFMIN, SCL,
+     $                   SMLNUM, TST1, TST2, ULP
+      INTEGER            I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN,
+     $                   JROW, JTOP, K, K1, KDU, KMS, KNZ, KRCOL, KZS,
+     $                   M, M22, MBOT, MEND, MSTART, MTOP, NBMPS, NDCOL,
+     $                   NS, NU
+      LOGICAL            ACCUM, BLK22, BMP22
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+*
+      INTRINSIC          ABS, DBLE, DCONJG, DIMAG, MAX, MIN, MOD
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         VT( 3 )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, ZGEMM, ZLACPY, ZLAQR1, ZLARFG, ZLASET,
+     $                   ZTRMM
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     ==== If there are no shifts, then there is nothing to do. ====
+*
+      IF( NSHFTS.LT.2 )
+     $   RETURN
+*
+*     ==== If the active block is empty or 1-by-1, then there
+*     .    is nothing to do. ====
+*
+      IF( KTOP.GE.KBOT )
+     $   RETURN
+*
+*     ==== NSHFTS is supposed to be even, but if is odd,
+*     .    then simply reduce it by one.  ====
+*
+      NS = NSHFTS - MOD( NSHFTS, 2 )
+*
+*     ==== Machine constants for deflation ====
+*
+      SAFMIN = DLAMCH( 'SAFE MINIMUM' )
+      SAFMAX = RONE / SAFMIN
+      CALL DLABAD( SAFMIN, SAFMAX )
+      ULP = DLAMCH( 'PRECISION' )
+      SMLNUM = SAFMIN*( DBLE( N ) / ULP )
+*
+*     ==== Use accumulated reflections to update far-from-diagonal
+*     .    entries ? ====
+*
+      ACCUM = ( KACC22.EQ.1 ) .OR. ( KACC22.EQ.2 )
+*
+*     ==== If so, exploit the 2-by-2 block structure? ====
+*
+      BLK22 = ( NS.GT.2 ) .AND. ( KACC22.EQ.2 )
+*
+*     ==== clear trash ====
+*
+      IF( KTOP+2.LE.KBOT )
+     $   H( KTOP+2, KTOP ) = ZERO
+*
+*     ==== NBMPS = number of 2-shift bulges in the chain ====
+*
+      NBMPS = NS / 2
+*
+*     ==== KDU = width of slab ====
+*
+      KDU = 6*NBMPS - 3
+*
+*     ==== Create and chase chains of NBMPS bulges ====
+*
+      DO 210 INCOL = 3*( 1-NBMPS ) + KTOP - 1, KBOT - 2, 3*NBMPS - 2
+         NDCOL = INCOL + KDU
+         IF( ACCUM )
+     $      CALL ZLASET( 'ALL', KDU, KDU, ZERO, ONE, U, LDU )
+*
+*        ==== Near-the-diagonal bulge chase.  The following loop
+*        .    performs the near-the-diagonal part of a small bulge
+*        .    multi-shift QR sweep.  Each 6*NBMPS-2 column diagonal
+*        .    chunk extends from column INCOL to column NDCOL
+*        .    (including both column INCOL and column NDCOL). The
+*        .    following loop chases a 3*NBMPS column long chain of
+*        .    NBMPS bulges 3*NBMPS-2 columns to the right.  (INCOL
+*        .    may be less than KTOP and and NDCOL may be greater than
+*        .    KBOT indicating phantom columns from which to chase
+*        .    bulges before they are actually introduced or to which
+*        .    to chase bulges beyond column KBOT.)  ====
+*
+         DO 140 KRCOL = INCOL, MIN( INCOL+3*NBMPS-3, KBOT-2 )
+*
+*           ==== Bulges number MTOP to MBOT are active double implicit
+*           .    shift bulges.  There may or may not also be small
+*           .    2-by-2 bulge, if there is room.  The inactive bulges
+*           .    (if any) must wait until the active bulges have moved
+*           .    down the diagonal to make room.  The phantom matrix
+*           .    paradigm described above helps keep track.  ====
+*
+            MTOP = MAX( 1, ( ( KTOP-1 )-KRCOL+2 ) / 3+1 )
+            MBOT = MIN( NBMPS, ( KBOT-KRCOL ) / 3 )
+            M22 = MBOT + 1
+            BMP22 = ( MBOT.LT.NBMPS ) .AND. ( KRCOL+3*( M22-1 ) ).EQ.
+     $              ( KBOT-2 )
+*
+*           ==== Generate reflections to chase the chain right
+*           .    one column.  (The minimum value of K is KTOP-1.) ====
+*
+            DO 10 M = MTOP, MBOT
+               K = KRCOL + 3*( M-1 )
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL ZLAQR1( 3, H( KTOP, KTOP ), LDH, S( 2*M-1 ),
+     $                         S( 2*M ), V( 1, M ) )
+                  ALPHA = V( 1, M )
+                  CALL ZLARFG( 3, ALPHA, V( 2, M ), 1, V( 1, M ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M ) = H( K+2, K )
+                  V( 3, M ) = H( K+3, K )
+                  CALL ZLARFG( 3, BETA, V( 2, M ), 1, V( 1, M ) )
+*
+*                 ==== A Bulge may collapse because of vigilant
+*                 .    deflation or destructive underflow.  (The
+*                 .    initial bulge is always collapsed.) Use
+*                 .    the two-small-subdiagonals trick to try
+*                 .    to get it started again. If V(2,M).NE.0 and
+*                 .    V(3,M) = H(K+3,K+1) = H(K+3,K+2) = 0, then
+*                 .    this bulge is collapsing into a zero
+*                 .    subdiagonal.  It will be restarted next
+*                 .    trip through the loop.)
+*
+                  IF( V( 1, M ).NE.ZERO .AND.
+     $                ( V( 3, M ).NE.ZERO .OR. ( H( K+3,
+     $                K+1 ).EQ.ZERO .AND. H( K+3, K+2 ).EQ.ZERO ) ) )
+     $                 THEN
+*
+*                    ==== Typical case: not collapsed (yet). ====
+*
+                     H( K+1, K ) = BETA
+                     H( K+2, K ) = ZERO
+                     H( K+3, K ) = ZERO
+                  ELSE
+*
+*                    ==== Atypical case: collapsed.  Attempt to
+*                    .    reintroduce ignoring H(K+1,K).  If the
+*                    .    fill resulting from the new reflector
+*                    .    is too large, then abandon it.
+*                    .    Otherwise, use the new one. ====
+*
+                     CALL ZLAQR1( 3, H( K+1, K+1 ), LDH, S( 2*M-1 ),
+     $                            S( 2*M ), VT )
+                     SCL = CABS1( VT( 1 ) ) + CABS1( VT( 2 ) ) +
+     $                     CABS1( VT( 3 ) )
+                     IF( SCL.NE.RZERO ) THEN
+                        VT( 1 ) = VT( 1 ) / SCL
+                        VT( 2 ) = VT( 2 ) / SCL
+                        VT( 3 ) = VT( 3 ) / SCL
+                     END IF
+*
+*                    ==== The following is the traditional and
+*                    .    conservative two-small-subdiagonals
+*                    .    test.  ====
+*                    .
+                     IF( CABS1( H( K+1, K ) )*
+     $                   ( CABS1( VT( 2 ) )+CABS1( VT( 3 ) ) ).GT.ULP*
+     $                   CABS1( VT( 1 ) )*( CABS1( H( K,
+     $                   K ) )+CABS1( H( K+1, K+1 ) )+CABS1( H( K+2,
+     $                   K+2 ) ) ) ) THEN
+*
+*                       ==== Starting a new bulge here would
+*                       .    create non-negligible fill.   If
+*                       .    the old reflector is diagonal (only
+*                       .    possible with underflows), then
+*                       .    change it to I.  Otherwise, use
+*                       .    it with trepidation. ====
+*
+                        IF( V( 2, M ).EQ.ZERO .AND. V( 3, M ).EQ.ZERO )
+     $                       THEN
+                           V( 1, M ) = ZERO
+                        ELSE
+                           H( K+1, K ) = BETA
+                           H( K+2, K ) = ZERO
+                           H( K+3, K ) = ZERO
+                        END IF
+                     ELSE
+*
+*                       ==== Stating a new bulge here would
+*                       .    create only negligible fill.
+*                       .    Replace the old reflector with
+*                       .    the new one. ====
+*
+                        ALPHA = VT( 1 )
+                        CALL ZLARFG( 3, ALPHA, VT( 2 ), 1, VT( 1 ) )
+                        REFSUM = H( K+1, K ) +
+     $                           H( K+2, K )*DCONJG( VT( 2 ) ) +
+     $                           H( K+3, K )*DCONJG( VT( 3 ) )
+                        H( K+1, K ) = H( K+1, K ) -
+     $                                DCONJG( VT( 1 ) )*REFSUM
+                        H( K+2, K ) = ZERO
+                        H( K+3, K ) = ZERO
+                        V( 1, M ) = VT( 1 )
+                        V( 2, M ) = VT( 2 )
+                        V( 3, M ) = VT( 3 )
+                     END IF
+                  END IF
+               END IF
+   10       CONTINUE
+*
+*           ==== Generate a 2-by-2 reflection, if needed. ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 ) THEN
+               IF( K.EQ.KTOP-1 ) THEN
+                  CALL ZLAQR1( 2, H( K+1, K+1 ), LDH, S( 2*M22-1 ),
+     $                         S( 2*M22 ), V( 1, M22 ) )
+                  BETA = V( 1, M22 )
+                  CALL ZLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+               ELSE
+                  BETA = H( K+1, K )
+                  V( 2, M22 ) = H( K+2, K )
+                  CALL ZLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )
+                  H( K+1, K ) = BETA
+                  H( K+2, K ) = ZERO
+               END IF
+            ELSE
+*
+*              ==== Initialize V(1,M22) here to avoid possible undefined
+*              .    variable problems later. ====
+*
+               V( 1, M22 ) = ZERO
+            END IF
+*
+*           ==== Multiply H by reflections from the left ====
+*
+            IF( ACCUM ) THEN
+               JBOT = MIN( NDCOL, KBOT )
+            ELSE IF( WANTT ) THEN
+               JBOT = N
+            ELSE
+               JBOT = KBOT
+            END IF
+            DO 30 J = MAX( KTOP, KRCOL ), JBOT
+               MEND = MIN( MBOT, ( J-KRCOL+2 ) / 3 )
+               DO 20 M = MTOP, MEND
+                  K = KRCOL + 3*( M-1 )
+                  REFSUM = DCONJG( V( 1, M ) )*
+     $                     ( H( K+1, J )+DCONJG( V( 2, M ) )*
+     $                     H( K+2, J )+DCONJG( V( 3, M ) )*H( K+3, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M )
+                  H( K+3, J ) = H( K+3, J ) - REFSUM*V( 3, M )
+   20          CONTINUE
+   30       CONTINUE
+            IF( BMP22 ) THEN
+               K = KRCOL + 3*( M22-1 )
+               DO 40 J = MAX( K+1, KTOP ), JBOT
+                  REFSUM = DCONJG( V( 1, M22 ) )*
+     $                     ( H( K+1, J )+DCONJG( V( 2, M22 ) )*
+     $                     H( K+2, J ) )
+                  H( K+1, J ) = H( K+1, J ) - REFSUM
+                  H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M22 )
+   40          CONTINUE
+            END IF
+*
+*           ==== Multiply H by reflections from the right.
+*           .    Delay filling in the last row until the
+*           .    vigilant deflation check is complete. ====
+*
+            IF( ACCUM ) THEN
+               JTOP = MAX( KTOP, INCOL )
+            ELSE IF( WANTT ) THEN
+               JTOP = 1
+            ELSE
+               JTOP = KTOP
+            END IF
+            DO 80 M = MTOP, MBOT
+               IF( V( 1, M ).NE.ZERO ) THEN
+                  K = KRCOL + 3*( M-1 )
+                  DO 50 J = JTOP, MIN( KBOT, K+3 )
+                     REFSUM = V( 1, M )*( H( J, K+1 )+V( 2, M )*
+     $                        H( J, K+2 )+V( 3, M )*H( J, K+3 ) )
+                     H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                     H( J, K+2 ) = H( J, K+2 ) -
+     $                             REFSUM*DCONJG( V( 2, M ) )
+                     H( J, K+3 ) = H( J, K+3 ) -
+     $                             REFSUM*DCONJG( V( 3, M ) )
+   50             CONTINUE
+*
+                  IF( ACCUM ) THEN
+*
+*                    ==== Accumulate U. (If necessary, update Z later
+*                    .    with with an efficient matrix-matrix
+*                    .    multiply.) ====
+*
+                     KMS = K - INCOL
+                     DO 60 J = MAX( 1, KTOP-INCOL ), KDU
+                        REFSUM = V( 1, M )*( U( J, KMS+1 )+V( 2, M )*
+     $                           U( J, KMS+2 )+V( 3, M )*U( J, KMS+3 ) )
+                        U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                        U( J, KMS+2 ) = U( J, KMS+2 ) -
+     $                                  REFSUM*DCONJG( V( 2, M ) )
+                        U( J, KMS+3 ) = U( J, KMS+3 ) -
+     $                                  REFSUM*DCONJG( V( 3, M ) )
+   60                CONTINUE
+                  ELSE IF( WANTZ ) THEN
+*
+*                    ==== U is not accumulated, so update Z
+*                    .    now by multiplying by reflections
+*                    .    from the right. ====
+*
+                     DO 70 J = ILOZ, IHIZ
+                        REFSUM = V( 1, M )*( Z( J, K+1 )+V( 2, M )*
+     $                           Z( J, K+2 )+V( 3, M )*Z( J, K+3 ) )
+                        Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                        Z( J, K+2 ) = Z( J, K+2 ) -
+     $                                REFSUM*DCONJG( V( 2, M ) )
+                        Z( J, K+3 ) = Z( J, K+3 ) -
+     $                                REFSUM*DCONJG( V( 3, M ) )
+   70                CONTINUE
+                  END IF
+               END IF
+   80       CONTINUE
+*
+*           ==== Special case: 2-by-2 reflection (if needed) ====
+*
+            K = KRCOL + 3*( M22-1 )
+            IF( BMP22 .AND. ( V( 1, M22 ).NE.ZERO ) ) THEN
+               DO 90 J = JTOP, MIN( KBOT, K+3 )
+                  REFSUM = V( 1, M22 )*( H( J, K+1 )+V( 2, M22 )*
+     $                     H( J, K+2 ) )
+                  H( J, K+1 ) = H( J, K+1 ) - REFSUM
+                  H( J, K+2 ) = H( J, K+2 ) -
+     $                          REFSUM*DCONJG( V( 2, M22 ) )
+   90          CONTINUE
+*
+               IF( ACCUM ) THEN
+                  KMS = K - INCOL
+                  DO 100 J = MAX( 1, KTOP-INCOL ), KDU
+                     REFSUM = V( 1, M22 )*( U( J, KMS+1 )+V( 2, M22 )*
+     $                        U( J, KMS+2 ) )
+                     U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM
+                     U( J, KMS+2 ) = U( J, KMS+2 ) -
+     $                               REFSUM*DCONJG( V( 2, M22 ) )
+  100             CONTINUE
+               ELSE IF( WANTZ ) THEN
+                  DO 110 J = ILOZ, IHIZ
+                     REFSUM = V( 1, M22 )*( Z( J, K+1 )+V( 2, M22 )*
+     $                        Z( J, K+2 ) )
+                     Z( J, K+1 ) = Z( J, K+1 ) - REFSUM
+                     Z( J, K+2 ) = Z( J, K+2 ) -
+     $                             REFSUM*DCONJG( V( 2, M22 ) )
+  110             CONTINUE
+               END IF
+            END IF
+*
+*           ==== Vigilant deflation check ====
+*
+            MSTART = MTOP
+            IF( KRCOL+3*( MSTART-1 ).LT.KTOP )
+     $         MSTART = MSTART + 1
+            MEND = MBOT
+            IF( BMP22 )
+     $         MEND = MEND + 1
+            IF( KRCOL.EQ.KBOT-2 )
+     $         MEND = MEND + 1
+            DO 120 M = MSTART, MEND
+               K = MIN( KBOT-1, KRCOL+3*( M-1 ) )
+*
+*              ==== The following convergence test requires that
+*              .    the tradition small-compared-to-nearby-diagonals
+*              .    criterion and the Ahues & Tisseur (LAWN 122, 1997)
+*              .    criteria both be satisfied.  The latter improves
+*              .    accuracy in some examples. Falling back on an
+*              .    alternate convergence criterion when TST1 or TST2
+*              .    is zero (as done here) is traditional but probably
+*              .    unnecessary. ====
+*
+               IF( H( K+1, K ).NE.ZERO ) THEN
+                  TST1 = CABS1( H( K, K ) ) + CABS1( H( K+1, K+1 ) )
+                  IF( TST1.EQ.RZERO ) THEN
+                     IF( K.GE.KTOP+1 )
+     $                  TST1 = TST1 + CABS1( H( K, K-1 ) )
+                     IF( K.GE.KTOP+2 )
+     $                  TST1 = TST1 + CABS1( H( K, K-2 ) )
+                     IF( K.GE.KTOP+3 )
+     $                  TST1 = TST1 + CABS1( H( K, K-3 ) )
+                     IF( K.LE.KBOT-2 )
+     $                  TST1 = TST1 + CABS1( H( K+2, K+1 ) )
+                     IF( K.LE.KBOT-3 )
+     $                  TST1 = TST1 + CABS1( H( K+3, K+1 ) )
+                     IF( K.LE.KBOT-4 )
+     $                  TST1 = TST1 + CABS1( H( K+4, K+1 ) )
+                  END IF
+                  IF( CABS1( H( K+1, K ) ).LE.MAX( SMLNUM, ULP*TST1 ) )
+     $                 THEN
+                     H12 = MAX( CABS1( H( K+1, K ) ),
+     $                     CABS1( H( K, K+1 ) ) )
+                     H21 = MIN( CABS1( H( K+1, K ) ),
+     $                     CABS1( H( K, K+1 ) ) )
+                     H11 = MAX( CABS1( H( K+1, K+1 ) ),
+     $                     CABS1( H( K, K )-H( K+1, K+1 ) ) )
+                     H22 = MIN( CABS1( H( K+1, K+1 ) ),
+     $                     CABS1( H( K, K )-H( K+1, K+1 ) ) )
+                     SCL = H11 + H12
+                     TST2 = H22*( H11 / SCL )
+*
+                     IF( TST2.EQ.RZERO .OR. H21*( H12 / SCL ).LE.
+     $                   MAX( SMLNUM, ULP*TST2 ) )H( K+1, K ) = ZERO
+                  END IF
+               END IF
+  120       CONTINUE
+*
+*           ==== Fill in the last row of each bulge. ====
+*
+            MEND = MIN( NBMPS, ( KBOT-KRCOL-1 ) / 3 )
+            DO 130 M = MTOP, MEND
+               K = KRCOL + 3*( M-1 )
+               REFSUM = V( 1, M )*V( 3, M )*H( K+4, K+3 )
+               H( K+4, K+1 ) = -REFSUM
+               H( K+4, K+2 ) = -REFSUM*DCONJG( V( 2, M ) )
+               H( K+4, K+3 ) = H( K+4, K+3 ) -
+     $                         REFSUM*DCONJG( V( 3, M ) )
+  130       CONTINUE
+*
+*           ==== End of near-the-diagonal bulge chase. ====
+*
+  140    CONTINUE
+*
+*        ==== Use U (if accumulated) to update far-from-diagonal
+*        .    entries in H.  If required, use U to update Z as
+*        .    well. ====
+*
+         IF( ACCUM ) THEN
+            IF( WANTT ) THEN
+               JTOP = 1
+               JBOT = N
+            ELSE
+               JTOP = KTOP
+               JBOT = KBOT
+            END IF
+            IF( ( .NOT.BLK22 ) .OR. ( INCOL.LT.KTOP ) .OR.
+     $          ( NDCOL.GT.KBOT ) .OR. ( NS.LE.2 ) ) THEN
+*
+*              ==== Updates not exploiting the 2-by-2 block
+*              .    structure of U.  K1 and NU keep track of
+*              .    the location and size of U in the special
+*              .    cases of introducing bulges and chasing
+*              .    bulges off the bottom.  In these special
+*              .    cases and in case the number of shifts
+*              .    is NS = 2, there is no 2-by-2 block
+*              .    structure to exploit.  ====
+*
+               K1 = MAX( 1, KTOP-INCOL )
+               NU = ( KDU-MAX( 0, NDCOL-KBOT ) ) - K1 + 1
+*
+*              ==== Horizontal Multiply ====
+*
+               DO 150 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+                  CALL ZGEMM( 'C', 'N', NU, JLEN, NU, ONE, U( K1, K1 ),
+     $                        LDU, H( INCOL+K1, JCOL ), LDH, ZERO, WH,
+     $                        LDWH )
+                  CALL ZLACPY( 'ALL', NU, JLEN, WH, LDWH,
+     $                         H( INCOL+K1, JCOL ), LDH )
+  150          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 160 JROW = JTOP, MAX( KTOP, INCOL ) - 1, NV
+                  JLEN = MIN( NV, MAX( KTOP, INCOL )-JROW )
+                  CALL ZGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                        H( JROW, INCOL+K1 ), LDH, U( K1, K1 ),
+     $                        LDU, ZERO, WV, LDWV )
+                  CALL ZLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                         H( JROW, INCOL+K1 ), LDH )
+  160          CONTINUE
+*
+*              ==== Z multiply (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 170 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+                     CALL ZGEMM( 'N', 'N', JLEN, NU, NU, ONE,
+     $                           Z( JROW, INCOL+K1 ), LDZ, U( K1, K1 ),
+     $                           LDU, ZERO, WV, LDWV )
+                     CALL ZLACPY( 'ALL', JLEN, NU, WV, LDWV,
+     $                            Z( JROW, INCOL+K1 ), LDZ )
+  170             CONTINUE
+               END IF
+            ELSE
+*
+*              ==== Updates exploiting U's 2-by-2 block structure.
+*              .    (I2, I4, J2, J4 are the last rows and columns
+*              .    of the blocks.) ====
+*
+               I2 = ( KDU+1 ) / 2
+               I4 = KDU
+               J2 = I4 - I2
+               J4 = KDU
+*
+*              ==== KZS and KNZ deal with the band of zeros
+*              .    along the diagonal of one of the triangular
+*              .    blocks. ====
+*
+               KZS = ( J4-J2 ) - ( NS+1 )
+               KNZ = NS + 1
+*
+*              ==== Horizontal multiply ====
+*
+               DO 180 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH
+                  JLEN = MIN( NH, JBOT-JCOL+1 )
+*
+*                 ==== Copy bottom of H to top+KZS of scratch ====
+*                  (The first KZS rows get multiplied by zero.) ====
+*
+                  CALL ZLACPY( 'ALL', KNZ, JLEN, H( INCOL+1+J2, JCOL ),
+     $                         LDH, WH( KZS+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL ZLASET( 'ALL', KZS, JLEN, ZERO, ZERO, WH, LDWH )
+                  CALL ZTRMM( 'L', 'U', 'C', 'N', KNZ, JLEN, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WH( KZS+1, 1 ),
+     $                        LDWH )
+*
+*                 ==== Multiply top of H by U11' ====
+*
+                  CALL ZGEMM( 'C', 'N', I2, JLEN, J2, ONE, U, LDU,
+     $                        H( INCOL+1, JCOL ), LDH, ONE, WH, LDWH )
+*
+*                 ==== Copy top of H bottom of WH ====
+*
+                  CALL ZLACPY( 'ALL', J2, JLEN, H( INCOL+1, JCOL ), LDH,
+     $                         WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U21' ====
+*
+                  CALL ZTRMM( 'L', 'L', 'C', 'N', J2, JLEN, ONE,
+     $                        U( 1, I2+1 ), LDU, WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL ZGEMM( 'C', 'N', I4-I2, JLEN, J4-J2, ONE,
+     $                        U( J2+1, I2+1 ), LDU,
+     $                        H( INCOL+1+J2, JCOL ), LDH, ONE,
+     $                        WH( I2+1, 1 ), LDWH )
+*
+*                 ==== Copy it back ====
+*
+                  CALL ZLACPY( 'ALL', KDU, JLEN, WH, LDWH,
+     $                         H( INCOL+1, JCOL ), LDH )
+  180          CONTINUE
+*
+*              ==== Vertical multiply ====
+*
+               DO 190 JROW = JTOP, MAX( INCOL, KTOP ) - 1, NV
+                  JLEN = MIN( NV, MAX( INCOL, KTOP )-JROW )
+*
+*                 ==== Copy right of H to scratch (the first KZS
+*                 .    columns get multiplied by zero) ====
+*
+                  CALL ZLACPY( 'ALL', JLEN, KNZ, H( JROW, INCOL+1+J2 ),
+     $                         LDH, WV( 1, 1+KZS ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL ZLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, LDWV )
+                  CALL ZTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                        U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                        LDWV )
+*
+*                 ==== Multiply by U11 ====
+*
+                  CALL ZGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                        H( JROW, INCOL+1 ), LDH, U, LDU, ONE, WV,
+     $                        LDWV )
+*
+*                 ==== Copy left of H to right of scratch ====
+*
+                  CALL ZLACPY( 'ALL', JLEN, J2, H( JROW, INCOL+1 ), LDH,
+     $                         WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U21 ====
+*
+                  CALL ZTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                        U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), LDWV )
+*
+*                 ==== Multiply by U22 ====
+*
+                  CALL ZGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                        H( JROW, INCOL+1+J2 ), LDH,
+     $                        U( J2+1, I2+1 ), LDU, ONE, WV( 1, 1+I2 ),
+     $                        LDWV )
+*
+*                 ==== Copy it back ====
+*
+                  CALL ZLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                         H( JROW, INCOL+1 ), LDH )
+  190          CONTINUE
+*
+*              ==== Multiply Z (also vertical) ====
+*
+               IF( WANTZ ) THEN
+                  DO 200 JROW = ILOZ, IHIZ, NV
+                     JLEN = MIN( NV, IHIZ-JROW+1 )
+*
+*                    ==== Copy right of Z to left of scratch (first
+*                    .     KZS columns get multiplied by zero) ====
+*
+                     CALL ZLACPY( 'ALL', JLEN, KNZ,
+     $                            Z( JROW, INCOL+1+J2 ), LDZ,
+     $                            WV( 1, 1+KZS ), LDWV )
+*
+*                    ==== Multiply by U12 ====
+*
+                     CALL ZLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV,
+     $                            LDWV )
+                     CALL ZTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,
+     $                           U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U11 ====
+*
+                     CALL ZGEMM( 'N', 'N', JLEN, I2, J2, ONE,
+     $                           Z( JROW, INCOL+1 ), LDZ, U, LDU, ONE,
+     $                           WV, LDWV )
+*
+*                    ==== Copy left of Z to right of scratch ====
+*
+                     CALL ZLACPY( 'ALL', JLEN, J2, Z( JROW, INCOL+1 ),
+     $                            LDZ, WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Multiply by U21 ====
+*
+                     CALL ZTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,
+     $                           U( 1, I2+1 ), LDU, WV( 1, 1+I2 ),
+     $                           LDWV )
+*
+*                    ==== Multiply by U22 ====
+*
+                     CALL ZGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,
+     $                           Z( JROW, INCOL+1+J2 ), LDZ,
+     $                           U( J2+1, I2+1 ), LDU, ONE,
+     $                           WV( 1, 1+I2 ), LDWV )
+*
+*                    ==== Copy the result back to Z ====
+*
+                     CALL ZLACPY( 'ALL', JLEN, KDU, WV, LDWV,
+     $                            Z( JROW, INCOL+1 ), LDZ )
+  200             CONTINUE
+               END IF
+            END IF
+         END IF
+  210 CONTINUE
+*
+*     ==== End of ZLAQR5 ====
+*
+      END
diff --git a/libcruft/lapack/zlarf.f b/libcruft/lapack/zlarf.f
new file mode 100644
index 0000000..d5233c8
--- /dev/null
+++ b/libcruft/lapack/zlarf.f
@@ -0,0 +1,120 @@
+      SUBROUTINE ZLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, LDC, M, N
+      COMPLEX*16         TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARF applies a complex elementary reflector H to a complex M-by-N
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a complex scalar and v is a complex vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*  To apply H' (the conjugate transpose of H), supply conjg(tau) instead
+*  tau.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) COMPLEX*16 array, dimension
+*                     (1 + (M-1)*abs(INCV)) if SIDE = 'L'
+*                  or (1 + (N-1)*abs(INCV)) if SIDE = 'R'
+*          The vector v in the representation of H. V is not used if
+*          TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) COMPLEX*16
+*          The value tau in the representation of H.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZGEMV, ZGERC
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C' * v
+*
+            CALL ZGEMV( 'Conjugate transpose', M, N, ONE, C, LDC, V,
+     $                  INCV, ZERO, WORK, 1 )
+*
+*           C := C - v * w'
+*
+            CALL ZGERC( M, N, -TAU, V, INCV, WORK, 1, C, LDC )
+         END IF
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w := C * v
+*
+            CALL ZGEMV( 'No transpose', M, N, ONE, C, LDC, V, INCV,
+     $                  ZERO, WORK, 1 )
+*
+*           C := C - w * v'
+*
+            CALL ZGERC( M, N, -TAU, WORK, 1, V, INCV, C, LDC )
+         END IF
+      END IF
+      RETURN
+*
+*     End of ZLARF
+*
+      END
diff --git a/libcruft/lapack/zlarfb.f b/libcruft/lapack/zlarfb.f
new file mode 100644
index 0000000..af93ea5
--- /dev/null
+++ b/libcruft/lapack/zlarfb.f
@@ -0,0 +1,608 @@
+      SUBROUTINE ZLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,
+     $                   T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARFB applies a complex block reflector H or its transpose H' to a
+*  complex M-by-N matrix C, from either the left or the right.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'C': apply H' (Conjugate transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  V       (input) COMPLEX*16 array, dimension
+*                                (LDV,K) if STOREV = 'C'
+*                                (LDV,M) if STOREV = 'R' and SIDE = 'L'
+*                                (LDV,N) if STOREV = 'R' and SIDE = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);
+*          if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);
+*          if STOREV = 'R', LDV >= K.
+*
+*  T       (input) COMPLEX*16 array, dimension (LDT,K)
+*          The triangular K-by-K matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZCOPY, ZGEMM, ZLACGV, ZTRMM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'C'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( STOREV, 'C' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1 )    (first K rows)
+*                     ( V2 )
+*           where  V1  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C1'
+*
+               DO 10 J = 1, K
+                  CALL ZCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL ZLACGV( N, WORK( 1, J ), 1 )
+   10          CONTINUE
+*
+*              W := W * V1
+*
+               CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2
+*
+                  CALL ZGEMM( 'Conjugate transpose', 'No transpose', N,
+     $                        K, M-K, ONE, C( K+1, 1 ), LDC,
+     $                        V( K+1, 1 ), LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL ZTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2 * W'
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose',
+     $                        M-K, N, K, -ONE, V( K+1, 1 ), LDV, WORK,
+     $                        LDWORK, ONE, C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 30 J = 1, K
+                  DO 20 I = 1, N
+                     C( J, I ) = C( J, I ) - DCONJG( WORK( I, J ) )
+   20             CONTINUE
+   30          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C1
+*
+               DO 40 J = 1, K
+                  CALL ZCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40          CONTINUE
+*
+*              W := W * V1
+*
+               CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2
+*
+                  CALL ZGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,
+     $                        ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL ZTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2'
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        N-K, K, -ONE, WORK, LDWORK, V( K+1, 1 ),
+     $                        LDV, ONE, C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1'
+*
+               CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 60 J = 1, K
+                  DO 50 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+   50             CONTINUE
+   60          CONTINUE
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1 )
+*                     ( V2 )    (last K rows)
+*           where  V2  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V  =  (C1'*V1 + C2'*V2)  (stored in WORK)
+*
+*              W := C2'
+*
+               DO 70 J = 1, K
+                  CALL ZCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL ZLACGV( N, WORK( 1, J ), 1 )
+   70          CONTINUE
+*
+*              W := W * V2
+*
+               CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1
+*
+                  CALL ZGEMM( 'Conjugate transpose', 'No transpose', N,
+     $                        K, M-K, ONE, C, LDC, V, LDV, ONE, WORK,
+     $                        LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL ZTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1 * W'
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose',
+     $                        M-K, N, K, -ONE, V, LDV, WORK, LDWORK,
+     $                        ONE, C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V( M-K+1, 1 ), LDV, WORK,
+     $                     LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 90 J = 1, K
+                  DO 80 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) -
+     $                               DCONJG( WORK( I, J ) )
+   80             CONTINUE
+   90          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V  =  (C1*V1 + C2*V2)  (stored in WORK)
+*
+*              W := C2
+*
+               DO 100 J = 1, K
+                  CALL ZCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  100          CONTINUE
+*
+*              W := W * V2
+*
+               CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1
+*
+                  CALL ZGEMM( 'No transpose', 'No transpose', M, K, N-K,
+     $                        ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL ZTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V'
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1'
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        N-K, K, -ONE, WORK, LDWORK, V, LDV, ONE,
+     $                        C, LDC )
+               END IF
+*
+*              W := W * V2'
+*
+               CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V( N-K+1, 1 ), LDV, WORK,
+     $                     LDWORK )
+*
+*              C2 := C2 - W
+*
+               DO 120 J = 1, K
+                  DO 110 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  110             CONTINUE
+  120          CONTINUE
+            END IF
+         END IF
+*
+      ELSE IF( LSAME( STOREV, 'R' ) ) THEN
+*
+         IF( LSAME( DIRECT, 'F' ) ) THEN
+*
+*           Let  V =  ( V1  V2 )    (V1: first K columns)
+*           where  V1  is unit upper triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C1'
+*
+               DO 130 J = 1, K
+                  CALL ZCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL ZLACGV( N, WORK( 1, J ), 1 )
+  130          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V, LDV, WORK, LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C2'*V2'
+*
+                  CALL ZGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', N, K, M-K, ONE,
+     $                        C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,
+     $                        WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL ZTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C2 := C2 - V2' * W'
+*
+                  CALL ZGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', M-K, N, K, -ONE,
+     $                        V( 1, K+1 ), LDV, WORK, LDWORK, ONE,
+     $                        C( K+1, 1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W'
+*
+               DO 150 J = 1, K
+                  DO 140 I = 1, N
+                     C( J, I ) = C( J, I ) - DCONJG( WORK( I, J ) )
+  140             CONTINUE
+  150          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C1
+*
+               DO 160 J = 1, K
+                  CALL ZCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+  160          CONTINUE
+*
+*              W := W * V1'
+*
+               CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V, LDV, WORK, LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C2 * V2'
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        K, N-K, ONE, C( 1, K+1 ), LDC,
+     $                        V( 1, K+1 ), LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL ZTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C2 := C2 - W * V2
+*
+                  CALL ZGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE,
+     $                        C( 1, K+1 ), LDC )
+               END IF
+*
+*              W := W * V1
+*
+               CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,
+     $                     K, ONE, V, LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 180 J = 1, K
+                  DO 170 I = 1, M
+                     C( I, J ) = C( I, J ) - WORK( I, J )
+  170             CONTINUE
+  180          CONTINUE
+*
+            END IF
+*
+         ELSE
+*
+*           Let  V =  ( V1  V2 )    (V2: last K columns)
+*           where  V2  is unit lower triangular.
+*
+            IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*              Form  H * C  or  H' * C  where  C = ( C1 )
+*                                                  ( C2 )
+*
+*              W := C' * V'  =  (C1'*V1' + C2'*V2') (stored in WORK)
+*
+*              W := C2'
+*
+               DO 190 J = 1, K
+                  CALL ZCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
+                  CALL ZLACGV( N, WORK( 1, J ), 1 )
+  190          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', N, K, ONE, V( 1, M-K+1 ), LDV, WORK,
+     $                     LDWORK )
+               IF( M.GT.K ) THEN
+*
+*                 W := W + C1'*V1'
+*
+                  CALL ZGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', N, K, M-K, ONE, C,
+     $                        LDC, V, LDV, ONE, WORK, LDWORK )
+               END IF
+*
+*              W := W * T'  or  W * T
+*
+               CALL ZTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - V' * W'
+*
+               IF( M.GT.K ) THEN
+*
+*                 C1 := C1 - V1' * W'
+*
+                  CALL ZGEMM( 'Conjugate transpose',
+     $                        'Conjugate transpose', M-K, N, K, -ONE, V,
+     $                        LDV, WORK, LDWORK, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,
+     $                     K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
+*
+*              C2 := C2 - W'
+*
+               DO 210 J = 1, K
+                  DO 200 I = 1, N
+                     C( M-K+J, I ) = C( M-K+J, I ) -
+     $                               DCONJG( WORK( I, J ) )
+  200             CONTINUE
+  210          CONTINUE
+*
+            ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*              Form  C * H  or  C * H'  where  C = ( C1  C2 )
+*
+*              W := C * V'  =  (C1*V1' + C2*V2')  (stored in WORK)
+*
+*              W := C2
+*
+               DO 220 J = 1, K
+                  CALL ZCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
+  220          CONTINUE
+*
+*              W := W * V2'
+*
+               CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',
+     $                     'Unit', M, K, ONE, V( 1, N-K+1 ), LDV, WORK,
+     $                     LDWORK )
+               IF( N.GT.K ) THEN
+*
+*                 W := W + C1 * V1'
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose', M,
+     $                        K, N-K, ONE, C, LDC, V, LDV, ONE, WORK,
+     $                        LDWORK )
+               END IF
+*
+*              W := W * T  or  W * T'
+*
+               CALL ZTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,
+     $                     ONE, T, LDT, WORK, LDWORK )
+*
+*              C := C - W * V
+*
+               IF( N.GT.K ) THEN
+*
+*                 C1 := C1 - W * V1
+*
+                  CALL ZGEMM( 'No transpose', 'No transpose', M, N-K, K,
+     $                        -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
+               END IF
+*
+*              W := W * V2
+*
+               CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,
+     $                     K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )
+*
+*              C1 := C1 - W
+*
+               DO 240 J = 1, K
+                  DO 230 I = 1, M
+                     C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )
+  230             CONTINUE
+  240          CONTINUE
+*
+            END IF
+*
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZLARFB
+*
+      END
diff --git a/libcruft/lapack/zlarfg.f b/libcruft/lapack/zlarfg.f
new file mode 100644
index 0000000..d024f92
--- /dev/null
+++ b/libcruft/lapack/zlarfg.f
@@ -0,0 +1,145 @@
+      SUBROUTINE ZLARFG( N, ALPHA, X, INCX, TAU )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      COMPLEX*16         ALPHA, TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARFG generates a complex elementary reflector H of order n, such
+*  that
+*
+*        H' * ( alpha ) = ( beta ),   H' * H = I.
+*             (   x   )   (   0  )
+*
+*  where alpha and beta are scalars, with beta real, and x is an
+*  (n-1)-element complex vector. H is represented in the form
+*
+*        H = I - tau * ( 1 ) * ( 1 v' ) ,
+*                      ( v )
+*
+*  where tau is a complex scalar and v is a complex (n-1)-element
+*  vector. Note that H is not hermitian.
+*
+*  If the elements of x are all zero and alpha is real, then tau = 0
+*  and H is taken to be the unit matrix.
+*
+*  Otherwise  1 <= real(tau) <= 2  and  abs(tau-1) <= 1 .
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the elementary reflector.
+*
+*  ALPHA   (input/output) COMPLEX*16
+*          On entry, the value alpha.
+*          On exit, it is overwritten with the value beta.
+*
+*  X       (input/output) COMPLEX*16 array, dimension
+*                         (1+(N-2)*abs(INCX))
+*          On entry, the vector x.
+*          On exit, it is overwritten with the vector v.
+*
+*  INCX    (input) INTEGER
+*          The increment between elements of X. INCX > 0.
+*
+*  TAU     (output) COMPLEX*16
+*          The value tau.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J, KNT
+      DOUBLE PRECISION   ALPHI, ALPHR, BETA, RSAFMN, SAFMIN, XNORM
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLAPY3, DZNRM2
+      COMPLEX*16         ZLADIV
+      EXTERNAL           DLAMCH, DLAPY3, DZNRM2, ZLADIV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DIMAG, SIGN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZDSCAL, ZSCAL
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 ) THEN
+         TAU = ZERO
+         RETURN
+      END IF
+*
+      XNORM = DZNRM2( N-1, X, INCX )
+      ALPHR = DBLE( ALPHA )
+      ALPHI = DIMAG( ALPHA )
+*
+      IF( XNORM.EQ.ZERO .AND. ALPHI.EQ.ZERO ) THEN
+*
+*        H  =  I
+*
+         TAU = ZERO
+      ELSE
+*
+*        general case
+*
+         BETA = -SIGN( DLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )
+         SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' )
+         RSAFMN = ONE / SAFMIN
+*
+         IF( ABS( BETA ).LT.SAFMIN ) THEN
+*
+*           XNORM, BETA may be inaccurate; scale X and recompute them
+*
+            KNT = 0
+   10       CONTINUE
+            KNT = KNT + 1
+            CALL ZDSCAL( N-1, RSAFMN, X, INCX )
+            BETA = BETA*RSAFMN
+            ALPHI = ALPHI*RSAFMN
+            ALPHR = ALPHR*RSAFMN
+            IF( ABS( BETA ).LT.SAFMIN )
+     $         GO TO 10
+*
+*           New BETA is at most 1, at least SAFMIN
+*
+            XNORM = DZNRM2( N-1, X, INCX )
+            ALPHA = DCMPLX( ALPHR, ALPHI )
+            BETA = -SIGN( DLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )
+            TAU = DCMPLX( ( BETA-ALPHR ) / BETA, -ALPHI / BETA )
+            ALPHA = ZLADIV( DCMPLX( ONE ), ALPHA-BETA )
+            CALL ZSCAL( N-1, ALPHA, X, INCX )
+*
+*           If ALPHA is subnormal, it may lose relative accuracy
+*
+            ALPHA = BETA
+            DO 20 J = 1, KNT
+               ALPHA = ALPHA*SAFMIN
+   20       CONTINUE
+         ELSE
+            TAU = DCMPLX( ( BETA-ALPHR ) / BETA, -ALPHI / BETA )
+            ALPHA = ZLADIV( DCMPLX( ONE ), ALPHA-BETA )
+            CALL ZSCAL( N-1, ALPHA, X, INCX )
+            ALPHA = BETA
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZLARFG
+*
+      END
diff --git a/libcruft/lapack/zlarft.f b/libcruft/lapack/zlarft.f
new file mode 100644
index 0000000..412265e
--- /dev/null
+++ b/libcruft/lapack/zlarft.f
@@ -0,0 +1,224 @@
+      SUBROUTINE ZLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARFT forms the triangular factor T of a complex block reflector H
+*  of order n, which is defined as a product of k elementary reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) COMPLEX*16 array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) COMPLEX*16 array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*               V = (  1       )                 V = (  1 v1 v1 v1 v1 )
+*                   ( v1  1    )                     (     1 v2 v2 v2 )
+*                   ( v1 v2  1 )                     (        1 v3 v3 )
+*                   ( v1 v2 v3 )
+*                   ( v1 v2 v3 )
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*               V = ( v1 v2 v3 )                 V = ( v1 v1  1       )
+*                   ( v1 v2 v3 )                     ( v2 v2 v2  1    )
+*                   (  1 v2 v3 )                     ( v3 v3 v3 v3  1 )
+*                   (     1 v3 )
+*                   (        1 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J
+      COMPLEX*16         VII
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZGEMV, ZLACGV, ZTRMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( LSAME( DIRECT, 'F' ) ) THEN
+         DO 20 I = 1, K
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 10 J = 1, I
+                  T( J, I ) = ZERO
+   10          CONTINUE
+            ELSE
+*
+*              general case
+*
+               VII = V( I, I )
+               V( I, I ) = ONE
+               IF( LSAME( STOREV, 'C' ) ) THEN
+*
+*                 T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i)
+*
+                  CALL ZGEMV( 'Conjugate transpose', N-I+1, I-1,
+     $                        -TAU( I ), V( I, 1 ), LDV, V( I, I ), 1,
+     $                        ZERO, T( 1, I ), 1 )
+               ELSE
+*
+*                 T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)'
+*
+                  IF( I.LT.N )
+     $               CALL ZLACGV( N-I, V( I, I+1 ), LDV )
+                  CALL ZGEMV( 'No transpose', I-1, N-I+1, -TAU( I ),
+     $                        V( 1, I ), LDV, V( I, I ), LDV, ZERO,
+     $                        T( 1, I ), 1 )
+                  IF( I.LT.N )
+     $               CALL ZLACGV( N-I, V( I, I+1 ), LDV )
+               END IF
+               V( I, I ) = VII
+*
+*              T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)
+*
+               CALL ZTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,
+     $                     LDT, T( 1, I ), 1 )
+               T( I, I ) = TAU( I )
+            END IF
+   20    CONTINUE
+      ELSE
+         DO 40 I = K, 1, -1
+            IF( TAU( I ).EQ.ZERO ) THEN
+*
+*              H(i)  =  I
+*
+               DO 30 J = I, K
+                  T( J, I ) = ZERO
+   30          CONTINUE
+            ELSE
+*
+*              general case
+*
+               IF( I.LT.K ) THEN
+                  IF( LSAME( STOREV, 'C' ) ) THEN
+                     VII = V( N-K+I, I )
+                     V( N-K+I, I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i)
+*
+                     CALL ZGEMV( 'Conjugate transpose', N-K+I, K-I,
+     $                           -TAU( I ), V( 1, I+1 ), LDV, V( 1, I ),
+     $                           1, ZERO, T( I+1, I ), 1 )
+                     V( N-K+I, I ) = VII
+                  ELSE
+                     VII = V( I, N-K+I )
+                     V( I, N-K+I ) = ONE
+*
+*                    T(i+1:k,i) :=
+*                            - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)'
+*
+                     CALL ZLACGV( N-K+I-1, V( I, 1 ), LDV )
+                     CALL ZGEMV( 'No transpose', K-I, N-K+I, -TAU( I ),
+     $                           V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                           T( I+1, I ), 1 )
+                     CALL ZLACGV( N-K+I-1, V( I, 1 ), LDV )
+                     V( I, N-K+I ) = VII
+                  END IF
+*
+*                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+                  CALL ZTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                        T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+               END IF
+               T( I, I ) = TAU( I )
+            END IF
+   40    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZLARFT
+*
+      END
diff --git a/libcruft/lapack/zlarfx.f b/libcruft/lapack/zlarfx.f
new file mode 100644
index 0000000..327b9d0
--- /dev/null
+++ b/libcruft/lapack/zlarfx.f
@@ -0,0 +1,641 @@
+      SUBROUTINE ZLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            LDC, M, N
+      COMPLEX*16         TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARFX applies a complex elementary reflector H to a complex m by n
+*  matrix C, from either the left or the right. H is represented in the
+*  form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a complex scalar and v is a complex vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix
+*
+*  This version uses inline code if H has order < 11.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  V       (input) COMPLEX*16 array, dimension (M) if SIDE = 'L'
+*                                        or (N) if SIDE = 'R'
+*          The vector v in the representation of H.
+*
+*  TAU     (input) COMPLEX*16
+*          The value tau in the representation of H.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the m by n matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDA >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N) if SIDE = 'L'
+*                                            or (M) if SIDE = 'R'
+*          WORK is not referenced if H has order < 11.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            J
+      COMPLEX*16         SUM, T1, T10, T2, T3, T4, T5, T6, T7, T8, T9,
+     $                   V1, V10, V2, V3, V4, V5, V6, V7, V8, V9
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZGEMV, ZGERC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( TAU.EQ.ZERO )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C, where H has order m.
+*
+         GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,
+     $           170, 190 )M
+*
+*        Code for general M
+*
+*        w := C'*v
+*
+         CALL ZGEMV( 'Conjugate transpose', M, N, ONE, C, LDC, V, 1,
+     $               ZERO, WORK, 1 )
+*
+*        C := C - tau * v * w'
+*
+         CALL ZGERC( M, N, -TAU, V, 1, WORK, 1, C, LDC )
+         GO TO 410
+   10    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*DCONJG( V( 1 ) )
+         DO 20 J = 1, N
+            C( 1, J ) = T1*C( 1, J )
+   20    CONTINUE
+         GO TO 410
+   30    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         DO 40 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+   40    CONTINUE
+         GO TO 410
+   50    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         DO 60 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+   60    CONTINUE
+         GO TO 410
+   70    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         DO 80 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+   80    CONTINUE
+         GO TO 410
+   90    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         V5 = DCONJG( V( 5 ) )
+         T5 = TAU*DCONJG( V5 )
+         DO 100 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+  100    CONTINUE
+         GO TO 410
+  110    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         V5 = DCONJG( V( 5 ) )
+         T5 = TAU*DCONJG( V5 )
+         V6 = DCONJG( V( 6 ) )
+         T6 = TAU*DCONJG( V6 )
+         DO 120 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+  120    CONTINUE
+         GO TO 410
+  130    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         V5 = DCONJG( V( 5 ) )
+         T5 = TAU*DCONJG( V5 )
+         V6 = DCONJG( V( 6 ) )
+         T6 = TAU*DCONJG( V6 )
+         V7 = DCONJG( V( 7 ) )
+         T7 = TAU*DCONJG( V7 )
+         DO 140 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+  140    CONTINUE
+         GO TO 410
+  150    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         V5 = DCONJG( V( 5 ) )
+         T5 = TAU*DCONJG( V5 )
+         V6 = DCONJG( V( 6 ) )
+         T6 = TAU*DCONJG( V6 )
+         V7 = DCONJG( V( 7 ) )
+         T7 = TAU*DCONJG( V7 )
+         V8 = DCONJG( V( 8 ) )
+         T8 = TAU*DCONJG( V8 )
+         DO 160 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+  160    CONTINUE
+         GO TO 410
+  170    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         V5 = DCONJG( V( 5 ) )
+         T5 = TAU*DCONJG( V5 )
+         V6 = DCONJG( V( 6 ) )
+         T6 = TAU*DCONJG( V6 )
+         V7 = DCONJG( V( 7 ) )
+         T7 = TAU*DCONJG( V7 )
+         V8 = DCONJG( V( 8 ) )
+         T8 = TAU*DCONJG( V8 )
+         V9 = DCONJG( V( 9 ) )
+         T9 = TAU*DCONJG( V9 )
+         DO 180 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+  180    CONTINUE
+         GO TO 410
+  190    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = DCONJG( V( 1 ) )
+         T1 = TAU*DCONJG( V1 )
+         V2 = DCONJG( V( 2 ) )
+         T2 = TAU*DCONJG( V2 )
+         V3 = DCONJG( V( 3 ) )
+         T3 = TAU*DCONJG( V3 )
+         V4 = DCONJG( V( 4 ) )
+         T4 = TAU*DCONJG( V4 )
+         V5 = DCONJG( V( 5 ) )
+         T5 = TAU*DCONJG( V5 )
+         V6 = DCONJG( V( 6 ) )
+         T6 = TAU*DCONJG( V6 )
+         V7 = DCONJG( V( 7 ) )
+         T7 = TAU*DCONJG( V7 )
+         V8 = DCONJG( V( 8 ) )
+         T8 = TAU*DCONJG( V8 )
+         V9 = DCONJG( V( 9 ) )
+         T9 = TAU*DCONJG( V9 )
+         V10 = DCONJG( V( 10 ) )
+         T10 = TAU*DCONJG( V10 )
+         DO 200 J = 1, N
+            SUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +
+     $            V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +
+     $            V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J ) +
+     $            V10*C( 10, J )
+            C( 1, J ) = C( 1, J ) - SUM*T1
+            C( 2, J ) = C( 2, J ) - SUM*T2
+            C( 3, J ) = C( 3, J ) - SUM*T3
+            C( 4, J ) = C( 4, J ) - SUM*T4
+            C( 5, J ) = C( 5, J ) - SUM*T5
+            C( 6, J ) = C( 6, J ) - SUM*T6
+            C( 7, J ) = C( 7, J ) - SUM*T7
+            C( 8, J ) = C( 8, J ) - SUM*T8
+            C( 9, J ) = C( 9, J ) - SUM*T9
+            C( 10, J ) = C( 10, J ) - SUM*T10
+  200    CONTINUE
+         GO TO 410
+      ELSE
+*
+*        Form  C * H, where H has order n.
+*
+         GO TO ( 210, 230, 250, 270, 290, 310, 330, 350,
+     $           370, 390 )N
+*
+*        Code for general N
+*
+*        w := C * v
+*
+         CALL ZGEMV( 'No transpose', M, N, ONE, C, LDC, V, 1, ZERO,
+     $               WORK, 1 )
+*
+*        C := C - tau * w * v'
+*
+         CALL ZGERC( M, N, -TAU, WORK, 1, V, 1, C, LDC )
+         GO TO 410
+  210    CONTINUE
+*
+*        Special code for 1 x 1 Householder
+*
+         T1 = ONE - TAU*V( 1 )*DCONJG( V( 1 ) )
+         DO 220 J = 1, M
+            C( J, 1 ) = T1*C( J, 1 )
+  220    CONTINUE
+         GO TO 410
+  230    CONTINUE
+*
+*        Special code for 2 x 2 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         DO 240 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+  240    CONTINUE
+         GO TO 410
+  250    CONTINUE
+*
+*        Special code for 3 x 3 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         DO 260 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+  260    CONTINUE
+         GO TO 410
+  270    CONTINUE
+*
+*        Special code for 4 x 4 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         DO 280 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+  280    CONTINUE
+         GO TO 410
+  290    CONTINUE
+*
+*        Special code for 5 x 5 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*DCONJG( V5 )
+         DO 300 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+  300    CONTINUE
+         GO TO 410
+  310    CONTINUE
+*
+*        Special code for 6 x 6 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*DCONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*DCONJG( V6 )
+         DO 320 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+  320    CONTINUE
+         GO TO 410
+  330    CONTINUE
+*
+*        Special code for 7 x 7 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*DCONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*DCONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*DCONJG( V7 )
+         DO 340 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+  340    CONTINUE
+         GO TO 410
+  350    CONTINUE
+*
+*        Special code for 8 x 8 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*DCONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*DCONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*DCONJG( V7 )
+         V8 = V( 8 )
+         T8 = TAU*DCONJG( V8 )
+         DO 360 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+  360    CONTINUE
+         GO TO 410
+  370    CONTINUE
+*
+*        Special code for 9 x 9 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*DCONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*DCONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*DCONJG( V7 )
+         V8 = V( 8 )
+         T8 = TAU*DCONJG( V8 )
+         V9 = V( 9 )
+         T9 = TAU*DCONJG( V9 )
+         DO 380 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+  380    CONTINUE
+         GO TO 410
+  390    CONTINUE
+*
+*        Special code for 10 x 10 Householder
+*
+         V1 = V( 1 )
+         T1 = TAU*DCONJG( V1 )
+         V2 = V( 2 )
+         T2 = TAU*DCONJG( V2 )
+         V3 = V( 3 )
+         T3 = TAU*DCONJG( V3 )
+         V4 = V( 4 )
+         T4 = TAU*DCONJG( V4 )
+         V5 = V( 5 )
+         T5 = TAU*DCONJG( V5 )
+         V6 = V( 6 )
+         T6 = TAU*DCONJG( V6 )
+         V7 = V( 7 )
+         T7 = TAU*DCONJG( V7 )
+         V8 = V( 8 )
+         T8 = TAU*DCONJG( V8 )
+         V9 = V( 9 )
+         T9 = TAU*DCONJG( V9 )
+         V10 = V( 10 )
+         T10 = TAU*DCONJG( V10 )
+         DO 400 J = 1, M
+            SUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +
+     $            V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +
+     $            V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 ) +
+     $            V10*C( J, 10 )
+            C( J, 1 ) = C( J, 1 ) - SUM*T1
+            C( J, 2 ) = C( J, 2 ) - SUM*T2
+            C( J, 3 ) = C( J, 3 ) - SUM*T3
+            C( J, 4 ) = C( J, 4 ) - SUM*T4
+            C( J, 5 ) = C( J, 5 ) - SUM*T5
+            C( J, 6 ) = C( J, 6 ) - SUM*T6
+            C( J, 7 ) = C( J, 7 ) - SUM*T7
+            C( J, 8 ) = C( J, 8 ) - SUM*T8
+            C( J, 9 ) = C( J, 9 ) - SUM*T9
+            C( J, 10 ) = C( J, 10 ) - SUM*T10
+  400    CONTINUE
+         GO TO 410
+      END IF
+  410 CONTINUE
+      RETURN
+*
+*     End of ZLARFX
+*
+      END
diff --git a/libcruft/lapack/zlartg.f b/libcruft/lapack/zlartg.f
new file mode 100644
index 0000000..6d3a850
--- /dev/null
+++ b/libcruft/lapack/zlartg.f
@@ -0,0 +1,195 @@
+      SUBROUTINE ZLARTG( F, G, CS, SN, R )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION   CS
+      COMPLEX*16         F, G, R, SN
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARTG generates a plane rotation so that
+*
+*     [  CS  SN  ]     [ F ]     [ R ]
+*     [  __      ]  .  [   ]  =  [   ]   where CS**2 + |SN|**2 = 1.
+*     [ -SN  CS  ]     [ G ]     [ 0 ]
+*
+*  This is a faster version of the BLAS1 routine ZROTG, except for
+*  the following differences:
+*     F and G are unchanged on return.
+*     If G=0, then CS=1 and SN=0.
+*     If F=0, then CS=0 and SN is chosen so that R is real.
+*
+*  Arguments
+*  =========
+*
+*  F       (input) COMPLEX*16
+*          The first component of vector to be rotated.
+*
+*  G       (input) COMPLEX*16
+*          The second component of vector to be rotated.
+*
+*  CS      (output) DOUBLE PRECISION
+*          The cosine of the rotation.
+*
+*  SN      (output) COMPLEX*16
+*          The sine of the rotation.
+*
+*  R       (output) COMPLEX*16
+*          The nonzero component of the rotated vector.
+*
+*  Further Details
+*  ======= =======
+*
+*  3-5-96 - Modified with a new algorithm by W. Kahan and J. Demmel
+*
+*  This version has a few statements commented out for thread safety
+*  (machine parameters are computed on each entry). 10 feb 03, SJH.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   TWO, ONE, ZERO
+      PARAMETER          ( TWO = 2.0D+0, ONE = 1.0D+0, ZERO = 0.0D+0 )
+      COMPLEX*16         CZERO
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+*     LOGICAL            FIRST
+      INTEGER            COUNT, I
+      DOUBLE PRECISION   D, DI, DR, EPS, F2, F2S, G2, G2S, SAFMIN,
+     $                   SAFMN2, SAFMX2, SCALE
+      COMPLEX*16         FF, FS, GS
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION   DLAMCH, DLAPY2
+      EXTERNAL           DLAMCH, DLAPY2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, INT, LOG,
+     $                   MAX, SQRT
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   ABS1, ABSSQ
+*     ..
+*     .. Save statement ..
+*     SAVE               FIRST, SAFMX2, SAFMIN, SAFMN2
+*     ..
+*     .. Data statements ..
+*     DATA               FIRST / .TRUE. /
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( FF ) = MAX( ABS( DBLE( FF ) ), ABS( DIMAG( FF ) ) )
+      ABSSQ( FF ) = DBLE( FF )**2 + DIMAG( FF )**2
+*     ..
+*     .. Executable Statements ..
+*
+*     IF( FIRST ) THEN
+         SAFMIN = DLAMCH( 'S' )
+         EPS = DLAMCH( 'E' )
+         SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
+     $            LOG( DLAMCH( 'B' ) ) / TWO )
+         SAFMX2 = ONE / SAFMN2
+*        FIRST = .FALSE.
+*     END IF
+      SCALE = MAX( ABS1( F ), ABS1( G ) )
+      FS = F
+      GS = G
+      COUNT = 0
+      IF( SCALE.GE.SAFMX2 ) THEN
+   10    CONTINUE
+         COUNT = COUNT + 1
+         FS = FS*SAFMN2
+         GS = GS*SAFMN2
+         SCALE = SCALE*SAFMN2
+         IF( SCALE.GE.SAFMX2 )
+     $      GO TO 10
+      ELSE IF( SCALE.LE.SAFMN2 ) THEN
+         IF( G.EQ.CZERO ) THEN
+            CS = ONE
+            SN = CZERO
+            R = F
+            RETURN
+         END IF
+   20    CONTINUE
+         COUNT = COUNT - 1
+         FS = FS*SAFMX2
+         GS = GS*SAFMX2
+         SCALE = SCALE*SAFMX2
+         IF( SCALE.LE.SAFMN2 )
+     $      GO TO 20
+      END IF
+      F2 = ABSSQ( FS )
+      G2 = ABSSQ( GS )
+      IF( F2.LE.MAX( G2, ONE )*SAFMIN ) THEN
+*
+*        This is a rare case: F is very small.
+*
+         IF( F.EQ.CZERO ) THEN
+            CS = ZERO
+            R = DLAPY2( DBLE( G ), DIMAG( G ) )
+*           Do complex/real division explicitly with two real divisions
+            D = DLAPY2( DBLE( GS ), DIMAG( GS ) )
+            SN = DCMPLX( DBLE( GS ) / D, -DIMAG( GS ) / D )
+            RETURN
+         END IF
+         F2S = DLAPY2( DBLE( FS ), DIMAG( FS ) )
+*        G2 and G2S are accurate
+*        G2 is at least SAFMIN, and G2S is at least SAFMN2
+         G2S = SQRT( G2 )
+*        Error in CS from underflow in F2S is at most
+*        UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS
+*        If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN,
+*        and so CS .lt. sqrt(SAFMIN)
+*        If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN
+*        and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS)
+*        Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S
+         CS = F2S / G2S
+*        Make sure abs(FF) = 1
+*        Do complex/real division explicitly with 2 real divisions
+         IF( ABS1( F ).GT.ONE ) THEN
+            D = DLAPY2( DBLE( F ), DIMAG( F ) )
+            FF = DCMPLX( DBLE( F ) / D, DIMAG( F ) / D )
+         ELSE
+            DR = SAFMX2*DBLE( F )
+            DI = SAFMX2*DIMAG( F )
+            D = DLAPY2( DR, DI )
+            FF = DCMPLX( DR / D, DI / D )
+         END IF
+         SN = FF*DCMPLX( DBLE( GS ) / G2S, -DIMAG( GS ) / G2S )
+         R = CS*F + SN*G
+      ELSE
+*
+*        This is the most common case.
+*        Neither F2 nor F2/G2 are less than SAFMIN
+*        F2S cannot overflow, and it is accurate
+*
+         F2S = SQRT( ONE+G2 / F2 )
+*        Do the F2S(real)*FS(complex) multiply with two real multiplies
+         R = DCMPLX( F2S*DBLE( FS ), F2S*DIMAG( FS ) )
+         CS = ONE / F2S
+         D = F2 + G2
+*        Do complex/real division explicitly with two real divisions
+         SN = DCMPLX( DBLE( R ) / D, DIMAG( R ) / D )
+         SN = SN*DCONJG( GS )
+         IF( COUNT.NE.0 ) THEN
+            IF( COUNT.GT.0 ) THEN
+               DO 30 I = 1, COUNT
+                  R = R*SAFMX2
+   30          CONTINUE
+            ELSE
+               DO 40 I = 1, -COUNT
+                  R = R*SAFMN2
+   40          CONTINUE
+            END IF
+         END IF
+      END IF
+      RETURN
+*
+*     End of ZLARTG
+*
+      END
diff --git a/libcruft/lapack/zlarz.f b/libcruft/lapack/zlarz.f
new file mode 100644
index 0000000..1812467
--- /dev/null
+++ b/libcruft/lapack/zlarz.f
@@ -0,0 +1,157 @@
+      SUBROUTINE ZLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE
+      INTEGER            INCV, L, LDC, M, N
+      COMPLEX*16         TAU
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         C( LDC, * ), V( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARZ applies a complex elementary reflector H to a complex
+*  M-by-N matrix C, from either the left or the right. H is represented
+*  in the form
+*
+*        H = I - tau * v * v'
+*
+*  where tau is a complex scalar and v is a complex vector.
+*
+*  If tau = 0, then H is taken to be the unit matrix.
+*
+*  To apply H' (the conjugate transpose of H), supply conjg(tau) instead
+*  tau.
+*
+*  H is a product of k elementary reflectors as returned by ZTZRZF.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': form  H * C
+*          = 'R': form  C * H
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  L       (input) INTEGER
+*          The number of entries of the vector V containing
+*          the meaningful part of the Householder vectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) COMPLEX*16 array, dimension (1+(L-1)*abs(INCV))
+*          The vector v in the representation of H as returned by
+*          ZTZRZF. V is not used if TAU = 0.
+*
+*  INCV    (input) INTEGER
+*          The increment between elements of v. INCV <> 0.
+*
+*  TAU     (input) COMPLEX*16
+*          The value tau in the representation of H.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by the matrix H * C if SIDE = 'L',
+*          or C * H if SIDE = 'R'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension
+*                         (N) if SIDE = 'L'
+*                      or (M) if SIDE = 'R'
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZAXPY, ZCOPY, ZGEMV, ZGERC, ZGERU, ZLACGV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:n ) = conjg( C( 1, 1:n ) )
+*
+            CALL ZCOPY( N, C, LDC, WORK, 1 )
+            CALL ZLACGV( N, WORK, 1 )
+*
+*           w( 1:n ) = conjg( w( 1:n ) + C( m-l+1:m, 1:n )' * v( 1:l ) )
+*
+            CALL ZGEMV( 'Conjugate transpose', L, N, ONE, C( M-L+1, 1 ),
+     $                  LDC, V, INCV, ONE, WORK, 1 )
+            CALL ZLACGV( N, WORK, 1 )
+*
+*           C( 1, 1:n ) = C( 1, 1:n ) - tau * w( 1:n )
+*
+            CALL ZAXPY( N, -TAU, WORK, 1, C, LDC )
+*
+*           C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                               tau * v( 1:l ) * conjg( w( 1:n )' )
+*
+            CALL ZGERU( L, N, -TAU, V, INCV, WORK, 1, C( M-L+1, 1 ),
+     $                  LDC )
+         END IF
+*
+      ELSE
+*
+*        Form  C * H
+*
+         IF( TAU.NE.ZERO ) THEN
+*
+*           w( 1:m ) = C( 1:m, 1 )
+*
+            CALL ZCOPY( M, C, 1, WORK, 1 )
+*
+*           w( 1:m ) = w( 1:m ) + C( 1:m, n-l+1:n, 1:n ) * v( 1:l )
+*
+            CALL ZGEMV( 'No transpose', M, L, ONE, C( 1, N-L+1 ), LDC,
+     $                  V, INCV, ONE, WORK, 1 )
+*
+*           C( 1:m, 1 ) = C( 1:m, 1 ) - tau * w( 1:m )
+*
+            CALL ZAXPY( M, -TAU, WORK, 1, C, 1 )
+*
+*           C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                               tau * w( 1:m ) * v( 1:l )'
+*
+            CALL ZGERC( M, L, -TAU, WORK, 1, V, INCV, C( 1, N-L+1 ),
+     $                  LDC )
+*
+         END IF
+*
+      END IF
+*
+      RETURN
+*
+*     End of ZLARZ
+*
+      END
diff --git a/libcruft/lapack/zlarzb.f b/libcruft/lapack/zlarzb.f
new file mode 100644
index 0000000..05d2a0e
--- /dev/null
+++ b/libcruft/lapack/zlarzb.f
@@ -0,0 +1,234 @@
+      SUBROUTINE ZLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,
+     $                   LDV, T, LDT, C, LDC, WORK, LDWORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, SIDE, STOREV, TRANS
+      INTEGER            K, L, LDC, LDT, LDV, LDWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         C( LDC, * ), T( LDT, * ), V( LDV, * ),
+     $                   WORK( LDWORK, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARZB applies a complex block reflector H or its transpose H**H
+*  to a complex distributed M-by-N  C from the left or the right.
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply H or H' from the Left
+*          = 'R': apply H or H' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply H (No transpose)
+*          = 'C': apply H' (Conjugate transpose)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Indicates how H is formed from a product of elementary
+*          reflectors
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Indicates how the vectors which define the elementary
+*          reflectors are stored:
+*          = 'C': Columnwise                        (not supported yet)
+*          = 'R': Rowwise
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C.
+*
+*  K       (input) INTEGER
+*          The order of the matrix T (= the number of elementary
+*          reflectors whose product defines the block reflector).
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix V containing the
+*          meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  V       (input) COMPLEX*16 array, dimension (LDV,NV).
+*          If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.
+*
+*  T       (input) COMPLEX*16 array, dimension (LDT,K)
+*          The triangular K-by-K matrix T in the representation of the
+*          block reflector.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by H*C or H'*C or C*H or C*H'.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (LDWORK,K)
+*
+*  LDWORK  (input) INTEGER
+*          The leading dimension of the array WORK.
+*          If SIDE = 'L', LDWORK >= max(1,N);
+*          if SIDE = 'R', LDWORK >= max(1,M).
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      CHARACTER          TRANST
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZCOPY, ZGEMM, ZLACGV, ZTRMM
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 .OR. N.LE.0 )
+     $   RETURN
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLARZB', -INFO )
+         RETURN
+      END IF
+*
+      IF( LSAME( TRANS, 'N' ) ) THEN
+         TRANST = 'C'
+      ELSE
+         TRANST = 'N'
+      END IF
+*
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  H * C  or  H' * C
+*
+*        W( 1:n, 1:k ) = conjg( C( 1:k, 1:n )' )
+*
+         DO 10 J = 1, K
+            CALL ZCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
+   10    CONTINUE
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) + ...
+*                        conjg( C( m-l+1:m, 1:n )' ) * V( 1:k, 1:l )'
+*
+         IF( L.GT.0 )
+     $      CALL ZGEMM( 'Transpose', 'Conjugate transpose', N, K, L,
+     $                  ONE, C( M-L+1, 1 ), LDC, V, LDV, ONE, WORK,
+     $                  LDWORK )
+*
+*        W( 1:n, 1:k ) = W( 1:n, 1:k ) * T'  or  W( 1:m, 1:k ) * T
+*
+         CALL ZTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+*
+*        C( 1:k, 1:n ) = C( 1:k, 1:n ) - conjg( W( 1:n, 1:k )' )
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, K
+               C( I, J ) = C( I, J ) - WORK( J, I )
+   20       CONTINUE
+   30    CONTINUE
+*
+*        C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...
+*                    conjg( V( 1:k, 1:l )' ) * conjg( W( 1:n, 1:k )' )
+*
+         IF( L.GT.0 )
+     $      CALL ZGEMM( 'Transpose', 'Transpose', L, N, K, -ONE, V, LDV,
+     $                  WORK, LDWORK, ONE, C( M-L+1, 1 ), LDC )
+*
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form  C * H  or  C * H'
+*
+*        W( 1:m, 1:k ) = C( 1:m, 1:k )
+*
+         DO 40 J = 1, K
+            CALL ZCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
+   40    CONTINUE
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) + ...
+*                        C( 1:m, n-l+1:n ) * conjg( V( 1:k, 1:l )' )
+*
+         IF( L.GT.0 )
+     $      CALL ZGEMM( 'No transpose', 'Transpose', M, K, L, ONE,
+     $                  C( 1, N-L+1 ), LDC, V, LDV, ONE, WORK, LDWORK )
+*
+*        W( 1:m, 1:k ) = W( 1:m, 1:k ) * conjg( T )  or
+*                        W( 1:m, 1:k ) * conjg( T' )
+*
+         DO 50 J = 1, K
+            CALL ZLACGV( K-J+1, T( J, J ), 1 )
+   50    CONTINUE
+         CALL ZTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, ONE, T,
+     $               LDT, WORK, LDWORK )
+         DO 60 J = 1, K
+            CALL ZLACGV( K-J+1, T( J, J ), 1 )
+   60    CONTINUE
+*
+*        C( 1:m, 1:k ) = C( 1:m, 1:k ) - W( 1:m, 1:k )
+*
+         DO 80 J = 1, K
+            DO 70 I = 1, M
+               C( I, J ) = C( I, J ) - WORK( I, J )
+   70       CONTINUE
+   80    CONTINUE
+*
+*        C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...
+*                            W( 1:m, 1:k ) * conjg( V( 1:k, 1:l ) )
+*
+         DO 90 J = 1, L
+            CALL ZLACGV( K, V( 1, J ), 1 )
+   90    CONTINUE
+         IF( L.GT.0 )
+     $      CALL ZGEMM( 'No transpose', 'No transpose', M, L, K, -ONE,
+     $                  WORK, LDWORK, V, LDV, ONE, C( 1, N-L+1 ), LDC )
+         DO 100 J = 1, L
+            CALL ZLACGV( K, V( 1, J ), 1 )
+  100    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of ZLARZB
+*
+      END
diff --git a/libcruft/lapack/zlarzt.f b/libcruft/lapack/zlarzt.f
new file mode 100644
index 0000000..9242ed3
--- /dev/null
+++ b/libcruft/lapack/zlarzt.f
@@ -0,0 +1,186 @@
+      SUBROUTINE ZLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, STOREV
+      INTEGER            K, LDT, LDV, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         T( LDT, * ), TAU( * ), V( LDV, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLARZT forms the triangular factor T of a complex block reflector
+*  H of order > n, which is defined as a product of k elementary
+*  reflectors.
+*
+*  If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
+*
+*  If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
+*
+*  If STOREV = 'C', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th column of the array V, and
+*
+*     H  =  I - V * T * V'
+*
+*  If STOREV = 'R', the vector which defines the elementary reflector
+*  H(i) is stored in the i-th row of the array V, and
+*
+*     H  =  I - V' * T * V
+*
+*  Currently, only STOREV = 'R' and DIRECT = 'B' are supported.
+*
+*  Arguments
+*  =========
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies the order in which the elementary reflectors are
+*          multiplied to form the block reflector:
+*          = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
+*          = 'B': H = H(k) . . . H(2) H(1) (Backward)
+*
+*  STOREV  (input) CHARACTER*1
+*          Specifies how the vectors which define the elementary
+*          reflectors are stored (see also Further Details):
+*          = 'C': columnwise                        (not supported yet)
+*          = 'R': rowwise
+*
+*  N       (input) INTEGER
+*          The order of the block reflector H. N >= 0.
+*
+*  K       (input) INTEGER
+*          The order of the triangular factor T (= the number of
+*          elementary reflectors). K >= 1.
+*
+*  V       (input/output) COMPLEX*16 array, dimension
+*                               (LDV,K) if STOREV = 'C'
+*                               (LDV,N) if STOREV = 'R'
+*          The matrix V. See further details.
+*
+*  LDV     (input) INTEGER
+*          The leading dimension of the array V.
+*          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i).
+*
+*  T       (output) COMPLEX*16 array, dimension (LDT,K)
+*          The k by k triangular factor T of the block reflector.
+*          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
+*          lower triangular. The rest of the array is not used.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= K.
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The shape of the matrix V and the storage of the vectors which define
+*  the H(i) is best illustrated by the following example with n = 5 and
+*  k = 3. The elements equal to 1 are not stored; the corresponding
+*  array elements are modified but restored on exit. The rest of the
+*  array is not used.
+*
+*  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
+*
+*                                              ______V_____
+*         ( v1 v2 v3 )                        /            \
+*         ( v1 v2 v3 )                      ( v1 v1 v1 v1 v1 . . . . 1 )
+*     V = ( v1 v2 v3 )                      ( v2 v2 v2 v2 v2 . . . 1   )
+*         ( v1 v2 v3 )                      ( v3 v3 v3 v3 v3 . . 1     )
+*         ( v1 v2 v3 )
+*            .  .  .
+*            .  .  .
+*            1  .  .
+*               1  .
+*                  1
+*
+*  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
+*
+*                                                        ______V_____
+*            1                                          /            \
+*            .  1                           ( 1 . . . . v1 v1 v1 v1 v1 )
+*            .  .  1                        ( . 1 . . . v2 v2 v2 v2 v2 )
+*            .  .  .                        ( . . 1 . . v3 v3 v3 v3 v3 )
+*            .  .  .
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*     V = ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*         ( v1 v2 v3 )
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMV, ZLACGV, ZTRMV
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Executable Statements ..
+*
+*     Check for currently supported options
+*
+      INFO = 0
+      IF( .NOT.LSAME( DIRECT, 'B' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THEN
+         INFO = -2
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLARZT', -INFO )
+         RETURN
+      END IF
+*
+      DO 20 I = K, 1, -1
+         IF( TAU( I ).EQ.ZERO ) THEN
+*
+*           H(i)  =  I
+*
+            DO 10 J = I, K
+               T( J, I ) = ZERO
+   10       CONTINUE
+         ELSE
+*
+*           general case
+*
+            IF( I.LT.K ) THEN
+*
+*              T(i+1:k,i) = - tau(i) * V(i+1:k,1:n) * V(i,1:n)'
+*
+               CALL ZLACGV( N, V( I, 1 ), LDV )
+               CALL ZGEMV( 'No transpose', K-I, N, -TAU( I ),
+     $                     V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,
+     $                     T( I+1, I ), 1 )
+               CALL ZLACGV( N, V( I, 1 ), LDV )
+*
+*              T(i+1:k,i) = T(i+1:k,i+1:k) * T(i+1:k,i)
+*
+               CALL ZTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
+     $                     T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
+            END IF
+            T( I, I ) = TAU( I )
+         END IF
+   20 CONTINUE
+      RETURN
+*
+*     End of ZLARZT
+*
+      END
diff --git a/libcruft/lapack/zlascl.f b/libcruft/lapack/zlascl.f
new file mode 100644
index 0000000..36bb244
--- /dev/null
+++ b/libcruft/lapack/zlascl.f
@@ -0,0 +1,267 @@
+      SUBROUTINE ZLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TYPE
+      INTEGER            INFO, KL, KU, LDA, M, N
+      DOUBLE PRECISION   CFROM, CTO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLASCL multiplies the M by N complex matrix A by the real scalar
+*  CTO/CFROM.  This is done without over/underflow as long as the final
+*  result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
+*  A may be full, upper triangular, lower triangular, upper Hessenberg,
+*  or banded.
+*
+*  Arguments
+*  =========
+*
+*  TYPE    (input) CHARACTER*1
+*          TYPE indices the storage type of the input matrix.
+*          = 'G':  A is a full matrix.
+*          = 'L':  A is a lower triangular matrix.
+*          = 'U':  A is an upper triangular matrix.
+*          = 'H':  A is an upper Hessenberg matrix.
+*          = 'B':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the lower
+*                  half stored.
+*          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
+*                  and upper bandwidth KU and with the only the upper
+*                  half stored.
+*          = 'Z':  A is a band matrix with lower bandwidth KL and upper
+*                  bandwidth KU.
+*
+*  KL      (input) INTEGER
+*          The lower bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  KU      (input) INTEGER
+*          The upper bandwidth of A.  Referenced only if TYPE = 'B',
+*          'Q' or 'Z'.
+*
+*  CFROM   (input) DOUBLE PRECISION
+*  CTO     (input) DOUBLE PRECISION
+*          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
+*          without over/underflow if the final result CTO*A(I,J)/CFROM
+*          can be represented without over/underflow.  CFROM must be
+*          nonzero.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
+*          storage type.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  INFO    (output) INTEGER
+*          0  - successful exit
+*          <0 - if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            DONE
+      INTEGER            I, ITYPE, J, K1, K2, K3, K4
+      DOUBLE PRECISION   BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, DLAMCH
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, MIN
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+*
+      IF( LSAME( TYPE, 'G' ) ) THEN
+         ITYPE = 0
+      ELSE IF( LSAME( TYPE, 'L' ) ) THEN
+         ITYPE = 1
+      ELSE IF( LSAME( TYPE, 'U' ) ) THEN
+         ITYPE = 2
+      ELSE IF( LSAME( TYPE, 'H' ) ) THEN
+         ITYPE = 3
+      ELSE IF( LSAME( TYPE, 'B' ) ) THEN
+         ITYPE = 4
+      ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
+         ITYPE = 5
+      ELSE IF( LSAME( TYPE, 'Z' ) ) THEN
+         ITYPE = 6
+      ELSE
+         ITYPE = -1
+      END IF
+*
+      IF( ITYPE.EQ.-1 ) THEN
+         INFO = -1
+      ELSE IF( CFROM.EQ.ZERO ) THEN
+         INFO = -4
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.
+     $         ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN
+         INFO = -7
+      ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -9
+      ELSE IF( ITYPE.GE.4 ) THEN
+         IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN
+            INFO = -2
+         ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.
+     $            ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )
+     $             THEN
+            INFO = -3
+         ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.
+     $            ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.
+     $            ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN
+            INFO = -9
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLASCL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. M.EQ.0 )
+     $   RETURN
+*
+*     Get machine parameters
+*
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+*
+      CFROMC = CFROM
+      CTOC = CTO
+*
+   10 CONTINUE
+      CFROM1 = CFROMC*SMLNUM
+      CTO1 = CTOC / BIGNUM
+      IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
+         MUL = SMLNUM
+         DONE = .FALSE.
+         CFROMC = CFROM1
+      ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
+         MUL = BIGNUM
+         DONE = .FALSE.
+         CTOC = CTO1
+      ELSE
+         MUL = CTOC / CFROMC
+         DONE = .TRUE.
+      END IF
+*
+      IF( ITYPE.EQ.0 ) THEN
+*
+*        Full matrix
+*
+         DO 30 J = 1, N
+            DO 20 I = 1, M
+               A( I, J ) = A( I, J )*MUL
+   20       CONTINUE
+   30    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.1 ) THEN
+*
+*        Lower triangular matrix
+*
+         DO 50 J = 1, N
+            DO 40 I = J, M
+               A( I, J ) = A( I, J )*MUL
+   40       CONTINUE
+   50    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.2 ) THEN
+*
+*        Upper triangular matrix
+*
+         DO 70 J = 1, N
+            DO 60 I = 1, MIN( J, M )
+               A( I, J ) = A( I, J )*MUL
+   60       CONTINUE
+   70    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.3 ) THEN
+*
+*        Upper Hessenberg matrix
+*
+         DO 90 J = 1, N
+            DO 80 I = 1, MIN( J+1, M )
+               A( I, J ) = A( I, J )*MUL
+   80       CONTINUE
+   90    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.4 ) THEN
+*
+*        Lower half of a symmetric band matrix
+*
+         K3 = KL + 1
+         K4 = N + 1
+         DO 110 J = 1, N
+            DO 100 I = 1, MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  100       CONTINUE
+  110    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.5 ) THEN
+*
+*        Upper half of a symmetric band matrix
+*
+         K1 = KU + 2
+         K3 = KU + 1
+         DO 130 J = 1, N
+            DO 120 I = MAX( K1-J, 1 ), K3
+               A( I, J ) = A( I, J )*MUL
+  120       CONTINUE
+  130    CONTINUE
+*
+      ELSE IF( ITYPE.EQ.6 ) THEN
+*
+*        Band matrix
+*
+         K1 = KL + KU + 2
+         K2 = KL + 1
+         K3 = 2*KL + KU + 1
+         K4 = KL + KU + 1 + M
+         DO 150 J = 1, N
+            DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )
+               A( I, J ) = A( I, J )*MUL
+  140       CONTINUE
+  150    CONTINUE
+*
+      END IF
+*
+      IF( .NOT.DONE )
+     $   GO TO 10
+*
+      RETURN
+*
+*     End of ZLASCL
+*
+      END
diff --git a/libcruft/lapack/zlaset.f b/libcruft/lapack/zlaset.f
new file mode 100644
index 0000000..88fc21b
--- /dev/null
+++ b/libcruft/lapack/zlaset.f
@@ -0,0 +1,114 @@
+      SUBROUTINE ZLASET( UPLO, M, N, ALPHA, BETA, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, M, N
+      COMPLEX*16         ALPHA, BETA
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLASET initializes a 2-D array A to BETA on the diagonal and
+*  ALPHA on the offdiagonals.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the part of the matrix A to be set.
+*          = 'U':      Upper triangular part is set. The lower triangle
+*                      is unchanged.
+*          = 'L':      Lower triangular part is set. The upper triangle
+*                      is unchanged.
+*          Otherwise:  All of the matrix A is set.
+*
+*  M       (input) INTEGER
+*          On entry, M specifies the number of rows of A.
+*
+*  N       (input) INTEGER
+*          On entry, N specifies the number of columns of A.
+*
+*  ALPHA   (input) COMPLEX*16
+*          All the offdiagonal array elements are set to ALPHA.
+*
+*  BETA    (input) COMPLEX*16
+*          All the diagonal array elements are set to BETA.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the m by n matrix A.
+*          On exit, A(i,j) = ALPHA, 1 <= i <= m, 1 <= j <= n, i.ne.j;
+*                   A(i,i) = BETA , 1 <= i <= min(m,n)
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Set the diagonal to BETA and the strictly upper triangular
+*        part of the array to ALPHA.
+*
+         DO 20 J = 2, N
+            DO 10 I = 1, MIN( J-1, M )
+               A( I, J ) = ALPHA
+   10       CONTINUE
+   20    CONTINUE
+         DO 30 I = 1, MIN( N, M )
+            A( I, I ) = BETA
+   30    CONTINUE
+*
+      ELSE IF( LSAME( UPLO, 'L' ) ) THEN
+*
+*        Set the diagonal to BETA and the strictly lower triangular
+*        part of the array to ALPHA.
+*
+         DO 50 J = 1, MIN( M, N )
+            DO 40 I = J + 1, M
+               A( I, J ) = ALPHA
+   40       CONTINUE
+   50    CONTINUE
+         DO 60 I = 1, MIN( N, M )
+            A( I, I ) = BETA
+   60    CONTINUE
+*
+      ELSE
+*
+*        Set the array to BETA on the diagonal and ALPHA on the
+*        offdiagonal.
+*
+         DO 80 J = 1, N
+            DO 70 I = 1, M
+               A( I, J ) = ALPHA
+   70       CONTINUE
+   80    CONTINUE
+         DO 90 I = 1, MIN( M, N )
+            A( I, I ) = BETA
+   90    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLASET
+*
+      END
diff --git a/libcruft/lapack/zlasr.f b/libcruft/lapack/zlasr.f
new file mode 100644
index 0000000..507a20c
--- /dev/null
+++ b/libcruft/lapack/zlasr.f
@@ -0,0 +1,363 @@
+      SUBROUTINE ZLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIRECT, PIVOT, SIDE
+      INTEGER            LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   C( * ), S( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLASR applies a sequence of real plane rotations to a complex matrix
+*  A, from either the left or the right.
+*
+*  When SIDE = 'L', the transformation takes the form
+*
+*     A := P*A
+*
+*  and when SIDE = 'R', the transformation takes the form
+*
+*     A := A*P**T
+*
+*  where P is an orthogonal matrix consisting of a sequence of z plane
+*  rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',
+*  and P**T is the transpose of P.
+*  
+*  When DIRECT = 'F' (Forward sequence), then
+*  
+*     P = P(z-1) * ... * P(2) * P(1)
+*  
+*  and when DIRECT = 'B' (Backward sequence), then
+*  
+*     P = P(1) * P(2) * ... * P(z-1)
+*  
+*  where P(k) is a plane rotation matrix defined by the 2-by-2 rotation
+*  
+*     R(k) = (  c(k)  s(k) )
+*          = ( -s(k)  c(k) ).
+*  
+*  When PIVOT = 'V' (Variable pivot), the rotation is performed
+*  for the plane (k,k+1), i.e., P(k) has the form
+*  
+*     P(k) = (  1                                            )
+*            (       ...                                     )
+*            (              1                                )
+*            (                   c(k)  s(k)                  )
+*            (                  -s(k)  c(k)                  )
+*            (                                1              )
+*            (                                     ...       )
+*            (                                            1  )
+*  
+*  where R(k) appears as a rank-2 modification to the identity matrix in
+*  rows and columns k and k+1.
+*  
+*  When PIVOT = 'T' (Top pivot), the rotation is performed for the
+*  plane (1,k+1), so P(k) has the form
+*  
+*     P(k) = (  c(k)                    s(k)                 )
+*            (         1                                     )
+*            (              ...                              )
+*            (                     1                         )
+*            ( -s(k)                    c(k)                 )
+*            (                                 1             )
+*            (                                      ...      )
+*            (                                             1 )
+*  
+*  where R(k) appears in rows and columns 1 and k+1.
+*  
+*  Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is
+*  performed for the plane (k,z), giving P(k) the form
+*  
+*     P(k) = ( 1                                             )
+*            (      ...                                      )
+*            (             1                                 )
+*            (                  c(k)                    s(k) )
+*            (                         1                     )
+*            (                              ...              )
+*            (                                     1         )
+*            (                 -s(k)                    c(k) )
+*  
+*  where R(k) appears in rows and columns k and z.  The rotations are
+*  performed without ever forming P(k) explicitly.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          Specifies whether the plane rotation matrix P is applied to
+*          A on the left or the right.
+*          = 'L':  Left, compute A := P*A
+*          = 'R':  Right, compute A:= A*P**T
+*
+*  PIVOT   (input) CHARACTER*1
+*          Specifies the plane for which P(k) is a plane rotation
+*          matrix.
+*          = 'V':  Variable pivot, the plane (k,k+1)
+*          = 'T':  Top pivot, the plane (1,k+1)
+*          = 'B':  Bottom pivot, the plane (k,z)
+*
+*  DIRECT  (input) CHARACTER*1
+*          Specifies whether P is a forward or backward sequence of
+*          plane rotations.
+*          = 'F':  Forward, P = P(z-1)*...*P(2)*P(1)
+*          = 'B':  Backward, P = P(1)*P(2)*...*P(z-1)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  If m <= 1, an immediate
+*          return is effected.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  If n <= 1, an
+*          immediate return is effected.
+*
+*  C       (input) DOUBLE PRECISION array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The cosines c(k) of the plane rotations.
+*
+*  S       (input) DOUBLE PRECISION array, dimension
+*                  (M-1) if SIDE = 'L'
+*                  (N-1) if SIDE = 'R'
+*          The sines s(k) of the plane rotations.  The 2-by-2 plane
+*          rotation part of the matrix P(k), R(k), has the form
+*          R(k) = (  c(k)  s(k) )
+*                 ( -s(k)  c(k) ).
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          The M-by-N matrix A.  On exit, A is overwritten by P*A if
+*          SIDE = 'R' or by A*P**T if SIDE = 'L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, INFO, J
+      DOUBLE PRECISION   CTEMP, STEMP
+      COMPLEX*16         TEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters
+*
+      INFO = 0
+      IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THEN
+         INFO = 1
+      ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT,
+     $         'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THEN
+         INFO = 2
+      ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) )
+     $          THEN
+         INFO = 3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = 4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = 5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = 9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLASR ', INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )
+     $   RETURN
+      IF( LSAME( SIDE, 'L' ) ) THEN
+*
+*        Form  P * A
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 20 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 10 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   10                CONTINUE
+                  END IF
+   20          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 40 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 30 I = 1, N
+                        TEMP = A( J+1, I )
+                        A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )
+                        A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )
+   30                CONTINUE
+                  END IF
+   40          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 60 J = 2, M
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 50 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   50                CONTINUE
+                  END IF
+   60          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 80 J = M, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 70 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )
+                        A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )
+   70                CONTINUE
+                  END IF
+   80          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 100 J = 1, M - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 90 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+   90                CONTINUE
+                  END IF
+  100          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 120 J = M - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 110 I = 1, N
+                        TEMP = A( J, I )
+                        A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP
+                        A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP
+  110                CONTINUE
+                  END IF
+  120          CONTINUE
+            END IF
+         END IF
+      ELSE IF( LSAME( SIDE, 'R' ) ) THEN
+*
+*        Form A * P'
+*
+         IF( LSAME( PIVOT, 'V' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 140 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 130 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  130                CONTINUE
+                  END IF
+  140          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 160 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 150 I = 1, M
+                        TEMP = A( I, J+1 )
+                        A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
+                        A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
+  150                CONTINUE
+                  END IF
+  160          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'T' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 180 J = 2, N
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 170 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  170                CONTINUE
+                  END IF
+  180          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 200 J = N, 2, -1
+                  CTEMP = C( J-1 )
+                  STEMP = S( J-1 )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 190 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
+                        A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
+  190                CONTINUE
+                  END IF
+  200          CONTINUE
+            END IF
+         ELSE IF( LSAME( PIVOT, 'B' ) ) THEN
+            IF( LSAME( DIRECT, 'F' ) ) THEN
+               DO 220 J = 1, N - 1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 210 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  210                CONTINUE
+                  END IF
+  220          CONTINUE
+            ELSE IF( LSAME( DIRECT, 'B' ) ) THEN
+               DO 240 J = N - 1, 1, -1
+                  CTEMP = C( J )
+                  STEMP = S( J )
+                  IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
+                     DO 230 I = 1, M
+                        TEMP = A( I, J )
+                        A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
+                        A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
+  230                CONTINUE
+                  END IF
+  240          CONTINUE
+            END IF
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZLASR
+*
+      END
diff --git a/libcruft/lapack/zlassq.f b/libcruft/lapack/zlassq.f
new file mode 100644
index 0000000..a209984
--- /dev/null
+++ b/libcruft/lapack/zlassq.f
@@ -0,0 +1,101 @@
+      SUBROUTINE ZLASSQ( N, X, INCX, SCALE, SUMSQ )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, N
+      DOUBLE PRECISION   SCALE, SUMSQ
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLASSQ returns the values scl and ssq such that
+*
+*     ( scl**2 )*ssq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
+*
+*  where x( i ) = abs( X( 1 + ( i - 1 )*INCX ) ). The value of sumsq is
+*  assumed to be at least unity and the value of ssq will then satisfy
+*
+*     1.0 .le. ssq .le. ( sumsq + 2*n ).
+*
+*  scale is assumed to be non-negative and scl returns the value
+*
+*     scl = max( scale, abs( real( x( i ) ) ), abs( aimag( x( i ) ) ) ),
+*            i
+*
+*  scale and sumsq must be supplied in SCALE and SUMSQ respectively.
+*  SCALE and SUMSQ are overwritten by scl and ssq respectively.
+*
+*  The routine makes only one pass through the vector X.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements to be used from the vector X.
+*
+*  X       (input) COMPLEX*16 array, dimension (N)
+*          The vector x as described above.
+*             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of the vector X.
+*          INCX > 0.
+*
+*  SCALE   (input/output) DOUBLE PRECISION
+*          On entry, the value  scale  in the equation above.
+*          On exit, SCALE is overwritten with the value  scl .
+*
+*  SUMSQ   (input/output) DOUBLE PRECISION
+*          On entry, the value  sumsq  in the equation above.
+*          On exit, SUMSQ is overwritten with the value  ssq .
+*
+* =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            IX
+      DOUBLE PRECISION   TEMP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.GT.0 ) THEN
+         DO 10 IX = 1, 1 + ( N-1 )*INCX, INCX
+            IF( DBLE( X( IX ) ).NE.ZERO ) THEN
+               TEMP1 = ABS( DBLE( X( IX ) ) )
+               IF( SCALE.LT.TEMP1 ) THEN
+                  SUMSQ = 1 + SUMSQ*( SCALE / TEMP1 )**2
+                  SCALE = TEMP1
+               ELSE
+                  SUMSQ = SUMSQ + ( TEMP1 / SCALE )**2
+               END IF
+            END IF
+            IF( DIMAG( X( IX ) ).NE.ZERO ) THEN
+               TEMP1 = ABS( DIMAG( X( IX ) ) )
+               IF( SCALE.LT.TEMP1 ) THEN
+                  SUMSQ = 1 + SUMSQ*( SCALE / TEMP1 )**2
+                  SCALE = TEMP1
+               ELSE
+                  SUMSQ = SUMSQ + ( TEMP1 / SCALE )**2
+               END IF
+            END IF
+   10    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLASSQ
+*
+      END
diff --git a/libcruft/lapack/zlaswp.f b/libcruft/lapack/zlaswp.f
new file mode 100644
index 0000000..8b07e48
--- /dev/null
+++ b/libcruft/lapack/zlaswp.f
@@ -0,0 +1,119 @@
+      SUBROUTINE ZLASWP( N, A, LDA, K1, K2, IPIV, INCX )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, K1, K2, LDA, N
+*     ..
+*     .. Array Arguments ..
+      INTEGER            IPIV( * )
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLASWP performs a series of row interchanges on the matrix A.
+*  One row interchange is initiated for each of rows K1 through K2 of A.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the matrix of column dimension N to which the row
+*          interchanges will be applied.
+*          On exit, the permuted matrix.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*
+*  K1      (input) INTEGER
+*          The first element of IPIV for which a row interchange will
+*          be done.
+*
+*  K2      (input) INTEGER
+*          The last element of IPIV for which a row interchange will
+*          be done.
+*
+*  IPIV    (input) INTEGER array, dimension (K2*abs(INCX))
+*          The vector of pivot indices.  Only the elements in positions
+*          K1 through K2 of IPIV are accessed.
+*          IPIV(K) = L implies rows K and L are to be interchanged.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of IPIV.  If IPIV
+*          is negative, the pivots are applied in reverse order.
+*
+*  Further Details
+*  ===============
+*
+*  Modified by
+*   R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, I1, I2, INC, IP, IX, IX0, J, K, N32
+      COMPLEX*16         TEMP
+*     ..
+*     .. Executable Statements ..
+*
+*     Interchange row I with row IPIV(I) for each of rows K1 through K2.
+*
+      IF( INCX.GT.0 ) THEN
+         IX0 = K1
+         I1 = K1
+         I2 = K2
+         INC = 1
+      ELSE IF( INCX.LT.0 ) THEN
+         IX0 = 1 + ( 1-K2 )*INCX
+         I1 = K2
+         I2 = K1
+         INC = -1
+      ELSE
+         RETURN
+      END IF
+*
+      N32 = ( N / 32 )*32
+      IF( N32.NE.0 ) THEN
+         DO 30 J = 1, N32, 32
+            IX = IX0
+            DO 20 I = I1, I2, INC
+               IP = IPIV( IX )
+               IF( IP.NE.I ) THEN
+                  DO 10 K = J, J + 31
+                     TEMP = A( I, K )
+                     A( I, K ) = A( IP, K )
+                     A( IP, K ) = TEMP
+   10             CONTINUE
+               END IF
+               IX = IX + INCX
+   20       CONTINUE
+   30    CONTINUE
+      END IF
+      IF( N32.NE.N ) THEN
+         N32 = N32 + 1
+         IX = IX0
+         DO 50 I = I1, I2, INC
+            IP = IPIV( IX )
+            IF( IP.NE.I ) THEN
+               DO 40 K = N32, N
+                  TEMP = A( I, K )
+                  A( I, K ) = A( IP, K )
+                  A( IP, K ) = TEMP
+   40          CONTINUE
+            END IF
+            IX = IX + INCX
+   50    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLASWP
+*
+      END
diff --git a/libcruft/lapack/zlatbs.f b/libcruft/lapack/zlatbs.f
new file mode 100644
index 0000000..5dccd83
--- /dev/null
+++ b/libcruft/lapack/zlatbs.f
@@ -0,0 +1,908 @@
+      SUBROUTINE ZLATBS( UPLO, TRANS, DIAG, NORMIN, N, KD, AB, LDAB, X,
+     $                   SCALE, CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, KD, LDAB, N
+      DOUBLE PRECISION   SCALE
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   CNORM( * )
+      COMPLEX*16         AB( LDAB, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLATBS solves one of the triangular systems
+*
+*     A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b,
+*
+*  with scaling to prevent overflow, where A is an upper or lower
+*  triangular band matrix.  Here A' denotes the transpose of A, x and b
+*  are n-element vectors, and s is a scaling factor, usually less than
+*  or equal to 1, chosen so that the components of x will be less than
+*  the overflow threshold.  If the unscaled problem will not cause
+*  overflow, the Level 2 BLAS routine ZTBSV is called.  If the matrix A
+*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a
+*  non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b     (No transpose)
+*          = 'T':  Solve A**T * x = s*b  (Transpose)
+*          = 'C':  Solve A**H * x = s*b  (Conjugate transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of subdiagonals or superdiagonals in the
+*          triangular matrix A.  KD >= 0.
+*
+*  AB      (input) COMPLEX*16 array, dimension (LDAB,N)
+*          The upper or lower triangular band matrix A, stored in the
+*          first KD+1 rows of the array. The j-th column of A is stored
+*          in the j-th column of the array AB as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  X       (input/output) COMPLEX*16 array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scaling factor s for the triangular system
+*             A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) DOUBLE PRECISION array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, ZTBSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine ZTBSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A**T *x = b  or
+*  A**H *x = b.  The basic algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call ZTBSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0,
+     $                   TWO = 2.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST, JLEN, MAIND
+      DOUBLE PRECISION   BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
+     $                   XBND, XJ, XMAX
+      COMPLEX*16         CSUMJ, TJJS, USCAL, ZDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX, IZAMAX
+      DOUBLE PRECISION   DLAMCH, DZASUM
+      COMPLEX*16         ZDOTC, ZDOTU, ZLADIV
+      EXTERNAL           LSAME, IDAMAX, IZAMAX, DLAMCH, DZASUM, ZDOTC,
+     $                   ZDOTU, ZLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, XERBLA, ZAXPY, ZDSCAL, ZTBSV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1, CABS2
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+      CABS2( ZDUM ) = ABS( DBLE( ZDUM ) / 2.D0 ) +
+     $                ABS( DIMAG( ZDUM ) / 2.D0 )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLATBS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM / DLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               JLEN = MIN( KD, J-1 )
+               CNORM( J ) = DZASUM( JLEN, AB( KD+1-JLEN, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N
+               JLEN = MIN( KD, N-J )
+               IF( JLEN.GT.0 ) THEN
+                  CNORM( J ) = DZASUM( JLEN, AB( 2, J ), 1 )
+               ELSE
+                  CNORM( J ) = ZERO
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM/2.
+*
+      IMAX = IDAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM*HALF ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = HALF / ( SMLNUM*TMAX )
+         CALL DSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine ZTBSV can be used.
+*
+      XMAX = ZERO
+      DO 30 J = 1, N
+         XMAX = MAX( XMAX, CABS2( X( J ) ) )
+   30 CONTINUE
+      XBND = XMAX
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 60
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+               TJJS = AB( MAIND, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = G(j-1) / abs(A(j,j))
+*
+                  XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+*
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   40       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 50 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   50       CONTINUE
+         END IF
+   60    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A**T * x = b  or  A**H * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+            MAIND = KD + 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+            MAIND = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 90
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+               TJJS = AB( MAIND, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+                  IF( XJ.GT.TJJ )
+     $               XBND = XBND*( TJJ / XJ )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+   70       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 80 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   80       CONTINUE
+         END IF
+   90    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL ZTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM*HALF ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = ( BIGNUM*HALF ) / XMAX
+            CALL ZDSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         ELSE
+            XMAX = XMAX*TWO
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 120 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = CABS1( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = AB( MAIND, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 110
+               END IF
+               TJJ = CABS1( TJJS )
+               IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                  IF( TJJ.LT.ONE ) THEN
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                        REC = ONE / XJ
+                        CALL ZDSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                  END IF
+                  X( J ) = ZLADIV( X( J ), TJJS )
+                  XJ = CABS1( X( J ) )
+               ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                  IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                     REC = ( TJJ*BIGNUM ) / XJ
+                     IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                        REC = REC / CNORM( J )
+                     END IF
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+                  X( J ) = ZLADIV( X( J ), TJJS )
+                  XJ = CABS1( X( J ) )
+               ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                  DO 100 I = 1, N
+                     X( I ) = ZERO
+  100             CONTINUE
+                  X( J ) = ONE
+                  XJ = ONE
+                  SCALE = ZERO
+                  XMAX = ZERO
+               END IF
+  110          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL ZDSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(max(1,j-kd):j-1) := x(max(1,j-kd):j-1) -
+*                                             x(j)* A(max(1,j-kd):j-1,j)
+*
+                     JLEN = MIN( KD, J-1 )
+                     CALL ZAXPY( JLEN, -X( J )*TSCAL,
+     $                           AB( KD+1-JLEN, J ), 1, X( J-JLEN ), 1 )
+                     I = IZAMAX( J-1, X, 1 )
+                     XMAX = CABS1( X( I ) )
+                  END IF
+               ELSE IF( J.LT.N ) THEN
+*
+*                 Compute the update
+*                    x(j+1:min(j+kd,n)) := x(j+1:min(j+kd,n)) -
+*                                          x(j) * A(j+1:min(j+kd,n),j)
+*
+                  JLEN = MIN( KD, N-J )
+                  IF( JLEN.GT.0 )
+     $               CALL ZAXPY( JLEN, -X( J )*TSCAL, AB( 2, J ), 1,
+     $                           X( J+1 ), 1 )
+                  I = J + IZAMAX( N-J, X( J+1 ), 1 )
+                  XMAX = CABS1( X( I ) )
+               END IF
+  120       CONTINUE
+*
+         ELSE IF( LSAME( TRANS, 'T' ) ) THEN
+*
+*           Solve A**T * x = b
+*
+            DO 170 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                     REC = MIN( ONE, REC*TJJ )
+                     USCAL = ZLADIV( USCAL, TJJS )
+                  END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.DCMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call ZDOTU to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     CSUMJ = ZDOTU( JLEN, AB( KD+1-JLEN, J ), 1,
+     $                       X( J-JLEN ), 1 )
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     IF( JLEN.GT.1 )
+     $                  CSUMJ = ZDOTU( JLEN, AB( 2, J ), 1, X( J+1 ),
+     $                          1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     DO 130 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( AB( KD+I-JLEN, J )*USCAL )*
+     $                          X( J-JLEN-1+I )
+  130                CONTINUE
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     DO 140 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( AB( I+1, J )*USCAL )*X( J+I )
+  140                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.DCMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJS = AB( MAIND, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 160
+                  END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                           REC = ONE / XJ
+                           CALL ZDSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        CALL ZDSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**T *x = 0.
+*
+                     DO 150 I = 1, N
+                        X( I ) = ZERO
+  150                CONTINUE
+                     X( J ) = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  160             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = ZLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  170       CONTINUE
+*
+         ELSE
+*
+*           Solve A**H * x = b
+*
+            DO 220 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = DCONJG( AB( MAIND, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                     REC = MIN( ONE, REC*TJJ )
+                     USCAL = ZLADIV( USCAL, TJJS )
+                  END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.DCMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call ZDOTC to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     CSUMJ = ZDOTC( JLEN, AB( KD+1-JLEN, J ), 1,
+     $                       X( J-JLEN ), 1 )
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     IF( JLEN.GT.1 )
+     $                  CSUMJ = ZDOTC( JLEN, AB( 2, J ), 1, X( J+1 ),
+     $                          1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     JLEN = MIN( KD, J-1 )
+                     DO 180 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( DCONJG( AB( KD+I-JLEN, J ) )*
+     $                          USCAL )*X( J-JLEN-1+I )
+  180                CONTINUE
+                  ELSE
+                     JLEN = MIN( KD, N-J )
+                     DO 190 I = 1, JLEN
+                        CSUMJ = CSUMJ + ( DCONJG( AB( I+1, J ) )*USCAL )
+     $                          *X( J+I )
+  190                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.DCMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                     TJJS = DCONJG( AB( MAIND, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 210
+                  END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                           REC = ONE / XJ
+                           CALL ZDSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        CALL ZDSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**H *x = 0.
+*
+                     DO 200 I = 1, N
+                        X( I ) = ZERO
+  200                CONTINUE
+                     X( J ) = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  210             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = ZLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  220       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL DSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of ZLATBS
+*
+      END
diff --git a/libcruft/lapack/zlatrd.f b/libcruft/lapack/zlatrd.f
new file mode 100644
index 0000000..5fef7b5
--- /dev/null
+++ b/libcruft/lapack/zlatrd.f
@@ -0,0 +1,279 @@
+      SUBROUTINE ZLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            LDA, LDW, N, NB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   E( * )
+      COMPLEX*16         A( LDA, * ), TAU( * ), W( LDW, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLATRD reduces NB rows and columns of a complex Hermitian matrix A to
+*  Hermitian tridiagonal form by a unitary similarity
+*  transformation Q' * A * Q, and returns the matrices V and W which are
+*  needed to apply the transformation to the unreduced part of A.
+*
+*  If UPLO = 'U', ZLATRD reduces the last NB rows and columns of a
+*  matrix, of which the upper triangle is supplied;
+*  if UPLO = 'L', ZLATRD reduces the first NB rows and columns of a
+*  matrix, of which the lower triangle is supplied.
+*
+*  This is an auxiliary routine called by ZHETRD.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored:
+*          = 'U': Upper triangular
+*          = 'L': Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.
+*
+*  NB      (input) INTEGER
+*          The number of rows and columns to be reduced.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n-by-n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n-by-n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*          On exit:
+*          if UPLO = 'U', the last NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements above the diagonal
+*            with the array TAU, represent the unitary matrix Q as a
+*            product of elementary reflectors;
+*          if UPLO = 'L', the first NB columns have been reduced to
+*            tridiagonal form, with the diagonal elements overwriting
+*            the diagonal elements of A; the elements below the diagonal
+*            with the array TAU, represent the  unitary matrix Q as a
+*            product of elementary reflectors.
+*          See Further Details.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  E       (output) DOUBLE PRECISION array, dimension (N-1)
+*          If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal
+*          elements of the last NB columns of the reduced matrix;
+*          if UPLO = 'L', E(1:nb) contains the subdiagonal elements of
+*          the first NB columns of the reduced matrix.
+*
+*  TAU     (output) COMPLEX*16 array, dimension (N-1)
+*          The scalar factors of the elementary reflectors, stored in
+*          TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'.
+*          See Further Details.
+*
+*  W       (output) COMPLEX*16 array, dimension (LDW,NB)
+*          The n-by-nb matrix W required to update the unreduced part
+*          of A.
+*
+*  LDW     (input) INTEGER
+*          The leading dimension of the array W. LDW >= max(1,N).
+*
+*  Further Details
+*  ===============
+*
+*  If UPLO = 'U', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(n) H(n-1) . . . H(n-nb+1).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i),
+*  and tau in TAU(i-1).
+*
+*  If UPLO = 'L', the matrix Q is represented as a product of elementary
+*  reflectors
+*
+*     Q = H(1) H(2) . . . H(nb).
+*
+*  Each H(i) has the form
+*
+*     H(i) = I - tau * v * v'
+*
+*  where tau is a complex scalar, and v is a complex vector with
+*  v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),
+*  and tau in TAU(i).
+*
+*  The elements of the vectors v together form the n-by-nb matrix V
+*  which is needed, with W, to apply the transformation to the unreduced
+*  part of the matrix, using a Hermitian rank-2k update of the form:
+*  A := A - V*W' - W*V'.
+*
+*  The contents of A on exit are illustrated by the following examples
+*  with n = 5 and nb = 2:
+*
+*  if UPLO = 'U':                       if UPLO = 'L':
+*
+*    (  a   a   a   v4  v5 )              (  d                  )
+*    (      a   a   v4  v5 )              (  1   d              )
+*    (          a   1   v5 )              (  v1  1   a          )
+*    (              d   1  )              (  v1  v2  a   a      )
+*    (                  d  )              (  v1  v2  a   a   a  )
+*
+*  where d denotes a diagonal element of the reduced matrix, a denotes
+*  an element of the original matrix that is unchanged, and vi denotes
+*  an element of the vector defining H(i).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE, HALF
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   HALF = ( 0.5D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, IW
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZAXPY, ZGEMV, ZHEMV, ZLACGV, ZLARFG, ZSCAL
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX*16         ZDOTC
+      EXTERNAL           LSAME, ZDOTC
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+      IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*        Reduce last NB columns of upper triangle
+*
+         DO 10 I = N, N - NB + 1, -1
+            IW = I - N + NB
+            IF( I.LT.N ) THEN
+*
+*              Update A(1:i,i)
+*
+               A( I, I ) = DBLE( A( I, I ) )
+               CALL ZLACGV( N-I, W( I, IW+1 ), LDW )
+               CALL ZGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ),
+     $                     LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 )
+               CALL ZLACGV( N-I, W( I, IW+1 ), LDW )
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+               CALL ZGEMV( 'No transpose', I, N-I, -ONE, W( 1, IW+1 ),
+     $                     LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 )
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+               A( I, I ) = DBLE( A( I, I ) )
+            END IF
+            IF( I.GT.1 ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(1:i-2,i)
+*
+               ALPHA = A( I-1, I )
+               CALL ZLARFG( I-1, ALPHA, A( 1, I ), 1, TAU( I-1 ) )
+               E( I-1 ) = ALPHA
+               A( I-1, I ) = ONE
+*
+*              Compute W(1:i-1,i)
+*
+               CALL ZHEMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1,
+     $                     ZERO, W( 1, IW ), 1 )
+               IF( I.LT.N ) THEN
+                  CALL ZGEMV( 'Conjugate transpose', I-1, N-I, ONE,
+     $                        W( 1, IW+1 ), LDW, A( 1, I ), 1, ZERO,
+     $                        W( I+1, IW ), 1 )
+                  CALL ZGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+                  CALL ZGEMV( 'Conjugate transpose', I-1, N-I, ONE,
+     $                        A( 1, I+1 ), LDA, A( 1, I ), 1, ZERO,
+     $                        W( I+1, IW ), 1 )
+                  CALL ZGEMV( 'No transpose', I-1, N-I, -ONE,
+     $                        W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE,
+     $                        W( 1, IW ), 1 )
+               END IF
+               CALL ZSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 )
+               ALPHA = -HALF*TAU( I-1 )*ZDOTC( I-1, W( 1, IW ), 1,
+     $                 A( 1, I ), 1 )
+               CALL ZAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 )
+            END IF
+*
+   10    CONTINUE
+      ELSE
+*
+*        Reduce first NB columns of lower triangle
+*
+         DO 20 I = 1, NB
+*
+*           Update A(i:n,i)
+*
+            A( I, I ) = DBLE( A( I, I ) )
+            CALL ZLACGV( I-1, W( I, 1 ), LDW )
+            CALL ZGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ),
+     $                  LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 )
+            CALL ZLACGV( I-1, W( I, 1 ), LDW )
+            CALL ZLACGV( I-1, A( I, 1 ), LDA )
+            CALL ZGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ),
+     $                  LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 )
+            CALL ZLACGV( I-1, A( I, 1 ), LDA )
+            A( I, I ) = DBLE( A( I, I ) )
+            IF( I.LT.N ) THEN
+*
+*              Generate elementary reflector H(i) to annihilate
+*              A(i+2:n,i)
+*
+               ALPHA = A( I+1, I )
+               CALL ZLARFG( N-I, ALPHA, A( MIN( I+2, N ), I ), 1,
+     $                      TAU( I ) )
+               E( I ) = ALPHA
+               A( I+1, I ) = ONE
+*
+*              Compute W(i+1:n,i)
+*
+               CALL ZHEMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA,
+     $                     A( I+1, I ), 1, ZERO, W( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', N-I, I-1, ONE,
+     $                     W( I+1, 1 ), LDW, A( I+1, I ), 1, ZERO,
+     $                     W( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, 1 ),
+     $                     LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL ZGEMV( 'Conjugate transpose', N-I, I-1, ONE,
+     $                     A( I+1, 1 ), LDA, A( I+1, I ), 1, ZERO,
+     $                     W( 1, I ), 1 )
+               CALL ZGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, 1 ),
+     $                     LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 )
+               CALL ZSCAL( N-I, TAU( I ), W( I+1, I ), 1 )
+               ALPHA = -HALF*TAU( I )*ZDOTC( N-I, W( I+1, I ), 1,
+     $                 A( I+1, I ), 1 )
+               CALL ZAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), 1 )
+            END IF
+*
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLATRD
+*
+      END
diff --git a/libcruft/lapack/zlatrs.f b/libcruft/lapack/zlatrs.f
new file mode 100644
index 0000000..7466096
--- /dev/null
+++ b/libcruft/lapack/zlatrs.f
@@ -0,0 +1,879 @@
+      SUBROUTINE ZLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
+     $                   CNORM, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORMIN, TRANS, UPLO
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   SCALE
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   CNORM( * )
+      COMPLEX*16         A( LDA, * ), X( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLATRS solves one of the triangular systems
+*
+*     A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b,
+*
+*  with scaling to prevent overflow.  Here A is an upper or lower
+*  triangular matrix, A**T denotes the transpose of A, A**H denotes the
+*  conjugate transpose of A, x and b are n-element vectors, and s is a
+*  scaling factor, usually less than or equal to 1, chosen so that the
+*  components of x will be less than the overflow threshold.  If the
+*  unscaled problem will not cause overflow, the Level 2 BLAS routine
+*  ZTRSV is called. If the matrix A is singular (A(j,j) = 0 for some j),
+*  then s is set to 0 and a non-trivial solution to A*x = 0 is returned.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the operation applied to A.
+*          = 'N':  Solve A * x = s*b     (No transpose)
+*          = 'T':  Solve A**T * x = s*b  (Transpose)
+*          = 'C':  Solve A**H * x = s*b  (Conjugate transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  NORMIN  (input) CHARACTER*1
+*          Specifies whether CNORM has been set or not.
+*          = 'Y':  CNORM contains the column norms on entry
+*          = 'N':  CNORM is not set on entry.  On exit, the norms will
+*                  be computed and stored in CNORM.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading n by n
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading n by n lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max (1,N).
+*
+*  X       (input/output) COMPLEX*16 array, dimension (N)
+*          On entry, the right hand side b of the triangular system.
+*          On exit, X is overwritten by the solution vector x.
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scaling factor s for the triangular system
+*             A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b.
+*          If SCALE = 0, the matrix A is singular or badly scaled, and
+*          the vector x is an exact or approximate solution to A*x = 0.
+*
+*  CNORM   (input or output) DOUBLE PRECISION array, dimension (N)
+*
+*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
+*          contains the norm of the off-diagonal part of the j-th column
+*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal
+*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
+*          must be greater than or equal to the 1-norm.
+*
+*          If NORMIN = 'N', CNORM is an output argument and CNORM(j)
+*          returns the 1-norm of the offdiagonal part of the j-th column
+*          of A.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -k, the k-th argument had an illegal value
+*
+*  Further Details
+*  ======= =======
+*
+*  A rough bound on x is computed; if that is less than overflow, ZTRSV
+*  is called, otherwise, specific code is used which checks for possible
+*  overflow or divide-by-zero at every operation.
+*
+*  A columnwise scheme is used for solving A*x = b.  The basic algorithm
+*  if A is lower triangular is
+*
+*       x[1:n] := b[1:n]
+*       for j = 1, ..., n
+*            x(j) := x(j) / A(j,j)
+*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
+*       end
+*
+*  Define bounds on the components of x after j iterations of the loop:
+*     M(j) = bound on x[1:j]
+*     G(j) = bound on x[j+1:n]
+*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
+*
+*  Then for iteration j+1 we have
+*     M(j+1) <= G(j) / | A(j+1,j+1) |
+*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
+*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
+*
+*  where CNORM(j+1) is greater than or equal to the infinity-norm of
+*  column j+1 of A, not counting the diagonal.  Hence
+*
+*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
+*                  1<=i<=j
+*  and
+*
+*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
+*                                   1<=i< j
+*
+*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine ZTRSV if the
+*  reciprocal of the largest M(j), j=1,..,n, is larger than
+*  max(underflow, 1/overflow).
+*
+*  The bound on x(j) is also used to determine when a step in the
+*  columnwise method can be performed without fear of overflow.  If
+*  the computed bound is greater than a large constant, x is scaled to
+*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to
+*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
+*
+*  Similarly, a row-wise scheme is used to solve A**T *x = b  or
+*  A**H *x = b.  The basic algorithm for A upper triangular is
+*
+*       for j = 1, ..., n
+*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
+*       end
+*
+*  We simultaneously compute two bounds
+*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
+*       M(j) = bound on x(i), 1<=i<=j
+*
+*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
+*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
+*  Then the bound on x(j) is
+*
+*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
+*
+*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
+*                      1<=i<=j
+*
+*  and we can safely call ZTRSV if 1/M(n) and 1/G(n) are both greater
+*  than max(underflow, 1/overflow).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, HALF, ONE, TWO
+      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0,
+     $                   TWO = 2.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRAN, NOUNIT, UPPER
+      INTEGER            I, IMAX, J, JFIRST, JINC, JLAST
+      DOUBLE PRECISION   BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
+     $                   XBND, XJ, XMAX
+      COMPLEX*16         CSUMJ, TJJS, USCAL, ZDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX, IZAMAX
+      DOUBLE PRECISION   DLAMCH, DZASUM
+      COMPLEX*16         ZDOTC, ZDOTU, ZLADIV
+      EXTERNAL           LSAME, IDAMAX, IZAMAX, DLAMCH, DZASUM, ZDOTC,
+     $                   ZDOTU, ZLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DSCAL, XERBLA, ZAXPY, ZDSCAL, ZTRSV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1, CABS2
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+      CABS2( ZDUM ) = ABS( DBLE( ZDUM ) / 2.D0 ) +
+     $                ABS( DIMAG( ZDUM ) / 2.D0 )
+*     ..
+*     .. Executable Statements ..
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+*     Test the input parameters.
+*
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
+     $         LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
+     $         LSAME( NORMIN, 'N' ) ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLATRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine machine dependent parameters to control overflow.
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM / DLAMCH( 'Precision' )
+      BIGNUM = ONE / SMLNUM
+      SCALE = ONE
+*
+      IF( LSAME( NORMIN, 'N' ) ) THEN
+*
+*        Compute the 1-norm of each column, not including the diagonal.
+*
+         IF( UPPER ) THEN
+*
+*           A is upper triangular.
+*
+            DO 10 J = 1, N
+               CNORM( J ) = DZASUM( J-1, A( 1, J ), 1 )
+   10       CONTINUE
+         ELSE
+*
+*           A is lower triangular.
+*
+            DO 20 J = 1, N - 1
+               CNORM( J ) = DZASUM( N-J, A( J+1, J ), 1 )
+   20       CONTINUE
+            CNORM( N ) = ZERO
+         END IF
+      END IF
+*
+*     Scale the column norms by TSCAL if the maximum element in CNORM is
+*     greater than BIGNUM/2.
+*
+      IMAX = IDAMAX( N, CNORM, 1 )
+      TMAX = CNORM( IMAX )
+      IF( TMAX.LE.BIGNUM*HALF ) THEN
+         TSCAL = ONE
+      ELSE
+         TSCAL = HALF / ( SMLNUM*TMAX )
+         CALL DSCAL( N, TSCAL, CNORM, 1 )
+      END IF
+*
+*     Compute a bound on the computed solution vector to see if the
+*     Level 2 BLAS routine ZTRSV can be used.
+*
+      XMAX = ZERO
+      DO 30 J = 1, N
+         XMAX = MAX( XMAX, CABS2( X( J ) ) )
+   30 CONTINUE
+      XBND = XMAX
+*
+      IF( NOTRAN ) THEN
+*
+*        Compute the growth in A * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         ELSE
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 60
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 40 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+               TJJS = A( J, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = G(j-1) / abs(A(j,j))
+*
+                  XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+*
+               IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
+*
+*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
+*
+                  GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
+               ELSE
+*
+*                 G(j) could overflow, set GROW to 0.
+*
+                  GROW = ZERO
+               END IF
+   40       CONTINUE
+            GROW = XBND
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 50 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 60
+*
+*              G(j) = G(j-1)*( 1 + CNORM(j) )
+*
+               GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
+   50       CONTINUE
+         END IF
+   60    CONTINUE
+*
+      ELSE
+*
+*        Compute the growth in A**T * x = b  or  A**H * x = b.
+*
+         IF( UPPER ) THEN
+            JFIRST = 1
+            JLAST = N
+            JINC = 1
+         ELSE
+            JFIRST = N
+            JLAST = 1
+            JINC = -1
+         END IF
+*
+         IF( TSCAL.NE.ONE ) THEN
+            GROW = ZERO
+            GO TO 90
+         END IF
+*
+         IF( NOUNIT ) THEN
+*
+*           A is non-unit triangular.
+*
+*           Compute GROW = 1/G(j) and XBND = 1/M(j).
+*           Initially, M(0) = max{x(i), i=1,...,n}.
+*
+            GROW = HALF / MAX( XBND, SMLNUM )
+            XBND = GROW
+            DO 70 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
+*
+               XJ = ONE + CNORM( J )
+               GROW = MIN( GROW, XBND / XJ )
+*
+               TJJS = A( J, J )
+               TJJ = CABS1( TJJS )
+*
+               IF( TJJ.GE.SMLNUM ) THEN
+*
+*                 M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
+*
+                  IF( XJ.GT.TJJ )
+     $               XBND = XBND*( TJJ / XJ )
+               ELSE
+*
+*                 M(j) could overflow, set XBND to 0.
+*
+                  XBND = ZERO
+               END IF
+   70       CONTINUE
+            GROW = MIN( GROW, XBND )
+         ELSE
+*
+*           A is unit triangular.
+*
+*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
+*
+            GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
+            DO 80 J = JFIRST, JLAST, JINC
+*
+*              Exit the loop if the growth factor is too small.
+*
+               IF( GROW.LE.SMLNUM )
+     $            GO TO 90
+*
+*              G(j) = ( 1 + CNORM(j) )*G(j-1)
+*
+               XJ = ONE + CNORM( J )
+               GROW = GROW / XJ
+   80       CONTINUE
+         END IF
+   90    CONTINUE
+      END IF
+*
+      IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
+*
+*        Use the Level 2 BLAS solve if the reciprocal of the bound on
+*        elements of X is not too small.
+*
+         CALL ZTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )
+      ELSE
+*
+*        Use a Level 1 BLAS solve, scaling intermediate results.
+*
+         IF( XMAX.GT.BIGNUM*HALF ) THEN
+*
+*           Scale X so that its components are less than or equal to
+*           BIGNUM in absolute value.
+*
+            SCALE = ( BIGNUM*HALF ) / XMAX
+            CALL ZDSCAL( N, SCALE, X, 1 )
+            XMAX = BIGNUM
+         ELSE
+            XMAX = XMAX*TWO
+         END IF
+*
+         IF( NOTRAN ) THEN
+*
+*           Solve A * x = b
+*
+            DO 120 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) / A(j,j), scaling x if necessary.
+*
+               XJ = CABS1( X( J ) )
+               IF( NOUNIT ) THEN
+                  TJJS = A( J, J )*TSCAL
+               ELSE
+                  TJJS = TSCAL
+                  IF( TSCAL.EQ.ONE )
+     $               GO TO 110
+               END IF
+               TJJ = CABS1( TJJS )
+               IF( TJJ.GT.SMLNUM ) THEN
+*
+*                    abs(A(j,j)) > SMLNUM:
+*
+                  IF( TJJ.LT.ONE ) THEN
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by 1/b(j).
+*
+                        REC = ONE / XJ
+                        CALL ZDSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                  END IF
+                  X( J ) = ZLADIV( X( J ), TJJS )
+                  XJ = CABS1( X( J ) )
+               ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                    0 < abs(A(j,j)) <= SMLNUM:
+*
+                  IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
+*                       to avoid overflow when dividing by A(j,j).
+*
+                     REC = ( TJJ*BIGNUM ) / XJ
+                     IF( CNORM( J ).GT.ONE ) THEN
+*
+*                          Scale by 1/CNORM(j) to avoid overflow when
+*                          multiplying x(j) times column j.
+*
+                        REC = REC / CNORM( J )
+                     END IF
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+                  X( J ) = ZLADIV( X( J ), TJJS )
+                  XJ = CABS1( X( J ) )
+               ELSE
+*
+*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                    scale = 0, and compute a solution to A*x = 0.
+*
+                  DO 100 I = 1, N
+                     X( I ) = ZERO
+  100             CONTINUE
+                  X( J ) = ONE
+                  XJ = ONE
+                  SCALE = ZERO
+                  XMAX = ZERO
+               END IF
+  110          CONTINUE
+*
+*              Scale x if necessary to avoid overflow when adding a
+*              multiple of column j of A.
+*
+               IF( XJ.GT.ONE ) THEN
+                  REC = ONE / XJ
+                  IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
+*
+*                    Scale x by 1/(2*abs(x(j))).
+*
+                     REC = REC*HALF
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                  END IF
+               ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
+*
+*                 Scale x by 1/2.
+*
+                  CALL ZDSCAL( N, HALF, X, 1 )
+                  SCALE = SCALE*HALF
+               END IF
+*
+               IF( UPPER ) THEN
+                  IF( J.GT.1 ) THEN
+*
+*                    Compute the update
+*                       x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
+*
+                     CALL ZAXPY( J-1, -X( J )*TSCAL, A( 1, J ), 1, X,
+     $                           1 )
+                     I = IZAMAX( J-1, X, 1 )
+                     XMAX = CABS1( X( I ) )
+                  END IF
+               ELSE
+                  IF( J.LT.N ) THEN
+*
+*                    Compute the update
+*                       x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
+*
+                     CALL ZAXPY( N-J, -X( J )*TSCAL, A( J+1, J ), 1,
+     $                           X( J+1 ), 1 )
+                     I = J + IZAMAX( N-J, X( J+1 ), 1 )
+                     XMAX = CABS1( X( I ) )
+                  END IF
+               END IF
+  120       CONTINUE
+*
+         ELSE IF( LSAME( TRANS, 'T' ) ) THEN
+*
+*           Solve A**T * x = b
+*
+            DO 170 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                     REC = MIN( ONE, REC*TJJ )
+                     USCAL = ZLADIV( USCAL, TJJS )
+                  END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.DCMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call ZDOTU to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     CSUMJ = ZDOTU( J-1, A( 1, J ), 1, X, 1 )
+                  ELSE IF( J.LT.N ) THEN
+                     CSUMJ = ZDOTU( N-J, A( J+1, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     DO 130 I = 1, J - 1
+                        CSUMJ = CSUMJ + ( A( I, J )*USCAL )*X( I )
+  130                CONTINUE
+                  ELSE IF( J.LT.N ) THEN
+                     DO 140 I = J + 1, N
+                        CSUMJ = CSUMJ + ( A( I, J )*USCAL )*X( I )
+  140                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.DCMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+                     TJJS = A( J, J )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 160
+                  END IF
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                           REC = ONE / XJ
+                           CALL ZDSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        CALL ZDSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**T *x = 0.
+*
+                     DO 150 I = 1, N
+                        X( I ) = ZERO
+  150                CONTINUE
+                     X( J ) = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  160             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = ZLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  170       CONTINUE
+*
+         ELSE
+*
+*           Solve A**H * x = b
+*
+            DO 220 J = JFIRST, JLAST, JINC
+*
+*              Compute x(j) = b(j) - sum A(k,j)*x(k).
+*                                    k<>j
+*
+               XJ = CABS1( X( J ) )
+               USCAL = TSCAL
+               REC = ONE / MAX( XMAX, ONE )
+               IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
+*
+*                 If x(j) could overflow, scale x by 1/(2*XMAX).
+*
+                  REC = REC*HALF
+                  IF( NOUNIT ) THEN
+                     TJJS = DCONJG( A( J, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                  END IF
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.ONE ) THEN
+*
+*                       Divide by A(j,j) when scaling x if A(j,j) > 1.
+*
+                     REC = MIN( ONE, REC*TJJ )
+                     USCAL = ZLADIV( USCAL, TJJS )
+                  END IF
+                  IF( REC.LT.ONE ) THEN
+                     CALL ZDSCAL( N, REC, X, 1 )
+                     SCALE = SCALE*REC
+                     XMAX = XMAX*REC
+                  END IF
+               END IF
+*
+               CSUMJ = ZERO
+               IF( USCAL.EQ.DCMPLX( ONE ) ) THEN
+*
+*                 If the scaling needed for A in the dot product is 1,
+*                 call ZDOTC to perform the dot product.
+*
+                  IF( UPPER ) THEN
+                     CSUMJ = ZDOTC( J-1, A( 1, J ), 1, X, 1 )
+                  ELSE IF( J.LT.N ) THEN
+                     CSUMJ = ZDOTC( N-J, A( J+1, J ), 1, X( J+1 ), 1 )
+                  END IF
+               ELSE
+*
+*                 Otherwise, use in-line code for the dot product.
+*
+                  IF( UPPER ) THEN
+                     DO 180 I = 1, J - 1
+                        CSUMJ = CSUMJ + ( DCONJG( A( I, J ) )*USCAL )*
+     $                          X( I )
+  180                CONTINUE
+                  ELSE IF( J.LT.N ) THEN
+                     DO 190 I = J + 1, N
+                        CSUMJ = CSUMJ + ( DCONJG( A( I, J ) )*USCAL )*
+     $                          X( I )
+  190                CONTINUE
+                  END IF
+               END IF
+*
+               IF( USCAL.EQ.DCMPLX( TSCAL ) ) THEN
+*
+*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
+*                 was not used to scale the dotproduct.
+*
+                  X( J ) = X( J ) - CSUMJ
+                  XJ = CABS1( X( J ) )
+                  IF( NOUNIT ) THEN
+                     TJJS = DCONJG( A( J, J ) )*TSCAL
+                  ELSE
+                     TJJS = TSCAL
+                     IF( TSCAL.EQ.ONE )
+     $                  GO TO 210
+                  END IF
+*
+*                    Compute x(j) = x(j) / A(j,j), scaling if necessary.
+*
+                  TJJ = CABS1( TJJS )
+                  IF( TJJ.GT.SMLNUM ) THEN
+*
+*                       abs(A(j,j)) > SMLNUM:
+*
+                     IF( TJJ.LT.ONE ) THEN
+                        IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                             Scale X by 1/abs(x(j)).
+*
+                           REC = ONE / XJ
+                           CALL ZDSCAL( N, REC, X, 1 )
+                           SCALE = SCALE*REC
+                           XMAX = XMAX*REC
+                        END IF
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE IF( TJJ.GT.ZERO ) THEN
+*
+*                       0 < abs(A(j,j)) <= SMLNUM:
+*
+                     IF( XJ.GT.TJJ*BIGNUM ) THEN
+*
+*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
+*
+                        REC = ( TJJ*BIGNUM ) / XJ
+                        CALL ZDSCAL( N, REC, X, 1 )
+                        SCALE = SCALE*REC
+                        XMAX = XMAX*REC
+                     END IF
+                     X( J ) = ZLADIV( X( J ), TJJS )
+                  ELSE
+*
+*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
+*                       scale = 0 and compute a solution to A**H *x = 0.
+*
+                     DO 200 I = 1, N
+                        X( I ) = ZERO
+  200                CONTINUE
+                     X( J ) = ONE
+                     SCALE = ZERO
+                     XMAX = ZERO
+                  END IF
+  210             CONTINUE
+               ELSE
+*
+*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
+*                 product has already been divided by 1/A(j,j).
+*
+                  X( J ) = ZLADIV( X( J ), TJJS ) - CSUMJ
+               END IF
+               XMAX = MAX( XMAX, CABS1( X( J ) ) )
+  220       CONTINUE
+         END IF
+         SCALE = SCALE / TSCAL
+      END IF
+*
+*     Scale the column norms by 1/TSCAL for return.
+*
+      IF( TSCAL.NE.ONE ) THEN
+         CALL DSCAL( N, ONE / TSCAL, CNORM, 1 )
+      END IF
+*
+      RETURN
+*
+*     End of ZLATRS
+*
+      END
diff --git a/libcruft/lapack/zlatrz.f b/libcruft/lapack/zlatrz.f
new file mode 100644
index 0000000..c1c7aab
--- /dev/null
+++ b/libcruft/lapack/zlatrz.f
@@ -0,0 +1,133 @@
+      SUBROUTINE ZLATRZ( M, N, L, A, LDA, TAU, WORK )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            L, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLATRZ factors the M-by-(M+L) complex upper trapezoidal matrix
+*  [ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R  0 ) * Z by means
+*  of unitary transformations, where  Z is an (M+L)-by-(M+L) unitary
+*  matrix and, R and A1 are M-by-M upper triangular matrices.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing the
+*          meaningful part of the Householder vectors. N-M >= L >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements N-L+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          unitary matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (M)
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an l element vector. tau and z( k )
+*  are chosen to annihilate the elements of the kth row of A2.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A2, such that the elements of z( k ) are
+*  in  a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A1.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I
+      COMPLEX*16         ALPHA
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZLACGV, ZLARFG, ZLARZ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      DO 20 I = M, 1, -1
+*
+*        Generate elementary reflector H(i) to annihilate
+*        [ A(i,i) A(i,n-l+1:n) ]
+*
+         CALL ZLACGV( L, A( I, N-L+1 ), LDA )
+         ALPHA = DCONJG( A( I, I ) )
+         CALL ZLARFG( L+1, ALPHA, A( I, N-L+1 ), LDA, TAU( I ) )
+         TAU( I ) = DCONJG( TAU( I ) )
+*
+*        Apply H(i) to A(1:i-1,i:n) from the right
+*
+         CALL ZLARZ( 'Right', I-1, N-I+1, L, A( I, N-L+1 ), LDA,
+     $               DCONJG( TAU( I ) ), A( 1, I ), LDA, WORK )
+         A( I, I ) = DCONJG( ALPHA )
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of ZLATRZ
+*
+      END
diff --git a/libcruft/lapack/zlauu2.f b/libcruft/lapack/zlauu2.f
new file mode 100644
index 0000000..03e95ec
--- /dev/null
+++ b/libcruft/lapack/zlauu2.f
@@ -0,0 +1,143 @@
+      SUBROUTINE ZLAUU2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAUU2 computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the unblocked form of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I
+      DOUBLE PRECISION   AII
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX*16         ZDOTC
+      EXTERNAL           LSAME, ZDOTC
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDSCAL, ZGEMV, ZLACGV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLAUU2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the product U * U'.
+*
+         DO 10 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = AII*AII + DBLE( ZDOTC( N-I, A( I, I+1 ), LDA,
+     $                     A( I, I+1 ), LDA ) )
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+               CALL ZGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),
+     $                     LDA, A( I, I+1 ), LDA, DCMPLX( AII ),
+     $                     A( 1, I ), 1 )
+               CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+            ELSE
+               CALL ZDSCAL( I, AII, A( 1, I ), 1 )
+            END IF
+   10    CONTINUE
+*
+      ELSE
+*
+*        Compute the product L' * L.
+*
+         DO 20 I = 1, N
+            AII = A( I, I )
+            IF( I.LT.N ) THEN
+               A( I, I ) = AII*AII + DBLE( ZDOTC( N-I, A( I+1, I ), 1,
+     $                     A( I+1, I ), 1 ) )
+               CALL ZLACGV( I-1, A( I, 1 ), LDA )
+               CALL ZGEMV( 'Conjugate transpose', N-I, I-1, ONE,
+     $                     A( I+1, 1 ), LDA, A( I+1, I ), 1,
+     $                     DCMPLX( AII ), A( I, 1 ), LDA )
+               CALL ZLACGV( I-1, A( I, 1 ), LDA )
+            ELSE
+               CALL ZDSCAL( I, AII, A( I, 1 ), LDA )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZLAUU2
+*
+      END
diff --git a/libcruft/lapack/zlauum.f b/libcruft/lapack/zlauum.f
new file mode 100644
index 0000000..d408bbc
--- /dev/null
+++ b/libcruft/lapack/zlauum.f
@@ -0,0 +1,160 @@
+      SUBROUTINE ZLAUUM( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZLAUUM computes the product U * U' or L' * L, where the triangular
+*  factor U or L is stored in the upper or lower triangular part of
+*  the array A.
+*
+*  If UPLO = 'U' or 'u' then the upper triangle of the result is stored,
+*  overwriting the factor U in A.
+*  If UPLO = 'L' or 'l' then the lower triangle of the result is stored,
+*  overwriting the factor L in A.
+*
+*  This is the blocked form of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the triangular factor stored in the array A
+*          is upper or lower triangular:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the triangular factor U or L.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the triangular factor U or L.
+*          On exit, if UPLO = 'U', the upper triangle of A is
+*          overwritten with the upper triangle of the product U * U';
+*          if UPLO = 'L', the lower triangle of A is overwritten with
+*          the lower triangle of the product L' * L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+      COMPLEX*16         CONE
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            I, IB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMM, ZHERK, ZLAUU2, ZTRMM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZLAUUM', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'ZLAUUM', UPLO, N, -1, -1, -1 )
+*
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZLAUU2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute the product U * U'.
+*
+            DO 10 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',
+     $                     'Non-unit', I-1, IB, CONE, A( I, I ), LDA,
+     $                     A( 1, I ), LDA )
+               CALL ZLAUU2( 'Upper', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose',
+     $                        I-1, IB, N-I-IB+1, CONE, A( 1, I+IB ),
+     $                        LDA, A( I, I+IB ), LDA, CONE, A( 1, I ),
+     $                        LDA )
+                  CALL ZHERK( 'Upper', 'No transpose', IB, N-I-IB+1,
+     $                        ONE, A( I, I+IB ), LDA, ONE, A( I, I ),
+     $                        LDA )
+               END IF
+   10       CONTINUE
+         ELSE
+*
+*           Compute the product L' * L.
+*
+            DO 20 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+               CALL ZTRMM( 'Left', 'Lower', 'Conjugate transpose',
+     $                     'Non-unit', IB, I-1, CONE, A( I, I ), LDA,
+     $                     A( I, 1 ), LDA )
+               CALL ZLAUU2( 'Lower', IB, A( I, I ), LDA, INFO )
+               IF( I+IB.LE.N ) THEN
+                  CALL ZGEMM( 'Conjugate transpose', 'No transpose', IB,
+     $                        I-1, N-I-IB+1, CONE, A( I+IB, I ), LDA,
+     $                        A( I+IB, 1 ), LDA, CONE, A( I, 1 ), LDA )
+                  CALL ZHERK( 'Lower', 'Conjugate transpose', IB,
+     $                        N-I-IB+1, ONE, A( I+IB, I ), LDA, ONE,
+     $                        A( I, I ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZLAUUM
+*
+      END
diff --git a/libcruft/lapack/zpbcon.f b/libcruft/lapack/zpbcon.f
new file mode 100644
index 0000000..004cffc
--- /dev/null
+++ b/libcruft/lapack/zpbcon.f
@@ -0,0 +1,198 @@
+      SUBROUTINE ZPBCON( UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK,
+     $                   RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         AB( LDAB, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPBCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a complex Hermitian positive definite band matrix using
+*  the Cholesky factorization A = U**H*U or A = L*L**H computed by
+*  ZPBTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of sub-diagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input) COMPLEX*16 array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          The 1-norm (or infinity-norm) of the Hermitian band matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      DOUBLE PRECISION   AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+      COMPLEX*16         ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IZAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDRSCL, ZLACN2, ZLATBS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPBCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of the inverse.
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL ZLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL ZLATBS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, KD, AB, LDAB, WORK, SCALEL, RWORK,
+     $                   INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL ZLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEU, RWORK, INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL ZLATBS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   KD, AB, LDAB, WORK, SCALEL, RWORK, INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL ZLATBS( 'Lower', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, KD, AB, LDAB, WORK, SCALEU, RWORK,
+     $                   INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = IZAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL ZDRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+*
+      RETURN
+*
+*     End of ZPBCON
+*
+      END
diff --git a/libcruft/lapack/zpbtf2.f b/libcruft/lapack/zpbtf2.f
new file mode 100644
index 0000000..13b58a8
--- /dev/null
+++ b/libcruft/lapack/zpbtf2.f
@@ -0,0 +1,200 @@
+      SUBROUTINE ZPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPBTF2 computes the Cholesky factorization of a complex Hermitian
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix, U' is the conjugate transpose
+*  of U, and L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored:
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of super-diagonals of the matrix A if UPLO = 'U',
+*          or the number of sub-diagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) COMPLEX*16 array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the Hermitian band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U'*U or A = L*L' of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, KLD, KN
+      DOUBLE PRECISION   AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDSCAL, ZHER, ZLACGV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MAX, MIN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPBTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      KLD = MAX( 1, LDAB-1 )
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = DBLE( AB( KD+1, J ) )
+            IF( AJJ.LE.ZERO ) THEN
+               AB( KD+1, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            AB( KD+1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of row J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL ZDSCAL( KN, ONE / AJJ, AB( KD, J+1 ), KLD )
+               CALL ZLACGV( KN, AB( KD, J+1 ), KLD )
+               CALL ZHER( 'Upper', KN, -ONE, AB( KD, J+1 ), KLD,
+     $                    AB( KD+1, J+1 ), KLD )
+               CALL ZLACGV( KN, AB( KD, J+1 ), KLD )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = DBLE( AB( 1, J ) )
+            IF( AJJ.LE.ZERO ) THEN
+               AB( 1, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            AB( 1, J ) = AJJ
+*
+*           Compute elements J+1:J+KN of column J and update the
+*           trailing submatrix within the band.
+*
+            KN = MIN( KD, N-J )
+            IF( KN.GT.0 ) THEN
+               CALL ZDSCAL( KN, ONE / AJJ, AB( 2, J ), 1 )
+               CALL ZHER( 'Lower', KN, -ONE, AB( 2, J ), 1,
+     $                    AB( 1, J+1 ), KLD )
+            END IF
+   20    CONTINUE
+      END IF
+      RETURN
+*
+   30 CONTINUE
+      INFO = J
+      RETURN
+*
+*     End of ZPBTF2
+*
+      END
diff --git a/libcruft/lapack/zpbtrf.f b/libcruft/lapack/zpbtrf.f
new file mode 100644
index 0000000..18abd23
--- /dev/null
+++ b/libcruft/lapack/zpbtrf.f
@@ -0,0 +1,371 @@
+      SUBROUTINE ZPBTRF( UPLO, N, KD, AB, LDAB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         AB( LDAB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPBTRF computes the Cholesky factorization of a complex Hermitian
+*  positive definite band matrix A.
+*
+*  The factorization has the form
+*     A = U**H * U,  if UPLO = 'U', or
+*     A = L  * L**H,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  AB      (input/output) COMPLEX*16 array, dimension (LDAB,N)
+*          On entry, the upper or lower triangle of the Hermitian band
+*          matrix A, stored in the first KD+1 rows of the array.  The
+*          j-th column of A is stored in the j-th column of the array AB
+*          as follows:
+*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
+*
+*          On exit, if INFO = 0, the triangular factor U or L from the
+*          Cholesky factorization A = U**H*U or A = L*L**H of the band
+*          matrix A, in the same storage format as A.
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  Further Details
+*  ===============
+*
+*  The band storage scheme is illustrated by the following example, when
+*  N = 6, KD = 2, and UPLO = 'U':
+*
+*  On entry:                       On exit:
+*
+*      *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
+*      *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
+*     a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66
+*
+*  Similarly, if UPLO = 'L' the format of A is as follows:
+*
+*  On entry:                       On exit:
+*
+*     a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
+*     a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
+*     a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *
+*
+*  Array elements marked * are not used by the routine.
+*
+*  Contributed by
+*  Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+      COMPLEX*16         CONE
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ) )
+      INTEGER            NBMAX, LDWORK
+      PARAMETER          ( NBMAX = 32, LDWORK = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I2, I3, IB, II, J, JJ, NB
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         WORK( LDWORK, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMM, ZHERK, ZPBTF2, ZPOTF2, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( ( .NOT.LSAME( UPLO, 'U' ) ) .AND.
+     $    ( .NOT.LSAME( UPLO, 'L' ) ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPBTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment
+*
+      NB = ILAENV( 1, 'ZPBTRF', UPLO, N, KD, -1, -1 )
+*
+*     The block size must not exceed the semi-bandwidth KD, and must not
+*     exceed the limit set by the size of the local array WORK.
+*
+      NB = MIN( NB, NBMAX )
+*
+      IF( NB.LE.1 .OR. NB.GT.KD ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZPBTF2( UPLO, N, KD, AB, LDAB, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( LSAME( UPLO, 'U' ) ) THEN
+*
+*           Compute the Cholesky factorization of a Hermitian band
+*           matrix, given the upper triangle of the matrix in band
+*           storage.
+*
+*           Zero the upper triangle of the work array.
+*
+            DO 20 J = 1, NB
+               DO 10 I = 1, J - 1
+                  WORK( I, J ) = ZERO
+   10          CONTINUE
+   20       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 70 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL ZPOTF2( UPLO, IB, AB( KD+1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11   A12   A13
+*                          A22   A23
+*                                A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A12, A22 and
+*                 A23 are empty if IB = KD. The upper triangle of A13
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A12
+*
+                     CALL ZTRSM( 'Left', 'Upper', 'Conjugate transpose',
+     $                           'Non-unit', IB, I2, CONE,
+     $                           AB( KD+1, I ), LDAB-1,
+     $                           AB( KD+1-IB, I+IB ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL ZHERK( 'Upper', 'Conjugate transpose', I2, IB,
+     $                           -ONE, AB( KD+1-IB, I+IB ), LDAB-1, ONE,
+     $                           AB( KD+1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the lower triangle of A13 into the work array.
+*
+                     DO 40 JJ = 1, I3
+                        DO 30 II = JJ, IB
+                           WORK( II, JJ ) = AB( II-JJ+1, JJ+I+KD-1 )
+   30                   CONTINUE
+   40                CONTINUE
+*
+*                    Update A13 (in the work array).
+*
+                     CALL ZTRSM( 'Left', 'Upper', 'Conjugate transpose',
+     $                           'Non-unit', IB, I3, CONE,
+     $                           AB( KD+1, I ), LDAB-1, WORK, LDWORK )
+*
+*                    Update A23
+*
+                     IF( I2.GT.0 )
+     $                  CALL ZGEMM( 'Conjugate transpose',
+     $                              'No transpose', I2, I3, IB, -CONE,
+     $                              AB( KD+1-IB, I+IB ), LDAB-1, WORK,
+     $                              LDWORK, CONE, AB( 1+IB, I+KD ),
+     $                              LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL ZHERK( 'Upper', 'Conjugate transpose', I3, IB,
+     $                           -ONE, WORK, LDWORK, ONE,
+     $                           AB( KD+1, I+KD ), LDAB-1 )
+*
+*                    Copy the lower triangle of A13 back into place.
+*
+                     DO 60 JJ = 1, I3
+                        DO 50 II = JJ, IB
+                           AB( II-JJ+1, JJ+I+KD-1 ) = WORK( II, JJ )
+   50                   CONTINUE
+   60                CONTINUE
+                  END IF
+               END IF
+   70       CONTINUE
+         ELSE
+*
+*           Compute the Cholesky factorization of a Hermitian band
+*           matrix, given the lower triangle of the matrix in band
+*           storage.
+*
+*           Zero the lower triangle of the work array.
+*
+            DO 90 J = 1, NB
+               DO 80 I = J + 1, NB
+                  WORK( I, J ) = ZERO
+   80          CONTINUE
+   90       CONTINUE
+*
+*           Process the band matrix one diagonal block at a time.
+*
+            DO 140 I = 1, N, NB
+               IB = MIN( NB, N-I+1 )
+*
+*              Factorize the diagonal block
+*
+               CALL ZPOTF2( UPLO, IB, AB( 1, I ), LDAB-1, II )
+               IF( II.NE.0 ) THEN
+                  INFO = I + II - 1
+                  GO TO 150
+               END IF
+               IF( I+IB.LE.N ) THEN
+*
+*                 Update the relevant part of the trailing submatrix.
+*                 If A11 denotes the diagonal block which has just been
+*                 factorized, then we need to update the remaining
+*                 blocks in the diagram:
+*
+*                    A11
+*                    A21   A22
+*                    A31   A32   A33
+*
+*                 The numbers of rows and columns in the partitioning
+*                 are IB, I2, I3 respectively. The blocks A21, A22 and
+*                 A32 are empty if IB = KD. The lower triangle of A31
+*                 lies outside the band.
+*
+                  I2 = MIN( KD-IB, N-I-IB+1 )
+                  I3 = MIN( IB, N-I-KD+1 )
+*
+                  IF( I2.GT.0 ) THEN
+*
+*                    Update A21
+*
+                     CALL ZTRSM( 'Right', 'Lower',
+     $                           'Conjugate transpose', 'Non-unit', I2,
+     $                           IB, CONE, AB( 1, I ), LDAB-1,
+     $                           AB( 1+IB, I ), LDAB-1 )
+*
+*                    Update A22
+*
+                     CALL ZHERK( 'Lower', 'No transpose', I2, IB, -ONE,
+     $                           AB( 1+IB, I ), LDAB-1, ONE,
+     $                           AB( 1, I+IB ), LDAB-1 )
+                  END IF
+*
+                  IF( I3.GT.0 ) THEN
+*
+*                    Copy the upper triangle of A31 into the work array.
+*
+                     DO 110 JJ = 1, IB
+                        DO 100 II = 1, MIN( JJ, I3 )
+                           WORK( II, JJ ) = AB( KD+1-JJ+II, JJ+I-1 )
+  100                   CONTINUE
+  110                CONTINUE
+*
+*                    Update A31 (in the work array).
+*
+                     CALL ZTRSM( 'Right', 'Lower',
+     $                           'Conjugate transpose', 'Non-unit', I3,
+     $                           IB, CONE, AB( 1, I ), LDAB-1, WORK,
+     $                           LDWORK )
+*
+*                    Update A32
+*
+                     IF( I2.GT.0 )
+     $                  CALL ZGEMM( 'No transpose',
+     $                              'Conjugate transpose', I3, I2, IB,
+     $                              -CONE, WORK, LDWORK, AB( 1+IB, I ),
+     $                              LDAB-1, CONE, AB( 1+KD-IB, I+IB ),
+     $                              LDAB-1 )
+*
+*                    Update A33
+*
+                     CALL ZHERK( 'Lower', 'No transpose', I3, IB, -ONE,
+     $                           WORK, LDWORK, ONE, AB( 1, I+KD ),
+     $                           LDAB-1 )
+*
+*                    Copy the upper triangle of A31 back into place.
+*
+                     DO 130 JJ = 1, IB
+                        DO 120 II = 1, MIN( JJ, I3 )
+                           AB( KD+1-JJ+II, JJ+I-1 ) = WORK( II, JJ )
+  120                   CONTINUE
+  130                CONTINUE
+                  END IF
+               END IF
+  140       CONTINUE
+         END IF
+      END IF
+      RETURN
+*
+  150 CONTINUE
+      RETURN
+*
+*     End of ZPBTRF
+*
+      END
diff --git a/libcruft/lapack/zpbtrs.f b/libcruft/lapack/zpbtrs.f
new file mode 100644
index 0000000..ccca34f
--- /dev/null
+++ b/libcruft/lapack/zpbtrs.f
@@ -0,0 +1,145 @@
+      SUBROUTINE ZPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, KD, LDAB, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         AB( LDAB, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPBTRS solves a system of linear equations A*X = B with a Hermitian
+*  positive definite band matrix A using the Cholesky factorization
+*  A = U**H*U or A = L*L**H computed by ZPBTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangular factor stored in AB;
+*          = 'L':  Lower triangular factor stored in AB.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  KD      (input) INTEGER
+*          The number of superdiagonals of the matrix A if UPLO = 'U',
+*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  AB      (input) COMPLEX*16 array, dimension (LDAB,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H of the band matrix A, stored in the
+*          first KD+1 rows of the array.  The j-th column of U or L is
+*          stored in the j-th column of the array AB as follows:
+*          if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
+*          if UPLO ='L', AB(1+i-j,j)    = L(i,j) for j<=i<=min(n,j+kd).
+*
+*  LDAB    (input) INTEGER
+*          The leading dimension of the array AB.  LDAB >= KD+1.
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZTBSV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( KD.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDAB.LT.KD+1 ) THEN
+         INFO = -6
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPBTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+         DO 10 J = 1, NRHS
+*
+*           Solve U'*X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Upper', 'Conjugate transpose', 'Non-unit', N,
+     $                  KD, AB, LDAB, B( 1, J ), 1 )
+*
+*           Solve U*X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Upper', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+         DO 20 J = 1, NRHS
+*
+*           Solve L*X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Lower', 'No transpose', 'Non-unit', N, KD, AB,
+     $                  LDAB, B( 1, J ), 1 )
+*
+*           Solve L'*X = B, overwriting B with X.
+*
+            CALL ZTBSV( 'Lower', 'Conjugate transpose', 'Non-unit', N,
+     $                  KD, AB, LDAB, B( 1, J ), 1 )
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZPBTRS
+*
+      END
diff --git a/libcruft/lapack/zpocon.f b/libcruft/lapack/zpocon.f
new file mode 100644
index 0000000..af24264
--- /dev/null
+++ b/libcruft/lapack/zpocon.f
@@ -0,0 +1,184 @@
+      SUBROUTINE ZPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, RWORK,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   ANORM, RCOND
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPOCON estimates the reciprocal of the condition number (in the
+*  1-norm) of a complex Hermitian positive definite matrix using the
+*  Cholesky factorization A = U**H*U or A = L*L**H computed by ZPOTRF.
+*
+*  An estimate is obtained for norm(inv(A)), and the reciprocal of the
+*  condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H, as computed by ZPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  ANORM   (input) DOUBLE PRECISION
+*          The 1-norm (or infinity-norm) of the Hermitian matrix A.
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an
+*          estimate of the 1-norm of inv(A) computed in this routine.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE
+      DOUBLE PRECISION   AINVNM, SCALE, SCALEL, SCALEU, SMLNUM
+      COMPLEX*16         ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH
+      EXTERNAL           LSAME, IZAMAX, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDRSCL, ZLACN2, ZLATRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MAX
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( ANORM.LT.ZERO ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPOCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      RCOND = ZERO
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      ELSE IF( ANORM.EQ.ZERO ) THEN
+         RETURN
+      END IF
+*
+      SMLNUM = DLAMCH( 'Safe minimum' )
+*
+*     Estimate the 1-norm of inv(A).
+*
+      KASE = 0
+      NORMIN = 'N'
+   10 CONTINUE
+      CALL ZLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+      IF( KASE.NE.0 ) THEN
+         IF( UPPER ) THEN
+*
+*           Multiply by inv(U').
+*
+            CALL ZLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, A, LDA, WORK, SCALEL, RWORK, INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(U).
+*
+            CALL ZLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEU, RWORK, INFO )
+         ELSE
+*
+*           Multiply by inv(L).
+*
+            CALL ZLATRS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,
+     $                   A, LDA, WORK, SCALEL, RWORK, INFO )
+            NORMIN = 'Y'
+*
+*           Multiply by inv(L').
+*
+            CALL ZLATRS( 'Lower', 'Conjugate transpose', 'Non-unit',
+     $                   NORMIN, N, A, LDA, WORK, SCALEU, RWORK, INFO )
+         END IF
+*
+*        Multiply by 1/SCALE if doing so will not cause overflow.
+*
+         SCALE = SCALEL*SCALEU
+         IF( SCALE.NE.ONE ) THEN
+            IX = IZAMAX( N, WORK, 1 )
+            IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )
+     $         GO TO 20
+            CALL ZDRSCL( N, SCALE, WORK, 1 )
+         END IF
+         GO TO 10
+      END IF
+*
+*     Compute the estimate of the reciprocal condition number.
+*
+      IF( AINVNM.NE.ZERO )
+     $   RCOND = ( ONE / AINVNM ) / ANORM
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of ZPOCON
+*
+      END
diff --git a/libcruft/lapack/zpotf2.f b/libcruft/lapack/zpotf2.f
new file mode 100644
index 0000000..ca9df44
--- /dev/null
+++ b/libcruft/lapack/zpotf2.f
@@ -0,0 +1,174 @@
+      SUBROUTINE ZPOTF2( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPOTF2 computes the Cholesky factorization of a complex Hermitian
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U' * U ,  if UPLO = 'U', or
+*     A = L  * L',  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the unblocked version of the algorithm, calling Level 2 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the upper or lower triangular part of the
+*          Hermitian matrix A is stored.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          n by n upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U'*U  or A = L*L'.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite, and the factorization could not be
+*               completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+      COMPLEX*16         CONE
+      PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J
+      DOUBLE PRECISION   AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      COMPLEX*16         ZDOTC
+      EXTERNAL           LSAME, ZDOTC
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDSCAL, ZGEMV, ZLACGV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPOTF2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Compute the Cholesky factorization A = U'*U.
+*
+         DO 10 J = 1, N
+*
+*           Compute U(J,J) and test for non-positive-definiteness.
+*
+            AJJ = DBLE( A( J, J ) ) - ZDOTC( J-1, A( 1, J ), 1,
+     $            A( 1, J ), 1 )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of row J.
+*
+            IF( J.LT.N ) THEN
+               CALL ZLACGV( J-1, A( 1, J ), 1 )
+               CALL ZGEMV( 'Transpose', J-1, N-J, -CONE, A( 1, J+1 ),
+     $                     LDA, A( 1, J ), 1, CONE, A( J, J+1 ), LDA )
+               CALL ZLACGV( J-1, A( 1, J ), 1 )
+               CALL ZDSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
+            END IF
+   10    CONTINUE
+      ELSE
+*
+*        Compute the Cholesky factorization A = L*L'.
+*
+         DO 20 J = 1, N
+*
+*           Compute L(J,J) and test for non-positive-definiteness.
+*
+            AJJ = DBLE( A( J, J ) ) - ZDOTC( J-1, A( J, 1 ), LDA,
+     $            A( J, 1 ), LDA )
+            IF( AJJ.LE.ZERO ) THEN
+               A( J, J ) = AJJ
+               GO TO 30
+            END IF
+            AJJ = SQRT( AJJ )
+            A( J, J ) = AJJ
+*
+*           Compute elements J+1:N of column J.
+*
+            IF( J.LT.N ) THEN
+               CALL ZLACGV( J-1, A( J, 1 ), LDA )
+               CALL ZGEMV( 'No transpose', N-J, J-1, -CONE, A( J+1, 1 ),
+     $                     LDA, A( J, 1 ), LDA, CONE, A( J+1, J ), 1 )
+               CALL ZLACGV( J-1, A( J, 1 ), LDA )
+               CALL ZDSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = J
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of ZPOTF2
+*
+      END
diff --git a/libcruft/lapack/zpotrf.f b/libcruft/lapack/zpotrf.f
new file mode 100644
index 0000000..8677260
--- /dev/null
+++ b/libcruft/lapack/zpotrf.f
@@ -0,0 +1,186 @@
+      SUBROUTINE ZPOTRF( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPOTRF computes the Cholesky factorization of a complex Hermitian
+*  positive definite matrix A.
+*
+*  The factorization has the form
+*     A = U**H * U,  if UPLO = 'U', or
+*     A = L  * L**H,  if UPLO = 'L',
+*  where U is an upper triangular matrix and L is lower triangular.
+*
+*  This is the block version of the algorithm, calling Level 3 BLAS.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
+*          N-by-N upper triangular part of A contains the upper
+*          triangular part of the matrix A, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of A contains the lower
+*          triangular part of the matrix A, and the strictly upper
+*          triangular part of A is not referenced.
+*
+*          On exit, if INFO = 0, the factor U or L from the Cholesky
+*          factorization A = U**H*U or A = L*L**H.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the factorization could not be
+*                completed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      COMPLEX*16         CONE
+      PARAMETER          ( ONE = 1.0D+0, CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            J, JB, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZGEMM, ZHERK, ZPOTF2, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPOTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'ZPOTRF', UPLO, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code.
+*
+         CALL ZPOTF2( UPLO, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code.
+*
+         IF( UPPER ) THEN
+*
+*           Compute the Cholesky factorization A = U'*U.
+*
+            DO 10 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL ZHERK( 'Upper', 'Conjugate transpose', JB, J-1,
+     $                     -ONE, A( 1, J ), LDA, ONE, A( J, J ), LDA )
+               CALL ZPOTF2( 'Upper', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block row.
+*
+                  CALL ZGEMM( 'Conjugate transpose', 'No transpose', JB,
+     $                        N-J-JB+1, J-1, -CONE, A( 1, J ), LDA,
+     $                        A( 1, J+JB ), LDA, CONE, A( J, J+JB ),
+     $                        LDA )
+                  CALL ZTRSM( 'Left', 'Upper', 'Conjugate transpose',
+     $                        'Non-unit', JB, N-J-JB+1, CONE, A( J, J ),
+     $                        LDA, A( J, J+JB ), LDA )
+               END IF
+   10       CONTINUE
+*
+         ELSE
+*
+*           Compute the Cholesky factorization A = L*L'.
+*
+            DO 20 J = 1, N, NB
+*
+*              Update and factorize the current diagonal block and test
+*              for non-positive-definiteness.
+*
+               JB = MIN( NB, N-J+1 )
+               CALL ZHERK( 'Lower', 'No transpose', JB, J-1, -ONE,
+     $                     A( J, 1 ), LDA, ONE, A( J, J ), LDA )
+               CALL ZPOTF2( 'Lower', JB, A( J, J ), LDA, INFO )
+               IF( INFO.NE.0 )
+     $            GO TO 30
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute the current block column.
+*
+                  CALL ZGEMM( 'No transpose', 'Conjugate transpose',
+     $                        N-J-JB+1, JB, J-1, -CONE, A( J+JB, 1 ),
+     $                        LDA, A( J, 1 ), LDA, CONE, A( J+JB, J ),
+     $                        LDA )
+                  CALL ZTRSM( 'Right', 'Lower', 'Conjugate transpose',
+     $                        'Non-unit', N-J-JB+1, JB, CONE, A( J, J ),
+     $                        LDA, A( J+JB, J ), LDA )
+               END IF
+   20       CONTINUE
+         END IF
+      END IF
+      GO TO 40
+*
+   30 CONTINUE
+      INFO = INFO + J - 1
+*
+   40 CONTINUE
+      RETURN
+*
+*     End of ZPOTRF
+*
+      END
diff --git a/libcruft/lapack/zpotri.f b/libcruft/lapack/zpotri.f
new file mode 100644
index 0000000..ab3094a
--- /dev/null
+++ b/libcruft/lapack/zpotri.f
@@ -0,0 +1,96 @@
+      SUBROUTINE ZPOTRI( UPLO, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPOTRI computes the inverse of a complex Hermitian positive definite
+*  matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
+*  computed by ZPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the triangular factor U or L from the Cholesky
+*          factorization A = U**H*U or A = L*L**H, as computed by
+*          ZPOTRF.
+*          On exit, the upper or lower triangle of the (Hermitian)
+*          inverse of A, overwriting the input factor U or L.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the (i,i) element of the factor U or L is
+*                zero, and the inverse could not be computed.
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLAUUM, ZTRTRI
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPOTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Invert the triangular Cholesky factor U or L.
+*
+      CALL ZTRTRI( UPLO, 'Non-unit', N, A, LDA, INFO )
+      IF( INFO.GT.0 )
+     $   RETURN
+*
+*     Form inv(U)*inv(U)' or inv(L)'*inv(L).
+*
+      CALL ZLAUUM( UPLO, N, A, LDA, INFO )
+*
+      RETURN
+*
+*     End of ZPOTRI
+*
+      END
diff --git a/libcruft/lapack/zpotrs.f b/libcruft/lapack/zpotrs.f
new file mode 100644
index 0000000..d2136cc
--- /dev/null
+++ b/libcruft/lapack/zpotrs.f
@@ -0,0 +1,132 @@
+      SUBROUTINE ZPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPOTRS solves a system of linear equations A*X = B with a Hermitian
+*  positive definite matrix A using the Cholesky factorization
+*  A = U**H*U or A = L*L**H computed by ZPOTRF.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  Upper triangle of A is stored;
+*          = 'L':  Lower triangle of A is stored.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The triangular factor U or L from the Cholesky factorization
+*          A = U**H*U or A = L*L**H, as computed by ZPOTRF.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPOTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+      IF( UPPER ) THEN
+*
+*        Solve A*X = B where A = U'*U.
+*
+*        Solve U'*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Upper', 'Conjugate transpose', 'Non-unit',
+     $               N, NRHS, ONE, A, LDA, B, LDB )
+*
+*        Solve U*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+      ELSE
+*
+*        Solve A*X = B where A = L*L'.
+*
+*        Solve L*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Non-unit', N,
+     $               NRHS, ONE, A, LDA, B, LDB )
+*
+*        Solve L'*X = B, overwriting B with X.
+*
+         CALL ZTRSM( 'Left', 'Lower', 'Conjugate transpose', 'Non-unit',
+     $               N, NRHS, ONE, A, LDA, B, LDB )
+      END IF
+*
+      RETURN
+*
+*     End of ZPOTRS
+*
+      END
diff --git a/libcruft/lapack/zptsv.f b/libcruft/lapack/zptsv.f
new file mode 100644
index 0000000..da0f777
--- /dev/null
+++ b/libcruft/lapack/zptsv.f
@@ -0,0 +1,100 @@
+      SUBROUTINE ZPTSV( N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * )
+      COMPLEX*16         B( LDB, * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPTSV computes the solution to a complex system of linear equations
+*  A*X = B, where A is an N-by-N Hermitian positive definite tridiagonal
+*  matrix, and X and B are N-by-NRHS matrices.
+*
+*  A is factored as A = L*D*L**H, and the factored form of A is then
+*  used to solve the system of equations.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the factorization A = L*D*L**H.
+*
+*  E       (input/output) COMPLEX*16 array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L**H factorization of
+*          A.  E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U**H*D*U factorization of A.
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,N)
+*          On entry, the N-by-NRHS right hand side matrix B.
+*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  if INFO = i, the leading minor of order i is not
+*                positive definite, and the solution has not been
+*                computed.  The factorization has not been completed
+*                unless i = N.
+*
+*  =====================================================================
+*
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZPTTRF, ZPTTRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPTSV ', -INFO )
+         RETURN
+      END IF
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      CALL ZPTTRF( N, D, E, INFO )
+      IF( INFO.EQ.0 ) THEN
+*
+*        Solve the system A*X = B, overwriting B with X.
+*
+         CALL ZPTTRS( 'Lower', N, NRHS, D, E, B, LDB, INFO )
+      END IF
+      RETURN
+*
+*     End of ZPTSV
+*
+      END
diff --git a/libcruft/lapack/zpttrf.f b/libcruft/lapack/zpttrf.f
new file mode 100644
index 0000000..6deda45
--- /dev/null
+++ b/libcruft/lapack/zpttrf.f
@@ -0,0 +1,168 @@
+      SUBROUTINE ZPTTRF( N, D, E, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * )
+      COMPLEX*16         E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPTTRF computes the L*D*L' factorization of a complex Hermitian
+*  positive definite tridiagonal matrix A.  The factorization may also
+*  be regarded as having the form A = U'*D*U.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the n diagonal elements of the tridiagonal matrix
+*          A.  On exit, the n diagonal elements of the diagonal matrix
+*          D from the L*D*L' factorization of A.
+*
+*  E       (input/output) COMPLEX*16 array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix A.  On exit, the (n-1) subdiagonal elements of the
+*          unit bidiagonal factor L from the L*D*L' factorization of A.
+*          E can also be regarded as the superdiagonal of the unit
+*          bidiagonal factor U from the U'*D*U factorization of A.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*          > 0: if INFO = k, the leading minor of order k is not
+*               positive definite; if k < N, the factorization could not
+*               be completed, while if k = N, the factorization was
+*               completed, but D(N) <= 0.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO
+      PARAMETER          ( ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, I4
+      DOUBLE PRECISION   EII, EIR, F, G
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DBLE, DCMPLX, DIMAG, MOD
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF( N.LT.0 ) THEN
+         INFO = -1
+         CALL XERBLA( 'ZPTTRF', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Compute the L*D*L' (or U'*D*U) factorization of A.
+*
+      I4 = MOD( N-1, 4 )
+      DO 10 I = 1, I4
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 30
+         END IF
+         EIR = DBLE( E( I ) )
+         EII = DIMAG( E( I ) )
+         F = EIR / D( I )
+         G = EII / D( I )
+         E( I ) = DCMPLX( F, G )
+         D( I+1 ) = D( I+1 ) - F*EIR - G*EII
+   10 CONTINUE
+*
+      DO 20 I = I4 + 1, N - 4, 4
+*
+*        Drop out of the loop if d(i) <= 0: the matrix is not positive
+*        definite.
+*
+         IF( D( I ).LE.ZERO ) THEN
+            INFO = I
+            GO TO 30
+         END IF
+*
+*        Solve for e(i) and d(i+1).
+*
+         EIR = DBLE( E( I ) )
+         EII = DIMAG( E( I ) )
+         F = EIR / D( I )
+         G = EII / D( I )
+         E( I ) = DCMPLX( F, G )
+         D( I+1 ) = D( I+1 ) - F*EIR - G*EII
+*
+         IF( D( I+1 ).LE.ZERO ) THEN
+            INFO = I + 1
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+1) and d(i+2).
+*
+         EIR = DBLE( E( I+1 ) )
+         EII = DIMAG( E( I+1 ) )
+         F = EIR / D( I+1 )
+         G = EII / D( I+1 )
+         E( I+1 ) = DCMPLX( F, G )
+         D( I+2 ) = D( I+2 ) - F*EIR - G*EII
+*
+         IF( D( I+2 ).LE.ZERO ) THEN
+            INFO = I + 2
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+2) and d(i+3).
+*
+         EIR = DBLE( E( I+2 ) )
+         EII = DIMAG( E( I+2 ) )
+         F = EIR / D( I+2 )
+         G = EII / D( I+2 )
+         E( I+2 ) = DCMPLX( F, G )
+         D( I+3 ) = D( I+3 ) - F*EIR - G*EII
+*
+         IF( D( I+3 ).LE.ZERO ) THEN
+            INFO = I + 3
+            GO TO 30
+         END IF
+*
+*        Solve for e(i+3) and d(i+4).
+*
+         EIR = DBLE( E( I+3 ) )
+         EII = DIMAG( E( I+3 ) )
+         F = EIR / D( I+3 )
+         G = EII / D( I+3 )
+         E( I+3 ) = DCMPLX( F, G )
+         D( I+4 ) = D( I+4 ) - F*EIR - G*EII
+   20 CONTINUE
+*
+*     Check d(n) for positive definiteness.
+*
+      IF( D( N ).LE.ZERO )
+     $   INFO = N
+*
+   30 CONTINUE
+      RETURN
+*
+*     End of ZPTTRF
+*
+      END
diff --git a/libcruft/lapack/zpttrs.f b/libcruft/lapack/zpttrs.f
new file mode 100644
index 0000000..e372d00
--- /dev/null
+++ b/libcruft/lapack/zpttrs.f
@@ -0,0 +1,135 @@
+      SUBROUTINE ZPTTRS( UPLO, N, NRHS, D, E, B, LDB, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * )
+      COMPLEX*16         B( LDB, * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPTTRS solves a tridiagonal system of the form
+*     A * X = B
+*  using the factorization A = U'*D*U or A = L*D*L' computed by ZPTTRF.
+*  D is a diagonal matrix specified in the vector D, U (or L) is a unit
+*  bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
+*  the vector E, and X and B are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies the form of the factorization and whether the
+*          vector E is the superdiagonal of the upper bidiagonal factor
+*          U or the subdiagonal of the lower bidiagonal factor L.
+*          = 'U':  A = U'*D*U, E is the superdiagonal of U
+*          = 'L':  A = L*D*L', E is the subdiagonal of L
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          factorization A = U'*D*U or A = L*D*L'.
+*
+*  E       (input) COMPLEX*16 array, dimension (N-1)
+*          If UPLO = 'U', the (n-1) superdiagonal elements of the unit
+*          bidiagonal factor U from the factorization A = U'*D*U.
+*          If UPLO = 'L', the (n-1) subdiagonal elements of the unit
+*          bidiagonal factor L from the factorization A = L*D*L'.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            UPPER
+      INTEGER            IUPLO, J, JB, NB
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZPTTS2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments.
+*
+      INFO = 0
+      UPPER = ( UPLO.EQ.'U' .OR. UPLO.EQ.'u' )
+      IF( .NOT.UPPER .AND. .NOT.( UPLO.EQ.'L' .OR. UPLO.EQ.'l' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZPTTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 .OR. NRHS.EQ.0 )
+     $   RETURN
+*
+*     Determine the number of right-hand sides to solve at a time.
+*
+      IF( NRHS.EQ.1 ) THEN
+         NB = 1
+      ELSE
+         NB = MAX( 1, ILAENV( 1, 'ZPTTRS', UPLO, N, NRHS, -1, -1 ) )
+      END IF
+*
+*     Decode UPLO
+*
+      IF( UPPER ) THEN
+         IUPLO = 1
+      ELSE
+         IUPLO = 0
+      END IF
+*
+      IF( NB.GE.NRHS ) THEN
+         CALL ZPTTS2( IUPLO, N, NRHS, D, E, B, LDB )
+      ELSE
+         DO 10 J = 1, NRHS, NB
+            JB = MIN( NRHS-J+1, NB )
+            CALL ZPTTS2( IUPLO, N, JB, D, E, B( 1, J ), LDB )
+   10    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZPTTRS
+*
+      END
diff --git a/libcruft/lapack/zptts2.f b/libcruft/lapack/zptts2.f
new file mode 100644
index 0000000..e2a90fc
--- /dev/null
+++ b/libcruft/lapack/zptts2.f
@@ -0,0 +1,176 @@
+      SUBROUTINE ZPTTS2( IUPLO, N, NRHS, D, E, B, LDB )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IUPLO, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * )
+      COMPLEX*16         B( LDB, * ), E( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZPTTS2 solves a tridiagonal system of the form
+*     A * X = B
+*  using the factorization A = U'*D*U or A = L*D*L' computed by ZPTTRF.
+*  D is a diagonal matrix specified in the vector D, U (or L) is a unit
+*  bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
+*  the vector E, and X and B are N by NRHS matrices.
+*
+*  Arguments
+*  =========
+*
+*  IUPLO   (input) INTEGER
+*          Specifies the form of the factorization and whether the
+*          vector E is the superdiagonal of the upper bidiagonal factor
+*          U or the subdiagonal of the lower bidiagonal factor L.
+*          = 1:  A = U'*D*U, E is the superdiagonal of U
+*          = 0:  A = L*D*L', E is the subdiagonal of L
+*
+*  N       (input) INTEGER
+*          The order of the tridiagonal matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  D       (input) DOUBLE PRECISION array, dimension (N)
+*          The n diagonal elements of the diagonal matrix D from the
+*          factorization A = U'*D*U or A = L*D*L'.
+*
+*  E       (input) COMPLEX*16 array, dimension (N-1)
+*          If IUPLO = 1, the (n-1) superdiagonal elements of the unit
+*          bidiagonal factor U from the factorization A = U'*D*U.
+*          If IUPLO = 0, the (n-1) subdiagonal elements of the unit
+*          bidiagonal factor L from the factorization A = L*D*L'.
+*
+*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+*          On entry, the right hand side vectors B for the system of
+*          linear equations.
+*          On exit, the solution vectors, X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, J
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           ZDSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+*     Quick return if possible
+*
+      IF( N.LE.1 ) THEN
+         IF( N.EQ.1 )
+     $      CALL ZDSCAL( NRHS, 1.D0 / D( 1 ), B, LDB )
+         RETURN
+      END IF
+*
+      IF( IUPLO.EQ.1 ) THEN
+*
+*        Solve A * X = B using the factorization A = U'*D*U,
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.2 ) THEN
+            J = 1
+   10       CONTINUE
+*
+*           Solve U' * x = b.
+*
+            DO 20 I = 2, N
+               B( I, J ) = B( I, J ) - B( I-1, J )*DCONJG( E( I-1 ) )
+   20       CONTINUE
+*
+*           Solve D * U * x = b.
+*
+            DO 30 I = 1, N
+               B( I, J ) = B( I, J ) / D( I )
+   30       CONTINUE
+            DO 40 I = N - 1, 1, -1
+               B( I, J ) = B( I, J ) - B( I+1, J )*E( I )
+   40       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 10
+            END IF
+         ELSE
+            DO 70 J = 1, NRHS
+*
+*              Solve U' * x = b.
+*
+               DO 50 I = 2, N
+                  B( I, J ) = B( I, J ) - B( I-1, J )*DCONJG( E( I-1 ) )
+   50          CONTINUE
+*
+*              Solve D * U * x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               DO 60 I = N - 1, 1, -1
+                  B( I, J ) = B( I, J ) / D( I ) - B( I+1, J )*E( I )
+   60          CONTINUE
+   70       CONTINUE
+         END IF
+      ELSE
+*
+*        Solve A * X = B using the factorization A = L*D*L',
+*        overwriting each right hand side vector with its solution.
+*
+         IF( NRHS.LE.2 ) THEN
+            J = 1
+   80       CONTINUE
+*
+*           Solve L * x = b.
+*
+            DO 90 I = 2, N
+               B( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )
+   90       CONTINUE
+*
+*           Solve D * L' * x = b.
+*
+            DO 100 I = 1, N
+               B( I, J ) = B( I, J ) / D( I )
+  100       CONTINUE
+            DO 110 I = N - 1, 1, -1
+               B( I, J ) = B( I, J ) - B( I+1, J )*DCONJG( E( I ) )
+  110       CONTINUE
+            IF( J.LT.NRHS ) THEN
+               J = J + 1
+               GO TO 80
+            END IF
+         ELSE
+            DO 140 J = 1, NRHS
+*
+*              Solve L * x = b.
+*
+               DO 120 I = 2, N
+                  B( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )
+  120          CONTINUE
+*
+*              Solve D * L' * x = b.
+*
+               B( N, J ) = B( N, J ) / D( N )
+               DO 130 I = N - 1, 1, -1
+                  B( I, J ) = B( I, J ) / D( I ) -
+     $                        B( I+1, J )*DCONJG( E( I ) )
+  130          CONTINUE
+  140       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZPTTS2
+*
+      END
diff --git a/libcruft/lapack/zrot.f b/libcruft/lapack/zrot.f
new file mode 100644
index 0000000..9c548e2
--- /dev/null
+++ b/libcruft/lapack/zrot.f
@@ -0,0 +1,91 @@
+      SUBROUTINE ZROT( N, CX, INCX, CY, INCY, C, S )
+*
+*  -- LAPACK auxiliary routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, INCY, N
+      DOUBLE PRECISION   C
+      COMPLEX*16         S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         CX( * ), CY( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZROT   applies a plane rotation, where the cos (C) is real and the
+*  sin (S) is complex, and the vectors CX and CY are complex.
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The number of elements in the vectors CX and CY.
+*
+*  CX      (input/output) COMPLEX*16 array, dimension (N)
+*          On input, the vector X.
+*          On output, CX is overwritten with C*X + S*Y.
+*
+*  INCX    (input) INTEGER
+*          The increment between successive values of CY.  INCX <> 0.
+*
+*  CY      (input/output) COMPLEX*16 array, dimension (N)
+*          On input, the vector Y.
+*          On output, CY is overwritten with -CONJG(S)*X + C*Y.
+*
+*  INCY    (input) INTEGER
+*          The increment between successive values of CY.  INCX <> 0.
+*
+*  C       (input) DOUBLE PRECISION
+*  S       (input) COMPLEX*16
+*          C and S define a rotation
+*             [  C          S  ]
+*             [ -conjg(S)   C  ]
+*          where C*C + S*CONJG(S) = 1.0.
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IX, IY
+      COMPLEX*16         STEMP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 .AND. INCY.EQ.1 )
+     $   GO TO 20
+*
+*     Code for unequal increments or equal increments not equal to 1
+*
+      IX = 1
+      IY = 1
+      IF( INCX.LT.0 )
+     $   IX = ( -N+1 )*INCX + 1
+      IF( INCY.LT.0 )
+     $   IY = ( -N+1 )*INCY + 1
+      DO 10 I = 1, N
+         STEMP = C*CX( IX ) + S*CY( IY )
+         CY( IY ) = C*CY( IY ) - DCONJG( S )*CX( IX )
+         CX( IX ) = STEMP
+         IX = IX + INCX
+         IY = IY + INCY
+   10 CONTINUE
+      RETURN
+*
+*     Code for both increments equal to 1
+*
+   20 CONTINUE
+      DO 30 I = 1, N
+         STEMP = C*CX( I ) + S*CY( I )
+         CY( I ) = C*CY( I ) - DCONJG( S )*CX( I )
+         CX( I ) = STEMP
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/lapack/zsteqr.f b/libcruft/lapack/zsteqr.f
new file mode 100644
index 0000000..a72fdd9
--- /dev/null
+++ b/libcruft/lapack/zsteqr.f
@@ -0,0 +1,503 @@
+      SUBROUTINE ZSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPZ
+      INTEGER            INFO, LDZ, N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   D( * ), E( * ), WORK( * )
+      COMPLEX*16         Z( LDZ, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZSTEQR computes all eigenvalues and, optionally, eigenvectors of a
+*  symmetric tridiagonal matrix using the implicit QL or QR method.
+*  The eigenvectors of a full or band complex Hermitian matrix can also
+*  be found if ZHETRD or ZHPTRD or ZHBTRD has been used to reduce this
+*  matrix to tridiagonal form.
+*
+*  Arguments
+*  =========
+*
+*  COMPZ   (input) CHARACTER*1
+*          = 'N':  Compute eigenvalues only.
+*          = 'V':  Compute eigenvalues and eigenvectors of the original
+*                  Hermitian matrix.  On entry, Z must contain the
+*                  unitary matrix used to reduce the original matrix
+*                  to tridiagonal form.
+*          = 'I':  Compute eigenvalues and eigenvectors of the
+*                  tridiagonal matrix.  Z is initialized to the identity
+*                  matrix.
+*
+*  N       (input) INTEGER
+*          The order of the matrix.  N >= 0.
+*
+*  D       (input/output) DOUBLE PRECISION array, dimension (N)
+*          On entry, the diagonal elements of the tridiagonal matrix.
+*          On exit, if INFO = 0, the eigenvalues in ascending order.
+*
+*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
+*          On entry, the (n-1) subdiagonal elements of the tridiagonal
+*          matrix.
+*          On exit, E has been destroyed.
+*
+*  Z       (input/output) COMPLEX*16 array, dimension (LDZ, N)
+*          On entry, if  COMPZ = 'V', then Z contains the unitary
+*          matrix used in the reduction to tridiagonal form.
+*          On exit, if INFO = 0, then if COMPZ = 'V', Z contains the
+*          orthonormal eigenvectors of the original Hermitian matrix,
+*          and if COMPZ = 'I', Z contains the orthonormal eigenvectors
+*          of the symmetric tridiagonal matrix.
+*          If COMPZ = 'N', then Z is not referenced.
+*
+*  LDZ     (input) INTEGER
+*          The leading dimension of the array Z.  LDZ >= 1, and if
+*          eigenvectors are desired, then  LDZ >= max(1,N).
+*
+*  WORK    (workspace) DOUBLE PRECISION array, dimension (max(1,2*N-2))
+*          If COMPZ = 'N', then WORK is not referenced.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*          > 0:  the algorithm has failed to find all the eigenvalues in
+*                a total of 30*N iterations; if INFO = i, then i
+*                elements of E have not converged to zero; on exit, D
+*                and E contain the elements of a symmetric tridiagonal
+*                matrix which is unitarily similar to the original
+*                matrix.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
+      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
+     $                   THREE = 3.0D0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
+     $                   CONE = ( 1.0D0, 0.0D0 ) )
+      INTEGER            MAXIT
+      PARAMETER          ( MAXIT = 30 )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
+     $                   LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
+     $                   NM1, NMAXIT
+      DOUBLE PRECISION   ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
+     $                   S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH, DLANST, DLAPY2
+      EXTERNAL           LSAME, DLAMCH, DLANST, DLAPY2
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLAE2, DLAEV2, DLARTG, DLASCL, DLASRT, XERBLA,
+     $                   ZLASET, ZLASR, ZSWAP
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SIGN, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+*
+      IF( LSAME( COMPZ, 'N' ) ) THEN
+         ICOMPZ = 0
+      ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
+         ICOMPZ = 1
+      ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
+         ICOMPZ = 2
+      ELSE
+         ICOMPZ = -1
+      END IF
+      IF( ICOMPZ.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,
+     $         N ) ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZSTEQR', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+      IF( N.EQ.1 ) THEN
+         IF( ICOMPZ.EQ.2 )
+     $      Z( 1, 1 ) = CONE
+         RETURN
+      END IF
+*
+*     Determine the unit roundoff and over/underflow thresholds.
+*
+      EPS = DLAMCH( 'E' )
+      EPS2 = EPS**2
+      SAFMIN = DLAMCH( 'S' )
+      SAFMAX = ONE / SAFMIN
+      SSFMAX = SQRT( SAFMAX ) / THREE
+      SSFMIN = SQRT( SAFMIN ) / EPS2
+*
+*     Compute the eigenvalues and eigenvectors of the tridiagonal
+*     matrix.
+*
+      IF( ICOMPZ.EQ.2 )
+     $   CALL ZLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
+*
+      NMAXIT = N*MAXIT
+      JTOT = 0
+*
+*     Determine where the matrix splits and choose QL or QR iteration
+*     for each block, according to whether top or bottom diagonal
+*     element is smaller.
+*
+      L1 = 1
+      NM1 = N - 1
+*
+   10 CONTINUE
+      IF( L1.GT.N )
+     $   GO TO 160
+      IF( L1.GT.1 )
+     $   E( L1-1 ) = ZERO
+      IF( L1.LE.NM1 ) THEN
+         DO 20 M = L1, NM1
+            TST = ABS( E( M ) )
+            IF( TST.EQ.ZERO )
+     $         GO TO 30
+            IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
+     $          1 ) ) ) )*EPS ) THEN
+               E( M ) = ZERO
+               GO TO 30
+            END IF
+   20    CONTINUE
+      END IF
+      M = N
+*
+   30 CONTINUE
+      L = L1
+      LSV = L
+      LEND = M
+      LENDSV = LEND
+      L1 = M + 1
+      IF( LEND.EQ.L )
+     $   GO TO 10
+*
+*     Scale submatrix in rows and columns L to LEND
+*
+      ANORM = DLANST( 'I', LEND-L+1, D( L ), E( L ) )
+      ISCALE = 0
+      IF( ANORM.EQ.ZERO )
+     $   GO TO 10
+      IF( ANORM.GT.SSFMAX ) THEN
+         ISCALE = 1
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
+     $                INFO )
+      ELSE IF( ANORM.LT.SSFMIN ) THEN
+         ISCALE = 2
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
+     $                INFO )
+         CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
+     $                INFO )
+      END IF
+*
+*     Choose between QL and QR iteration
+*
+      IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
+         LEND = LSV
+         L = LENDSV
+      END IF
+*
+      IF( LEND.GT.L ) THEN
+*
+*        QL Iteration
+*
+*        Look for small subdiagonal element.
+*
+   40    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDM1 = LEND - 1
+            DO 50 M = L, LENDM1
+               TST = ABS( E( M ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+
+     $             SAFMIN )GO TO 60
+   50       CONTINUE
+         END IF
+*
+         M = LEND
+*
+   60    CONTINUE
+         IF( M.LT.LEND )
+     $      E( M ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 80
+*
+*        If remaining matrix is 2-by-2, use DLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L+1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL DLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )
+               WORK( L ) = C
+               WORK( N-1+L ) = S
+               CALL ZLASR( 'R', 'V', 'B', N, 2, WORK( L ),
+     $                     WORK( N-1+L ), Z( 1, L ), LDZ )
+            ELSE
+               CALL DLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )
+            END IF
+            D( L ) = RT1
+            D( L+1 ) = RT2
+            E( L ) = ZERO
+            L = L + 2
+            IF( L.LE.LEND )
+     $         GO TO 40
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L+1 )-P ) / ( TWO*E( L ) )
+         R = DLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         MM1 = M - 1
+         DO 70 I = MM1, L, -1
+            F = S*E( I )
+            B = C*E( I )
+            CALL DLARTG( G, F, C, S, R )
+            IF( I.NE.M-1 )
+     $         E( I+1 ) = R
+            G = D( I+1 ) - P
+            R = ( D( I )-G )*S + TWO*C*B
+            P = S*R
+            D( I+1 ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = -S
+            END IF
+*
+   70    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = M - L + 1
+            CALL ZLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),
+     $                  Z( 1, L ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( L ) = G
+         GO TO 40
+*
+*        Eigenvalue found.
+*
+   80    CONTINUE
+         D( L ) = P
+*
+         L = L + 1
+         IF( L.LE.LEND )
+     $      GO TO 40
+         GO TO 140
+*
+      ELSE
+*
+*        QR Iteration
+*
+*        Look for small superdiagonal element.
+*
+   90    CONTINUE
+         IF( L.NE.LEND ) THEN
+            LENDP1 = LEND + 1
+            DO 100 M = L, LENDP1, -1
+               TST = ABS( E( M-1 ) )**2
+               IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+
+     $             SAFMIN )GO TO 110
+  100       CONTINUE
+         END IF
+*
+         M = LEND
+*
+  110    CONTINUE
+         IF( M.GT.LEND )
+     $      E( M-1 ) = ZERO
+         P = D( L )
+         IF( M.EQ.L )
+     $      GO TO 130
+*
+*        If remaining matrix is 2-by-2, use DLAE2 or SLAEV2
+*        to compute its eigensystem.
+*
+         IF( M.EQ.L-1 ) THEN
+            IF( ICOMPZ.GT.0 ) THEN
+               CALL DLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )
+               WORK( M ) = C
+               WORK( N-1+M ) = S
+               CALL ZLASR( 'R', 'V', 'F', N, 2, WORK( M ),
+     $                     WORK( N-1+M ), Z( 1, L-1 ), LDZ )
+            ELSE
+               CALL DLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )
+            END IF
+            D( L-1 ) = RT1
+            D( L ) = RT2
+            E( L-1 ) = ZERO
+            L = L - 2
+            IF( L.GE.LEND )
+     $         GO TO 90
+            GO TO 140
+         END IF
+*
+         IF( JTOT.EQ.NMAXIT )
+     $      GO TO 140
+         JTOT = JTOT + 1
+*
+*        Form shift.
+*
+         G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )
+         R = DLAPY2( G, ONE )
+         G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )
+*
+         S = ONE
+         C = ONE
+         P = ZERO
+*
+*        Inner loop
+*
+         LM1 = L - 1
+         DO 120 I = M, LM1
+            F = S*E( I )
+            B = C*E( I )
+            CALL DLARTG( G, F, C, S, R )
+            IF( I.NE.M )
+     $         E( I-1 ) = R
+            G = D( I ) - P
+            R = ( D( I+1 )-G )*S + TWO*C*B
+            P = S*R
+            D( I ) = G + P
+            G = C*R - B
+*
+*           If eigenvectors are desired, then save rotations.
+*
+            IF( ICOMPZ.GT.0 ) THEN
+               WORK( I ) = C
+               WORK( N-1+I ) = S
+            END IF
+*
+  120    CONTINUE
+*
+*        If eigenvectors are desired, then apply saved rotations.
+*
+         IF( ICOMPZ.GT.0 ) THEN
+            MM = L - M + 1
+            CALL ZLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),
+     $                  Z( 1, M ), LDZ )
+         END IF
+*
+         D( L ) = D( L ) - P
+         E( LM1 ) = G
+         GO TO 90
+*
+*        Eigenvalue found.
+*
+  130    CONTINUE
+         D( L ) = P
+*
+         L = L - 1
+         IF( L.GE.LEND )
+     $      GO TO 90
+         GO TO 140
+*
+      END IF
+*
+*     Undo scaling if necessary
+*
+  140 CONTINUE
+      IF( ISCALE.EQ.1 ) THEN
+         CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      ELSE IF( ISCALE.EQ.2 ) THEN
+         CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
+     $                D( LSV ), N, INFO )
+         CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),
+     $                N, INFO )
+      END IF
+*
+*     Check for no convergence to an eigenvalue after a total
+*     of N*MAXIT iterations.
+*
+      IF( JTOT.EQ.NMAXIT ) THEN
+         DO 150 I = 1, N - 1
+            IF( E( I ).NE.ZERO )
+     $         INFO = INFO + 1
+  150    CONTINUE
+         RETURN
+      END IF
+      GO TO 10
+*
+*     Order eigenvalues and eigenvectors.
+*
+  160 CONTINUE
+      IF( ICOMPZ.EQ.0 ) THEN
+*
+*        Use Quick Sort
+*
+         CALL DLASRT( 'I', N, D, INFO )
+*
+      ELSE
+*
+*        Use Selection Sort to minimize swaps of eigenvectors
+*
+         DO 180 II = 2, N
+            I = II - 1
+            K = I
+            P = D( I )
+            DO 170 J = II, N
+               IF( D( J ).LT.P ) THEN
+                  K = J
+                  P = D( J )
+               END IF
+  170       CONTINUE
+            IF( K.NE.I ) THEN
+               D( K ) = D( I )
+               D( I ) = P
+               CALL ZSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
+            END IF
+  180    CONTINUE
+      END IF
+      RETURN
+*
+*     End of ZSTEQR
+*
+      END
diff --git a/libcruft/lapack/ztgevc.f b/libcruft/lapack/ztgevc.f
new file mode 100644
index 0000000..b8da962
--- /dev/null
+++ b/libcruft/lapack/ztgevc.f
@@ -0,0 +1,633 @@
+      SUBROUTINE ZTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
+     $                   LDVL, VR, LDVR, MM, M, WORK, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDP, LDS, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
+     $                   VR( LDVR, * ), WORK( * )
+*     ..
+*
+*
+*  Purpose
+*  =======
+*
+*  ZTGEVC computes some or all of the right and/or left eigenvectors of
+*  a pair of complex matrices (S,P), where S and P are upper triangular.
+*  Matrix pairs of this type are produced by the generalized Schur
+*  factorization of a complex matrix pair (A,B):
+*  
+*     A = Q*S*Z**H,  B = Q*P*Z**H
+*  
+*  as computed by ZGGHRD + ZHGEQZ.
+*  
+*  The right eigenvector x and the left eigenvector y of (S,P)
+*  corresponding to an eigenvalue w are defined by:
+*  
+*     S*x = w*P*x,  (y**H)*S = w*(y**H)*P,
+*  
+*  where y**H denotes the conjugate tranpose of y.
+*  The eigenvalues are not input to this routine, but are computed
+*  directly from the diagonal elements of S and P.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of (S,P), or the products Z*X and/or Q*Y,
+*  where Z and Q are input matrices.
+*  If Q and Z are the unitary factors from the generalized Schur
+*  factorization of a matrix pair (A,B), then Z*X and Q*Y
+*  are the matrices of right and left eigenvectors of (A,B).
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R': compute right eigenvectors only;
+*          = 'L': compute left eigenvectors only;
+*          = 'B': compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A': compute all right and/or left eigenvectors;
+*          = 'B': compute all right and/or left eigenvectors,
+*                 backtransformed by the matrices in VR and/or VL;
+*          = 'S': compute selected right and/or left eigenvectors,
+*                 specified by the logical array SELECT.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          If HOWMNY='S', SELECT specifies the eigenvectors to be
+*          computed.  The eigenvector corresponding to the j-th
+*          eigenvalue is computed if SELECT(j) = .TRUE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrices S and P.  N >= 0.
+*
+*  S       (input) COMPLEX*16 array, dimension (LDS,N)
+*          The upper triangular matrix S from a generalized Schur
+*          factorization, as computed by ZHGEQZ.
+*
+*  LDS     (input) INTEGER
+*          The leading dimension of array S.  LDS >= max(1,N).
+*
+*  P       (input) COMPLEX*16 array, dimension (LDP,N)
+*          The upper triangular matrix P from a generalized Schur
+*          factorization, as computed by ZHGEQZ.  P must have real
+*          diagonal elements.
+*
+*  LDP     (input) INTEGER
+*          The leading dimension of array P.  LDP >= max(1,N).
+*
+*  VL      (input/output) COMPLEX*16 array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the unitary matrix Q
+*          of left Schur vectors returned by ZHGEQZ).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
+*                      SELECT, stored consecutively in the columns of
+*                      VL, in the same order as their eigenvalues.
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'l' or 'B' or 'b', LDVL >= N.
+*
+*  VR      (input/output) COMPLEX*16 array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Q (usually the unitary matrix Z
+*          of right Schur vectors returned by ZHGEQZ).
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
+*          if HOWMNY = 'B', the matrix Z*X;
+*          if HOWMNY = 'S', the right eigenvectors of (S,P) specified by
+*                      SELECT, stored consecutively in the columns of
+*                      VR, in the same order as their eigenvalues.
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B', LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
+*          is set to N.  Each selected eigenvector occupies one column.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit.
+*          < 0:  if INFO = -i, the i-th argument had an illegal value.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   CONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            COMPL, COMPR, ILALL, ILBACK, ILBBAD, ILCOMP,
+     $                   LSA, LSB
+      INTEGER            I, IBEG, IEIG, IEND, IHWMNY, IM, ISIDE, ISRC,
+     $                   J, JE, JR
+      DOUBLE PRECISION   ACOEFA, ACOEFF, ANORM, ASCALE, BCOEFA, BIG,
+     $                   BIGNUM, BNORM, BSCALE, DMIN, SAFMIN, SBETA,
+     $                   SCALE, SMALL, TEMP, ULP, XMAX
+      COMPLEX*16         BCOEFF, CA, CB, D, SALPHA, SUM, SUMA, SUMB, X
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH
+      COMPLEX*16         ZLADIV
+      EXTERNAL           LSAME, DLAMCH, ZLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, XERBLA, ZGEMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   ABS1
+*     ..
+*     .. Statement Function definitions ..
+      ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test the input parameters
+*
+      IF( LSAME( HOWMNY, 'A' ) ) THEN
+         IHWMNY = 1
+         ILALL = .TRUE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
+         IHWMNY = 2
+         ILALL = .FALSE.
+         ILBACK = .FALSE.
+      ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
+         IHWMNY = 3
+         ILALL = .TRUE.
+         ILBACK = .TRUE.
+      ELSE
+         IHWMNY = -1
+      END IF
+*
+      IF( LSAME( SIDE, 'R' ) ) THEN
+         ISIDE = 1
+         COMPL = .FALSE.
+         COMPR = .TRUE.
+      ELSE IF( LSAME( SIDE, 'L' ) ) THEN
+         ISIDE = 2
+         COMPL = .TRUE.
+         COMPR = .FALSE.
+      ELSE IF( LSAME( SIDE, 'B' ) ) THEN
+         ISIDE = 3
+         COMPL = .TRUE.
+         COMPR = .TRUE.
+      ELSE
+         ISIDE = -1
+      END IF
+*
+      INFO = 0
+      IF( ISIDE.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( IHWMNY.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Count the number of eigenvectors
+*
+      IF( .NOT.ILALL ) THEN
+         IM = 0
+         DO 10 J = 1, N
+            IF( SELECT( J ) )
+     $         IM = IM + 1
+   10    CONTINUE
+      ELSE
+         IM = N
+      END IF
+*
+*     Check diagonal of B
+*
+      ILBBAD = .FALSE.
+      DO 20 J = 1, N
+         IF( DIMAG( P( J, J ) ).NE.ZERO )
+     $      ILBBAD = .TRUE.
+   20 CONTINUE
+*
+      IF( ILBBAD ) THEN
+         INFO = -7
+      ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
+         INFO = -10
+      ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
+         INFO = -12
+      ELSE IF( MM.LT.IM ) THEN
+         INFO = -13
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTGEVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      M = IM
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Machine Constants
+*
+      SAFMIN = DLAMCH( 'Safe minimum' )
+      BIG = ONE / SAFMIN
+      CALL DLABAD( SAFMIN, BIG )
+      ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
+      SMALL = SAFMIN*N / ULP
+      BIG = ONE / SMALL
+      BIGNUM = ONE / ( SAFMIN*N )
+*
+*     Compute the 1-norm of each column of the strictly upper triangular
+*     part of A and B to check for possible overflow in the triangular
+*     solver.
+*
+      ANORM = ABS1( S( 1, 1 ) )
+      BNORM = ABS1( P( 1, 1 ) )
+      RWORK( 1 ) = ZERO
+      RWORK( N+1 ) = ZERO
+      DO 40 J = 2, N
+         RWORK( J ) = ZERO
+         RWORK( N+J ) = ZERO
+         DO 30 I = 1, J - 1
+            RWORK( J ) = RWORK( J ) + ABS1( S( I, J ) )
+            RWORK( N+J ) = RWORK( N+J ) + ABS1( P( I, J ) )
+   30    CONTINUE
+         ANORM = MAX( ANORM, RWORK( J )+ABS1( S( J, J ) ) )
+         BNORM = MAX( BNORM, RWORK( N+J )+ABS1( P( J, J ) ) )
+   40 CONTINUE
+*
+      ASCALE = ONE / MAX( ANORM, SAFMIN )
+      BSCALE = ONE / MAX( BNORM, SAFMIN )
+*
+*     Left eigenvectors
+*
+      IF( COMPL ) THEN
+         IEIG = 0
+*
+*        Main loop over eigenvalues
+*
+         DO 140 JE = 1, N
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( ILCOMP ) THEN
+               IEIG = IEIG + 1
+*
+               IF( ABS1( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( DBLE( P( JE, JE ) ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- return unit eigenvector
+*
+                  DO 50 JR = 1, N
+                     VL( JR, IEIG ) = CZERO
+   50             CONTINUE
+                  VL( IEIG, IEIG ) = CONE
+                  GO TO 140
+               END IF
+*
+*              Non-singular eigenvalue:
+*              Compute coefficients  a  and  b  in
+*                   H
+*                 y  ( a A - b B ) = 0
+*
+               TEMP = ONE / MAX( ABS1( S( JE, JE ) )*ASCALE,
+     $                ABS( DBLE( P( JE, JE ) ) )*BSCALE, SAFMIN )
+               SALPHA = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*DBLE( P( JE, JE ) ) )*BSCALE
+               ACOEFF = SBETA*ASCALE
+               BCOEFF = SALPHA*BSCALE
+*
+*              Scale to avoid underflow
+*
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEFF ).LT.SMALL
+               LSB = ABS1( SALPHA ).GE.SAFMIN .AND. ABS1( BCOEFF ).LT.
+     $               SMALL
+*
+               SCALE = ONE
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS1( SALPHA ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEFF ),
+     $                    ABS1( BCOEFF ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEFF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEFF = SCALE*ACOEFF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFF = BSCALE*( SCALE*SALPHA )
+                  ELSE
+                     BCOEFF = SCALE*BCOEFF
+                  END IF
+               END IF
+*
+               ACOEFA = ABS( ACOEFF )
+               BCOEFA = ABS1( BCOEFF )
+               XMAX = ONE
+               DO 60 JR = 1, N
+                  WORK( JR ) = CZERO
+   60          CONTINUE
+               WORK( JE ) = CONE
+               DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*                                              H
+*              Triangular solve of  (a A - b B)  y = 0
+*
+*                                      H
+*              (rowwise in  (a A - b B) , or columnwise in a A - b B)
+*
+               DO 100 J = JE + 1, N
+*
+*                 Compute
+*                       j-1
+*                 SUM = sum  conjg( a*S(k,j) - b*P(k,j) )*x(k)
+*                       k=je
+*                 (Scale if necessary)
+*
+                  TEMP = ONE / XMAX
+                  IF( ACOEFA*RWORK( J )+BCOEFA*RWORK( N+J ).GT.BIGNUM*
+     $                TEMP ) THEN
+                     DO 70 JR = JE, J - 1
+                        WORK( JR ) = TEMP*WORK( JR )
+   70                CONTINUE
+                     XMAX = ONE
+                  END IF
+                  SUMA = CZERO
+                  SUMB = CZERO
+*
+                  DO 80 JR = JE, J - 1
+                     SUMA = SUMA + DCONJG( S( JR, J ) )*WORK( JR )
+                     SUMB = SUMB + DCONJG( P( JR, J ) )*WORK( JR )
+   80             CONTINUE
+                  SUM = ACOEFF*SUMA - DCONJG( BCOEFF )*SUMB
+*
+*                 Form x(j) = - SUM / conjg( a*S(j,j) - b*P(j,j) )
+*
+*                 with scaling and perturbation of the denominator
+*
+                  D = DCONJG( ACOEFF*S( J, J )-BCOEFF*P( J, J ) )
+                  IF( ABS1( D ).LE.DMIN )
+     $               D = DCMPLX( DMIN )
+*
+                  IF( ABS1( D ).LT.ONE ) THEN
+                     IF( ABS1( SUM ).GE.BIGNUM*ABS1( D ) ) THEN
+                        TEMP = ONE / ABS1( SUM )
+                        DO 90 JR = JE, J - 1
+                           WORK( JR ) = TEMP*WORK( JR )
+   90                   CONTINUE
+                        XMAX = TEMP*XMAX
+                        SUM = TEMP*SUM
+                     END IF
+                  END IF
+                  WORK( J ) = ZLADIV( -SUM, D )
+                  XMAX = MAX( XMAX, ABS1( WORK( J ) ) )
+  100          CONTINUE
+*
+*              Back transform eigenvector if HOWMNY='B'.
+*
+               IF( ILBACK ) THEN
+                  CALL ZGEMV( 'N', N, N+1-JE, CONE, VL( 1, JE ), LDVL,
+     $                        WORK( JE ), 1, CZERO, WORK( N+1 ), 1 )
+                  ISRC = 2
+                  IBEG = 1
+               ELSE
+                  ISRC = 1
+                  IBEG = JE
+               END IF
+*
+*              Copy and scale eigenvector into column of VL
+*
+               XMAX = ZERO
+               DO 110 JR = IBEG, N
+                  XMAX = MAX( XMAX, ABS1( WORK( ( ISRC-1 )*N+JR ) ) )
+  110          CONTINUE
+*
+               IF( XMAX.GT.SAFMIN ) THEN
+                  TEMP = ONE / XMAX
+                  DO 120 JR = IBEG, N
+                     VL( JR, IEIG ) = TEMP*WORK( ( ISRC-1 )*N+JR )
+  120             CONTINUE
+               ELSE
+                  IBEG = N + 1
+               END IF
+*
+               DO 130 JR = 1, IBEG - 1
+                  VL( JR, IEIG ) = CZERO
+  130          CONTINUE
+*
+            END IF
+  140    CONTINUE
+      END IF
+*
+*     Right eigenvectors
+*
+      IF( COMPR ) THEN
+         IEIG = IM + 1
+*
+*        Main loop over eigenvalues
+*
+         DO 250 JE = N, 1, -1
+            IF( ILALL ) THEN
+               ILCOMP = .TRUE.
+            ELSE
+               ILCOMP = SELECT( JE )
+            END IF
+            IF( ILCOMP ) THEN
+               IEIG = IEIG - 1
+*
+               IF( ABS1( S( JE, JE ) ).LE.SAFMIN .AND.
+     $             ABS( DBLE( P( JE, JE ) ) ).LE.SAFMIN ) THEN
+*
+*                 Singular matrix pencil -- return unit eigenvector
+*
+                  DO 150 JR = 1, N
+                     VR( JR, IEIG ) = CZERO
+  150             CONTINUE
+                  VR( IEIG, IEIG ) = CONE
+                  GO TO 250
+               END IF
+*
+*              Non-singular eigenvalue:
+*              Compute coefficients  a  and  b  in
+*
+*              ( a A - b B ) x  = 0
+*
+               TEMP = ONE / MAX( ABS1( S( JE, JE ) )*ASCALE,
+     $                ABS( DBLE( P( JE, JE ) ) )*BSCALE, SAFMIN )
+               SALPHA = ( TEMP*S( JE, JE ) )*ASCALE
+               SBETA = ( TEMP*DBLE( P( JE, JE ) ) )*BSCALE
+               ACOEFF = SBETA*ASCALE
+               BCOEFF = SALPHA*BSCALE
+*
+*              Scale to avoid underflow
+*
+               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEFF ).LT.SMALL
+               LSB = ABS1( SALPHA ).GE.SAFMIN .AND. ABS1( BCOEFF ).LT.
+     $               SMALL
+*
+               SCALE = ONE
+               IF( LSA )
+     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
+               IF( LSB )
+     $            SCALE = MAX( SCALE, ( SMALL / ABS1( SALPHA ) )*
+     $                    MIN( BNORM, BIG ) )
+               IF( LSA .OR. LSB ) THEN
+                  SCALE = MIN( SCALE, ONE /
+     $                    ( SAFMIN*MAX( ONE, ABS( ACOEFF ),
+     $                    ABS1( BCOEFF ) ) ) )
+                  IF( LSA ) THEN
+                     ACOEFF = ASCALE*( SCALE*SBETA )
+                  ELSE
+                     ACOEFF = SCALE*ACOEFF
+                  END IF
+                  IF( LSB ) THEN
+                     BCOEFF = BSCALE*( SCALE*SALPHA )
+                  ELSE
+                     BCOEFF = SCALE*BCOEFF
+                  END IF
+               END IF
+*
+               ACOEFA = ABS( ACOEFF )
+               BCOEFA = ABS1( BCOEFF )
+               XMAX = ONE
+               DO 160 JR = 1, N
+                  WORK( JR ) = CZERO
+  160          CONTINUE
+               WORK( JE ) = CONE
+               DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
+*
+*              Triangular solve of  (a A - b B) x = 0  (columnwise)
+*
+*              WORK(1:j-1) contains sums w,
+*              WORK(j+1:JE) contains x
+*
+               DO 170 JR = 1, JE - 1
+                  WORK( JR ) = ACOEFF*S( JR, JE ) - BCOEFF*P( JR, JE )
+  170          CONTINUE
+               WORK( JE ) = CONE
+*
+               DO 210 J = JE - 1, 1, -1
+*
+*                 Form x(j) := - w(j) / d
+*                 with scaling and perturbation of the denominator
+*
+                  D = ACOEFF*S( J, J ) - BCOEFF*P( J, J )
+                  IF( ABS1( D ).LE.DMIN )
+     $               D = DCMPLX( DMIN )
+*
+                  IF( ABS1( D ).LT.ONE ) THEN
+                     IF( ABS1( WORK( J ) ).GE.BIGNUM*ABS1( D ) ) THEN
+                        TEMP = ONE / ABS1( WORK( J ) )
+                        DO 180 JR = 1, JE
+                           WORK( JR ) = TEMP*WORK( JR )
+  180                   CONTINUE
+                     END IF
+                  END IF
+*
+                  WORK( J ) = ZLADIV( -WORK( J ), D )
+*
+                  IF( J.GT.1 ) THEN
+*
+*                    w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
+*
+                     IF( ABS1( WORK( J ) ).GT.ONE ) THEN
+                        TEMP = ONE / ABS1( WORK( J ) )
+                        IF( ACOEFA*RWORK( J )+BCOEFA*RWORK( N+J ).GE.
+     $                      BIGNUM*TEMP ) THEN
+                           DO 190 JR = 1, JE
+                              WORK( JR ) = TEMP*WORK( JR )
+  190                      CONTINUE
+                        END IF
+                     END IF
+*
+                     CA = ACOEFF*WORK( J )
+                     CB = BCOEFF*WORK( J )
+                     DO 200 JR = 1, J - 1
+                        WORK( JR ) = WORK( JR ) + CA*S( JR, J ) -
+     $                               CB*P( JR, J )
+  200                CONTINUE
+                  END IF
+  210          CONTINUE
+*
+*              Back transform eigenvector if HOWMNY='B'.
+*
+               IF( ILBACK ) THEN
+                  CALL ZGEMV( 'N', N, JE, CONE, VR, LDVR, WORK, 1,
+     $                        CZERO, WORK( N+1 ), 1 )
+                  ISRC = 2
+                  IEND = N
+               ELSE
+                  ISRC = 1
+                  IEND = JE
+               END IF
+*
+*              Copy and scale eigenvector into column of VR
+*
+               XMAX = ZERO
+               DO 220 JR = 1, IEND
+                  XMAX = MAX( XMAX, ABS1( WORK( ( ISRC-1 )*N+JR ) ) )
+  220          CONTINUE
+*
+               IF( XMAX.GT.SAFMIN ) THEN
+                  TEMP = ONE / XMAX
+                  DO 230 JR = 1, IEND
+                     VR( JR, IEIG ) = TEMP*WORK( ( ISRC-1 )*N+JR )
+  230             CONTINUE
+               ELSE
+                  IEND = 0
+               END IF
+*
+               DO 240 JR = IEND + 1, N
+                  VR( JR, IEIG ) = CZERO
+  240          CONTINUE
+*
+            END IF
+  250    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZTGEVC
+*
+      END
diff --git a/libcruft/lapack/ztrcon.f b/libcruft/lapack/ztrcon.f
new file mode 100644
index 0000000..755072e
--- /dev/null
+++ b/libcruft/lapack/ztrcon.f
@@ -0,0 +1,204 @@
+      SUBROUTINE ZTRCON( NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK,
+     $                   RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, NORM, UPLO
+      INTEGER            INFO, LDA, N
+      DOUBLE PRECISION   RCOND
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         A( LDA, * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRCON estimates the reciprocal of the condition number of a
+*  triangular matrix A, in either the 1-norm or the infinity-norm.
+*
+*  The norm of A is computed and an estimate is obtained for
+*  norm(inv(A)), then the reciprocal of the condition number is
+*  computed as
+*     RCOND = 1 / ( norm(A) * norm(inv(A)) ).
+*
+*  Arguments
+*  =========
+*
+*  NORM    (input) CHARACTER*1
+*          Specifies whether the 1-norm condition number or the
+*          infinity-norm condition number is required:
+*          = '1' or 'O':  1-norm;
+*          = 'I':         Infinity-norm.
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  RCOND   (output) DOUBLE PRECISION
+*          The reciprocal of the condition number of the matrix A,
+*          computed as RCOND = 1/(norm(A) * norm(inv(A))).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE, ZERO
+      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, ONENRM, UPPER
+      CHARACTER          NORMIN
+      INTEGER            IX, KASE, KASE1
+      DOUBLE PRECISION   AINVNM, ANORM, SCALE, SMLNUM, XNORM
+      COMPLEX*16         ZDUM
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH, ZLANTR
+      EXTERNAL           LSAME, IZAMAX, DLAMCH, ZLANTR
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZDRSCL, ZLACN2, ZLATRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DIMAG, MAX
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )
+      NOUNIT = LSAME( DIAG, 'N' )
+*
+      IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTRCON', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         RCOND = ONE
+         RETURN
+      END IF
+*
+      RCOND = ZERO
+      SMLNUM = DLAMCH( 'Safe minimum' )*DBLE( MAX( 1, N ) )
+*
+*     Compute the norm of the triangular matrix A.
+*
+      ANORM = ZLANTR( NORM, UPLO, DIAG, N, N, A, LDA, RWORK )
+*
+*     Continue only if ANORM > 0.
+*
+      IF( ANORM.GT.ZERO ) THEN
+*
+*        Estimate the norm of the inverse of A.
+*
+         AINVNM = ZERO
+         NORMIN = 'N'
+         IF( ONENRM ) THEN
+            KASE1 = 1
+         ELSE
+            KASE1 = 2
+         END IF
+         KASE = 0
+   10    CONTINUE
+         CALL ZLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.KASE1 ) THEN
+*
+*              Multiply by inv(A).
+*
+               CALL ZLATRS( UPLO, 'No transpose', DIAG, NORMIN, N, A,
+     $                      LDA, WORK, SCALE, RWORK, INFO )
+            ELSE
+*
+*              Multiply by inv(A').
+*
+               CALL ZLATRS( UPLO, 'Conjugate transpose', DIAG, NORMIN,
+     $                      N, A, LDA, WORK, SCALE, RWORK, INFO )
+            END IF
+            NORMIN = 'Y'
+*
+*           Multiply by 1/SCALE if doing so will not cause overflow.
+*
+            IF( SCALE.NE.ONE ) THEN
+               IX = IZAMAX( N, WORK, 1 )
+               XNORM = CABS1( WORK( IX ) )
+               IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )
+     $            GO TO 20
+               CALL ZDRSCL( N, SCALE, WORK, 1 )
+            END IF
+            GO TO 10
+         END IF
+*
+*        Compute the estimate of the reciprocal condition number.
+*
+         IF( AINVNM.NE.ZERO )
+     $      RCOND = ( ONE / ANORM ) / AINVNM
+      END IF
+*
+   20 CONTINUE
+      RETURN
+*
+*     End of ZTRCON
+*
+      END
diff --git a/libcruft/lapack/ztrevc.f b/libcruft/lapack/ztrevc.f
new file mode 100644
index 0000000..21142f4
--- /dev/null
+++ b/libcruft/lapack/ztrevc.f
@@ -0,0 +1,386 @@
+      SUBROUTINE ZTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
+     $                   LDVR, MM, M, WORK, RWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTREVC computes some or all of the right and/or left eigenvectors of
+*  a complex upper triangular matrix T.
+*  Matrices of this type are produced by the Schur factorization of
+*  a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR.
+*  
+*  The right eigenvector x and the left eigenvector y of T corresponding
+*  to an eigenvalue w are defined by:
+*  
+*               T*x = w*x,     (y**H)*T = w*(y**H)
+*  
+*  where y**H denotes the conjugate transpose of the vector y.
+*  The eigenvalues are not input to this routine, but are read directly
+*  from the diagonal of T.
+*  
+*  This routine returns the matrices X and/or Y of right and left
+*  eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*  input matrix.  If Q is the unitary factor that reduces a matrix A to
+*  Schur form T, then Q*X and Q*Y are the matrices of right and left
+*  eigenvectors of A.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'R':  compute right eigenvectors only;
+*          = 'L':  compute left eigenvectors only;
+*          = 'B':  compute both right and left eigenvectors.
+*
+*  HOWMNY  (input) CHARACTER*1
+*          = 'A':  compute all right and/or left eigenvectors;
+*          = 'B':  compute all right and/or left eigenvectors,
+*                  backtransformed using the matrices supplied in
+*                  VR and/or VL;
+*          = 'S':  compute selected right and/or left eigenvectors,
+*                  as indicated by the logical array SELECT.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*          computed.
+*          The eigenvector corresponding to the j-th eigenvalue is
+*          computed if SELECT(j) = .TRUE..
+*          Not referenced if HOWMNY = 'A' or 'B'.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) COMPLEX*16 array, dimension (LDT,N)
+*          The upper triangular matrix T.  T is modified, but restored
+*          on exit.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  VL      (input/output) COMPLEX*16 array, dimension (LDVL,MM)
+*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*          Schur vectors returned by ZHSEQR).
+*          On exit, if SIDE = 'L' or 'B', VL contains:
+*          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*Y;
+*          if HOWMNY = 'S', the left eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VL, in the same order as their
+*                           eigenvalues.
+*          Not referenced if SIDE = 'R'.
+*
+*  LDVL    (input) INTEGER
+*          The leading dimension of the array VL.  LDVL >= 1, and if
+*          SIDE = 'L' or 'B', LDVL >= N.
+*
+*  VR      (input/output) COMPLEX*16 array, dimension (LDVR,MM)
+*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*          Schur vectors returned by ZHSEQR).
+*          On exit, if SIDE = 'R' or 'B', VR contains:
+*          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*          if HOWMNY = 'B', the matrix Q*X;
+*          if HOWMNY = 'S', the right eigenvectors of T specified by
+*                           SELECT, stored consecutively in the columns
+*                           of VR, in the same order as their
+*                           eigenvalues.
+*          Not referenced if SIDE = 'L'.
+*
+*  LDVR    (input) INTEGER
+*          The leading dimension of the array VR.  LDVR >= 1, and if
+*          SIDE = 'R' or 'B'; LDVR >= N.
+*
+*  MM      (input) INTEGER
+*          The number of columns in the arrays VL and/or VR. MM >= M.
+*
+*  M       (output) INTEGER
+*          The number of columns in the arrays VL and/or VR actually
+*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
+*          is set to N.  Each selected eigenvector occupies one
+*          column.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (2*N)
+*
+*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  The algorithm used in this program is basically backward (forward)
+*  substitution, with scaling to make the the code robust against
+*  possible overflow.
+*
+*  Each eigenvector is normalized so that the element of largest
+*  magnitude has magnitude 1; here the magnitude of a complex number
+*  (x,y) is taken to be |x| + |y|.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      COMPLEX*16         CMZERO, CMONE
+      PARAMETER          ( CMZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   CMONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, OVER, RIGHTV, SOMEV
+      INTEGER            I, II, IS, J, K, KI
+      DOUBLE PRECISION   OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
+      COMPLEX*16         CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IZAMAX
+      DOUBLE PRECISION   DLAMCH, DZASUM
+      EXTERNAL           LSAME, IZAMAX, DLAMCH, DZASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZCOPY, ZDSCAL, ZGEMV, ZLATRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV = LSAME( HOWMNY, 'A' )
+      OVER = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+*     Set M to the number of columns required to store the selected
+*     eigenvectors.
+*
+      IF( SOMEV ) THEN
+         M = 0
+         DO 10 J = 1, N
+            IF( SELECT( J ) )
+     $         M = M + 1
+   10    CONTINUE
+      ELSE
+         M = N
+      END IF
+*
+      INFO = 0
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE IF( MM.LT.M ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTREVC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Set the constants to control overflow.
+*
+      UNFL = DLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL DLABAD( UNFL, OVFL )
+      ULP = DLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+*
+*     Store the diagonal elements of T in working array WORK.
+*
+      DO 20 I = 1, N
+         WORK( I+N ) = T( I, I )
+   20 CONTINUE
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      RWORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         RWORK( J ) = DZASUM( J-1, T( 1, J ), 1 )
+   30 CONTINUE
+*
+      IF( RIGHTV ) THEN
+*
+*        Compute right eigenvectors.
+*
+         IS = M
+         DO 80 KI = N, 1, -1
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 80
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+            WORK( 1 ) = CMONE
+*
+*           Form right-hand side.
+*
+            DO 40 K = 1, KI - 1
+               WORK( K ) = -T( K, KI )
+   40       CONTINUE
+*
+*           Solve the triangular system:
+*              (T(1:KI-1,1:KI-1) - T(KI,KI))*X = SCALE*WORK.
+*
+            DO 50 K = 1, KI - 1
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+   50       CONTINUE
+*
+            IF( KI.GT.1 ) THEN
+               CALL ZLATRS( 'Upper', 'No transpose', 'Non-unit', 'Y',
+     $                      KI-1, T, LDT, WORK( 1 ), SCALE, RWORK,
+     $                      INFO )
+               WORK( KI ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VR and normalize.
+*
+            IF( .NOT.OVER ) THEN
+               CALL ZCOPY( KI, WORK( 1 ), 1, VR( 1, IS ), 1 )
+*
+               II = IZAMAX( KI, VR( 1, IS ), 1 )
+               REMAX = ONE / CABS1( VR( II, IS ) )
+               CALL ZDSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+               DO 60 K = KI + 1, N
+                  VR( K, IS ) = CMZERO
+   60          CONTINUE
+            ELSE
+               IF( KI.GT.1 )
+     $            CALL ZGEMV( 'N', N, KI-1, CMONE, VR, LDVR, WORK( 1 ),
+     $                        1, DCMPLX( SCALE ), VR( 1, KI ), 1 )
+*
+               II = IZAMAX( N, VR( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VR( II, KI ) )
+               CALL ZDSCAL( N, REMAX, VR( 1, KI ), 1 )
+            END IF
+*
+*           Set back the original diagonal elements of T.
+*
+            DO 70 K = 1, KI - 1
+               T( K, K ) = WORK( K+N )
+   70       CONTINUE
+*
+            IS = IS - 1
+   80    CONTINUE
+      END IF
+*
+      IF( LEFTV ) THEN
+*
+*        Compute left eigenvectors.
+*
+         IS = 1
+         DO 130 KI = 1, N
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 130
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+            WORK( N ) = CMONE
+*
+*           Form right-hand side.
+*
+            DO 90 K = KI + 1, N
+               WORK( K ) = -DCONJG( T( KI, K ) )
+   90       CONTINUE
+*
+*           Solve the triangular system:
+*              (T(KI+1:N,KI+1:N) - T(KI,KI))'*X = SCALE*WORK.
+*
+            DO 100 K = KI + 1, N
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+  100       CONTINUE
+*
+            IF( KI.LT.N ) THEN
+               CALL ZLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                      'Y', N-KI, T( KI+1, KI+1 ), LDT,
+     $                      WORK( KI+1 ), SCALE, RWORK, INFO )
+               WORK( KI ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VL and normalize.
+*
+            IF( .NOT.OVER ) THEN
+               CALL ZCOPY( N-KI+1, WORK( KI ), 1, VL( KI, IS ), 1 )
+*
+               II = IZAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+               REMAX = ONE / CABS1( VL( II, IS ) )
+               CALL ZDSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+               DO 110 K = 1, KI - 1
+                  VL( K, IS ) = CMZERO
+  110          CONTINUE
+            ELSE
+               IF( KI.LT.N )
+     $            CALL ZGEMV( 'N', N, N-KI, CMONE, VL( 1, KI+1 ), LDVL,
+     $                        WORK( KI+1 ), 1, DCMPLX( SCALE ),
+     $                        VL( 1, KI ), 1 )
+*
+               II = IZAMAX( N, VL( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VL( II, KI ) )
+               CALL ZDSCAL( N, REMAX, VL( 1, KI ), 1 )
+            END IF
+*
+*           Set back the original diagonal elements of T.
+*
+            DO 120 K = KI + 1, N
+               T( K, K ) = WORK( K+N )
+  120       CONTINUE
+*
+            IS = IS + 1
+  130    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZTREVC
+*
+      END
diff --git a/libcruft/lapack/ztrexc.f b/libcruft/lapack/ztrexc.f
new file mode 100644
index 0000000..6931369
--- /dev/null
+++ b/libcruft/lapack/ztrexc.f
@@ -0,0 +1,162 @@
+      SUBROUTINE ZTREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ
+      INTEGER            IFST, ILST, INFO, LDQ, LDT, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         Q( LDQ, * ), T( LDT, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTREXC reorders the Schur factorization of a complex matrix
+*  A = Q*T*Q**H, so that the diagonal element of T with row index IFST
+*  is moved to row ILST.
+*
+*  The Schur form T is reordered by a unitary similarity transformation
+*  Z**H*T*Z, and optionally the matrix Q of Schur vectors is updated by
+*  postmultplying it with Z.
+*
+*  Arguments
+*  =========
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V':  update the matrix Q of Schur vectors;
+*          = 'N':  do not update Q.
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) COMPLEX*16 array, dimension (LDT,N)
+*          On entry, the upper triangular matrix T.
+*          On exit, the reordered upper triangular matrix.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) COMPLEX*16 array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          unitary transformation matrix Z which reorders T.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.  LDQ >= max(1,N).
+*
+*  IFST    (input) INTEGER
+*  ILST    (input) INTEGER
+*          Specify the reordering of the diagonal elements of T:
+*          The element with row index IFST is moved to row ILST by a
+*          sequence of transpositions between adjacent elements.
+*          1 <= IFST <= N; 1 <= ILST <= N.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            WANTQ
+      INTEGER            K, M1, M2, M3
+      DOUBLE PRECISION   CS
+      COMPLEX*16         SN, T11, T22, TEMP
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARTG, ZROT
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters.
+*
+      INFO = 0
+      WANTQ = LSAME( COMPQ, 'V' )
+      IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) ) THEN
+         INFO = -6
+      ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THEN
+         INFO = -7
+      ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTREXC', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.1 .OR. IFST.EQ.ILST )
+     $   RETURN
+*
+      IF( IFST.LT.ILST ) THEN
+*
+*        Move the IFST-th diagonal element forward down the diagonal.
+*
+         M1 = 0
+         M2 = -1
+         M3 = 1
+      ELSE
+*
+*        Move the IFST-th diagonal element backward up the diagonal.
+*
+         M1 = -1
+         M2 = 0
+         M3 = -1
+      END IF
+*
+      DO 10 K = IFST + M1, ILST + M2, M3
+*
+*        Interchange the k-th and (k+1)-th diagonal elements.
+*
+         T11 = T( K, K )
+         T22 = T( K+1, K+1 )
+*
+*        Determine the transformation to perform the interchange.
+*
+         CALL ZLARTG( T( K, K+1 ), T22-T11, CS, SN, TEMP )
+*
+*        Apply transformation to the matrix T.
+*
+         IF( K+2.LE.N )
+     $      CALL ZROT( N-K-1, T( K, K+2 ), LDT, T( K+1, K+2 ), LDT, CS,
+     $                 SN )
+         CALL ZROT( K-1, T( 1, K ), 1, T( 1, K+1 ), 1, CS,
+     $              DCONJG( SN ) )
+*
+         T( K, K ) = T22
+         T( K+1, K+1 ) = T11
+*
+         IF( WANTQ ) THEN
+*
+*           Accumulate transformation in the matrix Q.
+*
+            CALL ZROT( N, Q( 1, K ), 1, Q( 1, K+1 ), 1, CS,
+     $                 DCONJG( SN ) )
+         END IF
+*
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of ZTREXC
+*
+      END
diff --git a/libcruft/lapack/ztrsen.f b/libcruft/lapack/ztrsen.f
new file mode 100644
index 0000000..a07a22f
--- /dev/null
+++ b/libcruft/lapack/ztrsen.f
@@ -0,0 +1,359 @@
+      SUBROUTINE ZTRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, W, M, S,
+     $                   SEP, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
+*
+*     .. Scalar Arguments ..
+      CHARACTER          COMPQ, JOB
+      INTEGER            INFO, LDQ, LDT, LWORK, M, N
+      DOUBLE PRECISION   S, SEP
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      COMPLEX*16         Q( LDQ, * ), T( LDT, * ), W( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRSEN reorders the Schur factorization of a complex matrix
+*  A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in
+*  the leading positions on the diagonal of the upper triangular matrix
+*  T, and the leading columns of Q form an orthonormal basis of the
+*  corresponding right invariant subspace.
+*
+*  Optionally the routine computes the reciprocal condition numbers of
+*  the cluster of eigenvalues and/or the invariant subspace.
+*
+*  Arguments
+*  =========
+*
+*  JOB     (input) CHARACTER*1
+*          Specifies whether condition numbers are required for the
+*          cluster of eigenvalues (S) or the invariant subspace (SEP):
+*          = 'N': none;
+*          = 'E': for eigenvalues only (S);
+*          = 'V': for invariant subspace only (SEP);
+*          = 'B': for both eigenvalues and invariant subspace (S and
+*                 SEP).
+*
+*  COMPQ   (input) CHARACTER*1
+*          = 'V': update the matrix Q of Schur vectors;
+*          = 'N': do not update Q.
+*
+*  SELECT  (input) LOGICAL array, dimension (N)
+*          SELECT specifies the eigenvalues in the selected cluster. To
+*          select the j-th eigenvalue, SELECT(j) must be set to .TRUE..
+*
+*  N       (input) INTEGER
+*          The order of the matrix T. N >= 0.
+*
+*  T       (input/output) COMPLEX*16 array, dimension (LDT,N)
+*          On entry, the upper triangular matrix T.
+*          On exit, T is overwritten by the reordered matrix T, with the
+*          selected eigenvalues as the leading diagonal elements.
+*
+*  LDT     (input) INTEGER
+*          The leading dimension of the array T. LDT >= max(1,N).
+*
+*  Q       (input/output) COMPLEX*16 array, dimension (LDQ,N)
+*          On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
+*          On exit, if COMPQ = 'V', Q has been postmultiplied by the
+*          unitary transformation matrix which reorders T; the leading M
+*          columns of Q form an orthonormal basis for the specified
+*          invariant subspace.
+*          If COMPQ = 'N', Q is not referenced.
+*
+*  LDQ     (input) INTEGER
+*          The leading dimension of the array Q.
+*          LDQ >= 1; and if COMPQ = 'V', LDQ >= N.
+*
+*  W       (output) COMPLEX*16 array, dimension (N)
+*          The reordered eigenvalues of T, in the same order as they
+*          appear on the diagonal of T.
+*
+*  M       (output) INTEGER
+*          The dimension of the specified invariant subspace.
+*          0 <= M <= N.
+*
+*  S       (output) DOUBLE PRECISION
+*          If JOB = 'E' or 'B', S is a lower bound on the reciprocal
+*          condition number for the selected cluster of eigenvalues.
+*          S cannot underestimate the true reciprocal condition number
+*          by more than a factor of sqrt(N). If M = 0 or N, S = 1.
+*          If JOB = 'N' or 'V', S is not referenced.
+*
+*  SEP     (output) DOUBLE PRECISION
+*          If JOB = 'V' or 'B', SEP is the estimated reciprocal
+*          condition number of the specified invariant subspace. If
+*          M = 0 or N, SEP = norm(T).
+*          If JOB = 'N' or 'E', SEP is not referenced.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If JOB = 'N', LWORK >= 1;
+*          if JOB = 'E', LWORK = max(1,M*(N-M));
+*          if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)).
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  ZTRSEN first collects the selected eigenvalues by computing a unitary
+*  transformation Z to move them to the top left corner of T. In other
+*  words, the selected eigenvalues are the eigenvalues of T11 in:
+*
+*                Z'*T*Z = ( T11 T12 ) n1
+*                         (  0  T22 ) n2
+*                            n1  n2
+*
+*  where N = n1+n2 and Z' means the conjugate transpose of Z. The first
+*  n1 columns of Z span the specified invariant subspace of T.
+*
+*  If T has been obtained from the Schur factorization of a matrix
+*  A = Q*T*Q', then the reordered Schur factorization of A is given by
+*  A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span the
+*  corresponding invariant subspace of A.
+*
+*  The reciprocal condition number of the average of the eigenvalues of
+*  T11 may be returned in S. S lies between 0 (very badly conditioned)
+*  and 1 (very well conditioned). It is computed as follows. First we
+*  compute R so that
+*
+*                         P = ( I  R ) n1
+*                             ( 0  0 ) n2
+*                               n1 n2
+*
+*  is the projector on the invariant subspace associated with T11.
+*  R is the solution of the Sylvester equation:
+*
+*                        T11*R - R*T22 = T12.
+*
+*  Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote
+*  the two-norm of M. Then S is computed as the lower bound
+*
+*                      (1 + F-norm(R)**2)**(-1/2)
+*
+*  on the reciprocal of 2-norm(P), the true reciprocal condition number.
+*  S cannot underestimate 1 / 2-norm(P) by more than a factor of
+*  sqrt(N).
+*
+*  An approximate error bound for the computed average of the
+*  eigenvalues of T11 is
+*
+*                         EPS * norm(T) / S
+*
+*  where EPS is the machine precision.
+*
+*  The reciprocal condition number of the right invariant subspace
+*  spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP.
+*  SEP is defined as the separation of T11 and T22:
+*
+*                     sep( T11, T22 ) = sigma-min( C )
+*
+*  where sigma-min(C) is the smallest singular value of the
+*  n1*n2-by-n1*n2 matrix
+*
+*     C  = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )
+*
+*  I(m) is an m by m identity matrix, and kprod denotes the Kronecker
+*  product. We estimate sigma-min(C) by the reciprocal of an estimate of
+*  the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C)
+*  cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2).
+*
+*  When SEP is small, small changes in T can cause large changes in
+*  the invariant subspace. An approximate bound on the maximum angular
+*  error in the computed right invariant subspace is
+*
+*                      EPS * norm(T) / SEP
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WANTBH, WANTQ, WANTS, WANTSP
+      INTEGER            IERR, K, KASE, KS, LWMIN, N1, N2, NN
+      DOUBLE PRECISION   EST, RNORM, SCALE
+*     ..
+*     .. Local Arrays ..
+      INTEGER            ISAVE( 3 )
+      DOUBLE PRECISION   RWORK( 1 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   ZLANGE
+      EXTERNAL           LSAME, ZLANGE
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLACN2, ZLACPY, ZTREXC, ZTRSYL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, SQRT
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters.
+*
+      WANTBH = LSAME( JOB, 'B' )
+      WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
+      WANTSP = LSAME( JOB, 'V' ) .OR. WANTBH
+      WANTQ = LSAME( COMPQ, 'V' )
+*
+*     Set M to the number of selected eigenvalues.
+*
+      M = 0
+      DO 10 K = 1, N
+         IF( SELECT( K ) )
+     $      M = M + 1
+   10 CONTINUE
+*
+      N1 = M
+      N2 = N - M
+      NN = N1*N2
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+*
+      IF( WANTSP ) THEN
+         LWMIN = MAX( 1, 2*NN )
+      ELSE IF( LSAME( JOB, 'N' ) ) THEN
+         LWMIN = 1
+      ELSE IF( LSAME( JOB, 'E' ) ) THEN
+         LWMIN = MAX( 1, NN )
+      END IF
+*
+      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.WANTS .AND. .NOT.WANTSP )
+     $     THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
+         INFO = -14
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         WORK( 1 ) = LWMIN
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTRSEN', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.N .OR. M.EQ.0 ) THEN
+         IF( WANTS )
+     $      S = ONE
+         IF( WANTSP )
+     $      SEP = ZLANGE( '1', N, N, T, LDT, RWORK )
+         GO TO 40
+      END IF
+*
+*     Collect the selected eigenvalues at the top left corner of T.
+*
+      KS = 0
+      DO 20 K = 1, N
+         IF( SELECT( K ) ) THEN
+            KS = KS + 1
+*
+*           Swap the K-th eigenvalue to position KS.
+*
+            IF( K.NE.KS )
+     $         CALL ZTREXC( COMPQ, N, T, LDT, Q, LDQ, K, KS, IERR )
+         END IF
+   20 CONTINUE
+*
+      IF( WANTS ) THEN
+*
+*        Solve the Sylvester equation for R:
+*
+*           T11*R - R*T22 = scale*T12
+*
+         CALL ZLACPY( 'F', N1, N2, T( 1, N1+1 ), LDT, WORK, N1 )
+         CALL ZTRSYL( 'N', 'N', -1, N1, N2, T, LDT, T( N1+1, N1+1 ),
+     $                LDT, WORK, N1, SCALE, IERR )
+*
+*        Estimate the reciprocal of the condition number of the cluster
+*        of eigenvalues.
+*
+         RNORM = ZLANGE( 'F', N1, N2, WORK, N1, RWORK )
+         IF( RNORM.EQ.ZERO ) THEN
+            S = ONE
+         ELSE
+            S = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*
+     $          SQRT( RNORM ) )
+         END IF
+      END IF
+*
+      IF( WANTSP ) THEN
+*
+*        Estimate sep(T11,T22).
+*
+         EST = ZERO
+         KASE = 0
+   30    CONTINUE
+         CALL ZLACN2( NN, WORK( NN+1 ), WORK, EST, KASE, ISAVE )
+         IF( KASE.NE.0 ) THEN
+            IF( KASE.EQ.1 ) THEN
+*
+*              Solve T11*R - R*T22 = scale*X.
+*
+               CALL ZTRSYL( 'N', 'N', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            ELSE
+*
+*              Solve T11'*R - R*T22' = scale*X.
+*
+               CALL ZTRSYL( 'C', 'C', -1, N1, N2, T, LDT,
+     $                      T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,
+     $                      IERR )
+            END IF
+            GO TO 30
+         END IF
+*
+         SEP = SCALE / EST
+      END IF
+*
+   40 CONTINUE
+*
+*     Copy reordered eigenvalues to W.
+*
+      DO 50 K = 1, N
+         W( K ) = T( K, K )
+   50 CONTINUE
+*
+      WORK( 1 ) = LWMIN
+*
+      RETURN
+*
+*     End of ZTRSEN
+*
+      END
diff --git a/libcruft/lapack/ztrsyl.f b/libcruft/lapack/ztrsyl.f
new file mode 100644
index 0000000..d2e0ecc
--- /dev/null
+++ b/libcruft/lapack/ztrsyl.f
@@ -0,0 +1,365 @@
+      SUBROUTINE ZTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
+     $                   LDC, SCALE, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          TRANA, TRANB
+      INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
+      DOUBLE PRECISION   SCALE
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRSYL solves the complex Sylvester matrix equation:
+*
+*     op(A)*X + X*op(B) = scale*C or
+*     op(A)*X - X*op(B) = scale*C,
+*
+*  where op(A) = A or A**H, and A and B are both upper triangular. A is
+*  M-by-M and B is N-by-N; the right hand side C and the solution X are
+*  M-by-N; and scale is an output scale factor, set <= 1 to avoid
+*  overflow in X.
+*
+*  Arguments
+*  =========
+*
+*  TRANA   (input) CHARACTER*1
+*          Specifies the option op(A):
+*          = 'N': op(A) = A    (No transpose)
+*          = 'C': op(A) = A**H (Conjugate transpose)
+*
+*  TRANB   (input) CHARACTER*1
+*          Specifies the option op(B):
+*          = 'N': op(B) = B    (No transpose)
+*          = 'C': op(B) = B**H (Conjugate transpose)
+*
+*  ISGN    (input) INTEGER
+*          Specifies the sign in the equation:
+*          = +1: solve op(A)*X + X*op(B) = scale*C
+*          = -1: solve op(A)*X - X*op(B) = scale*C
+*
+*  M       (input) INTEGER
+*          The order of the matrix A, and the number of rows in the
+*          matrices X and C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The order of the matrix B, and the number of columns in the
+*          matrices X and C. N >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,M)
+*          The upper triangular matrix A.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,M).
+*
+*  B       (input) COMPLEX*16 array, dimension (LDB,N)
+*          The upper triangular matrix B.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B. LDB >= max(1,N).
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N right hand side matrix C.
+*          On exit, C is overwritten by the solution matrix X.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M)
+*
+*  SCALE   (output) DOUBLE PRECISION
+*          The scale factor, scale, set <= 1 to avoid overflow in X.
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          = 1: A and B have common or very close eigenvalues; perturbed
+*               values were used to solve the equation (but the matrices
+*               A and B are unchanged).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ONE
+      PARAMETER          ( ONE = 1.0D+0 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOTRNA, NOTRNB
+      INTEGER            J, K, L
+      DOUBLE PRECISION   BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
+     $                   SMLNUM
+      COMPLEX*16         A11, SUML, SUMR, VEC, X11
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      DOUBLE PRECISION   DLAMCH, ZLANGE
+      COMPLEX*16         ZDOTC, ZDOTU, ZLADIV
+      EXTERNAL           LSAME, DLAMCH, ZLANGE, ZDOTC, ZDOTU, ZLADIV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DLABAD, XERBLA, ZDSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and Test input parameters
+*
+      NOTRNA = LSAME( TRANA, 'N' )
+      NOTRNB = LSAME( TRANB, 'N' )
+*
+      INFO = 0
+      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'C' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTRSYL', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+*     Set constants to control overflow
+*
+      EPS = DLAMCH( 'P' )
+      SMLNUM = DLAMCH( 'S' )
+      BIGNUM = ONE / SMLNUM
+      CALL DLABAD( SMLNUM, BIGNUM )
+      SMLNUM = SMLNUM*DBLE( M*N ) / EPS
+      BIGNUM = ONE / SMLNUM
+      SMIN = MAX( SMLNUM, EPS*ZLANGE( 'M', M, M, A, LDA, DUM ),
+     $       EPS*ZLANGE( 'M', N, N, B, LDB, DUM ) )
+      SCALE = ONE
+      SGN = ISGN
+*
+      IF( NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-left corner column by column by
+*
+*            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                    M                        L-1
+*          R(K,L) = SUM [A(K,I)*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)].
+*                  I=K+1                      J=1
+*
+         DO 30 L = 1, N
+            DO 20 K = M, 1, -1
+*
+               SUML = ZDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
+     $                C( MIN( K+1, M ), L ), 1 )
+               SUMR = ZDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
+               VEC = C( K, L ) - ( SUML+SGN*SUMR )
+*
+               SCALOC = ONE
+               A11 = A( K, K ) + SGN*B( L, L )
+               DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+               X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 10 J = 1, N
+                     CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
+   10             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+   20       CONTINUE
+   30    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
+*
+*        Solve    A' *X + ISGN*X*B = scale*C.
+*
+*        The (K,L)th block of X is determined starting from
+*        upper-left corner column by column by
+*
+*            A'(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                   K-1                         L-1
+*          R(K,L) = SUM [A'(I,K)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)]
+*                   I=1                         J=1
+*
+         DO 60 L = 1, N
+            DO 50 K = 1, M
+*
+               SUML = ZDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
+               SUMR = ZDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
+               VEC = C( K, L ) - ( SUML+SGN*SUMR )
+*
+               SCALOC = ONE
+               A11 = DCONJG( A( K, K ) ) + SGN*B( L, L )
+               DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+*
+               X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 40 J = 1, N
+                     CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
+   40             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+   50       CONTINUE
+   60    CONTINUE
+*
+      ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A'*X + ISGN*X*B' = C.
+*
+*        The (K,L)th block of X is determined starting from
+*        upper-right corner column by column by
+*
+*            A'(K,K)*X(K,L) + ISGN*X(K,L)*B'(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                    K-1
+*           R(K,L) = SUM [A'(I,K)*X(I,L)] +
+*                    I=1
+*                           N
+*                     ISGN*SUM [X(K,J)*B'(L,J)].
+*                          J=L+1
+*
+         DO 90 L = N, 1, -1
+            DO 80 K = 1, M
+*
+               SUML = ZDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
+               SUMR = ZDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
+     $                B( L, MIN( L+1, N ) ), LDB )
+               VEC = C( K, L ) - ( SUML+SGN*DCONJG( SUMR ) )
+*
+               SCALOC = ONE
+               A11 = DCONJG( A( K, K )+SGN*B( L, L ) )
+               DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+*
+               X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 70 J = 1, N
+                     CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
+   70             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+   80       CONTINUE
+   90    CONTINUE
+*
+      ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
+*
+*        Solve    A*X + ISGN*X*B' = C.
+*
+*        The (K,L)th block of X is determined starting from
+*        bottom-left corner column by column by
+*
+*           A(K,K)*X(K,L) + ISGN*X(K,L)*B'(L,L) = C(K,L) - R(K,L)
+*
+*        Where
+*                    M                          N
+*          R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B'(L,J)]
+*                  I=K+1                      J=L+1
+*
+         DO 120 L = N, 1, -1
+            DO 110 K = M, 1, -1
+*
+               SUML = ZDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
+     $                C( MIN( K+1, M ), L ), 1 )
+               SUMR = ZDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
+     $                B( L, MIN( L+1, N ) ), LDB )
+               VEC = C( K, L ) - ( SUML+SGN*DCONJG( SUMR ) )
+*
+               SCALOC = ONE
+               A11 = A( K, K ) + SGN*DCONJG( B( L, L ) )
+               DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
+               IF( DA11.LE.SMIN ) THEN
+                  A11 = SMIN
+                  DA11 = SMIN
+                  INFO = 1
+               END IF
+               DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
+               IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
+                  IF( DB.GT.BIGNUM*DA11 )
+     $               SCALOC = ONE / DB
+               END IF
+*
+               X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
+*
+               IF( SCALOC.NE.ONE ) THEN
+                  DO 100 J = 1, N
+                     CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
+  100             CONTINUE
+                  SCALE = SCALE*SCALOC
+               END IF
+               C( K, L ) = X11
+*
+  110       CONTINUE
+  120    CONTINUE
+*
+      END IF
+*
+      RETURN
+*
+*     End of ZTRSYL
+*
+      END
diff --git a/libcruft/lapack/ztrti2.f b/libcruft/lapack/ztrti2.f
new file mode 100644
index 0000000..73c7bbc
--- /dev/null
+++ b/libcruft/lapack/ztrti2.f
@@ -0,0 +1,146 @@
+      SUBROUTINE ZTRTI2( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRTI2 computes the inverse of a complex upper or lower triangular
+*  matrix.
+*
+*  This is the Level 2 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          Specifies whether the matrix A is upper or lower triangular.
+*          = 'U':  Upper triangular
+*          = 'L':  Lower triangular
+*
+*  DIAG    (input) CHARACTER*1
+*          Specifies whether or not the matrix A is unit triangular.
+*          = 'N':  Non-unit triangular
+*          = 'U':  Unit triangular
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading n by n upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading n by n lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -k, the k-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J
+      COMPLEX*16         AJJ
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZSCAL, ZTRMV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTRTI2', -INFO )
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Compute inverse of upper triangular matrix.
+*
+         DO 10 J = 1, N
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+*
+*           Compute elements 1:j-1 of j-th column.
+*
+            CALL ZTRMV( 'Upper', 'No transpose', DIAG, J-1, A, LDA,
+     $                  A( 1, J ), 1 )
+            CALL ZSCAL( J-1, AJJ, A( 1, J ), 1 )
+   10    CONTINUE
+      ELSE
+*
+*        Compute inverse of lower triangular matrix.
+*
+         DO 20 J = N, 1, -1
+            IF( NOUNIT ) THEN
+               A( J, J ) = ONE / A( J, J )
+               AJJ = -A( J, J )
+            ELSE
+               AJJ = -ONE
+            END IF
+            IF( J.LT.N ) THEN
+*
+*              Compute elements j+1:n of j-th column.
+*
+               CALL ZTRMV( 'Lower', 'No transpose', DIAG, N-J,
+     $                     A( J+1, J+1 ), LDA, A( J+1, J ), 1 )
+               CALL ZSCAL( N-J, AJJ, A( J+1, J ), 1 )
+            END IF
+   20    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZTRTI2
+*
+      END
diff --git a/libcruft/lapack/ztrtri.f b/libcruft/lapack/ztrtri.f
new file mode 100644
index 0000000..7caa977
--- /dev/null
+++ b/libcruft/lapack/ztrtri.f
@@ -0,0 +1,177 @@
+      SUBROUTINE ZTRTRI( UPLO, DIAG, N, A, LDA, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, UPLO
+      INTEGER            INFO, LDA, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRTRI computes the inverse of a complex upper or lower triangular
+*  matrix A.
+*
+*  This is the Level 3 BLAS version of the algorithm.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the triangular matrix A.  If UPLO = 'U', the
+*          leading N-by-N upper triangular part of the array A contains
+*          the upper triangular matrix, and the strictly lower
+*          triangular part of A is not referenced.  If UPLO = 'L', the
+*          leading N-by-N lower triangular part of the array A contains
+*          the lower triangular matrix, and the strictly upper
+*          triangular part of A is not referenced.  If DIAG = 'U', the
+*          diagonal elements of A are also not referenced and are
+*          assumed to be 1.
+*          On exit, the (triangular) inverse of the original matrix, in
+*          the same storage format.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, A(i,i) is exactly zero.  The triangular
+*               matrix is singular and its inverse can not be computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT, UPPER
+      INTEGER            J, JB, NB, NN
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZTRMM, ZTRSM, ZTRTI2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      UPPER = LSAME( UPLO, 'U' )
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTRTRI', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity if non-unit.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+         INFO = 0
+      END IF
+*
+*     Determine the block size for this environment.
+*
+      NB = ILAENV( 1, 'ZTRTRI', UPLO // DIAG, N, -1, -1, -1 )
+      IF( NB.LE.1 .OR. NB.GE.N ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZTRTI2( UPLO, DIAG, N, A, LDA, INFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( UPPER ) THEN
+*
+*           Compute inverse of upper triangular matrix
+*
+            DO 20 J = 1, N, NB
+               JB = MIN( NB, N-J+1 )
+*
+*              Compute rows 1:j-1 of current block column
+*
+               CALL ZTRMM( 'Left', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, ONE, A, LDA, A( 1, J ), LDA )
+               CALL ZTRSM( 'Right', 'Upper', 'No transpose', DIAG, J-1,
+     $                     JB, -ONE, A( J, J ), LDA, A( 1, J ), LDA )
+*
+*              Compute inverse of current diagonal block
+*
+               CALL ZTRTI2( 'Upper', DIAG, JB, A( J, J ), LDA, INFO )
+   20       CONTINUE
+         ELSE
+*
+*           Compute inverse of lower triangular matrix
+*
+            NN = ( ( N-1 ) / NB )*NB + 1
+            DO 30 J = NN, 1, -NB
+               JB = MIN( NB, N-J+1 )
+               IF( J+JB.LE.N ) THEN
+*
+*                 Compute rows j+jb:n of current block column
+*
+                  CALL ZTRMM( 'Left', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, ONE, A( J+JB, J+JB ), LDA,
+     $                        A( J+JB, J ), LDA )
+                  CALL ZTRSM( 'Right', 'Lower', 'No transpose', DIAG,
+     $                        N-J-JB+1, JB, -ONE, A( J, J ), LDA,
+     $                        A( J+JB, J ), LDA )
+               END IF
+*
+*              Compute inverse of current diagonal block
+*
+               CALL ZTRTI2( 'Lower', DIAG, JB, A( J, J ), LDA, INFO )
+   30       CONTINUE
+         END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRTRI
+*
+      END
diff --git a/libcruft/lapack/ztrtrs.f b/libcruft/lapack/ztrtrs.f
new file mode 100644
index 0000000..b42d5a5
--- /dev/null
+++ b/libcruft/lapack/ztrtrs.f
@@ -0,0 +1,148 @@
+      SUBROUTINE ZTRTRS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB,
+     $                   INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          DIAG, TRANS, UPLO
+      INTEGER            INFO, LDA, LDB, N, NRHS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), B( LDB, * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTRTRS solves a triangular system of the form
+*
+*     A * X = B,  A**T * X = B,  or  A**H * X = B,
+*
+*  where A is a triangular matrix of order N, and B is an N-by-NRHS
+*  matrix.  A check is made to verify that A is nonsingular.
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U':  A is upper triangular;
+*          = 'L':  A is lower triangular.
+*
+*  TRANS   (input) CHARACTER*1
+*          Specifies the form of the system of equations:
+*          = 'N':  A * X = B     (No transpose)
+*          = 'T':  A**T * X = B  (Transpose)
+*          = 'C':  A**H * X = B  (Conjugate transpose)
+*
+*  DIAG    (input) CHARACTER*1
+*          = 'N':  A is non-unit triangular;
+*          = 'U':  A is unit triangular.
+*
+*  N       (input) INTEGER
+*          The order of the matrix A.  N >= 0.
+*
+*  NRHS    (input) INTEGER
+*          The number of right hand sides, i.e., the number of columns
+*          of the matrix B.  NRHS >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,N)
+*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
+*          upper triangular part of the array A contains the upper
+*          triangular matrix, and the strictly lower triangular part of
+*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
+*          triangular part of the array A contains the lower triangular
+*          matrix, and the strictly upper triangular part of A is not
+*          referenced.  If DIAG = 'U', the diagonal elements of A are
+*          also not referenced and are assumed to be 1.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,N).
+*
+*  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
+*          On entry, the right hand side matrix B.
+*          On exit, if INFO = 0, the solution matrix X.
+*
+*  LDB     (input) INTEGER
+*          The leading dimension of the array B.  LDB >= max(1,N).
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*          > 0: if INFO = i, the i-th diagonal element of A is zero,
+*               indicating that the matrix is singular and the solutions
+*               X have not been computed.
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZTRSM
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      NOUNIT = LSAME( DIAG, 'N' )
+      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.
+     $         LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( NRHS.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -7
+      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
+         INFO = -9
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTRTRS', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Check for singularity.
+*
+      IF( NOUNIT ) THEN
+         DO 10 INFO = 1, N
+            IF( A( INFO, INFO ).EQ.ZERO )
+     $         RETURN
+   10    CONTINUE
+      END IF
+      INFO = 0
+*
+*     Solve A * x = b,  A**T * x = b,  or  A**H * x = b.
+*
+      CALL ZTRSM( 'Left', UPLO, TRANS, DIAG, N, NRHS, ONE, A, LDA, B,
+     $            LDB )
+*
+      RETURN
+*
+*     End of ZTRTRS
+*
+      END
diff --git a/libcruft/lapack/ztzrzf.f b/libcruft/lapack/ztzrzf.f
new file mode 100644
index 0000000..5c9c654
--- /dev/null
+++ b/libcruft/lapack/ztzrzf.f
@@ -0,0 +1,244 @@
+      SUBROUTINE ZTZRZF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZTZRZF reduces the M-by-N ( M<=N ) complex upper trapezoidal matrix A
+*  to upper triangular form by means of unitary transformations.
+*
+*  The upper trapezoidal matrix A is factored as
+*
+*     A = ( R  0 ) * Z,
+*
+*  where Z is an N-by-N unitary matrix and R is an M-by-M upper
+*  triangular matrix.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix A.  M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix A.  N >= M.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the leading M-by-N upper trapezoidal part of the
+*          array A must contain the matrix to be factorized.
+*          On exit, the leading M-by-M upper triangular part of A
+*          contains the upper triangular matrix R, and elements M+1 to
+*          N of the first M rows of A, with the array TAU, represent the
+*          unitary matrix Z as a product of M elementary reflectors.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.  LDA >= max(1,M).
+*
+*  TAU     (output) COMPLEX*16 array, dimension (M)
+*          The scalar factors of the elementary reflectors.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.  LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  The factorization is obtained by Householder's method.  The kth
+*  transformation matrix, Z( k ), which is used to introduce zeros into
+*  the ( m - k + 1 )th row of A, is given in the form
+*
+*     Z( k ) = ( I     0   ),
+*              ( 0  T( k ) )
+*
+*  where
+*
+*     T( k ) = I - tau*u( k )*u( k )',   u( k ) = (   1    ),
+*                                                 (   0    )
+*                                                 ( z( k ) )
+*
+*  tau is a scalar and z( k ) is an ( n - m ) element vector.
+*  tau and z( k ) are chosen to annihilate the elements of the kth row
+*  of X.
+*
+*  The scalar tau is returned in the kth element of TAU and the vector
+*  u( k ) in the kth row of A, such that the elements of z( k ) are
+*  in  a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in
+*  the upper triangular part of A.
+*
+*  Z is given by
+*
+*     Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IWS, KI, KK, LDWORK, LWKOPT, M1, MU, NB,
+     $                   NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARZB, ZLARZT, ZLATRZ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -4
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. M.EQ.N ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.
+*
+            NB = ILAENV( 1, 'ZGERQF', ' ', M, N, -1, -1 )
+            LWKOPT = M*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+            INFO = -7
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTZRZF', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 ) THEN
+         RETURN
+      ELSE IF( M.EQ.N ) THEN
+         DO 10 I = 1, N
+            TAU( I ) = ZERO
+   10    CONTINUE
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 1
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.M ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'ZGERQF', ' ', M, N, -1, -1 ) )
+         IF( NX.LT.M ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'ZGERQF', ' ', M, N, -1,
+     $                 -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.M .AND. NX.LT.M ) THEN
+*
+*        Use blocked code initially.
+*        The last kk rows are handled by the block method.
+*
+         M1 = MIN( M+1, N )
+         KI = ( ( M-NX-1 ) / NB )*NB
+         KK = MIN( M, KI+NB )
+*
+         DO 20 I = M - KK + KI + 1, M - KK + 1, -NB
+            IB = MIN( M-I+1, NB )
+*
+*           Compute the TZ factorization of the current block
+*           A(i:i+ib-1,i:n)
+*
+            CALL ZLATRZ( IB, N-I+1, N-M, A( I, I ), LDA, TAU( I ),
+     $                   WORK )
+            IF( I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL ZLARZT( 'Backward', 'Rowwise', N-M, IB, A( I, M1 ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:i-1,i:n) from the right
+*
+               CALL ZLARZB( 'Right', 'No transpose', 'Backward',
+     $                      'Rowwise', I-1, N-I+1, IB, N-M, A( I, M1 ),
+     $                      LDA, WORK, LDWORK, A( 1, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+   20    CONTINUE
+         MU = I + NB - 1
+      ELSE
+         MU = M
+      END IF
+*
+*     Use unblocked code to factor the last or only block
+*
+      IF( MU.GT.0 )
+     $   CALL ZLATRZ( MU, N, N-M, A, LDA, TAU, WORK )
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of ZTZRZF
+*
+      END
diff --git a/libcruft/lapack/zung2l.f b/libcruft/lapack/zung2l.f
new file mode 100644
index 0000000..29178b9
--- /dev/null
+++ b/libcruft/lapack/zung2l.f
@@ -0,0 +1,128 @@
+      SUBROUTINE ZUNG2L( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNG2L generates an m by n complex matrix Q with orthonormal columns,
+*  which is defined as the last n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by ZGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by ZGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the m-by-n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEQLF.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, II, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARF, ZSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNG2L', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns 1:n-k to columns of the unit matrix
+*
+      DO 20 J = 1, N - K
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( M-N+J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = 1, K
+         II = N - K + I
+*
+*        Apply H(i) to A(1:m-k+i,1:n-k+i) from the left
+*
+         A( M-N+II, II ) = ONE
+         CALL ZLARF( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), A,
+     $               LDA, WORK )
+         CALL ZSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 )
+         A( M-N+II, II ) = ONE - TAU( I )
+*
+*        Set A(m-k+i+1:m,n-k+i) to zero
+*
+         DO 30 L = M - N + II + 1, M
+            A( L, II ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of ZUNG2L
+*
+      END
diff --git a/libcruft/lapack/zung2r.f b/libcruft/lapack/zung2r.f
new file mode 100644
index 0000000..cd89f26
--- /dev/null
+++ b/libcruft/lapack/zung2r.f
@@ -0,0 +1,130 @@
+      SUBROUTINE ZUNG2R( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNG2R generates an m by n complex matrix Q with orthonormal columns,
+*  which is defined as the first n columns of a product of k elementary
+*  reflectors of order m
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by ZGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by ZGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the m by n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEQRF.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (N)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARF, ZSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNG2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 )
+     $   RETURN
+*
+*     Initialise columns k+1:n to columns of the unit matrix
+*
+      DO 20 J = K + 1, N
+         DO 10 L = 1, M
+            A( L, J ) = ZERO
+   10    CONTINUE
+         A( J, J ) = ONE
+   20 CONTINUE
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i) to A(i:m,i:n) from the left
+*
+         IF( I.LT.N ) THEN
+            A( I, I ) = ONE
+            CALL ZLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),
+     $                  A( I, I+1 ), LDA, WORK )
+         END IF
+         IF( I.LT.M )
+     $      CALL ZSCAL( M-I, -TAU( I ), A( I+1, I ), 1 )
+         A( I, I ) = ONE - TAU( I )
+*
+*        Set A(1:i-1,i) to zero
+*
+         DO 30 L = 1, I - 1
+            A( L, I ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of ZUNG2R
+*
+      END
diff --git a/libcruft/lapack/zungbr.f b/libcruft/lapack/zungbr.f
new file mode 100644
index 0000000..94f7482
--- /dev/null
+++ b/libcruft/lapack/zungbr.f
@@ -0,0 +1,245 @@
+      SUBROUTINE ZUNGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          VECT
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGBR generates one of the complex unitary matrices Q or P**H
+*  determined by ZGEBRD when reducing a complex matrix A to bidiagonal
+*  form: A = Q * B * P**H.  Q and P**H are defined as products of
+*  elementary reflectors H(i) or G(i) respectively.
+*
+*  If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q
+*  is of order M:
+*  if m >= k, Q = H(1) H(2) . . . H(k) and ZUNGBR returns the first n
+*  columns of Q, where m >= n >= k;
+*  if m < k, Q = H(1) H(2) . . . H(m-1) and ZUNGBR returns Q as an
+*  M-by-M matrix.
+*
+*  If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**H
+*  is of order N:
+*  if k < n, P**H = G(k) . . . G(2) G(1) and ZUNGBR returns the first m
+*  rows of P**H, where n >= m >= k;
+*  if k >= n, P**H = G(n-1) . . . G(2) G(1) and ZUNGBR returns P**H as
+*  an N-by-N matrix.
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          Specifies whether the matrix Q or the matrix P**H is
+*          required, as defined in the transformation applied by ZGEBRD:
+*          = 'Q':  generate Q;
+*          = 'P':  generate P**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q or P**H to be returned.
+*          M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q or P**H to be returned.
+*          N >= 0.
+*          If VECT = 'Q', M >= N >= min(M,K);
+*          if VECT = 'P', N >= M >= min(N,K).
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original M-by-K
+*          matrix reduced by ZGEBRD.
+*          If VECT = 'P', the number of rows in the original K-by-N
+*          matrix reduced by ZGEBRD.
+*          K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by ZGEBRD.
+*          On exit, the M-by-N matrix Q or P**H.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= M.
+*
+*  TAU     (input) COMPLEX*16 array, dimension
+*                                (min(M,K)) if VECT = 'Q'
+*                                (min(N,K)) if VECT = 'P'
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i), which determines Q or P**H, as
+*          returned by ZGEBRD in its array argument TAUQ or TAUP.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,min(M,N)).
+*          For optimum performance LWORK >= min(M,N)*NB, where NB
+*          is the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, WANTQ
+      INTEGER            I, IINFO, J, LWKOPT, MN, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZUNGLQ, ZUNGQR
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      WANTQ = LSAME( VECT, 'Q' )
+      MN = MIN( M, N )
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M,
+     $         K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT.
+     $         MIN( N, K ) ) ) ) THEN
+         INFO = -3
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -6
+      ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THEN
+         INFO = -9
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( WANTQ ) THEN
+            NB = ILAENV( 1, 'ZUNGQR', ' ', M, N, K, -1 )
+         ELSE
+            NB = ILAENV( 1, 'ZUNGLQ', ' ', M, N, K, -1 )
+         END IF
+         LWKOPT = MAX( 1, MN )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( WANTQ ) THEN
+*
+*        Form Q, determined by a call to ZGEBRD to reduce an m-by-k
+*        matrix
+*
+         IF( M.GE.K ) THEN
+*
+*           If m >= k, assume m >= n >= k
+*
+            CALL ZUNGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If m < k, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           column to the right, and set the first row and column of Q
+*           to those of the unit matrix
+*
+            DO 20 J = M, 2, -1
+               A( 1, J ) = ZERO
+               DO 10 I = J + 1, M
+                  A( I, J ) = A( I, J-1 )
+   10          CONTINUE
+   20       CONTINUE
+            A( 1, 1 ) = ONE
+            DO 30 I = 2, M
+               A( I, 1 ) = ZERO
+   30       CONTINUE
+            IF( M.GT.1 ) THEN
+*
+*              Form Q(2:m,2:m)
+*
+               CALL ZUNGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      ELSE
+*
+*        Form P', determined by a call to ZGEBRD to reduce a k-by-n
+*        matrix
+*
+         IF( K.LT.N ) THEN
+*
+*           If k < n, assume k <= m <= n
+*
+            CALL ZUNGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+         ELSE
+*
+*           If k >= n, assume m = n
+*
+*           Shift the vectors which define the elementary reflectors one
+*           row downward, and set the first row and column of P' to
+*           those of the unit matrix
+*
+            A( 1, 1 ) = ONE
+            DO 40 I = 2, N
+               A( I, 1 ) = ZERO
+   40       CONTINUE
+            DO 60 J = 2, N
+               DO 50 I = J - 1, 2, -1
+                  A( I, J ) = A( I-1, J )
+   50          CONTINUE
+               A( 1, J ) = ZERO
+   60       CONTINUE
+            IF( N.GT.1 ) THEN
+*
+*              Form P'(2:n,2:n)
+*
+               CALL ZUNGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                      LWORK, IINFO )
+            END IF
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZUNGBR
+*
+      END
diff --git a/libcruft/lapack/zunghr.f b/libcruft/lapack/zunghr.f
new file mode 100644
index 0000000..fcf32ab
--- /dev/null
+++ b/libcruft/lapack/zunghr.f
@@ -0,0 +1,165 @@
+      SUBROUTINE ZUNGHR( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            IHI, ILO, INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGHR generates a complex unitary matrix Q which is defined as the
+*  product of IHI-ILO elementary reflectors of order N, as returned by
+*  ZGEHRD:
+*
+*  Q = H(ilo) H(ilo+1) . . . H(ihi-1).
+*
+*  Arguments
+*  =========
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  ILO     (input) INTEGER
+*  IHI     (input) INTEGER
+*          ILO and IHI must have the same values as in the previous call
+*          of ZGEHRD. Q is equal to the unit matrix except in the
+*          submatrix Q(ilo+1:ihi,ilo+1:ihi).
+*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by ZGEHRD.
+*          On exit, the N-by-N unitary matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,N).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEHRD.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= IHI-ILO.
+*          For optimum performance LWORK >= (IHI-ILO)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IINFO, J, LWKOPT, NB, NH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZUNGQR
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NH = IHI - ILO
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( N.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
+         INFO = -2
+      ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, NH ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         NB = ILAENV( 1, 'ZUNGQR', ' ', NH, NH, NH, -1 )
+         LWKOPT = MAX( 1, NH )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGHR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+*     Shift the vectors which define the elementary reflectors one
+*     column to the right, and set the first ilo and the last n-ihi
+*     rows and columns to those of the unit matrix
+*
+      DO 40 J = IHI, ILO + 1, -1
+         DO 10 I = 1, J - 1
+            A( I, J ) = ZERO
+   10    CONTINUE
+         DO 20 I = J + 1, IHI
+            A( I, J ) = A( I, J-1 )
+   20    CONTINUE
+         DO 30 I = IHI + 1, N
+            A( I, J ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      DO 60 J = 1, ILO
+         DO 50 I = 1, N
+            A( I, J ) = ZERO
+   50    CONTINUE
+         A( J, J ) = ONE
+   60 CONTINUE
+      DO 80 J = IHI + 1, N
+         DO 70 I = 1, N
+            A( I, J ) = ZERO
+   70    CONTINUE
+         A( J, J ) = ONE
+   80 CONTINUE
+*
+      IF( NH.GT.0 ) THEN
+*
+*        Generate Q(ilo+1:ihi,ilo+1:ihi)
+*
+         CALL ZUNGQR( NH, NH, NH, A( ILO+1, ILO+1 ), LDA, TAU( ILO ),
+     $                WORK, LWORK, IINFO )
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZUNGHR
+*
+      END
diff --git a/libcruft/lapack/zungl2.f b/libcruft/lapack/zungl2.f
new file mode 100644
index 0000000..502411b
--- /dev/null
+++ b/libcruft/lapack/zungl2.f
@@ -0,0 +1,136 @@
+      SUBROUTINE ZUNGL2( M, N, K, A, LDA, TAU, WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGL2 generates an m-by-n complex matrix Q with orthonormal rows,
+*  which is defined as the first m rows of a product of k elementary
+*  reflectors of order n
+*
+*        Q  =  H(k)' . . . H(2)' H(1)'
+*
+*  as returned by ZGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by ZGELQF in the first k rows of its array argument A.
+*          On exit, the m by n matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGELQF.
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension (M)
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE, ZERO
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ),
+     $                   ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      INTEGER            I, J, L
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLACGV, ZLARF, ZSCAL
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGL2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 )
+     $   RETURN
+*
+      IF( K.LT.M ) THEN
+*
+*        Initialise rows k+1:m to rows of the unit matrix
+*
+         DO 20 J = 1, N
+            DO 10 L = K + 1, M
+               A( L, J ) = ZERO
+   10       CONTINUE
+            IF( J.GT.K .AND. J.LE.M )
+     $         A( J, J ) = ONE
+   20    CONTINUE
+      END IF
+*
+      DO 40 I = K, 1, -1
+*
+*        Apply H(i)' to A(i:m,i:n) from the right
+*
+         IF( I.LT.N ) THEN
+            CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+            IF( I.LT.M ) THEN
+               A( I, I ) = ONE
+               CALL ZLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,
+     $                     DCONJG( TAU( I ) ), A( I+1, I ), LDA, WORK )
+            END IF
+            CALL ZSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA )
+            CALL ZLACGV( N-I, A( I, I+1 ), LDA )
+         END IF
+         A( I, I ) = ONE - DCONJG( TAU( I ) )
+*
+*        Set A(i,1:i-1) to zero
+*
+         DO 30 L = 1, I - 1
+            A( I, L ) = ZERO
+   30    CONTINUE
+   40 CONTINUE
+      RETURN
+*
+*     End of ZUNGL2
+*
+      END
diff --git a/libcruft/lapack/zunglq.f b/libcruft/lapack/zunglq.f
new file mode 100644
index 0000000..ab4a018
--- /dev/null
+++ b/libcruft/lapack/zunglq.f
@@ -0,0 +1,215 @@
+      SUBROUTINE ZUNGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGLQ generates an M-by-N complex matrix Q with orthonormal rows,
+*  which is defined as the first M rows of a product of K elementary
+*  reflectors of order N
+*
+*        Q  =  H(k)' . . . H(2)' H(1)'
+*
+*  as returned by ZGELQF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. N >= M.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. M >= K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the i-th row must contain the vector which defines
+*          the elementary reflector H(i), for i = 1,2,...,k, as returned
+*          by ZGELQF in the first k rows of its array argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGELQF.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,M).
+*          For optimum performance LWORK >= M*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit;
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARFB, ZLARFT, ZUNGL2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'ZUNGLQ', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, M )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.M ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = M
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'ZUNGLQ', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = M
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'ZUNGLQ', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk rows are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(kk+1:m,1:kk) to zero.
+*
+         DO 20 J = 1, KK
+            DO 10 I = KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.M )
+     $   CALL ZUNGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.M ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL ZLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),
+     $                      LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H' to A(i+ib:m,i:n) from the right
+*
+               CALL ZLARFB( 'Right', 'Conjugate transpose', 'Forward',
+     $                      'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),
+     $                      LDA, WORK, LDWORK, A( I+IB, I ), LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H' to columns i:n of current block
+*
+            CALL ZUNGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set columns 1:i-1 of current block to zero
+*
+            DO 40 J = 1, I - 1
+               DO 30 L = I, I + IB - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZUNGLQ
+*
+      END
diff --git a/libcruft/lapack/zungql.f b/libcruft/lapack/zungql.f
new file mode 100644
index 0000000..4232abe
--- /dev/null
+++ b/libcruft/lapack/zungql.f
@@ -0,0 +1,222 @@
+      SUBROUTINE ZUNGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGQL generates an M-by-N complex matrix Q with orthonormal columns,
+*  which is defined as the last N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(k) . . . H(2) H(1)
+*
+*  as returned by ZGEQLF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the (n-k+i)-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by ZGEQLF in the last k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEQLF.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT,
+     $                   NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARFB, ZLARFT, ZUNG2L
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+            NB = ILAENV( 1, 'ZUNGQL', ' ', M, N, K, -1 )
+            LWKOPT = N*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+            INFO = -8
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGQL', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'ZUNGQL', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'ZUNGQL', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the first block.
+*        The last kk columns are handled by the block method.
+*
+         KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )
+*
+*        Set A(m-kk+1:m,1:n-kk) to zero.
+*
+         DO 20 J = 1, N - KK
+            DO 10 I = M - KK + 1, M
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the first or only block.
+*
+      CALL ZUNG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = K - KK + 1, K, NB
+            IB = MIN( NB, K-I+1 )
+            IF( N-K+I.GT.1 ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i+ib-1) . . . H(i+1) H(i)
+*
+               CALL ZLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,
+     $                      A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left
+*
+               CALL ZLARFB( 'Left', 'No transpose', 'Backward',
+     $                      'Columnwise', M-K+I+IB-1, N-K+I-1, IB,
+     $                      A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,
+     $                      WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows 1:m-k+i+ib-1 of current block
+*
+            CALL ZUNG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA,
+     $                   TAU( I ), WORK, IINFO )
+*
+*           Set rows m-k+i+ib:m of current block to zero
+*
+            DO 40 J = N - K + I, N - K + I + IB - 1
+               DO 30 L = M - K + I + IB, M
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZUNGQL
+*
+      END
diff --git a/libcruft/lapack/zungqr.f b/libcruft/lapack/zungqr.f
new file mode 100644
index 0000000..bf5c699
--- /dev/null
+++ b/libcruft/lapack/zungqr.f
@@ -0,0 +1,216 @@
+      SUBROUTINE ZUNGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      INTEGER            INFO, K, LDA, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGQR generates an M-by-N complex matrix Q with orthonormal columns,
+*  which is defined as the first N columns of a product of K elementary
+*  reflectors of order M
+*
+*        Q  =  H(1) H(2) . . . H(k)
+*
+*  as returned by ZGEQRF.
+*
+*  Arguments
+*  =========
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix Q. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix Q. M >= N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines the
+*          matrix Q. N >= K >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the i-th column must contain the vector which
+*          defines the elementary reflector H(i), for i = 1,2,...,k, as
+*          returned by ZGEQRF in the first k columns of its array
+*          argument A.
+*          On exit, the M-by-N matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The first dimension of the array A. LDA >= max(1,M).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEQRF.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= max(1,N).
+*          For optimum performance LWORK >= N*NB, where NB is the
+*          optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument has an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY
+      INTEGER            I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,
+     $                   LWKOPT, NB, NBMIN, NX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARFB, ZLARFT, ZUNG2R
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. External Functions ..
+      INTEGER            ILAENV
+      EXTERNAL           ILAENV
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      NB = ILAENV( 1, 'ZUNGQR', ' ', M, N, K, -1 )
+      LWKOPT = MAX( 1, N )*NB
+      WORK( 1 ) = LWKOPT
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( M.LT.0 ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 .OR. N.GT.M ) THEN
+         INFO = -2
+      ELSE IF( K.LT.0 .OR. K.GT.N ) THEN
+         INFO = -3
+      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+         INFO = -5
+      ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -8
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.LE.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      NX = 0
+      IWS = N
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+*
+*        Determine when to cross over from blocked to unblocked code.
+*
+         NX = MAX( 0, ILAENV( 3, 'ZUNGQR', ' ', M, N, K, -1 ) )
+         IF( NX.LT.K ) THEN
+*
+*           Determine if workspace is large enough for blocked code.
+*
+            LDWORK = N
+            IWS = LDWORK*NB
+            IF( LWORK.LT.IWS ) THEN
+*
+*              Not enough workspace to use optimal NB:  reduce NB and
+*              determine the minimum value of NB.
+*
+               NB = LWORK / LDWORK
+               NBMIN = MAX( 2, ILAENV( 2, 'ZUNGQR', ' ', M, N, K, -1 ) )
+            END IF
+         END IF
+      END IF
+*
+      IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
+*
+*        Use blocked code after the last block.
+*        The first kk columns are handled by the block method.
+*
+         KI = ( ( K-NX-1 ) / NB )*NB
+         KK = MIN( K, KI+NB )
+*
+*        Set A(1:kk,kk+1:n) to zero.
+*
+         DO 20 J = KK + 1, N
+            DO 10 I = 1, KK
+               A( I, J ) = ZERO
+   10       CONTINUE
+   20    CONTINUE
+      ELSE
+         KK = 0
+      END IF
+*
+*     Use unblocked code for the last or only block.
+*
+      IF( KK.LT.N )
+     $   CALL ZUNG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,
+     $                TAU( KK+1 ), WORK, IINFO )
+*
+      IF( KK.GT.0 ) THEN
+*
+*        Use blocked code
+*
+         DO 50 I = KI + 1, 1, -NB
+            IB = MIN( NB, K-I+1 )
+            IF( I+IB.LE.N ) THEN
+*
+*              Form the triangular factor of the block reflector
+*              H = H(i) H(i+1) . . . H(i+ib-1)
+*
+               CALL ZLARFT( 'Forward', 'Columnwise', M-I+1, IB,
+     $                      A( I, I ), LDA, TAU( I ), WORK, LDWORK )
+*
+*              Apply H to A(i:m,i+ib:n) from the left
+*
+               CALL ZLARFB( 'Left', 'No transpose', 'Forward',
+     $                      'Columnwise', M-I+1, N-I-IB+1, IB,
+     $                      A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),
+     $                      LDA, WORK( IB+1 ), LDWORK )
+            END IF
+*
+*           Apply H to rows i:m of current block
+*
+            CALL ZUNG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK,
+     $                   IINFO )
+*
+*           Set rows 1:i-1 of current block to zero
+*
+            DO 40 J = I, I + IB - 1
+               DO 30 L = 1, I - 1
+                  A( L, J ) = ZERO
+   30          CONTINUE
+   40       CONTINUE
+   50    CONTINUE
+      END IF
+*
+      WORK( 1 ) = IWS
+      RETURN
+*
+*     End of ZUNGQR
+*
+      END
diff --git a/libcruft/lapack/zungtr.f b/libcruft/lapack/zungtr.f
new file mode 100644
index 0000000..5de7c10
--- /dev/null
+++ b/libcruft/lapack/zungtr.f
@@ -0,0 +1,184 @@
+      SUBROUTINE ZUNGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          UPLO
+      INTEGER            INFO, LDA, LWORK, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNGTR generates a complex unitary matrix Q which is defined as the
+*  product of n-1 elementary reflectors of order N, as returned by
+*  ZHETRD:
+*
+*  if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),
+*
+*  if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).
+*
+*  Arguments
+*  =========
+*
+*  UPLO    (input) CHARACTER*1
+*          = 'U': Upper triangle of A contains elementary reflectors
+*                 from ZHETRD;
+*          = 'L': Lower triangle of A contains elementary reflectors
+*                 from ZHETRD.
+*
+*  N       (input) INTEGER
+*          The order of the matrix Q. N >= 0.
+*
+*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
+*          On entry, the vectors which define the elementary reflectors,
+*          as returned by ZHETRD.
+*          On exit, the N-by-N unitary matrix Q.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= N.
+*
+*  TAU     (input) COMPLEX*16 array, dimension (N-1)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZHETRD.
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK. LWORK >= N-1.
+*          For optimum performance LWORK >= (N-1)*NB, where NB is
+*          the optimal blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ZERO, ONE
+      PARAMETER          ( ZERO = ( 0.0D+0, 0.0D+0 ),
+     $                   ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LQUERY, UPPER
+      INTEGER            I, IINFO, J, LWKOPT, NB
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZUNGQL, ZUNGQR
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LQUERY = ( LWORK.EQ.-1 )
+      UPPER = LSAME( UPLO, 'U' )
+      IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
+         INFO = -1
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -2
+      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
+         INFO = -4
+      ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THEN
+         INFO = -7
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( UPPER ) THEN
+            NB = ILAENV( 1, 'ZUNGQL', ' ', N-1, N-1, N-1, -1 )
+         ELSE
+            NB = ILAENV( 1, 'ZUNGQR', ' ', N-1, N-1, N-1, -1 )
+         END IF
+         LWKOPT = MAX( 1, N-1 )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNGTR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( N.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      IF( UPPER ) THEN
+*
+*        Q was determined by a call to ZHETRD with UPLO = 'U'
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the left, and set the last row and column of Q to
+*        those of the unit matrix
+*
+         DO 20 J = 1, N - 1
+            DO 10 I = 1, J - 1
+               A( I, J ) = A( I, J+1 )
+   10       CONTINUE
+            A( N, J ) = ZERO
+   20    CONTINUE
+         DO 30 I = 1, N - 1
+            A( I, N ) = ZERO
+   30    CONTINUE
+         A( N, N ) = ONE
+*
+*        Generate Q(1:n-1,1:n-1)
+*
+         CALL ZUNGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, IINFO )
+*
+      ELSE
+*
+*        Q was determined by a call to ZHETRD with UPLO = 'L'.
+*
+*        Shift the vectors which define the elementary reflectors one
+*        column to the right, and set the first row and column of Q to
+*        those of the unit matrix
+*
+         DO 50 J = N, 2, -1
+            A( 1, J ) = ZERO
+            DO 40 I = J + 1, N
+               A( I, J ) = A( I, J-1 )
+   40       CONTINUE
+   50    CONTINUE
+         A( 1, 1 ) = ONE
+         DO 60 I = 2, N
+            A( I, 1 ) = ZERO
+   60    CONTINUE
+         IF( N.GT.1 ) THEN
+*
+*           Generate Q(2:n,2:n)
+*
+            CALL ZUNGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+     $                   LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZUNGTR
+*
+      END
diff --git a/libcruft/lapack/zunm2r.f b/libcruft/lapack/zunm2r.f
new file mode 100644
index 0000000..7d4c067
--- /dev/null
+++ b/libcruft/lapack/zunm2r.f
@@ -0,0 +1,201 @@
+      SUBROUTINE ZUNM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNM2R overwrites the general complex m-by-n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'C', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'C',
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by ZGEQRF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'C': apply Q' (Conjugate transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          ZGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEQRF.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      COMPLEX*16         AII, TAUI
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARF
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNM2R', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         IF( NOTRAN ) THEN
+            TAUI = TAU( I )
+         ELSE
+            TAUI = DCONJG( TAU( I ) )
+         END IF
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL ZLARF( SIDE, MI, NI, A( I, I ), 1, TAUI, C( IC, JC ), LDC,
+     $               WORK )
+         A( I, I ) = AII
+   10 CONTINUE
+      RETURN
+*
+*     End of ZUNM2R
+*
+      END
diff --git a/libcruft/lapack/zunmbr.f b/libcruft/lapack/zunmbr.f
new file mode 100644
index 0000000..b32ce33
--- /dev/null
+++ b/libcruft/lapack/zunmbr.f
@@ -0,0 +1,288 @@
+      SUBROUTINE ZUNMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,
+     $                   LDC, WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS, VECT
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  If VECT = 'Q', ZUNMBR overwrites the general complex M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  If VECT = 'P', ZUNMBR overwrites the general complex M-by-N matrix C
+*  with
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      P * C          C * P
+*  TRANS = 'C':      P**H * C       C * P**H
+*
+*  Here Q and P**H are the unitary matrices determined by ZGEBRD when
+*  reducing a complex matrix A to bidiagonal form: A = Q * B * P**H. Q
+*  and P**H are defined as products of elementary reflectors H(i) and
+*  G(i) respectively.
+*
+*  Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the
+*  order of the unitary matrix Q or P**H that is applied.
+*
+*  If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:
+*  if nq >= k, Q = H(1) H(2) . . . H(k);
+*  if nq < k, Q = H(1) H(2) . . . H(nq-1).
+*
+*  If VECT = 'P', A is assumed to have been a K-by-NQ matrix:
+*  if k < nq, P = G(1) G(2) . . . G(k);
+*  if k >= nq, P = G(1) G(2) . . . G(nq-1).
+*
+*  Arguments
+*  =========
+*
+*  VECT    (input) CHARACTER*1
+*          = 'Q': apply Q or Q**H;
+*          = 'P': apply P or P**H.
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q, Q**H, P or P**H from the Left;
+*          = 'R': apply Q, Q**H, P or P**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q or P;
+*          = 'C':  Conjugate transpose, apply Q**H or P**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          If VECT = 'Q', the number of columns in the original
+*          matrix reduced by ZGEBRD.
+*          If VECT = 'P', the number of rows in the original
+*          matrix reduced by ZGEBRD.
+*          K >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension
+*                                (LDA,min(nq,K)) if VECT = 'Q'
+*                                (LDA,nq)        if VECT = 'P'
+*          The vectors which define the elementary reflectors H(i) and
+*          G(i), whose products determine the matrices Q and P, as
+*          returned by ZGEBRD.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If VECT = 'Q', LDA >= max(1,nq);
+*          if VECT = 'P', LDA >= max(1,min(nq,K)).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (min(nq,K))
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i) or G(i) which determines Q or P, as returned
+*          by ZGEBRD in the array argument TAUQ or TAUP.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q
+*          or P*C or P**H*C or C*P or C*P**H.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M);
+*          if N = 0 or M = 0, LWORK >= 1.
+*          For optimum performance LWORK >= max(1,N*NB) if SIDE = 'L',
+*          and LWORK >= max(1,M*NB) if SIDE = 'R', where NB is the
+*          optimal blocksize. (NB = 0 if M = 0 or N = 0.)
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            APPLYQ, LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZUNMLQ, ZUNMQR
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      APPLYQ = LSAME( VECT, 'Q' )
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q or P and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         NW = 0
+      END IF
+      IF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -2
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -3
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -5
+      ELSE IF( K.LT.0 ) THEN
+         INFO = -6
+      ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR.
+     $         ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) )
+     $          THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -13
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( NW.GT.0 ) THEN
+            IF( APPLYQ ) THEN
+               IF( LEFT ) THEN
+                  NB = ILAENV( 1, 'ZUNMQR', SIDE // TRANS, M-1, N, M-1,
+     $                 -1 )
+               ELSE
+                  NB = ILAENV( 1, 'ZUNMQR', SIDE // TRANS, M, N-1, N-1,
+     $                 -1 )
+               END IF
+            ELSE
+               IF( LEFT ) THEN
+                  NB = ILAENV( 1, 'ZUNMLQ', SIDE // TRANS, M-1, N, M-1,
+     $                 -1 )
+               ELSE
+                  NB = ILAENV( 1, 'ZUNMLQ', SIDE // TRANS, M, N-1, N-1,
+     $                 -1 )
+               END IF
+            END IF
+            LWKOPT = MAX( 1, NW*NB )
+         ELSE
+            LWKOPT = 1
+         END IF
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNMBR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 )
+     $   RETURN
+*
+      IF( APPLYQ ) THEN
+*
+*        Apply Q
+*
+         IF( NQ.GE.K ) THEN
+*
+*           Q was determined by a call to ZGEBRD with nq >= k
+*
+            CALL ZUNMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           Q was determined by a call to ZGEBRD with nq < k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL ZUNMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,
+     $                   C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      ELSE
+*
+*        Apply P
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'C'
+         ELSE
+            TRANST = 'N'
+         END IF
+         IF( NQ.GT.K ) THEN
+*
+*           P was determined by a call to ZGEBRD with nq > k
+*
+            CALL ZUNMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, IINFO )
+         ELSE IF( NQ.GT.1 ) THEN
+*
+*           P was determined by a call to ZGEBRD with nq <= k
+*
+            IF( LEFT ) THEN
+               MI = M - 1
+               NI = N
+               I1 = 2
+               I2 = 1
+            ELSE
+               MI = M
+               NI = N - 1
+               I1 = 1
+               I2 = 2
+            END IF
+            CALL ZUNMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA,
+     $                   TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO )
+         END IF
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZUNMBR
+*
+      END
diff --git a/libcruft/lapack/zunml2.f b/libcruft/lapack/zunml2.f
new file mode 100644
index 0000000..cced4a7
--- /dev/null
+++ b/libcruft/lapack/zunml2.f
@@ -0,0 +1,205 @@
+      SUBROUTINE ZUNML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNML2 overwrites the general complex m-by-n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'C', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'C',
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k)' . . . H(2)' H(1)'
+*
+*  as returned by ZGELQF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'C': apply Q' (Conjugate transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          ZGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGELQF.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16         ONE
+      PARAMETER          ( ONE = ( 1.0D+0, 0.0D+0 ) )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JC, MI, NI, NQ
+      COMPLEX*16         AII, TAUI
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLACGV, ZLARF
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNML2', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. NOTRAN .OR. .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JC = 1
+      ELSE
+         MI = M
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         IF( NOTRAN ) THEN
+            TAUI = DCONJG( TAU( I ) )
+         ELSE
+            TAUI = TAU( I )
+         END IF
+         IF( I.LT.NQ )
+     $      CALL ZLACGV( NQ-I, A( I, I+1 ), LDA )
+         AII = A( I, I )
+         A( I, I ) = ONE
+         CALL ZLARF( SIDE, MI, NI, A( I, I ), LDA, TAUI, C( IC, JC ),
+     $               LDC, WORK )
+         A( I, I ) = AII
+         IF( I.LT.NQ )
+     $      CALL ZLACGV( NQ-I, A( I, I+1 ), LDA )
+   10 CONTINUE
+      RETURN
+*
+*     End of ZUNML2
+*
+      END
diff --git a/libcruft/lapack/zunmlq.f b/libcruft/lapack/zunmlq.f
new file mode 100644
index 0000000..b170875
--- /dev/null
+++ b/libcruft/lapack/zunmlq.f
@@ -0,0 +1,267 @@
+      SUBROUTINE ZUNMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNMLQ overwrites the general complex M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(k)' . . . H(2)' H(1)'
+*
+*  as returned by ZGELQF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**H from the Left;
+*          = 'R': apply Q or Q**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'C':  Conjugate transpose, apply Q**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          ZGELQF in the first k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGELQF.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARFB, ZLARFT, ZUNML2
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'ZUNMLQ', SIDE // TRANS, M, N, K,
+     $        -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNMLQ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'ZUNMLQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZUNML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'C'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL ZLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL ZLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,
+     $                   A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK,
+     $                   LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZUNMLQ
+*
+      END
diff --git a/libcruft/lapack/zunmqr.f b/libcruft/lapack/zunmqr.f
new file mode 100644
index 0000000..f9b1e98
--- /dev/null
+++ b/libcruft/lapack/zunmqr.f
@@ -0,0 +1,260 @@
+      SUBROUTINE ZUNMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNMQR overwrites the general complex M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by ZGEQRF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**H from the Left;
+*          = 'R': apply Q or Q**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'C':  Conjugate transpose, apply Q**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension (LDA,K)
+*          The i-th column must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          ZGEQRF in the first k columns of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A.
+*          If SIDE = 'L', LDA >= max(1,M);
+*          if SIDE = 'R', LDA >= max(1,N).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZGEQRF.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
+     $                   LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARFB, ZLARFT, ZUNM2R
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = N
+      ELSE
+         NQ = N
+         NW = M
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
+         INFO = -7
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+         INFO = -12
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+*
+*        Determine the block size.  NB may be at most NBMAX, where NBMAX
+*        is used to define the local array T.
+*
+         NB = MIN( NBMAX, ILAENV( 1, 'ZUNMQR', SIDE // TRANS, M, N, K,
+     $        -1 ) )
+         LWKOPT = MAX( 1, NW )*NB
+         WORK( 1 ) = LWKOPT
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNMQR', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
+         WORK( 1 ) = 1
+         RETURN
+      END IF
+*
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'ZUNMQR', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZUNM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
+     $                IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+         ELSE
+            MI = M
+            IC = 1
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i) H(i+1) . . . H(i+ib-1)
+*
+            CALL ZLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ),
+     $                   LDA, TAU( I ), T, LDT )
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL ZLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI,
+     $                   IB, A( I, I ), LDA, T, LDT, C( IC, JC ), LDC,
+     $                   WORK, LDWORK )
+   10    CONTINUE
+      END IF
+      WORK( 1 ) = LWKOPT
+      RETURN
+*
+*     End of ZUNMQR
+*
+      END
diff --git a/libcruft/lapack/zunmr3.f b/libcruft/lapack/zunmr3.f
new file mode 100644
index 0000000..111c1c9
--- /dev/null
+++ b/libcruft/lapack/zunmr3.f
@@ -0,0 +1,212 @@
+      SUBROUTINE ZUNMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, INFO )
+*
+*  -- LAPACK routine (version 3.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     November 2006
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNMR3 overwrites the general complex m by n matrix C with
+*
+*        Q * C  if SIDE = 'L' and TRANS = 'N', or
+*
+*        Q'* C  if SIDE = 'L' and TRANS = 'C', or
+*
+*        C * Q  if SIDE = 'R' and TRANS = 'N', or
+*
+*        C * Q' if SIDE = 'R' and TRANS = 'C',
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by ZTZRZF. Q is of order m if SIDE = 'L' and of order n
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q' from the Left
+*          = 'R': apply Q or Q' from the Right
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N': apply Q  (No transpose)
+*          = 'C': apply Q' (Conjugate transpose)
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          ZTZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZTZRZF.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the m-by-n matrix C.
+*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace) COMPLEX*16 array, dimension
+*                                   (N) if SIDE = 'L',
+*                                   (M) if SIDE = 'R'
+*
+*  INFO    (output) INTEGER
+*          = 0: successful exit
+*          < 0: if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      LOGICAL            LEFT, NOTRAN
+      INTEGER            I, I1, I2, I3, IC, JA, JC, MI, NI, NQ
+      COMPLEX*16         TAUI
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      EXTERNAL           LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARZ
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          DCONJG, MAX
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+*
+*     NQ is the order of Q
+*
+      IF( LEFT ) THEN
+         NQ = M
+      ELSE
+         NQ = N
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNMR3', -INFO )
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
+     $   RETURN
+*
+      IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THEN
+         I1 = 1
+         I2 = K
+         I3 = 1
+      ELSE
+         I1 = K
+         I2 = 1
+         I3 = -1
+      END IF
+*
+      IF( LEFT ) THEN
+         NI = N
+         JA = M - L + 1
+         JC = 1
+      ELSE
+         MI = M
+         JA = N - L + 1
+         IC = 1
+      END IF
+*
+      DO 10 I = I1, I2, I3
+         IF( LEFT ) THEN
+*
+*           H(i) or H(i)' is applied to C(i:m,1:n)
+*
+            MI = M - I + 1
+            IC = I
+         ELSE
+*
+*           H(i) or H(i)' is applied to C(1:m,i:n)
+*
+            NI = N - I + 1
+            JC = I
+         END IF
+*
+*        Apply H(i) or H(i)'
+*
+         IF( NOTRAN ) THEN
+            TAUI = TAU( I )
+         ELSE
+            TAUI = DCONJG( TAU( I ) )
+         END IF
+         CALL ZLARZ( SIDE, MI, NI, L, A( I, JA ), LDA, TAUI,
+     $               C( IC, JC ), LDC, WORK )
+*
+   10 CONTINUE
+*
+      RETURN
+*
+*     End of ZUNMR3
+*
+      END
diff --git a/libcruft/lapack/zunmrz.f b/libcruft/lapack/zunmrz.f
new file mode 100644
index 0000000..dcce686
--- /dev/null
+++ b/libcruft/lapack/zunmrz.f
@@ -0,0 +1,297 @@
+      SUBROUTINE ZUNMRZ( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                   WORK, LWORK, INFO )
+*
+*  -- LAPACK routine (version 3.1.1) --
+*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+*     January 2007
+*
+*     .. Scalar Arguments ..
+      CHARACTER          SIDE, TRANS
+      INTEGER            INFO, K, L, LDA, LDC, LWORK, M, N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
+*     ..
+*
+*  Purpose
+*  =======
+*
+*  ZUNMRZ overwrites the general complex M-by-N matrix C with
+*
+*                  SIDE = 'L'     SIDE = 'R'
+*  TRANS = 'N':      Q * C          C * Q
+*  TRANS = 'C':      Q**H * C       C * Q**H
+*
+*  where Q is a complex unitary matrix defined as the product of k
+*  elementary reflectors
+*
+*        Q = H(1) H(2) . . . H(k)
+*
+*  as returned by ZTZRZF. Q is of order M if SIDE = 'L' and of order N
+*  if SIDE = 'R'.
+*
+*  Arguments
+*  =========
+*
+*  SIDE    (input) CHARACTER*1
+*          = 'L': apply Q or Q**H from the Left;
+*          = 'R': apply Q or Q**H from the Right.
+*
+*  TRANS   (input) CHARACTER*1
+*          = 'N':  No transpose, apply Q;
+*          = 'C':  Conjugate transpose, apply Q**H.
+*
+*  M       (input) INTEGER
+*          The number of rows of the matrix C. M >= 0.
+*
+*  N       (input) INTEGER
+*          The number of columns of the matrix C. N >= 0.
+*
+*  K       (input) INTEGER
+*          The number of elementary reflectors whose product defines
+*          the matrix Q.
+*          If SIDE = 'L', M >= K >= 0;
+*          if SIDE = 'R', N >= K >= 0.
+*
+*  L       (input) INTEGER
+*          The number of columns of the matrix A containing
+*          the meaningful part of the Householder reflectors.
+*          If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
+*
+*  A       (input) COMPLEX*16 array, dimension
+*                               (LDA,M) if SIDE = 'L',
+*                               (LDA,N) if SIDE = 'R'
+*          The i-th row must contain the vector which defines the
+*          elementary reflector H(i), for i = 1,2,...,k, as returned by
+*          ZTZRZF in the last k rows of its array argument A.
+*          A is modified by the routine but restored on exit.
+*
+*  LDA     (input) INTEGER
+*          The leading dimension of the array A. LDA >= max(1,K).
+*
+*  TAU     (input) COMPLEX*16 array, dimension (K)
+*          TAU(i) must contain the scalar factor of the elementary
+*          reflector H(i), as returned by ZTZRZF.
+*
+*  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
+*          On entry, the M-by-N matrix C.
+*          On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
+*
+*  LDC     (input) INTEGER
+*          The leading dimension of the array C. LDC >= max(1,M).
+*
+*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
+*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
+*
+*  LWORK   (input) INTEGER
+*          The dimension of the array WORK.
+*          If SIDE = 'L', LWORK >= max(1,N);
+*          if SIDE = 'R', LWORK >= max(1,M).
+*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
+*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
+*          blocksize.
+*
+*          If LWORK = -1, then a workspace query is assumed; the routine
+*          only calculates the optimal size of the WORK array, returns
+*          this value as the first entry of the WORK array, and no error
+*          message related to LWORK is issued by XERBLA.
+*
+*  INFO    (output) INTEGER
+*          = 0:  successful exit
+*          < 0:  if INFO = -i, the i-th argument had an illegal value
+*
+*  Further Details
+*  ===============
+*
+*  Based on contributions by
+*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      INTEGER            NBMAX, LDT
+      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            LEFT, LQUERY, NOTRAN
+      CHARACTER          TRANST
+      INTEGER            I, I1, I2, I3, IB, IC, IINFO, IWS, JA, JC,
+     $                   LDWORK, LWKOPT, MI, NB, NBMIN, NI, NQ, NW
+*     ..
+*     .. Local Arrays ..
+      COMPLEX*16         T( LDT, NBMAX )
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV
+      EXTERNAL           LSAME, ILAENV
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZLARZB, ZLARZT, ZUNMR3
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          MAX, MIN
+*     ..
+*     .. Executable Statements ..
+*
+*     Test the input arguments
+*
+      INFO = 0
+      LEFT = LSAME( SIDE, 'L' )
+      NOTRAN = LSAME( TRANS, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
+*
+*     NQ is the order of Q and NW is the minimum dimension of WORK
+*
+      IF( LEFT ) THEN
+         NQ = M
+         NW = MAX( 1, N )
+      ELSE
+         NQ = N
+         NW = MAX( 1, M )
+      END IF
+      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
+         INFO = -1
+      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
+         INFO = -2
+      ELSE IF( M.LT.0 ) THEN
+         INFO = -3
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
+         INFO = -5
+      ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.
+     $         ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THEN
+         INFO = -6
+      ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
+         INFO = -8
+      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
+         INFO = -11
+      END IF
+*
+      IF( INFO.EQ.0 ) THEN
+         IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+            LWKOPT = 1
+         ELSE
+*
+*           Determine the block size.  NB may be at most NBMAX, where
+*           NBMAX is used to define the local array T.
+*
+            NB = MIN( NBMAX, ILAENV( 1, 'ZUNMRQ', SIDE // TRANS, M, N,
+     $                               K, -1 ) )
+            LWKOPT = NW*NB
+         END IF
+         WORK( 1 ) = LWKOPT
+*
+         IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
+            INFO = -13
+         END IF
+      END IF
+*
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZUNMRZ', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible
+*
+      IF( M.EQ.0 .OR. N.EQ.0 ) THEN
+         RETURN
+      END IF
+*
+*     Determine the block size.  NB may be at most NBMAX, where NBMAX
+*     is used to define the local array T.
+*
+      NB = MIN( NBMAX, ILAENV( 1, 'ZUNMRQ', SIDE // TRANS, M, N, K,
+     $     -1 ) )
+      NBMIN = 2
+      LDWORK = NW
+      IF( NB.GT.1 .AND. NB.LT.K ) THEN
+         IWS = NW*NB
+         IF( LWORK.LT.IWS ) THEN
+            NB = LWORK / LDWORK
+            NBMIN = MAX( 2, ILAENV( 2, 'ZUNMRQ', SIDE // TRANS, M, N, K,
+     $              -1 ) )
+         END IF
+      ELSE
+         IWS = NW
+      END IF
+*
+      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
+*
+*        Use unblocked code
+*
+         CALL ZUNMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,
+     $                WORK, IINFO )
+      ELSE
+*
+*        Use blocked code
+*
+         IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.
+     $       ( .NOT.LEFT .AND. NOTRAN ) ) THEN
+            I1 = 1
+            I2 = K
+            I3 = NB
+         ELSE
+            I1 = ( ( K-1 ) / NB )*NB + 1
+            I2 = 1
+            I3 = -NB
+         END IF
+*
+         IF( LEFT ) THEN
+            NI = N
+            JC = 1
+            JA = M - L + 1
+         ELSE
+            MI = M
+            IC = 1
+            JA = N - L + 1
+         END IF
+*
+         IF( NOTRAN ) THEN
+            TRANST = 'C'
+         ELSE
+            TRANST = 'N'
+         END IF
+*
+         DO 10 I = I1, I2, I3
+            IB = MIN( NB, K-I+1 )
+*
+*           Form the triangular factor of the block reflector
+*           H = H(i+ib-1) . . . H(i+1) H(i)
+*
+            CALL ZLARZT( 'Backward', 'Rowwise', L, IB, A( I, JA ), LDA,
+     $                   TAU( I ), T, LDT )
+*
+            IF( LEFT ) THEN
+*
+*              H or H' is applied to C(i:m,1:n)
+*
+               MI = M - I + 1
+               IC = I
+            ELSE
+*
+*              H or H' is applied to C(1:m,i:n)
+*
+               NI = N - I + 1
+               JC = I
+            END IF
+*
+*           Apply H or H'
+*
+            CALL ZLARZB( SIDE, TRANST, 'Backward', 'Rowwise', MI, NI,
+     $                   IB, L, A( I, JA ), LDA, T, LDT, C( IC, JC ),
+     $                   LDC, WORK, LDWORK )
+   10    CONTINUE
+*
+      END IF
+*
+      WORK( 1 ) = LWKOPT
+*
+      RETURN
+*
+*     End of ZUNMRZ
+*
+      END
diff --git a/libcruft/misc/Makefile.in b/libcruft/misc/Makefile.in
new file mode 100644
index 0000000..17dfa82
--- /dev/null
+++ b/libcruft/misc/Makefile.in
@@ -0,0 +1,65 @@
+# Makefile for octave's libcruft/misc directory
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003,
+#               2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = d1mach.f r1mach.f i1mach.f
+
+CSRC = f77-fcn.c lo-error.c cquit.c
+
+CXXSRC = f77-extern.cc quit.cc
+
+MAKEDEPS := $(patsubst %.c, %.d, $(CSRC)) $(patsubst %.cc, %.d, $(CXXSRC))
+
+INCLUDES := f77-fcn.h lo-error.h oct-dlldefs.h quit.h
+
+SPECIAL:= d1mach-tst.for $(INCLUDES)
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+include ../Makerules
+
+install install-strip::
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octincludedir)/octave
+	for f in $(INCLUDES); do \
+	  rm -f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	done
+	$(mk-includedir-link)
+
+uninstall::
+	for f in $(INCLUDES); do rm -f $(DESTDIR)$(octincludedir)/octave/$$f; done
+
+ifdef omit_deps
+.PHONY: $(MAKEDEPS)
+endif
+
+-include $(MAKEDEPS)
diff --git a/libcruft/misc/cquit.c b/libcruft/misc/cquit.c
new file mode 100644
index 0000000..444b1a3
--- /dev/null
+++ b/libcruft/misc/cquit.c
@@ -0,0 +1,266 @@
+/*
+
+Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <string.h>
+
+#include "quit.h"
+
+octave_jmp_buf current_context;
+
+void
+octave_save_current_context (void *save_buf)
+{
+  memcpy (save_buf, current_context, sizeof (octave_jmp_buf));
+}
+
+void
+octave_restore_current_context (void *save_buf)
+{
+  memcpy (current_context, save_buf, sizeof (octave_jmp_buf));
+}
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+
+/* FIXME -- eventually remove the debugging */
+#if defined (DEBUG)
+
+#define PRINT_CURRENT_THREAD() printf ("%lx: ", GetCurrentThreadId ())
+
+#define DEBUGs(s) \
+  do \
+    { \
+      PRINT_CURRENT_THREAD (); \
+      printf (s "\n"); \
+      fflush (stdout); \
+    } \
+  while (0)
+
+#define DEBUGd(s, d) \
+  do \
+    { \
+      PRINT_CURRENT_THREAD (); \
+      printf (s "\n", d); \
+      fflush (stdout); \
+    } \
+  while (0)
+
+#else
+#define DEBUGs(s)
+#define DEBUGd(s, d)
+#endif
+
+CRITICAL_SECTION w32_thread_setjmp_mutex;
+static CONTEXT w32_signal_context;
+static int w32_signal_to_raise = 0;
+static DWORD w32_main_thread_id;
+static HANDLE w32_main_thread;
+static HANDLE w32_restore_thread = NULL;
+
+int
+w32_in_main_thread(void)
+{
+  return (GetCurrentThreadId () == w32_main_thread_id);
+}
+
+static DWORD WINAPI
+w32_reset_context (LPVOID v)
+{
+  PCONTEXT context = (PCONTEXT)v;
+  int ret;
+
+  /* Mutex the setjmp/longjmp */
+  EnterCriticalSection (&w32_thread_setjmp_mutex);
+
+  DEBUGs ("enter w32_set_context");
+  SuspendThread (w32_main_thread);
+  DEBUGs ("main suspended");
+  if (! SetThreadContext (w32_main_thread, context)) 
+    {
+      fprintf (stderr, "%lx: context failed: ctrl-c won't work\n",
+	       GetCurrentThreadId ()); 
+      fflush (stderr);
+    }
+  DEBUGs ("context captured (or not)");
+  ret = ResumeThread (w32_main_thread);
+  DEBUGd ("main resumed with %d", ret);
+
+  LeaveCriticalSection (&w32_thread_setjmp_mutex);
+  return 0;
+}
+
+static void 
+w32_raise_in_main (void)
+{
+  DWORD threadid;
+
+  DEBUGd ("w32_raise_in_main with signal %d", w32_signal_to_raise);
+  raise (w32_signal_to_raise);
+  DEBUGd ("w32_raise_in_main signal %d returned a value",
+	  w32_signal_to_raise);
+
+  DEBUGs ("attempting to restore main to pre-signal configuration");
+  if (w32_restore_thread != NULL) /* Catch leaky threads */
+    CloseHandle (w32_restore_thread);
+  w32_restore_thread = CreateThread (NULL, 10000, w32_reset_context,
+				     &w32_signal_context, 0, &threadid);
+  if (w32_restore_thread == NULL) 
+    {
+      fprintf (stderr, "w32_raise_in_main couldn't create thread\n"); 
+      fflush (stderr);
+    } 
+  else 
+    {
+      DEBUGs ("waiting to restore raise context");
+      WaitForSingleObject (w32_restore_thread, INFINITE);
+      fprintf (stderr, "w32_raise_in_main couldn't restore context\n"); 
+      fflush (stderr);
+    }
+}
+
+void
+w32_raise_final (void)
+{
+  CloseHandle (w32_main_thread);
+  if (w32_restore_thread != NULL) /* Catch leaky threads */
+    CloseHandle (w32_restore_thread);
+  w32_main_thread = w32_restore_thread = NULL;
+}
+
+/* Raise the given signal in the main thread.  w32_raise_init ()
+   must have been called from the main thread already.  */
+void
+w32_raise (int sig)
+{
+  int ret;
+
+  if (w32_in_main_thread ()) 
+    {
+      /* Called from main thread -- a simple raise () should work.  */
+      DEBUGd ("raising signal %d within main", signal);
+      raise (sig);
+      DEBUGd ("returning from signal %d within main", signal);
+    } 
+  else 
+    {
+      /* Called from alternate thread -- call w32_raise_in_main in the
+         main thread with w32_signal_to_raise set to the signal */
+      CONTEXT raise_context;
+      DEBUGd ("raising signal %d from separate thread", signal);
+
+      /* Suspend main and remember the context.  */
+      SuspendThread (w32_main_thread);
+      /* X86 code */
+      w32_signal_context.ContextFlags 
+	= CONTEXT_FULL|CONTEXT_FLOATING_POINT|CONTEXT_DEBUG_REGISTERS;
+      GetThreadContext (w32_main_thread, &w32_signal_context);
+
+      /* Change the context to w32_raise_in_main.  The
+	 context.Eip=&fn trick for setting the program counter is
+	 courtesy of
+
+	   http://fit.c2.com/files/LispPlatform/lisp/clisp-2.28/src/win32aux.d
+
+         Auxiliary functions for CLISP on Win32, Bruno Haible
+	 1997-1999.  */
+
+      memcpy (&raise_context, &w32_signal_context, sizeof (CONTEXT));
+      raise_context.Eip = (DWORD)&w32_raise_in_main; /* X86 code */
+      w32_signal_to_raise = sig;
+      SetThreadContext (w32_main_thread, &raise_context);
+
+      /* Resume main at w32_raise_in_main */
+      ret = ResumeThread (w32_main_thread);
+      DEBUGd ("main resumed at w32_raise_in_main with suspend count %d",
+	      ret);
+    }
+}
+
+void
+w32_sigint_init (void)
+{
+  /* Capture main context */
+  w32_main_thread_id = GetCurrentThreadId ();
+  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
+		   GetCurrentProcess (), &w32_main_thread,
+		   0, FALSE, DUPLICATE_SAME_ACCESS);
+
+  InitializeCriticalSectionAndSpinCount (&w32_thread_setjmp_mutex, 0);
+}
+
+#endif /* #if defined (__WIN32__) && ! defined (_POSIX_VERSION) */
+
+void
+octave_jump_to_enclosing_context (void)
+{
+#if defined (OCTAVE_HAVE_SIG_JUMP)
+  siglongjmp (current_context, 1);
+#else
+  longjmp (current_context, 1);
+#endif
+}
+
+/* Allow us to save the signal mask and then restore it to the most
+   recently saved value.  This is necessary when using the POSIX
+   signal handling interface on some systems calling longjmp out of
+   the signal handler to get to the top level on an interrupt doesn't
+   restore the original signal mask.  Alternatively, we could use
+   sigsetjmp/siglongjmp, but saving and restoring the signal mask
+   ourselves works ok and seems simpler just now.  */
+
+#if defined (HAVE_POSIX_SIGNALS)
+static sigset_t octave_signal_mask;
+#endif
+
+void
+octave_save_signal_mask (void)
+{
+#if defined (HAVE_POSIX_SIGNALS)
+  sigprocmask (0, 0, &octave_signal_mask);
+#endif
+}
+
+void
+octave_restore_signal_mask (void)
+{
+#if defined (HAVE_POSIX_SIGNALS)
+  sigprocmask (SIG_SETMASK, &octave_signal_mask, 0);
+#endif
+}
+
+sig_atomic_t octave_interrupt_immediately = 0;
+
+sig_atomic_t octave_interrupt_state = 0;
+
+sig_atomic_t octave_exception_state = 0;
+
+volatile sig_atomic_t octave_signal_caught = 0;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/d1mach-tst.for b/libcruft/misc/d1mach-tst.for
new file mode 100644
index 0000000..0ba89f0
--- /dev/null
+++ b/libcruft/misc/d1mach-tst.for
@@ -0,0 +1,8 @@
+      program main
+      integer i
+      double precision d1mach
+      double precision t1, t2
+      do 10 i = 1, 5
+        print *, d1mach (i)
+   10 continue
+      end
diff --git a/libcruft/misc/d1mach.f b/libcruft/misc/d1mach.f
new file mode 100644
index 0000000..edafe69
--- /dev/null
+++ b/libcruft/misc/d1mach.f
@@ -0,0 +1,24 @@
+      double precision function d1mach (i)
+      integer i
+      logical init
+      double precision dmach(5)
+      double precision dlamch
+      external dlamch
+      save init, dmach
+      data init /.false./
+      if (.not. init) then
+        dmach(1) = dlamch ('u')
+        dmach(2) = dlamch ('o')
+        dmach(3) = dlamch ('e')
+        dmach(4) = dlamch ('p')
+        dmach(5) = log10 (dlamch ('b'))
+        init = .true.
+      endif
+      if (i .lt. 1 .or. i .gt. 5) goto 999
+      d1mach = dmach(i)
+      return
+  999 write (*, 1999) i
+ 1999 format (' d1mach - i out of bounds', i10)
+      call xstopx (' ')
+      d1mach = 0
+      end
diff --git a/libcruft/misc/f77-extern.cc b/libcruft/misc/f77-extern.cc
new file mode 100644
index 0000000..3e66282
--- /dev/null
+++ b/libcruft/misc/f77-extern.cc
@@ -0,0 +1,42 @@
+// misc-extern.cc                                     -*- C++ -*-
+/*
+
+Copyright (C) 1996, 1997, 2002, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+// This whole file is a kluge just to avoid unresolved symbol errors
+// when creating shared versions of libcruft.
+
+// So we can check to see if an exception has occurred.
+int f77_exception_encountered = 0;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/f77-fcn.c b/libcruft/misc/f77-fcn.c
new file mode 100644
index 0000000..7afb331
--- /dev/null
+++ b/libcruft/misc/f77-fcn.c
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1996, 1997, 2001, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "f77-fcn.h"
+#include "quit.h"
+#include "lo-error.h"
+
+/* All the STOP statements in the Fortran routines have been replaced
+   with a call to XSTOPX.
+
+   XSTOPX jumps back to the entry point for the Fortran function that
+   called us.  Then the calling function should do whatever cleanup
+   is necessary.  */
+
+F77_RET_T
+#if defined (F77_USES_CRAY_CALLING_CONVENTION)
+F77_FUNC (xstopx, XSTOPX) (octave_cray_ftn_ch_dsc desc)
+#elif defined (F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION)
+F77_FUNC (xstopx, XSTOPX) (const char *s, int slen)
+#else
+F77_FUNC (xstopx, XSTOPX) (const char *s, long slen)
+#endif
+{
+#if defined (F77_USES_CRAY_CALLING_CONVENTION)
+  const char *s = desc.const_ptr = ptr_arg;
+  unsigned long slen = desc.mask.len;
+#endif
+
+  f77_exception_encountered = 1;
+
+  /* Skip printing message if it is just a single blank character.  */
+  if (s && slen > 0 && ! (slen == 1 && *s == ' '))
+    (*current_liboctave_error_handler) ("%.*s", slen, s);
+
+  octave_jump_to_enclosing_context ();
+
+  F77_RETURN (0)
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/f77-fcn.h b/libcruft/misc/f77-fcn.h
new file mode 100644
index 0000000..ba867bc
--- /dev/null
+++ b/libcruft/misc/f77-fcn.h
@@ -0,0 +1,236 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_f77_fcn_h)
+#define octave_f77_fcn_h 1
+
+#include "quit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Hack to stringize macro results. */
+#define xSTRINGIZE(x) #x
+#define STRINGIZE(x) xSTRINGIZE(x)
+
+/* How to print an error for the F77_XFCN macro. */
+
+#define F77_XFCN_ERROR(f, F) \
+  (*current_liboctave_error_handler) \
+    ("exception encountered in Fortran subroutine %s", \
+     STRINGIZE (F77_FUNC (f, F)))
+
+/* This can be used to call a Fortran subroutine that might call
+   XSTOPX.  XSTOPX will call lonjmp with current_context.  Once back
+   here, we'll restore the previous context and return.  We may also
+   end up here if an interrupt is processed when the Fortran
+   subroutine is called.  In that case, we resotre the context and go
+   to the top level.  The error_state should be checked immediately
+   after this macro is used. */
+
+#define F77_XFCN(f, F, args) \
+  do \
+    { \
+      octave_jmp_buf saved_context; \
+      sig_atomic_t saved_octave_interrupt_immediately = octave_interrupt_immediately; \
+      f77_exception_encountered = 0; \
+      octave_save_current_context (saved_context); \
+      if (octave_set_current_context) \
+	{ \
+	  octave_interrupt_immediately = saved_octave_interrupt_immediately; \
+          octave_restore_current_context (saved_context); \
+	  if (f77_exception_encountered) \
+	    F77_XFCN_ERROR (f, F); \
+          else \
+	    octave_rethrow_exception (); \
+	} \
+      else \
+        { \
+	  octave_interrupt_immediately++; \
+	  F77_FUNC (f, F) args; \
+	  octave_interrupt_immediately--; \
+          octave_restore_current_context (saved_context); \
+        } \
+    } \
+  while (0)
+
+/* So we can check to see if an exception has occurred. */
+CRUFT_API extern int f77_exception_encountered;
+
+#if !defined (F77_FCN)
+#define F77_FCN(f, F) F77_FUNC (f, F)
+#endif
+
+#if defined (F77_USES_CRAY_CALLING_CONVENTION)
+
+#include <fortran.h>
+
+/* Use these macros to pass character strings from C to Fortran.  */
+#define F77_CHAR_ARG(x) octave_make_cray_ftn_ch_dsc (x, strlen (x))
+#define F77_CONST_CHAR_ARG(x) \
+  octave_make_cray_const_ftn_ch_dsc (x, strlen (x))
+#define F77_CHAR_ARG2(x, l) octave_make_cray_ftn_ch_dsc (x, l)
+#define F77_CONST_CHAR_ARG2(x, l) octave_make_cray_const_ftn_ch_dsc (x, l)
+#define F77_CXX_STRING_ARG(x) \
+  octave_make_cray_const_ftn_ch_dsc (x.c_str (), x.length ())
+#define F77_CHAR_ARG_LEN(l)
+#define F77_CHAR_ARG_DECL octave_cray_ftn_ch_dsc
+#define F77_CONST_CHAR_ARG_DECL octave_cray_ftn_ch_dsc
+#define F77_CHAR_ARG_LEN_DECL
+
+/* Use these macros to write C-language functions that accept
+   Fortran-style character strings.  */
+#define F77_CHAR_ARG_DEF(s, len) octave_cray_ftn_ch_dsc s
+#define F77_CONST_CHAR_ARG_DEF(s, len) octave_cray_ftn_ch_dsc s
+#define F77_CHAR_ARG_LEN_DEF(len) 
+#define F77_CHAR_ARG_USE(s) s.ptr
+#define F77_CHAR_ARG_LEN_USE(s, len) (s.mask.len>>3)
+
+#define F77_RET_T int
+#define F77_RETURN(retval) return retval;
+
+/* FIXME -- these should work for SV1 or Y-MP systems but will
+   need to be changed for others.  */
+
+typedef union
+{
+  const char *const_ptr;
+  char *ptr;
+  struct
+  {
+    unsigned off : 6;
+    unsigned len : 26;
+    unsigned add : 32;
+  } mask;
+} octave_cray_descriptor;
+
+typedef void *octave_cray_ftn_ch_dsc;
+
+#ifdef __cplusplus
+#define OCTAVE_F77_FCN_INLINE inline
+#else
+#define OCTAVE_F77_FCN_INLINE
+#endif
+
+static OCTAVE_F77_FCN_INLINE octave_cray_ftn_ch_dsc
+octave_make_cray_ftn_ch_dsc (char *ptr_arg, unsigned long len_arg)
+{
+  octave_cray_descriptor desc;
+  desc.ptr = ptr_arg;
+  desc.mask.len = len_arg << 3;
+  return *((octave_cray_ftn_ch_dsc *) &desc);
+}
+
+static OCTAVE_F77_FCN_INLINE octave_cray_ftn_ch_dsc
+octave_make_cray_const_ftn_ch_dsc (const char *ptr_arg, unsigned long len_arg)
+{
+  octave_cray_descriptor desc;
+  desc.const_ptr = ptr_arg;
+  desc.mask.len = len_arg << 3;
+  return *((octave_cray_ftn_ch_dsc *) &desc);
+}
+
+#ifdef __cplusplus
+#undef OCTAVE_F77_FCN_INLINE
+#endif
+
+#elif defined (F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION)
+
+/* Use these macros to pass character strings from C to Fortran.  */
+#define F77_CHAR_ARG(x) x, strlen (x)
+#define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x)
+#define F77_CHAR_ARG2(x, l) x, l
+#define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l)
+#define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ())
+#define F77_CHAR_ARG_LEN(l)
+#define F77_CHAR_ARG_DECL char *, int
+#define F77_CONST_CHAR_ARG_DECL const char *, int
+#define F77_CHAR_ARG_LEN_DECL
+
+/* Use these macros to write C-language functions that accept
+   Fortran-style character strings.  */
+#define F77_CHAR_ARG_DEF(s, len) char *s, int len
+#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s, int len
+#define F77_CHAR_ARG_LEN_DEF(len) 
+#define F77_CHAR_ARG_USE(s) s
+#define F77_CHAR_ARG_LEN_USE(s, len) len
+
+#define F77_RET_T void
+#define F77_RETURN(retval)
+
+#else
+
+/* Assume f2c-compatible calling convention.  */
+
+/* Use these macros to pass character strings from C to Fortran.  */
+#define F77_CHAR_ARG(x) x
+#define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x)
+#define F77_CHAR_ARG2(x, l) x
+#define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l)
+#define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ())
+#define F77_CHAR_ARG_LEN(l) , l
+#define F77_CHAR_ARG_DECL char *
+#define F77_CONST_CHAR_ARG_DECL const char *
+#define F77_CHAR_ARG_LEN_DECL , long
+
+/* Use these macros to write C-language functions that accept
+   Fortran-style character strings.  */
+#define F77_CHAR_ARG_DEF(s, len) char *s
+#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s
+#define F77_CHAR_ARG_LEN_DEF(len) , long len
+#define F77_CHAR_ARG_USE(s) s
+#define F77_CHAR_ARG_LEN_USE(s, len) len
+
+#define F77_RET_T int
+#define F77_RETURN(retval) return retval;
+
+#endif
+
+
+/* Build a C string local variable CS from the Fortran string parameter S
+   declared as F77_CHAR_ARG_DEF(s, len) or F77_CONST_CHAR_ARG_DEF(s, len).
+   The string will be cleaned up at the end of the current block.  
+   Needs to include <cstring> and <vector>.  */
+
+#define F77_CSTRING(s, len, cs) \
+ OCTAVE_LOCAL_BUFFER (char, cs, F77_CHAR_ARG_LEN_USE (s, len) + 1); \
+ memcpy (cs, F77_CHAR_ARG_USE (s), F77_CHAR_ARG_LEN_USE (s, len)); \
+ cs[F77_CHAR_ARG_LEN_USE(s, len)] = '\0' 
+
+
+extern CRUFT_API F77_RET_T
+F77_FUNC (xstopx, XSTOPX) (F77_CONST_CHAR_ARG_DECL
+			   F77_CHAR_ARG_LEN_DECL) GCC_ATTR_NORETURN;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/i1mach.f b/libcruft/misc/i1mach.f
new file mode 100644
index 0000000..dc9bb5f
--- /dev/null
+++ b/libcruft/misc/i1mach.f
@@ -0,0 +1,27 @@
+      integer function i1mach (i)
+      integer i, imach(16)
+      logical init
+      double precision dlamch
+      real slamch
+      external dlamch, slamch
+      save imach, init
+      data imach / 5, 6, 0, 6, 32, 4, 2, 31, 2147483647,
+     $     2, 0, 0, 0, 0, 0, 0 /
+      data init /.false./
+      if (.not. init) then
+        imach(11) = slamch ('n')
+        imach(12) = slamch ('m')
+        imach(13) = slamch ('l')
+        imach(14) = dlamch ('n')
+        imach(15) = dlamch ('m')
+        imach(16) = dlamch ('l')
+        init = .true.
+      endif
+      if (i .lt. 1 .or. i .gt. 16) goto 999
+      i1mach = imach(i)
+      return
+  999 write (*, 1999) i
+ 1999 format (' i1mach - i out of bounds', i10)
+      call xstopx (' ')
+      i1mach = 0
+      end
diff --git a/libcruft/misc/lo-error.c b/libcruft/misc/lo-error.c
new file mode 100644
index 0000000..479e16c
--- /dev/null
+++ b/libcruft/misc/lo-error.c
@@ -0,0 +1,120 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "lo-error.h"
+
+/* Having this file in this directory is a kluge to avoid unresolved
+   symbol errors when creating shared versions of libcruft. */
+
+/* Pointer to the current error handling function. */
+liboctave_error_handler current_liboctave_error_handler
+  = liboctave_fatal;
+
+/* Pointer to the current warning handler. */
+liboctave_warning_handler current_liboctave_warning_handler
+  = liboctave_warning;
+
+/* Pointer to the current warning_with_id handler. */
+liboctave_warning_with_id_handler current_liboctave_warning_with_id_handler
+  = liboctave_warning_with_id;
+
+static void
+verror (const char *name, const char *fmt, va_list args)
+{
+  if (name)
+    fprintf (stderr, "%s: ", name);
+
+  vfprintf (stderr, fmt, args);
+  fprintf (stderr, "\n");
+  fflush (stderr);
+}
+
+void
+set_liboctave_error_handler (liboctave_error_handler f)
+{
+  if (f)
+    current_liboctave_error_handler = f;
+  else
+    current_liboctave_error_handler = liboctave_fatal;
+}
+
+void
+set_liboctave_warning_handler (liboctave_warning_handler f)
+{
+  if (f)
+    current_liboctave_warning_handler = f;
+  else
+    current_liboctave_warning_handler = liboctave_warning;
+}
+
+void
+set_liboctave_warning_with_id_handler (liboctave_warning_with_id_handler f)
+{
+  if (f)
+    current_liboctave_warning_with_id_handler = f;
+  else
+    current_liboctave_warning_with_id_handler = liboctave_warning_with_id;
+}
+
+void
+liboctave_fatal (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror ("fatal", fmt, args);
+  va_end (args);
+
+  exit (1);
+}
+
+void
+liboctave_warning (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror ("warning", fmt, args);
+  va_end (args);
+}
+
+void
+liboctave_warning_with_id (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror ("warning", fmt, args);
+  va_end (args);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/lo-error.h b/libcruft/misc/lo-error.h
new file mode 100644
index 0000000..829361e
--- /dev/null
+++ b/libcruft/misc/lo-error.h
@@ -0,0 +1,66 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_error_h)
+#define octave_liboctave_error_h 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void liboctave_fatal (const char *fmt, ...) GCC_ATTR_NORETURN;
+
+extern void liboctave_warning (const char *fmt, ...);
+
+extern void liboctave_warning_with_id (const char *id, const char *fmt, ...);
+
+typedef void (*liboctave_error_handler) (const char *, ...);
+
+typedef void (*liboctave_warning_handler) (const char *, ...);
+
+typedef void (*liboctave_warning_with_id_handler) (const char *, const char *, ...);
+
+/* Would be nice to make these pointers private, but we want to share
+   them among all the liboctave classes. */
+CRUFT_API extern liboctave_error_handler current_liboctave_error_handler;
+
+CRUFT_API extern liboctave_warning_handler current_liboctave_warning_handler;
+
+CRUFT_API extern liboctave_warning_with_id_handler current_liboctave_warning_with_id_handler;
+
+CRUFT_API extern void set_liboctave_error_handler (liboctave_error_handler f);
+
+CRUFT_API extern void set_liboctave_warning_handler (liboctave_warning_handler f);
+
+CRUFT_API extern void set_liboctave_warning_with_id_handler (liboctave_warning_with_id_handler f);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/oct-dlldefs.h b/libcruft/misc/oct-dlldefs.h
new file mode 100644
index 0000000..7f6604c
--- /dev/null
+++ b/libcruft/misc/oct-dlldefs.h
@@ -0,0 +1,69 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dlldefs_h)
+#define octave_dlldefs_h 1
+
+#if defined (_MSC_VER)
+#define OCTAVE_EXPORT __declspec(dllexport)
+#define OCTAVE_IMPORT __declspec(dllimport)
+#else
+/* All other compilers, at least for now. */
+#define OCTAVE_EXPORT
+#define OCTAVE_IMPORT
+#endif
+
+/* API macro for libcruft */
+#ifdef CRUFT_DLL
+#define CRUFT_API OCTAVE_EXPORT
+#else
+#define CRUFT_API OCTAVE_IMPORT
+#endif
+
+/* API macro for liboctave */
+#ifdef OCTAVE_DLL
+#define OCTAVE_API OCTAVE_EXPORT
+#else
+#define OCTAVE_API OCTAVE_IMPORT
+#endif
+
+/* API macro for src */
+#ifdef OCTINTERP_DLL
+#define OCTINTERP_API OCTAVE_EXPORT
+#else
+#define OCTINTERP_API OCTAVE_IMPORT
+#endif
+
+/* API macro for src/graphics */
+#ifdef OCTGRAPHICS_DLL
+#define OCTGRAPHICS_API OCTAVE_EXPORT
+#else
+#define OCTGRAPHICS_API OCTAVE_IMPORT
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/quit.cc b/libcruft/misc/quit.cc
new file mode 100644
index 0000000..a47e3ab
--- /dev/null
+++ b/libcruft/misc/quit.cc
@@ -0,0 +1,108 @@
+/*
+
+Copyright (C) 2002, 2003, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstring>
+
+#include <iostream>
+#include <new>
+
+#include "quit.h"
+
+void (*octave_signal_hook) (void) = 0;
+void (*octave_interrupt_hook) (void) = 0;
+void (*octave_bad_alloc_hook) (void) = 0;
+
+void
+octave_handle_signal (void)
+{
+  if (octave_signal_hook)
+    octave_signal_hook ();
+
+  if (octave_interrupt_state > 0)
+    {
+      octave_interrupt_state = -1;
+      octave_throw_interrupt_exception ();
+    }
+}
+
+void
+octave_throw_interrupt_exception (void)
+{
+  if (octave_interrupt_hook)
+    octave_interrupt_hook ();
+    
+  throw octave_interrupt_exception ();
+}
+
+void
+octave_throw_execution_exception (void)
+{
+  // FIXME -- would a hook function be useful here?
+
+  octave_exception_state = octave_exec_exception;
+    
+  throw octave_execution_exception ();
+}
+
+void
+octave_throw_bad_alloc (void)
+{
+  if (octave_bad_alloc_hook)
+    octave_bad_alloc_hook ();
+    
+  octave_exception_state = octave_alloc_exception;
+
+  throw std::bad_alloc ();
+}
+
+void
+octave_rethrow_exception (void)
+{
+  if (octave_interrupt_state)
+    octave_throw_interrupt_exception ();
+  else
+    {
+      switch (octave_exception_state)
+	{
+	case octave_exec_exception:
+	  octave_throw_execution_exception ();
+	  break;
+
+	case octave_alloc_exception:
+	  octave_throw_bad_alloc ();
+	  break;
+
+	default:
+	  break;
+	}
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/quit.h b/libcruft/misc/quit.h
new file mode 100644
index 0000000..c5afc26
--- /dev/null
+++ b/libcruft/misc/quit.h
@@ -0,0 +1,223 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_quit_h)
+#define octave_quit_h 1
+
+#ifdef __cplusplus
+#include <new>
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+
+#include <windows.h>
+#undef min
+#undef max
+
+CRUFT_API extern void w32_sigint_init (void);   /* setup */
+CRUFT_API extern void w32_raise_final (void);   /* tear down */
+CRUFT_API extern void w32_raise (int sig);      /* raise signal in main thread */
+CRUFT_API extern int w32_in_main_thread (void); /* return true if in main thread */
+
+#endif
+
+#if defined (OCTAVE_HAVE_SIG_JUMP)
+
+typedef sigjmp_buf octave_jmp_buf;
+
+#define octave_set_current_context sigsetjmp (current_context, 1)
+
+#else
+
+typedef jmp_buf octave_jmp_buf;
+
+#define octave_set_current_context setjmp (current_context)
+
+#endif
+
+CRUFT_API extern octave_jmp_buf current_context;
+
+CRUFT_API extern void octave_save_current_context (void *);
+
+CRUFT_API extern void octave_restore_current_context (void *);
+
+CRUFT_API extern void octave_jump_to_enclosing_context (void) GCC_ATTR_NORETURN;
+
+CRUFT_API extern void octave_save_signal_mask (void);
+
+CRUFT_API extern void octave_restore_signal_mask (void);
+
+#ifdef __cplusplus
+class
+octave_execution_exception
+{
+};
+
+class
+octave_interrupt_exception
+{
+};
+#endif
+
+enum octave_exception
+{
+  octave_no_exception = 0,
+  octave_exec_exception = 1,
+  octave_alloc_exception = 2
+};
+
+CRUFT_API extern sig_atomic_t octave_interrupt_immediately;
+
+/*
+  > 0: interrupt pending
+    0: no interrupt pending
+  < 0: handling interrupt
+*/
+CRUFT_API extern sig_atomic_t octave_interrupt_state;
+
+CRUFT_API extern sig_atomic_t octave_exception_state;
+
+CRUFT_API extern volatile sig_atomic_t octave_signal_caught;
+
+CRUFT_API extern void octave_handle_signal (void);
+
+CRUFT_API extern void octave_throw_interrupt_exception (void) GCC_ATTR_NORETURN;
+
+CRUFT_API extern void octave_throw_execution_exception (void) GCC_ATTR_NORETURN;
+
+CRUFT_API extern void octave_throw_bad_alloc (void) GCC_ATTR_NORETURN;
+
+CRUFT_API extern void octave_rethrow_exception (void);
+
+#define OCTAVE_QUIT \
+  do \
+    { \
+      if (octave_signal_caught) \
+        { \
+          octave_signal_caught = 0; \
+          octave_handle_signal (); \
+        } \
+    } \
+  while (0)
+
+/* Normally, you just want to use
+
+     BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+     ... some code that calls a "foreign" function ...
+     END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+   but sometimes it is useful to do something like
+
+     BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1;
+     ... custom code here, normally ending in a call to
+         octave_rethrow_exception ...
+     BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2;
+
+   so that you can perform extra clean up operations before throwing
+   the interrupt exception.  */
+
+#define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; \
+  octave_rethrow_exception (); \
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2
+
+#define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1 \
+  do \
+    { \
+      octave_jmp_buf saved_context; \
+ \
+      octave_save_current_context (saved_context); \
+ \
+      if (octave_set_current_context) \
+	{ \
+	  octave_restore_current_context (saved_context)
+
+#define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2 \
+	} \
+      else \
+	{ \
+	  octave_interrupt_immediately++
+
+#define END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \
+	  octave_interrupt_immediately--; \
+          octave_restore_current_context (saved_context); \
+        } \
+    } \
+  while (0)
+
+#ifdef __cplusplus
+
+#define BEGIN_INTERRUPT_WITH_EXCEPTIONS \
+  sig_atomic_t saved_octave_interrupt_immediately = octave_interrupt_immediately; \
+ \
+  try \
+    { \
+      octave_interrupt_immediately = 0;
+
+#define END_INTERRUPT_WITH_EXCEPTIONS \
+    } \
+  catch (octave_interrupt_exception) \
+    { \
+      octave_interrupt_immediately = saved_octave_interrupt_immediately; \
+      octave_jump_to_enclosing_context (); \
+    } \
+  catch (octave_execution_exception) \
+    { \
+      octave_interrupt_immediately = saved_octave_interrupt_immediately; \
+      octave_exception_state = octave_exec_exception; \
+      octave_jump_to_enclosing_context (); \
+    } \
+  catch (std::bad_alloc) \
+    { \
+      octave_interrupt_immediately = saved_octave_interrupt_immediately; \
+      octave_exception_state = octave_alloc_exception; \
+      octave_jump_to_enclosing_context (); \
+    } \
+ \
+  octave_interrupt_immediately = saved_octave_interrupt_immediately
+#endif
+
+#ifdef __cplusplus
+}
+
+/* These should only be declared for C++ code, and should also be
+   outside of any extern "C" block.  */
+
+extern CRUFT_API void (*octave_signal_hook) (void);
+extern CRUFT_API void (*octave_interrupt_hook) (void);
+extern CRUFT_API void (*octave_bad_alloc_hook) (void);
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/libcruft/misc/r1mach.f b/libcruft/misc/r1mach.f
new file mode 100644
index 0000000..bd6492d
--- /dev/null
+++ b/libcruft/misc/r1mach.f
@@ -0,0 +1,24 @@
+      double precision function r1mach (i)
+      integer i
+      logical init
+      double precision rmach(5)
+      double precision slamch
+      external slamch
+      save init, rmach
+      data init /.false./
+      if (.not. init) then
+        rmach(1) = slamch ('u')
+        rmach(2) = slamch ('o')
+        rmach(3) = slamch ('e')
+        rmach(4) = slamch ('p')
+        rmach(5) = log10 (slamch ('b'))
+        init = .true.
+      endif
+      if (i .lt. 1 .or. i .gt. 5) goto 999
+      r1mach = rmach(i)
+      return
+  999 write (*, 1999) i
+ 1999 format (' r1mach - i out of bounds', i10)
+      call xstopx (' ')
+      d1mach = 0
+      end
diff --git a/libcruft/mkf77def.in b/libcruft/mkf77def.in
new file mode 100644
index 0000000..b567272
--- /dev/null
+++ b/libcruft/mkf77def.in
@@ -0,0 +1,46 @@
+#! /bin/sh
+#
+# Copyright (C) 2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+SED=${SED:-'sed'}
+AWK=${AWK:-'awk'}
+
+F77_TOLOWER=%F77_APPEND_UNDERSCORE%
+F77_APPEND_UNDERSCORE=%F77_APPEND_UNDERSCORE%
+F77_APPEND_EXTRA_UNDERSCORE=%F77_APPEND_EXTRA_UNDERSCORE%
+
+if $F77_TOLOWER; then
+  case_cmd="tolower";
+else
+  case_cmd="toupper";
+fi
+
+if $F77_APPEND_UNDERSCORE; then
+  uscore="_";
+else
+  uscore="";
+fi
+
+if $F77_APPEND_EXTRA_UNDERSCORE; then
+  awkcmd="$AWK '{ if (\$0 ~ /_/) extra = \"_\"; else extra = \"\"; printf (\"%s%s%s\n\", $case_cmd (\$0), \"$uscore\", extra); }'"
+else
+  awkcmd="$AWK '{ printf (\"%s%s\n\", tolower (\$0), \"$uscore\"); }'"
+fi
+
+$SED -n -e 'y/ABCDEFGHIJLKMNOPQRSTUVWXYZ/abcdefghijlkmnopqrstuvwxyz/; s/^\(      \|	\)[ 	]*\(.*function\|subroutine\|entry\)[ 	]*\([^ 	(]*\).*$/\3/p' | eval $awkcmd
diff --git a/libcruft/odepack/Makefile.in b/libcruft/odepack/Makefile.in
new file mode 100644
index 0000000..00641d1
--- /dev/null
+++ b/libcruft/odepack/Makefile.in
@@ -0,0 +1,34 @@
+# Makefile for octave's libcruft/odepack directory
+#
+# Copyright (C) 1993, 1994, 1995, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = cfode.f dlsode.f ewset.f intdy.f prepj.f solsy.f stode.f vnorm.f \
+  scfode.f sewset.f sintdy.f slsode.f sprepj.f ssolsy.f sstode.f svnorm.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/odepack/cfode.f b/libcruft/odepack/cfode.f
new file mode 100644
index 0000000..f07d17d
--- /dev/null
+++ b/libcruft/odepack/cfode.f
@@ -0,0 +1,112 @@
+      SUBROUTINE CFODE (METH, ELCO, TESCO)
+CLLL. OPTIMIZE
+      INTEGER METH
+      INTEGER I, IB, NQ, NQM1, NQP1
+      DOUBLE PRECISION ELCO, TESCO
+      DOUBLE PRECISION AGAMQ, FNQ, FNQM1, PC, PINT, RAGQ,
+     1   RQFAC, RQ1FAC, TSIGN, XPIN
+      DIMENSION ELCO(13,12), TESCO(3,12)
+C-----------------------------------------------------------------------
+C CFODE IS CALLED BY THE INTEGRATOR ROUTINE TO SET COEFFICIENTS
+C NEEDED THERE.  THE COEFFICIENTS FOR THE CURRENT METHOD, AS
+C GIVEN BY THE VALUE OF METH, ARE SET FOR ALL ORDERS AND SAVED.
+C THE MAXIMUM ORDER ASSUMED HERE IS 12 IF METH = 1 AND 5 IF METH = 2. 
+C (A SMALLER VALUE OF THE MAXIMUM ORDER IS ALSO ALLOWED.)
+C CFODE IS CALLED ONCE AT THE BEGINNING OF THE PROBLEM,
+C AND IS NOT CALLED AGAIN UNLESS AND UNTIL METH IS CHANGED. 
+C
+C THE ELCO ARRAY CONTAINS THE BASIC METHOD COEFFICIENTS.
+C THE COEFFICIENTS EL(I), 1 .LE. I .LE. NQ+1, FOR THE METHOD OF
+C ORDER NQ ARE STORED IN ELCO(I,NQ).  THEY ARE GIVEN BY A GENETRATING 
+C POLYNOMIAL, I.E., 
+C     L(X) = EL(1) + EL(2)*X + ... + EL(NQ+1)*X**NQ.
+C FOR THE IMPLICIT ADAMS METHODS, L(X) IS GIVEN BY
+C     DL/DX = (X+1)*(X+2)*...*(X+NQ-1)/FACTORIAL(NQ-1),    L(-1) = 0. 
+C FOR THE BDF METHODS, L(X) IS GIVEN BY 
+C     L(X) = (X+1)*(X+2)* ... *(X+NQ)/K,
+C WHERE         K = FACTORIAL(NQ)*(1 + 1/2 + ... + 1/NQ).
+C
+C THE TESCO ARRAY CONTAINS TEST CONSTANTS USED FOR THE
+C LOCAL ERROR TEST AND THE SELECTION OF STEP SIZE AND/OR ORDER.
+C AT ORDER NQ, TESCO(K,NQ) IS USED FOR THE SELECTION OF STEP
+C SIZE AT ORDER NQ - 1 IF K = 1, AT ORDER NQ IF K = 2, AND AT ORDER
+C NQ + 1 IF K = 3.
+C-----------------------------------------------------------------------
+      DIMENSION PC(12)
+C
+      GO TO (100, 200), METH
+C
+ 100  ELCO(1,1) = 1.0D0
+      ELCO(2,1) = 1.0D0
+      TESCO(1,1) = 0.0D0
+      TESCO(2,1) = 2.0D0
+      TESCO(1,2) = 1.0D0
+      TESCO(3,12) = 0.0D0
+      PC(1) = 1.0D0 
+      RQFAC = 1.0D0 
+      DO 140 NQ = 2,12
+C-----------------------------------------------------------------------
+C THE PC ARRAY WILL CONTAIN THE COEFFICIENTS OF THE POLYNOMIAL
+C     P(X) = (X+1)*(X+2)*...*(X+NQ-1).
+C INITIALLY, P(X) = 1.
+C-----------------------------------------------------------------------
+        RQ1FAC = RQFAC
+        RQFAC = RQFAC/DBLE(NQ)
+        NQM1 = NQ - 1
+        FNQM1 = DBLE(NQM1)  
+        NQP1 = NQ + 1
+C FORM COEFFICIENTS OF P(X)*(X+NQ-1). ----------------------------------
+        PC(NQ) = 0.0D0
+        DO 110 IB = 1,NQM1
+          I = NQP1 - IB
+ 110      PC(I) = PC(I-1) + FNQM1*PC(I) 
+        PC(1) = FNQM1*PC(1)
+C COMPUTE INTEGRAL, -1 TO 0, OF P(X) AND X*P(X). -----------------------
+        PINT = PC(1)
+        XPIN = PC(1)/2.0D0
+        TSIGN = 1.0D0
+        DO 120 I = 2,NQ
+          TSIGN = -TSIGN
+          PINT = PINT + TSIGN*PC(I)/DBLE(I)     
+ 120      XPIN = XPIN + TSIGN*PC(I)/DBLE(I+1)   
+C STORE COEFFICIENTS IN ELCO AND TESCO. --------------------------------
+        ELCO(1,NQ) = PINT*RQ1FAC
+        ELCO(2,NQ) = 1.0D0
+        DO 130 I = 2,NQ
+ 130      ELCO(I+1,NQ) = RQ1FAC*PC(I)/DBLE(I)   
+        AGAMQ = RQFAC*XPIN
+        RAGQ = 1.0D0/AGAMQ
+        TESCO(2,NQ) = RAGQ
+        IF (NQ .LT. 12) TESCO(1,NQP1) = RAGQ*RQFAC/DBLE(NQP1)       
+        TESCO(3,NQM1) = RAGQ
+ 140    CONTINUE
+      RETURN
+C
+ 200  PC(1) = 1.0D0 
+      RQ1FAC = 1.0D0
+      DO 230 NQ = 1,5
+C-----------------------------------------------------------------------
+C THE PC ARRAY WILL CONTAIN THE COEFFICIENTS OF THE POLYNOMIAL
+C     P(X) = (X+1)*(X+2)*...*(X+NQ).
+C INITIALLY, P(X) = 1.
+C-----------------------------------------------------------------------
+        FNQ = DBLE(NQ)      
+        NQP1 = NQ + 1
+C FORM COEFFICIENTS OF P(X)*(X+NQ). ------------------------------------
+        PC(NQP1) = 0.0D0
+        DO 210 IB = 1,NQ
+          I = NQ + 2 - IB
+ 210      PC(I) = PC(I-1) + FNQ*PC(I)
+        PC(1) = FNQ*PC(1)
+C STORE COEFFICIENTS IN ELCO AND TESCO. --------------------------------
+        DO 220 I = 1,NQP1
+ 220      ELCO(I,NQ) = PC(I)/PC(2)
+        ELCO(2,NQ) = 1.0D0
+        TESCO(1,NQ) = RQ1FAC
+        TESCO(2,NQ) = DBLE(NQP1)/ELCO(1,NQ)     
+        TESCO(3,NQ) = DBLE(NQ+2)/ELCO(1,NQ)     
+        RQ1FAC = RQ1FAC/FNQ
+ 230    CONTINUE
+      RETURN
+C----------------------- END OF SUBROUTINE CFODE -----------------------
+      END 
diff --git a/libcruft/odepack/dlsode.f b/libcruft/odepack/dlsode.f
new file mode 100644
index 0000000..af060b7
--- /dev/null
+++ b/libcruft/odepack/dlsode.f
@@ -0,0 +1,1522 @@
+      SUBROUTINE DLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
+     1            ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)
+      EXTERNAL F, JAC
+      INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
+      DOUBLE PRECISION Y, T, TOUT, RTOL, ATOL, RWORK
+      DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW)
+C-----------------------------------------------------------------------
+C THIS IS THE MARCH 30, 1987 VERSION OF 
+C LSODE.. LIVERMORE SOLVER FOR ORDINARY DIFFERENTIAL EQUATIONS.
+C THIS VERSION IS IN DOUBLE PRECISION.
+C
+C LSODE SOLVES THE INITIAL VALUE PROBLEM FOR STIFF OR NONSTIFF
+C SYSTEMS OF FIRST ORDER ODE-S,
+C     DY/DT = F(T,Y) ,  OR, IN COMPONENT FORM,
+C     DY(I)/DT = F(I) = F(I,T,Y(1),Y(2),...,Y(NEQ)) (I = 1,...,NEQ).
+C LSODE IS A PACKAGE BASED ON THE GEAR AND GEARB PACKAGES, AND ON THE 
+C OCTOBER 23, 1978 VERSION OF THE TENTATIVE ODEPACK USER INTERFACE
+C STANDARD, WITH MINOR MODIFICATIONS.
+C-----------------------------------------------------------------------
+C REFERENCE..
+C     ALAN C. HINDMARSH,  ODEPACK, A SYSTEMATIZED COLLECTION OF ODE
+C     SOLVERS, IN SCIENTIFIC COMPUTING, R. S. STEPLEMAN ET AL. (EDS.),
+C     NORTH-HOLLAND, AMSTERDAM, 1983, PP. 55-64.
+C-----------------------------------------------------------------------
+C AUTHOR AND CONTACT.. ALAN C. HINDMARSH,
+C                      COMPUTING AND MATHEMATICS RESEARCH DIV., L-316 
+C                      LAWRENCE LIVERMORE NATIONAL LABORATORY
+C                      LIVERMORE, CA 94550.
+C-----------------------------------------------------------------------
+C SUMMARY OF USAGE. 
+C
+C COMMUNICATION BETWEEN THE USER AND THE LSODE PACKAGE, FOR NORMAL
+C SITUATIONS, IS SUMMARIZED HERE.  THIS SUMMARY DESCRIBES ONLY A SUBSET
+C OF THE FULL SET OF OPTIONS AVAILABLE.  SEE THE FULL DESCRIPTION FOR 
+C DETAILS, INCLUDING OPTIONAL COMMUNICATION, NONSTANDARD OPTIONS,
+C AND INSTRUCTIONS FOR SPECIAL SITUATIONS.  SEE ALSO THE EXAMPLE
+C PROBLEM (WITH PROGRAM AND OUTPUT) FOLLOWING THIS SUMMARY. 
+C
+C A. FIRST PROVIDE A SUBROUTINE OF THE FORM..
+C               SUBROUTINE F (NEQ, T, Y, YDOT, IERR)
+C               DIMENSION Y(NEQ), YDOT(NEQ)
+C WHICH SUPPLIES THE VECTOR FUNCTION F BY LOADING YDOT(I) WITH F(I).
+C
+C B. NEXT DETERMINE (OR GUESS) WHETHER OR NOT THE PROBLEM IS STIFF.
+C STIFFNESS OCCURS WHEN THE JACOBIAN MATRIX DF/DY HAS AN EIGENVALUE
+C WHOSE REAL PART IS NEGATIVE AND LARGE IN MAGNITUDE, COMPARED TO THE 
+C RECIPROCAL OF THE T SPAN OF INTEREST.  IF THE PROBLEM IS NONSTIFF,
+C USE A METHOD FLAG MF = 10.  IF IT IS STIFF, THERE ARE FOUR STANDARD 
+C CHOICES FOR MF, AND LSODE REQUIRES THE JACOBIAN MATRIX IN SOME FORM.
+C THIS MATRIX IS REGARDED EITHER AS FULL (MF = 21 OR 22),
+C OR BANDED (MF = 24 OR 25).  IN THE BANDED CASE, LSODE REQUIRES TWO
+C HALF-BANDWIDTH PARAMETERS ML AND MU.  THESE ARE, RESPECTIVELY, THE
+C WIDTHS OF THE LOWER AND UPPER PARTS OF THE BAND, EXCLUDING THE MAIN 
+C DIAGONAL.  THUS THE BAND CONSISTS OF THE LOCATIONS (I,J) WITH
+C I-ML .LE. J .LE. I+MU, AND THE FULL BANDWIDTH IS ML+MU+1. 
+C
+C C. IF THE PROBLEM IS STIFF, YOU ARE ENCOURAGED TO SUPPLY THE JACOBIAN
+C DIRECTLY (MF = 21 OR 24), BUT IF THIS IS NOT FEASIBLE, LSODE WILL
+C COMPUTE IT INTERNALLY BY DIFFERENCE QUOTIENTS (MF = 22 OR 25).
+C IF YOU ARE SUPPLYING THE JACOBIAN, PROVIDE A SUBROUTINE OF THE FORM..
+C               SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
+C               DIMENSION Y(NEQ), PD(NROWPD,NEQ)
+C WHICH SUPPLIES DF/DY BY LOADING PD AS FOLLOWS.. 
+C     FOR A FULL JACOBIAN (MF = 21), LOAD PD(I,J) WITH DF(I)/DY(J),
+C THE PARTIAL DERIVATIVE OF F(I) WITH RESPECT TO Y(J).  (IGNORE THE
+C ML AND MU ARGUMENTS IN THIS CASE.)
+C     FOR A BANDED JACOBIAN (MF = 24), LOAD PD(I-J+MU+1,J) WITH
+C DF(I)/DY(J), I.E. LOAD THE DIAGONAL LINES OF DF/DY INTO THE ROWS OF 
+C PD FROM THE TOP DOWN.
+C     IN EITHER CASE, ONLY NONZERO ELEMENTS NEED BE LOADED. 
+C
+C D. WRITE A MAIN PROGRAM WHICH CALLS SUBROUTINE LSODE ONCE FOR
+C EACH POINT AT WHICH ANSWERS ARE DESIRED.  THIS SHOULD ALSO PROVIDE
+C FOR POSSIBLE USE OF LOGICAL UNIT 6 FOR OUTPUT OF ERROR MESSAGES
+C BY LSODE.  ON THE FIRST CALL TO LSODE, SUPPLY ARGUMENTS AS FOLLOWS..
+C F      = NAME OF SUBROUTINE FOR RIGHT-HAND SIDE VECTOR F. 
+C          THIS NAME MUST BE DECLARED EXTERNAL IN CALLING PROGRAM.
+C NEQ    = NUMBER OF FIRST ORDER ODE-S. 
+C Y      = ARRAY OF INITIAL VALUES, OF LENGTH NEQ.
+C T      = THE INITIAL VALUE OF THE INDEPENDENT VARIABLE.
+C TOUT   = FIRST POINT WHERE OUTPUT IS DESIRED (.NE. T).
+C ITOL   = 1 OR 2 ACCORDING AS ATOL (BELOW) IS A SCALAR OR ARRAY.
+C RTOL   = RELATIVE TOLERANCE PARAMETER (SCALAR). 
+C ATOL   = ABSOLUTE TOLERANCE PARAMETER (SCALAR OR ARRAY).
+C          THE ESTIMATED LOCAL ERROR IN Y(I) WILL BE CONTROLLED SO AS 
+C          TO BE ROUGHLY LESS (IN MAGNITUDE) THAN 
+C             EWT(I) = RTOL*ABS(Y(I)) + ATOL     IF ITOL = 1, OR
+C             EWT(I) = RTOL*ABS(Y(I)) + ATOL(I)  IF ITOL = 2.
+C          THUS THE LOCAL ERROR TEST PASSES IF, IN EACH COMPONENT,
+C          EITHER THE ABSOLUTE ERROR IS LESS THAN ATOL (OR ATOL(I)),
+C          OR THE RELATIVE ERROR IS LESS THAN RTOL.
+C          USE RTOL = 0.0 FOR PURE ABSOLUTE ERROR CONTROL, AND
+C          USE ATOL = 0.0 (OR ATOL(I) = 0.0) FOR PURE RELATIVE ERROR
+C          CONTROL.  CAUTION.. ACTUAL (GLOBAL) ERRORS MAY EXCEED THESE
+C          LOCAL TOLERANCES, SO CHOOSE THEM CONSERVATIVELY. 
+C ITASK  = 1 FOR NORMAL COMPUTATION OF OUTPUT VALUES OF Y AT T = TOUT.
+C ISTATE = INTEGER FLAG (INPUT AND OUTPUT).  SET ISTATE = 1.
+C IOPT   = 0 TO INDICATE NO OPTIONAL INPUTS USED. 
+C RWORK  = REAL WORK ARRAY OF LENGTH AT LEAST..
+C             20 + 16*NEQ                    FOR MF = 10,
+C             22 +  9*NEQ + NEQ**2           FOR MF = 21 OR 22,
+C             22 + 10*NEQ + (2*ML + MU)*NEQ  FOR MF = 24 OR 25.
+C LRW    = DECLARED LENGTH OF RWORK (IN USER-S DIMENSION).
+C IWORK  = INTEGER WORK ARRAY OF LENGTH AT LEAST..
+C             20        FOR MF = 10,
+C             20 + NEQ  FOR MF = 21, 22, 24, OR 25.
+C          IF MF = 24 OR 25, INPUT IN IWORK(1),IWORK(2) THE LOWER
+C          AND UPPER HALF-BANDWIDTHS ML,MU.
+C LIW    = DECLARED LENGTH OF IWORK (IN USER-S DIMENSION).
+C JAC    = NAME OF SUBROUTINE FOR JACOBIAN MATRIX (MF = 21 OR 24).
+C          IF USED, THIS NAME MUST BE DECLARED EXTERNAL IN CALLING
+C          PROGRAM.  IF NOT USED, PASS A DUMMY NAME.
+C MF     = METHOD FLAG.  STANDARD VALUES ARE..
+C          10 FOR NONSTIFF (ADAMS) METHOD, NO JACOBIAN USED.
+C          21 FOR STIFF (BDF) METHOD, USER-SUPPLIED FULL JACOBIAN.
+C          22 FOR STIFF METHOD, INTERNALLY GENERATED FULL JACOBIAN.
+C          24 FOR STIFF METHOD, USER-SUPPLIED BANDED JACOBIAN.
+C          25 FOR STIFF METHOD, INTERNALLY GENERATED BANDED JACOBIAN. 
+C NOTE THAT THE MAIN PROGRAM MUST DECLARE ARRAYS Y, RWORK, IWORK,
+C AND POSSIBLY ATOL.
+C
+C E. THE OUTPUT FROM THE FIRST CALL (OR ANY CALL) IS..
+C      Y = ARRAY OF COMPUTED VALUES OF Y(T) VECTOR.
+C      T = CORRESPONDING VALUE OF INDEPENDENT VARIABLE (NORMALLY TOUT).
+C ISTATE = 2  IF LSODE WAS SUCCESSFUL, NEGATIVE OTHERWISE.
+C          -1 MEANS EXCESS WORK DONE ON THIS CALL (PERHAPS WRONG MF). 
+C          -2 MEANS EXCESS ACCURACY REQUESTED (TOLERANCES TOO SMALL). 
+C          -3 MEANS ILLEGAL INPUT DETECTED (SEE PRINTED MESSAGE).
+C          -4 MEANS REPEATED ERROR TEST FAILURES (CHECK ALL INPUTS).
+C          -5 MEANS REPEATED CONVERGENCE FAILURES (PERHAPS BAD JACOBIAN
+C             SUPPLIED OR WRONG CHOICE OF MF OR TOLERANCES).
+C          -6 MEANS ERROR WEIGHT BECAME ZERO DURING PROBLEM. (SOLUTION
+C             COMPONENT I VANISHED, AND ATOL OR ATOL(I) = 0.)
+C         -13 MEANS EXIT REQUESTED IN USER-SUPPLIED FUNCTION.
+C
+C F. TO CONTINUE THE INTEGRATION AFTER A SUCCESSFUL RETURN, SIMPLY
+C RESET TOUT AND CALL LSODE AGAIN.  NO OTHER PARAMETERS NEED BE RESET.
+C
+C-----------------------------------------------------------------------
+C EXAMPLE PROBLEM.
+C
+C THE FOLLOWING IS A SIMPLE EXAMPLE PROBLEM, WITH THE CODING
+C NEEDED FOR ITS SOLUTION BY LSODE.  THE PROBLEM IS FROM CHEMICAL
+C KINETICS, AND CONSISTS OF THE FOLLOWING THREE RATE EQUATIONS..
+C     DY1/DT = -.04*Y1 + 1.E4*Y2*Y3
+C     DY2/DT = .04*Y1 - 1.E4*Y2*Y3 - 3.E7*Y2**2
+C     DY3/DT = 3.E7*Y2**2
+C ON THE INTERVAL FROM T = 0.0 TO T = 4.E10, WITH INITIAL CONDITIONS
+C Y1 = 1.0, Y2 = Y3 = 0.  THE PROBLEM IS STIFF.
+C
+C THE FOLLOWING CODING SOLVES THIS PROBLEM WITH LSODE, USING MF = 21
+C AND PRINTING RESULTS AT T = .4, 4., ..., 4.E10.  IT USES
+C ITOL = 2 AND ATOL MUCH SMALLER FOR Y2 THAN Y1 OR Y3 BECAUSE
+C Y2 HAS MUCH SMALLER VALUES. 
+C AT THE END OF THE RUN, STATISTICAL QUANTITIES OF INTEREST ARE
+C PRINTED (SEE OPTIONAL OUTPUTS IN THE FULL DESCRIPTION BELOW).
+C
+C     EXTERNAL FEX, JEX
+C     DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y
+C     DIMENSION Y(3), ATOL(3), RWORK(58), IWORK(23)
+C     NEQ = 3
+C     Y(1) = 1.D0
+C     Y(2) = 0.D0
+C     Y(3) = 0.D0
+C     T = 0.D0
+C     TOUT = .4D0
+C     ITOL = 2
+C     RTOL = 1.D-4
+C     ATOL(1) = 1.D-6
+C     ATOL(2) = 1.D-10
+C     ATOL(3) = 1.D-6
+C     ITASK = 1
+C     ISTATE = 1
+C     IOPT = 0
+C     LRW = 58
+C     LIW = 23
+C     MF = 21
+C     DO 40 IOUT = 1,12
+C       CALL LSODE(FEX,NEQ,Y,T,TOUT,ITOL,RTOL,ATOL,ITASK,ISTATE,
+C    1     IOPT,RWORK,LRW,IWORK,LIW,JEX,MF)
+C       WRITE(6,20)T,Y(1),Y(2),Y(3)
+C 20    FORMAT(7H AT T =,E12.4,6H   Y =,3E14.6)
+C       IF (ISTATE .LT. 0) GO TO 80
+C 40    TOUT = TOUT*10.D0
+C     WRITE(6,60)IWORK(11),IWORK(12),IWORK(13)
+C 60  FORMAT(/12H NO. STEPS =,I4,11H  NO. F-S =,I4,11H  NO. J-S =,I4) 
+C     STOP
+C 80  WRITE(6,90)ISTATE
+C 90  FORMAT(///22H ERROR HALT.. ISTATE =,I3)
+C     STOP
+C     END 
+C
+C     SUBROUTINE FEX (NEQ, T, Y, YDOT)
+C     DOUBLE PRECISION T, Y, YDOT
+C     DIMENSION Y(3), YDOT(3) 
+C     YDOT(1) = -.04D0*Y(1) + 1.D4*Y(2)*Y(3)
+C     YDOT(3) = 3.D7*Y(2)*Y(2)
+C     YDOT(2) = -YDOT(1) - YDOT(3)
+C     RETURN
+C     END 
+C
+C     SUBROUTINE JEX (NEQ, T, Y, ML, MU, PD, NRPD)
+C     DOUBLE PRECISION PD, T, Y
+C     DIMENSION Y(3), PD(NRPD,3)
+C     PD(1,1) = -.04D0
+C     PD(1,2) = 1.D4*Y(3)
+C     PD(1,3) = 1.D4*Y(2)
+C     PD(2,1) = .04D0
+C     PD(2,3) = -PD(1,3)
+C     PD(3,2) = 6.D7*Y(2)
+C     PD(2,2) = -PD(1,2) - PD(3,2)
+C     RETURN
+C     END 
+C
+C THE OUTPUT OF THIS PROGRAM (ON A CDC-7600 IN SINGLE PRECISION)
+C IS AS FOLLOWS..
+C
+C   AT T =  4.0000E-01   Y =  9.851726E-01  3.386406E-05  1.479357E-02
+C   AT T =  4.0000E+00   Y =  9.055142E-01  2.240418E-05  9.446344E-02
+C   AT T =  4.0000E+01   Y =  7.158050E-01  9.184616E-06  2.841858E-01
+C   AT T =  4.0000E+02   Y =  4.504846E-01  3.222434E-06  5.495122E-01
+C   AT T =  4.0000E+03   Y =  1.831701E-01  8.940379E-07  8.168290E-01
+C   AT T =  4.0000E+04   Y =  3.897016E-02  1.621193E-07  9.610297E-01
+C   AT T =  4.0000E+05   Y =  4.935213E-03  1.983756E-08  9.950648E-01
+C   AT T =  4.0000E+06   Y =  5.159269E-04  2.064759E-09  9.994841E-01
+C   AT T =  4.0000E+07   Y =  5.306413E-05  2.122677E-10  9.999469E-01
+C   AT T =  4.0000E+08   Y =  5.494529E-06  2.197824E-11  9.999945E-01
+C   AT T =  4.0000E+09   Y =  5.129458E-07  2.051784E-12  9.999995E-01
+C   AT T =  4.0000E+10   Y = -7.170586E-08 -2.868234E-13  1.000000E+00
+C
+C   NO. STEPS = 330  NO. F-S = 405  NO. J-S =  69 
+C-----------------------------------------------------------------------
+C FULL DESCRIPTION OF USER INTERFACE TO LSODE.
+C
+C THE USER INTERFACE TO LSODE CONSISTS OF THE FOLLOWING PARTS.
+C
+C I.   THE CALL SEQUENCE TO SUBROUTINE LSODE, WHICH IS A DRIVER
+C      ROUTINE FOR THE SOLVER.  THIS INCLUDES DESCRIPTIONS OF BOTH
+C      THE CALL SEQUENCE ARGUMENTS AND OF USER-SUPPLIED ROUTINES.
+C      FOLLOWING THESE DESCRIPTIONS IS A DESCRIPTION OF
+C      OPTIONAL INPUTS AVAILABLE THROUGH THE CALL SEQUENCE, AND THEN
+C      A DESCRIPTION OF OPTIONAL OUTPUTS (IN THE WORK ARRAYS).
+C
+C II.  DESCRIPTIONS OF OTHER ROUTINES IN THE LSODE PACKAGE THAT MAY BE
+C      (OPTIONALLY) CALLED BY THE USER.  THESE PROVIDE THE ABILITY TO 
+C      ALTER ERROR MESSAGE HANDLING, SAVE AND RESTORE THE INTERNAL
+C      COMMON, AND OBTAIN SPECIFIED DERIVATIVES OF THE SOLUTION Y(T). 
+C
+C III. DESCRIPTIONS OF COMMON BLOCKS TO BE DECLARED IN OVERLAY
+C      OR SIMILAR ENVIRONMENTS, OR TO BE SAVED WHEN DOING AN INTERRUPT
+C      OF THE PROBLEM AND CONTINUED SOLUTION LATER.
+C
+C IV.  DESCRIPTION OF TWO ROUTINES IN THE LSODE PACKAGE, EITHER OF
+C      WHICH THE USER MAY REPLACE WITH HIS OWN VERSION, IF DESIRED.
+C      THESE RELATE TO THE MEASUREMENT OF ERRORS. 
+C
+C-----------------------------------------------------------------------
+C PART I.  CALL SEQUENCE.
+C
+C THE CALL SEQUENCE PARAMETERS USED FOR INPUT ONLY ARE
+C     F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, MF, 
+C AND THOSE USED FOR BOTH INPUT AND OUTPUT ARE
+C     Y, T, ISTATE. 
+C THE WORK ARRAYS RWORK AND IWORK ARE ALSO USED FOR CONDITIONAL AND
+C OPTIONAL INPUTS AND OPTIONAL OUTPUTS.  (THE TERM OUTPUT HERE REFERS 
+C TO THE RETURN FROM SUBROUTINE LSODE TO THE USER-S CALLING PROGRAM.) 
+C
+C THE LEGALITY OF INPUT PARAMETERS WILL BE THOROUGHLY CHECKED ON THE
+C INITIAL CALL FOR THE PROBLEM, BUT NOT CHECKED THEREAFTER UNLESS A
+C CHANGE IN INPUT PARAMETERS IS FLAGGED BY ISTATE = 3 ON INPUT.
+C
+C THE DESCRIPTIONS OF THE CALL ARGUMENTS ARE AS FOLLOWS.
+C
+C F      = THE NAME OF THE USER-SUPPLIED SUBROUTINE DEFINING THE
+C          ODE SYSTEM.  THE SYSTEM MUST BE PUT IN THE FIRST-ORDER
+C          FORM DY/DT = F(T,Y), WHERE F IS A VECTOR-VALUED FUNCTION
+C          OF THE SCALAR T AND THE VECTOR Y.  SUBROUTINE F IS TO
+C          COMPUTE THE FUNCTION F.  IT IS TO HAVE THE FORM
+C               SUBROUTINE F (NEQ, T, Y, YDOT)
+C               DIMENSION Y(1), YDOT(1) 
+C          WHERE NEQ, T, AND Y ARE INPUT, AND THE ARRAY YDOT = F(T,Y) 
+C          IS OUTPUT.  Y AND YDOT ARE ARRAYS OF LENGTH NEQ. 
+C          (IN THE DIMENSION STATEMENT ABOVE, 1 IS A DUMMY
+C          DIMENSION.. IT CAN BE REPLACED BY ANY VALUE.)
+C          SUBROUTINE F SHOULD NOT ALTER Y(1),...,Y(NEQ).
+C          F MUST BE DECLARED EXTERNAL IN THE CALLING PROGRAM.
+C
+C          SUBROUTINE F MAY ACCESS USER-DEFINED QUANTITIES IN
+C          NEQ(2),... AND/OR IN Y(NEQ(1)+1),... IF NEQ IS AN ARRAY
+C          (DIMENSIONED IN F) AND/OR Y HAS LENGTH EXCEEDING NEQ(1).
+C          SEE THE DESCRIPTIONS OF NEQ AND Y BELOW.
+C
+C          IF QUANTITIES COMPUTED IN THE F ROUTINE ARE NEEDED
+C          EXTERNALLY TO LSODE, AN EXTRA CALL TO F SHOULD BE MADE
+C          FOR THIS PURPOSE, FOR CONSISTENT AND ACCURATE RESULTS.
+C          IF ONLY THE DERIVATIVE DY/DT IS NEEDED, USE INTDY INSTEAD. 
+C
+C NEQ    = THE SIZE OF THE ODE SYSTEM (NUMBER OF FIRST ORDER
+C          ORDINARY DIFFERENTIAL EQUATIONS).  USED ONLY FOR INPUT.
+C          NEQ MAY BE DECREASED, BUT NOT INCREASED, DURING THE PROBLEM.
+C          IF NEQ IS DECREASED (WITH ISTATE = 3 ON INPUT), THE
+C          REMAINING COMPONENTS OF Y SHOULD BE LEFT UNDISTURBED, IF
+C          THESE ARE TO BE ACCESSED IN F AND/OR JAC.
+C
+C          NORMALLY, NEQ IS A SCALAR, AND IT IS GENERALLY REFERRED TO 
+C          AS A SCALAR IN THIS USER INTERFACE DESCRIPTION.  HOWEVER,
+C          NEQ MAY BE AN ARRAY, WITH NEQ(1) SET TO THE SYSTEM SIZE.
+C          (THE LSODE PACKAGE ACCESSES ONLY NEQ(1).)  IN EITHER CASE, 
+C          THIS PARAMETER IS PASSED AS THE NEQ ARGUMENT IN ALL CALLS
+C          TO F AND JAC.  HENCE, IF IT IS AN ARRAY, LOCATIONS
+C          NEQ(2),... MAY BE USED TO STORE OTHER INTEGER DATA AND PASS
+C          IT TO F AND/OR JAC.  SUBROUTINES F AND/OR JAC MUST INCLUDE 
+C          NEQ IN A DIMENSION STATEMENT IN THAT CASE.
+C
+C Y      = A REAL ARRAY FOR THE VECTOR OF DEPENDENT VARIABLES, OF
+C          LENGTH NEQ OR MORE.  USED FOR BOTH INPUT AND OUTPUT ON THE 
+C          FIRST CALL (ISTATE = 1), AND ONLY FOR OUTPUT ON OTHER CALLS.
+C          ON THE FIRST CALL, Y MUST CONTAIN THE VECTOR OF INITIAL
+C          VALUES.  ON OUTPUT, Y CONTAINS THE COMPUTED SOLUTION VECTOR,
+C          EVALUATED AT T.  IF DESIRED, THE Y ARRAY MAY BE USED
+C          FOR OTHER PURPOSES BETWEEN CALLS TO THE SOLVER.
+C
+C          THIS ARRAY IS PASSED AS THE Y ARGUMENT IN ALL CALLS TO
+C          F AND JAC.  HENCE ITS LENGTH MAY EXCEED NEQ, AND LOCATIONS 
+C          Y(NEQ+1),... MAY BE USED TO STORE OTHER REAL DATA AND
+C          PASS IT TO F AND/OR JAC.  (THE LSODE PACKAGE ACCESSES ONLY 
+C          Y(1),...,Y(NEQ).)
+C
+C T      = THE INDEPENDENT VARIABLE.  ON INPUT, T IS USED ONLY ON THE 
+C          FIRST CALL, AS THE INITIAL POINT OF THE INTEGRATION.
+C          ON OUTPUT, AFTER EACH CALL, T IS THE VALUE AT WHICH A
+C          COMPUTED SOLUTION Y IS EVALUATED (USUALLY THE SAME AS TOUT).
+C          ON AN ERROR RETURN, T IS THE FARTHEST POINT REACHED.
+C
+C TOUT   = THE NEXT VALUE OF T AT WHICH A COMPUTED SOLUTION IS DESIRED.
+C          USED ONLY FOR INPUT.
+C
+C          WHEN STARTING THE PROBLEM (ISTATE = 1), TOUT MAY BE EQUAL
+C          TO T FOR ONE CALL, THEN SHOULD .NE. T FOR THE NEXT CALL.
+C          FOR THE INITIAL T, AN INPUT VALUE OF TOUT .NE. T IS USED
+C          IN ORDER TO DETERMINE THE DIRECTION OF THE INTEGRATION
+C          (I.E. THE ALGEBRAIC SIGN OF THE STEP SIZES) AND THE ROUGH
+C          SCALE OF THE PROBLEM.  INTEGRATION IN EITHER DIRECTION
+C          (FORWARD OR BACKWARD IN T) IS PERMITTED.
+C
+C          IF ITASK = 2 OR 5 (ONE-STEP MODES), TOUT IS IGNORED AFTER
+C          THE FIRST CALL (I.E. THE FIRST CALL WITH TOUT .NE. T).
+C          OTHERWISE, TOUT IS REQUIRED ON EVERY CALL.
+C
+C          IF ITASK = 1, 3, OR 4, THE VALUES OF TOUT NEED NOT BE
+C          MONOTONE, BUT A VALUE OF TOUT WHICH BACKS UP IS LIMITED
+C          TO THE CURRENT INTERNAL T INTERVAL, WHOSE ENDPOINTS ARE
+C          TCUR - HU AND TCUR (SEE OPTIONAL OUTPUTS, BELOW, FOR
+C          TCUR AND HU).
+C
+C ITOL   = AN INDICATOR FOR THE TYPE OF ERROR CONTROL.  SEE 
+C          DESCRIPTION BELOW UNDER ATOL.  USED ONLY FOR INPUT.
+C
+C RTOL   = A RELATIVE ERROR TOLERANCE PARAMETER, EITHER A SCALAR OR
+C          AN ARRAY OF LENGTH NEQ.  SEE DESCRIPTION BELOW UNDER ATOL. 
+C          INPUT ONLY.
+C
+C ATOL   = AN ABSOLUTE ERROR TOLERANCE PARAMETER, EITHER A SCALAR OR
+C          AN ARRAY OF LENGTH NEQ.  INPUT ONLY.
+C
+C             THE INPUT PARAMETERS ITOL, RTOL, AND ATOL DETERMINE
+C          THE ERROR CONTROL PERFORMED BY THE SOLVER.  THE SOLVER WILL
+C          CONTROL THE VECTOR E = (E(I)) OF ESTIMATED LOCAL ERRORS
+C          IN Y, ACCORDING TO AN INEQUALITY OF THE FORM
+C                      RMS-NORM OF ( E(I)/EWT(I) )   .LE.   1,
+C          WHERE       EWT(I) = RTOL(I)*ABS(Y(I)) + ATOL(I),
+C          AND THE RMS-NORM (ROOT-MEAN-SQUARE NORM) HERE IS 
+C          RMS-NORM(V) = SQRT(SUM V(I)**2 / NEQ).  HERE EWT = (EWT(I))
+C          IS A VECTOR OF WEIGHTS WHICH MUST ALWAYS BE POSITIVE, AND
+C          THE VALUES OF RTOL AND ATOL SHOULD ALL BE NON-NEGATIVE.
+C          THE FOLLOWING TABLE GIVES THE TYPES (SCALAR/ARRAY) OF
+C          RTOL AND ATOL, AND THE CORRESPONDING FORM OF EWT(I).
+C
+C             ITOL    RTOL       ATOL          EWT(I)
+C              1     SCALAR     SCALAR     RTOL*ABS(Y(I)) + ATOL
+C              2     SCALAR     ARRAY      RTOL*ABS(Y(I)) + ATOL(I)
+C              3     ARRAY      SCALAR     RTOL(I)*ABS(Y(I)) + ATOL
+C              4     ARRAY      ARRAY      RTOL(I)*ABS(Y(I)) + ATOL(I)
+C
+C          WHEN EITHER OF THESE PARAMETERS IS A SCALAR, IT NEED NOT
+C          BE DIMENSIONED IN THE USER-S CALLING PROGRAM.
+C
+C          IF NONE OF THE ABOVE CHOICES (WITH ITOL, RTOL, AND ATOL
+C          FIXED THROUGHOUT THE PROBLEM) IS SUITABLE, MORE GENERAL
+C          ERROR CONTROLS CAN BE OBTAINED BY SUBSTITUTING
+C          USER-SUPPLIED ROUTINES FOR THE SETTING OF EWT AND/OR FOR
+C          THE NORM CALCULATION.  SEE PART IV BELOW.
+C
+C          IF GLOBAL ERRORS ARE TO BE ESTIMATED BY MAKING A REPEATED
+C          RUN ON THE SAME PROBLEM WITH SMALLER TOLERANCES, THEN ALL
+C          COMPONENTS OF RTOL AND ATOL (I.E. OF EWT) SHOULD BE SCALED 
+C          DOWN UNIFORMLY.
+C
+C ITASK  = AN INDEX SPECIFYING THE TASK TO BE PERFORMED.
+C          INPUT ONLY.  ITASK HAS THE FOLLOWING VALUES AND MEANINGS.
+C          1  MEANS NORMAL COMPUTATION OF OUTPUT VALUES OF Y(T) AT
+C             T = TOUT (BY OVERSHOOTING AND INTERPOLATING). 
+C          2  MEANS TAKE ONE STEP ONLY AND RETURN.
+C          3  MEANS STOP AT THE FIRST INTERNAL MESH POINT AT OR
+C             BEYOND T = TOUT AND RETURN.
+C          4  MEANS NORMAL COMPUTATION OF OUTPUT VALUES OF Y(T) AT
+C             T = TOUT BUT WITHOUT OVERSHOOTING T = TCRIT.
+C             TCRIT MUST BE INPUT AS RWORK(1).  TCRIT MAY BE EQUAL TO 
+C             OR BEYOND TOUT, BUT NOT BEHIND IT IN THE DIRECTION OF
+C             INTEGRATION.  THIS OPTION IS USEFUL IF THE PROBLEM
+C             HAS A SINGULARITY AT OR BEYOND T = TCRIT.
+C          5  MEANS TAKE ONE STEP, WITHOUT PASSING TCRIT, AND RETURN. 
+C             TCRIT MUST BE INPUT AS RWORK(1).
+C
+C          NOTE..  IF ITASK = 4 OR 5 AND THE SOLVER REACHES TCRIT
+C          (WITHIN ROUNDOFF), IT WILL RETURN T = TCRIT (EXACTLY) TO
+C          INDICATE THIS (UNLESS ITASK = 4 AND TOUT COMES BEFORE TCRIT,
+C          IN WHICH CASE ANSWERS AT T = TOUT ARE RETURNED FIRST).
+C
+C ISTATE = AN INDEX USED FOR INPUT AND OUTPUT TO SPECIFY THE
+C          THE STATE OF THE CALCULATION.
+C
+C          ON INPUT, THE VALUES OF ISTATE ARE AS FOLLOWS.
+C          1  MEANS THIS IS THE FIRST CALL FOR THE PROBLEM
+C             (INITIALIZATIONS WILL BE DONE).  SEE NOTE BELOW.
+C          2  MEANS THIS IS NOT THE FIRST CALL, AND THE CALCULATION
+C             IS TO CONTINUE NORMALLY, WITH NO CHANGE IN ANY INPUT
+C             PARAMETERS EXCEPT POSSIBLY TOUT AND ITASK.
+C             (IF ITOL, RTOL, AND/OR ATOL ARE CHANGED BETWEEN CALLS
+C             WITH ISTATE = 2, THE NEW VALUES WILL BE USED BUT NOT
+C             TESTED FOR LEGALITY.)
+C          3  MEANS THIS IS NOT THE FIRST CALL, AND THE
+C             CALCULATION IS TO CONTINUE NORMALLY, BUT WITH 
+C             A CHANGE IN INPUT PARAMETERS OTHER THAN
+C             TOUT AND ITASK.  CHANGES ARE ALLOWED IN
+C             NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF, ML, MU,
+C             AND ANY OF THE OPTIONAL INPUTS EXCEPT H0.
+C             (SEE IWORK DESCRIPTION FOR ML AND MU.)
+C          NOTE..  A PRELIMINARY CALL WITH TOUT = T IS NOT COUNTED
+C          AS A FIRST CALL HERE, AS NO INITIALIZATION OR CHECKING OF
+C          INPUT IS DONE.  (SUCH A CALL IS SOMETIMES USEFUL FOR THE
+C          PURPOSE OF OUTPUTTING THE INITIAL CONDITIONS.)
+C          THUS THE FIRST CALL FOR WHICH TOUT .NE. T REQUIRES
+C          ISTATE = 1 ON INPUT.
+C
+C          ON OUTPUT, ISTATE HAS THE FOLLOWING VALUES AND MEANINGS.
+C           1  MEANS NOTHING WAS DONE, AS TOUT WAS EQUAL TO T WITH
+C              ISTATE = 1 ON INPUT.  (HOWEVER, AN INTERNAL COUNTER WAS
+C              SET TO DETECT AND PREVENT REPEATED CALLS OF THIS TYPE.)
+C           2  MEANS THE INTEGRATION WAS PERFORMED SUCCESSFULLY.
+C          -1  MEANS AN EXCESSIVE AMOUNT OF WORK (MORE THAN MXSTEP
+C              STEPS) WAS DONE ON THIS CALL, BEFORE COMPLETING THE
+C              REQUESTED TASK, BUT THE INTEGRATION WAS OTHERWISE
+C              SUCCESSFUL AS FAR AS T.  (MXSTEP IS AN OPTIONAL INPUT
+C              AND IS NORMALLY 500.)  TO CONTINUE, THE USER MAY
+C              SIMPLY RESET ISTATE TO A VALUE .GT. 1 AND CALL AGAIN
+C              (THE EXCESS WORK STEP COUNTER WILL BE RESET TO 0).
+C              IN ADDITION, THE USER MAY INCREASE MXSTEP TO AVOID
+C              THIS ERROR RETURN (SEE BELOW ON OPTIONAL INPUTS).
+C          -2  MEANS TOO MUCH ACCURACY WAS REQUESTED FOR THE PRECISION
+C              OF THE MACHINE BEING USED.  THIS WAS DETECTED BEFORE
+C              COMPLETING THE REQUESTED TASK, BUT THE INTEGRATION
+C              WAS SUCCESSFUL AS FAR AS T.  TO CONTINUE, THE TOLERANCE
+C              PARAMETERS MUST BE RESET, AND ISTATE MUST BE SET
+C              TO 3.  THE OPTIONAL OUTPUT TOLSF MAY BE USED FOR THIS
+C              PURPOSE.  (NOTE.. IF THIS CONDITION IS DETECTED BEFORE 
+C              TAKING ANY STEPS, THEN AN ILLEGAL INPUT RETURN
+C              (ISTATE = -3) OCCURS INSTEAD.)
+C          -3  MEANS ILLEGAL INPUT WAS DETECTED, BEFORE TAKING ANY
+C              INTEGRATION STEPS.  SEE WRITTEN MESSAGE FOR DETAILS.
+C              NOTE..  IF THE SOLVER DETECTS AN INFINITE LOOP OF CALLS
+C              TO THE SOLVER WITH ILLEGAL INPUT, IT WILL CAUSE
+C              THE RUN TO STOP.
+C          -4  MEANS THERE WERE REPEATED ERROR TEST FAILURES ON
+C              ONE ATTEMPTED STEP, BEFORE COMPLETING THE REQUESTED
+C              TASK, BUT THE INTEGRATION WAS SUCCESSFUL AS FAR AS T.
+C              THE PROBLEM MAY HAVE A SINGULARITY, OR THE INPUT
+C              MAY BE INAPPROPRIATE.
+C          -5  MEANS THERE WERE REPEATED CONVERGENCE TEST FAILURES ON 
+C              ONE ATTEMPTED STEP, BEFORE COMPLETING THE REQUESTED
+C              TASK, BUT THE INTEGRATION WAS SUCCESSFUL AS FAR AS T.
+C              THIS MAY BE CAUSED BY AN INACCURATE JACOBIAN MATRIX,
+C              IF ONE IS BEING USED.
+C          -6  MEANS EWT(I) BECAME ZERO FOR SOME I DURING THE
+C              INTEGRATION.  PURE RELATIVE ERROR CONTROL (ATOL(I)=0.0)
+C              WAS REQUESTED ON A VARIABLE WHICH HAS NOW VANISHED.
+C              THE INTEGRATION WAS SUCCESSFUL AS FAR AS T.
+C
+C          NOTE..  SINCE THE NORMAL OUTPUT VALUE OF ISTATE IS 2,
+C          IT DOES NOT NEED TO BE RESET FOR NORMAL CONTINUATION.
+C          ALSO, SINCE A NEGATIVE INPUT VALUE OF ISTATE WILL BE
+C          REGARDED AS ILLEGAL, A NEGATIVE OUTPUT VALUE REQUIRES THE
+C          USER TO CHANGE IT, AND POSSIBLY OTHER INPUTS, BEFORE
+C          CALLING THE SOLVER AGAIN.
+C
+C IOPT   = AN INTEGER FLAG TO SPECIFY WHETHER OR NOT ANY OPTIONAL
+C          INPUTS ARE BEING USED ON THIS CALL.  INPUT ONLY. 
+C          THE OPTIONAL INPUTS ARE LISTED SEPARATELY BELOW. 
+C          IOPT = 0 MEANS NO OPTIONAL INPUTS ARE BEING USED.
+C                   DEFAULT VALUES WILL BE USED IN ALL CASES.
+C          IOPT = 1 MEANS ONE OR MORE OPTIONAL INPUTS ARE BEING USED. 
+C
+C RWORK  = A REAL WORKING ARRAY (DOUBLE PRECISION).
+C          THE LENGTH OF RWORK MUST BE AT LEAST
+C             20 + NYH*(MAXORD + 1) + 3*NEQ + LWM    WHERE
+C          NYH    = THE INITIAL VALUE OF NEQ,
+C          MAXORD = 12 (IF METH = 1) OR 5 (IF METH = 2) (UNLESS A
+C                   SMALLER VALUE IS GIVEN AS AN OPTIONAL INPUT),
+C          LWM   = 0             IF MITER = 0,
+C          LWM   = NEQ**2 + 2    IF MITER IS 1 OR 2,
+C          LWM   = NEQ + 2       IF MITER = 3, AND
+C          LWM   = (2*ML+MU+1)*NEQ + 2 IF MITER IS 4 OR 5.
+C          (SEE THE MF DESCRIPTION FOR METH AND MITER.)
+C          THUS IF MAXORD HAS ITS DEFAULT VALUE AND NEQ IS CONSTANT,
+C          THIS LENGTH IS..
+C             20 + 16*NEQ                  FOR MF = 10,
+C             22 + 16*NEQ + NEQ**2         FOR MF = 11 OR 12,
+C             22 + 17*NEQ                  FOR MF = 13,
+C             22 + 17*NEQ + (2*ML+MU)*NEQ  FOR MF = 14 OR 15,
+C             20 +  9*NEQ                  FOR MF = 20,
+C             22 +  9*NEQ + NEQ**2         FOR MF = 21 OR 22,
+C             22 + 10*NEQ                  FOR MF = 23,
+C             22 + 10*NEQ + (2*ML+MU)*NEQ  FOR MF = 24 OR 25.
+C          THE FIRST 20 WORDS OF RWORK ARE RESERVED FOR CONDITIONAL
+C          AND OPTIONAL INPUTS AND OPTIONAL OUTPUTS.
+C
+C          THE FOLLOWING WORD IN RWORK IS A CONDITIONAL INPUT..
+C            RWORK(1) = TCRIT = CRITICAL VALUE OF T WHICH THE SOLVER
+C                       IS NOT TO OVERSHOOT.  REQUIRED IF ITASK IS
+C                       4 OR 5, AND IGNORED OTHERWISE.  (SEE ITASK.)
+C
+C LRW    = THE LENGTH OF THE ARRAY RWORK, AS DECLARED BY THE USER.
+C          (THIS WILL BE CHECKED BY THE SOLVER.)
+C
+C IWORK  = AN INTEGER WORK ARRAY.  THE LENGTH OF IWORK MUST BE AT LEAST
+C             20        IF MITER = 0 OR 3 (MF = 10, 13, 20, 23), OR
+C             20 + NEQ  OTHERWISE (MF = 11, 12, 14, 15, 21, 22, 24, 25).
+C          THE FIRST FEW WORDS OF IWORK ARE USED FOR CONDITIONAL AND
+C          OPTIONAL INPUTS AND OPTIONAL OUTPUTS.
+C
+C          THE FOLLOWING 2 WORDS IN IWORK ARE CONDITIONAL INPUTS..
+C            IWORK(1) = ML     THESE ARE THE LOWER AND UPPER
+C            IWORK(2) = MU     HALF-BANDWIDTHS, RESPECTIVELY, OF THE
+C                       BANDED JACOBIAN, EXCLUDING THE MAIN DIAGONAL. 
+C                       THE BAND IS DEFINED BY THE MATRIX LOCATIONS
+C                       (I,J) WITH I-ML .LE. J .LE. I+MU.  ML AND MU
+C                       MUST SATISFY  0 .LE.  ML,MU  .LE. NEQ-1.
+C                       THESE ARE REQUIRED IF MITER IS 4 OR 5, AND
+C                       IGNORED OTHERWISE.  ML AND MU MAY IN FACT BE
+C                       THE BAND PARAMETERS FOR A MATRIX TO WHICH
+C                       DF/DY IS ONLY APPROXIMATELY EQUAL.
+C
+C LIW    = THE LENGTH OF THE ARRAY IWORK, AS DECLARED BY THE USER.
+C          (THIS WILL BE CHECKED BY THE SOLVER.)
+C
+C NOTE..  THE WORK ARRAYS MUST NOT BE ALTERED BETWEEN CALLS TO LSODE
+C FOR THE SAME PROBLEM, EXCEPT POSSIBLY FOR THE CONDITIONAL AND
+C OPTIONAL INPUTS, AND EXCEPT FOR THE LAST 3*NEQ WORDS OF RWORK.
+C THE LATTER SPACE IS USED FOR INTERNAL SCRATCH SPACE, AND SO IS
+C AVAILABLE FOR USE BY THE USER OUTSIDE LSODE BETWEEN CALLS, IF
+C DESIRED (BUT NOT FOR USE BY F OR JAC).
+C
+C JAC    = THE NAME OF THE USER-SUPPLIED ROUTINE (MITER = 1 OR 4) TO
+C          COMPUTE THE JACOBIAN MATRIX, DF/DY, AS A FUNCTION OF
+C          THE SCALAR T AND THE VECTOR Y.  IT IS TO HAVE THE FORM
+C               SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
+C               DIMENSION Y(1), PD(NROWPD,1)
+C          WHERE NEQ, T, Y, ML, MU, AND NROWPD ARE INPUT AND THE ARRAY
+C          PD IS TO BE LOADED WITH PARTIAL DERIVATIVES (ELEMENTS OF
+C          THE JACOBIAN MATRIX) ON OUTPUT.  PD MUST BE GIVEN A FIRST
+C          DIMENSION OF NROWPD.  T AND Y HAVE THE SAME MEANING AS IN
+C          SUBROUTINE F.  (IN THE DIMENSION STATEMENT ABOVE, 1 IS A
+C          DUMMY DIMENSION.. IT CAN BE REPLACED BY ANY VALUE.)
+C               IN THE FULL MATRIX CASE (MITER = 1), ML AND MU ARE
+C          IGNORED, AND THE JACOBIAN IS TO BE LOADED INTO PD IN
+C          COLUMNWISE MANNER, WITH DF(I)/DY(J) LOADED INTO PD(I,J).
+C               IN THE BAND MATRIX CASE (MITER = 4), THE ELEMENTS
+C          WITHIN THE BAND ARE TO BE LOADED INTO PD IN COLUMNWISE
+C          MANNER, WITH DIAGONAL LINES OF DF/DY LOADED INTO THE ROWS
+C          OF PD.  THUS DF(I)/DY(J) IS TO BE LOADED INTO PD(I-J+MU+1,J).
+C          ML AND MU ARE THE HALF-BANDWIDTH PARAMETERS (SEE IWORK).
+C          THE LOCATIONS IN PD IN THE TWO TRIANGULAR AREAS WHICH
+C          CORRESPOND TO NONEXISTENT MATRIX ELEMENTS CAN BE IGNORED
+C          OR LOADED ARBITRARILY, AS THEY ARE OVERWRITTEN BY LSODE.
+C               JAC NEED NOT PROVIDE DF/DY EXACTLY.  A CRUDE
+C          APPROXIMATION (POSSIBLY WITH A SMALLER BANDWIDTH) WILL DO. 
+C               IN EITHER CASE, PD IS PRESET TO ZERO BY THE SOLVER,
+C          SO THAT ONLY THE NONZERO ELEMENTS NEED BE LOADED BY JAC.
+C          EACH CALL TO JAC IS PRECEDED BY A CALL TO F WITH THE SAME
+C          ARGUMENTS NEQ, T, AND Y.  THUS TO GAIN SOME EFFICIENCY,
+C          INTERMEDIATE QUANTITIES SHARED BY BOTH CALCULATIONS MAY BE 
+C          SAVED IN A USER COMMON BLOCK BY F AND NOT RECOMPUTED BY JAC,
+C          IF DESIRED.  ALSO, JAC MAY ALTER THE Y ARRAY, IF DESIRED.
+C          JAC MUST BE DECLARED EXTERNAL IN THE CALLING PROGRAM.
+C               SUBROUTINE JAC MAY ACCESS USER-DEFINED QUANTITIES IN
+C          NEQ(2),... AND/OR IN Y(NEQ(1)+1),... IF NEQ IS AN ARRAY
+C          (DIMENSIONED IN JAC) AND/OR Y HAS LENGTH EXCEEDING NEQ(1). 
+C          SEE THE DESCRIPTIONS OF NEQ AND Y ABOVE.
+C
+C MF     = THE METHOD FLAG.  USED ONLY FOR INPUT.  THE LEGAL VALUES OF
+C          MF ARE 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, AND 25. 
+C          MF HAS DECIMAL DIGITS METH AND MITER.. MF = 10*METH + MITER.
+C          METH INDICATES THE BASIC LINEAR MULTISTEP METHOD..
+C            METH = 1 MEANS THE IMPLICIT ADAMS METHOD.
+C            METH = 2 MEANS THE METHOD BASED ON BACKWARD
+C                     DIFFERENTIATION FORMULAS (BDF-S).
+C          MITER INDICATES THE CORRECTOR ITERATION METHOD.. 
+C            MITER = 0 MEANS FUNCTIONAL ITERATION (NO JACOBIAN MATRIX 
+C                      IS INVOLVED).
+C            MITER = 1 MEANS CHORD ITERATION WITH A USER-SUPPLIED
+C                      FULL (NEQ BY NEQ) JACOBIAN.
+C            MITER = 2 MEANS CHORD ITERATION WITH AN INTERNALLY
+C                      GENERATED (DIFFERENCE QUOTIENT) FULL JACOBIAN
+C                      (USING NEQ EXTRA CALLS TO F PER DF/DY VALUE).
+C            MITER = 3 MEANS CHORD ITERATION WITH AN INTERNALLY
+C                      GENERATED DIAGONAL JACOBIAN APPROXIMATION.
+C                      (USING 1 EXTRA CALL TO F PER DF/DY EVALUATION).
+C            MITER = 4 MEANS CHORD ITERATION WITH A USER-SUPPLIED
+C                      BANDED JACOBIAN. 
+C            MITER = 5 MEANS CHORD ITERATION WITH AN INTERNALLY
+C                      GENERATED BANDED JACOBIAN (USING ML+MU+1 EXTRA 
+C                      CALLS TO F PER DF/DY EVALUATION).
+C          IF MITER = 1 OR 4, THE USER MUST SUPPLY A SUBROUTINE JAC
+C          (THE NAME IS ARBITRARY) AS DESCRIBED ABOVE UNDER JAC.
+C          FOR OTHER VALUES OF MITER, A DUMMY ARGUMENT CAN BE USED.
+C-----------------------------------------------------------------------
+C OPTIONAL INPUTS.
+C
+C THE FOLLOWING IS A LIST OF THE OPTIONAL INPUTS PROVIDED FOR IN THE
+C CALL SEQUENCE.  (SEE ALSO PART II.)  FOR EACH SUCH INPUT VARIABLE,
+C THIS TABLE LISTS ITS NAME AS USED IN THIS DOCUMENTATION, ITS
+C LOCATION IN THE CALL SEQUENCE, ITS MEANING, AND THE DEFAULT VALUE.
+C THE USE OF ANY OF THESE INPUTS REQUIRES IOPT = 1, AND IN THAT
+C CASE ALL OF THESE INPUTS ARE EXAMINED.  A VALUE OF ZERO FOR ANY
+C OF THESE OPTIONAL INPUTS WILL CAUSE THE DEFAULT VALUE TO BE USED.
+C THUS TO USE A SUBSET OF THE OPTIONAL INPUTS, SIMPLY PRELOAD
+C LOCATIONS 5 TO 10 IN RWORK AND IWORK TO 0.0 AND 0 RESPECTIVELY, AND 
+C THEN SET THOSE OF INTEREST TO NONZERO VALUES.
+C
+C NAME    LOCATION      MEANING AND DEFAULT VALUE 
+C
+C H0      RWORK(5)  THE STEP SIZE TO BE ATTEMPTED ON THE FIRST STEP.
+C                   THE DEFAULT VALUE IS DETERMINED BY THE SOLVER.
+C
+C HMAX    RWORK(6)  THE MAXIMUM ABSOLUTE STEP SIZE ALLOWED. 
+C                   THE DEFAULT VALUE IS INFINITE.
+C
+C HMIN    RWORK(7)  THE MINIMUM ABSOLUTE STEP SIZE ALLOWED. 
+C                   THE DEFAULT VALUE IS 0.  (THIS LOWER BOUND IS NOT 
+C                   ENFORCED ON THE FINAL STEP BEFORE REACHING TCRIT
+C                   WHEN ITASK = 4 OR 5.)
+C
+C MAXORD  IWORK(5)  THE MAXIMUM ORDER TO BE ALLOWED.  THE DEFAULT
+C                   VALUE IS 12 IF METH = 1, AND 5 IF METH = 2.
+C                   IF MAXORD EXCEEDS THE DEFAULT VALUE, IT WILL
+C                   BE REDUCED TO THE DEFAULT VALUE.
+C                   IF MAXORD IS CHANGED DURING THE PROBLEM, IT MAY
+C                   CAUSE THE CURRENT ORDER TO BE REDUCED.
+C
+C MXSTEP  IWORK(6)  MAXIMUM NUMBER OF (INTERNALLY DEFINED) STEPS
+C                   ALLOWED DURING ONE CALL TO THE SOLVER.
+C                   THE DEFAULT VALUE IS 500.
+C
+C MXHNIL  IWORK(7)  MAXIMUM NUMBER OF MESSAGES PRINTED (PER PROBLEM)
+C                   WARNING THAT T + H = T ON A STEP (H = STEP SIZE). 
+C                   THIS MUST BE POSITIVE TO RESULT IN A NON-DEFAULT
+C                   VALUE.  THE DEFAULT VALUE IS 10.
+C-----------------------------------------------------------------------
+C OPTIONAL OUTPUTS. 
+C
+C AS OPTIONAL ADDITIONAL OUTPUT FROM LSODE, THE VARIABLES LISTED
+C BELOW ARE QUANTITIES RELATED TO THE PERFORMANCE OF LSODE
+C WHICH ARE AVAILABLE TO THE USER.  THESE ARE COMMUNICATED BY WAY OF
+C THE WORK ARRAYS, BUT ALSO HAVE INTERNAL MNEMONIC NAMES AS SHOWN.
+C EXCEPT WHERE STATED OTHERWISE, ALL OF THESE OUTPUTS ARE DEFINED
+C ON ANY SUCCESSFUL RETURN FROM LSODE, AND ON ANY RETURN WITH
+C ISTATE = -1, -2, -4, -5, OR -6.  ON AN ILLEGAL INPUT RETURN
+C (ISTATE = -3), THEY WILL BE UNCHANGED FROM THEIR EXISTING VALUES
+C (IF ANY), EXCEPT POSSIBLY FOR TOLSF, LENRW, AND LENIW.
+C ON ANY ERROR RETURN, OUTPUTS RELEVANT TO THE ERROR WILL BE DEFINED, 
+C AS NOTED BELOW.
+C
+C NAME    LOCATION      MEANING
+C
+C HU      RWORK(11) THE STEP SIZE IN T LAST USED (SUCCESSFULLY).
+C
+C HCUR    RWORK(12) THE STEP SIZE TO BE ATTEMPTED ON THE NEXT STEP.
+C
+C TCUR    RWORK(13) THE CURRENT VALUE OF THE INDEPENDENT VARIABLE
+C                   WHICH THE SOLVER HAS ACTUALLY REACHED, I.E. THE
+C                   CURRENT INTERNAL MESH POINT IN T.  ON OUTPUT, TCUR
+C                   WILL ALWAYS BE AT LEAST AS FAR AS THE ARGUMENT
+C                   T, BUT MAY BE FARTHER (IF INTERPOLATION WAS DONE).
+C
+C TOLSF   RWORK(14) A TOLERANCE SCALE FACTOR, GREATER THAN 1.0,
+C                   COMPUTED WHEN A REQUEST FOR TOO MUCH ACCURACY WAS 
+C                   DETECTED (ISTATE = -3 IF DETECTED AT THE START OF 
+C                   THE PROBLEM, ISTATE = -2 OTHERWISE).  IF ITOL IS
+C                   LEFT UNALTERED BUT RTOL AND ATOL ARE UNIFORMLY
+C                   SCALED UP BY A FACTOR OF TOLSF FOR THE NEXT CALL, 
+C                   THEN THE SOLVER IS DEEMED LIKELY TO SUCCEED.
+C                   (THE USER MAY ALSO IGNORE TOLSF AND ALTER THE
+C                   TOLERANCE PARAMETERS IN ANY OTHER WAY APPROPRIATE.)
+C
+C NST     IWORK(11) THE NUMBER OF STEPS TAKEN FOR THE PROBLEM SO FAR. 
+C
+C NFE     IWORK(12) THE NUMBER OF F EVALUATIONS FOR THE PROBLEM SO FAR.
+C
+C NJE     IWORK(13) THE NUMBER OF JACOBIAN EVALUATIONS (AND OF MATRIX 
+C                   LU DECOMPOSITIONS) FOR THE PROBLEM SO FAR.
+C
+C NQU     IWORK(14) THE METHOD ORDER LAST USED (SUCCESSFULLY).
+C
+C NQCUR   IWORK(15) THE ORDER TO BE ATTEMPTED ON THE NEXT STEP.
+C
+C IMXER   IWORK(16) THE INDEX OF THE COMPONENT OF LARGEST MAGNITUDE IN
+C                   THE WEIGHTED LOCAL ERROR VECTOR ( E(I)/EWT(I) ),
+C                   ON AN ERROR RETURN WITH ISTATE = -4 OR -5.
+C
+C LENRW   IWORK(17) THE LENGTH OF RWORK ACTUALLY REQUIRED.
+C                   THIS IS DEFINED ON NORMAL RETURNS AND ON AN ILLEGAL
+C                   INPUT RETURN FOR INSUFFICIENT STORAGE.
+C
+C LENIW   IWORK(18) THE LENGTH OF IWORK ACTUALLY REQUIRED.
+C                   THIS IS DEFINED ON NORMAL RETURNS AND ON AN ILLEGAL
+C                   INPUT RETURN FOR INSUFFICIENT STORAGE.
+C
+C THE FOLLOWING TWO ARRAYS ARE SEGMENTS OF THE RWORK ARRAY WHICH
+C MAY ALSO BE OF INTEREST TO THE USER AS OPTIONAL OUTPUTS.
+C FOR EACH ARRAY, THE TABLE BELOW GIVES ITS INTERNAL NAME,
+C ITS BASE ADDRESS IN RWORK, AND ITS DESCRIPTION. 
+C
+C NAME    BASE ADDRESS      DESCRIPTION 
+C
+C YH      21             THE NORDSIECK HISTORY ARRAY, OF SIZE NYH BY
+C                        (NQCUR + 1), WHERE NYH IS THE INITIAL VALUE
+C                        OF NEQ.  FOR J = 0,1,...,NQCUR, COLUMN J+1
+C                        OF YH CONTAINS HCUR**J/FACTORIAL(J) TIMES
+C                        THE J-TH DERIVATIVE OF THE INTERPOLATING
+C                        POLYNOMIAL CURRENTLY REPRESENTING THE SOLUTION,
+C                        EVALUATED AT T = TCUR.
+C
+C ACOR     LENRW-NEQ+1   ARRAY OF SIZE NEQ USED FOR THE ACCUMULATED
+C                        CORRECTIONS ON EACH STEP, SCALED ON OUTPUT
+C                        TO REPRESENT THE ESTIMATED LOCAL ERROR IN Y
+C                        ON THE LAST STEP.  THIS IS THE VECTOR E IN
+C                        THE DESCRIPTION OF THE ERROR CONTROL.  IT IS 
+C                        DEFINED ONLY ON A SUCCESSFUL RETURN FROM LSODE.
+C
+C-----------------------------------------------------------------------
+C PART II.  OTHER ROUTINES CALLABLE.
+C
+C THE FOLLOWING ARE OPTIONAL CALLS WHICH THE USER MAY MAKE TO
+C GAIN ADDITIONAL CAPABILITIES IN CONJUNCTION WITH LSODE.
+C (THE ROUTINES XSETUN AND XSETF ARE DESIGNED TO CONFORM TO THE
+C SLATEC ERROR HANDLING PACKAGE.)
+C
+C     FORM OF CALL                  FUNCTION
+C   CALL XSETUN(LUN)          SET THE LOGICAL UNIT NUMBER, LUN, FOR
+C                             OUTPUT OF MESSAGES FROM LSODE, IF
+C                             THE DEFAULT IS NOT DESIRED.
+C                             THE DEFAULT VALUE OF LUN IS 6.
+C
+C   CALL XSETF(MFLAG)         SET A FLAG TO CONTROL THE PRINTING OF
+C                             MESSAGES BY LSODE.
+C                             MFLAG = 0 MEANS DO NOT PRINT. (DANGER.. 
+C                             THIS RISKS LOSING VALUABLE INFORMATION.)
+C                             MFLAG = 1 MEANS PRINT (THE DEFAULT).
+C
+C                             EITHER OF THE ABOVE CALLS MAY BE MADE AT
+C                             ANY TIME AND WILL TAKE EFFECT IMMEDIATELY.
+C
+C   CALL SRCOM(RSAV,ISAV,JOB) SAVES AND RESTORES THE CONTENTS OF
+C                             THE INTERNAL COMMON BLOCKS USED BY
+C                             LSODE (SEE PART III BELOW).
+C                             RSAV MUST BE A REAL ARRAY OF LENGTH 218 
+C                             OR MORE, AND ISAV MUST BE AN INTEGER
+C                             ARRAY OF LENGTH 41 OR MORE.
+C                             JOB=1 MEANS SAVE COMMON INTO RSAV/ISAV. 
+C                             JOB=2 MEANS RESTORE COMMON FROM RSAV/ISAV.
+C                                SRCOM IS USEFUL IF ONE IS
+C                             INTERRUPTING A RUN AND RESTARTING
+C                             LATER, OR ALTERNATING BETWEEN TWO OR
+C                             MORE PROBLEMS SOLVED WITH LSODE.
+C
+C   CALL INTDY(,,,,,)         PROVIDE DERIVATIVES OF Y, OF VARIOUS
+C        (SEE BELOW)          ORDERS, AT A SPECIFIED POINT T, IF
+C                             DESIRED.  IT MAY BE CALLED ONLY AFTER
+C                             A SUCCESSFUL RETURN FROM LSODE.
+C
+C THE DETAILED INSTRUCTIONS FOR USING INTDY ARE AS FOLLOWS. 
+C THE FORM OF THE CALL IS..
+C
+C   CALL INTDY (T, K, RWORK(21), NYH, DKY, IFLAG) 
+C
+C THE INPUT PARAMETERS ARE..
+C
+C T         = VALUE OF INDEPENDENT VARIABLE WHERE ANSWERS ARE DESIRED 
+C             (NORMALLY THE SAME AS THE T LAST RETURNED BY LSODE).
+C             FOR VALID RESULTS, T MUST LIE BETWEEN TCUR - HU AND TCUR.
+C             (SEE OPTIONAL OUTPUTS FOR TCUR AND HU.)
+C K         = INTEGER ORDER OF THE DERIVATIVE DESIRED.  K MUST SATISFY
+C             0 .LE. K .LE. NQCUR, WHERE NQCUR IS THE CURRENT ORDER
+C             (SEE OPTIONAL OUTPUTS).  THE CAPABILITY CORRESPONDING
+C             TO K = 0, I.E. COMPUTING Y(T), IS ALREADY PROVIDED
+C             BY LSODE DIRECTLY.  SINCE NQCUR .GE. 1, THE FIRST
+C             DERIVATIVE DY/DT IS ALWAYS AVAILABLE WITH INTDY.
+C RWORK(21) = THE BASE ADDRESS OF THE HISTORY ARRAY YH.
+C NYH       = COLUMN LENGTH OF YH, EQUAL TO THE INITIAL VALUE OF NEQ. 
+C
+C THE OUTPUT PARAMETERS ARE.. 
+C
+C DKY       = A REAL ARRAY OF LENGTH NEQ CONTAINING THE COMPUTED VALUE
+C             OF THE K-TH DERIVATIVE OF Y(T).
+C IFLAG     = INTEGER FLAG, RETURNED AS 0 IF K AND T WERE LEGAL,
+C             -1 IF K WAS ILLEGAL, AND -2 IF T WAS ILLEGAL. 
+C             ON AN ERROR RETURN, A MESSAGE IS ALSO WRITTEN.
+C-----------------------------------------------------------------------
+C PART III.  COMMON BLOCKS.
+C
+C IF LSODE IS TO BE USED IN AN OVERLAY SITUATION, THE USER
+C MUST DECLARE, IN THE PRIMARY OVERLAY, THE VARIABLES IN..
+C   (1) THE CALL SEQUENCE TO LSODE,
+C   (2) THE INTERNAL COMMON BLOCK
+C         /LS0001/  OF LENGTH  257  (218 DOUBLE PRECISION WORDS
+C                         FOLLOWED BY 39 INTEGER WORDS),
+C
+C IF LSODE IS USED ON A SYSTEM IN WHICH THE CONTENTS OF INTERNAL
+C COMMON BLOCKS ARE NOT PRESERVED BETWEEN CALLS, THE USER SHOULD
+C DECLARE THE ABOVE TWO COMMON BLOCKS IN HIS MAIN PROGRAM TO INSURE
+C THAT THEIR CONTENTS ARE PRESERVED.
+C
+C IF THE SOLUTION OF A GIVEN PROBLEM BY LSODE IS TO BE INTERRUPTED
+C AND THEN LATER CONTINUED, SUCH AS WHEN RESTARTING AN INTERRUPTED RUN
+C OR ALTERNATING BETWEEN TWO OR MORE PROBLEMS, THE USER SHOULD SAVE,
+C FOLLOWING THE RETURN FROM THE LAST LSODE CALL PRIOR TO THE
+C INTERRUPTION, THE CONTENTS OF THE CALL SEQUENCE VARIABLES AND THE
+C INTERNAL COMMON BLOCKS, AND LATER RESTORE THESE VALUES BEFORE THE
+C NEXT LSODE CALL FOR THAT PROBLEM.  TO SAVE AND RESTORE THE COMMON
+C BLOCKS, USE SUBROUTINE SRCOM (SEE PART II ABOVE).
+C
+C-----------------------------------------------------------------------
+C PART IV.  OPTIONALLY REPLACEABLE SOLVER ROUTINES.
+C
+C BELOW ARE DESCRIPTIONS OF TWO ROUTINES IN THE LSODE PACKAGE WHICH
+C RELATE TO THE MEASUREMENT OF ERRORS.  EITHER ROUTINE CAN BE
+C REPLACED BY A USER-SUPPLIED VERSION, IF DESIRED.  HOWEVER, SINCE SUCH
+C A REPLACEMENT MAY HAVE A MAJOR IMPACT ON PERFORMANCE, IT SHOULD BE
+C DONE ONLY WHEN ABSOLUTELY NECESSARY, AND ONLY WITH GREAT CAUTION.
+C (NOTE.. THE MEANS BY WHICH THE PACKAGE VERSION OF A ROUTINE IS
+C SUPERSEDED BY THE USER-S VERSION MAY BE SYSTEM-DEPENDENT.)
+C
+C (A) EWSET.
+C THE FOLLOWING SUBROUTINE IS CALLED JUST BEFORE EACH INTERNAL
+C INTEGRATION STEP, AND SETS THE ARRAY OF ERROR WEIGHTS, EWT, AS
+C DESCRIBED UNDER ITOL/RTOL/ATOL ABOVE..
+C     SUBROUTINE EWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
+C WHERE NEQ, ITOL, RTOL, AND ATOL ARE AS IN THE LSODE CALL SEQUENCE,
+C YCUR CONTAINS THE CURRENT DEPENDENT VARIABLE VECTOR, AND
+C EWT IS THE ARRAY OF WEIGHTS SET BY EWSET.
+C
+C IF THE USER SUPPLIES THIS SUBROUTINE, IT MUST RETURN IN EWT(I)
+C (I = 1,...,NEQ) A POSITIVE QUANTITY SUITABLE FOR COMPARING ERRORS
+C IN Y(I) TO.  THE EWT ARRAY RETURNED BY EWSET IS PASSED TO THE
+C VNORM ROUTINE (SEE BELOW), AND ALSO USED BY LSODE IN THE COMPUTATION
+C OF THE OPTIONAL OUTPUT IMXER, THE DIAGONAL JACOBIAN APPROXIMATION,
+C AND THE INCREMENTS FOR DIFFERENCE QUOTIENT JACOBIANS.
+C
+C IN THE USER-SUPPLIED VERSION OF EWSET, IT MAY BE DESIRABLE TO USE
+C THE CURRENT VALUES OF DERIVATIVES OF Y.  DERIVATIVES UP TO ORDER NQ 
+C ARE AVAILABLE FROM THE HISTORY ARRAY YH, DESCRIBED ABOVE UNDER
+C OPTIONAL OUTPUTS.  IN EWSET, YH IS IDENTICAL TO THE YCUR ARRAY,
+C EXTENDED TO NQ + 1 COLUMNS WITH A COLUMN LENGTH OF NYH AND SCALE
+C FACTORS OF H**J/FACTORIAL(J).  ON THE FIRST CALL FOR THE PROBLEM,
+C GIVEN BY NST = 0, NQ IS 1 AND H IS TEMPORARILY SET TO 1.0.
+C THE QUANTITIES NQ, NYH, H, AND NST CAN BE OBTAINED BY INCLUDING
+C IN EWSET THE STATEMENTS..
+C     DOUBLE PRECISION H, RLS 
+C     COMMON /LS0001/ RLS(218),ILS(39)
+C     NQ = ILS(35)
+C     NYH = ILS(14) 
+C     NST = ILS(36) 
+C     H = RLS(212)
+C THUS, FOR EXAMPLE, THE CURRENT VALUE OF DY/DT CAN BE OBTAINED AS
+C YCUR(NYH+I)/H  (I=1,...,NEQ)  (AND THE DIVISION BY H IS
+C UNNECESSARY WHEN NST = 0).
+C
+C (B) VNORM.
+C THE FOLLOWING IS A REAL FUNCTION ROUTINE WHICH COMPUTES THE WEIGHTED
+C ROOT-MEAN-SQUARE NORM OF A VECTOR V.. 
+C     D = VNORM (N, V, W)
+C WHERE.. 
+C   N = THE LENGTH OF THE VECTOR,
+C   V = REAL ARRAY OF LENGTH N CONTAINING THE VECTOR,
+C   W = REAL ARRAY OF LENGTH N CONTAINING WEIGHTS,
+C   D = SQRT( (1/N) * SUM(V(I)*W(I))**2 ).
+C VNORM IS CALLED WITH N = NEQ AND WITH W(I) = 1.0/EWT(I), WHERE
+C EWT IS AS SET BY SUBROUTINE EWSET.
+C
+C IF THE USER SUPPLIES THIS FUNCTION, IT SHOULD RETURN A NON-NEGATIVE 
+C VALUE OF VNORM SUITABLE FOR USE IN THE ERROR CONTROL IN LSODE.
+C NONE OF THE ARGUMENTS SHOULD BE ALTERED BY VNORM.
+C FOR EXAMPLE, A USER-SUPPLIED VNORM ROUTINE MIGHT..
+C   -SUBSTITUTE A MAX-NORM OF (V(I)*W(I)) FOR THE RMS-NORM, OR
+C   -IGNORE SOME COMPONENTS OF V IN THE NORM, WITH THE EFFECT OF
+C    SUPPRESSING THE ERROR CONTROL ON THOSE COMPONENTS OF Y.
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C OTHER ROUTINES IN THE LSODE PACKAGE.
+C
+C IN ADDITION TO SUBROUTINE LSODE, THE LSODE PACKAGE INCLUDES THE
+C FOLLOWING SUBROUTINES AND FUNCTION ROUTINES..
+C  INTDY    COMPUTES AN INTERPOLATED VALUE OF THE Y VECTOR AT T = TOUT.
+C  STODE    IS THE CORE INTEGRATOR, WHICH DOES ONE STEP OF THE
+C           INTEGRATION AND THE ASSOCIATED ERROR CONTROL.
+C  CFODE    SETS ALL METHOD COEFFICIENTS AND TEST CONSTANTS.
+C  PREPJ    COMPUTES AND PREPROCESSES THE JACOBIAN MATRIX J = DF/DY
+C           AND THE NEWTON ITERATION MATRIX P = I - H*L0*J. 
+C  SOLSY    MANAGES SOLUTION OF LINEAR SYSTEM IN CHORD ITERATION.
+C  EWSET    SETS THE ERROR WEIGHT VECTOR EWT BEFORE EACH STEP.
+C  VNORM    COMPUTES THE WEIGHTED R.M.S. NORM OF A VECTOR.
+C  SRCOM    IS A USER-CALLABLE ROUTINE TO SAVE AND RESTORE
+C           THE CONTENTS OF THE INTERNAL COMMON BLOCKS.
+C  DGETRF AND DGETRS   ARE ROUTINES FROM LAPACK FOR SOLVING FULL
+C           SYSTEMS OF LINEAR ALGEBRAIC EQUATIONS.
+C  DGBTRF AND DGBTRS   ARE ROUTINES FROM LAPACK FOR SOLVING BANDED
+C           LINEAR SYSTEMS.
+C  DAXPY, DSCAL, IDAMAX, AND DDOT   ARE BASIC LINEAR ALGEBRA MODULES
+C           (BLAS) USED BY THE ABOVE LINPACK ROUTINES.
+C  D1MACH   COMPUTES THE UNIT ROUNDOFF IN A MACHINE-INDEPENDENT MANNER.
+C  XERRWD, XSETUN, AND XSETF   HANDLE THE PRINTING OF ALL ERROR
+C           MESSAGES AND WARNINGS.  XERRWD IS MACHINE-DEPENDENT.
+C NOTE..  VNORM, IDAMAX, DDOT, AND D1MACH ARE FUNCTION ROUTINES.
+C ALL THE OTHERS ARE SUBROUTINES.
+C
+C THE INTRINSIC AND EXTERNAL ROUTINES USED BY LSODE ARE..
+C DABS, DMAX1, DMIN1, DBLE, MAX0, MIN0, MOD, DSIGN, DSQRT, AND WRITE. 
+C
+C A BLOCK DATA SUBPROGRAM IS ALSO INCLUDED WITH THE PACKAGE,
+C FOR LOADING SOME OF THE VARIABLES IN INTERNAL COMMON.
+C
+C-----------------------------------------------------------------------
+C THE FOLLOWING CARD IS FOR OPTIMIZED COMPILATION ON LLNL COMPILERS.
+CLLL. OPTIMIZE
+C-----------------------------------------------------------------------
+      EXTERNAL PREPJ, SOLSY
+      INTEGER ILLIN, INIT, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
+     1   MXSTEP, MXHNIL, NHNIL, NTREP, NSLAST, NYH, IOWNS
+      INTEGER ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER, 
+     1   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, I1, I2, IFLAG, IMXER, KGO, LF0,
+     1   LENIW, LENRW, LENWM, ML, MORD, MU, MXHNL0, MXSTP0
+      DOUBLE PRECISION ROWNS, 
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      DOUBLE PRECISION ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI,
+     1   TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0,
+     2   D1MACH, VNORM
+      DIMENSION MORD(2)
+      LOGICAL IHIT
+C-----------------------------------------------------------------------
+C THE FOLLOWING INTERNAL COMMON BLOCK CONTAINS
+C (A) VARIABLES WHICH ARE LOCAL TO ANY SUBROUTINE BUT WHOSE VALUES MUST
+C     BE PRESERVED BETWEEN CALLS TO THE ROUTINE (OWN VARIABLES), AND
+C (B) VARIABLES WHICH ARE COMMUNICATED BETWEEN SUBROUTINES. 
+C THE STRUCTURE OF THE BLOCK IS AS FOLLOWS..  ALL REAL VARIABLES ARE
+C LISTED FIRST, FOLLOWED BY ALL INTEGERS.  WITHIN EACH TYPE, THE
+C VARIABLES ARE GROUPED WITH THOSE LOCAL TO SUBROUTINE LSODE FIRST,
+C THEN THOSE LOCAL TO SUBROUTINE STODE, AND FINALLY THOSE USED
+C FOR COMMUNICATION.  THE BLOCK IS DECLARED IN SUBROUTINES
+C LSODE, INTDY, STODE, PREPJ, AND SOLSY.  GROUPS OF VARIABLES ARE
+C REPLACED BY DUMMY ARRAYS IN THE COMMON DECLARATIONS IN ROUTINES
+C WHERE THOSE VARIABLES ARE NOT USED.
+C-----------------------------------------------------------------------
+      COMMON /LS0001/ ROWNS(209),
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     2   ILLIN, INIT, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
+     3   MXSTEP, MXHNIL, NHNIL, NTREP, NSLAST, NYH, IOWNS(6),
+     4   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C
+      DATA  MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
+C-----------------------------------------------------------------------
+C BLOCK A.
+C THIS CODE BLOCK IS EXECUTED ON EVERY CALL.
+C IT TESTS ISTATE AND ITASK FOR LEGALITY AND BRANCHES APPROPRIATELY.
+C IF ISTATE .GT. 1 BUT THE FLAG INIT SHOWS THAT INITIALIZATION HAS
+C NOT YET BEEN DONE, AN ERROR RETURN OCCURS.
+C IF ISTATE = 1 AND TOUT = T, JUMP TO BLOCK G AND RETURN IMMEDIATELY. 
+C-----------------------------------------------------------------------
+      IF (ISTATE .LT. 1 .OR. ISTATE .GT. 3) GO TO 601
+      IF (ITASK .LT. 1 .OR. ITASK .GT. 5) GO TO 602
+      IF (ISTATE .EQ. 1) GO TO 10
+      IF (INIT .EQ. 0) GO TO 603
+      IF (ISTATE .EQ. 2) GO TO 200
+      GO TO 20
+ 10   INIT = 0
+      IF (TOUT .EQ. T) GO TO 430
+ 20   NTREP = 0
+C-----------------------------------------------------------------------
+C BLOCK B.
+C THE NEXT CODE BLOCK IS EXECUTED FOR THE INITIAL CALL (ISTATE = 1),
+C OR FOR A CONTINUATION CALL WITH PARAMETER CHANGES (ISTATE = 3).
+C IT CONTAINS CHECKING OF ALL INPUTS AND VARIOUS INITIALIZATIONS.
+C
+C FIRST CHECK LEGALITY OF THE NON-OPTIONAL INPUTS NEQ, ITOL, IOPT,
+C MF, ML, AND MU.
+C-----------------------------------------------------------------------
+      IF (NEQ(1) .LE. 0) GO TO 604
+      IF (ISTATE .EQ. 1) GO TO 25
+      IF (NEQ(1) .GT. N) GO TO 605
+ 25   N = NEQ(1)
+      IF (ITOL .LT. 1 .OR. ITOL .GT. 4) GO TO 606 
+      IF (IOPT .LT. 0 .OR. IOPT .GT. 1) GO TO 607 
+      METH = MF/10
+      MITER = MF - 10*METH
+      IF (METH .LT. 1 .OR. METH .GT. 2) GO TO 608 
+      IF (MITER .LT. 0 .OR. MITER .GT. 5) GO TO 608
+      IF (MITER .LE. 3) GO TO 30
+      ML = IWORK(1) 
+      MU = IWORK(2) 
+      IF (ML .LT. 0 .OR. ML .GE. N) GO TO 609
+      IF (MU .LT. 0 .OR. MU .GE. N) GO TO 610
+ 30   CONTINUE
+C NEXT PROCESS AND CHECK THE OPTIONAL INPUTS. --------------------------
+      IF (IOPT .EQ. 1) GO TO 40
+      MAXORD = MORD(METH)
+      MXSTEP = MXSTP0
+      MXHNIL = MXHNL0
+      IF (ISTATE .EQ. 1) H0 = 0.0D0
+      HMXI = 0.0D0
+      HMIN = 0.0D0
+      GO TO 60
+ 40   MAXORD = IWORK(5)
+      IF (MAXORD .LT. 0) GO TO 611
+      IF (MAXORD .EQ. 0) MAXORD = 100
+      MAXORD = MIN0(MAXORD,MORD(METH))
+      MXSTEP = IWORK(6)
+      IF (MXSTEP .LT. 0) GO TO 612
+      IF (MXSTEP .EQ. 0) MXSTEP = MXSTP0
+      MXHNIL = IWORK(7)
+      IF (MXHNIL .LT. 0) GO TO 613
+      IF (MXHNIL .EQ. 0) MXHNIL = MXHNL0
+      IF (ISTATE .NE. 1) GO TO 50
+      H0 = RWORK(5) 
+      IF ((TOUT - T)*H0 .LT. 0.0D0) GO TO 614
+ 50   HMAX = RWORK(6)
+      IF (HMAX .LT. 0.0D0) GO TO 615
+      HMXI = 0.0D0
+      IF (HMAX .GT. 0.0D0) HMXI = 1.0D0/HMAX
+      HMIN = RWORK(7)
+      IF (HMIN .LT. 0.0D0) GO TO 616
+C-----------------------------------------------------------------------
+C SET WORK ARRAY POINTERS AND CHECK LENGTHS LRW AND LIW.
+C POINTERS TO SEGMENTS OF RWORK AND IWORK ARE NAMED BY PREFIXING L TO 
+C THE NAME OF THE SEGMENT.  E.G., THE SEGMENT YH STARTS AT RWORK(LYH).
+C SEGMENTS OF RWORK (IN ORDER) ARE DENOTED  YH, WM, EWT, SAVF, ACOR.
+C-----------------------------------------------------------------------
+ 60   LYH = 21
+      IF (ISTATE .EQ. 1) NYH = N
+      LWM = LYH + (MAXORD + 1)*NYH
+      IF (MITER .EQ. 0) LENWM = 0
+      IF (MITER .EQ. 1 .OR. MITER .EQ. 2) LENWM = N*N + 2
+      IF (MITER .EQ. 3) LENWM = N + 2
+      IF (MITER .GE. 4) LENWM = (2*ML + MU + 1)*N + 2
+      LEWT = LWM + LENWM
+      LSAVF = LEWT + N
+      LACOR = LSAVF + N
+      LENRW = LACOR + N - 1
+      IWORK(17) = LENRW
+      LIWM = 1
+      LENIW = 20 + N
+      IF (MITER .EQ. 0 .OR. MITER .EQ. 3) LENIW = 20
+      IWORK(18) = LENIW
+      IF (LENRW .GT. LRW) GO TO 617
+      IF (LENIW .GT. LIW) GO TO 618
+C CHECK RTOL AND ATOL FOR LEGALITY. ------------------------------------
+      RTOLI = RTOL(1)
+      ATOLI = ATOL(1)
+      DO 70 I = 1,N 
+        IF (ITOL .GE. 3) RTOLI = RTOL(I)
+        IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I)
+        IF (RTOLI .LT. 0.0D0) GO TO 619 
+        IF (ATOLI .LT. 0.0D0) GO TO 620 
+ 70     CONTINUE
+      IF (ISTATE .EQ. 1) GO TO 100
+C IF ISTATE = 3, SET FLAG TO SIGNAL PARAMETER CHANGES TO STODE. --------
+      JSTART = -1
+      IF (NQ .LE. MAXORD) GO TO 90
+C MAXORD WAS REDUCED BELOW NQ.  COPY YH(*,MAXORD+2) INTO SAVF. ---------
+      DO 80 I = 1,N 
+ 80     RWORK(I+LSAVF-1) = RWORK(I+LWM-1)
+C RELOAD WM(1) = RWORK(LWM), SINCE LWM MAY HAVE CHANGED. ---------------
+ 90   IF (MITER .GT. 0) RWORK(LWM) = DSQRT(UROUND)
+      IF (N .EQ. NYH) GO TO 200
+C NEQ WAS REDUCED.  ZERO PART OF YH TO AVOID UNDEFINED REFERENCES. -----
+      I1 = LYH + L*NYH
+      I2 = LYH + (MAXORD + 1)*NYH - 1
+      IF (I1 .GT. I2) GO TO 200
+      DO 95 I = I1,I2
+ 95     RWORK(I) = 0.0D0
+      GO TO 200
+C-----------------------------------------------------------------------
+C BLOCK C.
+C THE NEXT BLOCK IS FOR THE INITIAL CALL ONLY (ISTATE = 1). 
+C IT CONTAINS ALL REMAINING INITIALIZATIONS, THE INITIAL CALL TO F,
+C AND THE CALCULATION OF THE INITIAL STEP SIZE.
+C THE ERROR WEIGHTS IN EWT ARE INVERTED AFTER BEING LOADED. 
+C-----------------------------------------------------------------------
+ 100  UROUND = D1MACH(4)
+      TN = T
+      IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 110
+      TCRIT = RWORK(1)
+      IF ((TCRIT - TOUT)*(TOUT - T) .LT. 0.0D0) GO TO 625
+      IF (H0 .NE. 0.0D0 .AND. (T + H0 - TCRIT)*H0 .GT. 0.0D0)
+     1   H0 = TCRIT - T
+ 110  JSTART = 0
+      IF (MITER .GT. 0) RWORK(LWM) = DSQRT(UROUND)
+      NHNIL = 0
+      NST = 0
+      NJE = 0
+      NSLAST = 0
+      HU = 0.0D0
+      NQU = 0
+      CCMAX = 0.3D0 
+      MAXCOR = 3
+      MSBP = 20
+      MXNCF = 10
+C INITIAL CALL TO F.  (LF0 POINTS TO YH(*,2).) -------------------------
+      LF0 = LYH + NYH
+      IERR = 0
+      CALL F (NEQ, T, Y, RWORK(LF0), IERR)
+      IF (IERR .LT. 0) THEN
+        ISTATE = -13
+        RETURN
+      ENDIF
+      NFE = 1
+C LOAD THE INITIAL VALUE VECTOR IN YH. ---------------------------------
+      DO 115 I = 1,N
+ 115    RWORK(I+LYH-1) = Y(I) 
+C LOAD AND INVERT THE EWT ARRAY.  (H IS TEMPORARILY SET TO 1.0.) -------
+      NQ = 1
+      H = 1.0D0
+      CALL EWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
+      DO 120 I = 1,N
+        IF (RWORK(I+LEWT-1) .LE. 0.0D0) GO TO 621 
+ 120    RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
+C-----------------------------------------------------------------------
+C THE CODING BELOW COMPUTES THE STEP SIZE, H0, TO BE ATTEMPTED ON THE 
+C FIRST STEP, UNLESS THE USER HAS SUPPLIED A VALUE FOR THIS.
+C FIRST CHECK THAT TOUT - T DIFFERS SIGNIFICANTLY FROM ZERO.
+C A SCALAR TOLERANCE QUANTITY TOL IS COMPUTED, AS MAX(RTOL(I))
+C IF THIS IS POSITIVE, OR MAX(ATOL(I)/ABS(Y(I))) OTHERWISE, ADJUSTED
+C SO AS TO BE BETWEEN 100*UROUND AND 1.0E-3.
+C THEN THE COMPUTED VALUE H0 IS GIVEN BY..
+C                                      NEQ
+C   H0**2 = TOL / ( W0**-2 + (1/NEQ) * SUM ( F(I)/YWT(I) )**2  )
+C                                       1
+C WHERE   W0     = MAX ( ABS(T), ABS(TOUT) ),
+C         F(I)   = I-TH COMPONENT OF INITIAL VALUE OF F,
+C         YWT(I) = EWT(I)/TOL  (A WEIGHT FOR Y(I)).
+C THE SIGN OF H0 IS INFERRED FROM THE INITIAL VALUES OF TOUT AND T.
+C-----------------------------------------------------------------------
+      IF (H0 .NE. 0.0D0) GO TO 180
+      TDIST = DABS(TOUT - T)
+      W0 = DMAX1(DABS(T),DABS(TOUT))
+      IF (TDIST .LT. 2.0D0*UROUND*W0) GO TO 622
+      TOL = RTOL(1) 
+      IF (ITOL .LE. 2) GO TO 140
+      DO 130 I = 1,N
+ 130    TOL = DMAX1(TOL,RTOL(I))
+ 140  IF (TOL .GT. 0.0D0) GO TO 160
+      ATOLI = ATOL(1)
+      DO 150 I = 1,N
+        IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I)
+        AYI = DABS(Y(I))
+        IF (AYI .NE. 0.0D0) TOL = DMAX1(TOL,ATOLI/AYI)
+ 150    CONTINUE
+ 160  TOL = DMAX1(TOL,100.0D0*UROUND)
+      TOL = DMIN1(TOL,0.001D0)
+      SUM = VNORM (N, RWORK(LF0), RWORK(LEWT))
+      SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
+      H0 = 1.0D0/DSQRT(SUM)
+      H0 = DMIN1(H0,TDIST)
+      H0 = DSIGN(H0,TOUT-T)
+C ADJUST H0 IF NECESSARY TO MEET HMAX BOUND. ---------------------------
+ 180  RH = DABS(H0)*HMXI
+      IF (RH .GT. 1.0D0) H0 = H0/RH
+C LOAD H WITH H0 AND SCALE YH(*,2) BY H0. ------------------------------
+      H = H0
+      DO 190 I = 1,N
+ 190    RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
+      GO TO 270
+C-----------------------------------------------------------------------
+C BLOCK D.
+C THE NEXT CODE BLOCK IS FOR CONTINUATION CALLS ONLY (ISTATE = 2 OR 3)
+C AND IS TO CHECK STOP CONDITIONS BEFORE TAKING A STEP.
+C-----------------------------------------------------------------------
+ 200  NSLAST = NST
+      GO TO (210, 250, 220, 230, 240), ITASK
+ 210  IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 250
+      CALL INTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      IF (IFLAG .NE. 0) GO TO 627
+      T = TOUT
+      GO TO 420
+ 220  TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
+      IF ((TP - TOUT)*H .GT. 0.0D0) GO TO 623
+      IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 250
+      GO TO 400
+ 230  TCRIT = RWORK(1)
+      IF ((TN - TCRIT)*H .GT. 0.0D0) GO TO 624
+      IF ((TCRIT - TOUT)*H .LT. 0.0D0) GO TO 625
+      IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 245
+      CALL INTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      IF (IFLAG .NE. 0) GO TO 627
+      T = TOUT
+      GO TO 420
+ 240  TCRIT = RWORK(1)
+      IF ((TN - TCRIT)*H .GT. 0.0D0) GO TO 624
+ 245  HMX = DABS(TN) + DABS(H)
+      IHIT = DABS(TN - TCRIT) .LE. 100.0D0*UROUND*HMX
+      IF (IHIT) GO TO 400
+      TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
+      IF ((TNEXT - TCRIT)*H .LE. 0.0D0) GO TO 250 
+      H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
+      IF (ISTATE .EQ. 2) JSTART = -2
+C-----------------------------------------------------------------------
+C BLOCK E.
+C THE NEXT BLOCK IS NORMALLY EXECUTED FOR ALL CALLS AND CONTAINS
+C THE CALL TO THE ONE-STEP CORE INTEGRATOR STODE. 
+C
+C THIS IS A LOOPING POINT FOR THE INTEGRATION STEPS.
+C
+C FIRST CHECK FOR TOO MANY STEPS BEING TAKEN, UPDATE EWT (IF NOT AT
+C START OF PROBLEM), CHECK FOR TOO MUCH ACCURACY BEING REQUESTED, AND 
+C CHECK FOR H BELOW THE ROUNDOFF LEVEL IN T.
+C-----------------------------------------------------------------------
+ 250  CONTINUE
+      IF ((NST-NSLAST) .GE. MXSTEP) GO TO 500
+      CALL EWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
+      DO 260 I = 1,N
+        IF (RWORK(I+LEWT-1) .LE. 0.0D0) GO TO 510 
+ 260    RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
+ 270  TOLSF = UROUND*VNORM (N, RWORK(LYH), RWORK(LEWT))
+      IF (TOLSF .LE. 1.0D0) GO TO 280
+      TOLSF = TOLSF*2.0D0
+      IF (NST .EQ. 0) GO TO 626
+      GO TO 520
+ 280  IF ((TN + H) .NE. TN) GO TO 290
+      NHNIL = NHNIL + 1
+      IF (NHNIL .GT. MXHNIL) GO TO 290
+      CALL XERRWD('LSODE--  WARNING..INTERNAL T (=R1) AND H (=R2) ARE',
+     1   50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD(
+     1  '      SUCH THAT IN THE MACHINE, T + H = T ON THE NEXT STEP  ',
+     1   60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      (H = STEP SIZE). SOLVER WILL CONTINUE ANYWAY',
+     1   50, 101, 0, 0, 0, 0, 2, TN, H) 
+      IF (NHNIL .LT. MXHNIL) GO TO 290
+      CALL XERRWD('LSODE--  ABOVE WARNING HAS BEEN ISSUED I1 TIMES.  ',
+     1   50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      IT WILL NOT BE ISSUED AGAIN FOR THIS PROBLEM',
+     1   50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
+ 290  CONTINUE
+C-----------------------------------------------------------------------
+C     CALL STODE(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,PREPJ,SOLSY)
+C-----------------------------------------------------------------------
+      IERR = 0
+      CALL STODE (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT),
+     1   RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM),
+     2   F, JAC, PREPJ, SOLSY, IERR)
+      IF (IERR .LT. 0) THEN
+        ISTATE = -13
+        RETURN
+      ENDIF
+      KGO = 1 - KFLAG
+      GO TO (300, 530, 540), KGO
+C-----------------------------------------------------------------------
+C BLOCK F.
+C THE FOLLOWING BLOCK HANDLES THE CASE OF A SUCCESSFUL RETURN FROM THE
+C CORE INTEGRATOR (KFLAG = 0).  TEST FOR STOP CONDITIONS.
+C-----------------------------------------------------------------------
+ 300  INIT = 1
+      GO TO (310, 400, 330, 340, 350), ITASK
+C ITASK = 1.  IF TOUT HAS BEEN REACHED, INTERPOLATE. -------------------
+ 310  IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 250
+      CALL INTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      T = TOUT
+      GO TO 420
+C ITASK = 3.  JUMP TO EXIT IF TOUT WAS REACHED. ------------------------
+ 330  IF ((TN - TOUT)*H .GE. 0.0D0) GO TO 400
+      GO TO 250
+C ITASK = 4.  SEE IF TOUT OR TCRIT WAS REACHED.  ADJUST H IF NECESSARY.
+ 340  IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 345
+      CALL INTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      T = TOUT
+      GO TO 420
+ 345  HMX = DABS(TN) + DABS(H)
+      IHIT = DABS(TN - TCRIT) .LE. 100.0D0*UROUND*HMX
+      IF (IHIT) GO TO 400
+      TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
+      IF ((TNEXT - TCRIT)*H .LE. 0.0D0) GO TO 250 
+      H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
+      JSTART = -2
+      GO TO 250
+C ITASK = 5.  SEE IF TCRIT WAS REACHED AND JUMP TO EXIT. ---------------
+ 350  HMX = DABS(TN) + DABS(H)
+      IHIT = DABS(TN - TCRIT) .LE. 100.0D0*UROUND*HMX
+C-----------------------------------------------------------------------
+C BLOCK G.
+C THE FOLLOWING BLOCK HANDLES ALL SUCCESSFUL RETURNS FROM LSODE.
+C IF ITASK .NE. 1, Y IS LOADED FROM YH AND T IS SET ACCORDINGLY.
+C ISTATE IS SET TO 2, THE ILLEGAL INPUT COUNTER IS ZEROED, AND THE
+C OPTIONAL OUTPUTS ARE LOADED INTO THE WORK ARRAYS BEFORE RETURNING.
+C IF ISTATE = 1 AND TOUT = T, THERE IS A RETURN WITH NO ACTION TAKEN, 
+C EXCEPT THAT IF THIS HAS HAPPENED REPEATEDLY, THE RUN IS TERMINATED. 
+C-----------------------------------------------------------------------
+ 400  DO 410 I = 1,N
+ 410    Y(I) = RWORK(I+LYH-1) 
+      T = TN
+      IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 420
+      IF (IHIT) T = TCRIT
+ 420  ISTATE = 2
+      ILLIN = 0
+      RWORK(11) = HU
+      RWORK(12) = H 
+      RWORK(13) = TN
+      IWORK(11) = NST
+      IWORK(12) = NFE
+      IWORK(13) = NJE
+      IWORK(14) = NQU
+      IWORK(15) = NQ
+      RETURN
+C
+ 430  NTREP = NTREP + 1
+      IF (NTREP .LT. 5) RETURN
+      CALL XERRWD(
+     1  'LSODE--  REPEATED CALLS WITH ISTATE = 1 AND TOUT = T (=R1)  ',
+     1   60, 301, 0, 0, 0, 0, 1, T, 0.0D0)
+      GO TO 800
+C-----------------------------------------------------------------------
+C BLOCK H.
+C THE FOLLOWING BLOCK HANDLES ALL UNSUCCESSFUL RETURNS OTHER THAN
+C THOSE FOR ILLEGAL INPUT.  FIRST THE ERROR MESSAGE ROUTINE IS CALLED.
+C IF THERE WAS AN ERROR TEST OR CONVERGENCE TEST FAILURE, IMXER IS SET.
+C THEN Y IS LOADED FROM YH, T IS SET TO TN, AND THE ILLEGAL INPUT
+C COUNTER ILLIN IS SET TO 0.  THE OPTIONAL OUTPUTS ARE LOADED INTO
+C THE WORK ARRAYS BEFORE RETURNING.
+C-----------------------------------------------------------------------
+C THE MAXIMUM NUMBER OF STEPS WAS TAKEN BEFORE REACHING TOUT. ----------
+ 500  CALL XERRWD('LSODE--  AT CURRENT T (=R1), MXSTEP (=I1) STEPS   ',
+     1   50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      TAKEN ON THIS CALL BEFORE REACHING TOUT     ',
+     1   50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
+      ISTATE = -1
+      GO TO 580
+C EWT(I) .LE. 0.0 FOR SOME I (NOT AT START OF PROBLEM). ----------------
+ 510  EWTI = RWORK(LEWT+I-1)
+      CALL XERRWD('LSODE--  AT T (=R1), EWT(I1) HAS BECOME R2 .LE. 0.',
+     1   50, 202, 0, 1, I, 0, 2, TN, EWTI)
+      ISTATE = -6
+      GO TO 580
+C TOO MUCH ACCURACY REQUESTED FOR MACHINE PRECISION. -------------------
+ 520  CALL XERRWD('LSODE--  AT T (=R1), TOO MUCH ACCURACY REQUESTED  ',
+     1   50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      FOR PRECISION OF MACHINE..  SEE TOLSF (=R2) ',
+     1   50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
+      RWORK(14) = TOLSF
+      ISTATE = -2
+      GO TO 580
+C KFLAG = -1.  ERROR TEST FAILED REPEATEDLY OR WITH ABS(H) = HMIN. -----
+ 530  CALL XERRWD('LSODE--  AT T(=R1) AND STEP SIZE H(=R2), THE ERROR',
+     1   50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      TEST FAILED REPEATEDLY OR WITH ABS(H) = HMIN',
+     1   50, 204, 0, 0, 0, 0, 2, TN, H) 
+      ISTATE = -4
+      GO TO 560
+C KFLAG = -2.  CONVERGENCE FAILED REPEATEDLY OR WITH ABS(H) = HMIN. ----
+ 540  CALL XERRWD('LSODE--  AT T (=R1) AND STEP SIZE H (=R2), THE    ',
+     1   50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      CORRECTOR CONVERGENCE FAILED REPEATEDLY     ',
+     1   50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD('      OR WITH ABS(H) = HMIN   ',
+     1   30, 205, 0, 0, 0, 0, 2, TN, H) 
+      ISTATE = -5
+C COMPUTE IMXER IF RELEVANT. -------------------------------------------
+ 560  BIG = 0.0D0
+      IMXER = 1
+      DO 570 I = 1,N
+        SIZE = DABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
+        IF (BIG .GE. SIZE) GO TO 570
+        BIG = SIZE
+        IMXER = I
+ 570    CONTINUE
+      IWORK(16) = IMXER
+C SET Y VECTOR, T, ILLIN, AND OPTIONAL OUTPUTS. ------------------------
+ 580  DO 590 I = 1,N
+ 590    Y(I) = RWORK(I+LYH-1) 
+      T = TN
+      ILLIN = 0
+      RWORK(11) = HU
+      RWORK(12) = H 
+      RWORK(13) = TN
+      IWORK(11) = NST
+      IWORK(12) = NFE
+      IWORK(13) = NJE
+      IWORK(14) = NQU
+      IWORK(15) = NQ
+      RETURN
+C-----------------------------------------------------------------------
+C BLOCK I.
+C THE FOLLOWING BLOCK HANDLES ALL ERROR RETURNS DUE TO ILLEGAL INPUT
+C (ISTATE = -3), AS DETECTED BEFORE CALLING THE CORE INTEGRATOR.
+C FIRST THE ERROR MESSAGE ROUTINE IS CALLED.  THEN IF THERE HAVE BEEN 
+C 5 CONSECUTIVE SUCH RETURNS JUST BEFORE THIS CALL TO THE SOLVER,
+C THE RUN IS HALTED.
+C-----------------------------------------------------------------------
+ 601  CALL XERRWD('LSODE--  ISTATE (=I1) ILLEGAL ',
+     1   30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0) 
+      GO TO 700
+ 602  CALL XERRWD('LSODE--  ITASK (=I1) ILLEGAL  ',
+     1   30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 603  CALL XERRWD('LSODE--  ISTATE .GT. 1 BUT LSODE NOT INITIALIZED  ',
+     1   50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 604  CALL XERRWD('LSODE--  NEQ (=I1) .LT. 1     ',
+     1   30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0) 
+      GO TO 700
+ 605  CALL XERRWD('LSODE--  ISTATE = 3 AND NEQ INCREASED (I1 TO I2)  ',
+     1   50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0) 
+      GO TO 700
+ 606  CALL XERRWD('LSODE--  ITOL (=I1) ILLEGAL   ',
+     1   30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 607  CALL XERRWD('LSODE--  IOPT (=I1) ILLEGAL   ',
+     1   30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 608  CALL XERRWD('LSODE--  MF (=I1) ILLEGAL     ',
+     1   30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 609  CALL XERRWD('LSODE--  ML (=I1) ILLEGAL.. .LT.0 OR .GE.NEQ (=I2)',
+     1   50, 9, 0, 2, ML, NEQ(1), 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 610  CALL XERRWD('LSODE--  MU (=I1) ILLEGAL.. .LT.0 OR .GE.NEQ (=I2)',
+     1   50, 10, 0, 2, MU, NEQ(1), 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 611  CALL XERRWD('LSODE--  MAXORD (=I1) .LT. 0  ',
+     1   30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 612  CALL XERRWD('LSODE--  MXSTEP (=I1) .LT. 0  ',
+     1   30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 613  CALL XERRWD('LSODE--  MXHNIL (=I1) .LT. 0  ',
+     1   30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 614  CALL XERRWD('LSODE--  TOUT (=R1) BEHIND T (=R2)      ',
+     1   40, 14, 0, 0, 0, 0, 2, TOUT, T)
+      CALL XERRWD('      INTEGRATION DIRECTION IS GIVEN BY H0 (=R1)  ',
+     1   50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
+      GO TO 700
+ 615  CALL XERRWD('LSODE--  HMAX (=R1) .LT. 0.0  ',
+     1   30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
+      GO TO 700
+ 616  CALL XERRWD('LSODE--  HMIN (=R1) .LT. 0.0  ',
+     1   30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
+      GO TO 700
+ 617  CALL XERRWD(
+     1  'LSODE--  RWORK LENGTH NEEDED, LENRW (=I1), EXCEEDS LRW (=I2)',
+     1   60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 618  CALL XERRWD(
+     1  'LSODE--  IWORK LENGTH NEEDED, LENIW (=I1), EXCEEDS LIW (=I2)',
+     1   60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
+      GO TO 700
+ 619  CALL XERRWD('LSODE--  RTOL(I1) IS R1 .LT. 0.0        ',
+     1   40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
+      GO TO 700
+ 620  CALL XERRWD('LSODE--  ATOL(I1) IS R1 .LT. 0.0        ',
+     1   40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
+      GO TO 700
+ 621  EWTI = RWORK(LEWT+I-1)
+      CALL XERRWD('LSODE--  EWT(I1) IS R1 .LE. 0.0         ',
+     1   40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
+      GO TO 700
+ 622  CALL XERRWD(
+     1  'LSODE--  TOUT (=R1) TOO CLOSE TO T(=R2) TO START INTEGRATION',
+     1   60, 22, 0, 0, 0, 0, 2, TOUT, T)
+      GO TO 700
+ 623  CALL XERRWD(
+     1  'LSODE--  ITASK = I1 AND TOUT (=R1) BEHIND TCUR - HU (= R2)  ',
+     1   60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
+      GO TO 700
+ 624  CALL XERRWD(
+     1  'LSODE--  ITASK = 4 OR 5 AND TCRIT (=R1) BEHIND TCUR (=R2)   ',
+     1   60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
+      GO TO 700
+ 625  CALL XERRWD(
+     1  'LSODE--  ITASK = 4 OR 5 AND TCRIT (=R1) BEHIND TOUT (=R2)   ',
+     1   60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
+      GO TO 700
+ 626  CALL XERRWD('LSODE--  AT START OF PROBLEM, TOO MUCH ACCURACY   ',
+     1   50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      CALL XERRWD(
+     1  '      REQUESTED FOR PRECISION OF MACHINE..  SEE TOLSF (=R1) ',
+     1   60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
+      RWORK(14) = TOLSF
+      GO TO 700
+ 627  CALL XERRWD('LSODE--  TROUBLE FROM INTDY. ITASK = I1, TOUT = R1',
+     1   50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
+C
+ 700  IF (ILLIN .EQ. 5) GO TO 710
+      ILLIN = ILLIN + 1
+      ISTATE = -3
+      RETURN
+ 710  CALL XERRWD('LSODE--  REPEATED OCCURRENCES OF ILLEGAL INPUT    ',
+     1   50, 302, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
+C
+ 800  CALL XERRWD('LSODE--  RUN ABORTED.. APPARENT INFINITE LOOP     ',
+     1   50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
+      RETURN
+C----------------------- END OF SUBROUTINE LSODE -----------------------
+      END 
diff --git a/libcruft/odepack/ewset.f b/libcruft/odepack/ewset.f
new file mode 100644
index 0000000..5809ff8
--- /dev/null
+++ b/libcruft/odepack/ewset.f
@@ -0,0 +1,32 @@
+      SUBROUTINE EWSET (N, ITOL, RTOL, ATOL, YCUR, EWT)
+CLLL. OPTIMIZE
+C-----------------------------------------------------------------------
+C THIS SUBROUTINE SETS THE ERROR WEIGHT VECTOR EWT ACCORDING TO
+C     EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(I),  I = 1,...,N,
+C WITH THE SUBSCRIPT ON RTOL AND/OR ATOL POSSIBLY REPLACED BY 1 ABOVE,
+C DEPENDING ON THE VALUE OF ITOL.
+C-----------------------------------------------------------------------
+      INTEGER N, ITOL
+      INTEGER I
+      DOUBLE PRECISION RTOL, ATOL, YCUR, EWT
+      DIMENSION RTOL(*), ATOL(*), YCUR(N), EWT(N) 
+C
+      GO TO (10, 20, 30, 40), ITOL
+ 10   CONTINUE
+      DO 15 I = 1,N 
+ 15     EWT(I) = RTOL(1)*DABS(YCUR(I)) + ATOL(1)
+      RETURN
+ 20   CONTINUE
+      DO 25 I = 1,N 
+ 25     EWT(I) = RTOL(1)*DABS(YCUR(I)) + ATOL(I)
+      RETURN
+ 30   CONTINUE
+      DO 35 I = 1,N 
+ 35     EWT(I) = RTOL(I)*DABS(YCUR(I)) + ATOL(1)
+      RETURN
+ 40   CONTINUE
+      DO 45 I = 1,N 
+ 45     EWT(I) = RTOL(I)*DABS(YCUR(I)) + ATOL(I)
+      RETURN
+C----------------------- END OF SUBROUTINE EWSET -----------------------
+      END 
diff --git a/libcruft/odepack/intdy.f b/libcruft/odepack/intdy.f
new file mode 100644
index 0000000..57edc91
--- /dev/null
+++ b/libcruft/odepack/intdy.f
@@ -0,0 +1,84 @@
+      SUBROUTINE INTDY (T, K, YH, NYH, DKY, IFLAG)
+CLLL. OPTIMIZE
+      INTEGER K, NYH, IFLAG
+      INTEGER IOWND, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     2   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, IC, J, JB, JB2, JJ, JJ1, JP1
+      DOUBLE PRECISION T, YH, DKY
+      DOUBLE PRECISION ROWNS, 
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      DOUBLE PRECISION C, R, S, TP
+      DIMENSION YH(NYH,*), DKY(*)
+      COMMON /LS0001/ ROWNS(209),
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     3   IOWND(14), IOWNS(6), 
+     4   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C-----------------------------------------------------------------------
+C INTDY COMPUTES INTERPOLATED VALUES OF THE K-TH DERIVATIVE OF THE
+C DEPENDENT VARIABLE VECTOR Y, AND STORES IT IN DKY.  THIS ROUTINE
+C IS CALLED WITHIN THE PACKAGE WITH K = 0 AND T = TOUT, BUT MAY
+C ALSO BE CALLED BY THE USER FOR ANY K UP TO THE CURRENT ORDER.
+C (SEE DETAILED INSTRUCTIONS IN THE USAGE DOCUMENTATION.)
+C-----------------------------------------------------------------------
+C THE COMPUTED VALUES IN DKY ARE GOTTEN BY INTERPOLATION USING THE
+C NORDSIECK HISTORY ARRAY YH.  THIS ARRAY CORRESPONDS UNIQUELY TO A
+C VECTOR-VALUED POLYNOMIAL OF DEGREE NQCUR OR LESS, AND DKY IS SET
+C TO THE K-TH DERIVATIVE OF THIS POLYNOMIAL AT T. 
+C THE FORMULA FOR DKY IS..
+C              Q
+C  DKY(I)  =  SUM  C(J,K) * (T - TN)**(J-K) * H**(-J) * YH(I,J+1)
+C             J=K
+C WHERE  C(J,K) = J*(J-1)*...*(J-K+1), Q = NQCUR, TN = TCUR, H = HCUR.
+C THE QUANTITIES  NQ = NQCUR, L = NQ+1, N = NEQ, TN, AND H ARE
+C COMMUNICATED BY COMMON.  THE ABOVE SUM IS DONE IN REVERSE ORDER.
+C IFLAG IS RETURNED NEGATIVE IF EITHER K OR T IS OUT OF BOUNDS.
+C-----------------------------------------------------------------------
+      IFLAG = 0
+      IF (K .LT. 0 .OR. K .GT. NQ) GO TO 80
+      TP = TN - HU -  100.0D0*UROUND*(TN + HU)
+      IF ((T-TP)*(T-TN) .GT. 0.0D0) GO TO 90
+C
+      S = (T - TN)/H
+      IC = 1
+      IF (K .EQ. 0) GO TO 15
+      JJ1 = L - K
+      DO 10 JJ = JJ1,NQ
+ 10     IC = IC*JJ
+ 15   C = DBLE(IC)
+      DO 20 I = 1,N 
+ 20     DKY(I) = C*YH(I,L)
+      IF (K .EQ. NQ) GO TO 55 
+      JB2 = NQ - K
+      DO 50 JB = 1,JB2
+        J = NQ - JB 
+        JP1 = J + 1 
+        IC = 1
+        IF (K .EQ. 0) GO TO 35
+        JJ1 = JP1 - K
+        DO 30 JJ = JJ1,J
+ 30       IC = IC*JJ
+ 35     C = DBLE(IC)
+        DO 40 I = 1,N
+ 40       DKY(I) = C*YH(I,JP1) + S*DKY(I)
+ 50     CONTINUE
+      IF (K .EQ. 0) RETURN
+ 55   R = H**(-K)
+      DO 60 I = 1,N 
+ 60     DKY(I) = R*DKY(I)
+      RETURN
+C
+ 80   CALL XERRWD('INTDY--  K (=I1) ILLEGAL      ',
+     1   30, 51, 0, 1, K, 0, 0, 0.0D0, 0.0D0)
+      IFLAG = -1
+      RETURN
+ 90   CALL XERRWD('INTDY--  T (=R1) ILLEGAL      ',
+     1   30, 52, 0, 0, 0, 0, 1, T, 0.0D0)
+      CALL XERRWD(
+     1  '      T NOT IN INTERVAL TCUR - HU (= R1) TO TCUR (=R2)      ',
+     1   60, 52, 0, 0, 0, 0, 2, TP, TN) 
+      IFLAG = -2
+      RETURN
+C----------------------- END OF SUBROUTINE INTDY -----------------------
+      END 
diff --git a/libcruft/odepack/prepj.f b/libcruft/odepack/prepj.f
new file mode 100644
index 0000000..6dd9cc4
--- /dev/null
+++ b/libcruft/odepack/prepj.f
@@ -0,0 +1,177 @@
+      SUBROUTINE PREPJ (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM,
+     1   F, JAC, IERR)
+CLLL. OPTIMIZE
+      EXTERNAL F, JAC
+      INTEGER NEQ, NYH, IWM
+      INTEGER IOWND, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     2   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, I1, I2, IER, II, J, J1, JJ, LENP,
+     1   MBA, MBAND, MEB1, MEBAND, ML, ML3, MU, NP1
+      DOUBLE PRECISION Y, YH, EWT, FTEM, SAVF, WM 
+      DOUBLE PRECISION ROWNS, 
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      DOUBLE PRECISION CON, DI, FAC, HL0, R, R0, SRUR, YI, YJ, YJJ,
+     1   VNORM
+      DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), FTEM(*), SAVF(*),
+     1   WM(*), IWM(*)
+      COMMON /LS0001/ ROWNS(209),
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     3   IOWND(14), IOWNS(6), 
+     4   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C-----------------------------------------------------------------------
+C PREPJ IS CALLED BY STODE TO COMPUTE AND PROCESS THE MATRIX
+C P = I - H*EL(1)*J , WHERE J IS AN APPROXIMATION TO THE JACOBIAN.
+C HERE J IS COMPUTED BY THE USER-SUPPLIED ROUTINE JAC IF
+C MITER = 1 OR 4, OR BY FINITE DIFFERENCING IF MITER = 2, 3, OR 5.
+C IF MITER = 3, A DIAGONAL APPROXIMATION TO J IS USED.
+C J IS STORED IN WM AND REPLACED BY P.  IF MITER .NE. 3, P IS THEN
+C SUBJECTED TO LU DECOMPOSITION IN PREPARATION FOR LATER SOLUTION
+C OF LINEAR SYSTEMS WITH P AS COEFFICIENT MATRIX. THIS IS DONE
+C BY DGETRF IF MITER = 1 OR 2, AND BY DGBTRF IF MITER = 4 OR 5.
+C
+C IN ADDITION TO VARIABLES DESCRIBED PREVIOUSLY, COMMUNICATION
+C WITH PREPJ USES THE FOLLOWING..
+C Y     = ARRAY CONTAINING PREDICTED VALUES ON ENTRY.
+C FTEM  = WORK ARRAY OF LENGTH N (ACOR IN STODE). 
+C SAVF  = ARRAY CONTAINING F EVALUATED AT PREDICTED Y.
+C WM    = REAL WORK SPACE FOR MATRICES.  ON OUTPUT IT CONTAINS THE
+C         INVERSE DIAGONAL MATRIX IF MITER = 3 AND THE LU DECOMPOSITION
+C         OF P IF MITER IS 1, 2 , 4, OR 5.
+C         STORAGE OF MATRIX ELEMENTS STARTS AT WM(3).
+C         WM ALSO CONTAINS THE FOLLOWING MATRIX-RELATED DATA..
+C         WM(1) = SQRT(UROUND), USED IN NUMERICAL JACOBIAN INCREMENTS.
+C         WM(2) = H*EL0, SAVED FOR LATER USE IF MITER = 3.
+C IWM   = INTEGER WORK SPACE CONTAINING PIVOT INFORMATION, STARTING AT
+C         IWM(21), IF MITER IS 1, 2, 4, OR 5.  IWM ALSO CONTAINS BAND 
+C         PARAMETERS ML = IWM(1) AND MU = IWM(2) IF MITER IS 4 OR 5.
+C EL0   = EL(1) (INPUT).
+C IERPJ = OUTPUT ERROR FLAG,  = 0 IF NO TROUBLE, .GT. 0 IF
+C         P MATRIX FOUND TO BE SINGULAR.
+C JCUR  = OUTPUT FLAG = 1 TO INDICATE THAT THE JACOBIAN MATRIX
+C         (OR APPROXIMATION) IS NOW CURRENT.
+C THIS ROUTINE ALSO USES THE COMMON VARIABLES EL0, H, TN, UROUND,
+C MITER, N, NFE, AND NJE.
+C-----------------------------------------------------------------------
+      NJE = NJE + 1 
+      IERPJ = 0
+      JCUR = 1
+      HL0 = H*EL0
+      GO TO (100, 200, 300, 400, 500), MITER
+C IF MITER = 1, CALL JAC AND MULTIPLY BY SCALAR. -----------------------
+ 100  LENP = N*N
+      DO 110 I = 1,LENP
+ 110    WM(I+2) = 0.0D0
+      CALL JAC (NEQ, TN, Y, 0, 0, WM(3), N)
+      CON = -HL0
+      DO 120 I = 1,LENP
+ 120    WM(I+2) = WM(I+2)*CON 
+      GO TO 240
+C IF MITER = 2, MAKE N CALLS TO F TO APPROXIMATE J. --------------------
+ 200  FAC = VNORM (N, SAVF, EWT)
+      R0 = 1000.0D0*DABS(H)*UROUND*DBLE(N)*FAC  
+      IF (R0 .EQ. 0.0D0) R0 = 1.0D0
+      SRUR = WM(1)
+      J1 = 2
+      DO 230 J = 1,N
+        YJ = Y(J)
+        R = DMAX1(SRUR*DABS(YJ),R0/EWT(J))
+        Y(J) = Y(J) + R
+        FAC = -HL0/R
+        IERR = 0
+        CALL F (NEQ, TN, Y, FTEM, IERR)
+        IF (IERR .LT. 0) RETURN
+        DO 220 I = 1,N
+ 220      WM(I+J1) = (FTEM(I) - SAVF(I))*FAC
+        Y(J) = YJ
+        J1 = J1 + N 
+ 230    CONTINUE
+      NFE = NFE + N 
+C ADD IDENTITY MATRIX. -------------------------------------------------
+ 240  J = 3
+      NP1 = N + 1
+      DO 250 I = 1,N
+        WM(J) = WM(J) + 1.0D0 
+ 250    J = J + NP1 
+C DO LU DECOMPOSITION ON P. --------------------------------------------
+      CALL DGETRF ( N, N, WM(3), N, IWM(21), IER)
+      IF (IER .NE. 0) IERPJ = 1
+      RETURN
+C IF MITER = 3, CONSTRUCT A DIAGONAL APPROXIMATION TO J AND P. ---------
+ 300  WM(2) = HL0
+      R = EL0*0.1D0 
+      DO 310 I = 1,N
+ 310    Y(I) = Y(I) + R*(H*SAVF(I) - YH(I,2))
+      IERR = 0
+      CALL F (NEQ, TN, Y, WM(3), IERR)
+      IF (IERR .LT. 0) RETURN
+      NFE = NFE + 1 
+      DO 320 I = 1,N
+        R0 = H*SAVF(I) - YH(I,2)
+        DI = 0.1D0*R0 - H*(WM(I+2) - SAVF(I))
+        WM(I+2) = 1.0D0
+        IF (DABS(R0) .LT. UROUND/EWT(I)) GO TO 320
+        IF (DABS(DI) .EQ. 0.0D0) GO TO 330
+        WM(I+2) = 0.1D0*R0/DI 
+ 320    CONTINUE
+      RETURN
+ 330  IERPJ = 1
+      RETURN
+C IF MITER = 4, CALL JAC AND MULTIPLY BY SCALAR. -----------------------
+ 400  ML = IWM(1)
+      MU = IWM(2)
+      ML3 = ML + 3
+      MBAND = ML + MU + 1
+      MEBAND = MBAND + ML
+      LENP = MEBAND*N
+      DO 410 I = 1,LENP
+ 410    WM(I+2) = 0.0D0
+      CALL JAC (NEQ, TN, Y, ML, MU, WM(ML3), MEBAND)
+      CON = -HL0
+      DO 420 I = 1,LENP
+ 420    WM(I+2) = WM(I+2)*CON 
+      GO TO 570
+C IF MITER = 5, MAKE MBAND CALLS TO F TO APPROXIMATE J. ----------------
+ 500  ML = IWM(1)
+      MU = IWM(2)
+      MBAND = ML + MU + 1
+      MBA = MIN0(MBAND,N)
+      MEBAND = MBAND + ML
+      MEB1 = MEBAND - 1
+      SRUR = WM(1)
+      FAC = VNORM (N, SAVF, EWT)
+      R0 = 1000.0D0*DABS(H)*UROUND*DBLE(N)*FAC  
+      IF (R0 .EQ. 0.0D0) R0 = 1.0D0
+      DO 560 J = 1,MBA
+        DO 530 I = J,N,MBAND
+          YI = Y(I) 
+          R = DMAX1(SRUR*DABS(YI),R0/EWT(I))
+ 530      Y(I) = Y(I) + R
+        IERR = 0
+        CALL F (NEQ, TN, Y, FTEM, IERR)
+        IF (IERR .LT. 0) RETURN
+        DO 550 JJ = J,N,MBAND 
+          Y(JJ) = YH(JJ,1)
+          YJJ = Y(JJ)
+          R = DMAX1(SRUR*DABS(YJJ),R0/EWT(JJ))
+          FAC = -HL0/R
+          I1 = MAX0(JJ-MU,1)
+          I2 = MIN0(JJ+ML,N)
+          II = JJ*MEB1 - ML + 2
+          DO 540 I = I1,I2
+ 540        WM(II+I) = (FTEM(I) - SAVF(I))*FAC
+ 550      CONTINUE
+ 560    CONTINUE
+      NFE = NFE + MBA
+C ADD IDENTITY MATRIX. -------------------------------------------------
+ 570  II = MBAND + 2
+      DO 580 I = 1,N
+        WM(II) = WM(II) + 1.0D0
+ 580    II = II + MEBAND
+C DO LU DECOMPOSITION OF P. --------------------------------------------
+      CALL DGBTRF ( N, N, ML, MU, WM(3), MEBAND, IWM(21), IER)
+      IF (IER .NE. 0) IERPJ = 1
+      RETURN
+C----------------------- END OF SUBROUTINE PREPJ -----------------------
+      END 
diff --git a/libcruft/odepack/scfode.f b/libcruft/odepack/scfode.f
new file mode 100644
index 0000000..d5a9619
--- /dev/null
+++ b/libcruft/odepack/scfode.f
@@ -0,0 +1,127 @@
+      SUBROUTINE SCFODE (METH, ELCO, TESCO)
+C***BEGIN PROLOGUE  SCFODE
+C***SUBSIDIARY
+C***PURPOSE  Set ODE integrator coefficients.
+C***TYPE      SINGLE PRECISION (SCFODE-S, DCFODE-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  SCFODE is called by the integrator routine to set coefficients
+C  needed there.  The coefficients for the current method, as
+C  given by the value of METH, are set for all orders and saved.
+C  The maximum order assumed here is 12 if METH = 1 and 5 if METH = 2.
+C  (A smaller value of the maximum order is also allowed.)
+C  SCFODE is called once at the beginning of the problem,
+C  and is not called again unless and until METH is changed.
+C
+C  The ELCO array contains the basic method coefficients.
+C  The coefficients el(i), 1 .le. i .le. nq+1, for the method of
+C  order nq are stored in ELCO(i,nq).  They are given by a genetrating
+C  polynomial, i.e.,
+C      l(x) = el(1) + el(2)*x + ... + el(nq+1)*x**nq.
+C  For the implicit Adams methods, l(x) is given by
+C      dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1),    l(-1) = 0.
+C  For the BDF methods, l(x) is given by
+C      l(x) = (x+1)*(x+2)* ... *(x+nq)/K,
+C  where         K = factorial(nq)*(1 + 1/2 + ... + 1/nq).
+C
+C  The TESCO array contains test constants used for the
+C  local error test and the selection of step size and/or order.
+C  At order nq, TESCO(k,nq) is used for the selection of step
+C  size at order nq - 1 if k = 1, at order nq if k = 2, and at order
+C  nq + 1 if k = 3.
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890503  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C***END PROLOGUE  SCFODE
+C**End
+      INTEGER METH
+      INTEGER I, IB, NQ, NQM1, NQP1
+      REAL ELCO, TESCO
+      REAL AGAMQ, FNQ, FNQM1, PC, PINT, RAGQ,
+     1   RQFAC, RQ1FAC, TSIGN, XPIN
+      DIMENSION ELCO(13,12), TESCO(3,12)
+      DIMENSION PC(12)
+C
+C***FIRST EXECUTABLE STATEMENT  SCFODE
+      GO TO (100, 200), METH
+C
+ 100  ELCO(1,1) = 1.0E0
+      ELCO(2,1) = 1.0E0
+      TESCO(1,1) = 0.0E0
+      TESCO(2,1) = 2.0E0
+      TESCO(1,2) = 1.0E0
+      TESCO(3,12) = 0.0E0
+      PC(1) = 1.0E0
+      RQFAC = 1.0E0
+      DO 140 NQ = 2,12
+C-----------------------------------------------------------------------
+C The PC array will contain the coefficients of the polynomial
+C     p(x) = (x+1)*(x+2)*...*(x+nq-1).
+C Initially, p(x) = 1.
+C-----------------------------------------------------------------------
+        RQ1FAC = RQFAC
+        RQFAC = RQFAC/NQ
+        NQM1 = NQ - 1
+        FNQM1 = NQM1
+        NQP1 = NQ + 1
+C Form coefficients of p(x)*(x+nq-1). ----------------------------------
+        PC(NQ) = 0.0E0
+        DO 110 IB = 1,NQM1
+          I = NQP1 - IB
+ 110      PC(I) = PC(I-1) + FNQM1*PC(I)
+        PC(1) = FNQM1*PC(1)
+C Compute integral, -1 to 0, of p(x) and x*p(x). -----------------------
+        PINT = PC(1)
+        XPIN = PC(1)/2.0E0
+        TSIGN = 1.0E0
+        DO 120 I = 2,NQ
+          TSIGN = -TSIGN
+          PINT = PINT + TSIGN*PC(I)/I
+ 120      XPIN = XPIN + TSIGN*PC(I)/(I+1)
+C Store coefficients in ELCO and TESCO. --------------------------------
+        ELCO(1,NQ) = PINT*RQ1FAC
+        ELCO(2,NQ) = 1.0E0
+        DO 130 I = 2,NQ
+ 130      ELCO(I+1,NQ) = RQ1FAC*PC(I)/I
+        AGAMQ = RQFAC*XPIN
+        RAGQ = 1.0E0/AGAMQ
+        TESCO(2,NQ) = RAGQ
+        IF (NQ .LT. 12) TESCO(1,NQP1) = RAGQ*RQFAC/NQP1
+        TESCO(3,NQM1) = RAGQ
+ 140    CONTINUE
+      RETURN
+C
+ 200  PC(1) = 1.0E0
+      RQ1FAC = 1.0E0
+      DO 230 NQ = 1,5
+C-----------------------------------------------------------------------
+C The PC array will contain the coefficients of the polynomial
+C     p(x) = (x+1)*(x+2)*...*(x+nq).
+C Initially, p(x) = 1.
+C-----------------------------------------------------------------------
+        FNQ = NQ
+        NQP1 = NQ + 1
+C Form coefficients of p(x)*(x+nq). ------------------------------------
+        PC(NQP1) = 0.0E0
+        DO 210 IB = 1,NQ
+          I = NQ + 2 - IB
+ 210      PC(I) = PC(I-1) + FNQ*PC(I)
+        PC(1) = FNQ*PC(1)
+C Store coefficients in ELCO and TESCO. --------------------------------
+        DO 220 I = 1,NQP1
+ 220      ELCO(I,NQ) = PC(I)/PC(2)
+        ELCO(2,NQ) = 1.0E0
+        TESCO(1,NQ) = RQ1FAC
+        TESCO(2,NQ) = NQP1/ELCO(1,NQ)
+        TESCO(3,NQ) = (NQ+2)/ELCO(1,NQ)
+        RQ1FAC = RQ1FAC/FNQ
+ 230    CONTINUE
+      RETURN
+C----------------------- END OF SUBROUTINE SCFODE ----------------------
+      END
diff --git a/libcruft/odepack/sewset.f b/libcruft/odepack/sewset.f
new file mode 100644
index 0000000..6967aa1
--- /dev/null
+++ b/libcruft/odepack/sewset.f
@@ -0,0 +1,47 @@
+      SUBROUTINE SEWSET (N, ITOL, RTOL, ATOL, YCUR, EWT)
+C***BEGIN PROLOGUE  SEWSET
+C***SUBSIDIARY
+C***PURPOSE  Set error weight vector.
+C***TYPE      SINGLE PRECISION (SEWSET-S, DEWSET-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  This subroutine sets the error weight vector EWT according to
+C      EWT(i) = RTOL(i)*ABS(YCUR(i)) + ATOL(i),  i = 1,...,N,
+C  with the subscript on RTOL and/or ATOL possibly replaced by 1 above,
+C  depending on the value of ITOL.
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890503  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C***END PROLOGUE  SEWSET
+C**End
+      INTEGER N, ITOL
+      INTEGER I
+      REAL RTOL, ATOL, YCUR, EWT
+      DIMENSION RTOL(*), ATOL(*), YCUR(N), EWT(N)
+C
+C***FIRST EXECUTABLE STATEMENT  SEWSET
+      GO TO (10, 20, 30, 40), ITOL
+ 10   CONTINUE
+      DO 15 I = 1,N
+ 15     EWT(I) = RTOL(1)*ABS(YCUR(I)) + ATOL(1)
+      RETURN
+ 20   CONTINUE
+      DO 25 I = 1,N
+ 25     EWT(I) = RTOL(1)*ABS(YCUR(I)) + ATOL(I)
+      RETURN
+ 30   CONTINUE
+      DO 35 I = 1,N
+ 35     EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(1)
+      RETURN
+ 40   CONTINUE
+      DO 45 I = 1,N
+ 45     EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(I)
+      RETURN
+C----------------------- END OF SUBROUTINE SEWSET ----------------------
+      END
diff --git a/libcruft/odepack/sintdy.f b/libcruft/odepack/sintdy.f
new file mode 100644
index 0000000..0913e36
--- /dev/null
+++ b/libcruft/odepack/sintdy.f
@@ -0,0 +1,108 @@
+      SUBROUTINE SINTDY (T, K, YH, NYH, DKY, IFLAG)
+C***BEGIN PROLOGUE  SINTDY
+C***SUBSIDIARY
+C***PURPOSE  Interpolate solution derivatives.
+C***TYPE      SINGLE PRECISION (SINTDY-S, DINTDY-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  SINTDY computes interpolated values of the K-th derivative of the
+C  dependent variable vector y, and stores it in DKY.  This routine
+C  is called within the package with K = 0 and T = TOUT, but may
+C  also be called by the user for any K up to the current order.
+C  (See detailed instructions in the usage documentation.)
+C
+C  The computed values in DKY are gotten by interpolation using the
+C  Nordsieck history array YH.  This array corresponds uniquely to a
+C  vector-valued polynomial of degree NQCUR or less, and DKY is set
+C  to the K-th derivative of this polynomial at T.
+C  The formula for DKY is:
+C               q
+C   DKY(i)  =  sum  c(j,K) * (T - tn)**(j-K) * h**(-j) * YH(i,j+1)
+C              j=K
+C  where  c(j,K) = j*(j-1)*...*(j-K+1), q = NQCUR, tn = TCUR, h = HCUR.
+C  The quantities  nq = NQCUR, l = nq+1, N = NEQ, tn, and h are
+C  communicated by COMMON.  The above sum is done in reverse order.
+C  IFLAG is returned negative if either K or T is out of bounds.
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  XERRWV
+C***COMMON BLOCKS    SLS001
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890503  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C   010412  Reduced size of Common block /SLS001/. (ACH)
+C   031105  Restored 'own' variables to Common block /SLS001/, to
+C           enable interrupt/restart feature. (ACH)
+C   050427  Corrected roundoff decrement in TP. (ACH)
+C***END PROLOGUE  SINTDY
+C**End
+      INTEGER K, NYH, IFLAG
+      REAL T, YH, DKY
+      DIMENSION YH(NYH,*), DKY(*)
+      INTEGER IOWND, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     2   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     3   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      REAL ROWNS,
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      COMMON /SLS001/ ROWNS(209),
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     2   IOWND(6), IOWNS(6),
+     3   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     4   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, IC, J, JB, JB2, JJ, JJ1, JP1
+      REAL C, R, S, TP
+      CHARACTER*80 MSG
+C
+C***FIRST EXECUTABLE STATEMENT  SINTDY
+      IFLAG = 0
+      IF (K .LT. 0 .OR. K .GT. NQ) GO TO 80
+      TP = TN - HU -  100.0E0*UROUND*SIGN(ABS(TN) + ABS(HU), HU)
+      IF ((T-TP)*(T-TN) .GT. 0.0E0) GO TO 90
+C
+      S = (T - TN)/H
+      IC = 1
+      IF (K .EQ. 0) GO TO 15
+      JJ1 = L - K
+      DO 10 JJ = JJ1,NQ
+ 10     IC = IC*JJ
+ 15   C = IC
+      DO 20 I = 1,N
+ 20     DKY(I) = C*YH(I,L)
+      IF (K .EQ. NQ) GO TO 55
+      JB2 = NQ - K
+      DO 50 JB = 1,JB2
+        J = NQ - JB
+        JP1 = J + 1
+        IC = 1
+        IF (K .EQ. 0) GO TO 35
+        JJ1 = JP1 - K
+        DO 30 JJ = JJ1,J
+ 30       IC = IC*JJ
+ 35     C = IC
+        DO 40 I = 1,N
+ 40       DKY(I) = C*YH(I,JP1) + S*DKY(I)
+ 50     CONTINUE
+      IF (K .EQ. 0) RETURN
+ 55   R = H**(-K)
+      DO 60 I = 1,N
+ 60     DKY(I) = R*DKY(I)
+      RETURN
+C
+ 80   CALL XERRWD('SINTDY-  K (=I1) illegal      ', 
+     1     30, 51, 0, 1, K, 0, 0, 0.0E0, 0.0E0)
+      IFLAG = -1
+      RETURN
+ 90   CALL XERRWD('SINTDY-  T (=R1) illegal      ', 
+     1     30, 52, 0, 0, 0, 0, 1, T, 0.0E0)
+      CALL XERRWD(
+     1   '      T not in interval TCUR - HU (= R1) to TCUR (=R2)      ',
+     1    60, 52, 0, 0, 0, 0, 2, TP, TN)
+      IFLAG = -2
+      RETURN
+C----------------------- END OF SUBROUTINE SINTDY ----------------------
+      END
diff --git a/libcruft/odepack/slsode.f b/libcruft/odepack/slsode.f
new file mode 100644
index 0000000..7c3d688
--- /dev/null
+++ b/libcruft/odepack/slsode.f
@@ -0,0 +1,1757 @@
+*DECK SLSODE
+      SUBROUTINE SLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
+     1                  ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)
+      EXTERNAL F, JAC
+      INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
+      REAL Y, T, TOUT, RTOL, ATOL, RWORK
+      DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW)
+C***BEGIN PROLOGUE  SLSODE
+C***PURPOSE  Livermore Solver for Ordinary Differential Equations.
+C            SLSODE solves the initial-value problem for stiff or
+C            nonstiff systems of first-order ODE's,
+C               dy/dt = f(t,y),   or, in component form,
+C               dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(N)),  i=1,...,N.
+C***CATEGORY  I1A
+C***TYPE      SINGLE PRECISION (SLSODE-S, DLSODE-D)
+C***KEYWORDS  ORDINARY DIFFERENTIAL EQUATIONS, INITIAL VALUE PROBLEM,
+C             STIFF, NONSTIFF
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C             Center for Applied Scientific Computing, L-561
+C             Lawrence Livermore National Laboratory
+C             Livermore, CA 94551.
+C***DESCRIPTION
+C
+C     NOTE: The "Usage" and "Arguments" sections treat only a subset of
+C           available options, in condensed fashion.  The options
+C           covered and the information supplied will support most
+C           standard uses of SLSODE.
+C
+C           For more sophisticated uses, full details on all options are
+C           given in the concluding section, headed "Long Description."
+C           A synopsis of the SLSODE Long Description is provided at the
+C           beginning of that section; general topics covered are:
+C           - Elements of the call sequence; optional input and output
+C           - Optional supplemental routines in the SLSODE package
+C           - internal COMMON block
+C
+C *Usage:
+C     Communication between the user and the SLSODE package, for normal
+C     situations, is summarized here.  This summary describes a subset
+C     of the available options.  See "Long Description" for complete
+C     details, including optional communication, nonstandard options,
+C     and instructions for special situations.
+C
+C     A sample program is given in the "Examples" section.
+C
+C     Refer to the argument descriptions for the definitions of the
+C     quantities that appear in the following sample declarations.
+C
+C     For MF = 10,
+C        PARAMETER  (LRW = 20 + 16*NEQ,           LIW = 20)
+C     For MF = 21 or 22,
+C        PARAMETER  (LRW = 22 +  9*NEQ + NEQ**2,  LIW = 20 + NEQ)
+C     For MF = 24 or 25,
+C        PARAMETER  (LRW = 22 + 10*NEQ + (2*ML+MU)*NEQ,
+C       *                                         LIW = 20 + NEQ)
+C
+C        EXTERNAL F, JAC
+C        INTEGER  NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK(LIW),
+C       *         LIW, MF
+C        REAL Y(NEQ), T, TOUT, RTOL, ATOL(ntol), RWORK(LRW)
+C
+C        CALL SLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
+C       *            ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)
+C
+C *Arguments:
+C     F     :EXT    Name of subroutine for right-hand-side vector f.
+C                   This name must be declared EXTERNAL in calling
+C                   program.  The form of F must be:
+C
+C                   SUBROUTINE  F (NEQ, T, Y, YDOT)
+C                   INTEGER  NEQ
+C                   REAL T, Y(*), YDOT(*)
+C
+C                   The inputs are NEQ, T, Y.  F is to set
+C
+C                   YDOT(i) = f(i,T,Y(1),Y(2),...,Y(NEQ)),
+C                                                     i = 1, ..., NEQ .
+C
+C     NEQ   :IN     Number of first-order ODE's.
+C
+C     Y     :INOUT  Array of values of the y(t) vector, of length NEQ.
+C                   Input:  For the first call, Y should contain the
+C                           values of y(t) at t = T. (Y is an input
+C                           variable only if ISTATE = 1.)
+C                   Output: On return, Y will contain the values at the
+C                           new t-value.
+C
+C     T     :INOUT  Value of the independent variable.  On return it
+C                   will be the current value of t (normally TOUT).
+C
+C     TOUT  :IN     Next point where output is desired (.NE. T).
+C
+C     ITOL  :IN     1 or 2 according as ATOL (below) is a scalar or
+C                   an array.
+C
+C     RTOL  :IN     Relative tolerance parameter (scalar).
+C
+C     ATOL  :IN     Absolute tolerance parameter (scalar or array).
+C                   If ITOL = 1, ATOL need not be dimensioned.
+C                   If ITOL = 2, ATOL must be dimensioned at least NEQ.
+C
+C                   The estimated local error in Y(i) will be controlled
+C                   so as to be roughly less (in magnitude) than
+C
+C                   EWT(i) = RTOL*ABS(Y(i)) + ATOL     if ITOL = 1, or
+C                   EWT(i) = RTOL*ABS(Y(i)) + ATOL(i)  if ITOL = 2.
+C
+C                   Thus the local error test passes if, in each
+C                   component, either the absolute error is less than
+C                   ATOL (or ATOL(i)), or the relative error is less
+C                   than RTOL.
+C
+C                   Use RTOL = 0.0 for pure absolute error control, and
+C                   use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative
+C                   error control.  Caution:  Actual (global) errors may
+C                   exceed these local tolerances, so choose them
+C                   conservatively.
+C
+C     ITASK :IN     Flag indicating the task SLSODE is to perform.
+C                   Use ITASK = 1 for normal computation of output
+C                   values of y at t = TOUT.
+C
+C     ISTATE:INOUT  Index used for input and output to specify the state
+C                   of the calculation.
+C                   Input:
+C                    1   This is the first call for a problem.
+C                    2   This is a subsequent call.
+C                   Output:
+C                    1   Nothing was done, as TOUT was equal to T.
+C                    2   SLSODE was successful (otherwise, negative).
+C                        Note that ISTATE need not be modified after a
+C                        successful return.
+C                   -1   Excess work done on this call (perhaps wrong
+C                        MF).
+C                   -2   Excess accuracy requested (tolerances too
+C                        small).
+C                   -3   Illegal input detected (see printed message).
+C                   -4   Repeated error test failures (check all
+C                        inputs).
+C                   -5   Repeated convergence failures (perhaps bad
+C                        Jacobian supplied or wrong choice of MF or
+C                        tolerances).
+C                   -6   Error weight became zero during problem
+C                        (solution component i vanished, and ATOL or
+C                        ATOL(i) = 0.).
+C
+C     IOPT  :IN     Flag indicating whether optional inputs are used:
+C                   0   No.
+C                   1   Yes.  (See "Optional inputs" under "Long
+C                       Description," Part 1.)
+C
+C     RWORK :WORK   Real work array of length at least:
+C                   20 + 16*NEQ                    for MF = 10,
+C                   22 +  9*NEQ + NEQ**2           for MF = 21 or 22,
+C                   22 + 10*NEQ + (2*ML + MU)*NEQ  for MF = 24 or 25.
+C
+C     LRW   :IN     Declared length of RWORK (in user's DIMENSION
+C                   statement).
+C
+C     IWORK :WORK   Integer work array of length at least:
+C                   20        for MF = 10,
+C                   20 + NEQ  for MF = 21, 22, 24, or 25.
+C
+C                   If MF = 24 or 25, input in IWORK(1),IWORK(2) the
+C                   lower and upper Jacobian half-bandwidths ML,MU.
+C
+C                   On return, IWORK contains information that may be
+C                   of interest to the user:
+C
+C            Name   Location   Meaning
+C            -----  ---------  -----------------------------------------
+C            NST    IWORK(11)  Number of steps taken for the problem so
+C                              far.
+C            NFE    IWORK(12)  Number of f evaluations for the problem
+C                              so far.
+C            NJE    IWORK(13)  Number of Jacobian evaluations (and of
+C                              matrix LU decompositions) for the problem
+C                              so far.
+C            NQU    IWORK(14)  Method order last used (successfully).
+C            LENRW  IWORK(17)  Length of RWORK actually required.  This
+C                              is defined on normal returns and on an
+C                              illegal input return for insufficient
+C                              storage.
+C            LENIW  IWORK(18)  Length of IWORK actually required.  This
+C                              is defined on normal returns and on an
+C                              illegal input return for insufficient
+C                              storage.
+C
+C     LIW   :IN     Declared length of IWORK (in user's DIMENSION
+C                   statement).
+C
+C     JAC   :EXT    Name of subroutine for Jacobian matrix (MF =
+C                   21 or 24).  If used, this name must be declared
+C                   EXTERNAL in calling program.  If not used, pass a
+C                   dummy name.  The form of JAC must be:
+C
+C                   SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
+C                   INTEGER NEQ, ML, MU, NROWPD
+C                   REAL T, Y(*), PD(NROWPD,*)
+C
+C                   See item c, under "Description" below for more
+C                   information about JAC.
+C
+C     MF    :IN     Method flag.  Standard values are:
+C                   10  Nonstiff (Adams) method, no Jacobian used.
+C                   21  Stiff (BDF) method, user-supplied full Jacobian.
+C                   22  Stiff method, internally generated full
+C                       Jacobian.
+C                   24  Stiff method, user-supplied banded Jacobian.
+C                   25  Stiff method, internally generated banded
+C                       Jacobian.
+C
+C *Description:
+C     SLSODE solves the initial value problem for stiff or nonstiff
+C     systems of first-order ODE's,
+C
+C        dy/dt = f(t,y) ,
+C
+C     or, in component form,
+C
+C        dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ))
+C                                                  (i = 1, ..., NEQ) .
+C
+C     SLSODE is a package based on the GEAR and GEARB packages, and on
+C     the October 23, 1978, version of the tentative ODEPACK user
+C     interface standard, with minor modifications.
+C
+C     The steps in solving such a problem are as follows.
+C
+C     a. First write a subroutine of the form
+C
+C           SUBROUTINE  F (NEQ, T, Y, YDOT)
+C           INTEGER  NEQ
+C           REAL T, Y(*), YDOT(*)
+C
+C        which supplies the vector function f by loading YDOT(i) with
+C        f(i).
+C
+C     b. Next determine (or guess) whether or not the problem is stiff.
+C        Stiffness occurs when the Jacobian matrix df/dy has an
+C        eigenvalue whose real part is negative and large in magnitude
+C        compared to the reciprocal of the t span of interest.  If the
+C        problem is nonstiff, use method flag MF = 10.  If it is stiff,
+C        there are four standard choices for MF, and SLSODE requires the
+C        Jacobian matrix in some form.  This matrix is regarded either
+C        as full (MF = 21 or 22), or banded (MF = 24 or 25).  In the
+C        banded case, SLSODE requires two half-bandwidth parameters ML
+C        and MU. These are, respectively, the widths of the lower and
+C        upper parts of the band, excluding the main diagonal.  Thus the
+C        band consists of the locations (i,j) with
+C
+C           i - ML <= j <= i + MU ,
+C
+C        and the full bandwidth is ML + MU + 1 .
+C
+C     c. If the problem is stiff, you are encouraged to supply the
+C        Jacobian directly (MF = 21 or 24), but if this is not feasible,
+C        SLSODE will compute it internally by difference quotients (MF =
+C        22 or 25).  If you are supplying the Jacobian, write a
+C        subroutine of the form
+C
+C           SUBROUTINE  JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
+C           INTEGER  NEQ, ML, MU, NRWOPD
+C           REAL T, Y(*), PD(NROWPD,*)
+C
+C        which provides df/dy by loading PD as follows:
+C        - For a full Jacobian (MF = 21), load PD(i,j) with df(i)/dy(j),
+C          the partial derivative of f(i) with respect to y(j).  (Ignore
+C          the ML and MU arguments in this case.)
+C        - For a banded Jacobian (MF = 24), load PD(i-j+MU+1,j) with
+C          df(i)/dy(j); i.e., load the diagonal lines of df/dy into the
+C          rows of PD from the top down.
+C        - In either case, only nonzero elements need be loaded.
+C
+C     d. Write a main program that calls subroutine SLSODE once for each
+C        point at which answers are desired.  This should also provide
+C        for possible use of logical unit 6 for output of error messages
+C        by SLSODE.
+C
+C        Before the first call to SLSODE, set ISTATE = 1, set Y and T to
+C        the initial values, and set TOUT to the first output point.  To
+C        continue the integration after a successful return, simply
+C        reset TOUT and call SLSODE again.  No other parameters need be
+C        reset.
+C
+C *Examples:
+C     The following is a simple example problem, with the coding needed
+C     for its solution by SLSODE. The problem is from chemical kinetics,
+C     and consists of the following three rate equations:
+C
+C        dy1/dt = -.04*y1 + 1.E4*y2*y3
+C        dy2/dt = .04*y1 - 1.E4*y2*y3 - 3.E7*y2**2
+C        dy3/dt = 3.E7*y2**2
+C
+C     on the interval from t = 0.0 to t = 4.E10, with initial conditions
+C     y1 = 1.0, y2 = y3 = 0. The problem is stiff.
+C
+C     The following coding solves this problem with SLSODE, using 
+C     MF = 21 and printing results at t = .4, 4., ..., 4.E10.  It uses 
+C     ITOL = 2 and ATOL much smaller for y2 than for y1 or y3 because y2 
+C     has much smaller values.  At the end of the run, statistical 
+C     quantities of interest are printed.
+C
+C        EXTERNAL  FEX, JEX
+C        INTEGER  IOPT, IOUT, ISTATE, ITASK, ITOL, IWORK(23), LIW, LRW,
+C       *         MF, NEQ
+C        REAL  ATOL(3), RTOL, RWORK(58), T, TOUT, Y(3)
+C        NEQ = 3
+C        Y(1) = 1.
+C        Y(2) = 0.
+C        Y(3) = 0.
+C        T = 0.
+C        TOUT = .4
+C        ITOL = 2
+C        RTOL = 1.E-4
+C        ATOL(1) = 1.E-6
+C        ATOL(2) = 1.E-10
+C        ATOL(3) = 1.E-6
+C        ITASK = 1
+C        ISTATE = 1
+C        IOPT = 0
+C        LRW = 58
+C        LIW = 23
+C        MF = 21
+C        DO 40 IOUT = 1,12
+C          CALL SLSODE (FEX, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
+C       *               ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JEX, MF)
+C          WRITE(6,20)  T, Y(1), Y(2), Y(3)
+C    20    FORMAT(' At t =',E12.4,'   y =',3E14.6)
+C          IF (ISTATE .LT. 0)  GO TO 80
+C    40    TOUT = TOUT*10.
+C        WRITE(6,60)  IWORK(11), IWORK(12), IWORK(13)
+C    60  FORMAT(/' No. steps =',i4,',  No. f-s =',i4,',  No. J-s =',i4)
+C        STOP
+C    80  WRITE(6,90)  ISTATE
+C    90  FORMAT(///' Error halt.. ISTATE =',I3)
+C        STOP
+C        END
+C
+C        SUBROUTINE  FEX (NEQ, T, Y, YDOT)
+C        INTEGER  NEQ
+C        REAL  T, Y(3), YDOT(3)
+C        YDOT(1) = -.04*Y(1) + 1.E4*Y(2)*Y(3)
+C        YDOT(3) = 3.E7*Y(2)*Y(2)
+C        YDOT(2) = -YDOT(1) - YDOT(3)
+C        RETURN
+C        END
+C
+C        SUBROUTINE  JEX (NEQ, T, Y, ML, MU, PD, NRPD)
+C        INTEGER  NEQ, ML, MU, NRPD
+C        REAL  T, Y(3), PD(NRPD,3)
+C        PD(1,1) = -.04
+C        PD(1,2) = 1.E4*Y(3)
+C        PD(1,3) = 1.E4*Y(2)
+C        PD(2,1) = .04
+C        PD(2,3) = -PD(1,3)
+C        PD(3,2) = 6.E7*Y(2)
+C        PD(2,2) = -PD(1,2) - PD(3,2)
+C        RETURN
+C        END
+C
+C     The output from this program (on a Cray-1 in single precision)
+C     is as follows.
+C
+C     At t =  4.0000e-01   y =  9.851726e-01  3.386406e-05  1.479357e-02
+C     At t =  4.0000e+00   y =  9.055142e-01  2.240418e-05  9.446344e-02
+C     At t =  4.0000e+01   y =  7.158050e-01  9.184616e-06  2.841858e-01
+C     At t =  4.0000e+02   y =  4.504846e-01  3.222434e-06  5.495122e-01
+C     At t =  4.0000e+03   y =  1.831701e-01  8.940379e-07  8.168290e-01
+C     At t =  4.0000e+04   y =  3.897016e-02  1.621193e-07  9.610297e-01
+C     At t =  4.0000e+05   y =  4.935213e-03  1.983756e-08  9.950648e-01
+C     At t =  4.0000e+06   y =  5.159269e-04  2.064759e-09  9.994841e-01
+C     At t =  4.0000e+07   y =  5.306413e-05  2.122677e-10  9.999469e-01
+C     At t =  4.0000e+08   y =  5.494530e-06  2.197825e-11  9.999945e-01
+C     At t =  4.0000e+09   y =  5.129458e-07  2.051784e-12  9.999995e-01
+C     At t =  4.0000e+10   y = -7.170603e-08 -2.868241e-13  1.000000e+00
+C
+C     No. steps = 330,  No. f-s = 405,  No. J-s = 69
+C
+C *Accuracy:
+C     The accuracy of the solution depends on the choice of tolerances
+C     RTOL and ATOL.  Actual (global) errors may exceed these local
+C     tolerances, so choose them conservatively.
+C
+C *Cautions:
+C     The work arrays should not be altered between calls to SLSODE for
+C     the same problem, except possibly for the conditional and optional
+C     inputs.
+C
+C *Portability:
+C     Since NEQ is dimensioned inside SLSODE, some compilers may object
+C     to a call to SLSODE with NEQ a scalar variable.  In this event, 
+C     use DIMENSION NEQ(1).  Similar remarks apply to RTOL and ATOL.
+C
+C     Note to Cray users:
+C     For maximum efficiency, use the CFT77 compiler.  Appropriate
+C     compiler optimization directives have been inserted for CFT77.
+C
+C *Reference:
+C     Alan C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE
+C     Solvers," in Scientific Computing, R. S. Stepleman, et al., Eds.
+C     (North-Holland, Amsterdam, 1983), pp. 55-64.
+C
+C *Long Description:
+C     The following complete description of the user interface to
+C     SLSODE consists of four parts:
+C
+C     1.  The call sequence to subroutine SLSODE, which is a driver
+C         routine for the solver.  This includes descriptions of both
+C         the call sequence arguments and user-supplied routines.
+C         Following these descriptions is a description of optional
+C         inputs available through the call sequence, and then a
+C         description of optional outputs in the work arrays.
+C
+C     2.  Descriptions of other routines in the SLSODE package that may
+C         be (optionally) called by the user.  These provide the ability
+C         to alter error message handling, save and restore the internal
+C         COMMON, and obtain specified derivatives of the solution y(t).
+C
+C     3.  Descriptions of COMMON block to be declared in overlay or
+C         similar environments, or to be saved when doing an interrupt
+C         of the problem and continued solution later.
+C
+C     4.  Description of two routines in the SLSODE package, either of
+C         which the user may replace with his own version, if desired.
+C         These relate to the measurement of errors.
+C
+C
+C                         Part 1.  Call Sequence
+C                         ----------------------
+C
+C     Arguments
+C     ---------
+C     The call sequence parameters used for input only are
+C
+C        F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, MF,
+C
+C     and those used for both input and output are
+C
+C        Y, T, ISTATE.
+C
+C     The work arrays RWORK and IWORK are also used for conditional and
+C     optional inputs and optional outputs.  (The term output here
+C     refers to the return from subroutine SLSODE to the user's calling
+C     program.)
+C
+C     The legality of input parameters will be thoroughly checked on the
+C     initial call for the problem, but not checked thereafter unless a
+C     change in input parameters is flagged by ISTATE = 3 on input.
+C
+C     The descriptions of the call arguments are as follows.
+C
+C     F        The name of the user-supplied subroutine defining the ODE
+C              system.  The system must be put in the first-order form
+C              dy/dt = f(t,y), where f is a vector-valued function of
+C              the scalar t and the vector y. Subroutine F is to compute
+C              the function f. It is to have the form
+C
+C                 SUBROUTINE F (NEQ, T, Y, YDOT)
+C                 REAL T, Y(*), YDOT(*)
+C
+C              where NEQ, T, and Y are input, and the array YDOT =
+C              f(T,Y) is output.  Y and YDOT are arrays of length NEQ.
+C              Subroutine F should not alter Y(1),...,Y(NEQ).  F must be
+C              declared EXTERNAL in the calling program.
+C
+C              Subroutine F may access user-defined quantities in
+C              NEQ(2),... and/or in Y(NEQ(1)+1),..., if NEQ is an array
+C              (dimensioned in F) and/or Y has length exceeding NEQ(1).
+C              See the descriptions of NEQ and Y below.
+C
+C              If quantities computed in the F routine are needed
+C              externally to SLSODE, an extra call to F should be made
+C              for this purpose, for consistent and accurate results.
+C              If only the derivative dy/dt is needed, use SINTDY
+C              instead.
+C
+C     NEQ      The size of the ODE system (number of first-order
+C              ordinary differential equations).  Used only for input.
+C              NEQ may be decreased, but not increased, during the
+C              problem.  If NEQ is decreased (with ISTATE = 3 on input),
+C              the remaining components of Y should be left undisturbed,
+C              if these are to be accessed in F and/or JAC.
+C
+C              Normally, NEQ is a scalar, and it is generally referred
+C              to as a scalar in this user interface description.
+C              However, NEQ may be an array, with NEQ(1) set to the
+C              system size.  (The SLSODE package accesses only NEQ(1).)
+C              In either case, this parameter is passed as the NEQ
+C              argument in all calls to F and JAC.  Hence, if it is an
+C              array, locations NEQ(2),... may be used to store other
+C              integer data and pass it to F and/or JAC.  Subroutines
+C              F and/or JAC must include NEQ in a DIMENSION statement
+C              in that case.
+C
+C     Y        A real array for the vector of dependent variables, of
+C              length NEQ or more.  Used for both input and output on
+C              the first call (ISTATE = 1), and only for output on
+C              other calls.  On the first call, Y must contain the
+C              vector of initial values.  On output, Y contains the
+C              computed solution vector, evaluated at T. If desired,
+C              the Y array may be used for other purposes between
+C              calls to the solver.
+C
+C              This array is passed as the Y argument in all calls to F
+C              and JAC.  Hence its length may exceed NEQ, and locations
+C              Y(NEQ+1),... may be used to store other real data and
+C              pass it to F and/or JAC.  (The SLSODE package accesses
+C              only Y(1),...,Y(NEQ).)
+C
+C     T        The independent variable.  On input, T is used only on
+C              the first call, as the initial point of the integration.
+C              On output, after each call, T is the value at which a
+C              computed solution Y is evaluated (usually the same as
+C              TOUT).  On an error return, T is the farthest point
+C              reached.
+C
+C     TOUT     The next value of T at which a computed solution is
+C              desired.  Used only for input.
+C
+C              When starting the problem (ISTATE = 1), TOUT may be equal
+C              to T for one call, then should not equal T for the next
+C              call.  For the initial T, an input value of TOUT .NE. T
+C              is used in order to determine the direction of the
+C              integration (i.e., the algebraic sign of the step sizes)
+C              and the rough scale of the problem.  Integration in
+C              either direction (forward or backward in T) is permitted.
+C
+C              If ITASK = 2 or 5 (one-step modes), TOUT is ignored
+C              after the first call (i.e., the first call with
+C              TOUT .NE. T).  Otherwise, TOUT is required on every call.
+C
+C              If ITASK = 1, 3, or 4, the values of TOUT need not be
+C              monotone, but a value of TOUT which backs up is limited
+C              to the current internal T interval, whose endpoints are
+C              TCUR - HU and TCUR.  (See "Optional Outputs" below for
+C              TCUR and HU.)
+C
+C
+C     ITOL     An indicator for the type of error control.  See
+C              description below under ATOL.  Used only for input.
+C
+C     RTOL     A relative error tolerance parameter, either a scalar or
+C              an array of length NEQ.  See description below under
+C              ATOL.  Input only.
+C
+C     ATOL     An absolute error tolerance parameter, either a scalar or
+C              an array of length NEQ.  Input only.
+C
+C              The input parameters ITOL, RTOL, and ATOL determine the
+C              error control performed by the solver.  The solver will
+C              control the vector e = (e(i)) of estimated local errors
+C              in Y, according to an inequality of the form
+C
+C                 rms-norm of ( e(i)/EWT(i) ) <= 1,
+C
+C              where
+C
+C                 EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
+C
+C              and the rms-norm (root-mean-square norm) here is
+C
+C                 rms-norm(v) = SQRT(sum v(i)**2 / NEQ).
+C
+C              Here EWT = (EWT(i)) is a vector of weights which must
+C              always be positive, and the values of RTOL and ATOL
+C              should all be nonnegative.  The following table gives the
+C              types (scalar/array) of RTOL and ATOL, and the
+C              corresponding form of EWT(i).
+C
+C              ITOL    RTOL      ATOL      EWT(i)
+C              ----    ------    ------    -----------------------------
+C              1       scalar    scalar    RTOL*ABS(Y(i)) + ATOL
+C              2       scalar    array     RTOL*ABS(Y(i)) + ATOL(i)
+C              3       array     scalar    RTOL(i)*ABS(Y(i)) + ATOL
+C              4       array     array     RTOL(i)*ABS(Y(i)) + ATOL(i)
+C
+C              When either of these parameters is a scalar, it need not
+C              be dimensioned in the user's calling program.
+C
+C              If none of the above choices (with ITOL, RTOL, and ATOL
+C              fixed throughout the problem) is suitable, more general
+C              error controls can be obtained by substituting
+C              user-supplied routines for the setting of EWT and/or for
+C              the norm calculation.  See Part 4 below.
+C
+C              If global errors are to be estimated by making a repeated
+C              run on the same problem with smaller tolerances, then all
+C              components of RTOL and ATOL (i.e., of EWT) should be
+C              scaled down uniformly.
+C
+C     ITASK    An index specifying the task to be performed.  Input
+C              only.  ITASK has the following values and meanings:
+C              1   Normal computation of output values of y(t) at
+C                  t = TOUT (by overshooting and interpolating).
+C              2   Take one step only and return.
+C              3   Stop at the first internal mesh point at or beyond
+C                  t = TOUT and return.
+C              4   Normal computation of output values of y(t) at
+C                  t = TOUT but without overshooting t = TCRIT.  TCRIT
+C                  must be input as RWORK(1).  TCRIT may be equal to or
+C                  beyond TOUT, but not behind it in the direction of
+C                  integration.  This option is useful if the problem
+C                  has a singularity at or beyond t = TCRIT.
+C              5   Take one step, without passing TCRIT, and return.
+C                  TCRIT must be input as RWORK(1).
+C
+C              Note:  If ITASK = 4 or 5 and the solver reaches TCRIT
+C              (within roundoff), it will return T = TCRIT (exactly) to
+C              indicate this (unless ITASK = 4 and TOUT comes before
+C              TCRIT, in which case answers at T = TOUT are returned
+C              first).
+C
+C     ISTATE   An index used for input and output to specify the state
+C              of the calculation.
+C
+C              On input, the values of ISTATE are as follows:
+C              1   This is the first call for the problem
+C                  (initializations will be done).  See "Note" below.
+C              2   This is not the first call, and the calculation is to
+C                  continue normally, with no change in any input
+C                  parameters except possibly TOUT and ITASK.  (If ITOL,
+C                  RTOL, and/or ATOL are changed between calls with
+C                  ISTATE = 2, the new values will be used but not
+C                  tested for legality.)
+C              3   This is not the first call, and the calculation is to
+C                  continue normally, but with a change in input
+C                  parameters other than TOUT and ITASK.  Changes are
+C                  allowed in NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF,
+C                  ML, MU, and any of the optional inputs except H0.
+C                  (See IWORK description for ML and MU.)
+C
+C              Note:  A preliminary call with TOUT = T is not counted as
+C              a first call here, as no initialization or checking of
+C              input is done.  (Such a call is sometimes useful for the
+C              purpose of outputting the initial conditions.)  Thus the
+C              first call for which TOUT .NE. T requires ISTATE = 1 on
+C              input.
+C
+C              On output, ISTATE has the following values and meanings:
+C               1  Nothing was done, as TOUT was equal to T with
+C                  ISTATE = 1 on input.
+C               2  The integration was performed successfully.
+C              -1  An excessive amount of work (more than MXSTEP steps)
+C                  was done on this call, before completing the
+C                  requested task, but the integration was otherwise
+C                  successful as far as T. (MXSTEP is an optional input
+C                  and is normally 500.)  To continue, the user may
+C                  simply reset ISTATE to a value >1 and call again (the
+C                  excess work step counter will be reset to 0).  In
+C                  addition, the user may increase MXSTEP to avoid this
+C                  error return; see "Optional Inputs" below.
+C              -2  Too much accuracy was requested for the precision of
+C                  the machine being used.  This was detected before
+C                  completing the requested task, but the integration
+C                  was successful as far as T. To continue, the
+C                  tolerance parameters must be reset, and ISTATE must
+C                  be set to 3. The optional output TOLSF may be used
+C                  for this purpose.  (Note:  If this condition is
+C                  detected before taking any steps, then an illegal
+C                  input return (ISTATE = -3) occurs instead.)
+C              -3  Illegal input was detected, before taking any
+C                  integration steps.  See written message for details.
+C                  (Note:  If the solver detects an infinite loop of
+C                  calls to the solver with illegal input, it will cause
+C                  the run to stop.)
+C              -4  There were repeated error-test failures on one
+C                  attempted step, before completing the requested task,
+C                  but the integration was successful as far as T.  The
+C                  problem may have a singularity, or the input may be
+C                  inappropriate.
+C              -5  There were repeated convergence-test failures on one
+C                  attempted step, before completing the requested task,
+C                  but the integration was successful as far as T. This
+C                  may be caused by an inaccurate Jacobian matrix, if
+C                  one is being used.
+C              -6  EWT(i) became zero for some i during the integration.
+C                  Pure relative error control (ATOL(i)=0.0) was
+C                  requested on a variable which has now vanished.  The
+C                  integration was successful as far as T.
+C
+C              Note:  Since the normal output value of ISTATE is 2, it
+C              does not need to be reset for normal continuation.  Also,
+C              since a negative input value of ISTATE will be regarded
+C              as illegal, a negative output value requires the user to
+C              change it, and possibly other inputs, before calling the
+C              solver again.
+C
+C     IOPT     An integer flag to specify whether any optional inputs
+C              are being used on this call.  Input only.  The optional
+C              inputs are listed under a separate heading below.
+C              0   No optional inputs are being used.  Default values
+C                  will be used in all cases.
+C              1   One or more optional inputs are being used.
+C
+C     RWORK    A real working array (single precision).  The length of
+C              RWORK must be at least
+C
+C                 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM
+C
+C              where
+C                 NYH = the initial value of NEQ,
+C              MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
+C                       smaller value is given as an optional input),
+C                 LWM = 0           if MITER = 0,
+C                 LWM = NEQ**2 + 2  if MITER = 1 or 2,
+C                 LWM = NEQ + 2     if MITER = 3, and
+C                 LWM = (2*ML + MU + 1)*NEQ + 2
+C                                   if MITER = 4 or 5.
+C              (See the MF description below for METH and MITER.)
+C
+C              Thus if MAXORD has its default value and NEQ is constant,
+C              this length is:
+C              20 + 16*NEQ                    for MF = 10,
+C              22 + 16*NEQ + NEQ**2           for MF = 11 or 12,
+C              22 + 17*NEQ                    for MF = 13,
+C              22 + 17*NEQ + (2*ML + MU)*NEQ  for MF = 14 or 15,
+C              20 +  9*NEQ                    for MF = 20,
+C              22 +  9*NEQ + NEQ**2           for MF = 21 or 22,
+C              22 + 10*NEQ                    for MF = 23,
+C              22 + 10*NEQ + (2*ML + MU)*NEQ  for MF = 24 or 25.
+C
+C              The first 20 words of RWORK are reserved for conditional
+C              and optional inputs and optional outputs.
+C
+C              The following word in RWORK is a conditional input:
+C              RWORK(1) = TCRIT, the critical value of t which the
+C                         solver is not to overshoot.  Required if ITASK
+C                         is 4 or 5, and ignored otherwise.  See ITASK.
+C
+C     LRW      The length of the array RWORK, as declared by the user.
+C              (This will be checked by the solver.)
+C
+C     IWORK    An integer work array.  Its length must be at least
+C              20       if MITER = 0 or 3 (MF = 10, 13, 20, 23), or
+C              20 + NEQ otherwise (MF = 11, 12, 14, 15, 21, 22, 24, 25).
+C              (See the MF description below for MITER.)  The first few
+C              words of IWORK are used for conditional and optional
+C              inputs and optional outputs.
+C
+C              The following two words in IWORK are conditional inputs:
+C              IWORK(1) = ML   These are the lower and upper half-
+C              IWORK(2) = MU   bandwidths, respectively, of the banded
+C                              Jacobian, excluding the main diagonal.
+C                         The band is defined by the matrix locations
+C                         (i,j) with i - ML <= j <= i + MU. ML and MU
+C                         must satisfy 0 <= ML,MU <= NEQ - 1. These are
+C                         required if MITER is 4 or 5, and ignored
+C                         otherwise.  ML and MU may in fact be the band
+C                         parameters for a matrix to which df/dy is only
+C                         approximately equal.
+C
+C     LIW      The length of the array IWORK, as declared by the user.
+C              (This will be checked by the solver.)
+C
+C     Note:  The work arrays must not be altered between calls to SLSODE
+C     for the same problem, except possibly for the conditional and
+C     optional inputs, and except for the last 3*NEQ words of RWORK.
+C     The latter space is used for internal scratch space, and so is
+C     available for use by the user outside SLSODE between calls, if
+C     desired (but not for use by F or JAC).
+C
+C     JAC      The name of the user-supplied routine (MITER = 1 or 4) to
+C              compute the Jacobian matrix, df/dy, as a function of the
+C              scalar t and the vector y.  (See the MF description below
+C              for MITER.)  It is to have the form
+C
+C                 SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
+C                 REAL T, Y(*), PD(NROWPD,*)
+C
+C              where NEQ, T, Y, ML, MU, and NROWPD are input and the
+C              array PD is to be loaded with partial derivatives
+C              (elements of the Jacobian matrix) on output.  PD must be
+C              given a first dimension of NROWPD.  T and Y have the same
+C              meaning as in subroutine F.
+C
+C              In the full matrix case (MITER = 1), ML and MU are
+C              ignored, and the Jacobian is to be loaded into PD in
+C              columnwise manner, with df(i)/dy(j) loaded into PD(i,j).
+C
+C              In the band matrix case (MITER = 4), the elements within
+C              the band are to be loaded into PD in columnwise manner,
+C              with diagonal lines of df/dy loaded into the rows of PD.
+C              Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j).  ML
+C              and MU are the half-bandwidth parameters (see IWORK).
+C              The locations in PD in the two triangular areas which
+C              correspond to nonexistent matrix elements can be ignored
+C              or loaded arbitrarily, as they are overwritten by SLSODE.
+C
+C              JAC need not provide df/dy exactly. A crude approximation
+C              (possibly with a smaller bandwidth) will do.
+C
+C              In either case, PD is preset to zero by the solver, so
+C              that only the nonzero elements need be loaded by JAC.
+C              Each call to JAC is preceded by a call to F with the same
+C              arguments NEQ, T, and Y. Thus to gain some efficiency,
+C              intermediate quantities shared by both calculations may
+C              be saved in a user COMMON block by F and not recomputed
+C              by JAC, if desired.  Also, JAC may alter the Y array, if
+C              desired.  JAC must be declared EXTERNAL in the calling
+C              program.
+C
+C              Subroutine JAC may access user-defined quantities in
+C              NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
+C              (dimensioned in JAC) and/or Y has length exceeding
+C              NEQ(1).  See the descriptions of NEQ and Y above.
+C
+C     MF       The method flag.  Used only for input.  The legal values
+C              of MF are 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24,
+C              and 25.  MF has decimal digits METH and MITER:
+C                 MF = 10*METH + MITER .
+C
+C              METH indicates the basic linear multistep method:
+C              1   Implicit Adams method.
+C              2   Method based on backward differentiation formulas
+C                  (BDF's).
+C
+C              MITER indicates the corrector iteration method:
+C              0   Functional iteration (no Jacobian matrix is
+C                  involved).
+C              1   Chord iteration with a user-supplied full (NEQ by
+C                  NEQ) Jacobian.
+C              2   Chord iteration with an internally generated
+C                  (difference quotient) full Jacobian (using NEQ
+C                  extra calls to F per df/dy value).
+C              3   Chord iteration with an internally generated
+C                  diagonal Jacobian approximation (using one extra call
+C                  to F per df/dy evaluation).
+C              4   Chord iteration with a user-supplied banded Jacobian.
+C              5   Chord iteration with an internally generated banded
+C                  Jacobian (using ML + MU + 1 extra calls to F per
+C                  df/dy evaluation).
+C
+C              If MITER = 1 or 4, the user must supply a subroutine JAC
+C              (the name is arbitrary) as described above under JAC.
+C              For other values of MITER, a dummy argument can be used.
+C
+C     Optional Inputs
+C     ---------------
+C     The following is a list of the optional inputs provided for in the
+C     call sequence.  (See also Part 2.)  For each such input variable,
+C     this table lists its name as used in this documentation, its
+C     location in the call sequence, its meaning, and the default value.
+C     The use of any of these inputs requires IOPT = 1, and in that case
+C     all of these inputs are examined.  A value of zero for any of
+C     these optional inputs will cause the default value to be used.
+C     Thus to use a subset of the optional inputs, simply preload
+C     locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively,
+C     and then set those of interest to nonzero values.
+C
+C     Name    Location   Meaning and default value
+C     ------  ---------  -----------------------------------------------
+C     H0      RWORK(5)   Step size to be attempted on the first step.
+C                        The default value is determined by the solver.
+C     HMAX    RWORK(6)   Maximum absolute step size allowed.  The
+C                        default value is infinite.
+C     HMIN    RWORK(7)   Minimum absolute step size allowed.  The
+C                        default value is 0.  (This lower bound is not
+C                        enforced on the final step before reaching
+C                        TCRIT when ITASK = 4 or 5.)
+C     MAXORD  IWORK(5)   Maximum order to be allowed.  The default value
+C                        is 12 if METH = 1, and 5 if METH = 2. (See the
+C                        MF description above for METH.)  If MAXORD
+C                        exceeds the default value, it will be reduced
+C                        to the default value.  If MAXORD is changed
+C                        during the problem, it may cause the current
+C                        order to be reduced.
+C     MXSTEP  IWORK(6)   Maximum number of (internally defined) steps
+C                        allowed during one call to the solver.  The
+C                        default value is 500.
+C     MXHNIL  IWORK(7)   Maximum number of messages printed (per
+C                        problem) warning that T + H = T on a step
+C                        (H = step size).  This must be positive to
+C                        result in a nondefault value.  The default
+C                        value is 10.
+C
+C     Optional Outputs
+C     ----------------
+C     As optional additional output from SLSODE, the variables listed
+C     below are quantities related to the performance of SLSODE which 
+C     are available to the user.  These are communicated by way of the
+C     work arrays, but also have internal mnemonic names as shown. 
+C     Except where stated otherwise, all of these outputs are defined on
+C     any successful return from SLSODE, and on any return with ISTATE =
+C     -1, -2, -4, -5, or -6.  On an illegal input return (ISTATE = -3),
+C     they will be unchanged from their existing values (if any), except
+C     possibly for TOLSF, LENRW, and LENIW.  On any error return,
+C     outputs relevant to the error will be defined, as noted below.
+C
+C     Name   Location   Meaning
+C     -----  ---------  ------------------------------------------------
+C     HU     RWORK(11)  Step size in t last used (successfully).
+C     HCUR   RWORK(12)  Step size to be attempted on the next step.
+C     TCUR   RWORK(13)  Current value of the independent variable which
+C                       the solver has actually reached, i.e., the
+C                       current internal mesh point in t. On output,
+C                       TCUR will always be at least as far as the
+C                       argument T, but may be farther (if interpolation
+C                       was done).
+C     TOLSF  RWORK(14)  Tolerance scale factor, greater than 1.0,
+C                       computed when a request for too much accuracy
+C                       was detected (ISTATE = -3 if detected at the
+C                       start of the problem, ISTATE = -2 otherwise).
+C                       If ITOL is left unaltered but RTOL and ATOL are
+C                       uniformly scaled up by a factor of TOLSF for the
+C                       next call, then the solver is deemed likely to
+C                       succeed.  (The user may also ignore TOLSF and
+C                       alter the tolerance parameters in any other way
+C                       appropriate.)
+C     NST    IWORK(11)  Number of steps taken for the problem so far.
+C     NFE    IWORK(12)  Number of F evaluations for the problem so far.
+C     NJE    IWORK(13)  Number of Jacobian evaluations (and of matrix LU
+C                       decompositions) for the problem so far.
+C     NQU    IWORK(14)  Method order last used (successfully).
+C     NQCUR  IWORK(15)  Order to be attempted on the next step.
+C     IMXER  IWORK(16)  Index of the component of largest magnitude in
+C                       the weighted local error vector ( e(i)/EWT(i) ),
+C                       on an error return with ISTATE = -4 or -5.
+C     LENRW  IWORK(17)  Length of RWORK actually required.  This is
+C                       defined on normal returns and on an illegal
+C                       input return for insufficient storage.
+C     LENIW  IWORK(18)  Length of IWORK actually required.  This is
+C                       defined on normal returns and on an illegal
+C                       input return for insufficient storage.
+C
+C     The following two arrays are segments of the RWORK array which may
+C     also be of interest to the user as optional outputs.  For each
+C     array, the table below gives its internal name, its base address
+C     in RWORK, and its description.
+C
+C     Name  Base address  Description
+C     ----  ------------  ----------------------------------------------
+C     YH    21            The Nordsieck history array, of size NYH by
+C                         (NQCUR + 1), where NYH is the initial value of
+C                         NEQ.  For j = 0,1,...,NQCUR, column j + 1 of
+C                         YH contains HCUR**j/factorial(j) times the jth
+C                         derivative of the interpolating polynomial
+C                         currently representing the solution, evaluated
+C                         at t = TCUR.
+C     ACOR  LENRW-NEQ+1   Array of size NEQ used for the accumulated
+C                         corrections on each step, scaled on output to
+C                         represent the estimated local error in Y on
+C                         the last step.  This is the vector e in the
+C                         description of the error control.  It is
+C                         defined only on successful return from SLSODE.
+C
+C
+C                    Part 2.  Other Callable Routines
+C                    --------------------------------
+C
+C     The following are optional calls which the user may make to gain
+C     additional capabilities in conjunction with SLSODE.
+C
+C     Form of call              Function
+C     ------------------------  ----------------------------------------
+C     CALL XSETUN(LUN)          Set the logical unit number, LUN, for
+C                               output of messages from SLSODE, if the
+C                               default is not desired.  The default
+C                               value of LUN is 6. This call may be made
+C                               at any time and will take effect
+C                               immediately.
+C     CALL XSETF(MFLAG)         Set a flag to control the printing of
+C                               messages by SLSODE.  MFLAG = 0 means do
+C                               not print.  (Danger:  this risks losing
+C                               valuable information.)  MFLAG = 1 means
+C                               print (the default).  This call may be
+C                               made at any time and will take effect
+C                               immediately.
+C     CALL SSRCOM(RSAV,ISAV,JOB)  Saves and restores the contents of the
+C                               internal COMMON blocks used by SLSODE
+C                               (see Part 3 below).  RSAV must be a
+C                               real array of length 218 or more, and
+C                               ISAV must be an integer array of length
+C                               37 or more.  JOB = 1 means save COMMON
+C                               into RSAV/ISAV.  JOB = 2 means restore
+C                               COMMON from same.  SSRCOM is useful if
+C                               one is interrupting a run and restarting
+C                               later, or alternating between two or
+C                               more problems solved with SLSODE.
+C     CALL SINTDY(,,,,,)        Provide derivatives of y, of various
+C     (see below)               orders, at a specified point t, if
+C                               desired.  It may be called only after a
+C                               successful return from SLSODE.  Detailed
+C                               instructions follow.
+C
+C     Detailed instructions for using SINTDY
+C     --------------------------------------
+C     The form of the CALL is:
+C
+C           CALL SINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)
+C
+C     The input parameters are:
+C
+C     T          Value of independent variable where answers are
+C                desired (normally the same as the T last returned by
+C                SLSODE).  For valid results, T must lie between
+C                TCUR - HU and TCUR.  (See "Optional Outputs" above
+C                for TCUR and HU.)
+C     K          Integer order of the derivative desired.  K must
+C                satisfy 0 <= K <= NQCUR, where NQCUR is the current
+C                order (see "Optional Outputs").  The capability
+C                corresponding to K = 0, i.e., computing y(t), is
+C                already provided by SLSODE directly.  Since
+C                NQCUR >= 1, the first derivative dy/dt is always
+C                available with SINTDY.
+C     RWORK(21)  The base address of the history array YH.
+C     NYH        Column length of YH, equal to the initial value of NEQ.
+C
+C     The output parameters are:
+C
+C     DKY        Real array of length NEQ containing the computed value
+C                of the Kth derivative of y(t).
+C     IFLAG      Integer flag, returned as 0 if K and T were legal,
+C                -1 if K was illegal, and -2 if T was illegal.
+C                On an error return, a message is also written.
+C
+C
+C                          Part 3.  Common Blocks
+C                          ----------------------
+C
+C     If SLSODE is to be used in an overlay situation, the user must
+C     declare, in the primary overlay, the variables in:
+C     (1) the call sequence to SLSODE,
+C     (2) the internal COMMON block /SLS001/, of length 255 
+C         (218 single precision words followed by 37 integer words).
+C
+C     If SLSODE is used on a system in which the contents of internal
+C     COMMON blocks are not preserved between calls, the user should
+C     declare the above COMMON block in his main program to insure that
+C     its contents are preserved.
+C
+C     If the solution of a given problem by SLSODE is to be interrupted
+C     and then later continued, as when restarting an interrupted run or
+C     alternating between two or more problems, the user should save,
+C     following the return from the last SLSODE call prior to the
+C     interruption, the contents of the call sequence variables and the
+C     internal COMMON block, and later restore these values before the
+C     next SLSODE call for that problem.   In addition, if XSETUN and/or
+C     XSETF was called for non-default handling of error messages, then
+C     these calls must be repeated.  To save and restore the COMMON
+C     block, use subroutine SSRCOM (see Part 2 above).
+C
+C
+C              Part 4.  Optionally Replaceable Solver Routines
+C              -----------------------------------------------
+C
+C     Below are descriptions of two routines in the SLSODE package which
+C     relate to the measurement of errors.  Either routine can be
+C     replaced by a user-supplied version, if desired.  However, since
+C     such a replacement may have a major impact on performance, it
+C     should be done only when absolutely necessary, and only with great
+C     caution.  (Note:  The means by which the package version of a
+C     routine is superseded by the user's version may be system-
+C     dependent.)
+C
+C     SEWSET
+C     ------
+C     The following subroutine is called just before each internal
+C     integration step, and sets the array of error weights, EWT, as
+C     described under ITOL/RTOL/ATOL above:
+C
+C           SUBROUTINE SEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
+C
+C     where NEQ, ITOL, RTOL, and ATOL are as in the SLSODE call
+C     sequence, YCUR contains the current dependent variable vector,
+C     and EWT is the array of weights set by SEWSET.
+C
+C     If the user supplies this subroutine, it must return in EWT(i)
+C     (i = 1,...,NEQ) a positive quantity suitable for comparing errors
+C     in Y(i) to.  The EWT array returned by SEWSET is passed to the
+C     SVNORM routine (see below), and also used by SLSODE in the
+C     computation of the optional output IMXER, the diagonal Jacobian
+C     approximation, and the increments for difference quotient
+C     Jacobians.
+C
+C     In the user-supplied version of SEWSET, it may be desirable to use
+C     the current values of derivatives of y. Derivatives up to order NQ
+C     are available from the history array YH, described above under
+C     optional outputs.  In SEWSET, YH is identical to the YCUR array,
+C     extended to NQ + 1 columns with a column length of NYH and scale
+C     factors of H**j/factorial(j).  On the first call for the problem,
+C     given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
+C     NYH is the initial value of NEQ.  The quantities NQ, H, and NST
+C     can be obtained by including in SEWSET the statements:
+C           REAL RLS
+C           COMMON /SLS001/ RLS(218),ILS(37)
+C           NQ = ILS(33)
+C           NST = ILS(34)
+C           H = RLS(212)
+C     Thus, for example, the current value of dy/dt can be obtained as
+C     YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is unnecessary
+C     when NST = 0).
+C
+C     SVNORM
+C     ------
+C     SVNORM is a real function routine which computes the weighted
+C     root-mean-square norm of a vector v:
+C
+C        d = SVNORM (n, v, w)
+C
+C     where:
+C     n = the length of the vector,
+C     v = real array of length n containing the vector,
+C     w = real array of length n containing weights,
+C     d = SQRT( (1/n) * sum(v(i)*w(i))**2 ).
+C
+C     SVNORM is called with n = NEQ and with w(i) = 1.0/EWT(i), where
+C     EWT is as set by subroutine SEWSET.
+C
+C     If the user supplies this function, it should return a nonnegative
+C     value of SVNORM suitable for use in the error control in SLSODE.
+C     None of the arguments should be altered by SVNORM.  For example, a
+C     user-supplied SVNORM routine might:
+C     - Substitute a max-norm of (v(i)*w(i)) for the rms-norm, or
+C     - Ignore some components of v in the norm, with the effect of
+C       suppressing the error control on those components of Y.
+C  ---------------------------------------------------------------------
+C***ROUTINES CALLED  SEWSET, SINTDY, D1MACH, SSTODE, SVNORM, XERRWD
+C***COMMON BLOCKS    SLS001
+C***REVISION HISTORY  (YYYYMMDD)
+C 19791129  DATE WRITTEN
+C 19791213  Minor changes to declarations; DELP init. in STODE.
+C 19800118  Treat NEQ as array; integer declarations added throughout;
+C           minor changes to prologue.
+C 19800306  Corrected TESCO(1,NQP1) setting in CFODE.
+C 19800519  Corrected access of YH on forced order reduction;
+C           numerous corrections to prologues and other comments.
+C 19800617  In main driver, added loading of SQRT(UROUND) in RWORK;
+C           minor corrections to main prologue.
+C 19800923  Added zero initialization of HU and NQU.
+C 19801218  Revised XERRWV routine; minor corrections to main prologue.
+C 19810401  Minor changes to comments and an error message.
+C 19810814  Numerous revisions: replaced EWT by 1/EWT; used flags
+C           JCUR, ICF, IERPJ, IERSL between STODE and subordinates;
+C           added tuning parameters CCMAX, MAXCOR, MSBP, MXNCF;
+C           reorganized returns from STODE; reorganized type decls.;
+C           fixed message length in XERRWV; changed default LUNIT to 6;
+C           changed Common lengths; changed comments throughout.
+C 19870330  Major update by ACH: corrected comments throughout;
+C           removed TRET from Common; rewrote EWSET with 4 loops;
+C           fixed t test in INTDY; added Cray directives in STODE;
+C           in STODE, fixed DELP init. and logic around PJAC call;
+C           combined routines to save/restore Common;
+C           passed LEVEL = 0 in error message calls (except run abort).
+C 19890426  Modified prologue to SLATEC/LDOC format.  (FNF)
+C 19890501  Many improvements to prologue.  (FNF)
+C 19890503  A few final corrections to prologue.  (FNF)
+C 19890504  Minor cosmetic changes.  (FNF)
+C 19890510  Corrected description of Y in Arguments section.  (FNF)
+C 19890517  Minor corrections to prologue.  (FNF)
+C 19920514  Updated with prologue edited 891025 by G. Shaw for manual.
+C 19920515  Converted source lines to upper case.  (FNF)
+C 19920603  Revised XERRWV calls using mixed upper-lower case.  (ACH)
+C 19920616  Revised prologue comment regarding CFT.  (ACH)
+C 19921116  Revised prologue comments regarding Common.  (ACH).
+C 19930326  Added comment about non-reentrancy.  (FNF)
+C 19930723  Changed R1MACH to RUMACH. (FNF)
+C 19930801  Removed ILLIN and NTREP from Common (affects driver logic);
+C           minor changes to prologue and internal comments;
+C           changed Hollerith strings to quoted strings; 
+C           changed internal comments to mixed case;
+C           replaced XERRWV with new version using character type;
+C           changed dummy dimensions from 1 to *. (ACH)
+C 19930809  Changed to generic intrinsic names; changed names of
+C           subprograms and Common blocks to SLSODE etc. (ACH)
+C 19930929  Eliminated use of REAL intrinsic; other minor changes. (ACH)
+C 20010412  Removed all 'own' variables from Common block /SLS001/
+C           (affects declarations in 6 routines). (ACH)
+C 20010509  Minor corrections to prologue. (ACH)
+C 20031105  Restored 'own' variables to Common block /SLS001/, to
+C           enable interrupt/restart feature. (ACH)
+C 20031112  Added SAVE statements for data-loaded constants.
+C
+C***  END PROLOGUE  SLSODE
+C
+C*Internal Notes:
+C
+C Other Routines in the SLSODE Package.
+C
+C In addition to Subroutine SLSODE, the SLSODE package includes the
+C following subroutines and function routines:
+C  SINTDY   computes an interpolated value of the y vector at t = TOUT.
+C  SSTODE   is the core integrator, which does one step of the
+C           integration and the associated error control.
+C  SCFODE   sets all method coefficients and test constants.
+C  SPREPJ   computes and preprocesses the Jacobian matrix J = df/dy
+C           and the Newton iteration matrix P = I - h*l0*J.
+C  SSOLSY   manages solution of linear system in chord iteration.
+C  SEWSET   sets the error weight vector EWT before each step.
+C  SVNORM   computes the weighted R.M.S. norm of a vector.
+C  SSRCOM   is a user-callable routine to save and restore
+C           the contents of the internal Common block.
+C  DGETRF AND DGETRS   ARE ROUTINES FROM LAPACK FOR SOLVING FULL
+C           SYSTEMS OF LINEAR ALGEBRAIC EQUATIONS.
+C  DGBTRF AND DGBTRS   ARE ROUTINES FROM LAPACK FOR SOLVING BANDED
+C           LINEAR SYSTEMS.
+C  D1MACH   computes the unit roundoff in a machine-independent manner.
+C  XERRWD, XSETUN, XSETF, IXSAV, IUMACH   handle the printing of all
+C           error messages and warnings.  XERRWD is machine-dependent.
+C Note: SVNORM, D1MACH, IXSAV, and IUMACH are function routines.
+C All the others are subroutines.
+C
+C**End
+C
+C  Declare externals.
+      EXTERNAL SPREPJ, SSOLSY
+      REAL D1MACH, SVNORM
+C
+C  Declare all other variables.
+      INTEGER INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     2   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     3   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, I1, I2, IFLAG, IMXER, KGO, LF0,
+     1   LENIW, LENRW, LENWM, ML, MORD, MU, MXHNL0, MXSTP0
+      REAL ROWNS,
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      REAL ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI,
+     1   TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
+      DIMENSION MORD(2)
+      LOGICAL IHIT
+      CHARACTER*80 MSG
+      SAVE MORD, MXSTP0, MXHNL0
+C-----------------------------------------------------------------------
+C The following internal Common block contains
+C (a) variables which are local to any subroutine but whose values must
+C     be preserved between calls to the routine ("own" variables), and
+C (b) variables which are communicated between subroutines.
+C The block SLS001 is declared in subroutines SLSODE, SINTDY, SSTODE,
+C SPREPJ, and SSOLSY.
+C Groups of variables are replaced by dummy arrays in the Common
+C declarations in routines where those variables are not used.
+C-----------------------------------------------------------------------
+      COMMON /SLS001/ ROWNS(209),
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     2   INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6),
+     3   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     4   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C
+      DATA  MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
+C-----------------------------------------------------------------------
+C Block A.
+C This code block is executed on every call.
+C It tests ISTATE and ITASK for legality and branches appropriately.
+C If ISTATE .GT. 1 but the flag INIT shows that initialization has
+C not yet been done, an error return occurs.
+C If ISTATE = 1 and TOUT = T, return immediately.
+C-----------------------------------------------------------------------
+C
+C***FIRST EXECUTABLE STATEMENT  SLSODE
+      IF (ISTATE .LT. 1 .OR. ISTATE .GT. 3) GO TO 601
+      IF (ITASK .LT. 1 .OR. ITASK .GT. 5) GO TO 602
+      IF (ISTATE .EQ. 1) GO TO 10
+      IF (INIT .EQ. 0) GO TO 603
+      IF (ISTATE .EQ. 2) GO TO 200
+      GO TO 20
+ 10   INIT = 0
+      IF (TOUT .EQ. T) RETURN
+C-----------------------------------------------------------------------
+C Block B.
+C The next code block is executed for the initial call (ISTATE = 1),
+C or for a continuation call with parameter changes (ISTATE = 3).
+C It contains checking of all inputs and various initializations.
+C
+C First check legality of the non-optional inputs NEQ, ITOL, IOPT,
+C MF, ML, and MU.
+C-----------------------------------------------------------------------
+ 20   IF (NEQ(1) .LE. 0) GO TO 604
+      IF (ISTATE .EQ. 1) GO TO 25
+      IF (NEQ(1) .GT. N) GO TO 605
+ 25   N = NEQ(1)
+      IF (ITOL .LT. 1 .OR. ITOL .GT. 4) GO TO 606
+      IF (IOPT .LT. 0 .OR. IOPT .GT. 1) GO TO 607
+      METH = MF/10
+      MITER = MF - 10*METH
+      IF (METH .LT. 1 .OR. METH .GT. 2) GO TO 608
+      IF (MITER .LT. 0 .OR. MITER .GT. 5) GO TO 608
+      IF (MITER .LE. 3) GO TO 30
+      ML = IWORK(1)
+      MU = IWORK(2)
+      IF (ML .LT. 0 .OR. ML .GE. N) GO TO 609
+      IF (MU .LT. 0 .OR. MU .GE. N) GO TO 610
+ 30   CONTINUE
+C Next process and check the optional inputs. --------------------------
+      IF (IOPT .EQ. 1) GO TO 40
+      MAXORD = MORD(METH)
+      MXSTEP = MXSTP0
+      MXHNIL = MXHNL0
+      IF (ISTATE .EQ. 1) H0 = 0.0E0
+      HMXI = 0.0E0
+      HMIN = 0.0E0
+      GO TO 60
+ 40   MAXORD = IWORK(5)
+      IF (MAXORD .LT. 0) GO TO 611
+      IF (MAXORD .EQ. 0) MAXORD = 100
+      MAXORD = MIN(MAXORD,MORD(METH))
+      MXSTEP = IWORK(6)
+      IF (MXSTEP .LT. 0) GO TO 612
+      IF (MXSTEP .EQ. 0) MXSTEP = MXSTP0
+      MXHNIL = IWORK(7)
+      IF (MXHNIL .LT. 0) GO TO 613
+      IF (MXHNIL .EQ. 0) MXHNIL = MXHNL0
+      IF (ISTATE .NE. 1) GO TO 50
+      H0 = RWORK(5)
+      IF ((TOUT - T)*H0 .LT. 0.0E0) GO TO 614
+ 50   HMAX = RWORK(6)
+      IF (HMAX .LT. 0.0E0) GO TO 615
+      HMXI = 0.0E0
+      IF (HMAX .GT. 0.0E0) HMXI = 1.0E0/HMAX
+      HMIN = RWORK(7)
+      IF (HMIN .LT. 0.0E0) GO TO 616
+C-----------------------------------------------------------------------
+C Set work array pointers and check lengths LRW and LIW.
+C Pointers to segments of RWORK and IWORK are named by prefixing L to
+C the name of the segment.  E.g., the segment YH starts at RWORK(LYH).
+C Segments of RWORK (in order) are denoted  YH, WM, EWT, SAVF, ACOR.
+C-----------------------------------------------------------------------
+ 60   LYH = 21
+      IF (ISTATE .EQ. 1) NYH = N
+      LWM = LYH + (MAXORD + 1)*NYH
+      IF (MITER .EQ. 0) LENWM = 0
+      IF (MITER .EQ. 1 .OR. MITER .EQ. 2) LENWM = N*N + 2
+      IF (MITER .EQ. 3) LENWM = N + 2
+      IF (MITER .GE. 4) LENWM = (2*ML + MU + 1)*N + 2
+      LEWT = LWM + LENWM
+      LSAVF = LEWT + N
+      LACOR = LSAVF + N
+      LENRW = LACOR + N - 1
+      IWORK(17) = LENRW
+      LIWM = 1
+      LENIW = 20 + N
+      IF (MITER .EQ. 0 .OR. MITER .EQ. 3) LENIW = 20
+      IWORK(18) = LENIW
+      IF (LENRW .GT. LRW) GO TO 617
+      IF (LENIW .GT. LIW) GO TO 618
+C Check RTOL and ATOL for legality. ------------------------------------
+      RTOLI = RTOL(1)
+      ATOLI = ATOL(1)
+      DO 70 I = 1,N
+        IF (ITOL .GE. 3) RTOLI = RTOL(I)
+        IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I)
+        IF (RTOLI .LT. 0.0E0) GO TO 619
+        IF (ATOLI .LT. 0.0E0) GO TO 620
+ 70     CONTINUE
+      IF (ISTATE .EQ. 1) GO TO 100
+C If ISTATE = 3, set flag to signal parameter changes to SSTODE. -------
+      JSTART = -1
+      IF (NQ .LE. MAXORD) GO TO 90
+C MAXORD was reduced below NQ.  Copy YH(*,MAXORD+2) into SAVF. ---------
+      DO 80 I = 1,N
+ 80     RWORK(I+LSAVF-1) = RWORK(I+LWM-1)
+C Reload WM(1) = RWORK(LWM), since LWM may have changed. ---------------
+ 90   IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND)
+      IF (N .EQ. NYH) GO TO 200
+C NEQ was reduced.  Zero part of YH to avoid undefined references. -----
+      I1 = LYH + L*NYH
+      I2 = LYH + (MAXORD + 1)*NYH - 1
+      IF (I1 .GT. I2) GO TO 200
+      DO 95 I = I1,I2
+ 95     RWORK(I) = 0.0E0
+      GO TO 200
+C-----------------------------------------------------------------------
+C Block C.
+C The next block is for the initial call only (ISTATE = 1).
+C It contains all remaining initializations, the initial call to F,
+C and the calculation of the initial step size.
+C The error weights in EWT are inverted after being loaded.
+C-----------------------------------------------------------------------
+ 100  UROUND = D1MACH(4)
+      TN = T
+      IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 110
+      TCRIT = RWORK(1)
+      IF ((TCRIT - TOUT)*(TOUT - T) .LT. 0.0E0) GO TO 625
+      IF (H0 .NE. 0.0E0 .AND. (T + H0 - TCRIT)*H0 .GT. 0.0E0)
+     1   H0 = TCRIT - T
+ 110  JSTART = 0
+      IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND)
+      NHNIL = 0
+      NST = 0
+      NJE = 0
+      NSLAST = 0
+      HU = 0.0E0
+      NQU = 0
+      CCMAX = 0.3E0
+      MAXCOR = 3
+      MSBP = 20
+      MXNCF = 10
+C Initial call to F.  (LF0 points to YH(*,2).) -------------------------
+      LF0 = LYH + NYH
+      CALL F (NEQ, T, Y, RWORK(LF0))
+      NFE = 1
+C Load the initial value vector in YH. ---------------------------------
+      DO 115 I = 1,N
+ 115    RWORK(I+LYH-1) = Y(I)
+C Load and invert the EWT array.  (H is temporarily set to 1.0.) -------
+      NQ = 1
+      H = 1.0E0
+      CALL SEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
+      DO 120 I = 1,N
+        IF (RWORK(I+LEWT-1) .LE. 0.0E0) GO TO 621
+ 120    RWORK(I+LEWT-1) = 1.0E0/RWORK(I+LEWT-1)
+C-----------------------------------------------------------------------
+C The coding below computes the step size, H0, to be attempted on the
+C first step, unless the user has supplied a value for this.
+C First check that TOUT - T differs significantly from zero.
+C A scalar tolerance quantity TOL is computed, as MAX(RTOL(I))
+C if this is positive, or MAX(ATOL(I)/ABS(Y(I))) otherwise, adjusted
+C so as to be between 100*UROUND and 1.0E-3.
+C Then the computed value H0 is given by..
+C                                      NEQ
+C   H0**2 = TOL / ( w0**-2 + (1/NEQ) * SUM ( f(i)/ywt(i) )**2  )
+C                                       1
+C where   w0     = MAX ( ABS(T), ABS(TOUT) ),
+C         f(i)   = i-th component of initial value of f,
+C         ywt(i) = EWT(i)/TOL  (a weight for y(i)).
+C The sign of H0 is inferred from the initial values of TOUT and T.
+C-----------------------------------------------------------------------
+      IF (H0 .NE. 0.0E0) GO TO 180
+      TDIST = ABS(TOUT - T)
+      W0 = MAX(ABS(T),ABS(TOUT))
+      IF (TDIST .LT. 2.0E0*UROUND*W0) GO TO 622
+      TOL = RTOL(1)
+      IF (ITOL .LE. 2) GO TO 140
+      DO 130 I = 1,N
+ 130    TOL = MAX(TOL,RTOL(I))
+ 140  IF (TOL .GT. 0.0E0) GO TO 160
+      ATOLI = ATOL(1)
+      DO 150 I = 1,N
+        IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I)
+        AYI = ABS(Y(I))
+        IF (AYI .NE. 0.0E0) TOL = MAX(TOL,ATOLI/AYI)
+ 150    CONTINUE
+ 160  TOL = MAX(TOL,100.0E0*UROUND)
+      TOL = MIN(TOL,0.001E0)
+      SUM = SVNORM (N, RWORK(LF0), RWORK(LEWT))
+      SUM = 1.0E0/(TOL*W0*W0) + TOL*SUM**2
+      H0 = 1.0E0/SQRT(SUM)
+      H0 = MIN(H0,TDIST)
+      H0 = SIGN(H0,TOUT-T)
+C Adjust H0 if necessary to meet HMAX bound. ---------------------------
+ 180  RH = ABS(H0)*HMXI
+      IF (RH .GT. 1.0E0) H0 = H0/RH
+C Load H with H0 and scale YH(*,2) by H0. ------------------------------
+      H = H0
+      DO 190 I = 1,N
+ 190    RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
+      GO TO 270
+C-----------------------------------------------------------------------
+C Block D.
+C The next code block is for continuation calls only (ISTATE = 2 or 3)
+C and is to check stop conditions before taking a step.
+C-----------------------------------------------------------------------
+ 200  NSLAST = NST
+      GO TO (210, 250, 220, 230, 240), ITASK
+ 210  IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 250
+      CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      IF (IFLAG .NE. 0) GO TO 627
+      T = TOUT
+      GO TO 420
+ 220  TP = TN - HU*(1.0E0 + 100.0E0*UROUND)
+      IF ((TP - TOUT)*H .GT. 0.0E0) GO TO 623
+      IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 250
+      GO TO 400
+ 230  TCRIT = RWORK(1)
+      IF ((TN - TCRIT)*H .GT. 0.0E0) GO TO 624
+      IF ((TCRIT - TOUT)*H .LT. 0.0E0) GO TO 625
+      IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 245
+      CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      IF (IFLAG .NE. 0) GO TO 627
+      T = TOUT
+      GO TO 420
+ 240  TCRIT = RWORK(1)
+      IF ((TN - TCRIT)*H .GT. 0.0E0) GO TO 624
+ 245  HMX = ABS(TN) + ABS(H)
+      IHIT = ABS(TN - TCRIT) .LE. 100.0E0*UROUND*HMX
+      IF (IHIT) GO TO 400
+      TNEXT = TN + H*(1.0E0 + 4.0E0*UROUND)
+      IF ((TNEXT - TCRIT)*H .LE. 0.0E0) GO TO 250
+      H = (TCRIT - TN)*(1.0E0 - 4.0E0*UROUND)
+      IF (ISTATE .EQ. 2) JSTART = -2
+C-----------------------------------------------------------------------
+C Block E.
+C The next block is normally executed for all calls and contains
+C the call to the one-step core integrator SSTODE.
+C
+C This is a looping point for the integration steps.
+C
+C First check for too many steps being taken, update EWT (if not at
+C start of problem), check for too much accuracy being requested, and
+C check for H below the roundoff level in T.
+C-----------------------------------------------------------------------
+ 250  CONTINUE
+      IF ((NST-NSLAST) .GE. MXSTEP) GO TO 500
+      CALL SEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
+      DO 260 I = 1,N
+        IF (RWORK(I+LEWT-1) .LE. 0.0E0) GO TO 510
+ 260    RWORK(I+LEWT-1) = 1.0E0/RWORK(I+LEWT-1)
+ 270  TOLSF = UROUND*SVNORM (N, RWORK(LYH), RWORK(LEWT))
+      IF (TOLSF .LE. 1.0E0) GO TO 280
+      TOLSF = TOLSF*2.0E0
+      IF (NST .EQ. 0) GO TO 626
+      GO TO 520
+ 280  IF ((TN + H) .NE. TN) GO TO 290
+      NHNIL = NHNIL + 1
+      IF (NHNIL .GT. MXHNIL) GO TO 290
+      CALL XERRWD('SLSODE-  Warning..internal T (=R1) and H (=R2) are', 
+     1     50, 101, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD(
+     1  '      such that in the machine, T + H = T on the next step  ', 
+     1     60, 101, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      (H = step size). Solver will continue anyway', 
+     1     50, 101, 0, 0, 0, 0, 2, TN, H)
+      IF (NHNIL .LT. MXHNIL) GO TO 290
+      CALL XERRWD('SLSODE-  Above warning has been issued I1 times.  ', 
+     1     50, 102, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      It will not be issued again for this problem', 
+     1     50, 102, 0, 1, MXHNIL, 0, 0, 0.0E0, 0.0E0)
+ 290  CONTINUE
+C-----------------------------------------------------------------------
+C  CALL SSTODE(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,SPREPJ,SSOLSY)
+C-----------------------------------------------------------------------
+      CALL SSTODE (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT),
+     1   RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM),
+     2   F, JAC, SPREPJ, SSOLSY)
+      KGO = 1 - KFLAG
+      GO TO (300, 530, 540), KGO
+C-----------------------------------------------------------------------
+C Block F.
+C The following block handles the case of a successful return from the
+C core integrator (KFLAG = 0).  Test for stop conditions.
+C-----------------------------------------------------------------------
+ 300  INIT = 1
+      GO TO (310, 400, 330, 340, 350), ITASK
+C ITASK = 1.  If TOUT has been reached, interpolate. -------------------
+ 310  IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 250
+      CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      T = TOUT
+      GO TO 420
+C ITASK = 3.  Jump to exit if TOUT was reached. ------------------------
+ 330  IF ((TN - TOUT)*H .GE. 0.0E0) GO TO 400
+      GO TO 250
+C ITASK = 4.  See if TOUT or TCRIT was reached.  Adjust H if necessary.
+ 340  IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 345
+      CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
+      T = TOUT
+      GO TO 420
+ 345  HMX = ABS(TN) + ABS(H)
+      IHIT = ABS(TN - TCRIT) .LE. 100.0E0*UROUND*HMX
+      IF (IHIT) GO TO 400
+      TNEXT = TN + H*(1.0E0 + 4.0E0*UROUND)
+      IF ((TNEXT - TCRIT)*H .LE. 0.0E0) GO TO 250
+      H = (TCRIT - TN)*(1.0E0 - 4.0E0*UROUND)
+      JSTART = -2
+      GO TO 250
+C ITASK = 5.  See if TCRIT was reached and jump to exit. ---------------
+ 350  HMX = ABS(TN) + ABS(H)
+      IHIT = ABS(TN - TCRIT) .LE. 100.0E0*UROUND*HMX
+C-----------------------------------------------------------------------
+C Block G.
+C The following block handles all successful returns from SLSODE.
+C If ITASK .NE. 1, Y is loaded from YH and T is set accordingly.
+C ISTATE is set to 2, and the optional outputs are loaded into the
+C work arrays before returning.
+C-----------------------------------------------------------------------
+ 400  DO 410 I = 1,N
+ 410    Y(I) = RWORK(I+LYH-1)
+      T = TN
+      IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 420
+      IF (IHIT) T = TCRIT
+ 420  ISTATE = 2
+      RWORK(11) = HU
+      RWORK(12) = H
+      RWORK(13) = TN
+      IWORK(11) = NST
+      IWORK(12) = NFE
+      IWORK(13) = NJE
+      IWORK(14) = NQU
+      IWORK(15) = NQ
+      RETURN
+C-----------------------------------------------------------------------
+C Block H.
+C The following block handles all unsuccessful returns other than
+C those for illegal input.  First the error message routine is called.
+C If there was an error test or convergence test failure, IMXER is set.
+C Then Y is loaded from YH and T is set to TN.  The optional outputs
+C are loaded into the work arrays before returning.
+C-----------------------------------------------------------------------
+C The maximum number of steps was taken before reaching TOUT. ----------
+ 500  CALL XERRWD('SLSODE-  At current T (=R1), MXSTEP (=I1) steps   ', 
+     1 50, 201, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      taken on this call before reaching TOUT     ', 
+     1     50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0E0)
+      ISTATE = -1
+      GO TO 580
+C EWT(I) .LE. 0.0 for some I (not at start of problem). ----------------
+ 510  EWTI = RWORK(LEWT+I-1)
+      CALL XERRWD('SLSODE-  At T (=R1), EWT(I1) has become R2 .LE. 0.', 
+     1 50, 202, 0, 1, I, 0, 2, TN, EWTI)
+      ISTATE = -6
+      GO TO 580
+C Too much accuracy requested for machine precision. -------------------
+ 520  CALL XERRWD('SLSODE-  At T (=R1), too much accuracy requested  ', 
+     1     50, 203, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      for precision of machine..  see TOLSF (=R2) ', 
+     1     50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
+      RWORK(14) = TOLSF
+      ISTATE = -2
+      GO TO 580
+C KFLAG = -1.  Error test failed repeatedly or with ABS(H) = HMIN. -----
+ 530  CALL XERRWD('SLSODE-  At T(=R1) and step size H(=R2), the error', 
+     1     50, 204, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      test failed repeatedly or with ABS(H) = HMIN', 
+     1     50, 204, 0, 0, 0, 0, 2, TN, H)
+      ISTATE = -4
+      GO TO 560
+C KFLAG = -2.  Convergence failed repeatedly or with ABS(H) = HMIN. ----
+ 540  CALL XERRWD('SLSODE-  At T (=R1) and step size H (=R2), the    ',
+     1     50, 205, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      corrector convergence failed repeatedly     ', 
+     1     50, 205, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD('      or with ABS(H) = HMIN   ', 
+     1     30, 205, 0, 0, 0, 0, 2, TN, H)
+      ISTATE = -5
+C Compute IMXER if relevant. -------------------------------------------
+ 560  BIG = 0.0E0
+      IMXER = 1
+      DO 570 I = 1,N
+        SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
+        IF (BIG .GE. SIZE) GO TO 570
+        BIG = SIZE
+        IMXER = I
+ 570    CONTINUE
+      IWORK(16) = IMXER
+C Set Y vector, T, and optional outputs. -------------------------------
+ 580  DO 590 I = 1,N
+ 590    Y(I) = RWORK(I+LYH-1)
+      T = TN
+      RWORK(11) = HU
+      RWORK(12) = H
+      RWORK(13) = TN
+      IWORK(11) = NST
+      IWORK(12) = NFE
+      IWORK(13) = NJE
+      IWORK(14) = NQU
+      IWORK(15) = NQ
+      RETURN
+C-----------------------------------------------------------------------
+C Block I.
+C The following block handles all error returns due to illegal input
+C (ISTATE = -3), as detected before calling the core integrator.
+C First the error message routine is called.  If the illegal input 
+C is a negative ISTATE, the run is aborted (apparent infinite loop).
+C-----------------------------------------------------------------------
+ 601  CALL XERRWD('SLSODE-  ISTATE (=I1) illegal ',
+     1     30, 1, 0, 1, ISTATE, 0, 0, 0.0E0, 0.0E0)
+      IF (ISTATE .LT. 0) GO TO 800
+      GO TO 700
+ 602  CALL XERRWD('SLSODE-  ITASK (=I1) illegal  ', 
+     1     30, 2, 0, 1, ITASK, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 603  CALL XERRWD('SLSODE-  ISTATE .GT. 1 but SLSODE not initialized ', 
+     1     50, 3, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 604  CALL XERRWD('SLSODE-  NEQ (=I1) .LT. 1     ', 
+     1     30, 4, 0, 1, NEQ(1), 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 605  CALL XERRWD('SLSODE-  ISTATE = 3 and NEQ increased (I1 to I2)  ', 
+     1     50, 5, 0, 2, N, NEQ(1), 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 606  CALL XERRWD('SLSODE-  ITOL (=I1) illegal   ',
+     1     30, 6, 0, 1, ITOL, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 607  CALL XERRWD('SLSODE-  IOPT (=I1) illegal   ', 
+     1     30, 7, 0, 1, IOPT, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 608  CALL XERRWD('SLSODE-  MF (=I1) illegal     ', 
+     1     30, 8, 0, 1, MF, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 609  CALL XERRWD('SLSODE-  ML (=I1) illegal.. .LT.0 or .GE.NEQ (=I2)', 
+     1     50, 9, 0, 2, ML, NEQ(1), 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 610  CALL XERRWD('SLSODE-  MU (=I1) illegal.. .LT.0 or .GE.NEQ (=I2)', 
+     1     50, 10, 0, 2, MU, NEQ(1), 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 611  CALL XERRWD('SLSODE-  MAXORD (=I1) .LT. 0  ', 
+     1     30, 11, 0, 1, MAXORD, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 612  CALL XERRWD('SLSODE-  MXSTEP (=I1) .LT. 0  ', 
+     1 30, 12, 0, 1, MXSTEP, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 613  CALL XERRWD('SLSODE-  MXHNIL (=I1) .LT. 0  ', 
+     1     30, 13, 0, 1, MXHNIL, 0, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 614  CALL XERRWD('SLSODE-  TOUT (=R1) behind T (=R2)      ', 
+     1     40, 14, 0, 0, 0, 0, 2, TOUT, T)
+      CALL XERRWD('      Integration direction is given by H0 (=R1)  ', 
+     1     50, 14, 0, 0, 0, 0, 1, H0, 0.0E0)
+      GO TO 700
+ 615  CALL XERRWD('SLSODE-  HMAX (=R1) .LT. 0.0  ', 
+     1     30, 15, 0, 0, 0, 0, 1, HMAX, 0.0E0)
+      GO TO 700
+ 616  CALL XERRWD('SLSODE-  HMIN (=R1) .LT. 0.0  ', 
+     1     30, 16, 0, 0, 0, 0, 1, HMIN, 0.0E0)
+      GO TO 700
+ 617  CALL XERRWD(
+     1  'SLSODE-  RWORK length needed, LENRW (=I1), exceeds LRW (=I2)', 
+     1   60, 17, 0, 2, LENRW, LRW, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 618  CALL XERRWD(
+     1   'SLSODE-  IWORK length needed, LENIW (=I1), exceeds LIW (=I2)',
+     1    60, 18, 0, 2, LENIW, LIW, 0, 0.0E0, 0.0E0)
+      GO TO 700
+ 619  CALL XERRWD('SLSODE-  RTOL(I1) is R1 .LT. 0.0        ', 
+     1     40, 19, 0, 1, I, 0, 1, RTOLI, 0.0E0)
+      GO TO 700
+ 620  CALL XERRWD('SLSODE-  ATOL(I1) is R1 .LT. 0.0        ', 
+     1     40, 20, 0, 1, I, 0, 1, ATOLI, 0.0E0)
+      GO TO 700
+ 621  EWTI = RWORK(LEWT+I-1)
+      CALL XERRWD('SLSODE-  EWT(I1) is R1 .LE. 0.0         ', 
+     1     40, 21, 0, 1, I, 0, 1, EWTI, 0.0E0)
+      GO TO 700
+ 622  CALL XERRWD(
+     1   'SLSODE-  TOUT (=R1) too close to T(=R2) to start integration',
+     1     60, 22, 0, 0, 0, 0, 2, TOUT, T)
+      GO TO 700
+ 623  CALL XERRWD(
+     1 'SLSODE-  ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2)  ', 
+     1     60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
+      GO TO 700
+ 624  CALL XERRWD(
+     1   'SLSODE-  ITASK = 4 OR 5 and TCRIT (=R1) behind TCUR (=R2)   ',
+     1    60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
+      GO TO 700
+ 625  CALL XERRWD(
+     1  'SLSODE-  ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2)   ',
+     1   60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
+      GO TO 700
+ 626  CALL XERRWD('SLSODE-  At start of problem, too much accuracy   ',
+     1     50, 26, 0, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      CALL XERRWD(
+     1   '      requested for precision of machine..  See TOLSF (=R1) ',
+     1    60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0E0)
+      RWORK(14) = TOLSF
+      GO TO 700
+ 627  CALL XERRWD('SLSODE-  Trouble in SINTDY.  ITASK = I1, TOUT = R1', 
+     1     50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0E0)
+C
+ 700  ISTATE = -3
+      RETURN
+C
+ 800  CALL XERRWD('SLSODE-  Run aborted.. apparent infinite loop     ', 
+     1     50, 303, 2, 0, 0, 0, 0, 0.0E0, 0.0E0)
+      RETURN
+C----------------------- END OF SUBROUTINE SLSODE ----------------------
+      END
diff --git a/libcruft/odepack/solsy.f b/libcruft/odepack/solsy.f
new file mode 100644
index 0000000..7893dc3
--- /dev/null
+++ b/libcruft/odepack/solsy.f
@@ -0,0 +1,69 @@
+      SUBROUTINE SOLSY (WM, IWM, X, TEM)
+CLLL. OPTIMIZE
+      INTEGER IWM
+      INTEGER IOWND, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     2   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, MEBAND, ML, MU
+      DOUBLE PRECISION WM, X, TEM
+      DOUBLE PRECISION ROWNS, 
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      DOUBLE PRECISION DI, HL0, PHL0, R 
+      DIMENSION WM(*), IWM(*), X(*), TEM(*)
+      COMMON /LS0001/ ROWNS(209),
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     3   IOWND(14), IOWNS(6), 
+     4   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C-----------------------------------------------------------------------
+C THIS ROUTINE MANAGES THE SOLUTION OF THE LINEAR SYSTEM ARISING FROM 
+C A CHORD ITERATION.  IT IS CALLED IF MITER .NE. 0.
+C IF MITER IS 1 OR 2, IT CALLS DGETRS TO ACCOMPLISH THIS.
+C IF MITER = 3 IT UPDATES THE COEFFICIENT H*EL0 IN THE DIAGONAL
+C MATRIX, AND THEN COMPUTES THE SOLUTION.
+C IF MITER IS 4 OR 5, IT CALLS DGBTRS.
+C COMMUNICATION WITH SOLSY USES THE FOLLOWING VARIABLES..
+C WM    = REAL WORK SPACE CONTAINING THE INVERSE DIAGONAL MATRIX IF
+C         MITER = 3 AND THE LU DECOMPOSITION OF THE MATRIX OTHERWISE. 
+C         STORAGE OF MATRIX ELEMENTS STARTS AT WM(3).
+C         WM ALSO CONTAINS THE FOLLOWING MATRIX-RELATED DATA..
+C         WM(1) = SQRT(UROUND) (NOT USED HERE),
+C         WM(2) = HL0, THE PREVIOUS VALUE OF H*EL0, USED IF MITER = 3.
+C IWM   = INTEGER WORK SPACE CONTAINING PIVOT INFORMATION, STARTING AT
+C         IWM(21), IF MITER IS 1, 2, 4, OR 5.  IWM ALSO CONTAINS BAND 
+C         PARAMETERS ML = IWM(1) AND MU = IWM(2) IF MITER IS 4 OR 5.
+C X     = THE RIGHT-HAND SIDE VECTOR ON INPUT, AND THE SOLUTION VECTOR
+C         ON OUTPUT, OF LENGTH N.
+C TEM   = VECTOR OF WORK SPACE OF LENGTH N, NOT USED IN THIS VERSION. 
+C IERSL = OUTPUT FLAG (IN COMMON).  IERSL = 0 IF NO TROUBLE OCCURRED. 
+C         IERSL = 1 IF A SINGULAR MATRIX AROSE WITH MITER = 3.
+C THIS ROUTINE ALSO USES THE COMMON VARIABLES EL0, H, MITER, AND N.
+C-----------------------------------------------------------------------
+      IERSL = 0
+      GO TO (100, 100, 300, 400, 400), MITER
+ 100  CALL DGETRS ( 'N', N, 1, WM(3), N, IWM(21), X, N, INLPCK)
+      RETURN
+C
+ 300  PHL0 = WM(2)
+      HL0 = H*EL0
+      WM(2) = HL0
+      IF (HL0 .EQ. PHL0) GO TO 330
+      R = HL0/PHL0
+      DO 320 I = 1,N
+        DI = 1.0D0 - R*(1.0D0 - 1.0D0/WM(I+2))
+        IF (DABS(DI) .EQ. 0.0D0) GO TO 390
+ 320    WM(I+2) = 1.0D0/DI
+ 330  DO 340 I = 1,N
+ 340    X(I) = WM(I+2)*X(I)
+      RETURN
+ 390  IERSL = 1
+      RETURN
+C
+ 400  ML = IWM(1)
+      MU = IWM(2)
+      MEBAND = 2*ML + MU + 1
+      CALL DGBTRS ( 'N', N, ML, MU, 1, WM(3), MEBAND, IWM(21), X, N, 
+     * INLPCK)
+      RETURN
+C----------------------- END OF SUBROUTINE SOLSY -----------------------
+      END 
diff --git a/libcruft/odepack/sprepj.f b/libcruft/odepack/sprepj.f
new file mode 100644
index 0000000..faa41c6
--- /dev/null
+++ b/libcruft/odepack/sprepj.f
@@ -0,0 +1,193 @@
+      SUBROUTINE SPREPJ (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM,
+     1   F, JAC)
+C***BEGIN PROLOGUE  SPREPJ
+C***SUBSIDIARY
+C***PURPOSE  Compute and process Newton iteration matrix.
+C***TYPE      SINGLE PRECISION (SPREPJ-S, DPREPJ-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  SPREPJ is called by SSTODE to compute and process the matrix
+C  P = I - h*el(1)*J , where J is an approximation to the Jacobian.
+C  Here J is computed by the user-supplied routine JAC if
+C  MITER = 1 or 4, or by finite differencing if MITER = 2, 3, or 5.
+C  If MITER = 3, a diagonal approximation to J is used.
+C  J is stored in WM and replaced by P.  If MITER .ne. 3, P is then
+C  subjected to LU decomposition in preparation for later solution
+C  of linear systems with P as coefficient matrix.  This is done
+C  by SGETRF if MITER = 1 or 2, and by SGBTRF if MITER = 4 or 5.
+C
+C  In addition to variables described in SSTODE and SLSODE prologues,
+C  communication with SPREPJ uses the following:
+C  Y     = array containing predicted values on entry.
+C  FTEM  = work array of length N (ACOR in SSTODE).
+C  SAVF  = array containing f evaluated at predicted y.
+C  WM    = real work space for matrices.  On output it contains the
+C          inverse diagonal matrix if MITER = 3 and the LU decomposition
+C          of P if MITER is 1, 2 , 4, or 5.
+C          Storage of matrix elements starts at WM(3).
+C          WM also contains the following matrix-related data:
+C          WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
+C          WM(2) = H*EL0, saved for later use if MITER = 3.
+C  IWM   = integer work space containing pivot information, starting at
+C          IWM(21), if MITER is 1, 2, 4, or 5.  IWM also contains band
+C          parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
+C  EL0   = EL(1) (input).
+C  IERPJ = output error flag,  = 0 if no trouble, .gt. 0 if
+C          P matrix found to be singular.
+C  JCUR  = output flag = 1 to indicate that the Jacobian matrix
+C          (or approximation) is now current.
+C  This routine also uses the COMMON variables EL0, H, TN, UROUND,
+C  MITER, N, NFE, and NJE.
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  SGBTRF, SGETRF, SVNORM
+C***COMMON BLOCKS    SLS001
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890504  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C   010412  Reduced size of Common block /SLS001/. (ACH)
+C   031105  Restored 'own' variables to Common block /SLS001/, to
+C           enable interrupt/restart feature. (ACH)
+C***END PROLOGUE  SPREPJ
+C**End
+      EXTERNAL F, JAC
+      INTEGER NEQ, NYH, IWM
+      REAL Y, YH, EWT, FTEM, SAVF, WM
+      DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), FTEM(*), SAVF(*),
+     1   WM(*), IWM(*)
+      INTEGER IOWND, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     2   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     3   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      REAL ROWNS,
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      COMMON /SLS001/ ROWNS(209),
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     2   IOWND(6), IOWNS(6),
+     3   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     4   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, I1, I2, IER, II, J, J1, JJ, LENP,
+     1   MBA, MBAND, MEB1, MEBAND, ML, ML3, MU, NP1
+      REAL CON, DI, FAC, HL0, R, R0, SRUR, YI, YJ, YJJ,
+     1   SVNORM
+C
+C***FIRST EXECUTABLE STATEMENT  SPREPJ
+      NJE = NJE + 1
+      IERPJ = 0
+      JCUR = 1
+      HL0 = H*EL0
+      GO TO (100, 200, 300, 400, 500), MITER
+C If MITER = 1, call JAC and multiply by scalar. -----------------------
+ 100  LENP = N*N
+      DO 110 I = 1,LENP
+ 110    WM(I+2) = 0.0E0
+      CALL JAC (NEQ, TN, Y, 0, 0, WM(3), N)
+      CON = -HL0
+      DO 120 I = 1,LENP
+ 120    WM(I+2) = WM(I+2)*CON
+      GO TO 240
+C If MITER = 2, make N calls to F to approximate J. --------------------
+ 200  FAC = SVNORM (N, SAVF, EWT)
+      R0 = 1000.0E0*ABS(H)*UROUND*N*FAC
+      IF (R0 .EQ. 0.0E0) R0 = 1.0E0
+      SRUR = WM(1)
+      J1 = 2
+      DO 230 J = 1,N
+        YJ = Y(J)
+        R = MAX(SRUR*ABS(YJ),R0/EWT(J))
+        Y(J) = Y(J) + R
+        FAC = -HL0/R
+        CALL F (NEQ, TN, Y, FTEM)
+        DO 220 I = 1,N
+ 220      WM(I+J1) = (FTEM(I) - SAVF(I))*FAC
+        Y(J) = YJ
+        J1 = J1 + N
+ 230    CONTINUE
+      NFE = NFE + N
+C Add identity matrix. -------------------------------------------------
+ 240  J = 3
+      NP1 = N + 1
+      DO 250 I = 1,N
+        WM(J) = WM(J) + 1.0E0
+ 250    J = J + NP1
+C Do LU decomposition on P. --------------------------------------------
+      CALL SGETRF (N, N, WM(3), N, IWM(21), IER)
+      IF (IER .NE. 0) IERPJ = 1
+      RETURN
+C If MITER = 3, construct a diagonal approximation to J and P. ---------
+ 300  WM(2) = HL0
+      R = EL0*0.1E0
+      DO 310 I = 1,N
+ 310    Y(I) = Y(I) + R*(H*SAVF(I) - YH(I,2))
+      CALL F (NEQ, TN, Y, WM(3))
+      NFE = NFE + 1
+      DO 320 I = 1,N
+        R0 = H*SAVF(I) - YH(I,2)
+        DI = 0.1E0*R0 - H*(WM(I+2) - SAVF(I))
+        WM(I+2) = 1.0E0
+        IF (ABS(R0) .LT. UROUND/EWT(I)) GO TO 320
+        IF (ABS(DI) .EQ. 0.0E0) GO TO 330
+        WM(I+2) = 0.1E0*R0/DI
+ 320    CONTINUE
+      RETURN
+ 330  IERPJ = 1
+      RETURN
+C If MITER = 4, call JAC and multiply by scalar. -----------------------
+ 400  ML = IWM(1)
+      MU = IWM(2)
+      ML3 = ML + 3
+      MBAND = ML + MU + 1
+      MEBAND = MBAND + ML
+      LENP = MEBAND*N
+      DO 410 I = 1,LENP
+ 410    WM(I+2) = 0.0E0
+      CALL JAC (NEQ, TN, Y, ML, MU, WM(ML3), MEBAND)
+      CON = -HL0
+      DO 420 I = 1,LENP
+ 420    WM(I+2) = WM(I+2)*CON
+      GO TO 570
+C If MITER = 5, make MBAND calls to F to approximate J. ----------------
+ 500  ML = IWM(1)
+      MU = IWM(2)
+      MBAND = ML + MU + 1
+      MBA = MIN(MBAND,N)
+      MEBAND = MBAND + ML
+      MEB1 = MEBAND - 1
+      SRUR = WM(1)
+      FAC = SVNORM (N, SAVF, EWT)
+      R0 = 1000.0E0*ABS(H)*UROUND*N*FAC
+      IF (R0 .EQ. 0.0E0) R0 = 1.0E0
+      DO 560 J = 1,MBA
+        DO 530 I = J,N,MBAND
+          YI = Y(I)
+          R = MAX(SRUR*ABS(YI),R0/EWT(I))
+ 530      Y(I) = Y(I) + R
+        CALL F (NEQ, TN, Y, FTEM)
+        DO 550 JJ = J,N,MBAND
+          Y(JJ) = YH(JJ,1)
+          YJJ = Y(JJ)
+          R = MAX(SRUR*ABS(YJJ),R0/EWT(JJ))
+          FAC = -HL0/R
+          I1 = MAX(JJ-MU,1)
+          I2 = MIN(JJ+ML,N)
+          II = JJ*MEB1 - ML + 2
+          DO 540 I = I1,I2
+ 540        WM(II+I) = (FTEM(I) - SAVF(I))*FAC
+ 550      CONTINUE
+ 560    CONTINUE
+      NFE = NFE + MBA
+C Add identity matrix. -------------------------------------------------
+ 570  II = MBAND + 2
+      DO 580 I = 1,N
+        WM(II) = WM(II) + 1.0E0
+ 580    II = II + MEBAND
+C Do LU decomposition of P. --------------------------------------------
+      CALL SGBTRF ( N, N, ML, MU, WM(3), MEBAND, IWM(21), IER)
+      IF (IER .NE. 0) IERPJ = 1
+      RETURN
+C----------------------- END OF SUBROUTINE SPREPJ ----------------------
+      END
diff --git a/libcruft/odepack/ssolsy.f b/libcruft/odepack/ssolsy.f
new file mode 100644
index 0000000..7617968
--- /dev/null
+++ b/libcruft/odepack/ssolsy.f
@@ -0,0 +1,91 @@
+      SUBROUTINE SSOLSY (WM, IWM, X, TEM)
+C***BEGIN PROLOGUE  SSOLSY
+C***SUBSIDIARY
+C***PURPOSE  ODEPACK linear system solver.
+C***TYPE      SINGLE PRECISION (SSOLSY-S, DSOLSY-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  This routine manages the solution of the linear system arising from
+C  a chord iteration.  It is called if MITER .ne. 0.
+C  If MITER is 1 or 2, it calls SGETRF to accomplish this.
+C  If MITER = 3 it updates the coefficient h*EL0 in the diagonal
+C  matrix, and then computes the solution.
+C  If MITER is 4 or 5, it calls SGBTRS.
+C  Communication with SSOLSY uses the following variables:
+C  WM    = real work space containing the inverse diagonal matrix if
+C          MITER = 3 and the LU decomposition of the matrix otherwise.
+C          Storage of matrix elements starts at WM(3).
+C          WM also contains the following matrix-related data:
+C          WM(1) = SQRT(UROUND) (not used here),
+C          WM(2) = HL0, the previous value of h*EL0, used if MITER = 3.
+C  IWM   = integer work space containing pivot information, starting at
+C          IWM(21), if MITER is 1, 2, 4, or 5.  IWM also contains band
+C          parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
+C  X     = the right-hand side vector on input, and the solution vector
+C          on output, of length N.
+C  TEM   = vector of work space of length N, not used in this version.
+C  IERSL = output flag (in COMMON).  IERSL = 0 if no trouble occurred.
+C          IERSL = 1 if a singular matrix arose with MITER = 3.
+C  This routine also uses the COMMON variables EL0, H, MITER, and N.
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  SGBTRS, SGETRS
+C***COMMON BLOCKS    SLS001
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890503  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C   010412  Reduced size of Common block /SLS001/. (ACH)
+C   031105  Restored 'own' variables to Common block /SLS001/, to
+C           enable interrupt/restart feature. (ACH)
+C***END PROLOGUE  SSOLSY
+C**End
+      INTEGER IWM
+      REAL WM, X, TEM
+      DIMENSION WM(*), IWM(*), X(*), TEM(*)
+      INTEGER IOWND, IOWNS,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     2   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     3   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      REAL ROWNS,
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      COMMON /SLS001/ ROWNS(209),
+     1   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     2   IOWND(6), IOWNS(6),
+     3   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     4   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, MEBAND, ML, MU
+      REAL DI, HL0, PHL0, R
+C
+C***FIRST EXECUTABLE STATEMENT  SSOLSY
+      IERSL = 0
+      GO TO (100, 100, 300, 400, 400), MITER
+ 100  CALL SGETRS ( 'N', N, 1, WM(3), N, IWM(21), X, N, INLPCK)
+      RETURN
+C
+ 300  PHL0 = WM(2)
+      HL0 = H*EL0
+      WM(2) = HL0
+      IF (HL0 .EQ. PHL0) GO TO 330
+      R = HL0/PHL0
+      DO 320 I = 1,N
+        DI = 1.0E0 - R*(1.0E0 - 1.0E0/WM(I+2))
+        IF (ABS(DI) .EQ. 0.0E0) GO TO 390
+ 320    WM(I+2) = 1.0E0/DI
+ 330  DO 340 I = 1,N
+ 340    X(I) = WM(I+2)*X(I)
+      RETURN
+ 390  IERSL = 1
+      RETURN
+C
+ 400  ML = IWM(1)
+      MU = IWM(2)
+      MEBAND = 2*ML + MU + 1
+      CALL SGBTRS ( 'N', N, ML, MU, 1, WM(3), MEBAND, IWM(21), X, N, 
+     * INLPCK)
+      RETURN
+C----------------------- END OF SUBROUTINE SSOLSY ----------------------
+      END
diff --git a/libcruft/odepack/sstode.f b/libcruft/odepack/sstode.f
new file mode 100644
index 0000000..adc1696
--- /dev/null
+++ b/libcruft/odepack/sstode.f
@@ -0,0 +1,497 @@
+      SUBROUTINE SSTODE (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR,
+     1   WM, IWM, F, JAC, PJAC, SLVS)
+C***BEGIN PROLOGUE  SSTODE
+C***SUBSIDIARY
+C***PURPOSE  Performs one step of an ODEPACK integration.
+C***TYPE      SINGLE PRECISION (SSTODE-S, DSTODE-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  SSTODE performs one step of the integration of an initial value
+C  problem for a system of ordinary differential equations.
+C  Note:  SSTODE is independent of the value of the iteration method
+C  indicator MITER, when this is .ne. 0, and hence is independent
+C  of the type of chord method used, or the Jacobian structure.
+C  Communication with SSTODE is done with the following variables:
+C
+C  NEQ    = integer array containing problem size in NEQ(1), and
+C           passed as the NEQ argument in all calls to F and JAC.
+C  Y      = an array of length .ge. N used as the Y argument in
+C           all calls to F and JAC.
+C  YH     = an NYH by LMAX array containing the dependent variables
+C           and their approximate scaled derivatives, where
+C           LMAX = MAXORD + 1.  YH(i,j+1) contains the approximate
+C           j-th derivative of y(i), scaled by h**j/factorial(j)
+C           (j = 0,1,...,NQ).  on entry for the first step, the first
+C           two columns of YH must be set from the initial values.
+C  NYH    = a constant integer .ge. N, the first dimension of YH.
+C  YH1    = a one-dimensional array occupying the same space as YH.
+C  EWT    = an array of length N containing multiplicative weights
+C           for local error measurements.  Local errors in Y(i) are
+C           compared to 1.0/EWT(i) in various error tests.
+C  SAVF   = an array of working storage, of length N.
+C           Also used for input of YH(*,MAXORD+2) when JSTART = -1
+C           and MAXORD .lt. the current order NQ.
+C  ACOR   = a work array of length N, used for the accumulated
+C           corrections.  On a successful return, ACOR(i) contains
+C           the estimated one-step local error in Y(i).
+C  WM,IWM = real and integer work arrays associated with matrix
+C           operations in chord iteration (MITER .ne. 0).
+C  PJAC   = name of routine to evaluate and preprocess Jacobian matrix
+C           and P = I - h*el0*JAC, if a chord method is being used.
+C  SLVS   = name of routine to solve linear system in chord iteration.
+C  CCMAX  = maximum relative change in h*el0 before PJAC is called.
+C  H      = the step size to be attempted on the next step.
+C           H is altered by the error control algorithm during the
+C           problem.  H can be either positive or negative, but its
+C           sign must remain constant throughout the problem.
+C  HMIN   = the minimum absolute value of the step size h to be used.
+C  HMXI   = inverse of the maximum absolute value of h to be used.
+C           HMXI = 0.0 is allowed and corresponds to an infinite hmax.
+C           HMIN and HMXI may be changed at any time, but will not
+C           take effect until the next change of h is considered.
+C  TN     = the independent variable. TN is updated on each step taken.
+C  JSTART = an integer used for input only, with the following
+C           values and meanings:
+C                0  perform the first step.
+C            .gt.0  take a new step continuing from the last.
+C               -1  take the next step with a new value of H, MAXORD,
+C                     N, METH, MITER, and/or matrix parameters.
+C               -2  take the next step with a new value of H,
+C                     but with other inputs unchanged.
+C           On return, JSTART is set to 1 to facilitate continuation.
+C  KFLAG  = a completion code with the following meanings:
+C                0  the step was succesful.
+C               -1  the requested error could not be achieved.
+C               -2  corrector convergence could not be achieved.
+C               -3  fatal error in PJAC or SLVS.
+C           A return with KFLAG = -1 or -2 means either
+C           abs(H) = HMIN or 10 consecutive failures occurred.
+C           On a return with KFLAG negative, the values of TN and
+C           the YH array are as of the beginning of the last
+C           step, and H is the last step size attempted.
+C  MAXORD = the maximum order of integration method to be allowed.
+C  MAXCOR = the maximum number of corrector iterations allowed.
+C  MSBP   = maximum number of steps between PJAC calls (MITER .gt. 0).
+C  MXNCF  = maximum number of convergence failures allowed.
+C  METH/MITER = the method flags.  See description in driver.
+C  N      = the number of first-order differential equations.
+C  The values of CCMAX, H, HMIN, HMXI, TN, JSTART, KFLAG, MAXORD,
+C  MAXCOR, MSBP, MXNCF, METH, MITER, and N are communicated via COMMON.
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  SCFODE, SVNORM
+C***COMMON BLOCKS    SLS001
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890503  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C   010413  Reduced size of Common block /SLS001/. (ACH)
+C   031105  Restored 'own' variables to Common block /SLS001/, to
+C           enable interrupt/restart feature. (ACH)
+C***END PROLOGUE  SSTODE
+C**End
+      EXTERNAL F, JAC, PJAC, SLVS
+      INTEGER NEQ, NYH, IWM
+      REAL Y, YH, YH1, EWT, SAVF, ACOR, WM
+      DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*),
+     1   ACOR(*), WM(*), IWM(*)
+      INTEGER IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     2   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     3   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, I1, IREDO, IRET, J, JB, M, NCF, NEWQ
+      REAL CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO,
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      REAL DCON, DDN, DEL, DELP, DSM, DUP, EXDN, EXSM, EXUP,
+     1   R, RH, RHDN, RHSM, RHUP, TOLD, SVNORM
+      COMMON /SLS001/ CONIT, CRATE, EL(13), ELCO(13,12),
+     1   HOLD, RMAX, TESCO(3,12),
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,
+     3   IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP,
+     3   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,
+     4   LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C
+C***FIRST EXECUTABLE STATEMENT  SSTODE
+      KFLAG = 0
+      TOLD = TN
+      NCF = 0
+      IERPJ = 0
+      IERSL = 0
+      JCUR = 0
+      ICF = 0
+      DELP = 0.0E0
+      IF (JSTART .GT. 0) GO TO 200
+      IF (JSTART .EQ. -1) GO TO 100
+      IF (JSTART .EQ. -2) GO TO 160
+C-----------------------------------------------------------------------
+C On the first call, the order is set to 1, and other variables are
+C initialized.  RMAX is the maximum ratio by which H can be increased
+C in a single step.  It is initially 1.E4 to compensate for the small
+C initial H, but then is normally equal to 10.  If a failure
+C occurs (in corrector convergence or error test), RMAX is set to 2
+C for the next increase.
+C-----------------------------------------------------------------------
+      LMAX = MAXORD + 1
+      NQ = 1
+      L = 2
+      IALTH = 2
+      RMAX = 10000.0E0
+      RC = 0.0E0
+      EL0 = 1.0E0
+      CRATE = 0.7E0
+      HOLD = H
+      MEO = METH
+      NSLP = 0
+      IPUP = MITER
+      IRET = 3
+      GO TO 140
+C-----------------------------------------------------------------------
+C The following block handles preliminaries needed when JSTART = -1.
+C IPUP is set to MITER to force a matrix update.
+C If an order increase is about to be considered (IALTH = 1),
+C IALTH is reset to 2 to postpone consideration one more step.
+C If the caller has changed METH, SCFODE is called to reset
+C the coefficients of the method.
+C If the caller has changed MAXORD to a value less than the current
+C order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
+C If H is to be changed, YH must be rescaled.
+C If H or METH is being changed, IALTH is reset to L = NQ + 1
+C to prevent further changes in H for that many steps.
+C-----------------------------------------------------------------------
+ 100  IPUP = MITER
+      LMAX = MAXORD + 1
+      IF (IALTH .EQ. 1) IALTH = 2
+      IF (METH .EQ. MEO) GO TO 110
+      CALL SCFODE (METH, ELCO, TESCO)
+      MEO = METH
+      IF (NQ .GT. MAXORD) GO TO 120
+      IALTH = L
+      IRET = 1
+      GO TO 150
+ 110  IF (NQ .LE. MAXORD) GO TO 160
+ 120  NQ = MAXORD
+      L = LMAX
+      DO 125 I = 1,L
+ 125    EL(I) = ELCO(I,NQ)
+      NQNYH = NQ*NYH
+      RC = RC*EL(1)/EL0
+      EL0 = EL(1)
+      CONIT = 0.5E0/(NQ+2)
+      DDN = SVNORM (N, SAVF, EWT)/TESCO(1,L)
+      EXDN = 1.0E0/L
+      RHDN = 1.0E0/(1.3E0*DDN**EXDN + 0.0000013E0)
+      RH = MIN(RHDN,1.0E0)
+      IREDO = 3
+      IF (H .EQ. HOLD) GO TO 170
+      RH = MIN(RH,ABS(H/HOLD))
+      H = HOLD
+      GO TO 175
+C-----------------------------------------------------------------------
+C SCFODE is called to get all the integration coefficients for the
+C current METH.  Then the EL vector and related constants are reset
+C whenever the order NQ is changed, or at the start of the problem.
+C-----------------------------------------------------------------------
+ 140  CALL SCFODE (METH, ELCO, TESCO)
+ 150  DO 155 I = 1,L
+ 155    EL(I) = ELCO(I,NQ)
+      NQNYH = NQ*NYH
+      RC = RC*EL(1)/EL0
+      EL0 = EL(1)
+      CONIT = 0.5E0/(NQ+2)
+      GO TO (160, 170, 200), IRET
+C-----------------------------------------------------------------------
+C If H is being changed, the H ratio RH is checked against
+C RMAX, HMIN, and HMXI, and the YH array rescaled.  IALTH is set to
+C L = NQ + 1 to prevent a change of H for that many steps, unless
+C forced by a convergence or error test failure.
+C-----------------------------------------------------------------------
+ 160  IF (H .EQ. HOLD) GO TO 200
+      RH = H/HOLD
+      H = HOLD
+      IREDO = 3
+      GO TO 175
+ 170  RH = MAX(RH,HMIN/ABS(H))
+ 175  RH = MIN(RH,RMAX)
+      RH = RH/MAX(1.0E0,ABS(H)*HMXI*RH)
+      R = 1.0E0
+      DO 180 J = 2,L
+        R = R*RH
+        DO 180 I = 1,N
+ 180      YH(I,J) = YH(I,J)*R
+      H = H*RH
+      RC = RC*RH
+      IALTH = L
+      IF (IREDO .EQ. 0) GO TO 690
+C-----------------------------------------------------------------------
+C This section computes the predicted values by effectively
+C multiplying the YH array by the Pascal Triangle matrix.
+C RC is the ratio of new to old values of the coefficient  H*EL(1).
+C When RC differs from 1 by more than CCMAX, IPUP is set to MITER
+C to force PJAC to be called, if a Jacobian is involved.
+C In any case, PJAC is called at least every MSBP steps.
+C-----------------------------------------------------------------------
+ 200  IF (ABS(RC-1.0E0) .GT. CCMAX) IPUP = MITER
+      IF (NST .GE. NSLP+MSBP) IPUP = MITER
+      TN = TN + H
+      I1 = NQNYH + 1
+      DO 215 JB = 1,NQ
+        I1 = I1 - NYH
+Cdir$ ivdep
+        DO 210 I = I1,NQNYH
+ 210      YH1(I) = YH1(I) + YH1(I+NYH)
+ 215    CONTINUE
+C-----------------------------------------------------------------------
+C Up to MAXCOR corrector iterations are taken.  A convergence test is
+C made on the R.M.S. norm of each correction, weighted by the error
+C weight vector EWT.  The sum of the corrections is accumulated in the
+C vector ACOR(i).  The YH array is not altered in the corrector loop.
+C-----------------------------------------------------------------------
+ 220  M = 0
+      DO 230 I = 1,N
+ 230    Y(I) = YH(I,1)
+      CALL F (NEQ, TN, Y, SAVF)
+      NFE = NFE + 1
+      IF (IPUP .LE. 0) GO TO 250
+C-----------------------------------------------------------------------
+C If indicated, the matrix P = I - h*el(1)*J is reevaluated and
+C preprocessed before starting the corrector iteration.  IPUP is set
+C to 0 as an indicator that this has been done.
+C-----------------------------------------------------------------------
+      CALL PJAC (NEQ, Y, YH, NYH, EWT, ACOR, SAVF, WM, IWM, F, JAC)
+      IPUP = 0
+      RC = 1.0E0
+      NSLP = NST
+      CRATE = 0.7E0
+      IF (IERPJ .NE. 0) GO TO 430
+ 250  DO 260 I = 1,N
+ 260    ACOR(I) = 0.0E0
+ 270  IF (MITER .NE. 0) GO TO 350
+C-----------------------------------------------------------------------
+C In the case of functional iteration, update Y directly from
+C the result of the last function evaluation.
+C-----------------------------------------------------------------------
+      DO 290 I = 1,N
+        SAVF(I) = H*SAVF(I) - YH(I,2)
+ 290    Y(I) = SAVF(I) - ACOR(I)
+      DEL = SVNORM (N, Y, EWT)
+      DO 300 I = 1,N
+        Y(I) = YH(I,1) + EL(1)*SAVF(I)
+ 300    ACOR(I) = SAVF(I)
+      GO TO 400
+C-----------------------------------------------------------------------
+C In the case of the chord method, compute the corrector error,
+C and solve the linear system with that as right-hand side and
+C P as coefficient matrix.
+C-----------------------------------------------------------------------
+ 350  DO 360 I = 1,N
+ 360    Y(I) = H*SAVF(I) - (YH(I,2) + ACOR(I))
+      CALL SLVS (WM, IWM, Y, SAVF)
+      IF (IERSL .LT. 0) GO TO 430
+      IF (IERSL .GT. 0) GO TO 410
+      DEL = SVNORM (N, Y, EWT)
+      DO 380 I = 1,N
+        ACOR(I) = ACOR(I) + Y(I)
+ 380    Y(I) = YH(I,1) + EL(1)*ACOR(I)
+C-----------------------------------------------------------------------
+C Test for convergence.  If M.gt.0, an estimate of the convergence
+C rate constant is stored in CRATE, and this is used in the test.
+C-----------------------------------------------------------------------
+ 400  IF (M .NE. 0) CRATE = MAX(0.2E0*CRATE,DEL/DELP)
+      DCON = DEL*MIN(1.0E0,1.5E0*CRATE)/(TESCO(2,NQ)*CONIT)
+      IF (DCON .LE. 1.0E0) GO TO 450
+      M = M + 1
+      IF (M .EQ. MAXCOR) GO TO 410
+      IF (M .GE. 2 .AND. DEL .GT. 2.0E0*DELP) GO TO 410
+      DELP = DEL
+      CALL F (NEQ, TN, Y, SAVF)
+      NFE = NFE + 1
+      GO TO 270
+C-----------------------------------------------------------------------
+C The corrector iteration failed to converge.
+C If MITER .ne. 0 and the Jacobian is out of date, PJAC is called for
+C the next try.  Otherwise the YH array is retracted to its values
+C before prediction, and H is reduced, if possible.  If H cannot be
+C reduced or MXNCF failures have occurred, exit with KFLAG = -2.
+C-----------------------------------------------------------------------
+ 410  IF (MITER .EQ. 0 .OR. JCUR .EQ. 1) GO TO 430
+      ICF = 1
+      IPUP = MITER
+      GO TO 220
+ 430  ICF = 2
+      NCF = NCF + 1
+      RMAX = 2.0E0
+      TN = TOLD
+      I1 = NQNYH + 1
+      DO 445 JB = 1,NQ
+        I1 = I1 - NYH
+Cdir$ ivdep
+        DO 440 I = I1,NQNYH
+ 440      YH1(I) = YH1(I) - YH1(I+NYH)
+ 445    CONTINUE
+      IF (IERPJ .LT. 0 .OR. IERSL .LT. 0) GO TO 680
+      IF (ABS(H) .LE. HMIN*1.00001E0) GO TO 670
+      IF (NCF .EQ. MXNCF) GO TO 670
+      RH = 0.25E0
+      IPUP = MITER
+      IREDO = 1
+      GO TO 170
+C-----------------------------------------------------------------------
+C The corrector has converged.  JCUR is set to 0
+C to signal that the Jacobian involved may need updating later.
+C The local error test is made and control passes to statement 500
+C if it fails.
+C-----------------------------------------------------------------------
+ 450  JCUR = 0
+      IF (M .EQ. 0) DSM = DEL/TESCO(2,NQ)
+      IF (M .GT. 0) DSM = SVNORM (N, ACOR, EWT)/TESCO(2,NQ)
+      IF (DSM .GT. 1.0E0) GO TO 500
+C-----------------------------------------------------------------------
+C After a successful step, update the YH array.
+C Consider changing H if IALTH = 1.  Otherwise decrease IALTH by 1.
+C If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
+C use in a possible order increase on the next step.
+C If a change in H is considered, an increase or decrease in order
+C by one is considered also.  A change in H is made only if it is by a
+C factor of at least 1.1.  If not, IALTH is set to 3 to prevent
+C testing for that many steps.
+C-----------------------------------------------------------------------
+      KFLAG = 0
+      IREDO = 0
+      NST = NST + 1
+      HU = H
+      NQU = NQ
+      DO 470 J = 1,L
+        DO 470 I = 1,N
+ 470      YH(I,J) = YH(I,J) + EL(J)*ACOR(I)
+      IALTH = IALTH - 1
+      IF (IALTH .EQ. 0) GO TO 520
+      IF (IALTH .GT. 1) GO TO 700
+      IF (L .EQ. LMAX) GO TO 700
+      DO 490 I = 1,N
+ 490    YH(I,LMAX) = ACOR(I)
+      GO TO 700
+C-----------------------------------------------------------------------
+C The error test failed.  KFLAG keeps track of multiple failures.
+C Restore TN and the YH array to their previous values, and prepare
+C to try the step again.  Compute the optimum step size for this or
+C one lower order.  After 2 or more failures, H is forced to decrease
+C by a factor of 0.2 or less.
+C-----------------------------------------------------------------------
+ 500  KFLAG = KFLAG - 1
+      TN = TOLD
+      I1 = NQNYH + 1
+      DO 515 JB = 1,NQ
+        I1 = I1 - NYH
+Cdir$ ivdep
+        DO 510 I = I1,NQNYH
+ 510      YH1(I) = YH1(I) - YH1(I+NYH)
+ 515    CONTINUE
+      RMAX = 2.0E0
+      IF (ABS(H) .LE. HMIN*1.00001E0) GO TO 660
+      IF (KFLAG .LE. -3) GO TO 640
+      IREDO = 2
+      RHUP = 0.0E0
+      GO TO 540
+C-----------------------------------------------------------------------
+C Regardless of the success or failure of the step, factors
+C RHDN, RHSM, and RHUP are computed, by which H could be multiplied
+C at order NQ - 1, order NQ, or order NQ + 1, respectively.
+C In the case of failure, RHUP = 0.0 to avoid an order increase.
+C The largest of these is determined and the new order chosen
+C accordingly.  If the order is to be increased, we compute one
+C additional scaled derivative.
+C-----------------------------------------------------------------------
+ 520  RHUP = 0.0E0
+      IF (L .EQ. LMAX) GO TO 540
+      DO 530 I = 1,N
+ 530    SAVF(I) = ACOR(I) - YH(I,LMAX)
+      DUP = SVNORM (N, SAVF, EWT)/TESCO(3,NQ)
+      EXUP = 1.0E0/(L+1)
+      RHUP = 1.0E0/(1.4E0*DUP**EXUP + 0.0000014E0)
+ 540  EXSM = 1.0E0/L
+      RHSM = 1.0E0/(1.2E0*DSM**EXSM + 0.0000012E0)
+      RHDN = 0.0E0
+      IF (NQ .EQ. 1) GO TO 560
+      DDN = SVNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
+      EXDN = 1.0E0/NQ
+      RHDN = 1.0E0/(1.3E0*DDN**EXDN + 0.0000013E0)
+ 560  IF (RHSM .GE. RHUP) GO TO 570
+      IF (RHUP .GT. RHDN) GO TO 590
+      GO TO 580
+ 570  IF (RHSM .LT. RHDN) GO TO 580
+      NEWQ = NQ
+      RH = RHSM
+      GO TO 620
+ 580  NEWQ = NQ - 1
+      RH = RHDN
+      IF (KFLAG .LT. 0 .AND. RH .GT. 1.0E0) RH = 1.0E0
+      GO TO 620
+ 590  NEWQ = L
+      RH = RHUP
+      IF (RH .LT. 1.1E0) GO TO 610
+      R = EL(L)/L
+      DO 600 I = 1,N
+ 600    YH(I,NEWQ+1) = ACOR(I)*R
+      GO TO 630
+ 610  IALTH = 3
+      GO TO 700
+ 620  IF ((KFLAG .EQ. 0) .AND. (RH .LT. 1.1E0)) GO TO 610
+      IF (KFLAG .LE. -2) RH = MIN(RH,0.2E0)
+C-----------------------------------------------------------------------
+C If there is a change of order, reset NQ, l, and the coefficients.
+C In any case H is reset according to RH and the YH array is rescaled.
+C Then exit from 690 if the step was OK, or redo the step otherwise.
+C-----------------------------------------------------------------------
+      IF (NEWQ .EQ. NQ) GO TO 170
+ 630  NQ = NEWQ
+      L = NQ + 1
+      IRET = 2
+      GO TO 150
+C-----------------------------------------------------------------------
+C Control reaches this section if 3 or more failures have occured.
+C If 10 failures have occurred, exit with KFLAG = -1.
+C It is assumed that the derivatives that have accumulated in the
+C YH array have errors of the wrong order.  Hence the first
+C derivative is recomputed, and the order is set to 1.  Then
+C H is reduced by a factor of 10, and the step is retried,
+C until it succeeds or H reaches HMIN.
+C-----------------------------------------------------------------------
+ 640  IF (KFLAG .EQ. -10) GO TO 660
+      RH = 0.1E0
+      RH = MAX(HMIN/ABS(H),RH)
+      H = H*RH
+      DO 645 I = 1,N
+ 645    Y(I) = YH(I,1)
+      CALL F (NEQ, TN, Y, SAVF)
+      NFE = NFE + 1
+      DO 650 I = 1,N
+ 650    YH(I,2) = H*SAVF(I)
+      IPUP = MITER
+      IALTH = 5
+      IF (NQ .EQ. 1) GO TO 200
+      NQ = 1
+      L = 2
+      IRET = 3
+      GO TO 150
+C-----------------------------------------------------------------------
+C All returns are made through this section.  H is saved in HOLD
+C to allow the caller to change H on the next step.
+C-----------------------------------------------------------------------
+ 660  KFLAG = -1
+      GO TO 720
+ 670  KFLAG = -2
+      GO TO 720
+ 680  KFLAG = -3
+      GO TO 720
+ 690  RMAX = 10.0E0
+ 700  R = 1.0E0/TESCO(2,NQU)
+      DO 710 I = 1,N
+ 710    ACOR(I) = ACOR(I)*R
+ 720  HOLD = H
+      JSTART = 1
+      RETURN
+C----------------------- END OF SUBROUTINE SSTODE ----------------------
+      END
diff --git a/libcruft/odepack/stode.f b/libcruft/odepack/stode.f
new file mode 100644
index 0000000..aa2d1e0
--- /dev/null
+++ b/libcruft/odepack/stode.f
@@ -0,0 +1,483 @@
+      SUBROUTINE STODE (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR,
+     1   WM, IWM, F, JAC, PJAC, SLVS, IERR)
+CLLL. OPTIMIZE
+      EXTERNAL F, JAC, PJAC, SLVS
+      INTEGER NEQ, NYH, IWM
+      INTEGER IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP,
+     1   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     2   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+      INTEGER I, I1, IREDO, IRET, J, JB, M, NCF, NEWQ
+      DOUBLE PRECISION Y, YH, YH1, EWT, SAVF, ACOR, WM
+      DOUBLE PRECISION CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO,
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
+      DOUBLE PRECISION DCON, DDN, DEL, DELP, DSM, DUP, EXDN, EXSM, EXUP,
+     1   R, RH, RHDN, RHSM, RHUP, TOLD, VNORM
+      DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*),
+     1   ACOR(*), WM(*), IWM(*)
+      COMMON /LS0001/ CONIT, CRATE, EL(13), ELCO(13,12),
+     1   HOLD, RMAX, TESCO(3,12),
+     2   CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, IOWND(14),
+     3   IALTH, IPUP, LMAX, MEO, NQNYH, NSLP,
+     4   ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, METH, MITER,
+     5   MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
+C-----------------------------------------------------------------------
+C STODE PERFORMS ONE STEP OF THE INTEGRATION OF AN INITIAL VALUE
+C PROBLEM FOR A SYSTEM OF ORDINARY DIFFERENTIAL EQUATIONS.
+C NOTE.. STODE IS INDEPENDENT OF THE VALUE OF THE ITERATION METHOD
+C INDICATOR MITER, WHEN THIS IS .NE. 0, AND HENCE IS INDEPENDENT
+C OF THE TYPE OF CHORD METHOD USED, OR THE JACOBIAN STRUCTURE.
+C COMMUNICATION WITH STODE IS DONE WITH THE FOLLOWING VARIABLES..
+C
+C NEQ    = INTEGER ARRAY CONTAINING PROBLEM SIZE IN NEQ(1), AND
+C          PASSED AS THE NEQ ARGUMENT IN ALL CALLS TO F AND JAC.
+C Y      = AN ARRAY OF LENGTH .GE. N USED AS THE Y ARGUMENT IN
+C          ALL CALLS TO F AND JAC.
+C YH     = AN NYH BY LMAX ARRAY CONTAINING THE DEPENDENT VARIABLES
+C          AND THEIR APPROXIMATE SCALED DERIVATIVES, WHERE
+C          LMAX = MAXORD + 1.  YH(I,J+1) CONTAINS THE APPROXIMATE
+C          J-TH DERIVATIVE OF Y(I), SCALED BY H**J/FACTORIAL(J)
+C          (J = 0,1,...,NQ).  ON ENTRY FOR THE FIRST STEP, THE FIRST
+C          TWO COLUMNS OF YH MUST BE SET FROM THE INITIAL VALUES.
+C NYH    = A CONSTANT INTEGER .GE. N, THE FIRST DIMENSION OF YH.
+C YH1    = A ONE-DIMENSIONAL ARRAY OCCUPYING THE SAME SPACE AS YH.
+C EWT    = AN ARRAY OF LENGTH N CONTAINING MULTIPLICATIVE WEIGHTS
+C          FOR LOCAL ERROR MEASUREMENTS.  LOCAL ERRORS IN Y(I) ARE
+C          COMPARED TO 1.0/EWT(I) IN VARIOUS ERROR TESTS.
+C SAVF   = AN ARRAY OF WORKING STORAGE, OF LENGTH N.
+C          ALSO USED FOR INPUT OF YH(*,MAXORD+2) WHEN JSTART = -1
+C          AND MAXORD .LT. THE CURRENT ORDER NQ.
+C ACOR   = A WORK ARRAY OF LENGTH N, USED FOR THE ACCUMULATED
+C          CORRECTIONS.  ON A SUCCESSFUL RETURN, ACOR(I) CONTAINS
+C          THE ESTIMATED ONE-STEP LOCAL ERROR IN Y(I).
+C WM,IWM = REAL AND INTEGER WORK ARRAYS ASSOCIATED WITH MATRIX
+C          OPERATIONS IN CHORD ITERATION (MITER .NE. 0).
+C PJAC   = NAME OF ROUTINE TO EVALUATE AND PREPROCESS JACOBIAN MATRIX 
+C          AND P = I - H*EL0*JAC, IF A CHORD METHOD IS BEING USED.
+C SLVS   = NAME OF ROUTINE TO SOLVE LINEAR SYSTEM IN CHORD ITERATION. 
+C CCMAX  = MAXIMUM RELATIVE CHANGE IN H*EL0 BEFORE PJAC IS CALLED.
+C H      = THE STEP SIZE TO BE ATTEMPTED ON THE NEXT STEP.
+C          H IS ALTERED BY THE ERROR CONTROL ALGORITHM DURING THE
+C          PROBLEM.  H CAN BE EITHER POSITIVE OR NEGATIVE, BUT ITS
+C          SIGN MUST REMAIN CONSTANT THROUGHOUT THE PROBLEM.
+C HMIN   = THE MINIMUM ABSOLUTE VALUE OF THE STEP SIZE H TO BE USED.
+C HMXI   = INVERSE OF THE MAXIMUM ABSOLUTE VALUE OF H TO BE USED.
+C          HMXI = 0.0 IS ALLOWED AND CORRESPONDS TO AN INFINITE HMAX. 
+C          HMIN AND HMXI MAY BE CHANGED AT ANY TIME, BUT WILL NOT
+C          TAKE EFFECT UNTIL THE NEXT CHANGE OF H IS CONSIDERED.
+C TN     = THE INDEPENDENT VARIABLE. TN IS UPDATED ON EACH STEP TAKEN.
+C JSTART = AN INTEGER USED FOR INPUT ONLY, WITH THE FOLLOWING
+C          VALUES AND MEANINGS..
+C               0  PERFORM THE FIRST STEP.
+C           .GT.0  TAKE A NEW STEP CONTINUING FROM THE LAST.
+C              -1  TAKE THE NEXT STEP WITH A NEW VALUE OF H, MAXORD,
+C                    N, METH, MITER, AND/OR MATRIX PARAMETERS.
+C              -2  TAKE THE NEXT STEP WITH A NEW VALUE OF H,
+C                    BUT WITH OTHER INPUTS UNCHANGED.
+C          ON RETURN, JSTART IS SET TO 1 TO FACILITATE CONTINUATION.
+C KFLAG  = A COMPLETION CODE WITH THE FOLLOWING MEANINGS..
+C               0  THE STEP WAS SUCCESFUL.
+C              -1  THE REQUESTED ERROR COULD NOT BE ACHIEVED.
+C              -2  CORRECTOR CONVERGENCE COULD NOT BE ACHIEVED.
+C              -3  FATAL ERROR IN PJAC OR SLVS.
+C          A RETURN WITH KFLAG = -1 OR -2 MEANS EITHER
+C          ABS(H) = HMIN OR 10 CONSECUTIVE FAILURES OCCURRED.
+C          ON A RETURN WITH KFLAG NEGATIVE, THE VALUES OF TN AND
+C          THE YH ARRAY ARE AS OF THE BEGINNING OF THE LAST 
+C          STEP, AND H IS THE LAST STEP SIZE ATTEMPTED.
+C MAXORD = THE MAXIMUM ORDER OF INTEGRATION METHOD TO BE ALLOWED.
+C MAXCOR = THE MAXIMUM NUMBER OF CORRECTOR ITERATIONS ALLOWED.
+C MSBP   = MAXIMUM NUMBER OF STEPS BETWEEN PJAC CALLS (MITER .GT. 0). 
+C MXNCF  = MAXIMUM NUMBER OF CONVERGENCE FAILURES ALLOWED.
+C METH/MITER = THE METHOD FLAGS.  SEE DESCRIPTION IN DRIVER.
+C N      = THE NUMBER OF FIRST-ORDER DIFFERENTIAL EQUATIONS.
+C IERR   = ERROR FLAG FROM USER-SUPPLIED FUNCTION
+C-----------------------------------------------------------------------
+      KFLAG = 0
+      TOLD = TN
+      NCF = 0
+      IERPJ = 0
+      IERSL = 0
+      JCUR = 0
+      ICF = 0
+      DELP = 0.0D0
+      IF (JSTART .GT. 0) GO TO 200
+      IF (JSTART .EQ. -1) GO TO 100
+      IF (JSTART .EQ. -2) GO TO 160
+C-----------------------------------------------------------------------
+C ON THE FIRST CALL, THE ORDER IS SET TO 1, AND OTHER VARIABLES ARE
+C INITIALIZED.  RMAX IS THE MAXIMUM RATIO BY WHICH H CAN BE INCREASED 
+C IN A SINGLE STEP.  IT IS INITIALLY 1.E4 TO COMPENSATE FOR THE SMALL 
+C INITIAL H, BUT THEN IS NORMALLY EQUAL TO 10.  IF A FAILURE
+C OCCURS (IN CORRECTOR CONVERGENCE OR ERROR TEST), RMAX IS SET AT 2
+C FOR THE NEXT INCREASE.
+C-----------------------------------------------------------------------
+      LMAX = MAXORD + 1
+      NQ = 1
+      L = 2
+      IALTH = 2
+      RMAX = 10000.0D0
+      RC = 0.0D0
+      EL0 = 1.0D0
+      CRATE = 0.7D0 
+      HOLD = H
+      MEO = METH
+      NSLP = 0
+      IPUP = MITER
+      IRET = 3
+      GO TO 140
+C-----------------------------------------------------------------------
+C THE FOLLOWING BLOCK HANDLES PRELIMINARIES NEEDED WHEN JSTART = -1.
+C IPUP IS SET TO MITER TO FORCE A MATRIX UPDATE.
+C IF AN ORDER INCREASE IS ABOUT TO BE CONSIDERED (IALTH = 1),
+C IALTH IS RESET TO 2 TO POSTPONE CONSIDERATION ONE MORE STEP.
+C IF THE CALLER HAS CHANGED METH, CFODE IS CALLED TO RESET
+C THE COEFFICIENTS OF THE METHOD.
+C IF THE CALLER HAS CHANGED MAXORD TO A VALUE LESS THAN THE CURRENT
+C ORDER NQ, NQ IS REDUCED TO MAXORD, AND A NEW H CHOSEN ACCORDINGLY.
+C IF H IS TO BE CHANGED, YH MUST BE RESCALED.
+C IF H OR METH IS BEING CHANGED, IALTH IS RESET TO L = NQ + 1
+C TO PREVENT FURTHER CHANGES IN H FOR THAT MANY STEPS.
+C-----------------------------------------------------------------------
+ 100  IPUP = MITER
+      LMAX = MAXORD + 1
+      IF (IALTH .EQ. 1) IALTH = 2
+      IF (METH .EQ. MEO) GO TO 110
+      CALL CFODE (METH, ELCO, TESCO)
+      MEO = METH
+      IF (NQ .GT. MAXORD) GO TO 120
+      IALTH = L
+      IRET = 1
+      GO TO 150
+ 110  IF (NQ .LE. MAXORD) GO TO 160
+ 120  NQ = MAXORD
+      L = LMAX
+      DO 125 I = 1,L
+ 125    EL(I) = ELCO(I,NQ)
+      NQNYH = NQ*NYH
+      RC = RC*EL(1)/EL0
+      EL0 = EL(1)
+      CONIT = 0.5D0/DBLE(NQ+2)
+      DDN = VNORM (N, SAVF, EWT)/TESCO(1,L)
+      EXDN = 1.0D0/DBLE(L)  
+      RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
+      RH = DMIN1(RHDN,1.0D0)
+      IREDO = 3
+      IF (H .EQ. HOLD) GO TO 170
+      RH = DMIN1(RH,DABS(H/HOLD))
+      H = HOLD
+      GO TO 175
+C-----------------------------------------------------------------------
+C CFODE IS CALLED TO GET ALL THE INTEGRATION COEFFICIENTS FOR THE
+C CURRENT METH.  THEN THE EL VECTOR AND RELATED CONSTANTS ARE RESET
+C WHENEVER THE ORDER NQ IS CHANGED, OR AT THE START OF THE PROBLEM.
+C-----------------------------------------------------------------------
+ 140  CALL CFODE (METH, ELCO, TESCO)
+ 150  DO 155 I = 1,L
+ 155    EL(I) = ELCO(I,NQ)
+      NQNYH = NQ*NYH
+      RC = RC*EL(1)/EL0
+      EL0 = EL(1)
+      CONIT = 0.5D0/DBLE(NQ+2)
+      GO TO (160, 170, 200), IRET
+C-----------------------------------------------------------------------
+C IF H IS BEING CHANGED, THE H RATIO RH IS CHECKED AGAINST
+C RMAX, HMIN, AND HMXI, AND THE YH ARRAY RESCALED.  IALTH IS SET TO
+C L = NQ + 1 TO PREVENT A CHANGE OF H FOR THAT MANY STEPS, UNLESS
+C FORCED BY A CONVERGENCE OR ERROR TEST FAILURE.
+C-----------------------------------------------------------------------
+ 160  IF (H .EQ. HOLD) GO TO 200
+      RH = H/HOLD
+      H = HOLD
+      IREDO = 3
+      GO TO 175
+ 170  RH = DMAX1(RH,HMIN/DABS(H))
+ 175  RH = DMIN1(RH,RMAX)
+      RH = RH/DMAX1(1.0D0,DABS(H)*HMXI*RH)
+      R = 1.0D0
+      DO 180 J = 2,L
+        R = R*RH
+        DO 180 I = 1,N
+ 180      YH(I,J) = YH(I,J)*R 
+      H = H*RH
+      RC = RC*RH
+      IALTH = L
+      IF (IREDO .EQ. 0) GO TO 690
+C-----------------------------------------------------------------------
+C THIS SECTION COMPUTES THE PREDICTED VALUES BY EFFECTIVELY 
+C MULTIPLYING THE YH ARRAY BY THE PASCAL TRIANGLE MATRIX.
+C RC IS THE RATIO OF NEW TO OLD VALUES OF THE COEFFICIENT  H*EL(1).
+C WHEN RC DIFFERS FROM 1 BY MORE THAN CCMAX, IPUP IS SET TO MITER
+C TO FORCE PJAC TO BE CALLED, IF A JACOBIAN IS INVOLVED.
+C IN ANY CASE, PJAC IS CALLED AT LEAST EVERY MSBP STEPS.
+C-----------------------------------------------------------------------
+ 200  IF (DABS(RC-1.0D0) .GT. CCMAX) IPUP = MITER 
+      IF (NST .GE. NSLP+MSBP) IPUP = MITER
+      TN = TN + H
+      I1 = NQNYH + 1
+      DO 215 JB = 1,NQ
+        I1 = I1 - NYH
+CDIR$ IVDEP
+        DO 210 I = I1,NQNYH
+ 210      YH1(I) = YH1(I) + YH1(I+NYH)
+ 215    CONTINUE
+C-----------------------------------------------------------------------
+C UP TO MAXCOR CORRECTOR ITERATIONS ARE TAKEN.  A CONVERGENCE TEST IS 
+C MADE ON THE R.M.S. NORM OF EACH CORRECTION, WEIGHTED BY THE ERROR
+C WEIGHT VECTOR EWT.  THE SUM OF THE CORRECTIONS IS ACCUMULATED IN THE
+C VECTOR ACOR(I).  THE YH ARRAY IS NOT ALTERED IN THE CORRECTOR LOOP. 
+C-----------------------------------------------------------------------
+ 220  M = 0
+      DO 230 I = 1,N
+ 230    Y(I) = YH(I,1)
+      IERR = 0
+      CALL F (NEQ, TN, Y, SAVF, IERR)
+      IF (IERR .LT. 0) RETURN
+      NFE = NFE + 1 
+      IF (IPUP .LE. 0) GO TO 250
+C-----------------------------------------------------------------------
+C IF INDICATED, THE MATRIX P = I - H*EL(1)*J IS REEVALUATED AND
+C PREPROCESSED BEFORE STARTING THE CORRECTOR ITERATION.  IPUP IS SET
+C TO 0 AS AN INDICATOR THAT THIS HAS BEEN DONE.
+C-----------------------------------------------------------------------
+      IERR = 0
+      CALL PJAC (NEQ, Y, YH, NYH, EWT, ACOR, SAVF, WM, IWM, F, JAC,
+     1   IERR)
+      IF (IERR .LT. 0) RETURN
+      IPUP = 0
+      RC = 1.0D0
+      NSLP = NST
+      CRATE = 0.7D0 
+      IF (IERPJ .NE. 0) GO TO 430
+ 250  DO 260 I = 1,N
+ 260    ACOR(I) = 0.0D0
+ 270  IF (MITER .NE. 0) GO TO 350
+C-----------------------------------------------------------------------
+C IN THE CASE OF FUNCTIONAL ITERATION, UPDATE Y DIRECTLY FROM
+C THE RESULT OF THE LAST FUNCTION EVALUATION.
+C-----------------------------------------------------------------------
+      DO 290 I = 1,N
+        SAVF(I) = H*SAVF(I) - YH(I,2)
+ 290    Y(I) = SAVF(I) - ACOR(I)
+      DEL = VNORM (N, Y, EWT) 
+      DO 300 I = 1,N
+        Y(I) = YH(I,1) + EL(1)*SAVF(I)
+ 300    ACOR(I) = SAVF(I)
+      GO TO 400
+C-----------------------------------------------------------------------
+C IN THE CASE OF THE CHORD METHOD, COMPUTE THE CORRECTOR ERROR,
+C AND SOLVE THE LINEAR SYSTEM WITH THAT AS RIGHT-HAND SIDE AND
+C P AS COEFFICIENT MATRIX.
+C-----------------------------------------------------------------------
+ 350  DO 360 I = 1,N
+ 360    Y(I) = H*SAVF(I) - (YH(I,2) + ACOR(I))
+      CALL SLVS (WM, IWM, Y, SAVF)
+      IF (IERSL .LT. 0) GO TO 430
+      IF (IERSL .GT. 0) GO TO 410
+      DEL = VNORM (N, Y, EWT) 
+      DO 380 I = 1,N
+        ACOR(I) = ACOR(I) + Y(I)
+ 380    Y(I) = YH(I,1) + EL(1)*ACOR(I)
+C-----------------------------------------------------------------------
+C TEST FOR CONVERGENCE.  IF M.GT.0, AN ESTIMATE OF THE CONVERGENCE
+C RATE CONSTANT IS STORED IN CRATE, AND THIS IS USED IN THE TEST.
+C-----------------------------------------------------------------------
+ 400  IF (M .NE. 0) CRATE = DMAX1(0.2D0*CRATE,DEL/DELP)
+      DCON = DEL*DMIN1(1.0D0,1.5D0*CRATE)/(TESCO(2,NQ)*CONIT)
+      IF (DCON .LE. 1.0D0) GO TO 450
+      M = M + 1
+      IF (M .EQ. MAXCOR) GO TO 410
+      IF (M .GE. 2 .AND. DEL .GT. 2.0D0*DELP) GO TO 410
+      DELP = DEL
+      IERR = 0
+      CALL F (NEQ, TN, Y, SAVF, IERR)
+      IF (IERR .LT. 0) RETURN
+      NFE = NFE + 1 
+      GO TO 270
+C-----------------------------------------------------------------------
+C THE CORRECTOR ITERATION FAILED TO CONVERGE.
+C IF MITER .NE. 0 AND THE JACOBIAN IS OUT OF DATE, PJAC IS CALLED FOR 
+C THE NEXT TRY.  OTHERWISE THE YH ARRAY IS RETRACTED TO ITS VALUES
+C BEFORE PREDICTION, AND H IS REDUCED, IF POSSIBLE.  IF H CANNOT BE
+C REDUCED OR MXNCF FAILURES HAVE OCCURRED, EXIT WITH KFLAG = -2.
+C-----------------------------------------------------------------------
+ 410  IF (MITER .EQ. 0 .OR. JCUR .EQ. 1) GO TO 430
+      ICF = 1
+      IPUP = MITER
+      GO TO 220
+ 430  ICF = 2
+      NCF = NCF + 1 
+      RMAX = 2.0D0
+      TN = TOLD
+      I1 = NQNYH + 1
+      DO 445 JB = 1,NQ
+        I1 = I1 - NYH
+CDIR$ IVDEP
+        DO 440 I = I1,NQNYH
+ 440      YH1(I) = YH1(I) - YH1(I+NYH)
+ 445    CONTINUE
+      IF (IERPJ .LT. 0 .OR. IERSL .LT. 0) GO TO 680
+      IF (DABS(H) .LE. HMIN*1.00001D0) GO TO 670
+      IF (NCF .EQ. MXNCF) GO TO 670
+      RH = 0.25D0
+      IPUP = MITER
+      IREDO = 1
+      GO TO 170
+C-----------------------------------------------------------------------
+C THE CORRECTOR HAS CONVERGED.  JCUR IS SET TO 0
+C TO SIGNAL THAT THE JACOBIAN INVOLVED MAY NEED UPDATING LATER.
+C THE LOCAL ERROR TEST IS MADE AND CONTROL PASSES TO STATEMENT 500
+C IF IT FAILS.
+C-----------------------------------------------------------------------
+ 450  JCUR = 0
+      IF (M .EQ. 0) DSM = DEL/TESCO(2,NQ)
+      IF (M .GT. 0) DSM = VNORM (N, ACOR, EWT)/TESCO(2,NQ)
+      IF (DSM .GT. 1.0D0) GO TO 500
+C-----------------------------------------------------------------------
+C AFTER A SUCCESSFUL STEP, UPDATE THE YH ARRAY.
+C CONSIDER CHANGING H IF IALTH = 1.  OTHERWISE DECREASE IALTH BY 1.
+C IF IALTH IS THEN 1 AND NQ .LT. MAXORD, THEN ACOR IS SAVED FOR
+C USE IN A POSSIBLE ORDER INCREASE ON THE NEXT STEP.
+C IF A CHANGE IN H IS CONSIDERED, AN INCREASE OR DECREASE IN ORDER
+C BY ONE IS CONSIDERED ALSO.  A CHANGE IN H IS MADE ONLY IF IT IS BY A
+C FACTOR OF AT LEAST 1.1.  IF NOT, IALTH IS SET TO 3 TO PREVENT
+C TESTING FOR THAT MANY STEPS.
+C-----------------------------------------------------------------------
+      KFLAG = 0
+      IREDO = 0
+      NST = NST + 1 
+      HU = H
+      NQU = NQ
+      DO 470 J = 1,L
+        DO 470 I = 1,N
+ 470      YH(I,J) = YH(I,J) + EL(J)*ACOR(I)
+      IALTH = IALTH - 1
+      IF (IALTH .EQ. 0) GO TO 520
+      IF (IALTH .GT. 1) GO TO 700
+      IF (L .EQ. LMAX) GO TO 700
+      DO 490 I = 1,N
+ 490    YH(I,LMAX) = ACOR(I)
+      GO TO 700
+C-----------------------------------------------------------------------
+C THE ERROR TEST FAILED.  KFLAG KEEPS TRACK OF MULTIPLE FAILURES.
+C RESTORE TN AND THE YH ARRAY TO THEIR PREVIOUS VALUES, AND PREPARE
+C TO TRY THE STEP AGAIN.  COMPUTE THE OPTIMUM STEP SIZE FOR THIS OR
+C ONE LOWER ORDER.  AFTER 2 OR MORE FAILURES, H IS FORCED TO DECREASE 
+C BY A FACTOR OF 0.2 OR LESS. 
+C-----------------------------------------------------------------------
+ 500  KFLAG = KFLAG - 1
+      TN = TOLD
+      I1 = NQNYH + 1
+      DO 515 JB = 1,NQ
+        I1 = I1 - NYH
+CDIR$ IVDEP
+        DO 510 I = I1,NQNYH
+ 510      YH1(I) = YH1(I) - YH1(I+NYH)
+ 515    CONTINUE
+      RMAX = 2.0D0
+      IF (DABS(H) .LE. HMIN*1.00001D0) GO TO 660
+      IF (KFLAG .LE. -3) GO TO 640
+      IREDO = 2
+      RHUP = 0.0D0
+      GO TO 540
+C-----------------------------------------------------------------------
+C REGARDLESS OF THE SUCCESS OR FAILURE OF THE STEP, FACTORS 
+C RHDN, RHSM, AND RHUP ARE COMPUTED, BY WHICH H COULD BE MULTIPLIED
+C AT ORDER NQ - 1, ORDER NQ, OR ORDER NQ + 1, RESPECTIVELY. 
+C IN THE CASE OF FAILURE, RHUP = 0.0 TO AVOID AN ORDER INCREASE.
+C THE LARGEST OF THESE IS DETERMINED AND THE NEW ORDER CHOSEN
+C ACCORDINGLY.  IF THE ORDER IS TO BE INCREASED, WE COMPUTE ONE
+C ADDITIONAL SCALED DERIVATIVE.
+C-----------------------------------------------------------------------
+ 520  RHUP = 0.0D0
+      IF (L .EQ. LMAX) GO TO 540
+      DO 530 I = 1,N
+ 530    SAVF(I) = ACOR(I) - YH(I,LMAX)
+      DUP = VNORM (N, SAVF, EWT)/TESCO(3,NQ)
+      EXUP = 1.0D0/DBLE(L+1)
+      RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0)
+ 540  EXSM = 1.0D0/DBLE(L)  
+      RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
+      RHDN = 0.0D0
+      IF (NQ .EQ. 1) GO TO 560
+      DDN = VNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
+      EXDN = 1.0D0/DBLE(NQ) 
+      RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
+ 560  IF (RHSM .GE. RHUP) GO TO 570
+      IF (RHUP .GT. RHDN) GO TO 590
+      GO TO 580
+ 570  IF (RHSM .LT. RHDN) GO TO 580
+      NEWQ = NQ
+      RH = RHSM
+      GO TO 620
+ 580  NEWQ = NQ - 1 
+      RH = RHDN
+      IF (KFLAG .LT. 0 .AND. RH .GT. 1.0D0) RH = 1.0D0
+      GO TO 620
+ 590  NEWQ = L
+      RH = RHUP
+      IF (RH .LT. 1.1D0) GO TO 610
+      R = EL(L)/DBLE(L)     
+      DO 600 I = 1,N
+ 600    YH(I,NEWQ+1) = ACOR(I)*R
+      GO TO 630
+ 610  IALTH = 3
+      GO TO 700
+ 620  IF ((KFLAG .EQ. 0) .AND. (RH .LT. 1.1D0)) GO TO 610
+      IF (KFLAG .LE. -2) RH = DMIN1(RH,0.2D0)
+C-----------------------------------------------------------------------
+C IF THERE IS A CHANGE OF ORDER, RESET NQ, L, AND THE COEFFICIENTS.
+C IN ANY CASE H IS RESET ACCORDING TO RH AND THE YH ARRAY IS RESCALED.
+C THEN EXIT FROM 690 IF THE STEP WAS OK, OR REDO THE STEP OTHERWISE.
+C-----------------------------------------------------------------------
+      IF (NEWQ .EQ. NQ) GO TO 170
+ 630  NQ = NEWQ
+      L = NQ + 1
+      IRET = 2
+      GO TO 150
+C-----------------------------------------------------------------------
+C CONTROL REACHES THIS SECTION IF 3 OR MORE FAILURES HAVE OCCURED.
+C IF 10 FAILURES HAVE OCCURRED, EXIT WITH KFLAG = -1.
+C IT IS ASSUMED THAT THE DERIVATIVES THAT HAVE ACCUMULATED IN THE
+C YH ARRAY HAVE ERRORS OF THE WRONG ORDER.  HENCE THE FIRST 
+C DERIVATIVE IS RECOMPUTED, AND THE ORDER IS SET TO 1.  THEN
+C H IS REDUCED BY A FACTOR OF 10, AND THE STEP IS RETRIED,
+C UNTIL IT SUCCEEDS OR H REACHES HMIN.
+C-----------------------------------------------------------------------
+ 640  IF (KFLAG .EQ. -10) GO TO 660
+      RH = 0.1D0
+      RH = DMAX1(HMIN/DABS(H),RH)
+      H = H*RH
+      DO 645 I = 1,N
+ 645    Y(I) = YH(I,1)
+      IERR = 0
+      CALL F (NEQ, TN, Y, SAVF, IERR)
+      IF (IERR .LT. 0) RETURN
+      NFE = NFE + 1 
+      DO 650 I = 1,N
+ 650    YH(I,2) = H*SAVF(I)
+      IPUP = MITER
+      IALTH = 5
+      IF (NQ .EQ. 1) GO TO 200
+      NQ = 1
+      L = 2
+      IRET = 3
+      GO TO 150
+C-----------------------------------------------------------------------
+C ALL RETURNS ARE MADE THROUGH THIS SECTION.  H IS SAVED IN HOLD
+C TO ALLOW THE CALLER TO CHANGE H ON THE NEXT STEP.
+C-----------------------------------------------------------------------
+ 660  KFLAG = -1
+      GO TO 720
+ 670  KFLAG = -2
+      GO TO 720
+ 680  KFLAG = -3
+      GO TO 720
+ 690  RMAX = 10.0D0 
+ 700  R = 1.0D0/TESCO(2,NQU)
+      DO 710 I = 1,N
+ 710    ACOR(I) = ACOR(I)*R
+ 720  HOLD = H
+      JSTART = 1
+      RETURN
+C----------------------- END OF SUBROUTINE STODE -----------------------
+      END 
diff --git a/libcruft/odepack/svnorm.f b/libcruft/odepack/svnorm.f
new file mode 100644
index 0000000..f10689e
--- /dev/null
+++ b/libcruft/odepack/svnorm.f
@@ -0,0 +1,34 @@
+      REAL FUNCTION SVNORM (N, V, W)
+C***BEGIN PROLOGUE  SVNORM
+C***SUBSIDIARY
+C***PURPOSE  Weighted root-mean-square vector norm.
+C***TYPE      SINGLE PRECISION (SVNORM-S, DVNORM-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  This function routine computes the weighted root-mean-square norm
+C  of the vector of length N contained in the array V, with weights
+C  contained in the array W of length N:
+C    SVNORM = SQRT( (1/N) * SUM( V(i)*W(i) )**2 )
+C
+C***SEE ALSO  SLSODE
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   791129  DATE WRITTEN
+C   890501  Modified prologue to SLATEC/LDOC format.  (FNF)
+C   890503  Minor cosmetic changes.  (FNF)
+C   930809  Renamed to allow single/double precision versions. (ACH)
+C***END PROLOGUE  SVNORM
+C**End
+      INTEGER N,   I
+      REAL V, W,   SUM
+      DIMENSION V(N), W(N)
+C
+C***FIRST EXECUTABLE STATEMENT  SVNORM
+      SUM = 0.0E0
+      DO 10 I = 1,N
+ 10     SUM = SUM + (V(I)*W(I))**2
+      SVNORM = SQRT(SUM/N)
+      RETURN
+C----------------------- END OF FUNCTION SVNORM ------------------------
+      END
diff --git a/libcruft/odepack/vnorm.f b/libcruft/odepack/vnorm.f
new file mode 100644
index 0000000..4c02a56
--- /dev/null
+++ b/libcruft/odepack/vnorm.f
@@ -0,0 +1,18 @@
+      DOUBLE PRECISION FUNCTION VNORM (N, V, W)
+CLLL. OPTIMIZE
+C-----------------------------------------------------------------------
+C THIS FUNCTION ROUTINE COMPUTES THE WEIGHTED ROOT-MEAN-SQUARE NORM
+C OF THE VECTOR OF LENGTH N CONTAINED IN THE ARRAY V, WITH WEIGHTS
+C CONTAINED IN THE ARRAY W OF LENGTH N..
+C   VNORM = SQRT( (1/N) * SUM( V(I)*W(I) )**2 )
+C-----------------------------------------------------------------------
+      INTEGER N,   I
+      DOUBLE PRECISION V, W,   SUM
+      DIMENSION V(N), W(N)
+      SUM = 0.0D0
+      DO 10 I = 1,N 
+ 10     SUM = SUM + (V(I)*W(I))**2
+      VNORM = DSQRT(SUM/DBLE(N))      
+      RETURN
+C----------------------- END OF FUNCTION VNORM -------------------------
+      END 
diff --git a/libcruft/ordered-qz/Makefile.in b/libcruft/ordered-qz/Makefile.in
new file mode 100644
index 0000000..bdda8c2
--- /dev/null
+++ b/libcruft/ordered-qz/Makefile.in
@@ -0,0 +1,33 @@
+# Makefile for octave's libcruft/ordered-qz directory
+#
+# Copyright (C) 1998, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = dsubsp.f exchqz.f ssubsp.f sexchqz.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/ordered-qz/dsubsp.f b/libcruft/ordered-qz/dsubsp.f
new file mode 100644
index 0000000..da554e8
--- /dev/null
+++ b/libcruft/ordered-qz/dsubsp.f
@@ -0,0 +1,104 @@
+      SUBROUTINE DSUBSP(NMAX, N, A, B, Z, FTEST, EPS, NDIM, FAIL, IND)
+      INTEGER NMAX, N, FTEST, NDIM, IND(N)
+      LOGICAL FAIL
+      DOUBLE PRECISION A(NMAX,N), B(NMAX,N), Z(NMAX,N), EPS
+C*
+C* GIVEN THE UPPER TRIANGULAR MATRIX B AND UPPER HESSENBERG MATRIX A
+C* WITH 1X1 OR 2X2 DIAGONAL BLOCKS, THIS ROUTINE REORDERS THE DIAGONAL
+C* BLOCKS ALONG WITH THEIR GENERALIZED EIGENVALUES BY CONSTRUCTING EQUI-
+C* VALENCE TRANSFORMATIONS QT AND ZT. THE ROW TRANSFORMATION ZT IS ALSO
+C* PERFORMED ON THE GIVEN (INITIAL) TRANSFORMATION Z (RESULTING FROM A
+C* POSSIBLE PREVIOUS STEP OR INITIALIZED WITH THE IDENTITY MATRIX).
+C* AFTER REORDERING, THE EIGENVALUES INSIDE THE REGION SPECIFIED BY THE
+C* FUNCTION FTEST APPEAR AT THE TOP. IF NDIM IS THEIR NUMBER THEN THE
+C* NDIM FIRST COLUMNS OF Z SPAN THE REQUESTED SUBSPACE. DSUBSP REQUIRES
+C* THE SUBROUTINE EXCHQZ AND THE INTEGER FUNCTION FTEST WHICH HAS TO BE
+C* PROVIDED BY THE USER. THE PARAMETERS IN THE CALLING SEQUENCE ARE :
+C* (STARRED PARAMETERS ARE ALTERED BY THE SUBROUTINE)
+C*
+C*    NMAX     THE FIRST DIMENSION OF A, B AND Z
+C*    N        THE ORDER OF A, B AND Z
+C*   *A,*B     THE MATRIX PAIR WHOSE BLOCKS ARE TO BE REORDERED.
+C*   *Z        UPON RETURN THIS ARRAY IS MULTIPLIED BY THE COLUMN
+C*             TRANSFORMATION ZT.
+C*    FTEST(LS,ALPHA,BETA,S,P) AN INTEGER FUNCTION DESCRIBING THE
+C*             SPECTRUM OF THE DEFLATING SUBSPACE TO BE COMPUTED:
+C*             WHEN LS=1 FTEST CHECKS IF ALPHA/BETA IS IN THAT SPECTRUM
+C*             WHEN LS=2 FTEST CHECKS IF THE TWO COMPLEX CONJUGATE
+C*             ROOTS WITH SUM S AND PRODUCT P ARE IN THAT SPECTRUM
+C*             IF THE ANSWER IS POSITIVE, FTEST=1, OTHERWISE FTEST=-1
+C*    EPS      THE REQUIRED ABSOLUTE ACCURACY OF THE RESULT
+C*   *NDIM     AN INTEGER GIVING THE DIMENSION OF THE COMPUTED
+C*             DEFLATING SUBSPACE
+C*   *FAIL     A LOGICAL VARIABLE WHICH IS FALSE ON A NORMAL RETURN,
+C*             TRUE OTHERWISE (WHEN EXCHQZ FAILS)
+C*   *IND      AN INTEGER WORKING ARRAY OF DIMENSION AT LEAST N
+C*
+      INTEGER L, LS, LS1, LS2, L1, LL, NUM, IS, L2I, L2K, I, K, II,
+     * ISTEP, IFIRST
+      DOUBLE PRECISION S, P, D, ALPHA, BETA
+      FAIL = .TRUE.
+      NDIM = 0
+      NUM = 0
+      L = 0
+      LS = 1
+C*** CONSTRUCT ARRAY IND(I) WHERE :
+C***     IABS(IND(I)) IS THE SIZE OF THE BLOCK I
+C***     SIGN(IND(I)) INDICATES THE LOCATION OF ITS EIGENVALUES
+C***                  (AS DETERMINED BY FTEST).
+C*** NUM IS THE NUMBER OF ELEMENTS IN THIS ARRAY
+      DO 30 LL=1,N
+        L = L + LS
+        IF (L.GT.N) GO TO 40
+        L1 = L + 1
+        IF (L1.GT.N) GO TO 10
+        IF (A(L1,L).EQ.0.) GO TO 10
+C* HERE A 2X2  BLOCK IS CHECKED *
+        LS = 2
+        D = B(L,L)*B(L1,L1)
+        S = (A(L,L)*B(L1,L1)+A(L1,L1)*B(L,L)-A(L1,L)*B(L,L1))/D
+        P = (A(L,L)*A(L1,L1)-A(L,L1)*A(L1,L))/D
+        IS = FTEST(LS,ALPHA,BETA,S,P)
+        GO TO 20
+C* HERE A 1X1  BLOCK IS CHECKED *
+   10   LS = 1
+        IS = FTEST(LS,A(L,L),B(L,L),S,P)
+   20   NUM = NUM + 1
+        IF (IS.EQ.1) NDIM = NDIM + LS
+        IND(NUM) = LS*IS
+   30 CONTINUE
+C***  REORDER BLOCKS SUCH THAT THOSE WITH POSITIVE VALUE
+C***    OF IND(.) APPEAR FIRST.
+   40 L2I = 1
+      DO 100 I=1,NUM
+        IF (IND(I).GT.0) GO TO 90
+C* IF A NEGATIVE IND(I) IS ENCOUNTERED, THEN SEARCH FOR THE FIRST
+C* POSITIVE IND(K) FOLLOWING ON IT
+        L2K = L2I
+        DO 60 K=I,NUM
+          IF (IND(K).LT.0) GO TO 50
+          GO TO 70
+   50     L2K = L2K - IND(K)
+   60   CONTINUE
+C* IF THERE ARE NO POSITIVE INDICES FOLLOWING ON A NEGATIVE ONE
+C* THEN STOP
+        GO TO 110
+C* IF A POSITIVE IND(K) FOLLOWS ON A NEGATIVE IND(I) THEN
+C* INTERCHANGE BLOCK K BEFORE BLOCK I BY PERFORMING K-I SWAPS
+   70   ISTEP = K - I
+        LS2 = IND(K)
+        L = L2K
+        DO 80 II=1,ISTEP
+          IFIRST = K - II
+          LS1 = -IND(IFIRST)
+          L = L - LS1
+          CALL EXCHQZ(NMAX, N, A, B, Z, L, LS1, LS2, EPS, FAIL)
+          IF (FAIL) RETURN
+          IND(IFIRST+1) = IND(IFIRST)
+   80   CONTINUE
+        IND(I) = LS2
+   90   L2I = L2I + IND(I)
+  100 CONTINUE
+  110 FAIL = .FALSE.
+      RETURN
+      END
diff --git a/libcruft/ordered-qz/exchqz.f b/libcruft/ordered-qz/exchqz.f
new file mode 100644
index 0000000..34c2c1b
--- /dev/null
+++ b/libcruft/ordered-qz/exchqz.f
@@ -0,0 +1,263 @@
+      SUBROUTINE EXCHQZ(NMAX, N, A, B, Z, L, LS1, LS2, EPS, FAIL)
+      INTEGER NMAX, N, L, LS1, LS2
+      DOUBLE PRECISION A(NMAX,N), B(NMAX,N), Z(NMAX,N), EPS
+      LOGICAL FAIL
+c modified july 9, 1998 a.s.hodel at eng.auburn.edu:
+c     REAL changed to DOUBLE PRECISION
+c     calls to AMAX1 changed to call MAX instead.
+c     calls to SROT  changed to DROT  (both in BLAS)
+c     calls to giv changed to dlartg (LAPACK); required new variable tempr
+C*
+C* GIVEN THE UPPER TRIANGULAR MATRIX B AND UPPER HESSENBERG MATRIX A
+C* WITH CONSECUTIVE LS1XLS1 AND LS2XLS2 DIAGONAL BLOCKS (LS1,LS2.LE.2)
+C* STARTING AT ROW/COLUMN L, EXCHQZ PRODUCES EQUIVALENCE TRANSFORMA-
+C* TIONS QT AND ZT THAT EXCHANGE THE BLOCKS ALONG WITH THEIR GENERALIZED
+C* EIGENVALUES. EXCHQZ REQUIRES THE SUBROUTINES DROT (BLAS) AND GIV.
+C* THE PARAMETERS IN THE CALLING SEQUENCE ARE (STARRED PARAMETERS ARE
+C* ALTERED BY THE SUBROUTINE):
+C*
+C*    NMAX     THE FIRST DIMENSION OF A, B AND Z
+C*    N        THE ORDER OF A, B AND Z
+C*   *A,*B     THE MATRIX PAIR WHOSE BLOCKS ARE TO BE INTERCHANGED
+C*   *Z        UPON RETURN THIS ARRAY IS MULTIPLIED BY THE COLUMN
+C*             TRANSFORMATION ZT.
+C*    L        THE POSITION OF THE BLOCKS
+C*    LS1      THE SIZE OF THE FIRST BLOCK
+C*    LS2      THE SIZE OF THE SECOND BLOCK
+C*    EPS      THE REQUIRED ABSOLUTE ACCURACY OF THE RESULT
+C*   *FAIL     A LOGICAL VARIABLE WHICH IS FALSE ON A NORMAL RETURN,
+C*             TRUE OTHERWISE.
+C*
+      INTEGER I, J, L1, L2, L3, LI, LJ, LL, IT1, IT2
+      DOUBLE PRECISION U(3,3), D, E, F, G, SA, SB, A11B11, A21B11,
+     * A12B22, B12B22,
+     * A22B22, AMMBMM, ANMBMM, AMNBNN, BMNBNN, ANNBNN, TEMPR
+      LOGICAL ALTB
+      FAIL = .FALSE.
+      L1 = L + 1
+      LL = LS1 + LS2
+      IF (LL.GT.2) GO TO 10
+C*** INTERCHANGE 1X1 AND 1X1 BLOCKS VIA AN EQUIVALENCE
+C*** TRANSFORMATION       A:=Q*A*Z , B:=Q*B*Z
+C*** WHERE Q AND Z ARE GIVENS ROTATIONS
+      F = MAX(ABS(A(L1,L1)),ABS(B(L1,L1)))
+      ALTB = .TRUE.
+      IF (ABS(A(L1,L1)).GE.F) ALTB = .FALSE.
+      SA = A(L1,L1)/F
+      SB = B(L1,L1)/F
+      F = SA*B(L,L) - SB*A(L,L)
+C* CONSTRUCT THE COLUMN TRANSFORMATION Z
+      G = SA*B(L,L1) - SB*A(L,L1)
+      CALL DLARTG(F, G, D, E,TEMPR)
+      CALL DROT(L1, A(1,L), 1, A(1,L1), 1, E, -D)
+      CALL DROT(L1, B(1,L), 1, B(1,L1), 1, E, -D)
+      CALL DROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* CONSTRUCT THE ROW TRANSFORMATION Q
+      IF (ALTB) CALL DLARTG(B(L,L), B(L1,L), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL DLARTG(A(L,L), A(L1,L), D, E,TEMPR)
+      CALL DROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+      A(L1,L) = 0.
+      B(L1,L) = 0.
+      RETURN
+C*** INTERCHANGE 1X1 AND 2X2 BLOCKS VIA AN EQUIVALENCE
+C*** TRANSFORMATION  A:=Q2*Q1*A*Z1*Z2 , B:=Q2*Q1*B*Z1*Z2
+C*** WHERE EACH QI AND ZI IS A GIVENS ROTATION
+   10 L2 = L + 2
+      IF (LS1.EQ.2) GO TO 60
+      G = MAX(ABS(A(L,L)),ABS(B(L,L)))
+      ALTB = .TRUE.
+      IF (ABS(A(L,L)).LT.G) GO TO 20
+      ALTB = .FALSE.
+      CALL DLARTG(A(L1,L1), A(L2,L1), D, E,TEMPR)
+      CALL DROT(N-L, A(L1,L1), NMAX, A(L2,L1), NMAX, D, E)
+      CALL DROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+C**  EVALUATE THE PENCIL AT THE EIGENVALUE CORRESPONDING
+C**  TO THE 1X1 BLOCK
+   20 SA = A(L,L)/G
+      SB = B(L,L)/G
+      DO 40 J=1,2
+        LJ = L + J
+        DO 30 I=1,3
+          LI = L + I - 1
+          U(I,J) = SA*B(LI,LJ) - SB*A(LI,LJ)
+   30   CONTINUE
+   40 CONTINUE
+      CALL DLARTG(U(3,1), U(3,2), D, E,TEMPR)
+      CALL DROT(3, U(1,1), 1, U(1,2), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q1
+      CALL DLARTG(U(1,1), U(2,1), D, E,TEMPR)
+      U(2,2) = -U(1,2)*E + U(2,2)*D
+      CALL DROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z1
+      IF (ALTB) CALL DLARTG(B(L1,L), B(L1,L1), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL DLARTG(A(L1,L), A(L1,L1), D, E,TEMPR)
+      CALL DROT(L2, A(1,L), 1, A(1,L1), 1, E, -D)
+      CALL DROT(L2, B(1,L), 1, B(1,L1), 1, E, -D)
+      CALL DROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q2
+      CALL DLARTG(U(2,2), U(3,2), D, E,TEMPR)
+      CALL DROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L1,L), NMAX, B(L2,L), NMAX, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z2
+      IF (ALTB) CALL DLARTG(B(L2,L1), B(L2,L2), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL DLARTG(A(L2,L1), A(L2,L2), D, E,TEMPR)
+      CALL DROT(L2, A(1,L1), 1, A(1,L2), 1, E, -D)
+      CALL DROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+      CALL DROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+      IF (ALTB) GO TO 50
+      CALL DLARTG(B(L,L), B(L1,L), D, E,TEMPR)
+      CALL DROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C*  PUT THE NEGLECTABLE ELEMENTS EQUAL TO ZERO
+   50 A(L2,L) = 0.
+      A(L2,L1) = 0.
+      B(L1,L) = 0.
+      B(L2,L) = 0.
+      B(L2,L1) = 0.
+      RETURN
+C*** INTERCHANGE 2X2 AND 1X1 BLOCKS VIA AN EQUIVALENCE
+C*** TRANSFORMATION  A:=Q2*Q1*A*Z1*Z2 , B:=Q2*Q1*B*Z1*Z2
+C*** WHERE EACH QI AND ZI IS A GIVENS ROTATION
+   60 IF (LS2.EQ.2) GO TO 110
+      G = MAX(ABS(A(L2,L2)),ABS(B(L2,L2)))
+      ALTB = .TRUE.
+      IF (ABS(A(L2,L2)).LT.G) GO TO 70
+      ALTB = .FALSE.
+      CALL DLARTG(A(L,L), A(L1,L), D, E,TEMPR)
+      CALL DROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C**  EVALUATE THE PENCIL AT THE EIGENVALUE CORRESPONDING
+C**  TO THE 1X1 BLOCK
+   70 SA = A(L2,L2)/G
+      SB = B(L2,L2)/G
+      DO 90 I=1,2
+        LI = L + I - 1
+        DO 80 J=1,3
+          LJ = L + J - 1
+          U(I,J) = SA*B(LI,LJ) - SB*A(LI,LJ)
+   80   CONTINUE
+   90 CONTINUE
+      CALL DLARTG(U(1,1), U(2,1), D, E,TEMPR)
+      CALL DROT(3, U(1,1), 3, U(2,1), 3, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z1
+      CALL DLARTG(U(2,2), U(2,3), D, E,TEMPR)
+      U(1,2) = U(1,2)*E - U(1,3)*D
+      CALL DROT(L2, A(1,L1), 1, A(1,L2), 1, E, -D)
+      CALL DROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+      CALL DROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q1
+      IF (ALTB) CALL DLARTG(B(L1,L1), B(L2,L1), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL DLARTG(A(L1,L1), A(L2,L1), D, E,TEMPR)
+      CALL DROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L1,L), NMAX, B(L2,L), NMAX, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z2
+      CALL DLARTG(U(1,1), U(1,2), D, E,TEMPR)
+      CALL DROT(L2, A(1,L), 1, A(1,L1), 1, E, -D)
+      CALL DROT(L2, B(1,L), 1, B(1,L1), 1, E, -D)
+      CALL DROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q2
+      IF (ALTB) CALL DLARTG(B(L,L), B(L1,L), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL DLARTG(A(L,L), A(L1,L), D, E,TEMPR)
+      CALL DROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL DROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+      IF (ALTB) GO TO 100
+      CALL DLARTG(B(L1,L1), B(L2,L1), D, E,TEMPR)
+      CALL DROT(N-L, A(L1,L1), NMAX, A(L2,L1), NMAX, D, E)
+      CALL DROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+C*  PUT THE NEGLECTABLE ELEMENTS EQUAL TO ZERO
+  100 A(L1,L) = 0.
+      A(L2,L) = 0.
+      B(L1,L) = 0.
+      B(L2,1) = 0.
+      B(L2,L1) = 0.
+      RETURN
+C*** INTERCHANGE 2X2 AND 2X2 BLOCKS VIA A SEQUENCE OF
+C*** QZ-STEPS REALIZED BY THE EQUIVALENCE TRANSFORMATIONS
+C***          A:=Q5*Q4*Q3*Q2*Q1*A*Z1*Z2*Z3*Z4*Z5
+C***          B:=Q5*Q4*Q3*Q2*Q1*B*Z1*Z2*Z3*Z4*Z5
+C*** WHERE EACH QI AND ZI IS A GIVENS ROTATION
+  110 L3 = L + 3
+C* COMPUTE IMPLICIT SHIFT
+      AMMBMM = A(L,L)/B(L,L)
+      ANMBMM = A(L1,L)/B(L,L)
+      AMNBNN = A(L,L1)/B(L1,L1)
+      ANNBNN = A(L1,L1)/B(L1,L1)
+      BMNBNN = B(L,L1)/B(L1,L1)
+      DO 130 IT1=1,3
+        U(1,1) = 1.
+        U(2,1) = 1.
+        U(3,1) = 1.
+        DO 120 IT2=1,10
+C* PERFORM ROW TRANSFORMATIONS Q1 AND Q2
+          CALL DLARTG(U(2,1), U(3,1), D, E,TEMPR)
+          CALL DROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+          CALL DROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+          U(2,1) = D*U(2,1) + E*U(3,1)
+          CALL DLARTG(U(1,1), U(2,1), D, E,TEMPR)
+          CALL DROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+          CALL DROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C* PERFORM COLUMN TRANSFORMATIONS Z1 AND Z2
+          CALL DLARTG(B(L2,L1), B(L2,L2), D, E,TEMPR)
+          CALL DROT(L3, A(1,L1), 1, A(1,L2), 1, E, -D)
+          CALL DROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+          CALL DROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+          CALL DLARTG(B(L1,L), B(L1,L1), D, E,TEMPR)
+          CALL DROT(L3, A(1,L), 1, A(1,L1), 1, E, -D)
+          CALL DROT(L1, B(1,L), 1, B(1,L1), 1, E, -D)
+          CALL DROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* PERFORM TRANSFORMATIONS Q3,Z3,Q4,Z4,Q5 AND Z5 IN
+C* ORDER TO REDUCE THE PENCIL TO HESSENBERG FORM
+          CALL DLARTG(A(L2,L), A(L3,L), D, E,TEMPR)
+          CALL DROT(N-L+1, A(L2,L), NMAX, A(L3,L), NMAX, D, E)
+          CALL DROT(N-L1, B(L2,L2), NMAX, B(L3,L2), NMAX, D, E)
+          CALL DLARTG(B(L3,L2), B(L3,L3), D, E,TEMPR)
+          CALL DROT(L3, A(1,L2), 1, A(1,L3), 1, E, -D)
+          CALL DROT(L3, B(1,L2), 1, B(1,L3), 1, E, -D)
+          CALL DROT(N, Z(1,L2), 1, Z(1,L3), 1, E, -D)
+          CALL DLARTG(A(L1,L), A(L2,L), D, E,TEMPR)
+          CALL DROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+          CALL DROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+          CALL DLARTG(B(L2,L1), B(L2,L2), D, E,TEMPR)
+          CALL DROT(L3, A(1,L1), 1, A(1,L2), 1, E, -D)
+          CALL DROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+          CALL DROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+          CALL DLARTG(A(L2,L1), A(L3,L1), D, E,TEMPR)
+          CALL DROT(N-L, A(L2,L1), NMAX, A(L3,L1), NMAX, D, E)
+          CALL DROT(N-L1, B(L2,L2), NMAX, B(L3,L2), NMAX, D, E)
+          CALL DLARTG(B(L3,L2), B(L3,L3), D, E,TEMPR)
+          CALL DROT(L3, A(1,L2), 1, A(1,L3), 1, E, -D)
+          CALL DROT(L3, B(1,L2), 1, B(1,L3), 1, E, -D)
+          CALL DROT(N, Z(1,L2), 1, Z(1,L3), 1, E, -D)
+C* TEST OF CONVERGENCE ON THE ELEMENT SEPARATING THE BLOCKS
+          IF (ABS(A(L2,L1)).LE.EPS) GO TO 140
+C* COMPUTE A NEW SHIFT IN CASE OF NO CONVERGENCE
+          A11B11 = A(L,L)/B(L,L)
+          A12B22 = A(L,L1)/B(L1,L1)
+          A21B11 = A(L1,L)/B(L,L)
+          A22B22 = A(L1,L1)/B(L1,L1)
+          B12B22 = B(L,L1)/B(L1,L1)
+          U(1,1) = ((AMMBMM-A11B11)*(ANNBNN-A11B11)-AMNBNN*
+     *     ANMBMM+ANMBMM*BMNBNN*A11B11)/A21B11 + A12B22 - A11B11*B12B22
+          U(2,1) = (A22B22-A11B11) - A21B11*B12B22 - (AMMBMM-A11B11) -
+     *     (ANNBNN-A11B11) + ANMBMM*BMNBNN
+          U(3,1) = A(L2,L1)/B(L1,L1)
+  120   CONTINUE
+  130 CONTINUE
+      FAIL = .TRUE.
+      RETURN
+C*  PUT THE NEGLECTABLE ELEMENTS EQUAL TO ZERO IN
+C*  CASE OF CONVERGENCE
+  140 A(L2,L) = 0.
+      A(L2,L1) = 0.
+      A(L3,L) = 0.
+      A(L3,L1) = 0.
+      B(L1,L) = 0.
+      B(L2,L) = 0.
+      B(L2,L1) = 0.
+      B(L3,L) = 0.
+      B(L3,L1) = 0.
+      B(L3,L2) = 0.
+      RETURN
+      END
diff --git a/libcruft/ordered-qz/sexchqz.f b/libcruft/ordered-qz/sexchqz.f
new file mode 100644
index 0000000..b2be465
--- /dev/null
+++ b/libcruft/ordered-qz/sexchqz.f
@@ -0,0 +1,261 @@
+      SUBROUTINE SEXCHQZ(NMAX, N, A, B, Z, L, LS1, LS2, EPS, FAIL)
+      INTEGER NMAX, N, L, LS1, LS2
+      REAL A(NMAX,N), B(NMAX,N), Z(NMAX,N), EPS
+      LOGICAL FAIL
+c modified july 9, 1998 a.s.hodel at eng.auburn.edu:
+c     calls to AMAX1 changed to call MAX instead.
+c     calls to giv changed to slartg (LAPACK); required new variable tempr
+C*
+C* GIVEN THE UPPER TRIANGULAR MATRIX B AND UPPER HESSENBERG MATRIX A
+C* WITH CONSECUTIVE LS1XLS1 AND LS2XLS2 DIAGONAL BLOCKS (LS1,LS2.LE.2)
+C* STARTING AT ROW/COLUMN L, EXCHQZ PRODUCES EQUIVALENCE TRANSFORMA-
+C* TIONS QT AND ZT THAT EXCHANGE THE BLOCKS ALONG WITH THEIR GENERALIZED
+C* EIGENVALUES. EXCHQZ REQUIRES THE SUBROUTINES SROT (BLAS) AND GIV.
+C* THE PARAMETERS IN THE CALLING SEQUENCE ARE (STARRED PARAMETERS ARE
+C* ALTERED BY THE SUBROUTINE):
+C*
+C*    NMAX     THE FIRST DIMENSION OF A, B AND Z
+C*    N        THE ORDER OF A, B AND Z
+C*   *A,*B     THE MATRIX PAIR WHOSE BLOCKS ARE TO BE INTERCHANGED
+C*   *Z        UPON RETURN THIS ARRAY IS MULTIPLIED BY THE COLUMN
+C*             TRANSFORMATION ZT.
+C*    L        THE POSITION OF THE BLOCKS
+C*    LS1      THE SIZE OF THE FIRST BLOCK
+C*    LS2      THE SIZE OF THE SECOND BLOCK
+C*    EPS      THE REQUIRED ABSOLUTE ACCURACY OF THE RESULT
+C*   *FAIL     A LOGICAL VARIABLE WHICH IS FALSE ON A NORMAL RETURN,
+C*             TRUE OTHERWISE.
+C*
+      INTEGER I, J, L1, L2, L3, LI, LJ, LL, IT1, IT2
+      REAL U(3,3), D, E, F, G, SA, SB, A11B11, A21B11,
+     * A12B22, B12B22,
+     * A22B22, AMMBMM, ANMBMM, AMNBNN, BMNBNN, ANNBNN, TEMPR
+      LOGICAL ALTB
+      FAIL = .FALSE.
+      L1 = L + 1
+      LL = LS1 + LS2
+      IF (LL.GT.2) GO TO 10
+C*** INTERCHANGE 1X1 AND 1X1 BLOCKS VIA AN EQUIVALENCE
+C*** TRANSFORMATION       A:=Q*A*Z , B:=Q*B*Z
+C*** WHERE Q AND Z ARE GIVENS ROTATIONS
+      F = MAX(ABS(A(L1,L1)),ABS(B(L1,L1)))
+      ALTB = .TRUE.
+      IF (ABS(A(L1,L1)).GE.F) ALTB = .FALSE.
+      SA = A(L1,L1)/F
+      SB = B(L1,L1)/F
+      F = SA*B(L,L) - SB*A(L,L)
+C* CONSTRUCT THE COLUMN TRANSFORMATION Z
+      G = SA*B(L,L1) - SB*A(L,L1)
+      CALL SLARTG(F, G, D, E,TEMPR)
+      CALL SROT(L1, A(1,L), 1, A(1,L1), 1, E, -D)
+      CALL SROT(L1, B(1,L), 1, B(1,L1), 1, E, -D)
+      CALL SROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* CONSTRUCT THE ROW TRANSFORMATION Q
+      IF (ALTB) CALL SLARTG(B(L,L), B(L1,L), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL SLARTG(A(L,L), A(L1,L), D, E,TEMPR)
+      CALL SROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+      A(L1,L) = 0.
+      B(L1,L) = 0.
+      RETURN
+C*** INTERCHANGE 1X1 AND 2X2 BLOCKS VIA AN EQUIVALENCE
+C*** TRANSFORMATION  A:=Q2*Q1*A*Z1*Z2 , B:=Q2*Q1*B*Z1*Z2
+C*** WHERE EACH QI AND ZI IS A GIVENS ROTATION
+   10 L2 = L + 2
+      IF (LS1.EQ.2) GO TO 60
+      G = MAX(ABS(A(L,L)),ABS(B(L,L)))
+      ALTB = .TRUE.
+      IF (ABS(A(L,L)).LT.G) GO TO 20
+      ALTB = .FALSE.
+      CALL SLARTG(A(L1,L1), A(L2,L1), D, E,TEMPR)
+      CALL SROT(N-L, A(L1,L1), NMAX, A(L2,L1), NMAX, D, E)
+      CALL SROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+C**  EVALUATE THE PENCIL AT THE EIGENVALUE CORRESPONDING
+C**  TO THE 1X1 BLOCK
+   20 SA = A(L,L)/G
+      SB = B(L,L)/G
+      DO 40 J=1,2
+        LJ = L + J
+        DO 30 I=1,3
+          LI = L + I - 1
+          U(I,J) = SA*B(LI,LJ) - SB*A(LI,LJ)
+   30   CONTINUE
+   40 CONTINUE
+      CALL SLARTG(U(3,1), U(3,2), D, E,TEMPR)
+      CALL SROT(3, U(1,1), 1, U(1,2), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q1
+      CALL SLARTG(U(1,1), U(2,1), D, E,TEMPR)
+      U(2,2) = -U(1,2)*E + U(2,2)*D
+      CALL SROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z1
+      IF (ALTB) CALL SLARTG(B(L1,L), B(L1,L1), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL SLARTG(A(L1,L), A(L1,L1), D, E,TEMPR)
+      CALL SROT(L2, A(1,L), 1, A(1,L1), 1, E, -D)
+      CALL SROT(L2, B(1,L), 1, B(1,L1), 1, E, -D)
+      CALL SROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q2
+      CALL SLARTG(U(2,2), U(3,2), D, E,TEMPR)
+      CALL SROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L1,L), NMAX, B(L2,L), NMAX, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z2
+      IF (ALTB) CALL SLARTG(B(L2,L1), B(L2,L2), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL SLARTG(A(L2,L1), A(L2,L2), D, E,TEMPR)
+      CALL SROT(L2, A(1,L1), 1, A(1,L2), 1, E, -D)
+      CALL SROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+      CALL SROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+      IF (ALTB) GO TO 50
+      CALL SLARTG(B(L,L), B(L1,L), D, E,TEMPR)
+      CALL SROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C*  PUT THE NEGLECTABLE ELEMENTS EQUAL TO ZERO
+   50 A(L2,L) = 0.
+      A(L2,L1) = 0.
+      B(L1,L) = 0.
+      B(L2,L) = 0.
+      B(L2,L1) = 0.
+      RETURN
+C*** INTERCHANGE 2X2 AND 1X1 BLOCKS VIA AN EQUIVALENCE
+C*** TRANSFORMATION  A:=Q2*Q1*A*Z1*Z2 , B:=Q2*Q1*B*Z1*Z2
+C*** WHERE EACH QI AND ZI IS A GIVENS ROTATION
+   60 IF (LS2.EQ.2) GO TO 110
+      G = MAX(ABS(A(L2,L2)),ABS(B(L2,L2)))
+      ALTB = .TRUE.
+      IF (ABS(A(L2,L2)).LT.G) GO TO 70
+      ALTB = .FALSE.
+      CALL SLARTG(A(L,L), A(L1,L), D, E,TEMPR)
+      CALL SROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C**  EVALUATE THE PENCIL AT THE EIGENVALUE CORRESPONDING
+C**  TO THE 1X1 BLOCK
+   70 SA = A(L2,L2)/G
+      SB = B(L2,L2)/G
+      DO 90 I=1,2
+        LI = L + I - 1
+        DO 80 J=1,3
+          LJ = L + J - 1
+          U(I,J) = SA*B(LI,LJ) - SB*A(LI,LJ)
+   80   CONTINUE
+   90 CONTINUE
+      CALL SLARTG(U(1,1), U(2,1), D, E,TEMPR)
+      CALL SROT(3, U(1,1), 3, U(2,1), 3, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z1
+      CALL SLARTG(U(2,2), U(2,3), D, E,TEMPR)
+      U(1,2) = U(1,2)*E - U(1,3)*D
+      CALL SROT(L2, A(1,L1), 1, A(1,L2), 1, E, -D)
+      CALL SROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+      CALL SROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q1
+      IF (ALTB) CALL SLARTG(B(L1,L1), B(L2,L1), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL SLARTG(A(L1,L1), A(L2,L1), D, E,TEMPR)
+      CALL SROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L1,L), NMAX, B(L2,L), NMAX, D, E)
+C* PERFORM THE COLUMN TRANSFORMATION Z2
+      CALL SLARTG(U(1,1), U(1,2), D, E,TEMPR)
+      CALL SROT(L2, A(1,L), 1, A(1,L1), 1, E, -D)
+      CALL SROT(L2, B(1,L), 1, B(1,L1), 1, E, -D)
+      CALL SROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* PERFORM THE ROW TRANSFORMATION Q2
+      IF (ALTB) CALL SLARTG(B(L,L), B(L1,L), D, E,TEMPR)
+      IF (.NOT.ALTB) CALL SLARTG(A(L,L), A(L1,L), D, E,TEMPR)
+      CALL SROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+      CALL SROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+      IF (ALTB) GO TO 100
+      CALL SLARTG(B(L1,L1), B(L2,L1), D, E,TEMPR)
+      CALL SROT(N-L, A(L1,L1), NMAX, A(L2,L1), NMAX, D, E)
+      CALL SROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+C*  PUT THE NEGLECTABLE ELEMENTS EQUAL TO ZERO
+  100 A(L1,L) = 0.
+      A(L2,L) = 0.
+      B(L1,L) = 0.
+      B(L2,1) = 0.
+      B(L2,L1) = 0.
+      RETURN
+C*** INTERCHANGE 2X2 AND 2X2 BLOCKS VIA A SEQUENCE OF
+C*** QZ-STEPS REALIZED BY THE EQUIVALENCE TRANSFORMATIONS
+C***          A:=Q5*Q4*Q3*Q2*Q1*A*Z1*Z2*Z3*Z4*Z5
+C***          B:=Q5*Q4*Q3*Q2*Q1*B*Z1*Z2*Z3*Z4*Z5
+C*** WHERE EACH QI AND ZI IS A GIVENS ROTATION
+  110 L3 = L + 3
+C* COMPUTE IMPLICIT SHIFT
+      AMMBMM = A(L,L)/B(L,L)
+      ANMBMM = A(L1,L)/B(L,L)
+      AMNBNN = A(L,L1)/B(L1,L1)
+      ANNBNN = A(L1,L1)/B(L1,L1)
+      BMNBNN = B(L,L1)/B(L1,L1)
+      DO 130 IT1=1,3
+        U(1,1) = 1.
+        U(2,1) = 1.
+        U(3,1) = 1.
+        DO 120 IT2=1,10
+C* PERFORM ROW TRANSFORMATIONS Q1 AND Q2
+          CALL SLARTG(U(2,1), U(3,1), D, E,TEMPR)
+          CALL SROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+          CALL SROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+          U(2,1) = D*U(2,1) + E*U(3,1)
+          CALL SLARTG(U(1,1), U(2,1), D, E,TEMPR)
+          CALL SROT(N-L+1, A(L,L), NMAX, A(L1,L), NMAX, D, E)
+          CALL SROT(N-L+1, B(L,L), NMAX, B(L1,L), NMAX, D, E)
+C* PERFORM COLUMN TRANSFORMATIONS Z1 AND Z2
+          CALL SLARTG(B(L2,L1), B(L2,L2), D, E,TEMPR)
+          CALL SROT(L3, A(1,L1), 1, A(1,L2), 1, E, -D)
+          CALL SROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+          CALL SROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+          CALL SLARTG(B(L1,L), B(L1,L1), D, E,TEMPR)
+          CALL SROT(L3, A(1,L), 1, A(1,L1), 1, E, -D)
+          CALL SROT(L1, B(1,L), 1, B(1,L1), 1, E, -D)
+          CALL SROT(N, Z(1,L), 1, Z(1,L1), 1, E, -D)
+C* PERFORM TRANSFORMATIONS Q3,Z3,Q4,Z4,Q5 AND Z5 IN
+C* ORDER TO REDUCE THE PENCIL TO HESSENBERG FORM
+          CALL SLARTG(A(L2,L), A(L3,L), D, E,TEMPR)
+          CALL SROT(N-L+1, A(L2,L), NMAX, A(L3,L), NMAX, D, E)
+          CALL SROT(N-L1, B(L2,L2), NMAX, B(L3,L2), NMAX, D, E)
+          CALL SLARTG(B(L3,L2), B(L3,L3), D, E,TEMPR)
+          CALL SROT(L3, A(1,L2), 1, A(1,L3), 1, E, -D)
+          CALL SROT(L3, B(1,L2), 1, B(1,L3), 1, E, -D)
+          CALL SROT(N, Z(1,L2), 1, Z(1,L3), 1, E, -D)
+          CALL SLARTG(A(L1,L), A(L2,L), D, E,TEMPR)
+          CALL SROT(N-L+1, A(L1,L), NMAX, A(L2,L), NMAX, D, E)
+          CALL SROT(N-L, B(L1,L1), NMAX, B(L2,L1), NMAX, D, E)
+          CALL SLARTG(B(L2,L1), B(L2,L2), D, E,TEMPR)
+          CALL SROT(L3, A(1,L1), 1, A(1,L2), 1, E, -D)
+          CALL SROT(L2, B(1,L1), 1, B(1,L2), 1, E, -D)
+          CALL SROT(N, Z(1,L1), 1, Z(1,L2), 1, E, -D)
+          CALL SLARTG(A(L2,L1), A(L3,L1), D, E,TEMPR)
+          CALL SROT(N-L, A(L2,L1), NMAX, A(L3,L1), NMAX, D, E)
+          CALL SROT(N-L1, B(L2,L2), NMAX, B(L3,L2), NMAX, D, E)
+          CALL SLARTG(B(L3,L2), B(L3,L3), D, E,TEMPR)
+          CALL SROT(L3, A(1,L2), 1, A(1,L3), 1, E, -D)
+          CALL SROT(L3, B(1,L2), 1, B(1,L3), 1, E, -D)
+          CALL SROT(N, Z(1,L2), 1, Z(1,L3), 1, E, -D)
+C* TEST OF CONVERGENCE ON THE ELEMENT SEPARATING THE BLOCKS
+          IF (ABS(A(L2,L1)).LE.EPS) GO TO 140
+C* COMPUTE A NEW SHIFT IN CASE OF NO CONVERGENCE
+          A11B11 = A(L,L)/B(L,L)
+          A12B22 = A(L,L1)/B(L1,L1)
+          A21B11 = A(L1,L)/B(L,L)
+          A22B22 = A(L1,L1)/B(L1,L1)
+          B12B22 = B(L,L1)/B(L1,L1)
+          U(1,1) = ((AMMBMM-A11B11)*(ANNBNN-A11B11)-AMNBNN*
+     *     ANMBMM+ANMBMM*BMNBNN*A11B11)/A21B11 + A12B22 - A11B11*B12B22
+          U(2,1) = (A22B22-A11B11) - A21B11*B12B22 - (AMMBMM-A11B11) -
+     *     (ANNBNN-A11B11) + ANMBMM*BMNBNN
+          U(3,1) = A(L2,L1)/B(L1,L1)
+  120   CONTINUE
+  130 CONTINUE
+      FAIL = .TRUE.
+      RETURN
+C*  PUT THE NEGLECTABLE ELEMENTS EQUAL TO ZERO IN
+C*  CASE OF CONVERGENCE
+  140 A(L2,L) = 0.
+      A(L2,L1) = 0.
+      A(L3,L) = 0.
+      A(L3,L1) = 0.
+      B(L1,L) = 0.
+      B(L2,L) = 0.
+      B(L2,L1) = 0.
+      B(L3,L) = 0.
+      B(L3,L1) = 0.
+      B(L3,L2) = 0.
+      RETURN
+      END
diff --git a/libcruft/ordered-qz/ssubsp.f b/libcruft/ordered-qz/ssubsp.f
new file mode 100644
index 0000000..d237ab9
--- /dev/null
+++ b/libcruft/ordered-qz/ssubsp.f
@@ -0,0 +1,104 @@
+      SUBROUTINE SSUBSP(NMAX, N, A, B, Z, FTEST, EPS, NDIM, FAIL, IND)
+      INTEGER NMAX, N, FTEST, NDIM, IND(N)
+      LOGICAL FAIL
+      REAL A(NMAX,N), B(NMAX,N), Z(NMAX,N), EPS
+C*
+C* GIVEN THE UPPER TRIANGULAR MATRIX B AND UPPER HESSENBERG MATRIX A
+C* WITH 1X1 OR 2X2 DIAGONAL BLOCKS, THIS ROUTINE REORDERS THE DIAGONAL
+C* BLOCKS ALONG WITH THEIR GENERALIZED EIGENVALUES BY CONSTRUCTING EQUI-
+C* VALENCE TRANSFORMATIONS QT AND ZT. THE ROW TRANSFORMATION ZT IS ALSO
+C* PERFORMED ON THE GIVEN (INITIAL) TRANSFORMATION Z (RESULTING FROM A
+C* POSSIBLE PREVIOUS STEP OR INITIALIZED WITH THE IDENTITY MATRIX).
+C* AFTER REORDERING, THE EIGENVALUES INSIDE THE REGION SPECIFIED BY THE
+C* FUNCTION FTEST APPEAR AT THE TOP. IF NDIM IS THEIR NUMBER THEN THE
+C* NDIM FIRST COLUMNS OF Z SPAN THE REQUESTED SUBSPACE. DSUBSP REQUIRES
+C* THE SUBROUTINE EXCHQZ AND THE INTEGER FUNCTION FTEST WHICH HAS TO BE
+C* PROVIDED BY THE USER. THE PARAMETERS IN THE CALLING SEQUENCE ARE :
+C* (STARRED PARAMETERS ARE ALTERED BY THE SUBROUTINE)
+C*
+C*    NMAX     THE FIRST DIMENSION OF A, B AND Z
+C*    N        THE ORDER OF A, B AND Z
+C*   *A,*B     THE MATRIX PAIR WHOSE BLOCKS ARE TO BE REORDERED.
+C*   *Z        UPON RETURN THIS ARRAY IS MULTIPLIED BY THE COLUMN
+C*             TRANSFORMATION ZT.
+C*    FTEST(LS,ALPHA,BETA,S,P) AN INTEGER FUNCTION DESCRIBING THE
+C*             SPECTRUM OF THE DEFLATING SUBSPACE TO BE COMPUTED:
+C*             WHEN LS=1 FTEST CHECKS IF ALPHA/BETA IS IN THAT SPECTRUM
+C*             WHEN LS=2 FTEST CHECKS IF THE TWO COMPLEX CONJUGATE
+C*             ROOTS WITH SUM S AND PRODUCT P ARE IN THAT SPECTRUM
+C*             IF THE ANSWER IS POSITIVE, FTEST=1, OTHERWISE FTEST=-1
+C*    EPS      THE REQUIRED ABSOLUTE ACCURACY OF THE RESULT
+C*   *NDIM     AN INTEGER GIVING THE DIMENSION OF THE COMPUTED
+C*             DEFLATING SUBSPACE
+C*   *FAIL     A LOGICAL VARIABLE WHICH IS FALSE ON A NORMAL RETURN,
+C*             TRUE OTHERWISE (WHEN SEXCHQZ FAILS)
+C*   *IND      AN INTEGER WORKING ARRAY OF DIMENSION AT LEAST N
+C*
+      INTEGER L, LS, LS1, LS2, L1, LL, NUM, IS, L2I, L2K, I, K, II,
+     * ISTEP, IFIRST
+      REAL S, P, D, ALPHA, BETA
+      FAIL = .TRUE.
+      NDIM = 0
+      NUM = 0
+      L = 0
+      LS = 1
+C*** CONSTRUCT ARRAY IND(I) WHERE :
+C***     IABS(IND(I)) IS THE SIZE OF THE BLOCK I
+C***     SIGN(IND(I)) INDICATES THE LOCATION OF ITS EIGENVALUES
+C***                  (AS DETERMINED BY FTEST).
+C*** NUM IS THE NUMBER OF ELEMENTS IN THIS ARRAY
+      DO 30 LL=1,N
+        L = L + LS
+        IF (L.GT.N) GO TO 40
+        L1 = L + 1
+        IF (L1.GT.N) GO TO 10
+        IF (A(L1,L).EQ.0.) GO TO 10
+C* HERE A 2X2  BLOCK IS CHECKED *
+        LS = 2
+        D = B(L,L)*B(L1,L1)
+        S = (A(L,L)*B(L1,L1)+A(L1,L1)*B(L,L)-A(L1,L)*B(L,L1))/D
+        P = (A(L,L)*A(L1,L1)-A(L,L1)*A(L1,L))/D
+        IS = FTEST(LS,ALPHA,BETA,S,P)
+        GO TO 20
+C* HERE A 1X1  BLOCK IS CHECKED *
+   10   LS = 1
+        IS = FTEST(LS,A(L,L),B(L,L),S,P)
+   20   NUM = NUM + 1
+        IF (IS.EQ.1) NDIM = NDIM + LS
+        IND(NUM) = LS*IS
+   30 CONTINUE
+C***  REORDER BLOCKS SUCH THAT THOSE WITH POSITIVE VALUE
+C***    OF IND(.) APPEAR FIRST.
+   40 L2I = 1
+      DO 100 I=1,NUM
+        IF (IND(I).GT.0) GO TO 90
+C* IF A NEGATIVE IND(I) IS ENCOUNTERED, THEN SEARCH FOR THE FIRST
+C* POSITIVE IND(K) FOLLOWING ON IT
+        L2K = L2I
+        DO 60 K=I,NUM
+          IF (IND(K).LT.0) GO TO 50
+          GO TO 70
+   50     L2K = L2K - IND(K)
+   60   CONTINUE
+C* IF THERE ARE NO POSITIVE INDICES FOLLOWING ON A NEGATIVE ONE
+C* THEN STOP
+        GO TO 110
+C* IF A POSITIVE IND(K) FOLLOWS ON A NEGATIVE IND(I) THEN
+C* INTERCHANGE BLOCK K BEFORE BLOCK I BY PERFORMING K-I SWAPS
+   70   ISTEP = K - I
+        LS2 = IND(K)
+        L = L2K
+        DO 80 II=1,ISTEP
+          IFIRST = K - II
+          LS1 = -IND(IFIRST)
+          L = L - LS1
+          CALL SEXCHQZ(NMAX, N, A, B, Z, L, LS1, LS2, EPS, FAIL)
+          IF (FAIL) RETURN
+          IND(IFIRST+1) = IND(IFIRST)
+   80   CONTINUE
+        IND(I) = LS2
+   90   L2I = L2I + IND(I)
+  100 CONTINUE
+  110 FAIL = .FALSE.
+      RETURN
+      END
diff --git a/libcruft/quadpack/Makefile.in b/libcruft/quadpack/Makefile.in
new file mode 100644
index 0000000..d7733d4
--- /dev/null
+++ b/libcruft/quadpack/Makefile.in
@@ -0,0 +1,35 @@
+# Makefile for octave's libcruft/quadpack directory
+#
+# Copyright (C) 1993, 1994, 1995, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC = dqagi.f dqagie.f dqagp.f dqagpe.f dqelg.f dqk15i.f \
+  dqk21.f dqpsrt.f qagie.f qagi.f qagpe.f qagp.f qelg.f \
+  qk15i.f qk21.f qpsrt.f xerror.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/quadpack/dqagi.f b/libcruft/quadpack/dqagi.f
new file mode 100644
index 0000000..8158e6b
--- /dev/null
+++ b/libcruft/quadpack/dqagi.f
@@ -0,0 +1,190 @@
+      SUBROUTINE DQAGI(F,BOUND,INF,EPSABS,EPSREL,RESULT,ABSERR,NEVAL,
+     *   IER,LIMIT,LENW,LAST,IWORK,WORK)
+C***BEGIN PROLOGUE  DQAGI
+C***DATE WRITTEN   800101   (YYMMDD)
+C***REVISION DATE  830518   (YYMMDD)
+C***CATEGORY NO.  H2A3A1,H2A4A1
+C***KEYWORDS  AUTOMATIC INTEGRATOR, INFINITE INTERVALS,
+C             GENERAL-PURPOSE, TRANSFORMATION, EXTRAPOLATION,
+C             GLOBALLY ADAPTIVE
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH. & PROGR. DIV. -K.U.LEUVEN
+C***PURPOSE  THE ROUTINE CALCULATES AN APPROXIMATION RESULT TO A GIVEN
+C            INTEGRAL   I = INTEGRAL OF F OVER (BOUND,+INFINITY)
+C            OR I = INTEGRAL OF F OVER (-INFINITY,BOUND)
+C            OR I = INTEGRAL OF F OVER (-INFINITY,+INFINITY)
+C            HOPEFULLY SATISFYING FOLLOWING CLAIM FOR ACCURACY
+C            ABS(I-RESULT).LE.MAX(EPSABS,EPSREL*ABS(I)).
+C***DESCRIPTION
+C
+C        INTEGRATION OVER INFINITE INTERVALS
+C        STANDARD FORTRAN SUBROUTINE
+C
+C        PARAMETERS
+C         ON ENTRY
+C            F      - SUBROUTINE F(X,RESULT) DEFINING THE INTEGRAND
+C                     FUNCTION F(X). THE ACTUAL NAME FOR F NEEDS TO BE
+C                     DECLARED E X T E R N A L IN THE DRIVER PROGRAM.
+C
+C            BOUND  - DOUBLE PRECISION
+C                     FINITE BOUND OF INTEGRATION RANGE
+C                     (HAS NO MEANING IF INTERVAL IS DOUBLY-INFINITE)
+C
+C            INF    - INTEGER
+C                     INDICATING THE KIND OF INTEGRATION RANGE INVOLVED
+C                     INF = 1 CORRESPONDS TO  (BOUND,+INFINITY),
+C                     INF = -1            TO  (-INFINITY,BOUND),
+C                     INF = 2             TO (-INFINITY,+INFINITY).
+C
+C            EPSABS - DOUBLE PRECISION
+C                     ABSOLUTE ACCURACY REQUESTED
+C            EPSREL - DOUBLE PRECISION
+C                     RELATIVE ACCURACY REQUESTED
+C                     IF  EPSABS.LE.0
+C                     AND EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28),
+C                     THE ROUTINE WILL END WITH IER = 6.
+C
+C
+C         ON RETURN
+C            RESULT - DOUBLE PRECISION
+C                     APPROXIMATION TO THE INTEGRAL
+C
+C            ABSERR - DOUBLE PRECISION
+C                     ESTIMATE OF THE MODULUS OF THE ABSOLUTE ERROR,
+C                     WHICH SHOULD EQUAL OR EXCEED ABS(I-RESULT)
+C
+C            NEVAL  - INTEGER
+C                     NUMBER OF INTEGRAND EVALUATIONS
+C
+C            IER    - INTEGER
+C                     IER = 0 NORMAL AND RELIABLE TERMINATION OF THE
+C                             ROUTINE. IT IS ASSUMED THAT THE REQUESTED
+C                             ACCURACY HAS BEEN ACHIEVED.
+C                   - IER.GT.0 ABNORMAL TERMINATION OF THE ROUTINE. THE
+C                             ESTIMATES FOR RESULT AND ERROR ARE LESS
+C                             RELIABLE. IT IS ASSUMED THAT THE REQUESTED
+C                             ACCURACY HAS NOT BEEN ACHIEVED.
+C            ERROR MESSAGES
+C                     IER = 1 MAXIMUM NUMBER OF SUBDIVISIONS ALLOWED
+C                             HAS BEEN ACHIEVED. ONE CAN ALLOW MORE
+C                             SUBDIVISIONS BY INCREASING THE VALUE OF
+C                             LIMIT (AND TAKING THE ACCORDING DIMENSION
+C                             ADJUSTMENTS INTO ACCOUNT). HOWEVER, IF
+C                             THIS YIELDS NO IMPROVEMENT IT IS ADVISED
+C                             TO ANALYZE THE INTEGRAND IN ORDER TO
+C                             DETERMINE THE INTEGRATION DIFFICULTIES. IF
+C                             THE POSITION OF A LOCAL DIFFICULTY CAN BE
+C                             DETERMINED (E.G. SINGULARITY,
+C                             DISCONTINUITY WITHIN THE INTERVAL) ONE
+C                             WILL PROBABLY GAIN FROM SPLITTING UP THE
+C                             INTERVAL AT THIS POINT AND CALLING THE
+C                             INTEGRATOR ON THE SUBRANGES. IF POSSIBLE,
+C                             AN APPROPRIATE SPECIAL-PURPOSE INTEGRATOR
+C                             SHOULD BE USED, WHICH IS DESIGNED FOR
+C                             HANDLING THE TYPE OF DIFFICULTY INVOLVED.
+C                         = 2 THE OCCURRENCE OF ROUNDOFF ERROR IS
+C                             DETECTED, WHICH PREVENTS THE REQUESTED
+C                             TOLERANCE FROM BEING ACHIEVED.
+C                             THE ERROR MAY BE UNDER-ESTIMATED.
+C                         = 3 EXTREMELY BAD INTEGRAND BEHAVIOUR OCCURS
+C                             AT SOME POINTS OF THE INTEGRATION
+C                             INTERVAL.
+C                         = 4 THE ALGORITHM DOES NOT CONVERGE.
+C                             ROUNDOFF ERROR IS DETECTED IN THE
+C                             EXTRAPOLATION TABLE.
+C                             IT IS ASSUMED THAT THE REQUESTED TOLERANCE
+C                             CANNOT BE ACHIEVED, AND THAT THE RETURNED
+C                             RESULT IS THE BEST WHICH CAN BE OBTAINED.
+C                         = 5 THE INTEGRAL IS PROBABLY DIVERGENT, OR
+C                             SLOWLY CONVERGENT. IT MUST BE NOTED THAT
+C                             DIVERGENCE CAN OCCUR WITH ANY OTHER VALUE
+C                             OF IER.
+C                         = 6 THE INPUT IS INVALID, BECAUSE
+C                             (EPSABS.LE.0 AND
+C                              EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28))
+C                              OR LIMIT.LT.1 OR LENIW.LT.LIMIT*4.
+C                             RESULT, ABSERR, NEVAL, LAST ARE SET TO
+C                             ZERO. EXEPT WHEN LIMIT OR LENIW IS
+C                             INVALID, IWORK(1), WORK(LIMIT*2+1) AND
+C                             WORK(LIMIT*3+1) ARE SET TO ZERO, WORK(1)
+C                             IS SET TO A AND WORK(LIMIT+1) TO B.
+C
+C         DIMENSIONING PARAMETERS
+C            LIMIT - INTEGER
+C                    DIMENSIONING PARAMETER FOR IWORK
+C                    LIMIT DETERMINES THE MAXIMUM NUMBER OF SUBINTERVALS
+C                    IN THE PARTITION OF THE GIVEN INTEGRATION INTERVAL
+C                    (A,B), LIMIT.GE.1.
+C                    IF LIMIT.LT.1, THE ROUTINE WILL END WITH IER = 6.
+C
+C            LENW  - INTEGER
+C                    DIMENSIONING PARAMETER FOR WORK
+C                    LENW MUST BE AT LEAST LIMIT*4.
+C                    IF LENW.LT.LIMIT*4, THE ROUTINE WILL END
+C                    WITH IER = 6.
+C
+C            LAST  - INTEGER
+C                    ON RETURN, LAST EQUALS THE NUMBER OF SUBINTERVALS
+C                    PRODUCED IN THE SUBDIVISION PROCESS, WHICH
+C                    DETERMINES THE NUMBER OF SIGNIFICANT ELEMENTS
+C                    ACTUALLY IN THE WORK ARRAYS.
+C
+C         WORK ARRAYS
+C            IWORK - INTEGER
+C                    VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                    K ELEMENTS OF WHICH CONTAIN POINTERS
+C                    TO THE ERROR ESTIMATES OVER THE SUBINTERVALS,
+C                    SUCH THAT WORK(LIMIT*3+IWORK(1)),... ,
+C                    WORK(LIMIT*3+IWORK(K)) FORM A DECREASING
+C                    SEQUENCE, WITH K = LAST IF LAST.LE.(LIMIT/2+2), AND
+C                    K = LIMIT+1-LAST OTHERWISE
+C
+C            WORK  - DOUBLE PRECISION
+C                    VECTOR OF DIMENSION AT LEAST LENW
+C                    ON RETURN
+C                    WORK(1), ..., WORK(LAST) CONTAIN THE LEFT
+C                     END POINTS OF THE SUBINTERVALS IN THE
+C                     PARTITION OF (A,B),
+C                    WORK(LIMIT+1), ..., WORK(LIMIT+LAST) CONTAIN
+C                     THE RIGHT END POINTS,
+C                    WORK(LIMIT*2+1), ...,WORK(LIMIT*2+LAST) CONTAIN THE
+C                     INTEGRAL APPROXIMATIONS OVER THE SUBINTERVALS,
+C                    WORK(LIMIT*3+1), ..., WORK(LIMIT*3)
+C                     CONTAIN THE ERROR ESTIMATES.
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  DQAGIE,XERROR
+C***END PROLOGUE  DQAGI
+C
+      DOUBLE PRECISION ABSERR,BOUND,EPSABS,EPSREL,RESULT,WORK
+      INTEGER IER,INF,IWORK,LAST,LENW,LIMIT,LVL,L1,L2,L3,NEVAL
+C
+      DIMENSION IWORK(LIMIT),WORK(LENW)
+C
+      EXTERNAL F
+C
+C         CHECK VALIDITY OF LIMIT AND LENW.
+C
+C***FIRST EXECUTABLE STATEMENT  DQAGI
+      IER = 6
+      NEVAL = 0
+      LAST = 0
+      RESULT = 0.0D+00
+      ABSERR = 0.0D+00
+      IF(LIMIT.LT.1.OR.LENW.LT.LIMIT*4) GO TO 10
+C
+C         PREPARE CALL FOR DQAGIE.
+C
+      L1 = LIMIT+1
+      L2 = LIMIT+L1
+      L3 = LIMIT+L2
+C
+      CALL DQAGIE(F,BOUND,INF,EPSABS,EPSREL,LIMIT,RESULT,ABSERR,
+     *  NEVAL,IER,WORK(1),WORK(L1),WORK(L2),WORK(L3),IWORK,LAST)
+C
+C         CALL ERROR HANDLER IF NECESSARY.
+C
+       LVL = 0
+10    IF(IER.EQ.6) LVL = 1
+      IF(IER.GT.0) CALL XERROR('ABNORMAL RETURN FROM DQAGI',26,IER,LVL)
+      RETURN
+      END
diff --git a/libcruft/quadpack/dqagie.f b/libcruft/quadpack/dqagie.f
new file mode 100644
index 0000000..878b40a
--- /dev/null
+++ b/libcruft/quadpack/dqagie.f
@@ -0,0 +1,457 @@
+      SUBROUTINE DQAGIE(F,BOUND,INF,EPSABS,EPSREL,LIMIT,RESULT,ABSERR,
+     *   NEVAL,IER,ALIST,BLIST,RLIST,ELIST,IORD,LAST)
+C***BEGIN PROLOGUE  DQAGIE
+C***DATE WRITTEN   800101   (YYMMDD)
+C***REVISION DATE  830518   (YYMMDD)
+C***CATEGORY NO.  H2A3A1,H2A4A1
+C***KEYWORDS  AUTOMATIC INTEGRATOR, INFINITE INTERVALS,
+C             GENERAL-PURPOSE, TRANSFORMATION, EXTRAPOLATION,
+C             GLOBALLY ADAPTIVE
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH & PROGR. DIV - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH & PROGR. DIV - K.U.LEUVEN
+C***PURPOSE  THE ROUTINE CALCULATES AN APPROXIMATION RESULT TO A GIVEN
+C            INTEGRAL   I = INTEGRAL OF F OVER (BOUND,+INFINITY)
+C            OR I = INTEGRAL OF F OVER (-INFINITY,BOUND)
+C            OR I = INTEGRAL OF F OVER (-INFINITY,+INFINITY),
+C            HOPEFULLY SATISFYING FOLLOWING CLAIM FOR ACCURACY
+C            ABS(I-RESULT).LE.MAX(EPSABS,EPSREL*ABS(I))
+C***DESCRIPTION
+C
+C INTEGRATION OVER INFINITE INTERVALS
+C STANDARD FORTRAN SUBROUTINE
+C
+C            F      - SUBROUTINE F(X,IERR,RESULT) DEFINING THE INTEGRAND
+C                     FUNCTION F(X). THE ACTUAL NAME FOR F NEEDS TO BE
+C                     DECLARED E X T E R N A L IN THE DRIVER PROGRAM.
+C
+C            BOUND  - DOUBLE PRECISION
+C                     FINITE BOUND OF INTEGRATION RANGE
+C                     (HAS NO MEANING IF INTERVAL IS DOUBLY-INFINITE)
+C
+C            INF    - DOUBLE PRECISION
+C                     INDICATING THE KIND OF INTEGRATION RANGE INVOLVED
+C                     INF = 1 CORRESPONDS TO  (BOUND,+INFINITY),
+C                     INF = -1            TO  (-INFINITY,BOUND),
+C                     INF = 2             TO (-INFINITY,+INFINITY).
+C
+C            EPSABS - DOUBLE PRECISION
+C                     ABSOLUTE ACCURACY REQUESTED
+C            EPSREL - DOUBLE PRECISION
+C                     RELATIVE ACCURACY REQUESTED
+C                     IF  EPSABS.LE.0
+C                     AND EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28),
+C                     THE ROUTINE WILL END WITH IER = 6.
+C
+C            LIMIT  - INTEGER
+C                     GIVES AN UPPER BOUND ON THE NUMBER OF SUBINTERVALS
+C                     IN THE PARTITION OF (A,B), LIMIT.GE.1
+C
+C         ON RETURN
+C            RESULT - DOUBLE PRECISION
+C                     APPROXIMATION TO THE INTEGRAL
+C
+C            ABSERR - DOUBLE PRECISION
+C                     ESTIMATE OF THE MODULUS OF THE ABSOLUTE ERROR,
+C                     WHICH SHOULD EQUAL OR EXCEED ABS(I-RESULT)
+C
+C            NEVAL  - INTEGER
+C                     NUMBER OF INTEGRAND EVALUATIONS
+C
+C            IER    - INTEGER
+C                     IER = 0 NORMAL AND RELIABLE TERMINATION OF THE
+C                             ROUTINE. IT IS ASSUMED THAT THE REQUESTED
+C                             ACCURACY HAS BEEN ACHIEVED.
+C                     IER.GT.0 ABNORMAL TERMINATION OF THE ROUTINE. THE
+C                             ESTIMATES FOR RESULT AND ERROR ARE LESS
+C                             RELIABLE. IT IS ASSUMED THAT THE REQUESTED
+C                             ACCURACY HAS NOT BEEN ACHIEVED.
+C                     IER.LT.0 EXIT REQUESTED FROM USER-SUPPLIED
+C                             FUNCTION.
+C
+C            ERROR MESSAGES
+C                     IER = 1 MAXIMUM NUMBER OF SUBDIVISIONS ALLOWED
+C                             HAS BEEN ACHIEVED. ONE CAN ALLOW MORE
+C                             SUBDIVISIONS BY INCREASING THE VALUE OF
+C                             LIMIT (AND TAKING THE ACCORDING DIMENSION
+C                             ADJUSTMENTS INTO ACCOUNT). HOWEVER,IF
+C                             THIS YIELDS NO IMPROVEMENT IT IS ADVISED
+C                             TO ANALYZE THE INTEGRAND IN ORDER TO
+C                             DETERMINE THE INTEGRATION DIFFICULTIES.
+C                             IF THE POSITION OF A LOCAL DIFFICULTY CAN
+C                             BE DETERMINED (E.G. SINGULARITY,
+C                             DISCONTINUITY WITHIN THE INTERVAL) ONE
+C                             WILL PROBABLY GAIN FROM SPLITTING UP THE
+C                             INTERVAL AT THIS POINT AND CALLING THE
+C                             INTEGRATOR ON THE SUBRANGES. IF POSSIBLE,
+C                             AN APPROPRIATE SPECIAL-PURPOSE INTEGRATOR
+C                             SHOULD BE USED, WHICH IS DESIGNED FOR
+C                             HANDLING THE TYPE OF DIFFICULTY INVOLVED.
+C                         = 2 THE OCCURRENCE OF ROUNDOFF ERROR IS
+C                             DETECTED, WHICH PREVENTS THE REQUESTED
+C                             TOLERANCE FROM BEING ACHIEVED.
+C                             THE ERROR MAY BE UNDER-ESTIMATED.
+C                         = 3 EXTREMELY BAD INTEGRAND BEHAVIOUR OCCURS
+C                             AT SOME POINTS OF THE INTEGRATION
+C                             INTERVAL.
+C                         = 4 THE ALGORITHM DOES NOT CONVERGE.
+C                             ROUNDOFF ERROR IS DETECTED IN THE
+C                             EXTRAPOLATION TABLE.
+C                             IT IS ASSUMED THAT THE REQUESTED TOLERANCE
+C                             CANNOT BE ACHIEVED, AND THAT THE RETURNED
+C                             RESULT IS THE BEST WHICH CAN BE OBTAINED.
+C                         = 5 THE INTEGRAL IS PROBABLY DIVERGENT, OR
+C                             SLOWLY CONVERGENT. IT MUST BE NOTED THAT
+C                             DIVERGENCE CAN OCCUR WITH ANY OTHER VALUE
+C                             OF IER.
+C                         = 6 THE INPUT IS INVALID, BECAUSE
+C                             (EPSABS.LE.0 AND
+C                              EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28),
+C                             RESULT, ABSERR, NEVAL, LAST, RLIST(1),
+C                             ELIST(1) AND IORD(1) ARE SET TO ZERO.
+C                             ALIST(1) AND BLIST(1) ARE SET TO 0
+C                             AND 1 RESPECTIVELY.
+C
+C            ALIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE LEFT
+C                     END POINTS OF THE SUBINTERVALS IN THE PARTITION
+C                     OF THE TRANSFORMED INTEGRATION RANGE (0,1).
+C
+C            BLIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE RIGHT
+C                     END POINTS OF THE SUBINTERVALS IN THE PARTITION
+C                     OF THE TRANSFORMED INTEGRATION RANGE (0,1).
+C
+C            RLIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE INTEGRAL
+C                     APPROXIMATIONS ON THE SUBINTERVALS
+C
+C            ELIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT,  THE FIRST
+C                     LAST ELEMENTS OF WHICH ARE THE MODULI OF THE
+C                     ABSOLUTE ERROR ESTIMATES ON THE SUBINTERVALS
+C
+C            IORD   - INTEGER
+C                     VECTOR OF DIMENSION LIMIT, THE FIRST K
+C                     ELEMENTS OF WHICH ARE POINTERS TO THE
+C                     ERROR ESTIMATES OVER THE SUBINTERVALS,
+C                     SUCH THAT ELIST(IORD(1)), ..., ELIST(IORD(K))
+C                     FORM A DECREASING SEQUENCE, WITH K = LAST
+C                     IF LAST.LE.(LIMIT/2+2), AND K = LIMIT+1-LAST
+C                     OTHERWISE
+C
+C            LAST   - INTEGER
+C                     NUMBER OF SUBINTERVALS ACTUALLY PRODUCED
+C                     IN THE SUBDIVISION PROCESS
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH,DQELG,DQK15I,DQPSRT
+C***END PROLOGUE  DQAGIE
+      DOUBLE PRECISION ABSEPS,ABSERR,ALIST,AREA,AREA1,AREA12,AREA2,A1,
+     *  A2,BLIST,BOUN,BOUND,B1,B2,CORREC,DABS,DEFABS,DEFAB1,DEFAB2,
+     *  DMAX1,DRES,D1MACH,ELIST,EPMACH,EPSABS,EPSREL,ERLARG,ERLAST,
+     *  ERRBND,ERRMAX,ERROR1,ERROR2,ERRO12,ERRSUM,ERTEST,OFLOW,RESABS,
+     *  RESEPS,RESULT,RES3LA,RLIST,RLIST2,SMALL,UFLOW
+      INTEGER ID,IER,IERRO,INF,IORD,IROFF1,IROFF2,IROFF3,JUPBND,K,KSGN,
+     *  KTMIN,LAST,LIMIT,MAXERR,NEVAL,NRES,NRMAX,NUMRL2
+      LOGICAL EXTRAP,NOEXT
+C
+      DIMENSION ALIST(LIMIT),BLIST(LIMIT),ELIST(LIMIT),IORD(LIMIT),
+     *  RES3LA(3),RLIST(LIMIT),RLIST2(52)
+C
+      EXTERNAL F
+C
+C            THE DIMENSION OF RLIST2 IS DETERMINED BY THE VALUE OF
+C            LIMEXP IN SUBROUTINE DQELG.
+C
+C
+C            LIST OF MAJOR VARIABLES
+C            -----------------------
+C
+C           ALIST     - LIST OF LEFT END POINTS OF ALL SUBINTERVALS
+C                       CONSIDERED UP TO NOW
+C           BLIST     - LIST OF RIGHT END POINTS OF ALL SUBINTERVALS
+C                       CONSIDERED UP TO NOW
+C           RLIST(I)  - APPROXIMATION TO THE INTEGRAL OVER
+C                       (ALIST(I),BLIST(I))
+C           RLIST2    - ARRAY OF DIMENSION AT LEAST (LIMEXP+2),
+C                       CONTAINING THE PART OF THE EPSILON TABLE
+C                       WICH IS STILL NEEDED FOR FURTHER COMPUTATIONS
+C           ELIST(I)  - ERROR ESTIMATE APPLYING TO RLIST(I)
+C           MAXERR    - POINTER TO THE INTERVAL WITH LARGEST ERROR
+C                       ESTIMATE
+C           ERRMAX    - ELIST(MAXERR)
+C           ERLAST    - ERROR ON THE INTERVAL CURRENTLY SUBDIVIDED
+C                       (BEFORE THAT SUBDIVISION HAS TAKEN PLACE)
+C           AREA      - SUM OF THE INTEGRALS OVER THE SUBINTERVALS
+C           ERRSUM    - SUM OF THE ERRORS OVER THE SUBINTERVALS
+C           ERRBND    - REQUESTED ACCURACY MAX(EPSABS,EPSREL*
+C                       ABS(RESULT))
+C           *****1    - VARIABLE FOR THE LEFT SUBINTERVAL
+C           *****2    - VARIABLE FOR THE RIGHT SUBINTERVAL
+C           LAST      - INDEX FOR SUBDIVISION
+C           NRES      - NUMBER OF CALLS TO THE EXTRAPOLATION ROUTINE
+C           NUMRL2    - NUMBER OF ELEMENTS CURRENTLY IN RLIST2. IF AN
+C                       APPROPRIATE APPROXIMATION TO THE COMPOUNDED
+C                       INTEGRAL HAS BEEN OBTAINED, IT IS PUT IN
+C                       RLIST2(NUMRL2) AFTER NUMRL2 HAS BEEN INCREASED
+C                       BY ONE.
+C           SMALL     - LENGTH OF THE SMALLEST INTERVAL CONSIDERED UP
+C                       TO NOW, MULTIPLIED BY 1.5
+C           ERLARG    - SUM OF THE ERRORS OVER THE INTERVALS LARGER
+C                       THAN THE SMALLEST INTERVAL CONSIDERED UP TO NOW
+C           EXTRAP    - LOGICAL VARIABLE DENOTING THAT THE ROUTINE
+C                       IS ATTEMPTING TO PERFORM EXTRAPOLATION. I.E.
+C                       BEFORE SUBDIVIDING THE SMALLEST INTERVAL WE
+C                       TRY TO DECREASE THE VALUE OF ERLARG.
+C           NOEXT     - LOGICAL VARIABLE DENOTING THAT EXTRAPOLATION
+C                       IS NO LONGER ALLOWED (TRUE-VALUE)
+C
+C            MACHINE DEPENDENT CONSTANTS
+C            ---------------------------
+C
+C           EPMACH IS THE LARGEST RELATIVE SPACING.
+C           UFLOW IS THE SMALLEST POSITIVE MAGNITUDE.
+C           OFLOW IS THE LARGEST POSITIVE MAGNITUDE.
+C
+C***FIRST EXECUTABLE STATEMENT  DQAGIE
+       EPMACH = D1MACH(4)
+C
+C           TEST ON VALIDITY OF PARAMETERS
+C           -----------------------------
+C
+      IER = 0
+      NEVAL = 0
+      LAST = 0
+      RESULT = 0.0D+00
+      ABSERR = 0.0D+00
+      ALIST(1) = 0.0D+00
+      BLIST(1) = 0.1D+01
+      RLIST(1) = 0.0D+00
+      ELIST(1) = 0.0D+00
+      IORD(1) = 0
+      IF(EPSABS.LE.0.0D+00.AND.EPSREL.LT.DMAX1(0.5D+02*EPMACH,0.5D-28))
+     *  IER = 6
+       IF(IER.EQ.6) GO TO 999
+C
+C
+C           FIRST APPROXIMATION TO THE INTEGRAL
+C           -----------------------------------
+C
+C           DETERMINE THE INTERVAL TO BE MAPPED ONTO (0,1).
+C           IF INF = 2 THE INTEGRAL IS COMPUTED AS I = I1+I2, WHERE
+C           I1 = INTEGRAL OF F OVER (-INFINITY,0),
+C           I2 = INTEGRAL OF F OVER (0,+INFINITY).
+C
+      BOUN = BOUND
+      IF(INF.EQ.2) BOUN = 0.0D+00
+      CALL DQK15I(F,BOUN,INF,0.0D+00,0.1D+01,RESULT,ABSERR,
+     *  DEFABS,RESABS,IER)
+      IF (IER .LT. 0) RETURN
+C
+C           TEST ON ACCURACY
+C
+      LAST = 1
+      RLIST(1) = RESULT
+      ELIST(1) = ABSERR
+      IORD(1) = 1
+      DRES = DABS(RESULT)
+      ERRBND = DMAX1(EPSABS,EPSREL*DRES)
+      IF(ABSERR.LE.1.0D+02*EPMACH*DEFABS.AND.ABSERR.GT.ERRBND) IER = 2
+      IF(LIMIT.EQ.1) IER = 1
+      IF(IER.NE.0.OR.(ABSERR.LE.ERRBND.AND.ABSERR.NE.RESABS).OR.
+     *  ABSERR.EQ.0.0D+00) GO TO 130
+C
+C           INITIALIZATION
+C           --------------
+C
+      UFLOW = D1MACH(1)
+      OFLOW = D1MACH(2)
+      RLIST2(1) = RESULT
+      ERRMAX = ABSERR
+      MAXERR = 1
+      AREA = RESULT
+      ERRSUM = ABSERR
+      ABSERR = OFLOW
+      NRMAX = 1
+      NRES = 0
+      KTMIN = 0
+      NUMRL2 = 2
+      EXTRAP = .FALSE.
+      NOEXT = .FALSE.
+      IERRO = 0
+      IROFF1 = 0
+      IROFF2 = 0
+      IROFF3 = 0
+      KSGN = -1
+      IF(DRES.GE.(0.1D+01-0.5D+02*EPMACH)*DEFABS) KSGN = 1
+C
+C           MAIN DO-LOOP
+C           ------------
+C
+      DO 90 LAST = 2,LIMIT
+C
+C           BISECT THE SUBINTERVAL WITH NRMAX-TH LARGEST ERROR ESTIMATE.
+C
+        A1 = ALIST(MAXERR)
+        B1 = 0.5D+00*(ALIST(MAXERR)+BLIST(MAXERR))
+        A2 = B1
+        B2 = BLIST(MAXERR)
+        ERLAST = ERRMAX
+        CALL DQK15I(F,BOUN,INF,A1,B1,AREA1,ERROR1,RESABS,DEFAB1,IER)
+        IF (IER .LT. 0) RETURN
+        CALL DQK15I(F,BOUN,INF,A2,B2,AREA2,ERROR2,RESABS,DEFAB2,IER)
+        IF (IER .LT. 0) RETURN
+C
+C           IMPROVE PREVIOUS APPROXIMATIONS TO INTEGRAL
+C           AND ERROR AND TEST FOR ACCURACY.
+C
+        AREA12 = AREA1+AREA2
+        ERRO12 = ERROR1+ERROR2
+        ERRSUM = ERRSUM+ERRO12-ERRMAX
+        AREA = AREA+AREA12-RLIST(MAXERR)
+        IF(DEFAB1.EQ.ERROR1.OR.DEFAB2.EQ.ERROR2)GO TO 15
+        IF(DABS(RLIST(MAXERR)-AREA12).GT.0.1D-04*DABS(AREA12)
+     *  .OR.ERRO12.LT.0.99D+00*ERRMAX) GO TO 10
+        IF(EXTRAP) IROFF2 = IROFF2+1
+        IF(.NOT.EXTRAP) IROFF1 = IROFF1+1
+   10   IF(LAST.GT.10.AND.ERRO12.GT.ERRMAX) IROFF3 = IROFF3+1
+   15   RLIST(MAXERR) = AREA1
+        RLIST(LAST) = AREA2
+        ERRBND = DMAX1(EPSABS,EPSREL*DABS(AREA))
+C
+C           TEST FOR ROUNDOFF ERROR AND EVENTUALLY SET ERROR FLAG.
+C
+        IF(IROFF1+IROFF2.GE.10.OR.IROFF3.GE.20) IER = 2
+        IF(IROFF2.GE.5) IERRO = 3
+C
+C           SET ERROR FLAG IN THE CASE THAT THE NUMBER OF
+C           SUBINTERVALS EQUALS LIMIT.
+C
+        IF(LAST.EQ.LIMIT) IER = 1
+C
+C           SET ERROR FLAG IN THE CASE OF BAD INTEGRAND BEHAVIOUR
+C           AT SOME POINTS OF THE INTEGRATION RANGE.
+C
+        IF(DMAX1(DABS(A1),DABS(B2)).LE.(0.1D+01+0.1D+03*EPMACH)*
+     *  (DABS(A2)+0.1D+04*UFLOW)) IER = 4
+C
+C           APPEND THE NEWLY-CREATED INTERVALS TO THE LIST.
+C
+        IF(ERROR2.GT.ERROR1) GO TO 20
+        ALIST(LAST) = A2
+        BLIST(MAXERR) = B1
+        BLIST(LAST) = B2
+        ELIST(MAXERR) = ERROR1
+        ELIST(LAST) = ERROR2
+        GO TO 30
+   20   ALIST(MAXERR) = A2
+        ALIST(LAST) = A1
+        BLIST(LAST) = B1
+        RLIST(MAXERR) = AREA2
+        RLIST(LAST) = AREA1
+        ELIST(MAXERR) = ERROR2
+        ELIST(LAST) = ERROR1
+C
+C           CALL SUBROUTINE DQPSRT TO MAINTAIN THE DESCENDING ORDERING
+C           IN THE LIST OF ERROR ESTIMATES AND SELECT THE SUBINTERVAL
+C           WITH NRMAX-TH LARGEST ERROR ESTIMATE (TO BE BISECTED NEXT).
+C
+   30   CALL DQPSRT(LIMIT,LAST,MAXERR,ERRMAX,ELIST,IORD,NRMAX)
+        IF(ERRSUM.LE.ERRBND) GO TO 115
+        IF(IER.NE.0) GO TO 100
+        IF(LAST.EQ.2) GO TO 80
+        IF(NOEXT) GO TO 90
+        ERLARG = ERLARG-ERLAST
+        IF(DABS(B1-A1).GT.SMALL) ERLARG = ERLARG+ERRO12
+        IF(EXTRAP) GO TO 40
+C
+C           TEST WHETHER THE INTERVAL TO BE BISECTED NEXT IS THE
+C           SMALLEST INTERVAL.
+C
+        IF(DABS(BLIST(MAXERR)-ALIST(MAXERR)).GT.SMALL) GO TO 90
+        EXTRAP = .TRUE.
+        NRMAX = 2
+   40   IF(IERRO.EQ.3.OR.ERLARG.LE.ERTEST) GO TO 60
+C
+C           THE SMALLEST INTERVAL HAS THE LARGEST ERROR.
+C           BEFORE BISECTING DECREASE THE SUM OF THE ERRORS OVER THE
+C           LARGER INTERVALS (ERLARG) AND PERFORM EXTRAPOLATION.
+C
+        ID = NRMAX
+        JUPBND = LAST
+        IF(LAST.GT.(2+LIMIT/2)) JUPBND = LIMIT+3-LAST
+        DO 50 K = ID,JUPBND
+          MAXERR = IORD(NRMAX)
+          ERRMAX = ELIST(MAXERR)
+          IF(DABS(BLIST(MAXERR)-ALIST(MAXERR)).GT.SMALL) GO TO 90
+          NRMAX = NRMAX+1
+   50   CONTINUE
+C
+C           PERFORM EXTRAPOLATION.
+C
+   60   NUMRL2 = NUMRL2+1
+        RLIST2(NUMRL2) = AREA
+        CALL DQELG(NUMRL2,RLIST2,RESEPS,ABSEPS,RES3LA,NRES)
+        KTMIN = KTMIN+1
+        IF(KTMIN.GT.5.AND.ABSERR.LT.0.1D-02*ERRSUM) IER = 5
+        IF(ABSEPS.GE.ABSERR) GO TO 70
+        KTMIN = 0
+        ABSERR = ABSEPS
+        RESULT = RESEPS
+        CORREC = ERLARG
+        ERTEST = DMAX1(EPSABS,EPSREL*DABS(RESEPS))
+        IF(ABSERR.LE.ERTEST) GO TO 100
+C
+C            PREPARE BISECTION OF THE SMALLEST INTERVAL.
+C
+   70   IF(NUMRL2.EQ.1) NOEXT = .TRUE.
+        IF(IER.EQ.5) GO TO 100
+        MAXERR = IORD(1)
+        ERRMAX = ELIST(MAXERR)
+        NRMAX = 1
+        EXTRAP = .FALSE.
+        SMALL = SMALL*0.5D+00
+        ERLARG = ERRSUM
+        GO TO 90
+   80   SMALL = 0.375D+00
+        ERLARG = ERRSUM
+        ERTEST = ERRBND
+        RLIST2(2) = AREA
+   90 CONTINUE
+C
+C           SET FINAL RESULT AND ERROR ESTIMATE.
+C           ------------------------------------
+C
+  100 IF(ABSERR.EQ.OFLOW) GO TO 115
+      IF((IER+IERRO).EQ.0) GO TO 110
+      IF(IERRO.EQ.3) ABSERR = ABSERR+CORREC
+      IF(IER.EQ.0) IER = 3
+      IF(RESULT.NE.0.0D+00.AND.AREA.NE.0.0D+00)GO TO 105
+      IF(ABSERR.GT.ERRSUM)GO TO 115
+      IF(AREA.EQ.0.0D+00) GO TO 130
+      GO TO 110
+  105 IF(ABSERR/DABS(RESULT).GT.ERRSUM/DABS(AREA))GO TO 115
+C
+C           TEST ON DIVERGENCE
+C
+  110 IF(KSGN.EQ.(-1).AND.DMAX1(DABS(RESULT),DABS(AREA)).LE.
+     * DEFABS*0.1D-01) GO TO 130
+      IF(0.1D-01.GT.(RESULT/AREA).OR.(RESULT/AREA).GT.0.1D+03.
+     *OR.ERRSUM.GT.DABS(AREA)) IER = 6
+      GO TO 130
+C
+C           COMPUTE GLOBAL INTEGRAL SUM.
+C
+  115 RESULT = 0.0D+00
+      DO 120 K = 1,LAST
+        RESULT = RESULT+RLIST(K)
+  120 CONTINUE
+      ABSERR = ERRSUM
+  130 NEVAL = 30*LAST-15
+      IF(INF.EQ.2) NEVAL = 2*NEVAL
+      IF(IER.GT.2) IER=IER-1
+  999 RETURN
+      END
diff --git a/libcruft/quadpack/dqagp.f b/libcruft/quadpack/dqagp.f
new file mode 100644
index 0000000..2bd6dfc
--- /dev/null
+++ b/libcruft/quadpack/dqagp.f
@@ -0,0 +1,224 @@
+      SUBROUTINE DQAGP(F,A,B,NPTS2,POINTS,EPSABS,EPSREL,RESULT,ABSERR,
+     *   NEVAL,IER,LENIW,LENW,LAST,IWORK,WORK)
+C***BEGIN PROLOGUE  DQAGP
+C***DATE WRITTEN   800101   (YYMMDD)
+C***REVISION DATE  830518   (YYMMDD)
+C***CATEGORY NO.  H2A2A1
+C***KEYWORDS  AUTOMATIC INTEGRATOR, GENERAL-PURPOSE,
+C             SINGULARITIES AT USER SPECIFIED POINTS,
+C             EXTRAPOLATION, GLOBALLY ADAPTIVE
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH. & PROGR. DIV - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C***PURPOSE  THE ROUTINE CALCULATES AN APPROXIMATION RESULT TO A GIVEN
+C            DEFINITE INTEGRAL I = INTEGRAL OF F OVER (A,B),
+C            HOPEFULLY SATISFYING FOLLOWING CLAIM FOR ACCURACY
+C            BREAK POINTS OF THE INTEGRATION INTERVAL, WHERE LOCAL
+C            DIFFICULTIES OF THE INTEGRAND MAY OCCUR (E.G.
+C            SINGULARITIES, DISCONTINUITIES), ARE PROVIDED BY THE USER.
+C***DESCRIPTION
+C
+C        COMPUTATION OF A DEFINITE INTEGRAL
+C        STANDARD FORTRAN SUBROUTINE
+C        DOUBLE PRECISION VERSION
+C
+C        PARAMETERS
+C         ON ENTRY
+C            F      - SUBROUTINE F(X,IERR,RESULT) DEFINING THE INTEGRAND
+C                     FUNCTION F(X). THE ACTUAL NAME FOR F NEEDS TO BE
+C                     DECLARED E X T E R N A L IN THE DRIVER PROGRAM.
+C
+C            A      - DOUBLE PRECISION
+C                     LOWER LIMIT OF INTEGRATION
+C
+C            B      - DOUBLE PRECISION
+C                     UPPER LIMIT OF INTEGRATION
+C
+C            NPTS2  - INTEGER
+C                     NUMBER EQUAL TO TWO MORE THAN THE NUMBER OF
+C                     USER-SUPPLIED BREAK POINTS WITHIN THE INTEGRATION
+C                     RANGE, NPTS.GE.2.
+C                     IF NPTS2.LT.2, THE ROUTINE WILL END WITH IER = 6.
+C
+C            POINTS - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION NPTS2, THE FIRST (NPTS2-2)
+C                     ELEMENTS OF WHICH ARE THE USER PROVIDED BREAK
+C                     POINTS. IF THESE POINTS DO NOT CONSTITUTE AN
+C                     ASCENDING SEQUENCE THERE WILL BE AN AUTOMATIC
+C                     SORTING.
+C
+C            EPSABS - DOUBLE PRECISION
+C                     ABSOLUTE ACCURACY REQUESTED
+C            EPSREL - DOUBLE PRECISION
+C                     RELATIVE ACCURACY REQUESTED
+C                     IF  EPSABS.LE.0
+C                     AND EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28),
+C                     THE ROUTINE WILL END WITH IER = 6.
+C
+C         ON RETURN
+C            RESULT - DOUBLE PRECISION
+C                     APPROXIMATION TO THE INTEGRAL
+C
+C            ABSERR - DOUBLE PRECISION
+C                     ESTIMATE OF THE MODULUS OF THE ABSOLUTE ERROR,
+C                     WHICH SHOULD EQUAL OR EXCEED ABS(I-RESULT)
+C
+C            NEVAL  - INTEGER
+C                     NUMBER OF INTEGRAND EVALUATIONS
+C
+C            IER    - INTEGER
+C                     IER = 0 NORMAL AND RELIABLE TERMINATION OF THE
+C                             ROUTINE. IT IS ASSUMED THAT THE REQUESTED
+C                             ACCURACY HAS BEEN ACHIEVED.
+C                     IER.GT.0 ABNORMAL TERMINATION OF THE ROUTINE.
+C                             THE ESTIMATES FOR INTEGRAL AND ERROR ARE
+C                             LESS RELIABLE. IT IS ASSUMED THAT THE
+C                             REQUESTED ACCURACY HAS NOT BEEN ACHIEVED.
+C            ERROR MESSAGES
+C                     IER = 1 MAXIMUM NUMBER OF SUBDIVISIONS ALLOWED
+C                             HAS BEEN ACHIEVED. ONE CAN ALLOW MORE
+C                             SUBDIVISIONS BY INCREASING THE VALUE OF
+C                             LIMIT (AND TAKING THE ACCORDING DIMENSION
+C                             ADJUSTMENTS INTO ACCOUNT). HOWEVER, IF
+C                             THIS YIELDS NO IMPROVEMENT IT IS ADVISED
+C                             TO ANALYZE THE INTEGRAND IN ORDER TO
+C                             DETERMINE THE INTEGRATION DIFFICULTIES. IF
+C                             THE POSITION OF A LOCAL DIFFICULTY CAN BE
+C                             DETERMINED (I.E. SINGULARITY,
+C                             DISCONTINUITY WITHIN THE INTERVAL), IT
+C                             SHOULD BE SUPPLIED TO THE ROUTINE AS AN
+C                             ELEMENT OF THE VECTOR POINTS. IF NECESSARY
+C                             AN APPROPRIATE SPECIAL-PURPOSE INTEGRATOR
+C                             MUST BE USED, WHICH IS DESIGNED FOR
+C                             HANDLING THE TYPE OF DIFFICULTY INVOLVED.
+C                         = 2 THE OCCURRENCE OF ROUNDOFF ERROR IS
+C                             DETECTED, WHICH PREVENTS THE REQUESTED
+C                             TOLERANCE FROM BEING ACHIEVED.
+C                             THE ERROR MAY BE UNDER-ESTIMATED.
+C                         = 3 EXTREMELY BAD INTEGRAND BEHAVIOUR OCCURS
+C                             AT SOME POINTS OF THE INTEGRATION
+C                             INTERVAL.
+C                         = 4 THE ALGORITHM DOES NOT CONVERGE.
+C                             ROUNDOFF ERROR IS DETECTED IN THE
+C                             EXTRAPOLATION TABLE.
+C                             IT IS PRESUMED THAT THE REQUESTED
+C                             TOLERANCE CANNOT BE ACHIEVED, AND THAT
+C                             THE RETURNED RESULT IS THE BEST WHICH
+C                             CAN BE OBTAINED.
+C                         = 5 THE INTEGRAL IS PROBABLY DIVERGENT, OR
+C                             SLOWLY CONVERGENT. IT MUST BE NOTED THAT
+C                             DIVERGENCE CAN OCCUR WITH ANY OTHER VALUE
+C                             OF IER.GT.0.
+C                         = 6 THE INPUT IS INVALID BECAUSE
+C                             NPTS2.LT.2 OR
+C                             BREAK POINTS ARE SPECIFIED OUTSIDE
+C                             THE INTEGRATION RANGE OR
+C                             (EPSABS.LE.0 AND
+C                              EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28))
+C                             RESULT, ABSERR, NEVAL, LAST ARE SET TO
+C                             ZERO. EXEPT WHEN LENIW OR LENW OR NPTS2 IS
+C                             INVALID, IWORK(1), IWORK(LIMIT+1),
+C                             WORK(LIMIT*2+1) AND WORK(LIMIT*3+1)
+C                             ARE SET TO ZERO.
+C                             WORK(1) IS SET TO A AND WORK(LIMIT+1)
+C                             TO B (WHERE LIMIT = (LENIW-NPTS2)/2).
+C
+C         DIMENSIONING PARAMETERS
+C            LENIW - INTEGER
+C                    DIMENSIONING PARAMETER FOR IWORK
+C                    LENIW DETERMINES LIMIT = (LENIW-NPTS2)/2,
+C                    WHICH IS THE MAXIMUM NUMBER OF SUBINTERVALS IN THE
+C                    PARTITION OF THE GIVEN INTEGRATION INTERVAL (A,B),
+C                    LENIW.GE.(3*NPTS2-2).
+C                    IF LENIW.LT.(3*NPTS2-2), THE ROUTINE WILL END WITH
+C                    IER = 6.
+C
+C            LENW  - INTEGER
+C                    DIMENSIONING PARAMETER FOR WORK
+C                    LENW MUST BE AT LEAST LENIW*2-NPTS2.
+C                    IF LENW.LT.LENIW*2-NPTS2, THE ROUTINE WILL END
+C                    WITH IER = 6.
+C
+C            LAST  - INTEGER
+C                    ON RETURN, LAST EQUALS THE NUMBER OF SUBINTERVALS
+C                    PRODUCED IN THE SUBDIVISION PROCESS, WHICH
+C                    DETERMINES THE NUMBER OF SIGNIFICANT ELEMENTS
+C                    ACTUALLY IN THE WORK ARRAYS.
+C
+C         WORK ARRAYS
+C            IWORK - INTEGER
+C                    VECTOR OF DIMENSION AT LEAST LENIW. ON RETURN,
+C                    THE FIRST K ELEMENTS OF WHICH CONTAIN
+C                    POINTERS TO THE ERROR ESTIMATES OVER THE
+C                    SUBINTERVALS, SUCH THAT WORK(LIMIT*3+IWORK(1)),...,
+C                    WORK(LIMIT*3+IWORK(K)) FORM A DECREASING
+C                    SEQUENCE, WITH K = LAST IF LAST.LE.(LIMIT/2+2), AND
+C                    K = LIMIT+1-LAST OTHERWISE
+C                    IWORK(LIMIT+1), ...,IWORK(LIMIT+LAST) CONTAIN THE
+C                     SUBDIVISION LEVELS OF THE SUBINTERVALS, I.E.
+C                     IF (AA,BB) IS A SUBINTERVAL OF (P1,P2)
+C                     WHERE P1 AS WELL AS P2 IS A USER-PROVIDED
+C                     BREAK POINT OR INTEGRATION LIMIT, THEN (AA,BB) HAS
+C                     LEVEL L IF ABS(BB-AA) = ABS(P2-P1)*2**(-L),
+C                    IWORK(LIMIT*2+1), ..., IWORK(LIMIT*2+NPTS2) HAVE
+C                     NO SIGNIFICANCE FOR THE USER,
+C                    NOTE THAT LIMIT = (LENIW-NPTS2)/2.
+C
+C            WORK  - DOUBLE PRECISION
+C                    VECTOR OF DIMENSION AT LEAST LENW
+C                    ON RETURN
+C                    WORK(1), ..., WORK(LAST) CONTAIN THE LEFT
+C                     END POINTS OF THE SUBINTERVALS IN THE
+C                     PARTITION OF (A,B),
+C                    WORK(LIMIT+1), ..., WORK(LIMIT+LAST) CONTAIN
+C                     THE RIGHT END POINTS,
+C                    WORK(LIMIT*2+1), ..., WORK(LIMIT*2+LAST) CONTAIN
+C                     THE INTEGRAL APPROXIMATIONS OVER THE SUBINTERVALS,
+C                    WORK(LIMIT*3+1), ..., WORK(LIMIT*3+LAST)
+C                     CONTAIN THE CORRESPONDING ERROR ESTIMATES,
+C                    WORK(LIMIT*4+1), ..., WORK(LIMIT*4+NPTS2)
+C                     CONTAIN THE INTEGRATION LIMITS AND THE
+C                     BREAK POINTS SORTED IN AN ASCENDING SEQUENCE.
+C                    NOTE THAT LIMIT = (LENIW-NPTS2)/2.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  DQAGPE,XERROR
+C***END PROLOGUE  DQAGP
+C
+      DOUBLE PRECISION A,ABSERR,B,EPSABS,EPSREL,POINTS,RESULT,WORK
+      INTEGER IER,IWORK,LAST,LENIW,LENW,LIMIT,LVL,L1,L2,L3,L4,NEVAL,
+     *  NPTS2
+C
+      DIMENSION IWORK(LENIW),POINTS(NPTS2),WORK(LENW)
+C
+      EXTERNAL F
+C
+C         CHECK VALIDITY OF LIMIT AND LENW.
+C
+C***FIRST EXECUTABLE STATEMENT  DQAGP
+      IER = 6
+      NEVAL = 0
+      LAST = 0
+      RESULT = 0.0D+00
+      ABSERR = 0.0D+00
+      IF(LENIW.LT.(3*NPTS2-2).OR.LENW.LT.(LENIW*2-NPTS2).OR.NPTS2.LT.2)
+     *  GO TO 10
+C
+C         PREPARE CALL FOR DQAGPE.
+C
+      LIMIT = (LENIW-NPTS2)/2
+      L1 = LIMIT+1
+      L2 = LIMIT+L1
+      L3 = LIMIT+L2
+      L4 = LIMIT+L3
+C
+      CALL DQAGPE(F,A,B,NPTS2,POINTS,EPSABS,EPSREL,LIMIT,RESULT,ABSERR,
+     *  NEVAL,IER,WORK(1),WORK(L1),WORK(L2),WORK(L3),WORK(L4),
+     *  IWORK(1),IWORK(L1),IWORK(L2),LAST)
+C
+C         CALL ERROR HANDLER IF NECESSARY.
+C
+      LVL = 0
+10    IF(IER.EQ.6) LVL = 1
+      IF(IER.GT.0) CALL XERROR('ABNORMAL RETURN FROM DQAGP',26,IER,LVL)
+      RETURN
+      END
diff --git a/libcruft/quadpack/dqagpe.f b/libcruft/quadpack/dqagpe.f
new file mode 100644
index 0000000..1c00db8
--- /dev/null
+++ b/libcruft/quadpack/dqagpe.f
@@ -0,0 +1,555 @@
+      SUBROUTINE DQAGPE(F,A,B,NPTS2,POINTS,EPSABS,EPSREL,LIMIT,RESULT,
+     *   ABSERR,NEVAL,IER,ALIST,BLIST,RLIST,ELIST,PTS,IORD,LEVEL,NDIN,
+     *   LAST)
+C***BEGIN PROLOGUE  DQAGPE
+C***DATE WRITTEN   800101   (YYMMDD)
+C***REVISION DATE  830518   (YYMMDD)
+C***CATEGORY NO.  H2A2A1
+C***KEYWORDS  AUTOMATIC INTEGRATOR, GENERAL-PURPOSE,
+C             SINGULARITIES AT USER SPECIFIED POINTS,
+C             EXTRAPOLATION, GLOBALLY ADAPTIVE.
+C***AUTHOR  PIESSENS,ROBERT ,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C***PURPOSE  THE ROUTINE CALCULATES AN APPROXIMATION RESULT TO A GIVEN
+C            DEFINITE INTEGRAL I = INTEGRAL OF F OVER (A,B), HOPEFULLY
+C            SATISFYING FOLLOWING CLAIM FOR ACCURACY ABS(I-RESULT).LE.
+C            MAX(EPSABS,EPSREL*ABS(I)). BREAK POINTS OF THE INTEGRATION
+C            INTERVAL, WHERE LOCAL DIFFICULTIES OF THE INTEGRAND MAY
+C            OCCUR(E.G. SINGULARITIES,DISCONTINUITIES),PROVIDED BY USER.
+C***DESCRIPTION
+C
+C        COMPUTATION OF A DEFINITE INTEGRAL
+C        STANDARD FORTRAN SUBROUTINE
+C        DOUBLE PRECISION VERSION
+C
+C        PARAMETERS
+C         ON ENTRY
+C            F      - SUBROUTINE F(X,IERR,RESULT) DEFINING THE INTEGRAND
+C                     FUNCTION F(X). THE ACTUAL NAME FOR F NEEDS TO BE
+C                     DECLARED E X T E R N A L IN THE DRIVER PROGRAM.
+C
+C            A      - DOUBLE PRECISION
+C                     LOWER LIMIT OF INTEGRATION
+C
+C            B      - DOUBLE PRECISION
+C                     UPPER LIMIT OF INTEGRATION
+C
+C            NPTS2  - INTEGER
+C                     NUMBER EQUAL TO TWO MORE THAN THE NUMBER OF
+C                     USER-SUPPLIED BREAK POINTS WITHIN THE INTEGRATION
+C                     RANGE, NPTS2.GE.2.
+C                     IF NPTS2.LT.2, THE ROUTINE WILL END WITH IER = 6.
+C
+C            POINTS - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION NPTS2, THE FIRST (NPTS2-2)
+C                     ELEMENTS OF WHICH ARE THE USER PROVIDED BREAK
+C                     POINTS. IF THESE POINTS DO NOT CONSTITUTE AN
+C                     ASCENDING SEQUENCE THERE WILL BE AN AUTOMATIC
+C                     SORTING.
+C
+C            EPSABS - DOUBLE PRECISION
+C                     ABSOLUTE ACCURACY REQUESTED
+C            EPSREL - DOUBLE PRECISION
+C                     RELATIVE ACCURACY REQUESTED
+C                     IF  EPSABS.LE.0
+C                     AND EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28),
+C                     THE ROUTINE WILL END WITH IER = 6.
+C
+C            LIMIT  - INTEGER
+C                     GIVES AN UPPER BOUND ON THE NUMBER OF SUBINTERVALS
+C                     IN THE PARTITION OF (A,B), LIMIT.GE.NPTS2
+C                     IF LIMIT.LT.NPTS2, THE ROUTINE WILL END WITH
+C                     IER = 6.
+C
+C         ON RETURN
+C            RESULT - DOUBLE PRECISION
+C                     APPROXIMATION TO THE INTEGRAL
+C
+C            ABSERR - DOUBLE PRECISION
+C                     ESTIMATE OF THE MODULUS OF THE ABSOLUTE ERROR,
+C                     WHICH SHOULD EQUAL OR EXCEED ABS(I-RESULT)
+C
+C            NEVAL  - INTEGER
+C                     NUMBER OF INTEGRAND EVALUATIONS
+C
+C            IER    - INTEGER
+C                     IER = 0 NORMAL AND RELIABLE TERMINATION OF THE
+C                             ROUTINE. IT IS ASSUMED THAT THE REQUESTED
+C                             ACCURACY HAS BEEN ACHIEVED.
+C                     IER.GT.0 ABNORMAL TERMINATION OF THE ROUTINE.
+C                             THE ESTIMATES FOR INTEGRAL AND ERROR ARE
+C                             LESS RELIABLE. IT IS ASSUMED THAT THE
+C                             REQUESTED ACCURACY HAS NOT BEEN ACHIEVED.
+C                      IER.LT.0 EXIT REQUESTED FROM USER-SUPPLIED
+C                             FUNCTION.
+C
+C            ERROR MESSAGES
+C                     IER = 1 MAXIMUM NUMBER OF SUBDIVISIONS ALLOWED
+C                             HAS BEEN ACHIEVED. ONE CAN ALLOW MORE
+C                             SUBDIVISIONS BY INCREASING THE VALUE OF
+C                             LIMIT (AND TAKING THE ACCORDING DIMENSION
+C                             ADJUSTMENTS INTO ACCOUNT). HOWEVER, IF
+C                             THIS YIELDS NO IMPROVEMENT IT IS ADVISED
+C                             TO ANALYZE THE INTEGRAND IN ORDER TO
+C                             DETERMINE THE INTEGRATION DIFFICULTIES. IF
+C                             THE POSITION OF A LOCAL DIFFICULTY CAN BE
+C                             DETERMINED (I.E. SINGULARITY,
+C                             DISCONTINUITY WITHIN THE INTERVAL), IT
+C                             SHOULD BE SUPPLIED TO THE ROUTINE AS AN
+C                             ELEMENT OF THE VECTOR POINTS. IF NECESSARY
+C                             AN APPROPRIATE SPECIAL-PURPOSE INTEGRATOR
+C                             MUST BE USED, WHICH IS DESIGNED FOR
+C                             HANDLING THE TYPE OF DIFFICULTY INVOLVED.
+C                         = 2 THE OCCURRENCE OF ROUNDOFF ERROR IS
+C                             DETECTED, WHICH PREVENTS THE REQUESTED
+C                             TOLERANCE FROM BEING ACHIEVED.
+C                             THE ERROR MAY BE UNDER-ESTIMATED.
+C                         = 3 EXTREMELY BAD INTEGRAND BEHAVIOUR OCCURS
+C                             AT SOME POINTS OF THE INTEGRATION
+C                             INTERVAL.
+C                         = 4 THE ALGORITHM DOES NOT CONVERGE.
+C                             ROUNDOFF ERROR IS DETECTED IN THE
+C                             EXTRAPOLATION TABLE. IT IS PRESUMED THAT
+C                             THE REQUESTED TOLERANCE CANNOT BE
+C                             ACHIEVED, AND THAT THE RETURNED RESULT IS
+C                             THE BEST WHICH CAN BE OBTAINED.
+C                         = 5 THE INTEGRAL IS PROBABLY DIVERGENT, OR
+C                             SLOWLY CONVERGENT. IT MUST BE NOTED THAT
+C                             DIVERGENCE CAN OCCUR WITH ANY OTHER VALUE
+C                             OF IER.GT.0.
+C                         = 6 THE INPUT IS INVALID BECAUSE
+C                             NPTS2.LT.2 OR
+C                             BREAK POINTS ARE SPECIFIED OUTSIDE
+C                             THE INTEGRATION RANGE OR
+C                             (EPSABS.LE.0 AND
+C                              EPSREL.LT.MAX(50*REL.MACH.ACC.,0.5D-28))
+C                             OR LIMIT.LT.NPTS2.
+C                             RESULT, ABSERR, NEVAL, LAST, RLIST(1),
+C                             AND ELIST(1) ARE SET TO ZERO. ALIST(1) AND
+C                             BLIST(1) ARE SET TO A AND B RESPECTIVELY.
+C
+C            ALIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE LEFT END POINTS
+C                     OF THE SUBINTERVALS IN THE PARTITION OF THE GIVEN
+C                     INTEGRATION RANGE (A,B)
+C
+C            BLIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE RIGHT END POINTS
+C                     OF THE SUBINTERVALS IN THE PARTITION OF THE GIVEN
+C                     INTEGRATION RANGE (A,B)
+C
+C            RLIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE INTEGRAL
+C                     APPROXIMATIONS ON THE SUBINTERVALS
+C
+C            ELIST  - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST
+C                      LAST  ELEMENTS OF WHICH ARE THE MODULI OF THE
+C                     ABSOLUTE ERROR ESTIMATES ON THE SUBINTERVALS
+C
+C            PTS    - DOUBLE PRECISION
+C                     VECTOR OF DIMENSION AT LEAST NPTS2, CONTAINING THE
+C                     INTEGRATION LIMITS AND THE BREAK POINTS OF THE
+C                     INTERVAL IN ASCENDING SEQUENCE.
+C
+C            LEVEL  - INTEGER
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, CONTAINING THE
+C                     SUBDIVISION LEVELS OF THE SUBINTERVAL, I.E. IF
+C                     (AA,BB) IS A SUBINTERVAL OF (P1,P2) WHERE P1 AS
+C                     WELL AS P2 IS A USER-PROVIDED BREAK POINT OR
+C                     INTEGRATION LIMIT, THEN (AA,BB) HAS LEVEL L IF
+C                     ABS(BB-AA) = ABS(P2-P1)*2**(-L).
+C
+C            NDIN   - INTEGER
+C                     VECTOR OF DIMENSION AT LEAST NPTS2, AFTER FIRST
+C                     INTEGRATION OVER THE INTERVALS (PTS(I)),PTS(I+1),
+C                     I = 0,1, ..., NPTS2-2, THE ERROR ESTIMATES OVER
+C                     SOME OF THE INTERVALS MAY HAVE BEEN INCREASED
+C                     ARTIFICIALLY, IN ORDER TO PUT THEIR SUBDIVISION
+C                     FORWARD. IF THIS HAPPENS FOR THE SUBINTERVAL
+C                     NUMBERED K, NDIN(K) IS PUT TO 1, OTHERWISE
+C                     NDIN(K) = 0.
+C
+C            IORD   - INTEGER
+C                     VECTOR OF DIMENSION AT LEAST LIMIT, THE FIRST K
+C                     ELEMENTS OF WHICH ARE POINTERS TO THE
+C                     ERROR ESTIMATES OVER THE SUBINTERVALS,
+C                     SUCH THAT ELIST(IORD(1)), ..., ELIST(IORD(K))
+C                     FORM A DECREASING SEQUENCE, WITH K = LAST
+C                     IF LAST.LE.(LIMIT/2+2), AND K = LIMIT+1-LAST
+C                     OTHERWISE
+C
+C            LAST   - INTEGER
+C                     NUMBER OF SUBINTERVALS ACTUALLY PRODUCED IN THE
+C                     SUBDIVISIONS PROCESS
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH,DQELG,DQK21,DQPSRT
+C***END PROLOGUE  DQAGPE
+      DOUBLE PRECISION A,ABSEPS,ABSERR,ALIST,AREA,AREA1,AREA12,AREA2,A1,
+     *  A2,B,BLIST,B1,B2,CORREC,DABS,DEFABS,DEFAB1,DEFAB2,DMAX1,DMIN1,
+     *  DRES,D1MACH,ELIST,EPMACH,EPSABS,EPSREL,ERLARG,ERLAST,ERRBND,
+     *  ERRMAX,ERROR1,ERRO12,ERROR2,ERRSUM,ERTEST,OFLOW,POINTS,PTS,
+     *  RESA,RESABS,RESEPS,RESULT,RES3LA,RLIST,RLIST2,SIGN,TEMP,UFLOW
+      INTEGER I,ID,IER,IERRO,IND1,IND2,IORD,IP1,IROFF1,IROFF2,IROFF3,J,
+     *  JLOW,JUPBND,K,KSGN,KTMIN,LAST,LEVCUR,LEVEL,LEVMAX,LIMIT,MAXERR,
+     *  NDIN,NEVAL,NINT,NINTP1,NPTS,NPTS2,NRES,NRMAX,NUMRL2
+      LOGICAL EXTRAP,NOEXT
+C
+C
+      DIMENSION ALIST(LIMIT),BLIST(LIMIT),ELIST(LIMIT),IORD(LIMIT),
+     *  LEVEL(LIMIT),NDIN(NPTS2),POINTS(NPTS2),PTS(NPTS2),RES3LA(3),
+     *  RLIST(LIMIT),RLIST2(52)
+C
+      EXTERNAL F
+C
+C            THE DIMENSION OF RLIST2 IS DETERMINED BY THE VALUE OF
+C            LIMEXP IN SUBROUTINE EPSALG (RLIST2 SHOULD BE OF DIMENSION
+C            (LIMEXP+2) AT LEAST).
+C
+C
+C            LIST OF MAJOR VARIABLES
+C            -----------------------
+C
+C           ALIST     - LIST OF LEFT END POINTS OF ALL SUBINTERVALS
+C                       CONSIDERED UP TO NOW
+C           BLIST     - LIST OF RIGHT END POINTS OF ALL SUBINTERVALS
+C                       CONSIDERED UP TO NOW
+C           RLIST(I)  - APPROXIMATION TO THE INTEGRAL OVER
+C                       (ALIST(I),BLIST(I))
+C           RLIST2    - ARRAY OF DIMENSION AT LEAST LIMEXP+2
+C                       CONTAINING THE PART OF THE EPSILON TABLE WHICH
+C                       IS STILL NEEDED FOR FURTHER COMPUTATIONS
+C           ELIST(I)  - ERROR ESTIMATE APPLYING TO RLIST(I)
+C           MAXERR    - POINTER TO THE INTERVAL WITH LARGEST ERROR
+C                       ESTIMATE
+C           ERRMAX    - ELIST(MAXERR)
+C           ERLAST    - ERROR ON THE INTERVAL CURRENTLY SUBDIVIDED
+C                       (BEFORE THAT SUBDIVISION HAS TAKEN PLACE)
+C           AREA      - SUM OF THE INTEGRALS OVER THE SUBINTERVALS
+C           ERRSUM    - SUM OF THE ERRORS OVER THE SUBINTERVALS
+C           ERRBND    - REQUESTED ACCURACY MAX(EPSABS,EPSREL*
+C                       ABS(RESULT))
+C           *****1    - VARIABLE FOR THE LEFT SUBINTERVAL
+C           *****2    - VARIABLE FOR THE RIGHT SUBINTERVAL
+C           LAST      - INDEX FOR SUBDIVISION
+C           NRES      - NUMBER OF CALLS TO THE EXTRAPOLATION ROUTINE
+C           NUMRL2    - NUMBER OF ELEMENTS IN RLIST2. IF AN APPROPRIATE
+C                       APPROXIMATION TO THE COMPOUNDED INTEGRAL HAS
+C                       BEEN OBTAINED, IT IS PUT IN RLIST2(NUMRL2) AFTER
+C                       NUMRL2 HAS BEEN INCREASED BY ONE.
+C           ERLARG    - SUM OF THE ERRORS OVER THE INTERVALS LARGER
+C                       THAN THE SMALLEST INTERVAL CONSIDERED UP TO NOW
+C           EXTRAP    - LOGICAL VARIABLE DENOTING THAT THE ROUTINE
+C                       IS ATTEMPTING TO PERFORM EXTRAPOLATION. I.E.
+C                       BEFORE SUBDIVIDING THE SMALLEST INTERVAL WE
+C                       TRY TO DECREASE THE VALUE OF ERLARG.
+C           NOEXT     - LOGICAL VARIABLE DENOTING THAT EXTRAPOLATION IS
+C                       NO LONGER ALLOWED (TRUE-VALUE)
+C
+C            MACHINE DEPENDENT CONSTANTS
+C            ---------------------------
+C
+C           EPMACH IS THE LARGEST RELATIVE SPACING.
+C           UFLOW IS THE SMALLEST POSITIVE MAGNITUDE.
+C           OFLOW IS THE LARGEST POSITIVE MAGNITUDE.
+C
+C***FIRST EXECUTABLE STATEMENT  DQAGPE
+      EPMACH = D1MACH(4)
+C
+C            TEST ON VALIDITY OF PARAMETERS
+C            -----------------------------
+C
+      IER = 0
+      NEVAL = 0
+      LAST = 0
+      RESULT = 0.0D+00
+      ABSERR = 0.0D+00
+      ALIST(1) = A
+      BLIST(1) = B
+      RLIST(1) = 0.0D+00
+      ELIST(1) = 0.0D+00
+      IORD(1) = 0
+      LEVEL(1) = 0
+      NPTS = NPTS2-2
+      IF(NPTS2.LT.2.OR.LIMIT.LE.NPTS.OR.(EPSABS.LE.0.0D+00.AND.
+     *  EPSREL.LT.DMAX1(0.5D+02*EPMACH,0.5D-28))) IER = 6
+      IF(IER.EQ.6) GO TO 999
+C
+C            IF ANY BREAK POINTS ARE PROVIDED, SORT THEM INTO AN
+C            ASCENDING SEQUENCE.
+C
+      SIGN = 1.0D+00
+      IF(A.GT.B) SIGN = -1.0D+00
+      PTS(1) = DMIN1(A,B)
+      IF(NPTS.EQ.0) GO TO 15
+      DO 10 I = 1,NPTS
+        PTS(I+1) = POINTS(I)
+   10 CONTINUE
+   15 PTS(NPTS+2) = DMAX1(A,B)
+      NINT = NPTS+1
+      A1 = PTS(1)
+      IF(NPTS.EQ.0) GO TO 40
+      NINTP1 = NINT+1
+      DO 20 I = 1,NINT
+        IP1 = I+1
+        DO 20 J = IP1,NINTP1
+          IF(PTS(I).LE.PTS(J)) GO TO 20
+          TEMP = PTS(I)
+          PTS(I) = PTS(J)
+          PTS(J) = TEMP
+   20 CONTINUE
+      IF(PTS(1).NE.DMIN1(A,B).OR.PTS(NINTP1).NE.DMAX1(A,B)) IER = 6
+      IF(IER.EQ.6) GO TO 999
+C
+C            COMPUTE FIRST INTEGRAL AND ERROR APPROXIMATIONS.
+C            ------------------------------------------------
+C
+   40 RESABS = 0.0D+00
+      DO 50 I = 1,NINT
+        B1 = PTS(I+1)
+        CALL DQK21(F,A1,B1,AREA1,ERROR1,DEFABS,RESA,IER)
+        IF (IER .LT. 0) RETURN
+        ABSERR = ABSERR+ERROR1
+        RESULT = RESULT+AREA1
+        NDIN(I) = 0
+        IF(ERROR1.EQ.RESA.AND.ERROR1.NE.0.0D+00) NDIN(I) = 1
+        RESABS = RESABS+DEFABS
+        LEVEL(I) = 0
+        ELIST(I) = ERROR1
+        ALIST(I) = A1
+        BLIST(I) = B1
+        RLIST(I) = AREA1
+        IORD(I) = I
+        A1 = B1
+   50 CONTINUE
+      ERRSUM = 0.0D+00
+      DO 55 I = 1,NINT
+        IF(NDIN(I).EQ.1) ELIST(I) = ABSERR
+        ERRSUM = ERRSUM+ELIST(I)
+   55 CONTINUE
+C
+C           TEST ON ACCURACY.
+C
+      LAST = NINT
+      NEVAL = 21*NINT
+      DRES = DABS(RESULT)
+      ERRBND = DMAX1(EPSABS,EPSREL*DRES)
+      IF(ABSERR.LE.0.1D+03*EPMACH*RESABS.AND.ABSERR.GT.ERRBND) IER = 2
+      IF(NINT.EQ.1) GO TO 80
+      DO 70 I = 1,NPTS
+        JLOW = I+1
+        IND1 = IORD(I)
+        DO 60 J = JLOW,NINT
+          IND2 = IORD(J)
+          IF(ELIST(IND1).GT.ELIST(IND2)) GO TO 60
+          IND1 = IND2
+          K = J
+   60   CONTINUE
+        IF(IND1.EQ.IORD(I)) GO TO 70
+        IORD(K) = IORD(I)
+        IORD(I) = IND1
+   70 CONTINUE
+      IF(LIMIT.LT.NPTS2) IER = 1
+   80 IF(IER.NE.0.OR.ABSERR.LE.ERRBND) GO TO 210
+C
+C           INITIALIZATION
+C           --------------
+C
+      RLIST2(1) = RESULT
+      MAXERR = IORD(1)
+      ERRMAX = ELIST(MAXERR)
+      AREA = RESULT
+      NRMAX = 1
+      NRES = 0
+      NUMRL2 = 1
+      KTMIN = 0
+      EXTRAP = .FALSE.
+      NOEXT = .FALSE.
+      ERLARG = ERRSUM
+      ERTEST = ERRBND
+      LEVMAX = 1
+      IROFF1 = 0
+      IROFF2 = 0
+      IROFF3 = 0
+      IERRO = 0
+      UFLOW = D1MACH(1)
+      OFLOW = D1MACH(2)
+      ABSERR = OFLOW
+      KSGN = -1
+      IF(DRES.GE.(0.1D+01-0.5D+02*EPMACH)*RESABS) KSGN = 1
+C
+C           MAIN DO-LOOP
+C           ------------
+C
+      DO 160 LAST = NPTS2,LIMIT
+C
+C           BISECT THE SUBINTERVAL WITH THE NRMAX-TH LARGEST ERROR
+C           ESTIMATE.
+C
+        LEVCUR = LEVEL(MAXERR)+1
+        A1 = ALIST(MAXERR)
+        B1 = 0.5D+00*(ALIST(MAXERR)+BLIST(MAXERR))
+        A2 = B1
+        B2 = BLIST(MAXERR)
+        ERLAST = ERRMAX
+        CALL DQK21(F,A1,B1,AREA1,ERROR1,RESA,DEFAB1,IER)
+        IF (IER .LT. 0) RETURN
+        CALL DQK21(F,A2,B2,AREA2,ERROR2,RESA,DEFAB2,IER)
+        IF (IER .LT. 0) RETURN
+C
+C           IMPROVE PREVIOUS APPROXIMATIONS TO INTEGRAL
+C           AND ERROR AND TEST FOR ACCURACY.
+C
+        NEVAL = NEVAL+42
+        AREA12 = AREA1+AREA2
+        ERRO12 = ERROR1+ERROR2
+        ERRSUM = ERRSUM+ERRO12-ERRMAX
+        AREA = AREA+AREA12-RLIST(MAXERR)
+        IF(DEFAB1.EQ.ERROR1.OR.DEFAB2.EQ.ERROR2) GO TO 95
+        IF(DABS(RLIST(MAXERR)-AREA12).GT.0.1D-04*DABS(AREA12)
+     *  .OR.ERRO12.LT.0.99D+00*ERRMAX) GO TO 90
+        IF(EXTRAP) IROFF2 = IROFF2+1
+        IF(.NOT.EXTRAP) IROFF1 = IROFF1+1
+   90   IF(LAST.GT.10.AND.ERRO12.GT.ERRMAX) IROFF3 = IROFF3+1
+   95   LEVEL(MAXERR) = LEVCUR
+        LEVEL(LAST) = LEVCUR
+        RLIST(MAXERR) = AREA1
+        RLIST(LAST) = AREA2
+        ERRBND = DMAX1(EPSABS,EPSREL*DABS(AREA))
+C
+C           TEST FOR ROUNDOFF ERROR AND EVENTUALLY SET ERROR FLAG.
+C
+        IF(IROFF1+IROFF2.GE.10.OR.IROFF3.GE.20) IER = 2
+        IF(IROFF2.GE.5) IERRO = 3
+C
+C           SET ERROR FLAG IN THE CASE THAT THE NUMBER OF
+C           SUBINTERVALS EQUALS LIMIT.
+C
+        IF(LAST.EQ.LIMIT) IER = 1
+C
+C           SET ERROR FLAG IN THE CASE OF BAD INTEGRAND BEHAVIOUR
+C           AT A POINT OF THE INTEGRATION RANGE
+C
+        IF(DMAX1(DABS(A1),DABS(B2)).LE.(0.1D+01+0.1D+03*EPMACH)*
+     *  (DABS(A2)+0.1D+04*UFLOW)) IER = 4
+C
+C           APPEND THE NEWLY-CREATED INTERVALS TO THE LIST.
+C
+        IF(ERROR2.GT.ERROR1) GO TO 100
+        ALIST(LAST) = A2
+        BLIST(MAXERR) = B1
+        BLIST(LAST) = B2
+        ELIST(MAXERR) = ERROR1
+        ELIST(LAST) = ERROR2
+        GO TO 110
+  100   ALIST(MAXERR) = A2
+        ALIST(LAST) = A1
+        BLIST(LAST) = B1
+        RLIST(MAXERR) = AREA2
+        RLIST(LAST) = AREA1
+        ELIST(MAXERR) = ERROR2
+        ELIST(LAST) = ERROR1
+C
+C           CALL SUBROUTINE DQPSRT TO MAINTAIN THE DESCENDING ORDERING
+C           IN THE LIST OF ERROR ESTIMATES AND SELECT THE SUBINTERVAL
+C           WITH NRMAX-TH LARGEST ERROR ESTIMATE (TO BE BISECTED NEXT).
+C
+  110   CALL DQPSRT(LIMIT,LAST,MAXERR,ERRMAX,ELIST,IORD,NRMAX)
+C ***JUMP OUT OF DO-LOOP
+        IF(ERRSUM.LE.ERRBND) GO TO 190
+C ***JUMP OUT OF DO-LOOP
+        IF(IER.NE.0) GO TO 170
+        IF(NOEXT) GO TO 160
+        ERLARG = ERLARG-ERLAST
+        IF(LEVCUR+1.LE.LEVMAX) ERLARG = ERLARG+ERRO12
+        IF(EXTRAP) GO TO 120
+C
+C           TEST WHETHER THE INTERVAL TO BE BISECTED NEXT IS THE
+C           SMALLEST INTERVAL.
+C
+        IF(LEVEL(MAXERR)+1.LE.LEVMAX) GO TO 160
+        EXTRAP = .TRUE.
+        NRMAX = 2
+  120   IF(IERRO.EQ.3.OR.ERLARG.LE.ERTEST) GO TO 140
+C
+C           THE SMALLEST INTERVAL HAS THE LARGEST ERROR.
+C           BEFORE BISECTING DECREASE THE SUM OF THE ERRORS OVER
+C           THE LARGER INTERVALS (ERLARG) AND PERFORM EXTRAPOLATION.
+C
+        ID = NRMAX
+        JUPBND = LAST
+        IF(LAST.GT.(2+LIMIT/2)) JUPBND = LIMIT+3-LAST
+        DO 130 K = ID,JUPBND
+          MAXERR = IORD(NRMAX)
+          ERRMAX = ELIST(MAXERR)
+C ***JUMP OUT OF DO-LOOP
+          IF(LEVEL(MAXERR)+1.LE.LEVMAX) GO TO 160
+          NRMAX = NRMAX+1
+  130   CONTINUE
+C
+C           PERFORM EXTRAPOLATION.
+C
+  140   NUMRL2 = NUMRL2+1
+        RLIST2(NUMRL2) = AREA
+        IF(NUMRL2.LE.2) GO TO 155
+        CALL DQELG(NUMRL2,RLIST2,RESEPS,ABSEPS,RES3LA,NRES)
+        KTMIN = KTMIN+1
+        IF(KTMIN.GT.5.AND.ABSERR.LT.0.1D-02*ERRSUM) IER = 5
+        IF(ABSEPS.GE.ABSERR) GO TO 150
+        KTMIN = 0
+        ABSERR = ABSEPS
+        RESULT = RESEPS
+        CORREC = ERLARG
+        ERTEST = DMAX1(EPSABS,EPSREL*DABS(RESEPS))
+C ***JUMP OUT OF DO-LOOP
+        IF(ABSERR.LT.ERTEST) GO TO 170
+C
+C           PREPARE BISECTION OF THE SMALLEST INTERVAL.
+C
+  150   IF(NUMRL2.EQ.1) NOEXT = .TRUE.
+        IF(IER.GE.5) GO TO 170
+  155   MAXERR = IORD(1)
+        ERRMAX = ELIST(MAXERR)
+        NRMAX = 1
+        EXTRAP = .FALSE.
+        LEVMAX = LEVMAX+1
+        ERLARG = ERRSUM
+  160 CONTINUE
+C
+C           SET THE FINAL RESULT.
+C           ---------------------
+C
+C
+  170 IF(ABSERR.EQ.OFLOW) GO TO 190
+      IF((IER+IERRO).EQ.0) GO TO 180
+      IF(IERRO.EQ.3) ABSERR = ABSERR+CORREC
+      IF(IER.EQ.0) IER = 3
+      IF(RESULT.NE.0.0D+00.AND.AREA.NE.0.0D+00)GO TO 175
+      IF(ABSERR.GT.ERRSUM)GO TO 190
+      IF(AREA.EQ.0.0D+00) GO TO 210
+      GO TO 180
+  175 IF(ABSERR/DABS(RESULT).GT.ERRSUM/DABS(AREA))GO TO 190
+C
+C           TEST ON DIVERGENCE.
+C
+  180 IF(KSGN.EQ.(-1).AND.DMAX1(DABS(RESULT),DABS(AREA)).LE.
+     *  RESABS*0.1D-01) GO TO 210
+      IF(0.1D-01.GT.(RESULT/AREA).OR.(RESULT/AREA).GT.0.1D+03.OR.
+     *  ERRSUM.GT.DABS(AREA)) IER = 6
+      GO TO 210
+C
+C           COMPUTE GLOBAL INTEGRAL SUM.
+C
+  190 RESULT = 0.0D+00
+      DO 200 K = 1,LAST
+        RESULT = RESULT+RLIST(K)
+  200 CONTINUE
+      ABSERR = ERRSUM
+  210 IF(IER.GT.2) IER = IER-1
+      RESULT = RESULT*SIGN
+  999 RETURN
+      END
diff --git a/libcruft/quadpack/dqelg.f b/libcruft/quadpack/dqelg.f
new file mode 100644
index 0000000..19f1220
--- /dev/null
+++ b/libcruft/quadpack/dqelg.f
@@ -0,0 +1,184 @@
+      SUBROUTINE DQELG(N,EPSTAB,RESULT,ABSERR,RES3LA,NRES)
+C***BEGIN PROLOGUE  DQELG
+C***REFER TO  DQAGIE,DQAGOE,DQAGPE,DQAGSE
+C***ROUTINES CALLED  D1MACH
+C***REVISION DATE  830518   (YYMMDD)
+C***KEYWORDS  EPSILON ALGORITHM, CONVERGENCE ACCELERATION,
+C             EXTRAPOLATION
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH & PROGR. DIV. - K.U.LEUVEN
+C***PURPOSE  THE ROUTINE DETERMINES THE LIMIT OF A GIVEN SEQUENCE OF
+C            APPROXIMATIONS, BY MEANS OF THE EPSILON ALGORITHM OF
+C            P.WYNN. AN ESTIMATE OF THE ABSOLUTE ERROR IS ALSO GIVEN.
+C            THE CONDENSED EPSILON TABLE IS COMPUTED. ONLY THOSE
+C            ELEMENTS NEEDED FOR THE COMPUTATION OF THE NEXT DIAGONAL
+C            ARE PRESERVED.
+C***DESCRIPTION
+C
+C           EPSILON ALGORITHM
+C           STANDARD FORTRAN SUBROUTINE
+C           DOUBLE PRECISION VERSION
+C
+C           PARAMETERS
+C              N      - INTEGER
+C                       EPSTAB(N) CONTAINS THE NEW ELEMENT IN THE
+C                       FIRST COLUMN OF THE EPSILON TABLE.
+C
+C              EPSTAB - DOUBLE PRECISION
+C                       VECTOR OF DIMENSION 52 CONTAINING THE ELEMENTS
+C                       OF THE TWO LOWER DIAGONALS OF THE TRIANGULAR
+C                       EPSILON TABLE. THE ELEMENTS ARE NUMBERED
+C                       STARTING AT THE RIGHT-HAND CORNER OF THE
+C                       TRIANGLE.
+C
+C              RESULT - DOUBLE PRECISION
+C                       RESULTING APPROXIMATION TO THE INTEGRAL
+C
+C              ABSERR - DOUBLE PRECISION
+C                       ESTIMATE OF THE ABSOLUTE ERROR COMPUTED FROM
+C                       RESULT AND THE 3 PREVIOUS RESULTS
+C
+C              RES3LA - DOUBLE PRECISION
+C                       VECTOR OF DIMENSION 3 CONTAINING THE LAST 3
+C                       RESULTS
+C
+C              NRES   - INTEGER
+C                       NUMBER OF CALLS TO THE ROUTINE
+C                       (SHOULD BE ZERO AT FIRST CALL)
+C
+C***END PROLOGUE  DQELG
+C
+      DOUBLE PRECISION ABSERR,DABS,DELTA1,DELTA2,DELTA3,DMAX1,D1MACH,
+     *  EPMACH,EPSINF,EPSTAB,ERROR,ERR1,ERR2,ERR3,E0,E1,E1ABS,E2,E3,
+     *  OFLOW,RES,RESULT,RES3LA,SS,TOL1,TOL2,TOL3
+      INTEGER I,IB,IB2,IE,INDX,K1,K2,K3,LIMEXP,N,NEWELM,NRES,NUM
+      DIMENSION EPSTAB(52),RES3LA(3)
+C
+C           LIST OF MAJOR VARIABLES
+C           -----------------------
+C
+C           E0     - THE 4 ELEMENTS ON WHICH THE COMPUTATION OF A NEW
+C           E1       ELEMENT IN THE EPSILON TABLE IS BASED
+C           E2
+C           E3                 E0
+C                        E3    E1    NEW
+C                              E2
+C           NEWELM - NUMBER OF ELEMENTS TO BE COMPUTED IN THE NEW
+C                    DIAGONAL
+C           ERROR  - ERROR = ABS(E1-E0)+ABS(E2-E1)+ABS(NEW-E2)
+C           RESULT - THE ELEMENT IN THE NEW DIAGONAL WITH LEAST VALUE
+C                    OF ERROR
+C
+C           MACHINE DEPENDENT CONSTANTS
+C           ---------------------------
+C
+C           EPMACH IS THE LARGEST RELATIVE SPACING.
+C           OFLOW IS THE LARGEST POSITIVE MAGNITUDE.
+C           LIMEXP IS THE MAXIMUM NUMBER OF ELEMENTS THE EPSILON
+C           TABLE CAN CONTAIN. IF THIS NUMBER IS REACHED, THE UPPER
+C           DIAGONAL OF THE EPSILON TABLE IS DELETED.
+C
+C***FIRST EXECUTABLE STATEMENT  DQELG
+      EPMACH = D1MACH(4)
+      OFLOW = D1MACH(2)
+      NRES = NRES+1
+      ABSERR = OFLOW
+      RESULT = EPSTAB(N)
+      IF(N.LT.3) GO TO 100
+      LIMEXP = 50
+      EPSTAB(N+2) = EPSTAB(N)
+      NEWELM = (N-1)/2
+      EPSTAB(N) = OFLOW
+      NUM = N
+      K1 = N
+      DO 40 I = 1,NEWELM
+        K2 = K1-1
+        K3 = K1-2
+        RES = EPSTAB(K1+2)
+        E0 = EPSTAB(K3)
+        E1 = EPSTAB(K2)
+        E2 = RES
+        E1ABS = DABS(E1)
+        DELTA2 = E2-E1
+        ERR2 = DABS(DELTA2)
+        TOL2 = DMAX1(DABS(E2),E1ABS)*EPMACH
+        DELTA3 = E1-E0
+        ERR3 = DABS(DELTA3)
+        TOL3 = DMAX1(E1ABS,DABS(E0))*EPMACH
+        IF(ERR2.GT.TOL2.OR.ERR3.GT.TOL3) GO TO 10
+C
+C           IF E0, E1 AND E2 ARE EQUAL TO WITHIN MACHINE
+C           ACCURACY, CONVERGENCE IS ASSUMED.
+C           RESULT = E2
+C           ABSERR = ABS(E1-E0)+ABS(E2-E1)
+C
+        RESULT = RES
+        ABSERR = ERR2+ERR3
+C ***JUMP OUT OF DO-LOOP
+        GO TO 100
+   10   E3 = EPSTAB(K1)
+        EPSTAB(K1) = E1
+        DELTA1 = E1-E3
+        ERR1 = DABS(DELTA1)
+        TOL1 = DMAX1(E1ABS,DABS(E3))*EPMACH
+C
+C           IF TWO ELEMENTS ARE VERY CLOSE TO EACH OTHER, OMIT
+C           A PART OF THE TABLE BY ADJUSTING THE VALUE OF N
+C
+        IF(ERR1.LE.TOL1.OR.ERR2.LE.TOL2.OR.ERR3.LE.TOL3) GO TO 20
+        SS = 0.1D+01/DELTA1+0.1D+01/DELTA2-0.1D+01/DELTA3
+        EPSINF = DABS(SS*E1)
+C
+C           TEST TO DETECT IRREGULAR BEHAVIOUR IN THE TABLE, AND
+C           EVENTUALLY OMIT A PART OF THE TABLE ADJUSTING THE VALUE
+C           OF N.
+C
+        IF(EPSINF.GT.0.1D-03) GO TO 30
+   20   N = I+I-1
+C ***JUMP OUT OF DO-LOOP
+        GO TO 50
+C
+C           COMPUTE A NEW ELEMENT AND EVENTUALLY ADJUST
+C           THE VALUE OF RESULT.
+C
+   30   RES = E1+0.1D+01/SS
+        EPSTAB(K1) = RES
+        K1 = K1-2
+        ERROR = ERR2+DABS(RES-E2)+ERR3
+        IF(ERROR.GT.ABSERR) GO TO 40
+        ABSERR = ERROR
+        RESULT = RES
+   40 CONTINUE
+C
+C           SHIFT THE TABLE.
+C
+   50 IF(N.EQ.LIMEXP) N = 2*(LIMEXP/2)-1
+      IB = 1
+      IF((NUM/2)*2.EQ.NUM) IB = 2
+      IE = NEWELM+1
+      DO 60 I=1,IE
+        IB2 = IB+2
+        EPSTAB(IB) = EPSTAB(IB2)
+        IB = IB2
+   60 CONTINUE
+      IF(NUM.EQ.N) GO TO 80
+      INDX = NUM-N+1
+      DO 70 I = 1,N
+        EPSTAB(I)= EPSTAB(INDX)
+        INDX = INDX+1
+   70 CONTINUE
+   80 IF(NRES.GE.4) GO TO 90
+      RES3LA(NRES) = RESULT
+      ABSERR = OFLOW
+      GO TO 100
+C
+C           COMPUTE ERROR ESTIMATE
+C
+   90 ABSERR = DABS(RESULT-RES3LA(3))+DABS(RESULT-RES3LA(2))
+     *  +DABS(RESULT-RES3LA(1))
+      RES3LA(1) = RES3LA(2)
+      RES3LA(2) = RES3LA(3)
+      RES3LA(3) = RESULT
+  100 ABSERR = DMAX1(ABSERR,0.5D+01*EPMACH*DABS(RESULT))
+      RETURN
+      END
diff --git a/libcruft/quadpack/dqk15i.f b/libcruft/quadpack/dqk15i.f
new file mode 100644
index 0000000..7eba16d
--- /dev/null
+++ b/libcruft/quadpack/dqk15i.f
@@ -0,0 +1,211 @@
+      SUBROUTINE DQK15I(F,BOUN,INF,A,B,RESULT,ABSERR,RESABS,RESASC,
+     1   IERR)
+C***BEGIN PROLOGUE  DQK15I
+C***DATE WRITTEN   800101   (YYMMDD)
+C***REVISION DATE  830518   (YYMMDD)
+C***CATEGORY NO.  H2A3A2,H2A4A2
+C***KEYWORDS  15-POINT TRANSFORMED GAUSS-KRONROD RULES
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C***PURPOSE  THE ORIGINAL (INFINITE INTEGRATION RANGE IS MAPPED
+C            ONTO THE INTERVAL (0,1) AND (A,B) IS A PART OF (0,1).
+C            IT IS THE PURPOSE TO COMPUTE
+C            I = INTEGRAL OF TRANSFORMED INTEGRAND OVER (A,B),
+C            J = INTEGRAL OF ABS(TRANSFORMED INTEGRAND) OVER (A,B).
+C***DESCRIPTION
+C
+C           INTEGRATION RULE
+C           STANDARD FORTRAN SUBROUTINE
+C           DOUBLE PRECISION VERSION
+C
+C           PARAMETERS
+C            ON ENTRY
+C              F      - SUBROUTINE F(X,IERR,RESULT) DEFINING THE INTEGRAND
+C                       FUNCTION F(X). THE ACTUAL NAME FOR F NEEDS TO BE
+C                       DECLARED E X T E R N A L IN THE CALLING PROGRAM.
+C
+C              BOUN   - DOUBLE PRECISION
+C                       FINITE BOUND OF ORIGINAL INTEGRATION
+C                       RANGE (SET TO ZERO IF INF = +2)
+C
+C              INF    - INTEGER
+C                       IF INF = -1, THE ORIGINAL INTERVAL IS
+C                                   (-INFINITY,BOUND),
+C                       IF INF = +1, THE ORIGINAL INTERVAL IS
+C                                   (BOUND,+INFINITY),
+C                       IF INF = +2, THE ORIGINAL INTERVAL IS
+C                                   (-INFINITY,+INFINITY) AND
+C                       THE INTEGRAL IS COMPUTED AS THE SUM OF TWO
+C                       INTEGRALS, ONE OVER (-INFINITY,0) AND ONE OVER
+C                       (0,+INFINITY).
+C
+C              A      - DOUBLE PRECISION
+C                       LOWER LIMIT FOR INTEGRATION OVER SUBRANGE
+C                       OF (0,1)
+C
+C              B      - DOUBLE PRECISION
+C                       UPPER LIMIT FOR INTEGRATION OVER SUBRANGE
+C                       OF (0,1)
+C
+C            ON RETURN
+C              RESULT - DOUBLE PRECISION
+C                       APPROXIMATION TO THE INTEGRAL I
+C                       RESULT IS COMPUTED BY APPLYING THE 15-POINT
+C                       KRONROD RULE(RESK) OBTAINED BY OPTIMAL ADDITION
+C                       OF ABSCISSAE TO THE 7-POINT GAUSS RULE(RESG).
+C
+C              ABSERR - DOUBLE PRECISION
+C                       ESTIMATE OF THE MODULUS OF THE ABSOLUTE ERROR,
+C                       WHICH SHOULD EQUAL OR EXCEED ABS(I-RESULT)
+C
+C              RESABS - DOUBLE PRECISION
+C                       APPROXIMATION TO THE INTEGRAL J
+C
+C              RESASC - DOUBLE PRECISION
+C                       APPROXIMATION TO THE INTEGRAL OF
+C                       ABS((TRANSFORMED INTEGRAND)-I/(B-A)) OVER (A,B)
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH
+C***END PROLOGUE  DQK15I
+C
+      DOUBLE PRECISION A,ABSC,ABSC1,ABSC2,ABSERR,B,BOUN,CENTR,DABS,DINF,
+     *  DMAX1,DMIN1,D1MACH,EPMACH,FC,FSUM,FVAL1,FVAL2,FV1,FV2,HLGTH,
+     *  RESABS,RESASC,RESG,RESK,RESKH,RESULT,TABSC1,TABSC2,UFLOW,WG,WGK,
+     *  XGK,FVALT
+      INTEGER INF,J
+      EXTERNAL F
+C
+      DIMENSION FV1(7),FV2(7),XGK(8),WGK(8),WG(8)
+C
+C           THE ABSCISSAE AND WEIGHTS ARE SUPPLIED FOR THE INTERVAL
+C           (-1,1).  BECAUSE OF SYMMETRY ONLY THE POSITIVE ABSCISSAE AND
+C           THEIR CORRESPONDING WEIGHTS ARE GIVEN.
+C
+C           XGK    - ABSCISSAE OF THE 15-POINT KRONROD RULE
+C                    XGK(2), XGK(4), ... ABSCISSAE OF THE 7-POINT
+C                    GAUSS RULE
+C                    XGK(1), XGK(3), ...  ABSCISSAE WHICH ARE OPTIMALLY
+C                    ADDED TO THE 7-POINT GAUSS RULE
+C
+C           WGK    - WEIGHTS OF THE 15-POINT KRONROD RULE
+C
+C           WG     - WEIGHTS OF THE 7-POINT GAUSS RULE, CORRESPONDING
+C                    TO THE ABSCISSAE XGK(2), XGK(4), ...
+C                    WG(1), WG(3), ... ARE SET TO ZERO.
+C
+      DATA WG(1) / 0.0D0 /
+      DATA WG(2) / 0.1294849661 6886969327 0611432679 082D0 /
+      DATA WG(3) / 0.0D0 /
+      DATA WG(4) / 0.2797053914 8927666790 1467771423 780D0 /
+      DATA WG(5) / 0.0D0 /
+      DATA WG(6) / 0.3818300505 0511894495 0369775488 975D0 /
+      DATA WG(7) / 0.0D0 /
+      DATA WG(8) / 0.4179591836 7346938775 5102040816 327D0 /
+C
+      DATA XGK(1) / 0.9914553711 2081263920 6854697526 329D0 /
+      DATA XGK(2) / 0.9491079123 4275852452 6189684047 851D0 /
+      DATA XGK(3) / 0.8648644233 5976907278 9712788640 926D0 /
+      DATA XGK(4) / 0.7415311855 9939443986 3864773280 788D0 /
+      DATA XGK(5) / 0.5860872354 6769113029 4144838258 730D0 /
+      DATA XGK(6) / 0.4058451513 7739716690 6606412076 961D0 /
+      DATA XGK(7) / 0.2077849550 0789846760 0689403773 245D0 /
+      DATA XGK(8) / 0.0000000000 0000000000 0000000000 000D0 /
+C
+      DATA WGK(1) / 0.0229353220 1052922496 3732008058 970D0 /
+      DATA WGK(2) / 0.0630920926 2997855329 0700663189 204D0 /
+      DATA WGK(3) / 0.1047900103 2225018383 9876322541 518D0 /
+      DATA WGK(4) / 0.1406532597 1552591874 5189590510 238D0 /
+      DATA WGK(5) / 0.1690047266 3926790282 6583426598 550D0 /
+      DATA WGK(6) / 0.1903505780 6478540991 3256402421 014D0 /
+      DATA WGK(7) / 0.2044329400 7529889241 4161999234 649D0 /
+      DATA WGK(8) / 0.2094821410 8472782801 2999174891 714D0 /
+C
+C
+C           LIST OF MAJOR VARIABLES
+C           -----------------------
+C
+C           CENTR  - MID POINT OF THE INTERVAL
+C           HLGTH  - HALF-LENGTH OF THE INTERVAL
+C           ABSC*  - ABSCISSA
+C           TABSC* - TRANSFORMED ABSCISSA
+C           FVAL*  - FUNCTION VALUE
+C           RESG   - RESULT OF THE 7-POINT GAUSS FORMULA
+C           RESK   - RESULT OF THE 15-POINT KRONROD FORMULA
+C           RESKH  - APPROXIMATION TO THE MEAN VALUE OF THE TRANSFORMED
+C                    INTEGRAND OVER (A,B), I.E. TO I/(B-A)
+C
+C           MACHINE DEPENDENT CONSTANTS
+C           ---------------------------
+C
+C           EPMACH IS THE LARGEST RELATIVE SPACING.
+C           UFLOW IS THE SMALLEST POSITIVE MAGNITUDE.
+C
+C***FIRST EXECUTABLE STATEMENT  DQK15I
+      EPMACH = D1MACH(4)
+      UFLOW = D1MACH(1)
+      DINF = MIN0(1,INF)
+C
+      CENTR = 0.5D+00*(A+B)
+      HLGTH = 0.5D+00*(B-A)
+      TABSC1 = BOUN+DINF*(0.1D+01-CENTR)/CENTR
+      IERR = 0
+      CALL F(TABSC1,IERR,FVAL1)
+      IF (IERR .LT. 0) RETURN
+      IF(INF.EQ.2) THEN
+        CALL F(-TABSC1,IERR,FVALT)
+        IF (IERR .LT. 0) RETURN
+        FVAL1 = FVAL1+FVALT
+      ENDIF
+      FC = (FVAL1/CENTR)/CENTR
+C
+C           COMPUTE THE 15-POINT KRONROD APPROXIMATION TO
+C           THE INTEGRAL, AND ESTIMATE THE ERROR.
+C
+      RESG = WG(8)*FC
+      RESK = WGK(8)*FC
+      RESABS = DABS(RESK)
+      DO 10 J=1,7
+        ABSC = HLGTH*XGK(J)
+        ABSC1 = CENTR-ABSC
+        ABSC2 = CENTR+ABSC
+        TABSC1 = BOUN+DINF*(0.1D+01-ABSC1)/ABSC1
+        TABSC2 = BOUN+DINF*(0.1D+01-ABSC2)/ABSC2
+        CALL F(TABSC1,IERR,FVAL1)
+        IF (IERR .LT. 0) RETURN
+        CALL F(TABSC2,IERR,FVAL2)
+        IF (IERR .LT. 0) RETURN
+        IF(INF.EQ.2) THEN
+          CALL F(-TABSC1,IERR,FVALT)
+          IF (IERR .LT. 0) RETURN
+          FVAL1 = FVAL1+FVALT
+        ENDIF
+        IF(INF.EQ.2) THEN
+          CALL F(-TABSC2,IERR,FVALT)
+          IF (IERR .LT. 0) RETURN
+          FVAL2 = FVAL2+FVALT
+        ENDIF
+        FVAL1 = (FVAL1/ABSC1)/ABSC1
+        FVAL2 = (FVAL2/ABSC2)/ABSC2
+        FV1(J) = FVAL1
+        FV2(J) = FVAL2
+        FSUM = FVAL1+FVAL2
+        RESG = RESG+WG(J)*FSUM
+        RESK = RESK+WGK(J)*FSUM
+        RESABS = RESABS+WGK(J)*(DABS(FVAL1)+DABS(FVAL2))
+   10 CONTINUE
+      RESKH = RESK*0.5D+00
+      RESASC = WGK(8)*DABS(FC-RESKH)
+      DO 20 J=1,7
+        RESASC = RESASC+WGK(J)*(DABS(FV1(J)-RESKH)+DABS(FV2(J)-RESKH))
+   20 CONTINUE
+      RESULT = RESK*HLGTH
+      RESASC = RESASC*HLGTH
+      RESABS = RESABS*HLGTH
+      ABSERR = DABS((RESK-RESG)*HLGTH)
+      IF(RESASC.NE.0.0D+00.AND.ABSERR.NE.0.D0) ABSERR = RESASC*
+     * DMIN1(0.1D+01,(0.2D+03*ABSERR/RESASC)**1.5D+00)
+      IF(RESABS.GT.UFLOW/(0.5D+02*EPMACH)) ABSERR = DMAX1
+     * ((EPMACH*0.5D+02)*RESABS,ABSERR)
+      RETURN
+      END
diff --git a/libcruft/quadpack/dqk21.f b/libcruft/quadpack/dqk21.f
new file mode 100644
index 0000000..dfbe9d4
--- /dev/null
+++ b/libcruft/quadpack/dqk21.f
@@ -0,0 +1,187 @@
+      SUBROUTINE DQK21(F,A,B,RESULT,ABSERR,RESABS,RESASC,IERR)
+C***BEGIN PROLOGUE  DQK21
+C***DATE WRITTEN   800101   (YYMMDD)
+C***REVISION DATE  830518   (YYMMDD)
+C***CATEGORY NO.  H2A1A2
+C***KEYWORDS  21-POINT GAUSS-KRONROD RULES
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C***PURPOSE  TO COMPUTE I = INTEGRAL OF F OVER (A,B), WITH ERROR
+C                           ESTIMATE
+C                       J = INTEGRAL OF ABS(F) OVER (A,B)
+C***DESCRIPTION
+C
+C           INTEGRATION RULES
+C           STANDARD FORTRAN SUBROUTINE
+C           DOUBLE PRECISION VERSION
+C
+C           PARAMETERS
+C            ON ENTRY
+C              F      - SUBROUTINE F(X,IERR,RESULT) DEFINING THE INTEGRAND
+C                       FUNCTION F(X). THE ACTUAL NAME FOR F NEEDS TO BE
+C                       DECLARED E X T E R N A L IN THE DRIVER PROGRAM.
+C
+C              A      - DOUBLE PRECISION
+C                       LOWER LIMIT OF INTEGRATION
+C
+C              B      - DOUBLE PRECISION
+C                       UPPER LIMIT OF INTEGRATION
+C
+C            ON RETURN
+C              RESULT - DOUBLE PRECISION
+C                       APPROXIMATION TO THE INTEGRAL I
+C                       RESULT IS COMPUTED BY APPLYING THE 21-POINT
+C                       KRONROD RULE (RESK) OBTAINED BY OPTIMAL ADDITION
+C                       OF ABSCISSAE TO THE 10-POINT GAUSS RULE (RESG).
+C
+C              ABSERR - DOUBLE PRECISION
+C                       ESTIMATE OF THE MODULUS OF THE ABSOLUTE ERROR,
+C                       WHICH SHOULD NOT EXCEED ABS(I-RESULT)
+C
+C              RESABS - DOUBLE PRECISION
+C                       APPROXIMATION TO THE INTEGRAL J
+C
+C              RESASC - DOUBLE PRECISION
+C                       APPROXIMATION TO THE INTEGRAL OF ABS(F-I/(B-A))
+C                       OVER (A,B)
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH
+C***END PROLOGUE  DQK21
+C
+      DOUBLE PRECISION A,ABSC,ABSERR,B,CENTR,DABS,DHLGTH,DMAX1,DMIN1,
+     *  D1MACH,EPMACH,FC,FSUM,FVAL1,FVAL2,FV1,FV2,HLGTH,RESABS,RESASC,
+     *  RESG,RESK,RESKH,RESULT,UFLOW,WG,WGK,XGK
+      INTEGER J,JTW,JTWM1
+      EXTERNAL F
+C
+      DIMENSION FV1(10),FV2(10),WG(5),WGK(11),XGK(11)
+C
+C           THE ABSCISSAE AND WEIGHTS ARE GIVEN FOR THE INTERVAL (-1,1).
+C           BECAUSE OF SYMMETRY ONLY THE POSITIVE ABSCISSAE AND THEIR
+C           CORRESPONDING WEIGHTS ARE GIVEN.
+C
+C           XGK    - ABSCISSAE OF THE 21-POINT KRONROD RULE
+C                    XGK(2), XGK(4), ...  ABSCISSAE OF THE 10-POINT
+C                    GAUSS RULE
+C                    XGK(1), XGK(3), ...  ABSCISSAE WHICH ARE OPTIMALLY
+C                    ADDED TO THE 10-POINT GAUSS RULE
+C
+C           WGK    - WEIGHTS OF THE 21-POINT KRONROD RULE
+C
+C           WG     - WEIGHTS OF THE 10-POINT GAUSS RULE
+C
+C
+C GAUSS QUADRATURE WEIGHTS AND KRONRON QUADRATURE ABSCISSAE AND WEIGHTS
+C AS EVALUATED WITH 80 DECIMAL DIGIT ARITHMETIC BY L. W. FULLERTON,
+C BELL LABS, NOV. 1981.
+C
+      DATA WG  (  1) / 0.0666713443 0868813759 3568809893 332 D0 /
+      DATA WG  (  2) / 0.1494513491 5058059314 5776339657 697 D0 /
+      DATA WG  (  3) / 0.2190863625 1598204399 5534934228 163 D0 /
+      DATA WG  (  4) / 0.2692667193 0999635509 1226921569 469 D0 /
+      DATA WG  (  5) / 0.2955242247 1475287017 3892994651 338 D0 /
+C
+      DATA XGK (  1) / 0.9956571630 2580808073 5527280689 003 D0 /
+      DATA XGK (  2) / 0.9739065285 1717172007 7964012084 452 D0 /
+      DATA XGK (  3) / 0.9301574913 5570822600 1207180059 508 D0 /
+      DATA XGK (  4) / 0.8650633666 8898451073 2096688423 493 D0 /
+      DATA XGK (  5) / 0.7808177265 8641689706 3717578345 042 D0 /
+      DATA XGK (  6) / 0.6794095682 9902440623 4327365114 874 D0 /
+      DATA XGK (  7) / 0.5627571346 6860468333 9000099272 694 D0 /
+      DATA XGK (  8) / 0.4333953941 2924719079 9265943165 784 D0 /
+      DATA XGK (  9) / 0.2943928627 0146019813 1126603103 866 D0 /
+      DATA XGK ( 10) / 0.1488743389 8163121088 4826001129 720 D0 /
+      DATA XGK ( 11) / 0.0000000000 0000000000 0000000000 000 D0 /
+C
+      DATA WGK (  1) / 0.0116946388 6737187427 8064396062 192 D0 /
+      DATA WGK (  2) / 0.0325581623 0796472747 8818972459 390 D0 /
+      DATA WGK (  3) / 0.0547558965 7435199603 1381300244 580 D0 /
+      DATA WGK (  4) / 0.0750396748 1091995276 7043140916 190 D0 /
+      DATA WGK (  5) / 0.0931254545 8369760553 5065465083 366 D0 /
+      DATA WGK (  6) / 0.1093871588 0229764189 9210590325 805 D0 /
+      DATA WGK (  7) / 0.1234919762 6206585107 7958109831 074 D0 /
+      DATA WGK (  8) / 0.1347092173 1147332592 8054001771 707 D0 /
+      DATA WGK (  9) / 0.1427759385 7706008079 7094273138 717 D0 /
+      DATA WGK ( 10) / 0.1477391049 0133849137 4841515972 068 D0 /
+      DATA WGK ( 11) / 0.1494455540 0291690566 4936468389 821 D0 /
+C
+C
+C           LIST OF MAJOR VARIABLES
+C           -----------------------
+C
+C           CENTR  - MID POINT OF THE INTERVAL
+C           HLGTH  - HALF-LENGTH OF THE INTERVAL
+C           ABSC   - ABSCISSA
+C           FVAL*  - FUNCTION VALUE
+C           RESG   - RESULT OF THE 10-POINT GAUSS FORMULA
+C           RESK   - RESULT OF THE 21-POINT KRONROD FORMULA
+C           RESKH  - APPROXIMATION TO THE MEAN VALUE OF F OVER (A,B),
+C                    I.E. TO I/(B-A)
+C
+C
+C           MACHINE DEPENDENT CONSTANTS
+C           ---------------------------
+C
+C           EPMACH IS THE LARGEST RELATIVE SPACING.
+C           UFLOW IS THE SMALLEST POSITIVE MAGNITUDE.
+C
+C***FIRST EXECUTABLE STATEMENT  DQK21
+      EPMACH = D1MACH(4)
+      UFLOW = D1MACH(1)
+C
+      CENTR = 0.5D+00*(A+B)
+      HLGTH = 0.5D+00*(B-A)
+      DHLGTH = DABS(HLGTH)
+C
+C           COMPUTE THE 21-POINT KRONROD APPROXIMATION TO
+C           THE INTEGRAL, AND ESTIMATE THE ABSOLUTE ERROR.
+C
+      RESG = 0.0D+00
+      IERR = 0
+      CALL F(CENTR,IERR,FC)
+      IF (IERR .LT. 0) RETURN
+      RESK = WGK(11)*FC
+      RESABS = DABS(RESK)
+      DO 10 J=1,5
+        JTW = 2*J
+        ABSC = HLGTH*XGK(JTW)
+        CALL F(CENTR-ABSC,IERR,FVAL1)
+        IF (IERR .LT. 0) RETURN
+        CALL F(CENTR+ABSC,IERR,FVAL2)
+        IF (IERR .LT. 0) RETURN
+        FV1(JTW) = FVAL1
+        FV2(JTW) = FVAL2
+        FSUM = FVAL1+FVAL2
+        RESG = RESG+WG(J)*FSUM
+        RESK = RESK+WGK(JTW)*FSUM
+        RESABS = RESABS+WGK(JTW)*(DABS(FVAL1)+DABS(FVAL2))
+   10 CONTINUE
+      DO 15 J = 1,5
+        JTWM1 = 2*J-1
+        ABSC = HLGTH*XGK(JTWM1)
+        CALL F(CENTR-ABSC,IERR,FVAL1)
+        IF (IERR .LT. 0) RETURN
+        CALL F(CENTR+ABSC,IERR,FVAL2)
+        IF (IERR .LT. 0) RETURN
+        FV1(JTWM1) = FVAL1
+        FV2(JTWM1) = FVAL2
+        FSUM = FVAL1+FVAL2
+        RESK = RESK+WGK(JTWM1)*FSUM
+        RESABS = RESABS+WGK(JTWM1)*(DABS(FVAL1)+DABS(FVAL2))
+   15 CONTINUE
+      RESKH = RESK*0.5D+00
+      RESASC = WGK(11)*DABS(FC-RESKH)
+      DO 20 J=1,10
+        RESASC = RESASC+WGK(J)*(DABS(FV1(J)-RESKH)+DABS(FV2(J)-RESKH))
+   20 CONTINUE
+      RESULT = RESK*HLGTH
+      RESABS = RESABS*DHLGTH
+      RESASC = RESASC*DHLGTH
+      ABSERR = DABS((RESK-RESG)*HLGTH)
+      IF(RESASC.NE.0.0D+00.AND.ABSERR.NE.0.0D+00)
+     *  ABSERR = RESASC*DMIN1(0.1D+01,(0.2D+03*ABSERR/RESASC)**1.5D+00)
+      IF(RESABS.GT.UFLOW/(0.5D+02*EPMACH)) ABSERR = DMAX1
+     *  ((EPMACH*0.5D+02)*RESABS,ABSERR)
+      RETURN
+      END
diff --git a/libcruft/quadpack/dqpsrt.f b/libcruft/quadpack/dqpsrt.f
new file mode 100644
index 0000000..db821ee
--- /dev/null
+++ b/libcruft/quadpack/dqpsrt.f
@@ -0,0 +1,129 @@
+      SUBROUTINE DQPSRT(LIMIT,LAST,MAXERR,ERMAX,ELIST,IORD,NRMAX)
+C***BEGIN PROLOGUE  DQPSRT
+C***REFER TO  DQAGE,DQAGIE,DQAGPE,DQAWSE
+C***ROUTINES CALLED  (NONE)
+C***REVISION DATE  810101   (YYMMDD)
+C***KEYWORDS  SEQUENTIAL SORTING
+C***AUTHOR  PIESSENS,ROBERT,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C           DE DONCKER,ELISE,APPL. MATH. & PROGR. DIV. - K.U.LEUVEN
+C***PURPOSE  THIS ROUTINE MAINTAINS THE DESCENDING ORDERING IN THE
+C            LIST OF THE LOCAL ERROR ESTIMATED RESULTING FROM THE
+C            INTERVAL SUBDIVISION PROCESS. AT EACH CALL TWO ERROR
+C            ESTIMATES ARE INSERTED USING THE SEQUENTIAL SEARCH
+C            METHOD, TOP-DOWN FOR THE LARGEST ERROR ESTIMATE AND
+C            BOTTOM-UP FOR THE SMALLEST ERROR ESTIMATE.
+C***DESCRIPTION
+C
+C           ORDERING ROUTINE
+C           STANDARD FORTRAN SUBROUTINE
+C           DOUBLE PRECISION VERSION
+C
+C           PARAMETERS (MEANING AT OUTPUT)
+C              LIMIT  - INTEGER
+C                       MAXIMUM NUMBER OF ERROR ESTIMATES THE LIST
+C                       CAN CONTAIN
+C
+C              LAST   - INTEGER
+C                       NUMBER OF ERROR ESTIMATES CURRENTLY IN THE LIST
+C
+C              MAXERR - INTEGER
+C                       MAXERR POINTS TO THE NRMAX-TH LARGEST ERROR
+C                       ESTIMATE CURRENTLY IN THE LIST
+C
+C              ERMAX  - DOUBLE PRECISION
+C                       NRMAX-TH LARGEST ERROR ESTIMATE
+C                       ERMAX = ELIST(MAXERR)
+C
+C              ELIST  - DOUBLE PRECISION
+C                       VECTOR OF DIMENSION LAST CONTAINING
+C                       THE ERROR ESTIMATES
+C
+C              IORD   - INTEGER
+C                       VECTOR OF DIMENSION LAST, THE FIRST K ELEMENTS
+C                       OF WHICH CONTAIN POINTERS TO THE ERROR
+C                       ESTIMATES, SUCH THAT
+C                       ELIST(IORD(1)),...,  ELIST(IORD(K))
+C                       FORM A DECREASING SEQUENCE, WITH
+C                       K = LAST IF LAST.LE.(LIMIT/2+2), AND
+C                       K = LIMIT+1-LAST OTHERWISE
+C
+C              NRMAX  - INTEGER
+C                       MAXERR = IORD(NRMAX)
+C
+C***END PROLOGUE  DQPSRT
+C
+      DOUBLE PRECISION ELIST,ERMAX,ERRMAX,ERRMIN
+      INTEGER I,IBEG,IDO,IORD,ISUCC,J,JBND,JUPBN,K,LAST,LIMIT,MAXERR,
+     *  NRMAX
+      DIMENSION ELIST(LAST),IORD(LAST)
+C
+C           CHECK WHETHER THE LIST CONTAINS MORE THAN
+C           TWO ERROR ESTIMATES.
+C
+C***FIRST EXECUTABLE STATEMENT  DQPSRT
+      IF(LAST.GT.2) GO TO 10
+      IORD(1) = 1
+      IORD(2) = 2
+      GO TO 90
+C
+C           THIS PART OF THE ROUTINE IS ONLY EXECUTED IF, DUE TO A
+C           DIFFICULT INTEGRAND, SUBDIVISION INCREASED THE ERROR
+C           ESTIMATE. IN THE NORMAL CASE THE INSERT PROCEDURE SHOULD
+C           START AFTER THE NRMAX-TH LARGEST ERROR ESTIMATE.
+C
+   10 ERRMAX = ELIST(MAXERR)
+      IF(NRMAX.EQ.1) GO TO 30
+      IDO = NRMAX-1
+      DO 20 I = 1,IDO
+        ISUCC = IORD(NRMAX-1)
+C ***JUMP OUT OF DO-LOOP
+        IF(ERRMAX.LE.ELIST(ISUCC)) GO TO 30
+        IORD(NRMAX) = ISUCC
+        NRMAX = NRMAX-1
+   20    CONTINUE
+C
+C           COMPUTE THE NUMBER OF ELEMENTS IN THE LIST TO BE MAINTAINED
+C           IN DESCENDING ORDER. THIS NUMBER DEPENDS ON THE NUMBER OF
+C           SUBDIVISIONS STILL ALLOWED.
+C
+   30 JUPBN = LAST
+      IF(LAST.GT.(LIMIT/2+2)) JUPBN = LIMIT+3-LAST
+      ERRMIN = ELIST(LAST)
+C
+C           INSERT ERRMAX BY TRAVERSING THE LIST TOP-DOWN,
+C           STARTING COMPARISON FROM THE ELEMENT ELIST(IORD(NRMAX+1)).
+C
+      JBND = JUPBN-1
+      IBEG = NRMAX+1
+      IF(IBEG.GT.JBND) GO TO 50
+      DO 40 I=IBEG,JBND
+        ISUCC = IORD(I)
+C ***JUMP OUT OF DO-LOOP
+        IF(ERRMAX.GE.ELIST(ISUCC)) GO TO 60
+        IORD(I-1) = ISUCC
+   40 CONTINUE
+   50 IORD(JBND) = MAXERR
+      IORD(JUPBN) = LAST
+      GO TO 90
+C
+C           INSERT ERRMIN BY TRAVERSING THE LIST BOTTOM-UP.
+C
+   60 IORD(I-1) = MAXERR
+      K = JBND
+      DO 70 J=I,JBND
+        ISUCC = IORD(K)
+C ***JUMP OUT OF DO-LOOP
+        IF(ERRMIN.LT.ELIST(ISUCC)) GO TO 80
+        IORD(K+1) = ISUCC
+        K = K-1
+   70 CONTINUE
+      IORD(I) = LAST
+      GO TO 90
+   80 IORD(K+1) = LAST
+C
+C           SET MAXERR AND ERMAX.
+C
+   90 MAXERR = IORD(NRMAX)
+      ERMAX = ELIST(MAXERR)
+      RETURN
+      END
diff --git a/libcruft/quadpack/qagi.f b/libcruft/quadpack/qagi.f
new file mode 100644
index 0000000..258c799
--- /dev/null
+++ b/libcruft/quadpack/qagi.f
@@ -0,0 +1,190 @@
+      subroutine qagi(f,bound,inf,epsabs,epsrel,result,abserr,neval,
+     *   ier,limit,lenw,last,iwork,work)
+c***begin prologue  qagi
+c***date written   800101   (yymmdd)
+c***revision date  830518   (yymmdd)
+c***category no.  h2a3a1,h2a4a1
+c***keywords  automatic integrator, infinite intervals,
+c             general-purpose, transformation, extrapolation,
+c             globally adaptive
+c***author  piessens,robert,appl. math. & progr. div. - k.u.leuven
+c           de doncker,elise,appl. math. & progr. div. -k.u.leuven
+c***purpose  the routine calculates an approximation result to a given
+c            integral   i = integral of f over (bound,+infinity)
+c                    or i = integral of f over (-infinity,bound)
+c                    or i = integral of f over (-infinity,+infinity)
+c            hopefully satisfying following claim for accuracy
+c            abs(i-result).le.max(epsabs,epsrel*abs(i)).
+c***description
+c
+c        integration over infinite intervals
+c        standard fortran subroutine
+c
+c        parameters
+c         on entry
+c            f      - subroutine f(x,result) defining the integrand
+c                     function f(x). the actual name for f needs to be
+c                     declared e x t e r n a l in the driver program.
+c
+c            bound  - real
+c                     finite bound of integration range
+c                     (has no meaning if interval is doubly-infinite)
+c
+c            inf    - integer
+c                     indicating the kind of integration range involved
+c                     inf = 1 corresponds to  (bound,+infinity),
+c                     inf = -1            to  (-infinity,bound),
+c                     inf = 2             to (-infinity,+infinity).
+c
+c            epsabs - real
+c                     absolute accuracy requested
+c            epsrel - real
+c                     relative accuracy requested
+c                     if  epsabs.le.0
+c                     and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c                     the routine will end with ier = 6.
+c
+c
+c         on return
+c            result - real
+c                     approximation to the integral
+c
+c            abserr - real
+c                     estimate of the modulus of the absolute error,
+c                     which should equal or exceed abs(i-result)
+c
+c            neval  - integer
+c                     number of integrand evaluations
+c
+c            ier    - integer
+c                     ier = 0 normal and reliable termination of the
+c                             routine. it is assumed that the requested
+c                             accuracy has been achieved.
+c                   - ier.gt.0 abnormal termination of the routine. the
+c                             estimates for result and error are less
+c                             reliable. it is assumed that the requested
+c                             accuracy has not been achieved.
+c            error messages
+c                     ier = 1 maximum number of subdivisions allowed
+c                             has been achieved. one can allow more
+c                             subdivisions by increasing the value of
+c                             limit (and taking the according dimension
+c                             adjustments into account). however, if
+c                             this yields no improvement it is advised
+c                             to analyze the integrand in order to
+c                             determine the integration difficulties. if
+c                             the position of a local difficulty can be
+c                             determined (e.g. singularity,
+c                             discontinuity within the interval) one
+c                             will probably gain from splitting up the
+c                             interval at this point and calling the
+c                             integrator on the subranges. if possible,
+c                             an appropriate special-purpose integrator
+c                             should be used, which is designed for
+c                             handling the type of difficulty involved.
+c                         = 2 the occurrence of roundoff error is
+c                             detected, which prevents the requested
+c                             tolerance from being achieved.
+c                             the error may be under-estimated.
+c                         = 3 extremely bad integrand behaviour occurs
+c                             at some points of the integration
+c                             interval.
+c                         = 4 the algorithm does not converge.
+c                             roundoff error is detected in the
+c                             extrapolation table.
+c                             it is assumed that the requested tolerance
+c                             cannot be achieved, and that the returned
+c                             result is the best which can be obtained.
+c                         = 5 the integral is probably divergent, or
+c                             slowly convergent. it must be noted that
+c                             divergence can occur with any other value
+c                             of ier.
+c                         = 6 the input is invalid, because
+c                             (epsabs.le.0 and
+c                              epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
+c                              or limit.lt.1 or leniw.lt.limit*4.
+c                             result, abserr, neval, last are set to
+c                             zero. exept when limit or leniw is
+c                             invalid, iwork(1), work(limit*2+1) and
+c                             work(limit*3+1) are set to zero, work(1)
+c                             is set to a and work(limit+1) to b.
+c
+c         dimensioning parameters
+c            limit - integer
+c                    dimensioning parameter for iwork
+c                    limit determines the maximum number of subintervals
+c                    in the partition of the given integration interval
+c                    (a,b), limit.ge.1.
+c                    if limit.lt.1, the routine will end with ier = 6.
+c
+c            lenw  - integer
+c                    dimensioning parameter for work
+c                    lenw must be at least limit*4.
+c                    if lenw.lt.limit*4, the routine will end
+c                    with ier = 6.
+c
+c            last  - integer
+c                    on return, last equals the number of subintervals
+c                    produced in the subdivision process, which
+c                    determines the number of significant elements
+c                    actually in the work arrays.
+c
+c         work arrays
+c            iwork - integer
+c                    vector of dimension at least limit, the first
+c                    k elements of which contain pointers
+c                    to the error estimates over the subintervals,
+c                    such that work(limit*3+iwork(1)),... ,
+c                    work(limit*3+iwork(k)) form a decreasing
+c                    sequence, with k = last if last.le.(limit/2+2), and
+c                    k = limit+1-last otherwise
+c
+c            work  - real
+c                    vector of dimension at least lenw
+c                    on return
+c                    work(1), ..., work(last) contain the left
+c                     end points of the subintervals in the
+c                     partition of (a,b),
+c                    work(limit+1), ..., work(limit+last) contain
+c                     the right end points,
+c                    work(limit*2+1), ...,work(limit*2+last) contain the
+c                     integral approximations over the subintervals,
+c                    work(limit*3+1), ..., work(limit*3)
+c                     contain the error estimates.
+c***references  (none)
+c***routines called  qagie,xerror
+c***end prologue  qagi
+c
+      real   abserr,  epsabs,epsrel,result,work
+      integer ier,iwork,    lenw,limit,lvl,l1,l2,l3,neval
+c
+      dimension iwork(limit),work(lenw)
+c
+      external f
+c
+c         check validity of limit and lenw.
+c
+c***first executable statement  qagi
+      ier = 6
+      neval = 0
+      last = 0
+      result = 0.0e+00
+      abserr = 0.0e+00
+      if(limit.lt.1.or.lenw.lt.limit*4) go to 10
+c
+c         prepare call for qagie.
+c
+      l1 = limit+1
+      l2 = limit+l1
+      l3 = limit+l2
+c
+      call qagie(f,bound,inf,epsabs,epsrel,limit,result,abserr,
+     *  neval,ier,work(1),work(l1),work(l2),work(l3),iwork,last)
+c
+c         call error handler if necessary.
+c
+      lvl = 0
+10    if(ier.eq.6) lvl = 1
+      if(ier.ne.0) call xerror('abnormal return from  qagi',26,ier,lvl)
+      return
+      end
diff --git a/libcruft/quadpack/qagie.f b/libcruft/quadpack/qagie.f
new file mode 100644
index 0000000..15d6968
--- /dev/null
+++ b/libcruft/quadpack/qagie.f
@@ -0,0 +1,460 @@
+      subroutine qagie(f,bound,inf,epsabs,epsrel,limit,result,abserr,
+     *   neval,ier,alist,blist,rlist,elist,iord,last)
+c***begin prologue  qagie
+c***date written   800101   (yymmdd)
+c***revision date  830518   (yymmdd)
+c***category no.  h2a3a1,h2a4a1
+c***keywords  automatic integrator, infinite intervals,
+c             general-purpose, transformation, extrapolation,
+c             globally adaptive
+c***author  piessens,robert,appl. math & progr. div - k.u.leuven
+c           de doncker,elise,appl. math & progr. div - k.u.leuven
+c***purpose  the routine calculates an approximation result to a given
+c            integral   i = integral of f over (bound,+infinity)
+c                    or i = integral of f over (-infinity,bound)
+c                    or i = integral of f over (-infinity,+infinity),
+c                    hopefully satisfying following claim for accuracy
+c                    abs(i-result).le.max(epsabs,epsrel*abs(i))
+c***description
+c
+c integration over infinite intervals
+c standard fortran subroutine
+c
+c            f      - subroutine f(x,ierr,result) defining the integrand
+c                     function f(x). the actual name for f needs to be
+c                     declared e x t e r n a l in the driver program.
+c
+c            bound  - real
+c                     finite bound of integration range
+c                     (has no meaning if interval is doubly-infinite)
+c
+c            inf    - real
+c                     indicating the kind of integration range involved
+c                     inf = 1 corresponds to  (bound,+infinity),
+c                     inf = -1            to  (-infinity,bound),
+c                     inf = 2             to (-infinity,+infinity).
+c
+c            epsabs - real
+c                     absolute accuracy requested
+c            epsrel - real
+c                     relative accuracy requested
+c                     if  epsabs.le.0
+c                     and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c                     the routine will end with ier = 6.
+c
+c            limit  - integer
+c                     gives an upper bound on the number of subintervals
+c                     in the partition of (a,b), limit.ge.1
+c
+c         on return
+c            result - real
+c                     approximation to the integral
+c
+c            abserr - real
+c                     estimate of the modulus of the absolute error,
+c                     which should equal or exceed abs(i-result)
+c
+c            neval  - integer
+c                     number of integrand evaluations
+c
+c            ier    - integer
+c                     ier = 0 normal and reliable termination of the
+c                             routine. it is assumed that the requested
+c                             accuracy has been achieved.
+c                   - ier.gt.0 abnormal termination of the routine. the
+c                             estimates for result and error are less
+c                             reliable. it is assumed that the requested
+c                             accuracy has not been achieved.
+c            error messages
+c                     ier = 1 maximum number of subdivisions allowed
+c                             has been achieved. one can allow more
+c                             subdivisions by increasing the value of
+c                             limit (and taking the according dimension
+c                             adjustments into account). however,if
+c                             this yields no improvement it is advised
+c                             to analyze the integrand in order to
+c                             determine the integration difficulties.
+c                             if the position of a local difficulty can
+c                             be determined (e.g. singularity,
+c                             discontinuity within the interval) one
+c                             will probably gain from splitting up the
+c                             interval at this point and calling the
+c                             integrator on the subranges. if possible,
+c                             an appropriate special-purpose integrator
+c                             should be used, which is designed for
+c                             handling the type of difficulty involved.
+c                         = 2 the occurrence of roundoff error is
+c                             detected, which prevents the requested
+c                             tolerance from being achieved.
+c                             the error may be under-estimated.
+c                         = 3 extremely bad integrand behaviour occurs
+c                             at some points of the integration
+c                             interval.
+c                         = 4 the algorithm does not converge.
+c                             roundoff error is detected in the
+c                             extrapolation table.
+c                             it is assumed that the requested tolerance
+c                             cannot be achieved, and that the returned
+c                             result is the best which can be obtained.
+c                         = 5 the integral is probably divergent, or
+c                             slowly convergent. it must be noted that
+c                             divergence can occur with any other value
+c                             of ier.
+c                         = 6 the input is invalid, because
+c                             (epsabs.le.0 and
+c                              epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c                             result, abserr, neval, last, rlist(1),
+c                             elist(1) and iord(1) are set to zero.
+c                             alist(1) and blist(1) are set to 0
+c                             and 1 respectively.
+c
+c            alist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the left
+c                     end points of the subintervals in the partition
+c                     of the transformed integration range (0,1).
+c
+c            blist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the right
+c                     end points of the subintervals in the partition
+c                     of the transformed integration range (0,1).
+c
+c            rlist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the integral
+c                     approximations on the subintervals
+c
+c            elist  - real
+c                     vector of dimension at least limit,  the first
+c                     last elements of which are the moduli of the
+c                     absolute error estimates on the subintervals
+c
+c            iord   - integer
+c                     vector of dimension limit, the first k
+c                     elements of which are pointers to the
+c                     error estimates over the subintervals,
+c                     such that elist(iord(1)), ..., elist(iord(k))
+c                     form a decreasing sequence, with k = last
+c                     if last.le.(limit/2+2), and k = limit+1-last
+c                     otherwise
+c
+c            last   - integer
+c                     number of subintervals actually produced
+c                     in the subdivision process
+c
+c***references  (none)
+c***routines called  qelg,qk15i,qpsrt,r1mach
+c***end prologue  qagie
+c
+      real abseps,abserr,alist,area,area1,area12,area2,a1,
+     *  a2,blist,boun,bound,b1,b2,correc,defabs,defab1,defab2,
+     *  dres,r1mach,elist,epmach,epsabs,epsrel,erlarg,erlast,
+     *  errbnd,errmax,error1,error2,erro12,errsum,ertest,oflow,resabs,
+     *  reseps,result,res3la,rlist,rlist2,small,uflow
+      integer id,ier,ierro,inf,iord,iroff1,iroff2,iroff3,jupbnd,k,ksgn,
+     *  ktmin,last,limit,maxerr,neval,nres,nrmax,numrl2
+      logical extrap,noext
+c
+      dimension alist(limit),blist(limit),elist(limit),iord(limit),
+     *  res3la(3),rlist(limit),rlist2(52)
+c
+      external f
+c
+c            the dimension of rlist2 is determined by the value of
+c            limexp in subroutine qelg.
+c
+c
+c            list of major variables
+c            -----------------------
+c
+c           alist     - list of left end points of all subintervals
+c                       considered up to now
+c           blist     - list of right end points of all subintervals
+c                       considered up to now
+c           rlist(i)  - approximation to the integral over
+c                       (alist(i),blist(i))
+c           rlist2    - array of dimension at least (limexp+2),
+c                       containing the part of the epsilon table
+c                       wich is still needed for further computations
+c           elist(i)  - error estimate applying to rlist(i)
+c           maxerr    - pointer to the interval with largest error
+c                       estimate
+c           errmax    - elist(maxerr)
+c           erlast    - error on the interval currently subdivided
+c                       (before that subdivision has taken place)
+c           area      - sum of the integrals over the subintervals
+c           errsum    - sum of the errors over the subintervals
+c           errbnd    - requested accuracy max(epsabs,epsrel*
+c                       abs(result))
+c           *****1    - variable for the left subinterval
+c           *****2    - variable for the right subinterval
+c           last      - index for subdivision
+c           nres      - number of calls to the extrapolation routine
+c           numrl2    - number of elements currently in rlist2. if an
+c                       appropriate approximation to the compounded
+c                       integral has been obtained, it is put in
+c                       rlist2(numrl2) after numrl2 has been increased
+c                       by one.
+c           small     - length of the smallest interval considered up
+c                       to now, multiplied by 1.5
+c           erlarg    - sum of the errors over the intervals larger
+c                       than the smallest interval considered up to now
+c           extrap    - logical variable denoting that the routine
+c                       is attempting to perform extrapolation. i.e.
+c                       before subdividing the smallest interval we
+c                       try to decrease the value of erlarg.
+c           noext     - logical variable denoting that extrapolation
+c                       is no longer allowed (true-value)
+c
+c            machine dependent constants
+c            ---------------------------
+c
+c           epmach is the largest relative spacing.
+c           uflow is the smallest positive magnitude.
+c           oflow is the largest positive magnitude.
+c
+       epmach = r1mach(4)
+c
+c           test on validity of parameters
+c           -----------------------------
+c
+c***first executable statement  qagie
+      ier = 0
+      neval = 0
+      last = 0
+      result = 0.0e+00
+      abserr = 0.0e+00
+      alist(1) = 0.0e+00
+      blist(1) = 0.1e+01
+      rlist(1) = 0.0e+00
+      elist(1) = 0.0e+00
+      iord(1) = 0
+      if(epsabs.le.0.0e+00.and.epsrel.lt.amax1(0.5e+02*epmach,0.5e-14))
+     *  ier = 6
+      if(ier.eq.6) go to 999
+c
+c
+c           first approximation to the integral
+c           -----------------------------------
+c
+c           determine the interval to be mapped onto (0,1).
+c           if inf = 2 the integral is computed as i = i1+i2, where
+c           i1 = integral of f over (-infinity,0),
+c           i2 = integral of f over (0,+infinity).
+c
+      boun = bound
+      if(inf.eq.2) boun = 0.0e+00
+      call qk15i(f,boun,inf,0.0e+00,0.1e+01,result,abserr,
+     *  defabs,resabs,ier)
+      if (ier.lt.0) return
+c
+c           test on accuracy
+c
+      last = 1
+      rlist(1) = result
+      elist(1) = abserr
+      iord(1) = 1
+      dres = abs(result)
+      errbnd = amax1(epsabs,epsrel*dres)
+      if(abserr.le.1.0e+02*epmach*defabs.and.abserr.gt.
+     *  errbnd) ier = 2
+      if(limit.eq.1) ier = 1
+      if(ier.ne.0.or.(abserr.le.errbnd.and.abserr.ne.resabs).or.
+     *  abserr.eq.0.0e+00) go to 130
+c
+c           initialization
+c           --------------
+c
+      uflow = r1mach(1)
+      oflow = r1mach(2)
+      rlist2(1) = result
+      errmax = abserr
+      maxerr = 1
+      area = result
+      errsum = abserr
+      abserr = oflow
+      nrmax = 1
+      nres = 0
+      ktmin = 0
+      numrl2 = 2
+      extrap = .false.
+      noext = .false.
+      ierro = 0
+      iroff1 = 0
+      iroff2 = 0
+      iroff3 = 0
+      ksgn = -1
+      if(dres.ge.(0.1e+01-0.5e+02*epmach)*defabs) ksgn = 1
+c
+c           main do-loop
+c           ------------
+c
+      do 90 last = 2,limit
+c
+c           bisect the subinterval with nrmax-th largest
+c           error estimate.
+c
+        a1 = alist(maxerr)
+        b1 = 0.5e+00*(alist(maxerr)+blist(maxerr))
+        a2 = b1
+        b2 = blist(maxerr)
+        erlast = errmax
+        call qk15i(f,boun,inf,a1,b1,area1,error1,resabs,defab1,ier)
+        if (ier.lt.0) return
+        call qk15i(f,boun,inf,a2,b2,area2,error2,resabs,defab2,ier)
+        if (ier.lt.0) return
+c
+c           improve previous approximations to integral
+c           and error and test for accuracy.
+c
+        area12 = area1+area2
+        erro12 = error1+error2
+        errsum = errsum+erro12-errmax
+        area = area+area12-rlist(maxerr)
+        if(defab1.eq.error1.or.defab2.eq.error2)go to 15
+        if(abs(rlist(maxerr)-area12).gt.0.1e-04*abs(area12)
+     *  .or.erro12.lt.0.99e+00*errmax) go to 10
+        if(extrap) iroff2 = iroff2+1
+        if(.not.extrap) iroff1 = iroff1+1
+   10   if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
+   15   rlist(maxerr) = area1
+        rlist(last) = area2
+        errbnd = amax1(epsabs,epsrel*abs(area))
+c
+c           test for roundoff error and eventually
+c           set error flag.
+c
+        if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
+        if(iroff2.ge.5) ierro = 3
+c
+c           set error flag in the case that the number of
+c           subintervals equals limit.
+c
+        if(last.eq.limit) ier = 1
+c
+c           set error flag in the case of bad integrand behaviour
+c           at some points of the integration range.
+c
+        if(amax1(abs(a1),abs(b2)).le.(0.1e+01+0.1e+03*epmach)*
+     *  (abs(a2)+0.1e+04*uflow)) ier = 4
+c
+c           append the newly-created intervals to the list.
+c
+        if(error2.gt.error1) go to 20
+        alist(last) = a2
+        blist(maxerr) = b1
+        blist(last) = b2
+        elist(maxerr) = error1
+        elist(last) = error2
+        go to 30
+   20   alist(maxerr) = a2
+        alist(last) = a1
+        blist(last) = b1
+        rlist(maxerr) = area2
+        rlist(last) = area1
+        elist(maxerr) = error2
+        elist(last) = error1
+c
+c           call subroutine qpsrt to maintain the descending ordering
+c           in the list of error estimates and select the
+c           subinterval with nrmax-th largest error estimate (to be
+c           bisected next).
+c
+   30   call qpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
+        if(errsum.le.errbnd) go to 115
+        if(ier.ne.0) go to 100
+        if(last.eq.2) go to 80
+        if(noext) go to 90
+        erlarg = erlarg-erlast
+        if(abs(b1-a1).gt.small) erlarg = erlarg+erro12
+        if(extrap) go to 40
+c
+c           test whether the interval to be bisected next is the
+c           smallest interval.
+c
+        if(abs(blist(maxerr)-alist(maxerr)).gt.small) go to 90
+        extrap = .true.
+        nrmax = 2
+   40   if(ierro.eq.3.or.erlarg.le.ertest) go to 60
+c
+c           the smallest interval has the largest error.
+c           before bisecting decrease the sum of the errors
+c           over the larger intervals (erlarg) and perform
+c           extrapolation.
+c
+        id = nrmax
+        jupbnd = last
+        if(last.gt.(2+limit/2)) jupbnd = limit+3-last
+        do 50 k = id,jupbnd
+          maxerr = iord(nrmax)
+          errmax = elist(maxerr)
+          if(abs(blist(maxerr)-alist(maxerr)).gt.small) go to 90
+          nrmax = nrmax+1
+   50   continue
+c
+c           perform extrapolation.
+c
+   60   numrl2 = numrl2+1
+        rlist2(numrl2) = area
+        call qelg(numrl2,rlist2,reseps,abseps,res3la,nres)
+        ktmin = ktmin+1
+        if(ktmin.gt.5.and.abserr.lt.0.1e-02*errsum) ier = 5
+        if(abseps.ge.abserr) go to 70
+        ktmin = 0
+        abserr = abseps
+        result = reseps
+        correc = erlarg
+        ertest = amax1(epsabs,epsrel*abs(reseps))
+        if(abserr.le.ertest) go to 100
+c
+c            prepare bisection of the smallest interval.
+c
+   70   if(numrl2.eq.1) noext = .true.
+        if(ier.eq.5) go to 100
+        maxerr = iord(1)
+        errmax = elist(maxerr)
+        nrmax = 1
+        extrap = .false.
+        small = small*0.5e+00
+        erlarg = errsum
+        go to 90
+   80   small = 0.375e+00
+        erlarg = errsum
+        ertest = errbnd
+        rlist2(2) = area
+   90 continue
+c
+c           set final result and error estimate.
+c           ------------------------------------
+c
+  100 if(abserr.eq.oflow) go to 115
+      if((ier+ierro).eq.0) go to 110
+      if(ierro.eq.3) abserr = abserr+correc
+      if(ier.eq.0) ier = 3
+      if(result.ne.0.0e+00.and.area.ne.0.0e+00)go to 105
+      if(abserr.gt.errsum)go to 115
+      if(area.eq.0.0e+00) go to 130
+      go to 110
+  105 if(abserr/abs(result).gt.errsum/abs(area))go to 115
+c
+c           test on divergence
+c
+  110 if(ksgn.eq.(-1).and.amax1(abs(result),abs(area)).le.
+     * defabs*0.1e-01) go to 130
+      if(0.1e-01.gt.(result/area).or.(result/area).gt.0.1e+03.
+     *or.errsum.gt.abs(area)) ier = 6
+      go to 130
+c
+c           compute global integral sum.
+c
+  115 result = 0.0e+00
+      do 120 k = 1,last
+        result = result+rlist(k)
+  120 continue
+      abserr = errsum
+  130 neval = 30*last-15
+      if(inf.eq.2) neval = 2*neval
+      if(ier.gt.2) ier=ier-1
+  999 return
+      end
diff --git a/libcruft/quadpack/qagp.f b/libcruft/quadpack/qagp.f
new file mode 100644
index 0000000..6b6caf0
--- /dev/null
+++ b/libcruft/quadpack/qagp.f
@@ -0,0 +1,223 @@
+      subroutine qagp(f,a,b,npts2,points,epsabs,epsrel,result,abserr,
+     *   neval,ier,leniw,lenw,last,iwork,work)
+c***begin prologue  qagp
+c***date written   800101   (yymmdd)
+c***revision date  830518   (yymmdd)
+c***category no.  h2a2a1
+c***keywords  automatic integrator, general-purpose,
+c             singularities at user specified points,
+c             extrapolation, globally adaptive
+c***author  piessens,robert,appl. math. & progr. div - k.u.leuven
+c           de doncker,elise,appl. math. & progr. div. - k.u.leuven
+c***purpose  the routine calculates an approximation result to a given
+c            definite integral i = integral of f over (a,b),
+c            hopefully satisfying following claim for accuracy
+c            break points of the integration interval, where local
+c            difficulties of the integrand may occur(e.g. singularities,
+c            discontinuities), are provided by the user.
+c***description
+c
+c        computation of a definite integral
+c        standard fortran subroutine
+c        real version
+c
+c        parameters
+c         on entry
+c            f      - subroutine f(x,ierr,result) defining the integrand
+c                     function f(x). the actual name for f needs to be
+c                     declared e x t e r n a l in the driver program.
+c
+c            a      - real
+c                     lower limit of integration
+c
+c            b      - real
+c                     upper limit of integration
+c
+c            npts2  - integer
+c                     number equal to two more than the number of
+c                     user-supplied break points within the integration
+c                     range, npts.ge.2.
+c                     if npts2.lt.2, the routine will end with ier = 6.
+c
+c            points - real
+c                     vector of dimension npts2, the first (npts2-2)
+c                     elements of which are the user provided break
+c                     points. if these points do not constitute an
+c                     ascending sequence there will be an automatic
+c                     sorting.
+c
+c            epsabs - real
+c                     absolute accuracy requested
+c            epsrel - real
+c                     relative accuracy requested
+c                     if  epsabs.le.0
+c                     and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c                     the routine will end with ier = 6.
+c
+c         on return
+c            result - real
+c                     approximation to the integral
+c
+c            abserr - real
+c                     estimate of the modulus of the absolute error,
+c                     which should equal or exceed abs(i-result)
+c
+c            neval  - integer
+c                     number of integrand evaluations
+c
+c            ier    - integer
+c                     ier = 0 normal and reliable termination of the
+c                             routine. it is assumed that the requested
+c                             accuracy has been achieved.
+c                     ier.gt.0 abnormal termination of the routine.
+c                             the estimates for integral and error are
+c                             less reliable. it is assumed that the
+c                             requested accuracy has not been achieved.
+c            error messages
+c                     ier = 1 maximum number of subdivisions allowed
+c                             has been achieved. one can allow more
+c                             subdivisions by increasing the value of
+c                             limit (and taking the according dimension
+c                             adjustments into account). however, if
+c                             this yields no improvement it is advised
+c                             to analyze the integrand in order to
+c                             determine the integration difficulties. if
+c                             the position of a local difficulty can be
+c                             determined (i.e. singularity,
+c                             discontinuity within the interval), it
+c                             should be supplied to the routine as an
+c                             element of the vector points. if necessary
+c                             an appropriate special-purpose integrator
+c                             must be used, which is designed for
+c                             handling the type of difficulty involved.
+c                         = 2 the occurrence of roundoff error is
+c                             detected, which prevents the requested
+c                             tolerance from being achieved.
+c                             the error may be under-estimated.
+c                         = 3 extremely bad integrand behaviour occurs
+c                             at some points of the integration
+c                             interval.
+c                         = 4 the algorithm does not converge.
+c                             roundoff error is detected in the
+c                             extrapolation table.
+c                             it is presumed that the requested
+c                             tolerance cannot be achieved, and that
+c                             the returned result is the best which
+c                             can be obtained.
+c                         = 5 the integral is probably divergent, or
+c                             slowly convergent. it must be noted that
+c                             divergence can occur with any other value
+c                             of ier.gt.0.
+c                         = 6 the input is invalid because
+c                             npts2.lt.2 or
+c                             break points are specified outside
+c                             the integration range or
+c                             (epsabs.le.0 and
+c                              epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
+c                             result, abserr, neval, last are set to
+c                             zero. exept when leniw or lenw or npts2 is
+c                             invalid, iwork(1), iwork(limit+1),
+c                             work(limit*2+1) and work(limit*3+1)
+c                             are set to zero.
+c                             work(1) is set to a and work(limit+1)
+c                             to b (where limit = (leniw-npts2)/2).
+c
+c         dimensioning parameters
+c            leniw - integer
+c                    dimensioning parameter for iwork
+c                    leniw determines limit = (leniw-npts2)/2,
+c                    which is the maximum number of subintervals in the
+c                    partition of the given integration interval (a,b),
+c                    leniw.ge.(3*npts2-2).
+c                    if leniw.lt.(3*npts2-2), the routine will end with
+c                    ier = 6.
+c
+c            lenw  - integer
+c                    dimensioning parameter for work
+c                    lenw must be at least leniw*2-npts2.
+c                    if lenw.lt.leniw*2-npts2, the routine will end
+c                    with ier = 6.
+c
+c            last  - integer
+c                    on return, last equals the number of subintervals
+c                    produced in the subdivision process, which
+c                    determines the number of significant elements
+c                    actually in the work arrays.
+c
+c         work arrays
+c            iwork - integer
+c                    vector of dimension at least leniw. on return,
+c                    the first k elements of which contain
+c                    pointers to the error estimates over the
+c                    subintervals, such that work(limit*3+iwork(1)),...,
+c                    work(limit*3+iwork(k)) form a decreasing
+c                    sequence, with k = last if last.le.(limit/2+2), and
+c                    k = limit+1-last otherwise
+c                    iwork(limit+1), ...,iwork(limit+last) contain the
+c                     subdivision levels of the subintervals, i.e.
+c                     if (aa,bb) is a subinterval of (p1,p2)
+c                     where p1 as well as p2 is a user-provided
+c                     break point or integration limit, then (aa,bb) has
+c                     level l if abs(bb-aa) = abs(p2-p1)*2**(-l),
+c                    iwork(limit*2+1), ..., iwork(limit*2+npts2) have
+c                     no significance for the user,
+c                    note that limit = (leniw-npts2)/2.
+c
+c            work  - real
+c                    vector of dimension at least lenw
+c                    on return
+c                    work(1), ..., work(last) contain the left
+c                     end points of the subintervals in the
+c                     partition of (a,b),
+c                    work(limit+1), ..., work(limit+last) contain
+c                     the right end points,
+c                    work(limit*2+1), ..., work(limit*2+last) contain
+c                     the integral approximations over the subintervals,
+c                    work(limit*3+1), ..., work(limit*3+last)
+c                     contain the corresponding error estimates,
+c                    work(limit*4+1), ..., work(limit*4+npts2)
+c                     contain the integration limits and the
+c                     break points sorted in an ascending sequence.
+c                    note that limit = (leniw-npts2)/2.
+c
+c***references  (none)
+c***routines called  qagpe,xerror
+c***end prologue  qagp
+c
+      real a,abserr,b,epsabs,epsrel,points,result,work
+      integer ier,iwork,leniw,lenw,limit,lvl,l1,l2,l3,neval,npts2
+c
+      dimension iwork(leniw),points(npts2),work(lenw)
+c
+      external f
+c
+c         check validity of limit and lenw.
+c
+c***first executable statement  qagp
+      ier = 6
+      neval = 0
+      last = 0
+      result = 0.0e+00
+      abserr = 0.0e+00
+      if(leniw.lt.(3*npts2-2).or.lenw.lt.(leniw*2-npts2).or.npts2.lt.2)
+     *  go to 10
+c
+c         prepare call for qagpe.
+c
+      limit = (leniw-npts2)/2
+      l1 = limit+1
+      l2 = limit+l1
+      l3 = limit+l2
+      l4 = limit+l3
+c
+      call qagpe(f,a,b,npts2,points,epsabs,epsrel,limit,result,abserr,
+     *  neval,ier,work(1),work(l1),work(l2),work(l3),work(l4),
+     *  iwork(1),iwork(l1),iwork(l2),last)
+c
+c         call error handler if necessary.
+c
+      lvl = 0
+10    if(ier.eq.6) lvl = 1
+      if(ier.ne.0) call xerror('abnormal return from  qagp',26,ier,lvl)
+      return
+      end
diff --git a/libcruft/quadpack/qagpe.f b/libcruft/quadpack/qagpe.f
new file mode 100644
index 0000000..54bd08c
--- /dev/null
+++ b/libcruft/quadpack/qagpe.f
@@ -0,0 +1,560 @@
+      subroutine qagpe(f,a,b,npts2,points,epsabs,epsrel,limit,result,
+     *   abserr,neval,ier,alist,blist,rlist,elist,pts,iord,level,ndin,
+     *   last)
+c***begin prologue  qagpe
+c***date written   800101   (yymmdd)
+c***revision date  830518   (yymmdd)
+c***category no.  h2a2a1
+c***keywords  automatic integrator, general-purpose,
+c             singularities at user specified points,
+c             extrapolation, globally adaptive.
+c***author  piessens,robert ,appl. math. & progr. div. - k.u.leuven
+c           de doncker,elise,appl. math. & progr. div. - k.u.leuven
+c***purpose  the routine calculates an approximation result to a given
+c            definite integral i = integral of f over (a,b),hopefully
+c            satisfying following claim for accuracy abs(i-result).le.
+c            max(epsabs,epsrel*abs(i)). break points of the integration
+c            interval, where local difficulties of the integrand may
+c            occur(e.g. singularities,discontinuities),provided by user.
+c***description
+c
+c        computation of a definite integral
+c        standard fortran subroutine
+c        real version
+c
+c        parameters
+c         on entry
+c            f      - subroutine f(x,ierr,result) defining the integrand
+c                     function f(x). the actual name for f needs to be
+c                     declared e x t e r n a l in the driver program.
+c
+c            a      - real
+c                     lower limit of integration
+c
+c            b      - real
+c                     upper limit of integration
+c
+c            npts2  - integer
+c                     number equal to two more than the number of
+c                     user-supplied break points within the integration
+c                     range, npts2.ge.2.
+c                     if npts2.lt.2, the routine will end with ier = 6.
+c
+c            points - real
+c                     vector of dimension npts2, the first (npts2-2)
+c                     elements of which are the user provided break
+c                     points. if these points do not constitute an
+c                     ascending sequence there will be an automatic
+c                     sorting.
+c
+c            epsabs - real
+c                     absolute accuracy requested
+c            epsrel - real
+c                     relative accuracy requested
+c                     if  epsabs.le.0
+c                     and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c                     the routine will end with ier = 6.
+c
+c            limit  - integer
+c                     gives an upper bound on the number of subintervals
+c                     in the partition of (a,b), limit.ge.npts2
+c                     if limit.lt.npts2, the routine will end with
+c                     ier = 6.
+c
+c         on return
+c            result - real
+c                     approximation to the integral
+c
+c            abserr - real
+c                     estimate of the modulus of the absolute error,
+c                     which should equal or exceed abs(i-result)
+c
+c            neval  - integer
+c                     number of integrand evaluations
+c
+c            ier    - integer
+c                     ier = 0 normal and reliable termination of the
+c                             routine. it is assumed that the requested
+c                             accuracy has been achieved.
+c                     ier.gt.0 abnormal termination of the routine.
+c                             the estimates for integral and error are
+c                             less reliable. it is assumed that the
+c                             requested accuracy has not been achieved.
+c            error messages
+c                     ier = 1 maximum number of subdivisions allowed
+c                             has been achieved. one can allow more
+c                             subdivisions by increasing the value of
+c                             limit (and taking the according dimension
+c                             adjustments into account). however, if
+c                             this yields no improvement it is advised
+c                             to analyze the integrand in order to
+c                             determine the integration difficulties. if
+c                             the position of a local difficulty can be
+c                             determined (i.e. singularity,
+c                             discontinuity within the interval), it
+c                             should be supplied to the routine as an
+c                             element of the vector points. if necessary
+c                             an appropriate special-purpose integrator
+c                             must be used, which is designed for
+c                             handling the type of difficulty involved.
+c                         = 2 the occurrence of roundoff error is
+c                             detected, which prevents the requested
+c                             tolerance from being achieved.
+c                             the error may be under-estimated.
+c                         = 3 extremely bad integrand behaviour occurs
+c                             at some points of the integration
+c                             interval.
+c                         = 4 the algorithm does not converge.
+c                             roundoff error is detected in the
+c                             extrapolation table. it is presumed that
+c                             the requested tolerance cannot be
+c                             achieved, and that the returned result is
+c                             the best which can be obtained.
+c                         = 5 the integral is probably divergent, or
+c                             slowly convergent. it must be noted that
+c                             divergence can occur with any other value
+c                             of ier.gt.0.
+c                         = 6 the input is invalid because
+c                             npts2.lt.2 or
+c                             break points are specified outside
+c                             the integration range or
+c                             (epsabs.le.0 and
+c                              epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
+c                             or limit.lt.npts2.
+c                             result, abserr, neval, last, rlist(1),
+c                             and elist(1) are set to zero. alist(1) and
+c                             blist(1) are set to a and b respectively.
+c
+c            alist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the left end points
+c                     of the subintervals in the partition of the given
+c                     integration range (a,b)
+c
+c            blist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the right end points
+c                     of the subintervals in the partition of the given
+c                     integration range (a,b)
+c
+c            rlist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the integral
+c                     approximations on the subintervals
+c
+c            elist  - real
+c                     vector of dimension at least limit, the first
+c                      last  elements of which are the moduli of the
+c                     absolute error estimates on the subintervals
+c
+c            pts    - real
+c                     vector of dimension at least npts2, containing the
+c                     integration limits and the break points of the
+c                     interval in ascending sequence.
+c
+c            level  - integer
+c                     vector of dimension at least limit, containing the
+c                     subdivision levels of the subinterval, i.e. if
+c                     (aa,bb) is a subinterval of (p1,p2) where p1 as
+c                     well as p2 is a user-provided break point or
+c                     integration limit, then (aa,bb) has level l if
+c                     abs(bb-aa) = abs(p2-p1)*2**(-l).
+c
+c            ndin   - integer
+c                     vector of dimension at least npts2, after first
+c                     integration over the intervals (pts(i)),pts(i+1),
+c                     i = 0,1, ..., npts2-2, the error estimates over
+c                     some of the intervals may have been increased
+c                     artificially, in order to put their subdivision
+c                     forward. if this happens for the subinterval
+c                     numbered k, ndin(k) is put to 1, otherwise
+c                     ndin(k) = 0.
+c
+c            iord   - integer
+c                     vector of dimension at least limit, the first k
+c                     elements of which are pointers to the
+c                     error estimates over the subintervals,
+c                     such that elist(iord(1)), ..., elist(iord(k))
+c                     form a decreasing sequence, with k = last
+c                     if last.le.(limit/2+2), and k = limit+1-last
+c                     otherwise
+c
+c            last   - integer
+c                     number of subintervals actually produced in the
+c                     subdivisions process
+c
+c***references  (none)
+c***routines called  qelg,qk21,qpsrt,r1mach
+c***end prologue  qagpe
+      real a,abseps,abserr,alist,area,area1,area12,area2,a1,
+     *  a2,b,blist,b1,b2,correc,defabs,defab1,defab2,
+     *  dres,r1mach,elist,epmach,epsabs,epsrel,erlarg,erlast,errbnd,
+     *  errmax,error1,erro12,error2,errsum,ertest,oflow,points,pts,
+     *  resa,resabs,reseps,result,res3la,rlist,rlist2,sign,temp,
+     *  uflow
+      integer i,id,ier,ierro,ind1,ind2,iord,ip1,iroff1,iroff2,
+     *  iroff3,j,jlow,jupbnd,k,ksgn,ktmin,last,levcur,level,levmax,
+     *  limit,maxerr,ndin,neval,nint,nintp1,npts,npts2,nres,
+     *  nrmax,numrl2
+      logical extrap,noext
+c
+c
+      dimension alist(limit),blist(limit),elist(limit),iord(limit),
+     *  level(limit),ndin(npts2),points(npts2),pts(npts2),res3la(3),
+     *  rlist(limit),rlist2(52)
+c
+      external f
+c
+c            the dimension of rlist2 is determined by the value of
+c            limexp in subroutine epsalg (rlist2 should be of dimension
+c            (limexp+2) at least).
+c
+c
+c            list of major variables
+c            -----------------------
+c
+c           alist     - list of left end points of all subintervals
+c                       considered up to now
+c           blist     - list of right end points of all subintervals
+c                       considered up to now
+c           rlist(i)  - approximation to the integral over
+c                       (alist(i),blist(i))
+c           rlist2    - array of dimension at least limexp+2
+c                       containing the part of the epsilon table which
+c                       is still needed for further computations
+c           elist(i)  - error estimate applying to rlist(i)
+c           maxerr    - pointer to the interval with largest error
+c                       estimate
+c           errmax    - elist(maxerr)
+c           erlast    - error on the interval currently subdivided
+c                       (before that subdivision has taken place)
+c           area      - sum of the integrals over the subintervals
+c           errsum    - sum of the errors over the subintervals
+c           errbnd    - requested accuracy max(epsabs,epsrel*
+c                       abs(result))
+c           *****1    - variable for the left subinterval
+c           *****2    - variable for the right subinterval
+c           last      - index for subdivision
+c           nres      - number of calls to the extrapolation routine
+c           numrl2    - number of elements in rlist2. if an
+c                       appropriate approximation to the compounded
+c                       integral has been obtained, it is put in
+c                       rlist2(numrl2) after numrl2 has been increased
+c                       by one.
+c           erlarg    - sum of the errors over the intervals larger
+c                       than the smallest interval considered up to now
+c           extrap    - logical variable denoting that the routine
+c                       is attempting to perform extrapolation. i.e.
+c                       before subdividing the smallest interval we
+c                       try to decrease the value of erlarg.
+c           noext     - logical variable denoting that extrapolation is
+c                       no longer allowed (true-value)
+c
+c            machine dependent constants
+c            ---------------------------
+c
+c           epmach is the largest relative spacing.
+c           uflow is the smallest positive magnitude.
+c           oflow is the largest positive magnitude.
+c
+c***first executable statement  qagpe
+      epmach = r1mach(4)
+c
+c            test on validity of parameters
+c            -----------------------------
+c
+      ier = 0
+      neval = 0
+      last = 0
+      result = 0.0e+00
+      abserr = 0.0e+00
+      alist(1) = a
+      blist(1) = b
+      rlist(1) = 0.0e+00
+      elist(1) = 0.0e+00
+      iord(1) = 0
+      level(1) = 0
+      npts = npts2-2
+      if(npts2.lt.2.or.limit.le.npts.or.(epsabs.le.0.0e+00.and.
+     *  epsrel.lt.amax1(0.5e+02*epmach,0.5e-14))) ier = 6
+      if(ier.eq.6) go to 210
+c
+c            if any break points are provided, sort them into an
+c            ascending sequence.
+c
+      sign = 1.0e+00
+      if(a.gt.b) sign = -1.0e+00
+      pts(1) = amin1(a,b)
+      if(npts.eq.0) go to 15
+      do 10 i = 1,npts
+        pts(i+1) = points(i)
+   10 continue
+   15 pts(npts+2) = amax1(a,b)
+      nint = npts+1
+      a1 = pts(1)
+      if(npts.eq.0) go to 40
+      nintp1 = nint+1
+      do 20 i = 1,nint
+        ip1 = i+1
+        do 20 j = ip1,nintp1
+          if(pts(i).le.pts(j)) go to 20
+          temp = pts(i)
+          pts(i) = pts(j)
+          pts(j) = temp
+   20 continue
+      if(pts(1).ne.amin1(a,b).or.pts(nintp1).ne.
+     *  amax1(a,b)) ier = 6
+      if(ier.eq.6) go to 999
+c
+c            compute first integral and error approximations.
+c            ------------------------------------------------
+c
+   40 resabs = 0.0e+00
+      do 50 i = 1,nint
+        b1 = pts(i+1)
+        call qk21(f,a1,b1,area1,error1,defabs,resa,ier)
+        if (ier.lt.0) return
+        abserr = abserr+error1
+        result = result+area1
+        ndin(i) = 0
+        if(error1.eq.resa.and.error1.ne.0.0e+00) ndin(i) = 1
+        resabs = resabs+defabs
+        level(i) = 0
+        elist(i) = error1
+        alist(i) = a1
+        blist(i) = b1
+        rlist(i) = area1
+        iord(i) = i
+        a1 = b1
+   50 continue
+      errsum = 0.0e+00
+      do 55 i = 1,nint
+        if(ndin(i).eq.1) elist(i) = abserr
+        errsum = errsum+elist(i)
+   55 continue
+c
+c           test on accuracy.
+c
+      last = nint
+      neval = 21*nint
+      dres = abs(result)
+      errbnd = amax1(epsabs,epsrel*dres)
+      if(abserr.le.0.1e+03*epmach*resabs.and.abserr.gt.
+     *  errbnd) ier = 2
+      if(nint.eq.1) go to 80
+      do 70 i = 1,npts
+        jlow = i+1
+        ind1 = iord(i)
+        do 60 j = jlow,nint
+          ind2 = iord(j)
+          if(elist(ind1).gt.elist(ind2)) go to 60
+          ind1 = ind2
+          k = j
+   60   continue
+        if(ind1.eq.iord(i)) go to 70
+        iord(k) = iord(i)
+        iord(i) = ind1
+   70 continue
+      if(limit.lt.npts2) ier = 1
+   80 if(ier.ne.0.or.abserr.le.errbnd) go to 999
+c
+c           initialization
+c           --------------
+c
+      rlist2(1) = result
+      maxerr = iord(1)
+      errmax = elist(maxerr)
+      area = result
+      nrmax = 1
+      nres = 0
+      numrl2 = 1
+      ktmin = 0
+      extrap = .false.
+      noext = .false.
+      erlarg = errsum
+      ertest = errbnd
+      levmax = 1
+      iroff1 = 0
+      iroff2 = 0
+      iroff3 = 0
+      ierro = 0
+      uflow = r1mach(1)
+      oflow = r1mach(2)
+      abserr = oflow
+      ksgn = -1
+      if(dres.ge.(0.1e+01-0.5e+02*epmach)*resabs) ksgn = 1
+c
+c           main do-loop
+c           ------------
+c
+      do 160 last = npts2,limit
+c
+c           bisect the subinterval with the nrmax-th largest
+c           error estimate.
+c
+        levcur = level(maxerr)+1
+        a1 = alist(maxerr)
+        b1 = 0.5e+00*(alist(maxerr)+blist(maxerr))
+        a2 = b1
+        b2 = blist(maxerr)
+        erlast = errmax
+        call qk21(f,a1,b1,area1,error1,resa,defab1,ier)
+        if (ier.lt.0) return
+        call qk21(f,a2,b2,area2,error2,resa,defab2,ier)
+        if (ier.lt.0) return
+c
+c           improve previous approximations to integral
+c           and error and test for accuracy.
+c
+        neval = neval+42
+        area12 = area1+area2
+        erro12 = error1+error2
+        errsum = errsum+erro12-errmax
+        area = area+area12-rlist(maxerr)
+        if(defab1.eq.error1.or.defab2.eq.error2) go to 95
+        if(abs(rlist(maxerr)-area12).gt.0.1e-04*abs(area12)
+     *  .or.erro12.lt.0.99e+00*errmax) go to 90
+        if(extrap) iroff2 = iroff2+1
+        if(.not.extrap) iroff1 = iroff1+1
+   90   if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
+   95   level(maxerr) = levcur
+        level(last) = levcur
+        rlist(maxerr) = area1
+        rlist(last) = area2
+        errbnd = amax1(epsabs,epsrel*abs(area))
+c
+c           test for roundoff error and eventually
+c           set error flag.
+c
+        if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
+        if(iroff2.ge.5) ierro = 3
+c
+c           set error flag in the case that the number of
+c           subintervals equals limit.
+c
+        if(last.eq.limit) ier = 1
+c
+c           set error flag in the case of bad integrand behaviour
+c           at a point of the integration range
+c
+        if(amax1(abs(a1),abs(b2)).le.(0.1e+01+0.1e+03*epmach)*
+     *  (abs(a2)+0.1e+04*uflow)) ier = 4
+c
+c           append the newly-created intervals to the list.
+c
+        if(error2.gt.error1) go to 100
+        alist(last) = a2
+        blist(maxerr) = b1
+        blist(last) = b2
+        elist(maxerr) = error1
+        elist(last) = error2
+        go to 110
+  100   alist(maxerr) = a2
+        alist(last) = a1
+        blist(last) = b1
+        rlist(maxerr) = area2
+        rlist(last) = area1
+        elist(maxerr) = error2
+        elist(last) = error1
+c
+c           call subroutine qpsrt to maintain the descending ordering
+c           in the list of error estimates and select the
+c           subinterval with nrmax-th largest error estimate (to be
+c           bisected next).
+c
+  110   call qpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
+c ***jump out of do-loop
+        if(errsum.le.errbnd) go to 190
+c ***jump out of do-loop
+        if(ier.ne.0) go to 170
+        if(noext) go to 160
+        erlarg = erlarg-erlast
+        if(levcur+1.le.levmax) erlarg = erlarg+erro12
+        if(extrap) go to 120
+c
+c           test whether the interval to be bisected next is the
+c           smallest interval.
+c
+        if(level(maxerr)+1.le.levmax) go to 160
+        extrap = .true.
+        nrmax = 2
+  120   if(ierro.eq.3.or.erlarg.le.ertest) go to 140
+c
+c           the smallest interval has the largest error.
+c           before bisecting decrease the sum of the errors
+c           over the larger intervals (erlarg) and perform
+c           extrapolation.
+c
+        id = nrmax
+        jupbnd = last
+        if(last.gt.(2+limit/2)) jupbnd = limit+3-last
+        do 130 k = id,jupbnd
+          maxerr = iord(nrmax)
+          errmax = elist(maxerr)
+c ***jump out of do-loop
+          if(level(maxerr)+1.le.levmax) go to 160
+          nrmax = nrmax+1
+  130   continue
+c
+c           perform extrapolation.
+c
+  140   numrl2 = numrl2+1
+        rlist2(numrl2) = area
+        if(numrl2.le.2) go to 155
+        call qelg(numrl2,rlist2,reseps,abseps,res3la,nres)
+        ktmin = ktmin+1
+        if(ktmin.gt.5.and.abserr.lt.0.1e-02*errsum) ier = 5
+        if(abseps.ge.abserr) go to 150
+        ktmin = 0
+        abserr = abseps
+        result = reseps
+        correc = erlarg
+        ertest = amax1(epsabs,epsrel*abs(reseps))
+c ***jump out of do-loop
+        if(abserr.lt.ertest) go to 170
+c
+c           prepare bisection of the smallest interval.
+c
+  150   if(numrl2.eq.1) noext = .true.
+        if(ier.ge.5) go to 170
+  155   maxerr = iord(1)
+        errmax = elist(maxerr)
+        nrmax = 1
+        extrap = .false.
+        levmax = levmax+1
+        erlarg = errsum
+  160 continue
+c
+c           set the final result.
+c           ---------------------
+c
+c
+  170 if(abserr.eq.oflow) go to 190
+      if((ier+ierro).eq.0) go to 180
+      if(ierro.eq.3) abserr = abserr+correc
+      if(ier.eq.0) ier = 3
+      if(result.ne.0.0e+00.and.area.ne.0.0e+00)go to 175
+      if(abserr.gt.errsum)go to 190
+      if(area.eq.0.0e+00) go to 210
+      go to 180
+  175 if(abserr/abs(result).gt.errsum/abs(area))go to 190
+c
+c           test on divergence.
+c
+  180 if(ksgn.eq.(-1).and.amax1(abs(result),abs(area)).le.
+     *  resabs*0.1e-01) go to 210
+      if(0.1e-01.gt.(result/area).or.(result/area).gt.0.1e+03.or.
+     *  errsum.gt.abs(area)) ier = 6
+      go to 210
+c
+c           compute global integral sum.
+c
+  190 result = 0.0e+00
+      do 200 k = 1,last
+        result = result+rlist(k)
+  200 continue
+      abserr = errsum
+  210 if(ier.gt.2) ier = ier - 1
+      result = result*sign
+ 999  return
+      end
diff --git a/libcruft/quadpack/qelg.f b/libcruft/quadpack/qelg.f
new file mode 100644
index 0000000..3263526
--- /dev/null
+++ b/libcruft/quadpack/qelg.f
@@ -0,0 +1,184 @@
+      subroutine qelg(n,epstab,result,abserr,res3la,nres)
+c***begin prologue  qelg
+c***refer to  qagie,qagoe,qagpe,qagse
+c***routines called  r1mach
+c***revision date  830518   (yymmdd)
+c***keywords  epsilon algorithm, convergence acceleration,
+c             extrapolation
+c***author  piessens,robert,appl. math. & progr. div. - k.u.leuven
+c           de doncker,elise,appl. math & progr. div. - k.u.leuven
+c***purpose  the routine determines the limit of a given sequence of
+c            approximations, by means of the epsilon algorithm of
+c            p. wynn. an estimate of the absolute error is also given.
+c            the condensed epsilon table is computed. only those
+c            elements needed for the computation of the next diagonal
+c            are preserved.
+c***description
+c
+c           epsilon algorithm
+c           standard fortran subroutine
+c           real version
+c
+c           parameters
+c              n      - integer
+c                       epstab(n) contains the new element in the
+c                       first column of the epsilon table.
+c
+c              epstab - real
+c                       vector of dimension 52 containing the elements
+c                       of the two lower diagonals of the triangular
+c                       epsilon table. the elements are numbered
+c                       starting at the right-hand corner of the
+c                       triangle.
+c
+c              result - real
+c                       resulting approximation to the integral
+c
+c              abserr - real
+c                       estimate of the absolute error computed from
+c                       result and the 3 previous results
+c
+c              res3la - real
+c                       vector of dimension 3 containing the last 3
+c                       results
+c
+c              nres   - integer
+c                       number of calls to the routine
+c                       (should be zero at first call)
+c
+c***end prologue  qelg
+c
+      real abserr,delta1,delta2,delta3,r1mach,
+     *  epmach,epsinf,epstab,error,err1,err2,err3,e0,e1,e1abs,e2,e3,
+     *  oflow,res,result,res3la,ss,tol1,tol2,tol3
+      integer i,ib,ib2,ie,indx,k1,k2,k3,limexp,n,newelm,nres,num
+      dimension epstab(52),res3la(3)
+c
+c           list of major variables
+c           -----------------------
+c
+c           e0     - the 4 elements on which the
+c           e1       computation of a new element in
+c           e2       the epsilon table is based
+c           e3                 e0
+c                        e3    e1    new
+c                              e2
+c           newelm - number of elements to be computed in the new
+c                    diagonal
+c           error  - error = abs(e1-e0)+abs(e2-e1)+abs(new-e2)
+c           result - the element in the new diagonal with least value
+c                    of error
+c
+c           machine dependent constants
+c           ---------------------------
+c
+c           epmach is the largest relative spacing.
+c           oflow is the largest positive magnitude.
+c           limexp is the maximum number of elements the epsilon
+c           table can contain. if this number is reached, the upper
+c           diagonal of the epsilon table is deleted.
+c
+c***first executable statement  qelg
+      epmach = r1mach(4)
+      oflow = r1mach(2)
+      nres = nres+1
+      abserr = oflow
+      result = epstab(n)
+      if(n.lt.3) go to 100
+      limexp = 50
+      epstab(n+2) = epstab(n)
+      newelm = (n-1)/2
+      epstab(n) = oflow
+      num = n
+      k1 = n
+      do 40 i = 1,newelm
+        k2 = k1-1
+        k3 = k1-2
+        res = epstab(k1+2)
+        e0 = epstab(k3)
+        e1 = epstab(k2)
+        e2 = res
+        e1abs = abs(e1)
+        delta2 = e2-e1
+        err2 = abs(delta2)
+        tol2 = amax1(abs(e2),e1abs)*epmach
+        delta3 = e1-e0
+        err3 = abs(delta3)
+        tol3 = amax1(e1abs,abs(e0))*epmach
+        if(err2.gt.tol2.or.err3.gt.tol3) go to 10
+c
+c           if e0, e1 and e2 are equal to within machine
+c           accuracy, convergence is assumed.
+c           result = e2
+c           abserr = abs(e1-e0)+abs(e2-e1)
+c
+        result = res
+        abserr = err2+err3
+c ***jump out of do-loop
+        go to 100
+   10   e3 = epstab(k1)
+        epstab(k1) = e1
+        delta1 = e1-e3
+        err1 = abs(delta1)
+        tol1 = amax1(e1abs,abs(e3))*epmach
+c
+c           if two elements are very close to each other, omit
+c           a part of the table by adjusting the value of n
+c
+        if(err1.le.tol1.or.err2.le.tol2.or.err3.le.tol3) go to 20
+        ss = 0.1e+01/delta1+0.1e+01/delta2-0.1e+01/delta3
+        epsinf = abs(ss*e1)
+c
+c           test to detect irregular behaviour in the table, and
+c           eventually omit a part of the table adjusting the value
+c           of n.
+c
+        if(epsinf.gt.0.1e-03) go to 30
+   20   n = i+i-1
+c ***jump out of do-loop
+        go to 50
+c
+c           compute a new element and eventually adjust
+c           the value of result.
+c
+   30   res = e1+0.1e+01/ss
+        epstab(k1) = res
+        k1 = k1-2
+        error = err2+abs(res-e2)+err3
+        if(error.gt.abserr) go to 40
+        abserr = error
+        result = res
+   40 continue
+c
+c           shift the table.
+c
+   50 if(n.eq.limexp) n = 2*(limexp/2)-1
+      ib = 1
+      if((num/2)*2.eq.num) ib = 2
+      ie = newelm+1
+      do 60 i=1,ie
+        ib2 = ib+2
+        epstab(ib) = epstab(ib2)
+        ib = ib2
+   60 continue
+      if(num.eq.n) go to 80
+      indx = num-n+1
+      do 70 i = 1,n
+        epstab(i)= epstab(indx)
+        indx = indx+1
+   70 continue
+   80 if(nres.ge.4) go to 90
+      res3la(nres) = result
+      abserr = oflow
+      go to 100
+c
+c           compute error estimate
+c
+   90 abserr = abs(result-res3la(3))+abs(result-res3la(2))
+     *  +abs(result-res3la(1))
+      res3la(1) = res3la(2)
+      res3la(2) = res3la(3)
+      res3la(3) = result
+  100 abserr = amax1(abserr,0.5e+01*epmach*abs(result))
+      return
+      end
diff --git a/libcruft/quadpack/qk15i.f b/libcruft/quadpack/qk15i.f
new file mode 100644
index 0000000..f8dd7f1
--- /dev/null
+++ b/libcruft/quadpack/qk15i.f
@@ -0,0 +1,202 @@
+      subroutine qk15i(f,boun,inf,a,b,result,abserr,resabs,resasc,ierr)
+c***begin prologue  qk15i
+c***date written   800101   (yymmdd)
+c***revision date  830518   (yymmdd)
+c***category no.  h2a3a2,h2a4a2
+c***keywords  15-point transformed gauss-kronrod rules
+c***author  piessens,robert,appl. math. & progr. div. - k.u.leuven
+c           de doncker,elise,appl. math. & progr. div. - k.u.leuven
+c***purpose  the original (infinite integration range is mapped
+c            onto the interval (0,1) and (a,b) is a part of (0,1).
+c            it is the purpose to compute
+c            i = integral of transformed integrand over (a,b),
+c            j = integral of abs(transformed integrand) over (a,b).
+c***description
+c
+c           integration rule
+c           standard fortran subroutine
+c           real version
+c
+c           parameters
+c            on entry
+c              f      - subroutine f(x,ierr,result) defining the integrand
+c                       function f(x). the actual name for f needs to be
+c                       declared e x t e r n a l in the calling program.
+c
+c              boun   - real
+c                       finite bound of original integration
+c                       range (set to zero if inf = +2)
+c
+c              inf    - integer
+c                       if inf = -1, the original interval is
+c                                   (-infinity,bound),
+c                       if inf = +1, the original interval is
+c                                   (bound,+infinity),
+c                       if inf = +2, the original interval is
+c                                   (-infinity,+infinity) and
+c                       the integral is computed as the sum of two
+c                       integrals, one over (-infinity,0) and one over
+c                       (0,+infinity).
+c
+c              a      - real
+c                       lower limit for integration over subrange
+c                       of (0,1)
+c
+c              b      - real
+c                       upper limit for integration over subrange
+c                       of (0,1)
+c
+c            on return
+c              result - real
+c                       approximation to the integral i
+c                       result is computed by applying the 15-point
+c                       kronrod rule(resk) obtained by optimal addition
+c                       of abscissae to the 7-point gauss rule(resg).
+c
+c              abserr - real
+c                       estimate of the modulus of the absolute error,
+c                       which should equal or exceed abs(i-result)
+c
+c              resabs - real
+c                       approximation to the integral j
+c
+c              resasc - real
+c                       approximation to the integral of
+c                       abs((transformed integrand)-i/(b-a)) over (a,b)
+c
+c***references  (none)
+c***routines called  r1mach
+c***end prologue  qk15i
+c
+      real a,absc,absc1,absc2,abserr,b,boun,centr,
+     *  dinf,r1mach,epmach,fc,fsum,fval1,fval2,fvalt,fv1,
+     *  fv2,hlgth,resabs,resasc,resg,resk,reskh,result,tabsc1,tabsc2,
+     *  uflow,wg,wgk,xgk
+      integer inf,j,min0
+      external f
+c
+      dimension fv1(7),fv2(7),xgk(8),wgk(8),wg(8)
+c
+c           the abscissae and weights are supplied for the interval
+c           (-1,1).  because of symmetry only the positive abscissae and
+c           their corresponding weights are given.
+c
+c           xgk    - abscissae of the 15-point kronrod rule
+c                    xgk(2), xgk(4), ... abscissae of the 7-point
+c                    gauss rule
+c                    xgk(1), xgk(3), ...  abscissae which are optimally
+c                    added to the 7-point gauss rule
+c
+c           wgk    - weights of the 15-point kronrod rule
+c
+c           wg     - weights of the 7-point gauss rule, corresponding
+c                    to the abscissae xgk(2), xgk(4), ...
+c                    wg(1), wg(3), ... are set to zero.
+c
+      data xgk(1),xgk(2),xgk(3),xgk(4),xgk(5),xgk(6),xgk(7),
+     *  xgk(8)/
+     *     0.9914553711208126e+00,     0.9491079123427585e+00,
+     *     0.8648644233597691e+00,     0.7415311855993944e+00,
+     *     0.5860872354676911e+00,     0.4058451513773972e+00,
+     *     0.2077849550078985e+00,     0.0000000000000000e+00/
+c
+      data wgk(1),wgk(2),wgk(3),wgk(4),wgk(5),wgk(6),wgk(7),
+     *  wgk(8)/
+     *     0.2293532201052922e-01,     0.6309209262997855e-01,
+     *     0.1047900103222502e+00,     0.1406532597155259e+00,
+     *     0.1690047266392679e+00,     0.1903505780647854e+00,
+     *     0.2044329400752989e+00,     0.2094821410847278e+00/
+c
+      data wg(1),wg(2),wg(3),wg(4),wg(5),wg(6),wg(7),wg(8)/
+     *     0.0000000000000000e+00,     0.1294849661688697e+00,
+     *     0.0000000000000000e+00,     0.2797053914892767e+00,
+     *     0.0000000000000000e+00,     0.3818300505051189e+00,
+     *     0.0000000000000000e+00,     0.4179591836734694e+00/
+c
+c
+c           list of major variables
+c           -----------------------
+c
+c           centr  - mid point of the interval
+c           hlgth  - half-length of the interval
+c           absc*  - abscissa
+c           tabsc* - transformed abscissa
+c           fval*  - function value
+c           resg   - result of the 7-point gauss formula
+c           resk   - result of the 15-point kronrod formula
+c           reskh  - approximation to the mean value of the transformed
+c                    integrand over (a,b), i.e. to i/(b-a)
+c
+c           machine dependent constants
+c           ---------------------------
+c
+c           epmach is the largest relative spacing.
+c           uflow is the smallest positive magnitude.
+c
+c***first executable statement  qk15i
+      epmach = r1mach(4)
+      uflow = r1mach(1)
+      dinf = min0(1,inf)
+c
+      centr = 0.5e+00*(a+b)
+      hlgth = 0.5e+00*(b-a)
+      tabsc1 = boun+dinf*(0.1e+01-centr)/centr
+      call f(tabsc1, ierr, fval1)
+      if (ierr.lt.0) return
+      if(inf.eq.2) then
+         call f(-tabsc1, ierr, fval1)
+         if (ierr.lt.0) return
+         fval1 = fval1 + fvalt
+      endif
+      fc = (fval1/centr)/centr
+c
+c           compute the 15-point kronrod approximation to
+c           the integral, and estimate the error.
+c
+      resg = wg(8)*fc
+      resk = wgk(8)*fc
+      resabs = abs(resk)
+      do 10 j=1,7
+        absc = hlgth*xgk(j)
+        absc1 = centr-absc
+        absc2 = centr+absc
+        tabsc1 = boun+dinf*(0.1e+01-absc1)/absc1
+        tabsc2 = boun+dinf*(0.1e+01-absc2)/absc2
+        call f(tabsc1, ierr, fval1)
+        if (ierr.lt.0) return
+        call f(tabsc2, ierr, fval2)
+        if (ierr.lt.0) return
+        if(inf.eq.2) then
+           call f(-tabsc1,ierr,fvalt)
+           if (ierr.lt.0) return
+           fval1 = fval1 + fvalt
+        endif
+        if(inf.eq.2) then
+           call f(-tabsc2,ierr,fvalt)
+           if (ierr.lt.0) return
+           fval2 = fval2 + fvalt
+        endif
+        fval1 = (fval1/absc1)/absc1
+        fval2 = (fval2/absc2)/absc2
+        fv1(j) = fval1
+        fv2(j) = fval2
+        fsum = fval1+fval2
+        resg = resg+wg(j)*fsum
+        resk = resk+wgk(j)*fsum
+        resabs = resabs+wgk(j)*(abs(fval1)+abs(fval2))
+   10 continue
+      reskh = resk*0.5e+00
+      resasc = wgk(8)*abs(fc-reskh)
+      do 20 j=1,7
+        resasc = resasc+wgk(j)*(abs(fv1(j)-reskh)+abs(fv2(j)-reskh))
+   20 continue
+      result = resk*hlgth
+      resasc = resasc*hlgth
+      resabs = resabs*hlgth
+      abserr = abs((resk-resg)*hlgth)
+      if(resasc.ne.0.0e+00.and.abserr.ne.0.e0) abserr = resasc*
+     * amin1(0.1e+01,(0.2e+03*abserr/resasc)**1.5e+00)
+      if(resabs.gt.uflow/(0.5e+02*epmach)) abserr = amax1
+     * ((epmach*0.5e+02)*resabs,abserr)
+      return
+      end
diff --git a/libcruft/quadpack/qk21.f b/libcruft/quadpack/qk21.f
new file mode 100644
index 0000000..7204c70
--- /dev/null
+++ b/libcruft/quadpack/qk21.f
@@ -0,0 +1,175 @@
+      subroutine qk21(f,a,b,result,abserr,resabs,resasc,ierr)
+c***begin prologue  qk21
+c***date written   800101   (yymmdd)
+c***revision date  830518   (yymmdd)
+c***category no.  h2a1a2
+c***keywords  21-point gauss-kronrod rules
+c***author  piessens,robert,appl. math. & progr. div. - k.u.leuven
+c           de doncker,elise,appl. math. & progr. div. - k.u.leuven
+c***purpose  to compute i = integral of f over (a,b), with error
+c                           estimate
+c                       j = integral of abs(f) over (a,b)
+c***description
+c
+c           integration rules
+c           standard fortran subroutine
+c           real version
+c
+c           parameters
+c            on entry
+c              f      - subroutine f(x,ierr,result) defining the integrand
+c                       function f(x). the actual name for f needs to be
+c                       declared e x t e r n a l in the driver program.
+c
+c              a      - real
+c                       lower limit of integration
+c
+c              b      - real
+c                       upper limit of integration
+c
+c            on return
+c              result - real
+c                       approximation to the integral i
+c                       result is computed by applying the 21-point
+c                       kronrod rule (resk) obtained by optimal addition
+c                       of abscissae to the 10-point gauss rule (resg).
+c
+c              abserr - real
+c                       estimate of the modulus of the absolute error,
+c                       which should not exceed abs(i-result)
+c
+c              resabs - real
+c                       approximation to the integral j
+c
+c              resasc - real
+c                       approximation to the integral of abs(f-i/(b-a))
+c                       over (a,b)
+c
+c***references  (none)
+c***routines called  r1mach
+c***end prologue  qk21
+c
+      real a,absc,abserr,b,centr,dhlgth,epmach,fc,fsum,fval1,fval2,
+     *  fv1,fv2,hlgth,resabs,resg,resk,reskh,result,r1mach,uflow,wg,wgk,
+     *  xgk
+      integer j,jtw,jtwm1
+      external f
+c
+      dimension fv1(10),fv2(10),wg(5),wgk(11),xgk(11)
+c
+c           the abscissae and weights are given for the interval (-1,1).
+c           because of symmetry only the positive abscissae and their
+c           corresponding weights are given.
+c
+c           xgk    - abscissae of the 21-point kronrod rule
+c                    xgk(2), xgk(4), ...  abscissae of the 10-point
+c                    gauss rule
+c                    xgk(1), xgk(3), ...  abscissae which are optimally
+c                    added to the 10-point gauss rule
+c
+c           wgk    - weights of the 21-point kronrod rule
+c
+c           wg     - weights of the 10-point gauss rule
+c
+      data xgk(1),xgk(2),xgk(3),xgk(4),xgk(5),xgk(6),xgk(7),
+     *  xgk(8),xgk(9),xgk(10),xgk(11)/
+     *         0.9956571630258081e+00,     0.9739065285171717e+00,
+     *     0.9301574913557082e+00,     0.8650633666889845e+00,
+     *     0.7808177265864169e+00,     0.6794095682990244e+00,
+     *     0.5627571346686047e+00,     0.4333953941292472e+00,
+     *     0.2943928627014602e+00,     0.1488743389816312e+00,
+     *     0.0000000000000000e+00/
+c
+      data wgk(1),wgk(2),wgk(3),wgk(4),wgk(5),wgk(6),wgk(7),
+     *  wgk(8),wgk(9),wgk(10),wgk(11)/
+     *     0.1169463886737187e-01,     0.3255816230796473e-01,
+     *     0.5475589657435200e-01,     0.7503967481091995e-01,
+     *     0.9312545458369761e-01,     0.1093871588022976e+00,
+     *     0.1234919762620659e+00,     0.1347092173114733e+00,
+     *     0.1427759385770601e+00,     0.1477391049013385e+00,
+     *     0.1494455540029169e+00/
+c
+      data wg(1),wg(2),wg(3),wg(4),wg(5)/
+     *     0.6667134430868814e-01,     0.1494513491505806e+00,
+     *     0.2190863625159820e+00,     0.2692667193099964e+00,
+     *     0.2955242247147529e+00/
+c
+c
+c           list of major variables
+c           -----------------------
+c
+c           centr  - mid point of the interval
+c           hlgth  - half-length of the interval
+c           absc   - abscissa
+c           fval*  - function value
+c           resg   - result of the 10-point gauss formula
+c           resk   - result of the 21-point kronrod formula
+c           reskh  - approximation to the mean value of f over (a,b),
+c                    i.e. to i/(b-a)
+c
+c
+c           machine dependent constants
+c           ---------------------------
+c
+c           epmach is the largest relative spacing.
+c           uflow is the smallest positive magnitude.
+c
+c***first executable statement  qk21
+      epmach = r1mach(4)
+      uflow = r1mach(1)
+c
+      centr = 0.5e+00*(a+b)
+      hlgth = 0.5e+00*(b-a)
+      dhlgth = abs(hlgth)
+c
+c           compute the 21-point kronrod approximation to
+c           the integral, and estimate the absolute error.
+c
+      resg = 0.0e+00
+      call f(centr, ierr, fc)
+      if (ierr .lt. 0) return
+      resk = wgk(11)*fc
+      resabs = abs(resk)
+      do 10 j=1,5
+        jtw = 2*j
+        absc = hlgth*xgk(jtw)
+        call f(centr-absc,ierr,fval1)
+        if (ierr .lt. 0) return
+        call f(centr+absc,ierr,fval2)
+        if (ierr .lt. 0) return
+        fv1(jtw) = fval1
+        fv2(jtw) = fval2
+        fsum = fval1+fval2
+        resg = resg+wg(j)*fsum
+        resk = resk+wgk(jtw)*fsum
+        resabs = resabs+wgk(jtw)*(abs(fval1)+abs(fval2))
+   10 continue
+      do 15 j = 1,5
+        jtwm1 = 2*j-1
+        absc = hlgth*xgk(jtwm1)
+        call f(centr-absc,ierr,fval1)
+        if (ierr .lt. 0) return
+        call f(centr+absc,ierr,fval2)
+        if (ierr .lt. 0) return
+        fv1(jtwm1) = fval1
+        fv2(jtwm1) = fval2
+        fsum = fval1+fval2
+        resk = resk+wgk(jtwm1)*fsum
+        resabs = resabs+wgk(jtwm1)*(abs(fval1)+abs(fval2))
+   15 continue
+      reskh = resk*0.5e+00
+      resasc = wgk(11)*abs(fc-reskh)
+      do 20 j=1,10
+        resasc = resasc+wgk(j)*(abs(fv1(j)-reskh)+abs(fv2(j)-reskh))
+   20 continue
+      result = resk*hlgth
+      resabs = resabs*dhlgth
+      resasc = resasc*dhlgth
+      abserr = abs((resk-resg)*hlgth)
+      if(resasc.ne.0.0e+00.and.abserr.ne.0.0e+00)
+     *  abserr = resasc*amin1(0.1e+01,
+     *  (0.2e+03*abserr/resasc)**1.5e+00)
+      if(resabs.gt.uflow/(0.5e+02*epmach)) abserr = amax1
+     *  ((epmach*0.5e+02)*resabs,abserr)
+      return
+      end
diff --git a/libcruft/quadpack/qpsrt.f b/libcruft/quadpack/qpsrt.f
new file mode 100644
index 0000000..b5779ea
--- /dev/null
+++ b/libcruft/quadpack/qpsrt.f
@@ -0,0 +1,136 @@
+      subroutine qpsrt(limit,last,maxerr,ermax,elist,iord,nrmax)
+c***begin prologue  qpsrt
+c***refer to  qage,qagie,qagpe,qagse,qawce,qawse,qawoe
+c***routines called  (none)
+c***keywords  sequential sorting
+c***description
+c
+c 1.        qpsrt
+c           ordering routine
+c              standard fortran subroutine
+c              real version
+c
+c 2.        purpose
+c              this routine maintains the descending ordering
+c              in the list of the local error estimates resulting from
+c              the interval subdivision process. at each call two error
+c              estimates are inserted using the sequential search
+c              method, top-down for the largest error estimate
+c              and bottom-up for the smallest error estimate.
+c
+c 3.        calling sequence
+c              call qpsrt(limit,last,maxerr,ermax,elist,iord,nrmax)
+c
+c           parameters (meaning at output)
+c              limit  - integer
+c                       maximum number of error estimates the list
+c                       can contain
+c
+c              last   - integer
+c                       number of error estimates currently
+c                       in the list
+c
+c              maxerr - integer
+c                       maxerr points to the nrmax-th largest error
+c                       estimate currently in the list
+c
+c              ermax  - real
+c                       nrmax-th largest error estimate
+c                       ermax = elist(maxerr)
+c
+c              elist  - real
+c                       vector of dimension last containing
+c                       the error estimates
+c
+c              iord   - integer
+c                       vector of dimension last, the first k
+c                       elements of which contain pointers
+c                       to the error estimates, such that
+c                       elist(iord(1)),... , elist(iord(k))
+c                       form a decreasing sequence, with
+c                       k = last if last.le.(limit/2+2), and
+c                       k = limit+1-last otherwise
+c
+c              nrmax  - integer
+c                       maxerr = iord(nrmax)
+c
+c 4.        no subroutines or functions needed
+c***end prologue  qpsrt
+c
+      real elist,ermax,errmax,errmin
+      integer i,ibeg,ido,iord,isucc,j,jbnd,jupbn,k,last,limit,maxerr,
+     *  nrmax
+      dimension elist(last),iord(last)
+c
+c           check whether the list contains more than
+c           two error estimates.
+c
+c***first executable statement  qpsrt
+      if(last.gt.2) go to 10
+      iord(1) = 1
+      iord(2) = 2
+      go to 90
+c
+c           this part of the routine is only executed
+c           if, due to a difficult integrand, subdivision
+c           increased the error estimate. in the normal case
+c           the insert procedure should start after the
+c           nrmax-th largest error estimate.
+c
+   10 errmax = elist(maxerr)
+      if(nrmax.eq.1) go to 30
+      ido = nrmax-1
+      do 20 i = 1,ido
+        isucc = iord(nrmax-1)
+c ***jump out of do-loop
+        if(errmax.le.elist(isucc)) go to 30
+        iord(nrmax) = isucc
+        nrmax = nrmax-1
+   20    continue
+c
+c           compute the number of elements in the list to
+c           be maintained in descending order. this number
+c           depends on the number of subdivisions still
+c           allowed.
+c
+   30 jupbn = last
+      if(last.gt.(limit/2+2)) jupbn = limit+3-last
+      errmin = elist(last)
+c
+c           insert errmax by traversing the list top-down,
+c           starting comparison from the element elist(iord(nrmax+1)).
+c
+      jbnd = jupbn-1
+      ibeg = nrmax+1
+      if(ibeg.gt.jbnd) go to 50
+      do 40 i=ibeg,jbnd
+        isucc = iord(i)
+c ***jump out of do-loop
+        if(errmax.ge.elist(isucc)) go to 60
+        iord(i-1) = isucc
+   40 continue
+   50 iord(jbnd) = maxerr
+      iord(jupbn) = last
+      go to 90
+c
+c           insert errmin by traversing the list bottom-up.
+c
+   60 iord(i-1) = maxerr
+      k = jbnd
+      do 70 j=i,jbnd
+        isucc = iord(k)
+c ***jump out of do-loop
+        if(errmin.lt.elist(isucc)) go to 80
+        iord(k+1) = isucc
+        k = k-1
+   70 continue
+      iord(i) = last
+      go to 90
+   80 iord(k+1) = last
+c
+c           set maxerr and ermax.
+c
+   90 maxerr = iord(nrmax)
+      ermax = elist(maxerr)
+      return
+      end
diff --git a/libcruft/quadpack/xerror.f b/libcruft/quadpack/xerror.f
new file mode 100644
index 0000000..072fd3a
--- /dev/null
+++ b/libcruft/quadpack/xerror.f
@@ -0,0 +1,39 @@
+      SUBROUTINE XERROR(MESSG,NMESSG,NERR,LEVEL)
+C
+C     ABSTRACT
+C        XERROR PROCESSES A DIAGNOSTIC MESSAGE, IN A MANNER
+C        DETERMINED BY THE VALUE OF LEVEL AND THE CURRENT VALUE
+C        OF THE LIBRARY ERROR CONTROL FLAG, KONTRL.
+C        (SEE SUBROUTINE XSETF FOR DETAILS.)
+C
+C     DESCRIPTION OF PARAMETERS
+C      --INPUT--
+C        MESSG - THE HOLLERITH MESSAGE TO BE PROCESSED, CONTAINING
+C                NO MORE THAN 72 CHARACTERS.
+C        NMESSG- THE ACTUAL NUMBER OF CHARACTERS IN MESSG.
+C        NERR  - THE ERROR NUMBER ASSOCIATED WITH THIS MESSAGE.
+C                NERR MUST NOT BE ZERO.
+C        LEVEL - ERROR CATEGORY.
+C                =2 MEANS THIS IS AN UNCONDITIONALLY FATAL ERROR.
+C                =1 MEANS THIS IS A RECOVERABLE ERROR.  (I.E., IT IS
+C                   NON-FATAL IF XSETF HAS BEEN APPROPRIATELY CALLED.)
+C                =0 MEANS THIS IS A WARNING MESSAGE ONLY.
+C                =-1 MEANS THIS IS A WARNING MESSAGE WHICH IS TO BE
+C                   PRINTED AT MOST ONCE, REGARDLESS OF HOW MANY
+C                   TIMES THIS CALL IS EXECUTED.
+C
+C     EXAMPLES
+C        CALL XERROR(23HSMOOTH -- NUM WAS ZERO.,23,1,2)
+C        CALL XERROR(43HINTEG  -- LESS THAN FULL ACCURACY ACHIEVED.,
+C                    43,2,1)
+C        CALL XERROR(65HROOTER -- ACTUAL ZERO OF F FOUND BEFORE INTERVAL
+C    1 FULLY COLLAPSED.,65,3,0)
+C        CALL XERROR(39HEXP    -- UNDERFLOWS BEING SET TO ZERO.,39,1,-1)
+C
+C     WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE
+C     LATEST REVISION ---  7 FEB 1979
+C
+      DIMENSION MESSG(NMESSG)
+      CALL XERRWD(MESSG,NMESSG,NERR,LEVEL,0,0,0,0,0.,0.)
+      RETURN
+      END
diff --git a/libcruft/ranlib/Basegen.doc b/libcruft/ranlib/Basegen.doc
new file mode 100644
index 0000000..bec25c8
--- /dev/null
+++ b/libcruft/ranlib/Basegen.doc
@@ -0,0 +1,382 @@
+
+
+
+
+
+
+
+
+
+
+
+                                     RANDLIB
+
+            Library of Fortran Routines for Random Number Generation
+
+
+
+
+
+
+
+
+                          Base Generator Documentation
+
+
+
+
+
+
+
+
+                            Compiled and Written by:
+
+                                 Barry W. Brown
+                                  James Lovato
+                                   
+
+
+
+
+
+
+
+
+
+                     Department of Biomathematics, Box 237
+                     The University of Texas, M.D. Anderson Cancer Center
+                     1515 Holcombe Boulevard
+                     Houston, TX      77030
+
+
+ This work was supported by grant CA-16672 from the National Cancer Institute.
+
+
+
+
+                     Base Random Number Generator
+
+
+
+I. OVERVIEW AND DEFAULT BEHAVIOR
+
+This   set of programs contains   32 virtual random number generators.
+Each generator can provide 1,048,576 blocks of numbers, and each block
+is of length 1,073,741,824.  Any generator can be set to the beginning
+or end of the current block or to its starting value.  The methods are
+from the paper  cited  immediately below, and  most of the  code  is a
+transliteration from the Pascal of the paper into Fortran.
+
+P.  L'Ecuyer and S. Cote.   Implementing a Random  Number Package with
+Splitting Facilities.  ACM Transactions on Mathematical Software 17:1,
+pp 98-111.
+
+Most users won't need the sophisticated  capabilities of this package,
+and will desire a single generator.  This single generator (which will
+have a non-repeating length  of 2.3 X  10^18 numbers) is the  default.
+In order to accommodate this use, the concept of the current generator
+is added to those of the  cited paper;  references to a  generator are
+always to the current generator.  The  current generator  is initially
+generator number  1; it  can  be  changed by   SETCGN, and the ordinal
+number of the current generator can be obtained from GETCGN.
+
+The user of the default can set the  initial values of the two integer
+seeds with SETALL.   If the user does  not set the   seeds, the random
+number   generation will  use   the  default   values, 1234567890  and
+123456789.  The values of the current seeds can be  achieved by a call
+to GETSD.  Random number may be obtained as integers ranging from 1 to
+a large integer by reference to function IGNLGI or as a floating point
+number between 0 and 1 by a reference to function RANF.  These are the
+only routines  needed by a user desiring   a single stream   of random
+numbers.
+
+II. CONCEPTS
+
+A stream of pseudo-random numbers is a sequence, each member  of which
+can be obtained either as an integer in  the range 1..2,147,483,563 or
+as a floating point number in the range [0..1].  The user is in charge
+of which representation is desired.
+
+The method contains an algorithm  for generating a  stream with a very
+long period, 2.3 X 10^18.   This  stream  in  partitioned into G (=32)
+virtual generators.  Each virtual generator contains 2^20 (=1,048,576)
+blocks   of non-overlapping   random  numbers.   Each  block is   2^30
+(=1,073,741,824) in length.
+
+
+
+Base Random Number Generator Page 2
+
+
+The state of a generator  is determined by two  integers called seeds.
+The seeds can be  initialized  by the  user; the initial values of the
+first must lie between 1 and 2,147,483,562, that of the second between
+1 and 2,147,483,398.  Each time a number is generated,  the  values of
+the seeds  change.   Three  values   of seeds are remembered   by  the
+generators  at all times:  the   value with  which the  generator  was
+initialized, the value at the beginning of the current block,  and the
+value at the beginning of the next block.   The seeds of any generator
+can be set to any of these three values at any time.
+
+    Of the  32 virtual   generators, exactly one    will  be  the  current
+generator, i.e., that one will  be used to  generate values for IGNLGI
+and RANDF.   Initially, the current generator is   set to number  one.
+The current generator may be changed by calling SETCGN, and the number
+of the current generator can be obtained using GETCGN.
+
+III. AN EXAMPLE
+
+An example of  the  need  for these capabilities   is as follows.  Two
+statistical techniques are being compared on  data of different sizes.
+The first  technique uses   bootstrapping  and is  thought to   be  as
+accurate using less data   than the second method  which  employs only
+brute force.
+
+For the first method, a data set of size uniformly distributed between
+25 and 50 will be generated.  Then the data set  of the specified size
+will be generated and alalyzed.  The second method will  choose a data
+set size between 100 and 200, generate the data  and alalyze it.  This
+process will be repeated 1000 times.
+
+For  variance reduction, we  want the  random numbers  used in the two
+methods to be the  same for each of  the 1000 comparisons.  But method
+two will  use more random  numbers than   method one and  without this
+package, synchronization might be difficult.
+
+With the package, it is a snap.  Use generator 1 to obtain  the sample
+size for  method one and generator 2  to obtain the  data.  Then reset
+the state to the beginning  of the current  block and do the same  for
+the second method.  This assures that the initial data  for method two
+is that used by  method  one.  When both  have concluded,  advance the
+block for both generators.
+
+IV.  THE INTERFACE
+
+A random number is obtained either  as a random  integer between 1 and
+2,147,483,562  by invoking integer  function  IGNLGI (I GeNerate LarGe
+Integer)  or as a  random  floating point  number  between 0 and 1  by
+invoking real function RANF.  Neither function has arguments.
+
+The  seed of the  first generator  can  be set by invoking  subroutine
+SETALL;   the values of   the seeds  of   the other 31 generators  are
+calculated from this value.
+
+
+
+Base Random Number Generator Page 3
+
+
+The number of  the current generator  can be set by calling subroutine
+SETCGN, which takes a single argument, the integer generator number in
+the range 1..32.  The number of the current  generator can be obtained
+by invoking subroutine GETCGN  which returns the number  in its single
+integer argument.
+
+
+V. CALLING SEQUENCES
+
+      A. SETTING THE SEED OF ALL GENERATORS
+
+C**********************************************************************  
+C                                                                        
+C      SUBROUTINE SETALL(ISEED1,ISEED2)                                  
+C               SET ALL random number generators                         
+C                                                                        
+C     Sets the initial seed of generator 1 to ISEED1 and ISEED2. The     
+C     initial seeds of the other generators are set accordingly, and     
+C     all generators states are set to these seeds.                      
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     ISEED1 -> First of two integer seeds                               
+C                                   INTEGER ISEED1                       
+C                                                                        
+C     ISEED2 -> Second of two integer seeds                              
+C                                   INTEGER ISEED1                       
+C                                                                        
+C**********************************************************************  
+
+
+      B. OBTAINING RANDOM NUMBERS
+
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION IGNLGI()                                          
+C               GeNerate LarGe Integer                                   
+C                                                                        
+C     Returns a random integer following a uniform distribution over     
+C     (1, 2147483562) using the current generator.                       
+C                                                                        
+C**********************************************************************  
+
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION RANF()                                               
+C                RANDom number generator as a Function                   
+C                                                                        
+C     Returns a random floating point number from a uniform distribution 
+C     over 0 - 1 (endpoints of this interval are not returned) using the 
+C     current generator                                                  
+C                                                                        
+C**********************************************************************  
+
+
+
+Base Random Number Generator                                    Page 4
+
+
+      C. SETTING AND OBTAINING THE NUMBER OF THE CURRENT GENERATOR
+
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE SETCGN( G )                                             
+C                      Set GeNerator                                     
+C                                                                        
+C     Sets  the  current  generator to G. All references to a generator
+C     are to the current generator.                                      
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C     G --> Number of the current random number generator (1..32)        
+C                    INTEGER G                                           
+C                                                                        
+C**********************************************************************
+
+C**********************************************************************  
+C                                                                        
+C      SUBROUTINE GETCGN(G)                                              
+C                         Get GeNerator                                  
+C                                                                        
+C     Returns in G the number of the current random number generator     
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C     G <-- Number of the current random number generator (1..32)        
+C                    INTEGER G                                           
+C                                                                        
+C**********************************************************************  
+  
+      D. OBTAINING OR CHANGING SEEDS IN CURRENT GENERATOR
+
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE ADVNST(K)                                               
+C               ADV-a-N-ce ST-ate                                        
+C                                                                        
+C     Advances the state  of  the current  generator  by 2^K values  and 
+C     resets the initial seed to that value.                             
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     K -> The generator is advanced by 2^K values                        
+C                                   INTEGER K                            
+C                                                                        
+C**********************************************************************  
+
+
+
+Base Random Number Generator                                    Page 5
+
+
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE GETSD(ISEED1,ISEED2)                                  
+C               GET SeeD                                                 
+C                                                                        
+C     Returns the value of two integer seeds of the current generator    
+C
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C                                                                        
+C     ISEED1 <- First integer seed of generator G                        
+C                                   INTEGER ISEED1                       
+C                                                                        
+C     ISEED2 <- Second integer seed of generator G                       
+C                                   INTEGER ISEED1                       
+C                                                                        
+C**********************************************************************  
+
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE INITGN(ISDTYP)                                          
+C          INIT-ialize current G-e-N-erator                              
+C                                                                        
+C     Reinitializes the state of the current generator                   
+C
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     ISDTYP -> The state to which the generator is to be set            
+C          ISDTYP = -1  => sets the seeds to their initial value
+C          ISDTYP =  0  => sets the seeds to the first value of
+C                          the current block
+C          ISDTYP =  1  => sets the seeds to the first value of
+C                          the next block
+C                                                                        
+C                                   INTEGER ISDTYP                       
+C                                                                        
+C**********************************************************************  
+
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE SETSD(ISEED1,ISEED2)                                    
+C               SET S-ee-D of current generator                          
+C                                                                        
+C     Resets the initial  seed of  the current  generator to  ISEED1 and
+C     ISEED2. The seeds of the other generators remain unchanged.
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     ISEED1 -> First integer seed                                       
+C                                   INTEGER ISEED1                       
+C                                                                        
+C     ISEED2 -> Second integer seed                                      
+C                                   INTEGER ISEED1                       
+C                                                                        
+C**********************************************************************  
+
+
+
+Base Random Number Generator                                    Page 6
+
+
+      E. MISCELLANY
+
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION MLTMOD(A,S,M)                                     
+C                                                                        
+C                    Returns (A*S) MOD M                                 
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     A, S, M  -->                                                       
+C                         INTEGER A,S,M                                  
+C                                                                        
+C**********************************************************************  
+
+C**********************************************************************  
+C                                                                        
+C      SUBROUTINE SETANT(QVALUE)                                         
+C               SET ANTithetic                                           
+C                                                                        
+C     Sets whether the current generator produces antithetic values.  If 
+C     X   is  the value  normally returned  from  a uniform [0,1] random 
+C     number generator then 1  - X is the antithetic  value. If X is the 
+C     value  normally  returned  from a   uniform  [0,N]  random  number 
+C     generator then N - 1 - X is the antithetic value.                  
+C                                                                        
+C     All generators are initialized to NOT generate antithetic values.  
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C     QVALUE -> .TRUE. if generator G is to generating antithetic        
+C                    values, otherwise .FALSE.                           
+C                                   LOGICAL QVALUE                       
+C                                                                        
+C**********************************************************************  
diff --git a/libcruft/ranlib/HOWTOGET b/libcruft/ranlib/HOWTOGET
new file mode 100644
index 0000000..4fb58dc
--- /dev/null
+++ b/libcruft/ranlib/HOWTOGET
@@ -0,0 +1,31 @@
+
+                                WHERE TO GET IT
+
+     Software written  by members  of the section   is freely available  to
+     anyone.  Reposting  on other   archives is  encouraged.  The  code  is
+     furnished in source form and as DOS and Macintosh executables. Readers
+     with Internet access  and a browser  might note the following web site
+     addresses:
+
+          University of Texas M. D. Anderson Cancer Center Home Page:
+                           http://utmdacc.mdacc.tmc.edu/
+
+                    Department of Biomathematics Home Page:
+                           http://odin.mdacc.tmc.edu/
+
+
+                              Available Software:
+                       http://odin.mdacc.tmc.edu/anonftp/
+
+
+     Our code can also be obtained  by anonymous ftp to odin.mdacc.tmc.edu.
+     The index is on file ./pub/index.
+
+     Our statistical  code is  also  posted  to statlib  after some  delay.
+     Statlib can be accessed at:
+                             http://lib.stat.cmu.edu/
+     See in particular:
+                    http://lib.stat.cmu.edu/general/Utexas/
+
+     The code is also archived at many other sites (at their option).  Use
+     your favorite search engine to find one close to you.
diff --git a/libcruft/ranlib/Makefile.in b/libcruft/ranlib/Makefile.in
new file mode 100644
index 0000000..69b2788
--- /dev/null
+++ b/libcruft/ranlib/Makefile.in
@@ -0,0 +1,40 @@
+# Makefile for octave's libcruft/ranlib directory
+#
+# Copyright (C) 1993, 1994, 1995, 1997, 1998, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+SPECIAL = HOWTOGET README randlib.chs randlib.fdoc \
+	tstbot.for tstgmn.for tstmid.for
+
+EXTERNAL_DISTFILES = $(DISTFILES) $(srcdir)/Basegen.doc
+
+FSRC = advnst.f genbet.f genchi.f genexp.f genf.f gengam.f \
+  genmn.f genmul.f gennch.f gennf.f gennor.f genprm.f genunf.f \
+  getcgn.f getsd.f ignbin.f ignlgi.f ignnbn.f ignpoi.f ignuin.f \
+  initgn.f inrgcm.f lennob.f mltmod.f phrtsd.f qrgnin.f ranf.f \
+  setall.f setant.f setgmn.f setsd.f sexpo.f sgamma.f snorm.f wrap.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/ranlib/README b/libcruft/ranlib/README
new file mode 100644
index 0000000..9103ffc
--- /dev/null
+++ b/libcruft/ranlib/README
@@ -0,0 +1,346 @@
+
+
+
+
+
+
+
+
+
+
+
+                                     RANDLIB
+
+            Library of Fortran Routines for Random Number Generation
+
+
+                          Version 1.3 -- August, 1997
+
+
+
+
+                                     README
+
+
+
+
+
+
+
+
+                            Compiled and Written by:
+
+                                 Barry W. Brown
+                                  James Lovato
+                                 Kathy Russell
+                                  John Venier
+
+
+
+
+
+
+
+
+
+                     Department of Biomathematics, Box 237
+                     The University of Texas, M.D. Anderson Cancer Center
+                     1515 Holcombe Boulevard
+                     Houston, TX      77030
+
+
+ This work was supported by grant CA-16672 from the National Cancer Institute.
+
+
+
+                       THANKS TO OUR SUPPORTERS
+
+This work  was supported  in part by  grant CA-16672 from the National
+Cancer Institute.  We are grateful  to Larry and  Pat McNeil of Corpus
+Cristi for their generous support.  Some equipment used in this effort
+was provided by IBM as part of a cooperative study agreement; we thank
+them.
+
+
+                          SUMMARY OF RANDLIB
+
+The bottom level routines provide 32 virtual random number generators.
+Each generator can provide 1,048,576 blocks of numbers, and each block
+is of length 1,073,741,824.  Any generator can be set to the beginning
+or end  of the current  block or to  its starting value.  Packaging is
+provided   so  that  if  these capabilities  are not  needed, a single
+generator with period 2.3 X 10^18 is seen.
+
+Using this base, routines are provided that return:
+    (1)  Beta random deviates
+    (2)  Chi-square random deviates
+    (3)  Exponential random deviates
+    (4)  F random deviates
+    (5)  Gamma random deviates
+    (6)  Multivariate normal random deviates (mean and covariance
+         matrix specified)
+    (7)  Noncentral chi-square random deviates
+    (8)  Noncentral F random deviates
+    (9)  Univariate normal random deviates
+    (10) Random permutations of an integer array
+    (11) Real uniform random deviates between specified limits
+    (12) Binomial random deviates
+    (13) Negative Binomial random deviates
+    (14) Multinomial random deviates
+    (15) Poisson random deviates
+    (16) Integer uniform deviates between specified limits
+    (17) Seeds for the random number generator calculated from a
+         character string
+
+                             INSTALLATION
+
+Directory src contains  the Fortran source.  The  Fortran code from this
+directory should be  compiled and placed  in a library.   Directory test
+contains three test programs for this code.
+
+
+
+
+
+
+                            DOCUMENTATION
+
+Documentation  is  on directory doc on the  distribution.   All of the
+documentation is  in the  form   of  character  (ASCII)    files.   An
+explanation of the concepts involved in the base generator and details
+of its implementation are contained in Basegen.doc.  A summary  of all
+of the  available  routines is  contained  in randlib.chs  (chs  is  an
+abbreviation of 'cheat sheet').  The 'chs'  file  will probably be the
+reference to randlib  that is primarily used.   The  file, randlib.fdoc,
+contains all comments heading  each routine.   There is somewhat  more
+information   in  'fdoc' than  'chs',  but  the additional information
+consists primarily of references to the literature.
+
+
+
+                               SOURCES
+
+The following routines,  which  were  written by others   and  lightly
+modified for consistency in packaging, are included in RANDLIB.
+
+                        Bottom Level Routines
+
+These routines are a transliteration of the Pascal in the reference to
+Fortran.
+
+L'Ecuyer, P. and  Cote, S. "Implementing  a Random Number Package with
+Splitting  Facilities."  ACM  Transactions   on Mathematical Software,
+17:98-111 (1991)
+
+                             Exponential
+
+This code was obtained from Netlib.
+
+Ahrens,  J.H. and  Dieter, U.   Computer Methods for Sampling From the
+Exponential and Normal  Distributions.  Comm. ACM,  15,10 (Oct. 1972),
+873 - 882.
+
+                                Gamma
+
+(Case R >= 1.0)                                          
+
+Ahrens, J.H. and Dieter, U.  Generating Gamma  Variates by  a Modified
+Rejection Technique.  Comm. ACM, 25,1 (Jan. 1982), 47 - 54.
+Algorithm GD                                                       
+
+(Case 0.0 <= R <= 1.0)                                   
+
+Ahrens, J.H. and Dieter, U.  Computer Methods for Sampling from Gamma,
+Beta,  Poisson  and Binomial   Distributions.    Computing, 12 (1974),
+223-246.  Adaptation of algorithm GS.
+
+
+
+
+
+
+                                Normal
+
+This code was obtained from netlib.
+
+Ahrens, J.H.  and  Dieter, U.    Extensions of   Forsythe's Method for
+Random Sampling  from  the Normal Distribution.  Math. Comput., 27,124
+(Oct. 1973), 927 - 937.
+
+                               Binomial
+
+This code was kindly sent me by Dr. Kachitvichyanukul.
+
+Kachitvichyanukul,  V. and Schmeiser, B.   W.  Binomial Random Variate
+Generation.  Communications of the ACM, 31, 2 (February, 1988) 216.
+
+
+                               Poisson
+
+This code was obtained from netlib.
+
+Ahrens,  J.H. and Dieter, U.   Computer Generation of Poisson Deviates
+From Modified  Normal Distributions.  ACM Trans.  Math. Software, 8, 2
+(June 1982),163-179
+
+                                 Beta
+
+This code was written by us following the recipe in the following.
+
+R. C.  H.   Cheng Generating  Beta Variables  with  Nonintegral  Shape
+Parameters. Communications of  the ACM,  21:317-322 (1978) (Algorithms
+BB and BC)
+
+                               Linpack
+
+Routines SPOFA and SDOT are used to perform the Cholesky decomposition
+of  the covariance  matrix  in  SETGMN  (used  for  the  generation of
+multivariate normal deviates).
+
+Dongarra, J.  J., Moler,   C.  B., Bunch, J.   R. and  Stewart, G.  W.
+Linpack User's Guide.  SIAM Press, Philadelphia.  (1979)
+
+
+
+
+                              LEGALITIES
+
+Code that appeared  in an    ACM  publication  is subject  to    their
+algorithms policy:
+
+     Submittal of  an  algorithm    for publication  in   one of   the  ACM
+     Transactions implies that unrestricted use  of the algorithm within  a
+     computer is permissible.   General permission  to copy and  distribute
+     the algorithm without fee is granted provided that the copies  are not
+     made  or   distributed for  direct   commercial  advantage.    The ACM
+     copyright notice and the title of the publication and its date appear,
+     and  notice is given that copying  is by permission of the Association
+     for Computing Machinery.  To copy otherwise, or to republish, requires
+     a fee and/or specific permission.
+
+     Krogh, F.  Algorithms  Policy.  ACM  Tran.   Math.  Softw.   13(1987),
+     183-186.
+
+We place the Randlib code that we have written in the public domain.  
+
+                                 NO WARRANTY
+     
+     WE PROVIDE ABSOLUTELY  NO 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
+     THIS PROGRAM PROVE  DEFECTIVE, YOU ASSUME  THE COST  OF  ALL NECESSARY
+     SERVICING, REPAIR OR CORRECTION.
+     
+     IN NO  EVENT  SHALL THE UNIVERSITY  OF TEXAS OR  ANY  OF ITS COMPONENT
+     INSTITUTIONS INCLUDING M. D.   ANDERSON HOSPITAL BE LIABLE  TO YOU FOR
+     DAMAGES, INCLUDING ANY  LOST PROFITS, LOST MONIES,   OR OTHER SPECIAL,
+     INCIDENTAL   OR  CONSEQUENTIAL DAMAGES   ARISING   OUT  OF  THE USE OR
+     INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA OR
+     ITS ANALYSIS BEING  RENDERED INACCURATE OR  LOSSES SUSTAINED  BY THIRD
+     PARTIES) THE PROGRAM.
+     
+     (Above NO WARRANTY modified from the GNU NO WARRANTY statement.)
+
+
+
+                         WHAT'S NEW IN VERSION 1.1?
+
+  
+Random number generation  for  the Negative Binomial  and  Multinomial
+distributions has been included.
+
+Two errors in the code  which generates random  numbers from the Gamma
+distribution were fixed.
+
+
+                         WHAT'S NEW IN VERSION 1.2?
+
+We changed the name  of the package  from 'ranlib' to 'randlib'.  This
+was done so  that we can determine who  archives it.   'ranlib' is the
+name of a Unix utility which produces many spurious hits on a web
+search engine.
+
+
+The linpack routines are now housed in the /src directory.
+
+In  several routines, some   variables were   given an  explicit  SAVE
+attribute  and  some  dummy  initial values   were changed to  prevent
+potential errors.
+'genbet.f' 'ignbin.f'   'ignpoi.f' 'phrtsd.f'   'sexpo.f'   'sgamma.f'
+'snorm.f'
+
+In several  routines, argument checking was  implemented; the code now
+breaks if inappropriate values are passed to it.
+'genbet.f' A and B must be >= 1.0E-37 instead of 0.0
+'genexp.f' AV must be >= 0.0
+'gengam.f' A and R both must be > 0.0
+'gennor.f' SD must be >= 0.0
+'ignbin.f' N must be >= 0, and 0.0 <= PP <= 1.0.
+'ignnbn.f' N must be > 0, 0.0 < P < 1.0 (previously allowed N = 0)
+'ignpoi.f' MU must be >= 0.0
+
+For the Non-Central  Chi-Squared and Non-Central  F distributions, the
+case DF = 1.0 (DFN = 1.0 for the F) is now allowed.
+'gennch.f' 'gennf.f'
+
+Wherever possible,  the   user-accessible  code  now calls    the base
+generators   directly.   This means   improved performance  and  fewer
+dependencies, but the routines should work  exactly as before from the
+user's point of view.
+'genchi.f' 'genf.f' 'gennch.f' 'gennf.f' 'ignnbn.f'
+
+Many minor modifications  have been  made which  should make  the code
+more robust, without changing how the code is used.
+'genbet.f'   'gengam.f'  'ignpoi.f'  'ignuin.f'  'sgamma.f' 'tstmid.f'
+
+Finally, five distributions have  been added to the  mid-level tester,
+which test the Exponential, Gamma, Multinomial, Negative Binomial, and
+Normal distributions.
+'tstmid.f'
+
+
+
+
+                   WHAT'S NOT NEW IN VERSION 1.2 ?
+
+No calling sequences have changed.
+
+		      WHAT'S NEW IN VERSION 1.3?
+
+The calling sequence of SETGMN has been changed!  We added an argument
+(INTEGER LDCOVM) representing the leading actual dimension of COVM, to
+allow the user to use this routine in  the case that COVM is contained
+in a larger array.  This change also makes the routine more compatible
+with  LINPACK    routines.  See  the    following files  for  details:
+'setgmn.f' in the /src directory, and 'randlib.fdoc' and 'randlib.chs'
+in the /doc directory.
+
+Briefly, the declaration of SETGMN has been changed
+from:
+      SUBROUTINE setgmn(meanv,covm,p,parm)
+to:
+      SUBROUTINE setgmn(meanv,covm,ldcovm,p,parm)
+
+The program 'tstgmn.f' (in the /test directory) was changed to reflect
+the change in the calling sequence of SETGMN.
+
+'randlib.fdoc' and 'randlib.chs' in the /doc directory were changed to
+relect the change in the calling sequence of SETGMN.
+
+Minor changes were made in two routines  ('sgamma.f' and 'sexpo.f') to
+fix unusual bugs.
+
+The protection from overflow   in deviate generation in  two  routines
+('genf.f'  and 'gennf.f')   was changed to   prevent a  constant  from
+underflowing at compile time.
+
+                   WHAT'S NOT NEW IN VERSION 1.3 ?
+
+No calling sequences (other than SETGMN) have changed.
+
+			     MANY THANKS
+
+The authors would like to thank the many users  who have reported bugs
+and  suggested improvements; Randlib  would  not  be  the  same  today
+without them.  We heartily encourage others to join them.
diff --git a/libcruft/ranlib/advnst.f b/libcruft/ranlib/advnst.f
new file mode 100644
index 0000000..927f745
--- /dev/null
+++ b/libcruft/ranlib/advnst.f
@@ -0,0 +1,79 @@
+      SUBROUTINE advnst(k)
+C**********************************************************************
+C
+C     SUBROUTINE ADVNST(K)
+C               ADV-a-N-ce ST-ate
+C
+C     Advances the state  of  the current  generator  by 2^K values  and
+C     resets the initial seed to that value.
+C
+C     This is  a  transcription from   Pascal to  Fortran    of  routine
+C     Advance_State from the paper
+C
+C     L'Ecuyer, P. and  Cote, S. "Implementing  a  Random Number Package
+C     with  Splitting   Facilities."  ACM  Transactions  on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C     K -> The generator is advanced by2^K values
+C                                   INTEGER K
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER k
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER g,i,ib1,ib2
+C     ..
+C     .. External Functions ..
+      INTEGER mltmod
+      LOGICAL qrgnin
+      EXTERNAL mltmod,qrgnin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn,setsd
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C     Abort unless random number generator initialized
+      IF (qrgnin()) GO TO 10
+      WRITE (*,*) ' ADVNST called before random number generator ',
+     +  ' initialized -- abort!'
+      STOP ' ADVNST called before random number generator initialized'
+
+   10 CALL getcgn(g)
+C
+      ib1 = a1
+      ib2 = a2
+      DO 20,i = 1,k
+          ib1 = mltmod(ib1,ib1,m1)
+          ib2 = mltmod(ib2,ib2,m2)
+   20 CONTINUE
+      CALL setsd(mltmod(ib1,cg1(g),m1),mltmod(ib2,cg2(g),m2))
+C
+C     NOW, IB1 = A1**K AND IB2 = A2**K
+C
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/genbet.f b/libcruft/ranlib/genbet.f
new file mode 100644
index 0000000..c813d19
--- /dev/null
+++ b/libcruft/ranlib/genbet.f
@@ -0,0 +1,249 @@
+      REAL FUNCTION genbet(aa,bb)
+C**********************************************************************
+C
+C     REAL FUNCTION GENBET( A, B )
+C               GeNerate BETa random deviate
+C
+C
+C                              Function
+C
+C
+C     Returns a single random deviate from the beta distribution with
+C     parameters A and B.  The density of the beta is
+C               x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1
+C
+C
+C                              Arguments
+C
+C
+C     A --> First parameter of the beta distribution
+C                         REAL A
+C     JJV                 (A > 1.0E-37)
+C
+C     B --> Second parameter of the beta distribution
+C                         REAL B
+C     JJV                 (B > 1.0E-37)
+C
+C
+C                              Method
+C
+C
+C     R. C. H. Cheng
+C     Generating Beta Variates with Nonintegral Shape Parameters
+C     Communications of the ACM, 21:317-322  (1978)
+C     (Algorithms BB and BC)
+C
+C**********************************************************************
+C     .. Parameters ..
+C     Close to the largest number that can be exponentiated
+      REAL expmax
+C     JJV changed this - 89 was too high, and LOG(1.0E38) = 87.49823
+      PARAMETER (expmax=87.49823)
+C     Close to the largest representable single precision number
+      REAL infnty
+      PARAMETER (infnty=1.0E38)
+C     JJV added the parameter minlog
+C     Close to the smallest number of which a LOG can be taken.
+      REAL minlog
+      PARAMETER (minlog=1.0E-37)
+C     ..
+C     .. Scalar Arguments ..
+      REAL aa,bb
+C     ..
+C     .. Local Scalars ..
+      REAL a,alpha,b,beta,delta,gamma,k1,k2,olda,oldb,r,s,t,u1,u2,v,w,y,
+     +     z
+      LOGICAL qsame
+C     ..
+C     .. External Functions ..
+      REAL ranf
+      EXTERNAL ranf
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC exp,log,max,min,sqrt
+C     ..
+C     .. Save statement ..
+C     JJV added a,b
+      SAVE olda,oldb,alpha,beta,gamma,k1,k2,a,b
+C     ..
+C     .. Data statements ..
+C     JJV changed these to ridiculous values
+      DATA olda,oldb/-1.0E37,-1.0E37/
+C     ..
+C     .. Executable Statements ..
+      qsame = (olda.EQ.aa) .AND. (oldb.EQ.bb)
+      IF (qsame) GO TO 20
+C     JJV added small minimum for small log problem in calc of W
+      IF (.NOT. (aa.LT.minlog.OR.bb.LT.minlog)) GO TO 10
+      WRITE (*,*) ' AA or BB < ',minlog,' in GENBET - Abort!'
+      WRITE (*,*) ' AA: ',aa,' BB ',bb
+      STOP ' AA or BB too small in GENBET - Abort!'
+
+   10 olda = aa
+      oldb = bb
+   20 IF (.NOT. (min(aa,bb).GT.1.0)) GO TO 100
+
+
+C     Alborithm BB
+
+C
+C     Initialize
+C
+      IF (qsame) GO TO 30
+      a = min(aa,bb)
+      b = max(aa,bb)
+      alpha = a + b
+      beta = sqrt((alpha-2.0)/ (2.0*a*b-alpha))
+      gamma = a + 1.0/beta
+   30 CONTINUE
+   40 u1 = ranf()
+C
+C     Step 1
+C
+      u2 = ranf()
+      v = beta*log(u1/ (1.0-u1))
+C     JJV altered this
+      IF (v.GT.expmax) GO TO 55
+C     JJV added checker to see if a*exp(v) will overflow
+C     JJV 50 _was_ w = a*exp(v); also note here a > 1.0
+   50 w = exp(v)
+      IF (w.GT.infnty/a) GO TO 55
+      w = a*w
+      GO TO 60
+ 55   w = infnty
+
+   60 z = u1**2*u2
+      r = gamma*v - 1.3862944
+      s = a + r - w
+C
+C     Step 2
+C
+      IF ((s+2.609438).GE. (5.0*z)) GO TO 70
+C
+C     Step 3
+C
+      t = log(z)
+      IF (s.GT.t) GO TO 70
+C
+C     Step 4
+C
+C     JJV added checker to see if log(alpha/(b+w)) will 
+C     JJV overflow.  If so, we count the log as -INF, and
+C     JJV consequently evaluate conditional as true, i.e.
+C     JJV the algorithm rejects the trial and starts over
+C     JJV May not need this here since ALPHA > 2.0
+      IF (alpha/(b+w).LT.minlog) GO TO 40
+
+      IF ((r+alpha*log(alpha/ (b+w))).LT.t) GO TO 40
+C
+C     Step 5
+C
+   70 IF (.NOT. (aa.EQ.a)) GO TO 80
+      genbet = w/ (b+w)
+      GO TO 90
+
+   80 genbet = b/ (b+w)
+   90 GO TO 230
+
+
+C     Algorithm BC
+
+C
+C     Initialize
+C
+  100 IF (qsame) GO TO 110
+      a = max(aa,bb)
+      b = min(aa,bb)
+      alpha = a + b
+      beta = 1.0/b
+      delta = 1.0 + a - b
+      k1 = delta* (0.0138889+0.0416667*b)/ (a*beta-0.777778)
+      k2 = 0.25 + (0.5+0.25/delta)*b
+  110 CONTINUE
+  120 u1 = ranf()
+C
+C     Step 1
+C
+      u2 = ranf()
+      IF (u1.GE.0.5) GO TO 130
+C
+C     Step 2
+C
+      y = u1*u2
+      z = u1*y
+      IF ((0.25*u2+z-y).GE.k1) GO TO 120
+      GO TO 170
+C
+C     Step 3
+C
+  130 z = u1**2*u2
+      IF (.NOT. (z.LE.0.25)) GO TO 160
+      v = beta*log(u1/ (1.0-u1))
+
+C     JJV instead of checking v > expmax at top, I will check
+C     JJV if a < 1, then check the appropriate values
+
+      IF (a.GT.1.0) GO TO 135
+C     JJV A < 1 so it can help out if EXP(V) would overflow
+      IF (v.GT.expmax) GO TO 132
+      w = a*exp(v)
+      GO TO 200
+ 132  w = v + log(a)
+      IF (w.GT.expmax) GO TO 140
+      w = exp(w)
+      GO TO 200
+
+C     JJV in this case A > 1
+ 135  IF (v.GT.expmax) GO TO 140
+      w = exp(v)
+      IF (w.GT.infnty/a) GO TO 140
+      w = a*w
+      GO TO 200
+ 140  w = infnty
+      GO TO 200
+
+  160 IF (z.GE.k2) GO TO 120
+C
+C     Step 4
+C
+C
+C     Step 5
+C
+  170 v = beta*log(u1/ (1.0-u1))
+
+C     JJV same kind of checking as above
+      IF (a.GT.1.0) GO TO 175
+C     JJV A < 1 so it can help out if EXP(V) would overflow
+      IF (v.GT.expmax) GO TO 172
+      w = a*exp(v)
+      GO TO 190
+ 172  w = v + log(a)
+      IF (w.GT.expmax) GO TO 180
+      w = exp(w)
+      GO TO 190
+
+C     JJV in this case A > 1
+ 175  IF (v.GT.expmax) GO TO 180
+      w = exp(v)
+      IF (w.GT.infnty/a) GO TO 180
+      w = a*w
+      GO TO 190
+
+  180 w = infnty
+
+C     JJV here we also check to see if log overlows; if so, we treat it
+C     JJV as -INF, which means condition is true, i.e. restart
+  190 IF (alpha/(b+w).LT.minlog) GO TO 120
+      IF ((alpha* (log(alpha/ (b+w))+v)-1.3862944).LT.log(z)) GO TO 120
+C
+C     Step 6
+C
+  200 IF (.NOT. (a.EQ.aa)) GO TO 210
+      genbet = w/ (b+w)
+      GO TO 220
+
+  210 genbet = b/ (b+w)
+  220 CONTINUE
+  230 RETURN
+
+      END
diff --git a/libcruft/ranlib/genchi.f b/libcruft/ranlib/genchi.f
new file mode 100644
index 0000000..e8fcbb0
--- /dev/null
+++ b/libcruft/ranlib/genchi.f
@@ -0,0 +1,49 @@
+      REAL FUNCTION genchi(df)
+C**********************************************************************
+C
+C     REAL FUNCTION GENCHI( DF )
+C                Generate random value of CHIsquare variable
+C
+C
+C                              Function
+C
+C
+C     Generates random deviate from the distribution of a chisquare
+C     with DF degrees of freedom random variable.
+C
+C
+C                              Arguments
+C
+C
+C     DF --> Degrees of freedom of the chisquare
+C            (Must be positive)
+C                         REAL DF
+C
+C
+C                              Method
+C
+C
+C     Uses relation between chisquare and gamma.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL df
+C     ..
+C     .. External Functions ..
+C      REAL gengam
+C      EXTERNAL gengam
+      REAL sgamma
+      EXTERNAL sgamma
+C     ..
+C     .. Executable Statements ..
+      IF (.NOT. (df.LE.0.0)) GO TO 10
+      WRITE (*,*) 'DF <= 0 in GENCHI - ABORT'
+      WRITE (*,*) 'Value of DF: ',df
+      STOP 'DF <= 0 in GENCHI - ABORT'
+
+C     JJV changed this to call sgamma directly
+C   10 genchi = 2.0*gengam(1.0,df/2.0)
+ 10   genchi = 2.0*sgamma(df/2.0)
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/genexp.f b/libcruft/ranlib/genexp.f
new file mode 100644
index 0000000..9fa0d35
--- /dev/null
+++ b/libcruft/ranlib/genexp.f
@@ -0,0 +1,60 @@
+      REAL FUNCTION genexp(av)
+
+C**********************************************************************
+C
+C     REAL FUNCTION GENEXP( AV )
+C
+C                    GENerate EXPonential random deviate
+C
+C
+C                              Function
+C
+C
+C     Generates a single random deviate from an exponential
+C     distribution with mean AV.
+C
+C
+C                              Arguments
+C
+C
+C     AV --> The mean of the exponential distribution from which
+C            a random deviate is to be generated.
+C                              REAL AV
+C     JJV                      (AV >= 0)
+C
+C     GENEXP <-- The random deviate.
+C                              REAL GENEXP
+C
+C
+C                              Method
+C
+C
+C     Renames SEXPO from TOMS as slightly modified by BWB to use RANF
+C     instead of SUNIF.
+C
+C     For details see:
+C
+C               Ahrens, J.H. and Dieter, U.
+C               Computer Methods for Sampling From the
+C               Exponential and Normal Distributions.
+C               Comm. ACM, 15,10 (Oct. 1972), 873 - 882.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL av
+C     ..
+C     .. External Functions ..
+      REAL sexpo
+      EXTERNAL sexpo
+C     ..
+C     .. Executable Statements ..
+C     JJV added check to ensure AV >= 0.0 
+      IF (av.GE.0.0) GO TO 10
+      WRITE (*,*) 'AV < 0.0 in GENEXP - ABORT'
+      WRITE (*,*) 'Value of AV: ',av
+      STOP 'AV < 0.0 in GENEXP - ABORT'
+
+ 10   genexp = sexpo()*av
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/genf.f b/libcruft/ranlib/genf.f
new file mode 100644
index 0000000..028e2d3
--- /dev/null
+++ b/libcruft/ranlib/genf.f
@@ -0,0 +1,72 @@
+      REAL FUNCTION genf(dfn,dfd)
+C**********************************************************************
+C
+C     REAL FUNCTION GENF( DFN, DFD )
+C                GENerate random deviate from the F distribution
+C
+C
+C                              Function
+C
+C
+C     Generates a random deviate from the F (variance ratio)
+C     distribution with DFN degrees of freedom in the numerator
+C     and DFD degrees of freedom in the denominator.
+C
+C
+C                              Arguments
+C
+C
+C     DFN --> Numerator degrees of freedom
+C             (Must be positive)
+C                              REAL DFN
+C      DFD --> Denominator degrees of freedom
+C             (Must be positive)
+C                              REAL DFD
+C
+C
+C                              Method
+C
+C
+C     Directly generates ratio of chisquare variates
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL dfd,dfn
+C     ..
+C     .. Local Scalars ..
+      REAL xden,xnum
+C     ..
+C     JJV changed this code to call sgamma directly
+C     .. External Functions ..
+C      REAL genchi
+C      EXTERNAL genchi
+      REAL sgamma
+      EXTERNAL sgamma
+C     ..
+C     .. Executable Statements ..
+      IF (.NOT. (dfn.LE.0.0.OR.dfd.LE.0.0)) GO TO 10
+      WRITE (*,*) 'Degrees of freedom nonpositive in GENF - abort!'
+      WRITE (*,*) 'DFN value: ',dfn,'DFD value: ',dfd
+      STOP 'Degrees of freedom nonpositive in GENF - abort!'
+
+ 10   xnum = 2.0*sgamma(dfn/2.0)/dfn
+
+C      GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD )
+      xden = 2.0*sgamma(dfd/2.0)/dfd
+C     JJV changed constant so that it will not underflow at compile time
+C     JJV while not slowing generator by using double precision or logs.
+C      IF (.NOT. (xden.LE. (1.0E-38*xnum))) GO TO 20
+      IF (.NOT. (xden.LE. (1.0E-37*xnum))) GO TO 20
+      WRITE (*,*) ' GENF - generated numbers would cause overflow'
+      WRITE (*,*) ' Numerator ',xnum,' Denominator ',xden
+C     JJV next 2 lines changed to maintain truncation of large deviates.
+C      WRITE (*,*) ' GENF returning 1.0E38'
+C      genf = 1.0E38
+      WRITE (*,*) ' GENF returning 1.0E37'
+      genf = 1.0E37
+      GO TO 30
+
+   20 genf = xnum/xden
+   30 RETURN
+
+      END
diff --git a/libcruft/ranlib/gengam.f b/libcruft/ranlib/gengam.f
new file mode 100644
index 0000000..1238b17
--- /dev/null
+++ b/libcruft/ranlib/gengam.f
@@ -0,0 +1,71 @@
+      REAL FUNCTION gengam(a,r)
+C**********************************************************************
+C
+C     REAL FUNCTION GENGAM( A, R )
+C           GENerates random deviates from GAMma distribution
+C
+C
+C                              Function
+C
+C
+C     Generates random deviates from the gamma distribution whose
+C     density is
+C          (A**R)/Gamma(R) * X**(R-1) * Exp(-A*X)
+C
+C
+C                              Arguments
+C
+C
+C     JJV added the argument ranges supported
+C     A --> Location parameter of Gamma distribution
+C                              REAL A ( A > 0 )
+C
+C     R --> Shape parameter of Gamma distribution
+C                              REAL R ( R > 0 )
+C
+C
+C                              Method
+C
+C
+C     Renames SGAMMA from TOMS as slightly modified by BWB to use RANF
+C     instead of SUNIF.
+C
+C     For details see:
+C               (Case R >= 1.0)
+C               Ahrens, J.H. and Dieter, U.
+C               Generating Gamma Variates by a
+C               Modified Rejection Technique.
+C               Comm. ACM, 25,1 (Jan. 1982), 47 - 54.
+C     Algorithm GD
+C
+C     JJV altered the following to reflect sgamma argument ranges
+C               (Case 0.0 < R < 1.0)
+C               Ahrens, J.H. and Dieter, U.
+C               Computer Methods for Sampling from Gamma,
+C               Beta, Poisson and Binomial Distributions.
+C               Computing, 12 (1974), 223-246/
+C     Adapted algorithm GS.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL a,r
+C     ..
+C     .. External Functions ..
+      REAL sgamma
+      EXTERNAL sgamma
+C     ..
+C     .. Executable Statements ..
+
+C     JJV added argument value checker
+      IF ( a.GT.0.0 .AND. r.GT.0.0 ) GO TO 10
+      WRITE (*,*) 'In GENGAM - Either (1) Location param A <= 0.0 or'
+      WRITE (*,*) '(2) Shape param R <= 0.0 - ABORT!'
+      WRITE (*,*) 'A value: ',a,'R value: ',r
+      STOP 'Location or shape param out of range in GENGAM - ABORT!'
+C     JJV end addition
+
+ 10   gengam = sgamma(r)/a
+C      gengam = gengam/a
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/genmn.f b/libcruft/ranlib/genmn.f
new file mode 100644
index 0000000..c29c918
--- /dev/null
+++ b/libcruft/ranlib/genmn.f
@@ -0,0 +1,82 @@
+      SUBROUTINE genmn(parm,x,work)
+C**********************************************************************
+C
+C     SUBROUTINE GENMN(PARM,X,WORK)
+C              GENerate Multivariate Normal random deviate
+C
+C
+C                              Arguments
+C
+C
+C     PARM --> Parameters needed to generate multivariate normal
+C               deviates (MEANV and Cholesky decomposition of
+C               COVM). Set by a previous call to SETGMN.
+C               1 : 1                - size of deviate, P
+C               2 : P + 1            - mean vector
+C               P+2 : P*(P+3)/2 + 1  - upper half of cholesky
+C                                       decomposition of cov matrix
+C                                             REAL PARM(*)
+C
+C     X    <-- Vector deviate generated.
+C                                             REAL X(P)
+C
+C     WORK <--> Scratch array
+C                                             REAL WORK(P)
+C
+C
+C                              Method
+C
+C
+C     1) Generate P independent standard normal deviates - Ei ~ N(0,1)
+C
+C     2) Using Cholesky decomposition find A s.t. trans(A)*A = COVM
+C
+C     3) trans(A)E + MEANV ~ N(MEANV,COVM)
+C
+C**********************************************************************
+C     .. Array Arguments ..
+      REAL parm(*),work(*),x(*)
+C     ..
+C     .. Local Scalars ..
+      REAL ae
+      INTEGER i,icount,j,p
+C     ..
+C     .. External Functions ..
+      REAL snorm
+      EXTERNAL snorm
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC int
+C     ..
+C     .. Executable Statements ..
+      p = int(parm(1))
+C
+C     Generate P independent normal deviates - WORK ~ N(0,1)
+C
+      DO 10,i = 1,p
+          work(i) = snorm()
+   10 CONTINUE
+      DO 30,i = 1,p
+C
+C     PARM (P+2 : P*(P+3)/2 + 1) contains A, the Cholesky
+C      decomposition of the desired covariance matrix.
+C          trans(A)(1,1) = PARM(P+2)
+C          trans(A)(2,1) = PARM(P+3)
+C          trans(A)(2,2) = PARM(P+2+P)
+C          trans(A)(3,1) = PARM(P+4)
+C          trans(A)(3,2) = PARM(P+3+P)
+C          trans(A)(3,3) = PARM(P+2-1+2P)  ...
+C
+C     trans(A)*WORK + MEANV ~ N(MEANV,COVM)
+C
+          icount = 0
+          ae = 0.0
+          DO 20,j = 1,i
+              icount = icount + j - 1
+              ae = ae + parm(i+ (j-1)*p-icount+p+1)*work(j)
+   20     CONTINUE
+          x(i) = ae + parm(i+1)
+   30 CONTINUE
+      RETURN
+C
+      END
diff --git a/libcruft/ranlib/genmul.f b/libcruft/ranlib/genmul.f
new file mode 100644
index 0000000..75377be
--- /dev/null
+++ b/libcruft/ranlib/genmul.f
@@ -0,0 +1,92 @@
+      SUBROUTINE genmul(n,p,ncat,ix)
+C**********************************************************************
+C
+C            SUBROUTINE GENMUL( N, P, NCAT, IX )
+C     GENerate an observation from the MULtinomial distribution
+C
+C
+C                              Arguments
+C
+C
+C     N --> Number of events that will be classified into one of
+C           the categories 1..NCAT
+C                         INTEGER N
+C
+C     P --> Vector of probabilities.  P(i) is the probability that
+C           an event will be classified into category i.  Thus, P(i)
+C           must be [0,1]. Only the first NCAT-1 P(i) must be defined
+C           since P(NCAT) is 1.0 minus the sum of the first
+C           NCAT-1 P(i).
+C                         REAL P(NCAT-1)
+C
+C     NCAT --> Number of categories.  Length of P and IX.
+C                         INTEGER NCAT
+C
+C     IX <-- Observation from multinomial distribution.  All IX(i)
+C            will be nonnegative and their sum will be N.
+C                         INTEGER IX(NCAT)
+C
+C
+C                              Method
+C
+C
+C     Algorithm from page 559 of
+C
+C     Devroye, Luc
+C
+C     Non-Uniform Random Variate Generation.  Springer-Verlag,
+C     New York, 1986.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      INTEGER n,ncat
+C     ..
+C     .. Array Arguments ..
+      REAL p(*)
+      INTEGER ix(*)
+C     ..
+C     .. Local Scalars ..
+      REAL prob,ptot,sum
+      INTEGER i,icat,ntot
+C     ..
+C     .. External Functions ..
+      INTEGER ignbin
+      EXTERNAL ignbin
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC abs
+C     ..
+C     .. Executable Statements ..
+
+C     Check Arguments
+      IF (n.LT.0) STOP 'N < 0 in GENMUL'
+      IF (ncat.LE.1) STOP 'NCAT <= 1 in GENMUL'
+      ptot = 0.0
+      DO 10,i = 1,ncat - 1
+          IF (p(i).LT.0.0) STOP 'Some P(i) < 0 in GENMUL'
+          IF (p(i).GT.1.0) STOP 'Some P(i) > 1 in GENMUL'
+          ptot = ptot + p(i)
+   10 CONTINUE
+      IF (ptot.GT.0.99999) STOP 'Sum of P(i) > 1 in GENMUL'
+
+C     Initialize variables
+      ntot = n
+      sum = 1.0
+      DO 20,i = 1,ncat
+          ix(i) = 0
+   20 CONTINUE
+
+C     Generate the observation
+      DO 30,icat = 1,ncat - 1
+          prob = p(icat)/sum
+          ix(icat) = ignbin(ntot,prob)
+          ntot = ntot - ix(icat)
+          IF (ntot.LE.0) RETURN
+          sum = sum - p(icat)
+   30 CONTINUE
+      ix(ncat) = ntot
+
+C     Finished
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/gennch.f b/libcruft/ranlib/gennch.f
new file mode 100644
index 0000000..0d3a4f1
--- /dev/null
+++ b/libcruft/ranlib/gennch.f
@@ -0,0 +1,69 @@
+      REAL FUNCTION gennch(df,xnonc)
+C**********************************************************************
+C
+C     REAL FUNCTION GENNCH( DF, XNONC )
+C           Generate random value of Noncentral CHIsquare variable
+C
+C
+C                              Function
+C
+C
+
+C     Generates random deviate  from the  distribution  of a  noncentral
+C     chisquare with DF degrees  of freedom and noncentrality  parameter
+C     XNONC.
+C
+C
+C                              Arguments
+C
+C
+C     DF --> Degrees of freedom of the chisquare
+C            (Must be >= 1.0)
+C                         REAL DF
+C
+C     XNONC --> Noncentrality parameter of the chisquare
+C               (Must be >= 0.0)
+C                         REAL XNONC
+C
+C
+C                              Method
+C
+C
+C     Uses fact that  noncentral chisquare  is  the  sum of a  chisquare
+C     deviate with DF-1  degrees of freedom plus the  square of a normal
+C     deviate with mean sqrt(XNONC) and standard deviation 1.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL df,xnonc
+C     ..
+C     .. External Functions ..
+C     JJV changed these to call SGAMMA and SNORM directly
+C      REAL genchi,gennor
+C      EXTERNAL genchi,gennor
+      REAL sgamma,snorm
+      EXTERNAL sgamma,snorm
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC sqrt
+C     ..
+C     JJV changed abort to df < 1, and added case: df = 1 
+C     .. Executable Statements ..
+      IF (.NOT. (df.LT.1.0.OR.xnonc.LT.0.0)) GO TO 10
+      WRITE (*,*) 'DF < 1 or XNONC < 0 in GENNCH - ABORT'
+      WRITE (*,*) 'Value of DF: ',df,' Value of XNONC',xnonc
+      STOP 'DF < 1 or XNONC < 0 in GENNCH - ABORT'
+
+C     JJV changed this to call SGAMMA and SNORM directly
+C      gennch = genchi(df-1.0) + gennor(sqrt(xnonc),1.0)**2
+
+ 10   IF (df.GE.1.000001) GO TO 20
+C     JJV case DF = 1.0
+      gennch = (snorm() + sqrt(xnonc))**2
+      GO TO 30
+
+C     JJV case DF > 1.0
+ 20   gennch = 2.0*sgamma((df-1.0)/2.0) + (snorm() + sqrt(xnonc))**2
+ 30   RETURN
+      
+      END
diff --git a/libcruft/ranlib/gennf.f b/libcruft/ranlib/gennf.f
new file mode 100644
index 0000000..35d3f2f
--- /dev/null
+++ b/libcruft/ranlib/gennf.f
@@ -0,0 +1,96 @@
+      REAL FUNCTION gennf(dfn,dfd,xnonc)
+
+C**********************************************************************
+C
+C     REAL FUNCTION GENNF( DFN, DFD, XNONC )
+C           GENerate random deviate from the Noncentral F distribution
+C
+C
+C                              Function
+C
+C
+C     Generates a random deviate from the  noncentral F (variance ratio)
+C     distribution with DFN degrees of freedom in the numerator, and DFD
+C     degrees of freedom in the denominator, and noncentrality parameter
+C     XNONC.
+C
+C
+C                              Arguments
+C
+C
+C     DFN --> Numerator degrees of freedom
+C             (Must be >= 1.0)
+C                              REAL DFN
+C      DFD --> Denominator degrees of freedom
+C             (Must be positive)
+C                              REAL DFD
+C
+C     XNONC --> Noncentrality parameter
+C               (Must be nonnegative)
+C                              REAL XNONC
+C
+C
+C                              Method
+C
+C
+C     Directly generates ratio of noncentral numerator chisquare variate
+C     to central denominator chisquare variate.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL dfd,dfn,xnonc
+C     ..
+C     .. Local Scalars ..
+      REAL xden,xnum
+      LOGICAL qcond
+C     ..
+C     .. External Functions ..
+C     JJV changed the code to call SGAMMA and SNORM directly
+C      REAL genchi,gennch
+C      EXTERNAL genchi,gennch
+      REAL sgamma,snorm
+      EXTERNAL sgamma,snorm
+C     ..
+C     .. Executable Statements ..
+C     JJV changed the argument checker to allow DFN = 1.0
+C     JJV in the same way as GENNCH was changed.
+      qcond = dfn .LT. 1.0 .OR. dfd .LE. 0.0 .OR. xnonc .LT. 0.0
+      IF (.NOT. (qcond)) GO TO 10
+      WRITE (*,*) 'In GENNF - Either (1) Numerator DF < 1.0 or'
+      WRITE (*,*) '(2) Denominator DF <= 0.0 or '
+      WRITE (*,*) '(3) Noncentrality parameter < 0.0'
+      WRITE (*,*) 'DFN value: ',dfn,'DFD value: ',dfd,'XNONC value: ',
+     +  xnonc
+      STOP 'Degrees of freedom or noncent param out of range in GENNF'
+
+C      GENNF = ( GENNCH( DFN, XNONC ) / DFN ) / ( GENCHI( DFD ) / DFD )
+C     JJV changed this to call SGAMMA and SNORM directly
+C     xnum = gennch(dfn,xnonc)/dfn
+ 10   IF (dfn.GE.1.000001) GO TO 20
+C     JJV case dfn = 1.0 - here I am treating dfn as exactly 1.0
+      xnum = (snorm() + sqrt(xnonc))**2
+      GO TO 30
+
+C     JJV case dfn > 1.0
+ 20   xnum = (2.0*sgamma((dfn-1.0)/2.0) + (snorm()+sqrt(xnonc))**2)/dfn
+
+C     xden = genchi(dfd)/dfd
+ 30   xden = 2.0*sgamma(dfd/2.0)/dfd
+      
+C     JJV changed constant so that it will not underflow at compile time
+C     JJV while not slowing generator by using double precision or logs.
+C      IF (.NOT. (xden.LE. (1.0E-38*xnum))) GO TO 40
+      IF (.NOT. (xden.LE. (1.0E-37*xnum))) GO TO 40
+      WRITE (*,*) ' GENNF - generated numbers would cause overflow'
+      WRITE (*,*) ' Numerator ',xnum,' Denominator ',xden
+C     JJV next 2 lines changed to maintain truncation of large deviates.
+C      WRITE (*,*) ' GENNF returning 1.0E38'
+C      gennf = 1.0E38
+      WRITE (*,*) ' GENNF returning 1.0E37'
+      gennf = 1.0E37
+      GO TO 50
+
+   40 gennf = xnum/xden
+   50 RETURN
+
+      END
diff --git a/libcruft/ranlib/gennor.f b/libcruft/ranlib/gennor.f
new file mode 100644
index 0000000..1291b29
--- /dev/null
+++ b/libcruft/ranlib/gennor.f
@@ -0,0 +1,61 @@
+      REAL FUNCTION gennor(av,sd)
+C**********************************************************************
+C
+C     REAL FUNCTION GENNOR( AV, SD )
+C
+C         GENerate random deviate from a NORmal distribution
+C
+C
+C                              Function
+C
+C
+C     Generates a single random deviate from a normal distribution
+C     with mean, AV, and standard deviation, SD.
+C
+C
+C                              Arguments
+C
+C
+C     AV --> Mean of the normal distribution.
+C                              REAL AV
+C
+C     SD --> Standard deviation of the normal distribution.
+C                              REAL SD
+C     JJV                      (SD >= 0)
+C
+C     GENNOR <-- Generated normal deviate.
+C                              REAL GENNOR
+C
+C
+C                              Method
+C
+C
+C     Renames SNORM from TOMS as slightly modified by BWB to use RANF
+C     instead of SUNIF.
+C
+C     For details see:
+C               Ahrens, J.H. and Dieter, U.
+C               Extensions of Forsythe's Method for Random
+C               Sampling from the Normal Distribution.
+C               Math. Comput., 27,124 (Oct. 1973), 927 - 937.
+C
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL av,sd
+C     ..
+C     .. External Functions ..
+      REAL snorm
+      EXTERNAL snorm
+C     ..
+C     .. Executable Statements ..
+C     JJV added check to ensure SD >= 0.0 
+      IF (sd.GE.0.0) GO TO 10
+      WRITE (*,*) 'SD < 0.0 in GENNOR - ABORT'
+      WRITE (*,*) 'Value of SD: ',sd
+      STOP 'SD < 0.0 in GENNOR - ABORT'
+
+ 10   gennor = sd*snorm() + av
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/genprm.f b/libcruft/ranlib/genprm.f
new file mode 100644
index 0000000..0760390
--- /dev/null
+++ b/libcruft/ranlib/genprm.f
@@ -0,0 +1,41 @@
+      SUBROUTINE genprm(iarray,larray)
+C**********************************************************************
+C
+C    SUBROUTINE GENPRM( IARRAY, LARRAY )
+C               GENerate random PeRMutation of iarray
+C
+C
+C                              Arguments
+C
+C
+C     IARRAY <--> On output IARRAY is a random permutation of its
+C                 value on input
+C                         INTEGER IARRAY( LARRAY )
+C
+C     LARRAY <--> Length of IARRAY
+C                         INTEGER LARRAY
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      INTEGER larray
+C     ..
+C     .. Array Arguments ..
+      INTEGER iarray(larray)
+C     ..
+C     .. Local Scalars ..
+      INTEGER i,itmp,iwhich
+C     ..
+C     .. External Functions ..
+      INTEGER ignuin
+      EXTERNAL ignuin
+C     ..
+C     .. Executable Statements ..
+      DO 10,i = 1,larray
+          iwhich = ignuin(i,larray)
+          itmp = iarray(iwhich)
+          iarray(iwhich) = iarray(i)
+          iarray(i) = itmp
+   10 CONTINUE
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/genunf.f b/libcruft/ranlib/genunf.f
new file mode 100644
index 0000000..55b1315
--- /dev/null
+++ b/libcruft/ranlib/genunf.f
@@ -0,0 +1,42 @@
+      REAL FUNCTION genunf(low,high)
+C**********************************************************************
+C
+C     REAL FUNCTION GENUNF( LOW, HIGH )
+C
+C               GeNerate Uniform Real between LOW and HIGH
+C
+C
+C                              Function
+C
+C
+C     Generates a real uniformly distributed between LOW and HIGH.
+C
+C
+C                              Arguments
+C
+C
+C     LOW --> Low bound (exclusive) on real value to be generated
+C                         REAL LOW
+C
+C     HIGH --> High bound (exclusive) on real value to be generated
+C                         REAL HIGH
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL high,low
+C     ..
+C     .. External Functions ..
+      REAL ranf
+      EXTERNAL ranf
+C     ..
+C     .. Executable Statements ..
+      IF (.NOT. (low.GT.high)) GO TO 10
+      WRITE (*,*) 'LOW > HIGH in GENUNF: LOW ',low,' HIGH: ',high
+      WRITE (*,*) 'Abort'
+      STOP 'LOW > High in GENUNF - Abort'
+
+   10 genunf = low + (high-low)*ranf()
+
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/getcgn.f b/libcruft/ranlib/getcgn.f
new file mode 100644
index 0000000..597f52c
--- /dev/null
+++ b/libcruft/ranlib/getcgn.f
@@ -0,0 +1,55 @@
+      SUBROUTINE getcgn(g)
+      INTEGER g
+C**********************************************************************
+C
+C      SUBROUTINE GETCGN(G)
+C                         Get GeNerator
+C
+C     Returns in G the number of the current random number generator
+C
+C
+C                              Arguments
+C
+C
+C     G <-- Number of the current random number generator (1..32)
+C                    INTEGER G
+C
+C**********************************************************************
+C
+      INTEGER curntg,numg
+      SAVE curntg
+      PARAMETER (numg=32)
+      DATA curntg/1/
+C
+      g = curntg
+      RETURN
+
+      ENTRY setcgn(g)
+C**********************************************************************
+C
+C     SUBROUTINE SETCGN( G )
+C                      Set GeNerator
+C
+C     Sets  the  current  generator to G.    All references to a generat
+C     are to the current generator.
+C
+C
+C                              Arguments
+C
+C
+C     G --> Number of the current random number generator (1..32)
+C                    INTEGER G
+C
+C**********************************************************************
+C
+C     Abort if generator number out of range
+C
+      IF (.NOT. (g.LT.0.OR.g.GT.numg)) GO TO 10
+      WRITE (*,*) ' Generator number out of range in SETCGN:',
+     +  ' Legal range is 1 to ',numg,' -- ABORT!'
+      STOP ' Generator number out of range in SETCGN'
+
+   10 curntg = g
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/getsd.f b/libcruft/ranlib/getsd.f
new file mode 100644
index 0000000..f9ad1bc
--- /dev/null
+++ b/libcruft/ranlib/getsd.f
@@ -0,0 +1,72 @@
+      SUBROUTINE getsd(iseed1,iseed2)
+C**********************************************************************
+C
+C     SUBROUTINE GETSD(G,ISEED1,ISEED2)
+C               GET SeeD
+C
+C     Returns the value of two integer seeds of the current generator
+C
+C     This  is   a  transcription from  Pascal   to  Fortran  of routine
+C     Get_State from the paper
+C
+C     L'Ecuyer, P. and  Cote,  S. "Implementing a Random Number  Package
+C     with   Splitting Facilities."  ACM  Transactions   on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C
+C     ISEED1 <- First integer seed of generator G
+C                                   INTEGER ISEED1
+C
+C     ISEED2 <- Second integer seed of generator G
+C                                   INTEGER ISEED1
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER iseed1,iseed2
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER g
+C     ..
+C     .. External Functions ..
+      LOGICAL qrgnin
+      EXTERNAL qrgnin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C     Abort unless random number generator initialized
+      IF (qrgnin()) GO TO 10
+      WRITE (*,*) ' GETSD called before random number generator ',
+     +  ' initialized -- abort!'
+      STOP ' GETSD called before random number generator initialized'
+
+   10 CALL getcgn(g)
+      iseed1 = cg1(g)
+      iseed2 = cg2(g)
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/ignbin.f b/libcruft/ranlib/ignbin.f
new file mode 100644
index 0000000..eb785ca
--- /dev/null
+++ b/libcruft/ranlib/ignbin.f
@@ -0,0 +1,325 @@
+      INTEGER FUNCTION ignbin(n,pp)
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNBIN( N, PP )
+C
+C                    GENerate BINomial random deviate
+C
+C
+C                              Function
+C
+C
+C     Generates a single random deviate from a binomial
+C     distribution whose number of trials is N and whose
+C     probability of an event in each trial is P.
+C
+C
+C                              Arguments
+C
+C
+C     N  --> The number of trials in the binomial distribution
+C            from which a random deviate is to be generated.
+C                              INTEGER N
+C     JJV                      (N >= 0)
+C
+C     PP --> The probability of an event in each trial of the
+C            binomial distribution from which a random deviate
+C            is to be generated.
+C                              REAL PP
+C     JJV                      (0.0 <= pp <= 1.0)
+C
+C     IGNBIN <-- A random deviate yielding the number of events
+C                from N independent trials, each of which has
+C                a probability of event P.
+C                              INTEGER IGNBIN
+C
+C
+C                              Note
+C
+C
+C     Uses RANF so the value of the seeds, ISEED1 and ISEED2 must be set
+C     by a call similar to the following
+C          DUM = RANSET( ISEED1, ISEED2 )
+C
+C
+C                              Method
+C
+C
+C     This is algorithm BTPE from:
+C
+C         Kachitvichyanukul, V. and Schmeiser, B. W.
+C
+C         Binomial Random Variate Generation.
+C         Communications of the ACM, 31, 2
+C         (February, 1988) 216.
+C
+C**********************************************************************
+C     SUBROUTINE BTPEC(N,PP,ISEED,JX)
+C
+C     BINOMIAL RANDOM VARIATE GENERATOR
+C     MEAN .LT. 30 -- INVERSE CDF
+C       MEAN .GE. 30 -- ALGORITHM BTPE:  ACCEPTANCE-REJECTION VIA
+C       FOUR REGION COMPOSITION.  THE FOUR REGIONS ARE A TRIANGLE
+C       (SYMMETRIC IN THE CENTER), A PAIR OF PARALLELOGRAMS (ABOVE
+C       THE TRIANGLE), AND EXPONENTIAL LEFT AND RIGHT TAILS.
+C
+C     BTPE REFERS TO BINOMIAL-TRIANGLE-PARALLELOGRAM-EXPONENTIAL.
+C     BTPEC REFERS TO BTPE AND "COMBINED."  THUS BTPE IS THE
+C       RESEARCH AND BTPEC IS THE IMPLEMENTATION OF A COMPLETE
+C       USABLE ALGORITHM.
+C     REFERENCE:  VORATAS KACHITVICHYANUKUL AND BRUCE SCHMEISER,
+C       "BINOMIAL RANDOM VARIATE GENERATION,"
+C       COMMUNICATIONS OF THE ACM, FORTHCOMING
+C     WRITTEN:  SEPTEMBER 1980.
+C       LAST REVISED:  MAY 1985, JULY 1987
+C     REQUIRED SUBPROGRAM:  RAND() -- A UNIFORM (0,1) RANDOM NUMBER
+C                           GENERATOR
+C     ARGUMENTS
+C
+C       N : NUMBER OF BERNOULLI TRIALS            (INPUT)
+C       PP : PROBABILITY OF SUCCESS IN EACH TRIAL (INPUT)
+C       ISEED:  RANDOM NUMBER SEED                (INPUT AND OUTPUT)
+C       JX:  RANDOMLY GENERATED OBSERVATION       (OUTPUT)
+C
+C     VARIABLES
+C       PSAVE: VALUE OF PP FROM THE LAST CALL TO BTPEC
+C       NSAVE: VALUE OF N FROM THE LAST CALL TO BTPEC
+C       XNP:  VALUE OF THE MEAN FROM THE LAST CALL TO BTPEC
+C
+C       P: PROBABILITY USED IN THE GENERATION PHASE OF BTPEC
+C       FFM: TEMPORARY VARIABLE EQUAL TO XNP + P
+C       M:  INTEGER VALUE OF THE CURRENT MODE
+C       FM:  FLOATING POINT VALUE OF THE CURRENT MODE
+C       XNPQ: TEMPORARY VARIABLE USED IN SETUP AND SQUEEZING STEPS
+C       P1:  AREA OF THE TRIANGLE
+C       C:  HEIGHT OF THE PARALLELOGRAMS
+C       XM:  CENTER OF THE TRIANGLE
+C       XL:  LEFT END OF THE TRIANGLE
+C       XR:  RIGHT END OF THE TRIANGLE
+C       AL:  TEMPORARY VARIABLE
+C       XLL:  RATE FOR THE LEFT EXPONENTIAL TAIL
+C       XLR:  RATE FOR THE RIGHT EXPONENTIAL TAIL
+C       P2:  AREA OF THE PARALLELOGRAMS
+C       P3:  AREA OF THE LEFT EXPONENTIAL TAIL
+C       P4:  AREA OF THE RIGHT EXPONENTIAL TAIL
+C       U:  A U(0,P4) RANDOM VARIATE USED FIRST TO SELECT ONE OF THE
+C           FOUR REGIONS AND THEN CONDITIONALLY TO GENERATE A VALUE
+C           FROM THE REGION
+C       V:  A U(0,1) RANDOM NUMBER USED TO GENERATE THE RANDOM VALUE
+C           (REGION 1) OR TRANSFORMED INTO THE VARIATE TO ACCEPT OR
+C           REJECT THE CANDIDATE VALUE
+C       IX:  INTEGER CANDIDATE VALUE
+C       X:  PRELIMINARY CONTINUOUS CANDIDATE VALUE IN REGION 2 LOGIC
+C           AND A FLOATING POINT IX IN THE ACCEPT/REJECT LOGIC
+C       K:  ABSOLUTE VALUE OF (IX-M)
+C       F:  THE HEIGHT OF THE SCALED DENSITY FUNCTION USED IN THE
+C           ACCEPT/REJECT DECISION WHEN BOTH M AND IX ARE SMALL
+C           ALSO USED IN THE INVERSE TRANSFORMATION
+C       R: THE RATIO P/Q
+C       G: CONSTANT USED IN CALCULATION OF PROBABILITY
+C       MP:  MODE PLUS ONE, THE LOWER INDEX FOR EXPLICIT CALCULATION
+C            OF F WHEN IX IS GREATER THAN M
+C       IX1:  CANDIDATE VALUE PLUS ONE, THE LOWER INDEX FOR EXPLICIT
+C             CALCULATION OF F WHEN IX IS LESS THAN M
+C       I:  INDEX FOR EXPLICIT CALCULATION OF F FOR BTPE
+C       AMAXP: MAXIMUM ERROR OF THE LOGARITHM OF NORMAL BOUND
+C       YNORM: LOGARITHM OF NORMAL BOUND
+C       ALV:  NATURAL LOGARITHM OF THE ACCEPT/REJECT VARIATE V
+C
+C       X1,F1,Z,W,Z2,X2,F2, AND W2 ARE TEMPORARY VARIABLES TO BE
+C       USED IN THE FINAL ACCEPT/REJECT TEST
+C
+C       QN: PROBABILITY OF NO SUCCESS IN N TRIALS
+C
+C     REMARK
+C       IX AND JX COULD LOGICALLY BE THE SAME VARIABLE, WHICH WOULD
+C       SAVE A MEMORY POSITION AND A LINE OF CODE.  HOWEVER, SOME
+C       COMPILERS (E.G.,CDC MNF) OPTIMIZE BETTER WHEN THE ARGUMENTS
+C       ARE NOT INVOLVED.
+C
+C     ISEED NEEDS TO BE DOUBLE PRECISION IF THE IMSL ROUTINE
+C     GGUBFS IS USED TO GENERATE UNIFORM RANDOM NUMBER, OTHERWISE
+C     TYPE OF ISEED SHOULD BE DICTATED BY THE UNIFORM GENERATOR
+C
+C**********************************************************************
+
+C
+C
+C
+C*****DETERMINE APPROPRIATE ALGORITHM AND WHETHER SETUP IS NECESSARY
+C
+C     ..
+C     .. Scalar Arguments ..
+      REAL pp
+      INTEGER n
+C     ..
+C     .. Local Scalars ..
+      REAL al,alv,amaxp,c,f,f1,f2,ffm,fm,g,p,p1,p2,p3,p4,psave,q,qn,r,u,
+     +     v,w,w2,x,x1,x2,xl,xll,xlr,xm,xnp,xnpq,xr,ynorm,z,z2
+      INTEGER i,ix,ix1,k,m,mp,nsave
+C     ..
+C     .. External Functions ..
+      REAL ranf
+      EXTERNAL ranf
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC abs,alog,amin1,iabs,int,sqrt
+C     JJV ..
+C     JJV .. Save statement ..
+      SAVE p,q,m,fm,xnp,xnpq,p1,xm,xl,xr,c,xll,xlr,p2,p3,p4,qn,r,g,
+     +     psave,nsave
+C     JJV I am including the variables in data statements
+C     ..
+C     .. Data statements ..
+C     JJV made these ridiculous starting values - the hope is that
+C     JJV no one will call this the first time with them as args
+      DATA psave,nsave/-1.0E37,-214748365/
+C     ..
+C     .. Executable Statements ..
+      IF (pp.NE.psave) GO TO 10
+      IF (n.NE.nsave) GO TO 20
+      IF (xnp-30.0.LT.0.0) GO TO 150
+      GO TO 30
+C
+C*****SETUP, PERFORM ONLY WHEN PARAMETERS CHANGE
+C
+
+C     JJV added the argument checker - involved only renaming 10
+C     JJV and 20 to the checkers and adding checkers
+C     JJV Only remaining problem - if called initially with the
+C     JJV initial values of psave and nsave, it will hang
+ 10   IF (pp.LT.0.0) STOP 'PP < 0.0 in IGNBIN - ABORT!'
+      IF (pp.GT.1.0) STOP 'PP > 1.0 in IGNBIN - ABORT!'
+      psave = pp
+      p = amin1(psave,1.-psave)
+      q = 1. - p
+ 20   IF (n.LT.0) STOP 'N < 0 in IGNBIN - ABORT!'
+      xnp = n*p
+      nsave = n
+      IF (xnp.LT.30.) GO TO 140
+      ffm = xnp + p
+      m = ffm
+      fm = m
+      xnpq = xnp*q
+      p1 = int(2.195*sqrt(xnpq)-4.6*q) + 0.5
+      xm = fm + 0.5
+      xl = xm - p1
+      xr = xm + p1
+      c = 0.134 + 20.5/ (15.3+fm)
+      al = (ffm-xl)/ (ffm-xl*p)
+      xll = al* (1.+.5*al)
+      al = (xr-ffm)/ (xr*q)
+      xlr = al* (1.+.5*al)
+      p2 = p1* (1.+c+c)
+      p3 = p2 + c/xll
+      p4 = p3 + c/xlr
+C      WRITE(6,100) N,P,P1,P2,P3,P4,XL,XR,XM,FM
+C  100 FORMAT(I15,4F18.7/5F18.7)
+C
+C*****GENERATE VARIATE
+C
+   30 u = ranf()*p4
+      v = ranf()
+C
+C     TRIANGULAR REGION
+C
+      IF (u.GT.p1) GO TO 40
+      ix = xm - p1*v + u
+      GO TO 170
+C
+C     PARALLELOGRAM REGION
+C
+   40 IF (u.GT.p2) GO TO 50
+      x = xl + (u-p1)/c
+      v = v*c + 1. - abs(xm-x)/p1
+      IF (v.GT.1. .OR. v.LE.0.) GO TO 30
+      ix = x
+      GO TO 70
+C
+C     LEFT TAIL
+C
+   50 IF (u.GT.p3) GO TO 60
+      ix = xl + alog(v)/xll
+      IF (ix.LT.0) GO TO 30
+      v = v* (u-p2)*xll
+      GO TO 70
+C
+C     RIGHT TAIL
+C
+   60 ix = xr - alog(v)/xlr
+      IF (ix.GT.n) GO TO 30
+      v = v* (u-p3)*xlr
+C
+C*****DETERMINE APPROPRIATE WAY TO PERFORM ACCEPT/REJECT TEST
+C
+   70 k = iabs(ix-m)
+      IF (k.GT.20 .AND. k.LT.xnpq/2-1) GO TO 130
+C
+C     EXPLICIT EVALUATION
+C
+      f = 1.0
+      r = p/q
+      g = (n+1)*r
+      IF (m-ix.LT.0) GO TO 80
+      IF (m-ix.EQ.0) GO TO 120
+      GO TO 100
+   80 mp = m + 1
+      DO 90 i = mp,ix
+          f = f* (g/i-r)
+   90 CONTINUE
+      GO TO 120
+
+  100 ix1 = ix + 1
+      DO 110 i = ix1,m
+          f = f/ (g/i-r)
+  110 CONTINUE
+  120 IF (v-f.LE.0) GO TO 170
+      GO TO 30
+C
+C     SQUEEZING USING UPPER AND LOWER BOUNDS ON ALOG(F(X))
+C
+  130 amaxp = (k/xnpq)* ((k* (k/3.+.625)+.1666666666666)/xnpq+.5)
+      ynorm = -k*k/ (2.*xnpq)
+      alv = alog(v)
+      IF (alv.LT.ynorm-amaxp) GO TO 170
+      IF (alv.GT.ynorm+amaxp) GO TO 30
+C
+C     STIRLING'S FORMULA TO MACHINE ACCURACY FOR
+C     THE FINAL ACCEPTANCE/REJECTION TEST
+C
+      x1 = ix + 1
+      f1 = fm + 1.
+      z = n + 1 - fm
+      w = n - ix + 1.
+      z2 = z*z
+      x2 = x1*x1
+      f2 = f1*f1
+      w2 = w*w
+      IF (alv- (xm*alog(f1/x1)+ (n-m+.5)*alog(z/w)+ (ix-
+     +    m)*alog(w*p/ (x1*q))+ (13860.- (462.- (132.- (99.-
+     +    140./f2)/f2)/f2)/f2)/f1/166320.+ (13860.- (462.- (132.- (99.-
+     +    140./z2)/z2)/z2)/z2)/z/166320.+ (13860.- (462.- (132.- (99.-
+     +    140./x2)/x2)/x2)/x2)/x1/166320.+ (13860.- (462.- (132.- (99.-
+     +    140./w2)/w2)/w2)/w2)/w/166320.) .LE. 0.) GO TO 170
+      GO TO 30
+C
+C     INVERSE CDF LOGIC FOR MEAN LESS THAN 30
+C
+  140 qn = q**n
+      r = p/q
+      g = r* (n+1)
+  150 ix = 0
+      f = qn
+      u = ranf()
+  160 IF (u.LT.f) GO TO 170
+      IF (ix.GT.110) GO TO 150
+      u = u - f
+      ix = ix + 1
+      f = f* (g/ix-r)
+      GO TO 160
+
+  170 IF (psave.GT.0.5) ix = n - ix
+      ignbin = ix
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/ignlgi.f b/libcruft/ranlib/ignlgi.f
new file mode 100644
index 0000000..4c04ee0
--- /dev/null
+++ b/libcruft/ranlib/ignlgi.f
@@ -0,0 +1,77 @@
+      INTEGER FUNCTION ignlgi()
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNLGI()
+C               GeNerate LarGe Integer
+C
+C     Returns a random integer following a uniform distribution over
+C     (1, 2147483562) using the current generator.
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     Random from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER curntg,k,s1,s2,z
+      LOGICAL qqssd
+C     ..
+C     .. External Functions ..
+      LOGICAL qrgnin
+      EXTERNAL qrgnin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn,inrgcm,rgnqsd,setall
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C
+C     IF THE RANDOM NUMBER PACKAGE HAS NOT BEEN INITIALIZED YET, DO SO.
+C     IT CAN BE INITIALIZED IN ONE OF TWO WAYS : 1) THE FIRST CALL TO
+C     THIS ROUTINE  2) A CALL TO SETALL.
+C
+      IF (.NOT. (qrgnin())) CALL inrgcm()
+      CALL rgnqsd(qqssd)
+      IF (.NOT. (qqssd)) CALL setall(1234567890,123456789)
+C
+C     Get Current Generator
+C
+      CALL getcgn(curntg)
+      s1 = cg1(curntg)
+      s2 = cg2(curntg)
+      k = s1/53668
+      s1 = a1* (s1-k*53668) - k*12211
+      IF (s1.LT.0) s1 = s1 + m1
+      k = s2/52774
+      s2 = a2* (s2-k*52774) - k*3791
+      IF (s2.LT.0) s2 = s2 + m2
+      cg1(curntg) = s1
+      cg2(curntg) = s2
+      z = s1 - s2
+      IF (z.LT.1) z = z + m1 - 1
+      IF (qanti(curntg)) z = m1 - z
+      ignlgi = z
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/ignnbn.f b/libcruft/ranlib/ignnbn.f
new file mode 100644
index 0000000..f58f4ba
--- /dev/null
+++ b/libcruft/ranlib/ignnbn.f
@@ -0,0 +1,78 @@
+      INTEGER FUNCTION ignnbn(n,p)
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNNBN( N, P )
+C
+C                GENerate Negative BiNomial random deviate
+C
+C
+C                              Function
+C
+C
+C     Generates a single random deviate from a negative binomial
+C     distribution.
+C
+C
+C                              Arguments
+C
+C
+C     N  --> Required number of events.
+C                              INTEGER N
+C     JJV                      (N > 0)
+C
+C     P  --> The probability of an event during a Bernoulli trial.
+C                              REAL P
+C     JJV                      (0.0 < P < 1.0)
+C
+C
+C
+C                              Method
+C
+C
+C     Algorithm from page 480 of
+C
+C     Devroye, Luc
+C
+C     Non-Uniform Random Variate Generation.  Springer-Verlag,
+C     New York, 1986.
+C
+C**********************************************************************
+C     ..
+C     .. Scalar Arguments ..
+      REAL p
+      INTEGER n
+C     ..
+C     .. Local Scalars ..
+      REAL y,a,r
+C     ..
+C     .. External Functions ..
+C     JJV changed to call SGAMMA directly
+C     REAL gengam
+      REAL sgamma
+      INTEGER ignpoi
+C      EXTERNAL gengam,ignpoi
+      EXTERNAL sgamma,ignpoi
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC real
+C     ..
+C     .. Executable Statements ..
+C     Check Arguments
+C     JJV changed argumnet checker to abort if N <= 0
+      IF (n.LE.0) STOP 'N <= 0 in IGNNBN'
+      IF (p.LE.0.0) STOP 'P <= 0.0 in IGNNBN'
+      IF (p.GE.1.0) STOP 'P >= 1.0 in IGNNBN'
+
+C     Generate Y, a random gamma (n,(1-p)/p) variable
+C     JJV Note: the above parametrization is consistent with Devroye,
+C     JJV       but gamma (p/(1-p),n) is the equivalent in our code
+ 10   r = real(n)
+      a = p/ (1.0-p)
+C      y = gengam(a,r)
+      y = sgamma(r)/a
+
+C     Generate a random Poisson(y) variable
+      ignnbn = ignpoi(y)
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/ignpoi.f b/libcruft/ranlib/ignpoi.f
new file mode 100644
index 0000000..a176c0e
--- /dev/null
+++ b/libcruft/ranlib/ignpoi.f
@@ -0,0 +1,284 @@
+      INTEGER FUNCTION ignpoi(mu)
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNPOI( MU )
+C
+C                    GENerate POIsson random deviate
+C
+C
+C                              Function
+C
+C
+C     Generates a single random deviate from a Poisson
+C     distribution with mean MU.
+C
+C
+C                              Arguments
+C
+C
+C     MU --> The mean of the Poisson distribution from which
+C            a random deviate is to be generated.
+C                              REAL MU
+C     JJV                    (MU >= 0.0)
+C
+C     IGNPOI <-- The random deviate.
+C                              INTEGER IGNPOI (non-negative)
+C
+C
+C                              Method
+C
+C
+C     Renames KPOIS from TOMS as slightly modified by BWB to use RANF
+C     instead of SUNIF.
+C
+C     For details see:
+C
+C               Ahrens, J.H. and Dieter, U.
+C               Computer Generation of Poisson Deviates
+C               From Modified Normal Distributions.
+C               ACM Trans. Math. Software, 8, 2
+C               (June 1982),163-179
+C
+C**********************************************************************
+C**********************************************************************C
+C**********************************************************************C
+C                                                                      C
+C                                                                      C
+C     P O I S S O N  DISTRIBUTION                                      C
+C                                                                      C
+C                                                                      C
+C**********************************************************************C
+C**********************************************************************C
+C                                                                      C
+C     FOR DETAILS SEE:                                                 C
+C                                                                      C
+C               AHRENS, J.H. AND DIETER, U.                            C
+C               COMPUTER GENERATION OF POISSON DEVIATES                C
+C               FROM MODIFIED NORMAL DISTRIBUTIONS.                    C
+C               ACM TRANS. MATH. SOFTWARE, 8,2 (JUNE 1982), 163 - 179. C
+C                                                                      C
+C     (SLIGHTLY MODIFIED VERSION OF THE PROGRAM IN THE ABOVE ARTICLE)  C
+C                                                                      C
+C**********************************************************************C
+C
+C      INTEGER FUNCTION IGNPOI(IR,MU)
+C
+C     INPUT:  IR=CURRENT STATE OF BASIC RANDOM NUMBER GENERATOR
+C             MU=MEAN MU OF THE POISSON DISTRIBUTION
+C     OUTPUT: IGNPOI=SAMPLE FROM THE POISSON-(MU)-DISTRIBUTION
+C
+C
+C
+C     MUPREV=PREVIOUS MU, MUOLD=MU AT LAST EXECUTION OF STEP P OR CASE B
+C     TABLES: COEFFICIENTS A0-A7 FOR STEP F. FACTORIALS FACT
+C     COEFFICIENTS A(K) - FOR PX = FK*V*V*SUM(A(K)*V**K)-DEL
+C
+C
+C
+C     SEPARATION OF CASES A AND B
+C
+C     .. Scalar Arguments ..
+      REAL mu
+C     ..
+C     .. Local Scalars ..
+      REAL a0,a1,a2,a3,a4,a5,a6,a7,b1,b2,c,c0,c1,c2,c3,d,del,difmuk,e,
+     +     fk,fx,fy,g,muold,muprev,omega,p,p0,px,py,q,s,t,u,v,x,xx
+C     JJV I added a variable 'll' here - it is the 'l' for CASE A
+      INTEGER j,k,kflag,l,ll,m
+C     ..
+C     .. Local Arrays ..
+      REAL fact(10),pp(35)
+C     ..
+C     .. External Functions ..
+      REAL ranf,sexpo,snorm
+      EXTERNAL ranf,sexpo,snorm
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC abs,alog,exp,float,ifix,max0,min0,sign,sqrt
+C     ..
+C     JJV added this for case: mu unchanged
+C     .. Save statement ..
+      SAVE s, d, l, ll, omega, c3, c2, c1, c0, c, m, p, q, p0,
+     +     a0, a1, a2, a3, a4, a5, a6, a7, fact, muprev, muold
+C     ..
+C     JJV end addition - I am including vars in Data statements
+C     .. Data statements ..
+C     JJV changed initial values of MUPREV and MUOLD to -1.0E37
+C     JJV if no one calls IGNPOI with MU = -1.0E37 the first time,
+C     JJV the code shouldn't break
+      DATA muprev,muold/-1.0E37,-1.0E37/
+      DATA a0,a1,a2,a3,a4,a5,a6,a7/-.5,.3333333,-.2500068,.2000118,
+     +     -.1661269,.1421878,-.1384794,.1250060/
+      DATA fact/1.,1.,2.,6.,24.,120.,720.,5040.,40320.,362880./
+C     ..
+C     .. Executable Statements ..
+
+      IF (mu.EQ.muprev) GO TO 10
+      IF (mu.LT.10.0) GO TO 120
+C
+C     C A S E  A. (RECALCULATION OF S,D,LL IF MU HAS CHANGED)
+C
+C     JJV This is the case where I changed 'l' to 'll'
+C     JJV Here 'll' is set once and used in a comparison once
+
+      muprev = mu
+      s = sqrt(mu)
+      d = 6.0*mu*mu
+C
+C             THE POISSON PROBABILITIES PK EXCEED THE DISCRETE NORMAL
+C             PROBABILITIES FK WHENEVER K >= M(MU). LL=IFIX(MU-1.1484)
+C             IS AN UPPER BOUND TO M(MU) FOR ALL MU >= 10 .
+C
+      ll = ifix(mu-1.1484)
+C
+C     STEP N. NORMAL SAMPLE - SNORM(IR) FOR STANDARD NORMAL DEVIATE
+C
+   10 g = mu + s*snorm()
+      IF (g.LT.0.0) GO TO 20
+      ignpoi = ifix(g)
+C
+C     STEP I. IMMEDIATE ACCEPTANCE IF IGNPOI IS LARGE ENOUGH
+C
+      IF (ignpoi.GE.ll) RETURN
+C
+C     STEP S. SQUEEZE ACCEPTANCE - SUNIF(IR) FOR (0,1)-SAMPLE U
+C
+      fk = float(ignpoi)
+      difmuk = mu - fk
+      u = ranf()
+      IF (d*u.GE.difmuk*difmuk*difmuk) RETURN
+C
+C     STEP P. PREPARATIONS FOR STEPS Q AND H.
+C             (RECALCULATIONS OF PARAMETERS IF NECESSARY)
+C             .3989423=(2*PI)**(-.5)  .416667E-1=1./24.  .1428571=1./7.
+C             THE QUANTITIES B1, B2, C3, C2, C1, C0 ARE FOR THE HERMITE
+C             APPROXIMATIONS TO THE DISCRETE NORMAL PROBABILITIES FK.
+C             C=.1069/MU GUARANTEES MAJORIZATION BY THE 'HAT'-FUNCTION.
+C
+   20 IF (mu.EQ.muold) GO TO 30
+      muold = mu
+      omega = .3989423/s
+      b1 = .4166667E-1/mu
+      b2 = .3*b1*b1
+      c3 = .1428571*b1*b2
+      c2 = b2 - 15.*c3
+      c1 = b1 - 6.*b2 + 45.*c3
+      c0 = 1. - b1 + 3.*b2 - 15.*c3
+      c = .1069/mu
+   30 IF (g.LT.0.0) GO TO 50
+C
+C             'SUBROUTINE' F IS CALLED (KFLAG=0 FOR CORRECT RETURN)
+C
+      kflag = 0
+      GO TO 70
+C
+C     STEP Q. QUOTIENT ACCEPTANCE (RARE CASE)
+C
+   40 IF (fy-u*fy.LE.py*exp(px-fx)) RETURN
+C
+C     STEP E. EXPONENTIAL SAMPLE - SEXPO(IR) FOR STANDARD EXPONENTIAL
+C             DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT'
+C             (IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.)
+C
+   50 e = sexpo()
+      u = ranf()
+      u = u + u - 1.0
+      t = 1.8 + sign(e,u)
+      IF (t.LE. (-.6744)) GO TO 50
+      ignpoi = ifix(mu+s*t)
+      fk = float(ignpoi)
+      difmuk = mu - fk
+C
+C             'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN)
+C
+      kflag = 1
+      GO TO 70
+C
+C     STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION)
+C
+   60 IF (c*abs(u).GT.py*exp(px+e)-fy*exp(fx+e)) GO TO 50
+      RETURN
+C
+C     STEP F. 'SUBROUTINE' F. CALCULATION OF PX,PY,FX,FY.
+C             CASE IGNPOI .LT. 10 USES FACTORIALS FROM TABLE FACT
+C
+   70 IF (ignpoi.GE.10) GO TO 80
+      px = -mu
+      py = mu**ignpoi/fact(ignpoi+1)
+      GO TO 110
+C
+C             CASE IGNPOI .GE. 10 USES POLYNOMIAL APPROXIMATION
+C             A0-A7 FOR ACCURACY WHEN ADVISABLE
+C             .8333333E-1=1./12.  .3989423=(2*PI)**(-.5)
+C
+   80 del = .8333333E-1/fk
+      del = del - 4.8*del*del*del
+      v = difmuk/fk
+      IF (abs(v).LE.0.25) GO TO 90
+      px = fk*alog(1.0+v) - difmuk - del
+      GO TO 100
+
+   90 px = fk*v*v* (((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0) -
+     +     del
+  100 py = .3989423/sqrt(fk)
+  110 x = (0.5-difmuk)/s
+      xx = x*x
+      fx = -0.5*xx
+      fy = omega* (((c3*xx+c2)*xx+c1)*xx+c0)
+      IF (kflag.LE.0) GO TO 40
+      GO TO 60
+C
+C     C A S E  B. (START NEW TABLE AND CALCULATE P0 IF NECESSARY)
+C
+C     JJV changed MUPREV assignment from 0.0 to initial value
+  120 muprev = -1.0E37
+      IF (mu.EQ.muold) GO TO 130
+C     JJV added argument checker here
+      IF (mu.GE.0.0) GO TO 125
+      WRITE (*,*) 'MU < 0 in IGNPOI - ABORT'
+      WRITE (*,*) 'Value of MU: ',mu
+      STOP 'MU < 0 in IGNPOI - ABORT'
+C     JJV added line label here
+ 125  muold = mu
+      m = max0(1,ifix(mu))
+      l = 0
+      p = exp(-mu)
+      q = p
+      p0 = p
+C
+C     STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
+C
+  130 u = ranf()
+      ignpoi = 0
+      IF (u.LE.p0) RETURN
+C
+C     STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE
+C             PP-TABLE OF CUMULATIVE POISSON PROBABILITIES
+C             (0.458=PP(9) FOR MU=10)
+C
+      IF (l.EQ.0) GO TO 150
+      j = 1
+      IF (u.GT.0.458) j = min0(l,m)
+      DO 140 k = j,l
+          IF (u.LE.pp(k)) GO TO 180
+  140 CONTINUE
+      IF (l.EQ.35) GO TO 130
+C
+C     STEP C. CREATION OF NEW POISSON PROBABILITIES P
+C             AND THEIR CUMULATIVES Q=PP(K)
+C
+  150 l = l + 1
+      DO 160 k = l,35
+          p = p*mu/float(k)
+          q = q + p
+          pp(k) = q
+          IF (u.LE.q) GO TO 170
+  160 CONTINUE
+      l = 35
+      GO TO 130
+
+  170 l = k
+  180 ignpoi = k
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/ignuin.f b/libcruft/ranlib/ignuin.f
new file mode 100644
index 0000000..7a0cfc6
--- /dev/null
+++ b/libcruft/ranlib/ignuin.f
@@ -0,0 +1,95 @@
+      INTEGER FUNCTION ignuin(low,high)
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNUIN( LOW, HIGH )
+C
+C               GeNerate Uniform INteger
+C
+C
+C                              Function
+C
+C
+C     Generates an integer uniformly distributed between LOW and HIGH.
+C
+C
+C                              Arguments
+C
+C
+C     LOW --> Low bound (inclusive) on integer value to be generated
+C                         INTEGER LOW
+C
+C     HIGH --> High bound (inclusive) on integer value to be generated
+C                         INTEGER HIGH
+C
+C
+C                              Note
+C
+C
+C     If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and
+C     stops the program.
+C
+C**********************************************************************
+
+C     IGNLGI generates integers between 1 and 2147483562
+C     MAXNUM is 1 less than maximum generable value
+C     .. Parameters ..
+      INTEGER maxnum
+      PARAMETER (maxnum=2147483561)
+      CHARACTER*(*) err1,err2
+      PARAMETER (err1='LOW > HIGH in IGNUIN',
+     +          err2=' ( HIGH - LOW ) > 2,147,483,561 in IGNUIN')
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER high,low
+C     ..
+C     .. Local Scalars ..
+      INTEGER err,ign,maxnow,range,ranp1
+C     ..
+C     .. External Functions ..
+      INTEGER ignlgi
+      EXTERNAL ignlgi
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC mod
+C     ..
+C     .. Executable Statements ..
+      IF (.NOT. (low.GT.high)) GO TO 10
+      err = 1
+C      ABORT-PROGRAM
+      GO TO 80
+
+   10 range = high - low
+      IF (.NOT. (range.GT.maxnum)) GO TO 20
+      err = 2
+C      ABORT-PROGRAM
+      GO TO 80
+
+   20 IF (.NOT. (low.EQ.high)) GO TO 30
+      ignuin = low
+      RETURN
+
+C     Number to be generated should be in range 0..RANGE
+C     Set MAXNOW so that the number of integers in 0..MAXNOW is an
+C     integral multiple of the number in 0..RANGE
+
+   30 ranp1 = range + 1
+      maxnow = (maxnum/ranp1)*ranp1
+   40 ign = ignlgi() - 1
+      IF (.NOT. (ign.LE.maxnow)) GO TO 40
+      ignuin = low + mod(ign,ranp1)
+      RETURN
+
+   80 IF (.NOT. (err.EQ.1)) GO TO 90
+      WRITE (*,*) err1
+      GO TO 100
+
+C     TO ABORT-PROGRAM
+   90 WRITE (*,*) err2
+  100 WRITE (*,*) ' LOW: ',low,' HIGH: ',high
+      WRITE (*,*) ' Abort on Fatal ERROR'
+      IF (.NOT. (err.EQ.1)) GO TO 110
+      STOP 'LOW > HIGH in IGNUIN'
+
+  110 STOP ' ( HIGH - LOW ) > 2,147,483,561 in IGNUIN'
+
+  120 END
diff --git a/libcruft/ranlib/initgn.f b/libcruft/ranlib/initgn.f
new file mode 100644
index 0000000..8209aed
--- /dev/null
+++ b/libcruft/ranlib/initgn.f
@@ -0,0 +1,92 @@
+      SUBROUTINE initgn(isdtyp)
+C**********************************************************************
+C
+C     SUBROUTINE INITGN(ISDTYP)
+C          INIT-ialize current G-e-N-erator
+C
+C     Reinitializes the state of the current generator
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     Init_Generator from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C     ISDTYP -> The state to which the generator is to be set
+C
+C          ISDTYP = -1  => sets the seeds to their initial value
+C          ISDTYP =  0  => sets the seeds to the first value of
+C                          the current block
+C          ISDTYP =  1  => sets the seeds to the first value of
+C                          the next block
+C
+C                                   INTEGER ISDTYP
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER isdtyp
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER g
+C     ..
+C     .. External Functions ..
+      LOGICAL qrgnin
+      INTEGER mltmod
+      EXTERNAL qrgnin,mltmod
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C     Abort unless random number generator initialized
+      IF (qrgnin()) GO TO 10
+      WRITE (*,*) ' INITGN called before random number generator ',
+     +  ' initialized -- abort!'
+      STOP ' INITGN called before random number generator initialized'
+
+   10 CALL getcgn(g)
+      IF ((-1).NE. (isdtyp)) GO TO 20
+      lg1(g) = ig1(g)
+      lg2(g) = ig2(g)
+      GO TO 50
+
+   20 IF ((0).NE. (isdtyp)) GO TO 30
+      CONTINUE
+      GO TO 50
+C     do nothing
+   30 IF ((1).NE. (isdtyp)) GO TO 40
+      lg1(g) = mltmod(a1w,lg1(g),m1)
+      lg2(g) = mltmod(a2w,lg2(g),m2)
+      GO TO 50
+
+   40 STOP 'ISDTYP NOT IN RANGE'
+
+   50 cg1(g) = lg1(g)
+      cg2(g) = lg2(g)
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/inrgcm.f b/libcruft/ranlib/inrgcm.f
new file mode 100644
index 0000000..1a2ac13
--- /dev/null
+++ b/libcruft/ranlib/inrgcm.f
@@ -0,0 +1,70 @@
+      SUBROUTINE inrgcm()
+C**********************************************************************
+C
+C     SUBROUTINE INRGCM()
+C          INitialize Random number Generator CoMmon
+C
+C
+C                              Function
+C
+C
+C     Initializes common area  for random number  generator.  This saves
+C     the  nuisance  of  a  BLOCK DATA  routine  and the  difficulty  of
+C     assuring that the routine is loaded with the other routines.
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER i
+      LOGICAL qdum
+C     ..
+C     .. External Functions ..
+      LOGICAL qrgnsn
+      EXTERNAL qrgnsn
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C     V=20;                            W=30;
+C
+C     A1W = MOD(A1**(2**W),M1)         A2W = MOD(A2**(2**W),M2)
+C     A1VW = MOD(A1**(2**(V+W)),M1)    A2VW = MOD(A2**(2**(V+W)),M2)
+C
+C   If V or W is changed A1W, A2W, A1VW, and A2VW need to be recomputed.
+C    An efficient way to precompute a**(2*j) MOD m is to start with
+C    a and square it j times modulo m using the function MLTMOD.
+C
+      m1 = 2147483563
+      m2 = 2147483399
+      a1 = 40014
+      a2 = 40692
+      a1w = 1033780774
+      a2w = 1494757890
+      a1vw = 2082007225
+      a2vw = 784306273
+      DO 10,i = 1,numg
+          qanti(i) = .FALSE.
+   10 CONTINUE
+C
+C     Tell the world that common has been initialized
+C
+      qdum = qrgnsn(.TRUE.)
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/lennob.f b/libcruft/ranlib/lennob.f
new file mode 100644
index 0000000..e7c56c3
--- /dev/null
+++ b/libcruft/ranlib/lennob.f
@@ -0,0 +1,36 @@
+      INTEGER FUNCTION lennob(string)
+      IMPLICIT INTEGER (a-p,r-z),LOGICAL (q)
+C**********************************************************************
+C
+C     INTEGER FUNCTION LENNOB( STRING )
+C                LENgth NOt counting trailing Blanks
+C
+C
+C                              Function
+C
+C
+C     Returns the length of STRING up to and including the last
+C     non-blank character.
+C
+C
+C                              Arguments
+C
+C
+C     STRING --> String whose length not counting trailing blanks
+C                is returned.
+C
+C**********************************************************************
+      CHARACTER*(*) string
+
+      end = len(string)
+      DO 20,i = end,1,-1
+          IF (.NOT. (string(i:i).NE.' ')) GO TO 10
+          lennob = i
+          RETURN
+
+   10     CONTINUE
+   20 CONTINUE
+      lennob = 0
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/mltmod.f b/libcruft/ranlib/mltmod.f
new file mode 100644
index 0000000..9a4bb2b
--- /dev/null
+++ b/libcruft/ranlib/mltmod.f
@@ -0,0 +1,106 @@
+      INTEGER FUNCTION mltmod(a,s,m)
+C**********************************************************************
+C
+C     INTEGER FUNCTION MLTMOD(A,S,M)
+C
+C                    Returns (A*S) MOD M
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     MULtMod_Decompos from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C     A, S, M  -->
+C                         INTEGER A,S,M
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER h
+      PARAMETER (h=32768)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER a,m,s
+C     ..
+C     .. Local Scalars ..
+      INTEGER a0,a1,k,p,q,qh,rh
+C     ..
+C     .. Executable Statements ..
+C
+C     H = 2**((b-2)/2) where b = 32 because we are using a 32 bit
+C      machine. On a different machine recompute H
+C
+      IF (.NOT. (a.LE.0.OR.a.GE.m.OR.s.LE.0.OR.s.GE.m)) GO TO 10
+      WRITE (*,*) ' A, M, S out of order in MLTMOD - ABORT!'
+      WRITE (*,*) ' A = ',a,' S = ',s,' M = ',m
+      WRITE (*,*) ' MLTMOD requires: 0 < A < M; 0 < S < M'
+      STOP ' A, M, S out of order in MLTMOD - ABORT!'
+
+   10 IF (.NOT. (a.LT.h)) GO TO 20
+      a0 = a
+      p = 0
+      GO TO 120
+
+   20 a1 = a/h
+      a0 = a - h*a1
+      qh = m/h
+      rh = m - h*qh
+      IF (.NOT. (a1.GE.h)) GO TO 50
+      a1 = a1 - h
+      k = s/qh
+      p = h* (s-k*qh) - k*rh
+   30 IF (.NOT. (p.LT.0)) GO TO 40
+      p = p + m
+      GO TO 30
+
+   40 GO TO 60
+
+   50 p = 0
+C
+C     P = (A2*S*H)MOD M
+C
+   60 IF (.NOT. (a1.NE.0)) GO TO 90
+      q = m/a1
+      k = s/q
+      p = p - k* (m-a1*q)
+      IF (p.GT.0) p = p - m
+      p = p + a1* (s-k*q)
+   70 IF (.NOT. (p.LT.0)) GO TO 80
+      p = p + m
+      GO TO 70
+
+   80 CONTINUE
+   90 k = p/qh
+C
+C     P = ((A2*H + A1)*S)MOD M
+C
+      p = h* (p-k*qh) - k*rh
+  100 IF (.NOT. (p.LT.0)) GO TO 110
+      p = p + m
+      GO TO 100
+
+  110 CONTINUE
+  120 IF (.NOT. (a0.NE.0)) GO TO 150
+C
+C     P = ((A2*H + A1)*H*S)MOD M
+C
+      q = m/a0
+      k = s/q
+      p = p - k* (m-a0*q)
+      IF (p.GT.0) p = p - m
+      p = p + a0* (s-k*q)
+  130 IF (.NOT. (p.LT.0)) GO TO 140
+      p = p + m
+      GO TO 130
+
+  140 CONTINUE
+  150 mltmod = p
+C
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/phrtsd.f b/libcruft/ranlib/phrtsd.f
new file mode 100644
index 0000000..466e310
--- /dev/null
+++ b/libcruft/ranlib/phrtsd.f
@@ -0,0 +1,92 @@
+      SUBROUTINE phrtsd(phrase,seed1,seed2)
+C**********************************************************************
+C
+C     SUBROUTINE PHRTSD( PHRASE, SEED1, SEED2 )
+C               PHRase To SeeDs
+C
+C
+C                              Function
+C
+C
+C     Uses a phrase (character string) to generate two seeds for the RGN
+C     random number generator.
+C
+C
+C                              Arguments
+C
+C
+C     PHRASE --> Phrase to be used for random number generation
+C                         CHARACTER*(*) PHRASE
+C
+C     SEED1 <-- First seed for RGN generator
+C                         INTEGER SEED1
+C
+C     SEED2 <-- Second seed for RGN generator
+C                         INTEGER SEED2
+C
+C
+C                              Note
+C
+C
+C     Trailing blanks are eliminated before the seeds are generated.
+C
+C     Generated seed values will fall in the range 1..2^30
+C     (1..1,073,741,824)
+C
+C**********************************************************************
+C     .. Parameters ..
+      CHARACTER*(*) table
+      PARAMETER (table='abcdefghijklmnopqrstuvwxyz'//
+     +          'ABCDEFGHIJKLMNOPQRSTUVWXYZ'//'0123456789'//
+     +          '!@#$%^&*()_+[];:''"<>?,./')
+      INTEGER twop30
+      PARAMETER (twop30=1073741824)
+      INTEGER sixty4
+      PARAMETER (sixty4=64)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER seed1,seed2
+      CHARACTER phrase* (*)
+C     ..
+C     .. Local Scalars ..
+      INTEGER i,ichr,j,lphr,idxval
+C     ..
+C     .. Local Arrays ..
+      INTEGER shift(0:4),values(5)
+C     ..
+C     .. External Functions ..
+      INTEGER lennob
+      EXTERNAL lennob
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC index,mod
+C     ..
+C     JJV added Save statement for variable in Data statement 
+C     .. Save statements ..
+      SAVE shift
+C     JJV end addition 
+C     .. 
+C     .. Data statements ..
+      DATA shift/1,64,4096,262144,16777216/
+C     ..
+C     .. Executable Statements ..
+      seed1 = 1234567890
+      seed2 = 123456789
+      lphr = lennob(phrase)
+      IF (lphr.LT.1) RETURN
+      DO 30,i = 1,lphr
+          idxval = index(table,phrase(i:i))
+          ichr = mod(idxval,sixty4)
+          IF (ichr.EQ.0) ichr = 63
+          DO 10,j = 1,5
+              values(j) = ichr - j
+              IF (values(j).LT.1) values(j) = values(j) + 63
+   10     CONTINUE
+          DO 20,j = 1,5
+              seed1 = mod(seed1+shift(j-1)*values(j),twop30)
+              seed2 = mod(seed2+shift(j-1)*values(6-j),twop30)
+   20     CONTINUE
+   30 CONTINUE
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/qrgnin.f b/libcruft/ranlib/qrgnin.f
new file mode 100644
index 0000000..b82f1f9
--- /dev/null
+++ b/libcruft/ranlib/qrgnin.f
@@ -0,0 +1,48 @@
+      LOGICAL FUNCTION qrgnin()
+C**********************************************************************
+C
+C     LOGICAL FUNCTION QRGNIN()
+C               Q Random GeNerators INitialized?
+C
+C     A trivial routine to determine whether or not the random
+C     number generator has been initialized.  Returns .TRUE. if
+C     it has, else .FALSE.
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      LOGICAL qvalue
+C     ..
+C     .. Local Scalars ..
+      LOGICAL qinit
+C     ..
+C     .. Entry Points ..
+      LOGICAL qrgnsn
+C     ..
+C     .. Save statement ..
+      SAVE qinit
+C     ..
+C     .. Data statements ..
+      DATA qinit/.FALSE./
+C     ..
+C     .. Executable Statements ..
+      qrgnin = qinit
+      RETURN
+
+      ENTRY qrgnsn(qvalue)
+C**********************************************************************
+C
+C     LOGICAL FUNCTION QRGNSN( QVALUE )
+C               Q Random GeNerators Set whether iNitialized
+C
+C     Sets state of whether random number generator is initialized
+C     to QVALUE.
+C
+C     This routine is actually an entry in QRGNIN, hence it is a
+C     logical function.  It returns the (meaningless) value .TRUE.
+C
+C**********************************************************************
+      qinit = qvalue
+      qrgnsn = .TRUE.
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/randlib.chs b/libcruft/ranlib/randlib.chs
new file mode 100644
index 0000000..8a5b885
--- /dev/null
+++ b/libcruft/ranlib/randlib.chs
@@ -0,0 +1,368 @@
+                    SUMMARY OF ROUTINES IN RANDLIB
+
+0. Base Level Routines to Set and Obtain Values of Seeds
+
+(These should be the only base level routines used by  those who don't
+need multiple generators with blocks of numbers.)
+
+C**********************************************************************
+C
+C      SUBROUTINE SETALL(ISEED1,ISEED2)
+C               SET ALL random number generators
+C      INTEGER ISEED1, ISEED2
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     SUBROUTINE GETSD(ISEED1,ISEED2)
+C               GET SeeD
+C     INTEGER ISEED1, ISEED2
+C
+C     Returns the value of two integer seeds of the current generator
+C     in ISEED1, ISEED2
+C
+C**********************************************************************
+
+I. Higher Level Routines
+
+C**********************************************************************
+C
+C     REAL FUNCTION GENBET( A, B )
+C               GeNerate BETa random deviate
+C     REAL A,B
+C
+C     Returns a single random deviate from the beta distribution with
+C     parameters A and B.  The density of the beta is
+C               x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENCHI( DF )
+C                Generate random value of CHIsquare variable
+C     REAL DF
+C
+C     Generates random deviate from the distribution of a chisquare
+C     with DF degrees of freedom random variable.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENEXP( AV )
+C                    GENerate EXPonential random deviate
+C     REAL AV
+C
+C     Generates a single random deviate from an exponential
+C     distribution with mean AV.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENF( DFN, DFD )
+C                GENerate random deviate from the F distribution
+C     REAL DFN, DFD
+C
+C     Generates a random deviate from the F (variance ratio)
+C     distribution with DFN degrees of freedom in the numerator
+C     and DFD degrees of freedom in the denominator.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENGAM( A, R )
+C           GENerates random deviates from GAMma distribution
+C     REAL A, R
+C
+C     Generates random deviates from the gamma distribution whose
+C     density is
+C          (A**R)/Gamma(R) * X**(R-1) * Exp(-A*X)
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     SUBROUTINE GENMN(PARM,X,WORK)
+C              GENerate Multivariate Normal random deviate
+C     REAL PARM(*), X(*), WORK(*)
+C
+C     PARM is set by SETGMN which must be called prior to GENMN.  The
+C     generated deviates are placed in X.  WORK is a work array of the
+C     same size as X.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     SUBROUTINE GENMUL( N, P, NCAT, IX )
+C              GENerate MULtinomial random deviate
+C     REAL P(*)
+C     INTEGER N, NCAT, IX(*)
+C
+C     Generates deviates from a Multinomial distribution with NCAT
+C     categories.  P specifies the probability of an event in each
+C     category. The generated deviates are placed in IX.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENNCH( DF, XNONC )
+C           Generate random value of Noncentral CHIsquare variable
+C     REAL DF, XNONC
+C
+C     Generates random deviate  from the  distribution  of a  noncentral
+C     chisquare with DF degrees  of freedom and noncentrality  parameter
+C     XNONC.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENNF( DFN, DFD, XNONC )
+C           GENerate random deviate from the Noncentral F distribution
+C     REAL DFN, DFD, XNONC
+C
+C     Generates a random deviate from the  noncentral F (variance ratio)
+C     distribution with DFN degrees of freedom in the numerator, and DFD
+C     degrees of freedom in the denominator, and noncentrality parameter
+C     XNONC.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENNOR( AV, SD )
+C         GENerate random deviate from a NORmal distribution
+C     REAL AV, SD
+C
+C     Generates a single random deviate from a normal distribution
+C     with mean, AV, and standard deviation, SD.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C    SUBROUTINE GENPRM( IARRAY, LARRAY )
+C               GENerate random PeRMutation of iarray
+C    INTEGER IARRAY(LARRAY), LARRAY
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION GENUNF( LOW, HIGH )
+C               GeNerate Uniform Real between LOW and HIGH
+C     REAL LOW, HIGH
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNBIN( N, P )
+C                    GENerate BINomial random deviate
+C     INTEGER N
+C     REAL P
+C
+C     Returns a single random deviate from a binomial
+C     distribution whose number of trials is N and whose
+C     probability of an event in each trial is P.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNNBN( N, P )
+C               GENerate Negative BiNomial random deviate
+C     INTEGER N
+C     REAL P
+C
+C     Returns a single random deviate from a negative binomial
+C     distribution with number of events N and whose
+C     probability of an event in each trial is P.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNPOI( AV )
+C                    GENerate POIsson random deviate
+C     REAL AV
+C
+C     Generates a single random deviate from a Poisson
+C     distribution with mean AV.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNUIN( LOW, HIGH )
+C               GeNerate Uniform INteger
+C     INTEGER LOW, HIGH
+C
+C     Generates an integer uniformly distributed between LOW and HIGH.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     SUBROUTINE PHRTSD( PHRASE, SEED1, SEED2 )
+C               PHRase To SeeDs
+C     CHARACTER*(*) PHRASE
+C     INTEGER SEED1, SEED2
+C
+C     Uses a phrase (character string) to generate two seeds for the RGN
+C     random number generator.
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     REAL FUNCTION RANF()
+C                RANDom number generator as a Function
+C
+C     Returns a random floating point number from a uniform distribution
+C     over 0 - 1 (endpoints of this interval are not returned) using the
+C     current generator
+C
+C**********************************************************************
+C**********************************************************************
+C
+C     SUBROUTINE SETGMN( MEANV, COVM, LDCOVM, P, PARM)
+C            SET Generate Multivariate Normal random deviate
+C     INTEGER LDCOVM, P
+C     REAL MEANV(P), COVM(LDCOVM,P), PARM(P*(P+3)/2 + 1)
+C
+C     P is the length of normal vectors to be generated, MEANV
+C     is the vector of their means and COVM(1:P,1:P) is their variance
+C     covariance matrix.  LDCOVM is the leading actual dimension of
+C     COVM, which this routine needs to know although only the
+C     (1:P,1:P) slice of COVM is used.
+C     Places information necessary to generate the deviates in PARM.
+C
+C**********************************************************************
+
+II. Uniform Generator and Associated Routines
+
+
+      A. SETTING THE SEED OF ALL GENERATORS
+
+C**********************************************************************
+C
+C      SUBROUTINE SETALL(ISEED1,ISEED2)
+C               SET ALL random number generators
+C      INTEGER ISEED1, ISEED2
+C
+C**********************************************************************
+
+      B. OBTAINING RANDOM NUMBERS
+
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNLGI()
+C               GeNerate LarGe Integer
+C
+C     Returns a random integer following a uniform distribution over
+C     (1, 2147483562) using the current generator.
+C
+C**********************************************************************
+
+C**********************************************************************
+C
+C     REAL FUNCTION RANF()
+C                RANDom number generator as a Function
+C
+C     Returns a random floating point number from a uniform distribution
+C     over 0 - 1 (endpoints of this interval are not returned) using the
+C     current generator
+C
+C**********************************************************************
+
+      C. SETTING AND OBTAINING THE NUMBER OF THE CURRENT GENERATOR
+
+C**********************************************************************
+C
+C     SUBROUTINE SETCGN( G )
+C                      Set GeNerator
+C     INTEGER G
+C
+C     Sets  the  current  generator to G. All references to a generator
+C     are to the current generator.
+C
+C**********************************************************************
+
+C**********************************************************************
+C
+C      SUBROUTINE GETCGN(G)
+C               GET Current GeNerator
+C      INTEGER G
+C
+C      Returns in G the number of the current random number generator
+C
+C**********************************************************************
+
+      D. OBTAINING OR CHANGING SEEDS IN CURRENT GENERATOR
+
+C**********************************************************************
+C
+C     SUBROUTINE ADVNST(K)
+C               ADV-a-N-ce ST-ate
+C     INTEGER K
+C
+C     Advances the state  of  the current  generator  by 2^K values  and
+C     resets the initial seed to that value.
+C
+C**********************************************************************
+
+C**********************************************************************
+C
+C     SUBROUTINE GETSD(ISEED1,ISEED2)
+C               GET SeeD
+C     INTEGER ISEED1, ISEED2
+C
+C     Returns the value of two integer seeds of the current generator
+C     in ISEED1, ISEED2
+C
+C**********************************************************************
+
+C**********************************************************************
+C
+C     SUBROUTINE INITGN(ISDTYP)
+C          INIT-ialize current G-e-N-erator
+C
+C     INTEGER ISDTYP    The state to which the generator is to be set
+C          ISDTYP = -1  => sets the seeds to their initial value
+C          ISDTYP =  0  => sets the seeds to the first value of
+C                          the current block
+C          ISDTYP =  1  => sets the seeds to the first value of
+C                          the next block
+C
+C**********************************************************************
+
+C**********************************************************************
+C
+C     SUBROUTINE SETSD(ISEED1,ISEED2)
+C               SET S-ee-D of current generator
+C
+C     Resets the initial  seed of  the current  generator to  ISEED1 and
+C     ISEED2. The seeds of the other generators remain unchanged.
+C
+C**********************************************************************
+
+      E. MISCELLANY
+
+C**********************************************************************
+C
+C     INTEGER FUNCTION MLTMOD(A,S,M)
+C                    Returns (A*S) MOD M
+C     INTEGER A, S, M
+C
+C**********************************************************************
+
+C**********************************************************************
+C
+C      SUBROUTINE SETANT(QVALUE)
+C               SET ANTithetic
+C      LOGICAL QVALUE
+C
+C     Sets whether the current generator produces antithetic values.  If
+C     X   is  the value  normally returned  from  a uniform [0,1] random
+C     number generator then 1  - X is the antithetic  value. If X is the
+C     value  normally  returned  from a   uniform  [0,N]  random  number
+C     generator then N - 1 - X is the antithetic value.
+C
+C     All generators are initialized to NOT generate antithetic values.
+C
+C**********************************************************************
+
+
+
+
+
+
diff --git a/libcruft/ranlib/randlib.fdoc b/libcruft/ranlib/randlib.fdoc
new file mode 100644
index 0000000..2fecbee
--- /dev/null
+++ b/libcruft/ranlib/randlib.fdoc
@@ -0,0 +1,961 @@
+
+
+
+
+
+
+
+
+
+
+
+                                     RANDLIB
+
+            Library of Fortran Routines for Random Number Generation
+
+
+
+
+
+
+
+
+                       Full Documentation of Each Routine
+
+
+
+
+
+
+
+
+                            Compiled and Written by:
+
+                                 Barry W. Brown
+                                  James Lovato
+                                   
+
+
+
+
+
+
+
+
+
+                     Department of Biomathematics, Box 237
+                     The University of Texas, M.D. Anderson Cancer Center
+                     1515 Holcombe Boulevard
+                     Houston, TX      77030
+
+
+ This work was supported by grant CA-16672 from the National Cancer Institute.
+
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE ADVNST(K)                                               
+C               ADV-a-N-ce ST-ate                                        
+C                                                                        
+C     Advances the state  of  the current  generator  by 2^K values  and 
+C     resets the initial seed to that value.                             
+C                                                                        
+C     This is  a  transcription from   Pascal to  Fortran    of  routine 
+C     Advance_State from the paper                                       
+C                                                                        
+C     L'Ecuyer, P. and  Cote, S. "Implementing  a  Random Number Package 
+C     with  Splitting   Facilities."  ACM  Transactions  on Mathematical 
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     K -> The generator is advanced by2^K values                        
+C                                   INTEGER K                            
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENBET( A, B )                                       
+C               GeNerate BETa random deviate                             
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Returns a single random deviate from the beta distribution with    
+C     parameters A and B.  The density of the beta is                    
+C               x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1             
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     A --> First parameter of the beta distribution                     
+C                         REAL A                                         
+C                         (A >= 1.0E-37)
+C                                                                        
+C     B --> Second parameter of the beta distribution                    
+C                         REAL B                                         
+C                         (B >= 1.0E-37)
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     R. C. H. Cheng                                                     
+C     Generating Beta Variables with Nonintegral Shape Parameters         
+C     Communications of the ACM, 21:317-322  (1978)                      
+C     (Algorithms BB and BC)                                             
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENCHI( DF )                                         
+C                Generate random value of CHIsquare variable             
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates random deviate from the distribution of a chisquare      
+C     with DF degrees of freedom random variable.                        
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     DF --> Degrees of freedom of the chisquare                         
+C            (Must be positive)                                          
+C                         REAL DF                                        
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Uses relation between chisquare and gamma.                         
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENEXP( AV )                                         
+C                                                                        
+C                    GENerate EXPonential random deviate                 
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a single random deviate from an exponential              
+C     distribution with mean AV.                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     AV --> The mean of the exponential distribution from which         
+C            a random deviate is to be generated.                        
+C                              REAL AV                                   
+C                              (AV >= 0)
+C                                                                        
+C     GENEXP <-- The random deviate.                                     
+C                              REAL GENEXP                               
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Renames SEXPO from TOMS as slightly modified by BWB to use RANF    
+C     instead of SUNIF.                                                  
+C                                                                        
+C     For details see:                                                   
+C                                                                        
+C               Ahrens, J.H. and Dieter, U.                              
+C               Computer Methods for Sampling From the                   
+C               Exponential and Normal Distributions.                    
+C               Comm. ACM, 15,10 (Oct. 1972), 873 - 882.                 
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENF( DFN, DFD )                                     
+C                GENerate random deviate from the F distribution         
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a random deviate from the F (variance ratio)             
+C     distribution with DFN degrees of freedom in the numerator          
+C     and DFD degrees of freedom in the denominator.                     
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     DFN --> Numerator degrees of freedom                               
+C             (Must be positive)                                         
+C                              REAL DFN                                  
+C      DFD --> Denominator degrees of freedom                            
+C             (Must be positive)                                         
+C                              REAL DFD                                  
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Directly generates ratio of chisquare variates                     
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENGAM( A, R )                                       
+C           GENerates random deviates from GAMma distribution            
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates random deviates from the gamma distribution whose        
+C     density is                                                         
+C          (A**R)/Gamma(R) * X**(R-1) * Exp(-A*X)                        
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     A --> Location parameter of Gamma distribution                     
+C                              REAL A ( A > 0 )
+C                                                                        
+C     R --> Shape parameter of Gamma distribution                        
+C                              REAL R ( R > 0 )
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Renames SGAMMA from TOMS as slightly modified by BWB to use RANF   
+C     instead of SUNIF.                                                  
+C                                                                        
+C     For details see:                                                   
+C               (Case R >= 1.0)                                          
+C               Ahrens, J.H. and Dieter, U.                              
+C               Generating Gamma Variates by a                           
+C               Modified Rejection Technique.                            
+C               Comm. ACM, 25,1 (Jan. 1982), 47 - 54.                    
+C     Algorithm GD                                                       
+C                                                                        
+C               (Case 0.0 < R < 1.0)                                   
+C               Ahrens, J.H. and Dieter, U.                              
+C               Computer Methods for Sampling from Gamma,                
+C               Beta, Poisson and Binomial Distributions.                
+C               Computing, 12 (1974), 223-246/                           
+C     Adapted algorithm GS.                                              
+C                                                                        
+C**********************************************************************  
+C********************************************************************** 
+C                                                                       
+C     SUBROUTINE GENMN(PARM,X,WORK)                                     
+C              GENerate Multivariate Normal random deviate              
+C                                                                       
+C                                                                       
+C                              Arguments                                
+C                                                                       
+C                                                                       
+C     PARM --> Parameters needed to generate multivariate normal        
+C               deviates (MEANV and Cholesky decomposition of           
+C               COVM). Set by a previous call to SETGMN.                
+C                                                                       
+C               1 : 1                - size of deviate, P               
+C               2 : P + 1            - mean vector                      
+C               P+2 : P*(P+3)/2 + 1  - upper half of cholesky           
+C                                       decomposition of cov matrix     
+C                                             REAL PARM(*)              
+C                                                                       
+C     X    <-- Vector deviate generated.                                
+C                                             REAL X(P)                 
+C                                                                       
+C     WORK <--> Scratch array                                           
+C                                             REAL WORK(P)              
+C                                                                       
+C                                                                       
+C                              Method                                   
+C                                                                       
+C                                                                       
+C     1) Generate P independent standard normal deviates - Ei ~ N(0,1)  
+C                                                                       
+C     2) SETGMN uses Cholesky decomposition find A s.t. trans(A)*A = COV
+C                                                                       
+C     3) Generate trans(A)*E + MEANV ~ N(MEANV,COVM)                    
+C                                                                       
+C********************************************************************** 
+C**********************************************************************
+C
+C            SUBROUTINE GENMUL( N, P, NCAT, IX )
+C     GENerate an observation from the MULtinomial distribution
+C
+C
+C                              Arguments
+C
+C
+C     N --> Number of events that will be classified into one of
+C           the categories 1..NCAT
+C                         INTEGER N
+C	                  (N >= 0)
+C
+C     P --> Vector of probabilities.  P(i) is the probability that
+C           an event will be classified into category i.  Thus, P(i)
+C           must be [0,1]. Only the first NCAT-1 P(i) must be defined
+C           since P(NCAT) is 1.0 minus the sum of the first
+C           NCAT-1 P(i).
+C                         REAL P(NCAT-1)
+C
+C     NCAT --> Number of categories.  Length of P and IX.
+C                         INTEGER NCAT
+C	                  (NCAT > 1)
+C
+C     IX <-- Observation from multinomial distribution.  All IX(i)
+C            will be nonnegative and their sum will be N.
+C                         INTEGER IX(NCAT)
+C
+C
+C                              Method
+C
+C
+C     Algorithm from page 559 of
+C
+C     Devroye, Luc
+C
+C     Non-Uniform Random Variate Generation.  Springer-Verlag,
+C     New York, 1986.
+C
+C**********************************************************************
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENNCH( DF, XNONC )                                  
+C           Generate random value of Noncentral CHIsquare variable       
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C                                                                         
+C     Generates random deviate  from the  distribution  of a  noncentral 
+C     chisquare with DF degrees  of freedom and noncentrality  parameter 
+C     XNONC.                                                             
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     DF --> Degrees of freedom of the chisquare                         
+C            (Must be >= 1.0)                                             
+C                         REAL DF                                        
+C                                                                        
+C     XNONC --> Noncentrality parameter of the chisquare                 
+C               (Must be >= 0.0)                                         
+C                         REAL XNONC                                     
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Uses fact that  noncentral chisquare  is  the  sum of a  chisquare 
+C     deviate with DF-1  degrees of freedom plus the  square of a normal 
+C     deviate with mean XNONC and standard deviation 1.                  
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENNF( DFN, DFD, XNONC )                             
+C           GENerate random deviate from the Noncentral F distribution   
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a random deviate from the  noncentral F (variance ratio) 
+C     distribution with DFN degrees of freedom in the numerator, and DFD 
+C     degrees of freedom in the denominator, and noncentrality parameter 
+C     XNONC.                                                             
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     DFN --> Numerator degrees of freedom                               
+C             (Must be >= 1.0)                                           
+C                              REAL DFN                                  
+C      DFD --> Denominator degrees of freedom                            
+C             (Must be positive)                                         
+C                              REAL DFD                                  
+C                                                                        
+C     XNONC --> Noncentrality parameter                                  
+C               (Must be nonnegative)                                    
+C                              REAL XNONC                                
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Directly generates ratio of noncentral numerator chisquare variate 
+C     to central denominator chisquare variate.                          
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENNOR( AV, SD )                                     
+C                                                                        
+C         GENerate random deviate from a NORmal distribution             
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a single random deviate from a normal distribution       
+C     with mean, AV, and standard deviation, SD.                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     AV --> Mean of the normal distribution.                            
+C                              REAL AV                                   
+C                                                                        
+C     SD --> Standard deviation of the normal distribution.              
+C                              REAL SD                                   
+C                              (SD >= 0)
+C                                                                        
+C     GENNOR <-- Generated normal deviate.                               
+C                              REAL GENNOR                               
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Renames SNORM from TOMS as slightly modified by BWB to use RANF    
+C     instead of SUNIF.                                                  
+C                                                                        
+C     For details see:                                                   
+C               Ahrens, J.H. and Dieter, U.                              
+C               Extensions of Forsythe's Method for Random               
+C               Sampling from the Normal Distribution.                   
+C               Math. Comput., 27,124 (Oct. 1973), 927 - 937.            
+C                                                                        
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C    SUBROUTINE GENPRM( IARRAY, LARRAY )                                 
+C               GENerate random PeRMutation of iarray                    
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     IARRAY <--> On output IARRAY is a random permutation of its        
+C                 value on input                                         
+C                         INTEGER IARRAY( LARRAY )                       
+C                                                                        
+C     LARRAY <--> Length of IARRAY                                       
+C                         INTEGER LARRAY                                 
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION GENUNF( LOW, HIGH )                                  
+C                                                                        
+C               GeNerate Uniform Real between LOW and HIGH               
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a real uniformly distributed between LOW and HIGH.       
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     LOW --> Low bound (exclusive) on real value to be generated        
+C                         REAL LOW                                       
+C                                                                        
+C     HIGH --> High bound (exclusive) on real value to be generated      
+C                         REAL HIGH                                      
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C      SUBROUTINE GETCGN(G)                                              
+C                         Get GeNerator                                  
+C                                                                        
+C     Returns in G the number of the current random number generator     
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     G <-- Number of the current random number generator (1..32)        
+C                    INTEGER G                                           
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE GETSD(ISEED1,ISEED2)                                  
+C               GET SeeD                                                 
+C                                                                        
+C     Returns the value of two integer seeds of the current generator    
+C                                                                        
+C     This  is   a  transcription from  Pascal   to  Fortran  of routine 
+C     Get_State from the paper                                           
+C                                                                        
+C     L'Ecuyer, P. and  Cote,  S. "Implementing a Random Number  Package 
+C     with   Splitting Facilities."  ACM  Transactions   on Mathematical 
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C                                                                        
+C     ISEED1 <- First integer seed of generator G                        
+C                                   INTEGER ISEED1                       
+C                                                                        
+C     ISEED2 <- Second integer seed of generator G                       
+C                                   INTEGER ISEED1                       
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION IGNBIN( N, P )                                    
+C                                                                        
+C                    GENerate BINomial random deviate                    
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a single random deviate from a binomial                  
+C     distribution whose number of trials is N and whose                 
+C     probability of an event in each trial is P.                        
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     N  --> The number of trials in the binomial distribution           
+C            from which a random deviate is to be generated.             
+C                              INTEGER N                                 
+C                              (N >= 0)
+C                                                                        
+C     P  --> The probability of an event in each trial of the            
+C            binomial distribution from which a random deviate           
+C            is to be generated.                                         
+C                              REAL P                                    
+C                              (0.0 <= P <= 1.0)
+C                                                                        
+C     IGNBIN <-- A random deviate yielding the number of events          
+C                from N independent trials, each of which has            
+C                a probability of event P.                               
+C                              INTEGER IGNBIN                            
+C                                                                        
+C                                                                        
+C                              Note                                      
+C                                                                        
+C                                                                        
+C     Uses RANF so the value of the seeds, ISEED1 and ISEED2 must be set 
+C     by a call similar to the following                                 
+C          DUM = RANSET( ISEED1, ISEED2 )                                
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     This is algorithm BTPE from:                                       
+C                                                                        
+C         Kachitvichyanukul, V. and Schmeiser, B. W.                     
+C                                                                        
+C         Binomial Random Variate Generation.                            
+C         Communications of the ACM, 31, 2                               
+C         (February, 1988) 216.                                          
+C                                                                        
+C**********************************************************************  
+C**********************************************************************
+C
+C     INTEGER FUNCTION IGNNBN( N, P )
+C
+C                GENerate Negative BiNomial random deviate
+C
+C
+C                              Function
+C
+C
+C     Generates a single random deviate from a negative binomial
+C     distribution.
+C
+C
+C                              Arguments
+C
+C
+C     N  --> Required number of events.
+C                              INTEGER N
+C                              (N > 0)
+C
+C     P  --> The probability of an event during a Bernoulli trial.
+C                              REAL P
+C                              (0.0 < P < 1.0)
+C
+C
+C
+C                              Method
+C
+C
+C     Algorithm from page 480 of
+C
+C     Devroye, Luc
+C
+C     Non-Uniform Random Variate Generation.  Springer-Verlag,
+C     New York, 1986.
+C
+C**********************************************************************
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION IGNLGI()                                          
+C               GeNerate LarGe Integer                                   
+C                                                                        
+C     Returns a random integer following a uniform distribution over     
+C     (1, 2147483562) using the current generator.                       
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     Random from the paper                                              
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION IGNPOI( MU )                                      
+C                                                                        
+C                    GENerate POIsson random deviate                     
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates a single random deviate from a Poisson                   
+C     distribution with mean MU.                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     MU --> The mean of the Poisson distribution from which             
+C            a random deviate is to be generated.                        
+C                              REAL MU                                   
+C                            (MU >= 0.0)
+C                                                                        
+C     IGNPOI <-- The random deviate.                                     
+C                              REAL IGNPOI (non-negative)
+C                                                                        
+C                                                                        
+C                              Method                                    
+C                                                                        
+C                                                                        
+C     Renames KPOIS from TOMS as slightly modified by BWB to use RANF    
+C     instead of SUNIF.                                                  
+C                                                                        
+C     For details see:                                                   
+C                                                                        
+C               Ahrens, J.H. and Dieter, U.                              
+C               Computer Generation of Poisson Deviates                  
+C               From Modified Normal Distributions.                      
+C               ACM Trans. Math. Software, 8, 2                          
+C               (June 1982),163-179                                      
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION IGNUIN( LOW, HIGH )                               
+C                                                                        
+C               GeNerate Uniform INteger                                 
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Generates an integer uniformly distributed between LOW and HIGH.   
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     LOW --> Low bound (inclusive) on integer value to be generated     
+C                         INTEGER LOW                                    
+C                                                                        
+C     HIGH --> High bound (inclusive) on integer value to be generated   
+C                         INTEGER HIGH                                   
+C                                                                        
+C                                                                        
+C                              Note                                      
+C                                                                        
+C                                                                        
+C     If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and   
+C     stops the program.                                                 
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE INITGN(ISDTYP)                                          
+C          INIT-ialize current G-e-N-erator                              
+C                                                                        
+C     Reinitializes the state of the current generator                   
+C          ISDTYP = -1  => sets the state to its initial seed            
+C          ISDTYP =  0  => sets the state to its last (previous) seed    
+C          ISDTYP =  1  => sets the state to a new seed 2^w values       
+C                              from its last seed                        
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     Init_Generator from the paper                                      
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     ISDTYP -> The state to which the generator is to be set            
+C                                                                        
+C                                   INTEGER ISDTYP                       
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE INRGCM()                                                
+C          INitialize Random number Generator CoMmon                     
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Initializes common area  for random number  generator.  This saves 
+C     the  nuisance  of  a  BLOCK DATA  routine  and the  difficulty  of 
+C     assuring that the routine is loaded with the other routines.       
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     INTEGER FUNCTION MLTMOD(A,S,M)                                     
+C                                                                        
+C                    Returns (A*S) MOD M                                 
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     MULtMod_Decompos from the paper                                    
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     A, S, M  -->                                                       
+C                         INTEGER A,S,M                                  
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE PHRTSD( PHRASE, SEED1, SEED2 )                          
+C               PHRase To SeeDs                                          
+C                                                                        
+C                                                                        
+C                              Function                                  
+C                                                                        
+C                                                                        
+C     Uses a phrase (character string) to generate two seeds for the RGN 
+C     random number generator.                                           
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     PHRASE --> Phrase to be used for random number generation          
+C                         CHARACTER*(*) PHRASE                           
+C                                                                        
+C     SEED1 <-- First seed for RGN generator                             
+C                         INTEGER SEED1                                  
+C                                                                        
+C     SEED2 <-- Second seed for RGN generator                            
+C                         INTEGER SEED2                                  
+C                                                                        
+C                                                                        
+C                              Note                                      
+C                                                                        
+C                                                                        
+C     Trailing blanks are eliminated before the seeds are generated.     
+C                                                                        
+C     Generated seed values will fall in the range 1..2^30               
+C     (1..1,073,741,824)                                                 
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     REAL FUNCTION RANF()                                               
+C                RANDom number generator as a Function                   
+C                                                                        
+C     Returns a random floating point number from a uniform distribution 
+C     over 0 - 1 (endpoints of this interval are not returned) using the 
+C     current generator                                                  
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     Uniform_01 from the paper                                          
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C      SUBROUTINE SETALL(ISEED1,ISEED2)                                  
+C               SET ALL random number generators                         
+C                                                                        
+C     Sets the initial seed of generator 1 to ISEED1 and ISEED2. The     
+C     initial seeds of the other generators are set accordingly, and     
+C     all generators states are set to these seeds.                      
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     Set_Initial_Seed from the paper                                    
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     ISEED1 -> First of two integer seeds                               
+C                                   INTEGER ISEED1                       
+C                                                                        
+C     ISEED2 -> Second of two integer seeds                              
+C                                   INTEGER ISEED1                       
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C      SUBROUTINE SETANT(QVALUE)                                         
+C               SET ANTithetic                                           
+C                                                                        
+C     Sets whether the current generator produces antithetic values.  If 
+C     X   is  the value  normally returned  from  a uniform [0,1] random 
+C     number generator then 1  - X is the antithetic  value. If X is the 
+C     value  normally  returned  from a   uniform  [0,N]  random  number 
+C     generator then N - 1 - X is the antithetic value.                  
+C                                                                        
+C     All generators are initialized to NOT generate antithetic values.  
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     Set_Antithetic from the paper                                      
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     QVALUE -> .TRUE. if generator G is to generating antithetic        
+C                    values, otherwise .FALSE.                           
+C                                   LOGICAL QVALUE                       
+C                                                                        
+C**********************************************************************  
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE SETCGN( G )                                             
+C                      Set GeNerator                                     
+C                                                                        
+C     Sets  the  current  generator to G.    All references to a generato
+C     are to the current generator.                                      
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     G --> Number of the current random number generator (1..32)        
+C                    INTEGER G                                           
+C                                                                        
+C**********************************************************************  
+C**********************************************************************
+C
+C     SUBROUTINE SETGMN( MEANV, COVM, LDCOVM, P, PARM)
+C            SET Generate Multivariate Normal random deviate
+C
+C
+C                              Function
+C
+C
+C      Places P, MEANV, and the Cholesky factoriztion of COVM
+C      in PARM for GENMN.
+C
+C
+C                              Arguments
+C
+C
+C     MEANV --> Mean vector of multivariate normal distribution.
+C                                        REAL MEANV(P)
+C
+C     COVM   <--> (Input) Covariance   matrix    of  the  multivariate
+C                 normal distribution.  This routine uses only the
+C                 (1:P,1:P) slice of COVM, but needs to know LDCOVM.
+C
+C                 (Output) Destroyed on output
+C                                        REAL COVM(LDCOVM,P)
+C
+C     LDCOVM --> Leading actual dimension of COVM.
+C                                        INTEGER LDCOVM
+C
+C     P     --> Dimension of the normal, or length of MEANV.
+C                                        INTEGER P
+C
+C     PARM <-- Array of parameters needed to generate multivariate
+C                normal deviates (P, MEANV and Cholesky decomposition
+C                of COVM).
+C                1 : 1                - P
+C                2 : P + 1            - MEANV
+C                P+2 : P*(P+3)/2 + 1  - Cholesky decomposition of COVM
+C                                             REAL PARM(P*(P+3)/2 + 1)
+C
+C**********************************************************************
+C**********************************************************************  
+C                                                                        
+C     SUBROUTINE SETSD(ISEED1,ISEED2)                                    
+C               SET S-ee-D of current generator                          
+C                                                                        
+C     Resets the initial seed and state of generator g to ISEED1 and     
+C     ISEED2. The seeds and states of the other generators  remain       
+C     unchanged.                                                         
+C                                                                        
+C     This is a transcription from Pascal to Fortran of routine          
+C     Set_Seed from the paper                                            
+C                                                                        
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package    
+C     with Splitting Facilities." ACM Transactions on Mathematical       
+C     Software, 17:98-111 (1991)                                         
+C                                                                        
+C                                                                        
+C                              Arguments                                 
+C                                                                        
+C                                                                        
+C     ISEED1 -> First integer seed                                       
+C                                   INTEGER ISEED1                       
+C                                                                        
+C     ISEED2 -> Second integer seed                                      
+C                                   INTEGER ISEED1                       
+C                                                                        
+C**********************************************************************  
diff --git a/libcruft/ranlib/ranf.f b/libcruft/ranlib/ranf.f
new file mode 100644
index 0000000..2a7a789
--- /dev/null
+++ b/libcruft/ranlib/ranf.f
@@ -0,0 +1,31 @@
+      REAL FUNCTION ranf()
+C**********************************************************************
+C
+C     REAL FUNCTION RANF()
+C                RANDom number generator as a Function
+C
+C     Returns a random floating point number from a uniform distribution
+C     over 0 - 1 (endpoints of this interval are not returned) using the
+C     current generator
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     Uniform_01 from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C**********************************************************************
+C     .. External Functions ..
+      INTEGER ignlgi
+      EXTERNAL ignlgi
+C     ..
+C     .. Executable Statements ..
+C
+C     4.656613057E-10 is 1/M1  M1 is set in a data statement in IGNLGI
+C      and is currently 2147483563. If M1 changes, change this also.
+C
+      ranf = ignlgi()*4.656613057E-10
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/setall.f b/libcruft/ranlib/setall.f
new file mode 100644
index 0000000..50542a8
--- /dev/null
+++ b/libcruft/ranlib/setall.f
@@ -0,0 +1,103 @@
+      SUBROUTINE setall(iseed1,iseed2)
+C**********************************************************************
+C
+C      SUBROUTINE SETALL(ISEED1,ISEED2)
+C               SET ALL random number generators
+C
+C     Sets the initial seed of generator 1 to ISEED1 and ISEED2. The
+C     initial seeds of the other generators are set accordingly, and
+C     all generators states are set to these seeds.
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     Set_Initial_Seed from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C     ISEED1 -> First of two integer seeds
+C                                   INTEGER ISEED1
+C
+C     ISEED2 -> Second of two integer seeds
+C                                   INTEGER ISEED1
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER iseed1,iseed2
+      LOGICAL qssd
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER g,ocgn
+      LOGICAL qqssd
+C     ..
+C     .. External Functions ..
+      INTEGER mltmod
+      LOGICAL qrgnin
+      EXTERNAL mltmod,qrgnin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn,initgn,inrgcm,setcgn
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/,qqssd
+C     ..
+C     .. Data statements ..
+      DATA qqssd/.FALSE./
+C     ..
+C     .. Executable Statements ..
+C
+C     TELL IGNLGI, THE ACTUAL NUMBER GENERATOR, THAT THIS ROUTINE
+C      HAS BEEN CALLED.
+C
+      qqssd = .TRUE.
+      CALL getcgn(ocgn)
+C
+C     Initialize Common Block if Necessary
+C
+      IF (.NOT. (qrgnin())) CALL inrgcm()
+      ig1(1) = iseed1
+      ig2(1) = iseed2
+      CALL initgn(-1)
+      DO 10,g = 2,numg
+          ig1(g) = mltmod(a1vw,ig1(g-1),m1)
+          ig2(g) = mltmod(a2vw,ig2(g-1),m2)
+          CALL setcgn(g)
+          CALL initgn(-1)
+   10 CONTINUE
+      CALL setcgn(ocgn)
+      RETURN
+
+      ENTRY rgnqsd(qssd)
+C**********************************************************************
+C
+C     SUBROUTINE RGNQSD
+C                    Random Number Generator Query SeeD set?
+C
+C     Returns (LOGICAL) QSSD as .TRUE. if SETALL has been invoked,
+C     otherwise returns .FALSE.
+C
+C**********************************************************************
+      qssd = qqssd
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/setant.f b/libcruft/ranlib/setant.f
new file mode 100644
index 0000000..85ec501
--- /dev/null
+++ b/libcruft/ranlib/setant.f
@@ -0,0 +1,74 @@
+      SUBROUTINE setant(qvalue)
+C**********************************************************************
+C
+C      SUBROUTINE SETANT(QVALUE)
+C               SET ANTithetic
+C
+C     Sets whether the current generator produces antithetic values.  If
+C     X   is  the value  normally returned  from  a uniform [0,1] random
+C     number generator then 1  - X is the antithetic  value. If X is the
+C     value  normally  returned  from a   uniform  [0,N]  random  number
+C     generator then N - 1 - X is the antithetic value.
+C
+C     All generators are initialized to NOT generate antithetic values.
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     Set_Antithetic from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C     QVALUE -> .TRUE. if generator G is to generating antithetic
+C                    values, otherwise .FALSE.
+C                                   LOGICAL QVALUE
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalar Arguments ..
+      LOGICAL qvalue
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER g
+C     ..
+C     .. External Functions ..
+      LOGICAL qrgnin
+      EXTERNAL qrgnin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C     Abort unless random number generator initialized
+      IF (qrgnin()) GO TO 10
+      WRITE (*,*) ' SETANT called before random number generator ',
+     +  ' initialized -- abort!'
+      STOP ' SETANT called before random number generator initialized'
+
+   10 CALL getcgn(g)
+      qanti(g) = qvalue
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/setgmn.f b/libcruft/ranlib/setgmn.f
new file mode 100644
index 0000000..432fd3b
--- /dev/null
+++ b/libcruft/ranlib/setgmn.f
@@ -0,0 +1,107 @@
+      SUBROUTINE setgmn(meanv,covm,ldcovm,p,parm)
+C      SUBROUTINE setgmn(meanv,covm,p,parm)
+C     JJV changed this routine to take leading dimension of COVM
+C     JJV argument and pass it to SPOTRF, making it easier to use
+C     JJV if the COVM which is used is contained in a larger matrix
+C     JJV and to make the routine more consistent with LAPACK.
+C     JJV Changes are in comments, declarations, and the call to SPOTRF.
+C**********************************************************************
+C
+C     SUBROUTINE SETGMN( MEANV, COVM, LDCOVM, P, PARM)
+C            SET Generate Multivariate Normal random deviate
+C
+C
+C                              Function
+C
+C
+C      Places P, MEANV, and the Cholesky factoriztion of COVM
+C      in PARM for GENMN.
+C
+C
+C                              Arguments
+C
+C
+C     MEANV --> Mean vector of multivariate normal distribution.
+C                                        REAL MEANV(P)
+C
+C     COVM   <--> (Input) Covariance   matrix    of  the  multivariate
+C                 normal distribution.  This routine uses only the
+C                 (1:P,1:P) slice of COVM, but needs to know LDCOVM.
+C
+C                 (Output) Destroyed on output
+C                                        REAL COVM(LDCOVM,P)
+C
+C     LDCOVM --> Leading actual dimension of COVM.
+C                                        INTEGER LDCOVM
+C
+C     P     --> Dimension of the normal, or length of MEANV.
+C                                        INTEGER P
+C
+C     PARM <-- Array of parameters needed to generate multivariate
+C                normal deviates (P, MEANV and Cholesky decomposition
+C                of COVM).
+C                1 : 1                - P
+C                2 : P + 1            - MEANV
+C                P+2 : P*(P+3)/2 + 1  - Cholesky decomposition of COVM
+C                                             REAL PARM(P*(P+3)/2 + 1)
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+C      INTEGER p
+      INTEGER p, ldcovm
+C     ..
+C     .. Array Arguments ..
+C      REAL covm(p,p),meanv(p),parm(p* (p+3)/2+1)
+      REAL covm(ldcovm,p),meanv(p),parm(p* (p+3)/2+1)
+C     ..
+C     .. Local Scalars ..
+      INTEGER i,icount,info,j
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL spotrf
+C     ..
+C     .. Executable Statements ..
+C
+C
+C     TEST THE INPUT
+C
+      IF (.NOT. (p.LE.0)) GO TO 10
+      WRITE (*,*) 'P nonpositive in SETGMN'
+      WRITE (*,*) 'Value of P: ',p
+      STOP 'P nonpositive in SETGMN'
+
+   10 parm(1) = p
+C
+C     PUT P AND MEANV INTO PARM
+C
+      DO 20,i = 2,p + 1
+          parm(i) = meanv(i-1)
+   20 CONTINUE
+C
+C      Cholesky decomposition to find A s.t. trans(A)*(A) = COVM
+C
+C      CALL spofa(covm,p,p,info)
+C      CALL spofa(covm,ldcovm,p,info)
+      CALL spotrf ( 'Upper', p, covm, ldcovm, info)
+      IF (.NOT. (info.NE.0)) GO TO 30
+      WRITE (*,*) ' COVM not positive definite in SETGMN'
+      STOP ' COVM not positive definite in SETGMN'
+
+   30 icount = p + 1
+C
+C     PUT UPPER HALF OF A, WHICH IS NOW THE CHOLESKY FACTOR, INTO PARM
+C          COVM(1,1) = PARM(P+2)
+C          COVM(1,2) = PARM(P+3)
+C                    :
+C          COVM(1,P) = PARM(2P+1)
+C          COVM(2,2) = PARM(2P+2)  ...
+C
+      DO 50,i = 1,p
+          DO 40,j = i,p
+              icount = icount + 1
+              parm(icount) = covm(i,j)
+   40     CONTINUE
+   50 CONTINUE
+      RETURN
+C
+      END
diff --git a/libcruft/ranlib/setsd.f b/libcruft/ranlib/setsd.f
new file mode 100644
index 0000000..3333ae5
--- /dev/null
+++ b/libcruft/ranlib/setsd.f
@@ -0,0 +1,73 @@
+      SUBROUTINE setsd(iseed1,iseed2)
+C**********************************************************************
+C
+C     SUBROUTINE SETSD(ISEED1,ISEED2)
+C               SET S-ee-D of current generator
+C
+C     Resets the initial  seed of  the current  generator to  ISEED1 and
+C     ISEED2. The seeds of the other generators remain unchanged.
+C
+C     This is a transcription from Pascal to Fortran of routine
+C     Set_Seed from the paper
+C
+C     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
+C     with Splitting Facilities." ACM Transactions on Mathematical
+C     Software, 17:98-111 (1991)
+C
+C
+C                              Arguments
+C
+C
+C     ISEED1 -> First integer seed
+C                                   INTEGER ISEED1
+C
+C     ISEED2 -> Second integer seed
+C                                   INTEGER ISEED1
+C
+C**********************************************************************
+C     .. Parameters ..
+      INTEGER numg
+      PARAMETER (numg=32)
+C     ..
+C     .. Scalar Arguments ..
+      INTEGER iseed1,iseed2
+C     ..
+C     .. Scalars in Common ..
+      INTEGER a1,a1vw,a1w,a2,a2vw,a2w,m1,m2
+C     ..
+C     .. Arrays in Common ..
+      INTEGER cg1(numg),cg2(numg),ig1(numg),ig2(numg),lg1(numg),
+     +        lg2(numg)
+      LOGICAL qanti(numg)
+C     ..
+C     .. Local Scalars ..
+      INTEGER g
+C     ..
+C     .. External Functions ..
+      LOGICAL qrgnin
+      EXTERNAL qrgnin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getcgn,initgn
+C     ..
+C     .. Common blocks ..
+      COMMON /globe/m1,m2,a1,a2,a1w,a2w,a1vw,a2vw,ig1,ig2,lg1,lg2,cg1,
+     +       cg2,qanti
+C     ..
+C     .. Save statement ..
+      SAVE /globe/
+C     ..
+C     .. Executable Statements ..
+C     Abort unless random number generator initialized
+      IF (qrgnin()) GO TO 10
+      WRITE (*,*) ' SETSD called before random number generator ',
+     +  ' initialized -- abort!'
+      STOP ' SETSD called before random number generator initialized'
+
+   10 CALL getcgn(g)
+      ig1(g) = iseed1
+      ig2(g) = iseed2
+      CALL initgn(-1)
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/sexpo.f b/libcruft/ranlib/sexpo.f
new file mode 100644
index 0000000..06c4c22
--- /dev/null
+++ b/libcruft/ranlib/sexpo.f
@@ -0,0 +1,78 @@
+      REAL FUNCTION sexpo()
+C**********************************************************************C
+C                                                                      C
+C                                                                      C
+C     (STANDARD-)  E X P O N E N T I A L   DISTRIBUTION                C
+C                                                                      C
+C                                                                      C
+C**********************************************************************C
+C**********************************************************************C
+C                                                                      C
+C     FOR DETAILS SEE:                                                 C
+C                                                                      C
+C               AHRENS, J.H. AND DIETER, U.                            C
+C               COMPUTER METHODS FOR SAMPLING FROM THE                 C
+C               EXPONENTIAL AND NORMAL DISTRIBUTIONS.                  C
+C               COMM. ACM, 15,10 (OCT. 1972), 873 - 882.               C
+C                                                                      C
+C     ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM       C
+C     'SA' IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION)       C
+C                                                                      C
+C     Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of   C
+C     SUNIF.  The argument IR thus goes away.                          C
+C                                                                      C
+C**********************************************************************C
+C
+C
+C     Q(N) = SUM(ALOG(2.0)**K/K!)    K=1,..,N ,      THE HIGHEST N
+C     (HERE 8) IS DETERMINED BY Q(N)=1.0 WITHIN STANDARD PRECISION
+C
+C     JJV added a Save statement for q (in Data statement)
+C     .. Local Scalars ..
+      REAL a,q1,u,umin,ustar
+      INTEGER i
+C     ..
+C     .. Local Arrays ..
+      REAL q(8)
+C     ..
+C     .. External Functions ..
+      REAL ranf
+      EXTERNAL ranf
+C     ..
+C     .. Equivalences ..
+      EQUIVALENCE (q(1),q1)
+C     ..
+C     .. Save statement ..
+      SAVE q
+C     ..
+C     .. Data statements ..
+      DATA q/.6931472,.9333737,.9888778,.9984959,.9998293,.9999833,
+     +     .9999986,.9999999/
+C     ..
+C
+   10 a = 0.0
+      u = ranf()
+      GO TO 30
+
+   20 a = a + q1
+   30 u = u + u
+C     JJV changed the following to reflect the true algorithm and
+C     JJV prevent unpredictable behavior if U is initially 0.5.
+C      IF (u.LE.1.0) GO TO 20
+      IF (u.LT.1.0) GO TO 20
+   40 u = u - 1.0
+      IF (u.GT.q1) GO TO 60
+   50 sexpo = a + u
+      RETURN
+
+   60 i = 1
+      ustar = ranf()
+      umin = ustar
+   70 ustar = ranf()
+      IF (ustar.LT.umin) umin = ustar
+   80 i = i + 1
+      IF (u.GT.q(i)) GO TO 70
+   90 sexpo = a + umin*q1
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/sgamma.f b/libcruft/ranlib/sgamma.f
new file mode 100644
index 0000000..dad3d1c
--- /dev/null
+++ b/libcruft/ranlib/sgamma.f
@@ -0,0 +1,235 @@
+      REAL FUNCTION sgamma(a)
+C**********************************************************************C
+C                                                                      C
+C                                                                      C
+C     (STANDARD-)  G A M M A  DISTRIBUTION                             C
+C                                                                      C
+C                                                                      C
+C**********************************************************************C
+C**********************************************************************C
+C                                                                      C
+C               PARAMETER  A >= 1.0  !                                 C
+C                                                                      C
+C**********************************************************************C
+C                                                                      C
+C     FOR DETAILS SEE:                                                 C
+C                                                                      C
+C               AHRENS, J.H. AND DIETER, U.                            C
+C               GENERATING GAMMA VARIATES BY A                         C
+C               MODIFIED REJECTION TECHNIQUE.                          C
+C               COMM. ACM, 25,1 (JAN. 1982), 47 - 54.                  C
+C                                                                      C
+C     STEP NUMBERS CORRESPOND TO ALGORITHM 'GD' IN THE ABOVE PAPER     C
+C                                 (STRAIGHTFORWARD IMPLEMENTATION)     C
+C                                                                      C
+C     Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of   C
+C     SUNIF.  The argument IR thus goes away.                          C
+C                                                                      C
+C**********************************************************************C
+C                                                                      C
+C               PARAMETER  0.0 < A < 1.0  !                            C
+C                                                                      C
+C**********************************************************************C
+C                                                                      C
+C     FOR DETAILS SEE:                                                 C
+C                                                                      C
+C               AHRENS, J.H. AND DIETER, U.                            C
+C               COMPUTER METHODS FOR SAMPLING FROM GAMMA,              C
+C               BETA, POISSON AND BINOMIAL DISTRIBUTIONS.              C
+C               COMPUTING, 12 (1974), 223 - 246.                       C
+C                                                                      C
+C     (ADAPTED IMPLEMENTATION OF ALGORITHM 'GS' IN THE ABOVE PAPER)    C
+C                                                                      C
+C**********************************************************************C
+C
+C
+C     INPUT: A =PARAMETER (MEAN) OF THE STANDARD GAMMA DISTRIBUTION
+C     OUTPUT: SGAMMA = SAMPLE FROM THE GAMMA-(A)-DISTRIBUTION
+C
+C     COEFFICIENTS Q(K) - FOR Q0 = SUM(Q(K)*A**(-K))
+C     COEFFICIENTS A(K) - FOR Q = Q0+(T*T/2)*SUM(A(K)*V**K)
+C     COEFFICIENTS E(K) - FOR EXP(Q)-1 = SUM(E(K)*Q**K)
+C
+C     .. Scalar Arguments ..
+      REAL a
+C     ..
+C     .. Local Scalars .. (JJV added B0 to fix rare and subtle bug)
+      REAL a1,a2,a3,a4,a5,a6,a7,aa,aaa,b,b0,c,d,e,e1,e2,e3,e4,e5,p,q,q0,
+     +     q1,q2,q3,q4,q5,q6,q7,r,s,s2,si,sqrt32,t,u,v,w,x
+C     ..
+C     .. External Functions ..
+      REAL ranf,sexpo,snorm
+      EXTERNAL ranf,sexpo,snorm
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC abs,alog,exp,sign,sqrt
+C     ..
+C     .. Save statement ..
+C     JJV added Save statement for vars in Data satatements
+      SAVE aa,aaa,s2,s,d,q0,b,si,c,q1,q2,q3,q4,q5,q6,q7,a1,a2,a3,a4,a5,
+     +     a6,a7,e1,e2,e3,e4,e5,sqrt32
+C     ..
+C     .. Data statements ..
+C
+C     PREVIOUS A PRE-SET TO ZERO - AA IS A', AAA IS A"
+C     SQRT32 IS THE SQUAREROOT OF 32 = 5.656854249492380
+C
+      DATA q1,q2,q3,q4,q5,q6,q7/.04166669,.02083148,.00801191,.00144121,
+     +     -.00007388,.00024511,.00024240/
+      DATA a1,a2,a3,a4,a5,a6,a7/.3333333,-.2500030,.2000062,-.1662921,
+     +     .1423657,-.1367177,.1233795/
+      DATA e1,e2,e3,e4,e5/1.,.4999897,.1668290,.0407753,.0102930/
+      DATA aa/0.0/,aaa/0.0/,sqrt32/5.656854/
+C     ..
+C     .. Executable Statements ..
+C
+      IF (a.EQ.aa) GO TO 10
+      IF (a.LT.1.0) GO TO 130
+C
+C     STEP  1:  RECALCULATIONS OF S2,S,D IF A HAS CHANGED
+C
+      aa = a
+      s2 = a - 0.5
+      s = sqrt(s2)
+      d = sqrt32 - 12.0*s
+C
+C     STEP  2:  T=STANDARD NORMAL DEVIATE,
+C               X=(S,1/2)-NORMAL DEVIATE.
+C               IMMEDIATE ACCEPTANCE (I)
+C
+   10 t = snorm()
+      x = s + 0.5*t
+      sgamma = x*x
+      IF (t.GE.0.0) RETURN
+C
+C     STEP  3:  U= 0,1 -UNIFORM SAMPLE. SQUEEZE ACCEPTANCE (S)
+C
+      u = ranf()
+      IF (d*u.LE.t*t*t) RETURN
+C
+C     STEP  4:  RECALCULATIONS OF Q0,B,SI,C IF NECESSARY
+C
+      IF (a.EQ.aaa) GO TO 40
+      aaa = a
+      r = 1.0/a
+      q0 = ((((((q7*r+q6)*r+q5)*r+q4)*r+q3)*r+q2)*r+q1)*r
+C
+C               APPROXIMATION DEPENDING ON SIZE OF PARAMETER A
+C               THE CONSTANTS IN THE EXPRESSIONS FOR B, SI AND
+C               C WERE ESTABLISHED BY NUMERICAL EXPERIMENTS
+C
+      IF (a.LE.3.686) GO TO 30
+      IF (a.LE.13.022) GO TO 20
+C
+C               CASE 3:  A .GT. 13.022
+C
+      b = 1.77
+      si = .75
+      c = .1515/s
+      GO TO 40
+C
+C               CASE 2:  3.686 .LT. A .LE. 13.022
+C
+   20 b = 1.654 + .0076*s2
+      si = 1.68/s + .275
+      c = .062/s + .024
+      GO TO 40
+C
+C               CASE 1:  A .LE. 3.686
+C
+   30 b = .463 + s + .178*s2
+      si = 1.235
+      c = .195/s - .079 + .16*s
+C
+C     STEP  5:  NO QUOTIENT TEST IF X NOT POSITIVE
+C
+   40 IF (x.LE.0.0) GO TO 70
+C
+C     STEP  6:  CALCULATION OF V AND QUOTIENT Q
+C
+      v = t/ (s+s)
+      IF (abs(v).LE.0.25) GO TO 50
+      q = q0 - s*t + 0.25*t*t + (s2+s2)*alog(1.0+v)
+      GO TO 60
+
+   50 q = q0 + 0.5*t*t* ((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v
+C
+C     STEP  7:  QUOTIENT ACCEPTANCE (Q)
+C
+   60 IF (alog(1.0-u).LE.q) RETURN
+C
+C     STEP  8:  E=STANDARD EXPONENTIAL DEVIATE
+C               U= 0,1 -UNIFORM DEVIATE
+C               T=(B,SI)-DOUBLE EXPONENTIAL (LAPLACE) SAMPLE
+C
+   70 e = sexpo()
+      u = ranf()
+      u = u + u - 1.0
+      t = b + sign(si*e,u)
+C
+C     STEP  9:  REJECTION IF T .LT. TAU(1) = -.71874483771719
+C
+   80 IF (t.LT. (-.7187449)) GO TO 70
+C
+C     STEP 10:  CALCULATION OF V AND QUOTIENT Q
+C
+      v = t/ (s+s)
+      IF (abs(v).LE.0.25) GO TO 90
+      q = q0 - s*t + 0.25*t*t + (s2+s2)*alog(1.0+v)
+      GO TO 100
+
+   90 q = q0 + 0.5*t*t* ((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v
+C
+C     STEP 11:  HAT ACCEPTANCE (H) (IF Q NOT POSITIVE GO TO STEP 8)
+C
+  100 IF (q.LE.0.0) GO TO 70
+      IF (q.LE.0.5) GO TO 110
+C
+C     JJV modified the code through line 125 to handle large Q case
+C
+      IF (q.LT.15.0) GO TO 105
+C
+C     JJV Here Q is large enough that Q = log(exp(Q) - 1.0) (for real Q)
+C     JJV so reformulate test at 120 in terms of one EXP, if not too big
+C     JJV 87.49823 is close to the largest real which can be
+C     JJV exponentiated (87.49823 = log(1.0E38))
+C
+      IF ((q+e-0.5*t*t).GT.87.49823) GO TO 125
+      IF (c*abs(u).GT.exp(q+e-0.5*t*t)) GO TO 70
+      GO TO 125
+
+ 105  w = exp(q) - 1.0
+      GO TO 120
+
+  110 w = ((((e5*q+e4)*q+e3)*q+e2)*q+e1)*q
+C
+C               IF T IS REJECTED, SAMPLE AGAIN AT STEP 8
+C
+  120 IF (c*abs(u).GT.w*exp(e-0.5*t*t)) GO TO 70
+ 125  x = s + 0.5*t
+      sgamma = x*x
+      RETURN
+C
+C     ALTERNATE METHOD FOR PARAMETERS A BELOW 1  (.3678794=EXP(-1.))
+C
+C     JJV changed B to B0 (which was added to declarations for this)
+C     JJV in 130 to END to fix rare and subtle bug.
+C     JJV Line: '130 aa = 0.0' was removed (unnecessary, wasteful).
+C     JJV Reasons: the state of AA only serves to tell the A .GE. 1.0
+C     JJV case if certain A-dependant constants need to be recalculated.
+C     JJV The A .LT. 1.0 case (here) no longer changes any of these, and
+C     JJV the recalculation of B (which used to change with an
+C     JJV A .LT. 1.0 call) is governed by the state of AAA anyway.
+C
+ 130  b0 = 1.0 + .3678794*a
+  140 p = b0*ranf()
+      IF (p.GE.1.0) GO TO 150
+      sgamma = exp(alog(p)/a)
+      IF (sexpo().LT.sgamma) GO TO 140
+      RETURN
+
+  150 sgamma = -alog((b0-p)/a)
+      IF (sexpo().LT. (1.0-a)*alog(sgamma)) GO TO 140
+      RETURN
+
+      END
diff --git a/libcruft/ranlib/snorm.f b/libcruft/ranlib/snorm.f
new file mode 100644
index 0000000..29195ea
--- /dev/null
+++ b/libcruft/ranlib/snorm.f
@@ -0,0 +1,138 @@
+      REAL FUNCTION snorm()
+C**********************************************************************C
+C                                                                      C
+C                                                                      C
+C     (STANDARD-)  N O R M A L  DISTRIBUTION                           C
+C                                                                      C
+C                                                                      C
+C**********************************************************************C
+C**********************************************************************C
+C                                                                      C
+C     FOR DETAILS SEE:                                                 C
+C                                                                      C
+C               AHRENS, J.H. AND DIETER, U.                            C
+C               EXTENSIONS OF FORSYTHE'S METHOD FOR RANDOM             C
+C               SAMPLING FROM THE NORMAL DISTRIBUTION.                 C
+C               MATH. COMPUT., 27,124 (OCT. 1973), 927 - 937.          C
+C                                                                      C
+C     ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM 'FL'  C
+C     (M=5) IN THE ABOVE PAPER     (SLIGHTLY MODIFIED IMPLEMENTATION)  C
+C                                                                      C
+C     Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of   C
+C     SUNIF.  The argument IR thus goes away.                          C
+C                                                                      C
+C**********************************************************************C
+C
+C
+C     THE DEFINITIONS OF THE CONSTANTS A(K), D(K), T(K) AND
+C     H(K) ARE ACCORDING TO THE ABOVEMENTIONED ARTICLE
+C
+C     .. Local Scalars ..
+      REAL aa,s,tt,u,ustar,w,y
+      INTEGER i
+C     ..
+C     .. Local Arrays ..
+      REAL a(32),d(31),h(31),t(31)
+C     ..
+C     .. External Functions ..
+      REAL ranf
+      EXTERNAL ranf
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC float,int
+C     ..
+C     .. Save statement ..
+C     JJV added a Save statement for arrays initialized in Data statmts
+      SAVE a,d,t,h
+C     ..
+C     .. Data statements ..
+      DATA a/0.0,.3917609E-1,.7841241E-1,.1177699,.1573107,.1970991,
+     +     .2372021,.2776904,.3186394,.3601299,.4022501,.4450965,
+     +     .4887764,.5334097,.5791322,.6260990,.6744898,.7245144,
+     +     .7764218,.8305109,.8871466,.9467818,1.009990,1.077516,
+     +     1.150349,1.229859,1.318011,1.417797,1.534121,1.675940,
+     +     1.862732,2.153875/
+      DATA d/5*0.0,.2636843,.2425085,.2255674,.2116342,.1999243,
+     +     .1899108,.1812252,.1736014,.1668419,.1607967,.1553497,
+     +     .1504094,.1459026,.1417700,.1379632,.1344418,.1311722,
+     +     .1281260,.1252791,.1226109,.1201036,.1177417,.1155119,
+     +     .1134023,.1114027,.1095039/
+      DATA t/.7673828E-3,.2306870E-2,.3860618E-2,.5438454E-2,
+     +     .7050699E-2,.8708396E-2,.1042357E-1,.1220953E-1,.1408125E-1,
+     +     .1605579E-1,.1815290E-1,.2039573E-1,.2281177E-1,.2543407E-1,
+     +     .2830296E-1,.3146822E-1,.3499233E-1,.3895483E-1,.4345878E-1,
+     +     .4864035E-1,.5468334E-1,.6184222E-1,.7047983E-1,.8113195E-1,
+     +     .9462444E-1,.1123001,.1364980,.1716886,.2276241,.3304980,
+     +     .5847031/
+      DATA h/.3920617E-1,.3932705E-1,.3950999E-1,.3975703E-1,
+     +     .4007093E-1,.4045533E-1,.4091481E-1,.4145507E-1,.4208311E-1,
+     +     .4280748E-1,.4363863E-1,.4458932E-1,.4567523E-1,.4691571E-1,
+     +     .4833487E-1,.4996298E-1,.5183859E-1,.5401138E-1,.5654656E-1,
+     +     .5953130E-1,.6308489E-1,.6737503E-1,.7264544E-1,.7926471E-1,
+     +     .8781922E-1,.9930398E-1,.1155599,.1404344,.1836142,.2790016,
+     +     .7010474/
+C     ..
+C     .. Executable Statements ..
+C
+   10 u = ranf()
+      s = 0.0
+      IF (u.GT.0.5) s = 1.0
+      u = u + u - s
+   20 u = 32.0*u
+      i = int(u)
+      IF (i.EQ.32) i = 31
+      IF (i.EQ.0) GO TO 100
+C
+C                                START CENTER
+C
+   30 ustar = u - float(i)
+      aa = a(i)
+   40 IF (ustar.LE.t(i)) GO TO 60
+      w = (ustar-t(i))*h(i)
+C
+C                                EXIT   (BOTH CASES)
+C
+   50 y = aa + w
+      snorm = y
+      IF (s.EQ.1.0) snorm = -y
+      RETURN
+C
+C                                CENTER CONTINUED
+C
+   60 u = ranf()
+      w = u* (a(i+1)-aa)
+      tt = (0.5*w+aa)*w
+      GO TO 80
+
+   70 tt = u
+      ustar = ranf()
+   80 IF (ustar.GT.tt) GO TO 50
+   90 u = ranf()
+      IF (ustar.GE.u) GO TO 70
+      ustar = ranf()
+      GO TO 40
+C
+C                                START TAIL
+C
+  100 i = 6
+      aa = a(32)
+      GO TO 120
+
+  110 aa = aa + d(i)
+      i = i + 1
+  120 u = u + u
+      IF (u.LT.1.0) GO TO 110
+  130 u = u - 1.0
+  140 w = u*d(i)
+      tt = (0.5*w+aa)*w
+      GO TO 160
+
+  150 tt = u
+  160 ustar = ranf()
+      IF (ustar.GT.tt) GO TO 50
+  170 u = ranf()
+      IF (ustar.GE.u) GO TO 150
+      u = ranf()
+      GO TO 140
+
+      END
diff --git a/libcruft/ranlib/tstbot.for b/libcruft/ranlib/tstbot.for
new file mode 100644
index 0000000..4547f02
--- /dev/null
+++ b/libcruft/ranlib/tstbot.for
@@ -0,0 +1,94 @@
+      PROGRAM tstbot
+C**********************************************************************
+C
+C     A test program for the bottom level routines
+C
+C**********************************************************************
+C     Set up the random number generator
+C     .. Local Scalars ..
+      INTEGER ians,iblock,igen,iseed1,iseed2,itmp,ix,ixgen,nbad
+C     ..
+C     .. Local Arrays ..
+      INTEGER answer(10000),genlst(5)
+C     ..
+C     .. External Functions ..
+      INTEGER ignlgi
+      EXTERNAL ignlgi
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL getsd,initgn,setall,setcgn
+C     ..
+C     .. Data statements ..
+      DATA genlst/1,5,10,20,32/
+C     ..
+C     .. Executable Statements ..
+      nbad = 0
+      WRITE (*,9000)
+
+ 9000 FORMAT (' For five virual generators of the 32'/
+     +       ' This test generates 10000 numbers then resets the block'/
+     +       '      and does it again'/
+     +       ' Any disagreements are reported -- there should be none'/)
+C
+C     Set up Generators
+C
+      CALL setall(12345,54321)
+C
+C     For a selected set of generators
+C
+      DO 60,ixgen = 1,5
+          igen = genlst(ixgen)
+          CALL setcgn(igen)
+          WRITE (*,*) ' Testing generator ',igen
+C
+C     Use 10 blocks
+C
+          CALL initgn(-1)
+          CALL getsd(iseed1,iseed2)
+          DO 20,iblock = 1,10
+C
+C     Generate 1000 numbers
+C
+              DO 10,ians = 1,1000
+                  ix = ians + (iblock-1)*1000
+                  answer(ix) = ignlgi()
+   10         CONTINUE
+              CALL initgn(+1)
+   20     CONTINUE
+          CALL initgn(-1)
+C
+C     Do it again and compare answers
+C
+          CALL getsd(iseed1,iseed2)
+C
+C     Use 10 blocks
+C
+          DO 50,iblock = 1,10
+C
+C     Generate 1000 numbers
+C
+              DO 40,ians = 1,1000
+                  ix = ians + (iblock-1)*1000
+C      ANSWER( IX ) = IGNLGI()
+                  itmp = ignlgi()
+                  IF (.NOT. (itmp.NE.answer(ix))) GO TO 30
+                  WRITE (*,9010) iblock,ians,ix,answer(ix),itmp
+
+ 9010             FORMAT (' Disagreement on regeneration of numbers'/
+     +                   ' Block ',I2,' N within Block ',I2,
+     +                   ' Index in answer ',I5/
+     +                   ' Originally Generated ',I10,' Regenerated ',
+     +                   I10)
+
+                  nbad = nbad + 1
+                  IF (nbad.GT.10) STOP ' More than 10 mismatches'
+   30             CONTINUE
+   40         CONTINUE
+              CALL initgn(+1)
+   50     CONTINUE
+          WRITE (*,*) ' Finished testing generator ',igen
+          WRITE (*,*) ' Test completed successfully'
+   60 CONTINUE
+      STOP
+
+      END
diff --git a/libcruft/ranlib/tstgmn.for b/libcruft/ranlib/tstgmn.for
new file mode 100644
index 0000000..7c755a1
--- /dev/null
+++ b/libcruft/ranlib/tstgmn.for
@@ -0,0 +1,229 @@
+C     JJV changed name to ONECOV to avoid confusion with array COVAR
+C     JJV this was also changed in the body of the function
+C      REAL FUNCTION covar(x,y,n)
+      REAL FUNCTION onecov(x,y,n)
+C     .. Scalar Arguments ..
+      INTEGER n
+C     ..
+C     .. Array Arguments ..
+      REAL x(n),y(n)
+C     ..
+C     .. Local Scalars ..
+      REAL avx,avy,varx,vary,xmax,xmin
+      INTEGER i
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL stat
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC real
+C     ..
+C     .. Executable Statements ..
+      CALL stat(x,n,avx,varx,xmin,xmax)
+      CALL stat(y,n,avy,vary,xmin,xmax)
+C      covar = 0.0
+      onecov = 0.0
+      DO 10,i = 1,n
+C      covar = covar + (x(i)-avx)* (y(i)-avy)
+         onecov = onecov + (x(i)-avx)* (y(i)-avy)
+ 10   CONTINUE
+C      covar = covar/real(n-1)
+      onecov = onecov/real(n-1)
+      RETURN
+      
+      END
+
+C     JJV Added argument LDXCOV (leading dimension of XCOVAR) to be
+C     JJV consistent with the program TSTGMN, see comments below.
+C     JJV This change necessitated changes in the declarations.
+C      SUBROUTINE prcomp(p,mean,xcovar,answer)
+      SUBROUTINE prcomp(p,mean,xcovar,ldxcov,answer)
+
+C      INTEGER p,maxp
+      INTEGER p,maxp,ldxcov
+      PARAMETER (maxp=10)
+C      REAL mean(p),xcovar(p,p),rcovar(maxp,maxp)
+      REAL mean(p),xcovar(ldxcov,p),rcovar(maxp,maxp)
+      REAL answer(1000,maxp)
+C     JJV added ONECOV because of name change to function COVAR
+C      REAL rmean(maxp),rvar(maxp)
+      REAL rmean(maxp),rvar(maxp),onecov
+      INTEGER maxobs
+      PARAMETER (maxobs=1000)
+
+      DO 10,i = 1,p
+          CALL stat(answer(1,i),maxobs,rmean(i),rvar(i),dum1,dum2)
+          WRITE (*,*) ' Variable Number',i
+          WRITE (*,*) ' Mean ',mean(i),' Generated ',rmean(i)
+          WRITE (*,*) ' Variance ',xcovar(i,i),' Generated',rvar(i)
+   10 CONTINUE
+      WRITE (*,*) '                   Covariances'
+      DO 30,i = 1,p
+          DO 20,j = 1,i - 1
+              WRITE (*,*) ' I = ',i,' J = ',j
+C     JJV changed COVAR to match new name
+C              rcovar(i,j) = covar(answer(1,i),answer(1,j),maxobs)
+              rcovar(i,j) = onecov(answer(1,i),answer(1,j),maxobs)
+              WRITE (*,*) ' Covariance ',xcovar(i,j),' Generated ',
+     +          rcovar(i,j)
+   20     CONTINUE
+   30 CONTINUE
+      RETURN
+
+      END
+
+C     JJV added LDCOV (leading dimension of COVAR) to be
+C     JJV consistent with the program TSTGMN, see comments below.
+C     JJV This change necessitated changes in the declarations.
+C      SUBROUTINE setcov(p,var,corr,covar)
+      SUBROUTINE setcov(p,var,corr,covar,ldcov)
+C     Set covariance matrix from variance and common correlation
+C     .. Scalar Arguments ..
+      REAL corr
+C      INTEGER p
+      INTEGER p,ldcov
+C     ..
+C     .. Array Arguments ..
+C      REAL covar(p,p),var(p)
+      REAL covar(ldcov,p),var(p)
+C     ..
+C     .. Local Scalars ..
+      INTEGER i,j
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC sqrt
+C     ..
+C     .. Executable Statements ..
+      DO 40,i = 1,p
+          DO 30,j = 1,p
+              IF (.NOT. (i.EQ.j)) GO TO 10
+              covar(i,j) = var(i)
+              GO TO 20
+
+   10         covar(i,j) = corr*sqrt(var(i)*var(j))
+   20         CONTINUE
+   30     CONTINUE
+   40 CONTINUE
+      RETURN
+
+      END
+
+      SUBROUTINE stat(x,n,av,var,xmin,xmax)
+C     .. Scalar Arguments ..
+      REAL av,var,xmax,xmin
+      INTEGER n
+C     ..
+C     .. Array Arguments ..
+      REAL x(n)
+C     ..
+C     .. Local Scalars ..
+      REAL sum
+      INTEGER i
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC real
+C     ..
+C     .. Executable Statements ..
+      xmin = x(1)
+      xmax = x(1)
+      sum = 0.0
+      DO 10,i = 1,n
+          sum = sum + x(i)
+          IF (x(i).LT.xmin) xmin = x(i)
+          IF (x(i).GT.xmax) xmax = x(i)
+   10 CONTINUE
+      av = sum/real(n)
+      sum = 0.0
+      DO 20,i = 1,n
+          sum = sum + (x(i)-av)**2
+   20 CONTINUE
+      var = sum/real(n-1)
+      RETURN
+
+      END
+
+      PROGRAM tstgmn
+C     Test Generation of Multivariate Normal Data
+C     JJV SETGMN was: SUBROUTINE setgmn(meanv,covm,p,parm)
+C     JJV         is: SUBROUTINE setgmn(meanv,covm,ldcovm,p,parm)
+C     JJV So the covariance matrices have been changed to 2-dim'l
+C     JJV matrices, and the additional argument has been added to
+C     JJV the subroutine call.  Additional changes have been made
+C     JJV to reflect this.  (in declarations, the matrix copy routine,
+C     JJV and in subroutine calls.)
+C     .. Parameters ..
+      INTEGER maxp
+      PARAMETER (maxp=10)
+      INTEGER maxobs
+      PARAMETER (maxobs=1000)
+C     JJV this parameter is no longer needed
+C      INTEGER p2
+C      PARAMETER (p2=maxp*maxp)
+C     ..
+C     .. Local Scalars ..
+      REAL corr
+      INTEGER i,iobs,is1,is2,j,p
+      CHARACTER phrase*100
+C     ..
+C     .. Local Arrays ..
+C      REAL answer(1000,maxp),ccovar(p2),covar(p2),mean(maxp),param(500),
+C     +     temp(maxp),var(maxp),work(maxp)
+      REAL answer(1000,maxp),ccovar(maxp,maxp),covar(maxp,maxp),
+     +     mean(maxp),param(500),temp(maxp),var(maxp),work(maxp)
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL genmn,phrtsd,prcomp,setall,setcov,setgmn
+C     ..
+C     .. Executable Statements ..
+      WRITE (*,9000)
+
+ 9000 FORMAT (
+     +     ' Tests Multivariate Normal Generator for Up to 10 Variables'
+     +       /
+     +  ' User inputs means, variances, one correlation that is applied'
+     +       /'     to all pairs of variables'/
+     +       ' 1000 multivariate normal deviates are generated'/
+     +     ' Means, variances and covariances are calculated for these.'
+     +       )
+
+   10 WRITE (*,*) 'Enter number of variables for normal generator'
+      READ (*,*) p
+      WRITE (*,*) 'Enter mean vector of length ',p
+      READ (*,*) (mean(i),i=1,p)
+      WRITE (*,*) 'Enter variance vector of length ',p
+      READ (*,*) (var(i),i=1,p)
+      WRITE (*,*) 'Enter correlation of all variables'
+      READ (*,*) corr
+C      CALL setcov(p,var,corr,covar)
+      CALL setcov(p,var,corr,covar,maxp)
+      WRITE (*,*) ' Enter phrase to initialize rn generator'
+      READ (*,'(a)') phrase
+      CALL phrtsd(phrase,is1,is2)
+      CALL setall(is1,is2)
+C      DO 20,i = 1,p2
+C          ccovar(i) = covar(i)
+C 20   CONTINUE
+      DO 25,i = 1,maxp
+         DO 20,j = 1,maxp
+            ccovar(i,j) = covar(i,j)
+ 20      CONTINUE
+ 25   CONTINUE
+C
+C     Generate Variables
+C
+C      CALL setgmn(mean,ccovar,p,param)
+      CALL setgmn(mean,ccovar,maxp,p,param)
+      DO 40,iobs = 1,maxobs
+          CALL genmn(param,work,temp)
+          DO 30,j = 1,p
+              answer(iobs,j) = work(j)
+   30     CONTINUE
+   40 CONTINUE
+C      CALL prcomp(p,mean,covar,answer)
+      CALL prcomp(p,mean,covar,maxp,answer)
+C
+C     Print Comparison of Generated and Reconstructed Values
+C
+      GO TO 10
+
+      END
diff --git a/libcruft/ranlib/tstmid.for b/libcruft/ranlib/tstmid.for
new file mode 100644
index 0000000..2a00f8f
--- /dev/null
+++ b/libcruft/ranlib/tstmid.for
@@ -0,0 +1,611 @@
+      SUBROUTINE stat(x,n,av,var,xmin,xmax)
+C**********************************************************************
+C
+C     SUBROUTINE STAT( X, N, AV, VAR)
+C
+C               compute STATistics
+C
+C
+C                              Function
+C
+C
+C     Computes AVerage and VARiance of array X(N).
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL av,var,xmax,xmin
+      INTEGER n
+C     ..
+C     .. Array Arguments ..
+      REAL x(n)
+C     ..
+C     .. Local Scalars ..
+      REAL sum
+      INTEGER i
+C     ..
+C     .. Intrinsic Functions ..
+      INTRINSIC real
+C     ..
+C     .. Executable Statements ..
+      xmin = x(1)
+      xmax = x(1)
+      sum = 0.0
+      DO 10,i = 1,n
+          sum = sum + x(i)
+          IF (x(i).LT.xmin) xmin = x(i)
+          IF (x(i).GT.xmax) xmax = x(i)
+   10 CONTINUE
+      av = sum/real(n)
+      sum = 0.0
+      DO 20,i = 1,n
+          sum = sum + (x(i)-av)**2
+   20 CONTINUE
+      var = sum/real(n-1)
+      RETURN
+
+      END
+      PROGRAM tstall
+      IMPLICIT LOGICAL (q)
+C     Interactive test for PHRTSD
+C     .. Parameters ..
+      INTEGER mxwh,mxncat
+      PARAMETER (mxwh=15,mxncat=100)
+C     ..
+C     .. Local Scalars ..
+      REAL av,avtr,var,vartr,xmin,xmax,pevt,psum,rtry
+      INTEGER i,is1,is2,itmp,iwhich,j,mxint,nperm,nrep,ntot,ntry,ncat
+      CHARACTER type*4,phrase*100
+C     ..
+C     .. Local Arrays ..
+      REAL array(1000),param(3),prob(mxncat)
+      INTEGER iarray(1000),perm(500)
+C     ..
+C     .. External Functions ..
+      REAL genbet,genchi,genf,gennch,gennf,genunf,genexp,gengam,gennor
+      INTEGER ignuin,ignnbn
+      EXTERNAL genbet,genchi,genf,gennch,gennf,genunf,ignuin
+C     ..
+C     .. External Subroutines ..
+      EXTERNAL genprm,phrtsd,setall,stat,trstat,genmul
+C     ..
+C     .. Executable Statements ..
+      WRITE (*,9000)
+
+ 9000 FORMAT (' Tests most generators of specific distributions.'/
+     +       ' Generates 1000 deviates: reports mean and variance.'/
+     +       ' Also reports theoretical mean and variance.'/
+     +       ' If theoretical mean or var doesn''t exist prints -1.'/
+     +       ' For permutations, generates one permutation of 1..n'/
+     +       '     and prints it.'/
+     +       ' For uniform integers asks for upper bound, number of'/
+     +       '     replicates per integer in 1..upper bound.'/
+     +       '     Prints table of num times each integer generated.'/
+     +       ' For multinomial asks for number of events to be'/
+     +       '     classified, number of categories in which they'/
+     +       '     are to be classified, and the probabilities that'/
+     +       '     an event will be classified in the categories,'/
+     +       '     for all but the last category.  Prints table of'/
+     +       '     number of events by category, true probability'/
+     +       '     associated with each category, and observed'/
+     +       '     proportion of events in each category.')
+C
+C     Menu for choosing tests
+C
+   10 WRITE (*,9010)
+
+ 9010 FORMAT (' Enter number corresponding to choice:'/
+     +       '      (0) Exit this program'/
+     +       '      (1) Generate Chi-Square deviates'/
+     +       '      (2) Generate noncentral Chi-Square deviates'/
+     +       '      (3) Generate F deviates'/
+     +       '      (4) Generate noncentral F  deviates'/
+     +       '      (5) Generate random permutation'/
+     +       '      (6) Generate uniform integers'/
+     +       '      (7) Generate uniform reals'/
+     +       '      (8) Generate beta deviates'/
+     +       '      (9) Generate binomial outcomes'/
+     +       '     (10) Generate Poisson outcomes'/
+     +       '     (11) Generate exponential deviates'/
+     +       '     (12) Generate gamma deviates'/
+     +       '     (13) Generate multinomial outcomes'/
+     +       '     (14) Generate normal deviates'/
+     +       '     (15) Generate negative binomial outcomes'/)
+
+      READ (*,*) iwhich
+      IF (.NOT. (iwhich.LT.0.OR.iwhich.GT.mxwh)) GO TO 20
+      WRITE (*,*) ' Choices are 1..',mxwh,' - try again.'
+      GO TO 10
+
+   20 IF (iwhich.EQ.0) STOP ' Normal termination rn tests'
+      WRITE (*,*) ' Enter phrase to initialize rn generator'
+      READ (*,'(a)') phrase
+      CALL phrtsd(phrase,is1,is2)
+      CALL setall(is1,is2)
+
+      IF ((1).NE. (iwhich)) GO TO 40
+C
+C     Chi-square deviates
+C
+      type = 'chis'
+      WRITE (*,*) ' Enter (real) df for the chi-square generation'
+      READ (*,*) param(1)
+      DO 30,i = 1,1000
+          array(i) = genchi(param(1))
+   30 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+
+ 9020 FORMAT (' Mean Generated: ',T30,G15.7,5X,'True:',T60,
+     +       G15.7/' Variance Generated:',T30,G15.7,5X,'True:',T60,
+     +       G15.7/' Minimum: ',T30,G15.7,5X,'Maximum:',T60,G15.7)
+
+      GO TO 420
+
+   40 IF ((2).NE. (iwhich)) GO TO 60
+
+C
+C     Noncentral Chi-square deviates
+C
+      type = 'ncch'
+      WRITE (*,*) ' Enter (real) df'
+      WRITE (*,*) '       (real) noncentrality parameter'
+      READ (*,*) param(1),param(2)
+      DO 50,i = 1,1000
+          array(i) = gennch(param(1),param(2))
+   50 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+   60 IF ((3).NE. (iwhich)) GO TO 80
+
+C
+C     F deviates
+C
+      type = 'f'
+      WRITE (*,*) ' Enter (real) df of the numerator'
+      WRITE (*,*) '       (real) df of the denominator'
+      READ (*,*) param(1),param(2)
+      DO 70,i = 1,1000
+          array(i) = genf(param(1),param(2))
+   70 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+   80 IF ((4).NE. (iwhich)) GO TO 100
+
+C
+C     Noncentral F deviates
+C
+      type = 'ncf'
+      WRITE (*,*) ' Enter (real) df of the numerator'
+      WRITE (*,*) '       (real) df of the denominator'
+      WRITE (*,*) '       (real) noncentrality parameter'
+      READ (*,*) param(1),param(2),param(3)
+      DO 90,i = 1,1000
+          array(i) = gennf(param(1),param(2),param(3))
+   90 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+  100 IF ((5).NE. (iwhich)) GO TO 140
+
+C
+C     Random permutation
+C
+  110 WRITE (*,*) ' Enter size of permutation'
+      READ (*,*) nperm
+      IF (.NOT. (nperm.LT.1.OR.nperm.GT.500)) GO TO 120
+      WRITE (*,*) ' Permutation size must be between 1 and 500 ',
+     +  '- try again!'
+      GO TO 110
+
+  120 WRITE (*,*) '       Random Permutation Generated - Size',nperm
+      DO 130,i = 1,500
+          perm(i) = i
+  130 CONTINUE
+      CALL genprm(perm,nperm)
+      WRITE (*,*) ' Perm Generated'
+      WRITE (*,'(20I4)') (perm(i),i=1,nperm)
+      GO TO 420
+
+  140 IF ((6).NE. (iwhich)) GO TO 170
+
+C
+C     Uniform integer
+C
+      WRITE (*,*) ' Enter maximum uniform integer'
+      READ (*,*) mxint
+      WRITE (*,*) ' Enter number of replications per integer'
+      READ (*,*) nrep
+      DO 150,i = 1,1000
+          iarray(i) = 0
+  150 CONTINUE
+      ntot = mxint*nrep
+      DO 160,i = 1,ntot
+          itmp = ignuin(1,mxint)
+          iarray(itmp) = iarray(itmp) + 1
+  160 CONTINUE
+      WRITE (*,*) '         Counts of Integers Generated'
+      WRITE (*,'(20I4)') (iarray(j),j=1,mxint)
+      GO TO 420
+
+  170 IF ((7).NE. (iwhich)) GO TO 190
+
+C
+C     Uniform real
+C
+      type = 'unif'
+      WRITE (*,*) ' Enter Low then High bound for uniforms'
+      READ (*,*) param(1),param(2)
+      DO 180,i = 1,1000
+          array(i) = genunf(param(1),param(2))
+  180 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+  190 IF ((8).NE. (iwhich)) GO TO 210
+
+C
+C     Beta deviate
+C
+      type = 'beta'
+      WRITE (*,*) ' Enter A, B for Beta deviate'
+      READ (*,*) param(1),param(2)
+      DO 200,i = 1,1000
+          array(i) = genbet(param(1),param(2))
+  200 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+  210 IF ((9).NE. (iwhich)) GO TO 240
+
+C
+C     Binomial outcomes
+C
+      type = 'bin'
+      WRITE (*,*) ' Enter number of trials, Prob event for ',
+     +  'binomial outcomes'
+      READ (*,*) ntry,pevt
+      DO 220,i = 1,1000
+          iarray(i) = ignbin(ntry,pevt)
+  220 CONTINUE
+      DO 230,i = 1,1000
+          array(i) = iarray(i)
+  230 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      param(1) = ntry
+      param(2) = pevt
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+  240 IF ((10).NE. (iwhich)) GO TO 270
+
+C
+C     Poisson outcomes
+C
+      type = 'pois'
+      WRITE (*,*) ' Enter mean for Poisson generation'
+      READ (*,*) param(1)
+      DO 250,i = 1,1000
+          iarray(i) = ignpoi(param(1))
+  250 CONTINUE
+      DO 260,i = 1,1000
+          array(i) = iarray(i)
+  260 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+  270 IF ((11).NE. (iwhich)) GO TO 290
+
+C
+C     Exponential deviates
+C
+      type = 'expo'
+      WRITE (*,*) ' Enter (real) AV for Exponential'
+      READ (*,*) param(1)
+      DO 280,i = 1,1000
+          array(i) = genexp(param(1))
+ 280   CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+
+      GO TO 420
+
+ 290  IF ((12).NE. (iwhich)) GO TO 310
+
+C
+C     Gamma deviates
+C
+      type = 'gamm'
+      WRITE (*,*) ' Enter (real) A, (real) R for Gamma deviate'
+      READ (*,*) param(1),param(2)
+      DO 300,i = 1,1000
+          array(i) = gengam(param(1),param(2))
+  300 CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+ 310  IF ((13).NE. (iwhich)) GO TO 360
+
+C      
+C     Multinomial outcomes
+C
+      WRITE (*,*) ' Enter (int) number of observations: '
+      READ (*,*) ntry
+ 320  WRITE (*,*) ' Enter (int) num. of categories: <= ',mxncat
+      READ (*,*) ncat
+      IF (ncat.GT.mxncat) THEN
+         WRITE (*,*) ' number of categories must be <= ',mxncat
+         WRITE (*,*) ' Try again ... '
+         GO TO 320
+      END IF
+      WRITE (*,*) ' Enter (real) prob. vector of length ',ncat-1
+      READ (*,*) (prob(i),i=1,ncat-1)
+      CALL genmul(ntry,prob,ncat,iarray)
+      ntot = 0
+      IF (ntry.GT.0) THEN
+         rtry = real(ntry)
+         DO 330, i = 1,ncat
+            ntot = ntot + iarray(i)
+            array(i) = iarray(i)/rtry
+ 330     CONTINUE
+      ELSE
+         DO 340, i = 1,ncat
+            ntot = ntot + iarray(i)
+            array(i) = 0.0
+ 340     CONTINUE
+      ENDIF
+      psum = 0.0
+      DO 350, i = 1,ncat-1
+         psum = psum + prob(i)
+ 350  CONTINUE
+      prob(ncat) = 1.0 - psum
+
+      WRITE (*,*) ' Total number of observations: ',ntot
+      WRITE (*,*) ' Total observations by category: '
+      WRITE (*,'(10I8)') (iarray(i),i=1,ncat)
+      WRITE (*,*) ' True probabilities by category: '
+      WRITE (*,'(8F10.7)') (prob(i),i=1,ncat)
+      WRITE (*,*) ' Observed proportions by category: '
+      WRITE (*,'(8F10.7)') (array(i),i=1,ncat)
+      GO TO 420
+
+ 360  IF ((14).NE. (iwhich)) GO TO 380
+
+C
+C     Normal deviates
+C
+      type = 'norm'
+      WRITE (*,*) ' Enter (real) AV, (real) SD for Normal'
+      READ (*,*) param(1),param(2)
+      DO 370,i = 1,1000
+         array(i) = gennor(param(1),param(2))
+ 370  CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+ 380  IF ((15).NE. (iwhich)) GO TO 410
+
+C
+C     Negative Binomial outcomes
+C
+      type = 'nbin'
+      WRITE (*,*) ' Enter required (int) Number of events then '
+      WRITE (*,*) ' (real) Prob of an event for negative binomial'
+      READ (*,*) ntry,pevt
+      DO 390,i = 1,1000
+         iarray(i) = ignnbn(ntry,pevt)
+ 390  CONTINUE
+      DO 400,i = 1,1000
+         array(i) = iarray(i)
+ 400  CONTINUE
+      CALL stat(array,1000,av,var,xmin,xmax)
+      param(1) = ntry
+      param(2) = pevt
+      CALL trstat(type,param,avtr,vartr)
+      WRITE (*,9020) av,avtr,var,vartr,xmin,xmax
+      GO TO 420
+
+ 410  CONTINUE
+ 420  GO TO 10
+
+      END
+      SUBROUTINE trstat(type,parin,av,var)
+      IMPLICIT INTEGER (i-n),REAL (a-h,o-p,r-z),LOGICAL (q)
+C**********************************************************************
+C
+C     SUBROUTINE TRSTAT( TYPE, PARIN, AV, VAR )
+C               TRue STATistics
+C
+C     Returns mean and variance for a number of statistical distribution
+C     as a function of their parameters.
+C
+C
+C                              Arguments
+C
+C
+C     TYPE --> Character string indicating type of distribution
+C             'chis' chisquare
+C             'ncch' noncentral chisquare
+C             'f'    F (variance ratio)
+C             'ncf'  noncentral f
+C             'unif' uniform
+C             'beta' beta distribution
+C             'bin'  binomial
+C             'pois' poisson
+C             'expo' exponential
+C             'gamm' gamma
+C             'norm' normal
+C             'nbin' negative binomial
+C                         CHARACTER*(4) TYPE
+C
+C     PARIN --> Array containing parameters of distribution
+C              chisquare
+C               PARIN(1) is df
+C              noncentral chisquare
+C               PARIN(1) is df
+C               PARIN(2) is noncentrality parameter
+C              F (variance ratio)
+C               PARIN(1) is df numerator
+C               PARIN(2) is df denominator
+C              noncentral F
+C               PARIN(1) is df numerator
+C               PARIN(2) is df denominator
+C               PARIN(3) is noncentrality parameter
+C              uniform
+C               PARIN(1) is LOW bound
+C               PARIN(2) is HIGH bound
+C              beta
+C               PARIN(1) is A
+C               PARIN(2) is B
+C              binomial
+C               PARIN(1) is Number of trials
+C               PARIN(2) is Prob Event at Each Trial
+C              poisson
+C               PARIN(1) is Mean
+C              exponential
+C               PARIN(1) is Mean
+C              gamma
+C               PARIN(1) is A
+C               PARIN(2) is R
+C              normal
+C               PARIN(1) is Mean
+C               PARIN(2) is Standard Deviation
+C              negative binomial
+C               PARIN(1) is required Number of events
+C               PARIN(2) is Probability of event
+C                         REAL PARIN(*)
+C
+C     AV <-- Mean of specified distribution with specified parameters
+C                         REAL AV
+C
+C     VAR <-- Variance of specified distribution with specified paramete
+C                         REAL VAR
+C
+C
+C                              Note
+C
+C
+C     AV and Var will be returned -1 if mean or variance is infinite
+C
+C**********************************************************************
+C     .. Scalar Arguments ..
+      REAL av,var
+      CHARACTER type* (4)
+C     ..
+C     .. Array Arguments ..
+      REAL parin(*)
+C     ..
+C     .. Local Scalars ..
+      REAL a,b,range
+C     ..
+C     .. Executable Statements ..
+      IF (('chis').NE. (type)) GO TO 10
+      av = parin(1)
+      var = 2.0*parin(1)
+      GO TO 210
+
+   10 IF (('ncch').NE. (type)) GO TO 20
+      a = parin(1) + parin(2)
+      b = parin(2)/a
+      av = a
+      var = 2.0*a* (1.0+b)
+      GO TO 210
+
+   20 IF (('f').NE. (type)) GO TO 70
+      IF (.NOT. (parin(2).LE.2.0001)) GO TO 30
+      av = -1.0
+      GO TO 40
+
+   30 av = parin(2)/ (parin(2)-2.0)
+   40 IF (.NOT. (parin(2).LE.4.0001)) GO TO 50
+      var = -1.0
+      GO TO 60
+
+   50 var = (2.0*parin(2)**2* (parin(1)+parin(2)-2.0))/
+     +      (parin(1)* (parin(2)-2.0)**2* (parin(2)-4.0))
+   60 GO TO 210
+
+   70 IF (('ncf').NE. (type)) GO TO 120
+      IF (.NOT. (parin(2).LE.2.0001)) GO TO 80
+      av = -1.0
+      GO TO 90
+
+   80 av = (parin(2)* (parin(1)+parin(3)))/ ((parin(2)-2.0)*parin(1))
+   90 IF (.NOT. (parin(2).LE.4.0001)) GO TO 100
+      var = -1.0
+      GO TO 110
+
+  100 a = (parin(1)+parin(3))**2 + (parin(1)+2.0*parin(3))*
+     +    (parin(2)-2.0)
+      b = (parin(2)-2.0)**2* (parin(2)-4.0)
+      var = 2.0* (parin(2)/parin(1))**2* (a/b)
+  110 GO TO 210
+
+  120 IF (('unif').NE. (type)) GO TO 130
+      range = parin(2) - parin(1)
+      av = parin(1) + range/2.0
+      var = range**2/12.0
+      GO TO 210
+
+  130 IF (('beta').NE. (type)) GO TO 140
+      av = parin(1)/ (parin(1)+parin(2))
+      var = (av*parin(2))/ ((parin(1)+parin(2))*
+     +      (parin(1)+parin(2)+1.0))
+      GO TO 210
+
+  140 IF (('bin').NE. (type)) GO TO 150
+      av = parin(1)*parin(2)
+      var = av* (1.0-parin(2))
+      GO TO 210
+
+  150 IF (('pois').NE. (type)) GO TO 160
+      av = parin(1)
+      var = parin(1)
+      GO TO 210
+
+ 160  IF (('expo').NE. (type)) GO TO 170
+      av = parin(1)
+      var = parin(1)**2
+      GO TO 210
+
+ 170  IF (('gamm').NE. (type)) GO TO 180
+      av = parin(2) / parin(1)
+      var = av / parin(1)
+      GO TO 210
+
+ 180  IF (('norm').NE. (type)) GO TO 190
+      av = parin(1)
+      var = parin(2)**2
+      GO TO 210
+
+ 190  IF (('nbin').NE. (type)) GO TO 200
+      av = parin(1) * (1.0 - parin(2)) / parin(2)
+      var = av / parin(2)
+      GO TO 210
+
+  200 WRITE (*,*) 'Unimplemented type ',type
+      STOP 'Unimplemented type in TRSTAT'
+
+  210 RETURN
+
+      END
diff --git a/libcruft/ranlib/wrap.f b/libcruft/ranlib/wrap.f
new file mode 100644
index 0000000..1ac5804
--- /dev/null
+++ b/libcruft/ranlib/wrap.f
@@ -0,0 +1,25 @@
+      subroutine dgennor (av, sd, result)
+      double precision av, sd, result
+      result = gennor (real (av), real (sd))
+      return
+      end
+      subroutine dgenunf (low, high, result)
+      double precision low, high, result
+      result = genunf (real (low), real (high))
+      return
+      end
+      subroutine dgenexp (av, result)
+      double precision av, result
+      result = genexp (real (av))
+      return
+      end
+      subroutine dgengam (a, r, result)
+      double precision a, r, result
+      result = gengam (real (a), real (r))
+      return
+      end
+      subroutine dignpoi (mu, result)
+      double precision mu, result
+      result = ignpoi (real (mu))
+      return
+      end
diff --git a/libcruft/slatec-err/Makefile.in b/libcruft/slatec-err/Makefile.in
new file mode 100644
index 0000000..ec2e4c4
--- /dev/null
+++ b/libcruft/slatec-err/Makefile.in
@@ -0,0 +1,34 @@
+# Makefile for octave's libcruft/slatec-err directory
+#
+# Copyright (C) 1999, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+include $(TOPDIR)/Makeconf
+
+FSRC = fdump.f ixsav.f j4save.f xerclr.f xercnt.f xerhlt.f xermsg.f \
+  xerprn.f xerrwd.f xersve.f xgetf.f xgetua.f xsetf.f xsetua.f
+
+include ../Makerules
diff --git a/libcruft/slatec-err/fdump.f b/libcruft/slatec-err/fdump.f
new file mode 100644
index 0000000..1f44a57
--- /dev/null
+++ b/libcruft/slatec-err/fdump.f
@@ -0,0 +1,31 @@
+*DECK FDUMP
+      SUBROUTINE FDUMP
+C***BEGIN PROLOGUE  FDUMP
+C***PURPOSE  Symbolic dump (should be locally written).
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3
+C***TYPE      ALL (FDUMP-A)
+C***KEYWORDS  ERROR, XERMSG
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C        ***Note*** Machine Dependent Routine
+C        FDUMP is intended to be replaced by a locally written
+C        version which produces a symbolic dump.  Failing this,
+C        it should be replaced by a version which prints the
+C        subprogram nesting list.  Note that this dump must be
+C        printed on each of up to five files, as indicated by the
+C        XGETUA routine.  See XSETUA and XGETUA for details.
+C
+C     Written by Ron Jones, with SLATEC Common Math Library Subcommittee
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C***END PROLOGUE  FDUMP
+C***FIRST EXECUTABLE STATEMENT  FDUMP
+      RETURN
+      END
diff --git a/libcruft/slatec-err/ixsav.f b/libcruft/slatec-err/ixsav.f
new file mode 100644
index 0000000..6484541
--- /dev/null
+++ b/libcruft/slatec-err/ixsav.f
@@ -0,0 +1,70 @@
+*DECK IXSAV
+      INTEGER FUNCTION IXSAV (IPAR, IVALUE, ISET)
+C***BEGIN PROLOGUE  IXSAV
+C***SUBSIDIARY
+C***PURPOSE  Save and recall error message control parameters.
+C***LIBRARY   MATHLIB
+C***CATEGORY  R3C
+C***TYPE      ALL (IXSAV-A)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  IXSAV saves and recalls one of two error message parameters:
+C    LUNIT, the logical unit number to which messages are printed, and
+C    MESFLG, the message print flag.
+C  This is a modification of the SLATEC library routine J4SAVE.
+C
+C  Saved local variables..
+C   LUNIT  = Logical unit number for messages.
+C   LUNDEF = Default logical unit number, data-loaded to 6 below
+C            (may be machine-dependent).
+C   MESFLG = Print control flag..
+C            1 means print all messages (the default).
+C            0 means no printing.
+C
+C  On input..
+C    IPAR   = Parameter indicator (1 for LUNIT, 2 for MESFLG).
+C    IVALUE = The value to be set for the parameter, if ISET = .TRUE.
+C    ISET   = Logical flag to indicate whether to read or write.
+C             If ISET = .TRUE., the parameter will be given
+C             the value IVALUE.  If ISET = .FALSE., the parameter
+C             will be unchanged, and IVALUE is a dummy argument.
+C
+C  On return..
+C    IXSAV = The (old) value of the parameter.
+C
+C***SEE ALSO  XERMSG, XERRWD, XERRWV
+C***ROUTINES CALLED  NONE
+C***REVISION HISTORY  (YYMMDD)
+C   921118  DATE WRITTEN
+C   930329  Modified prologue to SLATEC format. (FNF)
+C   941025  Minor modification re default unit number. (ACH)
+C***END PROLOGUE  IXSAV
+C
+C**End
+      LOGICAL ISET
+      INTEGER IPAR, IVALUE
+C-----------------------------------------------------------------------
+      INTEGER LUNIT, LUNDEF, MESFLG
+C-----------------------------------------------------------------------
+C The following Fortran-77 declaration is to cause the values of the
+C listed (local) variables to be saved between calls to this routine.
+C-----------------------------------------------------------------------
+      SAVE LUNIT, LUNDEF, MESFLG
+      DATA LUNIT/-1/, LUNDEF/6/, MESFLG/1/
+C
+C***FIRST EXECUTABLE STATEMENT  IXSAV
+      IF (IPAR .EQ. 1) THEN
+        IF (LUNIT .EQ. -1) LUNIT = LUNDEF
+        IXSAV = LUNIT
+        IF (ISET) LUNIT = IVALUE
+        ENDIF
+C
+      IF (IPAR .EQ. 2) THEN
+        IXSAV = MESFLG
+        IF (ISET) MESFLG = IVALUE
+        ENDIF
+C
+      RETURN
+C----------------------- End of Function IXSAV -------------------------
+      END
diff --git a/libcruft/slatec-err/j4save.f b/libcruft/slatec-err/j4save.f
new file mode 100644
index 0000000..89c17d3
--- /dev/null
+++ b/libcruft/slatec-err/j4save.f
@@ -0,0 +1,65 @@
+*DECK J4SAVE
+      FUNCTION J4SAVE (IWHICH, IVALUE, ISET)
+C***BEGIN PROLOGUE  J4SAVE
+C***SUBSIDIARY
+C***PURPOSE  Save or recall global variables needed by error
+C            handling routines.
+C***LIBRARY   SLATEC (XERROR)
+C***TYPE      INTEGER (J4SAVE-I)
+C***KEYWORDS  ERROR MESSAGES, ERROR NUMBER, RECALL, SAVE, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        J4SAVE saves and recalls several global variables needed
+C        by the library error handling routines.
+C
+C     Description of Parameters
+C      --Input--
+C        IWHICH - Index of item desired.
+C                = 1 Refers to current error number.
+C                = 2 Refers to current error control flag.
+C                = 3 Refers to current unit number to which error
+C                    messages are to be sent.  (0 means use standard.)
+C                = 4 Refers to the maximum number of times any
+C                     message is to be printed (as set by XERMAX).
+C                = 5 Refers to the total number of units to which
+C                     each error message is to be written.
+C                = 6 Refers to the 2nd unit for error messages
+C                = 7 Refers to the 3rd unit for error messages
+C                = 8 Refers to the 4th unit for error messages
+C                = 9 Refers to the 5th unit for error messages
+C        IVALUE - The value to be set for the IWHICH-th parameter,
+C                 if ISET is .TRUE. .
+C        ISET   - If ISET=.TRUE., the IWHICH-th parameter will BE
+C                 given the value, IVALUE.  If ISET=.FALSE., the
+C                 IWHICH-th parameter will be unchanged, and IVALUE
+C                 is a dummy parameter.
+C      --Output--
+C        The (old) value of the IWHICH-th parameter will be returned
+C        in the function value, J4SAVE.
+C
+C***SEE ALSO  XERMSG
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900205  Minor modifications to prologue.  (WRB)
+C   900402  Added TYPE section.  (WRB)
+C   910411  Added KEYWORDS section.  (WRB)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  J4SAVE
+      LOGICAL ISET
+      INTEGER IPARAM(9)
+      SAVE IPARAM
+      DATA IPARAM(1),IPARAM(2),IPARAM(3),IPARAM(4)/0,2,0,-1/
+      DATA IPARAM(5)/1/
+      DATA IPARAM(6),IPARAM(7),IPARAM(8),IPARAM(9)/0,0,0,0/
+C***FIRST EXECUTABLE STATEMENT  J4SAVE
+      J4SAVE = IPARAM(IWHICH)
+      IF (ISET) IPARAM(IWHICH) = IVALUE
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xerclr.f b/libcruft/slatec-err/xerclr.f
new file mode 100644
index 0000000..e190284
--- /dev/null
+++ b/libcruft/slatec-err/xerclr.f
@@ -0,0 +1,31 @@
+*DECK XERCLR
+      SUBROUTINE XERCLR
+C***BEGIN PROLOGUE  XERCLR
+C***PURPOSE  Reset current error number to zero.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XERCLR-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        This routine simply resets the current error number to zero.
+C        This may be necessary in order to determine that a certain
+C        error has occurred again since the last time NUMXER was
+C        referenced.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  J4SAVE
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XERCLR
+C***FIRST EXECUTABLE STATEMENT  XERCLR
+      JUNK = J4SAVE(1,0,.TRUE.)
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xercnt.f b/libcruft/slatec-err/xercnt.f
new file mode 100644
index 0000000..06c82ab
--- /dev/null
+++ b/libcruft/slatec-err/xercnt.f
@@ -0,0 +1,60 @@
+*DECK XERCNT
+      SUBROUTINE XERCNT (LIBRAR, SUBROU, MESSG, NERR, LEVEL, KONTRL)
+C***BEGIN PROLOGUE  XERCNT
+C***SUBSIDIARY
+C***PURPOSE  Allow user control over handling of errors.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XERCNT-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        Allows user control over handling of individual errors.
+C        Just after each message is recorded, but before it is
+C        processed any further (i.e., before it is printed or
+C        a decision to abort is made), a call is made to XERCNT.
+C        If the user has provided his own version of XERCNT, he
+C        can then override the value of KONTROL used in processing
+C        this message by redefining its value.
+C        KONTRL may be set to any value from -2 to 2.
+C        The meanings for KONTRL are the same as in XSETF, except
+C        that the value of KONTRL changes only for this message.
+C        If KONTRL is set to a value outside the range from -2 to 2,
+C        it will be moved back into that range.
+C
+C     Description of Parameters
+C
+C      --Input--
+C        LIBRAR - the library that the routine is in.
+C        SUBROU - the subroutine that XERMSG is being called from
+C        MESSG  - the first 20 characters of the error message.
+C        NERR   - same as in the call to XERMSG.
+C        LEVEL  - same as in the call to XERMSG.
+C        KONTRL - the current value of the control flag as set
+C                 by a call to XSETF.
+C
+C      --Output--
+C        KONTRL - the new value of KONTRL.  If KONTRL is not
+C                 defined, it will remain at its original value.
+C                 This changed value of control affects only
+C                 the current occurrence of the current message.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900206  Routine changed from user-callable to subsidiary.  (WRB)
+C   900510  Changed calling sequence to include LIBRARY and SUBROUTINE
+C           names, changed routine name from XERCTL to XERCNT.  (RWC)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XERCNT
+      CHARACTER*(*) LIBRAR, SUBROU, MESSG
+C***FIRST EXECUTABLE STATEMENT  XERCNT
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xerhlt.f b/libcruft/slatec-err/xerhlt.f
new file mode 100644
index 0000000..141d280
--- /dev/null
+++ b/libcruft/slatec-err/xerhlt.f
@@ -0,0 +1,39 @@
+*DECK XERHLT
+      SUBROUTINE XERHLT (MESSG)
+C***BEGIN PROLOGUE  XERHLT
+C***SUBSIDIARY
+C***PURPOSE  Abort program execution and print error message.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XERHLT-A)
+C***KEYWORDS  ABORT PROGRAM EXECUTION, ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        ***Note*** machine dependent routine
+C        XERHLT aborts the execution of the program.
+C        The error message causing the abort is given in the calling
+C        sequence, in case one needs it for printing on a dayfile,
+C        for example.
+C
+C     Description of Parameters
+C        MESSG is as in XERMSG.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900206  Routine changed from user-callable to subsidiary.  (WRB)
+C   900510  Changed calling sequence to delete length of character
+C           and changed routine name from XERABT to XERHLT.  (RWC)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XERHLT
+      CHARACTER*(*) MESSG
+C***FIRST EXECUTABLE STATEMENT  XERHLT
+      CALL XSTOPX (MESSG)
+      END
diff --git a/libcruft/slatec-err/xermsg.f b/libcruft/slatec-err/xermsg.f
new file mode 100644
index 0000000..0584a9b
--- /dev/null
+++ b/libcruft/slatec-err/xermsg.f
@@ -0,0 +1,368 @@
+*DECK XERMSG
+      SUBROUTINE XERMSG (LIBRAR, SUBROU, MESSG, NERR, LEVEL)
+C***BEGIN PROLOGUE  XERMSG
+C***PURPOSE  Process error messages for SLATEC and other libraries.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XERMSG-A)
+C***KEYWORDS  ERROR MESSAGE, XERROR
+C***AUTHOR  Fong, Kirby, (NMFECC at LLNL)
+C***DESCRIPTION
+C
+C   XERMSG processes a diagnostic message in a manner determined by the
+C   value of LEVEL and the current value of the library error control
+C   flag, KONTRL.  See subroutine XSETF for details.
+C
+C    LIBRAR   A character constant (or character variable) with the name
+C             of the library.  This will be 'SLATEC' for the SLATEC
+C             Common Math Library.  The error handling package is
+C             general enough to be used by many libraries
+C             simultaneously, so it is desirable for the routine that
+C             detects and reports an error to identify the library name
+C             as well as the routine name.
+C
+C    SUBROU   A character constant (or character variable) with the name
+C             of the routine that detected the error.  Usually it is the
+C             name of the routine that is calling XERMSG.  There are
+C             some instances where a user callable library routine calls
+C             lower level subsidiary routines where the error is
+C             detected.  In such cases it may be more informative to
+C             supply the name of the routine the user called rather than
+C             the name of the subsidiary routine that detected the
+C             error.
+C
+C    MESSG    A character constant (or character variable) with the text
+C             of the error or warning message.  In the example below,
+C             the message is a character constant that contains a
+C             generic message.
+C
+C                   CALL XERMSG ('SLATEC', 'MMPY',
+C                  *'THE ORDER OF THE MATRIX EXCEEDS THE ROW DIMENSION',
+C                  *3, 1)
+C
+C             It is possible (and is sometimes desirable) to generate a
+C             specific message--e.g., one that contains actual numeric
+C             values.  Specific numeric values can be converted into
+C             character strings using formatted WRITE statements into
+C             character variables.  This is called standard Fortran
+C             internal file I/O and is exemplified in the first three
+C             lines of the following example.  You can also catenate
+C             substrings of characters to construct the error message.
+C             Here is an example showing the use of both writing to
+C             an internal file and catenating character strings.
+C
+C                   CHARACTER*5 CHARN, CHARL
+C                   WRITE (CHARN,10) N
+C                   WRITE (CHARL,10) LDA
+C                10 FORMAT(I5)
+C                   CALL XERMSG ('SLATEC', 'MMPY', 'THE ORDER'//CHARN//
+C                  *   ' OF THE MATRIX EXCEEDS ITS ROW DIMENSION OF'//
+C                  *   CHARL, 3, 1)
+C
+C             There are two subtleties worth mentioning.  One is that
+C             the // for character catenation is used to construct the
+C             error message so that no single character constant is
+C             continued to the next line.  This avoids confusion as to
+C             whether there are trailing blanks at the end of the line.
+C             The second is that by catenating the parts of the message
+C             as an actual argument rather than encoding the entire
+C             message into one large character variable, we avoid
+C             having to know how long the message will be in order to
+C             declare an adequate length for that large character
+C             variable.  XERMSG calls XERPRN to print the message using
+C             multiple lines if necessary.  If the message is very long,
+C             XERPRN will break it into pieces of 72 characters (as
+C             requested by XERMSG) for printing on multiple lines.
+C             Also, XERMSG asks XERPRN to prefix each line with ' *  '
+C             so that the total line length could be 76 characters.
+C             Note also that XERPRN scans the error message backwards
+C             to ignore trailing blanks.  Another feature is that
+C             the substring '$$' is treated as a new line sentinel
+C             by XERPRN.  If you want to construct a multiline
+C             message without having to count out multiples of 72
+C             characters, just use '$$' as a separator.  '$$'
+C             obviously must occur within 72 characters of the
+C             start of each line to have its intended effect since
+C             XERPRN is asked to wrap around at 72 characters in
+C             addition to looking for '$$'.
+C
+C    NERR     An integer value that is chosen by the library routine's
+C             author.  It must be in the range -99 to 999 (three
+C             printable digits).  Each distinct error should have its
+C             own error number.  These error numbers should be described
+C             in the machine readable documentation for the routine.
+C             The error numbers need be unique only within each routine,
+C             so it is reasonable for each routine to start enumerating
+C             errors from 1 and proceeding to the next integer.
+C
+C    LEVEL    An integer value in the range 0 to 2 that indicates the
+C             level (severity) of the error.  Their meanings are
+C
+C            -1  A warning message.  This is used if it is not clear
+C                that there really is an error, but the user's attention
+C                may be needed.  An attempt is made to only print this
+C                message once.
+C
+C             0  A warning message.  This is used if it is not clear
+C                that there really is an error, but the user's attention
+C                may be needed.
+C
+C             1  A recoverable error.  This is used even if the error is
+C                so serious that the routine cannot return any useful
+C                answer.  If the user has told the error package to
+C                return after recoverable errors, then XERMSG will
+C                return to the Library routine which can then return to
+C                the user's routine.  The user may also permit the error
+C                package to terminate the program upon encountering a
+C                recoverable error.
+C
+C             2  A fatal error.  XERMSG will not return to its caller
+C                after it receives a fatal error.  This level should
+C                hardly ever be used; it is much better to allow the
+C                user a chance to recover.  An example of one of the few
+C                cases in which it is permissible to declare a level 2
+C                error is a reverse communication Library routine that
+C                is likely to be called repeatedly until it integrates
+C                across some interval.  If there is a serious error in
+C                the input such that another step cannot be taken and
+C                the Library routine is called again without the input
+C                error having been corrected by the caller, the Library
+C                routine will probably be called forever with improper
+C                input.  In this case, it is reasonable to declare the
+C                error to be fatal.
+C
+C    Each of the arguments to XERMSG is input; none will be modified by
+C    XERMSG.  A routine may make multiple calls to XERMSG with warning
+C    level messages; however, after a call to XERMSG with a recoverable
+C    error, the routine should return to the user.  Do not try to call
+C    XERMSG with a second recoverable error after the first recoverable
+C    error because the error package saves the error number.  The user
+C    can retrieve this error number by calling another entry point in
+C    the error handling package and then clear the error number when
+C    recovering from the error.  Calling XERMSG in succession causes the
+C    old error number to be overwritten by the latest error number.
+C    This is considered harmless for error numbers associated with
+C    warning messages but must not be done for error numbers of serious
+C    errors.  After a call to XERMSG with a recoverable error, the user
+C    must be given a chance to call NUMXER or XERCLR to retrieve or
+C    clear the error number.
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  FDUMP, J4SAVE, XERCNT, XERHLT, XERPRN, XERSVE
+C***REVISION HISTORY  (YYMMDD)
+C   880101  DATE WRITTEN
+C   880621  REVISED AS DIRECTED AT SLATEC CML MEETING OF FEBRUARY 1988.
+C           THERE ARE TWO BASIC CHANGES.
+C           1.  A NEW ROUTINE, XERPRN, IS USED INSTEAD OF XERPRT TO
+C               PRINT MESSAGES.  THIS ROUTINE WILL BREAK LONG MESSAGES
+C               INTO PIECES FOR PRINTING ON MULTIPLE LINES.  '$$' IS
+C               ACCEPTED AS A NEW LINE SENTINEL.  A PREFIX CAN BE
+C               ADDED TO EACH LINE TO BE PRINTED.  XERMSG USES EITHER
+C               ' ***' OR ' *  ' AND LONG MESSAGES ARE BROKEN EVERY
+C               72 CHARACTERS (AT MOST) SO THAT THE MAXIMUM LINE
+C               LENGTH OUTPUT CAN NOW BE AS GREAT AS 76.
+C           2.  THE TEXT OF ALL MESSAGES IS NOW IN UPPER CASE SINCE THE
+C               FORTRAN STANDARD DOCUMENT DOES NOT ADMIT THE EXISTENCE
+C               OF LOWER CASE.
+C   880708  REVISED AFTER THE SLATEC CML MEETING OF JUNE 29 AND 30.
+C           THE PRINCIPAL CHANGES ARE
+C           1.  CLARIFY COMMENTS IN THE PROLOGUES
+C           2.  RENAME XRPRNT TO XERPRN
+C           3.  REWORK HANDLING OF '$$' IN XERPRN TO HANDLE BLANK LINES
+C               SIMILAR TO THE WAY FORMAT STATEMENTS HANDLE THE /
+C               CHARACTER FOR NEW RECORDS.
+C   890706  REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO
+C           CLEAN UP THE CODING.
+C   890721  REVISED TO USE NEW FEATURE IN XERPRN TO COUNT CHARACTERS IN
+C           PREFIX.
+C   891013  REVISED TO CORRECT COMMENTS.
+C   891214  Prologue converted to Version 4.0 format.  (WRB)
+C   900510  Changed test on NERR to be -9999999 < NERR < 99999999, but
+C           NERR .ne. 0, and on LEVEL to be -2 < LEVEL < 3.  Added
+C           LEVEL=-1 logic, changed calls to XERSAV to XERSVE, and
+C           XERCTL to XERCNT.  (RWC)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XERMSG
+      CHARACTER*(*) LIBRAR, SUBROU, MESSG
+      CHARACTER*8 XLIBR, XSUBR
+      CHARACTER*72  TEMP
+      CHARACTER*20  LFIRST
+C***FIRST EXECUTABLE STATEMENT  XERMSG
+      LKNTRL = J4SAVE (2, 0, .FALSE.)
+      MAXMES = J4SAVE (4, 0, .FALSE.)
+C
+C       LKNTRL IS A LOCAL COPY OF THE CONTROL FLAG KONTRL.
+C       MAXMES IS THE MAXIMUM NUMBER OF TIMES ANY PARTICULAR MESSAGE
+C          SHOULD BE PRINTED.  IF MAXMES IS LESS THAN ZERO, THERE IS
+C          NO LIMIT.
+C
+C       WE PRINT A FATAL ERROR MESSAGE AND TERMINATE FOR AN ERROR IN
+C          CALLING XERMSG.  THE ERROR NUMBER SHOULD BE POSITIVE,
+C          AND THE LEVEL SHOULD BE BETWEEN 0 AND 2.
+C
+      IF (NERR.LT.-9999999 .OR. NERR.GT.99999999 .OR. NERR.EQ.0 .OR.
+     *   LEVEL.LT.-1 .OR. LEVEL.GT.2) THEN
+         CALL XERPRN (' ***', -1, 'FATAL ERROR IN...$$ ' //
+     *      'XERMSG -- INVALID ERROR NUMBER OR LEVEL$$ '//
+     *      'JOB ABORT DUE TO FATAL ERROR.', 72)
+         CALL XERSVE (' ', ' ', ' ', 0, 0, 0, KDUMMY)
+         CALL XERHLT (' ***XERMSG -- INVALID INPUT')
+         RETURN
+      ENDIF
+C
+C       RECORD THE MESSAGE.
+C
+      I = J4SAVE (1, NERR, .TRUE.)
+      CALL XERSVE (LIBRAR, SUBROU, MESSG, 1, NERR, LEVEL, KOUNT)
+C
+C       HANDLE PRINT-ONCE WARNING MESSAGES.
+C
+      IF (LEVEL.EQ.-1 .AND. KOUNT.GT.1) RETURN
+C
+C       ALLOW TEMPORARY USER OVERRIDE OF THE CONTROL FLAG.
+C
+      XLIBR  = LIBRAR
+      XSUBR  = SUBROU
+      LFIRST = MESSG
+      LERR   = NERR
+      LLEVEL = LEVEL
+      CALL XERCNT (XLIBR, XSUBR, LFIRST, LERR, LLEVEL, LKNTRL)
+C
+      LKNTRL = MAX(-2, MIN(2,LKNTRL))
+      MKNTRL = ABS(LKNTRL)
+C
+C       SKIP PRINTING IF THE CONTROL FLAG VALUE AS RESET IN XERCNT IS
+C       ZERO AND THE ERROR IS NOT FATAL.
+C
+      IF (LEVEL.LT.2 .AND. LKNTRL.EQ.0) GO TO 30
+      IF (LEVEL.EQ.0 .AND. MAXMES.GE.0 .AND. KOUNT.GT.MAXMES) GO TO 30
+      IF (LEVEL.EQ.1 .AND. MAXMES.GE.0 .AND. KOUNT.GT.MAXMES
+     *    .AND. MKNTRL.EQ.1) GO TO 30
+      IF (LEVEL.EQ.2 .AND. MAXMES.GE.0 .AND. KOUNT.GT.MAX(1,MAXMES))
+     *    GO TO 30
+C
+C       ANNOUNCE THE NAMES OF THE LIBRARY AND SUBROUTINE BY BUILDING A
+C       MESSAGE IN CHARACTER VARIABLE TEMP (NOT EXCEEDING 66 CHARACTERS)
+C       AND SENDING IT OUT VIA XERPRN.  PRINT ONLY IF CONTROL FLAG
+C       IS NOT ZERO.
+C
+      IF (LKNTRL .NE. 0) THEN
+         TEMP(1:21) = 'MESSAGE FROM ROUTINE '
+         I = MIN(LEN(SUBROU), 16)
+         TEMP(22:21+I) = SUBROU(1:I)
+         TEMP(22+I:33+I) = ' IN LIBRARY '
+         LTEMP = 33 + I
+         I = MIN(LEN(LIBRAR), 16)
+         TEMP(LTEMP+1:LTEMP+I) = LIBRAR (1:I)
+         TEMP(LTEMP+I+1:LTEMP+I+1) = '.'
+         LTEMP = LTEMP + I + 1
+         CALL XERPRN (' ***', -1, TEMP(1:LTEMP), 72)
+      ENDIF
+C
+C       IF LKNTRL IS POSITIVE, PRINT AN INTRODUCTORY LINE BEFORE
+C       PRINTING THE MESSAGE.  THE INTRODUCTORY LINE TELLS THE CHOICE
+C       FROM EACH OF THE FOLLOWING THREE OPTIONS.
+C       1.  LEVEL OF THE MESSAGE
+C              'INFORMATIVE MESSAGE'
+C              'POTENTIALLY RECOVERABLE ERROR'
+C              'FATAL ERROR'
+C       2.  WHETHER CONTROL FLAG WILL ALLOW PROGRAM TO CONTINUE
+C              'PROG CONTINUES'
+C              'PROG ABORTED'
+C       3.  WHETHER OR NOT A TRACEBACK WAS REQUESTED.  (THE TRACEBACK
+C           MAY NOT BE IMPLEMENTED AT SOME SITES, SO THIS ONLY TELLS
+C           WHAT WAS REQUESTED, NOT WHAT WAS DELIVERED.)
+C              'TRACEBACK REQUESTED'
+C              'TRACEBACK NOT REQUESTED'
+C       NOTICE THAT THE LINE INCLUDING FOUR PREFIX CHARACTERS WILL NOT
+C       EXCEED 74 CHARACTERS.
+C       WE SKIP THE NEXT BLOCK IF THE INTRODUCTORY LINE IS NOT NEEDED.
+C
+      IF (LKNTRL .GT. 0) THEN
+C
+C       THE FIRST PART OF THE MESSAGE TELLS ABOUT THE LEVEL.
+C
+         IF (LEVEL .LE. 0) THEN
+            TEMP(1:20) = 'INFORMATIVE MESSAGE,'
+            LTEMP = 20
+         ELSEIF (LEVEL .EQ. 1) THEN
+            TEMP(1:30) = 'POTENTIALLY RECOVERABLE ERROR,'
+            LTEMP = 30
+         ELSE
+            TEMP(1:12) = 'FATAL ERROR,'
+            LTEMP = 12
+         ENDIF
+C
+C       THEN WHETHER THE PROGRAM WILL CONTINUE.
+C
+         IF ((MKNTRL.EQ.2 .AND. LEVEL.GE.1) .OR.
+     *       (MKNTRL.EQ.1 .AND. LEVEL.EQ.2)) THEN
+            TEMP(LTEMP+1:LTEMP+14) = ' PROG ABORTED,'
+            LTEMP = LTEMP + 14
+         ELSE
+            TEMP(LTEMP+1:LTEMP+16) = ' PROG CONTINUES,'
+            LTEMP = LTEMP + 16
+         ENDIF
+C
+C       FINALLY TELL WHETHER THERE SHOULD BE A TRACEBACK.
+C
+         IF (LKNTRL .GT. 0) THEN
+            TEMP(LTEMP+1:LTEMP+20) = ' TRACEBACK REQUESTED'
+            LTEMP = LTEMP + 20
+         ELSE
+            TEMP(LTEMP+1:LTEMP+24) = ' TRACEBACK NOT REQUESTED'
+            LTEMP = LTEMP + 24
+         ENDIF
+         CALL XERPRN (' ***', -1, TEMP(1:LTEMP), 72)
+      ENDIF
+C
+C       NOW SEND OUT THE MESSAGE.
+C
+      CALL XERPRN (' *  ', -1, MESSG, 72)
+C
+C       IF LKNTRL IS POSITIVE, WRITE THE ERROR NUMBER AND REQUEST A
+C          TRACEBACK.
+C
+      IF (LKNTRL .GT. 0) THEN
+         WRITE (TEMP, '(''ERROR NUMBER = '', I8)') NERR
+         DO 10 I=16,22
+            IF (TEMP(I:I) .NE. ' ') GO TO 20
+   10    CONTINUE
+C
+   20    CALL XERPRN (' *  ', -1, TEMP(1:15) // TEMP(I:23), 72)
+         CALL FDUMP
+      ENDIF
+C
+C       IF LKNTRL IS NOT ZERO, PRINT A BLANK LINE AND AN END OF MESSAGE.
+C
+      IF (LKNTRL .NE. 0) THEN
+         CALL XERPRN (' *  ', -1, ' ', 72)
+         CALL XERPRN (' ***', -1, 'END OF MESSAGE', 72)
+         CALL XERPRN ('    ',  0, ' ', 72)
+      ENDIF
+C
+C       IF THE ERROR IS NOT FATAL OR THE ERROR IS RECOVERABLE AND THE
+C       CONTROL FLAG IS SET FOR RECOVERY, THEN RETURN.
+C
+   30 IF (LEVEL.LE.0 .OR. (LEVEL.EQ.1 .AND. MKNTRL.LE.1)) RETURN
+C
+C       THE PROGRAM WILL BE STOPPED DUE TO AN UNRECOVERED ERROR OR A
+C       FATAL ERROR.  PRINT THE REASON FOR THE ABORT AND THE ERROR
+C       SUMMARY IF THE CONTROL FLAG AND THE MAXIMUM ERROR COUNT PERMIT.
+C
+      IF (LKNTRL.GT.0
+     *    .AND. (MAXMES.LT.0 .OR. KOUNT.LT.MAX(1,MAXMES))) THEN
+         IF (LEVEL .EQ. 1) THEN
+            CALL XERPRN
+     *         (' ***', -1, 'JOB ABORT DUE TO UNRECOVERED ERROR.', 72)
+         ELSE
+            CALL XERPRN(' ***', -1, 'JOB ABORT DUE TO FATAL ERROR.', 72)
+         ENDIF
+         CALL XERSVE (' ', ' ', ' ', -1, 0, 0, KDUMMY)
+         CALL XERHLT (' ')
+      ELSE
+         CALL XERHLT (MESSG)
+      ENDIF
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xerprn.f b/libcruft/slatec-err/xerprn.f
new file mode 100644
index 0000000..97eedf4
--- /dev/null
+++ b/libcruft/slatec-err/xerprn.f
@@ -0,0 +1,228 @@
+*DECK XERPRN
+      SUBROUTINE XERPRN (PREFIX, NPREF, MESSG, NWRAP)
+C***BEGIN PROLOGUE  XERPRN
+C***SUBSIDIARY
+C***PURPOSE  Print error messages processed by XERMSG.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XERPRN-A)
+C***KEYWORDS  ERROR MESSAGES, PRINTING, XERROR
+C***AUTHOR  Fong, Kirby, (NMFECC at LLNL)
+C***DESCRIPTION
+C
+C This routine sends one or more lines to each of the (up to five)
+C logical units to which error messages are to be sent.  This routine
+C is called several times by XERMSG, sometimes with a single line to
+C print and sometimes with a (potentially very long) message that may
+C wrap around into multiple lines.
+C
+C PREFIX  Input argument of type CHARACTER.  This argument contains
+C         characters to be put at the beginning of each line before
+C         the body of the message.  No more than 16 characters of
+C         PREFIX will be used.
+C
+C NPREF   Input argument of type INTEGER.  This argument is the number
+C         of characters to use from PREFIX.  If it is negative, the
+C         intrinsic function LEN is used to determine its length.  If
+C         it is zero, PREFIX is not used.  If it exceeds 16 or if
+C         LEN(PREFIX) exceeds 16, only the first 16 characters will be
+C         used.  If NPREF is positive and the length of PREFIX is less
+C         than NPREF, a copy of PREFIX extended with blanks to length
+C         NPREF will be used.
+C
+C MESSG   Input argument of type CHARACTER.  This is the text of a
+C         message to be printed.  If it is a long message, it will be
+C         broken into pieces for printing on multiple lines.  Each line
+C         will start with the appropriate prefix and be followed by a
+C         piece of the message.  NWRAP is the number of characters per
+C         piece; that is, after each NWRAP characters, we break and
+C         start a new line.  In addition the characters '$$' embedded
+C         in MESSG are a sentinel for a new line.  The counting of
+C         characters up to NWRAP starts over for each new line.  The
+C         value of NWRAP typically used by XERMSG is 72 since many
+C         older error messages in the SLATEC Library are laid out to
+C         rely on wrap-around every 72 characters.
+C
+C NWRAP   Input argument of type INTEGER.  This gives the maximum size
+C         piece into which to break MESSG for printing on multiple
+C         lines.  An embedded '$$' ends a line, and the count restarts
+C         at the following character.  If a line break does not occur
+C         on a blank (it would split a word) that word is moved to the
+C         next line.  Values of NWRAP less than 16 will be treated as
+C         16.  Values of NWRAP greater than 132 will be treated as 132.
+C         The actual line length will be NPREF + NWRAP after NPREF has
+C         been adjusted to fall between 0 and 16 and NWRAP has been
+C         adjusted to fall between 16 and 132.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  I1MACH, XGETUA
+C***REVISION HISTORY  (YYMMDD)
+C   880621  DATE WRITTEN
+C   880708  REVISED AFTER THE SLATEC CML SUBCOMMITTEE MEETING OF
+C           JUNE 29 AND 30 TO CHANGE THE NAME TO XERPRN AND TO REWORK
+C           THE HANDLING OF THE NEW LINE SENTINEL TO BEHAVE LIKE THE
+C           SLASH CHARACTER IN FORMAT STATEMENTS.
+C   890706  REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO
+C           STREAMLINE THE CODING AND FIX A BUG THAT CAUSED EXTRA BLANK
+C           LINES TO BE PRINTED.
+C   890721  REVISED TO ADD A NEW FEATURE.  A NEGATIVE VALUE OF NPREF
+C           CAUSES LEN(PREFIX) TO BE USED AS THE LENGTH.
+C   891013  REVISED TO CORRECT ERROR IN CALCULATING PREFIX LENGTH.
+C   891214  Prologue converted to Version 4.0 format.  (WRB)
+C   900510  Added code to break messages between words.  (RWC)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XERPRN
+      CHARACTER*(*) PREFIX, MESSG
+      INTEGER NPREF, NWRAP
+      CHARACTER*148 CBUFF
+      INTEGER IU(5), NUNIT
+      CHARACTER*2 NEWLIN
+      PARAMETER (NEWLIN = '$$')
+C***FIRST EXECUTABLE STATEMENT  XERPRN
+      CALL XGETUA(IU,NUNIT)
+C
+C       A ZERO VALUE FOR A LOGICAL UNIT NUMBER MEANS TO USE THE STANDARD
+C       ERROR MESSAGE UNIT INSTEAD.  I1MACH(4) RETRIEVES THE STANDARD
+C       ERROR MESSAGE UNIT.
+C
+      N = I1MACH(4)
+      DO 10 I=1,NUNIT
+         IF (IU(I) .EQ. 0) IU(I) = N
+   10 CONTINUE
+C
+C       LPREF IS THE LENGTH OF THE PREFIX.  THE PREFIX IS PLACED AT THE
+C       BEGINNING OF CBUFF, THE CHARACTER BUFFER, AND KEPT THERE DURING
+C       THE REST OF THIS ROUTINE.
+C
+      IF ( NPREF .LT. 0 ) THEN
+         LPREF = LEN(PREFIX)
+      ELSE
+         LPREF = NPREF
+      ENDIF
+      LPREF = MIN(16, LPREF)
+      IF (LPREF .NE. 0) CBUFF(1:LPREF) = PREFIX
+C
+C       LWRAP IS THE MAXIMUM NUMBER OF CHARACTERS WE WANT TO TAKE AT ONE
+C       TIME FROM MESSG TO PRINT ON ONE LINE.
+C
+      LWRAP = MAX(16, MIN(132, NWRAP))
+C
+C       SET LENMSG TO THE LENGTH OF MESSG, IGNORE ANY TRAILING BLANKS.
+C
+      LENMSG = LEN(MESSG)
+      N = LENMSG
+      DO 20 I=1,N
+         IF (MESSG(LENMSG:LENMSG) .NE. ' ') GO TO 30
+         LENMSG = LENMSG - 1
+   20 CONTINUE
+   30 CONTINUE
+C
+C       IF THE MESSAGE IS ALL BLANKS, THEN PRINT ONE BLANK LINE.
+C
+      IF (LENMSG .EQ. 0) THEN
+         CBUFF(LPREF+1:LPREF+1) = ' '
+         DO 40 I=1,NUNIT
+            WRITE(IU(I), '(A)') CBUFF(1:LPREF+1)
+   40    CONTINUE
+         RETURN
+      ENDIF
+C
+C       SET NEXTC TO THE POSITION IN MESSG WHERE THE NEXT SUBSTRING
+C       STARTS.  FROM THIS POSITION WE SCAN FOR THE NEW LINE SENTINEL.
+C       WHEN NEXTC EXCEEDS LENMSG, THERE IS NO MORE TO PRINT.
+C       WE LOOP BACK TO LABEL 50 UNTIL ALL PIECES HAVE BEEN PRINTED.
+C
+C       WE LOOK FOR THE NEXT OCCURRENCE OF THE NEW LINE SENTINEL.  THE
+C       INDEX INTRINSIC FUNCTION RETURNS ZERO IF THERE IS NO OCCURRENCE
+C       OR IF THE LENGTH OF THE FIRST ARGUMENT IS LESS THAN THE LENGTH
+C       OF THE SECOND ARGUMENT.
+C
+C       THERE ARE SEVERAL CASES WHICH SHOULD BE CHECKED FOR IN THE
+C       FOLLOWING ORDER.  WE ARE ATTEMPTING TO SET LPIECE TO THE NUMBER
+C       OF CHARACTERS THAT SHOULD BE TAKEN FROM MESSG STARTING AT
+C       POSITION NEXTC.
+C
+C       LPIECE .EQ. 0   THE NEW LINE SENTINEL DOES NOT OCCUR IN THE
+C                       REMAINDER OF THE CHARACTER STRING.  LPIECE
+C                       SHOULD BE SET TO LWRAP OR LENMSG+1-NEXTC,
+C                       WHICHEVER IS LESS.
+C
+C       LPIECE .EQ. 1   THE NEW LINE SENTINEL STARTS AT MESSG(NEXTC:
+C                       NEXTC).  LPIECE IS EFFECTIVELY ZERO, AND WE
+C                       PRINT NOTHING TO AVOID PRODUCING UNNECESSARY
+C                       BLANK LINES.  THIS TAKES CARE OF THE SITUATION
+C                       WHERE THE LIBRARY ROUTINE HAS A MESSAGE OF
+C                       EXACTLY 72 CHARACTERS FOLLOWED BY A NEW LINE
+C                       SENTINEL FOLLOWED BY MORE CHARACTERS.  NEXTC
+C                       SHOULD BE INCREMENTED BY 2.
+C
+C       LPIECE .GT. LWRAP+1  REDUCE LPIECE TO LWRAP.
+C
+C       ELSE            THIS LAST CASE MEANS 2 .LE. LPIECE .LE. LWRAP+1
+C                       RESET LPIECE = LPIECE-1.  NOTE THAT THIS
+C                       PROPERLY HANDLES THE END CASE WHERE LPIECE .EQ.
+C                       LWRAP+1.  THAT IS, THE SENTINEL FALLS EXACTLY
+C                       AT THE END OF A LINE.
+C
+      NEXTC = 1
+   50 LPIECE = INDEX(MESSG(NEXTC:LENMSG), NEWLIN)
+      IF (LPIECE .EQ. 0) THEN
+C
+C       THERE WAS NO NEW LINE SENTINEL FOUND.
+C
+         IDELTA = 0
+         LPIECE = MIN(LWRAP, LENMSG+1-NEXTC)
+         IF (LPIECE .LT. LENMSG+1-NEXTC) THEN
+            DO 52 I=LPIECE+1,2,-1
+               IF (MESSG(NEXTC+I-1:NEXTC+I-1) .EQ. ' ') THEN
+                  LPIECE = I-1
+                  IDELTA = 1
+                  GOTO 54
+               ENDIF
+   52       CONTINUE
+         ENDIF
+   54    CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1)
+         NEXTC = NEXTC + LPIECE + IDELTA
+      ELSEIF (LPIECE .EQ. 1) THEN
+C
+C       WE HAVE A NEW LINE SENTINEL AT MESSG(NEXTC:NEXTC+1).
+C       DON'T PRINT A BLANK LINE.
+C
+         NEXTC = NEXTC + 2
+         GO TO 50
+      ELSEIF (LPIECE .GT. LWRAP+1) THEN
+C
+C       LPIECE SHOULD BE SET DOWN TO LWRAP.
+C
+         IDELTA = 0
+         LPIECE = LWRAP
+         DO 56 I=LPIECE+1,2,-1
+            IF (MESSG(NEXTC+I-1:NEXTC+I-1) .EQ. ' ') THEN
+               LPIECE = I-1
+               IDELTA = 1
+               GOTO 58
+            ENDIF
+   56    CONTINUE
+   58    CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1)
+         NEXTC = NEXTC + LPIECE + IDELTA
+      ELSE
+C
+C       IF WE ARRIVE HERE, IT MEANS 2 .LE. LPIECE .LE. LWRAP+1.
+C       WE SHOULD DECREMENT LPIECE BY ONE.
+C
+         LPIECE = LPIECE - 1
+         CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1)
+         NEXTC  = NEXTC + LPIECE + 2
+      ENDIF
+C
+C       PRINT
+C
+      DO 60 I=1,NUNIT
+         WRITE(IU(I), '(A)') CBUFF(1:LPREF+LPIECE)
+   60 CONTINUE
+C
+      IF (NEXTC .LE. LENMSG) GO TO 50
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xerrwd.f b/libcruft/slatec-err/xerrwd.f
new file mode 100644
index 0000000..8244c32
--- /dev/null
+++ b/libcruft/slatec-err/xerrwd.f
@@ -0,0 +1,97 @@
+
+*DECK XERRWD
+      SUBROUTINE XERRWD (MSG, NMES, NERR, LEVEL, NI, I1, I2, NR, R1, R2)
+C***BEGIN PROLOGUE  XERRWD
+C***SUBSIDIARY
+C***PURPOSE  Write error message with values.
+C***LIBRARY   MATHLIB
+C***CATEGORY  R3C
+C***TYPE      DOUBLE PRECISION (XERRWV-S, XERRWD-D)
+C***AUTHOR  Hindmarsh, Alan C., (LLNL)
+C***DESCRIPTION
+C
+C  Subroutines XERRWD, XSETF, XSETUN, and the function routine IXSAV,
+C  as given here, constitute a simplified version of the SLATEC error
+C  handling package.
+C
+C  All arguments are input arguments.
+C
+C  MSG    = The message (character array).
+C  NMES   = The length of MSG (number of characters).
+C  NERR   = The error number (not used).
+C  LEVEL  = The error level..
+C           0 or 1 means recoverable (control returns to caller).
+C           2 means fatal (run is aborted--see note below).
+C  NI     = Number of integers (0, 1, or 2) to be printed with message.
+C  I1,I2  = Integers to be printed, depending on NI.
+C  NR     = Number of reals (0, 1, or 2) to be printed with message.
+C  R1,R2  = Reals to be printed, depending on NR.
+C
+C  Note..  this routine is machine-dependent and specialized for use
+C  in limited context, in the following ways..
+C  1. The argument MSG is assumed to be of type CHARACTER, and
+C     the message is printed with a format of (1X,A).
+C  2. The message is assumed to take only one line.
+C     Multi-line messages are generated by repeated calls.
+C  3. If LEVEL = 2, control passes to the statement   STOP
+C     to abort the run.  This statement may be machine-dependent.
+C  4. R1 and R2 are assumed to be in double precision and are printed
+C     in D21.13 format.
+C
+C***ROUTINES CALLED  IXSAV
+C***REVISION HISTORY  (YYMMDD)
+C   920831  DATE WRITTEN
+C   921118  Replaced MFLGSV/LUNSAV by IXSAV. (ACH)
+C   930329  Modified prologue to SLATEC format. (FNF)
+C   930407  Changed MSG from CHARACTER*1 array to variable. (FNF)
+C   930922  Minor cosmetic change. (FNF)
+C***END PROLOGUE  XERRWD
+C
+C*Internal Notes:
+C
+C For a different default logical unit number, IXSAV (or a subsidiary
+C routine that it calls) will need to be modified.
+C For a different run-abort command, change the statement following
+C statement 100 at the end.
+C-----------------------------------------------------------------------
+C Subroutines called by XERRWD.. None
+C Function routine called by XERRWD.. IXSAV
+C-----------------------------------------------------------------------
+C**End
+C
+C  Declare arguments.
+C
+      DOUBLE PRECISION R1, R2
+      INTEGER NMES, NERR, LEVEL, NI, I1, I2, NR
+      CHARACTER*(*) MSG
+C
+C  Declare local variables.
+C
+      INTEGER LUNIT, IXSAV, MESFLG
+C
+C  Get logical unit number and message print flag.
+C
+C***FIRST EXECUTABLE STATEMENT  XERRWD
+      LUNIT = IXSAV (1, 0, .FALSE.)
+      MESFLG = IXSAV (2, 0, .FALSE.)
+      IF (MESFLG .EQ. 0) GO TO 100
+C
+C  Write the message.
+C
+      WRITE (LUNIT,10)  MSG(1:NMES)
+ 10   FORMAT(1X,A)
+      IF (NI .EQ. 1) WRITE (LUNIT, 20) I1
+ 20   FORMAT(6X,'In above message,  I1 =',I10)
+      IF (NI .EQ. 2) WRITE (LUNIT, 30) I1,I2
+ 30   FORMAT(6X,'In above message,  I1 =',I10,3X,'I2 =',I10)
+      IF (NR .EQ. 1) WRITE (LUNIT, 40) R1
+ 40   FORMAT(6X,'In above message,  R1 =',D21.13)
+      IF (NR .EQ. 2) WRITE (LUNIT, 50) R1,R2
+ 50   FORMAT(6X,'In above,  R1 =',D21.13,3X,'R2 =',D21.13)
+C
+C  Abort the run if LEVEL = 2.
+C
+ 100  IF (LEVEL .NE. 2) RETURN
+      CALL XSTOPX (' ')
+C----------------------- End of Subroutine XERRWD ----------------------
+      END
diff --git a/libcruft/slatec-err/xersve.f b/libcruft/slatec-err/xersve.f
new file mode 100644
index 0000000..6bd2a4f
--- /dev/null
+++ b/libcruft/slatec-err/xersve.f
@@ -0,0 +1,155 @@
+*DECK XERSVE
+      SUBROUTINE XERSVE (LIBRAR, SUBROU, MESSG, KFLAG, NERR, LEVEL,
+     +   ICOUNT)
+C***BEGIN PROLOGUE  XERSVE
+C***SUBSIDIARY
+C***PURPOSE  Record that an error has occurred.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3
+C***TYPE      ALL (XERSVE-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C *Usage:
+C
+C        INTEGER  KFLAG, NERR, LEVEL, ICOUNT
+C        CHARACTER * (len) LIBRAR, SUBROU, MESSG
+C
+C        CALL XERSVE (LIBRAR, SUBROU, MESSG, KFLAG, NERR, LEVEL, ICOUNT)
+C
+C *Arguments:
+C
+C        LIBRAR :IN    is the library that the message is from.
+C        SUBROU :IN    is the subroutine that the message is from.
+C        MESSG  :IN    is the message to be saved.
+C        KFLAG  :IN    indicates the action to be performed.
+C                      when KFLAG > 0, the message in MESSG is saved.
+C                      when KFLAG=0 the tables will be dumped and
+C                      cleared.
+C                      when KFLAG < 0, the tables will be dumped and
+C                      not cleared.
+C        NERR   :IN    is the error number.
+C        LEVEL  :IN    is the error severity.
+C        ICOUNT :OUT   the number of times this message has been seen,
+C                      or zero if the table has overflowed and does not
+C                      contain this message specifically.  When KFLAG=0,
+C                      ICOUNT will not be altered.
+C
+C *Description:
+C
+C   Record that this error occurred and possibly dump and clear the
+C   tables.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  I1MACH, XGETUA
+C***REVISION HISTORY  (YYMMDD)
+C   800319  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900413  Routine modified to remove reference to KFLAG.  (WRB)
+C   900510  Changed to add LIBRARY NAME and SUBROUTINE to calling
+C           sequence, use IF-THEN-ELSE, make number of saved entries
+C           easily changeable, changed routine name from XERSAV to
+C           XERSVE.  (RWC)
+C   910626  Added LIBTAB and SUBTAB to SAVE statement.  (BKS)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XERSVE
+      PARAMETER (LENTAB=10)
+      INTEGER LUN(5)
+      CHARACTER*(*) LIBRAR, SUBROU, MESSG
+      CHARACTER*8  LIBTAB(LENTAB), SUBTAB(LENTAB), LIB, SUB
+      CHARACTER*20 MESTAB(LENTAB), MES
+      DIMENSION NERTAB(LENTAB), LEVTAB(LENTAB), KOUNT(LENTAB)
+      SAVE LIBTAB, SUBTAB, MESTAB, NERTAB, LEVTAB, KOUNT, KOUNTX, NMSG
+      DATA KOUNTX/0/, NMSG/0/
+C***FIRST EXECUTABLE STATEMENT  XERSVE
+C
+      IF (KFLAG.LE.0) THEN
+C
+C        Dump the table.
+C
+         IF (NMSG.EQ.0) RETURN
+C
+C        Print to each unit.
+C
+         CALL XGETUA (LUN, NUNIT)
+         DO 20 KUNIT = 1,NUNIT
+            IUNIT = LUN(KUNIT)
+            IF (IUNIT.EQ.0) IUNIT = I1MACH(4)
+C
+C           Print the table header.
+C
+            WRITE (IUNIT,9000)
+C
+C           Print body of table.
+C
+            DO 10 I = 1,NMSG
+               WRITE (IUNIT,9010) LIBTAB(I), SUBTAB(I), MESTAB(I),
+     *            NERTAB(I),LEVTAB(I),KOUNT(I)
+   10       CONTINUE
+C
+C           Print number of other errors.
+C
+            IF (KOUNTX.NE.0) WRITE (IUNIT,9020) KOUNTX
+            WRITE (IUNIT,9030)
+   20    CONTINUE
+C
+C        Clear the error tables.
+C
+         IF (KFLAG.EQ.0) THEN
+            NMSG = 0
+            KOUNTX = 0
+         ENDIF
+      ELSE
+C
+C        PROCESS A MESSAGE...
+C        SEARCH FOR THIS MESSG, OR ELSE AN EMPTY SLOT FOR THIS MESSG,
+C        OR ELSE DETERMINE THAT THE ERROR TABLE IS FULL.
+C
+         LIB = LIBRAR
+         SUB = SUBROU
+         MES = MESSG
+         DO 30 I = 1,NMSG
+            IF (LIB.EQ.LIBTAB(I) .AND. SUB.EQ.SUBTAB(I) .AND.
+     *         MES.EQ.MESTAB(I) .AND. NERR.EQ.NERTAB(I) .AND.
+     *         LEVEL.EQ.LEVTAB(I)) THEN
+                  KOUNT(I) = KOUNT(I) + 1
+                  ICOUNT = KOUNT(I)
+                  RETURN
+            ENDIF
+   30    CONTINUE
+C
+         IF (NMSG.LT.LENTAB) THEN
+C
+C           Empty slot found for new message.
+C
+            NMSG = NMSG + 1
+            LIBTAB(I) = LIB
+            SUBTAB(I) = SUB
+            MESTAB(I) = MES
+            NERTAB(I) = NERR
+            LEVTAB(I) = LEVEL
+            KOUNT (I) = 1
+            ICOUNT    = 1
+         ELSE
+C
+C           Table is full.
+C
+            KOUNTX = KOUNTX+1
+            ICOUNT = 0
+         ENDIF
+      ENDIF
+      RETURN
+C
+C     Formats.
+C
+ 9000 FORMAT ('0          ERROR MESSAGE SUMMARY' /
+     +   ' LIBRARY    SUBROUTINE MESSAGE START             NERR',
+     +   '     LEVEL     COUNT')
+ 9010 FORMAT (1X,A,3X,A,3X,A,3I10)
+ 9020 FORMAT ('0OTHER ERRORS NOT INDIVIDUALLY TABULATED = ', I10)
+ 9030 FORMAT (1X)
+      END
diff --git a/libcruft/slatec-err/xgetf.f b/libcruft/slatec-err/xgetf.f
new file mode 100644
index 0000000..da2d7f2
--- /dev/null
+++ b/libcruft/slatec-err/xgetf.f
@@ -0,0 +1,30 @@
+*DECK XGETF
+      SUBROUTINE XGETF (KONTRL)
+C***BEGIN PROLOGUE  XGETF
+C***PURPOSE  Return the current value of the error control flag.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XGETF-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C   Abstract
+C        XGETF returns the current value of the error control flag
+C        in KONTRL.  See subroutine XSETF for flag value meanings.
+C        (KONTRL is an output parameter only.)
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  J4SAVE
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XGETF
+C***FIRST EXECUTABLE STATEMENT  XGETF
+      KONTRL = J4SAVE(2,0,.FALSE.)
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xgetua.f b/libcruft/slatec-err/xgetua.f
new file mode 100644
index 0000000..2e7db02
--- /dev/null
+++ b/libcruft/slatec-err/xgetua.f
@@ -0,0 +1,51 @@
+*DECK XGETUA
+      SUBROUTINE XGETUA (IUNITA, N)
+C***BEGIN PROLOGUE  XGETUA
+C***PURPOSE  Return unit number(s) to which error messages are being
+C            sent.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3C
+C***TYPE      ALL (XGETUA-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        XGETUA may be called to determine the unit number or numbers
+C        to which error messages are being sent.
+C        These unit numbers may have been set by a call to XSETUN,
+C        or a call to XSETUA, or may be a default value.
+C
+C     Description of Parameters
+C      --Output--
+C        IUNIT - an array of one to five unit numbers, depending
+C                on the value of N.  A value of zero refers to the
+C                default unit, as defined by the I1MACH machine
+C                constant routine.  Only IUNIT(1),...,IUNIT(N) are
+C                defined by XGETUA.  The values of IUNIT(N+1),...,
+C                IUNIT(5) are not defined (for N .LT. 5) or altered
+C                in any way by XGETUA.
+C        N     - the number of units to which copies of the
+C                error messages are being sent.  N will be in the
+C                range from 1 to 5.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  J4SAVE
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XGETUA
+      DIMENSION IUNITA(5)
+C***FIRST EXECUTABLE STATEMENT  XGETUA
+      N = J4SAVE(5,0,.FALSE.)
+      DO 30 I=1,N
+         INDEX = I+4
+         IF (I.EQ.1) INDEX = 3
+         IUNITA(I) = J4SAVE(INDEX,0,.FALSE.)
+   30 CONTINUE
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xsetf.f b/libcruft/slatec-err/xsetf.f
new file mode 100644
index 0000000..2039e82
--- /dev/null
+++ b/libcruft/slatec-err/xsetf.f
@@ -0,0 +1,60 @@
+*DECK XSETF
+      SUBROUTINE XSETF (KONTRL)
+C***BEGIN PROLOGUE  XSETF
+C***PURPOSE  Set the error control flag.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3A
+C***TYPE      ALL (XSETF-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        XSETF sets the error control flag value to KONTRL.
+C        (KONTRL is an input parameter only.)
+C        The following table shows how each message is treated,
+C        depending on the values of KONTRL and LEVEL.  (See XERMSG
+C        for description of LEVEL.)
+C
+C        If KONTRL is zero or negative, no information other than the
+C        message itself (including numeric values, if any) will be
+C        printed.  If KONTRL is positive, introductory messages,
+C        trace-backs, etc., will be printed in addition to the message.
+C
+C              ABS(KONTRL)
+C        LEVEL        0              1              2
+C        value
+C          2        fatal          fatal          fatal
+C
+C          1     not printed      printed         fatal
+C
+C          0     not printed      printed        printed
+C
+C         -1     not printed      printed        printed
+C                                  only           only
+C                                  once           once
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  J4SAVE, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900510  Change call to XERRWV to XERMSG.  (RWC)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XSETF
+      CHARACTER *8 XERN1
+C***FIRST EXECUTABLE STATEMENT  XSETF
+      IF (ABS(KONTRL) .GT. 2) THEN
+         WRITE (XERN1, '(I8)') KONTRL
+         CALL XERMSG ('SLATEC', 'XSETF',
+     *      'INVALID ARGUMENT = ' // XERN1, 1, 2)
+         RETURN
+      ENDIF
+C
+      JUNK = J4SAVE(2,KONTRL,.TRUE.)
+      RETURN
+      END
diff --git a/libcruft/slatec-err/xsetua.f b/libcruft/slatec-err/xsetua.f
new file mode 100644
index 0000000..5b58f84
--- /dev/null
+++ b/libcruft/slatec-err/xsetua.f
@@ -0,0 +1,59 @@
+*DECK XSETUA
+      SUBROUTINE XSETUA (IUNITA, N)
+C***BEGIN PROLOGUE  XSETUA
+C***PURPOSE  Set logical unit numbers (up to 5) to which error
+C            messages are to be sent.
+C***LIBRARY   SLATEC (XERROR)
+C***CATEGORY  R3B
+C***TYPE      ALL (XSETUA-A)
+C***KEYWORDS  ERROR, XERROR
+C***AUTHOR  Jones, R. E., (SNLA)
+C***DESCRIPTION
+C
+C     Abstract
+C        XSETUA may be called to declare a list of up to five
+C        logical units, each of which is to receive a copy of
+C        each error message processed by this package.
+C        The purpose of XSETUA is to allow simultaneous printing
+C        of each error message on, say, a main output file,
+C        an interactive terminal, and other files such as graphics
+C        communication files.
+C
+C     Description of Parameters
+C      --Input--
+C        IUNIT - an array of up to five unit numbers.
+C                Normally these numbers should all be different
+C                (but duplicates are not prohibited.)
+C        N     - the number of unit numbers provided in IUNIT
+C                must have 1 .LE. N .LE. 5.
+C
+C***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
+C                 Error-handling Package, SAND82-0800, Sandia
+C                 Laboratories, 1982.
+C***ROUTINES CALLED  J4SAVE, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   790801  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900510  Change call to XERRWV to XERMSG.  (RWC)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  XSETUA
+      DIMENSION IUNITA(5)
+      CHARACTER *8 XERN1
+C***FIRST EXECUTABLE STATEMENT  XSETUA
+C
+      IF (N.LT.1 .OR. N.GT.5) THEN
+         WRITE (XERN1, '(I8)') N
+         CALL XERMSG ('SLATEC', 'XSETUA',
+     *      'INVALID NUMBER OF UNITS, N = ' // XERN1, 1, 2)
+         RETURN
+      ENDIF
+C
+      DO 10 I=1,N
+         INDEX = I+4
+         IF (I.EQ.1) INDEX = 3
+         JUNK = J4SAVE(INDEX,IUNITA(I),.TRUE.)
+   10 CONTINUE
+      JUNK = J4SAVE(5,N,.TRUE.)
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/Makefile.in b/libcruft/slatec-fn/Makefile.in
new file mode 100644
index 0000000..6027ed6
--- /dev/null
+++ b/libcruft/slatec-fn/Makefile.in
@@ -0,0 +1,40 @@
+# Makefile for octave's libcruft/slatec-fn directory
+#
+# Copyright (C) 1995, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+include $(TOPDIR)/Makeconf
+
+FSRC = albeta.f alngam.f alnrel.f algams.f acosh.f asinh.f atanh.f betai.f \
+  csevl.f d9gmit.f d9lgic.f d9lgit.f d9lgmc.f dacosh.f dasinh.f datanh.f \
+  dbetai.f dcsevl.f derf.f derfc.f dgami.f dgamit.f dgamlm.f dgamma.f \
+  dgamr.f dlbeta.f dlgams.f dlngam.f dlnrel.f dpchim.f dpchst.f erf.f erfc.f \
+  gami.f gamit.f gamlim.f gamma.f gamr.f initds.f inits.f pchim.f pchst.f \
+  r9lgmc.f r9lgit.f r9gmit.f r9lgic.f xdacosh.f xdasinh.f xdatanh.f \
+  xdbetai.f xderf.f xderfc.f xdgami.f xdgamit.f xdgamma.f xgmainc.f xacosh.f \
+  xasinh.f xatanh.f xerf.f xerfc.f xsgmainc.f xgamma.f xbetai.f
+
+include ../Makerules
diff --git a/libcruft/slatec-fn/acosh.f b/libcruft/slatec-fn/acosh.f
new file mode 100644
index 0000000..acfd00c
--- /dev/null
+++ b/libcruft/slatec-fn/acosh.f
@@ -0,0 +1,39 @@
+*DECK ACOSH
+      FUNCTION ACOSH (X)
+C***BEGIN PROLOGUE  ACOSH
+C***PURPOSE  Compute the arc hyperbolic cosine.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4C
+C***TYPE      SINGLE PRECISION (ACOSH-S, DACOSH-D, CACOSH-C)
+C***KEYWORDS  ACOSH, ARC HYPERBOLIC COSINE, ELEMENTARY FUNCTIONS, FNLIB,
+C             INVERSE HYPERBOLIC COSINE
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ACOSH(X) computes the arc hyperbolic cosine of X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900326  Removed duplicate information from DESCRIPTION section.
+C           (WRB)
+C***END PROLOGUE  ACOSH
+      SAVE ALN2,XMAX
+      DATA ALN2 / 0.6931471805 5994530942E0/
+      DATA XMAX /0./
+C***FIRST EXECUTABLE STATEMENT  ACOSH
+      IF (XMAX.EQ.0.) XMAX = 1.0/SQRT(R1MACH(3))
+C
+      IF (X .LT. 1.0) CALL XERMSG ('SLATEC', 'ACOSH', 'X LESS THAN 1',
+     +   1, 2)
+C
+      IF (X.LT.XMAX) ACOSH = LOG (X + SQRT(X*X-1.0))
+      IF (X.GE.XMAX) ACOSH = ALN2 + LOG(X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/albeta.f b/libcruft/slatec-fn/albeta.f
new file mode 100644
index 0000000..4ed6aca
--- /dev/null
+++ b/libcruft/slatec-fn/albeta.f
@@ -0,0 +1,63 @@
+*DECK ALBETA
+      FUNCTION ALBETA (A, B)
+C***BEGIN PROLOGUE  ALBETA
+C***PURPOSE  Compute the natural logarithm of the complete Beta
+C            function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7B
+C***TYPE      SINGLE PRECISION (ALBETA-S, DLBETA-D, CLBETA-C)
+C***KEYWORDS  FNLIB, LOGARITHM OF THE COMPLETE BETA FUNCTION,
+C             SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ALBETA computes the natural log of the complete beta function.
+C
+C Input Parameters:
+C       A   real and positive
+C       B   real and positive
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  ALNGAM, ALNREL, GAMMA, R9LGMC, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900326  Removed duplicate information from DESCRIPTION section.
+C           (WRB)
+C   900727  Added EXTERNAL statement.  (WRB)
+C***END PROLOGUE  ALBETA
+      EXTERNAL GAMMA
+      SAVE SQ2PIL
+      DATA SQ2PIL / 0.9189385332 0467274 E0 /
+C***FIRST EXECUTABLE STATEMENT  ALBETA
+      P = MIN (A, B)
+      Q = MAX (A, B)
+C
+      IF (P .LE. 0.0) CALL XERMSG ('SLATEC', 'ALBETA',
+     +   'BOTH ARGUMENTS MUST BE GT ZERO', 1, 2)
+      IF (P.GE.10.0) GO TO 30
+      IF (Q.GE.10.0) GO TO 20
+C
+C P AND Q ARE SMALL.
+C
+      ALBETA = LOG(GAMMA(P) * (GAMMA(Q)/GAMMA(P+Q)) )
+      RETURN
+C
+C P IS SMALL, BUT Q IS BIG.
+C
+ 20   CORR = R9LGMC(Q) - R9LGMC(P+Q)
+      ALBETA = ALNGAM(P) + CORR + P - P*LOG(P+Q) +
+     1  (Q-0.5)*ALNREL(-P/(P+Q))
+      RETURN
+C
+C P AND Q ARE BIG.
+C
+ 30   CORR = R9LGMC(P) + R9LGMC(Q) - R9LGMC(P+Q)
+      ALBETA = -0.5*LOG(Q) + SQ2PIL + CORR + (P-0.5)*LOG(P/(P+Q))
+     1  + Q*ALNREL(-P/(P+Q))
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/algams.f b/libcruft/slatec-fn/algams.f
new file mode 100644
index 0000000..230d78a
--- /dev/null
+++ b/libcruft/slatec-fn/algams.f
@@ -0,0 +1,38 @@
+*DECK ALGAMS
+      SUBROUTINE ALGAMS (X, ALGAM, SGNGAM)
+C***BEGIN PROLOGUE  ALGAMS
+C***PURPOSE  Compute the logarithm of the absolute value of the Gamma
+C            function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      SINGLE PRECISION (ALGAMS-S, DLGAMS-D)
+C***KEYWORDS  ABSOLUTE VALUE OF THE LOGARITHM OF THE GAMMA FUNCTION,
+C             FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Evaluates the logarithm of the absolute value of the gamma
+C function.
+C     X           - input argument
+C     ALGAM       - result
+C     SGNGAM      - is set to the sign of GAMMA(X) and will
+C                   be returned at +1.0 or -1.0.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  ALNGAM
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C***END PROLOGUE  ALGAMS
+C***FIRST EXECUTABLE STATEMENT  ALGAMS
+      ALGAM = ALNGAM(X)
+      SGNGAM = 1.0
+      IF (X.GT.0.0) RETURN
+C
+      INT = MOD (-AINT(X), 2.0) + 0.1
+      IF (INT.EQ.0) SGNGAM = -1.0
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/alngam.f b/libcruft/slatec-fn/alngam.f
new file mode 100644
index 0000000..7ba410b
--- /dev/null
+++ b/libcruft/slatec-fn/alngam.f
@@ -0,0 +1,70 @@
+*DECK ALNGAM
+      FUNCTION ALNGAM (X)
+C***BEGIN PROLOGUE  ALNGAM
+C***PURPOSE  Compute the logarithm of the absolute value of the Gamma
+C            function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      SINGLE PRECISION (ALNGAM-S, DLNGAM-D, CLNGAM-C)
+C***KEYWORDS  ABSOLUTE VALUE, COMPLETE GAMMA FUNCTION, FNLIB, LOGARITHM,
+C             SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ALNGAM(X) computes the logarithm of the absolute value of the
+C gamma function at X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  GAMMA, R1MACH, R9LGMC, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900326  Removed duplicate information from DESCRIPTION section.
+C           (WRB)
+C   900727  Added EXTERNAL statement.  (WRB)
+C***END PROLOGUE  ALNGAM
+      LOGICAL FIRST
+      EXTERNAL GAMMA
+      SAVE SQ2PIL, SQPI2L, PI, XMAX, DXREL, FIRST
+      DATA SQ2PIL / 0.9189385332 0467274E0/
+      DATA SQPI2L / 0.2257913526 4472743E0/
+      DATA PI     / 3.1415926535 8979324E0/
+      DATA FIRST  /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  ALNGAM
+      IF (FIRST) THEN
+         XMAX = R1MACH(2)/LOG(R1MACH(2))
+         DXREL = SQRT (R1MACH(4))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.10.0) GO TO 20
+C
+C LOG (ABS (GAMMA(X))) FOR  ABS(X) .LE. 10.0
+C
+      ALNGAM = LOG (ABS (GAMMA(X)))
+      RETURN
+C
+C LOG (ABS (GAMMA(X))) FOR ABS(X) .GT. 10.0
+C
+ 20   IF (Y .GT. XMAX) CALL XERMSG ('SLATEC', 'ALNGAM',
+     +   'ABS(X) SO BIG ALNGAM OVERFLOWS', 2, 2)
+C
+      IF (X.GT.0.) ALNGAM = SQ2PIL + (X-0.5)*LOG(X) - X + R9LGMC(Y)
+      IF (X.GT.0.) RETURN
+C
+      SINPIY = ABS (SIN(PI*Y))
+      IF (SINPIY .EQ. 0.) CALL XERMSG ('SLATEC', 'ALNGAM',
+     +   'X IS A NEGATIVE INTEGER', 3, 2)
+C
+      IF (ABS((X-AINT(X-0.5))/X) .LT. DXREL) CALL XERMSG ('SLATEC',
+     +   'ALNGAM', 'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR ' //
+     +   'NEGATIVE INTEGER', 1, 1)
+C
+      ALNGAM = SQPI2L + (X-0.5)*LOG(Y) - X - LOG(SINPIY) - R9LGMC(Y)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/alnrel.f b/libcruft/slatec-fn/alnrel.f
new file mode 100644
index 0000000..1617189
--- /dev/null
+++ b/libcruft/slatec-fn/alnrel.f
@@ -0,0 +1,78 @@
+*DECK ALNREL
+      FUNCTION ALNREL (X)
+C***BEGIN PROLOGUE  ALNREL
+C***PURPOSE  Evaluate ln(1+X) accurate in the sense of relative error.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4B
+C***TYPE      SINGLE PRECISION (ALNREL-S, DLNREL-D, CLNREL-C)
+C***KEYWORDS  ELEMENTARY FUNCTIONS, FNLIB, LOGARITHM
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ALNREL(X) evaluates ln(1+X) accurately in the sense of relative
+C error when X is very small.  This routine must be used to
+C maintain relative error accuracy whenever X is small and
+C accurately known.
+C
+C Series for ALNR       on the interval -3.75000D-01 to  3.75000D-01
+C                                        with weighted error   1.93E-17
+C                                         log weighted error  16.72
+C                               significant figures required  16.44
+C                                    decimal places required  17.40
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, INITS, R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900326  Removed duplicate information from DESCRIPTION section.
+C           (WRB)
+C***END PROLOGUE  ALNREL
+      DIMENSION ALNRCS(23)
+      LOGICAL FIRST
+      SAVE ALNRCS, NLNREL, XMIN, FIRST
+      DATA ALNRCS( 1) /   1.0378693562 743770E0 /
+      DATA ALNRCS( 2) /   -.1336430150 4908918E0 /
+      DATA ALNRCS( 3) /    .0194082491 35520563E0 /
+      DATA ALNRCS( 4) /   -.0030107551 12753577E0 /
+      DATA ALNRCS( 5) /    .0004869461 47971548E0 /
+      DATA ALNRCS( 6) /   -.0000810548 81893175E0 /
+      DATA ALNRCS( 7) /    .0000137788 47799559E0 /
+      DATA ALNRCS( 8) /   -.0000023802 21089435E0 /
+      DATA ALNRCS( 9) /    .0000004164 04162138E0 /
+      DATA ALNRCS(10) /   -.0000000735 95828378E0 /
+      DATA ALNRCS(11) /    .0000000131 17611876E0 /
+      DATA ALNRCS(12) /   -.0000000023 54670931E0 /
+      DATA ALNRCS(13) /    .0000000004 25227732E0 /
+      DATA ALNRCS(14) /   -.0000000000 77190894E0 /
+      DATA ALNRCS(15) /    .0000000000 14075746E0 /
+      DATA ALNRCS(16) /   -.0000000000 02576907E0 /
+      DATA ALNRCS(17) /    .0000000000 00473424E0 /
+      DATA ALNRCS(18) /   -.0000000000 00087249E0 /
+      DATA ALNRCS(19) /    .0000000000 00016124E0 /
+      DATA ALNRCS(20) /   -.0000000000 00002987E0 /
+      DATA ALNRCS(21) /    .0000000000 00000554E0 /
+      DATA ALNRCS(22) /   -.0000000000 00000103E0 /
+      DATA ALNRCS(23) /    .0000000000 00000019E0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  ALNREL
+      IF (FIRST) THEN
+         NLNREL = INITS (ALNRCS, 23, 0.1*R1MACH(3))
+         XMIN = -1.0 + SQRT(R1MACH(4))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LE. (-1.0)) CALL XERMSG ('SLATEC', 'ALNREL', 'X IS LE -1',
+     +   2, 2)
+      IF (X .LT. XMIN) CALL XERMSG ('SLATEC', 'ALNREL',
+     +   'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR -1', 1, 1)
+C
+      IF (ABS(X).LE.0.375) ALNREL = X*(1. -
+     1  X*CSEVL (X/.375, ALNRCS, NLNREL))
+      IF (ABS(X).GT.0.375) ALNREL = LOG (1.0+X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/asinh.f b/libcruft/slatec-fn/asinh.f
new file mode 100644
index 0000000..7a62d59
--- /dev/null
+++ b/libcruft/slatec-fn/asinh.f
@@ -0,0 +1,74 @@
+*DECK ASINH
+      FUNCTION ASINH (X)
+C***BEGIN PROLOGUE  ASINH
+C***PURPOSE  Compute the arc hyperbolic sine.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4C
+C***TYPE      SINGLE PRECISION (ASINH-S, DASINH-D, CASINH-C)
+C***KEYWORDS  ARC HYPERBOLIC SINE, ASINH, ELEMENTARY FUNCTIONS, FNLIB,
+C             INVERSE HYPERBOLIC SINE
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ASINH(X) computes the arc hyperbolic sine of X.
+C
+C Series for ASNH       on the interval  0.          to  1.00000D+00
+C                                        with weighted error   2.19E-17
+C                                         log weighted error  16.66
+C                               significant figures required  15.60
+C                                    decimal places required  17.31
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, INITS, R1MACH
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C***END PROLOGUE  ASINH
+      DIMENSION ASNHCS(20)
+      LOGICAL FIRST
+      SAVE ALN2, ASNHCS, NTERMS, XMAX, SQEPS, FIRST
+      DATA ALN2 /0.6931471805 5994530942E0/
+      DATA ASNHCS( 1) /   -.1282003991 1738186E0 /
+      DATA ASNHCS( 2) /   -.0588117611 89951768E0 /
+      DATA ASNHCS( 3) /    .0047274654 32212481E0 /
+      DATA ASNHCS( 4) /   -.0004938363 16265361E0 /
+      DATA ASNHCS( 5) /    .0000585062 07058557E0 /
+      DATA ASNHCS( 6) /   -.0000074669 98328931E0 /
+      DATA ASNHCS( 7) /    .0000010011 69358355E0 /
+      DATA ASNHCS( 8) /   -.0000001390 35438587E0 /
+      DATA ASNHCS( 9) /    .0000000198 23169483E0 /
+      DATA ASNHCS(10) /   -.0000000028 84746841E0 /
+      DATA ASNHCS(11) /    .0000000004 26729654E0 /
+      DATA ASNHCS(12) /   -.0000000000 63976084E0 /
+      DATA ASNHCS(13) /    .0000000000 09699168E0 /
+      DATA ASNHCS(14) /   -.0000000000 01484427E0 /
+      DATA ASNHCS(15) /    .0000000000 00229037E0 /
+      DATA ASNHCS(16) /   -.0000000000 00035588E0 /
+      DATA ASNHCS(17) /    .0000000000 00005563E0 /
+      DATA ASNHCS(18) /   -.0000000000 00000874E0 /
+      DATA ASNHCS(19) /    .0000000000 00000138E0 /
+      DATA ASNHCS(20) /   -.0000000000 00000021E0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  ASINH
+      IF (FIRST) THEN
+         NTERMS = INITS (ASNHCS, 20, 0.1*R1MACH(3))
+         SQEPS = SQRT (R1MACH(3))
+         XMAX = 1.0/SQEPS
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.1.0) GO TO 20
+C
+      ASINH = X
+      IF (Y.GT.SQEPS) ASINH = X*(1.0 + CSEVL (2.*X*X-1., ASNHCS,NTERMS))
+      RETURN
+C
+ 20   IF (Y.LT.XMAX) ASINH = LOG (Y + SQRT(Y**2+1.))
+      IF (Y.GE.XMAX) ASINH = ALN2 + LOG(Y)
+      ASINH = SIGN (ASINH, X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/atanh.f b/libcruft/slatec-fn/atanh.f
new file mode 100644
index 0000000..083d6c1
--- /dev/null
+++ b/libcruft/slatec-fn/atanh.f
@@ -0,0 +1,72 @@
+*DECK ATANH
+      FUNCTION ATANH (X)
+C***BEGIN PROLOGUE  ATANH
+C***PURPOSE  Compute the arc hyperbolic tangent.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4C
+C***TYPE      SINGLE PRECISION (ATANH-S, DATANH-D, CATANH-C)
+C***KEYWORDS  ARC HYPERBOLIC TANGENT, ATANH, ELEMENTARY FUNCTIONS,
+C             FNLIB, INVERSE HYPERBOLIC TANGENT
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ATANH(X) computes the arc hyperbolic tangent of X.
+C
+C Series for ATNH       on the interval  0.          to  2.50000D-01
+C                                        with weighted error   6.70E-18
+C                                         log weighted error  17.17
+C                               significant figures required  16.01
+C                                    decimal places required  17.76
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, INITS, R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900326  Removed duplicate information from DESCRIPTION section.
+C           (WRB)
+C***END PROLOGUE  ATANH
+      DIMENSION ATNHCS(15)
+      LOGICAL FIRST
+      SAVE ATNHCS, NTERMS, DXREL, SQEPS, FIRST
+      DATA ATNHCS( 1) /    .0943951023 93195492E0 /
+      DATA ATNHCS( 2) /    .0491984370 55786159E0 /
+      DATA ATNHCS( 3) /    .0021025935 22455432E0 /
+      DATA ATNHCS( 4) /    .0001073554 44977611E0 /
+      DATA ATNHCS( 5) /    .0000059782 67249293E0 /
+      DATA ATNHCS( 6) /    .0000003505 06203088E0 /
+      DATA ATNHCS( 7) /    .0000000212 63743437E0 /
+      DATA ATNHCS( 8) /    .0000000013 21694535E0 /
+      DATA ATNHCS( 9) /    .0000000000 83658755E0 /
+      DATA ATNHCS(10) /    .0000000000 05370503E0 /
+      DATA ATNHCS(11) /    .0000000000 00348665E0 /
+      DATA ATNHCS(12) /    .0000000000 00022845E0 /
+      DATA ATNHCS(13) /    .0000000000 00001508E0 /
+      DATA ATNHCS(14) /    .0000000000 00000100E0 /
+      DATA ATNHCS(15) /    .0000000000 00000006E0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  ATANH
+      IF (FIRST) THEN
+         NTERMS = INITS (ATNHCS, 15, 0.1*R1MACH(3))
+         DXREL = SQRT (R1MACH(4))
+         SQEPS = SQRT (3.0*R1MACH(3))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y .GE. 1.0) CALL XERMSG ('SLATEC', 'ATANH', 'ABS(X) GE 1', 2,
+     +   2)
+C
+      IF (1.0-Y .LT. DXREL) CALL XERMSG ('SLATEC', 'ATANH',
+     +   'ANSWER LT HALF PRECISION BECAUSE ABS(X) TOO NEAR 1', 1, 1)
+C
+      ATANH = X
+      IF (Y.GT.SQEPS .AND. Y.LE.0.5) ATANH = X*(1.0 + CSEVL (8.*X*X-1.,
+     1  ATNHCS, NTERMS))
+      IF (Y.GT.0.5) ATANH = 0.5*LOG((1.0+X)/(1.0-X))
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/betai.f b/libcruft/slatec-fn/betai.f
new file mode 100644
index 0000000..1d281da
--- /dev/null
+++ b/libcruft/slatec-fn/betai.f
@@ -0,0 +1,118 @@
+*DECK BETAI
+      REAL FUNCTION BETAI (X, PIN, QIN)
+C***BEGIN PROLOGUE  BETAI
+C***PURPOSE  Calculate the incomplete Beta function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7F
+C***TYPE      SINGLE PRECISION (BETAI-S, DBETAI-D)
+C***KEYWORDS  FNLIB, INCOMPLETE BETA FUNCTION, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C   BETAI calculates the REAL incomplete beta function.
+C
+C   The incomplete beta function ratio is the probability that a
+C   random variable from a beta distribution having parameters PIN and
+C   QIN will be less than or equal to X.
+C
+C     -- Input Arguments -- All arguments are REAL.
+C   X      upper limit of integration.  X must be in (0,1) inclusive.
+C   PIN    first beta distribution parameter.  PIN must be .GT. 0.0.
+C   QIN    second beta distribution parameter.  QIN must be .GT. 0.0.
+C
+C***REFERENCES  Nancy E. Bosten and E. L. Battiste, Remark on Algorithm
+C                 179, Communications of the ACM 17, 3 (March 1974),
+C                 pp. 156.
+C***ROUTINES CALLED  ALBETA, R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900326  Removed duplicate information from DESCRIPTION section.
+C           (WRB)
+C   920528  DESCRIPTION and REFERENCES sections revised.  (WRB)
+C***END PROLOGUE  BETAI
+      LOGICAL FIRST
+      SAVE EPS, ALNEPS, SML, ALNSML, FIRST
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  BETAI
+      IF (FIRST) THEN
+         EPS = R1MACH(3)
+         ALNEPS = LOG(EPS)
+         SML = R1MACH(1)
+         ALNSML = LOG(SML)
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 0. .OR. X .GT. 1.0) CALL XERMSG ('SLATEC', 'BETAI',
+     +   'X IS NOT IN THE RANGE (0,1)', 1, 2)
+      IF (PIN .LE. 0. .OR. QIN .LE. 0.) CALL XERMSG ('SLATEC', 'BETAI',
+     +   'P AND/OR Q IS LE ZERO', 2, 2)
+C
+      Y = X
+      P = PIN
+      Q = QIN
+      IF (Q.LE.P .AND. X.LT.0.8) GO TO 20
+      IF (X.LT.0.2) GO TO 20
+      Y = 1.0 - Y
+      P = QIN
+      Q = PIN
+C
+ 20   IF ((P+Q)*Y/(P+1.).LT.EPS) GO TO 80
+C
+C EVALUATE THE INFINITE SUM FIRST.
+C TERM WILL EQUAL Y**P/BETA(PS,P) * (1.-PS)I * Y**I / FAC(I)
+C
+      PS = Q - AINT(Q)
+      IF (PS.EQ.0.) PS = 1.0
+      XB = P*LOG(Y) -  ALBETA(PS, P) - LOG(P)
+      BETAI = 0.0
+      IF (XB.LT.ALNSML) GO TO 40
+C
+      BETAI = EXP (XB)
+      TERM = BETAI*P
+      IF (PS.EQ.1.0) GO TO 40
+C
+      N = MAX (ALNEPS/LOG(Y), 4.0E0)
+      DO 30 I=1,N
+        TERM = TERM*(I-PS)*Y/I
+        BETAI = BETAI + TERM/(P+I)
+ 30   CONTINUE
+C
+C NOW EVALUATE THE FINITE SUM, MAYBE.
+C
+ 40   IF (Q.LE.1.0) GO TO 70
+C
+      XB = P*LOG(Y) + Q*LOG(1.0-Y) - ALBETA(P,Q) - LOG(Q)
+      IB = MAX (XB/ALNSML, 0.0E0)
+      TERM = EXP (XB - IB*ALNSML)
+      C = 1.0/(1.0-Y)
+      P1 = Q*C/(P+Q-1.)
+C
+      FINSUM = 0.0
+      N = Q
+      IF (Q.EQ.REAL(N)) N = N - 1
+      DO 50 I=1,N
+        IF (P1.LE.1.0 .AND. TERM/EPS.LE.FINSUM) GO TO 60
+        TERM = (Q-I+1)*C*TERM/(P+Q-I)
+C
+        IF (TERM.GT.1.0) IB = IB - 1
+        IF (TERM.GT.1.0) TERM = TERM*SML
+C
+        IF (IB.EQ.0) FINSUM = FINSUM + TERM
+ 50   CONTINUE
+C
+ 60   BETAI = BETAI + FINSUM
+ 70   IF (Y.NE.X .OR. P.NE.PIN) BETAI = 1.0 - BETAI
+      BETAI = MAX (MIN (BETAI, 1.0), 0.0)
+      RETURN
+C
+ 80   BETAI = 0.0
+      XB = P*LOG(MAX(Y,SML)) - LOG(P) - ALBETA(P,Q)
+      IF (XB.GT.ALNSML .AND. Y.NE.0.) BETAI = EXP (XB)
+      IF (Y.NE.X .OR. P.NE.PIN) BETAI = 1.0 - BETAI
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/csevl.f b/libcruft/slatec-fn/csevl.f
new file mode 100644
index 0000000..8b7d2a8
--- /dev/null
+++ b/libcruft/slatec-fn/csevl.f
@@ -0,0 +1,65 @@
+*DECK CSEVL
+      FUNCTION CSEVL (X, CS, N)
+C***BEGIN PROLOGUE  CSEVL
+C***PURPOSE  Evaluate a Chebyshev series.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C3A2
+C***TYPE      SINGLE PRECISION (CSEVL-S, DCSEVL-D)
+C***KEYWORDS  CHEBYSHEV SERIES, FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C  Evaluate the N-term Chebyshev series CS at X.  Adapted from
+C  a method presented in the paper by Broucke referenced below.
+C
+C       Input Arguments --
+C  X    value at which the series is to be evaluated.
+C  CS   array of N terms of a Chebyshev series.  In evaluating
+C       CS, only half the first coefficient is summed.
+C  N    number of terms in array CS.
+C
+C***REFERENCES  R. Broucke, Ten subroutines for the manipulation of
+C                 Chebyshev series, Algorithm 446, Communications of
+C                 the A.C.M. 16, (1973) pp. 254-256.
+C               L. Fox and I. B. Parker, Chebyshev Polynomials in
+C                 Numerical Analysis, Oxford University Press, 1968,
+C                 page 56.
+C***ROUTINES CALLED  R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890831  Modified array declarations.  (WRB)
+C   890831  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900329  Prologued revised extensively and code rewritten to allow
+C           X to be slightly outside interval (-1,+1).  (WRB)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  CSEVL
+      REAL B0, B1, B2, CS(*), ONEPL, TWOX, X
+      LOGICAL FIRST
+      SAVE FIRST, ONEPL
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  CSEVL
+      IF (FIRST) ONEPL = 1.0E0 + R1MACH(4)
+      FIRST = .FALSE.
+      IF (N .LT. 1) CALL XERMSG ('SLATEC', 'CSEVL',
+     +   'NUMBER OF TERMS .LE. 0', 2, 2)
+      IF (N .GT. 1000) CALL XERMSG ('SLATEC', 'CSEVL',
+     +   'NUMBER OF TERMS .GT. 1000', 3, 2)
+      IF (ABS(X) .GT. ONEPL) CALL XERMSG ('SLATEC', 'CSEVL',
+     +   'X OUTSIDE THE INTERVAL (-1,+1)', 1, 1)
+C
+      B1 = 0.0E0
+      B0 = 0.0E0
+      TWOX = 2.0*X
+      DO 10 I = 1,N
+         B2 = B1
+         B1 = B0
+         NI = N + 1 - I
+         B0 = TWOX*B1 - B2 + CS(NI)
+   10 CONTINUE
+C
+      CSEVL = 0.5E0*(B0-B2)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/d9gmit.f b/libcruft/slatec-fn/d9gmit.f
new file mode 100644
index 0000000..9752136
--- /dev/null
+++ b/libcruft/slatec-fn/d9gmit.f
@@ -0,0 +1,91 @@
+*DECK D9GMIT
+      DOUBLE PRECISION FUNCTION D9GMIT (A, X, ALGAP1, SGNGAM, ALX)
+C***BEGIN PROLOGUE  D9GMIT
+C***SUBSIDIARY
+C***PURPOSE  Compute Tricomi's incomplete Gamma function for small
+C            arguments.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      DOUBLE PRECISION (R9GMIT-S, D9GMIT-D)
+C***KEYWORDS  COMPLEMENTARY INCOMPLETE GAMMA FUNCTION, FNLIB, SMALL X,
+C             SPECIAL FUNCTIONS, TRICOMI
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute Tricomi's incomplete gamma function for small X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DLNGAM, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890911  Removed unnecessary intrinsics.  (WRB)
+C   890911  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  D9GMIT
+      DOUBLE PRECISION A, X, ALGAP1, SGNGAM, ALX, AE, AEPS, ALGS, ALG2,
+     1  BOT, EPS, FK, S, SGNG2, T, TE, D1MACH, DLNGAM
+      LOGICAL FIRST
+      SAVE EPS, BOT, FIRST
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  D9GMIT
+      IF (FIRST) THEN
+         EPS = 0.5D0*D1MACH(3)
+         BOT = LOG (D1MACH(1))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LE. 0.D0) CALL XERMSG ('SLATEC', 'D9GMIT',
+     +   'X SHOULD BE GT 0', 1, 2)
+C
+      MA = A + 0.5D0
+      IF (A.LT.0.D0) MA = A - 0.5D0
+      AEPS = A - MA
+C
+      AE = A
+      IF (A.LT.(-0.5D0)) AE = AEPS
+C
+      T = 1.D0
+      TE = AE
+      S = T
+      DO 20 K=1,200
+        FK = K
+        TE = -X*TE/FK
+        T = TE/(AE+FK)
+        S = S + T
+        IF (ABS(T).LT.EPS*ABS(S)) GO TO 30
+ 20   CONTINUE
+      CALL XERMSG ('SLATEC', 'D9GMIT',
+     +   'NO CONVERGENCE IN 200 TERMS OF TAYLOR-S SERIES', 2, 2)
+C
+ 30   IF (A.GE.(-0.5D0)) ALGS = -ALGAP1 + LOG(S)
+      IF (A.GE.(-0.5D0)) GO TO 60
+C
+      ALGS = -DLNGAM(1.D0+AEPS) + LOG(S)
+      S = 1.0D0
+      M = -MA - 1
+      IF (M.EQ.0) GO TO 50
+      T = 1.0D0
+      DO 40 K=1,M
+        T = X*T/(AEPS-(M+1-K))
+        S = S + T
+        IF (ABS(T).LT.EPS*ABS(S)) GO TO 50
+ 40   CONTINUE
+C
+ 50   D9GMIT = 0.0D0
+      ALGS = -MA*LOG(X) + ALGS
+      IF (S.EQ.0.D0 .OR. AEPS.EQ.0.D0) GO TO 60
+C
+      SGNG2 = SGNGAM * SIGN (1.0D0, S)
+      ALG2 = -X - ALGAP1 + LOG(ABS(S))
+C
+      IF (ALG2.GT.BOT) D9GMIT = SGNG2 * EXP(ALG2)
+      IF (ALGS.GT.BOT) D9GMIT = D9GMIT + EXP(ALGS)
+      RETURN
+C
+ 60   D9GMIT = EXP (ALGS)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/d9lgic.f b/libcruft/slatec-fn/d9lgic.f
new file mode 100644
index 0000000..fbe764d
--- /dev/null
+++ b/libcruft/slatec-fn/d9lgic.f
@@ -0,0 +1,54 @@
+*DECK D9LGIC
+      DOUBLE PRECISION FUNCTION D9LGIC (A, X, ALX)
+C***BEGIN PROLOGUE  D9LGIC
+C***SUBSIDIARY
+C***PURPOSE  Compute the log complementary incomplete Gamma function
+C            for large X and for A .LE. X.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      DOUBLE PRECISION (R9LGIC-S, D9LGIC-D)
+C***KEYWORDS  COMPLEMENTARY INCOMPLETE GAMMA FUNCTION, FNLIB, LARGE X,
+C             LOGARITHM, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute the log complementary incomplete gamma function for large X
+C and for A .LE. X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  D9LGIC
+      DOUBLE PRECISION A, X, ALX, EPS, FK, P, R, S, T, XMA, XPA, D1MACH
+      SAVE EPS
+      DATA EPS / 0.D0 /
+C***FIRST EXECUTABLE STATEMENT  D9LGIC
+      IF (EPS.EQ.0.D0) EPS = 0.5D0*D1MACH(3)
+C
+      XPA = X + 1.0D0 - A
+      XMA = X - 1.D0 - A
+C
+      R = 0.D0
+      P = 1.D0
+      S = P
+      DO 10 K=1,300
+        FK = K
+        T = FK*(A-FK)*(1.D0+R)
+        R = -T/((XMA+2.D0*FK)*(XPA+2.D0*FK)+T)
+        P = R*P
+        S = S + P
+        IF (ABS(P).LT.EPS*S) GO TO 20
+ 10   CONTINUE
+      CALL XERMSG ('SLATEC', 'D9LGIC',
+     +   'NO CONVERGENCE IN 300 TERMS OF CONTINUED FRACTION', 1, 2)
+C
+ 20   D9LGIC = A*ALX - X + LOG(S/XPA)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/d9lgit.f b/libcruft/slatec-fn/d9lgit.f
new file mode 100644
index 0000000..8cc79f1
--- /dev/null
+++ b/libcruft/slatec-fn/d9lgit.f
@@ -0,0 +1,67 @@
+*DECK D9LGIT
+      DOUBLE PRECISION FUNCTION D9LGIT (A, X, ALGAP1)
+C***BEGIN PROLOGUE  D9LGIT
+C***SUBSIDIARY
+C***PURPOSE  Compute the logarithm of Tricomi's incomplete Gamma
+C            function with Perron's continued fraction for large X and
+C            A .GE. X.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      DOUBLE PRECISION (R9LGIT-S, D9LGIT-D)
+C***KEYWORDS  FNLIB, INCOMPLETE GAMMA FUNCTION, LOGARITHM,
+C             PERRON'S CONTINUED FRACTION, SPECIAL FUNCTIONS, TRICOMI
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute the log of Tricomi's incomplete gamma function with Perron's
+C continued fraction for large X and for A .GE. X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  D9LGIT
+      DOUBLE PRECISION A, X, ALGAP1, AX, A1X, EPS, FK, HSTAR, P, R, S,
+     1  SQEPS, T, D1MACH
+      LOGICAL FIRST
+      SAVE EPS, SQEPS, FIRST
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  D9LGIT
+      IF (FIRST) THEN
+         EPS = 0.5D0*D1MACH(3)
+         SQEPS = SQRT(D1MACH(4))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LE. 0.D0 .OR. A .LT. X) CALL XERMSG ('SLATEC', 'D9LGIT',
+     +   'X SHOULD BE GT 0.0 AND LE A', 2, 2)
+C
+      AX = A + X
+      A1X = AX + 1.0D0
+      R = 0.D0
+      P = 1.D0
+      S = P
+      DO 20 K=1,200
+        FK = K
+        T = (A+FK)*X*(1.D0+R)
+        R = T/((AX+FK)*(A1X+FK)-T)
+        P = R*P
+        S = S + P
+        IF (ABS(P).LT.EPS*S) GO TO 30
+ 20   CONTINUE
+      CALL XERMSG ('SLATEC', 'D9LGIT',
+     +   'NO CONVERGENCE IN 200 TERMS OF CONTINUED FRACTION', 3, 2)
+C
+ 30   HSTAR = 1.0D0 - X*S/A1X
+      IF (HSTAR .LT. SQEPS) CALL XERMSG ('SLATEC', 'D9LGIT',
+     +   'RESULT LESS THAN HALF PRECISION', 1, 1)
+C
+      D9LGIT = -X - ALGAP1 - LOG(HSTAR)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/d9lgmc.f b/libcruft/slatec-fn/d9lgmc.f
new file mode 100644
index 0000000..0b4b327
--- /dev/null
+++ b/libcruft/slatec-fn/d9lgmc.f
@@ -0,0 +1,76 @@
+*DECK D9LGMC
+      DOUBLE PRECISION FUNCTION D9LGMC (X)
+C***BEGIN PROLOGUE  D9LGMC
+C***SUBSIDIARY
+C***PURPOSE  Compute the log Gamma correction factor so that
+C            LOG(DGAMMA(X)) = LOG(SQRT(2*PI)) + (X-5.)*LOG(X) - X
+C            + D9LGMC(X).
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      DOUBLE PRECISION (R9LGMC-S, D9LGMC-D, C9LGMC-C)
+C***KEYWORDS  COMPLETE GAMMA FUNCTION, CORRECTION TERM, FNLIB,
+C             LOG GAMMA, LOGARITHM, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute the log gamma correction factor for X .GE. 10. so that
+C LOG (DGAMMA(X)) = LOG(SQRT(2*PI)) + (X-.5)*LOG(X) - X + D9lGMC(X)
+C
+C Series for ALGM       on the interval  0.          to  1.00000E-02
+C                                        with weighted error   1.28E-31
+C                                         log weighted error  30.89
+C                               significant figures required  29.81
+C                                    decimal places required  31.48
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DCSEVL, INITDS, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  D9LGMC
+      DOUBLE PRECISION X, ALGMCS(15), XBIG, XMAX, DCSEVL, D1MACH
+      LOGICAL FIRST
+      SAVE ALGMCS, NALGM, XBIG, XMAX, FIRST
+      DATA ALGMCS(  1) / +.1666389480 4518632472 0572965082 2 D+0      /
+      DATA ALGMCS(  2) / -.1384948176 0675638407 3298605913 5 D-4      /
+      DATA ALGMCS(  3) / +.9810825646 9247294261 5717154748 7 D-8      /
+      DATA ALGMCS(  4) / -.1809129475 5724941942 6330626671 9 D-10     /
+      DATA ALGMCS(  5) / +.6221098041 8926052271 2601554341 6 D-13     /
+      DATA ALGMCS(  6) / -.3399615005 4177219443 0333059966 6 D-15     /
+      DATA ALGMCS(  7) / +.2683181998 4826987489 5753884666 6 D-17     /
+      DATA ALGMCS(  8) / -.2868042435 3346432841 4462239999 9 D-19     /
+      DATA ALGMCS(  9) / +.3962837061 0464348036 7930666666 6 D-21     /
+      DATA ALGMCS( 10) / -.6831888753 9857668701 1199999999 9 D-23     /
+      DATA ALGMCS( 11) / +.1429227355 9424981475 7333333333 3 D-24     /
+      DATA ALGMCS( 12) / -.3547598158 1010705471 9999999999 9 D-26     /
+      DATA ALGMCS( 13) / +.1025680058 0104709120 0000000000 0 D-27     /
+      DATA ALGMCS( 14) / -.3401102254 3167487999 9999999999 9 D-29     /
+      DATA ALGMCS( 15) / +.1276642195 6300629333 3333333333 3 D-30     /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  D9LGMC
+      IF (FIRST) THEN
+         NALGM = INITDS (ALGMCS, 15, REAL(D1MACH(3)) )
+         XBIG = 1.0D0/SQRT(D1MACH(3))
+         XMAX = EXP (MIN(LOG(D1MACH(2)/12.D0), -LOG(12.D0*D1MACH(1))))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 10.D0) CALL XERMSG ('SLATEC', 'D9LGMC',
+     +   'X MUST BE GE 10', 1, 2)
+      IF (X.GE.XMAX) GO TO 20
+C
+      D9LGMC = 1.D0/(12.D0*X)
+      IF (X.LT.XBIG) D9LGMC = DCSEVL (2.0D0*(10.D0/X)**2-1.D0, ALGMCS,
+     1  NALGM) / X
+      RETURN
+C
+ 20   D9LGMC = 0.D0
+      CALL XERMSG ('SLATEC', 'D9LGMC', 'X SO BIG D9LGMC UNDERFLOWS', 2,
+     +   1)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/dacosh.f b/libcruft/slatec-fn/dacosh.f
new file mode 100644
index 0000000..06cfb3f
--- /dev/null
+++ b/libcruft/slatec-fn/dacosh.f
@@ -0,0 +1,40 @@
+*DECK DACOSH
+      DOUBLE PRECISION FUNCTION DACOSH (X)
+C***BEGIN PROLOGUE  DACOSH
+C***PURPOSE  Compute the arc hyperbolic cosine.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4C
+C***TYPE      DOUBLE PRECISION (ACOSH-S, DACOSH-D, CACOSH-C)
+C***KEYWORDS  ACOSH, ARC HYPERBOLIC COSINE, ELEMENTARY FUNCTIONS, FNLIB,
+C             INVERSE HYPERBOLIC COSINE
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DACOSH(X) calculates the double precision arc hyperbolic cosine for
+C double precision argument X.  The result is returned on the
+C positive branch.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  DACOSH
+      DOUBLE PRECISION X, DLN2, XMAX,  D1MACH
+      SAVE DLN2, XMAX
+      DATA DLN2 / 0.6931471805 5994530941 7232121458 18 D0 /
+      DATA XMAX / 0.D0 /
+C***FIRST EXECUTABLE STATEMENT  DACOSH
+      IF (XMAX.EQ.0.D0) XMAX = 1.0D0/SQRT(D1MACH(3))
+C
+      IF (X .LT. 1.D0) CALL XERMSG ('SLATEC', 'DACOSH',
+     +   'X LESS THAN 1', 1, 2)
+C
+      IF (X.LT.XMAX) DACOSH = LOG (X+SQRT(X*X-1.0D0))
+      IF (X.GE.XMAX) DACOSH = DLN2 + LOG(X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dasinh.f b/libcruft/slatec-fn/dasinh.f
new file mode 100644
index 0000000..7836777
--- /dev/null
+++ b/libcruft/slatec-fn/dasinh.f
@@ -0,0 +1,89 @@
+*DECK DASINH
+      DOUBLE PRECISION FUNCTION DASINH (X)
+C***BEGIN PROLOGUE  DASINH
+C***PURPOSE  Compute the arc hyperbolic sine.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4C
+C***TYPE      DOUBLE PRECISION (ASINH-S, DASINH-D, CASINH-C)
+C***KEYWORDS  ARC HYPERBOLIC SINE, ASINH, ELEMENTARY FUNCTIONS, FNLIB,
+C             INVERSE HYPERBOLIC SINE
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DASINH(X) calculates the double precision arc hyperbolic
+C sine for double precision argument X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DCSEVL, INITDS
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C***END PROLOGUE  DASINH
+      DOUBLE PRECISION X, ASNHCS(39), ALN2, SQEPS, XMAX, Y,
+     1  DCSEVL, D1MACH
+      LOGICAL FIRST
+      SAVE ASNHCS, ALN2, NTERMS, XMAX, SQEPS, FIRST
+      DATA ASNHCS(  1) / -.1282003991 1738186343 3721273592 68 D+0     /
+      DATA ASNHCS(  2) / -.5881176118 9951767565 2117571383 62 D-1     /
+      DATA ASNHCS(  3) / +.4727465432 2124815640 7252497560 29 D-2     /
+      DATA ASNHCS(  4) / -.4938363162 6536172101 3601747902 73 D-3     /
+      DATA ASNHCS(  5) / +.5850620705 8557412287 4948352593 21 D-4     /
+      DATA ASNHCS(  6) / -.7466998328 9313681354 7550692171 88 D-5     /
+      DATA ASNHCS(  7) / +.1001169358 3558199265 9661920158 12 D-5     /
+      DATA ASNHCS(  8) / -.1390354385 8708333608 6164722588 86 D-6     /
+      DATA ASNHCS(  9) / +.1982316948 3172793547 3173602371 48 D-7     /
+      DATA ASNHCS( 10) / -.2884746841 7848843612 7472728003 17 D-8     /
+      DATA ASNHCS( 11) / +.4267296546 7159937953 4575149959 07 D-9     /
+      DATA ASNHCS( 12) / -.6397608465 4366357868 7526323096 81 D-10    /
+      DATA ASNHCS( 13) / +.9699168608 9064704147 8782931311 79 D-11    /
+      DATA ASNHCS( 14) / -.1484427697 2043770830 2466583656 96 D-11    /
+      DATA ASNHCS( 15) / +.2290373793 9027447988 0401843789 83 D-12    /
+      DATA ASNHCS( 16) / -.3558839513 2732645159 9789426513 10 D-13    /
+      DATA ASNHCS( 17) / +.5563969408 0056789953 3745390885 54 D-14    /
+      DATA ASNHCS( 18) / -.8746250959 9624678045 6665935201 62 D-15    /
+      DATA ASNHCS( 19) / +.1381524884 4526692155 8688022981 29 D-15    /
+      DATA ASNHCS( 20) / -.2191668828 2900363984 9551422641 49 D-16    /
+      DATA ASNHCS( 21) / +.3490465852 4827565638 3139237068 80 D-17    /
+      DATA ASNHCS( 22) / -.5578578840 0895742439 6301570321 06 D-18    /
+      DATA ASNHCS( 23) / +.8944514661 7134012551 0508827989 33 D-19    /
+      DATA ASNHCS( 24) / -.1438342634 6571317305 5518452394 66 D-19    /
+      DATA ASNHCS( 25) / +.2319181187 2169963036 3261446826 66 D-20    /
+      DATA ASNHCS( 26) / -.3748700795 3314343674 5706045439 99 D-21    /
+      DATA ASNHCS( 27) / +.6073210982 2064279404 5492428800 00 D-22    /
+      DATA ASNHCS( 28) / -.9859940276 4633583177 3701734400 00 D-23    /
+      DATA ASNHCS( 29) / +.1603921745 2788496315 2326382933 33 D-23    /
+      DATA ASNHCS( 30) / -.2613884735 0287686596 7161343999 99 D-24    /
+      DATA ASNHCS( 31) / +.4267084960 6857390833 3581653333 33 D-25    /
+      DATA ASNHCS( 32) / -.6977021703 9185243299 7307733333 33 D-26    /
+      DATA ASNHCS( 33) / +.1142508833 6806858659 8126933333 33 D-26    /
+      DATA ASNHCS( 34) / -.1873529207 8860968933 0210133333 33 D-27    /
+      DATA ASNHCS( 35) / +.3076358441 4464922794 0659200000 00 D-28    /
+      DATA ASNHCS( 36) / -.5057736403 1639824787 0463999999 99 D-29    /
+      DATA ASNHCS( 37) / +.8325075471 2689142224 2133333333 33 D-30    /
+      DATA ASNHCS( 38) / -.1371845728 2501044163 9253333333 33 D-30    /
+      DATA ASNHCS( 39) / +.2262986842 6552784104 1066666666 66 D-31    /
+      DATA ALN2 / 0.6931471805 5994530941 7232121458 18D0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DASINH
+      IF (FIRST) THEN
+         NTERMS = INITDS (ASNHCS, 39, 0.1*REAL(D1MACH(3)) )
+         SQEPS = SQRT(D1MACH(3))
+         XMAX = 1.0D0/SQEPS
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.1.0D0) GO TO 20
+C
+      DASINH = X
+      IF (Y.GT.SQEPS) DASINH = X*(1.0D0 + DCSEVL (2.D0*X*X-1.D0,
+     1  ASNHCS, NTERMS) )
+      RETURN
+ 20   IF (Y.LT.XMAX) DASINH = LOG (Y+SQRT(Y*Y+1.D0))
+      IF (Y.GE.XMAX) DASINH = ALN2 + LOG(Y)
+      DASINH = SIGN (DASINH, X)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/datanh.f b/libcruft/slatec-fn/datanh.f
new file mode 100644
index 0000000..3599a48
--- /dev/null
+++ b/libcruft/slatec-fn/datanh.f
@@ -0,0 +1,83 @@
+*DECK DATANH
+      DOUBLE PRECISION FUNCTION DATANH (X)
+C***BEGIN PROLOGUE  DATANH
+C***PURPOSE  Compute the arc hyperbolic tangent.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4C
+C***TYPE      DOUBLE PRECISION (ATANH-S, DATANH-D, CATANH-C)
+C***KEYWORDS  ARC HYPERBOLIC TANGENT, ATANH, ELEMENTARY FUNCTIONS,
+C             FNLIB, INVERSE HYPERBOLIC TANGENT
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DATANH(X) calculates the double precision arc hyperbolic
+C tangent for double precision argument X.
+C
+C Series for ATNH       on the interval  0.          to  2.50000E-01
+C                                        with weighted error   6.86E-32
+C                                         log weighted error  31.16
+C                               significant figures required  30.00
+C                                    decimal places required  31.88
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DCSEVL, INITDS, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  DATANH
+      DOUBLE PRECISION X, ATNHCS(27), DXREL, SQEPS, Y, DCSEVL, D1MACH
+      LOGICAL FIRST
+      SAVE ATNHCS, NTERMS, DXREL, SQEPS, FIRST
+      DATA ATNHCS(  1) / +.9439510239 3195492308 4289221863 3 D-1      /
+      DATA ATNHCS(  2) / +.4919843705 5786159472 0003457666 8 D-1      /
+      DATA ATNHCS(  3) / +.2102593522 4554327634 7932733175 2 D-2      /
+      DATA ATNHCS(  4) / +.1073554449 7761165846 4073104527 6 D-3      /
+      DATA ATNHCS(  5) / +.5978267249 2930314786 4278751787 2 D-5      /
+      DATA ATNHCS(  6) / +.3505062030 8891348459 6683488620 0 D-6      /
+      DATA ATNHCS(  7) / +.2126374343 7653403508 9621931443 1 D-7      /
+      DATA ATNHCS(  8) / +.1321694535 7155271921 2980172305 5 D-8      /
+      DATA ATNHCS(  9) / +.8365875501 1780703646 2360405295 9 D-10     /
+      DATA ATNHCS( 10) / +.5370503749 3110021638 8143458777 2 D-11     /
+      DATA ATNHCS( 11) / +.3486659470 1571079229 7124578429 0 D-12     /
+      DATA ATNHCS( 12) / +.2284549509 6034330155 2402411972 2 D-13     /
+      DATA ATNHCS( 13) / +.1508407105 9447930448 7422906755 8 D-14     /
+      DATA ATNHCS( 14) / +.1002418816 8041091261 3699572283 7 D-15     /
+      DATA ATNHCS( 15) / +.6698674738 1650695397 1552688298 6 D-17     /
+      DATA ATNHCS( 16) / +.4497954546 4949310830 8332762453 3 D-18     /
+      DATA ATNHCS( 17) / +.3032954474 2794535416 8236714666 6 D-19     /
+      DATA ATNHCS( 18) / +.2052702064 1909368264 6386141866 6 D-20     /
+      DATA ATNHCS( 19) / +.1393848977 0538377131 9301461333 3 D-21     /
+      DATA ATNHCS( 20) / +.9492580637 2245769719 5895466666 6 D-23     /
+      DATA ATNHCS( 21) / +.6481915448 2423076049 8244266666 6 D-24     /
+      DATA ATNHCS( 22) / +.4436730205 7236152726 3232000000 0 D-25     /
+      DATA ATNHCS( 23) / +.3043465618 5431616389 1200000000 0 D-26     /
+      DATA ATNHCS( 24) / +.2091881298 7923934740 4799999999 9 D-27     /
+      DATA ATNHCS( 25) / +.1440445411 2340505613 6533333333 3 D-28     /
+      DATA ATNHCS( 26) / +.9935374683 1416404650 6666666666 6 D-30     /
+      DATA ATNHCS( 27) / +.6863462444 3582600533 3333333333 3 D-31     /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DATANH
+      IF (FIRST) THEN
+         NTERMS = INITDS (ATNHCS, 27, 0.1*REAL(D1MACH(3)) )
+         DXREL = SQRT(D1MACH(4))
+         SQEPS = SQRT(3.0D0*D1MACH(3))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y .GE. 1.D0) CALL XERMSG ('SLATEC', 'DATANH', 'ABS(X) GE 1',
+     +   2, 2)
+C
+      IF (1.D0-Y .LT. DXREL) CALL XERMSG ('SLATEC', 'DATANH',
+     +   'ANSWER LT HALF PRECISION BECAUSE ABS(X) TOO NEAR 1', 1, 1)
+C
+      DATANH = X
+      IF (Y.GT.SQEPS .AND. Y.LE.0.5D0) DATANH = X*(1.0D0 +
+     1  DCSEVL (8.D0*X*X-1.D0, ATNHCS, NTERMS) )
+      IF (Y.GT.0.5D0) DATANH = 0.5D0*LOG ((1.0D0+X)/(1.0D0-X))
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dbetai.f b/libcruft/slatec-fn/dbetai.f
new file mode 100644
index 0000000..3e71322
--- /dev/null
+++ b/libcruft/slatec-fn/dbetai.f
@@ -0,0 +1,121 @@
+
+*DECK DBETAI
+      DOUBLE PRECISION FUNCTION DBETAI (X, PIN, QIN)
+C***BEGIN PROLOGUE  DBETAI
+C***PURPOSE  Calculate the incomplete Beta function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7F
+C***TYPE      DOUBLE PRECISION (BETAI-S, DBETAI-D)
+C***KEYWORDS  FNLIB, INCOMPLETE BETA FUNCTION, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C   DBETAI calculates the DOUBLE PRECISION incomplete beta function.
+C
+C   The incomplete beta function ratio is the probability that a
+C   random variable from a beta distribution having parameters PIN and
+C   QIN will be less than or equal to X.
+C
+C     -- Input Arguments -- All arguments are DOUBLE PRECISION.
+C   X      upper limit of integration.  X must be in (0,1) inclusive.
+C   PIN    first beta distribution parameter.  PIN must be .GT. 0.0.
+C   QIN    second beta distribution parameter.  QIN must be .GT. 0.0.
+C
+C***REFERENCES  Nancy E. Bosten and E. L. Battiste, Remark on Algorithm
+C                 179, Communications of the ACM 17, 3 (March 1974),
+C                 pp. 156.
+C***ROUTINES CALLED  D1MACH, DLBETA, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890911  Removed unnecessary intrinsics.  (WRB)
+C   890911  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920528  DESCRIPTION and REFERENCES sections revised.  (WRB)
+C***END PROLOGUE  DBETAI
+      DOUBLE PRECISION X, PIN, QIN, ALNEPS, ALNSML, C, EPS, FINSUM, P,
+     1  PS, Q, SML, TERM, XB, XI, Y, D1MACH, DLBETA, P1
+      LOGICAL FIRST
+      SAVE EPS, ALNEPS, SML, ALNSML, FIRST
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DBETAI
+      IF (FIRST) THEN
+         EPS = D1MACH(3)
+         ALNEPS = LOG (EPS)
+         SML = D1MACH(1)
+         ALNSML = LOG (SML)
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 0.D0 .OR. X .GT. 1.D0) CALL XERMSG ('SLATEC', 'DBETAI',
+     +   'X IS NOT IN THE RANGE (0,1)', 1, 2)
+      IF (PIN .LE. 0.D0 .OR. QIN .LE. 0.D0) CALL XERMSG ('SLATEC',
+     +   'DBETAI', 'P AND/OR Q IS LE ZERO', 2, 2)
+C
+      Y = X
+      P = PIN
+      Q = QIN
+      IF (Q.LE.P .AND. X.LT.0.8D0) GO TO 20
+      IF (X.LT.0.2D0) GO TO 20
+      Y = 1.0D0 - Y
+      P = QIN
+      Q = PIN
+C
+ 20   IF ((P+Q)*Y/(P+1.D0).LT.EPS) GO TO 80
+C
+C EVALUATE THE INFINITE SUM FIRST.  TERM WILL EQUAL
+C Y**P/BETA(PS,P) * (1.-PS)-SUB-I * Y**I / FAC(I) .
+C
+      PS = Q - AINT(Q)
+      IF (PS.EQ.0.D0) PS = 1.0D0
+      XB = P*LOG(Y) - DLBETA(PS,P) - LOG(P)
+      DBETAI = 0.0D0
+      IF (XB.LT.ALNSML) GO TO 40
+C
+      DBETAI = EXP (XB)
+      TERM = DBETAI*P
+      IF (PS.EQ.1.0D0) GO TO 40
+      N = MAX (ALNEPS/LOG(Y), 4.0D0)
+      DO 30 I=1,N
+        XI = I
+        TERM = TERM * (XI-PS)*Y/XI
+        DBETAI = DBETAI + TERM/(P+XI)
+ 30   CONTINUE
+C
+C NOW EVALUATE THE FINITE SUM, MAYBE.
+C
+ 40   IF (Q.LE.1.0D0) GO TO 70
+C
+      XB = P*LOG(Y) + Q*LOG(1.0D0-Y) - DLBETA(P,Q) - LOG(Q)
+      IB = MAX (XB/ALNSML, 0.0D0)
+      TERM = EXP(XB - IB*ALNSML)
+      C = 1.0D0/(1.D0-Y)
+      P1 = Q*C/(P+Q-1.D0)
+C
+      FINSUM = 0.0D0
+      N = Q
+      IF (Q.EQ.DBLE(N)) N = N - 1
+      DO 50 I=1,N
+        IF (P1.LE.1.0D0 .AND. TERM/EPS.LE.FINSUM) GO TO 60
+        XI = I
+        TERM = (Q-XI+1.0D0)*C*TERM/(P+Q-XI)
+C
+        IF (TERM.GT.1.0D0) IB = IB - 1
+        IF (TERM.GT.1.0D0) TERM = TERM*SML
+C
+        IF (IB.EQ.0) FINSUM = FINSUM + TERM
+ 50   CONTINUE
+C
+ 60   DBETAI = DBETAI + FINSUM
+ 70   IF (Y.NE.X .OR. P.NE.PIN) DBETAI = 1.0D0 - DBETAI
+      DBETAI = MAX (MIN (DBETAI, 1.0D0), 0.0D0)
+      RETURN
+C
+ 80   DBETAI = 0.0D0
+      XB = P*LOG(MAX(Y,SML)) - LOG(P) - DLBETA(P,Q)
+      IF (XB.GT.ALNSML .AND. Y.NE.0.0D0) DBETAI = EXP(XB)
+      IF (Y.NE.X .OR. P.NE.PIN) DBETAI = 1.0D0 - DBETAI
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dcsevl.f b/libcruft/slatec-fn/dcsevl.f
new file mode 100644
index 0000000..7cff406
--- /dev/null
+++ b/libcruft/slatec-fn/dcsevl.f
@@ -0,0 +1,65 @@
+*DECK DCSEVL
+      DOUBLE PRECISION FUNCTION DCSEVL (X, CS, N)
+C***BEGIN PROLOGUE  DCSEVL
+C***PURPOSE  Evaluate a Chebyshev series.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C3A2
+C***TYPE      DOUBLE PRECISION (CSEVL-S, DCSEVL-D)
+C***KEYWORDS  CHEBYSHEV SERIES, FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C  Evaluate the N-term Chebyshev series CS at X.  Adapted from
+C  a method presented in the paper by Broucke referenced below.
+C
+C       Input Arguments --
+C  X    value at which the series is to be evaluated.
+C  CS   array of N terms of a Chebyshev series.  In evaluating
+C       CS, only half the first coefficient is summed.
+C  N    number of terms in array CS.
+C
+C***REFERENCES  R. Broucke, Ten subroutines for the manipulation of
+C                 Chebyshev series, Algorithm 446, Communications of
+C                 the A.C.M. 16, (1973) pp. 254-256.
+C               L. Fox and I. B. Parker, Chebyshev Polynomials in
+C                 Numerical Analysis, Oxford University Press, 1968,
+C                 page 56.
+C***ROUTINES CALLED  D1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890831  Modified array declarations.  (WRB)
+C   890831  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900329  Prologued revised extensively and code rewritten to allow
+C           X to be slightly outside interval (-1,+1).  (WRB)
+C   920501  Reformatted the REFERENCES section.  (WRB)
+C***END PROLOGUE  DCSEVL
+      DOUBLE PRECISION B0, B1, B2, CS(*), ONEPL, TWOX, X, D1MACH
+      LOGICAL FIRST
+      SAVE FIRST, ONEPL
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DCSEVL
+      IF (FIRST) ONEPL = 1.0D0 + D1MACH(4)
+      FIRST = .FALSE.
+      IF (N .LT. 1) CALL XERMSG ('SLATEC', 'DCSEVL',
+     +   'NUMBER OF TERMS .LE. 0', 2, 2)
+      IF (N .GT. 1000) CALL XERMSG ('SLATEC', 'DCSEVL',
+     +   'NUMBER OF TERMS .GT. 1000', 3, 2)
+      IF (ABS(X) .GT. ONEPL) CALL XERMSG ('SLATEC', 'DCSEVL',
+     +   'X OUTSIDE THE INTERVAL (-1,+1)', 1, 1)
+C
+      B1 = 0.0D0
+      B0 = 0.0D0
+      TWOX = 2.0D0*X
+      DO 10 I = 1,N
+         B2 = B1
+         B1 = B0
+         NI = N + 1 - I
+         B0 = TWOX*B1 - B2 + CS(NI)
+   10 CONTINUE
+C
+      DCSEVL = 0.5D0*(B0-B2)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/derf.f b/libcruft/slatec-fn/derf.f
new file mode 100644
index 0000000..60d05fd
--- /dev/null
+++ b/libcruft/slatec-fn/derf.f
@@ -0,0 +1,83 @@
+*DECK DERF
+      DOUBLE PRECISION FUNCTION DERF (X)
+C***BEGIN PROLOGUE  DERF
+C***PURPOSE  Compute the error function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C8A, L5A1E
+C***TYPE      DOUBLE PRECISION (ERF-S, DERF-D)
+C***KEYWORDS  ERF, ERROR FUNCTION, FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DERF(X) calculates the double precision error function for double
+C precision argument X.
+C
+C Series for ERF        on the interval  0.          to  1.00000E+00
+C                                        with weighted error   1.28E-32
+C                                         log weighted error  31.89
+C                               significant figures required  31.05
+C                                    decimal places required  32.55
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DCSEVL, DERFC, INITDS
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900727  Added EXTERNAL statement.  (WRB)
+C   920618  Removed space from variable name.  (RWC, WRB)
+C***END PROLOGUE  DERF
+      DOUBLE PRECISION X, ERFCS(21), SQEPS, SQRTPI, XBIG, Y, D1MACH,
+     1  DCSEVL, DERFC
+      LOGICAL FIRST
+      EXTERNAL DERFC
+      SAVE ERFCS, SQRTPI, NTERF, XBIG, SQEPS, FIRST
+      DATA ERFCS(  1) / -.4904612123 4691808039 9845440333 76 D-1     /
+      DATA ERFCS(  2) / -.1422612051 0371364237 8247418996 31 D+0     /
+      DATA ERFCS(  3) / +.1003558218 7599795575 7546767129 33 D-1     /
+      DATA ERFCS(  4) / -.5768764699 7674847650 8270255091 67 D-3     /
+      DATA ERFCS(  5) / +.2741993125 2196061034 4221607914 71 D-4     /
+      DATA ERFCS(  6) / -.1104317550 7344507604 1353812959 05 D-5     /
+      DATA ERFCS(  7) / +.3848875542 0345036949 9613114981 74 D-7     /
+      DATA ERFCS(  8) / -.1180858253 3875466969 6317518015 81 D-8     /
+      DATA ERFCS(  9) / +.3233421582 6050909646 4029309533 54 D-10    /
+      DATA ERFCS( 10) / -.7991015947 0045487581 6073747085 95 D-12    /
+      DATA ERFCS( 11) / +.1799072511 3961455611 9672454866 34 D-13    /
+      DATA ERFCS( 12) / -.3718635487 8186926382 3168282094 93 D-15    /
+      DATA ERFCS( 13) / +.7103599003 7142529711 6899083946 66 D-17    /
+      DATA ERFCS( 14) / -.1261245511 9155225832 4954248533 33 D-18    /
+      DATA ERFCS( 15) / +.2091640694 1769294369 1705002666 66 D-20    /
+      DATA ERFCS( 16) / -.3253973102 9314072982 3641600000 00 D-22    /
+      DATA ERFCS( 17) / +.4766867209 7976748332 3733333333 33 D-24    /
+      DATA ERFCS( 18) / -.6598012078 2851343155 1999999999 99 D-26    /
+      DATA ERFCS( 19) / +.8655011469 9637626197 3333333333 33 D-28    /
+      DATA ERFCS( 20) / -.1078892517 7498064213 3333333333 33 D-29    /
+      DATA ERFCS( 21) / +.1281188399 3017002666 6666666666 66 D-31    /
+      DATA SQRTPI / 1.772453850 9055160272 9816748334 115D0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DERF
+      IF (FIRST) THEN
+         NTERF = INITDS (ERFCS, 21, 0.1*REAL(D1MACH(3)))
+         XBIG = SQRT(-LOG(SQRTPI*D1MACH(3)))
+         SQEPS = SQRT(2.0D0*D1MACH(3))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.1.D0) GO TO 20
+C
+C ERF(X) = 1.0 - ERFC(X)  FOR  -1.0 .LE. X .LE. 1.0
+C
+      IF (Y.LE.SQEPS) DERF = 2.0D0*X*X/SQRTPI
+      IF (Y.GT.SQEPS) DERF = X*(1.0D0 + DCSEVL (2.D0*X*X-1.D0,
+     1  ERFCS, NTERF))
+      RETURN
+C
+C ERF(X) = 1.0 - ERFC(X) FOR ABS(X) .GT. 1.0
+C
+ 20   IF (Y.LE.XBIG) DERF = SIGN (1.0D0-DERFC(Y), X)
+      IF (Y.GT.XBIG) DERF = SIGN (1.0D0, X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/derfc.f b/libcruft/slatec-fn/derfc.f
new file mode 100644
index 0000000..9d1326e
--- /dev/null
+++ b/libcruft/slatec-fn/derfc.f
@@ -0,0 +1,226 @@
+*DECK DERFC
+      DOUBLE PRECISION FUNCTION DERFC (X)
+C***BEGIN PROLOGUE  DERFC
+C***PURPOSE  Compute the complementary error function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C8A, L5A1E
+C***TYPE      DOUBLE PRECISION (ERFC-S, DERFC-D)
+C***KEYWORDS  COMPLEMENTARY ERROR FUNCTION, ERFC, FNLIB,
+C             SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DERFC(X) calculates the double precision complementary error function
+C for double precision argument X.
+C
+C Series for ERF        on the interval  0.          to  1.00000E+00
+C                                        with weighted Error   1.28E-32
+C                                         log weighted Error  31.89
+C                               significant figures required  31.05
+C                                    decimal places required  32.55
+C
+C Series for ERC2       on the interval  2.50000E-01 to  1.00000E+00
+C                                        with weighted Error   2.67E-32
+C                                         log weighted Error  31.57
+C                               significant figures required  30.31
+C                                    decimal places required  32.42
+C
+C Series for ERFC       on the interval  0.          to  2.50000E-01
+C                                        with weighted error   1.53E-31
+C                                         log weighted error  30.82
+C                               significant figures required  29.47
+C                                    decimal places required  31.70
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DCSEVL, INITDS, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920618  Removed space from variable names.  (RWC, WRB)
+C***END PROLOGUE  DERFC
+      DOUBLE PRECISION X, ERFCS(21), ERFCCS(59), ERC2CS(49), SQEPS,
+     1  SQRTPI, XMAX, TXMAX, XSML, Y, D1MACH, DCSEVL
+      LOGICAL FIRST
+      SAVE ERFCS, ERC2CS, ERFCCS, SQRTPI, NTERF,
+     1 NTERFC, NTERC2, XSML, XMAX, SQEPS, FIRST
+      DATA ERFCS(  1) / -.4904612123 4691808039 9845440333 76 D-1     /
+      DATA ERFCS(  2) / -.1422612051 0371364237 8247418996 31 D+0     /
+      DATA ERFCS(  3) / +.1003558218 7599795575 7546767129 33 D-1     /
+      DATA ERFCS(  4) / -.5768764699 7674847650 8270255091 67 D-3     /
+      DATA ERFCS(  5) / +.2741993125 2196061034 4221607914 71 D-4     /
+      DATA ERFCS(  6) / -.1104317550 7344507604 1353812959 05 D-5     /
+      DATA ERFCS(  7) / +.3848875542 0345036949 9613114981 74 D-7     /
+      DATA ERFCS(  8) / -.1180858253 3875466969 6317518015 81 D-8     /
+      DATA ERFCS(  9) / +.3233421582 6050909646 4029309533 54 D-10    /
+      DATA ERFCS( 10) / -.7991015947 0045487581 6073747085 95 D-12    /
+      DATA ERFCS( 11) / +.1799072511 3961455611 9672454866 34 D-13    /
+      DATA ERFCS( 12) / -.3718635487 8186926382 3168282094 93 D-15    /
+      DATA ERFCS( 13) / +.7103599003 7142529711 6899083946 66 D-17    /
+      DATA ERFCS( 14) / -.1261245511 9155225832 4954248533 33 D-18    /
+      DATA ERFCS( 15) / +.2091640694 1769294369 1705002666 66 D-20    /
+      DATA ERFCS( 16) / -.3253973102 9314072982 3641600000 00 D-22    /
+      DATA ERFCS( 17) / +.4766867209 7976748332 3733333333 33 D-24    /
+      DATA ERFCS( 18) / -.6598012078 2851343155 1999999999 99 D-26    /
+      DATA ERFCS( 19) / +.8655011469 9637626197 3333333333 33 D-28    /
+      DATA ERFCS( 20) / -.1078892517 7498064213 3333333333 33 D-29    /
+      DATA ERFCS( 21) / +.1281188399 3017002666 6666666666 66 D-31    /
+      DATA ERC2CS(  1) / -.6960134660 2309501127 3915082619 7 D-1      /
+      DATA ERC2CS(  2) / -.4110133936 2620893489 8221208466 6 D-1      /
+      DATA ERC2CS(  3) / +.3914495866 6896268815 6114370524 4 D-2      /
+      DATA ERC2CS(  4) / -.4906395650 5489791612 8093545077 4 D-3      /
+      DATA ERC2CS(  5) / +.7157479001 3770363807 6089414182 5 D-4      /
+      DATA ERC2CS(  6) / -.1153071634 1312328338 0823284791 2 D-4      /
+      DATA ERC2CS(  7) / +.1994670590 2019976350 5231486770 9 D-5      /
+      DATA ERC2CS(  8) / -.3642666471 5992228739 3611843071 1 D-6      /
+      DATA ERC2CS(  9) / +.6944372610 0050125899 3127721463 3 D-7      /
+      DATA ERC2CS( 10) / -.1371220902 1043660195 3460514121 0 D-7      /
+      DATA ERC2CS( 11) / +.2788389661 0071371319 6386034808 7 D-8      /
+      DATA ERC2CS( 12) / -.5814164724 3311615518 6479105031 6 D-9      /
+      DATA ERC2CS( 13) / +.1238920491 7527531811 8016881795 0 D-9      /
+      DATA ERC2CS( 14) / -.2690639145 3067434323 9042493788 9 D-10     /
+      DATA ERC2CS( 15) / +.5942614350 8479109824 4470968384 0 D-11     /
+      DATA ERC2CS( 16) / -.1332386735 7581195792 8775442057 0 D-11     /
+      DATA ERC2CS( 17) / +.3028046806 1771320171 7369724330 4 D-12     /
+      DATA ERC2CS( 18) / -.6966648814 9410325887 9586758895 4 D-13     /
+      DATA ERC2CS( 19) / +.1620854541 0539229698 1289322762 8 D-13     /
+      DATA ERC2CS( 20) / -.3809934465 2504919998 7691305772 9 D-14     /
+      DATA ERC2CS( 21) / +.9040487815 9788311493 6897101297 5 D-15     /
+      DATA ERC2CS( 22) / -.2164006195 0896073478 0981204700 3 D-15     /
+      DATA ERC2CS( 23) / +.5222102233 9958549846 0798024417 2 D-16     /
+      DATA ERC2CS( 24) / -.1269729602 3645553363 7241552778 0 D-16     /
+      DATA ERC2CS( 25) / +.3109145504 2761975838 3622741295 1 D-17     /
+      DATA ERC2CS( 26) / -.7663762920 3203855240 0956671481 1 D-18     /
+      DATA ERC2CS( 27) / +.1900819251 3627452025 3692973329 0 D-18     /
+      DATA ERC2CS( 28) / -.4742207279 0690395452 2565599996 5 D-19     /
+      DATA ERC2CS( 29) / +.1189649200 0765283828 8068307845 1 D-19     /
+      DATA ERC2CS( 30) / -.3000035590 3257802568 4527131306 6 D-20     /
+      DATA ERC2CS( 31) / +.7602993453 0432461730 1938527709 8 D-21     /
+      DATA ERC2CS( 32) / -.1935909447 6068728815 6981104913 0 D-21     /
+      DATA ERC2CS( 33) / +.4951399124 7733378810 0004238677 3 D-22     /
+      DATA ERC2CS( 34) / -.1271807481 3363718796 0862198988 8 D-22     /
+      DATA ERC2CS( 35) / +.3280049600 4695130433 1584165205 3 D-23     /
+      DATA ERC2CS( 36) / -.8492320176 8228965689 2479242239 9 D-24     /
+      DATA ERC2CS( 37) / +.2206917892 8075602235 1987998719 9 D-24     /
+      DATA ERC2CS( 38) / -.5755617245 6965284983 1281950719 9 D-25     /
+      DATA ERC2CS( 39) / +.1506191533 6392342503 5414405119 9 D-25     /
+      DATA ERC2CS( 40) / -.3954502959 0187969531 0428569599 9 D-26     /
+      DATA ERC2CS( 41) / +.1041529704 1515009799 8464505173 3 D-26     /
+      DATA ERC2CS( 42) / -.2751487795 2787650794 5017890133 3 D-27     /
+      DATA ERC2CS( 43) / +.7290058205 4975574089 9770368000 0 D-28     /
+      DATA ERC2CS( 44) / -.1936939645 9159478040 7750109866 6 D-28     /
+      DATA ERC2CS( 45) / +.5160357112 0514872983 7005482666 6 D-29     /
+      DATA ERC2CS( 46) / -.1378419322 1930940993 8964480000 0 D-29     /
+      DATA ERC2CS( 47) / +.3691326793 1070690422 5109333333 3 D-30     /
+      DATA ERC2CS( 48) / -.9909389590 6243654206 5322666666 6 D-31     /
+      DATA ERC2CS( 49) / +.2666491705 1953884133 2394666666 6 D-31     /
+      DATA ERFCCS(  1) / +.7151793102 0292477450 3697709496 D-1        /
+      DATA ERFCCS(  2) / -.2653243433 7606715755 8893386681 D-1        /
+      DATA ERFCCS(  3) / +.1711153977 9208558833 2699194606 D-2        /
+      DATA ERFCCS(  4) / -.1637516634 5851788416 3746404749 D-3        /
+      DATA ERFCCS(  5) / +.1987129350 0552036499 5974806758 D-4        /
+      DATA ERFCCS(  6) / -.2843712412 7665550875 0175183152 D-5        /
+      DATA ERFCCS(  7) / +.4606161308 9631303696 9379968464 D-6        /
+      DATA ERFCCS(  8) / -.8227753025 8792084205 7766536366 D-7        /
+      DATA ERFCCS(  9) / +.1592141872 7709011298 9358340826 D-7        /
+      DATA ERFCCS( 10) / -.3295071362 2528432148 6631665072 D-8        /
+      DATA ERFCCS( 11) / +.7223439760 4005554658 1261153890 D-9        /
+      DATA ERFCCS( 12) / -.1664855813 3987295934 4695966886 D-9        /
+      DATA ERFCCS( 13) / +.4010392588 2376648207 7671768814 D-10       /
+      DATA ERFCCS( 14) / -.1004816214 4257311327 2170176283 D-10       /
+      DATA ERFCCS( 15) / +.2608275913 3003338085 9341009439 D-11       /
+      DATA ERFCCS( 16) / -.6991110560 4040248655 7697812476 D-12       /
+      DATA ERFCCS( 17) / +.1929492333 2617070862 4205749803 D-12       /
+      DATA ERFCCS( 18) / -.5470131188 7543310649 0125085271 D-13       /
+      DATA ERFCCS( 19) / +.1589663309 7626974483 9084032762 D-13       /
+      DATA ERFCCS( 20) / -.4726893980 1975548392 0369584290 D-14       /
+      DATA ERFCCS( 21) / +.1435873376 7849847867 2873997840 D-14       /
+      DATA ERFCCS( 22) / -.4449510561 8173583941 7250062829 D-15       /
+      DATA ERFCCS( 23) / +.1404810884 7682334373 7305537466 D-15       /
+      DATA ERFCCS( 24) / -.4513818387 7642108962 5963281623 D-16       /
+      DATA ERFCCS( 25) / +.1474521541 0451330778 7018713262 D-16       /
+      DATA ERFCCS( 26) / -.4892621406 9457761543 6841552532 D-17       /
+      DATA ERFCCS( 27) / +.1647612141 4106467389 5301522827 D-17       /
+      DATA ERFCCS( 28) / -.5626817176 3294080929 9928521323 D-18       /
+      DATA ERFCCS( 29) / +.1947443382 2320785142 9197867821 D-18       /
+      DATA ERFCCS( 30) / -.6826305642 9484207295 6664144723 D-19       /
+      DATA ERFCCS( 31) / +.2421988887 2986492401 8301125438 D-19       /
+      DATA ERFCCS( 32) / -.8693414133 5030704256 3800861857 D-20       /
+      DATA ERFCCS( 33) / +.3155180346 2280855712 2363401262 D-20       /
+      DATA ERFCCS( 34) / -.1157372324 0496087426 1239486742 D-20       /
+      DATA ERFCCS( 35) / +.4288947161 6056539462 3737097442 D-21       /
+      DATA ERFCCS( 36) / -.1605030742 0576168500 5737770964 D-21       /
+      DATA ERFCCS( 37) / +.6063298757 4538026449 5069923027 D-22       /
+      DATA ERFCCS( 38) / -.2311404251 6979584909 8840801367 D-22       /
+      DATA ERFCCS( 39) / +.8888778540 6618855255 4702955697 D-23       /
+      DATA ERFCCS( 40) / -.3447260576 6513765223 0718495566 D-23       /
+      DATA ERFCCS( 41) / +.1347865460 2069650682 7582774181 D-23       /
+      DATA ERFCCS( 42) / -.5311794071 1250217364 5873201807 D-24       /
+      DATA ERFCCS( 43) / +.2109341058 6197831682 8954734537 D-24       /
+      DATA ERFCCS( 44) / -.8438365587 9237891159 8133256738 D-25       /
+      DATA ERFCCS( 45) / +.3399982524 9452089062 7359576337 D-25       /
+      DATA ERFCCS( 46) / -.1379452388 0732420900 2238377110 D-25       /
+      DATA ERFCCS( 47) / +.5634490311 8332526151 3392634811 D-26       /
+      DATA ERFCCS( 48) / -.2316490434 4770654482 3427752700 D-26       /
+      DATA ERFCCS( 49) / +.9584462844 6018101526 3158381226 D-27       /
+      DATA ERFCCS( 50) / -.3990722880 3301097262 4224850193 D-27       /
+      DATA ERFCCS( 51) / +.1672129225 9444773601 7228709669 D-27       /
+      DATA ERFCCS( 52) / -.7045991522 7660138563 8803782587 D-28       /
+      DATA ERFCCS( 53) / +.2979768402 8642063541 2357989444 D-28       /
+      DATA ERFCCS( 54) / -.1262522466 4606192972 2422632994 D-28       /
+      DATA ERFCCS( 55) / +.5395438704 5424879398 5299653154 D-29       /
+      DATA ERFCCS( 56) / -.2380992882 5314591867 5346190062 D-29       /
+      DATA ERFCCS( 57) / +.1099052830 1027615735 9726683750 D-29       /
+      DATA ERFCCS( 58) / -.4867713741 6449657273 2518677435 D-30       /
+      DATA ERFCCS( 59) / +.1525877264 1103575676 3200828211 D-30       /
+      DATA SQRTPI / 1.772453850 9055160272 9816748334 115D0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DERFC
+      IF (FIRST) THEN
+         ETA = 0.1*REAL(D1MACH(3))
+         NTERF = INITDS (ERFCS, 21, ETA)
+         NTERFC = INITDS (ERFCCS, 59, ETA)
+         NTERC2 = INITDS (ERC2CS, 49, ETA)
+C
+         XSML = -SQRT(-LOG(SQRTPI*D1MACH(3)))
+         TXMAX = SQRT(-LOG(SQRTPI*D1MACH(1)))
+         XMAX = TXMAX - 0.5D0*LOG(TXMAX)/TXMAX - 0.01D0
+         SQEPS = SQRT(2.0D0*D1MACH(3))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X.GT.XSML) GO TO 20
+C
+C ERFC(X) = 1.0 - ERF(X)  FOR  X .LT. XSML
+C
+      DERFC = 2.0D0
+      RETURN
+C
+ 20   IF (X.GT.XMAX) GO TO 40
+      Y = ABS(X)
+      IF (Y.GT.1.0D0) GO TO 30
+C
+C ERFC(X) = 1.0 - ERF(X)  FOR ABS(X) .LE. 1.0
+C
+      IF (Y.LT.SQEPS) DERFC = 1.0D0 - 2.0D0*X/SQRTPI
+      IF (Y.GE.SQEPS) DERFC = 1.0D0 - X*(1.0D0 + DCSEVL (2.D0*X*X-1.D0,
+     1  ERFCS, NTERF))
+      RETURN
+C
+C ERFC(X) = 1.0 - ERF(X)  FOR  1.0 .LT. ABS(X) .LE. XMAX
+C
+ 30   Y = Y*Y
+      IF (Y.LE.4.D0) DERFC = EXP(-Y)/ABS(X) * (0.5D0 + DCSEVL (
+     1  (8.D0/Y-5.D0)/3.D0, ERC2CS, NTERC2) )
+      IF (Y.GT.4.D0) DERFC = EXP(-Y)/ABS(X) * (0.5D0 + DCSEVL (
+     1  8.D0/Y-1.D0, ERFCCS, NTERFC) )
+      IF (X.LT.0.D0) DERFC = 2.0D0 - DERFC
+      RETURN
+C
+ 40   CALL XERMSG ('SLATEC', 'DERFC', 'X SO BIG ERFC UNDERFLOWS', 1, 1)
+      DERFC = 0.D0
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/dgami.f b/libcruft/slatec-fn/dgami.f
new file mode 100644
index 0000000..857aa7c
--- /dev/null
+++ b/libcruft/slatec-fn/dgami.f
@@ -0,0 +1,47 @@
+
+*DECK DGAMI
+      DOUBLE PRECISION FUNCTION DGAMI (A, X)
+C***BEGIN PROLOGUE  DGAMI
+C***PURPOSE  Evaluate the incomplete Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      DOUBLE PRECISION (GAMI-S, DGAMI-D)
+C***KEYWORDS  FNLIB, INCOMPLETE GAMMA FUNCTION, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Evaluate the incomplete gamma function defined by
+C
+C DGAMI = integral from T = 0 to X of EXP(-T) * T**(A-1.0) .
+C
+C DGAMI is evaluated for positive values of A and non-negative values
+C of X.  A slight deterioration of 2 or 3 digits accuracy will occur
+C when DGAMI is very large or very small, because logarithmic variables
+C are used.  The function and both arguments are double precision.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  DGAMIT, DLNGAM, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  DGAMI
+      DOUBLE PRECISION A, X, FACTOR, DLNGAM, DGAMIT
+C***FIRST EXECUTABLE STATEMENT  DGAMI
+      IF (A .LE. 0.D0) CALL XERMSG ('SLATEC', 'DGAMI',
+     +   'A MUST BE GT ZERO', 1, 2)
+      IF (X .LT. 0.D0) CALL XERMSG ('SLATEC', 'DGAMI',
+     +   'X MUST BE GE ZERO', 2, 2)
+C
+      DGAMI = 0.D0
+      IF (X.EQ.0.0D0) RETURN
+C
+C THE ONLY ERROR POSSIBLE IN THE EXPRESSION BELOW IS A FATAL OVERFLOW.
+      FACTOR = EXP (DLNGAM(A) + A*LOG(X))
+C
+      DGAMI = FACTOR * DGAMIT (A, X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dgamit.f b/libcruft/slatec-fn/dgamit.f
new file mode 100644
index 0000000..68c0092
--- /dev/null
+++ b/libcruft/slatec-fn/dgamit.f
@@ -0,0 +1,119 @@
+*DECK DGAMIT
+      DOUBLE PRECISION FUNCTION DGAMIT (A, X)
+C***BEGIN PROLOGUE  DGAMIT
+C***PURPOSE  Calculate Tricomi's form of the incomplete Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      DOUBLE PRECISION (GAMIT-S, DGAMIT-D)
+C***KEYWORDS  COMPLEMENTARY INCOMPLETE GAMMA FUNCTION, FNLIB,
+C             SPECIAL FUNCTIONS, TRICOMI
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C   Evaluate Tricomi's incomplete Gamma function defined by
+C
+C   DGAMIT = X**(-A)/GAMMA(A) * integral from 0 to X of EXP(-T) *
+C              T**(A-1.)
+C
+C   for A .GT. 0.0 and by analytic continuation for A .LE. 0.0.
+C   GAMMA(X) is the complete gamma function of X.
+C
+C   DGAMIT is evaluated for arbitrary real values of A and for non-
+C   negative values of X (even though DGAMIT is defined for X .LT.
+C   0.0), except that for X = 0 and A .LE. 0.0, DGAMIT is infinite,
+C   which is a fatal error.
+C
+C   The function and both arguments are DOUBLE PRECISION.
+C
+C   A slight deterioration of 2 or 3 digits accuracy will occur when
+C   DGAMIT is very large or very small in absolute value, because log-
+C   arithmic variables are used.  Also, if the parameter  A  is very
+C   close to a negative integer (but not a negative integer), there is
+C   a loss of accuracy, which is reported if the result is less than
+C   half machine precision.
+C
+C***REFERENCES  W. Gautschi, A computational procedure for incomplete
+C                 gamma functions, ACM Transactions on Mathematical
+C                 Software 5, 4 (December 1979), pp. 466-481.
+C               W. Gautschi, Incomplete gamma functions, Algorithm 542,
+C                 ACM Transactions on Mathematical Software 5, 4
+C                 (December 1979), pp. 482-489.
+C***ROUTINES CALLED  D1MACH, D9GMIT, D9LGIC, D9LGIT, DGAMR, DLGAMS,
+C                    DLNGAM, XERCLR, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920528  DESCRIPTION and REFERENCES sections revised.  (WRB)
+C***END PROLOGUE  DGAMIT
+      DOUBLE PRECISION A, X, AEPS, AINTA, ALGAP1, ALNEPS, ALNG, ALX,
+     1  BOT, H, SGA, SGNGAM, SQEPS, T, D1MACH, DGAMR, D9GMIT, D9LGIT,
+     2  DLNGAM, D9LGIC
+      LOGICAL FIRST
+      SAVE ALNEPS, SQEPS, BOT, FIRST
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DGAMIT
+      IF (FIRST) THEN
+         ALNEPS = -LOG (D1MACH(3))
+         SQEPS = SQRT(D1MACH(4))
+         BOT = LOG (D1MACH(1))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 0.D0) CALL XERMSG ('SLATEC', 'DGAMIT', 'X IS NEGATIVE'
+     +   , 2, 2)
+C
+      IF (X.NE.0.D0) ALX = LOG (X)
+      SGA = 1.0D0
+      IF (A.NE.0.D0) SGA = SIGN (1.0D0, A)
+      AINTA = AINT (A + 0.5D0*SGA)
+      AEPS = A - AINTA
+C
+      IF (X.GT.0.D0) GO TO 20
+      DGAMIT = 0.0D0
+      IF (AINTA.GT.0.D0 .OR. AEPS.NE.0.D0) DGAMIT = DGAMR(A+1.0D0)
+      RETURN
+C
+ 20   IF (X.GT.1.D0) GO TO 30
+      IF (A.GE.(-0.5D0) .OR. AEPS.NE.0.D0) CALL DLGAMS (A+1.0D0, ALGAP1,
+     1  SGNGAM)
+      DGAMIT = D9GMIT (A, X, ALGAP1, SGNGAM, ALX)
+      RETURN
+C
+ 30   IF (A.LT.X) GO TO 40
+      T = D9LGIT (A, X, DLNGAM(A+1.0D0))
+      IF (T.LT.BOT) CALL XERCLR
+      DGAMIT = EXP (T)
+      RETURN
+C
+ 40   ALNG = D9LGIC (A, X, ALX)
+C
+C EVALUATE DGAMIT IN TERMS OF LOG (DGAMIC (A, X))
+C
+      H = 1.0D0
+      IF (AEPS.EQ.0.D0 .AND. AINTA.LE.0.D0) GO TO 50
+C
+      CALL DLGAMS (A+1.0D0, ALGAP1, SGNGAM)
+      T = LOG (ABS(A)) + ALNG - ALGAP1
+      IF (T.GT.ALNEPS) GO TO 60
+C
+      IF (T.GT.(-ALNEPS)) H = 1.0D0 - SGA * SGNGAM * EXP(T)
+      IF (ABS(H).GT.SQEPS) GO TO 50
+C
+      CALL XERCLR
+      CALL XERMSG ('SLATEC', 'DGAMIT', 'RESULT LT HALF PRECISION', 1,
+     +   1)
+C
+ 50   T = -A*ALX + LOG(ABS(H))
+      IF (T.LT.BOT) CALL XERCLR
+      DGAMIT = SIGN (EXP(T), H)
+      RETURN
+C
+ 60   T = T - A*ALX
+      IF (T.LT.BOT) CALL XERCLR
+      DGAMIT = -SGA * SGNGAM * EXP(T)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/dgamlm.f b/libcruft/slatec-fn/dgamlm.f
new file mode 100644
index 0000000..7604c88
--- /dev/null
+++ b/libcruft/slatec-fn/dgamlm.f
@@ -0,0 +1,62 @@
+*DECK DGAMLM
+      SUBROUTINE DGAMLM (XMIN, XMAX)
+C***BEGIN PROLOGUE  DGAMLM
+C***PURPOSE  Compute the minimum and maximum bounds for the argument in
+C            the Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A, R2
+C***TYPE      DOUBLE PRECISION (GAMLIM-S, DGAMLM-D)
+C***KEYWORDS  COMPLETE GAMMA FUNCTION, FNLIB, LIMITS, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Calculate the minimum and maximum legal bounds for X in gamma(X).
+C XMIN and XMAX are not the only bounds, but they are the only non-
+C trivial ones to calculate.
+C
+C             Output Arguments --
+C XMIN   double precision minimum legal value of X in gamma(X).  Any
+C        smaller value of X might result in underflow.
+C XMAX   double precision maximum legal value of X in gamma(X).  Any
+C        larger value of X might cause overflow.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  DGAMLM
+      DOUBLE PRECISION XMIN, XMAX, ALNBIG, ALNSML, XLN, XOLD, D1MACH
+C***FIRST EXECUTABLE STATEMENT  DGAMLM
+      ALNSML = LOG(D1MACH(1))
+      XMIN = -ALNSML
+      DO 10 I=1,10
+        XOLD = XMIN
+        XLN = LOG(XMIN)
+        XMIN = XMIN - XMIN*((XMIN+0.5D0)*XLN - XMIN - 0.2258D0 + ALNSML)
+     1    / (XMIN*XLN+0.5D0)
+        IF (ABS(XMIN-XOLD).LT.0.005D0) GO TO 20
+ 10   CONTINUE
+      CALL XERMSG ('SLATEC', 'DGAMLM', 'UNABLE TO FIND XMIN', 1, 2)
+C
+ 20   XMIN = -XMIN + 0.01D0
+C
+      ALNBIG = LOG (D1MACH(2))
+      XMAX = ALNBIG
+      DO 30 I=1,10
+        XOLD = XMAX
+        XLN = LOG(XMAX)
+        XMAX = XMAX - XMAX*((XMAX-0.5D0)*XLN - XMAX + 0.9189D0 - ALNBIG)
+     1    / (XMAX*XLN-0.5D0)
+        IF (ABS(XMAX-XOLD).LT.0.005D0) GO TO 40
+ 30   CONTINUE
+      CALL XERMSG ('SLATEC', 'DGAMLM', 'UNABLE TO FIND XMAX', 2, 2)
+C
+ 40   XMAX = XMAX - 0.01D0
+      XMIN = MAX (XMIN, -XMAX+1.D0)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dgamma.f b/libcruft/slatec-fn/dgamma.f
new file mode 100644
index 0000000..7b2c183
--- /dev/null
+++ b/libcruft/slatec-fn/dgamma.f
@@ -0,0 +1,153 @@
+*DECK DGAMMA
+      DOUBLE PRECISION FUNCTION DGAMMA (X)
+C***BEGIN PROLOGUE  DGAMMA
+C***PURPOSE  Compute the complete Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      DOUBLE PRECISION (GAMMA-S, DGAMMA-D, CGAMMA-C)
+C***KEYWORDS  COMPLETE GAMMA FUNCTION, FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DGAMMA(X) calculates the double precision complete Gamma function
+C for double precision argument X.
+C
+C Series for GAM        on the interval  0.          to  1.00000E+00
+C                                        with weighted error   5.79E-32
+C                                         log weighted error  31.24
+C                               significant figures required  30.00
+C                                    decimal places required  32.05
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, D9LGMC, DCSEVL, DGAMLM, INITDS, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890911  Removed unnecessary intrinsics.  (WRB)
+C   890911  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920618  Removed space from variable name.  (RWC, WRB)
+C***END PROLOGUE  DGAMMA
+      DOUBLE PRECISION X, GAMCS(42), DXREL, PI, SINPIY, SQ2PIL, XMAX,
+     1  XMIN, Y, D9LGMC, DCSEVL, D1MACH
+      LOGICAL FIRST
+C
+      SAVE GAMCS, PI, SQ2PIL, NGAM, XMIN, XMAX, DXREL, FIRST
+      DATA GAMCS(  1) / +.8571195590 9893314219 2006239994 2 D-2      /
+      DATA GAMCS(  2) / +.4415381324 8410067571 9131577165 2 D-2      /
+      DATA GAMCS(  3) / +.5685043681 5993633786 3266458878 9 D-1      /
+      DATA GAMCS(  4) / -.4219835396 4185605010 1250018662 4 D-2      /
+      DATA GAMCS(  5) / +.1326808181 2124602205 8400679635 2 D-2      /
+      DATA GAMCS(  6) / -.1893024529 7988804325 2394702388 6 D-3      /
+      DATA GAMCS(  7) / +.3606925327 4412452565 7808221722 5 D-4      /
+      DATA GAMCS(  8) / -.6056761904 4608642184 8554829036 5 D-5      /
+      DATA GAMCS(  9) / +.1055829546 3022833447 3182350909 3 D-5      /
+      DATA GAMCS( 10) / -.1811967365 5423840482 9185589116 6 D-6      /
+      DATA GAMCS( 11) / +.3117724964 7153222777 9025459316 9 D-7      /
+      DATA GAMCS( 12) / -.5354219639 0196871408 7408102434 7 D-8      /
+      DATA GAMCS( 13) / +.9193275519 8595889468 8778682594 0 D-9      /
+      DATA GAMCS( 14) / -.1577941280 2883397617 6742327395 3 D-9      /
+      DATA GAMCS( 15) / +.2707980622 9349545432 6654043308 9 D-10     /
+      DATA GAMCS( 16) / -.4646818653 8257301440 8166105893 3 D-11     /
+      DATA GAMCS( 17) / +.7973350192 0074196564 6076717535 9 D-12     /
+      DATA GAMCS( 18) / -.1368078209 8309160257 9949917230 9 D-12     /
+      DATA GAMCS( 19) / +.2347319486 5638006572 3347177168 8 D-13     /
+      DATA GAMCS( 20) / -.4027432614 9490669327 6657053469 9 D-14     /
+      DATA GAMCS( 21) / +.6910051747 3721009121 3833697525 7 D-15     /
+      DATA GAMCS( 22) / -.1185584500 2219929070 5238712619 2 D-15     /
+      DATA GAMCS( 23) / +.2034148542 4963739552 0102605193 2 D-16     /
+      DATA GAMCS( 24) / -.3490054341 7174058492 7401294910 8 D-17     /
+      DATA GAMCS( 25) / +.5987993856 4853055671 3505106602 6 D-18     /
+      DATA GAMCS( 26) / -.1027378057 8722280744 9006977843 1 D-18     /
+      DATA GAMCS( 27) / +.1762702816 0605298249 4275966074 8 D-19     /
+      DATA GAMCS( 28) / -.3024320653 7353062609 5877211204 2 D-20     /
+      DATA GAMCS( 29) / +.5188914660 2183978397 1783355050 6 D-21     /
+      DATA GAMCS( 30) / -.8902770842 4565766924 4925160106 6 D-22     /
+      DATA GAMCS( 31) / +.1527474068 4933426022 7459689130 6 D-22     /
+      DATA GAMCS( 32) / -.2620731256 1873629002 5732833279 9 D-23     /
+      DATA GAMCS( 33) / +.4496464047 8305386703 3104657066 6 D-24     /
+      DATA GAMCS( 34) / -.7714712731 3368779117 0390152533 3 D-25     /
+      DATA GAMCS( 35) / +.1323635453 1260440364 8657271466 6 D-25     /
+      DATA GAMCS( 36) / -.2270999412 9429288167 0231381333 3 D-26     /
+      DATA GAMCS( 37) / +.3896418998 0039914493 2081663999 9 D-27     /
+      DATA GAMCS( 38) / -.6685198115 1259533277 9212799999 9 D-28     /
+      DATA GAMCS( 39) / +.1146998663 1400243843 4761386666 6 D-28     /
+      DATA GAMCS( 40) / -.1967938586 3451346772 9510399999 9 D-29     /
+      DATA GAMCS( 41) / +.3376448816 5853380903 3489066666 6 D-30     /
+      DATA GAMCS( 42) / -.5793070335 7821357846 2549333333 3 D-31     /
+      DATA PI / 3.1415926535 8979323846 2643383279 50 D0 /
+      DATA SQ2PIL / 0.9189385332 0467274178 0329736405 62 D0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DGAMMA
+      IF (FIRST) THEN
+         NGAM = INITDS (GAMCS, 42, 0.1*REAL(D1MACH(3)) )
+C
+         CALL DGAMLM (XMIN, XMAX)
+         DXREL = SQRT(D1MACH(4))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.10.D0) GO TO 50
+C
+C COMPUTE GAMMA(X) FOR -XBND .LE. X .LE. XBND.  REDUCE INTERVAL AND FIND
+C GAMMA(1+Y) FOR 0.0 .LE. Y .LT. 1.0 FIRST OF ALL.
+C
+      N = X
+      IF (X.LT.0.D0) N = N - 1
+      Y = X - N
+      N = N - 1
+      DGAMMA = 0.9375D0 + DCSEVL (2.D0*Y-1.D0, GAMCS, NGAM)
+      IF (N.EQ.0) RETURN
+C
+      IF (N.GT.0) GO TO 30
+C
+C COMPUTE GAMMA(X) FOR X .LT. 1.0
+C
+      N = -N
+      IF (X .EQ. 0.D0) CALL XERMSG ('SLATEC', 'DGAMMA', 'X IS 0', 4, 2)
+      IF (X .LT. 0.0 .AND. X+N-2 .EQ. 0.D0) CALL XERMSG ('SLATEC',
+     +   'DGAMMA', 'X IS A NEGATIVE INTEGER', 4, 2)
+      IF (X .LT. (-0.5D0) .AND. ABS((X-AINT(X-0.5D0))/X) .LT. DXREL)
+     +   CALL XERMSG ('SLATEC', 'DGAMMA',
+     +   'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR NEGATIVE INTEGER',
+     +   1, 1)
+C
+      DO 20 I=1,N
+        DGAMMA = DGAMMA/(X+I-1 )
+ 20   CONTINUE
+      RETURN
+C
+C GAMMA(X) FOR X .GE. 2.0 AND X .LE. 10.0
+C
+ 30   DO 40 I=1,N
+        DGAMMA = (Y+I) * DGAMMA
+ 40   CONTINUE
+      RETURN
+C
+C GAMMA(X) FOR ABS(X) .GT. 10.0.  RECALL Y = ABS(X).
+C
+ 50   IF (X .GT. XMAX) CALL XERMSG ('SLATEC', 'DGAMMA',
+     +   'X SO BIG GAMMA OVERFLOWS', 3, 2)
+C
+      DGAMMA = 0.D0
+      IF (X .LT. XMIN) CALL XERMSG ('SLATEC', 'DGAMMA',
+     +   'X SO SMALL GAMMA UNDERFLOWS', 2, 1)
+      IF (X.LT.XMIN) RETURN
+C
+      DGAMMA = EXP ((Y-0.5D0)*LOG(Y) - Y + SQ2PIL + D9LGMC(Y) )
+      IF (X.GT.0.D0) RETURN
+C
+      IF (ABS((X-AINT(X-0.5D0))/X) .LT. DXREL) CALL XERMSG ('SLATEC',
+     +   'DGAMMA',
+     +   'ANSWER LT HALF PRECISION, X TOO NEAR NEGATIVE INTEGER', 1, 1)
+C
+      SINPIY = SIN (PI*Y)
+      IF (SINPIY .EQ. 0.D0) CALL XERMSG ('SLATEC', 'DGAMMA',
+     +   'X IS A NEGATIVE INTEGER', 4, 2)
+C
+      DGAMMA = -PI/(Y*SINPIY*DGAMMA)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dgamr.f b/libcruft/slatec-fn/dgamr.f
new file mode 100644
index 0000000..9572a33
--- /dev/null
+++ b/libcruft/slatec-fn/dgamr.f
@@ -0,0 +1,44 @@
+*DECK DGAMR
+      DOUBLE PRECISION FUNCTION DGAMR (X)
+C***BEGIN PROLOGUE  DGAMR
+C***PURPOSE  Compute the reciprocal of the Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      DOUBLE PRECISION (GAMR-S, DGAMR-D, CGAMR-C)
+C***KEYWORDS  FNLIB, RECIPROCAL GAMMA FUNCTION, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DGAMR(X) calculates the double precision reciprocal of the
+C complete Gamma function for double precision argument X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  DGAMMA, DLGAMS, XERCLR, XGETF, XSETF
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900727  Added EXTERNAL statement.  (WRB)
+C***END PROLOGUE  DGAMR
+      DOUBLE PRECISION X, ALNGX, SGNGX, DGAMMA
+      EXTERNAL DGAMMA
+C***FIRST EXECUTABLE STATEMENT  DGAMR
+      DGAMR = 0.0D0
+      IF (X.LE.0.0D0 .AND. AINT(X).EQ.X) RETURN
+C
+      CALL XGETF (IROLD)
+      CALL XSETF (1)
+      IF (ABS(X).GT.10.0D0) GO TO 10
+      DGAMR = 1.0D0/DGAMMA(X)
+      CALL XERCLR
+      CALL XSETF (IROLD)
+      RETURN
+C
+ 10   CALL DLGAMS (X, ALNGX, SGNGX)
+      CALL XERCLR
+      CALL XSETF (IROLD)
+      DGAMR = SGNGX * EXP(-ALNGX)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/dlbeta.f b/libcruft/slatec-fn/dlbeta.f
new file mode 100644
index 0000000..f5b0853
--- /dev/null
+++ b/libcruft/slatec-fn/dlbeta.f
@@ -0,0 +1,62 @@
+*DECK DLBETA
+      DOUBLE PRECISION FUNCTION DLBETA (A, B)
+C***BEGIN PROLOGUE  DLBETA
+C***PURPOSE  Compute the natural logarithm of the complete Beta
+C            function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7B
+C***TYPE      DOUBLE PRECISION (ALBETA-S, DLBETA-D, CLBETA-C)
+C***KEYWORDS  FNLIB, LOGARITHM OF THE COMPLETE BETA FUNCTION,
+C             SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DLBETA(A,B) calculates the double precision natural logarithm of
+C the complete beta function for double precision arguments
+C A and B.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D9LGMC, DGAMMA, DLNGAM, DLNREL, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900727  Added EXTERNAL statement.  (WRB)
+C***END PROLOGUE  DLBETA
+      DOUBLE PRECISION A, B, P, Q, CORR, SQ2PIL, D9LGMC, DGAMMA, DLNGAM,
+     1  DLNREL
+      EXTERNAL DGAMMA
+      SAVE SQ2PIL
+      DATA SQ2PIL / 0.9189385332 0467274178 0329736405 62 D0 /
+C***FIRST EXECUTABLE STATEMENT  DLBETA
+      P = MIN (A, B)
+      Q = MAX (A, B)
+C
+      IF (P .LE. 0.D0) CALL XERMSG ('SLATEC', 'DLBETA',
+     +   'BOTH ARGUMENTS MUST BE GT ZERO', 1, 2)
+C
+      IF (P.GE.10.D0) GO TO 30
+      IF (Q.GE.10.D0) GO TO 20
+C
+C P AND Q ARE SMALL.
+C
+      DLBETA = LOG (DGAMMA(P) * (DGAMMA(Q)/DGAMMA(P+Q)) )
+      RETURN
+C
+C P IS SMALL, BUT Q IS BIG.
+C
+ 20   CORR = D9LGMC(Q) - D9LGMC(P+Q)
+      DLBETA = DLNGAM(P) + CORR + P - P*LOG(P+Q)
+     1  + (Q-0.5D0)*DLNREL(-P/(P+Q))
+      RETURN
+C
+C P AND Q ARE BIG.
+C
+ 30   CORR = D9LGMC(P) + D9LGMC(Q) - D9LGMC(P+Q)
+      DLBETA = -0.5D0*LOG(Q) + SQ2PIL + CORR + (P-0.5D0)*LOG(P/(P+Q))
+     1  + Q*DLNREL(-P/(P+Q))
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/dlgams.f b/libcruft/slatec-fn/dlgams.f
new file mode 100644
index 0000000..c14828a
--- /dev/null
+++ b/libcruft/slatec-fn/dlgams.f
@@ -0,0 +1,37 @@
+*DECK DLGAMS
+      SUBROUTINE DLGAMS (X, DLGAM, SGNGAM)
+C***BEGIN PROLOGUE  DLGAMS
+C***PURPOSE  Compute the logarithm of the absolute value of the Gamma
+C            function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      DOUBLE PRECISION (ALGAMS-S, DLGAMS-D)
+C***KEYWORDS  ABSOLUTE VALUE OF THE LOGARITHM OF THE GAMMA FUNCTION,
+C             FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DLGAMS(X,DLGAM,SGNGAM) calculates the double precision natural
+C logarithm of the absolute value of the Gamma function for
+C double precision argument X and stores the result in double
+C precision argument DLGAM.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  DLNGAM
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C***END PROLOGUE  DLGAMS
+      DOUBLE PRECISION X, DLGAM, SGNGAM, DLNGAM
+C***FIRST EXECUTABLE STATEMENT  DLGAMS
+      DLGAM = DLNGAM(X)
+      SGNGAM = 1.0D0
+      IF (X.GT.0.D0) RETURN
+C
+      INT = MOD (-AINT(X), 2.0D0) + 0.1D0
+      IF (INT.EQ.0) SGNGAM = -1.0D0
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dlngam.f b/libcruft/slatec-fn/dlngam.f
new file mode 100644
index 0000000..3755450
--- /dev/null
+++ b/libcruft/slatec-fn/dlngam.f
@@ -0,0 +1,73 @@
+*DECK DLNGAM
+      DOUBLE PRECISION FUNCTION DLNGAM (X)
+C***BEGIN PROLOGUE  DLNGAM
+C***PURPOSE  Compute the logarithm of the absolute value of the Gamma
+C            function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      DOUBLE PRECISION (ALNGAM-S, DLNGAM-D, CLNGAM-C)
+C***KEYWORDS  ABSOLUTE VALUE, COMPLETE GAMMA FUNCTION, FNLIB, LOGARITHM,
+C             SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DLNGAM(X) calculates the double precision logarithm of the
+C absolute value of the Gamma function for double precision
+C argument X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, D9LGMC, DGAMMA, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900727  Added EXTERNAL statement.  (WRB)
+C***END PROLOGUE  DLNGAM
+      DOUBLE PRECISION X, DXREL, PI, SINPIY, SQPI2L, SQ2PIL, XMAX,
+     1  Y, DGAMMA, D9LGMC, D1MACH, TEMP
+      LOGICAL FIRST
+      EXTERNAL DGAMMA
+      SAVE SQ2PIL, SQPI2L, PI, XMAX, DXREL, FIRST
+      DATA SQ2PIL / 0.9189385332 0467274178 0329736405 62 D0 /
+      DATA SQPI2L / +.2257913526 4472743236 3097614947 441 D+0    /
+      DATA PI / 3.1415926535 8979323846 2643383279 50 D0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DLNGAM
+      IF (FIRST) THEN
+         TEMP = 1.D0/LOG(D1MACH(2))
+         XMAX = TEMP*D1MACH(2)
+         DXREL = SQRT(D1MACH(4))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS (X)
+      IF (Y.GT.10.D0) GO TO 20
+C
+C LOG (ABS (DGAMMA(X)) ) FOR ABS(X) .LE. 10.0
+C
+      DLNGAM = LOG (ABS (DGAMMA(X)) )
+      RETURN
+C
+C LOG ( ABS (DGAMMA(X)) ) FOR ABS(X) .GT. 10.0
+C
+ 20   IF (Y .GT. XMAX) CALL XERMSG ('SLATEC', 'DLNGAM',
+     +   'ABS(X) SO BIG DLNGAM OVERFLOWS', 2, 2)
+C
+      IF (X.GT.0.D0) DLNGAM = SQ2PIL + (X-0.5D0)*LOG(X) - X + D9LGMC(Y)
+      IF (X.GT.0.D0) RETURN
+C
+      SINPIY = ABS (SIN(PI*Y))
+      IF (SINPIY .EQ. 0.D0) CALL XERMSG ('SLATEC', 'DLNGAM',
+     +   'X IS A NEGATIVE INTEGER', 3, 2)
+C
+      IF (ABS((X-AINT(X-0.5D0))/X) .LT. DXREL) CALL XERMSG ('SLATEC',
+     +   'DLNGAM',
+     +   'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR NEGATIVE INTEGER',
+     +   1, 1)
+C
+      DLNGAM = SQPI2L + (X-0.5D0)*LOG(Y) - X - LOG(SINPIY) - D9LGMC(Y)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/dlnrel.f b/libcruft/slatec-fn/dlnrel.f
new file mode 100644
index 0000000..403232d
--- /dev/null
+++ b/libcruft/slatec-fn/dlnrel.f
@@ -0,0 +1,98 @@
+*DECK DLNREL
+      DOUBLE PRECISION FUNCTION DLNREL (X)
+C***BEGIN PROLOGUE  DLNREL
+C***PURPOSE  Evaluate ln(1+X) accurate in the sense of relative error.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C4B
+C***TYPE      DOUBLE PRECISION (ALNREL-S, DLNREL-D, CLNREL-C)
+C***KEYWORDS  ELEMENTARY FUNCTIONS, FNLIB, LOGARITHM
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C DLNREL(X) calculates the double precision natural logarithm of
+C (1.0+X) for double precision argument X.  This routine should
+C be used when X is small and accurate to calculate the logarithm
+C accurately (in the relative error sense) in the neighborhood
+C of 1.0.
+C
+C Series for ALNR       on the interval -3.75000E-01 to  3.75000E-01
+C                                        with weighted error   6.35E-32
+C                                         log weighted error  31.20
+C                               significant figures required  30.93
+C                                    decimal places required  32.01
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  D1MACH, DCSEVL, INITDS, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  DLNREL
+      DOUBLE PRECISION ALNRCS(43), X, XMIN,  DCSEVL, D1MACH
+      LOGICAL FIRST
+      SAVE ALNRCS, NLNREL, XMIN, FIRST
+      DATA ALNRCS(  1) / +.1037869356 2743769800 6862677190 98 D+1     /
+      DATA ALNRCS(  2) / -.1336430150 4908918098 7660415531 33 D+0     /
+      DATA ALNRCS(  3) / +.1940824913 5520563357 9261993747 50 D-1     /
+      DATA ALNRCS(  4) / -.3010755112 7535777690 3765377765 92 D-2     /
+      DATA ALNRCS(  5) / +.4869461479 7154850090 4563665091 37 D-3     /
+      DATA ALNRCS(  6) / -.8105488189 3175356066 8099430086 22 D-4     /
+      DATA ALNRCS(  7) / +.1377884779 9559524782 9382514960 59 D-4     /
+      DATA ALNRCS(  8) / -.2380221089 4358970251 3699929149 35 D-5     /
+      DATA ALNRCS(  9) / +.4164041621 3865183476 3918599019 89 D-6     /
+      DATA ALNRCS( 10) / -.7359582837 8075994984 2668370319 98 D-7     /
+      DATA ALNRCS( 11) / +.1311761187 6241674949 1522943450 11 D-7     /
+      DATA ALNRCS( 12) / -.2354670931 7742425136 6960923301 75 D-8     /
+      DATA ALNRCS( 13) / +.4252277327 6034997775 6380529625 67 D-9     /
+      DATA ALNRCS( 14) / -.7719089413 4840796826 1081074933 00 D-10    /
+      DATA ALNRCS( 15) / +.1407574648 1359069909 2153564721 91 D-10    /
+      DATA ALNRCS( 16) / -.2576907205 8024680627 5370786275 84 D-11    /
+      DATA ALNRCS( 17) / +.4734240666 6294421849 1543950059 38 D-12    /
+      DATA ALNRCS( 18) / -.8724901267 4742641745 3012632926 75 D-13    /
+      DATA ALNRCS( 19) / +.1612461490 2740551465 7398331191 15 D-13    /
+      DATA ALNRCS( 20) / -.2987565201 5665773006 7107924168 15 D-14    /
+      DATA ALNRCS( 21) / +.5548070120 9082887983 0413216972 79 D-15    /
+      DATA ALNRCS( 22) / -.1032461915 8271569595 1413339619 32 D-15    /
+      DATA ALNRCS( 23) / +.1925023920 3049851177 8785032448 68 D-16    /
+      DATA ALNRCS( 24) / -.3595507346 5265150011 1897078442 66 D-17    /
+      DATA ALNRCS( 25) / +.6726454253 7876857892 1945742267 73 D-18    /
+      DATA ALNRCS( 26) / -.1260262416 8735219252 0824256375 46 D-18    /
+      DATA ALNRCS( 27) / +.2364488440 8606210044 9161589555 19 D-19    /
+      DATA ALNRCS( 28) / -.4441937705 0807936898 8783891797 33 D-20    /
+      DATA ALNRCS( 29) / +.8354659446 4034259016 2412939946 66 D-21    /
+      DATA ALNRCS( 30) / -.1573155941 6479562574 8992535210 66 D-21    /
+      DATA ALNRCS( 31) / +.2965312874 0247422686 1543697066 66 D-22    /
+      DATA ALNRCS( 32) / -.5594958348 1815947292 1560132266 66 D-23    /
+      DATA ALNRCS( 33) / +.1056635426 8835681048 1872841386 66 D-23    /
+      DATA ALNRCS( 34) / -.1997248368 0670204548 3149994666 66 D-24    /
+      DATA ALNRCS( 35) / +.3778297781 8839361421 0498559999 99 D-25    /
+      DATA ALNRCS( 36) / -.7153158688 9081740345 0381653333 33 D-26    /
+      DATA ALNRCS( 37) / +.1355248846 3674213646 5020245333 33 D-26    /
+      DATA ALNRCS( 38) / -.2569467304 8487567430 0798293333 33 D-27    /
+      DATA ALNRCS( 39) / +.4874775606 6216949076 4595199999 99 D-28    /
+      DATA ALNRCS( 40) / -.9254211253 0849715321 1323733333 33 D-29    /
+      DATA ALNRCS( 41) / +.1757859784 1760239233 2697600000 00 D-29    /
+      DATA ALNRCS( 42) / -.3341002667 7731010351 3770666666 66 D-30    /
+      DATA ALNRCS( 43) / +.6353393618 0236187354 1802666666 66 D-31    /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  DLNREL
+      IF (FIRST) THEN
+         NLNREL = INITDS (ALNRCS, 43, 0.1*REAL(D1MACH(3)))
+         XMIN = -1.0D0 + SQRT(D1MACH(4))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LE. (-1.D0)) CALL XERMSG ('SLATEC', 'DLNREL', 'X IS LE -1'
+     +   , 2, 2)
+      IF (X .LT. XMIN) CALL XERMSG ('SLATEC', 'DLNREL',
+     +   'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR -1', 1, 1)
+C
+      IF (ABS(X).LE.0.375D0) DLNREL = X*(1.D0 -
+     1  X*DCSEVL (X/.375D0, ALNRCS, NLNREL))
+C
+      IF (ABS(X).GT.0.375D0) DLNREL = LOG (1.0D0+X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/dpchim.f b/libcruft/slatec-fn/dpchim.f
new file mode 100644
index 0000000..d8f08a2
--- /dev/null
+++ b/libcruft/slatec-fn/dpchim.f
@@ -0,0 +1,285 @@
+*DECK DPCHIM
+      SUBROUTINE DPCHIM (N, X, F, D, INCFD, IERR)
+C***BEGIN PROLOGUE  DPCHIM
+C***PURPOSE  Set derivatives needed to determine a monotone piecewise
+C            cubic Hermite interpolant to given data.  Boundary values
+C            are provided which are compatible with monotonicity.  The
+C            interpolant will have an extremum at each point where mono-
+C            tonicity switches direction.  (See DPCHIC if user control
+C            is desired over boundary or switch conditions.)
+C***LIBRARY   SLATEC (PCHIP)
+C***CATEGORY  E1A
+C***TYPE      DOUBLE PRECISION (PCHIM-S, DPCHIM-D)
+C***KEYWORDS  CUBIC HERMITE INTERPOLATION, MONOTONE INTERPOLATION,
+C             PCHIP, PIECEWISE CUBIC INTERPOLATION
+C***AUTHOR  Fritsch, F. N., (LLNL)
+C             Lawrence Livermore National Laboratory
+C             P.O. Box 808  (L-316)
+C             Livermore, CA  94550
+C             FTS 532-4275, (510) 422-4275
+C***DESCRIPTION
+C
+C          DPCHIM:  Piecewise Cubic Hermite Interpolation to
+C                  Monotone data.
+C
+C     Sets derivatives needed to determine a monotone piecewise cubic
+C     Hermite interpolant to the data given in X and F.
+C
+C     Default boundary conditions are provided which are compatible
+C     with monotonicity.  (See DPCHIC if user control of boundary con-
+C     ditions is desired.)
+C
+C     If the data are only piecewise monotonic, the interpolant will
+C     have an extremum at each point where monotonicity switches direc-
+C     tion.  (See DPCHIC if user control is desired in such cases.)
+C
+C     To facilitate two-dimensional applications, includes an increment
+C     between successive values of the F- and D-arrays.
+C
+C     The resulting piecewise cubic Hermite function may be evaluated
+C     by DPCHFE or DPCHFD.
+C
+C ----------------------------------------------------------------------
+C
+C  Calling sequence:
+C
+C        PARAMETER  (INCFD = ...)
+C        INTEGER  N, IERR
+C        DOUBLE PRECISION  X(N), F(INCFD,N), D(INCFD,N)
+C
+C        CALL  DPCHIM (N, X, F, D, INCFD, IERR)
+C
+C   Parameters:
+C
+C     N -- (input) number of data points.  (Error return if N.LT.2 .)
+C           If N=2, simply does linear interpolation.
+C
+C     X -- (input) real*8 array of independent variable values.  The
+C           elements of X must be strictly increasing:
+C                X(I-1) .LT. X(I),  I = 2(1)N.
+C           (Error return if not.)
+C
+C     F -- (input) real*8 array of dependent variable values to be
+C           interpolated.  F(1+(I-1)*INCFD) is value corresponding to
+C           X(I).  DPCHIM is designed for monotonic data, but it will
+C           work for any F-array.  It will force extrema at points where
+C           monotonicity switches direction.  If some other treatment of
+C           switch points is desired, DPCHIC should be used instead.
+C                                     -----
+C     D -- (output) real*8 array of derivative values at the data
+C           points.  If the data are monotonic, these values will
+C           determine a monotone cubic Hermite function.
+C           The value corresponding to X(I) is stored in
+C                D(1+(I-1)*INCFD),  I=1(1)N.
+C           No other entries in D are changed.
+C
+C     INCFD -- (input) increment between successive values in F and D.
+C           This argument is provided primarily for 2-D applications.
+C           (Error return if  INCFD.LT.1 .)
+C
+C     IERR -- (output) error flag.
+C           Normal return:
+C              IERR = 0  (no errors).
+C           Warning error:
+C              IERR.GT.0  means that IERR switches in the direction
+C                 of monotonicity were detected.
+C           "Recoverable" errors:
+C              IERR = -1  if N.LT.2 .
+C              IERR = -2  if INCFD.LT.1 .
+C              IERR = -3  if the X-array is not strictly increasing.
+C             (The D-array has not been changed in any of these cases.)
+C               NOTE:  The above errors are checked in the order listed,
+C                   and following arguments have **NOT** been validated.
+C
+C***REFERENCES  1. F. N. Fritsch and J. Butland, A method for construc-
+C                 ting local monotone piecewise cubic interpolants, SIAM
+C                 Journal on Scientific and Statistical Computing 5, 2
+C                 (June 1984), pp. 300-304.
+C               2. F. N. Fritsch and R. E. Carlson, Monotone piecewise
+C                 cubic interpolation, SIAM Journal on Numerical Ana-
+C                 lysis 17, 2 (April 1980), pp. 238-246.
+C***ROUTINES CALLED  DPCHST, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   811103  DATE WRITTEN
+C   820201  1. Introduced  DPCHST  to reduce possible over/under-
+C             flow problems.
+C           2. Rearranged derivative formula for same reason.
+C   820602  1. Modified end conditions to be continuous functions
+C             of data when monotonicity switches in next interval.
+C           2. Modified formulas so end conditions are less prone
+C             of over/underflow problems.
+C   820803  Minor cosmetic changes for release 1.
+C   870707  Corrected XERROR calls for d.p. name(s).
+C   870813  Updated Reference 1.
+C   890206  Corrected XERROR calls.
+C   890411  Added SAVE statements (Vers. 3.2).
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890703  Corrected category record.  (WRB)
+C   890831  Modified array declarations.  (WRB)
+C   891006  Cosmetic changes to prologue.  (WRB)
+C   891006  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920429  Revised format and order of references.  (WRB,FNF)
+C***END PROLOGUE  DPCHIM
+C  Programming notes:
+C
+C     1. The function  DPCHST(ARG1,ARG2)  is assumed to return zero if
+C        either argument is zero, +1 if they are of the same sign, and
+C        -1 if they are of opposite sign.
+C     2. To produce a single precision version, simply:
+C        a. Change DPCHIM to PCHIM wherever it occurs,
+C        b. Change DPCHST to PCHST wherever it occurs,
+C        c. Change all references to the Fortran intrinsics to their
+C           single precision equivalents,
+C        d. Change the double precision declarations to real, and
+C        e. Change the constants ZERO and THREE to single precision.
+C
+C  DECLARE ARGUMENTS.
+C
+      INTEGER  N, INCFD, IERR
+      DOUBLE PRECISION  X(*), F(INCFD,*), D(INCFD,*)
+C
+C  DECLARE LOCAL VARIABLES.
+C
+      INTEGER  I, NLESS1
+      DOUBLE PRECISION  DEL1, DEL2, DMAX, DMIN, DRAT1, DRAT2, DSAVE,
+     *      H1, H2, HSUM, HSUMT3, THREE, W1, W2, ZERO
+      SAVE ZERO, THREE
+      DOUBLE PRECISION  DPCHST
+      DATA  ZERO /0.D0/, THREE/3.D0/
+C
+C  VALIDITY-CHECK ARGUMENTS.
+C
+C***FIRST EXECUTABLE STATEMENT  DPCHIM
+      IF ( N.LT.2 )  GO TO 5001
+      IF ( INCFD.LT.1 )  GO TO 5002
+      DO 1  I = 2, N
+         IF ( X(I).LE.X(I-1) )  GO TO 5003
+    1 CONTINUE
+C
+C  FUNCTION DEFINITION IS OK, GO ON.
+C
+      IERR = 0
+      NLESS1 = N - 1
+      H1 = X(2) - X(1)
+      DEL1 = (F(1,2) - F(1,1))/H1
+      DSAVE = DEL1
+C
+C  SPECIAL CASE N=2 -- USE LINEAR INTERPOLATION.
+C
+      IF (NLESS1 .GT. 1)  GO TO 10
+      D(1,1) = DEL1
+      D(1,N) = DEL1
+      GO TO 5000
+C
+C  NORMAL CASE  (N .GE. 3).
+C
+   10 CONTINUE
+      H2 = X(3) - X(2)
+      DEL2 = (F(1,3) - F(1,2))/H2
+C
+C  SET D(1) VIA NON-CENTERED THREE-POINT FORMULA, ADJUSTED TO BE
+C     SHAPE-PRESERVING.
+C
+      HSUM = H1 + H2
+      W1 = (H1 + HSUM)/HSUM
+      W2 = -H1/HSUM
+      D(1,1) = W1*DEL1 + W2*DEL2
+      IF ( DPCHST(D(1,1),DEL1) .LE. ZERO)  THEN
+         D(1,1) = ZERO
+      ELSE IF ( DPCHST(DEL1,DEL2) .LT. ZERO)  THEN
+C        NEED DO THIS CHECK ONLY IF MONOTONICITY SWITCHES.
+         DMAX = THREE*DEL1
+         IF (ABS(D(1,1)) .GT. ABS(DMAX))  D(1,1) = DMAX
+      ENDIF
+C
+C  LOOP THROUGH INTERIOR POINTS.
+C
+      DO 50  I = 2, NLESS1
+         IF (I .EQ. 2)  GO TO 40
+C
+         H1 = H2
+         H2 = X(I+1) - X(I)
+         HSUM = H1 + H2
+         DEL1 = DEL2
+         DEL2 = (F(1,I+1) - F(1,I))/H2
+   40    CONTINUE
+C
+C        SET D(I)=0 UNLESS DATA ARE STRICTLY MONOTONIC.
+C
+         D(1,I) = ZERO
+         IF ( DPCHST(DEL1,DEL2) .LT. 0.)  GO TO 42
+         IF ( DPCHST(DEL1,DEL2) .EQ. 0.)  GO TO 41
+         GO TO 45
+C
+C        COUNT NUMBER OF CHANGES IN DIRECTION OF MONOTONICITY.
+C
+   41    CONTINUE
+         IF (DEL2 .EQ. ZERO)  GO TO 50
+         IF ( DPCHST(DSAVE,DEL2) .LT. ZERO)  IERR = IERR + 1
+         DSAVE = DEL2
+         GO TO 50
+C
+   42    CONTINUE
+         IERR = IERR + 1
+         DSAVE = DEL2
+         GO TO 50
+C
+C        USE BRODLIE MODIFICATION OF BUTLAND FORMULA.
+C
+   45    CONTINUE
+         HSUMT3 = HSUM+HSUM+HSUM
+         W1 = (HSUM + H1)/HSUMT3
+         W2 = (HSUM + H2)/HSUMT3
+         DMAX = MAX( ABS(DEL1), ABS(DEL2) )
+         DMIN = MIN( ABS(DEL1), ABS(DEL2) )
+         DRAT1 = DEL1/DMAX
+         DRAT2 = DEL2/DMAX
+         D(1,I) = DMIN/(W1*DRAT1 + W2*DRAT2)
+C
+   50 CONTINUE
+C
+C  SET D(N) VIA NON-CENTERED THREE-POINT FORMULA, ADJUSTED TO BE
+C     SHAPE-PRESERVING.
+C
+      W1 = -H2/HSUM
+      W2 = (H2 + HSUM)/HSUM
+      D(1,N) = W1*DEL1 + W2*DEL2
+      IF ( DPCHST(D(1,N),DEL2) .LE. ZERO)  THEN
+         D(1,N) = ZERO
+      ELSE IF ( DPCHST(DEL1,DEL2) .LT. ZERO)  THEN
+C        NEED DO THIS CHECK ONLY IF MONOTONICITY SWITCHES.
+         DMAX = THREE*DEL2
+         IF (ABS(D(1,N)) .GT. ABS(DMAX))  D(1,N) = DMAX
+      ENDIF
+C
+C  NORMAL RETURN.
+C
+ 5000 CONTINUE
+      RETURN
+C
+C  ERROR RETURNS.
+C
+ 5001 CONTINUE
+C     N.LT.2 RETURN.
+      IERR = -1
+      CALL XERMSG ('SLATEC', 'DPCHIM',
+     +   'NUMBER OF DATA POINTS LESS THAN TWO', IERR, 1)
+      RETURN
+C
+ 5002 CONTINUE
+C     INCFD.LT.1 RETURN.
+      IERR = -2
+      CALL XERMSG ('SLATEC', 'DPCHIM', 'INCREMENT LESS THAN ONE', IERR,
+     +   1)
+      RETURN
+C
+ 5003 CONTINUE
+C     X-ARRAY NOT STRICTLY INCREASING.
+      IERR = -3
+      CALL XERMSG ('SLATEC', 'DPCHIM',
+     +   'X-ARRAY NOT STRICTLY INCREASING', IERR, 1)
+      RETURN
+C------------- LAST LINE OF DPCHIM FOLLOWS -----------------------------
+      END
diff --git a/libcruft/slatec-fn/dpchst.f b/libcruft/slatec-fn/dpchst.f
new file mode 100644
index 0000000..9fc3894
--- /dev/null
+++ b/libcruft/slatec-fn/dpchst.f
@@ -0,0 +1,59 @@
+*DECK DPCHST
+      DOUBLE PRECISION FUNCTION DPCHST (ARG1, ARG2)
+C***BEGIN PROLOGUE  DPCHST
+C***SUBSIDIARY
+C***PURPOSE  DPCHIP Sign-Testing Routine
+C***LIBRARY   SLATEC (PCHIP)
+C***TYPE      DOUBLE PRECISION (PCHST-S, DPCHST-D)
+C***AUTHOR  Fritsch, F. N., (LLNL)
+C***DESCRIPTION
+C
+C         DPCHST:  DPCHIP Sign-Testing Routine.
+C
+C
+C     Returns:
+C        -1. if ARG1 and ARG2 are of opposite sign.
+C         0. if either argument is zero.
+C        +1. if ARG1 and ARG2 are of the same sign.
+C
+C     The object is to do this without multiplying ARG1*ARG2, to avoid
+C     possible over/underflow problems.
+C
+C  Fortran intrinsics used:  SIGN.
+C
+C***SEE ALSO  DPCHCE, DPCHCI, DPCHCS, DPCHIM
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   811103  DATE WRITTEN
+C   820805  Converted to SLATEC library version.
+C   870813  Minor cosmetic changes.
+C   890411  Added SAVE statements (Vers. 3.2).
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900328  Added TYPE section.  (WRB)
+C   910408  Updated AUTHOR and DATE WRITTEN sections in prologue.  (WRB)
+C   930503  Improved purpose.  (FNF)
+C***END PROLOGUE  DPCHST
+C
+C**End
+C
+C  DECLARE ARGUMENTS.
+C
+      DOUBLE PRECISION  ARG1, ARG2
+C
+C  DECLARE LOCAL VARIABLES.
+C
+      DOUBLE PRECISION  ONE, ZERO
+      SAVE ZERO, ONE
+      DATA  ZERO /0.D0/,  ONE/1.D0/
+C
+C  PERFORM THE TEST.
+C
+C***FIRST EXECUTABLE STATEMENT  DPCHST
+      DPCHST = SIGN(ONE,ARG1) * SIGN(ONE,ARG2)
+      IF ((ARG1.EQ.ZERO) .OR. (ARG2.EQ.ZERO))  DPCHST = ZERO
+C
+      RETURN
+C------------- LAST LINE OF DPCHST FOLLOWS -----------------------------
+      END
diff --git a/libcruft/slatec-fn/erf.f b/libcruft/slatec-fn/erf.f
new file mode 100644
index 0000000..bfef0ef
--- /dev/null
+++ b/libcruft/slatec-fn/erf.f
@@ -0,0 +1,73 @@
+*DECK ERF
+      FUNCTION ERF (X)
+C***BEGIN PROLOGUE  ERF
+C***PURPOSE  Compute the error function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C8A, L5A1E
+C***TYPE      SINGLE PRECISION (ERF-S, DERF-D)
+C***KEYWORDS  ERF, ERROR FUNCTION, FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ERF(X) calculates the single precision error function for
+C single precision argument X.
+C
+C Series for ERF        on the interval  0.          to  1.00000D+00
+C                                        with weighted error   7.10E-18
+C                                         log weighted error  17.15
+C                               significant figures required  16.31
+C                                    decimal places required  17.71
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, ERFC, INITS, R1MACH
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900727  Added EXTERNAL statement.  (WRB)
+C   920618  Removed space from variable name.  (RWC, WRB)
+C***END PROLOGUE  ERF
+      DIMENSION ERFCS(13)
+      LOGICAL FIRST
+      EXTERNAL ERFC
+      SAVE ERFCS, SQRTPI, NTERF, XBIG, SQEPS, FIRST
+      DATA ERFCS( 1) /   -.0490461212 34691808E0 /
+      DATA ERFCS( 2) /   -.1422612051 0371364E0 /
+      DATA ERFCS( 3) /    .0100355821 87599796E0 /
+      DATA ERFCS( 4) /   -.0005768764 69976748E0 /
+      DATA ERFCS( 5) /    .0000274199 31252196E0 /
+      DATA ERFCS( 6) /   -.0000011043 17550734E0 /
+      DATA ERFCS( 7) /    .0000000384 88755420E0 /
+      DATA ERFCS( 8) /   -.0000000011 80858253E0 /
+      DATA ERFCS( 9) /    .0000000000 32334215E0 /
+      DATA ERFCS(10) /   -.0000000000 00799101E0 /
+      DATA ERFCS(11) /    .0000000000 00017990E0 /
+      DATA ERFCS(12) /   -.0000000000 00000371E0 /
+      DATA ERFCS(13) /    .0000000000 00000007E0 /
+      DATA SQRTPI /1.772453850 9055160E0/
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  ERF
+      IF (FIRST) THEN
+         NTERF = INITS (ERFCS, 13, 0.1*R1MACH(3))
+         XBIG = SQRT(-LOG(SQRTPI*R1MACH(3)))
+         SQEPS = SQRT(2.0*R1MACH(3))
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.1.) GO TO 20
+C
+C ERF(X) = 1. - ERFC(X) FOR -1. .LE. X .LE. 1.
+C
+      IF (Y.LE.SQEPS) ERF = 2.0*X/SQRTPI
+      IF (Y.GT.SQEPS) ERF = X*(1.0 + CSEVL(2.*X**2-1., ERFCS, NTERF))
+      RETURN
+C
+C ERF(X) = 1. - ERFC(X) FOR  ABS(X) .GT. 1.
+C
+ 20   IF (Y.LE.XBIG) ERF = SIGN (1.0-ERFC(Y), X)
+      IF (Y.GT.XBIG) ERF = SIGN (1.0, X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/erfc.f b/libcruft/slatec-fn/erfc.f
new file mode 100644
index 0000000..baab90f
--- /dev/null
+++ b/libcruft/slatec-fn/erfc.f
@@ -0,0 +1,156 @@
+*DECK ERFC
+      FUNCTION ERFC (X)
+C***BEGIN PROLOGUE  ERFC
+C***PURPOSE  Compute the complementary error function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C8A, L5A1E
+C***TYPE      SINGLE PRECISION (ERFC-S, DERFC-D)
+C***KEYWORDS  COMPLEMENTARY ERROR FUNCTION, ERFC, FNLIB,
+C             SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C ERFC(X) calculates the single precision complementary error
+C function for single precision argument X.
+C
+C Series for ERF        on the interval  0.          to  1.00000D+00
+C                                        with weighted error   7.10E-18
+C                                         log weighted error  17.15
+C                               significant figures required  16.31
+C                                    decimal places required  17.71
+C
+C Series for ERFC       on the interval  0.          to  2.50000D-01
+C                                        with weighted error   4.81E-17
+C                                         log weighted error  16.32
+C                        approx significant figures required  15.0
+C
+C
+C Series for ERC2       on the interval  2.50000D-01 to  1.00000D+00
+C                                        with weighted error   5.22E-17
+C                                         log weighted error  16.28
+C                        approx significant figures required  15.0
+C                                    decimal places required  16.96
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, INITS, R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920618  Removed space from variable names.  (RWC, WRB)
+C***END PROLOGUE  ERFC
+      DIMENSION ERFCS(13), ERFCCS(24), ERC2CS(23)
+      LOGICAL FIRST
+      SAVE ERFCS, ERC2CS, ERFCCS, SQRTPI, NTERF, NTERFC,
+     1 NTERC2, XSML, XMAX, SQEPS, FIRST
+      DATA ERFCS( 1) /   -.0490461212 34691808E0 /
+      DATA ERFCS( 2) /   -.1422612051 0371364E0 /
+      DATA ERFCS( 3) /    .0100355821 87599796E0 /
+      DATA ERFCS( 4) /   -.0005768764 69976748E0 /
+      DATA ERFCS( 5) /    .0000274199 31252196E0 /
+      DATA ERFCS( 6) /   -.0000011043 17550734E0 /
+      DATA ERFCS( 7) /    .0000000384 88755420E0 /
+      DATA ERFCS( 8) /   -.0000000011 80858253E0 /
+      DATA ERFCS( 9) /    .0000000000 32334215E0 /
+      DATA ERFCS(10) /   -.0000000000 00799101E0 /
+      DATA ERFCS(11) /    .0000000000 00017990E0 /
+      DATA ERFCS(12) /   -.0000000000 00000371E0 /
+      DATA ERFCS(13) /    .0000000000 00000007E0 /
+      DATA ERC2CS( 1) /   -.0696013466 02309501E0 /
+      DATA ERC2CS( 2) /   -.0411013393 62620893E0 /
+      DATA ERC2CS( 3) /    .0039144958 66689626E0 /
+      DATA ERC2CS( 4) /   -.0004906395 65054897E0 /
+      DATA ERC2CS( 5) /    .0000715747 90013770E0 /
+      DATA ERC2CS( 6) /   -.0000115307 16341312E0 /
+      DATA ERC2CS( 7) /    .0000019946 70590201E0 /
+      DATA ERC2CS( 8) /   -.0000003642 66647159E0 /
+      DATA ERC2CS( 9) /    .0000000694 43726100E0 /
+      DATA ERC2CS(10) /   -.0000000137 12209021E0 /
+      DATA ERC2CS(11) /    .0000000027 88389661E0 /
+      DATA ERC2CS(12) /   -.0000000005 81416472E0 /
+      DATA ERC2CS(13) /    .0000000001 23892049E0 /
+      DATA ERC2CS(14) /   -.0000000000 26906391E0 /
+      DATA ERC2CS(15) /    .0000000000 05942614E0 /
+      DATA ERC2CS(16) /   -.0000000000 01332386E0 /
+      DATA ERC2CS(17) /    .0000000000 00302804E0 /
+      DATA ERC2CS(18) /   -.0000000000 00069666E0 /
+      DATA ERC2CS(19) /    .0000000000 00016208E0 /
+      DATA ERC2CS(20) /   -.0000000000 00003809E0 /
+      DATA ERC2CS(21) /    .0000000000 00000904E0 /
+      DATA ERC2CS(22) /   -.0000000000 00000216E0 /
+      DATA ERC2CS(23) /    .0000000000 00000052E0 /
+      DATA ERFCCS( 1) /   0.0715179310 202925E0 /
+      DATA ERFCCS( 2) /   -.0265324343 37606719E0 /
+      DATA ERFCCS( 3) /    .0017111539 77920853E0 /
+      DATA ERFCCS( 4) /   -.0001637516 63458512E0 /
+      DATA ERFCCS( 5) /    .0000198712 93500549E0 /
+      DATA ERFCCS( 6) /   -.0000028437 12412769E0 /
+      DATA ERFCCS( 7) /    .0000004606 16130901E0 /
+      DATA ERFCCS( 8) /   -.0000000822 77530261E0 /
+      DATA ERFCCS( 9) /    .0000000159 21418724E0 /
+      DATA ERFCCS(10) /   -.0000000032 95071356E0 /
+      DATA ERFCCS(11) /    .0000000007 22343973E0 /
+      DATA ERFCCS(12) /   -.0000000001 66485584E0 /
+      DATA ERFCCS(13) /    .0000000000 40103931E0 /
+      DATA ERFCCS(14) /   -.0000000000 10048164E0 /
+      DATA ERFCCS(15) /    .0000000000 02608272E0 /
+      DATA ERFCCS(16) /   -.0000000000 00699105E0 /
+      DATA ERFCCS(17) /    .0000000000 00192946E0 /
+      DATA ERFCCS(18) /   -.0000000000 00054704E0 /
+      DATA ERFCCS(19) /    .0000000000 00015901E0 /
+      DATA ERFCCS(20) /   -.0000000000 00004729E0 /
+      DATA ERFCCS(21) /    .0000000000 00001432E0 /
+      DATA ERFCCS(22) /   -.0000000000 00000439E0 /
+      DATA ERFCCS(23) /    .0000000000 00000138E0 /
+      DATA ERFCCS(24) /   -.0000000000 00000048E0 /
+      DATA SQRTPI /1.772453850 9055160E0/
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  ERFC
+      IF (FIRST) THEN
+         ETA = 0.1*R1MACH(3)
+         NTERF = INITS (ERFCS, 13, ETA)
+         NTERFC = INITS (ERFCCS, 24, ETA)
+         NTERC2 = INITS (ERC2CS, 23, ETA)
+C
+         XSML = -SQRT (-LOG(SQRTPI*R1MACH(3)))
+         TXMAX = SQRT (-LOG(SQRTPI*R1MACH(1)))
+         XMAX = TXMAX - 0.5*LOG(TXMAX)/TXMAX - 0.01
+         SQEPS = SQRT (2.0*R1MACH(3))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X.GT.XSML) GO TO 20
+C
+C ERFC(X) = 1.0 - ERF(X) FOR X .LT. XSML
+C
+      ERFC = 2.
+      RETURN
+C
+ 20   IF (X.GT.XMAX) GO TO 40
+      Y = ABS(X)
+      IF (Y.GT.1.0) GO TO 30
+C
+C ERFC(X) = 1.0 - ERF(X) FOR -1. .LE. X .LE. 1.
+C
+      IF (Y.LT.SQEPS) ERFC = 1.0 - 2.0*X/SQRTPI
+      IF (Y.GE.SQEPS) ERFC = 1.0 -
+     1  X*(1.0 + CSEVL (2.*X*X-1., ERFCS, NTERF) )
+      RETURN
+C
+C ERFC(X) = 1.0 - ERF(X) FOR 1. .LT. ABS(X) .LE. XMAX
+C
+ 30   Y = Y*Y
+      IF (Y.LE.4.) ERFC = EXP(-Y)/ABS(X) * (0.5 + CSEVL ((8./Y-5.)/3.,
+     1  ERC2CS, NTERC2) )
+      IF (Y.GT.4.) ERFC = EXP(-Y)/ABS(X) * (0.5 + CSEVL (8./Y-1.,
+     1  ERFCCS, NTERFC) )
+      IF (X.LT.0.) ERFC = 2.0 - ERFC
+      RETURN
+C
+ 40   CALL XERMSG ('SLATEC', 'ERFC', 'X SO BIG ERFC UNDERFLOWS', 1, 1)
+      ERFC = 0.
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/gami.f b/libcruft/slatec-fn/gami.f
new file mode 100644
index 0000000..d507574
--- /dev/null
+++ b/libcruft/slatec-fn/gami.f
@@ -0,0 +1,45 @@
+*DECK GAMI
+      FUNCTION GAMI (A, X)
+C***BEGIN PROLOGUE  GAMI
+C***PURPOSE  Evaluate the incomplete Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      SINGLE PRECISION (GAMI-S, DGAMI-D)
+C***KEYWORDS  FNLIB, INCOMPLETE GAMMA FUNCTION, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Evaluate the incomplete gamma function defined by
+C
+C GAMI = integral from T = 0 to X of EXP(-T) * T**(A-1.0) .
+C
+C GAMI is evaluated for positive values of A and non-negative values
+C of X.  A slight deterioration of 2 or 3 digits accuracy will occur
+C when GAMI is very large or very small, because logarithmic variables
+C are used.  GAMI, A, and X are single precision.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  ALNGAM, GAMIT, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  GAMI
+C***FIRST EXECUTABLE STATEMENT  GAMI
+      IF (A .LE. 0.0) CALL XERMSG ('SLATEC', 'GAMI',
+     +   'A MUST BE GT ZERO', 1, 2)
+      IF (X .LT. 0.0) CALL XERMSG ('SLATEC', 'GAMI',
+     +   'X MUST BE GE ZERO', 2, 2)
+C
+      GAMI = 0.0
+      IF (X.EQ.0.0) RETURN
+C
+C THE ONLY ERROR POSSIBLE IN THE EXPRESSION BELOW IS A FATAL OVERFLOW.
+      FACTOR = EXP (ALNGAM(A) + A*LOG(X) )
+C
+      GAMI = FACTOR * GAMIT(A, X)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/gamit.f b/libcruft/slatec-fn/gamit.f
new file mode 100644
index 0000000..451cf0b
--- /dev/null
+++ b/libcruft/slatec-fn/gamit.f
@@ -0,0 +1,112 @@
+*DECK GAMIT
+      REAL FUNCTION GAMIT (A, X)
+C***BEGIN PROLOGUE  GAMIT
+C***PURPOSE  Calculate Tricomi's form of the incomplete Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      SINGLE PRECISION (GAMIT-S, DGAMIT-D)
+C***KEYWORDS  COMPLEMENTARY INCOMPLETE GAMMA FUNCTION, FNLIB,
+C             SPECIAL FUNCTIONS, TRICOMI
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C   Evaluate Tricomi's incomplete gamma function defined by
+C
+C   GAMIT = X**(-A)/GAMMA(A) * integral from 0 to X of EXP(-T) *
+C             T**(A-1.)
+C
+C   for A .GT. 0.0 and by analytic continuation for A .LE. 0.0.
+C   GAMMA(X) is the complete gamma function of X.
+C
+C   GAMIT is evaluated for arbitrary real values of A and for non-
+C   negative values of X (even though GAMIT is defined for X .LT.
+C   0.0), except that for X = 0 and A .LE. 0.0, GAMIT is infinite,
+C   which is a fatal error.
+C
+C   The function and both arguments are REAL.
+C
+C   A slight deterioration of 2 or 3 digits accuracy will occur when
+C   GAMIT is very large or very small in absolute value, because log-
+C   arithmic variables are used.  Also, if the parameter  A  is very
+C   close to a negative integer (but not a negative integer), there is
+C   a loss of accuracy, which is reported if the result is less than
+C   half machine precision.
+C
+C***REFERENCES  W. Gautschi, A computational procedure for incomplete
+C                 gamma functions, ACM Transactions on Mathematical
+C                 Software 5, 4 (December 1979), pp. 466-481.
+C               W. Gautschi, Incomplete gamma functions, Algorithm 542,
+C                 ACM Transactions on Mathematical Software 5, 4
+C                 (December 1979), pp. 482-489.
+C***ROUTINES CALLED  ALGAMS, ALNGAM, GAMR, R1MACH, R9GMIT, R9LGIC,
+C                    R9LGIT, XERCLR, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920528  DESCRIPTION and REFERENCES sections revised.  (WRB)
+C***END PROLOGUE  GAMIT
+      LOGICAL FIRST
+      SAVE ALNEPS, SQEPS, BOT, FIRST
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  GAMIT
+      IF (FIRST) THEN
+         ALNEPS = -LOG(R1MACH(3))
+         SQEPS = SQRT(R1MACH(4))
+         BOT = LOG(R1MACH(1))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 0.0) CALL XERMSG ('SLATEC', 'GAMIT', 'X IS NEGATIVE',
+     +   2, 2)
+C
+      IF (X.NE.0.0) ALX = LOG(X)
+      SGA = 1.0
+      IF (A.NE.0.0) SGA = SIGN (1.0, A)
+      AINTA = AINT (A+0.5*SGA)
+      AEPS = A - AINTA
+C
+      IF (X.GT.0.0) GO TO 20
+      GAMIT = 0.0
+      IF (AINTA.GT.0.0 .OR. AEPS.NE.0.0) GAMIT = GAMR(A+1.0)
+      RETURN
+C
+ 20   IF (X.GT.1.0) GO TO 40
+      IF (A.GE.(-0.5) .OR. AEPS.NE.0.0) CALL ALGAMS (A+1.0, ALGAP1,
+     1  SGNGAM)
+      GAMIT = R9GMIT (A, X, ALGAP1, SGNGAM, ALX)
+      RETURN
+C
+ 40   IF (A.LT.X) GO TO 50
+      T = R9LGIT (A, X, ALNGAM(A+1.0))
+      IF (T.LT.BOT) CALL XERCLR
+      GAMIT = EXP(T)
+      RETURN
+C
+ 50   ALNG = R9LGIC (A, X, ALX)
+C
+C EVALUATE GAMIT IN TERMS OF LOG(GAMIC(A,X))
+C
+      H = 1.0
+      IF (AEPS.EQ.0.0 .AND. AINTA.LE.0.0) GO TO 60
+      CALL ALGAMS (A+1.0, ALGAP1, SGNGAM)
+      T = LOG(ABS(A)) + ALNG - ALGAP1
+      IF (T.GT.ALNEPS) GO TO 70
+      IF (T.GT.(-ALNEPS)) H = 1.0 - SGA*SGNGAM*EXP(T)
+      IF (ABS(H).GT.SQEPS) GO TO 60
+      CALL XERCLR
+      CALL XERMSG ('SLATEC', 'GAMIT', 'RESULT LT HALF PRECISION', 1, 1)
+C
+ 60   T = -A*ALX + LOG(ABS(H))
+      IF (T.LT.BOT) CALL XERCLR
+      GAMIT = SIGN (EXP(T), H)
+      RETURN
+C
+ 70   T = T - A*ALX
+      IF (T.LT.BOT) CALL XERCLR
+      GAMIT = -SGA*SGNGAM*EXP(T)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/gamlim.f b/libcruft/slatec-fn/gamlim.f
new file mode 100644
index 0000000..2b7ef10
--- /dev/null
+++ b/libcruft/slatec-fn/gamlim.f
@@ -0,0 +1,61 @@
+*DECK GAMLIM
+      SUBROUTINE GAMLIM (XMIN, XMAX)
+C***BEGIN PROLOGUE  GAMLIM
+C***PURPOSE  Compute the minimum and maximum bounds for the argument in
+C            the Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A, R2
+C***TYPE      SINGLE PRECISION (GAMLIM-S, DGAMLM-D)
+C***KEYWORDS  COMPLETE GAMMA FUNCTION, FNLIB, LIMITS, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Calculate the minimum and maximum legal bounds for X in GAMMA(X).
+C XMIN and XMAX are not the only bounds, but they are the only non-
+C trivial ones to calculate.
+C
+C             Output Arguments --
+C XMIN   minimum legal value of X in GAMMA(X).  Any smaller value of
+C        X might result in underflow.
+C XMAX   maximum legal value of X in GAMMA(X).  Any larger value will
+C        cause overflow.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  GAMLIM
+C***FIRST EXECUTABLE STATEMENT  GAMLIM
+      ALNSML = LOG(R1MACH(1))
+      XMIN = -ALNSML
+      DO 10 I=1,10
+        XOLD = XMIN
+        XLN = LOG(XMIN)
+        XMIN = XMIN - XMIN*((XMIN+0.5)*XLN - XMIN - 0.2258 + ALNSML)
+     1    / (XMIN*XLN + 0.5)
+        IF (ABS(XMIN-XOLD).LT.0.005) GO TO 20
+ 10   CONTINUE
+      CALL XERMSG ('SLATEC', 'GAMLIM', 'UNABLE TO FIND XMIN', 1, 2)
+C
+ 20   XMIN = -XMIN + 0.01
+C
+      ALNBIG = LOG(R1MACH(2))
+      XMAX = ALNBIG
+      DO 30 I=1,10
+        XOLD = XMAX
+        XLN = LOG(XMAX)
+        XMAX = XMAX - XMAX*((XMAX-0.5)*XLN - XMAX + 0.9189 - ALNBIG)
+     1    / (XMAX*XLN - 0.5)
+        IF (ABS(XMAX-XOLD).LT.0.005) GO TO 40
+ 30   CONTINUE
+      CALL XERMSG ('SLATEC', 'GAMLIM', 'UNABLE TO FIND XMAX', 2, 2)
+C
+ 40   XMAX = XMAX - 0.01
+      XMIN = MAX (XMIN, -XMAX+1.)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/gamma.f b/libcruft/slatec-fn/gamma.f
new file mode 100644
index 0000000..afcec90
--- /dev/null
+++ b/libcruft/slatec-fn/gamma.f
@@ -0,0 +1,138 @@
+*DECK GAMMA
+      FUNCTION GAMMA (X)
+C***BEGIN PROLOGUE  GAMMA
+C***PURPOSE  Compute the complete Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      SINGLE PRECISION (GAMMA-S, DGAMMA-D, CGAMMA-C)
+C***KEYWORDS  COMPLETE GAMMA FUNCTION, FNLIB, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C GAMMA computes the gamma function at X, where X is not 0, -1, -2, ....
+C GAMMA and X are single precision.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, GAMLIM, INITS, R1MACH, R9LGMC, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  GAMMA
+      DIMENSION GCS(23)
+      LOGICAL FIRST
+      SAVE GCS, PI, SQ2PIL, NGCS, XMIN, XMAX, DXREL, FIRST
+      DATA GCS   ( 1) / .0085711955 90989331E0/
+      DATA GCS   ( 2) / .0044153813 24841007E0/
+      DATA GCS   ( 3) / .0568504368 1599363E0/
+      DATA GCS   ( 4) /-.0042198353 96418561E0/
+      DATA GCS   ( 5) / .0013268081 81212460E0/
+      DATA GCS   ( 6) /-.0001893024 529798880E0/
+      DATA GCS   ( 7) / .0000360692 532744124E0/
+      DATA GCS   ( 8) /-.0000060567 619044608E0/
+      DATA GCS   ( 9) / .0000010558 295463022E0/
+      DATA GCS   (10) /-.0000001811 967365542E0/
+      DATA GCS   (11) / .0000000311 772496471E0/
+      DATA GCS   (12) /-.0000000053 542196390E0/
+      DATA GCS   (13) / .0000000009 193275519E0/
+      DATA GCS   (14) /-.0000000001 577941280E0/
+      DATA GCS   (15) / .0000000000 270798062E0/
+      DATA GCS   (16) /-.0000000000 046468186E0/
+      DATA GCS   (17) / .0000000000 007973350E0/
+      DATA GCS   (18) /-.0000000000 001368078E0/
+      DATA GCS   (19) / .0000000000 000234731E0/
+      DATA GCS   (20) /-.0000000000 000040274E0/
+      DATA GCS   (21) / .0000000000 000006910E0/
+      DATA GCS   (22) /-.0000000000 000001185E0/
+      DATA GCS   (23) / .0000000000 000000203E0/
+      DATA PI /3.14159 26535 89793 24E0/
+C SQ2PIL IS LOG (SQRT (2.*PI) )
+      DATA SQ2PIL /0.91893 85332 04672 74E0/
+      DATA FIRST /.TRUE./
+C
+C LANL DEPENDENT CODE REMOVED 81.02.04
+C
+C***FIRST EXECUTABLE STATEMENT  GAMMA
+      IF (FIRST) THEN
+C
+C ---------------------------------------------------------------------
+C INITIALIZE.  FIND LEGAL BOUNDS FOR X, AND DETERMINE THE NUMBER OF
+C TERMS IN THE SERIES REQUIRED TO ATTAIN AN ACCURACY TEN TIMES BETTER
+C THAN MACHINE PRECISION.
+C
+         NGCS = INITS (GCS, 23, 0.1*R1MACH(3))
+C
+         CALL GAMLIM (XMIN, XMAX)
+         DXREL = SQRT (R1MACH(4))
+C
+C ---------------------------------------------------------------------
+C FINISH INITIALIZATION.  START EVALUATING GAMMA(X).
+C
+      ENDIF
+      FIRST = .FALSE.
+C
+      Y = ABS(X)
+      IF (Y.GT.10.0) GO TO 50
+C
+C COMPUTE GAMMA(X) FOR ABS(X) .LE. 10.0.  REDUCE INTERVAL AND
+C FIND GAMMA(1+Y) FOR 0. .LE. Y .LT. 1. FIRST OF ALL.
+C
+      N = X
+      IF (X.LT.0.) N = N - 1
+      Y = X - N
+      N = N - 1
+      GAMMA = 0.9375 + CSEVL(2.*Y-1., GCS, NGCS)
+      IF (N.EQ.0) RETURN
+C
+      IF (N.GT.0) GO TO 30
+C
+C COMPUTE GAMMA(X) FOR X .LT. 1.
+C
+      N = -N
+      IF (X .EQ. 0.) CALL XERMSG ('SLATEC', 'GAMMA', 'X IS 0', 4, 2)
+      IF (X .LT. 0. .AND. X+N-2 .EQ. 0.) CALL XERMSG ('SLATEC', 'GAMMA'
+     1, 'X IS A NEGATIVE INTEGER', 4, 2)
+      IF (X .LT. (-0.5) .AND. ABS((X-AINT(X-0.5))/X) .LT. DXREL) CALL
+     1XERMSG ( 'SLATEC', 'GAMMA',
+     2'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR NEGATIVE INTEGER'
+     3, 1, 1)
+C
+      DO 20 I=1,N
+        GAMMA = GAMMA / (X+I-1)
+ 20   CONTINUE
+      RETURN
+C
+C GAMMA(X) FOR X .GE. 2.
+C
+ 30   DO 40 I=1,N
+        GAMMA = (Y+I)*GAMMA
+ 40   CONTINUE
+      RETURN
+C
+C COMPUTE GAMMA(X) FOR ABS(X) .GT. 10.0.  RECALL Y = ABS(X).
+C
+ 50   IF (X .GT. XMAX) CALL XERMSG ('SLATEC', 'GAMMA',
+     +   'X SO BIG GAMMA OVERFLOWS', 3, 2)
+C
+      GAMMA = 0.
+      IF (X .LT. XMIN) CALL XERMSG ('SLATEC', 'GAMMA',
+     +   'X SO SMALL GAMMA UNDERFLOWS', 2, 1)
+      IF (X.LT.XMIN) RETURN
+C
+      GAMMA = EXP((Y-0.5)*LOG(Y) - Y + SQ2PIL + R9LGMC(Y) )
+      IF (X.GT.0.) RETURN
+C
+      IF (ABS((X-AINT(X-0.5))/X) .LT. DXREL) CALL XERMSG ('SLATEC',
+     +   'GAMMA',
+     +   'ANSWER LT HALF PRECISION, X TOO NEAR NEGATIVE INTEGER', 1, 1)
+C
+      SINPIY = SIN (PI*Y)
+      IF (SINPIY .EQ. 0.) CALL XERMSG ('SLATEC', 'GAMMA',
+     +   'X IS A NEGATIVE INTEGER', 4, 2)
+C
+      GAMMA = -PI / (Y*SINPIY*GAMMA)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/gamr.f b/libcruft/slatec-fn/gamr.f
new file mode 100644
index 0000000..8a7d50d
--- /dev/null
+++ b/libcruft/slatec-fn/gamr.f
@@ -0,0 +1,42 @@
+*DECK GAMR
+      FUNCTION GAMR (X)
+C***BEGIN PROLOGUE  GAMR
+C***PURPOSE  Compute the reciprocal of the Gamma function.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7A
+C***TYPE      SINGLE PRECISION (GAMR-S, DGAMR-D, CGAMR-C)
+C***KEYWORDS  FNLIB, RECIPROCAL GAMMA FUNCTION, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C GAMR is a single precision function that evaluates the reciprocal
+C of the gamma function for single precision argument X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  ALGAMS, GAMMA, XERCLR, XGETF, XSETF
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   861211  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900727  Added EXTERNAL statement.  (WRB)
+C***END PROLOGUE  GAMR
+      EXTERNAL GAMMA
+C***FIRST EXECUTABLE STATEMENT  GAMR
+      GAMR = 0.0
+      IF (X.LE.0.0 .AND. AINT(X).EQ.X) RETURN
+C
+      CALL XGETF (IROLD)
+      CALL XSETF (1)
+      IF (ABS(X).GT.10.0) GO TO 10
+      GAMR = 1.0/GAMMA(X)
+      CALL XERCLR
+      CALL XSETF (IROLD)
+      RETURN
+C
+ 10   CALL ALGAMS (X, ALNGX, SGNGX)
+      CALL XERCLR
+      CALL XSETF (IROLD)
+      GAMR = SGNGX * EXP(-ALNGX)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/initds.f b/libcruft/slatec-fn/initds.f
new file mode 100644
index 0000000..36eca15
--- /dev/null
+++ b/libcruft/slatec-fn/initds.f
@@ -0,0 +1,54 @@
+*DECK INITDS
+      FUNCTION INITDS (OS, NOS, ETA)
+C***BEGIN PROLOGUE  INITDS
+C***PURPOSE  Determine the number of terms needed in an orthogonal
+C            polynomial series so that it meets a specified accuracy.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C3A2
+C***TYPE      DOUBLE PRECISION (INITS-S, INITDS-D)
+C***KEYWORDS  CHEBYSHEV, FNLIB, INITIALIZE, ORTHOGONAL POLYNOMIAL,
+C             ORTHOGONAL SERIES, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C  Initialize the orthogonal series, represented by the array OS, so
+C  that INITDS is the number of terms needed to insure the error is no
+C  larger than ETA.  Ordinarily, ETA will be chosen to be one-tenth
+C  machine precision.
+C
+C             Input Arguments --
+C   OS     double precision array of NOS coefficients in an orthogonal
+C          series.
+C   NOS    number of coefficients in OS.
+C   ETA    single precision scalar containing requested accuracy of
+C          series.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770601  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890831  Modified array declarations.  (WRB)
+C   891115  Modified error message.  (WRB)
+C   891115  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  INITDS
+      DOUBLE PRECISION OS(*)
+C***FIRST EXECUTABLE STATEMENT  INITDS
+      IF (NOS .LT. 1) CALL XERMSG ('SLATEC', 'INITDS',
+     +   'Number of coefficients is less than 1', 2, 1)
+C
+      ERR = 0.
+      DO 10 II = 1,NOS
+        I = NOS + 1 - II
+        ERR = ERR + ABS(REAL(OS(I)))
+        IF (ERR.GT.ETA) GO TO 20
+   10 CONTINUE
+C
+   20 IF (I .EQ. NOS) CALL XERMSG ('SLATEC', 'INITDS',
+     +   'Chebyshev series too short for specified accuracy', 1, 1)
+      INITDS = I
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/inits.f b/libcruft/slatec-fn/inits.f
new file mode 100644
index 0000000..e34154f
--- /dev/null
+++ b/libcruft/slatec-fn/inits.f
@@ -0,0 +1,53 @@
+*DECK INITS
+      FUNCTION INITS (OS, NOS, ETA)
+C***BEGIN PROLOGUE  INITS
+C***PURPOSE  Determine the number of terms needed in an orthogonal
+C            polynomial series so that it meets a specified accuracy.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C3A2
+C***TYPE      SINGLE PRECISION (INITS-S, INITDS-D)
+C***KEYWORDS  CHEBYSHEV, FNLIB, INITIALIZE, ORTHOGONAL POLYNOMIAL,
+C             ORTHOGONAL SERIES, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C  Initialize the orthogonal series, represented by the array OS, so
+C  that INITS is the number of terms needed to insure the error is no
+C  larger than ETA.  Ordinarily, ETA will be chosen to be one-tenth
+C  machine precision.
+C
+C             Input Arguments --
+C   OS     single precision array of NOS coefficients in an orthogonal
+C          series.
+C   NOS    number of coefficients in OS.
+C   ETA    single precision scalar containing requested accuracy of
+C          series.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770401  DATE WRITTEN
+C   890831  Modified array declarations.  (WRB)
+C   891115  Modified error message.  (WRB)
+C   891115  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C***END PROLOGUE  INITS
+      REAL OS(*)
+C***FIRST EXECUTABLE STATEMENT  INITS
+      IF (NOS .LT. 1) CALL XERMSG ('SLATEC', 'INITS',
+     +   'Number of coefficients is less than 1', 2, 1)
+C
+      ERR = 0.
+      DO 10 II = 1,NOS
+        I = NOS + 1 - II
+        ERR = ERR + ABS(OS(I))
+        IF (ERR.GT.ETA) GO TO 20
+   10 CONTINUE
+C
+   20 IF (I .EQ. NOS) CALL XERMSG ('SLATEC', 'INITS',
+     +   'Chebyshev series too short for specified accuracy', 1, 1)
+      INITS = I
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/pchim.f b/libcruft/slatec-fn/pchim.f
new file mode 100644
index 0000000..8c12f00
--- /dev/null
+++ b/libcruft/slatec-fn/pchim.f
@@ -0,0 +1,280 @@
+*DECK PCHIM
+      SUBROUTINE PCHIM (N, X, F, D, INCFD, IERR)
+C***BEGIN PROLOGUE  PCHIM
+C***PURPOSE  Set derivatives needed to determine a monotone piecewise
+C            cubic Hermite interpolant to given data.  Boundary values
+C            are provided which are compatible with monotonicity.  The
+C            interpolant will have an extremum at each point where mono-
+C            tonicity switches direction.  (See PCHIC if user control is
+C            desired over boundary or switch conditions.)
+C***LIBRARY   SLATEC (PCHIP)
+C***CATEGORY  E1A
+C***TYPE      SINGLE PRECISION (PCHIM-S, DPCHIM-D)
+C***KEYWORDS  CUBIC HERMITE INTERPOLATION, MONOTONE INTERPOLATION,
+C             PCHIP, PIECEWISE CUBIC INTERPOLATION
+C***AUTHOR  Fritsch, F. N., (LLNL)
+C             Lawrence Livermore National Laboratory
+C             P.O. Box 808  (L-316)
+C             Livermore, CA  94550
+C             FTS 532-4275, (510) 422-4275
+C***DESCRIPTION
+C
+C          PCHIM:  Piecewise Cubic Hermite Interpolation to
+C                  Monotone data.
+C
+C     Sets derivatives needed to determine a monotone piecewise cubic
+C     Hermite interpolant to the data given in X and F.
+C
+C     Default boundary conditions are provided which are compatible
+C     with monotonicity.  (See PCHIC if user control of boundary con-
+C     ditions is desired.)
+C
+C     If the data are only piecewise monotonic, the interpolant will
+C     have an extremum at each point where monotonicity switches direc-
+C     tion.  (See PCHIC if user control is desired in such cases.)
+C
+C     To facilitate two-dimensional applications, includes an increment
+C     between successive values of the F- and D-arrays.
+C
+C     The resulting piecewise cubic Hermite function may be evaluated
+C     by PCHFE or PCHFD.
+C
+C ----------------------------------------------------------------------
+C
+C  Calling sequence:
+C
+C        PARAMETER  (INCFD = ...)
+C        INTEGER  N, IERR
+C        REAL  X(N), F(INCFD,N), D(INCFD,N)
+C
+C        CALL  PCHIM (N, X, F, D, INCFD, IERR)
+C
+C   Parameters:
+C
+C     N -- (input) number of data points.  (Error return if N.LT.2 .)
+C           If N=2, simply does linear interpolation.
+C
+C     X -- (input) real array of independent variable values.  The
+C           elements of X must be strictly increasing:
+C                X(I-1) .LT. X(I),  I = 2(1)N.
+C           (Error return if not.)
+C
+C     F -- (input) real array of dependent variable values to be inter-
+C           polated.  F(1+(I-1)*INCFD) is value corresponding to X(I).
+C           PCHIM is designed for monotonic data, but it will work for
+C           any F-array.  It will force extrema at points where mono-
+C           tonicity switches direction.  If some other treatment of
+C           switch points is desired, PCHIC should be used instead.
+C                                     -----
+C     D -- (output) real array of derivative values at the data points.
+C           If the data are monotonic, these values will determine a
+C           a monotone cubic Hermite function.
+C           The value corresponding to X(I) is stored in
+C                D(1+(I-1)*INCFD),  I=1(1)N.
+C           No other entries in D are changed.
+C
+C     INCFD -- (input) increment between successive values in F and D.
+C           This argument is provided primarily for 2-D applications.
+C           (Error return if  INCFD.LT.1 .)
+C
+C     IERR -- (output) error flag.
+C           Normal return:
+C              IERR = 0  (no errors).
+C           Warning error:
+C              IERR.GT.0  means that IERR switches in the direction
+C                 of monotonicity were detected.
+C           "Recoverable" errors:
+C              IERR = -1  if N.LT.2 .
+C              IERR = -2  if INCFD.LT.1 .
+C              IERR = -3  if the X-array is not strictly increasing.
+C             (The D-array has not been changed in any of these cases.)
+C               NOTE:  The above errors are checked in the order listed,
+C                   and following arguments have **NOT** been validated.
+C
+C***REFERENCES  1. F. N. Fritsch and J. Butland, A method for construc-
+C                 ting local monotone piecewise cubic interpolants, SIAM
+C                 Journal on Scientific and Statistical Computing 5, 2
+C                 (June 1984), pp. 300-304.
+C               2. F. N. Fritsch and R. E. Carlson, Monotone piecewise
+C                 cubic interpolation, SIAM Journal on Numerical Ana-
+C                 lysis 17, 2 (April 1980), pp. 238-246.
+C***ROUTINES CALLED  PCHST, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   811103  DATE WRITTEN
+C   820201  1. Introduced  PCHST  to reduce possible over/under-
+C             flow problems.
+C           2. Rearranged derivative formula for same reason.
+C   820602  1. Modified end conditions to be continuous functions
+C             of data when monotonicity switches in next interval.
+C           2. Modified formulas so end conditions are less prone
+C             of over/underflow problems.
+C   820803  Minor cosmetic changes for release 1.
+C   870813  Updated Reference 1.
+C   890411  Added SAVE statements (Vers. 3.2).
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890703  Corrected category record.  (WRB)
+C   890831  Modified array declarations.  (WRB)
+C   890831  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   920429  Revised format and order of references.  (WRB,FNF)
+C***END PROLOGUE  PCHIM
+C  Programming notes:
+C
+C     1. The function  PCHST(ARG1,ARG2)  is assumed to return zero if
+C        either argument is zero, +1 if they are of the same sign, and
+C        -1 if they are of opposite sign.
+C     2. To produce a double precision version, simply:
+C        a. Change PCHIM to DPCHIM wherever it occurs,
+C        b. Change PCHST to DPCHST wherever it occurs,
+C        c. Change all references to the Fortran intrinsics to their
+C           double precision equivalents,
+C        d. Change the real declarations to double precision, and
+C        e. Change the constants ZERO and THREE to double precision.
+C
+C  DECLARE ARGUMENTS.
+C
+      INTEGER  N, INCFD, IERR
+      REAL  X(*), F(INCFD,*), D(INCFD,*)
+C
+C  DECLARE LOCAL VARIABLES.
+C
+      INTEGER  I, NLESS1
+      REAL  DEL1, DEL2, DMAX, DMIN, DRAT1, DRAT2, DSAVE,
+     *      H1, H2, HSUM, HSUMT3, THREE, W1, W2, ZERO
+      SAVE ZERO, THREE
+      REAL  PCHST
+      DATA  ZERO /0./,  THREE /3./
+C
+C  VALIDITY-CHECK ARGUMENTS.
+C
+C***FIRST EXECUTABLE STATEMENT  PCHIM
+      IF ( N.LT.2 )  GO TO 5001
+      IF ( INCFD.LT.1 )  GO TO 5002
+      DO 1  I = 2, N
+         IF ( X(I).LE.X(I-1) )  GO TO 5003
+    1 CONTINUE
+C
+C  FUNCTION DEFINITION IS OK, GO ON.
+C
+      IERR = 0
+      NLESS1 = N - 1
+      H1 = X(2) - X(1)
+      DEL1 = (F(1,2) - F(1,1))/H1
+      DSAVE = DEL1
+C
+C  SPECIAL CASE N=2 -- USE LINEAR INTERPOLATION.
+C
+      IF (NLESS1 .GT. 1)  GO TO 10
+      D(1,1) = DEL1
+      D(1,N) = DEL1
+      GO TO 5000
+C
+C  NORMAL CASE  (N .GE. 3).
+C
+   10 CONTINUE
+      H2 = X(3) - X(2)
+      DEL2 = (F(1,3) - F(1,2))/H2
+C
+C  SET D(1) VIA NON-CENTERED THREE-POINT FORMULA, ADJUSTED TO BE
+C     SHAPE-PRESERVING.
+C
+      HSUM = H1 + H2
+      W1 = (H1 + HSUM)/HSUM
+      W2 = -H1/HSUM
+      D(1,1) = W1*DEL1 + W2*DEL2
+      IF ( PCHST(D(1,1),DEL1) .LE. ZERO)  THEN
+         D(1,1) = ZERO
+      ELSE IF ( PCHST(DEL1,DEL2) .LT. ZERO)  THEN
+C        NEED DO THIS CHECK ONLY IF MONOTONICITY SWITCHES.
+         DMAX = THREE*DEL1
+         IF (ABS(D(1,1)) .GT. ABS(DMAX))  D(1,1) = DMAX
+      ENDIF
+C
+C  LOOP THROUGH INTERIOR POINTS.
+C
+      DO 50  I = 2, NLESS1
+         IF (I .EQ. 2)  GO TO 40
+C
+         H1 = H2
+         H2 = X(I+1) - X(I)
+         HSUM = H1 + H2
+         DEL1 = DEL2
+         DEL2 = (F(1,I+1) - F(1,I))/H2
+   40    CONTINUE
+C
+C        SET D(I)=0 UNLESS DATA ARE STRICTLY MONOTONIC.
+C
+         D(1,I) = ZERO
+         IF ( PCHST(DEL1,DEL2) )  42, 41, 45
+C
+C        COUNT NUMBER OF CHANGES IN DIRECTION OF MONOTONICITY.
+C
+   41    CONTINUE
+         IF (DEL2 .EQ. ZERO)  GO TO 50
+         IF ( PCHST(DSAVE,DEL2) .LT. ZERO)  IERR = IERR + 1
+         DSAVE = DEL2
+         GO TO 50
+C
+   42    CONTINUE
+         IERR = IERR + 1
+         DSAVE = DEL2
+         GO TO 50
+C
+C        USE BRODLIE MODIFICATION OF BUTLAND FORMULA.
+C
+   45    CONTINUE
+         HSUMT3 = HSUM+HSUM+HSUM
+         W1 = (HSUM + H1)/HSUMT3
+         W2 = (HSUM + H2)/HSUMT3
+         DMAX = MAX( ABS(DEL1), ABS(DEL2) )
+         DMIN = MIN( ABS(DEL1), ABS(DEL2) )
+         DRAT1 = DEL1/DMAX
+         DRAT2 = DEL2/DMAX
+         D(1,I) = DMIN/(W1*DRAT1 + W2*DRAT2)
+C
+   50 CONTINUE
+C
+C  SET D(N) VIA NON-CENTERED THREE-POINT FORMULA, ADJUSTED TO BE
+C     SHAPE-PRESERVING.
+C
+      W1 = -H2/HSUM
+      W2 = (H2 + HSUM)/HSUM
+      D(1,N) = W1*DEL1 + W2*DEL2
+      IF ( PCHST(D(1,N),DEL2) .LE. ZERO)  THEN
+         D(1,N) = ZERO
+      ELSE IF ( PCHST(DEL1,DEL2) .LT. ZERO)  THEN
+C        NEED DO THIS CHECK ONLY IF MONOTONICITY SWITCHES.
+         DMAX = THREE*DEL2
+         IF (ABS(D(1,N)) .GT. ABS(DMAX))  D(1,N) = DMAX
+      ENDIF
+C
+C  NORMAL RETURN.
+C
+ 5000 CONTINUE
+      RETURN
+C
+C  ERROR RETURNS.
+C
+ 5001 CONTINUE
+C     N.LT.2 RETURN.
+      IERR = -1
+      CALL XERMSG ('SLATEC', 'PCHIM',
+     +   'NUMBER OF DATA POINTS LESS THAN TWO', IERR, 1)
+      RETURN
+C
+ 5002 CONTINUE
+C     INCFD.LT.1 RETURN.
+      IERR = -2
+      CALL XERMSG ('SLATEC', 'PCHIM', 'INCREMENT LESS THAN ONE', IERR,
+     +   1)
+      RETURN
+C
+ 5003 CONTINUE
+C     X-ARRAY NOT STRICTLY INCREASING.
+      IERR = -3
+      CALL XERMSG ('SLATEC', 'PCHIM', 'X-ARRAY NOT STRICTLY INCREASING'
+     +   , IERR, 1)
+      RETURN
+C------------- LAST LINE OF PCHIM FOLLOWS ------------------------------
+      END
diff --git a/libcruft/slatec-fn/pchst.f b/libcruft/slatec-fn/pchst.f
new file mode 100644
index 0000000..e623120
--- /dev/null
+++ b/libcruft/slatec-fn/pchst.f
@@ -0,0 +1,57 @@
+*DECK PCHST
+      REAL FUNCTION PCHST (ARG1, ARG2)
+C***BEGIN PROLOGUE  PCHST
+C***SUBSIDIARY
+C***PURPOSE  PCHIP Sign-Testing Routine
+C***LIBRARY   SLATEC (PCHIP)
+C***TYPE      SINGLE PRECISION (PCHST-S, DPCHST-D)
+C***AUTHOR  Fritsch, F. N., (LLNL)
+C***DESCRIPTION
+C
+C         PCHST:  PCHIP Sign-Testing Routine.
+C
+C     Returns:
+C        -1. if ARG1 and ARG2 are of opposite sign.
+C         0. if either argument is zero.
+C        +1. if ARG1 and ARG2 are of the same sign.
+C
+C     The object is to do this without multiplying ARG1*ARG2, to avoid
+C     possible over/underflow problems.
+C
+C  Fortran intrinsics used:  SIGN.
+C
+C***SEE ALSO  PCHCE, PCHCI, PCHCS, PCHIM
+C***ROUTINES CALLED  (NONE)
+C***REVISION HISTORY  (YYMMDD)
+C   811103  DATE WRITTEN
+C   820805  Converted to SLATEC library version.
+C   870813  Minor cosmetic changes.
+C   890411  Added SAVE statements (Vers. 3.2).
+C   890411  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900328  Added TYPE section.  (WRB)
+C   910408  Updated AUTHOR and DATE WRITTEN sections in prologue.  (WRB)
+C   930503  Improved purpose.  (FNF)
+C***END PROLOGUE  PCHST
+C
+C**End
+C
+C  DECLARE ARGUMENTS.
+C
+      REAL  ARG1, ARG2
+C
+C  DECLARE LOCAL VARIABLES.
+C
+      REAL  ONE, ZERO
+      SAVE ZERO, ONE
+      DATA  ZERO /0./,  ONE /1./
+C
+C  PERFORM THE TEST.
+C
+C***FIRST EXECUTABLE STATEMENT  PCHST
+      PCHST = SIGN(ONE,ARG1) * SIGN(ONE,ARG2)
+      IF ((ARG1.EQ.ZERO) .OR. (ARG2.EQ.ZERO))  PCHST = ZERO
+C
+      RETURN
+C------------- LAST LINE OF PCHST FOLLOWS ------------------------------
+      END
diff --git a/libcruft/slatec-fn/r9gmit.f b/libcruft/slatec-fn/r9gmit.f
new file mode 100644
index 0000000..3d81492
--- /dev/null
+++ b/libcruft/slatec-fn/r9gmit.f
@@ -0,0 +1,84 @@
+*DECK R9GMIT
+      FUNCTION R9GMIT (A, X, ALGAP1, SGNGAM, ALX)
+C***BEGIN PROLOGUE  R9GMIT
+C***SUBSIDIARY
+C***PURPOSE  Compute Tricomi's incomplete Gamma function for small
+C            arguments.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      SINGLE PRECISION (R9GMIT-S, D9GMIT-D)
+C***KEYWORDS  COMPLEMENTARY INCOMPLETE GAMMA FUNCTION, FNLIB, SMALL X,
+C             SPECIAL FUNCTIONS, TRICOMI
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute Tricomi's incomplete gamma function for small X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  ALNGAM, R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  R9GMIT
+      SAVE EPS, BOT
+      DATA EPS, BOT / 2*0.0 /
+C***FIRST EXECUTABLE STATEMENT  R9GMIT
+      IF (EPS.EQ.0.0) EPS = 0.5*R1MACH(3)
+      IF (BOT.EQ.0.0) BOT = LOG(R1MACH(1))
+C
+      IF (X .LE. 0.0) CALL XERMSG ('SLATEC', 'R9GMIT',
+     +   'X SHOULD BE GT 0', 1, 2)
+C
+      MA = A + 0.5
+      IF (A.LT.0.0) MA = A - 0.5
+      AEPS = A - MA
+C
+      AE = A
+      IF (A.LT.(-0.5)) AE = AEPS
+C
+      T = 1.0
+      TE = AE
+      S = T
+      DO 20 K=1,200
+        FK = K
+        TE = -X*TE/FK
+        T = TE/(AE+FK)
+        S = S + T
+        IF (ABS(T).LT.EPS*ABS(S)) GO TO 30
+ 20   CONTINUE
+      CALL XERMSG ('SLATEC', 'R9GMIT',
+     +   'NO CONVERGENCE IN 200 TERMS OF TAYLOR-S SERIES', 2, 2)
+C
+ 30   IF (A.GE.(-0.5)) ALGS = -ALGAP1 + LOG(S)
+      IF (A.GE.(-0.5)) GO TO 60
+C
+      ALGS = -ALNGAM(1.0+AEPS) + LOG(S)
+      S = 1.0
+      M = -MA - 1
+      IF (M.EQ.0) GO TO 50
+      T = 1.0
+      DO 40 K=1,M
+        T = X*T/(AEPS-M-1+K)
+        S = S + T
+        IF (ABS(T).LT.EPS*ABS(S)) GO TO 50
+ 40   CONTINUE
+C
+ 50   R9GMIT = 0.0
+      ALGS = -MA*LOG(X) + ALGS
+      IF (S.EQ.0.0 .OR. AEPS.EQ.0.0) GO TO 60
+C
+      SGNG2 = SGNGAM*SIGN(1.0,S)
+      ALG2 = -X - ALGAP1 + LOG(ABS(S))
+C
+      IF (ALG2.GT.BOT) R9GMIT = SGNG2*EXP(ALG2)
+      IF (ALGS.GT.BOT) R9GMIT = R9GMIT + EXP(ALGS)
+      RETURN
+C
+ 60   R9GMIT = EXP(ALGS)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/r9lgic.f b/libcruft/slatec-fn/r9lgic.f
new file mode 100644
index 0000000..45b9866
--- /dev/null
+++ b/libcruft/slatec-fn/r9lgic.f
@@ -0,0 +1,53 @@
+*DECK R9LGIC
+      FUNCTION R9LGIC (A, X, ALX)
+C***BEGIN PROLOGUE  R9LGIC
+C***SUBSIDIARY
+C***PURPOSE  Compute the log complementary incomplete Gamma function
+C            for large X and for A .LE. X.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      SINGLE PRECISION (R9LGIC-S, D9LGIC-D)
+C***KEYWORDS  COMPLEMENTARY INCOMPLETE GAMMA FUNCTION, FNLIB, LARGE X,
+C             LOGARITHM, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute the log complementary incomplete gamma function for large X
+C and for A .LE. X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  R9LGIC
+      SAVE EPS
+      DATA EPS / 0.0 /
+C***FIRST EXECUTABLE STATEMENT  R9LGIC
+      IF (EPS.EQ.0.0) EPS = 0.5*R1MACH(3)
+C
+      XPA = X + 1.0 - A
+      XMA = X - 1.0 - A
+C
+      R = 0.0
+      P = 1.0
+      S = P
+      DO 10 K=1,200
+        FK = K
+        T = FK*(A-FK)*(1.0+R)
+        R = -T/((XMA+2.0*FK)*(XPA+2.0*FK)+T)
+        P = R*P
+        S = S + P
+        IF (ABS(P).LT.EPS*S) GO TO 20
+ 10   CONTINUE
+      CALL XERMSG ('SLATEC', 'R9LGIC',
+     +   'NO CONVERGENCE IN 200 TERMS OF CONTINUED FRACTION', 1, 2)
+C
+ 20   R9LGIC = A*ALX - X + LOG(S/XPA)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/r9lgit.f b/libcruft/slatec-fn/r9lgit.f
new file mode 100644
index 0000000..e19f5ec
--- /dev/null
+++ b/libcruft/slatec-fn/r9lgit.f
@@ -0,0 +1,61 @@
+*DECK R9LGIT
+      FUNCTION R9LGIT (A, X, ALGAP1)
+C***BEGIN PROLOGUE  R9LGIT
+C***SUBSIDIARY
+C***PURPOSE  Compute the logarithm of Tricomi's incomplete Gamma
+C            function with Perron's continued fraction for large X and
+C            A .GE. X.
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      SINGLE PRECISION (R9LGIT-S, D9LGIT-D)
+C***KEYWORDS  FNLIB, INCOMPLETE GAMMA FUNCTION, LOGARITHM,
+C             PERRON'S CONTINUED FRACTION, SPECIAL FUNCTIONS, TRICOMI
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute the log of Tricomi's incomplete gamma function with Perron's
+C continued fraction for large X and for A .GE. X.
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770701  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  R9LGIT
+      SAVE EPS, SQEPS
+      DATA EPS, SQEPS / 2*0.0 /
+C***FIRST EXECUTABLE STATEMENT  R9LGIT
+      IF (EPS.EQ.0.0) EPS = 0.5*R1MACH(3)
+      IF (SQEPS.EQ.0.0) SQEPS = SQRT(R1MACH(4))
+C
+      IF (X .LE. 0.0 .OR. A .LT. X) CALL XERMSG ('SLATEC', 'R9LGIT',
+     +   'X SHOULD BE GT 0.0 AND LE A', 2, 2)
+C
+      AX = A + X
+      A1X = AX + 1.0
+      R = 0.0
+      P = 1.0
+      S = P
+      DO 20 K=1,200
+        FK = K
+        T = (A+FK)*X*(1.0+R)
+        R = T/((AX+FK)*(A1X+FK)-T)
+        P = R*P
+        S = S + P
+        IF (ABS(P).LT.EPS*S) GO TO 30
+ 20   CONTINUE
+      CALL XERMSG ('SLATEC', 'R9LGIT',
+     +   'NO CONVERGENCE IN 200 TERMS OF CONTINUED FRACTION', 3, 2)
+C
+ 30   HSTAR = 1.0 - X*S/A1X
+      IF (HSTAR .LT. SQEPS) CALL XERMSG ('SLATEC', 'R9LGIT',
+     +   'RESULT LESS THAN HALF PRECISION', 1, 1)
+C
+      R9LGIT = -X - ALGAP1 - LOG(HSTAR)
+C
+      RETURN
+      END
diff --git a/libcruft/slatec-fn/r9lgmc.f b/libcruft/slatec-fn/r9lgmc.f
new file mode 100644
index 0000000..044f7f1
--- /dev/null
+++ b/libcruft/slatec-fn/r9lgmc.f
@@ -0,0 +1,66 @@
+*DECK R9LGMC
+      FUNCTION R9LGMC (X)
+C***BEGIN PROLOGUE  R9LGMC
+C***SUBSIDIARY
+C***PURPOSE  Compute the log Gamma correction factor so that
+C            LOG(GAMMA(X)) = LOG(SQRT(2*PI)) + (X-.5)*LOG(X) - X
+C            + R9LGMC(X).
+C***LIBRARY   SLATEC (FNLIB)
+C***CATEGORY  C7E
+C***TYPE      SINGLE PRECISION (R9LGMC-S, D9LGMC-D, C9LGMC-C)
+C***KEYWORDS  COMPLETE GAMMA FUNCTION, CORRECTION TERM, FNLIB,
+C             LOG GAMMA, LOGARITHM, SPECIAL FUNCTIONS
+C***AUTHOR  Fullerton, W., (LANL)
+C***DESCRIPTION
+C
+C Compute the log gamma correction factor for X .GE. 10.0 so that
+C  LOG (GAMMA(X)) = LOG(SQRT(2*PI)) + (X-.5)*LOG(X) - X + R9LGMC(X)
+C
+C Series for ALGM       on the interval  0.          to  1.00000D-02
+C                                        with weighted error   3.40E-16
+C                                         log weighted error  15.47
+C                               significant figures required  14.39
+C                                    decimal places required  15.86
+C
+C***REFERENCES  (NONE)
+C***ROUTINES CALLED  CSEVL, INITS, R1MACH, XERMSG
+C***REVISION HISTORY  (YYMMDD)
+C   770801  DATE WRITTEN
+C   890531  Changed all specific intrinsics to generic.  (WRB)
+C   890531  REVISION DATE from Version 3.2
+C   891214  Prologue converted to Version 4.0 format.  (BAB)
+C   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
+C   900720  Routine changed from user-callable to subsidiary.  (WRB)
+C***END PROLOGUE  R9LGMC
+      DIMENSION ALGMCS(6)
+      LOGICAL FIRST
+      SAVE ALGMCS, NALGM, XBIG, XMAX, FIRST
+      DATA ALGMCS( 1) /    .1666389480 45186E0 /
+      DATA ALGMCS( 2) /   -.0000138494 817606E0 /
+      DATA ALGMCS( 3) /    .0000000098 108256E0 /
+      DATA ALGMCS( 4) /   -.0000000000 180912E0 /
+      DATA ALGMCS( 5) /    .0000000000 000622E0 /
+      DATA ALGMCS( 6) /   -.0000000000 000003E0 /
+      DATA FIRST /.TRUE./
+C***FIRST EXECUTABLE STATEMENT  R9LGMC
+      IF (FIRST) THEN
+         NALGM = INITS (ALGMCS, 6, R1MACH(3))
+         XBIG = 1.0/SQRT(R1MACH(3))
+         XMAX = EXP (MIN(LOG(R1MACH(2)/12.0), -LOG(12.0*R1MACH(1))) )
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 10.0) CALL XERMSG ('SLATEC', 'R9LGMC',
+     +   'X MUST BE GE 10', 1, 2)
+      IF (X.GE.XMAX) GO TO 20
+C
+      R9LGMC = 1.0/(12.0*X)
+      IF (X.LT.XBIG) R9LGMC = CSEVL (2.0*(10./X)**2-1., ALGMCS, NALGM)/X
+      RETURN
+C
+ 20   R9LGMC = 0.0
+      CALL XERMSG ('SLATEC', 'R9LGMC', 'X SO BIG R9LGMC UNDERFLOWS', 2,
+     +   1)
+      RETURN
+C
+      END
diff --git a/libcruft/slatec-fn/xacosh.f b/libcruft/slatec-fn/xacosh.f
new file mode 100644
index 0000000..a7a8b3e
--- /dev/null
+++ b/libcruft/slatec-fn/xacosh.f
@@ -0,0 +1,6 @@
+      subroutine xacosh (x, result)
+      external acosh
+      real x, result, acosh
+      result = acosh (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xasinh.f b/libcruft/slatec-fn/xasinh.f
new file mode 100644
index 0000000..475ff16
--- /dev/null
+++ b/libcruft/slatec-fn/xasinh.f
@@ -0,0 +1,6 @@
+      subroutine xasinh (x, result)
+      external asinh
+      real x, result, asinh
+      result = asinh (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xatanh.f b/libcruft/slatec-fn/xatanh.f
new file mode 100644
index 0000000..5abf32d
--- /dev/null
+++ b/libcruft/slatec-fn/xatanh.f
@@ -0,0 +1,6 @@
+      subroutine xatanh (x, result)
+      external atanh
+      real x, result, atanh
+      result = atanh (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xbetai.f b/libcruft/slatec-fn/xbetai.f
new file mode 100644
index 0000000..a99a21b
--- /dev/null
+++ b/libcruft/slatec-fn/xbetai.f
@@ -0,0 +1,6 @@
+      subroutine xbetai (x, a, b, result)
+      external betai
+      real x, a, b, result, betai
+      result = betai (x, a, b)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdacosh.f b/libcruft/slatec-fn/xdacosh.f
new file mode 100644
index 0000000..340cbb2
--- /dev/null
+++ b/libcruft/slatec-fn/xdacosh.f
@@ -0,0 +1,6 @@
+      subroutine xdacosh (x, result)
+      external dacosh
+      double precision x, result, dacosh
+      result = dacosh (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdasinh.f b/libcruft/slatec-fn/xdasinh.f
new file mode 100644
index 0000000..ffdaa3c
--- /dev/null
+++ b/libcruft/slatec-fn/xdasinh.f
@@ -0,0 +1,6 @@
+      subroutine xdasinh (x, result)
+      external dasinh
+      double precision x, result, dasinh
+      result = dasinh (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdatanh.f b/libcruft/slatec-fn/xdatanh.f
new file mode 100644
index 0000000..a95fe2e
--- /dev/null
+++ b/libcruft/slatec-fn/xdatanh.f
@@ -0,0 +1,6 @@
+      subroutine xdatanh (x, result)
+      external datanh
+      double precision x, result, datanh
+      result = datanh (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdbetai.f b/libcruft/slatec-fn/xdbetai.f
new file mode 100644
index 0000000..8bfe289
--- /dev/null
+++ b/libcruft/slatec-fn/xdbetai.f
@@ -0,0 +1,6 @@
+      subroutine xdbetai (x, a, b, result)
+      external dbetai
+      double precision x, a, b, result, dbetai
+      result = dbetai (x, a, b)
+      return
+      end
diff --git a/libcruft/slatec-fn/xderf.f b/libcruft/slatec-fn/xderf.f
new file mode 100644
index 0000000..9f1bda0
--- /dev/null
+++ b/libcruft/slatec-fn/xderf.f
@@ -0,0 +1,6 @@
+      subroutine xderf (x, result)
+      external derf
+      double precision x, result, derf
+      result = derf (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xderfc.f b/libcruft/slatec-fn/xderfc.f
new file mode 100644
index 0000000..e5aa6cb
--- /dev/null
+++ b/libcruft/slatec-fn/xderfc.f
@@ -0,0 +1,6 @@
+      subroutine xderfc (x, result)
+      external derfc
+      double precision x, result, derfc
+      result = derfc (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdgami.f b/libcruft/slatec-fn/xdgami.f
new file mode 100644
index 0000000..d282013
--- /dev/null
+++ b/libcruft/slatec-fn/xdgami.f
@@ -0,0 +1,6 @@
+      subroutine xdgami (a, x, result)
+      external dgami
+      double precision a, x, result, dgami
+      result = dgami (a, x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdgamit.f b/libcruft/slatec-fn/xdgamit.f
new file mode 100644
index 0000000..c8d99c3
--- /dev/null
+++ b/libcruft/slatec-fn/xdgamit.f
@@ -0,0 +1,6 @@
+      subroutine xdgamit (a, x, result)
+      external dgamit
+      double precision a, x, result, dgamit
+      result = dgamit (a, x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xdgamma.f b/libcruft/slatec-fn/xdgamma.f
new file mode 100644
index 0000000..a6ac6cf
--- /dev/null
+++ b/libcruft/slatec-fn/xdgamma.f
@@ -0,0 +1,6 @@
+      subroutine xdgamma (x, result)
+      external dgamma
+      double precision x, result, dgamma
+      result = dgamma (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xerf.f b/libcruft/slatec-fn/xerf.f
new file mode 100644
index 0000000..0edfd8e
--- /dev/null
+++ b/libcruft/slatec-fn/xerf.f
@@ -0,0 +1,6 @@
+      subroutine xerf (x, result)
+      external erf
+      real x, result, erf
+      result = erf (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xerfc.f b/libcruft/slatec-fn/xerfc.f
new file mode 100644
index 0000000..4faa5df
--- /dev/null
+++ b/libcruft/slatec-fn/xerfc.f
@@ -0,0 +1,6 @@
+      subroutine xerfc (x, result)
+      external erfc
+      real x, result, erfc
+      result = erfc (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xgamma.f b/libcruft/slatec-fn/xgamma.f
new file mode 100644
index 0000000..8da5bf0
--- /dev/null
+++ b/libcruft/slatec-fn/xgamma.f
@@ -0,0 +1,6 @@
+      subroutine xgamma (x, result)
+      external gamma
+      real x, result, gamma
+      result = gamma (x)
+      return
+      end
diff --git a/libcruft/slatec-fn/xgmainc.f b/libcruft/slatec-fn/xgmainc.f
new file mode 100644
index 0000000..82c7883
--- /dev/null
+++ b/libcruft/slatec-fn/xgmainc.f
@@ -0,0 +1,100 @@
+      subroutine xgammainc (a, x, result)
+
+c -- jwe, based on DGAMIT.
+c
+c -- Do a better job than dgami for large values of x.
+
+      double precision a, x, result
+      intrinsic exp, log, sqrt, sign, aint
+      external dgami, dlngam, d9lgit, d9lgic, d9gmit
+
+C     external dgamr
+C     DOUBLE PRECISION DGAMR
+
+      DOUBLE PRECISION AEPS, AINTA, ALGAP1, ALNEPS, ALNG, ALX,
+     $     BOT, H, SGA, SGNGAM, SQEPS, T, D1MACH, D9GMIT,
+     $     D9LGIC, D9LGIT, DLNGAM, DGAMI 
+
+      LOGICAL FIRST
+
+      SAVE ALNEPS, SQEPS, BOT, FIRST
+
+      DATA FIRST /.TRUE./
+
+      if (x .eq. 0.0d0) then
+
+        if (a .eq. 0.0d0) then
+          result = 1.0d0
+        else
+          result = 0.0d0
+        endif
+
+      else
+
+      IF (FIRST) THEN
+         ALNEPS = -LOG (D1MACH(3))
+         SQEPS = SQRT(D1MACH(4))
+         BOT = LOG (D1MACH(1))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 0.D0) CALL XERMSG ('SLATEC', 'XGMAINC', 'X IS NEGATIVE'
+     +   , 2, 2)
+C
+      IF (X.NE.0.D0) ALX = LOG (X)
+      SGA = 1.0D0
+      IF (A.NE.0.D0) SGA = SIGN (1.0D0, A)
+      AINTA = AINT (A + 0.5D0*SGA)
+      AEPS = A - AINTA
+C
+C      IF (X.GT.0.D0) GO TO 20
+C      DGAMIT = 0.0D0
+C      IF (AINTA.GT.0.D0 .OR. AEPS.NE.0.D0) DGAMIT = DGAMR(A+1.0D0)
+C      RETURN
+C
+ 20   IF (X.GT.1.D0) GO TO 30
+      IF (A.GE.(-0.5D0) .OR. AEPS.NE.0.D0) CALL DLGAMS (A+1.0D0, ALGAP1,
+     1  SGNGAM)
+C      DGAMIT = D9GMIT (A, X, ALGAP1, SGNGAM, ALX)
+      result = exp (a*alx + log (D9GMIT (A, X, ALGAP1, SGNGAM, ALX)))
+      RETURN
+C
+ 30   IF (A.LT.X) GO TO 40
+      T = D9LGIT (A, X, DLNGAM(A+1.0D0))
+      IF (T.LT.BOT) CALL XERCLR
+C      DGAMIT = EXP (T)
+      result = EXP (a*alx + T)
+      RETURN
+C
+ 40   ALNG = D9LGIC (A, X, ALX)
+C
+C EVALUATE DGAMIT IN TERMS OF LOG (DGAMIC (A, X))
+C
+      H = 1.0D0
+      IF (AEPS.EQ.0.D0 .AND. AINTA.LE.0.D0) GO TO 50
+C
+      CALL DLGAMS (A+1.0D0, ALGAP1, SGNGAM)
+      T = LOG (ABS(A)) + ALNG - ALGAP1
+      IF (T.GT.ALNEPS) GO TO 60
+C
+      IF (T.GT.(-ALNEPS)) H = 1.0D0 - SGA * SGNGAM * EXP(T)
+      IF (ABS(H).GT.SQEPS) GO TO 50
+C
+      CALL XERCLR
+      CALL XERMSG ('SLATEC', 'XGMAINC', 'RESULT LT HALF PRECISION', 1,
+     +   1)
+C
+C 50   T = -A*ALX + LOG(ABS(H))
+C      IF (T.LT.BOT) CALL XERCLR
+C      DGAMIT = SIGN (EXP(T), H)
+ 50   result = H
+      RETURN
+C
+C 60   T = T - A*ALX
+ 60   IF (T.LT.BOT) CALL XERCLR
+      result = -SGA * SGNGAM * EXP(T)
+      RETURN
+
+      endif
+      return
+      end
diff --git a/libcruft/slatec-fn/xsgmainc.f b/libcruft/slatec-fn/xsgmainc.f
new file mode 100644
index 0000000..2897b23
--- /dev/null
+++ b/libcruft/slatec-fn/xsgmainc.f
@@ -0,0 +1,100 @@
+      subroutine xsgammainc (a, x, result)
+
+c -- jwe, based on GAMIT.
+c
+c -- Do a better job than gami for large values of x.
+
+      real a, x, result
+      intrinsic exp, log, sqrt, sign, aint
+      external gami, alngam, r9lgit, r9lgic, r9gmit
+
+C     external gamr
+C     real GAMR
+
+      REAL AEPS, AINTA, ALGAP1, ALNEPS, ALNG, ALX,
+     $     BOT, H, SGA, SGNGAM, SQEPS, T, R1MACH, R9GMIT,
+     $     R9LGIC, R9LGIT, ALNGAM, GAMI 
+
+      LOGICAL FIRST
+
+      SAVE ALNEPS, SQEPS, BOT, FIRST
+
+      DATA FIRST /.TRUE./
+
+      if (x .eq. 0.0e0) then
+
+        if (a .eq. 0.0e0) then
+          result = 1.0e0
+        else
+          result = 0.0e0
+        endif
+
+      else
+
+      IF (FIRST) THEN
+         ALNEPS = -LOG (R1MACH(3))
+         SQEPS = SQRT(R1MACH(4))
+         BOT = LOG (R1MACH(1))
+      ENDIF
+      FIRST = .FALSE.
+C
+      IF (X .LT. 0.E0) CALL XERMSG ('SLATEC', 'XGMAINC', 'X IS NEGATIVE'
+     +   , 2, 2)
+C
+      IF (X.NE.0.E0) ALX = LOG (X)
+      SGA = 1.0E0
+      IF (A.NE.0.E0) SGA = SIGN (1.0E0, A)
+      AINTA = AINT (A + 0.5E0*SGA)
+      AEPS = A - AINTA
+C
+C      IF (X.GT.0.E0) GO TO 20
+C      GAMIT = 0.0E0
+C      IF (AINTA.GT.0.E0 .OR. AEPS.NE.0.E0) GAMIT = GAMR(A+1.0E0)
+C      RETURN
+C
+ 20   IF (X.GT.1.E0) GO TO 30
+      IF (A.GE.(-0.5E0) .OR. AEPS.NE.0.E0) CALL ALGAMS (A+1.0E0, ALGAP1,
+     1  SGNGAM)
+C      GAMIT = R9GMIT (A, X, ALGAP1, SGNGAM, ALX)
+      result = exp (a*alx + log (R9GMIT (A, X, ALGAP1, SGNGAM, ALX)))
+      RETURN
+C
+ 30   IF (A.LT.X) GO TO 40
+      T = R9LGIT (A, X, ALNGAM(A+1.0E0))
+      IF (T.LT.BOT) CALL XERCLR
+C      GAMIT = EXP (T)
+      result = EXP (a*alx + T)
+      RETURN
+C
+ 40   ALNG = R9LGIC (A, X, ALX)
+C
+C EVALUATE GAMIT IN TERMS OF LOG (DGAMIC (A, X))
+C
+      H = 1.0E0
+      IF (AEPS.EQ.0.E0 .AND. AINTA.LE.0.E0) GO TO 50
+C
+      CALL ALGAMS (A+1.0E0, ALGAP1, SGNGAM)
+      T = LOG (ABS(A)) + ALNG - ALGAP1
+      IF (T.GT.ALNEPS) GO TO 60
+C
+      IF (T.GT.(-ALNEPS)) H = 1.0E0 - SGA * SGNGAM * EXP(T)
+      IF (ABS(H).GT.SQEPS) GO TO 50
+C
+      CALL XERCLR
+      CALL XERMSG ('SLATEC', 'XGMAINC', 'RESULT LT HALF PRECISION', 1,
+     +   1)
+C
+C 50   T = -A*ALX + LOG(ABS(H))
+C      IF (T.LT.BOT) CALL XERCLR
+C      GAMIT = SIGN (EXP(T), H)
+ 50   result = H
+      RETURN
+C
+C 60   T = T - A*ALX
+ 60   IF (T.LT.BOT) CALL XERCLR
+      result = -SGA * SGNGAM * EXP(T)
+      RETURN
+
+      endif
+      return
+      end
diff --git a/libcruft/villad/Makefile.in b/libcruft/villad/Makefile.in
new file mode 100644
index 0000000..dba84c9
--- /dev/null
+++ b/libcruft/villad/Makefile.in
@@ -0,0 +1,33 @@
+# Makefile for octave's libcruft/villad directory
+#
+# Copyright (C) 1993, 1994, 1995, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+EXTERNAL_DISTFILES = $(DISTFILES)
+
+FSRC := dfopr.f dif.f intrp.f jcobi.f radau.f vilerr.f
+
+include $(TOPDIR)/Makeconf
+
+include ../Makerules
diff --git a/libcruft/villad/dfopr.f b/libcruft/villad/dfopr.f
new file mode 100644
index 0000000..71b28bc
--- /dev/null
+++ b/libcruft/villad/dfopr.f
@@ -0,0 +1,176 @@
+      SUBROUTINE DFOPR
+     +  (
+     +  ND, N, N0, N1, I, ID, DIF1, DIF2, DIF3, ROOT, VECT
+     +  )
+      INTEGER           ND, N, N0, N1, I, ID
+      DOUBLE PRECISION  DIF1(ND), DIF2(ND), DIF3(ND), ROOT(ND), VECT(ND)
+C
+C***********************************************************************
+C
+C     VILLADSEN AND MICHELSEN, PAGES 133-134, 419
+C
+C     INPUT PARAMETERS:
+C
+C       ND     : THE DIMENSION OF THE VECTORS DIF1, DIF2, DIF3, AND ROOT
+C
+C       N      : THE DEGREE OF THE JACOBI POLYNOMIAL, (i.e. THE NUMBER
+C                OF INTERIOR INTERPOLATION POINTS)
+C
+C       N0     : DETERMINES WHETHER X = 0 IS INCLUDED AS AN
+C                INTERPOLATION POINT
+C
+C                  N0 = 0  ==>  X = 0 IS NOT INCLUDED
+C                  N0 = 1  ==>  X = 0 IS INCLUDED
+C
+C       N1     : DETERMINES WHETHER X = 1 IS INCLUDED AS AN
+C                INTERPOLATION POINT
+C
+C                  N1 = 0  ==>  X = 1 IS NOT INCLUDED
+C                  N1 = 1  ==>  X = 1 IS INCLUDED
+C
+C       I      : THE INDEX OF THE NODE FOR WHICH THE WEIGHTS ARE TO BE
+C                CALCULATED
+C
+C       ID     : INDICATOR
+C
+C                  ID = 1  ==>  FIRST DERIVATIVE WEIGHTS ARE COMPUTED
+C                  ID = 2  ==>  SECOND DERIVATIVE WEIGHTS ARE COMPUTED
+C                  ID = 3  ==>  GAUSSIAN WEIGHTS ARE COMPUTED (IN THIS
+C                               CASE, THE VALUE OF I IS IRRELEVANT)
+C
+C     OUTPUT PARAMETERS:
+C
+C       DIF1   : ONE DIMENSIONAL VECTOR CONTAINING THE FIRST DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C       DIF2   : ONE DIMENSIONAL VECTOR CONTAINING THE SECOND DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C       DIF3   : ONE DIMENSIONAL VECTOR CONTAINING THE THIRD DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C       VECT   : ONE DIMENSIONAL VECTOR OF COMPUTED WEIGHTS
+C
+C     COMMON BLOCKS:      NONE
+C
+C     REQUIRED ROUTINES:  VILERR
+C
+C***********************************************************************
+C
+      INTEGER           J,NT,IER
+      DOUBLE PRECISION  AX,X,Y
+      DOUBLE PRECISION  ZERO,ONE,TWO,THREE
+      LOGICAL          LSTOP
+C
+      PARAMETER ( ZERO = 0.0D+00, ONE    = 1.0D+00,
+     +            TWO  = 2.0D+00, THREE  = 3.0D+00 )
+C
+C -- ERROR CHECKING
+C
+      IF ((N0 .NE. 0) .AND. (N0 .NE. 1)) THEN
+        IER   = 1
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((N1 .NE. 0) .AND. (N1 .NE. 1)) THEN
+        IER   = 2
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF (ND .LT. (N + N0 + N1)) THEN
+        IER   = 3
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((ID .NE. 1) .AND. (ID.NE. 2) .AND. (ID .NE. 3)) THEN
+        IER   = 6
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF (ID .NE. 3) THEN
+        IF (I .LT. 1) THEN
+          IER   = 4
+          LSTOP = .TRUE.
+          CALL VILERR(IER,LSTOP)
+        ELSE
+        END IF
+C
+        IF (I .GT. (N + N0 + N1)) THEN
+          IER   = 5
+          LSTOP = .TRUE.
+          CALL VILERR(IER,LSTOP)
+        ELSE
+        END IF
+      ELSE
+      END IF
+C
+      IF ((N + N0 + N1) .LT. 1) THEN
+        IER   = 7
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+C -- EVALUATE DISCRETIZATION MATRICES AND GAUSSIAN QUADRATURE
+C -- WEIGHTS.  QUADRATURE WEIGHTS ARE NORMALIZED TO SUM TO ONE.
+C
+      NT = N + N0 + N1
+C
+      IF (ID .NE. 3) THEN
+        DO 20 J = 1,NT
+C
+          IF (J .EQ. I) THEN
+            IF (ID .EQ. 1) THEN
+              VECT(I) = DIF2(I)/DIF1(I)/TWO
+            ELSE
+              VECT(I) = DIF3(I)/DIF1(I)/THREE
+            END IF
+          ELSE
+            Y       = ROOT(I) - ROOT(J)
+            VECT(J) = DIF1(I)/DIF1(J)/Y
+            IF (ID .EQ. 2) THEN
+              VECT(J) = VECT(J)*(DIF2(I)/DIF1(I) - TWO/Y)
+            ELSE
+            END IF
+          END IF
+C
+   20   CONTINUE
+      ELSE
+        Y = ZERO
+C
+        DO 25 J = 1,NT
+C
+          X  = ROOT(J)
+          AX = X*(ONE - X)
+C
+          IF(N0 .EQ. 0) THEN
+            AX = AX/X/X
+          ELSE
+          END IF
+C
+          IF(N1 .EQ. 0) THEN
+            AX = AX/(ONE - X)/(ONE - X)
+          ELSE
+          END IF
+C
+          VECT(J) = AX/DIF1(J)**2
+          Y       = Y + VECT(J)
+C
+   25   CONTINUE
+C
+        DO 60 J = 1,NT
+          VECT(J) = VECT(J)/Y
+   60   CONTINUE
+C
+      END IF
+C
+      RETURN
+      END
diff --git a/libcruft/villad/dif.f b/libcruft/villad/dif.f
new file mode 100644
index 0000000..1e8a8c1
--- /dev/null
+++ b/libcruft/villad/dif.f
@@ -0,0 +1,74 @@
+      SUBROUTINE DIF ( NT, ROOT, DIF1, DIF2, DIF3 )
+C
+      INTEGER           NT
+      DOUBLE PRECISION  ROOT(NT), DIF1(NT), DIF2(NT), DIF3(NT)
+
+C
+C***********************************************************************
+C
+C     SUBROUTINE DIF
+C
+C     THIS ROUTINE IS NOT GIVEN SEPARATELY BY VILLADSEN AND MICHELSEN
+C     BUT AS PART OF JCOBI
+C
+C     DIF COMPUTES THE FIRST THREE DERIVATIVES OF THE NODE POLYNOMIAL
+C
+C                     N0     (ALPHA,BETA)           N1
+C       P  (X)  =  (X)   *  P (X)         *  (1 - X)
+C        NT                   N
+C
+C     AT THE INTERPOLATION POINTS.  EACH OF THE PARAMETERS N0 AND N1
+C     MAY BE GIVEN THE VALUE 0 OR 1.  NT = N + N0 + N1
+C
+C     THE VALUES OF ROOT MUST BE KNOWN BEFORE A CALL TO DIF IS POSSIBLE.
+C     THEY MAY BE COMPUTED USING JCOBI.
+C
+C     PARAMETER LIST:     SEE THE SUBROUTINE JCOBI
+C
+C     COMMON BLOCKS:      NONE
+C
+C     REQUIRED ROUTINES:  VILERR
+C
+C***********************************************************************
+C
+      INTEGER           I,J,IER
+      DOUBLE PRECISION  X,Y
+      DOUBLE PRECISION  ZERO,ONE,TWO,THREE
+      LOGICAL           LSTOP
+C
+      PARAMETER ( ZERO = 0.0D+00, ONE   = 1.0D+00,
+     +            TWO  = 2.0D+00, THREE = 3.0D+00 )
+C
+C -- ERROR CHECKING
+C
+      IF (NT .LT. 1) THEN
+        IER   = 7
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+C -- EVALUATE DERIVATIVES OF NODE POLYNOMIAL USING RECURSION FORMULAS
+C
+      DO 40 I = 1,NT
+C
+        X       = ROOT(I)
+        DIF1(I) = ONE
+        DIF2(I) = ZERO
+        DIF3(I) = ZERO
+C
+        DO 30 J = 1,NT
+C
+          IF (J .NE. I) THEN
+            Y       = X - ROOT(J)
+            DIF3(I) = Y*DIF3(I) + THREE*DIF2(I)
+            DIF2(I) = Y*DIF2(I) + TWO  *DIF1(I)
+            DIF1(I) = Y*DIF1(I)
+          ELSE
+          END IF
+C
+   30   CONTINUE
+   40 CONTINUE
+C
+      RETURN
+      END
diff --git a/libcruft/villad/intrp.f b/libcruft/villad/intrp.f
new file mode 100644
index 0000000..4dcdec2
--- /dev/null
+++ b/libcruft/villad/intrp.f
@@ -0,0 +1,93 @@
+      SUBROUTINE INTRP ( ND, NT, X, ROOT, DIF1, XINTP )
+C
+      INTEGER           ND, NT
+      DOUBLE PRECISION  ROOT(ND), DIF1(ND), XINTP(ND)
+C
+C***********************************************************************
+C
+C     LAGRANGE INTERPOLATION
+C
+C     VILLADSEN AND MICHELSEN, PAGES 132-133, 420
+C
+C     INPUT PARAMETERS:
+C
+C       NT     : THE TOTAL NUMBER OF INTERPOLATION POINTS FOR WHICH THE
+C                VALUE OF THE DEPENDENT VARIABLE Y IS KNOWN.  NOTE:
+C
+C                  NT = N + N0 + N1
+C
+C       X      : THE ABCISSA X WHERE Y(X) IS DESIRED
+C
+C       ROOT   : ONE DIMENSIONAL VECTOR CONTAINING ON EXIT THE
+C                N + N0 + N1 ZEROS OF THE NODE POLYNOMIAL USED IN THE
+C                INTERPOLATION ROUTINE
+C
+C       DIF1   : ONE DIMENSIONAL VECTOR CONTAINING THE FIRST DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C     OUTPUT PARAMETERS:
+C
+C       XINTP  : THE VECTOR OF INTERPOLATION WEIGHTS
+C
+C                Y(X) IS GIVEN BY:
+C
+C                            NT
+C                  Y(X)  =  SUM  XINTRP(I) * Y(I)
+C                           I=1
+C
+C     COMMON BLOCKS:      NONE
+C
+C     REQUIRED ROUTINES:  VILERR
+C
+C***********************************************************************
+C
+      INTEGER           I,IER
+      DOUBLE PRECISION  POL,Y,X
+      DOUBLE PRECISION  ZERO,ONE
+      LOGICAL           LSTOP
+C
+      PARAMETER ( ZERO = 0.0D+00, ONE = 1.0D+00 )
+C
+C -- ERROR CHECKING
+C
+      IF (ND .LT. NT) THEN
+        IER   = 3
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF (NT .LT. 1) THEN
+        IER   = 7
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+C -- EVALUATE LAGRANGIAN INTERPOLATION COEFFICIENTS
+C
+      POL = ONE
+C
+      DO 5 I = 1,NT
+C
+        Y        = X - ROOT(I)
+        XINTP(I) = ZERO
+C
+        IF (Y .EQ. ZERO) THEN
+          XINTP(I) = ONE
+        ELSE
+        END IF
+C
+        POL = POL*Y
+C
+    5 CONTINUE
+C
+      IF (POL .NE. ZERO) THEN
+        DO 6 I = 1,NT
+          XINTP(I) = POL/DIF1(I)/(X - ROOT(I))
+    6   CONTINUE
+      ELSE
+      END IF
+C
+      RETURN
+      END
diff --git a/libcruft/villad/jcobi.f b/libcruft/villad/jcobi.f
new file mode 100644
index 0000000..8f45d1d
--- /dev/null
+++ b/libcruft/villad/jcobi.f
@@ -0,0 +1,240 @@
+****************************************************************
+*
+*     The following routines (JCOBI, DIF, DFOPR, INTRP, AND RADAU)
+*     are the same as found in Villadsen, J. and M.L. Michelsen,
+*     Solution of Differential Equation Models by Polynomial
+*     Approximation, Prentice-Hall (1978) pages 418-420.
+*
+*     Cosmetic changes (elimination of arithmetic IF statements, most
+*     GO TO statements, and indentation of program blocks) made by:
+*
+*     John W. Eaton
+*     Department of Chemical Engineering
+*     The University of Texas at Austin
+*     Austin, Texas 78712
+*
+*     June 6, 1987
+*
+*     Some error checking additions also made on June 7, 1987
+*
+*     Further cosmetic changes made August 20, 1987
+*
+************************************************************************
+*
+      SUBROUTINE JCOBI
+     +  (
+     +  ND, N, N0, N1, ALPHA, BETA, DIF1, DIF2, DIF3, ROOT
+     +  )
+C
+      INTEGER
+     +
+     +  ND, N, N0, N1
+C 
+      DOUBLE PRECISION
+     +
+     +  ALPHA, BETA, DIF1(ND), DIF2(ND), DIF3(ND), ROOT(ND)
+C
+C***********************************************************************
+C
+C     VILLADSEN AND MICHELSEN, PAGES 131-132, 418
+C
+C     THIS SUBROUTINE COMPUTES THE ZEROS OF THE JACOBI POLYNOMIAL
+C
+C        (ALPHA,BETA)
+C       P  (X)
+C        N
+C
+C     USE DIF (GIVEN BELOW) TO COMPUTE THE DERIVATIVES OF THE NODE
+C     POLYNOMIAL
+C
+C                     N0     (ALPHA,BETA)           N1
+C       P  (X)  =  (X)   *  P (X)         *  (1 - X)
+C        NT                   N
+C
+C     AT THE INTERPOLATION POINTS.
+C
+C     INPUT PARAMETERS:
+C
+C       ND     : THE DIMENSION OF THE VECTORS DIF1, DIF2, DIF3, AND ROOT
+C
+C       N      : THE DEGREE OF THE JACOBI POLYNOMIAL, (i.e. THE NUMBER
+C                OF INTERIOR INTERPOLATION POINTS)
+C
+C       N0     : DETERMINES WHETHER X = 0 IS INCLUDED AS AN
+C                INTERPOLATION POINT
+C
+C                  N0 = 0  ==>  X = 0 IS NOT INCLUDED
+C                  N0 = 1  ==>  X = 0 IS INCLUDED
+C
+C       N1     : DETERMINES WHETHER X = 1 IS INCLUDED AS AN
+C                INTERPOLATION POINT
+C
+C                  N1 = 0  ==>  X = 1 IS NOT INCLUDED
+C                  N1 = 1  ==>  X = 1 IS INCLUDED
+C
+C       ALPHA  : THE VALUE OF ALPHA IN THE DESCRIPTION OF THE JACOBI
+C                POLYNOMIAL
+C
+C       BETA   : THE VALUE OF BETA IN THE DESCRIPTION OF THE JACOBI
+C                POLYNOMIAL
+C
+C       FOR A MORE COMPLETE EXPLANATION OF ALPHA AN BETA, SEE VILLADSEN
+C       AND MICHELSEN, PAGES 57 TO 59
+C
+C     OUTPUT PARAMETERS:
+C
+C       ROOT   : ONE DIMENSIONAL VECTOR CONTAINING ON EXIT THE
+C                N + N0 + N1 ZEROS OF THE NODE POLYNOMIAL USED IN THE
+C                INTERPOLATION ROUTINE
+C
+C       DIF1   : ONE DIMENSIONAL VECTOR CONTAINING THE FIRST DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C       DIF2   : ONE DIMENSIONAL VECTOR CONTAINING THE SECOND DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C       DIF3   : ONE DIMENSIONAL VECTOR CONTAINING THE THIRD DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C     COMMON BLOCKS:      NONE
+C
+C     REQUIRED ROUTINES:  VILERR, DIF
+C
+C***********************************************************************
+C
+      INTEGER           I,J,NT,IER
+      DOUBLE PRECISION  AB,AD,AP,Z1,Z,Y,X,XD,XN,XD1,XN1,XP,XP1,ZC
+      DOUBLE PRECISION  ZERO,ONE,TWO
+      LOGICAL           LSTOP
+C
+      PARAMETER ( ZERO = 0.0D+00, ONE = 1.0D+00, TWO = 2.0D+00 )
+C
+C -- ERROR CHECKING
+C
+      IF ((N0 .NE. 0) .AND. (N0 .NE. 1)) THEN
+        IER   = 1
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((N1 .NE. 0) .AND. (N1 .NE. 1)) THEN
+        IER   = 2
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF (ND .LT. (N + N0 + N1)) THEN
+        IER   = 3
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((N + N0 + N1) .LT. 1) THEN
+        IER   = 7
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+C -- FIRST EVALUATION OF COEFFICIENTS IN RECURSION FORMULAS.
+C -- RECURSION COEFFICIENTS ARE STORED IN DIF1 AND DIF2.
+C
+      AB      = ALPHA + BETA
+      AD      = BETA - ALPHA
+      AP      = BETA*ALPHA
+      DIF1(1) = (AD/(AB + TWO) + ONE)/TWO
+      DIF2(1) = ZERO
+C
+      IF(N .GE. 2) THEN
+        DO 10 I = 2,N
+C
+          Z1      = DBLE(I) - ONE
+          Z       = AB + 2*Z1
+          DIF1(I) = (AB*AD/Z/(Z + TWO) + ONE)/TWO
+C
+          IF (I .EQ. 2) THEN
+            DIF2(I) = (AB + AP + Z1)/Z/Z/(Z + ONE)
+          ELSE
+            Z       = Z*Z
+            Y       = Z1*(AB + Z1)
+            Y       = Y*(AP + Y)
+            DIF2(I) = Y/Z/(Z - ONE)
+          END IF
+C
+   10   CONTINUE
+      ELSE
+      END IF
+C
+C -- ROOT DETERMINATION BY NEWTON METHOD WITH SUPPRESSION OF
+C -- PREVIOUSLY DETERMINED ROOTS
+C
+      X = ZERO
+C
+      DO 20 I = 1,N
+C
+   25   CONTINUE
+        XD  = ZERO
+        XN  = ONE
+        XD1 = ZERO
+        XN1 = ZERO
+C
+        DO 30 J = 1,N
+          XP  = (DIF1(J) - X)*XN  - DIF2(J)*XD
+          XP1 = (DIF1(J) - X)*XN1 - DIF2(J)*XD1 - XN
+          XD  = XN
+          XD1 = XN1
+          XN  = XP
+          XN1 = XP1
+   30   CONTINUE
+C
+        ZC  = ONE
+        Z   = XN/XN1
+C
+        IF (I .NE. 1) THEN
+          DO 22 J = 2,I
+            ZC = ZC - Z/(X - ROOT(J-1))
+   22     CONTINUE
+        ELSE
+        END IF
+C
+        Z  = Z/ZC
+        X  = X - Z
+C
+        IF (DABS(Z) .GT. 1.D-09) THEN
+C
+C -- BACKWARD BRANCH
+C
+          GO TO 25
+        ELSE
+        END IF
+C
+        ROOT(I) = X
+        X = X + 0.0001D0
+C
+   20 CONTINUE
+C
+C -- ADD INTERPOLATION POINTS AT X = 0 AND/OR X = 1
+C
+      NT = N + N0 + N1
+C
+      IF (N0 .NE. 0) THEN
+        DO 31 I = 1,N
+          J = N + 1 - I
+          ROOT(J+1) = ROOT(J)
+   31   CONTINUE
+        ROOT(1) = ZERO
+      ELSE
+      END IF
+C
+      IF (N1 .EQ. 1) THEN
+        ROOT(NT) = ONE
+      ELSE
+      END IF
+C
+      CALL DIF ( NT, ROOT, DIF1, DIF2, DIF3 )
+C
+      RETURN
+      END
diff --git a/libcruft/villad/radau.f b/libcruft/villad/radau.f
new file mode 100644
index 0000000..1497889
--- /dev/null
+++ b/libcruft/villad/radau.f
@@ -0,0 +1,209 @@
+      SUBROUTINE RADAU
+     +  (
+     +  ND, N, N0, N1, ID, ALPHA, BETA, ROOT, DIF1, VECT
+     +  )
+C
+      INTEGER           ND, N, N0, N1, ID
+      DOUBLE PRECISION  ALPHA, BETA, ROOT(ND), DIF1(ND), VECT(ND)
+C
+C***********************************************************************
+C
+C     RADAU OR LOBATTO QUADRATURE
+C
+C     VILLADSEN AND MICHELSEN, PAGES 133-135, 419
+C
+C     INPUT PARAMETERS:
+C
+C       ND     : THE DIMENSION OF THE VECTORS DIF1, DIF2, DIF3, AND ROOT
+C
+C       N      : THE DEGREE OF THE JACOBI POLYNOMIAL, (i.e. THE NUMBER
+C                OF INTERIOR INTERPOLATION POINTS)
+C
+C       N0     : DETERMINES WHETHER X = 0 IS INCLUDED AS AN
+C                INTERPOLATION POINT
+C
+C                  N0 = 0  ==>  X = 0 IS NOT INCLUDED
+C                  N0 = 1  ==>  X = 0 IS INCLUDED
+C
+C       N1     : DETERMINES WHETHER X = 1 IS INCLUDED AS AN
+C                INTERPOLATION POINT
+C
+C                  N1 = 0  ==>  X = 1 IS NOT INCLUDED
+C                  N1 = 1  ==>  X = 1 IS INCLUDED
+C
+C       ID     : INDICATOR
+C
+C                  ID = 1  ==>  RADAU QUADRATURE WEIGHTS INCLUDING X = 1
+C                  ID = 2  ==>  RADAU QUADRATURE WEIGHTS INCLUDING X = 0
+C                  ID = 3  ==>  LOBATTO QUADRATURE WEIGHTS INCLUDING
+C                               BOTH X = 0 AND X = 1
+C
+C       ALPHA  : THE VALUE OF ALPHA IN THE DESCRIPTION OF THE JACOBI
+C                POLYNOMIAL
+C
+C       BETA   : THE VALUE OF BETA IN THE DESCRIPTION OF THE JACOBI
+C                POLYNOMIAL
+C
+C                FOR A MORE COMPLETE EXPLANATION OF ALPHA AN BETA, SEE
+C                VILLADSEN AND MICHELSEN, PAGES 57 TO 59
+C
+C       ROOT   : ONE DIMENSIONAL VECTOR CONTAINING ON EXIT THE
+C                N + N0 + N1 ZEROS OF THE NODE POLYNOMIAL USED IN THE
+C                INTERPOLATION ROUTINE
+C
+C       DIF1   : ONE DIMENSIONAL VECTOR CONTAINING THE FIRST DERIVATIVE
+C                OF THE NODE POLYNOMIAL AT THE ZEROS
+C
+C       THE NODE POLYNOMIAL IS GIVEN BY
+C
+C                     N0    (ALPHA',BETA')          N1
+C         P  (X)  =  X   * P (X)           * (X - 1)
+C          NT               N
+C
+C       THE ARGUMENTS ALPHA' AND BETA' TO BE USED IN JCOBI FOR
+C       CALCULATION OF ROOT AND DIF1 DEPEND ON WHETHER X = 0 , X = 1 OR
+C       BOTH ARE USED AS EXTRA QUADRATURE POINTS.  THUS:
+C
+C         ID = 1:  ALPHA' = ALPHA + 1, BETA' = BETA
+C         ID = 2:  ALPHA' = ALPHA    , BETA' = BETA + 1
+C         ID = 3:  ALPHA' = ALPHA + 1, BETA' = BETA + 1
+C
+C       NOTE:
+C
+C         ID = 1  REQUIRES THAT N0 = 0 OR 1, N1 = 1
+C         ID = 2  REQUIRES THAT N0 = 1     , N1 = 0 OR 1
+C         ID = 3  REQUIRES THAT N0 = 1     , N1 = 1
+C
+C     OUTPUT PARAMETERS:
+C
+C       VECT   : VECTOR OF THE NT COMPUTED QUADRATURE WEIGHTS,
+C                NORMALIZED SUCH THAT
+C
+C                   NT
+C                  SUM  VECT(I) = 1
+C                  I=1
+C
+C                FOR A MORE COMPLETE EXPLANATION SEE VILLADSEN AND
+C                MICHELSEN, PAGES 133 TO 135
+C
+C     COMMON BLOCKS:      NONE
+C
+C     REQUIRED ROUTINES:  VILERR
+C
+C***********************************************************************
+C
+      INTEGER           I,NT,IER
+      DOUBLE PRECISION  AX,S,X
+      DOUBLE PRECISION  ZERO,ONE
+      LOGICAL           LSTOP
+C
+      PARAMETER ( ZERO = 0.0D+00, ONE = 1.0D+00 )
+C
+C -- ERROR CHECKING
+C
+      IF ((N0 .NE. 0) .AND. (N0 .NE. 1)) THEN
+        IER   = 1
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((N1 .NE. 0) .AND. (N1 .NE. 1)) THEN
+        IER   = 2
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF (ND .LT. (N + N0 + N1)) THEN
+        IER   = 3
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((N + N0 + N1) .LT. 1) THEN
+        IER   = 7
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((ID .NE. 1) .AND. (ID.NE. 2) .AND. (ID .NE. 3)) THEN
+        IER   = 8
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((ID .EQ. 1) .AND. (N1 .NE. 1)) THEN
+        IER   = 9
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((ID .EQ. 2) .AND. (N0 .NE. 1)) THEN
+        IER   = 10
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+      IF ((ID .EQ. 3) .AND. ((N0 .NE. 1) .OR. (N1 .NE. 1))) THEN
+        IER   = 11
+        LSTOP = .TRUE.
+        CALL VILERR(IER,LSTOP)
+      ELSE
+      END IF
+C
+C -- EVALUATE RADAU OR LOBATTO QUADRATURE WEIGHTS
+C
+      S  = ZERO
+      NT = N + N0 + N1
+C
+      DO 40 I = 1,NT
+C
+        X = ROOT(I)
+C
+        IF      (ID .EQ. 1) THEN
+          AX = X
+          IF (N0 .EQ. 0) THEN
+            AX = ONE/AX
+          ELSE
+          END IF
+        ELSE IF (ID .EQ. 2) THEN
+          AX = ONE - X
+          IF (N1 .EQ. 0) THEN
+            AX = ONE/AX
+          ELSE
+          END IF
+        ELSE IF (ID .EQ. 3) THEN
+          AX = ONE
+        ELSE
+        END IF
+C
+        VECT(I) = AX/DIF1(I)**2
+C
+   40 CONTINUE
+C
+      IF (ID .NE. 2) THEN
+        VECT(NT) = VECT(NT)/(ONE + ALPHA)
+      ELSE
+      END IF
+C
+      IF (ID .GT. 1) THEN
+        VECT(1)  = VECT( 1)/(ONE + BETA)
+      ELSE
+      END IF
+C
+      DO 50 I = 1,NT
+        S = S + VECT(I)
+   50 CONTINUE
+C
+      DO 60 I = 1,NT
+        VECT(I) = VECT(I)/S
+   60 CONTINUE
+C
+      RETURN
+      END
diff --git a/libcruft/villad/vilerr.f b/libcruft/villad/vilerr.f
new file mode 100644
index 0000000..9993ec2
--- /dev/null
+++ b/libcruft/villad/vilerr.f
@@ -0,0 +1,89 @@
+      SUBROUTINE VILERR ( IER, LSTOP )
+C
+      INTEGER  IER
+      LOGICAL  LSTOP
+C
+C***********************************************************************
+C
+C     THIS SUBROUTINE HANDLES ERRORS FOR THE SUBROUTINES JCOBI, DFOPR,
+C     INTRP, AND RADAU GIVEN BY VILLADSEN AND MICHELSEN.
+C
+C     PARAMETER LIST:
+C
+C       IER    : ERROR NUMBER
+C       LSTOP  : LOGICAL FLAG
+C
+C                LSTOP = .TRUE.   ==>  FATAL ERROR, PROGRAM TERMINATION
+C                LSTOP = .FALSE.  ==>  WARNING ERROR, NORMAL RETURN
+C
+C     COMMON BLOCKS:      NONE
+C
+C     REQUIRED ROUTINES:  NONE
+C
+C***********************************************************************
+C
+C -- BEGIN
+C
+      IF      ( IER .EQ.  1) THEN
+C
+        WRITE(*,*) '** VILERR : Illegal value for N0 '
+C
+      ELSE IF ( IER .EQ.  2) THEN
+C
+        WRITE(*,*) '** VILERR : Illegal value for N1 '
+C
+      ELSE IF ( IER .EQ.  3 ) THEN
+C
+        WRITE(*,*) '** VILERR : Insufficient dimension for problem '
+C
+      ELSE IF ( IER .EQ.  4 ) THEN
+C
+        WRITE(*,*) '** VILERR : Index less than zero in DFOPR '
+C
+      ELSE IF ( IER .EQ.  5 ) THEN
+C
+        WRITE(*,*) '** VILERR : Index greater than NTOTAL in DFOPR '
+C
+      ELSE IF ( IER .EQ.  6 ) THEN
+C
+        WRITE(*,*) '** VILERR : Illegal ID in DFOPR '
+C
+      ELSE IF ( IER .EQ.  7 ) THEN
+C
+        WRITE(*,*) '** VILERR : Number of interpolation points '
+        WRITE(*,*) '            less than 1 '
+C
+      ELSE IF ( IER .EQ.  8 ) THEN
+C
+        WRITE(*,*) '** VILERR : Illegal ID in RADAU '
+C
+      ELSE IF ( IER .EQ.  9 ) THEN
+C
+        WRITE(*,*) '** VILERR : ID = 1 but N1 not equal to 1 in RADAU '
+C
+      ELSE IF ( IER .EQ. 10 ) THEN
+C
+        WRITE(*,*) '** VILERR : ID = 2 but N0 not equal to 1 in RADAU '
+C
+      ELSE IF ( IER .EQ. 11 ) THEN
+C
+        WRITE(*,*) '** VILERR : ID = 3 but N0 not equal to 1 or '
+        WRITE(*,*) '            N1 not equal to 1 in RADAU '
+C
+      ELSE
+C
+        WRITE(*,*) 'UNRECOGNIZED ERROR FLAG SET FOR VILERR '
+C
+      END IF
+C
+      IF ( LSTOP ) THEN
+C
+C -- PROGRAM EXECUTION TERMINATES HERE
+C
+        CALL XSTOPX (' ')
+C
+      ELSE
+      END IF
+C
+      RETURN
+      END
diff --git a/liboctave/Array-C.cc b/liboctave/Array-C.cc
new file mode 100644
index 0000000..2e462d2
--- /dev/null
+++ b/liboctave/Array-C.cc
@@ -0,0 +1,118 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of Complex values.
+
+#include "oct-cmplx.h"
+#include "lo-mappers.h"
+
+#include "Array.h"
+#include "Array.cc"
+#include "oct-sort.cc"
+
+template <>
+inline bool
+sort_isnan<Complex> (const Complex& x)
+{
+  return xisnan (x);
+}
+
+static bool
+nan_ascending_compare (const Complex& x, const Complex& y)
+{
+  return (xisnan (y)
+	  ? ! xisnan (x)
+	  : ((std::abs (x) < std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x)))));
+}
+
+static bool
+nan_descending_compare (const Complex& x, const Complex& y)
+{
+  return (xisnan (x)
+	  ? ! xisnan (y)
+	  : ((std::abs (x) > std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x)))));
+}
+
+Array<Complex>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<Complex>& a , bool allow_chk)
+{
+  Array<Complex>::compare_fcn_type result = 0;
+
+  if (allow_chk)
+    {
+      octave_idx_type k = 0;
+      for (; k < a.numel () && ! xisnan (a(k)); k++) ;
+      if (k == a.numel ())
+        {
+          if (mode == ASCENDING)
+            result = octave_sort<Complex>::ascending_compare;
+          else if (mode == DESCENDING)
+            result = octave_sort<Complex>::descending_compare;
+        }
+    }
+
+  if (! result)
+    {
+      if (mode == ASCENDING)
+        result = nan_ascending_compare;
+      else if (mode == DESCENDING)
+        result = nan_descending_compare;
+    }
+
+  return result;
+}
+
+INSTANTIATE_ARRAY_SORT (Complex);
+
+INSTANTIATE_ARRAY (Complex, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<Complex>;
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class OCTAVE_API ArrayN<Complex>;
+
+template OCTAVE_API std::ostream& operator << (std::ostream&, const ArrayN<Complex>&);
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+#ifdef _MSC_VER
+template class OCTAVE_API DiagArray2<Complex>::Proxy;
+#endif
+template class OCTAVE_API DiagArray2<Complex>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-b.cc b/liboctave/Array-b.cc
new file mode 100644
index 0000000..5f44033
--- /dev/null
+++ b/liboctave/Array-b.cc
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of bool values.
+
+#include "Array.h"
+#include "Array.cc"
+#include "oct-sort.cc"
+
+INSTANTIATE_ARRAY_SORT (bool);
+
+INSTANTIATE_ARRAY (bool, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<bool>;
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class OCTAVE_API ArrayN<bool>;
+
+template OCTAVE_API std::ostream& operator << (std::ostream&, const ArrayN<bool>&);
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+template class OCTAVE_API DiagArray2<bool>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-ch.cc b/liboctave/Array-ch.cc
new file mode 100644
index 0000000..babfa53
--- /dev/null
+++ b/liboctave/Array-ch.cc
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of char values.
+
+#include "Array.h"
+#include "Array.cc"
+#include "oct-sort.cc"
+
+INSTANTIATE_ARRAY_SORT (char);
+
+INSTANTIATE_ARRAY (char, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<char>;
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class OCTAVE_API ArrayN<char>;
+
+template OCTAVE_API std::ostream& operator << (std::ostream&, const ArrayN<char>&);
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+template class OCTAVE_API DiagArray2<char>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-d.cc b/liboctave/Array-d.cc
new file mode 100644
index 0000000..f7c7859
--- /dev/null
+++ b/liboctave/Array-d.cc
@@ -0,0 +1,114 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of double values.
+
+#include "lo-mappers.h"
+#include "Array.h"
+#include "Array.cc"
+#include "oct-locbuf.h"
+
+#define INLINE_ASCENDING_SORT
+#define INLINE_DESCENDING_SORT
+#include "oct-sort.cc"
+
+template <>
+inline bool
+sort_isnan<double> (double x)
+{
+  return xisnan (x);
+}
+
+static bool
+nan_ascending_compare (double x, double y)
+{
+  return xisnan (y) ? ! xisnan (x) : x < y;
+}
+
+static bool
+nan_descending_compare (double x, double y)
+{
+  return xisnan (x) ? ! xisnan (y) : x > y;
+}
+
+Array<double>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<double>& a , bool allow_chk)
+{
+  Array<double>::compare_fcn_type result = 0;
+
+  if (allow_chk)
+    {
+      octave_idx_type k = 0;
+      for (; k < a.numel () && ! xisnan (a(k)); k++) ;
+      if (k == a.numel ())
+        {
+          if (mode == ASCENDING)
+            result = octave_sort<double>::ascending_compare;
+          else if (mode == DESCENDING)
+            result = octave_sort<double>::descending_compare;
+        }
+    }
+
+  if (! result)
+    {
+      if (mode == ASCENDING)
+        result = nan_ascending_compare;
+      else if (mode == DESCENDING)
+        result = nan_descending_compare;
+    }
+
+  return result;
+}
+
+INSTANTIATE_ARRAY_SORT (double);
+
+INSTANTIATE_ARRAY (double, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<double>;
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class OCTAVE_API ArrayN<double>;
+
+template OCTAVE_API std::ostream& operator << (std::ostream&, const ArrayN<double>&);
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+#ifdef _MSC_VER
+template class OCTAVE_API DiagArray2<double>::Proxy;
+#endif
+template class OCTAVE_API DiagArray2<double>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-f.cc b/liboctave/Array-f.cc
new file mode 100644
index 0000000..a41b444
--- /dev/null
+++ b/liboctave/Array-f.cc
@@ -0,0 +1,114 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of float values.
+
+#include "lo-mappers.h"
+#include "Array.h"
+#include "Array.cc"
+#include "oct-locbuf.h"
+
+#define INLINE_ASCENDING_SORT
+#define INLINE_DESCENDING_SORT
+#include "oct-sort.cc"
+
+template <>
+inline bool
+sort_isnan<float> (float x)
+{
+  return xisnan (x);
+}
+
+static bool
+nan_ascending_compare (float x, float y)
+{
+  return xisnan (y) ? ! xisnan (x) : x < y;
+}
+
+static bool
+nan_descending_compare (float x, float y)
+{
+  return xisnan (x) ? ! xisnan (y) : x > y;
+}
+
+Array<float>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<float>& a , bool allow_chk)
+{
+  Array<float>::compare_fcn_type result = 0;
+
+  if (allow_chk)
+    {
+      octave_idx_type k = 0;
+      for (; k < a.numel () && ! xisnan (a(k)); k++) ;
+      if (k == a.numel ())
+        {
+          if (mode == ASCENDING)
+            result = octave_sort<float>::ascending_compare;
+          else if (mode == DESCENDING)
+            result = octave_sort<float>::descending_compare;
+        }
+    }
+
+  if (! result)
+    {
+      if (mode == ASCENDING)
+        result = nan_ascending_compare;
+      else if (mode == DESCENDING)
+        result = nan_descending_compare;
+    }
+
+  return result;
+}
+
+INSTANTIATE_ARRAY_SORT (float);
+
+INSTANTIATE_ARRAY (float, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<float>;
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class OCTAVE_API ArrayN<float>;
+
+template OCTAVE_API std::ostream& operator << (std::ostream&, const ArrayN<float>&);
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+#ifdef _MSC_VER
+template class OCTAVE_API DiagArray2<float>::Proxy;
+#endif
+template class OCTAVE_API DiagArray2<float>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-fC.cc b/liboctave/Array-fC.cc
new file mode 100644
index 0000000..8fb7ee6
--- /dev/null
+++ b/liboctave/Array-fC.cc
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of FloatComplex values.
+
+#include "oct-cmplx.h"
+#include "lo-mappers.h"
+
+#include "Array.h"
+#include "Array.cc"
+#include "oct-sort.cc"
+
+template <>
+inline bool
+sort_isnan<FloatComplex> (const FloatComplex& x)
+{
+  return xisnan (x);
+}
+
+static bool
+nan_ascending_compare (const FloatComplex& x, const FloatComplex& y)
+{
+  return (xisnan (y)
+	  ? ! xisnan (x)
+	  : ((std::abs (x) < std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x)))));
+}
+
+static bool
+nan_descending_compare (const FloatComplex& x, const FloatComplex& y)
+{
+  return (xisnan (x)
+	  ? ! xisnan (y)
+	  : ((std::abs (x) > std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x)))));
+}
+
+Array<FloatComplex>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<FloatComplex>& a,
+		     bool allow_chk)
+{
+  Array<FloatComplex>::compare_fcn_type result = 0;
+
+  if (allow_chk)
+    {
+      octave_idx_type k = 0;
+      for (; k < a.numel () && ! xisnan (a(k)); k++) ;
+      if (k == a.numel ())
+        {
+          if (mode == ASCENDING)
+            result = octave_sort<FloatComplex>::ascending_compare;
+          else if (mode == DESCENDING)
+            result = octave_sort<FloatComplex>::descending_compare;
+        }
+    }
+
+  if (! result)
+    {
+      if (mode == ASCENDING)
+        result = nan_ascending_compare;
+      else if (mode == DESCENDING)
+        result = nan_descending_compare;
+    }
+
+  return result;
+}
+
+INSTANTIATE_ARRAY_SORT (FloatComplex);
+
+INSTANTIATE_ARRAY (FloatComplex, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<FloatComplex>;
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class OCTAVE_API ArrayN<FloatComplex>;
+
+template OCTAVE_API std::ostream& operator << (std::ostream&, const ArrayN<FloatComplex>&);
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+#ifdef _MSC_VER
+template class OCTAVE_API DiagArray2<FloatComplex>::Proxy;
+#endif
+template class OCTAVE_API DiagArray2<FloatComplex>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-i.cc b/liboctave/Array-i.cc
new file mode 100644
index 0000000..e014427
--- /dev/null
+++ b/liboctave/Array-i.cc
@@ -0,0 +1,84 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-inttypes.h"
+
+// Instantiate Arrays of integer values.
+
+#include "Array.h"
+#include "Array.cc"
+
+#define INLINE_ASCENDING_SORT
+#define INLINE_DESCENDING_SORT
+#include "oct-sort.cc"
+
+INSTANTIATE_ARRAY_SORT (int);
+INSTANTIATE_ARRAY_SORT (long);
+#if defined (HAVE_LONG_LONG_INT)
+INSTANTIATE_ARRAY_SORT (long long);
+#endif
+
+INSTANTIATE_ARRAY (int, OCTAVE_API);
+INSTANTIATE_ARRAY (long, OCTAVE_API);
+#if defined (HAVE_LONG_LONG_INT)
+INSTANTIATE_ARRAY (long long, OCTAVE_API);
+#endif
+
+INSTANTIATE_ARRAY_SORT (octave_int8);
+INSTANTIATE_ARRAY_SORT (octave_int16);
+INSTANTIATE_ARRAY_SORT (octave_int32);
+INSTANTIATE_ARRAY_SORT (octave_int64);
+
+INSTANTIATE_ARRAY (octave_int8, OCTAVE_API);
+INSTANTIATE_ARRAY (octave_int16, OCTAVE_API);
+INSTANTIATE_ARRAY (octave_int32, OCTAVE_API);
+INSTANTIATE_ARRAY (octave_int64, OCTAVE_API);
+
+INSTANTIATE_ARRAY_SORT (octave_uint8);
+INSTANTIATE_ARRAY_SORT (octave_uint16);
+INSTANTIATE_ARRAY_SORT (octave_uint32);
+INSTANTIATE_ARRAY_SORT (octave_uint64);
+
+INSTANTIATE_ARRAY (octave_uint8, OCTAVE_API);
+INSTANTIATE_ARRAY (octave_uint16, OCTAVE_API);
+INSTANTIATE_ARRAY (octave_uint32, OCTAVE_API);
+INSTANTIATE_ARRAY (octave_uint64, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<int>;
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+template class OCTAVE_API DiagArray2<int>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-idx-vec.cc b/liboctave/Array-idx-vec.cc
new file mode 100644
index 0000000..43182cf
--- /dev/null
+++ b/liboctave/Array-idx-vec.cc
@@ -0,0 +1,42 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2003, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of integer values.
+
+#include "idx-vector.h"
+
+#include "Array.h"
+#include "Array.cc"
+
+NO_INSTANTIATE_ARRAY_SORT (idx_vector);
+
+INSTANTIATE_ARRAY (idx_vector, OCTAVE_API);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-s.cc b/liboctave/Array-s.cc
new file mode 100644
index 0000000..481e695
--- /dev/null
+++ b/liboctave/Array-s.cc
@@ -0,0 +1,54 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 1998, 2001, 2003, 2005, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Arrays of short int values.
+
+#include "Array.h"
+#include "Array.cc"
+
+#define INLINE_ASCENDING_SORT
+#define INLINE_DESCENDING_SORT
+#include "oct-sort.cc"
+
+INSTANTIATE_ARRAY_SORT (short);
+
+INSTANTIATE_ARRAY (short, OCTAVE_API);
+
+#include "Array2.h"
+
+template class Array2<short>;
+
+#include "DiagArray2.h"
+#include "DiagArray2.cc"
+
+template class DiagArray2<short>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-str.cc b/liboctave/Array-str.cc
new file mode 100644
index 0000000..5fff9cc
--- /dev/null
+++ b/liboctave/Array-str.cc
@@ -0,0 +1,43 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2003, 2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+// Instantiate Arrays of strings.
+
+#include "Array.h"
+#include "Array.cc"
+#include "oct-sort.cc"
+
+INSTANTIATE_ARRAY_SORT (std::string);
+
+INSTANTIATE_ARRAY (std::string, OCTAVE_API);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-util.cc b/liboctave/Array-util.cc
new file mode 100644
index 0000000..8e64cea
--- /dev/null
+++ b/liboctave/Array-util.cc
@@ -0,0 +1,532 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array-util.h"
+#include "dim-vector.h"
+#include "lo-error.h"
+
+bool
+index_in_bounds (const Array<octave_idx_type>& ra_idx,
+		 const dim_vector& dimensions)
+{
+  bool retval = true;
+
+  int n = ra_idx.length ();
+
+  if (n == dimensions.length ())
+    {
+      for (int i = 0; i < n; i++)
+	{
+	  if (ra_idx(i) < 0 || ra_idx(i) >= dimensions(i))
+	    {
+	      retval = false;
+	      break;
+	    }
+	}
+    }
+  else
+    retval = false;
+
+  return retval;
+}
+
+void
+increment_index (Array<octave_idx_type>& ra_idx, const dim_vector& dimensions,
+		 int start_dimension)
+{
+  ra_idx(start_dimension)++;
+
+  int n = ra_idx.length () - 1;
+  int nda = dimensions.length ();
+
+  for (int i = start_dimension; i < n; i++)
+    {
+      if (ra_idx(i) < (i < nda ? dimensions(i) : 1))
+ 	break;
+      else
+ 	{
+ 	  ra_idx(i) = 0;
+ 	  ra_idx(i+1)++;
+ 	}
+    }
+}
+
+octave_idx_type
+get_scalar_idx (Array<octave_idx_type>& idx, dim_vector& dims)
+{
+  octave_idx_type retval (-1);
+
+  int n = idx.length ();
+
+  if (n > 0)
+    {
+      retval = idx(--n);
+
+      while (--n >= 0)
+	{      		
+	  retval *= dims (n);
+	
+	  retval += idx(n);
+	}
+    }
+  return retval;
+}
+
+octave_idx_type
+num_ones (const Array<octave_idx_type>& ra_idx)
+{
+  octave_idx_type retval = 0;
+
+  for (octave_idx_type i = 0; i < ra_idx.length (); i++)
+    {
+      if (ra_idx (i) == 1)
+	retval++;
+    }
+
+  return retval;
+}
+
+bool
+is_scalar (const dim_vector& dim)
+{
+  bool retval = true;
+
+  int n = dim.length ();
+
+  if (n == 0)
+    {
+      retval = false;
+    }
+  else
+    {
+      for (int i = 0; i < n; i ++)
+	{
+	  if (dim (i) != 1)
+	    {
+	      retval = false;
+	
+	      break;
+	    }
+	}
+    }
+  return retval;
+}
+
+bool
+is_vector (const dim_vector& dim)
+{
+  int m = 0;
+  int n = dim.length ();
+
+  if (n == 0)
+    m = 2;
+  else
+    {
+      for (int i = 0; i < n; i ++)
+	if (dim (i) > 1)
+	  m++;
+	else if (dim(i) < 1)
+	  m += 2;
+    }
+
+  return (m < 2);
+}
+
+bool
+any_ones (const Array<octave_idx_type>& arr)
+{
+  bool retval = false;
+
+  for (octave_idx_type i = 0; i < arr.length (); i++)
+    {
+      if (arr (i) == 1)
+	{
+	  retval = true;
+	
+	  break;
+	}
+    }
+  return retval;
+}
+
+octave_idx_type
+compute_index (const Array<octave_idx_type>& ra_idx, const dim_vector& dims)
+{
+  octave_idx_type retval = -1;
+
+  int n = dims.length ();
+
+  if (n > 0 && n == ra_idx.length ())
+    {
+      retval = ra_idx(--n);
+
+      while (--n >= 0)
+	{
+	  retval *= dims(n);
+	
+	  retval += ra_idx(n);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("ArrayN<T>::compute_index: invalid ra_idxing operation");
+
+  return retval;
+}
+
+Array<octave_idx_type>
+conv_to_int_array (const Array<idx_vector>& a)
+{
+  Array<octave_idx_type> retval (a.length ());
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    retval (i) = a(i).elem (0);
+
+  return retval;
+}
+
+Array<idx_vector>
+conv_to_array (const idx_vector *tmp, const octave_idx_type len)
+{
+  Array<idx_vector> retval (len);
+
+  for (octave_idx_type i = 0; i < len; i++)
+      retval (i) = tmp[i];
+
+  return retval;
+}
+
+dim_vector
+freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok)
+{
+  dim_vector retval;
+
+  int n = ra_idx.length ();
+
+  assert (n == dimensions.length ());
+
+  retval.resize (n);
+
+  static const char *tag[3] = { "row", "column", 0 };
+
+  for (int i = 0; i < n; i++)
+    retval(i) = ra_idx(i).freeze (dimensions(i), tag[i < 2 ? i : 3],
+				  resize_ok);
+
+  return retval;
+}
+
+bool
+vector_equivalent (const dim_vector& dv)
+{
+  int n = dv.length ();
+
+  bool found_first = false;
+
+  for (int i = 0; i < n; i++)
+    {
+      if (dv(i) != 1)
+        {
+	  if (! found_first)
+	    found_first = true;
+	  else
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+bool
+all_ok (const Array<idx_vector>& ra_idx)
+{
+  bool retval = true;
+
+  octave_idx_type n = ra_idx.length ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      if (! ra_idx(i))
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+bool
+any_orig_empty (const Array<idx_vector>& ra_idx)
+{
+  bool retval = false;
+
+  octave_idx_type n = ra_idx.length ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      if (ra_idx(i).orig_empty ())
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+bool
+all_colon_equiv (const Array<idx_vector>& ra_idx,
+		 const dim_vector& frozen_lengths)
+{
+  bool retval = true;
+
+  octave_idx_type idx_n = ra_idx.length ();
+
+  int n = frozen_lengths.length ();
+
+  assert (idx_n == n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      if (! ra_idx(i).is_colon_equiv (frozen_lengths(i)))
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+bool
+all_ones (const Array<octave_idx_type>& arr)
+{
+  bool retval = true;
+
+  for (octave_idx_type i = 0; i < arr.length (); i++)
+    {
+      if (arr(i) != 1)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+Array<octave_idx_type>
+get_elt_idx (const Array<idx_vector>& ra_idx,
+	     const Array<octave_idx_type>& result_idx)
+{
+  octave_idx_type n = ra_idx.length ();
+
+  Array<octave_idx_type> retval (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    retval(i) = ra_idx(i).elem (result_idx(i));
+
+  return retval;
+}
+
+Array<octave_idx_type>
+get_ra_idx (octave_idx_type idx, const dim_vector& dims)
+{
+  Array<octave_idx_type> retval;
+
+  int n_dims = dims.length ();
+
+  retval.resize (n_dims);
+
+  for (int i = 0; i < n_dims; i++)
+    retval(i) = 0;
+
+  assert (idx > 0 || idx < dims.numel ());
+
+  for (octave_idx_type i = 0; i < idx; i++)
+    increment_index (retval, dims);
+
+  // FIXME -- the solution using increment_index is not
+  // efficient.
+
+#if 0
+  octave_idx_type var = 1;
+  for (int i = 0; i < n_dims; i++)
+    {
+      std::cout << "idx: " << idx << ", var: " << var
+		<< ", dims(" << i << "): " << dims(i) <<"\n";
+      retval(i) = ((int)floor(((idx) / (double)var))) % dims(i);
+      idx -= var * retval(i);
+      var = dims(i);
+    }
+#endif
+
+  return retval;
+}
+
+dim_vector
+zero_dims_inquire (const Array<idx_vector>& ia, const dim_vector& rhdv)
+{
+  int ial = ia.length (), rhdvl = rhdv.length ();
+  dim_vector rdv;
+  rdv.resize (ial);
+  bool *scalar = new bool[ial], *colon = new bool[ial];
+  // Mark scalars and colons, count non-scalar indices.
+  int nonsc = 0; 
+  bool all_colons = true;
+  for (int i = 0; i < ial; i++)
+    {
+      // FIXME -- should we check for length() instead?
+      scalar[i] = ia(i).is_scalar ();
+      colon[i] = ia(i).is_colon ();
+      if (! scalar[i]) nonsc++;
+      if (! colon[i]) rdv(i) = ia(i).extent (0);
+      all_colons = all_colons && colon[i];
+    }
+
+  // If the number of nonscalar indices matches the dimensionality of
+  // RHS, we try an exact match, inquiring even singleton dimensions.
+  if (all_colons)
+    {
+      rdv = rhdv;
+      rdv.resize(ial, 1);
+    }
+  else if (nonsc == rhdvl)
+    {
+      for (int i = 0, j = 0; i < ial; i++)
+        {
+          if (scalar[i]) continue;
+          if (colon[i])
+            rdv(i) = rhdv(j);
+          j++;
+        }
+    }
+  else
+    {
+      dim_vector rhdv0 = rhdv;
+      rhdv0.chop_all_singletons ();
+      int rhdv0l = rhdv0.length ();
+      for (int i = 0, j = 0; i < ial; i++)
+        {
+          if (scalar[i]) continue;
+          if (colon[i])
+            rdv(i) =  (j < rhdv0l) ? rhdv0(j++) : 1;
+        }
+    }
+
+  delete [] scalar;
+  delete [] colon;
+
+  return rdv;
+}
+
+dim_vector
+zero_dims_inquire (const idx_vector& i, const idx_vector& j,
+		   const dim_vector& rhdv)
+{
+  bool icol = i.is_colon (), jcol = j.is_colon ();
+  dim_vector rdv;
+  if (icol && jcol && rhdv.length () == 2)
+    {
+      rdv(0) = rhdv(0);
+      rdv(1) = rhdv(1);
+    }
+  else if (rhdv.length () == 2
+           && ! i.is_scalar () && ! j.is_scalar ())
+    {
+      rdv(0) = icol ? rhdv(0) : i.extent (0);
+      rdv(1) = jcol ? rhdv(1) : j.extent (0);
+    }
+  else
+    {
+      dim_vector rhdv0 = rhdv;
+      rhdv0.chop_all_singletons ();
+      int k = 0;
+      rdv(0) = i.extent (0);
+      if (icol)
+        rdv(0) = rhdv0(k++);
+      else if (! i.is_scalar ())
+        k++;
+      rdv(1) = j.extent (0);
+      if (jcol)
+        rdv(1) = rhdv0(k++);
+      else if (! j.is_scalar ())
+        k++;
+    }
+
+  return rdv;
+}
+
+int
+permute_vector_compare (const void *a, const void *b)
+{
+  const permute_vector *pva = static_cast<const permute_vector *> (a);
+  const permute_vector *pvb = static_cast<const permute_vector *> (b);
+
+  return pva->pidx > pvb->pidx;
+}
+
+void
+gripe_nan_to_logical_conversion (void)
+{
+  (*current_liboctave_error_handler) ("invalid conversion of NaN to logical");
+}
+
+void
+gripe_nonconformant (const char *op, int op1_len, int op2_len)
+{
+  (*current_liboctave_error_handler)
+    ("%s: nonconformant arguments (op1 len: %d, op2 len: %d)",
+     op, op1_len, op2_len);
+}
+
+void
+gripe_nonconformant (const char *op, int op1_nr, int op1_nc,
+		     int op2_nr, int op2_nc)
+{
+  (*current_liboctave_error_handler)
+    ("%s: nonconformant arguments (op1 is %dx%d, op2 is %dx%d)",
+     op, op1_nr, op1_nc, op2_nr, op2_nc);
+}
+
+void
+gripe_nonconformant (const char *op, dim_vector& op1_dims,
+		     dim_vector& op2_dims)
+{
+  std::string op1_dims_str = op1_dims.str ();
+  std::string op2_dims_str = op2_dims.str ();
+
+  (*current_liboctave_error_handler)
+    ("%s: nonconformant arguments (op1 is %s, op2 is %s)",
+     op, op1_dims_str.c_str (), op2_dims_str.c_str ());
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-util.h b/liboctave/Array-util.h
new file mode 100644
index 0000000..657bcd4
--- /dev/null
+++ b/liboctave/Array-util.h
@@ -0,0 +1,107 @@
+/*
+
+Copyright (C) 2000, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Array_util_h)
+#define octave_Array_util_h 1
+
+#include <cassert>
+
+#include "Array.h"
+#include "dim-vector.h"
+#include "idx-vector.h"
+#include "lo-error.h"
+
+extern OCTAVE_API bool index_in_bounds (const Array<octave_idx_type>& ra_idx,
+			     const dim_vector& dimensions);
+
+extern OCTAVE_API void increment_index (Array<octave_idx_type>& ra_idx,
+			     const dim_vector& dimensions,
+			     int start_dimension = 0);
+
+extern OCTAVE_API octave_idx_type get_scalar_idx (Array<octave_idx_type>& idx, dim_vector& dims);
+
+extern OCTAVE_API octave_idx_type num_ones (const Array<octave_idx_type>& ra_idx);
+
+extern OCTAVE_API bool is_scalar (const dim_vector& dim);
+
+extern OCTAVE_API bool is_vector (const dim_vector& dim);
+
+extern OCTAVE_API bool any_ones (const Array<octave_idx_type>& arr);
+
+extern OCTAVE_API octave_idx_type compute_index (const Array<octave_idx_type>& ra_idx, const dim_vector& dims);
+
+extern OCTAVE_API Array<octave_idx_type> conv_to_int_array (const Array<idx_vector>& a);
+
+extern OCTAVE_API Array<idx_vector> conv_to_array (const idx_vector *tmp, const octave_idx_type len);
+
+extern OCTAVE_API dim_vector freeze (Array<idx_vector>& ra_idx,
+			  const dim_vector& dimensions, int resize_ok);
+
+extern OCTAVE_API bool vector_equivalent (const dim_vector& dv);
+
+extern OCTAVE_API bool all_ok (const Array<idx_vector>& ra_idx);
+
+extern OCTAVE_API bool any_orig_empty (const Array<idx_vector>& ra_idx);
+
+extern OCTAVE_API bool all_colon_equiv (const Array<idx_vector>& ra_idx,
+			     const dim_vector& frozen_lengths);
+
+extern OCTAVE_API bool all_ones (const Array<octave_idx_type>& arr);
+
+extern OCTAVE_API Array<octave_idx_type> get_elt_idx (const Array<idx_vector>& ra_idx,
+			       const Array<octave_idx_type>& result_idx);
+
+extern OCTAVE_API Array<octave_idx_type> get_ra_idx (octave_idx_type idx, const dim_vector& dims);
+
+extern OCTAVE_API dim_vector zero_dims_inquire (const Array<idx_vector>& ia,
+                                                const dim_vector& rhdv);
+
+extern OCTAVE_API dim_vector zero_dims_inquire (const idx_vector& i, const idx_vector& j,
+                                                const dim_vector& rhdv);
+
+struct
+permute_vector
+{
+  octave_idx_type pidx;
+  octave_idx_type iidx;
+};
+
+extern int OCTAVE_API permute_vector_compare (const void *a, const void *b);
+
+extern void OCTAVE_API gripe_nan_to_logical_conversion (void);
+
+extern void OCTAVE_API gripe_nonconformant (const char *op, int op1_len, int op2_len);
+
+extern void OCTAVE_API gripe_nonconformant (const char *op, int op1_nr, int op1_nc,
+				 int op2_nr, int op2_nc);
+
+
+extern void OCTAVE_API gripe_nonconformant (const char *op, dim_vector& op1_dims,
+				 dim_vector& op2_dims);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array-voidp.cc b/liboctave/Array-voidp.cc
new file mode 100644
index 0000000..9caabf6
--- /dev/null
+++ b/liboctave/Array-voidp.cc
@@ -0,0 +1,50 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2003, 2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+// Instantiate Arrays of void *.
+
+#include "Array.h"
+#include "Array.cc"
+
+NO_INSTANTIATE_ARRAY_SORT (void *);
+
+INSTANTIATE_ARRAY (void *, OCTAVE_API);
+
+#include "Array2.h"
+
+template class OCTAVE_API Array2<void *>;
+
+#include "Array3.h"
+
+template class OCTAVE_API Array3<void *>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array.cc b/liboctave/Array.cc
new file mode 100644
index 0000000..084c10a
--- /dev/null
+++ b/liboctave/Array.cc
@@ -0,0 +1,2709 @@
+// Template array classes
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007 John W. Eaton 
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <climits>
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+#include <new>
+
+#include "Array.h"
+#include "Array-util.h"
+#include "idx-vector.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+// One dimensional array class.  Handles the reference counting for
+// all the derived classes.
+
+template <class T>
+void
+Array<T>::make_unique (void)
+{
+  if (rep->count > 1)
+    {
+      --rep->count;
+      rep = new ArrayRep (slice_data, slice_len, true);
+      slice_data = rep->data;
+    }
+}
+
+template <class T>
+Array<T>::Array (const Array<T>& a, const dim_vector& dv)
+  : rep (a.rep), dimensions (dv), 
+    slice_data (a.slice_data), slice_len (a.slice_len)
+{
+  rep->count++;
+
+  if (a.numel () < dv.numel ())
+    (*current_liboctave_error_handler)
+      ("Array::Array (const Array&, const dim_vector&): dimension mismatch");
+}
+
+template <class T>
+Array<T>::~Array (void)
+{
+  if (--rep->count <= 0)
+    delete rep;
+}
+
+template <class T>
+Array<T>&
+Array<T>::operator = (const Array<T>& a)
+{
+  if (this != &a)
+    {
+      if (--rep->count <= 0)
+	delete rep;
+
+      rep = a.rep;
+      rep->count++;
+
+      dimensions = a.dimensions;
+      slice_data = a.slice_data;
+      slice_len = a.slice_len;
+    }
+
+  return *this;
+}
+
+template <class T>
+void
+Array<T>::fill (const T& val)
+{
+  if (rep->count > 1)
+    {
+      --rep->count;
+      rep = new ArrayRep (length (), val);
+      slice_data = rep->data;
+    }
+  else
+    std::fill (slice_data, slice_data + slice_len, val);
+}
+
+template <class T>
+Array<T>
+Array<T>::squeeze (void) const
+{
+  Array<T> retval = *this;
+
+  if (ndims () > 2)
+    {
+      bool dims_changed = false;
+
+      dim_vector new_dimensions = dimensions;
+
+      int k = 0;
+
+      for (int i = 0; i < ndims (); i++)
+	{
+	  if (dimensions(i) == 1)
+	    dims_changed = true;
+	  else
+	    new_dimensions(k++) = dimensions(i);
+	}
+
+      if (dims_changed)
+	{
+	  switch (k)
+	    {
+	    case 0:
+	      new_dimensions = dim_vector (1, 1);
+	      break;
+
+	    case 1:
+	      {
+		octave_idx_type tmp = new_dimensions(0);
+
+		new_dimensions.resize (2);
+
+		new_dimensions(0) = tmp;
+		new_dimensions(1) = 1;
+	      }
+	      break;
+
+	    default:
+	      new_dimensions.resize (k);
+	      break;
+	    }
+	}
+
+      retval = Array<T> (*this, new_dimensions);
+    }
+
+  return retval;
+}
+
+// KLUGE
+
+// The following get_size functions will throw a std::bad_alloc ()
+// exception if the requested size is larger than can be indexed by
+// octave_idx_type.  This may be smaller than the actual amount of
+// memory that can be safely allocated on a system.  However, if we
+// don't fail here, we can end up with a mysterious crash inside a
+// function that is iterating over an array using octave_idx_type
+// indices.
+
+// A guess (should be quite conservative).
+#define MALLOC_OVERHEAD 1024
+
+template <class T>
+octave_idx_type
+Array<T>::get_size (octave_idx_type r, octave_idx_type c)
+{
+  static int nl;
+  static double dl
+    = frexp (static_cast<double> 
+	(std::numeric_limits<octave_idx_type>::max() - MALLOC_OVERHEAD) / sizeof (T), &nl);
+
+  int nr, nc;
+  double dr = frexp (static_cast<double> (r), &nr);   // r = dr * 2^nr
+  double dc = frexp (static_cast<double> (c), &nc);   // c = dc * 2^nc
+
+  int nt = nr + nc;
+  double dt = dr * dc;
+
+  if (dt < 0.5)
+    {
+      nt--;
+      dt *= 2;
+    }
+
+  if (nt < nl || (nt == nl && dt < dl))
+    return r * c;
+  else
+    {
+      throw std::bad_alloc ();
+      return 0;
+    }
+}
+
+template <class T>
+octave_idx_type
+Array<T>::get_size (octave_idx_type r, octave_idx_type c, octave_idx_type p)
+{
+  static int nl;
+  static double dl
+    = frexp (static_cast<double>
+	(std::numeric_limits<octave_idx_type>::max() - MALLOC_OVERHEAD) / sizeof (T), &nl);
+
+  int nr, nc, np;
+  double dr = frexp (static_cast<double> (r), &nr);
+  double dc = frexp (static_cast<double> (c), &nc);
+  double dp = frexp (static_cast<double> (p), &np);
+
+  int nt = nr + nc + np;
+  double dt = dr * dc * dp;
+
+  if (dt < 0.5)
+    {
+      nt--;
+      dt *= 2;
+
+      if (dt < 0.5)
+	{
+	  nt--;
+	  dt *= 2;
+	}
+    }
+
+  if (nt < nl || (nt == nl && dt < dl))
+    return r * c * p;
+  else
+    {
+      throw std::bad_alloc ();
+      return 0;
+    }
+}
+
+template <class T>
+octave_idx_type
+Array<T>::get_size (const dim_vector& ra_idx)
+{
+  static int nl;
+  static double dl
+    = frexp (static_cast<double>
+	(std::numeric_limits<octave_idx_type>::max() - MALLOC_OVERHEAD) / sizeof (T), &nl);
+
+  int n = ra_idx.length ();
+
+  int nt = 0;
+  double dt = 1;
+
+  for (int i = 0; i < n; i++)
+    {
+      int nra_idx;
+      double dra_idx = frexp (static_cast<double> (ra_idx(i)), &nra_idx);
+
+      nt += nra_idx;
+      dt *= dra_idx;
+
+      if (dt < 0.5)
+	{
+	  nt--;
+	  dt *= 2;
+	}
+    }
+
+  if (nt < nl || (nt == nl && dt < dl))
+    {
+      octave_idx_type retval = 1;
+
+      for (int i = 0; i < n; i++)
+	retval *= ra_idx(i);
+
+      return retval;
+    }
+  else
+    {
+      throw std::bad_alloc ();
+      return 0;
+    }
+}
+
+#undef MALLOC_OVERHEAD
+
+template <class T>
+octave_idx_type
+Array<T>::compute_index (const Array<octave_idx_type>& ra_idx) const
+{
+  octave_idx_type retval = -1;
+
+  int n = dimensions.length ();
+
+  if (n > 0 && n == ra_idx.length ())
+    {
+      retval = ra_idx(--n);
+
+      while (--n >= 0)
+	{
+	  retval *= dimensions(n);
+	  retval += ra_idx(n);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::compute_index: invalid ra_idxing operation");
+
+  return retval;
+}
+
+template <class T>
+T
+Array<T>::range_error (const char *fcn, octave_idx_type n) const
+{
+  (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n);
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, octave_idx_type n)
+{
+  (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d): range error", fcn, i, j);
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j)
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d): range error", fcn, i, j);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k) const
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d, %d): range error", fcn, i, j, k);
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k)
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d, %d): range error", fcn, i, j, k);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Array<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const
+{
+  std::ostringstream buf;
+
+  buf << fcn << " (";
+
+  octave_idx_type n = ra_idx.length ();
+
+  if (n > 0)
+    buf << ra_idx(0);
+
+  for (octave_idx_type i = 1; i < n; i++)
+    buf << ", " << ra_idx(i);
+
+  buf << "): range error";
+
+  std::string buf_str = buf.str ();
+
+  (*current_liboctave_error_handler) (buf_str.c_str ());
+
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx)
+{
+  std::ostringstream buf;
+
+  buf << fcn << " (";
+
+  octave_idx_type n = ra_idx.length ();
+
+  if (n > 0)
+    buf << ra_idx(0);
+
+  for (octave_idx_type i = 1; i < n; i++)
+    buf << ", " << ra_idx(i);
+
+  buf << "): range error";
+
+  std::string buf_str = buf.str ();
+
+  (*current_liboctave_error_handler) (buf_str.c_str ());
+
+  static T foo;
+  return foo;
+}
+
+template <class T>
+Array<T>
+Array<T>::reshape (const dim_vector& new_dims) const
+{
+  Array<T> retval;
+
+  if (dimensions != new_dims)
+    {
+      if (dimensions.numel () == new_dims.numel ())
+	retval = Array<T> (*this, new_dims);
+      else
+	{
+	  std::string dimensions_str = dimensions.str ();
+	  std::string new_dims_str = new_dims.str ();
+
+	  (*current_liboctave_error_handler)
+	    ("reshape: can't reshape %s array to %s array",
+	     dimensions_str.c_str (), new_dims_str.c_str ());
+	}
+    }
+  else
+    retval = *this;
+
+  return retval;
+}
+
+// Helper class for multi-d dimension permuting (generalized transpose).
+class rec_permute_helper
+{
+  octave_idx_type *dim, *stride;
+  bool use_blk;
+  int top;
+
+public:
+  rec_permute_helper (const dim_vector& dv, const Array<octave_idx_type>& perm)
+    {
+      int n = dv.length ();
+      assert (n == perm.length ());
+
+      dim = new octave_idx_type [2*n];
+      // A hack to avoid double allocation
+      stride = dim + n;
+
+      // Get cumulative dimensions.
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, cdim, n+1);
+      cdim[0] = 1;
+      for (int i = 1; i < n+1; i++) cdim[i] = cdim[i-1] * dv(i-1);
+
+      // Setup the permuted strides.
+      for (int k = 0; k < n; k++)
+        {
+          int kk = perm(k);
+          dim[k] = dv(kk);
+          stride[k] = cdim[kk];
+        }
+
+      // Reduce contiguous runs.
+      top = 0;
+      for (int k = 1; k < n; k++)
+        {
+          if (stride[k] == stride[top]*dim[top])
+            dim[top] *= dim[k];
+          else
+            {
+              top++;
+              dim[top] = dim[k];
+              stride[top] = stride[k];
+            }
+        }
+
+      // Determine whether we can use block transposes.
+      use_blk = top >= 1 && stride[1] == 1 && stride[0] == dim[1];
+
+    }
+
+  ~rec_permute_helper (void) { delete [] dim; }
+
+  // Helper method for fast blocked transpose.
+  template <class T>
+  static T *
+  blk_trans (const T *src, T *dest, octave_idx_type nr, octave_idx_type nc)
+    {
+      static const octave_idx_type m = 8;
+      OCTAVE_LOCAL_BUFFER (T, blk, m*m);
+      for (octave_idx_type kr = 0; kr < nr; kr += m)
+        for (octave_idx_type kc = 0; kc < nc; kc += m)
+          {
+            octave_idx_type lr = std::min (m, nr - kr);
+            octave_idx_type lc = std::min (m, nc - kc);
+            if (lr == m && lc == m)
+              {
+                const T *ss = src + kc * nr + kr;
+                for (octave_idx_type j = 0; j < m; j++)
+                  for (octave_idx_type i = 0; i < m; i++)
+                    blk[j*m+i] = ss[j*nr + i];
+                T *dd = dest + kr * nc + kc;
+                for (octave_idx_type j = 0; j < m; j++)
+                  for (octave_idx_type i = 0; i < m; i++)
+                    dd[j*nc+i] = blk[i*m+j];
+              }
+            else
+              {
+                const T *ss = src + kc * nr + kr;
+                for (octave_idx_type j = 0; j < lc; j++)
+                  for (octave_idx_type i = 0; i < lr; i++)
+                    blk[j*m+i] = ss[j*nr + i];
+                T *dd = dest + kr * nc + kc;
+                for (octave_idx_type j = 0; j < lr; j++)
+                  for (octave_idx_type i = 0; i < lc; i++)
+                    dd[j*nc+i] = blk[i*m+j];
+              }
+          }
+
+      return dest + nr*nc;
+    }
+private:
+
+  // Recursive N-d generalized transpose
+  template <class T>
+  T *do_permute (const T *src, T *dest, int lev) const
+    {
+      if (lev == 0)
+        {
+          octave_idx_type step = stride[0], len = dim[0];
+          if (step == 1)
+            dest = std::copy (src, src + len, dest);
+          else
+            {
+              for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                dest[i] = src[j];
+
+              dest += len;
+            }
+        }
+      else if (use_blk && lev == 1)
+        dest = blk_trans (src, dest, dim[1], dim[0]);
+      else
+        {
+          octave_idx_type step = stride[lev], len = dim[lev];
+          for (octave_idx_type i = 0, j = 0; i < len; i++, j+= step)
+           dest = do_permute (src + i * step, dest, lev-1);
+        }
+
+      return dest;
+    }
+  
+public:
+
+  template <class T>
+  void permute (const T *src, T *dest) const { do_permute (src, dest, top); }
+
+};
+
+
+template <class T>
+Array<T>
+Array<T>::permute (const Array<octave_idx_type>& perm_vec_arg, bool inv) const
+{
+  Array<T> retval;
+
+  Array<octave_idx_type> perm_vec = perm_vec_arg;
+
+  dim_vector dv = dims ();
+  dim_vector dv_new;
+
+  int perm_vec_len = perm_vec_arg.length ();
+
+  if (perm_vec_len < dv.length ())
+    (*current_liboctave_error_handler)
+      ("%s: invalid permutation vector", inv ? "ipermute" : "permute");
+
+  dv_new.resize (perm_vec_len);
+
+  // Append singleton dimensions as needed.
+  dv.resize (perm_vec_len, 1);
+
+  // Need this array to check for identical elements in permutation array.
+  OCTAVE_LOCAL_BUFFER_INIT (bool, checked, perm_vec_len, false);
+
+  // Find dimension vector of permuted array.
+  for (int i = 0; i < perm_vec_len; i++)
+    {
+      octave_idx_type perm_elt = perm_vec.elem (i);
+      if (perm_elt >= perm_vec_len || perm_elt < 0)
+	{
+	  (*current_liboctave_error_handler)
+	    ("%s: permutation vector contains an invalid element",
+	     inv ? "ipermute" : "permute");
+
+	  return retval;
+	}
+
+      if (checked[perm_elt])
+	{
+	  (*current_liboctave_error_handler)
+	    ("%s: permutation vector cannot contain identical elements",
+	     inv ? "ipermute" : "permute");
+
+	  return retval;
+	}
+      else
+	checked[perm_elt] = true;
+
+      dv_new(i) = dv(perm_elt);
+    }
+
+  if (inv)
+    {
+      for (int i = 0; i < perm_vec_len; i++)
+        perm_vec(perm_vec_arg(i)) = i;
+    }
+
+  retval = Array<T> (dv_new);
+
+  if (numel () > 0)
+    {
+      rec_permute_helper rh (dv, perm_vec);
+      rh.permute (data (), retval.fortran_vec ());
+    }
+
+  retval.chop_trailing_singletons ();
+
+  return retval;
+}
+
+// Helper class for multi-d index reduction and recursive indexing/indexed assignment.
+// Rationale: we could avoid recursion using a state machine instead. However, using
+// recursion is much more amenable to possible parallelization in the future.
+// Also, the recursion solution is cleaner and more understandable.
+class rec_index_helper
+{
+  octave_idx_type *dim, *cdim;
+  idx_vector *idx;
+  int top;
+
+public:
+  rec_index_helper (const dim_vector& dv, const Array<idx_vector>& ia)
+    {
+      int n = ia.length ();
+      assert (n > 0 && (dv.length () == std::max (n, 2)));
+
+      dim = new octave_idx_type [2*n];
+      // A hack to avoid double allocation
+      cdim = dim + n;
+      idx = new idx_vector [n];
+      top = 0;
+
+      dim[0] = dv(0);
+      cdim[0] = 1;
+      idx[0] = ia(0);
+
+      for (int i = 1; i < n; i++)
+        {
+          // Try reduction...
+          if (idx[top].maybe_reduce (dim[top], ia(i), dv(i)))
+            {
+              // Reduction successful, fold dimensions.
+              dim[top] *= dv(i);
+            }
+          else
+            {
+              // Unsuccessful, store index & cumulative dim.
+              top++;
+              idx[top] = ia(i);
+              dim[top] = dv(i);
+              cdim[top] = cdim[top-1] * dim[top-1];
+            } 
+        }
+    }
+
+  ~rec_index_helper (void) { delete [] idx; delete [] dim; }
+
+private:
+
+  // Recursive N-d indexing
+  template <class T>
+  T *do_index (const T *src, T *dest, int lev) const
+    {
+      if (lev == 0)
+        dest += idx[0].index (src, dim[0], dest);
+      else
+        {
+          octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev];
+          for (octave_idx_type i = 0; i < n; i++)
+            dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1);
+        }
+
+      return dest;
+    }
+  
+  // Recursive N-d indexed assignment
+  template <class T>
+  const T *do_assign (const T *src, T *dest, int lev) const
+    {
+      if (lev == 0)
+        src += idx[0].assign (src, dim[0], dest);
+      else
+        {
+          octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev];
+          for (octave_idx_type i = 0; i < n; i++)
+            src = do_assign (src, dest + d*idx[lev].xelem (i), lev-1);
+        }
+
+      return src;
+    }
+
+  // Recursive N-d indexed assignment
+  template <class T>
+  void do_fill (const T& val, T *dest, int lev) const
+    {
+      if (lev == 0)
+        idx[0].fill (val, dim[0], dest);
+      else
+        {
+          octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev];
+          for (octave_idx_type i = 0; i < n; i++)
+            do_fill (val, dest + d*idx[lev].xelem (i), lev-1);
+        }
+    }
+
+public:
+
+  template <class T>
+  void index (const T *src, T *dest) const { do_index (src, dest, top); }
+
+  template <class T>
+  void assign (const T *src, T *dest) const { do_assign (src, dest, top); }
+
+  template <class T>
+  void fill (const T& val, T *dest) const { do_fill (val, dest, top); }
+
+  bool is_cont_range (octave_idx_type& l, 
+                            octave_idx_type& u) const
+    {
+      return top == 0 && idx[0].is_cont_range (dim[0], l, u);
+    }
+};
+
+// Helper class for multi-d recursive resizing
+// This handles resize () in an efficient manner, touching memory only
+// once (apart from reinitialization)
+class rec_resize_helper
+{
+  octave_idx_type *cext, *sext, *dext;
+  int n;
+
+public:
+  rec_resize_helper (const dim_vector& ndv, const dim_vector& odv)
+    {
+      int l = ndv.length ();
+      assert (odv.length () == l);
+      octave_idx_type ld = 1;
+      int i = 0;
+      for (; i < l-1 && ndv(i) == odv(i); i++) ld *= ndv(i);
+      n = l - i;
+      cext = new octave_idx_type[3*n];
+      // Trick to avoid three allocations
+      sext = cext + n;
+      dext = sext + n;
+
+      octave_idx_type sld = ld, dld = ld;
+      for (int j = 0; j < n; j++)
+        {
+          cext[j] = std::min (ndv(i+j), odv(i+j));
+          sext[j] = sld *= odv(i+j);
+          dext[j] = dld *= ndv(i+j);
+        }
+      cext[0] *= ld;
+    }
+
+  ~rec_resize_helper (void) { delete [] cext; }
+
+private:
+  // recursive resizing
+  template <class T>
+  void do_resize_fill (const T* src, T *dest, const T& rfv, int lev) const
+    {
+      if (lev == 0)
+        {
+          T* destc = std::copy (src, src + cext[0], dest);
+          std::fill (destc, dest + dext[0], rfv);
+        }
+      else
+        {
+          octave_idx_type sd = sext[lev-1], dd = dext[lev-1], k;
+          for (k = 0; k < cext[lev]; k++)
+            do_resize_fill (src + k * sd, dest + k * dd, rfv, lev - 1);
+
+          std::fill (dest + k * dd, dest + dext[lev], rfv);
+        }
+    }
+public:
+  template <class T>
+  void resize_fill (const T* src, T *dest, const T& rfv) const 
+    { do_resize_fill (src, dest, rfv, n-1); }
+
+};
+
+static void gripe_index_out_of_range (void)
+{
+  (*current_liboctave_error_handler)
+    ("A(I): Index exceeds matrix dimension.");
+}
+
+template <class T>
+Array<T>
+Array<T>::index (const idx_vector& i) const
+{
+  octave_idx_type n = numel ();
+  Array<T> retval;
+
+  if (i.is_colon ())
+    {
+      // A(:) produces a shallow copy as a column vector.
+      retval = Array<T> (*this, dim_vector (n, 1));
+    }
+  else if (i.extent (n) != n)
+    {
+      gripe_index_out_of_range ();
+    }
+  else
+    {
+      // FIXME -- this is the only place where orig_dimensions are used.
+      dim_vector rd = i.orig_dimensions ();
+      octave_idx_type il = i.length (n);
+
+      // FIXME -- this is for Matlab compatibility.  Matlab 2007 given
+      //
+      //   b = ones(3,1)
+      //
+      // yields the following:
+      //
+      //   b(zeros(0,0)) gives []
+      //   b(zeros(1,0)) gives zeros(0,1)
+      //   b(zeros(0,1)) gives zeros(0,1)
+      //   b(zeros(0,m)) gives zeros(0,m)
+      //   b(zeros(m,0)) gives zeros(m,0)
+      //   b(1:2) gives ones(2,1)
+      //   b(ones(2)) gives ones(2) etc.
+      //
+      // As you can see, the behaviour is weird, but the tests end up pretty
+      // simple.  Nah, I don't want to suggest that this is ad hoc :)
+
+      if (ndims () == 2 && n != 1)
+        {
+          if (columns () == 1 && rd(0) == 1)
+            rd = dim_vector (il, 1);
+          else if (rows () == 1 && rd(1) == 1)
+            rd = dim_vector (1, il);
+        }
+
+      octave_idx_type l, u;
+      if (il != 0 && i.is_cont_range (n, l, u))
+        // If suitable, produce a shallow slice.
+        retval = Array<T> (*this, rd, l, u);
+      else
+        {
+          // Don't use resize here to avoid useless initialization for POD
+          // types.
+          retval = Array<T> (rd);
+
+          if (il != 0)
+            i.index (data (), n, retval.fortran_vec ());
+        }
+    }
+
+  return retval;
+}
+
+template <class T>
+Array<T>
+Array<T>::index (const idx_vector& i, const idx_vector& j) const
+{
+  // Get dimensions, allowing Fortran indexing in the 2nd dim.
+  dim_vector dv = dimensions.redim (2);
+  octave_idx_type r = dv(0), c = dv(1);
+  Array<T> retval;
+
+  if (i.is_colon () && j.is_colon ())
+    {
+      // A(:,:) produces a shallow copy.
+      retval = Array<T> (*this, dv);
+    }
+  else if (i.extent (r) != r || j.extent (c) != c)
+    {
+      gripe_index_out_of_range ();
+    }
+  else
+    {
+      octave_idx_type n = numel (), il = i.length (r), jl = j.length (c);
+
+      idx_vector ii (i);
+
+      if (ii.maybe_reduce (r, j, c))
+        {
+          octave_idx_type l, u;
+          if (ii.length () > 0 && ii.is_cont_range (n, l, u))
+            // If suitable, produce a shallow slice.
+            retval = Array<T> (*this, dim_vector (il, jl), l, u);
+          else
+            {
+              // Don't use resize here to avoid useless initialization for POD types.
+              retval = Array<T> (dim_vector (il, jl));
+
+              ii.index (data (), n, retval.fortran_vec ());
+            }
+        }
+      else
+        {
+          // Don't use resize here to avoid useless initialization for POD types.
+          retval = Array<T> (dim_vector (il, jl));
+
+          const T* src = data ();
+          T *dest = retval.fortran_vec ();
+
+          for (octave_idx_type k = 0; k < jl; k++)
+            dest += i.index (src + r * j.xelem (k), r, dest);
+        }
+    }
+
+  return retval;
+}
+
+template <class T>
+Array<T>
+Array<T>::index (const Array<idx_vector>& ia) const
+{
+  int ial = ia.length ();
+  Array<T> retval;
+
+  // FIXME: is this dispatching necessary?
+  if (ial == 1)
+    retval = index (ia(0));
+  else if (ial == 2)
+    retval = index (ia(0), ia(1));
+  else if (ial > 0)
+    {
+      // Get dimensions, allowing Fortran indexing in the last dim.
+      dim_vector dv = dimensions.redim (ial);
+
+      // Check for out of bounds conditions.
+      bool all_colons = true, mismatch = false;
+      for (int i = 0; i < ial; i++)
+        {
+          if (ia(i).extent (dv(i)) != dv(i))
+            {
+              mismatch = true;
+              break;
+            }
+          else
+            all_colons = all_colons && ia(i).is_colon ();
+        }
+
+
+      if (mismatch)
+        {
+          gripe_index_out_of_range ();
+        }
+      else if (all_colons)
+        {
+          // A(:,:,...,:) produces a shallow copy.
+          retval = Array<T> (*this, dv);
+        }
+      else 
+        {
+          // Form result dimensions.
+          dim_vector rdv;
+          rdv.resize (ial);
+          for (int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i));
+          rdv.chop_trailing_singletons ();
+
+          // Prepare for recursive indexing
+          rec_index_helper rh (dv, ia);
+
+          octave_idx_type l, u;
+          if (rh.is_cont_range (l, u))
+            // If suitable, produce a shallow slice.
+            retval = Array<T> (*this, rdv, l, u);
+          else
+            {
+              // Don't use resize here to avoid useless initialization for POD types.
+              retval = Array<T> (rdv);
+
+              // Do it.
+              rh.index (data (), retval.fortran_vec ());
+            }
+        }
+    }
+
+  return retval;
+}
+
+// FIXME -- the following is a common error message to resize,
+// regardless of whether it's called from assign or elsewhere.  It
+// seems OK to me, but eventually the gripe can be specialized.
+// Anyway, propagating various error messages into procedure is, IMHO,
+// a nonsense.  If anything, we should change error handling here (and
+// throughout liboctave) to allow custom handling of errors
+static void gripe_invalid_resize (void)
+{
+  (*current_liboctave_error_handler)
+    ("resize: Invalid resizing operation or ambiguous assignment to an out-of-bounds array element.");
+}
+
+// The default fill value.  Override if you want a different one.
+
+template <class T>
+T Array<T>::resize_fill_value ()
+{
+  return T ();
+}
+
+// Yes, we could do resize using index & assign.  However, that would
+// possibly involve a lot more memory traffic than we actually need.
+
+template <class T>
+void
+Array<T>::resize_fill (octave_idx_type n, const T& rfv)
+{
+  if (n >= 0 && ndims () == 2)
+    {
+      dim_vector dv;
+      // This is driven by Matlab's behaviour of giving a *row* vector
+      // on some out-of-bounds assignments.  Specifically, Matlab
+      // allows a(i) with out-of-bouds i when a is either of 0x0, 1x0,
+      // 1x1, 0xN, and gives a row vector in all cases (yes, even the
+      // last one, search me why).  Giving a column vector would make
+      // much more sense (given the way trailing singleton dims are
+      // treated).
+      bool invalid = false;
+      if (rows () == 0 || rows () == 1)
+        dv = dim_vector (1, n);          
+      else if (columns () == 1)
+        dv = dim_vector (n, 1);
+      else
+         invalid = true;
+        
+      if (invalid)
+        gripe_invalid_resize ();
+      else
+        {
+          octave_idx_type nx = numel ();
+          if (n == nx - 1 && n > 0)
+            {
+              // Stack "pop" operation.
+              if (rep->count == 1)
+                slice_data[slice_len-1] = T ();
+              slice_len--;
+              dimensions = dv;
+            }
+          else if (n == nx + 1 && nx > 0)
+            {
+              // Stack "push" operation.
+              if (rep->count == 1 && slice_data + slice_len < rep->data + rep->len)
+                {
+                  slice_data[slice_len++] = rfv;
+                  dimensions = dv;
+                }
+              else
+                {
+                  static const octave_idx_type max_stack_chunk = 1024;
+                  octave_idx_type nn = n + std::min (nx, max_stack_chunk);
+                  Array<T> tmp (Array<T> (nn), dv, 0, n);
+                  T *dest = tmp.fortran_vec ();
+
+                  std::copy (data (), data () + nx, dest);
+                  dest[nx] = rfv;
+
+                  *this = tmp;
+                }
+            }
+          else if (n != nx)
+            {
+              Array<T> tmp = Array<T> (dv);
+              T *dest = tmp.fortran_vec ();
+
+              octave_idx_type n0 = std::min (n, nx), n1 = n - n0;
+              dest = std::copy (data (), data () + n0, dest);
+              std::fill (dest, dest + n1, rfv);
+
+              *this = tmp;
+            }
+        }
+    }
+  else
+    gripe_invalid_resize ();
+}
+
+template <class T>
+void
+Array<T>::resize_fill (octave_idx_type r, octave_idx_type c, const T& rfv)
+{
+  if (r >= 0 && c >= 0 && ndims () == 2)
+    {
+      octave_idx_type rx = rows (), cx = columns ();
+      if (r != rx || c != cx)
+        {
+          Array<T> tmp = Array<T> (dim_vector (r, c));
+          T *dest = tmp.fortran_vec ();
+
+          octave_idx_type r0 = std::min (r, rx), r1 = r - r0;
+          octave_idx_type c0 = std::min (c, cx), c1 = c - c0;
+          const T *src = data ();
+          if (r == rx)
+            dest = std::copy (src, src + r * c0, dest);
+          else
+            {
+              for (octave_idx_type k = 0; k < c0; k++)
+                {
+                  dest = std::copy (src, src + r0, dest);
+                  src += rx;
+                  std::fill (dest, dest + r1, rfv);
+                  dest += r1;
+                }
+            }
+
+          std::fill (dest, dest + r * c1, rfv);
+
+          *this = tmp;
+        }
+    }
+  else
+    gripe_invalid_resize ();
+
+}
+
+template<class T>
+void
+Array<T>::resize_fill (const dim_vector& dv, const T& rfv)
+{
+  int dvl = dv.length ();
+  if (dvl == 2)
+    resize (dv(0), dv(1), rfv);
+  else if (dimensions != dv)
+    {
+      if (dimensions.length () <= dvl && ! dv.any_neg ())
+        {
+          Array<T> tmp (dv);
+          // Prepare for recursive resizing.
+          rec_resize_helper rh (dv, dimensions.redim (dvl));
+
+          // Do it.
+          rh.resize_fill (data (), tmp.fortran_vec (), rfv);   
+          *this = tmp;
+        }
+      else
+        gripe_invalid_resize ();
+    }
+}
+
+template <class T>
+Array<T> 
+Array<T>::index (const idx_vector& i, bool resize_ok, const T& rfv) const
+{
+  Array<T> tmp = *this;
+  if (resize_ok)
+    {
+      octave_idx_type n = numel (), nx = i.extent (n);
+      if (n != nx)
+        {
+          if (i.is_scalar ())
+            return Array<T> (1, rfv);
+          else
+            tmp.resize_fill (nx, rfv);
+        }
+
+      if (tmp.numel () != nx)
+        return Array<T> ();
+    }
+
+  return tmp.index (i);
+}
+
+template <class T>
+Array<T> 
+Array<T>::index (const idx_vector& i, const idx_vector& j, 
+                 bool resize_ok, const T& rfv) const
+{
+  Array<T> tmp = *this;
+  if (resize_ok)
+    {
+      dim_vector dv = dimensions.redim (2);
+      octave_idx_type r = dv(0), c = dv(1);
+      octave_idx_type rx = i.extent (r), cx = j.extent (c);
+      if (r != rx || c != cx)
+        {
+          if (i.is_scalar () && j.is_scalar ())
+            return Array<T> (1, rfv);
+          else
+            tmp.resize_fill (rx, cx, rfv);
+        }
+
+      if (tmp.rows () != rx || tmp.columns () != cx)
+        return Array<T> ();
+    }
+
+  return tmp.index (i, j);  
+}
+
+template <class T>
+Array<T> 
+Array<T>::index (const Array<idx_vector>& ia,
+                 bool resize_ok, const T& rfv) const
+{
+  Array<T> tmp = *this;
+  if (resize_ok)
+    {
+      int ial = ia.length ();
+      dim_vector dv = dimensions.redim (ial);
+      dim_vector dvx; dvx.resize (ial);
+      for (int i = 0; i < ial; i++) dvx(i) = ia(i).extent (dv (i));
+      if (! (dvx == dv))
+        {
+          bool all_scalars = true;
+          for (int i = 0; i < ial; i++) 
+            all_scalars = all_scalars && ia(i).is_scalar ();
+          if (all_scalars)
+            return Array<T> (1, rfv);
+          else
+            tmp.resize_fill (dvx, rfv);
+        }
+
+      if (tmp.dimensions != dvx)
+        return Array<T> ();
+    }
+
+  return tmp.index (ia);  
+}
+
+
+static void 
+gripe_invalid_assignment_size (void)
+{
+  (*current_liboctave_error_handler)
+    ("A(I) = X: X must have the same size as I");
+}
+
+static void
+gripe_assignment_dimension_mismatch (void)
+{
+  (*current_liboctave_error_handler)
+    ("A(I,J,...) = X: dimensions mismatch");
+}
+
+template <class T>
+void
+Array<T>::assign (const idx_vector& i, const Array<T>& rhs, const T& rfv)
+{
+  octave_idx_type n = numel (), rhl = rhs.numel ();
+
+  if (rhl == 1 || i.length (n) == rhl)
+    {
+      octave_idx_type nx = i.extent (n);
+      // Try to resize first if necessary. 
+      if (nx != n)
+        {
+          // Optimize case A = []; A(1:n) = X with A empty. 
+          if (rows () == 0 && columns () == 0 && ndims () == 2
+              && i.is_colon_equiv (nx))
+            {
+              if (rhl == 1)
+                *this = Array<T> (dim_vector (1, nx), rhs(0));
+              else
+                *this = Array<T> (rhs, dim_vector (1, nx));
+              return;
+            }
+
+          resize_fill (nx, rfv);      
+          n = numel ();
+        }
+
+      if (i.is_colon ())
+        {
+          // A(:) = X makes a full fill or a shallow copy.
+          if (rhl == 1)
+            fill (rhs(0));
+          else
+            *this = rhs.reshape (dimensions);
+        }
+      else
+        {
+          if (rhl == 1)
+            i.fill (rhs(0), n, fortran_vec ());
+          else
+            i.assign (rhs.data (), n, fortran_vec ());
+        }
+    }
+  else
+    gripe_invalid_assignment_size ();
+}
+
+template <class T>
+void
+Array<T>::assign (const idx_vector& i, const idx_vector& j,
+                  const Array<T>& rhs, const T& rfv)
+{
+  // Get RHS extents, discarding singletons.
+  dim_vector rhdv = rhs.dims (); 
+  // Get LHS extents, allowing Fortran indexing in the second dim.
+  dim_vector dv = dimensions.redim (2);
+  // Check for out-of-bounds and form resizing dimensions.
+  dim_vector rdv; 
+  // In the special when all dimensions are zero, colons are allowed
+  // to inquire the shape of RHS.  The rules are more obscure, so we
+  // solve that elsewhere.
+  if (dv.all_zero ())
+    rdv = zero_dims_inquire (i, j, rhdv);
+  else
+    {
+      rdv(0) = i.extent (dv(0));
+      rdv(1) = j.extent (dv(1));
+    }
+
+  bool isfill = rhs.numel () == 1;
+  octave_idx_type il = i.length (rdv(0)), jl = j.length (rdv(1));
+  rhdv.chop_all_singletons ();
+  bool match = (isfill
+		|| (rhdv.length () == 2 && il == rhdv(0) && jl == rhdv(1)));
+  match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1);
+
+  if (match)
+    {
+      // Resize if requested.
+      if (rdv != dv)
+        {
+          // Optimize case A = []; A(1:m, 1:n) = X
+          if (dv.all_zero () && i.is_colon_equiv (rdv(0))
+              && j.is_colon_equiv (rdv(1)))
+            {
+              if (isfill)
+                *this = Array<T> (rdv, rhs(0));
+              else
+                *this = Array<T> (rhs, rdv);
+              return;
+            }
+
+          resize (rdv, rfv);
+          dv = dimensions;
+        }
+
+      if (i.is_colon () && j.is_colon ())
+        {
+          // A(:,:) = X makes a full fill or a shallow copy
+          if (isfill)
+            fill (rhs(0));
+          else
+            *this = rhs.reshape (dimensions);
+        }
+      else
+        {
+          // The actual work.
+          octave_idx_type n = numel (), r = dv (0), c = dv (1);
+          idx_vector ii (i);
+
+          const T* src = rhs.data ();
+          T *dest = fortran_vec ();
+
+          // Try reduction first.
+          if (ii.maybe_reduce (r, j, c))
+            {
+              if (isfill)
+                ii.fill (*src, n, dest);
+              else
+                ii.assign (src, n, dest);
+            }
+          else
+            {
+              if (isfill)
+                {
+                  for (octave_idx_type k = 0; k < jl; k++)
+                    i.fill (*src, r, dest + r * j.xelem (k));
+                }
+              else
+                {
+                  for (octave_idx_type k = 0; k < jl; k++)
+                    src += i.assign (src, r, dest + r * j.xelem (k));
+                }
+            }
+        }
+    }
+  else
+    gripe_assignment_dimension_mismatch ();
+}
+
+template <class T>
+void
+Array<T>::assign (const Array<idx_vector>& ia,
+                  const Array<T>& rhs, const T& rfv)
+{
+  int ial = ia.length ();
+
+  // FIXME: is this dispatching necessary / desirable?
+  if (ial == 1)
+    assign (ia(0), rhs, rfv);
+  else if (ial == 2)
+    assign (ia(0), ia(1), rhs, rfv);
+  else if (ial > 0)
+    {
+      // Get RHS extents, discarding singletons.
+      dim_vector rhdv = rhs.dims ();
+
+      // Get LHS extents, allowing Fortran indexing in the second dim.
+      dim_vector dv = dimensions.redim (ial);
+      
+      // Get the extents forced by indexing. 
+      dim_vector rdv;
+
+      // In the special when all dimensions are zero, colons are
+      // allowed to inquire the shape of RHS.  The rules are more
+      // obscure, so we solve that elsewhere.
+      if (dv.all_zero ())
+        rdv = zero_dims_inquire (ia, rhdv);
+      else
+        {
+          rdv.resize (ial);
+          for (int i = 0; i < ial; i++)
+            rdv(i) = ia(i).extent (dv(i));
+        }
+
+      // Check whether LHS and RHS match, up to singleton dims.
+      bool match = true, all_colons = true, isfill = rhs.numel () == 1;
+
+      rhdv.chop_all_singletons ();
+      int j = 0, rhdvl = rhdv.length ();
+      for (int i = 0; i < ial; i++)
+        {
+          all_colons = all_colons && ia(i).is_colon ();
+          octave_idx_type l = ia(i).length (rdv(i));
+          if (l == 1) continue;
+          match = match && j < rhdvl && l == rhdv(j++);
+        }
+
+      match = match && (j == rhdvl || rhdv(j) == 1);
+      match = match || isfill;
+            
+      if (match)
+        {
+          // Resize first if necessary.
+          if (rdv != dv)
+            {
+              resize_fill (rdv, rfv);
+              dv = dimensions;
+              chop_trailing_singletons ();
+            }
+
+          if (all_colons)
+            {
+              // A(:,:,...,:) = X makes a full fill or a shallow copy.
+              if (isfill)
+                fill (rhs(0));
+              else
+                *this = rhs.reshape (dimensions);
+            }
+          else
+            {
+              // Do the actual work.
+
+              // Prepare for recursive indexing
+              rec_index_helper rh (dv, ia);
+
+              // Do it.
+              if (isfill)
+                rh.fill (rhs(0), fortran_vec ());
+              else
+                rh.assign (rhs.data (), fortran_vec ());
+            }
+        }
+      else 
+        gripe_assignment_dimension_mismatch ();
+    }
+}
+
+template <class T>
+void 
+Array<T>::delete_elements (const idx_vector& i)
+{
+  octave_idx_type n = numel ();
+  if (i.is_colon ())
+    { 
+      *this = Array<T> ();
+    }
+  else if (i.extent (n) != n)
+    {
+      gripe_index_out_of_range ();
+    }
+  else if (i.length (n) != 0)
+    {
+      octave_idx_type l, u;
+      bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1;
+      if (i.is_scalar () && i(0) == n-1)
+        {
+          // Stack "pop" operation.
+          resize (n-1);
+        }
+      else if (i.is_cont_range (n, l, u))
+        {
+          // Special case deleting a contiguous range.
+          octave_idx_type m = n + l - u;
+          Array<T> tmp (dim_vector (col_vec ? m : 1, !col_vec ? m : 1));
+          const T *src = data ();
+          T *dest = tmp.fortran_vec ();
+          dest = std::copy (src, src + l, dest);
+          dest = std::copy (src + u, src + n, dest);
+          *this = tmp;
+        }
+      else
+        {
+          // Use index.
+          *this = index (i.complement (n));
+        }
+    }
+}
+
+template <class T>
+void 
+Array<T>::delete_elements (int dim, const idx_vector& i)
+{
+  if (dim < 0 || dim >= ndims ())
+    {
+      (*current_liboctave_error_handler)
+        ("invalid dimension in delete_elements");
+      return;
+    }
+
+  octave_idx_type n = dimensions (dim);
+  if (i.is_colon ())
+    { 
+      *this = Array<T> ();
+    }
+  else if (i.extent (n) != n)
+    {
+      gripe_index_out_of_range ();
+    }
+  else if (i.length (n) != 0)
+    {
+      octave_idx_type l, u;
+
+      if (i.is_cont_range (n, l, u))
+        {
+          // Special case deleting a contiguous range.
+          octave_idx_type nd = n + l - u, dl = 1, du = 1;
+          dim_vector rdv = dimensions;
+          rdv(dim) = nd;
+          for (int k = 0; k < dim; k++) dl *= dimensions(k);
+          for (int k = dim + 1; k < ndims (); k++) du *= dimensions(k);
+
+          // Special case deleting a contiguous range.
+          Array<T> tmp = Array<T> (rdv);
+          const T *src = data ();
+          T *dest = tmp.fortran_vec ();
+          l *= dl; u *= dl; n *= dl;
+          for (octave_idx_type k = 0; k < du; k++)
+            {
+              dest = std::copy (src, src + l, dest);
+              dest = std::copy (src + u, src + n, dest);
+              src += n;
+            }
+
+          *this = tmp;
+        }
+      else
+        {
+          // Use index.
+          Array<idx_vector> ia (ndims (), idx_vector::colon);
+          ia (dim) = i.complement (n);
+          *this = index (ia);
+        }
+    }
+}
+
+template <class T>
+void 
+Array<T>::delete_elements (const Array<idx_vector>& ia)
+{
+  if (ia.length () == 1)
+    delete_elements (ia(0));
+  else
+    {
+      int len = ia.length (), k, dim = -1;
+      for (k = 0; k < len; k++)
+        {
+          if (! ia(k).is_colon ())
+            {
+              if (dim < 0)
+                dim = k;
+              else
+                break;
+            }
+        }
+      if (dim < 0)
+        {
+          dim_vector dv = dimensions;
+          dv(0) = 0;
+          *this = Array<T> (dv);
+        }
+      else if (k == len)
+        {
+          delete_elements (dim, ia(dim));
+        }
+      else
+        {
+          (*current_liboctave_error_handler)
+            ("A null assignment can only have one non-colon index.");
+        }
+    }
+
+}
+
+// FIXME: Remove these methods or implement them using assign.
+
+template <class T>
+Array<T>&
+Array<T>::insert (const Array<T>& a, octave_idx_type r, octave_idx_type c)
+{
+  if (ndims () == 2 && a.ndims () == 2)
+    insert2 (a, r, c);
+  else
+    insertN (a, r, c);
+
+  return *this;
+}
+
+
+template <class T>
+Array<T>&
+Array<T>::insert2 (const Array<T>& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_rows = a.rows ();
+  octave_idx_type a_cols = a.cols ();
+
+  if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  for (octave_idx_type j = 0; j < a_cols; j++)
+    for (octave_idx_type i = 0; i < a_rows; i++)
+      elem (r+i, c+j) = a.elem (i, j);
+
+  return *this;
+}
+
+template <class T>
+Array<T>&
+Array<T>::insertN (const Array<T>& a, octave_idx_type r, octave_idx_type c)
+{
+  dim_vector dv = dims ();
+
+  dim_vector a_dv = a.dims ();
+
+  int n = a_dv.length ();
+
+  if (n == dimensions.length ())
+    {
+      Array<octave_idx_type> a_ra_idx (a_dv.length (), 0);
+
+      a_ra_idx.elem (0) = r;
+      a_ra_idx.elem (1) = c;
+
+      for (int i = 0; i < n; i++)
+	{
+	  if (a_ra_idx(i) < 0 || (a_ra_idx(i) + a_dv(i)) > dv(i))
+	    {
+	      (*current_liboctave_error_handler)
+		("Array<T>::insert: range error for insert");
+	      return *this;
+	    }
+	}
+
+      octave_idx_type n_elt = a.numel ();
+      
+      const T *a_data = a.data ();   
+   
+      octave_idx_type iidx = 0;
+	  
+      octave_idx_type a_rows = a_dv(0);
+
+      octave_idx_type this_rows = dv(0);
+	  
+      octave_idx_type numel_page = a_dv(0) * a_dv(1);	  
+
+      octave_idx_type count_pages = 0;
+	  
+      for (octave_idx_type i = 0; i < n_elt; i++)
+	{
+	  if (i != 0 && i % a_rows == 0)
+	    iidx += (this_rows - a_rows);	      
+	  
+	  if (i % numel_page == 0)
+	    iidx = c * dv(0) + r + dv(0) * dv(1) * count_pages++;
+
+	  elem (iidx++) = a_data[i];
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::insert: invalid indexing operation");
+
+  return *this;
+}
+
+template <class T>
+Array<T>&
+Array<T>::insert (const Array<T>& a, const Array<octave_idx_type>& ra_idx)
+{
+  octave_idx_type n = ra_idx.length ();
+
+  if (n == dimensions.length ())
+    {
+      dim_vector dva = a.dims ();
+      dim_vector dv = dims ();
+      int len_a = dva.length ();
+      int non_full_dim = 0;
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  if (ra_idx(i) < 0 || (ra_idx(i) + 
+				(i < len_a ? dva(i) : 1)) > dimensions(i))
+	    {
+	      (*current_liboctave_error_handler)
+		("Array<T>::insert: range error for insert");
+	      return *this;
+	    }
+
+	  if (dv(i) != (i < len_a ? dva(i) : 1))
+	    non_full_dim++;
+	}
+
+      if (dva.numel ())
+        {
+	  if (non_full_dim < 2)
+	    {
+	      // Special case for fast concatenation
+	      const T *a_data = a.data ();
+	      octave_idx_type numel_to_move = 1;
+	      octave_idx_type skip = 0;
+	      for (int i = 0; i < len_a; i++)
+		if (ra_idx(i) == 0 && dva(i) == dv(i))
+		  numel_to_move *= dva(i);
+		else
+		  {
+		    skip = numel_to_move * (dv(i) - dva(i));
+		    numel_to_move *= dva(i);
+		    break;
+		  }
+
+	      octave_idx_type jidx = ra_idx(n-1);
+	      for (int i = n-2; i >= 0; i--)
+		{
+		  jidx *= dv(i);
+		  jidx += ra_idx(i);
+		}
+
+	      octave_idx_type iidx = 0;
+	      octave_idx_type moves = dva.numel () / numel_to_move;
+	      for (octave_idx_type i = 0; i < moves; i++)
+		{
+		  for (octave_idx_type j = 0; j < numel_to_move; j++)
+		    elem (jidx++) = a_data[iidx++];
+		  jidx += skip;
+		}
+	    }
+	  else
+	    {
+	      // Generic code
+	      const T *a_data = a.data ();
+	      int nel = a.numel ();
+	      Array<octave_idx_type> a_idx (n, 0);
+
+	      for (int i = 0; i < nel; i++)
+		{
+		  int iidx = a_idx(n-1) + ra_idx(n-1);
+		  for (int j = n-2; j >= 0; j--)
+		    {
+		      iidx *= dv(j);
+		      iidx += a_idx(j) + ra_idx(j);
+		    }
+
+		  elem (iidx) = a_data[i];
+
+		  increment_index (a_idx, dva);
+		}
+	    }
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::insert: invalid indexing operation");
+
+  return *this;
+}
+
+
+template <class T>
+Array<T>
+Array<T>::transpose (void) const
+{
+  assert (ndims () == 2);
+
+  octave_idx_type nr = dim1 ();
+  octave_idx_type nc = dim2 ();
+
+  if (nr >= 8 && nc >= 8)
+    {
+      Array<T> result (dim_vector (nc, nr));
+
+      // Reuse the implementation used for permuting.
+
+      rec_permute_helper::blk_trans (data (), result.fortran_vec (), nr, nc);
+
+      return result;
+    }
+  else if (nr > 1 && nc > 1)
+    {
+      Array<T> result (dim_vector (nc, nr));
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  result.xelem (j, i) = xelem (i, j);
+
+      return result;
+    }
+  else
+    {
+      // Fast transpose for vectors and empty matrices.
+      return Array<T> (*this, dim_vector (nc, nr));
+    }
+}
+
+template <class T>
+static T
+no_op_fcn (const T& x)
+{
+  return x;
+}
+
+template <class T>
+Array<T>
+Array<T>::hermitian (T (*fcn) (const T&)) const
+{
+  assert (ndims () == 2);
+
+  if (! fcn)
+    fcn = no_op_fcn<T>;
+
+  octave_idx_type nr = dim1 ();
+  octave_idx_type nc = dim2 ();
+
+  if (nr >= 8 && nc >= 8)
+    {
+      Array<T> result (dim_vector (nc, nr));
+
+      // Blocked transpose to attempt to avoid cache misses.
+
+      // Don't use OCTAVE_LOCAL_BUFFER here as it doesn't work with bool
+      // on some compilers.
+      T buf[64];
+
+      octave_idx_type ii = 0, jj;
+      for (jj = 0; jj < (nc - 8 + 1); jj += 8)
+	{
+	  for (ii = 0; ii < (nr - 8 + 1); ii += 8)
+	    {
+	      // Copy to buffer
+	      for (octave_idx_type j = jj, k = 0, idxj = jj * nr; 
+		   j < jj + 8; j++, idxj += nr)
+		for (octave_idx_type i = ii; i < ii + 8; i++)
+		  buf[k++] = xelem (i + idxj);
+
+	      // Copy from buffer
+	      for (octave_idx_type i = ii, idxi = ii * nc; i < ii + 8; 
+		   i++, idxi += nc)
+		for (octave_idx_type j = jj, k = i - ii; j < jj + 8; 
+		     j++, k+=8)
+		  result.xelem (j + idxi) = fcn (buf[k]);
+	    }
+
+	  if (ii < nr)
+	    for (octave_idx_type j = jj; j < jj + 8; j++)
+	      for (octave_idx_type i = ii; i < nr; i++)
+		result.xelem (j, i) = fcn (xelem (i, j));
+	} 
+
+      for (octave_idx_type j = jj; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  result.xelem (j, i) = fcn (xelem (i, j));
+
+      return result;
+    }
+  else
+    {
+      Array<T> result (dim_vector (nc, nr));
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  result.xelem (j, i) = fcn (xelem (i, j));
+
+      return result;
+    }
+}
+
+/*
+
+%% Tranpose tests for matrices of the tile size and plus or minus a row
+%% and with four tiles.
+
+%!shared m7, mt7, m8, mt8, m9, mt9
+%! m7 = reshape (1 : 7*8, 8, 7);
+%! mt7 = [1:8; 9:16; 17:24; 25:32; 33:40; 41:48; 49:56];
+%! m8 = reshape (1 : 8*8, 8, 8);
+%! mt8 = mt8 = [mt7; 57:64];
+%! m9 = reshape (1 : 9*8, 8, 9);
+%! mt9 = [mt8; 65:72];
+
+%!assert(m7', mt7)
+%!assert((1i*m7).', 1i * mt7)
+%!assert((1i*m7)', conj (1i * mt7))
+%!assert(m8', mt8)
+%!assert((1i*m8).', 1i * mt8)
+%!assert((1i*m8)', conj (1i * mt8))
+%!assert(m9', mt9)
+%!assert((1i*m9).', 1i * mt9)
+%!assert((1i*m9)', conj (1i * mt9))
+%!assert([m7, m8; m7, m8]', [mt7, mt7; mt8, mt8])
+%!assert((1i*[m7, m8; m7, m8]).', 1i * [mt7, mt7; mt8, mt8])
+%!assert((1i*[m7, m8; m7, m8])', conj (1i * [mt7, mt7; mt8, mt8]))
+%!assert([m8, m8; m8, m8]', [mt8, mt8; mt8, mt8])
+%!assert((1i*[m8, m8; m8, m8]).', 1i * [mt8, mt8; mt8, mt8])
+%!assert((1i*[m8, m8; m8, m8])', conj (1i * [mt8, mt8; mt8, mt8]))
+%!assert([m9, m8; m9, m8]', [mt9, mt9; mt8, mt8])
+%!assert((1i*[m9, m8; m9, m8]).', 1i * [mt9, mt9; mt8, mt8])
+%!assert((1i*[m9, m8; m9, m8])', conj (1i * [mt9, mt9; mt8, mt8]))
+
+*/
+
+template <class T>
+T *
+Array<T>::fortran_vec (void)
+{
+  make_unique ();
+
+  return slice_data;
+}
+
+template <class T>
+void
+Array<T>::maybe_delete_dims (void)
+{
+  int nd = dimensions.length ();
+
+  dim_vector new_dims (1, 1);
+
+  bool delete_dims = true;
+
+  for (int i = nd - 1; i >= 0; i--)
+    {
+      if (delete_dims)
+        {
+          if (dimensions(i) != 1)
+	    {
+	      delete_dims = false;
+
+	      new_dims = dim_vector (i + 1, dimensions(i));
+	    }
+        }
+      else
+	new_dims(i) = dimensions(i);
+    }
+
+  if (nd != new_dims.length ())
+    dimensions = new_dims;
+}
+
+// Non-real types don't have NaNs.
+template <class T>
+inline bool
+sort_isnan (typename ref_param<T>::type)
+{
+  return false;
+}
+
+template <class T>
+Array<T>
+Array<T>::sort (octave_idx_type dim, sortmode mode) const
+{
+  if (dim < 0 || dim >= ndims ())
+    {
+      (*current_liboctave_error_handler)
+        ("sort: invalid dimension");
+      return Array<T> ();
+    }
+
+  Array<T> m (dims ());
+
+  dim_vector dv = m.dims ();
+
+  if (m.length () < 1)
+    return m;
+
+  octave_idx_type ns = dv(dim);
+  octave_idx_type iter = dv.numel () / ns;
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  T *v = m.fortran_vec ();
+  const T *ov = data ();
+
+  octave_sort<T> lsort;
+  
+  if (mode) 
+    lsort.set_compare (mode);
+  else
+    return m;
+
+  if (stride == 1)
+    {
+      for (octave_idx_type j = 0; j < iter; j++)
+	{
+          // copy and partition out NaNs. 
+          // FIXME: impact on integer types noticeable?
+          octave_idx_type kl = 0, ku = ns;
+          for (octave_idx_type i = 0; i < ns; i++)
+            {
+              T tmp = ov[i];
+              if (sort_isnan<T> (tmp))
+                v[--ku] = tmp;
+              else
+                v[kl++] = tmp;
+            }
+
+          // sort.
+	  lsort.sort (v, kl);
+
+          if (ku < ns)
+            {
+              // NaNs are in reverse order
+              std::reverse (v + ku, v + ns);
+              if (mode == DESCENDING)
+                std::rotate (v, v + ku, v + ns);
+            }
+
+	  v += ns;
+          ov += ns;
+	}
+    }
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (T, buf, ns);
+
+      for (octave_idx_type j = 0; j < iter; j++) 
+	{
+	  octave_idx_type offset = j;
+	  octave_idx_type offset2 = 0;
+
+	  while (offset >= stride)
+	    {
+	      offset -= stride;
+	      offset2++;
+	    }
+
+	  offset += offset2 * stride * ns;
+	  
+          // gather and partition out NaNs. 
+          // FIXME: impact on integer types noticeable?
+          octave_idx_type kl = 0, ku = ns;
+          for (octave_idx_type i = 0; i < ns; i++)
+            {
+              T tmp = ov[i*stride + offset];
+              if (sort_isnan<T> (tmp))
+                buf[--ku] = tmp;
+              else
+                buf[kl++] = tmp;
+            }
+
+          // sort.
+	  lsort.sort (buf, kl);
+
+          if (ku < ns)
+            {
+              // NaNs are in reverse order
+              std::reverse (buf + ku, buf + ns);
+              if (mode == DESCENDING)
+                std::rotate (buf, buf + ku, buf + ns);
+            }
+
+          // scatter.
+	  for (octave_idx_type i = 0; i < ns; i++)
+	    v[i*stride + offset] = buf[i];
+	}
+    }
+
+  return m;
+}
+
+template <class T>
+Array<T>
+Array<T>::sort (Array<octave_idx_type> &sidx, octave_idx_type dim, 
+		sortmode mode) const
+{
+  if (dim < 0 || dim >= ndims ())
+    {
+      (*current_liboctave_error_handler)
+        ("sort: invalid dimension");
+      return Array<T> ();
+    }
+
+  Array<T> m (dims ());
+
+  dim_vector dv = m.dims ();
+
+  if (m.length () < 1)
+    {
+      sidx = Array<octave_idx_type> (dv);
+      return m;
+    }
+
+  octave_idx_type ns = dv(dim);
+  octave_idx_type iter = dv.numel () / ns;
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  T *v = m.fortran_vec ();
+  const T *ov = data ();
+
+  octave_sort<T> lsort;
+
+  sidx = Array<octave_idx_type> (dv);
+  octave_idx_type *vi = sidx.fortran_vec ();
+  
+  if (mode) 
+    lsort.set_compare (mode);
+  else
+    return m;
+
+  if (stride == 1)
+    {
+      for (octave_idx_type j = 0; j < iter; j++)
+	{
+          // copy and partition out NaNs. 
+          // FIXME: impact on integer types noticeable?
+          octave_idx_type kl = 0, ku = ns;
+          for (octave_idx_type i = 0; i < ns; i++)
+            {
+              T tmp = ov[i];
+              if (sort_isnan<T> (tmp))
+                {
+                  --ku;
+                  v[ku] = tmp;
+                  vi[ku] = i;
+                }
+              else
+                {
+                  v[kl] = tmp;
+                  vi[kl] = i;
+                  kl++;
+                }
+            }
+
+          // sort.
+	  lsort.sort (v, vi, kl);
+
+          if (ku < ns)
+            {
+              // NaNs are in reverse order
+              std::reverse (v + ku, v + ns);
+              std::reverse (vi + ku, vi + ns);
+              if (mode == DESCENDING)
+                {
+                  std::rotate (v, v + ku, v + ns);
+                  std::rotate (vi, vi + ku, vi + ns);
+                }
+            }
+
+	  v += ns;
+          vi += ns;
+          ov += ns;
+	}
+    }
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (T, buf, ns);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, bufi, ns);
+
+      for (octave_idx_type j = 0; j < iter; j++) 
+	{
+	  octave_idx_type offset = j;
+	  octave_idx_type offset2 = 0;
+
+	  while (offset >= stride)
+	    {
+	      offset -= stride;
+	      offset2++;
+	    }
+
+	  offset += offset2 * stride * ns;
+	  
+          // gather and partition out NaNs. 
+          // FIXME: impact on integer types noticeable?
+          octave_idx_type kl = 0, ku = ns;
+          for (octave_idx_type i = 0; i < ns; i++)
+            {
+              T tmp = ov[i*stride + offset];
+              if (sort_isnan<T> (tmp))
+                {
+                  --ku;
+                  buf[ku] = tmp;
+                  bufi[ku] = i;
+                }
+              else
+                {
+                  buf[kl] = tmp;
+                  bufi[kl] = i;
+                  kl++;
+                }
+            }
+
+          // sort.
+	  lsort.sort (buf, bufi, kl);
+
+          if (ku < ns)
+            {
+              // NaNs are in reverse order
+              std::reverse (buf + ku, buf + ns);
+              std::reverse (bufi + ku, bufi + ns);
+              if (mode == DESCENDING)
+                {
+                  std::rotate (buf, buf + ku, buf + ns);
+                  std::rotate (bufi, bufi + ku, bufi + ns);
+                }
+            }
+
+          // scatter.
+	  for (octave_idx_type i = 0; i < ns; i++)
+	    v[i*stride + offset] = buf[i];
+	  for (octave_idx_type i = 0; i < ns; i++)
+	    vi[i*stride + offset] = bufi[i];
+	}
+    }
+
+  return m;
+}
+
+template <class T>
+sortmode
+Array<T>::is_sorted (sortmode mode) const
+{
+  if (nelem () <= 1)
+    return ASCENDING;
+
+  const T *lo = data (), *hi = data () + nelem () - 1;
+
+  // Check for NaNs at the beginning and end.
+  if (mode != ASCENDING && sort_isnan<T> (*lo))
+    {
+      mode = DESCENDING;
+      do
+        ++lo;
+      while (lo < hi && sort_isnan<T> (*lo));
+    }
+  else if (mode != DESCENDING && sort_isnan<T> (*hi))
+    {
+      mode = ASCENDING;
+      do
+        --hi;
+      while (lo < hi && sort_isnan<T> (*hi));
+    }
+  
+  octave_sort<T> lsort;
+
+  // If mode is still unknown, compare lo and hi
+  if (! mode)
+    {
+      if (lsort.descending_compare (*lo, *hi))
+        mode = DESCENDING;
+      else if (lsort.ascending_compare (*lo, *hi))
+        mode = ASCENDING;
+      else
+        mode = ASCENDING;
+    }
+
+  lsort.set_compare (mode);
+
+  if (! lsort.is_sorted (lo, hi - lo + 1))
+    mode = UNSORTED;
+
+  return mode;
+}
+
+template <class T>
+typename Array<T>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<T>& /* a */,
+		     bool /* allow_chk */)
+{
+  if (mode == ASCENDING)
+    return octave_sort<T>::ascending_compare;
+  else if (mode == DESCENDING)
+    return octave_sort<T>::descending_compare;
+  else
+    return 0;
+}
+
+template <class T>
+Array<octave_idx_type>
+Array<T>::sort_rows_idx (sortmode mode) const
+{
+  Array<octave_idx_type> idx;
+
+  octave_sort<T> lsort;
+
+  lsort.set_compare (sortrows_comparator (mode, *this, true));
+
+  octave_idx_type r = rows (), c = cols ();
+
+  idx = Array<octave_idx_type> (r);
+
+  lsort.sort_rows (data (), idx.fortran_vec (), r, c);
+
+  return idx;
+}
+
+
+template <class T>
+sortmode 
+Array<T>::is_sorted_rows (sortmode mode) const
+{
+  octave_sort<T> lsort;
+
+  octave_idx_type r = rows (), c = cols ();
+
+  if (r <= 1 || c == 0)
+    return mode ? mode : ASCENDING;
+
+  if (! mode)
+    {
+      // Auto-detect mode.
+      compare_fcn_type compare
+	= sortrows_comparator (ASCENDING, *this, false);
+
+      octave_idx_type i;
+      for (i = 0; i < cols (); i++)
+        {
+          T l = elem (0, i), u = elem (rows () - 1, i);
+          if (compare (l, u))
+            {
+              if (mode == DESCENDING)
+                {
+                  mode = UNSORTED;
+                  break;
+                }
+              else
+                mode = ASCENDING;
+            }
+          else if (compare (u, l))
+            {
+              if (mode == ASCENDING)
+                {
+                  mode = UNSORTED;
+                  break;
+                }
+              else
+                mode = DESCENDING;
+            }
+        }
+      if (! mode && i == cols ())
+        mode = ASCENDING;
+    }
+
+  if (mode)
+    {
+      lsort.set_compare (sortrows_comparator (mode, *this, false));
+
+      if (! lsort.is_sorted_rows (data (), r, c))
+        mode = UNSORTED;
+    }
+
+  return mode;
+
+}
+
+// Do a binary lookup in a sorted array.
+template <class T>
+octave_idx_type 
+Array<T>::lookup (const T& value, sortmode mode) const
+{
+  octave_idx_type n = numel ();
+  octave_sort<T> lsort;
+
+  if (mode == UNSORTED)
+    {
+      // auto-detect mode
+      if (n > 1 && lsort.descending_compare (elem (0), elem (n-1)))
+        mode = DESCENDING;
+      else
+        mode = ASCENDING;
+    }
+
+  lsort.set_compare (mode);
+
+  return lsort.lookup (data (), n, value);
+}
+
+// Ditto, but for an array of values, specializing on long runs.
+// Adds optional offset to all indices.
+template <class T>
+Array<octave_idx_type> 
+Array<T>::lookup (const Array<T>& values, sortmode mode, 
+                  bool linf, bool rinf) const
+{
+  octave_idx_type n = numel ();
+  octave_sort<T> lsort;
+  Array<octave_idx_type> idx (values.dims ());
+
+  if (mode == UNSORTED)
+    {
+      // auto-detect mode
+      if (n > 1 && lsort.descending_compare (elem (0), elem (n-1)))
+        mode = DESCENDING;
+      else
+        mode = ASCENDING;
+    }
+
+  lsort.set_compare (mode);
+
+  // set offset and shift size.
+  octave_idx_type offset = 0;
+
+  if (linf && n > 0)
+    {
+      offset++;
+      n--;
+    }
+  if (rinf && n > 0)
+    n--;
+
+  lsort.lookup (data () + offset, n, values.data (), values.numel (),
+                idx.fortran_vec (), offset);
+
+  return idx;
+}
+
+template <class T>
+Array<octave_idx_type> 
+Array<T>::find (octave_idx_type n, bool backward) const
+{
+  Array<octave_idx_type> retval;
+  const T *src = data ();
+  octave_idx_type nel = nelem ();
+  const T zero = T ();
+  if (n < 0 || n >= nel)
+    {
+      // We want all elements, which means we'll almost surely need
+      // to resize. So count first, then allocate array of exact size.
+      octave_idx_type cnt = 0;
+      for (octave_idx_type i = 0; i < nel; i++)
+        cnt += src[i] != zero;
+
+      retval = Array<octave_idx_type> (cnt);
+      octave_idx_type *dest = retval.fortran_vec ();
+      for (octave_idx_type i = 0; i < nel; i++)
+        if (src[i] != zero) *dest++ = i;
+    }
+  else
+    {
+      // We want a fixed max number of elements, usually small. So be
+      // optimistic, alloc the array in advance, and then resize if
+      // needed.
+      retval = Array<octave_idx_type> (n);
+      if (backward)
+        {
+          // Do the search as a series of successive single-element searches.
+          octave_idx_type k = 0, l = nel - 1;
+          for (; k < n; k++)
+            {
+              for (;l >= 0 && src[l] == zero; l--) ;
+              if (l >= 0)
+                retval(k) = l--;
+              else
+                break;
+            }
+          if (k < n)
+            retval.resize (k);
+          octave_idx_type *rdata = retval.fortran_vec ();
+          std::reverse (rdata, rdata + k);
+        }
+      else
+        {
+          // Do the search as a series of successive single-element searches.
+          octave_idx_type k = 0, l = 0;
+          for (; k < n; k++)
+            {
+              for (;l != nel && src[l] == zero; l++) ;
+              if (l != nel)
+                retval(k) = l++;
+              else
+                break;
+            }
+          if (k < n)
+            retval.resize (k);
+        }
+    }
+
+  // Fixup return dimensions, for Matlab compatibility.
+  // find(zeros(0,0)) -> zeros(0,0)
+  // find(zeros(1,0)) -> zeros(1,0)
+  // find(zeros(0,1)) -> zeros(0,1)
+  // find(zeros(0,X)) -> zeros(0,1)
+  // find(zeros(1,1)) -> zeros(0,0) !!!! WHY?
+  // find(zeros(0,1,0)) -> zeros(0,0)
+  // find(zeros(0,1,0,1)) -> zeros(0,0) etc
+
+  if ((numel () == 1 && retval.is_empty ())
+      || (rows () == 0 && dims ().numel (1) == 0))
+    retval.dimensions = dim_vector ();
+  else if (rows () == 1 && ndims () == 2)
+    retval.dimensions = dim_vector (1, retval.length ());
+
+  return retval;
+}
+
+
+#define INSTANTIATE_ARRAY_SORT(T) template class OCTAVE_API octave_sort<T>;
+
+#define NO_INSTANTIATE_ARRAY_SORT(T) \
+ \
+template <> Array<T>  \
+Array<T>::sort (octave_idx_type, sortmode) const { return *this; } \
+ \
+template <> Array<T>  \
+Array<T>::sort (Array<octave_idx_type> &sidx, octave_idx_type, sortmode) const \
+{ sidx = Array<octave_idx_type> (); return *this; } \
+ \
+template <> sortmode  \
+Array<T>::is_sorted (sortmode) const  \
+{ return UNSORTED; } \
+ \
+Array<T>::compare_fcn_type \
+sortrows_comparator (sortmode, const Array<T>&, bool) \
+{ return 0; } \
+ \
+template <> Array<octave_idx_type>  \
+Array<T>::sort_rows_idx (sortmode) const  \
+{ return Array<octave_idx_type> (); } \
+ \
+template <> sortmode  \
+Array<T>::is_sorted_rows (sortmode) const \
+{ return UNSORTED; } \
+ \
+template <> octave_idx_type  \
+Array<T>::lookup (T const &, sortmode) const \
+{ return 0; } \
+template <> Array<octave_idx_type>  \
+Array<T>::lookup (const Array<T>&, sortmode, bool, bool) const \
+{ return Array<octave_idx_type> (); } \
+template <> Array<octave_idx_type> \
+Array<T>::find (octave_idx_type, bool) const\
+{ return Array<octave_idx_type> (); } \
+
+
+template <class T>
+Array<T>
+Array<T>::diag (octave_idx_type k) const
+{
+  dim_vector dv = dims ();
+  octave_idx_type nd = dv.length ();
+  Array<T> d;
+
+  if (nd > 2)
+    (*current_liboctave_error_handler) ("Matrix must be 2-dimensional");    
+  else
+    {
+      octave_idx_type nnr = dv (0);
+      octave_idx_type nnc = dv (1);
+
+      if (nnr == 0 || nnc == 0)
+	; // do nothing
+      else if (nnr != 1 && nnc != 1)
+	{
+	  if (k > 0)
+	    nnc -= k;
+	  else if (k < 0)
+	    nnr += k;
+
+	  if (nnr > 0 && nnc > 0)
+	    {
+	      octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc;
+
+	      d.resize (dim_vector (ndiag, 1));
+
+	      if (k > 0)
+		{
+		  for (octave_idx_type i = 0; i < ndiag; i++)
+		    d.xelem (i) = elem (i, i+k);
+		}
+	      else if (k < 0)
+		{
+		  for (octave_idx_type i = 0; i < ndiag; i++)
+		    d.xelem (i) = elem (i-k, i);
+		}
+	      else
+		{
+		  for (octave_idx_type i = 0; i < ndiag; i++)
+		    d.xelem (i) = elem (i, i);
+		}
+	    }
+	  else
+	    (*current_liboctave_error_handler)
+	      ("diag: requested diagonal out of range");
+	}
+      else if (nnr != 0 && nnc != 0)
+	{
+	  octave_idx_type roff = 0;
+	  octave_idx_type coff = 0;
+	  if (k > 0)
+	    {
+	      roff = 0;
+	      coff = k;
+	    }
+	  else if (k < 0)
+	    {
+	      roff = -k;
+	      coff = 0;
+	    }
+
+	  if (nnr == 1)
+	    {
+	      octave_idx_type n = nnc + std::abs (k);
+	      d = Array<T> (dim_vector (n, n), resize_fill_value ());
+
+	      for (octave_idx_type i = 0; i < nnc; i++)
+		d.xelem (i+roff, i+coff) = elem (0, i);
+	    }
+	  else
+	    {
+	      octave_idx_type n = nnr + std::abs (k);
+	      d = Array<T> (dim_vector (n, n), resize_fill_value ());
+
+	      for (octave_idx_type i = 0; i < nnr; i++)
+		d.xelem (i+roff, i+coff) = elem (i, 0);
+	    }
+	}
+    }
+
+  return d;
+}
+
+template <class T>
+void
+Array<T>::print_info (std::ostream& os, const std::string& prefix) const
+{
+  os << prefix << "rep address: " << rep << '\n'
+     << prefix << "rep->len:    " << rep->len << '\n'
+     << prefix << "rep->data:   " << static_cast<void *> (rep->data) << '\n'
+     << prefix << "rep->count:  " << rep->count << '\n'
+     << prefix << "slice_data:  " << static_cast<void *> (slice_data) << '\n'
+     << prefix << "slice_len:   " << slice_len << '\n';
+
+  // 2D info:
+  //
+  //     << pefix << "rows: " << rows () << "\n"
+  //     << prefix << "cols: " << cols () << "\n";
+}
+
+template <class T>
+void Array<T>::instantiation_guard ()
+{
+  // This guards against accidental implicit instantiations.
+  // Array<T> instances should always be explicit and use INSTANTIATE_ARRAY.
+  T::__xXxXx__();
+}
+
+#define INSTANTIATE_ARRAY(T, API) \
+  template <> void Array<T>::instantiation_guard () { } \
+  template class API Array<T>
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array.h b/liboctave/Array.h
new file mode 100644
index 0000000..da69e5e
--- /dev/null
+++ b/liboctave/Array.h
@@ -0,0 +1,643 @@
+// Template array classes
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Array_h)
+#define octave_Array_h 1
+
+#include <cassert>
+#include <cstddef>
+
+#include <algorithm>
+#include <iosfwd>
+
+#include "dim-vector.h"
+#include "idx-vector.h"
+#include "lo-traits.h"
+#include "lo-utils.h"
+#include "oct-sort.h"
+#include "quit.h"
+
+// One dimensional array class.  Handles the reference counting for
+// all the derived classes.
+
+template <class T>
+class
+Array
+{
+protected:
+
+  //--------------------------------------------------------------------
+  // The real representation of all arrays.
+  //--------------------------------------------------------------------
+
+  class ArrayRep
+  {
+  public:
+
+    T *data;
+    octave_idx_type len;
+    int count;
+
+    ArrayRep (T *d, octave_idx_type l, bool copy = false) 
+      : data (copy ? new T [l] : d), len (l), count (1) 
+        { 
+          if (copy)
+            std::copy (d, d + l, data);
+        }
+
+    ArrayRep (void) : data (0), len (0), count (1) { }
+
+    explicit ArrayRep (octave_idx_type n) : data (new T [n]), len (n), count (1) { }
+
+    explicit ArrayRep (octave_idx_type n, const T& val)
+      : data (new T [n]), len (n), count (1)
+      {
+        std::fill (data, data + n, val);
+      }
+
+    ArrayRep (const ArrayRep& a)
+      : data (new T [a.len]), len (a.len), count (1)
+      {
+        std::copy (a.data, a.data + a.len, data);
+      }
+ 
+    ~ArrayRep (void) { delete [] data; }
+
+    octave_idx_type length (void) const { return len; }
+
+  private:
+
+    // No assignment!
+
+    ArrayRep& operator = (const ArrayRep& a);
+  };
+
+  //--------------------------------------------------------------------
+
+public:
+
+  void make_unique (void);
+
+  typedef T element_type;
+
+  typedef bool (*compare_fcn_type) (typename ref_param<T>::type,
+				    typename ref_param<T>::type);
+
+protected:
+
+  typename Array<T>::ArrayRep *rep;
+
+  dim_vector dimensions;
+
+  // Rationale:
+  // slice_data is a pointer to rep->data, denoting together with slice_len the
+  // actual portion of the data referenced by this Array<T> object. This allows
+  // to make shallow copies not only of a whole array, but also of contiguous
+  // subranges. Every time rep is directly manipulated, slice_data and slice_len
+  // need to be properly updated.
+
+  T* slice_data;
+  octave_idx_type slice_len;
+
+  Array (T *d, octave_idx_type n)
+    : rep (new typename Array<T>::ArrayRep (d, n)), dimensions (n) 
+    { 
+      slice_data = rep->data;
+      slice_len = rep->len;
+    }
+
+  Array (T *d, const dim_vector& dv)
+    : rep (new typename Array<T>::ArrayRep (d, get_size (dv))),
+      dimensions (dv) 
+    { 
+      slice_data = rep->data;
+      slice_len = rep->len;
+    }
+
+  // slice constructor
+  Array (const Array<T>& a, const dim_vector& dv,
+         octave_idx_type l, octave_idx_type u)
+    : rep(a.rep), dimensions (dv)
+    {
+      rep->count++;
+      slice_data = a.slice_data + l;
+      slice_len = std::min (u, a.slice_len) - l;
+    }
+
+private:
+
+  typename Array<T>::ArrayRep *nil_rep (void) const
+    {
+      static typename Array<T>::ArrayRep *nr
+	= new typename Array<T>::ArrayRep ();
+
+      return nr;
+    }
+
+  template <class U>
+  T *
+  coerce (const U *a, octave_idx_type len)
+  {
+    T *retval = new T [len];
+
+    for (octave_idx_type i = 0; i < len; i++)
+      retval[i] = T (a[i]);
+
+    return retval;
+  }
+
+public:
+
+  Array (void)
+    : rep (nil_rep ()), dimensions () 
+    { 
+      rep->count++; 
+      slice_data = rep->data;
+      slice_len = rep->len;
+    }
+
+  explicit Array (octave_idx_type n)
+    : rep (new typename Array<T>::ArrayRep (n)), dimensions (n) 
+    { 
+      slice_data = rep->data;
+      slice_len = rep->len;
+    }
+
+  explicit Array (octave_idx_type n, const T& val)
+    : rep (new typename Array<T>::ArrayRep (n)), dimensions (n)
+    {
+      slice_data = rep->data;
+      slice_len = rep->len;
+      fill (val);
+    }
+
+  // Type conversion case.
+  template <class U>
+  Array (const Array<U>& a)
+    : rep (new typename Array<T>::ArrayRep (coerce (a.data (), a.length ()), a.length ())),
+      dimensions (a.dims ())
+    {
+      slice_data = rep->data;
+      slice_len = rep->len;
+    }
+
+  // No type conversion case.
+  Array (const Array<T>& a)
+    : rep (a.rep), dimensions (a.dimensions)
+    {
+      rep->count++;
+      slice_data = a.slice_data;
+      slice_len = a.slice_len;
+    }
+
+public:
+
+  Array (const dim_vector& dv)
+    : rep (new typename Array<T>::ArrayRep (get_size (dv))),
+      dimensions (dv) 
+    { 
+      slice_data = rep->data;
+      slice_len = rep->len;
+    }
+
+  Array (const dim_vector& dv, const T& val)
+    : rep (new typename Array<T>::ArrayRep (get_size (dv))),
+      dimensions (dv)
+    {
+      slice_data = rep->data;
+      slice_len = rep->len;
+      fill (val);
+    }
+
+  Array (const Array<T>& a, const dim_vector& dv);
+
+  virtual ~Array (void);
+
+  Array<T>& operator = (const Array<T>& a);
+
+  void fill (const T& val); 
+
+  octave_idx_type capacity (void) const { return slice_len; }
+  octave_idx_type length (void) const { return capacity (); }
+  octave_idx_type nelem (void) const { return capacity (); }
+  octave_idx_type numel (void) const { return nelem (); }
+
+  octave_idx_type dim1 (void) const { return dimensions(0); }
+  octave_idx_type dim2 (void) const { return dimensions(1); }
+  octave_idx_type dim3 (void) const { return dimensions(2); }
+
+  octave_idx_type rows (void) const { return dim1 (); }
+  octave_idx_type cols (void) const { return dim2 (); }
+  octave_idx_type columns (void) const { return dim2 (); }
+  octave_idx_type pages (void) const { return dim3 (); }
+
+  size_t byte_size (void) const { return numel () * sizeof (T); }
+
+  // Return a const-reference so that dims ()(i) works efficiently.
+  const dim_vector& dims (void) const { return dimensions; }
+
+  Array<T> squeeze (void) const;
+  
+  void chop_trailing_singletons (void) 
+  { dimensions.chop_trailing_singletons (); }
+  
+  static octave_idx_type get_size (octave_idx_type r, octave_idx_type c);
+  static octave_idx_type get_size (octave_idx_type r, octave_idx_type c, octave_idx_type p);
+  static octave_idx_type get_size (const dim_vector& dv);
+
+  octave_idx_type compute_index (const Array<octave_idx_type>& ra_idx) const;
+
+  T range_error (const char *fcn, octave_idx_type n) const;
+  T& range_error (const char *fcn, octave_idx_type n);
+
+  T range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const;
+  T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j);
+
+  T range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k) const;
+  T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k);
+
+  T range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const;
+  T& range_error (const char *fcn, const Array<octave_idx_type>& ra_idx);
+
+  // No checking, even for multiple references, ever.
+
+  T& xelem (octave_idx_type n) { return slice_data [n]; }
+  T xelem (octave_idx_type n) const { return slice_data [n]; }
+
+  T& xelem (octave_idx_type i, octave_idx_type j) { return xelem (dim1()*j+i); }
+  T xelem (octave_idx_type i, octave_idx_type j) const { return xelem (dim1()*j+i); }
+
+  T& xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return xelem (i, dim2()*k+j); }
+  T xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return xelem (i, dim2()*k+j); }
+
+  T& xelem (const Array<octave_idx_type>& ra_idx)
+    { return xelem (compute_index (ra_idx)); }
+
+  T xelem (const Array<octave_idx_type>& ra_idx) const
+    { return xelem (compute_index (ra_idx)); }
+
+  // FIXME -- would be nice to fix this so that we don't
+  // unnecessarily force a copy, but that is not so easy, and I see no
+  // clean way to do it.
+
+  T& checkelem (octave_idx_type n)
+    {
+      if (n < 0 || n >= slice_len)
+	return range_error ("T& Array<T>::checkelem", n);
+      else
+	{
+	  make_unique ();
+	  return xelem (n);
+	}
+    }
+
+  T& checkelem (octave_idx_type i, octave_idx_type j)
+    {
+      if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
+	return range_error ("T& Array<T>::checkelem", i, j);
+      else
+	return elem (dim1()*j+i);
+    }
+
+  T& checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k)
+    {
+      if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ())
+	return range_error ("T& Array<T>::checkelem", i, j, k);
+      else
+	return elem (i, dim2()*k+j);
+    }
+
+  T& checkelem (const Array<octave_idx_type>& ra_idx)
+    {
+      octave_idx_type i = compute_index (ra_idx);
+
+      if (i < 0)
+	return range_error ("T& Array<T>::checkelem", ra_idx);
+      else
+	return elem (i);
+    }
+
+  T& elem (octave_idx_type n)
+    {
+      make_unique ();
+      return xelem (n);
+    }
+
+  T& elem (octave_idx_type i, octave_idx_type j) { return elem (dim1()*j+i); }
+
+  T& elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, dim2()*k+j); }
+
+  T& elem (const Array<octave_idx_type>& ra_idx)
+    { return Array<T>::elem (compute_index (ra_idx)); }
+
+#if defined (BOUNDS_CHECKING)
+  T& operator () (octave_idx_type n) { return checkelem (n); }
+  T& operator () (octave_idx_type i, octave_idx_type j) { return checkelem (i, j); }
+  T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return checkelem (i, j, k); }
+  T& operator () (const Array<octave_idx_type>& ra_idx) { return checkelem (ra_idx); }
+#else
+  T& operator () (octave_idx_type n) { return elem (n); }
+  T& operator () (octave_idx_type i, octave_idx_type j) { return elem (i, j); }
+  T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, j, k); }
+  T& operator () (const Array<octave_idx_type>& ra_idx) { return elem (ra_idx); }
+#endif
+
+  T checkelem (octave_idx_type n) const
+    {
+      if (n < 0 || n >= slice_len)
+	return range_error ("T Array<T>::checkelem", n);
+      else
+	return xelem (n);
+    }
+
+  T checkelem (octave_idx_type i, octave_idx_type j) const
+    {
+      if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
+	return range_error ("T Array<T>::checkelem", i, j);
+      else
+	return elem (dim1()*j+i);
+    }
+
+  T checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const
+    {
+      if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ())
+	return range_error ("T Array<T>::checkelem", i, j, k);
+      else
+	return Array<T>::elem (i, Array<T>::dim1()*k+j);
+    }
+
+  T checkelem (const Array<octave_idx_type>& ra_idx) const
+    {
+      octave_idx_type i = compute_index (ra_idx);
+
+      if (i < 0)
+	return range_error ("T Array<T>::checkelem", ra_idx);
+      else
+	return Array<T>::elem (i);
+    }
+
+  T elem (octave_idx_type n) const { return xelem (n); }
+
+  T elem (octave_idx_type i, octave_idx_type j) const { return elem (dim1()*j+i); }
+
+  T elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return elem (i, dim2()*k+j); }
+
+  T elem (const Array<octave_idx_type>& ra_idx) const
+    { return Array<T>::elem (compute_index (ra_idx)); }
+
+#if defined (BOUNDS_CHECKING)
+  T operator () (octave_idx_type n) const { return checkelem (n); }
+  T operator () (octave_idx_type i, octave_idx_type j) const { return checkelem (i, j); }
+  T operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return checkelem (i, j, k); }
+  T operator () (const Array<octave_idx_type>& ra_idx) const { return checkelem (ra_idx); }
+#else
+  T operator () (octave_idx_type n) const { return elem (n); }
+  T operator () (octave_idx_type i, octave_idx_type j) const { return elem (i, j); }
+  T operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return elem (i, j, k); }
+  T operator () (const Array<octave_idx_type>& ra_idx) const { return elem (ra_idx); }
+#endif
+
+  Array<T> reshape (const dim_vector& new_dims) const;
+
+  Array<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const;
+  Array<T> ipermute (const Array<octave_idx_type>& vec) const
+    { return permute (vec, true); }
+
+  bool is_square (void) const { return (dim1 () == dim2 ()); }
+
+  bool is_empty (void) const { return numel () == 0; }
+
+  bool is_vector (void) const { return dimensions.is_vector (); }
+
+  Array<T> transpose (void) const;
+  Array<T> hermitian (T (*fcn) (const T&) = 0) const;
+
+  const T *data (void) const { return slice_data; }
+
+  const T *fortran_vec (void) const { return data (); }
+
+  T *fortran_vec (void);
+
+  int ndims (void) const { return dimensions.length (); }
+
+  void maybe_delete_dims (void);
+
+  // Indexing without resizing.
+
+  Array<T> index (const idx_vector& i) const;
+
+  Array<T> index (const idx_vector& i, const idx_vector& j) const;
+
+  Array<T> index (const Array<idx_vector>& ia) const;
+
+  static T resize_fill_value (); 
+
+  // Resizing (with fill).
+
+  void resize_fill (octave_idx_type n, const T& rfv);
+
+  void resize_fill (octave_idx_type nr, octave_idx_type nc, const T& rfv);
+
+  void resize_fill (const dim_vector& dv, const T& rfv);
+
+  // Resizing with default fill.
+  // Rationale: 
+  // These use the default fill value rather than leaving memory uninitialized.
+  // Resizing without fill leaves the resulting array in a rather weird state,
+  // where part of the data is initialized an part isn't.
+
+  void resize (octave_idx_type n)
+    { resize_fill (n, resize_fill_value ()); }
+
+  // FIXME -- this method cannot be defined here because it would
+  // clash with
+  //
+  //   void resize (octave_idx_type, const T&)
+  //
+  // (these become indistinguishable when T = octave_idx_type).
+  // In the future, I think the resize (.., const T& rfv) overloads
+  // should go away in favor of using resize_fill.
+
+  // void resize (octave_idx_type nr, octave_idx_type nc)
+  //  { resize_fill (nr, nc, resize_fill_value ()); }
+
+  void resize (dim_vector dv)
+    { resize_fill (dv, resize_fill_value ()); }
+
+  // FIXME -- these are here for backward compatibility. They should
+  // go away in favor of using resize_fill directly.
+  void resize (octave_idx_type n, const T& rfv)
+    { resize_fill (n, static_cast<T> (rfv)); }
+
+  void resize (octave_idx_type nr, octave_idx_type nc, const T& rfv)
+    { resize_fill (nr, nc, rfv); }
+
+  void resize (dim_vector dv, const T& rfv)
+    { resize_fill (dv, rfv); }
+
+  // Indexing with possible resizing and fill
+  // FIXME -- this is really a corner case, that should better be
+  // handled directly in liboctinterp.
+
+  Array<T> index (const idx_vector& i, bool resize_ok,
+                  const T& rfv = resize_fill_value ()) const;
+
+  Array<T> index (const idx_vector& i, const idx_vector& j, 
+                  bool resize_ok, const T& rfv = resize_fill_value ()) const;
+
+  Array<T> index (const Array<idx_vector>& ia,
+                  bool resize_ok, const T& rfv = resize_fill_value ()) const;
+
+  // Indexed assignment (always with resize & fill).
+
+  void assign (const idx_vector& i, const Array<T>& rhs, 
+               const T& rfv = resize_fill_value ());
+
+  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs,
+               const T& rfv = resize_fill_value ());
+
+  void assign (const Array<idx_vector>& ia, const Array<T>& rhs,
+               const T& rfv = resize_fill_value ());
+
+  // Deleting elements.
+
+  // A(I) = [] (with a single subscript)
+  void delete_elements (const idx_vector& i);
+
+  // A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon)
+  void delete_elements (int dim, const idx_vector& i);
+
+  // Dispatcher to the above two.
+  void delete_elements (const Array<idx_vector>& ia);
+
+  // FIXME -- are these required? What exactly are they supposed to do?.
+
+  Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c);
+  Array<T>& insert2 (const Array<T>& a, octave_idx_type r, octave_idx_type c);
+  Array<T>& insertN (const Array<T>& a, octave_idx_type r, octave_idx_type c);
+
+  Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx);
+
+  void maybe_economize (void)
+    {
+      if (rep->count == 1 && slice_len != rep->len)
+        {
+          ArrayRep *new_rep = new ArrayRep (slice_data, slice_len, true);
+          delete rep;
+          rep = new_rep;
+          slice_data = rep->data;
+        }
+    }
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return const_cast<T *> (data ()); }
+
+  Array<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const;
+  Array<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		 sortmode mode = ASCENDING) const;
+
+  // Ordering is auto-detected or can be specified.
+  sortmode is_sorted (sortmode mode = UNSORTED) const;
+
+  // Sort by rows returns only indices.
+  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const;
+
+  // Ordering is auto-detected or can be specified.
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const;
+
+  // Do a binary lookup in a sorted array.
+  // Mode can be specified or is auto-detected by comparing 1st and last element.
+  octave_idx_type lookup (const T& value, sortmode mode = UNSORTED) const;
+
+  // Ditto, but for an array of values, specializing on long runs.
+  // If linf is true, the leftmost interval is extended to infinity 
+  // (indices will be >= 1).
+  // If rinf is true, the rightmost interval is extended to infinity 
+  // (indices will be <= length ()-1).
+  Array<octave_idx_type> lookup (const Array<T>& values, sortmode mode = UNSORTED, 
+                                 bool linf = false, bool rinf = false) const;
+
+  // Find indices of (at most n) nonzero elements. If n is specified, backward
+  // specifies search from backward.
+  Array<octave_idx_type> find (octave_idx_type n = -1, bool backward = false) const;
+
+  Array<T> diag (octave_idx_type k = 0) const;
+
+  template <class U, class F>
+  Array<U>
+  map (F fcn) const
+  {
+    octave_idx_type len = length ();
+
+    const T *m = data ();
+
+    Array<U> result (dims ());
+    U *p = result.fortran_vec ();
+
+    for (octave_idx_type i = 0; i < len; i++)
+      {
+	OCTAVE_QUIT;
+
+	p[i] = fcn (m[i]);
+      }
+
+    return result;
+  }
+
+  // This is non-breakable map, suitable for fast functions. Efficiency
+  // relies on compiler's ability to inline a function pointer. This seems
+  // to be OK with recent GCC.
+  template <class U>
+  Array<U>
+  fastmap (U (*fcn) (typename ref_param<T>::type)) const
+  {
+    octave_idx_type len = length ();
+
+    const T *m = data ();
+
+    Array<U> result (dims ());
+    U *p = result.fortran_vec ();
+
+    std::transform (m, m + len, p, fcn);
+
+    return result;
+  }
+
+  template <class U> friend class Array;
+
+private:
+  static void instantiation_guard ();
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array2.h b/liboctave/Array2.h
new file mode 100644
index 0000000..2f42759
--- /dev/null
+++ b/liboctave/Array2.h
@@ -0,0 +1,164 @@
+// Template array classes
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Array2_h)
+#define octave_Array2_h 1
+
+#include <cassert>
+#include <climits>
+#include <cstdlib>
+
+#include "Array.h"
+#include "lo-error.h"
+#include "lo-math.h"
+
+class idx_vector;
+
+// Two dimensional array class.
+
+template <class T>
+class
+Array2 : public Array<T>
+{
+protected:
+
+  static octave_idx_type get_size (octave_idx_type r, octave_idx_type c) { return Array<T>::get_size (r, c); }
+
+  Array2 (T *d, octave_idx_type r, octave_idx_type c) : Array<T> (d, dim_vector (r, c)) { }
+
+public:
+
+  Array2 (void) : Array<T> (dim_vector (0, 0)) { }
+
+  Array2 (octave_idx_type r, octave_idx_type c) : Array<T> (dim_vector (r, c)) { }
+
+  Array2 (octave_idx_type r, octave_idx_type c, const T& val)
+    : Array<T> (dim_vector (r, c), val) { }
+
+  Array2 (const dim_vector& dv) : Array<T> (dv) 
+    { 
+      if (dv.length () != 2)
+	(*current_liboctave_error_handler) ("too many dimensions");
+    }
+
+  Array2 (const dim_vector& dv, const T& val) : Array<T> (dv) 
+    { 
+      if (dv.length () != 2)
+	(*current_liboctave_error_handler) ("too many dimensions");
+      else
+	Array<T>::fill (val); 
+    }
+
+  Array2 (const Array2<T>& a) : Array<T> (a, a.dims ()) { }
+
+  Array2 (const Array<T>& a, octave_idx_type r, octave_idx_type c)
+    : Array<T> (a, dim_vector (r, c)) { }
+
+  template <class U>
+  Array2 (const Array<U>& a) : Array<T> (a) { }
+
+  template <class U>
+  Array2 (const Array<U>& a, const dim_vector& dv)
+    : Array<T> (a, dv) { }
+
+  ~Array2 (void) { }
+
+  Array2<T>& operator = (const Array2<T>& a)
+    {
+      if (this != &a)
+	Array<T>::operator = (a);
+
+      return *this;
+    }
+
+  void resize (octave_idx_type r, octave_idx_type c)
+    { Array<T>::resize_fill (r, c, Array<T>::resize_fill_value ()); }
+
+  void resize (octave_idx_type r, octave_idx_type c, const T& val)
+    { Array<T>::resize_fill (r, c, val); }
+
+  Array2<T>& insert (const Array2<T>& a, octave_idx_type r, octave_idx_type c)
+    {
+      Array<T>::insert (a, r, c);
+      return *this;
+    }
+
+  Array2<T> transpose (void) const
+    {
+      Array<T> tmp = Array<T>::transpose ();
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
+
+  Array2<T> hermitian (T (*fcn) (const T&) = 0) const
+    {
+      Array<T> tmp = Array<T>::hermitian (fcn);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
+
+  Array2<T> index (const idx_vector& i, bool resize_ok = false,
+		   const T& rfv = Array<T>::resize_fill_value ()) const
+    {
+      Array<T> tmp = Array<T>::index (i, resize_ok, rfv);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
+
+  Array2<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok = false,
+		   const T& rfv = Array<T>::resize_fill_value ()) const
+    {
+      Array<T> tmp = Array<T>::index (i, j, resize_ok, rfv);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
+
+  Array2<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    {
+      Array<T> tmp = Array<T>::sort (dim, mode);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
+
+  Array2<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		 sortmode mode = ASCENDING) const
+    {
+      Array<T> tmp = Array<T>::sort (sidx, dim, mode);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
+
+  Array2<T> diag (octave_idx_type k) const
+  {
+    return Array<T>::diag (k);
+  }
+
+  template <class U, class F>
+  Array2<U> map (F fcn) const
+  {
+    return Array<T>::template map<U> (fcn);
+  }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Array3.h b/liboctave/Array3.h
new file mode 100644
index 0000000..b71febc
--- /dev/null
+++ b/liboctave/Array3.h
@@ -0,0 +1,100 @@
+// Template array classes
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Array3_h)
+#define octave_Array3_h 1
+
+#include <cassert>
+#include <cstdlib>
+
+#include "Array.h"
+#include "lo-error.h"
+
+class idx_vector;
+
+// Three dimensional array class.
+
+template <class T>
+class
+Array3 : public Array<T>
+{
+protected:
+
+  static octave_idx_type get_size (octave_idx_type r, octave_idx_type c, octave_idx_type p)
+    { return Array<T>::get_size (r, c, p); }
+
+  Array3 (T *d, octave_idx_type r, octave_idx_type c, octave_idx_type p) : Array<T> (d, dim_vector (r, c, p)) { }
+
+public:
+
+  Array3 (void) : Array<T> (dim_vector (0, 0, 0)) { }
+
+  Array3 (octave_idx_type r, octave_idx_type c, octave_idx_type p) : Array<T> (dim_vector (r, c, p)) { }
+
+  Array3 (octave_idx_type r, octave_idx_type c, octave_idx_type p, const T& val)
+    : Array<T> (dim_vector (r, c, p), val) { }
+
+  Array3 (const Array3<T>& a)
+    : Array<T> (a, a.dims ()) { }
+
+  Array3 (const Array<T>& a, octave_idx_type r, octave_idx_type c, octave_idx_type p)
+    : Array<T> (a, dim_vector (r, c, p)) { }
+
+  ~Array3 (void) { }
+
+  Array3<T>& operator = (const Array3<T>& a)
+    {
+      if (this != &a)
+	Array<T>::operator = (a);
+
+      return *this;
+    }
+
+  void resize (octave_idx_type r, octave_idx_type c, octave_idx_type p) 
+    { Array<T>::resize (dim_vector (r, c, p)); }
+
+  void resize (octave_idx_type r, octave_idx_type c, octave_idx_type p, const T& val)
+    { Array<T>::resize_fill (dim_vector (r, c, p), val); }
+
+  Array3<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    {
+      Array<T> tmp = Array<T>::sort (dim, mode);
+      return Array3<T> (tmp, tmp.rows (), tmp.columns (), tmp.pages ());
+    }
+
+  Array3<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		 sortmode mode = ASCENDING) const
+    {
+      Array<T> tmp = Array<T>::sort (sidx, dim, mode);
+      return Array3<T> (tmp, tmp.rows (), tmp.columns (), tmp.pages ());
+    }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ArrayN.cc b/liboctave/ArrayN.cc
new file mode 100644
index 0000000..2c66ff8
--- /dev/null
+++ b/liboctave/ArrayN.cc
@@ -0,0 +1,144 @@
+// Template array classes
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "ArrayN.h"
+#include "idx-vector.h"
+#include "lo-error.h"
+
+// N-dimensional array class.
+
+template <class T>
+std::ostream&
+operator << (std::ostream& os, const ArrayN<T>& a)
+{
+  dim_vector a_dims = a.dims ();
+
+  int n_dims = a_dims.length ();
+
+  os << n_dims << "-dimensional array";
+
+  if (n_dims)
+    os << " (" << a_dims.str () << ")";
+
+  os <<"\n\n";
+
+  if (n_dims)
+    {
+      os << "data:";
+
+      Array<octave_idx_type> ra_idx (n_dims, 0);
+
+      // Number of times the first 2d-array is to be displayed.
+
+      octave_idx_type m = 1;
+      for (int i = 2; i < n_dims; i++)
+	m *= a_dims(i);
+
+      if (m == 1)
+        {
+          octave_idx_type rows = 0;
+          octave_idx_type cols = 0;
+
+          switch (n_dims)
+            {
+	    case 2:
+	      rows = a_dims(0);
+	      cols = a_dims(1);
+
+	      for (octave_idx_type j = 0; j < rows; j++)
+		{
+		  ra_idx(0) = j;
+		  for (octave_idx_type k = 0; k < cols; k++)
+		    {
+		      ra_idx(1) = k;
+		      os << " " << a.elem(ra_idx);
+		    }
+		  os << "\n";
+		}
+	      break;
+
+	    default:
+	      rows = a_dims(0);
+
+	      for (octave_idx_type k = 0; k < rows; k++)
+		{
+		  ra_idx(0) = k;
+		  os << " " << a.elem(ra_idx);
+		}
+	      break;
+	    }
+
+          os << "\n";
+        }
+      else
+        {
+          octave_idx_type rows = a_dims(0);
+          octave_idx_type cols = a_dims(1);
+
+          for (int i = 0; i < m; i++)
+            {
+              os << "\n(:,:,";
+
+              for (int j = 2; j < n_dims - 1; j++)
+		os << ra_idx(j) + 1 << ",";
+
+	      os << ra_idx(n_dims - 1) + 1 << ") = \n";
+
+	      for (octave_idx_type j = 0; j < rows; j++)
+	        {
+	          ra_idx(0) = j;
+
+	          for (octave_idx_type k = 0; k < cols; k++)
+	            {
+		      ra_idx(1) = k;
+		      os << " " << a.elem(ra_idx);
+		    }
+
+	          os << "\n";
+	        }
+
+	      os << "\n";
+
+	      if (i != m - 1)
+		increment_index (ra_idx, a_dims, 2);
+            }
+        }
+    }
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ArrayN.h b/liboctave/ArrayN.h
new file mode 100644
index 0000000..0c751dc
--- /dev/null
+++ b/liboctave/ArrayN.h
@@ -0,0 +1,169 @@
+// Template array classes
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ArrayN_h)
+#define octave_ArrayN_h 1
+
+#include <cassert>
+#include <climits>
+#include <cstdlib>
+
+#include <iosfwd>
+
+#include "Array.h"
+#include "Array2.h"
+#include "lo-error.h"
+#include "lo-math.h"
+
+class idx_vector;
+
+// N-dimensional array class.
+
+template <class T>
+class
+ArrayN : public Array<T>
+{
+protected:
+
+  ArrayN (T *d, const dim_vector& dv) : Array<T> (d, dv) { }
+
+public:
+
+  // These really need to be protected (and they will be in the
+  // future, so don't depend on them being here!), but they can't be
+  // until template friends work correctly in g++.
+
+  ArrayN (void) : Array<T> () { }
+
+  ArrayN (const dim_vector& dv) : Array<T> (dv) { }
+
+  ArrayN (const dim_vector& dv, const T& val)
+    : Array<T> (dv) { Array<T>::fill (val); }
+
+  template <class U>
+  explicit ArrayN (const Array2<U>& a) : Array<T> (a, a.dims ()) { }
+
+  template <class U>
+  ArrayN (const ArrayN<U>& a) : Array<T> (a, a.dims ()) { }
+
+  template <class U>
+  ArrayN (const Array<U>& a) : Array<T> (a) { }
+
+  template <class U>
+  ArrayN (const Array<U>& a, const dim_vector& dv)
+    : Array<T> (a, dv) { }
+
+  ~ArrayN (void) { }
+
+  ArrayN<T>& operator = (const ArrayN<T>& a)
+    {
+      if (this != &a)
+	Array<T>::operator = (a);
+
+      return *this;
+    }
+
+  ArrayN<T> reshape (const dim_vector& new_dims) const
+    { return Array<T>::reshape (new_dims); }
+
+  ArrayN<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const
+    { return Array<T>::permute (vec, inv); }
+
+  ArrayN<T> ipermute (const Array<octave_idx_type>& vec) const
+    { return Array<T>::ipermute (vec); }
+
+  ArrayN<T> squeeze (void) const { return Array<T>::squeeze (); }
+
+  ArrayN<T> transpose (void) const { return Array<T>::transpose (); }
+  ArrayN<T> hermitian (T (*fcn) (const T&) = 0) const { return Array<T>::hermitian (fcn); }
+
+  ArrayN<T>& insert (const ArrayN<T>& a, const dim_vector& dv)
+    {
+      Array<T>::insert (a, dv);
+      return *this;
+    }
+
+  ArrayN<T>& insert (const ArrayN<T>& a, octave_idx_type r, octave_idx_type c)
+  {
+    Array<T>::insert (a, r, c);
+    return *this;
+  }
+
+  ArrayN<T> index (const idx_vector& i, bool resize_ok = false,
+		   const T& rfv = Array<T>::resize_fill_value ()) const
+    {
+      Array<T> tmp = Array<T>::index (i, resize_ok, rfv);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
+
+  ArrayN<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok = false,
+		   const T& rfv = Array<T>::resize_fill_value ()) const
+    {
+      Array<T> tmp = Array<T>::index (i, j, resize_ok, rfv);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
+
+  ArrayN<T> index (const Array<idx_vector>& ra_idx, bool resize_ok = false,
+		   const T& rfv = Array<T>::resize_fill_value ()) const
+    {
+      Array<T> tmp = Array<T>::index (ra_idx, resize_ok, rfv);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
+
+  ArrayN<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    {
+      Array<T> tmp = Array<T>::sort (dim, mode);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
+
+  ArrayN<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		 sortmode mode = ASCENDING) const
+    {
+      Array<T> tmp = Array<T>::sort (sidx, dim, mode);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
+
+  ArrayN<T> diag (octave_idx_type k) const
+  {
+    return Array<T>::diag (k);
+  }
+
+  template <class U, class F>
+  ArrayN<U> map (F fcn) const
+  {
+    return Array<T>::template map<U> (fcn);
+  }
+};
+
+template <class T>
+std::ostream&
+operator << (std::ostream&, const ArrayN<T>&);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CColVector.cc b/liboctave/CColVector.cc
new file mode 100644
index 0000000..e36a517
--- /dev/null
+++ b/liboctave/CColVector.cc
@@ -0,0 +1,546 @@
+// ColumnVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgemv, ZGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const Complex&,
+			   const Complex*, const octave_idx_type&, const Complex*,
+			   const octave_idx_type&, const Complex&, Complex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+}
+
+// Complex Column Vector class
+
+ComplexColumnVector::ComplexColumnVector (const ColumnVector& a)
+   : MArray<Complex> (a.length ())
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i) = a.elem (i);
+}
+
+bool
+ComplexColumnVector::operator == (const ComplexColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+ComplexColumnVector::operator != (const ComplexColumnVector& a) const
+{
+  return !(*this == a);
+}
+
+// destructive insert/delete/reorder operations
+
+ComplexColumnVector&
+ComplexColumnVector::insert (const ColumnVector& a, octave_idx_type r)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::insert (const ComplexColumnVector& a, octave_idx_type r)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::fill (double val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::fill (const Complex& val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::fill (double val, octave_idx_type r1, octave_idx_type r2)
+{
+  octave_idx_type len = length ();
+
+  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  if (r2 >= r1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = r1; i <= r2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::fill (const Complex& val, octave_idx_type r1, octave_idx_type r2)
+{
+  octave_idx_type len = length ();
+
+  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  if (r2 >= r1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = r1; i <= r2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexColumnVector
+ComplexColumnVector::stack (const ColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nr_insert = len;
+  ComplexColumnVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nr_insert);
+  return retval;
+}
+
+ComplexColumnVector
+ComplexColumnVector::stack (const ComplexColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nr_insert = len;
+  ComplexColumnVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nr_insert);
+  return retval;
+}
+
+ComplexRowVector 
+ComplexColumnVector::hermitian (void) const
+{ 
+  return MArray<Complex>::hermitian (std::conj);
+}
+
+ComplexRowVector
+ComplexColumnVector::transpose (void) const
+{
+  return MArray<Complex>::transpose ();
+}
+
+ComplexColumnVector
+conj (const ComplexColumnVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  ComplexColumnVector retval;
+  if (a_len > 0)
+    retval = ComplexColumnVector (mx_inline_conj_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+// resize is the destructive equivalent for this one
+
+ComplexColumnVector
+ComplexColumnVector::extract (octave_idx_type r1, octave_idx_type r2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+
+  ComplexColumnVector result (new_r);
+
+  for (octave_idx_type i = 0; i < new_r; i++)
+    result.elem (i) = elem (r1+i);
+
+  return result;
+}
+
+ComplexColumnVector
+ComplexColumnVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  ComplexColumnVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.elem (i) = elem (r1+i);
+
+  return result;
+}
+
+// column vector by column vector -> column vector operations
+
+ComplexColumnVector&
+ComplexColumnVector::operator += (const ColumnVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator +=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::operator -= (const ColumnVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator -=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_subtract2 (d, a.data (), len);
+  return *this;
+}
+
+// matrix by column vector -> column vector operations
+
+ComplexColumnVector
+operator * (const ComplexMatrix& m, const ColumnVector& a)
+{
+  ComplexColumnVector tmp (a);
+  return m * tmp;
+}
+
+ComplexColumnVector
+operator * (const ComplexMatrix& m, const ComplexColumnVector& a)
+{
+  ComplexColumnVector retval;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+  else
+    {
+      if (nc == 0 || nr == 0)
+	retval.resize (nr, 0.0);
+      else
+	{
+	  octave_idx_type ld = nr;
+
+	  retval.resize (nr);
+	  Complex *y = retval.fortran_vec ();
+
+	  F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
+				   nr, nc, 1.0, m.data (), ld,
+				   a.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+// matrix by column vector -> column vector operations
+
+ComplexColumnVector
+operator * (const Matrix& m, const ComplexColumnVector& a)
+{
+  ComplexMatrix tmp (m);
+  return tmp * a;
+}
+
+// diagonal matrix by column vector -> column vector operations
+
+ComplexColumnVector
+operator * (const DiagMatrix& m, const ComplexColumnVector& a)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+      return ComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return ComplexColumnVector (0);
+
+  ComplexColumnVector result (nr);
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (octave_idx_type i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
+
+ComplexColumnVector
+operator * (const ComplexDiagMatrix& m, const ColumnVector& a)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+      return ComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return ComplexColumnVector (0);
+
+  ComplexColumnVector result (nr);
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (octave_idx_type i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
+
+ComplexColumnVector
+operator * (const ComplexDiagMatrix& m, const ComplexColumnVector& a)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+      return ComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return ComplexColumnVector (0);
+
+  ComplexColumnVector result (nr);
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (octave_idx_type i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
+
+// other operations
+
+ColumnVector
+ComplexColumnVector::map (dmapper fcn) const
+{
+  return MArray<Complex>::map<double> (func_ptr (fcn));
+}
+
+ComplexColumnVector
+ComplexColumnVector::map (cmapper fcn) const
+{
+  return MArray<Complex>::map<Complex> (func_ptr (fcn));
+}
+
+Complex
+ComplexColumnVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  Complex res = elem (0);
+  double absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) < absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+Complex
+ComplexColumnVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  Complex res = elem (0);
+  double absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) > absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const ComplexColumnVector& a)
+{
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << /* setw (field_width) << */ a.elem (i) << "\n";
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, ComplexColumnVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      double tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CColVector.h b/liboctave/CColVector.h
new file mode 100644
index 0000000..53f4d8f
--- /dev/null
+++ b/liboctave/CColVector.h
@@ -0,0 +1,144 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexColumnVector_h)
+#define octave_ComplexColumnVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+ComplexColumnVector : public MArray<Complex>
+{
+friend class ComplexMatrix;
+friend class ComplexRowVector;
+
+public:
+
+  ComplexColumnVector (void) : MArray<Complex> () { }
+
+  explicit ComplexColumnVector (octave_idx_type n) : MArray<Complex> (n) { }
+
+  ComplexColumnVector (octave_idx_type n, const Complex& val)
+    : MArray<Complex> (n, val) { }
+
+  ComplexColumnVector (const ComplexColumnVector& a) : MArray<Complex> (a) { }
+
+  ComplexColumnVector (const MArray<Complex>& a) : MArray<Complex> (a) { }
+
+  explicit ComplexColumnVector (const ColumnVector& a);
+
+  ComplexColumnVector& operator = (const ComplexColumnVector& a)
+    {
+      MArray<Complex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const ComplexColumnVector& a) const;
+  bool operator != (const ComplexColumnVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  ComplexColumnVector& insert (const ColumnVector& a, octave_idx_type r);
+  ComplexColumnVector& insert (const ComplexColumnVector& a, octave_idx_type r);
+
+  ComplexColumnVector& fill (double val);
+  ComplexColumnVector& fill (const Complex& val);
+  ComplexColumnVector& fill (double val, octave_idx_type r1, octave_idx_type r2);
+  ComplexColumnVector& fill (const Complex& val, octave_idx_type r1, octave_idx_type r2);
+
+  ComplexColumnVector stack (const ColumnVector& a) const;
+  ComplexColumnVector stack (const ComplexColumnVector& a) const;
+
+  ComplexRowVector hermitian (void) const;
+  ComplexRowVector transpose (void) const;
+
+  friend OCTAVE_API ComplexColumnVector conj (const ComplexColumnVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  ComplexColumnVector extract (octave_idx_type r1, octave_idx_type r2) const;
+
+  ComplexColumnVector extract_n (octave_idx_type r1, octave_idx_type n) const;
+
+  // column vector by column vector -> column vector operations
+
+  ComplexColumnVector& operator += (const ColumnVector& a);
+  ComplexColumnVector& operator -= (const ColumnVector& a);
+
+  // matrix by column vector -> column vector operations
+
+  friend OCTAVE_API ComplexColumnVector operator * (const ComplexMatrix& a,
+					 const ColumnVector& b);
+
+  friend OCTAVE_API ComplexColumnVector operator * (const ComplexMatrix& a,
+					 const ComplexColumnVector& b);
+
+  // matrix by column vector -> column vector operations
+
+  friend OCTAVE_API ComplexColumnVector operator * (const Matrix& a,
+					 const ComplexColumnVector& b);
+
+  // diagonal matrix by column vector -> column vector operations
+
+  friend OCTAVE_API ComplexColumnVector operator * (const DiagMatrix& a,
+					 const ComplexColumnVector& b);
+
+  friend OCTAVE_API ComplexColumnVector operator * (const ComplexDiagMatrix& a,
+					 const ColumnVector& b);
+
+  friend OCTAVE_API ComplexColumnVector operator * (const ComplexDiagMatrix& a,
+					 const ComplexColumnVector& b);
+
+  // other operations
+
+  typedef double (*dmapper) (const Complex&);
+  typedef Complex (*cmapper) (const Complex&);
+
+  ColumnVector map (dmapper fcn) const;
+  ComplexColumnVector map (cmapper fcn) const;
+
+  Complex min (void) const;
+  Complex max (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexColumnVector& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, ComplexColumnVector& a);
+
+private:
+
+  ComplexColumnVector (Complex *d, octave_idx_type l) : MArray<Complex> (d, l) { }
+};
+
+MARRAY_FORWARD_DEFS (MArray, ComplexColumnVector, Complex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CDiagMatrix.cc b/liboctave/CDiagMatrix.cc
new file mode 100644
index 0000000..747ea76
--- /dev/null
+++ b/liboctave/CDiagMatrix.cc
@@ -0,0 +1,605 @@
+// DiagMatrix manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Complex Diagonal Matrix class
+
+ComplexDiagMatrix::ComplexDiagMatrix (const DiagMatrix& a)
+  : MDiagArray2<Complex> (a.rows (), a.cols ())
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+bool
+ComplexDiagMatrix::operator == (const ComplexDiagMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return 0;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+ComplexDiagMatrix::operator != (const ComplexDiagMatrix& a) const
+{
+  return !(*this == a);
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (double val)
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = val;
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const Complex& val)
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = val;
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (double val, octave_idx_type beg, octave_idx_type end)
+{
+  if (beg < 0 || end >= length () || end < beg)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = beg; i <= end; i++)
+    elem (i, i) = val;
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const Complex& val, octave_idx_type beg, octave_idx_type end)
+{
+  if (beg < 0 || end >= length () || end < beg)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = beg; i <= end; i++)
+    elem (i, i) = val;
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const ColumnVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const ComplexColumnVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const RowVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const ComplexRowVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const ColumnVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const ComplexColumnVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const RowVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::fill (const ComplexRowVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+DiagMatrix
+ComplexDiagMatrix::abs (void) const
+{
+  DiagMatrix retval (rows (), cols ());
+  for (octave_idx_type i = 0; i < rows (); i++)
+    retval(i, i) = std::abs (elem (i, i));
+  return retval;
+}
+
+ComplexDiagMatrix
+conj (const ComplexDiagMatrix& a)
+{
+  ComplexDiagMatrix retval;
+  octave_idx_type a_len = a.length ();
+  if (a_len > 0)
+    retval = ComplexDiagMatrix (mx_inline_conj_dup (a.data (), a_len),
+				a.rows (), a.cols ());
+  return retval;
+}
+
+// resize is the destructive analog for this one
+
+ComplexMatrix
+ComplexDiagMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  ComplexMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.elem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+ComplexRowVector
+ComplexDiagMatrix::row (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= r)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector (); 
+    }
+
+  ComplexRowVector retval (c, 0.0);
+  if (r <= c || (r > c && i < c))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+ComplexRowVector
+ComplexDiagMatrix::row (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return row (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return row (rows () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector ();
+    }
+}
+
+ComplexColumnVector
+ComplexDiagMatrix::column (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= c)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ComplexColumnVector (); 
+    }
+
+  ComplexColumnVector retval (r, 0.0);
+  if (r >= c || (r < c && i < r))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+ComplexColumnVector
+ComplexDiagMatrix::column (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ComplexColumnVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return column (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return column (cols () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ComplexColumnVector (); 
+    }
+}
+
+ComplexDiagMatrix
+ComplexDiagMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  return inverse (info);
+}
+
+ComplexDiagMatrix
+ComplexDiagMatrix::inverse (octave_idx_type& info) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (r != c)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return ComplexDiagMatrix ();
+    }
+
+  ComplexDiagMatrix retval (r, c);
+
+  info = 0;
+  for (octave_idx_type i = 0; i < length (); i++)
+    {
+      if (elem (i, i) == 0.0)
+	{
+	  info = -1;
+	  return *this;
+	}
+      else
+	retval.elem (i, i) = 1.0 / elem (i, i);
+    }
+
+  return retval;
+}
+
+ComplexDiagMatrix
+ComplexDiagMatrix::pseudo_inverse (void) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  octave_idx_type len = length ();
+
+  ComplexDiagMatrix retval (c, r);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      if (elem (i, i) != 0.0)
+        retval.elem (i, i) = 1.0 / elem (i, i);
+      else
+        retval.elem (i, i) = 0.0;
+    }
+
+  return retval;
+}
+
+bool
+ComplexDiagMatrix::all_elements_are_real (void) const
+{
+  octave_idx_type len = length ();
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      double ip = std::imag (elem (i, i));
+
+      if (ip != 0.0 || lo_ieee_signbit (ip))
+        return false;
+    }
+
+  return true;
+}
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::operator += (const DiagMatrix& a)
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r != a_nr || c != a_nc)
+    {
+      gripe_nonconformant ("operator +=", r, c, a_nr, a_nc);
+      return *this;
+    }
+
+  if (r == 0 || c == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexDiagMatrix
+operator * (const ComplexDiagMatrix& a, const DiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return ComplexDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return ComplexDiagMatrix (a_nr, a_nc, 0.0);
+
+  ComplexDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      Complex a_element = a.elem (i, i);
+      double b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+ComplexDiagMatrix
+operator * (const DiagMatrix& a, const ComplexDiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return ComplexDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return ComplexDiagMatrix (a_nr, a_nc, 0.0);
+
+  ComplexDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      double a_element = a.elem (i, i);
+      Complex b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+ComplexDiagMatrix
+operator * (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return ComplexDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return ComplexDiagMatrix (a_nr, a_nc, 0.0);
+
+  ComplexDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      Complex a_element = a.elem (i, i);
+      Complex b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+// other operations
+
+ComplexDET
+ComplexDiagMatrix::determinant (void) const
+{
+  ComplexDET det (1.0);
+  if (rows () != cols ())
+    {
+      (*current_liboctave_error_handler) ("determinant requires square matrix");
+      det = ComplexDET (0.0);
+    }
+  else
+    {
+      octave_idx_type len = length ();
+      for (octave_idx_type i = 0; i < len; i++)
+        det *= elem (i, i);
+    }
+
+  return det;
+}
+
+double
+ComplexDiagMatrix::rcond (void) const
+{
+  ColumnVector av = diag (0).map (std::abs);
+  double amx = av.max (), amn = av.min ();
+  return amx == 0 ? 0.0 : amn / amx;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const ComplexDiagMatrix& a)
+{
+  Complex ZERO (0.0);
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  if (i == j)
+	    os << " " /* setw (field_width) */ << a.elem (i, i);
+	  else
+	    os << " " /* setw (field_width) */ << ZERO;
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CDiagMatrix.h b/liboctave/CDiagMatrix.h
new file mode 100644
index 0000000..a1e32ba
--- /dev/null
+++ b/liboctave/CDiagMatrix.h
@@ -0,0 +1,164 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexDiagMatrix_h)
+#define octave_ComplexDiagMatrix_h 1
+
+#include "MDiagArray2.h"
+
+#include "dRowVector.h"
+#include "CRowVector.h"
+#include "dColVector.h"
+#include "CColVector.h"
+#include "DET.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+ComplexDiagMatrix : public MDiagArray2<Complex>
+{
+public:
+
+  ComplexDiagMatrix (void) : MDiagArray2<Complex> () { }
+
+  ComplexDiagMatrix (octave_idx_type r, octave_idx_type c) : MDiagArray2<Complex> (r, c) { }
+
+  ComplexDiagMatrix (octave_idx_type r, octave_idx_type c, const Complex& val)
+    : MDiagArray2<Complex> (r, c, val) { }
+
+  explicit ComplexDiagMatrix (const RowVector& a)
+    : MDiagArray2<Complex> (ComplexRowVector (a)) { }
+
+  explicit ComplexDiagMatrix (const ComplexRowVector& a)
+    : MDiagArray2<Complex> (a) { }
+
+  explicit ComplexDiagMatrix (const ColumnVector& a)
+    : MDiagArray2<Complex> (ComplexColumnVector (a)) { }
+
+  explicit ComplexDiagMatrix (const ComplexColumnVector& a)
+    : MDiagArray2<Complex> (a) { }
+
+  explicit ComplexDiagMatrix (const DiagMatrix& a);
+
+  ComplexDiagMatrix (const MDiagArray2<Complex>& a)
+    : MDiagArray2<Complex> (a) { }
+
+  ComplexDiagMatrix (const ComplexDiagMatrix& a)
+    : MDiagArray2<Complex> (a) { }
+
+  template <class U>
+  ComplexDiagMatrix (const DiagArray2<U>& a) 
+    : MDiagArray2<Complex> (a) { }
+
+  ComplexDiagMatrix& operator = (const ComplexDiagMatrix& a)
+    {
+      MDiagArray2<Complex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const ComplexDiagMatrix& a) const;
+  bool operator != (const ComplexDiagMatrix& a) const;
+
+  ComplexDiagMatrix& fill (double val);
+  ComplexDiagMatrix& fill (const Complex& val);
+  ComplexDiagMatrix& fill (double val, octave_idx_type beg, octave_idx_type end);
+  ComplexDiagMatrix& fill (const Complex& val, octave_idx_type beg, octave_idx_type end);
+  ComplexDiagMatrix& fill (const ColumnVector& a);
+  ComplexDiagMatrix& fill (const ComplexColumnVector& a);
+  ComplexDiagMatrix& fill (const RowVector& a);
+  ComplexDiagMatrix& fill (const ComplexRowVector& a);
+  ComplexDiagMatrix& fill (const ColumnVector& a, octave_idx_type beg);
+  ComplexDiagMatrix& fill (const ComplexColumnVector& a, octave_idx_type beg);
+  ComplexDiagMatrix& fill (const RowVector& a, octave_idx_type beg);
+  ComplexDiagMatrix& fill (const ComplexRowVector& a, octave_idx_type beg);
+
+  ComplexDiagMatrix hermitian (void) const { return MDiagArray2<Complex>::hermitian (std::conj); }
+  ComplexDiagMatrix transpose (void) const { return MDiagArray2<Complex>::transpose(); }
+  DiagMatrix abs (void) const; 
+
+  friend OCTAVE_API ComplexDiagMatrix conj (const ComplexDiagMatrix& a);
+
+  // resize is the destructive analog for this one
+
+  ComplexMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  // extract row or column i
+
+  ComplexRowVector row (octave_idx_type i) const;
+  ComplexRowVector row (char *s) const;
+
+  ComplexColumnVector column (octave_idx_type i) const;
+  ComplexColumnVector column (char *s) const;
+
+  ComplexDiagMatrix inverse (octave_idx_type& info) const;
+  ComplexDiagMatrix inverse (void) const;
+  ComplexDiagMatrix pseudo_inverse (void) const;
+
+  bool all_elements_are_real (void) const;
+
+  // diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+  ComplexDiagMatrix& operator += (const DiagMatrix& a);
+  ComplexDiagMatrix& operator -= (const DiagMatrix& a);
+
+  // other operations
+
+  ComplexColumnVector diag (octave_idx_type k = 0) const
+    { return MDiagArray2<Complex>::diag (k); }
+
+  ComplexDET determinant (void) const;
+  double rcond (void) const;
+
+  // i/o
+
+  friend std::ostream& operator << (std::ostream& os, const ComplexDiagMatrix& a);
+
+private:
+
+  ComplexDiagMatrix (Complex *d, octave_idx_type nr, octave_idx_type nc)
+    : MDiagArray2<Complex> (d, nr, nc) { }
+};
+
+OCTAVE_API ComplexDiagMatrix conj (const ComplexDiagMatrix& a);
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+OCTAVE_API ComplexDiagMatrix
+operator * (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b);
+
+OCTAVE_API ComplexDiagMatrix
+operator * (const ComplexDiagMatrix& a, const DiagMatrix& b);
+
+OCTAVE_API ComplexDiagMatrix
+operator * (const DiagMatrix& a, const ComplexDiagMatrix& b);
+
+MDIAGARRAY2_FORWARD_DEFS (MDiagArray2, ComplexDiagMatrix, Complex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CMatrix.cc b/liboctave/CMatrix.cc
new file mode 100644
index 0000000..0011575
--- /dev/null
+++ b/liboctave/CMatrix.cc
@@ -0,0 +1,4090 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <vector>
+
+// FIXME
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "Array-util.h"
+#include "CMatrix.h"
+#include "CmplxAEPBAL.h"
+#include "DET.h"
+#include "CmplxSCHUR.h"
+#include "CmplxSVD.h"
+#include "CmplxCHOL.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "mx-cm-dm.h"
+#include "mx-dm-cm.h"
+#include "mx-cm-s.h"
+#include "mx-inlines.cc"
+#include "mx-op-defs.h"
+#include "oct-cmplx.h"
+#include "oct-norm.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#endif
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (xilaenv, XILAENV) (const octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			       F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&,
+			       const octave_idx_type&, const octave_idx_type&,
+			       octave_idx_type&
+			       F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgebal, ZGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, Complex*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgebak, DGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgemm, ZGEMM) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			   const Complex&, const Complex*, const octave_idx_type&,
+			   const Complex*, const octave_idx_type&, const Complex&,
+			   Complex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgemv, ZGEMV) (F77_CONST_CHAR_ARG_DECL,
+                           const octave_idx_type&, const octave_idx_type&, const Complex&,
+                           const Complex*, const octave_idx_type&, const Complex*,
+                           const octave_idx_type&, const Complex&, Complex*, const octave_idx_type&
+                           F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xzdotu, XZDOTU) (const octave_idx_type&, const Complex*, const octave_idx_type&,
+			     const Complex*, const octave_idx_type&, Complex&);
+
+  F77_RET_T
+  F77_FUNC (xzdotc, XZDOTC) (const octave_idx_type&, const Complex*, const octave_idx_type&,
+			     const Complex*, const octave_idx_type&, Complex&);
+
+  F77_RET_T
+  F77_FUNC (zsyrk, ZSYRK) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, 
+			   const Complex&, const Complex*, const octave_idx_type&,
+			   const Complex&, Complex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zherk, ZHERK) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, 
+			   const Complex&, const Complex*, const octave_idx_type&,
+			   const Complex&, Complex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgetrf, ZGETRF) (const octave_idx_type&, const octave_idx_type&, Complex*, const octave_idx_type&,
+			     octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgetrs, ZGETRS) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, Complex*, const octave_idx_type&,
+			     const octave_idx_type*, Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgetri, ZGETRI) (const octave_idx_type&, Complex*, const octave_idx_type&, const octave_idx_type*,
+			     Complex*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgecon, ZGECON) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, Complex*, 
+			     const octave_idx_type&, const double&, double&, 
+			     Complex*, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgelsy, ZGELSY) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, octave_idx_type*, double&, octave_idx_type&,
+			     Complex*, const octave_idx_type&, double*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgelsd, ZGELSD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, double*, double&, octave_idx_type&,
+			     Complex*, const octave_idx_type&, double*, 
+			     octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zpotrf, ZPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     Complex*, const octave_idx_type&, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpocon, ZPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     Complex*, const octave_idx_type&, const double&,
+			     double&, Complex*, double*,
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpotrs, ZPOTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const Complex*, 
+			     const octave_idx_type&, Complex*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ztrtri, ZTRTRI) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const Complex*, 
+			     const octave_idx_type&, octave_idx_type& 
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ztrcon, ZTRCON) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const Complex*, const octave_idx_type&, double&,
+			     Complex*, double*, octave_idx_type& 
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ztrtrs, ZTRTRS) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const Complex*, 
+			     const octave_idx_type&, Complex*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  // Note that the original complex fft routines were not written for
+  // double complex arguments.  They have been modified by adding an
+  // implicit double precision (a-h,o-z) statement at the beginning of
+  // each subroutine.
+
+  F77_RET_T
+  F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zlartg, ZLARTG) (const Complex&, const Complex&,
+			     double&, Complex&, Complex&);
+
+  F77_RET_T
+  F77_FUNC (ztrsyl, ZTRSYL) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     const Complex*, const octave_idx_type&,
+			     const Complex*, const octave_idx_type&,
+			     const Complex*, const octave_idx_type&, double&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xzlange, XZLANGE) (F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&, const Complex*,
+			       const octave_idx_type&, double*, double&
+			       F77_CHAR_ARG_LEN_DECL);
+}
+
+static const Complex Complex_NaN_result (octave_NaN, octave_NaN);
+
+// Complex Matrix class
+
+ComplexMatrix::ComplexMatrix (const Matrix& a)
+  : MArray2<Complex> (a.rows (), a.cols ())
+{
+  for (octave_idx_type j = 0; j < cols (); j++)
+    for (octave_idx_type i = 0; i < rows (); i++)
+      elem (i, j) = a.elem (i, j);
+}
+
+ComplexMatrix::ComplexMatrix (const RowVector& rv)
+  : MArray2<Complex> (1, rv.length (), 0.0)
+{
+  for (octave_idx_type i = 0; i < rv.length (); i++)
+    elem (0, i) = rv.elem (i);
+}
+
+ComplexMatrix::ComplexMatrix (const ColumnVector& cv)
+  : MArray2<Complex> (cv.length (), 1, 0.0)
+{
+  for (octave_idx_type i = 0; i < cv.length (); i++)
+    elem (i, 0) = cv.elem (i);
+}
+
+ComplexMatrix::ComplexMatrix (const DiagMatrix& a)
+  : MArray2<Complex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+ComplexMatrix::ComplexMatrix (const ComplexRowVector& rv)
+  : MArray2<Complex> (Array2<Complex> (rv, 1, rv.length ()))
+{
+}
+
+ComplexMatrix::ComplexMatrix (const ComplexColumnVector& cv)
+  : MArray2<Complex> (Array2<Complex> (cv, cv.length (), 1))
+{
+}
+
+ComplexMatrix::ComplexMatrix (const ComplexDiagMatrix& a)
+  : MArray2<Complex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+// FIXME -- could we use a templated mixed-type copy function
+// here?
+
+ComplexMatrix::ComplexMatrix (const boolMatrix& a)
+  : MArray2<Complex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = a.elem (i, j);
+}
+
+ComplexMatrix::ComplexMatrix (const charMatrix& a)
+  : MArray2<Complex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = static_cast<unsigned char> (a.elem (i, j));
+}
+
+bool
+ComplexMatrix::operator == (const ComplexMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return false;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+ComplexMatrix::operator != (const ComplexMatrix& a) const
+{
+  return !(*this == a);
+}
+
+bool
+ComplexMatrix::is_hermitian (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (is_square () && nr > 0)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	for (octave_idx_type j = i; j < nc; j++)
+	  if (elem (i, j) != conj (elem (j, i)))
+	    return false;
+
+      return true;
+    }
+
+  return false;
+}
+
+// destructive insert/delete/reorder operations
+
+ComplexMatrix&
+ComplexMatrix::insert (const Matrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_nr >0 && a_nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < a_nc; j++)
+	for (octave_idx_type i = 0; i < a_nr; i++)
+	  xelem (r+i, c+j) = a.elem (i, j);
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const RowVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r, c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const ColumnVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const DiagMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
+
+  octave_idx_type a_len = a.length ();
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c+i) = a.elem (i, i);
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const ComplexMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Array2<Complex>::insert (a, r, c);
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const ComplexRowVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+  if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (r, c+i) = a.elem (i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const ComplexColumnVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::insert (const ComplexDiagMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
+
+  octave_idx_type a_len = a.length ();
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c+i) = a.elem (i, i);
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::fill (double val)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::fill (const Complex& val)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::fill (double val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
+      || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (r2 >= r1 && c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = c1; j <= c2; j++)
+	for (octave_idx_type i = r1; i <= r2; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::fill (const Complex& val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
+      || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (r2 >= r1 && c2 >=c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = c1; j <= c2; j++)
+	for (octave_idx_type i = r1; i <= r2; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const Matrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const RowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != 1)
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + a.length ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const ColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.length ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + 1);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const DiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const ComplexMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const ComplexRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != 1)
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + a.length ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const ComplexColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.length ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + 1);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::append (const ComplexDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  ComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const Matrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const RowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + 1, nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const ColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != 1)
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + a.length (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const DiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const ComplexMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const ComplexRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + 1, nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const ComplexColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != 1)
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + a.length (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::stack (const ComplexDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  ComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+ComplexMatrix
+conj (const ComplexMatrix& a)
+{
+  return ComplexMatrix (mx_inline_conj_dup (a.data (), a.length ()),
+                        a.rows (), a.cols ());
+}
+
+// resize is the destructive equivalent for this one
+
+ComplexMatrix
+ComplexMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  ComplexMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+ComplexMatrix
+ComplexMatrix::extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const
+{
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+ComplexRowVector
+ComplexMatrix::row (octave_idx_type i) const
+{
+  return MArray<Complex> (index (idx_vector (i), idx_vector::colon));
+}
+
+ComplexColumnVector
+ComplexMatrix::column (octave_idx_type i) const
+{
+  return MArray<Complex> (index (idx_vector::colon, idx_vector (i)));
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  double rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (octave_idx_type& info) const
+{
+  double rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (octave_idx_type& info, double& rcon, int force,
+			int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, force, calc_cond);
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (MatrixType &mattype) const
+{
+  octave_idx_type info;
+  double rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (MatrixType &mattype, octave_idx_type& info) const
+{
+  double rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::tinverse (MatrixType &mattype, octave_idx_type& info,
+			 double& rcon, int force, int calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr == 0 || nc == 0)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      int typ = mattype.type ();
+      char uplo = (typ == MatrixType::Lower ? 'L' : 'U');
+      char udiag = 'N';
+      retval = *this;
+      Complex *tmp_data = retval.fortran_vec ();
+
+      F77_XFCN (ztrtri, ZTRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+				 F77_CONST_CHAR_ARG2 (&udiag, 1),
+				 nr, tmp_data, nr, info 
+				 F77_CHAR_ARG_LEN (1)
+				 F77_CHAR_ARG_LEN (1)));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  octave_idx_type ztrcon_info = 0;
+	  char job = '1';
+
+	  OCTAVE_LOCAL_BUFFER (Complex, cwork, 2*nr);
+	  OCTAVE_LOCAL_BUFFER (double, rwork, nr);
+
+	  F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     F77_CONST_CHAR_ARG2 (&uplo, 1),
+				     F77_CONST_CHAR_ARG2 (&udiag, 1),
+				     nr, tmp_data, nr, rcon, 
+				     cwork, rwork, ztrcon_info 
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (ztrcon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this; // Restore matrix contents.
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::finverse (MatrixType &mattype, octave_idx_type& info,
+			 double& rcon, int force, int calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      Array<octave_idx_type> ipvt (nr);
+      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+      retval = *this;
+      Complex *tmp_data = retval.fortran_vec ();
+
+      Array<Complex> z(1);
+      octave_idx_type lwork = -1;
+
+      // Query the optimum work array size.
+
+      F77_XFCN (zgetri, ZGETRI, (nc, tmp_data, nr, pipvt, 
+				 z.fortran_vec (), lwork, info));
+
+      lwork = static_cast<octave_idx_type> (std::real(z(0)));
+      lwork = (lwork <  2 *nc ? 2*nc : lwork);
+      z.resize (lwork);
+      Complex *pz = z.fortran_vec ();
+
+      info = 0;
+
+      // Calculate the norm of the matrix, for later use.
+      double anorm;
+      if (calc_cond)
+	anorm  = retval.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+      F77_XFCN (zgetrf, ZGETRF, (nc, nc, tmp_data, nr, pipvt, info));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  // Now calculate the condition number for non-singular matrix.
+	  octave_idx_type zgecon_info = 0;
+	  char job = '1';
+	  Array<double> rz (2 * nc);
+	  double *prz = rz.fortran_vec ();
+	  F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nc, tmp_data, nr, anorm, 
+				     rcon, pz, prz, zgecon_info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (zgecon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this;  // Restore contents.
+      else
+	{
+	  octave_idx_type zgetri_info = 0;
+
+	  F77_XFCN (zgetri, ZGETRI, (nc, tmp_data, nr, pipvt,
+				     pz, lwork, zgetri_info));
+
+	  if (zgetri_info != 0) 
+	    info = -1;
+	}
+
+      if (info != 0)
+	mattype.mark_as_rectangular();
+    }
+  
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (MatrixType &mattype, octave_idx_type& info,
+			double& rcon, int force, int calc_cond) const
+{
+  int typ = mattype.type (false);
+  ComplexMatrix ret;
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Upper || typ == MatrixType::Lower)
+    ret = tinverse (mattype, info, rcon, force, calc_cond);
+  else
+    {
+      if (mattype.is_hermitian ())
+	{
+	  ComplexCHOL chol (*this, info, calc_cond);
+	  if (info == 0)
+	    {
+	      if (calc_cond)
+		rcon = chol.rcond();
+	      else
+		rcon = 1.0;
+	      ret = chol.inverse ();
+	    }
+	  else
+	    mattype.mark_as_unsymmetric ();
+	}
+
+      if (!mattype.is_hermitian ())
+	ret = finverse(mattype, info, rcon, force, calc_cond);
+
+      if ((mattype.is_hermitian () || calc_cond) && rcon == 0.)
+	ret = ComplexMatrix (rows (), columns (), Complex (octave_Inf, 0.));
+    }
+
+  return ret;
+}
+
+ComplexMatrix
+ComplexMatrix::pseudo_inverse (double tol) const
+{
+  ComplexMatrix retval;
+
+  ComplexSVD result (*this, SVD::economy);
+
+  DiagMatrix S = result.singular_values ();
+  ComplexMatrix U = result.left_singular_matrix ();
+  ComplexMatrix V = result.right_singular_matrix ();
+
+  ColumnVector sigma = S.diag ();
+
+  octave_idx_type r = sigma.length () - 1;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (tol <= 0.0)
+    {
+      if (nr > nc)
+	tol = nr * sigma.elem (0) * DBL_EPSILON;
+      else
+	tol = nc * sigma.elem (0) * DBL_EPSILON;
+    }
+
+  while (r >= 0 && sigma.elem (r) < tol)
+    r--;
+
+  if (r < 0)
+    retval = ComplexMatrix (nc, nr, 0.0);
+  else
+    {
+      ComplexMatrix Ur = U.extract (0, 0, nr-1, r);
+      DiagMatrix D = DiagMatrix (sigma.extract (0, r)) . inverse ();
+      ComplexMatrix Vr = V.extract (0, 0, nc-1, r);
+      retval = Vr * D * Ur.hermitian ();
+    }
+
+  return retval;
+}
+
+#if defined (HAVE_FFTW3)
+
+ComplexMatrix
+ComplexMatrix::fourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  const Complex *in (data ());
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::fft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::ifourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  const Complex *in (data ());
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::ifft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::fourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  ComplexMatrix retval (rows (), cols ());
+  const Complex *in (data ());
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::fftNd (in, out, 2, dv);
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::ifourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  ComplexMatrix retval (rows (), cols ());
+  const Complex *in (data ());
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (in, out, 2, dv);
+
+  return retval;
+}
+
+#else
+
+ComplexMatrix
+ComplexMatrix::fourier (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftf, ZFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::ifourier (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftb, ZFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<double> (npts);
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::fourier2d (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftf, ZFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<Complex> tmp (npts);
+  Complex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i];
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::ifourier2d (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftb, ZFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<double> (npts);
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<Complex> tmp (npts);
+  Complex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i] / static_cast<double> (npts);
+    }
+
+  return retval;
+}
+
+#endif
+
+ComplexDET
+ComplexMatrix::determinant (void) const
+{
+  octave_idx_type info;
+  double rcon;
+  return determinant (info, rcon, 0);
+}
+
+ComplexDET
+ComplexMatrix::determinant (octave_idx_type& info) const
+{
+  double rcon;
+  return determinant (info, rcon, 0);
+}
+
+ComplexDET
+ComplexMatrix::determinant (octave_idx_type& info, double& rcon, int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return determinant (mattype, info, rcon, calc_cond);
+}
+
+ComplexDET
+ComplexMatrix::determinant (MatrixType& mattype,
+                            octave_idx_type& info, double& rcon,
+			    int calc_cond) const
+{
+  ComplexDET retval (1.0);
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+        typ = mattype.type (*this);
+
+      if (typ == MatrixType::Lower || typ == MatrixType::Upper)
+        {
+          for (octave_idx_type i = 0; i < nc; i++) 
+            retval *= elem (i,i);
+        }
+      else if (typ == MatrixType::Hermitian)
+        {
+          ComplexMatrix atmp = *this;
+          Complex *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+          double anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+
+          char job = 'L';
+          F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+                                     tmp_data, nr, info
+                                     F77_CHAR_ARG_LEN (1)));
+
+          if (info != 0) 
+            {
+              rcon = 0.0;
+              mattype.mark_as_unsymmetric ();
+              typ = MatrixType::Full;
+            }
+          else 
+            {
+              Array<Complex> z (2 * nc);
+              Complex *pz = z.fortran_vec ();
+              Array<double> rz (nc);
+              double *prz = rz.fortran_vec ();
+
+              F77_XFCN (zpocon, ZPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                         nr, tmp_data, nr, anorm,
+                                         rcon, pz, prz, info
+                                         F77_CHAR_ARG_LEN (1)));
+
+              if (info != 0) 
+                rcon = 0.0;
+
+              for (octave_idx_type i = 0; i < nc; i++) 
+                retval *= atmp (i,i);
+
+              retval = retval.square ();
+            }
+        }
+      else if (typ != MatrixType::Full)
+        (*current_liboctave_error_handler) ("det: invalid dense matrix type");
+
+      if (typ == MatrixType::Full)
+        {
+          Array<octave_idx_type> ipvt (nr);
+          octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+          ComplexMatrix atmp = *this;
+          Complex *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+
+          // Calculate the norm of the matrix, for later use.
+          double anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+          F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+          // Throw-away extra info LAPACK gives so as to not change output.
+          rcon = 0.0;
+          if (info != 0) 
+            {
+              info = -1;
+              retval = ComplexDET ();
+            } 
+          else 
+            {
+              if (calc_cond) 
+                {
+                  // Now calc the condition number for non-singular matrix.
+                  char job = '1';
+                  Array<Complex> z (2 * nc);
+                  Complex *pz = z.fortran_vec ();
+                  Array<double> rz (2 * nc);
+                  double *prz = rz.fortran_vec ();
+
+                  F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                             nc, tmp_data, nr, anorm, 
+                                             rcon, pz, prz, info
+                                             F77_CHAR_ARG_LEN (1)));
+                }
+
+              if (info != 0) 
+                {
+                  info = -1;
+                  retval = ComplexDET ();
+                } 
+              else 
+                {
+                  for (octave_idx_type i = 0; i < nc; i++) 
+                    {
+                      Complex c = atmp(i,i);
+                      retval *= (ipvt(i) != (i+1)) ? -c : c;
+                    }
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+double
+ComplexMatrix::rcond (void) const
+{
+  MatrixType mattype (*this);
+  return rcond (mattype);
+}
+
+double
+ComplexMatrix::rcond (MatrixType &mattype) const
+{
+  double rcon;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else if (nr == 0 || nc == 0)
+    rcon = octave_Inf;
+  else
+    {
+      int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+	typ = mattype.type (*this);
+
+      // Only calculate the condition number for LU/Cholesky
+      if (typ == MatrixType::Upper)
+	{
+	  const Complex *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'U';
+	  char dia = 'N';
+
+	  Array<Complex> z (2 * nc);
+	  Complex *pz = z.fortran_vec ();
+	  Array<double> rz (nc);
+	  double *prz = rz.fortran_vec ();
+
+	  F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, prz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0;
+	}
+      else if  (typ == MatrixType::Permuted_Upper)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Lower)
+	{
+	  const Complex *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'L';
+	  char dia = 'N';
+
+	  Array<Complex> z (2 * nc);
+	  Complex *pz = z.fortran_vec ();
+	  Array<double> rz (nc);
+	  double *prz = rz.fortran_vec ();
+
+	  F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, prz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0.0;
+	}
+      else if (typ == MatrixType::Permuted_Lower)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+	{
+	  double anorm = -1.0;
+	  ComplexMatrix atmp = *this;
+	  Complex *tmp_data = atmp.fortran_vec ();
+
+	  if (typ == MatrixType::Hermitian)
+	    {
+	      octave_idx_type info = 0;
+	      char job = 'L';
+	      anorm = atmp.abs().sum().
+		row(static_cast<octave_idx_type>(0)).max();
+
+	      F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+					 tmp_data, nr, info
+					 F77_CHAR_ARG_LEN (1)));
+
+	      if (info != 0) 
+		{
+		  rcon = 0.0;
+
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}
+	      else 
+		{
+		  Array<Complex> z (2 * nc);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> rz (nc);
+		  double *prz = rz.fortran_vec ();
+
+		  F77_XFCN (zpocon, ZPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+
+
+	  if (typ == MatrixType::Full)
+	    {
+	      octave_idx_type info = 0;
+
+	      Array<octave_idx_type> ipvt (nr);
+	      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	      if(anorm < 0.)
+		anorm = atmp.abs().sum().
+		  row(static_cast<octave_idx_type>(0)).max();
+
+	      Array<Complex> z (2 * nc);
+	      Complex *pz = z.fortran_vec ();
+	      Array<double> rz (2 * nc);
+	      double *prz = rz.fortran_vec ();
+
+	      F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	      if (info != 0) 
+		{ 
+		  rcon = 0.0;
+		  mattype.mark_as_rectangular ();
+		} 
+	      else 
+		{
+		  char job = '1';
+		  F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+	}
+      else
+	rcon = 0.0;
+    }
+
+  return rcon;
+}
+
+ComplexMatrix
+ComplexMatrix::utsolve (MatrixType &mattype, const ComplexMatrix& b, 
+			octave_idx_type& info, double& rcon, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const Complex *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'U';
+		  char dia = 'N';
+
+		  Array<Complex> z (2 * nc);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> rz (nc);
+		  double *prz = rz.fortran_vec ();
+
+		  F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, prz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  Complex *result = retval.fortran_vec ();
+
+		  char uplo = 'U';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::ltsolve (MatrixType &mattype, const ComplexMatrix& b, 
+			octave_idx_type& info, double& rcon, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const Complex *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'L';
+		  char dia = 'N';
+
+		  Array<Complex> z (2 * nc);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> rz (nc);
+		  double *prz = rz.fortran_vec ();
+
+		  F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, prz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  Complex *result = retval.fortran_vec ();
+
+		  char uplo = 'L';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::fsolve (MatrixType &mattype, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcon,
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      volatile int typ = mattype.type ();
+ 
+     // Calculate the norm of the matrix, for later use.
+      double anorm = -1.;
+
+      if (typ == MatrixType::Hermitian)
+	{
+	  info = 0;
+	  char job = 'L';
+	  ComplexMatrix atmp = *this;
+	  Complex *tmp_data = atmp.fortran_vec ();
+	  anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+				     tmp_data, nr, info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    {
+	      info = -2;
+
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<Complex> z (2 * nc);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> rz (nc);
+		  double *prz = rz.fortran_vec ();
+
+		  F77_XFCN (zpocon, ZPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  Complex *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  F77_XFCN (zpotrs, ZPOTRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	      else
+		{
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Full)
+	{
+	  info = 0;
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  ComplexMatrix atmp = *this;
+	  Complex *tmp_data = atmp.fortran_vec ();
+
+	  Array<Complex> z (2 * nc);
+	  Complex *pz = z.fortran_vec ();
+	  Array<double> rz (2 * nc);
+	  double *prz = rz.fortran_vec ();
+
+	  // Calculate the norm of the matrix, for later use.
+	  if (anorm < 0.)
+	    anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    { 
+	      info = -2;
+
+	      if (sing_handler)
+		sing_handler (rcon);
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	      mattype.mark_as_rectangular ();
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  // Now calculate the condition number for 
+		  // non-singular matrix.
+		  char job = '1';
+		  F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  Complex *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  char job = 'N';
+		  F77_XFCN (zgetrs, ZGETRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     pipvt, result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1))); 
+		}
+	      else
+		mattype.mark_as_rectangular ();		    
+	    }
+	}
+    }
+  
+  return retval;
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const Matrix& b, 
+		      octave_idx_type& info) const
+{
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		      double& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		      double& rcon, solve_singularity_handler sing_handler,
+		      bool singular_fallback) const
+{
+  ComplexMatrix tmp (b);
+  return solve (typ, tmp, info, rcon, sing_handler, singular_fallback);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const ComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const ComplexMatrix& b, 
+		      octave_idx_type& info) const
+{
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &typ, const ComplexMatrix& b, 
+		      octave_idx_type& info, double& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+		      octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler,
+		      bool singular_fallback) const
+{
+  ComplexMatrix retval;
+  int typ = mattype.type ();
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  // Only calculate the condition number for LU/Cholesky
+  if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, info, rcon, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return ComplexMatrix ();
+    }
+
+  // Rectangular or one of the above solvers flags a singular matrix
+  if (singular_fallback && mattype.type () == MatrixType::Rectangular)
+    {
+      octave_idx_type rank;
+      retval = lssolve (b, info, rank, rcon);
+    }
+
+  return retval;
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (typ, ComplexColumnVector (b), info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info) const
+{
+  double rcon;
+  return solve (typ, ComplexColumnVector (b), info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info, double& rcon) const
+{
+  return solve (typ, ComplexColumnVector (b), info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  return solve (typ, ComplexColumnVector (b), info, rcon, sing_handler);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, 
+		      octave_idx_type& info) const
+{
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b,
+		      octave_idx_type& info, double& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b,
+		      octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+
+  ComplexMatrix tmp (b);
+  return solve (typ, tmp, info, rcon, sing_handler).column(static_cast<octave_idx_type> (0));
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const Matrix& b, octave_idx_type& info) const
+{
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (b);
+  return solve (tmp, info, rcon, sing_handler);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const ComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info) const
+{
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+ComplexMatrix
+ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (ComplexColumnVector (b), info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info) const
+{
+  double rcon;
+  return solve (ComplexColumnVector (b), info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, 
+		      double& rcon) const
+{
+  return solve (ComplexColumnVector (b), info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, 
+		      double& rcon, 
+		      solve_singularity_handler sing_handler) const
+{
+  return solve (ComplexColumnVector (b), info, rcon, sing_handler);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info,
+		      double& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+ComplexColumnVector
+ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info,
+		      double& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const Matrix& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (ComplexMatrix (b), info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const Matrix& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (ComplexMatrix (b), info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const Matrix& b, octave_idx_type& info,
+			octave_idx_type& rank) const
+{
+  double rcon;
+  return lssolve (ComplexMatrix (b), info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const Matrix& b, octave_idx_type& info,
+			octave_idx_type& rank, double& rcon) const
+{
+  return lssolve (ComplexMatrix (b), info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const ComplexMatrix& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info,
+			octave_idx_type& rank) const
+{
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ComplexMatrix
+ComplexMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, 
+			octave_idx_type& rank, double& rcon) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nrhs = b.cols ();
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m== 0 || n == 0 || b.cols () == 0)
+    retval = ComplexMatrix (n, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+
+      if (m != n)
+	{
+	  retval = ComplexMatrix (maxmn, nrhs);
+
+	  for (octave_idx_type j = 0; j < nrhs; j++)
+	    for (octave_idx_type i = 0; i < m; i++)
+	      retval.elem (i, j) = b.elem (i, j);
+	}
+      else
+	retval = b;
+
+      ComplexMatrix atmp = *this;
+      Complex *tmp_data = atmp.fortran_vec ();
+
+      Complex *pretval = retval.fortran_vec ();
+      Array<double> s (minmn);
+      double *ps = s.fortran_vec ();
+
+      // Ask ZGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<Complex> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("ZGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      octave_idx_type mnthr;
+      F77_FUNC (xilaenv, XILAENV) (6, F77_CONST_CHAR_ARG2 ("ZGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   m, n, nrhs, -1, mnthr
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of rwork and iwork because ZGELSD in
+      // older versions of LAPACK does not return them on a query
+      // call.
+      double dminmn = static_cast<double> (minmn);
+      double dsmlsizp1 = static_cast<double> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      double tmp = log2 (dminmn / dsmlsizp1);
+#else
+      double tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type lrwork = minmn*(10 + 2*smlsiz + 8*nlvl)
+	+ 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
+      if (lrwork < 1)
+	lrwork = 1;
+      Array<double> rwork (lrwork);
+      double *prwork = rwork.fortran_vec ();
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, prwork, piwork, info));
+
+      // The workspace query is broken in at least LAPACK 3.0.0
+      // through 3.1.1 when n >= mnthr.  The obtuse formula below
+      // should provide sufficient workspace for ZGELSD to operate
+      // efficiently.
+      if (n >= mnthr)
+	{
+	  octave_idx_type addend = m;
+
+	  if (2*m-4 > addend)
+	    addend = 2*m-4;
+
+	  if (nrhs > addend)
+	    addend = nrhs;
+
+	  if (n-3*m > addend)
+	    addend = n-3*m;
+
+	  const octave_idx_type lworkaround = 4*m + m*m + addend;
+
+	  if (std::real (work(0)) < lworkaround)
+	    work(0) = lworkaround;
+	}
+      else if (m >= n)
+	{
+	  octave_idx_type lworkaround = 2*m + m*nrhs;
+
+	  if (std::real (work(0)) < lworkaround)
+	    work(0) = lworkaround;
+	}
+
+      lwork = static_cast<octave_idx_type> (std::real (work(0)));
+      work.resize (lwork);
+
+      F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 prwork, piwork, info));
+
+      if (rank < minmn)
+	(*current_liboctave_warning_handler) 
+	  ("zgelsd: rank deficient %dx%d matrix, rank = %d, tol = %e",
+	   m, n, rank, rcon);
+
+      if (s.elem (0) == 0.0)
+	rcon = 0.0;
+      else
+	rcon = s.elem (minmn - 1) / s.elem (0);
+
+      retval.resize (n, nrhs);
+    }
+
+  return retval;
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ColumnVector& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (ComplexColumnVector (b), info, rank, rcon);
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ColumnVector& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (ComplexColumnVector (b), info, rank, rcon);
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ColumnVector& b, octave_idx_type& info, 
+			octave_idx_type& rank) const
+{
+  double rcon;
+  return lssolve (ComplexColumnVector (b), info, rank, rcon);
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ColumnVector& b, octave_idx_type& info, 
+			octave_idx_type& rank, double& rcon) const
+{
+  return lssolve (ComplexColumnVector (b), info, rank, rcon);
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank) const
+{
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+
+}
+
+ComplexColumnVector
+ComplexMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank, double& rcon) const
+{
+  ComplexColumnVector retval;
+
+  octave_idx_type nrhs = 1;
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.length ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m == 0 || n == 0 || b.cols () == 0)
+    retval = ComplexColumnVector (n, Complex (0.0, 0.0));
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+
+      if (m != n)
+	{
+	  retval = ComplexColumnVector (maxmn);
+
+	  for (octave_idx_type i = 0; i < m; i++)
+	    retval.elem (i) = b.elem (i);
+	}
+      else
+	retval = b;
+
+      ComplexMatrix atmp = *this;
+      Complex *tmp_data = atmp.fortran_vec ();
+
+      Complex *pretval = retval.fortran_vec ();
+      Array<double> s (minmn);
+      double *ps = s.fortran_vec ();
+
+      // Ask ZGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<Complex> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("ZGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of rwork and iwork because ZGELSD in
+      // older versions of LAPACK does not return them on a query
+      // call.
+      double dminmn = static_cast<double> (minmn);
+      double dsmlsizp1 = static_cast<double> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      double tmp = log2 (dminmn / dsmlsizp1);
+#else
+      double tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type lrwork = minmn*(10 + 2*smlsiz + 8*nlvl)
+	+ 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
+      if (lrwork < 1)
+	lrwork = 1;
+      Array<double> rwork (lrwork);
+      double *prwork = rwork.fortran_vec ();
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, prwork, piwork, info));
+
+      lwork = static_cast<octave_idx_type> (std::real (work(0)));
+      work.resize (lwork);
+      rwork.resize (static_cast<octave_idx_type> (rwork(0)));
+      iwork.resize (iwork(0));
+
+      F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 prwork, piwork, info));
+
+      if (rank < minmn)
+	{
+	  if (rank < minmn)
+	    (*current_liboctave_warning_handler) 
+	      ("zgelsd: rank deficient %dx%d matrix, rank = %d, tol = %e",
+	       m, n, rank, rcon);
+
+	  if (s.elem (0) == 0.0)
+	    rcon = 0.0;
+	  else
+	    rcon = s.elem (minmn - 1) / s.elem (0);
+
+	  retval.resize (n, nrhs);
+	}
+    }
+
+  return retval;
+}
+
+// column vector by row vector -> matrix operations
+
+ComplexMatrix
+operator * (const ColumnVector& v, const ComplexRowVector& a)
+{
+  ComplexColumnVector tmp (v);
+  return tmp * a;
+}
+
+ComplexMatrix
+operator * (const ComplexColumnVector& a, const RowVector& b)
+{
+  ComplexRowVector tmp (b);
+  return a * tmp;
+}
+
+ComplexMatrix
+operator * (const ComplexColumnVector& v, const ComplexRowVector& a)
+{
+  ComplexMatrix retval;
+
+  octave_idx_type len = v.length ();
+
+  if (len != 0)
+    {
+      octave_idx_type a_len = a.length ();
+
+      retval = ComplexMatrix (len, a_len);
+      Complex *c = retval.fortran_vec ();
+
+      F77_XFCN (zgemm, ZGEMM, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 ("N", 1),
+			       len, a_len, 1, 1.0, v.data (), len,
+			       a.data (), 1, 0.0, c, len
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+    }
+
+  return retval;
+}
+
+// matrix by diagonal matrix -> matrix operations
+
+ComplexMatrix&
+ComplexMatrix::operator += (const DiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator -= (const DiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator += (const ComplexDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator -= (const ComplexDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+// matrix by matrix -> matrix operations
+
+ComplexMatrix&
+ComplexMatrix::operator += (const Matrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  if (nr == 0 || nc == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator -= (const Matrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  if (nr == 0 || nc == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_subtract2 (d, a.data (), length ());
+  return *this;
+}
+
+// unary operations
+
+boolMatrix
+ComplexMatrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  boolMatrix b (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      b.elem (i, j) = elem (i, j) == 0.0;
+
+  return b;
+}
+
+// other operations
+
+Matrix
+ComplexMatrix::map (dmapper fcn) const
+{
+  return MArray2<Complex>::map<double> (func_ptr (fcn));
+}
+
+ComplexMatrix
+ComplexMatrix::map (cmapper fcn) const
+{
+  return MArray2<Complex>::map<Complex> (func_ptr (fcn));
+}
+
+boolMatrix
+ComplexMatrix::map (bmapper fcn) const
+{
+  return MArray2<Complex>::map<bool> (func_ptr (fcn));
+}
+
+bool
+ComplexMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	Complex val = elem (i, j);
+	if (xisnan (val))
+	  return true;
+      }
+
+  return false;
+}
+
+bool
+ComplexMatrix::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	Complex val = elem (i, j);
+	if (xisinf (val) || xisnan (val))
+	  return true;
+      }
+
+  return false;
+}
+
+// Return true if no elements have imaginary components.
+
+bool
+ComplexMatrix::all_elements_are_real (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  double ip = std::imag (elem (i, j));
+
+	  if (ip != 0.0 || lo_ieee_signbit (ip))
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of CM has a non-integer real or
+// imaginary part.  Also extract the largest and smallest (real or
+// imaginary) values and return them in MAX_VAL and MIN_VAL. 
+
+bool
+ComplexMatrix::all_integers (double& max_val, double& min_val) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      Complex val = elem (0, 0);
+
+      double r_val = std::real (val);
+      double i_val = std::imag (val);
+
+      max_val = r_val;
+      min_val = r_val;
+
+      if (i_val > max_val)
+	max_val = i_val;
+
+      if (i_val < max_val)
+	min_val = i_val;
+    }
+  else
+    return false;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	Complex val = elem (i, j);
+
+	double r_val = std::real (val);
+	double i_val = std::imag (val);
+
+	if (r_val > max_val)
+	  max_val = r_val;
+
+	if (i_val > max_val)
+	  max_val = i_val;
+
+	if (r_val < min_val)
+	  min_val = r_val;
+
+	if (i_val < min_val)
+	  min_val = i_val;
+
+	if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
+	  return false;
+      }
+
+  return true;
+}
+
+bool
+ComplexMatrix::too_large_for_float (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	Complex val = elem (i, j);
+
+	double r_val = std::real (val);
+	double i_val = std::imag (val);
+
+	if ((! (xisnan (r_val) || xisinf (r_val))
+	     && fabs (r_val) > FLT_MAX)
+	    || (! (xisnan (i_val) || xisinf (i_val))
+		&& fabs (i_val) > FLT_MAX))
+	  return true;
+      }
+
+  return false;
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+boolMatrix
+ComplexMatrix::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, Complex> (*this, dim, mx_inline_all);
+}
+
+boolMatrix
+ComplexMatrix::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, Complex> (*this, dim, mx_inline_any);
+}
+
+ComplexMatrix
+ComplexMatrix::cumprod (int dim) const
+{
+  return do_mx_cum_op<ComplexMatrix, Complex> (*this, dim, mx_inline_cumprod);
+}
+
+ComplexMatrix
+ComplexMatrix::cumsum (int dim) const
+{
+  return do_mx_cum_op<ComplexMatrix, Complex> (*this, dim, mx_inline_cumsum);
+}
+
+ComplexMatrix
+ComplexMatrix::prod (int dim) const
+{
+  return do_mx_red_op<ComplexMatrix, Complex> (*this, dim, mx_inline_prod);
+}
+
+ComplexMatrix
+ComplexMatrix::sum (int dim) const
+{
+  return do_mx_red_op<ComplexMatrix, Complex> (*this, dim, mx_inline_sum);
+}
+
+ComplexMatrix
+ComplexMatrix::sumsq (int dim) const
+{
+  return do_mx_red_op<Matrix, Complex> (*this, dim, mx_inline_sumsq);
+}
+
+Matrix ComplexMatrix::abs (void) const
+{
+  return Matrix (mx_inline_cabs_dup (data (), length ()),
+                 rows (), cols ());
+}
+
+ComplexMatrix
+ComplexMatrix::diag (octave_idx_type k) const
+{
+  return MArray2<Complex>::diag (k);
+}
+
+bool
+ComplexMatrix::row_is_real_only (octave_idx_type i) const
+{
+  bool retval = true;
+
+  octave_idx_type nc = columns ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      if (std::imag (elem (i, j)) != 0.0)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;	      
+}
+
+bool
+ComplexMatrix::column_is_real_only (octave_idx_type j) const
+{
+  bool retval = true;
+
+  octave_idx_type nr = rows ();
+
+  for (octave_idx_type i = 0; i < nr; i++)
+    {
+      if (std::imag (elem (i, j)) != 0.0)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;	      
+}
+
+ComplexColumnVector
+ComplexMatrix::row_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_min (dummy_idx);
+}
+
+ComplexColumnVector
+ComplexMatrix::row_min (Array<octave_idx_type>& idx_arg) const
+{
+  ComplexColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  bool real_only = row_is_real_only (i);
+
+	  octave_idx_type idx_j;
+
+	  Complex tmp_min;
+
+	  double abs_min = octave_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_min = elem (i, idx_j);
+
+	      if (! xisnan (tmp_min))
+		{
+		  abs_min = real_only ? std::real (tmp_min) : std::abs (tmp_min);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      Complex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp < abs_min)
+		{
+		  idx_j = j;
+		  tmp_min = tmp;
+		  abs_min = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_min))
+	    {
+	      result.elem (i) = Complex_NaN_result;
+	      idx_arg.elem (i) = 0;
+	    }
+	  else
+	    {
+	      result.elem (i) = tmp_min;
+	      idx_arg.elem (i) = idx_j;
+	    }
+        }
+    }
+
+  return result;
+}
+
+ComplexColumnVector
+ComplexMatrix::row_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_max (dummy_idx);
+}
+
+ComplexColumnVector
+ComplexMatrix::row_max (Array<octave_idx_type>& idx_arg) const
+{
+  ComplexColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  bool real_only = row_is_real_only (i);
+
+	  octave_idx_type idx_j;
+
+	  Complex tmp_max;
+
+	  double abs_max = octave_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_max = elem (i, idx_j);
+
+	      if (! xisnan (tmp_max))
+		{
+		  abs_max = real_only ? std::real (tmp_max) : std::abs (tmp_max);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      Complex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp > abs_max)
+		{
+		  idx_j = j;
+		  tmp_max = tmp;
+		  abs_max = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_max))
+	    {
+	      result.elem (i) = Complex_NaN_result;
+	      idx_arg.elem (i) = 0;
+	    }
+	  else
+	    {
+	      result.elem (i) = tmp_max;
+	      idx_arg.elem (i) = idx_j;
+	    }
+        }
+    }
+
+  return result;
+}
+
+ComplexRowVector
+ComplexMatrix::column_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_min (dummy_idx);
+}
+
+ComplexRowVector
+ComplexMatrix::column_min (Array<octave_idx_type>& idx_arg) const
+{
+  ComplexRowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  bool real_only = column_is_real_only (j);
+
+	  octave_idx_type idx_i;
+
+	  Complex tmp_min;
+
+	  double abs_min = octave_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_min = elem (idx_i, j);
+
+	      if (! xisnan (tmp_min))
+		{
+		  abs_min = real_only ? std::real (tmp_min) : std::abs (tmp_min);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      Complex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp < abs_min)
+		{
+		  idx_i = i;
+		  tmp_min = tmp;
+		  abs_min = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_min))
+	    {
+	      result.elem (j) = Complex_NaN_result;
+	      idx_arg.elem (j) = 0;
+	    }
+	  else
+	    {
+	      result.elem (j) = tmp_min;
+	      idx_arg.elem (j) = idx_i;
+	    }
+        }
+    }
+
+  return result;
+}
+
+ComplexRowVector
+ComplexMatrix::column_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_max (dummy_idx);
+}
+
+ComplexRowVector
+ComplexMatrix::column_max (Array<octave_idx_type>& idx_arg) const
+{
+  ComplexRowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  bool real_only = column_is_real_only (j);
+
+	  octave_idx_type idx_i;
+
+	  Complex tmp_max;
+
+	  double abs_max = octave_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_max = elem (idx_i, j);
+
+	      if (! xisnan (tmp_max))
+		{
+		  abs_max = real_only ? std::real (tmp_max) : std::abs (tmp_max);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      Complex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp > abs_max)
+		{
+		  idx_i = i;
+		  tmp_max = tmp;
+		  abs_max = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_max))
+	    {
+	      result.elem (j) = Complex_NaN_result;
+	      idx_arg.elem (j) = 0;
+	    }
+	  else
+	    {
+	      result.elem (j) = tmp_max;
+	      idx_arg.elem (j) = idx_i;
+	    }
+        }
+    }
+
+  return result;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const ComplexMatrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  os << " ";
+	  octave_write_complex (os, a.elem (i, j));
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, ComplexMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      Complex tmp;
+      for (octave_idx_type i = 0; i < nr; i++)
+	for (octave_idx_type j = 0; j < nc; j++)
+	  {
+	    tmp = octave_read_complex (is);
+	    if (is)
+	      a.elem (i, j) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+done:
+
+  return is;
+}
+
+ComplexMatrix
+Givens (const Complex& x, const Complex& y)
+{
+  double cc;
+  Complex cs, temp_r;
+ 
+  F77_FUNC (zlartg, ZLARTG) (x, y, cc, cs, temp_r);
+
+  ComplexMatrix g (2, 2);
+
+  g.elem (0, 0) = cc;
+  g.elem (1, 1) = cc;
+  g.elem (0, 1) = cs;
+  g.elem (1, 0) = -conj (cs);
+
+  return g;
+}
+
+ComplexMatrix
+Sylvester (const ComplexMatrix& a, const ComplexMatrix& b,
+	   const ComplexMatrix& c)
+{
+  ComplexMatrix retval;
+
+  // FIXME -- need to check that a, b, and c are all the same
+  // size.
+
+  // Compute Schur decompositions
+
+  ComplexSCHUR as (a, "U");
+  ComplexSCHUR bs (b, "U");
+  
+  // Transform c to new coordinates.
+
+  ComplexMatrix ua = as.unitary_matrix ();
+  ComplexMatrix sch_a = as.schur_matrix ();
+
+  ComplexMatrix ub = bs.unitary_matrix ();
+  ComplexMatrix sch_b = bs.schur_matrix ();
+  
+  ComplexMatrix cx = ua.hermitian () * c * ub;
+
+  // Solve the sylvester equation, back-transform, and return the
+  // solution.
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type b_nr = b.rows ();
+
+  double scale;
+  octave_idx_type info;
+
+  Complex *pa = sch_a.fortran_vec ();
+  Complex *pb = sch_b.fortran_vec ();
+  Complex *px = cx.fortran_vec ();
+  
+  F77_XFCN (ztrsyl, ZTRSYL, (F77_CONST_CHAR_ARG2 ("N", 1),
+			     F77_CONST_CHAR_ARG2 ("N", 1),
+			     1, a_nr, b_nr, pa, a_nr, pb,
+			     b_nr, px, a_nr, scale, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  // FIXME -- check info?
+
+  retval = -ua * cx * ub.hermitian ();
+
+  return retval;
+}
+
+ComplexMatrix
+operator * (const ComplexMatrix& m, const Matrix& a)
+{
+  ComplexMatrix tmp (a);
+  return m * tmp;
+}
+
+ComplexMatrix
+operator * (const Matrix& m, const ComplexMatrix& a)
+{
+  ComplexMatrix tmp (m);
+  return tmp * a;
+}
+
+/* Simple Dot Product, Matrix-Vector and Matrix-Matrix Unit tests
+%!assert([1+i 2+i 3+i] * [ 4+i ; 5+i ; 6+i], 29+21i, 1e-14)
+%!assert([1+i 2+i ; 3+i 4+i ] * [5+i ; 6+i], [15 + 14i ; 37 + 18i], 1e-14)
+%!assert([1+i 2+i ; 3+i 4+i ] * [5+i 6+i ; 7+i 8+i], [17 + 15i 20 + 17i; 41 + 19i 48 + 21i], 1e-14)
+%!assert([1 i]*[i 0]', -i);
+*/
+
+/* Test some simple identities
+%!shared M, cv, rv
+%! M = randn(10,10)+i*rand(10,10);
+%! cv = randn(10,1)+i*rand(10,1);
+%! rv = randn(1,10)+i*rand(1,10);
+%!assert([M*cv,M*cv],M*[cv,cv],1e-14)
+%!assert([M.'*cv,M.'*cv],M.'*[cv,cv],1e-14)
+%!assert([M'*cv,M'*cv],M'*[cv,cv],1e-14)
+%!assert([rv*M;rv*M],[rv;rv]*M,1e-14)
+%!assert([rv*M.';rv*M.'],[rv;rv]*M.',1e-14)
+%!assert([rv*M';rv*M'],[rv;rv]*M',1e-14)
+%!assert(2*rv*cv,[rv,rv]*[cv;cv],1e-14)
+*/
+
+static const char *
+get_blas_trans_arg (bool trans, bool conj)
+{
+  static char blas_notrans = 'N', blas_trans = 'T', blas_conj_trans = 'C';
+  return trans ? (conj ? &blas_conj_trans : &blas_trans) : &blas_notrans;
+}
+
+// the general GEMM operation
+
+ComplexMatrix
+xgemm (bool transa, bool conja, const ComplexMatrix& a, 
+       bool transb, bool conjb, const ComplexMatrix& b)
+{
+  ComplexMatrix retval;
+
+  // conjugacy is ignored if no transpose
+  conja = conja && transa;
+  conjb = conjb && transb;
+
+  octave_idx_type a_nr = transa ? a.cols () : a.rows ();
+  octave_idx_type a_nc = transa ? a.rows () : a.cols ();
+
+  octave_idx_type b_nr = transb ? b.cols () : b.rows ();
+  octave_idx_type b_nc = transb ? b.rows () : b.cols ();
+
+  if (a_nc != b_nr)
+    gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+  else
+    {
+      if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+	retval = ComplexMatrix (a_nr, b_nc, 0.0);
+      else if (a.data () == b.data () && a_nr == b_nc && transa != transb)
+        {
+	  octave_idx_type lda = a.rows ();
+
+          retval = ComplexMatrix (a_nr, b_nc);
+	  Complex *c = retval.fortran_vec ();
+
+          const char *ctransa = get_blas_trans_arg (transa, conja);
+          if (conja || conjb)
+            {
+              F77_XFCN (zherk, ZHERK, (F77_CONST_CHAR_ARG2 ("U", 1),
+                                       F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                       a_nr, a_nc, 1.0,
+                                       a.data (), lda, 0.0, c, a_nr
+                                       F77_CHAR_ARG_LEN (1)
+                                       F77_CHAR_ARG_LEN (1)));
+              for (int j = 0; j < a_nr; j++)
+                for (int i = 0; i < j; i++)
+                  retval.xelem (j,i) = std::conj (retval.xelem (i,j));
+            }
+          else
+            {
+              F77_XFCN (zsyrk, ZSYRK, (F77_CONST_CHAR_ARG2 ("U", 1),
+                                       F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                       a_nr, a_nc, 1.0,
+                                       a.data (), lda, 0.0, c, a_nr
+                                       F77_CHAR_ARG_LEN (1)
+                                       F77_CHAR_ARG_LEN (1)));
+              for (int j = 0; j < a_nr; j++)
+                for (int i = 0; i < j; i++)
+                  retval.xelem (j,i) = retval.xelem (i,j);
+
+            }
+
+        }
+      else
+	{
+	  octave_idx_type lda = a.rows (), tda = a.cols ();
+	  octave_idx_type ldb = b.rows (), tdb = b.cols ();
+
+	  retval = ComplexMatrix (a_nr, b_nc);
+	  Complex *c = retval.fortran_vec ();
+
+	  if (b_nc == 1 && a_nr == 1)
+	    {
+              if (conja == conjb)
+                {
+                  F77_FUNC (xzdotu, XZDOTU) (a_nc, a.data (), 1, b.data (), 1, *c);
+                  if (conja) *c = std::conj (*c);
+                }
+              else if (conja)
+                  F77_FUNC (xzdotc, XZDOTC) (a_nc, a.data (), 1, b.data (), 1, *c);
+              else
+                  F77_FUNC (xzdotc, XZDOTC) (a_nc, b.data (), 1, a.data (), 1, *c);
+            }
+          else if (b_nc == 1 && ! conjb)
+            {
+              const char *ctransa = get_blas_trans_arg (transa, conja);
+              F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                       lda, tda, 1.0,  a.data (), lda,
+                                       b.data (), 1, 0.0, c, 1
+                                       F77_CHAR_ARG_LEN (1)));
+            }
+          else if (a_nr == 1 && ! conja && ! conjb)
+            {
+              const char *crevtransb = get_blas_trans_arg (! transb, conjb);
+              F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 (crevtransb, 1),
+                                       ldb, tdb, 1.0,  b.data (), ldb,
+                                       a.data (), 1, 0.0, c, 1
+                                       F77_CHAR_ARG_LEN (1)));
+            }
+	  else
+	    {
+              const char *ctransa = get_blas_trans_arg (transa, conja);
+              const char *ctransb = get_blas_trans_arg (transb, conjb);
+	      F77_XFCN (zgemm, ZGEMM, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+				       F77_CONST_CHAR_ARG2 (ctransb, 1),
+				       a_nr, b_nc, a_nc, 1.0, a.data (),
+				       lda, b.data (), ldb, 0.0, c, a_nr
+				       F77_CHAR_ARG_LEN (1)
+				       F77_CHAR_ARG_LEN (1)));
+	    }
+	}
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+operator * (const ComplexMatrix& a, const ComplexMatrix& b)
+{
+  return xgemm (false, false, a, false, false, b);
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nr == 0 || nc == 0) \
+    return T (nr, nc);
+
+ComplexMatrix
+min (const Complex& c, const ComplexMatrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (ComplexMatrix);
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (c, m (i, j));
+      }
+
+  return result;
+}
+
+ComplexMatrix
+min (const ComplexMatrix& m, const Complex& c)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (ComplexMatrix);
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (m (i, j), c);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+min (const ComplexMatrix& a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return ComplexMatrix ();
+    }
+
+  EMPTY_RETURN_CHECK (ComplexMatrix);
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      int columns_are_real_only = 1;
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+	    {
+	      columns_are_real_only = 0;
+	      break;
+	    }
+	}
+
+      if (columns_are_real_only)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    result (i, j) = xmin (std::real (a (i, j)), std::real (b (i, j)));
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = xmin (a (i, j), b (i, j));
+	    }
+	}
+    }
+
+  return result;
+}
+
+ComplexMatrix
+max (const Complex& c, const ComplexMatrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (ComplexMatrix);
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (c, m (i, j));
+      }
+
+  return result;
+}
+
+ComplexMatrix
+max (const ComplexMatrix& m, const Complex& c)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (ComplexMatrix);
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (m (i, j), c);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+max (const ComplexMatrix& a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return ComplexMatrix ();
+    }
+
+  EMPTY_RETURN_CHECK (ComplexMatrix);
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      int columns_are_real_only = 1;
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+	    {
+	      columns_are_real_only = 0;
+	      break;
+	    }
+	}
+
+      if (columns_are_real_only)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = xmax (std::real (a (i, j)), std::real (b (i, j)));
+	    }
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = xmax (a (i, j), b (i, j));
+	    }
+	}
+    }
+
+  return result;
+}
+
+MS_CMP_OPS(ComplexMatrix, std::real, Complex, std::real)
+MS_BOOL_OPS(ComplexMatrix, Complex, 0.0)
+
+SM_CMP_OPS(Complex, std::real, ComplexMatrix, std::real)
+SM_BOOL_OPS(Complex, ComplexMatrix, 0.0)
+
+MM_CMP_OPS(ComplexMatrix, std::real, ComplexMatrix, std::real)
+MM_BOOL_OPS(ComplexMatrix, ComplexMatrix, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CMatrix.h b/liboctave/CMatrix.h
new file mode 100644
index 0000000..4f36611
--- /dev/null
+++ b/liboctave/CMatrix.h
@@ -0,0 +1,428 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexMatrix_h)
+#define octave_ComplexMatrix_h 1
+
+#include "MArray2.h"
+#include "MDiagArray2.h"
+#include "MatrixType.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+#include "oct-cmplx.h"
+#include "DET.h"
+
+class
+OCTAVE_API
+ComplexMatrix : public MArray2<Complex>
+{
+public:
+ 
+  typedef void (*solve_singularity_handler) (double rcon);
+
+  ComplexMatrix (void) : MArray2<Complex> () { }
+
+  ComplexMatrix (octave_idx_type r, octave_idx_type c) : MArray2<Complex> (r, c) { }
+
+  ComplexMatrix (octave_idx_type r, octave_idx_type c, const Complex& val)
+    : MArray2<Complex> (r, c, val) { }
+
+  ComplexMatrix (const dim_vector& dv) : MArray2<Complex> (dv) { }
+
+  ComplexMatrix (const dim_vector& dv, const Complex& val) 
+    : MArray2<Complex> (dv, val) { }
+
+  ComplexMatrix (const ComplexMatrix& a) : MArray2<Complex> (a) { }
+
+  template <class U>
+  ComplexMatrix (const MArray2<U>& a) : MArray2<Complex> (a) { }
+
+  template <class U>
+  ComplexMatrix (const Array2<U>& a) : MArray2<Complex> (a) { }
+
+  explicit ComplexMatrix (const Matrix& a);
+
+  explicit ComplexMatrix (const RowVector& rv);
+
+  explicit ComplexMatrix (const ColumnVector& cv);
+
+  explicit ComplexMatrix (const DiagMatrix& a);
+
+  explicit ComplexMatrix (const ComplexRowVector& rv);
+
+  explicit ComplexMatrix (const ComplexColumnVector& cv);
+
+  explicit ComplexMatrix (const ComplexDiagMatrix& a);
+
+  explicit ComplexMatrix (const boolMatrix& a);
+
+  explicit ComplexMatrix (const charMatrix& a);
+
+  ComplexMatrix& operator = (const ComplexMatrix& a)
+    {
+      MArray2<Complex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const ComplexMatrix& a) const;
+  bool operator != (const ComplexMatrix& a) const;
+
+  bool is_hermitian (void) const;
+
+  // destructive insert/delete/reorder operations
+
+  ComplexMatrix& insert (const Matrix& a, octave_idx_type r, octave_idx_type c);
+  ComplexMatrix& insert (const RowVector& a, octave_idx_type r, octave_idx_type c);
+  ComplexMatrix& insert (const ColumnVector& a, octave_idx_type r, octave_idx_type c);
+  ComplexMatrix& insert (const DiagMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  ComplexMatrix& insert (const ComplexMatrix& a, octave_idx_type r, octave_idx_type c);
+  ComplexMatrix& insert (const ComplexRowVector& a, octave_idx_type r, octave_idx_type c);
+  ComplexMatrix& insert (const ComplexColumnVector& a, octave_idx_type r, octave_idx_type c);
+  ComplexMatrix& insert (const ComplexDiagMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  ComplexMatrix& fill (double val);
+  ComplexMatrix& fill (const Complex& val);
+  ComplexMatrix& fill (double val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+  ComplexMatrix& fill (const Complex& val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+
+  ComplexMatrix append (const Matrix& a) const;
+  ComplexMatrix append (const RowVector& a) const;
+  ComplexMatrix append (const ColumnVector& a) const;
+  ComplexMatrix append (const DiagMatrix& a) const;
+
+  ComplexMatrix append (const ComplexMatrix& a) const;
+  ComplexMatrix append (const ComplexRowVector& a) const;
+  ComplexMatrix append (const ComplexColumnVector& a) const;
+  ComplexMatrix append (const ComplexDiagMatrix& a) const;
+
+  ComplexMatrix stack (const Matrix& a) const;
+  ComplexMatrix stack (const RowVector& a) const;
+  ComplexMatrix stack (const ColumnVector& a) const;
+  ComplexMatrix stack (const DiagMatrix& a) const;
+
+  ComplexMatrix stack (const ComplexMatrix& a) const;
+  ComplexMatrix stack (const ComplexRowVector& a) const;
+  ComplexMatrix stack (const ComplexColumnVector& a) const;
+  ComplexMatrix stack (const ComplexDiagMatrix& a) const;
+
+  ComplexMatrix hermitian (void) const
+    { return MArray2<Complex>::hermitian (std::conj); }
+  ComplexMatrix transpose (void) const
+    { return MArray2<Complex>::transpose (); }
+
+  friend OCTAVE_API ComplexMatrix conj (const ComplexMatrix& a);
+
+  // resize is the destructive equivalent for this one
+
+  ComplexMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  ComplexMatrix extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const;
+
+  // extract row or column i.
+
+  ComplexRowVector row (octave_idx_type i) const;
+
+  ComplexColumnVector column (octave_idx_type i) const;
+
+private:
+  ComplexMatrix tinverse (MatrixType &mattype, octave_idx_type& info,
+			  double& rcon, int force, int calc_cond) const;
+
+  ComplexMatrix finverse (MatrixType &mattype, octave_idx_type& info,
+			  double& rcon, int force, int calc_cond) const;
+
+public:
+  ComplexMatrix inverse (void) const;
+  ComplexMatrix inverse (octave_idx_type& info) const;
+  ComplexMatrix inverse (octave_idx_type& info, double& rcon, int force = 0, 
+			 int calc_cond = 1) const;
+
+  ComplexMatrix inverse (MatrixType &mattype) const;
+  ComplexMatrix inverse (MatrixType &mattype, octave_idx_type& info) const;
+  ComplexMatrix inverse (MatrixType &mattype, octave_idx_type& info,
+			 double& rcon, int force = 0, 
+			 int calc_cond = 1) const;
+
+  ComplexMatrix pseudo_inverse (double tol = 0.0) const;
+
+  ComplexMatrix fourier (void) const;
+  ComplexMatrix ifourier (void) const;
+
+  ComplexMatrix fourier2d (void) const;
+  ComplexMatrix ifourier2d (void) const;
+
+  ComplexDET determinant (void) const;
+  ComplexDET determinant (octave_idx_type& info) const;
+  ComplexDET determinant (octave_idx_type& info, double& rcon, int calc_cond = 1) const;
+  ComplexDET determinant (MatrixType &mattype, octave_idx_type& info, 
+                          double& rcon, int calc_cond = 1) const;
+
+  double rcond (void) const;
+  double rcond (MatrixType &mattype) const;
+
+private:
+  // Upper triangular matrix solvers
+  ComplexMatrix utsolve (MatrixType &typ, const ComplexMatrix& b,
+		  octave_idx_type& info, double& rcon, 
+		  solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Lower triangular matrix solvers
+  ComplexMatrix ltsolve (MatrixType &typ, const ComplexMatrix& b,
+		  octave_idx_type& info, double& rcon, 
+		  solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Full matrix solvers (umfpack/cholesky)
+  ComplexMatrix fsolve (MatrixType &typ, const ComplexMatrix& b,
+		 octave_idx_type& info, double& rcon, 
+		 solve_singularity_handler sing_handler,
+		 bool calc_cond = false) const;
+
+public:
+  // Generic interface to solver with no probing of type
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b) const;
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b, 
+		       octave_idx_type& info) const;
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b, 
+		       octave_idx_type& info, double& rcon) const;
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		       double& rcon, solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcon) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcon,
+		       solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b) const;
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+			     octave_idx_type& info, double& rcon) const;
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+			     octave_idx_type& info, double& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (MatrixType &typ, 
+			     const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info, double& rcon) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info, double& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  // Generic interface to solver with probing of type
+  ComplexMatrix solve (const Matrix& b) const;
+  ComplexMatrix solve (const Matrix& b, octave_idx_type& info) const;
+  ComplexMatrix solve (const Matrix& b, octave_idx_type& info, double& rcon) const;
+  ComplexMatrix solve (const Matrix& b, octave_idx_type& info, double& rcon,
+		       solve_singularity_handler sing_handler) const;
+
+  ComplexMatrix solve (const ComplexMatrix& b) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon,
+		       solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (const ColumnVector& b) const;
+  ComplexColumnVector solve (const ColumnVector& b, octave_idx_type& info) const;
+  ComplexColumnVector solve (const ColumnVector& b, octave_idx_type& info,
+			     double& rcon) const;
+  ComplexColumnVector solve (const ColumnVector& b, octave_idx_type& info, double& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcon) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  ComplexMatrix lssolve (const Matrix& b) const;
+  ComplexMatrix lssolve (const Matrix& b, octave_idx_type& info) const;
+  ComplexMatrix lssolve (const Matrix& b, octave_idx_type& info, 
+			 octave_idx_type& rank) const;
+  ComplexMatrix lssolve (const Matrix& b, octave_idx_type& info, 
+			 octave_idx_type& rank, double& rcon) const;
+
+  ComplexMatrix lssolve (const ComplexMatrix& b) const;
+  ComplexMatrix lssolve (const ComplexMatrix& b, octave_idx_type& info) const;
+  ComplexMatrix lssolve (const ComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank) const;
+  ComplexMatrix lssolve (const ComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank, double& rcon) const;
+
+  ComplexColumnVector lssolve (const ColumnVector& b) const;
+  ComplexColumnVector lssolve (const ColumnVector& b,
+			       octave_idx_type& info) const;
+  ComplexColumnVector lssolve (const ColumnVector& b, octave_idx_type& info,
+			       octave_idx_type& rank) const;
+  ComplexColumnVector lssolve (const ColumnVector& b, octave_idx_type& info,
+			       octave_idx_type& rank, double& rcon) const;
+
+  ComplexColumnVector lssolve (const ComplexColumnVector& b) const;
+  ComplexColumnVector lssolve (const ComplexColumnVector& b,
+			       octave_idx_type& info) const;
+  ComplexColumnVector lssolve (const ComplexColumnVector& b,
+			       octave_idx_type& info,
+			       octave_idx_type& rank) const;
+  ComplexColumnVector lssolve (const ComplexColumnVector& b,
+			       octave_idx_type& info,
+			       octave_idx_type& rank, double& rcon) const;
+
+  // matrix by diagonal matrix -> matrix operations
+
+  ComplexMatrix& operator += (const DiagMatrix& a);
+  ComplexMatrix& operator -= (const DiagMatrix& a);
+
+  ComplexMatrix& operator += (const ComplexDiagMatrix& a);
+  ComplexMatrix& operator -= (const ComplexDiagMatrix& a);
+
+  // matrix by matrix -> matrix operations
+
+  ComplexMatrix& operator += (const Matrix& a);
+  ComplexMatrix& operator -= (const Matrix& a);
+
+  // unary operations
+
+  boolMatrix operator ! (void) const;
+
+  // other operations
+
+  typedef double (*dmapper) (const Complex&);
+  typedef Complex (*cmapper) (const Complex&);
+  typedef bool (*bmapper) (const Complex&);
+
+  Matrix map (dmapper fcn) const;
+  ComplexMatrix map (cmapper fcn) const;
+  boolMatrix map (bmapper fcn) const;
+
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool all_elements_are_real (void) const;
+  bool all_integers (double& max_val, double& min_val) const;
+  bool too_large_for_float (void) const;
+
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+  ComplexMatrix cumprod (int dim = -1) const;
+  ComplexMatrix cumsum (int dim = -1) const;
+  ComplexMatrix prod (int dim = -1) const;
+  ComplexMatrix sum (int dim = -1) const;
+  ComplexMatrix sumsq (int dim = -1) const;
+  Matrix abs (void) const;
+
+  ComplexMatrix diag (octave_idx_type k = 0) const;
+
+  bool row_is_real_only (octave_idx_type) const;
+  bool column_is_real_only (octave_idx_type) const;
+
+  ComplexColumnVector row_min (void) const;
+  ComplexColumnVector row_max (void) const;
+
+  ComplexColumnVector row_min (Array<octave_idx_type>& index) const; 
+  ComplexColumnVector row_max (Array<octave_idx_type>& index) const;
+
+  ComplexRowVector column_min (void) const;
+  ComplexRowVector column_max (void) const;
+
+  ComplexRowVector column_min (Array<octave_idx_type>& index) const;
+  ComplexRowVector column_max (Array<octave_idx_type>& index) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexMatrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, ComplexMatrix& a);
+
+  static Complex resize_fill_value (void) { return Complex (0.0, 0.0); }
+
+private:
+
+  ComplexMatrix (Complex *d, octave_idx_type r, octave_idx_type c) : MArray2<Complex> (d, r, c) { }
+};
+
+extern OCTAVE_API ComplexMatrix conj (const ComplexMatrix& a);
+
+// column vector by row vector -> matrix operations
+
+extern OCTAVE_API ComplexMatrix
+operator * (const ColumnVector& a, const ComplexRowVector& b);
+
+extern OCTAVE_API ComplexMatrix
+operator * (const ComplexColumnVector& a, const RowVector& b);
+
+extern OCTAVE_API ComplexMatrix
+operator * (const ComplexColumnVector& a, const ComplexRowVector& b);
+
+extern OCTAVE_API ComplexMatrix
+Givens (const Complex&, const Complex&);
+
+extern OCTAVE_API ComplexMatrix
+Sylvester (const ComplexMatrix&, const ComplexMatrix&, const ComplexMatrix&);
+
+extern OCTAVE_API ComplexMatrix 
+xgemm (bool transa, bool conja, const ComplexMatrix& a, 
+       bool transb, bool conjb, const ComplexMatrix& b);
+
+extern OCTAVE_API ComplexMatrix operator * (const Matrix&,        const ComplexMatrix&);
+extern OCTAVE_API ComplexMatrix operator * (const ComplexMatrix&, const Matrix&);
+extern OCTAVE_API ComplexMatrix operator * (const ComplexMatrix&, const ComplexMatrix&);
+
+extern OCTAVE_API ComplexMatrix min (const Complex& c, const ComplexMatrix& m);
+extern OCTAVE_API ComplexMatrix min (const ComplexMatrix& m, const Complex& c);
+extern OCTAVE_API ComplexMatrix min (const ComplexMatrix& a, const ComplexMatrix& b);
+
+extern OCTAVE_API ComplexMatrix max (const Complex& c, const ComplexMatrix& m);
+extern OCTAVE_API ComplexMatrix max (const ComplexMatrix& m, const Complex& c);
+extern OCTAVE_API ComplexMatrix max (const ComplexMatrix& a, const ComplexMatrix& b);
+
+MS_CMP_OP_DECLS (ComplexMatrix, Complex, OCTAVE_API)
+MS_BOOL_OP_DECLS (ComplexMatrix, Complex, OCTAVE_API)
+
+SM_CMP_OP_DECLS (Complex, ComplexMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (Complex, ComplexMatrix, OCTAVE_API)
+
+MM_CMP_OP_DECLS (ComplexMatrix, ComplexMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (ComplexMatrix, ComplexMatrix, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArray2, ComplexMatrix, Complex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CNDArray.cc b/liboctave/CNDArray.cc
new file mode 100644
index 0000000..4e22a28
--- /dev/null
+++ b/liboctave/CNDArray.cc
@@ -0,0 +1,1085 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <vector>
+
+#include "Array-util.h"
+#include "CNDArray.h"
+#include "mx-base.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+#include "mx-op-defs.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#else
+extern "C"
+{
+  // Note that the original complex fft routines were not written for
+  // double complex arguments.  They have been modified by adding an
+  // implicit double precision (a-h,o-z) statement at the beginning of
+  // each subroutine.
+
+  F77_RET_T
+  F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*);
+}
+#endif
+
+ComplexNDArray::ComplexNDArray (const charNDArray& a)
+  : MArrayN<Complex> (a.dims ())
+{
+  octave_idx_type n = a.numel ();
+  for (octave_idx_type i = 0; i < n; i++)
+    xelem (i) = static_cast<unsigned char> (a(i));
+}
+
+#if defined (HAVE_FFTW3)
+ComplexNDArray
+ComplexNDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  const Complex *in (fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::fft (in + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  const Complex *in (fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::ifft (in + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::fourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return ComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  const Complex *in = fortran_vec ();
+  ComplexNDArray retval (dv);
+  Complex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return ComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  const Complex *in = fortran_vec ();
+  ComplexNDArray retval (dv);
+  Complex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::ifftNd (in + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  const Complex *in (fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::fftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  const Complex *in (fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+#else
+ComplexNDArray
+ComplexNDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  ComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (zfftf, ZFFTF) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i];
+	}
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  ComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (zfftb, ZFFTB) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i] /
+	      static_cast<double> (npts);
+	}
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::fourier2d (void) const
+{
+  dim_vector dv = dims ();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] /
+		  static_cast<double> (npts);
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+ComplexNDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] /
+		  static_cast<double> (npts);
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+#endif
+
+// unary operations
+
+boolNDArray
+ComplexNDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (octave_idx_type i = 0; i < length (); i++)
+    b.elem (i) = elem (i) == 0.0;
+
+  return b;
+}
+
+// FIXME -- this is not quite the right thing.
+
+bool
+ComplexNDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = elem (i);
+      if (xisnan (val))
+	return true;
+    }
+  return false;
+}
+
+bool
+ComplexNDArray::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = elem (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+  return false;
+}
+
+// Return true if no elements have imaginary components.
+
+bool
+ComplexNDArray::all_elements_are_real (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double ip = std::imag (elem (i));
+
+      if (ip != 0.0 || lo_ieee_signbit (ip))
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of CM has a non-integer real or
+// imaginary part.  Also extract the largest and smallest (real or
+// imaginary) values and return them in MAX_VAL and MIN_VAL. 
+
+bool
+ComplexNDArray::all_integers (double& max_val, double& min_val) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (nel > 0)
+    {
+      Complex val = elem (0);
+
+      double r_val = std::real (val);
+      double i_val = std::imag (val);
+      
+      max_val = r_val;
+      min_val = r_val;
+
+      if (i_val > max_val)
+	max_val = i_val;
+
+      if (i_val < max_val)
+	min_val = i_val;
+    }
+  else
+    return false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = elem (i);
+
+      double r_val = std::real (val);
+      double i_val = std::imag (val);
+
+      if (r_val > max_val)
+	max_val = r_val;
+
+      if (i_val > max_val)
+	max_val = i_val;
+
+      if (r_val < min_val)
+	min_val = r_val;
+
+      if (i_val < min_val)
+	min_val = i_val;
+
+      if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+ComplexNDArray::too_large_for_float (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = elem (i);
+
+      double r_val = std::real (val);
+      double i_val = std::imag (val);
+
+      if ((! (xisnan (r_val) || xisinf (r_val))
+	   && fabs (r_val) > FLT_MAX)
+	  || (! (xisnan (i_val) || xisinf (i_val))
+	      && fabs (i_val) > FLT_MAX))
+	return true;
+    }
+
+  return false;
+}
+
+boolNDArray
+ComplexNDArray::all (int dim) const
+{
+  return do_mx_red_op<boolNDArray, Complex> (*this, dim, mx_inline_all);
+}
+
+boolNDArray
+ComplexNDArray::any (int dim) const
+{
+  return do_mx_red_op<boolNDArray, Complex> (*this, dim, mx_inline_any);
+}
+
+ComplexNDArray
+ComplexNDArray::cumprod (int dim) const
+{
+  return do_mx_cum_op<ComplexNDArray, Complex> (*this, dim, mx_inline_cumprod);
+}
+
+ComplexNDArray
+ComplexNDArray::cumsum (int dim) const
+{
+  return do_mx_cum_op<ComplexNDArray, Complex> (*this, dim, mx_inline_cumsum);
+}
+
+ComplexNDArray
+ComplexNDArray::prod (int dim) const
+{
+  return do_mx_red_op<ComplexNDArray, Complex> (*this, dim, mx_inline_prod);
+}
+
+ComplexNDArray
+ComplexNDArray::sum (int dim) const
+{
+  return do_mx_red_op<ComplexNDArray, Complex> (*this, dim, mx_inline_sum);
+}
+
+ComplexNDArray
+ComplexNDArray::sumsq (int dim) const
+{
+  return do_mx_red_op<NDArray, Complex> (*this, dim, mx_inline_sumsq);
+}
+
+ComplexNDArray
+ComplexNDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+ComplexNDArray
+ComplexNDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  ComplexNDArray tmp (rb);
+  if (rb.numel () > 0)
+    insert (tmp, ra_idx);
+  return *this;
+}
+
+ComplexNDArray
+concat (NDArray& ra, ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  ComplexNDArray retval (ra);
+  if (rb.numel () > 0)
+    retval.insert (rb, ra_idx);
+  return retval;
+}
+
+static const Complex Complex_NaN_result (octave_NaN, octave_NaN);
+
+ComplexNDArray
+ComplexNDArray::max (int dim) const
+{
+  return do_mx_minmax_op<ComplexNDArray> (*this, dim, mx_inline_max);
+}
+
+ComplexNDArray
+ComplexNDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_max);
+}
+
+ComplexNDArray
+ComplexNDArray::min (int dim) const
+{
+  return do_mx_minmax_op<ComplexNDArray> (*this, dim, mx_inline_min);
+}
+
+ComplexNDArray
+ComplexNDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_min);
+}
+
+ComplexNDArray
+ComplexNDArray::cummax (int dim) const
+{
+  return do_mx_cumminmax_op<ComplexNDArray> (*this, dim, mx_inline_cummax);
+}
+
+ComplexNDArray
+ComplexNDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_cummax);
+}
+
+ComplexNDArray
+ComplexNDArray::cummin (int dim) const
+{
+  return do_mx_cumminmax_op<ComplexNDArray> (*this, dim, mx_inline_cummin);
+}
+
+ComplexNDArray
+ComplexNDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_cummin);
+}
+
+NDArray
+ComplexNDArray::abs (void) const
+{
+  return NDArray (mx_inline_cabs_dup (data (), length ()),
+                  dims ());
+}
+
+boolNDArray
+ComplexNDArray::isnan (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisnan));
+}
+
+boolNDArray
+ComplexNDArray::isinf (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisinf));
+}
+
+boolNDArray
+ComplexNDArray::isfinite (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xfinite));
+}
+
+ComplexNDArray
+conj (const ComplexNDArray& a)
+{
+  return ComplexNDArray (mx_inline_conj_dup (a.data (), a.length ()),
+                         a.dims ());
+}
+
+ComplexNDArray&
+ComplexNDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  dim_vector a_dv = a.dims ();
+  
+  int n = a_dv.length ();
+  
+  if (n == dimensions.length ())
+    {
+      Array<octave_idx_type> a_ra_idx (a_dv.length (), 0);
+      
+      a_ra_idx.elem (0) = r;
+      a_ra_idx.elem (1) = c;
+      
+      for (int i = 0; i < n; i++)
+	{
+	  if (a_ra_idx (i) < 0 || (a_ra_idx (i) + a_dv (i)) > dimensions (i))
+	    {
+	      (*current_liboctave_error_handler)
+		("Array<T>::insert: range error for insert");
+	      return *this;
+	    }
+	}
+      
+      a_ra_idx.elem (0) = 0;
+      a_ra_idx.elem (1) = 0;
+      
+      octave_idx_type n_elt = a.numel ();
+      
+      // IS make_unique () NECCESSARY HERE??
+
+      for (octave_idx_type i = 0; i < n_elt; i++)
+	{
+	  Array<octave_idx_type> ra_idx = a_ra_idx;
+	  
+	  ra_idx.elem (0) = a_ra_idx (0) + r;
+	  ra_idx.elem (1) = a_ra_idx (1) + c;
+	  
+	  elem (ra_idx) = a.elem (a_ra_idx);
+
+	  increment_index (a_ra_idx, a_dv);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::insert: invalid indexing operation");
+
+  return *this;
+}
+
+ComplexNDArray&
+ComplexNDArray::insert (const ComplexNDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<Complex>::insert (a, r, c);
+  return *this;
+}
+
+ComplexNDArray&
+ComplexNDArray::insert (const ComplexNDArray& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<Complex>::insert (a, ra_idx);
+  return *this;
+}
+
+ComplexMatrix
+ComplexNDArray::matrix_value (void) const
+{
+  ComplexMatrix retval;
+
+  if (ndims () == 2)
+      retval = ComplexMatrix (Array2<Complex> (*this));
+  else
+    (*current_liboctave_error_handler)
+      ("invalid conversion of ComplexNDArray to ComplexMatrix");
+
+  return retval;
+}
+
+void
+ComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx,
+				 const dim_vector& dimensions,
+				 int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+octave_idx_type 
+ComplexNDArray::compute_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+ComplexNDArray
+ComplexNDArray::diag (octave_idx_type k) const
+{
+  return MArrayN<Complex>::diag (k);
+}
+
+NDArray
+ComplexNDArray::map (dmapper fcn) const
+{
+  return MArrayN<Complex>::map<double> (func_ptr (fcn));
+}
+
+ComplexNDArray
+ComplexNDArray::map (cmapper fcn) const
+{
+  return MArrayN<Complex>::map<Complex> (func_ptr (fcn));
+}
+
+boolNDArray
+ComplexNDArray::map (bmapper fcn) const
+{
+  return MArrayN<Complex>::map<bool> (func_ptr (fcn));
+}
+
+// This contains no information on the array structure !!!
+std::ostream&
+operator << (std::ostream& os, const ComplexNDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      os << " ";
+      octave_write_complex (os, a.elem (i));
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, ComplexNDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  if (nel > 0)
+    {
+      Complex tmp;
+      for (octave_idx_type i = 0; i < nel; i++)
+	  {
+	    tmp = octave_read_complex (is);
+	    if (is)
+	      a.elem (i) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+ done:
+
+  return is;
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nel == 0)	\
+    return T (dv);
+
+ComplexNDArray
+min (const Complex& c, const ComplexNDArray& m)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (ComplexNDArray);
+
+  ComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (c, m (i));
+    }
+
+  return result;
+}
+
+ComplexNDArray
+min (const ComplexNDArray& m, const Complex& c)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (ComplexNDArray);
+
+  ComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (c, m (i));
+    }
+
+  return result;
+}
+
+ComplexNDArray
+min (const ComplexNDArray& a, const ComplexNDArray& b)
+{
+  dim_vector dv = a.dims ();
+  int nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return ComplexNDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (ComplexNDArray);
+
+  ComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (a (i), b (i));
+    }
+
+  return result;
+}
+
+ComplexNDArray
+max (const Complex& c, const ComplexNDArray& m)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (ComplexNDArray);
+
+  ComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (c, m (i));
+    }
+
+  return result;
+}
+
+ComplexNDArray
+max (const ComplexNDArray& m, const Complex& c)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (ComplexNDArray);
+
+  ComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (c, m (i));
+    }
+
+  return result;
+}
+
+ComplexNDArray
+max (const ComplexNDArray& a, const ComplexNDArray& b)
+{
+  dim_vector dv = a.dims ();
+  int nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return ComplexNDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (ComplexNDArray);
+
+  ComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (a (i), b (i));
+    }
+
+  return result;
+}
+
+NDS_CMP_OPS(ComplexNDArray, std::real, Complex, std::real)
+NDS_BOOL_OPS(ComplexNDArray, Complex, 0.0)
+
+SND_CMP_OPS(Complex, std::real, ComplexNDArray, std::real)
+SND_BOOL_OPS(Complex, ComplexNDArray, 0.0)
+
+NDND_CMP_OPS(ComplexNDArray, std::real, ComplexNDArray, std::real)
+NDND_BOOL_OPS(ComplexNDArray, ComplexNDArray, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CNDArray.h b/liboctave/CNDArray.h
new file mode 100644
index 0000000..3c596cd
--- /dev/null
+++ b/liboctave/CNDArray.h
@@ -0,0 +1,180 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexNDArray_h)
+#define octave_ComplexNDArray_h 1
+
+#include "MArrayN.h"
+#include "CMatrix.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+class
+OCTAVE_API
+ComplexNDArray : public MArrayN<Complex>
+{
+public:
+
+  ComplexNDArray (void) : MArrayN<Complex> () { }
+
+  ComplexNDArray (const dim_vector& dv) : MArrayN<Complex> (dv) { }
+
+  ComplexNDArray (const dim_vector& dv, const Complex& val)
+    : MArrayN<Complex> (dv, val) { }
+  
+  ComplexNDArray (const ComplexNDArray& a) : MArrayN<Complex> (a) { }
+
+  ComplexNDArray (const ComplexMatrix& a) : MArrayN<Complex> (a) { }
+
+  template <class U>
+  ComplexNDArray (const MArrayN<U>& a) : MArrayN<Complex> (a) { }
+
+  template <class U>
+  ComplexNDArray (const ArrayN<U>& a) : MArrayN<Complex> (a) { }
+
+  ComplexNDArray (const charNDArray&); 
+
+  ComplexNDArray& operator = (const ComplexNDArray& a)
+    {
+      MArrayN<Complex>::operator = (a);
+      return *this;
+    }
+
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
+  // FIXME -- this is not quite the right thing.
+
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool all_elements_are_real (void) const;
+  bool all_integers (double& max_val, double& min_val) const;
+  bool too_large_for_float (void) const;
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+
+  ComplexNDArray cumprod (int dim = -1) const;
+  ComplexNDArray cumsum (int dim = -1) const;
+  ComplexNDArray prod (int dim = -1) const;
+  ComplexNDArray sum (int dim = -1) const;
+  ComplexNDArray sumsq (int dim = -1) const;
+  ComplexNDArray concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx);
+  ComplexNDArray concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx);
+
+  ComplexNDArray max (int dim = 0) const;
+  ComplexNDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  ComplexNDArray min (int dim = 0) const;
+  ComplexNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const;
+
+  ComplexNDArray cummax (int dim = 0) const;
+  ComplexNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  ComplexNDArray cummin (int dim = 0) const;
+  ComplexNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const;
+
+  ComplexNDArray& insert (const NDArray& a, octave_idx_type r, octave_idx_type c);
+  ComplexNDArray& insert (const ComplexNDArray& a, octave_idx_type r, octave_idx_type c);
+  ComplexNDArray& insert (const ComplexNDArray& a, const Array<octave_idx_type>& ra_idx);
+  
+  NDArray abs (void) const;
+  boolNDArray isnan (void) const;
+  boolNDArray isinf (void) const;
+  boolNDArray isfinite (void) const;
+
+  friend OCTAVE_API ComplexNDArray conj (const ComplexNDArray& a);
+
+  ComplexNDArray fourier (int dim = 1) const;
+  ComplexNDArray ifourier (int dim = 1) const;
+
+  ComplexNDArray fourier2d (void) const;
+  ComplexNDArray ifourier2d (void) const;
+
+  ComplexNDArray fourierNd (void) const;
+  ComplexNDArray ifourierNd (void) const;
+
+  ComplexMatrix matrix_value (void) const;
+
+  ComplexNDArray squeeze (void) const { return MArrayN<Complex>::squeeze (); }
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexNDArray& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, ComplexNDArray& a);
+
+  static Complex resize_fill_value (void) { return Complex (0.0, 0.0); }
+
+  //  bool all_elements_are_real (void) const;
+  //  bool all_integers (double& max_val, double& min_val) const;
+
+  ComplexNDArray diag (octave_idx_type k = 0) const;
+
+  typedef double (*dmapper) (const Complex&);
+  typedef Complex (*cmapper) (const Complex&);
+  typedef bool (*bmapper) (const Complex&);
+
+  NDArray map (dmapper fcn) const;
+  ComplexNDArray map (cmapper fcn) const;
+  boolNDArray map (bmapper fcn) const;
+
+private:
+
+  ComplexNDArray (Complex *d, const dim_vector& dv)
+    : MArrayN<Complex> (d, dv) { }
+};
+
+extern OCTAVE_API ComplexNDArray conj (const ComplexNDArray& a);
+
+extern OCTAVE_API ComplexNDArray min (const Complex& c, const ComplexNDArray& m);
+extern OCTAVE_API ComplexNDArray min (const ComplexNDArray& m, const Complex& c);
+extern OCTAVE_API ComplexNDArray min (const ComplexNDArray& a, const ComplexNDArray& b);
+
+extern OCTAVE_API ComplexNDArray max (const Complex& c, const ComplexNDArray& m);
+extern OCTAVE_API ComplexNDArray max (const ComplexNDArray& m, const Complex& c);
+extern OCTAVE_API ComplexNDArray max (const ComplexNDArray& a, const ComplexNDArray& b);
+
+NDS_CMP_OP_DECLS (ComplexNDArray, Complex, OCTAVE_API)
+NDS_BOOL_OP_DECLS (ComplexNDArray, Complex, OCTAVE_API)
+
+SND_CMP_OP_DECLS (Complex, ComplexNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (Complex, ComplexNDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (ComplexNDArray, ComplexNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (ComplexNDArray, ComplexNDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, ComplexNDArray, Complex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CRowVector.cc b/liboctave/CRowVector.cc
new file mode 100644
index 0000000..bf47039
--- /dev/null
+++ b/liboctave/CRowVector.cc
@@ -0,0 +1,509 @@
+// RowVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgemv, ZGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const Complex&,
+			   const Complex*, const octave_idx_type&, const Complex*,
+			   const octave_idx_type&, const Complex&, Complex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xzdotu, XZDOTU) (const octave_idx_type&, const Complex*, const octave_idx_type&,
+			     const Complex*, const octave_idx_type&, Complex&);
+}
+
+// Complex Row Vector class
+
+ComplexRowVector::ComplexRowVector (const RowVector& a)
+  : MArray<Complex> (a.length ())
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i) = a.elem (i);
+}
+
+bool
+ComplexRowVector::operator == (const ComplexRowVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+ComplexRowVector::operator != (const ComplexRowVector& a) const
+{
+  return !(*this == a);
+}
+
+// destructive insert/delete/reorder operations
+
+ComplexRowVector&
+ComplexRowVector::insert (const RowVector& a, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (c < 0 || c + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::insert (const ComplexRowVector& a, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (c < 0 || c + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::fill (double val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::fill (const Complex& val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::fill (double val, octave_idx_type c1, octave_idx_type c2)
+{
+  octave_idx_type len = length ();
+
+  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = c1; i <= c2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::fill (const Complex& val, octave_idx_type c1, octave_idx_type c2)
+{
+  octave_idx_type len = length ();
+
+  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = c1; i <= c2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ComplexRowVector
+ComplexRowVector::append (const RowVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nc_insert = len;
+  ComplexRowVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nc_insert);
+  return retval;
+}
+
+ComplexRowVector
+ComplexRowVector::append (const ComplexRowVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nc_insert = len;
+  ComplexRowVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nc_insert);
+  return retval;
+}
+
+ComplexColumnVector
+ComplexRowVector::hermitian (void) const
+{
+  return MArray<Complex>::hermitian (std::conj);
+}
+
+ComplexColumnVector
+ComplexRowVector::transpose (void) const
+{
+  return MArray<Complex>::transpose ();
+}
+
+ComplexRowVector
+conj (const ComplexRowVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  ComplexRowVector retval;
+  if (a_len > 0)
+    retval = ComplexRowVector (mx_inline_conj_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+// resize is the destructive equivalent for this one
+
+ComplexRowVector
+ComplexRowVector::extract (octave_idx_type c1, octave_idx_type c2) const
+{
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  ComplexRowVector result (new_c);
+
+  for (octave_idx_type i = 0; i < new_c; i++)
+    result.elem (i) = elem (c1+i);
+
+  return result;
+}
+
+ComplexRowVector
+ComplexRowVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  ComplexRowVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.elem (i) = elem (r1+i);
+
+  return result;
+}
+
+// row vector by row vector -> row vector operations
+
+ComplexRowVector&
+ComplexRowVector::operator += (const RowVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator +=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::operator -= (const RowVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator -=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_subtract2 (d, a.data (), len);
+  return *this;
+}
+
+// row vector by matrix -> row vector
+
+ComplexRowVector
+operator * (const ComplexRowVector& v, const ComplexMatrix& a)
+{
+  ComplexRowVector retval;
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != len)
+    gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
+  else
+    {
+      if (len == 0)
+	retval.resize (a_nc, 0.0);
+      else
+	{
+	  // Transpose A to form A'*x == (x'*A)'
+
+	  octave_idx_type ld = a_nr;
+
+	  retval.resize (a_nc);
+	  Complex *y = retval.fortran_vec ();
+
+	  F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
+				   a_nr, a_nc, 1.0, a.data (),
+				   ld, v.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+ComplexRowVector
+operator * (const RowVector& v, const ComplexMatrix& a)
+{
+  ComplexRowVector tmp (v);
+  return tmp * a;
+}
+
+// other operations
+
+RowVector
+ComplexRowVector::map (dmapper fcn) const
+{
+  return MArray<Complex>::map<double> (func_ptr (fcn));
+}
+
+ComplexRowVector
+ComplexRowVector::map (cmapper fcn) const
+{
+  return MArray<Complex>::map<Complex> (func_ptr (fcn));
+}
+
+Complex
+ComplexRowVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return Complex (0.0);
+
+  Complex res = elem (0);
+  double absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) < absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+Complex
+ComplexRowVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return Complex (0.0);
+
+  Complex res = elem (0);
+  double absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) > absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const ComplexRowVector& a)
+{
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << " " /* setw (field_width) */ << a.elem (i);
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, ComplexRowVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      Complex tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+// row vector by column vector -> scalar
+
+// row vector by column vector -> scalar
+
+Complex
+operator * (const ComplexRowVector& v, const ColumnVector& a)
+{
+  ComplexColumnVector tmp (a);
+  return v * tmp;
+}
+
+Complex
+operator * (const ComplexRowVector& v, const ComplexColumnVector& a)
+{
+  Complex retval (0.0, 0.0);
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    gripe_nonconformant ("operator *", len, a_len);
+  else if (len != 0)
+    F77_FUNC (xzdotu, XZDOTU) (len, v.data (), 1, a.data (), 1, retval);
+
+  return retval;
+}
+
+// other operations
+
+ComplexRowVector
+linspace (const Complex& x1, const Complex& x2, octave_idx_type n)
+{
+  ComplexRowVector retval;
+
+  if (n > 0)
+    {
+      retval.resize (n);
+      Complex delta = (x2 - x1) / (n - 1.0);
+      retval.elem (0) = x1;
+      for (octave_idx_type i = 1; i < n-1; i++)
+	retval.elem (i) = x1 + 1.0 * i * delta;
+      retval.elem (n-1) = x2;
+    }
+  else
+    {
+      retval.resize (1);
+      retval.elem (0) = x2;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CRowVector.h b/liboctave/CRowVector.h
new file mode 100644
index 0000000..88139ab
--- /dev/null
+++ b/liboctave/CRowVector.h
@@ -0,0 +1,136 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexRowVector_h)
+#define octave_ComplexRowVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+ComplexRowVector : public MArray<Complex>
+{
+friend class ComplexColumnVector;
+
+public:
+
+  ComplexRowVector (void) : MArray<Complex> () { }
+
+  explicit ComplexRowVector (octave_idx_type n) : MArray<Complex> (n) { }
+
+  ComplexRowVector (octave_idx_type n, const Complex& val) : MArray<Complex> (n, val) { }
+
+  ComplexRowVector (const ComplexRowVector& a) : MArray<Complex> (a) { }
+
+  ComplexRowVector (const MArray<Complex>& a) : MArray<Complex> (a) { }
+
+  explicit ComplexRowVector (const RowVector& a);
+
+  ComplexRowVector& operator = (const ComplexRowVector& a)
+    {
+      MArray<Complex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const ComplexRowVector& a) const;
+  bool operator != (const ComplexRowVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  ComplexRowVector& insert (const RowVector& a, octave_idx_type c);
+  ComplexRowVector& insert (const ComplexRowVector& a, octave_idx_type c);
+
+  ComplexRowVector& fill (double val);
+  ComplexRowVector& fill (const Complex& val);
+  ComplexRowVector& fill (double val, octave_idx_type c1, octave_idx_type c2);
+  ComplexRowVector& fill (const Complex& val, octave_idx_type c1, octave_idx_type c2);
+
+  ComplexRowVector append (const RowVector& a) const;
+  ComplexRowVector append (const ComplexRowVector& a) const;
+
+  ComplexColumnVector hermitian (void) const;
+  ComplexColumnVector transpose (void) const;
+
+  friend ComplexRowVector conj (const ComplexRowVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  ComplexRowVector extract (octave_idx_type c1, octave_idx_type c2) const;
+
+  ComplexRowVector extract_n (octave_idx_type c1, octave_idx_type n) const;
+
+  // row vector by row vector -> row vector operations
+
+  ComplexRowVector& operator += (const RowVector& a);
+  ComplexRowVector& operator -= (const RowVector& a);
+
+  // row vector by matrix -> row vector
+
+  friend ComplexRowVector operator * (const ComplexRowVector& a,
+				      const ComplexMatrix& b);
+
+  friend ComplexRowVector operator * (const RowVector& a,
+				      const ComplexMatrix& b);
+
+  // other operations
+
+  typedef double (*dmapper) (const Complex&);
+  typedef Complex (*cmapper) (const Complex&);
+
+  RowVector map (dmapper fcn) const;
+  ComplexRowVector map (cmapper fcn) const;
+
+  Complex min (void) const;
+  Complex max (void) const;
+
+  // i/o
+
+  friend std::ostream& operator << (std::ostream& os, const ComplexRowVector& a);
+  friend std::istream& operator >> (std::istream& is, ComplexRowVector& a);
+
+private:
+
+  ComplexRowVector (Complex *d, octave_idx_type l) : MArray<Complex> (d, l) { }
+};
+
+// row vector by column vector -> scalar
+
+Complex operator * (const ComplexRowVector& a, const ColumnVector& b);
+
+Complex operator * (const ComplexRowVector& a, const ComplexColumnVector& b);
+
+// other operations
+
+OCTAVE_API ComplexRowVector linspace (const Complex& x1, const Complex& x2, octave_idx_type n);
+
+MARRAY_FORWARD_DEFS (MArray, ComplexRowVector, Complex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CSparse.cc b/liboctave/CSparse.cc
new file mode 100644
index 0000000..f0e3e5c
--- /dev/null
+++ b/liboctave/CSparse.cc
@@ -0,0 +1,7968 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <vector>
+
+#include "quit.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "f77-fcn.h"
+#include "dRowVector.h"
+#include "oct-locbuf.h"
+
+#include "dDiagMatrix.h"
+#include "CDiagMatrix.h"
+#include "CSparse.h"
+#include "boolSparse.h"
+#include "dSparse.h"
+#include "functor.h"
+#include "oct-spparms.h"
+#include "SparseCmplxLU.h"
+#include "oct-sparse.h"
+#include "sparse-util.h"
+#include "SparseCmplxCHOL.h"
+#include "SparseCmplxQR.h"
+
+#include "Sparse-diag-op-defs.h"
+
+#include "Sparse-perm-op-defs.h"
+
+// Define whether to use a basic QR solver or one that uses a Dulmange
+// Mendelsohn factorization to seperate the problem into under-determined,
+// well-determined and over-determined parts and solves them seperately
+#ifndef USE_QRSOLVE
+#include "sparse-dmsolve.cc"
+#endif
+
+// Fortran functions we call.
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgbtrf, ZGBTRF) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+			     const octave_idx_type&, Complex*, const octave_idx_type&, octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgbtrs, ZGBTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+			     const Complex*, const octave_idx_type&,
+			     const octave_idx_type*, Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgbcon, ZGBCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const octave_idx_type&, Complex*, 
+			     const octave_idx_type&, const octave_idx_type*, const double&, 
+			     double&, Complex*, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpbtrf, ZPBTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpbtrs, ZPBTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const octave_idx_type&, Complex*, const octave_idx_type&, 
+			     Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpbcon, ZPBCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, Complex*, const octave_idx_type&, 
+			     const double&, double&, Complex*, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgttrf, ZGTTRF) (const octave_idx_type&, Complex*, Complex*, Complex*,
+			     Complex*, octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgttrs, ZGTTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     const octave_idx_type&, const Complex*, const Complex*,
+			     const Complex*, const Complex*, const octave_idx_type*,
+			     Complex *, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, double*, Complex*,
+			   Complex*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgtsv, ZGTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*,
+			   Complex*, Complex*, const octave_idx_type&, octave_idx_type&);
+}
+
+SparseComplexMatrix::SparseComplexMatrix (const SparseMatrix& a)
+  : MSparse<Complex> (a.rows (), a.cols (), a.nnz ())
+{
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = a.nnz ();
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    cidx (i) = a.cidx (i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      data (i) = Complex (a.data (i));
+      ridx (i) = a.ridx (i);
+    }
+}
+
+SparseComplexMatrix::SparseComplexMatrix (const SparseBoolMatrix& a)
+  : MSparse<Complex> (a.rows (), a.cols (), a.nnz ())
+{
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = a.nnz ();
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    cidx (i) = a.cidx (i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      data (i) = Complex (a.data (i));
+      ridx (i) = a.ridx (i);
+    }
+}
+
+SparseComplexMatrix::SparseComplexMatrix (const ComplexDiagMatrix& a)
+  : MSparse<Complex> (a.rows (), a.cols (), a.length ())
+{
+  octave_idx_type j = 0, l = a.length ();
+  for (octave_idx_type i = 0; i < l; i++)
+    {
+      cidx (i) = j;
+      if (a(i, i) != 0.0)
+        {
+          data (j) = a(i, i);
+          ridx (j) = i;
+          j++;
+        }
+    }
+  for (octave_idx_type i = l; i <= a.cols (); i++)
+    cidx(i) = j;
+}
+bool
+SparseComplexMatrix::operator == (const SparseComplexMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nnz ();
+  octave_idx_type nr_a = a.rows ();
+  octave_idx_type nc_a = a.cols ();
+  octave_idx_type nz_a = a.nnz ();
+
+  if (nr != nr_a || nc != nc_a || nz != nz_a)
+    return false;
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    if (cidx(i) != a.cidx(i))
+	return false;
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    if (data(i) != a.data(i) || ridx(i) != a.ridx(i))
+      return false;
+
+  return true;
+}
+
+bool
+SparseComplexMatrix::operator != (const SparseComplexMatrix& a) const
+{
+  return !(*this == a);
+}
+
+bool
+SparseComplexMatrix::is_hermitian (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr == nc && nr > 0)
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      octave_idx_type ri = ridx(i);
+
+	      if (ri != j)
+		{
+		  bool found = false;
+
+		  for (octave_idx_type k = cidx(ri); k < cidx(ri+1); k++)
+		    {
+		      if (ridx(k) == j)
+			{
+			  if (data(i) == conj(data(k)))
+			    found = true;
+			  break;
+			}
+		    }
+
+		  if (! found)
+		    return false;
+		}
+	    }
+	}
+
+      return true;
+    }
+
+  return false;
+}
+
+static const Complex Complex_NaN_result (octave_NaN, octave_NaN);
+
+SparseComplexMatrix
+SparseComplexMatrix::max (int dim) const
+{
+  Array2<octave_idx_type> dummy_idx;
+  return max (dummy_idx, dim);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::max (Array2<octave_idx_type>& idx_arg, int dim) const
+{
+  SparseComplexMatrix result;
+  dim_vector dv = dims ();
+
+  if (dv.numel () == 0 || dim > dv.length () || dim < 0)
+    return result;
+ 
+  octave_idx_type nr = dv(0);
+  octave_idx_type nc = dv(1);
+
+  if (dim == 0)
+    {
+      idx_arg.resize (1, nc);
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  Complex tmp_max;
+	  double abs_max = octave_NaN;
+	  octave_idx_type idx_j = 0;
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      if (ridx(i) != idx_j)
+		break;
+	      else
+		idx_j++;
+	    }
+
+	  if (idx_j != nr)
+	    {
+	      tmp_max = 0.;
+	      abs_max = 0.;
+	    }
+
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      Complex tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      double abs_tmp = std::abs (tmp);
+
+	      if (xisnan (abs_max) || abs_tmp > abs_max)
+		{
+		  idx_j = ridx (i);
+		  tmp_max = tmp;
+		  abs_max = abs_tmp;
+		}
+	    }
+
+ 	  idx_arg.elem (j) = xisnan (tmp_max) ? 0 : idx_j;
+	  if (abs_max != 0.)
+	    nel++;
+	}
+
+      result = SparseComplexMatrix (1, nc, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  Complex tmp = elem (idx_arg(j), j);
+	  if (tmp != 0.)
+	    {
+	      result.xdata (ii) = tmp;
+	      result.xridx (ii++) = 0;
+	    }
+	  result.xcidx (j+1) = ii;
+	}
+    }
+  else
+    {
+      idx_arg.resize (nr, 1, 0);
+
+      for (octave_idx_type i = cidx(0); i < cidx(1); i++)
+	idx_arg.elem(ridx(i)) = -1;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    if (idx_arg.elem(i) != -1)
+	      continue;
+	    bool found = false;
+	    for (octave_idx_type k = cidx(j); k < cidx(j+1); k++)
+	      if (ridx(k) == i)
+		{
+		  found = true;
+		  break;
+		}
+	    
+	    if (!found)
+	      idx_arg.elem(i) = j;
+
+	  }
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      octave_idx_type ir = ridx (i);
+	      octave_idx_type ix = idx_arg.elem (ir);
+	      Complex tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (ix == -1 || std::abs(tmp) > std::abs(elem (ir, ix)))
+		idx_arg.elem (ir) = j;
+	    }
+	}
+
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nr; j++)
+	if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.)
+	  nel++;
+
+      result = SparseComplexMatrix (nr, 1, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      result.xcidx (1) = nel;
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (idx_arg(j) == -1)
+	    {
+	      idx_arg(j) = 0;
+	      result.xdata (ii) = Complex_NaN_result;
+	      result.xridx (ii++) = j;
+	    }
+	  else
+	    {
+	      Complex tmp = elem (j, idx_arg(j));
+	      if (tmp != 0.)
+		{
+		  result.xdata (ii) = tmp;
+		  result.xridx (ii++) = j;
+		}
+	    }
+	}
+    }
+
+  return result;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::min (int dim) const
+{
+  Array2<octave_idx_type> dummy_idx;
+  return min (dummy_idx, dim);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::min (Array2<octave_idx_type>& idx_arg, int dim) const
+{
+  SparseComplexMatrix result;
+  dim_vector dv = dims ();
+
+  if (dv.numel () == 0 || dim > dv.length () || dim < 0)
+    return result;
+ 
+  octave_idx_type nr = dv(0);
+  octave_idx_type nc = dv(1);
+
+  if (dim == 0)
+    {
+      idx_arg.resize (1, nc);
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  Complex tmp_min;
+	  double abs_min = octave_NaN;
+	  octave_idx_type idx_j = 0;
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      if (ridx(i) != idx_j)
+		break;
+	      else
+		idx_j++;
+	    }
+
+	  if (idx_j != nr)
+	    {
+	      tmp_min = 0.;
+	      abs_min = 0.;
+	    }
+
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      Complex tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      double abs_tmp = std::abs (tmp);
+
+	      if (xisnan (abs_min) || abs_tmp < abs_min)
+		{
+		  idx_j = ridx (i);
+		  tmp_min = tmp;
+		  abs_min = abs_tmp;
+		}
+	    }
+
+ 	  idx_arg.elem (j) = xisnan (tmp_min) ? 0 : idx_j;
+	  if (abs_min != 0.)
+	    nel++;
+	}
+
+      result = SparseComplexMatrix (1, nc, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  Complex tmp = elem (idx_arg(j), j);
+	  if (tmp != 0.)
+	    {
+	      result.xdata (ii) = tmp;
+	      result.xridx (ii++) = 0;
+	    }
+	  result.xcidx (j+1) = ii;
+	}
+    }
+  else
+    {
+      idx_arg.resize (nr, 1, 0);
+
+      for (octave_idx_type i = cidx(0); i < cidx(1); i++)
+	idx_arg.elem(ridx(i)) = -1;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    if (idx_arg.elem(i) != -1)
+	      continue;
+	    bool found = false;
+	    for (octave_idx_type k = cidx(j); k < cidx(j+1); k++)
+	      if (ridx(k) == i)
+		{
+		  found = true;
+		  break;
+		}
+	    
+	    if (!found)
+	      idx_arg.elem(i) = j;
+
+	  }
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      octave_idx_type ir = ridx (i);
+	      octave_idx_type ix = idx_arg.elem (ir);
+	      Complex tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (ix == -1 || std::abs(tmp) < std::abs(elem (ir, ix)))
+		idx_arg.elem (ir) = j;
+	    }
+	}
+
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nr; j++)
+	if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.)
+	  nel++;
+
+      result = SparseComplexMatrix (nr, 1, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      result.xcidx (1) = nel;
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (idx_arg(j) == -1)
+	    {
+	      idx_arg(j) = 0;
+	      result.xdata (ii) = Complex_NaN_result;
+	      result.xridx (ii++) = j;
+	    }
+	  else
+	    {
+	      Complex tmp = elem (j, idx_arg(j));
+	      if (tmp != 0.)
+		{
+		  result.xdata (ii) = tmp;
+		  result.xridx (ii++) = j;
+		}
+	    }
+	}
+    }
+
+  return result;
+}
+
+ComplexRowVector 
+SparseComplexMatrix::row (octave_idx_type i) const
+{
+  octave_idx_type nc = columns ();
+  ComplexRowVector retval (nc, 0);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type k = cidx (j); k < cidx (j+1); k++)
+      {
+        if (ridx (k) == i)
+          {
+            retval(j) = data (k);
+            break;
+          }
+      }
+
+  return retval;
+}
+
+ComplexColumnVector 
+SparseComplexMatrix::column (octave_idx_type i) const
+{
+  octave_idx_type nr = rows ();
+  ComplexColumnVector retval (nr);
+
+  for (octave_idx_type k = cidx (i); k < cidx (i+1); k++)
+    retval(ridx (k)) = data (k);
+
+  return retval;
+}
+
+// destructive insert/delete/reorder operations
+
+SparseComplexMatrix&
+SparseComplexMatrix::insert (const SparseMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  SparseComplexMatrix tmp (a);
+  return insert (tmp /*a*/, r, c);
+}
+
+SparseComplexMatrix&
+SparseComplexMatrix::insert (const SparseComplexMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  MSparse<Complex>::insert (a, r, c);
+  return *this;
+}
+
+SparseComplexMatrix&
+SparseComplexMatrix::insert (const SparseMatrix& a, const Array<octave_idx_type>& indx)
+{
+  SparseComplexMatrix tmp (a);
+  return insert (tmp /*a*/, indx);
+}
+
+SparseComplexMatrix&
+SparseComplexMatrix::insert (const SparseComplexMatrix& a, const Array<octave_idx_type>& indx)
+{
+  MSparse<Complex>::insert (a, indx);
+  return *this;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::concat (const SparseComplexMatrix& rb, 
+			     const Array<octave_idx_type>& ra_idx)
+{
+  // Don't use numel to avoid all possiblity of an overflow
+  if (rb.rows () > 0 && rb.cols () > 0)
+    insert (rb, ra_idx(0), ra_idx(1));
+  return *this;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::concat (const SparseMatrix& rb, const Array<octave_idx_type>& ra_idx)
+{
+  SparseComplexMatrix tmp (rb);
+  if (rb.rows () > 0 && rb.cols () > 0)
+    insert (tmp, ra_idx(0), ra_idx(1));
+  return *this;
+}
+
+ComplexMatrix
+SparseComplexMatrix::matrix_value (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  ComplexMatrix retval (nr, nc, Complex (0.0, 0.0));
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+      retval.elem (ridx(i), j) = data (i);
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::hermitian (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nnz ();
+  SparseComplexMatrix retval (nc, nr, nz);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    retval.xcidx (ridx (i) + 1)++;
+  // retval.xcidx[1:nr] holds the row degrees for rows 0:(nr-1)
+  nz = 0;
+  for (octave_idx_type i = 1; i <= nr; i++)
+    {
+      const octave_idx_type tmp = retval.xcidx (i);
+      retval.xcidx (i) = nz;
+      nz += tmp;
+    }
+  // retval.xcidx[1:nr] holds row entry *start* offsets for rows 0:(nr-1)
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type k = cidx(j); k < cidx(j+1); k++)
+      {
+	octave_idx_type q = retval.xcidx (ridx (k) + 1)++;
+	retval.xridx (q) = j;
+	retval.xdata (q) = conj (data (k));
+      }
+  assert (nnz () == retval.xcidx (nr));
+  // retval.xcidx[1:nr] holds row entry *end* offsets for rows 0:(nr-1)
+  // and retval.xcidx[0:(nr-1)] holds their row entry *start* offsets
+
+  return retval;
+}
+
+SparseComplexMatrix
+conj (const SparseComplexMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type nz = a.nnz ();
+  SparseComplexMatrix retval (nc, nr, nz);
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    retval.cidx (i) = a.cidx (i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      retval.data (i) = conj (a.data (i));
+      retval.ridx (i) = a.ridx (i);
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  double rcond;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcond, 0, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::inverse (MatrixType& mattype) const
+{
+  octave_idx_type info;
+  double rcond;
+  return inverse (mattype, info, rcond, 0, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::inverse (MatrixType& mattype, octave_idx_type& info) const
+{
+  double rcond;
+  return inverse (mattype, info, rcond, 0, 0);
+}
+
+SparseComplexMatrix 
+SparseComplexMatrix::dinverse (MatrixType &mattyp, octave_idx_type& info, 
+			double& rcond, const bool,
+			const bool calccond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  info = 0;
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattyp.type ();
+      mattyp.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  if (typ == MatrixType::Permuted_Diagonal)
+	    retval = transpose();
+	  else
+	    retval = *this;
+	      
+	  // Force make_unique to be called
+	  Complex *v = retval.data();
+
+	  if (calccond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  double tmp = std::abs(v[i]);
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    v[i] = 1.0 / v[i];
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix 
+SparseComplexMatrix::tinverse (MatrixType &mattyp, octave_idx_type& info, 
+			       double& rcond, const bool,
+			       const bool calccond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  info = 0;
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattyp.type ();
+      mattyp.info ();
+
+      if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+
+	  if (calccond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Upper || typ == MatrixType::Lower)
+	    {
+	      octave_idx_type nz = nnz ();
+	      octave_idx_type cx = 0;
+	      octave_idx_type nz2 = nz;
+	      retval = SparseComplexMatrix (nr, nc, nz2);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  OCTAVE_QUIT;
+		  // place the 1 in the identity position
+		  octave_idx_type cx_colstart = cx;
+	  
+		  if (cx == nz2)
+		    {
+		      nz2 *= 2;
+		      retval.change_capacity (nz2);
+		    }
+
+		  retval.xcidx(i) = cx;
+		  retval.xridx(cx) = i;
+		  retval.xdata(cx) = 1.0;
+		  cx++;
+
+		  // iterate accross columns of input matrix
+		  for (octave_idx_type j = i+1; j < nr; j++) 
+		    {
+		      Complex v = 0.;
+		      // iterate to calculate sum
+		      octave_idx_type colXp = retval.xcidx(i);
+		      octave_idx_type colUp = cidx(j);
+		      octave_idx_type rpX, rpU;
+
+		      if (cidx(j) == cidx(j+1))
+			{
+			  (*current_liboctave_error_handler) 
+			    ("division by zero");
+			  goto inverse_singular;
+			}
+
+		      do
+			{
+			  OCTAVE_QUIT;
+			  rpX = retval.xridx(colXp);
+			  rpU = ridx(colUp);
+
+			  if (rpX < rpU) 
+			    colXp++;
+			  else if (rpX > rpU) 
+			    colUp++;
+			  else 
+			    {
+			      v -= retval.xdata(colXp) * data(colUp);
+			      colXp++;
+			      colUp++;
+			    }
+			} while ((rpX<j) && (rpU<j) && 
+				 (colXp<cx) && (colUp<nz));
+
+
+		      // get A(m,m)
+		      if (typ == MatrixType::Upper)
+			colUp = cidx(j+1) - 1;
+		      else
+			colUp = cidx(j);
+		      Complex pivot = data(colUp);
+		      if (pivot == 0. || ridx(colUp) != j) 
+			{
+			  (*current_liboctave_error_handler) 
+			    ("division by zero");
+			  goto inverse_singular;
+			}
+
+		      if (v != 0.)
+			{
+			  if (cx == nz2)
+			    {
+			      nz2 *= 2;
+			      retval.change_capacity (nz2);
+			    }
+
+			  retval.xridx(cx) = j;
+			  retval.xdata(cx) = v / pivot;
+			  cx++;
+			}
+		    }
+
+		  // get A(m,m)
+		  octave_idx_type colUp;
+		  if (typ == MatrixType::Upper)
+		    colUp = cidx(i+1) - 1;
+		  else
+		    colUp = cidx(i);
+		  Complex pivot = data(colUp);
+		  if (pivot == 0. || ridx(colUp) != i) 
+		    {
+		      (*current_liboctave_error_handler) ("division by zero");
+		      goto inverse_singular;
+		    }
+
+		  if (pivot != 1.0)
+		    for (octave_idx_type j = cx_colstart; j < cx; j++)
+		      retval.xdata(j) /= pivot;
+		}
+	      retval.xcidx(nr) = cx;
+	      retval.maybe_compress ();
+	    }
+	  else
+	    {
+	      octave_idx_type nz = nnz ();
+	      octave_idx_type cx = 0;
+	      octave_idx_type nz2 = nz;
+	      retval = SparseComplexMatrix (nr, nc, nz2);
+
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nr);
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr);
+
+	      octave_idx_type *perm = mattyp.triangular_perm();
+	      if (typ == MatrixType::Permuted_Upper)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    rperm[perm[i]] = i;
+		}
+	      else
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    rperm[i] = perm[i];
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    perm[rperm[i]] = i;
+		}
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  OCTAVE_QUIT;
+		  octave_idx_type iidx = rperm[i];
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    work[j] = 0.;
+
+		  // place the 1 in the identity position
+		  work[iidx] = 1.0;
+
+		  // iterate accross columns of input matrix
+		  for (octave_idx_type j = iidx+1; j < nr; j++) 
+		    {
+		      Complex v = 0.;
+		      octave_idx_type jidx = perm[j];
+		      // iterate to calculate sum
+		      for (octave_idx_type k = cidx(jidx); 
+			   k < cidx(jidx+1); k++)
+			{
+			  OCTAVE_QUIT;
+			  v -= work[ridx(k)] * data(k);
+			}
+
+		      // get A(m,m)
+		      Complex pivot;
+		      if (typ == MatrixType::Permuted_Upper)
+			pivot = data(cidx(jidx+1) - 1);
+		      else
+			pivot = data(cidx(jidx));
+		      if (pivot == 0.) 
+			{
+			  (*current_liboctave_error_handler) 
+			    ("division by zero");
+			  goto inverse_singular;
+			}
+
+		      work[j] = v / pivot;
+		    }
+
+		  // get A(m,m)
+		  octave_idx_type colUp;
+		  if (typ == MatrixType::Permuted_Upper)
+		    colUp = cidx(perm[iidx]+1) - 1;
+		  else
+		    colUp = cidx(perm[iidx]);		  
+
+  		  Complex pivot = data(colUp);
+		  if (pivot == 0.)
+		    {
+		      (*current_liboctave_error_handler) 
+			("division by zero");
+		      goto inverse_singular;
+		    }
+
+		  octave_idx_type new_cx = cx;
+		  for (octave_idx_type j = iidx; j < nr; j++)
+		    if (work[j] != 0.0)
+		      {
+			new_cx++;
+			if (pivot != 1.0)
+			  work[j] /= pivot;
+		      }
+
+		  if (cx < new_cx)
+		    {
+		      nz2 = (2*nz2 < new_cx ? new_cx : 2*nz2);
+		      retval.change_capacity (nz2);
+		    }
+
+		  retval.xcidx(i) = cx;
+		  for (octave_idx_type j = iidx; j < nr; j++)
+		    if (work[j] != 0.)
+		      {
+			retval.xridx(cx) = j;
+			retval.xdata(cx++) = work[j];
+		      }
+		}
+
+	      retval.xcidx(nr) = cx;
+	      retval.maybe_compress ();
+	    }
+
+	  if (calccond)
+	    {
+	      // Calculate the 1-norm of inverse matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = retval.cidx(j); 
+		       i < retval.cidx(j+1); i++)
+		    atmp += std::abs(retval.data(i));
+		  if (atmp > ainvnorm)
+		    ainvnorm = atmp;
+		}
+
+	      rcond = 1. / ainvnorm / anorm;     
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+
+ inverse_singular:
+  return SparseComplexMatrix();
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::inverse (MatrixType& mattype, octave_idx_type& info, 
+			      double& rcond, int, int calc_cond) const
+{
+  int typ = mattype.type (false);
+  SparseComplexMatrix ret;
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    ret = dinverse (mattype, info, rcond, true, calc_cond);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    ret = tinverse (mattype, info, rcond, true, calc_cond).transpose();
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    { 
+      MatrixType newtype = mattype.transpose();
+      ret = transpose().tinverse (newtype, info, rcond, true, calc_cond);
+    }
+  else
+    {
+      if (mattype.is_hermitian())
+	{
+	  MatrixType tmp_typ (MatrixType::Upper);
+	  SparseComplexCHOL fact (*this, info, false);
+	  rcond = fact.rcond();
+	  if (info == 0)
+	    {
+	      double rcond2;
+	      SparseMatrix Q = fact.Q();
+	      SparseComplexMatrix InvL = fact.L().transpose().
+		tinverse(tmp_typ, info, rcond2, true, false);
+	      ret = Q * InvL.hermitian() * InvL * Q.transpose();
+	    }
+	  else
+	    {
+	      // Matrix is either singular or not positive definite
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	}
+
+      if (!mattype.is_hermitian())
+	{
+	  octave_idx_type n = rows();
+	  ColumnVector Qinit(n);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    Qinit(i) = i;
+
+	  MatrixType tmp_typ (MatrixType::Upper);
+	  SparseComplexLU fact (*this, Qinit, Matrix (), false, false);
+	  rcond = fact.rcond();
+	  double rcond2;
+	  SparseComplexMatrix InvL = fact.L().transpose().
+	    tinverse(tmp_typ, info, rcond2, true, false);
+	  SparseComplexMatrix InvU = fact.U().
+	    tinverse(tmp_typ, info, rcond2, true, false).transpose();
+	  ret = fact.Pc().transpose() * InvU * InvL * fact.Pr();
+	}
+    }
+
+  return ret;
+}
+
+ComplexDET
+SparseComplexMatrix::determinant (void) const
+{
+  octave_idx_type info;
+  double rcond;
+  return determinant (info, rcond, 0);
+}
+
+ComplexDET
+SparseComplexMatrix::determinant (octave_idx_type& info) const
+{
+  double rcond;
+  return determinant (info, rcond, 0);
+}
+
+ComplexDET
+SparseComplexMatrix::determinant (octave_idx_type& err, double& rcond, int) const
+{
+  ComplexDET retval;
+#ifdef HAVE_UMFPACK
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    {
+      retval = ComplexDET (1.0);
+    }
+  else
+    {
+      err = 0;
+
+      // Setup the control parameters
+      Matrix Control (UMFPACK_CONTROL, 1);
+      double *control = Control.fortran_vec ();
+      UMFPACK_ZNAME (defaults) (control);
+
+      double tmp = octave_sparse_params::get_key ("spumoni");
+      if (!xisnan (tmp))
+	Control (UMFPACK_PRL) = tmp;
+
+      tmp = octave_sparse_params::get_key ("piv_tol");
+      if (!xisnan (tmp))
+	{
+	  Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+	  Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+	}
+
+      // Set whether we are allowed to modify Q or not
+      tmp = octave_sparse_params::get_key ("autoamd");
+      if (!xisnan (tmp))
+	Control (UMFPACK_FIXQ) = tmp;
+
+      // Turn-off UMFPACK scaling for LU 
+      Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
+
+      UMFPACK_ZNAME (report_control) (control);
+
+      const octave_idx_type *Ap = cidx ();
+      const octave_idx_type *Ai = ridx ();
+      const Complex *Ax = data ();
+
+      UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai, 
+				     reinterpret_cast<const double *> (Ax), 
+				     0, 1, control);
+
+      void *Symbolic;
+      Matrix Info (1, UMFPACK_INFO);
+      double *info = Info.fortran_vec ();
+      int status = UMFPACK_ZNAME (qsymbolic) 
+	(nr, nc, Ap, Ai, reinterpret_cast<const double *> (Ax), 0, 
+	 0, &Symbolic, control, info);
+
+      if (status < 0)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("SparseComplexMatrix::determinant symbolic factorization failed");
+
+	  UMFPACK_ZNAME (report_status) (control, status);
+	  UMFPACK_ZNAME (report_info) (control, info);
+
+	  UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+	}
+      else
+	{
+	  UMFPACK_ZNAME (report_symbolic) (Symbolic, control);
+
+	  void *Numeric;
+	  status
+	    = UMFPACK_ZNAME (numeric) (Ap, Ai,
+				       reinterpret_cast<const double *> (Ax),
+				       0, Symbolic, &Numeric, control, info) ;
+	  UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+
+	  rcond = Info (UMFPACK_RCOND);
+
+	  if (status < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("SparseComplexMatrix::determinant numeric factorization failed");
+
+	      UMFPACK_ZNAME (report_status) (control, status);
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    {
+	      UMFPACK_ZNAME (report_numeric) (Numeric, control);
+
+	      double c10[2], e10;
+
+              status = UMFPACK_ZNAME (get_determinant) (c10, 0, &e10,
+                                                        Numeric, info);
+
+	      if (status < 0)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("SparseComplexMatrix::determinant error calculating determinant");
+		  
+		  UMFPACK_ZNAME (report_status) (control, status);
+		  UMFPACK_ZNAME (report_info) (control, info);
+		}
+	      else
+		retval = ComplexDET (Complex (c10[0], c10[1]), e10, 10);
+		  
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	}
+    }
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::dsolve (MatrixType &mattype, const Matrix& b,
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler, bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  retval.resize (nc, b.cols(), Complex(0.,0.));
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+		for (octave_idx_type i = 0; i < nm; i++)
+		  retval(i,j) = b(i,j) / data (i);
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      for (octave_idx_type k = 0; k < nc; k++)
+		for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+		  retval(k,j) = b(ridx(i),j) / data (i);
+	    
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = std::abs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.0;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::dsolve (MatrixType &mattype, const SparseMatrix& b,
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler,
+			     bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      {
+		for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		  {
+		    if (b.ridx(i) >= nm)
+		      break;
+		    retval.xridx (ii) = b.ridx(i);
+		    retval.xdata (ii++) = b.data(i) / data (b.ridx (i));
+		  }
+		retval.xcidx(j+1) = ii;
+	      }
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      {
+		for (octave_idx_type l = 0; l < nc; l++)
+		  for (octave_idx_type i = cidx(l); i < cidx(l+1); i++)
+		    {
+		      bool found = false;
+		      octave_idx_type k;
+		      for (k = b.cidx(j); k < b.cidx(j+1); k++)
+			if (ridx(i) == b.ridx(k))
+			  {
+			    found = true;
+			    break;
+			  }
+		      if (found)
+			{
+			  retval.xridx (ii) = l;
+			  retval.xdata (ii++) = b.data(k) / data (i);
+			}
+		    }
+		retval.xcidx(j+1) = ii;
+	      }
+	    
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = std::abs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.0;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::dsolve (MatrixType &mattype, const ComplexMatrix& b,
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler,
+			     bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  retval.resize (nc, b.cols(), Complex(0.,0.));
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      for (octave_idx_type i = 0; i < nm; i++)
+		retval(i,j) = b(i,j) / data (i);
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      for (octave_idx_type k = 0; k < nc; k++)
+		for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+		  retval(k,j) = b(ridx(i),j) / data (i);
+	    
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  double tmp = std::abs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.0;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::dsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler,
+			     bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      {
+		for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		  {
+		    if (b.ridx(i) >= nm)
+		      break;
+		    retval.xridx (ii) = b.ridx(i);
+		    retval.xdata (ii++) = b.data(i) / data (b.ridx (i));
+		  }
+		retval.xcidx(j+1) = ii;
+	      }
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      {
+		for (octave_idx_type l = 0; l < nc; l++)
+		  for (octave_idx_type i = cidx(l); i < cidx(l+1); i++)
+		    {
+		      bool found = false;
+		      octave_idx_type k;
+		      for (k = b.cidx(j); k < b.cidx(j+1); k++)
+			if (ridx(i) == b.ridx(k))
+			  {
+			    found = true;
+			    break;
+			  }
+		      if (found)
+			{
+			  retval.xridx (ii) = l;
+			  retval.xdata (ii++) = b.data(k) / data (i);
+			}
+		    }
+		retval.xcidx(j+1) = ii;
+	      }
+	    
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = std::abs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.0;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::utsolve (MatrixType &mattype, const Matrix& b,
+			      octave_idx_type& err, double& rcond,
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      retval.resize (nc, b_nc);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(kidx+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval (perm[i], j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      retval.resize (nc, b_nc);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::utsolve (MatrixType &mattype, const SparseMatrix& b,
+			      octave_idx_type& err, double& rcond, 
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nc);
+	      for (octave_idx_type i = 0; i < nc; i++)
+		rperm[perm[i]] = i;
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(kidx+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[rperm[i]] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[rperm[i]];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::utsolve (MatrixType &mattype, const ComplexMatrix& b,
+			      octave_idx_type& err, double& rcond, 
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      retval.resize (nc, b_nc);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(kidx+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval (perm[i], j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      retval.resize (nc, b_nc);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::utsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+			      octave_idx_type& err, double& rcond, 
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nc);
+	      for (octave_idx_type i = 0; i < nc; i++)
+		rperm[perm[i]] = i;
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(kidx+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[rperm[i]] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[rperm[i]];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nr-1; k >= 0; k--)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::ltsolve (MatrixType &mattype, const Matrix& b, 
+			      octave_idx_type& err, double& rcond, 
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      retval.resize (nc, b_nc);
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[perm[i]] = b(i,j);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data (mini) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(mini);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      Complex tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      retval.resize (nc, b_nc, 0.);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k));
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::ltsolve (MatrixType &mattype, const SparseMatrix& b, 
+			      octave_idx_type& err, double& rcond, 
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[perm[b.ridx(i)]] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data (mini) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(mini);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      Complex tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k));
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::ltsolve (MatrixType &mattype, const ComplexMatrix& b,
+			      octave_idx_type& err, double& rcond,
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      retval.resize (nc, b_nc);
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[perm[i]] = b(i,j);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data (mini) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(mini);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      Complex tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      retval.resize (nc, b_nc, 0.);
+
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k));
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::ltsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+			      octave_idx_type& err, double& rcond, 
+			      solve_singularity_handler sing_handler,
+			      bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[perm[b.ridx(i)]] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data (mini) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(mini);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      Complex tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = work[k] / data(cidx(k));
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      Complex tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += std::abs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::trisolve (MatrixType &mattype, const Matrix& b,
+			       octave_idx_type& err, double& rcond,
+			       solve_singularity_handler sing_handler,
+			       bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = std::real(data(ii++));
+		  DL[j] = data(ii);
+		  ii += 2;
+		}
+	      D[nc-1] = std::real(data(ii));
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = std::real(data(i));
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		  }
+	    }
+	      
+	  octave_idx_type b_nc = b.cols();
+	  retval = ComplexMatrix (b);
+	  Complex *result = retval.fortran_vec ();
+
+	  F77_XFCN (zptsv, ZPTSV, (nr, b_nc, D, DL, result, 
+				   b.rows(), err));
+
+	  if (err != 0)
+	    {
+	      err = 0;
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Tridiagonal;
+	    }
+	  else 
+	    rcond = 1.;
+	}
+
+      if (typ == MatrixType::Tridiagonal)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (Complex, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  octave_idx_type b_nc = b.cols();
+	  retval = ComplexMatrix (b);
+	  Complex *result = retval.fortran_vec ();
+
+	  F77_XFCN (zgtsv, ZGTSV, (nr, b_nc, DL, D, DU, result, 
+				   b.rows(), err));
+
+	  if (err != 0)
+	    {
+	      rcond = 0.;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    rcond = 1.;
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	       (*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::trisolve (MatrixType &mattype, const SparseMatrix& b,
+			       octave_idx_type& err, double& rcond, 
+			       solve_singularity_handler sing_handler,
+			       bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      // Note can't treat symmetric case as there is no dpttrf function
+      if (typ == MatrixType::Tridiagonal ||
+	  typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, DU2, nr - 2);
+	  OCTAVE_LOCAL_BUFFER (Complex, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (Complex, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  F77_XFCN (zgttrf, ZGTTRF, (nr, DL, D, DU, DU2, pipvt, err));
+
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      char job = 'N';
+	      volatile octave_idx_type x_nz = b.nnz ();
+	      octave_idx_type b_nc = b.cols ();
+	      retval = SparseComplexMatrix (nr, b_nc, x_nz);
+	      retval.xcidx(0) = 0;
+	      volatile octave_idx_type ii = 0;
+	      rcond = 1.0;
+
+	      OCTAVE_LOCAL_BUFFER (Complex, work, nr);
+
+	      for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  F77_XFCN (zgttrs, ZGTTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, 1, DL, D, DU, DU2, pipvt, 
+			     work, b.rows (), err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  // Count non-zeros in work vector and adjust 
+		  // space in retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+	    }
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::trisolve (MatrixType &mattype, const ComplexMatrix& b,
+			       octave_idx_type& err, double& rcond, 
+			       solve_singularity_handler sing_handler,
+			       bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = std::real(data(ii++));
+		  DL[j] = data(ii);
+		  ii += 2;
+		}
+	      D[nc-1] = std::real(data(ii));
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = std::real (data(i));
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		  }
+	    }
+
+	  octave_idx_type b_nr = b.rows ();
+	  octave_idx_type b_nc = b.cols();
+	  rcond = 1.;
+
+	  retval = ComplexMatrix (b);
+	  Complex *result = retval.fortran_vec ();
+		  
+	  F77_XFCN (zptsv, ZPTSV, (nr, b_nc, D, DL, result, 
+				   b_nr, err));
+
+	  if (err != 0)
+	    {
+	      err = 0;
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Tridiagonal;
+	    }
+	}
+
+      if (typ == MatrixType::Tridiagonal)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (Complex, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  octave_idx_type b_nr = b.rows();
+	  octave_idx_type b_nc = b.cols();
+	  rcond = 1.;
+
+	  retval = ComplexMatrix (b);
+	  Complex *result = retval.fortran_vec ();
+	      
+	  F77_XFCN (zgtsv, ZGTSV, (nr, b_nc, DL, D, DU, result, 
+				   b_nr, err));
+
+	  if (err != 0)
+	    {
+	      rcond = 0.;
+	      err = -2;
+		      
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+	    }
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::trisolve (MatrixType &mattype, 
+			       const SparseComplexMatrix& b, 
+			       octave_idx_type& err, double& rcond, 
+			       solve_singularity_handler sing_handler,
+			       bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      // Note can't treat symmetric case as there is no dpttrf function
+      if (typ == MatrixType::Tridiagonal ||
+	  typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, DU2, nr - 2);
+	  OCTAVE_LOCAL_BUFFER (Complex, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (Complex, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  F77_XFCN (zgttrf, ZGTTRF, (nr, DL, D, DU, DU2, pipvt, err));
+
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+	    } 
+	  else 
+	    {	
+	      rcond = 1.;
+	      char job = 'N';
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
+
+	      // Take a first guess that the number of non-zero terms
+	      // will be as many as in b
+	      volatile octave_idx_type x_nz = b.nnz ();
+	      volatile octave_idx_type ii = 0;
+	      retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+	      retval.xcidx(0) = 0;
+	      for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		{
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    Bx[i] = b (i,j);
+
+		  F77_XFCN (zgttrs, ZGTTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, 1, DL, D, DU, DU2, pipvt, 
+			     Bx, b_nr, err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0)
+		    {
+		      (*current_liboctave_error_handler)
+			("SparseComplexMatrix::solve solve failed");
+
+		      err = -1;
+		      break;
+		    }
+
+		  // Count non-zeros in work vector and adjust 
+		  // space in retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (Bx[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (Bx[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = Bx[i];
+		      }
+
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+	    }
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::bsolve (MatrixType &mattype, const Matrix& b,
+			     octave_idx_type& err, double& rcond,
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (zpbtrf, ZPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      // Matrix is not positive definite!! Fall through to
+	      // unsymmetric banded solver.
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zpbcon, ZPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.0;
+
+	      if (err == 0)
+		{
+		  retval = ComplexMatrix (b);
+		  Complex *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  F77_XFCN (zpbtrs, ZPBTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, n_lower, b_nc, tmp_data,
+			     ldm, result, b.rows(), err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseMatrix::solve solve failed");
+		      err = -1;
+		    }
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (zgbtrf, ZGBTRF, (nr, nc, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  // Throw-away extra info LAPACK gives so as to not 
+	  // change output.
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zgbcon, ZGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  retval = ComplexMatrix (b);
+		  Complex *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  char job = 'N';
+		  F77_XFCN (zgbtrs, ZGBTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, n_lower, n_upper, b_nc, tmp_data,
+			     ldm, pipvt, result, b.rows(), err
+			     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::bsolve (MatrixType &mattype, const SparseMatrix& b,
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (zpbtrf, ZPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zpbcon, ZPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.0;
+
+	      if (err == 0)
+		{
+		  octave_idx_type b_nr = b.rows ();
+		  octave_idx_type b_nc = b.cols ();
+		  OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
+
+		  // Take a first guess that the number of non-zero terms
+		  // will be as many as in b
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  volatile octave_idx_type ii = 0;
+		  retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+		  retval.xcidx(0) = 0;
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			Bx[i] = b.elem (i, j);
+
+		      F77_XFCN (zpbtrs, ZPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bx, b_nr, err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler) 
+			    ("SparseComplexMatrix::solve solve failed");
+			  err = -1;
+			  break;
+			}
+
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			{
+			  Complex tmp = Bx[i];
+			  if (tmp != 0.0)
+			    {
+			      if (ii == x_nz)
+				{
+				  // Resize the sparse matrix
+				  octave_idx_type sz = x_nz * 
+				    (b_nc - j) / b_nc;
+				  sz = (sz > 10 ? sz : 10) + x_nz;
+				  retval.change_capacity (sz);
+				  x_nz = sz;
+				}
+			      retval.xdata(ii) = tmp;
+			      retval.xridx(ii++) = i;
+			    }
+			}
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (zgbtrf, ZGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		sing_handler (rcond);
+		mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zgbcon, ZGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  char job = 'N';
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  octave_idx_type b_nc = b.cols ();
+		  retval = SparseComplexMatrix (nr, b_nc, x_nz);
+		  retval.xcidx(0) = 0;
+		  volatile octave_idx_type ii = 0;
+
+		  OCTAVE_LOCAL_BUFFER (Complex, work, nr);
+
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < nr; i++)
+			work[i] = 0.;
+		      for (octave_idx_type i = b.cidx(j); 
+			   i < b.cidx(j+1); i++)
+			work[b.ridx(i)] = b.data(i);
+
+		      F77_XFCN (zgbtrs, ZGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, work, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      // Count non-zeros in work vector and adjust 
+		      // space in retval if needed
+		      octave_idx_type new_nnz = 0;
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (work[i] != 0.)
+			  new_nnz++;
+
+		      if (ii + new_nnz > x_nz)
+			{
+			  // Resize the sparse matrix
+			  octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+			  retval.change_capacity (sz);
+			  x_nz = sz;
+			}
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (work[i] != 0.)
+			  {
+			    retval.xridx(ii) = i;
+			    retval.xdata(ii++) = work[i];
+			  }
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::bsolve (MatrixType &mattype, const ComplexMatrix& b, 
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (zpbtrf, ZPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      // Matrix is not positive definite!! Fall through to
+	      // unsymmetric banded solver.
+	      rcond = 0.0;
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zpbcon, ZPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.0;
+
+	      if (err == 0)
+		{
+		  octave_idx_type b_nr = b.rows ();
+		  octave_idx_type b_nc = b.cols ();
+		  retval = ComplexMatrix (b);
+		  Complex *result = retval.fortran_vec ();
+
+		  F77_XFCN (zpbtrs, ZPBTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, n_lower, b_nc, tmp_data,
+			     ldm, result, b_nr, err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseComplexMatrix::solve solve failed");
+		      err = -1;
+		    }
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (zgbtrf, ZGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zgbcon, ZGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  char job = 'N';
+		  octave_idx_type b_nc = b.cols ();
+		  retval = ComplexMatrix (b);
+		  Complex *result = retval.fortran_vec ();
+
+		  F77_XFCN (zgbtrs, ZGBTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, n_lower, n_upper, b_nc, tmp_data,
+			     ldm, pipvt, result, b.rows (), err
+			     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::bsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+			     octave_idx_type& err, double& rcond, 
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (zpbtrf, ZPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      // Matrix is not positive definite!! Fall through to
+	      // unsymmetric banded solver.
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+
+	      rcond = 0.0;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zpbcon, ZPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.0;
+
+	      if (err == 0)
+		{
+		  octave_idx_type b_nr = b.rows ();
+		  octave_idx_type b_nc = b.cols ();
+		  OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
+
+		  // Take a first guess that the number of non-zero terms
+		  // will be as many as in b
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  volatile octave_idx_type ii = 0;
+		  retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+		  retval.xcidx(0) = 0;
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			Bx[i] = b (i,j);
+
+		      F77_XFCN (zpbtrs, ZPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bx, b_nr, err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler) 
+			    ("SparseMatrix::solve solve failed");
+			  err = -1;
+			  break;
+			}
+
+		      // Count non-zeros in work vector and adjust 
+		      // space in retval if needed
+		      octave_idx_type new_nnz = 0;
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0.)
+			  new_nnz++;
+
+		      if (ii + new_nnz > x_nz)
+			{
+			  // Resize the sparse matrix
+			  octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+			  retval.change_capacity (sz);
+			  x_nz = sz;
+			}
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0.)
+			  {
+			    retval.xridx(ii) = i;
+			    retval.xdata(ii++) = Bx[i];
+			  }
+
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  ComplexMatrix m_band (ldm, nc);
+	  Complex *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += std::abs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (zgbtrf, ZGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<Complex> z (2 * nr);
+		  Complex *pz = z.fortran_vec ();
+		  Array<double> iz (nr);
+		  double *piz = iz.fortran_vec ();
+
+		  F77_XFCN (zgbcon, ZGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  char job = 'N';
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  octave_idx_type b_nc = b.cols ();
+		  retval = SparseComplexMatrix (nr, b_nc, x_nz);
+		  retval.xcidx(0) = 0;
+		  volatile octave_idx_type ii = 0;
+
+		  OCTAVE_LOCAL_BUFFER (Complex, Bx, nr);
+
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < nr; i++)
+			Bx[i] = 0.;
+
+		      for (octave_idx_type i = b.cidx(j); 
+			   i < b.cidx(j+1); i++)
+			Bx[b.ridx(i)] = b.data(i);
+
+		      F77_XFCN (zgbtrs, ZGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, Bx, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      // Count non-zeros in work vector and adjust 
+		      // space in retval if needed
+		      octave_idx_type new_nnz = 0;
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0.)
+			  new_nnz++;
+
+		      if (ii + new_nnz > x_nz)
+			{
+			  // Resize the sparse matrix
+			  octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+			  retval.change_capacity (sz);
+			  x_nz = sz;
+			}
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0.)
+			  {
+			    retval.xridx(ii) = i;
+			    retval.xdata(ii++) = Bx[i]; 
+			  }
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+void *
+SparseComplexMatrix::factorize (octave_idx_type& err, double &rcond,
+				Matrix &Control, Matrix &Info,
+				solve_singularity_handler sing_handler,
+				bool calc_cond) const
+{
+  // The return values
+  void *Numeric = 0;
+  err = 0;
+
+#ifdef HAVE_UMFPACK
+  // Setup the control parameters
+  Control = Matrix (UMFPACK_CONTROL, 1);
+  double *control = Control.fortran_vec ();
+  UMFPACK_ZNAME (defaults) (control);
+
+  double tmp = octave_sparse_params::get_key ("spumoni");
+  if (!xisnan (tmp))
+    Control (UMFPACK_PRL) = tmp;
+  tmp = octave_sparse_params::get_key ("piv_tol");
+  if (!xisnan (tmp))
+    {
+      Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+      Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+    }
+
+  // Set whether we are allowed to modify Q or not
+  tmp = octave_sparse_params::get_key ("autoamd");
+  if (!xisnan (tmp))
+    Control (UMFPACK_FIXQ) = tmp;
+
+  UMFPACK_ZNAME (report_control) (control);
+
+  const octave_idx_type *Ap = cidx ();
+  const octave_idx_type *Ai = ridx ();
+  const Complex *Ax = data ();
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai,
+				 reinterpret_cast<const double *> (Ax),
+				 0, 1, control);
+
+  void *Symbolic;
+  Info = Matrix (1, UMFPACK_INFO);
+  double *info = Info.fortran_vec ();
+  int status = UMFPACK_ZNAME (qsymbolic) (nr, nc, Ap, Ai, 
+				     reinterpret_cast<const double *> (Ax), 
+				     0, 0, &Symbolic, control, info);
+
+  if (status < 0)
+    {
+      (*current_liboctave_error_handler) 
+	("SparseComplexMatrix::solve symbolic factorization failed");
+      err = -1;
+
+      UMFPACK_ZNAME (report_status) (control, status);
+      UMFPACK_ZNAME (report_info) (control, info);
+
+      UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+    }
+  else
+    {
+      UMFPACK_ZNAME (report_symbolic) (Symbolic, control);
+
+      status = UMFPACK_ZNAME (numeric) (Ap, Ai,
+				   reinterpret_cast<const double *> (Ax), 0, 
+				   Symbolic, &Numeric, control, info) ;
+      UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+
+      if (calc_cond)
+	rcond = Info (UMFPACK_RCOND);
+      else
+	rcond = 1.;
+      volatile double rcond_plus_one = rcond + 1.0;
+
+      if (status == UMFPACK_WARNING_singular_matrix || 
+	  rcond_plus_one == 1.0 || xisnan (rcond))
+	{
+	  UMFPACK_ZNAME (report_numeric) (Numeric, control);
+
+	  err = -2;
+
+	  if (sing_handler)
+	    sing_handler (rcond);
+	  else
+	    (*current_liboctave_error_handler)
+	      ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+	       rcond);
+
+	}
+      else if (status < 0)
+	  {
+	    (*current_liboctave_error_handler) 
+	      ("SparseComplexMatrix::solve numeric factorization failed");
+
+	    UMFPACK_ZNAME (report_status) (control, status);
+	    UMFPACK_ZNAME (report_info) (control, info);
+	      
+	    err = -1;
+	  }
+	else
+	  {
+	    UMFPACK_ZNAME (report_numeric) (Numeric, control);
+	  }
+    }
+
+  if (err != 0)
+    UMFPACK_ZNAME (free_numeric) (&Numeric);
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+
+  return Numeric;
+}
+
+ComplexMatrix
+SparseComplexMatrix::fsolve (MatrixType &mattype, const Matrix& b,
+			     octave_idx_type& err, double& rcond,
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_COMPLEX;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_dense Bstore;
+	  cholmod_dense *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->d = B->nrow;
+	  B->nzmax = B->nrow * B->ncol;
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->xtype = CHOLMOD_REAL;
+	  if (nc < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    // We won't alter it, honest :-)
+	    B->x = const_cast<double *>(b.fortran_vec());
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_dense *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(solve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval.resize (b.rows (), b.cols());
+	      for (octave_idx_type j = 0; j < b.cols(); j++)
+		{
+		  octave_idx_type jr = j * b.rows();
+		  for (octave_idx_type i = 0; i < b.rows(); i++)
+		    retval.xelem(i,j) = static_cast<Complex *>(X->x)[jr + i];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_dense) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info, 
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const Complex *Ax = data ();
+#ifdef UMFPACK_SEPARATE_SPLIT
+	      const double *Bx = b.fortran_vec ();
+	      OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+	      for (octave_idx_type i = 0; i < b_nr; i++)
+		Bz[i] = 0.;
+#else
+	      OCTAVE_LOCAL_BUFFER (Complex, Bz, b_nr);
+#endif
+	      retval.resize (b_nr, b_nc);
+	      Complex *Xx = retval.fortran_vec ();
+
+	      for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr)
+		{
+#ifdef UMFPACK_SEPARATE_SPLIT
+		  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
+					     Ai,
+					     reinterpret_cast<const double *> (Ax), 
+					     0,
+					     reinterpret_cast<double *> (&Xx[iidx]), 
+					     0,
+					     &Bx[iidx], Bz, Numeric, 
+					     control, info);
+#else
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    Bz[i] = b.elem (i, j);
+
+		  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
+					     Ai,
+					     reinterpret_cast<const double *> (Ax), 
+					     0,
+					     reinterpret_cast<double *> (&Xx[iidx]), 
+					     0,
+					     reinterpret_cast<const double *> (Bz),
+					     0, Numeric, 
+					     control, info);
+#endif
+
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseComplexMatrix::solve solve failed");
+
+		      UMFPACK_ZNAME (report_status) (control, status);
+		      
+		      err = -1;
+
+		      break;
+		    }
+		}
+
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::fsolve (MatrixType &mattype, const SparseMatrix& b, 
+			     octave_idx_type& err, double& rcond,
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_COMPLEX;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_sparse Bstore;
+	  cholmod_sparse *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->p = b.cidx();
+	  B->i = b.ridx();
+	  B->nzmax = b.nnz();
+	  B->packed = true;
+	  B->sorted = true;
+	  B->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  B->itype = CHOLMOD_LONG;
+#else
+	  B->itype = CHOLMOD_INT;
+#endif
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->stype = 0;
+	  B->xtype = CHOLMOD_REAL;
+
+	  if (b.rows() < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    B->x = b.data();
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_sparse *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval = SparseComplexMatrix 
+		(static_cast<octave_idx_type>(X->nrow), 
+		 static_cast<octave_idx_type>(X->ncol),
+		 static_cast<octave_idx_type>(X->nzmax));
+	      for (octave_idx_type j = 0; 
+		   j <= static_cast<octave_idx_type>(X->ncol); j++)
+		retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j];
+	      for (octave_idx_type j = 0; 
+		   j < static_cast<octave_idx_type>(X->nzmax); j++)
+		{
+		  retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j];
+		  retval.xdata(j) = static_cast<Complex *>(X->x)[j];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_sparse) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info, 
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const Complex *Ax = data ();
+
+#ifdef UMFPACK_SEPARATE_SPLIT
+	      OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+	      for (octave_idx_type i = 0; i < b_nr; i++)
+		Bz[i] = 0.;
+#else
+	      OCTAVE_LOCAL_BUFFER (Complex, Bz, b_nr);
+#endif
+
+	      // Take a first guess that the number of non-zero terms
+	      // will be as many as in b
+	      octave_idx_type x_nz = b.nnz ();
+	      octave_idx_type ii = 0;
+	      retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+	      OCTAVE_LOCAL_BUFFER (Complex, Xx, b_nr);
+	      
+	      retval.xcidx(0) = 0;
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+
+#ifdef UMFPACK_SEPARATE_SPLIT
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    Bx[i] = b.elem (i, j);
+
+		  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
+					     Ai,
+					     reinterpret_cast<const double *> (Ax),
+					     0,
+					     reinterpret_cast<double *> (Xx),
+					     0, 
+					     Bx, Bz, Numeric, control, 
+					     info);
+#else
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    Bz[i] = b.elem (i, j);
+
+		  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, Ai, 
+					     reinterpret_cast<const double *> (Ax),
+					     0,
+					     reinterpret_cast<double *> (Xx),
+					     0,
+					     reinterpret_cast<double *> (Bz),
+					     0,
+					     Numeric, control, 
+					     info);
+#endif
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseComplexMatrix::solve solve failed");
+
+		      UMFPACK_ZNAME (report_status) (control, status);
+		      
+		      err = -1;
+
+		      break;
+		    }
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      Complex tmp = Xx[i];
+		      if (tmp != 0.0)
+			{
+			  if (ii == x_nz)
+			    {
+			      // Resize the sparse matrix
+			      octave_idx_type sz = x_nz * (b_nc - j) / b_nc;
+			      sz = (sz > 10 ? sz : 10) + x_nz;
+			      retval.change_capacity (sz);
+			      x_nz = sz;
+			    }
+			  retval.xdata(ii) = tmp;
+			  retval.xridx(ii++) = i;
+			}
+		    }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::fsolve (MatrixType &mattype, const ComplexMatrix& b, 
+			     octave_idx_type& err, double& rcond,
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_COMPLEX;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_dense Bstore;
+	  cholmod_dense *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->d = B->nrow;
+	  B->nzmax = B->nrow * B->ncol;
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->xtype = CHOLMOD_COMPLEX;
+	  if (nc < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    // We won't alter it, honest :-)
+	    B->x = const_cast<Complex *>(b.fortran_vec());
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_dense *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(solve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval.resize (b.rows (), b.cols());
+	      for (octave_idx_type j = 0; j < b.cols(); j++)
+		{
+		  octave_idx_type jr = j * b.rows();
+		  for (octave_idx_type i = 0; i < b.rows(); i++)
+		    retval.xelem(i,j) = static_cast<Complex *>(X->x)[jr + i];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_dense) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info,
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const Complex *Ax = data ();
+	      const Complex *Bx = b.fortran_vec ();
+
+	      retval.resize (b_nr, b_nc);
+	      Complex *Xx = retval.fortran_vec ();
+	      
+	      for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr)
+		{
+		  status = 
+		    UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, Ai, 
+				      reinterpret_cast<const double *> (Ax), 
+				      0,
+				      reinterpret_cast<double *> (&Xx[iidx]), 
+				      0,
+				      reinterpret_cast<const double *> (&Bx[iidx]), 
+				      0, Numeric, control, info);
+		  
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseComplexMatrix::solve solve failed");
+
+		      UMFPACK_ZNAME (report_status) (control, status);
+		      
+		      err = -1;
+
+		      break;
+		    }
+		}
+
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::fsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+			     octave_idx_type& err, double& rcond,
+			     solve_singularity_handler sing_handler,
+			     bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_COMPLEX;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_sparse Bstore;
+	  cholmod_sparse *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->p = b.cidx();
+	  B->i = b.ridx();
+	  B->nzmax = b.nnz();
+	  B->packed = true;
+	  B->sorted = true;
+	  B->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  B->itype = CHOLMOD_LONG;
+#else
+	  B->itype = CHOLMOD_INT;
+#endif
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->stype = 0;
+	  B->xtype = CHOLMOD_COMPLEX;
+
+	  if (b.rows() < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    B->x = b.data();
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_sparse *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval = SparseComplexMatrix 
+		(static_cast<octave_idx_type>(X->nrow), 
+		 static_cast<octave_idx_type>(X->ncol),
+		 static_cast<octave_idx_type>(X->nzmax));
+	      for (octave_idx_type j = 0; 
+		   j <= static_cast<octave_idx_type>(X->ncol); j++)
+		retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j];
+	      for (octave_idx_type j = 0; 
+		   j < static_cast<octave_idx_type>(X->nzmax); j++)
+		{
+		  retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j];
+		  retval.xdata(j) = static_cast<Complex *>(X->x)[j];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_sparse) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info,
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const Complex *Ax = data ();
+
+	      OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
+
+	      // Take a first guess that the number of non-zero terms
+	      // will be as many as in b
+	      octave_idx_type x_nz = b.nnz ();
+	      octave_idx_type ii = 0;
+	      retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+	      OCTAVE_LOCAL_BUFFER (Complex, Xx, b_nr);
+	      
+	      retval.xcidx(0) = 0;
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    Bx[i] = b (i,j);
+
+		  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
+					     Ai,
+					     reinterpret_cast<const double *> (Ax),
+					     0,
+					     reinterpret_cast<double *> (Xx),
+					     0,
+					     reinterpret_cast<double *> (Bx),
+					     0, Numeric, control, info);
+		  
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseComplexMatrix::solve solve failed");
+
+		      UMFPACK_ZNAME (report_status) (control, status);
+		  
+		      err = -1;
+
+		      break;
+		    }
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      Complex tmp = Xx[i];
+		      if (tmp != 0.0)
+			{
+			  if (ii == x_nz)
+			    {
+			      // Resize the sparse matrix
+			      octave_idx_type sz = x_nz * (b_nc - j) / b_nc;
+			      sz = (sz > 10 ? sz : 10) + x_nz;
+			      retval.change_capacity (sz);
+			      x_nz = sz;
+			    }
+			  retval.xdata(ii) = tmp;
+			  retval.xridx(ii++) = i;
+			}
+		    }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      rcond = Info (UMFPACK_RCOND);
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (status == UMFPACK_WARNING_singular_matrix || 
+		  rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    sing_handler (rcond);
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+
+		}
+
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const Matrix& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const Matrix& b,
+			    octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const Matrix& b,
+			    octave_idx_type& err, double& rcond, 
+			    solve_singularity_handler sing_handler,
+			    bool singular_fallback) const
+{
+  ComplexMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return ComplexMatrix ();
+    }
+
+  if (singular_fallback && mattype.type(false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<ComplexMatrix, SparseComplexMatrix,
+	Matrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseMatrix& b, 
+			    octave_idx_type& err, double& rcond,
+			    solve_singularity_handler sing_handler,
+			    bool singular_fallback) const
+{
+  SparseComplexMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return SparseComplexMatrix ();
+    }
+
+  if (singular_fallback && mattype.type(false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<SparseComplexMatrix, SparseComplexMatrix,
+	SparseMatrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+			    octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+			    octave_idx_type& err, double& rcond, 
+			    solve_singularity_handler sing_handler,
+			    bool singular_fallback) const
+{
+  ComplexMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return ComplexMatrix ();
+    }
+
+  if (singular_fallback && mattype.type(false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<ComplexMatrix, SparseComplexMatrix,
+	ComplexMatrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, 
+			    const SparseComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b,
+			    octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, 
+			    octave_idx_type& err, double& rcond,
+			    solve_singularity_handler sing_handler,
+			    bool singular_fallback) const
+{
+  SparseComplexMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return SparseComplexMatrix ();
+    }
+
+  if (singular_fallback && mattype.type(false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<SparseComplexMatrix, SparseComplexMatrix,
+	SparseComplexMatrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ColumnVector& b) const
+{
+  octave_idx_type info; double rcond;
+  return solve (mattype, b, info, rcond);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ColumnVector& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ColumnVector& b, 
+			    octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ColumnVector& b, 
+			    octave_idx_type& info, double& rcond,
+			    solve_singularity_handler sing_handler) const
+{
+  Matrix tmp (b);
+  return solve (mattype, tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, 
+			    const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b,
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b,
+			    octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b,
+			    octave_idx_type& info, double& rcond,
+			    solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (b);
+  return solve (mattype, tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const Matrix& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const Matrix& b, octave_idx_type& info, 
+		     double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const Matrix& b, octave_idx_type& err, 
+			    double& rcond, 
+			    solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseMatrix& b, 
+		     octave_idx_type& err, double& rcond,
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const ComplexMatrix& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const ComplexMatrix& b, 
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseComplexMatrix::solve (const ComplexMatrix& b, 
+		     octave_idx_type& err, double& rcond, 
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseComplexMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseComplexMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::solve (const SparseComplexMatrix& b, 
+		     octave_idx_type& err, double& rcond,
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ColumnVector& b) const
+{
+  octave_idx_type info; double rcond;
+  return solve (b, info, rcond);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, 
+			    double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond,
+			    solve_singularity_handler sing_handler) const
+{
+  Matrix tmp (b);
+  return solve (tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, 
+		     double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, 
+			    double& rcond,
+			    solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (b);
+  return solve (tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+// unary operations
+SparseBoolMatrix
+SparseComplexMatrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz1 = nnz ();
+  octave_idx_type nz2 = nr*nc - nz1;
+   
+  SparseBoolMatrix r (nr, nc, nz2);
+   
+  octave_idx_type ii = 0;
+  octave_idx_type jj = 0;
+  r.cidx (0) = 0;
+  for (octave_idx_type i = 0; i < nc; i++)
+    {
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (jj < cidx(i+1) && ridx(jj) == j)
+	    jj++;
+	  else
+	    {
+	      r.data(ii) = true;
+	      r.ridx(ii++) = j;
+	    }
+	}
+      r.cidx (i+1) = ii;
+    }
+
+  return r;
+}
+
+SparseComplexMatrix 
+SparseComplexMatrix::squeeze (void) const
+{ 
+  return MSparse<Complex>::squeeze (); 
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::index (idx_vector& i, int resize_ok) const 
+{ 
+  return MSparse<Complex>::index (i, resize_ok); 
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::index (idx_vector& i, idx_vector& j, int resize_ok) const 
+{ 
+  return MSparse<Complex>::index (i, j, resize_ok); 
+}
+  
+SparseComplexMatrix
+SparseComplexMatrix::index (Array<idx_vector>& ra_idx, int resize_ok) const 
+{ 
+  return MSparse<Complex>::index (ra_idx, resize_ok); 
+}
+SparseComplexMatrix
+SparseComplexMatrix::reshape (const dim_vector& new_dims) const
+{
+  return MSparse<Complex>::reshape (new_dims);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::permute (const Array<octave_idx_type>& vec, bool inv) const
+{
+  return MSparse<Complex>::permute (vec, inv);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::ipermute (const Array<octave_idx_type>& vec) const
+{
+  return MSparse<Complex>::ipermute (vec);
+}
+
+// other operations
+
+bool
+SparseComplexMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = data (i);
+      if (xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+SparseComplexMatrix::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = data (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+// Return true if no elements have imaginary components.
+
+bool
+SparseComplexMatrix::all_elements_are_real (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double ip = std::imag (data (i));
+      
+      if (ip != 0.0 || lo_ieee_signbit (ip))
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of CM has a non-integer real or
+// imaginary part.  Also extract the largest and smallest (real or
+// imaginary) values and return them in MAX_VAL and MIN_VAL. 
+
+bool
+SparseComplexMatrix::all_integers (double& max_val, double& min_val) const
+{
+  octave_idx_type nel = nnz ();
+
+  if (nel == 0)
+    return false;
+
+  max_val = std::real(data (0));
+  min_val = std::real(data (0));
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+	Complex val = data (i);
+
+	double r_val = std::real (val);
+	double i_val = std::imag (val);
+
+	if (r_val > max_val)
+	  max_val = r_val;
+
+	if (i_val > max_val)
+	  max_val = i_val;
+
+	if (r_val < min_val)
+	  min_val = r_val;
+
+	if (i_val < min_val)
+	  min_val = i_val;
+
+	if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
+	  return false;
+    }
+
+  return true;
+}
+
+bool
+SparseComplexMatrix::too_large_for_float (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+	Complex val = data (i);
+
+	double r_val = std::real (val);
+	double i_val = std::imag (val);
+
+	if (r_val > FLT_MAX
+	    || i_val > FLT_MAX
+	    || r_val < FLT_MIN
+	    || i_val < FLT_MIN)
+	  return true;
+    }
+
+  return false;
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+SparseBoolMatrix
+SparseComplexMatrix::all (int dim) const
+{
+  SPARSE_ALL_OP (dim);
+}
+
+SparseBoolMatrix
+SparseComplexMatrix::any (int dim) const
+{
+  SPARSE_ANY_OP (dim);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::cumprod (int dim) const
+{
+  SPARSE_CUMPROD (SparseComplexMatrix, Complex, cumprod);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::cumsum (int dim) const
+{
+  SPARSE_CUMSUM (SparseComplexMatrix, Complex, cumsum);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::prod (int dim) const
+{
+  if ((rows() == 1 && dim == -1) || dim == 1)
+    return transpose (). prod (0). transpose();
+  else
+    {
+      SPARSE_REDUCTION_OP (SparseComplexMatrix, Complex, *=, 
+			   (cidx(j+1) - cidx(j) < nr ? 0.0 : 1.0), 1.0);
+    }
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::sum (int dim) const
+{
+  SPARSE_REDUCTION_OP (SparseComplexMatrix, Complex, +=, 0.0, 0.0);
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::sumsq (int dim) const
+{
+#define ROW_EXPR \
+  Complex d = data (i); \
+  tmp [ridx(i)] += d * conj (d)
+
+#define COL_EXPR \
+  Complex d = data (i); \
+  tmp [j] += d * conj (d)
+
+  SPARSE_BASE_REDUCTION_OP (SparseComplexMatrix, Complex, ROW_EXPR, 
+			    COL_EXPR, 0.0, 0.0);
+
+#undef ROW_EXPR
+#undef COL_EXPR
+}
+
+SparseMatrix SparseComplexMatrix::abs (void) const
+{
+  octave_idx_type nz = nnz ();
+  octave_idx_type nc = cols ();
+
+  SparseMatrix retval (rows(), nc, nz);
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    retval.cidx (i) = cidx (i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      retval.data (i) = std::abs (data (i));
+      retval.ridx (i) = ridx (i);
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::diag (octave_idx_type k) const
+{
+  return MSparse<Complex>::diag (k);
+}
+
+SparseMatrix
+SparseComplexMatrix::map (dmapper fcn) const
+{
+  return MSparse<Complex>::map<double> (func_ptr (fcn));
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::map (cmapper fcn) const
+{
+  return MSparse<Complex>::map<Complex> (func_ptr (fcn));
+}
+
+SparseBoolMatrix
+SparseComplexMatrix::map (bmapper fcn) const
+{
+  return MSparse<Complex>::map<bool> (func_ptr (fcn));
+}
+
+std::ostream&
+operator << (std::ostream& os, const SparseComplexMatrix& a)
+{
+  octave_idx_type nc = a.cols ();
+
+   // add one to the printed indices to go from
+   //  zero-based to one-based arrays
+   for (octave_idx_type j = 0; j < nc; j++)  {
+      OCTAVE_QUIT;
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++) {
+	os << a.ridx(i) + 1 << " "  << j + 1 << " ";
+	octave_write_complex (os, a.data(i));
+	os << "\n";
+      }
+   }
+
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, SparseComplexMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type nz = a.nzmax ();
+
+  if (nr > 0 && nc > 0)
+    {
+      octave_idx_type itmp, jtmp, jold = 0;
+      Complex tmp;
+      octave_idx_type ii = 0;
+       
+      a.cidx (0) = 0;
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  is >> itmp;
+	  itmp--;
+	  is >> jtmp;
+	  jtmp--;
+	  tmp = octave_read_complex (is);
+
+	  if (is)
+	    {
+	      if (jold != jtmp)
+		{
+		  for (octave_idx_type j = jold; j < jtmp; j++)
+		    a.cidx(j+1) = ii;
+		  
+		  jold = jtmp;
+		}
+	      a.data (ii) = tmp;
+	      a.ridx (ii++) = itmp;
+	    }
+	  else
+	    goto done;
+	}
+
+      for (octave_idx_type j = jold; j < nc; j++)
+	a.cidx(j+1) = ii;
+    }
+
+ done:
+
+  return is;
+}
+
+SparseComplexMatrix
+operator * (const SparseComplexMatrix& m, const SparseMatrix& a)
+{
+  SPARSE_SPARSE_MUL (SparseComplexMatrix, Complex, double);
+}
+
+SparseComplexMatrix
+operator * (const SparseMatrix& m, const SparseComplexMatrix& a)
+{
+  SPARSE_SPARSE_MUL (SparseComplexMatrix, Complex, Complex);
+}
+
+SparseComplexMatrix
+operator * (const SparseComplexMatrix& m, const SparseComplexMatrix& a)
+{
+  SPARSE_SPARSE_MUL (SparseComplexMatrix, Complex, Complex);
+}
+
+ComplexMatrix
+operator * (const ComplexMatrix& m, const SparseMatrix& a)
+{
+  FULL_SPARSE_MUL (ComplexMatrix, double, Complex (0.,0.));
+}
+
+ComplexMatrix
+operator * (const Matrix& m, const SparseComplexMatrix& a)
+{
+  FULL_SPARSE_MUL (ComplexMatrix, Complex, Complex (0.,0.));
+}
+
+ComplexMatrix
+operator * (const ComplexMatrix& m, const SparseComplexMatrix& a)
+{
+  FULL_SPARSE_MUL (ComplexMatrix, Complex, Complex (0.,0.));
+}
+
+ComplexMatrix
+mul_trans (const ComplexMatrix& m, const SparseComplexMatrix& a)
+{
+  FULL_SPARSE_MUL_TRANS (ComplexMatrix, Complex, Complex (0.,0.), );
+}
+
+ComplexMatrix
+mul_herm (const ComplexMatrix& m, const SparseComplexMatrix& a)
+{
+  FULL_SPARSE_MUL_TRANS (ComplexMatrix, Complex, Complex (0.,0.), conj);
+}
+
+ComplexMatrix
+operator * (const SparseComplexMatrix& m, const Matrix& a)
+{
+  SPARSE_FULL_MUL (ComplexMatrix, double, Complex (0.,0.));
+}
+
+ComplexMatrix
+operator * (const SparseMatrix& m, const ComplexMatrix& a)
+{
+  SPARSE_FULL_MUL (ComplexMatrix, Complex, Complex (0.,0.));
+}
+
+ComplexMatrix
+operator * (const SparseComplexMatrix& m, const ComplexMatrix& a)
+{
+  SPARSE_FULL_MUL (ComplexMatrix, Complex, Complex (0.,0.));
+}
+
+ComplexMatrix
+trans_mul (const SparseComplexMatrix& m, const ComplexMatrix& a)
+{
+  SPARSE_FULL_TRANS_MUL (ComplexMatrix, Complex, Complex (0.,0.), );
+}
+
+ComplexMatrix
+herm_mul (const SparseComplexMatrix& m, const ComplexMatrix& a)
+{
+  SPARSE_FULL_TRANS_MUL (ComplexMatrix, Complex, Complex (0.,0.), conj);
+}
+
+// diag * sparse and sparse * diag
+SparseComplexMatrix
+operator * (const DiagMatrix& d, const SparseComplexMatrix& a)
+{
+  return do_mul_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator * (const SparseComplexMatrix& a, const DiagMatrix& d)
+{
+  return do_mul_sm_dm<SparseComplexMatrix> (a, d);
+}
+
+SparseComplexMatrix
+operator * (const ComplexDiagMatrix& d, const SparseMatrix& a)
+{
+  return do_mul_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator * (const SparseMatrix& a, const ComplexDiagMatrix& d)
+{
+  return do_mul_sm_dm<SparseComplexMatrix> (a, d);
+}
+
+SparseComplexMatrix
+operator * (const ComplexDiagMatrix& d, const SparseComplexMatrix& a)
+{
+  return do_mul_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator * (const SparseComplexMatrix& a, const ComplexDiagMatrix& d)
+{
+  return do_mul_sm_dm<SparseComplexMatrix> (a, d);
+}
+
+SparseComplexMatrix
+operator + (const ComplexDiagMatrix& d, const SparseMatrix& a)
+{
+  return do_add_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator + (const DiagMatrix& d, const SparseComplexMatrix& a)
+{
+  return do_add_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator + (const ComplexDiagMatrix& d, const SparseComplexMatrix& a)
+{
+  return do_add_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator + (const SparseMatrix& a, const ComplexDiagMatrix& d)
+{
+  return do_add_sm_dm<SparseComplexMatrix> (a, d);
+}
+SparseComplexMatrix
+operator + (const SparseComplexMatrix& a, const DiagMatrix& d)
+{
+  return do_add_sm_dm<SparseComplexMatrix> (a, d);
+}
+SparseComplexMatrix
+operator + (const SparseComplexMatrix&a, const ComplexDiagMatrix& d)
+{
+  return do_add_sm_dm<SparseComplexMatrix> (a, d);
+}
+
+SparseComplexMatrix
+operator - (const ComplexDiagMatrix& d, const SparseMatrix& a)
+{
+  return do_sub_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator - (const DiagMatrix& d, const SparseComplexMatrix& a)
+{
+  return do_sub_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator - (const ComplexDiagMatrix& d, const SparseComplexMatrix& a)
+{
+  return do_sub_dm_sm<SparseComplexMatrix> (d, a);
+}
+SparseComplexMatrix
+operator - (const SparseMatrix& a, const ComplexDiagMatrix& d)
+{
+  return do_sub_sm_dm<SparseComplexMatrix> (a, d);
+}
+SparseComplexMatrix
+operator - (const SparseComplexMatrix& a, const DiagMatrix& d)
+{
+  return do_sub_sm_dm<SparseComplexMatrix> (a, d);
+}
+SparseComplexMatrix
+operator - (const SparseComplexMatrix&a, const ComplexDiagMatrix& d)
+{
+  return do_sub_sm_dm<SparseComplexMatrix> (a, d);
+}
+
+// perm * sparse and sparse * perm
+
+SparseComplexMatrix
+operator * (const PermMatrix& p, const SparseComplexMatrix& a)
+{
+  return octinternal_do_mul_pm_sm (p, a);
+}
+
+SparseComplexMatrix
+operator * (const SparseComplexMatrix& a, const PermMatrix& p)
+{
+  return octinternal_do_mul_sm_pm (a, p);
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nr == 0 || nc == 0) \
+    return T (nr, nc);
+
+SparseComplexMatrix
+min (const Complex& c, const SparseComplexMatrix& m)
+{
+  SparseComplexMatrix result;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (SparseComplexMatrix);
+
+  if (abs(c) == 0.)
+    return SparseComplexMatrix (nr, nc);
+  else
+    {
+      result = SparseComplexMatrix (m);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	  result.data(i) = xmin(c, m.data(i));
+    }
+  
+  return result;
+}
+
+SparseComplexMatrix
+min (const SparseComplexMatrix& m, const Complex& c)
+{
+  return min (c, m);
+}
+
+SparseComplexMatrix
+min (const SparseComplexMatrix& a, const SparseComplexMatrix& b)
+{
+  SparseComplexMatrix r;
+
+  if ((a.rows() == b.rows()) && (a.cols() == b.cols())) 
+    {
+      octave_idx_type a_nr = a.rows ();
+      octave_idx_type a_nc = a.cols ();
+
+      octave_idx_type b_nr = b.rows ();
+      octave_idx_type b_nc = b.cols ();
+
+      if (a_nr == 0 || b_nc == 0 || a.nnz () == 0 || b.nnz () == 0)
+	return SparseComplexMatrix (a_nr, a_nc);
+
+      if (a_nr != b_nr || a_nc != b_nc)
+	gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+      else
+	{
+	  r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+       
+	  octave_idx_type jx = 0;
+	  r.cidx (0) = 0;
+	  for (octave_idx_type i = 0 ; i < a_nc ; i++)
+	    {
+	      octave_idx_type  ja = a.cidx(i);
+	      octave_idx_type  ja_max = a.cidx(i+1);
+	      bool ja_lt_max= ja < ja_max;
+           
+	      octave_idx_type  jb = b.cidx(i);
+	      octave_idx_type  jb_max = b.cidx(i+1);
+	      bool jb_lt_max = jb < jb_max;
+           
+	      while (ja_lt_max || jb_lt_max )
+		{
+		  OCTAVE_QUIT;
+		  if ((! jb_lt_max) ||
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb))))
+		    {
+		      Complex tmp = xmin (a.data(ja), 0.);
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = a.ridx(ja);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		    }
+		  else if (( !ja_lt_max ) ||
+			   (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) )
+		    {
+		      Complex tmp = xmin (0., b.data(jb));
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = b.ridx(jb);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		  else
+		    {
+		      Complex tmp = xmin (a.data(ja), b.data(jb));
+		      if (tmp != 0.)
+			{
+                          r.data(jx) = tmp;
+                          r.ridx(jx) = a.ridx(ja);
+                          jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		}
+	      r.cidx(i+1) = jx;
+	    }
+	  
+	  r.maybe_compress ();
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("matrix size mismatch");
+
+  return r;
+}
+
+SparseComplexMatrix
+max (const Complex& c, const SparseComplexMatrix& m)
+{
+  SparseComplexMatrix result;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (SparseComplexMatrix);
+
+  // Count the number of non-zero elements
+  if (xmax(c, 0.) != 0.)
+    {
+      result = SparseComplexMatrix (nr, nc, c);
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	  result.xdata(m.ridx(i) + j * nr) = xmax (c, m.data(i));
+    }
+  else
+    result = SparseComplexMatrix (m);
+
+  return result;
+}
+
+SparseComplexMatrix
+max (const SparseComplexMatrix& m, const Complex& c)
+{
+  return max (c, m);
+}
+
+SparseComplexMatrix
+max (const SparseComplexMatrix& a, const SparseComplexMatrix& b)
+{
+  SparseComplexMatrix r;
+
+  if ((a.rows() == b.rows()) && (a.cols() == b.cols())) 
+    {
+      octave_idx_type a_nr = a.rows ();
+      octave_idx_type a_nc = a.cols ();
+
+      octave_idx_type b_nr = b.rows ();
+      octave_idx_type b_nc = b.cols ();
+
+      if (a_nr == 0 || b_nc == 0)
+	return SparseComplexMatrix (a_nr, a_nc);
+      if (a.nnz () == 0)
+	return SparseComplexMatrix (b);
+      if (b.nnz () == 0)
+	return SparseComplexMatrix (a);
+
+      if (a_nr != b_nr || a_nc != b_nc)
+	gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+      else
+	{
+	  r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+       
+	  octave_idx_type jx = 0;
+	  r.cidx (0) = 0;
+	  for (octave_idx_type i = 0 ; i < a_nc ; i++)
+	    {
+	      octave_idx_type  ja = a.cidx(i);
+	      octave_idx_type  ja_max = a.cidx(i+1);
+	      bool ja_lt_max= ja < ja_max;
+           
+	      octave_idx_type  jb = b.cidx(i);
+	      octave_idx_type  jb_max = b.cidx(i+1);
+	      bool jb_lt_max = jb < jb_max;
+           
+	      while (ja_lt_max || jb_lt_max )
+		{
+		  OCTAVE_QUIT;
+		  if ((! jb_lt_max) ||
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb))))
+		    {
+		      Complex tmp = xmax (a.data(ja), 0.);
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = a.ridx(ja);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		    }
+		  else if (( !ja_lt_max ) ||
+			   (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) )
+		    {
+		      Complex tmp = xmax (0., b.data(jb));
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = b.ridx(jb);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		  else
+		    {
+		      Complex tmp = xmax (a.data(ja), b.data(jb));
+		      if (tmp != 0.)
+			{
+                          r.data(jx) = tmp;
+                          r.ridx(jx) = a.ridx(ja);
+                          jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		}
+	      r.cidx(i+1) = jx;
+	    }
+	  
+	  r.maybe_compress ();
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("matrix size mismatch");
+
+  return r;
+}
+
+SPARSE_SMS_CMP_OPS (SparseComplexMatrix, 0.0, real, Complex, 
+		   0.0, real)
+SPARSE_SMS_BOOL_OPS (SparseComplexMatrix, Complex, 0.0)
+
+SPARSE_SSM_CMP_OPS (Complex, 0.0, real, SparseComplexMatrix, 
+		   0.0, real)
+SPARSE_SSM_BOOL_OPS (Complex, SparseComplexMatrix, 0.0)
+
+SPARSE_SMSM_CMP_OPS (SparseComplexMatrix, 0.0, real, SparseComplexMatrix, 
+		     0.0, real)
+SPARSE_SMSM_BOOL_OPS (SparseComplexMatrix, SparseComplexMatrix, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CSparse.h b/liboctave/CSparse.h
new file mode 100644
index 0000000..843e2be
--- /dev/null
+++ b/liboctave/CSparse.h
@@ -0,0 +1,544 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_CSparse_h)
+#define octave_CSparse_h 1
+
+#include "dMatrix.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
+#include "dColVector.h"
+#include "CColVector.h"
+#include "oct-cmplx.h"
+
+#include "DET.h"
+#include "MSparse.h"
+#include "MSparse-defs.h"
+#include "Sparse-op-defs.h"
+#include "MatrixType.h"
+
+class PermMatrix;
+class DiagMatrix;
+class ComplexDiagMatrix;
+class SparseMatrix;
+class SparseBoolMatrix;
+
+class
+OCTAVE_API
+SparseComplexMatrix : public MSparse<Complex>
+{
+public:
+  
+  typedef void (*solve_singularity_handler) (double rcond);
+
+  SparseComplexMatrix (void) : MSparse<Complex> () { }
+
+  SparseComplexMatrix (octave_idx_type r, octave_idx_type c) : MSparse<Complex> (r, c) { }
+
+  SparseComplexMatrix (const dim_vector& dv, octave_idx_type nz = 0) : 
+    MSparse<Complex> (dv, nz) { }
+
+  explicit SparseComplexMatrix (octave_idx_type r, octave_idx_type c, Complex val) 
+    : MSparse<Complex> (r, c, val) { }
+
+  SparseComplexMatrix (octave_idx_type r, octave_idx_type c, double val) 
+    : MSparse<Complex> (r, c, Complex (val)) { }
+
+  SparseComplexMatrix (const SparseComplexMatrix& a) 
+    : MSparse<Complex> (a) { }
+
+  SparseComplexMatrix (const SparseComplexMatrix& a, const dim_vector& dv) 
+    : MSparse<Complex> (a, dv) { }
+
+  SparseComplexMatrix (const MSparse<Complex>& a) : MSparse<Complex> (a) { }
+
+  explicit SparseComplexMatrix (const ComplexMatrix& a) 
+    : MSparse<Complex> (a) { }
+
+  explicit SparseComplexMatrix (const ComplexNDArray& a) 
+    : MSparse<Complex> (a) { }
+
+  explicit SparseComplexMatrix (const Array<Complex> a, const Array<octave_idx_type>& r, 
+			 const Array<octave_idx_type>& c, octave_idx_type nr = -1, 
+			 octave_idx_type nc = -1, bool sum_terms = true)
+    : MSparse<Complex> (a, r, c, nr, nc, sum_terms) { }
+
+  explicit SparseComplexMatrix (const Array<Complex> a, 
+				const Array<double>& r, 
+				const Array<double>& c, octave_idx_type nr = -1, 
+				octave_idx_type nc = -1, bool sum_terms = true)
+    : MSparse<Complex> (a, r, c, nr, nc, sum_terms) { }
+
+  explicit SparseComplexMatrix (const SparseMatrix& a);
+
+  explicit SparseComplexMatrix (const SparseBoolMatrix& a);
+
+  explicit SparseComplexMatrix (const ComplexDiagMatrix& a);
+
+  SparseComplexMatrix (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) 
+    : MSparse<Complex> (r, c, num_nz) { }
+
+  SparseComplexMatrix& operator = (const SparseComplexMatrix& a)
+    {
+      MSparse<Complex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const SparseComplexMatrix& a) const;
+  bool operator != (const SparseComplexMatrix& a) const;
+
+  bool is_hermitian (void) const;
+
+  SparseComplexMatrix max (int dim = 0) const;
+  SparseComplexMatrix max (Array2<octave_idx_type>& index, int dim = 0) const;
+  SparseComplexMatrix min (int dim = 0) const;
+  SparseComplexMatrix min (Array2<octave_idx_type>& index, int dim = 0) const;
+
+  SparseComplexMatrix& insert (const SparseComplexMatrix& a, octave_idx_type r, octave_idx_type c);
+  SparseComplexMatrix& insert (const SparseMatrix& a, octave_idx_type r, octave_idx_type c);
+  SparseComplexMatrix& insert (const SparseComplexMatrix& a, const Array<octave_idx_type>& indx);
+  SparseComplexMatrix& insert (const SparseMatrix& a, const Array<octave_idx_type>& indx);
+
+  SparseComplexMatrix concat (const SparseComplexMatrix& rb,
+			      const Array<octave_idx_type>& ra_idx);
+  SparseComplexMatrix concat (const SparseMatrix& rb,
+			      const Array<octave_idx_type>& ra_idx);
+
+  ComplexMatrix matrix_value (void) const;
+
+  SparseComplexMatrix hermitian (void) const;  // complex conjugate transpose
+  SparseComplexMatrix transpose (void) const
+    { return MSparse<Complex>::transpose (); }
+
+  friend SparseComplexMatrix conj (const SparseComplexMatrix& a);
+
+  // extract row or column i.
+
+  ComplexRowVector row (octave_idx_type i) const;
+
+  ComplexColumnVector column (octave_idx_type i) const;
+
+private:
+  SparseComplexMatrix dinverse (MatrixType &mattyp, octave_idx_type& info, 
+				double& rcond, const bool force = false, 
+				const bool calccond = true) const;
+
+  SparseComplexMatrix tinverse (MatrixType &mattyp, octave_idx_type& info, 
+				double& rcond, const bool force = false, 
+				const bool calccond = true) const;
+
+public:
+  SparseComplexMatrix inverse (void) const;
+  SparseComplexMatrix inverse (MatrixType& mattype) const;
+  SparseComplexMatrix inverse (MatrixType& mattype, 
+			       octave_idx_type& info) const;
+  SparseComplexMatrix inverse (MatrixType& mattype, octave_idx_type& info, 
+			       double& rcond, int force = 0, 
+			       int calc_cond = 1) const;
+
+  ComplexDET determinant (void) const;
+  ComplexDET determinant (octave_idx_type& info) const;
+  ComplexDET determinant (octave_idx_type& info, double& rcond, 
+				int calc_cond = 1) const;
+
+private:
+  // Diagonal matrix solvers
+  ComplexMatrix dsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix dsolve (MatrixType &typ, const ComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler, 
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix dsolve (MatrixType &typ, const SparseMatrix& b, 
+		octave_idx_type& info, double& rcond,
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix dsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Upper triangular matrix solvers
+  ComplexMatrix utsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix utsolve (MatrixType &typ, const ComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix utsolve (MatrixType &typ, const SparseMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix utsolve (MatrixType &typ, const SparseComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Lower triangular matrix solvers
+  ComplexMatrix ltsolve (MatrixType &typ, const Matrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix ltsolve (MatrixType &typ, const ComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix ltsolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix ltsolve (MatrixType &typ, const SparseComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Tridiagonal matrix solvers
+  ComplexMatrix trisolve (MatrixType &typ, const Matrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix trisolve (MatrixType &typ, const ComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix trisolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix trisolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Banded matrix solvers (umfpack/cholesky)
+  ComplexMatrix bsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix bsolve (MatrixType &typ, const ComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix bsolve (MatrixType &typ, const SparseMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix bsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond,
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Full matrix solvers (umfpack/cholesky)
+  void * factorize (octave_idx_type& err, double &rcond, Matrix &Control, 
+		Matrix &Info, solve_singularity_handler sing_handler,
+		bool calc_cond) const;
+
+  ComplexMatrix fsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix fsolve (MatrixType &typ, const ComplexMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix fsolve (MatrixType &typ, const SparseMatrix& b, 
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix fsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+public:
+  // Generic interface to solver with no probing of type
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b) const;
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b, 
+		       octave_idx_type& info) const;
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		       double& rcond) const;
+  ComplexMatrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		       double& rcond, solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcond) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b,
+		       octave_idx_type& info, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  SparseComplexMatrix solve (MatrixType &typ, const SparseMatrix& b) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseMatrix& b, 
+			     octave_idx_type& info) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseMatrix& b, 
+			     octave_idx_type& info, double& rcond) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseMatrix& b, 
+			     octave_idx_type& info, double& rcond, 
+			     solve_singularity_handler sing_handler,
+			     bool singular_fallback = true) const;
+
+  SparseComplexMatrix solve (MatrixType &typ, 
+			     const SparseComplexMatrix& b) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseComplexMatrix& b, 
+			     octave_idx_type& info) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseComplexMatrix& b, 
+			     octave_idx_type& info, double& rcond) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseComplexMatrix& b,
+			     octave_idx_type& info, double& rcond, 
+			     solve_singularity_handler sing_handler,
+			     bool singular_fallback = true) const;
+
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b) const;
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+			     octave_idx_type& info, double& rcond) const;
+  ComplexColumnVector solve (MatrixType &typ, const ColumnVector& b,
+			     octave_idx_type& info, double& rcond, 
+			     solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (MatrixType &typ, 
+			     const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b,
+			     octave_idx_type& info, double& rcond) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b,
+			     octave_idx_type& info, double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  // Generic interface to solver with probing of type
+  ComplexMatrix solve (const Matrix& b) const;
+  ComplexMatrix solve (const Matrix& b, octave_idx_type& info) const;
+  ComplexMatrix solve (const Matrix& b, octave_idx_type& info, 
+		       double& rcond) const;
+  ComplexMatrix solve (const Matrix& b, octave_idx_type& info, double& rcond, 
+		       solve_singularity_handler sing_handler) const;
+
+  ComplexMatrix solve (const ComplexMatrix& b) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, 
+		       double& rcond) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info,
+		       double& rcond, solve_singularity_handler sing_handler) const;
+
+  SparseComplexMatrix solve (const SparseMatrix& b) const;
+  SparseComplexMatrix solve (const SparseMatrix& b, octave_idx_type& info) const;
+  SparseComplexMatrix solve (const SparseMatrix& b, octave_idx_type& info, 
+			     double& rcond) const;
+  SparseComplexMatrix solve (const SparseMatrix& b, octave_idx_type& info, 
+			     double& rcond, 
+			     solve_singularity_handler sing_handler) const;
+
+  SparseComplexMatrix solve (const SparseComplexMatrix& b) const;
+  SparseComplexMatrix solve (const SparseComplexMatrix& b, 
+			     octave_idx_type& info) const;
+  SparseComplexMatrix solve (const SparseComplexMatrix& b,
+			     octave_idx_type& info, double& rcond) const;
+  SparseComplexMatrix solve (const SparseComplexMatrix& b,
+			     octave_idx_type& info, double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (const ColumnVector& b) const;
+  ComplexColumnVector solve (const ColumnVector& b, octave_idx_type& info) const;
+  ComplexColumnVector solve (const ColumnVector& b, octave_idx_type& info,
+			     double& rcond) const;
+  ComplexColumnVector solve (const ColumnVector& b, octave_idx_type& info, 
+			     double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcond) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  SparseComplexMatrix squeeze (void) const;
+
+  SparseComplexMatrix index (idx_vector& i, int resize_ok) const;
+
+  SparseComplexMatrix index (idx_vector& i, idx_vector& j, int resize_ok) const;
+  
+  SparseComplexMatrix index (Array<idx_vector>& ra_idx, int resize_ok) const;
+
+  SparseComplexMatrix reshape (const dim_vector& new_dims) const;
+
+  SparseComplexMatrix permute (const Array<octave_idx_type>& vec, 
+			       bool inv = false) const;
+
+  SparseComplexMatrix ipermute (const Array<octave_idx_type>& vec) const;
+
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool all_elements_are_real (void) const;
+  bool all_integers (double& max_val, double& min_val) const;
+  bool too_large_for_float (void) const;
+
+  SparseBoolMatrix operator ! (void) const;
+
+  SparseBoolMatrix all (int dim = -1) const;
+  SparseBoolMatrix any (int dim = -1) const;
+
+  SparseComplexMatrix cumprod (int dim = -1) const;
+  SparseComplexMatrix cumsum (int dim = -1) const;
+  SparseComplexMatrix prod (int dim = -1) const;
+  SparseComplexMatrix sum (int dim = -1) const;
+  SparseComplexMatrix sumsq (int dim = -1) const;
+  SparseMatrix abs (void) const;
+
+  SparseComplexMatrix diag (octave_idx_type k = 0) const;
+
+  // i/o
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, 
+				    const SparseComplexMatrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, 
+				    SparseComplexMatrix& a);
+
+  typedef double (*dmapper) (const Complex&);
+  typedef Complex (*cmapper) (const Complex&);
+  typedef bool (*bmapper) (const Complex&);
+  SparseMatrix map (dmapper fcn) const;
+  SparseComplexMatrix map (cmapper fcn) const;
+  SparseBoolMatrix map (bmapper fcn) const;
+};
+
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseMatrix&,        
+				       const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseComplexMatrix&, 
+				       const SparseMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseComplexMatrix&, 
+				       const SparseComplexMatrix&);
+
+extern OCTAVE_API ComplexMatrix operator * (const Matrix&,        
+				       const SparseComplexMatrix&);
+extern OCTAVE_API ComplexMatrix operator * (const ComplexMatrix&, 
+				       const SparseMatrix&);
+extern OCTAVE_API ComplexMatrix operator * (const ComplexMatrix&, 
+				       const SparseComplexMatrix&);
+extern OCTAVE_API ComplexMatrix mul_trans (const ComplexMatrix&, 
+				       const SparseComplexMatrix&);
+extern OCTAVE_API ComplexMatrix mul_herm (const ComplexMatrix&, 
+				       const SparseComplexMatrix&);
+
+extern OCTAVE_API ComplexMatrix operator * (const SparseMatrix&,        
+				       const ComplexMatrix&);
+extern OCTAVE_API ComplexMatrix operator * (const SparseComplexMatrix&, 
+				       const Matrix&);
+extern OCTAVE_API ComplexMatrix operator * (const SparseComplexMatrix&, 
+				       const ComplexMatrix&);
+extern OCTAVE_API ComplexMatrix trans_mul (const SparseComplexMatrix&, 
+				       const ComplexMatrix&);
+extern OCTAVE_API ComplexMatrix herm_mul (const SparseComplexMatrix&, 
+				       const ComplexMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix operator * (const DiagMatrix&, const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseComplexMatrix&, const DiagMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix operator * (const ComplexDiagMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseMatrix&, const ComplexDiagMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix operator * (const ComplexDiagMatrix&, const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseComplexMatrix&, const ComplexDiagMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix operator + (const ComplexDiagMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator + (const DiagMatrix&, const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator + (const ComplexDiagMatrix&, const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator + (const SparseMatrix&, const ComplexDiagMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator + (const SparseComplexMatrix&, const DiagMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator + (const SparseComplexMatrix&, const ComplexDiagMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix operator - (const ComplexDiagMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator - (const DiagMatrix&, const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator - (const ComplexDiagMatrix&, const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator - (const SparseMatrix&, const ComplexDiagMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator - (const SparseComplexMatrix&, const DiagMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator - (const SparseComplexMatrix&, const ComplexDiagMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix operator * (const PermMatrix&,
+						  const SparseComplexMatrix&);
+extern OCTAVE_API SparseComplexMatrix operator * (const SparseComplexMatrix&,
+						  const PermMatrix&);
+
+extern OCTAVE_API SparseComplexMatrix min (const Complex& c, 
+				const SparseComplexMatrix& m);
+extern OCTAVE_API SparseComplexMatrix min (const SparseComplexMatrix& m, 
+				const Complex& c);
+extern OCTAVE_API SparseComplexMatrix min (const SparseComplexMatrix& a, 
+				const SparseComplexMatrix& b);
+
+extern OCTAVE_API SparseComplexMatrix max (const Complex& c, 
+				const SparseComplexMatrix& m);
+extern OCTAVE_API SparseComplexMatrix max (const SparseComplexMatrix& m, 
+				const Complex& c);
+extern OCTAVE_API SparseComplexMatrix max (const SparseComplexMatrix& a, 
+				const SparseComplexMatrix& b);
+
+SPARSE_SMS_CMP_OP_DECLS (SparseComplexMatrix, Complex, OCTAVE_API)
+SPARSE_SMS_BOOL_OP_DECLS (SparseComplexMatrix, Complex, OCTAVE_API)
+
+SPARSE_SSM_CMP_OP_DECLS (Complex, SparseComplexMatrix, OCTAVE_API)
+SPARSE_SSM_BOOL_OP_DECLS (Complex, SparseComplexMatrix, OCTAVE_API)
+
+SPARSE_SMSM_CMP_OP_DECLS (SparseComplexMatrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_SMSM_BOOL_OP_DECLS (SparseComplexMatrix, SparseComplexMatrix, OCTAVE_API)
+
+SPARSE_FORWARD_DEFS (MSparse, SparseComplexMatrix, ComplexMatrix, Complex)
+
+#ifdef IDX_TYPE_LONG
+#define UMFPACK_ZNAME(name) umfpack_zl_ ## name
+#else
+#define UMFPACK_ZNAME(name) umfpack_zi_ ## name
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog
new file mode 100644
index 0000000..1b0b23b
--- /dev/null
+++ b/liboctave/ChangeLog
@@ -0,0 +1,11166 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Makefile.in: Add PTHREAD_CFLAGS to LINK_DEPS.
+
+2009-08-05  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (LINK_DEPS): Include $(PTHREAD_LIBS) in the list.
+
+2009-11-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* base-aepbal.h (permuting_vector): Fix lower part swapping.
+
+2009-11-18  David Grundberg  <davidg at cs.umu.se>
+
+       * str-vec.cc (string_vector::list_in_columns): Avoid crash on
+       empty arguments from list_in_columns.
+
+2009-10-27  David Bateman  <dbateman at free.fr>
+
+	* SparsedbleLU.cc (SparseLU::SparseLU (const SparseMatrix&,
+	const Matrix&, bool), SparseLU::SparseLU (const SparseMatrix&,
+	const ColumnVector&, const Matrix&, boo, bool, double, bool,
+	bool)): Fix test for valid pivot tolerance.
+	* SparseCmplxLU.cc (SparseComplexLU::SparseComplexLU 
+	(const SparseComplexMatrix&, const Matrix&, bool), 
+	SparseComplexLU::SparseComplexLU (const SparseComplexMatrix&,
+	const ColumnVector&, const Matrix&, boo, bool, double, bool,
+	bool)): Ditto.
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+2009-08-31  John W. Eaton  <jwe at octave.org>
+
+	* liboctave/lo-ieee.cc (octave_ieee_init): Abort if floating point
+	format is not recognized as IEEE.
+
+2009-08-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-util.cc (zero_dims_inquire): Add matching ndims case.
+
+2009-08-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dMatrix.cc, fMatrix.cc, CMatrix.cc, fCMatrix.cc: Add more tests.
+	* CMatrix.cc (xgemm): Fix vector * matrix case.
+	* fCMatrix.cc (xgemm): Ditto.
+
+2009-08-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* fMatrix.cc, fCMatrix.cc: Make tests use single precision.
+
+2009-08-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* CMatrix.cc (xgemm): Fix typo. Add test.
+	* fCMatrix.cc (xgemm): Ditto.
+
+2009-07-20  John W. Eaton  <jwe at octave.org>
+
+	* lo-ieee.cc (octave_ieee_init) [__NetBSD__]: Call nan to
+	initialize Octave_NaN and nanf, to initialize Octave_Float_NaN.
+
+2009-07-08  John W. Eaton  <jwe at octave.org>
+
+	* dim-vector.h (dim_vector::dim_vector_rep::dim_vector_rep
+	(octave_idx_type, const dim_vector_rep *, int)):
+	Enforce 2-d objects here.
+	(dim_vector::dim_vector_rep::dim_vector_rep): Simply copy object.
+	(dim_vector::resize): Allow N < 2.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-07-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Sparse-op-defs.h (SPARSE_ALL_OP): Fix typo.
+	* dSparse.cc (SparseMatrix::prod): Ditto.
+	* CSparse.cc (ComplexSparseMatrix::prod): Ditto.
+
+2009-07-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Sparse-diag-op-defs.h (inner_do_add_sm_dm): Rewrite to ensure
+	ordering of row indices.
+
+2009-06-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* pathsearch.h (class dir_path::static_members): Decorate with
+	OCTAVE_API.
+
+2009-06-24  Alexander Barth  <barth.alexander at gmail.com>
+
+	* eigs-base.cc (EigsRealSymmetricMatrix,
+	EigsRealSymmetricMatrixShift, EigsRealSymmetricFunc,
+	EigsRealNonSymmetricMatrix, EigsRealNonSymmetricMatrixShift,
+	EigsRealNonSymmetricFunc, EigsComplexNonSymmetricMatrix,
+	EigsComplexNonSymmetricMatrixShift, EigsComplexNonSymmetricFunc):
+	Use octave_idx_type for parameters of type LOGICAL in ARPACK.
+
+2009-06-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* chMatrix.cc (charMatrix::charMatrix (const string_vector&)):
+	Optimize w.r.t. COW of std::string.
+
+2009-06-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dMatrix.cc (xgemm): Replace resize() with uninitialized allocations
+	where appropriate.
+	* fMatrix.cc (xgemm): Ditto.
+	* CMatrix.cc (xgemm): Ditto.
+	* fCMatrix.cc (xgemm): Ditto.
+
+2009-06-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* cmd-edit.cc (command_editor::force_default_editor): New static
+	method.
+	* cmd-edit.h: Declare it.
+
+2009-06-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* lo-mappers.cc (xlog2 (const Complex&, int&), xlog2 (const
+	FloatComplex&, int&)): Use more robust expression.
+
+2009-06-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::find): Avoid allocating excessive memory. Fix
+	order for backward searches.
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-C.cc (class DiagArray2<Complex>::Proxy): Only explicitly
+	instantiate DiagArray2<T>::Proxy on MSVC.
+	* Array-d.cc (class DiagArray2<double>::Proxy): Ditto.
+	* Array-f.cc (class DiagArray2<float>::Proxy): Ditto.
+	* Array-fC.cc (class DiagArray2<FloatComplex>::Proxy): Ditto.
+
+2009-05-26  John W. Eaton  <jwe at octave.org>
+
+	* pathsearch.h (dir_path::path_sep_char (char),
+	dir_path::static_members::path_sep_char (char)): New functions.
+
+2009-05-21  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Array-C.cc (class DiagArray2<Complex>::Proxy): Tag with OCTAVE_API.
+	* Array-d.cc (class DiagArray2<double>::Proxy): Ditto.
+	* Array-f.cc (class DiagArray2<float>::Proxy): Ditto.
+	* Array-fC.cc (class DiagArray2<FloatComplex>::Proxy): Ditto.
+	* Array.cc (class octave_sort<T>): Ditto.
+	* CColVector.h (conj, operator*, operator>>, operator<<): Ditto.
+	* CDiagMatrix.h (class ComplexDiagMatrix, conj, operator*): Ditto.
+	* CMatrix.h (conj): Ditto.
+	* CNDArray.h (conj): Ditto.
+	* PermMatrix.h (class PermMatrix, operator*): Ditto.
+	* dDiagMatrix.h (class DiagMatrix): Ditto.
+	* fCColVector.h (conj, operator*, operator>>, operator<<): Ditto.
+	* fCDiagMatrix.h (class FloatComplexDiagMatrix, conj, operator*):
+	Ditto.
+	* fCMatrix.h (conj): Ditto.
+	* fCNDArray.h (conj): Ditto.
+	* fDiagMatrix.h (operator*): Ditto.
+	* oct-locbuf.h (octave_chunk_buffer::octave_chunk_buffer,
+	octave_chunk_buffer::~octave_chunk_buffer): Ditto.
+	* oct-inttypes.cc (octave_int_cmp_op::emulate_op): Ditto.
+	* DET.h (class base_det<T>): Remove OCTAVE_API (cannot be applied on
+	templates).
+	* oct-inttypes.cc (octave_int_cmp_op::emulate_op<class xop>): Ditto.
+
+	* CmplxQR.cc (ComplexQR::insert_col, ComplexQR::delete_col): Copy
+	volatile variable to avoid MSVC compilation error (cannot pass
+	volatile variable as const& argument).
+	* dbleQR.cc (QR::insert_col, QR::delete_col): Ditto.
+	* fCmplxQR.cc (FloatComplexQR::insert_col,
+	FloatComplexQR::delete_col): Ditto.
+	* floatQR.cc (FloatQR::insert_col, FloatQR::delete_col): Ditto.
+
+	* oct-mutex.cc: Exclude pthread.h inclusion under Win32.
+
+	* base-aepbal.h (base_aepbal::operator=): Add missing return
+	statement.
+
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* eigs-base.cc (
+	EigsRealSymmetricMatrix,
+	EigsRealSymmetricMatrixShift,
+	EigsRealSymmetricFunc,
+	EigsRealNonSymmetricMatrix,
+	EigsRealNonSymmetricMatrixShift,
+	EigsRealNonSymmetricFunc,
+	EigsComplexNonSymmetricMatrix,
+	EigsComplexNonSymmetricMatrixShift,
+	EigsComplexNonSymmetricFunc): Update tests.
+
+2009-05-21  Jaroslav Hajek  <highegg at gmail.com>
+
+
+	* CMatrix.cc 
+	(ComplexMatrix::all, ComplexMatrix::any, ComplexMatrix::cumprod,
+	ComplexMatrix::cumsum, ComplexMatrix::prod, ComplexMatrix::sum,
+	ComplexMatrix::sumsq): Use explicit template qualifications
+	to workaround bugs in Intel C++ and MSVC++ compilers.
+	* CNDArray.cc
+	(ComplexNDArray::all, ComplexNDArray::any, ComplexNDArray::cumprod,
+	ComplexNDArray::cumsum, ComplexNDArray::prod, ComplexNDArray::sum,
+	ComplexNDArray::sumsq): Ditto.
+	* boolMatrix.cc
+	(boolMatrix::all, boolMatrix::any): Ditto.
+	* boolNDArray.cc
+	(boolNDArray::all, boolNDArray::any): Ditto.
+	* chMatrix.cc
+	(charMatrix::all, charMatrix::any): Ditto.
+	* chNDArray.cc
+	(charNDArray::all, charNDArray::any): Ditto.
+	* dMatrix.cc
+	(Matrix::all, Matrix::any, Matrix::cumprod,
+	Matrix::cumsum, Matrix::prod, Matrix::sum,
+	Matrix::sumsq): Ditto.
+	* dNDArray.cc
+	(NDArray::all, NDArray::any, NDArray::cumprod,
+	NDArray::cumsum, NDArray::prod, NDArray::sum,
+	NDArray::sumsq): Ditto.
+	* fCMatrix.cc
+	(FloatComplexMatrix::all, FloatComplexMatrix::any, FloatComplexMatrix::cumprod,
+	FloatComplexMatrix::cumsum, FloatComplexMatrix::prod, FloatComplexMatrix::sum,
+	FloatComplexMatrix::sumsq): Ditto.
+	* fCNDArray.cc
+	(FloatComplexNDArray::all, FloatComplexNDArray::any, FloatComplexNDArray::cumprod,
+	FloatComplexNDArray::cumsum, FloatComplexNDArray::prod, FloatComplexNDArray::sum,
+	FloatComplexNDArray::sumsq): Ditto.
+	* fMatrix.cc
+	(FloatMatrix::all, FloatMatrix::any, FloatMatrix::cumprod,
+	FloatMatrix::cumsum, FloatMatrix::prod, FloatMatrix::sum,
+	FloatMatrix::sumsq): Ditto.
+	* fNDArray.cc
+	(FloatNDArray::all, FloatNDArray::any, FloatNDArray::cumprod,
+	FloatNDArray::cumsum, FloatNDArray::prod, FloatNDArray::sum,
+	FloatNDArray::sumsq): Ditto.
+	* intNDArray.cc
+	(intNDArray<T>::all, intNDArray<T>::any,
+	intNDArray<T>::cumsum, intNDArray<T>::sum): Ditto.
+
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Makefile.in: Remove reference to ArrayN-idx.h.
+
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-voidp.cc: New source.
+	* Array.cc (NO_INSTANTIATE_ARRAY_SORT): const T& -> T const &
+	* Makefile.in: Include it.
+
+2009-05-15  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* Array.cc (Array<T>::instantiation_guard): New function
+	(INSTANTIATE_ARRAY): Always override it here.
+	* Array.h: Declare it.
+
+2009-05-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ArrayN-idx.h: Remove file.
+	* ArrayN.cc: Don't include it.
+	* MArrayN.cc: Dtto.
+
+2009-05-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-util.cc (zero_dims_inquire): Move j++ out of branch.
+
+2009-05-07  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+        * Makefile.in: (SHLPRE): Rename from SHLLIBPRE.
+
+2009-05-05  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* file-ops.h (file_ops::tail) New function.
+
+2009-05-05  Carsten Clark  <tantumquantum+gnuoctave at gmail.com>
+
+	* Quad.cc (user_function): Use access_double and assign_double on
+	SPARC only, not on all Sun systems.
+	* sun-utils.h: Likewise, define these functions on SPARC only.
+
+2009-05-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Sparse.cc (assign1): Fix an old indexing bug.
+
+2009-05-04  Carsten Clark  <tantumquantum+gnuoctave at gmail.com>
+
+	* Quad.cc (float_user_function): Remove Sun/GCC special case.
+
+2009-04-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.cc (idx_vector::idx_range_rep::idx_range_rep (const
+	Range&)): Check for positive integer indices. Unify gripes.
+
+2009-04-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (rec_permute_helper::blk_trans): Declare as static.
+	(Array<T>::transpose): Reuse it.
+
+2009-04-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::make_unique): Don't economize when unique.
+	(Array<T>::resize_fill (octave_idx_type, const T&)): Optimize push &
+	pop operations.
+	(Array<T>::delete_elements (const idx_vector&)): Do pop operation
+	using resize.
+
+2009-03-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::assign): Remove redundant checks after invalid
+	resize.
+
+2009-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::find): Reshape result for Matlab compatibility.
+	* Array.h (Array<T>): Add friend template declaration.
+
+2009-03-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.cc (idx_vector::idx_vector_rep::idx_vector_rep (const
+	Array<bool>&): Use more M*b-compatible behaviour.
+
+2009-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dim-vector.h (dim_vector::numel): Add optional argument, simplify.
+
+2009-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.h (Array<T>::dims): Return a const reference.
+	(Array<T>::is_vector): New method.
+
+2009-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::find): New method.
+	* Array.h: Declare it.
+
+2009-03-25  John W. Eaton  <jwe at octave.org>
+
+	* EIG.cc (EIG::init (const Matrix&, bool),
+	EIG::init (const Matrix&, const Matrix&, bool)):
+	Avoid volatile declaration for tmp variable.
+
+	* Makefile.in (MATRIX_INC): Add Sparse-diag-op-defs.h and
+	Sparse-perm-op-defs.h to the list.
+
+2009-03-25  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* oct-inttypes.cc (INT_DOUBLE_BINOP_DECL (*, uint64),
+	INT_DOUBLE_BINOP_DECL (*, int64)): x -> y where appropriate.
+
+2009-03-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (rec_permute_helper::use_blk): New field.
+	(rec_permute_helper::blk_trans): New method.
+	(rec_permute_helper::rec_permute_helper): Use smart reductions,
+	detect possibility of using blocked transpose.
+	(rec_permute_helper::do_permute): Use blocked transpose if possible.
+
+2009-03-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.cc (convert_index(double,...)): Simplify.
+
+2009-03-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-d.cc: lo_ieee_isnan -> xisnan.
+	* Array-f.cc: Ditto.
+	* oct-inttypes.cc: Ditto.
+	* oct-inttypes.h: Ditto.
+	* CDiagMatrix.cc: Add missing include.
+	* fCDiagMatrix.cc: Ditto.
+
+2009-03-20  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* CColVector.cc, CMatrix.cc, CNDArray.cc, CRowVector.cc, CSparse.cc,
+	boolSparse.cc, dColVector.cc, dMatrix.cc, dNDArray.cc, dRowVector.cc,
+	dSparse.cc, fCColVector.cc, fCMatrix.cc, fCNDArray.cc, fCRowVector.cc,
+	fColVector.cc, fMatrix.cc, fNDArray.cc, fRowVector.cc, intNDArray.cc:
+	Allow empty arrays in stream input operators.
+
+2009-03-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.h (Array<T>::fastmap): New method.
+	* dNDArray.cc (NDArray::isnan, NDArray::isinf, NDArray::isfinite):
+	New methods.
+	* dNDArray.h: Declare them.
+	* fNDArray.cc (FloatNDArray::isnan, FloatNDArray::isinf,
+	FloatNDArray::isfinite): New methods.
+	* fNDArray.h: Declare them.
+	* CNDArray.cc (ComplexNDArray::isnan, ComplexNDArray::isinf,
+	ComplexNDArray::isfinite): New methods.
+	* CNDArray.h: Declare them.
+	* fCNDArray.cc (FloatComplexNDArray::isnan, FloatComplexNDArray::isinf,
+	FloatComplexNDArray::isfinite): New methods.
+	* fCNDArray.h: Declare them.
+	* lo-mappers.h (xisnan, xisinf, xfinite): If possible, use definitions
+	from <cmath>.
+
+2009-03-18  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-norm.cc (get_eps): Remove that hack.
+	(higham): Use std::numeric_limits instead.
+	Include OCTAVE_QUIT.
+
+2009-03-16  Jason Riedy  <jason at acm.org>
+
+	* Sparse.cc (transpose): Eliminate the workspace by computing in
+	retval.xcidx.
+	* CSparse.cc (hermitian): Eliminate the workspace by computing in
+	retval.xcidx.
+
+2009-03-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-op-decl.h (NDS_BOOL_OP_DECLS, SND_BOOL_OP_DECLS, NDND_BOOL_OP_DECLS): Support compound binary ops.
+	* mx-op-defs.h (NDS_BOOL_OPS, SND_BOOL_OPS, NDND_BOOL_OPS): Ditto. Optimize.
+	* mx-op-defs.h (NDS_CMP_OP, SND_CMP_OP, NDND_CMP_OP): Optimize.
+
+2009-03-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* fNDArray.h (FloatMatrix::matrix_value): Fix return type.
+	* dNDArray.cc (Matrix::matrix_value): Simplify.
+	* fNDArray.cc (FloatMatrix::matrix_value): Simplify.
+	* CNDArray.cc (ComplexMatrix::matrix_value): Simplify.
+	* fCNDArray.cc (FloatComplexMatrix::matrix_value): Simplify.
+
+2009-03-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Range.h (Range::Range (double, double, octave_idx_type)): Remove
+	constructor body.
+	* Range.cc: Move it here. Check for invalid range op results.
+	(all operators): Validate cache for invalid range op results.
+	* idx-vector.h (idx_vector::index): Optimize zero-step range case.
+	* idx-vector.cc (idx_vector::maybe_reduce): Always reduce colon in
+	singleton dimension.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* sparse-base-lu.cc (Pr_mat): New member function.  Return the row
+	permutation as a PermMatrix.
+	(Pc_mat): New member function.  Return the col permutation as a
+	PermMatrix.
+
+	* sparse-base-lu.h (sparse_base_lu): Declare Pc_mat and Pr_mat
+	member functions.
+
+2009-03-09  Jason Riedy  <jason at acm.org>
+
+	* Sparse-diag-op-defs.h (octave_impl::inner_do_add_sm_dm): New
+	template function.  Implementation for adding sparse and diagonal
+	matrices.  Takes two functional arguments, opa and opd, to
+	generate both subtraction variants.
+	(octave_impl::do_commutative_add_dm_sm): New template function.
+	Ensure A+D and D+A use the same generated code.
+	(octave_impl::do_add_dm_sm): New template function.  Check
+	arguments for diag + sparse and call inner routine.
+	(octave_impl::do_sub_dm_sm): New template function.  Check
+	arguments for diag - sparse and call inner routine.
+	(octave_impl::do_add_sm_dm): New template function.  Check
+	arguments for sparse + diag and call inner routine.
+	(octave_impl::do_sub_sm_dm): New template function.  Check
+	arguments for sparse - diag and call inner routine.
+
+	* dSparse.h (operator +): Declare overrides for real diag +
+	sparse.
+	(operator -): Declare overrides for real diag - sparse, sparse -
+	diag.
+
+	* dSparse.cc (operator +): Define overrides for real diag +
+	sparse.
+	(operator -): Define overrides for real diag - sparse, sparse -
+	diag.
+
+	* CSparse.h (operator +): Declare overrides for complex and real
+	combinations of diag + sparse.
+	(operator -): Declare overrides for complex and real combinations
+	of diag - sparse, sparse - diag.
+
+	* CSparse.cc (operator +): Define overrides for complex and real
+	combinations of diag + sparse.
+	(operator -): Define overrides for complex and real combinations
+	of diag - sparse, sparse - diag.
+
+2009-03-08  Jason Riedy  <jason at acm.org>
+
+	* Sparse-diag-op-defs.h (octave_impl::do_mul_dm_sm)
+	(octave_impl::do_mul_sm_dm): New template
+	functions. Implementations for sparse * diag and diag * sparse.
+
+	* CSparse.h (operator *, trans_mul, herm_mul): Add overloads for
+	DiagMatrix and ComplexDiagMatrix.
+	* CSparse.cc (operator *, trans_mul, herm_mul): Implement
+	operations by calling approprate functions in
+	Sparse-diag-op-defs.h.
+	* dSparse.h (operator *, trans_mul): Add overloads for DiagMatrix.
+	* dSparse.cc (operator *, trans_mul): Implement operations by
+	calling approprate functions in Sparse-diag-op-defs.h.
+
+2009-03-12  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (bitshift): Apply mask even if not shifting.
+	From Seb Astien <se6astien2 at googlemail.com>.
+
+2009-03-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* PermMatrix.cc (PermMatrix::power): New method.
+	* PermMatrix.h: Declare it.
+
+2009-03-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dNDArray.cc (NDArray::NDArray (const charNDArray&)): New
+	constructor.
+	* fNDArray.cc (FloatNDArray::FloatNDArray (const charNDArray&)):
+	Ditto.
+	* CNDArray.cc (ComplexNDArray::ComplexNDArray (const charNDArray&)):
+	Ditto.
+	* fCNDArray.cc (FloatComplexNDArray::FloatComplexNDArray 
+	(const charNDArray&)): Ditto.
+
+	* dNDArray.h (NDArray::NDArray (const charNDArray&)): Declare.
+	* fNDArray.h (FloatNDArray::FloatNDArray (const charNDArray&)):
+	Ditto.
+	* CNDArray.h (ComplexNDArray::ComplexNDArray (const charNDArray&)):
+	Ditto.
+	* fCNDArray.h (FloatComplexNDArray::FloatComplexNDArray 
+	(const charNDArray&)): Ditto.
+
+	* dMatrix.cc (Matrix::Matrix (const charMatrix&)): Cast to unsigned
+	chars.
+	* fMatrix.cc (FloatMatrix::FloatMatrix (const charMatrix&)): Likewise.
+	* CMatrix.cc (ComplexMatrix::ComplexMatrix (const charMatrix&)):
+	Likewise.
+	* fCMatrix.cc (FloatComplexMatrix::FloatComplexMatrix 
+	(const charMatrix&)): Likewise.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* Sparse-perm-op-defs.h (octinternal_do_mul_colpm_sm): New
+	template function.  Logic for the column permutation * sparse
+	matrix operator.
+	(octinternal_do_mul_pm_sm): New template function.  Logic for the
+	permutation matrix * sparse matrix operator.  Note that there is
+	no special row perm * sparse routine; the permutation is inverted
+	and the col perm routine is called.
+	(octinternal_do_mul_sm_rowpm): New template function.  Logic for
+	the sparse matrix * row permutation operator.
+	(octinternal_do_mul_sm_colpm): New template function.  Logic for
+	the sparse matrix * column permutation operator.
+	(octinternal_do_mul_sm_pm): New template function.  Logic for the
+	sparse matrix * permutation matrix operator.
+
+	* dSparse.h (operator *): Declare sparse * permutation and
+	permutation * sparse.
+	* dSparse.cc (operator *): Define sparse * permutation and
+	permutation * sparse.
+
+	* CSparse.h (operator *): Declare sparse * permutation and
+	permutation * sparse.
+	* CSparse.cc (operator *): Define sparse * permutation and
+	permutation * sparse.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* sparse-base-lu.cc (Pc_vec): The column permutation should be
+	Ufact.cols ()-long, not Lfact.rows ()-long.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* dSparse.cc (SparseMatrix::SparseMatrix (const PermMatrix&)):
+	Fix conversion to add values to the matrix as well as getting
+	structure correct.
+
+2009-03-10  John W. Eaton  <jwe at octave.org>
+
+	* Array.h, ArrayN.h, Bounds.h, CmplxAEPBAL.h, CmplxCHOL.h,
+	CmplxGEPBAL.h, CmplxHESS.h, CmplxQR.h, CmplxQRP.h, CmplxSCHUR.h,
+	CmplxSVD.h, CollocWt.h, EIG.h, FEGrid.h, LinConst.h, Range.h,
+	Sparse.h, SparseCmplxQR.h, SparseQR.h, dbleAEPBAL.h, dbleCHOL.h,
+	dbleGEPBAL.h, dbleHESS.h, dbleQR.h, dbleQRP.h, dbleSCHUR.h,
+	dbleSVD.h, dim-vector.h, fCmplxAEPBAL.h, fCmplxCHOL.h,
+	fCmplxGEPBAL.h, fCmplxHESS.h, fCmplxQR.h, fCmplxQRP.h,
+	fCmplxSCHUR.h, fCmplxSVD.h, fEIG.h, floatAEPBAL.h, floatCHOL.h,
+	floatGEPBAL.h, floatHESS.h, floatQR.h, floatQRP.h, floatSCHUR.h,
+	floatSVD.h, idx-vector.h, lo-utils.h, oct-inttypes.h,
+	oct-spparms.h, str-vec.h: Include <iosfwd> instead of <iosstream>.
+
+2009-03-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (OP_CUMMINMAX_FCN2): r -> r0 where appropriate.
+
+2009-03-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.h (idx_vector::bloop): loop --> bloop.
+	(idx_vector::loop): New method.
+	* MArray.cc (MArray<T>::idx_add (cons idx_vector&, T))
+	(MArray<T>::idx_add (cons idx_vector&, const MArray<T>&)): New methods.
+	* MArray.h: Declare them.
+
+2009-03-05  Jason Riedy  <jason at acm.org>
+
+	* Sparse.h (Sparse<T>::elt_type): Remove typedef, replace with:
+	* Sparse.h (Sparse<T>::element_type): Add typedef to be consistent
+	with Array.h
+	* DiagArray2.h (DiagArray2<T>::elt_type): Likewise, removed.
+	* DiagArray2.h (DiagArray2<T>::element_type): Define by using
+	Array<T>::element_type.
+	* intNDArray.h (intNDArray<T>::element_type): Remove, inherited
+	from MArrayN<T>.
+
+2009-03-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dSparse.h (SparseMatrix::SparseMatrix(const PermMatrix&)): New
+	constructor.
+	(SparseMatrix::SparseMatrix(const DiagMatrix&)): Fix implementation.
+	* CSparse.h (SparseComplexMatrix::SparseComplexMatrix(const ComplexDiagMatrix&)): 
+	Fix implementation.
+
+2009-03-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* PermMatrix.h (PermMatrix::elem): Fix comparisons.
+
+2009-03-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* lo-mappers.cc (xmin (float, float), xmax (float, float)): Simplify.
+
+2009-03-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc: Add missing #include.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in: Make maintainer-clean and distclean the same.
+
+2009-02-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.cc (pow (const octave_int<T>&, const octave_int<T>&)):
+	Simplify.
+
+2009-02-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.h (octave_int_cmp_op::mop): Implement as simple
+	forwarders when OCTAVE_INT_USE_LONG_DOUBLE is not defined.
+	(octave_int_cmp_op::emulate_mop): New static overloaded template
+	member function.
+	* oct-inttypes.cc: Turn the octave_int_cmp_op::mop definitions into
+	defs for octave_int_cmp_op::emulate_mop. 
+	(INSTANTIATE_INT64_DOUBLE_CMP_OP0): Instantiate
+	octave_int_cmp_op::emulate_op instead.
+
+2009-02-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dDiagMatrix.cc (DiagMatrix::pseudo_inverse): New method.
+	* dDiagMatrix.h: Declare it.
+	* fDiagMatrix.cc (FloatDiagMatrix::pseudo_inverse): New method.
+	* fDiagMatrix.h: Declare it.
+	* CDiagMatrix.cc (ComplexDiagMatrix::pseudo_inverse): New method.
+	* CDiagMatrix.h: Declare it.
+	* fCDiagMatrix.cc (FloatComplexDiagMatrix::pseudo_inverse): New method.
+	* fCDiagMatrix.h: Declare it.
+
+2009-02-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-sort.h (octave_sort<T>::MergeState::MergeState): New
+	constructor.
+	(octave_sort<T>::MergeState::~MergeState): New destructor.
+	(octave_sort<T>::MergeState::reset, 
+	octave_sort<T>::MergeState::getmem,
+	octave_sort<T>::MergeState::getmemi): New methods.
+	(octave_sort<T>::sort,
+	octave_sort<T>::merge_lo, octave_sort<T>::merge_hi
+	octave_sort<T>::merge_at): Reflect change.
+
+2009-02-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-types.h (sortmode): Move enum here.
+	* oct-sort.h (octave_sort<T>::ms): Declare as pointer.
+	(octave_sort<T>::lookup): New overloaded method.
+	* oct-sort.cc: Reflect change to ms.
+	(octave_sort<T>::lookup): New overloaded method.
+	(out_of_range_pred): New helper class.
+	(out_of_range): New helper function.
+	* oct-lookup.h: Remove file.
+	* Array.cc (Array<T>::lookup): New overloaded method.
+	* Array.h: Declare it.
+
+2009-02-18  John W. Eaton  <jwe at octave.org>
+
+	* dbleQR.cc (QR::init, QR::form): Cast int to octave_idx_type in
+	call to std::max.
+	* floatQR.cc (FloatQR::init, FloatQR::form): Ditto.
+	* CmplxQR.cc (ComplexQR::init, ComplexQR::form): Ditto.
+	* fCmplxQR.cc (FloatComplexQR::init, FloatComplexQR::form): Ditto.
+
+	* dbleQRP.cc (QRP::init): Cast int to octave_idx_type in call to
+	std::max and as operand to -= operator.
+	* CmplxQRP.cc (ComplexQRP::init): Ditto.
+	* floatQRP.cc (FloatQRP::init): Ditto.
+	* fCmplxQRP.cc (FloatComplexQRP::init): Ditto.
+
+	* CDiagMatrix.cc, CDiagMatrix.h (ComplexDiagMatrix::inverse):
+	Declare info as octave_idx_type, not int.
+	* dDiagMatrix.cc, dDiagMatrix.h (DiagMatrix::inverse): Ditto.
+	* fDiagMatrix.cc, fCDiagMatrix.h (FloatDiagMatrix::inverse): Ditto.
+	* fCDiagMatrix.cc, fCDiagMatrix.h (FloatComplexDiagMatrix::inverse):
+	Ditto.
+
+	* dMatrix.cc (Matrix::determinant):
+	Declare local variables volatile as needed to avoid "maybe
+	clobbered by vfork" warning from GCC.
+	* fMatrix.cc (FloatMatrix::determinant): Likewise.
+	* CMatrix.cc (ComplexMatrix::determinant): Likewise.
+	* fCMatrix.cc (FloatComplexMatrix::determinant): Likewise.
+	* dbleQR.cc (QR::update, QR::insert_col, QR::delete_col): Likewise.
+	* floatQR.cc (FloatQR::update, FloatQR::insert_col,
+	FloatQR::delete_col): Likewise.
+	* CmplxQR.cc (ComplexQR::update, ComplexQR::insert_col,
+	ComplexQR::delete_col): Likewise.
+	* fCmplxQR.cc (FloatComplexQR::update, FloatComplexQR::insert_col,
+	FloatComplexQR::delete_col): Likewise.
+
+	* dMatrix.cc (padec, solve_singularity_warning): Delete unused
+	static variable and function.
+	* CMatrix.cc (padec, solve_singularity_warning): Ditto.
+	* fMatrix.cc (padec, solve_singularity_warning): Ditto.
+	* fCMatrix.cc (padec, solve_singularity_warning): Ditto.
+
+2009-02-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::resize (const dim_vector&)): Check for negative
+	dimensions.
+
+2009-02-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.cc (pow (const octave_int<T>&, const octave_int<T>&)):
+	Use octave_int comparisons to avoid warning for unsigned types.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::resize (const dim_vector&)): Remove dead branch.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (OP_CUM_FCN, OP_CUM_FCN2, OP_CUM_FCNN):
+	Add TSRC/TRES parameters.
+	(mx_inline_cumcount): New function.
+	* intNDArray.cc (intNDArray::cumsum): New method.
+	* intNDArray.h: Declare it.
+	* boolNDArray.cc (boolNDArray::cumsum): New method.
+	* boolNDArray.h: Declare it.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (OP_CUMMINMAX_FCN, OP_CUMMINMAX_FCN2,
+	OP_CUMMINMAX_FCNN): New macros.
+	(mx_inline_cummax, mx_inline_cummin, do_mx_cumminmax_op):
+	New overloaded template functions.
+
+	* dNDArray.cc (NDArray::cummin, NDArray::cummax): New methods.
+	* dNDArray.h: Declare them.
+
+	* fNDArray.cc (FloatNDArray::cummin, FloatNDArray::cummax): New
+	methods.
+	* fNDArray.h: Declare them.
+
+	* CNDArray.cc (ComplexNDArray::cummin, ComplexNDArray::cummax): New
+	methods.
+	* CNDArray.h: Declare them.
+
+	* fCNDArray.cc (FloatComplexNDArray::cummin,
+	FloatComplexNDArray::cummax): New methods.
+	* fCNDArray.h: Declare them.
+
+	* intNDArray.cc (intNDArray::cummin, intNDArray::cummax): New methods.
+	* intNDArray.h: Declare them.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (OP_MINMAX_FCN): Correct behaviour with NaNs.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* MArray-defs.h: Move declarative part to MArray-decl.h
+	* MArray-decl.h: New source.
+
+	* mx-op-defs.h: Move declarative part to mx-op-decl.h.
+	* mx-op-decl.h: New source.
+
+	* Makefile.in: Include new sources in build.
+	* mk-ops.awk: Include mx-op-decl.h in headers, mx-op-defs in .cc
+	files.
+
+	* CMatrix.cc, CMatrix.h, CNDArray.cc, CNDArray.h, MArray.h, MArray2.h,
+	MArrayN.h, MDiagArray2.h, boolMatrix.cc, boolMatrix.h, boolNDArray.cc,
+	boolNDArray.h, chMatrix.cc, chMatrix.h, chNDArray.cc, chNDArray.h,
+	dMatrix.cc, dMatrix.h, dNDArray.cc, dNDArray.h, fCMatrix.cc,
+	fCMatrix.h, fCNDArray.cc, fCNDArray.h, fMatrix.cc, fMatrix.h,
+	fNDArray.cc, fNDArray.h, int16NDArray.cc, int16NDArray.h,
+	int32NDArray.cc, int32NDArray.h, int64NDArray.cc, int64NDArray.h,
+	int8NDArray.cc, int8NDArray.h, uint16NDArray.cc, uint16NDArray.h,
+	uint32NDArray.cc, uint32NDArray.h, uint64NDArray.cc, uint64NDArray.h,
+	uint8NDArray.cc, uint8NDArray.h: Ditto.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::assign (const idx_vector& i,
+	const idx_vector& j,...)): Fix invalid dimension inquiry.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* mx-inlines.cc (OP_ROW_SHORT_CIRCUIT): New macro.
+	(mx_inline_any, mx_inline_all): Override row-reduction case.
+	(MX_CUMULATIVE_OP, MX_BASE_REDUCTION_OP, MX_REDUCTION_OP,
+	MX_ANY_OP, MX_ALL_OP, MX_ND_ANY_ALL, MX_ND_REDUCTION,
+	MX_ND_COMPLEX_OP_REDUCTION, MX_ND_CUMULATIVE_OP,
+	MX_ND_ANY_EVAL, MX_ND_ALL_EVAL, MX_ND_REAL_OP_REDUCTION):
+	Remove unused macros.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* mx-inlines.cc (OP_RED_FCNN): Use explicit type qualification.
+	(mx_inline_count): New overloaded template function.
+	* boolNDArray.h (boolNDArray::sum): Return NDArray.
+	* boolNDArray.cc (boolNDArray::sum): Return NDArray, use do_mx-red_op.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-C.cc, Array-fC.cc: Don't redefine complex comparison.
+	* Sparse.cc (Sparse::sort): Don't use vec_index.
+	* Sparse-C.cc, Sparse-d.cc, Sparse-b.cc: Don't reinstantiate
+	octave_sort, reflect changes.
+	* sparse-sort.cc: Explicitly instantiate octave_sort for requested
+	pointer types.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-cmplx.h (operator <, operator >): New operators.
+	* mx-inlines.cc (OP_MINMAX_FCN, OP_MINMAX_FCN2, OP_MINMAX_FCNN):
+	New macros.
+	(mx_inline_min, mx_inline_max, do_mx_minmax_op): New overloaded
+	template functions.
+	* dNDArray (NDArray::min, NDArray::max): Use do_mx_minmax_op.
+	* fNDArray (FloatNDArray::min, FloatNDArray::max): Ditto.
+	* CNDArray (ComplexNDArray::min, ComplexNDArray::max): Ditto.
+	* fCNDArray (FloatComplexNDArray::min, FloatComplexNDArray::max):
+	Ditto.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* chMatrix.cc (charMatrix::all, charMatrix::any): Use do_mx_red_op.
+	* chNDArray.cc (charNDArray::all, charNDArray::any): Ditto.
+
+2009-02-16  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.cc (default_command_editor::do_readline):
+	Use fputs instead of fprintf.
+
+2009-02-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (OP_RED_FCN, OP_RED_FCN2, OP_RED_FCNN, OP_CUM_FCN,
+	OP_CUM_FCN2, OP_CUM_FCNN): Include TRET parameter.
+	(OP_RED_ANYC, OP_RED_ANYR, OP_RED_ALLC, OP_RED_ALLR): New macros.
+	(is_true, is_false): New template functions.
+	(mx_inline_any, mx_inline_all): New template functions.
+
+	* dMatrix.cc (Matrix::any, Matrix::all): Use do_mx_red_op and
+	do_mx_cum_op.
+	* fMatrix.cc (FloatMatrix::any, FloatMatrix::all): Use do_mx_red_op
+	and do_mx_cum_op.
+	* CMatrix.cc (ComplexMatrix::any, ComplexMatrix::all): Use
+	do_mx_red_op and do_mx_cum_op.
+	* fCMatrix.cc (FloatComplexMatrix::any, FloatComplexMatrix::all): Use
+	do_mx_red_op and do_mx_cum_op.
+
+	* dNDArray.cc (NDArray::any, NDArray::all): Use do_mx_red_op and
+	do_mx_cum_op.
+	* fNDArray.cc (FloatNDArray::any, FloatNDArray::all): Use do_mx_red_op
+	and do_mx_cum_op.
+	* CNDArray.cc (ComplexNDArray::any, ComplexNDArray::all): Use
+	do_mx_red_op and do_mx_cum_op.
+	* fCNDArray.cc (FloatComplexNDArray::any, FloatComplexNDArray::all):
+	Use do_mx_red_op and do_mx_cum_op.
+
+	* intNDArray.cc (intNDArray::any, intNDArray::all): Use do_mx_red_op and
+	do_mx_cum_op.
+
+	* boolNDArray.cc (boolNDArray::any, boolNDArray::all): Use do_mx_red_op and
+	do_mx_cum_op.
+
+	* boolMatrix.cc (boolMatrix::any, boolMatrix::all): Use do_mx_red_op and
+	do_mx_cum_op.
+
+2009-02-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* intNDArray.cc: include mx-inlines.cc.
+	(intNDArray::sum): Use mx_do_red_op (..., mx_inline_sum).
+	* Range.cc (Range::is_sorted): Add missing return statement.
+
+2009-02-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (OP_RED_SUM, OP_RED_PROD, OP_RED_SUMSQ, OP_RED_SUMSQC,
+	OP_RED_FCN, OP_RED_FCN2, OP_RED_FCNN, OP_CUM_FCN, OP_CUM_FCN2,
+	OP_CUM_FCNN): New macros.
+	(mx_inline_sum, mx_inline_prod, mx_inline_sumsq, mx_inline_cumsum,
+	mx_inline_cumprod, get_extent_triplet, do_mx_red_op, do_mx_cum_op):
+	New template functions.
+	* dMatrix.cc (Matrix::cumprod, Matrix::cumsum, Matrix::prod,
+	Matrix::sum, Matrix::sumsq): Use do_mx_red_op and do_mx_cum_op.
+	* fMatrix.cc (FloatMatrix::cumprod, FloatMatrix::cumsum,
+	FloatMatrix::prod, FloatMatrix::sum, FloatMatrix::sumsq): Use
+	do_mx_red_op and do_mx_cum_op.
+	* CMatrix.cc (ComplexMatrix::cumprod, ComplexMatrix::cumsum,
+	ComplexMatrix::prod, ComplexMatrix::sum, ComplexMatrix::sumsq): Use
+	do_mx_red_op and do_mx_cum_op.
+	* fCMatrix.cc (FloatComplexMatrix::cumprod,
+	FloatComplexMatrix::cumsum, FloatComplexMatrix::prod,
+	FloatComplexMatrix::sum, FloatComplexMatrix::sumsq): Use do_mx_red_op
+	and do_mx_cum_op.
+
+2009-02-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.h (if_else_type): Remove
+	(octave_int_base::truncate_int): Use if_then_else.
+
+2009-02-12  John W. Eaton  <jwe at octave.org>
+
+	* lo-traits.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+	* Array.h (compare_fcn_type): New typedef.
+	* oct-sort.h (compare_fcn_type): Ditto.
+
+	* oct-sort.h, oct-sort.cc (octave_sort<T>::octave_sort,
+	octave_sort<T>::set_compare, octave_sort<T>::compare): 
+	Use typedef to simplify decl.
+	(octave_sort<T>::ascending_compare,
+	octave_sort<T>::descending_compare):
+	Use ref_param<T>::type for parameter decl.
+
+	* Array.cc (sort_isnan): Use ref_param<T>::type for parameter decl.
+	(Array<T>::sort): Use explicit template parameter for sort_isnan calls.
+
+	* Array.cc, Array-C.cc, Array-fC.cc, Array-d.cc, Array-f.cc
+	(sortrows_comparator): Rename from _sortrows_comparator.  Change
+	all uses.  Use typedef for return value to simplify decl.
+	(sort_isnan): Rename from _sort_isnan.  Change all uses.
+	(NO_INSTANTIATE_ARRAY_SORT): Use typedef to simplify instantiation
+	of sortrows_comparator.
+
+	* Array-C.cc, Array-fC.cc (sort_isnan, ascending_compare,
+	descending_compare, nan_ascending_compare,
+	nan_descending_compare):
+
+2009-02-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-sort.cc (octave_sort<T>::is_sorted, octave_sort<T>::sort_rows,
+	octave_sort<T>::is_sorted_rows): New methods.
+	* oct-sort.h: Declare them.
+
+	* Array.cc (Array<T>::is_sorted): New method.
+	(INSTANTIATE_ARRAY_SORT, NO_INSTANTIATE_ARRAY_SORT,
+	INSTANTIATE_ARRAY_AND_ASSIGN, INSTANTIATE_ARRAY): Move macros here.
+	* Array.h: Reflect changes.
+
+	* dim-vector.h (dim_vector::is_vector): New method.
+	* Array-C.cc, Array-fC.cc: Override _sort_isnan, don't check for 
+	NaN in default comparators. Provide NaN-safe comparators, override
+	_sortrows_comparator.
+	* Array-d.cc, Array-f.cc: Provide NaN-safe comparators, override
+	_sortrows_comparator.	
+	* Range.cc (Range::is_sorted): New method.
+	* Range.h: Declare it.
+
+2009-02-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-sort.cc (octave_sort<T>): Rewrite for optimizations. Allow
+	inlined comparison functor and by-the-way indexed sorting.
+	* oct-sort.h (octave_sort<T>): Update interface.
+	* Array.cc (Array<T>::sort): Reflect changes. Use copy & partition
+	mechanism.
+	* Array-d.cc, Array-f.cc, Array-C.cc, Array-fC.cc, Array-s.cc,
+	Array-i.cc: Reflect changes.
+
+2009-02-05  John W. Eaton  <jwe at octave.org>
+
+	* file-stat.cc (base_file_stat::is_sock):
+	Use EXISTS instead of OK in previous change.
+
+	* file-stat.cc (base_file_stat::is_blk, base_file_stat::is_chr,
+	base_file_stat::is_dir, base_file_stat::is_fifo,
+	base_file_stat::is_lnk, base_file_stat::is_reg,
+	base_file_stat::is_sock): Return false if object is not initialized.
+	From Rafael Laboissiere <rafael at debian.org>.
+
+2009-02-05  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* idx-vector.h (idx_vector::idx_colon_rep,
+	idx_vector::idx_scalar_rep, idx_vector::idx_range_rep,
+	idx_vector::idx_vector_rep): Declare allocators.
+	* idx-vector.cc: Define them.
+
+2009-02-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* str-vec.h (string_vector::sort): Remove implementation.
+	* str-vec.cc (string_vector::sort): Move here. Use in-place sorting.
+	* Array-str.cc: Fix order of header files.
+	* oct-sort.cc (octave_sort<T>::merge_hi): std::copy ->
+	std::copy_backward where appropriate.
+
+2009-02-05  John W. Eaton  <jwe at octave.org>
+
+	* Array-util.cc (zero_dims_inquire): Eliminate unused variable MATCH.
+
+	* Sparse.cc (assign (Sparse<LT>& lhs, const Sparse<RT>& rhs)):
+	Eliminate unused variable N.
+
+	* MArray-f.cc (MArray<float>::norm (float p) const,
+	MArray<FloatComplex>::norm (float p) const): Pass P to xnorm.
+
+	* eigs-base.cc (EigsRealNonSymmetricFunc, EigsRealSymmetricFunc)
+	(EigsComplexNonSymmetricFunc): Avoid unused parameter warning.
+	* idx-vector.cc (idx_vector::freeze): Likewise.
+
+2009-02-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-locbuf.h: Specialize OCTAVE_LOCAL_BUFFER to use chunked
+	allocation for pointers and const pointers.
+
+2009-02-03  Benjamin Lindner  <lindnerben at gmx.net>
+	
+	* Makefile.in: Add missing library reference.
+
+2009-02-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::sort (octave_idx_type, sortmode)):
+	Copy array on-the-fly.
+	(Array<T>::sort (Array<octave_idx_type> &, octave_idx_type, sortmode)):
+	Copy array on-the-fly, use bare pointers rather than vec_index.
+
+	* Array-d.cc (Array<double>::sort (octave_idx_type, sortmode)):
+	Copy array on-the-fly.
+	(Array<double>::sort (Array<octave_idx_type> &, octave_idx_type, sortmode)):
+	Copy array on-the-fly, use bare pointers rather than vec_index.
+
+	* Array-f.cc (Array<float>::sort (octave_idx_type, sortmode)):
+	Copy array on-the-fly.
+	(Array<float>::sort (Array<octave_idx_type> &, octave_idx_type, sortmode)):
+	Copy array on-the-fly, use bare pointers rather than vec_index.
+
+2009-02-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (mx_inline_fabs_dup, mx_inline_cabs_dup): New funcs.
+
+	* dMatrix.cc (real, imag, Matrix::abs): Simplify.
+	* fMatrix.cc (real, imag, FloatMatrix::abs): Simplify.
+	* CMatrix.cc (ComplexMatrix::abs, ComplexMatrix::conj): Simplify.
+	* fCMatrix.cc (FloatComplexMatrix::abs, FloatComplexMatrix::conj): Simplify.
+
+	* CMatrix.h, fCMatrix.h (conj): Add missing decl.
+
+	* dNDArray.cc (real, imag, NDArray::abs): Simplify.
+	* fNDArray.cc (real, imag, FloatNDArray::abs): Simplify.
+	* CNDArray.cc (ComplexNDArray::abs, ComplexNDArray::conj): Simplify.
+	* fCNDArray.cc (FloatComplexNDArray::abs, FloatComplexNDArray::conj): Simplify.
+
+	* CMatrix.h, fCMatrix.h (conj): New decl.
+
+2009-01-29  John W. Eaton  <jwe at octave.org>
+
+	* intNDArray.h (intNDArray<T>:any_element_is_nan): New function.
+	* boolNDArrah.h (boolNDArray::any_element_is_nan): New function.
+	* chNDArray.h (charNDArray::any_element_is_nan): New function.
+
+2009-01-28  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (LIBRARIES, install, uninstall): Use SHLLIBPRE
+	and SHLBINPRE library prefixes.
+	From Marco Atzeri <marco_atzeri at yahoo.it>.
+
+2009-01-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dMatrix.cc (Matrix::Matrix (const RowVector&)): Use shallow copy.
+	(Matrix::Matrix (const ColumnVector&)): Ditto.
+	(Matrix::row): Ditto.
+	(Matrix::column): Ditto.
+
+	* fMatrix.cc (FloatMatrix::FloatMatrix (const FloatRowVector&)): Use
+	shallow copy.
+	(FloatMatrix::FloatMatrix (const FloatColumnVector&)): Ditto.
+	(FloatMatrix::row): Ditto.
+	(FloatMatrix::column): Ditto.
+
+	* CMatrix.cc (ComplexMatrix::ComplexMatrix (const ComplexRowVector&)):
+	Use shallow copy.
+	(ComplexMatrix::ComplexMatrix (const ComplexColumnVector&)): Ditto.
+	(ComplexMatrix::row): Ditto.
+	(ComplexMatrix::column): Ditto.
+
+	* fCMatrix.cc (FloatComplexMatrix::FloatComplexMatrix (const FloatComplexRowVector&)):
+	Use shallow copy.
+	(FloatComplexMatrix::FloatComplexMatrix (const FloatComplexColumnVector&)): Ditto.
+	(FloatComplexMatrix::row): Ditto.
+	(FloatComplexMatrix::column): Ditto.
+
+2009-01-27  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* Makefile.in (LINK_DEPS): Include ARPACK_LIBS and REGEX_LIBS in
+	the list.
+
+2009-01-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dbleQR.cc (QR::init): Use form. Use local buffers.
+	Query for optimal block size.
+	(QR::form): New function.
+	* dbleQR.h: Declare it.
+	* dbleQRP.cc (QRP::init):Use form. Use local buffers.
+	Query for optimal block size.
+
+	* floatQR.cc (FloatQR::init): Use form. Use local buffers.
+	Query for optimal block size.
+	(FloatQR::form): New function.
+	* floatQR.h: Declare it.
+	* floatQRP.cc (FloatQRP::init):Use form. Use local buffers.
+	Query for optimal block size.
+
+	* CmplxQR.cc (ComplexQR::init): Use form. Use local buffers.
+	Query for optimal block size.
+	(ComplexQR::form): New function.
+	* CmplxQR.h: Declare it.
+	* CmplxQRP.cc (ComplexQRP::init):Use form. Use local buffers.
+	Query for optimal block size.
+
+	* fCmplxQR.cc (FloatComplexQR::init): Use form. Use local buffers.
+	Query for optimal block size.
+	(FloatComplexQR::form): New function.
+	* fCmplxQR.h: Declare it.
+	* fCmplxQRP.cc (FloatComplexQRP::init):Use form. Use local buffers.
+	Query for optimal block size.
+
+2009-01-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::assign (const idx_vector&, const Array<T>&)):
+	Optimize assignment to an empty array.
+	(Array<T>::assign (const idx_vector&, const idx_vector&, const Array<T>&)):
+	Optimize assignment to an empty array.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array2.h (Array2<T>::index): Declare resize_ok as bool.
+	* ArrayN.h (ArrayN<T>::index): Ditto. Declare index vectors as const
+	refs.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Range.cc (sort_internal): Add missing test.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::index (..., bool resize_ok)):
+	Optimize the all-scalar-indices cases.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dbleQR.h: Optionally declare warn_qrupdate_once.
+	* dbleQR.cc: Define it.
+	* (CmplxQR.h, dbleQR.h, fCmplxQR.h, floatQR.h): Declare replacement
+	methods unconditionally.
+	* (CmplxQR.cc, dbleQR.cc, fCmplxQR.cc, floatQR.cc): Define
+	updating replacement methods.
+	* (CmplxCHOL.h, dbleCHOL.h, fCmplxCHOL.h, floatCHOL.h): Declare
+	replacement methods unconditionally.
+	* (CmplxCHOL.cc, dbleCHOL.cc, fCmplxCHOL.cc, floatCHOL.cc): Define
+	updating replacement methods.
+
+2009-01-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Range.cc ( operator + (double x, const Range& r),
+	operator + (const Range& r, double x),
+	operator - (double x, const Range& r),
+	operator - (const Range& r, double x),
+	operator * (double x, const Range& r),
+	operator * (const Range& r, double x)): New operators.
+	* Range.h: Declare them.
+
+
+2009-01-20  John W. Eaton  <jwe at octave.org>
+
+	* file-stat.h, file-stat.cc (class base_file_stat): New base class.
+	(class file_stat): Derive from base_file_stat.
+	(class file_fstat): New class, derived from base_file_stat.
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* floatQR.h (FloatQR::update, FloatQR::insert_col,
+	FloatQR::insert_row, FloatQR::delete_col, FloatQR::delete_row,
+	FloatQR::shift_col): Update interfaces.
+
+	* floatQR.cc: Update external decls for qrupdate routines.
+	(FloatQR::update, FloatQR::insert_col, FloatQR::insert_row,
+	FloatQR::delete_col, FloatQR::delete_row, FloatQR::shift_col): Reflect
+	changes in qrupdate interfaces, implement batch updates.
+
+	* dbleQR.h (QR::update, QR::insert_col, QR::insert_row,
+	QR::delete_col, QR::delete_row, QR::shift_col): Update interfaces.
+
+	* dbleQR.cc: Update external decls for qrupdate routines.
+	(QR::update, QR::insert_col, QR::insert_row, QR::delete_col,
+	QR::delete_row, QR::shift_col): Reflect changes in qrupdate
+	interfaces, implement batch updates.
+
+	* fCmplxQR.h (FloatComplexQR::update, FloatComplexQR::insert_col,
+	FloatComplexQR::insert_row, FloatComplexQR::delete_col,
+	FloatComplexQR::delete_row, FloatComplexQR::shift_col): Update
+	interfaces.
+
+	* fCmplxQR.cc: Update external decls for qrupdate routines.
+	(FloatComplexQR::update, FloatComplexQR::insert_col,
+	FloatComplexQR::insert_row, FloatComplexQR::delete_col,
+	FloatComplexQR::delete_row, FloatComplexQR::shift_col): Reflect
+	changes in qrupdate interfaces,
+	implement batch updates.
+
+	* CmplxQR.h (ComplexQR::update, ComplexQR::insert_col,
+	ComplexQR::insert_row, ComplexQR::delete_col, ComplexQR::delete_row,
+	ComplexQR::shift_col): Update interfaces.
+
+	* CmplxQR.cc: Update external decls for qrupdate routines.
+	(ComplexQR::update, ComplexQR::insert_col,
+	ComplexQR::insert_row, ComplexQR::delete_col, ComplexQR::delete_row,
+	ComplexQR::shift_col): Reflect changes in qrupdate interfaces,
+	implement batch updates.
+
+	* floatCHOL.h (FloatCHOL::update, FloatCHOL::downdate,
+	FloatCHOL::insert_sym): Update interfaces.
+	* floatCHOL.cc: Update external decls for qrupdate routines.
+	(FloatCHOL::update, FloatCHOL::downdate, FloatCHOL::insert_sym,
+	FloatCHOL::delete_sym, FloatCHOL::shift_sym): Reflect changes in
+	qrupdate interfaces,
+
+	* CHOL.h (CHOL::update, CHOL::downdate, CHOL::insert_sym): Update
+	interfaces.
+	* CHOL.cc: Update external decls for qrupdate routines.
+	(CHOL::update, CHOL::downdate, CHOL::insert_sym, CHOL::delete_sym,
+	CHOL::shift_sym): Reflect changes in qrupdate interfaces,
+
+	* fCmplxCHOL.h (FloatComplexCHOL::update, FloatComplexCHOL::downdate,
+	FloatComplexCHOL::insert_sym): Update interfaces.  
+	* fCmplxCHOL.cc: Update external decls for qrupdate routines.
+	(FloatComplexCHOL::update, FloatComplexCHOL::downdate,
+	FloatComplexCHOL::insert_sym, FloatComplexCHOL::delete_sym,
+	FloatComplexCHOL::shift_sym): Reflect changes in qrupdate interfaces,
+
+	* CmplxCHOL.h (ComplexCHOL::update, ComplexCHOL::downdate,
+	ComplexCHOL::insert_sym): Update interfaces.
+	* CmplxCHOL.cc: Update external decls for qrupdate routines.
+	(ComplexCHOL::update, ComplexCHOL::downdate, ComplexCHOL::insert_sym,
+	ComplexCHOL::delete_sym, ComplexCHOL::shift_sym): Reflect changes in
+	qrupdate interfaces,
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.h (Array<T>): Document internal use of slice_data and
+	slice_len.
+
+2009-01-15  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.cc (Sparse<T>::reshape): Include mismatched dimensions in
+	error message.
+	* Array.cc (Array<T>::reshape): Likewise.
+	From Robert Millan <rmh at aybabtu.com>.
+
+2009-01-14  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* Array.h (Array<T>::rep, Array<T>::dimensions): Make protected.
+	* Array.cc (Array<T>::make_unique): Move implementation here.
+	(Array<T>::fill): Ditto.
+	* DiagArray2.h (DiagArray2<T>): Reimplement without abusing
+	Array<T> internals.
+	(DiagArray2<T>::operator Array2<T>): New method.
+	* DiagArray2.cc (DiagArray2<T>): Update methods.
+	* MDiagArray2.h (MDiagArray2<T>::operator Array2<T>): Simplify.
+	* PermMatrix.h (PermMatrix): Reimplement without abusing
+	Array<T> internals.
+	* PermMatrix.cc (PermMatrix): Update methods.
+
+2009-01-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc, Array.h (all Array<T> constructors): Handle slice_data and
+	slice_len.
+	(Array<T>::Array<T> (const Array<T>&, const dim_vector&,
+	octave_idx_type, octave_idx_type)): New constructor.
+	(Array<T>::index): Use shallow copy when index reduces to a contiguous
+	range.
+	(Array<T>::make_unique): Rewrite.
+	(Array<T>::ArrayRep): Delete redundant methods.
+	(rec_index_helper::is_cont_range): New method.
+	(Array<T>::maybe_economize): New method.
+	* DiagArray2.cc (DiagArray2<T>::resize): Fix the mess.
+
+2008-01-15  Rafael Laboissiere  <rafael at debian.org>
+
+	* oct-md5.cc: Include <cstdio>.
+
+2009-01-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.h (Array::ArrayRep::qsort): Remove.
+	(Array::qsort): Remove.
+	* glob-match.cc (glob_match::glob): qsort -> sort.
+	* str-vec.cc (string_vector::compare): Remove.
+	* str-vec.h (string_vector::compare): Remove decl.
+	(string_vector::qsort): Rename to sort, call Array::sort.
+
+2008-12-23  David Bateman  <dbateman at free.fr>
+
+	* eigs-base.cc: New file with template wrapper for ARPACK.
+	* Makefile.in (TEMPLATE_SRC): Add it here.
+
+2008-12-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (rec_permute_helper): New class.
+	(Array<T>::permute): Rewrite using the recursive algorithm.
+
+2008-12-12  David Bateman  <dbateman at free.fr>
+
+	* sparse-base-chol.cc (inverse): Fix inversion based on cholesky 
+	factorization.
+	
+2008-12-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-locbuf.cc: New source.
+	* oct-locbuf.h (octave_chunk_buffer): New class.
+	(octave_local_buffer): Subclass from octave_chunk_buffer for selected
+	POD types.
+
+2008-12-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-op-defs.h (DMDM_BIN_OP): Fix invalid buffer length.
+
+2008-12-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dMatrix.h, dMatrix.cc (Matrix::expm): Remove.
+	* fMatrix.h, fMatrix.cc (FloatMatrix::expm): Remove.
+	* CMatrix.h, CMatrix.cc (ComplexMatrix::expm): Remove.
+	* fCMatrix.h, fCMatrix.cc (FloatComplexMatrix::expm): Remove.
+
+2008-12-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* base-aepbal.h: New source.
+	* dbleAEPBAL.h, dbleAEPBAL.cc: Rebase AEPBAL on base_aepbal.
+	* floatAEPBAL.h, floatAEPBAL.cc: Rebase FloatAEPBAL on base_aepbal.
+	* CmplxAEPBAL.h, CmplxAEPBAL.cc: Rebase ComplexAEPBAL on base_aepbal.
+	* fCmplxAEPBAL.h, fCmplxAEPBAL.cc: Rebase FloatComplexAEPBAL on base_aepbal.
+
+2008-12-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.cc (idx_vector::idx_vector_rep::idx_vector_rep (const 
+	Sparse<bool>&)): New constructor.
+	* idx_vector.h: Declare it.
+	(idx_vector::idx_vector (const Sparse<bool>&)): New constructor.
+	* idx-vector.cc (idx_vector::idx_vector_rep::idx_vector_rep (const
+	Array<bool>&)): Fix extent calculation.
+
+2008-12-09  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (INCLUDES): Add oct-locbuf.h
+	
+2008-12-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mx-inlines.cc (mx_inline_fill_vs): New template function.
+	* mx-op-defs.h (everywhere): Replace int by octave_idx_type.
+	(MDM_MULTIPLY_OP): Use mx_inline_mul_vs and mx_inline_fill_vs.
+	(DMM_MULTIPLY_OP): Ditto.
+	* fDiagMatrix.cc (operator *): Remove redundant ifs.
+	* fCDiagMatrix.cc (operator *): Remove redundant ifs.
+
+2008-12-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-locbuf.h (OCTAVE_LOCAL_BUFFER_INIT): New macro.
+
+2008-10-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-locbuf.h: New header file.
+	* Array-d.cc, Array-f.cc, Array.cc, CMatrix.cc, CNDArray.cc,
+	CSparse.cc, CmplxCHOL.cc, CmplxGEPBAL.cc, MatrixType.cc,
+	Sparse-op-defs.h, Sparse.cc, SparseCmplxLU.cc, SparseCmplxQR.cc,
+	SparseQR.cc, SparsedbleLU.cc, dMatrix.cc, dNDArray.cc, dSparse.cc,
+	data-conv.cc, dbleCHOL.cc, dbleGEPBAL.cc, fCMatrix.cc, fCNDArray.cc,
+	fCmplxCHOL.cc, fCmplxGEPBAL.cc, fMatrix.cc, fNDArray.cc, file-ops.cc,
+	floatCHOL.cc, floatGEPBAL.cc, lo-sysdep.cc, oct-fftw.cc, oct-md5.cc,
+	oct-rand.cc, regex-match.cc, sparse-dmsolve.cc: Include oct-locbuf.h.
+
+2008-12-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DiagArray2.h (DiagArray2<T>): Inherit Array<T> privately.
+	(DiagArray2<T>::dim1, dim2, rows, columns, cols, length,
+	nelem, numel, byte_size, dims): New methods.
+	(DiagArray2<T>::diag): New method decl.
+	* DiagArray2.cc (DiagArray2<T>::diag): New method.
+	* MDiagArray2.h (MDiagArray2<T>::diag): New method.
+	* dDiagMatrix.cc (DiagMatrix::diag): Remove.
+	* fDiagMatrix.cc (FloatDiagMatrix::diag): Remove.
+	* CDiagMatrix.cc (ComplexDiagMatrix::diag): Remove.
+	* fCDiagMatrix.cc (FloatComplexDiagMatrix::diag): Remove.
+
+	* PermMatrix.h (PermMatrix): Inherit Array<octave_idx_type> privately.
+	(PermMatrix::dim1, dim2, rows, columns, cols, length,
+	nelem, numel, byte_size, dims): New methods.
+
+	
+2008-12-04  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* dDiagMatrix.cc (DiagMatrix::determinant, DiagMatrix::rcond): New
+	method.
+	* dDiagMatrix.h: Declare them.
+	* fDiagMatrix.cc (FloatDiagMatrix::determinant,
+	FloatDiagMatrix::rcond): New methods.
+	* fDiagMatrix.h: Declare them.
+	* CDiagMatrix.cc (ComplexDiagMatrix::determinant,
+	ComplexDiagMatrix::rcond): New methods.
+	* CDiagMatrix.h: Declare them.
+	* fCDiagMatrix.cc (FloatComplexDiagMatrix::determinant,
+	FloatComplexDiagMatrix::rcond): New methods.
+	* fCDiagMatrix.h: Declare them.
+
+2008-12-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.cc (idx-vector::complement): Add missing delete.
+
+2008-12-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dbleQRP.cc (QRP::QRP): Call DGEQP3 rather than DGEQPF.
+	* floatQRP.cc (FloatQRP::FloatQRP): Call SGEQP3 rather than SGEQPF.
+	* CmplxQRP.cc (ComplexQRP::ComplexQRP): Call ZGEQP3 rather than ZGEQPF.
+	* fCmplxQRP.cc (FloatComplexQRP::FloatComplexQRP): Call CGEQP3 rather than CGEQPF.
+
+2008-12-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* PermMatrix.h, PermMatrix.cc: New sources.
+	* MDiagArray2.cc (MDiagArray2<T>::is_multiple_of_identity): New method.
+	* MDiagArray2.h (MDiagArray2<T>::is_multiple_of_identity): Declare it.
+	* idx-vector.cc (idx_vector::is_permutation): New method.
+	* idx-vector.h (idx_vector::is_permutation): Declare it.
+	* base-lu.cc (base_lu::getp): New method.
+	(base_lu::P): Call getp.
+	(base_lu::Pvec): Call getp.
+	* base-lu.h (base_lu): Delcare P as PermMatrix. Remove unused template
+	params.
+	* dbleQRP.cc (dbleQRP::dbleQRP): Construct a permutation matrix.
+	(dbleQRP::Pvec): New method.
+	* dbleQRP.h: Declare new method. Declare P as PermMatrix.
+	* CmplxQRP.cc (ComplexQRP): Likewise.
+	* CmplxQRP.h (ComplexQRP): Likewise.
+	* floatQRP.cc (FloatQRP): Likewise.
+	* floatQRP.h (FloatQRP): Likewise.
+	* fCmplxQRP.cc (FloatComplexQRP): Likewise.
+	* fCmplxQRP.h (FloatComplexQRP): Likewise.
+
+2008-12-01  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DiagArray2.h (DiagArray2<T>::DiagArray2<T> (const DiagArray2<U>&)): New template
+	constructor.
+	(DiagArray2<T>::elem, xelem, operator ()): Move to header file to
+	enable inlining.
+	* DiagArray2.cc (DiagArray2<T>::elem, xelem, operator ()): Remove
+	implementations.
+	* MDiagArray2.h (MDiagArray2<T>::MDiagArray2<T> (const DiagArray2<U>&)): New template
+	constructor.
+	(MDiagArray2<T>::nnz): New method.
+	* MDiagArray2.cc (MDiagArray2<T>::nnz): Implement it.
+
+	* dDiagMatrix.h (DiagMatrix::DiagMatrix (const DiagArray2<U>&)): New template
+	constructor.
+	(DiagMatrix::abs): New method decl.
+	(real (const ComplexDiagMatrix&), imag (const ComplexDiagMatrix&)):
+	New decls.
+	* dDiagMatrix.cc (DiagMatrix::abs): New method.
+	(operator *(const DiagMatrix&, const DiagMatrix&)): Optimize.
+	(real (const ComplexDiagMatrix&), imag (const ComplexDiagMatrix&)):
+	New functions.
+
+	* fDiagMatrix.h (FloatDiagMatrix::FloatDiagMatrix (const DiagArray2<U>&)): New template
+	constructor.
+	(FloatDiagMatrix::abs): New method decl.
+	(real (const FloatComplexDiagMatrix&), imag (const FloatComplexDiagMatrix&)):
+	New decls.
+	* fDiagMatrix.cc (FloatDiagMatrix::abs): New method.
+	(operator *(const FloatDiagMatrix&, const FloatDiagMatrix&)): Optimize.
+	(real (const FloatComplexDiagMatrix&), imag (const FloatComplexDiagMatrix&)):
+	New functions.
+	
+	* CDiagMatrix.h (ComplexDiagMatrix::ComplexDiagMatrix (const DiagArray2<U>&)): New template
+	constructor.
+	(ComplexDiagMatrix::abs): New method decl.
+	(conj (const ComplexDiagMatrix&)): Add missing decl.
+	(ComplexDiagMatrix::all_elements_are_real): New method decl.
+
+	* CDiagMatrix.cc (CDiagMatrix::abs): New method.
+	(operator *(const DiagMatrix&, const ComplexDiagMatrix&)): Optimize.
+	(operator *(const ComplexDiagMatrix&, const DiagMatrix&)): Optimize.
+	(operator *(const ComplexDiagMatrix&, const ComplexDiagMatrix&)): Optimize.
+	(ComplexDiagMatrix::all_elements_are_real): New method.
+
+	* fCDiagMatrix.h (FloatComplexDiagMatrix::FloatComplexDiagMatrix (const DiagArray2<U>&)): New template
+	constructor.
+	(FloatComplexDiagMatrix::abs): New method decl.
+	(conj (const FloatComplexDiagMatrix&)): Add missing decl.
+	(FloatComplexDiagMatrix::all_elements_are_real): New method decl.
+
+	* fCDiagMatrix.cc (CDiagMatrix::abs): New method.
+	(operator *(const FloatDiagMatrix&, const FloatComplexDiagMatrix&)): Optimize.
+	(operator *(const FloatComplexDiagMatrix&, const FloatDiagMatrix&)): Optimize.
+	(operator *(const ComplexDiagMatrix&, const ComplexDiagMatrix&)): Optimize.
+	(FloatComplexDiagMatrix::all_elements_are_real): New method.
+
+	* dSparse.cc (SparseMatrix::SparseMatrix (const DiagMatrix&)): New
+	constructor.
+	* dSparse.h (SparseMatrix::SparseMatrix (const DiagMatrix&)): Declare
+	it.
+
+	* CSparse.cc (SparseComplexMatrix::SparseComplexMatrix (const ComplexDiagMatrix&)): 
+	New constructor.
+	* CSparse.h (SparseComplexMatrix::SparseComplexMatrix (const ComplexDiagMatrix&)): 
+	Declare it.
+	* mx-op-defs.h (DMM_MULTIPLY_OP, MDM_MULTIPLY_OP): Optimize.
+
+2008-11-21  Jarkko Kaleva  <d3roga at gmail.com>
+
+	* EIG.h (EIG::EIG (const Matrix& a, const Matrix& b, 
+	bool calc_eigenvectors = true)): New constructor.
+	(EIG::EIG (const Matrix& a, const Matrix& b, octave_idx_type& info, 
+	bool calc_eigenvectors = true)): New constructor.
+	(EIG::EIG (const ComplexMatrix& a, const ComplexMatrix& b, 
+	bool calc_eigenvectors = true)): New constructor.
+	(EIG::EIG (const ComplexMatrix& a, const ComplexMatrix& b, 
+	octave_idx_type& info, bool calc_eigenvectors = true)): New 
+	constructor.
+	* EIG.cc (EIG::init (const Matrix& a, const Matrix& b, 
+	bool calc_eigenvectors)): New function.
+	(EIG::init (const ComplexMatrix& a, const ComplexMatrix& b, 
+	bool calc_eigenvectors)): New function.
+	(EIG::symmetric_init (const Matrix& a, const Matrix& b, 
+	bool calc_eigenvectors)): New function.
+	(EIG::hermitian_init (const ComplexMatrix& a, const ComplexMatrix& b, 
+	bool calc_eigenvectors)): New function.
+	* fEIG.h (fEIG::fEIG (const FloatMatrix& a, const FloatMatrix& b, 
+	bool calc_eigenvectors = true)): New constructor.
+	(fEIG::fEIG (const FloatMatrix& a, const FloatMatrix& b, 
+	octave_idx_type& info, bool calc_eigenvectors = true)): New 
+	constructor.
+	(fEIG::fEIG (const FloatComplexMatrix& a, const FloatComplexMatrix& b, 
+	bool calc_eigenvectors = true)): New constructor.	
+	(fEIG::fEIG (const FloatComplexMatrix& a, const FloatComplexMatrix& b, 
+	octave_idx_type& info, bool calc_eigenvectors = true)): New 
+	constructor.
+	(fEIG::init (const FloatMatrix& a, const FloatMatrix& b, 
+	bool calc_eigenvectors)): New function.
+	(fEIG::init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, 
+	bool calc_eigenvectors)): New function.
+	(fEIG::symmetric_init (const FloatMatrix& a, const FloatMatrix& b, 
+	bool calc_eigenvectors)): New function.
+	(fEIG::hermitian_init (const FloatComplexMatrix& a, 
+	const FloatComplexMatrix& b, bool calc_eigenvectors)): New function.
+
+2008-11-19  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* dMatrix.cc (Matrix::determinant),
+	fMatrix.cc (FloatMatrix::determinant),
+	CMatrix.cc (ComplexMatrix::determinant),
+	fCMatrix.cc (FloatComplexMatrix::determinant):
+	Use atmp(i,i) instead of elem(i,i).
+
+2008-11-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DET.h (base_det<T>::square): New member function.
+	* dMatrix.cc (Matrix::determinant),
+	fMatrix.cc (FloatMatrix::determinant),
+	CMatrix.cc (ComplexMatrix::determinant),
+	fCMatrix.cc (FloatComplexMatrix::determinant):
+	Allow taking MatrixType argument.
+	* dMatrix.h, fMatrix.h, CMatrix.h, fCMatrix.h: Update decls.
+
+2008-11-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DET.h: New source.
+	* CmplxDET.cc, CmplxDET.h, dbleDET.cc, dbleDET.h, fCmplxDET.cc,
+	fCmplxDET.h, floatDET.cc, floatDET.h: Remove.
+	* Makefile.in: Reflect changes.
+	* mx-defs.h: Remove DET decls.
+	* mx-ext.h, dMatrix.h, fMatrix.h, CMatrix.h, fCMatrix.h,
+	dSparse.h, CSparse.h: Include only DET.h.
+	* dMatrix.cc (Matrix::determinant),
+	fMatrix.cc (FloatMatrix::determinant),
+	CMatrix.cc (ComplexMatrix::determinant),
+	fCMatrix.cc (FloatComplexMatrix::determinant),
+	dSparse.cc (SparseMatrix::determinant),
+	CSparse.cc (SparseComplexMatrix::determinant): Use new class.
+
+2008-11-18  David Bateman  <dbateman at free.fr>
+
+	* file-ops.cc (std::string file_ops::tilde_expand (const 
+	std::string&)): Check if the string contains a tilde and fast 
+	return if not.
+
+2008-11-17  John W. Eaton  <jwe at octave.org>
+
+	* dir-ops.cc (dir_entry::read): Use std::list<std::string> to
+	cache names before converting to string_vector.
+
+2008-11-14  David Bateman  <dbateman at free.fr>
+
+	* Array2.h (Array2<T> Array2<T>::index): Correct use of
+	resize_fill_value.
+
+2008-11-12  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* MArray-C.cc, MArray-d.cc, MArray-f.cc, MArray-fC.cc: Declare
+	MArray<T>::norm specialization before implicit MArray<T> implicit
+	instantiation.
+	* idx-vector.h (class idx_vector::idx_base_rep, class
+	idx_vector::idx_range_rep, class idx_vector::idx_colon_rep, class
+	idx_vector::idx_scalar_rep, class idx_vector::idx_vector_rep): Add
+	OCTAVE_API tag.
+	* idx-vector.cc (idx_vector::idx_scalar_rep::idx_scalar_rep(T),
+	idx_vector::idx_vector_rep::idx_vector_rep(const Array<T>&)): Ditto.
+	* oct-inttypes.cc (octave_int<T>::type_name): Ditto.
+	* oct-inttypes.cc (powf(const octave_int<T>&,const float&)): Cast 'b'
+	to double.
+	* oct-inttypes.h: Undefine min/max.
+	* oct-norm.h (xnorm, xfrobnorm, xcolnorms, xrownorms): Add OCTAVE_API
+	tag.
+	* oct-norm.cc (xnorm, xfrobnorm, xcolnorms, xrownorms): Ditto.
+
+2008-11-12  Jaroslav Hajek <highegg at gmail.com>
+
+	* DiagArray2.h (DiagArray2<T>::maybe_delete_elements): Remove
+	declaration.
+
+2008-11-09  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-norm.cc: Don't include Array.cc.  
+	(column_norms (const MArray2<T>&, ...)): Use std::vector instead of Array<T> for
+	accumulator containers. Use empty constructor instead of
+	Array<T>::resize.
+	(row_norms (const MArray2<T>&, ...)): Ditto.
+	(column_norms (const MSparse2<T>&, ...)): Ditto.
+	(row_norms (const MSparse2<T>&, ...)): Ditto.
+
+2008-10-31  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-norm.h: New header file.
+	* oct-norm.cc: New source.
+	* CSparse.cc (SparseComplexMatrix::row, SparseComplexMatrix::column):
+	New member functions.
+	* CSparse.h (SparseComplexMatrix): Declare them.
+	* dSparse.cc (SparseMatrix::row, SparseMatrix::column):
+	New member functions.
+	* dSparse.h (SparseMatrix): Declare them.
+	* MArray-C.cc (MArray<Complex>::norm), 
+	MArray-d.cc (MArray<double>::norm), 
+	MArray-fC.cc (MArray<FloatComplex>::norm), 
+	MArray-f.cc (MArray<float>::norm): Wrap a call to xnorm. 
+
+	* MArray-defs.h (MARRAY_NORM_BODY): Remove.
+
+2008-11-02  Jaroslav Hajek <highegg at gmail.com>
+
+	* idx-vector.cc (idx_vector::is_complement): Set resulting extent
+	correctly.
+	* Array.cc (Array<T>::delete_elements (int, const idx_vector&)):
+	Fix check for invalid dim.
+
+2008-10-31  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.h (idx_vector::idx_range_rep::extent): Don't change
+	extent when len is zero.
+	* idx-vector.h (idx_vector::idx_range_rep::idx_range_rep (void)):
+	Create empty range by default.
+
+2008-10-30  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-inttypes.h (octave_int_abs): New function.
+	(octave_int_arith_base<T, true>::div): Use octave_int_abs instead of
+	std::abs.
+	* oct-inttypes.cc (octave_int_arith_base<int64_t, true>): Ditto.
+
+2008-10-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* Array-C.cc Array-d.cc Array-f.cc Array-fC.cc Array-i.cc Array-s.cc:
+	Don't use semicolon after INSTANTIATE_ARRAY_ASSIGN.
+	* Array-util.h (zero_dims_inquire): New declarations.
+	(is_in, how_many_lgt, short_freeze): Remove declarations.
+	* Array-util.cc (zero_dims_inquire): New functions.
+	(is_in, how_many_lgt, short_freeze): Remove functions.
+	* Array.cc (Array<T>::index, Array<T>::resize_fill, Array<T>::resize,
+	Array<T>::assign, Array<T>::delete_elements):
+	Rewrite.
+	* Array.h (Array<T>::index, Array<T>::resize_fill, Array<T>::resize,
+	Array<T>::assign, Array<T>::delete_elements):
+	Rewrite interfaces.
+	* Array2.h (Array2<T>::resize): Call Array<T>::resize_fill.
+	* Array3.h (Array3<T>::resize): Call Array<T>::resize_fill.
+	* ArrayN.h (ArrayN<T>::resize): Remove declarations.
+	(ArrayN<T>::index): Fix call to resize_fill_value.
+	* Sparse.cc (assign, assign1): Use zero-based indices.
+	* chMatrix.h: Include mx-op-defs.h
+	* dim-vector.h (dim_vector::any_neg, dim_vector::chop_all_singletons,
+	dim_vector::redim): New member functions.
+	* idx-vector.cc: Mostly rewrite.
+	* idx-vector.h: Mostly rewrite.
+
+2008-10-29  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* lo-specfun.cc (cbesj, cbesy, cbesi, cbesk, cbesh1, cbesh2): Do not
+	use std::complex::real() and std::complex::imag() as l-value, this is
+	not supported under MSVC.
+
+2008-10-28  John W. Eaton  <jwe at octave.org>
+
+	* lo-specfun.cc: Fix prototypes for the Fortran subroutines cbesh,
+	cbesi, cbesj, cbesk, and cbesy.
+	(cbesh, cbesi, cbesj, cbesk, cbesy): Fix calls to Fortran
+	subroutines.
+
+2008-10-28  Brian Gough  <bjg at gnu.org>
+
+	* lo-specfun.cc (zbesi): Fix scaling factor for negative alpha.
+	(cbesi): Likewise.
+
+2008-10-23  John Swensen  <jpswensen at comcast.net>
+
+	* oct-shlib.cc (octave_dyld_shlib::open): Call NSLinkEditError to
+	get better diagnostic if NSLinkModule fails.
+
+2008-10-23  John W. Eaton  <jwe at octave.org>
+
+	* oct-shlib.cc (octave_dlopen_shlib::open): Use RTLD_NOW instead
+	of RTLD_LAZY.
+
+2008-10-12  Jaroslav Hajek <highegg at gmail.com>
+
+	* CSparse.cc (ComplexMatrix::expm): Improve inverse preconditioning
+	according to Marco Caliari.
+	* dSparse.cc (Matrix::expm): Likewise.
+	* fCSparse.cc (FloatComplexMatrix::expm): Likewise.
+	* fSparse.cc (FloatMatrix::expm): Likewise.
+
+2008-10-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* sparse-util.h (SparseCholPrint): Change char * argument to const
+	char *.
+	* sparse-util.cc (SparseCholPrint): Likewise.
+
+2008-10-09  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-sort.cc (octave_sort<T>::merge_getmem,
+	octave_sort<T>::merge_freemem): Replace malloc -> new [], free ->
+	delete [].
+	(octave_sort<T>::merge_lo, octave_sort<T>::merge_hi): Replace
+	std::memcpy and std::memmove with std::copy.
+
+2008-10-08  John W. Eaton  <jwe at octave.org>
+
+	* Sparse-op-defs.h (SPARSE_SMSM_BOOL_OPS): Duplicate code for scalar
+	sparse arguments rather than rely on extern function.
+
+2008-10-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.h (octave_base_int<T>::compute_threshold): Return
+	exclusive bounds rather than inclusive, be resistant to compiler
+	optimizations.
+	(octave_base_int<T>::convert_real): Use exclusive bounds.
+
+2008-10-07  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-inttypes.h (OCTAVE_INT_DOUBLE_BIN_OP): Change octave_int64 to 
+	octave_uint64 where appropriate.
+
+2008-10-06  David Bateman  <dbateman at free.fr>
+	
+	* Sparse-op-defs.h (SPARSE_SMSM_CMP_OPS): Duplicate code for scalar
+	sparse arguments rather than rely on extern function.
+
+2008-10-06  John W. Eaton  <jwe at octave.org>
+
+	* Spasre-op-defs.h: Undo previous change.
+
+2008-10-01  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-inttypes.h (octave_int<T>::one, octave_int<T>::zero): Declare
+	constants. 
+	* oct-inttypes.cc: Define them.
+	* oct-inttypes.h: Define mixed operations via long double if possible.
+	* oct-inttypes.cc: Define alternative implementations for 64-bit
+	multiplication and mixed operations. 
+	* mx-ops: Instantiate all 64-bit integer operations.
+
+2008-10-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-lookup.h: Mark functions inline. Add missing std:: qualifiers.
+
+2008-10-06  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.h (Sparse<T>::elt_type): New typedef.
+	* Sparse-op-defs.h (SPARSE_SMSM_BOOL_OP, SPARSE_MSM_CMP_OP):
+	Use it to call sparse-matrix/scalar operator instead of attempting
+	to instantiate mixed-type sparse-matrix/scalar operators.
+
+2008-10-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.h (Array<T>::maybe_delete_elements): Remove rfv argument from
+	declaration.
+	* Array.cc (Array<T>::maybe_delete_elements): Remove all usages of
+	rfv.
+
+2008-10-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (assignN): Do not call maybe_delete_elements when
+	for empty matrix.
+
+2008-09-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.h: Mostly rewrite. 
+	* oct-inttypes.cc: Modstly rewrite.
+
+2008-09-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (Array<T>::maybe_delete_elements_2(idx_vector&)): Return on
+	empty index vector.
+
+2008-09-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (assign1, assign2, assignN): Do not call
+	maybe_delete_elements.
+	(maybe_delete_elements (Array<idx_vector>&)): Call the 1D and 2D
+	special handlers if possible.
+	* Sparse.cc (assign1, assign2, assignN): Do not call
+	maybe_delete_elements.
+
+2008-09-22  Brian Gough  <bjg at gnu.org>
+
+	* oct-rand.cc (initialize_mersenne_twister): Use separate
+	initializations for each generator to avoid correlation.
+
+2008-09-12  Jaroslav Hajek  <highegg at gmail.com>
+ 
+ 	* oct-inttypes.h (pow (const octave_int<T>&, const octave_int<T>&)): 
+
+2008-09-19  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign1, assign2, assignN):
+	Clear lhs index before throwing error.
+	(Array<T>::value): Clear index before throwing error.
+
+2008-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (maybe_delete_elements_2 (idx_vector&)): Fix tests to get
+	better Matlab compatibility.
+	(maybe_delete_elements (idx_vector&, idx_vector&)): Fix tests to get
+	better Matlab compatibility, simplify, gripe on invalid 2-D deletion.
+
+2008-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.h (Array<T>::coerce): Use octave_idx_type instead of int.
+
+2008-09-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.h (pow (const octave_int<T>&, const octave_int<T>&)): 
+	Handle negative exponent correctly.
+
+2008-08-19  David Bateman  <dbateman at free.fr>
+
+	* oct-inttypes.h (template <class T1, class T2> inline T2
+	octave_int_fit_to_range (const T1&, const T2&, const T2&),
+	template <typename T> inline T octave_int_fit_to_range (const
+	double&, const T&, const T&), template <> inline T2
+	octave_int_fit_to_range<T1, T2> (const T1&, const T2&, const T2&),
+	OCTAVE_S_US_FTR): Check and flag integer trunctation.
+	(OCTAVE_INT_FIT_TO_RANGE, OCTAVE_INT_FIT_TO_RANGE2): Adapt for the
+	above change.
+	(OCTAVE_INT_CONV_FIT_TO_RANGE): New macro for conversion to
+	integer types.
+	(octave_int<T>::conv_error_type): New enum to flag conversion and
+	math warnings.
+	(octave_int<T>::octave_int (U i), octave_int<T>::octave_int
+	(double i), octave_int<>::octave_int (const octave_int<U>& i)):
+	Flag conversion and math errors other than integer truncation.
+	(octave_int<T> octave_int<T>::operator - (void)): Flag truncation
+	error.
+	(static bool get_trunc_flag (void), static bool clear_trunc_flag
+	(void, static bool trunc_flag)): Delete.
+	(static int get_conv_flag (void), static bool get_trunc_flag (void),
+	static bool get_nan_flag (void), static bool get_non_int_flag (void),
+	static bool get_math_trunc_flag (void), static void
+	clear_conv_flag (void)): New functions to query and reset
+	conversion and mathw arning state.
+	(static int cov_flag): New parameter holding current conversion
+	and math warning state. Set it to zero.
+	(template <class T> octave_int<T> powf (float, const
+	octave_int<T>&), template <class T> octave_int<T> powf (const
+	octave_int<T>&, float)): New functions.
+
+2008-08-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* lo-ieee.cc (octave_ieee_init): Try to ensure that octave_NaN is
+	classified as positive by lo_ieee_signbit.
+
+2008-08-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array.cc (no_op_fcn): New static function.
+	(Array<T>::hermitian): If fcn is null, set to no_op_fcn.
+
+2008-08-07  John W. Eaton  <jwe at octave.org>
+
+	* sprse-base-chol.h, oct-sparse.h: Don't include config.h.
+
+	* cmd-edit.cc, file-ops.h, kpse.cc, oct-env.cc, pathsearch.cc:
+	Replace all uses of NPOS with std::string::npos.
+
+	* fCmplxLU.h, CmplxLU.h: Fix typo in definition of
+	multiple-inclusion guard macro.
+
+2008-08-05  John W. Eaton  <jwe at octave.org>
+
+	* file-ops.h, file-ops.cc (file_ops::static_members):
+	New singleton class for static members of file_ops.
+
+	* pathsearch.h, pathsearch.cc (class dir_path::static_members):
+	New singleton class for static members of dir_path.
+
+	* pathsearch.cc (dir_path::init): Move octave_kpathsea_initialized
+	here from file scope.
+
+2008-08-04  John W. Eaton  <jwe at octave.org>
+
+	* oct-env.cc (octave_env::do_set_program_name,
+	octave_env::do_base_pathname): Fix usage of
+	file_ops::dir_sep_chars.
+	(octave_env::do_make_absolute): Fix usage of
+	file_ops::dir_sep_chars and file_ops::dir_sep_str.
+	(octave_env::do_get_home_directory): Fix usage of
+	file_ops::dir_sep_str.
+
+	* file-ops.h (file_ops::do_is_dir_sep): New function.
+	(file_ops_::is_dir_sep): Call it.
+	* file-ops.cc (class file_ops): Make it a proper singleton object.
+	(file_ops::file_ops): New constructor.
+	(file_ops::instance_ok): New function.
+	(file_ops::xdir_sep_char): Now private.  No longer static.  Rename
+	from dir_sep_char.
+	(file_ops::xdir_sep_str): Likewise, from dir_sep_str.
+	(file_ops::xdir_sep_chars): Likewise, from dir_sep_chars.
+	(file_ops::dir_sep_char, file_ops::dir_sep_str,
+	file_ops::dir_sep_chars): New functions.
+	(file_ops::recursive_rmdir): Fix usage of file_ops::dir_sep_str.
+	(file_ops::concat): Fix usage of file_ops::dir_sep_char.
+
+	* oct-env.cc (octave_env::instance_ok): Fix typo in error message.
+
+2008-07-30  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h: Style fixes.
+
+2008-07-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-inttypes.h (octave_int<T>::trunc_flag): New member static field.
+	(octave_int<T>::get_trunc_flag, octave_int<T>::clear_trunc_flag): New
+	member functions.
+	(octave_int<T>::octave_int (const octave_int<U>&)): set trunc_flag
+	on truncation.
+	(SPECIALIZE_WIDENING_CONVERSION): New macro.
+	(DECLARE_OCTAVE_INT_TYPENAME): New macro.
+
+2008-07-29  David Bateman  <dbateman at free.fr>
+
+	* lo-ieee.h (LO_IEEE_NA_HW, LO_IEEE_NA_LW, LO_IEEE_NA_FLOAT):
+	Change definition so cast from single to double and visa versa
+	maintains NA value.
+	(LO_IEEE_NA_HW_OLD, LO_IEEE_NA_LW_OLD): Keep old values.
+	(extern OCTAVE_API int __lo_ieee_is_old_NA (double)): Function to
+	detect old NA value.
+	(extern OCTAVE_API double __lo_ieee_replace_old_NA (double)):
+	Function to replace old NA value with new new.
+	* lo-cieee.c (int __lo_ieee_is_old_NA (double)): Function to
+	detect old NA value.
+	(double __lo_ieee_replace_old_NA (double)): Function to replace
+	old NA value with new new.
+	* data-conv.cc (void read_doubles(std::istream&, double *, 
+	save_type, int, bool, octave_mach_info::float_format)): Test if
+	loaded NA values is the old representation and replace it.
+	
+2008-07-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* lo-math.h: Ensure log2 is undefined from cmath in C++ mode.
+
+2008-07-21  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* oct-mutex.h (octave_base_mutex::octave_base_mutex): Initialize
+	count to 1, not -1.
+
+	* oct-mutex.cc (octave_base_mutex::lock, octave_base_mutex::unlock):
+	Replace error calls with (*current_liboctave_error_handler).
+
+2008-07-21  John W. Eaton  <jwe at octave.org>
+
+	* regex-match.cc (regex_match::init): Initialize err to 0.
+
+2008-07-19  John W. Eaton  <jwe at octave.org>
+
+	* oct-mutex.h (class octave_base_mutex): New class.
+	(class octave_mutex): Don't use union for rep and count.
+	(octave_mutex::rep): Declare as octave_base_mutex.
+	(octave_mutex::count): Delete.
+	(octave_mutex::lock, octave_mutex::unlock): No longer virtual.
+	(octave_mutex::~octave_mutex): No need to check that rep is
+	valid or set rep to zero after deleting.
+	(octave_mutex::operator =): No need to check that rep is valid.
+	* oct-mutex.cc (octave_w32_mutex, octave_pthread_mutex): Derive
+	from octave_base_mutex, not octave_mutex.
+
+2008-07-18  John W. Eaton  <jwe at octave.org>
+
+	* oct-mutex.h (octave_mutex::octave_mutex (int)): Initialize rep
+	to 0, not count.
+	* oct-mutex.cc (octave_mutex::octave_mutex (void)): Set rep->count
+	to 1 instead of incrementing it.
+
+2008-07-17  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* dNDArray.cc: Do not include ctor NDArray(Array<octave_idx_type>,
+	bool, bool) into conditional HAVE_FFTW3 preprocessor statement.
+
+2008-07-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-mutex.h (octave_autolock::octave_autolock (void),
+	octave_autolock (const octave_autolock&),
+	octave_autolock::operator = (const octave_autolock&)):
+	Delete definitions.
+
+2008-07-16  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* cmd-edit.cc (event_hook_lock): New static mutex variable.
+	(command_editor::event_handler): Lock and copy event_hook_set before
+	executing handlers.
+	(command_editor::add_event_hook, command_editor::remove_event_hook):
+	Autolock event_hook_lock.
+
+2008-07-15  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* oct-mutex.h, oct-mutex.cc: New files.
+	* Makefile.in: Add them to appropriate lists.
+
+2008-07-15  John W. Eaton  <jwe at octave.org>
+
+	* oct-sort.cc, oct-sort.h (octave_sort<T>::count_run): Declare
+	descending arg as bool&.
+	(octave_sort<T>::sort): Pass bool to count_run for descending arg.
+
+2008-07-11  John W. Eaton  <jwe at octave.org>
+
+	* dDiagMatrix.cc (DiagMatrix::diag): Return empty ColumnVector if
+	number of rows or columns is 0.
+	* fDiagMatrix.cc (FloatDiagMatrix::diag): Likewise.
+
+	* Array-util.cc (is_vector): Avoid GCC warning.
+	* Array-f.cc (Array<float>::sort): Likewise.
+	* Array-d.cc (Array<double>::sort): Likewise.
+	* dbleQR.cc (QR::QR (const Matrix&, const Matrix&)): Likewise.
+	* CmplxQR.cc (ComplexQR::ComplexQR (const ComplexMatrix&, const
+	ComplexMatrix&)): Likewise.
+	* floatQR.cc (FloatQR::FloatQR (const FloatMatrix&, const
+	FloatMatrix&)): Likewise.
+	* fCmplxQR.cc (FloatComplexQR::FloatComplexQR (const
+	FloatComplexMatrix&, const FloatComplexMatrix&)): Likewise.
+	* Quad.cc (IndefQuad::do_integrate (octave_idx_type&,
+	octave_idx_type&, float&), FloatIndefQuad::do_integrate,
+	DefQuad::do_integrate octave_idx_type&, octave_idx_type&, float&,
+	FloatIndefQuad::do_integrate): Likewise.
+
+	* mx-op-defs.h (MS_BOOL_OP, SM_BOOL_OP, MM_BOOL_OP, NDS_BOOL_OP,
+	SND_BOOL_OP, NDND_BOOL_OP): Detect NaN values.
+	* Array-util.cc (gripe_nan_to_logical_conversion): New function.
+	* Array-util.h: Provide decl.
+	* oct-inttypes.h (xisnan (octave_int<T>)): New function.
+	* lo-mappers.h (xisnan (bool), xisnan (char)): New inline functions.
+
+	* CMatrix.cc, CNDArray.cc, CSparse.cc, dMatrix.cc, dNDArray.cc,
+	dSparse.cc, fCMatrix.cc, fCNDArray.cc, fMatrix.cc, fNDArray.cc:
+	New member function, any_element_is_nan.
+	* CMatrix.h, CNDArray.h, CSparse.h, dMatrix.h, dNDArray.h,
+	dSparse.h, fCMatrix.h, fCNDArray.h, fMatrix.h, fNDArray.h:
+	Provide decl.
+
+2008-07-10  David Bateman  <dbateman at free.fr>
+
+	* dNDArray.cc (NDArray::NDArray (const Array<octave_idx_type>&,
+	bool, bool)): New constructor.
+	* dNDArray.h: Provide decl.
+
+2008-07-10  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* lo-specfun.h: Fix typo in erff/erfcf declaration.
+	* lo-specfun.cc: Ditto. Add atanhf implementation.
+
+2008-06-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* MatrixType.h: Add missing include statement.
+
+2008-06-13  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* lo-mappers.cc (arg): Remove ambiguity about atan2(float,float) usage.
+	* fCmplxDET.cc (FloatComplexDET::initialize10): Likewise, for pow.
+
+2008-06-11  John W. Eaton  <jwe at octave.org>
+
+	* so-array.h, so-array.cc, Array-so.cc: Delete.
+	* Makefile.in: Remove them from the lists.
+
+2008-06-05  John W. Eaton  <jwe at octave.org>
+
+	* oct-shlib.cc (octave_base_shlib::remove): Only dereference
+	counter if iterator is valid.
+
+2008-06-02  David Bateman  <dbateman at free.fr>
+
+	* fCmplxDET.cc (FloatComplexDET::value_will_overflow,
+	FloatComplexDET:value_will_underflow): Replace DBL_MIN and DBL_MAX
+	with FLT_MIN and FLT_MAX.
+	* floatDET.cc ((FloatDET::value_will_overflow,
+	FloatDET:value_will_underflow): Ditto.
+	* lo-cieee.c (__lo_ieee_float_is_NA): Check only a sngle word for
+	float NA value.
+	(lo_ieee_float_inf_value): Return correct float Infinity value.
+	(lo_ieee_float_NA_value): Return correct float NA value.
+	(lo_ieee_float_NaN_value): Return correct float NaN value.
+	* lo-ieee.cc (octave_ieee_init): Set float NA value correctly.
+	* lo-ieee.h (lo_ieee_float): value of union is of type float.
+	(LO_IEEE_NA_FLOAT): Make NA value a valid float NaN.
+	(LO_IEEE_NA_FLOAT_LW): Delete.
+
+2008-06-02  David Bateman  <dbateman at free.fr>
+
+	* fCmplxLU.cc (class FloatComplexLU): Correct error in instantiation.
+	* floatLU.cc (class FloatLU): ditto.
+	* floatLU.h (class FloatLU): ditto.
+	
+	* floatAEPBAL.cc (octave_idx_type FloatAEPBALANCE::init (const
+	FloatMatrix&, const std::string&)): Use FloatMatrix to initialize
+	balancing_mat.
+
+	* Makefile.in (MATRIX_INC): Add fCmplxAEPBAL.h and floatAEPBAL.h.
+	(MATRIX_SRC): Add fCmplxAEPBAL.cc and floatAEPBAL.cc.
+
+2008-05-21  David Bateman  <dbateman at free.fr>
+
+	* Quad-opts.in: Handle single precision tolerances.
+	* Quad.cc (float_user_fcn): New static variable.
+	(quad_float_fcn_ptr): New typedef.
+	(qagp, quagi): New QUADPACK decls.
+	(float_user_function): New function.
+	(DefQuad::do_integrate, IndefQuad::do_integrate): Float versions.
+	(FloatDefQuad::do_integrate, FloatIndefQuad::do_integrate):
+	New functions.
+	* Quad.h (class Quad): Handle float type.
+	(class FloatDefQuad, class FloatIndefQuad): New classes.
+
+2008-05-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* fCMatrix.h (xgemm): Provide decl.
+	(xcdotc, csyrk, cherk): New F77 decls.
+	* fMatrix.cc (xgemm): New function.
+	(operator * (const FloatMatrix&, const FloatMatrix&)): Simplify.
+	(get_blas_trans_arg): New function.
+	* fCMatrix.h (xgemm): Provide decl.
+	(ssyrk): New F77 decl.
+	* fCMatrix.cc (xgemm): New function.
+	(operator * (const FloatComplexMatrix&, const
+	FloatComplexMatrix&)): Simplify.
+	(get_blas_trans_arg): New function.
+
+	* dMatrix.cc, CMatrix.cc, Sparse-op-defs.h: Add missing copyright.
+
+	* Sparse-op-defs.h (SPARSE_FULL_MUL): Simplify scalar*matrix case.
+	Correct indenting. 
+	(SPARSE_FULL_TRANS_MUL): New macro.
+	(FULL_SPARSE_MUL): Simplify scalar*matrix case. Correct indenting.
+	Move OCTAVE_QUIT one level up.
+	(FULL_SPARSE_MUL_TRANS): New macro.
+	* dSparse.h (mul_trans, trans_mul): Provide decl.
+	* dSparse.cc (mul_trans, trans_mul): New functions.
+	* CSparse.h (mul_trans, trans_mul, mul_herm, herm_mul): Provide decl.
+	* CSparse.cc (mul_trans, trans_mul, mul_herm, herm_mul): New functions.
+
+	* dMatrix.h (xgemm): Provide decl.
+	* dMatrix.cc (xgemm): New function.
+	(operator * (const Matrix&, const Matrix&)): Simplify.
+	(get_blas_trans_arg): New function.
+	* CMatrix.h (xgemm): Provide decl.
+	* CMatrix.cc (xgemm): New function.
+	(operator * (const ComplexMatrix&, const ComplexMatrix&)): Simplify.
+	(get_blas_trans_arg): New function.
+
+	* MatrixType.cc (matrix_real_probe, matrix_complex_probe):
+	New template functions.
+	(MatrixType::MatrixType (const Matrix&),
+	MatrixType::MatrixType (const FloatMatrix&)):
+	just call matrix_real_probe.
+	(MatrixType::MatrixType (const ComplexMatrix&),
+	MatrixType::MatrixType (const FloatComplexMatrix&)):
+	just call matrix_complex_probe.
+
+	* MatrixType.cc (MatrixType::MatrixType (matrix_type, bool)):
+	add missing test for Unknown.
+
+2008-05-21  David Bateman  <dbateman at free.fr>
+
+	* fCMatrix.cc (float rcond): Replace with float rcon everywhere
+	to avoid shadowed variable warning
+	(float ComplexMatrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(float ComplexMatrix::rcond (MatrixType &mattype) const): ditto.
+	* fCMatrix.h (float rcond):  Replace with float rcon everywhere
+	to avoid shadowed variable warning
+	(float ComplexMatrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(float ComplexMatrix::rcond (MatrixType &mattype) const): ditto.
+	* fMatrix.cc (float rcond): Replace with float rcon everywhere
+	to avoid shadowed variable warning
+	(float Matrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(float Matrix::rcond (MatrixType &mattype) const): ditto.
+	* fMatrix.h (float rcond):  Replace with float rcon everywhere
+	to avoid shadowed variable warning
+	(float Matrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(float Matrix::rcond (MatrixType &mattype) const): ditto.
+
+	* Array.cc: Fix transpose tests.
+
+	* CmplxGEBAL.cc (ComplexGEPBALANCE), dbleGEPBAL.cc (GEPBALANCE),
+	fCmplxGEPBAL.cc (FloatComplexGEPBALANCE), floatGEPBAL.cc
+	(FloatGEPBALANCE): New class for generalized eigenvalue balancing.
+	* CmplxGEBAL.h (ComplexGEPBALANCE), dbleGEPBAL.h (GEPBALANCE),
+	fCmplxGEPBAL.h (FloatComplexGEPBALANCE), floatGEPBAL.h
+	(FloatGEPBALANCE): Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+	
+	* floatAEPBAL.cc (FloatAEPBALANCE), fCmplxAEPBAL.cc
+	(FloatComplexAEPBALANCE): New classes for single precision 
+	Algebraic eignvalue balancing.
+	* floatAEPBAL.h (FloatAEPBALANCE), fCmplxAEPBAL.h
+	(FloatComplexAEPBALANCE): Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* floatHESS.cc (FloatHESS), fCmplxHESS.cc (FloatComplexHESS):  New
+	classes for single precision Hessenberg decomposition.
+	* floatHESS.h (FloatHESS), fCmplxHESS.h (FloatComplexHESS):
+	Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* floatQR.cc (FloatQR), fCmplxQR.cc (FloatComplexQR):  New
+	classes for single precision QR decomposition.
+	* floatQR.h (FloatQR), fCmplxQR.h (FloatComplexQR):
+	Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* floatQRP.cc (FloatQRP), fCmplxQRP.cc (FloatComplexQRP):  New
+	classes for single precision permuted QR decomposition.
+	* floatQRP.h (FloatQRP), fCmplxQRP.h (FloatComplexQRP):
+	Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* mx-defs (FloatAEPBALANCE, FloatComplexAEPBALANCE,
+	ComplexGEPBALANCE, FloatGEPBALANCE,FloatComplexGEPBALANCE,
+	FloatHESS, FloatComplexHESS, FloatQR, FloatComplexQR, QRP,
+	ComplexQRP, FloatQRP, FloatComplexQRP):	Declare classes.
+	
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (Array<T> Array<T>::transpose () const): Modify for tiled
+	transpose to limit the number of cache misses.
+	(Array<T> Array<T>::hermitian (T (*)(const&)) const): New method
+	for matrix conjugate transpose.
+	* Array.h (Array<T> hermitian (T (*)(const&)) const): Declare it.
+
+	* DiagArray2.cc (DiagArray2<T> DiagArray2<T>::transpose () const):
+	Specialization for diagonal arrays.
+	(DiagArray2<T> DiagArray2<T>::transpose (T (*) (const&)) const):
+	Ditto.
+	
+	* MArray.h (MArray<T> hermitian <T (*) (const&)) const): New method.
+	(MArray<T> transpose () const): Ditto.
+	* MArray2.h (MArray2<T> hermitian <T (*) (const&)) const): Ditto.
+	* Array2.h (Array2<T> hermitian <T (*) (const&)) const): Ditto.
+	* ArrayN.h (ArrayN<T> hermitian <T (*) (const&)) const): Ditto.
+	* MDiagArray2.h (MDiagArray2<T> transpose () const): Ditto.
+	(MDiagArray<T> hermitian <T (*) (const&)) const): Ditto.
+
+	* CColVector.cc (transpose, hermitian): Define in terms of base class.
+	* CRowVector.cc (transpose, hermitian): Ditto.
+	* dColVector.cc (transpose): Ditto.
+	* dRowVector.cc (transpose): Ditto.
+	* CDiagMatrix.h (transpose, hermitian): Ditto.
+	* dDiagMatrix.h (transpose): Ditto.
+
+	* fCColVector.cc (transpose, hermitian): Define in terms of base class.
+	* fCRowVector.cc (transpose, hermitian): Ditto.
+	* fColVector.cc (transpose): Ditto.
+	* fRowVector.cc (transpose): Ditto.
+	* fCDiagMatrix.h (transpose, hermitian): Ditto.
+	* fDiagMatrix.h (transpose): Ditto.
+
+	* CDiagMatrix.cc (ComplexDiagMatrix::transpose,
+	ComplexDiagMatrix::hermitian): Delete.
+	* dDiagMatrix.cc (DiagMatrix::transpose): Ditto.
+	* CMatrix.cc (ComplexMatrix::hermitian): Ditto.
+
+	* fCDiagMatrix.cc (FloatComplexDiagMatrix::transpose,
+	FloatComplexDiagMatrix::hermitian): Delete.
+	* fDiagMatrix.cc (FloatDiagMatrix::transpose): Ditto.
+	* fCMatrix.cc (FloatComplexMatrix::hermitian): Ditto.
+
+	* lo-mappers.cc (FloatComplex xlog2(const FloatComplex&), float
+	xlog2 (flot, int&), FloatComplex xlog2(const FloatComplex&, int&)):
+	New mapper functions for single precion values.
+	* lo-mappers.h (FloatComplex xlog2(const FloatComplex&), float
+	xlog2 (flot, int&), FloatComplex xlog2(const FloatComplex&, int&)):
+	Declare them.
+	
+	* CmplxGEBAL.cc (ComplexGEPBALANCE), dbleGEPBAL.cc (GEPBALANCE),
+	fCmplxGEPBAL.cc (FloatComplexGEPBALANCE), floatGEPBAL.cc
+	(FloatGEPBALANCE): New class for generalized eigenvalue balancing.
+	* CmplxGEBAL.h (ComplexGEPBALANCE), dbleGEPBAL.h (GEPBALANCE),
+	fCmplxGEPBAL.h (FloatComplexGEPBALANCE), floatGEPBAL.h
+	(FloatGEPBALANCE): Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+	
+	* floatAEPBAL.cc (FloatAEPBALANCE), fCmplxAEPBAL.cc
+	(FloatComplexAEPBALANCE): New classes for single precision 
+	Algebraic eignvalue balancing.
+	* floatAEPBAL.h (FloatAEPBALANCE), fCmplxAEPBAL.h
+	(FloatComplexAEPBALANCE): Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* floatHESS.cc (FloatHESS), fCmplxHESS.cc (FloatComplexHESS):  New
+	classes for single precision Hessenberg decomposition.
+	* floatHESS.h (FloatHESS), fCmplxHESS.h (FloatComplexHESS):
+	Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* floatQR.cc (FloatQR), fCmplxQR.cc (FloatComplexQR):  New
+	classes for single precision QR decomposition.
+	* floatQR.h (FloatQR), fCmplxQR.h (FloatComplexQR):
+	Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* floatQRP.cc (FloatQRP), fCmplxQRP.cc (FloatComplexQRP):  New
+	classes for single precision permuted QR decomposition.
+	* floatQRP.h (FloatQRP), fCmplxQRP.h (FloatComplexQRP):
+	Declare them.
+	* Makefile.in (MATRIX_INC): Include them here.
+	(MATRIX_SRC): and here.
+
+	* mx-defs (FloatAEPBALANCE, FloatComplexAEPBALANCE,
+	ComplexGEPBALANCE, FloatGEPBALANCE,FloatComplexGEPBALANCE,
+	FloatHESS, FloatComplexHESS, FloatQR, FloatComplexQR, QRP,
+	ComplexQRP, FloatQRP, FloatComplexQRP):	Declare classes.
+	
+	* Array-f.cc, Array-fC.cc, MArray-f.cc, MArray-fC.cc,
+	fCColVector.cc, fCColVector.h, fCDiagMatrix.cc, fCDiagMatrix.h,
+	fCMatrix.cc, fCMatrix.h, fCNDArray.cc, fCNDArray.h,
+	fCRowVector.cc, fCRowVector.h, fCmplxCHOL.cc, fCmplxCHOL.h,
+	fCmplxDET.cc, fCmplxDET.h, fCmplxLU.cc, fCmplxLU.h,
+	fCmplxSCHUR.cc, fCmplxSCHUR.h, fCmplxSVD.cc, fCmplxSVD.h,
+	fColVector.cc, fColVector.h, fDiagMatrix.cc, fDiagMatrix.h,
+	fEIG.cc, fEIG.h, fMatrix.cc, fMatrix.h, fNDArray.cc, fNDArray.h,
+	fRowVector.cc, fRowVector.h, floatCHOL.cc, floatCHOL.h,
+	floatDET.cc, floatDET.h, floatLU.cc, floatLU.h, floatSCHUR.cc,
+	floatSCHUR.h, floatSVD.cc, floatSVD.h: New files.
+	* Makefile.in (MATRIC_INC, TI_SRC, MATRIX_SRC): Add them.
+
+	* CMatrix.cc, CMatrix.h, CNDArray.cc, CNDArray.h, CmplxDET.cc,
+	MArray-C.cc, MArray-d.cc, MArray-defs.h, MArray.cc, MArray.h,
+	MatrixType.cc, MatrixType.h, SparseCmplxQR.cc, SparseCmplxQR.h,
+	SparseQR.cc, SparseQR.h, dMatrix.cc, dMatrix.h, dNDArray.cc,
+	dNDArray.h, data-conv.cc, data-conv.h, dbleDET.cc, dbleSVD.cc,
+	lo-cieee.c, lo-ieee.cc, lo-ieee.h, lo-mappers.cc, lo-mappers.h,
+	lo-specfun.cc, lo-specfun.h, lo-utils.cc, lo-utils.h, mx-base.h,
+	mx-defs.h, mx-ext.h, mx-inlines.cc, mx-op-defs.h, mx-ops,
+	oct-cmplx.h, oct-fftw.cc, oct-fftw.h, oct-inttypes.h, vx-ops:
+	Allow single precision types.
+	
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* CMatrix.cc (double rcond): Replace with double rcon everywhere
+	to avoid shadowed variable warning
+	(double ComplexMatrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(double ComplexMatrix::rcond (MatrixType &mattype) const): ditto.
+	* CMatrix.h (double rcond):  Replace with double rcon everywhere
+	to avoid shadowed variable warning
+	(double ComplexMatrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(double ComplexMatrix::rcond (MatrixType &mattype) const): ditto.
+	* dMatrix.cc (double rcond): Replace with double rcon everywhere
+	to avoid shadowed variable warning
+	(double Matrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(double Matrix::rcond (MatrixType &mattype) const): ditto.
+	* dMatrix.h (double rcond):  Replace with double rcon everywhere
+	to avoid shadowed variable warning
+	(double Matrix::rcond (void) const): New method for
+	reciprocal condition number calculation.
+	(double Matrix::rcond (MatrixType &mattype) const): ditto.
+
+	* regex-match.cc, regex-match.h: New class for simple regular
+	expression matching
+	* Makefile.in (INCLUDES): Add regex-match.h here, and
+	(LIBOCTAVE_CXX_SOURCES): regex-match.cc here.
+
+2008-05-19  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc: Replace some DGBCON with GPBCON where they are
+	incorrectly used.
+
+2008-05-13  David Bateman  <dbateman at free.fr>
+
+	* idx-vector.cc (IDX_VEC_REP::idx_vector_rep (const boolNDArray&)):
+	If len is zero size the index vector in the same manner as if len
+	is not zero.
+
+2008-05-05  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.cc (command_editor::re_read_init_file,
+	gnu_readline::do_re_read_init_file): New functions.
+	* cmd-edit.h (command_editor::re_read_init_file): Provide decl.
+	(command_editor::do_re_read_init_file): New function.
+	* oct-rl-edit.c (octave_rl_re_read_init_file): New function.
+	* oct-rl-edit.h: Provide decl.
+
+2008-05-05  Rafael Laboissiere  <rafael at debian.org>
+
+	* oct-rl-edit.c (octave_read_init_file): Simply call rl_read_init_file.
+
+2008-05-01  John W. Eaton  <jwe at octave.org>
+
+	* oct-shlib.h (octave_shlib::number_of_functions_loaded):
+	Return size_t instead of int value.
+	* oct-shlib.cc (octave_base_shlib::number_of_functions_loaded):
+	Likewise.
+	(octave_base_shlib::fcn_names): Now a std::map object.
+	Adjust all uses.
+	(octave_base_shlib::fcn_names_iterator,
+	octave_base_shlib::fcn_names_const_iterator): New typedefs.
+	(octave_base_shlib::add_to_fcn_names, octave_base_shlib::remove):
+	Perform reference counting for functions accessed.
+
+2008-04-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* lo-mappers.cc (xlog2 (double)): Compute log (2), not log2 (2).
+	(xlog2 (Complex), xlog2 (double, int&), xlog2 (Complex, int&)):
+	New functions.
+	* lo-mappers.h: Provide decls.
+
+2008-04-25  Michael Goffioul <michael.goffioul at gmail.com>
+
+	* oct-lookup.h (seq_lookup): Do not use output value of fill_n (MSVC
+	does not support it).
+
+2008-04-24  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* lo-sysdep.cc (octave_popen2): Don't set PIPE_NOWAIT for parentWrite.
+
+2008-04-21  John W. Eaton  <jwe at octave.org>
+
+	* idx-vector.cc (IDX_VEC_REP::idx_vector_rep (const boolNDArray&)):
+	Fix for-loop condition.
+
+2008-04-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* CmplxCHOL.cc, CmplxQR.cc, dbleCHOL.cc, dbleQR.cc: Fix calls to error()
+
+2008-04-16  David Bateman  <dbateman at free.fr>
+
+	* Sparse.h (Sparse<T>& operator = (Sparse<T>&)): Move definition
+	of the operator for here
+	* Sparse.cc (Sparse<T>& Sparse<T>::operator = (Sparse<T>&)): To
+	here. Also delete idx.
+	* Array.h (Array<T>& operator = (Array<T>&)): Move definition
+	of the operator for here
+	* Array.cc (Array<T>& Array<T>::operator = (Array<T>&)): To
+	here. Also delete idx.
+
+2008-04-09  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* lo-mappers.cc (xround): Avoid floating-point overflow when input
+	value is equal to bitmax implementation taken from gnulib).
+
+	* file-stat.cc (file_stat::update_internal): Do not strip trailing
+	file separator when path length is equal to 1 (handle case '\') under
+	__WIN32__ platforms.
+
+2008-04-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dbleQR.h, dbleQR.cc (QR::shift_cols): New method.
+	* CmplxQR.h, CmplxQR.cc (ComplexQR::shift_cols): New method.
+	* dbleCHOL.h, dbleCHOL.cc (CHOL::insert_sym, CHOL::delete_sym,
+	CHOL::shift_sym): New methods.
+	* CmplxCHOL.h, CmplxCHOL.cc (ComplexCHOL::insert_sym,
+	ComplexCHOL::delete_sym, ComplexCHOL::shift_sym): New methods.
+
+2008-04-03  John W. Eaton  <jwe at octave.org>
+
+	* lo-sysdep.cc [__WIN32__ && ! __CYGWIN__]: Include windows.h.
+
+2008-03-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-lookup.h: New file.
+
+2008-03-26  David Bateman  <dbateman at feee.fr>
+
+	* Array.cc (assignN): Additional fix for vector assignments.
+
+2008-03-25  David Bateman  <dbateman at feee.fr>
+
+	* Array.cc (assignN): refactor calculation of new dimensions when
+	original matrix is empty.
+	* Array-util.cc (bool is_vector (const dim_vector&)): New
+	function.
+	* Array-util.h (bool is_vector (const dim_vector&)): declare it.
+
+2008-03-25  David Bateman  <dbateman at free.fr>
+
+	* sparse-base-chol.h (sparse_base_chol_rep::~sparse_base_chol_rep
+	(void)): Only free the factorization if it was created
+	* spase-base-chol.cc (sparse_base_chol_rep::init): Don't attempt
+	to factorize a matrix that has been flagged as not being positive
+	definite.
+
+2008-03-25  John W. Eaton  <jwe at octave.org>
+
+	* lo-mappers.cc (xtrunc): New function.
+	* lo-mappers.h: Provide decl.
+
+2008-03-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* lo-specfun.cc (expm1, log1p): New functions.
+	* lo-specfun.h: Provide decls.
+
+	* lo-mappers.cc (xroundb): New function.
+	* lo-mappers.h: Provide decl.
+
+2008-03-23  David Bateman  <dbateman at free.fr>
+
+	* mx-ops: Definite binary operators for mixed integer array +
+	array case, except for 64bit cases.
+	
+2008-03-21  David Bateman  <dbateman at free.fr>
+
+	* oct-sparse.h: Add headers for amd.h.
+
+2008-03-20  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (Array<T> Array<T>::diag (octave_idx_type) const): New
+	method for diag function.
+	* Array.h  (Array<T> diag (octave_idx_type) const): Declare it.
+	* Array2.h (Array2<T> diag (octave_idx_type) const): New method.
+	* MArray2.h (MArray2<T> diag (octave_idx_type) const): ditto.
+	* ArrayN.h (ArrayN<T> diag (octave_idx_type) const): ditto.
+	* MArrayN.h (MArrayN<T> diag (octave_idx_type) const): ditto.
+
+	* Sparse.cc (Sparse<T> Sparse<T>::diag (octave_idx_type) const):
+	New method for the diag function.
+	* Sparse.h  (Sparse<T> diag (octave_idx_type) const): Declare it.
+	* MSparse.h (MSparse<T> diag (octave_idx_type) const): New method.
+
+	* Range.cc (Matrix Range::diag (octave_idx_type) const):
+	New method for the diag function.
+	* Range.h  (Matrix diag (octave_idx_type) const): Declare it.
+	
+	* CDiagMatrix.cc (ComplexColumnVector ComplexDiagMatrix::diag
+	(void) const): delete.
+	* dDiagMatrix.cc (ColumnVector DiagMatrix::diag (void) const): delete.
+	* dDiagMatrix.h (ColumnVector diag (void) const): ditto.
+	* CMatrix.cc (ComplexColumnVector ComplexMatrix::diag (void) const):
+	delete.
+	* CMatrix.h (ComplexColumnVector diag (void) const): ditto.
+	* dMatrix.cc (ColumnVector Matrix::diag (void) const): ditto.
+	* dMatrix.h (ColumnVector diag (void) const): ditto.
+	* boolMatrix.cc (boolMatrix boolMatrix::diag (void) const): ditto.
+	* boolMatrix.h (boolMatrix diag (void) const): ditto.
+	* chMatrix.cc (charMatrix charMatrix::diag (void) const): ditto.
+	* chMatrix.h (charMatrix diag (void) const): ditto.
+	* intNDArray.cc (intNDArray<T> intNDArray<T>::diag (void) const): ditto.
+	* intNDArray.h (intNDArray<T> diag (void) const): ditto.
+	
+	* CMatrix.cc (ComplexMatrix ComplexMatrix::diag (octave_idx_type)
+	const): Rewrite in terms of template classes function.
+	* CMatrix.h (ComplexMatrix diag (octave_idx_type)const ): Change
+	return type.
+	* dMatrix.cc (Matrix Matrix::diag (octave_idx_type) const): Rewrite in
+	terms of template classes function.
+	* dMatrix.h (Matrix diag (octave_idx_type) const): Change return type.
+	* boolMatrix.cc (boolMatrix boolMatrix::diag (octave_idx_type) const):
+	Rewrite in terms of template classes function.
+	* boolMatrix.h (boolMatrix diag (octave_idx_type) const): Change
+	return type. 
+	* chMatrix.cc (charMatrix charMatrix::diag (octave_idx_type)
+	const): Rewrite in terms of template classes function.
+	
+	* dSparse.cc (SparseMatrix SparseMatrix::diag (octave_idx_type) const):
+	Rewrite in terms of template classes function.
+	* CSparse.cc (SparseComplexMatrix SparseComplexMatrix::diag
+	(octave_idx_type) const): ditto.
+	* boolSparse.cc (SparseBoolMatrix SparseBoolMatrix::diag
+	(octave_idx_type) const): ditto.
+	* intNDArray.cc (intNDArray<T> intNDArray<T>::diag
+	(octave_idx_type) const): ditto.
+
+	* CNDArray.cc (ComplexNDArray ComplexNDArray::diag
+	(octave_idx_type) const): New method.
+	* CNDArray.h (ComplexNDArray diag (octave_idx_type) const):
+	Declare it.
+	* dNDArray.cc (NDArray NDArray::diag (octave_idx_type) const): New
+	method.
+	* dNDArray.h (NDArray diag (octave_idx_type) const): Declare it.
+	* chNDArray.cc (charNDArray charNDArray::diag
+	(octave_idx_type) const): New method.
+	* chNDArray.h (charNDArray diag (octave_idx_type) const):
+	Declare it.
+
+	
+2008-03-19  John W. Eaton  <jwe at octave.org>
+
+	* oct-env.cc (octave_env::do_base_pathname): Also handle rooted
+	relative filenames.
+
+2008-03-19  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (assignN): If orig_empty allow assignment like
+	a(1:10,1)=1:10
+
+	* Sparse.h (template <class U, class F> Sparse<U> map (F fcn)
+	const): New template function.
+	* MSparse.h (template <class U, class F> MSparse<U> map (F fcn)
+	const): ditto.
+	* dSparse.cc (SparseMatrix SparseMatrix::map (dmapper) const,
+	SparseComplexMatrix SparseMatrix::map (cmapper) const,
+	SparseBoolMatrix SparseMatrix::map (bmapper) const): Rewrite in
+	terms of the new template functor.
+	* CSparse.cc (SparseMatrix SparseComplexMatrix::map (dmapper) const,
+	SparseComplexMatrix SparseComplexMatrix::map (cmapper) const,
+	SparseBoolMatrix SparseComplexMatrix::map (bmapper) const): ditto.
+	
+2008-03-18  David Bateman  <dbateman at free.fr>
+
+	* lo-specfun.cc (Complex xlgamma (const Complex&)): New function.
+	* lo-specfun.h (Complex xlgamma (const Complex&)): Declare it.
+	* randpoison.c (xlgamma): Use lgamma if HAVE_LGAMMA is defined.
+	
+	* dNDArray.cc (NDArray::min, NDArraymax): chop trailing singletons.
+	* CNDarray.cc (ComplexNDArray::min, CompelxNDArray::max): ditto.
+	* intNDarray.cc (intNDArray<T>::min, intNDArray<T>::max): ditto.
+	
+	* Array.cc (Array<T>::index): Don't short_freeze on index with
+	fewer dimensions than the array only if the last dimension is empty.
+
+2008-03-18  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int_fit_to_range):
+	Use partial specialization for double values.
+
+2008-03-08  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.cc (Sparse<T>::index, assign): Likewise.
+	* Array.cc (Array<T>::index1, Array<T>::index2, Array<T>::indexN,
+	assign2): Eliminate use of idx_vector::is_one_zero method.
+	* idx-vector.cc, idx-vector.h
+	(idx_vector::maybe_convert_one_zero_to_idx,
+	IDX_VEC_REP::maybe_convert_one_zero_to_idx): Delete unused function.
+	(IDX_VEC_REP::one_zero): Delete data member.
+	(IDX_VEC_REP::is_colon_equiv): Delete one_zero check.
+	(idx_vector::is_one_zero, IDX_VEC_REP::is_one_zero): Delete function.
+
+2008-03-07  John W. Eaton  <jwe at octave.org>
+
+	* idx-vector.cc (IDX_VEC_REP::idx_vector_rep (bool),
+	IDX_VEC_REP::idx_vector_rep (const boolNDArray&)):
+	Simply perform the equivalent of "find" on the bool argument here,
+	set one_zero to 0 and orig_dims to size of resulting index vector.
+	(IDX_VEC_REP::freeze): Don't call maybe_convert_one_zero_to_idx here.
+
+2008-03-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dbleQR.cc (QR::insert_col, QR::insert_row, 
+	QR::delete_col, QR::delete_row): Use 0-based indexing.
+	* CmplxQR.cc (ComplexQR::insert_col, ComplexQR::insert_row, 
+	ComplexQR::delete_col, ComplexQR::delete_row): Likewise.
+
+	* dbleCHOL.cc: Small doc and declaration fixes.
+	* CmplxHOL.cc: Small doc and declaration fixes.
+	* CmplxQR.cc (ComplexQR::ComplexQR): Adjust code to match dbleQR.cc.
+	* dbleQR.cc (QR::delete_row): Fix incorrect test.
+	* CmplxQR.cc (ComplexQR::delete_row): Fix incorrect test.
+
+2008-03-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dbleCHOL.cc (CHOL::set, CHOL::update, CHOL::downdate):
+	New functions.
+	* dbleCHOL.h: Provide decls.
+	* CmplxCHOL.cc (ComplexCHOL::set, ComplexCHOL::update,
+	ComplexCHOL::downdate): New functions.
+	* CmplxCHOL.h: Provide decls.
+
+	* dbleQR.cc (QR::update, QR::insert_col, QR::delete_col,
+	QR::insert_row, QR::delete_row): New methods.
+	(QR::QR (const Matrix&, const MAtrix&)): New constructor.
+	* dbleQR.h: Provide decls.
+	* CmplxQR.cc (ComplexQR::update, ComplexQR::insert_col,
+	ComplexQR::delete_col, ComplexQR::insert_row,
+	ComplexQR::delete_row): New methods.
+	(ComplexQR::ComplexQR (const ComplexMatrix&, const ComplexMAtrix&)):
+	New constructor.
+	* CmplxQR.h: Provide decls.
+
+2008-03-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Array-C.cc, Sparse-C.cc: Include oct-sort.cc after definitions
+	of < and > operators.
+
+2008-03-03  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (assign1, assign1): Take care of repeated index
+	values. Adapt the test code to check for these cases.
+
+2008-03-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dMatrix.cc (Matrix::lssolve): Also avoid dgelsd lwork query bug
+	in lssolve method that accepts column vector argument.  Correct
+	calculation of nlvl.
+	* CMatrix.cc (ComplexMatrix::lssolve): Likewise, for zgelsd.
+
+2008-02-27  John W. Eaton  <jwe at octave.org>
+
+	* oct-rand.cc (class octave_rand): Make it a proper singleton class.
+
+2008-02-26  John W. Eaton  <jwe at octave.org>
+
+	* oct-rand.cc (get_dist_id): Fix typo.
+	(get_dist_id, octave_rand::distribution, octave_rand::scalar,
+	fill_rand): Improve error messages.
+
+	* oct-rand.cc (unknown_dist): New dist type.
+	(uniform_dist, normal_dist, expon_dist, poisson_dist, gamma_dist):
+	Use static const int instead of #define.
+	(get_dist_id): Default retval is unknown_dist.
+
+	* oct-rand.cc (rand_states): New static variable.
+	(initialize_rand_states, get_dist_id, get_internal_state,
+	set_internal_state, switch_to_generator, save_state): New functions.
+	(octave_rand::state): New arg to specify distribution.
+	Save state in rand_states instead of setting internal state.
+	Return named state.  Use set_internal_state to generate proper
+	state vector from user supplied state.  Save and restore current
+	state if specified and current distributions are different.
+	(octave_rand::distribution (void)): Use switch rather than if/else.
+	(octave_rand::distribution (const std::string&)): Likewise.
+	(octave_rand::uniform_distribution,
+	octave_rand::normal_distribution,
+	octave_rand::exponential_distribution,
+	octave_rand::poisson_distribution,
+	octave_rand::gamma_distribution): Call switch_to_generator.
+	(octave_rand::state, maybe_initialize): For new_generators, just
+	call initialize_rand_states if not already initialized.
+	(octave_rand::scalar, fill_rand): Save state after generating value.
+
+	* dMatrix.cc (Matrix::lssolve): Avoid another dgelsd lwork query bug.
+	* CMatrix.cc (ComplexMatrix::lssolve): Likewise, for zgelsd
+
+2008-02-24  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int_helper): New class.  Provide
+	specializations for signed and unsigned types.
+	(octave_int<T>::operator >>=, octave_int<T>::abs,
+	octave_int<T>::signum): Use static functions from
+	octave_int_helper class.
+
+	* oct-inttypes.h, oct-inttypes.cc (OCTAVE_US_TYPE1_CMP_OP,
+	OCTAVE_US_TYPE2_CMP_OP): Tag function declarations and definitions
+	with "template <>".
+
+2008-02-22  John W. Eaton  <jwe at octave.org>
+
+	* CSparse.cc, SparseCmplxLU.cc, SparsedbleLU.cc, dSparse.cc,
+	file-ops.cc, oct-group.cc, oct-shlib.cc, sparse-base-chol.h,
+	sparse-dmsolve.cc: Use 0 instead of NULL.
+
+2008-02-22  David Bateman  <dbateman at free.fr>
+
+	* boolSparse.cc (SparseBoolMatrix SparseBoolMatrix::diag 
+	(octave_idx_type) const): New method.
+	* boolSparse.h (SparseBoolMatrix SparseBoolMatrix::diag 
+	(octave_idx_type) const): Declare it.
+
+	* base-lu.h (lu_type Y (void) const): New method to return
+	factorization of xGETRF directly.
+	* sparse-base-lu.cc (template <class lu_type, class lu_elt_type,
+	class p_type, class p_elt_type> lu_type sparse_base_lu <lu_type, 
+	lu_elt_type, p_type, p_elt_type> :: Y (void) const): New method
+	to simulate the retirn of xGETRF.
+	* sparse-base-lu.h (template <class lu_type, class lu_elt_type,
+	class p_type, class p_elt_type> lu_type sparse_base_lu <lu_type, 
+	lu_elt_type, p_type, p_elt_type> :: Y (void) const): Declare it
+	(SparseMatrix R (void) const): Method to return scaling factors.
+	* SparsedbleLU.cc: Allow two element pivot thresholding and
+	scaling.
+	* SparseCmplxLU.cc: ditto.
+	* SparsedbleLU.h: Modify constructors to allow passing of two
+	element pivoting thresholds and flag for scaling
+	* SparseCmplxLU.h: ditto.
+
+	* base-lu.cc (ColumnVector P_vec (void) const): New method to
+	return permutations as a vector.
+	* base-lu.h (ColumnVector P_vec (void) const): Declare it.
+	* sparse-base-lu.cc (ColumnVector Pr_vec (void) const): New method
+	return row permutations as a vector.
+	(ColumnVector Pc_vec (void) const): New method return column 
+	permutations as a vector.
+	* sparse-base-lu.h (ColumnVector Pr_vec (void) const): Declare it.
+	(ColumnVector Pc_vec (void) const): Declare it.
+
+	* oct-spparms.cc: Add sym_tol field.
+	
+2008-02-20  David Bateman  <dbateman at free.fr>
+
+	* SparseComplexQR.cc (ComplexMatrix
+	SparseComplexQR::SparseComplexQR_rep::Q 
+	(void) const): New method.
+	* SparseComplexQR.h (ComplexMatrix
+	SparseComplexQR::SparseComplexQR_rep::Q 
+	(void) const): Declare it.
+	* SparseQR.cc (Matrix SparseQR::SparseQR_rep::Q	(void) const): ditto.
+	* SparseQR.h (Matrix SparseQR::SparseQR_rep::Q	(void) const): ditto.
+
+2008-02-20  John W. Eaton  <jwe at octave.org>
+
+	* boolNDArray.h (boolNDArray (const Array2<bool>&)): Delete.
+
+	* Marray2.h (MArray2 (const Array2<U>&),
+	MArray2 (const MArray2<U>&)): New templated constructors.
+
+	* Array2.h (Array2 (const Array<U>&),
+	Array2 (const Array<U>&, const dim_vector&)):
+	New templated constructors.
+
+	* CColVector.cc (ComplexColumnVector::map): Forward to MArray::map.
+	* dColVector.cc (ColumnVector::map): ditto.
+	* CRowVector.cc (ComplexRowVector::map): ditto.
+	* dRowVector.cc (RowVector::map): ditto.
+	* CMatrix.cc (ComplexMatrix::map): Forward to MArray2::map.
+	* dMatrix.cc (Matrix::map): ditto.
+
+	* dNDArray.cc (NDArray::map): New functions.
+	* dNDArray.h: Provide decls.
+
+	* CNDArray.cc (ComplexNDArray::map): New functions.
+	* CNDArray.h: Provide decls.
+
+	* MArray2.h (MArray2<T>::map): New function.
+	* Array2.h (Array2<T>::map): New function.
+	* MArrayN.h (MArrayN<T>::map): New function.
+	* ArrayN.h (ArrayN<T>::map): New function.
+	* Array.h (Array<T>::map): New function.
+
+	* functor.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+2008-02-20  David Bateman  <dbateman at free.fr>
+
+	* CColVector.h, CColVector.cc (ComplexColumnVector::apply): Remove.
+	* dColVector.h, dColVector.cc (ColumnVector::apply): ditto.
+	* CRowVector.h, CRowVector.cc (ComplexRowVector::apply): ditto.
+	* dRowVector.h, dRowVector.cc (RowVector::apply): ditto.
+	* CMatrix.h, CMatrix.cc (ComplexMatrix::apply): ditto.
+	* dMatrix.h, dMatrix.cc (Matrix::apply): ditto.
+
+	* CSparse.cc (apply): Remove.
+	(map): Replace old mapper code with code taken from ov-mapepr.cc
+	* CSparse.h (map): Reeclare them.
+	(dmapper, cmapper, bmapper): typedefs for mapper functions.
+	* dSparse.cc (apply): Remove.
+	(map): Replace old mapper code with code taken from ov-mapepr.cc
+	* dSparse.h (map): Reeclare them.
+	(dmapper, cmapper, bmapper): typedefs for mapper functions.
+
+	* intNDArray.cc (abs, signum): Two new mapper functions.
+	* intNDArray.h (abs, signum): Declare them.
+	* oct-inttypes.h (abs, signum): Mapper functions on scalar integer
+	base type.
+
+2008-02-15  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (Matrix::lssolve): Check n > mnthr, not n > m when
+	deciding whether to calculate workspace size, with mnthr from ILAENV.
+	* CMatrix.cc (ComplexMatrix::lssolve): Likewise.
+
+2008-02-14  John W. Eaton  <jwe at octave.org>
+
+	* CColVector.cc, CMatrix.cc, CRowVector.cc, CSparse.cc,
+	CmplxAEPBAL.cc, CmplxCHOL.cc, CmplxHESS.cc, CmplxLU.cc,
+	CmplxQR.cc, CmplxQRP.cc, CmplxSCHUR.cc, CmplxSVD.cc, DASPK.cc,
+	DASRT.cc, DASSL.cc, EIG.cc, LSODE.cc, NLEqn.cc, Quad.cc,
+	dColVector.cc, dMatrix.cc, dRowVector.cc, dSparse.cc,
+	dbleAEPBAL.cc, dbleCHOL.cc, dbleHESS.cc, dbleLU.cc, dbleQR.cc,
+	dbleQRP.cc, dbleSCHUR.cc, dbleSVD.cc:
+	Don't check f77_exception_encountered.
+
+2008-02-12  John W. Eaton  <jwe at octave.org>
+
+	* CMatrix.cc: Declare xilaenv instead of ilaenv.
+	(ComplexMatrix::lssolve): Call xilaenv instead of ilaenv.
+
+2008-02-12  Jason Riedy  <ejr at cs.berkeley.edu>
+  
+	* Array.cc (ascending_compare, descending_compare): Remove
+	non-standard extern in the instantiations.
+
+	* oct-sort.cc: Include <cstring> and sprinkle with std:: as needed.
+
+	* dMatrix.cc (ILAENV): Declare LAPACK Fortran function.
+	(Matrix::lssolve): Use ILAENV to query smlsiz.  And add an ugly
+	workaround for DGELSD's broken lwork query.  The formula is from
+	LAPACK's dgelsd.f source and allocates enough workspace to use an
+	efficient algorithm in the short-and-fat case (n > m).
+	* CMatrix.cc (ILAENV): Declare LAPACK Fortran function.
+	(ComplexMatrix::lssolve): Use ILAENV to query smlsiz.  And add an
+	ugly workaround for DGELSD's broken lwork query, as with double.
+
+2008-02-12  John W. Eaton  <jwe at octave.org>
+
+	* sparse-sort.cc: Don't explicitly instantiate
+	class octave_sort<octave_idx_vector_sort *>,
+	class octave_sort<octave_idx_type>, or
+	class octave_sort<octave_sparse_sort_idxl *>.
+
+	* Sparse.h (INSTANTIATE_SPARSE_SORT): Delete macro.
+	* Sparse-C.cc, Sparse-b.cc, Sparse-d.cc: Don't use it.
+
+	* Range.cc (Range::sort_internal): Avoid shadow warning from gcc.
+
+2008-02-11  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in ($(MAKEDEPS)): Skip dependencies if omit_deps is defined.
+
+2008-02-08  John W. Eaton  <jwe at octave.org>
+
+	* oct-sort.h (enum sortmode): Eliminate UNDEFINED.  Change all
+	uses of UNDEFINED to ASCENDING.
+
+2008-02-07  John W. Eaton  <jwe at octave.org>
+
+	* Range.cc (Range::sort_internal): Rename from sort.  New arg,
+	ASCENDING, with default value of true.
+	(Range::sort_internal (Array<octave_idx_type>&, bool)): New function.
+	(Range::sort (octave_idx_type, sortmode) const): New function.
+	(Range::sort (Array<octave_idx_type>&, octave_idx_type, sortmode)
+	const): New function.
+	* Range.h: Fix/provide decls.
+
+	* intNDArray.cc (intNDArray<T>::any (int)): Use != for comparison.
+
+2008-02-06  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in ($(OPTS_INC)): Use mv instead of move-if-change.
+	(stamp-prereq): Eliminate.
+	(clean): Don't remove stamp-prereq.
+	(libraries): Don't depend on stamp-prereq.
+	(PREREQ): New macro.
+	($(MAKEDEPS)): Depend on $(PREREQ), not stamp-prereq.
+	(distclean): Simplify with $(PREREQ).
+	(OPT_BASE): New macro.
+	(OPT_IN): Rename from OPTS_INC_DATA.  Define in terms of OPT_BASE.
+	(OPT_INC): Rename from OPTS_INC.  Define in terms of OPT_BASE.
+
+2008-02-05  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in: Unconditionally include $(MAKEDEPS).
+	Mark $(MAKEDEPS) as .PHONY targets if omit_deps is true.
+
+2008-02-03  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Array.cc (ascending_compare, descending_compare,
+	Array<T>::sort): Declare explicit specialization for T=double to
+	avoid symbol duplication error at link time.
+	* Array-d.cc (ascending_compare, descending_compare): Declare and
+	define as nonmember functions, not member functions of Array<T>.
+
+2008-02-03  John W. Eaton  <jwe at octave.org>
+
+	* Array-i.cc: Also instantiate Arrays for long long type if it exists.
+
+2008-02-03  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Array.cc: Don't include Range.h.
+
+2008-01-31  David Bateman  <dbateman at free.fr>
+
+	* oct-sort.cc: conversion of int to octave_idx_type where needed
+	for 64-bit builds.
+	(IFLT): Allow IFLT macro to be overridden.
+	* oct-sort.h: conversion of int to octave_idx_type where needed
+	for 64-bit builds.
+	(enum sortmode): Type of sort to perform.
+	(vec_index): Simple class to aid in indexed sorts.
+	
+	* Array.h ( Array<T> sort (octave_idx_type, sortmode) const,
+	Array<T> sort (Array<octave_idx_type> &, octave_idx_type,
+	sortmode) const): Array sorting methods.
+	(INSTANTIATE_ARRAY_SORT, NO_INSTANTIATE_ARRAY_SORT): Macros to
+	instantiate the array sorting methods.
+	* Array.cc (ascending_compare, descending_compare): New template
+	functions for generic sort comparison.
+  	( Array<T> Array<T>::sort (octave_idx_type, sortmode) const,
+	Array<T> Array<T>::sort (Array<octave_idx_type> &, octave_idx_type,
+	sortmode) const): Array sorting functions based of octave_sort
+	class.
+	* Array-C.cc: Instantiate the complex array sort methods. 
+	(IFLT): New macro to override the one in the
+	octave_sort class to avoid need for Complex < and > operators.
+	(static double xabs (const Complex&)): Complex abs function
+	avoiding std::abs(Inf) returning NaN with some compilers.
+	(ascending_compare, descending compare): override template
+	functions for complex comparison.
+	* Array-d.cc: Instantiate the double array sort methods. 
+	(Array<double> Array<double>::sort (octave_idx_type, 
+	sortmode) const, Array<double> Array<double>::sort 
+	(Array<octave_idx_type> &, octave_idx_type, sortmode) const): 
+	Array sorting functions based of octave_sort using uint64 sorting
+	on IEE754 doubles, for speed and correct sorting of Inf and NaN.
+	(ascending_compare, descending compare): override template
+	functions for double and uint64 comparison.
+	* Array-b.cc, Array-ch.cc, Array-i.cc, Array-s.cc, Array-str.cc: 
+	Instantiate the array sort methods.
+	* Array-idx-vec.cc: Null instantiation of array sort methods.
+	* Array2.h, Array3.h, ArrayN.h (sort): 2, 3 and N-dimensional
+	versions of the sort methods based on Array<T>::sort.
+
+	* CSparse.cc, dSparse.cc: Remove inclusion of octa-sort.h.
+	* Sparse.h ( Sparse<T> sort (octave_idx_type, sortmode) const,
+	Sparse<T> sort (Array<octave_idx_type> &, octave_idx_type,
+	sortmode) const): Sparse sorting methods.
+	(INSTANTIATE_ARRAY_SORT): Macro to instantiate the sparse sorting 
+	methods.
+	* Sparse.cc: replace sort with lsort throughout to avoid shadowing
+	of new sort method.
+	(sparse_ascending_compare, sparse_descending_compare): New template
+	functions for generic sort comparison.
+  	( Sparse<T> Sparse<T>::sort (octave_idx_type, sortmode) const,
+	Sparse<T> Sparse<T>::sort (Sparse<octave_idx_type> &, octave_idx_type,
+	sortmode) const): Sparse sorting functions based of octave_sort
+	class.
+	* Sparse-C.cc: Instantiate the complex sparse sort methods. 
+	(IFLT): New macro to override the one in the
+	octave_sort class to avoid need for Complex < and > operators.
+	(static double xabs (const Complex&)): Complex abs function
+	avoiding std::abs(Inf) returning NaN with some compilers.
+	(sparse_ascending_compare, sparse_descending compare): override
+	template functions for complex comparison.
+	* Sparse-d.cc: Instantiate the cdouble sparse sort methods. 
+	(sparse_ascending_compare, sparse_descending compare): override
+	template functions for double comparison.
+	* Array-b.cc: Instantiate the sparse sort methods.
+
+2008-01-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* idx-vector.h (idx_vector::idx_vector_rep::range_base,
+	idx_vector::idx_vector_rep::range_step,
+	idx_vector::idx_vector_rep::range_step): New data members.
+	(idx_vector::idx_vector_rep::idx_vector_rep): Initialize them.
+	* idx-vector.cc (IDX_VEC_REP::sort, IDX_VEC_REP::is_colon_equiv,
+	IDX_VEC_REP::init_state, IDX_VEC_REP::operator =,
+	IDX_VECTOR_REP::idx_vector_rep): Handle range.
+
+2008-01-18  Marco Caliari  <marco.caliari at univr.it>
+
+	* dMatrix.cc (Matrix::expm): Correctly perform reverse permutation.
+	* CMatrix.cc (ComplexMatrix::expm): Likewise.
+
+2008-01-22  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* oct-time.cc (octave_base_tim::init): Validate pointer argument;
+	this fixes the "localtime(-1)" crash under Windows.
+
+2008-01-18  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (solve_singularity_warning): New function.
+	(Matrix::expm): Pass pointer to solve_singularity_warning to
+	Matrix::solve method.  Exit early if Matrix::solve fails.
+	Limit sqpow value to avoid overflowing scale factor.
+	* CMatrix.cc (solve_singularity_warning): New function.
+	(ComplexMatrix::expm): Pass pointer to solve_singularity_warning to
+	ComplexMatrix::solve method.  Exit early if ComplexMatrix::solve fails.
+	Limit sqpow value to avoid overflowing scale factor.
+	From Marco Caliari <marco.caliari at univr.it>.
+
+2008-01-10  Kim Hansen  <kimhanse at gmail.com>
+
+	* Sparse.cc: New tests for slicing of sparse matrices.
+
+2008-01-07  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_ANY_ALL_OP_ROW_CODE): Don't break from
+	loop if this test succeeds.
+
+2008-01-03  David Bateman  <dbateman at free.fr>
+
+	* MSparse.cc (SPARSE_A2A2_OP): If first arg is scalar zero, then
+	need unary operator on remaining argument
+	* Sparse-op-defs.h (SPARSE_SMSM_BIN_OP_1): ditto.
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+2007-12-18  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (template <class T> Sparse<T> Sparse<T>::index 
+	(idx_vector&, int) const): Fix case indexing of non zero scalar 
+	stored as a sparse matrix.
+	(template <class T> Sparse<T> Sparse<T>::index (idx_vector&, 
+	idx_vector&, int) const): For the non permutated indexing case,
+	fix link list calculation and use.
+
+2007-12-17  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::indexN): Correctly handle scalar indexed by
+	N-d array.
+
+2007-12-17  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_ANY_ALL_OP_ROW_CODE): Use ridx for row
+	index.
+
+2007-12-11  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.cc (Sparse<T>::index (idx_vector&, int) const):
+	If indexing scalar with empty matrix, return empty array with same
+	size as index.
+
+2007-12-10  John W. Eaton  <jwe at octave.org>
+
+	* NLEqn.h (NLEqn::fval): New data member.  Adjust constructors
+	and assignment operator.
+	(NLEqn::function_value): New function.
+	* NLEqn.cc (NLEqn::solve): If solution is successful, compute
+	function value.
+
+	* file-ops.cc (file_ops::concat): New function.
+	* file-ops.h: Provide decl.
+
+2007-12-07  John W. Eaton  <jwe at octave.org>
+
+	* oct-time.cc (octave_base_tm::init): Only assign t->tm_zone if it
+	is not 0.
+
+2007-12-07  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_SMS_CMP_OP, SPARSE_SMS_BOOL_OP,
+	SPARSE_SSM_CMP_OP, SPARSE_SSM_BOOL_OP, SPARSE_SMSM_CMP_OP, 
+	SPARSE_SMSM_BOOL_OP, SPARSE_BASE_REDUCTION_OP): Use sparse
+	indexing where possible rather than the elem method.
+	(SPARSE_REDUCTION_OP_ROW_EXPR, SPARSE_REDUCTION_OP_COL_EXPR,
+	SPARSE_ANY_ALL_OP_ROW_CODE, SPARSE_ANY_ALL_OP_COL_CODE):
+	Replace for new version of SPARSE_BASE_REDUCTION_OP.
+	(SPARSE_ALL_OP): Specialize the initial value, and only treat dim
+	= 0 directly.
+	* CSparse.cc (SparseComplexMatrix SparseComplexMatrix::sumsq (int)
+	const): Replace ROW_EXPR and COL_EXPR functions for new version of
+	SPARSE_BASE_REDUCTION_OP.
+	(SparseComplexMatrix SparseComplexMatrix::prod (int) const):
+	Specialize the initial value, and only treat dim = 0 directly.
+	* dSparse.cc (SparseMatrix SparseMatrix::sumsq (int) const):
+	ditto.
+	(SparseMatrix SparseMatrix::prod (int) const): ditto.
+
+2007-12-06  John W. Eaton  <jwe at octave.org>
+
+	* CMatrix.cc (ComplexMatrix::expm): Update pointers to internal
+	data for npp and dpp after assignments.
+	* dMatrix.cc (Matrix::expm): Use same method as ComplexMatrix::expm.
+
+2007-12-04  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.cc (assign (Sparse<LT>&,  const Sparse<RT>&)):
+	Do nothing if one index is empty.
+
+2007-12-04  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (assign (Sparse<LT>&,  const Sparse<RT>&)):
+	Resize matrix as well if one dimension of lhs is zero and the rhs
+	index exceeds the lhs index.
+	* Sparse.cc (assign1 (Sparse<LT>&,  const Sparse<RT>&)):
+	Don't resize to a smaller matrix for empty matrices with a max rhs
+	index smaller than the non zero lhs index.
+
+2007-12-04  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Array-util.h: Tag permute_vector_compare with OCTAVE_API.
+
+2007-12-03  Moritz Borgmann  <octave at moriborg.de>
+
+	* Array-util.cc (permute_vector_compare): Move here from Array.cc.
+	* Array-util.h (permute_vector, permute_vector_compare): Provide decls.
+	* Array.cc (permute_vector, permute_vector_compare): Delete.
+
+2007-12-03  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (template <class LT, class RT> int assign
+	(Sparse<LT>&,  const Sparse<RT>&)): Only set return matrix size to
+	rhs values if both no. rows and columns are zero.
+
+2007-11-30  John W. Eaton  <jwe at octave.org>
+
+	* oct-sort.cc, oct-sort.h: Style fixes.
+
+	* lo-math.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* liboctave/Array2.h, liboctave/ArrayN.h, liboctave/CmplxDET.cc,
+	liboctave/DASPK.cc, liboctave/DASPK.h, liboctave/DASRT.cc,
+	liboctave/DASRT.h, liboctave/DASSL.cc, liboctave/DASSL.h,
+	liboctave/LSODE.cc, liboctave/LSODE.h, liboctave/NLEqn.h,
+	liboctave/Quad.h, liboctave/Range.cc, liboctave/dbleDET.cc,
+	liboctave/lo-cieee.c, liboctave/lo-ieee.cc,
+	liboctave/lo-mappers.cc, liboctave/oct-time.cc,
+	liboctave/oct-time.h, liboctave/randgamma.c,
+	liboctave/randmtzig.c, liboctave/randpoisson.c: Include lo-math.h
+	instead of cmath or math.h.
+	* lo-mappers.h: Don't include sunmath.h here.
+
+2007-11-26  John W. Eaton  <jwe at octave.org>
+
+	* idx-vector.h (idx_vector::idx_vector_rep (const intNDArray<U>&)):
+	Eliminate unnecessary second arg from call to tree_to_mat_idx.
+
+	* oct-inttypes.h (operator bool, operator char): Delete.
+	(bool_value, char_value, double_value, float_value): New functions.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* intNDArray.cc (template <class T> intNDArray<T>
+	intNDArray<T>::max (int) const, template <class T> intNDArray<T>
+	intNDArray<T>::max (ArrayN<octave_idx_type>&, int) const,
+	template <class T> intNDArray<T> intNDArray<T>::min (int) const, 
+	template <class T> intNDArray<T> intNDArray<T>::min 
+	(ArrayN<octave_idx_type>&, int) const): New methods for integer
+	classes.
+	* intNDArray.h (class intNDArray): Add min/max methods
+	* mx-op-defs.h (MIXMAX_DECLS, MINMAX_FCNS, SND_MINMAX_FCN,
+	NDS_MINMAX_FCN, NDND_MINMAX_FCN): New macro for instantiation of
+	min/max functions.
+	* int8NDArray.h, int16NDArray.h, int32NDArray.h, int64NDArray.h, 
+	uint8NDArray.h, uint16NDArray.h, uint32NDArray.h, uint64NDArray.h
+	(MINMAX_DECLS(T)): Declare the min/max functions for integer
+	types.
+	* int8NDArray.cc, int16NDArray.cc, int32NDArray.cc, int64NDArray.cc, 
+	uint8NDArray.cc, uint16NDArray.cc, uint32NDArray.cc, uint64NDArray.cc
+	(MINMAX_FCNS(T)): Instantiate the min/max functions for integer
+	types.
+
+	* Arrayc.cc (Array<T>::index (idx_vector&, idx_vector&, int,
+	const T& rfv) const): If ndims != 2 call ND version of index.
+
+2007-11-14  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (opeator T (void) const): New conversion operator.
+
+	* lo-specfun.cc (zbesi): When alpha is negative, don't limit
+	correction to half-integer values.  From Eric Chassande-Mottin
+	<echassandemottin at gmail.com>.
+
+2007-11-07  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* dMatrix.cc, CMatrix.cc: Help MSVC compiler to resolve
+	ambiguities related to math functions (in C++ mode).
+
+2007-11-06  David Bateman  <dbateman at free.fr>
+
+	* intNDArray.cc (intNDArray<T> intNDArray<T>::sum (int) const):
+	New method.
+	* intNDarray.h (intNDArray sum (int) const): Declare it.
+	* boolNDArray.cc (boolNDArray boolNDArray::sum (int) const):
+	New method.
+	* boolNDarray.cc (boolNDArray sum (int) const): Declare it.
+	* MArray-def.h (MARRAY_NORM_BODY): Scale frobenius norm by infinity
+	norm to avoid issues of over- and underflow.  From Rolf Fabian
+	<Rolf.Fabian at gmx.de>.
+
+2007-10-30  David Bateman  <dbateman at free.fr>
+
+	* DASRT-opts.in, LSODE-opts.in: Doc fixes for small book format.
+
+2007-10-30  John W. Eaton  <jwe at octave.org>
+
+	* CMatrix.cc (lssolve): Compute size of rwork and iwork arrays.
+	* dMatrix.cc (lssolve): Compute size of iwork array.
+
+2007-10-29  David Bateman  <dbateman at free.fr>
+
+	* CMatrix.h (lssolve (const Matrix&, octave_idx_type&, 
+	octave_idx_type&, double&) const, lssolve (const ComplexMatrix&, 
+	octave_idx_type&, octave_idx_type&, double&) const, lssolve 
+	(const ColumnVector&, octave_idx_type&, octave_idx_type&, 
+	double& rcond) const, lssolve (const ComplexColumnVector&, 
+	octave_idx_type&, octave_idx_type&, double& rcond) const): New
+	declarations.
+	* CMatrix.cc (lssolve (const Matrix&, octave_idx_type&, 
+	octave_idx_type&, double&) const, lssolve (const ComplexMatrix&, 
+	octave_idx_type&, octave_idx_type&, double&) const, lssolve 
+	(const ColumnVector&, octave_idx_type&, octave_idx_type&, 
+	double& rcond) const, lssolve (const ComplexColumnVector&, 
+	octave_idx_type&, octave_idx_type&, double& rcond) const): New
+	methods.
+	(lssolve (const Matrix&, octave_idx_type&, octave_idx_type&,
+	double&) const, lssolve (const ComplexMatrix&, octave_idx_type&, 
+	octave_idx_type&, double&) const): Also return rcond from the
+	singular values returned by XGELSD.
+	* dMatrix.h (lssolve (const Matrix&, octave_idx_type&, 
+	octave_idx_type&, double&) const, lssolve (const ComplexMatrix&, 
+	octave_idx_type&, octave_idx_type&, double&) const, lssolve 
+	(const ColumnVector&, octave_idx_type&, octave_idx_type&, 
+	double& rcond) const, lssolve (const ComplexColumnVector&, 
+	octave_idx_type&, octave_idx_type&, double& rcond) const): New
+	declarations.
+	* dMatrix.cc (lssolve (const Matrix&, octave_idx_type&, 
+	octave_idx_type&, double&) const, lssolve (const ComplexMatrix&, 
+	octave_idx_type&, octave_idx_type&, double&) const, lssolve 
+	(const ColumnVector&, octave_idx_type&, octave_idx_type&, 
+	double& rcond) const, lssolve (const ComplexColumnVector&, 
+	octave_idx_type&, octave_idx_type&, double& rcond) const): New
+	methods.
+	(lssolve (const Matrix&, octave_idx_type&, octave_idx_type&,
+	double&) const, lssolve (const ComplexMatrix&, octave_idx_type&, 
+	octave_idx_type&, double&) const): Also return rcond from the
+	singular values returned by XGELSD.
+		
+2007-10-26  David Bateman  <dbateman at free.fr>
+
+	* dMatrix.cc (Matrix::lssolve): Use xGELSD for rank deficient
+	matrices to avoid reliability issues with xGELSY.
+	* CMatrix.cc (ComplexMatrix::lssolve): Likewise.
+
+2007-10-25  John W. Eaton  <jwe at octave.org>
+
+	* oct-time.cc (octave_gmtime::init, octave_localtime::init):
+	Call unix_time on arg instead of relying on conversion operator.
+
+	* oct-time.h (octave_time::double_value): New function.
+	(octave_time::operator double () const): Delete.
+	(octave_time::operator time_t () const): Delete.
+
+2007-10-24  John W. Eaton  <jwe at octave.org>
+
+	* strptime.c: Also compile if OCTAVE_HAVE_BROKEN_STRPTIME is defined.
+
+2007-10-23  John W. Eaton  <jwe at octave.org>
+
+	* CRowVector.cc (operator * const ComplexRowVector&, const
+	ComplexColumnVector&)): Delete spurious code left from patch.
+
+2007-10-22  Kim Hansen  <kimhanse at gmail.com>
+
+	* chMatrix.cc, lo-utils.cc, oct-env.cc, oct-uname.cc,
+	sparse-sort.cc: Include <cstring>.
+
+2007-10-17  John W. Eaton  <jwe at octave.org>
+
+	* oct-sparse.h: Don't include metis.h.
+
+	* dSparse.cc (SparseMatrix::fsolve): Delete special code for METIS.
+	* CSparse.cc (SparseComplexMatrix::fsolve): Likewise.
+	* sparse-base-chol.cc (sparse_base_chol<chol_type, chol_elt,
+	p_type>::sparse_base_chol_rep::init): Likewise.
+
+2007-10-16  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (Matrix::inverse): Only check rcond == 0 if the
+	matrix is hermitian or calc_cond is true.
+	* CMatrix.cc (ComplexMatrix::inverse): Likewise.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+2007-10-11  Brian Gough  <bjg at network-theory.co.uk>
+
+	* DASSL-opts.in, LSODE-opts.in: Spelling fixes.
+
+2007-10-10  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* DASPK-opts.in, DASRT-opts.in, DASSL-opts.in: Spelling fixes.
+
+2007-10-10  John W. Eaton  <jwe at octave.org>
+
+	* LPsolve.h, LPsolve.cc: Delete.
+	* Makefile.in: Remove them from the INCLUDES and
+	LIBOCTAVE_CXX_SOURCES lists.
+
+2007-10-09  John W. Eaton  <jwe at octave.org>
+
+	* oct-time.cc (octave_strptime::init): Initialize t.tm_mon to -1
+	and t.tm_year to INT_MIN before call to oct_strptime.  Adjust
+	values to zero after call if they remain unchanged.
+
+	* dSparse.cc (SparseMatrix::all_elements_are_zero): New function.
+	* dNDArray.cc (NDArray::all_elements_are_zero): New function.
+
+2007-10-09  David Bateman  <dbateman at free.fr>
+
+	* oct-time.cc (octave_strptime::init): Only call mktime if mday is
+	valud and mon and year are also filled in.
+
+	* Array2.h (Array2<T>::Array2(const dim_vector&),
+	Array2<T>::Array(const dim_vector&, const T&)): Check that
+	dim_vector is 2 dimensional.
+
+	* Sparse.cc (Sparse<T> Sparse<T>::index (idx_vector&, idx_vector&,
+	int)): Remove a for loop in the random indexing case at the
+	expense of maintaining a set of linked lists of indices that point 
+	to the same column in the original matrix.
+	(int assign (Sparse<LT>&, Sparse<RT>)): Take a const copy of lhs
+	and use it on the RHS of expressions to avoid unnecessary calls to
+	make_unique.
+
+2007-10-08  David Bateman  <dbateman at free.fr>
+
+	* oct-rl-edit. (typedef rl_quoting_fcn_ptr, rl_dequoting_fcn_ptr,
+	rl_char_is_quoted_fcn_ptr, rl_command_fcn_ptr): New  typedefs
+	for readline compatible functions.
+	(octave_rl_redisplay): Redisplay the current line of text.
+	(octave_rl_newline):  Change interface to the same
+	as used by the equivalent readline function itself.
+	(octave_rl_filename_quoting_desired,
+	octave_rl_set_filename_quote_characters,
+	octave_rl_set_completer_quote_characters,
+	octave_rl_qet_quoting_function, octave_rl_qet_dequoting_function,
+	octave_rl_set_char_is_quoted_function): New functions to control
+	readline filename quoting and line acceptace.
+	* oct-rl-edit.c (octave_rl_newline): Change interface to the same
+	as used by the equivalent readline function itself.
+	(octave_rl_redisplay): Redisplay the current line of text.
+	(octave_rl_filename_quoting_desired,
+	octave_rl_set_filename_quote_characters,
+	octave_rl_set_completer_quote_characters,
+	octave_rl_qet_quoting_function, octave_rl_qet_dequoting_function,
+	octave_rl_set_char_is_quoted_function): New functions to control
+	readline filename quoting and line acceptace.
+	* cmd-edit.h (typedef quoting_fcn, typedef dequoting_fcn,
+	typedef char_is_quoted_fcn, user_accept_line_fcn): New typedefs
+	to map C++ function to readline compatible functions.
+	(set_filename_quote_characters): New function to set the
+	characters to if they appear in a filename that force the filename
+	to be quoted.
+	(set_completer_quote_characters): The characters that the readline
+	completion function considers as quotation characters.
+	(set_quoting_function, set_dequoting_function,
+	set_char_is_quoted_function, set_user_accept_line_function):
+	Functions to set the Octave functions to perform quoting and the
+	acceptance of a line of text by readline.
+	(get_quoting_function, get_dequoting_function,
+	get_char_is_quoted_function, get_user_accept_line_function):
+	Functions to get the above functions.
+	(accept_line): New method for the command_editor to accept a line
+	of text.
+	(file_quoting_desired): Function to set whether readline should
+	attempt to quote filenames.
+	(do_set_filename_quoting_characters, 
+	do_set_completer_quote_characters, do_set_quoting_function,
+	do_set_dequoting_function, do_set_char_is_quoted_function,
+	do_set_user_accept_line_function, do_get_quoting_function,
+	do_get_dequoting_function, do_get_char_is_quoted_function,
+	do_get_user_accept_line_function, do_filename_quoting_desired):
+	Virtual functions to control the behavior of readline quoting and
+	acceptance of lines.
+	(do_accept_line): Virtual function for the accept line function.
+	* cmd-edit.cc (class gnu_readline do_set_filename_quote_characters, 
+	do_completer_quote_characters, do_set_quoting_function,
+	do_set_dequoting_function, do_set_char_is_quoted_function,
+	do_set_user_accept_line_function, do_get_quoting_function,
+	do_get_dequoting_function, do_get_user_accept_line_function, 
+	do_accept_line, do_filename_quoting_desired, command_quoter,
+	command_dequoter, command_char_is_quoted, command_accept_line):
+	New functions in gnu_readline class to control filename quoting 
+	and line acceptance.
+	(quoting_function, dequoting_function, char_is_quoted_function,
+	user_accept_line_function): private variable to store functions
+	supplied for readline quoting and line acceptance.
+	(gnu_readline::gnu_readline): Also set the new function pointers
+	to zero.
+	(gnu_readline::do_newline): Adapt to new octave_rl_newline
+	interface.
+	(gnu_readeline::operate_and_get_next): Use new accept_line
+	function rather than newline.
+	(default_ommand_editor::do_accept_line): New method.
+	(class command_editor set_filename_quote_characters, 
+	set_completer_quote_characters, set_quoting_function,
+	set_dequoting_function, set_char_is_quoted_function,
+	set_user_accept_line_function, get_quoting_function,
+	get_dequoting_function, get_user_accept_line_function, 
+	accept_line, filename_quoting_desired): New functions checking
+	instance before calling virtual function.
+
+	* CMatrix.h, dMatrix.h, boolMatrix.h, chMatrix.h, MArray2.h,
+	Array2.h: Add dim_vector constructors.
+	* charNDArray.h (charNDArray (const dim_vector&)): Add missing
+	const to dim_vector constructors. 
+	* boolMatrix.cc, chMatrix.cc, intNDArray.cc (diag (void), diag
+	(octave_idx_type)): New methods to constructor diagonal matrices.
+	* boolMatrix.h, chMatrix.h, intNDArray.h (diag (void), diag
+	(octave_idx_type)): Declare them.
+
+
+2007-10-06  John W. Eaton  <jwe at octave.org>
+
+	* lo-specfun.cc: (zlgamma): Delete.
+	(xgamma): Use C library gamma function if available.
+	(xlgamma): Use C library lgamma function if available.
+	(xlgamma) [! HAVE_LGAMMA]: Allow calculation for any value of X
+	other than NaN or Inf.
+
+2007-10-05  John W. Eaton  <jwe at octave.org>
+
+	* lo-specfun.cc (zlgamma): New function.
+
+2007-10-04  John W. Eaton  <jwe at octave.org>
+
+	* oct-sort.cc (octave_sort<T>::binarysort): Remove register
+	qualifiers on local variables.
+
+2007-10-04  Marco Caliari  <mcaliari at math.unipd.it>
+
+	* CMatrix.cc (ComplexMatrix::expm): Limit shift to values less
+	than log(realmax) to avoid issues with NaN.
+
+2007-10-01  John W. Eaton  <jwe at octave.org>
+
+	* oct-time.cc (octave_strptime::init): Call mktime to propertly
+	initialize wday and yday.
+	From Matthias Drochner <m.drochner at fz-juelich.de>.
+
+	* cmd-edit.cc (command_editor::do_decode_prompt_string): Don't
+	insert extra '\001' when decoding \[ and \].
+
+2007-09-26  David Bateman  <dbateman at free.fr>
+
+	* dMatrix.cc (lssolve): Replace the use of xGELSS with xGELSY with
+	is much faster and no less accurate.
+	* CMatrix.cc (lssolve): ditto.
+
+2007-09-25  David Bateman  <dbateman at free.fr>
+
+	* dMatrix.cc (utsolve, ltsolve, fsolve, lssolve): Allow
+	zero dimensioned matrices.
+        * CMatrix.cc (utsolve, ltsolve, fsolve, lssolve): ditto.
+	* dSparse.cc (dsolve, utsolve, ltsolve, bsolve, trisolve, fsolve):
+	ditto.
+	* CSparse.cc (dsolve, utsolve, ltsolve, bsolve, trisolve, fsolve):
+	ditto.
+	* SparseQR.cc (SparseQR::SparseQR_rep::C, qrsolve): ditto.
+	* SparseCmplxQR.cc (SparseComplexQR::SparseComplexQR_rep::C,
+	qrsolve): ditto.
+	* sparse-dmsolve.cc (dmsolve): ditto.
+
+2007-09-21  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign1 (Array<LT>&, const Array<RT>&, const LT&)):
+	Also allow resizing empty LHS if it is 1x0 or 0xN.
+
+2007-09-19  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.cc (command_editor::remove_startup_hook):
+	Fix cut-and-paste error.
+	(gnu_readline::set_startup_hook): Only set hook function if new
+	function is different from the current one.
+
+2007-09-18  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.h, cmd-edit.cc (command_editor::startup_hook_set,
+	command_editor::event_hook_set): New static data.
+	(default_command_editor::set_startup_hook,
+	gnu_readline::set_startup_hook,
+	default_command_editor::restore_startup_hook,
+	gnu_readline_restore_event_hook):
+	Rename from do_set_startup_hook and do_set_event_hook.
+	(gnu_readline::operate_and_get_next): Call
+	command_editor::add_startup_hook, not
+	command_editor::set_startup_hook.
+	(command_editor::startup_handler, command_editor::event_handler):
+	New functions.
+	(command_editor::add_startup_hook, command_editor::add_event_hook,
+	command_editor::remove_startup_hook,
+	command_editor::remove_event_hook): Rename from set_startup_hook
+	and restore_startup_hook.  Handle hook sets here.
+	* cmd-edit.cc (gnu_history::do_goto_mark):
+	Call remove_startup_hook instead of restore_startup_hook.
+
+2007-09-17  John W. Eaton  <jwe at octave.org>
+
+	* lo-utils.cc (octave_read_complex, octave_read_double): Skip
+	leading whitespace.
+
+2007-09-13  John W. Eaton  <jwe at octave.org>
+
+	* lo-utils.cc (read_inf_nan_na, octave_read_double,
+	octave_read_complex): Use istream::get instead of >> to read
+	individual characters.
+
+2007-09-10  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign1): Don't call make_unique for invalid assignment.
+
+2007-09-10  David Bateman  <dbateman at free.fr>
+
+	* Array.h (Array<T>::make_unique): Make public so that the
+	::assign functions can access it directly.
+	* Array.cc (Array<T>::maybe_delete_elements_1(idx_vector&),
+	Array<T>::maybe_delete_elements_1(idx_vector&),
+	Array<T>::maybe_delete_elements(idx_vector&, idx_vector&),
+	Array<T>::maybe_delete_elements(Array<idx_vector>&, const T&)):
+	Use xelem for non const RHS to avoid call to make_unique.
+	(int assign1 (Array<LT>&, const Array<RT>&, const LT&)): Use
+	xelem for LHS and call lhs.make_unique() only once. Special case
+	the is_colon index case and use Array<T>::xelem(octave_idx_type)
+	rather than Array<T>::xelem(octave_idx_type,octave_idx_type) and
+	bring the additional multiplication out of the inner loop.
+	(int assign2 (Array<LT>&, const Array<RT>&, const LT&)): ditto.
+	(int assignN (Array<LT>&, const Array<RT>&, const LT&)): ditto.
+	* idx-vector.h (idx_vector::idx_vector_rep::idx_vector_rep 
+	(const Range& r)): Don't use init_state() method but special case
+	as with a Range can avoid exhaustive search.
+
+2007-09-07  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::fortran_vec): Call make_unique instead of
+	manipulating rep directly.
+
+	* Array.h (idx, idx_count): Declare mutable.
+	(Array<T>::set_index, Array<T>::clear_index, Array<T>::value):
+	Now const.
+
+2007-09-06  David Bateman  <dbateman at free.fr>
+
+        * Array-util.cc (increment_index): dimensions can have singleton
+        trailing dimensions.
+        * Array.h (range_error, xelem, checkelem, elem, operator ()):
+        Modify use of Array<int> to Array<octave_idx_type> and adjust
+        where necessary.
+        * Array.cc (range_error): ditto.
+        * MArrayN.h (permute, ipermute): ditto.
+        * ArrayN.h (permute, ipermute): ditto.
+        * so-array.cc (streamoff_array::compute_index): ditto.
+        * so-array.h (compute_index): ditto.
+        * CMattrix.cc (ComplexMatrix::exmpm): ditto.
+
+2007-08-29  David Bateman  <dbateman at free.fr>
+
+        * dSparse.cc (SparseMatrix SparseMatrix::inverse (MatrixType &, 
+        octave_idx_type&, double&, int, int)): Calculate with LU even for
+        matrices marked as singular.
+        * CSparse.cc (SparseComplexMatrix SparseComplexMatrix::inverse (
+        MatrixType &, octave_idx_type&, double&, int, int)): ditto.
+        * dMatrix.cc (Matrix Matrix::inverse (MatrixType &, octave_idx_type&,
+        double&, int, int)): ditto. If rcond==0 force matrix of infinities.
+        * dMatrix.cc (ComplexMatrix ComplexMatrix::inverse (MatrixType &,
+         octave_idx_type&, double&, int, int)): ditto.
+
+2007-08-27  John W. Eaton  <jwe at octave.org>
+
+	* oct-env.cc (octave_env::rooted_relative_pathname,
+	octave_env::do_rooted_relative_pathname): New functions.
+	* oct-env.h: Provide decls.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+        * MSparse.h (MSparse<T>& insert (const Sparse<T>&, 
+        const Array<octave_idx_type>&)): New method.
+        (MSparse (const dim_vector&, octave_idx_type)): Ditto.
+        * dSparse.h (SparseMatrix& SparseMatrix::insert (const
+        SparseMatrix&, const Array<octave_idx_type>&)): ditto.
+        (SparseMatrix (const dim_vector&, octave_idx_type)): ditto.
+        * dSparse.cc (SparseMatrix& SparseMatrix::insert (const
+        SparseMatrix&, const Array<octave_idx_type>&)): ditto.
+        * boolSparse.h (SparseBoolMatrix& SparseBoolMatrix::insert (const
+        SparseBoolMatrix&, const Array<octave_idx_type>&)): ditto.
+        * boolSparse.cc (SparseBoolMatrix& SparseBoolMatrix::insert (const
+        SparseBoolMatrix&, const Array<octave_idx_type>&)): ditto.
+        * CSparse.h (SparseComplexMatrix& SparseComplexMatrix::insert (const
+        SparseMatrix&, const Array<octave_idx_type>&),
+        SparseComplexMatrix& SparseComplexMatrix::insert (const
+        SparseComplexMatrix&, const Array<octave_idx_type>&)): ditto.
+        (SparseComplexMatrix (const dim_vector&, octave_idx_type)): ditto.
+        * CSparse.cc (SparseComplexMatrix& SparseComplexMatrix::insert (const
+        SparseMatrix&, const Array<octave_idx_type>&),
+        SparseComplexMatrix& SparseComplexMatrix::insert (const
+        SparseComplexMatrix&, const Array<octave_idx_type>&)): ditto.
+
+2007-08-19  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (Sparse<T>::permute): Avoid shadowing warning.
+
+2007-08-14  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.cc (Sparse<T>::permute): permutation vector is zero based.
+	Simplify.
+	(Sparse<T>::reshape): Warn about reshaping to N-d array.
+
+2007-08-10  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* file-stat.cc (file_stat::update_internal) [__WIN32__]:
+	Remove trailing dir separator when stat'ing directory except for
+	root directory.
+
+2007-07-25  David Bateman  <dbateman at free.fr>
+	
+	* Makefile.in: 	Adjust DISTFILES to allow out of tree "make dist" 
+	to work.
+
+2007-06-04  David Bateman  <dbateman at free.fr>
+
+	* oct-inttypes.h (octave_int<T>& operator <<= (const T2&),
+	octave_int<T>& operator >>= (const T2&)): Make shift operators
+	perform a twos complement arithmetic shift for both signed and
+	unsigned integers regardless of compiler implementations.
+
+2007-06-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* SparseCmplxQR.cc (OCTAVE_C99_ZERO): For CXSparse 2.2 and greater
+	use cs_complex_t(0,0) for the complex zero.
+
+	* MArray-ch.cc, MArray-d.cc, MArray-i.cc, MArray-s.cc:
+	Sprinkle class instantiations with OCTAVE_API as needed.
+
+	* Array.h (INSTANTIATE_ARRAY_ASSIGN, INSTANTIATE_ARRAY,
+	INSTANTIATE_ARRAY_AND_ASSIGN): New arg, API. Change all uses.
+	* MArray-defs.h (MARRAY_OP_ASSIGN_DECL, MARRAY_OP_ASSIGN_DECLS,
+	MARRAY_OP_ASSIGN_FWD_DECLS, MARRAY_OP_ASSIGN_FRIENDS,
+	MARRAY_OP_ASSIGN_DEFS, MARRAY_UNOP, MARRAY_UNOP_DECLS,
+	MARRAY_UNOP_FWD_DECLS, MARRAY_UNOP_FRIENDS, MARRAY_UNOP_DEFS,
+	MARRAY_BINOP_DECL, MARRAY_BINOP_DECLS, MARRAY_AA_BINOP_DECLS,
+	MDIAGARRAY2_DAS_BINOP_DECLS, MDIAGARRAY2_SDA_BINOP_DECLS,
+	MDIAGARRAY2_DADA_BINOP_DECLS, MARRAY_BINOP_FWD_DECLS,
+	MDIAGARRAY2_BINOP_FWD_DECLS, MARRAY_BINOP_FRIENDS,
+	MDIAGARRAY2_BINOP_FRIENDS, MARRAY_BINOP_DEFS,
+	MDIAGARRAY2_BINOP_DEFS, MARRAY_OPS_FORWARD_DECLS,
+	MDIAGARRAY2_OPS_FORWARD_DECLS, MARRAY_OPS_FRIEND_DECLS,
+	MDIAGARRAY2_OPS_FRIEND_DECLS, INSTANTIATE_MARRAY_FRIENDS,
+	INSTANTIATE_MARRAY2_FRIENDS, INSTANTIATE_MARRAYN_FRIENDS,
+	INSTANTIATE_MDIAGARRAY2_FRIENDS): Ditto.
+	* MSparse-defs.h (SPARSE_OP_ASSIGN_DECL, SPARSE_OP_ASSIGN_DECLS,
+	SPARSE_OP_ASSIGN_FWD_DECLS, SPARSE_OP_ASSIGN_FRIENDS,
+	SPARSE_OP_ASSIGN_DEFS, SPARSE_UNOP, SPARSE_UNOP_DECLS,
+	SPARSE_UNOP_FWD_DECLS, SPARSE_UNOP_FRIENDS, SPARSE_UNOP_DEFS,
+	SPARSE_BINOP_DECL, SPARSE_BINOP_DECLS, SPARSE_AA_BINOP_DECLS,
+	SPARSE_BINOP_FWD_DECLS, SPARSE_BINOP_FRIENDS, SPARSE_BINOP_DEFS,
+	SPARSE_OPS_FORWARD_DECLS, SPARSE_OPS_FRIEND_DECLS,
+	INSTANTIATE_SPARSE_FRIENDS): Ditto.
+	* Sparse-op-defs.h (SPARSE_BIN_OP_DECL, SPARSE_CMP_OP_DECL,
+	SPARSE_BOOL_OP_DECL, SPARSE_SMS_BIN_OP_DECLS,
+	SPARSE_SMS_CMP_OP_DECLS, SPARSE_SMS_EQNE_OP_DECLS,
+	SPARSE_SMS_BOOL_OP_DECLS, SPARSE_SSM_BIN_OP_DECLS,
+	SPARSE_SMS_OP_DECLS, SPARSE_SSM_BIN_OP_DECLS,
+	SPARSE_SSM_CMP_OP_DECLS, SPARSE_SSM_EQNE_OP_DECLS,
+	SPARSE_SSM_BOOL_OP_DECLS, SPARSE_SSM_OP_DECLS,
+	SPARSE_SMSM_BIN_OP_DECLS, SPARSE_SMSM_CMP_OP_DECLS,
+	SPARSE_SMSM_EQNE_OP_DECLS, SPARSE_SMSM_BOOL_OP_DECLS,
+	SPARSE_SMSM_OP_DECLS, SPARSE_MSM_BIN_OP_DECLS,
+	SPARSE_MSM_CMP_OP_DECLS, SPARSE_MSM_EQNE_OP_DECLS,
+	SPARSE_MSM_BOOL_OP_DECLS, SPARSE_MSM_OP_DECLS,
+	SPARSE_SMM_BIN_OP_DECLS, SPARSE_SMM_CMP_OP_DECLS,
+	SPARSE_SMM_EQNE_OP_DECLS, SPARSE_SMM_BOOL_OP_DECLS,
+	SPARSE_SMM_OP_DECLS): Ditto.
+	* Sparse.h (INSTANTIATE_SPARSE_ASSIGN, INSTANTIATE_SPARSE,
+	INSTANTIATE_SPARSE_AND_ASSIGN): Ditto.
+	* mx-op-defs.h (BIN_OP_DECL, CMP_OP_DECL, NDCMP_OP_DECL,
+	BOOL_OP_DECL, NDBOOL_OP_DECL, VS_BIN_OP_DECLS, VS_OP_DECLS,
+	SV_BIN_OP_DECLS, SV_OP_DECLS, VV_BIN_OP_DECLS, VV_OP_DECLS,
+	MS_BIN_OP_DECLS, MS_CMP_OP_DECLS, MS_BOOL_OP_DECLS, MS_OP_DECLS,
+	SM_BIN_OP_DECLS, SM_CMP_OP_DECLS, SM_BOOL_OP_DECLS, SM_OP_DECLS,
+	MM_BIN_OP_DECLS, MM_CMP_OP_DECLS, MM_BOOL_OP_DECLS, MM_OP_DECLS,
+	NDS_BIN_OP_DECLS, NDS_CMP_OP_DECLS, NDS_BOOL_OP_DECLS,
+	NDS_OP_DECLS, SND_BIN_OP_DECLS, SND_CMP_OP_DECLS,
+	SND_BOOL_OP_DECLS, SND_OP_DECLS, NDND_BIN_OP_DECLS,
+	NDND_CMP_OP_DECLS, NDND_BOOL_OP_DECLS, NDND_OP_DECLS,
+	SDM_BIN_OP_DECLS, SDM_OP_DECLS, DMS_BIN_OP_DECLS, DMS_OP_DECLS,
+	MDM_BIN_OP_DECLS, MDM_OP_DECLS, DMM_BIN_OP_DECLS, DMM_OP_DECLS,
+	DMDM_BIN_OP_DECLS, DMDM_OP_DECLS): Ditto.
+
+2007-06-12  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (Matrix::expm): Special case for scalar arg.
+	* CMatrix.cc (ComplexMatrix::expm): Likewise.
+
+2007-06-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* file-ops.cc (tilde_find_suffix, isolate_tilde_prefix,
+	tilde_expand_word): Use file_ops::is_dir_sep instead of comparing
+	with file_ops::dir_sep_char.
+
+	* MArray-C.cc: Sprinkle with OCTINTERP_API as needed.
+
+2007-06-04  David Bateman  <dbateman at free.fr>
+
+	* file-ops.cc: Typo.
+
+	* Sparse.cc (Sparse<T> Sparse<T>::reshape): If length of new
+	dimensions is greater than 2, collapse to 2-D.
+
+2007-06-02  David Bateman  <dbateman at free.fr>
+
+	* SparseCmplxQR.cc: Changes to support CXSparse 2.2.0.
+
+2007-05-31  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array::get_size): Throw std::bad_alloc exception if
+	the computed size is too large for the size of Octave's index type.
+
+2007-05-23  John W. Eaton  <jwe at octave.org>
+
+	* oct-sparse.h: Don't surround included files with extern "C" { ... }.
+
+2007-05-16  David Bateman  <dbateman at free.fr>
+
+	* dRowVector.cc (linspace): Return second argument if fewer than
+	two values are requested.
+	* CRowVector.cc (linspace): Likewise.
+
+2007-04-27  John W. Eaton  <jwe at octave.org>
+
+	* lo-mappers.cc (signum (const Complex&)): Special case for (0, 0).
+
+2007-04-25  John W. Eaton  <jwe at octave.org>
+
+	* oct-fftw.h (octave_fftw): Tag with OCTAVE_API.
+
+2007-04-20  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign1): For x(:) = RHS, require rhs_len == lhs_len,
+	not rhs_len == 1.
+
+2007-04-18  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* oct-md5.h (oct_md5, oct_md5_file): Tag decls with OCTAVE_API.
+
+2007-04-13  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::maybe_delete_elements_2): Don't return early
+	for empty matrix.  Only check for colon index equivalence if not empty.
+
+2007-04-10  John W. Eaton  <jwe at octave.org>
+
+	* SparseCmplxQR.cc
+	(SparseComplexQR::SparseComplexQR_rep::SparseComplexQR_rep):
+	Move GCC_ATTR_UNUSED before the parameter decl.
+	From Luis Ortiz  <lortiz at interactivesupercomputing.com>.
+
+2007-04-06  John W. Eaton  <jwe at octave.org>
+
+	* MArray-defs.h (MARRAY_NORM_BODY): New macro.
+	* MArray.h (MArray<T>::norm): New function.
+	* MArray.cc: Provide decl.
+	* MArray-d.cc (MArray<double>::norm): Define double specialization.
+	* MArray-C.cc (MArray<Complex>::norm): Define Complex specialization.
+
+2007-04-04  John W. Eaton  <jwe at octave.org>
+
+	* Range.cc (Range::nelem_internal): Likewise.
+	* lo-utils.cc (NINT): Use numeric_limits<int> instead of INT_MAX.
+	(NINTbig): Use numeric_limits<octave_idx_type> instead of INT_MAX.
+	From Scott Pakin <pakin at lanl.gov>.
+
+2007-04-04  David Bateman  <dbateman at free.fr>
+
+	* dMatrix.cc (Matrix::inverse): If calc_cond is true, calculate
+	the condition number for positive definite matrices.
+	* CMatrix.cc (ComplexMatrix::inverse): Ditto.
+	* dbleChol.h (CHOL(const Matrix&, bool)): New arg, calc_cond.
+	(CHOL(const Matrix&, octave_idx_type&, bool): Ditto.
+	(octave_idx_type init (const Matrix&, bool)): Ditto.
+	(CHOL(const CHOL&)): Copy xrcond.
+	(CHOL& operator = (const CHOL&)): Copy xrcond.
+	(xrcond): New private data member.
+	* CmplxCHOL.h (ComplexCHOL(const ComplexMatrix&, bool)): New arg,
+	calc_cond.
+	(ComplexCHOL(const ComplexMatrix&, octave_idx_type&, bool): Ditto
+	(octave_idx_type init (const ComplexMatrix&, bool)): Ditto.
+	(ComplexCHOL(const ComplexCHOL&)): Copy xrcond.
+	(ComplexCHOL& operator = (const ComplexCHOL&)): Copy xrcond.
+	(xrcond): New private data member.
+	* dbleCHOL.cc (CHOL::init(const Matrix&, bool)): If calc_cond is
+	true, calculate the condition number with dpocon.
+	* CmplxCHOL.cc (ComplexCHOL::init(const ComplexMatrix&, bool)): If
+	calc_cond is true, calculate the condition number with zpocon.
+
+2007-04-03  John W. Eaton  <jwe at octave.org>
+
+	* intNDArray.cc (intNDArray): Delete spurious semicolon.
+
+	* CMatrix.cc (ComplexMatrix::tinverse): Use Array<T> and
+	fortran_vec method instead of OCTAVE_LOCAL_BUFFER to avoid
+	"maybe clobbered by vfork" warning.
+
+	* Sparse-op-defs.h (SPARSE_CUMSUM): Add braces to avoid ambiguous
+	if/else.
+
+	* oct-spparms.h (octave_sparse_params): Define copy constructor
+	and destructor.
+
+	* Array.cc (assignN): Don't resize dimension if corresponding
+	index is empty.
+
+2007-04-02  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.h (Matrix::inverse): Reinstate versions without
+	MatrixType argument.
+	* CMatrix.h (ComplexMatrix::inverse): Likewise.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DISTDIRS): Delete variable.
+	(dist): Delete action for DISTDIRS.  Use ln instead of $(LN_S).
+
+2007-03-26  David Bateman  <dbateman at free.fr>
+
+	* MatrixType.cc: Replace all uses of the method
+	octave_sparse_params::get_key ("bandden") with 
+	octave_sparse_params::get_bandden (void).
+	(MatrixType::MatrixType (void)): Undo previous change but use
+	octave_sparse_params::get_bandden (void).
+	* oct-spparms.cc (get_bandden(void), do_get_bandden(void)): New
+	methods.
+	* oct-spparms.h (get_bandden(void), do_get_bandden(void)):
+	Declare them.	
+	
+2007-03-26  Luis Ortiz  <lortiz at interactivesupercomputing.com>
+	    David Bateman  <dbateman at free.fr>
+
+	* idx-vector.h.cc (IDX_VEC_REP::idx_vector_rep (const Range&)):
+	Check that all elements are ints before doing anything.  Simplify
+	calculation of index values.
+
+2007-03-26  David Bateman  <dbateman at free.fr>
+
+	* Range.cc (Range::all_elements_are_ints): Improve check.
+
+2007-03-26  John W. Eaton  <jwe at octave.org>
+
+	* chNDArray.cc, chMatrix.cc: Also generate comparison and bool ops.
+	* chNDArray.h, chMatrix.h: Provide decls.
+
+2007-03-24  Luis Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* MatrixType.cc (MatrixType::MatrixType (void)): Initialize
+	sp_bandden to zero for performance reasons as it's not used.
+
+2007-03-23  David Bateman  <dbateman at free.fr>
+
+	* oct-rand.cc (octave_rand::seed): Seed differently for big and
+	little endian.
+
+2007-03-15  John W. Eaton  <jwe at octave.org>
+
+	* lo-mappers.cc (acos): Use formula similar to what we use for asin.
+	From Alexander Barth <abarth at marine.usf.edu>.
+
+2007-03-12  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int::octave_int (double)):
+	New Specialization.  Round arg.
+	(operator / (const octave_int<T1>&, const octave_int<T2>&)):
+	Round result before converting type.
+
+2007-03-07  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign1): Avoid resizing if there is an error.
+
+	* dMatrix.cc, CMatrix.cc (operator *): Only check
+	f77_exception_encountered immediately after calls that use F77_XFCN.
+
+	* Array.cc (assign1 (Array<LT>&, const Array<RT>&, const LT&)):
+	Only allow resizing empty LHS if it is 0x0.
+
+	* Array.cc (Array<T>::maybe_delete_elements (Array<idx_vector>&,
+	const T&)): Handle case of more indices than dimensions.
+	(assign (Array<LT>&, const Array<RT>&, const LT&)): Allow more
+	cases to be handled by assignN.
+	(assignN (Array<LT>&, const Array<RT>&, const LT&)):
+	Special cases for 2-d array assignments for speed.
+	Improve handling of scalar RHS and empty indices.
+
+2007-03-05  David Bateman  <dbateman at free.fr>
+
+	* oct-md5.c (oct_md5_file (const std::string&)): New function.
+	* oct-md5.h (oct_md5_file (const std::string&)): Declare it.
+
+2007-03-02  John W. Eaton  <jwe at octave.org>
+
+	* str-vec.h (string_vector::empty): Return bool, not int.
+
+2007-03-01  David Bateman  <dbateman at free.fr>
+
+        * md5.h, md5.c: New files from libmd5-rfc sourceforge project for
+        an independent implementation of RFC1321.
+        * oct-md5.h, oct-md5: New files for treating std::string class
+        with MD5.
+        * Makefile.in (INCLUDES): Add md5.h and oct-md5.h
+        (LIBOCTAVE_CXX_SOURCES): Add oct-md5.cc
+        (LIBOCTAVE_C_SOURCES): Add md5.c
+
+2007-02-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (uninstall): Delete files listed in
+	$(INCLUDES_FOR_INSTALL), instead of $(INCLUDES).
+	From Thomas Treichl <Thomas.Treichl at gmx.net>.
+
+2007-02-27  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* file-ops.cc (file_ops::recursive_rmdir):
+	Close dir_entry object before calling rmdir.
+
+2007-02-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Use $(LN_S) instead of ln or ln -s.
+
+	* sparse-util.h (SparseCholPrint, SparseCholError):
+	Tag with OCTAVE_API.
+
+2007-02-18  David Bateman  <dbateman at free.fr>
+
+	* oct-rand.cc (do_old_initialization()): call setcgn(1) prior to
+	calling setall and reset to the current generator after.
+
+2007-02-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-shlib.h (octave_shlib::relative): New data member.
+	(octave_shlib::mark_relative, octave_shlib::is_relative):
+	New functions.
+
+2007-02-16  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* lo-sysdep.cc (octave_popen2): New function to simulate popen2 on
+	windows platform.
+	* lo-sysdep.h (octave_popen2): Declare it.
+	* oct-syscalls.cc (octave_syscalls::popen2): New function.
+	* oct-syscalls.h (octave_syscalls::popen2): Declare it.
+
+2007-02-14  John W. Eaton  <jwe at octave.org>
+
+	* kpse.cc (expand_elt): Omit special treatment for //.
+
+2007-02-06  John W. Eaton  <jwe at octave.org>
+
+	* file-ops.cc (file_ops::canonicalize_file_name) [HAVE_REALPATH]:
+	Don't delete value returned from realpath.
+
+2007-02-05  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* file-ops.cc (file_ops::canonicalize_file_name):
+	Provide implementation if realpath function is available.
+
+2007-01-29  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* oct-fftw.h: Sprinkle with OCTAVE_API as needed.
+
+2007-01-17  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* lo-sysdep.cc (octave_chdir): Handle directory names like "C:" on
+	Windows systems.
+
+2007-01-16  John W. Eaton  <jwe at octave.org>
+
+	* dSparse.cc: Fix dgbtrf decl for --enable-64.
+	(SparseMatrix::bsolve): Fix call to dgbtrf for --enable-64
+
+	* oct-fftw.h (fftw_planner): Provide decl.
+
+2007-01-11  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in (LINK_DEPS): Include $(CAMD_LIBS) in the list.
+
+2007-01-10  John W. Eaton  <jwe at octave.org>
+
+	* oct-sparse.h: Use HAVE_CHOLMOD_CHOLMOD_H, not
+	HAVE_UMFPACK_CHOLMOD_H for case of "cholmod/cholmod.h".
+
+2007-01-08  David Bateman  <dbateman at free.fr>
+
+	* oct-sparse.h: Replace sparsesuite with suitesparse and
+	SPARSESUITE with SUITESPARSE to match upstream name.
+
+2007-01-05  David Bateman  <dbateman at free.fr>
+
+	* oct-fftw.cc: (octave_fftw_planner::method (void), 
+	octave_fftw_planner (FftwMethod)): New methods to interrogate and
+	set the FFTW wisdom method used.
+	(octave_fftw_planner::create_plan) Modify to allow different 
+	methods to be used.
+	(octave_fftw_planner): Move class definition from here.
+	* oct-fftw.h (octave_fftw_planner): To here. Add method methods
+	and FftwMethod enum.
+
+2007-01-03  David Bateman  <dbateman at free.fr>
+
+	* MSparse.cc (SPARSE_A2A2_OP, SPARSE_A2A2_FCN_1,
+	SPARSE_A2A2_FCN_1): Modify macros so that scalars stored as
+	sparse matrices are special cased.
+
+	* Sparse-op-defs.h: Include mx-ops.h to have access to mixed
+	matrix, sparse matrix operations.
+	(SPARSE_SMSM_BIN_OP_1, SPARSE_SMSM_BIN_OP_2, SPARSE_SMSM_BIN_OP_3,
+	SPARSE_SMSM_CMP_OP, SPARSE_SMSM_BOOL_OP, SPARSE_MSM_BIN_OP_1,
+	SPARSE_MSM_BIN_OP_2, SPARSE_MSM_CMP_OP, SPARSE_MSM_BOOL_OP,
+	SPARSE_SMM_BIN_OP_1, SPARSE_SMM_BIN_OP_2, SPARSE_SMM_CMP_OP, 
+	SPARSE_SMM_BOOL_OP, SPARSE_SPARSE_MUL, SPARSE_FULL_MUL, 
+	FULL_SPARSE_MUL): Modify macros so that scalars stored as
+	sparse matrices are special cased.
+
+2006-12-22  David Bateman  <dbateman at free.fr>
+
+	* boolSparse.cc (SparseBoolMatrix::operator !): Fix off-by-one error.
+
+2006-12-22  John W. Eaton  <jwe at octave.org>
+
+	* dim-vector.h (dim_vector::dim_vector): Always start with at
+	least 2 dimensions.
+	(dim_vector::resize): Don't allow resizing to fewer than 2 dimensions.
+
+2006-12-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* lo-sysdep.cc (opendir): Avoid passing \\* to FindFirstFile.
+
+	* file-ops.cc (ops::canonicalize_file_name): Provide partial
+	implementation for Windows.
+
+2006-12-06  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc (SparseMatrix::is_symmetric): Faster implementation.
+	* CSparse.cc (SparseComplexMatrix::is_symmetric): Ditto.
+
+	* dMatrrix.cc (finverse): Old inverse method renamed inverse.
+        (tinverse): New method for triangular matrices.
+        (inverse): New function with matrix type probing.
+        * dMatrix.h (finverse, tinverse, inverse): New and modified
+        declarations.
+        * CMatrix.cc: Ditto.
+        * CMatrix.h: Ditto.
+
+2006-12-06  John W. Eaton  <jwe at octave.org>
+
+	* strptime.c (day_of_the_week): Use code from current glibc sources.
+
+2006-12-05  John W. Eaton  <jwe at octave.org>
+
+	* lo-utils.cc (octave_read_double): If we see '+' or '-' but not
+	followed by 'I' or 'i', try reading number after putting
+	characters back on input stream.
+
+2006-12-05  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* randpoisson.c (oct_fill_randp): For lambda > 1e8, upper limit of
+	loop is n, not L.
+
+2006-11-30  John W. Eaton  <jwe at octave.org>
+
+	* lo-utils.cc (octave_read_double, read_inf_nan_na):
+	Also recognize [+-][Ii]nf.
+
+2006-11-28  David Bateman  <dbateman at free.fr>
+
+	* oct-sparse.h: Allow sparse headers to also be in a sparsesuite
+	sub-directory.
+
+        * dSparse.cc (SparseMatrix::inverse): Transpose the matrix type as
+	well when calling tinverse for lower triangular matrices.
+        * CSparse.cc (SparseComplexMatrix::inverse):
+        Ditto.
+					
+2006-11-21  John W. Eaton  <jwe at octave.org>
+
+	* oct-env.cc (do_absolute_pathname): Undo previous change.
+
+2006-11-20  John W. Eaton  <jwe at octave.org>
+
+	* oct-env.cc (octave_env::do_absolute_pathname): Also return true
+	for ".", and names beginning with "./" or "../".
+
+2006-11-14  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* CMatrix.cc, dMatrix.cc: New tests.
+
+2006-11-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Array-d.cc, dDiagMatrix.h: Sprinkle with OCTAVE_API as needed.
+
+2006-11-11  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in ($(OPTS_INC), mx-ops.h):
+	Use $(simple-move-if-change-rule) here.
+
+2006-11-09  David Bateman  <dbateman at free.fr>
+
+	* sparse-base-chol.cc (sparse_base_chol_rep::Q): Cast perms(i) to
+	octave_idx_type, not int.
+
+2006-11-08  John W. Eaton  <jwe at octave.org>
+
+	* dir-ops.cc (dir_entry::read): Avoid rewinddir.
+
+2006-11-06  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Exit early if invalid indices are found.
+
+2006-11-03  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* strftime.c [HAVE_TZNAME]: Tag tzname with OCTAVE_IMPORT.
+
+2006-11-03  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DLL_CXXDEFS): Rename from XTRA_CXXDEFS.
+	(DLL_CDEFS): Rename from XTRA_CDEFS.
+	Substitute OCTAVE_DLL_DEFS, not XTRA_OCTAVE_DEFS.
+
+2006-10-28  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* oct-shlib.cc: Undefine min and max after including windows.h.
+	* oct-syscalls.cc (syscalls::pipe (int *)): Avoid infinite recursion.
+	* lo-sysdep.h: Move opendir, readdir, etc. decls here from
+	lo-sysdep.cc.
+
+2006-10-27  John W. Eaton  <jwe at octave.org>
+
+	* oct-time.cc [! HAVE_STRFTIME]: Declare strftime.
+
+2006-10-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* mx-op-defs.h (NDS_CMP_OP1, NDS_CMP_OPS1, NDS_CMP_OP2,
+	NDS_CMP_OPS2): New macros.
+
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* mx-ops (core-type): New field for integer types.
+	* mk-ops.awk: Handle core-type for integer comparison ops.
+
+	* lo-cutils.c (octave_strcasecmp, octave-strncasecmp):
+	Move here from src/cutils.c.
+	* lo-utils.h: Provide decls.
+	* strcasecmp.c: Move here from src/strcasecmp.c.
+	* strncase.c: Move here from src/strncase.c.
+	* Makefile.in (LIBOCTAVE_C_SOURCES): Add them to the list.
+
+2006-10-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* kpse.cc [! MSVC]: Don't include win32lib.h.
+
+	* Array-C.cc, Array-b.cc, Array-ch.cc, Array-i.cc, Array-util.h,
+	Array.h, CColVector.h, CMatrix.h, CNDArray.h, CRowVector.h,
+	CSparse.h, CmplxAEPBAL.h, CmplxCHOL.h, CmplxDET.h, CmplxHESS.h,
+	CmplxLU.h, CmplxQR.h, CmplxQRP.h, CmplxSCHUR.h, CmplxSVD.h,
+	CollocWt.h, DAE.h, DASPK.h, DASRT.h, DASSL.h, EIG.h, LSODE.h,
+	MArray-C.cc, MArray-defs.h, MSparse-C.cc, MSparse-d.cc,
+	MSparse-defs.h, MatrixType.h, NLEqn.h, Quad.h, Range.h,
+	Sparse-op-defs.h, Sparse.h, SparseCmplxCHOL.h, SparseCmplxLU.h,
+	SparseCmplxQR.h, SparseQR.h, SparsedbleCHOL.h, SparsedbleLU.h,
+	boolMatrix.h, boolNDArray.h, boolSparse.h, chMatrix.h,
+	chNDArray.h, cmd-edit.h, cmd-hist.h, dColVector.h, dDiagMatrix.h,
+	dMatrix.h, dNDArray.h, dRowVector.h, dSparse.h, data-conv.h,
+	dbleAEPBAL.h, dbleCHOL.h, dbleDET.h, dbleHESS.h, dbleLU.h,
+	dbleQR.h, dbleQRP.h, dbleSCHUR.h, dbleSVD.h, dir-ops.h,
+	file-ops.h, file-stat.h, glob-match.h, idx-vector.h,
+	int16NDArray.cc, int32NDArray.cc, int64NDArray.cc, int8NDArray.cc,
+	lo-cutils.c, lo-ieee.h, lo-mappers.h, lo-specfun.h, lo-utils.h,
+	mach-info.h, mx-op-defs.h, oct-alloc.h, oct-env.h, oct-group.h,
+	oct-inttypes.cc, oct-inttypes.h, oct-passwd.h, oct-rand.h,
+	oct-shlib.h, oct-spparms.h, oct-syscalls.h, oct-time.h,
+	oct-uname.h, pathsearch.h, prog-args.h, so-array.h, str-vec.h,
+	uint16NDArray.cc, uint32NDArray.cc, uint64NDArray.cc,
+	uint8NDArray.cc: Sprinkle with OCTAVE_API as needed.
+
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.cc (INSTANTIATE_INTTYPE_BIN_OP): Provide explicit
+	type qualification for OP.
+
+2006-10-26  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (Sparse<T>::resize_no_fill (octave_idx_type,
+	octave_idx_type)): Be more careful with the size of the input
+	matrix, and therefore don't create or read non existent data.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.cc (assign): Clear lhs index after error.
+
+2006-10-25  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (assign (Sparse<LT>&, const Sparse<RT>&)):
+	Fix previous patch so it works.
+
+2006-10-25  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* glob-match.h (glob_match::glob_match (const std::string&,
+	unsigned int)): Delete initializer for first arg.
+
+	* lo-sysdep.cc (opendir, readdir, rewinddir, closedir):
+	New functions.
+
+	* Makefile.in (XTRA_CDEFS, XTRA_CXXDEFS): Substitute here.
+
+	* oct-env.cc (octave_env::do_get_home_directory) [_MSC_VER]: Use
+	same code as __MINGW32__.
+	* syswait.h [_MSC_VER]: Define HAVE_WAITPID, WAITPID, and WNOHANG
+	the same as for __MINGW32__.
+
+	* randpoisson.c: Undefine INFINITE before redefining.
+
+2006-10-24  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (assign (Sparse<LT>&, const Sparse<RT>&)): Resize the
+	lhs at the point we know the assignment can succeed if the lhs is
+	empty.
+
+2006-10-23  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign2): Don't require vector assignments to be oriented.
+
+2006-10-17  John W. Eaton  <jwe at octave.org>
+
+	* lo-cieee.c: If isnan is not available but _isnan is, then define
+	isnan to be _isnan, and define HAVE_ISNAN.  Likewise for _finite
+	and _copysign.
+
+2006-10-17  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* oct-syscalls.cc (syscalls::waitpid): Always declare and define retval.
+
+	* CMatrix.cc (ComplexMatrix::solve): Avoid infinite recursion. 
+	* CSparse.cc (SparseComplexMatrix::insert): Likewise.
+
+	* oct-types.h.in: Include limits.h, for CHAR_BIT.
+
+2006-10-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Adapt rules to use $(LIBPRE).
+
+2006-10-03  David Bateman  <dbateman at free.fr>
+
+	* MatrixType.cc (MatrixType::MatrixType): Avoid crash if np == 0
+	or p == 0.
+
+2006-10-02  John W. Eaton  <jwe at octave.org>
+
+	* dbleDET.cc (DET::initialize2): Ensure arg to log10 is double.
+	* CmplxDET.cc (ComplexDET::initialize2): Likewise.
+
+2006-09-22  David Bateman  <dbateman at free.fr>
+
+	* MatrixType.h (MatrixType::MatrixType(const SparseComplexMatrix&)): 
+	Remove spurious warning. 
+
+2006-09-15  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::index (Array<idx_vector>&, int, const T&) const): 
+	Handle resizing.
+
+	* intNDArray.h (intNDArray<T>:elt_type): New typedef.
+
+2006-09-11  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (operator * (const Matrix&, const Matrix&))):
+	Handle M*v and rv*cv special cases. 
+	* CMatrix.cc (operator * (const ComplexMatrix&, const
+	ComplexMatrix&))): Likewise.
+	From Luis F. Ortiz <lortiz at interactivesupercomputing.com>.
+
+	* dRowVector.cc (operator * (const RowVector&, const
+	ColumnVector&)): Call xddot here instead of using a Fortran
+	function directly.
+	* CRowVector.cc (operator * (const ComplexRowVector&, const
+	ComplexColumnVector&)): Call xzdotu here.
+
+2006-09-05  John W. Eaton  <jwe at octave.org>
+
+	* chNDArray.cc (charNDArray::any, charNDArray::all): Compare
+	elements to '\0', not ' '.
+
+2006-08-25  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Special case for 0x0 arrays.
+
+2006-08-23  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc, dMatrix.h (Matrix::save_ascii): Delete function and decl.
+	* CMatrix.cc, CMatrix.h (ComplexMatrix::save_ascii): Likewise.
+
+2006-08-22  John W. Eaton  <jwe at octave.org>
+
+	* CMatrix.cc (ComplexMatrix::save_ascii): New function.
+	* dMatrix.cc (Matrix::save_ascii): New function.
+
+	* mx-inlines.cc (MX_ND_CUMULATIVE_OP): Correctly detect empty arrays.
+	If array is empty, return value is same size as array.
+	(MX_ND_REDUCTION): Correctly detect empty arrays.
+	If array is empty, produce correctly sized return value.
+
+2006-08-18  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (Matrix::any_element_not_one_or_zero): New function.
+	* dMatrix.h: Provide decl.
+	* dNDArray.cc (NDArray::any_element_not_one_or_zero): New function.
+	* dNDArray.h: Provide decl.
+	* intNDArray.cc (intNDArray<T>::any_element_not_one_or_zero):
+	New function.
+	* intNDArray.h: Provide decl.
+
+	* Array.cc (Array<T>::permute): Only rearrange values if array is
+	not empty.
+
+2006-07-26  John W. Eaton  <jwe at octave.org>
+
+	* dbleDET.cc (DET::initialize10, DET::value_will_underflow,
+	DET::value_will_overflow): Use xlog2 instead of log2.
+	(DET::initialize2, DET::initialize10): Use xround instead of round.
+	(DET::initialize2, DET::value): Use xexp2 instead of exp2.
+	* CmplxDET.cc (ComplexDET::initialize10,
+	ComplexDET::value_will_underflow,
+	ComplexDET::value_will_overflow): Use xlog2 instead of log2.
+	(ComplexDET::initialize2, ComplexDET::initialize10):
+	Use xround instead of round.
+	(ComplexDET::initialize2, ComplexDET::value):
+	Use xexp2 instead of exp2.
+
+	* lo-mappers.cc (M_LOG10E): Delete unused macro.
+	(xlog2, xexp2): New functions.
+	* lo-mappers.h: Provide decls.
+
+2006-07-22  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.h (Sparse<T>::mex_get_data, Sparse<T>::mex_get_ir,
+	Sparse<T>::mex_get_jc): New functions.
+
+2006-07-21  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int<T>::mex_get_data): New function.
+	* Array.h (Array<T>::mex_get_data): New function.
+
+2006-07-19  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int::operator bool (void)): New function.
+
+2006-07-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-spparms.h, oct-spparms.cc (class octave_sparse_params):
+	Rename from SparseParams.  Use same implementation method as other
+	singleton classes in Octave.  Change all uses of
+	Voctave_sparse_controls to use static functions from
+	octave_sparse_params class instead.
+
+	* oct-spparms.h, oct-spparms.cc (SparseParams::set_key,
+	SparseParams::get_key): Pass std::string arg by const reference,
+	not const value.
+
+2006-07-15  John W. Eaton  <jwe at octave.org>
+
+	* data-conv.cc: Instantiante swap_bytes templates here.
+
+	* MatrixType.cc (MatrixType::MatrixType):
+	Use complete initializer lists in constructors.
+
+2006-07-06  John W. Eaton  <jwe at octave.org>
+
+	* str-vec.cc (string_vector::string_vector (std::list<std::string>&)):
+	New constructor.
+	* str-vec.h: Provide decl.
+
+2006-07-01  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc (tinverse): Check for rows with no elements and zero
+	elements on the diagonal. Allow both Upper and Lower triangular
+	matrices to be treated.
+	* CSparse.cc (tinverse): ditto.
+	* Sparse-op-defs.h (SPARSE_SPARSE_MUL): Take into account 64-bit
+	constant assignment.
+	
+2006-06-30  John W. Eaton  <jwe at octave.org>
+
+	* lo-sysdep.cc (octave_chdir): Perform tilde expansion here.
+	* cmd-edit.cc (editor::read_init_file): Ditto.
+	* dir-ops.cc (dir_entry::open): Ditto.
+	* file-stat.cc (stat::update_internal): Ditto.
+	* cmd-hist.cc (command_history::set_file): Ditto.
+
+	* data-conv.cc (data_conv::string_to_data_type):
+	Correctly handle leading "*".
+
+2006-06-29  Atsushi Kajita  <a-kajita at mizar.freemail.ne.jp>
+
+	* Sparse.cc (Sparse<T>::SparseRep::elem): Avoid out of bounds
+	array access.
+	
+2006-06-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in: Finish renaming of OBJECTS -> LIBOCTAVE_OBJECTS.
+
+2006-06-21  John W. Eaton  <jwe at octave.org>
+
+	* oct-shlib.cc (octave_dlopen_shlib::close,
+	octave_shl_load_shlib::close, octave_w32_shlib::close):
+	Skip do_close_hook if cl_hook is 0.
+
+2006-06-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-sort.h: Don't include config.h, lo-mappers.h, or quit.h.
+	* randmtzig.h: Don't inlcude config.h.
+
+2006-05-31  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (assignN): Maybe reshape LHS before doing assignment.
+
+2006-05-23  John W. Eaton  <jwe at octave.org>
+
+	* oct-types.h.in: Include stdint.h or inttypes.h for integer
+	typedefs, or define them if those files are not available.
+	* oct-inttypes.h (octave_int8_t, octave_int16_t, octave_int32_t,
+	octave_int64_t, octave_uint8_t, octave_uint16_t, octave_uint32_t,
+	octave_uint64_t): Delete typedefs.  Replace all uses of these
+	types with int8_t, int16_t, etc.
+	* data-conv.h (TWO_BYTE_INT, FOUR_BYTE_INT, EIGHT_BYTE_INT):
+	Delete definitions.  Replace all uses of these macros with int8_t,
+	int16_t, etc.
+	* randmtzig.h: Delete integer typedefs.
+
+2006-05-18  John W. Eaton  <jwe at octave.org>
+
+	* EIG.cc (EIG::init): Trap Inf and NaN values here.
+	From Keith Goodman <kwgoodman at gmail.com>.
+
+2006-05-08  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_SPARSE_MUL): fix bug in previous
+	modification.
+
+2006-05-09  David Bateman  <dbateman at free.fr>
+
+	* sparse-dmsolve.cc: Remove reference to ov-re-sparse.h,
+	ov-cx-sparse. and error_state.
+	* SparseQR.cc, SparseCmplxQR.cc (qrsolve): Return info = -1 on error.
+	
+2006-05-08  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_SPARSE_MUL): Set column pointers in
+	first pass and use to determine which algorithm to use on a
+	column-by-column basis.
+
+2006-05-04  David Bateman  <dbateman at free.fr>
+
+	* SparseQR.cc, SparseQR.h, SparseCmplxQR.cc, SparseCmplxQR.h,
+	sparse-dmsolve.cc : Allow compilation with versions v2.0.0 of
+	CXSparse or later
+
+2006-05-03  David Bateman  <dbateman at free.fr>
+
+	* CMatrix.cc (zpotrf, zpocon, zpotrs, ztrcon, ztrtrs):
+	External declaration of lapack triangular and Cholesky codes.
+	(ComplexMatrix::utsolve, ComplexMatrix::ltsolve, 
+	ComplexMatrix::fsolve): New private solver codes for
+        upper, lower and LU/Cholesky solvers.
+	(ComplexMatrix::solve): New versions for cached matrix
+	type. Adapt old versions to call new versions
+	* CMatrix.h (utsolve, ltsolve, fsolve): Declaration of
+	new solvers.
+	(solve): New versions for cached matrix type.
+	* dMatrix.cc (dpotrf, dpocon, dpotrs, dtrcon, dtrtrs):
+	External declaration of lapack triangular and Cholesky codes.
+	(Matrix::utsolve, Matrix::ltsolve, 
+	Matrix::fsolve): New private solver codes for
+        upper, lower and LU/Cholesky solvers.
+	(Matrix::solve): New versions for cached matrix
+	type. Adapt old versions to call new versions
+	* dMatrix.h (utsolve, ltsolve, fsolve): Declaration of
+	new solvers.
+	(solve): New versions for cached matrix type.
+	* CSparse.cc: Replace all uses of SparseType with MatrixType.
+	* CSparse.h: ditto.
+	* dSparse.cc: ditto.
+	* dSparse.h: ditto.
+	* SparseCmplxCHOL.cc: ditto.
+	* SparsedbleCHOL.cc: ditto.
+	* sparse-dmsolve.cc: ditto.
+	* SparseType.cc, SparseType.h: delete.
+	* MatrixType.cc: New file for class to cache matrix type, based on
+	old SparseType class but caching matrix and sparse types.
+	* MatrixType.h: ditto.
+	* Makefile.in (MATRIX_INC, MATRIX_SRC): Add MatrixType.h and
+	MatrixType.cc respectively. Delete SparseType.h and SparseType.cc
+	respectively.
+	* mx-base.h: Include MatrixTye.h as header file.
+	
+2006-05-01  John W. Eaton  <jwe at octave.org>
+
+	* oct-shlib.h (octave_shlib::octave_shlib, octave_shlib::open):
+	Delete WARN_FUTURE arg.  Change all uses.
+	* oct-shlib.cc (octave_base_shlib::stamp_time): Delete arg.
+	Change all uses.  Use current_liboctave_warning_with_id_handler.
+	(octave_base_shlib::open): Delete arg.  Change all derived classes
+	and uses.
+
+2006-04-29  John W. Eaton  <jwe at octave.org>
+
+	* Array-flags.cc, Array-flags.h: Delete.
+	* Makefile.in (MATRIX_SRC): Remove Array-flags.cc from the list.
+	(MATRIX_INC): Remove Array-flags.h from the list.
+
+	* idx-vector.cc (IDX_VEC_REP::freeze): Delete warn_resize arg.
+	Use current_liboctave_warning_with_id_handler
+	with warning ID Octave:resize-on-range-error.
+	* idx-vector.h: Fix decl.
+	* Array.cc, Sparse.cc: Change all callers.
+
+	* Array.cc (Array<T>::maybe_delete_elements, Array<T>::index2,
+	assign2, assignN): Use current_liboctave_warning_with_id_handler
+	with warning ID Octave:fortran-indexing instead of
+	liboctave_wfi_flag.
+	* Sparse.cc (assign, Sparse<T>::index): Likewise.
+
+2006-04-26  John W. Eaton  <jwe at octave.org>
+
+	* pathsearch.cc (dir_path::path_sep_char, dir_path::path_sep_str):
+	New static data.
+	* pathsearch.h: Provide decls.
+	(dir_path::is_path_sep): New function.
+
+2006-04-18  John W. Eaton  <jwe at octave.org>
+
+	* randmtzig.c (randmt, randi53, randi54, randi64, randu32, randu53):
+	Omit inline from decl.
+
+	* Sparse.cc (Sparse<T>::index): Use std::vector<bool> to avoid
+	local array with variable dimension.
+
+2006-04-16  John W. Eaton  <jwe at octave.org>
+
+	* lo-sstream.h: Delete.
+	* Makefile.in (INCLUDES): Remove it from the list.
+
+	* dim-vector.h (dim_vector::str): Use std::ostringstream directly.
+	* Sparse.cc (Sparse::range_error): Likewise.
+	* DASSL.cc (DASSL::error_message): Likewise.
+	* LSODE.cc (LSODE::error_message): Likewise.
+	* DASRT.cc (DASRT::error_message): Likewise.
+	* DASPK.cc (DASPK::error_message): Likewise.
+	* Array.cc (Array::range_error): Likewise.
+
+	* kpse.cc (kpse_hash): Rename from hash.
+	(hash_lookup): Call kpse_hash instead of hash.
+
+	* SparseType.cc (SparseType::SparseType): Use std::vector<bool>
+	to avoid local array with variable dimension.
+
+2006-04-13  David Bateman  <dbateman at free.fr>
+
+        * Sparse.cc (assign (Sparse<LT>&, const Sparse<RT>&)):
+	Optimize assignment.
+
+2006-04-13  John W. Eaton  <jwe at octave.org>
+
+        * Sparse.cc (assign (Sparse<LT>&, const Sparse<RT>&)):
+	Eliminate unnecessary casts.
+	* SparsedbleLU.cc (SparseLU::SparseLU): Likewise.
+
+	* kpse.cc (fopen): Use reinterpret_cast instead of C-style cast.
+	(log_search, dir_links): Use static_cast instead of C-style cast.
+
+	* prog-args.cc (args::getopt): Use reinterpret_cast instead of X_CAST.
+	* oct-alloc.cc (allocator::grow): Likewise.
+	* CSparse.cc (SparseComplexMatrix::determinant,
+	SparseComplexMatrix::factorize, SparseComplexMatrix::fsolve):
+	Likewise.
+	* SparseCmplxLU.cc (SparseComplexLU::SparseComplexLU): Likewise.
+
+	* oct-sort.cc (roundupsize, octave_sort<T>::merge_getmem):
+	Use static_cast instead of C-style cast.
+	* CSparse.cc (SparseComplexMatrix::fsolve): Likewise.
+	* dSparse.cc (SparseMatrix::fsolve): Likewise.
+
+	* data-conv.cc (LS_DO_WRITE): Use static_cast for value conversion.
+	Use OCTAVE_LOCAL_BUFFER instead of new/delete.
+	(LS_DO_READ): Allocate local buffer to avoid pointer tricks.
+	(write_doubles, read_doubles, LS_DO_WRITE, LS_DO_READ):
+	Use reinterpret_cast instead of X_CAST.
+
+	* DiagArray2.h (DiagArray2::Proxy::operator&): No need to cast
+	return value here.
+
+2006-04-12  Rafael Laboissiere  <rafael at debian.org>
+
+	* ArrayN.h (ArrayN::ArrayN): Qualify fill with Array<T> base class.
+	* DiagArray2.h (DiagArray2::DiagArray2): Likewise.
+
+2006-04-03  David Bateman  <dbateman at free.fr>
+
+	* Sparse.cc (Sparse<T>::resize): Use xcidx rather than cdix, etc
+	to avoid copy of original matrix.
+
+	* Makefile.in (INCLUDES): Add randgamma.h, randpoisson.h and
+        randmtzig.h to the list.
+	(LIBOCTAVE_C_SOURCES): Add randgamma.c, randpoisson.c and
+        randmtzig.c to the list.
+	* oct-rand.cc (do_old_initialization): Rename from do_initialization.
+	(use_old_generators): New variable.
+	(old_initialized): Rename from initialized.
+	(new_initialized): New variable.
+	(oct_init_by_entropy): New function.
+	(maybe_initialize): Initialize new or old generator depending on
+	value of use_old_generators.
+	(octave_rand::state): New functions.
+	(octave_rand::distribution): Add gamma, exponential and poisson
+	distributions.
+	(octave_rand::exponential_distribution,
+	octave_rand::poisson_distribution,
+	octave_rand::gamma_distribution): New methods to select
+        exponential, poisson or gamma distribution.
+	(octave_rand::scalar, octave_rand::matrix, octave_rand::nd_array,
+	octave_rand::vector): Add new distributions.
+	* oct-rand.h: Provide decls for new functions.
+	(octave_rand::matrix, octave_rand::scalar, octave_rand::
+	(octave_rand::scalar, octave_rand::matrix, octave_rand::nd_array,
+	octave_rand::vector): New arg A, for gamma and poisson distributions.
+	* randpoisson.c, randpoisson.h, randgamma.c, randmtzig.c,
+        randmtzig.h: New files.
+
+2006-03-24  John W. Eaton  <jwe at octave.org>
+
+	* dSparse.cc (SparseMatrix::bsolve): Integer work vector is
+	Array<octave_idx_type>, so fortran_vec returns pointer to
+	octave_idx_type, not pointer to int.
+
+	* CMatrix.cc, CMatrix.h (ComplexMatrix::row (char*),
+	ComplexMatrix::column (char*)): Delete.
+	* dMatrix.cc, dMatrix.h (Matrix::row (char*),
+	Matrix::column (char*)): Delete.
+
+2006-03-21  David Bateman  <dbateman at free.fr>
+
+	* SparseQR.h: Publish externally used friends.
+	* SparseCmplxQR.h: ditto.
+
+2006-03-21  John W. Eaton  <jwe at octave.org>
+
+	* lo-specfun.cc (betainc): Use F77_XFCN instead of F77_FUNC for
+	call to xdbetai.
+
+2006-03-21  David Bateman  <dbateman at free.fr>
+
+	* lo-specfun.cc (xlgamma, xgamma): Trap special values.
+	(xlgamma): Use F77_XFCN instead of F77_FUNC for call to dlgams.
+
+	* dSparse.cc (solve): Add argument singular_fallback, to allow
+	fallback to QR solvers to be optional.
+	* CSparse.cc (solve): Ditto.
+	* dSparse.h (solve): update declaration for new argument.
+	* CSparse.h (solve): Ditto.
+	* sparse-dmsolve.cc (dmsolve): Use singular_fallback argument
+	to bypass QR solvers when solving the well determined part of
+	the problem.
+
+2006-03-17  John W. Eaton  <jwe at octave.org>
+
+	* str-vec.cc (vector::list_in_columns): New optional arg, width.
+
+2006-03-16  David Bateman  <dbateman at free.fr>
+
+	* CSparse.cc: Change use of nzmax to nnz to allow automatic
+	reduction of matrix size, except for a couple of cases where nzmax
+	is needed.
+	(zpbcon): Correct declaration of lapack zpbcon function.
+	(dsolve, utsolve, ltsolve, trisolve, bsolve, factorize, fsolve): Add
+	an argument to allow the calculation of condition number to be
+	optional.
+	(bsolve): Add code for the calculation of the condition number
+	using zpbcon and zgbcon.
+	(dsolve): Bug fix for rectangular matrices with sparse RHS.
+	(utsolve, ltsolve, trisolve, bsolve, fsolve): Mark matrix type as
+	singular if singularity is detected.
+	(solve): Use optional argument to disable calculation of
+	condition number for all but fsolve, for speed. Add code to 
+	allow rectnagular matrices or matrices identified as singular
+	to be treated.
+	(lssolve): delete.
+	(operator *): Don't recast real matrices as complex, but
+	rather use the macro directly on the real data.
+	* dSparse.cc: ditto.
+	* CSparse.h (dsolve, utsolve, ltsolve, trisolve, bsolve,
+	fsolve, factorize): Update declaration for new argument to
+	calculate the condition number.
+	(lssolve): delete.
+	* dSparse.h: ditto.
+	* Msparse.h: Change use of nxmax to nnz to allow automatic
+	reduction of matrix size, except for a couple of cases where
+	nzmax is needed.
+	* Sparse.cc: Change use of nxmax to nnz to allow automatic
+	reduction of matrix size, except for a couple of cases where
+	nzmax is needed.
+	(Sparse<T>::index (idx_vector&, idx_vector&, int) const):
+	Special case strict permutations for speed.
+	* Sparse-op-defs.h: Change use of nxmax to nnz to allow automatic
+	reduction of matrix size, except for a couple of cases where
+	nzmax is needed.
+	(SPARSE_SPARSE_MUL, SPARSE_FULL_MUL, FULL_SPARSE_MUL): Update
+	macros to allow mixed complex/real arguments.
+	* SparseCmplxQR.cc (OCTAVE_C99_ZERO): New macro for C99 zero
+        value.
+	(qrsolve): Use it to zero temporary buffers used bt CXSPARSE.
+	* SparseType.cc (SparseType::SparseType ()): Correct detection
+	of permutated triangular matrices to avoid seg-faults. Disable
+	detection of underdetermined lower and over-determined upper
+	matrix due to problems with non minimum norm solutions.
+	* sparse-dmsolve.cc: New file for Dulmage-Mendelsohn solver.
+	* Makefile.in: add sparse-dmsolve.cc to targets.
+
+2006-03-15  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* oct-time.cc (octave_strptime::init): Return useful character count.
+
+2006-03-08  David Bateman  <dbateman at free.fr>
+
+	* SparseCmplxQR.cc: Updates for new upstream CXSPARSE release. Fix for
+	g++ 4.x stl_vector.h issue with C99 double _Complex type.
+	* SparseCmplxQR.h:  Updates for new upstream CXSPARSE release.
+	* SparseQR.cc: ditto.
+	* SparseQR.h: ditto.
+	* oct-sparse.h: ditto.
+	* sparse-base-chol.cc (sparse_base_chol<>::sparse_base_chol_rep::init):
+	Declare info variable as volatile.
+
+	* Sparse.cc (Sparse<T>::transpose (void) const): Accelerate algorithm.
+	* CSparse.cc (SparseComplexMatrix::transpose (void) const): ditto.
+	
+2006-03-01  John W. Eaton  <jwe at octave.org>
+
+	* CMatrix.cc (ComplexMatrix::determinant):
+	Scale result by factors of 2, not 10.
+	* dMatrix.cc (Matrix::determinant): Likewise.
+
+	* dbleDET.h (DET::DET): Use initializer list.
+	(DET::coefficient2, DET::coefficient10, DET::exponent2,
+	DET::exponent10): New functions.
+	(DET::det): Delete.
+	(DET::c2, DET::c10, DET::e2, DET::e10, DET::base2): New data members.
+	Store value internally with double and int instead of 2-element
+	double vector.
+	(DET::initialize2, DET::initialize10): Provide decls.
+	* dbleDET.cc (DET::value_will_overflow,	DET::value_will_underflow): 
+	Return bool value, not int.
+	(DET::initialize2, DET::initialize10): New functions.
+
+	* CmplxDET.h (ComplexDET::ComplexDET): Use initializer list.
+	(ComplexDET::coefficient2, ComplexDET::coefficient10,
+	ComplexDET::exponent2, ComplexDET::exponent10): New functions.
+	(ComplexDET::det): Delete.
+	(ComplexDET::c2, ComplexDET::c10, ComplexDET::e2, ComplexDET::e10,
+	ComplexDET::base2): New data members.
+	Store value internally with Complex and int instead of 2-element
+	Complex vector.
+	(ComplexDET::initialize2, ComplexDET::initialize10): Provide decls.
+	* dbleComplexDET.cc (ComplexDET::value_will_overflow,
+	ComplexDET::value_will_underflow): Return bool value, not int.
+	(ComplexDET::initialize2, ComplexDET::initialize10): New functions.
+
+2006-02-24  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Clear index before reshaping.
+
+	* Array.h (Array<T>::operator =): Don't set idx to 0 if copying self.
+
+2006-02-20  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc (dsolve, utsolve, ltsolve): Remove restriction that 
+	matrix must be square in diagonal, permuted diagonal, triangular
+	and permuted triangular back/forward substitution code. Change
+	ambiguous use of no. rows and columns.
+	* CSParse.cc (dsolve, utsolve, ltsolve): ditto.
+	* SparseType.cc (SparseType::SparseType(const SparseMatrix&),
+	SparseType::SparseType(const SparseComplexMatrix&)): Recognize
+	rectangular diagonal, permuted diagonal, triangular and permuted
+	triangular matrices.
+	* Sparse.cc (Sparse<T>::Sparse (octave_idx_type, octave_idx_type, T)):
+	Treat case where third argument is zero.
+
+2006-02-15  John W. Eaton  <jwe at octave.org>
+
+	* kpse.cc: Do define ST_NLINK_TRICK for Cygwin systems.
+	(do_subdir) [ST_NLINK_TRICK]: Check links != 2 instead of links > 2. 
+
+	* getopt.c: Use __CYGWIN__ instead of __CYGWIN32__.
+
+2006-02-13  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (LINK_DEPS): Add missing dependencies on colamd,
+	ccolamd and cxsparse 
+
+2006-02-13  John W. Eaton  <jwe at octave.org>
+
+	* kpse.cc (kpse_path_iterator::next): Reverse order of tests in
+	while loop condition.
+	(kpse_path_iterator::operator =): Declare as private function but
+	don't define to prevent attempts to use assignment operator.
+	Don't define ST_NLINK_TRICK for Cygwin systems.
+
+2006-02-10  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Store in cummulative
+	product of all dimensions in CP_SZ.
+
+2006-02-09  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_CUMULATIVE_OP): Store in cummulative
+	product of all dimensions in CP_SZ.
+
+2006-02-09  David Bateman  <dbateman at free.fr>
+
+        * SparseQR.cc: new file for real sparse QR class.
+        * SparseQR.h: declaration.
+        * SparseCmplxQR.cc: new file for complex sparse QR class.
+        * SparseCmplxQR.h: declaration.
+        * dSparse.cc (dinverse,tinverse,inverse): Remove unused input args.
+        (factorize, fsolve): Enable code code lssolve.
+        (lssolve): disable unused args, write based in above sparse QR class.
+        * CSparse.cc (dinverse,tinverse,inverse): Remove unused input args.
+        (factorize, fsolve): Enable code code lssolve.
+        (lssolve): disable unused args, write based in above sparse QR class.
+        * oct-sparse.h: fix location of colamd, ccolamd and metis headers.
+        Include CXSparse headers.
+        * Makefile.in (MATRIX_INC): Include SparseQR.h and SparseCmplxQR.h.
+        (MATRIX_SRC): Include SparseQR.cc and SparseCmplxQR.cc.
+
+2006-02-08  John W. Eaton  <jwe at octave.org>
+
+	* Array-util.h (calc_permutated_idx): Delete.
+	* Array.cc (permute_vector): New data structure.
+	(permute_vector_compare): New function.
+	(Array<T>::permute): Rewrite to avoid calc_permutated_index for
+	improved performance.
+
+2006-02-04  David Bateman  <dbateman at free.fr>
+
+	* COLAMD: Remove all files, as now unused.
+
+2006-01-31  John W. Eaton  <jwe at octave.org>
+
+	* Sparse.h (Sparse<T>::nzmax): New function.
+	(Sparse<T>::nnz): Rename from nonzero.
+	Change all uses of old nnz function to be nzmax.  Change all uses
+	of nonzero to be nnz.
+	(Sparse<T>::nzmx): Rename from nnz (data member).  Change all uses.
+
+2006-01-21  David Bateman  <dbateman at free.fr>
+
+        * sparse-sort.cc (bool octave_sparse_sidxl_comp): 64-bit fix.
+        (bool octave_idx_vector_comp): New function.
+        (template class octave_sort<octave_idx_vector_sort *>): Instantiate
+        indexed idx_vector sorting function.
+        * sparse-sort.h (class octave_sparse_sort_idxl): 64-bit fix.
+        (class octave_idx_vector_sort): New class for indexed idx_vector
+        sorting.
+        (bool octave_idx_vector_comp): Declaration.
+        * Sparse.cc (int assign1(Sparse<LT>&, Sparse<RT>&)): Treat cases of
+        unordered LHS indexes in assignment using new octave_idx_vector_sort
+        class.
+        (int assign(Sparse<LT>&, Sparse<RT>&)): ditto.
+
+2006-01-30  John W. Eaton  <jwe at octave.org>
+
+	* so-array.h (streamoff_array::nnz): New funtion.
+	* boolNDArray.h (boolNDArray::nnz): New function.
+	* MArrayN.h (MArrayN<T>::nnz): New function.
+	* MArray.h (MArray<T>::nnz): New function.
+
+2006-01-04  David Bateman  <dbateman at free.fr>
+
+	* Spars-op-defs.h (SPARSE_SPARSE_MUL): Previous change resulted in
+	elements not being sorted in return matrix. Sort them, and make
+	solver select between two algorithms to further improve the 
+	performance.
+	* dSparse.cc: include oct-sort.h.
+	* CSparse.cc: ditto.
+	* sparse-sort.cc: Instantiate octave_sort<octave_idx_type>.
+	
+2005-12-28  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_SPARSE_MUL): Improved algorithm that is
+	faster in all cases, and significantly so for low density or small 
+	order problems.
+
+2005-11-30  John W. Eaton  <jwe at octave.org>
+
+	* LSODE.cc (LSODE::do_integrate (double)): Resize iwork and rwork
+	before setting any values in either array.
+
+2005-11-29  John W. Eaton  <jwe at octave.org>
+
+	* oct-uname.h, oct-uname.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2005-11-11  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::indexN): Simplify.
+
+2005-11-09  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int::operator char (void) const):
+	New conversion op.
+
+2005-11-01  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (distclean): Also remove oct-types.h.
+	From Quentin Spencer <qspencer at ieee.org>.
+
+2005-10-31  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc, CSparse.cc: Use C++ true/false instead of
+	preprocessor defined TRUE/FALSE.
+
+2005-10-30  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Iterate in direction of DIM.
+	(MX_ND_CUMULATIVE_OP): Likewise.
+
+2005-10-29  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Avoid increment_index to speed
+	things up.  Simplify.
+
+	* Array.cc (Array<T>::indexN): Simplify.  Delete separate special
+	case for "vector_equivalent".
+
+	* Array-util.cc (vector_equivalent): Arg is now dim_vector.
+
+2005-10-28  John W. Eaton  <jwe at octave.org>
+
+	* oct-sparse.h: Fix typo in HAVE_UFSPARSE_UMFPACK_H.
+	From Quentin Spencer <qspencer at ieee.org>.
+
+	* sparse-base-chol.cc: Use C++ true/false instead of
+	preprocessor defined TRUE/FALSE.  Use 0 instead of NULL.
+
+2005-10-27  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Reshape to final size instead of resizing.
+
+2005-10-26  John W. Eaton  <jwe at octave.org>
+
+	* oct-sparse.h: New file.
+	* oct-sparse.h.in: Delete.
+
+2005-10-26  David Bateman  <dbateman at free.fr>
+
+	* sparse-base-chol.h: Include cholmod specific code in HAVE_CHOLMOD
+	* sparse-base-chol.cc: ditto.
+
+2005-10-26  John W. Eaton  <jwe at octave.org>
+
+	Changes for GCC 4.1, tip from Arno J. Klaassen
+	<arno at heho.snv.jussieu.fr>:
+
+	* dSparse.h (real (const SparseComplexMatrix&)): 
+	Publish externally used friend function.
+	(imag (const SparseComplexMatrix&)): Likewise.
+
+	* dColVector.h (real (const ComplexColumnVector&)):
+	Publish externally used friend function.
+	(imag (const ComplexColumnVector&)): Likewise.
+
+	* dNDArray.h (real (const ComplexNDArray&)):
+	Publish externally used friend function.
+	(imag (const ComplexNDArray&)): Likewise.
+
+	* dMatrix.h (operator * (const ComplexMatrix&)): 
+	Move decl outside class.  No need to be friend.
+	(real (const ComplexMatrix&)): Publish externally used friend function.
+	(imag (const ComplexMatrix&)): Likewise.
+
+	* CMatrix.h: (operator * (const ColumnVector&, const
+	ComplexRowVector&)): Move decl outside class.  No need to be friend.
+	(operator * (const ComplexColumnVector&, const RowVector&)): Likewise.
+	(operator * (const ComplexColumnVector&, const ComplexRowVector& b)):
+	Likewise.
+
+2005-10-23  David Bateman  <dbateman at free.fr>
+	
+	* Sparse-op-defs.h (SPARSE_SPARSE_MUL): Check whether trailing zero
+	elements need to be removed.
+	
+	* oct-sparse.h.in: Include metis headers and some macros for long/int
+	versions of cholmod.
+	
+	* CSparse.cc (tinverse): New private function for the inversion of
+	an upper triangular matrix.
+	(dinverse): ditto for diagonal matrices.
+	(inverse): Add SparseType as an argument. Implement matrix inverse
+	using tinverse and dinverse.
+	(fsolve): Use cholmod to implement Cholesky solver.
+	* CSparse.h (tinverse, dinverse): Declarations
+	(inverse): Alter declaration to include SparseType.
+
+	* dSparse.cc (tinverse, dinverse, inverse, fsolve): ditto.
+	* dSparse.h (tinverse, dinverse, inverse): ditto.
+
+	* SparseType.cc: Fix complex constructor for hermitian matrices.
+	
+	* sparse-util.cc: New file for sparse utility functions.
+	* sparse-util.h: New file with declarations of sparse utility 
+	functions.
+
+	* sparse-base-chol.cc: New file with sparse cholesky class based
+	on cholmod.
+	* sparse-base-chol.h: New file with declaration of sparse cholesky
+	class based on cholmod.
+
+	* SparseCmplxCHOL.cc: Instantiate sparse cholesky class for Complex.
+	* SparseCmplxCHOL.h: Declaration of sparse cholesky class.
+
+	* SparsedbleCHOL.cc: ditto.
+	* SparsedbleCHOL.h: ditto.
+
+	* Makefile.in (MATRIX_INC): Include sparse-base-chol.h.
+	(INCLUDES): Include sparse-util.h
+	(TEMPLATE_SRC): Include sparse-base-chol.cc
+	(MATRIX_SRC): Include SparseCmplxCHOL.cc and SparsedbleCHOL.cc
+	
+2005-10-12  John W. Eaton  <jwe at octave.org>
+
+	* oct-env.cc (octave_env::have_x11_display): New function.
+	* oct-env.h: Provide decl.
+
+2005-09-29  John W. Eaton  <jwe at octave.org>
+
+	* file-stat.h (file_stat::mode): New function.
+
+	* file-stat.cc (file_stat::is_blk, file_stat::is_chr,
+	file_stat::is_dir, file_stat::is_fifo, file_stat::is_lnk,
+	file_stat::is_reg, file_stat::is_sock): New static functions.
+	* file-stat.h: Provide decls.
+
+2005-09-28  John W. Eaton  <jwe at octave.org>
+
+	* file-ops.cc (file_ops::recursive_rmdir): New function.
+	* file-ops.h: Provide decl.
+
+2005-09-19  David Bateman  <dbateman at free.fr>
+
+	* oct-env.cc (octave_env::do_get_home_directory):
+	Also check HOMEDRIVE under mingw.
+
+	* Makefile.in (LINK_DEPS): Include UFsparse libraries.
+
+2005-09-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-syscalls.cc: Include lo-utils.h here.
+	(octave_syscalls::waitpid): Call octave_waitpid here.
+
+	* lo-cutils.c (octave_waitpid): New function.
+	* lo-utils.h: Provide decl.  Include syswait.h here, not in
+	oct-syscalls.cc
+	
+
+	* syswait.h [__MINGW32__]: Define WAITPID here instead of defining
+	waitpid in src/sysdep.h.  Make this header C-compatible.
+
+	* oct-syscalls.cc (octave_syscalls::waitpid): New arg, status.
+	Change all uses.
+
+2005-09-15  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (MAKEDEPS_2): Omit unnecessary variable.
+
+	* oct-sparse.h.in: New file.
+	* Makefile.in (DISTFILES): Include it in the list.
+	(INCLUDES): Add oct-sparse.h to the list.
+
+2005-09-15  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc : Include oct-sparse.h for probed umfpack, colamd etc 
+	headers. Remove include of umfpack.h.
+	* CSparse.cc : ditto.
+	* SparsedbleLU.cc : ditto.
+	* SparseCmplxLU.cc : ditto.
+
+	* COLAMD : Remove colamd files from octave.
+	* COLAMD.files : delete.
+	* COLAMD.README : delete.
+	* Makefile.in: Remove COLAMD. Add LIBGLOB.
+	(LN_S): Change to DESTDIR before LN_S to avoid lack of symlinks 
+	under mingw.
+
+	* kpse.cc (ENV_SEP, ENV_SEP_STRING): Use SEPCHAR and SEPCHAR_STR
+	in definition.
+	* lo-cutils.c (octave_w32_library_search): Call GetProcAddress with
+	change of cast not allowed under g++ 3.x.
+	* lo-utils.h (octave_w32_library_search): Declaration.
+	* oct-env.cc (do_get_home_directory): Also check HOMEPATH under mingw.
+	* oct-shlib.cc (octave_w32_shlib::search): Use octave_w32_library_search.
+
+2005-09-07  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.cc (command_editor::do_decode_prompt_string):  Update
+	based on current code in Bash.  Handle a few more escape
+	sequences.  Do a better job of decoding \W.
+
+2005-09-04  David Bateman  <dbateman at free.fr>
+
+	* COLAMD: Update version of colamd to v2.4.
+	* COLAMD.files: Add colamd_global.c to COLAMD_SRC and second build of 
+	colamd.c for long version.
+
+2005-08-25  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (FULL_SPARSE_MUL, SPARSE_FULL_MUL): Macro for
+	mixed sparse/full multiply.
+	* dSparse.cc (operator *), CSparse.cc (operator *): New operators for
+	mixed sparse/full multiply.
+	* dSparse.h (operator *), CSparse.h (operator *): Declaration of
+	mixed sparse/full multiply operators.
+
+2005-07-25   Erik de Castro Lopo  <erikd at zip.com.au>
+
+	* oct-inttypes.h (OCTAVE_S_US_FTR): Compare <= 0 instead of < 0 to
+	avoid warnings for unsigned types.
+
+2005-07-07  John W. Eaton  <jwe at octave.org>
+
+	* dSparse.cc (SparseMatrix::factorize): Initialize Numeric to 0.
+	* CSparse.cc (SparseComplexMatrix::factorize:) Likewise.
+
+2005-06-15  John W. Eaton  <jwe at octave.org>
+
+	* oct-rl-edit.c (flush_stdout): Rename from no_redisplay.
+	Flush stdout here.
+	(octave_rl_clear_screen): Set rl_redisplay_function to flush_stdout.
+
+	* Array.h (Array::resize): Change int args to octave_idx_type.
+
+2005-06-14  John W. Eaton  <jwe at octave.org>
+
+	* CMatrix.cc, CNDArray.cc, CSparse.cc, dMatrix.cc, dNDArray.cc,
+	dSparse.cc, lo-cieee.c, lo-mappers.cc: Change all uses of
+	octave_is_NaN_or_NA to xisnan.
+
+	* lo-mappers.h (octave_is_NaN_or_NA): Mark with GCC_ATTR_DEPRECATED.
+	* lo-ieee.h (lo_ieee_is_NaN_or_NA): Likewise.
+
+	* lo-cieee.c (lo_ieee_is_NaN_or_NA): Now just a wrapper for
+	lo_ieee_isnan.
+
+	* dMatrix.cc (Matrix::too_large_for_float): Only check if abs
+	value is greater than FLT_MAX.
+	* CMatrix.cc (ComplexMatrix::too_large_for_float): Ditto.
+	* dNDArray.cc (NDArray::too_large_for_float): Ditto.
+	* CNDArray.cc (ComplexNDArray::too_large_for_float): Ditto.
+
+	* dMatrix.cc (Matrix::too_large_for_float): Special case Inf
+	values too.
+	* CMatrix.cc (ComplexMatrix::too_large_for_float): Ditto.
+
+	* dNDArray.cc (NDArray::too_large_for_float): Likewise for NaN,
+	NA, Inf values.
+	* CNDArray.cc (ComplexNDArray::too_large_for_float): Ditto.
+
+2005-06-14  David Bateman  <dbateman at free.fr>
+
+	* dMatrix.cc (Matrix::too_large_for_float): Special case NaN and
+	NA values.
+	* CMatrix.cc (ComplexMatrix::too_large_for_float): Ditto.
+
+2005-06-02  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Try harder to correctly resize previously
+	empty LHS.
+
+2005-05-16  David Bateman  <dbateman at free.fr>
+
+	* dSparse.h: Change UMFPACK_LONG_IDX to IDX_TYPE_LONG.
+	* CSparse.h: ditto.
+
+2005-05-10  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc (determinant): Free numeric factorization after
+	sucessful calculation.
+	* CSparse.cc (determinant): ditto.
+
+2005-05-06  John W. Eaton  <jwe at octave.org>
+
+	* dbleCHOL.cc (CHOL::init): Use xelem instead of elem for indexing
+	chol_mat.
+	(chol2mat_internal, chol2mat, CHOL::inverse): New functions.
+	* dbleCHOL.h (chol2mat_internal, chol2mat, CHOL::inverse):
+	Provide decls.
+
+	* CmplxChol.cc (ComplexCHOL::init): Use xelem instead of elem for
+	indexing chol_mat.
+	(chol2mat_internal, chol2mat, ComplexCHOL::inverse): New functions.
+	* CmplxCHOL.h (chol2mat_internal, chol2mat, CmplxCHOL::inverse):
+	Provide decls.
+
+2005-05-05  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::permute): Call chop_trailing_singletons on
+	retval before return.
+
+2005-05-04  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.cc (gnu_readline::do_readline): Extract const char*
+	from prompt outside of INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE block.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (LINK_DEPS): List $(UMFPACK_LIBS) ahead of $(BLAS_LIBS).
+	From Dmitri A. Sergatskov <dasergatskov at gmail.com>.
+
+2005-04-29  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc (trisolve): Diagonal passed to lapack zptsv is type
+	double.  Correct indexing for upper diagonal elements for sparse
+	tridiagonal.
+	* CSparse.cc (trisolve): ditto.
+
+	* CSparse.h (UMFPACK_ZNAME): Define macro to pick version of
+	UMFPACK for 64-bit.
+	* CSparse.cc (UMFPACK_ZNAME): Replace all umfpack_zi_* with 
+	UMFPACK_ZNAME(*).
+	* SparseCmplxLU.cc (UMFPACK_ZNAME): ditto
+
+	* dSparse.h (UMFPACK_DNAME): Define macro to pick version of
+	UMFPACK for 64-bit.
+	* dSparse.cc (UMFPACK_DNAME): Replace all umfpack_di_* with 
+	UMFPACK_DNAME(*).
+	* SparsedbleLU.cc (UMFPACK_DNAME): ditto
+
+	* dSparse.cc (ltsolve, utsolve): Correct permuted upper/lower
+	triangular back/forward substitution code.
+	* CSparse.cc (ltsolve, utsolve): ditto.
+
+	* dSparse.cc (solve): Use mattype.type (false) to force messaging
+	from spparms("spumoni",1).
+	* CSparse.cc (solve): ditto
+
+	* SparseType.cc (SparseType(void)): Print info for
+	spparms("spumoni",1).
+	(SparseType(const matrix_type), SparseType(const matrix_type, const
+	octave_idx_type, const octave_idx_type*), SparseType(const matrix_type,
+	const octave_idx_type, const octave_idx_type)): New constructors.
+	(SparseType (const SparseMatrix&), SparseType (SparseComplexMatrix&)):
+	Detect row permuted lower triangular and column permuted upper
+	triangular matrices. Remove one of the permutation vectors..
+
+	* SparseType.h: Simplify the permutation code.
+	(SparseType(const matrix_type), SparseType
+	(const matrix_type, const octave_idx_type, const octave_idx_type*), 
+	SparseType(const matrix_type, const octave_idx_type, 
+	const octave_idx_type)): Declarations.
+	
+2005-04-25  John W. Eaton  <jwe at octave.org>
+
+	* str-vec.cc (string_vector::delete_c_str_vec): Correctly free
+	array and its contents.
+
+2005-04-22  John W. Eaton  <jwe at octave.org>
+
+	* oct-rl-edit.c (octave_rl_set_terminal_name): Don't cast away
+	const here now that rl_terminal_name is declared const char*.
+
+2005-04-21  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DISTFILES): Include oct-types.h.in in the list.
+
+2005-04-19  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Don't crash if the index list is empty.
+
+2005-04-14  David Bateman  <dbateman at free.fr>
+
+	* SparseCmplxLU.cc: Add flags for incomplete factorization.
+	* SparsedbleLU.cc: Ditto.
+	* SparseCmplxLU.h: Definition.
+	* SparsedbleLU.h: ditto.
+
+	* SparseType.cc (transpose): New function.
+	* SparseType.h (transpose): Definition.
+	
+2005-04-11  John W. Eaton  <jwe at octave.org>
+
+	* lo-specfun.cc: Use F77_XFCN instead of F77_FUNC for calls to
+	fortran code that could end up calling XSTOPX.
+
+2005-04-10  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: include oct-types in INCLUDES so that it is 
+	installed
+	
+2005-04-08  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (clean): Use exact filenames instead of *.xxx.
+
+	* Initial merge of 64-bit changes from Clinton Chee:
+
+	2005-04-07  John W. Eaton  <jwe at octave.org>
+
+	* MArray-i.cc, Array-i.cc: Instantiate Array<long> and MArray<long>.
+
+	* CSparse.cc, CSparse.h, MSparse.cc, MSparse.h, Sparse-op-defs.h,
+	Sparse.cc, Sparse.h, SparseCmplxLU.cc, SparseType.cc,
+	SparseType.h, SparsedbleLU.cc, boolSparse.cc, boolSparse.h,
+	dSparse.cc, dSparse.h, sparse-base-lu.cc:
+	Use octave_idx_type instead of int where needed.
+
+	2005-03-31  Clinton Chee  <chee at parallel.hpc.unsw.edu.au>
+
+	* Array-util.cc, Array-util.h, Array.cc,Array.h, Array2.h,
+	Array3.h, ArrayN.cc, ArrayN.h, Bounds.cc, Bounds.h, CColVector.cc,
+	CColVector.h, CDiagMatrix.cc, CDiagMatrix.h, CMatrix.cc,
+	CMatrix.h, CNDArray.cc, CNDArray.h, CRowVector.cc, CRowVector.h,
+	CmplxAEPBAL.cc, CmplxAEPBAL.h, CmplxCHOL.cc, CmplxCHOL.h,
+	CmplxHESS.cc, CmplxHESS.h, CmplxLU.cc, CmplxQR.cc, CmplxQRP.cc,
+	CmplxSCHUR.cc, CmplxSCHUR.h, CmplxSVD.cc, CmplxSVD.h, CollocWt.cc,
+	CollocWt.h, DAEFunc.h, DASPK-opts.in,DASPK.cc,DASPK.h,
+	DASRT-opts.in, DASRT.cc, DASRT.h, DASSL-opts.in, DASSL.cc,
+	DASSL.h, DiagArray2.cc, DiagArray2.h, EIG.cc, EIG.h, FEGrid.cc,
+	FEGrid.h, LPsolve.cc, LPsolve.h, LSODE-opts.in, LSODE.cc, LSODE.h,
+	MArray-defs.h, MArray.cc, MArray.h, MArray2.cc, MArray2.h,
+	MArrayN.cc, MDiagArray2.cc, MDiagArray2.h, NLConst.h, NLEqn.cc,
+	NLEqn.h, Quad.cc, Quad.h, Range.cc,Range.cc, Range.h, base-de.h,
+	base-lu.cc, base-lu.h, base-min.h, boolMatrix.cc, boolMatrix.h,
+	boolNDArray.cc, boolNDArray.h, chMatrix.cc, chMatrix.h,
+	chNDArray.cc, chNDArray.h, dColVector.cc, dColVector.h,
+	dDiagMatrix.cc, dDiagMatrix.h, dMatrix.cc, dMatrix.h,
+	dNDArray.cc,dNDArray.cc, dNDArray.h, dRowVector.cc, dRowVector.h,
+	dbleAEPBAL.cc, dbleAEPBAL.h, dbleCHOL.cc, dbleCHOL.h, dbleHESS.cc,
+	dbleHESS.h, dbleLU.cc, dbleQR.cc, dbleQRP.cc, dbleSCHUR.cc,
+	dbleSCHUR.h, dbleSVD.cc, dbleSVD.h, dim-vector.h, idx-vector.cc,
+	idx-vector.h, intNDArray.cc, intNDArray.h, lo-specfun.cc,
+	lo-specfun.h, mach-info.cc, mx-inlines.cc, oct-fftw.cc,
+	oct-fftw.h, oct-rand.cc, oct-rand.h, so-array.cc, so-array.h,
+	str-vec.cc, str-vec.h:
+	Use octave_idx_type instead of int where needed.
+
+	2005-04-01  John W. Eaton  <jwe at octave.org>
+
+	* dim-vector.h, lo-utils.h: Include oct-types.h.
+
+	* oct-types.h.in: New file.
+
+	2005-03-31  Clinton Chee  <chee at parallel.hpc.unsw.edu.au>
+
+	* lo-utils.cc (NINTbig): New function.
+	* lo-utils.h: Provide decl.
+
+2005-04-06  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: Link to UMFPACK_LIBS.
+
+2005-04-05  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Avoid shadowed declaration in previous change.
+
+2005-04-01  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): For A(IDX-LIST) = RHS with A previously
+	undefined, correctly match colons in IDX-LIST with RHS dimensions
+	when resizing A.  When performing the assignment, just check that
+	the number of elements in RHS matches the number of elements
+	indexed by IDX-LIST.
+
+2005-03-30  John W. Eaton  <jwe at octave.org>
+
+	* lo-mappers.cc (log10, tan, tanh): Delete functions.
+	* lo-mappers.h (log10, tan, tanh): Delete decls.
+
+	* CColVector.cc, CNDArray.cc, CRowVector.cc, CSparse.cc,
+	dSparse.cc: Use std:: for Complex functions instead of relying on
+	wrappers from oct-cmplx.h.
+
+	* oct-cmplx.h: Provide typedef only.
+
+	* DiagArray2.cc (xelem): Don't use initializer for static data.
+	* DiagArray2.h (DiagArray<T>::Proxy::operator T ()):
+	Likewise.
+
+2005-03-26  John W. Eaton  <jwe at octave.org>
+
+	* cmd-edit.cc (do_readline): Wrap call to ::octave_rl_readline
+	with {BEGIN,END}_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE.
+
+2005-03-15  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (MATRIX_INC): Remove oct-spparms.h from the list.
+
+2005-03-14  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DISTFILES): Don't include $(UMFPACK_EXTRAS).
+	(DISTDIRS): Don't include UMFPACK.
+	(LIBOCTAVE_OBJECTS): Don't include $(UMFPACK_OBJ).
+	(UMFPACK_SPECIAL_1, UMFPACK_SPECIAL): No need for special include
+	flags for these files.
+	Don't include include $(srcdir)/UMFPACK.files.
+	Don't include include $(srcdir)/UMFPACK.rules.
+
+	* UMFPACK.README, UMFPACK.files, UMFPACK.patch, UMFPACK.rules:
+	Delete files.
+	* UMFPACK: Delete directory tree.
+
+	* dSparse.cc: Include <umfpack/umfpack.h> instead of just "umfpack.h".
+	* CSparse.cc: Likewise.
+	* SparsedbleLU.cc: Likewise.
+	* SparseCmplxLU.cc: Likewise.
+
+2005-03-14  David Bateman  <dbateman at free.org>
+
+	* CSParse.cc, SparseCmplxLU.cc, SparsedbleLU.cc, dSparse.cc:
+	Allow compilation to succeed if UMFPACK is not available.
+
+2005-03-09  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (bin-dist): Delete target.
+	(BINDISTLIBS, BINDISTFILES): Delete variables.
+
+2005-03-01  John W. Eaton  <jwe at octave.org>
+
+	* ODESSA.h, ODESSA.cc, ODESSA-opts.in: Delete.
+	* Makefile.in: Remove them from the lists.
+
+2005-02-28  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (LINK_DEPS): Remove -lglob from the list.
+
+2005-02-27  David Bateman  <dbateman at free.org>
+
+	* Sparse.cc (Sparse<T>::reshape): Set cidx for the N last elements
+	in the sparse matrix.
+	
+2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	Sparse merge.
+
+	2005-02-13  David Bateman  <dbateman at free.fr>
+
+	* CSparse.cc (SparseComplexMatrix:dsolve, SparseComplexMatrix:utsolve,
+	SparseComplexMatrix::ltsolve, SparseComplexMatrix::trisolve,
+	SparseComplexMatrix::bsolve, SparseComplexMatrix:fsolve): Split sparse
+	solver into separate functions for the diagonal, upper, lower 
+	triangular, tridiagonal, banded and full cases.
+	(SparseComplexMatrix::solve): rewrite to call the above function. One
+	version that probes the matrix type and another that assumes the type
+	is passed.
+
+	* dSparse.cc (SparseMatrix:dsolve, SparseMatrix:utsolve,
+	SparseMatrix::ltsolve, SparseMatrix::trisolve,
+	SparseMatrix::bsolve, SparseMatrix:fsolve): Likewise
+	(SparseMatrix::solve): Likewise
+
+	* CSparse.h (dsolve, utsolve, ltsolve, trisolve, bsolve, fsolve):
+	Declaration of new functions
+	* dSparse.h (dsolve, utsolve, ltsolve, trisolve, bsolve, fsolve):
+	Likewise
+
+	* CSparse.cc (operator !): Reverse the sense of the test.
+	* dSpase.cc (operator !): Likewise
+
+	* dSparse.h (type, band_size, is_dense, triangular_row_perm,
+	triangular_col_perm, sparse_info): Remove matrix type code
+	* CSparse.h (type, band_size, is_dense, triangular_row_perm,
+	triangular_col_perm, sparse_info): Likewise
+	* boolSparse.h (type, band_size, is_dense, triangular_row_perm,
+	triangular_col_perm, sparse_info): Likewise
+	* MSparse.h (type, band_size, is_dense, triangular_row_perm,
+	triangular_col_perm, sparse_info): Likewise
+	* Sparse.h (type, band_size, is_dense, triangular_row_perm,
+	triangular_col_perm, sparse_info, matrix_type): Likewise
+
+	* Sparse.cc (type, sparse_info, band_size): Remove type code
+	
+	* SparseType.h: New class for the matrix type used in solvers
+	* SparseType.cc: methods of sparse matrix type class
+	
+	* Makefile.in: Add SparseType.cc
+
+	2005-02-01  David Bateman  <dbateman at free.fr>
+
+	* UMFPACK: Update to version 4.4
+	* UMFPACK.patch: Version 4.4 contains most of the previous patch. Only
+	keep octave specific test files
+
+	2005-01-23  David Bateman  <dbateman at free.fr>
+
+	* dSparse.cc (SparseMatrix::solve): Include tridiagonal, cholesky
+	tridiagonal and banded cholesky solvers. Remove calculation of
+	condition number for banded solvers.
+	* CSparse.cc (SparseComplexMatrix::solve): ditto.
+
+	* Sparse.h (int type (int) const, bool is_dense (void) const):
+	new functions.
+	* MSparse.h (int type (int) const, bool is_dense (void) const): ditto
+	* dSparse.h (int type (int) const, bool is_dense (void) const): ditto
+	* CSparse.h (int type (int) const, bool is_dense (void) const): ditto
+	* boolSparse.h (int type (int) const, bool is_dense (void) const): 
+	ditto
+
+	* Sparse.cc (int Sparse<T>::type (int) const, 
+	bool Sparse<T>::is_dense (void) const): New functions definition
+	
+	* Sparse.h (matrix_type typ): Move caching of matrix type to SparseRep,
+	so it actually is cached, but disable
+
+	* oct-spparms.cc (SparseParams::init_keys): Change spmoni to spumoni
+	for compatiability
+	
+	2005-01-18  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (Array<T>::insert (const Array<T>&, const Array<int>&)):
+	Modify calculation of number elements to skip between copied blocks.
+
+	2005-01-07  David Bateman  <dbateman at free.fr>
+
+	* Sparse.h : Reverse definitions of numel and nelem.
+	* Sparse.cc (assign1): Use numel and not nelem
+	* Sparse-op-def.h: Replace all uses of nelem with numel
+	
+	2005-01-07  David Bateman  <dbateman at free.fr>
+
+	* dbleDET.h: Make SparseMatrix a friend of the class DET
+	* CmplexDET.h: Make SparseComplexMatrix a friend of the class 
+	ComplexDET
+	* dSparse.cc (SparseMatrix::determinant): Replace use of SparseDET 
+	by DET
+	* dSparse.h (determinant): ditto
+	* CSparse.cc (SparseComplexMatrix::determinant): Replace use of 
+	SparseComplexDET by ComplexDET
+	* CSparse.h (determinant): ditto
+	* SparsedbleDET.h, SparsedbleDET.cc, SparseCmplxDET.h, 
+	SparseCmplxDET.cc: delete files
+	* Makefile.in: Delete reference to SparsedbleDET.h, SparsedbleDET.cc,
+	SparseCmplxDET.h andSparseCmplxDET.cc.
+
+	* CSparse.cc (SparseComplexMatrix::solve): Store matrix type in 
+	local variable to avoid variable shadowing.
+	* dSparse.cc (SparseMatrix::solve): ditto.
+	
+        * boolSparse.cc boolSparse.h CSparse.cc CSparse.h dSparse.cc 
+	dSparse.h MSparse.cc MSparse-C.cc MSparse-d.cc MSparse-defs.h
+   	MSparse.h oct-spparms.cc oct-spparms.h Sparse-b.cc Sparse.cc 
+	Sparse-C.cc SparseCmplxLU.cc SparseCmplxLU.h SparsedbleLU.cc 
+	SparsedbleLU.h Sparse-d.cc Sparse.h Sparse-op-defs.h sparse-sort.cc 
+	sparse-sort.h: Remove additional licensing clause with authors
+	permission.
+	
+	2004-12-30  John W. Eaton  <jwe at octave.org>
+
+	* MSparse.cc (SPARSE_A2S_OP_2, SPARSE_SA2_OP_2):
+	Loop counter is int, not size_t.
+
+	* oct-spparms.cc (SparseParams::operator =): Return *this.
+
+	* Sparse-op-defs.h (SPARSE_SPARSE_MUL): Delete unused variable tmpval.
+
+	* dSparse.cc (operator << (ostream&, const SparseMatrix&), atan2):
+	Delete unused variables.
+	(SparseMatrix::solve): Avoid warnings about uninitialized
+	variables and variables that might be clobbered by longjmp.
+
+	* CSparse.cc (operator << (ostream&, const SparseComplexMatrix&),
+	min, max): Delete unused variables.
+	(SparseComplexMatrix::solve): Avoid warnings about uninitialized
+	variables and variables that might be clobbered by longjmp.
+
+	* Makefile.in (UMFPACK_SPECIAL): Include .d files in the list.
+
+	* Sparse-op-defs.h (SPARSE_SMS_BIN_OP_2, SPARSE_SSM_BIN_OP_2):
+	Loop counter is int, not size_t.
+
+	* CSparse.cc (SparseComplexMatrix::hermitian): Avoid shadow warnings.
+	* Sparse.cc (Sparse<T>::Sparse, Sparse<T>::type, assign): Likewise.
+	
+	* Sparse.h (Sparse::SparseRep): Order data members and initializer
+	lists consistently.
+
+	* mx-base.h: Include boolSparse.h, dSparse.h, and CSparse.h.
+
+	2004-12-29  John W. Eaton  <jwe at octave.org>
+
+	* COLAMD.files (COLAMD_EXTRAS): New variable.
+	* UMFPACK.files (UMFPACK_EXTRAS): New variable.
+	* Makefile.in (DISTFILES): Add $(COLAMD_EXTRAS) and
+	$(UMFPACK_EXTRAS) to the list.
+	(DISTDIRS): New variable.
+	(dist): Handle $(DISTDIRS).
+
+	Merge of sparse code from David Bateman <dbateman at free.fr> and 
+	Andy Adler <adler at site.uottawa.ca>.
+
+	* Makefile.in (VPATH): ADD @srcdir@/COLAMD to the list.
+
+	* Makefile.in (MAKEDEPS): Include $(COLAMD_SRC) and $(UMFPACK_SRC)
+	without directory prefix.
+
+	* Makefile.in (LIBOCTAVE_OBJECTS): Add $(COLAMD_OBJ) and
+	$(UMFPACK_OBJ) to the list.
+
+	* COLAMD: New directory.
+	* COLAMD.files: New file.
+	* Makefile.in: Include COLAMD.files.
+	(SOURCES): Add $(COLAMD_SOURCES) to the list.
+	(LIBOCTAVE_OBJECTS): Add $(COLAMD_OBJECTS) to the list.
+	(INCLUDES): Add $(COLAMD_INCLUDES) to the list.
+
+	* UMFPACK: New directory.
+	* UMFPACK.patch, UMFPACK.README, UMFPACK.files, UMFPACK.rules:
+	New files.
+	* Makefile.in: Include UMFPACK.files and UMFPACK.rules.
+	(SOURCES): Add $(UMFPACK_SOURCES) to the list.
+	(LIBOCTAVE_OBJECTS): Add $(UMFPACK_OBJECTS) to the list.
+	(INCLUDES): Add $(UMFPACK_INCLUDES) to the list.
+
+	* Makefile.in (SPARSE_MX_OP_INC): New variable.
+	(INCLUDES): Add it to the list.
+	(SPARSE_MX_OP_SRC): New variable.
+	(LIBOCTAVE_CXX_SOURCES): Add it to the list.
+	(distclean): Remove $(SPARSE_MX_OP_INC) and $(SPARSE_MX_OP_SRC).
+	(stamp-prereq): Depend on $(SPARSE_MX_OP_INC) and $(SPARSE_MX_OP_SRC).
+
+	* sparse-mk-ops.awk, sparse-mx-ops: New files.
+	* Makefile.in (DISTFILES): Add them to the lists.
+
+	* oct-spparms.h, sparse-sort.h: New files.
+	* Makefile.in (INCLUDES): Add them to the list.
+
+	* oct-spparms.cc, sparse-sort.cc: New files.
+	* Makefile.in (LIBOCTAVE_CXX_SOURCES): Add them to the list.
+
+	* sparse-base-lu.cc: New file.
+	* Makefile.in (TEMPLATE_SRC): Add it to the list.
+
+	* boolSparse.cc, CSparse.cc, dSparse.cc, MSparse.cc, Sparse.cc,
+	SparseCmplxDET.cc, SparseCmplxLU.cc, SparsedbleDET.cc,
+	SparsedbleLU.cc: New files.
+	* Makefile.in (MATRIX_SRC): Add them to the list.
+	
+	* boolSparse.h, CSparse.h, dSparse.h, MSparse-defs.h, MSparse.h,
+	Sparse.h, oct-spparms.h, sparse-base-lu.h, SparseCmplxDET.h,
+	SparseCmplxLU.h, SparsedbleDET.h, SparsedbleLU.h,
+	Sparse-op-defs.h: New files.
+	* Makefile.in (MATRIX_INC): Add them to the appropriate lists.
+
+	* MSparse-d.cc, MSparse-C.cc, Sparse-b.cc, Sparse-d.cc,
+	Sparse-C.cc: New files.
+	* Makefile.in (TI_SRC): Add them to the list.
+
+2005-02-18  John W. Eaton  <jwe at octave.org>
+
+	* file-ops.cc (file_ops::canonicalize_file_name) [HAVE_RESOLVEPATH]:
+	Pass current directory to octave_env::make_absolute.
+	Save value returned from octave_env::make_absolute in local var.
+	Pass const char*, not std::string as first arg of resolvepath.
+	Provide decl for resolved_len.
+
+2005-02-18  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::permute): Allow permutation vector longer
+	than number of dimenensions of permuted matrix.
+
+	* Array.cc (Array<T>::permute): Use zero-based indexing for perm_vec.
+	* Array-util.cc (calc_permutated_idx): Likewise.
+
+2005-02-10  David Bateman  <dbateman at free.fr>
+
+	* CNDArray.cc (ComplexNDarray::operator !): Change sense of test.
+	* CMatrix.cc (ComplexMatrix::operator !): Likewise.
+
+2005-02-09  John W. Eaton  <jwe at octave.org>
+
+	* file-ops.cc (file_ops::canonicalize_file_name): New functions.
+	* file-ops.h: Provide decls.
+
+	* kpse.cc (kpse_tilde_expand): Simply return NAME if it is empty.
+
+2005-02-08  John W. Eaton  <jwe at octave.org>
+
+	* Array-util.cc (freeze): Improve error message.
+
+2005-01-26  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (Array<T>::insert): Handle generic case, not just
+	special case for fast concatenation.
+
+2005-01-18  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Delete RET_ELT_TYPE arg.
+	Change all uses.  Use VAL instead of RET_ELT_TYPE when resizing.
+
+	* dNDArray.cc (NDArray::any): NaN does not count as a nonzero value.
+	* CNDArray.cc (ComplexNDArray::any): Likewise.
+
+2005-01-18  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (Array<T>::insert (const Array<T>&, const Array<int>&)):
+	Modify calculation of number elements to skip between copied blocks.
+
+2005-01-18  John W. Eaton  <jwe at octave.org>
+
+	* idx-vector.cc (IDX_VEC_REP::freeze): Call warning handler, not
+	error handler, to warn about resizing.
+
+2004-12-27  Martin Dalecki  <martin at dalecki.de>
+
+	* Array.cc, ArrayN.cc, base-lu.cc, boolMatrix.cc, boolNDArray.cc,
+	Bounds.cc, CColVector.cc, CDiagMatrix.cc, chMatrix.cc,
+	chNDArray.cc, CMatrix.cc, CmplxAEPBAL.cc, CmplxCHOL.cc,
+	CmplxDET.cc, CmplxHESS.cc, CmplxLU.cc, CmplxQR.cc, CmplxQRP.cc,
+	CmplxSCHUR.cc, CmplxSVD.cc, CNDArray.cc, CollocWt.cc,
+	CRowVector.cc, DASPK.cc, DASRT.cc, DASSL.cc, dbleAEPBAL.cc,
+	dbleCHOL.cc, dbleDET.cc, dbleHESS.cc, dbleLU.cc, dbleQR.cc,
+	dbleQRP.cc, dbleSCHUR.cc, dbleSVD.cc, dColVector.cc,
+	dDiagMatrix.cc, DiagArray2.cc, dMatrix.cc, dNDArray.cc,
+	dRowVector.cc, EIG.cc, FEGrid.cc, idx-vector.cc, int16NDArray.cc,
+	int32NDArray.cc, int64NDArray.cc, int8NDArray.cc, intNDArray.cc,
+	LinConst.cc, LPsolve.cc, LSODE.cc, MArray2.cc, MArray.cc,
+	MArrayN.cc, MDiagArray2.cc, NLEqn.cc, oct-alloc.cc, ODES.cc,
+	ODESSA.cc, Quad.cc, Range.cc, so-array.cc, uint16NDArray.cc,
+	uint32NDArray.cc, uint64NDArray.cc, uint8NDArray.cc:
+	Delete #pragma implementation.
+
+	* Array2.h, Array3.h, Array.h, ArrayN.h, base-lu.h, boolMatrix.h,
+	boolNDArray.h, Bounds.h, CColVector.h, CDiagMatrix.h, chMatrix.h,
+	chNDArray.h, CMatrix.h, CmplxAEPBAL.h, CmplxCHOL.h, CmplxDET.h,
+	CmplxHESS.h, CmplxLU.h, CmplxQR.h, CmplxQRP.h, CmplxSCHUR.h,
+	CmplxSVD.h, CNDArray.h, CollocWt.h, CRowVector.h, DASPK.h,
+	DASRT.h, DASSL.h, dbleAEPBAL.h, dbleCHOL.h, dbleDET.h, dbleHESS.h,
+	dbleLU.h, dbleQR.h, dbleQRP.h, dbleSCHUR.h, dbleSVD.h,
+	dColVector.h, dDiagMatrix.h, DiagArray2.h, dim-vector.h,
+	dMatrix.h, dNDArray.h, dRowVector.h, EIG.h, FEGrid.h,
+	idx-vector.h, int16NDArray.h, int32NDArray.h, int64NDArray.h,
+	int8NDArray.h, intNDArray.h, LinConst.h, LPsolve.h, LSODE.h,
+	MArray2.h, MArray.h, MArrayN.h, MDiagArray2.h, NLConst.h, NLEqn.h,
+	ODES.h, ODESSA.h, Quad.h, Range.h, so-array.h, uint16NDArray.h,
+	uint32NDArray.h, uint64NDArray.h, uint8NDArray.h:
+	Delete #pragma interface.
+
+2004-12-17  John W. Eaton  <jwe at octave.org>
+
+	* lo-cieee.c (lo_ieee_signbit): New function.
+	* lo-ieee.h: Provide decl.
+	Don't define lo_ieee_signbit as a macro here.
+	From Orion Poplawski <orion at cora.nwra.com>.
+
+2004-11-18  John W. Eaton  <jwe at octave.org>
+
+	* int32NDArray.cc (pow): Delete instantiation.
+	* int16NDArray.cc (pow): Likewise.
+	* int8NDArray.cc (pow): Likewise.
+	* uint32NDArray.cc (pow): Likewise.
+	* uint16NDArray.cc (pow): Likewise.
+	* uint8NDArray.cc (pow): Likewise.
+
+2004-11-17  John W. Eaton  <jwe at octave.org>
+
+	* kpse.cc (str_llist_float, str_llist_add, kpse_var_expand):
+	Now static.
+	(DB_ENVS, DB_HASH_SIZE, DB_NAME, ALIAS_NAME, ALIAS_HASH_SIZE,
+	DEFAULT_TEXMFDBS): Delete unused macros.
+
+	* Array.cc (Array<T>::index): Call generic N-d indexing function
+	if idx_arg is N-d.
+
+2004-11-09  David Bateman  <dbateman at free.fr>
+
+	* dNDArray.cc (concat): Delete.
+	(NDArray::concat): New methods.
+	* dNDArray.h: Provide decls.
+
+	* CNDArray.cc (concat): Delete.
+	(ComplexNDArray::concat): New methods.
+	* CNDArray.h: Provide decls.
+
+	* boolNDArray.cc (concat): Delete.
+	(boolNDArray::concat): New methods.
+	* boolNDArray.h: Provide decls.
+
+	* chNDArray.cc (concat): Delete.
+	(charNDArray::concat): New methods.
+	* chNDArray.h: Provide decls.
+
+	* oct-inttypes.h (OCTAVE_INT_CONCAT_FN, OCTAVE_INT_CONCAT_DECL):
+	Delete macros.
+
+	* int8NDArray.h, int16NDArray.h, int32NDArray.h, int64NDArray.h,
+	uint8NDArray.h, uint16NDArray.h, uint32NDArray.h, uint64NDArray.h
+	(OCTAVE_INT_CONCAT_DECL): Delete use of macro.
+
+	* int8NDArray.cc, int16NDArray.cc, int32NDArray.cc, int64NDArray.cc,
+	uint8NDArray.cc, uint16NDArray.cc, uint32NDArray.cc, uint64NDArray.cc
+	(OCTAVE_INT_CONCAT_FN): Delete use of macro.
+
+	* intNDArray.cc (intNDArray<T>::concat): New method.
+	* intNDArray.h: Provide decl.
+
+2004-11-08  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.cc: New file.
+	* Makefile.in (TI_SRC): Add it to the list.
+	* oct-inttypes.h (OCTAVE_US_TYPE1_CMP_OP, OCTAVE_US_TYPE1_CMP_OPS,
+	OCTAVE_SU_TYPE1_CMP_OP, OCTAVE_SU_TYPE1_CMP_OPS,
+	OCTAVE_TYPE1_CMP_OPS, OCTAVE_US_TYPE2_CMP_OP,
+	OCTAVE_US_TYPE2_CMP_OPS, OCTAVE_SU_TYPE2_CMP_OP,
+	OCTAVE_SU_TYPE2_CMP_OPS, OCTAVE_TYPE2_CMP_OPS):
+	New macros for comparison operations.  Avoid potential
+	problems with default conversions when comparing signed and
+	unsigned values.
+
+2004-11-03  John W. Eaton  <jwe at octave.org>
+
+	* dMatrix.cc (Matrix::inverse): Return info == -1 for any failure.
+	* CMatrix.cc (ComplexMatrix::inverse): Likewise.
+
+2004-10-19  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assignN): Avoid resizing if assignment will fail.
+
+2004-10-18  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign2): Save result of squeeze operation.
+	Squeeze if ndims is > 2, not if length of RHS vector is > 2.
+
+2004-10-11  David Bateman  <dbateman at free.fr>
+
+	* oct-fftw.cc (class octave_fftw_planner): Add inplace[2] to
+	flag whether transform in- or out-of-place.
+	(octave_fftw_planner::octave_fftw_planner): Initialize it.
+	(octave_fftw_planner::create_plan): Use it.
+
+2004-09-24  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (assign2, assignN): If index is empty, allow RHS to be
+	any empty matrix, not just [].
+
+2004-09-23  John W. Eaton  <jwe at octave.org>
+
+	* mx-ops: Include scalar zero value in type definitions.
+	Delete zero information from ops section.
+	* mk-ops.awk: Use type-specific zero info.
+
+	* mx-op-defs.h (MS_BOOL_OP, SM_BOOL_OP, MM_BOOL_OP, NDS_BOOL_OP,
+	SND_BOOL_OP, NDND_BOOL_OP): Args now include zero values for both
+	LHS and RHS.
+	(MS_BOOL_OPS2, SM_BOOL_OPS2, MM_BOOL_OPS2, NDS_BOOL_OPS2,
+	SND_BOOL_OPS2, NDND_BOOL_OPS2): New macros.
+	(MS_BOOL_OPS, SM_BOOL_OPS, MM_BOOL_OPS, NDS_BOOL_OPS,
+	SND_BOOL_OPS, NDND_BOOL_OPS): Define in terms of 2-zero versions.
+
+	* idx-vector.h (idx_vector::idx_vector_rep::idx_vector_rep (const
+	intNDArray<U>&)): Use explicit as_double () conversion in call to
+	tree_to_mat_idx.
+
+	* oct-inttypes.h (octave_int<T>::operator float): New conversion.
+	(pow): Instead of "if (b_val)", use "if (b_val != zero)".
+	Likewise for the "if (b_val & one)" test.
+	(operator <<, operator >>): Type of retval is octave_int<T1>, not T1.
+
+2004-09-23  David Bateman  <dbateman at free.fr>
+
+	* oct-inttypes.h (OCTAVE_INT_DOUBLE_CMP_OP, OCTAVE_DOUBLE_INT_CMP_OP):
+	New macros.  Use them to define mixed intX-double and double-intX ops.
+
+2004-09-22  Federico Zenith  <zenith at chemeng.ntnu.no>
+
+	* DASPK-opts.in, DASRT-opts.in, ODESSA-opts.in:
+	Fix doc string layout to avoid overfull hbox in printed output.
+
+2004-09-21  John W. Eaton  <jwe at octave.org>
+
+	* mach-info.h (octave_mach_info::flt_fmt_native): Delete.
+	* mach-info.cc (octave_mach_info::string_to_float_format):
+	For "native", set actual native format.
+	(octave_mach_info::float_format_as_string): Delete flt_fmt_native case.
+
+2004-09-17  David Bateman  <dbateman at free.fr>
+
+	* CmplxSCHUR.cc (CmplxSCHUR::init): New arg, calc_unitary to make the
+	calculation of the unitary matrix optional.
+	* dbleSCHUR.cc (SCHUR::init): Ditto.
+	* CmplxSCHUR.h, dbleSCHUR.h: Update decls.
+
+2004-09-15  David Bateman  <dbateman at free.fr>
+
+	* oct-sort.h (octave_sort<T>::set_compare (bool (*comp) (T, T))):
+	New function to set the comparison function for the sort.
+
+2004-09-10  John W. Eaton  <jwe at octave.org>
+
+	* lo-mappers.cc (xround): Fix typo.
+
+2004-09-08  John W. Eaton  <jwe at octave.org>
+
+	* Array.h (Array::~Array): Declare virtual.
+
+	* idx-vector.h (idx_vector::idx_vector): Initialize rep in member
+	initializaion list.  Don't set rep->count since the rep
+	constructor does that.
+
+2004-09-07  John W. Eaton  <jwe at octave.org>
+
+	* data-conv.cc (oct_data_conv::string_to_data_type): Handle dt_logical.
+	(oct_data_conv::data_type_as_string): Likewise.
+
+	* data-conv.h (oct_data_conv::data_type): Add dt_logical to list.
+
+	* Range.cc (round): Delete unused function.
+
+	* lo-mappers.cc (xround): Rename from round.  Change all uses.
+	If HAVE_ROUND, call round, otherwise fake with floor and ceil.
+
+	* oct-inttypes.h: Include <cmath> here.
+
+2004-09-03  David Bateman  <dbateman at free.fr>
+
+	* boolNDArray.cc (boolNDArray::concat, boolNDArray::insert):
+	New functions for boolean matrix concatenation.
+	* boolNDArray.h: Provide decls.
+
+2004-09-03  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttpes.h (OCTAVE_INT_CMP_OP): Convert operarands to double
+	to avoid signed/unsigned int comparison problems.
+
+	* mx-ops: Generate CMP and BOOL ops for mixed integer types and
+	for mixed integer and double types.
+
+	* mk-ops.awk: Output BIN_OP_DECLS, CMP_OP_DECLS, and BOOL_OP_DECLS
+	separately, and only if needed.
+
+	* oct-inttypes.h (octave_fit_to_range): Use constructor instead of
+	static_cast for type conversion.
+
+2004-09-01  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (pow, operator +, operator -, operator *,
+	operator /): Handle mixed integer/double ops.  If op generates a
+	NaN, set result to 0.
+	(octave_int::operator - (void)): Convert to double, then negate,
+	then fit to range.
+
+	* mx-ops: Define integer types.  Include declarations for mixed
+	integer/double ops.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (pow): Args now const reference.
+	(octave_int<T>::operator *=, octave_int<T>::operator /=,
+	octave_int<T>::operator <<=, octave_int<T>::operator >>=):
+	New member functions.
+	(OCTAVE_INT_BITSHIFT_OP): Delete macro.
+	(operator >> (const octave_int<T1>& x, const T2& y)):
+	Define in terms of >>=.
+	(operator << (const octave_int<T1>& x, const T2& y)):
+	Define in terms of <<=.
+	(bitshift): Operate on octave_int<T> objects, not the values, so
+	we get proper saturation properties.
+
+2004-08-31  David Bateman  <dbateman at free.fr>
+
+	* oct-inttypes.h (pow (constT, T)): New template.
+
+	* int8NDArray.cc, int16NDArray.cc, int32NDArray.cc, uint8NDArray.cc, 
+	uint16NDArray.cc, uint32NDArray.cc: Instantiate power function.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int::byte_size): New function.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (EXTRAS): Add intNDArray.cc to the list.
+
+	* data-conv.h (oct_data_conv::data_type): Include sized types.
+	Explicitly number enum elements.
+
+	* data-conv.cc (oct_data_conv::string_to_data_type (const
+	std::string&, int&, oct_data_conv::data_type&,
+	oct_data_conv::data_type&)): New function.
+	(oct_data_conv::string_to_data_type (const std::string&, int&,
+	oct_data_conv::data_type&)): New function.
+	(oct_data_conv::data_type_as_string): New function.
+
+	* dMatrix.cc (read_int, do_read, Matrix::read): Delete.
+	(write_int, do_write, Matrix::write): Delete.
+	* dMatrix.h (Matrix::read, Matrix::write): Delete decls.
+
+	* byte-swap.h: Use template functions and specialization.
+	Change all uses.
+	(swap_2_bytes, swap_4_bytes, swap_8_bytes): Delete.
+
+2004-08-30  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int_fit_to_range): Use template
+	specializations to avoid warnings about signed/unsigned comparisons.
+
+2004-08-28  John W. Eaton  <jwe at octave.org>
+
+	* data-conv.cc (do_float_format_conversion (unsigned char *,
+	size_t, int, oct_mach_info::float_format)): New function.
+	(GET_SIZED_INT_TYPE): New macro.
+	(string_to_data_type): Use it to return sized types corresponding
+	to Octave array data types.
+	(strip_spaces): New function.
+	(do_double_format_conversion, do_float_format_conversion): Pass
+	from_fmt and to_fmt.  Don't always assume the to_fmt is the native
+	float format.
+	(do_double_format_conversion,
+	IEEE_big_double_to_IEEE_little_double,
+	VAX_D_double_to_IEEE_little_double,
+	VAX_G_double_to_IEEE_little_double, Cray_to_IEEE_little_double,
+	IEEE_little_double_to_IEEE_big_double,
+	VAX_D_double_to_IEEE_big_double, VAX_G_double_to_IEEE_big_double,
+	Cray_to_IEEE_big_double, IEEE_little_double_to_VAX_D_double,
+	IEEE_big_double_to_VAX_D_double, VAX_G_double_to_VAX_D_double,
+	Cray_to_VAX_D_double, IEEE_little_double_to_VAX_G_double,
+	IEEE_big_double_to_VAX_G_double, VAX_D_double_to_VAX_G_double,
+	Cray_to_VAX_G_double):
+	Pass data as void*, not double*.
+	(do_float_format_conversion, IEEE_big_float_to_IEEE_little_float,
+	VAX_D_float_to_IEEE_little_float,
+	VAX_G_float_to_IEEE_little_float, Cray_to_IEEE_little_float,
+	IEEE_little_float_to_IEEE_big_float,
+	VAX_D_float_to_IEEE_big_float, VAX_G_float_to_IEEE_big_float,
+	Cray_to_IEEE_big_float, IEEE_little_float_to_VAX_D_float,
+	IEEE_big_float_to_VAX_D_float, VAX_G_float_to_VAX_D_float,
+	Cray_to_VAX_D_float, IEEE_little_float_to_VAX_G_float,
+	IEEE_big_float_to_VAX_G_float, VAX_D_float_to_VAX_G_float,
+	Cray_to_VAX_G_float):
+	Pass data as void*, not float*.
+
+2004-08-27  John W. Eaton  <jwe at octave.org>
+
+	* byte-swap.h (swap_bytes): New template versions, with
+	specializations.
+	(swap_2_bytes, swap_4_bytes, swap_8_bytes): Delete.
+	Change all uses.
+
+2004-08-24  David Bateman  <dbateman at free.fr>
+
+	* chNDArray.cc (concat): Check whether matrix to be inserted is
+	empty instead of checking final matrix.
+	* dNDArray.cc (concat): Likewise.
+	* CNDArray.cc (concat): Likewise.
+
+2004-08-23  David Bateman  <dbateman at free.fr>
+
+        * dim-vector.h (dim_vector::concat): Correct incrementation for
+	non-existent dimensions.
+
+2004-08-09  John W. Eaton  <jwe at octave.org>
+
+	* idx-vector.h (idx_vector::idx_vector_rep::tree_to_mat_idx
+	(const octave_int<U>&)): New member function. 
+	(idx_vector::idx_vector_rep::tree_to_mat_idx (double, bool&),
+	idx_vector::idx_vector_rep::tree_to_mat_idx (int)):
+	Now member functions instead of static in idx-vector.cc.
+	(idx_vector::idx_vector_rep::idx_vector_rep (const octave_int<U>&),
+	idx_vector::idx_vector_rep::idx_vector_rep (const intNDArray<U>&)):
+	New template constructors.
+
+2004-08-05  John W. Eaton  <jwe at octave.org>
+
+	* EIG.cc (EIG::init): Add volatile qualifier to nvr decl.
+
+	* intNDArray.cc (intNDArray<T>::operator !, intNDArray<T>::all,
+	intNDArray<T>::any): Sprinkle with this-> as needed.
+	* mx-inlines.cc (MX_ND_REDUCTION, MX_ND_CUMULATIVE_OP): Likewise.
+
+2004-08-03  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::squeeze): Do nothing for 2-d arrays.  For
+	arrays with more than two dimensions and only one non-singleton
+	dimension, return a column vector.
+
+2004-07-28  John W. Eaton  <jwe at octave.org>
+
+	* oct-cmplx.h (pow (const Complex&, const double&):
+	Convert second arg to complex to avoid libstdc++ bug.
+
+2004-07-27  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (bitshift): New arg, MASK.
+	(OCTAVE_INT_BITSHIFT_OP): Bitshift does not saturate.
+
+2004-07-23  John W. Eaton  <jwe at octave.org>
+
+	* Array.cc (Array<T>::reshape): Return *this if no change in size.
+
+2004-07-23  David Bateman  <dbateman at free.fr>
+
+	* Array.cc, Array.h (cat_ra): Delete.
+	* Array.h, Array-C.cc, Array-d.cc, Array-ch.cc, Array-i.cc 
+	(INSTANTIATE_ARRAY_CAT): Delete.
+
+	* dNDArray.cc, dNDArray.h, CNDArray.cc, CNDArray.h, chNDArray.cc, 
+	chNDArray.h, intNDArray.cc, intNDArray.h (cat): Delete.
+	
+	* Array.cc (Array<T>::insert): Copy data in NDArray version.
+
+	* dNDArray.cc, dNDArray.h, CNDArray.cc, CNDArray.h, chNDArray.cc, 
+	chNDArray.h (concat): New function used for concatenation that does
+	an indexed copy of one array into another.
+
+	* dim-vector.h (concat): New function to concatenate dim_vectors.
+
+	* dNDArray.cc, dNDArray.h, CNDArray.cc, CNDArray.h, chNDArray.cc,
+	chNDArray.h, intNDArray.cc, intNDArray.h (insert): New function for 
+	insertion of one NDArray into another.
+
+	* oct-inttype.cc (OCTAVE_INT_CONCAT_FN, OCTAVE_INT_CONCAT_DECL): New
+	macros to define the int/uint concatenation functions.
+
+	* uint8NDArray.cc, uint16NDArray.cc, uint32NDArray.cc, uint64NDArray.cc
+	int8NDArray.cc, int16NDArray.cc, int32NDArray.cc, int64NDArray.cc
+	(OCTAVE_INT_CONCAT_FN): Instantiate the concatenation function .
+
+	* uint8NDArray.h, uint16NDArray.h, uint32NDArray.h, uint64NDArray.h
+	int8NDArray.h, int16NDArray.h, int32NDArray.h, int64NDArray.h
+	(OCTAVE_INT_CONCAT_DECL): Declare the int/uint concatentaion
+	functions.
+
+2004-07-22  David Bateman  <dbateman at free.fr>
+
+	* oct-sort.h: Don't include oct-obj.h.
+
+	* lo-specfun.cc (is_integer_value): New function.
+	(zbesj, zbesi, zbesy): Special case negative integer or half
+	integer orders that cause overflow for small arguments.
+
+2004-07-12  John W. Eaton  <jwe at octave.org>
+
+	* oct-inttypes.h (octave_int<T>::nbits): New function.
+	(bitshift (const octave_int<T>&, int)): New function.
+
+2004-06-14  John W. Eaton  <jwe at octave.org>
+
+	* mx-base.h: Include headers for new int types.
+
+	* dNDArray.h, dNDArray.cc (NDArray::NDArray (const boolNDArray&),
+	NDArray::NDArray (const charNDArray&)): Delete.
+	(template <class U> explicit NDArray (const intNDArray<U>&)): New
+	constructor.
+	(NDArray::squeze): Call MArrayN::squeeze, not ArrayN::squeeze.
+
+	* chMatrix.h (CharMatrix::transpose): New forwarding functions for
+	return type conversion.
+
+	* ComplexNDArray.h, ComplexNDArray.cc
+	(ComplexNDArray::ComplexNDArray (const ArrayN<Complex>&),
+	(ComplexNDArray::ComplexNDArray (const NDArray&),
+	(ComplexNDArray::ComplexNDArray (const boolNDArray&),
+	(ComplexNDArray::ComplexNDArray (const charNDArray&)): Delete.
+	
+	(ComplexNDArray::squeze): Call MArrayN::squeeze, not ArrayN::squeeze.
+
+	* MArrayN.h:
+	(template <class U> explicit MArrayN<T>::MArrayN (const Array2<U>&),
+	(template <class U> MArrayN<T>::MArrayN (const ArrayN<U>&),
+	(template <class U> explicit MArrayN<T>::MArrayN (const MArray<U>&)):
+	New constructors.
+	(ArrayN<T>::reshape, ArrayN<T>::permute, ArrayN<T>::ipermute,
+	ArrayN<T>::squeeze):
+	New forwarding functions for return type conversion.
+
+	* ArrayN.h:
+	(template <class U> explicit ArrayN<T>::ArrayN (const Array2<U>&),
+	(template <class U> explicit ArrayN<T>::ArrayN (const ArrayN<U>&),
+	(template <class U> explicit ArrayN<T>::ArrayN (const Array<U>&),
+	(template <class U> explicit ArrayN<T>::ArrayN (const Array<U>&,
+	const dim_vector&)): New constructors.
+	(ArrayN<T>::reshape, ArrayN<T>::permute, ArrayN<T>::ipermute,
+	ArrayN<T>::transpose):
+	New forwarding functions for return type conversion.
+
+	* Array.h (template <class U> Array<T>::Array (const Array<U>&)):
+	New constructor.
+	(Array<T>::coerce, Array<T>::byte_size): New functions.
+
+	* Array-i.cc, MArray-i.cc: Instantiate new integer types.
+
+	* oct-inttypes.h, int16NDArray.h, int32NDArray.h, int64NDArray.h,
+	int8NDArray.h , intNDArray.h, uint16NDArray.h, uint32NDArray.h,
+	uint64NDArray.h, uint8NDArray.h, int16NDArray.cc, int32NDArray.cc,
+	int64NDArray.cc, int8NDArray.cc, intNDArray.cc, uint16NDArray.cc,
+	uint32NDArray.cc, uint64NDArray.cc, uint8NDArray.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2004-06-04  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): New arg, RET_ELT_TYPE.  Use
+	"RET_ELT_TYPE ()" rather than "false" as fill value for retval
+	resize op.  Change all uses.
+
+2004-06-03  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (assignN): Allow magic colon for dimensions lvalue
+	greater than the existing number of dimensions in lvalue.
+
+2004-04-30  David Bateman  <dbateman at free.fr>
+
+        * dim_vector.h (dim_vector::dim_vector_rep::dim_vector_rep):
+	New arg, fill_value.
+	(dim_vector::resize): Allow optional fill_value argument.
+
+        * Array.cc (Array<T>::index (Array<idx_vector>&, int, const T&)):
+	Don't chop trailing dimensions of Array<idx_vector> if there is
+	more than one element in idx_vector.  Resize the return value to
+	the size of Array<idx_vector>.
+
+	* Array-util.cc (short_freeze): Better freeze of last dimension of
+	idx_vector that is shorter than a dim_vector.
+
+2004-04-23  John W. Eaton  <jwe at octave.org>
+
+	* oct-sort.cc: Don't include oct-obj.h.
+
+2004-04-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::index2, Array<T>::indexN):
+	Don't set invalid dimensions on return value.
+
+2004-04-21  John W. Eaton  <jwe at octave.org>
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Chop trailing singletons.
+
+2004-04-06  David Bateman  <dbateman at free.fr>
+
+	* Array.cc (Array<T>::resize_no_fill (const dim_vector& dv),
+	Array<T>::resize_and_fill (const dim_vector& dv, const T& val)):
+	Make their behavior equivalent except for filling vs. not filling.
+
+  	* oct-sort.cc: New template class for arbitrary sorting.
+  	* oct-sort.h: Declaration of sort class.
+  	* Makefile: Add them to the appropriate lists.
+
+2004-04-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-inlines.cc (MX_ND_CUMULATIVE_OP): Fix off-by-one error.
+
+2004-04-02  David Bateman  <dbateman at free.fr>
+
+	* lo-specfun.cc (besselj, bessely, besseli, besselk, besselh1, 
+	besselh2, airy, biry, betainc, gammainc, do_bessel):
+	New N-d array versions.
+	(SN_BESSEL, NS_BESSEL, NN_BESSEL): New macros.
+	* lo-specfun.h (besselj, bessely, besseli, besselk, besselh1, 
+	besselh2, airy, biry, betainc, gammainc): Provide decls.
+	
+	* dNDArray.cc (NDArray::min, NDArray::max, min, max):
+	New functions.
+	* dNDArray.h (NDArray::min, NDArray::max, min, max): Provide decls.
+
+	* CNDArray.cc (ComplexNDArray::min, ComplexNDArray::max, min, max):
+	New functions.
+	* CNDArray.h (ComplexNDArray::min, ComplexNDArray::max, min, max): 
+	Provide decls.
+
+2004-03-17  David Hoover  <jazzdaq at yahoo.com>
+
+	* DASPK.cc (DASPK::do_integrate): Always add n*n elements to the
+	work vector, not just when using a numerical Jacobian.
+
+2004-03-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* so-array.cc (SND_CMP_OP, NDS_CMP_OP, NDND_CMP_OP):
+	Omit empty result args.
+
+	* Array.cc (Array<T>::Array (const Array<T>&, const dim_vector&)):
+	Move here from Array.h, check that size of array arg is not
+	smaller than the size defined by the new dimensions.
+
+2004-03-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::index2): Allow result to be N-d if indexing
+	a scalar or vector with an N-d array.
+
+2004-03-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::index2): If scalar or vector is indexed by
+	matrix, return object that is the same size as the index.
+
+	* mx-op-defs.h (NDND_CMP_OP, MM_CMP_OP): Require dimensions to agree.
+	Eliminate MT_RESULT args.  Return value is always size of args.
+	(MS_CMP_OP, SM_CMP_OP, NDS_CMP_OP, SND_CMP_OP):
+	Eliminate EMPTY_RESULT arg.
+	Return value is always size of matrix or N-d array arg.
+	(TBM, FBM, NBM): Delete unused macros.
+
+2004-03-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::maybe_delete_elements): Return immediately
+	if all LHS dimensions are zero.  For one index case, freeze and
+	sort idx_vec before checking length, and do nothing if
+	num_to_delete is zero.
+	(Array<T>::maybe_delete_elements_2): Omit Fortran-indexing warning.
+
+2004-03-04  David Bateman  <dbateman at free.fr>
+
+	* dNDArray.cc (NDArray::ifourier): Arg is int, not const int.
+	* CNDArray.cc (ComplexNDArray::ifourier): Likewise.
+
+2004-03-03  Hans Ekkehard Plesser  <hans.ekkehard.plesser at nlh.no>
+
+	* base-lu.cc (base_lu<>::L): Check bounds before setting diagonal
+	element.
+
+2004-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.h (Range::Range): Add cache to member initialization list.
+	(Range::clear_cache): New private function.
+
+	* Range.h (Range::set_base, Range::set_limit, Range::set_inc):
+	Use clear cache.  Don't do anything if range does not change.
+	* Range.cc (Range::sort): Likewise.
+
+2004-03-02  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Range.cc (Range::matrix_value): Cache result.
+	(Range::sort): Clear cache.
+	* Range.h (Range::cache): New data member.
+	(Range::set_base, Range::set_limit, Range::set_inc): Clear cache.
+	(Range::print_range): Delete.
+
+2004-03-02  David Bateman  <dbateman at free.fr>
+ 
+	* oct-fftw.cc: Only two versions of plan, and avoid endless
+	changes between them.  Faster for small fft's.
+	(octave_fftw_planner::simd_align, octave_fftw_planner::rsimd_align):
+	New member variables. 
+	(octave_fftw_planner::ialign, octave_fftw_planner::oalign,
+	octave_fftw_planner::rialign, octave_fftw_planner::roalign): Delete.
+	Change all uses.
+	(CHECK_SIMD_ALIGNMENT): New macro.
+	(octave_fftw_planner::create_plan): Use it.
+
+2004-03-01  Petter Risholm  <risholm at idi.ntnu.no>
+
+	* Array.cc (Array<T>::insertN): Eliminate N-d indexing.
+
+        * mx-inlines.cc (MX_ND_CAT): Delete macro.
+
+        * dNDArray.h, chNDArray.h, CNDArray.h (cat): Change declaration.
+        * dNDArray.cc (NDArray<T>::cat): Call new form of cat function.
+        * chNDArray.cc (charNDArray<T>::cat): Ditto.
+        * CNDArray.cc (ComplexNDArray<T>::cat): Ditto.
+
+        * Array.h (cat_ra): Return int.  Accept idx and move args, not add_dim.
+        * Array.cc (cat_ra): Speed up implementation by avoiding N-d indexing.
+
+2004-02-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-edit.c (octave_rl_set_startup_hook,
+	octave_rl_get_startup_hook, octave_rl_set_event_hook,
+	octave_rl_get_event_hook): Omit casts.
+	* oct-rl-edit.h (rl_startup_hook_fcn_ptr, rl_event_hook_fcn_ptr):
+	Return value for function pointer typedef is now int.
+	* cmd-edit.h (command_editor::startup_hook_fcn,
+	command_editor::event_hook_fcn): Likewise.
+	* cmd-hist.cc, cmd-hist.h (command_history::goto_mark,
+	command_history::do_goto_mark, gnu_history::do_goto_mark):
+	Return type is now int.  Return 0.
+
+	* EIG.cc (EIG::init, EIG::symmetric_init):
+	Query Lapack for workspace size.
+
+2004-02-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::resize_and_fill (const dim_vector&, const T&)): 
+	Fix thinko in extending dimensions.
+
+2004-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (Range::matrix_value, Range::min, Range::max):
+	Don't compute values beyond the limits of the range.
+	(operator << (std::ostream&, const Range&)): Likewise.
+
+2004-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-fftw.cc (octave_fftw_planner::create_plan):
+	Cast IN and OUT	args to ptrdiff_t instead of long before masking.
+	From Paul Kienzle <pkienzle at users.sf.net>.
+
+	* Array.cc (Array<T>::insertN (const Array<T>&, int, int)):
+	Rename from Array<T>::insert.
+	(Array<T>::insert2 (const Array<T>&, int, int)):
+	Reinstate old Array<T>::insert function under this name.
+	(Array<T>::insert (const Array<T>&, int, int)):
+	New function.  Dispatch to insert2 or insertN as appropriate.
+
+2004-02-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-fftw.cc (convert_packcomplex_1d, convert_packcomplex_Nd): 
+	Sprinkle with OCTAVE_QUIT.
+
+2004-02-16  David Bateman  <dbateman at free.fr>
+
+	* oct-fftw.cc (octave_fftw_planner::create_plan, octave_fftw::fftNd):
+	Add support for FFTW 3.x. Include the ability to
+	use the real to complex transform for fft's of real matrices
+	(octave_fftw_planner::create_plan2d): Delete.
+	(octave_fftw::fft2d): Delete.
+	(convert_packcomplex_1d, convert_packcomplex_Nd):
+	New static functions.
+	* oct-fftw.h: Update decls.
+
+	* dMatrix.cc (Matrix::fourier, Matrix::ifourier,
+	Matrix::fourier2d, Matrix::ifourier2d): FFT's use real to complex
+	transforms.  1D FFT of a matrix done as single call rather than
+	loop.  Update for FFTW 3.x
+	* CMatrix.cc (ComplexMatrix::fourier, ComplexMatrix::ifourier,
+	ComplexMatrix::fourier2d, ComplexMatrix::ifourier2d): 1D fft of a
+	matrix done as single call rather than loop.  Update for FFTW 3.x.
+
+	* dNDArray.cc (NDArray::fourier, NDArray::ifourier,
+	NDArray::fourierNd, NDArray::ifouriourNd): New fourier transform
+	functions for Nd arrays.
+	* dNArray.h Provide decls.
+	* CNDArray.cc (ComplexNDArray::fourier, ComplexNDArray::ifourier,
+	ComplexNDArray::fourierNd, ComplexNDArray::ifouriourNd): New
+	fourier transform functions for complex Nd arrays.
+	* CNArray.h: Provide decls.
+	
+2004-02-15  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (Array<T>::insert (const Array<T>&, int, int)):
+	Make it work for N-d arrays.
+
+	* ArrayN.h (ArrayN<T>::insert (const ArrayN<T>& a, int, int)):
+	New function.
+
+	* CNDArray.cc (ComplexNDArray::insert (const NDArray&, int, int),
+	ComplexNDArray::insert (const ComplexNDArray&, int, int)):
+	New functions.
+	* CNDArray.h: Provide decls.
+
+2004-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (LINK_DEPS): Always define.
+
+	* Array.cc (Array<T>::squeeze): Always return an array with at
+	least two dimensions.
+
+2004-02-13  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* mx-inlines.cc (MX_ND_CAT): New macro.
+	* dNDArray.cc (NDArray::cat): New function.
+	* dNDArray.h: Provide decls.
+	* CNDArray.cc (complexNDArray::cat): New function.
+	* CNDArray.h: Provide decls.
+	* chNDArray.cc (charNDArray::cat): New function.
+	* chNDArray.h: Provide decls.
+
+2004-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (maybe_delete_elements_2): Allow X(n) = [] for 2-d X.
+	(Array<T>assign2): Also call maybe_delete_elements for single
+	index when rows and columns or LHS are both greater than 1.
+
+2004-02-13  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (Array<T>::maybe_delete_elements):
+	Check for index out of bounds.	Handle one index.
+
+	* Array.cc (Array<T>::indexN): Use dim_vector (0, 0) instead of
+	dim_vector (0) to create empty return vector.
+
+2004-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::assignN): Don't crash if trying to resize a
+	non-empty LHS when the number of lhs dimensions is less than the
+	number of indices.  Detect error if attempting to resize non-empty
+	LHS with colon indices.
+
+2004-02-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::resize_and_fill): Don't bother to assign any
+	values unless the length of the new array is greater than 0.
+	(Array<T>::resize_no_fill): Likewise.
+
+	* Array-util.cc (index_in_bounds): Also return false if ra_idx(i)
+	is equal to dimensions(i).
+
+	* Array-util.h, Array-util.cc (equal_arrays, any_zero_len,
+	get_zero_len_size, number_of_elements):
+	Delete unused functions.
+
+	* Array-util.cc (get_ra_idx): Use dim_vector::numel instead of
+	number_of_elements function.
+	* Array.cc (Array<T>::indexN): Likewise.
+
+	* Array.cc (Array<T>::indexN): Use dim_vector::operator == instead
+	of equal_arrays function.
+	(Array<T>::index, Array<T>::indexN, Array<T>::assignN) Use
+	dim_vector::any_zero instead of any_zero_len function.
+
+	* Array.cc (Array<T>::assignN): Eliminate special case for empty index.
+	Don't skip reshaping and resizing if RHS is empty.
+
+	* Array.cc (Array<T>::assignN): Simplify loop for array	assignment.
+	Move body of MAYBE_RESIZE_ND_DIMS here since it is only used once.  
+	Delete unused variables is_colon and is_colon_equiv.
+	Correctly resize for expressions like x(:,:,2) = ones(3,3) when
+	LHS is not yet defined.
+	Error for resizing if number of indices is less than number of LHS
+	dimensions.
+
+	* Array.cc (Array<T>::maybe_delete_elements): Maybe warn about
+	Fortran-style indexing.
+
+2004-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::assignN): Simplify.
+	Allow assignments to succeed if number if indices is less than the
+	number of RHS dimensions.
+
+2004-02-05  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (Array<T>::maybe_delete_elements): Reshape LHS
+	when number of indices is less than number of dimensions.
+
+	* Array.cc (Array<T>::assignN, Array<T>::maybe_delete_elements):
+	Remove unsued variable lhs_inc.
+
+	* Array.cc (Array<T>::maybe_delete_elements): Declare idx_is_colon
+	and idx_is_colon_equiv Array<int> instead of dim_vector.
+
+	* Array.cc (Array<T>::assignN): Compute new dims in a cleaner way.
+
+	* Array.cc (Array<T>::index): Check for frozen_lengths.length ()
+	== n_dims before checking to see if all indices are colon_equiv.
+
+2004-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::assignN): Require RHS == 0x0 matrix for
+	deleting elements.
+	(Array<T>::index): Remove trailing singletons in ra_idx, but leave
+	at least ndims elements.
+
+2004-02-05  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (Array<T>::assignN): Accept assignment of a vector
+	oriented differently from the index.
+
+	* dim-vector.h (dim_vector::squeeze): Return value always has at
+	least two dimensions.
+
+2004-02-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dim-vector.h (dim_vector::squeeze): New function.
+	(Array<T>::assignN): Use it instead of chop_trailing_singltons for
+	deciding whether the assignment conforms.
+
+	* Array.cc (Array<T>::assignN): Simplify dimension check by
+	comparing rhs_dims and frozen_len sans trailing singletons.
+
+2004-02-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (tree_to_mat_idx): New arg, conversion_error.
+	Call error handler and return conversion_error == true if arg is
+	not integer.
+	(IDX_VEC_REP::idx_vector_rep): Exit early if conversion_error.
+
+2004-02-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* boolNDArray.h (boolNDArray::boolNDArray): Declare dim_vector
+	reference arg const.
+
+2004-01-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-flags.cc: Include Array-flags.h, not Array.h.  Doh.
+
+2004-01-30  Jakub Bogusz  <qboosh at pld-linux.org>
+
+	* Array-flags.h (liboctave_wfi_flag, liboctave_wrore_flag):
+	Now bool, to match definition in Array-flags.cc.
+
+2004-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc: Include <vector> instead of <memory> for new
+	definition of OCTAVE_LOCAL_BUFFER.
+
+	* EIG.cc, EIG.h (EIG::init, EIG::symmetric_init, EIG::hermitian_init):
+	New arg, calc_eigenvectors.
+	* EIG.h (EIG:EIG): New optional arg, calc_eigenvectors.
+	Based on patch from David Bateman <dbateman at free.fr>.
+
+2004-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::assign2, Array<T>::assignN):
+	For X(I) = RHS, don't restrict I to fewer elements than X.
+
+	* Array.cc (Array<T>::assign2): Simplify indexing for X(I) = RHS case.
+
+2004-01-22  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* mx-inlines.cc	(MX_ND_REDUCTION, MX_ND_CUMULATIVE_OP):
+	Simplify calculation of number of elements in retval.
+
+	* Array.cc (Array<T>::assignN): Eliminate unnecessray code for
+	filling when RHS is scalar and dimension lengths agree.
+
+2004-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (distclean): Remove mx-ops.h, $(MX_OP_INC),
+	$(VX_OP_INC), $(MX_OP_SRC), $(VX_OP_SRC), and $(OPTS_INC).
+
+2004-01-22  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (Array<T>::resize_and_fill): Correctly copy old elements.
+	(Array<T>::assign2): Check for RHS dimensions larger than 2.
+
+2004-01-21  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.h (Array<T>::chop_trailing_singletons): New function.
+	* Array.cc (Array<T>::assignN): Use it on LHS.
+
+	* Array.cc (Array<T>::assignN): Fix incorrectly nested if statement.
+	Retrieve scalar element by passin 0 instead of an index array.
+	Check for singleton dimensions where RHS is matrix or higher dimension.
+	Make sure index is in bounds.
+
+2004-01-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (octave_ieee_init): Ensure that octave_Inf,
+	octave_NaN, and octav_NA values are always initialized.  Check
+	floating point format, not HAVE_ISINF, HAVE_FINITE, or HAVE_ISNAN
+	to decide whether to do IEEE initialization.
+
+2004-01-06  David Bateman  <dbateman at free.fr>
+
+ 	* CNDArray.cc (ComplexNDArray::any_element_is_inf_or_nan, 
+ 	ComplexNDArray::all_elements_are_real, ComplexNDArray::all_integers,
+ 	ComplexNDArray::too_large_for_float): New functions
+ 
+ 	* CNDArray.cc (operator <<, operator >>): New IO operators.
+ 	* CNDArray.h: Provide decls.
+ 	* dNDArray.cc (operator <<, operator >>): New IO operators.
+ 	* dNDArray.h: Provide decls.
+
+2003-12-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-ops: Delete bnda x bnda, b x bnda, and bnda x b ops since
+	they are already defined in boolNDArray.cc.
+
+	* Array-util.cc (get_zero_len_size): Delete.
+	* Array.cc (Array<T>::index (Array<idx_vector>&, int, const T&)):
+	Handle zero-length result dimensions the same as empty original
+	indices.
+
+2003-12-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dim-vector.h (dim_vector::chop_trailing_singleton_dims,
+	dim_vector::dim_vector_rep::chop_trailing_singleton_dims):
+	New functions.
+	* Array.cc (ArrayN<T>::indexN): Use it.
+	(ArrayN<T>::index (Array<idx_vector>&, int, const T&)): Likewise.
+
+2003-11-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* boolNDArray.cc: Define BOOL ops.  Define mixed CMP ops.
+	* boolNDArray.h: Declare BOOL ops.  Declare mixed CMP ops.
+
+2003-11-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-ops.awk: Also emit #include "Array-util.h".
+
+	* mx-ops: Add bool, boolMatrix, and boolNDarray types.
+	Add bnda x bnda, b x bnda, and bnda x b ops.
+
+	* MArray-misc.cc: Delete.
+	* Makefile.in (MATRIX_SRC): Remove it from the list.
+
+	* Array-util.h, Array-util.cc (gripe_nonconformant): Move here from
+	MArray.h, MArray2.h, MArrayN.h, and MArray-misc.cc.
+
+2003-11-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleQR.cc (QR::init): Use separate pwork pointers.
+	* CmplxQR.cc (ComplexQR::init): Likewise.
+
+	* oct-group.cc (octave_group::getgrnam): Pass correct args to
+	two-arg getgrnam version.
+
+	* Array.cc (assignN): Allow single indexing to work.
+	(Array<T>::range_error (const char*, const Array<int>&)):
+	Report index values.
+
+	* Array.cc (Array<T>::index): Delete unused arg names.
+	* ODESSA.cc (odessa_j): Likewise.
+	* DASRT.cc (ddasrt_f, ddasrt_g): Likewise.
+	* DASPK.cc (ddaspk_psol): Likewise.
+	* lo-mappers.cc (imag): Likewise.
+	* Array-util.cc (get_zero_len_size): Likewise.
+	* kpse.cc (path_search, path_find_first_of): Likewise.
+	* cmd-edit.cc (do_generate_filename_completions): Likewise.
+
+	* dim-vector.h (dim_vector::all_ones): New function.
+
+2003-11-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.h (idx_vector::orig_empty): Check orig_dims for
+	zeros, not orig_rows or orig_columns.
+	(idx_vector::idx_vector_rep::orig_rows): Define using orig_dims.
+	(idx_vector::idx_vector_rep::orig_columns): Likewise.
+
+	* idx-vector.cc (idx_vector::idx_vector_rep::orig_nr,
+	(idx_vector::idx_vector_rep::orig_nc): Delete.
+
+	* idx-vector.cc (idx_vector::idx_vector_rep):
+	Use initialization lists for constructors.
+
+	* Array.cc (Array<T>::indexN): Correctly handle single colon index.
+	Omit special case for ra_idx.capacity () == 1.
+	Always allow single index for matrix args with optional warning.
+
+	* idx-vector.h, idx-vector.cc: Convert boolMatrix functions to use
+	boolNDArray.  Likewise, convert Matrix functions to use	NDArray.
+
+	* Array-so.cc: New file.  Move instantiations here from so-array.h.
+	* Makefile.in (TI_SRC): Add it to the list.
+
+	* MArray-defs.h (DO_VS_OP2, DO_VV_OP2): Accept args for element
+	type and the names of the left and right operands.  Change all uses.
+
+	* so-array.cc, so-array.h: New files.  Move streamoff_array here
+	from src/ov-streamoff.h and src/ov-streamoff.cc.
+
+2003-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArrayN.cc (operator -=, operator +=): Check dimensions, not
+	just length.
+
+	* Array2.h, Array3.h, DiagArray2.h, DiagArray2.cc, MDiagArray2.h,
+	ArrayN.h:  Add this-> or Base:: qualifiers for references to
+	non-dependent member functions and data as needed.
+
+	* DiagArray2.h, DiagArray2.cc: Delete unused code.
+
+	* Array2.h (Array2<T>::operator =): Don't copy dimensions here.
+	* Array3.h (Array3<T>::operator =): Likewise.
+	* DiagArray2.h (DiagArray2<T>::operator =): Likewise.
+	Include Array.h, not Array2.h.
+
+2003-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* str-vec.cc (list_in_columns): Fix previous change.
+
+	* dim-vector.h (dim_vector::num_ones): New function.
+	* Array.cc (maybe_delete_elements): Use it instead of
+	num_ones (const Array<int>&).
+
+	* Array.cc (assignN): Omit dubious check of singleton dimensions.
+
+	* dNDArray.cc (NDArray::all_elements_are_int_or_inf_or_nan,
+	NDArray::any_element_is_inf_or_nan, NDArray::too_large_for_float):
+	New functions.
+	* dNDArray.h: Provide decls.
+
+	* dMatrix.h (Matrix::any_element_is_negative,
+	Matrix::any_element_is_inf_or_nan, Matrix::too_large_for_float,
+	Matrix::all_elements_are_int_or_inf_or_nan, Matrix::all_integers):
+	Simplify.
+
+	* dNDArray.cc (NDArray::abs): Make it work for N-d arrays.
+	* CNDArray.cc (ComplexNDArray::abs): Likewise.
+
+	* dNDArray.cc (real, imag): New functions.
+	* dNDArray.h: Provide decls.
+
+2003-11-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (TEMPLATE_SRC): Move MArrayN.cc here from MATRIX_SRC.
+
+2003-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (Array<T>::resize (int, const T&)): Reinstate.
+	* MArray.h (resize): Delete.
+	* MArray2.h (resize): Delete.
+	* DASRT.cc (DASRT::integrate): Use resize, not resize_and_fill.
+	* ODESSA (ODESSA::integrate): Likewise.
+
+2003-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (dist): Depend on stamp-prereq.
+
+2003-11-12  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mach-info.c (oct_mach_info::init_float_format) [CRAY]:
+	Kluge to make it work.
+
+	* lo-ieee.cc (octave_ieee_init): Set octave_Inf, octave_NaN, and
+	octave_NA to DBL_MAX if native float format is vaxd, vaxg, or cray.
+
+	* cmd-edit.cc (gnu_readline::do_generate_filename_completions,
+	default_command_editor::do_generate_filename_completions,
+	command_editor::generate_filename_completions): New functions.
+	* cmd-edit.h: Provide decls.
+	* oct-rl-edit.c (octave_rl_filename_completion_function): New
+	function.
+	* oct-rl-edit.h: Provide decl.
+
+2003-11-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (INSTANTIATE_ARRAY_ASSIGN, INSTANTIATE_ARRAY_AND_ASSIGN,
+	INSTANTIATE_ARRAY): New macros.
+	* Array-C.cc, Array-b.cc, Array-ch.cc, Array-d.cc, Array-i.cc,
+	Array-idx-vec.cc, Array-s.cc, Array-str.cc, ODESSA.cc: Use them.
+
+	* Array.h (Array<T>::ipermute): New function.
+
+2003-11-11  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (Array<T>::permute): New function.
+	* Array.h: Provide decl.
+
+	* Array-util.cc (calc_permutated_idx): New function.
+	* Array-util.h: Provide decl.
+
+2003-11-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::index2): Return value has orientation of
+	indexed value if indexing a vector with a bool matrix.
+
+	* ArrayN.h (ArrayN<T>::get_size): Delete.
+
+	* Array.cc, ArrayN.cc, dNDArray.cc, CNDArray.cc, boolNDArray.cc,
+	chNDArray.cc: Include Array-util.h instead of ArrayN-inline.h.
+
+	* ArrayN-inline.h: Delete.
+	* Array-util.h, Array-util.cc: New files, from ArrayN-inline.h.
+	* Makefile.in: Fix the appropriate lists.
+
+	* Array.cc, Array.h, ArrayN.h, CMatrix.cc, CNDArray.h,
+	CRowVector.cc, CmplxQR.cc, CollocWt.h, DASPK.h, DASRT.h, DASSL.h,
+	FEGrid.cc, LP.h, LSODE.h, MArrayN.h, ODE.h, ODES.h, ODESSA.cc,
+	boolNDArray.h, chNDArray.h, dMatrix.cc, dNDArray.h, dRowVector.cc,
+	dbleQR.cc, kpse.cc, oct-rl-hist.c, str-vec.cc, str-vec.h:
+	Avoid -Wshadow warnings.
+
+2003-11-08  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (Array<T>::nil_rep): Qualify return type with typename.
+
+	* mk-ops.awk: Delete elements of bool_headers array individually.
+
+2003-11-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (maybe_delete_elements): Rename arg idx to ra_idx.
+
+2003-10-31  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* mx-inlines.cc (MX_ND_CUMULATIVE_OP): New macro.
+
+	* CNDArray.cc, CNDArray.h (ComplexNDArray::cumsum,
+	ComplexNDArray::cumprod): Return ComplexNDArray.  Handle N-d arrays.
+	* dNDArray.cc, dNDArray.h (NDArray::cumsum, NDArray::cumprod):
+	Return NDArray.  Handle N-d arrays.
+
+2003-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.cc (LSODE::do_integrate): Avoid name conflict on systems
+	that upcase Fortran names by calling dlsode instead of lsode.
+
+	* ODESSA.cc (ODESSA::do_integrate): Avoid name conflict on systems
+	that upcase Fortran names by calling dodessa instead of odessa.
+
+	* file-ops.cc (file_ops::symlink): Cope with systems that expect
+	non-const args for symlink system call.
+	(file_ops::readlink): Likewise, for readlink.
+
+	* DASRT.cc (DASRT::integrate): Fix typo in Fortran function name.
+
+2003-10-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mach-info.h (oct_mach_info): Prefix enum elements with flt_fmt_.
+	Change all uses.
+
+2003-10-29  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* dNDArray.cc (NDArray::cumprod, NDArray::cumsum, NDArray::prod,
+	NDArray::sum, NDArray::sumsq, NDArray::abs): New functions.
+	* dNDArray.h: Provide decls.
+	* CNDArray.cc (ComplexNDArray::cumprod, ComplexNDArray::cumsum,
+	ComplexNDArray::prod, ComplexNDArray::sum, ComplexNDArray::sumsq,
+	ComplexNDArray::abs): New functions.
+	* CNDArray.h: Provide decls.
+
+	* mx-inlines.cc (MX_ND_REDUCTION): Rename from MX_ND_ANY_ALL.
+	Generalize to handle other reduction operations.
+	(MX_ND_REAL_OP_REDUCTION, MX_ND_COMPLEX_OP_REDUCTION,
+	MX_ND_ALL_ANY_REDUCTION): New macros.
+
+2003-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::reshape): New function.
+	* Array.h: Provide decl.
+
+	* dim-vector.h (dim_vector::numel): New function.
+
+	* dim-vector.h (dim_vector_rep::dim_vector_rep (int, const
+	dim_vector&)): Correctly handle case of n < dv->ndims.
+
+2003-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dim-vector.h (dim_vector::any_zero): New function.
+	(dim_vector::str): New default arg, sep.
+
+	* Array.h (Array<T>::numel): New function.
+
+2003-10-27  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* mx-inlines.cc (MX_ND_ALL_EXPR, MX_ND_ANY_EXPR,
+	MX_ND_ALL_EVAL, MX_ND_ANY_EVAL, MX_ND_ALL_ANY): New macros.
+	* dNDArray.h (NDArray::all, NDArray::any): Return type now boolNDArray.
+	* CNDArray.h (ComplexNDArray::all, ComplexNDArray::any): Likewise.
+	* boolNDArray.h (boolNDArray::all, boolNDArray::any): Likewise.
+	* chNDArray.h (charNDArray::all, charNDArray::any): Likewise.
+	* dNDArray.cc (NDArray::all, NDArray::any): Make them work.
+	* CNDArray.cc (ComplexNDArray::all, ComplexNDArray::any): Likewise.
+	* boolNDArray.cc (boolNDArray::all, boolNDArray::any): Likewise.
+	* chNDArray.cc (charNDArray::all, charNDArray::any): Likewise.
+
+2003-10-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::resize_and_fill): Allow number of dimensions
+	to change.  From Petter Risholm  <risholm at stud.ntnu.no>.
+
+	* oct-rand.cc, CColVector.cc, CMatrix.cc, CRowVector.cc,
+	CmplxAEPBAL.cc CmplxCHOL.cc, CmplxHESS.cc, CmplxLU.cc, CmplxQR.cc,
+	CmplxQRP.cc, CmplxSCHUR.cc, CmplxSVD.cc, CollocWt.cc, DASPK.cc,
+	DASRT.cc, DASSL.cc, EIG.cc, LSODE.cc,  NLEqn.cc, ODESSA.cc,
+	Quad.cc, dColVector.cc, dMatrix.cc, dRowVector.cc, dbleAEPBAL.cc,
+	dbleCHOL.cc, dbleHESS.cc, dbleLU.cc, dbleQR.cc, dbleQRP.cc,
+	dbleSCHUR.cc, dbleSVD.cc, lo-specfun.cc:
+	Use new F77 arg macros in declarations of external Fortran
+	subroutines and for calling them.
+
+2003-10-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::resize_no_fill (const dim_vector&)):
+	Allow number of dimensions to change.
+	(Array<T>::resize_no_fill (int, int)): Require ndims to be 0 or 2.
+	(Array<T>::resize_and_fill (int, int, const T&)): Likewise.
+	(Array<T>::resize_no_fill (int, int, int)): Require ndims to be 0 or 3.
+	(Array<T>::resize_and_fill (int, int, int, const T&)): Likewise.
+	(Array<T>::transpose): Require ndims to be 2.
+	(Array<T>::index2): Likewise.
+	(Array<T>::index (idx_vector&, idx_vector&, int, const T&)): Likewise.
+	(Array<T>::maybe_delete_elements_2): Likewise.
+	(Array<T>::maybe_delete_elements (idx_vector&, idx_vector&)): Likewise.
+	(Array<T>::index1): Use resize_and_fill.
+	(MAYBE_RESIZE_ND_DIMS): Likewise.
+
+	* ODESSA.cc (ODESSA::integrate): Use resize_and_fill for x_s_out.
+
+	* MArray2.h (MArray2<T>::resize (int, int)): New function.
+	(MArray2<T>::resize (int, int, const T&)): New function.
+
+	* MArray.h (MArray<T>::resize (int)): New function.
+	(MArray<T>::resize (int, const T&)): New function.
+
+	* DASRT.cc (DASRT::integrate): Use resize_and_fill for jroot.
+
+	* DASPK-opts.in: Use single-arg resize for initial condition
+	heuristics.
+
+	* dim-vector.h (class dim_vector): Now reference counted.
+	(dim_vector_rep::elem): Use assert to check that index is in bounds.
+
+2003-10-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::squeeze): Delete redundant retval decl.
+
+	* mx-cdm-cm.cc, mx-cdm-cm.h, mx-cdm-cs.cc, mx-cdm-cs.h,
+	mx-cdm-dm.cc, mx-cdm-dm.h, mx-cdm-m.cc, mx-cdm-m.h, mx-cdm-s.cc,
+	mx-cdm-s.h, mx-cm-cdm.cc, mx-cm-cdm.h, mx-cm-dm.cc, mx-cm-dm.h,
+	mx-cm-m.cc, mx-cm-m.h, mx-cm-s.cc, mx-cm-s.h, mx-cs-cdm.cc,
+	mx-cs-cdm.h, mx-cs-dm.cc, mx-cs-dm.h, mx-cs-m.cc, mx-cs-m.h,
+	mx-dm-cdm.cc, mx-dm-cdm.h, mx-dm-cm.cc, mx-dm-cm.h, mx-dm-cs.cc,
+	mx-dm-cs.h, mx-dm-m.cc, mx-dm-m.h, mx-dm-s.cc, mx-dm-s.h,
+	mx-m-cdm.cc, mx-m-cdm.h, mx-m-cm.cc, mx-m-cm.h, mx-m-cs.cc,
+	mx-m-cs.h, mx-m-dm.cc, mx-m-dm.h, mx-ops.h, mx-s-cdm.cc,
+	mx-s-cdm.h, mx-s-cm.cc, mx-s-cm.h, mx-s-dm.cc, mx-s-dm.h,
+	vx-ccv-cv.cc, vx-ccv-cv.h, vx-ccv-s.cc, vx-ccv-s.h, vx-crv-rv.cc,
+	vx-crv-rv.h, vx-crv-s.cc, vx-crv-s.h, vx-cs-cv.cc, vx-cs-cv.h,
+	vx-cs-rv.cc, vx-cs-rv.h, vx-cv-ccv.cc, vx-cv-ccv.h, vx-cv-cs.cc,
+	vx-cv-cs.h, vx-rv-crv.cc, vx-rv-crv.h, vx-rv-cs.cc, vx-rv-cs.h,
+	vx-s-ccv.cc, vx-s-ccv.h, vx-s-crv.cc, vx-s-crv.h: Delete.  These
+	files are now automatically generated.
+
+	* Makefile.in ($(VX_OP_INC), $(VX_OP_SRC), $(MX_OP_INC),
+	$(MX_OP_SRC)): Generate lists with new mk-ops.awk script.
+	Add rules to generate these files and mx-ops.h.
+	(stamp-prereq): Depend on these files.
+
+	* mx-ops, vx-ops, mk-ops.awk: New files.
+	* Makefile.in (DISTFILES): Add them to the list.
+
+2003-10-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* NDArray.cc (NDArray::NDArray (const boolNDArray),
+	NDArray::NDArray (const charNDArray)): New constructors.
+	(NDArray::operator !): New function.
+	Provide NDS_CMP_OPS, NDS_BOOL_OPS, SND_CMP_OPS, SND_BOOL_OPS,
+	NDND_CMP_OPS, NDND_BOOL_OPS.
+
+	* CNDArray.cc (ComplexNDArray::ComplexNDArray (const NDArray&),
+	ComplexNDArray::ComplexNDArray (const boolNDArray&),
+	ComplexNDArray::ComplexNDArray (const charNDArray&)):
+	New constructors.
+	(ComplexNDArray::operator !): New function.
+	Provide NDS_CMP_OPS, NDS_BOOL_OPS, SND_CMP_OPS, SND_BOOL_OPS,
+	NDND_CMP_OPS, NDND_BOOL_OPS.
+
+	* ArrayN.h (resize (const dim_vector&)): Fix typo.
+
+	* boolNDArray.cc (boolNDArray::operator !): New function.
+	Provide NDND_CMP_OPS.
+
+	* MArrayN.cc (operator +=, operator -=): New functions.
+	Provide product and quotient functions.
+
+	* MArray-misc.cc (gripe_nonconformant (const char *, dim_vector&,
+	dim_vector&)): New function.
+
+	* dim-vector.h (dim_vector::str, dim_vector::all_zero,
+	operator ==, operator !=): New functions.
+	* ArrayN.cc (operator <<): Use dim_vector::str here.
+
+	* Array.cc (Array<T>::resize_no_fill, Array<T>::resize_and_fill):
+	No need to save old dimensions.
+
+	* oct-rand.cc (MAKE_RAND_ND_ARRAY): New macro.
+	(octave_rand::nd_array): New function.
+	* oct-rand.h (octave_rand::nd_array): Provide decl.
+
+	* mx-op-defs.h (NDCMP_OP_DECL, NDBOOL_OP_DECL, NDS_BIN_OP_DECLS,
+	NDS_BIN_OP, NDS_BIN_OPS, NDS_CMP_OP_DECLS, NDS_CMP_OP,
+	NDS_CMP_OPS, NDS_BOOL_OP_DECLS, NDS_BOOL_OP, NDS_BOOL_OPS,
+	NDS_OP_DECLS, SND_BIN_OP_DECLS, SND_BIN_OP, SND_BIN_OPS,
+	SND_CMP_OP_DECLS, SND_CMP_OP, SND_CMP_OPS, SND_BOOL_OP_DECLS,
+	SND_BOOL_OP, SND_BOOL_OPS, SND_OP_DECLS, NDND_BIN_OP_DECLS,
+	NDND_BIN_OP, NDND_BIN_OPS, NDND_CMP_OP_DECLS, NDND_CMP_OP,
+	NDND_CMP_OPS, NDND_BOOL_OP_DECLS, NDND_BOOL_OP, NDND_BOOL_OPS,
+	NDND_OP_DECLS): New macros.
+	* mx-cm-m.h, mx-cm-s.h, mx-cs-m.h, mx-m-cm.h, mx-m-cs.h,
+	mx-s-cm.h, mx-cm-m.cc, mx-cm-s.cc, mx-cs-m.cc, mx-m-cm.cc,
+	mx-m-cs.cc, mx-s-cm.cc: Use them.
+
+	* mx-defs.h (class NDArray, class ComplexNDArray, class
+	boolNDArray, class charNDArray): New forward decls.
+
+2003-10-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (assign2): No error (but don't do anything either) for
+	expressions like x([],j) = scalar.
+
+2003-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (assignN): Allow lhs(:) = scalar.
+
+	* CNDArray.cc (ComplexNDArray::increment_index): New function.
+	* dNDArray.cc (NDArray::increment_index): Likewise.
+	* boolNDArray.cc (boolNDArray::increment_index): Likewise.
+	* chNDArray.cc (charNDArray::increment_index): Likewise.
+
+	* dim-vector.h (rows, cols): Delete unused data members.
+
+	* Array.cc (Array<T>::get_size): Fix thinko.
+
+2003-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::squeeze): New function.
+	* CNDArray.h (ComplexNDArray::squeeze): Likewise.
+	* dNDArray.h (NDArray::squeeze): Likewise.
+	* boolNDArray.h (boolNDArray::squeeze): Likewise.
+	* chNDArray.h (charNDArray::squeeze): Likewise.
+
+2003-10-06  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* Array.cc (ArrayN<T>::indexN): New definition.
+	* Array.h (Array<T>::indexN): Provide decl.
+	* Array.cc (ArrayN<T>::index (idx_vector&, int, const T&):
+	Call indexN if more than 2 indices.
+	(ArrayN<T>::index (Array<idx_vector>&, int, const T&)):
+	Make it (mostly) work.
+	* ArrayN-inline.h (number_of_elements, get_ra_idx, short_freeze):
+	New functions.
+
+2003-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.cc (do_readline): Pass eof to octave_fgetl.
+	* lo-utils.cc (octave_fgets, octave_fgetl): New overloaded
+	versions with eof arg.
+
+2003-09-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (dimensions): Now public.
+	template <class LT, class RT>
+	(assign (Array<LT>&, const Array<RT>&, const LT&),
+	assign1 (Array<LT>&, const Array<RT>&, const LT&),
+	assign2 (Array<LT>&, const Array<RT>&, const LT&),
+	assignN (Array<LT>&, const Array<RT>&, const LT&),
+	resize_no_fill (int),
+	resize_no_fill (int, int),
+	resize_no_fill (int, int, int),
+	resize_no_fill (const dim_vector&),
+	resize_and_fill (int, const T&),
+	resize_and_fill (int, int, const T&),
+	resize_and_fill (int, int, int, const T&),
+	resize_and_fill (const dim_vector&, const T&)): Now public.
+
+	* Array.cc: Include <climits>.
+
+2003-09-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc: Merge Array-idx.h.
+	* Array-idx.h: Delete.
+
+	* chNDArray.h, chNDArray.cc, boolNDArray.h, boolNDArray.cc: New files.
+
+	* Array.h, Array-idx.h, Array.cc: Fold all N-d functionality here.
+	Turn inheritance hierarchy upside down (2-d and 3-d arrays are now
+	just special cases of the general purpose N-d Array object).
+
+	* dim-vector.h: New file.  Use dim_vector objects instead of
+	ints or Array<int> objects to represent the size of Array
+	objects.
+
+	* MArray-defs.h (INSTANTIATE_MARRAYN_FRIENDS): New macro.
+
+	* Array2-idx.h, Array3-idx.h, Array2.cc, Array3.cc: Delete.
+
+	* mx-base.h: Include NDArray header files.
+
+	* MArray-C.cc, MArray-d.cc: Also instantiate ArrayN objects.
+
+	* Array-C.cc, Array-b.cc, Array-ch.cc, Array-d.cc, Array-i.cc,
+	Array-s.cc: Also instantiate ArrayN objects.
+	Don't instantiate assign funcitons for Array2 objects.
+
+	* CDiagMatrix.cc (ComplexDiagMatrix::diag): Signal error with
+	liboctave_error_handler, not cerr.
+	* CMatrix.cc (ComplexMatrix::diag): Likewise.
+	* dDiagMatrix.cc (DiagMatrix::diag): Likewise.
+	* dMatrix.cc (Matrix::diag): Likewise.
+
+	* Array-flags.cc, Array.cc, Array.h, Array2.h, Array3.h, ArrayN.h:
+	Omit checks for HEAVYWEIGHT_INDEXING.
+
+2003-09-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-base.h: Include CNDarray.h.  Include dNDArray.h, not NDArray.h.
+
+	* CNDARray.h, CNDArray.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* dNDArray.h: Rename from NDArray.h.
+	* dNDArray.cc: Rename from NDArray.cc.
+	* Makefile.in: Rename them here too.
+
+2003-09-10  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* mx-base.h: Include NDArray.h, not ArrayN.h.
+
+	* MArrayN.cc, MArrayN.h, NDArray.h, NDArray.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2003-09-09  David Bateman  <dbateman at free.fr>
+
+	* lo-specfun.cc (zbesj, zbesy, zbesi, zbesk, zbesh1, zbesh2, airy,
+	biry): Always request scaled results from AMOS functions and
+	perform reverse scaling on results if scaled result not requested
+	by user.
+
+2003-09-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+ 
+ 	* lo-specfun.cc (xlgamma): Require nonnegative argument.
+
+2003-09-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-d.cc: Instantiate assign functions.
+
+2003-09-09  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ArrayN-idx.h (vector_equivalent, equal_arrays): New functions.
+	(get_elt_idx): Index ra_idx correctly.
+
+	* ArrayN-inline.h (index_in_bounds): Index is also condidered in
+	bounds if it is exactly on the bound.
+
+	* ArrayN.cc (ArrayN<T>::maybe_delete_dims): New function.
+	* ArrayN.h: Provide decl.
+
+	* ArrayN.h (ArrayN<T>::ArrayN<T> (const Matrix&)): New constructor.
+
+	* idx-vector.h (idx_vector::orig_dims): New member variable.
+	(idx_vector::idx_vector_rep::orig_dimensions): New function.
+	(idx_vector::orig_dimensions): New function.
+
+2003-09-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc (xlgamma): Require nonnegative argument.
+
+2003-09-04  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ArrayN-idx.h (maybe_delete_elements): Implement function.
+	(is_in, how_many_lgt, all_ones): New functions.
+
+2003-09-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (MATRIX_INC): Add ArrayN-inlines.h to the list.
+
+2003-09-03  Petter Risholm  <risholm at stud.ntnu.no>
+	
+	* ArrayN-inline.h: New file.
+	(index_in_bounds, increment_index): Move here.
+	* ArrayN.cc: From here.
+
+	* ArrayN.h (maybe_delete_elements): New arg, resize_fill_value.
+	* ArrayN-idx.h (assign): New function.
+
+2003-08-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc (zbesj, zbesy, zbesi, zbesk, airy, biry):
+	Also zero imaginary part of result if real part of input value is
+	zero.
+
+2003-07-30  Heine Kolltveit  <kolltvei at idi.ntnu.no>
+
+	* mx-base.h: Include ArrayN.h.
+
+2003-30-07  Heine Kolltveit  <kolltvei at idi.ntnu.no>
+
+        * ArrayN.cc (operator <<): Corrected output.
+
+2003-07-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ArrayN.cc (increment_index): New arg, start_dimension.
+
+2003-07-29  Heine Kolltveit  <kolltvei at idi.ntnu.no>
+
+	* ArrayN.cc (operator <<): Improve output readability.
+
+2003-07-29  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ArrayN.cc (ArrayN<T>::resize (const Array<int>&, const T&)):
+	* ArrayN.cc (ArrayN<T>::resize (const Array<int>&)):
+	Initialize old_len before changing size.
+
+2003-07-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-lib): Use $(INSTALL), not
+	$(INSTALL_PROGRAM) for $(SHLLIB) files.
+
+2003-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (xmin, xmax): Handle NaN in a Matlab-compatible
+	way.  Handle NA in an R-compatible way.
+
+	* lo-cieee.c (lo_ieee_is_NaN_or_NA): Also check for lo_ieee_is_NA.
+	(lo_ieee_is_NA): Don't call isnan unless HAVE_ISNAN is defined.
+
+	* lo-mappers.h (octave_is_NA (const Complex&)): Provide decl.
+	(octave_is_NaN_or_NA (const Complex&)): Likewise.
+
+	* dMatrix.cc (Matrix::row_min, Matrix::row_max,
+	Matrix::column_min, Matrix::column_max): Ignore NaNs.
+	* CMatrix.cc (ComplexMatrix::row_min, ComplexMatrix::row_max,
+	ComplexMatrix::column_min, ComplexMatrix::column_max): Likewise.
+
+2003-07-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign (Array2<LT>&, const Array2<RT>&, const LT&)):
+	Pass true for resize_ok arg to freeze.
+	* Array-idx.h (assign (Array<LT>&, const Array<RT>&, const LT&)): 
+	Likewise.
+
+	* idx-vector.cc (IDX_VEC_REP::freeze): New arg, warn_resize;
+	resize_ok arg is now bool.
+	* idx-vector.h (idx_vector::freeze): Likewise.
+
+	* Array-flags.cc, Array-flags.h (liboctave_wrore_flag):
+	Rename from liboctave_rre_flag.  Now bool.
+	(liboctave_wfi_flag): Now bool.
+
+	* Array2-idx.h (MAYBE_RESIZE_LHS): Don't check liboctave_rre_flag.
+
+2003-07-11  Russell Standish  <R.Standish at unsw.edu.au>
+
+	* Array.h (resize_fill_value): Now a top-level template function.
+	Accept object as argument.  Change all uses.
+
+2003-07-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-flags.cc, Array-flags.h (liboctave_pcv_flag): Delete.
+
+	* Array2-idx.h (Array2<T>::index): Use liboctave_wfi_flag, not
+	liboctave_dfi_flag.
+	(assign): Likewise.  For indexed assignments like X(I) = RHS with
+	X undefined or empty, always create a row vector.
+
+	* Array-flags.cc (liboctave_wfi_flag): Rename from liboctave_dfi_flag.
+	* Array-flags.h (liboctave_wfi_flag): Ditto.
+
+2003-06-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&, int, const T&)):
+	Magic colon indexing always produces an object with one column.
+
+2003-06-21  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* kpse-xfns.h (NAME_BEGINS_WITH_DEVICE): Arg is std::string, not char*.
+
+	* lo-ieee.h (signbit): Eliminate redundant extern "C" decl.
+
+2003-06-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (any_element_is_negative): If new optional arg
+	neg_zero is true, also return true for negative zero.
+
+2003-06-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.cc (DASSL::do_integrate): Set liw to 21 + n, not 20 + n.
+	Handle step limit.
+	* DASSL-opts.in: New option for step limit.
+
+2003-06-16  Per Persson  <persquare at mac.com>
+
+	* oct-shlib.cc: Include mach-o/dyld.h, not Mach-O/dyld.h.
+
+2003-06-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASRT.cc (DASRT::integrate): Set liw to 21 + n, not 20 + n.
+	Store step limit in iwork(20), not iwork(18).
+
+2003-05-16  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* oct-rand.cc: Use liboctave's clock layer instead of the system clock.
+
+2003-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Handle DESTDIR.
+
+	* kpse.cc (kpse_path_iterator::next): Skip consecutive colons here.
+	(kpse_path_iterator::set_end): Don't miss last element when not
+	followed by a colon.
+
+2003-05-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-idx.h (Array<T>::index): Fix off-by-one error.
+
+2003-05-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* kpse.cc (kpse_absolute_p): Fix typo in translation.
+	(find_first_of): Also do an absolute search on each
+	name before looking in the path.
+
+2003-05-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* kpse.cc (dir_list_add): Ensure that directory ends with a
+	directory separator.
+
+2003-04-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.cc: Include kpse.cc here.
+
+	* kpse.cc: All functions are now static.  Massive surgery to
+	condense kpathsearch library to a single file of just the
+	essentials for Octave and convert to using C++ strings (no more
+	calls to malloc, very few calls to new, so there should be much
+	less potential for introducing memory leaks now).
+
+	* Makefile.in (EXTRAS): Move kpse.cc here from
+	LIBOCT_PATHSEARCH_CXX_SOURCES.
+
+	* kpse.h, kpse-config.h: Delete.
+	* Makefile.in (INCLUDES): Delete them from the list.
+
+2003-04-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* str-vec.cc (string_vector::append (const std::string&),
+	string_vector::append (const string_vector&)): New methods.
+
+2003-04-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* kpse.cc, kpse.h: Replace fn_type with std::string.
+
+	* lo-ieee.h (lo_ieee_signbit): Provide signbit decl for MinGW systems.
+
+	* kpse.cc (xclosedir): Don't define or declare for Windows.
+	(READABLE): Now a static function to avoid warnings from MinGW
+	compiler.	
+
+2003-04-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* kpse.cc: Move most functions from kpse-xfns.c here and make
+	static.  Include most of kpse-xfns.h directly, removing
+	unnecessary bits.
+
+	* dMatrix.cc (Matrix::pseudo_inverse): Now const.
+	* CMatrix.cc (ComplexMatrix::pseudo_inverse): Likewise.
+
+2003-04-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* getopt.c, getopt1.c, getopt.h: Move here from kpathsea.
+	* Makefile.in: Add them to the appropriates lists.
+
+	* oct-getopt.c: Include "getopt.h", not <kpathsea/getopt.h>.
+
+	* Makefile.in (liboctave.$(LIBEXT), liboctave.$(SHLEXT)): Adjust
+	for new locations of kpathsea objects.
+	Delete kpathsea targets.
+
+	* pathsearch.cc (dir_path::set_program_name): Delete.
+
+	* kpse.cc: New file.
+	* Makefile.in (LIBOCT_PATHSEARCH_CXX_SOURCES): Add it to the list.
+
+	* kpse.c: New file.
+	* Makefile.in (LIBOCT_PATHSEARCH_C_SOURCES): Add it to the list.
+
+	* kpse.h, kpse-config.h, kpse-xfns.h: New files.
+	* Makefile.in (INCLUDES): Add them to the list.
+
+	* oct-kpse.h: Delete.
+	* Makefile.in (INCLUDES): Delete it from the list.
+
+2003-04-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleSVD.h (SVD::SVD, SVD::operator =): Also copy type_computed.
+	* CmplxSVD.h (ComplexSVD::ComplexSVD, ComplexSVD::operator =):
+	Likewise.
+	From Quentin H. Spencer <qspencer at ieee.org>.
+
+2003-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-getopt.c: Include <kpathsea/getopt.h>, not "getopt.h".
+
+2003-02-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-alloc.h (DECLARE_OCTAVE_ALLOCATOR): Handle systems with or
+	without placement delete.
+
+	* CMatrix.cc (ComplexMatrix::all_elements_are_real): Don't lose -0
+	imaginary parts.
+
+	* lo-ieee.h (lo_ieee_signbit): New macro.
+
+2003-02-18  David Bateman  <dbateman at free.fr>
+
+	* dMatrix.cc (Matrix::inverse, Matrix::determinant, Matrix::solve):
+	Use Lapack instead of Linpack.
+	* CMatrix.cc (ComplexMatrix::inverse, ComplexMatrix::determinant,
+	ComplexMatrix::solve): Likewise.
+
+	* dMatrix.cc (Matrix::determinant, Matrix::inverse): New arg,
+	calc_cond.  If 0, skip condition number calculation.
+	* CMatrix.cc (ComplexMatrix::determinant, ComplexMatrix::inverse):
+	Likewise.
+
+	* CmplxLU.cc (ComplexLU::ComplexLU): Allow non-square matrices.
+	* dbleLU.cc (LU::LU): Likewise.
+	* base-lu.cc (base_lu::L), base_lu::U, base_lu::P): Likewise.
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+  
+  	* octave.test/arith/prod-4.m, octave.test/arith/sum-4.m:
+
+2003-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index): Fix thinko.
+	Additional compatibility fix.
+
+2003-02-13  Arno Klaassen  <arno at scito.com>
+ 
+        * Array2-idx.h, Array2.cc, Array2.h, Array3.cc, Array3.h,
+	ArrayN.cc, ArrayN.h, DiagArray2.cc, DiagArray2.h, MDiagArray2.h:
+	Sprinkle with Array<T>:: as necessary for gcc 3.4.
+ 
+2003-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&, int, const T&)):
+	Compatibility fix.
+
+2003-02-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CColVector.cc (ComplexColumnVector::extract_n): New function.
+	* CRowVector.cc (ComplexRowVector::extract_n): Likewise.
+	* CMatrix.cc (ComplexMatrix::extract_n): Likewise.
+	* dColVector.cc (ColumnVector::extract_n): Likewise.
+	* dRowVector.cc (RowVector::extract_n): Likewise.
+	* dMatrix.cc (Matrix::extract_n): Likewise.
+
+	* CColVector.cc (ComplexColumnVector::insert): Improve efficiency
+	with make_unique and xelem.
+	* CRowVector.cc (ComplexRowVector::insert): Likewise.
+	* CMatrix.cc (ComplexMatrix::insert, ComplexMatrix::fill,
+	ComplexMatrix::extract, ComplexMatrix::row,
+	ComplexMatrix::column): Likewise.
+	* dColVector.cc (ColumnVector::insert): Likewise.
+	* dRowVector.cc (RowVector::insert): Likewise.
+	* dMatrix.cc (Matrix::insert, Matrix::fill, Matrix::extract,
+	Matrix::row, Matrix::column): Likewise.
+
+2003-01-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (imag (double)): Return 0.0 for all args, even NaN.
+
+2003-01-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc, dMatrix.cc: Move min and max functions here, from
+	src/DLD-FUNCTIONS/minmax.cc, and make them extern.
+	* CMatrix.h, dMatrix.h: Provide decls.
+
+2003-01-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rand.h, oct-rand.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2003-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index): Fix off-by-one error.
+
+2003-01-16  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* oct-syscalls.cc: Include signal.h.
+
+2003-01-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-syscalls.cc (octave_syscalls::kill): New function.
+	* oct-syscalls.h: Provide decl.
+	
+
+2003-01-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::read): Set size and return immediately if
+	there is nothing to read.
+
+2003-01-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-cutils.c: Define _XOPEN_SOURCE.
+
+2003-01-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* getopt.h: Update to version from kpathsearch, so we will install
+	the version that we are using.
+
+	* getopt.c, getopt1.c: Delete.
+	(INCLUDES): Delete them from the list.  We'll get these files from
+	kpathsearch.
+
+	* Makefile.in (liboctave.$(LIBEXT)): Link directly to
+	../kpathsea/STATIC/*.o.
+	(liboctave.$(SHLEXT)): Link directly to	../kpathsea/SHARED/*.o.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (read_int, write_int): Avoid warnings about
+	unreachable code.
+
+	* oct-alloc.h (DECLARE_OCTAVE_ALLOCATOR): Define operator delete
+	to correspond to placement new operator.
+
+	* dbleDET.cc (DET::value_will_overflow): We want det[1], not det[2].
+	(DET::value_will_underflow): Likewise.
+	* CmplxDET.cc (ComplexDET::value_will_overflow): Likewise.
+	(ComplexDET::value_will_underflow): Likewise.
+
+	* Makefile.in (distclean): Also remove stamp-prereq.
+
+	* Array2-idx.h (Array2<T>::assign): If assignment conforms but the
+	RHS and index are empty matrices, don't do anything.
+
+2002-12-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.cc (make_retval, free_c_array, make_c_names,
+	delete_c_names): New helper functions.
+	(dir_path::find_first_of): New function.
+	(dir_path::find_all_first_of): Likewise.
+	* pathsearch.h: Provide decls.
+
+	* oct-kpse.c (octave_kpse_path_find_first_of): New function.
+	(octave_kpse_all_path_find_first_of): Likewise.
+	* oct-kpse.h: Provide decls.
+
+2002-12-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ODESSA.cc (ODESSA::integrate): Handle maxord.
+	* ODESSA-opts.in: Likewise.
+
+	* LSODE.cc (ODESSA::integrate): Handle maxord.
+	* LSODE-opts.in: Likewise.
+
+2002-12-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ODESSA.cc (ODESSA::ODESSA): Initialize "initialized" data member
+	in all constructors.
+
+	* Makefile.in (liboctave.$(SHLEXT)): Include $(LIBKPATHSEA) here.
+	(LINK_DEPS): Not here.
+
+2002-12-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* str-vec.cc (string_vector::compare): New static member function.
+	* str-vec.h: Provide decl.
+	(string_vector::sort): Use it.
+	(str_vec_compare): Delete static function.
+
+	* oct-alloc.h (DECLARE_OCTAVE_ALLOCATOR): Also declare and define
+	a placement operator new.
+
+2002-12-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Matrix.h: Include mx-ops.h too.
+	* mx-ops.h: New file.
+
+2002-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASRT.cc, DASRT.h, Array.cc, ArrayN.h, Array.h, Array2.cc,
+	Array2.h, Array3.cc, Array3.h, Bounds.cc, Bounds.h, CRowVector.h,
+	CDiagMatrix.cc, CDiagMatrix.h, CMatrix.cc, CMatrix.h,
+	CRowVector.cc, CColVector.h, ChangeLog, CmplxAEPBAL.cc,
+	CmplxAEPBAL.h, CmplxCHOL.cc, CmplxCHOL.h, CmplxDET.cc, CmplxDET.h,
+	CmplxHESS.cc, CmplxHESS.h, CmplxLU.cc, CmplxLU.h, CmplxQR.cc,
+	CmplxQR.h, CmplxQRP.cc, ArrayN.cc, CmplxQRP.h, CmplxSCHUR.cc,
+	CmplxSCHUR.h, CmplxSVD.cc, CmplxSVD.h, CollocWt.cc, dMatrix.cc,
+	CollocWt.h, EIG.h, DASSL.cc, FEGrid.h, DASSL.h, DiagArray2.cc,
+	DiagArray2.h, EIG.cc, FEGrid.cc, LSODE.cc, LPsolve.cc, LPsolve.h,
+	LSODE.h, LinConst.cc, LinConst.h, MArray.h, MArray.cc, MArray2.cc,
+	MArray2.h, MDiagArray2.cc, MDiagArray2.h, Range.cc, NLConst.h,
+	NLEqn.cc, Range.h, NLEqn.h, Quad.cc, dbleQR.h, Quad.h, base-lu.cc,
+	base-lu.h, boolMatrix.cc, boolMatrix.h, dColVector.cc,
+	dColVector.h, dDiagMatrix.cc, dDiagMatrix.h, dMatrix.h,
+	dRowVector.cc, dRowVector.h, dbleAEPBAL.cc, dbleAEPBAL.h,
+	dbleCHOL.cc, dbleCHOL.h, dbleDET.cc, dbleDET.h, dbleHESS.cc,
+	dbleHESS.h, dbleLU.cc, dbleLU.h, dbleQR.cc, dbleQRP.cc, dbleQRP.h,
+	dbleSCHUR.cc, dbleSCHUR.h, dbleSVD.cc, dbleSVD.h, idx-vector.cc,
+	idx-vector.h, oct-alloc.cc, CColVector.cc, DASPK.h, DASPK.cc,
+	ODESSA.h, ODES.h, ODESSA.cc, ODES.cc, chMatrix.h, chMatrix.cc:
+	Use "defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)" instead of 
+	"! defined (NO_PRAGMA_INTERFACE_IMPLEMENTATION)".
+
+2002-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-shlib.cc (octave_dlopen_shlib::open): Use RTLD_GLOBAL too.
+	From Remy Bruno <remy.bruno at libertysurf.fr>
+
+2002-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc: Use F77_FUNC instead of F77_XFCN for calls to
+	fortran code that should run fast enough that it is not worth all
+	the setup costs of F77_XFCN.
+
+	* Quad.cc (user_function): Surround body of function with
+	BEGIN_INTERRUPT_WITH_EXCEPTIONS, END_INTERRUPT_WITH_EXCEPTIONS.
+	* ODESSA.cc (odessa_f, odessa_j, odessa_b): Likewise.
+	* NLEqn.cc (hybrd1_fcn, hybrj1_fcn): Likewise.
+	* LSODE.cc (lsode_f, lsode_j): Likewise.
+	* DASSL.cc (ddassl_f, ddassl_j): Likewise.
+	* DASRT.cc (ddasrt_f, ddasrt_j, ddasrt_g): Likewise.
+	* DASPK.cc (ddaspk_f, ddaspk_psol, ddaspk_j): Likewise.
+
+2002-11-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (octave_ieee_init): Check defined (__osf__) instead
+	of ! defined (linux).
+
+2002-11-09  Per Persson  <persquare at mac.com>
+
+	* oct-shlib.cc (octave_dyld_shlib): New class.
+	(make_shlib): Instantiate octave_dyld_shlib.
+
+2002-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc, dMatrix.cc: Sprinkle with OCTAVE_QUIT.
+
+	* ODESSA.cc (odessa_f, odessa_j, odessa_b): Abort on error.
+
+	* Array.h: Include <cstddef> here.
+
+2002-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASPK.cc (DASPK::do_integrate): Resize rwork and iwork before
+	using them.  Accept inequality contraint option of 0.  Assign
+	pabs_tol and prel_tol before calling DASPK.  Don't redeclare
+	abs_tol and rel_tol.
+
+	* cmd-edit.h (command_editor::filename_completion_desired): New
+	static function.
+	(command_editor::do_filename_completion_desired): New virtual function.
+	* oct-rl-edit.c (octave_rl_filename_completion_desired): New function.
+	* oct-rl-edit.h: Provide decl.
+
+	* Array2.cc (Array2<T>::get_size): #define MALLOC_OVERHEAD to
+	avoid OS X linker bug.
+	* ArrayN.cc (ArrayN<T>::get_size): Likewise.
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ODESFunc.h (ODESFunc::ODES_fsub, ODESFunc::ODES_bsub,
+	ODESFunc::ODES_jsub): Reorder args for consistency with other
+	solvers.
+	* ODESSA.cc: Fix all callers.
+
+	* mx-inlines.cc (MX_BASE_REDUCTION_OP): Also return scalar
+	MT_RESULT if nr == 1 && nc == 0 && dim == -1 (i.e.,
+	sum(zeros(1,0)) returns 0, not [](1x0)).
+
+2002-10-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (LINK_DEPS): Include $(FLIBS) here too.
+
+2002-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASRT.cc (DASRT::integrate): Fix computation of lrw
+	(ddasrt_f): Combine loops.
+
+	* NLEqn.cc (NLEqn::solve): Return current estimate of solution
+	instead of empty vector if user termninates iteration.
+
+2002-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-utils.cc (read_inf_nan_na, octave_read_double,
+	octave_read_complex, octave_write_double, octave_write_complex):
+	New functions.
+	* CMatrix.cc (operator << (std::ostream&, const ComplexMatrix&)):
+	Use octave_write_complex.
+	(operator >> (std::istream&, const ComplexMatrix&)):
+	Use octave_read_complex.
+	* dMatrix.cc (operator << (std::ostream&, double)):
+	Use octave_write_double.
+	(operator >> (std::istream&, double)): Use octave_read_double.
+
+2002-10-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-kpse.c (octave_kpse_clear_dir_cache): Delete.
+	* oct-kpse.h: Delete decl.
+	* pathsearch.cc (dir_path::init): Delete unnecessary call to
+	::octave_kpse_clear_dir_cache.
+
+2002-10-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-sstream.h: Undef HAVE_SSTREAM if using a version of g++
+	earlier than 3.0.
+
+	* Makefile.in (LINK_DEPS): Include $(LIBKPATHSEA) here.
+	(liboctave.$(SHLEXT)): Not here.
+
+2002-10-17  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* oct-shlib.cc (octave_w32_shlib): New class to support Windows.
+
+2002-10-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-lib): Don't bother with versions for
+	$(SHLBIN) files.
+
+2002-10-16  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in (LIB_DEPS): Include $(LIBS).
+
+2002-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-cieee.c: Move everything but lo_ieee_init here.
+	(lo_ieee_Inf_value, lo_ieee_NA_value, lo_ieee_NaN_value):
+	New functions.
+
+	* Makefile.in (install): No need to use cd to create links.
+	(LINK_DEPS): Include $(LIBOCTAVE_LFLAGS) before list of libraries.
+
+2002-10-14  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in: Merge liboctave with liboct-readline and
+	liboct-pathsearch.
+	Use link dependencies for shared libs if INCLUDE_LINK_DEPS.
+	(libraries): Depend on versioned library.
+	(liboctave.$(SHLEXT), liboctave.$(SHLEXT_VER)): Reverse actions --
+	build unversioned library, symbolic link adds version info.
+	(install, uninstall): Handle link and load forms of the library
+	separately.
+
+2002-10-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc: Use OCTAVE_USE_WINDOWS_API instead of __WIN32__ and
+	__CYGWIN__.
+
+	* file-ops.cc (file_ops::dir_sep_char, file_ops::dir_sep_str,
+	file_ops::dir_sep_chars): New static functions to replace
+	OCTAVE_DIR_SEP_CHAR, OCTAVE_DIR_SEP_STR, OCTAVE_DIR_SEP_CHARS.
+
+	* oct-env.cc (octave_env::do_set_program_name):
+	Use file_ops::dir_sep_chars instead of OCTAVE_DIR_SEP_CHARS.
+	(octave_env::do_base_pathname): Likewise.
+	(octave_env::do_make_absolute): Likewise.
+
+	* oct-env.cc (octave_env::do_make_absolute):
+	Use file_ops::dir_sep_str instead of OCTAVE_DIR_SEP_STR.
+	(octave_env::do_get_home_directory): Likewise.
+
+	* file-ops.cc (is_dir_sep): Use dir_sep_chars instead of embedding
+	that information here too.
+	(tilde_find_suffix, isolate_tilde_prefix, tilde_expand_word):
+	Use file_ops::dir_sep_char instead of OCTAVE_DIR_SEP_CHAR.
+
+	* file-ops.h: Use OCTAVE_HAVE_WINDOWS_FILESYSTEM and
+	OCTAVE_HAVE_POSIX_FILESYSTEM instead of __WIN32__ and __CYGWIN__.
+
+2002-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-env.h (octave_env::current_directory): Now mutable.
+	(octave_env:do_getcwd): Now const.
+
+	* file-ops.h, file-ops.cc (file_ops::is_dir_sep): New function.
+	(OCTAVE_DIR_SEP_CHAR, OCTAVE_DIR_SEP_STR, OCTAVE_DIR_SEP_CHARS,
+	OCTAVE_CURRENT_DIR_STR): New macros.
+	* oct-env.cc (is_dir_sep): Delete.
+	(octave_env::do_base_pathname): Look for OCTAVE_DIR_SEP_CHARS, not '/'.
+	(octave_env::do_set_program_name): Likewise.
+	(octave_env::do_polite_directory_format): Use file_ops::is_dir_sep
+	instead of checking for '/'.
+	(octave_env::pathname_backup): Likewise.
+	(octave_env::do_absolute_pathname): Likewise.
+	(octave_env::do_make_absolute): Likewise.
+	If dot_path is empty, use getcwd to set current_dir.
+	(octave_env::do_get_home_directory): Use OCTAVE_DIR_SEP_STR
+	instead of "/".
+
+2002-10-07  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* lo-cutils.c: On non-Posix Windows systems, include winsock.h.
+
+2002-10-07  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* oct-env.cc (octave_env::do_absolute_pathname): Recognize
+	absolute path names under MinGW as well.
+
+2002-10-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-env.cc: Include <cctype> too.
+
+2002-10-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-env.cc (octave_env::do_absolute_pathname): Handle Windows
+	filenames.
+	(octave_env::do_make_absolute): Check for absolute name with
+	do_absolute_path.
+	(octave_env::do_chdir): Likewise.
+	(is_dir_sep): New function.
+
+2002-10-03  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* oct-time.cc (octave_time::stamp): Better resolution for Windows
+	systems.
+
+2002-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::read): Clean up error handling logic.
+
+2002-09-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc (file_ops::mkdir): Handle one-arg mkdir here.
+
+	* lo-specfun.cc (acosh): Call xdacosh, not dacosh.
+
+2002-09-27  Per Persson  <persquare at mac.com>
+
+	* oct-group.cc (octave_group::octave_group): Dont' forget to set
+	gr_gid too.
+
+2002-09-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (xisnan, xfinite, xisinf): Simply forward to
+	lo_ieee_* functions.
+	* Makefile.in (LIBOCTAVE_C_SOURCES): Add lo-cieee.c to the list.
+	* lo-ieee.cc (lo_ieee_double): Rename from ieee_double.
+	(LO_IEEE_NA_HW, LO_IEEE_NA_LW): Rename from NA_HW and NA_LW.
+	* lo-cieee.c: New file.
+	[SCO] (isinf, isnan): Move here from lo-ieee.cc.
+	* lo-ieee.h: Now all extern "C".
+	(lo_ieee_isnan, lo_ieee_finite, lo_ieee_isinf): Move here from
+	lo-mappers.cc and rename from xisnan, xfinite, xisinf.
+
+	* lo-ieee.cc (lo_ieee_hw, lo_ieee_low): Rename from hw and lw.
+	Now extern.
+
+2002-09-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc, Array.h, Array2.cc, Array2.h, Array3.cc, Array3.h,
+	ArrayN.cc, ArrayN.h, Bounds.cc, Bounds.h, CColVector.cc,
+	CColVector.h, CDiagMatrix.cc, CDiagMatrix.h, CMatrix.cc,
+	CMatrix.h, CRowVector.cc, CRowVector.h, CmplxAEPBAL.cc,
+	CmplxAEPBAL.h, CmplxCHOL.cc, CmplxCHOL.h, CmplxDET.cc, CmplxDET.h,
+	CmplxHESS.cc, CmplxHESS.h, CmplxLU.cc, CmplxLU.h, CmplxQR.cc,
+	CmplxQR.h, CmplxQRP.cc, CmplxQRP.h, CmplxSCHUR.cc, CmplxSCHUR.h,
+	CmplxSVD.cc, CmplxSVD.h, CollocWt.cc, CollocWt.h, DAE.cc,
+	DASPK.cc, DASPK.h, DASRT.cc, DASRT.h, DASSL.cc, DASSL.h,
+	DiagArray2.cc, DiagArray2.h, EIG.cc, EIG.h, FEGrid.cc, FEGrid.h,
+	LPsolve.cc, LPsolve.h, LSODE.cc, LSODE.h, LinConst.cc, LinConst.h,
+	MArray.cc, MArray.h, MArray2.cc, MArray2.h, MDiagArray2.cc,
+	MDiagArray2.h, NLConst.h, NLEqn.cc, NLEqn.h, ODES.cc, ODES.h,
+	ODESSA.cc, ODESSA.h, Quad.cc, Quad.h, Range.cc, Range.h,
+	base-lu.cc, base-lu.h, boolMatrix.cc, boolMatrix.h, chMatrix.cc,
+	chMatrix.h, dColVector.cc, dColVector.h, dDiagMatrix.cc,
+	dDiagMatrix.h, dMatrix.cc, dMatrix.h, dRowVector.cc, dRowVector.h,
+	dbleAEPBAL.cc, dbleAEPBAL.h, dbleCHOL.cc, dbleCHOL.h, dbleDET.cc,
+	dbleDET.h, dbleHESS.cc, dbleHESS.h, dbleLU.cc, dbleLU.h,
+	dbleQR.cc, dbleQR.h, dbleQRP.cc, dbleQRP.h, dbleSCHUR.cc,
+	dbleSCHUR.h, dbleSVD.cc, dbleSVD.h, idx-vector.cc, idx-vector.h,
+	oct-alloc.cc:
+	If __GNUG__, use pragma interface/implementation.  Allow this to
+	be turned off by defining NO_PRAGMA_INTERFACE_IMPLEMENTATION.
+
+2002-09-26  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* file-ops.cc (file_ops::readlink): Don't declare buffer if
+	system readlink function is not available.
+
+	* lo-mappers.cc (xerf, xerfc): Delete.
+	* lo-mappers.h (xerf, xerfc): Delete decls.
+
+	* lo-mappers.cc: Remove unused #define M_PI.
+	* lo-specfun.cc: Add #define M_PI if needed.
+
+2002-09-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.cc (do_decode_prompt_string): Cope with possibility
+	that geteuid doesn't exist.
+
+	* LP.h: Rename LP class to octave_LP.
+	LPsolve.h: Change all uses.
+
+	* file-ops.cc, oct-passwd.cc oct-syscalls.cc oct-group.cc: Remove
+	incorrect token-pasting op.
+
+	* statdefs.h [! S_ISLNK]: undef HAVE_LSTAT instead of trying to
+	define lstat.
+
+2002-09-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc, Array.h, Array2.cc, Array2.h, Array3.cc, Array3.h,
+	ArrayN.cc, ArrayN.h, Bounds.cc, Bounds.h, CColVector.cc,
+	CColVector.h, CDiagMatrix.cc, CDiagMatrix.h, CMatrix.cc,
+	CMatrix.h, CRowVector.cc, CRowVector.h, CmplxAEPBAL.cc,
+	CmplxAEPBAL.h, CmplxCHOL.cc, CmplxCHOL.h, CmplxDET.cc, CmplxDET.h,
+	CmplxHESS.cc, CmplxHESS.h, CmplxLU.cc, CmplxLU.h, CmplxQR.cc,
+	CmplxQR.h, CmplxQRP.cc, CmplxQRP.h, CmplxSCHUR.cc, CmplxSCHUR.h,
+	CmplxSVD.cc, CmplxSVD.h, CollocWt.cc, CollocWt.h, DAE.cc,
+	DASPK.cc, DASPK.h, DASRT.cc, DASRT.h, DASSL.cc, DASSL.h,
+	DiagArray2.cc, DiagArray2.h, EIG.cc, EIG.h, FEGrid.cc, FEGrid.h,
+	LPsolve.cc, LPsolve.h, LSODE.cc, LSODE.h, LinConst.cc, LinConst.h,
+	MArray.cc, MArray.h, MArray2.cc, MArray2.h, MDiagArray2.cc,
+	MDiagArray2.h, NLConst.h, NLEqn.cc, NLEqn.h, ODES.cc, ODES.h,
+	ODESSA.cc, ODESSA.h, Quad.cc, Quad.h, Range.cc, Range.h,
+	base-lu.cc, base-lu.h, boolMatrix.cc, boolMatrix.h, chMatrix.cc,
+	chMatrix.h, dColVector.cc, dColVector.h, dDiagMatrix.cc,
+	dDiagMatrix.h, dMatrix.cc, dMatrix.h, dRowVector.cc, dRowVector.h,
+	dbleAEPBAL.cc, dbleAEPBAL.h, dbleCHOL.cc, dbleCHOL.h, dbleDET.cc,
+	dbleDET.h, dbleHESS.cc, dbleHESS.h, dbleLU.cc, dbleLU.h,
+	dbleQR.cc, dbleQR.h, dbleQRP.cc, dbleQRP.h, dbleSCHUR.cc,
+	dbleSCHUR.h, dbleSVD.cc, dbleSVD.h, idx-vector.cc, idx-vector.h,
+	oct-alloc.cc:
+	Use USE_PRAGMA_INTERFACE_IMPLEMENTATION instead of __GNUG__
+	to decide whether to use the interface/implementation pragmas.
+
+2002-09-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES): Add lo-sstream.h to the list.
+
+2002-08-17  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* CmplxCHOL.h, CollocWt.h, cmd-edit.h, oct-shlib.h: Don't use
+	qualified names.
+
+2002-08-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h, Array2-idx.h, DiagArray2.cc, Array2.cc, Array3.cc,
+	ArrayN.cc: Add typename where needed.
+
+	* DASPK.cc: Include lo-sstream.h and use macros instead of using
+	strstream classes directly.
+	* DASRT.cc: Likewise.
+	* DASSL.cc: Likewise.
+	* LSODE.cc: Likewise.
+	* ODESSA.cc: Likewise.
+
+	* cmd-hist.cc: Don't include <strstream>.
+	* oct-shlib.cc: Likewise.
+
+	* lo-sstream.h: New file.
+
+2002-08-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.h (rel_tol, abs_tol, px, pabs_tol, piwork, prwork, itol):
+	New data members.
+	(LSODE::sanity_checked): Delete unused data member.
+
+	* DASPKL.h (initialized, abs_tol, rel_tol, px, pxdot, pabs_tol,
+	prel_tol, pinfo, piwork, prwork): New data members.
+	* DASSL.h (DASSL): Likewise.
+
+	* DASRT.h (DASRT::sanity_checked): Delete unused data member.
+
+	* DASRT.cc (DASRT::integrate (double)): Better handling of
+	initialization, changes in options, etc.
+	* DASPK.cc (DASPK::do_integrate): Likewise.
+	* DASSL.cc (DASSL::do_integrate): Likewise.
+	* LSODE.cc (LSODE::do_integrate): Likewise.
+
+2002-08-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DAEFunc.h (DAEFunc::reset): New data member.
+	* DAERTFunc.h (DAERTFunc::reset): Likewise.
+
+	* base-de.h (base_diff_eqn::set_stop_time): Force restart here.
+	(base_diff_eqn::clear_stop_time): Likewise.
+
+	* DASSL.cc (DASSL::do_integrate (double)): Handle more optoins.
+	* DASPK.cc (DASPK::do_integrate (double)): Likewise.
+
+2002-08-15  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* DASPK-opts.in, DASPK.h: Move include to .in file.
+	* DASRT-opts.in, DASRT.h: Likewise.
+        * DASSL-opts.in, DASSL.h: Likewise.
+	* LSODE-opts.in, LSODE.h: Likewise.
+	* NLEqn-opts.in, NLEqn.h: Likewise.
+	* ODESSA-opts.in, ODESSA.h: Likewise.
+
+2002-08-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.cc (LSODE::error_message): Also return current T on
+	failures when that makes sense.
+	* DASSL.cc (DASSL::error_message): Likewise.
+	* DASRT.cc (DASRT::error_message): Likewise.
+	* DASPK.cc (DASPK::error_message): Likewise.
+	* ODESSA.cc (ODESSA:error_message): Likewise.
+
+	* Makefile.in (liboct-pathsearch.$(SHLEXT_VER)): Link to
+	$(LIBKPATHSEA) here.
+
+2002-08-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (lo_ieee_is_NA): New function.
+	(lo_ieee_is_NaN_or_NA): New function.
+	(octave_NA): New global value.
+	(octave_ieee_init): Initialize it.
+	* lo-mappers.cc (octave_is_NA): New function.
+	(octave_is_NaN_or_NA): New function.
+	(xisnan): Return false if NaN looks like a missing value.
+	(xisnan (const Complex&)): Use xisnan here.
+
+2002-08-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.h (ComplexMatrix::all, ComplexMatrix::any,
+	ComplexMatrix::cumprod, ComplexMatrix::cumsum,
+	ComplexMatrix::prod, ComplexMatrix::sum, ComplexMatrix::sumsq):
+	Default value for dim is -1, not 0.
+	* dMatrix.h (Matrix::all, Matrix::any, Matrix::cumprod,
+	Matrix::cumsum, Matrix::prod, Matrix::sum, Matrix::sumsq): Likewise.
+	* boolMatrix.h (boolMatrix:all, boolMatrix::any): Likewise.
+	* chMatrix.h (charMatrix::all, charMatrix::any): Likewise.
+
+	* mx-inlines.cc (MX_ANY_ALL_OP_ROW_CODE, MX_ANY_ALL_OP_COL_CODE):
+	New macros.
+	(MX_ANY_ALL_OP): Define MX_ANY_ALL_OP using them and
+	MX_BASE_REDUCTION_OP.
+	(MX_CUMULATIVE_OP): Fix spelling.  Change all uses.
+
+2002-08-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.h, chMatrix.cc (charMatrix::any, charMatrix::all):
+	Return boolMatrix, not Matrix.
+
+	* mx-inlines.cc (MX_ANY_ALL_OP, MX_ALL_OP, MX_ANY_OP): New macros.
+	* dMatrix.cc (Matrix::any): Replace guts with MX_ANY_OP.
+	(Matrix::all): Replace guts with MX_ALL_OP.
+	* CMatrix.cc (ComplexMatrix::any): Replace guts with MX_ANY_OP.
+	(ComplexMatrix::all): Replace guts with MX_ALL_OP.
+	* boolMatrix.cc (boolMatrix::any): Replace guts with MX_ANY_OP.
+	(boolMatrix::all): Replace guts with MX_ALL_OP.
+	* chMatrix.cc (charMatrix::any): Replace guts with MX_ANY_OP.
+	(charMatrix::all): Replace guts with MX_ALL_OP.
+
+	* dMatrix.h (Matrix::any): New arg, dim.
+	(Matrix::all): Likewise.
+	* CMatrix.h (ComplexMatrix::any): Likewise.
+	(ComplexMatrix::all): Likewise.
+	* boolMatrix.h (boolMatrix::any): Likewise.
+	(boolMatrix::all): Likewise.
+	* chMatrix.h (charMatrix::any): Likewise.
+	(charMatrix::all): Likewise.
+
+	* Makefile.in: Use $@-t instead of $@.t.
+
+2002-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc (gammainc): New arg, err, for scalar version.
+	Use it in matrix versions to avoid spewing multiple errors.
+	Call xgammainc instead of dgamit.
+
+2002-07-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (ComplexMatrix::ComplexMatrix (const boolMatrix&)): 
+	Get rows and columns right in loop.
+	(ComplexMatrix::ComplexMatrix (const charMatrix&)): Likewise.
+
+2002-07-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASPK.cc (DASPK::do_integrate): Allow array tolerances.
+	* DASRT.cc (DASRT::integrate): Likewise.
+	* DASSL.cc (DASSL::do_integrate): Likewise.
+
+	* Quad.cc: Don't pass tolerances in constructors.
+
+	* DASPK-opts.in, DASRT-opts.in, DASSL-opts.in, LSODE-opts.in,
+	NLeqn-opts.in, ODESSA-opts.in, Quad-opts.in: New files.
+	* DASPK-opts.h, DASRT-opts.h, DASSL-opts.h, LSODE-opts.h,
+	NLeqn-opts.h, ODESSA-opts.h, Quad-opts.h: Generate automatically
+	from corresponding .in files.
+	* LSODE.h, Quad.h: Replace options class definitions with included
+	file.
+	* Makefile.in (OPTS_INC_SRC, OPTS_INC): New variables, new rule to
+	create OPTS_INC files from OPTS_INC_SRC files.	
+	(stamp-prereq): New target.
+	(libraries): Depend on stamp-prereq.
+	Include stamp-prereq along with $(MAKEDEPS).
+
+2002-07-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* base-de.h (base_diff_eqn::istate): New data member.
+	(base_diff_eqn::integration_state): New member function.
+	* LSODE.h, LSODE.cc, ODESSA.h, ODESSA.cc: Delete corresponding
+	data members and functions.
+	* DASPK.h, DASRT.h, DASSL.h: Delete idid data member.
+	* DASPK.cc, DASRT.cc, DASSL.cc: Use istate instead of idid.
+
+2002-07-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* base-de.h (base_diff_eqn::stop_time,
+	base_diff_eqn::stop_time_set, base_diff_eqn::restart,
+	base_diff_eqn::integration_error): New data members.
+	(base_diff_eqn::set_stop_time, base_diff_eqn::clear_stop_time,
+	base_diff_eqn::force_restart, base_diff_eqn::integration_ok,
+	base_diff_eqn::error_message): New member functions.
+	* LSODE.h, LSODE.cc, DASSL.h, DASSL.cc, DASPK.h, DASPK.cc,
+	DASRT.h, DASRT.cc, ODESSA.h, ODESSA.cc: Delete corresponding data
+	members and functions.
+
+	* DASRT.h (DASRT::set_ng, DASRT::get_ng): Delete
+	* DASRT.cc (DASRT::DASRT): Set ng here.
+	(DASRT::integrate): Don't forget to set nn.
+
+	* DAEFunc.h (DAEFunc): Jacobian function now follows format of DASSL.
+	* DASSL.cc (ddassl_j): Make it work.
+	* DASPK.cc (ddaspk_j): Likewise.
+
+	* DAE.cc: Delete.
+
+	* DAERT.h, DAERTFunc.h, DASRT.h, DASRT.cc: New files for DAE
+	solving with root finding.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* base-dae.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* DAE.h (DAE): Derive from base_diff_alg_eqn, not base_diff_eqn.
+
+2002-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ODE.h: Move integrate and do_integrate method declarations and
+	definitions here.
+	* base-de.h: From here.
+
+	* ODES.h, ODES.cc, ODESFunc.h, ODESSA.h, ODESSA.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	(LIBOCTAVE_CXX_SOURCES): 
+
+2002-07-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* NLEqn.cc (NLEqn::error_message): New function.
+	* NLEqn.h (NLEqn::solution_state, NLEqn::solution_ok): New functions.
+
+2002-07-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-utils.cc (octave_fgetl): New function.
+	* cmd-edit.cc (do_readline): Use it instead of octave_fgets.
+
+2002-05-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.cc (LSODE::error_message): New function.
+	* LSODE.h: Provide decl.
+	(LSODE::integration_state): New function.
+	(LSODE::integration_ok): New function.
+
+2002-05-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.cc (LSODE_options::x_integration_method): New data member.
+	(LSODE_options::set_integration_method,
+	LSODE_options::integration_method): New functions.
+
+	* LSODE.h (LSODE_options::x_absolute_tolerance): Now Array<double>.
+	Change all uses.
+	(LSODE_OPTIONS::absolute_tolerance): Return Array<double>, not double.
+	(LSODE_OPTIONS::set_absolute_tolerance (const Array<double>&)):
+	New function.
+
+	* Array.h (Array::fortran_vec): New const version.
+
+2002-05-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.cc (gnu_readline::history_search_backward): New function.
+	(gnu_readline::history_search_forward): Likewise.
+	(gnu_readline::gnu_readline): Use them instead of passing pointers
+	to extern "C" functions to octave_rl_ad_defun.
+
+2002-05-22  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* DASPK.cc (ddaspk_psol): Return value.
+	* oct-rl-edit.c: Use /* ... */ to comment.
+
+2002-05-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.h (DASSL_options::init): Undo previous change.
+	(DASSL_options::set_absolute_tolerance): Likewise.
+	* LSODE.h (LSODE_options::init): Likewise.
+	(LSODE_options::set_absolute_tolerance): Likewise.
+
+	* DASPK.h (DASPK_options::init): Use default absolute tolerance of
+	sqrt(eps), not eps^2.
+	DASPK_options::set_absolute_tolerance): Likewise.
+
+2002-05-17  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* Array.h (Array<T>::resize_fill_value): Return default initialized
+	object.
+
+2002-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-edit.c (OCTAVE_RL_SAVE_STRING): New macro.
+	(octave_rl_set_name, octave_rl_set_basic_quote_characters): Use it.
+	(octave_rl_set_basic_word_break_characters,
+	octave_rl_set_completer_word_break_characters): New functions.
+	* oct-rl-edit.h: Provide decls.
+	* cmd-edit.cc (gnu_readline::do_set_basic_word_break_characters,
+	gnu_readline::do_set_completer_word_break_characters): New functions.
+	(command_editor::set_basic_quote_characters,
+	command_editor::set_completion_append_character): New static functions.
+	* cmd-edit.h: Provide decls.
+	(command_editor::do_set_basic_word_break_characters,
+	command_editor::do_set_completer_word_break_characters):
+	New virtual functions.
+
+	* CMatrix.h, boolMatrix.h, chMatrix.h, dMatrix.h
+	(resize_fill_value): New static function.
+
+	* Array-idx.h (Array<T>::index): New args, resize_ok and
+	resize_fill_value.
+	* Array2-idx.h (Array2<T>::index): Likewise.
+	* ArrayN-idx.h (ArrayN<T>::index): Likewise.
+
+	* Array2.cc (Array<T>::print_info): New function.
+	* Array2.h: Provide decl.
+
+	* Array.cc (Array<T>::print_info): New function.
+	* Array.h: Provide decl.
+
+2002-05-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.h (idx_vector::idx_vector (int)): New function.
+	(idx_vector_rep::idx_vector_rep (int)): New decl.
+	* idx-vector.cc (idx_vector_rep::idx_vector_rep (int)): New function.
+
+	* Array.h (Array<T>::resize_fill_value (void)): New static function.
+	(assign (Array<LT>&, const Array<RT>&)): Use it.
+	* Array2.h (assign (Array2<LT>&, const Array2<RT>&)): Use it.
+	* ArrayN.h (assign (ArrayN<LT>&, const ArrayN<RT>&)): Use it.
+
+2002-05-02  Cai Jianming  <caijianming at yahoo.co.uk> 
+
+	* Array3.h (Array3<T>::checkelem): Improve error message.
+	* ArrayN.h (ArrayN<T>::range_error): Likewise.
+	* DiagArray2.cc (DiagArray2<T>::checkelem): Likewise.
+	* DiagArray2.cc (DiagArray2<T>::operator ()): Likewise.
+
+2002-04-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.h (DASSL_options::init): Undo previous change.
+	(DASSL_options::set_absolute_tolerance): Likewise.
+
+2002-04-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASPK.h, DASPK.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2002-04-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&, idx_vector&) const):
+	Simplify indexing when one or both of the indices are empty.
+
+2002-04-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.h (DASSL_options::init): Set absolute tolerance to eps ^ 2.
+	(DASSL_options::set_absolute_tolerance): Likewise.
+	* LSODE.h (LSODE_options::init): Likewise.
+	(LSODE_options::set_absolute_tolerance): Likewise.
+
+2002-04-03  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* f2c-main.c (MAIN_, MAIN__): Delete.  Use F77_DUMMY_MAIN instead.
+	* file-stat.cc (file_stat::update_internal, file_stat::copy):
+	Use HAVE_STRUCT_STAT_ST_RDEV instead of HAVE_ST_RDEV.
+	Use HAVE_STRUCT_STAT_ST_BLKSIZE instead of HAVE_ST_BLKSIZE.
+	Use HAVE_STRUCT_STAT_ST_BLOCKS instead of HAVE_ST_BLOCKS.
+	* file-stat.h: Likewise.
+	* oct-time.cc (octave_time::octave_time, octave_base_tm::strftime,
+	octave_base_tm::init, octave_strptime::init): Use HAVE_TM_ZONE
+	instead of HAVE_STRUCT_TM_TM_ZONE.
+	* strftime.c: Likewise.
+	* lo-specfun.cc, mach-info.cc, CColVector.cc, CMatrix.cc,
+	CRowVector.cc, CmplxAEPBAL.cc, CmplxCHOL.cc, CmplxHESS.cc,
+	CmplxLU.cc, CmplxQR.cc, CmplxQRP.cc, CmplxSCHUR.cc, CmplxSVD.cc,
+	CollocWt.cc, DASSL.cc, EIG.cc, LSODE.cc, NLEqn.cc, Quad.cc,
+	dColVector.cc, dMatrix.cc, dRowVector.cc, dbleAEPBAL.cc,
+	dbleCHOL.cc, dbleHESS.cc, dbleLU.cc, dbleQR.cc, dbleQRP.cc,
+	dbleSCHUR.cc, dbleSVD.cc: Use F77_FUNC instead of F77_FCN.
+
+2002-04-02  Paul Kienzle  <pkienzle at users.sf.net>
+
+        * CmplxQR.cc (ComplexQR::init): Use economy QR decomposition
+	internally when the user requests it.
+	* CmplxQRP.cc (ComplexQRP::init): Ditto.
+	* dbleQR.cc (QR::init): Ditto.
+	* dbleQRP.cc (QRP::init): Ditto.
+
+2002-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-fftw.cc (octave_fftw::fft2d): Avoid having to find a
+	definition for NULL by passing 0 as the last arg to fftwnd_one.
+	(octave_fftw::ifft2d): Likewise.
+
+2002-02-22  Paul Kienzle  <pkienzle at jazz.ncnr.nist.gov>
+
+	* lo-mappers.cc (arg): Simply call atan2 (0.0, x).
+
+2001-12-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data-conv.cc (LS_DO_READ): Don't do anything unless len > 0.
+	(LS_DO_WRITE): Likewise.
+	
+2001-11-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-inlines.cc (MX_CUMMULATIVE_OP): New macro.
+	* CMatrix.cc (ComplexMatrix::cumprod, ComplexMatrix::cumsum): Use it.
+	* dMatrix.cc (Matrix::cumprod, Matrix::cumsum): Likewise.
+
+	* mx-inlines.cc (MX_REDUCTION_OP, MX_REDUCTION_OP_COL_EXPR,
+	MX_REDUCTION_OP_ROW_EXPR): New macros.
+	* dMatrix.cc (Matrix::prod, Matrix::sum): Use MX_REDUCTION_OP.
+	* CMatrix.cc (ComplexMatrix::prod, ComplexMatrix::sum): Likewise.
+
+	* mx-inlines.cc (MX_BASE_REDUCTION_OP): New macro.
+	DIM == -1 now means no orientation for vector sums.
+	* dMatrix.cc (ComplexMatrix::sumsq): Use it.
+	* CMatrix.cc (ComplexMatrix::sumsq): Likewise.
+
+2001-11-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (Range::nelem_internal): Special case ranges that must
+	have zero elements.
+
+2001-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Split out readline and pathsearch functionality
+	into separate liboct-readline and liboct-pathsearch libraries.
+
+	* oct-rl-edit.c (octave_rl_clear_screen): Call rl_clear_screen,
+	not _rl_clear_screen.  Temporarily redefine rl_redisplay_function
+	to do nothing for this call to rl_clear_screen.
+
+2001-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.cc (ddassl_f): Handle IRES returned from user supplied
+	function.
+	* DAEFunc.h (DAERHSFunc): Add IRES to prototype.
+
+2001-06-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::inverse, Matrix::solve, Matrix::determinant,
+	Matrix::inverse): Handle the case of rcond being a NaN the same as
+	a signular matrix.  From "Jianming" <caijianming at yahoo.co.uk>.
+	* CMatrix.cc (ComplexMatrix::inverse, ComplexMatrix::solve,
+	ComplexMatrix::determinant, ComplexMatrix::inverse): Likewise.
+
+2001-05-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (charMatrix::row_as_string): New parameter, raw.
+
+	* Array-i.cc, Array-s.cc, Array-d.cc, Array-ch.cc, Array-C.cc,
+	Array-b.cc: Instantiate three arg assign functions.
+
+	* ArrayN.cc (assign (ArrayN<LT>&, const ArrayN<RT>&, const LT&)):
+	New arg, resize_fill_value.
+	* ArrayN.h: Provide declaration.
+	(assign (ArrayN<LT>&, const ArrayN<RT>&): Define here by calling
+	three arg version.
+
+	* Array3.cc (assign (Array3<LT>&, const Array3<RT>&, const LT&)):
+	New arg, resize_fill_value.
+	* Array3.h: Provide declaration.
+	(assign (Array3<LT>&, const Array3<RT>&): Define here by calling
+	three arg version.
+
+	* Array2.cc (assign (Array2<LT>&, const Array2<RT>&, const LT&)):
+	New arg, resize_fill_value.
+	* Array2.h: Provide declaration.
+	(assign (Array2<LT>&, const Array2<RT>&): Define here by calling
+	three arg version.
+
+	* Array.cc (assign (Array<LT>&, const Array<RT>&, const LT&)):
+	New arg, resize_fill_value.
+	* Array.h: Provide declaration.
+	(assign (Array<LT>&, const Array<RT>&): Define here by calling
+	three arg version.
+
+2001-05-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.cc (dir_path::set_program_name): Set the environment
+	variables SELFAUTOLOC, SELFAUTODIR, SELFAUTOPARENT, and TEXMFDBS
+	to the empty string.
+
+2001-05-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2.h (Array2<T>::operator = (const Array2<T>&)):
+	Don't check for rep != a.rep.
+
+2001-05-02  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* oct-fftw.h, oct-fftw.cc: New files.
+	* Makefile.in (INCLUDES, SOURCES): Add new files.
+	* CMatrix.cc (ComplexMatrix::{fourier, ifourier, fourier2d, 
+	ifourier2d}): Use fftw if available.
+	* dMatrix.cc (Matrix::{fourier, ifourier, fourier2d, ifourier2d}): 
+	Likewise.
+
+2001-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-lib): Don't use mk-libdir-link.
+	(install-inc): Don't use mk-includedir-link.
+
+2001-02-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-cutils.c (octave_gethostname): New function.
+	* lo-utils.h: Provide declaration.
+	* oct-env.cc (octave_env::do_get_host_name):
+	Call octave_gethostname, instead of gethostname.
+
+	* lo-cutils.c (gethostname): Define here.
+	* lo-sysdep.cc: Not here.
+
+2001-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-cutils.c: Don't declare strptime.
+	(oct_strptime): Cast return type of strptime to char*.
+
+2001-02-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-edit.c (octave_rl_newline): Call rl_newline with two args.
+	(octave_rl_set_name): call rl_re_read_init_file with two args.
+	(octave_rl_read_init_file): Ditto.
+	(octave_rl_clear_undo_list): Call rl_free_undo_list, not
+	free_undo_list.
+	(octave_rl_completion_matches): Call rl_completion_matches, not
+	completion_matches.
+	(octave_rl_enable_paren_matching): New function.
+	(octave_rl_set_blink_matching_paren_flag): Delete.
+	(octave_rl_get_blink_matching_paren_flag): Delete.
+
+	* lo-mappers.h, lo-mappers.cc (log10 (const Complex&),
+	tanh (const Complex&)): Declare and define if not 
+	CXX_ISO_COMPLIANT_LIBRARY.
+
+2001-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.h (tanh (const Complex&)): Only declare if not
+	CXX_ISO_COMPLIANT_LIBRARY.
+
+2001-02-05  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* lo-mappers.cc (tanh (const Complex&)): Only define if not
+	CXX_ISO_COMPLIANT_LIBRARY.
+
+	* Makefile.in (TEMPLATE_AR, TEMPLATE_ARFLAGS): Use to create
+	archive libraries containing templates.
+
+	* ArrayN-idx.h (freeze, all_ok, any_orig_empty, any_zero_len,
+	get_zero_len_size, all_colon_equiv): Inline. 
+	(ArrayN<T>::index): Rename idx to arr_idx.
+	* ArrayN.cc (ArrayN<T>::index, ArrayN<T>::compute_index, 
+	ArrayN<T>::get_size, ArrayN<T>::range_error, ArrayN<T>::range_error,
+	increment_index, ArrayN<T>::resize, ArrayN<T>::insert): Likewise.
+
+2001-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.h, lo-mappers.cc (tan (const Complex&),
+	log10 (const Complex&)): Delete.
+
+	* oct-cmplx.h: Define forwarding functions for real, imag, abs,
+	arg, norm, conj, polar, cos, cosh, exp, log, log10, pow, sin,
+	sinh, sqrt, tan, and tanh.
+
+2001-01-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc, help.cc, load-save.cc, pr-output.cc, utils.cc:
+	Add std:: namespace qualifier as needed.
+
+	* mx-inlines.cc: Rename all functions with mx_inline_ prefix.
+	Change all uses to match.
+
+2001-01-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-cutils.c: Don't delcare strptime.
+
+2001-01-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (operator * (const ComplexMatrix&, const ComplexMatrix&):
+	Return correct size result for empty matrix case.
+
+2000-12-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (xmin (const Complex&, const Complex& y):
+	If args are equal in magnitude, return first arg instead of
+	second.
+
+2000-12-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (Range::nelem_internal): Call tfloor, not round, but
+	then try harder to compute correct number of elements.
+
+	* dMatrix.cc (Matrix::lssolve): Ask DGELSS for size of work vector.
+	* CMatrix.cc (ComplexMatrix::lssolve): Likewise, for ZGELSS.
+
+2000-12-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (Range::nelem_internal): Call round here, not tfloor.
+	Rename n_intervals to be n_elt.
+
+	* strptime.c: Surround everything after including config.h in
+	#ifndef HAVE_STRPTIME ... #endif.
+
+2000-11-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-idx.h (assign): When resizing, cast fill value to LT.
+	* Array2-idx.h (MAYBE_RESIZE_LHS): Likewise.
+
+2000-11-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArray-defs.h: Protect against multiple inclusion.
+
+2000-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data-conv.h (enum save_type): Move LS_U_LONG and LS_LONG to the
+	end of the list, to be compatible with previous versions of Octave.
+
+2000-11-16  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* oct-time.cc (DEFINE_SET_INT_FIELD_FCN): Don't check limits here,
+	since mktime is supposed to `normalize' the results for us.
+
+2000-10-31  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* Array2.cc (Array2<T>::transpose): Avoid copy for empty matrices
+	and vectors.  Use xelem for faster access to elements when copying.
+
+2000-10-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (ComplexMatrix::cumsum, ComplexMatrix::cumprod):
+	Correct indexing for operation across rows.
+	* dMatrix.cc (Matrix::cumsum, Matrix::cumprod): Likewise.
+
+2000-10-12  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&)): Avoid copying
+	elements if arg is a colon.
+
+2000-10-12  Cai Jianming  <caijianming at yahoo.co.uk>
+
+	* dMatrix.cc (Matrix::cumprod (int) const): New arg, DIM.
+	(Matrix::cumsum (int) const): Likewise.
+	(Matrix::prod (int) const): Likewise.
+	(Matrix::sum (int) const): Likewise.
+	(Matrix::sumsq (int) const): Likewise.
+	* CMatrix.cc (ComplexMatrix::cumprod (int dim) const): Likewise.
+	(ComplexMatrix::cumsum (int) const): Likewise.
+	(ComplexMatrix::prod (int) const): Likewise.
+	(ComplexMatrix::sum (int) const): Likewise.
+	(ComplexMatrix::sumsq (int) const): Likewise.
+
+2000-10-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&)): Correctly set
+	size if Array<T>::index returns an empty array.
+
+2000-08-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc (file_ops::link, file_ops::symlink,
+	file_ops::readlink): New functions.
+
+2000-08-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&)): If a scalar is
+	indexed, always return an object the same size as the index arg.
+
+	* oct-time.cc (octave_base_tm::strftime): Return empty string for
+	empty format.
+
+2000-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-cutils.c (oct_strptime): New function.
+	* oct-time.cc (octave_strptime::init): Call it instead of strptime.
+	Don't declare strptime.  Don't define _XOPEN_SOURCE or _BSD_SOURCE.
+
+2000-07-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc: Comment out _BSD_SOURCE and _XOPEN_SOURCE definitions.
+
+	* Makefile.in (MATRIX_INC): Add ArrayN-idx.h to the list.
+
+2000-06-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.h (read_int): Provide declaration.
+
+2000-06-29  James R. Van Zandt  <jrv at vanzandt.mv.com>
+
+	* data-conv.cc (read_doubles): Handle EIGHT_BYTE_INT cases.
+	(write_doubles): Ditto.
+	* data-conv.h: Ditto.
+	(enum save_type): New values, LS_U_LONG and LS_LONG.
+
+2000-06-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* boolMatrix.h: Declare MM_CMP_OPS here.
+	* boolMatrix.cc: Define them here.
+
+2000-06-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign): Allow x(bool) = RHS to succeed if x is
+	previously undefined and set size of x to size of bool index.
+	* idx-vector.cc (IDX_VEC_REP::maybe_convert_one_zero_to_idx):
+	Allow z_len to be zero.
+	(IDX_VEC_REP::freeze): If z_len is zero, set frozen_at_z_len to len.
+	If frozen, don't assert that frozen_at_z_len == z_len.
+
+2000-05-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-edit.c (octave_rl_clear_screen): Call _rl_clear_screen
+	instead of rl_clear_screen.
+
+2000-05-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-d.cc: Instantiate ArrayN<double> here too.
+	* Array-idx-vec.cc, ArrayN-idx.h, ArrayN.cc, ArrayN.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2000-04-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::operator =): Don't set max_indices to 1 here.
+
+2000-03-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-sysdep.h: octave_chdir returns int, not bool.
+
+2000-03-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (liboctave.$(SHLEXT)): Delete target
+	before rebuilding.
+
+2000-03-21  Ben Sapp  <bsapp at nua.lampf.lanl.gov>:
+
+	* Makefile.in (liboctave.$(LIBEXT)): New target.
+	(libraries): Depend only on library targets, not archive members.
+
+2000-03-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: (objects): New target.
+
+	* lo-cutils.c: New file.
+	* Makefile.in (SOURCES): Add it to the list.
+	* lo-utils.h: Declare octave_qsort here.
+	* Array.h (Array::qsort): Use it here.
+
+2000-03-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc: Include <sys/types.h> and <unistd.h>, if available.
+
+2000-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-hist.c (octave_history_list): Do something when not
+	printing line numbers.  Fix reallocation of retval.
+
+2000-02-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-inc): Install files in
+	$(octincludedir)/octave.
+	(uninstall): Remove them from the correct directory too.
+
+	* oct-time.cc: Temporarily define _BSD_SOURCE and _XOPEN_SOURCE if
+	they are not already defined.
+
+2000-02-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CRowVector.cc, CRowVector.h, CColVector.cc, CColVector.h:
+	Delete declarations and definitions of mixed-type vector-vector ops.
+
+2000-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.h, CMatrix.cc: Add lssolve methods for real-valued RHS
+	matrix and vector objects.
+
+	* mx-op-defs.h (DMM_BIN_OP): Explicitly request conversion to
+	return type from second arg type.
+	(MDM_BIN_OP): Likewise, for first arg type.
+
+	* dMatrix.cc (Matrix::fourier, Matrix::ifourier,
+	Matrix::fourier2d, Matrix::ifourier2d): Likewise.
+
+	* EIG.cc (EIG::symmetric_init, EIG::hermitian_init): Explicitly
+	request ColumnVector to ComplexColumnVector, and Matrix to
+	ComplexMatrix conversions.
+
+	* CmplxAEPBAL.cc (ComplexAEPBALANCE::init): Give balancing_mat its
+	initial value using ComplexMatrix constructor.
+
+	* CColVector.cc (product, quotient,
+	operator * (const DiagMatrix&, const ComplexColumnVetor&)):
+	Fix type of returned value.
+	* CDiagMatrix.cc (ComplexDiagMatrix::row,
+	ComplexDiagMatrix::column, ComplexDiagMatrix::inverse): Likewise.
+
+	* Array.h, CColVector.h, CDiagMatrix.h, CMatrix.h, CRowVector.h,
+	MArray.h, MDiagArray2.h, dColVector.h, dDiagMatrix.h, dMatrix.h,
+	dRowVector.h: Declare some constructors explicit, to disallow
+	potentially problematic automatic type conversions.
+
+2000-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* vx-rv-crv.h, vx-cv-ccv.h, vx-crv-rv.h, vx-ccv-cv.h,
+	vx-rv-crv.cc, vx-cv-ccv.cc, vx-crv-rv.cc, vx-ccv-cv.cc:
+	More new files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* vx-ccv-s.h, vx-crv-s.h, vx-cs-cv.h, vx-cs-rv.h, vx-cv-cs.h,
+	vx-rv-cs.h, vx-s-ccv.h, vx-s-crv.h, vx-ccv-s.cc, vx-crv-s.cc,
+	vx-cs-cv.cc, vx-cs-rv.cc, vx-cv-cs.cc, vx-rv-cs.cc, vx-s-ccv.cc,
+	vx-s-crv.cc:, New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* CRowVector.h, CRowVector.cc, CColVector.h, CColVector.cc:
+	Delete scalar by vector and vector by scalar binary ops.
+
+	* MArray-defs.h: More new macros to handle MDiagArray operators.
+	* dDiagMatrix.h, CDiagMatrix.h: Use the op-forwarding macros.
+
+2000-02-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-edit.c (octave_rl_set_event_hook): Take address of
+	rl_event_hook before casting to void **.
+	(octave_rl_set_startup_hook): Likewise, for rl_startup_hook.
+
+	* MArray-defs.h: Many new macros to make declaration and
+	definition of operators more consistent.
+	
+	* MArray.h, MArray2.h, dColVector.h, dRowVector.h, CColVector.h,
+	CRowVector.h, dMatrix.h, CMatrix.h: Use them.
+
+2000-02-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::ifourier): Cast divisor to double.
+	(Matrix::ifourier2d): Likewise.
+	* CMatrix.cc (ComplexMatrix::ifourier): Likewise.
+	(ComplexMatrix::ifourier2d): Likewise.
+
+	* Array.h (Array::ArrayRep::qsort): Cast len to size_t.
+
+2000-02-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-rl-edit.c, oct-rl-edit.h: New files for interface to GNU
+	readline library.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* oct-rl-hist.c, oct-rl-hist.h: New files for interface to GNU
+	readline history library.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* data-conv.cc (LS_DO_WRITE): Cast arg to ostream::write to char*.
+	(LS_DO_READ): Likewise, for istream::read.
+	(write_doubles): Likewise.
+	(read_doubles): Likewise.
+
+	* oct-env.cc (octave_env::do_polite_directory_format):
+	Use operator== and substr method to do limited-length string
+	comparison.
+
+	* Array2-idx.h, Array-idx.h: Avoid shadowing warnings for idx.
+
+	* Quad.h: Use do_integrate as name of pure virtual function.
+
+	* base-de.h: Use tt instead of t as arg names.
+	Add method with tcrit arg.
+
+	* DAE.h, DAE.cc: Likewise, also xx for x.
+
+	* DASSL.cc (dassl_fcn_ptr, dassl_jac_ptr): New typedefs.
+	* LSODE.cc: lsode_fcn_ptr, lsode_jac_ptr): Ditto.
+	* Quad.cc (quad_fcn_ptr): Ditto.
+	* NLEqn.cc (hybrd1_fcn_ptr, hybrj1_fcn_ptr): Ditto.
+
+	* oct-getopt.h, oct-getopt.c: New files for interface to getopt.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* oct-kpse.h, oct-kpse.c: New files for interface to kpathsearch.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* dMatrix.cc (write_int, read_int): No longer declared static.
+
+	* CDiagMatrix.h: Delete decls for friend operators that are
+	handled by MDiagArray2 class.  Move others outside class decl and
+	strip friend status.
+	* dDiagMatrix.h: Likewise.
+
+	* MArray.h: Delete decls for friend operators inside class decl.
+	* MArray2.h: Ditto.
+	* MDiagArray2.h: Ditto.
+
+	* MArray-defs.h (DO_VS_OP,, DO_SV_OP, DO_VV_OP, NEGV): Pass all
+	necessary parameters.  Don't allocate memory in the macro.  Change
+	all uses.
+
+	* dMatrix.h (class Matrix): Delete `friend class' decls.
+	* CMatrix.h (class ComplexMatrix): Ditto.
+
+	* mx-op-defs (MS_BOOL_OP, MS_BOOL_OPS, SM_BOOL_OP, SM_BOOL_OPS,
+	MM_BOOL_OP, MM_BOOL_OPS, MDM_MULTIPLY_OP, MDM_BIN_OPS,
+	DMM_MULTIPLY_OP, DMM_BIN_OPS): Pass zero constant as final arg, to
+	avoid type conflicts.  Change all uses.
+
+	* strptime.c (__mon_yday): Fix size of array decl.
+
+	* mx-inlines.cc: Use `xnot' instead of `not' for function name.
+
+	* chMatrix.cc (charMatrix::row_as_string): Delete extraneous
+	default value for second arg.
+
+	* Array2.cc (Array2<T>::resize): Add Array<T>:: qulaifier to
+	references to ArrayRep.
+
+2000-01-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (Array::ArrayRep): Now protected, not private.
+
+	* All source files: Include iostream, fstream, strstream,
+	etc. as needed instead of using forward declarations for these
+	classes.  Add std:: qualifier as needed.
+
+2000-01-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc: Declare strptime extern "C".
+
+2000-01-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc [! HAVE_STRPTIME]: Provide declaration.
+
+2000-01-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2.h (Array2<T>::get_size): Now protected instead of private.
+	* Array3.h, Array3.cc: Use it in constructors and resize methods
+	to get total size to be allocated.
+
+	* DASSL.cc (DASSL::integrate): Declare do_restart and save_output
+	as bool, not int.
+
+2000-01-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign (Array2<LT>& lhs, const Array2<RT>& rhs)): 
+	Allow A(idx) = RHS if idx is a boolean index with the same shape
+	as A, even when do_fortran_indexing is not enabled.
+	(Array2<T>::index (idx_vector& idx) const): Likewise, for A(idx).
+
+2000-01-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::solve (...)): Add new variant with
+	function pointer as final arg.  Passed function (if any) will be
+	called for singularity errors.
+	* CMatrix.cc (ComplexMatrix::solve (...)): Likewise.
+
+	* dMatrix.cc (Matrix::pseudo_inverse): Use economy SVD.
+	* CMatrix.cc (ComplexMatrix::pseudo_inverse): Likewise.
+
+	* lo-ieee.cc (octave_ieee_init): Don't include sunmath.h.
+	No longer bother with infinity or quiet_nan.
+
+	* Array2.cc (Array2<T>::get_size): New function.
+	(Array2<T>::Array2, Array2<T>::resize): Use it.
+
+2000-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::maybe_delete_elements (idx_vector&)):
+	New function.
+	(assign (Array2<LT>& lhs, const Array2<RT>& rhs)):
+	Use it when indexing with one arg instead of faking a second one.
+	(Array2<T>::maybe_delete_elements (idx_vector&, idx_vector&)):
+	Return empty matrices with the correct dimensions for A(:,:) = []
+	and also A(:,idx) = [], and A(idx,:) = [] when idx enumerates all
+	rows or columns.
+
+	* idx-vector.cc (IDX_VEC_REP::is_colon_equiv): Recognize a bool
+	vector that is all true values with a length equal to n as colon
+	equivalent.
+
+2000-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strptime.c: Only include langinfo.h if _LIBC is defined.
+
+2000-01-21  A. Scottedward Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* CMatrix.cc (ComplexMatrix::expm): Apply permutation and scaling
+	operations directly in step 2 and reverse step 2.
+	* dMatrix.cc (Matrix::expm): Apply permutation and scaling
+	operations directly in step 2 and reverse step 2.
+
+2000-01-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.h, oct-time.cc (octave_strptime): New class.
+
+	* strptime.c: New file, from glibc 2.1.2.
+	* Makefile.in (SOURCES): Add strptime.c to the list.
+
+2000-01-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArray.h (MArray <const Array<T>&)): New constructor.
+
+2000-01-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.cc (dir_path::all_directories): Avoid dereferencing
+	NULL directory list returned from kpse_element_dirs
+
+1999-12-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleLU.cc (LU::LU): Call DGETRF directly instead of calling DGESV.
+	* CmplxLU.cc (ComplexLU::ComplexLU): Likewise, call ZGETRF
+	directly, instead of calling ZGESV.
+
+1999-11-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data-conv.cc (init_sized_type_lookup_table): New function.
+	(string_to_data_type): Use it to improve lookup of data types.
+
+1999-11-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (is_symmetric): Move here from Array2.cc.
+	* Array2.h (is_symmetric): Delete declaration.
+
+1999-11-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-env.cc (do_get_user_name): Reverse sense of test.
+
+1999-11-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc (Fstrftime): Undo previous change.
+	(octave_time::octave_time (const octave_base_tm&)): Likewise.
+
+1999-11-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleSVD.cc (SVD::init): Let DGESVD determine work space requirement.
+	* CmplxSVD.cc (ComplexSVD::init): Likewise, for complex version.
+
+	* dbleSCHUR.cc (SCHUR::init): IWORK is always referenced by dgeesx.
+	Don't forget to pass length of third string argument to dgeesx.
+
+	* CmplxSCHUR.cc (ComplexSCHUR::init): Don't forget to pass length
+	of third string argument to zgeesx.
+
+1999-11-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DiagArray2.cc (DiagArray2<T>::operator () (int, int)):
+	On errors, simply return `T ()'.
+	(DiagArray2<T>::checkelem (int, int)): Likewise.
+
+1999-11-02  A. Scottedward Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* dMatrix.cc (Matrix::expm): Do balancing here instead of using
+	AEPBALANCE class.
+	* CMatrix.cc (ComplexMatrix::expm): Likewise.
+
+1999-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-shlib.cc, oct-shlib.h: New files.
+	* Makefile.in (INCLUDES, SOURCES): Add them to the lists.
+
+1999-10-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CRowVector.cc (linspace): Allow npoints == 1 if x1 == x2.
+	* dRowVector.cc (linspace): Ditto.
+
+	* oct-time.cc (Fstrftime): Don't save or delete tm_zone.
+	(octave_time::octave_time (const octave_base_tm&)): Likewise.
+
+1999-10-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.cc (DASSL::do_integrate (double)): If we have a function
+	to evaluate the Jacobian, set info(4), not iwork(4).
+	Set rwork(1) to the maximum step size, not rwork(2).
+
+1999-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.cc: Include <climits>.
+
+1999-10-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.h (command_editor::do_resize_terminal): New function.
+	* cmd-edit.cc (command_editor::resize_terminal): New function.
+	(gnu_readline::do_resize_terminal): New function.
+
+Fri Sep  3 12:39:17 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc: Include ieeefp.h and sunmath.h if we have them.
+	* lo-ieee.c: Likewise.
+	Delete extern "C" declarations for infinity and quiet_nan.
+
+Fri Aug 20 07:58:00 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-inlines.cc (VS_OP, SV_OP, VV_OP): Delete `extern template' decls.
+	(VS_OP_FCN, SV_OP_FCN, VV_OP_FCN): Declare template functions
+	`inline', not `static inline'.
+
+	* idx-vector.cc (intcmp): Declare args as const void *, not int *,
+	then cast to const int * to compare.
+
+Fri Jul 16 11:23:51 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DAEFunc.h: Remove useless preprocessor conditional.
+
+Thu Jul 15 14:10:33 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.cc (command_editor::do_decode_prompt_string):
+	Use octave_time object instead of time_t.
+
+	* file-stat.h (file_stat::fs_atime, file_stat::fs_mtime,
+	file_stat::fs_ctime): Now octave_time objects.
+	(file_stat::atime, file_stat::mtime, file_stat::ctime):
+	Return octave_time objects.
+	(file_stat::is_newer): Args are now octave_time objects instead of
+	time_t.
+
+	* oct-time.h (octave_time::as_double): Delete.
+	(octave_time::operator double ()): New function.
+	(octave_time::operator time_t ()): New function.
+	(octave_time::ctime): New function.
+	(octave_base_tm::strftime): Renamed from format_as_string.
+	(octave_base_tm::asctime): New function.
+	(operator == (const octave_time&, const octave_time&),
+	operator != (const octave_time&, const octave_time&),
+	operator < (const octave_time&, const octave_time&),
+	operator <= (const octave_time&, const octave_time&),
+	operator > (const octave_time&, const octave_time&),
+	operator >= (const octave_time&, const octave_time&)):
+	New comparison functions.
+
+	* strftime.c: Move here from src directory.
+	* Makefile.in (SOURCES): Add it to the list.
+
+	* oct-time.h (octave_time::octave_time (time_t)): New constructor.
+
+Wed Jul 14 17:38:07 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-time.h, oct-time.cc: New files.
+	* Makefile.in (INCLUDES, SOURCES): Add them to the lists.
+
+	* systime.h: Move here from src directory.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+Mon Jul 12 22:34:34 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-defs.h (b_d_Mapper, b_c_Mapper): New typedefs.
+	* dMatrix.cc (Matrix::map (b_d_Mapper)): New function.
+	* CMatrix.cc (ComplexMatrix::map (b_c_Mapper)): New function.
+	* lo-mappers.cc (xisinf, xisnan, xfinite): Return bool, not double.
+
+	* lo-mappers.cc (xmin, xmax): New functions to correctly handle NaNs.
+
+Mon May 10 07:45:11 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArray-defs.h (DO_VV_OP2): Fix macro definition to use arg.
+
+Wed May  5 20:06:10 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>index (idx_vector& idx)): Always return a
+	column vector for A(:), for compatibility with Matlab.
+
+Fri Apr 23 11:52:23 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.cc (LSODE::do_integrate (double)): Don't forget to set
+	iopt when there are optional inputs in rwork or iwork.
+
+Fri Mar 26 11:26:32 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (libraries): Use the libfoo.a(objects) method of
+	creating static libs.
+
+Thu Mar  4 02:17:04 1999  James Macnicol  <jamesm at evans.ee.adfa.oz.au>
+
+	* data-conv.cc (oct_data_conv::string_to_data_type): Handle uint16
+	and uint32 data types.
+
+Thu Mar  4 01:51:37 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (octave_ieee_init): Don't use __alpha__-specific code
+	for Linux.  Remove old Linux-specific code.
+
+Tue Jan 19 09:34:55 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (operator * (const ColumnVector& v, const RowVector& a)):
+	Don't require lengths to be equal.
+	* CMatrix.cc (operator * (const ComplexColumnVector& v, const
+	ComplexRowVector& a)): Likewise
+
+Tue Nov 24 23:38:19 1998  Eric Norum  <eric at skatter.USask.Ca>
+
+	* statdefs.h: Only define mode_t if not already defined.
+
+Tue Nov 24 17:24:52 1998  john  <john at arrows.demon.co.uk>
+
+	* lo-specfun.cc (airy, biry): Set imaginary part of result to zero
+	when appropriate.
+
+Mon Nov 23 09:57:05 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.cc (gnu_readline::gnu_readline): Set terminal name
+	before calling rl_initialize.
+
+Tue Nov 17 23:47:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc (besselh, airy, biry): New functions.
+	Update Bessel function support to use library by D. E. Amos.
+
+Thu Nov 12 17:44:15 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.h (command_editor::readline): Add new variation that
+	allows EOF information to be passed back to caller.
+
+	* dMatrix.cc (Matrix::read): Do the right thing for EOF when
+	amount of data to read is unspecified.
+
+Tue Nov 10 07:53:15 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-alloc.h (DECLARE_OCTAVE_ALLOCATOR): New macro.
+	(DEFINE_OCTAVE_ALLOCATOR): Ditto.
+
+	* byte-swap.h (swap_bytes, swap_2_bytes, swap_4_bytes, swap_8_bytes): 
+	Add volatile qualifier to void* arg.
+	Cast volatile void* arg to volatile char*.
+
+Mon Nov  9 08:28:31 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.h (command_editor::do_set_event_hook): New function.
+	(command_editor::do_restore_event_hook): Ditto.
+	* cmd-edit.cc (command_editor::set_event_hook): Ditto.
+	(command_editor::restore_event_hook): Ditto.
+	(gnu_readline::do_set_event_hook): Ditto.
+	(gnu_readline::do_restore_event_hook): Ditto.
+	(gnu_readline::previous_event_hook): New data member.
+	(gnu_readline::gnu_readline): Initialize previous_event_hook.
+
+Mon Nov  2 13:36:04 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (BINDISTLIBS): Don't include .$(SHLEXT_VER) in name.
+
+	* Makefile.in (stmp-pic): New target.
+	($(PICOBJ)): Depend on stmp-pic, not pic.
+	(clean): Remove stmp-pic
+
+	* Makefile.in: Undo previous change to avoid optmization when
+	compiling lo-ieee.cc.
+
+Sun Nov  1 10:10:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (xfinite): Define in terms of xfinite for real and
+	imaginary parts.
+	(xisinf): Define in terms of xisinf for real and imaginary parts.
+
+Thu Oct 29 18:57:50 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* boolMatrix.cc (boolMatrix::operator !): New function.
+
+Fri Oct 23 21:46:20 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.h (dir_path::default_path): New data member.
+	* pathsearch.cc (dir_path::init): Use it.
+
+	* Makefile.in: Avoid optmization when compiling lo-ieee.cc.
+
+Fri Oct 16 01:08:30 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (charMatrix::extract): New function.
+	(charMatrix::charMatrix (char c)): New constructor.
+
+Tue Oct 13 22:11:08 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.h: (command_editor::do_read_init_file): New function.
+	* cmd-edit.cc (command_editor::read_init_file): New function.
+	(gnu_readline::do_read_init_file): Likewise.
+
+Fri Sep 25 14:26:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-env.cc (octave_env::do_get_home_directory): 
+ 	If HOME can't be found, set it to "/".
+	(octave_env::do_get_user_name)
+	If user name can't be found, set it to "unknown".
+	(octave_env::do_get_host_name)
+	If host name can't be found, set it to "unknown".
+
+	* pathsearch.h (dir_path::rehash): New function.
+	* pathsearch.cc (dir_path::init): Clear kpathsea's internal
+	diretcory cache before doing initialization.
+
+Thu Sep 24 13:23:25 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Qzval): Delete.
+	(qzhes, qzit, qzval): Delete F77_FCN declarations.
+	* dMatrix.h (Qzval): Delete declaration.
+
+	* dbleGEPBAL.h, dbleGEPBAL.cc: Delete.
+	* Makefile.in (MATRIX_INC, MATRIX_SRC): Delete them from the lists.
+	* mx-ext.h: Don't include dbleGEPBAL.
+
+	* lo-ieee.cc (octave_ieee_init): For now, use X_CAST instead of
+	static_cast.
+
+Fri Sep  4 10:58:22 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::read): Skip after reading, not before.
+	From: Dr.-Ing. Torsten Finke <fi at igh-essen.com>.
+
+Wed Sep  2 09:50:21 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (octave_ieee_init): For Linux on arm, don't rely on
+	HUGE_VAL and NAN.
+
+Wed Aug 26 15:04:57 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign (Array2<LT>& lhs, const Array2<RT>& rhs)):
+	Handle x(i) = scalar for do_fortran_indexing == 1.
+
+Thu Jul 30 00:34:10 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (ComplexMatrix::ComplexMatrix (const charMatrix&)):
+	Alloctate space before attempting to use it.
+	(ComplexMatrix::ComplexMatrix (const boolMatrix&)): Likewise.
+
+Mon Jun 22 17:04:27 1998  Tomislav Goles  <tom at ait-tech.com>
+
+	* EIG.cc (EIG::init): Move invariant code outside loop.
+
+Thu Jun 18 11:08:23 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArray2.cc (MARRAY_A2A2_OP): If operands are empty, make result
+	have the same size as the operands.
+	
+Thu May 28 10:41:04 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DASSL.cc (DASSL::do_integrate): If an exception occurs in the
+	call to ddassl, set integration_error to 1 before calling the
+	error handler and returning.
+	* LSODE.cc (LSODE::do_integrate): Likewise.
+
+Wed May 27 13:46:30 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign): Allow A([],[]) = scalar and, if
+	do_fortran_indexing is set, A([]) = scalar.
+	* Array-idx.h (assign): Allow A([]) = scalar.
+
+Thu May 14 11:50:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mx-op-defs.h (MDM_MULTIPLY_OP): Compute result if dm_nc > 0, not
+	if dm_nc == 0.
+
+Thu Apr 23 16:15:37 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.h (dir_path::p_orig): New field.
+	* pathsearch.cc (dir_path::init): Perform variable and tilde
+	expansion on the original path here.
+	(dir_path::find_all): Don't do anything if not initialized.
+
+Tue Apr 14 14:41:30 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (index): Allow x(:) even when do_fortran_indexing
+	is not set.
+	(index): Allow x = zeros (2, 0); x(1,:) to work.
+
+	* lo-specfun.cc (gammainc): Use dgamit to compute
+	(\int_0^x exp(-t) t^(a-1) dt)/gamma(a), not just
+	\int_0^x exp(-t) t^(a-1) dt.
+
+Wed Apr  8 22:50:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-C.cc, Array-b.cc, Array-ch.cc, Array-i.cc, Array-d.cc,
+	Array-s.cc: Change return types of all `assign' explicit
+	instantiations to be int, not void, to match the template decl in
+	Array.h.
+
+Mon Apr  6 00:27:06 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc (gammainc): Reorder args in call to xdgami.
+
+Thu Feb 19 01:16:38 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-specfun.cc (xgamma, xlgamma): Define here.
+	* lo-mappers.cc: Not here.
+
+	* lo-specfun.h: Declare xgamma and xlgamma here.
+	* lo-mappers.h: Not here.
+
+	* lo-specfun.h: Never declare gamma or lgamma.
+
+Tue Feb 10 16:14:36 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-idx.h (assign): Allow A([]) = X to succeed if X is an
+	empty matrix of any dimension.
+
+Thu Feb  5 02:12:38 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-syscalls.cc (octave_syscalls::vfork): New function.
+
+	* lo-specfun.cc: Don't include dbleBessel.h.
+
+	* Makefile.in (INCLUDES): Delete oct-math.h from the list.
+
+	* dir-ops.h (dir_entry::operator bool ()): Return bool, not void*.
+	* file-stat.h (file_stat::operator bool ()): Likewise.
+	* idx-vector.h (idx_vector::operator bool ()): Likewise.
+	* oct-group.h (octave_group::operator bool ()): Likewise.
+	* oct-passwd.h (octave_passwd::operator bool ()): Likewise.
+
+	* data-conv.cc (IEEE_little_double_to_IEEE_big_double):
+	Don't cast arg in call to swap_8_bytes.
+	(IEEE_big_double_to_IEEE_little_double): Ditto
+	(IEEE_big_float_to_IEEE_little_float): Don't cast arg in call to
+	swap_4_bytes.
+	(IEEE_little_float_to_IEEE_big_float): Ditto
+
+	* oct-alloc.cc (grow): Use X_CAST, not static_cast.
+	* prog-args.cc (prog_args::getopt): Likewise.
+	* dMatrix.cc (read_int, do_read, write_int, do_write): Likewise.
+	* cmd-edit.cc (gnu_readline::do_set_completion_function): Likewise.
+	* data-conv.cc (LS_DO_READ, LS_DO_WRITE, read_doubles, write_doubles):
+	Likewise.
+
+	* byte-swap.h (swap_bytes, swap_2_bytes, swap_4_bytes,
+	swap_8_bytes): Declare ptr arg as void*, then use cast.
+
+Mon Feb  2 01:42:56 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install, uninstall): Use $(octlibdir), not $(libdir).
+	Use $(mk-libdir-link).
+
+	* file-stat.cc (file_stat::update_internal): Use stat and lstat,
+	not SAFE_STAT and SAFE_LSTAT.
+	(lstat): New function, defined if HAVE_LSTAT is not defined.
+	* safe-xstat.hin, safe-xstat.cin: Delete.
+	* Makefile.in: Delete rules for safe-stat.h, safe-stat.c,
+	safe-lstat.h, and safe-lstat.cc.
+
+Fri Jan 30 23:48:43 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (charMatrix::all, charMatrix::any): New functions.
+
+Tue Jan 20 16:30:00 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::expm): Skip trace normalization step if the
+	trace is negative. 
+	* CMatrix.cc (ComplexMatrix::expm): Skip trace normalization if
+	the real part of the trace is negative.
+
+Mon Jan 19 16:01:59 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::expm): Call xdlange instead of dlange.
+	* CMatrix.cc (ComplexMatrix::expm): Call xzlange instead of zlange.
+
+	* Array2-idx.h (assign): Allow operations like a = 1; a(2:3) = [1;2]
+	to succeed.
+
+Thu Dec 18 14:53:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (IDX_VEC_REP::sort): Don't do anything unless len > 1.
+	(make_uniq): Likewise.
+
+Fri Dec 12 10:58:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (octave_ieee_init): Check for linux before __alpha__.
+
+Sun Nov 30 14:59:12 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc: Include cmath and lo-specfun.h, not oct-math.h.
+
+	* lo-specfun.h, lo-specfun.cc: New files.
+	* Makefile.in (INCLUDES, SOURCES): Add them to the lists.
+
+	* acosh.c, asinh.c, atanh.c, erf.c, erfc.c, gamma.c, lgamma.c,
+	oct-math.h: Delete.
+	* Makefile.in (SOURCES): Delete them from the list.
+
+Wed Nov 26 20:02:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-sysdep.cc (octave_getcwd): Prefer getcwd over getwd.
+
+Wed Nov 19 02:30:04 1997  Mumit Khan  <khan at dhaka.xraylith.wisc.edu>
+
+	Changes to make support egcs snapshots that implement explicit
+	specification of template functions according to CD2.
+
+	* MArray.h: If NEED_TEMPLATE_FCN_SPECS is defined, add explicit
+	template function specs for template friends.
+	* MArray2.h: Likewise.
+	* MDiagArray2.h: Likewise.
+
+Thu Nov 13 21:57:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (sumsq): Compute equivalent of sum (x .* conj (x))
+
+Thu Oct  2 17:13:02 1997  Mumit Khan  <khan at dhaka.xraylith.wisc.edu>
+
+	* CRowVector.cc (linspace): Removed attempt for implicit conversion 
+	to complex<double>(int) instead of complex<double>(double).
+
+	* lo-mappers.cc (atanh): Ditto.
+
+Thu Jul 31 22:13:54 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (IDX_VEC_REP::sort): New function.
+	* idx-vector.h (idx_vector::sort): Ditto.
+	* Array2-idx.h (Array2<T>::maybe_delete_elements): Use it before
+	trying to delete elements specified by the index vectors.
+
+Fri Jul 25 17:31:26 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::lssolve): Increase lwork by factor of 16.
+	* CMatrix.cc (ComplexMatrix::lssolve): Ditto.
+
+Thu Jul 24 14:32:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc (tilde_expand_word): Fix off-by-one error.
+
+Wed Jul  9 19:40:23 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-sysdep.cc (octave_getcwd): If getwd is available, use it.
+	Call error handler if we can't find the current directory.
+
+Mon Jul  7 21:14:41 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (xisnan (double)): Return only 1 or 0.
+	(xfinite (double)): Ditto.
+
+	* dbleQR.cc (QR::init): Don't forget to initialize Q when type is raw.
+	* CmplxQR.cc (ComplexQR::init): Ditto.
+
+Sun Jun 15 21:06:37 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (acos (const Complex&)): Select branch that is
+	compatible with Matlab.
+
+Tue Jun 10 10:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h: Correctly handle empty matrices indexed by a
+	single colon.
+
+Fri Jun  6 04:27:40 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (xlgamma): Use F77_XFCN function to call dlgams.
+	(xgamma): Likewise, for calling xdgamma.
+
+	* FSQP.h, NPSOL.h, QPSOL.h, FSQP.cc, NPSOL.cc, QPSOL.cc: Delete
+	* Makefile.in (INCLUDES, SOURCES): Remove them from the lists.
+
+	* file-ops.cc (file_ops::tilde_expand): Steal more code from bash
+	to do better job expanding tildes.
+
+	* str-vec.cc (string_vector::string_vector (const char * const *):
+	Use temporary variable to compute length.
+
+Thu Jun  5 01:44:43 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Make building of static library optional.
+	(liboctave.$(SHLEXT_VER)): Add $(SONAME_FLAGS) to command.
+
+	* Makefile.in (stamp-picdir): Delete.
+	(pic): New target.  Don't worry so much about creating pic
+	directory only when it is really needed.
+	(stamp-interp): Delete.
+	(libraries): New target.  Depend on shared library directly.
+
+Wed Jun  4 00:08:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.h, pathsearch.cc (dir_pat::set_program_name):
+	New static function.
+
+Mon Jun  2 12:44:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-mappers.cc (fix): Use floor and ceil instead of casting to int.
+
+Thu May 22 16:20:43 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.h, cmd-edit.cc: Rename set_paren_string_delimiters to
+	set_basic_quote_characters, to match new version of readline.
+
+	* cmd-edit.cc (do_restore_terminal_state): Call readline function
+	for restoring terminal state through rl_deprep_term_function, now
+	declared in readline.h
+	(rl_deprep_terminal): Delete declaration.
+
+Wed May 21 16:30:25 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-in): Use new mk-includedir-link macro.
+	(install-lib): Install in $octlibdir.  Use new mk-libdir-link macro.
+
+Thu May 15 11:46:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-edit.cc (command_editor::increment_current_command_number):
+	New static function.
+
+Mon May 12 02:14:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (IDX_VEC_REP::is_colon_equiv): Make it work when
+	the vector is not sorted.
+
+	* CMatrix.cc (ComplexMatrix::operator !): Return boolMatrix.
+	* dMatrix.cc (Matrix::operator !): Likewise
+
+Wed May  7 21:14:06 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-syscalls.h, oct-syscalls.cc: New files.
+
+	* cmd-edit.h, cmd-edit.cc: Handle completion function.
+
+	* str-vec.h, str-vec.cc (string_vector::uniq): New function.
+
+Tue May  6 00:52:02 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES_FOR_INSTALL): New variable.
+	(install-inc): Use it.
+
+	* file-ops.h, file-ops.cc (tempnam): Add DIR and PREFIX args.
+	Handle errors and missing functions consistently.
+
+	* oct-group.h, oct-group.cc: New files.
+
+	* oct-passwd.cc: Handle errors and missing functions consistently.
+
+	* str-vec.h, str-vec.cc (c_str_vec, delete_c_str_vec): New functions.
+
+Mon May  5 17:53:01 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc: (file_ops::tilde_expand): Use new octave_passwd class.
+	* oct-env.cc (octave_env::do_get_user_name): Likewise.
+
+	* oct-passwd.h, oct-passwd.cc: New files.
+
+Sun May  4 22:17:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statdefs.h: Only include sys/types.h if HAVE_SYS_STAT_H is defined.
+
+	* mach-info.h, mach-info.cc: Add missing const qualifiers.
+	(instance_ok ()): New function.
+
+	* glob-match.h, glob-match.cc: Rename from oct-glob.h, oct-glob.cc.
+
+	* cmd-hist.h, cmd-hist.cc: Make it work without GNU readline.
+
+	* lo-utils.h, lo-utils.cc (strsave, octave_putenv): Move here from
+	src/utils.h and src/utils.cc.
+	(octave_fgets): New function, extracted from src/input.cc.
+
+	* cmd-edit.h, cmd-edit.cc: New files.  Provide wrapper class for
+	GNU readline, and allow Octave to work without GNU readline.
+
+	* lo-sysdep.h, lo-sysdep.cc: New files for miscellaneous
+	system-dependent functions.
+
+	* oct-env.h, oct-env.cc: New files for process environment stuff.
+
+	* file-stat.h, file-stat.cc: New files.  Extract file_stat class
+	from file-ops.h and file-ops.cc and move here.
+
+	* file-ops.h, file-ops.cc: Wrap functions in struct.  Move
+	tilde_expand functions here from src/dirfns.cc.
+
+Fri May  2 19:50:12 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathlen.h: New file, from ../src.
+
+Tue Apr 29 04:39:01 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::maybe_delete_elements): Prevent
+	out-of-bounds indexing of the index array.
+	* Array-idx.h (Array<T>::maybe_delete_elements): Likewise.
+
+Fri Mar 28 15:37:09 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.h (x_step_limit): New field.
+	(LSODE_options::init): Initialize it.
+	(LSODE_options::copy): Copy it.
+	(LSODE_options::set_step_limit, LSODE_options::step_limit):
+	New functions.
+	(LSODE::working_too_hard): Delete.
+	* LSODE.cc (LSODE::do_integrate): Handle step limit.
+
+Wed Mar 26 15:31:57 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArray-b.cc: Delete.
+	* Makefile.in: Delete it from the lists.
+
+	* boolMatrix.h (class bboolMatrix): Derive from Array2, not
+	MArray2, since most of the numeric ops don't really make sense.
+
+Tue Mar 25 17:37:25 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* boolMatrix.cc (boolMatrix::all, boolMatrix::any): New functions.
+
+	* dMatrix.cc (Matrix::all, Matrix::any): Return boolMatrix.
+	* CMatrix.cc (ComplexMatrix::all, ComplexMatrix::any): Likewise.
+
+	* idx-vector.h (idx_vector::idx_vector_rep::freeze,
+	idx_vector::freeze): Delete prefer_zero_one arg.
+	* Array-idx.h, Array2-idx.h: Change all callers.
+
+	* Array-flags.h, Array-flags.cc (liboctave_pzo_flag): Delete.
+
+	* mx-op-defs.h: New file for operator definitions.
+	* mx-cdm-cm.h, mx-cdm-cs.h, mx-cdm-dm.h, mx-cdm-m.h, mx-cdm-s.h,
+	mx-cm-cdm.h, mx-cm-dm.h, mx-cm-m.h, mx-cm-s.h, mx-cs-cdm.h,
+	mx-cs-dm.h, mx-cs-m.h, mx-dm-cdm.h, mx-dm-cm.h, mx-dm-cs.h,
+	mx-dm-m.h, mx-dm-s.h, mx-m-cdm.h, mx-m-cm.h, mx-m-cs.h, mx-m-dm.h,
+	mx-s-cdm.h, mx-s-cm.h, mx-s-dm.h, mx-cdm-cm.cc, mx-cdm-cs.cc,
+	mx-cdm-dm.cc, mx-cdm-m.cc, mx-cdm-s.cc, mx-cm-cdm.cc, mx-cm-dm.cc,
+	mx-cm-m.cc, mx-cm-s.cc, mx-cs-cdm.cc, mx-cs-dm.cc, mx-cs-m.cc,
+	mx-dm-cdm.cc, mx-dm-cm.cc, mx-dm-cs.cc, mx-dm-m.cc, mx-dm-s.cc,
+	mx-m-cdm.cc, mx-m-cm.cc, mx-m-cs.cc, mx-m-dm.cc, mx-s-cdm.cc,
+	mx-s-cm.cc, mx-s-dm.cc:
+	New files for mixed-type operations.
+	* Makefiles.in: Add them to the appropriate lists.
+
+	* mx-inlines.cc: Add bool by bool EQ ops.
+
+	* idx-vector.h, idx-vector.cc: Add constructors for bool and
+	boolMatrix types.
+	(idx_vector::maybe_convert_one_zero_to_idx,
+	idx_vector::idx_vector_rep::maybe_convert_one_zero_to_idx):
+	Delete second arg, prefer_zero_one.  Change all callers.
+
+	* boolMatrix.h, boolMatrix.cc: New files.
+	* mx-base.h: Include boolMatrix.h here.
+	* mx-defs.h: Provide forward declaration for boolMatrix here.
+
+	* chMatrix.h, chMatrix.cc: Delete unused junk.
+
+	* dMatrix.h, CMatrix.h: Delete friend declarations for operator+,
+	operator-, operator*, product, and quotient functions.
+	Add constructor for boolMatrix type.
+	* dMatrix.cc, CMatrix.cc: Delete operator+, operator-, operator*,
+	product, and quotient functions.
+
+	* CDiagMatrix.h: Delete friend declarations for operator+,
+	operator-, and product functions.
+	* CDiagMatrix.h: Delete operator+, operator-, and product functions.
+
+	* Array-b.cc: Also instantiate 2d and 2d diagonal arrays.
+
+Fri Mar 14 00:29:46 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* EIG.cc (EIG::hermitian_init (const ComplexMatrix&)): New function.
+	(EIG::init (const ComplexMatrix&)): Call it if arg is hermitian.
+	(EIG::symmetric_init (const Matrix&)): New function.
+	(EIG::init (const Matrix&)): Call it if arg is symmetric.
+
+	* CMatrix.cc (ComplexMatrix::is_hermitian): New function.
+
+Thu Mar 13 17:04:26 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2.cc (is_symmetric): New function.
+	* Array2.h (is_square): New function.
+
+Wed Mar 12 16:59:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-strip): New target.
+
+Mon Mar 10 22:34:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CmplxCHOL.cc, CmplxHESS.cc, CmplxLU.cc, CmplxQR.cc,
+	CmplxQRP.cc, CmplxSCHUR.cc, CmplxSVD.cc, EIG.cc, dbleCHOL.cc,
+	dbleHESS.cc, dbleLU.cc, dbleQR.cc, dbleQRP.cc, dbleSCHUR.cc,
+	dbleSVD.cc: Don't include mx-inlines.cc.
+
+	* mx-inlines.cc: Abuse the preprocessor to eliminate lots of
+	duplicate code.
+
+Sun Mar  9 03:44:52 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleQR.h (QR): Delete extra comma at end of list.
+
+	* prog-args.cc (prog_args::getopt): Add missing const in cast.
+
+	* dbleSVD.h (SVD::type): Delete extra comma at end of list.
+
+	* idx-vector.h (idx_vector): Delete unnecessary idx_vector:: and
+	idx_vecotr_rep:: qualifiers.
+
+	* Array.h (class Array): Delete unnecessary Array<T>:: qualifiers.
+
+	* data-conv.h (save_type): Delete extra comma at end of list.
+
+	* CMatrix.cc, FEGrid.cc, Range.cc, dMatrix.cc, data-conv.cc,
+	dir-ops.cc, file-ops.h, idx-vector.cc, idx-vector.h, lo-ieee.cc,
+	lo-mappers.cc, oct-alloc.cc: Use `static_cast<T> (val)' instead of
+	old C-style `(T) val' casts.
+
+Thu Mar  6 20:20:01 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (operator >>): Return if an error occurs instead of
+	just breaking out of the innermost loop.
+	* CMatrix.cc (operator >>): Likewise.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.5 released.
+
+Fri Feb 28 20:11:23 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CmplxQR.cc (ComplexQR::init): New function.
+	(ComplexQR::ComplexQR): Use it.  Use initializer list too.
+	* CmplxQRP.cc (ComplexQRP::init): New function.
+	Get sizes right in all cases.
+	(ComplexQR::ComplexQRP): Use it.  Use initializer list too.
+
+	* dbleQR.cc (QR::init): New function.
+	(QR::QR): Use it.  Use initializer list too.
+	* dbleQRP.cc (QRP::init): New function.
+	Get sizes right in all cases.
+	(QR::QRP): Use it.  Use initializer list too.
+
+Wed Feb 26 15:46:28 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mach-info.cc (oct_mach_info::string_to_float_format):
+	Recognize "vaxg", not "vax_g".
+
+Fri Feb 21 16:07:56 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (Array2<T>::maybe_delete_elements): Use correct
+	dimension in check for colon equivalent index.
+	* idx-vector.cc (IDX_VEC_REP::is_colon_equiv): A single-element
+	index whose value is 0 is also colon eqivalent for n == 1.
+
+	* lo-ieee.cc (octave_ieee_init): Reorder #ifdef stuff to put
+	system-specific tests first.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+Wed Feb 19 09:42:30 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc: D'oh, it's `extern "C"', not `#extern "C"'.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.3 released.
+
+Fri Feb 14 16:23:47 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (bin-dist): Don't write empty strings to LIBRARIES.
+
+Thu Feb 13 14:35:19 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-prereq): Depend on stamp-picdir.
+	(all): Don't depend on stamp-prereq or stamp-picdir.
+	(liboctave.a, stamp-shared): Do depend on stamp-prereq.
+	(stamp-picdir): Silence noise about making pic.
+	(stamp-shared): Use $(SH_LD) $(SH_LDFLAGS) instead of $(CXX) -shared.
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&, idx_vector&)):
+	Fix typo in last change. 
+
+	* CColVector.cc (ComplexColumnVector::map (d_c_mapper)):
+	Convert from friend (moved from dColVector.cc).
+	* CMatrix.cc (ComplexMatrix::map (d_c_mapper)):
+	Likewise (moved	from dMatrix.cc).
+	* CRowVector.cc (ComplexRowVector::map (d_c_mapper)):
+	Likewise (moved	from dRowVector.cc).
+
+	* dColVector.cc (ColumnVector::map (d_d_mapper)): Convert from friend.
+	* dMatrix.cc (Matrix::map (d_d_mapper)): Likewise.
+	* dRowVector.cc (RowVector::map (d_d_mapper)): Likewise.
+	* CColVector.cc (ComplexColumnVector::map (c_c_mapper)): Likewise.
+	* CMatrix.cc (ComplexMatrix::map (c_c_mapper)): Likewise.
+	* CRowVector.cc (ComplexRowVector::map (c_c_mapper)): Likewise.
+
+	* dColVector.cc (ColumnVector::apply): Rename from map, return *this.
+	* dMatrix.cc (Matrix::apply): Likewise.
+	* dRowVector.cc (RowVector::apply): Likewise.
+	* CColVector.cc (ComplexColumnVector::apply): Likewise.
+	* CMatrix.cc (ComplexMatrix::apply): Likewise.
+	* CRowVector.cc (ComplexRowVector::apply): Likewise.
+
+Tue Feb 11 19:44:28 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc: Declare quiet_nan() and infinity().
+
+Mon Feb 10 01:17:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc (oct_unlink (const string&, string&)):
+	New two-arg version.
+	(oct_rmdir (const string&, string&)): New two-arg version.
+	(oct_mkdir (const string&, mode_t, string&)): New three-arg version.
+	(oct_mkfifo (const string&, mode_t, string&)): New three-arg version.
+	(oct_rename (const string&, const string&, string&)):
+	New three-arg version.
+
+Fri Feb  7 13:15:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.h (idx_vector::orig_empty): New function.
+
+	* Array2-idx.h (Array2<T>::index (idx_vector&, idx_vector&)):
+	Don't always resize to [](0x0) if one of the indices is empty or
+	zero.
+
+Sun Feb  2 22:33:44 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-hist.cc (command_history::read): New arg, must_exist.
+	Set line_in_file here too.
+	(command_history::read_range): New arg, must_exist.
+
+Fri Jan 31 09:21:57 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f2c-main.c: Change C++-style comments to C-style comments.
+
+Tue Jan 28 10:46:02 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-inc): Create a relative symbolic link.
+
+Mon Jan 27 15:52:27 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+Sat Jan 25 22:36:21 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (bin-dist): New target.
+
+Wed Jan 22 16:18:53 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleSVD.cc (SVD::init): Work around apparent dgesvd() bug.
+	* CmplxSVD.cc (ComplexSVD::init): Work around apparent zgesvd() bug.
+
+Mon Jan 20 18:44:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (charMatrix::charMatrix (const string&)):
+	If the number of columns is zero, also set the number of rows to zero.
+	(charMatrix::charMatrix (const char *)): Likewise.
+
+Tue Jan  7 00:16:57 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Sun Jan  5 12:07:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::read): Correctly compute the number of
+	columns for resizing when the number of rows is specified but the
+	number of columns is not.
+
+Wed Dec 18 16:18:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (operator -): New function.
+
+	* lo-ieee.cc: Include <nan.h> on all systems that have it.
+
+Fri Dec 13 02:01:32 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign): Delay resizing left hand side until we
+	know if the assignment conforms.
+
+Tue Dec 10 01:43:09 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+Fri Dec  6 14:41:15 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign): If index is a colon, set number of
+	elements to the lhs dimension if the lhs dimension is greater than
+	zero.  Otherwise, set it to the rhs dimension.
+
+	* Version 1.94.
+
+	* Array2-idx.h (assign): Test for rhs scalar case first.
+	If index is colon, set number of elements to lhs dimension, not
+	rhs dimension.
+
+Thu Dec  5 13:05:18 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sun-utils.h: Don't declare MAIN_ or MAIN__ here.
+	* sun-utils.cc: Delete.
+	* f2c-main.c: New file
+
+	* Makefile.in: Fix file name lists.
+
+	* CMatrix.cc (lssolve): Don't redeclare retval, resize it.
+
+Wed Dec  4 12:24:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Qzval): Don't try to use same memory three times.
+	Create result using Complex constructor, not multiplication.
+	Order elements as they are returned from Eispack.
+
+Mon Dec  2 00:26:41 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc (octave_ieee_init): Kluge for octave_Inf on SCO.
+	Only include nan.h if SCO is defined.  Define _IEEE before
+	including it and undefine it afterward.
+	[SCO] (isnan): Don't mistake Inf as NaN.
+
+	* Array-idx.h (assign): Only resize if assignment conforms.
+
+Wed Nov 20 01:00:40 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES): Delete lo-error.h.
+	* lo-error.h: Delete (moved to libcruft/misc).
+
+	* Version 1.93.
+
+Tue Nov 19 23:07:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-glob.cc (glob_match::match): Don't expect our flag values to
+	be the same as they are in fnmatch.h.
+
+	* f77-fcn.c, f77-fcn.h: Move to libcruft/misc directory.
+
+	* Makefile.in (INCLUDES): Delete f77-fcn.h.
+	(SOURCES): Delete f77-fcn.c.
+
+Fri Nov 15 13:47:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.h: [SCO]: Declare isinf and isnan.
+
+Thu Nov 14 00:06:53 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.92.
+
+Wed Nov 13 11:19:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-hist.cc (command_history::add): Ignore empty input lines, or
+	lines that have only carriage return or newline.
+
+	* lo-ieee.cc (isnan, isinf): Provide functions for SCO.
+
+Tue Nov 12 11:11:21 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (idx_is_inf_or_nan): New function.
+	(IDX_VEC_REP::idx_vector_rep): Use it.
+
+Sun Nov 10 17:09:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* str-vec.h, str-vec.cc: Add constructors to make string vectors
+	from vectors of C strings.
+
+	* oct-glob.h, oct-glob.cc (glob_match): Allow pat to be a string
+	vector.
+	(glob_match::match): Allow match string to be a string vector.
+	(glob_match::glob): New function.
+
+	* chMatrix.cc (charMatrix::row_as_string): New arg, strip_ws.
+
+	* Array-b.cc: New file.
+	* Makefile.in (TI_SRC): Add it to the list.
+
+Fri Nov  8 18:09:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc: Change #include "" to #include <> for safe-lstat.h
+	and safe-stat.h, to avoid getting them from $srcdir when we really
+	want the version from the build directory.  (Maybe this should be
+	done for all the include files, not just those that are
+	auto-generated?  Hmm.)
+
+Thu Nov  7 10:45:11 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.91.
+
+	* Array3.cc (Array3<T>::resize): Make it work.
+
+Wed Nov  6 22:44:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-alloc.h, oct-alloc.cc: New files.
+	* Makefile.in: Add them to the lists.
+
+Mon Nov  4 21:49:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleQRP.cc (QRP::QRP): Don't pass tmp data to unsafe constructor.
+	* CmplxQRP.cc (ComplexQRP::ComplexQRP): Ditto.
+
+Sun Nov  3 15:45:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc (file_stat::is_blk, file_stat::is_chr,
+	file_stat::is_dir, file_stat::is_fifo, file_stat::is_lnk,
+	file_stat::is_reg, file_stat::is_sock): Just return false if the
+	underlying macro is not defined.	
+
+	* oct-math.h (lgamma, gamma): Delete declarations.
+	(asinh, acosh, atanh, erf, erfc): Declare arg types too.
+	Protect declarations with #ifdef HAVE_*.
+
+Wed Oct 30 11:42:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* Makefile.in (DISTFILES): Add ChangeLog.
+
+	* cmd-hist.cc: Only include fcntl.h if HAVE_FCNTL_H.
+
+	* Matrix-ext.cc: Include <cfloat>, not <float.h>.
+
+	* CMatrix.cc, cmd-hist.cc, file-ops.cc, file-ops.h, filemode.c,
+	mkdir.c, rename.c, rmdir.c, safe-xstat.cin, statdefs.h, sysdir.h,
+	tempname.c, utils.cc: Only include sys/types.h if HAVE_SYS_TYPES_H.
+
+	* Array3.h (T Array3<T>::checkelem): Return T() for bogus value,
+	since that is now accepatble syntax, even for built-in types.
+	* Array2.h (T Array2<T>::checkelem): Likewise
+
+Sat Oct 26 23:37:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.cc (mkfifo) [! HAVE_MKFIFO]: Just print an error
+	message and return -1.
+
+Fri Oct 25 01:24:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* str-vec.h (str_vec_compare): Declare args as const void *, then
+	cast them to const string * in the body of the function.
+
+	* file-ops.cc (file_stat::mode_as_string): Explicitly construct
+	string from buf.
+
+	* Array3.h (Array3::checkelem): Tag bogus return value with
+	GCC_ATTRIBUTE_UNUSED.
+	* Array2.h (Array2::checkelem): Likewise.
+	
+Thu Oct 24 19:40:36 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Quad.h (Quad): Define virtual destructor.
+
+Tue Oct 15 11:34:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (ComplexMatrix::all_elements_are_real): new function.
+
+Sun Oct 13 11:19:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sun-utils.h: Conditionally declare MAIN__ too.  Declare MAIN_
+	and MAIN__ extern "C".
+	* sun-utils.cc: Include sun-utils.h here.  Delete extern "C" stuff.
+
+Sat Oct 12 12:40:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* MArray-misc.cc: New file.
+	* Makefile.in (MATRIX_SRC): Add it to the list.
+
+	* mx-inlines.cc (equal): Return bool, not int.
+
+	* idx-vector.h (idx_vector (double)): New constructor.
+
+	* chMatrix.h, chMatrix.cc, CMatrix.h, CMatrix.cc, dMatrix.h,
+	dMatrix.cc, dDiagMatrix.h, dDiagMatrix.cc, dRowVector.h,
+	dRowVector.cc, dColVector.h, dColVector.cc, CColVector.h,
+	CColVector.cc, CDiagMatrix.h, CDiagMatrix.cc, CRowVector.h,
+	CRowVector.cc: Logical operators return bool, not int.
+
+	* CMatrix.h, CMatrix.cc (ComplexMatrix::any_element_is_inf_or_nan):
+	New function.
+
+	* dMatrix.h, dMatrix.cc (Matrix::any_element_is_negative,
+	Matrix::any_element_is_inf_or_nan, Matrix::abs,
+	Matrix::all_elements_are_inf_or_nan): New functions.
+
+	* Range.h, Range.cc (Range::all_elements_are_ints): New function.
+
+	* MArray.cc, MArray2.cc, MDiagArray2.cc: Call gripe_nonconformant
+	for errors.  Simplify macros by converting FCN to string for error
+	messages.
+
+	* Array-idx.h (Array<T>::index): New function.  Don't call
+	clear_index() here.
+	(Array<T>::value): Call it, do call clear_index() here.
+	* Array2-idx.h (Array<T>::value, Array<T>::index): Likewise, for
+	one and two arg index functions.
+
+Tue Sep 17 21:21:16 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DAEFunc.h: Delete #pragma interface since there is no longer a
+	separate implementation file.
+
+Tue Aug 20 17:38:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-picdir): Only create a pic subdirectory if
+	SHARED_LIBS is true AND CPICFLAG or CXXPICFLAG is not empty.
+
+	* idx-vector.cc (IDX_VEC_REP::is_colon_equiv): Rename arg sort to
+	sort_uniq.  If sort_uniq is nonzero, sort the elements and make
+	them uniq.
+
+	* CMatrix.cc (ComplexMatrix::row_max, ComplexMatrix::row_min,
+	ComplexMatrix::column_max, ComplexMatrix::column_min):
+	Rewrite.  Also return index as a reference arg.
+	(ComplexMatrix::row_max_loc, ComplexMatrix::row_min_loc,
+	ComplexMatrix::column_max_loc, ComplexMatrix::column_min_loc):
+	Delete.
+
+	* dMatrix.cc (Matrix::row_max, Matrix::row_min,
+	Matrix::column_max, Matrix::column_min):
+	Rewrite.  Also return index as a reference arg.
+	(Matrix::row_max_loc, Matrix::row_min_loc,
+	Matrix::column_max_loc, Matrix::column_min_loc): Delete.
+
+Fri Aug  9 05:01:04 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::row_min, Matrix::row_min_loc,
+	Matrix::row_max, Matrix::row_max_loc, Matrix::column_min,
+	Matrix::column_min_loc, Matrix::column_max,
+	Matrix::column_max_loc): Ignore leading NaNs.
+	* CMatrix.cc (ComplexMatrix::row_min, ComplexMatrix::row_min_loc,
+	ComplexMatrix::row_max, ComplexMatrix::row_max_loc,
+	ComplexMatrix::column_min, ComplexMatrix::column_min_loc,
+	ComplexMatrix::column_max, ComplexMatrix::column_max_loc): Ignore
+	leading NaNs.
+
+Thu Aug  8 16:04:17 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* QPSOL.cc (QPSOL::do_minimize): Insert linear constraint bounds
+	starting at n, not 0.
+
+Sat Jul 27 02:54:44 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::Matrix (const RowVector&),
+	Matrix::Matrix (const ColumnVector&)): New constructors.
+
+	* CMatrix.cc (ComplexMatrix::ComplexMatrix (const RowVector&),
+	ComplexMatrix::ComplexMatrix (const ColumnVector&),
+	ComplexMatrix::ComplexMatrix (const ComplexRowVector&),
+	ComplexMatrix::ComplexMatrix (const ComplexColumnVector&)):
+	New constructors.
+
+	* chMatrix.cc (charMatrix::charMatrix (const string_vector&)):
+	New constructor.
+
+Wed Jul 24 16:39:16 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* LSODE.cc (do_integrate): Check to make sure that the state and
+	derivative vectors are the same size.
+	* DASSL.cc (do_integrate): Likewise.
+
+Sun Jul 14 17:30:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::read, Matrix::write): Convert to use
+	iostreams and handler data format conversions.  Delete old methods
+	that used stdio.
+
+	* data-conv.h, data-conv.cc (oct_data_conv): New class.
+
+Fri Jul 12 13:52:44 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mach-info.h: Rename from float-fmt.h.
+	* mach-info.cc: Rename from float-fmt.cc.
+	Handle machine information using a singlton class.
+	* Makefile.in: Update appropriate lists.
+
+Tue Jul  9 11:49:10 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-flags.cc: Provide definitions for the flags even if
+	OCTAVE_SOURCE is not defined.
+
+	* Array.h, Array2.h, Array3.h: BOUNDS_CHECKING now affects
+	operator(), not elem().
+	* Array3.h: Move indexing methods here from Array3.cc.
+
+Mon Jun 24 02:30:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array3.cc (checkelem): Fix typo in call to Array2<T>::elem().
+
+	* Makefile.in (install-lib): Use INSTALL_PROGRAM instead of
+	INSTALL_DATA for shared libs.
+
+Thu Jun  6 09:59:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Quad.cc: Include lo-error.h here too.
+
+Mon May 27 12:41:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-ops.h: Include sys/types.h here.
+
+Wed May 22 00:20:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (charMatrix::transpose): Provide definition.
+
+	* Array-idx.h (maybe_delete_elements): Correctly compute number of
+	elements in result.
+	* Array2-idx.h (maybe_delete_elements): Likewise for number of
+	rows and columns in result.
+
+Tue May 21 23:46:09 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleQR.cc (QR::QR): Don't create result from to-be-deleted data.
+	* CmplxQR.cc (ComplexQR::ComplexQR): Likewise.
+
+Fri May 17 03:06:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-inc): Install in octincludedir, not includedir.
+
+Sun May 12 03:40:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (uninstall): Also delete shared library.
+	Split install into install-libs and install-includes.
+	(install-inc): If linkdir is a directory, leave it alone.
+
+	* sun-utils.cc (MAIN__): Define for Linux/ELF systems.
+
+Thu May  2 20:19:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-idx.h (assign): Handle A(:) = X for A undefined or empty.
+	* Array2-idx.h (assign): Likewise.
+
+Tue Apr 30 05:43:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2.cc (Array2<T>::range_error): New functions.
+
+	* Array.h (class Array<T>): elem() and operator() are now
+	equivalent, and do bounds checking by default.
+	* Array2.cc (class Array2<T>): Likewise.
+
+Sat Apr  6 21:26:11 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (maintainer-clean, distclean): Also delete
+	stamp-picdir, stamp-shared, and pic directory.
+	(stamp-prereq): New target.
+
+Fri Mar 29 13:44:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* NPSOL.h (NPSOL_options::set_option (const char *, int)):
+	New function.
+
+	* Array.h, Array.cc (Array<T>::range_error ()): New functions.
+	* Array.h (Array<T>::checkelem): Use them.
+
+	* base-lu.h, base-lu.cc: Parameterize based on types of matrix
+	elements too.
+	* dbleLU.h, dbleLU.cc, CmplxLU.h, CmplxLU.cc: Change to match.
+
+	* MDiagArray2.h (MDiagArray2 (const MArray<T>& a)): Delete.
+
+	* Makefile.in (distclean): Delete so_locations, which is created
+	on DEC Alpha systems.
+
+Sat Mar 23 04:02:53 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (HEAVYWEIGHT_INDEXING): Do define this here if it is not
+	already defined.
+
+Fri Mar 22 23:53:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.cc: Include config.h.
+
+Wed Mar 20 04:54:03 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2-idx.h (assign (Array2<LT>&, const Array2<RT>&)): Don't
+	allow M(I, J) = scalar if I or J is empty.
+
+	* Array-idx.h: Delete Array2 and Array3 code (now in Array2-idx.h
+	and Array3-idx.h).
+
+Thu Mar  7 10:20:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-error.h: Make comments C friendly.
+
+Sun Mar  3 14:04:32 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2.h (make_unique): Move all indexing functions here.
+	* Array2.cc: From here.
+
+	* Array.h, Array2.h (NO_BOUNDS_CHECKING): New macro to control
+	whether operator() calls elem or checkelem.
+
+	* Array.h (make_unique): New private function.
+	Move all indexing functions here.
+	* Array.cc: From here.
+
+	* pathsearch.cc (dir_path::find_all): Index tmp, don't dereference
+	it too.
+
+	* Array-d.cc, Array-ch.cc, Array-C.cc, Array-s.cc, Array-str.cc,
+	Array-i.cc, MArray-i.cc, MArray-s.cc, MArray-d.cc, MArray-ch.cc,
+	MArray-C.cc: Include config.h.
+
+	* Array.h, Array2.h, DiagArray2.h, Array3.h:
+	Don't define HEAVYWEIGHT_INDEXING here.
+
+Sat Mar  2 18:39:35 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* base-lu.h, base-lu.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	* dbleLU.h, dbleLU.cc, CmplxLU.h, Cmplx.cc: Derive from base_lu.
+
+Fri Mar  1 08:30:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array2.h, Array3.h, DiagArray2.h: New files, extracted from Array.h
+	* Array2-idx.h, Array3-idx.h: New files, extracted from Array-idx.h
+ 	* Array2.cc, Array3.cc, DiagArray2.cc: New files, from Array.cc.
+	* MArray2.h, MDiagArray2.h: New files, extracted from MArray.h.
+	* MArray2.cc, MDiagArray2.cc, MArray-defs.h: New files, from MArray.cc.
+	
+	* MArray.h (INSTANTIATE_MARRAY_FRIENDS): New macro.
+	(INSTANTIATE_MARRAY2_FRIENDS): Likewise.
+	(INSTANTIATE_MDIAGARRAY_FRIENDS): Likewise.
+	* MArray-C.cc, MArray-ch.cc, MArray-c.cc, MArray-i.cc, MArray-s.cc:
+	Simplify using new macros.
+
+Mon Feb 26 03:04:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install): If $(includedir) ends in version string,
+	make link to name that does not include version info.
+
+	* lo-ieee.cc: Include <cmath> here.
+
+Fri Feb 16 20:52:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-ieee.cc, lo-ieee.h: New files.
+	* lo-mappers.cc, lo-mappers.h: New files.
+	* lo-utils.cc, lo-utils.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+Thu Feb 15 22:02:17 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (all_integers, too_large_for_float): New functions.
+	* CMatrix.cc (all_integers, too_large_for_float): New functions.
+
+	* byte-swap.h, data-conv.h, data-conv.cc, float-fmt.h,
+	float-fmt.cc: New files.
+	* Makefile.in: Include them in the appropriate lists.
+
+Wed Feb 14 01:49:47 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Qzval): New function.
+
+Tue Feb 13 12:41:54 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* NPSOL.cc (NPSOL_options::set_option): Arg key is now string, not
+	char*.
+
+	* DASSL.h, DASSL.cc: Do better management of temporary workspace.
+	Use F77_XFCN to call Fortran subroutine.
+	* dColVector.cc, CColVector.cc: Likewise.
+	* dRowVector.cc, CRowVector.cc: Likewise.
+	* NPSOL.h, NPSOL.cc: Likewise.
+	* CmplxCHOL.cc: Likewise.
+	* dbleCHOL.cc: Likewise.
+	* CMatrix.cc: Likewise.
+	* dMatrix.cc: Likewise.
+	* QPSOL.cc: Likewise.
+	* LSODE.cc: Likewise.
+
+Sun Feb 11 14:14:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleHESS.cc (HESS::init): Dimension of tau is n-1, not n+1.
+
+	* dbleSCHUR.h, dbleSCHUR.cc: Do better management of temporary
+	workspace.  Use F77_XFCN to call Fortran subroutine.
+	* CmplxAEPBAL.h, CmplxAEPBAL.cc: Likewise.
+	* CmplxSCHUR.h, CmplxSCHUR.cc: Likewise.
+	* dbleGEPBAL.h, dbleGEPBAL.cc: Likewise.
+	* dbleAEPBAL.h, dbleAEPBAL.cc: Likewise.
+	* CmplxHESS.h, CmplxHESS.cc: Likewise.
+	* CmplxSVD.h, CmplxSVD.cc: Likewise.
+	* dbleHESS.h, dbleHESS.cc: Likewise.
+	* dbleSVD.h, dbleSVD.cc: Likewise.
+	* EIG.h, EIG.cc; Likewise.
+	* CollocWt.cc: Likewise.
+	* NLEqn.cc: Likewise.
+	* Quad.cc: Likewise.
+
+Sat Feb 10 12:14:59 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleLU.h, dbleLU.cc: Do better management of temporary workspace.
+	Use F77_XFCN to call Fortran subroutine.
+	* CmplxLU.h, CmplxLU.cc: Ditto.
+	* dbleQR.h, dbleQR.cc: Ditto.
+	* CmplxQR.h, CmplxQR.cc: Ditto.
+	* dbleQRP.h, dbleQRP.cc: Ditto.
+	* CmplxQRP.h, CmplxQRP.cc: Ditto.
+
+	* dir-ops.h (dir_entry::dir): Declare as void*, not DIR*.
+	(struct DIR): delete forward declaration.
+	(dir_entry::operator = (const dir_entry$)): Protect against
+	copying same object.
+	* dir-ops.cc: Cast dir appropriately.
+
+Fri Feb  9 16:12:44 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lo-error.cc: Moved to libcruft/misc.
+	* Makefile.in: Delete it from the list.
+
+	* f77-fcn.c (f77_context, f77_exception_encountered): Delete
+	definitions (they have been moved to libcruft/misc/f77-extern.cc).
+
+	* Array-flags.h: New file.
+	* Array-idx.h: Include it here.
+	* Makefile.in (MATRIX_INC): Add it to the list.
+
+	* Array-flags.cc: Renamed from Array-ext.cc.
+	(liboctave_dfi_flag): Renamed from dfi_flag.
+	(liboctave_pcv_flag): Renamed from pcv_flag.
+	(liboctave_pzo_flag): Renamed from pzo_flag.
+	(liboctave_rre_flag): Renamed from rre_flag.
+	* Array-idx.h: Change all uses of dfi_flag, etc.
+	* Makefile.in (MATRIX_SRC): Change file name here too.
+
+	* Makefile.in (LIBOCTAVE_LFLAGS, LIBOCTAVE_LIBS): New variables.
+	(stamp-shared): Use them here.
+
+Tue Feb  6 09:53:41 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-hist.cc (command_history::ignore_entries): Delete default
+	argument value.
+
+Mon Feb  5 12:07:50 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CmplxAEPBAL.h, CmplxCHOL.h, CmplxDET.h, CmplxHESS.h, CmplxLU.h,
+	CmplxQR.h, CmplxQRP.h, CmplxSCHUR.h, CmplxSVD.h, dbleAEPBAL.h,
+	dbleCHOL.h, dbleDET.h, dbleGEPBAL.h, dbleHESS.h, dbleLU.h,
+	dbleQR.h, dbleQRP.h, dbleSCHUR.h, dbleSVD.h:
+	Clean up constructors, assigment operator.
+
+Sun Feb  4 03:12:04 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* NPSOL.cc (do_minimize): Use F77_XFCN to call npsol.
+	Check f77_exception_encountered on return.
+
+	* f77-fcn.c (f77_exception_encountered): New variable.
+	(F77_XFCN): Set it.
+	* f77-fcn.h: Provide declaration.
+
+	* QPSOL.h (QPSOL_options::set_options): Renamed from copy().
+
+	* NPSOL.h (NPSOL_options::set_options): Renamed from copy().
+
+	* NLEqn.h (NLEqn_options::set_options): New function.
+	* Quad.h (Quad_options::set_options): Likewise.
+
+	* LP.h (class LP): Add accessors for LP data.
+
+	* NLEqn.h (NLEqn::n): Delete.
+
+	* NLEqn.h (class NLEqn::n): Likewise.
+
+	* NLP.h (class NLP): Add accessors for NLP data.
+
+	* NPSOL.h (class NPSOL_options): Move constructors, set, and
+	access functions here.
+	* NPSOL.cc.cc: From here.
+
+	* QLD.h (class QLD): Add destructor definition.
+	* Objective.h (class Objective): Likewise.
+	* ODEFunc.h (class ODEFunc): Likewise.
+	* NLFunc.h (class NLFunc): Likewise.
+	* NLEqn.h (class NLEqn): Likewise.
+	* NLConst.h (class NLConst): Likewise.
+	* LinConst.h (class LinConst): Likewise.
+	* LSODE.h (class LSODE_options): Likewise.
+	* CollocWt.h (class CollocWt): Likewise.
+	* Bounds.h (class Bounds): Likewise.
+
+	* QLD.cc (QLD::set_default_options): Delete.
+
+	* QP.h (QP): Add accessors for QP data.
+	Add copy constructor, operator =, and destructor definitions.
+
+	* Range.h, Quad.h, QP.h, QLD.h, Objective.h, NLP.h, NLFunc.h,
+	NLConst.h, LinConst.h, LSODE.h, LP.h, FEGrid.h, EIG.h, DASSL.h,
+	DAEFunc.h, CollocWt.h, Bounds.h:
+	Clean up constructors, assigment operator.
+	
+	* dRowVector.cc (RowVector::transpose): Use magic of reference
+	counting to avoid duplicating the data immediately.
+	* dColVector.cc (ColumnVector::transpose): Likewise.
+	* CRowVector.cc (ComplexrowVector::transpose): Likewise.
+	* CColVector.cc (ComplexColumnVector::transpose): Likewise.
+
+Sat Feb  3 01:02:36 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* prog-args.h (prog_args::option_argument): New enum.
+
+	* f77-fcn.h: Rename from f77-uscore.h.
+	(F77_XFCN_ERROR, F77_XFCN): New macros.
+	* f77-fcn.c: New file.
+	* Makefile.in (SOURCES): Add it to the list.
+
+	* ODEFunc.h: Clean up.
+
+	* DASSL.cc, DASSL.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* LSODE.cc, LSODE.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* ODE.cc: Delete.
+	* Makefile.in (SOURCES): Remove from list.
+
+	* base-de.h, DAE.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	* ODE.h: Only define interface for ODE classes.
+	* DAE.h: Only define interface for ODE classes.
+
+	* LPsolve.cc (do_minimize): Print sorry not implemented message.
+	(LPsolve::set_default_options)): Delete
+	* LPsolve.h (class LPsolve): Add operator =, copy constructor, and
+	destructor.
+
+	* LP.h (class LP): Add operator =, copy constructor, and destructor.
+
+	* QPSOL.h (QPSOL::QPSOL (const QPSOL&)): New constructor.
+	(QPSOL::operator =): Call base class operator = instead of assuming
+	we know what to copy.
+
+	* base-min.h (size): New function.
+
+	* NLP.h (NLP::size): Delete.
+	(NLP::NLP (const NLP&)): New constructor.
+	(NLP::operator =): Call base class operator = instead of assuming
+	we know what to copy.
+
+	* NPSOL.h, NPSOL.cc (NPSOL::option): Delete.
+	(class NPSOL): Add operator = and destructor.
+
+	* NPSOL.h: Add NPSOL_options() to list of constructor initalizers.
+
+Fri Feb  2 22:52:55 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (liboctave.a): Depend on $(PICOBJ).
+
+Wed Jan 31 05:29:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Givens, Sylvester, Matrix::expm): New functions.
+	* CMatrix.cc (Givens, Sylvester, ComplexMatrix::expm): Ditto.
+
+Mon Jan 29 00:00:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* prog-args.h, prog-args.cc: New files.
+	* Makefile.in: Add them to lists.
+
+	* getopt.h, getopt.c, getopt1.c: New files.
+	* Makefile.in: Add them to the lists.
+
+	* oct-term.h, oct-term.cc: New files.
+	* Makefile.in: Add them to the lists.
+
+	* str-vec.cc: New file.
+	* Makefile.in (SOURCES): Add it to the list.
+
+	* file-ops.cc (oct_tmpnam): Move here from src/utils.cc.
+
+	* tempname.c, tempnam.c: Move here from src directory.
+	* Makefile.in: Add to lists.
+
+Sun Jan 28 23:06:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cmd-hist.h, cmd-hist.cc: New files.
+	* Makefile.in: Add them to lists.
+
+Thu Jan 25 20:36:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-glob.h, oct-glob.cc: New files.
+	* Makefile.in: Add them to lists.
+
+Wed Jan 24 01:55:08 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.h, pathsearch.cc: New files.
+	* Makefile.in: Add them to lists.
+
+	* dir-ops.h, dir-ops.cc: New files.
+	* sysdir.h: Move here from src directory.
+	* Makefile.in: Add them to lists.
+
+	* Array.h (Array::qsort): Return *this, not void.
+	* str-vec.h (string_vector::qsort): Likewise.
+
+	* chMatrix.cc (row_as_string): Resize result to eliminate
+	unnecessary NULs.
+
+Tue Jan 23 00:40:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* safe-xstat.hin, safe-xstat.cin, statdefs.h, file-ops.h,
+	file-ops.cc, filemode.c, mkdir.c, rmdir.c, rename.c:
+	Files moved here from src directory.
+	* Makefile.in: Add them to lists.  Include appropriate rules.
+
+	* acosh.c, asinh.c, atanh.c, erf.c, erfc.c, gamma.c, lgamma.c:
+	Use pointers, not references (this is C code!).
+
+	* oct-math.h: New file.
+	* acosh.c, asinh.c, atanh.c, erf.c, erfc.c, gamma.c, lgamma.c:
+	Files moved here from src directory.
+	* Makefile.in: Add them to lists.
+
+Sun Jan 21 22:53:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (make_uniq): Fix major brain-o.
+
+	* CmplxSCHUR.h, CmplxSCHUR.cc, dbleSCHUR.h, dbleSCHUR.cc:
+	Convert	to use string class instead of char*.
+
+	* str-vec.h, Array-str.cc: New files.
+
+	* Array.h (Array::qsort): New function.
+
+Fri Jan 12 01:45:10 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h: Nest ArrayRep class inside Array class.
+	Refer to ArrayRep, not ArrayRep<T>.
+	Move all ArrayRep functions inline.
+	Don't declare other Array classes as friends of ArrayRep.
+	* Array.cc: Delete ArrayRep functions.
+	* Array-idx.h: Refer to ArrayRep, not ArrayRep<T>.
+
+	* Array-C.cc, Array-ch.cc, Array-d.cc, Array-i.cc, Array-s.cc:
+	Don't instantiate ArrayRep objects.
+
+Wed Jan 10 04:40:21 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (charMatrix::charMatrix (const string&)):
+	New constructor.
+
+Tue Jan  9 04:44:56 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleGEPBAL.cc (GEPBALANCE::init): Use string instead of char*
+	for balance_job arg.
+	* dbleAEPBAL.cc (AEPBALANCE::init): Likewise.
+	* CmplxAEPBAL.cc (ComplexAEPBALANCE::init): Likewise.
+
+	* chMatrix.cc (row_as_string): Return string, not const char*.
+
+Mon Jan  8 03:20:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (clean): If $(SHARED_LIBS), also remove shared libs.
+
+	* chMatrix.cc (row_as_string): Undo previous change.
+
+Sun Jan  7 19:50:16 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* chMatrix.cc (row_as_string): Do memory management here.  Caller
+	is expected to save string if necessary.
+
+Sat Jan  6 19:28:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h (class DiagArray): Enable nested Proxy class for all
+	platforms.
+
+	* Array.cc (Array<T>::operator = (const Array<T>&)): If rep ==
+	a.rep, don't mess with count.
+	* Array.h (Array2<T>& operator = (const Array2<T>&)): Likewise,
+	don't do anything if reps are the same.
+	(Array3<T>& operator = (const Array3<T>&)
+
+	* Array.h (ArrayRep<T>::operator = (const ArrayRep<T>&)):
+	Declare private with no definition to prevent misuse.
+
+	* Array.cc (Array2<T>::insert (const Array2<T>&, int, int)):
+	Get range check right.
+	* dMatrix.cc (Matrix::insert (const RowVector&, int, int)): Ditto.
+	(Matrix::insert (const ColumnVector&, int, int)): Ditto.
+	(Matrix::insert (const DiagMatrix&, int, int)): Ditto.
+	* CMatrix.cc (ComplexMatrix::insert (const Matrix&, int, int)): Ditto.
+	(ComplexMatrix::insert (const RowVector&, int, int)): Ditto.
+	(ComplexMatrix::insert (const ColumnVector&, int, int)): Ditto.
+	(ComplexMatrix::insert (const DiagMatrix&, int, int)): Ditto.
+	(ComplexMatrix::insert (const ComplexRowVector&, int, int)): Ditto.
+	(ComplexMatrix::insert (const ComplexColumnVector&, int, int)): Ditto.
+	(ComplexMatrix::insert (const ComplexDiagMatrix&, int, int)): Ditto.
+	* dRowVector.cc (RowVector::insert (const RowVector&, int)): Ditto.
+	* dColVector.cc
+	(ColumnVector::insert (const ColumnVector&, int)): Ditto.
+	* CRowVector.cc
+	(ComplexRowVector::insert (const RowVector&, int)): Ditto.
+	(ComplexRowVector::insert (const ComplexRowVector&, int)): Ditto.
+	* CColVector.cc
+	(ComplexColumnVector::insert (const ColumnVector&, int)): Ditto.
+	(ComplexColumnVector::insert (const ComplexColumnVector&, int)): Ditto.
+
+	* dMatrix.cc (Matrix::insert (const DiagMatrix&, int, int)):
+	Also fill in zeros, not just the diagonal.
+
+	* CDiagMatrix.cc (ComplexDiagMatrix::fill (double, int, int)):
+	Use END parameter properly.
+	(ComplexDiagMatrix::fill (const Complex&, int, int)): Ditto.
+	* dDiagMatrix.cc (DiagMatrix::fill (double, int, int)): Ditto.
+
+	* Array.h (ArrayRep<T>::ArrayRep (void)): Set count to 1 here.
+	(ArrayRep<T>::ArrayRep (T *, int)): Likewise.
+	* Array.cc (ArrayRep<T>::ArrayRep (const ArrayRep<T>&)):
+	Don't copy count.  Set it to 1.
+	(ArrayRep<T>::ArrayRep (int)): Set count to 1 here.
+
+	* Array.h (Array<T>::Array (T *, int)): After constructing rep,
+	don't set rep->count to 1 here (now handled by ArrayRep
+	constructors).
+	(Array<T>::Array (void)): Ditto.
+	(Array<T>::Array (int)): Ditto.
+	(Array<T>::T& elem (int)): Ditto.
+	* Array-idx.h (Array<T>::maybe_delete_elements (idx_vector&)): Ditto.
+	(Array2<T>::maybe_delete_elements (idx_vector&, idx_vector&)): Ditto.
+	* Array.cc: (Array<T>::Array (int, const T&)): Ditto.
+	(Array<T>::resize (int)): Ditto.
+	(Array<T>::resize (int, const T&)) :Ditto.
+	(Array<T>::fortran_vec (void)): Ditto.
+	(Array2<T>::resize (int, int)): Ditto.
+	(Array2<T>::resize (int, int, const T&)): Ditto.
+	(DiagArray<T>::resize (int, int)): Ditto.
+	(DiagArray<T>::resize (int, int, const T&)): Ditto.
+
+Sun Dec 31 21:23:26 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-ch.cc: Rename from Array-c.cc.
+	* MArray-ch.cc: Rename from MArray-c.cc.
+	* chMatrix.cc: Rename from cMatrix.cc.
+	* chMatrix.h: Rename from cMatrix.h.
+	* Makefile.in (TI_SRC): Use new names here.
+	* mx-base.h: Likewise.
+
+Fri Dec 29 21:45:00 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Handle shared libraries.
+
+Thu Dec 28 14:18:34 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CRowVector.cc (operator * (ComplexRowVector, ComplexMatrix)):
+	Correctly compute length of return value.  Correct rows and
+	columns in zgemv call.
+	* dRowVector.cc (operator * (RowVector, Matrix)): Likewise.
+
+Tue Dec 26 00:37:57 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-picdir): New target.
+	(all): Depend on it.
+
+Sun Dec 24 03:10:41 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES): Remove QLD.h.
+	(SOURCES): Remove QLD.cc.
+
+Wed Dec 20 00:43:46 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::inverse): New arg, force.
+ 	If force is nonzero, invert even if matrix is singular.
+	(ComplexMatrix::inverse): Likewise.
+
+	* dRowVector.cc, mx-inlines.cc, dMatrix.cc, dDiagMatrix.cc,
+	dColVector.cc,MArray-C.cc, CmplxDET.cc, CRowVector.cc, CMatrix.cc,
+	CDiagMatrix.cc, CColVector.cc, Array-C.cc, CmplxDET.h, CMatrix.h:
+	Include "oct-cmplx.h" instead of <Complex.h>.
+
+	* mx-defs.h: Include oct-cmplx.h in place of forward declaration
+	for class Complex.
+
+	* oct-cmplx.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+	* idx-vector.cc (IDX_VEC_REP::idx_vector_rep): Don't redeclare len.
+	(IDX_VEC_REP::maybe_convert_one_zero_to_idx): Don't redeclare count.
+	(IDX_VEC_REP::freeze): Don't redeclare max_val and min_val.
+	(intcmp, sort_data, make_uniq, copy_data, IDX_VEC_REP::print):
+	Avoid g++ bugs.
+
+Tue Nov 14 14:24:16 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-idx.h (maybe_delete_elements): Give useful error message.
+
+	* dbleSCHUR.cc, dbleSVD.cc: Include iostream.h.
+
+Mon Nov 13 08:35:07 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CDiagMatrix.cc (inverse): Return retval, not *this.
+	* dDiagMatrix.cc (inverse): Use same method as for Complex case.
+
+Sat Nov  4 05:06:12 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.h, Array.cc, Array-idx.h [HEAVYWEIGHT_INDEXING]: Keep
+	index vector object with Array, not ArrayRep.
+
+Fri Nov  3 06:52:38 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-idx.h (assign (Array2<T>&, const Array2<T>&): Don't fail
+	if index is a colon and resizing is maybe needed.
+
+Tue Oct 31 17:40:01 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.cc (IDX_VEC_REP::is_colon_equiv): Don't return true
+	if we have a vector of 1's.
+
+	* Array-idx.h (assign (Array2<LT>&, Array2<RT>&): If lhs has no
+	current orientation, require index and rhs to conform unless
+	do_fortran_indexing flag is set.
+
+Sun Oct 15 23:32:08 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array-d.cc, Array-C.cc, mx-base.h, mx-inlines.cc, dDiagMatrix.h,
+	CDiagMatrix.h, CMatrix.cc, CMatrix.h, dMatrix.h, mx-defs.h,
+	cMatrix.h, MArray.cc, MArray.h, MArray-i.cc, MArray-c.cc,
+	MArray-s.cc, Array.h, Array.cc, Array-c.cc, Array-i.cc,
+	Array-s.cc, cMatrix.cc, Array-idx.h, dMatrix.cc:
+	Massive changes to support additional data types.  Only charMatrix
+	is currently used in Octave.
+
+Thu Oct 12 02:22:36 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Array.cc (Array2<T>::insert (Array2<T>&, int, int): New function.
+	* CMatrix.cc (ComplexMatrix::insert (ComplexMatrix&, int, int):
+	Simply call Array2<Complex> version.
+	* dMatrix.cc (Matrix::insert (Matrix&, int, int): Similarly, just
+	call Array2<double> version.
+
+	* Array-C.cc, Array-d.cc: Instantiate new assign functions too.
+
+	* Array.h, Array.cc: Massive overhaul to support new way of
+	handling indexing.
+	* idx-vector.h, idx-vector.cc: Likewise.
+	* Array-ext.cc, Array-idx.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+Wed Oct 11 00:49:58 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (nelem_internal): Use tfloor here, not round.
+
+Sun Oct  8 18:21:02 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.h, idx-vector.cc: New files, moved from ../src.
+	* Makefile.in (SOURCES, INCLUDES): Include them in the lists.
+
+Sat Oct  7 19:07:02 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* CMatrix.cc (pseudo_inverse): Avoid bogus g++ warning.
+
+	* Array.h: Move simple member functions here.
+	* Array.cc: From here.
+
+Fri Oct  6 00:36:04 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Range.cc (tfloor, tceil, round): New static functions.
+	(Range::nelem_internal): Rewrite to use better method.
+
+	* dbleSVD.h (SVD::type): New item, sigma_only.
+	(type_computed): New var.
+	* dbleSVD.cc (left_singular_matrix, right_singular_matrix):
+	Handle possible error condition.
+	(init): Allow for SVD::sigma_only, save type computed.
+	* CmplxSVD.cc (left_singular_matrix, right_singular_matrix):
+	Handle possible error condition.
+	(init): Allow for SVD::sigma_only, save type computed.
+
+Wed Oct  4 15:33:35 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Nearly all non-matrix .h and .cc files:
+	Move short function bodies into class declarations for inlining.
+	Generally clean up.
+
+	* base-min.h: New file.
+	* LP.h (class LP): Derive from base_minimizer.
+	* QLP.h (class QLP): Derive from base_minimizer.
+	* NLP.h (class NLP): Derive from base_minimizer.
+	* Makefile.in (INCLUDES): Add base-min.h to the list.
+
+	* Makefile.in (SOURCES): Delete DAEFunc.cc, LP.cc, NLConst.cc,
+	NLFunc.cc, Objective.cc and QP.cc from list.
+
+Tue Sep 26 04:14:23 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dbleSCHUR.cc (select_ana): Remove name of unused parameter.
+	(SCHUR::SCHUR): Delete unused parameter ord.
+	* CmplxSCHUR.h (ComplexSCHUR::CmplxSCHUR): Likewise.
+
+	* CRowVector.cc
+ 	(ComplexRowVector::operator+ (const Complex&, const RowVector&),
+	(ComplexRowVector::operator- (const Complex&, const RowVector&),
+	(ComplexRowVector::operator* (const Complex&, const RowVector&),
+	(ComplexRowVector::operator/ (const Complex&, const RowVector&)):
+	Actually do something.
+	
+	* dMatrix.cc (Matrix::lssolve (ComplexMatrix&)): Use dummy vars.
+	(Matrix::lssolve (ComplexMatrix&, int&)): Likewise.
+	(Matrix::lssolve (ComplexMatrix&, int&, int&)): Likewise.
+
+	* Quad.cc (Quad_options::Quad_options (double, double)): New function.
+	* (Quad::Quad (integrand_fcn, double, double): Properly initialize
+	tolerances.
+	
+	* DAE.cc (ddassl_f, ddassl_j): Remove names of unused parameters.
+	* LPsolve.cc (LPsolve::minimize): Likewise.
+	* NPSOL.cc (NPSOL::option, npsol_confun, npsol_objfun): Likewise.
+	* ODE.cc (lsode_f, lsode_j): Likewise.
+	* QPSOL.cc (qphess): Likewise.
+
+Fri Sep 22 04:14:51 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dMatrix.cc: Include <cstring>.
+
+	* Array.cc: Try harder to avoid warnings from gcc in functions
+	that return bogus values after calling the error handler.
+
+Thu Sep 14 00:56:00 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Use `ifndef omit_deps', not `ifndef $(omit_deps)'.
+
+	* Makefile.in (TEMPLATE_SRC): Add Array-i.cc to the list.
+
+Tue Aug 22 00:41:06 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DAE.cc (dassl_f): Add UNUSED attribute for unused parameters.
+	(dassl_j): Likewise.
+	
+	* DAE.cc, NLEqn.cc, NPSOL.cc, ODE.cc, CColVector.cc, CMatrix.cc,
+	dColVector.cc, dMatrix.cc, CmplxLU.cc, dbleLU.cc, QPSOL.cc,
+	Array.cc, CollocWt.cc, FEGrid.h, LinConst.h:
+	Update for change in for loop variable scope for gcc 2.7.0.
+
+Mon Aug 21 19:34:53 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Only include dependency files if $(omit_deps) is
+	not set.
+
+Mon May  1 13:26:00 1995  John Eaton  (jwe at bullwinkle.che.utexas.edu)
+
+	* dbleSCHUR.h dbleSVD.h dbleQRP.h dbleQR.h dbleHESS.h dbleLU.h
+	dbleCHOL.h dbleGEPBAL.h dbleAEPBAL.h dbleDET.h dDiagMatrix.h
+	dColVector.h dMatrix.h dRowVector.h Quad.h Range.h QPSOL.h QLD.h
+	ODEFunc.h QP.h Objective.h NPSOL.h ODE.h NLEqn.h NLFunc.h
+	NLConst.h LinConst.h LPsolve.h LP.h FSQP.h FEGrid.h EIG.h
+	DAEFunc.h CollocWt.h DAE.h CmplxSVD.h CmplxQRP.h CmplxSCHUR.h
+	CmplxHESS.h CmplxDET.h CmplxLU.h CmplxQR.h CmplxCHOL.h
+	CmplxAEPBAL.h CRowVector.h CDiagMatrix.h Bounds.h CColVector.h
+	CMatrix.h dbleSCHUR.cc dbleSVD.cc dbleQRP.cc dbleQR.cc
+	dbleGEPBAL.cc dbleLU.cc dbleHESS.cc dbleDET.cc dbleCHOL.cc
+	dbleAEPBAL.cc dColVector.cc dRowVector.cc dMatrix.cc
+	dDiagMatrix.cc QPSOL.cc Range.cc Quad.cc QP.cc ODEFunc.cc QLD.cc
+	Objective.cc NLEqn.cc ODE.cc NPSOL.cc NLFunc.cc LPsolve.cc
+	NLConst.cc LinConst.cc FSQP.cc FEGrid.cc LP.cc DAE.cc EIG.cc
+	CollocWt.cc DAEFunc.cc CmplxSVD.cc CmplxSCHUR.cc CmplxQRP.cc
+	CmplxLU.cc CmplxQR.cc CmplxHESS.cc CmplxDET.cc CmplxCHOL.cc
+	CmplxAEPBAL.cc CRowVector.cc CColVector.cc CMatrix.cc
+	CDiagMatrix.cc Bounds.cc MArray.h MArray.cc Array.cc Array.h
+	NLP.h: Use pragma interface/implementation. Don't surround
+	contents in extern "C++".
+	* lo-error.h sun-utils.h: Don't surround contents in extern "C++".
+
+Tue Apr 11 10:59:24 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* f77-uscore.h (F77_FCN): Allow for possibility of uppercase
+	identifiers.
+	* utils.cc dbleSVD.cc dbleSCHUR.cc dbleQRP.cc dbleQR.cc dbleLU.cc
+	dbleHESS.cc dbleGEPBAL.cc dbleAEPBAL.cc dRowVector.cc
+	dColVector.cc QLD.cc CmplxSVD.cc CmplxCHOL.cc CmplxHESS.cc
+	CmplxQR.cc CmplxQRP.cc QPSOL.cc CmplxAEPBAL.cc CmplxLU.cc
+	CmplxSCHUR.cc dMatrix.cc CColVector.cc CRowVector.cc dbleCHOL.cc
+	CollocWt.cc NLEqn.cc EIG.cc DAE.cc ODE.cc CMatrix.cc NPSOL.cc
+	Quad.cc: Change usage of F77_FCN to match new definition
+
+	* utils.cc dbleSVD.cc dbleSCHUR.cc dbleQRP.cc dbleQR.cc dbleLU.cc
+	dbleHESS.cc dbleGEPBAL.cc dbleAEPBAL.cc dRowVector.cc
+	dColVector.cc QLD.cc CmplxSVD.cc CmplxCHOL.cc CmplxHESS.cc
+	CmplxQR.cc CmplxQRP.cc QPSOL.cc CmplxAEPBAL.cc CmplxLU.cc
+	CmplxSCHUR.cc dMatrix.cc CColVector.cc CRowVector.cc dbleCHOL.cc
+	CollocWt.cc NLEqn.cc EIG.cc DAE.cc ODE.cc CMatrix.cc NPSOL.cc
+	Quad.cc: Where appropriate, declare Fortran subroutines to take
+	args by reference instead of pointer.  Change all callers.
+
+Sun Apr  9 20:11:56 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* MArray.h (MArray2::~MArray2, MDiagArray::~MDiagArray): New
+	functions.  Make += and -= operators friend functions.
+
+	* Array.h (Array2::~Array2, Array3::~Array3,
+	DiagArray::~DiagArray): New functions.
+
+Wed Apr  5 21:21:13 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (EXTRAS): Don't distribute mx-kludge.cc.
+	(MATRIX_INC): Don't distribute mx-kludge.h.
+
+	* CColVector.h CColVector.cc CDiagMatrix.h CDiagMatrix.cc
+	CMatrix.h CMatrix.cc CRowVector.h CRowVector.cc dColVector.h
+	dColVector.cc dDiagMatrix.h dDiagMatrix.cc dMatrix.h dMatrix.cc
+	dRowVector.h dRowVector.cc:
+	Derive classes from MArray, MArray2, and MDiagArray, not Array,
+	Array2, and DiagArray2.
+	Don't use functions defined in mx-kludge.cc for arithmetic
+	like-type operations on arrays.
+
+	* MArray.cc: Use the classes defined here like-type mathematical
+	operations on Array objects.  Abuse CPP more.
+	* Makefile.in (TEMPLATE_SRC): Add it to the list.
+	(EXTRAS): Delete it from this list.
+
+	* MArray-C.cc, MArray-d.cc: New files.
+	* Makefile.in (TI_SRC): Add them to the list.
+
+Tue Apr  4 14:13:46 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* mx-kludge.cc: Abuse CPP even more.
+
+Mon Apr  3 21:05:30 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Objective.h (objective_function): Add missing const.
+	(gradient_function): Likewise.
+
+	* CColVector.h CColVector.cc CDiagMatrix.h CDiagMatrix.cc
+	CMatrix.h CMatrix.cc CRowVector.h CRowVector.cc dColVector.h
+	dColVector.cc dDiagMatrix.h dDiagMatrix.cc dMatrix.h dMatrix.cc
+	dRowVector.h dRowVector.cc:
+	Reorganize to declare and define friends where they should be,
+	based on the use of private constructors.
+
+Fri Mar 31 10:09:40 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* CRowVector.h (linspace): Add declaration.
+	* dRowVector.h (linspace): Likewise.
+
+	* dMatrix.cc (Matrix::inverse, Matrix::determinant, Matrix::solve):
+	Force result of rcond + 1.0 to be stored.
+	* CMatrix.cc (ComplexMatrix::inverse, ComplexMatrix::determinant,
+	ComplexMatrix::solve): Likewise.
+
+See ChangeLog.1 in the top level directory for earlier changes.
diff --git a/liboctave/CmplxAEPBAL.cc b/liboctave/CmplxAEPBAL.cc
new file mode 100644
index 0000000..7428d85
--- /dev/null
+++ b/liboctave/CmplxAEPBAL.cc
@@ -0,0 +1,109 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007 John W. Eaton
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "CmplxAEPBAL.h"
+#include "dMatrix.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgebal, ZGEBAL) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     Complex*, const octave_idx_type&,
+			     octave_idx_type&, octave_idx_type&, double*,
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+ 
+  F77_RET_T
+  F77_FUNC (zgebak, ZGEBAK) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&,
+			     const octave_idx_type&, const double*,
+			     const octave_idx_type&, Complex*,
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL  F77_CHAR_ARG_LEN_DECL);
+}
+
+ComplexAEPBALANCE::ComplexAEPBALANCE (const ComplexMatrix& a, 
+                                      bool noperm, bool noscal)
+  : base_aepbal<ComplexMatrix, ColumnVector> ()
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("AEPBALANCE requires square matrix");
+      return;
+    }
+
+  octave_idx_type info;
+
+  scale = ColumnVector (n);
+  double *pscale = scale.fortran_vec ();
+
+  balanced_mat = a;
+  Complex *p_balanced_mat = balanced_mat.fortran_vec ();
+
+  job = noperm ? (noscal ? 'N' : 'S') : (noscal ? 'P' : 'B');
+
+  F77_XFCN (zgebal, ZGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, ilo, ihi,
+			     pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+}
+
+ComplexMatrix
+ComplexAEPBALANCE::balancing_matrix (void) const
+{
+  octave_idx_type n = balanced_mat.rows ();
+  ComplexMatrix balancing_mat (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    balancing_mat.elem (i, i) = 1.0;
+
+  Complex *p_balancing_mat = balancing_mat.fortran_vec ();
+  const double *pscale = scale.fortran_vec ();
+
+  octave_idx_type info;
+
+  char side = 'R';
+
+  F77_XFCN (zgebak, ZGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n,
+			     p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return balancing_mat;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxAEPBAL.h b/liboctave/CmplxAEPBAL.h
new file mode 100644
index 0000000..130a42e
--- /dev/null
+++ b/liboctave/CmplxAEPBAL.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexAEPBALANCE_h)
+#define octave_ComplexAEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "base-aepbal.h"
+#include "CMatrix.h"
+#include "dColVector.h"
+
+class
+OCTAVE_API
+ComplexAEPBALANCE : public base_aepbal<ComplexMatrix, ColumnVector>
+{
+public:
+
+  ComplexAEPBALANCE (void) : base_aepbal<ComplexMatrix, ColumnVector> () { }
+
+  ComplexAEPBALANCE (const ComplexMatrix& a, bool noperm = false,
+                     bool noscal = false);
+
+  ComplexAEPBALANCE (const ComplexAEPBALANCE& a) 
+    : base_aepbal<ComplexMatrix, ColumnVector> (a) { }
+
+  ComplexMatrix balancing_matrix (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxCHOL.cc b/liboctave/CmplxCHOL.cc
new file mode 100644
index 0000000..3ec65c7
--- /dev/null
+++ b/liboctave/CmplxCHOL.cc
@@ -0,0 +1,449 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "dMatrix.h"
+#include "dRowVector.h"
+#include "CmplxCHOL.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#ifndef HAVE_QRUPDATE
+#include "dbleQR.h"
+#endif
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zpotrf, ZPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (zpotri, ZPOTRI) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpocon, ZPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, const double&,
+			     double&, Complex*, double*, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (zch1up, ZCH1UP) (const octave_idx_type&, Complex*, const octave_idx_type&,
+                             Complex*, double*);
+
+  F77_RET_T
+  F77_FUNC (zch1dn, ZCH1DN) (const octave_idx_type&, Complex*, const octave_idx_type&,
+                             Complex*, double*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zchinx, ZCHINX) (const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, Complex*, double*, 
+                             octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zchdex, ZCHDEX) (const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, double*);
+
+  F77_RET_T
+  F77_FUNC (zchshx, ZCHSHX) (const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&, 
+                             Complex*, double*);
+#endif
+}
+
+octave_idx_type
+ComplexCHOL::init (const ComplexMatrix& a, bool calc_cond)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler)
+	("ComplexCHOL requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type n = a_nc;
+  octave_idx_type info;
+
+  chol_mat = a;
+  Complex *h = chol_mat.fortran_vec ();
+
+  // Calculate the norm of the matrix, for later use.
+  double anorm = 0;
+  if (calc_cond) 
+    anorm = chol_mat.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+  F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 ("U", 1), n, h, n, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  xrcond = 0.0;
+  if (info != 0)
+    info = -1;
+  else if (calc_cond) 
+    {
+      octave_idx_type zpocon_info = 0;
+
+      // Now calculate the condition number for non-singular matrix.
+      Array<Complex> z (2*n);
+      Complex *pz = z.fortran_vec ();
+      Array<double> rz (n);
+      double *prz = rz.fortran_vec ();
+      F77_XFCN (zpocon, ZPOCON, (F77_CONST_CHAR_ARG2 ("U", 1), n, h,
+				 n, anorm, xrcond, pz, prz, zpocon_info
+				 F77_CHAR_ARG_LEN (1)));
+
+      if (zpocon_info != 0) 
+	info = -1;
+    }
+  else
+    {
+      // If someone thinks of a more graceful way of doing this (or
+      // faster for that matter :-)), please let me know!
+
+      if (n > 1)
+	for (octave_idx_type j = 0; j < a_nc; j++)
+	  for (octave_idx_type i = j+1; i < a_nr; i++)
+	    chol_mat.xelem (i, j) = 0.0;
+    }
+
+  return info;
+}
+
+static ComplexMatrix
+chol2inv_internal (const ComplexMatrix& r)
+{
+  ComplexMatrix retval;
+
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.cols ();
+
+  if (r_nr == r_nc)
+    {
+      octave_idx_type n = r_nc;
+      octave_idx_type info;
+
+      ComplexMatrix tmp = r;
+
+      F77_XFCN (zpotri, ZPOTRI, (F77_CONST_CHAR_ARG2 ("U", 1), n,
+				 tmp.fortran_vec (), n, info
+				 F77_CHAR_ARG_LEN (1)));
+
+      // If someone thinks of a more graceful way of doing this (or
+      // faster for that matter :-)), please let me know!
+
+      if (n > 1)
+	for (octave_idx_type j = 0; j < r_nc; j++)
+	  for (octave_idx_type i = j+1; i < r_nr; i++)
+	    tmp.xelem (i, j) = std::conj (tmp.xelem (j, i));
+
+      retval = tmp;
+    }
+  else
+    (*current_liboctave_error_handler) ("chol2inv requires square matrix");
+
+  return retval;
+}
+
+// Compute the inverse of a matrix using the Cholesky factorization.
+ComplexMatrix
+ComplexCHOL::inverse (void) const
+{
+  return chol2inv_internal (chol_mat);
+}
+
+void
+ComplexCHOL::set (const ComplexMatrix& R)
+{
+  if (R.is_square ()) 
+    chol_mat = R;
+  else
+    (*current_liboctave_error_handler) ("CHOL requires square matrix");
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+ComplexCHOL::update (const ComplexColumnVector& u)
+{
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      ComplexColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (double, rw, n);
+
+      F77_XFCN (zch1up, ZCH1UP, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), rw));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+octave_idx_type
+ComplexCHOL::downdate (const ComplexColumnVector& u)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      ComplexColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (double, rw, n);
+
+      F77_XFCN (zch1dn, ZCH1DN, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), rw, info));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+ComplexCHOL::insert_sym (const ComplexColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      ComplexColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (double, rw, n);
+
+      chol_mat.resize (n+1, n+1);
+
+      F77_XFCN (zchinx, ZCHINX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 j + 1, utmp.fortran_vec (), rw, info));
+    }
+
+  return info;
+}
+
+void
+ComplexCHOL::delete_sym (octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, rw, n);
+
+      F77_XFCN (zchdex, ZCHDEX, (n, chol_mat.fortran_vec (), chol_mat.rows (), 
+                                 j + 1, rw));
+
+      chol_mat.resize (n-1, n-1);
+    }
+}
+
+void
+ComplexCHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (Complex, w, n);
+      OCTAVE_LOCAL_BUFFER (double, rw, n);
+
+      F77_XFCN (zchshx, ZCHSHX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 i + 1, j + 1, w, rw));
+    }
+}
+
+#else
+
+void
+ComplexCHOL::update (const ComplexColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      init (chol_mat.hermitian () * chol_mat 
+            + ComplexMatrix (u) * ComplexMatrix (u).hermitian (), false);
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+static bool
+singular (const ComplexMatrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    if (a(i,i) == 0.0) return true;
+  return false;
+}
+
+octave_idx_type
+ComplexCHOL::downdate (const ComplexColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else
+        {
+          info = init (chol_mat.hermitian () * chol_mat 
+                       - ComplexMatrix (u) * ComplexMatrix (u).hermitian (), false);
+          if (info) info = 1;
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+ComplexCHOL::insert_sym (const ComplexColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else if (u(j).imag () != 0.0)
+        info = 3;
+      else
+        {
+          ComplexMatrix a = chol_mat.hermitian () * chol_mat;
+          ComplexMatrix a1 (n+1, n+1);
+          for (octave_idx_type k = 0; k < n+1; k++)
+            for (octave_idx_type l = 0; l < n+1; l++)
+              {
+                if (l == j)
+                  a1(k, l) = u(k);
+                else if (k == j)
+                  a1(k, l) = std::conj (u(l));
+                else
+                  a1(k, l) = a(k < j ? k : k-1, l < j ? l : l-1);
+              }
+          info = init (a1, false);
+          if (info) info = 1;
+        }
+    }
+
+  return info;
+}
+
+void
+ComplexCHOL::delete_sym (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      ComplexMatrix a = chol_mat.hermitian () * chol_mat;
+      a.delete_elements (1, idx_vector (j));
+      a.delete_elements (0, idx_vector (j));
+      init (a, false);
+    }
+}
+
+void
+ComplexCHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      ComplexMatrix a = chol_mat.hermitian () * chol_mat;
+      Array<octave_idx_type> p (n);
+      for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+      if (i < j)
+        {
+          for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+          p(j) = i;
+        }
+      else if (j < i)
+        {
+          p(j) = i;
+          for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+        }
+
+      init (a.index (idx_vector (p), idx_vector (p)), false);
+    }
+}
+
+#endif
+
+ComplexMatrix
+chol2inv (const ComplexMatrix& r)
+{
+  return chol2inv_internal (r);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxCHOL.h b/liboctave/CmplxCHOL.h
new file mode 100644
index 0000000..d9aa199
--- /dev/null
+++ b/liboctave/CmplxCHOL.h
@@ -0,0 +1,99 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexCHOL_h)
+#define octave_ComplexCHOL_h 1
+
+#include <iosfwd>
+
+#include "CMatrix.h"
+#include "CColVector.h"
+
+class
+OCTAVE_API
+ComplexCHOL
+{
+public:
+
+  ComplexCHOL (void) : chol_mat () { }
+
+  ComplexCHOL (const ComplexMatrix& a, bool calc_cond = false) { init (a, calc_cond); }
+
+  ComplexCHOL (const ComplexMatrix& a, octave_idx_type& info, bool calc_cond = false)
+    {
+      info = init (a, calc_cond);
+    }
+
+  ComplexCHOL (const ComplexCHOL& a)
+    : chol_mat (a.chol_mat), xrcond (a.xrcond) { }
+
+  ComplexCHOL& operator = (const ComplexCHOL& a)
+    {
+      if (this != &a)
+	{
+	  chol_mat = a.chol_mat;
+	  xrcond = a.xrcond;
+	}
+
+      return *this;
+    }
+
+  ComplexMatrix chol_matrix (void) const { return chol_mat; }
+
+  double rcond (void) const { return xrcond; }
+
+  ComplexMatrix inverse (void) const;
+
+  void set (const ComplexMatrix& R);
+
+  void update (const ComplexColumnVector& u);
+
+  octave_idx_type downdate (const ComplexColumnVector& u);
+
+  octave_idx_type insert_sym (const ComplexColumnVector& u, octave_idx_type j);
+
+  void delete_sym (octave_idx_type j);
+
+  void shift_sym (octave_idx_type i, octave_idx_type j);
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexCHOL& a);
+
+private:
+
+  ComplexMatrix chol_mat;
+
+  double xrcond;
+
+  octave_idx_type init (const ComplexMatrix& a, bool calc_cond);
+};
+
+ComplexMatrix OCTAVE_API chol2inv (const ComplexMatrix& r);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxGEPBAL.cc b/liboctave/CmplxGEPBAL.cc
new file mode 100644
index 0000000..f6be4e3
--- /dev/null
+++ b/liboctave/CmplxGEPBAL.cc
@@ -0,0 +1,131 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "CmplxGEPBAL.h"
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zggbal, ZGGBAL) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type& N,
+			     Complex* A, const octave_idx_type& LDA, Complex* B,
+			     const octave_idx_type& LDB, octave_idx_type& ILO, octave_idx_type& IHI,
+			     double* LSCALE, double* RSCALE,
+			     double* WORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dggbak, DGGBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO,
+			     const octave_idx_type& IHI, const double* LSCALE,
+			     const double* RSCALE, octave_idx_type& M, double* V,
+			     const octave_idx_type& LDV, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+}
+
+octave_idx_type
+ComplexGEPBALANCE::init (const ComplexMatrix& a, const ComplexMatrix& b, 
+		  const std::string& balance_job)
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("ComplexGEPBALANCE requires square matrix");
+      return -1;
+    }
+
+  if (a.dims() != b.dims ())
+    {
+      gripe_nonconformant ("ComplexGEPBALANCE", n, n, b.rows(), b.cols());
+      return -1;
+    } 
+
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  OCTAVE_LOCAL_BUFFER (double, plscale, n);
+  OCTAVE_LOCAL_BUFFER (double, prscale,  n);
+  OCTAVE_LOCAL_BUFFER (double, pwork, 6 * n);
+
+  balanced_mat = a;
+  Complex *p_balanced_mat = balanced_mat.fortran_vec ();
+  balanced_mat2 = b;
+  Complex *p_balanced_mat2 = balanced_mat2.fortran_vec ();
+
+  char job = balance_job[0];
+
+  F77_XFCN (zggbal, ZGGBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, p_balanced_mat2,
+			     n, ilo, ihi, plscale, prscale, pwork, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  balancing_mat = Matrix (n, n, 0.0);
+  balancing_mat2 = Matrix (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      OCTAVE_QUIT;
+      balancing_mat.elem (i ,i) = 1.0;
+      balancing_mat2.elem (i ,i) = 1.0;
+    }
+
+  double *p_balancing_mat = balancing_mat.fortran_vec ();
+  double *p_balancing_mat2 = balancing_mat2.fortran_vec ();
+
+  // first left
+  F77_XFCN (dggbak, DGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+      
+  // then right
+  F77_XFCN (dggbak, DGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("R", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat2, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxGEPBAL.h b/liboctave/CmplxGEPBAL.h
new file mode 100644
index 0000000..e53e5f6
--- /dev/null
+++ b/liboctave/CmplxGEPBAL.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexGEPBALANCE_h)
+#define octave_ComplexGEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "CMatrix.h"
+#include "dMatrix.h"
+
+class
+OCTAVE_API
+ComplexGEPBALANCE
+{
+public:
+
+  ComplexGEPBALANCE (void) : balanced_mat (), balancing_mat () { }
+
+  ComplexGEPBALANCE (const ComplexMatrix& a, const ComplexMatrix& b, const std::string& balance_job)
+    {
+      init (a, b, balance_job); 
+    }
+
+  ComplexGEPBALANCE (const ComplexGEPBALANCE& a)
+    : balanced_mat (a.balanced_mat), balanced_mat2 (a.balanced_mat2),
+    balancing_mat (a.balancing_mat), balancing_mat2 (a.balancing_mat2) { }
+
+  ComplexGEPBALANCE& operator = (const ComplexGEPBALANCE& a)
+    {
+      if (this != &a)
+	{
+	  balanced_mat = a.balanced_mat;
+	  balanced_mat2 = a.balanced_mat2;
+	  balancing_mat = a.balancing_mat;
+	  balancing_mat2 = a.balancing_mat2;
+	}
+      return *this;
+    }
+
+  ~ComplexGEPBALANCE (void) { }
+
+  ComplexMatrix balanced_matrix (void) const { return balanced_mat; }
+
+  ComplexMatrix balanced_matrix2 (void) const { return balanced_mat2; }
+
+  Matrix balancing_matrix (void) const { return balancing_mat; }
+
+  Matrix balancing_matrix2 (void) const { return balancing_mat2; }
+
+  friend std::ostream& operator << (std::ostream& os, const ComplexGEPBALANCE& a);
+
+private:
+
+  ComplexMatrix balanced_mat;
+  ComplexMatrix balanced_mat2;
+  Matrix balancing_mat;
+  Matrix balancing_mat2;
+
+  octave_idx_type init (const ComplexMatrix& a, const ComplexMatrix& b, 
+			const std::string& balance_job);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxHESS.cc b/liboctave/CmplxHESS.cc
new file mode 100644
index 0000000..086b082
--- /dev/null
+++ b/liboctave/CmplxHESS.cc
@@ -0,0 +1,127 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxHESS.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgebal, ZGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, Complex*, const octave_idx_type&,
+			     octave_idx_type&, octave_idx_type&, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+ 
+  F77_RET_T
+  F77_FUNC (zgehrd, ZGEHRD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     Complex*, const octave_idx_type&, octave_idx_type&);
+ 
+  F77_RET_T
+  F77_FUNC (zunghr, ZUNGHR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     Complex*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgebak, ZGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, Complex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+octave_idx_type
+ComplexHESS::init (const ComplexMatrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler)
+	("ComplexHESS requires square matrix");
+      return -1;
+    }
+
+  char job = 'N';
+  char side = 'R';
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 32 * n;
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  hess_mat = a;
+  Complex *h = hess_mat.fortran_vec ();
+
+  Array<double> scale (n);
+  double *pscale = scale.fortran_vec ();
+
+  F77_XFCN (zgebal, ZGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, h, n, ilo, ihi, pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  Array<Complex> tau (n-1);
+  Complex *ptau = tau.fortran_vec ();
+
+  Array<Complex> work (lwork);
+  Complex *pwork = work.fortran_vec ();
+
+  F77_XFCN (zgehrd, ZGEHRD, (n, ilo, ihi, h, n, ptau, pwork, lwork, info));
+
+  unitary_hess_mat = hess_mat;
+  Complex *z = unitary_hess_mat.fortran_vec ();
+
+  F77_XFCN (zunghr, ZUNGHR, (n, ilo, ihi, z, n, ptau, pwork,
+			     lwork, info));
+
+  F77_XFCN (zgebak, ZGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n, z, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  // If someone thinks of a more graceful way of
+  // doing this (or faster for that matter :-)),
+  // please let me know!
+
+  if (n > 2)
+    for (octave_idx_type j = 0; j < a_nc; j++)
+      for (octave_idx_type i = j+2; i < a_nr; i++)
+	hess_mat.elem (i, j) = 0;
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxHESS.h b/liboctave/CmplxHESS.h
new file mode 100644
index 0000000..b05a123
--- /dev/null
+++ b/liboctave/CmplxHESS.h
@@ -0,0 +1,81 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexHESS_h)
+#define octave_ComplexHESS_h 1
+
+#include <iosfwd>
+
+#include "CMatrix.h"
+
+class
+OCTAVE_API
+ComplexHESS
+{
+public:
+
+  ComplexHESS (void) : hess_mat (), unitary_hess_mat () { }
+
+  ComplexHESS (const ComplexMatrix& a) { init (a); }
+
+  ComplexHESS (const ComplexMatrix& a, octave_idx_type& info) { info = init (a); }
+
+  ComplexHESS (const ComplexHESS& a)
+    : hess_mat (a.hess_mat), unitary_hess_mat (a.unitary_hess_mat) { }
+
+  ComplexHESS& operator = (const ComplexHESS& a)
+    {
+      if (this != &a)
+	{
+	  hess_mat = a.hess_mat;
+	  unitary_hess_mat = a.unitary_hess_mat;
+	}
+      return *this;
+    }
+
+  ~ComplexHESS (void) { }
+
+  ComplexMatrix hess_matrix (void) const { return hess_mat; }
+
+  ComplexMatrix unitary_hess_matrix (void) const
+    {
+      return unitary_hess_mat;
+    }
+
+  friend std::ostream& operator << (std::ostream& os, const ComplexHESS& a);
+
+private:
+
+  ComplexMatrix hess_mat;
+  ComplexMatrix unitary_hess_mat;
+
+  octave_idx_type init (const ComplexMatrix& a);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxLU.cc b/liboctave/CmplxLU.cc
new file mode 100644
index 0000000..5dc628e
--- /dev/null
+++ b/liboctave/CmplxLU.cc
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxLU.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+// Instantiate the base LU class for the types we need.
+
+#include <base-lu.h>
+#include <base-lu.cc>
+
+template class base_lu <ComplexMatrix>;
+
+// Define the constructor for this particular derivation.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgetrf, ZGETRF) (const octave_idx_type&, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, octave_idx_type*, octave_idx_type&);
+}
+
+ComplexLU::ComplexLU (const ComplexMatrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+  ipvt.resize (mn);
+  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+  a_fact = a;
+  Complex *tmp_data = a_fact.fortran_vec ();
+
+  octave_idx_type info = 0;
+
+  F77_XFCN (zgetrf, ZGETRF, (a_nr, a_nc, tmp_data, a_nr, pipvt, info));
+
+  ipvt -= static_cast<octave_idx_type> (1);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxLU.h b/liboctave/CmplxLU.h
new file mode 100644
index 0000000..67e7d5e
--- /dev/null
+++ b/liboctave/CmplxLU.h
@@ -0,0 +1,62 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexLU_h)
+#define octave_ComplexLU_h 1
+
+#include "base-lu.h"
+#include "dMatrix.h"
+#include "CMatrix.h"
+
+class
+OCTAVE_API
+ComplexLU : public base_lu <ComplexMatrix>
+{
+public:
+
+  ComplexLU (void)
+    : base_lu <ComplexMatrix> () { }
+
+  ComplexLU (const ComplexMatrix& a);
+
+  ComplexLU (const ComplexLU& a)
+    : base_lu <ComplexMatrix> (a) { }
+
+  ComplexLU& operator = (const ComplexLU& a)
+    {
+      if (this != &a)
+	base_lu <ComplexMatrix> :: operator = (a);
+
+      return *this;
+    }
+
+  ~ComplexLU (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxQR.cc b/liboctave/CmplxQR.cc
new file mode 100644
index 0000000..ee91a7b
--- /dev/null
+++ b/liboctave/CmplxQR.cc
@@ -0,0 +1,720 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxQR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "Range.h"
+#include "idx-vector.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgeqrf, ZGEQRF) (const octave_idx_type&, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, Complex*, Complex*,
+			     const octave_idx_type&, octave_idx_type&); 
+
+  F77_RET_T
+  F77_FUNC (zungqr, ZUNGQR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     Complex*, const octave_idx_type&, octave_idx_type&);
+
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (zqr1up, ZQR1UP) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+                             Complex*, Complex*, Complex*, double*);
+
+  F77_RET_T
+  F77_FUNC (zqrinc, ZQRINC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, const Complex*, double*);
+
+  F77_RET_T
+  F77_FUNC (zqrdec, ZQRDEC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, double*);
+
+  F77_RET_T
+  F77_FUNC (zqrinr, ZQRINR) (const octave_idx_type&, const octave_idx_type&, 
+                             Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, const Complex*, double*);
+
+  F77_RET_T
+  F77_FUNC (zqrder, ZQRDER) (const octave_idx_type&, const octave_idx_type&, 
+                             Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, Complex*, double*);
+
+  F77_RET_T
+  F77_FUNC (zqrshc, ZQRSHC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+                             Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&,
+                             Complex*, double*);
+
+#endif
+}
+
+ComplexQR::ComplexQR (const ComplexMatrix& a, QR::type qr_type)
+  : q (), r ()
+{
+  init (a, qr_type);
+}
+
+void
+ComplexQR::init (const ComplexMatrix& a, QR::type qr_type)
+{
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (Complex, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  ComplexMatrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  if (m > 0)
+    {
+      // workspace query.
+      Complex clwork;
+      F77_XFCN (zgeqrf, ZGEQRF, (m, n, afact.fortran_vec (), m, tau, &clwork, -1, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = clwork.real ();
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (Complex, work, lwork);
+      F77_XFCN (zgeqrf, ZGEQRF, (m, n, afact.fortran_vec (), m, tau, work, lwork, info));
+    }
+
+  form (n, afact, tau, qr_type);
+}
+
+void ComplexQR::form (octave_idx_type n, ComplexMatrix& afact, 
+                      Complex *tau, QR::type qr_type)
+{
+  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type info;
+
+  if (qr_type == QR::raw)
+    {
+      for (octave_idx_type j = 0; j < min_mn; j++)
+	{
+	  octave_idx_type limit = j < min_mn - 1 ? j : min_mn - 1;
+	  for (octave_idx_type i = limit + 1; i < m; i++)
+	    afact.elem (i, j) *= tau[j];
+	}
+
+      r = afact;
+    }
+  else
+    {
+      // Attempt to minimize copying.
+      if (m >= n)
+        {
+          // afact will become q.
+          q = afact;
+          octave_idx_type k = qr_type == QR::economy ? n : m;
+          r = ComplexMatrix (k, n);
+          for (octave_idx_type j = 0; j < n; j++)
+            {
+              octave_idx_type i = 0;
+              for (; i <= j; i++)
+                r.xelem (i, j) = afact.xelem (i, j);
+              for (;i < k; i++)
+                r.xelem (i, j) = 0;
+            }
+          afact = ComplexMatrix (); // optimize memory
+        }
+      else
+        {
+          // afact will become r.
+          q = ComplexMatrix (m, m);
+          for (octave_idx_type j = 0; j < m; j++)
+            for (octave_idx_type i = j + 1; i < m; i++)
+              {
+                q.xelem (i, j) = afact.xelem (i, j);
+                afact.xelem (i, j) = 0;
+              }
+          r = afact;
+        }
+
+
+      if (m > 0)
+        {
+          octave_idx_type k = q.columns ();
+          // workspace query.
+          Complex clwork;
+          F77_XFCN (zungqr, ZUNGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     &clwork, -1, info));
+
+          // allocate buffer and do the job.
+          octave_idx_type lwork = clwork.real ();
+	  lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+          OCTAVE_LOCAL_BUFFER (Complex, work, lwork);
+          F77_XFCN (zungqr, ZUNGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     work, lwork, info));
+        }
+    }
+}
+
+ComplexQR::ComplexQR (const ComplexMatrix& q_arg, const ComplexMatrix& r_arg)
+{
+  octave_idx_type qr = q_arg.rows (), qc = q_arg.columns ();
+  octave_idx_type rr = r_arg.rows (), rc = r_arg.columns ();
+  if (qc == rr && (qr == qc || (qr > qc && rr == rc)))
+    {
+      q = q_arg;
+      r = r_arg;
+    }
+  else
+    (*current_liboctave_error_handler) ("QR dimensions mismatch");
+}
+
+QR::type
+ComplexQR::get_type (void) const
+{
+  QR::type retval;
+  if (!q.is_empty () && q.is_square ())
+    retval = QR::std;
+  else if (q.rows () > q.columns () && r.is_square ())
+    retval = QR::economy;
+  else
+    retval = QR::raw;
+  return retval;
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+ComplexQR::update (const ComplexColumnVector& u, const ComplexColumnVector& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      ComplexColumnVector utmp = u, vtmp = v;
+      OCTAVE_LOCAL_BUFFER (Complex, w, k);
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      F77_XFCN (zqr1up, ZQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                 utmp.fortran_vec (), vtmp.fortran_vec (), w, rw));
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+ComplexQR::update (const ComplexMatrix& u, const ComplexMatrix& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      OCTAVE_LOCAL_BUFFER (Complex, w, k);
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      for (volatile octave_idx_type i = 0; i < u.cols (); i++)
+        {
+          ComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          F77_XFCN (zqr1up, ZQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                     utmp.fortran_vec (), vtmp.fortran_vec (), w, rw));
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+ComplexQR::insert_col (const ComplexColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      if (k < m)
+        {
+          q.resize (m, k+1);
+          r.resize (k+1, n+1);
+        }
+      else
+        {
+          r.resize (k, n+1);
+        }
+
+      ComplexColumnVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      F77_XFCN (zqrinc, ZQRINC, (m, n, k, q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (), j + 1, 
+                                 utmp.data (), rw));
+    }
+}
+
+void
+ComplexQR::insert_col (const ComplexMatrix& u, const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      octave_idx_type kmax = std::min (k + nj, m);
+      if (k < m)
+        {
+          q.resize (m, kmax);
+          r.resize (kmax, n + nj);
+        }
+      else
+        {
+          r.resize (k, n + nj);
+        }
+
+      OCTAVE_LOCAL_BUFFER (double, rw, kmax);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          ComplexColumnVector utmp = u.column (jsi(i));
+          F77_XFCN (zqrinc, ZQRINC, (m, n + ii, std::min (kmax, k + ii), 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, 
+                                     utmp.data (), rw));
+        }
+    }
+}
+
+void
+ComplexQR::delete_col (octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      F77_XFCN (zqrdec, ZQRDEC, (m, n, k, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1, rw));
+
+      if (k < m)
+        {
+          q.resize (m, k-1);
+          r.resize (k-1, n-1);
+        }
+      else
+        {
+          r.resize (k, n-1);
+        }
+    }
+}
+
+void
+ComplexQR::delete_col (const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          F77_XFCN (zqrdec, ZQRDEC, (m, n - ii, k == m ? k : k - ii, 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, rw));
+        }
+      if (k < m)
+        {
+          q.resize (m, k - nj);
+          r.resize (k - nj, n - nj);
+        }
+      else
+        {
+          r.resize (k, n - nj);
+        }
+
+    }
+}
+
+void
+ComplexQR::insert_row (const ComplexRowVector& u, octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = std::min (m, n);
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      q.resize (m + 1, m + 1);
+      r.resize (m + 1, n);
+      ComplexRowVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      F77_XFCN (zqrinr, ZQRINR, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), 
+                                 j + 1, utmp.fortran_vec (), rw));
+
+    }
+}
+
+void
+ComplexQR::delete_row (octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (Complex, w, m);
+      OCTAVE_LOCAL_BUFFER (double, rw, m);
+      F77_XFCN (zqrder, ZQRDER, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1,
+                                 w, rw));
+
+      q.resize (m - 1, m - 1);
+      r.resize (m - 1, n);
+    }
+}
+
+void
+ComplexQR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (Complex, w, k);
+      OCTAVE_LOCAL_BUFFER (double, rw, k);
+      F77_XFCN (zqrshc, ZQRSHC, (m, n, k, 
+                                 q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (),
+                                 i + 1, j + 1, w, rw));
+    }
+}
+
+#else
+
+// Replacement update methods.
+
+void
+ComplexQR::update (const ComplexColumnVector& u, const ComplexColumnVector& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      init(q*r + ComplexMatrix (u) * ComplexMatrix (v).hermitian (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+ComplexQR::update (const ComplexMatrix& u, const ComplexMatrix& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      init(q*r + u * v.hermitian (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+static
+ComplexMatrix insert_col (const ComplexMatrix& a, octave_idx_type i,
+                          const ComplexColumnVector& x)
+{
+  ComplexMatrix retval (a.rows (), a.columns () + 1);
+  retval.assign (idx_vector::colon, idx_vector (0, i),
+                 a.index (idx_vector::colon, idx_vector (0, i)));
+  retval.assign (idx_vector::colon, idx_vector (i), x);
+  retval.assign (idx_vector::colon, idx_vector (i+1, retval.columns ()),
+                 a.index (idx_vector::colon, idx_vector (i, a.columns ())));
+  return retval;
+}
+
+static
+ComplexMatrix insert_row (const ComplexMatrix& a, octave_idx_type i,
+                          const ComplexRowVector& x)
+{
+  ComplexMatrix retval (a.rows () + 1, a.columns ());
+  retval.assign (idx_vector (0, i), idx_vector::colon,
+                 a.index (idx_vector (0, i), idx_vector::colon));
+  retval.assign (idx_vector (i), idx_vector::colon, x);
+  retval.assign (idx_vector (i+1, retval.rows ()), idx_vector::colon,
+                 a.index (idx_vector (i, a.rows ()), idx_vector::colon));
+  return retval;
+}
+
+static
+ComplexMatrix delete_col (const ComplexMatrix& a, octave_idx_type i)
+{
+  ComplexMatrix retval = a;
+  retval.delete_elements (1, idx_vector (i));
+  return retval;
+}
+
+static
+ComplexMatrix delete_row (const ComplexMatrix& a, octave_idx_type i)
+{
+  ComplexMatrix retval = a;
+  retval.delete_elements (0, idx_vector (i));
+  return retval;
+}
+
+static
+ComplexMatrix shift_cols (const ComplexMatrix& a, 
+                          octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = a.columns ();
+  Array<octave_idx_type> p (n);
+  for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+  if (i < j)
+    {
+      for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+      p(j) = i;
+    }
+  else if (j < i)
+    {
+      p(j) = i;
+      for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+    }
+
+  return a.index (idx_vector::colon, idx_vector (p));
+}
+
+void
+ComplexQR::insert_col (const ComplexColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_col (q*r, j, u), get_type ());
+    }
+}
+
+void
+ComplexQR::insert_col (const ComplexMatrix& u, const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      ComplexMatrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::insert_col (a, js(i), u.column (i));
+      init (a, get_type ());
+    }
+}
+
+void
+ComplexQR::delete_col (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_col (q*r, j), get_type ());
+    }
+}
+
+void
+ComplexQR::delete_col (const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      ComplexMatrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::delete_col (a, js(i));
+      init (a, get_type ());
+    }
+}
+
+void
+ComplexQR::insert_row (const ComplexRowVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_row (q*r, j, u), get_type ());
+    }
+}
+
+void
+ComplexQR::delete_row (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_row (q*r, j), get_type ());
+    }
+}
+
+void
+ComplexQR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      init (::shift_cols (q*r, i, j), get_type ());
+    }
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxQR.h b/liboctave/CmplxQR.h
new file mode 100644
index 0000000..4ac45bc
--- /dev/null
+++ b/liboctave/CmplxQR.h
@@ -0,0 +1,105 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek              
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexQR_h)
+#define octave_ComplexQR_h 1
+
+#include <iosfwd>
+
+#include "CMatrix.h"
+#include "CColVector.h"
+#include "CRowVector.h"
+#include "dbleQR.h"
+
+
+class
+OCTAVE_API
+ComplexQR
+{
+public:
+
+  ComplexQR (void) : q (), r () { }
+
+  ComplexQR (const ComplexMatrix&, QR::type = QR::std);
+
+  ComplexQR (const ComplexMatrix& q, const ComplexMatrix& r);
+
+  ComplexQR (const ComplexQR& a) : q (a.q), r (a.r) { }
+
+  ComplexQR& operator = (const ComplexQR& a)
+    {
+      if (this != &a)
+	{
+	  q = a.q;
+	  r = a.r;
+	}
+      return *this;
+    }
+
+  ~ComplexQR (void) { }
+
+  void init (const ComplexMatrix&, QR::type = QR::std);
+
+  ComplexMatrix Q (void) const { return q; }
+
+  ComplexMatrix R (void) const { return r; }
+
+  QR::type get_type (void) const;
+
+  void update (const ComplexColumnVector& u, const ComplexColumnVector& v);
+
+  void update (const ComplexMatrix& u, const ComplexMatrix& v);
+
+  void insert_col (const ComplexColumnVector& u, octave_idx_type j);
+
+  void insert_col (const ComplexMatrix& u, const Array<octave_idx_type>& j);
+
+  void delete_col (octave_idx_type j);
+
+  void delete_col (const Array<octave_idx_type>& j);
+
+  void insert_row (const ComplexRowVector& u, octave_idx_type j);
+
+  void delete_row (octave_idx_type j);
+
+  void shift_cols (octave_idx_type i, octave_idx_type j);
+
+  friend std::ostream&  operator << (std::ostream&, const ComplexQR&);
+
+protected:
+
+  void form (octave_idx_type n, ComplexMatrix& afact, 
+             Complex *tau, QR::type qr_type);
+
+  ComplexMatrix q;
+  ComplexMatrix r;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxQRP.cc b/liboctave/CmplxQRP.cc
new file mode 100644
index 0000000..cd31d7b
--- /dev/null
+++ b/liboctave/CmplxQRP.cc
@@ -0,0 +1,111 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "CmplxQRP.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgeqp3, ZGEQP3) (const octave_idx_type&, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, octave_idx_type*, Complex*, Complex*,
+			     const octave_idx_type&, double*, octave_idx_type&);
+}
+
+// It would be best to share some of this code with ComplexQR class...
+
+ComplexQRP::ComplexQRP (const ComplexMatrix& a, QR::type qr_type)
+  : ComplexQR (), p ()
+{
+  init (a, qr_type);
+}
+
+void
+ComplexQRP::init (const ComplexMatrix& a, QR::type qr_type)
+{
+  assert (qr_type != QR::raw);
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (Complex, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  ComplexMatrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  MArray<octave_idx_type> jpvt (n, 0);
+
+  if (m > 0)
+    {
+      OCTAVE_LOCAL_BUFFER (double, rwork, 2*n);
+
+      // workspace query.
+      Complex clwork;
+      F77_XFCN (zgeqp3, ZGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, &clwork, -1, rwork, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = clwork.real ();
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (Complex, work, lwork);
+      F77_XFCN (zgeqp3, ZGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, work, lwork, rwork, info));
+    }
+  else
+    for (octave_idx_type i = 0; i < n; i++) jpvt(i) = i+1;
+
+  // Form Permutation matrix (if economy is requested, return the
+  // indices only!)
+
+  jpvt -= static_cast<octave_idx_type> (1);
+  p = PermMatrix (jpvt, true);
+
+
+  form (n, afact, tau, qr_type);
+}
+
+ColumnVector
+ComplexQRP::Pvec (void) const
+{
+  Array<double> pa (p.pvec ());
+  ColumnVector pv (MArray<double> (pa) + 1.0);
+  return pv;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxQRP.h b/liboctave/CmplxQRP.h
new file mode 100644
index 0000000..6a3d2ea
--- /dev/null
+++ b/liboctave/CmplxQRP.h
@@ -0,0 +1,76 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexQRP_h)
+#define octave_ComplexQRP_h 1
+
+#include <iosfwd>
+
+#include "CmplxQR.h"
+#include "PermMatrix.h"
+#include "dColVector.h"
+
+class
+OCTAVE_API
+ComplexQRP : public ComplexQR
+{
+public:
+
+  ComplexQRP (void) : ComplexQR (), p () { }
+
+  ComplexQRP (const ComplexMatrix&, QR::type = QR::std);
+
+  ComplexQRP (const ComplexQRP& a) : ComplexQR (a), p (a.p) { }
+
+  ComplexQRP& operator = (const ComplexQRP& a)
+    {
+      if (this != &a)
+	{
+	  ComplexQR::operator = (a);
+	  p = a.p;
+	}
+      return *this;
+    }
+
+  ~ComplexQRP (void) { }
+
+  void init (const ComplexMatrix&, QR::type = QR::std);
+
+  PermMatrix P (void) const { return p; }
+
+  ColumnVector Pvec (void) const;
+
+  friend std::ostream&  operator << (std::ostream&, const ComplexQRP&);
+
+private:
+
+  PermMatrix p;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxSCHUR.cc b/liboctave/CmplxSCHUR.cc
new file mode 100644
index 0000000..ee9393a
--- /dev/null
+++ b/liboctave/CmplxSCHUR.cc
@@ -0,0 +1,142 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxSCHUR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgeesx, ZGEESX) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     ComplexSCHUR::select_function,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, Complex*, const octave_idx_type&, octave_idx_type&,
+			     Complex*, Complex*, const octave_idx_type&, double&,
+			     double&, Complex*, const octave_idx_type&, double*, octave_idx_type*,
+			     octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+static octave_idx_type
+select_ana (const Complex& a)
+{
+  return a.real () < 0.0;
+}
+
+static octave_idx_type
+select_dig (const Complex& a)
+{
+  return (abs (a) < 1.0);
+}
+
+octave_idx_type
+ComplexSCHUR::init (const ComplexMatrix& a, const std::string& ord, 
+		    bool calc_unitary)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler)
+	("ComplexSCHUR requires square matrix");
+      return -1;
+    }
+
+  // Workspace requirements may need to be fixed if any of the
+  // following change.
+
+  char jobvs;
+  char sense = 'N';
+  char sort = 'N';
+
+  if (calc_unitary)
+    jobvs = 'V';
+  else
+    jobvs = 'N';
+
+  char ord_char = ord.empty () ? 'U' : ord[0];
+
+  if (ord_char == 'A' || ord_char == 'D' || ord_char == 'a' || ord_char == 'd')
+    sort = 'S';
+
+  if (ord_char == 'A' || ord_char == 'a')
+    selector = select_ana;
+  else if (ord_char == 'D' || ord_char == 'd')
+    selector = select_dig;
+  else
+    selector = 0;
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 8 * n;
+  octave_idx_type info;
+  octave_idx_type sdim;
+  double rconde;
+  double rcondv;
+
+  schur_mat = a;
+  if (calc_unitary)
+    unitary_mat.resize (n, n);
+
+  Complex *s = schur_mat.fortran_vec ();
+  Complex *q = unitary_mat.fortran_vec ();
+
+  Array<double> rwork (n);
+  double *prwork = rwork.fortran_vec ();
+
+  Array<Complex> w (n);
+  Complex *pw = w.fortran_vec ();
+
+  Array<Complex> work (lwork);
+  Complex *pwork = work.fortran_vec ();
+
+  // BWORK is not referenced for non-ordered Schur.
+  Array<octave_idx_type> bwork ((ord_char == 'N' || ord_char == 'n') ? 0 : n);
+  octave_idx_type *pbwork = bwork.fortran_vec ();
+
+  F77_XFCN (zgeesx, ZGEESX, (F77_CONST_CHAR_ARG2 (&jobvs, 1),
+			     F77_CONST_CHAR_ARG2 (&sort, 1),
+			     selector,
+			     F77_CONST_CHAR_ARG2 (&sense, 1),
+			     n, s, n, sdim, pw, q, n, rconde, rcondv,
+			     pwork, lwork, prwork, pbwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxSCHUR.h b/liboctave/CmplxSCHUR.h
new file mode 100644
index 0000000..14f312b
--- /dev/null
+++ b/liboctave/CmplxSCHUR.h
@@ -0,0 +1,88 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexSCHUR_h)
+#define octave_ComplexSCHUR_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "CMatrix.h"
+
+class
+OCTAVE_API
+ComplexSCHUR
+{
+public:
+
+  ComplexSCHUR (void)
+    : schur_mat (), unitary_mat () { }
+
+  ComplexSCHUR (const ComplexMatrix& a, const std::string& ord,
+		bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { init (a, ord, calc_unitary); }
+
+  ComplexSCHUR (const ComplexMatrix& a, const std::string& ord, octave_idx_type& info,
+		bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { info = init (a, ord, calc_unitary); }
+
+  ComplexSCHUR (const ComplexSCHUR& a)
+    : schur_mat (a.schur_mat), unitary_mat (a.unitary_mat) { }
+
+  ComplexSCHUR& operator = (const ComplexSCHUR& a)
+    {
+      if (this != &a)
+	{
+	  schur_mat = a.schur_mat;
+	  unitary_mat = a.unitary_mat;
+	}
+      return *this;
+    }
+
+  ~ComplexSCHUR (void) { }
+
+  ComplexMatrix schur_matrix (void) const { return schur_mat; }
+
+  ComplexMatrix unitary_matrix (void) const { return unitary_mat; }
+
+  friend std::ostream& operator << (std::ostream& os, const ComplexSCHUR& a);
+
+  typedef octave_idx_type (*select_function) (const Complex&);
+
+private:
+
+  ComplexMatrix schur_mat;
+  ComplexMatrix unitary_mat;
+
+  select_function selector;
+
+  octave_idx_type init (const ComplexMatrix& a, const std::string& ord, bool calc_unitary);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxSVD.cc b/liboctave/CmplxSVD.cc
new file mode 100644
index 0000000..9d0bf00
--- /dev/null
+++ b/liboctave/CmplxSVD.cc
@@ -0,0 +1,173 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxSVD.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zgesvd, ZGESVD) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, double*, Complex*, const octave_idx_type&,
+			     Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+			     double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+ComplexMatrix
+ComplexSVD::left_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("ComplexSVD: U not computed because type == SVD::sigma_only");
+      return ComplexMatrix ();
+    }
+  else
+    return left_sm;
+}
+
+ComplexMatrix
+ComplexSVD::right_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("ComplexSVD: V not computed because type == SVD::sigma_only");
+      return ComplexMatrix ();
+    }
+  else
+    return right_sm;
+}
+
+octave_idx_type
+ComplexSVD::init (const ComplexMatrix& a, SVD::type svd_type)
+{
+  octave_idx_type info;
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  ComplexMatrix atmp = a;
+  Complex *tmp_data = atmp.fortran_vec ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  octave_idx_type max_mn = m > n ? m : n;
+
+  char jobu = 'A';
+  char jobv = 'A';
+
+  octave_idx_type ncol_u = m;
+  octave_idx_type nrow_vt = n;
+  octave_idx_type nrow_s = m;
+  octave_idx_type ncol_s = n;
+
+  switch (svd_type)
+    {
+    case SVD::economy:
+      jobu = jobv = 'S';
+      ncol_u = nrow_vt = nrow_s = ncol_s = min_mn;
+      break;
+
+    case SVD::sigma_only:
+
+      // Note:  for this case, both jobu and jobv should be 'N', but
+      // there seems to be a bug in dgesvd from Lapack V2.0.  To
+      // demonstrate the bug, set both jobu and jobv to 'N' and find
+      // the singular values of [eye(3), eye(3)].  The result is
+      // [-sqrt(2), -sqrt(2), -sqrt(2)].
+      //
+      // For Lapack 3.0, this problem seems to be fixed.
+
+      jobu = 'N';
+      jobv = 'N';
+      ncol_u = nrow_vt = 1;
+      break;
+
+    default:
+      break;
+    }
+
+  type_computed = svd_type;
+
+  if (! (jobu == 'N' || jobu == 'O'))
+    left_sm.resize (m, ncol_u);
+
+  Complex *u = left_sm.fortran_vec ();
+
+  sigma.resize (nrow_s, ncol_s);
+  double *s_vec = sigma.fortran_vec ();
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm.resize (nrow_vt, n);
+
+  Complex *vt = right_sm.fortran_vec ();
+
+  octave_idx_type lrwork = 5*max_mn;
+
+  Array<double> rwork (lrwork);
+
+  // Ask ZGESVD what the dimension of WORK should be.
+
+  octave_idx_type lwork = -1;
+
+  Array<Complex> work (1);
+
+  F77_XFCN (zgesvd, ZGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork,
+			     rwork.fortran_vec (), info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  lwork = static_cast<octave_idx_type> (work(0).real ());
+  work.resize (lwork);
+
+  F77_XFCN (zgesvd, ZGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork,
+			     rwork.fortran_vec (), info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm = right_sm.hermitian ();
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CmplxSVD.h b/liboctave/CmplxSVD.h
new file mode 100644
index 0000000..612a1d7
--- /dev/null
+++ b/liboctave/CmplxSVD.h
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ComplexSVD_h)
+#define octave_ComplexSVD_h 1
+
+#include <iosfwd>
+
+#include "dDiagMatrix.h"
+#include "CMatrix.h"
+#include "dbleSVD.h"
+
+class
+OCTAVE_API
+ComplexSVD
+{
+public:
+
+  ComplexSVD (void) { }
+
+  ComplexSVD (const ComplexMatrix& a, SVD::type svd_type = SVD::std)
+    {
+      init (a, svd_type);
+    }
+
+  ComplexSVD (const ComplexMatrix& a, octave_idx_type& info,
+	      SVD::type svd_type = SVD::std)
+    {
+      info = init (a, svd_type);
+    }
+
+  ComplexSVD (const ComplexSVD& a)
+    : type_computed (a.type_computed),
+      sigma (a.sigma), left_sm (a.left_sm), right_sm (a.right_sm) { }
+
+  ComplexSVD& operator = (const ComplexSVD& a)
+    {
+      if (this != &a)
+	{
+	  type_computed = a.type_computed;
+	  sigma = a.sigma;
+	  left_sm = a.left_sm;
+	  right_sm = a.right_sm;
+	}
+      return *this;
+    }
+
+  ~ComplexSVD (void) { }
+
+  DiagMatrix singular_values (void) const { return sigma; }
+
+  ComplexMatrix left_singular_matrix (void) const;
+
+  ComplexMatrix right_singular_matrix (void) const;
+
+  friend std::ostream&  operator << (std::ostream& os, const ComplexSVD& a);
+
+private:
+
+  SVD::type type_computed;
+
+  DiagMatrix sigma;
+  ComplexMatrix left_sm;
+  ComplexMatrix right_sm;
+
+  octave_idx_type init (const ComplexMatrix& a, SVD::type svd_type = SVD::std);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CollocWt.cc b/liboctave/CollocWt.cc
new file mode 100644
index 0000000..d2243f0
--- /dev/null
+++ b/liboctave/CollocWt.cc
@@ -0,0 +1,193 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004,
+              2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "CollocWt.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (jcobi, JCOBI) (octave_idx_type&, octave_idx_type&, octave_idx_type&, octave_idx_type&, double&,
+			   double&, double*, double*, double*,
+			   double*);
+
+  F77_RET_T
+  F77_FUNC (dfopr, DFOPR) (octave_idx_type&, octave_idx_type&, octave_idx_type&, octave_idx_type&, octave_idx_type&, octave_idx_type&,
+			   double*, double*, double*, double*,
+			   double*);
+}
+
+// Error handling.
+
+void
+CollocWt::error (const char* msg)
+{
+  (*current_liboctave_error_handler) ("fatal CollocWt error: %s", msg);
+}
+
+CollocWt&
+CollocWt::set_left (double val)
+{
+  if (val >= rb)
+    {
+      error ("left bound greater than right bound");
+      return *this;
+    }
+
+  lb = val;
+  initialized = 0;
+  return *this;
+}
+
+CollocWt&
+CollocWt::set_right (double val)
+{
+  if (val <= lb)
+    {
+      error ("right bound less than left bound");
+      return *this;
+    }
+
+  rb = val;
+  initialized = 0;
+  return *this;
+}
+
+void
+CollocWt::init (void)
+{
+  // Check for possible errors.
+
+  double wid = rb - lb;
+  if (wid <= 0.0)
+    {
+      error ("width less than or equal to zero");
+      return;
+    }
+
+  octave_idx_type nt = n + inc_left + inc_right;
+
+  if (nt < 0)
+    {
+      error ("total number of collocation points less than zero");
+      return;
+    }
+  else if (nt == 0)
+    return;
+
+  Array<double> dif1 (nt);
+  double *pdif1 = dif1.fortran_vec ();
+
+  Array<double> dif2 (nt);
+  double *pdif2 = dif2.fortran_vec ();
+
+  Array<double> dif3 (nt);
+  double *pdif3 = dif3.fortran_vec ();
+
+  Array<double> vect (nt);
+  double *pvect = vect.fortran_vec ();
+
+  r.resize (nt);
+  q.resize (nt);
+  A.resize (nt, nt);
+  B.resize (nt, nt);
+
+  double *pr = r.fortran_vec ();
+
+  // Compute roots.
+
+  F77_FUNC (jcobi, JCOBI) (nt, n, inc_left, inc_right, Alpha, Beta,
+			  pdif1, pdif2, pdif3, pr);
+
+  octave_idx_type id;
+
+  // First derivative weights.
+
+  id = 1;
+  for (octave_idx_type i = 1; i <= nt; i++)
+    {
+      F77_FUNC (dfopr, DFOPR) (nt, n, inc_left, inc_right, i, id, pdif1,
+			      pdif2, pdif3, pr, pvect); 
+
+      for (octave_idx_type j = 0; j < nt; j++)
+	A (i-1, j) = vect.elem (j);
+    }
+
+  // Second derivative weights.
+
+  id = 2;
+  for (octave_idx_type i = 1; i <= nt; i++)
+    {
+      F77_FUNC (dfopr, DFOPR) (nt, n, inc_left, inc_right, i, id, pdif1,
+			      pdif2, pdif3, pr, pvect); 
+
+      for (octave_idx_type j = 0; j < nt; j++)
+	B (i-1, j) = vect.elem (j);
+    }
+
+  // Gaussian quadrature weights.
+
+  id = 3;
+  double *pq = q.fortran_vec ();
+  F77_FUNC (dfopr, DFOPR) (nt, n, inc_left, inc_right, id, id, pdif1,
+			  pdif2, pdif3, pr, pq);
+
+  initialized = 1;
+}
+
+std::ostream&
+operator << (std::ostream& os, const CollocWt& a)
+{
+  if (a.left_included ())
+    os << "left  boundary is included\n";
+  else
+    os << "left  boundary is not included\n";
+
+  if (a.right_included ())
+    os << "right boundary is included\n";
+  else
+    os << "right boundary is not included\n";
+
+  os << "\n";
+
+  os << a.Alpha << " " << a.Beta << "\n\n"
+     << a.r << "\n\n"
+     << a.q << "\n\n"
+     << a.A << "\n"
+     << a.B << "\n";
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/CollocWt.h b/liboctave/CollocWt.h
new file mode 100644
index 0000000..df98df5
--- /dev/null
+++ b/liboctave/CollocWt.h
@@ -0,0 +1,194 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_CollocWt_h)
+#define octave_CollocWt_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "dColVector.h"
+
+class
+OCTAVE_API
+CollocWt
+{
+public:
+
+  CollocWt (void)
+    : n (0), inc_left (0), inc_right (0), lb (0.0), rb (1.0),
+      Alpha (0.0), Beta (0.0), r (), q (), A (), B (), initialized (0) { }
+
+  CollocWt (octave_idx_type nc, octave_idx_type il, octave_idx_type ir)
+    : n (nc), inc_left (il), inc_right (ir), lb (0.0), rb (1.0),
+      Alpha (0.0), Beta (0.0), r (), q (), A (), B (), initialized (0) { }
+
+  CollocWt (octave_idx_type nc, octave_idx_type il, octave_idx_type ir, double l, double rr)
+    : n (nc), inc_left (il), inc_right (ir), lb (l), rb (rr),
+      Alpha (0.0), Beta (0.0), r (), q (), A (), B (), initialized (0) { }
+
+  CollocWt (octave_idx_type nc, double a, double b, octave_idx_type il, octave_idx_type ir)
+    : n (nc), inc_left (il), inc_right (ir), lb (0.0), rb (1.0),
+      Alpha (a), Beta (b), initialized (0) { }
+
+  CollocWt (octave_idx_type nc, double a, double b, octave_idx_type il, octave_idx_type ir,
+		      double ll, double rr)  
+    : n (nc), inc_left (il), inc_right (ir), lb (ll), rb (rr),
+      Alpha (a), Beta (b), r (), q (), A (), B (), initialized (0) { }
+
+  CollocWt (const CollocWt& a)
+    : n (a.n), inc_left (a.inc_left), inc_right (a.inc_right),
+      lb (a.lb), rb (a.rb), Alpha (a.Alpha), Beta (a.Beta),
+      r (a.r), q (a.q), A (a.A), B (a.B),
+      initialized (a.initialized) { } 
+
+  CollocWt& operator = (const CollocWt& a)
+    {
+      if (this != &a)
+	{
+	  n = a.n;
+	  inc_left = a.inc_left;
+	  inc_right = a.inc_right;
+	  lb = a.lb;
+	  rb = a.rb;
+	  r = a.r;
+	  q = a.q;
+	  A = a.A;
+	  B = a.B;
+	  initialized = a.initialized;
+	}
+      return *this;
+    }
+
+  ~CollocWt (void) { }
+
+  CollocWt& resize (octave_idx_type nc)
+    {
+      n = nc;
+      initialized = 0;
+      return *this;
+    }
+
+  CollocWt& add_left (void)
+    {
+      inc_left = 1;
+      initialized = 0;
+      return *this;
+    }
+
+  CollocWt& delete_left (void)
+    {
+      inc_left = 0;
+      initialized = 0;
+      return *this;
+    }
+
+  CollocWt& set_left (double val);
+
+  CollocWt& add_right (void)
+    {
+      inc_right = 1;
+      initialized = 0;
+      return *this;
+    }
+
+  CollocWt& delete_right (void)
+    {
+      inc_right = 0;
+      initialized = 0;
+      return *this;
+    }
+
+  CollocWt& set_right (double val);
+
+  CollocWt& set_alpha (double val)
+    {
+      Alpha = val;
+      initialized = 0;
+      return *this;
+    }
+
+  CollocWt& set_beta (double val)
+    {
+      Beta = val;
+      initialized = 0;
+      return *this;
+    }
+
+  octave_idx_type ncol (void) const { return n; }
+
+  octave_idx_type left_included (void) const { return inc_left; }
+  octave_idx_type right_included (void) const { return inc_right; }
+
+  double left (void) const { return lb; }
+  double right (void) const { return rb; }
+
+  double width (void) const { return rb - lb; }
+
+  double alpha (void) const { return Alpha; }
+  double beta (void) const { return Beta; }
+
+  ColumnVector roots (void) { if (!initialized) init (); return r; }
+  ColumnVector quad (void) { if (!initialized) init (); return q; }
+
+  ColumnVector quad_weights (void) { return quad (); }
+
+  Matrix first (void) { if (!initialized) init (); return A; }
+
+  Matrix second (void) { if (!initialized) init (); return B; }
+
+  friend std::ostream& operator << (std::ostream&, const CollocWt&);
+
+protected:
+
+  octave_idx_type n;
+
+  octave_idx_type inc_left;
+  octave_idx_type inc_right;
+
+  double lb;
+  double rb;
+
+  double Alpha;
+  double Beta;
+
+  ColumnVector r;
+  ColumnVector q;
+
+  Matrix A;
+  Matrix B;
+
+  int initialized;
+
+  void init (void);
+
+  void error (const char *msg);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DAE.h b/liboctave/DAE.h
new file mode 100644
index 0000000..2226320
--- /dev/null
+++ b/liboctave/DAE.h
@@ -0,0 +1,68 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DAE_h)
+#define octave_DAE_h 1
+
+#include "DAEFunc.h"
+#include "base-dae.h"
+
+class
+OCTAVE_API
+DAE : public base_diff_alg_eqn, public DAEFunc
+{
+public:
+
+  DAE (void)
+    : base_diff_alg_eqn (), DAEFunc () { }
+
+  DAE (const ColumnVector& xx, double tt, DAEFunc& f)
+    : base_diff_alg_eqn (xx, tt), DAEFunc (f) { }
+
+  DAE (const ColumnVector& xx, const ColumnVector& xxdot,
+       double tt, DAEFunc& f)
+    : base_diff_alg_eqn (xx, xxdot, tt), DAEFunc (f) { }
+
+  DAE (const DAE& a)
+    : base_diff_alg_eqn (a), DAEFunc (a){ }
+
+  DAE& operator = (const DAE& a)
+    {
+      if (this != &a)
+	{
+	  base_diff_alg_eqn::operator = (a);
+	  DAEFunc::operator = (a);
+	}
+      return *this;
+    }
+
+  ~DAE (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DAEFunc.h b/liboctave/DAEFunc.h
new file mode 100644
index 0000000..4a791ff
--- /dev/null
+++ b/liboctave/DAEFunc.h
@@ -0,0 +1,111 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2001, 2002, 2005,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DAEFunc_h)
+#define octave_DAEFunc_h 1
+
+#include "oct-types.h"
+
+class Matrix;
+class ColumnVector;
+
+class
+DAEFunc
+{
+public:
+
+  typedef ColumnVector (*DAERHSFunc) (const ColumnVector& x,
+				      const ColumnVector& xdot,
+				      double t, octave_idx_type& ires);
+
+  // This is really the form used by DASSL:
+  //
+  //   PD = DG/DY + CJ * DG/DYPRIME
+
+  typedef Matrix (*DAEJacFunc) (const ColumnVector& x,
+				const ColumnVector& xdot,
+				double t, double cj);
+
+  DAEFunc (void)
+    : fun (0), jac (0), reset (true) { }
+
+  DAEFunc (DAERHSFunc f)
+    : fun (f), jac (0), reset (true) { }
+
+  DAEFunc (DAERHSFunc f, DAEJacFunc j)
+    : fun (f), jac (j), reset (true) { }
+
+  DAEFunc (const DAEFunc& a)
+    : fun (a.fun), jac (a.jac), reset (a.reset) { }
+
+  DAEFunc& operator = (const DAEFunc& a)
+    {
+      if (this != &a)
+	{
+	  fun = a.fun;
+	  jac = a.jac;
+	  reset = a.reset;
+	}
+      return *this;
+    }
+
+  ~DAEFunc (void) { }
+
+  DAERHSFunc function (void) const { return fun; }
+
+  DAEFunc& set_function (DAERHSFunc f)
+    {
+      fun = f;
+      reset = true;
+      return *this;
+    }
+
+  DAEJacFunc jacobian_function (void) const { return jac; }
+
+  DAEFunc& set_jacobian_function (DAEJacFunc j)
+    {
+      jac = j;
+      reset = true;
+      return *this;
+    }
+
+protected:
+
+  DAERHSFunc fun;
+  DAEJacFunc jac;
+
+  // This variable is TRUE when this object is constructed, and also
+  // after any internal data has changed.  Derived classes may use
+  // this information (and change it) to know when to (re)initialize
+  // their own internal data related to this object.
+
+  bool reset;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DAERT.h b/liboctave/DAERT.h
new file mode 100644
index 0000000..c6025c3
--- /dev/null
+++ b/liboctave/DAERT.h
@@ -0,0 +1,74 @@
+/*
+
+Copyright (C) 2002, 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DAERT_h)
+#define octave_DAERT_h 1
+
+#include "DAE.h"
+#include "DAERTFunc.h"
+#include "base-dae.h"
+
+class
+DAERT : public base_diff_alg_eqn, public DAERTFunc
+{
+public:
+
+  DAERT (void)
+    : base_diff_alg_eqn (), DAERTFunc () { }
+
+  DAERT (const ColumnVector& xx, double tt, DAERTFunc& f)
+    : base_diff_alg_eqn (xx, tt), DAERTFunc (f) { }
+
+  DAERT (const ColumnVector& xx, const ColumnVector& xxdot, double tt,
+	DAERTFunc& f)
+    : base_diff_alg_eqn (xx, xxdot, tt), DAERTFunc (f) { }
+
+  DAERT (const DAERT& a)
+    : base_diff_alg_eqn (a), DAERTFunc (a) { }
+
+  DAERT& operator = (const DAERT& a)
+    {
+      if (this != &a)
+	{
+	  base_diff_alg_eqn::operator = (a);
+	  DAERTFunc::operator = (a);
+
+	}
+      return *this;
+    }
+
+  ~DAERT (void) { }
+
+  void initialize (const ColumnVector& xx, const ColumnVector& xxdot,
+		   double tt)
+    {
+      base_diff_alg_eqn::initialize (xx, xxdot, tt);
+    }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DAERTFunc.h b/liboctave/DAERTFunc.h
new file mode 100644
index 0000000..417ead0
--- /dev/null
+++ b/liboctave/DAERTFunc.h
@@ -0,0 +1,93 @@
+/*
+
+Copyright (C) 2002, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DAERTFunc_h)
+#define octave_DAERTFunc_h 1
+
+#include "dMatrix.h"
+
+class
+DAERTFunc : public DAEFunc
+{
+public:
+
+  typedef ColumnVector (*DAERTConstrFunc) (const ColumnVector& x, double t);
+
+  DAERTFunc (void)
+    : DAEFunc (), constr (0), reset (true) { }
+
+  DAERTFunc (DAERHSFunc f)
+    : DAEFunc (f), constr (0), reset (true) { }
+
+  DAERTFunc (DAERHSFunc f, DAEJacFunc j)
+    : DAEFunc (f, j), constr (0), reset (true) { }
+
+  DAERTFunc (DAERHSFunc f, DAERTConstrFunc cf)
+    : DAEFunc (f), constr (cf), reset (true) { }
+
+  DAERTFunc (DAERHSFunc f, DAERTConstrFunc cf, DAEJacFunc j)
+    : DAEFunc (f, j), constr (cf), reset (true) { }
+
+  DAERTFunc (const DAERTFunc& a)
+    : DAEFunc (a), constr (a.constr), reset (a.reset) { }
+
+  DAERTFunc& operator = (const DAERTFunc& a)
+    {
+      if (this != &a)
+	{
+	  DAEFunc::operator = (a);
+	  constr = a.constr;
+	  reset = a.reset;
+	}
+      return *this;
+    }
+
+  ~DAERTFunc (void) { }
+
+  DAERTConstrFunc constraint_function (void) const { return constr; }
+
+  DAERTFunc& set_constraint_function (DAERTConstrFunc cf)
+    {
+      constr = cf;
+      reset = true;
+      return *this;
+    }
+
+protected:
+
+  DAERTConstrFunc constr;
+
+  // This variable is TRUE when this object is constructed, and also
+  // after any internal data has changed.  Derived classes may use
+  // this information (and change it) to know when to (re)initialize
+  // their own internal data related to this object.
+
+  bool reset;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DASPK-opts.h b/liboctave/DASPK-opts.h
new file mode 100644
index 0000000..b969502
--- /dev/null
+++ b/liboctave/DASPK-opts.h
@@ -0,0 +1,203 @@
+// DO NOT EDIT!
+// Generated automatically from DASPK-opts.in.
+
+#if !defined (octave_DASPK_options_h)
+#define octave_DASPK_options_h 1
+
+#include <cfloat>
+#include <cmath>
+
+#include <DAE.h>
+
+
+class
+DASPK_options
+{
+public:
+
+  DASPK_options (void) { init (); }
+
+  DASPK_options (const DASPK_options& opt) { copy (opt); }
+
+  DASPK_options& operator = (const DASPK_options& opt)
+    {
+      if (this != &opt)
+        copy (opt);
+
+      return *this;
+    }
+
+  ~DASPK_options (void) { }
+
+  void init (void)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_relative_tolerance.resize (1);
+      x_relative_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_initial_condition_heuristics.resize (6);
+      x_initial_condition_heuristics(0) = 5.0;
+      x_initial_condition_heuristics(1) = 6.0;
+      x_initial_condition_heuristics(2) = 5.0;
+      x_initial_condition_heuristics(3) = 0.0;
+      x_initial_condition_heuristics(4) = ::pow (DBL_EPSILON, 2.0/3.0);
+      x_initial_condition_heuristics(5) = 0.01;
+      x_algebraic_variables.resize (1);
+      x_algebraic_variables(0) = 0;
+      x_inequality_constraint_types.resize (1);
+      x_inequality_constraint_types(0) = 0;
+      x_initial_step_size = -1.0;
+      x_maximum_order = 5;
+      x_maximum_step_size = -1.0;
+      reset = true;
+    }
+
+  void copy (const DASPK_options& opt)
+    {
+      x_absolute_tolerance = opt.x_absolute_tolerance;
+      x_relative_tolerance = opt.x_relative_tolerance;
+      x_compute_consistent_initial_condition = opt.x_compute_consistent_initial_condition;
+      x_use_initial_condition_heuristics = opt.x_use_initial_condition_heuristics;
+      x_initial_condition_heuristics = opt.x_initial_condition_heuristics;
+      x_print_initial_condition_info = opt.x_print_initial_condition_info;
+      x_exclude_algebraic_variables_from_error_test = opt.x_exclude_algebraic_variables_from_error_test;
+      x_algebraic_variables = opt.x_algebraic_variables;
+      x_enforce_inequality_constraints = opt.x_enforce_inequality_constraints;
+      x_inequality_constraint_types = opt.x_inequality_constraint_types;
+      x_initial_step_size = opt.x_initial_step_size;
+      x_maximum_order = opt.x_maximum_order;
+      x_maximum_step_size = opt.x_maximum_step_size;
+      reset = opt.reset;
+    }
+
+  void set_options (const DASPK_options& opt) { copy (opt); }
+
+  void set_default_options (void) { init (); }
+
+  void set_absolute_tolerance (double val)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_absolute_tolerance (const Array<double>& val)
+    { x_absolute_tolerance = val; reset = true; }
+
+  void set_relative_tolerance (double val)
+    {
+      x_relative_tolerance.resize (1);
+      x_relative_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_relative_tolerance (const Array<double>& val)
+    { x_relative_tolerance = val; reset = true; }
+
+  void set_compute_consistent_initial_condition (octave_idx_type val)
+    { x_compute_consistent_initial_condition = val; reset = true; }
+
+  void set_use_initial_condition_heuristics (octave_idx_type val)
+    { x_use_initial_condition_heuristics = val; reset = true; }
+
+  void set_initial_condition_heuristics (const Array<double>& val)
+    { x_initial_condition_heuristics = val; reset = true; }
+
+  void set_print_initial_condition_info (octave_idx_type val)
+    { x_print_initial_condition_info = val; reset = true; }
+
+  void set_exclude_algebraic_variables_from_error_test (octave_idx_type val)
+    { x_exclude_algebraic_variables_from_error_test = val; reset = true; }
+
+  void set_algebraic_variables (int val)
+    {
+      x_algebraic_variables.resize (1);
+      x_algebraic_variables(0) = val;
+      reset = true;
+    }
+
+  void set_algebraic_variables (const Array<octave_idx_type>& val)
+    { x_algebraic_variables = val; reset = true; }
+
+  void set_enforce_inequality_constraints (octave_idx_type val)
+    { x_enforce_inequality_constraints = val; reset = true; }
+
+  void set_inequality_constraint_types (octave_idx_type val)
+    {
+      x_inequality_constraint_types.resize (1);
+      x_inequality_constraint_types(0) = val;
+      reset = true;
+    }
+
+  void set_inequality_constraint_types (const Array<octave_idx_type>& val)
+    { x_inequality_constraint_types = val; reset = true; }
+
+  void set_initial_step_size (double val)
+    { x_initial_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_maximum_order (octave_idx_type val)
+    { x_maximum_order = val; reset = true; }
+
+  void set_maximum_step_size (double val)
+    { x_maximum_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+  Array<double> absolute_tolerance (void) const
+    { return x_absolute_tolerance; }
+
+  Array<double> relative_tolerance (void) const
+    { return x_relative_tolerance; }
+
+  octave_idx_type compute_consistent_initial_condition (void) const
+    { return x_compute_consistent_initial_condition; }
+
+  octave_idx_type use_initial_condition_heuristics (void) const
+    { return x_use_initial_condition_heuristics; }
+
+  Array<double> initial_condition_heuristics (void) const
+    { return x_initial_condition_heuristics; }
+
+  octave_idx_type print_initial_condition_info (void) const
+    { return x_print_initial_condition_info; }
+
+  octave_idx_type exclude_algebraic_variables_from_error_test (void) const
+    { return x_exclude_algebraic_variables_from_error_test; }
+
+  Array<octave_idx_type> algebraic_variables (void) const
+    { return x_algebraic_variables; }
+
+  octave_idx_type enforce_inequality_constraints (void) const
+    { return x_enforce_inequality_constraints; }
+
+  Array<octave_idx_type> inequality_constraint_types (void) const
+    { return x_inequality_constraint_types; }
+
+  double initial_step_size (void) const
+    { return x_initial_step_size; }
+
+  octave_idx_type maximum_order (void) const
+    { return x_maximum_order; }
+
+  double maximum_step_size (void) const
+    { return x_maximum_step_size; }
+
+private:
+
+  Array<double> x_absolute_tolerance;
+  Array<double> x_relative_tolerance;
+  octave_idx_type x_compute_consistent_initial_condition;
+  octave_idx_type x_use_initial_condition_heuristics;
+  Array<double> x_initial_condition_heuristics;
+  octave_idx_type x_print_initial_condition_info;
+  octave_idx_type x_exclude_algebraic_variables_from_error_test;
+  Array<octave_idx_type> x_algebraic_variables;
+  octave_idx_type x_enforce_inequality_constraints;
+  Array<octave_idx_type> x_inequality_constraint_types;
+  double x_initial_step_size;
+  octave_idx_type x_maximum_order;
+  double x_maximum_step_size;
+
+protected:
+
+  bool reset;
+};
+
+#endif
diff --git a/liboctave/DASPK-opts.in b/liboctave/DASPK-opts.in
new file mode 100644
index 0000000..692576b
--- /dev/null
+++ b/liboctave/DASPK-opts.in
@@ -0,0 +1,319 @@
+# Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+CLASS = "DASPK"
+
+INCLUDE = "DAE.h"
+
+OPTION
+  NAME = "absolute tolerance"
+  DOC_ITEM
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "relative tolerance"
+  DOC_ITEM
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i))
+       <= rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "compute consistent initial condition"
+  DOC_ITEM
+Denoting the differential variables in the state vector by @samp{Y_d}
+and the algebraic variables by @samp{Y_a}, @code{ddaspk} can solve
+one of two initialization problems:
+
+ at enumerate
+ at item Given Y_d, calculate Y_a and Y'_d
+ at item Given Y', calculate Y.
+ at end enumerate
+
+In either case, initial values for the given components are input, and
+initial guesses for the unknown components must also be provided as
+input.  Set this option to 1 to solve the first problem, or 2 to solve
+the second (the default is 0, so you must provide a set of
+initial conditions that are consistent).
+
+If this option is set to a nonzero value, you must also set the
+ at code{\"algebraic variables\"} option to declare which variables in the
+problem are algebraic.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "use initial condition heuristics"
+  DOC_ITEM
+Set to a nonzero value to use the initial condition heuristics options
+described below.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "initial condition heuristics"
+  DOC_ITEM
+A vector of the following parameters that can be used to control the
+initial condition calculation.
+
+ at table @code
+ at item MXNIT
+Maximum number of Newton iterations (default is 5).
+ at item MXNJ
+Maximum number of Jacobian evaluations (default is 6).
+ at item MXNH
+Maximum number of values of the artificial stepsize parameter to be
+tried if the @code{\"compute consistent initial condition\"} option has
+been set to 1 (default is 5).
+
+Note that the maximum total number of Newton iterations allowed is
+ at code{MXNIT*MXNJ*MXNH} if the @code{\"compute consistent initial
+condition\"} option has been set to 1 and @code{MXNIT*MXNJ} if it is
+set to 2.
+ at item LSOFF
+Set to a nonzero value to disable the linesearch algorithm (default is
+0).
+ at item STPTOL
+Minimum scaled step in linesearch algorithm (default is eps^(2/3)).
+ at item EPINIT
+Swing factor in the Newton iteration convergence test.  The test is
+applied to the residual vector, premultiplied by the approximate
+Jacobian.  For convergence, the weighted RMS norm of this vector
+(scaled by the error weights) must be less than @code{EPINIT*EPCON},
+where @code{EPCON} = 0.33 is the analogous test constant used in the
+time steps.  The default is @code{EPINIT} = 0.01.
+ at end table
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (6);
+    $OPTVAR(0) = 5.0;
+    $OPTVAR(1) = 6.0;
+    $OPTVAR(2) = 5.0;
+    $OPTVAR(3) = 0.0;
+    $OPTVAR(4) = ::pow (DBL_EPSILON, 2.0/3.0);
+    $OPTVAR(5) = 0.01;
+  END_INIT_BODY
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "print initial condition info"
+  DOC_ITEM
+Set this option to a nonzero value to display detailed information
+about the initial condition calculation (default is 0).
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "exclude algebraic variables from error test"
+  DOC_ITEM
+Set to a nonzero value to exclude algebraic variables from the error
+test.  You must also set the @code{\"algebraic variables\"} option to
+declare which variables in the problem are algebraic (default is 0).
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "algebraic variables"
+  DOC_ITEM
+A vector of the same length as the state vector.  A nonzero element
+indicates that the corresponding element of the state vector is an
+algebraic variable (i.e., its derivative does not appear explicitly
+in the equation set.
+
+This option is required by the
+ at code{compute consistent initial condition\"} and
+ at code{\"exclude algebraic variables from error test\"} options.
+  END_DOC_ITEM
+  TYPE = "Array<octave_idx_type>"
+  SET_ARG_TYPE = const $TYPE&
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = 0;
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (int val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = val;
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "enforce inequality constraints"
+  DOC_ITEM
+Set to one of the following values to enforce the inequality
+constraints specified by the @code{\"inequality constraint types\"}
+option (default is 0).
+
+ at enumerate
+ at item To have constraint checking only in the initial condition calculation.
+ at item To enforce constraint checking during the integration.
+ at item To enforce both options 1 and 2.
+ at end enumerate
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "inequality constraint types"
+  DOC_ITEM
+A vector of the same length as the state specifying the type of
+inequality constraint.  Each element of the vector corresponds to an
+element of the state and should be assigned one of the following
+codes 
+
+ at table @asis
+ at item -2
+Less than zero.
+ at item -1
+Less than or equal to zero.
+ at item 0
+Not constrained.
+ at item 1
+Greater than or equal to zero.
+ at item 2
+Greater than zero.
+ at end table
+
+This option only has an effect if the
+ at code{\"enforce inequality constraints\"} option is nonzero.
+  END_DOC_ITEM
+  TYPE = "Array<octave_idx_type>"
+  SET_ARG_TYPE = const $TYPE&
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = 0;
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (octave_idx_type val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = val;
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "initial step size"
+  DOC_ITEM
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize (default is computed
+automatically).
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "maximum order"
+  DOC_ITEM
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive (default is 5).
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "5"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "maximum step size"
+  DOC_ITEM
+Setting the maximum stepsize will avoid passing over very large
+regions (default is not specified).
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
diff --git a/liboctave/DASPK.cc b/liboctave/DASPK.cc
new file mode 100644
index 0000000..b893721
--- /dev/null
+++ b/liboctave/DASPK.cc
@@ -0,0 +1,780 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <sstream>
+
+#include "DASPK.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-math.h"
+#include "quit.h"
+
+typedef octave_idx_type (*daspk_fcn_ptr) (const double&, const double*,
+			      const double*, const double&,
+			      double*, octave_idx_type&, double*, octave_idx_type*);
+
+typedef octave_idx_type (*daspk_jac_ptr) (const double&, const double*,
+			      const double*, double*,
+			      const double&, double*, octave_idx_type*);
+
+typedef octave_idx_type (*daspk_psol_ptr) (const octave_idx_type&, const double&,
+			       const double*, const double*,
+			       const double*, const double&,
+			       const double*, double*, octave_idx_type*,
+			       double*, const double&, octave_idx_type&,
+			       double*, octave_idx_type*);
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (ddaspk, DDASPK) (daspk_fcn_ptr, const octave_idx_type&, double&,
+			     double*, double*, double&, const octave_idx_type*,
+			     const double*, const double*, octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type*, const octave_idx_type&,
+			     const double*, const octave_idx_type*,
+			     daspk_jac_ptr, daspk_psol_ptr);
+}
+
+static DAEFunc::DAERHSFunc user_fun;
+static DAEFunc::DAEJacFunc user_jac;
+static octave_idx_type nn;
+
+static octave_idx_type
+ddaspk_f (const double& time, const double *state, const double *deriv,
+	  const double&, double *delta, octave_idx_type& ires, double *, octave_idx_type *)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  ColumnVector tmp_deriv (nn);
+  ColumnVector tmp_state (nn);
+  ColumnVector tmp_delta (nn);
+
+  for (octave_idx_type i = 0; i < nn; i++)
+    {
+      tmp_deriv.elem (i) = deriv [i];
+      tmp_state.elem (i) = state [i];
+    }
+
+  tmp_delta = user_fun (tmp_state, tmp_deriv, time, ires);
+
+  if (ires >= 0)
+    {
+      if (tmp_delta.length () == 0)
+	ires = -2;
+      else
+	{
+	  for (octave_idx_type i = 0; i < nn; i++)
+	    delta [i] = tmp_delta.elem (i);
+	}
+    }
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+//NEQ, T, Y, YPRIME, SAVR, WK, CJ, WGHT,
+//C                          WP, IWP, B, EPLIN, IER, RPAR, IPAR)
+
+static octave_idx_type
+ddaspk_psol (const octave_idx_type&, const double&, const double *,
+	     const double *, const double *, const double&,
+	     const double *, double *, octave_idx_type *, double *,
+	     const double&, octave_idx_type&, double *, octave_idx_type*)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  abort ();
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+
+static octave_idx_type
+ddaspk_j (const double& time, const double *state, const double *deriv,
+	  double *pd, const double& cj, double *, octave_idx_type *)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  // FIXME -- would be nice to avoid copying the data.
+
+  ColumnVector tmp_state (nn);
+  ColumnVector tmp_deriv (nn);
+
+  for (octave_idx_type i = 0; i < nn; i++)
+    {
+      tmp_deriv.elem (i) = deriv [i];
+      tmp_state.elem (i) = state [i];
+    }
+
+  Matrix tmp_pd = user_jac (tmp_state, tmp_deriv, time, cj);
+
+  for (octave_idx_type j = 0; j < nn; j++)
+    for (octave_idx_type i = 0; i < nn; i++)
+      pd [nn * j + i] = tmp_pd.elem (i, j);
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+ColumnVector
+DASPK::do_integrate (double tout)
+{
+  // FIXME -- should handle all this option stuff just once
+  // for each new problem.
+
+  ColumnVector retval;
+
+  if (! initialized || restart || DAEFunc::reset|| DASPK_options::reset)
+    {
+      integration_error = false;
+
+      initialized = true;
+
+      info.resize (20);
+
+      for (octave_idx_type i = 0; i < 20; i++)
+	info(i) = 0;
+
+      pinfo = info.fortran_vec ();
+
+      octave_idx_type n = size ();
+
+      nn = n;
+
+      info(0) = 0;
+
+      if (stop_time_set)
+	{
+	  rwork(0) = stop_time;
+	  info(3) = 1;
+	}
+      else
+	info(3) = 0;
+
+      px = x.fortran_vec ();
+      pxdot = xdot.fortran_vec ();
+
+      // DAEFunc
+
+      user_fun = DAEFunc::function ();
+      user_jac = DAEFunc::jacobian_function ();
+
+      if (user_fun)
+	{
+	  octave_idx_type ires = 0;
+
+	  ColumnVector res = (*user_fun) (x, xdot, t, ires);
+
+	  if (res.length () != x.length ())
+	    {
+	      (*current_liboctave_error_handler)
+		("daspk: inconsistent sizes for state and residual vectors");
+
+	      integration_error = true;
+	      return retval;
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("daspk: no user supplied RHS subroutine!");
+
+	  integration_error = true;
+	  return retval;
+	}
+  
+      info(4) = user_jac ? 1 : 0;
+
+      DAEFunc::reset = false;
+
+      octave_idx_type eiq = enforce_inequality_constraints ();
+      octave_idx_type ccic = compute_consistent_initial_condition ();
+      octave_idx_type eavfet = exclude_algebraic_variables_from_error_test ();
+
+      liw = 40 + n;
+      if (eiq == 1 || eiq == 3)
+	liw += n;
+      if (ccic == 1 || eavfet == 1)
+	liw += n;
+
+      lrw = 50 + 9*n + n*n;
+      if (eavfet == 1)
+	lrw += n;
+
+      iwork.resize (liw);
+      rwork.resize (lrw);
+
+      piwork = iwork.fortran_vec ();
+      prwork = rwork.fortran_vec ();
+
+      // DASPK_options
+
+      abs_tol = absolute_tolerance ();
+      rel_tol = relative_tolerance ();
+
+      octave_idx_type abs_tol_len = abs_tol.length ();
+      octave_idx_type rel_tol_len = rel_tol.length ();
+
+      if (abs_tol_len == 1 && rel_tol_len == 1)
+	{
+	  info(1) = 0;
+	}
+      else if (abs_tol_len == n && rel_tol_len == n)
+	{
+	  info(1) = 1;
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("daspk: inconsistent sizes for tolerance arrays");
+
+	  integration_error = true;
+	  return retval;
+	}
+
+      pabs_tol = abs_tol.fortran_vec ();
+      prel_tol = rel_tol.fortran_vec ();
+
+      double hmax = maximum_step_size ();
+      if (hmax >= 0.0)
+	{
+	  rwork(1) = hmax;
+	  info(6) = 1;
+	}
+      else
+	info(6) = 0;
+
+      double h0 = initial_step_size ();
+      if (h0 >= 0.0)
+	{
+	  rwork(2) = h0;
+	  info(7) = 1;
+	}
+      else
+	info(7) = 0;
+
+      octave_idx_type maxord = maximum_order ();
+      if (maxord >= 0)
+	{
+	  if (maxord > 0 && maxord < 6)
+	    {
+	      info(8) = 1;
+	      iwork(2) = maxord;
+	    }
+	  else
+	    {
+	      (*current_liboctave_error_handler)
+		("daspk: invalid value for maximum order");
+	      integration_error = true;
+	      return retval;
+	    }
+	}
+
+      switch (eiq)
+	{
+	case 1:
+	case 3:
+	  {
+	    Array<octave_idx_type> ict = inequality_constraint_types ();
+
+	    if (ict.length () == n)
+	      {
+		for (octave_idx_type i = 0; i < n; i++)
+		  {
+		    octave_idx_type val = ict(i);
+		    if (val < -2 || val > 2)
+		      {
+			(*current_liboctave_error_handler)
+			  ("daspk: invalid value for inequality constraint type");
+			integration_error = true;
+			return retval;
+		      }
+		    iwork(40+i) = val;
+		  }
+	      }
+	    else
+	      {
+		(*current_liboctave_error_handler)
+		  ("daspk: inequality constraint types size mismatch");
+		integration_error = true;
+		return retval;
+	      }
+	  }
+	  // Fall through...
+
+	case 0:
+	case 2:
+	  info(9) = eiq;
+	  break;
+
+	default:
+	  (*current_liboctave_error_handler)
+	    ("daspk: invalid value for enforce inequality constraints option");
+	  integration_error = true;
+	  return retval;
+	}
+
+      if (ccic)
+	{
+	  if (ccic == 1)
+	    {
+	      // FIXME -- this code is duplicated below.
+
+	      Array<octave_idx_type> av = algebraic_variables ();
+
+	      if (av.length () == n)
+		{
+		  octave_idx_type lid;
+		  if (eiq == 0 || eiq == 2)
+		    lid = 40;
+		  else if (eiq == 1 || eiq == 3)
+		    lid = 40 + n;
+		  else
+		    abort ();
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    iwork(lid+i) = av(i) ? -1 : 1;
+		}
+	      else
+		{
+		  (*current_liboctave_error_handler)
+		    ("daspk: algebraic variables size mismatch");
+		  integration_error = true;
+		  return retval;
+		}
+	    }
+	  else if (ccic != 2)
+	    {
+	      (*current_liboctave_error_handler)
+		("daspk: invalid value for compute consistent initial condition option");
+	      integration_error = true;
+	      return retval;
+	    }
+
+	  info(10) = ccic;
+	}
+
+      if (eavfet)
+	{
+	  info(15) = 1;
+
+	  // FIXME -- this code is duplicated above.
+
+	  Array<octave_idx_type> av = algebraic_variables ();
+
+	  if (av.length () == n)
+	    {
+	      octave_idx_type lid;
+	      if (eiq == 0 || eiq == 2)
+		lid = 40;
+	      else if (eiq == 1 || eiq == 3)
+		lid = 40 + n;
+	      else
+		abort ();
+
+	      for (octave_idx_type i = 0; i < n; i++)
+		iwork(lid+i) = av(i) ? -1 : 1;
+	    }
+	}
+
+      if (use_initial_condition_heuristics ())
+	{
+	  Array<double> ich = initial_condition_heuristics ();
+
+	  if (ich.length () == 6)
+	    {
+	      iwork(31) = NINTbig (ich(0));
+	      iwork(32) = NINTbig (ich(1));
+	      iwork(33) = NINTbig (ich(2));
+	      iwork(34) = NINTbig (ich(3));
+
+	      rwork(13) = ich(4);
+	      rwork(14) = ich(5);
+	    }
+	  else
+	    {
+	      (*current_liboctave_error_handler)
+		("daspk: invalid initial condition heuristics option");
+	      integration_error = true;
+	      return retval;
+	    }
+
+	  info(16) = 1;
+	}
+
+      octave_idx_type pici = print_initial_condition_info ();
+      switch (pici)
+	{
+	case 0:
+	case 1:
+	case 2:
+	  info(17) = pici;
+	  break;
+
+	default:
+	  (*current_liboctave_error_handler)
+	    ("daspk: invalid value for print initial condition info option");
+	  integration_error = true;
+	  return retval;
+	  break;
+	}
+
+      DASPK_options::reset = false;
+
+      restart = false;
+    }
+
+  static double *dummy = 0;
+  static octave_idx_type *idummy = 0;
+
+  F77_XFCN (ddaspk, DDASPK, (ddaspk_f, nn, t, px, pxdot, tout, pinfo,
+			     prel_tol, pabs_tol, istate, prwork, lrw,
+			     piwork, liw, dummy, idummy, ddaspk_j,
+			     ddaspk_psol));
+
+  switch (istate)
+    {
+    case 1: // A step was successfully taken in intermediate-output
+	    // mode. The code has not yet reached TOUT.
+    case 2: // The integration to TSTOP was successfully completed
+	    // (T=TSTOP) by stepping exactly to TSTOP.
+    case 3: // The integration to TOUT was successfully completed
+	    // (T=TOUT) by stepping past TOUT.  Y(*) is obtained by
+	    // interpolation.  YPRIME(*) is obtained by interpolation.
+    case 4: // The initial condition calculation, with
+	    // INFO(11) > 0, was successful, and INFO(14) = 1.
+	    // No integration steps were taken, and the solution
+	    // is not considered to have been started.
+      retval = x;
+      t = tout;
+      break;
+
+    case -1: // A large amount of work has been expended.  (~500 steps).
+    case -2: // The error tolerances are too stringent.
+    case -3: // The local error test cannot be satisfied because you
+	     // specified a zero component in ATOL and the
+	     // corresponding computed solution component is zero.
+	     // Thus, a pure relative error test is impossible for
+	     // this component.
+    case -6: // DDASPK had repeated error test failures on the last
+	     // attempted step.
+    case -7: // The corrector could not converge.
+    case -8: // The matrix of partial derivatives is singular.
+    case -9: // The corrector could not converge.  There were repeated
+	     // error test failures in this step.
+    case -10: // The corrector could not converge because IRES was
+	      // equal to minus one.
+    case -11: // IRES equal to -2 was encountered and control is being
+	      // returned to the calling program.
+    case -12: // DDASPK failed to compute the initial YPRIME.
+    case -13: // Unrecoverable error encountered inside user's
+	      // PSOL routine, and control is being returned to
+	      // the calling program.
+    case -14: // The Krylov linear system solver could not
+	      // achieve convergence.
+    case -33: // The code has encountered trouble from which it cannot
+	      // recover. A message is printed explaining the trouble
+	      // and control is returned to the calling program. For
+	      // example, this occurs when invalid input is detected.
+      integration_error = true;
+      break;
+
+    default:
+      integration_error = true;
+      (*current_liboctave_error_handler)
+	("unrecognized value of istate (= %d) returned from ddaspk",
+	 istate);
+      break;
+    }
+
+  return retval;
+}
+
+Matrix
+DASPK::do_integrate (const ColumnVector& tout)
+{
+  Matrix dummy;
+  return integrate (tout, dummy);
+}
+
+Matrix
+DASPK::integrate (const ColumnVector& tout, Matrix& xdot_out)
+{
+  Matrix retval;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      retval.resize (n_out, n);
+      xdot_out.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  retval.elem (0, i) = x.elem (i);
+	  xdot_out.elem (0, i) = xdot.elem (i);
+	}
+
+      for (octave_idx_type j = 1; j < n_out; j++)
+	{
+	  ColumnVector x_next = do_integrate (tout.elem (j));
+
+	  if (integration_error)
+	    return retval;
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      retval.elem (j, i) = x_next.elem (i);
+	      xdot_out.elem (j, i) = xdot.elem (i);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+Matrix
+DASPK::do_integrate (const ColumnVector& tout, const ColumnVector& tcrit)
+{
+  Matrix dummy;
+  return integrate (tout, dummy, tcrit);
+}
+
+Matrix
+DASPK::integrate (const ColumnVector& tout, Matrix& xdot_out,
+		  const ColumnVector& tcrit) 
+{
+  Matrix retval;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      retval.resize (n_out, n);
+      xdot_out.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  retval.elem (0, i) = x.elem (i);
+	  xdot_out.elem (0, i) = xdot.elem (i);
+	}
+
+      octave_idx_type n_crit = tcrit.capacity ();
+
+      if (n_crit > 0)
+	{
+	  octave_idx_type i_crit = 0;
+	  octave_idx_type i_out = 1;
+	  double next_crit = tcrit.elem (0);
+	  double next_out;
+	  while (i_out < n_out)
+	    {
+	      bool do_restart = false;
+
+	      next_out = tout.elem (i_out);
+	      if (i_crit < n_crit)
+		next_crit = tcrit.elem (i_crit);
+
+	      bool save_output;
+	      double t_out;
+
+	      if (next_crit == next_out)
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = true;
+		  i_out++;
+		  i_crit++;
+		  do_restart = true;
+		}
+	      else if (next_crit < next_out)
+		{
+		  if (i_crit < n_crit)
+		    {
+		      set_stop_time (next_crit);
+		      t_out = next_crit;
+		      save_output = false;
+		      i_crit++;
+		      do_restart = true;
+		    }
+		  else
+		    {
+		      clear_stop_time ();
+		      t_out = next_out;
+		      save_output = true;
+		      i_out++;
+		    }
+		}
+	      else
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = true;
+		  i_out++;
+		}
+
+	      ColumnVector x_next = do_integrate (t_out);
+
+	      if (integration_error)
+		return retval;
+
+	      if (save_output)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      retval.elem (i_out-1, i) = x_next.elem (i);
+		      xdot_out.elem (i_out-1, i) = xdot.elem (i);
+		    }
+		}
+
+	      if (do_restart)
+		force_restart ();
+	    }
+	}
+      else
+	{
+	  retval = integrate (tout, xdot_out);
+
+	  if (integration_error)
+	    return retval;
+	}
+    }
+
+  return retval;
+}
+
+std::string
+DASPK::error_message (void) const
+{
+  std::string retval;
+
+  std::ostringstream buf;
+  buf << t;
+  std::string t_curr = buf.str ();
+
+  switch (istate)
+    {
+    case 1:
+      retval = "a step was successfully taken in intermediate-output mode.";
+      break;
+
+    case 2:
+      retval = "integration completed by stepping exactly to TOUT";
+      break;
+
+    case 3:
+      retval = "integration to tout completed by stepping past TOUT";
+      break;
+
+    case 4:
+      retval = "initial condition calculation completed successfully";
+      break;
+
+    case -1:
+      retval = std::string ("a large amount of work has been expended (t =")
+	+ t_curr + ")";
+      break;
+
+    case -2:
+      retval = "the error tolerances are too stringent";
+      break;
+
+    case -3:
+      retval = std::string ("error weight became zero during problem. (t = ")
+	+ t_curr
+	+ "; solution component i vanished, and atol or atol(i) == 0)";
+      break;
+
+    case -6:
+      retval = std::string ("repeated error test failures on the last attempted step (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -7:
+      retval = std::string ("the corrector could not converge (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -8:
+      retval = std::string ("the matrix of partial derivatives is singular (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -9:
+      retval = std::string ("the corrector could not converge (t = ")
+	+ t_curr + "; repeated test failures)";
+      break;
+
+    case -10:
+      retval = std::string ("corrector could not converge because IRES was -1 (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -11:
+      retval = std::string ("return requested in user-supplied function (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -12:
+      retval = "failed to compute consistent initial conditions";
+      break;
+
+    case -13:
+      retval = std::string ("unrecoverable error encountered inside user's PSOL function (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -14:
+      retval = std::string ("the Krylov linear system solver failed to converge (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -33:
+      retval = "unrecoverable error (see printed message)";
+      break;
+
+    default:
+      retval = "unknown error state";
+      break;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DASPK.h b/liboctave/DASPK.h
new file mode 100644
index 0000000..18c88c3
--- /dev/null
+++ b/liboctave/DASPK.h
@@ -0,0 +1,92 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DASPK_h)
+#define octave_DASPK_h 1
+
+#include <cfloat>
+
+#include "DASPK-opts.h"
+#include "lo-math.h"
+
+class
+OCTAVE_API
+DASPK : public DAE, public DASPK_options
+{
+public:
+
+  DASPK (void) : DAE (), DASPK_options (), initialized (false) { }
+
+  DASPK (const ColumnVector& s, double tm, DAEFunc& f)
+    : DAE (s, tm, f), DASPK_options (), initialized (false) { }
+
+  DASPK (const ColumnVector& s, const ColumnVector& deriv,
+	 double tm, DAEFunc& f)
+    : DAE (s, deriv, tm, f), DASPK_options (), initialized (false) { }
+
+  ~DASPK (void) { }
+
+  ColumnVector do_integrate (double t);
+
+  Matrix do_integrate (const ColumnVector& tout);
+
+  Matrix do_integrate (const ColumnVector& tout, const ColumnVector& tcrit); 
+
+  Matrix integrate (const ColumnVector& tout, Matrix& xdot_out);
+
+  Matrix integrate (const ColumnVector& tout, Matrix& xdot_out,
+		    const ColumnVector& tcrit); 
+
+  std::string error_message (void) const;
+
+private:
+
+  bool initialized;
+
+  octave_idx_type liw;  
+  octave_idx_type lrw;
+
+  Array<octave_idx_type> info;
+  Array<octave_idx_type> iwork;
+
+  Array<double> rwork;
+
+  Array<double> abs_tol;
+  Array<double> rel_tol;
+
+  double *px;
+  double *pxdot;
+  double *pabs_tol;
+  double *prel_tol;
+  octave_idx_type *pinfo;
+  octave_idx_type *piwork;
+  double *prwork;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DASRT-opts.h b/liboctave/DASRT-opts.h
new file mode 100644
index 0000000..1307521
--- /dev/null
+++ b/liboctave/DASRT-opts.h
@@ -0,0 +1,123 @@
+// DO NOT EDIT!
+// Generated automatically from DASRT-opts.in.
+
+#if !defined (octave_DASRT_options_h)
+#define octave_DASRT_options_h 1
+
+#include <cfloat>
+#include <cmath>
+
+#include <DAERT.h>
+
+
+class
+DASRT_options
+{
+public:
+
+  DASRT_options (void) { init (); }
+
+  DASRT_options (const DASRT_options& opt) { copy (opt); }
+
+  DASRT_options& operator = (const DASRT_options& opt)
+    {
+      if (this != &opt)
+        copy (opt);
+
+      return *this;
+    }
+
+  ~DASRT_options (void) { }
+
+  void init (void)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_relative_tolerance.resize (1);
+      x_relative_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_initial_step_size = -1.0;
+      x_maximum_order = -1;
+      x_maximum_step_size = -1.0;
+      x_step_limit = -1;
+      reset = true;
+    }
+
+  void copy (const DASRT_options& opt)
+    {
+      x_absolute_tolerance = opt.x_absolute_tolerance;
+      x_relative_tolerance = opt.x_relative_tolerance;
+      x_initial_step_size = opt.x_initial_step_size;
+      x_maximum_order = opt.x_maximum_order;
+      x_maximum_step_size = opt.x_maximum_step_size;
+      x_step_limit = opt.x_step_limit;
+      reset = opt.reset;
+    }
+
+  void set_options (const DASRT_options& opt) { copy (opt); }
+
+  void set_default_options (void) { init (); }
+
+  void set_absolute_tolerance (double val)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_absolute_tolerance (const Array<double>& val)
+    { x_absolute_tolerance = val; reset = true; }
+
+  void set_relative_tolerance (double val)
+    {
+      x_relative_tolerance.resize (1);
+      x_relative_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_relative_tolerance (const Array<double>& val)
+    { x_relative_tolerance = val; reset = true; }
+
+  void set_initial_step_size (double val)
+    { x_initial_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_maximum_order (octave_idx_type val)
+    { x_maximum_order = val; reset = true; }
+
+  void set_maximum_step_size (double val)
+    { x_maximum_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_step_limit (octave_idx_type val)
+    { x_step_limit = (val >= 0) ? val : -1; reset = true; }
+  Array<double> absolute_tolerance (void) const
+    { return x_absolute_tolerance; }
+
+  Array<double> relative_tolerance (void) const
+    { return x_relative_tolerance; }
+
+  double initial_step_size (void) const
+    { return x_initial_step_size; }
+
+  octave_idx_type maximum_order (void) const
+    { return x_maximum_order; }
+
+  double maximum_step_size (void) const
+    { return x_maximum_step_size; }
+
+  octave_idx_type step_limit (void) const
+    { return x_step_limit; }
+
+private:
+
+  Array<double> x_absolute_tolerance;
+  Array<double> x_relative_tolerance;
+  double x_initial_step_size;
+  octave_idx_type x_maximum_order;
+  double x_maximum_step_size;
+  octave_idx_type x_step_limit;
+
+protected:
+
+  bool reset;
+};
+
+#endif
diff --git a/liboctave/DASRT-opts.in b/liboctave/DASRT-opts.in
new file mode 100644
index 0000000..4d5b5bc
--- /dev/null
+++ b/liboctave/DASRT-opts.in
@@ -0,0 +1,127 @@
+# Copyright (C) 2002, 2005, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+CLASS = "DASRT"
+
+INCLUDE = "DAERT.h"
+
+OPTION
+  NAME = "absolute tolerance"
+  DOC_ITEM
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "relative tolerance"
+  DOC_ITEM
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+ at example
+ at group
+  abs (local error in x(i)) <= ...
+      rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "initial step size"
+  DOC_ITEM
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize.
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "maximum order"
+  DOC_ITEM
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "-1"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "maximum step size"
+  DOC_ITEM
+Setting the maximum stepsize will avoid passing over very large
+regions.
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "step limit"
+  DOC_ITEM
+Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "-1"
+  SET_EXPR = "(val >= 0) ? val : -1"
+END_OPTION
diff --git a/liboctave/DASRT.cc b/liboctave/DASRT.cc
new file mode 100644
index 0000000..f18b667
--- /dev/null
+++ b/liboctave/DASRT.cc
@@ -0,0 +1,647 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <sstream>
+
+#include "DASRT.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-math.h"
+#include "quit.h"
+
+typedef octave_idx_type (*dasrt_fcn_ptr) (const double&, const double*, const double*,
+			      double*, octave_idx_type&, double*, octave_idx_type*);
+
+typedef octave_idx_type (*dasrt_jac_ptr) (const double&, const double*, const double*,
+			      double*, const double&, double*, octave_idx_type*);
+
+typedef octave_idx_type (*dasrt_constr_ptr) (const octave_idx_type&, const double&, const double*,
+				 const octave_idx_type&, double*, double*, octave_idx_type*);
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (ddasrt, DDASRT) (dasrt_fcn_ptr, const octave_idx_type&, double&,
+			     double*, double*, const double&, octave_idx_type*,
+			     const double*, const double*, octave_idx_type&, double*,
+			     const octave_idx_type&, octave_idx_type*, const octave_idx_type&, double*,
+			     octave_idx_type*, dasrt_jac_ptr, dasrt_constr_ptr,
+			     const octave_idx_type&, octave_idx_type*);
+}
+
+static DAEFunc::DAERHSFunc user_fsub;
+static DAEFunc::DAEJacFunc user_jsub;
+static DAERTFunc::DAERTConstrFunc user_csub;
+
+static octave_idx_type nn;
+
+static octave_idx_type
+ddasrt_f (const double& t, const double *state, const double *deriv,
+	  double *delta, octave_idx_type& ires, double *, octave_idx_type *)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  ColumnVector tmp_state (nn);
+  ColumnVector tmp_deriv (nn);
+
+  for (octave_idx_type i = 0; i < nn; i++)
+    {
+      tmp_state(i) = state[i];
+      tmp_deriv(i) = deriv[i];
+    }
+
+  ColumnVector tmp_fval = (*user_fsub) (tmp_state, tmp_deriv, t, ires);
+
+  if (tmp_fval.length () == 0)
+    ires = -2;
+  else
+    {
+      for (octave_idx_type i = 0; i < nn; i++)
+	delta[i] = tmp_fval(i);
+    }
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+octave_idx_type
+ddasrt_j (const double& time, const double *state, const double *deriv,
+	  double *pd, const double& cj, double *, octave_idx_type *)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  // FIXME -- would be nice to avoid copying the data.
+
+  ColumnVector tmp_state (nn);
+  ColumnVector tmp_deriv (nn);
+
+  for (octave_idx_type i = 0; i < nn; i++)
+    {
+      tmp_deriv.elem (i) = deriv [i];
+      tmp_state.elem (i) = state [i];
+    }
+
+  Matrix tmp_pd = (*user_jsub) (tmp_state, tmp_deriv, time, cj);
+
+  for (octave_idx_type j = 0; j < nn; j++)
+    for (octave_idx_type i = 0; i < nn; i++)
+      pd [nn * j + i] = tmp_pd.elem (i, j);
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+static octave_idx_type
+ddasrt_g (const octave_idx_type& neq, const double& t, const double *state,
+	  const octave_idx_type& ng, double *gout, double *, octave_idx_type *) 
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  octave_idx_type n = neq;
+
+  ColumnVector tmp_state (n);
+  for (octave_idx_type i = 0; i < n; i++)
+    tmp_state(i) = state[i];
+
+  ColumnVector tmp_fval = (*user_csub) (tmp_state, t);
+
+  for (octave_idx_type i = 0; i < ng; i++)
+    gout[i] = tmp_fval(i);
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+void
+DASRT::integrate (double tout)
+{
+  DASRT_result retval;
+
+  // I suppose this is the safe thing to do.  If this is the first
+  // call, or if anything about the problem has changed, we should
+  // start completely fresh.
+
+  if (! initialized || restart
+      || DAEFunc::reset || DAERTFunc::reset || DASRT_options::reset)
+    {
+      integration_error = false;
+
+      initialized = true;
+
+      info.resize (15);
+
+      for (octave_idx_type i = 0; i < 15; i++)
+	info(i) = 0;
+
+      pinfo = info.fortran_vec ();
+
+      octave_idx_type n = size ();
+
+      nn = n;
+
+      // DAERTFunc
+
+      user_csub = DAERTFunc::constraint_function ();
+
+      if (user_csub)
+	{
+	  ColumnVector tmp = (*user_csub) (x, t);
+	  ng = tmp.length ();
+	}
+      else
+	ng = 0;
+
+      octave_idx_type maxord = maximum_order ();
+      if (maxord >= 0)
+	{
+	  if (maxord > 0 && maxord < 6)
+	    {
+	      info(8) = 1;
+	      iwork(2) = maxord;
+	    }
+	  else
+	    {
+	      (*current_liboctave_error_handler)
+		("dassl: invalid value for maximum order");
+	      integration_error = true;
+	      return;
+	    }
+	}
+
+      liw = 21 + n;
+      lrw = 50 + 9*n + n*n + 3*ng;
+
+      iwork.resize (liw);
+      rwork.resize (lrw);
+
+      info(0) = 0;
+
+      if (stop_time_set)
+	{
+	  info(3) = 1;
+	  rwork(0) = stop_time;
+	}
+      else
+	info(3) = 0;
+
+      px = x.fortran_vec ();
+      pxdot = xdot.fortran_vec ();
+
+      piwork = iwork.fortran_vec ();
+      prwork = rwork.fortran_vec ();
+
+      restart = false;
+
+      // DAEFunc
+
+      user_fsub = DAEFunc::function ();
+      user_jsub = DAEFunc::jacobian_function ();
+
+      if (user_fsub)
+	{
+	  octave_idx_type ires = 0;
+
+	  ColumnVector fval = (*user_fsub) (x, xdot, t, ires);
+
+	  if (fval.length () != x.length ())
+	    {
+	      (*current_liboctave_error_handler)
+		("dasrt: inconsistent sizes for state and residual vectors");
+
+	      integration_error = true;
+	      return;
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("dasrt: no user supplied RHS subroutine!");
+
+	  integration_error = true;
+	  return;
+	}
+
+      info(4) = user_jsub ? 1 : 0;
+
+      DAEFunc::reset = false;
+
+      jroot.resize (ng, 1);
+
+      pjroot = jroot.fortran_vec ();
+
+      DAERTFunc::reset = false;
+
+      // DASRT_options
+
+      double mss = maximum_step_size ();
+      if (mss >= 0.0)
+	{
+	  rwork(1) = mss;
+	  info(6) = 1;
+	}
+      else
+	info(6) = 0;
+
+      double iss = initial_step_size ();
+      if (iss >= 0.0)
+	{
+	  rwork(2) = iss;
+	  info(7) = 1;
+	}
+      else
+	info(7) = 0;
+
+      if (step_limit () >= 0)
+	{
+	  info(11) = 1;
+	  iwork(20) = step_limit ();
+	}
+      else
+	info(11) = 0;
+
+      abs_tol = absolute_tolerance ();
+      rel_tol = relative_tolerance ();
+
+      octave_idx_type abs_tol_len = abs_tol.length ();
+      octave_idx_type rel_tol_len = rel_tol.length ();
+
+      if (abs_tol_len == 1 && rel_tol_len == 1)
+	{
+	  info.elem (1) = 0;
+	}
+      else if (abs_tol_len == n && rel_tol_len == n)
+	{
+	  info.elem (1) = 1;
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("dasrt: inconsistent sizes for tolerance arrays");
+
+	  integration_error = true;
+	  return;
+	}
+
+      pabs_tol = abs_tol.fortran_vec ();
+      prel_tol = rel_tol.fortran_vec ();
+
+      DASRT_options::reset = false;
+    }
+
+  static double *dummy = 0;
+  static octave_idx_type *idummy = 0;
+
+  F77_XFCN (ddasrt, DDASRT, (ddasrt_f, nn, t, px, pxdot, tout, pinfo,
+			     prel_tol, pabs_tol, istate, prwork, lrw,
+			     piwork, liw, dummy, idummy, ddasrt_j,
+			     ddasrt_g, ng, pjroot));
+
+  switch (istate)
+    {
+    case 1: // A step was successfully taken in intermediate-output
+	    // mode. The code has not yet reached TOUT.
+    case 2: // The integration to TOUT was successfully completed
+	    // (T=TOUT) by stepping exactly to TOUT.
+    case 3: // The integration to TOUT was successfully completed
+	    // (T=TOUT) by stepping past TOUT.  Y(*) is obtained by
+	    // interpolation.  YPRIME(*) is obtained by interpolation.
+      t = tout;
+      break;
+
+    case 4: //  The integration was successfully completed
+	    // by finding one or more roots of G at T.
+      break;
+
+    case -1: // A large amount of work has been expended.
+    case -2: // The error tolerances are too stringent.
+    case -3: // The local error test cannot be satisfied because you
+	     // specified a zero component in ATOL and the
+	     // corresponding computed solution component is zero.
+	     // Thus, a pure relative error test is impossible for
+	     // this component.
+    case -6: // DDASRT had repeated error test failures on the last
+	     // attempted step.
+    case -7: // The corrector could not converge.
+    case -8: // The matrix of partial derivatives is singular.
+    case -9: // The corrector could not converge.  There were repeated
+	     // error test failures in this step.
+    case -10: // The corrector could not converge because IRES was
+	      // equal to minus one.
+    case -11: // IRES equal to -2 was encountered and control is being
+	      // returned to the calling program.
+    case -12: // DASSL failed to compute the initial YPRIME.
+    case -33: // The code has encountered trouble from which it cannot
+	      // recover. A message is printed explaining the trouble
+	      // and control is returned to the calling program. For
+	      // example, this occurs when invalid input is detected.
+      integration_error = true;
+      break;
+
+    default:
+      integration_error = true;
+      (*current_liboctave_error_handler)
+	("unrecognized value of istate (= %d) returned from ddasrt",
+	 istate);
+      break;
+    }
+}
+
+DASRT_result
+DASRT::integrate (const ColumnVector& tout)
+{
+  DASRT_result retval;
+
+  Matrix x_out;
+  Matrix xdot_out;
+  ColumnVector t_out = tout;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      x_out.resize (n_out, n);
+      xdot_out.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  x_out(0,i) = x(i);
+	  xdot_out(0,i) = xdot(i);
+	}
+
+      for (octave_idx_type j = 1; j < n_out; j++)
+	{
+	  integrate (tout(j));
+
+	  if (integration_error)
+	    {
+	      retval = DASRT_result (x_out, xdot_out, t_out);
+	      return retval;
+	    }
+
+          if (istate == 4)
+            t_out(j) = t;
+          else
+            t_out(j) = tout(j);
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      x_out(j,i) = x(i);
+	      xdot_out(j,i) = xdot(i);
+	    }
+
+          if (istate == 4)
+	    {
+	      x_out.resize (j+1, n);
+	      xdot_out.resize (j+1, n);
+	      t_out.resize (j+1);
+	      break;
+	    }
+	}
+    }
+
+  retval = DASRT_result (x_out, xdot_out, t_out);
+
+  return retval;
+}
+
+DASRT_result
+DASRT::integrate (const ColumnVector& tout, const ColumnVector& tcrit) 
+{
+  DASRT_result retval;
+
+  Matrix x_out;
+  Matrix xdot_out;
+  ColumnVector t_outs = tout;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      x_out.resize (n_out, n);
+      xdot_out.resize (n_out, n);
+
+      octave_idx_type n_crit = tcrit.capacity ();
+
+      if (n_crit > 0)
+	{
+	  octave_idx_type i_crit = 0;
+	  octave_idx_type i_out = 1;
+	  double next_crit = tcrit(0);
+	  double next_out;
+	  while (i_out < n_out)
+	    {
+	      bool do_restart = false;
+
+	      next_out = tout(i_out);
+	      if (i_crit < n_crit)
+		next_crit = tcrit(i_crit);
+
+	      octave_idx_type save_output;
+	      double t_out;
+
+	      if (next_crit == next_out)
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = 1;
+		  i_out++;
+		  i_crit++;
+		  do_restart = true;
+		}
+	      else if (next_crit < next_out)
+		{
+		  if (i_crit < n_crit)
+		    {
+		      set_stop_time (next_crit);
+		      t_out = next_crit;
+		      save_output = 0;
+		      i_crit++;
+		      do_restart = true;
+		    }
+		  else
+		    {
+		      clear_stop_time ();
+		      t_out = next_out;
+		      save_output = 1;
+		      i_out++;
+		    }
+		}
+	      else
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = 1;
+		  i_out++;
+		}
+
+	      integrate (t_out);
+
+	      if (integration_error)
+		{
+		  retval = DASRT_result (x_out, xdot_out, t_outs);
+		  return retval;
+		}
+
+              if (istate == 4)
+                t_out = t;
+
+	      if (save_output)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      x_out(i_out-1,i) = x(i);
+		      xdot_out(i_out-1,i) = xdot(i);
+		    }
+
+                  t_outs(i_out-1) = t_out;
+
+                  if (istate == 4)
+                    {
+                      x_out.resize (i_out, n);
+                      xdot_out.resize (i_out, n);
+                      t_outs.resize (i_out);
+                      i_out = n_out;
+                    }
+		}
+
+	      if (do_restart)
+		force_restart ();
+	    }
+
+	  retval = DASRT_result (x_out, xdot_out, t_outs);
+	}
+      else
+	{
+	  retval = integrate (tout);
+
+	  if (integration_error)
+	    return retval;
+	}
+    }
+
+  return retval;
+}
+
+std::string
+DASRT::error_message (void) const
+{
+  std::string retval;
+
+  std::ostringstream buf;
+  buf << t;
+  std::string t_curr = buf.str ();
+
+  switch (istate)
+    {
+    case 1:
+      retval = "a step was successfully taken in intermediate-output mode.";
+      break;
+
+    case 2:
+      retval = "integration completed by stepping exactly to TOUT";
+      break;
+
+    case 3:
+      retval = "integration to tout completed by stepping past TOUT";
+      break;
+
+    case 4:
+      retval = "integration completed by finding one or more roots of G at T";
+      break;
+
+    case -1:
+      retval = std::string ("a large amount of work has been expended (t =")
+	+ t_curr + ")";
+      break;
+
+    case -2:
+      retval = "the error tolerances are too stringent";
+      break;
+
+    case -3:
+      retval = std::string ("error weight became zero during problem. (t = ")
+	+ t_curr
+	+ "; solution component i vanished, and atol or atol(i) == 0)";
+      break;
+
+    case -6:
+      retval = std::string ("repeated error test failures on the last attempted step (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -7:
+      retval = std::string ("the corrector could not converge (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -8:
+      retval = std::string ("the matrix of partial derivatives is singular (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -9:
+      retval = std::string ("the corrector could not converge (t = ")
+	+ t_curr + "; repeated test failures)";
+      break;
+
+    case -10:
+      retval = std::string ("corrector could not converge because IRES was -1 (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -11:
+      retval = std::string ("return requested in user-supplied function (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -12:
+      retval = "failed to compute consistent initial conditions";
+      break;
+
+    case -33:
+      retval = "unrecoverable error (see printed message)";
+      break;
+
+    default:
+      retval = "unknown error state";
+      break;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DASRT.h b/liboctave/DASRT.h
new file mode 100644
index 0000000..893abcb
--- /dev/null
+++ b/liboctave/DASRT.h
@@ -0,0 +1,128 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DASRT_h)
+#define octave_DASRT_h 1
+
+#include <cfloat>
+
+#include "DASRT-opts.h"
+#include "lo-math.h"
+
+class
+DASRT_result
+{
+public:
+
+  DASRT_result (void) { }
+
+  DASRT_result (const Matrix& xx, const Matrix& xxdot, const ColumnVector& tt)
+    : x (xx), xdot (xxdot), t (tt) { }
+
+  DASRT_result (const DASRT_result& r)
+    : x (r.x), xdot (r.xdot), t (r.t) { }
+
+  DASRT_result& operator = (const DASRT_result& r)
+    {
+      if (this != &r)
+	{
+	  x = r.x;
+	  xdot = r.xdot;
+          t = r.t;
+	}
+      return *this;
+    }
+
+  ~DASRT_result (void) { }
+
+  Matrix state (void) const { return x; }
+  Matrix deriv (void) const { return xdot; }
+  ColumnVector times (void) const { return t; }
+
+private:
+
+  Matrix x;
+  Matrix xdot;
+  ColumnVector t;
+};
+
+class
+OCTAVE_API
+DASRT : public DAERT, public DASRT_options
+{
+public:
+
+  DASRT (void) : DAERT (), DASRT_options (), initialized (false) { }
+
+  DASRT (const ColumnVector& s, double tm, DAERTFunc& f)
+    : DAERT (s, tm, f), DASRT_options (), initialized (false) { }
+
+  DASRT (const ColumnVector& s, const ColumnVector& deriv,
+	 double tm, DAERTFunc& f)
+    : DAERT (s, deriv, tm, f), DASRT_options (), initialized (false) { }
+
+  ~DASRT (void) { }
+
+  DASRT_result integrate (const ColumnVector& tout);
+
+  DASRT_result integrate (const ColumnVector& tout,
+			  const ColumnVector& tcrit); 
+
+  std::string error_message (void) const;
+
+private:
+
+  bool initialized;
+
+  octave_idx_type liw;  
+  octave_idx_type lrw;
+
+  octave_idx_type ng;
+
+  Array<octave_idx_type> info;
+  Array<octave_idx_type> iwork;
+  Array<octave_idx_type> jroot;
+
+  Array<double> rwork;
+
+  Array<double> abs_tol;
+  Array<double> rel_tol;
+
+  double *px;
+  double *pxdot;
+  double *pabs_tol;
+  double *prel_tol;
+  octave_idx_type *pinfo;
+  octave_idx_type *piwork;
+  double *prwork;
+  octave_idx_type *pjroot;
+
+  void integrate (double t);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DASSL-opts.h b/liboctave/DASSL-opts.h
new file mode 100644
index 0000000..2971c05
--- /dev/null
+++ b/liboctave/DASSL-opts.h
@@ -0,0 +1,139 @@
+// DO NOT EDIT!
+// Generated automatically from DASSL-opts.in.
+
+#if !defined (octave_DASSL_options_h)
+#define octave_DASSL_options_h 1
+
+#include <cfloat>
+#include <cmath>
+
+#include <DAE.h>
+
+
+class
+DASSL_options
+{
+public:
+
+  DASSL_options (void) { init (); }
+
+  DASSL_options (const DASSL_options& opt) { copy (opt); }
+
+  DASSL_options& operator = (const DASSL_options& opt)
+    {
+      if (this != &opt)
+        copy (opt);
+
+      return *this;
+    }
+
+  ~DASSL_options (void) { }
+
+  void init (void)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_relative_tolerance.resize (1);
+      x_relative_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_initial_step_size = -1.0;
+      x_maximum_order = -1;
+      x_maximum_step_size = -1.0;
+      x_step_limit = -1;
+      reset = true;
+    }
+
+  void copy (const DASSL_options& opt)
+    {
+      x_absolute_tolerance = opt.x_absolute_tolerance;
+      x_relative_tolerance = opt.x_relative_tolerance;
+      x_compute_consistent_initial_condition = opt.x_compute_consistent_initial_condition;
+      x_enforce_nonnegativity_constraints = opt.x_enforce_nonnegativity_constraints;
+      x_initial_step_size = opt.x_initial_step_size;
+      x_maximum_order = opt.x_maximum_order;
+      x_maximum_step_size = opt.x_maximum_step_size;
+      x_step_limit = opt.x_step_limit;
+      reset = opt.reset;
+    }
+
+  void set_options (const DASSL_options& opt) { copy (opt); }
+
+  void set_default_options (void) { init (); }
+
+  void set_absolute_tolerance (double val)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_absolute_tolerance (const Array<double>& val)
+    { x_absolute_tolerance = val; reset = true; }
+
+  void set_relative_tolerance (double val)
+    {
+      x_relative_tolerance.resize (1);
+      x_relative_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_relative_tolerance (const Array<double>& val)
+    { x_relative_tolerance = val; reset = true; }
+
+  void set_compute_consistent_initial_condition (octave_idx_type val)
+    { x_compute_consistent_initial_condition = val; reset = true; }
+
+  void set_enforce_nonnegativity_constraints (octave_idx_type val)
+    { x_enforce_nonnegativity_constraints = val; reset = true; }
+
+  void set_initial_step_size (double val)
+    { x_initial_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_maximum_order (octave_idx_type val)
+    { x_maximum_order = val; reset = true; }
+
+  void set_maximum_step_size (double val)
+    { x_maximum_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_step_limit (octave_idx_type val)
+    { x_step_limit = (val >= 0) ? val : -1; reset = true; }
+  Array<double> absolute_tolerance (void) const
+    { return x_absolute_tolerance; }
+
+  Array<double> relative_tolerance (void) const
+    { return x_relative_tolerance; }
+
+  octave_idx_type compute_consistent_initial_condition (void) const
+    { return x_compute_consistent_initial_condition; }
+
+  octave_idx_type enforce_nonnegativity_constraints (void) const
+    { return x_enforce_nonnegativity_constraints; }
+
+  double initial_step_size (void) const
+    { return x_initial_step_size; }
+
+  octave_idx_type maximum_order (void) const
+    { return x_maximum_order; }
+
+  double maximum_step_size (void) const
+    { return x_maximum_step_size; }
+
+  octave_idx_type step_limit (void) const
+    { return x_step_limit; }
+
+private:
+
+  Array<double> x_absolute_tolerance;
+  Array<double> x_relative_tolerance;
+  octave_idx_type x_compute_consistent_initial_condition;
+  octave_idx_type x_enforce_nonnegativity_constraints;
+  double x_initial_step_size;
+  octave_idx_type x_maximum_order;
+  double x_maximum_step_size;
+  octave_idx_type x_step_limit;
+
+protected:
+
+  bool reset;
+};
+
+#endif
diff --git a/liboctave/DASSL-opts.in b/liboctave/DASSL-opts.in
new file mode 100644
index 0000000..53f34e5
--- /dev/null
+++ b/liboctave/DASSL-opts.in
@@ -0,0 +1,154 @@
+# Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+CLASS = "DASSL"
+
+INCLUDE = "DAE.h"
+
+OPTION
+  NAME = "absolute tolerance"
+  DOC_ITEM
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "relative tolerance"
+  DOC_ITEM
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i))
+       <= rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "compute consistent initial condition"
+  DOC_ITEM
+If nonzero, @code{dassl} will attempt to compute a consistent set of initial
+conditions.  This is generally not reliable, so it is best to provide
+a consistent set and leave this option set to zero.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "enforce nonnegativity constraints"
+  DOC_ITEM
+If you know that the solutions to your equations will always be
+nonnegative, it may help to set this parameter to a nonzero
+value.  However, it is probably best to try leaving this option set to
+zero first, and only setting it to a nonzero value if that doesn't
+work very well.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "0"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "initial step size"
+  DOC_ITEM
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize.
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "maximum order"
+  DOC_ITEM
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "-1"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "maximum step size"
+  DOC_ITEM
+Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified).
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "step limit"
+  DOC_ITEM
+Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "-1"
+  SET_EXPR = "(val >= 0) ? val : -1"
+END_OPTION
diff --git a/liboctave/DASSL.cc b/liboctave/DASSL.cc
new file mode 100644
index 0000000..ed6e48c
--- /dev/null
+++ b/liboctave/DASSL.cc
@@ -0,0 +1,582 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <sstream>
+
+#include "DASSL.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-math.h"
+#include "quit.h"
+
+typedef octave_idx_type (*dassl_fcn_ptr) (const double&, const double*, const double*,
+			      double*, octave_idx_type&, double*, octave_idx_type*);
+
+typedef octave_idx_type (*dassl_jac_ptr) (const double&, const double*, const double*,
+			      double*, const double&, double*, octave_idx_type*);
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (ddassl, DDASSL) (dassl_fcn_ptr, const octave_idx_type&, double&,
+			     double*, double*, double&, const octave_idx_type*,
+			     const double*, const double*, octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type*, const octave_idx_type&,
+			     const double*, const octave_idx_type*,
+			     dassl_jac_ptr);
+}
+
+static DAEFunc::DAERHSFunc user_fun;
+static DAEFunc::DAEJacFunc user_jac;
+
+static octave_idx_type nn;
+
+static octave_idx_type
+ddassl_f (const double& time, const double *state, const double *deriv,
+	  double *delta, octave_idx_type& ires, double *, octave_idx_type *)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  // FIXME -- would be nice to avoid copying the data.
+
+  ColumnVector tmp_deriv (nn);
+  ColumnVector tmp_state (nn);
+  ColumnVector tmp_delta (nn);
+
+  for (octave_idx_type i = 0; i < nn; i++)
+    {
+      tmp_deriv.elem (i) = deriv [i];
+      tmp_state.elem (i) = state [i];
+    }
+
+  tmp_delta = user_fun (tmp_state, tmp_deriv, time, ires);
+
+  if (ires >= 0)
+    {
+      if (tmp_delta.length () == 0)
+	ires = -2;
+      else
+	{
+	  for (octave_idx_type i = 0; i < nn; i++)
+	    delta [i] = tmp_delta.elem (i);
+	}
+    }
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+static octave_idx_type
+ddassl_j (const double& time, const double *state, const double *deriv,
+	  double *pd, const double& cj, double *, octave_idx_type *)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  // FIXME -- would be nice to avoid copying the data.
+
+  ColumnVector tmp_state (nn);
+  ColumnVector tmp_deriv (nn);
+
+  for (octave_idx_type i = 0; i < nn; i++)
+    {
+      tmp_deriv.elem (i) = deriv [i];
+      tmp_state.elem (i) = state [i];
+    }
+
+  Matrix tmp_pd = user_jac (tmp_state, tmp_deriv, time, cj);
+
+  for (octave_idx_type j = 0; j < nn; j++)
+    for (octave_idx_type i = 0; i < nn; i++)
+      pd [nn * j + i] = tmp_pd.elem (i, j);
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+ColumnVector
+DASSL::do_integrate (double tout)
+{
+  ColumnVector retval;
+
+  if (! initialized || restart || DAEFunc::reset|| DASSL_options::reset)
+    {
+      integration_error = false;
+
+      initialized = true;
+
+      info.resize (15);
+
+      for (octave_idx_type i = 0; i < 15; i++)
+	info(i) = 0;
+
+      pinfo = info.fortran_vec ();
+
+      octave_idx_type n = size ();
+
+      liw = 21 + n;
+      lrw = 40 + 9*n + n*n;
+
+      nn = n;
+
+      iwork.resize (liw);
+      rwork.resize (lrw);
+
+      info(0) = 0;
+
+      if (stop_time_set)
+	{
+	  rwork(0) = stop_time;
+	  info(3) = 1;
+	}
+      else
+	info(3) = 0;
+
+      px = x.fortran_vec ();
+      pxdot = xdot.fortran_vec ();
+
+      piwork = iwork.fortran_vec ();
+      prwork = rwork.fortran_vec ();
+
+      restart = false;
+
+      // DAEFunc
+
+      user_fun = DAEFunc::function ();
+      user_jac = DAEFunc::jacobian_function ();
+
+      if (user_fun)
+	{
+	  octave_idx_type ires = 0;
+
+	  ColumnVector res = (*user_fun) (x, xdot, t, ires);
+
+	  if (res.length () != x.length ())
+	    {
+	      (*current_liboctave_error_handler)
+		("dassl: inconsistent sizes for state and residual vectors");
+
+	      integration_error = true;
+	      return retval;
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("dassl: no user supplied RHS subroutine!");
+
+	  integration_error = true;
+	  return retval;
+	}
+
+      info(4) = user_jac ? 1 : 0;
+  
+      DAEFunc::reset = false;
+
+      // DASSL_options
+
+      double hmax = maximum_step_size ();
+      if (hmax >= 0.0)
+	{
+	  rwork(1) = hmax;
+	  info(6) = 1;
+	}
+      else
+	info(6) = 0;
+
+      double h0 = initial_step_size ();
+      if (h0 >= 0.0)
+	{
+	  rwork(2) = h0;
+	  info(7) = 1;
+	}
+      else
+	info(7) = 0;
+
+      if (step_limit () >= 0)
+	{
+	  info(11) = 1;
+	  iwork(20) = step_limit ();
+	}
+      else
+	info(11) = 0;
+
+      octave_idx_type maxord = maximum_order ();
+      if (maxord >= 0)
+	{
+	  if (maxord > 0 && maxord < 6)
+	    {
+	      info(8) = 1;
+	      iwork(2) = maxord;
+	    }
+	  else
+	    {
+	      (*current_liboctave_error_handler)
+		("dassl: invalid value for maximum order");
+	      integration_error = true;
+	      return retval;
+	    }
+	}
+
+      octave_idx_type enc = enforce_nonnegativity_constraints ();
+      info(9) = enc ? 1 : 0;
+
+      octave_idx_type ccic = compute_consistent_initial_condition ();
+      info(10) = ccic ? 1 : 0;
+
+      abs_tol = absolute_tolerance ();
+      rel_tol = relative_tolerance ();
+
+      octave_idx_type abs_tol_len = abs_tol.length ();
+      octave_idx_type rel_tol_len = rel_tol.length ();
+
+      if (abs_tol_len == 1 && rel_tol_len == 1)
+	{
+	  info(1) = 0;
+	}
+      else if (abs_tol_len == n && rel_tol_len == n)
+	{
+	  info(1) = 1;
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("dassl: inconsistent sizes for tolerance arrays");
+
+	  integration_error = true;
+	  return retval;
+	}
+
+      pabs_tol = abs_tol.fortran_vec ();
+      prel_tol = rel_tol.fortran_vec ();
+
+      DASSL_options::reset = false;
+    }
+
+  static double *dummy = 0;
+  static octave_idx_type *idummy = 0;
+
+  F77_XFCN (ddassl, DDASSL, (ddassl_f, nn, t, px, pxdot, tout, pinfo,
+			     prel_tol, pabs_tol, istate, prwork, lrw,
+			     piwork, liw, dummy, idummy, ddassl_j));
+
+  switch (istate)
+    {
+    case 1: // A step was successfully taken in intermediate-output
+	    // mode. The code has not yet reached TOUT.
+    case 2: // The integration to TSTOP was successfully completed
+	    // (T=TSTOP) by stepping exactly to TSTOP.
+    case 3: // The integration to TOUT was successfully completed
+	    // (T=TOUT) by stepping past TOUT.  Y(*) is obtained by
+	    // interpolation.  YPRIME(*) is obtained by interpolation.
+      retval = x;
+      t = tout;
+      break;
+
+    case -1: // A large amount of work has been expended.  (~500 steps).
+    case -2: // The error tolerances are too stringent.
+    case -3: // The local error test cannot be satisfied because you
+	     // specified a zero component in ATOL and the
+	     // corresponding computed solution component is zero.
+	     // Thus, a pure relative error test is impossible for
+	     // this component.
+    case -6: // DDASSL had repeated error test failures on the last
+	     // attempted step.
+    case -7: // The corrector could not converge.
+    case -8: // The matrix of partial derivatives is singular.
+    case -9: // The corrector could not converge.  There were repeated
+	     // error test failures in this step.
+    case -10: // The corrector could not converge because IRES was
+	      // equal to minus one.
+    case -11: // IRES equal to -2 was encountered and control is being
+	      // returned to the calling program.
+    case -12: // DDASSL failed to compute the initial YPRIME.
+    case -33: // The code has encountered trouble from which it cannot
+	      // recover. A message is printed explaining the trouble
+	      // and control is returned to the calling program. For
+	      // example, this occurs when invalid input is detected.
+      integration_error = true;
+      break;
+
+    default:
+      integration_error = true;
+      (*current_liboctave_error_handler)
+	("unrecognized value of istate (= %d) returned from ddassl",
+	 istate);
+      break;
+    }
+
+  return retval;
+}
+
+Matrix
+DASSL::do_integrate (const ColumnVector& tout)
+{
+  Matrix dummy;
+  return integrate (tout, dummy);
+}
+
+Matrix
+DASSL::integrate (const ColumnVector& tout, Matrix& xdot_out)
+{
+  Matrix retval;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      retval.resize (n_out, n);
+      xdot_out.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  retval.elem (0, i) = x.elem (i);
+	  xdot_out.elem (0, i) = xdot.elem (i);
+	}
+
+      for (octave_idx_type j = 1; j < n_out; j++)
+	{
+	  ColumnVector x_next = do_integrate (tout.elem (j));
+
+	  if (integration_error)
+	    return retval;
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      retval.elem (j, i) = x_next.elem (i);
+	      xdot_out.elem (j, i) = xdot.elem (i);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+Matrix
+DASSL::do_integrate (const ColumnVector& tout, const ColumnVector& tcrit)
+{
+  Matrix dummy;
+  return integrate (tout, dummy, tcrit);
+}
+
+Matrix
+DASSL::integrate (const ColumnVector& tout, Matrix& xdot_out,
+		  const ColumnVector& tcrit) 
+{
+  Matrix retval;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      retval.resize (n_out, n);
+      xdot_out.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  retval.elem (0, i) = x.elem (i);
+	  xdot_out.elem (0, i) = xdot.elem (i);
+	}
+
+      octave_idx_type n_crit = tcrit.capacity ();
+
+      if (n_crit > 0)
+	{
+	  octave_idx_type i_crit = 0;
+	  octave_idx_type i_out = 1;
+	  double next_crit = tcrit.elem (0);
+	  double next_out;
+	  while (i_out < n_out)
+	    {
+	      bool do_restart = false;
+
+	      next_out = tout.elem (i_out);
+	      if (i_crit < n_crit)
+		next_crit = tcrit.elem (i_crit);
+
+	      bool save_output;
+	      double t_out;
+
+	      if (next_crit == next_out)
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = true;
+		  i_out++;
+		  i_crit++;
+		  do_restart = true;
+		}
+	      else if (next_crit < next_out)
+		{
+		  if (i_crit < n_crit)
+		    {
+		      set_stop_time (next_crit);
+		      t_out = next_crit;
+		      save_output = false;
+		      i_crit++;
+		      do_restart = true;
+		    }
+		  else
+		    {
+		      clear_stop_time ();
+		      t_out = next_out;
+		      save_output = true;
+		      i_out++;
+		    }
+		}
+	      else
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = true;
+		  i_out++;
+		}
+
+	      ColumnVector x_next = do_integrate (t_out);
+
+	      if (integration_error)
+		return retval;
+
+	      if (save_output)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      retval.elem (i_out-1, i) = x_next.elem (i);
+		      xdot_out.elem (i_out-1, i) = xdot.elem (i);
+		    }
+		}
+
+	      if (do_restart)
+		force_restart ();
+	    }
+	}
+      else
+	{
+	  retval = integrate (tout, xdot_out);
+
+	  if (integration_error)
+	    return retval;
+	}
+    }
+
+  return retval;
+}
+
+std::string
+DASSL::error_message (void) const
+{
+  std::string retval;
+
+  std::ostringstream buf;
+  buf << t;
+  std::string t_curr = buf.str ();
+
+  switch (istate)
+    {
+    case 1:
+      retval = "a step was successfully taken in intermediate-output mode.";
+      break;
+
+    case 2:
+      retval = "integration completed by stepping exactly to TOUT";
+      break;
+
+    case 3:
+      retval = "integration to tout completed by stepping past TOUT";
+      break;
+
+    case -1:
+      retval = std::string ("a large amount of work has been expended (t =")
+	+ t_curr + ")";
+      break;
+
+    case -2:
+      retval = "the error tolerances are too stringent";
+      break;
+
+    case -3:
+      retval = std::string ("error weight became zero during problem. (t = ")
+	+ t_curr
+	+ "; solution component i vanished, and atol or atol(i) == 0)";
+      break;
+
+    case -6:
+      retval = std::string ("repeated error test failures on the last attempted step (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -7:
+      retval = std::string ("the corrector could not converge (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -8:
+      retval = std::string ("the matrix of partial derivatives is singular (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -9:
+      retval = std::string ("the corrector could not converge (t = ")
+	+ t_curr + "; repeated test failures)";
+      break;
+
+    case -10:
+      retval = std::string ("corrector could not converge because IRES was -1 (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -11:
+      retval = std::string ("return requested in user-supplied function (t = ")
+	+ t_curr + ")";
+      break;
+
+    case -12:
+      retval = "failed to compute consistent initial conditions";
+      break;
+
+    case -33:
+      retval = "unrecoverable error (see printed message)";
+      break;
+
+    default:
+      retval = "unknown error state";
+      break;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DASSL.h b/liboctave/DASSL.h
new file mode 100644
index 0000000..3fd4bc3
--- /dev/null
+++ b/liboctave/DASSL.h
@@ -0,0 +1,92 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DASSL_h)
+#define octave_DASSL_h 1
+
+#include <cfloat>
+
+#include "DASSL-opts.h"
+#include "lo-math.h"
+
+class
+OCTAVE_API
+DASSL : public DAE, public DASSL_options
+{
+public:
+
+  DASSL (void) : DAE (), DASSL_options (), initialized (false) { }
+
+  DASSL (const ColumnVector& s, double tm, DAEFunc& f)
+    : DAE (s, tm, f), DASSL_options (), initialized (false) { }
+
+  DASSL (const ColumnVector& s, const ColumnVector& deriv,
+	 double tm, DAEFunc& f)
+    : DAE (s, deriv, tm, f), DASSL_options (), initialized (false) { }
+
+  ~DASSL (void) { }
+
+  ColumnVector do_integrate (double t);
+
+  Matrix do_integrate (const ColumnVector& tout);
+
+  Matrix do_integrate (const ColumnVector& tout, const ColumnVector& tcrit); 
+
+  Matrix integrate (const ColumnVector& tout, Matrix& xdot_out);
+
+  Matrix integrate (const ColumnVector& tout, Matrix& xdot_out,
+		    const ColumnVector& tcrit); 
+
+  std::string error_message (void) const;
+
+private:
+
+  bool initialized;
+
+  octave_idx_type liw;  
+  octave_idx_type lrw;
+
+  Array<octave_idx_type> info;
+  Array<octave_idx_type> iwork;
+
+  Array<double> rwork;
+
+  Array<double> abs_tol;
+  Array<double> rel_tol;
+
+  double *px;
+  double *pxdot;
+  double *pabs_tol;
+  double *prel_tol;
+  octave_idx_type *pinfo;
+  octave_idx_type *piwork;
+  double *prwork;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DET.h b/liboctave/DET.h
new file mode 100644
index 0000000..67b67e7
--- /dev/null
+++ b/liboctave/DET.h
@@ -0,0 +1,88 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DET_h)
+#define octave_DET_h 1
+
+#include <cmath>
+#include "oct-cmplx.h"
+#include "lo-mappers.h"
+
+template <class T>
+class
+base_det
+{
+public:
+
+  base_det (T c = 1, int e = 0) 
+    { 
+      c2 = xlog2 (c, e2); 
+      e2 += e; 
+    }
+
+  base_det (T c, double e, double b) 
+    { 
+      e *= xlog2 (b);
+      e2 = e;
+      c *= xexp2 (e - e2);
+      int f;
+      c2 = xlog2 (c, f);
+      e2 += f;
+    }
+
+  base_det (const base_det& a) : c2(a.c2), e2(a.e2) { }
+
+  base_det& operator = (const base_det& a)
+    {
+      c2 = a.c2;
+      e2 = a.e2;
+      return *this;
+    }
+
+  T coef (void) const { return c2; }
+  int exp (void) const { return e2; }
+
+  T value () const { return c2 * static_cast<T> (std::ldexp (1.0, e2)); }
+  operator T () const { return value (); }
+
+  base_det square () const { return base_det (c2*c2, e2+e2); }
+
+  void operator *= (T t)
+    {
+      int e;
+      c2 *= xlog2 (t, e);
+      e2 += e;
+    }
+
+private:
+
+  T c2;
+  int e2;
+};
+
+// Provide the old types by typedefs.
+typedef base_det<double> DET;
+typedef base_det<float> FloatDET;
+typedef base_det<Complex> ComplexDET;
+typedef base_det<FloatComplex> FloatComplexDET;
+
+#endif
diff --git a/liboctave/DiagArray2.cc b/liboctave/DiagArray2.cc
new file mode 100644
index 0000000..942a680
--- /dev/null
+++ b/liboctave/DiagArray2.cc
@@ -0,0 +1,184 @@
+// Template array classes
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include <iostream>
+
+#include <algorithm>
+
+#include "DiagArray2.h"
+
+#include "lo-error.h"
+
+template <class T>
+const typename DiagArray2<T>::Proxy& 
+DiagArray2<T>::Proxy::operator = (const T& val) const
+{
+  if (i == j)
+    {
+      if (object)
+        object->set (val, i);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("invalid assignment to off-diagonal in diagonal array");
+
+  return *this;
+}
+
+template <class T>
+DiagArray2<T>::Proxy::operator T () const
+{
+  if (object && i == j)
+    return object->get (i);
+  else
+    {
+      static T foo;
+      return foo;
+    }
+}
+
+template <class T>
+Array<T>
+DiagArray2<T>::diag (octave_idx_type k) const
+{
+  Array<T> d;
+
+  if (k == 0)
+    // The main diagonal is shallow-copied.
+    d = *this;
+  else if (k > 0 && k < cols ())
+    d = Array<T> (std::min (cols () - k, rows ()), T ());
+  else if (k < 0 && -k < rows ())
+    d = Array<T> (std::min (rows () + k, cols ()), T ());
+  else
+    (*current_liboctave_error_handler)
+      ("diag: requested diagonal out of range");
+
+  return d;
+}
+
+template <class T>
+DiagArray2<T>
+DiagArray2<T>::transpose (void) const
+{
+  DiagArray2<T> retval (*this);
+  retval.d1 = d2;
+  retval.d2 = d1;
+  return retval;
+}
+
+template <class T>
+DiagArray2<T>
+DiagArray2<T>::hermitian (T (* fcn) (const T&)) const
+{
+  DiagArray2<T> retval (dim2 (), dim1 ());
+  const T *p = this->data ();
+  T *q = retval.fortran_vec ();
+  for (octave_idx_type i = 0; i < this->length (); i++)
+    q [i] = fcn (p [i]);
+  return retval;
+}
+
+// A two-dimensional array with diagonal elements only.
+
+template <class T>
+T
+DiagArray2<T>::checkelem (octave_idx_type r, octave_idx_type c) const
+{
+  if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
+    {
+      (*current_liboctave_error_handler) ("range error in DiagArray2");
+      return T ();
+    }
+  return elem (r, c);
+}
+
+template <class T>
+typename DiagArray2<T>::Proxy
+DiagArray2<T>::checkelem (octave_idx_type r, octave_idx_type c) 
+{
+  if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
+    {
+      (*current_liboctave_error_handler) ("range error in DiagArray2");
+      return Proxy (0, r, c);
+    }
+  else
+    return Proxy (this, r, c);
+}
+
+template <class T>
+void
+DiagArray2<T>::resize (octave_idx_type r, octave_idx_type c)
+{
+  if (r < 0 || c < 0)
+    {
+      (*current_liboctave_error_handler) ("can't resize to negative dimensions");
+      return;
+    }
+
+  if (r != dim1 () || c != dim2 ())
+    {
+      Array<T>::resize (std::min (r, c));
+      d1 = r; d2 = c;
+    }
+}
+
+template <class T>
+void
+DiagArray2<T>::resize_fill (octave_idx_type r, octave_idx_type c, const T& val)
+{
+  if (r < 0 || c < 0)
+    {
+      (*current_liboctave_error_handler) ("can't resize to negative dimensions");
+      return;
+    }
+
+  if (r != dim1 () || c != dim2 ())
+    {
+      Array<T>::resize_fill (std::min (r, c), val);
+      d1 = r; d2 = c;
+    }
+}
+
+template <class T>
+DiagArray2<T>::operator Array2<T> (void) const
+{
+  Array2<T> result (dim1 (), dim2 ());
+  for (octave_idx_type i = 0, len = length (); i < len; i++)
+    result.xelem (i, i) = dgelem (i);
+
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/DiagArray2.h b/liboctave/DiagArray2.h
new file mode 100644
index 0000000..29f4613
--- /dev/null
+++ b/liboctave/DiagArray2.h
@@ -0,0 +1,232 @@
+// Template array classes
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DiagArray2_h)
+#define octave_DiagArray2_h 1
+
+#include <cassert>
+#include <cstdlib>
+
+#include "Array.h"
+#include "Array2.h"
+#include "lo-error.h"
+
+// A two-dimensional array with diagonal elements only.
+// Idea and example code for Proxy class and functions from:
+//
+// From: kanze at us-es.sel.de (James Kanze)
+// Subject: Re: How to overload [] to do READ/WRITE differently ?
+// Message-ID: <KANZE.93Nov29151407 at slsvhdt.us-es.sel.de>
+// Sender: news at us-es.sel.de
+// Date: 29 Nov 1993 14:14:07 GMT
+// --
+// James Kanze                             email: kanze at us-es.sel.de
+// GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
+
+// Array<T> is inherited privately so that some methods, like index, don't
+// produce unexpected results.
+
+template <class T>
+class
+DiagArray2 : protected Array<T>
+{
+private:
+
+  T get (octave_idx_type i) { return Array<T>::xelem (i); }
+
+  void set (const T& val, octave_idx_type i) { Array<T>::xelem (i) = val; }
+
+  class Proxy
+  {
+  public:
+
+    Proxy (DiagArray2<T> *ref, octave_idx_type r, octave_idx_type c)
+      : i (r), j (c), object (ref) { } 
+
+    const Proxy& operator = (const T& val) const;
+
+    operator T () const;
+
+  private:
+
+    // FIXME -- this is declared private to keep the user from
+    // taking the address of a Proxy.  Maybe it should be implemented
+    // by means of a companion function in the DiagArray2 class.
+
+    T *operator& () const { assert (0); return 0; }
+
+    octave_idx_type i;
+    octave_idx_type j;
+
+    DiagArray2<T> *object;
+
+  };
+
+  friend class Proxy;
+
+protected:
+  octave_idx_type d1, d2;
+
+  DiagArray2 (T *d, octave_idx_type r, octave_idx_type c) 
+    : Array<T> (d, std::min (r, c)), d1 (r), d2 (c) { }
+
+public:
+
+  using Array<T>::element_type;
+
+  DiagArray2 (void) 
+    : Array<T> (), d1 (0), d2 (0) { }
+
+  DiagArray2 (octave_idx_type r, octave_idx_type c) 
+    : Array<T> (std::min (r, c)), d1 (r), d2 (c) { }
+
+  DiagArray2 (octave_idx_type r, octave_idx_type c, const T& val) 
+    : Array<T> (std::min (r, c), val), d1 (r), d2 (c) { }
+
+  DiagArray2 (const Array<T>& a) 
+    : Array<T> (a), d1 (a.numel ()), d2 (a.numel ()) { }
+
+  DiagArray2 (const DiagArray2<T>& a) 
+    : Array<T> (a), d1 (a.d1), d2 (a.d2) { }
+
+  template <class U>
+  DiagArray2 (const DiagArray2<U>& a) 
+  : Array<T> (a.diag ()), d1 (a.dim1 ()), d2 (a.dim2 ()) { }
+
+  ~DiagArray2 (void) { }
+
+  DiagArray2<T>& operator = (const DiagArray2<T>& a)
+    {
+      if (this != &a)
+        {
+          Array<T>::operator = (a);
+          d1 = a.d1;
+          d2 = a.d2;
+        }
+
+      return *this;
+    }
+
+  octave_idx_type dim1 (void) const { return d1; }
+  octave_idx_type dim2 (void) const { return d2; }
+
+  octave_idx_type rows (void) const { return dim1 (); }
+  octave_idx_type cols (void) const { return dim2 (); }
+  octave_idx_type columns (void) const { return dim2 (); }
+
+  // FIXME: a dangerous ambiguity?
+  octave_idx_type length (void) const { return Array<T>::length (); }
+  octave_idx_type nelem (void) const { return dim1 () * dim2 (); }
+  octave_idx_type numel (void) const { return nelem (); }
+
+  size_t byte_size (void) const { return length () * sizeof (T); }
+
+  dim_vector dims (void) const { return dim_vector (d1, d2); }
+
+  Array<T> diag (octave_idx_type k = 0) const;
+
+  // Warning: the non-const two-index versions will silently ignore assignments
+  // to off-diagonal elements. 
+
+  T elem (octave_idx_type r, octave_idx_type c) const
+    {
+      return (r == c) ? Array<T>::elem (r) : T (0);
+    }
+
+  T& elem (octave_idx_type r, octave_idx_type c)
+    {
+      static T zero (0);
+      return (r == c) ? Array<T>::elem (r) : zero;
+    }
+
+  T dgelem (octave_idx_type i) const
+    { return Array<T>::elem (i); }
+
+  T& dgelem (octave_idx_type i) 
+    { return Array<T>::elem (i); }
+
+  T checkelem (octave_idx_type r, octave_idx_type c) const;
+  Proxy checkelem (octave_idx_type r, octave_idx_type c);
+
+  T operator () (octave_idx_type r, octave_idx_type c) const
+    {
+#if defined (BOUNDS_CHECKING)
+      return checkelem (r, c);
+#else
+      return elem (r, c);
+#endif
+    }
+
+  // FIXME: can this cause problems?
+#if defined (BOUNDS_CHECKING)
+  Proxy operator () (octave_idx_type r, octave_idx_type c)
+    {
+      return checkelem (r, c);
+    }
+#else
+  T& operator () (octave_idx_type r, octave_idx_type c) 
+    {
+      return elem (r, c);
+    }
+#endif
+
+  // No checking.
+
+  T xelem (octave_idx_type r, octave_idx_type c) const
+    {
+      return (r == c) ? Array<T>::xelem (r) : T (0);
+    }
+
+  T& dgxelem (octave_idx_type i)
+    { return Array<T>::xelem (i); }
+
+  T dgxelem (octave_idx_type i) const
+    { return Array<T>::xelem (i); }
+
+  void resize (octave_idx_type n, octave_idx_type m);
+  void resize_fill (octave_idx_type n, octave_idx_type m, const T& val);
+
+  DiagArray2<T> transpose (void) const;
+  DiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const;
+
+  operator Array2<T> (void) const;
+
+  const T *data (void) const { return Array<T>::data (); }
+
+  const T *fortran_vec (void) const { return Array<T>::fortran_vec (); }
+
+  T *fortran_vec (void) { return Array<T>::fortran_vec (); }
+
+  void print_info (std::ostream& os, const std::string& prefix) const
+    { Array<T>::print_info (os, prefix); }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/EIG.cc b/liboctave/EIG.cc
new file mode 100644
index 0000000..5607cd1
--- /dev/null
+++ b/liboctave/EIG.cc
@@ -0,0 +1,870 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "EIG.h"
+#include "dColVector.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgeev, DGEEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, double*, const octave_idx_type&, double*,
+			   double*, double*, const octave_idx_type&, double*,
+			   const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zgeev, ZGEEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, Complex*, const octave_idx_type&, Complex*,
+			   Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+			   Complex*, const octave_idx_type&, double*, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dsyev, DSYEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, double*, const octave_idx_type&, double*,
+			   double*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zheev, ZHEEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, Complex*, const octave_idx_type&, double*,
+			   Complex*, const octave_idx_type&, double*, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpotrf, DPOTRF) (F77_CONST_CHAR_ARG_DECL, 
+			   const octave_idx_type&, 
+			   double*, const octave_idx_type&,
+			   octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zpotrf, ZPOTRF) (F77_CONST_CHAR_ARG_DECL, 
+			   const octave_idx_type&, 
+			   Complex*, const octave_idx_type&,
+			   octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dggev, DGGEV) (F77_CONST_CHAR_ARG_DECL, 
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   double*, const octave_idx_type&,
+			   double*, const octave_idx_type&,
+			   double*, double*, double *,
+			   double*, const octave_idx_type&, double*, const octave_idx_type&,
+			   double*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dsygv, DSYGV) (const octave_idx_type&,
+			   F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   double*, const octave_idx_type&,
+			   double*, const octave_idx_type&,
+			   double*, double*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zggev, ZGGEV) (F77_CONST_CHAR_ARG_DECL, 
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   Complex*, const octave_idx_type&,
+			   Complex*, const octave_idx_type&,
+			   Complex*, Complex*,
+			   Complex*, const octave_idx_type&, Complex*, const octave_idx_type&,
+			   Complex*, const octave_idx_type&, double*, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zhegv, ZHEGV) (const octave_idx_type&,
+			   F77_CONST_CHAR_ARG_DECL, 
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   Complex*, const octave_idx_type&,
+			   Complex*, const octave_idx_type&,
+			   double*, Complex*, const octave_idx_type&, double*, 
+			   octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+}
+
+octave_idx_type
+EIG::init (const Matrix& a, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  if (a.is_symmetric ())
+    return symmetric_init (a, calc_ev);
+
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  Matrix atmp = a;
+  double *tmp_data = atmp.fortran_vec ();
+
+  Array<double> wr (n);
+  double *pwr = wr.fortran_vec ();
+
+  Array<double> wi (n);
+  double *pwi = wi.fortran_vec ();
+
+  octave_idx_type tnvr = calc_ev ? n : 0;
+  Matrix vr (tnvr, tnvr);
+  double *pvr = vr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  double dummy_work;
+
+  double *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (dgeev, DGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, tmp_data, n, pwr, pwi, dummy,
+			   idummy, pvr, n, &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<double> work (lwork);
+      double *pwork = work.fortran_vec ();
+
+      F77_XFCN (dgeev, DGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, tmp_data, n, pwr, pwi, dummy,
+			       idummy, pvr, n, pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in dgeev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("dgeev failed to converge");
+	  return info;
+	}
+
+      lambda.resize (n);
+      octave_idx_type nvr = calc_ev ? n : 0;
+      v.resize (nvr, nvr);
+
+      for (octave_idx_type j = 0; j < n; j++)
+	{
+	  if (wi.elem (j) == 0.0)
+	    {
+	      lambda.elem (j) = Complex (wr.elem (j));
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		v.elem (i, j) = vr.elem (i, j);
+	    }
+	  else
+	    {
+	      if (j+1 >= n)
+		{
+		  (*current_liboctave_error_handler) ("EIG: internal error");
+		  return -1;
+		}
+
+	      lambda.elem(j) = Complex (wr.elem(j), wi.elem(j));
+	      lambda.elem(j+1) = Complex (wr.elem(j+1), wi.elem(j+1));
+
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		{
+		  double real_part = vr.elem (i, j);
+		  double imag_part = vr.elem (i, j+1);
+		  v.elem (i, j) = Complex (real_part, imag_part);
+		  v.elem (i, j+1) = Complex (real_part, -imag_part);
+		}
+	      j++;
+	    }
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("dgeev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type 
+EIG::symmetric_init (const Matrix& a, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  Matrix atmp = a;
+  double *tmp_data = atmp.fortran_vec ();
+
+  ColumnVector wr (n);
+  double *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  double dummy_work;
+
+  F77_XFCN (dsyev, DSYEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, tmp_data, n, pwr, &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<double> work (lwork);
+      double *pwork = work.fortran_vec ();
+
+      F77_XFCN (dsyev, DSYEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, tmp_data, n, pwr, pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in dsyev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("dsyev failed to converge");
+	  return info;
+	}
+
+      lambda = ComplexColumnVector (wr);
+      v = calc_ev ? ComplexMatrix (atmp) : ComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("dsyev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+EIG::init (const ComplexMatrix& a, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  if (a.is_hermitian ())
+    return hermitian_init (a, calc_ev);
+
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  ComplexMatrix atmp = a;
+  Complex *tmp_data = atmp.fortran_vec ();
+
+  ComplexColumnVector w (n);
+  Complex *pw = w.fortran_vec ();
+
+  octave_idx_type nvr = calc_ev ? n : 0;
+  ComplexMatrix vtmp (nvr, nvr);
+  Complex *pv = vtmp.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  Complex dummy_work;
+
+  octave_idx_type lrwork = 2*n;
+  Array<double> rwork (lrwork);
+  double *prwork = rwork.fortran_vec ();
+
+  Complex *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (zgeev, ZGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, tmp_data, n, pw, dummy, idummy,
+			   pv, n, &dummy_work, lwork, prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<Complex> work (lwork);
+      Complex *pwork = work.fortran_vec ();
+
+      F77_XFCN (zgeev, ZGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, tmp_data, n, pw, dummy, idummy,
+			       pv, n, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in zgeev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("zgeev failed to converge");
+	  return info;
+	}
+
+      lambda = w;
+      v = vtmp;
+    }
+  else
+    (*current_liboctave_error_handler) ("zgeev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+EIG::hermitian_init (const ComplexMatrix& a, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  ComplexMatrix atmp = a;
+  Complex *tmp_data = atmp.fortran_vec ();
+
+  ColumnVector wr (n);
+  double *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  Complex dummy_work;
+
+  octave_idx_type lrwork = 3*n;
+  Array<double> rwork (lrwork);
+  double *prwork = rwork.fortran_vec ();
+
+  F77_XFCN (zheev, ZHEEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, tmp_data, n, pwr, &dummy_work, lwork,
+			   prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<Complex> work (lwork);
+      Complex *pwork = work.fortran_vec ();
+
+      F77_XFCN (zheev, ZHEEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, tmp_data, n, pwr, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in zheev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("zheev failed to converge");
+	  return info;
+	}
+
+      lambda = ComplexColumnVector (wr);
+      v = calc_ev ? ComplexMatrix (atmp) : ComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("zheev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+EIG::init (const Matrix& a, const Matrix& b, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  Matrix tmp = b;
+  double *tmp_data = tmp.fortran_vec ();
+
+  F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, tmp_data, n, 
+			     info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (a.is_symmetric () && b.is_symmetric () && info == 0)
+    return symmetric_init (a, b, calc_ev);
+
+  Matrix atmp = a;
+  double *atmp_data = atmp.fortran_vec ();
+
+  Matrix btmp = b;
+  double *btmp_data = btmp.fortran_vec ();
+
+  Array<double> ar (n);
+  double *par = ar.fortran_vec ();
+
+  Array<double> ai (n);
+  double *pai = ai.fortran_vec ();
+
+  Array<double> beta (n);
+  double *pbeta = beta.fortran_vec ();
+
+  octave_idx_type tnvr = calc_ev ? n : 0;
+  Matrix vr (tnvr, tnvr);
+  double *pvr = vr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  double dummy_work;
+
+  double *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (dggev, DGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, atmp_data, n, btmp_data, n, 
+			   par, pai, pbeta,
+			   dummy, idummy, pvr, n,
+			   &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<double> work (lwork);
+      double *pwork = work.fortran_vec ();
+
+      F77_XFCN (dggev, DGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, atmp_data, n, btmp_data, n, 
+			       par, pai, pbeta,
+			       dummy, idummy, pvr, n,
+			       pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in dggev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("dggev failed to converge");
+	  return info;
+	}
+
+      lambda.resize (n);
+      octave_idx_type nvr = calc_ev ? n : 0;
+      v.resize (nvr, nvr);
+
+      for (octave_idx_type j = 0; j < n; j++)
+	{
+	  if (ai.elem (j) == 0.0)
+	    {
+	      lambda.elem (j) = Complex (ar.elem (j) / beta.elem (j));
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		v.elem (i, j) = vr.elem (i, j);
+	    }
+	  else
+	    {
+	      if (j+1 >= n)
+		{
+		  (*current_liboctave_error_handler) ("EIG: internal error");
+		  return -1;
+		}
+
+	      lambda.elem(j) = Complex (ar.elem(j) / beta.elem (j), 
+	                                ai.elem(j) / beta.elem (j));
+	      lambda.elem(j+1) = Complex (ar.elem(j+1) / beta.elem (j+1), 
+	                                  ai.elem(j+1) / beta.elem (j+1));
+
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		{
+		  double real_part = vr.elem (i, j);
+		  double imag_part = vr.elem (i, j+1);
+		  v.elem (i, j) = Complex (real_part, imag_part);
+		  v.elem (i, j+1) = Complex (real_part, -imag_part);
+		}
+	      j++;
+	    }
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("dggev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type 
+EIG::symmetric_init (const Matrix& a, const Matrix& b, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  Matrix atmp = a;
+  double *atmp_data = atmp.fortran_vec ();
+
+  Matrix btmp = b;
+  double *btmp_data = btmp.fortran_vec ();
+
+  ColumnVector wr (n);
+  double *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  double dummy_work;
+
+  F77_XFCN (dsygv, DSYGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, atmp_data, n, 
+			   btmp_data, n, 
+			   pwr, &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<double> work (lwork);
+      double *pwork = work.fortran_vec ();
+
+      F77_XFCN (dsygv, DSYGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, atmp_data, n, 
+			       btmp_data, n, 
+			       pwr, pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in dsygv");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("dsygv failed to converge");
+	  return info;
+	}
+
+      lambda = ComplexColumnVector (wr);
+      v = calc_ev ? ComplexMatrix (atmp) : ComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("dsygv workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+EIG::init (const ComplexMatrix& a, const ComplexMatrix& b, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  ComplexMatrix tmp = b;
+  Complex*tmp_data = tmp.fortran_vec ();
+
+  F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, tmp_data, n, 
+			     info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (a.is_hermitian () && b.is_hermitian () && info == 0)
+    return hermitian_init (a, calc_ev);
+
+  ComplexMatrix atmp = a;
+  Complex *atmp_data = atmp.fortran_vec ();
+
+  ComplexMatrix btmp = b;
+  Complex *btmp_data = btmp.fortran_vec ();
+
+  ComplexColumnVector alpha (n);
+  Complex *palpha = alpha.fortran_vec ();
+
+  ComplexColumnVector beta (n);
+  Complex *pbeta = beta.fortran_vec ();
+
+  octave_idx_type nvr = calc_ev ? n : 0;
+  ComplexMatrix vtmp (nvr, nvr);
+  Complex *pv = vtmp.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  Complex dummy_work;
+
+  octave_idx_type lrwork = 8*n;
+  Array<double> rwork (lrwork);
+  double *prwork = rwork.fortran_vec ();
+
+  Complex *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (zggev, ZGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, atmp_data, n, btmp_data, n, 
+			   palpha, pbeta, dummy, idummy,
+			   pv, n, &dummy_work, lwork, prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<Complex> work (lwork);
+      Complex *pwork = work.fortran_vec ();
+
+      F77_XFCN (zggev, ZGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, atmp_data, n, btmp_data, n, 
+			       palpha, pbeta, dummy, idummy,
+			       pv, n, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+      
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in zggev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("zggev failed to converge");
+	  return info;
+	}
+
+      lambda.resize (n);
+
+      for (octave_idx_type j = 0; j < n; j++)
+        lambda.elem (j) = alpha.elem (j) / beta.elem(j);
+
+      v = vtmp;
+    }
+  else
+    (*current_liboctave_error_handler) ("zggev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+EIG::hermitian_init (const ComplexMatrix& a, const ComplexMatrix& b, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  ComplexMatrix atmp = a;
+  Complex *atmp_data = atmp.fortran_vec ();
+
+  ComplexMatrix btmp = b;
+  Complex *btmp_data = btmp.fortran_vec ();
+
+  ColumnVector wr (n);
+  double *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  Complex dummy_work;
+
+  octave_idx_type lrwork = 3*n;
+  Array<double> rwork (lrwork);
+  double *prwork = rwork.fortran_vec ();
+
+  F77_XFCN (zhegv, ZHEGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, atmp_data, n, 
+			   btmp_data, n,
+			   pwr, &dummy_work, lwork,
+			   prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<Complex> work (lwork);
+      Complex *pwork = work.fortran_vec ();
+
+      F77_XFCN (zhegv, ZHEGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, atmp_data, n, 
+			       btmp_data, n, 
+			       pwr, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in zhegv");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("zhegv failed to converge");
+	  return info;
+	}
+
+      lambda = ComplexColumnVector (wr);
+      v = calc_ev ? ComplexMatrix (atmp) : ComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("zhegv workspace query failed");
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/EIG.h b/liboctave/EIG.h
new file mode 100644
index 0000000..c99150d
--- /dev/null
+++ b/liboctave/EIG.h
@@ -0,0 +1,112 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_EIG_h)
+#define octave_EIG_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "CMatrix.h"
+#include "CColVector.h"
+
+class
+OCTAVE_API
+EIG
+{
+friend class Matrix;
+friend class ComplexMatrix;
+
+public:
+
+  EIG (void)
+    : lambda (), v () { }
+
+  EIG (const Matrix& a, bool calc_eigenvectors = true)
+    { init (a, calc_eigenvectors); }
+
+  EIG (const Matrix& a, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, calc_eigenvectors); }
+
+  EIG (const Matrix& a, const Matrix& b, bool calc_eigenvectors = true)
+    { init (a, b, calc_eigenvectors); }
+
+  EIG (const Matrix& a, const Matrix& b, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, b, calc_eigenvectors); }
+
+  EIG (const ComplexMatrix& a, bool calc_eigenvectors = true)
+    { init (a, calc_eigenvectors); }
+
+  EIG (const ComplexMatrix& a, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, calc_eigenvectors); }
+
+  EIG (const ComplexMatrix& a, const ComplexMatrix& b, bool calc_eigenvectors = true)
+    { init (a, b, calc_eigenvectors); }
+
+  EIG (const ComplexMatrix& a, const ComplexMatrix& b, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, b, calc_eigenvectors); }
+
+  EIG (const EIG& a)
+    : lambda (a.lambda), v (a.v) { }
+
+  EIG& operator = (const EIG& a)
+    {
+      if (this != &a)
+	{
+	  lambda = a.lambda;
+	  v = a.v;
+	}
+      return *this;
+    }
+
+  ~EIG (void) { }
+
+  ComplexColumnVector eigenvalues (void) const { return lambda; }
+
+  ComplexMatrix eigenvectors (void) const { return v; }
+
+  friend std::ostream&  operator << (std::ostream& os, const EIG& a);
+
+private:
+
+  ComplexColumnVector lambda;
+  ComplexMatrix v;
+
+  octave_idx_type init (const Matrix& a, bool calc_eigenvectors);
+  octave_idx_type init (const Matrix& a, const Matrix& b, bool calc_eigenvectors);
+  octave_idx_type init (const ComplexMatrix& a, bool calc_eigenvectors);
+  octave_idx_type init (const ComplexMatrix& a, const ComplexMatrix& b, bool calc_eigenvectors);
+
+  octave_idx_type symmetric_init (const Matrix& a, bool calc_eigenvectors);
+  octave_idx_type symmetric_init (const Matrix& a, const Matrix& b, bool calc_eigenvectors);
+  octave_idx_type hermitian_init (const ComplexMatrix& a, bool calc_eigenvectors);
+  octave_idx_type hermitian_init (const ComplexMatrix& a, const ComplexMatrix& b, bool calc_eigenvectors);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/LSODE-opts.h b/liboctave/LSODE-opts.h
new file mode 100644
index 0000000..8cd538e
--- /dev/null
+++ b/liboctave/LSODE-opts.h
@@ -0,0 +1,142 @@
+// DO NOT EDIT!
+// Generated automatically from LSODE-opts.in.
+
+#if !defined (octave_LSODE_options_h)
+#define octave_LSODE_options_h 1
+
+#include <cfloat>
+#include <cmath>
+
+#include <ODE.h>
+
+
+class
+LSODE_options
+{
+public:
+
+  LSODE_options (void) { init (); }
+
+  LSODE_options (const LSODE_options& opt) { copy (opt); }
+
+  LSODE_options& operator = (const LSODE_options& opt)
+    {
+      if (this != &opt)
+        copy (opt);
+
+      return *this;
+    }
+
+  ~LSODE_options (void) { }
+
+  void init (void)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = ::sqrt (DBL_EPSILON);
+      x_relative_tolerance = ::sqrt (DBL_EPSILON);
+      x_integration_method = "stiff";
+      x_initial_step_size = -1.0;
+      x_maximum_order = -1;
+      x_maximum_step_size = -1.0;
+      x_minimum_step_size = 0.0;
+      x_step_limit = 100000;
+      reset = true;
+    }
+
+  void copy (const LSODE_options& opt)
+    {
+      x_absolute_tolerance = opt.x_absolute_tolerance;
+      x_relative_tolerance = opt.x_relative_tolerance;
+      x_integration_method = opt.x_integration_method;
+      x_initial_step_size = opt.x_initial_step_size;
+      x_maximum_order = opt.x_maximum_order;
+      x_maximum_step_size = opt.x_maximum_step_size;
+      x_minimum_step_size = opt.x_minimum_step_size;
+      x_step_limit = opt.x_step_limit;
+      reset = opt.reset;
+    }
+
+  void set_options (const LSODE_options& opt) { copy (opt); }
+
+  void set_default_options (void) { init (); }
+
+  void set_absolute_tolerance (double val)
+    {
+      x_absolute_tolerance.resize (1);
+      x_absolute_tolerance(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+      reset = true;
+    }
+
+  void set_absolute_tolerance (const Array<double>& val)
+    { x_absolute_tolerance = val; reset = true; }
+
+  void set_relative_tolerance (double val)
+    { x_relative_tolerance = (val > 0.0) ? val : ::sqrt (DBL_EPSILON); reset = true; }
+
+  void set_integration_method (const std::string& val)
+    {
+      if (val == "stiff" || val == "bdf")
+        x_integration_method = "stiff";
+      else if (val == "non-stiff" || val == "adams")
+        x_integration_method = "non-stiff";
+      else
+        (*current_liboctave_error_handler)
+          ("lsode_options: method must be \"stiff\", \"bdf\", \"non-stiff\", or \"adams\"");
+      reset = true;
+    }
+
+  void set_initial_step_size (double val)
+    { x_initial_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_maximum_order (octave_idx_type val)
+    { x_maximum_order = val; reset = true; }
+
+  void set_maximum_step_size (double val)
+    { x_maximum_step_size = (val >= 0.0) ? val : -1.0; reset = true; }
+
+  void set_minimum_step_size (double val)
+    { x_minimum_step_size = (val >= 0.0) ? val : 0.0; reset = true; }
+
+  void set_step_limit (octave_idx_type val)
+    { x_step_limit = val; reset = true; }
+  Array<double> absolute_tolerance (void) const
+    { return x_absolute_tolerance; }
+
+  double relative_tolerance (void) const
+    { return x_relative_tolerance; }
+
+  std::string integration_method (void) const
+    { return x_integration_method; }
+
+  double initial_step_size (void) const
+    { return x_initial_step_size; }
+
+  octave_idx_type maximum_order (void) const
+    { return x_maximum_order; }
+
+  double maximum_step_size (void) const
+    { return x_maximum_step_size; }
+
+  double minimum_step_size (void) const
+    { return x_minimum_step_size; }
+
+  octave_idx_type step_limit (void) const
+    { return x_step_limit; }
+
+private:
+
+  Array<double> x_absolute_tolerance;
+  double x_relative_tolerance;
+  std::string x_integration_method;
+  double x_initial_step_size;
+  octave_idx_type x_maximum_order;
+  double x_maximum_step_size;
+  double x_minimum_step_size;
+  octave_idx_type x_step_limit;
+
+protected:
+
+  bool reset;
+};
+
+#endif
diff --git a/liboctave/LSODE-opts.in b/liboctave/LSODE-opts.in
new file mode 100644
index 0000000..bf171ec
--- /dev/null
+++ b/liboctave/LSODE-opts.in
@@ -0,0 +1,151 @@
+# Copyright (C) 2002, 2005, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+CLASS = "LSODE"
+
+INCLUDE = "ODE.h"
+
+OPTION
+  NAME = "absolute tolerance"
+  DOC_ITEM
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector.
+  END_DOC_ITEM
+  TYPE = "Array<double>"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_BODY
+    $OPTVAR.resize (1);
+    $OPTVAR(0) = ::sqrt (DBL_EPSILON);
+  END_INIT_BODY
+  SET_CODE
+    void set_$OPT (double val)
+      {
+        $OPTVAR.resize (1);
+        $OPTVAR(0) = (val > 0.0) ? val : ::sqrt (DBL_EPSILON);
+        reset = true;
+      }
+
+    void set_$OPT (const $TYPE& val)
+      { $OPTVAR = val; reset = true; }
+  END_SET_CODE
+END_OPTION
+
+OPTION
+  NAME = "relative tolerance"
+  DOC_ITEM
+Relative tolerance parameter.  Unlike the absolute tolerance, this
+parameter may only be a scalar.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i)) <= ...
+      rtol * abs (y(i)) + atol(i)
+ at end group
+ at end example
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "::sqrt (DBL_EPSILON)"
+  SET_EXPR = "(val > 0.0) ? val : ::sqrt (DBL_EPSILON)"
+END_OPTION
+
+OPTION
+  NAME = "integration method"
+  DOC_ITEM
+A string specifying the method of integration to use to solve the ODE
+system.  Valid values are
+
+ at table @asis
+ at item \"adams\"
+ at itemx \"non-stiff\"
+No Jacobian used (even if it is available).
+ at item \"bdf\"
+ at item \"stiff\"
+Use stiff backward differentiation formula (BDF) method.  If a
+function to compute the Jacobian is not supplied, @code{lsode} will
+compute a finite difference approximation of the Jacobian matrix.
+ at end table
+  END_DOC_ITEM
+  TYPE = "std::string"
+  SET_ARG_TYPE = "const $TYPE&"
+  INIT_VALUE = ""stiff""
+  SET_BODY
+    if (val == "stiff" || val == "bdf")
+      $OPTVAR = "stiff";
+    else if (val == "non-stiff" || val == "adams")
+      $OPTVAR = "non-stiff";
+    else
+      (*current_liboctave_error_handler)
+        ("lsode_options: method must be \"stiff\", \"bdf\", \"non-stiff\", or \"adams\"");
+  END_SET_BODY
+END_OPTION
+
+OPTION
+  NAME = "initial step size"
+  DOC_ITEM
+The step size to be attempted on the first step (default is determined
+automatically).
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "maximum order"
+  DOC_ITEM
+Restrict the maximum order of the solution method.  If using the Adams
+method, this option must be between 1 and 12.  Otherwise, it must be
+between 1 and 5, inclusive.
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "-1"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "maximum step size"
+  DOC_ITEM
+Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified).
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "-1.0"
+  SET_EXPR = "(val >= 0.0) ? val : -1.0"
+END_OPTION
+
+OPTION
+  NAME = "minimum step size"
+  DOC_ITEM
+The minimum absolute step size allowed (default is 0).
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "0.0"
+  SET_EXPR = "(val >= 0.0) ? val : 0.0"
+END_OPTION
+
+OPTION
+  NAME = "step limit"
+  DOC_ITEM
+Maximum number of steps allowed (default is 100000).
+  END_DOC_ITEM
+  TYPE = "octave_idx_type"
+  INIT_VALUE = "100000"
+  SET_EXPR = "val"
+END_OPTION
diff --git a/liboctave/LSODE.cc b/liboctave/LSODE.cc
new file mode 100644
index 0000000..0022109
--- /dev/null
+++ b/liboctave/LSODE.cc
@@ -0,0 +1,505 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <sstream>
+
+#include "LSODE.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-math.h"
+#include "quit.h"
+
+typedef octave_idx_type (*lsode_fcn_ptr) (const octave_idx_type&, const double&, double*,
+			      double*, octave_idx_type&);
+
+typedef octave_idx_type (*lsode_jac_ptr) (const octave_idx_type&, const double&, double*,
+			      const octave_idx_type&, const octave_idx_type&, double*, const
+			      octave_idx_type&);
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dlsode, DLSODE) (lsode_fcn_ptr, octave_idx_type&, double*, double&,
+			     double&, octave_idx_type&, double&, const double*, octave_idx_type&,
+			     octave_idx_type&, octave_idx_type&, double*, octave_idx_type&, octave_idx_type*, octave_idx_type&,
+			     lsode_jac_ptr, octave_idx_type&);
+}
+
+static ODEFunc::ODERHSFunc user_fun;
+static ODEFunc::ODEJacFunc user_jac;
+static ColumnVector *tmp_x;
+
+static octave_idx_type
+lsode_f (const octave_idx_type& neq, const double& time, double *,
+	 double *deriv, octave_idx_type& ierr) 
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  ColumnVector tmp_deriv;
+
+  // NOTE: this won't work if LSODE passes copies of the state vector.
+  //       In that case we have to create a temporary vector object
+  //       and copy.
+
+  tmp_deriv = (*user_fun) (*tmp_x, time);
+
+  if (tmp_deriv.length () == 0)
+    ierr = -1;
+  else
+    {
+      for (octave_idx_type i = 0; i < neq; i++)
+	deriv [i] = tmp_deriv.elem (i);
+    }
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+static octave_idx_type
+lsode_j (const octave_idx_type& neq, const double& time, double *,
+	 const octave_idx_type&, const octave_idx_type&, double *pd, const octave_idx_type& nrowpd)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  Matrix tmp_jac (neq, neq);
+
+  // NOTE: this won't work if LSODE passes copies of the state vector.
+  //       In that case we have to create a temporary vector object
+  //       and copy.
+
+  tmp_jac = (*user_jac) (*tmp_x, time);
+
+  for (octave_idx_type j = 0; j < neq; j++)
+    for (octave_idx_type i = 0; i < neq; i++)
+      pd [nrowpd * j + i] = tmp_jac (i, j);
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+ColumnVector
+LSODE::do_integrate (double tout)
+{
+  ColumnVector retval;
+
+  static octave_idx_type nn = 0;
+
+  if (! initialized || restart || ODEFunc::reset || LSODE_options::reset)
+    {
+      integration_error = false;
+
+      initialized = true;
+
+      istate = 1;
+
+      octave_idx_type n = size ();
+
+      nn = n;
+
+      octave_idx_type max_maxord = 0;
+
+      if (integration_method () == "stiff")
+	{
+	  max_maxord = 5;
+
+	  if (jac)
+	    method_flag = 21;
+	  else
+	    method_flag = 22;
+
+	  liw = 20 + n;
+	  lrw = 22 + n * (9 + n);
+	}
+      else
+	{
+	  max_maxord = 12;
+
+	  method_flag = 10;
+
+	  liw = 20;
+	  lrw = 22 + 16 * n;
+	}
+
+      maxord = maximum_order ();
+
+      iwork.resize (liw);
+
+      for (octave_idx_type i = 4; i < 9; i++)
+	iwork(i) = 0;
+
+      rwork.resize (lrw);
+
+      for (octave_idx_type i = 4; i < 9; i++)
+	rwork(i) = 0;
+
+      if (maxord >= 0)
+	{
+	  if (maxord > 0 && maxord <= max_maxord)
+	    {
+	      iwork(4) = maxord;
+	      iopt = 1;
+	    }	  
+	  else
+	    {
+	      (*current_liboctave_error_handler)
+		("lsode: invalid value for maximum order");
+	      integration_error = true;
+	      return retval;
+	    }
+	}
+
+      if (stop_time_set)
+	{
+	  itask = 4;
+	  rwork(0) = stop_time;
+	  iopt = 1;
+	}
+      else
+	{
+	  itask = 1;
+	}
+
+      px = x.fortran_vec ();
+
+      piwork = iwork.fortran_vec ();
+      prwork = rwork.fortran_vec ();
+
+      restart = false;
+
+      // ODEFunc
+
+      // NOTE: this won't work if LSODE passes copies of the state vector.
+      //       In that case we have to create a temporary vector object
+      //       and copy.
+
+      tmp_x = &x;
+
+      user_fun = function ();
+      user_jac = jacobian_function ();
+
+      ColumnVector xdot = (*user_fun) (x, t);
+
+      if (x.length () != xdot.length ())
+	{
+	  (*current_liboctave_error_handler)
+	    ("lsode: inconsistent sizes for state and derivative vectors");
+
+	  integration_error = true;
+	  return retval;
+	}
+
+      ODEFunc::reset = false;
+
+      // LSODE_options
+
+      rel_tol = relative_tolerance ();
+      abs_tol = absolute_tolerance ();
+
+      octave_idx_type abs_tol_len = abs_tol.length ();
+
+      if (abs_tol_len == 1)
+	itol = 1;
+      else if (abs_tol_len == n)
+	itol = 2;
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("lsode: inconsistent sizes for state and absolute tolerance vectors");
+
+	  integration_error = true;
+	  return retval;
+	}
+
+      double iss = initial_step_size ();
+      if (iss >= 0.0)
+	{
+	  rwork(4) = iss;
+	  iopt = 1;
+	}
+
+      double maxss = maximum_step_size ();
+      if (maxss >= 0.0)
+	{
+	  rwork(5) = maxss;
+	  iopt = 1;
+	}
+
+      double minss = minimum_step_size ();
+      if (minss >= 0.0)
+	{
+	  rwork(6) = minss;
+	  iopt = 1;
+	}
+
+      octave_idx_type sl = step_limit ();
+      if (sl > 0)
+	{
+	  iwork(5) = sl;
+	  iopt = 1;
+	}
+
+      pabs_tol = abs_tol.fortran_vec ();
+
+      LSODE_options::reset = false;
+    }
+
+  F77_XFCN (dlsode, DLSODE, (lsode_f, nn, px, t, tout, itol, rel_tol,
+			     pabs_tol, itask, istate, iopt, prwork, lrw,
+			     piwork, liw, lsode_j, method_flag));
+
+  switch (istate)
+    {
+    case 1:  // prior to initial integration step.
+    case 2:  // lsode was successful.
+      retval = x;
+      t = tout;
+      break;
+
+    case -1:  // excess work done on this call (perhaps wrong mf).
+    case -2:  // excess accuracy requested (tolerances too small).
+    case -3:  // invalid input detected (see printed message).
+    case -4:  // repeated error test failures (check all inputs).
+    case -5:  // repeated convergence failures (perhaps bad jacobian
+	      // supplied or wrong choice of mf or tolerances).
+    case -6:  // error weight became zero during problem. (solution
+	      // component i vanished, and atol or atol(i) = 0.)
+    case -13: // return requested in user-supplied function.
+      integration_error = true;
+      break;
+
+    default:
+      integration_error = true;
+      (*current_liboctave_error_handler)
+	("unrecognized value of istate (= %d) returned from lsode",
+	 istate);
+      break;
+    }
+
+  return retval;
+}
+
+std::string
+LSODE::error_message (void) const
+{
+  std::string retval;
+
+  std::ostringstream buf;
+  buf << t;
+  std::string t_curr = buf.str ();
+
+  switch (istate)
+    {
+    case 1:
+      retval = "prior to initial integration step";
+      break;
+
+    case 2:
+      retval = "successful exit";
+      break;
+	  
+    case 3:
+      retval = "prior to continuation call with modified parameters";
+      break;
+	  
+    case -1:
+      retval = std::string ("excess work on this call (t = ")
+	+ t_curr + "; perhaps wrong integration method)";
+      break;
+
+    case -2:
+      retval = "excess accuracy requested (tolerances too small)";
+      break;
+
+    case -3:
+      retval = "invalid input detected (see printed message)";
+      break;
+
+    case -4:
+      retval = std::string ("repeated error test failures (t = ")
+	+ t_curr + "check all inputs)";
+      break;
+
+    case -5:
+      retval = std::string ("repeated convergence failures (t = ")
+	+ t_curr
+	+ "perhaps bad jacobian supplied or wrong choice of integration method or tolerances)";
+      break;
+
+    case -6:
+      retval = std::string ("error weight became zero during problem. (t = ")
+	+ t_curr
+	+ "; solution component i vanished, and atol or atol(i) == 0)";
+      break;
+
+    case -13:
+      retval = "return requested in user-supplied function (t = "
+	+ t_curr + ")";
+      break;
+
+    default:
+      retval = "unknown error state";
+      break;
+    }
+
+  return retval;
+}
+
+Matrix
+LSODE::do_integrate (const ColumnVector& tout)
+{
+  Matrix retval;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      retval.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	retval.elem (0, i) = x.elem (i);
+
+      for (octave_idx_type j = 1; j < n_out; j++)
+	{
+	  ColumnVector x_next = do_integrate (tout.elem (j));
+
+	  if (integration_error)
+	    return retval;
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    retval.elem (j, i) = x_next.elem (i);
+	}
+    }
+
+  return retval;
+}
+
+Matrix
+LSODE::do_integrate (const ColumnVector& tout, const ColumnVector& tcrit)
+{
+  Matrix retval;
+
+  octave_idx_type n_out = tout.capacity ();
+  octave_idx_type n = size ();
+
+  if (n_out > 0 && n > 0)
+    {
+      retval.resize (n_out, n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	retval.elem (0, i) = x.elem (i);
+
+      octave_idx_type n_crit = tcrit.capacity ();
+
+      if (n_crit > 0)
+	{
+	  octave_idx_type i_crit = 0;
+	  octave_idx_type i_out = 1;
+	  double next_crit = tcrit.elem (0);
+	  double next_out;
+	  while (i_out < n_out)
+	    {
+	      bool do_restart = false;
+
+	      next_out = tout.elem (i_out);
+	      if (i_crit < n_crit)
+		next_crit = tcrit.elem (i_crit);
+
+	      octave_idx_type save_output;
+	      double t_out;
+
+	      if (next_crit == next_out)
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = 1;
+		  i_out++;
+		  i_crit++;
+		  do_restart = true;
+		}
+	      else if (next_crit < next_out)
+		{
+		  if (i_crit < n_crit)
+		    {
+		      set_stop_time (next_crit);
+		      t_out = next_crit;
+		      save_output = 0;
+		      i_crit++;
+		      do_restart = true;
+		    }
+		  else
+		    {
+		      clear_stop_time ();
+		      t_out = next_out;
+		      save_output = 1;
+		      i_out++;
+		    }
+		}
+	      else
+		{
+		  set_stop_time (next_crit);
+		  t_out = next_out;
+		  save_output = 1;
+		  i_out++;
+		}
+
+	      ColumnVector x_next = do_integrate (t_out);
+
+	      if (integration_error)
+		return retval;
+
+	      if (save_output)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    retval.elem (i_out-1, i) = x_next.elem (i);
+		}
+
+	      if (do_restart)
+		force_restart ();
+	    }
+	}
+      else
+	{
+	  retval = do_integrate (tout);
+
+	  if (integration_error)
+	    return retval;
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/LSODE.h b/liboctave/LSODE.h
new file mode 100644
index 0000000..0dfe7c4
--- /dev/null
+++ b/liboctave/LSODE.h
@@ -0,0 +1,85 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_LSODE_h)
+#define octave_LSODE_h 1
+
+#include <cfloat>
+
+#include "LSODE-opts.h"
+#include "lo-math.h"
+
+class
+OCTAVE_API
+LSODE : public ODE, public LSODE_options
+{
+public:
+
+  LSODE (void) : ODE (), LSODE_options (), initialized (false) { }
+
+  LSODE (const ColumnVector& s, double tm, const ODEFunc& f)
+    : ODE (s, tm, f), LSODE_options (), initialized (false) { }
+
+  ~LSODE (void) { }
+
+  ColumnVector do_integrate (double t);
+
+  Matrix do_integrate (const ColumnVector& tout);
+
+  Matrix do_integrate (const ColumnVector& tout, const ColumnVector& tcrit);
+
+  std::string error_message (void) const;
+
+private:
+
+  bool initialized;
+
+  octave_idx_type method_flag;
+  octave_idx_type maxord;
+  octave_idx_type itask;
+  octave_idx_type iopt;
+  octave_idx_type itol;
+
+  octave_idx_type liw;
+  octave_idx_type lrw;
+
+  Array<octave_idx_type> iwork;
+  Array<double> rwork;
+
+  double rel_tol;
+
+  Array<double> abs_tol;
+
+  double *px;
+  double *pabs_tol;
+  octave_idx_type *piwork;
+  double *prwork;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-C.cc b/liboctave/MArray-C.cc
new file mode 100644
index 0000000..369e150
--- /dev/null
+++ b/liboctave/MArray-C.cc
@@ -0,0 +1,74 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2003, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate MArrays of Complex values.
+
+#include "oct-cmplx.h"
+
+#include "MArray.h"
+#include "MArray.cc"
+template <> OCTAVE_API double MArray<Complex>::norm (double p) const;
+#include "CColVector.h"
+#include "oct-norm.h"
+
+template <>
+OCTAVE_API double
+MArray<Complex>::norm (double p) const
+{
+  return xnorm (ComplexColumnVector (*this), p);
+}
+
+template class OCTAVE_API MArray<Complex>;
+
+INSTANTIATE_MARRAY_FRIENDS (Complex, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<Complex>;
+
+INSTANTIATE_MARRAY2_FRIENDS (Complex, OCTAVE_API)
+
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class OCTAVE_API MArrayN<Complex>;
+
+INSTANTIATE_MARRAYN_FRIENDS (Complex, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<Complex>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (Complex, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-ch.cc b/liboctave/MArray-ch.cc
new file mode 100644
index 0000000..2044a6d
--- /dev/null
+++ b/liboctave/MArray-ch.cc
@@ -0,0 +1,54 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate MArrays of char values.
+
+#include "MArray.h"
+#include "MArray.cc"
+
+template class OCTAVE_API MArray<char>;
+
+INSTANTIATE_MARRAY_FRIENDS (char, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<char>;
+
+INSTANTIATE_MARRAY2_FRIENDS (char, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<char>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (char, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-d.cc b/liboctave/MArray-d.cc
new file mode 100644
index 0000000..e29f5f4
--- /dev/null
+++ b/liboctave/MArray-d.cc
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2003, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate MArrays of double values.
+
+#include "MArray.h"
+#include "MArray.cc"
+template <> OCTAVE_API double MArray<double>::norm (double p) const;
+#include "dColVector.h"
+#include "oct-norm.h"
+
+template <>
+OCTAVE_API double
+MArray<double>::norm (double p) const
+{
+  return xnorm (ColumnVector (*this), p);
+}
+
+template class OCTAVE_API MArray<double>;
+
+INSTANTIATE_MARRAY_FRIENDS (double, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<double>;
+
+INSTANTIATE_MARRAY2_FRIENDS (double, OCTAVE_API)
+
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class OCTAVE_API MArrayN<double>;
+
+INSTANTIATE_MARRAYN_FRIENDS (double, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<double>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (double, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-decl.h b/liboctave/MArray-decl.h
new file mode 100644
index 0000000..0dc1cc6
--- /dev/null
+++ b/liboctave/MArray-decl.h
@@ -0,0 +1,249 @@
+/*
+
+Copyright (C) 1996, 1999, 2000, 2003, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MArray_decl_h)
+#define octave_MArray_decl_h 1
+
+// A macro that can be used to declare and instantiate OP= operators.
+#define MARRAY_OP_ASSIGN_DECL(A_T, E_T, OP, PFX, API, LTGT, RHS_T) \
+  PFX API A_T<E_T>& \
+  operator OP LTGT (A_T<E_T>&, const RHS_T&)
+
+// All the OP= operators that we care about.
+#define MARRAY_OP_ASSIGN_DECLS(A_T, E_T, PFX, API, LTGT, RHS_T) \
+  MARRAY_OP_ASSIGN_DECL (A_T, E_T, +=, PFX, API, LTGT, RHS_T); \
+  MARRAY_OP_ASSIGN_DECL (A_T, E_T, -=, PFX, API, LTGT, RHS_T);
+
+// Generate forward declarations for OP= operators.
+#define MARRAY_OP_ASSIGN_FWD_DECLS(A_T, RHS_T, API) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, T, template <typename T>, API, , RHS_T)
+
+// Generate friend declarations for the OP= operators.
+#define MARRAY_OP_ASSIGN_FRIENDS(A_T, RHS_T, API) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, T, friend, API, <>, RHS_T)
+
+// A function that can be used to forward OP= operations from derived
+// classes back to us.
+#define MARRAY_OP_ASSIGN_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \
+  inline R \
+  F (X_T& x, const Y_T& y) \
+  { \
+    return R (F (C_X (x), C_Y (y))); \
+  }
+
+// All the OP= operators that we care about forwarding.
+#define MARRAY_OP_ASSIGN_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_OP_ASSIGN_FWD_FCN (R, operator +=, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_OP_ASSIGN_FWD_FCN (R, operator -=, T, C_X, X_T, C_Y, Y_T)
+
+// A macro that can be used to declare and instantiate unary operators.
+#define MARRAY_UNOP(A_T, E_T, F, PFX, API, LTGT) \
+  PFX API A_T<E_T> \
+  F LTGT (const A_T<E_T>&)
+
+// All the unary operators that we care about.
+#define MARRAY_UNOP_DECLS(A_T, E_T, PFX, API, LTGT) \
+  MARRAY_UNOP (A_T, E_T, operator +, PFX, API, LTGT); \
+  MARRAY_UNOP (A_T, E_T, operator -, PFX, API, LTGT);
+
+// Generate forward declarations for unary operators.
+#define MARRAY_UNOP_FWD_DECLS(A_T, API) \
+  MARRAY_UNOP_DECLS (A_T, T, template <typename T>, API, )
+
+// Generate friend declarations for the unary operators.
+#define MARRAY_UNOP_FRIENDS(A_T, API) \
+  MARRAY_UNOP_DECLS (A_T, T, friend, API, <>)
+
+// A function that can be used to forward unary operations from derived
+// classes back to us.
+#define MARRAY_UNOP_FWD_FCN(R, F, T, C_X, X_T) \
+  inline R \
+  F (const X_T& x) \
+  { \
+    return R (F (C_X (x))); \
+  }
+
+// All the unary operators that we care about forwarding.
+#define MARRAY_UNOP_FWD_DEFS(R, T, C_X, X_T) \
+  MARRAY_UNOP_FWD_FCN (R, operator +, T, C_X, X_T) \
+  MARRAY_UNOP_FWD_FCN (R, operator -, T, C_X, X_T)
+
+// A macro that can be used to declare and instantiate binary operators.
+#define MARRAY_BINOP_DECL(A_T, E_T, F, PFX, API, LTGT, X_T, Y_T) \
+  PFX API A_T<E_T> \
+  F LTGT (const X_T&, const Y_T&)
+
+// All the binary operators that we care about.  We have two
+// sets of macros since the MArray OP MArray operations use functions
+// (product and quotient) instead of operators (*, /).
+#define MARRAY_BINOP_DECLS(A_T, E_T, PFX, API, LTGT, X_T, Y_T) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator +, PFX, API, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator -, PFX, API, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator *, PFX, API, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator /, PFX, API, LTGT, X_T, Y_T);
+
+#define MARRAY_AA_BINOP_DECLS(A_T, E_T, PFX, API, LTGT) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator +, PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator -, PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, quotient,   PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, product,    PFX, API, LTGT, A_T<E_T>, A_T<E_T>);
+
+#define MDIAGARRAY2_DAS_BINOP_DECLS(A_T, E_T, PFX, API, LTGT, X_T, Y_T) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator *, PFX, API, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator /, PFX, API, LTGT, X_T, Y_T);
+
+#define MDIAGARRAY2_SDA_BINOP_DECLS(A_T, E_T, PFX, API, LTGT, X_T, Y_T) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator *, PFX, API, LTGT, X_T, Y_T);
+
+#define MDIAGARRAY2_DADA_BINOP_DECLS(A_T, E_T, PFX, API, LTGT) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator +, PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator -, PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, product,    PFX, API, LTGT, A_T<E_T>, A_T<E_T>);
+
+// Generate forward declarations for binary operators.
+#define MARRAY_BINOP_FWD_DECLS(A_T, API) \
+  MARRAY_BINOP_DECLS (A_T, T, template <typename T>, API, , A_T<T>, T) \
+  MARRAY_BINOP_DECLS (A_T, T, template <typename T>, API, , T, A_T<T>) \
+  MARRAY_AA_BINOP_DECLS (A_T, T, template <typename T>, API, )
+
+#define MDIAGARRAY2_BINOP_FWD_DECLS(A_T, API) \
+  MDIAGARRAY2_DAS_BINOP_DECLS (A_T, T, template <typename T>, API, , A_T<T>, T) \
+  MDIAGARRAY2_SDA_BINOP_DECLS (A_T, T, template <typename T>, API, , T, A_T<T>) \
+  MDIAGARRAY2_DADA_BINOP_DECLS (A_T, T, template <typename T>, API, )
+
+// Generate friend declarations for the binary operators.
+#define MARRAY_BINOP_FRIENDS(A_T, API) \
+  MARRAY_BINOP_DECLS (A_T, T, friend, API, <>, A_T<T>, T) \
+  MARRAY_BINOP_DECLS (A_T, T, friend, API, <>, T, A_T<T>) \
+  MARRAY_AA_BINOP_DECLS (A_T, T, friend, API, <>)
+
+#define MDIAGARRAY2_BINOP_FRIENDS(A_T, API) \
+  MDIAGARRAY2_DAS_BINOP_DECLS (A_T, T, friend, API, <>, A_T<T>, T) \
+  MDIAGARRAY2_SDA_BINOP_DECLS (A_T, T, friend, API, <>, T, A_T<T>) \
+  MDIAGARRAY2_DADA_BINOP_DECLS (A_T, T, friend, API, <>)
+
+// A function that can be used to forward binary operations from derived
+// classes back to us.
+#define MARRAY_BINOP_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \
+  inline R \
+  F (const X_T& x, const Y_T& y) \
+  { \
+    return R (F (C_X (x), C_Y (y))); \
+  }
+
+// The binary operators that we care about forwarding.  We have two
+// sets of macros since the MArray OP MArray operations use functions
+// (product and quotient) instead of operators (*, /).
+#define MARRAY_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator +, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator -, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator *, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator /, T, C_X, X_T, C_Y, Y_T)
+
+#define MARRAY_AA_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator +, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator -, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, product,    T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, quotient,   T, C_X, X_T, C_Y, Y_T)
+
+#define MDIAGARRAY2_DAS_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator *, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator /, T, C_X, X_T, C_Y, Y_T)
+
+#define MDIAGARRAY2_SDA_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator *, T, C_X, X_T, C_Y, Y_T)
+
+#define MDIAGARRAY2_DADA_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator +, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator -, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, product,    T, C_X, X_T, C_Y, Y_T)
+
+// Forward declarations for the MArray operators.
+#define MARRAY_OPS_FORWARD_DECLS(A_T, API) \
+  template <class T> \
+  class A_T; \
+ \
+  MARRAY_OP_ASSIGN_FWD_DECLS (A_T, T, API) \
+  MARRAY_OP_ASSIGN_FWD_DECLS (A_T, A_T<T>, API) \
+  MARRAY_UNOP_FWD_DECLS (A_T, API) \
+  MARRAY_BINOP_FWD_DECLS (A_T, API)
+
+#define MDIAGARRAY2_OPS_FORWARD_DECLS(A_T, API) \
+  template <class T> \
+  class A_T; \
+ \
+  MARRAY_OP_ASSIGN_FWD_DECLS (A_T, A_T<T>, API) \
+  MARRAY_UNOP_FWD_DECLS (A_T, API) \
+  MDIAGARRAY2_BINOP_FWD_DECLS (A_T, API)
+
+// Friend declarations for the MArray operators.
+#define MARRAY_OPS_FRIEND_DECLS(A_T, API) \
+  MARRAY_OP_ASSIGN_FRIENDS (A_T, T, API) \
+  MARRAY_OP_ASSIGN_FRIENDS (A_T, A_T<T>, API) \
+  MARRAY_UNOP_FRIENDS (A_T, API) \
+  MARRAY_BINOP_FRIENDS (A_T, API)
+
+#define MDIAGARRAY2_OPS_FRIEND_DECLS(A_T, API) \
+  MARRAY_OP_ASSIGN_FRIENDS (A_T, A_T<T>, API) \
+  MARRAY_UNOP_FRIENDS (A_T, API) \
+  MDIAGARRAY2_BINOP_FRIENDS (A_T, API)
+
+// Define all the MArray forwarding functions for return type R and
+// MArray element type T
+#define MARRAY_FORWARD_DEFS(B, R, T) \
+  MARRAY_OP_ASSIGN_FWD_DEFS \
+    (R, T, dynamic_cast<B<T>&>, R, , T) \
+ \
+  MARRAY_OP_ASSIGN_FWD_DEFS \
+    (R, T, \
+     dynamic_cast<B<T>&>, R, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_UNOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, , T) \
+ \
+  MARRAY_BINOP_FWD_DEFS \
+    (R, T, , T, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_AA_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, dynamic_cast<const B<T>&>, R)
+
+#define MDIAGARRAY2_FORWARD_DEFS(B, R, T) \
+  MARRAY_OP_ASSIGN_FWD_DEFS \
+    (R, T, \
+     dynamic_cast<B<T>&>, R, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_UNOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R) \
+ \
+  MDIAGARRAY2_DAS_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, , T) \
+ \
+  MDIAGARRAY2_SDA_BINOP_FWD_DEFS \
+    (R, T, , T, dynamic_cast<const B<T>&>, R) \
+ \
+  MDIAGARRAY2_DADA_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, dynamic_cast<const B<T>&>, R)
+
+#endif
diff --git a/liboctave/MArray-defs.h b/liboctave/MArray-defs.h
new file mode 100644
index 0000000..8f41b34
--- /dev/null
+++ b/liboctave/MArray-defs.h
@@ -0,0 +1,126 @@
+/*
+
+Copyright (C) 1996, 1999, 2000, 2003, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MArray_defs_h)
+#define octave_MArray_defs_h 1
+
+// Nothing like a little CPP abuse to brighten everyone's day.
+
+#define DO_VS_OP(r, l, v, OP, s) \
+  if (l > 0) \
+    { \
+      for (octave_idx_type i = 0; i < l; i++) \
+	r[i] = v[i] OP s; \
+    }
+
+#define DO_SV_OP(r, l, s, OP, v) \
+  if (l > 0) \
+    { \
+      for (octave_idx_type i = 0; i < l; i++) \
+	r[i] = s OP v[i]; \
+    }
+
+#define DO_VV_OP(r, l, x, OP, y) \
+  if (l > 0) \
+    { \
+      for (octave_idx_type i = 0; i < l; i++) \
+	r[i] = x[i] OP y[i]; \
+    }
+
+#define NEG_V(r, l, x) \
+  if (l > 0) \
+    { \
+      for (octave_idx_type i = 0; i < l; i++) \
+	r[i] = -x[i]; \
+    }
+
+#define DO_VS_OP2(T, a, OP, s) \
+  octave_idx_type l = a.length (); \
+  if (l > 0) \
+    { \
+      T *tmp = a.fortran_vec (); \
+      for (octave_idx_type i = 0; i < l; i++) \
+	tmp[i] OP s; \
+    }
+
+#define DO_VV_OP2(T, a, OP, b) \
+  do \
+    { \
+      T *a_tmp = a.fortran_vec (); \
+      const T *b_tmp = b.data (); \
+      for (octave_idx_type i = 0; i < l; i++) \
+	a_tmp[i] OP b_tmp[i]; \
+    } \
+  while (0)
+
+// Instantiate the OP= operators.
+#define MARRAY_OP_ASSIGN_DEFS(A_T, E_T, RHS_T, API) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, E_T, template, API, , RHS_T)
+
+// Instantiate the unary operators.
+#define MARRAY_UNOP_DEFS(A_T, E_T, API) \
+  MARRAY_UNOP_DECLS (A_T, E_T, template, API, )
+
+// Instantiate the binary operators.
+#define MARRAY_BINOP_DEFS(A_T, E_T, API) \
+  MARRAY_BINOP_DECLS (A_T, E_T, template, API, , A_T<E_T>, E_T) \
+  MARRAY_BINOP_DECLS (A_T, E_T, template, API, , E_T, A_T<E_T>) \
+  MARRAY_AA_BINOP_DECLS (A_T, E_T, template, API, )
+
+#define MDIAGARRAY2_BINOP_DEFS(A_T, E_T, API) \
+  MDIAGARRAY2_DAS_BINOP_DECLS (A_T, E_T, template, API, , A_T<E_T>, E_T) \
+  MDIAGARRAY2_SDA_BINOP_DECLS (A_T, E_T, template, API, , E_T, A_T<E_T>) \
+  MDIAGARRAY2_DADA_BINOP_DECLS (A_T, E_T, template, API, )
+
+// The following macros are for external use.
+
+// Instantiate all the MArray friends for MArray element type T.
+#define INSTANTIATE_MARRAY_FRIENDS(T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MArray, T, T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MArray, T, MArray<T>, API) \
+  MARRAY_UNOP_DEFS (MArray, T, API) \
+  MARRAY_BINOP_DEFS (MArray, T, API)
+
+// Instantiate all the MArray2 friends for MArray2 element type T.
+#define INSTANTIATE_MARRAY2_FRIENDS(T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MArray2, T, T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MArray2, T, MArray2<T>, API) \
+  MARRAY_UNOP_DEFS (MArray2, T, API) \
+  MARRAY_BINOP_DEFS (MArray2, T, API)
+
+// Instantiate all the MArrayN friends for MArrayN element type T.
+#define INSTANTIATE_MARRAYN_FRIENDS(T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MArrayN, T, T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MArrayN, T, MArrayN<T>, API) \
+  MARRAY_UNOP_DEFS (MArrayN, T, API) \
+  MARRAY_BINOP_DEFS (MArrayN, T, API)
+
+// Instantiate all the MDiagArray2 friends for MDiagArray2 element type T.
+#define INSTANTIATE_MDIAGARRAY2_FRIENDS(T, API) \
+  MARRAY_OP_ASSIGN_DEFS (MDiagArray2, T, MDiagArray2<T>, API) \
+  MARRAY_UNOP_DEFS (MDiagArray2, T, API) \
+  MDIAGARRAY2_BINOP_DEFS (MDiagArray2, T, API)
+
+// Now we have all the definitions we need.
+
+#endif
diff --git a/liboctave/MArray-f.cc b/liboctave/MArray-f.cc
new file mode 100644
index 0000000..6dc34b3
--- /dev/null
+++ b/liboctave/MArray-f.cc
@@ -0,0 +1,72 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2003, 2005, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate MArrays of float values.
+
+#include "MArray.h"
+#include "MArray.cc"
+template <> OCTAVE_API float MArray<float>::norm (float p) const;
+#include "fColVector.h"
+#include "oct-norm.h"
+
+template <>
+OCTAVE_API float
+MArray<float>::norm (float p) const
+{
+  return xnorm (FloatColumnVector (*this), p);
+}
+
+template class OCTAVE_API MArray<float>;
+
+INSTANTIATE_MARRAY_FRIENDS (float, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<float>;
+
+INSTANTIATE_MARRAY2_FRIENDS (float, OCTAVE_API)
+
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class OCTAVE_API MArrayN<float>;
+
+INSTANTIATE_MARRAYN_FRIENDS (float, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<float>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (float, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-fC.cc b/liboctave/MArray-fC.cc
new file mode 100644
index 0000000..eca0fb4
--- /dev/null
+++ b/liboctave/MArray-fC.cc
@@ -0,0 +1,74 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2003, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate MArrays of FloatComplex values.
+
+#include "oct-cmplx.h"
+
+#include "MArray.h"
+#include "MArray.cc"
+template <> OCTAVE_API float MArray<FloatComplex>::norm (float p) const;
+#include "fCColVector.h"
+#include "oct-norm.h"
+
+template <>
+OCTAVE_API float
+MArray<FloatComplex>::norm (float p) const
+{
+  return xnorm (FloatComplexColumnVector (*this), p);
+}
+
+template class OCTAVE_API MArray<FloatComplex>;
+
+INSTANTIATE_MARRAY_FRIENDS (FloatComplex, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<FloatComplex>;
+
+INSTANTIATE_MARRAY2_FRIENDS (FloatComplex, OCTAVE_API)
+
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class OCTAVE_API MArrayN<FloatComplex>;
+
+INSTANTIATE_MARRAYN_FRIENDS (FloatComplex, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<FloatComplex>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (FloatComplex, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-i.cc b/liboctave/MArray-i.cc
new file mode 100644
index 0000000..3848c50
--- /dev/null
+++ b/liboctave/MArray-i.cc
@@ -0,0 +1,105 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-inttypes.h"
+
+// Instantiate MArrays of int values.
+
+#include "MArray.h"
+#include "MArray.cc"
+
+template class OCTAVE_API MArray<int>;
+template class OCTAVE_API MArray<long>;
+
+INSTANTIATE_MARRAY_FRIENDS (int, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (long, OCTAVE_API)
+
+template class OCTAVE_API MArray<octave_int8>;
+template class OCTAVE_API MArray<octave_int16>;
+template class OCTAVE_API MArray<octave_int32>;
+template class OCTAVE_API MArray<octave_int64>;
+
+INSTANTIATE_MARRAY_FRIENDS (octave_int8, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (octave_int16, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (octave_int32, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (octave_int64, OCTAVE_API)
+
+template class OCTAVE_API MArray<octave_uint8>;
+template class OCTAVE_API MArray<octave_uint16>;
+template class OCTAVE_API MArray<octave_uint32>;
+template class OCTAVE_API MArray<octave_uint64>;
+
+INSTANTIATE_MARRAY_FRIENDS (octave_uint8, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (octave_uint16, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (octave_uint32, OCTAVE_API)
+INSTANTIATE_MARRAY_FRIENDS (octave_uint64, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<int>;
+
+INSTANTIATE_MARRAY2_FRIENDS (int, OCTAVE_API)
+
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class OCTAVE_API MArrayN<int>;
+
+INSTANTIATE_MARRAYN_FRIENDS (int, OCTAVE_API)
+
+template class OCTAVE_API MArrayN<octave_int8>;
+template class OCTAVE_API MArrayN<octave_int16>;
+template class OCTAVE_API MArrayN<octave_int32>;
+template class OCTAVE_API MArrayN<octave_int64>;
+
+INSTANTIATE_MARRAYN_FRIENDS (octave_int8, OCTAVE_API)
+INSTANTIATE_MARRAYN_FRIENDS (octave_int16, OCTAVE_API)
+INSTANTIATE_MARRAYN_FRIENDS (octave_int32, OCTAVE_API)
+INSTANTIATE_MARRAYN_FRIENDS (octave_int64, OCTAVE_API)
+
+template class OCTAVE_API MArrayN<octave_uint8>;
+template class OCTAVE_API MArrayN<octave_uint16>;
+template class OCTAVE_API MArrayN<octave_uint32>;
+template class OCTAVE_API MArrayN<octave_uint64>;
+
+INSTANTIATE_MARRAYN_FRIENDS (octave_uint8, OCTAVE_API)
+INSTANTIATE_MARRAYN_FRIENDS (octave_uint16, OCTAVE_API)
+INSTANTIATE_MARRAYN_FRIENDS (octave_uint32, OCTAVE_API)
+INSTANTIATE_MARRAYN_FRIENDS (octave_uint64, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<int>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (int, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray-s.cc b/liboctave/MArray-s.cc
new file mode 100644
index 0000000..0a5684a
--- /dev/null
+++ b/liboctave/MArray-s.cc
@@ -0,0 +1,54 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate MArrays of short int values.
+
+#include "MArray.h"
+#include "MArray.cc"
+
+template class OCTAVE_API MArray<short>;
+
+INSTANTIATE_MARRAY_FRIENDS (short, OCTAVE_API)
+
+#include "MArray2.h"
+#include "MArray2.cc"
+
+template class OCTAVE_API MArray2<short>;
+
+INSTANTIATE_MARRAY2_FRIENDS (short, OCTAVE_API)
+
+#include "MDiagArray2.h"
+#include "MDiagArray2.cc"
+
+template class OCTAVE_API MDiagArray2<short>;
+
+INSTANTIATE_MDIAGARRAY2_FRIENDS (short, OCTAVE_API)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray.cc b/liboctave/MArray.cc
new file mode 100644
index 0000000..677acec
--- /dev/null
+++ b/liboctave/MArray.cc
@@ -0,0 +1,259 @@
+/*
+
+Copyright (C) 1993, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+Copyright (C) 2009 VZLU Prague              
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MArray.h"
+#include "Array-util.h"
+#include "lo-error.h"
+
+#include "MArray-defs.h"
+
+// One dimensional array with math ops.
+
+template <class T>
+double
+MArray<T>::norm (double) const
+{
+  (*current_liboctave_error_handler)
+    ("norm: only implemented for double and complex values");
+
+  return 0;
+}
+
+template <class T>
+float
+MArray<T>::norm (float) const
+{
+  (*current_liboctave_error_handler)
+    ("norm: only implemented for double and complex values");
+
+  return 0;
+}
+
+template <class T>
+struct _idxadds_helper
+{
+  T *array;
+  T val;
+  _idxadds_helper (T *a, T v) : array (a), val (v) { }
+  void operator () (octave_idx_type i)
+    { array[i] += val; }
+};
+
+template <class T>
+struct _idxadda_helper
+{
+  T *array;
+  const T *vals;
+  _idxadda_helper (T *a, const T *v) : array (a), vals (v) { }
+  void operator () (octave_idx_type i)
+    { array[i] += *vals++; }
+};
+
+template <class T>
+void
+MArray<T>::idx_add (const idx_vector& idx, T val)
+{
+  octave_idx_type n = this->length ();
+  octave_idx_type ext = idx.extent (n);
+  if (ext > n)
+    {
+      this->resize (ext);
+      n = ext;
+    }
+
+  OCTAVE_QUIT;
+
+  octave_idx_type len = idx.length (n);
+  idx.loop (len, _idxadds_helper<T> (this->fortran_vec (), val));
+}
+
+template <class T>
+void
+MArray<T>::idx_add (const idx_vector& idx, const MArray<T>& vals)
+{
+  octave_idx_type n = this->length ();
+  octave_idx_type ext = idx.extent (n);
+  if (ext > n)
+    {
+      this->resize (ext);
+      n = ext;
+    }
+
+  OCTAVE_QUIT;
+
+  octave_idx_type len = std::min (idx.length (n), vals.length ());
+  idx.loop (len, _idxadda_helper<T> (this->fortran_vec (), vals.data ()));
+}
+
+// Element by element MArray by scalar ops.
+
+template <class T>
+MArray<T>&
+operator += (MArray<T>& a, const T& s)
+{
+  DO_VS_OP2 (T, a, +=, s)
+  return a;
+}
+
+template <class T>
+MArray<T>&
+operator -= (MArray<T>& a, const T& s)
+{
+  DO_VS_OP2 (T, a, -=, s)
+  return a;
+}
+
+// Element by element MArray by MArray ops.
+
+template <class T>
+MArray<T>&
+operator += (MArray<T>& a, const MArray<T>& b)
+{
+  octave_idx_type l = a.length ();
+  if (l > 0)
+    {
+      octave_idx_type bl = b.length ();
+      if (l != bl)
+	gripe_nonconformant ("operator +=", l, bl);
+      else
+	DO_VV_OP2 (T, a, +=, b);
+    }
+  return a;
+}
+
+template <class T>
+MArray<T>&
+operator -= (MArray<T>& a, const MArray<T>& b)
+{
+  octave_idx_type l = a.length ();
+  if (l > 0)
+    {
+      octave_idx_type bl = b.length ();
+      if (l != bl)
+	gripe_nonconformant ("operator -=", l, bl);
+      else
+	DO_VV_OP2 (T, a, -=, b);
+    }
+  return a;
+}
+
+// Element by element MArray by scalar ops.
+
+#define MARRAY_AS_OP(OP) \
+  template <class T> \
+  MArray<T> \
+  operator OP (const MArray<T>& a, const T& s) \
+  { \
+    MArray<T> result (a.length ()); \
+    T *r = result.fortran_vec (); \
+    octave_idx_type l = a.length (); \
+    const T *v = a.data (); \
+    DO_VS_OP (r, l, v, OP, s); \
+    return result; \
+  }
+
+MARRAY_AS_OP (+)
+MARRAY_AS_OP (-)
+MARRAY_AS_OP (*)
+MARRAY_AS_OP (/)
+
+// Element by element scalar by MArray ops.
+
+#define MARRAY_SA_OP(OP) \
+  template <class T> \
+  MArray<T> \
+  operator OP (const T& s, const MArray<T>& a) \
+  { \
+    MArray<T> result (a.length ()); \
+    T *r = result.fortran_vec (); \
+    octave_idx_type l = a.length (); \
+    const T *v = a.data (); \
+    DO_SV_OP (r, l, s, OP, v); \
+    return result; \
+  }
+
+MARRAY_SA_OP(+)
+MARRAY_SA_OP(-)
+MARRAY_SA_OP(*)
+MARRAY_SA_OP(/)
+
+// Element by element MArray by MArray ops.
+
+#define MARRAY_AA_OP(FCN, OP) \
+  template <class T> \
+  MArray<T> \
+  FCN (const MArray<T>& a, const MArray<T>& b) \
+  { \
+    octave_idx_type l = a.length (); \
+    octave_idx_type bl = b.length (); \
+    if (l != bl) \
+      { \
+	gripe_nonconformant (#FCN, l, bl); \
+	return MArray<T> (); \
+      } \
+    if (l == 0) \
+      return MArray<T> (); \
+    MArray<T> result (l); \
+    T *r = result.fortran_vec (); \
+    const T *x = a.data (); \
+    const T *y = b.data (); \
+    DO_VV_OP (r, l, x, OP, y); \
+    return result; \
+  }
+
+MARRAY_AA_OP (operator +, +)
+MARRAY_AA_OP (operator -, -)
+MARRAY_AA_OP (product,    *)
+MARRAY_AA_OP (quotient,   /)
+
+// Unary MArray ops.
+
+template <class T>
+MArray<T>
+operator + (const MArray<T>& a)
+{
+  return a;
+}
+
+template <class T>
+MArray<T>
+operator - (const MArray<T>& a)
+{
+  octave_idx_type l = a.length ();
+  MArray<T> result (l);
+  T *r = result.fortran_vec ();
+  const T *x = a.data ();
+  NEG_V (r, l, x);
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray.h b/liboctave/MArray.h
new file mode 100644
index 0000000..0d294c2
--- /dev/null
+++ b/liboctave/MArray.h
@@ -0,0 +1,113 @@
+// Template array classes with like-type math ops
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MArray_h)
+#define octave_MArray_h 1
+
+#include "Array.h"
+
+// One dimensional array with math ops.
+
+// But first, some preprocessor abuse...
+
+#include "MArray-decl.h"
+
+MARRAY_OPS_FORWARD_DECLS (MArray, )
+
+template <class T>
+class
+MArray : public Array<T>
+{
+protected:
+
+  MArray (T *d, octave_idx_type l) : Array<T> (d, l) { }
+
+public:
+  
+  MArray (void) : Array<T> () { }
+
+  explicit MArray (octave_idx_type n) : Array<T> (n) { }
+
+  MArray (octave_idx_type n, const T& val) : Array<T> (n, val) { }
+
+  MArray (const MArray<T>& a) : Array<T> (a) { }
+
+  MArray (const Array<T>& a) : Array<T> (a) { }
+
+  ~MArray (void) { }
+
+  MArray<T>& operator = (const MArray<T>& a)
+    {
+      Array<T>::operator = (a);
+      return *this;
+    }
+
+  MArray<T> transpose (void) const { return Array<T>::transpose (); }
+  MArray<T> hermitian (T (*fcn) (const T&) = 0) const { return Array<T>::hermitian (fcn); }
+
+  octave_idx_type nnz (void) const
+    {
+      octave_idx_type retval = 0;
+
+      const T *d = this->data ();
+
+      octave_idx_type nel = this->numel ();
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  if (d[i] != T ())
+	    retval++;
+	}
+
+      return retval;
+    }
+
+  double norm (double p) const;
+  float norm (float p) const;
+
+  template <class U, class F>
+  MArray<U> map (F fcn) const
+  {
+    return Array<T>::template map<U> (fcn);
+  }
+
+  // Performs indexed accumulative addition.
+
+  void idx_add (const idx_vector& idx, T val);
+
+  void idx_add (const idx_vector& idx, const MArray<T>& vals);
+
+  // Currently, the OPS functions don't need to be friends, but that
+  // may change.
+
+  // MARRAY_OPS_FRIEND_DECLS (MArray)
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray2.cc b/liboctave/MArray2.cc
new file mode 100644
index 0000000..8a691a2
--- /dev/null
+++ b/liboctave/MArray2.cc
@@ -0,0 +1,195 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MArray2.h"
+#include "Array-util.h"
+#include "lo-error.h"
+
+#include "MArray-defs.h"
+
+// Two dimensional array with math ops.
+
+// Element by element MArray2 by scalar ops.
+
+template <class T>
+MArray2<T>&
+operator += (MArray2<T>& a, const T& s)
+{
+  DO_VS_OP2 (T, a, +=, s)
+  return a;
+}
+
+template <class T>
+MArray2<T>&
+operator -= (MArray2<T>& a, const T& s)
+{
+  DO_VS_OP2 (T, a, -=, s)
+  return a;
+}
+
+// Element by element MArray2 by MArray2 ops.
+
+template <class T>
+MArray2<T>&
+operator += (MArray2<T>& a, const MArray2<T>& b)
+{
+  octave_idx_type r = a.rows ();
+  octave_idx_type c = a.cols ();
+  octave_idx_type br = b.rows ();
+  octave_idx_type bc = b.cols ();
+  if (r != br || c != bc)
+    gripe_nonconformant ("operator +=", r, c, br, bc);
+  else
+    {
+      if (r > 0 && c > 0)
+	{
+	  octave_idx_type l = a.length ();
+	  DO_VV_OP2 (T, a, +=, b);
+	}
+    }
+  return a;
+}
+
+template <class T>
+MArray2<T>&
+operator -= (MArray2<T>& a, const MArray2<T>& b)
+{
+  octave_idx_type r = a.rows ();
+  octave_idx_type c = a.cols ();
+  octave_idx_type br = b.rows ();
+  octave_idx_type bc = b.cols ();
+  if (r != br || c != bc)
+    gripe_nonconformant ("operator -=", r, c, br, bc);
+  else
+    {
+      if (r > 0 && c > 0)
+	{
+	  octave_idx_type l = a.length ();
+	  DO_VV_OP2 (T, a, -=, b);
+	}
+    }
+  return a;
+}
+
+// Element by element MArray2 by scalar ops.
+
+#define MARRAY_A2S_OP(OP) \
+  template <class T> \
+  MArray2<T> \
+  operator OP (const MArray2<T>& a, const T& s) \
+  { \
+    MArray2<T> result (a.rows (), a.cols ()); \
+    T *r = result.fortran_vec (); \
+    octave_idx_type l = a.length (); \
+    const T *v = a.data (); \
+    DO_VS_OP (r, l, v, OP, s); \
+    return result; \
+  }
+
+MARRAY_A2S_OP (+)
+MARRAY_A2S_OP (-)
+MARRAY_A2S_OP (*)
+MARRAY_A2S_OP (/)
+
+// Element by element scalar by MArray2 ops.
+
+#define MARRAY_SA2_OP(OP) \
+  template <class T> \
+  MArray2<T> \
+  operator OP (const T& s, const MArray2<T>& a) \
+  { \
+    MArray2<T> result (a.rows (), a.cols ()); \
+    T *r = result.fortran_vec (); \
+    octave_idx_type l = a.length (); \
+    const T *v = a.data (); \
+    DO_SV_OP (r, l, s, OP, v); \
+    return result; \
+  }
+
+MARRAY_SA2_OP (+)
+MARRAY_SA2_OP (-)
+MARRAY_SA2_OP (*)
+MARRAY_SA2_OP (/)
+
+// Element by element MArray2 by MArray2 ops.
+
+#define MARRAY_A2A2_OP(FCN, OP) \
+  template <class T> \
+  MArray2<T> \
+  FCN (const MArray2<T>& a, const MArray2<T>& b) \
+  { \
+    octave_idx_type a_nr = a.rows (); \
+    octave_idx_type a_nc = a.cols (); \
+    octave_idx_type b_nr = b.rows (); \
+    octave_idx_type b_nc = b.cols (); \
+    if (a_nr != b_nr || a_nc != b_nc) \
+      { \
+        gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \
+	return MArray2<T> (); \
+      } \
+    if (a_nr == 0 || a_nc == 0) \
+      return MArray2<T> (a_nr, a_nc); \
+    octave_idx_type l = a.length (); \
+    MArray2<T> result (a_nr, a_nc); \
+    T *r = result.fortran_vec (); \
+    const T *x = a.data (); \
+    const T *y = b.data (); \
+    DO_VV_OP (r, l, x, OP, y); \
+    return result; \
+  }
+
+MARRAY_A2A2_OP (operator +, +)
+MARRAY_A2A2_OP (operator -, -)
+MARRAY_A2A2_OP (product,    *)
+MARRAY_A2A2_OP (quotient,   /)
+
+// Unary MArray2 ops.
+
+template <class T>
+MArray2<T>
+operator + (const MArray2<T>& a)
+{
+  return a;
+}
+
+template <class T>
+MArray2<T>
+operator - (const MArray2<T>& a)
+{
+  octave_idx_type l = a.length ();
+  MArray2<T> result (a.rows (), a.cols ());
+  T *r = result.fortran_vec ();
+  const T *x = a.data ();
+  NEG_V (r, l, x);
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArray2.h b/liboctave/MArray2.h
new file mode 100644
index 0000000..9928347
--- /dev/null
+++ b/liboctave/MArray2.h
@@ -0,0 +1,108 @@
+// Template array classes with like-type math ops
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MArray2_h)
+#define octave_MArray2_h 1
+
+#include "Array2.h"
+
+// Two dimensional array with math ops.
+
+// But first, some preprocessor abuse...
+
+#include "MArray-decl.h"
+
+MARRAY_OPS_FORWARD_DECLS (MArray2, )
+
+template <class T>
+class
+MArray2 : public Array2<T>
+{
+protected:
+
+  MArray2 (T *d, octave_idx_type n, octave_idx_type m) : Array2<T> (d, n, m) { }
+
+public:
+
+  MArray2 (void) : Array2<T> () { }
+
+  MArray2 (octave_idx_type n, octave_idx_type m) : Array2<T> (n, m) { }
+
+  MArray2 (octave_idx_type n, octave_idx_type m, const T& val) : Array2<T> (n, m, val) { }
+
+  MArray2 (const dim_vector& dv) : Array2<T> (dv) { }
+
+  MArray2 (const dim_vector& dv, const T& val) : Array2<T> (dv, val) { }
+
+  MArray2 (const MArray2<T>& a) : Array2<T> (a) { }
+
+  MArray2 (const Array2<T>& a) : Array2<T> (a) { }
+
+  template <class U>
+  MArray2 (const Array2<U>& a) : Array2<T> (a) { }
+
+  template <class U>
+  MArray2 (const MArray2<U>& a) : Array2<T> (a) { }
+
+  ~MArray2 (void) { }
+
+  MArray2<T>& operator = (const MArray2<T>& a)
+    {
+      Array2<T>::operator = (a);
+      return *this;
+    }
+
+  MArray2<T>& insert (const Array2<T>& a, octave_idx_type r, octave_idx_type c)
+  {
+    Array2<T>::insert (a, r, c);
+    return *this;
+  }
+
+  MArray2<T> transpose (void) const { return Array2<T>::transpose (); }
+  MArray2<T> hermitian (T (*fcn) (const T&) = 0) const { return Array2<T>::hermitian (fcn); }
+
+  MArray2<T> diag (octave_idx_type k) const
+  {
+    return Array2<T>::diag (k);
+  }
+
+  template <class U, class F>
+  MArray2<U> map (F fcn) const
+  {
+    return Array2<T>::template map<U> (fcn);
+  }
+
+  // Currently, the OPS functions don't need to be friends, but that
+  // may change.
+
+  // MARRAY_OPS_FRIEND_DECLS (MArray2)
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArrayN.cc b/liboctave/MArrayN.cc
new file mode 100644
index 0000000..e518028
--- /dev/null
+++ b/liboctave/MArrayN.cc
@@ -0,0 +1,199 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MArrayN.h"
+#include "Array-util.h"
+#include "lo-error.h"
+
+#include "MArray-defs.h"
+
+// N-dimensional array with math ops.
+
+// Element by element MArrayN by scalar ops.
+
+template <class T>
+MArrayN<T>&
+operator += (MArrayN<T>& a, const T& s)
+{
+  DO_VS_OP2 (T, a, +=, s)
+  return a;
+}
+
+template <class T>
+MArrayN<T>&
+operator -= (MArrayN<T>& a, const T& s)
+{
+  DO_VS_OP2 (T, a, -=, s)
+  return a;
+}
+
+// Element by element MArrayN by MArrayN ops.
+
+template <class T>
+MArrayN<T>&
+operator += (MArrayN<T>& a, const MArrayN<T>& b)
+{
+  octave_idx_type l = a.length ();
+
+  if (l > 0)
+    {
+      dim_vector a_dims = a.dims ();
+      dim_vector b_dims = b.dims ();
+
+      if (a_dims != b_dims)
+	gripe_nonconformant ("operator +=", a_dims, b_dims);
+      else
+	DO_VV_OP2 (T, a, +=, b);
+    }
+
+  return a;
+}
+
+template <class T>
+MArrayN<T>&
+operator -= (MArrayN<T>& a, const MArrayN<T>& b)
+{
+  octave_idx_type l = a.length ();
+
+  if (l > 0)
+    {
+      dim_vector a_dims = a.dims ();
+      dim_vector b_dims = b.dims ();
+
+      if (a_dims != b_dims)
+	gripe_nonconformant ("operator -=", a_dims, b_dims);
+      else
+	DO_VV_OP2 (T, a, -=, b);
+    }
+  return a;
+}
+
+// Element by element MArrayN by scalar ops.
+
+#define MARRAYN_NDS_OP(OP) \
+  template <class T> \
+  MArrayN<T> \
+  operator OP (const MArrayN<T>& a, const T& s) \
+    { \
+      MArrayN<T> result (a.dims ()); \
+      T *r = result.fortran_vec (); \
+      octave_idx_type l = a.length (); \
+      const T *v = a.data (); \
+      DO_VS_OP (r, l, v, OP, s); \
+      return result; \
+    }
+
+MARRAYN_NDS_OP (+)
+MARRAYN_NDS_OP (-)
+MARRAYN_NDS_OP (*)
+MARRAYN_NDS_OP (/)
+
+// Element by element MArrayN by scalar ops.
+
+#define MARRAYN_SND_OP(OP) \
+  template <class T> \
+  MArrayN<T> \
+  operator OP (const T& s, const MArrayN<T>& a) \
+  { \
+    MArrayN<T> result (a.dims ()); \
+    T *r = result.fortran_vec (); \
+    octave_idx_type l = a.length (); \
+    const T *v = a.data (); \
+    DO_SV_OP (r, l, s, OP, v); \
+    return result; \
+  }
+
+MARRAYN_SND_OP (+)
+MARRAYN_SND_OP (-)
+MARRAYN_SND_OP (*)
+MARRAYN_SND_OP (/)
+
+#define MARRAY_NDND_OP(FCN, OP) \
+template <class T> \
+MArrayN<T> \
+FCN (const MArrayN<T>& a, const MArrayN<T>& b) \
+{ \
+dim_vector a_dims = a.dims (); \
+dim_vector b_dims = b.dims (); \
+int dims_ok = 1; \
+int any_dims_zero = 0; \
+if (a_dims.length () != b_dims.length ()) \
+ dims_ok = 0; \
+ else \
+   { \
+     for (int i = 0; i < a_dims.length (); i++) \
+       { \
+	 if (a_dims (i) != b_dims (i)) \
+	   { dims_ok = 0; break; } \
+	 if (a_dims (i) == 0) \
+	   any_dims_zero = 1; \
+       } \
+   } \
+ if (!dims_ok) \
+   { \
+     gripe_nonconformant (#FCN, a_dims, b_dims); \
+     return MArrayN<T> (); \
+   } \
+ if (any_dims_zero) \
+   return MArrayN<T> (a_dims); \
+ octave_idx_type l = a.length (); \
+ MArrayN<T> result (a_dims); \
+ T* r = result.fortran_vec (); \
+ const T *x = a.data (); \
+ const T *y = b.data (); \
+ DO_VV_OP (r, l, x, OP, y); \
+ return result; \
+}
+
+MARRAY_NDND_OP (operator +, +)
+MARRAY_NDND_OP (operator -, -)
+MARRAY_NDND_OP (product,    *)
+MARRAY_NDND_OP (quotient,   /)
+
+template <class T>
+MArrayN<T>
+operator + (const MArrayN<T>& a)
+{
+  return a;
+}
+
+template <class T>
+MArrayN<T>
+operator - (const MArrayN<T>& a)
+{
+  octave_idx_type l = a.length ();
+  MArrayN<T> result (a.dims ());
+  T *r = result.fortran_vec ();
+  const T *x = a.data ();
+  NEG_V (r, l, x);
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MArrayN.h b/liboctave/MArrayN.h
new file mode 100644
index 0000000..632f923
--- /dev/null
+++ b/liboctave/MArrayN.h
@@ -0,0 +1,120 @@
+// Template array classes with like-type math ops
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MArrayN_h)
+#define octave_MArrayN_h 1
+
+#include "ArrayN.h"
+#include "MArray2.h"
+#include "dim-vector.h"
+
+// N-dimensional array with math ops.
+
+// But first, some preprocessor abuse...
+
+#include "MArray-decl.h"
+
+MARRAY_OPS_FORWARD_DECLS (MArrayN, )
+
+template <class T>
+class
+MArrayN : public ArrayN<T>
+{
+protected:
+
+  MArrayN (T *d, const dim_vector& dv) : ArrayN<T> (d, dv) { }
+
+public:
+  
+  MArrayN (void) : ArrayN<T> () {}
+  
+  MArrayN (const dim_vector& dv) : ArrayN<T> (dv) { }
+  
+  MArrayN (const dim_vector& dv, const T& val) : ArrayN<T> (dv, val) { }
+
+  template <class U>
+  explicit MArrayN (const Array2<U>& a) : ArrayN<T> (a) { }
+
+  template <class U>
+  MArrayN (const ArrayN<U>& a) : ArrayN<T> (a) { }
+
+  template <class U>
+  MArrayN (const MArrayN<U>& a) : ArrayN<T> (a) { }
+
+  ~MArrayN (void) { }
+
+  MArrayN<T>& operator = (const MArrayN<T>& a)
+    {
+      ArrayN<T>::operator = (a);
+      return *this;
+    }
+
+  octave_idx_type nnz (void) const
+    {
+      octave_idx_type retval = 0;
+
+      const T *d = this->data ();
+
+      octave_idx_type nel = this->numel ();
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  if (d[i] != T ())
+	    retval++;
+	}
+
+      return retval;
+    }
+
+  MArrayN<T> reshape (const dim_vector& new_dims) const
+    { return ArrayN<T>::reshape (new_dims); }
+
+  MArrayN<T> permute (const Array<octave_idx_type>& vec, 
+		      bool inv = false) const
+    { return ArrayN<T>::permute (vec, inv); }
+
+  MArrayN<T> ipermute (const Array<octave_idx_type>& vec) const
+    { return ArrayN<T>::ipermute (vec); }
+
+  MArrayN squeeze (void) const { return ArrayN<T>::squeeze (); }
+
+  MArrayN<T> diag (octave_idx_type k) const
+  {
+    return ArrayN<T>::diag (k);
+  }
+
+  template <class U, class F>
+  MArrayN<U> map (F fcn) const
+  {
+    return ArrayN<T>::template map<U> (fcn);
+  }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MDiagArray2.cc b/liboctave/MDiagArray2.cc
new file mode 100644
index 0000000..a7b36ef
--- /dev/null
+++ b/liboctave/MDiagArray2.cc
@@ -0,0 +1,191 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MDiagArray2.h"
+#include "Array-util.h"
+#include "lo-error.h"
+
+#include "MArray-defs.h"
+
+template <class T>
+bool 
+MDiagArray2<T>::is_multiple_of_identity (T val) const
+{
+  bool retval = this->rows () == this->cols ();
+  if (retval)
+    {
+      octave_idx_type len = this->length (), i = 0;
+      for (;i < len; i++) 
+        if (DiagArray2<T>::elem (i, i) != val) break;
+      retval = i == len;
+    }
+
+  return retval;
+}
+
+// Some functions return a reference to this object after a failure.
+template <class T> MDiagArray2<T> MDiagArray2<T>::nil_array;
+
+// Two dimensional diagonal array with math ops.
+
+// Element by element MDiagArray2 by MDiagArray2 ops.
+
+template <class T>
+MDiagArray2<T>&
+operator += (MDiagArray2<T>& a, const MDiagArray2<T>& b)
+{
+  octave_idx_type r = a.rows ();
+  octave_idx_type c = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (r != b_nr || c != b_nc)
+    {
+      gripe_nonconformant ("operator +=", r, c, b_nr, b_nc);
+      return MDiagArray2<T>::nil_array;
+    }
+  else
+    {
+      octave_idx_type l = a.length ();
+      DO_VV_OP2 (T, a, +=, b);
+    }
+  return a;
+}
+
+template <class T>
+MDiagArray2<T>&
+operator -= (MDiagArray2<T>& a, const MDiagArray2<T>& b)
+{
+  octave_idx_type r = a.rows ();
+  octave_idx_type c = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (r != b_nr || c != b_nc)
+    {
+      gripe_nonconformant ("operator -=", r, c, b_nr, b_nc);
+      return MDiagArray2<T>::nil_array;
+    }
+  else
+    {
+      octave_idx_type l = a.length ();
+      DO_VV_OP2 (T, a, -=, b);
+    }
+  return a;
+}
+
+// Element by element MDiagArray2 by scalar ops.
+
+#define MARRAY_DAS_OP(OP) \
+  template <class T> \
+  MDiagArray2<T> \
+  operator OP (const MDiagArray2<T>& a, const T& s) \
+  { \
+    MDiagArray2<T> result (a.rows (), a.cols ()); \
+    T *r = result.fortran_vec (); \
+    octave_idx_type l = a.length (); \
+    const T *v = a.data (); \
+    DO_VS_OP (r, l, v, OP, s); \
+    return result; \
+  }
+
+MARRAY_DAS_OP (*)
+MARRAY_DAS_OP (/)
+
+// Element by element scalar by MDiagArray2 ops.
+
+template <class T>
+MDiagArray2<T>
+operator * (const T& s, const MDiagArray2<T>& a)
+{
+  MDiagArray2<T> result (a.rows (), a.cols ()); \
+  T *r = result.fortran_vec (); \
+  octave_idx_type l = a.length (); \
+  const T *v = a.data (); \
+  DO_SV_OP (r, l, s, *, v); \
+  return result; \
+}
+
+// Element by element MDiagArray2 by MDiagArray2 ops.
+
+#define MARRAY_DADA_OP(FCN, OP) \
+  template <class T> \
+  MDiagArray2<T> \
+  FCN (const MDiagArray2<T>& a, const MDiagArray2<T>& b) \
+  { \
+    octave_idx_type a_nr = a.rows (); \
+    octave_idx_type a_nc = a.cols (); \
+    octave_idx_type b_nr = b.rows (); \
+    octave_idx_type b_nc = b.cols (); \
+    if (a_nr != b_nr || a_nc != b_nc) \
+      { \
+        gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \
+	return MDiagArray2<T> (); \
+      } \
+    if (a_nc == 0 || a_nr == 0) \
+      return MDiagArray2<T> (); \
+    octave_idx_type l = a.length (); \
+    MDiagArray2<T> result (a_nr, a_nc); \
+    T *r = result.fortran_vec (); \
+    const T *x = a.data (); \
+    const T *y = b.data (); \
+    DO_VV_OP (r, l, x, OP, y); \
+    return result; \
+  }
+
+MARRAY_DADA_OP (operator +, +)
+MARRAY_DADA_OP (operator -, -)
+MARRAY_DADA_OP (product,    *)
+
+// Unary MDiagArray2 ops.
+
+template <class T>
+MDiagArray2<T>
+operator + (const MDiagArray2<T>& a)
+{
+  return a;
+}
+
+template <class T>
+MDiagArray2<T>
+operator - (const MDiagArray2<T>& a)
+{
+  octave_idx_type l = a.length ();
+  MDiagArray2<T> result (a.rows (), a.cols ());
+  T *r = result.fortran_vec ();
+  const T *x = a.data ();
+  NEG_V (r, l, x);
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MDiagArray2.h b/liboctave/MDiagArray2.h
new file mode 100644
index 0000000..391380c
--- /dev/null
+++ b/liboctave/MDiagArray2.h
@@ -0,0 +1,118 @@
+// Template array classes with like-type math ops
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MDiagArray2_h)
+#define octave_MDiagArray2_h 1
+
+#include "DiagArray2.h"
+#include "MArray2.h"
+#include "MArray.h"
+
+// Two dimensional diagonal array with math ops.
+
+// But first, some preprocessor abuse...
+
+#include "MArray-decl.h"
+
+MDIAGARRAY2_OPS_FORWARD_DECLS (MDiagArray2, )
+
+template <class T>
+class
+MDiagArray2 : public DiagArray2<T>
+{
+protected:
+
+  MDiagArray2 (T *d, octave_idx_type r, octave_idx_type c) : DiagArray2<T> (d, r, c) { }
+
+public:
+  
+  MDiagArray2 (void) : DiagArray2<T> () { }
+
+  MDiagArray2 (octave_idx_type r, octave_idx_type c) : DiagArray2<T> (r, c) { }
+
+  MDiagArray2 (octave_idx_type r, octave_idx_type c, const T& val) : DiagArray2<T> (r, c, val) { }
+
+  MDiagArray2 (const MDiagArray2<T>& a) : DiagArray2<T> (a) { }
+
+  MDiagArray2 (const DiagArray2<T>& a) : DiagArray2<T> (a) { }
+
+  template <class U>
+  MDiagArray2 (const DiagArray2<U>& a) : DiagArray2<T> (a) { }
+
+  explicit MDiagArray2 (const Array<T>& a) : DiagArray2<T> (a) { }
+
+  ~MDiagArray2 (void) { }
+
+  MDiagArray2<T>& operator = (const MDiagArray2<T>& a)
+    {
+      DiagArray2<T>::operator = (a);
+      return *this;
+    }
+
+  operator MArray2<T> () const
+    {
+      return DiagArray2<T>::operator Array2<T> ();
+    }
+
+  octave_idx_type nnz (void) const
+    {
+      octave_idx_type retval = 0;
+
+      const T *d = this->data ();
+
+      octave_idx_type nel = this->length ();
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  if (d[i] != T ())
+	    retval++;
+	}
+
+      return retval;
+    }
+
+  MArray<T> diag (octave_idx_type k = 0) const
+    { return DiagArray2<T>::diag (k); }
+
+  MDiagArray2<T> transpose (void) const { return DiagArray2<T>::transpose (); }
+  MDiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const { return DiagArray2<T>::hermitian (fcn); }
+
+  bool is_multiple_of_identity (T val) const;
+
+  static MDiagArray2<T> nil_array;
+
+  // Currently, the OPS functions don't need to be friends, but that
+  // may change.
+
+  // MDIAGARRAY2_OPS_FRIEND_DECLS (MDiagArray2)
+
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MSparse-C.cc b/liboctave/MSparse-C.cc
new file mode 100644
index 0000000..c97dc8d
--- /dev/null
+++ b/liboctave/MSparse-C.cc
@@ -0,0 +1,41 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-cmplx.h"
+
+#include "MSparse.h"
+#include "MSparse.cc"
+
+template class OCTAVE_API MSparse<Complex>;
+
+INSTANTIATE_SPARSE_FRIENDS (Complex, OCTAVE_API);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MSparse-d.cc b/liboctave/MSparse-d.cc
new file mode 100644
index 0000000..9ae7d71
--- /dev/null
+++ b/liboctave/MSparse-d.cc
@@ -0,0 +1,39 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MSparse.h"
+#include "MSparse.cc"
+
+template class OCTAVE_API MSparse<double>;
+
+INSTANTIATE_SPARSE_FRIENDS (double, OCTAVE_API);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MSparse-defs.h b/liboctave/MSparse-defs.h
new file mode 100644
index 0000000..f785bc9
--- /dev/null
+++ b/liboctave/MSparse-defs.h
@@ -0,0 +1,219 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MSparse_defs_h)
+#define octave_MSparse_defs_h 1
+
+// Nothing like a little CPP abuse to brighten everyone's day.
+
+// A macro that can be used to declare and instantiate OP= operators.
+#define SPARSE_OP_ASSIGN_DECL(A_T, E_T, OP, PFX, API, LTGT, RHS_T) \
+  PFX API A_T<E_T>& \
+  operator OP LTGT (A_T<E_T>&, const RHS_T&)
+
+// All the OP= operators that we care about.
+#define SPARSE_OP_ASSIGN_DECLS(A_T, E_T, PFX, API, LTGT, RHS_T) \
+  SPARSE_OP_ASSIGN_DECL (A_T, E_T, +=, PFX, API, LTGT, RHS_T); \
+  SPARSE_OP_ASSIGN_DECL (A_T, E_T, -=, PFX, API, LTGT, RHS_T);
+
+// Generate forward declarations for OP= operators.
+#define SPARSE_OP_ASSIGN_FWD_DECLS(A_T, RHS_T, API) \
+  SPARSE_OP_ASSIGN_DECLS (A_T, T, template <typename T>, API, , RHS_T)
+
+// Generate friend declarations for the OP= operators.
+#define SPARSE_OP_ASSIGN_FRIENDS(A_T, RHS_T, API) \
+  SPARSE_OP_ASSIGN_DECLS (A_T, T, friend, API, <>, RHS_T)
+
+// Instantiate the OP= operators.
+#define SPARSE_OP_ASSIGN_DEFS(A_T, E_T, RHS_T, API) \
+  SPARSE_OP_ASSIGN_DECLS (A_T, E_T, template, API, , RHS_T)
+
+// A function that can be used to forward OP= operations from derived
+// classes back to us.
+#define SPARSE_OP_ASSIGN_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \
+  inline R \
+  F (X_T& x, const Y_T& y) \
+  { \
+    return R (F (C_X (x), C_Y (y))); \
+  }
+
+// All the OP= operators that we care about forwarding.
+#define SPARSE_OP_ASSIGN_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_OP_ASSIGN_FWD_FCN (R, operator +=, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_OP_ASSIGN_FWD_FCN (R, operator -=, T, C_X, X_T, C_Y, Y_T)
+
+// A macro that can be used to declare and instantiate unary operators.
+#define SPARSE_UNOP(A_T, E_T, F, PFX, API, LTGT) \
+  PFX API A_T<E_T> \
+  F LTGT (const A_T<E_T>&)
+
+// All the unary operators that we care about.
+#define SPARSE_UNOP_DECLS(A_T, E_T, PFX, API, LTGT) \
+  SPARSE_UNOP (A_T, E_T, operator +, PFX, API, LTGT); \
+  SPARSE_UNOP (A_T, E_T, operator -, PFX, API, LTGT);
+
+// Generate forward declarations for unary operators.
+#define SPARSE_UNOP_FWD_DECLS(A_T, API) \
+  SPARSE_UNOP_DECLS (A_T, T, template <typename T>, API, )
+
+// Generate friend declarations for the unary operators.
+#define SPARSE_UNOP_FRIENDS(A_T, API) \
+  SPARSE_UNOP_DECLS (A_T, T, friend, API, <>)
+
+// Instantiate the unary operators.
+#define SPARSE_UNOP_DEFS(A_T, E_T, API) \
+  SPARSE_UNOP_DECLS (A_T, E_T, template, API, )
+
+// A function that can be used to forward unary operations from derived
+// classes back to us.
+#define SPARSE_UNOP_FWD_FCN(R, F, T, C_X, X_T) \
+  inline R \
+  F (const X_T& x) \
+  { \
+    return R (F (C_X (x))); \
+  }
+
+// All the unary operators that we care about forwarding.
+#define SPARSE_UNOP_FWD_DEFS(R, T, C_X, X_T) \
+  SPARSE_UNOP_FWD_FCN (R, operator +, T, C_X, X_T) \
+  SPARSE_UNOP_FWD_FCN (R, operator -, T, C_X, X_T)
+
+// A macro that can be used to declare and instantiate binary operators.
+#define SPARSE_BINOP_DECL(A_T, E_T, F, PFX, API, LTGT, X_T, Y_T) \
+  PFX API A_T<E_T> \
+  F LTGT (const X_T&, const Y_T&)
+
+// All the binary operators that we care about.  We have two
+// sets of macros since the MArray OP MArray operations use functions
+// (product and quotient) instead of operators (*, /).
+#define SPARSE_BINOP_DECLS(A_T, F_T, E_T, PFX, API, LTGT, X_T, Y_T)	 \
+  SPARSE_BINOP_DECL (F_T, E_T, operator +, PFX, API, LTGT, X_T, Y_T); \
+  SPARSE_BINOP_DECL (F_T, E_T, operator -, PFX, API, LTGT, X_T, Y_T); \
+  SPARSE_BINOP_DECL (A_T, E_T, operator *, PFX, API, LTGT, X_T, Y_T); \
+  SPARSE_BINOP_DECL (A_T, E_T, operator /, PFX, API, LTGT, X_T, Y_T);
+
+#define SPARSE_AA_BINOP_DECLS(A_T, E_T, PFX, API, LTGT) \
+  SPARSE_BINOP_DECL (A_T, E_T, operator +, PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  SPARSE_BINOP_DECL (A_T, E_T, operator -, PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  SPARSE_BINOP_DECL (A_T, E_T, quotient,   PFX, API, LTGT, A_T<E_T>, A_T<E_T>); \
+  SPARSE_BINOP_DECL (A_T, E_T, product,    PFX, API, LTGT, A_T<E_T>, A_T<E_T>);
+
+// Generate forward declarations for binary operators.
+#define SPARSE_BINOP_FWD_DECLS(A_T, F_T, API) \
+  SPARSE_BINOP_DECLS (A_T, F_T, T, template <typename T>, API, , A_T<T>, T)	\
+  SPARSE_BINOP_DECLS (A_T, F_T, T, template <typename T>, API, , T, A_T<T>) \
+  SPARSE_AA_BINOP_DECLS (A_T, T, template <typename T>, API, )
+
+// Generate friend declarations for the binary operators.
+#define SPARSE_BINOP_FRIENDS(A_T, F_T, API)		     \
+  SPARSE_BINOP_DECLS (A_T, F_T, T, friend, API, <>, A_T<T>, T)	\
+  SPARSE_BINOP_DECLS (A_T, F_T, T, friend, API, <>, T, A_T<T>)	\
+  SPARSE_AA_BINOP_DECLS (A_T, T, friend, API, <>)
+
+// Instantiate the binary operators.
+#define SPARSE_BINOP_DEFS(A_T, F_T, E_T, API) \
+  SPARSE_BINOP_DECLS (A_T, F_T, E_T, template, API, , A_T<E_T>, E_T)	\
+  SPARSE_BINOP_DECLS (A_T, F_T, E_T, template, API, , E_T, A_T<E_T>)	\
+  SPARSE_AA_BINOP_DECLS (A_T, E_T, template, API, )
+
+// A function that can be used to forward binary operations from derived
+// classes back to us.
+#define SPARSE_BINOP_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \
+  inline R \
+  F (const X_T& x, const Y_T& y) \
+  { \
+    return R (F (C_X (x), C_Y (y))); \
+  }
+
+// The binary operators that we care about forwarding.  We have two
+// sets of macros since the MSparse OP MSparse operations use functions
+// (product and quotient) instead of operators (*, /).
+#define SPARSE_BINOP_FWD_DEFS(R, F, T, C_X, X_T, C_Y, Y_T)     \
+  SPARSE_BINOP_FWD_FCN (F, operator +, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (F, operator -, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (R, operator *, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (R, operator /, T, C_X, X_T, C_Y, Y_T)
+
+#define SPARSE_AA_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (R, operator +, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (R, operator -, T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (R, product,    T, C_X, X_T, C_Y, Y_T) \
+  SPARSE_BINOP_FWD_FCN (R, quotient,   T, C_X, X_T, C_Y, Y_T)
+
+// Forward declarations for the MSparse operators.
+#define SPARSE_OPS_FORWARD_DECLS(A_T, F_T, API) \
+  template <class T> \
+  class A_T; \
+ \
+  /* SPARSE_OP_ASSIGN_FWD_DECLS (A_T, T) */ \
+  SPARSE_OP_ASSIGN_FWD_DECLS (A_T, A_T<T>, API) \
+  SPARSE_UNOP_FWD_DECLS (A_T, API) \
+  SPARSE_BINOP_FWD_DECLS (A_T, F_T, API)
+
+// Friend declarations for the MSparse operators.
+#define SPARSE_OPS_FRIEND_DECLS(A_T, F_T, API)  \
+  /* SPARSE_OP_ASSIGN_FRIENDS (A_T, T) */ \
+  SPARSE_OP_ASSIGN_FRIENDS (A_T, A_T<T>, API) \
+  SPARSE_UNOP_FRIENDS (A_T, API) \
+    SPARSE_BINOP_FRIENDS (A_T, F_T, API)
+
+// The following macros are for external use.
+
+// Instantiate all the MSparse friends for MSparse element type T.
+#define INSTANTIATE_SPARSE_FRIENDS(T, API) \
+  /* SPARSE_OP_ASSIGN_DEFS (MSparse, T, T) */ \
+  SPARSE_OP_ASSIGN_DEFS (MSparse, T, MSparse<T>, API) \
+  SPARSE_UNOP_DEFS (MSparse, T, API) \
+  SPARSE_BINOP_DEFS (MSparse, MArray2, T, API)
+
+// Define all the MSparse forwarding functions for return type R and
+// MSparse element type T
+#define SPARSE_FORWARD_DEFS(B, R, F, T) 	\
+  /* SPARSE_OP_ASSIGN_FWD_DEFS	*/ \
+  /* (R, T, dynamic_cast<B<T>&>, R, , T) */	\
+ \
+  SPARSE_OP_ASSIGN_FWD_DEFS \
+    (R, T, \
+     dynamic_cast<B<T>&>, R, dynamic_cast<const B<T>&>, R) \
+ \
+  SPARSE_UNOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R) \
+ \
+  SPARSE_BINOP_FWD_DEFS \
+    (R, F, T, dynamic_cast<const B<T>&>, R, , T) \
+ \
+  SPARSE_BINOP_FWD_DEFS \
+    (R, F, T, , T, dynamic_cast<const B<T>&>, R)	\
+ \
+  SPARSE_AA_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, dynamic_cast<const B<T>&>, R)
+
+// Now we have all the definitions we need.
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MSparse.cc b/liboctave/MSparse.cc
new file mode 100644
index 0000000..d2eedc8
--- /dev/null
+++ b/liboctave/MSparse.cc
@@ -0,0 +1,640 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "quit.h"
+#include "lo-error.h"
+#include "MArray2.h"
+#include "Array-util.h"
+
+#include "MSparse.h"
+#include "MSparse-defs.h"
+
+// sparse array with math ops.
+
+// Element by element MSparse by MSparse ops.
+
+template <class T>
+MSparse<T>&
+operator += (MSparse<T>& a, const MSparse<T>& b)
+{
+    MSparse<T> r;
+
+    octave_idx_type a_nr = a.rows ();
+    octave_idx_type a_nc = a.cols ();
+
+    octave_idx_type b_nr = b.rows ();
+    octave_idx_type b_nc = b.cols ();
+
+    if (a_nr != b_nr || a_nc != b_nc)
+      gripe_nonconformant ("operator +=" , a_nr, a_nc, b_nr, b_nc);
+    else
+      {
+        r = MSparse<T> (a_nr, a_nc, (a.nnz () + b.nnz ()));
+       
+        octave_idx_type jx = 0;
+        for (octave_idx_type i = 0 ; i < a_nc ; i++)
+          {
+            octave_idx_type  ja = a.cidx(i);
+            octave_idx_type  ja_max = a.cidx(i+1);
+            bool ja_lt_max= ja < ja_max;
+           
+            octave_idx_type  jb = b.cidx(i);
+            octave_idx_type  jb_max = b.cidx(i+1);
+            bool jb_lt_max = jb < jb_max;
+           
+            while (ja_lt_max || jb_lt_max )
+              {
+                OCTAVE_QUIT;
+                if ((! jb_lt_max) ||
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb))))
+                  {
+                    r.ridx(jx) = a.ridx(ja);
+                    r.data(jx) = a.data(ja) + 0.;
+                    jx++;
+                    ja++;
+                    ja_lt_max= ja < ja_max;
+                  }
+                else if (( !ja_lt_max ) ||
+                     (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) )
+                  {
+		    r.ridx(jx) = b.ridx(jb);
+		    r.data(jx) = 0. + b.data(jb);
+		    jx++;
+                    jb++;
+                    jb_lt_max= jb < jb_max;
+                  }
+                else
+                  {
+		     if ((a.data(ja) + b.data(jb)) != 0.)
+	               {
+                          r.data(jx) = a.data(ja) + b.data(jb);
+                          r.ridx(jx) = a.ridx(ja);
+                          jx++;
+                       }
+                     ja++;
+                     ja_lt_max= ja < ja_max;
+                     jb++;
+                     jb_lt_max= jb < jb_max;
+                  }
+              }
+            r.cidx(i+1) = jx;
+          }
+       
+	a = r.maybe_compress ();
+      }
+
+    return a;
+}
+
+template <class T>
+MSparse<T>&
+operator -= (MSparse<T>& a, const MSparse<T>& b)
+{
+    MSparse<T> r;
+
+    octave_idx_type a_nr = a.rows ();
+    octave_idx_type a_nc = a.cols ();
+
+    octave_idx_type b_nr = b.rows ();
+    octave_idx_type b_nc = b.cols ();
+
+    if (a_nr != b_nr || a_nc != b_nc)
+      gripe_nonconformant ("operator -=" , a_nr, a_nc, b_nr, b_nc);
+    else
+      {
+        r = MSparse<T> (a_nr, a_nc, (a.nnz () + b.nnz ()));
+       
+        octave_idx_type jx = 0;
+        for (octave_idx_type i = 0 ; i < a_nc ; i++)
+          {
+            octave_idx_type  ja = a.cidx(i);
+            octave_idx_type  ja_max = a.cidx(i+1);
+            bool ja_lt_max= ja < ja_max;
+           
+            octave_idx_type  jb = b.cidx(i);
+            octave_idx_type  jb_max = b.cidx(i+1);
+            bool jb_lt_max = jb < jb_max;
+           
+            while (ja_lt_max || jb_lt_max )
+              {
+                OCTAVE_QUIT;
+                if ((! jb_lt_max) ||
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb))))
+                  {
+                    r.ridx(jx) = a.ridx(ja);
+                    r.data(jx) = a.data(ja) - 0.;
+                    jx++;
+                    ja++;
+                    ja_lt_max= ja < ja_max;
+                  }
+                else if (( !ja_lt_max ) ||
+                     (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) )
+                  {
+		    r.ridx(jx) = b.ridx(jb);
+		    r.data(jx) = 0. - b.data(jb);
+		    jx++;
+                    jb++;
+                    jb_lt_max= jb < jb_max;
+                  }
+                else
+                  {
+		     if ((a.data(ja) - b.data(jb)) != 0.)
+	               {
+                          r.data(jx) = a.data(ja) - b.data(jb);
+                          r.ridx(jx) = a.ridx(ja);
+                          jx++;
+                       }
+                     ja++;
+                     ja_lt_max= ja < ja_max;
+                     jb++;
+                     jb_lt_max= jb < jb_max;
+                  }
+              }
+            r.cidx(i+1) = jx;
+          }
+       
+	a = r.maybe_compress ();
+      }
+
+    return a;
+}
+
+// Element by element MSparse by scalar ops.
+
+#define SPARSE_A2S_OP_1(OP) \
+  template <class T> \
+  MArray2<T> \
+  operator OP (const MSparse<T>& a, const T& s) \
+  { \
+    octave_idx_type nr = a.rows (); \
+    octave_idx_type nc = a.cols (); \
+ \
+    MArray2<T> r (nr, nc, (0.0 OP s));	\
+ \
+    for (octave_idx_type j = 0; j < nc; j++) \
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)	\
+        r.elem (a.ridx (i), j) = a.data (i) OP s;	\
+    return r; \
+  }
+
+#define SPARSE_A2S_OP_2(OP) \
+  template <class T> \
+  MSparse<T> \
+  operator OP (const MSparse<T>& a, const T& s) \
+  { \
+    octave_idx_type nr = a.rows (); \
+    octave_idx_type nc = a.cols (); \
+    octave_idx_type nz = a.nnz (); \
+ \
+    MSparse<T> r (nr, nc, nz); \
+ \
+    for (octave_idx_type i = 0; i < nz; i++) \
+      { \
+	r.data(i) = a.data(i) OP s; \
+	r.ridx(i) = a.ridx(i); \
+      } \
+    for (octave_idx_type i = 0; i < nc + 1; i++) \
+      r.cidx(i) = a.cidx(i); \
+    r.maybe_compress (true); \
+    return r; \
+  }
+
+
+SPARSE_A2S_OP_1 (+)
+SPARSE_A2S_OP_1 (-)
+SPARSE_A2S_OP_2 (*)
+SPARSE_A2S_OP_2 (/)
+
+// Element by element scalar by MSparse ops.
+
+#define SPARSE_SA2_OP_1(OP) \
+  template <class T> \
+  MArray2<T> \
+  operator OP (const T& s, const MSparse<T>& a) \
+  { \
+    octave_idx_type nr = a.rows (); \
+    octave_idx_type nc = a.cols (); \
+ \
+    MArray2<T> r (nr, nc, (s OP 0.0));	\
+ \
+    for (octave_idx_type j = 0; j < nc; j++) \
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)	\
+        r.elem (a.ridx (i), j) = s OP a.data (i);	\
+    return r; \
+  }
+
+#define SPARSE_SA2_OP_2(OP) \
+  template <class T> \
+  MSparse<T> \
+  operator OP (const T& s, const MSparse<T>& a) \
+  { \
+    octave_idx_type nr = a.rows (); \
+    octave_idx_type nc = a.cols (); \
+    octave_idx_type nz = a.nnz (); \
+ \
+    MSparse<T> r (nr, nc, nz); \
+ \
+    for (octave_idx_type i = 0; i < nz; i++) \
+      { \
+	r.data(i) = s OP a.data(i); \
+	r.ridx(i) = a.ridx(i); \
+      } \
+    for (octave_idx_type i = 0; i < nc + 1; i++) \
+      r.cidx(i) = a.cidx(i); \
+    r.maybe_compress (true); \
+    return r; \
+  }
+
+SPARSE_SA2_OP_1 (+)
+SPARSE_SA2_OP_1 (-)
+SPARSE_SA2_OP_2 (*)
+SPARSE_SA2_OP_2 (/)
+
+// Element by element MSparse by MSparse ops.
+
+#define SPARSE_A2A2_OP(OP) \
+  template <class T> \
+  MSparse<T> \
+  operator OP (const MSparse<T>& a, const MSparse<T>& b) \
+  { \
+    MSparse<T> r; \
+ \
+    octave_idx_type a_nr = a.rows (); \
+    octave_idx_type a_nc = a.cols (); \
+ \
+    octave_idx_type b_nr = b.rows (); \
+    octave_idx_type b_nc = b.cols (); \
+ \
+    if (a_nr == 1 && a_nc == 1) \
+      { \
+        if (a.elem(0,0) == 0.) \
+          r =  OP MSparse<T> (b); \
+        else \
+          { \
+	    r = MSparse<T> (b_nr, b_nc, a.data(0) OP 0.); \
+            \
+            for (octave_idx_type j = 0 ; j < b_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * b_nr; \
+                for (octave_idx_type i = b.cidx(j) ; i < b.cidx(j+1) ; i++) \
+                  { \
+                   OCTAVE_QUIT; \
+                   r.data(idxj + b.ridx(i)) = a.data(0) OP b.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (b_nr == 1 && b_nc == 1) \
+      { \
+        if (b.elem(0,0) == 0.) \
+          r = MSparse<T> (a); \
+        else \
+          { \
+	    r = MSparse<T> (a_nr, a_nc, 0. OP b.data(0)); \
+            \
+            for (octave_idx_type j = 0 ; j < a_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * a_nr; \
+                for (octave_idx_type i = a.cidx(j) ; i < a.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + a.ridx(i)) = a.data(i) OP b.data(0); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (a_nr != b_nr || a_nc != b_nc) \
+      gripe_nonconformant ("operator " # OP, a_nr, a_nc, b_nr, b_nc); \
+    else \
+      { \
+        r = MSparse<T> (a_nr, a_nc, (a.nnz () + b.nnz ())); \
+        \
+        octave_idx_type jx = 0; \
+	r.cidx (0) = 0; \
+        for (octave_idx_type i = 0 ; i < a_nc ; i++) \
+          { \
+            octave_idx_type  ja = a.cidx(i); \
+            octave_idx_type  ja_max = a.cidx(i+1); \
+            bool ja_lt_max= ja < ja_max; \
+            \
+            octave_idx_type  jb = b.cidx(i); \
+            octave_idx_type  jb_max = b.cidx(i+1); \
+            bool jb_lt_max = jb < jb_max; \
+            \
+            while (ja_lt_max || jb_lt_max ) \
+              { \
+                OCTAVE_QUIT; \
+                if ((! jb_lt_max) || \
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) \
+                  { \
+                    r.ridx(jx) = a.ridx(ja); \
+                    r.data(jx) = a.data(ja) OP 0.; \
+                    jx++; \
+                    ja++; \
+                    ja_lt_max= ja < ja_max; \
+                  } \
+                else if (( !ja_lt_max ) || \
+                     (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) ) \
+                  { \
+		    r.ridx(jx) = b.ridx(jb); \
+		    r.data(jx) = 0. OP b.data(jb); \
+		    jx++; \
+                    jb++; \
+                    jb_lt_max= jb < jb_max; \
+                  } \
+                else \
+                  { \
+		     if ((a.data(ja) OP b.data(jb)) != 0.) \
+	               { \
+                          r.data(jx) = a.data(ja) OP b.data(jb); \
+                          r.ridx(jx) = a.ridx(ja); \
+                          jx++; \
+                       } \
+                     ja++; \
+                     ja_lt_max= ja < ja_max; \
+                     jb++; \
+                     jb_lt_max= jb < jb_max; \
+                  } \
+              } \
+            r.cidx(i+1) = jx; \
+          } \
+        \
+	r.maybe_compress (); \
+      } \
+ \
+    return r; \
+  }
+
+#define SPARSE_A2A2_FCN_1(FCN, OP)	\
+  template <class T> \
+  MSparse<T> \
+  FCN (const MSparse<T>& a, const MSparse<T>& b) \
+  { \
+    MSparse<T> r; \
+ \
+    octave_idx_type a_nr = a.rows (); \
+    octave_idx_type a_nc = a.cols (); \
+ \
+    octave_idx_type b_nr = b.rows (); \
+    octave_idx_type b_nc = b.cols (); \
+ \
+    if (a_nr == 1 && a_nc == 1) \
+      { \
+        if (a.elem(0,0) == 0.) \
+          r = MSparse<T> (b_nr, b_nc); \
+        else \
+          { \
+	    r = MSparse<T> (b); \
+            octave_idx_type b_nnz = b.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < b_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = a.data(0) OP r.data(i); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (b_nr == 1 && b_nc == 1) \
+      { \
+        if (b.elem(0,0) == 0.) \
+          r = MSparse<T> (a_nr, a_nc); \
+        else \
+          { \
+	    r = MSparse<T> (a); \
+            octave_idx_type a_nnz = a.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < a_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = r.data(i) OP b.data(0); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (a_nr != b_nr || a_nc != b_nc) \
+      gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \
+    else \
+      { \
+        r = MSparse<T> (a_nr, a_nc, (a.nnz () > b.nnz () ? a.nnz () : b.nnz ())); \
+        \
+        octave_idx_type jx = 0; \
+	r.cidx (0) = 0; \
+        for (octave_idx_type i = 0 ; i < a_nc ; i++) \
+          { \
+            octave_idx_type  ja = a.cidx(i); \
+            octave_idx_type  ja_max = a.cidx(i+1); \
+            bool ja_lt_max= ja < ja_max; \
+            \
+            octave_idx_type  jb = b.cidx(i); \
+            octave_idx_type  jb_max = b.cidx(i+1); \
+            bool jb_lt_max = jb < jb_max; \
+            \
+            while (ja_lt_max || jb_lt_max ) \
+              { \
+                OCTAVE_QUIT; \
+                if ((! jb_lt_max) || \
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) \
+                  { \
+                     ja++; ja_lt_max= ja < ja_max; \
+                  } \
+                else if (( !ja_lt_max ) || \
+                     (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) ) \
+                  { \
+                     jb++; jb_lt_max= jb < jb_max; \
+                  } \
+                else \
+                  { \
+		     if ((a.data(ja) OP b.data(jb)) != 0.) \
+	               { \
+                          r.data(jx) = a.data(ja) OP b.data(jb); \
+                          r.ridx(jx) = a.ridx(ja); \
+                          jx++; \
+                       } \
+                     ja++; ja_lt_max= ja < ja_max; \
+                     jb++; jb_lt_max= jb < jb_max; \
+                  } \
+              } \
+            r.cidx(i+1) = jx; \
+          } \
+        \
+	r.maybe_compress (); \
+      } \
+ \
+    return r; \
+  }
+
+#define SPARSE_A2A2_FCN_2(FCN, OP)	\
+  template <class T> \
+  MSparse<T> \
+  FCN (const MSparse<T>& a, const MSparse<T>& b) \
+  { \
+    MSparse<T> r; \
+    T Zero = T (); \
+ \
+    octave_idx_type a_nr = a.rows (); \
+    octave_idx_type a_nc = a.cols (); \
+ \
+    octave_idx_type b_nr = b.rows (); \
+    octave_idx_type b_nc = b.cols (); \
+ \
+    if (a_nr == 1 && a_nc == 1) \
+      { \
+        T val = a.elem (0,0); \
+        T fill = val OP T(); \
+        if (fill == T()) \
+          { \
+            octave_idx_type b_nnz = b.nnz(); \
+            r = MSparse<T> (b); \
+            for (octave_idx_type i = 0 ; i < b_nnz ; i++) \
+              r.data (i) = val OP r.data(i); \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = MSparse<T> (b_nr, b_nc, fill); \
+            for (octave_idx_type j = 0 ; j < b_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * b_nr; \
+                for (octave_idx_type i = b.cidx(j) ; i < b.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + b.ridx(i)) = val OP b.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (b_nr == 1 && b_nc == 1) \
+      { \
+        T val = b.elem (0,0); \
+        T fill = T() OP val; \
+        if (fill == T()) \
+          { \
+            octave_idx_type a_nnz = a.nnz(); \
+            r = MSparse<T> (a); \
+            for (octave_idx_type i = 0 ; i < a_nnz ; i++) \
+              r.data (i) = r.data(i) OP val; \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = MSparse<T> (a_nr, a_nc, fill); \
+            for (octave_idx_type j = 0 ; j < a_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * a_nr; \
+                for (octave_idx_type i = a.cidx(j) ; i < a.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + a.ridx(i)) = a.data(i) OP val; \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (a_nr != b_nr || a_nc != b_nc) \
+      gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \
+    else \
+      { \
+        r = MSparse<T>( a_nr, a_nc, (Zero OP Zero)); \
+        \
+        for (octave_idx_type i = 0 ; i < a_nc ; i++) \
+          { \
+            octave_idx_type  ja = a.cidx(i); \
+            octave_idx_type  ja_max = a.cidx(i+1); \
+            bool ja_lt_max= ja < ja_max; \
+            \
+            octave_idx_type  jb = b.cidx(i); \
+            octave_idx_type  jb_max = b.cidx(i+1); \
+            bool jb_lt_max = jb < jb_max; \
+            \
+            while (ja_lt_max || jb_lt_max ) \
+              { \
+                OCTAVE_QUIT; \
+                if ((! jb_lt_max) || \
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) \
+                  { \
+		     r.elem (a.ridx(ja),i) = a.data(ja) OP Zero; \
+                     ja++; ja_lt_max= ja < ja_max; \
+                  } \
+                else if (( !ja_lt_max ) || \
+                     (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) ) \
+                  { \
+		     r.elem (b.ridx(jb),i) = Zero OP b.data(jb);	\
+                     jb++; jb_lt_max= jb < jb_max; \
+                  } \
+                else \
+                  { \
+                     r.elem (a.ridx(ja),i) = a.data(ja) OP b.data(jb); \
+                     ja++; ja_lt_max= ja < ja_max; \
+                     jb++; jb_lt_max= jb < jb_max; \
+                  } \
+              } \
+          } \
+        \
+	r.maybe_compress (true); \
+      } \
+ \
+    return r; \
+  }
+
+SPARSE_A2A2_OP (+)
+SPARSE_A2A2_OP (-)
+SPARSE_A2A2_FCN_1 (product,    *)
+SPARSE_A2A2_FCN_2 (quotient,   /)
+
+// Unary MSparse ops.
+
+template <class T>
+MSparse<T>
+operator + (const MSparse<T>& a)
+{
+  return a;
+}
+
+template <class T>
+MSparse<T>
+operator - (const MSparse<T>& a)
+{
+  MSparse<T> retval (a);
+  octave_idx_type nz = a.nnz ();
+  for (octave_idx_type i = 0; i < nz; i++)
+    retval.data(i) = - retval.data(i);
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MSparse.h b/liboctave/MSparse.h
new file mode 100644
index 0000000..927ebcd
--- /dev/null
+++ b/liboctave/MSparse.h
@@ -0,0 +1,138 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MSparse_h)
+#define octave_MSparse_h 1
+
+#include "MArray2.h"
+
+#include "Sparse.h"
+
+// Two dimensional sparse array with math ops.
+
+// But first, some preprocessor abuse...
+
+#include "MSparse-defs.h"
+
+SPARSE_OPS_FORWARD_DECLS (MSparse, MArray2, )
+
+template <class T>
+class
+MSparse : public Sparse<T>
+{
+public:
+
+  MSparse (void) : Sparse<T> () { }
+
+  MSparse (octave_idx_type n, octave_idx_type m) : Sparse<T> (n, m) { }
+
+  MSparse (const dim_vector& dv, octave_idx_type nz = 0) : 
+    Sparse<T> (dv, nz) { }
+
+  MSparse (const MSparse<T>& a) : Sparse<T> (a) { }
+
+  MSparse (const MSparse<T>& a, const dim_vector& dv) : Sparse<T> (a, dv) { }
+
+  MSparse (const Sparse<T>& a) : Sparse<T> (a) { }
+
+  MSparse (const Array<T> a, const Array<octave_idx_type>& r, 
+	   const Array<octave_idx_type>& c, octave_idx_type nr = -1, 
+	   octave_idx_type nc = -1, bool sum_terms = true)
+    : Sparse<T> (a, r, c, nr, nc, sum_terms) { }
+
+  MSparse (const Array<T> a, const Array<double>& r, 
+	   const Array<double>& c, octave_idx_type nr = -1, 
+	   octave_idx_type nc = -1, bool sum_terms = true)
+    : Sparse<T> (a, r, c, nr, nc, sum_terms) { }
+
+  explicit MSparse (octave_idx_type r, octave_idx_type c, T val) : Sparse<T> (r, c, val) { }
+
+  MSparse (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : Sparse<T> (r, c, num_nz) { }
+
+  ~MSparse (void) { }
+
+  MSparse<T>& operator = (const MSparse<T>& a)
+    {
+      Sparse<T>::operator = (a);
+      return *this;
+    }
+
+  MSparse<T>& insert (const Sparse<T>& a, octave_idx_type r, octave_idx_type c)
+  {
+    Sparse<T>::insert (a, r, c);
+    return *this;
+  }
+
+  MSparse<T>& insert (const Sparse<T>& a, const Array<octave_idx_type>& indx)
+  {
+    Sparse<T>::insert (a, indx);
+    return *this;
+  }
+
+  MSparse<T> transpose (void) const { return Sparse<T>::transpose (); }
+
+  MSparse<T> squeeze (void) const { return Sparse<T>::squeeze (); }
+
+  MSparse<T> index (idx_vector& i, int resize_ok) const 
+    { return Sparse<T>::index (i, resize_ok); }
+
+  MSparse<T> index (idx_vector& i, idx_vector& j, int resize_ok) const 
+    { return Sparse<T>::index (i, j, resize_ok); }
+  
+  MSparse<T> index (Array<idx_vector>& ra_idx, int resize_ok) const 
+    { return Sparse<T>::index (ra_idx, resize_ok); }
+
+  MSparse<T> reshape (const dim_vector& new_dims) const
+    { return Sparse<T>::reshape (new_dims); }
+     
+  MSparse<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const
+    { return Sparse<T>::permute (vec, inv); }
+
+  MSparse<T> ipermute (const Array<octave_idx_type>& vec) const
+    { return Sparse<T>::ipermute (vec); }
+
+
+  MSparse<T> diag (octave_idx_type k = 0) const
+  {
+    return Sparse<T>::diag (k);
+  }
+
+ template <class U, class F>
+  MSparse<U> map (F fcn) const
+  {
+    return Sparse<T>::template map<U> (fcn);
+  }
+
+  // Currently, the OPS functions don't need to be friends, but that
+  // may change.
+
+  // SPARSE_OPS_FRIEND_DECLS (MSparse, MArray2)
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Makefile.in b/liboctave/Makefile.in
new file mode 100644
index 0000000..975bd8b
--- /dev/null
+++ b/liboctave/Makefile.in
@@ -0,0 +1,391 @@
+# Makefile for octave's liboctave directory
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+#               2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+DLL_CDEFS = @OCTAVE_DLL_DEFS@
+DLL_CXXDEFS = @OCTAVE_DLL_DEFS@
+
+LINK_DEPS = \
+  -L../libcruft -L. $(RLD_FLAG) \
+  $(LIBCRUFT) $(CHOLMOD_LIBS) $(UMFPACK_LIBS) $(AMD_LIBS) $(CAMD_LIBS) \
+  $(COLAMD_LIBS) $(CCOLAMD_LIBS) $(CXSPARSE_LIBS) $(ARPACK_LIBS) \
+  $(QRUPDATE_LIBS) $(BLAS_LIBS) $(FFTW_LIBS) $(LIBREADLINE) $(LIBGLOB) \
+  $(REGEX_LIBS) $(LIBS) $(FLIBS) $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+
+MATRIX_INC := Array.h Array2.h Array3.h ArrayN.h DiagArray2.h \
+	Array-util.h MArray-decl.h MArray-defs.h \
+	MArray.h MArray2.h MDiagArray2.h Matrix.h MArrayN.h \
+	base-lu.h base-aepbal.h dim-vector.h mx-base.h mx-op-decl.h \
+	mx-op-defs.h mx-defs.h mx-ext.h CColVector.h CDiagMatrix.h \
+	CMatrix.h CNDArray.h CRowVector.h CmplxAEPBAL.h CmplxCHOL.h \
+	CmplxGEPBAL.h CmplxHESS.h CmplxLU.h CmplxQR.h CmplxQRP.h \
+	CmplxSCHUR.h CmplxSVD.h EIG.h fEIG.h boolMatrix.h boolNDArray.h \
+	chMatrix.h chNDArray.h dColVector.h dDiagMatrix.h dMatrix.h \
+	dNDArray.h dRowVector.h dbleAEPBAL.h dbleCHOL.h DET.h \
+	dbleGEPBAL.h dbleHESS.h dbleLU.h dbleQR.h dbleQRP.h dbleSCHUR.h \
+	dbleSVD.h boolSparse.h CSparse.h dSparse.h MSparse-defs.h MSparse.h \
+	Sparse.h sparse-base-lu.h SparseCmplxLU.h SparsedbleLU.h \
+	sparse-base-chol.h SparseCmplxCHOL.h SparsedbleCHOL.h \
+	SparseCmplxQR.h SparseQR.h Sparse-op-defs.h Sparse-diag-op-defs.h \
+	Sparse-perm-op-defs.h MatrixType.h PermMatrix.h \
+	int8NDArray.h uint8NDArray.h int16NDArray.h uint16NDArray.h \
+	int32NDArray.h uint32NDArray.h int64NDArray.h uint64NDArray.h \
+	intNDArray.h \
+	fCColVector.h fCRowVector.h fCDiagMatrix.h fCMatrix.h fCNDArray.h \
+	fColVector.h fRowVector.h fDiagMatrix.h fMatrix.h fNDArray.h \
+	fCmplxAEPBAL.h fCmplxGEPBAL.h fCmplxHESS.h fCmplxCHOL.h \
+	fCmplxLU.h fCmplxSCHUR.h fCmplxSVD.h fCmplxQR.h \
+	fCmplxQRP.h floatAEPBAL.h \
+	floatCHOL.h floatGEPBAL.h floatHESS.h floatLU.h \
+	floatSCHUR.h floatSVD.h floatQR.h floatQRP.h
+
+MX_OP_INC := $(shell $(AWK) -f $(srcdir)/mk-ops.awk prefix=mx list_h_files=1 $(srcdir)/mx-ops)
+
+VX_OP_INC := $(shell $(AWK) -f $(srcdir)/mk-ops.awk prefix=vx list_h_files=1 $(srcdir)/vx-ops)
+
+SPARSE_MX_OP_INC := $(shell $(AWK) -f $(srcdir)/sparse-mk-ops.awk prefix=smx list_h_files=1 $(srcdir)/sparse-mx-ops)
+
+OPT_BASE := $(addsuffix -opts, DASPK DASRT DASSL LSODE Quad)
+OPT_IN := $(addsuffix .in, $(OPT_BASE))
+OPT_INC := $(addsuffix .h, $(OPT_BASE))
+
+INCLUDES := CollocWt.h DAE.h DAEFunc.h DAERT.h \
+	DAERTFunc.h DASPK.h DASRT.h DASSL.h \
+	LSODE.h \
+	ODE.h ODEFunc.h ODES.h ODESFunc.h \
+	Quad.h Range.h base-dae.h \
+	base-de.h base-min.h byte-swap.h cmd-edit.h cmd-hist.h \
+	data-conv.h dir-ops.h file-ops.h file-stat.h functor.h getopt.h \
+	glob-match.h idx-vector.h kpse-xfns.h \
+	lo-ieee.h lo-mappers.h lo-math.h lo-specfun.h lo-sysdep.h \
+	lo-traits.h lo-utils.h mach-info.h md5.h oct-alloc.h oct-cmplx.h \
+	oct-env.h oct-fftw.h oct-getopt.h oct-group.h oct-inttypes.h \
+	oct-locbuf.h oct-md5.h oct-mutex.h oct-norm.h \
+        oct-passwd.h oct-rand.h oct-rl-edit.h oct-rl-hist.h oct-shlib.h \
+        oct-sort.h oct-spparms.h oct-syscalls.h oct-sparse.h oct-time.h \
+        oct-uname.h pathlen.h pathsearch.h prog-args.h \
+	randgamma.h randmtzig.h randpoisson.h regex-match.h \
+	sparse-sort.h statdefs.h str-vec.h \
+	sparse-util.h sun-utils.h sysdir.h systime.h syswait.h \
+	$(MATRIX_INC)
+
+BUILT_INCLUDES := oct-types.h mx-ops.h \
+	$(OPT_INC) \
+	$(MX_OP_INC) \
+	$(VX_OP_INC) \
+	$(SPARSE_MX_OP_INC)
+
+TEMPLATE_SRC := Array.cc ArrayN.cc eigs-base.cc DiagArray2.cc \
+	MArray.cc MArray2.cc MArrayN.cc MDiagArray2.cc \
+	base-lu.cc oct-sort.cc sparse-base-lu.cc \
+	sparse-base-chol.cc sparse-dmsolve.cc
+
+TI_SRC := Array-C.cc Array-b.cc Array-ch.cc Array-i.cc Array-d.cc \
+	Array-f.cc Array-fC.cc Array-s.cc Array-str.cc Array-voidp.cc \
+	Array-idx-vec.cc MArray-C.cc MArray-ch.cc MArray-i.cc MArray-d.cc \
+	MArray-f.cc MArray-fC.cc MArray-s.cc MSparse-C.cc MSparse-d.cc \
+	Sparse-C.cc Sparse-b.cc Sparse-d.cc oct-inttypes.cc
+
+MATRIX_SRC := Array-util.cc CColVector.cc \
+	CDiagMatrix.cc CMatrix.cc CNDArray.cc CRowVector.cc \
+	CmplxAEPBAL.cc CmplxCHOL.cc CmplxGEPBAL.cc CmplxHESS.cc \
+	CmplxLU.cc CmplxQR.cc CmplxQRP.cc CmplxSCHUR.cc CmplxSVD.cc \
+	EIG.cc fEIG.cc boolMatrix.cc boolNDArray.cc chMatrix.cc \
+	chNDArray.cc dColVector.cc dDiagMatrix.cc dMatrix.cc \
+	dNDArray.cc dRowVector.cc dbleAEPBAL.cc dbleCHOL.cc \
+	dbleGEPBAL.cc dbleHESS.cc dbleLU.cc dbleQR.cc dbleQRP.cc \
+	dbleSCHUR.cc dbleSVD.cc boolSparse.cc CSparse.cc dSparse.cc \
+	MSparse.cc Sparse.cc SparseCmplxLU.cc SparsedbleLU.cc \
+	SparseCmplxCHOL.cc SparsedbleCHOL.cc \
+	SparseCmplxQR.cc SparseQR.cc MatrixType.cc PermMatrix.cc \
+	int8NDArray.cc uint8NDArray.cc int16NDArray.cc uint16NDArray.cc \
+	int32NDArray.cc uint32NDArray.cc int64NDArray.cc uint64NDArray.cc \
+	fCColVector.cc fCRowVector.cc fCDiagMatrix.cc fCMatrix.cc fCNDArray.cc \
+	fColVector.cc fRowVector.cc fDiagMatrix.cc fMatrix.cc fNDArray.cc \
+	fCmplxAEPBAL.cc fCmplxCHOL.cc fCmplxGEPBAL.cc \
+	fCmplxHESS.cc fCmplxLU.cc fCmplxSCHUR.cc fCmplxSVD.cc fCmplxQR.cc \
+	fCmplxQRP.cc floatAEPBAL.cc floatCHOL.cc \
+	floatGEPBAL.cc floatHESS.cc floatLU.cc \
+	floatSCHUR.cc floatSVD.cc floatQR.cc floatQRP.cc
+
+MX_OP_SRC := $(shell $(AWK) -f $(srcdir)/mk-ops.awk prefix=mx list_cc_files=1 $(srcdir)/mx-ops)
+
+VX_OP_SRC := $(shell $(AWK) -f $(srcdir)/mk-ops.awk prefix=vx list_cc_files=1 $(srcdir)/vx-ops)
+
+SPARSE_MX_OP_SRC := $(shell $(AWK) -f $(srcdir)/sparse-mk-ops.awk prefix=smx list_cc_files=1 $(srcdir)/sparse-mx-ops)
+
+LIBOCTAVE_CXX_SOURCES := oct-locbuf.cc CollocWt.cc DASPK.cc DASRT.cc \
+	DASSL.cc LSODE.cc ODES.cc \
+	Quad.cc Range.cc data-conv.cc dir-ops.cc \
+	file-ops.cc file-stat.cc glob-match.cc idx-vector.cc \
+	lo-ieee.cc lo-mappers.cc lo-specfun.cc lo-sysdep.cc \
+	lo-utils.cc mach-info.cc oct-alloc.cc oct-env.cc \
+	oct-fftw.cc oct-group.cc oct-mutex.cc oct-md5.cc \
+	oct-norm.cc oct-passwd.cc oct-rand.cc \
+	oct-shlib.cc oct-spparms.cc oct-syscalls.cc oct-time.cc oct-uname.cc \
+	prog-args.cc regex-match.cc \
+	sparse-sort.cc sparse-util.cc str-vec.cc \
+	$(TI_SRC) \
+	$(MATRIX_SRC)
+
+BUILT_LIBOCTAVE_CXX_SOURCES := \
+	$(MX_OP_SRC) \
+	$(VX_OP_SRC) \
+	$(SPARSE_MX_OP_SRC)
+
+LIBOCTAVE_C_SOURCES := f2c-main.c filemode.c getopt.c getopt1.c \
+	lo-cieee.c lo-cutils.c md5.c mkdir.c oct-getopt.c \
+	randgamma.c randmtzig.c randpoisson.c rename.c \
+	rmdir.c strftime.c strptime.c strcasecmp.c strncase.c \
+	tempname.c tempnam.c
+
+LIBOCTAVE_SOURCES := $(LIBOCTAVE_CXX_SOURCES) $(BUILT_LIBOCTAVE_CXX_SOURCES) \
+	$(LIBOCTAVE_C_SOURCES)
+
+LIBOCT_READLINE_CXX_SOURCES := cmd-edit.cc cmd-hist.cc
+
+LIBOCT_READLINE_C_SOURCES := oct-rl-edit.c oct-rl-hist.c
+
+LIBOCT_READLINE_SOURCES := $(LIBOCT_READLINE_CXX_SOURCES) $(LIBOCT_READLINE_C_SOURCES)
+
+LIBOCT_PATHSEARCH_CXX_SOURCES := pathsearch.cc
+
+LIBOCT_PATHSEARCH_C_SOURCES := kpse-xfns.c
+
+LIBOCT_PATHSEARCH_SOURCES := \
+	$(LIBOCT_PATHSEARCH_C_SOURCES) $(LIBOCT_PATHSEARCH_CXX_SOURCES)
+
+SOURCES := \
+	$(LIBOCTAVE_SOURCES) \
+	$(LIBOCT_READLINE_SOURCES) \
+	$(LIBOCT_PATHSEARCH_SOURCES)
+
+EXTRAS := mx-inlines.cc kpse.cc intNDArray.cc
+
+INCLUDES_FOR_INSTALL := $(INCLUDES) $(BUILT_INCLUDES) $(TEMPLATE_SRC) $(EXTRAS)
+
+DISTFILES := $(addprefix $(srcdir)/, Makefile.in ChangeLog mk-ops.awk \
+	mx-ops vx-ops sparse-mk-ops.awk sparse-mx-ops oct-types.h.in \
+	$(TEMPLATE_SRC) \
+	$(LIBOCTAVE_CXX_SOURCES) \
+	$(LIBOCT_READLINE_SOURCES) \
+	$(LIBOCT_PATHSEARCH_SOURCES) \
+	$(LIBOCTAVE_C_SOURCES) \
+	$(INCLUDES) $(EXTRAS) $(OPT_IN)) \
+	$(BUILT_LIBOCTAVE_CXX_SOURCES) $(BUILT_INCLUDES)
+
+MAKEDEPS_1 := $(patsubst %.cc, %.d, $(SOURCES))
+MAKEDEPS := $(patsubst %.c, %.d, $(MAKEDEPS_1))
+
+LIBOCTAVE_OBJECTS := \
+	$(LIBOCTAVE_CXX_SOURCES:.cc=.o) \
+	$(BUILT_LIBOCTAVE_CXX_SOURCES:.cc=.o) \
+	$(LIBOCTAVE_C_SOURCES:.c=.o) \
+	$(LIBOCT_READLINE_CXX_SOURCES:.cc=.o) \
+	$(LIBOCT_READLINE_C_SOURCES:.c=.o) \
+	$(LIBOCT_PATHSEARCH_CXX_SOURCES:.cc=.o) \
+	$(LIBOCT_PATHSEARCH_C_SOURCES:.c=.o)
+
+ifeq ($(SHARED_LIBS), true)
+  ifdef CXXPICFLAG
+    LIBOCTAVE_PICOBJ := $(addprefix pic/, $(LIBOCTAVE_OBJECTS))
+  else
+    LIBOCTAVE_PICOBJ := $(LIBOCTAVE_OBJECTS)
+  endif
+endif
+
+all: libraries
+.PHONY: all
+
+objects: $(LIBOCTAVE_OBJECTS)
+
+stmp-pic: pic
+	@if [ -f stmp-pic ]; then \
+	  true; \
+	else \
+	  echo "touch stmp-pic"; \
+	  touch stmp-pic; \
+	fi
+
+pic:
+	@if [ -d pic ]; then \
+	  true; \
+	else \
+	  echo "mkdir pic"; \
+	  mkdir pic; \
+	fi
+
+PREREQ := $(OPT_INC) $(VX_OP_INC) $(VX_OP_SRC) \
+	$(MX_OP_INC) $(MX_OP_SRC) mx-ops.h \
+	$(SPARSE_MX_OP_INC) $(SPARSE_MX_OP_SRC)
+
+ifeq ($(SHARED_LIBS), true)
+  ifeq ($(STATIC_LIBS), true)
+    LIBRARIES = $(LIBPRE)octave.$(LIBEXT) $(SHLPRE)octave.$(SHLEXT_VER)
+  else
+    LIBRARIES = $(SHLPRE)octave.$(SHLEXT_VER)
+  endif
+else
+  ifeq ($(STATIC_LIBS), true)
+    LIBRARIES = $(LIBPRE)octave.$(LIBEXT)
+  else
+    LIBRARIES =
+  endif
+endif
+
+libraries: $(LIBRARIES)
+.PHONY: libraries
+
+$(LIBPRE)octave.$(LIBEXT): $(LIBOCTAVE_OBJECTS)
+	rm -f $@
+	$(TEMPLATE_AR) $(TEMPLATE_ARFLAGS) $@ $(LIBOCTAVE_OBJECTS)
+	$(RANLIB) $@
+
+$(SHLPRE)octave.$(SHLEXT_VER): $(SHLPRE)octave.$(SHLEXT)
+	rm -f $@
+	$(LN_S) $< $@
+
+$(SHLPRE)octave.$(SHLEXT): $(LIBOCTAVE_PICOBJ)
+	rm -f $@
+	$(SH_LD) $(SH_LDFLAGS) $(SONAME_FLAGS) -o $@ \
+	$(LIBOCTAVE_PICOBJ) $(LINK_DEPS)
+
+$(LIBOCTAVE_PICOBJ): stmp-pic
+
+ifndef omit_deps
+$(MAKEDEPS): $(PREREQ)
+endif
+
+check: all
+.PHONY: check
+
+install: install-lib install-inc
+.PHONY: install
+
+install-strip:
+	$(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM) -s" install
+.PHONY: install-strip
+
+install-lib:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octlibdir)
+	if $(STATIC_LIBS); then \
+	  rm -f $(DESTDIR)$(octlibdir)/$(LIBPRE)octave.$(LIBEXT); \
+	  $(INSTALL_DATA) $(LIBPRE)octave.$(LIBEXT) \
+	    $(DESTDIR)$(octlibdir)/$(LIBPRE)octave.$(LIBEXT); \
+	  $(RANLIB) $(DESTDIR)$(octlibdir)/$(LIBPRE)octave.$(LIBEXT); \
+	fi
+	if $(SHARED_LIBS); then \
+	  rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octave.$(SHLLIB_VER); \
+	  $(INSTALL) \
+	    $(SHLLIBPRE)octave.$(SHLLIB) $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octave.$(SHLLIB_VER); \
+	  rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octave.$(SHLLIB); \
+	  (cd $(DESTDIR)$(octlibdir) ; $(LN_S) $(SHLLIBPRE)octave.$(SHLLIB_VER) $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octave.$(SHLLIB)); \
+	  if  test x$(SHLBIN) != x ; then \
+	    rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)octave.$(SHLBIN); \
+	    $(INSTALL_PROGRAM) \
+	      $(SHLBINPRE)octave.$(SHLBIN) $(DESTDIR)$(bindir)/$(SHLBINPRE)octave.$(SHLBIN); \
+	  fi; \
+	fi
+.PHONY: install-lib
+
+install-inc:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octincludedir)/octave
+	for f in $(INCLUDES_FOR_INSTALL); do \
+	  rm -f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  if [ -f $$f ]; then \
+	    $(INSTALL_DATA) $$f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  else \
+	    $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  fi ; \
+	done
+.PHONY: install-inc
+
+uninstall:
+	rm -f $(DESTDIR)$(octlibdir)/$(LIBPRE)octave.$(LIBEXT)
+	rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octave.$(SHLLIB)
+	rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octave.$(SHLLIB_VER)
+	if test x$(SHLBIN) != x; then \
+	  rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)octave.$(SHLBIN); \
+	  rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)octave.$(SHLBIN_VER); \
+	fi
+	for f in $(INCLUDES_FOR_INSTALL); do rm -f $(DESTDIR)$(octincludedir)/octave/$$f; done
+.PHONY: uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+clean:
+	rm -f $(LIBPRE)octave.$(LIBEXT)
+	rm -f $(SHLPRE)octave.$(SHLEXT_VER) $(SHLPRE)octave.$(SHLEXT)
+	rm -f $(SHLBINPRE)octave.$(SHLBIN_VER) $(SHLBINPRE)octave.$(SHLBIN)
+	rm -f $(LIBOCTAVE_OBJECTS) $(MAKEDEPS) $(LIBOCTAVE_PICOBJ) stmp-pic
+	-rmdir pic
+.PHONY: clean
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean maintainer-clean: clean
+	rm -f tags TAGS
+	rm -f Makefile so_locations oct-types.h $(PREREQ)
+.PHONY: distclean maintainer-clean
+
+dist: $(PREREQ)
+	ln $(DISTFILES) ../`cat ../.fname`/liboctave
+.PHONY: dist
+
+$(OPT_INC) : %.h : %.in $(top_srcdir)/mk-opts.pl
+	@echo making $@ from $<
+	@perl $(top_srcdir)/mk-opts.pl --opt-class-header $< > $@-t
+	@mv $@-t $@
+
+$(VX_OP_INC) $(VX_OP_SRC) : $(srcdir)/mk-ops.awk vx-ops
+	$(AWK) -f $(srcdir)/mk-ops.awk prefix=vx $(srcdir)/vx-ops
+
+$(MX_OP_INC) $(MX_OP_SRC) : $(srcdir)/mk-ops.awk mx-ops
+	$(AWK) -f $(srcdir)/mk-ops.awk prefix=mx $(srcdir)/mx-ops
+
+$(SPARSE_MX_OP_INC) $(SPARSE_MX_OP_SRC) : $(srcdir)/sparse-mk-ops.awk sparse-mx-ops
+	$(AWK) -f $(srcdir)/sparse-mk-ops.awk prefix=smx $(srcdir)/sparse-mx-ops
+
+mx-ops.h : $(srcdir)/mk-ops.awk mx-ops
+	$(AWK) -f $(srcdir)/mk-ops.awk prefix=mx make_inclusive_header=mx-ops.h $(srcdir)/mx-ops > $@-t
+	$(simple-move-if-change-rule)
+
+ifdef omit_deps
+.PHONY: $(MAKEDEPS)
+endif
+
+-include $(MAKEDEPS)
diff --git a/liboctave/Matrix.h b/liboctave/Matrix.h
new file mode 100644
index 0000000..ed077b9
--- /dev/null
+++ b/liboctave/Matrix.h
@@ -0,0 +1,43 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2002, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Should probably say something here about why these classes are not
+// represented by some sort of inheritance tree...
+
+#if !defined (octave_Matrix_h)
+#define octave_Matrix_h 1
+
+#include "mx-base.h"
+
+#include "mx-ext.h"
+
+#include "mx-ops.h"
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/MatrixType.cc b/liboctave/MatrixType.cc
new file mode 100644
index 0000000..ec3e392
--- /dev/null
+++ b/liboctave/MatrixType.cc
@@ -0,0 +1,1278 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 David Bateman
+Copyright (C) 2006 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "MatrixType.h"
+#include "dMatrix.h"
+#include "CMatrix.h"
+#include "dSparse.h"
+#include "CSparse.h"
+#include "oct-spparms.h"
+#include "oct-locbuf.h"
+
+// FIXME There is a large code duplication here
+
+MatrixType::MatrixType (void)
+  : typ (MatrixType::Unknown), 
+    sp_bandden (octave_sparse_params::get_bandden()),
+    bandden (0), upper_band (0), 
+    lower_band (0), dense (false), full (false), nperm (0), perm (0) { }
+
+MatrixType::MatrixType (const MatrixType &a)
+  : typ (a.typ), sp_bandden (a.sp_bandden), bandden (a.bandden), 
+    upper_band (a.upper_band), lower_band (a.lower_band), 
+    dense (a.dense), full (a.full), nperm (a.nperm)
+{ 
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = a.perm[i];
+    }
+}
+
+template<class T> 
+MatrixType::matrix_type 
+matrix_real_probe (const MArray2<T>& a)
+{
+  MatrixType::matrix_type typ;
+  octave_idx_type nrows = a.rows ();
+  octave_idx_type ncols = a.cols ();
+
+  const T zero = 0;
+ 
+  if (ncols == nrows)
+    {
+      bool upper = true;
+      bool lower = true;
+      bool hermitian = true;
+
+      // do the checks for lower/upper/hermitian all in one pass.
+      ColumnVector diag(ncols);
+
+      for (octave_idx_type j = 0; 
+           j < ncols && upper; j++)
+	{
+          T d = a.elem (j,j);
+          upper = upper && (d != zero);
+          lower = lower && (d != zero);
+          hermitian = hermitian && (d > zero);
+          diag(j) = d;
+        }
+
+      for (octave_idx_type j = 0; 
+           j < ncols && (upper || lower || hermitian); j++)
+	{
+          for (octave_idx_type i = 0; i < j; i++)
+            {
+              double aij = a.elem (i,j), aji = a.elem (j,i);
+              lower = lower && (aij == zero);
+              upper = upper && (aji == zero);
+              hermitian = hermitian && (aij == aji 
+                                        && aij*aij < diag(i)*diag(j));
+            }
+	}
+
+      if (upper)
+	typ = MatrixType::Upper;
+      else if (lower)
+	typ = MatrixType::Lower;
+      else if (hermitian)
+	typ = MatrixType::Hermitian;
+      else 
+	typ = MatrixType::Full;
+    }
+  else
+    typ = MatrixType::Rectangular;
+
+  return typ;
+}
+
+template<class T> 
+MatrixType::matrix_type 
+matrix_complex_probe (const MArray2<T>& a)
+{
+  MatrixType::matrix_type typ;
+  octave_idx_type nrows = a.rows ();
+  octave_idx_type ncols = a.cols ();
+
+  const typename T::value_type zero = 0;
+
+  if (ncols == nrows)
+    {
+      bool upper = true;
+      bool lower = true;
+      bool hermitian = true;
+
+      // do the checks for lower/upper/hermitian all in one pass.
+      ColumnVector diag(ncols);
+
+      for (octave_idx_type j = 0; 
+           j < ncols && upper; j++)
+	{
+          T d = a.elem (j,j);
+          upper = upper && (d != zero);
+          lower = lower && (d != zero);
+          hermitian = hermitian && (d.real() > zero && d.imag() == zero);
+          diag (j) = d.real();
+        }
+
+      for (octave_idx_type j = 0; 
+           j < ncols && (upper || lower || hermitian); j++)
+	{
+          for (octave_idx_type i = 0; i < j; i++)
+            {
+              T aij = a.elem (i,j), aji = a.elem (j,i);
+              lower = lower && (aij == zero);
+              upper = upper && (aji == zero);
+              hermitian = hermitian && (aij == std::conj (aji)
+                                        && std::norm (aij) < diag(i)*diag(j));
+            }
+	}
+
+
+      if (upper)
+	typ = MatrixType::Upper;
+      else if (lower)
+	typ = MatrixType::Lower;
+      else if (hermitian)
+	typ = MatrixType::Hermitian;
+      else if (ncols == nrows)
+	typ = MatrixType::Full;
+    }
+  else
+    typ = MatrixType::Rectangular;
+
+  return typ;
+}
+
+MatrixType::MatrixType (const Matrix &a)
+  : typ (MatrixType::Unknown),
+    sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (true), nperm (0), perm (0)
+{
+  typ = matrix_real_probe (a);
+}
+
+MatrixType::MatrixType (const ComplexMatrix &a)
+  : typ (MatrixType::Unknown),
+    sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (true), nperm (0), perm (0)
+{
+  typ = matrix_complex_probe (a);
+}
+
+
+MatrixType::MatrixType (const FloatMatrix &a)
+  : typ (MatrixType::Unknown),
+    sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (true), nperm (0), perm (0)
+{
+  typ = matrix_real_probe (a);
+}
+
+MatrixType::MatrixType (const FloatComplexMatrix &a)
+  : typ (MatrixType::Unknown),
+    sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (true), nperm (0), perm (0)
+{
+  typ = matrix_complex_probe (a);
+}
+
+MatrixType::MatrixType (const SparseMatrix &a)
+  : typ (MatrixType::Unknown),
+    sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (false), nperm (0), perm (0)
+{
+  octave_idx_type nrows = a.rows ();
+  octave_idx_type ncols = a.cols ();
+  octave_idx_type nm = (ncols < nrows ? ncols : nrows);
+  octave_idx_type nnz = a.nzmax ();
+
+  if (octave_sparse_params::get_key ("spumoni") != 0.)
+    (*current_liboctave_warning_handler) 
+      ("Calculating Sparse Matrix Type");
+
+  sp_bandden = octave_sparse_params::get_bandden();
+  bool maybe_hermitian = false;
+  typ = MatrixType::Full;
+
+  if (nnz == nm)
+    {
+      matrix_type tmp_typ = MatrixType::Diagonal;
+      octave_idx_type i;
+      // Maybe the matrix is diagonal
+      for (i = 0; i < nm; i++)
+	{
+	  if (a.cidx(i+1) != a.cidx(i) + 1)
+	    {
+	      tmp_typ = MatrixType::Full;
+	      break;
+	    }
+	  if (a.ridx(i) != i)
+	    {
+	      tmp_typ = MatrixType::Permuted_Diagonal;
+	      break;
+	    }
+	}
+	  
+      if (tmp_typ == MatrixType::Permuted_Diagonal)
+	{
+	  std::vector<bool> found (nrows);
+
+	  for (octave_idx_type j = 0; j < i; j++)
+	    found [j] = true;
+	  for (octave_idx_type j = i; j < nrows; j++)
+	    found [j] = false;
+	      
+	  for (octave_idx_type j = i; j < nm; j++)
+	    {
+	      if ((a.cidx(j+1) > a.cidx(j) + 1)  || 
+		  ((a.cidx(j+1) == a.cidx(j) + 1) && found [a.ridx(j)]))
+		{
+		  tmp_typ = MatrixType::Full;
+		  break;
+		}
+	      found [a.ridx(j)] = true;
+	    }
+	}
+      typ = tmp_typ;
+    }
+
+  if (typ == MatrixType::Full)
+    {
+      // Search for banded, upper and lower triangular matrices
+      bool singular = false;
+      upper_band = 0;
+      lower_band = 0;
+      for (octave_idx_type j = 0; j < ncols; j++)
+	{
+	  bool zero_on_diagonal = false;
+	  if (j < nrows)
+	    {
+	      zero_on_diagonal = true;
+	      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+		if (a.ridx(i) == j)
+		  {
+		    zero_on_diagonal = false;
+		    break;
+		  }
+	    }
+
+	  if (zero_on_diagonal)
+	    {
+	      singular = true;
+	      break;
+	    }
+
+	  if (a.cidx(j+1) != a.cidx(j))
+	    {
+	      octave_idx_type ru = a.ridx(a.cidx(j));
+	      octave_idx_type rl = a.ridx(a.cidx(j+1)-1);
+
+	      if (j - ru > upper_band)
+		upper_band = j - ru;
+		  
+	      if (rl - j > lower_band)
+		lower_band = rl - j;
+	    }
+	}
+
+      if (!singular)
+	{
+	  bandden = double (nnz) /
+	    (double (ncols) * (double (lower_band) +
+			       double (upper_band)) -
+	     0.5 * double (upper_band + 1) * double (upper_band) -
+	     0.5 * double (lower_band + 1) * double (lower_band));
+
+	  if (nrows == ncols && sp_bandden != 1. && bandden > sp_bandden)
+	    {
+	      if (upper_band == 1 && lower_band == 1)
+		typ = MatrixType::Tridiagonal;
+	      else
+		typ = MatrixType::Banded;
+
+	      octave_idx_type nnz_in_band = 
+		(upper_band + lower_band + 1) * nrows -
+		(1 + upper_band) * upper_band / 2 -
+		(1 + lower_band) * lower_band / 2;
+	      if (nnz_in_band == nnz)
+		dense = true;
+	      else 
+		dense = false;
+	    }
+	  else if (upper_band == 0)
+	    typ = MatrixType::Lower;
+	  else if (lower_band == 0)
+	    typ = MatrixType::Upper;
+
+	  if (upper_band == lower_band && nrows == ncols)
+	    maybe_hermitian = true;
+	}
+
+      if (typ == MatrixType::Full)
+	{
+	  // Search for a permuted triangular matrix, and test if
+	  // permutation is singular
+
+	  // FIXME
+	  // Perhaps this should be based on a dmperm algorithm
+	  bool found = false;
+
+	  nperm = ncols;
+	  perm = new octave_idx_type [ncols];
+
+	  for (octave_idx_type i = 0; i < ncols; i++)
+	    perm [i] = -1;
+
+	  for (octave_idx_type i = 0; i < nm; i++)
+	    {
+	      found = false;
+
+	      for (octave_idx_type j = 0; j < ncols; j++)
+		{
+		  if ((a.cidx(j+1) - a.cidx(j)) > 0 && 
+		      (a.ridx(a.cidx(j+1)-1) == i))
+		    {
+		      perm [i] = j;
+		      found = true;
+		      break;
+		    }
+		}
+
+	      if (!found)
+		break;
+	    }
+
+	  if (found)
+	    {
+	      typ = MatrixType::Permuted_Upper;
+	      if (ncols > nrows)
+		{
+		  octave_idx_type k = nrows;
+		  for (octave_idx_type i = 0; i < ncols; i++)
+		    if (perm [i] == -1)
+		      perm[i] = k++;
+		}
+	    }
+	  else if (a.cidx(nm) == a.cidx(ncols))
+	    {
+	      nperm = nrows;
+	      delete [] perm;
+	      perm = new octave_idx_type [nrows];
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, tmp, nrows);
+
+	      for (octave_idx_type i = 0; i < nrows; i++)
+		{
+		  perm [i] = -1;
+		  tmp [i] = -1;
+		}
+
+	      for (octave_idx_type j = 0; j < ncols; j++)
+		for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+		    perm [a.ridx(i)] = j;
+
+	      found = true;
+	      for (octave_idx_type i = 0; i < nm; i++)
+		if (perm[i] == -1)
+		  {
+		    found = false;
+		    break;
+		  }
+		else
+		  {
+		    tmp[perm[i]] = 1;
+		  }
+
+	      if (found)
+		{
+		  octave_idx_type k = ncols;
+		  for (octave_idx_type i = 0; i < nrows; i++)
+		    {
+		      if (tmp[i] == -1)
+			{
+			  if (k < nrows)
+			    {
+			      perm[k++] = i;
+			    }
+			  else
+			    {
+			      found = false;
+			      break;
+			    }
+			}
+		    }
+		}
+
+	      if (found)
+		typ = MatrixType::Permuted_Lower;
+	      else
+		{
+		  delete [] perm;
+		  nperm = 0;
+		}
+	    }
+	  else
+	    {
+	      delete [] perm;
+	      nperm = 0;
+	    }
+	}
+
+      // FIXME
+      // Disable lower under-determined and upper over-determined problems
+      // as being detected, and force to treat as singular. As this seems
+      // to cause issues
+      if (((typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+	   && nrows > ncols) ||
+	  ((typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+	   && nrows < ncols))
+	{
+	  typ = MatrixType::Rectangular;
+	  if (typ == MatrixType::Permuted_Upper ||
+	      typ == MatrixType::Permuted_Lower)
+	    delete [] perm;
+	  nperm = 0;
+	}
+
+      if (typ == MatrixType::Full && ncols != nrows)
+	typ = MatrixType::Rectangular;
+
+      if (maybe_hermitian && (typ == MatrixType::Full || 
+			      typ == MatrixType::Tridiagonal || 
+			      typ == MatrixType::Banded))
+	{
+	  bool is_herm = true;
+
+          // first, check whether the diagonal is positive & extract it
+          ColumnVector diag (ncols);
+
+	  for (octave_idx_type j = 0; is_herm && j < ncols; j++)
+            {
+              is_herm = false;
+              for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+                {
+                  if (a.ridx(i) == j)
+                    {
+                      double d = a.data(i);
+                      is_herm = d > 0.;
+                      diag(j) = d;
+                      break;
+                    }
+                }
+            }
+
+
+          // next, check symmetry and 2x2 positiveness
+
+          for (octave_idx_type j = 0; is_herm && j < ncols; j++)
+            for (octave_idx_type i = a.cidx(j); is_herm && i < a.cidx(j+1); i++)
+              {
+                octave_idx_type k = a.ridx(i);
+                is_herm = k == j;
+                if (is_herm) 
+                  continue;
+                double d = a.data(i);
+                if (d*d < diag(j)*diag(k))
+                  {
+                    for (octave_idx_type l = a.cidx(k); l < a.cidx(k+1); l++)
+                      {
+                        if (a.ridx(l) == j)
+                          {
+                            is_herm = a.data(l) == d;
+                            break;
+                          }
+                      }
+                  }
+              }
+
+	  if (is_herm)
+	    {
+	      if (typ == MatrixType::Full)
+		typ = MatrixType::Hermitian;
+	      else if (typ == MatrixType::Banded)
+		typ = MatrixType::Banded_Hermitian;
+	      else
+		typ = MatrixType::Tridiagonal_Hermitian;
+	    }
+	}
+    }
+}
+
+MatrixType::MatrixType (const SparseComplexMatrix &a)
+  : typ (MatrixType::Unknown),
+    sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (false), nperm (0), perm (0)
+{
+  octave_idx_type nrows = a.rows ();
+  octave_idx_type ncols = a.cols ();
+  octave_idx_type nm = (ncols < nrows ? ncols : nrows);
+  octave_idx_type nnz = a.nzmax ();
+
+  if (octave_sparse_params::get_key ("spumoni") != 0.)
+    (*current_liboctave_warning_handler) 
+      ("Calculating Sparse Matrix Type");
+
+  sp_bandden = octave_sparse_params::get_bandden();
+  bool maybe_hermitian = false;
+  typ = MatrixType::Full;
+
+  if (nnz == nm)
+    {
+      matrix_type tmp_typ = MatrixType::Diagonal;
+      octave_idx_type i;
+      // Maybe the matrix is diagonal
+      for (i = 0; i < nm; i++)
+	{
+	  if (a.cidx(i+1) != a.cidx(i) + 1)
+	    {
+	      tmp_typ = MatrixType::Full;
+	      break;
+	    }
+	  if (a.ridx(i) != i)
+	    {
+	      tmp_typ = MatrixType::Permuted_Diagonal;
+	      break;
+	    }
+	}
+	  
+      if (tmp_typ == MatrixType::Permuted_Diagonal)
+	{
+	  std::vector<bool> found (nrows);
+
+	  for (octave_idx_type j = 0; j < i; j++)
+	    found [j] = true;
+	  for (octave_idx_type j = i; j < nrows; j++)
+	    found [j] = false;
+	      
+	  for (octave_idx_type j = i; j < nm; j++)
+	    {
+	      if ((a.cidx(j+1) > a.cidx(j) + 1)  || 
+		  ((a.cidx(j+1) == a.cidx(j) + 1) && found [a.ridx(j)]))
+		{
+		  tmp_typ = MatrixType::Full;
+		  break;
+		}
+	      found [a.ridx(j)] = true;
+	    }
+	}
+      typ = tmp_typ;
+    }
+
+  if (typ == MatrixType::Full)
+    {
+      // Search for banded, upper and lower triangular matrices
+      bool singular = false;
+      upper_band = 0;
+      lower_band = 0;
+      for (octave_idx_type j = 0; j < ncols; j++)
+	{
+	  bool zero_on_diagonal = false;
+	  if (j < nrows)
+	    {
+	      zero_on_diagonal = true;
+	      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+		if (a.ridx(i) == j)
+		  {
+		    zero_on_diagonal = false;
+		    break;
+		  }
+	    }
+
+	  if (zero_on_diagonal)
+	    {
+	      singular = true;
+	      break;
+	    }
+
+	  if (a.cidx(j+1) != a.cidx(j))
+	    {
+	      octave_idx_type ru = a.ridx(a.cidx(j));
+	      octave_idx_type rl = a.ridx(a.cidx(j+1)-1);
+
+	      if (j - ru > upper_band)
+		upper_band = j - ru;
+		  
+	      if (rl - j > lower_band)
+		lower_band = rl - j;
+	    }
+	}
+
+      if (!singular)
+	{
+	  bandden = double (nnz) /
+	    (double (ncols) * (double (lower_band) +
+			       double (upper_band)) -
+	     0.5 * double (upper_band + 1) * double (upper_band) -
+	     0.5 * double (lower_band + 1) * double (lower_band));
+
+	  if (nrows == ncols && sp_bandden != 1. && bandden > sp_bandden)
+	    {
+	      if (upper_band == 1 && lower_band == 1)
+		typ = MatrixType::Tridiagonal;
+	      else
+		typ = MatrixType::Banded;
+
+	      octave_idx_type nnz_in_band = 
+		(upper_band + lower_band + 1) * nrows -
+		(1 + upper_band) * upper_band / 2 -
+		(1 + lower_band) * lower_band / 2;
+	      if (nnz_in_band == nnz)
+		dense = true;
+	      else 
+		dense = false;
+	    }
+	  else if (upper_band == 0)
+	    typ = MatrixType::Lower;
+	  else if (lower_band == 0)
+	    typ = MatrixType::Upper;
+
+	  if (upper_band == lower_band && nrows == ncols)
+	    maybe_hermitian = true;
+	}
+
+      if (typ == MatrixType::Full)
+	{
+	  // Search for a permuted triangular matrix, and test if
+	  // permutation is singular
+
+	  // FIXME
+	  // Perhaps this should be based on a dmperm algorithm
+	  bool found = false;
+
+	  nperm = ncols;
+	  perm = new octave_idx_type [ncols];
+
+	  for (octave_idx_type i = 0; i < ncols; i++)
+	    perm [i] = -1;
+
+	  for (octave_idx_type i = 0; i < nm; i++)
+	    {
+	      found = false;
+
+	      for (octave_idx_type j = 0; j < ncols; j++)
+		{
+		  if ((a.cidx(j+1) - a.cidx(j)) > 0 && 
+		      (a.ridx(a.cidx(j+1)-1) == i))
+		    {
+		      perm [i] = j;
+		      found = true;
+		      break;
+		    }
+		}
+
+	      if (!found)
+		break;
+	    }
+
+	  if (found)
+	    {
+	      typ = MatrixType::Permuted_Upper;
+	      if (ncols > nrows)
+		{
+		  octave_idx_type k = nrows;
+		  for (octave_idx_type i = 0; i < ncols; i++)
+		    if (perm [i] == -1)
+		      perm[i] = k++;
+		}
+	    }
+	  else if (a.cidx(nm) == a.cidx(ncols))
+	    {
+	      nperm = nrows;
+	      delete [] perm;
+	      perm = new octave_idx_type [nrows];
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, tmp, nrows);
+
+	      for (octave_idx_type i = 0; i < nrows; i++)
+		{
+		  perm [i] = -1;
+		  tmp [i] = -1;
+		}
+
+	      for (octave_idx_type j = 0; j < ncols; j++)
+		for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+		    perm [a.ridx(i)] = j;
+
+	      found = true;
+	      for (octave_idx_type i = 0; i < nm; i++)
+		if (perm[i] == -1)
+		  {
+		    found = false;
+		    break;
+		  }
+		else
+		  {
+		    tmp[perm[i]] = 1;
+		  }
+
+	      if (found)
+		{
+		  octave_idx_type k = ncols;
+		  for (octave_idx_type i = 0; i < nrows; i++)
+		    {
+		      if (tmp[i] == -1)
+			{
+			  if (k < nrows)
+			    {
+			      perm[k++] = i;
+			    }
+			  else
+			    {
+			      found = false;
+			      break;
+			    }
+			}
+		    }
+		}
+
+	      if (found)
+		typ = MatrixType::Permuted_Lower;
+	      else
+		{
+		  delete [] perm;
+		  nperm = 0;
+		}
+	    }
+	  else
+	    {
+	      delete [] perm;
+	      nperm = 0;
+	    }
+	}
+
+      // FIXME
+      // Disable lower under-determined and upper over-determined problems
+      // as being detected, and force to treat as singular. As this seems
+      // to cause issues
+      if (((typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+	   && nrows > ncols) ||
+	  ((typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+	   && nrows < ncols))
+	{
+	  typ = MatrixType::Rectangular;
+	  if (typ == MatrixType::Permuted_Upper ||
+	      typ == MatrixType::Permuted_Lower)
+	    delete [] perm;
+	  nperm = 0;
+	}
+
+      if (typ == MatrixType::Full && ncols != nrows)
+	typ = MatrixType::Rectangular;
+
+      if (maybe_hermitian && (typ == MatrixType::Full || 
+			      typ == MatrixType::Tridiagonal || 
+			      typ == MatrixType::Banded))
+	{
+	  bool is_herm = true;
+
+          // first, check whether the diagonal is positive & extract it
+          ColumnVector diag (ncols);
+
+	  for (octave_idx_type j = 0; is_herm && j < ncols; j++)
+            {
+              is_herm = false;
+              for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+                {
+                  if (a.ridx(i) == j)
+                    {
+                      Complex d = a.data(i);
+                      is_herm = d.real() > 0. && d.imag() == 0.;
+                      diag(j) = d.real();
+                      break;
+                    }
+                }
+            }
+
+          // next, check symmetry and 2x2 positiveness
+
+          for (octave_idx_type j = 0; is_herm && j < ncols; j++)
+            for (octave_idx_type i = a.cidx(j); is_herm && i < a.cidx(j+1); i++)
+              {
+                octave_idx_type k = a.ridx(i);
+                is_herm = k == j;
+                if (is_herm) 
+                  continue;
+                Complex d = a.data(i);
+                if (std::norm (d) < diag(j)*diag(k))
+                  {
+                    d = std::conj (d);
+                    for (octave_idx_type l = a.cidx(k); l < a.cidx(k+1); l++)
+                      {
+                        if (a.ridx(l) == j)
+                          {
+                            is_herm = a.data(l) == d;
+                            break;
+                          }
+                      }
+                  }
+              }
+
+
+	  if (is_herm)
+	    {
+	      if (typ == MatrixType::Full)
+		typ = MatrixType::Hermitian;
+	      else if (typ == MatrixType::Banded)
+		typ = MatrixType::Banded_Hermitian;
+	      else
+		typ = MatrixType::Tridiagonal_Hermitian;
+	    }
+	}
+    }
+}
+MatrixType::MatrixType (const matrix_type t, bool _full)
+  : typ (MatrixType::Unknown),
+    sp_bandden (octave_sparse_params::get_bandden()),
+    bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (_full), nperm (0), perm (0)
+{
+  if (t == MatrixType::Unknown || t == MatrixType::Full 
+      || t == MatrixType::Diagonal || t == MatrixType::Permuted_Diagonal 
+      || t == MatrixType::Upper || t == MatrixType::Lower 
+      || t == MatrixType::Tridiagonal || t == MatrixType::Tridiagonal_Hermitian
+      || t == MatrixType::Rectangular)
+    typ = t;
+  else
+    (*current_liboctave_warning_handler) ("Invalid matrix type");
+}
+
+MatrixType::MatrixType (const matrix_type t, const octave_idx_type np,
+			const octave_idx_type *p, bool _full)
+  : typ (MatrixType::Unknown),
+    sp_bandden (octave_sparse_params::get_bandden()),
+    bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (_full), nperm (0), perm (0)
+{
+  if ((t == MatrixType::Permuted_Upper || t == MatrixType::Permuted_Lower) &&
+      np > 0 && p != 0)
+    {
+      typ = t;
+      nperm = np;
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = p[i];
+    }
+  else
+    (*current_liboctave_warning_handler) ("Invalid matrix type");
+}
+
+MatrixType::MatrixType (const matrix_type t, const octave_idx_type ku,
+			const octave_idx_type kl, bool _full)
+  : typ (MatrixType::Unknown),
+    sp_bandden (octave_sparse_params::get_bandden()),
+    bandden (0), upper_band (0), lower_band (0),
+    dense (false), full (_full), nperm (0), perm (0)
+{
+  if (t == MatrixType::Banded || t == MatrixType::Banded_Hermitian)
+    {
+      typ = t;
+      upper_band = ku;
+      lower_band = kl;
+    }
+  else
+    (*current_liboctave_warning_handler) ("Invalid sparse matrix type"); 
+}
+
+MatrixType::~MatrixType (void) 
+{ 
+  if (nperm != 0)
+    {
+      delete [] perm; 
+    }
+}
+
+MatrixType& 
+MatrixType::operator = (const MatrixType& a)
+{
+  if (this != &a)
+    {
+      typ = a.typ;
+      sp_bandden = a.sp_bandden;
+      bandden = a.bandden;
+      upper_band = a.upper_band;
+      lower_band = a.lower_band;
+      dense = a.dense;
+      full = a.full;
+      nperm = a.nperm;
+
+      if (nperm != 0)
+	{
+	  perm = new octave_idx_type [nperm];
+	  for (octave_idx_type i = 0; i < nperm; i++)
+	    perm[i] = a.perm[i];
+	}
+    }
+
+  return *this;
+}
+
+int
+MatrixType::type (bool quiet)
+{
+  if (typ != MatrixType::Unknown && (full ||
+      sp_bandden == octave_sparse_params::get_bandden()))
+    {
+      if (!quiet &&
+	  octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  if (typ != MatrixType::Unknown && 
+      octave_sparse_params::get_key ("spumoni") != 0.)
+    (*current_liboctave_warning_handler) 
+      ("Invalidating Matrix Type");
+
+  typ = MatrixType::Unknown;
+
+  return typ;
+}
+
+int
+MatrixType::type (const SparseMatrix &a)
+{
+  if (typ != MatrixType::Unknown && (full ||
+      sp_bandden == octave_sparse_params::get_bandden()))
+    {
+      if (octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  MatrixType tmp_typ (a);
+  typ = tmp_typ.typ;
+  sp_bandden = tmp_typ.sp_bandden;
+  bandden = tmp_typ.bandden;
+  upper_band = tmp_typ.upper_band;
+  lower_band = tmp_typ.lower_band;
+  dense = tmp_typ.dense;
+  full = tmp_typ.full;
+  nperm = tmp_typ.nperm;
+
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = tmp_typ.perm[i];
+    }
+
+  return typ;
+}
+
+int
+MatrixType::type (const SparseComplexMatrix &a)
+{
+  if (typ != MatrixType::Unknown && (full || 
+      sp_bandden == octave_sparse_params::get_bandden()))
+    {
+      if (octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  MatrixType tmp_typ (a);
+  typ = tmp_typ.typ;
+  sp_bandden = tmp_typ.sp_bandden;
+  bandden = tmp_typ.bandden;
+  upper_band = tmp_typ.upper_band;
+  lower_band = tmp_typ.lower_band;
+  dense = tmp_typ.dense;
+  full = tmp_typ.full;
+  nperm = tmp_typ.nperm;
+
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = tmp_typ.perm[i];
+    }
+
+  return typ;
+}
+
+int
+MatrixType::type (const Matrix &a)
+{
+  if (typ != MatrixType::Unknown)
+    {
+      if (octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  MatrixType tmp_typ (a);
+  typ = tmp_typ.typ;
+  full = tmp_typ.full;
+  nperm = tmp_typ.nperm;
+
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = tmp_typ.perm[i];
+    }
+
+  return typ;
+}
+
+int
+MatrixType::type (const ComplexMatrix &a)
+{
+  if (typ != MatrixType::Unknown)
+    {
+      if (octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  MatrixType tmp_typ (a);
+  typ = tmp_typ.typ;
+  full = tmp_typ.full; 
+  nperm = tmp_typ.nperm;
+
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = tmp_typ.perm[i];
+    }
+
+  return typ;
+}
+
+int
+MatrixType::type (const FloatMatrix &a)
+{
+  if (typ != MatrixType::Unknown)
+    {
+      if (octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  MatrixType tmp_typ (a);
+  typ = tmp_typ.typ;
+  full = tmp_typ.full;
+  nperm = tmp_typ.nperm;
+
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = tmp_typ.perm[i];
+    }
+
+  return typ;
+}
+
+int
+MatrixType::type (const FloatComplexMatrix &a)
+{
+  if (typ != MatrixType::Unknown)
+    {
+      if (octave_sparse_params::get_key ("spumoni") != 0.)
+  	(*current_liboctave_warning_handler) 
+  	  ("Using Cached Matrix Type");
+      
+      return typ;
+    }
+
+  MatrixType tmp_typ (a);
+  typ = tmp_typ.typ;
+  full = tmp_typ.full; 
+  nperm = tmp_typ.nperm;
+
+  if (nperm != 0)
+    {
+      perm = new octave_idx_type [nperm];
+      for (octave_idx_type i = 0; i < nperm; i++)
+	perm[i] = tmp_typ.perm[i];
+    }
+
+  return typ;
+}
+
+void
+MatrixType::info () const
+{
+  if (octave_sparse_params::get_key ("spumoni") != 0.)
+    {
+      if (typ == MatrixType::Unknown)
+	(*current_liboctave_warning_handler) 
+	  ("Unknown Matrix Type");
+      else if (typ == MatrixType::Diagonal)
+	(*current_liboctave_warning_handler) 
+	  ("Diagonal Sparse Matrix");
+      else if (typ == MatrixType::Permuted_Diagonal)
+	(*current_liboctave_warning_handler) 
+	  ("Permuted Diagonal Sparse Matrix");
+      else if (typ == MatrixType::Upper)
+	(*current_liboctave_warning_handler) 
+	  ("Upper Triangular Matrix");
+      else if (typ == MatrixType::Lower)
+	(*current_liboctave_warning_handler) 
+	  ("Lower Triangular Matrix");
+      else if (typ == MatrixType::Permuted_Upper)
+	(*current_liboctave_warning_handler) 
+	  ("Permuted Upper Triangular Matrix");
+      else if (typ == MatrixType::Permuted_Lower)
+	(*current_liboctave_warning_handler) 
+	  ("Permuted Lower Triangular Matrix");
+      else if (typ == MatrixType::Banded)
+	(*current_liboctave_warning_handler) 
+	  ("Banded Sparse Matrix %d-1-%d (Density %f)", lower_band, 
+	   upper_band, bandden);
+      else if (typ == MatrixType::Banded_Hermitian)
+	(*current_liboctave_warning_handler) 
+	  ("Banded Hermitian/Symmetric Sparse Matrix %d-1-%d (Density %f)", 
+	   lower_band, upper_band, bandden);
+      else if (typ == MatrixType::Hermitian)
+	(*current_liboctave_warning_handler) 
+	  ("Hermitian/Symmetric Matrix");
+      else if (typ == MatrixType::Tridiagonal)
+	(*current_liboctave_warning_handler) 
+	  ("Tridiagonal Sparse Matrix");
+      else if (typ == MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_warning_handler) 
+	  ("Hermitian/Symmetric Tridiagonal Sparse Matrix");
+      else if (typ == MatrixType::Rectangular)
+	(*current_liboctave_warning_handler) 
+	  ("Rectangular/Singular Matrix");
+      else if (typ == MatrixType::Full)
+	(*current_liboctave_warning_handler) 
+	  ("Full Matrix");
+    }
+}
+
+void
+MatrixType::mark_as_symmetric (void)
+{
+  if (typ == MatrixType::Tridiagonal || 
+      typ == MatrixType::Tridiagonal_Hermitian)
+    typ = MatrixType::Tridiagonal_Hermitian;
+  else if (typ == MatrixType::Banded ||
+	   typ == MatrixType::Banded_Hermitian)
+    typ = MatrixType::Banded_Hermitian;
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian || 
+	   typ == MatrixType::Unknown)
+    typ = MatrixType::Hermitian;
+  else
+    (*current_liboctave_error_handler) 
+      ("Can not mark current matrix type as symmetric");
+}
+
+void
+MatrixType::mark_as_unsymmetric (void)
+{
+  if (typ == MatrixType::Tridiagonal || 
+      typ == MatrixType::Tridiagonal_Hermitian)
+    typ = MatrixType::Tridiagonal;
+  else if (typ == MatrixType::Banded ||
+	   typ == MatrixType::Banded_Hermitian)
+    typ = MatrixType::Banded;
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian || 
+	   typ == MatrixType::Unknown)
+    typ = MatrixType::Full;
+}
+
+void
+MatrixType::mark_as_permuted (const octave_idx_type np, const octave_idx_type *p)
+{
+  nperm = np;
+  perm = new octave_idx_type [nperm];
+  for (octave_idx_type i = 0; i < nperm; i++)
+    perm[i] = p[i];
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    typ = MatrixType::Permuted_Diagonal;
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    typ = MatrixType::Permuted_Upper;
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    typ = MatrixType::Permuted_Lower;
+  else
+    (*current_liboctave_error_handler) 
+      ("Can not mark current matrix type as symmetric");
+}
+
+void
+MatrixType::mark_as_unpermuted (void)
+{
+  if (nperm)
+    {
+      nperm = 0;
+      delete [] perm;
+    }
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    typ = MatrixType::Diagonal;
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    typ = MatrixType::Upper;
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    typ = MatrixType::Lower;
+}
+
+MatrixType
+MatrixType::transpose (void) const
+{
+  MatrixType retval (*this);
+  if (typ == MatrixType::Upper)
+    retval.typ = MatrixType::Lower;
+  else if (typ == MatrixType::Permuted_Upper)
+    retval.typ = MatrixType::Permuted_Lower;
+  else if (typ == MatrixType::Lower)
+    retval.typ = MatrixType::Upper;
+  else if (typ == MatrixType::Permuted_Lower)
+    retval.typ = MatrixType::Permuted_Upper;
+  else if (typ == MatrixType::Banded)
+    {
+      retval.upper_band = lower_band;
+      retval.lower_band = upper_band;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/MatrixType.h b/liboctave/MatrixType.h
new file mode 100644
index 0000000..4c4f7dd
--- /dev/null
+++ b/liboctave/MatrixType.h
@@ -0,0 +1,190 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 David Bateman
+Copyright (C) 2006 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_MatrixType_h)
+#define octave_MatrixType_h
+
+#include "oct-types.h"
+
+class Matrix;
+class ComplexMatrix;
+class FloatMatrix;
+class FloatComplexMatrix;
+class SparseMatrix;
+class SparseComplexMatrix;
+
+class
+OCTAVE_API
+MatrixType
+{
+public:
+  enum matrix_type {
+    Unknown = 0,
+    Full,
+    Diagonal,
+    Permuted_Diagonal,
+    Upper,
+    Lower,
+    Permuted_Upper,
+    Permuted_Lower,
+    Banded,
+    Hermitian,
+    Banded_Hermitian,
+    Tridiagonal,
+    Tridiagonal_Hermitian,
+    Rectangular
+  };
+
+  MatrixType (void);
+
+  MatrixType (const MatrixType &a);
+
+  MatrixType (const Matrix &a);
+
+  MatrixType (const ComplexMatrix &a);
+
+  MatrixType (const FloatMatrix &a);
+
+  MatrixType (const FloatComplexMatrix &a);
+
+  MatrixType (const SparseMatrix &a);
+
+  MatrixType (const SparseComplexMatrix &a);
+
+  MatrixType (const matrix_type t, bool _full = false);
+
+  MatrixType (const matrix_type t, const octave_idx_type np,
+	      const octave_idx_type *p, bool _full = false);
+
+  MatrixType (const matrix_type t, const octave_idx_type ku, 
+	      const octave_idx_type kl, bool _full = false);
+
+  ~MatrixType (void);
+
+  MatrixType& operator = (const MatrixType& a);
+
+  int type (bool quiet = true);
+
+  int type (const Matrix &a);
+
+  int type (const ComplexMatrix &a);
+
+  int type (const FloatMatrix &a);
+
+  int type (const FloatComplexMatrix &a);
+
+  int type (const SparseMatrix &a);
+
+  int type (const SparseComplexMatrix &a);
+
+  double band_density (void) const { return bandden; }
+
+  int nupper (void) const { return upper_band; }
+
+  int nlower (void) const { return lower_band; }
+
+  bool is_dense (void) const { return dense; }
+
+  bool is_diagonal (void) const 
+    { return (typ == Diagonal || typ == Permuted_Diagonal); }
+  
+  bool is_upper_triangular (void) const 
+    { return (typ == Upper || typ == Permuted_Upper); }
+
+  bool is_lower_triangular (void) const 
+    { return (typ == Lower || typ == Permuted_Lower); }
+
+   bool is_banded (void)
+    { return (typ == Banded || typ == Banded_Hermitian); }
+  
+  bool is_tridiagonal (void) const
+    { return (typ == Tridiagonal || typ == Tridiagonal_Hermitian); }
+  
+  bool is_hermitian (void) const
+    { return (typ == Banded_Hermitian || typ == Tridiagonal_Hermitian ||
+	      typ == Hermitian); }
+
+  bool is_rectangular (void) const { return (typ == Rectangular); }
+
+  bool is_known (void) const { return (typ != Unknown); }
+
+  bool is_unknown (void) const { return (typ == Unknown); }
+
+  void info (void) const;
+
+  octave_idx_type * triangular_perm (void) const { return perm; }
+
+  void invalidate_type (void) { typ = Unknown; }
+
+  void mark_as_diagonal (void) { typ = Diagonal; }
+
+  void mark_as_permuted_diagonal (void) { typ = Permuted_Diagonal; }
+
+  void mark_as_upper_triangular (void) { typ = Upper; }
+
+  void mark_as_lower_triangular (void) { typ = Lower; }
+
+  void mark_as_tridiagonal (void) {typ = Tridiagonal; }
+
+  void mark_as_banded (const octave_idx_type ku, const octave_idx_type kl)
+    { typ = Banded; upper_band = ku; lower_band = kl; }
+
+  void mark_as_full (void) { typ = Full; }
+
+  void mark_as_rectangular (void) { typ = Rectangular; }
+
+  void mark_as_dense (void) { dense = true; }
+
+  void mark_as_not_dense (void) { dense = false; }
+
+  void mark_as_symmetric (void);
+
+  void mark_as_unsymmetric (void);
+
+  void mark_as_permuted (const octave_idx_type np, const octave_idx_type *p);
+
+  void mark_as_unpermuted (void);
+
+  MatrixType transpose (void) const;
+
+private:
+  void type (int new_typ) { typ = static_cast<matrix_type>(new_typ); }
+
+  matrix_type typ;
+  double sp_bandden;
+  double bandden;
+  octave_idx_type upper_band;
+  octave_idx_type lower_band;
+  bool dense;
+  bool full;
+  octave_idx_type nperm;
+  octave_idx_type *perm;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ODE.h b/liboctave/ODE.h
new file mode 100644
index 0000000..7b6f5e9
--- /dev/null
+++ b/liboctave/ODE.h
@@ -0,0 +1,121 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2002, 2003, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ODE_h)
+#define octave_ODE_h 1
+
+#include "ODEFunc.h"
+#include "base-de.h"
+
+class
+ODE : public base_diff_eqn, public ODEFunc
+{
+public:
+
+  ODE (void)
+    : base_diff_eqn (), ODEFunc () { }
+
+  ODE (const ColumnVector& s, double tm, const ODEFunc& f)
+    : base_diff_eqn (s, tm), ODEFunc (f) { }
+
+  ODE (const ODE& a)
+    : base_diff_eqn (a), ODEFunc (a) { }
+
+  ODE& operator = (const ODE& a)
+    {
+      if (this != &a)
+	{
+	  base_diff_eqn::operator = (a);
+	  ODEFunc::operator = (a);
+	}
+      return *this;
+    }
+
+  ~ODE (void) { }
+
+  // Derived classes must provide functions to actually do the
+  // integration.
+
+  // Return the vector of states at output time t.
+  virtual ColumnVector do_integrate (double tt) = 0;
+
+  // Return a matrix of states at each output time specified by t.
+  // The rows of the result matrix should each correspond to a new
+  // output time.
+  virtual Matrix do_integrate (const ColumnVector& tt) = 0;
+
+  virtual Matrix do_integrate (const ColumnVector& tt,
+			       const ColumnVector& ttcrit) = 0;
+
+  // Lots of ways to call the single function and optionally set and
+  // get additional information.
+
+  // Integrate to t from current point.
+  virtual ColumnVector integrate (double tt)
+    { return do_integrate (tt); }
+
+  // Set new x0, t0 and integrate to t.
+  virtual ColumnVector integrate (const ColumnVector& x0, double t0, double tt)
+    {
+      initialize (x0, t0);
+      return do_integrate (tt);
+    }
+
+  // Integrate from current point and return output at all points
+  // specified by t.
+  virtual Matrix integrate (const ColumnVector& tt)
+    { return do_integrate (tt); }
+
+  // Set new x0, t0 and integrate to return output at all points
+  // specified by t.
+  virtual Matrix integrate (const ColumnVector& x0, double t0,
+			    const ColumnVector& tt)
+    {
+      initialize (x0, t0);
+      return do_integrate (tt);
+    }
+
+  // Integrate from current point and return output at all points
+  // specified by t.
+  virtual Matrix integrate (const ColumnVector& tt,
+			    const ColumnVector& ttcrit)
+    { return do_integrate (tt, ttcrit); }
+
+  // Set new x0, t0 and integrate to return output at all points
+  // specified by t.
+  virtual Matrix integrate (const ColumnVector& x0, double t0,
+			    const ColumnVector& tt,
+			    const ColumnVector& ttcrit)
+    {
+      initialize (x0, t0);
+      return do_integrate (tt, ttcrit);
+    }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ODEFunc.h b/liboctave/ODEFunc.h
new file mode 100644
index 0000000..dc13f0a
--- /dev/null
+++ b/liboctave/ODEFunc.h
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2002, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ODEFunc_h)
+#define octave_ODEFunc_h 1
+
+class Matrix;
+class ColumnVector;
+
+class
+ODEFunc
+{
+public:
+
+  typedef ColumnVector (*ODERHSFunc) (const ColumnVector&, double);
+  typedef Matrix (*ODEJacFunc) (const ColumnVector&, double);
+
+  ODEFunc (void)
+    : fun (0), jac (0), reset (true) { }
+
+  ODEFunc (ODERHSFunc f)
+    : fun (f), jac (0), reset (true) { }
+
+  ODEFunc (ODERHSFunc f, ODEJacFunc j)
+    : fun (f), jac (j), reset (true) { }
+
+  ODEFunc (const ODEFunc& a)
+    : fun (a.fun), jac (a.jac), reset (true) { }
+
+  ODEFunc& operator = (const ODEFunc& a)
+    {
+      if (this != &a)
+	{
+	  fun = a.fun;
+	  jac = a.jac;
+	  reset = a.reset;
+	}
+      return *this;
+    }
+
+  ~ODEFunc (void) { }
+
+  ODERHSFunc function (void) const { return fun; }
+
+  ODEFunc& set_function (ODERHSFunc f)
+    {
+      fun = f;
+      reset = true;
+      return *this;
+    }
+
+  ODEJacFunc jacobian_function (void) const { return jac; }
+
+  ODEFunc& set_jacobian_function (ODEJacFunc j)
+    {
+      jac = j;
+      reset = true;
+      return *this;
+    }
+
+protected:
+
+  ODERHSFunc fun;
+  ODEJacFunc jac;
+
+  // This variable is TRUE when this object is constructed, and also
+  // after any internal data has changed.  Derived classes may use
+  // this information (and change it) to know when to (re)initialize
+  // their own internal data related to this object.
+
+  bool reset;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ODES.cc b/liboctave/ODES.cc
new file mode 100644
index 0000000..67ba5e8
--- /dev/null
+++ b/liboctave/ODES.cc
@@ -0,0 +1,50 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ODES.h"
+#include "lo-error.h"
+
+void
+ODES::initialize (const ColumnVector& xx, double tt)
+{
+  base_diff_eqn::initialize (xx, tt);
+  xdot = ColumnVector (xx.length (), 0.0);
+}
+
+void
+ODES::initialize (const ColumnVector& xx, double tt,
+		  const ColumnVector& xtheta)
+{
+  base_diff_eqn::initialize (xx, tt);
+  xdot = ColumnVector (xx.length (), 0.0);
+  theta = xtheta;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ODES.h b/liboctave/ODES.h
new file mode 100644
index 0000000..ec46df8
--- /dev/null
+++ b/liboctave/ODES.h
@@ -0,0 +1,85 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ODES_h)
+#define octave_ODES_h 1
+
+#include "ODESFunc.h"
+#include "base-de.h"
+
+class
+ODES : public base_diff_eqn, public ODESFunc
+{
+public:
+
+  ODES (void)
+    : base_diff_eqn (), ODESFunc (), theta () { }
+
+  ODES (const ColumnVector& s, double tm, ODESFunc& f)
+    : base_diff_eqn (s, tm), ODESFunc (f), xdot (s.length (), 0.0), theta () { }
+
+  ODES (const ColumnVector& s, const ColumnVector& xtheta, double tm,
+	ODESFunc& f)
+    : base_diff_eqn (s, tm), ODESFunc (f), xdot (s.length (), 0.0),
+      theta (xtheta) { }
+
+  ODES (const ODES& a)
+    : base_diff_eqn (a), ODESFunc (a), theta (a.theta) { }
+
+  ODES& operator = (const ODES& a)
+    {
+      if (this != &a)
+	{
+	  base_diff_eqn::operator = (a);
+	  ODESFunc::operator = (a);
+
+	  xdot = a.xdot;
+	  theta = a.theta;
+	}
+      return *this;
+    }
+
+  ~ODES (void) { }
+
+  ColumnVector parameter_vector (void) { return theta; }
+
+  void initialize (const ColumnVector& x, double t);
+
+  void initialize (const ColumnVector& x, double t,
+		   const ColumnVector& theta);
+
+protected:
+
+  // State vector time derivatives.
+  ColumnVector xdot;
+
+  // Parameter vector.
+  ColumnVector theta;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/ODESFunc.h b/liboctave/ODESFunc.h
new file mode 100644
index 0000000..fecf089
--- /dev/null
+++ b/liboctave/ODESFunc.h
@@ -0,0 +1,117 @@
+/*
+
+Copyright (C) 2002, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ODESFunc_h)
+#define octave_ODESFunc_h 1
+
+#include "dMatrix.h"
+
+class
+ODESFunc
+{
+public:
+
+  struct DAEJac
+    {
+      Matrix *dfdxdot;
+      Matrix *dfdx;
+    };
+
+  typedef ColumnVector (*ODES_fsub) (const ColumnVector& x, double,
+				     const ColumnVector& theta); 
+
+  typedef ColumnVector (*ODES_bsub) (const ColumnVector& x, double,
+				     const ColumnVector& theta, int column);
+
+  typedef Matrix (*ODES_jsub) (const ColumnVector& x, double,
+			       const ColumnVector& theta);
+
+  ODESFunc (void)
+    : fsub (0), bsub (0), jsub (0) { }
+
+  ODESFunc (ODES_fsub f)
+    : fsub (f), bsub (0), jsub (0) { }
+
+  ODESFunc (ODES_fsub f, ODES_bsub b)
+    : fsub (f), bsub (b), jsub (0) { }
+
+  ODESFunc (ODES_fsub f, ODES_bsub b, ODES_jsub j)
+    : fsub (f), bsub (b), jsub (j) { }
+
+  ODESFunc (const ODESFunc& a)
+    : fsub (a.fsub), bsub (a.bsub), jsub (a.jsub) { }
+
+  ODESFunc& operator = (const ODESFunc& a)
+    {
+      if (this != &a)
+	{
+	  fsub = a.fsub;
+	  bsub = a.bsub;
+	  jsub = a.jsub;
+	}
+      return *this;
+    }
+
+  ~ODESFunc (void) { }
+
+  ODES_fsub fsub_function (void) const { return fsub; }
+
+  ODESFunc& set_fsub_function (ODES_fsub f)
+    {
+      fsub = f;
+      return *this;
+    }
+
+  ODES_bsub bsub_function (void) const { return bsub; }
+
+  ODESFunc& set_bsub_function (ODES_bsub b)
+    {
+      bsub = b;
+      return *this;
+    }
+
+  ODES_jsub jsub_function (void) const { return jsub; }
+
+  ODESFunc& set_jsub_function (ODES_jsub j)
+    {
+      jsub = j;
+      return *this;
+    }
+
+protected:
+
+  ODES_fsub fsub;
+  ODES_bsub bsub;
+  ODES_jsub jsub;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
+
+
+
diff --git a/liboctave/PermMatrix.cc b/liboctave/PermMatrix.cc
new file mode 100644
index 0000000..d69ca3d
--- /dev/null
+++ b/liboctave/PermMatrix.cc
@@ -0,0 +1,192 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "PermMatrix.h"
+#include "idx-vector.h"
+#include "error.h"
+#include "Array-util.h"
+
+static void
+gripe_invalid_permutation (void)
+{
+  (*current_liboctave_error_handler)
+    ("PermMatrix: invalid permutation vector");
+}
+
+PermMatrix::PermMatrix (const Array<octave_idx_type>& p, bool colp, bool check)
+  : Array<octave_idx_type> (p), _colp(colp)
+{
+  if (check)
+    {
+      if (! idx_vector (p).is_permutation (p.length ()))
+        {
+          gripe_invalid_permutation ();
+          Array<octave_idx_type>::operator = (Array<octave_idx_type> ());
+        }
+    }
+}
+
+PermMatrix::PermMatrix (const idx_vector& idx, bool colp, octave_idx_type n)
+  : Array<octave_idx_type> (), _colp(colp)
+{
+  octave_idx_type len = idx.length (n);
+  if (! idx.is_permutation (len))
+    gripe_invalid_permutation ();
+  else
+    {
+      Array<octave_idx_type> idxa (len);
+      for (octave_idx_type i = 0; i < len; i++) idxa(i) = idx(i);
+      Array<octave_idx_type>::operator = (idxa);
+    }
+}
+
+PermMatrix::PermMatrix (octave_idx_type n)
+  : Array<octave_idx_type> (n), _colp (false)
+{
+  for (octave_idx_type i = 0; i < n; i++) xelem (i) = i;
+}
+
+octave_idx_type 
+PermMatrix::checkelem (octave_idx_type i, octave_idx_type j) const
+{
+  octave_idx_type len = Array<octave_idx_type>::length ();
+  if (i < 0 || j < 0 || i > len || j > len)
+    {
+      (*current_liboctave_error_handler) ("index out of range");
+      return 0;
+    }
+  else
+    return elem (i, j);
+}
+
+
+PermMatrix 
+PermMatrix::transpose (void) const
+{
+  PermMatrix retval (*this);
+  retval._colp = ! retval._colp;
+  return retval;
+}
+
+PermMatrix 
+PermMatrix::inverse (void) const
+{
+  return transpose ();
+}
+
+octave_idx_type 
+PermMatrix::determinant (void) const
+{
+  Array<octave_idx_type> pa = *this;
+  octave_idx_type len = pa.length (), *p = pa.fortran_vec ();
+  bool neg = false;
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      octave_idx_type j = p[i];
+      if (j != i)
+        {
+          p[i] = p[j];
+          p[j] = j;
+          neg = ! neg;
+        }
+    }
+  
+  return neg ? -1 : 1;
+}
+
+PermMatrix 
+PermMatrix::power (octave_idx_type m) const
+{
+  octave_idx_type n = rows ();
+  bool res_colp = _colp;
+  if (m < 0)
+    {
+      res_colp = ! res_colp;
+      m = -m;
+    }
+  else if (m == 0)
+    return PermMatrix (n);
+
+  const octave_idx_type *p = data ();
+  Array<octave_idx_type> res_pvec (n, -1);
+  octave_idx_type *q = res_pvec.fortran_vec ();
+
+  for (octave_idx_type ics = 0; ics < n; ics++)
+    {
+      if (q[ics] > 0)
+        continue;
+
+      // go forward m steps or until a cycle is found.
+      octave_idx_type ic, j;
+      for (j = 1, ic = p[ics]; j != m && ic != ics; j++, ic = p[ic]) ;
+      if (ic == ics)
+        {
+          // reduce power.
+          octave_idx_type mm = m % j;
+          // go forward mm steps.
+          for (j = 0, ic = ics; j != mm; j++, ic = p[ic]) ;
+        }
+
+      // now ic = p^m[ics]. Loop through the whole cycle.
+      octave_idx_type jcs = ics;
+      do
+        {
+          q[jcs] = ic;
+          jcs = p[jcs]; ic = p[ic];
+        }
+      while (jcs != ics);
+
+    }
+
+  return PermMatrix (res_pvec, res_colp, false);
+}
+
+PermMatrix 
+operator *(const PermMatrix& a, const PermMatrix& b)
+{
+  const Array<octave_idx_type> ia = a.pvec (), ib = b.pvec ();
+  PermMatrix r;
+  octave_idx_type n = a.columns ();
+  if (n != b.rows ())
+    gripe_nonconformant ("operator *", n, n, b.rows (), b.rows ());
+  else if (a._colp == b._colp)
+    {
+      r = PermMatrix ((a._colp 
+                       ? ia.index (idx_vector (ib)) 
+                       : ib.index (idx_vector (ia))), a._colp, false);
+    }
+  else
+    {
+      Array<octave_idx_type> ra (n);
+      if (a._colp)
+        ra.assign (idx_vector (ib), ia);
+      else
+        ra.assign (idx_vector (ia), ib);
+      r = PermMatrix (ra, a._colp, false);
+    }
+
+  return r;
+}
diff --git a/liboctave/PermMatrix.h b/liboctave/PermMatrix.h
new file mode 100644
index 0000000..c7def57
--- /dev/null
+++ b/liboctave/PermMatrix.h
@@ -0,0 +1,129 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_PermMatrix_h)
+#define octave_PermMatrix_h 1
+
+#include "Array.h"
+#include "mx-defs.h"
+
+// Array<T> is inherited privately so that some methods, like index, don't
+// produce unexpected results.
+
+class OCTAVE_API PermMatrix : protected Array<octave_idx_type>
+{
+
+public:
+
+  PermMatrix (void) : Array<octave_idx_type> (), _colp (false) { }
+
+  PermMatrix (octave_idx_type n);
+
+  PermMatrix (const Array<octave_idx_type>& p, bool colp = false, 
+              bool check = true);
+
+  PermMatrix (const PermMatrix& m)
+    : Array<octave_idx_type> (m), _colp(m._colp) { }
+  
+  PermMatrix (const idx_vector& idx, bool colp = false, octave_idx_type n = 0); 
+
+  octave_idx_type dim1 (void) const 
+    { return Array<octave_idx_type>::length (); }
+  octave_idx_type dim2 (void) const 
+    { return Array<octave_idx_type>::length (); }
+
+  octave_idx_type rows (void) const { return dim1 (); }
+  octave_idx_type cols (void) const { return dim2 (); }
+  octave_idx_type columns (void) const { return dim2 (); }
+
+  octave_idx_type perm_length (void) const 
+    { return Array<octave_idx_type>::length (); }
+  octave_idx_type length (void) const 
+    { return dim1 () * dim2 (); }
+  octave_idx_type nelem (void) const { return dim1 () * dim2 (); }
+  octave_idx_type numel (void) const { return nelem (); }
+
+  size_t byte_size (void) const { return perm_length () * sizeof (octave_idx_type); }
+
+  dim_vector dims (void) const { return dim_vector (dim1 (), dim2 ()); }
+
+  Array<octave_idx_type> pvec (void) const
+    { return *this; }
+
+  octave_idx_type 
+  elem (octave_idx_type i, octave_idx_type j) const
+    {
+      return (_colp 
+              ? ((Array<octave_idx_type>::elem (j) == i) ? 1 : 0)
+              : ((Array<octave_idx_type>::elem (i) == j) ? 1 : 0));
+    }
+
+  octave_idx_type 
+  checkelem (octave_idx_type i, octave_idx_type j) const;
+
+  octave_idx_type
+  operator () (octave_idx_type i, octave_idx_type j) const
+    {
+#if defined (BOUNDS_CHECKING)
+      return checkelem (i, j);
+#else
+      return elem (i, j);
+#endif
+    }
+  
+  // These are, in fact, super-fast.
+  PermMatrix transpose (void) const;
+  PermMatrix inverse (void) const;
+
+  // Determinant, i.e. the sign of permutation.
+  octave_idx_type determinant (void) const;
+
+  // Efficient integer power of a permutation.
+  PermMatrix power (octave_idx_type n) const;
+
+  bool is_col_perm (void) const { return _colp; }
+  bool is_row_perm (void) const { return !_colp; }
+
+  friend OCTAVE_API PermMatrix operator *(const PermMatrix& a, const PermMatrix& b);
+
+  const octave_idx_type *data (void) const 
+    { return Array<octave_idx_type>::data (); }
+
+  const octave_idx_type *fortran_vec (void) const 
+    { return Array<octave_idx_type>::fortran_vec (); }
+
+  octave_idx_type *fortran_vec (void) 
+    { return Array<octave_idx_type>::fortran_vec (); }
+
+  void print_info (std::ostream& os, const std::string& prefix) const
+    { Array<octave_idx_type>::print_info (os, prefix); }
+
+private:
+  bool _colp;
+};
+
+// Multiplying permutations together.
+PermMatrix 
+OCTAVE_API
+operator *(const PermMatrix& a, const PermMatrix& b);
+
+#endif
diff --git a/liboctave/Quad-opts.h b/liboctave/Quad-opts.h
new file mode 100644
index 0000000..3553045
--- /dev/null
+++ b/liboctave/Quad-opts.h
@@ -0,0 +1,88 @@
+// DO NOT EDIT!
+// Generated automatically from Quad-opts.in.
+
+#if !defined (octave_Quad_options_h)
+#define octave_Quad_options_h 1
+
+#include <cfloat>
+#include <cmath>
+
+
+
+class
+Quad_options
+{
+public:
+
+  Quad_options (void) { init (); }
+
+  Quad_options (const Quad_options& opt) { copy (opt); }
+
+  Quad_options& operator = (const Quad_options& opt)
+    {
+      if (this != &opt)
+        copy (opt);
+
+      return *this;
+    }
+
+  ~Quad_options (void) { }
+
+  void init (void)
+    {
+      x_absolute_tolerance = ::sqrt (DBL_EPSILON);
+      x_relative_tolerance = ::sqrt (DBL_EPSILON);
+      x_single_precision_absolute_tolerance = ::sqrt (FLT_EPSILON);
+      x_single_precision_relative_tolerance = ::sqrt (FLT_EPSILON);
+      reset = true;
+    }
+
+  void copy (const Quad_options& opt)
+    {
+      x_absolute_tolerance = opt.x_absolute_tolerance;
+      x_relative_tolerance = opt.x_relative_tolerance;
+      x_single_precision_absolute_tolerance = opt.x_single_precision_absolute_tolerance;
+      x_single_precision_relative_tolerance = opt.x_single_precision_relative_tolerance;
+      reset = opt.reset;
+    }
+
+  void set_options (const Quad_options& opt) { copy (opt); }
+
+  void set_default_options (void) { init (); }
+
+  void set_absolute_tolerance (double val)
+    { x_absolute_tolerance = val; reset = true; }
+
+  void set_relative_tolerance (double val)
+    { x_relative_tolerance = val; reset = true; }
+
+  void set_single_precision_absolute_tolerance (float val)
+    { x_single_precision_absolute_tolerance = val; reset = true; }
+
+  void set_single_precision_relative_tolerance (float val)
+    { x_single_precision_relative_tolerance = val; reset = true; }
+  double absolute_tolerance (void) const
+    { return x_absolute_tolerance; }
+
+  double relative_tolerance (void) const
+    { return x_relative_tolerance; }
+
+  float single_precision_absolute_tolerance (void) const
+    { return x_single_precision_absolute_tolerance; }
+
+  float single_precision_relative_tolerance (void) const
+    { return x_single_precision_relative_tolerance; }
+
+private:
+
+  double x_absolute_tolerance;
+  double x_relative_tolerance;
+  float x_single_precision_absolute_tolerance;
+  float x_single_precision_relative_tolerance;
+
+protected:
+
+  bool reset;
+};
+
+#endif
diff --git a/liboctave/Quad-opts.in b/liboctave/Quad-opts.in
new file mode 100644
index 0000000..9520d7e
--- /dev/null
+++ b/liboctave/Quad-opts.in
@@ -0,0 +1,64 @@
+# Copyright (C) 2002, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+CLASS = "Quad"
+
+OPTION
+  NAME = "absolute tolerance"
+  DOC_ITEM
+Absolute tolerance; may be zero for pure relative error test.
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "::sqrt (DBL_EPSILON)"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "relative tolerance"
+  DOC_ITEM
+Nonnegative relative tolerance.  If the absolute tolerance is zero,
+the relative tolerance must be greater than or equal to 
+ at code{max (50*eps, 0.5e-28)}.
+  END_DOC_ITEM
+  TYPE = "double"
+  INIT_VALUE = "::sqrt (DBL_EPSILON)"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "single precision absolute tolerance"
+  DOC_ITEM
+Absolute tolerance for single precision; may be zero for pure relative 
+error test.
+  END_DOC_ITEM
+  TYPE = "float"
+  INIT_VALUE = "::sqrt (FLT_EPSILON)"
+  SET_EXPR = "val"
+END_OPTION
+
+OPTION
+  NAME = "single precision relative tolerance"
+  DOC_ITEM
+Nonnegative relative tolerance for single precision.  If the absolute
+tolerance is zero, the relative tolerance must be greater than or equal to 
+ at code{max (50*eps, 0.5e-28)}.
+  END_DOC_ITEM
+  TYPE = "float"
+  INIT_VALUE = "::sqrt (FLT_EPSILON)"
+  SET_EXPR = "val"
+END_OPTION
diff --git a/liboctave/Quad.cc b/liboctave/Quad.cc
new file mode 100644
index 0000000..3c87352
--- /dev/null
+++ b/liboctave/Quad.cc
@@ -0,0 +1,303 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Quad.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "quit.h"
+#include "sun-utils.h"
+
+static integrand_fcn user_fcn;
+static float_integrand_fcn float_user_fcn;
+
+// FIXME -- would be nice to not have to have this global
+// variable.
+// Nonzero means an error occurred in the calculation of the integrand
+// function, and the user wants us to quit.
+int quad_integration_error = 0;
+
+typedef octave_idx_type (*quad_fcn_ptr) (double*, int&, double*);
+typedef octave_idx_type (*quad_float_fcn_ptr) (float*, int&, float*);
+			      
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dqagp, DQAGP) (quad_fcn_ptr, const double&, const double&,
+			   const octave_idx_type&, const double*, const double&,
+			   const double&, double&, double&, octave_idx_type&,
+			   octave_idx_type&, const octave_idx_type&, const octave_idx_type&, octave_idx_type&, octave_idx_type*,
+			   double*);
+
+  F77_RET_T
+  F77_FUNC (dqagi, DQAGI) (quad_fcn_ptr, const double&, const octave_idx_type&,
+			   const double&, const double&, double&,
+			   double&, octave_idx_type&, octave_idx_type&, const octave_idx_type&,
+			   const octave_idx_type&, octave_idx_type&, octave_idx_type*, double*); 
+
+  F77_RET_T
+  F77_FUNC (qagp, QAGP) (quad_float_fcn_ptr, const float&, const float&,
+			 const octave_idx_type&, const float*, const float&,
+			 const float&, float&, float&, octave_idx_type&,
+			 octave_idx_type&, const octave_idx_type&, const octave_idx_type&, octave_idx_type&, octave_idx_type*,
+			 float*);
+
+  F77_RET_T
+  F77_FUNC (qagi, QAGI) (quad_float_fcn_ptr, const float&, const octave_idx_type&,
+			 const float&, const float&, float&,
+			 float&, octave_idx_type&, octave_idx_type&, const octave_idx_type&,
+			 const octave_idx_type&, octave_idx_type&, octave_idx_type*, float*); 
+}
+
+static octave_idx_type
+user_function (double *x, int& ierr, double *result)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+#if defined (__sparc) && defined (__GNUC__)
+  double xx = access_double (x);
+#else
+  double xx = *x;
+#endif
+
+  quad_integration_error = 0;
+
+  double xresult = (*user_fcn) (xx);
+
+#if defined (__sparc) && defined (__GNUC__)
+  assign_double (result, xresult);
+#else
+  *result = xresult;
+#endif
+
+  if (quad_integration_error)
+    ierr = -1;
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+static octave_idx_type
+float_user_function (float *x, int& ierr, float *result)
+{
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  quad_integration_error = 0;
+
+  *result = (*float_user_fcn) (*x);
+
+  if (quad_integration_error)
+    ierr = -1;
+
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  return 0;
+}
+
+double
+DefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr)
+{
+  octave_idx_type npts = singularities.capacity () + 2;
+  double *points = singularities.fortran_vec ();
+  double result = 0.0;
+
+  octave_idx_type leniw = 183*npts - 122;
+  Array<octave_idx_type> iwork (leniw);
+  octave_idx_type *piwork = iwork.fortran_vec ();
+
+  octave_idx_type lenw = 2*leniw - npts;
+  Array<double> work (lenw);
+  double *pwork = work.fortran_vec ();
+
+  user_fcn = f;
+  octave_idx_type last;
+
+  double abs_tol = absolute_tolerance ();
+  double rel_tol = relative_tolerance ();
+
+  F77_XFCN (dqagp, DQAGP, (user_function, lower_limit, upper_limit,
+			   npts, points, abs_tol, rel_tol, result,
+			   abserr, neval, ier, leniw, lenw, last,
+			   piwork, pwork));
+
+  return result;
+}
+
+float
+DefQuad::do_integrate (octave_idx_type&, octave_idx_type&, float&)
+{
+  (*current_liboctave_error_handler) ("incorrect integration function called");
+  return 0.0;
+}
+
+double
+IndefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr)
+{
+  double result = 0.0;
+
+  octave_idx_type leniw = 128;
+  Array<octave_idx_type> iwork (leniw);
+  octave_idx_type *piwork = iwork.fortran_vec ();
+
+  octave_idx_type lenw = 8*leniw;
+  Array<double> work (lenw);
+  double *pwork = work.fortran_vec ();
+
+  user_fcn = f;
+  octave_idx_type last;
+
+  octave_idx_type inf;
+  switch (type)
+    {
+    case bound_to_inf:
+      inf = 1;
+      break;
+
+    case neg_inf_to_bound:
+      inf = -1;
+      break;
+
+    case doubly_infinite:
+      inf = 2;
+      break;
+
+    default:
+      assert (0);
+      break;
+    }
+
+  double abs_tol = absolute_tolerance ();
+  double rel_tol = relative_tolerance ();
+
+  F77_XFCN (dqagi, DQAGI, (user_function, bound, inf, abs_tol, rel_tol,
+			   result, abserr, neval, ier, leniw, lenw,
+			   last, piwork, pwork));
+
+  return result;
+}
+
+float
+IndefQuad::do_integrate (octave_idx_type&, octave_idx_type&, float&)
+{
+  (*current_liboctave_error_handler) ("incorrect integration function called");
+  return 0.0;
+}
+
+double
+FloatDefQuad::do_integrate (octave_idx_type&, octave_idx_type&, double&)
+{
+  (*current_liboctave_error_handler) ("incorrect integration function called");
+  return 0.0;
+}
+
+float
+FloatDefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr)
+{
+  octave_idx_type npts = singularities.capacity () + 2;
+  float *points = singularities.fortran_vec ();
+  float result = 0.0;
+
+  octave_idx_type leniw = 183*npts - 122;
+  Array<octave_idx_type> iwork (leniw);
+  octave_idx_type *piwork = iwork.fortran_vec ();
+
+  octave_idx_type lenw = 2*leniw - npts;
+  Array<float> work (lenw);
+  float *pwork = work.fortran_vec ();
+
+  float_user_fcn = ff;
+  octave_idx_type last;
+
+  float abs_tol = single_precision_absolute_tolerance ();
+  float rel_tol = single_precision_relative_tolerance ();
+
+  F77_XFCN (qagp, QAGP, (float_user_function, lower_limit, upper_limit,
+			 npts, points, abs_tol, rel_tol, result,
+			 abserr, neval, ier, leniw, lenw, last,
+			 piwork, pwork));
+
+  return result;
+}
+
+double
+FloatIndefQuad::do_integrate (octave_idx_type&, octave_idx_type&, double&)
+{
+  (*current_liboctave_error_handler) ("incorrect integration function called");
+  return 0.0;
+}
+
+float
+FloatIndefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr)
+{
+  float result = 0.0;
+
+  octave_idx_type leniw = 128;
+  Array<octave_idx_type> iwork (leniw);
+  octave_idx_type *piwork = iwork.fortran_vec ();
+
+  octave_idx_type lenw = 8*leniw;
+  Array<float> work (lenw);
+  float *pwork = work.fortran_vec ();
+
+  float_user_fcn = ff;
+  octave_idx_type last;
+
+  octave_idx_type inf;
+  switch (type)
+    {
+    case bound_to_inf:
+      inf = 1;
+      break;
+
+    case neg_inf_to_bound:
+      inf = -1;
+      break;
+
+    case doubly_infinite:
+      inf = 2;
+      break;
+
+    default:
+      assert (0);
+      break;
+    }
+
+  float abs_tol = single_precision_absolute_tolerance ();
+  float rel_tol = single_precision_relative_tolerance ();
+
+  F77_XFCN (qagi, QAGI, (float_user_function, bound, inf, abs_tol, rel_tol,
+			 result, abserr, neval, ier, leniw, lenw,
+			 last, piwork, pwork));
+
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Quad.h b/liboctave/Quad.h
new file mode 100644
index 0000000..6d94708
--- /dev/null
+++ b/liboctave/Quad.h
@@ -0,0 +1,253 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Quad_h)
+#define octave_Quad_h 1
+
+#include <cfloat>
+
+#include "dColVector.h"
+#include "fColVector.h"
+#include "lo-math.h"
+
+#if !defined (octave_Quad_typedefs)
+#define octave_Quad_typedefs 1
+
+typedef double (*integrand_fcn) (double x);
+typedef float (*float_integrand_fcn) (float x);
+
+#endif
+
+// FIXME -- would be nice to not have to have this global
+// variable.
+// Nonzero means an error occurred in the calculation of the integrand
+// function, and the user wants us to quit.
+extern OCTAVE_API int quad_integration_error;
+
+#include "Quad-opts.h"
+
+class
+OCTAVE_API
+Quad : public Quad_options
+{
+ public:
+
+  Quad (integrand_fcn fcn)
+    : Quad_options (), f (fcn) { }
+
+  Quad (float_integrand_fcn fcn)
+    : Quad_options (), ff (fcn) { }
+
+  virtual ~Quad (void) { }
+
+  virtual double integrate (void)
+    {
+      octave_idx_type ier, neval;
+      double abserr;
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual float float_integrate (void)
+    {
+      octave_idx_type ier, neval;
+      float abserr;
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual double integrate (octave_idx_type& ier)
+    {
+      octave_idx_type neval;
+      double abserr;
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual float float_integrate (octave_idx_type& ier)
+    {
+      octave_idx_type neval;
+      float abserr;
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual double integrate (octave_idx_type& ier, octave_idx_type& neval)
+    {
+      double abserr;
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual float float_integrate (octave_idx_type& ier, octave_idx_type& neval)
+    {
+      float abserr;
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual double integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr)
+    {
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual float float_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr)
+    {
+      return do_integrate (ier, neval, abserr);
+    }
+
+  virtual double do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr) = 0;
+
+  virtual float do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr) = 0;
+
+ protected:
+
+  integrand_fcn f;
+  float_integrand_fcn ff;
+};
+
+class
+OCTAVE_API
+DefQuad : public Quad
+{
+ public:
+
+  DefQuad (integrand_fcn fcn)
+    : Quad (fcn), lower_limit (0.0), upper_limit (1.0), singularities () { }
+
+  DefQuad (integrand_fcn fcn, double ll, double ul)
+    : Quad (fcn), lower_limit (ll), upper_limit (ul), singularities () { }
+
+  DefQuad (integrand_fcn fcn, double ll, double ul,
+	   const ColumnVector& sing)
+    : Quad (fcn), lower_limit (ll), upper_limit (ul),
+      singularities (sing) { }
+
+  DefQuad (integrand_fcn fcn, const ColumnVector& sing)
+    : Quad (fcn), lower_limit (0.0), upper_limit (1.0),
+      singularities (sing) { }
+
+  ~DefQuad (void) { }
+
+  double do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr);
+
+  float do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr);
+
+ private:
+
+  double lower_limit;
+  double upper_limit;
+
+  ColumnVector singularities;
+};
+
+class
+OCTAVE_API
+IndefQuad : public Quad
+{
+ public:
+
+  enum IntegralType { bound_to_inf, neg_inf_to_bound, doubly_infinite };
+
+  IndefQuad (integrand_fcn fcn)
+    : Quad (fcn), bound (0.0), type (bound_to_inf) { }
+
+  IndefQuad (integrand_fcn fcn, double b, IntegralType t)
+    : Quad (fcn), bound (b), type (t) { }
+
+  ~IndefQuad (void) { }
+
+  double do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr);
+
+  float do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr);
+
+ private:
+
+  double bound;
+  IntegralType type;
+  int integration_error;
+};
+
+class
+OCTAVE_API
+FloatDefQuad : public Quad
+{
+ public:
+
+  FloatDefQuad (float_integrand_fcn fcn)
+    : Quad (fcn), lower_limit (0.0), upper_limit (1.0), singularities () { }
+
+  FloatDefQuad (float_integrand_fcn fcn, float ll, float ul)
+    : Quad (fcn), lower_limit (ll), upper_limit (ul), singularities () { }
+
+  FloatDefQuad (float_integrand_fcn fcn, float ll, float ul,
+	   const FloatColumnVector& sing)
+    : Quad (fcn), lower_limit (ll), upper_limit (ul),
+      singularities (sing) { }
+
+  FloatDefQuad (float_integrand_fcn fcn, const FloatColumnVector& sing)
+    : Quad (fcn), lower_limit (0.0), upper_limit (1.0),
+      singularities (sing) { }
+
+  ~FloatDefQuad (void) { }
+
+  double do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr);
+
+  float do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr);
+
+ private:
+
+  float lower_limit;
+  float upper_limit;
+
+  FloatColumnVector singularities;
+};
+
+class
+OCTAVE_API
+FloatIndefQuad : public Quad
+{
+ public:
+
+  enum IntegralType { bound_to_inf, neg_inf_to_bound, doubly_infinite };
+
+  FloatIndefQuad (float_integrand_fcn fcn)
+    : Quad (fcn), bound (0.0), type (bound_to_inf) { }
+
+  FloatIndefQuad (float_integrand_fcn fcn, double b, IntegralType t)
+    : Quad (fcn), bound (b), type (t) { }
+
+  ~FloatIndefQuad (void) { }
+
+  double do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr);
+
+  float do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr);
+
+ private:
+
+  float bound;
+  IntegralType type;
+  int integration_error;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Range.cc b/liboctave/Range.cc
new file mode 100644
index 0000000..b84ec59
--- /dev/null
+++ b/liboctave/Range.cc
@@ -0,0 +1,466 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2004,
+              2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <limits>
+
+#include "Range.h"
+#include "lo-error.h"
+#include "lo-mappers.h"
+#include "lo-math.h"
+#include "lo-utils.h"
+
+Range::Range (double b, double i, octave_idx_type n)
+  : rng_base (b), rng_limit (b + n * i), rng_inc (i), 
+  rng_nelem (n), cache ()
+{
+  if (! xfinite (b) || ! xfinite (i))
+    rng_nelem = -2;
+}
+
+bool
+Range::all_elements_are_ints (void) const
+{
+  // If the base and increment are ints, the final value in the range
+  // will also be an integer, even if the limit is not. If there is one
+  // or fewer elements only the base needs to be an integer
+
+  return (! (xisnan (rng_base) || xisnan (rng_inc))
+	  && (NINTbig (rng_base) == rng_base || rng_nelem < 1)
+	  && (NINTbig (rng_inc) == rng_inc || rng_nelem <= 1));
+}
+
+Matrix
+Range::matrix_value (void) const
+{
+  if (rng_nelem > 0 && cache.nelem () == 0)
+    {
+      cache.resize (1, rng_nelem);
+      double b = rng_base;
+      double increment = rng_inc;
+      for (octave_idx_type i = 0; i < rng_nelem; i++)
+	cache(i) = b + i * increment;
+
+      // On some machines (x86 with extended precision floating point
+      // arithmetic, for example) it is possible that we can overshoot
+      // the limit by approximately the machine precision even though
+      // we were very careful in our calculation of the number of
+      // elements.
+
+      if ((rng_inc > 0 && cache(rng_nelem-1) > rng_limit)
+	  || (rng_inc < 0 && cache(rng_nelem-1) < rng_limit))
+	cache(rng_nelem-1) = rng_limit;
+    }
+
+  return cache;
+}
+
+
+// NOTE: max and min only return useful values if nelem > 0.
+
+double
+Range::min (void) const
+{
+  double retval = 0.0;
+  if (rng_nelem > 0)
+    {
+      if (rng_inc > 0)
+	retval = rng_base;
+      else
+	{
+	  retval = rng_base + (rng_nelem - 1) * rng_inc;
+
+	  // See the note in the matrix_value method above.
+
+	  if (retval < rng_limit)
+	    retval = rng_limit;
+	}
+
+    }
+  return retval;
+}
+
+double
+Range::max (void) const
+{
+  double retval = 0.0;
+  if (rng_nelem > 0)
+    {
+      if (rng_inc > 0)
+	{
+	  retval = rng_base + (rng_nelem - 1) * rng_inc;
+
+	  // See the note in the matrix_value method above.
+
+	  if (retval > rng_limit)
+	    retval = rng_limit;
+	}
+      else
+	retval = rng_base;
+    }
+  return retval;
+}
+
+void
+Range::sort_internal (bool ascending)
+{
+  if (ascending && rng_base > rng_limit && rng_inc < 0.0)
+    {
+      double tmp = rng_base;
+      rng_base = min ();
+      rng_limit = tmp;
+      rng_inc = -rng_inc;
+      clear_cache ();
+    }
+  else if (! ascending && rng_base < rng_limit && rng_inc > 0.0)
+    {
+      double tmp = rng_limit;
+      rng_limit = min ();
+      rng_base = tmp;
+      rng_inc = -rng_inc;
+      clear_cache ();
+    }
+}
+
+void
+Range::sort_internal (Array<octave_idx_type>& sidx, bool ascending)
+{
+  octave_idx_type nel = nelem ();
+
+  sidx.resize (dim_vector (1, nel));
+
+  octave_idx_type *psidx = sidx.fortran_vec ();
+
+  bool reverse = false;
+
+  if (ascending && rng_base > rng_limit && rng_inc < 0.0)
+    {
+      double tmp = rng_base;
+      rng_base = min ();
+      rng_limit = tmp;
+      rng_inc = -rng_inc;
+      clear_cache ();
+      reverse = true;
+    }
+  else if (! ascending && rng_base < rng_limit && rng_inc > 0.0)
+    {
+      double tmp = rng_limit;
+      rng_limit = min ();
+      rng_base = tmp;
+      rng_inc = -rng_inc;
+      clear_cache ();
+      reverse = true;
+    }
+
+  octave_idx_type tmp = reverse ? nel - 1 : 0;
+  octave_idx_type stp = reverse ? -1 : 1;
+
+  for (octave_idx_type i = 0; i < nel; i++, tmp += stp)
+    psidx[i] = tmp;
+
+}
+
+Matrix 
+Range::diag (octave_idx_type k) const
+{
+  return matrix_value ().diag (k);
+}
+
+Range
+Range::sort (octave_idx_type dim, sortmode mode) const
+{
+  Range retval = *this;
+
+  if (dim == 1)
+    {
+      if (mode == ASCENDING)
+	retval.sort_internal (true);
+      else if (mode == DESCENDING)
+	retval.sort_internal (false);
+    }
+  else if (dim != 0)
+    (*current_liboctave_error_handler) ("Range::sort: invalid dimension");
+
+  return retval;
+}
+
+Range
+Range::sort (Array<octave_idx_type>& sidx, octave_idx_type dim,
+	     sortmode mode) const
+{
+  Range retval = *this;
+
+  if (dim == 1)
+    {
+      if (mode == ASCENDING)
+	  retval.sort_internal (sidx, true);
+      else if (mode == DESCENDING)
+	retval.sort_internal (sidx, false);
+    }
+  else if (dim != 0)
+    (*current_liboctave_error_handler) ("Range::sort: invalid dimension");
+
+  return retval;
+}
+
+sortmode
+Range::is_sorted (sortmode mode) const
+{
+  if (rng_nelem > 1 && rng_inc < 0)
+    mode = (mode == ASCENDING) ? UNSORTED : DESCENDING;
+  else if (rng_nelem > 1 && rng_inc > 0)
+    mode = (mode == DESCENDING) ? UNSORTED : ASCENDING;
+  else
+    mode = mode ? mode : ASCENDING;
+
+  return mode;
+}
+
+std::ostream&
+operator << (std::ostream& os, const Range& a)
+{
+  double b = a.base ();
+  double increment = a.inc ();
+  octave_idx_type num_elem = a.nelem ();
+
+  for (octave_idx_type i = 0; i < num_elem-1; i++)
+    os << b + i * increment << " ";
+
+  // Prevent overshoot.  See comment in the matrix_value method
+  // above.
+
+  os << (increment > 0 ? a.max () : a.min ()) << "\n";
+
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, Range& a)
+{
+  is >> a.rng_base;
+  if (is)
+    {
+      is >> a.rng_limit;
+      if (is)
+	{
+	  is >> a.rng_inc;
+	  a.rng_nelem = a.nelem_internal ();
+	}
+    }
+
+  return is;
+}
+
+Range
+operator - (const Range& r)
+{
+  return Range (-r.base (), -r.inc (), r.nelem ());
+}
+
+Range operator + (double x, const Range& r)
+{
+  Range result (x + r.base (), r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = x + r.matrix_value ();
+
+  return result;
+}
+
+Range operator + (const Range& r, double x)
+{
+  Range result (r.base () + x, r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = r.matrix_value () + x;
+
+  return result;
+}
+
+Range operator - (double x, const Range& r)
+{
+  Range result (x - r.base (), -r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = x - r.matrix_value ();
+
+  return result;
+}
+
+Range operator - (const Range& r, double x)
+{
+  Range result (r.base () - x, r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = r.matrix_value () - x;
+
+  return result;
+}
+
+Range operator * (double x, const Range& r)
+{
+  Range result (x * r.base (), x * r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = x * r.matrix_value ();
+
+  return result;
+}
+
+Range operator * (const Range& r, double x)
+{
+  Range result (r.base () * x, r.inc () * x, r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = r.matrix_value () * x;
+
+  return result;
+}
+
+
+// C  See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5.
+// C
+// C===Tolerant FLOOR function.
+// C
+// C    X  -  is given as a Double Precision argument to be operated on.
+// C          It is assumed that X is represented with M mantissa bits.
+// C    CT -  is   given   as   a   Comparison   Tolerance   such   that
+// C          0.LT.CT.LE.3-SQRT(5)/2. If the relative difference between
+// C          X and A whole number is  less  than  CT,  then  TFLOOR  is
+// C          returned   as   this   whole   number.   By  treating  the
+// C          floating-point numbers as a finite ordered set  note  that
+// C          the  heuristic  EPS=2.**(-(M-1))   and   CT=3*EPS   causes
+// C          arguments  of  TFLOOR/TCEIL to be treated as whole numbers
+// C          if they are  exactly  whole  numbers  or  are  immediately
+// C          adjacent to whole number representations.  Since EPS,  the
+// C          "distance"  between  floating-point  numbers  on  the unit
+// C          interval, and M, the number of bits in X'S mantissa, exist
+// C          on  every  floating-point   computer,   TFLOOR/TCEIL   are
+// C          consistently definable on every floating-point computer.
+// C
+// C          For more information see the following references:
+// C    (1) P. E. Hagerty, "More On Fuzzy Floor And Ceiling," APL  QUOTE
+// C        QUAD 8(4):20-24, June 1978. Note that TFLOOR=FL5.
+// C    (2) L. M. Breed, "Definitions For Fuzzy Floor And Ceiling",  APL
+// C        QUOTE QUAD 8(3):16-23, March 1978. This paper cites FL1 through
+// C        FL5, the history of five years of evolutionary development of
+// C        FL5 - the seven lines of code below - by open collaboration
+// C        and corroboration of the mathematical-computing community.
+// C
+// C  Penn State University Center for Academic Computing
+// C  H. D. Knoble - August, 1978.
+
+static inline double
+tfloor (double x, double ct)
+{
+// C---------FLOOR(X) is the largest integer algebraically less than
+// C         or equal to X; that is, the unfuzzy FLOOR function.
+
+//  DINT (X) = X - DMOD (X, 1.0);
+//  FLOOR (X) = DINT (X) - DMOD (2.0 + DSIGN (1.0, X), 3.0);
+
+// C---------Hagerty's FL5 function follows...
+
+  double q = 1.0;
+
+  if (x < 0.0)
+    q = 1.0 - ct;
+
+  double rmax = q / (2.0 - ct);
+
+  double t1 = 1.0 + floor (x);
+  t1 = (ct / q) * (t1 < 0.0 ? -t1 : t1);
+  t1 = rmax < t1 ? rmax : t1;
+  t1 = ct > t1 ? ct : t1;
+  t1 = floor (x + t1);
+
+  if (x <= 0.0 || (t1 - x) < rmax)
+    return t1;
+  else
+    return t1 - 1.0;
+}
+
+static inline double
+tceil (double x, double ct)
+{
+  return -tfloor (-x, ct);
+}
+
+static inline bool
+teq (double u, double v, double ct = 3.0 * DBL_EPSILON)
+{
+  double tu = fabs (u);
+  double tv = fabs (v);
+
+  return fabs (u - v) < ((tu > tv ? tu : tv) * ct);
+}
+
+octave_idx_type
+Range::nelem_internal (void) const
+{
+  octave_idx_type retval = -1;
+
+  if (rng_inc == 0
+      || (rng_limit > rng_base && rng_inc < 0)
+      || (rng_limit < rng_base && rng_inc > 0))
+    {
+      retval = 0;
+    }
+  else
+    {
+      double ct = 3.0 * DBL_EPSILON;
+
+      double tmp = tfloor ((rng_limit - rng_base + rng_inc) / rng_inc, ct);
+
+      octave_idx_type n_elt = (tmp > 0.0 ? static_cast<octave_idx_type> (tmp) : 0);
+
+      // If the final element that we would compute for the range is
+      // equal to the limit of the range, or is an adjacent floating
+      // point number, accept it.  Otherwise, try a range with one
+      // fewer element.  If that fails, try again with one more
+      // element.
+      //
+      // I'm not sure this is very good, but it seems to work better than
+      // just using tfloor as above.  For example, without it, the
+      // expression 1.8:0.05:1.9 fails to produce the expected result of
+      // [1.8, 1.85, 1.9].
+
+      if (! teq (rng_base + (n_elt - 1) * rng_inc, rng_limit))
+	{
+	  if (teq (rng_base + (n_elt - 2) * rng_inc, rng_limit))
+	    n_elt--;
+	  else if (teq (rng_base + n_elt * rng_inc, rng_limit))
+	    n_elt++;
+	}
+
+      retval = (n_elt >= std::numeric_limits<octave_idx_type>::max () - 1) ? -1 : n_elt;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Range.h b/liboctave/Range.h
new file mode 100644
index 0000000..42d624a
--- /dev/null
+++ b/liboctave/Range.h
@@ -0,0 +1,156 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Range_h)
+#define octave_Range_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "oct-sort.h"
+
+class
+OCTAVE_API
+Range
+{
+ public:
+
+  Range (void)
+    : rng_base (0), rng_limit (0), rng_inc (0), rng_nelem (0), cache (1, 0) { }
+
+  Range (const Range& r)
+    : rng_base (r.rng_base), rng_limit (r.rng_limit), rng_inc (r.rng_inc),
+      rng_nelem (r.rng_nelem), cache (r.cache) { }
+
+  Range (double b, double l)
+    : rng_base (b), rng_limit (l), rng_inc (1),
+      rng_nelem (nelem_internal ()), cache () { }
+
+  Range (double b, double l, double i)
+    : rng_base (b), rng_limit (l), rng_inc (i),
+      rng_nelem (nelem_internal ()), cache () { }
+
+  // For operators' usage (to preserve element count).
+  Range (double b, double i, octave_idx_type n);
+
+  double base (void) const { return rng_base; }
+  double limit (void) const { return rng_limit; }
+  double inc (void) const { return rng_inc; }
+  octave_idx_type nelem (void) const { return rng_nelem; }
+
+  bool all_elements_are_ints (void) const;
+
+  Matrix matrix_value (void) const;
+
+  double min (void) const;
+  double max (void) const;
+
+  void sort_internal (bool ascending = true);
+  void sort_internal (Array<octave_idx_type>& sidx, bool ascending = true);
+
+  Matrix diag (octave_idx_type k = 0) const;
+
+  Range sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const;
+
+  Range sort (Array<octave_idx_type>& sidx, octave_idx_type dim = 0,
+	      sortmode mode = ASCENDING) const;
+
+  sortmode is_sorted (sortmode mode = ASCENDING) const;
+
+  void set_base (double b)
+  {
+    if (rng_base != b)
+      {
+	rng_base = b;
+	clear_cache ();
+      }
+  }
+
+  void set_limit (double l)
+  {
+    if (rng_limit != l)
+      {
+	rng_limit = l;
+	clear_cache ();
+      }
+  }
+
+  void set_inc (double i)
+  {
+    if (rng_inc != i)
+      {
+	rng_inc = i;
+	clear_cache ();
+      }
+  }
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const Range& r);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, Range& r);
+
+  friend OCTAVE_API Range operator - (const Range& r);
+  friend OCTAVE_API Range operator + (double x, const Range& r);
+  friend OCTAVE_API Range operator + (const Range& r, double x);
+  friend OCTAVE_API Range operator - (double x, const Range& r);
+  friend OCTAVE_API Range operator - (const Range& r, double x);
+  friend OCTAVE_API Range operator * (double x, const Range& r);
+  friend OCTAVE_API Range operator * (const Range& r, double x);
+
+  void print_range (void);
+
+ private:
+
+  double rng_base;
+  double rng_limit;
+  double rng_inc;
+
+  octave_idx_type rng_nelem;
+
+  mutable Matrix cache;
+
+  octave_idx_type nelem_internal (void) const;
+
+  void clear_cache (void) const { cache.resize (0, 0); }
+
+};
+
+extern OCTAVE_API Range operator - (const Range& r);
+
+extern OCTAVE_API Range operator + (double x, const Range& r);
+
+extern OCTAVE_API Range operator + (const Range& r, double x);
+
+extern OCTAVE_API Range operator - (double x, const Range& r);
+
+extern OCTAVE_API Range operator - (const Range& r, double x);
+
+extern OCTAVE_API Range operator * (double x, const Range& r);
+
+extern OCTAVE_API Range operator * (const Range& r, double x);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Sparse-C.cc b/liboctave/Sparse-C.cc
new file mode 100644
index 0000000..af0d216
--- /dev/null
+++ b/liboctave/Sparse-C.cc
@@ -0,0 +1,72 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Sparse matrix of complex values.
+
+#include "oct-cmplx.h"
+#include "lo-mappers.h"
+#include "lo-ieee.h"
+#include "Sparse.h"
+#include "Sparse.cc"
+
+
+static double
+xabs (const Complex& x)
+{
+  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
+}
+
+
+template <>
+bool
+sparse_ascending_compare<Complex> (const Complex& a, const Complex& b)
+{
+  return (xisnan (b) || (xabs (a) < xabs (b))
+	  || ((xabs (a) == xabs (b)) && (arg (a) < arg (b))));
+}
+
+template <>
+bool
+sparse_descending_compare<Complex> (const Complex& a, const Complex& b)
+{
+  return (xisnan (a) || (xabs (a) > xabs (b))
+	  || ((xabs (a) == xabs (b)) && (arg (a) > arg (b))));
+}
+
+INSTANTIATE_SPARSE_AND_ASSIGN (Complex, OCTAVE_API);
+
+INSTANTIATE_SPARSE_ASSIGN (Complex, double, OCTAVE_API);
+
+#if 0
+template std::ostream& operator << (std::ostream&, const Sparse<Complex>&);
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Sparse-b.cc b/liboctave/Sparse-b.cc
new file mode 100644
index 0000000..11cdbbe
--- /dev/null
+++ b/liboctave/Sparse-b.cc
@@ -0,0 +1,43 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Sparse matrix of double values.
+
+#include "Sparse.h"
+#include "Sparse.cc"
+
+INSTANTIATE_SPARSE_AND_ASSIGN (bool, OCTAVE_API);
+
+#if 0
+template std::ostream& operator << (std::ostream&, const Sparse<bool>&);
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Sparse-d.cc b/liboctave/Sparse-d.cc
new file mode 100644
index 0000000..5fca047
--- /dev/null
+++ b/liboctave/Sparse-d.cc
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Instantiate Sparse matrix of double values.
+
+#include "lo-mappers.h"
+#include "Sparse.h"
+#include "Sparse.cc"
+
+template <>
+bool
+sparse_ascending_compare<double> (double a, double b)
+{
+  return (xisnan (b) || (a < b));
+}
+
+template <>
+bool
+sparse_descending_compare<double> (double a, double b)
+{
+  return (xisnan (a) || (a > b));
+}
+
+INSTANTIATE_SPARSE_AND_ASSIGN (double, OCTAVE_API);
+
+#if 0
+template std::ostream& operator << (std::ostream&, const Sparse<double>&);
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Sparse-diag-op-defs.h b/liboctave/Sparse-diag-op-defs.h
new file mode 100644
index 0000000..5644052
--- /dev/null
+++ b/liboctave/Sparse-diag-op-defs.h
@@ -0,0 +1,236 @@
+/* -*- C++ -*-
+
+Copyright (C) 2009 Jason Riedy, Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_diag_op_defs_h)
+#define octave_sparse_diag_op_defs_h 1
+
+// Matrix multiplication
+
+template <typename RT, typename DM, typename SM>
+RT do_mul_dm_sm (const DM& d, const SM& a)
+{
+  const octave_idx_type nr = d.rows ();
+  const octave_idx_type nc = d.cols ();
+
+  const octave_idx_type a_nr = a.rows ();
+  const octave_idx_type a_nc = a.cols ();
+
+  if (nc != a_nr)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc);
+      return RT ();
+    }
+  else
+   {
+     RT r (nr, a_nc, a.nnz ());
+
+     octave_idx_type l = 0;
+
+     for (octave_idx_type j = 0; j < a_nc; j++)
+       {
+         r.xcidx (j) = l;
+	 const octave_idx_type colend = a.cidx (j+1);
+         for (octave_idx_type k = a.cidx (j); k < colend; k++)
+           {
+             const octave_idx_type i = a.ridx (k);
+             if (i >= nr) break;
+             r.xdata (l) = d.dgelem (i) * a.data (k);
+             r.xridx (l) = i;
+             l++;
+           }
+       }
+
+     r.xcidx (a_nc) = l;
+
+     r.maybe_compress (true);
+     return r;
+   }
+}
+
+template <typename RT, typename SM, typename DM>
+RT do_mul_sm_dm (const SM& a, const DM& d)
+{
+  const octave_idx_type nr = d.rows ();
+  const octave_idx_type nc = d.cols ();
+
+  const octave_idx_type a_nr = a.rows ();
+  const octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nc)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, nr, nc);
+      return RT ();
+    }
+  else
+   {
+
+     const octave_idx_type mnc = nc < a_nc ? nc: a_nc;
+     RT r (a_nr, nc, a.cidx (mnc));
+
+     for (octave_idx_type j = 0; j < mnc; ++j)
+       {
+	 const typename DM::element_type s = d.dgelem (j);
+	 const octave_idx_type colend = a.cidx (j+1);
+	 r.xcidx (j) = a.cidx (j);
+	 for (octave_idx_type k = a.cidx (j); k < colend; ++k)
+	   {
+	     r.xdata (k) = s * a.data (k);
+	     r.xridx (k) = a.ridx (k);
+	   }
+       }
+     for (octave_idx_type j = mnc; j <= nc; ++j)
+       r.xcidx (j) = a.cidx (mnc);
+
+     r.maybe_compress (true);
+     return r;
+   }
+}
+
+// FIXME: functors such as this should be gathered somewhere
+template <typename T>
+struct identity_val
+  : public std::unary_function <T, T>
+{
+  T operator () (const T x) { return x; }
+};
+
+// Matrix addition
+
+template <typename RT, typename SM, typename DM, typename OpA, typename OpD>
+RT inner_do_add_sm_dm (const SM& a, const DM& d, OpA opa, OpD opd)
+{
+  using std::min;
+  const octave_idx_type nr = d.rows ();
+  const octave_idx_type nc = d.cols ();
+  const octave_idx_type n = min (nr, nc);
+
+  const octave_idx_type a_nr = a.rows ();
+  const octave_idx_type a_nc = a.cols ();
+
+  const octave_idx_type nz = a.nnz ();
+  RT r (a_nr, a_nc, nz + n);
+  octave_idx_type k = 0;
+
+  for (octave_idx_type j = 0; j < nc; ++j)
+    {
+      OCTAVE_QUIT;
+      const octave_idx_type colend = a.cidx (j+1);
+      r.xcidx (j) = k;
+      octave_idx_type k_src = a.cidx (j), k_split;
+
+      for (k_split = k_src; k_split < colend; k_split++)
+        if (a.ridx (k_split) >= j)
+          break;
+
+      for (; k_src < k_split; k_src++, k++)
+        {
+          r.xridx (k) = a.ridx (k_src);
+          r.xdata (k) = opa (a.data (k_src));
+        }
+
+      if (k_src < colend && a.ridx (k_src) == j)
+        {
+          r.xridx (k) = j;
+          r.xdata (k) = opa (a.data (k_src)) + opd (d.dgelem (j));
+          k++; k_src++;
+        }
+      else
+        {
+          r.xridx (k) = j;
+          r.xdata (k) = opd (d.dgelem (j));
+          k++;
+        }
+
+      for (; k_src < colend; k_src++, k++)
+        {
+          r.xridx (k) = a.ridx (k_src);
+          r.xdata (k) = opa (a.data (k_src));
+        }
+
+    }
+  r.xcidx (nc) = k;
+
+  r.maybe_compress (true);
+  return r;
+}
+
+template <typename RT, typename DM, typename SM>
+RT do_commutative_add_dm_sm (const DM& d, const SM& a)
+{
+  // Extra function to ensure this is only emitted once.
+  return inner_do_add_sm_dm<RT> (a, d,
+				 identity_val<typename SM::element_type> (),
+				 identity_val<typename DM::element_type> ());
+}
+
+template <typename RT, typename DM, typename SM>
+RT do_add_dm_sm (const DM& d, const SM& a)
+{
+  if (a.rows () != d.rows () || a.cols () != d.cols ())
+    {
+      gripe_nonconformant ("operator +", d.rows (), d.cols (), a.rows (), a.cols ());
+      return RT ();
+    }
+  else
+    return do_commutative_add_dm_sm<RT> (d, a);
+}
+
+template <typename RT, typename DM, typename SM>
+RT do_sub_dm_sm (const DM& d, const SM& a)
+{
+  if (a.rows () != d.rows () || a.cols () != d.cols ())
+    {
+      gripe_nonconformant ("operator -", d.rows (), d.cols (), a.rows (), a.cols ());
+      return RT ();
+    }
+  else
+    return inner_do_add_sm_dm<RT> (a, d, std::negate<typename SM::element_type> (),
+				   identity_val<typename DM::element_type> ());
+}
+
+template <typename RT, typename SM, typename DM>
+RT do_add_sm_dm (const SM& a, const DM& d)
+{
+  if (a.rows () != d.rows () || a.cols () != d.cols ())
+    {
+      gripe_nonconformant ("operator +", a.rows (), a.cols (), d.rows (), d.cols ());
+      return RT ();
+    }
+  else
+    return do_commutative_add_dm_sm<RT> (d, a);
+}
+
+template <typename RT, typename SM, typename DM>
+RT do_sub_sm_dm (const SM& a, const DM& d)
+{
+  if (a.rows () != d.rows () || a.cols () != d.cols ())
+    {
+      gripe_nonconformant ("operator -", a.rows (), a.cols (), d.rows (), d.cols ());
+      return RT ();
+    }
+  else
+    return inner_do_add_sm_dm<RT> (a, d,
+				   identity_val<typename SM::element_type> (),
+				   std::negate<typename DM::element_type> ());
+}
+
+#endif // octave_sparse_diag_op_defs_h
diff --git a/liboctave/Sparse-op-defs.h b/liboctave/Sparse-op-defs.h
new file mode 100644
index 0000000..8548e3e
--- /dev/null
+++ b/liboctave/Sparse-op-defs.h
@@ -0,0 +1,2154 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_op_defs_h)
+#define octave_sparse_op_defs_h 1
+
+#include "Array-util.h"
+#include "mx-ops.h"
+#include "oct-locbuf.h"
+
+#define SPARSE_BIN_OP_DECL(R, OP, X, Y, API) \
+  extern API R OP (const X&, const Y&)
+
+#define SPARSE_CMP_OP_DECL(OP, X, Y, API) \
+  extern API SparseBoolMatrix OP (const X&, const Y&)
+
+#define SPARSE_BOOL_OP_DECL(OP, X, Y, API) \
+  extern API SparseBoolMatrix OP (const X&, const Y&)
+
+// matrix by scalar operations.
+
+#define SPARSE_SMS_BIN_OP_DECLS(R1, R2, M, S, API)  \
+  SPARSE_BIN_OP_DECL (R1, operator +, M, S, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M, S, API); \
+  SPARSE_BIN_OP_DECL (R2, operator *, M, S, API); \
+  SPARSE_BIN_OP_DECL (R2, operator /, M, S, API);
+
+#define SPARSE_SMS_BIN_OP_1(R, F, OP, M, S)	\
+  R \
+  F (const M& m, const S& s) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    R r (nr, nc, (0.0 OP s)); \
+ \
+    for (octave_idx_type j = 0; j < nc; j++) \
+      for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
+        r.elem (m.ridx (i), j) = m.data (i) OP s; \
+    return r; \
+  }
+
+#define SPARSE_SMS_BIN_OP_2(R, F, OP, M, S)	\
+  R \
+  F (const M& m, const S& s) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+    octave_idx_type nz = m.nnz (); \
+ \
+    R r (nr, nc, nz); \
+ \
+    for (octave_idx_type i = 0; i < nz; i++) \
+      { \
+	r.data(i) = m.data(i) OP s; \
+	r.ridx(i) = m.ridx(i); \
+      } \
+    for (octave_idx_type i = 0; i < nc + 1; i++) \
+      r.cidx(i) = m.cidx(i); \
+    \
+    r.maybe_compress (true); \
+    return r; \
+  }
+
+#define SPARSE_SMS_BIN_OPS(R1, R2, M, S) \
+  SPARSE_SMS_BIN_OP_1 (R1, operator +, +, M, S) \
+  SPARSE_SMS_BIN_OP_1 (R1, operator -, -, M, S) \
+  SPARSE_SMS_BIN_OP_2 (R2, operator *, *, M, S) \
+  SPARSE_SMS_BIN_OP_2 (R2, operator /, /, M, S)
+
+#define SPARSE_SMS_CMP_OP_DECLS(M, S, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M, S, API);
+
+#define SPARSE_SMS_EQNE_OP_DECLS(M, S, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M, S, API);
+
+#define SPARSE_SMS_CMP_OP(F, OP, M, MZ, MC, S, SZ, SC)	\
+  SparseBoolMatrix \
+  F (const M& m, const S& s) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+    SparseBoolMatrix r; \
+    \
+    if (MC (MZ) OP SC (s)) \
+      { \
+        r = SparseBoolMatrix (nr, nc, true); \
+	for (octave_idx_type j = 0; j < nc; j++) \
+	  for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+            if (! (MC (m.data (i)) OP SC (s))) \
+              r.data (m.ridx (i) + j * nr) = false; \
+        r.maybe_compress (true); \
+      } \
+    else \
+      { \
+        r = SparseBoolMatrix (nr, nc, m.nnz ()); \
+        r.cidx (0) = static_cast<octave_idx_type> (0); \
+        octave_idx_type nel = 0; \
+	for (octave_idx_type j = 0; j < nc; j++) \
+          { \
+	    for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+              if (MC (m.data (i)) OP SC (s)) \
+                { \
+                  r.ridx (nel) = m.ridx (i); \
+                  r.data (nel++) = true; \
+                } \
+            r.cidx (j + 1) = nel; \
+          } \
+        r.maybe_compress (false); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SMS_CMP_OPS(M, MZ, CM, S, SZ, CS)	\
+  SPARSE_SMS_CMP_OP (mx_el_lt, <,  M, MZ, CM, S, SZ, CS)	\
+  SPARSE_SMS_CMP_OP (mx_el_le, <=, M, MZ, CM, S, SZ, CS)	\
+  SPARSE_SMS_CMP_OP (mx_el_ge, >=, M, MZ, CM, S, SZ, CS)	\
+  SPARSE_SMS_CMP_OP (mx_el_gt, >,  M, MZ, CM, S, SZ, CS)	\
+  SPARSE_SMS_CMP_OP (mx_el_eq, ==, M, MZ,   , S, SZ,   )	\
+  SPARSE_SMS_CMP_OP (mx_el_ne, !=, M, MZ,   , S, SZ,   )
+
+#define SPARSE_SMS_EQNE_OPS(M, MZ, CM, S, SZ, CS)	\
+  SPARSE_SMS_CMP_OP (mx_el_eq, ==, M, MZ,   , S, SZ,   )	\
+  SPARSE_SMS_CMP_OP (mx_el_ne, !=, M, MZ,   , S, SZ,   )
+
+#define SPARSE_SMS_BOOL_OP_DECLS(M, S, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M, S, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M, S, API);
+
+#define SPARSE_SMS_BOOL_OP(F, OP, M, S, LHS_ZERO, RHS_ZERO) \
+  SparseBoolMatrix \
+  F (const M& m, const S& s) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+    SparseBoolMatrix r; \
+    \
+    if (nr > 0 && nc > 0) \
+      { \
+	if (LHS_ZERO OP (s != RHS_ZERO)) \
+	  { \
+            r = SparseBoolMatrix (nr, nc, true); \
+	    for (octave_idx_type j = 0; j < nc; j++) \
+	      for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+                if (! ((m.data(i) != LHS_ZERO) OP (s != RHS_ZERO))) \
+                  r.data (m.ridx (i) + j * nr) = false; \
+            r.maybe_compress (true); \
+          } \
+	else \
+	  { \
+            r = SparseBoolMatrix (nr, nc, m.nnz ()); \
+            r.cidx (0) = static_cast<octave_idx_type> (0); \
+            octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < nc; j++) \
+              { \
+	        for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+                  if ((m.data(i) != LHS_ZERO) OP (s != RHS_ZERO)) \
+                    { \
+                      r.ridx (nel) = m.ridx (i); \
+                      r.data (nel++) = true; \
+                    } \
+                r.cidx (j + 1) = nel; \
+              } \
+            r.maybe_compress (false); \
+          } \
+      }	\
+    return r; \
+  }
+
+#define SPARSE_SMS_BOOL_OPS2(M, S, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SMS_BOOL_OP (mx_el_and, &&, M, S, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SMS_BOOL_OP (mx_el_or,  ||, M, S, LHS_ZERO, RHS_ZERO)
+
+#define SPARSE_SMS_BOOL_OPS(M, S, ZERO) \
+  SPARSE_SMS_BOOL_OPS2(M, S, ZERO, ZERO)
+
+#define SPARSE_SMS_OP_DECLS(R1, R2, M, S, API) \
+  SPARSE_SMS_BIN_OP_DECLS (R1, R2, M, S, API)	 \
+  SPARSE_SMS_CMP_OP_DECLS (M, S, API) \
+  SPARSE_SMS_BOOL_OP_DECLS (M, S, API)
+
+// scalar by matrix operations.
+
+#define SPARSE_SSM_BIN_OP_DECLS(R1, R2, S, M, API)    \
+  SPARSE_BIN_OP_DECL (R1, operator +, S, M, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, S, M, API); \
+  SPARSE_BIN_OP_DECL (R2, operator *, S, M, API); \
+  SPARSE_BIN_OP_DECL (R2, operator /, S, M, API);
+
+#define SPARSE_SSM_BIN_OP_1(R, F, OP, S, M) \
+  R \
+  F (const S& s, const M& m) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    R r (nr, nc, (s OP 0.0)); \
+ \
+    for (octave_idx_type j = 0; j < nc; j++) \
+      for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
+        r.elem (m.ridx (i), j) = s OP m.data (i); \
+ \
+    return r; \
+  }
+
+#define SPARSE_SSM_BIN_OP_2(R, F, OP, S, M) \
+  R \
+  F (const S& s, const M& m) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+    octave_idx_type nz = m.nnz (); \
+ \
+    R r (nr, nc, nz); \
+ \
+    for (octave_idx_type i = 0; i < nz; i++) \
+      { \
+	r.data(i) = s OP m.data(i); \
+	r.ridx(i) = m.ridx(i); \
+      } \
+    for (octave_idx_type i = 0; i < nc + 1; i++) \
+      r.cidx(i) = m.cidx(i); \
+ \
+    r.maybe_compress(true); \
+    return r; \
+  }
+
+#define SPARSE_SSM_BIN_OPS(R1, R2, S, M) \
+  SPARSE_SSM_BIN_OP_1 (R1, operator +, +, S, M) \
+  SPARSE_SSM_BIN_OP_1 (R1, operator -, -, S, M) \
+  SPARSE_SSM_BIN_OP_2 (R2, operator *, *, S, M) \
+  SPARSE_SSM_BIN_OP_2 (R2, operator /, /, S, M)
+
+#define SPARSE_SSM_CMP_OP_DECLS(S, M, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, S, M, API);
+
+#define SPARSE_SSM_EQNE_OP_DECLS(S, M, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, S, M, API);
+
+#define SPARSE_SSM_CMP_OP(F, OP, S, SZ, SC, M, MZ, MC)	\
+  SparseBoolMatrix \
+  F (const S& s, const M& m) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+    SparseBoolMatrix r; \
+    \
+    if (SC (s) OP SC (MZ)) \
+      { \
+        r = SparseBoolMatrix (nr, nc, true); \
+	for (octave_idx_type j = 0; j < nc; j++) \
+	  for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+            if (! (SC (s) OP MC (m.data (i)))) \
+              r.data (m.ridx (i) + j * nr) = false; \
+        r.maybe_compress (true); \
+      } \
+    else \
+      { \
+        r = SparseBoolMatrix (nr, nc, m.nnz ()); \
+        r.cidx (0) = static_cast<octave_idx_type> (0); \
+        octave_idx_type nel = 0; \
+	for (octave_idx_type j = 0; j < nc; j++) \
+          { \
+	    for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+              if (SC (s) OP MC (m.data (i))) \
+                { \
+                  r.ridx (nel) = m.ridx (i); \
+                  r.data (nel++) = true; \
+                } \
+            r.cidx (j + 1) = nel; \
+          } \
+        r.maybe_compress (false); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SSM_CMP_OPS(S, SZ, SC, M, MZ, MC)	\
+  SPARSE_SSM_CMP_OP (mx_el_lt, <,  S, SZ, SC, M, MZ, MC)	\
+  SPARSE_SSM_CMP_OP (mx_el_le, <=, S, SZ, SC, M, MZ, MC)	\
+  SPARSE_SSM_CMP_OP (mx_el_ge, >=, S, SZ, SC, M, MZ, MC)	\
+  SPARSE_SSM_CMP_OP (mx_el_gt, >,  S, SZ, SC, M, MZ, MC)	\
+  SPARSE_SSM_CMP_OP (mx_el_eq, ==, S, SZ,   , M, MZ,   )	\
+  SPARSE_SSM_CMP_OP (mx_el_ne, !=, S, SZ,   , M, MZ,   )
+
+#define SPARSE_SSM_EQNE_OPS(S, SZ, SC, M, MZ, MC)	\
+  SPARSE_SSM_CMP_OP (mx_el_eq, ==, S, SZ,   , M, MZ,   )	\
+  SPARSE_SSM_CMP_OP (mx_el_ne, !=, S, SZ,   , M, MZ,   )
+
+#define SPARSE_SSM_BOOL_OP_DECLS(S, M, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, S, M, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  S, M, API); \
+
+#define SPARSE_SSM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO) \
+  SparseBoolMatrix \
+  F (const S& s, const M& m) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+    SparseBoolMatrix r; \
+    \
+    if (nr > 0 && nc > 0) \
+      { \
+	if ((s != LHS_ZERO) OP RHS_ZERO) \
+	  { \
+            r = SparseBoolMatrix (nr, nc, true); \
+	    for (octave_idx_type j = 0; j < nc; j++) \
+	      for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+                if (! ((s != LHS_ZERO) OP (m.data(i) != RHS_ZERO))) \
+                  r.data (m.ridx (i) + j * nr) = false; \
+            r.maybe_compress (true); \
+          } \
+	else \
+	  { \
+            r = SparseBoolMatrix (nr, nc, m.nnz ()); \
+            r.cidx (0) = static_cast<octave_idx_type> (0); \
+            octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < nc; j++) \
+              { \
+	        for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
+                  if ((s != LHS_ZERO) OP (m.data(i) != RHS_ZERO)) \
+                    { \
+                      r.ridx (nel) = m.ridx (i); \
+                      r.data (nel++) = true; \
+                    } \
+                r.cidx (j + 1) = nel; \
+              } \
+            r.maybe_compress (false); \
+          } \
+      }	\
+    return r; \
+  }
+
+#define SPARSE_SSM_BOOL_OPS2(S, M, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SSM_BOOL_OP (mx_el_and, &&, S, M, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SSM_BOOL_OP (mx_el_or,  ||, S, M, LHS_ZERO, RHS_ZERO)
+
+#define SPARSE_SSM_BOOL_OPS(S, M, ZERO) \
+  SPARSE_SSM_BOOL_OPS2(S, M, ZERO, ZERO)
+
+#define SPARSE_SSM_OP_DECLS(R1, R2, S, M, API) \
+  SPARSE_SSM_BIN_OP_DECLS (R1, R2, S, M, API)	 \
+  SPARSE_SSM_CMP_OP_DECLS (S, M, API) \
+  SPARSE_SSM_BOOL_OP_DECLS (S, M, API) \
+
+// matrix by matrix operations.
+
+#define SPARSE_SMSM_BIN_OP_DECLS(R1, R2, M1, M2, API)	\
+  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+
+#define SPARSE_SMSM_BIN_OP_1(R, F, OP, M1, M2)	\
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        if (m1.elem(0,0) == 0.) \
+          r = OP R (m2); \
+        else \
+          { \
+	    r = R (m2_nr, m2_nc, m1.data(0) OP 0.); \
+            \
+            for (octave_idx_type j = 0 ; j < m2_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m2_nr; \
+                for (octave_idx_type i = m2.cidx(j) ; i < m2.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m2.ridx(i)) = m1.data(0) OP m2.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        if (m2.elem(0,0) == 0.) \
+          r = R (m1); \
+        else \
+          { \
+	    r = R (m1_nr, m1_nc, 0. OP m2.data(0)); \
+            \
+            for (octave_idx_type j = 0 ; j < m1_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m1_nr; \
+                for (octave_idx_type i = m1.cidx(j) ; i < m1.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m1.ridx(i)) = m1.data(i) OP m2.data(0); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+	r = R (m1_nr, m1_nc, (m1.nnz () + m2.nnz ())); \
+        \
+        octave_idx_type jx = 0; \
+        r.cidx (0) = 0; \
+        for (octave_idx_type i = 0 ; i < m1_nc ; i++) \
+          { \
+            octave_idx_type  ja = m1.cidx(i); \
+            octave_idx_type  ja_max = m1.cidx(i+1); \
+            bool ja_lt_max= ja < ja_max; \
+            \
+            octave_idx_type  jb = m2.cidx(i); \
+            octave_idx_type  jb_max = m2.cidx(i+1); \
+            bool jb_lt_max = jb < jb_max; \
+            \
+            while (ja_lt_max || jb_lt_max ) \
+              { \
+                OCTAVE_QUIT; \
+                if ((! jb_lt_max) || \
+                      (ja_lt_max && (m1.ridx(ja) < m2.ridx(jb)))) \
+                  { \
+                    r.ridx(jx) = m1.ridx(ja); \
+                    r.data(jx) = m1.data(ja) OP 0.; \
+                    jx++; \
+                    ja++; \
+                    ja_lt_max= ja < ja_max; \
+                  } \
+                else if (( !ja_lt_max ) || \
+                     (jb_lt_max && (m2.ridx(jb) < m1.ridx(ja)) ) ) \
+                  { \
+		    r.ridx(jx) = m2.ridx(jb); \
+		    r.data(jx) = 0. OP m2.data(jb); \
+		    jx++; \
+                    jb++; \
+                    jb_lt_max= jb < jb_max; \
+                  } \
+                else \
+                  { \
+		     if ((m1.data(ja) OP m2.data(jb)) != 0.) \
+	               { \
+                          r.data(jx) = m1.data(ja) OP m2.data(jb); \
+                          r.ridx(jx) = m1.ridx(ja); \
+                          jx++; \
+                       } \
+                     ja++; \
+                     ja_lt_max= ja < ja_max; \
+                     jb++; \
+                     jb_lt_max= jb < jb_max; \
+                  } \
+              } \
+            r.cidx(i+1) = jx; \
+          } \
+        \
+	r.maybe_compress (); \
+      } \
+ \
+    return r; \
+  }
+
+#define SPARSE_SMSM_BIN_OP_2(R, F, OP, M1, M2)	\
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        if (m1.elem(0,0) == 0.) \
+          r = R (m2_nr, m2_nc); \
+        else \
+          { \
+	    r = R (m2); \
+            octave_idx_type m2_nnz = m2.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < m2_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = m1.data(0) OP r.data(i); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        if (m2.elem(0,0) == 0.) \
+          r = R (m1_nr, m1_nc); \
+        else \
+          { \
+	    r = R (m1); \
+            octave_idx_type m1_nnz = m1.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < m1_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = r.data(i) OP m2.data(0); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+        r = R (m1_nr, m1_nc, (m1.nnz () > m2.nnz () ? m1.nnz () : m2.nnz ())); \
+        \
+        octave_idx_type jx = 0; \
+	r.cidx (0) = 0; \
+        for (octave_idx_type i = 0 ; i < m1_nc ; i++) \
+          { \
+            octave_idx_type  ja = m1.cidx(i); \
+            octave_idx_type  ja_max = m1.cidx(i+1); \
+            bool ja_lt_max= ja < ja_max; \
+            \
+            octave_idx_type  jb = m2.cidx(i); \
+            octave_idx_type  jb_max = m2.cidx(i+1); \
+            bool jb_lt_max = jb < jb_max; \
+            \
+            while (ja_lt_max || jb_lt_max ) \
+              { \
+                OCTAVE_QUIT; \
+                if ((! jb_lt_max) || \
+                      (ja_lt_max && (m1.ridx(ja) < m2.ridx(jb)))) \
+                  { \
+                     ja++; ja_lt_max= ja < ja_max; \
+                  } \
+                else if (( !ja_lt_max ) || \
+                     (jb_lt_max && (m2.ridx(jb) < m1.ridx(ja)) ) ) \
+                  { \
+                     jb++; jb_lt_max= jb < jb_max; \
+                  } \
+                else \
+                  { \
+		     if ((m1.data(ja) OP m2.data(jb)) != 0.) \
+	               { \
+                          r.data(jx) = m1.data(ja) OP m2.data(jb); \
+                          r.ridx(jx) = m1.ridx(ja); \
+                          jx++; \
+                       } \
+                     ja++; ja_lt_max= ja < ja_max; \
+                     jb++; jb_lt_max= jb < jb_max; \
+                  } \
+              } \
+            r.cidx(i+1) = jx; \
+          } \
+        \
+	r.maybe_compress (); \
+      } \
+ \
+    return r; \
+  }
+
+#define SPARSE_SMSM_BIN_OP_3(R, F, OP, M1, M2)	\
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        if ((m1.elem (0,0) OP Complex()) == Complex()) \
+          { \
+            octave_idx_type m2_nnz = m2.nnz(); \
+            r = R (m2); \
+            for (octave_idx_type i = 0 ; i < m2_nnz ; i++) \
+              r.data (i) = m1.elem(0,0) OP r.data(i); \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = R (m2_nr, m2_nc, m1.elem(0,0) OP Complex ()); \
+            for (octave_idx_type j = 0 ; j < m2_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m2_nr; \
+                for (octave_idx_type i = m2.cidx(j) ; i < m2.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m2.ridx(i)) = m1.elem(0,0) OP m2.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        if ((Complex() OP m1.elem (0,0)) == Complex()) \
+          { \
+            octave_idx_type m1_nnz = m1.nnz(); \
+            r = R (m1); \
+            for (octave_idx_type i = 0 ; i < m1_nnz ; i++) \
+              r.data (i) = r.data(i) OP m2.elem(0,0); \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = R (m1_nr, m1_nc, Complex() OP m2.elem(0,0)); \
+            for (octave_idx_type j = 0 ; j < m1_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m1_nr; \
+                for (octave_idx_type i = m1.cidx(j) ; i < m1.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m1.ridx(i)) = m1.data(i) OP m2.elem(0,0); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+ \
+        /* FIXME Kludge... Always double/Complex, so Complex () */ \
+        r = R (m1_nr, m1_nc, (Complex () OP Complex ())); \
+        \
+        for (octave_idx_type i = 0 ; i < m1_nc ; i++) \
+          { \
+            octave_idx_type  ja = m1.cidx(i); \
+            octave_idx_type  ja_max = m1.cidx(i+1); \
+            bool ja_lt_max= ja < ja_max; \
+            \
+            octave_idx_type  jb = m2.cidx(i); \
+            octave_idx_type  jb_max = m2.cidx(i+1); \
+            bool jb_lt_max = jb < jb_max; \
+            \
+            while (ja_lt_max || jb_lt_max ) \
+              { \
+                OCTAVE_QUIT; \
+                if ((! jb_lt_max) || \
+                      (ja_lt_max && (m1.ridx(ja) < m2.ridx(jb)))) \
+                  { \
+		    /* keep those kludges coming */ \
+                    r.elem(m1.ridx(ja),i) = m1.data(ja) OP Complex (); \
+                    ja++; \
+                    ja_lt_max= ja < ja_max; \
+                  } \
+                else if (( !ja_lt_max ) || \
+                     (jb_lt_max && (m2.ridx(jb) < m1.ridx(ja)) ) ) \
+                  { \
+		    /* keep those kludges coming */ \
+                    r.elem(m2.ridx(jb),i) = Complex () OP m2.data(jb);	\
+                    jb++; \
+                    jb_lt_max= jb < jb_max; \
+                  } \
+                else \
+                  { \
+                    r.elem(m1.ridx(ja),i) = m1.data(ja) OP m2.data(jb); \
+                    ja++; \
+                    ja_lt_max= ja < ja_max; \
+                    jb++; \
+                    jb_lt_max= jb < jb_max; \
+                  } \
+              } \
+          } \
+	r.maybe_compress (true); \
+      } \
+ \
+    return r; \
+  }
+
+// Note that SM ./ SM needs to take into account the NaN and Inf values
+// implied by the division by zero.
+// FIXME Are the NaNs double(NaN) or Complex(NaN,Nan) in the complex
+// case?
+#define SPARSE_SMSM_BIN_OPS(R1, R2, M1, M2)  \
+  SPARSE_SMSM_BIN_OP_1 (R1, operator +,  +, M1, M2) \
+  SPARSE_SMSM_BIN_OP_1 (R1, operator -,  -, M1, M2) \
+  SPARSE_SMSM_BIN_OP_2 (R2, product,     *, M1, M2) \
+  SPARSE_SMSM_BIN_OP_3 (R2, quotient,    /, M1, M2)
+
+#define SPARSE_SMSM_CMP_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMSM_EQNE_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+// FIXME -- this macro duplicatest the bodies of the template
+// functions defined in the SPARSE_SSM_CMP_OP and SPARSE_SMS_CMP_OP
+// macros.
+
+#define SPARSE_SMSM_CMP_OP(F, OP, M1, Z1, C1, M2, Z2, C2)	\
+  SparseBoolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    SparseBoolMatrix r; \
+    \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+    \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+    \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+    if (C1 (m1.elem(0,0)) OP C2 (Z2)) \
+	  { \
+	    r = SparseBoolMatrix (m2_nr, m2_nc, true); \
+	    for (octave_idx_type j = 0; j < m2_nc; j++) \
+	      for (octave_idx_type i = m2.cidx(j); i < m2.cidx(j+1); i++) \
+		if (! (C1 (m1.elem (0,0)) OP C2 (m2.data(i)))) \
+		  r.data (m2.ridx (i) + j * m2_nr) = false; \
+	    r.maybe_compress (true); \
+	  } \
+	else \
+	  { \
+	    r = SparseBoolMatrix (m2_nr, m2_nc, m2.nnz ()); \
+	    r.cidx (0) = static_cast<octave_idx_type> (0); \
+	    octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m2_nc; j++) \
+	      { \
+		for (octave_idx_type i = m2.cidx(j); i < m2.cidx(j+1); i++) \
+		  if (C1 (m1.elem (0,0)) OP C2 (m2.data(i))) \
+		    { \
+		      r.ridx (nel) = m2.ridx (i); \
+		      r.data (nel++) = true; \
+		    } \
+		r.cidx (j + 1) = nel; \
+	      }	\
+	    r.maybe_compress (false); \
+	  } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+	if (C1 (Z1) OP C2 (m2.elem (0,0))) \
+	  { \
+	    r = SparseBoolMatrix (m1_nr, m1_nc, true); \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      for (octave_idx_type i = m1.cidx(j); i < m1.cidx(j+1); i++) \
+		if (! (C1 (m1.data (i)) OP C2 (m2.elem(0,0)))) \
+		  r.data (m1.ridx (i) + j * m1_nr) = false; \
+	    r.maybe_compress (true); \
+	  } \
+	else \
+	  { \
+	    r = SparseBoolMatrix (m1_nr, m1_nc, m1.nnz ()); \
+	    r.cidx (0) = static_cast<octave_idx_type> (0); \
+	    octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      { \
+		for (octave_idx_type i = m1.cidx(j); i < m1.cidx(j+1); i++) \
+		  if (C1 (m1.data (i)) OP C2 (m2.elem(0,0))) \
+		    { \
+		      r.ridx (nel) = m1.ridx (i); \
+		      r.data (nel++) = true; \
+		    } \
+		r.cidx (j + 1) = nel; \
+	      }	\
+	    r.maybe_compress (false); \
+	  } \
+      } \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+            if (C1 (Z1) OP C2 (Z2)) \
+	      { \
+                r = SparseBoolMatrix (m1_nr, m1_nc, true); \
+	        for (octave_idx_type j = 0; j < m1_nc; j++) \
+                  { \
+                     octave_idx_type i1 = m1.cidx (j); \
+                     octave_idx_type e1 = m1.cidx (j+1); \
+                     octave_idx_type i2 = m2.cidx (j); \
+                     octave_idx_type e2 = m2.cidx (j+1); \
+                     while (i1 < e1 || i2 < e2) \
+                       { \
+                         if (i1 == e1 || (i2 < e2 && m1.ridx(i1) > m2.ridx(i2))) \
+                           { \
+                             if (! (C1 (Z1) OP C2 (m2.data (i2)))) \
+                               r.data (m2.ridx (i2) + j * m1_nr) = false; \
+                             i2++; \
+                           } \
+                         else if (i2 == e2 || m1.ridx(i1) < m2.ridx(i2)) \
+                           { \
+                             if (! (C1 (m1.data (i1)) OP C2 (Z2))) \
+                               r.data (m1.ridx (i1) + j * m1_nr) = false; \
+                             i1++; \
+                           } \
+                         else \
+                           { \
+                             if (! (C1 (m1.data (i1)) OP C2 (m2.data (i2)))) \
+                               r.data (m1.ridx (i1) + j * m1_nr) = false; \
+                             i1++; \
+                             i2++; \
+                           } \
+                       } \
+                  } \
+                r.maybe_compress (true); \
+              } \
+            else \
+              { \
+                r = SparseBoolMatrix (m1_nr, m1_nc, m1.nnz () + m2.nnz ()); \
+                r.cidx (0) = static_cast<octave_idx_type> (0); \
+                octave_idx_type nel = 0; \
+	        for (octave_idx_type j = 0; j < m1_nc; j++) \
+                  { \
+                     octave_idx_type i1 = m1.cidx (j); \
+                     octave_idx_type e1 = m1.cidx (j+1); \
+                     octave_idx_type i2 = m2.cidx (j); \
+                     octave_idx_type e2 = m2.cidx (j+1); \
+                     while (i1 < e1 || i2 < e2) \
+                       { \
+                         if (i1 == e1 || (i2 < e2 && m1.ridx(i1) > m2.ridx(i2))) \
+                           { \
+                             if (C1 (Z1) OP C2 (m2.data (i2))) \
+                               { \
+                                 r.ridx (nel) = m2.ridx (i2); \
+                                 r.data (nel++) = true; \
+                               } \
+                             i2++; \
+                           } \
+                         else if (i2 == e2 || m1.ridx(i1) < m2.ridx(i2)) \
+                           { \
+                             if (C1 (m1.data (i1)) OP C2 (Z2)) \
+                               { \
+                                 r.ridx (nel) = m1.ridx (i1); \
+                                 r.data (nel++) = true; \
+                               } \
+                             i1++; \
+                           } \
+                         else \
+                           { \
+                             if (C1 (m1.data (i1)) OP C2 (m2.data (i2))) \
+                               { \
+                                 r.ridx (nel) = m1.ridx (i1); \
+                                 r.data (nel++) = true; \
+                               } \
+                             i1++; \
+                             i2++; \
+                           } \
+                       } \
+                     r.cidx (j + 1) = nel; \
+                  } \
+                r.maybe_compress (false); \
+              } \
+	  } \
+      }	      \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SMSM_CMP_OPS(M1, Z1, C1, M2, Z2, C2)  \
+  SPARSE_SMSM_CMP_OP (mx_el_lt, <,  M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_le, <=, M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_ge, >=, M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_gt, >,  M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1, Z1,   , M2, Z2,   ) \
+  SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1, Z1,   , M2, Z2,   )
+
+#define SPARSE_SMSM_EQNE_OPS(M1, Z1, C1, M2, Z2, C2)  \
+  SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1, Z1,   , M2, Z2,   ) \
+  SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1, Z1,   , M2, Z2,   )
+
+#define SPARSE_SMSM_BOOL_OP_DECLS(M1, M2, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+// FIXME -- this macro duplicatest the bodies of the template
+// functions defined in the SPARSE_SSM_BOOL_OP and SPARSE_SMS_BOOL_OP
+// macros.
+
+#define SPARSE_SMSM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
+  SparseBoolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    SparseBoolMatrix r; \
+    \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+    \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+    \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+	if (m2_nr > 0 && m2_nc > 0) \
+	  { \
+	    if ((m1.elem(0,0) != LHS_ZERO) OP RHS_ZERO)	\
+	      { \
+		r = SparseBoolMatrix (m2_nr, m2_nc, true); \
+		for (octave_idx_type j = 0; j < m2_nc; j++) \
+		  for (octave_idx_type i = m2.cidx(j); i < m2.cidx(j+1); i++) \
+		    if (! ((m1.elem(0,0) != LHS_ZERO) OP (m2.data(i) != RHS_ZERO))) \
+		      r.data (m2.ridx (i) + j * m2_nr) = false; \
+		r.maybe_compress (true); \
+	      } \
+	    else \
+	      { \
+		r = SparseBoolMatrix (m2_nr, m2_nc, m2.nnz ()); \
+		r.cidx (0) = static_cast<octave_idx_type> (0); \
+		octave_idx_type nel = 0; \
+		for (octave_idx_type j = 0; j < m2_nc; j++) \
+		  { \
+		    for (octave_idx_type i = m2.cidx(j); i < m2.cidx(j+1); i++) \
+		      if ((m1.elem(0,0) != LHS_ZERO) OP (m2.data(i) != RHS_ZERO)) \
+			{ \
+			  r.ridx (nel) = m2.ridx (i); \
+			  r.data (nel++) = true; \
+			} \
+		    r.cidx (j + 1) = nel; \
+		  } \
+		r.maybe_compress (false); \
+	      } \
+	  } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+	if (m1_nr > 0 && m1_nc > 0) \
+	  { \
+	    if (LHS_ZERO OP (m2.elem(0,0) != RHS_ZERO)) \
+	      { \
+		r = SparseBoolMatrix (m1_nr, m1_nc, true); \
+		for (octave_idx_type j = 0; j < m1_nc; j++) \
+		  for (octave_idx_type i = m1.cidx(j); i < m1.cidx(j+1); i++) \
+		    if (! ((m1.data(i) != LHS_ZERO) OP (m2.elem(0,0) != RHS_ZERO))) \
+		      r.data (m1.ridx (i) + j * m1_nr) = false; \
+		r.maybe_compress (true); \
+	      } \
+	    else \
+	      { \
+		r = SparseBoolMatrix (m1_nr, m1_nc, m1.nnz ()); \
+		r.cidx (0) = static_cast<octave_idx_type> (0); \
+		octave_idx_type nel = 0; \
+		for (octave_idx_type j = 0; j < m1_nc; j++) \
+		  { \
+		    for (octave_idx_type i = m1.cidx(j); i < m1.cidx(j+1); i++) \
+		      if ((m1.data(i) != LHS_ZERO) OP (m2.elem(0,0) != RHS_ZERO)) \
+			{ \
+			  r.ridx (nel) = m1.ridx (i); \
+			  r.data (nel++) = true; \
+			} \
+		    r.cidx (j + 1) = nel; \
+		  } \
+		r.maybe_compress (false); \
+	      } \
+	  } \
+      } \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+            r = SparseBoolMatrix (m1_nr, m1_nc, m1.nnz () + m2.nnz ()); \
+            r.cidx (0) = static_cast<octave_idx_type> (0); \
+            octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+              { \
+                octave_idx_type i1 = m1.cidx (j); \
+                octave_idx_type e1 = m1.cidx (j+1); \
+                octave_idx_type i2 = m2.cidx (j); \
+                octave_idx_type e2 = m2.cidx (j+1); \
+                while (i1 < e1 || i2 < e2) \
+                  { \
+                    if (i1 == e1 || (i2 < e2 && m1.ridx(i1) > m2.ridx(i2))) \
+                      { \
+                        if (LHS_ZERO OP m2.data (i2) != RHS_ZERO) \
+                          { \
+                            r.ridx (nel) = m2.ridx (i2); \
+                            r.data (nel++) = true; \
+                          } \
+                        i2++; \
+                      } \
+                    else if (i2 == e2 || m1.ridx(i1) < m2.ridx(i2)) \
+                      { \
+                        if (m1.data (i1) != LHS_ZERO OP RHS_ZERO) \
+                          { \
+                            r.ridx (nel) = m1.ridx (i1); \
+                            r.data (nel++) = true; \
+                          } \
+                        i1++; \
+                      } \
+                    else \
+                      { \
+                        if (m1.data (i1) != LHS_ZERO OP m2.data(i2) != RHS_ZERO) \
+                          { \
+                            r.ridx (nel) = m1.ridx (i1); \
+                            r.data (nel++) = true; \
+                          } \
+                        i1++; \
+                        i2++; \
+                      } \
+                  } \
+                r.cidx (j + 1) = nel; \
+              } \
+            r.maybe_compress (false); \
+	  } \
+      }	      \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SMSM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SMSM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SMSM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO) \
+
+#define SPARSE_SMSM_BOOL_OPS(M1, M2, ZERO) \
+  SPARSE_SMSM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+
+#define SPARSE_SMSM_OP_DECLS(R1, R2, M1, M2, API) \
+  SPARSE_SMSM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
+  SPARSE_SMSM_CMP_OP_DECLS (M1, M2, API) \
+  SPARSE_SMSM_BOOL_OP_DECLS (M1, M2, API)
+
+// matrix by matrix operations.
+
+#define SPARSE_MSM_BIN_OP_DECLS(R1, R2, M1, M2, API)	\
+  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+
+#define SPARSE_MSM_BIN_OP_1(R, F, OP, M1, M2)	\
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m2_nr == 1 && m2_nc == 1) \
+      r = R (m1 OP m2.elem(0,0)); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+        r = R (m1_nr, m1_nc); \
+        \
+        for (octave_idx_type j = 0; j < m1_nc; j++) \
+	  for (octave_idx_type i = 0; i < m1_nr; i++) \
+	    r.elem (i, j) = m1.elem (i, j) OP m2.elem (i, j); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_MSM_BIN_OP_2(R, F, OP, M1, M2, ZERO) \
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m2_nr == 1 && m2_nc == 1) \
+      r = R (m1 OP m2.elem(0,0)); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+	/* Count num of non-zero elements */ \
+	octave_idx_type nel = 0; \
+	for (octave_idx_type j = 0; j < m1_nc; j++) \
+	  for (octave_idx_type i = 0; i < m1_nr; i++) \
+	    if ((m1.elem(i, j) OP m2.elem(i, j)) != ZERO) \
+	      nel++; \
+	\
+        r = R (m1_nr, m1_nc, nel); \
+        \
+	octave_idx_type ii = 0; \
+	r.cidx (0) = 0; \
+        for (octave_idx_type j = 0 ; j < m1_nc ; j++) \
+          { \
+	    for (octave_idx_type i = 0 ; i < m1_nr ; i++)	\
+	      {	\
+	        if ((m1.elem(i, j) OP m2.elem(i, j)) != ZERO) \
+		  { \
+		    r.data (ii) = m1.elem(i, j) OP m2.elem(i,j); \
+		    r.ridx (ii++) = i; \
+		  } \
+	      } \
+	    r.cidx(j+1) = ii; \
+	  } \
+      } \
+ \
+    return r; \
+  }
+
+// FIXME Pass a specific ZERO value
+#define SPARSE_MSM_BIN_OPS(R1, R2, M1, M2) \
+  SPARSE_MSM_BIN_OP_1 (R1, operator +,  +, M1, M2) \
+  SPARSE_MSM_BIN_OP_1 (R1, operator -,  -, M1, M2) \
+  SPARSE_MSM_BIN_OP_2 (R2, product,     *, M1, M2, 0.0) \
+  SPARSE_MSM_BIN_OP_2 (R2, quotient,    /, M1, M2, 0.0)
+
+#define SPARSE_MSM_CMP_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_MSM_EQNE_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_MSM_CMP_OP(F, OP, M1, C1, M2, C2)	\
+  SparseBoolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    SparseBoolMatrix r; \
+    \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+    \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+    \
+    if (m2_nr == 1 && m2_nc == 1) \
+      r = SparseBoolMatrix (F (m1, m2.elem(0,0))); \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+	    /* Count num of non-zero elements */ \
+	    octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      for (octave_idx_type i = 0; i < m1_nr; i++) \
+		if (C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j))) \
+		  nel++; \
+            \
+            r = SparseBoolMatrix (m1_nr, m1_nc, nel); \
+            \
+	    octave_idx_type ii = 0; \
+	    r.cidx (0) = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      { \
+	        for (octave_idx_type i = 0; i < m1_nr; i++) \
+		  { \
+		    bool el = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \
+		    if (el) \
+		      { \
+			r.data(ii) = el; \
+			r.ridx(ii++) = i; \
+		      } \
+		  } \
+		r.cidx(j+1) = ii; \
+	      } \
+	  } \
+      }	      \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_MSM_CMP_OPS(M1, Z1, C1, M2, Z2, C2)  \
+  SPARSE_MSM_CMP_OP (mx_el_lt, <,  M1, C1, M2, C2) \
+  SPARSE_MSM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \
+  SPARSE_MSM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \
+  SPARSE_MSM_CMP_OP (mx_el_gt, >,  M1, C1, M2, C2) \
+  SPARSE_MSM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
+  SPARSE_MSM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+
+#define SPARSE_MSM_EQNE_OPS(M1, Z1, C1, M2, Z2, C2)  \
+  SPARSE_MSM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
+  SPARSE_MSM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+
+#define SPARSE_MSM_BOOL_OP_DECLS(M1, M2, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+#define SPARSE_MSM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
+  SparseBoolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    SparseBoolMatrix r; \
+    \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+    \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+    \
+    if (m2_nr == 1 && m2_nc == 1) \
+      r = SparseBoolMatrix  (F (m1, m2.elem(0,0))); \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+	    /* Count num of non-zero elements */ \
+	    octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      for (octave_idx_type i = 0; i < m1_nr; i++) \
+		if ((m1.elem(i, j) != LHS_ZERO) \
+		    OP (m2.elem(i, j) != RHS_ZERO)) \
+		  nel++; \
+            \
+            r = SparseBoolMatrix (m1_nr, m1_nc, nel); \
+            \
+	    octave_idx_type ii = 0; \
+	    r.cidx (0) = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      { \
+	        for (octave_idx_type i = 0; i < m1_nr; i++) \
+		  { \
+		    bool el = (m1.elem(i, j) != LHS_ZERO) \
+		      OP (m2.elem(i, j) != RHS_ZERO);	  \
+		    if (el) \
+		      { \
+			r.data(ii) = el; \
+			r.ridx(ii++) = i; \
+		      } \
+		  } \
+		r.cidx(j+1) = ii; \
+	      } \
+	  } \
+      }	      \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_MSM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \
+  SPARSE_MSM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \
+  SPARSE_MSM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO) \
+
+#define SPARSE_MSM_BOOL_OPS(M1, M2, ZERO) \
+  SPARSE_MSM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+
+#define SPARSE_MSM_OP_DECLS(R1, R2, M1, M2, API) \
+  SPARSE_MSM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
+  SPARSE_MSM_CMP_OP_DECLS (M1, M2, API) \
+  SPARSE_MSM_BOOL_OP_DECLS (M1, M2, API)
+
+// matrix by matrix operations.
+
+#define SPARSE_SMM_BIN_OP_DECLS(R1, R2, M1, M2, API)	\
+  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+
+#define SPARSE_SMM_BIN_OP_1(R, F, OP, M1, M2)	\
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == 1 && m1_nc == 1) \
+      r = R (m1.elem(0,0) OP m2); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+        r = R (m1_nr, m1_nc); \
+        \
+        for (octave_idx_type j = 0; j < m1_nc; j++) \
+	  for (octave_idx_type i = 0; i < m1_nr; i++) \
+	    r.elem (i, j) = m1.elem (i, j) OP m2.elem (i, j); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SMM_BIN_OP_2(R, F, OP, M1, M2, ZERO) \
+  R \
+  F (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == 1 && m1_nc == 1) \
+      r = R (m1.elem(0,0) OP m2); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+	/* Count num of non-zero elements */ \
+	octave_idx_type nel = 0; \
+	for (octave_idx_type j = 0; j < m1_nc; j++) \
+	  for (octave_idx_type i = 0; i < m1_nr; i++) \
+	    if ((m1.elem(i, j) OP m2.elem(i, j)) != ZERO) \
+	      nel++; \
+	\
+        r = R (m1_nr, m1_nc, nel); \
+        \
+	octave_idx_type ii = 0; \
+	r.cidx (0) = 0; \
+        for (octave_idx_type j = 0 ; j < m1_nc ; j++) \
+          { \
+	    for (octave_idx_type i = 0 ; i < m1_nr ; i++)	\
+	      {	\
+	        if ((m1.elem(i, j) OP m2.elem(i, j)) != ZERO) \
+		  { \
+		    r.data (ii) = m1.elem(i, j) OP m2.elem(i,j); \
+		    r.ridx (ii++) = i; \
+		  } \
+	      } \
+	    r.cidx(j+1) = ii; \
+	  } \
+      } \
+ \
+    return r; \
+  }
+
+// FIXME Pass a specific ZERO value
+#define SPARSE_SMM_BIN_OPS(R1, R2, M1, M2) \
+  SPARSE_SMM_BIN_OP_1 (R1, operator +,  +, M1, M2) \
+  SPARSE_SMM_BIN_OP_1 (R1, operator -,  -, M1, M2) \
+  SPARSE_SMM_BIN_OP_2 (R2, product,     *, M1, M2, 0.0) \
+  SPARSE_SMM_BIN_OP_2 (R2, quotient,    /, M1, M2, 0.0)
+
+#define SPARSE_SMM_CMP_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMM_EQNE_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMM_CMP_OP(F, OP, M1, C1, M2, C2)	\
+  SparseBoolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    SparseBoolMatrix r; \
+    \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+    \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+    \
+    if (m1_nr == 1 && m1_nc == 1) \
+      r = SparseBoolMatrix (F (m1.elem(0,0), m2)); \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+	    /* Count num of non-zero elements */ \
+	    octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      for (octave_idx_type i = 0; i < m1_nr; i++) \
+		if (C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j))) \
+		  nel++; \
+            \
+            r = SparseBoolMatrix (m1_nr, m1_nc, nel); \
+            \
+	    octave_idx_type ii = 0; \
+	    r.cidx (0) = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      { \
+	        for (octave_idx_type i = 0; i < m1_nr; i++) \
+		  { \
+		    bool el = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \
+		    if (el) \
+		      { \
+			r.data(ii) = el; \
+			r.ridx(ii++) = i; \
+		      } \
+		  } \
+		r.cidx(j+1) = ii; \
+	      } \
+	  } \
+      }	      \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SMM_CMP_OPS(M1, Z1, C1, M2, Z2, C2)  \
+  SPARSE_SMM_CMP_OP (mx_el_lt, <,  M1, C1, M2, C2) \
+  SPARSE_SMM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \
+  SPARSE_SMM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \
+  SPARSE_SMM_CMP_OP (mx_el_gt, >,  M1, C1, M2, C2) \
+  SPARSE_SMM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
+  SPARSE_SMM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+
+#define SPARSE_SMM_EQNE_OPS(M1, Z1, C1, M2, Z2, C2)  \
+  SPARSE_SMM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
+  SPARSE_SMM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+
+#define SPARSE_SMM_BOOL_OP_DECLS(M1, M2, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+#define SPARSE_SMM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
+  SparseBoolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    SparseBoolMatrix r; \
+    \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+    \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+    \
+    if (m1_nr == 1 && m1_nc == 1) \
+      r = SparseBoolMatrix (F (m1.elem(0,0), m2)); \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+	    /* Count num of non-zero elements */ \
+	    octave_idx_type nel = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      for (octave_idx_type i = 0; i < m1_nr; i++) \
+		if ((m1.elem(i, j) != LHS_ZERO) \
+		    OP (m2.elem(i, j) != RHS_ZERO)) \
+		  nel++; \
+            \
+            r = SparseBoolMatrix (m1_nr, m1_nc, nel); \
+            \
+	    octave_idx_type ii = 0; \
+	    r.cidx (0) = 0; \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      { \
+	        for (octave_idx_type i = 0; i < m1_nr; i++) \
+		  { \
+		    bool el = (m1.elem(i, j) != LHS_ZERO) \
+		      OP (m2.elem(i, j) != RHS_ZERO);	  \
+		    if (el) \
+		      { \
+			r.data(ii) = el; \
+			r.ridx(ii++) = i; \
+		      } \
+		  } \
+		r.cidx(j+1) = ii; \
+	      } \
+	  } \
+      }	      \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+    return r; \
+  }
+
+#define SPARSE_SMM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SMM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \
+  SPARSE_SMM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO) \
+
+#define SPARSE_SMM_BOOL_OPS(M1, M2, ZERO) \
+  SPARSE_SMM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+
+#define SPARSE_SMM_OP_DECLS(R1, R2, M1, M2, API) \
+  SPARSE_SMM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
+  SPARSE_SMM_CMP_OP_DECLS (M1, M2, API) \
+  SPARSE_SMM_BOOL_OP_DECLS (M1, M2, API)
+
+// Avoid some code duplication.  Maybe we should use templates.
+
+#define SPARSE_CUMSUM(RET_TYPE, ELT_TYPE, FCN)	\
+ \
+  octave_idx_type nr = rows (); \
+  octave_idx_type nc = cols (); \
+ \
+  RET_TYPE retval; \
+ \
+  if (nr > 0 && nc > 0) \
+    { \
+      if ((nr == 1 && dim == -1) || dim == 1) \
+	/* Ugly!! Is there a better way? */ \
+        retval = transpose (). FCN (0) .transpose (); \
+      else \
+	{ \
+          octave_idx_type nel = 0; \
+	  for (octave_idx_type i = 0; i < nc; i++) \
+            { \
+              ELT_TYPE t = ELT_TYPE (); \
+	      for (octave_idx_type j = cidx (i); j < cidx (i+1); j++)	\
+                { \
+                  t += data(j); \
+                  if (t != ELT_TYPE ()) \
+		    { \
+                      if (j == cidx(i+1) - 1) \
+			nel += nr - ridx(j);  \
+		      else \
+			nel += ridx(j+1) - ridx(j); \
+		    } \
+                } \
+	    } \
+	  retval = RET_TYPE (nr, nc, nel); \
+          retval.cidx(0) = 0; \
+	  octave_idx_type ii = 0; \
+	  for (octave_idx_type i = 0; i < nc; i++) \
+            { \
+              ELT_TYPE t = ELT_TYPE (); \
+	      for (octave_idx_type j = cidx (i); j < cidx (i+1); j++)	\
+                { \
+                  t += data(j); \
+                  if (t != ELT_TYPE ()) \
+                    { \
+                      if (j == cidx(i+1) - 1) \
+                        { \
+                          for (octave_idx_type k = ridx(j); k < nr; k++) \
+                            { \
+                               retval.data (ii) = t; \
+                               retval.ridx (ii++) = k; \
+                            } \
+                        } \
+		      else \
+			{ \
+                          for (octave_idx_type k = ridx(j); k < ridx(j+1); k++) \
+                            { \
+                               retval.data (ii) = t; \
+                               retval.ridx (ii++) = k; \
+                            } \
+                        } \
+                    } \
+                } \
+              retval.cidx(i+1) = ii; \
+	    } \
+	} \
+    } \
+  else \
+    retval = RET_TYPE (nr,nc); \
+ \
+  return retval
+
+
+#define SPARSE_CUMPROD(RET_TYPE, ELT_TYPE, FCN)	\
+ \
+  octave_idx_type nr = rows (); \
+  octave_idx_type nc = cols (); \
+ \
+  RET_TYPE retval; \
+ \
+  if (nr > 0 && nc > 0) \
+    { \
+      if ((nr == 1 && dim == -1) || dim == 1) \
+	/* Ugly!! Is there a better way? */ \
+        retval = transpose (). FCN (0) .transpose (); \
+      else \
+	{ \
+          octave_idx_type nel = 0; \
+	  for (octave_idx_type i = 0; i < nc; i++) \
+            { \
+	      octave_idx_type jj = 0; \
+	      for (octave_idx_type j = cidx (i); j < cidx (i+1); j++) \
+                { \
+		  if (jj == ridx(j)) \
+                    { \
+                      nel++; \
+                      jj++; \
+                    } \
+                  else \
+                    break; \
+                } \
+	    } \
+	  retval = RET_TYPE (nr, nc, nel); \
+          retval.cidx(0) = 0; \
+	  octave_idx_type ii = 0; \
+	  for (octave_idx_type i = 0; i < nc; i++) \
+            { \
+              ELT_TYPE t = ELT_TYPE (1.); \
+	      octave_idx_type jj = 0; \
+	      for (octave_idx_type j = cidx (i); j < cidx (i+1); j++) \
+                { \
+		  if (jj == ridx(j)) \
+                    { \
+                      t *= data(j); \
+                      retval.data(ii) = t; \
+                      retval.ridx(ii++) = jj++; \
+                    } \
+                  else \
+                    break; \
+                } \
+              retval.cidx(i+1) = ii; \
+	    } \
+	} \
+    } \
+  else \
+    retval = RET_TYPE (nr,nc); \
+ \
+  return retval
+
+#define SPARSE_BASE_REDUCTION_OP(RET_TYPE, EL_TYPE, ROW_EXPR, COL_EXPR, \
+			         INIT_VAL, MT_RESULT) \
+ \
+  octave_idx_type nr = rows (); \
+  octave_idx_type nc = cols (); \
+ \
+  RET_TYPE retval; \
+ \
+  if (nr > 0 && nc > 0) \
+    { \
+      if ((nr == 1 && dim == -1) || dim == 1) \
+	{ \
+          /* Define j here to allow fancy definition for prod method */ \
+          octave_idx_type j = 0; \
+	  OCTAVE_LOCAL_BUFFER (EL_TYPE, tmp, nr); \
+          \
+	  for (octave_idx_type i = 0; i < nr; i++) \
+	    tmp[i] = INIT_VAL; \
+	  for (j = 0; j < nc; j++) \
+            { \
+	      for (octave_idx_type i = cidx(j); i < cidx(j + 1); i++) \
+                { \
+	          ROW_EXPR; \
+                } \
+	    } \
+	  octave_idx_type nel = 0; \
+	  for (octave_idx_type i = 0; i < nr; i++) \
+	    if (tmp[i] != EL_TYPE ())  \
+	      nel++ ; \
+	  retval = RET_TYPE (nr, static_cast<octave_idx_type> (1), nel); \
+	  retval.cidx(0) = 0; \
+	  retval.cidx(1) = nel; \
+	  nel = 0; \
+	  for (octave_idx_type i = 0; i < nr; i++) \
+	    if (tmp[i] != EL_TYPE ())  \
+	      { \
+		retval.data(nel) = tmp[i]; \
+		retval.ridx(nel++) = i; \
+	      } \
+	} \
+      else \
+	{ \
+	  OCTAVE_LOCAL_BUFFER (EL_TYPE, tmp, nc); \
+          \
+	  for (octave_idx_type j = 0; j < nc; j++) \
+	    { \
+	      tmp[j] = INIT_VAL; \
+	      for (octave_idx_type i = cidx(j); i < cidx(j + 1); i++) \
+                { \
+		  COL_EXPR; \
+                } \
+	    } \
+	  octave_idx_type nel = 0; \
+	  for (octave_idx_type i = 0; i < nc; i++) \
+	    if (tmp[i] != EL_TYPE ())  \
+	      nel++ ; \
+	  retval = RET_TYPE (static_cast<octave_idx_type> (1), nc, nel); \
+	  retval.cidx(0) = 0; \
+	  nel = 0; \
+	  for (octave_idx_type i = 0; i < nc; i++) \
+	    if (tmp[i] != EL_TYPE ())  \
+	      { \
+		retval.data(nel) = tmp[i]; \
+		retval.ridx(nel++) = 0; \
+		retval.cidx(i+1) = retval.cidx(i) + 1; \
+	      } \
+	    else \
+	      retval.cidx(i+1) = retval.cidx(i); \
+	} \
+    } \
+  else if (nc == 0 && (nr == 0 || (nr == 1 && dim == -1))) \
+    { \
+      if (MT_RESULT) \
+        { \
+          retval = RET_TYPE (static_cast<octave_idx_type> (1), \
+                             static_cast<octave_idx_type> (1), \
+                             static_cast<octave_idx_type> (1)); \
+          retval.cidx(0) = 0; \
+          retval.cidx(1) = 1; \
+          retval.ridx(0) = 0; \
+          retval.data(0) = MT_RESULT; \
+        } \
+      else \
+          retval = RET_TYPE (static_cast<octave_idx_type> (1), \
+                             static_cast<octave_idx_type> (1), \
+                             static_cast<octave_idx_type> (0)); \
+    } \
+  else if (nr == 0 && (dim == 0 || dim == -1)) \
+    { \
+      if (MT_RESULT) \
+        { \
+          retval = RET_TYPE (static_cast<octave_idx_type> (1), nc, nc); \
+          retval.cidx (0) = 0; \
+          for (octave_idx_type i = 0; i < nc ; i++) \
+            { \
+              retval.ridx (i) = 0; \
+              retval.cidx (i+1) = i; \
+	      retval.data (i) = MT_RESULT; \
+	    } \
+        } \
+      else \
+        retval = RET_TYPE (static_cast<octave_idx_type> (1), nc, \
+			   static_cast<octave_idx_type> (0)); \
+    } \
+  else if (nc == 0 && dim == 1) \
+    { \
+      if (MT_RESULT) \
+        { \
+          retval = RET_TYPE (nr, static_cast<octave_idx_type> (1), nr); \
+          retval.cidx(0) = 0; \
+          retval.cidx(1) = nr; \
+          for (octave_idx_type i = 0; i < nr; i++) \
+	    { \
+	      retval.ridx(i) = i; \
+	      retval.data(i) = MT_RESULT; \
+	    } \
+        } \
+      else \
+        retval = RET_TYPE (nr, static_cast<octave_idx_type> (1), \
+			   static_cast<octave_idx_type> (0)); \
+    } \
+  else \
+    retval.resize (nr > 0, nc > 0); \
+ \
+  return retval
+
+#define SPARSE_REDUCTION_OP_ROW_EXPR(OP) \
+  tmp[ridx(i)] OP data (i)
+
+#define SPARSE_REDUCTION_OP_COL_EXPR(OP) \
+  tmp[j] OP data (i)
+
+#define SPARSE_REDUCTION_OP(RET_TYPE, EL_TYPE, OP, INIT_VAL, MT_RESULT)	\
+  SPARSE_BASE_REDUCTION_OP (RET_TYPE, EL_TYPE, \
+			SPARSE_REDUCTION_OP_ROW_EXPR (OP), \
+			SPARSE_REDUCTION_OP_COL_EXPR (OP), \
+			INIT_VAL, MT_RESULT)
+
+
+// Don't break from this loop if the test succeeds because
+// we are looping over the rows and not the columns in the inner
+// loop.
+#define SPARSE_ANY_ALL_OP_ROW_CODE(TEST_OP, TEST_TRUE_VAL) \
+  if (data (i) TEST_OP 0.0) \
+    tmp[ridx(i)] = TEST_TRUE_VAL; \
+
+#define SPARSE_ANY_ALL_OP_COL_CODE(TEST_OP, TEST_TRUE_VAL) \
+  if (data (i) TEST_OP 0.0) \
+    { \
+      tmp[j] = TEST_TRUE_VAL; \
+      break; \
+    }
+
+#define SPARSE_ANY_ALL_OP(DIM, INIT_VAL, MT_RESULT, TEST_OP, TEST_TRUE_VAL) \
+  SPARSE_BASE_REDUCTION_OP (SparseBoolMatrix, char, \
+			SPARSE_ANY_ALL_OP_ROW_CODE (TEST_OP, TEST_TRUE_VAL), \
+			SPARSE_ANY_ALL_OP_COL_CODE (TEST_OP, TEST_TRUE_VAL), \
+			INIT_VAL, MT_RESULT)
+
+#define SPARSE_ALL_OP(DIM) \
+  if ((rows() == 1 && dim == -1) || dim == 1) \
+    return transpose (). all (0). transpose(); \
+  else \
+    { \
+      SPARSE_ANY_ALL_OP (DIM, (cidx(j+1) - cidx(j) < nr ? false : true), \
+			 true, ==, false); \
+    }
+
+#define SPARSE_ANY_OP(DIM) SPARSE_ANY_ALL_OP (DIM, false, false, !=, true)
+
+#define SPARSE_SPARSE_MUL( RET_TYPE, RET_EL_TYPE, EL_TYPE ) \
+  octave_idx_type nr = m.rows (); \
+  octave_idx_type nc = m.cols (); \
+  \
+  octave_idx_type a_nr = a.rows (); \
+  octave_idx_type a_nc = a.cols (); \
+  \
+  if (nr == 1 && nc == 1) \
+   { \
+     RET_EL_TYPE s = m.elem(0,0); \
+     octave_idx_type nz = a.nnz(); \
+     RET_TYPE r (a_nr, a_nc, nz); \
+     \
+     for (octave_idx_type i = 0; i < nz; i++) \
+       { \
+         OCTAVE_QUIT; \
+	 r.data(i) = s * a.data(i); \
+	 r.ridx(i) = a.ridx(i); \
+       } \
+     for (octave_idx_type i = 0; i < a_nc + 1; i++) \
+       { \
+         OCTAVE_QUIT; \
+         r.cidx(i) = a.cidx(i); \
+       } \
+     \
+     r.maybe_compress (true); \
+     return r; \
+   } \
+  else if (a_nr == 1 && a_nc == 1) \
+   { \
+     RET_EL_TYPE s = a.elem(0,0); \
+     octave_idx_type nz = m.nnz(); \
+     RET_TYPE r (nr, nc, nz); \
+     \
+     for (octave_idx_type i = 0; i < nz; i++) \
+       { \
+         OCTAVE_QUIT; \
+	 r.data(i) = m.data(i) * s; \
+	 r.ridx(i) = m.ridx(i); \
+       } \
+     for (octave_idx_type i = 0; i < nc + 1; i++) \
+       { \
+         OCTAVE_QUIT; \
+         r.cidx(i) = m.cidx(i); \
+       } \
+     \
+     r.maybe_compress (true); \
+     return r; \
+   } \
+  else if (nc != a_nr) \
+    { \
+      gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc); \
+      return RET_TYPE (); \
+    } \
+  else \
+    { \
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, w, nr); \
+      RET_TYPE retval (nr, a_nc, static_cast<octave_idx_type> (0)); \
+      for (octave_idx_type i = 0; i < nr; i++) \
+	w[i] = 0; \
+      retval.xcidx(0) = 0; \
+      \
+      octave_idx_type nel = 0; \
+      \
+      for (octave_idx_type i = 0; i < a_nc; i++) \
+        { \
+          for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++) \
+            { \
+              octave_idx_type  col = a.ridx(j); \
+              for (octave_idx_type k = m.cidx(col) ; k < m.cidx(col+1); k++) \
+		{ \
+		  if (w[m.ridx(k)] < i + 1) \
+                    { \
+		      w[m.ridx(k)] = i + 1; \
+		      nel++; \
+		    } \
+	          OCTAVE_QUIT; \
+		} \
+	    } \
+          retval.xcidx(i+1) = nel; \
+	} \
+      \
+      if (nel == 0) \
+	return RET_TYPE (nr, a_nc); \
+      else \
+	{  \
+          for (octave_idx_type i = 0; i < nr; i++) \
+	    w[i] = 0; \
+	  \
+          OCTAVE_LOCAL_BUFFER (RET_EL_TYPE, Xcol, nr); \
+          \
+	  retval.change_capacity (nel); \
+	  /* The optimal break-point as estimated from simulations */ \
+	  /* Note that Mergesort is O(nz log(nz)) while searching all */ \
+	  /* values is O(nr), where nz here is non-zero per row of */ \
+	  /* length nr. The test itself was then derived from the */ \
+	  /* simulation with random square matrices and the observation */ \
+	  /* of the number of non-zero elements in the output matrix */ \
+	  /* it was found that the breakpoints were */ \
+	  /*   nr: 500  1000  2000  5000 10000 */ \
+	  /*   nz:   6    25    97   585  2202 */ \
+	  /* The below is a simplication of the 'polyfit'-ed parameters */ \
+	  /* to these breakpoints */ \
+          octave_idx_type n_per_col = (a_nc > 43000 ? 43000 : \
+					(a_nc * a_nc) / 43000); \
+	  octave_idx_type ii = 0; \
+	  octave_idx_type *ri = retval.xridx(); \
+	  octave_sort<octave_idx_type> sort; \
+	  \
+	  for (octave_idx_type i = 0; i < a_nc ; i++) \
+	    { \
+	      if (retval.xcidx(i+1) - retval.xcidx(i) > n_per_col) \
+		{ \
+		  for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++) \
+		    { \
+		      octave_idx_type col = a.ridx(j); \
+		      EL_TYPE tmpval = a.data(j); \
+		      for (octave_idx_type k = m.cidx(col) ; \
+			   k < m.cidx(col+1); k++) \
+			{ \
+			  OCTAVE_QUIT; \
+			  octave_idx_type row = m.ridx(k); \
+			  if (w[row] < i + 1) \
+			    { \
+			      w[row] = i + 1; \
+			      Xcol[row] = tmpval * m.data(k); \
+			    } \
+			  else \
+			    Xcol[row] += tmpval * m.data(k); \
+			} \
+		    } \
+		  for (octave_idx_type k = 0; k < nr; k++) \
+		    if (w[k] == i + 1) \
+		      { \
+		        retval.xdata(ii) = Xcol[k]; \
+		        retval.xridx(ii++) = k; \
+		      } \
+		} \
+	      else \
+		{ \
+		  for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++) \
+		    { \
+		      octave_idx_type col = a.ridx(j); \
+		      EL_TYPE tmpval = a.data(j); \
+		      for (octave_idx_type k = m.cidx(col) ; \
+			  k < m.cidx(col+1); k++) \
+			{ \
+			  OCTAVE_QUIT; \
+			  octave_idx_type row = m.ridx(k); \
+			  if (w[row] < i + 1) \
+			    { \
+			      w[row] = i + 1; \
+			      retval.xridx(ii++) = row;\
+			      Xcol[row] = tmpval * m.data(k); \
+			    } \
+			  else \
+			    Xcol[row] += tmpval * m.data(k); \
+			} \
+		    } \
+		  sort.sort (ri + retval.xcidx(i), ii - retval.xcidx(i)); \
+	          for (octave_idx_type k = retval.xcidx(i); k < ii; k++) \
+		    retval.xdata(k) = Xcol[retval.xridx(k)]; \
+		}  \
+	    } \
+	  retval.maybe_compress (true);\
+	  return retval; \
+	} \
+    }
+
+#define SPARSE_FULL_MUL( RET_TYPE, EL_TYPE, ZERO ) \
+  octave_idx_type nr = m.rows (); \
+  octave_idx_type nc = m.cols (); \
+  \
+  octave_idx_type a_nr = a.rows (); \
+  octave_idx_type a_nc = a.cols (); \
+  \
+  if (nr == 1 && nc == 1) \
+    { \
+      RET_TYPE retval = m.elem (0,0) * a; \
+      return retval; \
+    } \
+  else if (nc != a_nr) \
+    { \
+      gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc); \
+      return RET_TYPE (); \
+    } \
+  else \
+    { \
+      RET_TYPE retval (nr, a_nc, ZERO); \
+      \
+      for (octave_idx_type i = 0; i < a_nc ; i++) \
+        { \
+          for (octave_idx_type j = 0; j < a_nr; j++) \
+            { \
+              OCTAVE_QUIT; \
+              \
+              EL_TYPE tmpval = a.elem(j,i); \
+              for (octave_idx_type k = m.cidx(j) ; k < m.cidx(j+1); k++) \
+                retval.elem (m.ridx(k),i) += tmpval * m.data(k); \
+            } \
+        } \
+      return retval; \
+    }
+
+#define SPARSE_FULL_TRANS_MUL( RET_TYPE, EL_TYPE, ZERO, CONJ_OP ) \
+  octave_idx_type nr = m.rows (); \
+  octave_idx_type nc = m.cols (); \
+  \
+  octave_idx_type a_nr = a.rows (); \
+  octave_idx_type a_nc = a.cols (); \
+  \
+  if (nr == 1 && nc == 1) \
+    { \
+      RET_TYPE retval = CONJ_OP (m.elem(0,0)) * a; \
+      return retval; \
+    } \
+  else if (nr != a_nr) \
+    { \
+      gripe_nonconformant ("operator *", nc, nr, a_nr, a_nc); \
+      return RET_TYPE (); \
+    } \
+  else \
+    { \
+      RET_TYPE retval (nc, a_nc); \
+      \
+      for (octave_idx_type i = 0; i < a_nc ; i++) \
+        { \
+          for (octave_idx_type j = 0; j < nc; j++) \
+            { \
+              OCTAVE_QUIT; \
+              \
+              EL_TYPE acc = ZERO; \
+              for (octave_idx_type k = m.cidx(j) ; k < m.cidx(j+1); k++) \
+                acc += a.elem (m.ridx(k),i) * CONJ_OP (m.data(k)); \
+              retval.xelem (j,i) = acc; \
+            } \
+        } \
+      return retval; \
+    }
+
+#define FULL_SPARSE_MUL( RET_TYPE, EL_TYPE, ZERO ) \
+  octave_idx_type nr = m.rows (); \
+  octave_idx_type nc = m.cols (); \
+  \
+  octave_idx_type a_nr = a.rows (); \
+  octave_idx_type a_nc = a.cols (); \
+  \
+  if (a_nr == 1 && a_nc == 1) \
+    { \
+      RET_TYPE retval = m * a.elem (0,0); \
+      return retval; \
+    } \
+  else if (nc != a_nr) \
+    { \
+      gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc); \
+      return RET_TYPE (); \
+    } \
+  else \
+    { \
+      RET_TYPE retval (nr, a_nc, ZERO); \
+      \
+      for (octave_idx_type i = 0; i < a_nc ; i++) \
+        { \
+          OCTAVE_QUIT; \
+          for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++) \
+            { \
+              octave_idx_type col = a.ridx(j); \
+              EL_TYPE tmpval = a.data(j); \
+              \
+              for (octave_idx_type k = 0 ; k < nr; k++) \
+                retval.xelem (k,i) += tmpval * m.elem(k,col); \
+            } \
+        } \
+      return retval; \
+    }
+
+#define FULL_SPARSE_MUL_TRANS( RET_TYPE, EL_TYPE, ZERO, CONJ_OP ) \
+  octave_idx_type nr = m.rows (); \
+  octave_idx_type nc = m.cols (); \
+  \
+  octave_idx_type a_nr = a.rows (); \
+  octave_idx_type a_nc = a.cols (); \
+  \
+  if (a_nr == 1 && a_nc == 1) \
+    { \
+      RET_TYPE retval = m * CONJ_OP (a.elem(0,0)); \
+      return retval; \
+    } \
+  else if (nc != a_nc) \
+    { \
+      gripe_nonconformant ("operator *", nr, nc, a_nc, a_nr); \
+      return RET_TYPE (); \
+    } \
+  else \
+    { \
+      RET_TYPE retval (nr, a_nr, ZERO); \
+      \
+      for (octave_idx_type i = 0; i < a_nc ; i++) \
+        { \
+          OCTAVE_QUIT; \
+          for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++) \
+            { \
+              octave_idx_type col = a.ridx(j); \
+              EL_TYPE tmpval = CONJ_OP (a.data(j)); \
+              for (octave_idx_type k = 0 ; k < nr; k++) \
+                retval.xelem (k,col) += tmpval * m.elem(k,i); \
+            } \
+        } \
+      return retval; \
+    }
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Sparse-perm-op-defs.h b/liboctave/Sparse-perm-op-defs.h
new file mode 100644
index 0000000..4c7e4f3
--- /dev/null
+++ b/liboctave/Sparse-perm-op-defs.h
@@ -0,0 +1,164 @@
+/* -*- C++ -*-
+
+Copyright (C) 2009 Jason Riedy
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_perm_op_defs_h)
+#define octave_sparse_perm_op_defs_h 1
+
+// Matrix multiplication
+
+template <typename SM>
+SM octinternal_do_mul_colpm_sm (const octave_idx_type *pcol, const SM& a)
+// Relabel the rows according to pcol.
+{
+  const octave_idx_type nr = a.rows ();
+  const octave_idx_type nc = a.cols ();
+  const octave_idx_type nent = a.nnz ();
+  SM r (nr, nc, nent);
+
+  for (octave_idx_type k = 0; k < nent; ++k)
+    {
+      OCTAVE_QUIT;
+      r.xridx (k) = pcol[a.ridx (k)];
+      r.xdata (k) = a.data (k);
+    }
+  for (octave_idx_type j = 0; j <= nc; ++j)
+    r.xcidx (j) = a.cidx (j);
+
+  r.maybe_compress (false);
+  return r;
+}
+
+template <typename SM>
+SM octinternal_do_mul_pm_sm (const PermMatrix& p, const SM& a)
+{
+  const octave_idx_type nr = a.rows ();
+  if (p.cols () != nr)
+    {
+      gripe_nonconformant ("operator *", p.rows (), p.cols (), a.rows (), a.cols ());
+      return SM ();
+    }
+
+  if (p.is_row_perm ())
+    {
+      // Form the column permutation and then call the colpm_sm routine.
+      const octave_idx_type *prow = p.pvec ().data ();
+      OCTAVE_LOCAL_BUFFER(octave_idx_type, pcol, nr);
+      for (octave_idx_type i = 0; i < nr; ++i)
+	pcol[prow[i]] = i;
+      return octinternal_do_mul_colpm_sm (pcol, a);
+    }
+  else
+    return octinternal_do_mul_colpm_sm (p.pvec ().data (), a);
+}
+
+template <typename SM>
+SM octinternal_do_mul_sm_rowpm (const SM& a, const octave_idx_type *prow)
+// For a row permutation, iterate across the source a and stuff the
+// results into the correct destination column in r.
+{
+  const octave_idx_type nr = a.rows ();
+  const octave_idx_type nc = a.cols ();
+  const octave_idx_type nent = a.nnz ();
+  SM r (nr, nc, nent);
+
+  for (octave_idx_type j_src = 0; j_src < nc; ++j_src)
+    r.xcidx (prow[j_src]) = a.cidx (j_src+1) - a.cidx (j_src);
+  octave_idx_type k = 0;
+  for (octave_idx_type j = 0; j < nc; ++j)
+    {
+      const octave_idx_type tmp = r.xcidx (j);
+      r.xcidx (j) = k;
+      k += tmp;
+    }
+  r.xcidx (nc) = nent;
+
+  octave_idx_type k_src = 0;
+  for (octave_idx_type j_src = 0; j_src < nc; ++j_src)
+    {
+      OCTAVE_QUIT;
+      const octave_idx_type j = prow[j_src];
+      const octave_idx_type kend_src = a.cidx (j_src + 1);
+      for (k = r.xcidx (j); k_src < kend_src; ++k, ++k_src)
+	{
+	  r.xridx (k) = a.ridx (k_src);
+	  r.xdata (k) = a.data (k_src);
+	}
+    }
+  assert (k_src == nent);
+
+  r.maybe_compress (false);
+  return r;
+}
+
+template <typename SM>
+SM octinternal_do_mul_sm_colpm (const SM& a, const octave_idx_type *pcol)
+// For a column permutation, iterate across the destination r and pull
+// data from the correct column of a.
+{
+  const octave_idx_type nr = a.rows ();
+  const octave_idx_type nc = a.cols ();
+  const octave_idx_type nent = a.nnz ();
+  SM r (nr, nc, nent);
+
+  for (octave_idx_type j = 0; j < nc; ++j)
+    {
+      const octave_idx_type j_src = pcol[j];
+      r.xcidx (j+1) = r.xcidx (j) + (a.cidx (j_src+1) - a.cidx (j_src));
+    }
+  assert (r.xcidx (nc) == nent);
+
+  octave_idx_type k = 0;
+  for (octave_idx_type j = 0; j < nc; ++j)
+    {
+      OCTAVE_QUIT;
+      const octave_idx_type j_src = pcol[j];
+      octave_idx_type k_src;
+      const octave_idx_type kend_src = a.cidx (j_src + 1);
+      for (k_src = a.cidx (j_src); k_src < kend_src; ++k_src, ++k)
+	{
+	  r.xridx (k) = a.ridx (k_src);
+	  r.xdata (k) = a.data (k_src);
+	}
+    }
+  assert (k == nent);
+
+  r.maybe_compress (false);
+  return r;
+}
+
+template <typename SM>
+SM octinternal_do_mul_sm_pm (const SM& a, const PermMatrix& p)
+{
+  const octave_idx_type nc = a.cols ();
+  if (p.rows () != nc)
+    {
+      gripe_nonconformant ("operator *", a.rows (), a.cols (), p.rows (), p.cols ());
+      return SM ();
+    }
+
+  if (p.is_row_perm ())
+    return octinternal_do_mul_sm_rowpm (a, p.pvec ().data ());
+  else
+    return octinternal_do_mul_sm_colpm (a, p.pvec ().data ());
+}
+
+#endif // octave_sparse_perm_op_defs_h
diff --git a/liboctave/Sparse.cc b/liboctave/Sparse.cc
new file mode 100644
index 0000000..fe44a13
--- /dev/null
+++ b/liboctave/Sparse.cc
@@ -0,0 +1,3696 @@
+// Template sparse array class
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <climits>
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+#include "Array.h"
+#include "Array-util.h"
+#include "Range.h"
+#include "idx-vector.h"
+#include "lo-error.h"
+#include "quit.h"
+#include "oct-locbuf.h"
+
+#include "Sparse.h"
+#include "sparse-sort.h"
+#include "oct-spparms.h"
+
+template <class T>
+T&
+Sparse<T>::SparseRep::elem (octave_idx_type _r, octave_idx_type _c)
+{
+  octave_idx_type i;
+
+  if (nzmx > 0)
+    {
+      for (i = c[_c]; i < c[_c + 1]; i++)
+	if (r[i] == _r)
+	  return d[i];
+	else if (r[i] > _r)
+	  break;
+
+      // Ok, If we've gotten here, we're in trouble.. Have to create a 
+      // new element in the sparse array. This' gonna be slow!!!
+      if (c[ncols] == nzmx)
+	{
+	  (*current_liboctave_error_handler)
+	    ("Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled");
+	  return *d;
+	}
+
+      octave_idx_type to_move = c[ncols] - i;
+      if (to_move != 0)
+	{
+	  for (octave_idx_type j = c[ncols]; j > i; j--)
+	    {
+	      d[j] = d[j-1];
+	      r[j] = r[j-1];
+	    }
+	}
+
+      for (octave_idx_type j = _c + 1; j < ncols + 1; j++)
+	c[j] = c[j] + 1;
+      
+      d[i] = 0.;
+      r[i] = _r;
+
+      return d[i];
+    }
+  else
+    {
+      (*current_liboctave_error_handler)
+	("Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled");
+      return *d;
+    }
+}
+
+template <class T>
+T
+Sparse<T>::SparseRep::celem (octave_idx_type _r, octave_idx_type _c) const
+{
+  if (nzmx > 0)
+    for (octave_idx_type i = c[_c]; i < c[_c + 1]; i++)
+      if (r[i] == _r)
+	return d[i];
+  return T ();
+}
+
+template <class T>
+void
+Sparse<T>::SparseRep::maybe_compress (bool remove_zeros)
+{
+  octave_idx_type ndel = nzmx - c[ncols];
+  octave_idx_type nzero = 0;
+
+  if (remove_zeros)
+    for (octave_idx_type i = 0; i < nzmx - ndel; i++)
+      if (d[i] == T ())
+	nzero++;
+
+  if (!ndel && !nzero)
+    return;
+
+  if (!nzero)
+    {
+      octave_idx_type new_nzmx = nzmx - ndel;
+
+      T *new_data = new T [new_nzmx];
+      for (octave_idx_type i = 0; i < new_nzmx; i++)
+	new_data[i] = d[i];
+      delete [] d;
+      d = new_data;
+
+      octave_idx_type *new_ridx = new octave_idx_type [new_nzmx];
+      for (octave_idx_type i = 0; i < new_nzmx; i++)
+	new_ridx[i] = r[i];
+      delete [] r;
+      r = new_ridx;
+    }
+  else
+    {
+      octave_idx_type new_nzmx = nzmx - ndel - nzero;
+
+      T *new_data = new T [new_nzmx];
+      octave_idx_type *new_ridx = new octave_idx_type [new_nzmx];
+
+      octave_idx_type ii = 0;
+      octave_idx_type ic = 0;
+      for (octave_idx_type j = 0; j < ncols; j++)
+	{
+	  for (octave_idx_type k = ic; k < c[j+1]; k++)
+	    if (d[k] != T ())
+	      {
+		new_data [ii] = d[k];
+		new_ridx [ii++] = r[k];
+	      }
+	  ic = c[j+1];
+	  c[j+1] = ii;
+	}
+
+      delete [] d;
+      d = new_data;
+
+      delete [] r;
+      r = new_ridx;
+    }
+
+  nzmx -= ndel + nzero;
+}
+
+template <class T>
+void
+Sparse<T>::SparseRep::change_length (octave_idx_type nz)
+{
+  if (nz != nzmx)
+    {
+      octave_idx_type min_nzmx = (nz < nzmx ? nz : nzmx);
+
+      octave_idx_type * new_ridx = new octave_idx_type [nz];
+      for (octave_idx_type i = 0; i < min_nzmx; i++)
+	new_ridx[i] = r[i];
+
+      delete [] r;
+      r = new_ridx;
+
+      T * new_data = new T [nz];
+      for (octave_idx_type i = 0; i < min_nzmx; i++)
+	new_data[i] = d[i];
+
+      delete [] d;
+      d = new_data;
+
+      if (nz < nzmx)
+	for (octave_idx_type i = 0; i <= ncols; i++)
+	  if (c[i] > nz)
+	    c[i] = nz;
+
+      nzmx = nz;
+    }
+}
+
+template <class T>
+template <class U>
+Sparse<T>::Sparse (const Sparse<U>& a)
+  : dimensions (a.dimensions), idx (0), idx_count (0)
+{
+  if (a.nnz () == 0)
+    rep = new typename Sparse<T>::SparseRep (rows (), cols());
+  else
+    {
+      rep = new typename Sparse<T>::SparseRep (rows (), cols (), a.nnz ());
+      
+      octave_idx_type nz = a.nnz ();
+      octave_idx_type nc = cols ();
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  xdata (i) = T (a.data (i));
+	  xridx (i) = a.ridx (i);
+	}
+      for (octave_idx_type i = 0; i < nc + 1; i++)
+	xcidx (i) = a.cidx (i);
+    }
+}
+
+template <class T>
+Sparse<T>::Sparse (octave_idx_type nr, octave_idx_type nc, T val)
+  : dimensions (dim_vector (nr, nc)), idx (0), idx_count (0)
+{ 
+  if (val != T ())
+    {
+      rep = new typename Sparse<T>::SparseRep (nr, nc, nr*nc);
+
+      octave_idx_type ii = 0;
+      xcidx (0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      xdata (ii) = val;
+	      xridx (ii++) = i;
+	    } 
+	  xcidx (j+1) = ii;
+	}
+    }
+  else
+    {
+      rep = new typename Sparse<T>::SparseRep (nr, nc, 0);
+      for (octave_idx_type j = 0; j < nc+1; j++)
+	xcidx(j) = 0;
+    }
+}
+
+template <class T>
+Sparse<T>::Sparse (const dim_vector& dv)
+  : dimensions (dv), idx (0), idx_count (0)
+{ 
+  if (dv.length() != 2)
+    (*current_liboctave_error_handler)
+      ("Sparse::Sparse (const dim_vector&): dimension mismatch");
+  else
+    rep = new typename Sparse<T>::SparseRep (dv(0), dv(1));
+}
+
+template <class T>
+Sparse<T>::Sparse (const Sparse<T>& a, const dim_vector& dv)
+  : dimensions (dv), idx (0), idx_count (0)
+{
+
+  // Work in unsigned long long to avoid overflow issues with numel
+  unsigned long long a_nel = static_cast<unsigned long long>(a.rows ()) *
+    static_cast<unsigned long long>(a.cols ());
+  unsigned long long dv_nel = static_cast<unsigned long long>(dv (0)) *
+    static_cast<unsigned long long>(dv (1));
+
+  if (a_nel != dv_nel)
+    (*current_liboctave_error_handler)
+      ("Sparse::Sparse (const Sparse&, const dim_vector&): dimension mismatch");
+  else
+    {
+      dim_vector old_dims = a.dims();
+      octave_idx_type new_nzmx = a.nnz ();
+      octave_idx_type new_nr = dv (0);
+      octave_idx_type new_nc = dv (1);
+      octave_idx_type old_nr = old_dims (0);
+      octave_idx_type old_nc = old_dims (1);
+
+      rep = new typename Sparse<T>::SparseRep (new_nr, new_nc, new_nzmx);
+
+      octave_idx_type kk = 0;
+      xcidx(0) = 0;
+      for (octave_idx_type i = 0; i < old_nc; i++)
+	for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++)
+	  {
+	    octave_idx_type tmp = i * old_nr + a.ridx(j);
+	    octave_idx_type ii = tmp % new_nr;
+	    octave_idx_type jj = (tmp - ii) / new_nr; 
+	    for (octave_idx_type k = kk; k < jj; k++)
+	      xcidx(k+1) = j;
+	    kk = jj;
+	    xdata(j) = a.data(j);
+	    xridx(j) = ii;
+	  }
+      for (octave_idx_type k = kk; k < new_nc; k++)
+	xcidx(k+1) = new_nzmx;
+    }
+}
+
+template <class T>
+Sparse<T>::Sparse (const Array<T>& a, const Array<octave_idx_type>& r, 
+		   const Array<octave_idx_type>& c, octave_idx_type nr,
+		   octave_idx_type nc, bool sum_terms)
+  : dimensions (dim_vector (nr, nc)), idx (0), idx_count (0)
+{
+  octave_idx_type a_len = a.length ();
+  octave_idx_type r_len = r.length ();
+  octave_idx_type c_len = c.length ();
+  bool ri_scalar = (r_len == 1); 
+  bool ci_scalar = (c_len == 1);
+  bool cf_scalar = (a_len == 1);
+  
+  if ((a_len != r_len && !cf_scalar && !ri_scalar) ||
+      (a_len != c_len && !cf_scalar && !ci_scalar) ||
+      (r_len != c_len && !ri_scalar && !ci_scalar) || nr < 0 || nc < 0)
+    {
+      (*current_liboctave_error_handler)
+	("Sparse::Sparse (const Array<T>&, const Array<octave_idx_type>&, ...): dimension mismatch");
+      rep = nil_rep ();
+      dimensions = dim_vector (0, 0);
+    }
+  else
+    {
+      octave_idx_type max_nzmx = (r_len > c_len ? r_len : c_len);
+
+      OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl *, sidx, max_nzmx);
+      OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl, sidxX, max_nzmx);
+
+      for (octave_idx_type i = 0; i < max_nzmx; i++)
+	sidx[i] = &sidxX[i];
+
+      octave_idx_type actual_nzmx = 0;
+      OCTAVE_QUIT;
+      for (octave_idx_type i = 0; i < max_nzmx; i++) 
+	{
+	  octave_idx_type rowidx =  (ri_scalar ? r(0) : r(i));
+	  octave_idx_type colidx = (ci_scalar ? c(0) : c(i));
+	  if (rowidx < nr && rowidx >= 0 &&
+	      colidx < nc && colidx >= 0 ) 
+	    {
+	      if ( a (cf_scalar ? 0 : i ) != T ()) 
+		{
+		  sidx[actual_nzmx]->r = rowidx;
+		  sidx[actual_nzmx]->c = colidx;
+		  sidx[actual_nzmx]->idx = i;
+		  actual_nzmx++;	
+		}
+	    }
+	  else 
+	    {
+	      (*current_liboctave_error_handler)
+		("Sparse::Sparse : index (%d,%d) out of range", 
+		 rowidx + 1, colidx + 1);
+	      rep = nil_rep ();
+	      dimensions = dim_vector (0, 0);
+	      return;
+	    }
+	}
+  
+      if (actual_nzmx == 0)
+	rep = new typename Sparse<T>::SparseRep (nr, nc);
+      else
+	{
+	  OCTAVE_QUIT;
+	  octave_sort<octave_sparse_sort_idxl *> 
+	    lsort (octave_sparse_sidxl_comp);
+
+	  lsort.sort (sidx, actual_nzmx);
+	  OCTAVE_QUIT;
+
+	  // Now count the unique non-zero values
+	  octave_idx_type real_nzmx = 1;
+	  for (octave_idx_type i = 1; i < actual_nzmx; i++) 
+	    if (sidx[i-1]->r != sidx[i]->r || sidx[i-1]->c != sidx[i]->c) 
+	      real_nzmx++;
+
+	  rep = new typename Sparse<T>::SparseRep (nr, nc, real_nzmx);
+
+	  octave_idx_type cx = 0;
+	  octave_idx_type prev_rval = -1;
+	  octave_idx_type prev_cval = -1;
+	  octave_idx_type ii = -1;
+	  xcidx (0) = 0;
+	  for (octave_idx_type i = 0; i < actual_nzmx; i++) 
+	    {
+	      OCTAVE_QUIT;
+	      octave_idx_type iidx = sidx[i]->idx;
+	      octave_idx_type rval = sidx[i]->r;
+	      octave_idx_type cval = sidx[i]->c;
+
+	      if (prev_cval < cval || (prev_rval < rval && prev_cval == cval)) 
+		{
+		  octave_idx_type ci = static_cast<octave_idx_type> (c (ci_scalar ? 0 : iidx));
+		  ii++;
+		  while (cx < ci) 
+		    xcidx (++cx) = ii;
+		  xdata(ii) = a (cf_scalar ? 0 : iidx);
+		  xridx(ii) = static_cast<octave_idx_type> (r (ri_scalar ? 0 : iidx));
+		} 
+	      else 
+		{
+		  if (sum_terms)
+		    xdata(ii) += a (cf_scalar ? 0 : iidx);
+		  else
+		    xdata(ii) =  a (cf_scalar ? 0 : iidx);
+		}
+	      prev_rval = rval;
+	      prev_cval = cval;
+	    } 
+
+	  while (cx < nc) 
+	    xcidx (++cx) = ii + 1;
+	}
+    }
+}
+
+template <class T>
+Sparse<T>::Sparse (const Array<T>& a, const Array<double>& r, 
+		   const Array<double>& c, octave_idx_type nr,
+		   octave_idx_type nc, bool sum_terms)
+  : dimensions (dim_vector (nr, nc)), idx (0), idx_count (0)
+{
+  octave_idx_type a_len = a.length ();
+  octave_idx_type r_len = r.length ();
+  octave_idx_type c_len = c.length ();
+  bool ri_scalar = (r_len == 1); 
+  bool ci_scalar = (c_len == 1);
+  bool cf_scalar = (a_len == 1);
+
+  if ((a_len != r_len && !cf_scalar && !ri_scalar) ||
+      (a_len != c_len && !cf_scalar && !ci_scalar) ||
+      (r_len != c_len && !ri_scalar && !ci_scalar) || nr < 0 || nc < 0)
+    {
+      (*current_liboctave_error_handler)
+	("Sparse::Sparse (const Array<T>&, const Array<double>&, ...): dimension mismatch");
+      rep = nil_rep ();
+      dimensions = dim_vector (0, 0);
+    }
+  else
+    {
+      octave_idx_type max_nzmx = (r_len > c_len ? r_len : c_len);
+  
+      OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl *, sidx, max_nzmx);
+      OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl, sidxX, max_nzmx);
+
+      for (octave_idx_type i = 0; i < max_nzmx; i++)
+	sidx[i] = &sidxX[i];
+
+      octave_idx_type actual_nzmx = 0;
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < max_nzmx; i++) 
+	{
+	  octave_idx_type rowidx = static_cast<octave_idx_type> (ri_scalar ? r(0) : r(i));
+	  octave_idx_type colidx = static_cast<octave_idx_type> (ci_scalar ? c(0) : c(i));
+	  if (rowidx < nr && rowidx >= 0 &&
+	      colidx < nc && colidx >= 0 ) 
+	    {
+	      if ( a (cf_scalar ? 0 : i ) != T ()) 
+		{
+		  sidx[actual_nzmx]->r = rowidx;
+		  sidx[actual_nzmx]->c = colidx;
+		  sidx[actual_nzmx]->idx = i;
+		  actual_nzmx++;	
+		}
+	    }
+	  else 
+	    {
+	      (*current_liboctave_error_handler)
+		("Sparse::Sparse : index (%d,%d) out of range", 
+		 rowidx + 1, colidx + 1);
+	      rep = nil_rep ();
+	      dimensions = dim_vector (0, 0);
+	      return;
+	    }
+	}
+
+      if (actual_nzmx == 0)
+	rep = new typename Sparse<T>::SparseRep (nr, nc);
+      else
+	{
+	  OCTAVE_QUIT;
+	  octave_sort<octave_sparse_sort_idxl *> 
+	    lsort (octave_sparse_sidxl_comp);
+
+	  lsort.sort (sidx, actual_nzmx);
+	  OCTAVE_QUIT;
+
+	  // Now count the unique non-zero values
+	  octave_idx_type real_nzmx = 1;
+	  for (octave_idx_type i = 1; i < actual_nzmx; i++) 
+	    if (sidx[i-1]->r != sidx[i]->r || sidx[i-1]->c != sidx[i]->c) 
+	      real_nzmx++;
+
+	  rep = new typename Sparse<T>::SparseRep (nr, nc, real_nzmx);
+
+	  octave_idx_type cx = 0;
+	  octave_idx_type prev_rval = -1;
+	  octave_idx_type prev_cval = -1;
+	  octave_idx_type ii = -1;
+	  xcidx (0) = 0;
+	  for (octave_idx_type i = 0; i < actual_nzmx; i++) 
+	    {
+	      OCTAVE_QUIT;
+	      octave_idx_type iidx = sidx[i]->idx;
+	      octave_idx_type rval = sidx[i]->r;
+	      octave_idx_type cval = sidx[i]->c;
+
+	      if (prev_cval < cval || (prev_rval < rval && prev_cval == cval)) 
+		{
+		  octave_idx_type ci = static_cast<octave_idx_type> (c (ci_scalar ? 0 : iidx));
+		  ii++;
+
+		  while (cx < ci) 
+		    xcidx (++cx) = ii;
+		  xdata(ii) = a (cf_scalar ? 0 : iidx);
+		  xridx(ii) = static_cast<octave_idx_type> (r (ri_scalar ? 0 : iidx));
+		} 
+	      else 
+		{
+		  if (sum_terms)
+		    xdata(ii) += a (cf_scalar ? 0 : iidx);
+		  else
+		    xdata(ii) =  a (cf_scalar ? 0 : iidx);
+		}
+	      prev_rval = rval;
+	      prev_cval = cval;
+	    } 
+
+	  while (cx < nc) 
+	    xcidx (++cx) = ii + 1;
+	}
+    }
+}
+
+template <class T>
+Sparse<T>::Sparse (const Array2<T>& a)
+  : dimensions (a.dims ()), idx (0), idx_count (0)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type len = a.length ();
+  octave_idx_type new_nzmx = 0;
+
+  // First count the number of non-zero terms
+  for (octave_idx_type i = 0; i < len; i++)
+    if (a(i) != T ())
+      new_nzmx++;
+
+  rep = new typename Sparse<T>::SparseRep (nr, nc, new_nzmx);
+
+  octave_idx_type ii = 0;
+  xcidx(0) = 0;
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	if (a.elem (i,j) != T ())
+	  {
+	    xdata(ii) = a.elem (i,j);
+	    xridx(ii++) = i;
+	  }
+      xcidx(j+1) = ii;
+    }
+}
+
+template <class T>
+Sparse<T>::Sparse (const Array<T>& a)
+  : dimensions (a.dims ()), idx (0), idx_count (0)
+{
+  if (dimensions.length () > 2)
+    (*current_liboctave_error_handler)
+      ("Sparse::Sparse (const Array<T>&): dimension mismatch");
+  else
+    {
+      octave_idx_type nr = rows ();
+      octave_idx_type nc = cols ();
+      octave_idx_type len = a.length ();
+      octave_idx_type new_nzmx = 0;
+
+      // First count the number of non-zero terms
+      for (octave_idx_type i = 0; i < len; i++)
+	if (a(i) != T ())
+	  new_nzmx++;
+
+      rep = new typename Sparse<T>::SparseRep (nr, nc, new_nzmx);
+
+      octave_idx_type ii = 0;
+      xcidx(0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    if (a.elem (i,j) != T ())
+	      {
+		xdata(ii) = a.elem (i,j);
+		xridx(ii++) = i;
+	      }
+	  xcidx(j+1) = ii;
+	}
+    }
+}
+
+template <class T>
+Sparse<T>::~Sparse (void)
+{
+  if (--rep->count <= 0)
+    delete rep;
+
+  delete [] idx;
+}
+
+template <class T>
+Sparse<T>&
+Sparse<T>::operator = (const Sparse<T>& a)
+{
+  if (this != &a)
+    {
+      if (--rep->count <= 0)
+	delete rep;
+
+      rep = a.rep;
+      rep->count++;
+
+      dimensions = a.dimensions;
+
+      delete [] idx;
+      idx_count = 0;
+      idx = 0;
+    }
+
+  return *this;
+}
+
+template <class T>
+octave_idx_type
+Sparse<T>::compute_index (const Array<octave_idx_type>& ra_idx) const
+{
+  octave_idx_type retval = -1;
+
+  octave_idx_type n = dimensions.length ();
+
+  if (n > 0 && n == ra_idx.length ())
+    {
+      retval = ra_idx(--n);
+
+      while (--n >= 0)
+	{
+	  retval *= dimensions(n);
+	  retval += ra_idx(n);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Sparse<T>::compute_index: invalid ra_idxing operation");
+
+  return retval;
+}
+
+template <class T>
+T
+Sparse<T>::range_error (const char *fcn, octave_idx_type n) const
+{
+  (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n);
+  return T ();
+}
+
+template <class T>
+T&
+Sparse<T>::range_error (const char *fcn, octave_idx_type n)
+{
+  (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Sparse<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d): range error", fcn, i, j);
+  return T ();
+}
+
+template <class T>
+T&
+Sparse<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j)
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d): range error", fcn, i, j);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Sparse<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const
+{
+  std::ostringstream buf;
+
+  buf << fcn << " (";
+
+  octave_idx_type n = ra_idx.length ();
+
+  if (n > 0)
+    buf << ra_idx(0);
+
+  for (octave_idx_type i = 1; i < n; i++)
+    buf << ", " << ra_idx(i);
+
+  buf << "): range error";
+  
+  std::string buf_str = buf.str ();
+
+  (*current_liboctave_error_handler) (buf_str.c_str ());
+
+  return T ();
+}
+
+template <class T>
+T&
+Sparse<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx)
+{
+  std::ostringstream buf;
+
+  buf << fcn << " (";
+
+  octave_idx_type n = ra_idx.length ();
+
+  if (n > 0)
+    buf << ra_idx(0);
+
+  for (octave_idx_type i = 1; i < n; i++)
+    buf << ", " << ra_idx(i);
+
+  buf << "): range error";
+
+  std::string buf_str = buf.str ();
+
+  (*current_liboctave_error_handler) (buf_str.c_str ());
+
+  static T foo;
+  return foo;
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::reshape (const dim_vector& new_dims) const
+{
+  Sparse<T> retval;
+  dim_vector dims2 = new_dims;
+
+  if (dims2.length () > 2)
+    {
+      (*current_liboctave_warning_handler)
+	("reshape: sparse reshape to N-d array smashes dims");
+
+      for (octave_idx_type i = 2; i < dims2.length(); i++)
+	dims2(1) *= dims2(i);
+
+      dims2.resize (2);
+    }
+
+  if (dimensions != dims2)
+    {
+      if (dimensions.numel () == dims2.numel ())
+	{
+	  octave_idx_type new_nnz = nnz ();
+	  octave_idx_type new_nr = dims2 (0);
+	  octave_idx_type new_nc = dims2 (1);
+	  octave_idx_type old_nr = rows ();
+	  octave_idx_type old_nc = cols ();
+	  retval = Sparse<T> (new_nr, new_nc, new_nnz);
+
+	  octave_idx_type kk = 0;
+	  retval.xcidx(0) = 0;
+	  for (octave_idx_type i = 0; i < old_nc; i++)
+	    for (octave_idx_type j = cidx(i); j < cidx(i+1); j++)
+	      {
+		octave_idx_type tmp = i * old_nr + ridx(j);
+		octave_idx_type ii = tmp % new_nr;
+		octave_idx_type jj = (tmp - ii) / new_nr; 
+		for (octave_idx_type k = kk; k < jj; k++)
+		  retval.xcidx(k+1) = j;
+		kk = jj;
+		retval.xdata(j) = data(j);
+		retval.xridx(j) = ii;
+	      }
+	  for (octave_idx_type k = kk; k < new_nc; k++)
+	    retval.xcidx(k+1) = new_nnz;
+	}
+      else
+	{
+	  std::string dimensions_str = dimensions.str ();
+	  std::string new_dims_str = new_dims.str ();
+
+	  (*current_liboctave_error_handler)
+	    ("reshape: can't reshape %s array to %s array",
+	     dimensions_str.c_str (), new_dims_str.c_str ());
+	}
+    }
+  else
+    retval = *this;
+
+  return retval;
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::permute (const Array<octave_idx_type>& perm_vec, bool) const
+{
+  // The only valid permutations of a sparse array are [1, 2] and [2, 1].
+
+  bool fail = false;
+  bool trans = false;
+
+  if (perm_vec.length () == 2)
+    {
+      if (perm_vec(0) == 0 && perm_vec(1) == 1)
+	/* do nothing */;
+      else if (perm_vec(0) == 1 && perm_vec(1) == 0)
+	trans = true;
+      else
+	fail = true;
+    }
+  else
+    fail = true;
+
+  if (fail)
+    (*current_liboctave_error_handler)
+      ("permutation vector contains an invalid element");
+
+  return trans ? this->transpose () : *this;
+}
+
+template <class T>
+void
+Sparse<T>::resize_no_fill (const dim_vector& dv)
+{
+  octave_idx_type n = dv.length ();
+
+  if (n != 2)
+    {
+      (*current_liboctave_error_handler) ("sparse array must be 2-D");
+      return;
+    }
+
+  resize_no_fill (dv(0), dv(1));
+}
+
+template <class T>
+void
+Sparse<T>::resize_no_fill (octave_idx_type r, octave_idx_type c)
+{
+  if (r < 0 || c < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (ndims () == 0)
+    dimensions = dim_vector (0, 0);
+
+  if (r == dim1 () && c == dim2 ())
+    return;
+
+  typename Sparse<T>::SparseRep *old_rep = rep;
+
+  octave_idx_type nc = cols ();
+  octave_idx_type nr = rows ();
+
+  if (nnz () == 0 || r == 0 || c == 0)
+    // Special case of redimensioning to/from a sparse matrix with 
+    // no elements
+    rep = new typename Sparse<T>::SparseRep (r, c);
+  else
+    {
+      octave_idx_type n = 0;
+      Sparse<T> tmpval;
+      if (r >= nr)
+	{
+	  if (c > nc)
+	    n = xcidx(nc);
+	  else
+	    n = xcidx(c);
+
+	  tmpval = Sparse<T> (r, c, n);
+
+	  if (c > nc)
+	    {
+	      for (octave_idx_type i = 0; i < nc + 1; i++)
+		tmpval.cidx(i) = xcidx(i);
+	      for (octave_idx_type i = nc + 1; i < c + 1; i++)
+		tmpval.cidx(i) = tmpval.cidx(i-1);
+	    }
+	  else if (c <= nc)
+	    for (octave_idx_type i = 0; i < c + 1; i++)
+	      tmpval.cidx(i) = xcidx(i);
+	  
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      tmpval.data(i) = xdata(i);
+	      tmpval.ridx(i) = xridx(i);
+	    }
+	}
+      else
+	{
+	  // Count how many non zero terms before we do anything
+	  octave_idx_type min_nc = (c < nc ? c : nc);
+	  for (octave_idx_type i = 0; i < min_nc; i++)
+	    for (octave_idx_type j = xcidx(i); j < xcidx(i+1); j++)
+	      if (xridx(j) < r)
+		n++;
+
+	  if (n)
+	    {
+	      // Now that we know the size we can do something
+	      tmpval = Sparse<T> (r, c, n);
+
+	      tmpval.cidx(0);
+	      for (octave_idx_type i = 0, ii = 0; i < min_nc; i++)
+		{
+		  for (octave_idx_type j = xcidx(i); j < xcidx(i+1); j++)
+		    if (xridx(j) < r)
+		      {
+			tmpval.data(ii) = xdata(j);
+			tmpval.ridx(ii++) = xridx(j);
+		      }
+		  tmpval.cidx(i+1) = ii;
+		}
+	      if (c > min_nc)
+		for (octave_idx_type i = nc; i < c; i++)
+		  tmpval.cidx(i+1) = tmpval.cidx(i);
+	    }
+	  else
+	    tmpval = Sparse<T> (r, c);
+	}
+
+      rep = tmpval.rep;
+      rep->count++;
+    }
+
+  dimensions = dim_vector (r, c);
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+Sparse<T>&
+Sparse<T>::insert (const Sparse<T>& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_rows = a.rows ();
+  octave_idx_type a_cols = a.cols ();
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  // First count the number of elements in the final array
+  octave_idx_type nel = cidx(c) + a.nnz ();
+
+  if (c + a_cols < nc)
+    nel += cidx(nc) - cidx(c + a_cols);
+
+  for (octave_idx_type i = c; i < c + a_cols; i++)
+    for (octave_idx_type j = cidx(i); j < cidx(i+1); j++)
+      if (ridx(j) < r || ridx(j) >= r + a_rows)
+	nel++;
+
+  Sparse<T> tmp (*this);
+  --rep->count;
+  rep = new typename Sparse<T>::SparseRep (nr, nc, nel);
+
+  for (octave_idx_type i = 0; i < tmp.cidx(c); i++)
+    {
+      data(i) = tmp.data(i);
+      ridx(i) = tmp.ridx(i);
+    }
+  for (octave_idx_type i = 0; i < c + 1; i++)
+    cidx(i) = tmp.cidx(i);
+
+  octave_idx_type ii = cidx(c);
+
+  for (octave_idx_type i = c; i < c + a_cols; i++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++)
+	if (tmp.ridx(j) < r)
+	  {
+	    data(ii) = tmp.data(j);
+	    ridx(ii++) = tmp.ridx(j);
+	  }
+
+      OCTAVE_QUIT;
+
+      for (octave_idx_type j = a.cidx(i-c); j < a.cidx(i-c+1); j++)
+	{
+	  data(ii) = a.data(j);
+	  ridx(ii++) = r + a.ridx(j);
+	}
+
+      OCTAVE_QUIT;
+
+      for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++)
+	if (tmp.ridx(j) >= r + a_rows)
+	  {
+	    data(ii) = tmp.data(j);
+	    ridx(ii++) = tmp.ridx(j);
+	  }
+
+      cidx(i+1) = ii;
+    }
+
+  for (octave_idx_type i = c + a_cols; i < nc; i++)
+    {
+      for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++)
+	{
+	  data(ii) = tmp.data(j);
+	  ridx(ii++) = tmp.ridx(j);
+	}
+      cidx(i+1) = ii;
+    }
+
+  return *this;
+}
+
+template <class T>
+Sparse<T>&
+Sparse<T>::insert (const Sparse<T>& a, const Array<octave_idx_type>& ra_idx)
+{
+
+  if (ra_idx.length () != 2)
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  return insert (a, ra_idx (0), ra_idx (1));
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::transpose (void) const
+{
+  assert (ndims () == 2);
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nnz ();
+  Sparse<T> retval (nc, nr, nz);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    retval.xcidx (ridx (i) + 1)++;
+  // retval.xcidx[1:nr] holds the row degrees for rows 0:(nr-1)
+  nz = 0;
+  for (octave_idx_type i = 1; i <= nr; i++)
+    {
+      const octave_idx_type tmp = retval.xcidx (i);
+      retval.xcidx (i) = nz;
+      nz += tmp;
+    }
+  // retval.xcidx[1:nr] holds row entry *start* offsets for rows 0:(nr-1)
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type k = cidx(j); k < cidx(j+1); k++)
+      {
+	octave_idx_type q = retval.xcidx (ridx (k) + 1)++;
+	retval.xridx (q) = j;
+	retval.xdata (q) = data (k);
+      }
+  assert (nnz () == retval.xcidx (nr));
+  // retval.xcidx[1:nr] holds row entry *end* offsets for rows 0:(nr-1)
+  // and retval.xcidx[0:(nr-1)] holds their row entry *start* offsets
+
+  return retval;
+}
+
+template <class T>
+void
+Sparse<T>::clear_index (void)
+{
+  delete [] idx;
+  idx = 0;
+  idx_count = 0;
+}
+
+template <class T>
+void
+Sparse<T>::set_index (const idx_vector& idx_arg)
+{
+  octave_idx_type nd = ndims ();
+
+  if (! idx && nd > 0)
+    idx = new idx_vector [nd];
+
+  if (idx_count < nd)
+    {
+      idx[idx_count++] = idx_arg;
+    }
+  else
+    {
+      idx_vector *new_idx = new idx_vector [idx_count+1];
+
+      for (octave_idx_type i = 0; i < idx_count; i++)
+	new_idx[i] = idx[i];
+
+      new_idx[idx_count++] = idx_arg;
+
+      delete [] idx;
+
+      idx = new_idx;
+    }
+}
+
+template <class T>
+void
+Sparse<T>::maybe_delete_elements (idx_vector& idx_arg)
+{
+  octave_idx_type nr = dim1 ();
+  octave_idx_type nc = dim2 ();
+
+  if (nr == 0 && nc == 0)
+    return;
+
+  octave_idx_type n;
+  if (nr == 1)
+    n = nc;
+  else if (nc == 1)
+    n = nr;
+  else
+    {
+      // Reshape to row vector for Matlab compatibility.
+
+      n = nr * nc;
+      nr = 1;
+      nc = n;
+    }
+
+  if (idx_arg.is_colon_equiv (n, 1))
+    {
+      // Either A(:) = [] or A(idx) = [] with idx enumerating all
+      // elements, so we delete all elements and return [](0x0).  To
+      // preserve the orientation of the vector, you have to use
+      // A(idx,:) = [] (delete rows) or A(:,idx) (delete columns).
+
+      resize_no_fill (0, 0);
+      return;
+    }
+
+  idx_arg.sort (true);
+
+  octave_idx_type num_to_delete = idx_arg.length (n);
+
+  if (num_to_delete != 0)
+    {
+      octave_idx_type new_n = n;
+      octave_idx_type new_nnz = nnz ();
+
+      octave_idx_type iidx = 0;
+
+      const Sparse<T> tmp (*this);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  OCTAVE_QUIT;
+
+	  if (i == idx_arg.elem (iidx))
+	    {
+	      iidx++;
+	      new_n--;
+
+	      if (tmp.elem (i) != T ())
+		new_nnz--;
+
+	      if (iidx == num_to_delete)
+		break;
+	    }
+	}
+
+      if (new_n > 0)
+	{
+	  rep->count--;
+
+	  if (nr == 1)
+	    rep = new typename Sparse<T>::SparseRep (1, new_n, new_nnz);
+	  else
+	    rep = new typename Sparse<T>::SparseRep (new_n, 1, new_nnz);
+
+	  octave_idx_type ii = 0;
+	  octave_idx_type jj = 0;
+	  iidx = 0;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      OCTAVE_QUIT;
+
+	      if (iidx < num_to_delete && i == idx_arg.elem (iidx))
+		iidx++;
+	      else
+		{
+		  T el = tmp.elem (i);
+		  if (el != T ())
+		    {
+		      data(ii) = el;
+		      ridx(ii++) = jj;
+		    }
+		  jj++;
+		}
+	    }
+
+	  dimensions.resize (2);
+
+	  if (nr == 1)
+	    {
+	      ii = 0;
+	      cidx(0) = 0;
+	      for (octave_idx_type i = 0; i < new_n; i++)
+		{
+		  OCTAVE_QUIT;
+		  if (ridx(ii) == i)
+		    ridx(ii++) = 0;
+		  cidx(i+1) = ii;
+		}
+
+	      dimensions(0) = 1;
+	      dimensions(1) = new_n;
+	    }
+	  else
+	    {
+	      cidx(0) = 0;
+	      cidx(1) = new_nnz;
+	      dimensions(0) = new_n;
+	      dimensions(1) = 1;
+	    }
+	}
+      else
+	(*current_liboctave_error_handler)
+	  ("A(idx) = []: index out of range");
+    }
+}
+
+template <class T>
+void
+Sparse<T>::maybe_delete_elements (idx_vector& idx_i, idx_vector& idx_j)
+{
+  assert (ndims () == 2);
+
+  octave_idx_type nr = dim1 ();
+  octave_idx_type nc = dim2 ();
+
+  if (nr == 0 && nc == 0)
+    return;
+
+  if (idx_i.is_colon ())
+    {
+      if (idx_j.is_colon ())
+	{
+	  // A(:,:) -- We are deleting columns and rows, so the result
+	  // is [](0x0).
+
+	  resize_no_fill (0, 0);
+	  return;
+	}
+
+      if (idx_j.is_colon_equiv (nc, 1))
+	{
+	  // A(:,j) -- We are deleting columns by enumerating them,
+	  // If we enumerate all of them, we should have zero columns
+	  // with the same number of rows that we started with.
+
+	  resize_no_fill (nr, 0);
+	  return;
+	}
+    }
+
+  if (idx_j.is_colon () && idx_i.is_colon_equiv (nr, 1))
+    {
+      // A(i,:) -- We are deleting rows by enumerating them.  If we
+      // enumerate all of them, we should have zero rows with the
+      // same number of columns that we started with.
+
+      resize_no_fill (0, nc);
+      return;
+    }
+
+  if (idx_i.is_colon_equiv (nr, 1))
+    {
+      if (idx_j.is_colon_equiv (nc, 1))
+	resize_no_fill (0, 0);
+      else
+	{
+	  idx_j.sort (true);
+
+	  octave_idx_type num_to_delete = idx_j.length (nc);
+
+	  if (num_to_delete != 0)
+	    {
+	      if (nr == 1 && num_to_delete == nc)
+		resize_no_fill (0, 0);
+	      else
+		{
+		  octave_idx_type new_nc = nc;
+		  octave_idx_type new_nnz = nnz ();
+
+		  octave_idx_type iidx = 0;
+
+		  for (octave_idx_type j = 0; j < nc; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      if (j == idx_j.elem (iidx))
+			{
+			  iidx++;
+			  new_nc--;
+			  
+			  new_nnz -= cidx(j+1) - cidx(j);
+
+			  if (iidx == num_to_delete)
+			    break;
+			}
+		    }
+
+		  if (new_nc > 0)
+		    {
+		      const Sparse<T> tmp (*this);
+		      --rep->count;
+		      rep = new typename Sparse<T>::SparseRep (nr, new_nc, 
+							       new_nnz);
+		      octave_idx_type ii = 0;
+		      octave_idx_type jj = 0;
+		      iidx = 0;
+		      cidx(0) = 0;
+		      for (octave_idx_type j = 0; j < nc; j++)
+			{
+			  OCTAVE_QUIT;
+
+			  if (iidx < num_to_delete && j == idx_j.elem (iidx))
+			    iidx++;
+			  else
+			    {
+			      for (octave_idx_type i = tmp.cidx(j); 
+				   i < tmp.cidx(j+1); i++)
+				{
+				  data(jj) = tmp.data(i);
+				  ridx(jj++) = tmp.ridx(i);
+				}
+			      cidx(++ii) = jj;
+			    }
+			}
+
+		      dimensions.resize (2);
+		      dimensions(1) = new_nc;
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("A(idx) = []: index out of range");
+		}
+	    }
+	}
+    }
+  else if (idx_j.is_colon_equiv (nc, 1))
+    {
+      if (idx_i.is_colon_equiv (nr, 1))
+	resize_no_fill (0, 0);
+      else
+	{
+	  idx_i.sort (true);
+
+	  octave_idx_type num_to_delete = idx_i.length (nr);
+
+	  if (num_to_delete != 0)
+	    {
+	      if (nc == 1 && num_to_delete == nr)
+		resize_no_fill (0, 0);
+	      else
+		{
+		  octave_idx_type new_nr = nr;
+		  octave_idx_type new_nnz = nnz ();
+
+		  octave_idx_type iidx = 0;
+
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    {
+		      OCTAVE_QUIT;
+
+		      if (i == idx_i.elem (iidx))
+			{
+			  iidx++;
+			  new_nr--;
+			  
+			  for (octave_idx_type j = 0; j < nnz (); j++)
+			    if (ridx(j) == i)
+			      new_nnz--;
+
+			  if (iidx == num_to_delete)
+			    break;
+			}
+		    }
+
+		  if (new_nr > 0)
+		    {
+		      const Sparse<T> tmp (*this);
+		      --rep->count;
+		      rep = new typename Sparse<T>::SparseRep (new_nr, nc, 
+							       new_nnz);
+
+		      octave_idx_type jj = 0;
+		      cidx(0) = 0;
+		      for (octave_idx_type i = 0; i < nc; i++)
+			{
+			  iidx = 0;
+			  for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++)
+			    {
+			      OCTAVE_QUIT;
+
+			      octave_idx_type ri = tmp.ridx(j);
+
+			      while (iidx < num_to_delete && 
+				     ri > idx_i.elem (iidx))
+				{
+				  iidx++;
+				}
+
+			      if (iidx == num_to_delete ||
+				  ri != idx_i.elem(iidx))
+				{
+				  data(jj) = tmp.data(j);
+				  ridx(jj++) = ri - iidx;
+				}
+			    }
+			  cidx(i+1) = jj;
+			}
+
+		      dimensions.resize (2);
+		      dimensions(0) = new_nr;
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("A(idx) = []: index out of range");
+		}
+	    }
+	}
+    }
+}
+
+template <class T>
+void
+Sparse<T>::maybe_delete_elements (Array<idx_vector>& ra_idx)
+{
+  if (ra_idx.length () == 1)
+    maybe_delete_elements (ra_idx(0));
+  else if (ra_idx.length () == 2)
+    maybe_delete_elements (ra_idx(0), ra_idx(1));
+  else
+    (*current_liboctave_error_handler) 
+      ("range error for maybe_delete_elements");
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::value (void)
+{
+  Sparse<T> retval;
+
+  int n_idx = index_count ();
+
+  if (n_idx == 2)
+    {
+      idx_vector *tmp = get_idx ();
+
+      idx_vector idx_i = tmp[0];
+      idx_vector idx_j = tmp[1];
+
+      retval = index (idx_i, idx_j);
+    }
+  else if (n_idx == 1)
+    {
+      retval = index (idx[0]);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Sparse<T>::value: invalid number of indices specified");
+
+  clear_index ();
+
+  return retval;
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::index (idx_vector& idx_arg, int resize_ok) const
+{
+  Sparse<T> retval;
+
+  assert (ndims () == 2);
+
+  octave_idx_type nr = dim1 ();
+  octave_idx_type nc = dim2 ();
+  octave_idx_type nz = nnz ();
+
+  octave_idx_type orig_len = nr * nc;
+
+  dim_vector idx_orig_dims = idx_arg.orig_dimensions ();
+
+  octave_idx_type idx_orig_rows = idx_arg.orig_rows ();
+  octave_idx_type idx_orig_columns = idx_arg.orig_columns ();
+
+  if (idx_orig_dims.length () > 2)
+    (*current_liboctave_error_handler)
+      ("Sparse<T>::index: Can not index Sparse<T> with an N-D Array");
+  else if (idx_arg.is_colon ())
+    {
+      // Fast magic colon processing.
+      retval = Sparse<T> (nr * nc, 1, nz);
+
+      for (octave_idx_type i = 0; i < nc; i++)
+	for (octave_idx_type j = cidx(i); j < cidx(i+1); j++)
+	  {
+	    OCTAVE_QUIT;
+	    retval.xdata(j) = data(j); 
+	    retval.xridx(j) = ridx(j) + i * nr;
+	  }
+      retval.xcidx(0) = 0;
+      retval.xcidx(1) = nz;
+    }
+  else if (nr == 1 && nc == 1)
+    {
+      // You have to be pretty sick to get to this bit of code,
+      // since you have a scalar stored as a sparse matrix, and
+      // then want to make a dense matrix with sparse 
+      // representation. Ok, we'll do it, but you deserve what 
+      // you get!!
+      octave_idx_type n = idx_arg.freeze (length (), "sparse vector", resize_ok);
+      if (n == 0)
+
+	  retval = Sparse<T> (idx_orig_dims);
+      else if (nz < 1)
+	if (n >= idx_orig_dims.numel ())
+	  retval = Sparse<T> (idx_orig_dims);
+	else
+	  retval = Sparse<T> (dim_vector (n, 1));
+      else if (n >= idx_orig_dims.numel ())
+	{
+	  T el = elem (0);
+	  octave_idx_type new_nr = idx_orig_rows;
+	  octave_idx_type new_nc = idx_orig_columns;
+	  for (octave_idx_type i = 2; i < idx_orig_dims.length (); i++)
+	    new_nc *= idx_orig_dims (i);
+		
+	  retval = Sparse<T> (new_nr, new_nc, idx_arg.ones_count ());
+
+	  octave_idx_type ic = 0;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      if (i % new_nr == 0)
+		retval.xcidx(i / new_nr) = ic;
+
+	      octave_idx_type ii = idx_arg.elem (i);
+	      if (ii == 0)
+		{
+		  OCTAVE_QUIT;
+		  retval.xdata(ic) = el;
+		  retval.xridx(ic++) = i % new_nr;
+		}
+	    }
+	  retval.xcidx (new_nc) = ic;
+	}
+      else
+	{
+	  T el = elem (0);
+	  retval = Sparse<T> (n, 1, nz);
+  	 
+	  for (octave_idx_type i = 0; i < nz; i++) 
+	    {
+	      OCTAVE_QUIT;
+	      retval.xdata(i) = el;
+	      retval.xridx(i) = i;
+	    }
+	  retval.xcidx(0) = 0; 	 
+	  retval.xcidx(1) = n; 	 
+	}
+    }
+  else if (nr == 1 || nc == 1)
+    {
+      // If indexing a vector with a matrix, return value has same
+      // shape as the index.  Otherwise, it has same orientation as
+      // indexed object.
+      octave_idx_type len = length ();
+      octave_idx_type n = idx_arg.freeze (len, "sparse vector", resize_ok);
+
+      if (n == 0)
+	if (nr == 1)
+	  retval = Sparse<T> (dim_vector (1, 0));
+	else
+	  retval = Sparse<T> (dim_vector (0, 1));
+      else if (nz < 1)
+	if (idx_orig_rows == 1 || idx_orig_columns == 1)
+	  retval = Sparse<T> ((nr == 1 ? 1 : n), (nr == 1 ? n : 1));
+	else
+	  retval = Sparse<T> (idx_orig_dims);
+      else
+	{
+
+	  octave_idx_type new_nzmx = 0;
+	  if (nr == 1)
+	    for (octave_idx_type i = 0; i < n; i++)
+	      {
+		OCTAVE_QUIT;
+
+		octave_idx_type ii = idx_arg.elem (i);
+		if (ii < len)
+		  if (cidx(ii) != cidx(ii+1))
+		    new_nzmx++;
+	      }
+	  else
+	    for (octave_idx_type i = 0; i < n; i++)
+	      {
+		octave_idx_type ii = idx_arg.elem (i);
+		if (ii < len)
+		  for (octave_idx_type j = 0; j < nz; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      if (ridx(j) == ii)
+			new_nzmx++;
+		      if (ridx(j) >= ii)
+			break;
+		    }
+	      }
+
+	  if (idx_orig_rows == 1 || idx_orig_columns == 1)
+	    {
+	      if (nr == 1)
+		{
+		  retval = Sparse<T> (1, n, new_nzmx);
+		  octave_idx_type jj = 0;
+		  retval.xcidx(0) = 0;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      OCTAVE_QUIT;
+
+		      octave_idx_type ii = idx_arg.elem (i);
+		      if (ii < len)
+			if (cidx(ii) != cidx(ii+1))
+			  {
+			    retval.xdata(jj) = data(cidx(ii));
+			    retval.xridx(jj++) = 0;
+			  }
+		      retval.xcidx(i+1) = jj;
+		    }
+		}
+	      else
+		{
+		  retval = Sparse<T> (n, 1, new_nzmx);
+		  retval.xcidx(0) = 0;
+		  retval.xcidx(1) = new_nzmx;
+		  octave_idx_type jj = 0;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      octave_idx_type ii = idx_arg.elem (i);
+		      if (ii < len)
+			for (octave_idx_type j = 0; j < nz; j++)
+			  {
+			    OCTAVE_QUIT;
+
+			    if (ridx(j) == ii)
+			      {
+				retval.xdata(jj) = data(j);
+				retval.xridx(jj++) = i;
+			      }
+			    if (ridx(j) >= ii)
+			      break;
+			  }
+		    }
+		}
+	    }
+	  else 
+	    {
+	      octave_idx_type new_nr;
+	      octave_idx_type new_nc;
+	      if (n >= idx_orig_dims.numel ())
+		{
+		  new_nr = idx_orig_rows;
+		  new_nc = idx_orig_columns;
+		}
+	      else
+		{
+		  new_nr = n;
+		  new_nc = 1;
+		}
+
+	      retval = Sparse<T> (new_nr, new_nc, new_nzmx);
+
+	      if (nr == 1)
+		{
+		  octave_idx_type jj = 0;
+		  retval.xcidx(0) = 0;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      OCTAVE_QUIT;
+
+		      octave_idx_type ii = idx_arg.elem (i);
+		      if (ii < len)
+			if (cidx(ii) != cidx(ii+1))
+			  {
+			    retval.xdata(jj) = data(cidx(ii));
+			    retval.xridx(jj++) = 0;
+			  }
+		      retval.xcidx(i/new_nr+1) = jj;
+		    }
+		}
+	      else
+		{
+		  octave_idx_type jj = 0;
+		  retval.xcidx(0) = 0;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      octave_idx_type ii = idx_arg.elem (i);
+		      if (ii < len)
+			for (octave_idx_type j = 0; j < nz; j++)
+			  {
+			    OCTAVE_QUIT;
+
+			    if (ridx(j) == ii)
+			      {
+				retval.xdata(jj) = data(j);
+				retval.xridx(jj++) = i;
+			      }
+			    if (ridx(j) >= ii)
+			      break;
+			  }
+		      retval.xcidx(i/new_nr+1) = jj;
+		    }
+		}
+	    }
+	}
+    }
+  else
+    {
+      (*current_liboctave_warning_with_id_handler) 
+	("Octave:fortran-indexing", "single index used for sparse matrix");
+
+      // This code is only for indexing matrices.  The vector
+      // cases are handled above.
+
+      idx_arg.freeze (nr * nc, "matrix", resize_ok);
+
+      if (idx_arg)
+	{
+	  octave_idx_type result_nr = idx_orig_rows;
+	  octave_idx_type result_nc = idx_orig_columns;
+
+	  if (nz < 1)
+	    retval = Sparse<T> (result_nr, result_nc);
+	  else
+	    {
+	      // Count number of non-zero elements
+	      octave_idx_type new_nzmx = 0;
+	      octave_idx_type kk = 0;
+	      for (octave_idx_type j = 0; j < result_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < result_nr; i++)
+		    {
+		      OCTAVE_QUIT;
+		      
+		      octave_idx_type ii = idx_arg.elem (kk++);
+		      if (ii < orig_len)
+			{
+			  octave_idx_type fr = ii % nr;
+			  octave_idx_type fc = (ii - fr) / nr;
+			  for (octave_idx_type k = cidx(fc); k < cidx(fc+1); k++)
+			    {
+			      if (ridx(k) == fr)
+				new_nzmx++;
+			      if (ridx(k) >= fr)
+				break;
+			    }
+			}
+		    }
+		}
+	      
+	      retval = Sparse<T> (result_nr, result_nc, new_nzmx);
+
+	      kk = 0;
+	      octave_idx_type jj = 0;
+	      retval.xcidx(0) = 0;
+	      for (octave_idx_type j = 0; j < result_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < result_nr; i++)
+		    {
+		      OCTAVE_QUIT;
+
+		      octave_idx_type ii = idx_arg.elem (kk++);
+		      if (ii < orig_len)
+			{
+			  octave_idx_type fr = ii % nr;
+			  octave_idx_type fc = (ii - fr) / nr;
+			  for (octave_idx_type k = cidx(fc); k < cidx(fc+1); k++)
+			    {
+			      if (ridx(k) == fr)
+				{
+				  retval.xdata(jj) = data(k);
+				  retval.xridx(jj++) = i;
+				}
+			      if (ridx(k) >= fr)
+				break;
+			    }
+			}
+		    }
+		  retval.xcidx(j+1) = jj;
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+    }
+
+  return retval;
+}
+
+struct 
+idx_node 
+{
+  octave_idx_type i;
+  struct idx_node *next;
+};		    
+
+template <class T>
+Sparse<T>
+Sparse<T>::index (idx_vector& idx_i, idx_vector& idx_j, int resize_ok) const
+{
+  Sparse<T> retval;
+
+  assert (ndims () == 2);
+
+  octave_idx_type nr = dim1 ();
+  octave_idx_type nc = dim2 ();
+
+  octave_idx_type n = idx_i.freeze (nr, "row", resize_ok);
+  octave_idx_type m = idx_j.freeze (nc, "column", resize_ok);
+
+  if (idx_i && idx_j)
+    {
+      if (idx_i.orig_empty () || idx_j.orig_empty () || n == 0 || m == 0)
+	{
+	  retval.resize_no_fill (n, m);
+	}
+      else 
+	{
+	  int idx_i_colon = idx_i.is_colon_equiv (nr);
+	  int idx_j_colon = idx_j.is_colon_equiv (nc);
+
+	  if (idx_i_colon && idx_j_colon)
+	    {
+	      retval = *this;
+	    }
+	  else
+	    {
+	      // Identify if the indices have any repeated values
+	      bool permutation = true;
+
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, itmp, 
+				   (nr > nc ? nr : nc));
+	      octave_sort<octave_idx_type> lsort;
+
+	      if (n > nr || m > nc)
+		permutation = false;
+
+	      if (permutation && ! idx_i_colon)
+		{
+		  // Can't use something like
+		  //   idx_vector tmp_idx = idx_i;
+		  //   tmp_idx.sort (true);
+		  //   if (tmp_idx.length(nr) != n)
+		  //       permutation = false;
+		  // here as there is no make_unique function 
+		  // for idx_vector type.
+		  for (octave_idx_type i = 0; i < n; i++)
+		    itmp [i] = idx_i.elem (i);
+		  lsort.sort (itmp, n);
+		  for (octave_idx_type i = 1; i < n; i++)
+		    if (itmp[i-1] == itmp[i])
+		      {
+			permutation = false;
+			break;
+		      }
+		}
+	      if (permutation && ! idx_j_colon)
+		{
+		  for (octave_idx_type i = 0; i < m; i++)
+		    itmp [i] = idx_j.elem (i);
+		  lsort.sort (itmp, m);
+		  for (octave_idx_type i = 1; i < m; i++)
+		    if (itmp[i-1] == itmp[i])
+		      {
+			permutation = false;
+			break;
+		      }
+		}
+
+	      if (permutation)
+		{
+		  // Special case permutation like indexing for speed
+		  retval = Sparse<T> (n, m, nnz ());
+		  octave_idx_type *ri = retval.xridx ();
+	      
+		  std::vector<T> X (n);
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    itmp [i] = -1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    itmp[idx_i.elem(i)] = i;
+
+		  octave_idx_type kk = 0;
+		  retval.xcidx(0) = 0;
+		  for (octave_idx_type j = 0; j < m; j++)
+		    {
+		      octave_idx_type jj = idx_j.elem (j);
+		      for (octave_idx_type i = cidx(jj); i < cidx(jj+1); i++)
+			{
+			  OCTAVE_QUIT;
+
+			  octave_idx_type ii = itmp [ridx(i)];
+			  if (ii >= 0)
+			    {
+			      X [ii] = data (i);
+			      retval.xridx (kk++) = ii;
+			    }
+			}
+		      lsort.sort (ri + retval.xcidx (j), kk - retval.xcidx (j));
+		      for (octave_idx_type p = retval.xcidx (j); p < kk; p++)
+			retval.xdata (p) = X [retval.xridx (p)]; 
+		      retval.xcidx(j+1) = kk;
+		    }
+		  retval.maybe_compress ();
+		}
+	      else
+		{
+		  OCTAVE_LOCAL_BUFFER (struct idx_node, nodes, n); 
+		  OCTAVE_LOCAL_BUFFER (octave_idx_type, start_nodes, nr); 
+
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    start_nodes[i] = -1;
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    {
+		      octave_idx_type ii = idx_i.elem (i);
+		      nodes[i].i = i;
+		      nodes[i].next = 0;
+
+		      octave_idx_type node = start_nodes[ii];
+		      if (node == -1)
+			start_nodes[ii] = i;
+		      else
+			{
+			  while (nodes[node].next)
+			    node = nodes[node].next->i;
+			  nodes[node].next = nodes + i;
+			}
+		    }
+
+		  // First count the number of non-zero elements
+		  octave_idx_type new_nzmx = 0;
+		  for (octave_idx_type j = 0; j < m; j++)
+		    {
+		      octave_idx_type jj = idx_j.elem (j);
+
+		      if (jj < nc)
+			{
+			  for (octave_idx_type i = cidx(jj); 
+			       i < cidx(jj+1); i++)
+			    {
+			      OCTAVE_QUIT;
+
+			      octave_idx_type ii = start_nodes [ridx(i)];
+
+			      if (ii >= 0)
+				{
+				  struct idx_node inode = nodes[ii];
+			      
+				  while (true)
+				    {
+				      if (idx_i.elem (inode.i) < nr)
+					new_nzmx ++;
+				      if (inode.next == 0)
+					break;
+				      else
+					inode = *inode.next;
+				    }
+				}
+			    }
+			}
+		    }
+
+		  std::vector<T> X (n);
+		  retval = Sparse<T> (n, m, new_nzmx);
+		  octave_idx_type *ri = retval.xridx ();
+
+		  octave_idx_type kk = 0;
+		  retval.xcidx(0) = 0;
+		  for (octave_idx_type j = 0; j < m; j++)
+		    {
+		      octave_idx_type jj = idx_j.elem (j);
+		      if (jj < nc)
+			{
+			  for (octave_idx_type i = cidx(jj); 
+			       i < cidx(jj+1); i++)
+			    {
+			      OCTAVE_QUIT;
+
+			      octave_idx_type ii = start_nodes [ridx(i)];
+
+			      if (ii >= 0)
+				{
+				  struct idx_node inode = nodes[ii];
+			      
+				  while (true)
+				    {
+				      if (idx_i.elem (inode.i) < nr)
+					{
+					  X [inode.i] = data (i);
+					  retval.xridx (kk++) = inode.i;
+					}
+
+				      if (inode.next == 0)
+					break;
+				      else
+					inode = *inode.next;
+				    }
+				}
+			    }
+			  lsort.sort (ri + retval.xcidx (j), 
+				     kk - retval.xcidx (j));
+			  for (octave_idx_type p = retval.xcidx (j); 
+			       p < kk; p++)
+			    retval.xdata (p) = X [retval.xridx (p)]; 
+			  retval.xcidx(j+1) = kk;
+			}
+		    }
+		}
+	    }
+	}
+    }
+  // idx_vector::freeze() printed an error message for us.
+
+  return retval;
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::index (Array<idx_vector>& ra_idx, int resize_ok) const
+{
+
+  if (ra_idx.length () != 2)
+    {
+      (*current_liboctave_error_handler) ("range error for index");
+      return *this;
+    }
+
+  return index (ra_idx (0), ra_idx (1), resize_ok);
+}
+
+// Can't use versions of these in Array.cc due to duplication of the 
+// instantiations for Array<double and Sparse<double>, etc
+template <class T>
+bool 
+sparse_ascending_compare (typename ref_param<T>::type a, 
+                          typename ref_param<T>::type b)
+{
+  return (a < b);
+}
+
+template <class T>
+bool 
+sparse_descending_compare (typename ref_param<T>::type a, 
+                           typename ref_param<T>::type b)
+{
+  return (a > b);
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::sort (octave_idx_type dim, sortmode mode) const
+{
+  Sparse<T> m = *this;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  if (m.length () < 1)
+    return m;
+
+  if (dim > 0)
+    {
+      m = m.transpose ();
+      nr = m.rows ();
+      nc = m.columns ();
+    }
+
+  octave_sort<T> lsort;
+
+  if (mode == ASCENDING) 
+    lsort.set_compare (sparse_ascending_compare<T>);
+  else if (mode == DESCENDING)
+    lsort.set_compare (sparse_descending_compare<T>);
+  else
+    abort ();
+
+  T *v = m.data ();
+  octave_idx_type *mcidx = m.cidx ();
+  octave_idx_type *mridx = m.ridx ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      octave_idx_type ns = mcidx [j + 1] - mcidx [j];
+      lsort.sort (v, ns);
+
+      octave_idx_type i;
+      if (mode == ASCENDING) 
+	{
+	  for (i = 0; i < ns; i++)
+	    if (sparse_ascending_compare<T> (static_cast<T> (0), v [i]))
+	      break;
+	}
+      else
+	{
+	  for (i = 0; i < ns; i++)
+	    if (sparse_descending_compare<T> (static_cast<T> (0), v [i]))
+	      break;
+	}
+      for (octave_idx_type k = 0; k < i; k++)
+	mridx [k] = k;
+      for (octave_idx_type k = i; k < ns; k++)
+	mridx [k] = k - ns + nr; 
+
+      v += ns;
+      mridx += ns;
+    }
+
+  if (dim > 0)
+      m = m.transpose ();
+
+  return m;
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::sort (Array<octave_idx_type> &sidx, octave_idx_type dim, 
+		 sortmode mode) const
+{
+  Sparse<T> m = *this;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  if (m.length () < 1)
+    {
+      sidx = Array<octave_idx_type> (dim_vector (nr, nc));
+      return m;
+    }
+
+  if (dim > 0)
+    {
+      m = m.transpose ();
+      nr = m.rows ();
+      nc = m.columns ();
+    }
+
+  octave_sort<T> indexed_sort;
+
+  if (mode == ASCENDING) 
+    indexed_sort.set_compare (sparse_ascending_compare<T>);
+  else if (mode == DESCENDING)
+    indexed_sort.set_compare (sparse_descending_compare<T>);
+  else
+    abort ();
+
+  T *v = m.data ();
+  octave_idx_type *mcidx = m.cidx ();
+  octave_idx_type *mridx = m.ridx ();
+
+  sidx = Array<octave_idx_type> (dim_vector (nr, nc));
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, vi, nr);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      octave_idx_type ns = mcidx [j + 1] - mcidx [j];
+      octave_idx_type offset = j * nr;
+
+      if (ns == 0)
+	{
+	  for (octave_idx_type k = 0; k < nr; k++)
+	    sidx (offset + k) = k;
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < ns; i++)
+            vi[i] = mridx[i];
+
+	  indexed_sort.sort (v, vi, ns);
+
+	  octave_idx_type i;
+	  if (mode == ASCENDING) 
+	    {
+	      for (i = 0; i < ns; i++)
+		if (sparse_ascending_compare<T> (static_cast<T> (0), v[i]))
+		  break;
+	    }
+	  else
+	    {
+	      for (i = 0; i < ns; i++)
+		if (sparse_descending_compare<T> (static_cast<T> (0), v[i]))
+		  break;
+	    }
+
+	  octave_idx_type ii = 0;
+	  octave_idx_type jj = i;
+	  for (octave_idx_type k = 0; k < nr; k++)
+	    {
+	      if (ii < ns && mridx[ii] == k)
+		ii++;
+	      else
+		sidx (offset + jj++) = k;
+	    }
+
+	  for (octave_idx_type k = 0; k < i; k++)
+	    {
+	      sidx (k + offset) = vi [k];
+	      mridx [k] = k;
+	    }
+
+	  for (octave_idx_type k = i; k < ns; k++)
+	    {
+	      sidx (k - ns + nr + offset) = vi [k];
+	      mridx [k] = k - ns + nr; 
+	    }
+
+	  v += ns;
+	  mridx += ns;
+	}
+    }
+
+  if (dim > 0)
+    {
+      m = m.transpose ();
+      sidx = sidx.transpose ();
+    }
+
+  return m;
+}
+
+template <class T>
+Sparse<T>
+Sparse<T>::diag (octave_idx_type k) const
+{
+  octave_idx_type nnr = rows ();
+  octave_idx_type nnc = cols ();
+  Sparse<T> d;
+
+  if (nnr == 0 || nnc == 0)
+    ; // do nothing
+  else if (nnr != 1 && nnc != 1)
+    {
+      if (k > 0)
+	nnc -= k;
+      else if (k < 0)
+	nnr += k;
+
+      if (nnr > 0 && nnc > 0)
+	{
+	  octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc;
+
+	  // Count the number of non-zero elements
+	  octave_idx_type nel = 0;
+	  if (k > 0)
+	    {
+	      for (octave_idx_type i = 0; i < ndiag; i++)
+		if (elem (i, i+k) != 0.)
+		  nel++;
+	    }
+	  else if ( k < 0)
+	    {
+	      for (octave_idx_type i = 0; i < ndiag; i++)
+		if (elem (i-k, i) != 0.)
+		  nel++;
+	    }
+	  else
+	    {
+	      for (octave_idx_type i = 0; i < ndiag; i++)
+		if (elem (i, i) != 0.)
+		  nel++;
+	    }
+      
+	  d = Sparse<T> (ndiag, 1, nel);
+	  d.xcidx (0) = 0;
+	  d.xcidx (1) = nel;
+
+	  octave_idx_type ii = 0;
+	  if (k > 0)
+	    {
+	      for (octave_idx_type i = 0; i < ndiag; i++)
+		{
+		  T tmp = elem (i, i+k);
+		  if (tmp != 0.)
+		    {
+		      d.xdata (ii) = tmp;
+		      d.xridx (ii++) = i;
+		    }
+		}
+	    }
+	  else if ( k < 0)
+	    {
+	      for (octave_idx_type i = 0; i < ndiag; i++)
+		{
+		  T tmp = elem (i-k, i);
+		  if (tmp != 0.)
+		    {
+		      d.xdata (ii) = tmp;
+		      d.xridx (ii++) = i;
+		    }
+		}
+	    }
+	  else
+	    {
+	      for (octave_idx_type i = 0; i < ndiag; i++)
+		{
+		  T tmp = elem (i, i);
+		  if (tmp != 0.)
+		    {
+		      d.xdata (ii) = tmp;
+		      d.xridx (ii++) = i;
+		    }
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) 
+	  ("diag: requested diagonal out of range");
+    }
+  else if (nnr != 0 && nnc != 0)
+    {
+      octave_idx_type roff = 0;
+      octave_idx_type coff = 0;
+      if (k > 0) 
+	{
+	  roff = 0;
+	  coff = k;
+	} 
+      else if (k < 0) 
+	{
+	  roff = -k;
+	  coff = 0;
+	}
+
+      if (nnr == 1) 
+	{
+	  octave_idx_type n = nnc + std::abs (k);
+	  octave_idx_type nz = nzmax ();
+	  d = Sparse<T> (n, n, nz);
+	  for (octave_idx_type i = 0; i < coff+1; i++)
+	    d.xcidx (i) = 0;
+	  for (octave_idx_type j = 0; j < nnc; j++)
+	    {
+	      for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		{
+		  d.xdata (i) = data (i);
+		  d.xridx (i) = j + roff;
+		}
+	      d.xcidx (j + coff + 1) = cidx(j+1);
+	    }
+	  for (octave_idx_type i = nnc + coff + 1; i < n + 1; i++)
+	    d.xcidx (i) = nz;
+	} 
+      else 
+	{
+	  octave_idx_type n = nnr + std::abs (k);
+	  octave_idx_type nz = nzmax ();
+	  octave_idx_type ii = 0;
+	  octave_idx_type ir = ridx(0);
+	  d = Sparse<T> (n, n, nz);
+	  for (octave_idx_type i = 0; i < coff+1; i++)
+	    d.xcidx (i) = 0;
+	  for (octave_idx_type i = 0; i < nnr; i++)
+	    {
+	      if (ir == i)
+		{
+		  d.xdata (ii) = data (ii);
+		  d.xridx (ii++) = ir + roff;
+		  if (ii != nz)
+		    ir = ridx (ii);
+		}
+	      d.xcidx (i + coff + 1) = ii;
+	    }
+	  for (octave_idx_type i = nnr + coff + 1; i < n+1; i++)
+	    d.xcidx (i) = nz;
+	}
+    }
+
+  return d;
+}
+
+// FIXME
+// Unfortunately numel can overflow for very large but very sparse matrices.
+// For now just flag an error when this happens.
+template <class LT, class RT>
+int
+assign1 (Sparse<LT>& lhs, const Sparse<RT>& rhs)
+{
+  int retval = 1;
+
+  idx_vector *idx_tmp = lhs.get_idx ();
+
+  idx_vector lhs_idx = idx_tmp[0];
+
+  octave_idx_type lhs_len = lhs.numel ();
+  octave_idx_type rhs_len = rhs.numel ();
+
+  uint64_t long_lhs_len = 
+    static_cast<uint64_t> (lhs.rows ()) *
+    static_cast<uint64_t> (lhs.cols ());
+
+  uint64_t long_rhs_len = 
+    static_cast<uint64_t> (rhs.rows ()) *
+    static_cast<uint64_t> (rhs.cols ());
+
+  if (long_rhs_len != static_cast<uint64_t>(rhs_len) ||
+      long_lhs_len != static_cast<uint64_t>(lhs_len))
+    {
+      (*current_liboctave_error_handler)
+	("A(I) = X: Matrix dimensions too large to ensure correct\n",
+	 "operation. This is an limitation that should be removed\n",
+	 "in the future.");
+
+      lhs.clear_index ();
+      return 0;
+    }
+
+  octave_idx_type nr = lhs.rows ();
+  octave_idx_type nc = lhs.cols ();
+  octave_idx_type nz = lhs.nnz ();
+
+  octave_idx_type n = lhs_idx.freeze (lhs_len, "vector", true);
+
+  if (n != 0)
+    {
+      octave_idx_type max_idx = lhs_idx.max () + 1;
+      max_idx = max_idx < lhs_len ? lhs_len : max_idx;
+
+      // Take a constant copy of lhs. This means that elem won't 
+      // create missing elements.
+      const Sparse<LT> c_lhs (lhs);
+
+      if (rhs_len == n)
+	{
+	  octave_idx_type new_nzmx = lhs.nnz ();
+
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx, n);
+	  if (! lhs_idx.is_colon ())
+	    {
+	      // Ok here we have to be careful with the indexing,
+	      // to treat cases like "a([3,2,1]) = b", and still 
+	      // handle the need for strict sorting of the sparse 
+	      // elements.
+	      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *, sidx, n);
+	      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort, sidxX, n);
+
+	      for (octave_idx_type i = 0; i < n; i++)
+		{
+		  sidx[i] = &sidxX[i];
+		  sidx[i]->i = lhs_idx.elem(i);
+		  sidx[i]->idx = i;
+		}
+			  
+	      OCTAVE_QUIT;
+	      octave_sort<octave_idx_vector_sort *> 
+		sort (octave_idx_vector_comp);
+
+	      sort.sort (sidx, n);
+
+	      intNDArray<octave_idx_type> new_idx (dim_vector (n,1));
+
+	      for (octave_idx_type i = 0; i < n; i++)
+		{
+		  new_idx.xelem(i) = sidx[i]->i;
+		  rhs_idx[i] = sidx[i]->idx;
+		}
+
+	      lhs_idx = idx_vector (new_idx);
+	    }
+	  else
+	    for (octave_idx_type i = 0; i < n; i++)
+	      rhs_idx[i] = i;
+
+	  // First count the number of non-zero elements
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      OCTAVE_QUIT;
+
+	      octave_idx_type ii = lhs_idx.elem (i);
+	      if (i < n - 1 && lhs_idx.elem (i + 1) == ii)
+		continue;
+	      if (ii < lhs_len && c_lhs.elem(ii) != LT ())
+		new_nzmx--;
+	      if (rhs.elem(rhs_idx[i]) != RT ())
+		new_nzmx++;
+	    }
+
+	  if (nr > 1)
+	    {
+	      Sparse<LT> tmp ((max_idx > nr ? max_idx : nr), 1, new_nzmx);
+	      tmp.cidx(0) = 0;
+	      tmp.cidx(1) = new_nzmx;
+
+	      octave_idx_type i = 0;
+	      octave_idx_type ii = 0;
+	      if (i < nz)
+		ii = c_lhs.ridx(i);
+
+	      octave_idx_type j = 0;
+	      octave_idx_type jj = lhs_idx.elem(j);
+
+	      octave_idx_type kk = 0;
+
+	      while (j < n || i < nz)
+		{
+		  if (j < n - 1 && lhs_idx.elem (j + 1) == jj)
+		    {
+		      j++;
+		      jj = lhs_idx.elem (j);
+		      continue;
+		    }
+		  if (j == n || (i < nz && ii < jj))
+		    {
+		      tmp.xdata (kk) = c_lhs.data (i);
+		      tmp.xridx (kk++) = ii;
+		      if (++i < nz)
+			ii = c_lhs.ridx(i);
+		    }
+		  else
+		    {
+		      RT rtmp = rhs.elem (rhs_idx[j]);
+		      if (rtmp != RT ())
+			{
+			  tmp.xdata (kk) = rtmp;
+			  tmp.xridx (kk++) = jj;
+			}
+
+		      if (ii == jj && i < nz)
+			if (++i < nz)
+			  ii = c_lhs.ridx(i);
+		      if (++j < n)
+			jj = lhs_idx.elem(j);
+		    }
+		}
+
+	      lhs = tmp;
+	    }
+	  else
+	    {
+	      Sparse<LT> tmp (1, (max_idx > nc ? max_idx : nc), new_nzmx);
+
+	      octave_idx_type i = 0;
+	      octave_idx_type ii = 0;
+	      while (ii < nc && c_lhs.cidx(ii+1) <= i)
+		ii++;
+
+	      octave_idx_type j = 0;
+	      octave_idx_type jj = lhs_idx.elem(j);
+
+	      octave_idx_type kk = 0;
+	      octave_idx_type ic = 0;
+
+	      while (j < n || i < nz)
+		{
+		  if (j < n - 1 && lhs_idx.elem (j + 1) == jj)
+		    {
+		      j++;
+		      jj = lhs_idx.elem (j);
+		      continue;
+		    }
+		  if (j == n || (i < nz && ii < jj))
+		    {
+		      while (ic <= ii)
+			tmp.xcidx (ic++) = kk;
+		      tmp.xdata (kk) = c_lhs.data (i);
+		      tmp.xridx (kk++) = 0;
+		      i++;
+		      while (ii < nc && c_lhs.cidx(ii+1) <= i)
+			ii++;
+		    }
+		  else
+		    {
+		      while (ic <= jj)
+			tmp.xcidx (ic++) = kk;
+
+		      RT rtmp = rhs.elem (rhs_idx[j]);
+		      if (rtmp != RT ())
+			{
+			  tmp.xdata (kk) = rtmp;
+			  tmp.xridx (kk++) = 0;
+			}
+		      if (ii == jj)
+			{
+			  i++;
+			  while (ii < nc && c_lhs.cidx(ii+1) <= i)
+			    ii++;
+			}
+		      j++;
+		      if (j < n)
+			jj = lhs_idx.elem(j);
+		    }
+		}
+
+	      for (octave_idx_type iidx = ic; iidx < max_idx+1; iidx++)
+		tmp.xcidx(iidx) = kk;
+
+	      lhs = tmp;
+	    }
+	}
+      else if (rhs_len == 1)
+	{
+	  octave_idx_type new_nzmx = lhs.nnz ();
+	  RT scalar = rhs.elem (0);
+	  bool scalar_non_zero = (scalar != RT ());
+	  lhs_idx.sort (true);
+	  n = lhs_idx.length (n);
+
+	  // First count the number of non-zero elements
+	  if (scalar != RT ())
+	    new_nzmx += n;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      OCTAVE_QUIT;
+
+	      octave_idx_type ii = lhs_idx.elem (i);
+	      if (ii < lhs_len && c_lhs.elem(ii) != LT ())
+		new_nzmx--;
+	    }
+
+	  if (nr > 1)
+	    {
+	      Sparse<LT> tmp ((max_idx > nr ? max_idx : nr), 1, new_nzmx);
+	      tmp.cidx(0) = 0;
+	      tmp.cidx(1) = new_nzmx;
+
+	      octave_idx_type i = 0;
+	      octave_idx_type ii = 0;
+	      if (i < nz)
+		ii = c_lhs.ridx(i);
+
+	      octave_idx_type j = 0;
+	      octave_idx_type jj = lhs_idx.elem(j);
+
+	      octave_idx_type kk = 0;
+
+	      while (j < n || i < nz)
+		{
+		  if (j == n || (i < nz && ii < jj))
+		    {
+		      tmp.xdata (kk) = c_lhs.data (i);
+		      tmp.xridx (kk++) = ii;
+		      if (++i < nz)
+			ii = c_lhs.ridx(i);
+		    }
+		  else
+		    {
+		      if (scalar_non_zero)
+			{
+			  tmp.xdata (kk) = scalar;
+			  tmp.xridx (kk++) = jj;
+			}
+
+		      if (ii == jj && i < nz)
+			if (++i < nz)
+			  ii = c_lhs.ridx(i);
+		      if (++j < n)
+			jj = lhs_idx.elem(j);
+		    }
+		}
+
+	      lhs = tmp;
+	    }
+	  else
+	    {
+	      Sparse<LT> tmp (1, (max_idx > nc ? max_idx : nc), new_nzmx);
+
+	      octave_idx_type i = 0;
+	      octave_idx_type ii = 0;
+	      while (ii < nc && c_lhs.cidx(ii+1) <= i)
+		ii++;
+
+	      octave_idx_type j = 0;
+	      octave_idx_type jj = lhs_idx.elem(j);
+
+	      octave_idx_type kk = 0;
+	      octave_idx_type ic = 0;
+
+	      while (j < n || i < nz)
+		{
+		  if (j == n || (i < nz && ii < jj))
+		    {
+		      while (ic <= ii)
+			tmp.xcidx (ic++) = kk;
+		      tmp.xdata (kk) = c_lhs.data (i);
+		      i++;
+		      while (ii < nc && c_lhs.cidx(ii+1) <= i)
+			ii++;
+                      tmp.xridx (kk++) = 0;
+		    }
+		  else
+		    {
+		      while (ic <= jj)
+			tmp.xcidx (ic++) = kk;
+		      if (scalar_non_zero)
+                        {
+                          tmp.xdata (kk) = scalar;
+                          tmp.xridx (kk++) = 0;
+                        }
+		      if (ii == jj)
+			{
+			  i++;
+			  while (ii < nc && c_lhs.cidx(ii+1) <= i)
+			    ii++;
+			}
+		      j++;
+		      if (j < n)
+			jj = lhs_idx.elem(j);
+		    }
+		}
+
+	      for (octave_idx_type iidx = ic; iidx < max_idx+1; iidx++)
+		tmp.xcidx(iidx) = kk;
+
+	      lhs = tmp;
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("A(I) = X: X must be a scalar or a vector with same length as I");
+
+	  retval = 0;
+	}
+    }
+  else if (lhs_idx.is_colon ())
+    {
+      if (lhs_len == 0)
+	{
+
+	  octave_idx_type new_nzmx = rhs.nnz ();
+	  Sparse<LT> tmp (1, rhs_len, new_nzmx);
+
+	  octave_idx_type ii = 0;
+	  octave_idx_type jj = 0;
+	  for (octave_idx_type i = 0; i < rhs.cols(); i++)
+	    for (octave_idx_type j = rhs.cidx(i); j < rhs.cidx(i+1); j++)
+	      {
+		OCTAVE_QUIT;
+		for (octave_idx_type k = jj; k <= i * rhs.rows() + rhs.ridx(j); k++)
+		  tmp.cidx(jj++) = ii;
+
+		tmp.data(ii) = rhs.data(j);
+		tmp.ridx(ii++) = 0;
+	      }
+
+	  for (octave_idx_type i = jj; i < rhs_len + 1; i++)
+	    tmp.cidx(i) = ii;
+
+	  lhs = tmp;
+	}
+      else
+	(*current_liboctave_error_handler)
+	  ("A(:) = X: A must be the same size as X");
+    }
+  else if (! (rhs_len == 1 || rhs_len == 0))
+    {
+      (*current_liboctave_error_handler)
+	("A([]) = X: X must also be an empty matrix or a scalar");
+
+      retval = 0;
+    }
+
+  lhs.clear_index ();
+
+  return retval;
+}
+
+template <class LT, class RT>
+int
+assign (Sparse<LT>& lhs, const Sparse<RT>& rhs)
+{
+  int retval = 1;
+
+  int n_idx = lhs.index_count ();
+
+  octave_idx_type lhs_nr = lhs.rows ();
+  octave_idx_type lhs_nc = lhs.cols ();
+  octave_idx_type lhs_nz = lhs.nnz ();
+
+  octave_idx_type rhs_nr = rhs.rows ();
+  octave_idx_type rhs_nc = rhs.cols ();
+
+  idx_vector *tmp = lhs.get_idx ();
+
+  idx_vector idx_i;
+  idx_vector idx_j;
+
+  if (n_idx > 2)
+    {
+      (*current_liboctave_error_handler)
+        ("A(I, J) = X: can only have 1 or 2 indexes for sparse matrices");
+
+      lhs.clear_index ();
+      return 0;
+    }
+
+  if (n_idx > 1)
+    idx_j = tmp[1];
+
+  if (n_idx > 0)
+    idx_i = tmp[0];
+
+  // Take a constant copy of lhs. This means that ridx and family won't 
+  // call make_unique.
+  const Sparse<LT> c_lhs (lhs);
+
+  if (n_idx == 2)
+    {
+      octave_idx_type n = idx_i.freeze (lhs_nr, "row", true);
+      octave_idx_type m = idx_j.freeze (lhs_nc, "column", true);
+
+      int idx_i_is_colon = idx_i.is_colon ();
+      int idx_j_is_colon = idx_j.is_colon ();
+
+      if (lhs_nr == 0 && lhs_nc == 0)
+	{
+	  if (idx_i_is_colon)
+	    n = rhs_nr;
+
+	  if (idx_j_is_colon)
+	    m = rhs_nc;
+	}
+
+      if (idx_i && idx_j)
+        {
+          if (rhs_nr == 1 && rhs_nc == 1 && n >= 0 && m >= 0)
+            {
+              if (n > 0 && m > 0)
+                {
+                  idx_i.sort (true);
+                  n = idx_i.length (n);
+                  idx_j.sort (true);
+                  m = idx_j.length (m);
+
+                  octave_idx_type max_row_idx = idx_i_is_colon ? rhs_nr : 
+                    idx_i.max () + 1;
+                  octave_idx_type max_col_idx = idx_j_is_colon ? rhs_nc : 
+                    idx_j.max () + 1;
+                  octave_idx_type new_nr = max_row_idx > lhs_nr ? 
+                    max_row_idx : lhs_nr;
+                  octave_idx_type new_nc = max_col_idx > lhs_nc ? 
+                    max_col_idx : lhs_nc;
+                  RT scalar = rhs.elem (0, 0);
+
+                  // Count the number of non-zero terms
+                  octave_idx_type new_nzmx = lhs.nnz ();
+                  for (octave_idx_type j = 0; j < m; j++)
+                    {
+                      octave_idx_type jj = idx_j.elem (j);
+                      if (jj < lhs_nc)
+                        {
+                          for (octave_idx_type i = 0; i < n; i++)
+                            {
+                              OCTAVE_QUIT;
+
+                              octave_idx_type ii = idx_i.elem (i);
+
+                              if (ii < lhs_nr)
+                                {
+                                  for (octave_idx_type k = c_lhs.cidx(jj); 
+                                       k < c_lhs.cidx(jj+1); k++)
+                                    {
+                                      if (c_lhs.ridx(k) == ii)
+                                        new_nzmx--;
+                                      if (c_lhs.ridx(k) >= ii)
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                  if (scalar != RT())
+                    new_nzmx += m * n;
+
+                  Sparse<LT> stmp (new_nr, new_nc, new_nzmx);
+
+                  octave_idx_type jji = 0;
+                  octave_idx_type jj = idx_j.elem (jji);
+                  octave_idx_type kk = 0;
+                  stmp.cidx(0) = 0;
+                  for (octave_idx_type j = 0; j < new_nc; j++)
+                    {
+                      if (jji < m && jj == j)
+                        {
+                          octave_idx_type iii = 0;
+                          octave_idx_type ii = idx_i.elem (iii);
+                          octave_idx_type ppp = 0;
+                          octave_idx_type ppi = (j >= lhs_nc ? 0 : 
+                                                 c_lhs.cidx(j+1) - 
+                                                 c_lhs.cidx(j));
+                          octave_idx_type pp = (ppp < ppi ? 
+                                                c_lhs.ridx(c_lhs.cidx(j)+ppp) :
+                                                new_nr);
+                          while (ppp < ppi || iii < n)
+                            {
+                              if (iii < n && ii <= pp)
+                                {
+                                  if (scalar != RT ())
+                                    {
+                                      stmp.data(kk) = scalar;
+                                      stmp.ridx(kk++) = ii;
+                                    }
+                                  if (ii == pp)
+                                    pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr);					
+                                  if (++iii < n)
+                                    ii = idx_i.elem(iii);
+                                }
+                              else
+                                {
+                                  stmp.data(kk) = 
+                                    c_lhs.data(c_lhs.cidx(j)+ppp);
+                                  stmp.ridx(kk++) = pp;
+                                  pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr);
+                                }
+                            }
+                          if (++jji < m)
+                            jj = idx_j.elem(jji);
+                        }
+                      else if (j < lhs_nc) 
+                        {
+                          for (octave_idx_type i = c_lhs.cidx(j); 
+                               i < c_lhs.cidx(j+1); i++)
+                            {
+                              stmp.data(kk) = c_lhs.data(i);
+                              stmp.ridx(kk++) = c_lhs.ridx(i);
+                            }
+                        }
+                      stmp.cidx(j+1) = kk;
+                    }
+
+                  lhs = stmp;
+                }
+              else
+                {
+#if 0
+                  // FIXME -- the following code will make this
+                  // function behave the same as the full matrix
+                  // case for things like
+                  //
+                  // x = sparse (ones (2));
+                  // x([],3) = 2;
+                  //
+                  // x =
+                  //
+                  // Compressed Column Sparse (rows = 2, cols = 3, nnz = 4)
+                  //
+                  // (1, 1) ->  1
+                  // (2, 1) ->  1
+                  // (1, 2) ->  1
+                  // (2, 2) ->  1
+                  //
+                  // However, Matlab doesn't resize in this case
+                  // even though it does in the full matrix case.
+
+                  if (n > 0)
+                    {
+                      octave_idx_type max_row_idx = idx_i_is_colon ? 
+                        rhs_nr : idx_i.max () + 1;
+                      octave_idx_type new_nr = max_row_idx > lhs_nr ? 
+                        max_row_idx : lhs_nr;
+                      octave_idx_type new_nc = lhs_nc;
+
+                      lhs.resize (new_nr, new_nc);
+                    }
+                  else if (m > 0)
+                    {
+                      octave_idx_type max_col_idx = idx_j_is_colon ? 
+                        rhs_nc : idx_j.max () + 1;
+                      octave_idx_type new_nr = lhs_nr;
+                      octave_idx_type new_nc = max_col_idx > lhs_nc ? 
+                        max_col_idx : lhs_nc;
+
+                      lhs.resize  (new_nr, new_nc);
+                    }
+#endif
+                }
+            }
+          else if (n == rhs_nr && m == rhs_nc)
+            {
+              if (n > 0 && m > 0)
+                {
+                  octave_idx_type max_row_idx = idx_i_is_colon ? rhs_nr : 
+                    idx_i.max () + 1;
+                  octave_idx_type max_col_idx = idx_j_is_colon ? rhs_nc : 
+                    idx_j.max () + 1;
+                  octave_idx_type new_nr = max_row_idx > lhs_nr ?
+                    max_row_idx : lhs_nr;
+                  octave_idx_type new_nc = max_col_idx > lhs_nc ? 
+                    max_col_idx : lhs_nc;
+
+                  OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx_i, n);
+                  if (! idx_i.is_colon ())
+                    {
+                      // Ok here we have to be careful with the indexing,
+                      // to treat cases like "a([3,2,1],:) = b", and still 
+                      // handle the need for strict sorting of the sparse 
+                      // elements.
+                      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *,
+                                           sidx, n);
+                      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort,
+                                           sidxX, n);
+
+                      for (octave_idx_type i = 0; i < n; i++)
+                        {
+                          sidx[i] = &sidxX[i];
+                          sidx[i]->i = idx_i.elem(i);
+                          sidx[i]->idx = i;
+                        }
+
+                      OCTAVE_QUIT;
+                      octave_sort<octave_idx_vector_sort *> 
+                        sort (octave_idx_vector_comp);
+
+                      sort.sort (sidx, n);
+
+                      intNDArray<octave_idx_type> new_idx (dim_vector (n,1));
+
+                      for (octave_idx_type i = 0; i < n; i++)
+                        {
+                          new_idx.xelem(i) = sidx[i]->i;
+                          rhs_idx_i[i] = sidx[i]->idx;
+                        }
+
+                      idx_i = idx_vector (new_idx);
+                    }
+                  else
+                    for (octave_idx_type i = 0; i < n; i++)
+                      rhs_idx_i[i] = i;
+
+                  OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx_j, m);
+                  if (! idx_j.is_colon ())
+                    {
+                      // Ok here we have to be careful with the indexing,
+                      // to treat cases like "a([3,2,1],:) = b", and still 
+                      // handle the need for strict sorting of the sparse 
+                      // elements.
+                      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *,
+                                           sidx, m);
+                      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort,
+                                           sidxX, m);
+
+                      for (octave_idx_type i = 0; i < m; i++)
+                        {
+                          sidx[i] = &sidxX[i];
+                          sidx[i]->i = idx_j.elem(i);
+                          sidx[i]->idx = i;
+                        }
+
+                      OCTAVE_QUIT;
+                      octave_sort<octave_idx_vector_sort *> 
+                        sort (octave_idx_vector_comp);
+
+                      sort.sort (sidx, m);
+
+                      intNDArray<octave_idx_type> new_idx (dim_vector (m,1));
+
+                      for (octave_idx_type i = 0; i < m; i++)
+                        {
+                          new_idx.xelem(i) = sidx[i]->i;
+                          rhs_idx_j[i] = sidx[i]->idx;
+                        }
+
+                      idx_j = idx_vector (new_idx);
+                    }
+                  else
+                    for (octave_idx_type i = 0; i < m; i++)
+                      rhs_idx_j[i] = i;
+
+                  // Maximum number of non-zero elements
+                  octave_idx_type new_nzmx = lhs.nnz() + rhs.nnz();
+
+                  Sparse<LT> stmp (new_nr, new_nc, new_nzmx);
+
+                  octave_idx_type jji = 0;
+                  octave_idx_type jj = idx_j.elem (jji);
+                  octave_idx_type kk = 0;
+                  stmp.cidx(0) = 0;
+                  for (octave_idx_type j = 0; j < new_nc; j++)
+                    {
+                      if (jji < m && jj == j)
+                        {
+                          octave_idx_type iii = 0;
+                          octave_idx_type ii = idx_i.elem (iii);
+                          octave_idx_type ppp = 0;
+                          octave_idx_type ppi = (j >= lhs_nc ? 0 : 
+                                                 c_lhs.cidx(j+1) - 
+                                                 c_lhs.cidx(j));
+                          octave_idx_type pp = (ppp < ppi ? 
+                                                c_lhs.ridx(c_lhs.cidx(j)+ppp) :
+                                                new_nr);
+                          while (ppp < ppi || iii < n)
+                            {
+                              if (iii < n && ii <= pp)
+                                {
+                                  if (iii < n - 1 && 
+                                      idx_i.elem (iii + 1) == ii)
+                                    {
+                                      iii++;
+                                      ii = idx_i.elem(iii);
+                                      continue;
+                                    }
+
+                                  RT rtmp = rhs.elem (rhs_idx_i[iii], 
+                                                      rhs_idx_j[jji]);
+                                  if (rtmp != RT ())
+                                    {
+                                      stmp.data(kk) = rtmp;
+                                      stmp.ridx(kk++) = ii;
+                                    }
+                                  if (ii == pp)
+                                    pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr);					
+                                  if (++iii < n)
+                                    ii = idx_i.elem(iii);
+                                }
+                              else
+                                {
+                                  stmp.data(kk) = 
+                                    c_lhs.data(c_lhs.cidx(j)+ppp);
+                                  stmp.ridx(kk++) = pp;
+                                  pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr);
+                                }
+                            }
+                          if (++jji < m)
+                            jj = idx_j.elem(jji);
+                        }
+                      else if (j < lhs_nc) 
+                        {
+                          for (octave_idx_type i = c_lhs.cidx(j); 
+                               i < c_lhs.cidx(j+1); i++)
+                            {
+                              stmp.data(kk) = c_lhs.data(i);
+                              stmp.ridx(kk++) = c_lhs.ridx(i);
+                            }
+                        }
+                      stmp.cidx(j+1) = kk;
+                    }
+
+                  stmp.maybe_compress();
+                  lhs = stmp;
+                }
+            }
+          else if (n == 0 && m == 0)
+            {
+              if (! ((rhs_nr == 1 && rhs_nc == 1)
+                     || (rhs_nr == 0 || rhs_nc == 0)))
+                {
+                  (*current_liboctave_error_handler)
+                    ("A([], []) = X: X must be an empty matrix or a scalar");
+
+                  retval = 0;
+                }
+            }
+          else
+            {
+              (*current_liboctave_error_handler)
+                ("A(I, J) = X: X must be a scalar or the number of elements in I must");
+              (*current_liboctave_error_handler)
+                ("match the number of rows in X and the number of elements in J must");
+              (*current_liboctave_error_handler)
+                ("match the number of columns in X");
+
+              retval = 0;
+            }
+        }
+      // idx_vector::freeze() printed an error message for us.
+    }
+  else if (n_idx == 1)
+    {
+      int lhs_is_empty = lhs_nr == 0 || lhs_nc == 0;
+
+      if (lhs_is_empty || (lhs_nr == 1 && lhs_nc == 1))
+	{
+	  octave_idx_type lhs_len = lhs.length ();
+
+	  // Called for side-effects on idx_i.
+	  idx_i.freeze (lhs_len, 0, true);
+
+	  if (idx_i)
+            {
+              if (lhs_is_empty
+                  && idx_i.is_colon ()
+                  && ! (rhs_nr == 1 || rhs_nc == 1))
+                {
+                  (*current_liboctave_warning_with_id_handler)
+                    ("Octave:fortran-indexing",
+                     "A(:) = X: X is not a vector or scalar");
+                }
+              else
+                {
+                  octave_idx_type idx_nr = idx_i.orig_rows ();
+                  octave_idx_type idx_nc = idx_i.orig_columns ();
+
+                  if (! (rhs_nr == idx_nr && rhs_nc == idx_nc))
+                    (*current_liboctave_warning_with_id_handler)
+                      ("Octave:fortran-indexing",
+                       "A(I) = X: X does not have same shape as I");
+                }
+
+              if (! assign1 (lhs, rhs))
+                retval = 0;
+            }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+      else if (lhs_nr == 1)
+	{
+	  idx_i.freeze (lhs_nc, "vector", true);
+
+	  if (idx_i)
+            {
+              if (! assign1 (lhs, rhs))
+                retval = 0;
+            }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+      else if (lhs_nc == 1)
+	{
+	  idx_i.freeze (lhs_nr, "vector", true);
+
+	  if (idx_i)
+	    {
+	      if (! assign1 (lhs, rhs))
+		retval = 0;
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+      else
+	{
+	  if (! idx_i.is_colon ())
+	    (*current_liboctave_warning_with_id_handler)
+	      ("Octave:fortran-indexing", "single index used for matrix");
+
+	  octave_idx_type lhs_len = lhs.length ();
+
+	  octave_idx_type len = idx_i.freeze (lhs_nr * lhs_nc, "matrix");
+
+	  if (idx_i)
+	    {
+	      if (len == 0)
+		{
+		  if (! ((rhs_nr == 1 && rhs_nc == 1)
+			 || (rhs_nr == 0 || rhs_nc == 0)))
+		    (*current_liboctave_error_handler)
+		      ("A([]) = X: X must be an empty matrix or scalar");
+		}
+	      else if (len == rhs_nr * rhs_nc)
+		{
+		  octave_idx_type new_nzmx = lhs_nz;
+		  OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx, len);
+		  
+		  if (! idx_i.is_colon ())
+		    {
+		      // Ok here we have to be careful with the indexing, to
+		      // treat cases like "a([3,2,1]) = b", and still handle
+		      // the need for strict sorting of the sparse elements.
+
+		      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *, sidx, 
+					   len);
+		      OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort, sidxX, 
+					   len);
+
+		      for (octave_idx_type i = 0; i < len; i++)
+			{
+			  sidx[i] = &sidxX[i];
+			  sidx[i]->i = idx_i.elem(i);
+			  sidx[i]->idx = i;
+			}
+
+		      OCTAVE_QUIT;
+		      octave_sort<octave_idx_vector_sort *> 
+			sort (octave_idx_vector_comp);
+
+		      sort.sort (sidx, len);
+
+		      intNDArray<octave_idx_type> new_idx (dim_vector (len,1));
+
+		      for (octave_idx_type i = 0; i < len; i++)
+			{
+			  new_idx.xelem(i) = sidx[i]->i;
+			  rhs_idx[i] = sidx[i]->idx;
+			}
+
+		      idx_i = idx_vector (new_idx);
+		    }
+		  else
+		    for (octave_idx_type i = 0; i < len; i++)
+		      rhs_idx[i] = i;
+
+		  // First count the number of non-zero elements
+		  for (octave_idx_type i = 0; i < len; i++)
+		    {
+		      OCTAVE_QUIT;
+		      
+		      octave_idx_type ii = idx_i.elem (i);
+		      if (i < len - 1 && idx_i.elem (i + 1) == ii)
+			continue;
+		      if (ii < lhs_len && c_lhs.elem(ii) != LT ())
+			new_nzmx--;
+		      if (rhs.elem(rhs_idx[i]) != RT ())
+			new_nzmx++;
+		    }
+
+		  Sparse<LT> stmp (lhs_nr, lhs_nc, new_nzmx);
+
+		  octave_idx_type i = 0;
+		  octave_idx_type ii = 0;
+		  octave_idx_type ic = 0;
+		  if (i < lhs_nz)
+		    {
+		      while (ic < lhs_nc && i >= c_lhs.cidx(ic+1))
+			ic++;
+		      ii = ic * lhs_nr + c_lhs.ridx(i);
+		    }
+
+		  octave_idx_type j = 0;
+		  octave_idx_type jj = idx_i.elem (j);
+		  octave_idx_type jr = jj % lhs_nr;
+		  octave_idx_type jc = (jj - jr) / lhs_nr;
+
+		  octave_idx_type kk = 0;
+		  octave_idx_type kc = 0;
+
+		  while (j < len || i < lhs_nz)
+		    {
+		      if (j < len - 1 && idx_i.elem (j + 1) == jj)
+			{
+			  j++;
+			  jj = idx_i.elem (j);
+			  jr = jj % lhs_nr;
+			  jc = (jj - jr) / lhs_nr;
+			  continue;
+			}
+
+		      if (j == len || (i < lhs_nz && ii < jj))
+			{
+			  while (kc <= ic)
+			    stmp.xcidx (kc++) = kk;
+			  stmp.xdata (kk) = c_lhs.data (i);
+			  stmp.xridx (kk++) = c_lhs.ridx (i);
+			  i++;
+			  while (ic < lhs_nc && i >= c_lhs.cidx(ic+1))
+			    ic++;
+			  if (i < lhs_nz)
+			    ii = ic * lhs_nr + c_lhs.ridx(i);
+			}
+		      else
+			{
+			  while (kc <= jc)
+			    stmp.xcidx (kc++) = kk;
+			  RT rtmp = rhs.elem (rhs_idx[j]);
+			  if (rtmp != RT ())
+			    {
+			      stmp.xdata (kk) = rtmp;
+			      stmp.xridx (kk++) = jr;
+			    }
+			  if (ii == jj)
+			    {
+			      i++;
+			      while (ic < lhs_nc && i >= c_lhs.cidx(ic+1))
+				ic++;
+			      if (i < lhs_nz)
+				ii = ic * lhs_nr + c_lhs.ridx(i);
+			    }
+			  j++;
+			  if (j < len)
+			    {
+			      jj = idx_i.elem (j);
+			      jr = jj % lhs_nr;
+			      jc = (jj - jr) / lhs_nr;
+			    }
+			}
+		    }
+
+		  for (octave_idx_type iidx = kc; iidx < lhs_nc+1; iidx++)
+		    stmp.xcidx(iidx) = kk; 
+
+		  lhs = stmp;
+		}
+	      else if (rhs_nr == 1 && rhs_nc == 1)
+		{
+		  RT scalar = rhs.elem (0, 0);
+		  octave_idx_type new_nzmx = lhs_nz;
+		  idx_i.sort (true);
+		  len = idx_i.length (len);
+
+		  // First count the number of non-zero elements
+		  if (scalar != RT ())
+		    new_nzmx += len;
+		  for (octave_idx_type i = 0; i < len; i++)
+		    {
+		      OCTAVE_QUIT;
+		      octave_idx_type ii = idx_i.elem (i);
+		      if (ii < lhs_len && c_lhs.elem(ii) != LT ())
+			new_nzmx--;
+		    }
+
+		  Sparse<LT> stmp (lhs_nr, lhs_nc, new_nzmx);
+
+		  octave_idx_type i = 0;
+		  octave_idx_type ii = 0;
+		  octave_idx_type ic = 0;
+		  if (i < lhs_nz)
+		    {
+		      while (ic < lhs_nc && i >= c_lhs.cidx(ic+1))
+			ic++;
+		      ii = ic * lhs_nr + c_lhs.ridx(i);
+		    }
+
+		  octave_idx_type j = 0;
+		  octave_idx_type jj = idx_i.elem (j);
+		  octave_idx_type jr = jj % lhs_nr;
+		  octave_idx_type jc = (jj - jr) / lhs_nr;
+
+		  octave_idx_type kk = 0;
+		  octave_idx_type kc = 0;
+
+		  while (j < len || i < lhs_nz)
+		    {
+		      if (j == len || (i < lhs_nz && ii < jj))
+			{
+			  while (kc <= ic)
+			    stmp.xcidx (kc++) = kk;
+			  stmp.xdata (kk) = c_lhs.data (i);
+			  stmp.xridx (kk++) = c_lhs.ridx (i);
+			  i++;
+			  while (ic < lhs_nc && i >= c_lhs.cidx(ic+1))
+			    ic++;
+			  if (i < lhs_nz)
+			    ii = ic * lhs_nr + c_lhs.ridx(i);
+			}
+		      else
+			{
+			  while (kc <= jc)
+			    stmp.xcidx (kc++) = kk;
+			  if (scalar != RT ())
+			    {
+			      stmp.xdata (kk) = scalar;
+			      stmp.xridx (kk++) = jr;
+			    }
+			  if (ii == jj)
+			    {
+			      i++;
+			      while (ic < lhs_nc && i >= c_lhs.cidx(ic+1))
+				ic++;
+			      if (i < lhs_nz)
+				ii = ic * lhs_nr + c_lhs.ridx(i);
+			    }
+			  j++;
+			  if (j < len)
+			    {
+			      jj = idx_i.elem (j);
+			      jr = jj % lhs_nr;
+			      jc = (jj - jr) / lhs_nr;
+			    }
+			}
+		    }
+
+		  for (octave_idx_type iidx = kc; iidx < lhs_nc+1; iidx++)
+		    stmp.xcidx(iidx) = kk;
+		  
+		  lhs = stmp;
+		}
+	      else
+		{
+		  (*current_liboctave_error_handler)
+      ("A(I) = X: X must be a scalar or a matrix with the same size as I");
+
+		  retval = 0;
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+    }
+  else
+    {
+      (*current_liboctave_error_handler)
+	("invalid number of indices for matrix expression");
+
+      retval = 0;
+    }
+
+  lhs.clear_index ();
+
+  return retval;
+}
+
+/*
+ * Tests
+ *
+
+%!function x = set_slice(x, dim, slice, arg)
+%!  switch dim
+%!    case 11
+%!      x(slice) = 2;
+%!    case 21
+%!      x(slice, :) = 2;
+%!    case 22
+%!      x(:, slice) = 2;
+%!    otherwise
+%!      error("invalid dim, '%d'", dim);
+%!  endswitch
+%! endfunction
+
+%!function x = set_slice2(x, dim, slice)
+%!  switch dim
+%!    case 11
+%!      x(slice) = 2 * ones (size(slice));
+%!    case 21
+%!      x(slice, :) = 2 * ones (length(slice), columns (x));
+%!    case 22
+%!      x(:, slice) = 2 * ones (rows (x), length(slice));
+%!    otherwise
+%!      error("invalid dim, '%d'", dim);
+%!  endswitch
+%! endfunction
+
+%!function test_sparse_slice(size, dim, slice)
+%!  x = ones(size);
+%!  s = set_slice(sparse(x), dim, slice);
+%!  f = set_slice(x, dim, slice);
+%!  assert (nnz(s), nnz(f));
+%!  assert(full(s), f);
+%!  s = set_slice2(sparse(x), dim, slice);
+%!  f = set_slice2(x, dim, slice);
+%!  assert (nnz(s), nnz(f));
+%!  assert(full(s), f);
+%! endfunction
+
+#### 1d indexing
+
+## size = [2 0]
+%!test test_sparse_slice([2 0], 11, []);
+%!assert(set_slice(sparse(ones([2 0])), 11, 1), sparse([2 0]'));  # sparse different from full
+%!assert(set_slice(sparse(ones([2 0])), 11, 2), sparse([0 2]'));  # sparse different from full
+%!assert(set_slice(sparse(ones([2 0])), 11, 3), sparse([0 0 2]'));  # sparse different from full
+%!assert(set_slice(sparse(ones([2 0])), 11, 4), sparse([0 0 0 2]'));  # sparse different from full
+
+## size = [0 2]
+%!test test_sparse_slice([0 2], 11, []);
+%!assert(set_slice(sparse(ones([0 2])), 11, 1), sparse(1,2));  # sparse different from full
+%!test test_sparse_slice([0 2], 11, 2);
+%!test test_sparse_slice([0 2], 11, 3);
+%!test test_sparse_slice([0 2], 11, 4);
+%!test test_sparse_slice([0 2], 11, [4, 4]);
+
+## size = [2 1]
+%!test test_sparse_slice([2 1], 11, []);
+%!test test_sparse_slice([2 1], 11, 1);
+%!test test_sparse_slice([2 1], 11, 2);
+%!test test_sparse_slice([2 1], 11, 3);
+%!test test_sparse_slice([2 1], 11, 4);
+%!test test_sparse_slice([2 1], 11, [4, 4]);
+
+## size = [1 2]
+%!test test_sparse_slice([1 2], 11, []);
+%!test test_sparse_slice([1 2], 11, 1);
+%!test test_sparse_slice([1 2], 11, 2);
+%!test test_sparse_slice([1 2], 11, 3);
+%!test test_sparse_slice([1 2], 11, 4);
+%!test test_sparse_slice([1 2], 11, [4, 4]);
+
+## size = [2 2]
+%!test test_sparse_slice([2 2], 11, []);
+%!test test_sparse_slice([2 2], 11, 1);
+%!test test_sparse_slice([2 2], 11, 2);
+%!test test_sparse_slice([2 2], 11, 3);
+%!test test_sparse_slice([2 2], 11, 4);
+%!test test_sparse_slice([2 2], 11, [4, 4]);
+# These 2 errors are the same as in the full case
+%!error <invalid matrix index = 5> set_slice(sparse(ones([2 2])), 11, 5);
+%!error <invalid matrix index = 6> set_slice(sparse(ones([2 2])), 11, 6);
+
+
+#### 2d indexing
+
+## size = [2 0]
+%!test test_sparse_slice([2 0], 21, []);
+%!test test_sparse_slice([2 0], 21, 1);
+%!test test_sparse_slice([2 0], 21, 2);
+%!test test_sparse_slice([2 0], 21, [2,2]);
+%!assert(set_slice(sparse(ones([2 0])), 21, 3), sparse(2,0));  # sparse different from full
+%!assert(set_slice(sparse(ones([2 0])), 21, 4), sparse(2,0));  # sparse different from full
+%!test test_sparse_slice([2 0], 22, []);
+%!test test_sparse_slice([2 0], 22, 1);
+%!test test_sparse_slice([2 0], 22, 2);
+%!test test_sparse_slice([2 0], 22, [2,2]);
+%!assert(set_slice(sparse(ones([2 0])), 22, 3), sparse([0 0 2;0 0 2]));  # sparse different from full
+%!assert(set_slice(sparse(ones([2 0])), 22, 4), sparse([0 0 0 2;0 0 0 2]));  # sparse different from full
+
+## size = [0 2]
+%!test test_sparse_slice([0 2], 21, []);
+%!test test_sparse_slice([0 2], 21, 1);
+%!test test_sparse_slice([0 2], 21, 2);
+%!test test_sparse_slice([0 2], 21, [2,2]);
+%!assert(set_slice(sparse(ones([0 2])), 21, 3), sparse([0 0;0 0;2 2]));  # sparse different from full
+%!assert(set_slice(sparse(ones([0 2])), 21, 4), sparse([0 0;0 0;0 0;2 2]));  # sparse different from full
+%!test test_sparse_slice([0 2], 22, []);
+%!test test_sparse_slice([0 2], 22, 1);
+%!test test_sparse_slice([0 2], 22, 2);
+%!test test_sparse_slice([0 2], 22, [2,2]);
+%!assert(set_slice(sparse(ones([0 2])), 22, 3), sparse(0,2));  # sparse different from full
+%!assert(set_slice(sparse(ones([0 2])), 22, 4), sparse(0,2));  # sparse different from full
+
+## size = [2 1]
+%!test test_sparse_slice([2 1], 21, []);
+%!test test_sparse_slice([2 1], 21, 1);
+%!test test_sparse_slice([2 1], 21, 2);
+%!test test_sparse_slice([2 1], 21, [2,2]);
+%!test test_sparse_slice([2 1], 21, 3);
+%!test test_sparse_slice([2 1], 21, 4);
+%!test test_sparse_slice([2 1], 22, []);
+%!test test_sparse_slice([2 1], 22, 1);
+%!test test_sparse_slice([2 1], 22, 2);
+%!test test_sparse_slice([2 1], 22, [2,2]);
+%!test test_sparse_slice([2 1], 22, 3);
+%!test test_sparse_slice([2 1], 22, 4);
+
+## size = [1 2]
+%!test test_sparse_slice([1 2], 21, []);
+%!test test_sparse_slice([1 2], 21, 1);
+%!test test_sparse_slice([1 2], 21, 2);
+%!test test_sparse_slice([1 2], 21, [2,2]);
+%!test test_sparse_slice([1 2], 21, 3);
+%!test test_sparse_slice([1 2], 21, 4);
+%!test test_sparse_slice([1 2], 22, []);
+%!test test_sparse_slice([1 2], 22, 1);
+%!test test_sparse_slice([1 2], 22, 2);
+%!test test_sparse_slice([1 2], 22, [2,2]);
+%!test test_sparse_slice([1 2], 22, 3);
+%!test test_sparse_slice([1 2], 22, 4);
+
+## size = [2 2]
+%!test test_sparse_slice([2 2], 21, []);
+%!test test_sparse_slice([2 2], 21, 1);
+%!test test_sparse_slice([2 2], 21, 2);
+%!test test_sparse_slice([2 2], 21, [2,2]);
+%!test test_sparse_slice([2 2], 21, 3);
+%!test test_sparse_slice([2 2], 21, 4);
+%!test test_sparse_slice([2 2], 22, []);
+%!test test_sparse_slice([2 2], 22, 1);
+%!test test_sparse_slice([2 2], 22, 2);
+%!test test_sparse_slice([2 2], 22, [2,2]);
+%!test test_sparse_slice([2 2], 22, 3);
+%!test test_sparse_slice([2 2], 22, 4);
+
+*/
+
+template <class T>
+void
+Sparse<T>::print_info (std::ostream& os, const std::string& prefix) const
+{
+  os << prefix << "rep address: " << rep << "\n"
+     << prefix << "rep->nzmx:   " << rep->nzmx  << "\n"
+     << prefix << "rep->nrows:  " << rep->nrows << "\n"
+     << prefix << "rep->ncols:  " << rep->ncols << "\n"
+     << prefix << "rep->data:   " << static_cast<void *> (rep->d) << "\n"
+     << prefix << "rep->ridx:   " << static_cast<void *> (rep->r) << "\n"
+     << prefix << "rep->cidx:   " << static_cast<void *> (rep->c) << "\n"
+     << prefix << "rep->count:  " << rep->count << "\n";
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/Sparse.h b/liboctave/Sparse.h
new file mode 100644
index 0000000..951fd76
--- /dev/null
+++ b/liboctave/Sparse.h
@@ -0,0 +1,599 @@
+// Template sparse classes
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Sparse_h)
+#define octave_Sparse_h 1
+
+#include <cassert>
+#include <cstddef>
+
+#include <iosfwd>
+
+#include "Array.h"
+#include "Array2.h"
+#include "dim-vector.h"
+#include "lo-utils.h"
+
+#include "oct-sort.h"
+
+class idx_vector;
+
+// Two dimensional sparse class.  Handles the reference counting for
+// all the derived classes.
+
+template <class T>
+class
+Sparse
+{
+public:
+
+  typedef T element_type;
+
+protected:
+  //--------------------------------------------------------------------
+  // The real representation of all Sparse arrays.
+  //--------------------------------------------------------------------
+
+  class OCTAVE_API SparseRep
+  {
+  public:
+
+    T *d;
+    octave_idx_type *r;
+    octave_idx_type *c;
+    octave_idx_type nzmx;
+    octave_idx_type nrows;
+    octave_idx_type ncols;
+    int count;
+
+    SparseRep (void) : d (0), r (0), c (new octave_idx_type [1]), nzmx (0), nrows (0),
+		       ncols (0), count (1) { c[0] = 0; }
+
+    SparseRep (octave_idx_type n) : d (0), r (0), c (new octave_idx_type [n+1]), nzmx (0), nrows (n),
+      ncols (n), count (1)
+      { 
+	for (octave_idx_type i = 0; i < n + 1; i++)
+	  c[i] = 0;
+      }
+
+    SparseRep (octave_idx_type nr, octave_idx_type nc) : d (0), r (0), c (new octave_idx_type [nc+1]), nzmx (0), 
+      nrows (nr), ncols (nc), count (1)
+      { 
+	for (octave_idx_type i = 0; i < nc + 1; i++)
+	  c[i] = 0;
+      }
+
+    SparseRep (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz) : d (new T [nz]), 
+      r (new octave_idx_type [nz]), c (new octave_idx_type [nc+1]), nzmx (nz), nrows (nr), 
+      ncols (nc), count (1)
+      { 
+	for (octave_idx_type i = 0; i < nc + 1; i++)
+	  c[i] = 0;
+      }
+
+    SparseRep (const SparseRep& a)
+      : d (new T [a.nzmx]), r (new octave_idx_type [a.nzmx]), c (new octave_idx_type [a.ncols + 1]), 
+      nzmx (a.nzmx), nrows (a.nrows), ncols (a.ncols), count (1)
+      {
+	for (octave_idx_type i = 0; i < nzmx; i++)
+	  {
+	    d[i] = a.d[i];
+	    r[i] = a.r[i];
+	  }
+	for (octave_idx_type i = 0; i < ncols + 1; i++)
+	  c[i] = a.c[i];
+      }
+ 
+    ~SparseRep (void) { delete [] d; delete [] r; delete [] c; }
+
+    octave_idx_type length (void) const { return nzmx; }
+
+    octave_idx_type nnz (void) const { return c [ncols]; }
+
+    T& elem (octave_idx_type _r, octave_idx_type _c);
+
+    T celem (octave_idx_type _r, octave_idx_type _c) const;
+
+    T& data (octave_idx_type i) { return d[i]; }
+
+    T cdata (octave_idx_type i) const { return d[i]; }
+
+    octave_idx_type& ridx (octave_idx_type i) { return r[i]; }
+
+    octave_idx_type cridx (octave_idx_type i) const { return r[i]; }
+
+    octave_idx_type& cidx (octave_idx_type i) { return c[i]; }
+
+    octave_idx_type ccidx (octave_idx_type i) const { return c[i]; }
+
+    void maybe_compress (bool remove_zeros);
+
+    void change_length (octave_idx_type nz);
+
+  private:
+
+    // No assignment!
+
+    SparseRep& operator = (const SparseRep& a);
+  };
+
+  //--------------------------------------------------------------------
+
+  void make_unique (void)
+    {
+      if (rep->count > 1)
+	{
+	  --rep->count;
+	  rep = new SparseRep (*rep);
+	}
+    }
+
+public:
+
+  // !!! WARNING !!! -- these should be protected, not public.  You
+  // should not access these data members directly!
+
+  typename Sparse<T>::SparseRep *rep;
+
+  dim_vector dimensions;
+
+protected:
+  idx_vector *idx;
+  octave_idx_type idx_count;
+
+private:
+
+  typename Sparse<T>::SparseRep *nil_rep (void) const
+    {
+      static typename Sparse<T>::SparseRep *nr
+	= new typename Sparse<T>::SparseRep ();
+
+      nr->count++;
+
+      return nr;
+    }
+
+public:
+
+  Sparse (void)
+    : rep (nil_rep ()), dimensions (dim_vector(0,0)),
+      idx (0), idx_count (0) { }
+
+  explicit Sparse (octave_idx_type n)
+    : rep (new typename Sparse<T>::SparseRep (n)), 
+      dimensions (dim_vector (n, n)), idx (0), idx_count (0) { }
+
+  explicit Sparse (octave_idx_type nr, octave_idx_type nc)
+    : rep (new typename Sparse<T>::SparseRep (nr, nc)), 
+      dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) { }
+
+  explicit Sparse (octave_idx_type nr, octave_idx_type nc, T val);
+
+  Sparse (const dim_vector& dv, octave_idx_type nz)
+    : rep (new typename Sparse<T>::SparseRep (dv(0), dv(1), nz)),
+    dimensions (dv), idx (0), idx_count (0) { }
+
+  Sparse (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz)
+    : rep (new typename Sparse<T>::SparseRep (nr, nc, nz)),
+      dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) { }
+
+  // Type conversion case.
+  template <class U> Sparse (const Sparse<U>& a);
+
+  // No type conversion case.
+  Sparse (const Sparse<T>& a)
+    : rep (a.rep), dimensions (a.dimensions), idx (0), idx_count (0)
+    {
+      rep->count++;
+    }
+
+public:
+
+  Sparse (const dim_vector& dv);
+
+  Sparse (const Sparse<T>& a, const dim_vector& dv);
+
+  Sparse (const Array<T>& a, const Array<octave_idx_type>& r, const Array<octave_idx_type>& c,
+	  octave_idx_type nr, octave_idx_type nc, bool sum_terms);
+
+  Sparse (const Array<T>& a, const Array<double>& r, const Array<double>& c,
+	  octave_idx_type nr, octave_idx_type nc, bool sum_terms);
+
+  // Sparsify a normal matrix
+  Sparse (const Array2<T>& a);
+  Sparse (const Array<T>& a);
+
+  virtual ~Sparse (void);
+
+  Sparse<T>& operator = (const Sparse<T>& a);
+
+  // Note that nzmax and capacity are the amount of storage for
+  // non-zero elements, while nnz is the actual number of non-zero
+  // terms.
+  octave_idx_type nzmax (void) const { return rep->length (); }
+  octave_idx_type capacity (void) const { return nzmax (); }
+  octave_idx_type nnz (void) const { return rep->nnz (); }
+
+  // Paranoid number of elements test for case of dims = (-1,-1)
+  octave_idx_type numel (void) const 
+    { 
+      if (dim1() < 0 || dim2() < 0)
+        return 0;
+      else
+        return dimensions.numel (); 
+    }
+
+  octave_idx_type nelem (void) const { return capacity (); }
+  octave_idx_type length (void) const { return numel (); }
+
+  octave_idx_type dim1 (void) const { return dimensions(0); }
+  octave_idx_type dim2 (void) const { return dimensions(1); }
+
+  octave_idx_type rows (void) const { return dim1 (); }
+  octave_idx_type cols (void) const { return dim2 (); }
+  octave_idx_type columns (void) const { return dim2 (); }
+
+  octave_idx_type get_row_index (octave_idx_type k) { return ridx (k); }
+  octave_idx_type get_col_index (octave_idx_type k)
+    {
+      octave_idx_type ret = 0;
+      while (cidx(ret+1) < k)
+        ret++;
+      return ret;
+    }
+  size_t byte_size (void) const { return (cols () + 1) * sizeof (octave_idx_type) +
+      capacity () * (sizeof (T) + sizeof (octave_idx_type)); }
+
+  dim_vector dims (void) const { return dimensions; }
+
+  Sparse<T> squeeze (void) const { return *this; }
+  
+  octave_idx_type compute_index (const Array<octave_idx_type>& ra_idx) const;
+
+  T range_error (const char *fcn, octave_idx_type n) const;
+  T& range_error (const char *fcn, octave_idx_type n);
+
+  T range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const;
+  T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j);
+
+  T range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const;
+  T& range_error (const char *fcn, const Array<octave_idx_type>& ra_idx);
+
+  // No checking, even for multiple references, ever.
+
+  T& xelem (octave_idx_type n) 
+    { 
+      octave_idx_type i = n % rows (), j = n / rows(); 
+      return xelem (i, j); 
+    }
+
+  T xelem (octave_idx_type n) const 
+    { 
+      octave_idx_type i = n % rows (), j = n / rows(); 
+      return xelem (i, j); 
+    }
+  
+  T& xelem (octave_idx_type i, octave_idx_type j) { return rep->elem (i, j); }
+  T xelem (octave_idx_type i, octave_idx_type j) const { return rep->celem (i, j); }
+
+  T& xelem (const Array<octave_idx_type>& ra_idx)
+    { return xelem (compute_index (ra_idx)); }
+
+  T xelem (const Array<octave_idx_type>& ra_idx) const
+    { return xelem (compute_index (ra_idx)); }
+
+  // FIXME -- would be nice to fix this so that we don't
+  // unnecessarily force a copy, but that is not so easy, and I see no
+  // clean way to do it.
+
+  T& checkelem (octave_idx_type n)
+    {
+      if (n < 0 || n >= numel ())
+	return range_error ("T& Sparse<T>::checkelem", n);
+      else
+	{
+	  make_unique ();
+	  return xelem (n);
+	}
+    }
+
+  T& checkelem (octave_idx_type i, octave_idx_type j)
+    {
+      if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
+	return range_error ("T& Sparse<T>::checkelem", i, j);
+      else
+	{
+	  make_unique ();
+	  return xelem (i, j);
+	}
+    }
+
+  T& checkelem (const Array<octave_idx_type>& ra_idx)
+    {
+      octave_idx_type i = compute_index (ra_idx);
+
+      if (i < 0)
+	return range_error ("T& Sparse<T>::checkelem", ra_idx);
+      else
+	return elem (i);
+    }
+
+  T& elem (octave_idx_type n)
+    {
+      make_unique ();
+      return xelem (n);
+    }
+
+  T& elem (octave_idx_type i, octave_idx_type j) 
+    { 
+      make_unique ();
+      return xelem (i, j); 
+    }
+
+  T& elem (const Array<octave_idx_type>& ra_idx)
+    { return Sparse<T>::elem (compute_index (ra_idx)); }
+
+#if defined (BOUNDS_CHECKING)
+  T& operator () (octave_idx_type n) { return checkelem (n); }
+  T& operator () (octave_idx_type i, octave_idx_type j) { return checkelem (i, j); }
+  T& operator () (const Array<octave_idx_type>& ra_idx) { return checkelem (ra_idx); }
+#else
+  T& operator () (octave_idx_type n) { return elem (n); }
+  T& operator () (octave_idx_type i, octave_idx_type j) { return elem (i, j); }
+  T& operator () (const Array<octave_idx_type>& ra_idx) { return elem (ra_idx); }
+#endif
+
+  T checkelem (octave_idx_type n) const
+    {
+      if (n < 0 || n >= numel ())
+	return range_error ("T Sparse<T>::checkelem", n);
+      else
+	return xelem (n);
+    }
+
+  T checkelem (octave_idx_type i, octave_idx_type j) const
+    {
+      if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
+	return range_error ("T Sparse<T>::checkelem", i, j);
+      else
+	return xelem (i, j);
+    }
+
+  T checkelem (const Array<octave_idx_type>& ra_idx) const
+    {
+      octave_idx_type i = compute_index (ra_idx);
+
+      if (i < 0)
+	return range_error ("T Sparse<T>::checkelem", ra_idx);
+      else
+	return Sparse<T>::elem (i);
+    }
+
+  T elem (octave_idx_type n) const { return xelem (n); }
+
+  T elem (octave_idx_type i, octave_idx_type j) const { return xelem (i, j); }
+
+  T elem (const Array<octave_idx_type>& ra_idx) const
+    { return Sparse<T>::elem (compute_index (ra_idx)); }
+
+#if defined (BOUNDS_CHECKING)
+  T operator () (octave_idx_type n) const { return checkelem (n); }
+  T operator () (octave_idx_type i, octave_idx_type j) const { return checkelem (i, j); }
+  T operator () (const Array<octave_idx_type>& ra_idx) const { return checkelem (ra_idx); }
+#else
+  T operator () (octave_idx_type n) const { return elem (n); }
+  T operator () (octave_idx_type i, octave_idx_type j) const { return elem (i, j); }
+  T operator () (const Array<octave_idx_type>& ra_idx) const { return elem (ra_idx); }
+#endif
+
+  Sparse<T> maybe_compress (bool remove_zeros = false) 
+  { rep->maybe_compress (remove_zeros); return (*this); }
+
+  Sparse<T> reshape (const dim_vector& new_dims) const;
+
+  // !!! WARNING !!! -- the following resize_no_fill functions are 
+  // public because template friends don't work properly with versions
+  // of gcc earlier than 3.3.  You should use these functions only in 
+  // classes that are derived from Sparse<T>.
+
+  // protected:
+
+  void resize_no_fill (octave_idx_type r, octave_idx_type c);
+
+  void resize_no_fill (const dim_vector& dv);
+
+public:
+  Sparse<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const;
+
+  Sparse<T> ipermute (const Array<octave_idx_type>& vec) const
+    { return permute (vec, true); }
+
+  void resize (octave_idx_type r, octave_idx_type c) { resize_no_fill (r, c); }
+
+  void resize (const dim_vector& dv) { resize_no_fill (dv); }
+
+  void change_capacity (octave_idx_type nz) { rep->change_length (nz); }
+
+  Sparse<T>& insert (const Sparse<T>& a, octave_idx_type r, octave_idx_type c);
+  Sparse<T>& insert (const Sparse<T>& a, const Array<octave_idx_type>& idx);
+
+  bool is_square (void) const { return (dim1 () == dim2 ()); }
+
+  bool is_empty (void) const { return (rows () < 1 && cols () < 1); }
+
+  Sparse<T> transpose (void) const;
+
+  T* data (void) { make_unique (); return rep->d; }
+  T& data (octave_idx_type i) { make_unique (); return rep->data (i); }
+  T* xdata (void) { return rep->d; }
+  T& xdata (octave_idx_type i) { return rep->data (i); }
+
+  T data (octave_idx_type i) const { return rep->data (i); }
+  // FIXME -- shouldn't this be returning const T*?
+  T* data (void) const { return rep->d; }
+
+  octave_idx_type* ridx (void) { make_unique (); return rep->r; }
+  octave_idx_type& ridx (octave_idx_type i) { make_unique (); return rep->ridx (i); }
+  octave_idx_type* xridx (void) { return rep->r; }
+  octave_idx_type& xridx (octave_idx_type i) { return rep->ridx (i); }
+
+  octave_idx_type ridx (octave_idx_type i) const { return rep->cridx (i); }
+  // FIXME -- shouldn't this be returning const octave_idx_type*?
+  octave_idx_type* ridx (void) const { return rep->r; }
+
+  octave_idx_type* cidx (void) { make_unique (); return rep->c; }
+  octave_idx_type& cidx (octave_idx_type i) { make_unique (); return rep->cidx (i); }
+  octave_idx_type* xcidx (void) { return rep->c; }
+  octave_idx_type& xcidx (octave_idx_type i) { return rep->cidx (i); }
+
+  octave_idx_type cidx (octave_idx_type i) const { return rep->ccidx (i); }
+  // FIXME -- shouldn't this be returning const octave_idx_type*?
+  octave_idx_type* cidx (void) const { return rep->c; }
+
+  octave_idx_type ndims (void) const { return dimensions.length (); }
+
+  void clear_index (void);
+
+  void set_index (const idx_vector& i);
+
+  octave_idx_type index_count (void) const { return idx_count; }
+
+  idx_vector *get_idx (void) const { return idx; }
+
+  void maybe_delete_elements (idx_vector& i);
+
+  void maybe_delete_elements (idx_vector& i, idx_vector& j);
+
+  void maybe_delete_elements (Array<idx_vector>& ra_idx);
+
+  Sparse<T> value (void);
+
+  Sparse<T> index (idx_vector& i, int resize_ok = 0) const;
+
+  Sparse<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0) const;
+
+  Sparse<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0) const;
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
+
+  // Unsafe.  These functions exist to support the MEX interface.
+  // You should not use them anywhere else.
+  void *mex_get_data (void) const { return const_cast<T *> (data ()); }
+
+  octave_idx_type *mex_get_ir (void) const { return const_cast<octave_idx_type *> (ridx ()); }
+
+  octave_idx_type *mex_get_jc (void) const { return const_cast<octave_idx_type *> (cidx ()); }
+
+  Sparse<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const;
+  Sparse<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		 sortmode mode = ASCENDING) const;
+
+  Sparse<T> diag (octave_idx_type k = 0) const;
+
+  template <class U, class F>
+  Sparse<U>
+  map (F fcn) const
+  {
+    Sparse<U> result;
+    U f_zero = fcn (0.);
+
+    if (f_zero != 0.)
+      {
+	octave_idx_type nr = rows ();
+	octave_idx_type nc = cols ();
+      
+	result = Sparse<U> (nr, nc, f_zero);
+
+	for (octave_idx_type j = 0; j < nc; j++)
+	  for (octave_idx_type i = cidx(j); i < cidx (j+1); i++)
+	    {
+	      OCTAVE_QUIT;
+	      /* Use data instead of elem for better performance.  */
+	      result.data (ridx (i) + j * nr) = fcn (data(i));
+	    }
+
+	result.maybe_compress (true);
+      }
+    else
+      {
+	octave_idx_type nz = nnz ();
+	octave_idx_type nr = rows ();
+	octave_idx_type nc = cols ();
+
+	result = Sparse<U> (nr, nc, nz);
+	octave_idx_type ii = 0;
+	result.cidx (ii) = 0;
+
+	for (octave_idx_type j = 0; j < nc; j++)
+	  {
+	    for (octave_idx_type i = cidx(j); i < cidx (j+1); i++)
+	      {
+		U val = fcn (data (i));
+		if (val != 0.0)
+		  {
+		    result.data (ii) = val;
+		    result.ridx (ii++) = ridx (i);
+		  }
+		OCTAVE_QUIT;
+	      }
+	    result.cidx (j+1) = ii;
+	  }
+
+	result.maybe_compress (false);
+      }
+
+    return result;
+  }
+};
+
+// NOTE: these functions should be friends of the Sparse<T> class and
+// Sparse<T>::dimensions should be protected, not public, but we can't
+// do that because of bugs in gcc prior to 3.3.
+
+template <class LT, class RT>
+/* friend */ int
+assign (Sparse<LT>& lhs, const Sparse<RT>& rhs);
+
+template <class LT, class RT>
+/* friend */ int
+assign1 (Sparse<LT>& lhs, const Sparse<RT>& rhs);
+
+#define INSTANTIATE_SPARSE_ASSIGN(LT, RT, API) \
+  template API int assign (Sparse<LT>&, const Sparse<RT>&); \
+  template API int assign1 (Sparse<LT>&, const Sparse<RT>&);
+
+#define INSTANTIATE_SPARSE(T, API) \
+  template class API Sparse<T>;
+
+#define INSTANTIATE_SPARSE_AND_ASSIGN(T, API) \
+  INSTANTIATE_SPARSE (T, API); \
+  INSTANTIATE_SPARSE_ASSIGN (T, T, API)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseCmplxCHOL.cc b/liboctave/SparseCmplxCHOL.cc
new file mode 100644
index 0000000..cbf2e84
--- /dev/null
+++ b/liboctave/SparseCmplxCHOL.cc
@@ -0,0 +1,76 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SparseCmplxCHOL.h"
+
+// Instantiate the base CHOL class for the type we need
+#define OCTAVE_CHOLMOD_TYPE CHOLMOD_COMPLEX
+#include "sparse-base-chol.h"
+#include "sparse-base-chol.cc"
+template class sparse_base_chol <SparseComplexMatrix, Complex, SparseMatrix>;
+
+// Compute the inverse of a matrix using the Cholesky factorization.
+SparseComplexMatrix
+chol2inv (const SparseComplexMatrix& r)
+{
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.cols ();
+  SparseComplexMatrix retval;
+
+  if (r_nr == r_nc)
+    {
+      MatrixType mattype (r);
+      int typ = mattype.type (false);
+      double rcond;
+      octave_idx_type info;
+      SparseComplexMatrix rinv;
+
+      if (typ == MatrixType::Upper)
+	{
+	  rinv = r.inverse(mattype, info, rcond, true, false);
+	  retval = rinv.transpose() * rinv;
+	}
+      else if (typ == MatrixType::Lower)
+	{
+	  rinv = r.transpose().inverse(mattype, info, rcond, true, false);
+	  retval = rinv.transpose() * rinv;
+	}
+      else
+	(*current_liboctave_error_handler) 
+	  ("spchol2inv requires triangular matrix");
+    }
+  else
+    (*current_liboctave_error_handler) ("spchol2inv requires square matrix");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseCmplxCHOL.h b/liboctave/SparseCmplxCHOL.h
new file mode 100644
index 0000000..321cbe6
--- /dev/null
+++ b/liboctave/SparseCmplxCHOL.h
@@ -0,0 +1,104 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_complex_CHOL_h)
+#define octave_sparse_complex_CHOL_h 1
+
+#include "sparse-base-chol.h"
+#include "dSparse.h"
+#include "CSparse.h"
+
+class
+OCTAVE_API
+SparseComplexCHOL : 
+  public sparse_base_chol <SparseComplexMatrix, Complex, SparseMatrix>
+{
+public:
+
+  SparseComplexCHOL (void) : 
+    sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> () { }
+
+  SparseComplexCHOL (const SparseComplexMatrix& a, bool natural = true) : 
+    sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> 
+  (a, natural) { }
+
+  SparseComplexCHOL (const SparseComplexMatrix& a, octave_idx_type& info, 
+		     bool natural = true) :
+    sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> 
+  (a, info, natural) { }
+
+  SparseComplexCHOL (const SparseComplexCHOL& a) : 
+    sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> (a) { }
+
+  ~SparseComplexCHOL (void) { }
+
+  SparseComplexCHOL& operator = (const SparseComplexCHOL& a)
+    {
+      if (this != &a)
+	sparse_base_chol <SparseComplexMatrix, Complex, SparseMatrix> ::
+	  operator = (a);
+
+      return *this;
+    }
+
+  SparseComplexMatrix chol_matrix (void) const { return R(); }
+
+  SparseComplexMatrix L (void) const 
+    { return sparse_base_chol<SparseComplexMatrix, Complex, 
+	SparseMatrix>:: L (); }
+
+  SparseComplexMatrix R (void) const 
+    { return sparse_base_chol<SparseComplexMatrix, Complex,
+	SparseMatrix>:: R (); }
+
+  octave_idx_type P (void) const 
+   { return sparse_base_chol<SparseComplexMatrix, Complex, 
+        SparseMatrix>:: P (); }
+
+  ColumnVector perm (void) const 
+    { return sparse_base_chol<SparseComplexMatrix, Complex, 
+	SparseMatrix>:: perm (); }
+
+  SparseMatrix Q (void) const 
+    { return sparse_base_chol<SparseComplexMatrix, Complex, 
+	SparseMatrix>:: Q (); }
+
+  double rcond (void) const
+    { return sparse_base_chol<SparseComplexMatrix, Complex, 
+	SparseMatrix>:: rcond (); }
+
+  // Compute the inverse of a matrix using the Cholesky factorization.
+  SparseComplexMatrix inverse (void) const
+    { return sparse_base_chol<SparseComplexMatrix, Complex, 
+	SparseMatrix>:: inverse (); }
+};
+
+SparseComplexMatrix OCTAVE_API chol2inv (const SparseComplexMatrix& r);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseCmplxLU.cc b/liboctave/SparseCmplxLU.cc
new file mode 100644
index 0000000..7f697a9
--- /dev/null
+++ b/liboctave/SparseCmplxLU.cc
@@ -0,0 +1,486 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+#include "SparseCmplxLU.h"
+#include "oct-spparms.h"
+
+// Instantiate the base LU class for the types we need.
+
+#include "sparse-base-lu.h"
+#include "sparse-base-lu.cc"
+
+template class sparse_base_lu <SparseComplexMatrix, Complex, SparseMatrix, double>;
+
+#include "oct-sparse.h"
+
+SparseComplexLU::SparseComplexLU (const SparseComplexMatrix& a, 
+				  const Matrix& piv_thres, bool scale)
+{
+#ifdef HAVE_UMFPACK
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  // Setup the control parameters
+  Matrix Control (UMFPACK_CONTROL, 1);
+  double *control = Control.fortran_vec ();
+  UMFPACK_ZNAME (defaults) (control);
+
+  double tmp = octave_sparse_params::get_key ("spumoni");
+  if (!xisnan (tmp))
+    Control (UMFPACK_PRL) = tmp;
+  if (piv_thres.nelem() == 2)
+    {
+      tmp = (piv_thres (0) > 1. ? 1. : piv_thres (0));
+      if (!xisnan (tmp))
+	Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+      tmp = (piv_thres (1) > 1. ? 1. : piv_thres (1));
+      if (!xisnan (tmp))
+	Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+    }
+  else
+    {
+      tmp = octave_sparse_params::get_key ("piv_tol");
+      if (!xisnan (tmp))
+	Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+
+      tmp = octave_sparse_params::get_key ("sym_tol");
+      if (!xisnan (tmp))
+	  Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+    }
+
+  // Set whether we are allowed to modify Q or not
+  tmp = octave_sparse_params::get_key ("autoamd");
+  if (!xisnan (tmp))
+    Control (UMFPACK_FIXQ) = tmp;
+
+  // Turn-off UMFPACK scaling for LU 
+  if (scale)
+    Control (UMFPACK_SCALE) = UMFPACK_SCALE_SUM;
+  else
+    Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
+
+  UMFPACK_ZNAME (report_control) (control);
+
+  const octave_idx_type *Ap = a.cidx ();
+  const octave_idx_type *Ai = a.ridx ();
+  const Complex *Ax = a.data ();
+
+  UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai,
+				 reinterpret_cast<const double *> (Ax),
+				 0, 1, control);
+
+  void *Symbolic;
+  Matrix Info (1, UMFPACK_INFO);
+  double *info = Info.fortran_vec ();
+  int status = UMFPACK_ZNAME (qsymbolic) (nr, nc, Ap, Ai, 
+					  reinterpret_cast<const double *> (Ax),
+					  0, 0,
+					  &Symbolic, control, info);
+
+  if (status < 0)
+    {
+      (*current_liboctave_error_handler) 
+	    ("SparseComplexLU::SparseComplexLU symbolic factorization failed");
+
+      UMFPACK_ZNAME (report_status) (control, status);
+      UMFPACK_ZNAME (report_info) (control, info);
+
+      UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+    }
+  else
+    {
+      UMFPACK_ZNAME (report_symbolic) (Symbolic, control);
+
+      void *Numeric;
+      status = UMFPACK_ZNAME (numeric) (Ap, Ai,
+					reinterpret_cast<const double *> (Ax),
+					0, Symbolic, &Numeric, control,
+					info);
+      UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+
+      cond = Info (UMFPACK_RCOND);
+
+      if (status < 0)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("SparseComplexLU::SparseComplexLU numeric factorization failed");
+
+	  UMFPACK_ZNAME (report_status) (control, status);
+	  UMFPACK_ZNAME (report_info) (control, info);
+
+	  UMFPACK_ZNAME (free_numeric) (&Numeric);
+	}
+      else
+	{
+	  UMFPACK_ZNAME (report_numeric) (Numeric, control);
+
+	  octave_idx_type lnz, unz, ignore1, ignore2, ignore3;
+	  status = UMFPACK_ZNAME (get_lunz) (&lnz, &unz, &ignore1,
+					&ignore2, &ignore3, Numeric) ;
+	  
+	  if (status < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("SparseComplexLU::SparseComplexLU extracting LU factors failed");
+
+	      UMFPACK_ZNAME (report_status) (control, status);
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    {
+	      octave_idx_type n_inner = (nr < nc ? nr : nc);
+
+	      if (lnz < 1)
+		Lfact = SparseComplexMatrix (n_inner, nr,
+					     static_cast<octave_idx_type> (1));
+	      else
+		Lfact = SparseComplexMatrix (n_inner, nr, lnz);
+
+	      octave_idx_type *Ltp = Lfact.cidx ();
+	      octave_idx_type *Ltj = Lfact.ridx ();
+	      Complex *Ltx = Lfact.data ();
+
+	      if (unz < 1)
+		Ufact = SparseComplexMatrix (n_inner, nc,
+					     static_cast<octave_idx_type> (1));
+	      else
+		Ufact = SparseComplexMatrix (n_inner, nc, unz);
+
+	      octave_idx_type *Up = Ufact.cidx ();
+	      octave_idx_type *Uj = Ufact.ridx ();
+	      Complex *Ux = Ufact.data ();
+	      
+	      Rfact = SparseMatrix (nr, nr, nr);
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  Rfact.xridx (i) = i;
+		  Rfact.xcidx (i) = i;
+		}
+	      Rfact.xcidx (nr) = nr;
+	      double *Rx = Rfact.data ();
+
+	      P.resize (nr);
+	      octave_idx_type *p = P.fortran_vec ();
+
+	      Q.resize (nc);
+	      octave_idx_type *q = Q.fortran_vec ();
+
+	      octave_idx_type do_recip;
+	      status = UMFPACK_ZNAME (get_numeric) (Ltp, Ltj,
+						    reinterpret_cast<double *> (Ltx),
+						    0, Up, Uj,
+						    reinterpret_cast <double *> (Ux),
+						    0, p, q, 0, 0,
+						    &do_recip, Rx, Numeric);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric) ;
+
+	      if (status < 0)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("SparseComplexLU::SparseComplexLU extracting LU factors failed");
+
+		  UMFPACK_ZNAME (report_status) (control, status);
+		}
+	      else
+		{
+		  Lfact = Lfact.transpose ();
+
+		  if (do_recip)
+		    for (octave_idx_type i = 0; i < nr; i++)
+		      Rx[i] = 1.0 / Rx[i];
+
+		  UMFPACK_ZNAME (report_matrix) (nr, n_inner,
+					    Lfact.cidx (), Lfact.ridx (), 
+					    reinterpret_cast<double *> (Lfact.data()), 
+					    0, 1, control);
+
+		  UMFPACK_ZNAME (report_matrix) (n_inner, nc,
+					    Ufact.cidx (), Ufact.ridx (), 
+					    reinterpret_cast<double *> (Ufact.data()), 
+					    0, 1, control);
+		  UMFPACK_ZNAME (report_perm) (nr, p, control);
+		  UMFPACK_ZNAME (report_perm) (nc, q, control);
+		}
+
+	      UMFPACK_ZNAME (report_info) (control, info);
+	    }
+	}
+    }
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+}
+
+SparseComplexLU::SparseComplexLU (const SparseComplexMatrix& a, 
+				  const ColumnVector& Qinit, 
+				  const Matrix& piv_thres, bool scale,
+				  bool FixedQ, double droptol, 
+				  bool milu, bool udiag)
+{
+#ifdef HAVE_UMFPACK
+  if (milu)
+    (*current_liboctave_error_handler) 
+      ("Modified incomplete LU not implemented");   
+  else
+    {
+      octave_idx_type nr = a.rows ();
+      octave_idx_type nc = a.cols ();
+
+      // Setup the control parameters
+      Matrix Control (UMFPACK_CONTROL, 1);
+      double *control = Control.fortran_vec ();
+      UMFPACK_ZNAME (defaults) (control);
+
+      double tmp = octave_sparse_params::get_key ("spumoni");
+      if (!xisnan (tmp))
+	Control (UMFPACK_PRL) = tmp;
+      if (piv_thres.nelem() == 2)
+	{
+	  tmp = (piv_thres (0) > 1. ? 1. : piv_thres (0));
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+	  tmp = (piv_thres (1) > 1. ? 1. : piv_thres (1));
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+	}
+      else
+	{
+	  tmp = octave_sparse_params::get_key ("piv_tol");
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+
+	  tmp = octave_sparse_params::get_key ("sym_tol");
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+	}
+
+      if (droptol >= 0.)
+	Control (UMFPACK_DROPTOL) = droptol;
+
+      // Set whether we are allowed to modify Q or not
+      if (FixedQ)
+	Control (UMFPACK_FIXQ) = 1.0;
+      else
+	{
+	  tmp = octave_sparse_params::get_key ("autoamd");
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_FIXQ) = tmp;
+	}
+
+      // Turn-off UMFPACK scaling for LU 
+      if (scale)
+	Control (UMFPACK_SCALE) = UMFPACK_SCALE_SUM;
+      else
+	Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
+
+      UMFPACK_ZNAME (report_control) (control);
+
+      const octave_idx_type *Ap = a.cidx ();
+      const octave_idx_type *Ai = a.ridx ();
+      const Complex *Ax = a.data ();
+
+      UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai, 
+				reinterpret_cast<const double *> (Ax), 0,
+				1, control);
+
+      void *Symbolic;
+      Matrix Info (1, UMFPACK_INFO);
+      double *info = Info.fortran_vec ();
+      int status;
+
+      // Null loop so that qinit is imediately deallocated when not
+      // needed
+      do {
+	OCTAVE_LOCAL_BUFFER (octave_idx_type, qinit, nc);
+
+	for (octave_idx_type i = 0; i < nc; i++)
+	  qinit [i] = static_cast<octave_idx_type> (Qinit (i));
+
+	status = UMFPACK_ZNAME (qsymbolic) (nr, nc, Ap, Ai, 
+				       reinterpret_cast<const double *> (Ax),
+				       0, qinit, &Symbolic, control, 
+				       info);
+      } while (0);
+
+      if (status < 0)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("SparseComplexLU::SparseComplexLU symbolic factorization failed");
+
+	  UMFPACK_ZNAME (report_status) (control, status);
+	  UMFPACK_ZNAME (report_info) (control, info);
+
+	  UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+	}
+      else
+	{
+	  UMFPACK_ZNAME (report_symbolic) (Symbolic, control);
+
+	  void *Numeric;
+	  status = UMFPACK_ZNAME (numeric) (Ap, Ai, 
+				       reinterpret_cast<const double *> (Ax), 0,
+				       Symbolic, &Numeric, control, info) ;
+	  UMFPACK_ZNAME (free_symbolic) (&Symbolic) ;
+
+	  cond = Info (UMFPACK_RCOND);
+
+	  if (status < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("SparseComplexLU::SparseComplexLU numeric factorization failed");
+
+	      UMFPACK_ZNAME (report_status) (control, status);
+	      UMFPACK_ZNAME (report_info) (control, info);
+
+	      UMFPACK_ZNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    {
+	      UMFPACK_ZNAME (report_numeric) (Numeric, control);
+
+	      octave_idx_type lnz, unz, ignore1, ignore2, ignore3;
+	      status = UMFPACK_ZNAME (get_lunz) (&lnz, &unz,
+					    &ignore1, &ignore2, &ignore3, Numeric);
+	  
+	      if (status < 0)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("SparseComplexLU::SparseComplexLU extracting LU factors failed");
+
+		  UMFPACK_ZNAME (report_status) (control, status);
+		  UMFPACK_ZNAME (report_info) (control, info);
+
+		  UMFPACK_ZNAME (free_numeric) (&Numeric);
+		}
+	      else
+		{
+		  octave_idx_type n_inner = (nr < nc ? nr : nc);
+
+		  if (lnz < 1)
+		    Lfact = SparseComplexMatrix (n_inner, nr,
+		       static_cast<octave_idx_type> (1));
+		  else
+		    Lfact = SparseComplexMatrix (n_inner, nr, lnz);
+
+		  octave_idx_type *Ltp = Lfact.cidx ();
+		  octave_idx_type *Ltj = Lfact.ridx ();
+		  Complex *Ltx = Lfact.data ();
+
+		  if (unz < 1)
+		    Ufact = SparseComplexMatrix (n_inner, nc,
+		       static_cast<octave_idx_type> (1));
+		  else
+		    Ufact = SparseComplexMatrix  (n_inner, nc, unz);
+
+		  octave_idx_type *Up = Ufact.cidx ();
+		  octave_idx_type *Uj = Ufact.ridx ();
+		  Complex *Ux = Ufact.data ();
+	      
+		  Rfact = SparseMatrix (nr, nr, nr);
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    {
+		      Rfact.xridx (i) = i;
+		      Rfact.xcidx (i) = i;
+		    }
+		  Rfact.xcidx (nr) = nr;
+		  double *Rx = Rfact.data ();
+
+		  P.resize (nr);
+		  octave_idx_type *p = P.fortran_vec ();
+
+		  Q.resize (nc);
+		  octave_idx_type *q = Q.fortran_vec ();
+
+		  octave_idx_type do_recip;
+		  status = 
+		    UMFPACK_ZNAME (get_numeric) (Ltp, Ltj, 
+					    reinterpret_cast<double *> (Ltx),
+					    0, Up, Uj,
+					    reinterpret_cast<double *> (Ux), 
+					    0, p, q, 0, 0, 
+					    &do_recip, Rx, Numeric) ;
+
+		  UMFPACK_ZNAME (free_numeric) (&Numeric) ;
+
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseComplexLU::SparseComplexLU extracting LU factors failed");
+
+		      UMFPACK_ZNAME (report_status) (control, status);
+		    }
+		  else
+		    {
+		      Lfact = Lfact.transpose ();
+
+		      if (do_recip)
+			for (octave_idx_type i = 0; i < nr; i++)
+			  Rx[i] = 1.0 / Rx[i];
+
+		      UMFPACK_ZNAME (report_matrix) (nr, n_inner, 
+						Lfact.cidx (), 
+						Lfact.ridx (), 
+						reinterpret_cast<double *> (Lfact.data()), 
+						0, 1, control);
+
+		      UMFPACK_ZNAME (report_matrix) (n_inner, nc, 
+						Ufact.cidx (), 
+						Ufact.ridx (), 
+						reinterpret_cast<double *> (Ufact.data()), 
+						0, 1, control);
+		      UMFPACK_ZNAME (report_perm) (nr, p, control);
+		      UMFPACK_ZNAME (report_perm) (nc, q, control);
+		    }
+
+		  UMFPACK_ZNAME (report_info) (control, info);
+		}
+	    }
+	}
+
+      if (udiag)
+	(*current_liboctave_error_handler) 
+	  ("Option udiag of incomplete LU not implemented");   
+    }
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/SparseCmplxLU.h b/liboctave/SparseCmplxLU.h
new file mode 100644
index 0000000..2575cf4
--- /dev/null
+++ b/liboctave/SparseCmplxLU.h
@@ -0,0 +1,72 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_complex_LU_h)
+#define octave_sparse_complex_LU_h 1
+
+#include "sparse-base-lu.h"
+#include "dSparse.h"
+#include "CSparse.h"
+
+class
+OCTAVE_API
+SparseComplexLU 
+  : public sparse_base_lu <SparseComplexMatrix, Complex, SparseMatrix, double>
+{
+public:
+
+  SparseComplexLU (void) 
+    : sparse_base_lu <SparseComplexMatrix, Complex, SparseMatrix, double> () { }
+
+  SparseComplexLU (const SparseComplexMatrix& a, 
+		   const Matrix& piv_thres = Matrix (),
+		   bool scale = false);
+
+  SparseComplexLU (const SparseComplexMatrix& a, const ColumnVector& Qinit,
+		   const Matrix& piv_thres = Matrix (), 
+		   bool scale = false, bool FixedQ = false,
+		   double droptol = -1., bool milu = false,
+		   bool udiag = false);
+
+  SparseComplexLU (const SparseComplexLU& a) 
+    : sparse_base_lu <SparseComplexMatrix, Complex, SparseMatrix, double> (a) { }
+
+  SparseComplexLU& operator = (const SparseComplexLU& a)
+    {
+      if (this != &a)
+	sparse_base_lu <SparseComplexMatrix, Complex, SparseMatrix, double> 
+	  :: operator = (a);
+
+      return *this;
+    }
+
+  ~SparseComplexLU (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseCmplxQR.cc b/liboctave/SparseCmplxQR.cc
new file mode 100644
index 0000000..5c4838b
--- /dev/null
+++ b/liboctave/SparseCmplxQR.cc
@@ -0,0 +1,902 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+
+#include "lo-error.h"
+#include "SparseCmplxQR.h"
+#include "oct-locbuf.h"
+
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER < 2)) || (CS_VER < 2))
+typedef double _Complex cs_complex_t;
+
+// Why did g++ 4.x stl_vector.h make
+//   OCTAVE_LOCAL_BUFFER (cs_complex_t, buf, n)
+// an error ?
+#define OCTAVE_C99_COMPLEX(buf, n) \
+  OCTAVE_LOCAL_BUFFER (double, buf ## tmp, (2 * (n))); \
+  cs_complex_t *buf = reinterpret_cast<cs_complex_t *> (buf ## tmp);
+
+#define OCTAVE_C99_ZERO (0. + 0.iF)
+#define OCTAVE_C99_ONE (1. + 0.iF)
+#else
+#define OCTAVE_C99_COMPLEX(buf, n) \
+  OCTAVE_LOCAL_BUFFER (cs_complex_t, buf, (n));
+#define OCTAVE_C99_ZERO cs_complex_t(0., 0.);
+#define OCTAVE_C99_ONE cs_complex_t(1., 0.);
+#endif
+
+SparseComplexQR::SparseComplexQR_rep::SparseComplexQR_rep 
+(GCC_ATTR_UNUSED const SparseComplexMatrix& a, GCC_ATTR_UNUSED int order)
+{
+#ifdef HAVE_CXSPARSE
+  CXSPARSE_ZNAME () A;
+  A.nzmax = a.nnz ();
+  A.m = a.rows ();
+  A.n = a.cols ();
+  nrows = A.m;
+  // Cast away const on A, with full knowledge that CSparse won't touch it
+  // Prevents the methods below making a copy of the data.
+  A.p = const_cast<octave_idx_type *>(a.cidx ());
+  A.i = const_cast<octave_idx_type *>(a.ridx ());
+  A.x = const_cast<cs_complex_t *>(reinterpret_cast<const cs_complex_t *> 
+				      (a.data ()));
+  A.nz = -1;
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+  S = CXSPARSE_ZNAME (_sqr) (order, &A, 1);
+#else
+  S = CXSPARSE_ZNAME (_sqr) (&A, order - 1, 1);
+#endif
+  N = CXSPARSE_ZNAME (_qr) (&A, S);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  if (!N)
+    (*current_liboctave_error_handler)
+      ("SparseComplexQR: sparse matrix QR factorization filled");
+  count = 1;
+#else
+  (*current_liboctave_error_handler)
+    ("SparseComplexQR: sparse matrix QR factorization not implemented");
+#endif
+}
+
+SparseComplexQR::SparseComplexQR_rep::~SparseComplexQR_rep (void)
+{
+#ifdef HAVE_CXSPARSE
+  CXSPARSE_ZNAME (_sfree) (S);
+  CXSPARSE_ZNAME (_nfree) (N);
+#endif
+}
+
+SparseComplexMatrix 
+SparseComplexQR::SparseComplexQR_rep::V (void) const
+{
+#ifdef HAVE_CXSPARSE
+  // Drop zeros from V and sort
+  // FIXME Is the double transpose to sort necessary?
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  CXSPARSE_ZNAME (_dropzeros) (N->L);
+  CXSPARSE_ZNAME () *D = CXSPARSE_ZNAME (_transpose) (N->L, 1);
+  CXSPARSE_ZNAME (_spfree) (N->L);
+  N->L = CXSPARSE_ZNAME (_transpose) (D, 1);
+  CXSPARSE_ZNAME (_spfree) (D);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  octave_idx_type nc = N->L->n;
+  octave_idx_type nz = N->L->nzmax;
+  SparseComplexMatrix ret (N->L->m, nc, nz);
+  for (octave_idx_type j = 0; j < nc+1; j++)
+    ret.xcidx (j) = N->L->p[j];
+  for (octave_idx_type j = 0; j < nz; j++)
+    {
+      ret.xridx (j) = N->L->i[j];
+      ret.xdata (j) = reinterpret_cast<Complex *>(N->L->x)[j];
+    }
+  return ret;
+#else
+  return SparseComplexMatrix ();
+#endif
+}
+
+ColumnVector 
+SparseComplexQR::SparseComplexQR_rep::Pinv (void) const
+{
+#ifdef HAVE_CXSPARSE
+  ColumnVector ret(N->L->m);
+  for (octave_idx_type i = 0; i < N->L->m; i++)
+#if defined(CS_VER) && (CS_VER >= 2)
+    ret.xelem(i) = S->pinv[i];
+#else
+    ret.xelem(i) = S->Pinv[i];
+#endif
+  return ret;
+#else
+  return ColumnVector ();
+#endif
+}
+
+ColumnVector 
+SparseComplexQR::SparseComplexQR_rep::P (void) const
+{
+#ifdef HAVE_CXSPARSE
+  ColumnVector ret(N->L->m);
+  for (octave_idx_type i = 0; i < N->L->m; i++)
+#if defined(CS_VER) && (CS_VER >= 2)
+    ret.xelem(S->pinv[i]) = i;
+#else
+    ret.xelem(S->Pinv[i]) = i;
+#endif
+  return ret;
+#else
+  return ColumnVector ();
+#endif
+}
+
+SparseComplexMatrix 
+SparseComplexQR::SparseComplexQR_rep::R (const bool econ) const
+{
+#ifdef HAVE_CXSPARSE
+  // Drop zeros from R and sort
+  // FIXME Is the double transpose to sort necessary?
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  CXSPARSE_ZNAME (_dropzeros) (N->U);
+  CXSPARSE_ZNAME () *D = CXSPARSE_ZNAME (_transpose) (N->U, 1);
+  CXSPARSE_ZNAME (_spfree) (N->U);
+  N->U = CXSPARSE_ZNAME (_transpose) (D, 1);
+  CXSPARSE_ZNAME (_spfree) (D);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  octave_idx_type nc = N->U->n;
+  octave_idx_type nz = N->U->nzmax;
+  SparseComplexMatrix ret ((econ ? (nc > nrows ? nrows : nc) : nrows), nc, nz);
+  for (octave_idx_type j = 0; j < nc+1; j++)
+    ret.xcidx (j) = N->U->p[j];
+  for (octave_idx_type j = 0; j < nz; j++)
+    {
+      ret.xridx (j) = N->U->i[j];
+      ret.xdata (j) = reinterpret_cast<Complex *>(N->U->x)[j];
+    }
+  return ret;
+#else
+  return SparseComplexMatrix ();
+#endif
+}
+
+ComplexMatrix
+SparseComplexQR::SparseComplexQR_rep::C (const ComplexMatrix &b) const
+{
+#ifdef HAVE_CXSPARSE
+  octave_idx_type b_nr = b.rows();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type nc = N->L->n;
+  octave_idx_type nr = nrows;
+  const cs_complex_t *bvec = 
+    reinterpret_cast<const cs_complex_t *>(b.fortran_vec());
+  ComplexMatrix ret(b_nr, b_nc);
+  Complex *vec = ret.fortran_vec();
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler) ("matrix dimension mismatch");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    ret = ComplexMatrix (nc, b_nc, Complex (0.0, 0.0));
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (Complex, buf, S->m2);
+      for (volatile octave_idx_type j = 0, idx = 0; j < b_nc; j++, idx+=b_nr)
+	{
+	  OCTAVE_QUIT;
+	  volatile octave_idx_type nm = (nr < nc ? nr : nc);
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (S->pinv, bvec + idx, reinterpret_cast<cs_complex_t *>(buf), b_nr);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (b_nr, S->Pinv, bvec + idx, reinterpret_cast<cs_complex_t *>(buf));
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type i = 0; i < nm; i++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_ZNAME (_happly) 
+		(N->L, i, N->B[i], reinterpret_cast<cs_complex_t *>(buf));
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  for (octave_idx_type i = 0; i < b_nr; i++)
+	    vec[i+idx] = buf[i];
+	}
+    }
+  return ret;
+#else
+  return ComplexMatrix ();
+#endif
+}
+
+ComplexMatrix
+SparseComplexQR::SparseComplexQR_rep::Q (void) const
+{
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nc = N->L->n;
+  octave_idx_type nr = nrows;
+  ComplexMatrix ret(nr, nr);
+  Complex *vec = ret.fortran_vec();
+  if (nr < 0 || nc < 0)
+    (*current_liboctave_error_handler) ("matrix dimension mismatch");
+  else if (nr == 0 || nc == 0)
+    ret = ComplexMatrix (nc, nr, Complex (0.0, 0.0));
+  else
+    {
+      OCTAVE_C99_COMPLEX (bvec, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	bvec[i] = OCTAVE_C99_ZERO;
+      OCTAVE_LOCAL_BUFFER (Complex, buf, S->m2);
+      for (volatile octave_idx_type j = 0, idx = 0; j < nr; j++, idx+=nr)
+	{
+	  OCTAVE_QUIT;
+	  bvec[j] = OCTAVE_C99_ONE;
+	  volatile octave_idx_type nm = (nr < nc ? nr : nc);
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (S->pinv, bvec, reinterpret_cast<cs_complex_t *>(buf), nr);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (nr, S->Pinv, bvec, reinterpret_cast<cs_complex_t *>(buf));
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type i = 0; i < nm; i++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_ZNAME (_happly) 
+		(N->L, i, N->B[i], reinterpret_cast<cs_complex_t *>(buf));
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    vec[i+idx] = buf[i];
+	  bvec[j] = OCTAVE_C99_ZERO;
+	}
+    }
+  return ret.hermitian ();
+#else
+  return ComplexMatrix ();
+#endif
+}
+
+ComplexMatrix
+qrsolve(const SparseComplexMatrix&a, const Matrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type b_nr = b.rows();
+  ComplexMatrix x;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = ComplexMatrix (nc, b_nc, Complex (0.0, 0.0));
+  else if (nr >= nc)
+    {
+      SparseComplexQR q (a, 2);
+      if (! q.ok ())
+	return ComplexMatrix();
+      x.resize(nc, b_nc);
+      cs_complex_t *vec = reinterpret_cast<cs_complex_t *>
+	(x.fortran_vec());
+      OCTAVE_C99_COMPLEX (buf, q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (Complex, Xx, b_nr);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (q.S()->pinv, reinterpret_cast<cs_complex_t *>(Xx), buf, nr);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (nr, q.S()->Pinv, reinterpret_cast<cs_complex_t *>(Xx), buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_ZNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) (q.S()->q, buf, vec + idx, nc);
+#else
+	  CXSPARSE_ZNAME (_ipvec) (nc, q.S()->Q, buf, vec + idx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseComplexMatrix at = a.hermitian();
+      SparseComplexQR q (at, 2);
+      if (! q.ok ())
+	return ComplexMatrix();
+      x.resize(nc, b_nc);
+      cs_complex_t *vec = reinterpret_cast<cs_complex_t *>
+	(x.fortran_vec());
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_C99_COMPLEX (buf, nbuf);
+      OCTAVE_LOCAL_BUFFER (Complex, Xx, b_nr);
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+      OCTAVE_LOCAL_BUFFER (double, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = q.N()->B [i];
+#else
+      OCTAVE_LOCAL_BUFFER (Complex, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = conj (reinterpret_cast<Complex *>(q.N()->B) [i]);
+#endif
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec)
+	    (q.S()->q, reinterpret_cast<cs_complex_t *>(Xx), buf, nr);
+#else
+	  CXSPARSE_ZNAME (_pvec)
+	    (nr, q.S()->Q, reinterpret_cast<cs_complex_t *>(Xx), buf);
+#endif
+	  CXSPARSE_ZNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, B[j], buf);
+#else
+	      CXSPARSE_ZNAME (_happly) 
+		(q.N()->L, j, reinterpret_cast<cs_complex_t *>(B)[j], buf);
+#endif
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec) (q.S()->pinv, buf, vec + idx, nc);
+#else
+	  CXSPARSE_ZNAME (_pvec) (nc, q.S()->Pinv, buf, vec + idx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+      info = 0;
+    }
+
+  return x;
+#else
+  return ComplexMatrix ();
+#endif
+}
+
+SparseComplexMatrix
+qrsolve(const SparseComplexMatrix&a, const SparseMatrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type b_nr = b.rows();
+  SparseComplexMatrix x;
+  volatile octave_idx_type ii, x_nz;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = SparseComplexMatrix (nc, b_nc);
+  else if (nr >= nc)
+    {
+      SparseComplexQR q (a, 2);
+      if (! q.ok ())
+	return SparseComplexMatrix();
+      x = SparseComplexMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      OCTAVE_LOCAL_BUFFER (Complex, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_C99_COMPLEX (buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (q.S()->pinv, reinterpret_cast<cs_complex_t *>(Xx), buf, nr);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (nr, q.S()->Pinv, reinterpret_cast<cs_complex_t *>(Xx), buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_ZNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (q.S()->q, buf, reinterpret_cast<cs_complex_t *>(Xx), nc);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (nc, q.S()->Q, buf, reinterpret_cast<cs_complex_t *>(Xx));
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      Complex tmp = Xx[j];
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseComplexMatrix at = a.hermitian();
+      SparseComplexQR q (at, 2);
+      if (! q.ok ())
+	return SparseComplexMatrix();
+      x = SparseComplexMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (Complex, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_C99_COMPLEX (buf, nbuf);
+
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+      OCTAVE_LOCAL_BUFFER (double, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = q.N()->B [i];
+#else
+      OCTAVE_LOCAL_BUFFER (Complex, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = conj (reinterpret_cast<Complex *>(q.N()->B) [i]);
+#endif
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec)
+	    (q.S()->q, reinterpret_cast<cs_complex_t *>(Xx), buf, nr);
+#else
+	  CXSPARSE_ZNAME (_pvec)
+	    (nr, q.S()->Q, reinterpret_cast<cs_complex_t *>(Xx), buf);
+#endif
+	  CXSPARSE_ZNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, B[j], buf);
+#else
+	      CXSPARSE_ZNAME (_happly) 
+		(q.N()->L, j, reinterpret_cast<cs_complex_t *>(B)[j], buf);
+#endif
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec) 
+	    (q.S()->pinv, buf, reinterpret_cast<cs_complex_t *>(Xx), nc);
+#else
+	  CXSPARSE_ZNAME (_pvec) 
+	    (nc, q.S()->Pinv, buf, reinterpret_cast<cs_complex_t *>(Xx));
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      Complex tmp = Xx[j];
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+
+  x.maybe_compress ();
+  return x;
+#else
+  return SparseComplexMatrix ();
+#endif
+}
+
+ComplexMatrix
+qrsolve(const SparseComplexMatrix&a, const ComplexMatrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type b_nr = b.rows();
+  const cs_complex_t *bvec = 
+    reinterpret_cast<const cs_complex_t *>(b.fortran_vec());
+  ComplexMatrix x;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = ComplexMatrix (nc, b_nc, Complex (0.0, 0.0));
+  else if (nr >= nc)
+    {
+      SparseComplexQR q (a, 2);
+      if (! q.ok ())
+	return ComplexMatrix();
+      x.resize(nc, b_nc);
+      cs_complex_t *vec = reinterpret_cast<cs_complex_t *>
+	(x.fortran_vec());
+      OCTAVE_C99_COMPLEX (buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; 
+	   i++, idx+=nc, bidx+=b_nr)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) (q.S()->pinv, bvec + bidx, buf, nr);
+#else
+	  CXSPARSE_ZNAME (_ipvec) (nr, q.S()->Pinv, bvec + bidx, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_ZNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) (q.S()->q, buf, vec + idx, nc);
+#else
+	  CXSPARSE_ZNAME (_ipvec) (nc, q.S()->Q, buf, vec + idx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseComplexMatrix at = a.hermitian();
+      SparseComplexQR q (at, 2);
+      if (! q.ok ())
+	return ComplexMatrix();
+      x.resize(nc, b_nc);
+      cs_complex_t *vec = reinterpret_cast<cs_complex_t *>
+	(x.fortran_vec());
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_C99_COMPLEX (buf, nbuf);
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+      OCTAVE_LOCAL_BUFFER (double, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = q.N()->B [i];
+#else
+      OCTAVE_LOCAL_BUFFER (Complex, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = conj (reinterpret_cast<Complex *>(q.N()->B) [i]);
+#endif
+      for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; 
+	   i++, idx+=nc, bidx+=b_nr)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec) (q.S()->q, bvec + bidx, buf, nr);
+#else
+	  CXSPARSE_ZNAME (_pvec) (nr, q.S()->Q, bvec + bidx, buf);
+#endif
+	  CXSPARSE_ZNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, B[j], buf);
+#else
+	      CXSPARSE_ZNAME (_happly) 
+		(q.N()->L, j, reinterpret_cast<cs_complex_t *>(B)[j], buf);
+#endif
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec) (q.S()->pinv, buf, vec + idx, nc);
+#else
+	  CXSPARSE_ZNAME (_pvec) (nc, q.S()->Pinv, buf, vec + idx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+      info = 0;
+    }
+
+  return x;
+#else
+  return ComplexMatrix ();
+#endif
+}
+
+SparseComplexMatrix
+qrsolve(const SparseComplexMatrix&a, const SparseComplexMatrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type b_nr = b.rows();
+  SparseComplexMatrix x;
+  volatile octave_idx_type ii, x_nz;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = SparseComplexMatrix (nc, b_nc);
+  else if (nr >= nc)
+    {
+      SparseComplexQR q (a, 2);
+      if (! q.ok ())
+	return SparseComplexMatrix();
+      x = SparseComplexMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      OCTAVE_LOCAL_BUFFER (Complex, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_C99_COMPLEX (buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (q.S()->pinv, reinterpret_cast<cs_complex_t *>(Xx), buf, nr);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (nr, q.S()->Pinv, reinterpret_cast<cs_complex_t *>(Xx), buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_ZNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (q.S()->q, buf, reinterpret_cast<cs_complex_t *>(Xx), nc);
+#else
+	  CXSPARSE_ZNAME (_ipvec) 
+	    (nc, q.S()->Q, buf, reinterpret_cast<cs_complex_t *>(Xx));
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      Complex tmp = Xx[j];
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseComplexMatrix at = a.hermitian();
+      SparseComplexQR q (at, 2);
+      if (! q.ok ())
+	return SparseComplexMatrix();
+      x = SparseComplexMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (Complex, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_C99_COMPLEX (buf, nbuf);
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+      OCTAVE_LOCAL_BUFFER (double, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = q.N()->B [i];
+#else
+      OCTAVE_LOCAL_BUFFER (Complex, B, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	B[i] = conj (reinterpret_cast<Complex *>(q.N()->B) [i]);
+#endif
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = OCTAVE_C99_ZERO;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec)
+	    (q.S()->q, reinterpret_cast<cs_complex_t *>(Xx), buf, nr);
+#else
+	  CXSPARSE_ZNAME (_pvec)
+	    (nr, q.S()->Q, reinterpret_cast<cs_complex_t *>(Xx), buf);
+#endif
+	  CXSPARSE_ZNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (((CS_VER == 2) && (CS_SUBVER >= 2)) || (CS_VER > 2))
+	      CXSPARSE_ZNAME (_happly) (q.N()->L, j, B[j], buf);
+#else
+	      CXSPARSE_ZNAME (_happly) 
+		(q.N()->L, j, reinterpret_cast<cs_complex_t *>(B)[j], buf);
+#endif
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_ZNAME (_pvec) 
+	    (q.S()->pinv, buf, reinterpret_cast<cs_complex_t *>(Xx), nc);
+#else
+	  CXSPARSE_ZNAME (_pvec) 
+	    (nc, q.S()->Pinv, buf, reinterpret_cast<cs_complex_t *>(Xx));
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      Complex tmp = Xx[j];
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+
+  x.maybe_compress ();
+  return x;
+#else
+  return SparseComplexMatrix ();
+#endif
+}
+
+ComplexMatrix 
+qrsolve (const SparseComplexMatrix &a, const MArray2<double> &b, 
+	 octave_idx_type &info)
+{
+  return qrsolve (a, Matrix (b), info);
+}
+
+ComplexMatrix 
+qrsolve (const SparseComplexMatrix &a, const MArray2<Complex> &b, 
+	 octave_idx_type &info)
+{
+  return qrsolve (a, ComplexMatrix (b), info);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseCmplxQR.h b/liboctave/SparseCmplxQR.h
new file mode 100644
index 0000000..d2c50c5
--- /dev/null
+++ b/liboctave/SparseCmplxQR.h
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (sparse_cmplx_QR_h)
+#define sparse_cmplx_QR_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "CMatrix.h"
+#include "dSparse.h"
+#include "CSparse.h"
+#include "oct-sparse.h"
+
+#ifdef IDX_TYPE_LONG
+#define CXSPARSE_ZNAME(name) cs_cl ## name
+#else
+#define CXSPARSE_ZNAME(name) cs_ci ## name
+#endif
+
+class
+OCTAVE_API
+SparseComplexQR
+{
+protected:
+  class SparseComplexQR_rep
+  {
+  public:
+    SparseComplexQR_rep (const SparseComplexMatrix& a, int order);
+
+    ~SparseComplexQR_rep (void);
+#ifdef HAVE_CXSPARSE
+    bool ok (void) const { return (N && S); }
+#else
+    bool ok (void) const { return false; }
+#endif
+    SparseComplexMatrix V (void) const;
+
+    ColumnVector Pinv (void) const;
+
+    ColumnVector P (void) const;
+
+    SparseComplexMatrix R (const bool econ) const;
+
+    ComplexMatrix C (const ComplexMatrix &b) const;
+
+    ComplexMatrix Q (void) const;
+
+    int count;
+
+    octave_idx_type nrows;
+#ifdef HAVE_CXSPARSE
+    CXSPARSE_ZNAME (s) *S;
+
+    CXSPARSE_ZNAME (n) *N;
+#endif
+  };
+private:
+  SparseComplexQR_rep *rep;
+
+public:  
+  SparseComplexQR (void) : 
+    rep (new SparseComplexQR_rep (SparseComplexMatrix(), 0)) { }
+
+  SparseComplexQR (const SparseComplexMatrix& a, int order = 0) : 
+    rep (new SparseComplexQR_rep (a, order)) { }
+
+  SparseComplexQR (const SparseComplexQR& a) : rep (a.rep) { rep->count++; }
+
+  ~SparseComplexQR (void)
+    {
+      if (--rep->count <= 0)
+	delete rep;
+    }
+
+  SparseComplexQR& operator = (const SparseComplexQR& a)
+    {
+      if (this != &a)
+	{
+	  if (--rep->count <= 0)
+	    delete rep;
+
+	  rep = a.rep;
+	  rep->count++;
+	}
+      return *this;
+    }
+
+  bool ok (void) const { return rep->ok(); }
+
+  SparseComplexMatrix V (void) const { return rep->V(); }
+
+  ColumnVector Pinv (void) const { return rep->P(); }
+
+  ColumnVector P (void) const { return rep->P(); }
+
+  SparseComplexMatrix R (const bool econ = false) const 
+    { return rep->R(econ); }
+
+  ComplexMatrix C (const ComplexMatrix &b) const { return rep->C(b); }
+
+  ComplexMatrix Q (void) const { return rep->Q(); }
+
+  friend ComplexMatrix qrsolve (const SparseComplexMatrix &a, const Matrix &b,
+				octave_idx_type &info);
+
+  friend SparseComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+				      const SparseMatrix &b,
+				      octave_idx_type &info);
+
+  friend ComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+				const ComplexMatrix &b,
+				octave_idx_type &info);
+
+  friend SparseComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+				      const SparseComplexMatrix &b,
+				      octave_idx_type &info);
+
+protected:
+#ifdef HAVE_CXSPARSE
+  CXSPARSE_ZNAME (s) * S (void) { return rep->S; }
+
+  CXSPARSE_ZNAME (n) * N (void) { return rep->N; }
+#endif
+};
+
+
+// Publish externally used friend functions.
+
+extern ComplexMatrix qrsolve (const SparseComplexMatrix &a, const Matrix &b,
+			      octave_idx_type &info);
+
+extern ComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+			      const MArray2<double> &b, 
+			      octave_idx_type &info);
+
+extern SparseComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+				    const SparseMatrix &b,
+				    octave_idx_type &info);
+
+extern ComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+			      const ComplexMatrix &b,
+			      octave_idx_type &info);
+
+extern ComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+			      const MArray2<Complex> &b, 
+			      octave_idx_type &info);
+
+extern SparseComplexMatrix qrsolve (const SparseComplexMatrix &a, 
+				    const SparseComplexMatrix &b,
+				    octave_idx_type &info);
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseQR.cc b/liboctave/SparseQR.cc
new file mode 100644
index 0000000..cd0a683
--- /dev/null
+++ b/liboctave/SparseQR.cc
@@ -0,0 +1,919 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+
+#include "lo-error.h"
+#include "SparseQR.h"
+#include "oct-locbuf.h"
+
+SparseQR::SparseQR_rep::SparseQR_rep (const SparseMatrix& a, int order)
+{
+#ifdef HAVE_CXSPARSE
+  CXSPARSE_DNAME () A;
+  A.nzmax = a.nzmax ();
+  A.m = a.rows ();
+  A.n = a.cols ();
+  nrows = A.m;
+  // Cast away const on A, with full knowledge that CSparse won't touch it
+  // Prevents the methods below making a copy of the data.
+  A.p = const_cast<octave_idx_type *>(a.cidx ());
+  A.i = const_cast<octave_idx_type *>(a.ridx ());
+  A.x = const_cast<double *>(a.data ());
+  A.nz = -1;
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+  S = CXSPARSE_DNAME (_sqr) (order, &A, 1);
+#else
+  S = CXSPARSE_DNAME (_sqr) (&A, order - 1, 1);
+#endif
+
+  N = CXSPARSE_DNAME (_qr) (&A, S);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  if (!N)
+    (*current_liboctave_error_handler)
+      ("SparseQR: sparse matrix QR factorization filled");
+  count = 1;
+#else
+  (*current_liboctave_error_handler)
+    ("SparseQR: sparse matrix QR factorization not implemented");
+#endif
+}
+
+SparseQR::SparseQR_rep::~SparseQR_rep (void)
+{
+#ifdef HAVE_CXSPARSE
+  CXSPARSE_DNAME (_sfree) (S);
+  CXSPARSE_DNAME (_nfree) (N);
+#endif
+}
+
+SparseMatrix 
+SparseQR::SparseQR_rep::V (void) const
+{
+#ifdef HAVE_CXSPARSE
+  // Drop zeros from V and sort
+  // FIXME Is the double transpose to sort necessary?
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  CXSPARSE_DNAME (_dropzeros) (N->L);
+  CXSPARSE_DNAME () *D = CXSPARSE_DNAME (_transpose) (N->L, 1);
+  CXSPARSE_DNAME (_spfree) (N->L);
+  N->L = CXSPARSE_DNAME (_transpose) (D, 1);
+  CXSPARSE_DNAME (_spfree) (D);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  octave_idx_type nc = N->L->n;
+  octave_idx_type nz = N->L->nzmax;
+  SparseMatrix ret (N->L->m, nc, nz);
+  for (octave_idx_type j = 0; j < nc+1; j++)
+    ret.xcidx (j) = N->L->p[j];
+  for (octave_idx_type j = 0; j < nz; j++)
+    {
+      ret.xridx (j) = N->L->i[j];
+      ret.xdata (j) = N->L->x[j];
+    }
+  return ret;
+#else
+  return SparseMatrix ();
+#endif
+}
+
+ColumnVector 
+SparseQR::SparseQR_rep::Pinv (void) const
+{
+#ifdef HAVE_CXSPARSE
+  ColumnVector ret(N->L->m);
+  for (octave_idx_type i = 0; i < N->L->m; i++)
+#if defined(CS_VER) && (CS_VER >= 2)
+    ret.xelem(i) = S->pinv[i];
+#else
+    ret.xelem(i) = S->Pinv[i];
+#endif
+  return ret;
+#else
+  return ColumnVector ();
+#endif
+}
+
+ColumnVector 
+SparseQR::SparseQR_rep::P (void) const
+{
+#ifdef HAVE_CXSPARSE
+  ColumnVector ret(N->L->m);
+  for (octave_idx_type i = 0; i < N->L->m; i++)
+#if defined(CS_VER) && (CS_VER >= 2)
+    ret.xelem(S->pinv[i]) = i;
+#else
+    ret.xelem(S->Pinv[i]) = i;
+#endif
+  return ret;
+#else
+  return ColumnVector ();
+#endif
+}
+
+SparseMatrix 
+SparseQR::SparseQR_rep::R (const bool econ) const
+{
+#ifdef HAVE_CXSPARSE
+  // Drop zeros from R and sort
+  // FIXME Is the double transpose to sort necessary?
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  CXSPARSE_DNAME (_dropzeros) (N->U);
+  CXSPARSE_DNAME () *D = CXSPARSE_DNAME (_transpose) (N->U, 1);
+  CXSPARSE_DNAME (_spfree) (N->U);
+  N->U = CXSPARSE_DNAME (_transpose) (D, 1);
+  CXSPARSE_DNAME (_spfree) (D);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  octave_idx_type nc = N->U->n;
+  octave_idx_type nz = N->U->nzmax;
+
+  SparseMatrix ret ((econ ? (nc > nrows ? nrows : nc) : nrows), nc, nz);
+
+  for (octave_idx_type j = 0; j < nc+1; j++)
+    ret.xcidx (j) = N->U->p[j];
+  for (octave_idx_type j = 0; j < nz; j++)
+    {
+      ret.xridx (j) = N->U->i[j];
+      ret.xdata (j) = N->U->x[j];
+    }
+  return ret;
+#else
+  return SparseMatrix ();
+#endif
+}
+
+Matrix
+SparseQR::SparseQR_rep::C (const Matrix &b) const
+{
+#ifdef HAVE_CXSPARSE
+  octave_idx_type b_nr = b.rows();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type nc = N->L->n;
+  octave_idx_type nr = nrows;
+  const double *bvec = b.fortran_vec();
+  Matrix ret (b_nr, b_nc);
+  double *vec = ret.fortran_vec();
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler) ("matrix dimension mismatch");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    ret = Matrix (nc, b_nc, 0.0);
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, buf, S->m2);
+      for (volatile octave_idx_type j = 0, idx = 0; j < b_nc; j++, idx+=b_nr)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type i = nr; i < S->m2; i++)
+	    buf[i] = 0.;
+	  volatile octave_idx_type nm = (nr < nc ? nr : nc);
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (S->pinv, bvec + idx, buf, b_nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (b_nr, S->Pinv, bvec + idx, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (volatile octave_idx_type i = 0; i < nm; i++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (N->L, i, N->B[i], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  for (octave_idx_type i = 0; i < b_nr; i++)
+	    vec[i+idx] = buf[i];
+	}
+    }
+  return ret;
+#else
+  return Matrix ();
+#endif
+}
+
+Matrix
+SparseQR::SparseQR_rep::Q (void) const
+{
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nc = N->L->n;
+  octave_idx_type nr = nrows;
+  Matrix ret (nr, nr);
+  double *vec = ret.fortran_vec();
+  if (nr < 0 || nc < 0)
+    (*current_liboctave_error_handler) ("matrix dimension mismatch");
+  else if (nr == 0 || nc == 0)
+    ret = Matrix (nc, nr, 0.0);
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, bvec, nr + 1);
+      for (octave_idx_type i = 0; i < nr; i++)
+	bvec[i] = 0.;
+      OCTAVE_LOCAL_BUFFER (double, buf, S->m2);
+      for (volatile octave_idx_type j = 0, idx = 0; j < nr; j++, idx+=nr)
+	{
+	  OCTAVE_QUIT;
+	  bvec[j] = 1.0;
+	  for (octave_idx_type i = nr; i < S->m2; i++)
+	    buf[i] = 0.;
+	  volatile octave_idx_type nm = (nr < nc ? nr : nc);
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (S->pinv, bvec, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, S->Pinv, bvec, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (volatile octave_idx_type i = 0; i < nm; i++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (N->L, i, N->B[i], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    vec[i+idx] = buf[i];
+	  bvec[j] = 0.0;
+	}
+    }
+  return ret.transpose ();
+#else
+  return Matrix ();
+#endif
+}
+
+Matrix
+qrsolve(const SparseMatrix&a, const Matrix &b, octave_idx_type& info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type b_nr = b.rows();
+  const double *bvec = b.fortran_vec();
+  Matrix x;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = Matrix (nc, b_nc, 0.0);
+  else if (nr >= nc)
+    {
+      SparseQR q (a, 3);
+      if (! q.ok ()) 
+	return Matrix();
+      x.resize(nc, b_nc);
+      double *vec = x.fortran_vec();
+      OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; 
+	   i++, idx+=nc, bidx+=b_nr)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->pinv, bvec + bidx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, bvec + bidx, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_DNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, vec + idx, nc);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, vec + idx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseMatrix at = a.hermitian();
+      SparseQR q (at, 3);
+      if (! q.ok ())
+	return Matrix();
+      x.resize(nc, b_nc);
+      double *vec = x.fortran_vec();
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (double, buf, nbuf);
+      for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; 
+	   i++, idx+=nc, bidx+=b_nr)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->q, bvec + bidx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, bvec + bidx, buf);
+#endif
+	  CXSPARSE_DNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, vec + idx, nc);
+#else
+	  CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, vec + idx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+      info = 0;
+    }
+
+  return x;
+#else
+  return Matrix ();
+#endif
+}
+
+SparseMatrix
+qrsolve(const SparseMatrix&a, const SparseMatrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nr = b.rows();
+  octave_idx_type b_nc = b.cols();
+  SparseMatrix x;
+  volatile octave_idx_type ii, x_nz;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = SparseMatrix (nc, b_nc);
+  else if (nr >= nc)
+    {
+      SparseQR q (a, 3);
+      if (! q.ok ()) 
+	return SparseMatrix();
+      x = SparseMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_DNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      double tmp = Xx[j];
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseMatrix at = a.hermitian();
+      SparseQR q (at, 3);
+      if (! q.ok ())
+	return SparseMatrix();
+      x = SparseMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, buf, nbuf);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    Xx[j] = b.xelem(j,i);
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf);
+#endif
+	  CXSPARSE_DNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc);
+#else
+	  CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      double tmp = Xx[j];
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+
+  x.maybe_compress ();
+  return x;
+#else
+  return SparseMatrix ();
+#endif
+}
+
+ComplexMatrix
+qrsolve(const SparseMatrix&a, const ComplexMatrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nc = b.cols();
+  octave_idx_type b_nr = b.rows();
+  ComplexMatrix x;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = ComplexMatrix (nc, b_nc, Complex (0.0, 0.0));
+  else if (nr >= nc)
+    {
+      SparseQR q (a, 3);
+      if (! q.ok ())
+	return ComplexMatrix();
+      x.resize(nc, b_nc);
+      Complex *vec = x.fortran_vec();
+      OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    {
+	      Complex c = b.xelem (j,i);
+	      Xx[j] = std::real (c);
+	      Xz[j] = std::imag (c);
+	    }
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_DNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx);
+#endif
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = 0.;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xz, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xz, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_DNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xz, nc);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xz);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    vec[j+idx] = Complex (Xx[j], Xz[j]);
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseMatrix at = a.hermitian();
+      SparseQR q (at, 3);
+      if (! q.ok ())
+	return ComplexMatrix();
+      x.resize(nc, b_nc);
+      Complex *vec = x.fortran_vec();
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, buf, nbuf);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    {
+	      Complex c = b.xelem (j,i);
+	      Xx[j] = std::real (c);
+	      Xz[j] = std::imag (c);
+	    }
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf);
+#endif
+	  CXSPARSE_DNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc);
+#else
+	  CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->q, Xz, buf, nr);
+#else
+	  CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xz, buf);
+#endif
+	  CXSPARSE_DNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xz, nc);
+#else
+	  CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xz);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    vec[j+idx] = Complex (Xx[j], Xz[j]);
+	}
+      info = 0;
+    }
+
+  return x;
+#else
+  return ComplexMatrix ();
+#endif
+}
+
+SparseComplexMatrix
+qrsolve(const SparseMatrix&a, const SparseComplexMatrix &b, octave_idx_type &info)
+{
+  info = -1;
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows();
+  octave_idx_type nc = a.cols();
+  octave_idx_type b_nr = b.rows();
+  octave_idx_type b_nc = b.cols();
+  SparseComplexMatrix x;
+  volatile octave_idx_type ii, x_nz;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    x = SparseComplexMatrix (nc, b_nc);
+  else if (nr >= nc)
+    {
+      SparseQR q (a, 3);
+      if (! q.ok ()) 
+	return SparseComplexMatrix();
+      x = SparseComplexMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    {
+	      Complex c = b.xelem (j,i);
+	      Xx[j] = std::real (c);
+	      Xz[j] = std::imag (c);
+	    }
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_DNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (octave_idx_type j = nr; j < q.S()->m2; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xz, buf, nr);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xz, buf);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CXSPARSE_DNAME (_usolve) (q.N()->U, buf);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xz, nc);
+#else
+	  CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xz);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      Complex tmp = Complex (Xx[j], Xz[j]);
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+  else
+    {
+      SparseMatrix at = a.hermitian();
+      SparseQR q (at, 3);
+      if (! q.ok ())
+	return SparseComplexMatrix();
+      x = SparseComplexMatrix (nc, b_nc, b.nzmax());
+      x.xcidx(0) = 0;
+      x_nz = b.nzmax();
+      ii = 0;
+      volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2);
+      OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc));
+      OCTAVE_LOCAL_BUFFER (double, buf, nbuf);
+      for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc)
+	{
+	  OCTAVE_QUIT;
+	  for (octave_idx_type j = 0; j < b_nr; j++)
+	    {
+	      Complex c = b.xelem (j,i);
+	      Xx[j] = std::real (c);
+	      Xz[j] = std::imag (c);
+	    }
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr);
+#else
+	  CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf);
+#endif
+	  CXSPARSE_DNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc);
+#else
+	  CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (octave_idx_type j = nr; j < nbuf; j++)
+	    buf[j] = 0.;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->q, Xz, buf, nr);
+#else
+	  CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xz, buf);
+#endif
+	  CXSPARSE_DNAME (_utsolve) (q.N()->U, buf);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  for (volatile octave_idx_type j = nr-1; j >= 0; j--)
+	    {
+	      OCTAVE_QUIT;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xz, nc);
+#else
+	  CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xz);
+#endif
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      Complex tmp = Complex (Xx[j], Xz[j]);
+	      if (tmp != 0.0)
+		{
+		  if (ii == x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = x_nz * (b_nc - i) / b_nc;
+		      sz = (sz > 10 ? sz : 10) + x_nz;
+		      x.change_capacity (sz);
+		      x_nz = sz;
+		    }
+		  x.xdata(ii) = tmp;
+		  x.xridx(ii++) = j;
+		}
+	    }
+	  x.xcidx(i+1) = ii;
+	}
+      info = 0;
+    }
+
+  x.maybe_compress ();
+  return x;
+#else
+  return SparseComplexMatrix ();
+#endif
+}
+
+Matrix 
+qrsolve(const SparseMatrix &a, const MArray2<double> &b, 
+	octave_idx_type &info)
+{ 
+  return qrsolve (a, Matrix (b), info); 
+}
+
+ComplexMatrix 
+qrsolve(const SparseMatrix &a, const MArray2<Complex> &b, 
+	octave_idx_type &info)
+{ 
+  return qrsolve (a, ComplexMatrix (b), info);
+}
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparseQR.h b/liboctave/SparseQR.h
new file mode 100644
index 0000000..1c2085f
--- /dev/null
+++ b/liboctave/SparseQR.h
@@ -0,0 +1,170 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (sparse_QR_h)
+#define sparse_QR_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "CMatrix.h"
+#include "dSparse.h"
+#include "CSparse.h"
+#include "oct-sparse.h"
+
+#ifdef IDX_TYPE_LONG
+#define CXSPARSE_DNAME(name) cs_dl ## name
+#else
+#define CXSPARSE_DNAME(name) cs_di ## name
+#endif
+
+class
+OCTAVE_API
+SparseQR
+{
+protected:
+  class SparseQR_rep
+  {
+  public:
+    SparseQR_rep (const SparseMatrix& a, int order);
+
+    ~SparseQR_rep (void);
+#ifdef HAVE_CXSPARSE
+    bool ok (void) const { return (N && S); }
+#else
+    bool ok (void) const { return false; }
+#endif
+    SparseMatrix V (void) const;
+
+    ColumnVector Pinv (void) const;
+
+    ColumnVector P (void) const;
+
+    SparseMatrix R (const bool econ) const;
+
+    Matrix C (const Matrix &b) const;
+
+    Matrix Q (void) const;
+
+    int count;
+
+    octave_idx_type nrows;
+#ifdef HAVE_CXSPARSE
+    CXSPARSE_DNAME (s) *S;
+
+    CXSPARSE_DNAME (n) *N;
+#endif
+  };
+private:
+  SparseQR_rep *rep;
+
+public:  
+  SparseQR (void) : rep (new SparseQR_rep (SparseMatrix(), 0)) { }
+
+  SparseQR (const SparseMatrix& a, int order = 0) : 
+    rep (new SparseQR_rep (a, order)) { }
+
+  SparseQR (const SparseQR& a) : rep (a.rep) { rep->count++; }
+
+  ~SparseQR (void)
+    {
+      if (--rep->count <= 0)
+	delete rep;
+    }
+
+  SparseQR& operator = (const SparseQR& a)
+    {
+      if (this != &a)
+	{
+	  if (--rep->count <= 0)
+	    delete rep;
+
+	  rep = a.rep;
+	  rep->count++;
+	}
+      return *this;
+    }
+
+  bool ok (void) const { return rep->ok(); }
+
+  SparseMatrix V (void) const { return rep->V(); }
+
+  ColumnVector Pinv (void) const { return rep->P(); }
+
+  ColumnVector P (void) const { return rep->P(); }
+
+  SparseMatrix R (const bool econ = false) const { return rep->R(econ); }
+
+  Matrix C (const Matrix &b) const { return rep->C(b); }
+
+  Matrix Q (void) const { return rep->Q(); }
+
+  friend Matrix qrsolve (const SparseMatrix &a, const Matrix &b, 
+			 octave_idx_type &info);
+
+  friend SparseMatrix qrsolve (const SparseMatrix &a, const SparseMatrix &b,
+			 octave_idx_type &info);
+
+  friend ComplexMatrix qrsolve (const SparseMatrix &a, const ComplexMatrix &b,
+				octave_idx_type &info);
+
+  friend SparseComplexMatrix qrsolve (const SparseMatrix &a, 
+				      const SparseComplexMatrix &b,
+				      octave_idx_type &info);
+
+protected:
+#ifdef HAVE_CXSPARSE
+  CXSPARSE_DNAME (s) * S (void) { return rep->S; }
+
+  CXSPARSE_DNAME (n) * N (void) { return rep->N; }
+#endif
+};
+
+
+// Publish externally used friend functions.
+
+extern Matrix qrsolve (const SparseMatrix &a, const Matrix &b, 
+		       octave_idx_type &info);
+
+extern Matrix qrsolve (const SparseMatrix &a, const MArray2<double> &b, 
+		       octave_idx_type &info);
+
+extern SparseMatrix qrsolve (const SparseMatrix &a, const SparseMatrix &b,
+			     octave_idx_type &info);
+
+extern ComplexMatrix qrsolve (const SparseMatrix &a, const ComplexMatrix &b,
+			      octave_idx_type &info);
+
+extern ComplexMatrix qrsolve (const SparseMatrix &a, const MArray2<Complex> &b, 
+			      octave_idx_type &info);
+
+extern SparseComplexMatrix qrsolve (const SparseMatrix &a, 
+				    const SparseComplexMatrix &b,
+				    octave_idx_type &info);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparsedbleCHOL.cc b/liboctave/SparsedbleCHOL.cc
new file mode 100644
index 0000000..60e6366
--- /dev/null
+++ b/liboctave/SparsedbleCHOL.cc
@@ -0,0 +1,76 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SparsedbleCHOL.h"
+
+// Instantiate the base CHOL class for the type we need
+#define OCTAVE_CHOLMOD_TYPE CHOLMOD_REAL
+#include "sparse-base-chol.h"
+#include "sparse-base-chol.cc"
+template class sparse_base_chol <SparseMatrix, double, SparseMatrix>;
+
+// Compute the inverse of a matrix using the Cholesky factorization.
+SparseMatrix
+chol2inv (const SparseMatrix& r)
+{
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.cols ();
+  SparseMatrix retval;
+
+  if (r_nr == r_nc)
+    {
+      MatrixType mattype (r);
+      int typ = mattype.type (false);
+      double rcond;
+      octave_idx_type info;
+      SparseMatrix rinv;
+
+      if (typ == MatrixType::Upper)
+	{
+	  rinv = r.inverse(mattype, info, rcond, true, false);
+	  retval = rinv.transpose() * rinv;
+	}
+      else if (typ == MatrixType::Lower)
+	{
+	  rinv = r.transpose().inverse(mattype, info, rcond, true, false);
+	  retval = rinv.transpose() * rinv;
+	}
+      else
+	(*current_liboctave_error_handler) 
+	  ("spchol2inv requires triangular matrix");
+    }
+  else
+    (*current_liboctave_error_handler) ("spchol2inv requires square matrix");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparsedbleCHOL.h b/liboctave/SparsedbleCHOL.h
new file mode 100644
index 0000000..8114349
--- /dev/null
+++ b/liboctave/SparsedbleCHOL.h
@@ -0,0 +1,92 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_CHOL_h)
+#define octave_sparse_CHOL_h 1
+
+#include "sparse-base-chol.h"
+#include "dSparse.h"
+
+class
+OCTAVE_API
+SparseCHOL : public sparse_base_chol <SparseMatrix, double, SparseMatrix>
+{
+public:
+
+  SparseCHOL (void) : sparse_base_chol<SparseMatrix, double, SparseMatrix> () { }
+
+  SparseCHOL (const SparseMatrix& a, bool natural = true) : 
+    sparse_base_chol<SparseMatrix, double, SparseMatrix> (a, natural) { }
+
+  SparseCHOL (const SparseMatrix& a, octave_idx_type& info, 
+	      bool natural = true) : 
+    sparse_base_chol<SparseMatrix, double, SparseMatrix> (a, info, natural) { }
+
+  SparseCHOL (const SparseCHOL& a) : 
+    sparse_base_chol<SparseMatrix, double, SparseMatrix> (a) { }
+
+  ~SparseCHOL (void) { }
+
+  SparseCHOL& operator = (const SparseCHOL& a)
+    {
+      if (this != &a)
+	sparse_base_chol <SparseMatrix, double, SparseMatrix> :: operator = (a);
+
+      return *this;
+    }
+
+  SparseMatrix chol_matrix (void) const { return R(); }
+
+  SparseMatrix L (void) const 
+  { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: L (); }
+
+  SparseMatrix R (void) const 
+    { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: R (); }
+
+  octave_idx_type P (void) const 
+    { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: P (); }
+
+  ColumnVector perm (void) const 
+    { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: perm (); }
+
+  SparseMatrix Q (void) const 
+    { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: Q (); }
+
+  double rcond (void) const
+    { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: rcond (); }
+
+  // Compute the inverse of a matrix using the Cholesky factorization.
+  SparseMatrix inverse (void) const
+   { return sparse_base_chol<SparseMatrix, double, SparseMatrix>:: 
+       inverse (); }
+};
+
+SparseMatrix OCTAVE_API chol2inv (const SparseMatrix& r);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/SparsedbleLU.cc b/liboctave/SparsedbleLU.cc
new file mode 100644
index 0000000..2f2a083
--- /dev/null
+++ b/liboctave/SparsedbleLU.cc
@@ -0,0 +1,464 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+#include "SparsedbleLU.h"
+#include "oct-spparms.h"
+
+// Instantiate the base LU class for the types we need.
+
+#include "sparse-base-lu.h"
+#include "sparse-base-lu.cc"
+
+template class sparse_base_lu <SparseMatrix, double, SparseMatrix, double>;
+
+#include "oct-sparse.h"
+
+SparseLU::SparseLU (const SparseMatrix& a, const Matrix& piv_thres, bool scale)
+{
+#ifdef HAVE_UMFPACK
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  // Setup the control parameters
+  Matrix Control (UMFPACK_CONTROL, 1);
+  double *control = Control.fortran_vec ();
+  UMFPACK_DNAME (defaults) (control);
+
+  double tmp = octave_sparse_params::get_key ("spumoni");
+  if (!xisnan (tmp))
+    Control (UMFPACK_PRL) = tmp;
+
+  if (piv_thres.nelem() == 2)
+    {
+      tmp = (piv_thres (0) > 1. ? 1. : piv_thres (0));
+      if (!xisnan (tmp))
+	Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+      tmp = (piv_thres (1) > 1. ? 1. : piv_thres (1));
+      if (!xisnan (tmp))
+	Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+    }
+  else
+    {
+      tmp = octave_sparse_params::get_key ("piv_tol");
+      if (!xisnan (tmp))
+	Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+
+      tmp = octave_sparse_params::get_key ("sym_tol");
+      if (!xisnan (tmp))
+	  Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+    }
+
+  // Set whether we are allowed to modify Q or not
+  tmp = octave_sparse_params::get_key ("autoamd");
+  if (!xisnan (tmp))
+    Control (UMFPACK_FIXQ) = tmp;
+
+  if (scale)
+    Control (UMFPACK_SCALE) = UMFPACK_SCALE_SUM;
+  else
+    Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
+
+  UMFPACK_DNAME (report_control) (control);
+
+  const octave_idx_type *Ap = a.cidx ();
+  const octave_idx_type *Ai = a.ridx ();
+  const double *Ax = a.data ();
+
+  UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control);
+
+  void *Symbolic;
+  Matrix Info (1, UMFPACK_INFO);
+  double *info = Info.fortran_vec ();
+  int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, 0,
+				     &Symbolic, control, info);
+
+  if (status < 0)
+    {
+      (*current_liboctave_error_handler) 
+	    ("SparseLU::SparseLU symbolic factorization failed");
+
+      UMFPACK_DNAME (report_status) (control, status);
+      UMFPACK_DNAME (report_info) (control, info);
+
+      UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+    }
+  else
+    {
+      UMFPACK_DNAME (report_symbolic) (Symbolic, control);
+
+      void *Numeric;
+      status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, 
+				   &Numeric, control, info) ;
+      UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+
+      cond = Info (UMFPACK_RCOND);
+
+      if (status < 0)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("SparseLU::SparseLU numeric factorization failed");
+
+	  UMFPACK_DNAME (report_status) (control, status);
+	  UMFPACK_DNAME (report_info) (control, info);
+
+	  UMFPACK_DNAME (free_numeric) (&Numeric);
+	}
+      else
+	{
+	  UMFPACK_DNAME (report_numeric) (Numeric, control);
+
+	  octave_idx_type lnz, unz, ignore1, ignore2, ignore3;
+	  status = UMFPACK_DNAME (get_lunz) (&lnz, &unz, &ignore1,
+					&ignore2, &ignore3, Numeric) ;
+	  
+	  if (status < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("SparseLU::SparseLU extracting LU factors failed");
+
+	      UMFPACK_DNAME (report_status) (control, status);
+	      UMFPACK_DNAME (report_info) (control, info);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    {
+	      octave_idx_type n_inner = (nr < nc ? nr : nc);
+
+	      if (lnz < 1)
+		Lfact = SparseMatrix (n_inner, nr,
+				      static_cast<octave_idx_type> (1));
+	      else
+		Lfact = SparseMatrix (n_inner, nr, lnz);
+
+	      octave_idx_type *Ltp = Lfact.cidx ();
+	      octave_idx_type *Ltj = Lfact.ridx ();
+	      double *Ltx = Lfact.data ();
+
+	      if (unz < 1)
+		Ufact = SparseMatrix (n_inner, nc,
+				      static_cast<octave_idx_type> (1));
+	      else
+		Ufact = SparseMatrix (n_inner, nc, unz);
+
+	      octave_idx_type *Up = Ufact.cidx ();
+	      octave_idx_type *Uj = Ufact.ridx ();
+	      double *Ux = Ufact.data ();
+
+	      Rfact = SparseMatrix (nr, nr, nr);
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  Rfact.xridx (i) = i;
+		  Rfact.xcidx (i) = i;
+		}
+	      Rfact.xcidx (nr) = nr;
+	      double *Rx = Rfact.data ();
+
+	      P.resize (nr);
+	      octave_idx_type *p = P.fortran_vec ();
+
+	      Q.resize (nc);
+	      octave_idx_type *q = Q.fortran_vec ();
+
+	      octave_idx_type do_recip;
+	      status = UMFPACK_DNAME (get_numeric) (Ltp, Ltj, Ltx,
+					       Up, Uj, Ux, p, q, 0,
+					       &do_recip, Rx, 
+					       Numeric) ;
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric) ;
+
+	      if (status < 0)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("SparseLU::SparseLU extracting LU factors failed");
+
+		  UMFPACK_DNAME (report_status) (control, status);
+		}
+	      else
+		{
+		  Lfact = Lfact.transpose ();
+
+		  if (do_recip)
+		    for (octave_idx_type i = 0; i < nr; i++)
+		      Rx[i] = 1.0 / Rx[i];
+
+		  UMFPACK_DNAME (report_matrix) (nr, n_inner, 
+					    Lfact.cidx (), Lfact.ridx (),
+					    Lfact.data (), 1, control);
+		  UMFPACK_DNAME (report_matrix) (n_inner, nc, 
+					    Ufact.cidx (), Ufact.ridx (),
+					    Ufact.data (), 1, control);
+		  UMFPACK_DNAME (report_perm) (nr, p, control);
+		  UMFPACK_DNAME (report_perm) (nc, q, control);
+		}
+
+	      UMFPACK_DNAME (report_info) (control, info);
+	    }
+	}
+    }
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+}
+
+SparseLU::SparseLU (const SparseMatrix& a, const ColumnVector& Qinit,
+		    const Matrix& piv_thres, bool scale, bool FixedQ,
+		    double droptol, bool milu, bool udiag)
+{
+#ifdef HAVE_UMFPACK
+  if (milu)
+    (*current_liboctave_error_handler) 
+      ("Modified incomplete LU not implemented");   
+  else
+    {
+      octave_idx_type nr = a.rows ();
+      octave_idx_type nc = a.cols ();
+
+      // Setup the control parameters
+      Matrix Control (UMFPACK_CONTROL, 1);
+      double *control = Control.fortran_vec ();
+      UMFPACK_DNAME (defaults) (control);
+
+      double tmp = octave_sparse_params::get_key ("spumoni");
+      if (!xisnan (tmp))
+	Control (UMFPACK_PRL) = tmp;
+
+      if (piv_thres.nelem() == 2)
+	{
+	  tmp = (piv_thres (0) > 1. ? 1. : piv_thres (0));
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+	  tmp = (piv_thres (1) > 1. ? 1. : piv_thres (1));
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+	}
+      else
+	{
+	  tmp = octave_sparse_params::get_key ("piv_tol");
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+
+	  tmp = octave_sparse_params::get_key ("sym_tol");
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+	}
+
+      if (droptol >= 0.)
+	Control (UMFPACK_DROPTOL) = droptol;
+
+
+      // Set whether we are allowed to modify Q or not
+      if (FixedQ)
+	Control (UMFPACK_FIXQ) = 1.0;
+      else
+	{
+	  tmp = octave_sparse_params::get_key ("autoamd");
+	  if (!xisnan (tmp))
+	    Control (UMFPACK_FIXQ) = tmp;
+	}
+
+      if (scale)
+	Control (UMFPACK_SCALE) = UMFPACK_SCALE_SUM;
+      else
+	Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
+
+      UMFPACK_DNAME (report_control) (control);
+
+      const octave_idx_type *Ap = a.cidx ();
+      const octave_idx_type *Ai = a.ridx ();
+      const double *Ax = a.data ();
+
+      UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, 
+						     control);
+
+      void *Symbolic;
+      Matrix Info (1, UMFPACK_INFO);
+      double *info = Info.fortran_vec ();
+      int status;
+
+      // Null loop so that qinit is imediately deallocated when not needed
+      do {
+	OCTAVE_LOCAL_BUFFER (octave_idx_type, qinit, nc);
+
+	for (octave_idx_type i = 0; i < nc; i++)
+	  qinit [i] = static_cast<octave_idx_type> (Qinit (i));
+
+	status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, 
+				       qinit, &Symbolic, control, info);
+      } while (0);
+
+      if (status < 0)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("SparseLU::SparseLU symbolic factorization failed");
+
+	  UMFPACK_DNAME (report_status) (control, status);
+	  UMFPACK_DNAME (report_info) (control, info);
+
+	  UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+	}
+      else
+	{
+	  UMFPACK_DNAME (report_symbolic) (Symbolic, control);
+
+	  void *Numeric;
+	  status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic,
+				       &Numeric, control, info) ;
+	  UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+
+	  cond = Info (UMFPACK_RCOND);
+
+	  if (status < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("SparseLU::SparseLU numeric factorization failed");
+
+	      UMFPACK_DNAME (report_status) (control, status);
+	      UMFPACK_DNAME (report_info) (control, info);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    {
+	      UMFPACK_DNAME (report_numeric) (Numeric, control);
+
+	      octave_idx_type lnz, unz, ignore1, ignore2, ignore3;
+	      status = UMFPACK_DNAME (get_lunz) (&lnz, &unz, &ignore1, &ignore2,
+						 &ignore3, Numeric) ;
+	  
+	      if (status < 0)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("SparseLU::SparseLU extracting LU factors failed");
+
+		  UMFPACK_DNAME (report_status) (control, status);
+		  UMFPACK_DNAME (report_info) (control, info);
+
+		  UMFPACK_DNAME (free_numeric) (&Numeric);
+		}
+	      else
+		{
+		  octave_idx_type n_inner = (nr < nc ? nr : nc);
+
+		  if (lnz < 1)
+		    Lfact = SparseMatrix (n_inner, nr,
+					  static_cast<octave_idx_type> (1));
+		  else
+		    Lfact = SparseMatrix (n_inner, nr, lnz);
+
+		  octave_idx_type *Ltp = Lfact.cidx ();
+		  octave_idx_type *Ltj = Lfact.ridx ();
+		  double *Ltx = Lfact.data ();
+
+		  if (unz < 1)
+		    Ufact = SparseMatrix (n_inner, nc,
+					  static_cast<octave_idx_type> (1));
+		  else
+		    Ufact = SparseMatrix (n_inner, nc, unz);
+
+		  octave_idx_type *Up = Ufact.cidx ();
+		  octave_idx_type *Uj = Ufact.ridx ();
+		  double *Ux = Ufact.data ();
+
+		  Rfact = SparseMatrix (nr, nr, nr);
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    {
+		      Rfact.xridx (i) = i;
+		      Rfact.xcidx (i) = i;
+		    }
+		  Rfact.xcidx (nr) = nr;
+		  double *Rx = Rfact.data ();
+
+		  P.resize (nr);
+		  octave_idx_type *p = P.fortran_vec ();
+
+		  Q.resize (nc);
+		  octave_idx_type *q = Q.fortran_vec ();
+
+		  octave_idx_type do_recip;
+		  status = UMFPACK_DNAME (get_numeric) (Ltp, Ltj,
+						   Ltx, Up, Uj, Ux, p, q, 
+						   0, &do_recip, 
+						   Rx, Numeric) ;
+
+		  UMFPACK_DNAME (free_numeric) (&Numeric) ;
+
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseLU::SparseLU extracting LU factors failed");
+
+		      UMFPACK_DNAME (report_status) (control, status);
+		    }
+		  else
+		    {
+		      Lfact = Lfact.transpose ();
+
+		      if (do_recip)
+			for (octave_idx_type i = 0; i < nr; i++)
+			  Rx[i] = 1.0 / Rx[i];
+
+		      UMFPACK_DNAME (report_matrix) (nr, n_inner, 
+						Lfact.cidx (), 
+						Lfact.ridx (), 
+						Lfact.data (),
+						1, control);
+		      UMFPACK_DNAME (report_matrix) (n_inner, nc, 
+						Ufact.cidx (), 
+						Ufact.ridx (), 
+						Ufact.data (),
+						1, control);
+		      UMFPACK_DNAME (report_perm) (nr, p, control);
+		      UMFPACK_DNAME (report_perm) (nc, q, control);
+		    }
+
+		  UMFPACK_DNAME (report_info) (control, info);
+		}
+	    }
+	}
+
+      if (udiag)
+	(*current_liboctave_error_handler) 
+	  ("Option udiag of incomplete LU not implemented");   
+    }
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/SparsedbleLU.h b/liboctave/SparsedbleLU.h
new file mode 100644
index 0000000..24594ba
--- /dev/null
+++ b/liboctave/SparsedbleLU.h
@@ -0,0 +1,68 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_LU_h)
+#define octave_sparse_LU_h 1
+
+#include "sparse-base-lu.h"
+#include "dSparse.h"
+
+class
+OCTAVE_API
+SparseLU : public sparse_base_lu <SparseMatrix, double, SparseMatrix, double>
+{
+public:
+
+  SparseLU (void) 
+    : sparse_base_lu <SparseMatrix, double, SparseMatrix, double> () { }
+
+  SparseLU (const SparseMatrix& a, const Matrix& piv_thres = Matrix(),
+	    bool scale = false);
+
+  SparseLU (const SparseMatrix& a, const ColumnVector& Qinit, 
+	    const Matrix& piv_thres = Matrix(), bool scale = false, 
+	    bool FixedQ = false, double droptol = -1., 
+	    bool milu = false, bool udiag = false);
+
+  SparseLU (const SparseLU& a) 
+    : sparse_base_lu <SparseMatrix, double, SparseMatrix, double> (a) { }
+
+  SparseLU& operator = (const SparseLU& a)
+    {
+      if (this != &a)
+	sparse_base_lu <SparseMatrix, double, SparseMatrix, double> 
+	  :: operator = (a);
+
+      return *this;
+    }
+
+  ~SparseLU (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/base-aepbal.h b/liboctave/base-aepbal.h
new file mode 100644
index 0000000..71e7fbe
--- /dev/null
+++ b/liboctave/base-aepbal.h
@@ -0,0 +1,93 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_aepbal_h)
+#define octave_base_aepbal_h 1
+
+#include "oct-types.h"
+
+template <class MatrixT, class VectorT>
+class base_aepbal
+{
+protected:
+  MatrixT balanced_mat;
+  VectorT scale;
+  octave_idx_type ilo, ihi;
+  char job;
+  base_aepbal (void) : balanced_mat (), scale (), ilo (), ihi (), job () { }
+
+public:
+
+  base_aepbal (const base_aepbal& a) 
+    : balanced_mat (a.balanced_mat), scale (a.scale), 
+      ilo(a.ilo), ihi(a.ihi), job(a.job)
+  { 
+  }
+
+  base_aepbal& operator = (const base_aepbal& a)
+    {
+      balanced_mat = a.balanced_mat;
+      scale = a.scale;
+      ilo = a.ilo;
+      ihi = a.ihi;
+      job = a.job;
+      return *this;
+    }
+
+  MatrixT balanced_matrix (void) const { return balanced_mat; }
+
+  VectorT permuting_vector (void) const
+    {
+      octave_idx_type n = balanced_mat.rows ();
+      VectorT pv (n);
+      for (octave_idx_type i = 0; i < n; i++)
+        pv(i) = i+1;
+      for (octave_idx_type i = n-1; i >= ihi; i--)
+        {
+          octave_idx_type j = scale(i) - 1;
+          std::swap (pv(i), pv(j));
+        }
+      for (octave_idx_type i = 0; i < ilo-1; i++)
+        {
+          octave_idx_type j = scale(i) - 1;
+          std::swap (pv(i), pv(j));
+        }
+      
+      return pv;
+    }
+
+  VectorT scaling_vector (void) const
+    {
+      octave_idx_type n = balanced_mat.rows ();
+      VectorT scv (n);
+      for (octave_idx_type i = 0; i < ilo-1; i++)
+        scv(i) = 1;
+      for (octave_idx_type i = ilo-1; i < ihi; i++)
+        scv(i) = scale(i);
+      for (octave_idx_type i = ihi; i < n; i++)
+        scv(i) = 1;
+
+      return scv;
+    }
+};
+
+#endif
diff --git a/liboctave/base-dae.h b/liboctave/base-dae.h
new file mode 100644
index 0000000..9ec631f
--- /dev/null
+++ b/liboctave/base-dae.h
@@ -0,0 +1,84 @@
+/*
+
+Copyright (C) 2002, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_dae_h)
+#define octave_base_dae_h 1
+
+#include "base-de.h"
+
+class
+base_diff_alg_eqn : public base_diff_eqn
+{
+public:
+
+  base_diff_alg_eqn (void)
+    : base_diff_eqn (), xdot () { }
+
+  base_diff_alg_eqn (const ColumnVector& xx, double tt)
+    : base_diff_eqn (xx, tt), xdot (xx.length (), 0.0) { }
+
+  base_diff_alg_eqn (const ColumnVector& xx, const ColumnVector& xxdot,
+		     double tt)
+    : base_diff_eqn (xx, tt), xdot (xxdot) { }
+
+  base_diff_alg_eqn (const base_diff_alg_eqn& a)
+    : base_diff_eqn (a), xdot (a.xdot) { }
+
+  virtual ~base_diff_alg_eqn (void) { }
+
+  base_diff_alg_eqn& operator = (const base_diff_alg_eqn& a)
+    {
+      if (this != &a)
+	{
+	  base_diff_eqn::operator = (a);
+	  xdot = a.xdot;
+	}
+      return *this;
+    }
+
+  void initialize (const ColumnVector& x0, double t0)
+    {
+      base_diff_eqn::initialize (x0, t0);
+      xdot = ColumnVector (x0.length (), 0.0);
+    }
+
+  void initialize (const ColumnVector& x0, const ColumnVector& xdot0,
+		   double t0)
+    {
+      base_diff_eqn::initialize (x0, t0);
+      xdot = xdot0;
+    }
+
+  ColumnVector state_derivative (void) { return xdot; }
+
+protected:
+
+  ColumnVector xdot;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/base-de.h b/liboctave/base-de.h
new file mode 100644
index 0000000..312a6c6
--- /dev/null
+++ b/liboctave/base-de.h
@@ -0,0 +1,125 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_de_h)
+#define octave_base_de_h 1
+
+#include <string>
+
+#include "dColVector.h"
+#include "dMatrix.h"
+
+class
+base_diff_eqn
+{
+public:
+
+  base_diff_eqn (void)
+    : x (), t (0.0), stop_time (0.0), stop_time_set (false),
+      restart (true), integration_error (false), istate (0) { } 
+
+  base_diff_eqn (const ColumnVector& xx, double tt)
+    : x (xx), t (tt), stop_time (0.0), stop_time_set (false),
+      restart (true), integration_error (false), istate (0) { }
+
+  base_diff_eqn (const base_diff_eqn& a)
+    : x (a.x), t (a.t), stop_time (0.0), stop_time_set (false),
+      restart (true), integration_error (false), istate (0) { }
+
+  virtual ~base_diff_eqn (void) { }
+
+  base_diff_eqn& operator = (const base_diff_eqn& a)
+    {
+      if (this != &a)
+	{
+	  x = a.x;
+	  t = a.t;
+	  stop_time = a.stop_time;
+	  stop_time_set = a.stop_time_set;
+	  restart = a.restart;
+	  integration_error = a.integration_error;
+	  istate = a.istate;
+	}
+
+      return *this;
+    }
+
+  void initialize (const ColumnVector& x0, double t0)
+    {
+      x = x0;
+      t = t0;
+      integration_error = false;
+      istate = 0;
+      force_restart ();
+    }
+
+  octave_idx_type size (void) const { return x.capacity (); }
+
+  ColumnVector state (void) const { return x; }
+
+  double time (void) const { return t; }
+
+  void set_stop_time (double tt)
+    {
+      stop_time_set = true;
+      stop_time = tt;
+      force_restart ();
+    }
+
+  void clear_stop_time (void)
+    {
+      stop_time_set = false;
+      force_restart ();
+    }
+
+  virtual void force_restart (void) { restart = true; }
+
+  bool integration_ok (void) const { return ! integration_error; }
+
+  octave_idx_type integration_state (void) const { return istate; }
+
+  virtual std::string error_message (void) const = 0;
+
+protected:
+
+  ColumnVector x;
+
+  double t;
+
+  double stop_time;
+
+  bool stop_time_set;
+
+  bool restart;
+
+  bool integration_error;
+
+  octave_idx_type istate;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/base-lu.cc b/liboctave/base-lu.cc
new file mode 100644
index 0000000..968b4c7
--- /dev/null
+++ b/liboctave/base-lu.cc
@@ -0,0 +1,123 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "base-lu.h"
+
+template <class lu_type>
+lu_type
+base_lu <lu_type> :: L (void) const
+{
+  octave_idx_type a_nr = a_fact.rows ();
+  octave_idx_type a_nc = a_fact.cols ();
+  octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+  lu_type l (a_nr, mn, lu_elt_type (0.0));
+
+  for (octave_idx_type i = 0; i < a_nr; i++)
+    {
+      if (i < a_nc)
+	l.xelem (i, i) = 1.0;
+
+      for (octave_idx_type j = 0; j < (i < a_nc ? i : a_nc); j++)
+	l.xelem (i, j) = a_fact.xelem (i, j);
+    }
+
+  return l;
+}
+
+template <class lu_type>
+lu_type
+base_lu <lu_type> :: U (void) const
+{
+  octave_idx_type a_nr = a_fact.rows ();
+  octave_idx_type a_nc = a_fact.cols ();
+  octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+  lu_type u (mn, a_nc, lu_elt_type (0.0));
+
+  for (octave_idx_type i = 0; i < mn; i++)
+    {
+      for (octave_idx_type j = i; j < a_nc; j++)
+	u.xelem (i, j) = a_fact.xelem (i, j);
+    }
+
+  return u;
+}
+
+template <class lu_type>
+Array<octave_idx_type>
+base_lu <lu_type> :: getp (void) const
+{
+  octave_idx_type a_nr = a_fact.rows ();
+
+  Array<octave_idx_type> pvt (a_nr);
+
+  for (octave_idx_type i = 0; i < a_nr; i++)
+    pvt.xelem (i) = i;
+
+  for (octave_idx_type i = 0; i < ipvt.length(); i++)
+    {
+      octave_idx_type k = ipvt.xelem (i);
+
+      if (k != i)
+	{
+	  octave_idx_type tmp = pvt.xelem (k);
+	  pvt.xelem (k) = pvt.xelem (i);
+	  pvt.xelem (i) = tmp;
+	}
+    }
+
+  return pvt;
+}
+
+template <class lu_type>
+PermMatrix
+base_lu <lu_type> :: P (void) const
+{
+  return PermMatrix (getp (), false);
+}
+
+template <class lu_type>
+ColumnVector
+base_lu <lu_type> :: P_vec (void) const
+{
+  octave_idx_type a_nr = a_fact.rows ();
+
+  ColumnVector p (a_nr);
+
+  Array<octave_idx_type> pvt = getp ();
+
+  for (octave_idx_type i = 0; i < a_nr; i++)
+    p.xelem (i) = static_cast<double> (pvt.xelem (i) + 1);
+
+  return p;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/base-lu.h b/liboctave/base-lu.h
new file mode 100644
index 0000000..bac28f1
--- /dev/null
+++ b/liboctave/base-lu.h
@@ -0,0 +1,77 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_lu_h)
+#define octave_base_lu_h 1
+
+#include "MArray.h"
+#include "dColVector.h"
+#include "PermMatrix.h"
+
+template <class lu_type>
+class
+base_lu
+{
+public:
+
+  typedef typename lu_type::element_type lu_elt_type;
+
+  base_lu (void) { }
+
+  base_lu (const base_lu& a) : a_fact (a.a_fact), ipvt (a.ipvt) { }
+
+  base_lu& operator = (const base_lu& a)
+    {
+      if (this != &a)
+	{
+	  a_fact = a.a_fact;
+	  ipvt = a.ipvt;
+	}
+      return *this;
+    }
+
+  ~base_lu (void) { }
+
+  lu_type L (void) const;
+
+  lu_type U (void) const;
+
+  lu_type Y (void) const { return a_fact; }
+
+  PermMatrix P (void) const;
+
+  ColumnVector P_vec (void) const;
+
+protected:
+
+  Array<octave_idx_type> getp (void) const;
+  lu_type a_fact;
+  MArray<octave_idx_type> ipvt;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/base-min.h b/liboctave/base-min.h
new file mode 100644
index 0000000..b05a321
--- /dev/null
+++ b/liboctave/base-min.h
@@ -0,0 +1,130 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_min_h)
+#define octave_base_min_h 1
+
+#include "dColVector.h"
+
+class
+base_minimizer
+{
+public:
+
+  base_minimizer (void) : x () { }
+
+  base_minimizer (const ColumnVector& xx) : x (xx) { }
+
+  base_minimizer (const base_minimizer& a) : x (a.x) { }
+
+  virtual ~base_minimizer (void) { }
+
+  base_minimizer& operator = (const base_minimizer& a)
+    {
+      if (this != &a)
+	x = a.x;
+
+      return *this;
+    }
+
+  // Derived classes must provide a function to actually do the
+  // minimization.
+
+  virtual ColumnVector do_minimize (double& objf, octave_idx_type& inform,
+				    ColumnVector& lambda) = 0;
+
+  // Lots of ways to call the single function and optionally set and
+  // get additional information.
+
+  virtual ColumnVector minimize (void)
+    {
+      double objf;
+      octave_idx_type inform;
+      ColumnVector lambda;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (double& objf)
+    {
+      octave_idx_type inform;
+      ColumnVector lambda;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (double& objf, octave_idx_type& inform)
+    {
+      ColumnVector lambda;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (double& objf, octave_idx_type& inform,
+				 ColumnVector& lambda)
+    {
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (const ColumnVector& x0)
+    {
+      x = x0;
+      double objf;
+      octave_idx_type inform;
+      ColumnVector lambda;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (const ColumnVector& x0, double& objf)
+    {
+      x = x0;
+      octave_idx_type inform;
+      ColumnVector lambda;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (const ColumnVector& x0, double& objf,
+				 octave_idx_type& inform)
+    {
+      x = x0;
+      ColumnVector lambda;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  virtual ColumnVector minimize (const ColumnVector& x0, double& objf,
+				 octave_idx_type& inform, ColumnVector& lambda)
+    {
+      x = x0;
+      return do_minimize (objf, inform, lambda);
+    }
+
+  octave_idx_type size (void) const { return x.capacity (); }
+
+protected:
+
+  ColumnVector x;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/boolMatrix.cc b/liboctave/boolMatrix.cc
new file mode 100644
index 0000000..c5e3cbc
--- /dev/null
+++ b/liboctave/boolMatrix.cc
@@ -0,0 +1,108 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "lo-error.h"
+#include "str-vec.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "mx-op-defs.h"
+
+// boolMatrix class.
+
+bool
+boolMatrix::operator == (const boolMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return 0;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+boolMatrix::operator != (const boolMatrix& a) const
+{
+  return !(*this == a);
+}
+
+boolMatrix&
+boolMatrix::insert (const boolMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Array2<bool>::insert (a, r, c);
+  return *this;
+}
+
+// unary operations
+
+boolMatrix
+boolMatrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  boolMatrix b (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      b.elem (i, j) = ! elem (i, j);
+
+  return b;
+}
+
+// other operations
+
+boolMatrix
+boolMatrix::diag (octave_idx_type k) const
+{
+  return Array2<bool>::diag (k);
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+boolMatrix
+boolMatrix::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, bool> (*this, dim, mx_inline_all);
+}
+
+boolMatrix
+boolMatrix::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, bool> (*this, dim, mx_inline_any);
+}
+
+MM_CMP_OPS (boolMatrix, , boolMatrix, )
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/boolMatrix.h b/liboctave/boolMatrix.h
new file mode 100644
index 0000000..889c2fb
--- /dev/null
+++ b/liboctave/boolMatrix.h
@@ -0,0 +1,94 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_boolMatrix_int_h)
+#define octave_boolMatrix_int_h 1
+
+#include "Array2.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+class
+OCTAVE_API
+boolMatrix : public Array2<bool>
+{
+public:
+
+  boolMatrix (void) : Array2<bool> () { }
+  boolMatrix (octave_idx_type r, octave_idx_type c) : Array2<bool> (r, c) { }
+  boolMatrix (octave_idx_type r, octave_idx_type c, bool val) : Array2<bool> (r, c, val) { }
+  boolMatrix (const dim_vector& dv) : Array2<bool> (dv) { }
+  boolMatrix (const dim_vector& dv, bool val) : Array2<bool> (dv, val) { }
+  boolMatrix (const Array2<bool>& a) : Array2<bool> (a) { }
+  boolMatrix (const boolMatrix& a) : Array2<bool> (a) { }
+
+  boolMatrix& operator = (const boolMatrix& a)
+    {
+      Array2<bool>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const boolMatrix& a) const;
+  bool operator != (const boolMatrix& a) const;
+
+  boolMatrix transpose (void) const { return Array2<bool>::transpose (); }
+
+  // destructive insert/delete/reorder operations
+
+  boolMatrix& insert (const boolMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  // unary operations
+
+  boolMatrix operator ! (void) const;
+
+  // other operations
+
+  boolMatrix diag (octave_idx_type k = 0) const;
+
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+#if 0
+  // i/o
+
+  friend std::ostream& operator << (std::ostream& os, const Matrix& a);
+  friend std::istream& operator >> (std::istream& is, Matrix& a);
+#endif
+
+  static bool resize_fill_value (void) { return false; }
+
+private:
+
+  boolMatrix (bool *b, octave_idx_type r, octave_idx_type c) : Array2<bool> (b, r, c) { }
+};
+
+MM_CMP_OP_DECLS (boolMatrix, boolMatrix, OCTAVE_API)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/boolNDArray.cc b/liboctave/boolNDArray.cc
new file mode 100644
index 0000000..27c013a
--- /dev/null
+++ b/liboctave/boolNDArray.cc
@@ -0,0 +1,161 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array-util.h"
+#include "CNDArray.h"
+#include "mx-base.h"
+#include "lo-ieee.h"
+#include "mx-op-defs.h"
+
+// unary operations
+
+boolNDArray
+boolNDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (octave_idx_type i = 0; i < length (); i++)
+    b.elem (i) = ! elem (i);
+
+  return b;
+}
+
+// FIXME -- this is not quite the right thing.
+
+boolNDArray
+boolNDArray::all (int dim) const
+{
+  return do_mx_red_op<boolNDArray, bool> (*this, dim, mx_inline_all);
+}
+
+boolNDArray
+boolNDArray::any (int dim) const
+{
+  return do_mx_red_op<boolNDArray, bool> (*this, dim, mx_inline_any);
+}
+
+NDArray 
+boolNDArray::sum (int dim) const
+{
+  // NOTE: going via octave_idx_type is faster even though it requires a conversion.
+  return do_mx_red_op<Array<octave_idx_type> , bool> (*this, dim, mx_inline_count);
+}
+
+NDArray 
+boolNDArray::cumsum (int dim) const
+{
+  // NOTE: going via octave_idx_type is faster even though it requires a conversion.
+  return do_mx_cum_op<Array<octave_idx_type> , bool> (*this, dim, mx_inline_cumcount);
+}
+
+boolNDArray
+boolNDArray::concat (const boolNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+boolNDArray&
+boolNDArray::insert (const boolNDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<bool>::insert (a, r, c);
+  return *this;
+}
+
+boolNDArray&
+boolNDArray::insert (const boolNDArray& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<bool>::insert (a, ra_idx);
+  return *this;
+}
+
+
+
+boolMatrix
+boolNDArray::matrix_value (void) const
+{
+  boolMatrix retval;
+
+  int nd = ndims ();
+
+  switch (nd)
+    {
+    case 1:
+      retval = boolMatrix (Array2<bool> (*this, dimensions(0), 1));
+      break;
+
+    case 2:
+      retval = boolMatrix (Array2<bool> (*this, dimensions(0),
+					 dimensions(1)));
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("invalid conversion of boolNDArray to boolMatrix");
+      break;
+    }
+
+  return retval;
+}
+
+void
+boolNDArray::increment_index (Array<octave_idx_type>& ra_idx,
+			      const dim_vector& dimensions,
+			      int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+octave_idx_type
+boolNDArray::compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+boolNDArray
+boolNDArray::diag (octave_idx_type k) const
+{
+  return ArrayN<bool>::diag (k);
+}
+
+NDND_BOOL_OPS (boolNDArray, boolNDArray, false)
+NDND_CMP_OPS (boolNDArray, , boolNDArray, )
+
+NDS_BOOL_OPS (boolNDArray, bool, false)
+NDS_CMP_OPS (boolNDArray, , bool, )
+
+SND_BOOL_OPS (bool, boolNDArray, false)
+SND_CMP_OPS (bool, , boolNDArray, )
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/boolNDArray.h b/liboctave/boolNDArray.h
new file mode 100644
index 0000000..d0227dd
--- /dev/null
+++ b/liboctave/boolNDArray.h
@@ -0,0 +1,137 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_boolNDArray_h)
+#define octave_boolNDArray_h 1
+
+#include "ArrayN.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+#include "boolMatrix.h"
+
+class
+OCTAVE_API
+boolNDArray : public ArrayN<bool>
+{
+public:
+
+  boolNDArray (void) : ArrayN<bool> () { }
+
+  boolNDArray (const dim_vector& dv) : ArrayN<bool> (dv) { }
+
+  boolNDArray (const dim_vector& dv, const bool& val)
+    : ArrayN<bool> (dv, val) { }
+  
+  boolNDArray (const boolNDArray& a) : ArrayN<bool> (a) { }
+
+  boolNDArray (const boolMatrix& a) : ArrayN<bool> (a) { }
+
+  boolNDArray (const ArrayN<bool>& a) : ArrayN<bool> (a) { }
+
+  boolNDArray& operator = (const boolNDArray& a)
+    {
+      ArrayN<bool>::operator = (a);
+      return *this;
+    }
+
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
+  bool any_element_is_nan (void) const { return false; }
+
+  // FIXME -- this is not quite the right thing.
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+
+  NDArray sum (int dim = -1) const;
+  NDArray cumsum (int dim = -1) const;
+
+  boolNDArray concat (const boolNDArray& rb, const Array<octave_idx_type>& ra_idx);
+
+  boolNDArray& insert (const boolNDArray& a, octave_idx_type r, octave_idx_type c);
+  boolNDArray& insert (const boolNDArray& a, const Array<octave_idx_type>& ra_idx);
+
+  boolMatrix matrix_value (void) const;
+
+  boolNDArray squeeze (void) const { return ArrayN<bool>::squeeze (); }
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  // i/o
+
+  // friend std::ostream& operator << (std::ostream& os, const NDArray& a);
+  // friend std::istream& operator >> (std::istream& is, NDArray& a);
+
+  static bool resize_fill_value (void) { return false; }
+
+  //  bool all_elements_are_real (void) const;
+  //  bool all_integers (double& max_val, double& min_val) const;
+
+  octave_idx_type nnz (void) const
+    {
+      octave_idx_type retval = 0;
+
+      const bool *d = this->data ();
+
+      octave_idx_type nel = this->numel ();
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  if (d[i])
+	    retval++;
+	}
+
+      return retval;
+    }
+
+  boolNDArray diag (octave_idx_type k = 0) const;
+
+private:
+
+  boolNDArray (bool *d, dim_vector& dv) : ArrayN<bool> (d, dv) { }
+};
+
+NDND_BOOL_OP_DECLS (boolNDArray, boolNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (boolNDArray, boolNDArray, OCTAVE_API)
+
+NDS_BOOL_OP_DECLS (boolNDArray, bool, OCTAVE_API)
+NDS_CMP_OP_DECLS (boolNDArray, bool, OCTAVE_API)
+
+SND_BOOL_OP_DECLS (bool, boolNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (bool, boolNDArray, OCTAVE_API)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/boolSparse.cc b/liboctave/boolSparse.cc
new file mode 100644
index 0000000..671d8d1
--- /dev/null
+++ b/liboctave/boolSparse.cc
@@ -0,0 +1,282 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <vector>
+
+#include "config.h"
+#include "quit.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+
+#include "boolSparse.h"
+
+// SparseBoolMatrix class.
+
+bool
+SparseBoolMatrix::operator == (const SparseBoolMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nzmax ();
+  octave_idx_type nr_a = a.rows ();
+  octave_idx_type nc_a = a.cols ();
+  octave_idx_type nz_a = a.nzmax ();
+
+  if (nr != nr_a || nc != nc_a || nz != nz_a)
+    return false;
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    if (cidx(i) != a.cidx(i))
+	return false;
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    if (data(i) != a.data(i) || ridx(i) != a.ridx(i))
+      return false;
+
+  return true;
+}
+
+bool
+SparseBoolMatrix::operator != (const SparseBoolMatrix& a) const
+{
+  return !(*this == a);
+}
+
+SparseBoolMatrix&
+SparseBoolMatrix::insert (const SparseBoolMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Sparse<bool>::insert (a, r, c);
+  return *this;
+}
+
+SparseBoolMatrix&
+SparseBoolMatrix::insert (const SparseBoolMatrix& a, const Array<octave_idx_type>& indx)
+{
+  Sparse<bool>::insert (a, indx);
+  return *this;
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::concat (const SparseBoolMatrix& rb, const Array<octave_idx_type>& ra_idx)
+{
+  // Don't use numel to avoid all possiblity of an overflow
+  if (rb.rows () > 0 && rb.cols () > 0)
+    insert (rb, ra_idx(0), ra_idx(1));
+  return *this;
+}
+
+// unary operations
+
+SparseBoolMatrix
+SparseBoolMatrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz1 = nzmax ();
+  octave_idx_type nz2 = nr*nc - nz1;
+   
+  SparseBoolMatrix r (nr, nc, nz2);
+   
+  octave_idx_type ii = 0;
+  octave_idx_type jj = 0;
+  r.cidx (0) = 0;
+  for (octave_idx_type i = 0; i < nc; i++)
+    {
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (jj < cidx(i+1) && ridx(jj) == j)
+	    jj++;
+	  else
+	    {
+	      r.data(ii) = true;
+	      r.ridx(ii++) = j;
+	    }
+	}
+      r.cidx (i+1) = ii;
+    }
+
+  return r;
+}
+
+// other operations
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+SparseBoolMatrix
+SparseBoolMatrix::all (int dim) const
+{
+  SPARSE_ALL_OP (dim);
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::any (int dim) const
+{
+  SPARSE_ANY_OP (dim);
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::diag (octave_idx_type k) const
+{
+  return Sparse<bool>::diag (k);
+}
+
+boolMatrix
+SparseBoolMatrix::matrix_value (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  boolMatrix retval (nr, nc, false);
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+      retval.elem (ridx(i), j) = data (i);
+
+  return retval;
+}
+
+std::ostream&
+operator << (std::ostream& os, const SparseBoolMatrix& a)
+{
+  octave_idx_type nc = a.cols ();
+
+   // add one to the printed indices to go from
+   //  zero-based to one-based arrays
+   for (octave_idx_type j = 0; j < nc; j++)  
+     {
+       OCTAVE_QUIT;
+       for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	 os << a.ridx(i) + 1 << " "  << j + 1 << " " << a.data(i) << "\n";
+     }
+   
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, SparseBoolMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type nz = a.nzmax ();
+
+  if (nr > 0 && nc > 0)
+    {
+      octave_idx_type itmp, jtmp, jold = 0;
+      bool tmp;
+      octave_idx_type ii = 0;
+       
+      a.cidx (0) = 0;
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  is >> itmp;
+	  itmp--;
+	  is >> jtmp;
+	  jtmp--;
+	  is >> tmp;
+	  if (is)
+	    {
+	      if (jold != jtmp)
+		{
+		  for (octave_idx_type j = jold; j < jtmp; j++)
+		    a.cidx(j+1) = ii;
+		  
+		  jold = jtmp;
+		}
+	      a.data (ii) = tmp;
+	      a.ridx (ii++) = itmp;
+	    }
+	  else
+	    goto done;
+	}
+
+      for (octave_idx_type j = jold; j < nc; j++)
+	a.cidx(j+1) = ii;
+    }
+
+ done:
+
+  return is;
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::squeeze (void) const 
+{ 
+  return Sparse<bool>::squeeze (); 
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::index (idx_vector& i, int resize_ok) const 
+{ 
+  return Sparse<bool>::index (i, resize_ok); 
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::index (idx_vector& i, idx_vector& j, int resize_ok) const 
+{ 
+  return Sparse<bool>::index (i, j, resize_ok); 
+}
+  
+SparseBoolMatrix
+SparseBoolMatrix::index (Array<idx_vector>& ra_idx, int resize_ok) const 
+{ 
+  return Sparse<bool>::index (ra_idx, resize_ok); 
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::reshape (const dim_vector& new_dims) const
+{
+  return Sparse<bool>::reshape (new_dims);
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::permute (const Array<octave_idx_type>& vec, bool inv) const
+{
+  return Sparse<bool>::permute (vec, inv);
+}
+
+SparseBoolMatrix
+SparseBoolMatrix::ipermute (const Array<octave_idx_type>& vec) const
+{
+  return Sparse<bool>::ipermute (vec);
+}
+
+SPARSE_SMS_EQNE_OPS (SparseBoolMatrix, false, , bool, false, )
+SPARSE_SMS_BOOL_OPS (SparseBoolMatrix, bool, false)
+
+SPARSE_SSM_EQNE_OPS (bool, false, , SparseBoolMatrix, false, )
+SPARSE_SSM_BOOL_OPS (bool, SparseBoolMatrix, false)
+
+SPARSE_SMSM_EQNE_OPS (SparseBoolMatrix, false, , SparseBoolMatrix, false, )
+SPARSE_SMSM_BOOL_OPS (SparseBoolMatrix, SparseBoolMatrix, false)
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/boolSparse.h b/liboctave/boolSparse.h
new file mode 100644
index 0000000..b6179aa
--- /dev/null
+++ b/liboctave/boolSparse.h
@@ -0,0 +1,139 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_boolSparse_h)
+#define octave_boolSparse_h 1
+
+#include "Sparse.h"
+#include "MSparse-defs.h"
+#include "Sparse-op-defs.h"
+
+class
+OCTAVE_API
+SparseBoolMatrix : public Sparse<bool>
+{
+public:
+
+  SparseBoolMatrix (void) : Sparse<bool> () { }
+
+  SparseBoolMatrix (octave_idx_type r, octave_idx_type c) : Sparse<bool> (r, c) { }
+
+  explicit SparseBoolMatrix (octave_idx_type r, octave_idx_type c, bool val) 
+    : Sparse<bool> (r, c, val) { }
+
+  SparseBoolMatrix (const dim_vector& dv, octave_idx_type nz = 0) : 
+    Sparse<bool> (dv, nz) { }
+
+  SparseBoolMatrix (const Sparse<bool>& a) : Sparse<bool> (a) { }
+
+  SparseBoolMatrix (const SparseBoolMatrix& a) : Sparse<bool> (a) { }
+
+  SparseBoolMatrix (const SparseBoolMatrix& a, const dim_vector& dv) 
+    : Sparse<bool> (a, dv) { }
+
+  explicit SparseBoolMatrix (const boolMatrix& a) : Sparse<bool> (a) { }
+
+  explicit SparseBoolMatrix (const boolNDArray& a) : Sparse<bool> (a) { }
+
+  explicit SparseBoolMatrix (const Array<bool> a, const Array<octave_idx_type>& r, 
+			     const Array<octave_idx_type>& c, octave_idx_type nr = -1, 
+			     octave_idx_type nc = -1, bool sum_terms = true)
+    : Sparse<bool> (a, r, c, nr, nc, sum_terms) { }
+
+  explicit SparseBoolMatrix (const Array<bool> a, const Array<double>& r, 
+			     const Array<double>& c, octave_idx_type nr = -1, 
+			     octave_idx_type nc = -1, bool sum_terms = true)
+    : Sparse<bool> (a, r, c, nr, nc, sum_terms) { }
+
+  SparseBoolMatrix (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : Sparse<bool> (r, c, num_nz) { }
+
+  SparseBoolMatrix& operator = (const SparseBoolMatrix& a)
+    {
+      Sparse<bool>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const SparseBoolMatrix& a) const;
+  bool operator != (const SparseBoolMatrix& a) const;
+
+  SparseBoolMatrix transpose (void) const 
+    { return Sparse<bool>::transpose (); }
+
+  // destructive insert/delete/reorder operations
+
+  SparseBoolMatrix& insert (const SparseBoolMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  SparseBoolMatrix& insert (const SparseBoolMatrix& a, const Array<octave_idx_type>& indx);
+
+  SparseBoolMatrix concat (const SparseBoolMatrix& rb, 
+			   const Array<octave_idx_type>& ra_idx);
+
+  SparseBoolMatrix diag (octave_idx_type k = 0) const;
+
+  boolMatrix matrix_value (void) const;
+
+  SparseBoolMatrix squeeze (void) const;
+
+  SparseBoolMatrix index (idx_vector& i, int resize_ok) const;
+
+  SparseBoolMatrix index (idx_vector& i, idx_vector& j, int resize_ok) const;
+  
+  SparseBoolMatrix index (Array<idx_vector>& ra_idx, int resize_ok) const;
+
+  SparseBoolMatrix reshape (const dim_vector& new_dims) const;
+
+  SparseBoolMatrix permute (const Array<octave_idx_type>& vec, bool inv = false) const;
+
+  SparseBoolMatrix ipermute (const Array<octave_idx_type>& vec) const;
+
+  // unary operations
+
+  SparseBoolMatrix operator ! (void) const;
+
+  // other operations
+
+  SparseBoolMatrix all (int dim = -1) const;
+  SparseBoolMatrix any (int dim = -1) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const SparseBoolMatrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, SparseBoolMatrix& a);
+};
+
+SPARSE_SMS_EQNE_OP_DECLS (SparseBoolMatrix, bool, OCTAVE_API)
+SPARSE_SMS_BOOL_OP_DECLS (SparseBoolMatrix, bool, OCTAVE_API)
+
+SPARSE_SSM_EQNE_OP_DECLS (bool, SparseBoolMatrix, OCTAVE_API)
+SPARSE_SSM_BOOL_OP_DECLS (bool, SparseBoolMatrix, OCTAVE_API)
+
+SPARSE_SMSM_EQNE_OP_DECLS (SparseBoolMatrix, SparseBoolMatrix, OCTAVE_API)
+SPARSE_SMSM_BOOL_OP_DECLS (SparseBoolMatrix, SparseBoolMatrix, OCTAVE_API)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/byte-swap.h b/liboctave/byte-swap.h
new file mode 100644
index 0000000..b46198b
--- /dev/null
+++ b/liboctave/byte-swap.h
@@ -0,0 +1,103 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_byte_swap_h)
+#define octave_byte_swap_h 1
+
+// FIXME -- not sure these volatile qualifiers are really
+// needed or appropriate here.
+
+static inline void
+swap_bytes (volatile void *ptr, unsigned int i, unsigned int j)
+{
+  volatile char *t = static_cast<volatile char *> (ptr);
+
+  char tmp = t[i];
+  t[i] = t[j];
+  t[j] = tmp;
+}
+
+template <int n>
+void
+swap_bytes (volatile void *ptr)
+{
+  for (int i = 0; i < n/2; i++)
+    swap_bytes (ptr, i, n-1-i);
+}
+
+template <>
+inline void
+swap_bytes <1> (volatile void *)
+{
+}
+
+template <>
+inline void
+swap_bytes <2> (volatile void *ptr)
+{
+  swap_bytes (ptr, 0, 1);
+}
+
+template <>
+inline void
+swap_bytes <4> (volatile void *ptr)
+{
+  swap_bytes (ptr, 0, 3);
+  swap_bytes (ptr, 1, 2);
+}
+
+template <>
+inline void
+swap_bytes <8> (volatile void *ptr)
+{
+  swap_bytes (ptr, 0, 7);
+  swap_bytes (ptr, 1, 6);
+  swap_bytes (ptr, 2, 5);
+  swap_bytes (ptr, 3, 4);
+}
+
+template <int n>
+void
+swap_bytes (volatile void *ptr, int len)
+{
+  volatile char *t = static_cast<volatile char *> (ptr);
+
+  for (int i = 0; i < len; i++)
+    {
+      swap_bytes<n> (t);
+      t += n;
+    }
+}
+
+template <>
+inline void
+swap_bytes<1> (volatile void *, int)
+{
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/chMatrix.cc b/liboctave/chMatrix.cc
new file mode 100644
index 0000000..37ba212
--- /dev/null
+++ b/liboctave/chMatrix.cc
@@ -0,0 +1,230 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstring>
+
+#include <iostream>
+#include <string>
+
+#include "lo-error.h"
+#include "str-vec.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "mx-op-defs.h"
+
+// charMatrix class.
+
+charMatrix::charMatrix (char c)
+  : MArray2<char> ()
+{
+  octave_idx_type nc = 1;
+  octave_idx_type nr = 1;
+
+  resize (nr, nc);
+
+  elem (0, 0) = c;
+}
+
+charMatrix::charMatrix (const char *s)
+  : MArray2<char> ()
+{
+  octave_idx_type nc = s ? strlen (s) : 0;
+  octave_idx_type nr = s && nc > 0 ? 1 : 0;
+
+  resize (nr, nc);
+
+  for (octave_idx_type i = 0; i < nc; i++)
+    elem (0, i) = s[i];
+}
+
+charMatrix::charMatrix (const std::string& s)
+  : MArray2<char> ()
+{
+  octave_idx_type nc = s.length ();
+  octave_idx_type nr = nc > 0 ? 1 : 0;
+
+  resize (nr, nc);
+
+  for (octave_idx_type i = 0; i < nc; i++)
+    elem (0, i) = s[i];
+}
+
+charMatrix::charMatrix (const string_vector& s)
+  : MArray2<char> (s.length (), s.max_length (), 0)
+{
+  octave_idx_type nr = rows ();
+
+  for (octave_idx_type i = 0; i < nr; i++)
+    {
+      const std::string si = s(i);
+      octave_idx_type nc = si.length ();
+      for (octave_idx_type j = 0; j < nc; j++)
+	elem (i, j) = si[j];
+    }
+}
+
+bool
+charMatrix::operator == (const charMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return 0;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+charMatrix::operator != (const charMatrix& a) const
+{
+  return !(*this == a);
+}
+
+charMatrix&
+charMatrix::insert (const char *s, octave_idx_type r, octave_idx_type c)
+{
+  if (s)
+    {
+      octave_idx_type s_len = strlen (s);
+
+      if (r < 0 || r >= rows () || c < 0 || c + s_len - 1 > cols ())
+	{
+	  (*current_liboctave_error_handler) ("range error for insert");
+	  return *this;
+	}
+
+      for (octave_idx_type i = 0; i < s_len; i++)
+	elem (r, c+i) = s[i];
+    }
+  return *this;
+}
+
+charMatrix&
+charMatrix::insert (const charMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Array2<char>::insert (a, r, c);
+  return *this;
+}
+
+std::string
+charMatrix::row_as_string (octave_idx_type r, bool strip_ws, bool raw) const 
+{
+  std::string retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r == 0 && nr == 0 && nc == 0)
+    return retval;
+
+  if (r < 0 || r >= nr)
+    {
+      (*current_liboctave_error_handler) ("range error for row_as_string");
+      return retval;
+    }
+
+  retval.resize (nc, '\0');
+
+  for (octave_idx_type i = 0; i < nc; i++)
+    retval[i] = elem (r, i);
+
+  if (! raw)
+    {
+      if (strip_ws)
+	{
+	  while (--nc >= 0)
+	    {
+	      char c = retval[nc];
+	      if (c && c != ' ')
+		break;
+	    }
+	}
+      else
+	{
+	  while (--nc >= 0)
+	    if (retval[nc])
+	      break;
+	}
+
+      retval.resize (nc+1);
+    }
+
+  return retval;
+}
+
+charMatrix
+charMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  charMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.elem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+charMatrix
+charMatrix::diag (octave_idx_type k) const
+{
+  return MArray2<char>::diag (k);
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+boolMatrix
+charMatrix::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_all);
+}
+
+boolMatrix
+charMatrix::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_any);
+}
+
+MS_CMP_OPS(charMatrix, , char, )
+MS_BOOL_OPS(charMatrix, char, 0)
+
+SM_CMP_OPS(char, , charMatrix, )
+SM_BOOL_OPS(char, charMatrix, 0)
+
+MM_CMP_OPS(charMatrix, , charMatrix, )
+MM_BOOL_OPS(charMatrix, charMatrix, 0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/chMatrix.h b/liboctave/chMatrix.h
new file mode 100644
index 0000000..35d8890
--- /dev/null
+++ b/liboctave/chMatrix.h
@@ -0,0 +1,113 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_chMatrix_int_h)
+#define octave_chMatrix_int_h 1
+
+#include <string>
+
+#include "MArray2.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+#include "str-vec.h"
+
+class
+OCTAVE_API
+charMatrix : public MArray2<char>
+{
+friend class ComplexMatrix;
+
+public:
+
+  charMatrix (void) : MArray2<char> () { }
+  charMatrix (octave_idx_type r, octave_idx_type c) : MArray2<char> (r, c) { }
+  charMatrix (octave_idx_type r, octave_idx_type c, char val) : MArray2<char> (r, c, val) { }
+  charMatrix (const dim_vector& dv) : MArray2<char> (dv) { }
+  charMatrix (const dim_vector& dv, char val) : MArray2<char> (dv, val) { }
+  charMatrix (const MArray2<char>& a) : MArray2<char> (a) { }
+  charMatrix (const charMatrix& a) : MArray2<char> (a) { }
+  charMatrix (char c);
+  charMatrix (const char *s);
+  charMatrix (const std::string& s);
+  charMatrix (const string_vector& s);
+
+  charMatrix& operator = (const charMatrix& a)
+    {
+      MArray2<char>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const charMatrix& a) const;
+  bool operator != (const charMatrix& a) const;
+
+  charMatrix transpose (void) const { return MArray2<char>::transpose (); }
+
+  // destructive insert/delete/reorder operations
+
+  charMatrix& insert (const char *s, octave_idx_type r, octave_idx_type c);
+  charMatrix& insert (const charMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  std::string row_as_string (octave_idx_type, bool strip_ws = false, bool raw = false) const;
+
+  // resize is the destructive equivalent for this one
+
+  charMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  charMatrix diag (octave_idx_type k = 0) const;
+
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+#if 0
+  // i/o
+
+  friend std::ostream& operator << (std::ostream& os, const Matrix& a);
+  friend std::istream& operator >> (std::istream& is, Matrix& a);
+#endif
+
+  static char resize_fill_value (void) { return '\0'; }
+
+private:
+
+  charMatrix (char *ch, octave_idx_type r, octave_idx_type c) : MArray2<char> (ch, r, c) { }
+};
+
+MS_CMP_OP_DECLS (charMatrix, char, OCTAVE_API)
+MS_BOOL_OP_DECLS (charMatrix, char, OCTAVE_API)
+
+SM_CMP_OP_DECLS (char, charMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (char, charMatrix, OCTAVE_API)
+
+MM_CMP_OP_DECLS (charMatrix, charMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (charMatrix, charMatrix, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArray2, charMatrix, char)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/chNDArray.cc b/liboctave/chNDArray.cc
new file mode 100644
index 0000000..038a890
--- /dev/null
+++ b/liboctave/chNDArray.cc
@@ -0,0 +1,222 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array-util.h"
+#include "chNDArray.h"
+#include "mx-base.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "mx-op-defs.h"
+
+// FIXME -- this is not quite the right thing.
+
+boolNDArray
+charNDArray::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_all);
+}
+
+boolNDArray
+charNDArray::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_any);
+}
+
+charNDArray
+charNDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+charNDArray
+charNDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  charNDArray tmp (rb.dims ());
+  octave_idx_type nel = rb.numel ();
+
+  if (rb.numel () == 0)
+    return *this;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double d = rb.elem (i);
+
+      if (xisnan (d))
+	{
+	  (*current_liboctave_error_handler)
+	    ("invalid conversion from NaN to character");
+	  return *this;
+	}
+      else
+	{
+	  octave_idx_type ival = NINTbig (d);
+
+	  if (ival < 0 || ival > UCHAR_MAX)
+	    // FIXME -- is there something
+	    // better we could do? Should we warn the user?
+	    ival = 0;
+
+	  tmp.elem (i) = static_cast<char>(ival);
+	}
+    }
+
+  insert (tmp, ra_idx);
+  return *this;
+}
+
+charNDArray&
+charNDArray::insert (const charNDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<char>::insert (a, r, c);
+  return *this;
+}
+
+charNDArray&
+charNDArray::insert (const charNDArray& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<char>::insert (a, ra_idx);
+  return *this;
+}
+
+charMatrix
+charNDArray::matrix_value (void) const
+{
+  charMatrix retval;
+
+  int nd = ndims ();
+
+  switch (nd)
+    {
+    case 1:
+      retval = charMatrix (Array2<char> (*this, dimensions(0), 1));
+      break;
+
+    case 2:
+      retval = charMatrix (Array2<char> (*this, dimensions(0),
+					       dimensions(1)));
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("invalid conversion of charNDArray to charMatrix");
+      break;
+    }
+
+  return retval;
+}
+
+void
+charNDArray::increment_index (Array<octave_idx_type>& ra_idx,
+			      const dim_vector& dimensions,
+			      int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+octave_idx_type 
+charNDArray::compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+charNDArray
+charNDArray::diag (octave_idx_type k) const
+{
+  return MArrayN<char>::diag (k);
+}
+
+boolNDArray
+charNDArray::bmap (mapper fcn) const
+{
+  octave_idx_type len = length ();
+  const char *m = fortran_vec();
+  boolNDArray result (dims ());
+  bool *p = result.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      p[i] = bool (fcn (m[i]));
+    }
+
+  return result;
+}
+
+NDArray
+charNDArray::dmap (mapper fcn) const
+{
+  octave_idx_type len = length ();
+  const char *m = fortran_vec();
+  NDArray result (dims ());
+  double *p = result.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      p[i] = fcn (m[i]);
+    }
+
+  return result;
+}
+
+charNDArray
+charNDArray::smap (mapper fcn) const
+{
+  octave_idx_type len = length ();
+  const char *m = fortran_vec();
+  charNDArray result (dims ());
+  char *p = result.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      p[i] = fcn (m[i]);
+    }
+
+  return result;
+}
+
+NDS_CMP_OPS(charNDArray, , char, )
+NDS_BOOL_OPS(charNDArray, char, 0)
+
+SND_CMP_OPS(char, , charNDArray, )
+SND_BOOL_OPS(char, charNDArray, 0)
+
+NDND_CMP_OPS(charNDArray, , charNDArray, )
+NDND_BOOL_OPS(charNDArray, charNDArray, 0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/chNDArray.h b/liboctave/chNDArray.h
new file mode 100644
index 0000000..2bfa1ae
--- /dev/null
+++ b/liboctave/chNDArray.h
@@ -0,0 +1,123 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_charNDArray_h)
+#define octave_charNDArray_h 1
+
+#include "MArrayN.h"
+#include "chMatrix.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+class
+OCTAVE_API
+charNDArray : public MArrayN<char>
+{
+public:
+
+  charNDArray (void) : MArrayN<char> () { }
+
+  charNDArray (const dim_vector& dv) : MArrayN<char> (dv) { }
+
+  charNDArray (const dim_vector& dv, char val) : MArrayN<char> (dv, val) { }
+  
+  charNDArray (const charNDArray& a) : MArrayN<char> (a) { }
+
+  charNDArray (const charMatrix& a) : MArrayN<char> (a) { }
+
+  charNDArray (char c) : MArrayN<char> (charMatrix (c)) { }
+
+  charNDArray (const char *s) : MArrayN<char> (charMatrix (s)) { }
+
+  charNDArray (const std::string& s) : MArrayN<char> (charMatrix (s)) { }
+
+  charNDArray (const string_vector& s) : MArrayN<char> (charMatrix (s)) { }
+
+  charNDArray (const ArrayN<char>& a) : MArrayN<char> (a) { }
+
+  charNDArray& operator = (const charNDArray& a)
+    {
+      MArrayN<char>::operator = (a);
+      return *this;
+    }
+
+  bool any_element_is_nan (void) const { return false; }
+
+  // FIXME -- this is not quite the right thing.
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+  charNDArray concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx);
+  charNDArray concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx);
+
+  charNDArray& insert (const charNDArray& a, octave_idx_type r, octave_idx_type c);
+  charNDArray& insert (const charNDArray& a, const Array<octave_idx_type>& ra_idx);
+  
+  charMatrix matrix_value (void) const;
+
+  charNDArray squeeze (void) const { return ArrayN<char>::squeeze (); }
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  // i/o
+
+  // friend std::ostream& operator << (std::ostream& os, const charNDArray& a);
+  // friend std::istream& operator >> (std::istream& is, charNDArray& a);
+
+  static char resize_fill_value (void) { return '\0'; }
+
+  charNDArray diag (octave_idx_type k = 0) const;
+
+  typedef int (*mapper) (int);
+  boolNDArray bmap (mapper fcn) const;
+  NDArray dmap (mapper fcn) const;
+  charNDArray smap (mapper fcn) const;
+
+private:
+
+  charNDArray (char *d, dim_vector& dv) : MArrayN<char> (d, dv) { }
+};
+
+NDS_CMP_OP_DECLS (charNDArray, char, OCTAVE_API)
+NDS_BOOL_OP_DECLS (charNDArray, char, OCTAVE_API)
+
+SND_CMP_OP_DECLS (char, charNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (char, charNDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (charNDArray, charNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (charNDArray, charNDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, charNDArray, char)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/cmd-edit.cc b/liboctave/cmd-edit.cc
new file mode 100644
index 0000000..0991569
--- /dev/null
+++ b/liboctave/cmd-edit.cc
@@ -0,0 +1,1538 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+#include <cstring>
+
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "quit.h"
+
+#include "cmd-edit.h"
+#include "cmd-hist.h"
+#include "file-ops.h"
+#include "lo-error.h"
+#include "lo-utils.h"
+#include "oct-env.h"
+#include "oct-mutex.h"
+#include "oct-time.h"
+
+command_editor *command_editor::instance = 0;
+
+std::set<command_editor::startup_hook_fcn> command_editor::startup_hook_set;
+
+std::set<command_editor::event_hook_fcn> command_editor::event_hook_set;
+
+static octave_mutex event_hook_lock;
+
+#if defined (USE_READLINE)
+
+#include <cstdio>
+#include <cstdlib>
+
+#include "oct-rl-edit.h"
+
+class
+gnu_readline : public command_editor
+{
+public:
+
+  typedef command_editor::startup_hook_fcn startup_hook_fcn;
+
+  typedef command_editor::event_hook_fcn event_hook_fcn;
+
+  typedef command_editor::completion_fcn completion_fcn;
+
+  gnu_readline (void);
+
+  ~gnu_readline (void) { }
+
+  void do_set_name (const std::string& n);
+
+  std::string do_readline (const std::string& prompt, bool& eof);
+
+  void do_set_input_stream (FILE *f);
+
+  FILE *do_get_input_stream (void);
+
+  void do_set_output_stream (FILE *f);
+
+  FILE *do_get_output_stream (void);
+
+  int do_terminal_rows (void);
+
+  int do_terminal_cols (void);
+
+  void do_clear_screen (void);
+
+  void do_resize_terminal (void);
+
+  std::string newline_chars (void);
+
+  void do_restore_terminal_state (void);
+
+  void do_blink_matching_paren (bool flag);
+
+  void do_set_basic_word_break_characters (const std::string& s);
+
+  void do_set_completer_word_break_characters (const std::string& s);
+
+  void do_set_basic_quote_characters (const std::string& s);
+
+  void do_set_filename_quote_characters (const std::string& s);
+
+  void do_set_completer_quote_characters (const std::string& s);
+
+  void do_set_completion_append_character (char c);
+
+  void do_set_completion_function (completion_fcn f);
+
+  void do_set_quoting_function (quoting_fcn f);
+
+  void do_set_dequoting_function (dequoting_fcn f);
+
+  void do_set_char_is_quoted_function (char_is_quoted_fcn f);
+
+  void do_set_user_accept_line_function (user_accept_line_fcn f);
+
+  completion_fcn do_get_completion_function (void) const;
+
+  quoting_fcn do_get_quoting_function (void) const;
+
+  dequoting_fcn do_get_dequoting_function (void) const;
+
+  char_is_quoted_fcn do_get_char_is_quoted_function (void) const;
+
+  user_accept_line_fcn do_get_user_accept_line_function (void) const;
+
+  string_vector
+  do_generate_filename_completions (const std::string& text);
+
+  void do_insert_text (const std::string& text);
+
+  void do_newline (void);
+
+  void do_accept_line (void);
+
+  void do_clear_undo_list (void);
+
+  void set_startup_hook (startup_hook_fcn f);
+
+  void restore_startup_hook (void);
+
+  void set_event_hook (event_hook_fcn f);
+
+  void restore_event_hook (void);
+
+  void do_restore_event_hook (void);
+
+  void do_read_init_file (const std::string& file);
+
+  void do_re_read_init_file (void);
+
+  bool do_filename_completion_desired (bool);
+
+  bool do_filename_quoting_desired (bool);
+
+  static int operate_and_get_next (int, int);
+
+  static int history_search_backward (int, int);
+
+  static int history_search_forward (int, int);
+
+private:
+
+  startup_hook_fcn previous_startup_hook;
+
+  event_hook_fcn previous_event_hook;
+
+  completion_fcn completion_function;
+
+  quoting_fcn quoting_function;
+
+  dequoting_fcn dequoting_function;
+
+  char_is_quoted_fcn char_is_quoted_function;
+
+  user_accept_line_fcn user_accept_line_function;
+
+  static char *command_generator (const char *text, int state);
+
+  static char *command_quoter (char *text, int match_type, char *quote_pointer);
+  static char *command_dequoter (char *text, int match_type);
+
+  static int command_char_is_quoted (char *text, int index);
+
+  static int command_accept_line (int count, int key);
+
+  static char **command_completer (const char *text, int start, int end);
+};
+
+gnu_readline::gnu_readline ()
+  : command_editor (), previous_startup_hook (0),
+    previous_event_hook (0), completion_function (0),
+    quoting_function (0), dequoting_function (0),
+    char_is_quoted_function (0), user_accept_line_function (0)
+{
+  // FIXME -- need interface to rl_add_defun, rl_initialize, and
+  // a function to set rl_terminal_name
+
+  std::string term = octave_env::getenv ("TERM");
+
+  octave_rl_set_terminal_name (term.c_str ());
+
+  octave_rl_initialize ();
+
+  do_blink_matching_paren (true);
+
+  // Bind operate-and-get-next.
+
+  octave_rl_add_defun ("operate-and-get-next",
+		       gnu_readline::operate_and_get_next,
+		       octave_rl_ctrl ('O'));
+
+  // And the history search functions.
+
+  octave_rl_add_defun ("history-search-backward",
+		       gnu_readline::history_search_backward,
+		       octave_rl_meta ('P'));
+
+  octave_rl_add_defun ("history-search-forward",
+		       gnu_readline::history_search_forward,
+		       octave_rl_meta ('N'));
+}
+
+void
+gnu_readline::do_set_name (const std::string& nm)
+{
+  ::octave_rl_set_name (nm.c_str ());
+}
+
+std::string
+gnu_readline::do_readline (const std::string& prompt, bool& eof)
+{
+  std::string retval;
+
+  eof = false;
+
+  char *line = 0;
+
+  const char *p = prompt.c_str ();
+
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  line = ::octave_rl_readline (p);
+
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  if (line)
+    {
+      retval = line;
+
+      free (line);
+    }
+  else
+    eof = true;
+
+  return retval;
+}
+
+void
+gnu_readline::do_set_input_stream (FILE *f)
+{
+  ::octave_rl_set_input_stream (f);
+}
+
+FILE *
+gnu_readline::do_get_input_stream (void)
+{
+  return ::octave_rl_get_input_stream ();
+}
+
+void
+gnu_readline::do_set_output_stream (FILE *f)
+{
+  ::octave_rl_set_output_stream (f);
+}
+
+FILE *
+gnu_readline::do_get_output_stream (void)
+{
+  return ::octave_rl_get_output_stream ();
+}
+
+// GNU readline handles SIGWINCH, so these values have a good chance
+// of being correct even if the window changes size (they may be
+// wrong if, for example, the luser changes the window size while the
+// pager is running, and the signal is handled by the pager instead of
+// us.
+
+int
+gnu_readline::do_terminal_rows (void)
+{
+  int sh = ::octave_rl_screen_height ();
+
+  return sh > 0 ? sh : 24;
+}
+
+int
+gnu_readline::do_terminal_cols (void)
+{
+  int sw = ::octave_rl_screen_width ();
+
+  return sw > 0 ? sw : 80;
+}
+
+void
+gnu_readline::do_clear_screen (void)
+{
+  ::octave_rl_clear_screen ();
+}
+
+void
+gnu_readline::do_resize_terminal (void)
+{
+  ::octave_rl_resize_terminal ();
+}
+
+std::string
+gnu_readline::newline_chars (void)
+{
+  return "\r\n";
+}
+
+void
+gnu_readline::do_restore_terminal_state (void)
+{
+  ::octave_rl_restore_terminal_state ();
+}
+
+void
+gnu_readline::do_blink_matching_paren (bool flag)
+{
+  ::octave_rl_enable_paren_matching (flag ? 1 : 0);
+}
+
+void
+gnu_readline::do_set_basic_word_break_characters (const std::string& s)
+{
+  ::octave_rl_set_basic_word_break_characters (s.c_str ());
+}
+
+void
+gnu_readline::do_set_completer_word_break_characters (const std::string& s)
+{
+  ::octave_rl_set_completer_word_break_characters (s.c_str ());
+}
+
+void
+gnu_readline::do_set_basic_quote_characters (const std::string& s)
+{
+  ::octave_rl_set_basic_quote_characters (s.c_str ());
+}
+
+void
+gnu_readline::do_set_filename_quote_characters (const std::string& s)
+{
+  ::octave_rl_set_filename_quote_characters (s.c_str ());
+}
+
+void
+gnu_readline::do_set_completer_quote_characters (const std::string& s)
+{
+  ::octave_rl_set_completer_quote_characters (s.c_str ());
+}
+
+void
+gnu_readline::do_set_completion_append_character (char c)
+{
+  ::octave_rl_set_completion_append_character (c);
+}
+
+void
+gnu_readline::do_set_completion_function (completion_fcn f)
+{
+  completion_function = f;
+
+  rl_attempted_completion_fcn_ptr fp
+    = f ? gnu_readline::command_completer : 0;
+
+  ::octave_rl_set_completion_function (fp);
+}
+
+void
+gnu_readline::do_set_quoting_function (quoting_fcn f)
+{
+  quoting_function = f;
+
+  rl_quoting_fcn_ptr fp
+    = f ? gnu_readline::command_quoter : 0;
+
+  ::octave_rl_set_quoting_function (fp);
+}
+
+void
+gnu_readline::do_set_dequoting_function (dequoting_fcn f)
+{
+  dequoting_function = f;
+
+  rl_dequoting_fcn_ptr fp
+    = f ? gnu_readline::command_dequoter : 0;
+
+  ::octave_rl_set_dequoting_function (fp);
+}
+
+void
+gnu_readline::do_set_char_is_quoted_function (char_is_quoted_fcn f)
+{
+  char_is_quoted_function = f;
+
+  rl_char_is_quoted_fcn_ptr fp
+    = f ? gnu_readline::command_char_is_quoted : 0;
+
+  ::octave_rl_set_char_is_quoted_function (fp);
+}
+
+void
+gnu_readline::do_set_user_accept_line_function (user_accept_line_fcn f)
+{
+  user_accept_line_function = f;
+
+  if (f)
+    octave_rl_add_defun ("accept-line", gnu_readline::command_accept_line, 
+			 ::octave_rl_ctrl ('M'));
+  else
+    octave_rl_add_defun ("accept-line", ::octave_rl_newline,
+			 ::octave_rl_ctrl ('M'));
+}
+
+gnu_readline::completion_fcn
+gnu_readline::do_get_completion_function (void) const
+{
+  return completion_function;
+}
+
+gnu_readline::quoting_fcn
+gnu_readline::do_get_quoting_function (void) const
+{
+  return quoting_function;
+}
+
+gnu_readline::dequoting_fcn
+gnu_readline::do_get_dequoting_function (void) const
+{
+  return dequoting_function;
+}
+
+gnu_readline::char_is_quoted_fcn
+gnu_readline::do_get_char_is_quoted_function (void) const
+{
+  return char_is_quoted_function;
+}
+
+gnu_readline::user_accept_line_fcn
+gnu_readline::do_get_user_accept_line_function (void) const
+{
+  return user_accept_line_function;
+}
+
+string_vector
+gnu_readline::do_generate_filename_completions (const std::string& text)
+{
+  string_vector retval;
+
+  int n = 0;
+  int count = 0;
+
+  char *fn = 0;
+
+  while (1)
+    {
+      fn = ::octave_rl_filename_completion_function (text.c_str (), count);
+
+      if (fn)
+	{
+	  if (count == n)
+	    {
+	      // Famous last words:  Most large directories will not
+	      // have more than a few hundred files, so we should not
+	      // resize too many times even if the growth is linear...
+
+	      n += 100;
+	      retval.resize (n);
+	    }
+
+	  retval[count++] = fn;
+
+	  free (fn);
+	}
+      else
+	break;
+    }
+
+  retval.resize (count);
+
+  return retval;
+}
+
+void
+gnu_readline::do_insert_text (const std::string& text)
+{
+  ::octave_rl_insert_text (text.c_str ());
+}
+
+void
+gnu_readline::do_newline (void)
+{
+  ::octave_rl_newline (1, '\n');
+}
+
+void
+gnu_readline::do_accept_line (void)
+{
+  command_accept_line (1, '\n');
+}
+
+void
+gnu_readline::do_clear_undo_list ()
+{
+  ::octave_rl_clear_undo_list ();
+}
+
+void
+gnu_readline::set_startup_hook (startup_hook_fcn f)
+{
+  previous_startup_hook = ::octave_rl_get_startup_hook ();
+
+  if (f != previous_startup_hook)
+    ::octave_rl_set_startup_hook (f);
+}
+
+void
+gnu_readline::restore_startup_hook (void)
+{
+  ::octave_rl_set_startup_hook (previous_startup_hook);
+}
+
+void
+gnu_readline::set_event_hook (event_hook_fcn f)
+{
+  previous_event_hook = octave_rl_get_event_hook ();
+
+  ::octave_rl_set_event_hook (f);
+}
+
+void
+gnu_readline::restore_event_hook (void)
+{
+  ::octave_rl_set_event_hook (previous_event_hook);
+}
+
+void
+gnu_readline::do_read_init_file (const std::string& file)
+{
+  ::octave_rl_read_init_file (file.c_str ());
+}
+
+void
+gnu_readline::do_re_read_init_file (void)
+{
+  ::octave_rl_re_read_init_file ();
+}
+
+bool
+gnu_readline::do_filename_completion_desired (bool arg)
+{
+  return ::octave_rl_filename_completion_desired (arg);
+}
+
+bool
+gnu_readline::do_filename_quoting_desired (bool arg)
+{
+  return ::octave_rl_filename_quoting_desired (arg);
+}
+
+int
+gnu_readline::operate_and_get_next (int /* count */, int /* c */)
+{
+  // Accept the current line.
+
+  command_editor::accept_line ();
+
+  // Find the current line, and find the next line to use.
+
+  int x_where = command_history::where ();
+
+  int x_length = command_history::length ();
+
+  if ((command_history::is_stifled ()
+       && (x_length >= command_history::max_input_history ()))
+      || (x_where >= x_length - 1))
+    command_history::set_mark (x_where);
+  else
+    command_history::set_mark (x_where + 1);
+
+  command_editor::add_startup_hook (command_history::goto_mark);
+
+  return 0;
+}
+
+int
+gnu_readline::history_search_backward (int count, int c)
+{
+  return octave_rl_history_search_backward (count, c);
+}
+
+int
+gnu_readline::history_search_forward (int count, int c)
+{
+  return octave_rl_history_search_forward (count, c);
+}
+
+char *
+gnu_readline::command_generator (const char *text, int state)
+{
+  char *retval = 0;
+
+  completion_fcn f = command_editor::get_completion_function ();
+
+  std::string tmp = f (text, state);
+
+  size_t len = tmp.length ();
+
+  if (len > 0)
+    {
+      retval = static_cast<char *> (malloc (len+1));
+
+      strcpy (retval, tmp.c_str ());
+    }
+
+  return retval;
+}
+
+char *
+gnu_readline::command_quoter (char *text, int matches, char *qcp)
+{
+  char *retval = 0;
+
+  quoting_fcn f = command_editor::get_quoting_function ();
+
+  std::string tmp = f (text, matches, *qcp);
+
+  size_t len = tmp.length ();
+
+  if (len > 0)
+    {
+      retval = static_cast<char *> (malloc (len+1));
+
+      strcpy (retval, tmp.c_str ());
+    }
+
+  return retval;
+}
+
+char *
+gnu_readline::command_dequoter (char *text, int quote)
+{
+  char *retval = 0;
+
+  dequoting_fcn f = command_editor::get_dequoting_function ();
+
+  std::string tmp = f (text, quote);
+
+  size_t len = tmp.length ();
+
+  if (len > 0)
+    {
+      retval = static_cast<char *> (malloc (len+1));
+
+      strcpy (retval, tmp.c_str ());
+    }
+
+  return retval;
+}
+
+int
+gnu_readline::command_char_is_quoted (char *text, int quote)
+{
+  char_is_quoted_fcn f = command_editor::get_char_is_quoted_function ();
+
+  return f (text, quote);
+}
+
+int
+gnu_readline::command_accept_line (int count, int key)
+{
+  user_accept_line_fcn f = command_editor::get_user_accept_line_function ();
+
+  if (f)
+    f (::octave_rl_line_buffer ());
+
+  ::octave_rl_redisplay ();
+
+  return ::octave_rl_newline (count, key);
+}
+
+char **
+gnu_readline::command_completer (const char *text, int, int)
+{
+  char **matches = 0;
+  matches
+    = ::octave_rl_completion_matches (text, gnu_readline::command_generator);
+  return matches;
+}
+
+#endif
+
+class
+default_command_editor : public command_editor
+{
+public:
+
+  default_command_editor (void)
+    : command_editor (), input_stream (stdin), output_stream (stdout) { }
+
+  ~default_command_editor (void) { }
+
+  std::string do_readline (const std::string& prompt, bool& eof);
+
+  void do_set_input_stream (FILE *f);
+
+  FILE *do_get_input_stream (void);
+
+  void do_set_output_stream (FILE *f);
+
+  FILE *do_get_output_stream (void);
+
+  string_vector do_generate_filename_completions (const std::string& text);
+
+  void do_insert_text (const std::string&);
+
+  void do_newline (void);
+
+  void do_accept_line (void);
+
+private:
+
+  FILE *input_stream;
+
+  FILE *output_stream;
+};
+
+std::string
+default_command_editor::do_readline (const std::string& prompt, bool& eof)
+{
+  fputs (prompt.c_str (), output_stream);
+  fflush (output_stream);
+
+  return octave_fgetl (input_stream, eof);
+}
+
+void
+default_command_editor::do_set_input_stream (FILE *f)
+{
+  input_stream = f;
+}
+
+FILE *
+default_command_editor::do_get_input_stream (void)
+{
+  return input_stream;
+}
+
+void
+default_command_editor::do_set_output_stream (FILE *f)
+{
+  output_stream = f;
+}
+
+FILE *
+default_command_editor::do_get_output_stream (void)
+{
+  return output_stream;
+}
+
+string_vector
+default_command_editor::do_generate_filename_completions (const std::string&)
+{
+  // FIXME
+  return string_vector ();
+}
+
+void
+default_command_editor::do_insert_text (const std::string&)
+{
+  // FIXME
+}
+
+void
+default_command_editor::do_newline (void)
+{
+  // FIXME
+}
+
+void
+default_command_editor::do_accept_line (void)
+{
+  // FIXME
+}
+
+bool
+command_editor::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    make_command_editor ();
+
+  if (! instance)
+    {
+      current_liboctave_error_handler
+	("unable to create command history object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+command_editor::make_command_editor (void)
+{
+#if defined (USE_READLINE)
+  instance = new gnu_readline ();
+#else
+  instance = new default_command_editor ();
+#endif
+}
+
+void 
+command_editor::force_default_editor (void)
+{
+  delete instance;
+  instance = new default_command_editor ();
+}
+
+int
+command_editor::startup_handler (void)
+{
+  for (startup_hook_set_iterator p = startup_hook_set.begin ();
+       p != startup_hook_set.end (); p++)
+    {
+      startup_hook_fcn f = *p;
+
+      if (f)
+	f ();
+    }
+
+  return 0;
+}
+
+int
+command_editor::event_handler (void)
+{
+  event_hook_lock.lock ();
+
+  std::set<event_hook_fcn> hook_set (event_hook_set);
+
+  event_hook_lock.unlock ();
+
+  for (event_hook_set_iterator p = hook_set.begin ();
+       p != hook_set.end (); p++)
+    {
+      event_hook_fcn f = *p;
+
+      if (f)
+	f ();
+    }
+
+  return 0;
+}
+
+void
+command_editor::set_name (const std::string& n)
+{
+  if (instance_ok ())
+    instance->do_set_name (n);
+}
+
+std::string
+command_editor::readline (const std::string& prompt)
+{
+  bool eof;
+
+  return readline (prompt, eof);
+}
+
+std::string
+command_editor::readline (const std::string& prompt, bool& eof)
+{
+  return (instance_ok ())
+    ? instance->do_readline (prompt, eof) : std::string ();
+}
+
+void
+command_editor::set_input_stream (FILE *f)
+{
+  if (instance_ok ())
+    instance->do_set_input_stream (f);
+}
+
+FILE *
+command_editor::get_input_stream (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_input_stream () : 0;
+}
+
+void
+command_editor::set_output_stream (FILE *f)
+{
+  if (instance_ok ())
+    instance->do_set_output_stream (f);
+}
+
+FILE *
+command_editor::get_output_stream (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_output_stream () : 0;
+}
+
+int
+command_editor::terminal_rows (void)
+{
+  return (instance_ok ())
+    ? instance->do_terminal_rows () : -1;
+}
+
+int
+command_editor::terminal_cols (void)
+{
+  return (instance_ok ())
+    ? instance->do_terminal_cols () : -1;
+}
+
+void
+command_editor::clear_screen (void)
+{
+  if (instance_ok ())
+    instance->do_clear_screen ();
+}
+
+void
+command_editor::resize_terminal (void)
+{
+  if (instance_ok ())
+    instance->do_resize_terminal ();
+}
+
+std::string
+command_editor::decode_prompt_string (const std::string& s)
+{
+  return (instance_ok ())
+    ? instance->do_decode_prompt_string (s) : std::string ();
+}
+
+int
+command_editor::current_command_number (void)
+{
+  return (instance_ok ())
+    ? instance->command_number : 0;
+}
+
+void
+command_editor::reset_current_command_number (int n)
+{
+  if (instance_ok ())
+    instance->command_number = n;
+}
+
+void
+command_editor::increment_current_command_number (void)
+{
+  if (instance_ok ())
+    instance->command_number++;
+}
+
+void
+command_editor::restore_terminal_state (void)
+{
+  if (instance_ok ())
+    instance->do_restore_terminal_state ();
+}
+
+void
+command_editor::blink_matching_paren (bool flag)
+{
+  if (instance_ok ())
+    instance->do_blink_matching_paren (flag);
+}
+
+void
+command_editor::set_basic_word_break_characters (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_set_basic_word_break_characters (s);
+}
+
+void
+command_editor::set_completer_word_break_characters (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_set_completer_word_break_characters (s);
+}
+
+void
+command_editor::set_basic_quote_characters (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_set_basic_quote_characters (s);
+}
+
+void
+command_editor::set_filename_quote_characters (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_set_filename_quote_characters (s);
+}
+
+void
+command_editor::set_completer_quote_characters (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_set_completer_quote_characters (s);
+}
+
+void
+command_editor::set_completion_append_character (char c)
+{
+  if (instance_ok ())
+    instance->do_set_completion_append_character (c);
+}
+
+void
+command_editor::set_completion_function (completion_fcn f)
+{
+  if (instance_ok ())
+    instance->do_set_completion_function (f);
+}
+
+void
+command_editor::set_quoting_function (quoting_fcn f)
+{
+  if (instance_ok ())
+    instance->do_set_quoting_function (f);
+}
+
+void
+command_editor::set_dequoting_function (dequoting_fcn f)
+{
+  if (instance_ok ())
+    instance->do_set_dequoting_function (f);
+}
+
+void
+command_editor::set_char_is_quoted_function (char_is_quoted_fcn f)
+{
+  if (instance_ok ())
+    instance->do_set_char_is_quoted_function (f);
+}
+
+void
+command_editor::set_user_accept_line_function (user_accept_line_fcn f)
+{
+  if (instance_ok ())
+    instance->do_set_user_accept_line_function (f);
+}
+
+command_editor::completion_fcn
+command_editor::get_completion_function (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_completion_function () : 0;
+}
+
+command_editor::quoting_fcn
+command_editor::get_quoting_function (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_quoting_function () : 0;
+}
+
+command_editor::dequoting_fcn
+command_editor::get_dequoting_function (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_dequoting_function () : 0;
+}
+
+command_editor::char_is_quoted_fcn
+command_editor::get_char_is_quoted_function (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_char_is_quoted_function () : 0;
+}
+
+command_editor::user_accept_line_fcn
+command_editor::get_user_accept_line_function (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_user_accept_line_function () : 0;
+}
+
+string_vector
+command_editor::generate_filename_completions (const std::string& text)
+{
+  return (instance_ok ())
+    ? instance->do_generate_filename_completions (text) : string_vector ();
+}
+
+void
+command_editor::insert_text (const std::string& text)
+{
+  if (instance_ok ())
+    instance->do_insert_text (text);
+}
+
+void
+command_editor::newline (void)
+{
+  if (instance_ok ())
+    instance->do_newline ();
+}
+
+void
+command_editor::accept_line (void)
+{
+  if (instance_ok ())
+    instance->do_accept_line ();
+}
+
+void
+command_editor::clear_undo_list (void)
+{
+  if (instance_ok ())
+    instance->do_clear_undo_list ();
+}
+
+void
+command_editor::add_startup_hook (startup_hook_fcn f)
+{
+  if (instance_ok ())
+    {
+      startup_hook_set.insert (f);
+
+      instance->set_startup_hook (startup_handler);
+    }
+}
+
+void
+command_editor::remove_startup_hook (startup_hook_fcn f)
+{
+  if (instance_ok ())
+    {
+      startup_hook_set_iterator p = startup_hook_set.find (f);
+
+      if (p != startup_hook_set.end ())
+	startup_hook_set.erase (p);
+
+      if (startup_hook_set.empty ())
+	instance->restore_startup_hook ();
+    }
+}
+
+void
+command_editor::add_event_hook (event_hook_fcn f)
+{
+  octave_autolock guard (event_hook_lock);
+
+  if (instance_ok ())
+    {
+      event_hook_set.insert (f);
+
+      instance->set_event_hook (event_handler);
+    }
+}
+
+void
+command_editor::remove_event_hook (event_hook_fcn f)
+{
+  octave_autolock guard (event_hook_lock);
+
+  if (instance_ok ())
+    {
+      event_hook_set_iterator p = event_hook_set.find (f);
+
+      if (p != event_hook_set.end ())
+	event_hook_set.erase (p);
+
+      if (event_hook_set.empty ())
+	instance->restore_event_hook ();
+    }
+}
+
+void
+command_editor::read_init_file (const std::string& file_arg)
+{
+  if (instance_ok ())
+    {
+      std::string file = file_ops::tilde_expand (file_arg);
+
+      instance->do_read_init_file (file);
+    }
+}
+
+void
+command_editor::re_read_init_file (void)
+{
+  if (instance_ok ())
+    instance->do_re_read_init_file ();
+}
+
+bool
+command_editor::filename_completion_desired (bool arg)
+{
+  return (instance_ok ())
+    ? instance->do_filename_completion_desired (arg) : false;
+}
+
+bool
+command_editor::filename_quoting_desired (bool arg)
+{
+  return (instance_ok ())
+    ? instance->do_filename_quoting_desired (arg) : false;
+}
+
+// Return a string which will be printed as a prompt.  The string may
+// contain special characters which are decoded as follows: 
+//   
+//	\a	bell (ascii 07)
+//	\d	the date
+//	\e	escape (ascii 033)
+//	\h	the hostname up to the first `.'
+//	\H	the hostname
+//	\n	CRLF
+//	\r	CR
+//	\s	the name of the shell (program)
+//	\t	the time
+//	\T	the time in 12-hour hh:mm:ss format
+//	\@	the time in 12-hour hh:mm am/pm format
+//	\A	the time in 24-hour hh:mm format
+//	\u	your username
+//	\w	the current working directory
+//	\W	the last element of PWD
+//	\!	the history number of this command
+//	\#	the command number of this command
+//	\$	a $ or a # if you are root
+//	\nnn    character code nnn in octal
+//	\\	a backslash
+//	\[	begin a sequence of non-printing chars
+//	\]	end a sequence of non-printing chars
+
+std::string
+command_editor::do_decode_prompt_string (const std::string& s)
+{
+  std::string result;
+  std::string temp;
+  size_t i = 0;
+  size_t slen = s.length ();
+  int c;
+
+  while (i < slen)
+    {
+      c = s[i];
+
+      i++;
+
+      if (c == '\\')
+	{
+	  c = s[i];
+
+	  switch (c)
+	    {
+	    case '0':
+	    case '1':
+	    case '2':
+	    case '3':
+	    case '4':
+	    case '5':
+	    case '6':
+	    case '7':
+	      // Maybe convert an octal number.
+	      {
+		int n = read_octal (s.substr (i, 3));
+
+		temp = "\\";
+
+		if (n != -1)
+		  {
+		    i += 3;
+		    temp[0] = n;
+		  }
+
+		c = 0;
+		goto add_string;
+	      }
+
+	    case 'a':
+	      {
+		temp = '\a';
+
+		goto add_string;
+	      }
+
+	    case 'e':
+	      {
+		temp = '\033';
+
+		goto add_string;
+	      }
+
+	    case 'r':
+	      {
+		temp = '\r';
+
+		goto add_string;
+	      }
+
+	    case 'd':
+	    case 't':
+	    case 'T':
+	    case '@':
+	    case 'A':
+	      // Make the current time/date into a string.
+	      {
+		octave_localtime now;
+
+		if (c == 'd')
+		  temp = now.strftime ("%a %b %d");
+		else if (c == 't')
+		  temp = now.strftime ("%H:%M:%S");
+		else if (c == 'T')
+		  temp = now.strftime ("%I:%M:%S");
+		else if (c == '@')
+		  temp = now.strftime ("%I:%M %p");
+		else if (c == 'A')
+		  temp = now.strftime ("%H:%M");
+
+		goto add_string;
+	      }
+
+	    case 'n':
+	      {
+		temp = newline_chars ();
+
+		goto add_string;
+	      }
+
+	    case 's':
+	      {
+		temp = octave_env::get_program_name ();
+		temp = octave_env::base_pathname (temp);
+
+		goto add_string;
+	      }
+
+	    case 'w':
+	    case 'W':
+	      {
+		temp = octave_env::getcwd ();
+
+		std::string home_dir = octave_env::get_home_directory ();
+
+		if (c == 'W' && (home_dir.empty () || temp != home_dir))
+		  {
+		    if (temp != "/" && temp != "//")
+		      {
+			size_t pos = temp.rfind ('/');
+
+			if (pos != std::string::npos && pos != 0)
+			  temp = temp.substr (pos + 1);
+		      }
+		  }
+		else
+		  temp = octave_env::polite_directory_format (temp);
+
+		goto add_string;
+	      }
+
+	    case 'u':
+	      {
+		temp = octave_env::get_user_name ();
+
+		goto add_string;
+	      }
+
+	    case 'H':
+	      {
+		temp = octave_env::get_host_name ();
+
+		goto add_string;
+	      }
+
+	    case 'h':
+	      {
+		temp = octave_env::get_host_name ();
+
+		size_t pos = temp.find ('.');
+
+		if (pos != std::string::npos)
+		  temp.resize (pos);
+		
+		goto add_string;
+	      }
+
+	    case '#':
+	      {
+		char number_buffer[128];
+		sprintf (number_buffer, "%d", command_number);
+		temp = number_buffer;
+
+		goto add_string;
+	      }
+
+	    case '!':
+	      {
+		char number_buffer[128];
+		int num = command_history::current_number ();
+		if (num > 0)
+                  sprintf (number_buffer, "%d", num);
+		else
+		  strcpy (number_buffer, "!");
+		temp = number_buffer;
+
+		goto add_string;
+	      }
+
+	    case '$':
+	      {
+#if defined (HAVE_GETEUID)
+		temp = (::geteuid () == 0 ? "#" : "$");
+#else
+		temp = "$";
+#endif
+
+		goto add_string;
+	      }
+
+#if defined (USE_READLINE)
+	    case '[':
+	    case ']':
+	      {
+		temp.resize (1);
+
+		temp[0] = ((c == '[')
+			   ? ::octave_rl_prompt_start_ignore ()
+			   : ::octave_rl_prompt_end_ignore ());
+
+		goto add_string;
+	      }
+#endif
+
+	    case '\\':
+	      {
+		temp = "\\";
+
+		goto add_string;
+	      }
+
+	    default:
+	      {
+		temp = "\\ ";
+		temp[1] = c;
+
+		goto add_string;
+	      }
+
+	    add_string:
+	      {
+		if (c)
+		  i++;
+
+		result.append (temp);
+
+		break;
+	      }
+	    }
+	}
+      else
+	result += c;
+    }
+
+  return result;
+}
+
+// Return the octal number parsed from STRING, or -1 to indicate that
+// the string contained a bad number.
+
+int
+command_editor::read_octal (const std::string& s)
+{
+  int result = 0;
+  int digits = 0;
+
+  size_t i = 0;
+  size_t slen = s.length ();
+
+  while (i < slen && s[i] >= '0' && s[i] < '8')
+    {
+      digits++;
+      result = (result * 8) + s[i] - '0';
+      i++;
+    }
+
+  if (! digits || result > 0777 || i < slen)
+    result = -1;
+
+  return result;
+}
+
+void
+command_editor::error (int err_num)
+{
+  current_liboctave_error_handler ("%s", strerror (err_num));
+}
+
+void
+command_editor::error (const std::string& s)
+{
+  current_liboctave_error_handler ("%s", s.c_str ());
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/cmd-edit.h b/liboctave/cmd-edit.h
new file mode 100644
index 0000000..9d24846
--- /dev/null
+++ b/liboctave/cmd-edit.h
@@ -0,0 +1,299 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_cmd_edit_h)
+#define octave_cmd_edit_h 1
+
+#include <cstdio>
+
+#include <set>
+#include <string>
+
+#include "str-vec.h"
+
+class
+OCTAVE_API
+command_editor
+{
+protected:
+
+  command_editor (void)
+    : command_number (0) { }
+
+public:
+
+  typedef int (*startup_hook_fcn) (void);
+
+  typedef int (*event_hook_fcn) (void);
+
+  typedef std::string (*completion_fcn) (const std::string&, int);
+
+  typedef std::string (*quoting_fcn) (const std::string&, int, char);
+
+  typedef std::string (*dequoting_fcn) (const std::string&, int);
+
+  typedef int (*char_is_quoted_fcn) (const std::string&, int);
+
+  typedef void (*user_accept_line_fcn) (const std::string&);
+
+  virtual ~command_editor (void) { }
+
+  static void set_name (const std::string& n);
+
+  static std::string readline (const std::string& prompt);
+
+  static std::string readline (const std::string& prompt, bool& eof);
+
+  static void set_input_stream (FILE *f);
+
+  static FILE *get_input_stream (void);
+
+  static void set_output_stream (FILE *f);
+
+  static FILE *get_output_stream (void);
+
+  static int terminal_rows (void);
+
+  static int terminal_cols (void);
+
+  static void clear_screen (void);
+
+  static void resize_terminal (void);
+
+  static std::string decode_prompt_string (const std::string& s);
+
+  static void restore_terminal_state (void);
+
+  static void blink_matching_paren (bool flag);
+
+  static void set_basic_word_break_characters (const std::string& s);
+
+  static void set_completer_word_break_characters (const std::string& s);
+
+  static void set_basic_quote_characters (const std::string& s);
+
+  static void set_filename_quote_characters (const std::string& s);
+
+  static void set_completer_quote_characters (const std::string& s);
+
+  static void set_completion_append_character (char c);
+
+  static void set_completion_function (completion_fcn f);
+
+  static void set_quoting_function (quoting_fcn f);
+
+  static void set_dequoting_function (dequoting_fcn f);
+
+  static void set_char_is_quoted_function (char_is_quoted_fcn f);
+
+  static void set_user_accept_line_function (user_accept_line_fcn f);
+
+  static completion_fcn get_completion_function (void);
+
+  static quoting_fcn get_quoting_function (void);
+
+  static dequoting_fcn get_dequoting_function (void);
+
+  static char_is_quoted_fcn get_char_is_quoted_function (void);
+
+  static user_accept_line_fcn get_user_accept_line_function (void);
+
+  static string_vector generate_filename_completions (const std::string& text);
+
+  static void insert_text (const std::string& text);
+
+  static void newline (void);
+
+  static void accept_line (void);
+
+  static void clear_undo_list (void);
+
+  static void add_startup_hook (startup_hook_fcn f);
+
+  static void remove_startup_hook (startup_hook_fcn f);
+
+  static void add_event_hook (event_hook_fcn f);
+
+  static void remove_event_hook (event_hook_fcn f);
+
+  static void read_init_file (const std::string& file = std::string ());
+
+  static void re_read_init_file (void);
+
+  static bool filename_completion_desired (bool);
+
+  static bool filename_quoting_desired (bool);
+
+  static int current_command_number (void);
+
+  static void reset_current_command_number (int n);
+
+  static void increment_current_command_number (void);
+
+  static void force_default_editor (void);
+
+private:
+
+  // No copying!
+
+  command_editor (const command_editor&);
+
+  command_editor& operator = (const command_editor&);
+
+  static bool instance_ok (void);
+
+  static void make_command_editor (void);
+
+  static int startup_handler (void);
+
+  static int event_handler (void);
+
+  static std::set<startup_hook_fcn> startup_hook_set;
+
+  static std::set<event_hook_fcn> event_hook_set;
+
+  typedef std::set<startup_hook_fcn>::iterator startup_hook_set_iterator;
+  typedef std::set<startup_hook_fcn>::const_iterator startup_hook_set_const_iterator;
+
+  typedef std::set<event_hook_fcn>::iterator event_hook_set_iterator;
+  typedef std::set<event_hook_fcn>::const_iterator event_hook_set_const_iterator;
+
+  // The real thing.
+  static command_editor *instance;
+
+protected:
+
+  // To use something other than the GNU readline library, derive a new
+  // class from command_editor, overload these functions as
+  // necessary, and make instance point to the new class.
+
+  virtual void do_set_name (const std::string&) { }
+
+  std::string do_readline (const std::string& prompt)
+    {
+      bool eof;
+
+      return do_readline (prompt, eof);
+    }
+
+  virtual std::string do_readline (const std::string&, bool&) = 0;
+
+  virtual void do_set_input_stream (FILE *) = 0;
+
+  virtual FILE *do_get_input_stream (void) = 0;
+
+  virtual void do_set_output_stream (FILE *) = 0;
+
+  virtual FILE *do_get_output_stream (void) = 0;
+
+  virtual int do_terminal_rows (void) { return 24; }
+
+  virtual int do_terminal_cols (void) { return 80; }
+
+  virtual void do_clear_screen (void) { }
+
+  virtual void do_resize_terminal (void) { }
+
+  virtual std::string do_decode_prompt_string (const std::string&);
+
+  virtual std::string newline_chars (void) { return "\n"; } 
+
+  virtual void do_restore_terminal_state (void) { }
+
+  virtual void do_blink_matching_paren (bool) { }
+
+  virtual void do_set_basic_word_break_characters (const std::string&) { }
+
+  virtual void do_set_completer_word_break_characters (const std::string&) { }
+
+  virtual void do_set_basic_quote_characters (const std::string&) { }
+
+  virtual void do_set_filename_quote_characters (const std::string&) { }
+
+  virtual void do_set_completer_quote_characters (const std::string&) { }
+
+  virtual void do_set_completion_append_character (char) { }
+
+  virtual void do_set_completion_function (completion_fcn) { }
+
+  virtual void do_set_quoting_function (quoting_fcn) { }
+
+  virtual void do_set_dequoting_function (dequoting_fcn) { }
+
+  virtual void do_set_char_is_quoted_function (char_is_quoted_fcn) { }
+
+  virtual void do_set_user_accept_line_function (user_accept_line_fcn) { }
+
+  virtual completion_fcn do_get_completion_function (void) const { return 0; }
+
+  virtual quoting_fcn do_get_quoting_function (void) const { return 0; }
+
+  virtual dequoting_fcn do_get_dequoting_function (void) const { return 0; }
+
+  virtual char_is_quoted_fcn do_get_char_is_quoted_function (void) const { return 0; }
+
+  virtual user_accept_line_fcn do_get_user_accept_line_function (void) const { return 0; }
+
+  virtual string_vector do_generate_filename_completions (const std::string& text) = 0;
+
+  virtual void do_insert_text (const std::string&) = 0;
+
+  virtual void do_newline (void) = 0;
+
+  virtual void do_accept_line (void) = 0;
+
+  virtual void do_clear_undo_list (void) { }
+
+  virtual void set_startup_hook (startup_hook_fcn) { }
+
+  virtual void restore_startup_hook (void) { }
+
+  virtual void set_event_hook (startup_hook_fcn) { }
+
+  virtual void restore_event_hook (void) { }
+
+  virtual void do_read_init_file (const std::string&) { }
+
+  virtual void do_re_read_init_file (void) { }
+
+  virtual bool do_filename_completion_desired (bool) { return false; }
+
+  virtual bool do_filename_quoting_desired (bool) { return false; }
+
+  int read_octal (const std::string& s);
+
+  void error (int);
+
+  void error (const std::string&);
+
+  // The current command number.
+  int command_number;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/cmd-hist.cc b/liboctave/cmd-hist.cc
new file mode 100644
index 0000000..34bea4a
--- /dev/null
+++ b/liboctave/cmd-hist.cc
@@ -0,0 +1,829 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstring>
+
+#include <iostream>
+#include <string>
+
+#include "cmd-edit.h"
+#include "cmd-hist.h"
+#include "file-ops.h"
+#include "lo-error.h"
+#include "str-vec.h"
+
+command_history *command_history::instance = 0;
+
+#if defined (USE_READLINE)
+
+#include <cstdlib>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "oct-rl-hist.h"
+
+#include "file-stat.h"
+
+class
+gnu_history : public command_history
+{
+public:
+
+  gnu_history (void)
+    : command_history (), mark (0) { }
+
+  ~gnu_history (void) { }
+
+  void do_add (const std::string&);
+
+  void do_remove (int);
+
+  int do_where (void);
+
+  int do_length (void);
+
+  int do_max_input_history (void);
+
+  int do_base (void);
+
+  int do_current_number (void);
+
+  void do_stifle (int);
+
+  int do_unstifle (void);
+
+  int do_is_stifled (void);
+
+  void do_set_mark (int);
+
+  int do_goto_mark (void);
+
+  void do_read (const std::string&, bool);
+
+  void do_read_range (const std::string&, int, int, bool);
+
+  void do_write (const std::string&);
+
+  void do_append (const std::string&);
+
+  void do_truncate_file (const std::string&, int);
+
+  string_vector do_list (int, bool);
+
+  std::string do_get_entry (int);
+
+  void do_replace_entry (int, const std::string&);
+
+  void do_clean_up_and_save (const std::string&, int);
+
+private:
+
+  int mark;
+};
+
+void
+gnu_history::do_add (const std::string& s)
+{
+  if (! do_ignoring_entries ())
+    {
+      if (s.empty ()
+	  || (s.length () == 1 && (s[0] == '\r' || s[0] == '\n')))
+	return;
+
+      ::octave_add_history (s.c_str ());
+
+      lines_this_session++;
+    }
+}
+
+void
+gnu_history::do_remove (int n)
+{
+  ::octave_remove_history (n);
+}
+
+int
+gnu_history::do_where (void)
+{
+  return ::octave_where_history ();
+}
+
+int
+gnu_history::do_length (void)
+{
+  return ::octave_history_length ();
+}
+
+int
+gnu_history::do_max_input_history (void)
+{
+  return ::octave_max_input_history ();
+}
+
+int
+gnu_history::do_base (void)
+{
+  return ::octave_history_base ();
+}
+
+int
+gnu_history::do_current_number (void)
+{
+  return (xsize > 0) ? do_base () + do_where () : -1;
+}
+
+void
+gnu_history::do_stifle (int n)
+{
+  ::octave_stifle_history (n);
+}
+
+int
+gnu_history::do_unstifle (void)
+{
+  return ::octave_unstifle_history ();
+}
+
+int
+gnu_history::do_is_stifled (void)
+{
+  return ::octave_history_is_stifled ();
+}
+
+void
+gnu_history::do_set_mark (int n)
+{
+  mark = n;
+}
+
+int
+gnu_history::do_goto_mark (void)
+{
+  if (mark)
+    {
+      char *line = ::octave_history_goto_mark (mark);
+
+      if (line)
+	{
+	  command_editor::insert_text (line);
+
+	  command_editor::clear_undo_list ();
+	}
+    }
+
+  mark = 0;
+
+  // FIXME -- for operate_and_get_next.
+  command_editor::remove_startup_hook (command_history::goto_mark);
+
+  return 0;
+}
+
+void
+gnu_history::do_read (const std::string& f, bool must_exist)
+{
+  if (! f.empty ())
+    {
+      int status = ::octave_read_history (f.c_str ());
+
+      if (status != 0 && must_exist)
+	error (status);
+      else
+	{
+	  lines_in_file = do_where ();
+
+	  ::octave_using_history ();
+	}
+    }
+  else
+    error ("gnu_history::read: missing file name");
+}
+
+void
+gnu_history::do_read_range (const std::string& f, int from, int to,
+			    bool must_exist)
+{
+  if (from < 0)
+    from = lines_in_file;
+
+  if (! f.empty ())
+    {
+      int status = ::octave_read_history_range (f.c_str (), from, to);
+
+      if (status != 0 && must_exist)
+	error (status);
+      else
+	{
+	  lines_in_file = do_where ();
+
+	  ::octave_using_history ();
+	}
+    }
+  else
+    error ("gnu_history::read_range: missing file name");
+}
+
+void
+gnu_history::do_write (const std::string& f_arg)
+{
+  std::string f = f_arg;
+
+  if (f.empty ())
+    f = xfile;
+
+  if (! f.empty ())
+    {
+      int status = ::octave_write_history (f.c_str ());
+
+      if (status != 0)
+	error (status);
+    }
+  else
+    error ("gnu_history::write: missing file name");
+}
+
+void
+gnu_history::do_append (const std::string& f_arg)
+{
+  if (lines_this_session)
+    {
+      if (lines_this_session < do_where ())
+	{
+	  // Create file if it doesn't already exist.
+
+	  std::string f = f_arg;
+
+	  if (f.empty ())
+	    f = xfile;
+
+	  if (! f.empty ())
+	    {
+	      file_stat fs (f);
+
+	      if (! fs)
+		{
+		  int tem;
+
+		  tem = open (f.c_str (), O_CREAT, 0666);
+		  close (tem);
+		}
+
+	      int status
+		= ::octave_append_history (lines_this_session, f.c_str ());
+
+	      if (status != 0)
+		error (status);
+	      else
+		lines_in_file += lines_this_session;
+
+	      lines_this_session = 0;
+	    }
+	  else
+	    error ("gnu_history::append: missing file name");
+	}
+    }
+}
+
+void
+gnu_history::do_truncate_file (const std::string& f_arg, int n)
+{
+  std::string f = f_arg;
+
+  if (f.empty ())
+    f = xfile;
+
+  if (! f.empty ())
+    ::octave_history_truncate_file (f.c_str (), n);
+  else
+    error ("gnu_history::truncate_file: missing file name");
+}
+
+string_vector
+gnu_history::do_list (int limit, bool number_lines)
+{
+  string_vector retval;
+
+  if (limit)
+    retval = ::octave_history_list (limit, number_lines);
+
+  return retval;
+}
+
+std::string
+gnu_history::do_get_entry (int n)
+{
+  std::string retval;
+
+  char *line = ::octave_history_get (do_base () + n);
+
+  if (line)
+    retval = line;
+
+  return retval;
+}
+
+void
+gnu_history::do_replace_entry (int which, const std::string& line)
+{
+  ::octave_replace_history_entry (which, line.c_str ());
+}
+
+void
+gnu_history::do_clean_up_and_save (const std::string& f_arg, int n)
+{
+  std::string f = f_arg;
+
+  if (f.empty ())
+    f = xfile;
+
+  if (! f.empty ())
+    {
+      if (n < 0)
+	n = xsize;
+
+      stifle (n);
+
+      do_write (f.c_str ());
+    }
+  else
+    error ("gnu_history::clean_up_and_save: missing file name");
+}
+
+#endif
+
+bool
+command_history::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    make_command_history ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create command history object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+command_history::make_command_history (void)
+{
+#if defined (USE_READLINE)
+  instance = new gnu_history ();
+#else
+  instance = new command_history ();
+#endif
+}
+
+void
+command_history::set_file (const std::string& f_arg)
+{
+  if (instance_ok ())
+    {
+      std::string f = file_ops::tilde_expand (f_arg);
+
+      instance->do_set_file (f);
+    }
+}
+
+std::string
+command_history::file (void)
+{
+  return (instance_ok ())
+    ? instance->do_file () : std::string ();
+}
+
+void
+command_history::set_size (int n)
+{
+  if (instance_ok ())
+    instance->do_set_size (n);
+}
+
+int
+command_history::size (void)
+{
+  return (instance_ok ())
+    ? instance->do_size () : 0;
+}
+
+void
+command_history::ignore_entries (bool flag)
+{
+  if (instance_ok ())
+    instance->do_ignore_entries (flag);
+}
+
+bool
+command_history::ignoring_entries (void)
+{
+  return (instance_ok ())
+    ? instance->do_ignoring_entries () : false;
+}
+
+void
+command_history::add (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_add (s);
+}
+
+void
+command_history::remove (int n)
+{
+  if (instance_ok ())
+    instance->do_remove (n);
+}
+
+int
+command_history::where (void)
+{
+  return (instance_ok ())
+    ? instance->do_where () : 0;
+}
+
+int
+command_history::length (void)
+{
+  return (instance_ok ())
+    ? instance->do_length () : 0;
+}
+
+int
+command_history::max_input_history (void)
+{
+  return (instance_ok ())
+    ? instance->do_max_input_history () : 0;
+}
+
+int
+command_history::base (void)
+{
+  return (instance_ok ())
+    ? instance->do_base () : 0;
+}
+
+int
+command_history::current_number (void)
+{
+  return (instance_ok ())
+    ? instance->do_current_number () : 0;
+}
+
+void
+command_history::stifle (int n)
+{
+  if (instance_ok ())
+    instance->do_stifle (n);
+}
+
+int
+command_history::unstifle (void)
+{
+  return (instance_ok ())
+    ? instance->do_unstifle () : 0;
+}
+
+int
+command_history::is_stifled (void)
+{
+  return (instance_ok ())
+    ? instance->do_is_stifled () : 0;
+}
+
+void
+command_history::set_mark (int n)
+{
+  if (instance_ok ())
+    instance->do_set_mark (n);
+}
+
+int
+command_history::goto_mark (void)
+{
+  return (instance_ok ())
+    ? instance->do_goto_mark () : 0;
+}
+
+void
+command_history::read (bool must_exist)
+{
+  read (file (), must_exist);
+}
+
+void
+command_history::read (const std::string& f, bool must_exist)
+{
+  if (instance_ok ())
+    instance->do_read (f, must_exist);
+}
+
+void
+command_history::read_range (int from, int to, bool must_exist)
+{
+  read_range (file (), from, to, must_exist);
+}
+
+void
+command_history::read_range (const std::string& f, int from, int to,
+			     bool must_exist) 
+{
+  if (instance_ok ())
+    instance->do_read_range (f, from, to, must_exist);
+}
+
+void
+command_history::write (const std::string& f)
+{
+  if (instance_ok ())
+    instance->do_write (f);
+}
+
+void
+command_history::append (const std::string& f)
+{
+  if (instance_ok ())
+    instance->do_append (f);
+}
+
+void
+command_history::truncate_file (const std::string& f, int n)
+{
+  if (instance_ok ())
+    instance->do_truncate_file (f, n);
+}
+
+string_vector
+command_history::list (int limit, bool number_lines)
+{
+  return (instance_ok ())
+    ? instance->do_list (limit, number_lines) : string_vector ();
+}
+
+std::string
+command_history::get_entry (int n)
+{
+  return (instance_ok ())
+    ? instance->do_get_entry (n) : std::string ();
+}
+
+void
+command_history::replace_entry (int which, const std::string& line)
+{
+  if (instance_ok ())
+    instance->do_replace_entry (which, line);
+}
+
+void
+command_history::clean_up_and_save (const std::string& f, int n)
+{
+  if (instance_ok ())
+    instance->do_clean_up_and_save (f, n);
+}
+
+void
+command_history::do_set_file (const std::string& f)
+{
+  xfile = f;
+}
+
+std::string
+command_history::do_file (void)
+{
+  return xfile;
+}
+
+void
+command_history::do_set_size (int n)
+{
+  xsize = n;
+}
+
+int
+command_history::do_size (void)
+{
+  return xsize;
+}
+
+void
+command_history::do_ignore_entries (bool flag)
+{
+  ignoring_additions = flag;
+}
+
+bool
+command_history::do_ignoring_entries (void)
+{
+  return ignoring_additions;
+}
+
+void
+command_history::do_add (const std::string&)
+{
+}
+
+void
+command_history::do_remove (int)
+{
+}
+
+int
+command_history::do_where (void)
+{
+  return 0;
+}
+
+int
+command_history::do_length (void)
+{
+  return 0;
+}
+
+int
+command_history::do_max_input_history (void)
+{
+  return 0;
+}
+
+int
+command_history::do_base (void)
+{
+  return 0;
+}
+
+int
+command_history::do_current_number (void)
+{
+  return (xsize > 0) ? do_base () + do_where () : -1;
+}
+
+void
+command_history::do_stifle (int)
+{
+}
+
+int
+command_history::do_unstifle (void)
+{
+  return -1;
+}
+
+int
+command_history::do_is_stifled (void)
+{
+  return 0;
+}
+
+void
+command_history::do_set_mark (int)
+{
+}
+
+int
+command_history::do_goto_mark (void)
+{
+  return 0;
+}
+
+void
+command_history::do_read (const std::string& f, bool)
+{
+  if (f.empty ())
+    error ("command_history::read: missing file name");
+}
+
+void
+command_history::do_read_range (const std::string& f, int, int, bool)
+{
+  if (f.empty ())
+    error ("command_history::read_range: missing file name");
+}
+
+void
+command_history::do_write (const std::string& f_arg)
+{
+  std::string f = f_arg;
+
+  if (f.empty ())
+    f = xfile;
+
+  if (f.empty ())
+    error ("command_history::write: missing file name");
+}
+
+void
+command_history::do_append (const std::string& f_arg)
+{
+  if (lines_this_session)
+    {
+      if (lines_this_session < do_where ())
+	{
+	  // Create file if it doesn't already exist.
+
+	  std::string f = f_arg;
+
+	  if (f.empty ())
+	    f = xfile;
+
+	  if (f.empty ())
+	    error ("command_history::append: missing file name");
+	}
+    }
+}
+
+void
+command_history::do_truncate_file (const std::string& f_arg, int)
+{
+  std::string f = f_arg;
+
+  if (f.empty ())
+    f = xfile;
+
+  if (f.empty ())
+    error ("command_history::truncate_file: missing file name");
+}
+
+string_vector
+command_history::do_list (int, bool)
+{
+  return string_vector ();
+}
+
+std::string
+command_history::do_get_entry (int)
+{
+  return std::string ();
+}
+
+void
+command_history::do_replace_entry (int, const std::string&)
+{
+}
+
+void
+command_history::do_clean_up_and_save (const std::string& f_arg, int)
+{
+  std::string f = f_arg;
+
+  if (f.empty ())
+    f = xfile;
+
+  if (f.empty ())
+    error ("command_history::clean_up_and_save: missing file name");
+}
+
+void
+command_history::error (int err_num)
+{
+  (*current_liboctave_error_handler) ("%s", strerror (err_num));
+}
+
+void
+command_history::error (const std::string& s)
+{
+  (*current_liboctave_error_handler) ("%s", s.c_str ());
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/cmd-hist.h b/liboctave/cmd-hist.h
new file mode 100644
index 0000000..c18d52b
--- /dev/null
+++ b/liboctave/cmd-hist.h
@@ -0,0 +1,207 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_cmd_hist_h)
+#define octave_cmd_hist_h 1
+
+#include <string>
+
+#include "str-vec.h"
+
+class
+OCTAVE_API
+command_history
+{
+protected:
+
+  command_history (void)
+    : ignoring_additions (false), lines_in_file (0),
+      lines_this_session (0), xfile (), xsize (-1) { }
+
+public:
+
+  virtual ~command_history (void) { }
+
+  static void set_file (const std::string&);
+
+  static std::string file (void);
+
+  static void set_size (int);
+
+  static int size (void);
+
+  static void ignore_entries (bool = true);
+
+  static bool ignoring_entries (void);
+
+  static void add (const std::string&);
+
+  static void remove (int);
+
+  static int where (void);
+
+  static int length (void);
+
+  static int max_input_history (void);
+
+  static int base (void);
+
+  static int current_number (void);
+
+  static void stifle (int);
+
+  static int unstifle (void);
+
+  static int is_stifled (void);
+
+  static void set_mark (int n);
+
+  // Gag.  This declaration has to match the Function typedef in
+  // readline.h.
+
+  static int goto_mark (void);
+
+  static void read (bool = true);
+
+  static void read (const std::string&, bool = true);
+
+  static void read_range (int = -1, int = -1, bool = true);
+
+  static void read_range (const std::string&, int = -1, int = -1,
+			  bool = true);
+
+  static void write (const std::string& = std::string ());
+
+  static void append (const std::string& = std::string ());
+
+  static void truncate_file (const std::string& = std::string (), int = -1);
+
+  static string_vector list (int = -1, bool = false);
+
+  static std::string get_entry (int);
+
+  static void replace_entry (int, const std::string&);
+
+  static void clean_up_and_save (const std::string& = std::string (), int = -1);
+
+private:
+
+  // No copying!
+
+  command_history (const command_history&);
+
+  command_history& operator = (const command_history&);
+
+  static bool instance_ok (void);
+
+  static void make_command_history (void);
+
+  // The real thing.
+  static command_history *instance;
+
+protected:
+
+  // To use something other than the GNU history library, derive a new
+  // class from command_history, overload these functions as
+  // necessary, and make instance point to the new class.
+
+  virtual void do_set_file (const std::string&);
+
+  virtual std::string do_file (void);
+
+  virtual void do_set_size (int);
+
+  virtual int do_size (void);
+
+  virtual void do_ignore_entries (bool);
+
+  virtual bool do_ignoring_entries (void);
+
+  virtual void do_add (const std::string&);
+
+  virtual void do_remove (int);
+
+  virtual int do_where (void);
+
+  virtual int do_length (void);
+
+  virtual int do_max_input_history (void);
+
+  virtual int do_base (void);
+
+  virtual int do_current_number (void);
+
+  virtual void do_stifle (int);
+
+  virtual int do_unstifle (void);
+
+  virtual int do_is_stifled (void);
+
+  virtual void do_set_mark (int);
+
+  virtual int do_goto_mark (void);
+
+  virtual void do_read (const std::string&, bool);
+
+  virtual void do_read_range (const std::string&, int, int, bool);
+
+  virtual void do_write (const std::string&);
+
+  virtual void do_append (const std::string&);
+
+  virtual void do_truncate_file (const std::string&, int);
+
+  virtual string_vector do_list (int, bool);
+
+  virtual std::string do_get_entry (int);
+
+  virtual void do_replace_entry (int, const std::string&);
+
+  virtual void do_clean_up_and_save (const std::string&, int);
+
+  void error (int);
+
+  void error (const std::string&);
+
+  // TRUE means we are ignoring new additions.
+  bool ignoring_additions;
+
+  // The number of hisory lines we read from the history file.
+  int lines_in_file;
+
+  // The number of history lines we've saved so far.
+  int lines_this_session;
+
+  // The default history file.
+  std::string xfile;
+
+  // The number of lines of history to save.
+  int xsize;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dColVector.cc b/liboctave/dColVector.cc
new file mode 100644
index 0000000..26ea49a
--- /dev/null
+++ b/liboctave/dColVector.cc
@@ -0,0 +1,343 @@
+// ColumnVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const double&,
+			   const double*, const octave_idx_type&, const double*,
+			   const octave_idx_type&, const double&, double*,
+			   const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+}
+
+// Column Vector class.
+
+bool
+ColumnVector::operator == (const ColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+ColumnVector::operator != (const ColumnVector& a) const
+{
+  return !(*this == a);
+}
+
+ColumnVector&
+ColumnVector::insert (const ColumnVector& a, octave_idx_type r)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+ColumnVector&
+ColumnVector::fill (double val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ColumnVector&
+ColumnVector::fill (double val, octave_idx_type r1, octave_idx_type r2)
+{
+  octave_idx_type len = length ();
+
+  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  if (r2 >= r1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = r1; i <= r2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+ColumnVector
+ColumnVector::stack (const ColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nr_insert = len;
+  ColumnVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nr_insert);
+  return retval;
+}
+
+RowVector
+ColumnVector::transpose (void) const
+{
+  return MArray<double>::transpose();
+}
+
+ColumnVector
+real (const ComplexColumnVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  ColumnVector retval;
+  if (a_len > 0)
+    retval = ColumnVector (mx_inline_real_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+ColumnVector
+imag (const ComplexColumnVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  ColumnVector retval;
+  if (a_len > 0)
+    retval = ColumnVector (mx_inline_imag_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+// resize is the destructive equivalent for this one
+
+ColumnVector
+ColumnVector::extract (octave_idx_type r1, octave_idx_type r2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+
+  ColumnVector result (new_r);
+
+  for (octave_idx_type i = 0; i < new_r; i++)
+    result.xelem (i) = elem (r1+i);
+
+  return result;
+}
+
+ColumnVector
+ColumnVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  ColumnVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.xelem (i) = elem (r1+i);
+
+  return result;
+}
+
+// matrix by column vector -> column vector operations
+
+ColumnVector
+operator * (const Matrix& m, const ColumnVector& a)
+{
+  ColumnVector retval;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+  else
+    {
+      if (nr == 0 || nc == 0)
+	retval.resize (nr, 0.0);
+      else
+	{
+	  octave_idx_type ld = nr;
+
+	  retval.resize (nr);
+	  double *y = retval.fortran_vec ();
+
+	  F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
+				   nr, nc, 1.0, m.data (), ld,
+				   a.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+// diagonal matrix by column vector -> column vector operations
+
+ColumnVector
+operator * (const DiagMatrix& m, const ColumnVector& a)
+{
+  ColumnVector retval;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+  else
+    {
+      if (nr == 0 || nc == 0)
+	retval.resize (nr, 0.0);
+      else
+	{
+	  retval.resize (nr);
+
+	  for (octave_idx_type i = 0; i < a_len; i++)
+	    retval.elem (i) = a.elem (i) * m.elem (i, i);
+
+	  for (octave_idx_type i = a_len; i < nr; i++)
+	    retval.elem (i) = 0.0;
+	}
+    }
+
+  return retval;
+}
+
+// other operations
+
+ColumnVector
+ColumnVector::map (dmapper fcn) const
+{
+  return MArray<double>::map<double> (func_ptr (fcn));
+}
+
+ComplexColumnVector
+ColumnVector::map (cmapper fcn) const
+{
+  return MArray<double>::map<Complex> (func_ptr (fcn));
+}
+
+double
+ColumnVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  double res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) < res)
+      res = elem (i);
+
+  return res;
+}
+
+double
+ColumnVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  double res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) > res)
+      res = elem (i);
+
+  return res;
+}
+
+std::ostream&
+operator << (std::ostream& os, const ColumnVector& a)
+{
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << /* setw (field_width) << */ a.elem (i) << "\n";
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, ColumnVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      double tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dColVector.h b/liboctave/dColVector.h
new file mode 100644
index 0000000..4686b94
--- /dev/null
+++ b/liboctave/dColVector.h
@@ -0,0 +1,118 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ColumnVector_h)
+#define octave_ColumnVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+ColumnVector : public MArray<double>
+{
+public:
+
+  ColumnVector (void) : MArray<double> () { }
+
+  explicit ColumnVector (octave_idx_type n) : MArray<double> (n) { }
+
+  ColumnVector (octave_idx_type n, double val) : MArray<double> (n, val) { }
+
+  ColumnVector (const ColumnVector& a) : MArray<double> (a) { }
+
+  ColumnVector (const MArray<double>& a) : MArray<double> (a) { }
+
+  ColumnVector& operator = (const ColumnVector& a)
+    {
+      MArray<double>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const ColumnVector& a) const;
+  bool operator != (const ColumnVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  ColumnVector& insert (const ColumnVector& a, octave_idx_type r);
+
+  ColumnVector& fill (double val);
+  ColumnVector& fill (double val, octave_idx_type r1, octave_idx_type r2);
+
+  ColumnVector stack (const ColumnVector& a) const;
+
+  RowVector transpose (void) const;
+
+  friend OCTAVE_API ColumnVector real (const ComplexColumnVector& a);
+  friend OCTAVE_API ColumnVector imag (const ComplexColumnVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  ColumnVector extract (octave_idx_type r1, octave_idx_type r2) const;
+
+  ColumnVector extract_n (octave_idx_type r1, octave_idx_type n) const;
+
+  // matrix by column vector -> column vector operations
+
+  friend OCTAVE_API ColumnVector operator * (const Matrix& a, const ColumnVector& b);
+
+  // diagonal matrix by column vector -> column vector operations
+
+  friend OCTAVE_API ColumnVector operator * (const DiagMatrix& a, const ColumnVector& b);
+
+  // other operations
+
+  typedef double (*dmapper) (double);
+  typedef Complex (*cmapper) (const Complex&);
+
+  ColumnVector map (dmapper fcn) const;
+  ComplexColumnVector map (cmapper fcn) const;
+
+  double min (void) const;
+  double max (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ColumnVector& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, ColumnVector& a);
+
+private:
+
+  ColumnVector (double *d, octave_idx_type l) : MArray<double> (d, l) { }
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API ColumnVector real (const ComplexColumnVector& a);
+extern OCTAVE_API ColumnVector imag (const ComplexColumnVector& a);
+
+MARRAY_FORWARD_DEFS (MArray, ColumnVector, double)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dDiagMatrix.cc b/liboctave/dDiagMatrix.cc
new file mode 100644
index 0000000..ebb86c5
--- /dev/null
+++ b/liboctave/dDiagMatrix.cc
@@ -0,0 +1,415 @@
+// DiagMatrix manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Diagonal Matrix class.
+
+bool
+DiagMatrix::operator == (const DiagMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return 0;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+DiagMatrix::operator != (const DiagMatrix& a) const
+{
+  return !(*this == a);
+}
+
+DiagMatrix&
+DiagMatrix::fill (double val)
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = val;
+  return *this;
+}
+
+DiagMatrix&
+DiagMatrix::fill (double val, octave_idx_type beg, octave_idx_type end)
+{
+  if (beg < 0 || end >= length () || end < beg)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = beg; i <= end; i++)
+    elem (i, i) = val;
+
+  return *this;
+}
+
+DiagMatrix&
+DiagMatrix::fill (const ColumnVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+DiagMatrix&
+DiagMatrix::fill (const RowVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+DiagMatrix&
+DiagMatrix::fill (const ColumnVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+DiagMatrix&
+DiagMatrix::fill (const RowVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+DiagMatrix
+DiagMatrix::abs (void) const
+{
+  DiagMatrix retval (rows (), cols ());
+  for (octave_idx_type i = 0; i < rows (); i++)
+    retval(i, i) = std::abs (elem (i, i));
+  return retval;
+}
+
+DiagMatrix
+real (const ComplexDiagMatrix& a)
+{
+  DiagMatrix retval;
+  octave_idx_type a_len = a.length ();
+  if (a_len > 0)
+    retval = DiagMatrix (mx_inline_real_dup (a.data (), a_len), a.rows (),
+			 a.cols ());
+  return retval;
+}
+
+DiagMatrix
+imag (const ComplexDiagMatrix& a)
+{
+  DiagMatrix retval;
+  octave_idx_type a_len = a.length ();
+  if (a_len > 0)
+    retval = DiagMatrix (mx_inline_imag_dup (a.data (), a_len), a.rows (),
+			 a.cols ());
+  return retval;
+}
+
+Matrix
+DiagMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  Matrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.elem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+RowVector
+DiagMatrix::row (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= r)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
+
+  RowVector retval (c, 0.0);
+  if (r <= c || (r > c && i < c))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+RowVector
+DiagMatrix::row (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return row (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return row (rows () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
+}
+
+ColumnVector
+DiagMatrix::column (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= c)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
+
+  ColumnVector retval (r, 0.0);
+  if (r >= c || (r < c && i < r))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+ColumnVector
+DiagMatrix::column (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return column (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return column (cols () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
+}
+
+DiagMatrix
+DiagMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  return inverse (info);
+}
+
+DiagMatrix
+DiagMatrix::inverse (octave_idx_type &info) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  octave_idx_type len = length ();
+  if (r != c)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return DiagMatrix ();
+    }
+
+  DiagMatrix retval (r, c);
+
+  info = 0;
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      if (elem (i, i) == 0.0)
+	{
+	  info = -1;
+	  return *this;
+	}
+      else
+	retval.elem (i, i) = 1.0 / elem (i, i);
+    }
+
+  return retval;
+}
+
+DiagMatrix
+DiagMatrix::pseudo_inverse (void) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  octave_idx_type len = length ();
+
+  DiagMatrix retval (c, r);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      if (elem (i, i) != 0.0)
+        retval.elem (i, i) = 1.0 / elem (i, i);
+      else
+        retval.elem (i, i) = 0.0;
+    }
+
+  return retval;
+}
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+DiagMatrix
+operator * (const DiagMatrix& a, const DiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return DiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return DiagMatrix (a_nr, a_nc, 0.0);
+
+  DiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      double a_element = a.elem (i, i);
+      double b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+// other operations
+
+DET
+DiagMatrix::determinant (void) const
+{
+  DET det (1.0);
+  if (rows () != cols ())
+    {
+      (*current_liboctave_error_handler) ("determinant requires square matrix");
+      det = 0.0;
+    }
+  else
+    {
+      octave_idx_type len = length ();
+      for (octave_idx_type i = 0; i < len; i++)
+        det *= elem (i, i);
+    }
+
+  return det;
+}
+
+double
+DiagMatrix::rcond (void) const
+{
+  ColumnVector av  = diag (0).map (fabs);
+  double amx = av.max (), amn = av.min ();
+  return amx == 0 ? 0.0 : amn / amx;
+}
+
+std::ostream&
+operator << (std::ostream& os, const DiagMatrix& a)
+{
+//  int field_width = os.precision () + 7;
+
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  if (i == j)
+	    os << " " /* setw (field_width) */ << a.elem (i, i);
+	  else
+	    os << " " /* setw (field_width) */ << 0.0;
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dDiagMatrix.h b/liboctave/dDiagMatrix.h
new file mode 100644
index 0000000..73c461a
--- /dev/null
+++ b/liboctave/dDiagMatrix.h
@@ -0,0 +1,132 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_DiagMatrix_h)
+#define octave_DiagMatrix_h 1
+
+#include "MDiagArray2.h"
+
+#include "dRowVector.h"
+#include "dColVector.h"
+#include "DET.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+DiagMatrix : public MDiagArray2<double>
+{
+friend class SVD;
+friend class ComplexSVD;
+
+public:
+
+  DiagMatrix (void) : MDiagArray2<double> () { }
+
+  DiagMatrix (octave_idx_type r, octave_idx_type c) : MDiagArray2<double> (r, c) { }
+
+  DiagMatrix (octave_idx_type r, octave_idx_type c, double val) : MDiagArray2<double> (r, c, val) { }
+
+  DiagMatrix (const DiagMatrix& a) : MDiagArray2<double> (a) { }
+
+  DiagMatrix (const MDiagArray2<double>& a) : MDiagArray2<double> (a) { }
+
+  template <class U>
+  DiagMatrix (const DiagArray2<U>& a) : MDiagArray2<double> (a) { }
+
+  explicit DiagMatrix (const RowVector& a) : MDiagArray2<double> (a) { }
+
+  explicit DiagMatrix (const ColumnVector& a) : MDiagArray2<double> (a) { }
+
+  DiagMatrix& operator = (const DiagMatrix& a)
+    {
+      MDiagArray2<double>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const DiagMatrix& a) const;
+  bool operator != (const DiagMatrix& a) const;
+
+  DiagMatrix& fill (double val);
+  DiagMatrix& fill (double val, octave_idx_type beg, octave_idx_type end);
+  DiagMatrix& fill (const ColumnVector& a);
+  DiagMatrix& fill (const RowVector& a);
+  DiagMatrix& fill (const ColumnVector& a, octave_idx_type beg);
+  DiagMatrix& fill (const RowVector& a, octave_idx_type beg);
+
+  DiagMatrix transpose (void) const { return MDiagArray2<double>::transpose(); }
+  DiagMatrix abs (void) const; 
+
+  friend OCTAVE_API DiagMatrix real (const ComplexDiagMatrix& a);
+  friend OCTAVE_API DiagMatrix imag (const ComplexDiagMatrix& a);
+
+  // resize is the destructive analog for this one
+
+  Matrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  // extract row or column i.
+
+  RowVector row (octave_idx_type i) const;
+  RowVector row (char *s) const;
+
+  ColumnVector column (octave_idx_type i) const;
+  ColumnVector column (char *s) const;
+
+  DiagMatrix inverse (void) const;
+  DiagMatrix inverse (octave_idx_type& info) const;
+  DiagMatrix pseudo_inverse (void) const;
+
+  // other operations
+
+  ColumnVector diag (octave_idx_type k = 0) const
+    { return MDiagArray2<double>::diag (k); }
+
+  DET determinant (void) const;
+  double rcond (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const DiagMatrix& a);
+
+private:
+
+  DiagMatrix (double *d, octave_idx_type nr, octave_idx_type nc) : MDiagArray2<double> (d, nr, nc) { }
+};
+
+OCTAVE_API DiagMatrix real (const ComplexDiagMatrix& a);
+OCTAVE_API DiagMatrix imag (const ComplexDiagMatrix& a);
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+OCTAVE_API DiagMatrix
+operator * (const DiagMatrix& a, const DiagMatrix& b);
+
+MDIAGARRAY2_FORWARD_DEFS (MDiagArray2, DiagMatrix, double)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dMatrix.cc b/liboctave/dMatrix.cc
new file mode 100644
index 0000000..25bfef3
--- /dev/null
+++ b/liboctave/dMatrix.cc
@@ -0,0 +1,3419 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <vector>
+
+#include "Array-util.h"
+#include "byte-swap.h"
+#include "dMatrix.h"
+#include "dbleAEPBAL.h"
+#include "DET.h"
+#include "dbleSCHUR.h"
+#include "dbleSVD.h"
+#include "dbleCHOL.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "mx-m-dm.h"
+#include "mx-dm-m.h"
+#include "mx-inlines.cc"
+#include "mx-op-defs.h"
+#include "oct-cmplx.h"
+#include "oct-norm.h"
+#include "quit.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#endif
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (xilaenv, XILAENV) (const octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			       F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&,
+			       const octave_idx_type&, const octave_idx_type&,
+			       octave_idx_type&
+			       F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgebal, DGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgebak, DGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+
+  F77_RET_T
+  F77_FUNC (dgemm, DGEMM) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			   const double&, const double*, const octave_idx_type&,
+			   const double*, const octave_idx_type&, const double&,
+			   double*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const double&,
+			   const double*, const octave_idx_type&, const double*,
+			   const octave_idx_type&, const double&, double*,
+			   const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xddot, XDDOT) (const octave_idx_type&, const double*, const octave_idx_type&,
+			   const double*, const octave_idx_type&, double&);
+
+  F77_RET_T
+  F77_FUNC (dsyrk, DSYRK) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, 
+			   const double&, const double*, const octave_idx_type&,
+			   const double&, double*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgetrf, DGETRF) (const octave_idx_type&, const octave_idx_type&, double*, const octave_idx_type&,
+		      octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgetrs, DGETRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, const octave_idx_type&, 
+			     const double*, const octave_idx_type&,
+			     const octave_idx_type*, double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgetri, DGETRI) (const octave_idx_type&, double*, const octave_idx_type&, const octave_idx_type*,
+			     double*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgecon, DGECON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, double*, 
+			     const octave_idx_type&, const double&, double&, 
+			     double*, octave_idx_type*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgelsy, DGELSY) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     double*, const octave_idx_type&, double*,
+			     const octave_idx_type&, octave_idx_type*, double&, octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgelsd, DGELSD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     double*, const octave_idx_type&, double*,
+			     const octave_idx_type&, double*, double&, octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dpotrf, DPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     double *, const octave_idx_type&, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpocon, DPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     double*, const octave_idx_type&, const double&,
+			     double&, double*, octave_idx_type*,
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (dpotrs, DPOTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const double*, 
+			     const octave_idx_type&, double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dtrtri, DTRTRI) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (dtrcon, DTRCON) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const double*, const octave_idx_type&, double&,
+			     double*, octave_idx_type*, octave_idx_type& 
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (dtrtrs, DTRTRS) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const double*, 
+			     const octave_idx_type&, double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  // Note that the original complex fft routines were not written for
+  // double complex arguments.  They have been modified by adding an
+  // implicit double precision (a-h,o-z) statement at the beginning of
+  // each subroutine.
+
+  F77_RET_T
+  F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*);
+
+  F77_RET_T
+  F77_FUNC (dlartg, DLARTG) (const double&, const double&, double&,
+			     double&, double&);
+
+  F77_RET_T
+  F77_FUNC (dtrsyl, DTRSYL) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     const double*, const octave_idx_type&, const double*,
+			     const octave_idx_type&, const double*, const octave_idx_type&,
+			     double&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xdlange, XDLANGE) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			       const octave_idx_type&, const double*,
+			       const octave_idx_type&, double*, double&
+			       F77_CHAR_ARG_LEN_DECL); 
+}
+
+// Matrix class.
+
+Matrix::Matrix (const RowVector& rv)
+  : MArray2<double> (Array2<double> (rv, 1, rv.length ()))
+{
+}
+
+Matrix::Matrix (const ColumnVector& cv)
+  : MArray2<double> (Array2<double> (cv, cv.length (), 1))
+{
+}
+
+Matrix::Matrix (const DiagMatrix& a)
+  : MArray2<double> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+Matrix::Matrix (const PermMatrix& a)
+  : MArray2<double> (a.rows (), a.cols (), 0.0)
+{
+  const Array<octave_idx_type> ia (a.pvec ());
+  octave_idx_type len = a.rows ();
+  if (a.is_col_perm ())
+    for (octave_idx_type i = 0; i < len; i++)
+      elem (ia(i), i) = 1.0;
+  else
+    for (octave_idx_type i = 0; i < len; i++)
+      elem (i, ia(i)) = 1.0;
+}
+
+// FIXME -- could we use a templated mixed-type copy function
+// here?
+
+Matrix::Matrix (const boolMatrix& a)
+  : MArray2<double> (a.rows (), a.cols ())
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = a.elem (i, j);
+}
+
+Matrix::Matrix (const charMatrix& a)
+  : MArray2<double> (a.rows (), a.cols ())
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = static_cast<unsigned char> (a.elem (i, j));
+}
+
+bool
+Matrix::operator == (const Matrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return false;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+Matrix::operator != (const Matrix& a) const
+{
+  return !(*this == a);
+}
+
+bool
+Matrix::is_symmetric (void) const
+{
+  if (is_square () && rows () > 0)
+    {
+      for (octave_idx_type i = 0; i < rows (); i++)
+	for (octave_idx_type j = i+1; j < cols (); j++)
+	  if (elem (i, j) != elem (j, i))
+	    return false;
+
+      return true;
+    }
+
+  return false;
+}
+
+Matrix&
+Matrix::insert (const Matrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Array2<double>::insert (a, r, c);
+  return *this;
+}
+
+Matrix&
+Matrix::insert (const RowVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r, c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+Matrix&
+Matrix::insert (const ColumnVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c) = a.elem (i);
+    }
+
+  return *this;
+}
+
+Matrix&
+Matrix::insert (const DiagMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
+
+  octave_idx_type a_len = a.length ();
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c+i) = a.elem (i, i);
+    }
+
+  return *this;
+}
+
+Matrix&
+Matrix::fill (double val)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+Matrix&
+Matrix::fill (double val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
+      || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (r2 >= r1 && c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = c1; j <= c2; j++)
+	for (octave_idx_type i = r1; i <= r2; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+Matrix
+Matrix::append (const Matrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return Matrix ();
+    }
+
+  octave_idx_type nc_insert = nc;
+  Matrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+Matrix
+Matrix::append (const RowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != 1)
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return Matrix ();
+    }
+
+  octave_idx_type nc_insert = nc;
+  Matrix retval (nr, nc + a.length ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+Matrix
+Matrix::append (const ColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.length ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return Matrix ();
+    }
+
+  octave_idx_type nc_insert = nc;
+  Matrix retval (nr, nc + 1);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+Matrix
+Matrix::append (const DiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  Matrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+Matrix
+Matrix::stack (const Matrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  Matrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+Matrix
+Matrix::stack (const RowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  Matrix retval (nr + 1, nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+Matrix
+Matrix::stack (const ColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != 1)
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  Matrix retval (nr + a.length (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+Matrix
+Matrix::stack (const DiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  Matrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+Matrix
+real (const ComplexMatrix& a)
+{
+  return Matrix (mx_inline_real_dup (a.data (), a.length ()),
+                 a.rows (), a.cols ());
+}
+
+Matrix
+imag (const ComplexMatrix& a)
+{
+  return Matrix (mx_inline_imag_dup (a.data (), a.length ()),
+                 a.rows (), a.cols ());
+}
+
+Matrix
+Matrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  Matrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+Matrix
+Matrix::extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const
+{
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+RowVector
+Matrix::row (octave_idx_type i) const
+{
+  return MArray<double> (index (idx_vector (i), idx_vector::colon));
+}
+
+ColumnVector
+Matrix::column (octave_idx_type i) const
+{
+  return MArray<double> (index (idx_vector::colon, idx_vector (i)));
+}
+
+Matrix
+Matrix::inverse (void) const
+{
+  octave_idx_type info;
+  double rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+Matrix
+Matrix::inverse (octave_idx_type& info) const
+{
+  double rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+Matrix
+Matrix::inverse (octave_idx_type& info, double& rcon, int force,
+		 int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, force, calc_cond);
+}
+
+Matrix
+Matrix::inverse (MatrixType& mattype) const
+{
+  octave_idx_type info;
+  double rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+Matrix
+Matrix::inverse (MatrixType &mattype, octave_idx_type& info) const
+{
+  double rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+Matrix
+Matrix::tinverse (MatrixType &mattype, octave_idx_type& info, double& rcon, 
+		  int force, int calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr == 0 || nc == 0)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      int typ = mattype.type ();
+      char uplo = (typ == MatrixType::Lower ? 'L' : 'U');
+      char udiag = 'N';
+      retval = *this;
+      double *tmp_data = retval.fortran_vec ();
+
+      F77_XFCN (dtrtri, DTRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+				 F77_CONST_CHAR_ARG2 (&udiag, 1),
+				 nr, tmp_data, nr, info 
+				 F77_CHAR_ARG_LEN (1)
+				 F77_CHAR_ARG_LEN (1)));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  octave_idx_type dtrcon_info = 0;
+	  char job = '1';
+
+	  OCTAVE_LOCAL_BUFFER (double, work, 3 * nr);
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, nr);
+
+	  F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     F77_CONST_CHAR_ARG2 (&uplo, 1),
+				     F77_CONST_CHAR_ARG2 (&udiag, 1),
+				     nr, tmp_data, nr, rcon, 
+				     work, iwork, dtrcon_info 
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (dtrcon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this; // Restore matrix contents.
+    }
+
+  return retval;
+}
+
+
+Matrix
+Matrix::finverse (MatrixType &mattype, octave_idx_type& info, double& rcon, 
+		  int force, int calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr == 0 || nc == 0)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      Array<octave_idx_type> ipvt (nr);
+      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+      retval = *this;
+      double *tmp_data = retval.fortran_vec ();
+
+      Array<double> z(1);
+      octave_idx_type lwork = -1;
+
+      // Query the optimum work array size.
+      F77_XFCN (dgetri, DGETRI, (nc, tmp_data, nr, pipvt, 
+				 z.fortran_vec (), lwork, info));
+
+      lwork = static_cast<octave_idx_type> (z(0));
+      lwork = (lwork < 2 *nc ? 2*nc : lwork);
+      z.resize (lwork);
+      double *pz = z.fortran_vec ();
+
+      info = 0;
+
+      // Calculate the norm of the matrix, for later use.
+      double anorm = 0;
+      if (calc_cond) 
+	anorm = retval.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+      F77_XFCN (dgetrf, DGETRF, (nc, nc, tmp_data, nr, pipvt, info));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  octave_idx_type dgecon_info = 0;
+
+	  // Now calculate the condition number for non-singular matrix.
+	  char job = '1';
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+	  F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nc, tmp_data, nr, anorm, 
+				     rcon, pz, piz, dgecon_info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (dgecon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this; // Restore matrix contents.
+      else
+	{
+	  octave_idx_type dgetri_info = 0;
+
+	  F77_XFCN (dgetri, DGETRI, (nc, tmp_data, nr, pipvt,
+				     pz, lwork, dgetri_info));
+
+	  if (dgetri_info != 0) 
+	    info = -1;
+	}
+
+      if (info != 0)
+	mattype.mark_as_rectangular();
+    }
+
+  return retval;
+}
+
+Matrix
+Matrix::inverse (MatrixType &mattype, octave_idx_type& info, double& rcon, 
+		 int force, int calc_cond) const
+{
+  int typ = mattype.type (false);
+  Matrix ret;
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Upper || typ == MatrixType::Lower)
+    ret = tinverse (mattype, info, rcon, force, calc_cond);
+  else
+    {
+      if (mattype.is_hermitian ())
+	{
+	  CHOL chol (*this, info, calc_cond);
+	  if (info == 0)
+	    {
+	      if (calc_cond)
+		rcon = chol.rcond ();
+	      else
+		rcon = 1.0;
+	      ret = chol.inverse ();
+	    }
+	  else
+	    mattype.mark_as_unsymmetric ();
+	}
+
+      if (!mattype.is_hermitian ())
+	ret = finverse(mattype, info, rcon, force, calc_cond);
+
+      if ((mattype.is_hermitian () || calc_cond) && rcon == 0.)
+	ret = Matrix (rows (), columns (), octave_Inf);
+    }
+
+  return ret;
+}
+
+Matrix
+Matrix::pseudo_inverse (double tol) const
+{
+  SVD result (*this, SVD::economy);
+
+  DiagMatrix S = result.singular_values ();
+  Matrix U = result.left_singular_matrix ();
+  Matrix V = result.right_singular_matrix ();
+
+  ColumnVector sigma = S.diag ();
+
+  octave_idx_type r = sigma.length () - 1;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (tol <= 0.0)
+    {
+      if (nr > nc)
+	tol = nr * sigma.elem (0) * DBL_EPSILON;
+      else
+	tol = nc * sigma.elem (0) * DBL_EPSILON;
+    }
+
+  while (r >= 0 && sigma.elem (r) < tol)
+    r--;
+
+  if (r < 0)
+    return Matrix (nc, nr, 0.0);
+  else
+    {
+      Matrix Ur = U.extract (0, 0, nr-1, r);
+      DiagMatrix D = DiagMatrix (sigma.extract (0, r)) . inverse ();
+      Matrix Vr = V.extract (0, 0, nc-1, r);
+      return Vr * D * Ur.transpose ();
+    }
+}
+
+#if defined (HAVE_FFTW3)
+
+ComplexMatrix
+Matrix::fourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  const double *in (fortran_vec ());
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::fft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::ifourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  ComplexMatrix tmp (*this);
+  Complex *in (tmp.fortran_vec ());
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::ifft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::fourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  const double *in = fortran_vec ();
+  ComplexMatrix retval (rows (), cols ());
+  octave_fftw::fftNd (in, retval.fortran_vec (), 2, dv);
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::ifourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  ComplexMatrix retval (*this);
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (out, out, 2, dv);
+
+  return retval;
+}
+
+#else
+
+ComplexMatrix
+Matrix::fourier (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = ComplexMatrix (*this);
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftf, ZFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::ifourier (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = ComplexMatrix (*this);
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftb, ZFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<double> (npts);
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::fourier2d (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = ComplexMatrix (*this);
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftf, ZFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<Complex> tmp (npts);
+  Complex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i];
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::ifourier2d (void) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  retval = ComplexMatrix (*this);
+  Complex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (zfftb, ZFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<double> (npts);
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<Complex> tmp (npts);
+  Complex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i] / static_cast<double> (npts);
+    }
+
+  return retval;
+}
+
+#endif
+
+DET
+Matrix::determinant (void) const
+{
+  octave_idx_type info;
+  double rcon;
+  return determinant (info, rcon, 0);
+}
+
+DET
+Matrix::determinant (octave_idx_type& info) const
+{
+  double rcon;
+  return determinant (info, rcon, 0);
+}
+
+DET
+Matrix::determinant (octave_idx_type& info, double& rcon, int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return determinant (mattype, info, rcon, calc_cond);
+}
+
+DET
+Matrix::determinant (MatrixType& mattype,
+                     octave_idx_type& info, double& rcon, int calc_cond) const
+{
+  DET retval (1.0);
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+        typ = mattype.type (*this);
+
+      if (typ == MatrixType::Lower || typ == MatrixType::Upper)
+        {
+          for (octave_idx_type i = 0; i < nc; i++) 
+            retval *= elem (i,i);
+        }
+      else if (typ == MatrixType::Hermitian)
+        {
+          Matrix atmp = *this;
+          double *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+          double anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+
+          char job = 'L';
+          F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+                                     tmp_data, nr, info
+                                     F77_CHAR_ARG_LEN (1)));
+
+          if (info != 0) 
+            {
+              rcon = 0.0;
+              mattype.mark_as_unsymmetric ();
+              typ = MatrixType::Full;
+            }
+          else 
+            {
+              Array<double> z (3 * nc);
+              double *pz = z.fortran_vec ();
+              Array<octave_idx_type> iz (nc);
+              octave_idx_type *piz = iz.fortran_vec ();
+
+              F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                         nr, tmp_data, nr, anorm,
+                                         rcon, pz, piz, info
+                                         F77_CHAR_ARG_LEN (1)));
+
+              if (info != 0) 
+                rcon = 0.0;
+
+              for (octave_idx_type i = 0; i < nc; i++) 
+                retval *= atmp (i,i);
+
+              retval = retval.square ();
+            }
+        }
+      else if (typ != MatrixType::Full)
+        (*current_liboctave_error_handler) ("det: invalid dense matrix type");
+
+      if (typ == MatrixType::Full)
+        {
+          Array<octave_idx_type> ipvt (nr);
+          octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+          Matrix atmp = *this;
+          double *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+
+          // Calculate the norm of the matrix, for later use.
+          double anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+          F77_XFCN (dgetrf, DGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+          // Throw-away extra info LAPACK gives so as to not change output.
+          rcon = 0.0;
+          if (info != 0) 
+            {
+              info = -1;
+              retval = DET ();
+            } 
+          else 
+            {
+              if (calc_cond) 
+                {
+                  // Now calc the condition number for non-singular matrix.
+                  char job = '1';
+                  Array<double> z (4 * nc);
+                  double *pz = z.fortran_vec ();
+                  Array<octave_idx_type> iz (nc);
+                  octave_idx_type *piz = iz.fortran_vec ();
+
+                  F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                             nc, tmp_data, nr, anorm, 
+                                             rcon, pz, piz, info
+                                             F77_CHAR_ARG_LEN (1)));
+                }
+
+              if (info != 0) 
+                {
+                  info = -1;
+                  retval = DET ();
+                } 
+              else 
+                {
+                  for (octave_idx_type i = 0; i < nc; i++) 
+                    {
+                      double c = atmp(i,i);
+                      retval *= (ipvt(i) != (i+1)) ? -c : c;
+                    }
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+double
+Matrix::rcond (void) const
+{
+  MatrixType mattype (*this);
+  return rcond (mattype);
+}
+
+double
+Matrix::rcond (MatrixType &mattype) const
+{
+  double rcon;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else if (nr == 0 || nc == 0)
+    rcon = octave_Inf;
+  else
+    {
+      int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+	typ = mattype.type (*this);
+
+      // Only calculate the condition number for LU/Cholesky
+      if (typ == MatrixType::Upper)
+	{
+	  const double *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'U';
+	  char dia = 'N';
+
+	  Array<double> z (3 * nc);
+	  double *pz = z.fortran_vec ();
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+
+	  F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, piz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0.0;
+	}
+      else if  (typ == MatrixType::Permuted_Upper)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Lower)
+	{
+	  const double *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'L';
+	  char dia = 'N';
+
+	  Array<double> z (3 * nc);
+	  double *pz = z.fortran_vec ();
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+
+	  F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, piz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0.0;
+	}
+      else if (typ == MatrixType::Permuted_Lower)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+	{
+	  double anorm = -1.0;
+	  Matrix atmp = *this;
+	  double *tmp_data = atmp.fortran_vec ();
+
+	  if (typ == MatrixType::Hermitian)
+	    {
+	      octave_idx_type info = 0;
+	      char job = 'L';
+	      anorm = atmp.abs().sum().
+		row(static_cast<octave_idx_type>(0)).max();
+
+	      F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+					 tmp_data, nr, info
+					 F77_CHAR_ARG_LEN (1)));
+
+	      if (info != 0) 
+		{
+		  rcon = 0.0;
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}
+	      else 
+		{
+		  Array<double> z (3 * nc);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+
+	  if (typ == MatrixType::Full)
+	    {
+	      octave_idx_type info = 0;
+
+	      Array<octave_idx_type> ipvt (nr);
+	      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	      if(anorm < 0.)
+		anorm = atmp.abs().sum().
+		  row(static_cast<octave_idx_type>(0)).max();
+
+	      Array<double> z (4 * nc);
+	      double *pz = z.fortran_vec ();
+	      Array<octave_idx_type> iz (nc);
+	      octave_idx_type *piz = iz.fortran_vec ();
+
+	      F77_XFCN (dgetrf, DGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	      if (info != 0) 
+		{
+		  rcon = 0.0;
+		  mattype.mark_as_rectangular ();
+		}
+	      else 
+		{
+		  char job = '1';
+		  F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+	}
+      else
+	rcon = 0.0;
+    }
+
+  return rcon;
+}
+
+Matrix
+Matrix::utsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& info,
+		double& rcon, solve_singularity_handler sing_handler,
+		bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const double *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'U';
+		  char dia = 'N';
+
+		  Array<double> z (3 * nc);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, piz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  double *result = retval.fortran_vec ();
+
+		  char uplo = 'U';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+Matrix::ltsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& info,
+		double& rcon, solve_singularity_handler sing_handler,
+		bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const double *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'L';
+		  char dia = 'N';
+
+		  Array<double> z (3 * nc);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, piz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  double *result = retval.fortran_vec ();
+
+		  char uplo = 'L';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+Matrix::fsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& info,
+		double& rcon, solve_singularity_handler sing_handler,
+		bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      volatile int typ = mattype.type ();
+ 
+     // Calculate the norm of the matrix, for later use.
+      double anorm = -1.;
+
+      if (typ == MatrixType::Hermitian)
+	{
+	  info = 0;
+	  char job = 'L';
+	  Matrix atmp = *this;
+	  double *tmp_data = atmp.fortran_vec ();
+	  anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+				     tmp_data, nr, info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    {
+	      info = -2;
+
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<double> z (3 * nc);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  double *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  F77_XFCN (dpotrs, DPOTRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	      else
+		{
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}		    
+	    }
+	}
+
+      if (typ == MatrixType::Full)
+	{
+	  info = 0;
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  Matrix atmp = *this;
+	  double *tmp_data = atmp.fortran_vec ();
+	  if(anorm < 0.)
+	    anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  Array<double> z (4 * nc);
+	  double *pz = z.fortran_vec ();
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+
+	  F77_XFCN (dgetrf, DGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    {
+	      info = -2;
+
+	      if (sing_handler)
+		sing_handler (rcon);
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	      mattype.mark_as_rectangular ();
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  // Now calculate the condition number for 
+		  // non-singular matrix.
+		  char job = '1';
+		  F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile double rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  double *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  char job = 'N';
+		  F77_XFCN (dgetrs, DGETRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     pipvt, result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	      else
+		mattype.mark_as_rectangular ();
+	    }
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+Matrix::solve (MatrixType &typ, const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+Matrix
+Matrix::solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+	       double& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+Matrix
+Matrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& info,
+	       double& rcon, solve_singularity_handler sing_handler,
+	       bool singular_fallback) const
+{
+  Matrix retval;
+  int typ = mattype.type ();
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  // Only calculate the condition number for LU/Cholesky
+  if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, info, rcon, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return Matrix ();
+    }
+
+  // Rectangular or one of the above solvers flags a singular matrix
+  if (singular_fallback && mattype.type () == MatrixType::Rectangular)
+    {
+      octave_idx_type rank;
+      retval = lssolve (b, info, rank, rcon);
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::solve (MatrixType &typ, const ComplexMatrix& b) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b);
+}
+
+ComplexMatrix
+Matrix::solve (MatrixType &typ, const ComplexMatrix& b, 
+  octave_idx_type& info) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info);
+}
+
+ComplexMatrix
+Matrix::solve (MatrixType &typ, const ComplexMatrix& b, octave_idx_type& info,
+	       double& rcon) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info, rcon);
+}
+
+ComplexMatrix
+Matrix::solve (MatrixType &typ, const ComplexMatrix& b, octave_idx_type& info,
+	       double& rcon, solve_singularity_handler sing_handler,
+	       bool singular_fallback) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info, rcon, sing_handler, singular_fallback);
+}
+
+ColumnVector
+Matrix::solve (MatrixType &typ, const ColumnVector& b) const
+{
+  octave_idx_type info; double rcon;
+  return solve (typ, b, info, rcon);
+}
+
+ColumnVector
+Matrix::solve (MatrixType &typ, const ColumnVector& b, 
+	       octave_idx_type& info) const
+{
+  double rcon;
+  return solve (typ, b, info, rcon);
+}
+
+ColumnVector
+Matrix::solve (MatrixType &typ, const ColumnVector& b, octave_idx_type& info,
+	       double& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+ColumnVector
+Matrix::solve (MatrixType &typ, const ColumnVector& b, octave_idx_type& info,
+	       double& rcon, solve_singularity_handler sing_handler) const
+{
+  Matrix tmp (b);
+  return solve (typ, tmp, info, rcon, sing_handler).column(static_cast<octave_idx_type> (0));
+}
+
+ComplexColumnVector
+Matrix::solve (MatrixType &typ, const ComplexColumnVector& b) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b);
+}
+
+ComplexColumnVector
+Matrix::solve (MatrixType &typ, const ComplexColumnVector& b, 
+	       octave_idx_type& info) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info);
+}
+
+ComplexColumnVector
+Matrix::solve (MatrixType &typ, const ComplexColumnVector& b, 
+	       octave_idx_type& info, double& rcon) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info, rcon);
+}
+
+ComplexColumnVector
+Matrix::solve (MatrixType &typ, const ComplexColumnVector& b, 
+	       octave_idx_type& info, double& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve(typ, b, info, rcon, sing_handler);
+}
+
+Matrix
+Matrix::solve (const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+Matrix
+Matrix::solve (const Matrix& b, octave_idx_type& info) const
+{
+  double rcon;
+  return solve (b, info, rcon, 0);
+}
+
+Matrix
+Matrix::solve (const Matrix& b, octave_idx_type& info, double& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+Matrix
+Matrix::solve (const Matrix& b, octave_idx_type& info,
+	       double& rcon, solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+ComplexMatrix
+Matrix::solve (const ComplexMatrix& b) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b);
+}
+
+ComplexMatrix
+Matrix::solve (const ComplexMatrix& b, octave_idx_type& info) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b, info);
+}
+
+ComplexMatrix
+Matrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon);
+}
+
+ComplexMatrix
+Matrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon, sing_handler);
+}
+
+ColumnVector
+Matrix::solve (const ColumnVector& b) const
+{
+  octave_idx_type info; double rcon;
+  return solve (b, info, rcon);
+}
+
+ColumnVector
+Matrix::solve (const ColumnVector& b, octave_idx_type& info) const
+{
+  double rcon;
+  return solve (b, info, rcon);
+}
+
+ColumnVector
+Matrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+ColumnVector
+Matrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+ComplexColumnVector
+Matrix::solve (const ComplexColumnVector& b) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b);
+}
+
+ComplexColumnVector
+Matrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b, info);
+}
+
+ComplexColumnVector
+Matrix::solve (const ComplexColumnVector& b, octave_idx_type& info, double& rcon) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon);
+}
+
+ComplexColumnVector
+Matrix::solve (const ComplexColumnVector& b, octave_idx_type& info, double& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon, sing_handler);
+}
+
+Matrix
+Matrix::lssolve (const Matrix& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+Matrix
+Matrix::lssolve (const Matrix& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+Matrix
+Matrix::lssolve (const Matrix& b, octave_idx_type& info,
+		 octave_idx_type& rank) const
+{
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+Matrix
+Matrix::lssolve (const Matrix& b, octave_idx_type& info,
+		 octave_idx_type& rank, double &rcon) const
+{
+  Matrix retval;
+
+  octave_idx_type nrhs = b.cols ();
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m == 0 || n == 0 || b.cols () == 0)
+    retval = Matrix (n, b.cols (), 0.0);
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+      if (m != n)
+	{
+	  retval = Matrix (maxmn, nrhs, 0.0);
+
+	  for (octave_idx_type j = 0; j < nrhs; j++)
+	    for (octave_idx_type i = 0; i < m; i++)
+	      retval.elem (i, j) = b.elem (i, j);
+	}
+      else
+	retval = b;
+
+      Matrix atmp = *this;
+      double *tmp_data = atmp.fortran_vec ();
+
+      double *pretval = retval.fortran_vec ();
+      Array<double> s (minmn);
+      double *ps = s.fortran_vec ();
+
+      // Ask DGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<double> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("DGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      octave_idx_type mnthr;
+      F77_FUNC (xilaenv, XILAENV) (6, F77_CONST_CHAR_ARG2 ("DGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   m, n, nrhs, -1, mnthr
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of iwork because DGELSD in older versions
+      // of LAPACK does not return it on a query call.
+      double dminmn = static_cast<double> (minmn);
+      double dsmlsizp1 = static_cast<double> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      double tmp = log2 (dminmn / dsmlsizp1);
+#else
+      double tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, piwork, info));
+
+      // The workspace query is broken in at least LAPACK 3.0.0
+      // through 3.1.1 when n >= mnthr.  The obtuse formula below
+      // should provide sufficient workspace for DGELSD to operate
+      // efficiently.
+      if (n >= mnthr)
+	{
+	  const octave_idx_type wlalsd
+	    = 9*m + 2*m*smlsiz + 8*m*nlvl + m*nrhs + (smlsiz+1)*(smlsiz+1);
+
+	  octave_idx_type addend = m;
+
+	  if (2*m-4 > addend)
+	    addend = 2*m-4;
+
+	  if (nrhs > addend)
+	    addend = nrhs;
+
+	  if (n-3*m > addend)
+	    addend = n-3*m;
+
+	  if (wlalsd > addend)
+	    addend = wlalsd;
+
+	  const octave_idx_type lworkaround = 4*m + m*m + addend;
+
+	  if (work(0) < lworkaround)
+	    work(0) = lworkaround;
+	}
+      else if (m >= n)
+	{
+	  octave_idx_type lworkaround
+	    = 12*n + 2*n*smlsiz + 8*n*nlvl + n*nrhs + (smlsiz+1)*(smlsiz+1);
+
+	  if (work(0) < lworkaround)
+	    work(0) = lworkaround;
+	}
+
+      lwork = static_cast<octave_idx_type> (work(0));
+      work.resize (lwork);
+
+      F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 piwork, info));
+
+      if (rank < minmn)
+	(*current_liboctave_warning_handler) 
+	  ("dgelsd: rank deficient %dx%d matrix, rank = %d", m, n, rank);
+      if (s.elem (0) == 0.0)
+	rcon = 0.0;
+      else
+	rcon = s.elem (minmn - 1) / s.elem (0);
+
+      retval.resize (n, nrhs);
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+Matrix::lssolve (const ComplexMatrix& b) const
+{
+  ComplexMatrix tmp (*this);
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ComplexMatrix
+Matrix::lssolve (const ComplexMatrix& b, octave_idx_type& info) const
+{
+  ComplexMatrix tmp (*this);
+  octave_idx_type rank;
+  double rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ComplexMatrix
+Matrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, 
+		 octave_idx_type& rank) const
+{
+  ComplexMatrix tmp (*this);
+  double rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ComplexMatrix
+Matrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, 
+		 octave_idx_type& rank, double& rcon) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ColumnVector
+Matrix::lssolve (const ColumnVector& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ColumnVector
+Matrix::lssolve (const ColumnVector& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ColumnVector
+Matrix::lssolve (const ColumnVector& b, octave_idx_type& info,
+		 octave_idx_type& rank) const
+{
+  double rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+ColumnVector
+Matrix::lssolve (const ColumnVector& b, octave_idx_type& info,
+		 octave_idx_type& rank, double &rcon) const
+{
+  ColumnVector retval;
+
+  octave_idx_type nrhs = 1;
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.length ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m == 0 || n == 0)
+    retval = ColumnVector (n, 0.0);
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+ 
+      if (m != n)
+	{
+	  retval = ColumnVector (maxmn, 0.0);
+
+	  for (octave_idx_type i = 0; i < m; i++)
+	    retval.elem (i) = b.elem (i);
+	}
+      else
+	retval = b;
+
+      Matrix atmp = *this;
+      double *tmp_data = atmp.fortran_vec ();
+
+      double *pretval = retval.fortran_vec ();
+      Array<double> s (minmn);
+      double *ps = s.fortran_vec ();
+
+      // Ask DGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<double> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("DGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of iwork because DGELSD in older versions
+      // of LAPACK does not return it on a query call.
+      double dminmn = static_cast<double> (minmn);
+      double dsmlsizp1 = static_cast<double> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      double tmp = log2 (dminmn / dsmlsizp1);
+#else
+      double tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, piwork, info));
+
+      lwork = static_cast<octave_idx_type> (work(0));
+      work.resize (lwork);
+
+      F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 piwork, info));
+
+      if (rank < minmn)
+	{
+	  if (rank < minmn)
+	    (*current_liboctave_warning_handler) 
+	      ("dgelsd: rank deficient %dx%d matrix, rank = %d", m, n, rank);
+	  if (s.elem (0) == 0.0)
+	    rcon = 0.0;
+	  else
+	    rcon = s.elem (minmn - 1) / s.elem (0);
+	}
+
+      retval.resize (n, nrhs);
+    }
+
+  return retval;
+}
+
+ComplexColumnVector
+Matrix::lssolve (const ComplexColumnVector& b) const
+{
+  ComplexMatrix tmp (*this);
+  octave_idx_type info;
+  octave_idx_type rank;
+  double rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ComplexColumnVector
+Matrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  ComplexMatrix tmp (*this);
+  octave_idx_type rank;
+  double rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ComplexColumnVector
+Matrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, 
+		 octave_idx_type& rank) const
+{
+  ComplexMatrix tmp (*this);
+  double rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+ComplexColumnVector
+Matrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, 
+		 octave_idx_type& rank, double &rcon) const
+{
+  ComplexMatrix tmp (*this);
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+Matrix&
+Matrix::operator += (const DiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+Matrix&
+Matrix::operator -= (const DiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+// unary operations
+
+boolMatrix
+Matrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  boolMatrix b (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      b.elem (i, j) = ! elem (i, j);
+
+  return b;
+}
+
+// column vector by row vector -> matrix operations
+
+Matrix
+operator * (const ColumnVector& v, const RowVector& a)
+{
+  Matrix retval;
+
+  octave_idx_type len = v.length ();
+
+  if (len != 0)
+    {
+      octave_idx_type a_len = a.length ();
+
+      retval = Matrix (len, a_len);
+      double *c = retval.fortran_vec ();
+	  
+      F77_XFCN (dgemm, DGEMM, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 ("N", 1),
+			       len, a_len, 1, 1.0, v.data (), len,
+			       a.data (), 1, 0.0, c, len
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+    }
+
+  return retval;
+}
+
+// other operations.
+
+Matrix
+Matrix::map (dmapper fcn) const
+{
+  return MArray2<double>::map<double> (func_ptr (fcn));
+}
+
+ComplexMatrix
+Matrix::map (cmapper fcn) const
+{
+  return MArray2<double>::map<Complex> (func_ptr (fcn));
+}
+
+boolMatrix
+Matrix::map (bmapper fcn) const
+{
+  return MArray2<double>::map<bool> (func_ptr (fcn));
+}
+
+bool
+Matrix::any_element_is_negative (bool neg_zero) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (neg_zero)
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (lo_ieee_signbit (elem (i)))
+	  return true;
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (elem (i) < 0)
+	  return true;
+    }
+
+  return false;
+}
+
+bool
+Matrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+Matrix::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+Matrix::any_element_not_one_or_zero (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (val != 0 && val != 1)
+	return true;
+    }
+
+  return false;
+}
+
+bool
+Matrix::all_elements_are_int_or_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisnan (val) || D_NINT (val) == val)
+	continue;
+      else
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of M is not an integer.  Also extract
+// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
+
+bool
+Matrix::all_integers (double& max_val, double& min_val) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (nel > 0)
+    {
+      max_val = elem (0);
+      min_val = elem (0);
+    }
+  else
+    return false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+
+      if (val > max_val)
+	max_val = val;
+
+      if (val < min_val)
+	min_val = val;
+
+      if (D_NINT (val) != val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+Matrix::too_large_for_float (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+
+      if (! (xisnan (val) || xisinf (val))
+	  && fabs (val) > FLT_MAX)
+	return true;
+    }
+
+  return false;
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+boolMatrix
+Matrix::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, double> (*this, dim, mx_inline_all);
+}
+
+boolMatrix
+Matrix::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, double> (*this, dim, mx_inline_any);
+}
+
+Matrix
+Matrix::cumprod (int dim) const
+{
+  return do_mx_cum_op<Matrix, double> (*this, dim, mx_inline_cumprod);
+}
+
+Matrix
+Matrix::cumsum (int dim) const
+{
+  return do_mx_cum_op<Matrix, double> (*this, dim, mx_inline_cumsum);
+}
+
+Matrix
+Matrix::prod (int dim) const
+{
+  return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_prod);
+}
+
+Matrix
+Matrix::sum (int dim) const
+{
+  return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_sum);
+}
+
+Matrix
+Matrix::sumsq (int dim) const
+{
+  return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_sumsq);
+}
+
+Matrix
+Matrix::abs (void) const
+{
+  return Matrix (mx_inline_fabs_dup (data (), length ()),
+                 rows (), cols ());
+}
+
+Matrix
+Matrix::diag (octave_idx_type k) const
+{
+  return MArray2<double>::diag (k);
+}
+
+ColumnVector
+Matrix::row_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_min (dummy_idx);
+}
+
+ColumnVector
+Matrix::row_min (Array<octave_idx_type>& idx_arg) const
+{
+  ColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  octave_idx_type idx_j;
+
+	  double tmp_min = octave_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_min = elem (i, idx_j);
+
+	      if (! xisnan (tmp_min))
+		break;
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      double tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp < tmp_min)
+		{
+		  idx_j = j;
+		  tmp_min = tmp;
+		}
+	    }
+
+	  result.elem (i) = tmp_min;
+	  idx_arg.elem (i) = xisnan (tmp_min) ? 0 : idx_j;
+        }
+    }
+
+  return result;
+}
+
+ColumnVector
+Matrix::row_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_max (dummy_idx);
+}
+
+ColumnVector
+Matrix::row_max (Array<octave_idx_type>& idx_arg) const
+{
+  ColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  octave_idx_type idx_j;
+
+	  double tmp_max = octave_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_max = elem (i, idx_j);
+
+	      if (! xisnan (tmp_max))
+		break;
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      double tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp > tmp_max)
+		{
+		  idx_j = j;
+		  tmp_max = tmp;
+		}
+	    }
+
+	  result.elem (i) = tmp_max;
+	  idx_arg.elem (i) = xisnan (tmp_max) ? 0 : idx_j;
+        }
+    }
+
+  return result;
+}
+
+RowVector
+Matrix::column_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_min (dummy_idx);
+}
+
+RowVector
+Matrix::column_min (Array<octave_idx_type>& idx_arg) const
+{
+  RowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  octave_idx_type idx_i;
+
+	  double tmp_min = octave_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_min = elem (idx_i, j);
+
+	      if (! xisnan (tmp_min))
+		break;
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      double tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp < tmp_min)
+		{
+		  idx_i = i;
+		  tmp_min = tmp;
+		}
+	    }
+
+	  result.elem (j) = tmp_min;
+	  idx_arg.elem (j) = xisnan (tmp_min) ? 0 : idx_i;
+        }
+    }
+
+  return result;
+}
+
+RowVector
+Matrix::column_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_max (dummy_idx);
+}
+
+RowVector
+Matrix::column_max (Array<octave_idx_type>& idx_arg) const
+{
+  RowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  octave_idx_type idx_i;
+
+	  double tmp_max = octave_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_max = elem (idx_i, j);
+
+	      if (! xisnan (tmp_max))
+		break;
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      double tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp > tmp_max)
+		{
+		  idx_i = i;
+		  tmp_max = tmp;
+		}
+	    }
+
+	  result.elem (j) = tmp_max;
+	  idx_arg.elem (j) = xisnan (tmp_max) ? 0 : idx_i;
+        }
+    }
+
+  return result;
+}
+
+std::ostream&
+operator << (std::ostream& os, const Matrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  os << " ";
+	  octave_write_double (os, a.elem (i, j));
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, Matrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      double tmp;
+      for (octave_idx_type i = 0; i < nr; i++)
+	for (octave_idx_type j = 0; j < nc; j++)
+	  {
+	    tmp = octave_read_double (is);
+	    if (is)
+	      a.elem (i, j) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+ done:
+
+  return is;
+}
+
+Matrix
+Givens (double x, double y)
+{
+  double cc, s, temp_r;
+
+  F77_FUNC (dlartg, DLARTG) (x, y, cc, s, temp_r);
+
+  Matrix g (2, 2);
+
+  g.elem (0, 0) = cc;
+  g.elem (1, 1) = cc;
+  g.elem (0, 1) = s;
+  g.elem (1, 0) = -s;
+
+  return g;
+}
+
+Matrix
+Sylvester (const Matrix& a, const Matrix& b, const Matrix& c)
+{
+  Matrix retval;
+
+  // FIXME -- need to check that a, b, and c are all the same
+  // size.
+
+  // Compute Schur decompositions.
+
+  SCHUR as (a, "U");
+  SCHUR bs (b, "U");
+  
+  // Transform c to new coordinates.
+
+  Matrix ua = as.unitary_matrix ();
+  Matrix sch_a = as.schur_matrix ();
+
+  Matrix ub = bs.unitary_matrix ();
+  Matrix sch_b = bs.schur_matrix ();
+  
+  Matrix cx = ua.transpose () * c * ub;
+  
+  // Solve the sylvester equation, back-transform, and return the
+  // solution.
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type b_nr = b.rows ();
+
+  double scale;
+  octave_idx_type info;
+
+  double *pa = sch_a.fortran_vec ();
+  double *pb = sch_b.fortran_vec ();
+  double *px = cx.fortran_vec ();
+
+  F77_XFCN (dtrsyl, DTRSYL, (F77_CONST_CHAR_ARG2 ("N", 1),
+			     F77_CONST_CHAR_ARG2 ("N", 1),
+			     1, a_nr, b_nr, pa, a_nr, pb,
+			     b_nr, px, a_nr, scale, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+
+  // FIXME -- check info?
+  
+  retval = -ua*cx*ub.transpose ();
+
+  return retval;
+}
+
+// matrix by matrix -> matrix operations
+
+/* Simple Dot Product, Matrix-Vector and Matrix-Matrix Unit tests
+%!assert([1 2 3] * [ 4 ; 5 ; 6], 32, 1e-14)
+%!assert([1 2 ; 3 4 ] * [5 ; 6], [17 ; 39 ], 1e-14)
+%!assert([1 2 ; 3 4 ] * [5 6 ; 7 8], [19 22; 43 50], 1e-14)
+*/
+
+/* Test some simple identities
+%!shared M, cv, rv
+%! M = randn(10,10);
+%! cv = randn(10,1);
+%! rv = randn(1,10);
+%!assert([M*cv,M*cv],M*[cv,cv],1e-14)
+%!assert([M'*cv,M'*cv],M'*[cv,cv],1e-14)
+%!assert([rv*M;rv*M],[rv;rv]*M,1e-14)
+%!assert([rv*M';rv*M'],[rv;rv]*M',1e-14)
+%!assert(2*rv*cv,[rv,rv]*[cv;cv],1e-14)
+*/
+
+static const char *
+get_blas_trans_arg (bool trans)
+{
+  static char blas_notrans = 'N', blas_trans = 'T';
+  return (trans) ? &blas_trans : &blas_notrans;
+}
+
+// the general GEMM operation
+
+Matrix 
+xgemm (bool transa, const Matrix& a, bool transb, const Matrix& b)
+{
+  Matrix retval;
+
+  octave_idx_type a_nr = transa ? a.cols () : a.rows ();
+  octave_idx_type a_nc = transa ? a.rows () : a.cols ();
+
+  octave_idx_type b_nr = transb ? b.cols () : b.rows ();
+  octave_idx_type b_nc = transb ? b.rows () : b.cols ();
+
+  if (a_nc != b_nr)
+    gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+  else
+    {
+      if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+	retval = Matrix (a_nr, b_nc, 0.0);
+      else if (a.data () == b.data () && a_nr == b_nc && transa != transb)
+        {
+	  octave_idx_type lda = a.rows ();
+
+          retval = Matrix (a_nr, b_nc);
+	  double *c = retval.fortran_vec ();
+
+          const char *ctransa = get_blas_trans_arg (transa);
+          F77_XFCN (dsyrk, DSYRK, (F77_CONST_CHAR_ARG2 ("U", 1),
+                                   F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                   a_nr, a_nc, 1.0,
+                                   a.data (), lda, 0.0, c, a_nr
+                                   F77_CHAR_ARG_LEN (1)
+                                   F77_CHAR_ARG_LEN (1)));
+          for (int j = 0; j < a_nr; j++)
+            for (int i = 0; i < j; i++)
+              retval.xelem (j,i) = retval.xelem (i,j);
+
+        }
+      else
+	{
+	  octave_idx_type lda = a.rows (), tda = a.cols ();
+	  octave_idx_type ldb = b.rows (), tdb = b.cols ();
+
+	  retval = Matrix (a_nr, b_nc);
+	  double *c = retval.fortran_vec ();
+
+	  if (b_nc == 1)
+	    {
+	      if (a_nr == 1)
+		F77_FUNC (xddot, XDDOT) (a_nc, a.data (), 1, b.data (), 1, *c);
+	      else
+		{
+                  const char *ctransa = get_blas_trans_arg (transa);
+		  F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+					   lda, tda, 1.0,  a.data (), lda,
+					   b.data (), 1, 0.0, c, 1
+					   F77_CHAR_ARG_LEN (1)));
+		}
+            }
+          else if (a_nr == 1)
+            {
+              const char *crevtransb = get_blas_trans_arg (! transb);
+              F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 (crevtransb, 1),
+                                       ldb, tdb, 1.0,  b.data (), ldb,
+                                       a.data (), 1, 0.0, c, 1
+                                       F77_CHAR_ARG_LEN (1)));
+            }
+	  else
+	    {
+              const char *ctransa = get_blas_trans_arg (transa);
+              const char *ctransb = get_blas_trans_arg (transb);
+	      F77_XFCN (dgemm, DGEMM, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+				       F77_CONST_CHAR_ARG2 (ctransb, 1),
+				       a_nr, b_nc, a_nc, 1.0, a.data (),
+				       lda, b.data (), ldb, 0.0, c, a_nr
+				       F77_CHAR_ARG_LEN (1)
+				       F77_CHAR_ARG_LEN (1)));
+	    }
+	}
+    }
+
+  return retval;
+}
+
+Matrix
+operator * (const Matrix& a, const Matrix& b)
+{
+  return xgemm (false, a, false, b);
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nr == 0 || nc == 0) \
+    return T (nr, nc);
+
+Matrix
+min (double d, const Matrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (Matrix);
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (d, m (i, j));
+      }
+
+  return result;
+}
+
+Matrix
+min (const Matrix& m, double d)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (Matrix);
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (m (i, j), d);
+      }
+
+  return result;
+}
+
+Matrix
+min (const Matrix& a, const Matrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return Matrix ();
+    }
+
+  EMPTY_RETURN_CHECK (Matrix);
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (a (i, j), b (i, j));
+      }
+
+  return result;
+}
+
+Matrix
+max (double d, const Matrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (Matrix);
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (d, m (i, j));
+      }
+
+  return result;
+}
+
+Matrix
+max (const Matrix& m, double d)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (Matrix);
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (m (i, j), d);
+      }
+
+  return result;
+}
+
+Matrix
+max (const Matrix& a, const Matrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return Matrix ();
+    }
+
+  EMPTY_RETURN_CHECK (Matrix);
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (a (i, j), b (i, j));
+      }
+
+  return result;
+}
+
+MS_CMP_OPS(Matrix, , double, )
+MS_BOOL_OPS(Matrix, double, 0.0)
+
+SM_CMP_OPS(double, , Matrix, )
+SM_BOOL_OPS(double, Matrix, 0.0)
+
+MM_CMP_OPS(Matrix, , Matrix, )
+MM_BOOL_OPS(Matrix, Matrix, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dMatrix.h b/liboctave/dMatrix.h
new file mode 100644
index 0000000..c360ac1
--- /dev/null
+++ b/liboctave/dMatrix.h
@@ -0,0 +1,380 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_Matrix_int_h)
+#define octave_Matrix_int_h 1
+
+#include "MArray2.h"
+#include "MDiagArray2.h"
+#include "MatrixType.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+#include "DET.h"
+
+class
+OCTAVE_API
+Matrix : public MArray2<double>
+{
+public:
+
+  typedef void (*solve_singularity_handler) (double rcon);
+
+  Matrix (void) : MArray2<double> () { }
+
+  Matrix (octave_idx_type r, octave_idx_type c) : MArray2<double> (r, c) { }
+
+  Matrix (octave_idx_type r, octave_idx_type c, double val) : MArray2<double> (r, c, val) { }
+
+  Matrix (const dim_vector& dv) : MArray2<double> (dv) { }
+
+  Matrix (const dim_vector& dv, double val) : MArray2<double> (dv, val) { }
+
+  Matrix (const Matrix& a) : MArray2<double> (a) { }
+
+  template <class U>
+  Matrix (const MArray2<U>& a) : MArray2<double> (a) { }
+
+  template <class U>
+  Matrix (const Array2<U>& a) : MArray2<double> (a) { }
+
+  explicit Matrix (const RowVector& rv);
+
+  explicit Matrix (const ColumnVector& cv);
+
+  explicit Matrix (const DiagMatrix& a);
+
+  explicit Matrix (const PermMatrix& a);
+
+  explicit Matrix (const boolMatrix& a);
+
+  explicit Matrix (const charMatrix& a);
+
+  Matrix& operator = (const Matrix& a)
+    {
+      MArray2<double>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const Matrix& a) const;
+  bool operator != (const Matrix& a) const;
+
+  bool is_symmetric (void) const;
+
+  // destructive insert/delete/reorder operations
+
+  Matrix& insert (const Matrix& a, octave_idx_type r, octave_idx_type c);
+  Matrix& insert (const RowVector& a, octave_idx_type r, octave_idx_type c);
+  Matrix& insert (const ColumnVector& a, octave_idx_type r, octave_idx_type c);
+  Matrix& insert (const DiagMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  Matrix& fill (double val);
+  Matrix& fill (double val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+
+  Matrix append (const Matrix& a) const;
+  Matrix append (const RowVector& a) const;
+  Matrix append (const ColumnVector& a) const;
+  Matrix append (const DiagMatrix& a) const;
+
+  Matrix stack (const Matrix& a) const;
+  Matrix stack (const RowVector& a) const;
+  Matrix stack (const ColumnVector& a) const;
+  Matrix stack (const DiagMatrix& a) const;
+
+  friend OCTAVE_API Matrix real (const ComplexMatrix& a);
+  friend OCTAVE_API Matrix imag (const ComplexMatrix& a);
+
+  friend class ComplexMatrix;
+
+  Matrix transpose (void) const { return MArray2<double>::transpose (); }
+
+  // resize is the destructive equivalent for this one
+
+  Matrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  Matrix extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const;
+
+  // extract row or column i.
+
+  RowVector row (octave_idx_type i) const;
+
+  ColumnVector column (octave_idx_type i) const;
+
+private:
+  Matrix tinverse (MatrixType &mattype, octave_idx_type& info, double& rcon, 
+		   int force, int calc_cond) const;
+
+  Matrix finverse (MatrixType &mattype, octave_idx_type& info, double& rcon, 
+		   int force, int calc_cond) const;
+
+public:
+  Matrix inverse (void) const;
+  Matrix inverse (octave_idx_type& info) const;
+  Matrix inverse (octave_idx_type& info, double& rcon, int force = 0,
+		  int calc_cond = 1) const;
+
+  Matrix inverse (MatrixType &mattype) const;
+  Matrix inverse (MatrixType &mattype, octave_idx_type& info) const;
+  Matrix inverse (MatrixType &mattype, octave_idx_type& info, double& rcon,
+		  int force = 0, int calc_cond = 1) const;
+
+  Matrix pseudo_inverse (double tol = 0.0) const;
+
+  ComplexMatrix fourier (void) const;
+  ComplexMatrix ifourier (void) const;
+
+  ComplexMatrix fourier2d (void) const;
+  ComplexMatrix ifourier2d (void) const;
+
+  DET determinant (void) const;
+  DET determinant (octave_idx_type& info) const;
+  DET determinant (octave_idx_type& info, double& rcon, int calc_cond = 1) const;
+  DET determinant (MatrixType &mattype, octave_idx_type& info, 
+                   double& rcon, int calc_cond = 1) const;
+
+  double rcond (void) const;
+  double rcond (MatrixType &mattype) const;
+
+private:
+  // Upper triangular matrix solvers
+  Matrix utsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		  double& rcon, solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Lower triangular matrix solvers
+  Matrix ltsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		  double& rcon, solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Full matrix solvers (lu/cholesky)
+  Matrix fsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		 double& rcon, solve_singularity_handler sing_handler,
+		 bool calc_cond = false) const;
+
+public:
+  // Generic interface to solver with no probing of type
+  Matrix solve (MatrixType &typ, const Matrix& b) const;
+  Matrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info) const;
+  Matrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		double& rcon) const;
+  Matrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcon, solve_singularity_handler sing_handler,
+		bool singular_fallback = true) const;
+
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcon) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcon,
+		       solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b) const;
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info) const;
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info, double& rcon) const;
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (MatrixType &typ, 
+			     const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info, double& rcon) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info, double& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  // Generic interface to solver with probing of type
+  Matrix solve (const Matrix& b) const;
+  Matrix solve (const Matrix& b, octave_idx_type& info) const;
+  Matrix solve (const Matrix& b, octave_idx_type& info, double& rcon) const;
+  Matrix solve (const Matrix& b, octave_idx_type& info, double& rcon,
+		solve_singularity_handler sing_handler) const;
+
+  ComplexMatrix solve (const ComplexMatrix& b) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon,
+		       solve_singularity_handler sing_handler) const;
+
+  ColumnVector solve (const ColumnVector& b) const;
+  ColumnVector solve (const ColumnVector& b, octave_idx_type& info) const;
+  ColumnVector solve (const ColumnVector& b, octave_idx_type& info, double& rcon) const;
+  ColumnVector solve (const ColumnVector& b, octave_idx_type& info, double& rcon,
+		      solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcon) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  // Singular solvers
+  Matrix lssolve (const Matrix& b) const;
+  Matrix lssolve (const Matrix& b, octave_idx_type& info) const;
+  Matrix lssolve (const Matrix& b, octave_idx_type& info, 
+		  octave_idx_type& rank) const;
+  Matrix lssolve (const Matrix& b, octave_idx_type& info, 
+		  octave_idx_type& rank, double& rcon) const;
+
+  ComplexMatrix lssolve (const ComplexMatrix& b) const;
+  ComplexMatrix lssolve (const ComplexMatrix& b, octave_idx_type& info) const;
+  ComplexMatrix lssolve (const ComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank) const;
+  ComplexMatrix lssolve (const ComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank, double &rcon) const;
+
+  ColumnVector lssolve (const ColumnVector& b) const;
+  ColumnVector lssolve (const ColumnVector& b, octave_idx_type& info) const;
+  ColumnVector lssolve (const ColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank) const;
+  ColumnVector lssolve (const ColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank, double& rcon) const;
+
+  ComplexColumnVector lssolve (const ComplexColumnVector& b) const;
+  ComplexColumnVector lssolve (const ComplexColumnVector& b, 
+			       octave_idx_type& info) const;
+  ComplexColumnVector lssolve (const ComplexColumnVector& b,
+			       octave_idx_type& info,
+			       octave_idx_type& rank) const;
+  ComplexColumnVector lssolve (const ComplexColumnVector& b, 
+			       octave_idx_type& info,
+			       octave_idx_type& rank, double& rcon) const;
+
+  Matrix& operator += (const DiagMatrix& a);
+  Matrix& operator -= (const DiagMatrix& a);
+
+  // unary operations
+
+  boolMatrix operator ! (void) const;
+
+  // other operations
+
+  typedef double (*dmapper) (double);
+  typedef Complex (*cmapper) (const Complex&);
+  typedef bool (*bmapper) (double);
+
+  Matrix map (dmapper fcn) const;
+  ComplexMatrix map (cmapper fcn) const;
+  boolMatrix map (bmapper fcn) const;
+
+  bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool any_element_not_one_or_zero (void) const;
+  bool all_elements_are_int_or_inf_or_nan (void) const;
+  bool all_integers (double& max_val, double& min_val) const;
+  bool too_large_for_float (void) const;
+ 
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+  Matrix cumprod (int dim = -1) const;
+  Matrix cumsum (int dim = -1) const;
+  Matrix prod (int dim = -1) const;
+  Matrix sum (int dim = -1) const;
+  Matrix sumsq (int dim = -1) const;
+  Matrix abs (void) const;
+
+  Matrix diag (octave_idx_type k = 0) const;
+
+  ColumnVector row_min (void) const;
+  ColumnVector row_max (void) const;
+
+  ColumnVector row_min (Array<octave_idx_type>& index) const;
+  ColumnVector row_max (Array<octave_idx_type>& index) const;
+
+  RowVector column_min (void) const;
+  RowVector column_max (void) const;
+
+  RowVector column_min (Array<octave_idx_type>& index) const;
+  RowVector column_max (Array<octave_idx_type>& index) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const Matrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, Matrix& a);
+
+  static double resize_fill_value (void) { return 0; }
+
+private:
+
+  Matrix (double *d, octave_idx_type r, octave_idx_type c) : MArray2<double> (d, r, c) { }
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API Matrix real (const ComplexMatrix& a);
+extern OCTAVE_API Matrix imag (const ComplexMatrix& a);
+
+// column vector by row vector -> matrix operations
+
+extern OCTAVE_API Matrix operator * (const ColumnVector& a, const RowVector& b);
+
+// Other functions.
+
+extern OCTAVE_API Matrix Givens (double, double);
+
+extern OCTAVE_API Matrix Sylvester (const Matrix&, const Matrix&, const Matrix&);
+
+extern OCTAVE_API Matrix xgemm (bool transa, const Matrix& a, bool transb, const Matrix& b);
+
+extern OCTAVE_API Matrix operator * (const Matrix& a, const Matrix& b);
+
+extern OCTAVE_API Matrix min (double d, const Matrix& m);
+extern OCTAVE_API Matrix min (const Matrix& m, double d);
+extern OCTAVE_API Matrix min (const Matrix& a, const Matrix& b);
+
+extern OCTAVE_API Matrix max (double d, const Matrix& m);
+extern OCTAVE_API Matrix max (const Matrix& m, double d);
+extern OCTAVE_API Matrix max (const Matrix& a, const Matrix& b);
+
+MS_CMP_OP_DECLS (Matrix, double, OCTAVE_API)
+MS_BOOL_OP_DECLS (Matrix, double, OCTAVE_API)
+
+SM_CMP_OP_DECLS (double, Matrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (double, Matrix, OCTAVE_API)
+
+MM_CMP_OP_DECLS (Matrix, Matrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (Matrix, Matrix, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArray2, Matrix, double)
+
+template <class T>
+void read_int (std::istream& is, bool swap_bytes, T& val);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dNDArray.cc b/liboctave/dNDArray.cc
new file mode 100644
index 0000000..e1ad1e7
--- /dev/null
+++ b/liboctave/dNDArray.cc
@@ -0,0 +1,1134 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <vector>
+
+#include "Array-util.h"
+#include "dNDArray.h"
+#include "functor.h"
+#include "mx-base.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+#include "mx-op-defs.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#endif
+
+NDArray::NDArray (const Array<octave_idx_type>& a, bool zero_based,
+		  bool negative_to_nan)
+{
+  const octave_idx_type *pa = a.fortran_vec ();
+  resize (a.dims ());
+  double *ptmp = fortran_vec ();
+  if (negative_to_nan)
+    {
+      double nan_val = lo_ieee_nan_value ();
+
+      if (zero_based)
+	for (octave_idx_type i = 0; i < a.numel (); i++)
+	  {
+	    double val = static_cast<double> 
+	      (pa[i] + static_cast<octave_idx_type> (1));
+	    if (val <= 0)
+	      ptmp[i] = nan_val;
+	    else
+	      ptmp[i] = val;
+	  }
+      else
+	for (octave_idx_type i = 0; i < a.numel (); i++)
+	  {
+	    double val = static_cast<double> (pa[i]);
+	    if (val <= 0)
+	      ptmp[i] = nan_val;
+	    else
+	      ptmp[i] = val;
+	  }
+    }
+  else
+    {
+      if (zero_based)
+	for (octave_idx_type i = 0; i < a.numel (); i++)
+	  ptmp[i] = static_cast<double> 
+	    (pa[i] + static_cast<octave_idx_type> (1));
+      else
+	for (octave_idx_type i = 0; i < a.numel (); i++)
+	  ptmp[i] = static_cast<double> (pa[i]);
+    }
+}
+
+NDArray::NDArray (const charNDArray& a)
+  : MArrayN<double> (a.dims ())
+{
+  octave_idx_type n = a.numel ();
+  for (octave_idx_type i = 0; i < n; i++)
+    xelem (i) = static_cast<unsigned char> (a(i));
+}
+
+#if defined (HAVE_FFTW3)
+
+ComplexNDArray
+NDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  const double *in (fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::fft (in + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  ComplexNDArray retval (*this);
+  Complex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::ifft (out + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::fourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return ComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  const double *in = fortran_vec ();
+  ComplexNDArray retval (dv);
+  Complex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return ComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  ComplexNDArray retval (*this);
+  Complex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::ifftNd (out + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  const double *in (fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::fftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  ComplexNDArray tmp (*this);
+  Complex *in (tmp.fortran_vec ());
+  ComplexNDArray retval (dv);
+  Complex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+#else
+
+extern "C"
+{
+  // Note that the original complex fft routines were not written for
+  // double complex arguments.  They have been modified by adding an
+  // implicit double precision (a-h,o-z) statement at the beginning of
+  // each subroutine.
+
+  F77_RET_T
+  F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*);
+
+  F77_RET_T
+  F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*);
+}
+
+ComplexNDArray
+NDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  ComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (zfftf, ZFFTF) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i];
+	}
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return ComplexNDArray ();
+
+  ComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<Complex> wsave (nn);
+  Complex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (zfftb, ZFFTB) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i] / 
+	      static_cast<double> (npts);
+	}
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::fourier2d (void) const
+{
+  dim_vector dv = dims();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] / 
+		  static_cast<double> (npts);
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+ComplexNDArray
+NDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  ComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<Complex> wsave (nn);
+      Complex *pwsave = wsave.fortran_vec ();
+      Array<Complex> row (npts);
+      Complex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (zffti, ZFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] /
+		  static_cast<double> (npts);
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+#endif
+
+// unary operations
+
+boolNDArray
+NDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (octave_idx_type i = 0; i < length (); i++)
+    b.elem (i) = ! elem (i);
+
+  return b;
+}
+
+bool
+NDArray::any_element_is_negative (bool neg_zero) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (neg_zero)
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (lo_ieee_signbit (elem (i)))
+	  return true;
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (elem (i) < 0)
+	  return true;
+    }
+
+  return false;
+}
+
+bool
+NDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+NDArray::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+NDArray::any_element_not_one_or_zero (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (val != 0 && val != 1)
+	return true;
+    }
+
+  return false;
+}
+
+bool
+NDArray::all_elements_are_zero (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    if (elem (i) != 0)
+      return false;
+
+  return true;
+}
+
+bool
+NDArray::all_elements_are_int_or_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisnan (val) || D_NINT (val) == val)
+	continue;
+      else
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of M is not an integer.  Also extract
+// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
+
+bool
+NDArray::all_integers (double& max_val, double& min_val) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (nel > 0)
+    {
+      max_val = elem (0);
+      min_val = elem (0);
+    }
+  else
+    return false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+
+      if (val > max_val)
+	max_val = val;
+
+      if (val < min_val)
+	min_val = val;
+
+      if (D_NINT (val) != val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+NDArray::too_large_for_float (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+
+      if (! (xisnan (val) || xisinf (val))
+	  && fabs (val) > FLT_MAX)
+	return true;
+    }
+
+  return false;
+}
+
+// FIXME -- this is not quite the right thing.
+
+boolNDArray
+NDArray::all (int dim) const
+{
+  return do_mx_red_op<boolNDArray, double> (*this, dim, mx_inline_all);
+}
+
+boolNDArray
+NDArray::any (int dim) const
+{
+  return do_mx_red_op<boolNDArray, double> (*this, dim, mx_inline_any);
+}
+
+NDArray
+NDArray::cumprod (int dim) const
+{
+  return do_mx_cum_op<NDArray, double> (*this, dim, mx_inline_cumprod);
+}
+
+NDArray
+NDArray::cumsum (int dim) const
+{
+  return do_mx_cum_op<NDArray, double> (*this, dim, mx_inline_cumsum);
+}
+
+NDArray
+NDArray::prod (int dim) const
+{
+  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_prod);
+}
+
+NDArray
+NDArray::sum (int dim) const
+{
+  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_sum);
+}
+
+NDArray
+NDArray::sumsq (int dim) const
+{
+  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_sumsq);
+}
+
+NDArray
+NDArray::max (int dim) const
+{
+  return do_mx_minmax_op<NDArray> (*this, dim, mx_inline_max);
+}
+
+NDArray
+NDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<NDArray> (*this, idx_arg, dim, mx_inline_max);
+}
+
+NDArray
+NDArray::min (int dim) const
+{
+  return do_mx_minmax_op<NDArray> (*this, dim, mx_inline_min);
+}
+
+NDArray
+NDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<NDArray> (*this, idx_arg, dim, mx_inline_min);
+}
+
+NDArray
+NDArray::cummax (int dim) const
+{
+  return do_mx_cumminmax_op<NDArray> (*this, dim, mx_inline_cummax);
+}
+
+NDArray
+NDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<NDArray> (*this, idx_arg, dim, mx_inline_cummax);
+}
+
+NDArray
+NDArray::cummin (int dim) const
+{
+  return do_mx_cumminmax_op<NDArray> (*this, dim, mx_inline_cummin);
+}
+
+NDArray
+NDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<NDArray> (*this, idx_arg, dim, mx_inline_cummin);
+}
+
+NDArray
+NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+ComplexNDArray
+NDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  ComplexNDArray retval (*this);
+  if (rb.numel () > 0)
+    retval.insert (rb, ra_idx);
+  return retval;
+}
+
+charNDArray
+NDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  charNDArray retval (dims ());
+  octave_idx_type nel = numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double d = elem (i);
+
+      if (xisnan (d))
+	{
+	  (*current_liboctave_error_handler)
+	    ("invalid conversion from NaN to character");
+	  return retval;
+	}
+      else
+	{
+	  octave_idx_type ival = NINTbig (d);
+
+	  if (ival < 0 || ival > UCHAR_MAX)
+	    // FIXME -- is there something
+	    // better we could do? Should we warn the user?
+	    ival = 0;
+
+	  retval.elem (i) = static_cast<char>(ival);
+	}
+    }
+
+  if (rb.numel () == 0)
+    return retval;
+
+  retval.insert (rb, ra_idx);
+  return retval;
+}
+
+NDArray
+real (const ComplexNDArray& a)
+{
+  return NDArray (mx_inline_real_dup (a.data (), a.length ()),
+                  a.dims ());
+}
+
+NDArray
+imag (const ComplexNDArray& a)
+{
+  return NDArray (mx_inline_imag_dup (a.data (), a.length ()),
+                  a.dims ());
+}
+
+NDArray&
+NDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<double>::insert (a, r, c);
+  return *this;
+}
+
+NDArray&
+NDArray::insert (const NDArray& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<double>::insert (a, ra_idx);
+  return *this;
+}
+
+NDArray
+NDArray::abs (void) const
+{
+  return NDArray (mx_inline_fabs_dup (data (), length ()),
+                  dims ());
+}
+
+boolNDArray
+NDArray::isnan (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisnan));
+}
+
+boolNDArray
+NDArray::isinf (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisinf));
+}
+
+boolNDArray
+NDArray::isfinite (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xfinite));
+}
+
+Matrix
+NDArray::matrix_value (void) const
+{
+  Matrix retval;
+
+  if (ndims () == 2)
+      retval = Matrix (Array2<double> (*this));
+  else
+    (*current_liboctave_error_handler)
+      ("invalid conversion of NDArray to Matrix");
+
+  return retval;
+}
+
+void
+NDArray::increment_index (Array<octave_idx_type>& ra_idx,
+			  const dim_vector& dimensions,
+			  int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+octave_idx_type
+NDArray::compute_index (Array<octave_idx_type>& ra_idx,
+			const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+NDArray
+NDArray::diag (octave_idx_type k) const
+{
+  return MArrayN<double>::diag (k);
+}
+
+NDArray
+NDArray::map (dmapper fcn) const
+{
+  return MArrayN<double>::map<double> (func_ptr (fcn));
+}
+
+ComplexNDArray
+NDArray::map (cmapper fcn) const
+{
+  return MArrayN<double>::map<Complex> (func_ptr (fcn));
+}
+
+boolNDArray
+NDArray::map (bmapper fcn) const
+{
+  return MArrayN<double>::map<bool> (func_ptr (fcn));
+}
+
+// This contains no information on the array structure !!!
+std::ostream&
+operator << (std::ostream& os, const NDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      os << " ";
+      octave_write_double (os, a.elem (i));
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, NDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  if (nel > 0)
+    {
+      double tmp;
+      for (octave_idx_type i = 0; i < nel; i++)
+	  {
+	    tmp = octave_read_double (is);
+	    if (is)
+	      a.elem (i) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+ done:
+
+  return is;
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nel == 0)	\
+    return T (dv);
+
+NDArray
+min (double d, const NDArray& m)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+min (const NDArray& m, double d)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+min (const NDArray& a, const NDArray& b)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return NDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (a (i), b (i));
+    }
+
+  return result;
+}
+
+NDArray
+max (double d, const NDArray& m)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+max (const NDArray& m, double d)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+max (const NDArray& a, const NDArray& b)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return NDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (a (i), b (i));
+    }
+
+  return result;
+}
+
+NDS_CMP_OPS(NDArray, , double, )
+NDS_BOOL_OPS(NDArray, double, 0.0)
+
+SND_CMP_OPS(double, , NDArray, )
+SND_BOOL_OPS(double, NDArray, 0.0)
+
+NDND_CMP_OPS(NDArray, , NDArray, )
+NDND_BOOL_OPS(NDArray, NDArray, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dNDArray.h b/liboctave/dNDArray.h
new file mode 100644
index 0000000..0ab052e
--- /dev/null
+++ b/liboctave/dNDArray.h
@@ -0,0 +1,193 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_NDArray_h)
+#define octave_NDArray_h 1
+
+#include "MArrayN.h"
+#include "dMatrix.h"
+#include "intNDArray.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+class
+OCTAVE_API
+NDArray : public MArrayN<double>
+{
+public:
+
+  NDArray (void) : MArrayN<double> () { }
+
+  NDArray (const dim_vector& dv) : MArrayN<double> (dv) { }
+
+  NDArray (const dim_vector& dv, double val)
+    : MArrayN<double> (dv, val) { }
+  
+  NDArray (const NDArray& a) : MArrayN<double> (a) { }
+
+  NDArray (const Matrix& a) : MArrayN<double> (a) { }
+
+  NDArray (const Array<octave_idx_type>& a, bool zero_based = false, 
+	   bool negative_to_nan = false);
+
+  template <class U>
+  NDArray (const MArrayN<U>& a) : MArrayN<double> (a) { }
+
+  template <class U>
+  NDArray (const ArrayN<U>& a) : MArrayN<double> (a) { }
+
+  template <class U>
+  explicit NDArray (const intNDArray<U>& a) : MArrayN<double> (a) { }
+
+  NDArray (const charNDArray&); 
+
+  NDArray& operator = (const NDArray& a)
+    {
+      MArrayN<double>::operator = (a);
+      return *this;
+    }
+
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
+  bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool any_element_not_one_or_zero (void) const;
+  bool all_elements_are_zero (void) const;
+  bool all_elements_are_int_or_inf_or_nan (void) const;
+  bool all_integers (double& max_val, double& min_val) const;
+  bool too_large_for_float (void) const;
+
+  // FIXME -- this is not quite the right thing.
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+
+  NDArray cumprod (int dim = -1) const;
+  NDArray cumsum (int dim = -1) const;
+  NDArray prod (int dim = -1) const;
+  NDArray sum (int dim = -1) const;  
+  NDArray sumsq (int dim = -1) const;
+  NDArray concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx);
+  ComplexNDArray concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx);
+  charNDArray concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx);
+
+  NDArray max (int dim = 0) const;
+  NDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  NDArray min (int dim = 0) const;
+  NDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  
+  NDArray cummax (int dim = 0) const;
+  NDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  NDArray cummin (int dim = 0) const;
+  NDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const;
+
+  NDArray& insert (const NDArray& a, octave_idx_type r, octave_idx_type c);
+  NDArray& insert (const NDArray& a, const Array<octave_idx_type>& ra_idx);
+
+  NDArray abs (void) const;
+  boolNDArray isnan (void) const;
+  boolNDArray isinf (void) const;
+  boolNDArray isfinite (void) const;
+
+  ComplexNDArray fourier (int dim = 1) const;
+  ComplexNDArray ifourier (int dim = 1) const;
+
+  ComplexNDArray fourier2d (void) const;
+  ComplexNDArray ifourier2d (void) const;
+
+  ComplexNDArray fourierNd (void) const;
+  ComplexNDArray ifourierNd (void) const;
+
+  friend OCTAVE_API NDArray real (const ComplexNDArray& a);
+  friend OCTAVE_API NDArray imag (const ComplexNDArray& a);
+
+  friend class ComplexNDArray;
+
+  Matrix matrix_value (void) const;
+
+  NDArray squeeze (void) const { return MArrayN<double>::squeeze (); }
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const NDArray& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, NDArray& a);
+
+  static double resize_fill_value (void) { return 0; }
+
+  NDArray diag (octave_idx_type k = 0) const;
+
+  typedef double (*dmapper) (double);
+  typedef Complex (*cmapper) (const Complex&);
+  typedef bool (*bmapper) (double);
+
+  NDArray map (dmapper fcn) const;
+  ComplexNDArray map (cmapper fcn) const;
+  boolNDArray map (bmapper fcn) const;
+
+private:
+
+  NDArray (double *d, const dim_vector& dv) : MArrayN<double> (d, dv) { }
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API NDArray real (const ComplexNDArray& a);
+extern OCTAVE_API NDArray imag (const ComplexNDArray& a);
+
+extern OCTAVE_API NDArray min (double d, const NDArray& m);
+extern OCTAVE_API NDArray min (const NDArray& m, double d);
+extern OCTAVE_API NDArray min (const NDArray& a, const NDArray& b);
+
+extern OCTAVE_API NDArray max (double d, const NDArray& m);
+extern OCTAVE_API NDArray max (const NDArray& m, double d);
+extern OCTAVE_API NDArray max (const NDArray& a, const NDArray& b);
+
+NDS_CMP_OP_DECLS (NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, double, OCTAVE_API)
+
+SND_CMP_OP_DECLS (double, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, NDArray, double)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dRowVector.cc b/liboctave/dRowVector.cc
new file mode 100644
index 0000000..c16f70d
--- /dev/null
+++ b/liboctave/dRowVector.cc
@@ -0,0 +1,364 @@
+// RowVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const double&,
+			   const double*, const octave_idx_type&, const double*,
+			   const octave_idx_type&, const double&, double*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (xddot, XDDOT) (const octave_idx_type&, const double*, const octave_idx_type&,
+			   const double*, const octave_idx_type&, double&);
+}
+
+// Row Vector class.
+
+bool
+RowVector::operator == (const RowVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+RowVector::operator != (const RowVector& a) const
+{
+  return !(*this == a);
+}
+
+RowVector&
+RowVector::insert (const RowVector& a, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (c < 0 || c + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+RowVector&
+RowVector::fill (double val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+RowVector&
+RowVector::fill (double val, octave_idx_type c1, octave_idx_type c2)
+{
+  octave_idx_type len = length ();
+
+  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = c1; i <= c2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+RowVector
+RowVector::append (const RowVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nc_insert = len;
+  RowVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nc_insert);
+  return retval;
+}
+
+ColumnVector
+RowVector::transpose (void) const
+{
+  return MArray<double>::transpose();
+}
+
+RowVector
+real (const ComplexRowVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  RowVector retval;
+  if (a_len > 0)
+    retval = RowVector (mx_inline_real_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+RowVector
+imag (const ComplexRowVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  RowVector retval;
+  if (a_len > 0)
+    retval = RowVector (mx_inline_imag_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+RowVector
+RowVector::extract (octave_idx_type c1, octave_idx_type c2) const
+{
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  RowVector result (new_c);
+
+  for (octave_idx_type i = 0; i < new_c; i++)
+    result.xelem (i) = elem (c1+i);
+
+  return result;
+}
+
+RowVector
+RowVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  RowVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.xelem (i) = elem (r1+i);
+
+  return result;
+}
+
+// row vector by matrix -> row vector
+
+RowVector
+operator * (const RowVector& v, const Matrix& a)
+{
+  RowVector retval;
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != len)
+    gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
+  else
+    {
+      if (len == 0)
+	retval.resize (a_nc, 0.0);
+      else
+	{
+	  // Transpose A to form A'*x == (x'*A)'
+
+	  octave_idx_type ld = a_nr;
+
+	  retval.resize (a_nc);
+	  double *y = retval.fortran_vec ();
+
+	  F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
+				   a_nr, a_nc, 1.0, a.data (),
+				   ld, v.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+// other operations
+
+RowVector
+RowVector::map (dmapper fcn) const
+{
+  return MArray<double>::map<double> (func_ptr (fcn));
+}
+
+ComplexRowVector
+RowVector::map (cmapper fcn) const
+{
+  return MArray<double>::map<Complex> (func_ptr (fcn));
+}
+
+double
+RowVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0;
+
+  double res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) < res)
+      res = elem (i);
+
+  return res;
+}
+
+double
+RowVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0;
+
+  double res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) > res)
+      res = elem (i);
+
+  return res;
+}
+
+std::ostream&
+operator << (std::ostream& os, const RowVector& a)
+{
+//  int field_width = os.precision () + 7;
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << " " /* setw (field_width) */ << a.elem (i);
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, RowVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      double tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+// other operations
+
+RowVector
+linspace (double x1, double x2, octave_idx_type n)
+{
+  RowVector retval;
+
+  if (n > 1)
+    {
+      retval.resize (n);
+      double delta = (x2 - x1) / (n - 1);
+      retval.elem (0) = x1;
+      for (octave_idx_type i = 1; i < n-1; i++)
+	retval.elem (i) = x1 + i * delta;
+      retval.elem (n-1) = x2;
+    }
+  else
+    {
+      retval.resize (1);
+      retval.elem (0) = x2;
+    }
+
+  return retval;
+}
+
+// row vector by column vector -> scalar
+
+double
+operator * (const RowVector& v, const ColumnVector& a)
+{
+  double retval = 0.0;
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    gripe_nonconformant ("operator *", len, a_len);
+  else if (len != 0)
+    F77_FUNC (xddot, XDDOT) (len, v.data (), 1, a.data (), 1, retval);
+
+  return retval;
+}
+
+Complex
+operator * (const RowVector& v, const ComplexColumnVector& a)
+{
+  ComplexRowVector tmp (v);
+  return tmp * a;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dRowVector.h b/liboctave/dRowVector.h
new file mode 100644
index 0000000..c579ba4
--- /dev/null
+++ b/liboctave/dRowVector.h
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_RowVector_h)
+#define octave_RowVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+RowVector : public MArray<double>
+{
+public:
+
+  RowVector (void) : MArray<double> () { }
+
+  explicit RowVector (octave_idx_type n) : MArray<double> (n) { }
+
+  RowVector (octave_idx_type n, double val) : MArray<double> (n, val) { }
+
+  RowVector (const RowVector& a) : MArray<double> (a) { }
+
+  RowVector (const MArray<double>& a) : MArray<double> (a) { }
+
+  RowVector& operator = (const RowVector& a)
+    {
+      MArray<double>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const RowVector& a) const;
+  bool operator != (const RowVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  RowVector& insert (const RowVector& a, octave_idx_type c);
+
+  RowVector& fill (double val);
+  RowVector& fill (double val, octave_idx_type c1, octave_idx_type c2);
+
+  RowVector append (const RowVector& a) const;
+
+  ColumnVector transpose (void) const;
+
+  friend OCTAVE_API RowVector real (const ComplexRowVector& a);
+  friend OCTAVE_API RowVector imag (const ComplexRowVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  RowVector extract (octave_idx_type c1, octave_idx_type c2) const;
+
+  RowVector extract_n (octave_idx_type c1, octave_idx_type n) const;
+
+  // row vector by matrix -> row vector
+
+  friend OCTAVE_API RowVector operator * (const RowVector& a, const Matrix& b);
+
+  // other operations
+
+  typedef double (*dmapper) (double);
+  typedef Complex (*cmapper) (const Complex&);
+
+  RowVector map (dmapper fcn) const;
+  ComplexRowVector map (cmapper fcn) const;
+
+  double min (void) const;
+  double max (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const RowVector& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, RowVector& a);
+
+private:
+
+  RowVector (double *d, octave_idx_type l) : MArray<double> (d, l) { }
+};
+
+// row vector by column vector -> scalar
+
+double OCTAVE_API operator * (const RowVector& a, const ColumnVector& b);
+
+Complex OCTAVE_API operator * (const RowVector& a, const ComplexColumnVector& b);
+
+// other operations
+
+OCTAVE_API RowVector linspace (double x1, double x2, octave_idx_type n);
+
+MARRAY_FORWARD_DEFS (MArray, RowVector, double)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dSparse.cc b/liboctave/dSparse.cc
new file mode 100644
index 0000000..7842227
--- /dev/null
+++ b/liboctave/dSparse.cc
@@ -0,0 +1,8077 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <vector>
+#include <functional>
+
+#include "quit.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "f77-fcn.h"
+#include "dRowVector.h"
+#include "oct-locbuf.h"
+
+#include "dDiagMatrix.h"
+#include "CSparse.h"
+#include "boolSparse.h"
+#include "dSparse.h"
+#include "functor.h"
+#include "oct-spparms.h"
+#include "SparsedbleLU.h"
+#include "MatrixType.h"
+#include "oct-sparse.h"
+#include "sparse-util.h"
+#include "SparsedbleCHOL.h"
+#include "SparseQR.h"
+
+#include "Sparse-diag-op-defs.h"
+
+#include "Sparse-perm-op-defs.h"
+
+// Define whether to use a basic QR solver or one that uses a Dulmange
+// Mendelsohn factorization to seperate the problem into under-determined,
+// well-determined and over-determined parts and solves them seperately
+#ifndef USE_QRSOLVE
+#include "sparse-dmsolve.cc"
+#endif
+
+// Fortran functions we call.
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgbtrf, DGBTRF) (const octave_idx_type&, const octave_idx_type&,
+			     const octave_idx_type&, const octave_idx_type&,
+			     double*, const octave_idx_type&,
+			     octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgbtrs, DGBTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+			     const double*, const octave_idx_type&,
+			     const octave_idx_type*, double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgbcon, DGBCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const octave_idx_type&, double*, 
+			     const octave_idx_type&, const octave_idx_type*, const double&, 
+			     double&, double*, octave_idx_type*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpbtrf, DPBTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpbtrs, DPBTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const octave_idx_type&, double*, const octave_idx_type&, 
+			     double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpbcon, DPBCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, double*, const octave_idx_type&, 
+			     const double&, double&, double*, octave_idx_type*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (dptsv, DPTSV) (const octave_idx_type&, const octave_idx_type&, double*, double*,
+			   double*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgtsv, DGTSV) (const octave_idx_type&, const octave_idx_type&, double*, double*,
+			   double*, double*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgttrf, DGTTRF) (const octave_idx_type&, double*, double*, double*, double*,
+			     octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgttrs, DGTTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     const octave_idx_type&, const double*, const double*,
+			     const double*, const double*, const octave_idx_type*,
+			     double *, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, double*, Complex*,
+			   Complex*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zgtsv, ZGTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*,
+			   Complex*, Complex*, const octave_idx_type&, octave_idx_type&);
+
+}
+
+SparseMatrix::SparseMatrix (const SparseBoolMatrix &a)
+  : MSparse<double> (a.rows (), a.cols (), a.nnz ())
+{
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = a.nnz ();
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    cidx (i) = a.cidx (i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      data (i) = a.data (i);
+      ridx (i) = a.ridx (i);
+    }
+}
+
+SparseMatrix::SparseMatrix (const DiagMatrix& a)
+  : MSparse<double> (a.rows (), a.cols (), a.length ())
+{
+  octave_idx_type j = 0, l = a.length ();
+  for (octave_idx_type i = 0; i < l; i++)
+    {
+      cidx (i) = j;
+      if (a(i, i) != 0.0)
+        {
+          data (j) = a(i, i);
+          ridx (j) = i;
+          j++;
+        }
+    }
+  for (octave_idx_type i = l; i <= a.cols (); i++)
+    cidx(i) = j;
+}
+
+SparseMatrix::SparseMatrix (const PermMatrix& a)
+  : MSparse<double> (a.rows (), a.cols (), a.rows ())
+{
+  octave_idx_type n = a.rows ();
+  for (octave_idx_type i = 0; i <= n; i++) 
+    cidx (i) = i;
+  const Array<octave_idx_type> pv = a.pvec ();
+
+  if (a.is_row_perm ())
+    {
+      for (octave_idx_type i = 0; i < n; i++)
+        ridx (pv (i)) = i;
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < n; i++)
+        ridx (i) = pv (i);
+    }
+
+  for (octave_idx_type i = 0; i < n; i++)
+    data (i) = 1.0;
+}
+
+bool
+SparseMatrix::operator == (const SparseMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nnz ();
+  octave_idx_type nr_a = a.rows ();
+  octave_idx_type nc_a = a.cols ();
+  octave_idx_type nz_a = a.nnz ();
+
+  if (nr != nr_a || nc != nc_a || nz != nz_a)
+    return false;
+
+  for (octave_idx_type i = 0; i < nc + 1; i++)
+    if (cidx(i) != a.cidx(i))
+	return false;
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    if (data(i) != a.data(i) || ridx(i) != a.ridx(i))
+      return false;
+
+  return true;
+}
+
+bool
+SparseMatrix::operator != (const SparseMatrix& a) const
+{
+  return !(*this == a);
+}
+
+bool
+SparseMatrix::is_symmetric (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr == nc && nr > 0)
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      octave_idx_type ri = ridx(i);
+
+	      if (ri != j)
+		{
+		  bool found = false;
+
+		  for (octave_idx_type k = cidx(ri); k < cidx(ri+1); k++)
+		    {
+		      if (ridx(k) == j)
+			{
+			  if (data(i) == data(k))
+			    found = true;
+			  break;
+			}
+		    }
+
+		  if (! found)
+		    return false;
+		}
+	    }
+	}
+
+      return true;
+    }
+
+  return false;
+}
+
+SparseMatrix&
+SparseMatrix::insert (const SparseMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  MSparse<double>::insert (a, r, c);
+  return *this;
+}
+
+SparseMatrix&
+SparseMatrix::insert (const SparseMatrix& a, const Array<octave_idx_type>& indx)
+{
+  MSparse<double>::insert (a, indx);
+  return *this;
+}
+
+SparseMatrix
+SparseMatrix::max (int dim) const
+{
+  Array2<octave_idx_type> dummy_idx;
+  return max (dummy_idx, dim);
+}
+
+SparseMatrix
+SparseMatrix::max (Array2<octave_idx_type>& idx_arg, int dim) const
+{
+  SparseMatrix result;
+  dim_vector dv = dims ();
+
+  if (dv.numel () == 0 || dim > dv.length () || dim < 0)
+    return result;
+ 
+  octave_idx_type nr = dv(0);
+  octave_idx_type nc = dv(1);
+
+  if (dim == 0)
+    {
+      idx_arg.resize (1, nc);
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  double tmp_max = octave_NaN;
+	  octave_idx_type idx_j = 0;
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      if (ridx(i) != idx_j)
+		break;
+	      else
+		idx_j++;
+	    }
+
+	  if (idx_j != nr)
+	    tmp_max = 0.;
+
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      double tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (xisnan (tmp_max) || tmp > tmp_max)
+		{
+		  idx_j = ridx (i);
+		  tmp_max = tmp;
+		}
+
+	    }
+
+ 	  idx_arg.elem (j) = xisnan (tmp_max) ? 0 : idx_j;
+	  if (tmp_max != 0.)
+	    nel++;
+	}
+
+      result = SparseMatrix (1, nc, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  double tmp = elem (idx_arg(j), j);
+	  if (tmp != 0.)
+	    {
+	      result.xdata (ii) = tmp;
+	      result.xridx (ii++) = 0;
+	    }
+	  result.xcidx (j+1) = ii;
+
+	}
+    }
+  else
+    {
+      idx_arg.resize (nr, 1, 0);
+
+      for (octave_idx_type i = cidx(0); i < cidx(1); i++)
+	idx_arg.elem(ridx(i)) = -1;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    if (idx_arg.elem(i) != -1)
+	      continue;
+	    bool found = false;
+	    for (octave_idx_type k = cidx(j); k < cidx(j+1); k++)
+	      if (ridx(k) == i)
+		{
+		  found = true;
+		  break;
+		}
+	    
+	    if (!found)
+	      idx_arg.elem(i) = j;
+
+	  }
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      octave_idx_type ir = ridx (i);
+	      octave_idx_type ix = idx_arg.elem (ir);
+	      double tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (ix == -1 || tmp > elem (ir, ix))
+		idx_arg.elem (ir) = j;
+	    }
+	}
+
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nr; j++)
+	if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.)
+	  nel++;
+
+      result = SparseMatrix (nr, 1, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      result.xcidx (1) = nel;
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (idx_arg(j) == -1)
+	    {
+	      idx_arg(j) = 0;
+	      result.xdata (ii) = octave_NaN;
+	      result.xridx (ii++) = j;
+	    }
+	  else
+	    {
+	      double tmp = elem (j, idx_arg(j));
+	      if (tmp != 0.)
+		{
+		  result.xdata (ii) = tmp;
+		  result.xridx (ii++) = j;
+		}
+	    }
+	}
+    }
+
+  return result;
+}
+
+SparseMatrix
+SparseMatrix::min (int dim) const
+{
+  Array2<octave_idx_type> dummy_idx;
+  return min (dummy_idx, dim);
+}
+
+SparseMatrix
+SparseMatrix::min (Array2<octave_idx_type>& idx_arg, int dim) const
+{
+  SparseMatrix result;
+  dim_vector dv = dims ();
+
+  if (dv.numel () == 0 || dim > dv.length () || dim < 0)
+    return result;
+ 
+  octave_idx_type nr = dv(0);
+  octave_idx_type nc = dv(1);
+
+  if (dim == 0)
+    {
+      idx_arg.resize (1, nc);
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  double tmp_min = octave_NaN;
+	  octave_idx_type idx_j = 0;
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      if (ridx(i) != idx_j)
+		break;
+	      else
+		idx_j++;
+	    }
+
+	  if (idx_j != nr)
+	    tmp_min = 0.;
+
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      double tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (xisnan (tmp_min) || tmp < tmp_min)
+		{
+		  idx_j = ridx (i);
+		  tmp_min = tmp;
+		}
+
+	    }
+
+ 	  idx_arg.elem (j) = xisnan (tmp_min) ? 0 : idx_j;
+	  if (tmp_min != 0.)
+	    nel++;
+	}
+
+      result = SparseMatrix (1, nc, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  double tmp = elem (idx_arg(j), j);
+	  if (tmp != 0.)
+	    {
+	      result.xdata (ii) = tmp;
+	      result.xridx (ii++) = 0;
+	    }
+	  result.xcidx (j+1) = ii;
+
+	}
+    }
+  else
+    {
+      idx_arg.resize (nr, 1, 0);
+
+      for (octave_idx_type i = cidx(0); i < cidx(1); i++)
+	idx_arg.elem(ridx(i)) = -1;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    if (idx_arg.elem(i) != -1)
+	      continue;
+	    bool found = false;
+	    for (octave_idx_type k = cidx(j); k < cidx(j+1); k++)
+	      if (ridx(k) == i)
+		{
+		  found = true;
+		  break;
+		}
+	    
+	    if (!found)
+	      idx_arg.elem(i) = j;
+
+	  }
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	    {
+	      octave_idx_type ir = ridx (i);
+	      octave_idx_type ix = idx_arg.elem (ir);
+	      double tmp = data (i);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (ix == -1 || tmp < elem (ir, ix))
+		idx_arg.elem (ir) = j;
+	    }
+	}
+
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nr; j++)
+	if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.)
+	  nel++;
+
+      result = SparseMatrix (nr, 1, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx (0) = 0;
+      result.xcidx (1) = nel;
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (idx_arg(j) == -1)
+	    {
+	      idx_arg(j) = 0;
+	      result.xdata (ii) = octave_NaN;
+	      result.xridx (ii++) = j;
+	    }
+	  else
+	    {
+	      double tmp = elem (j, idx_arg(j));
+	      if (tmp != 0.)
+		{
+		  result.xdata (ii) = tmp;
+		  result.xridx (ii++) = j;
+		}
+	    }
+	}
+    }
+
+  return result;
+}
+
+RowVector 
+SparseMatrix::row (octave_idx_type i) const
+{
+  octave_idx_type nc = columns ();
+  RowVector retval (nc, 0);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type k = cidx (j); k < cidx (j+1); k++)
+      {
+        if (ridx (k) == i)
+          {
+            retval(j) = data (k);
+            break;
+          }
+      }
+
+  return retval;
+}
+
+ColumnVector 
+SparseMatrix::column (octave_idx_type i) const
+{
+  octave_idx_type nr = rows ();
+  ColumnVector retval (nr);
+
+  for (octave_idx_type k = cidx (i); k < cidx (i+1); k++)
+    retval(ridx (k)) = data (k);
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::concat (const SparseMatrix& rb, const Array<octave_idx_type>& ra_idx)
+{
+  // Don't use numel to avoid all possiblity of an overflow
+  if (rb.rows () > 0 && rb.cols () > 0)
+    insert (rb, ra_idx(0), ra_idx(1));
+  return *this;
+}
+
+SparseComplexMatrix
+SparseMatrix::concat (const SparseComplexMatrix& rb, const Array<octave_idx_type>& ra_idx)
+{
+  SparseComplexMatrix retval (*this);
+  if (rb.rows () > 0 && rb.cols () > 0)
+    retval.insert (rb, ra_idx(0), ra_idx(1));
+  return retval;
+}
+
+SparseMatrix
+real (const SparseComplexMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type nz = a.nnz ();
+  SparseMatrix r (nr, nc, nz);
+
+  for (octave_idx_type i = 0; i < nc +1; i++)
+    r.cidx(i) = a.cidx(i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      r.data(i) = std::real (a.data(i));
+      r.ridx(i) = a.ridx(i);
+    }
+
+  return r;
+}
+
+SparseMatrix
+imag (const SparseComplexMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type nz = a.nnz ();
+  SparseMatrix r (nr, nc, nz);
+
+  for (octave_idx_type i = 0; i < nc +1; i++)
+    r.cidx(i) = a.cidx(i);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    {
+      r.data(i) = std::imag (a.data(i));
+      r.ridx(i) = a.ridx(i);
+    }
+
+  return r;
+}
+
+SparseMatrix 
+atan2 (const double& x, const SparseMatrix& y)
+{
+  octave_idx_type nr = y.rows ();
+  octave_idx_type nc = y.cols ();
+
+  if (x == 0.)
+    return SparseMatrix (nr, nc);
+  else
+    {
+      // Its going to be basically full, so this is probably the
+      // best way to handle it.
+      Matrix tmp (nr, nc, atan2 (x, 0.));
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = y.cidx (j); i < y.cidx (j+1); i++)
+	  tmp.elem (y.ridx(i), j) = atan2 (x, y.data(i));
+
+      return SparseMatrix (tmp);
+    }
+}
+
+SparseMatrix 
+atan2 (const SparseMatrix& x, const double& y)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+  octave_idx_type nz = x.nnz ();
+
+  SparseMatrix retval (nr, nc, nz);
+
+  octave_idx_type ii = 0;
+  retval.xcidx(0) = 0;
+  for (octave_idx_type i = 0; i < nc; i++)
+    {
+      for (octave_idx_type j = x.cidx(i); j < x.cidx(i+1); j++)
+	{
+	  double tmp = atan2 (x.data(j), y);
+	  if (tmp != 0.)
+	    {
+	      retval.xdata (ii) = tmp;
+	      retval.xridx (ii++) = x.ridx (j);
+	    }
+	}
+      retval.xcidx (i+1) = ii;
+    }
+
+  if (ii != nz)
+    {
+      SparseMatrix retval2 (nr, nc, ii);
+      for (octave_idx_type i = 0; i < nc+1; i++)
+	retval2.xcidx (i) = retval.cidx (i);
+      for (octave_idx_type i = 0; i < ii; i++)
+	{
+	  retval2.xdata (i) = retval.data (i);
+	  retval2.xridx (i) = retval.ridx (i);
+	}
+      return retval2;
+    }
+  else
+    return retval;
+}
+
+SparseMatrix 
+atan2 (const SparseMatrix& x, const SparseMatrix& y)
+{
+  SparseMatrix r;
+
+  if ((x.rows() == y.rows()) && (x.cols() == y.cols())) 
+    {
+      octave_idx_type x_nr = x.rows ();
+      octave_idx_type x_nc = x.cols ();
+
+      octave_idx_type y_nr = y.rows ();
+      octave_idx_type y_nc = y.cols ();
+
+      if (x_nr != y_nr || x_nc != y_nc)
+	gripe_nonconformant ("atan2", x_nr, x_nc, y_nr, y_nc);
+      else
+	{
+	  r = SparseMatrix (x_nr, x_nc, (x.nnz () + y.nnz ()));
+       
+	  octave_idx_type jx = 0;
+	  r.cidx (0) = 0;
+	  for (octave_idx_type i = 0 ; i < x_nc ; i++)
+	    {
+	      octave_idx_type  ja = x.cidx(i);
+	      octave_idx_type  ja_max = x.cidx(i+1);
+	      bool ja_lt_max= ja < ja_max;
+           
+	      octave_idx_type  jb = y.cidx(i);
+	      octave_idx_type  jb_max = y.cidx(i+1);
+	      bool jb_lt_max = jb < jb_max;
+           
+	      while (ja_lt_max || jb_lt_max )
+		{
+		  OCTAVE_QUIT;
+		  if ((! jb_lt_max) ||
+                      (ja_lt_max && (x.ridx(ja) < y.ridx(jb))))
+		    {
+		      r.ridx(jx) = x.ridx(ja);
+		      r.data(jx) = atan2 (x.data(ja), 0.);
+		      jx++;
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		    }
+		  else if (( !ja_lt_max ) ||
+			   (jb_lt_max && (y.ridx(jb) < x.ridx(ja)) ) )
+		    {
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		  else
+		    {
+		      double tmp = atan2 (x.data(ja), y.data(jb));
+		      if (tmp != 0.)
+			{
+                          r.data(jx) = tmp;
+                          r.ridx(jx) = x.ridx(ja);
+                          jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		}
+	      r.cidx(i+1) = jx;
+	    }
+	  
+	  r.maybe_compress ();
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("matrix size mismatch");
+
+  return r;
+}
+
+SparseMatrix
+SparseMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  double rcond;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcond, 0, 0);
+}
+
+SparseMatrix
+SparseMatrix::inverse (MatrixType& mattype) const
+{
+  octave_idx_type info;
+  double rcond;
+  return inverse (mattype, info, rcond, 0, 0);
+}
+
+SparseMatrix
+SparseMatrix::inverse (MatrixType& mattype, octave_idx_type& info) const
+{
+  double rcond;
+  return inverse (mattype, info, rcond, 0, 0);
+}
+
+SparseMatrix 
+SparseMatrix::dinverse (MatrixType &mattyp, octave_idx_type& info, 
+			double& rcond, const bool, 
+			const bool calccond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  info = 0;
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattyp.type ();
+      mattyp.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  if (typ == MatrixType::Permuted_Diagonal)
+	    retval = transpose();
+	  else
+	    retval = *this;
+	      
+	  // Force make_unique to be called
+	  double *v = retval.data();
+
+	  if (calccond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  double tmp = fabs(v[i]);
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    v[i] = 1.0 / v[i];
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseMatrix 
+SparseMatrix::tinverse (MatrixType &mattyp, octave_idx_type& info, 
+			double& rcond, const bool, 
+			const bool calccond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  info = 0;
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattyp.type ();
+      mattyp.info ();
+
+      if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper || 
+	  typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+
+	  if (calccond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Upper || typ == MatrixType::Lower)
+	    {
+	      octave_idx_type nz = nnz ();
+	      octave_idx_type cx = 0;
+	      octave_idx_type nz2 = nz;
+	      retval = SparseMatrix (nr, nc, nz2);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  OCTAVE_QUIT;
+		  // place the 1 in the identity position
+		  octave_idx_type cx_colstart = cx;
+	  
+		  if (cx == nz2)
+		    {
+		      nz2 *= 2;
+		      retval.change_capacity (nz2);
+		    }
+
+		  retval.xcidx(i) = cx;
+		  retval.xridx(cx) = i;
+		  retval.xdata(cx) = 1.0;
+		  cx++;
+
+		  // iterate accross columns of input matrix
+		  for (octave_idx_type j = i+1; j < nr; j++) 
+		    {
+		      double v = 0.;
+		      // iterate to calculate sum
+		      octave_idx_type colXp = retval.xcidx(i);
+		      octave_idx_type colUp = cidx(j);
+		      octave_idx_type rpX, rpU;
+
+		      if (cidx(j) == cidx(j+1))
+			{
+			  (*current_liboctave_error_handler) 
+			    ("division by zero");
+			  goto inverse_singular;
+			}
+
+		      do
+			{
+			  OCTAVE_QUIT;
+			  rpX = retval.xridx(colXp);
+			  rpU = ridx(colUp);
+
+			  if (rpX < rpU) 
+			    colXp++;
+			  else if (rpX > rpU) 
+			    colUp++;
+			  else 
+			    {
+			      v -= retval.xdata(colXp) * data(colUp);
+			      colXp++;
+			      colUp++;
+			    }
+			} while ((rpX<j) && (rpU<j) && 
+				 (colXp<cx) && (colUp<nz));
+
+		      // get A(m,m)
+		      if (typ == MatrixType::Upper)
+			colUp = cidx(j+1) - 1;
+		      else
+			colUp = cidx(j);
+		      double pivot = data(colUp);
+		      if (pivot == 0. || ridx(colUp) != j) 
+			{
+			  (*current_liboctave_error_handler) 
+			    ("division by zero");
+			  goto inverse_singular;
+			}
+
+		      if (v != 0.)
+			{
+			  if (cx == nz2)
+			    {
+			      nz2 *= 2;
+			      retval.change_capacity (nz2);
+			    }
+
+			  retval.xridx(cx) = j;
+			  retval.xdata(cx) = v / pivot;
+			  cx++;
+			}
+		    }
+
+		  // get A(m,m)
+		  octave_idx_type colUp;
+		  if (typ == MatrixType::Upper)
+		    colUp = cidx(i+1) - 1;
+		  else
+		    colUp = cidx(i);
+		  double pivot = data(colUp);
+		  if (pivot == 0. || ridx(colUp) != i) 
+		    {
+		      (*current_liboctave_error_handler) ("division by zero");
+		      goto inverse_singular;
+		    }
+
+		  if (pivot != 1.0)
+		    for (octave_idx_type j = cx_colstart; j < cx; j++)
+		      retval.xdata(j) /= pivot;
+		}
+	      retval.xcidx(nr) = cx;
+	      retval.maybe_compress ();
+	    }
+	  else
+	    {
+	      octave_idx_type nz = nnz ();
+	      octave_idx_type cx = 0;
+	      octave_idx_type nz2 = nz;
+	      retval = SparseMatrix (nr, nc, nz2);
+
+	      OCTAVE_LOCAL_BUFFER (double, work, nr);
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr);
+
+	      octave_idx_type *perm = mattyp.triangular_perm();
+	      if (typ == MatrixType::Permuted_Upper)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    rperm[perm[i]] = i;
+		}
+	      else
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    rperm[i] = perm[i];
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    perm[rperm[i]] = i;
+		}
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  OCTAVE_QUIT;
+		  octave_idx_type iidx = rperm[i];
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    work[j] = 0.;
+
+		  // place the 1 in the identity position
+		  work[iidx] = 1.0;
+
+		  // iterate accross columns of input matrix
+		  for (octave_idx_type j = iidx+1; j < nr; j++) 
+		    {
+		      double v = 0.;
+		      octave_idx_type jidx = perm[j];
+		      // iterate to calculate sum
+		      for (octave_idx_type k = cidx(jidx); 
+			   k < cidx(jidx+1); k++)
+			{
+			  OCTAVE_QUIT;
+			  v -= work[ridx(k)] * data(k);
+			}
+
+		      // get A(m,m)
+		      double pivot;
+		      if (typ == MatrixType::Permuted_Upper)
+			pivot = data(cidx(jidx+1) - 1);
+		      else
+			pivot = data(cidx(jidx));
+		      if (pivot == 0.) 
+			{
+			  (*current_liboctave_error_handler) 
+			    ("division by zero");
+			  goto inverse_singular;
+			}
+
+		      work[j] = v / pivot;
+		    }
+
+		  // get A(m,m)
+		  octave_idx_type colUp;
+		  if (typ == MatrixType::Permuted_Upper)
+		    colUp = cidx(perm[iidx]+1) - 1;
+		  else
+		    colUp = cidx(perm[iidx]);
+
+		  double pivot = data(colUp);
+		  if (pivot == 0.)
+		    {
+		      (*current_liboctave_error_handler) 
+			("division by zero");
+		      goto inverse_singular;
+		    }
+
+		  octave_idx_type new_cx = cx;
+		  for (octave_idx_type j = iidx; j < nr; j++)
+		    if (work[j] != 0.0)
+		      {
+			new_cx++;
+			if (pivot != 1.0)
+			  work[j] /= pivot;
+		      }
+
+		  if (cx < new_cx)
+		    {
+		      nz2 = (2*nz2 < new_cx ? new_cx : 2*nz2);
+		      retval.change_capacity (nz2);
+		    }
+
+		  retval.xcidx(i) = cx;
+		  for (octave_idx_type j = iidx; j < nr; j++)
+		    if (work[j] != 0.)
+		      {
+			retval.xridx(cx) = j;
+			retval.xdata(cx++) = work[j];
+		      }
+		}
+
+	      retval.xcidx(nr) = cx;
+	      retval.maybe_compress ();
+	    }
+
+	  if (calccond)
+	    {
+	      // Calculate the 1-norm of inverse matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = retval.cidx(j); 
+		       i < retval.cidx(j+1); i++)
+		    atmp += fabs(retval.data(i));
+		  if (atmp > ainvnorm)
+		    ainvnorm = atmp;
+		}
+
+	      rcond = 1. / ainvnorm / anorm;     
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+
+ inverse_singular:
+  return SparseMatrix();
+}
+
+SparseMatrix
+SparseMatrix::inverse (MatrixType &mattype, octave_idx_type& info, 
+		       double& rcond, int, int calc_cond) const
+{
+  int typ = mattype.type (false);
+  SparseMatrix ret;
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    ret = dinverse (mattype, info, rcond, true, calc_cond);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    ret = tinverse (mattype, info, rcond, true, calc_cond).transpose();
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    {
+      MatrixType newtype = mattype.transpose();
+      ret = transpose().tinverse (newtype, info, rcond, true, calc_cond);
+    }
+  else
+    {
+      if (mattype.is_hermitian())
+	{
+	  MatrixType tmp_typ (MatrixType::Upper);
+	  SparseCHOL fact (*this, info, false);
+	  rcond = fact.rcond();
+	  if (info == 0)
+	    {
+	      double rcond2;
+	      SparseMatrix Q = fact.Q();
+	      SparseMatrix InvL = fact.L().transpose().tinverse(tmp_typ,
+					   info, rcond2, true, false);
+	      ret = Q * InvL.transpose() * InvL * Q.transpose();
+	    }
+	  else
+	    {
+	      // Matrix is either singular or not positive definite
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	}
+
+      if (!mattype.is_hermitian())
+	{
+	  octave_idx_type n = rows();
+	  ColumnVector Qinit(n);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    Qinit(i) = i;
+
+	  MatrixType tmp_typ (MatrixType::Upper);
+	  SparseLU fact (*this, Qinit, Matrix(), false, false);
+	  rcond = fact.rcond();
+	  double rcond2;
+	  SparseMatrix InvL = fact.L().transpose().tinverse(tmp_typ, 
+					   info, rcond2, true, false);
+	  SparseMatrix InvU = fact.U().tinverse(tmp_typ, info, rcond2,
+					   true, false).transpose();
+	  ret = fact.Pc().transpose() * InvU * InvL * fact.Pr();
+	}
+    }
+
+  return ret;
+}
+
+DET
+SparseMatrix::determinant (void) const
+{
+  octave_idx_type info;
+  double rcond;
+  return determinant (info, rcond, 0);
+}
+
+DET
+SparseMatrix::determinant (octave_idx_type& info) const
+{
+  double rcond;
+  return determinant (info, rcond, 0);
+}
+
+DET
+SparseMatrix::determinant (octave_idx_type& err, double& rcond, int) const
+{
+  DET retval;
+
+#ifdef HAVE_UMFPACK
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    {
+      retval = DET (1.0);
+    }
+  else
+    {
+      err = 0;
+
+      // Setup the control parameters
+      Matrix Control (UMFPACK_CONTROL, 1);
+      double *control = Control.fortran_vec ();
+      UMFPACK_DNAME (defaults) (control);
+
+      double tmp = octave_sparse_params::get_key ("spumoni");
+      if (!xisnan (tmp))
+	Control (UMFPACK_PRL) = tmp;
+
+      tmp = octave_sparse_params::get_key ("piv_tol");
+      if (!xisnan (tmp))
+	{
+	  Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+	  Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+	}
+
+      // Set whether we are allowed to modify Q or not
+      tmp = octave_sparse_params::get_key ("autoamd");
+      if (!xisnan (tmp))
+	Control (UMFPACK_FIXQ) = tmp;
+
+      // Turn-off UMFPACK scaling for LU 
+      Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
+
+      UMFPACK_DNAME (report_control) (control);
+
+      const octave_idx_type *Ap = cidx ();
+      const octave_idx_type *Ai = ridx ();
+      const double *Ax = data ();
+
+      UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control);
+
+      void *Symbolic;
+      Matrix Info (1, UMFPACK_INFO);
+      double *info = Info.fortran_vec ();
+      int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, 
+					 Ax, 0, &Symbolic, control, info);
+
+      if (status < 0)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("SparseMatrix::determinant symbolic factorization failed");
+
+	  UMFPACK_DNAME (report_status) (control, status);
+	  UMFPACK_DNAME (report_info) (control, info);
+
+	  UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+	}
+      else
+	{
+	  UMFPACK_DNAME (report_symbolic) (Symbolic, control);
+
+	  void *Numeric;
+	  status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, 
+				       &Numeric, control, info) ;
+	  UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+
+	  rcond = Info (UMFPACK_RCOND);
+
+	  if (status < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("SparseMatrix::determinant numeric factorization failed");
+
+	      UMFPACK_DNAME (report_status) (control, status);
+	      UMFPACK_DNAME (report_info) (control, info);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    {
+	      UMFPACK_DNAME (report_numeric) (Numeric, control);
+
+	      double c10, e10;
+
+	      status = UMFPACK_DNAME (get_determinant) (&c10, &e10, Numeric, info);
+
+	      if (status < 0)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("SparseMatrix::determinant error calculating determinant");
+		  
+		  UMFPACK_DNAME (report_status) (control, status);
+		  UMFPACK_DNAME (report_info) (control, info);
+		}
+	      else
+		retval = DET (c10, e10, 10);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	}
+    }
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+
+  return retval;
+}
+
+Matrix
+SparseMatrix::dsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& err,
+		      double& rcond, solve_singularity_handler, 
+		      bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  retval.resize (nc, b.cols(), 0.);
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      for (octave_idx_type i = 0; i < nm; i++)
+		retval(i,j) = b(i,j) / data (i);
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      for (octave_idx_type k = 0; k < nc; k++)
+		for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+		  retval(k,j) = b(ridx(i),j) / data (i);
+
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = fabs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::dsolve (MatrixType &mattype, const SparseMatrix& b, 
+		      octave_idx_type& err, double& rcond, 
+		      solve_singularity_handler, bool calc_cond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseMatrix (nc, b_nc, b_nz);
+
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b_nc; j++)
+	      {
+		for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		  {
+		    if (b.ridx(i) >= nm)
+		      break;
+		    retval.xridx (ii) = b.ridx(i);
+		    retval.xdata (ii++) = b.data(i) / data (b.ridx (i));
+		  }
+		retval.xcidx(j+1) = ii;
+	      }
+	  else
+	    for (octave_idx_type j = 0; j < b_nc; j++)
+	      {
+		for (octave_idx_type l = 0; l < nc; l++)
+		  for (octave_idx_type i = cidx(l); i < cidx(l+1); i++)
+		    {
+		      bool found = false;
+		      octave_idx_type k;
+		      for (k = b.cidx(j); k < b.cidx(j+1); k++)
+			if (ridx(i) == b.ridx(k))
+			  {
+			    found = true;
+			    break;
+			  }
+		      if (found)
+			{
+			  retval.xridx (ii) = l;
+			  retval.xdata (ii++) = b.data(k) / data (i);
+			}
+		    }
+		retval.xcidx(j+1) = ii;
+	      }
+
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = fabs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::dsolve (MatrixType &mattype, const ComplexMatrix& b,
+		      octave_idx_type& err, double& rcond,
+		      solve_singularity_handler, bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  retval.resize (nc, b.cols(), 0);
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+		for (octave_idx_type i = 0; i < nm; i++)
+		  retval(i,j) = b(i,j) / data (i);
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      for (octave_idx_type k = 0; k < nc; k++)
+		for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+		  retval(k,j) = b(ridx(i),j) / data (i);
+	    
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = fabs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::dsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+		     octave_idx_type& err, double& rcond, 
+		     solve_singularity_handler, bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc < nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Diagonal ||
+	  typ == MatrixType::Permuted_Diagonal)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  if (typ == MatrixType::Diagonal)
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      {
+		for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		  {
+		    if (b.ridx(i) >= nm)
+		      break;
+		    retval.xridx (ii) = b.ridx(i);
+		    retval.xdata (ii++) = b.data(i) / data (b.ridx (i));
+		  }
+		retval.xcidx(j+1) = ii;
+	      }
+	  else
+	    for (octave_idx_type j = 0; j < b.cols(); j++)
+	      {
+		for (octave_idx_type l = 0; l < nc; l++)
+		  for (octave_idx_type i = cidx(l); i < cidx(l+1); i++)
+		    {
+		      bool found = false;
+		      octave_idx_type k;
+		      for (k = b.cidx(j); k < b.cidx(j+1); k++)
+			if (ridx(i) == b.ridx(k))
+			  {
+			    found = true;
+			    break;
+			  }
+		      if (found)
+			{
+			  retval.xridx (ii) = l;
+			  retval.xdata (ii++) = b.data(k) / data (i);
+			}
+		    }
+		retval.xcidx(j+1) = ii;
+	      }
+	    
+	  if (calc_cond)
+	    {
+	      double dmax = 0., dmin = octave_Inf; 
+	      for (octave_idx_type i = 0; i < nm; i++)
+		{
+		  double tmp = fabs(data(i));
+		  if (tmp > dmax)
+		    dmax = tmp;
+		  if (tmp < dmin)
+		    dmin = tmp;
+		}
+	      rcond = dmin / dmax;
+	    }
+	  else
+	    rcond = 1.;
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+SparseMatrix::utsolve (MatrixType &mattype, const Matrix& b,
+		       octave_idx_type& err, double& rcond,
+		       solve_singularity_handler sing_handler, 
+		       bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      retval.resize (nc, b_nc);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(cidx(kidx+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (perm[i], j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+	      retval.resize (nc, b_nc);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(cidx(k+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::utsolve (MatrixType &mattype, const SparseMatrix& b,
+		       octave_idx_type& err, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nc);
+	      for (octave_idx_type i = 0; i < nc; i++)
+		rperm[perm[i]] = i;
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(cidx(kidx+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[rperm[i]] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[rperm[i]];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(cidx(k+1)-1);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::utsolve (MatrixType &mattype, const ComplexMatrix& b, 
+		       octave_idx_type& err, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      retval.resize (nc, b_nc);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    cwork[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    cwork[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (cwork[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(cidx(kidx+1)-1);
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (perm[i], j) = cwork[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+	      retval.resize (nc, b_nc);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    cwork[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    cwork[i] = 0.;
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (cwork[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(cidx(k+1)-1);
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      cwork[iidx] = cwork[iidx] - tmp  * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = cwork[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::utsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+		       octave_idx_type& err, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      octave_idx_type *perm = mattype.triangular_perm ();
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nc);
+	      for (octave_idx_type i = 0; i < nc; i++)
+		rperm[perm[i]] = i;
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    cwork[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    cwork[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      octave_idx_type kidx = perm[k];
+
+		      if (cwork[k] != 0.)
+			{
+			  if (ridx(cidx(kidx+1)-1) != k ||
+			      data(cidx(kidx+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(cidx(kidx+1)-1);
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(kidx); 
+			       i < cidx(kidx+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[rperm[i]] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = cwork[rperm[i]];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  octave_idx_type iidx = perm[k];
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(iidx+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(iidx); 
+				   i < cidx(iidx+1)-1; i++)
+				{
+				  octave_idx_type idx2 = ridx(i);
+				  work[idx2] = work[idx2] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    cwork[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    cwork[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = nc-1; k >= 0; k--)
+		    {
+		      if (cwork[k] != 0.)
+			{
+			  if (ridx(cidx(k+1)-1) != k ||
+			      data(cidx(k+1)-1) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(cidx(k+1)-1);
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = cwork[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k >= 0; k--)
+			{
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k+1)-1);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1)-1; i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = 0; i < j+1; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+SparseMatrix::ltsolve (MatrixType &mattype, const Matrix& b,
+		       octave_idx_type& err, double& rcond,
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      retval.resize (nc, b_nc);
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  if (nc > nr)
+		    for (octave_idx_type i = 0; i < nm; i++)
+		      work[i] = 0.;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[perm[i]] = b(i,j);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data(mini) == 0)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(mini);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      double tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+	      retval.resize (nc, b_nc, 0.);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(cidx(k));
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; 
+			       i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = work[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::ltsolve (MatrixType &mattype, const SparseMatrix& b, 
+		       octave_idx_type& err, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[perm[b.ridx(i)]] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data(mini) == 0)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(mini);
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      double tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nr; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, work, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (work[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  double tmp = work[k] / data(cidx(k));
+			  work[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      work[iidx] = work[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::ltsolve (MatrixType &mattype, const ComplexMatrix& b, 
+		       octave_idx_type& err, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  octave_idx_type b_nc = b.cols ();
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      retval.resize (nc, b_nc);
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    cwork[i] = 0.;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    cwork[perm[i]] = b(i,j);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (cwork[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data(mini) == 0)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(mini);
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval (i, j) = cwork[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      double tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+	      retval.resize (nc, b_nc, 0.);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    cwork[i] = b(i,j);
+		  for (octave_idx_type i = nr; i < nc; i++)
+		    cwork[i] = 0.;
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (cwork[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(cidx(k));
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    retval.xelem (i, j) = cwork[i];
+		}
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::ltsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+		       octave_idx_type& err, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nm = (nc > nr ? nc : nr);
+  err = 0;
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  double anorm = 0.;
+	  double ainvnorm = 0.;
+	  rcond = 1.;
+
+	  if (calc_cond)
+	    {
+	      // Calculate the 1-norm of matrix for rcond calculation
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  octave_idx_type b_nc = b.cols ();
+	  octave_idx_type b_nz = b.nnz ();
+	  retval = SparseComplexMatrix (nc, b_nc, b_nz);
+	  retval.xcidx(0) = 0;
+	  octave_idx_type ii = 0;
+	  octave_idx_type x_nz = b_nz;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+	      octave_idx_type *perm = mattype.triangular_perm ();
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    cwork[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    cwork[perm[b.ridx(i)]] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (cwork[k] != 0.)
+			{
+			  octave_idx_type minr = nr;
+			  octave_idx_type mini = 0;
+
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    if (perm[ridx(i)] < minr)
+			      {
+				minr = perm[ridx(i)];
+				mini = i;
+			      }
+
+			  if (minr != k || data(mini) == 0)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(mini);
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(k); i < cidx(k+1); i++)
+			    {
+			      if (i == mini)
+				continue;
+
+			      octave_idx_type iidx = perm[ridx(i)];
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = cwork[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = 0; k < nc; k++)
+			{
+			  if (work[k] != 0.)
+			    {
+			      octave_idx_type minr = nr;
+			      octave_idx_type mini = 0;
+
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				if (perm[ridx(i)] < minr)
+				  {
+				    minr = perm[ridx(i)];
+				    mini = i;
+				  }
+
+			      double tmp = work[k] / data(mini);
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k); 
+				   i < cidx(k+1); i++)
+				{
+				  if (i == mini)
+				    continue;
+
+				  octave_idx_type iidx = perm[ridx(i)];
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Complex, cwork, nm);
+
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    cwork[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    cwork[b.ridx(i)] = b.data(i);
+
+		  for (octave_idx_type k = 0; k < nc; k++)
+		    {
+		      if (cwork[k] != 0.)
+			{
+			  if (ridx(cidx(k)) != k ||
+			      data(cidx(k)) == 0.)
+			    {
+			      err = -2;
+			      goto triangular_error;
+			    }			    
+
+			  Complex tmp = cwork[k] / data(cidx(k));
+			  cwork[k] = tmp;
+			  for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++)
+			    {
+			      octave_idx_type iidx = ridx(i);
+			      cwork[iidx] = cwork[iidx] - tmp * data(i);
+			    }
+			}
+		    }
+
+		  // Count non-zeros in work vector and adjust space in
+		  // retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nc; i++)
+		    if (cwork[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = cwork[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      if (calc_cond)
+		{
+		  // Calculation of 1-norm of inv(*this)
+		  OCTAVE_LOCAL_BUFFER (double, work, nm);
+		  for (octave_idx_type i = 0; i < nm; i++)
+		    work[i] = 0.;
+
+		  for (octave_idx_type j = 0; j < nr; j++)
+		    {
+		      work[j] = 1.;
+
+		      for (octave_idx_type k = j; k < nc; k++)
+			{
+
+			  if (work[k] != 0.)
+			    {
+			      double tmp = work[k] / data(cidx(k));
+			      work[k] = tmp;
+			      for (octave_idx_type i = cidx(k)+1; 
+				   i < cidx(k+1); i++)
+				{
+				  octave_idx_type iidx = ridx(i);
+				  work[iidx] = work[iidx] - tmp * data(i);
+				}
+			    }
+			}
+		      double atmp = 0;
+		      for (octave_idx_type i = j; i < nc; i++)
+			{
+			  atmp += fabs(work[i]);
+			  work[i] = 0.;
+			}
+		      if (atmp > ainvnorm)
+			ainvnorm = atmp;
+		    }
+		  rcond = 1. / ainvnorm / anorm;
+		}
+	    }
+
+	triangular_error:
+	  if (err != 0)
+	    {
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+
+	  volatile double rcond_plus_one = rcond + 1.0;
+
+	  if (rcond_plus_one == 1.0 || xisnan (rcond))
+	    {
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision, rcond = %g",
+		   rcond);
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+SparseMatrix::trisolve (MatrixType &mattype, const Matrix& b,
+			octave_idx_type& err, double& rcond,
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (double, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii);
+		  ii += 2;
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		  }
+	    }
+	      
+	  octave_idx_type b_nc = b.cols();
+	  retval = b;
+	  double *result = retval.fortran_vec ();
+
+	  F77_XFCN (dptsv, DPTSV, (nr, b_nc, D, DL, result, 
+				   b.rows(), err));
+
+	  if (err != 0)
+	    {
+	      err = 0;
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Tridiagonal;
+	    }
+	  else 
+	    rcond = 1.;
+	}
+
+      if (typ == MatrixType::Tridiagonal)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (double, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  octave_idx_type b_nc = b.cols();
+	  retval = b;
+	  double *result = retval.fortran_vec ();
+
+	  F77_XFCN (dgtsv, DGTSV, (nr, b_nc, DL, D, DU, result, 
+				   b.rows(), err));
+
+	  if (err != 0)
+	    {
+	      rcond = 0.;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    rcond = 1.;
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	       (*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::trisolve (MatrixType &mattype, const SparseMatrix& b, 
+			octave_idx_type& err, double& rcond, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseMatrix (nc, b.cols ());
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      // Note can't treat symmetric case as there is no dpttrf function
+      if (typ == MatrixType::Tridiagonal ||
+	  typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2);
+	  OCTAVE_LOCAL_BUFFER (double, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (double, DL, nr - 1);
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  F77_XFCN (dgttrf, DGTTRF, (nr, DL, D, DU, DU2, pipvt, err));
+
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      rcond = 1.0;
+	      char job = 'N';
+	      volatile octave_idx_type x_nz = b.nnz ();
+	      octave_idx_type b_nc = b.cols ();
+	      retval = SparseMatrix (nr, b_nc, x_nz);
+	      retval.xcidx(0) = 0;
+	      volatile octave_idx_type ii = 0;
+
+	      OCTAVE_LOCAL_BUFFER (double, work, nr);
+
+	      for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    work[i] = 0.;
+		  for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+		    work[b.ridx(i)] = b.data(i);
+
+		  F77_XFCN (dgttrs, DGTTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, 1, DL, D, DU, DU2, pipvt, 
+			     work, b.rows (), err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  // Count non-zeros in work vector and adjust 
+		  // space in retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (work[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (work[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = work[i];
+		      }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+	    }
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::trisolve (MatrixType &mattype, const ComplexMatrix& b, 
+			octave_idx_type& err, double& rcond, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+      
+      if (typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii);
+		  ii += 2;
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		  }
+	    }
+
+	  octave_idx_type b_nr = b.rows ();
+	  octave_idx_type b_nc = b.cols();
+	  rcond = 1.;
+
+	  retval = b;
+	  Complex *result = retval.fortran_vec ();
+		  
+	  F77_XFCN (zptsv, ZPTSV, (nr, b_nc, D, DL, result, 
+				   b_nr, err));
+
+	  if (err != 0)
+	    {
+	      err = 0;
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Tridiagonal;
+	    }
+	}
+
+      if (typ == MatrixType::Tridiagonal)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (Complex, D, nr);
+	  OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1);
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  octave_idx_type b_nr = b.rows();
+	  octave_idx_type b_nc = b.cols();
+	  rcond = 1.;
+
+	  retval = b;
+	  Complex *result = retval.fortran_vec ();
+	      
+	  F77_XFCN (zgtsv, ZGTSV, (nr, b_nc, DL, D, DU, result, 
+				   b_nr, err));
+
+	  if (err != 0)
+	    {
+	      rcond = 0.;
+	      err = -2;
+		      
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+	    }
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::trisolve (MatrixType &mattype, const SparseComplexMatrix& b,
+			octave_idx_type& err, double& rcond, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else if (calc_cond)
+    (*current_liboctave_error_handler) 
+      ("calculation of condition number not implemented");
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      int typ = mattype.type ();
+      mattype.info ();
+      
+      // Note can't treat symmetric case as there is no dpttrf function
+      if (typ == MatrixType::Tridiagonal ||
+	  typ == MatrixType::Tridiagonal_Hermitian)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2);
+	  OCTAVE_LOCAL_BUFFER (double, DU, nr - 1);
+	  OCTAVE_LOCAL_BUFFER (double, D, nr);
+	  OCTAVE_LOCAL_BUFFER (double, DL, nr - 1);
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  if (mattype.is_dense ())
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < nc-1; j++)
+		{
+		  D[j] = data(ii++);
+		  DL[j] = data(ii++);
+		  DU[j] = data(ii++);
+		}
+	      D[nc-1] = data(ii);
+	    }
+	  else
+	    {
+	      D[0] = 0.;
+	      for (octave_idx_type i = 0; i < nr - 1; i++)
+		{
+		  D[i+1] = 0.;
+		  DL[i] = 0.;
+		  DU[i] = 0.;
+		}
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		  {
+		    if (ridx(i) == j)
+		      D[j] = data(i);
+		    else if (ridx(i) == j + 1)
+		      DL[j] = data(i);
+		    else if (ridx(i) == j - 1)
+		      DU[j-1] = data(i);
+		  }
+	    }
+
+	  F77_XFCN (dgttrf, DGTTRF, (nr, DL, D, DU, DU2, pipvt, err));
+
+	  if (err != 0) 
+	    {
+	      rcond = 0.0;
+	      err = -2;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+	    } 
+	  else 
+	    {	
+	      rcond = 1.;
+	      char job = 'N';
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+
+	      // Take a first guess that the number of non-zero terms
+	      // will be as many as in b
+	      volatile octave_idx_type x_nz = b.nnz ();
+	      volatile octave_idx_type ii = 0;
+	      retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+	      retval.xcidx(0) = 0;
+	      for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		{
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      Complex c = b (i,j);
+		      Bx[i] = std::real (c);
+		      Bz[i] = std::imag (c);
+		    }
+
+		  F77_XFCN (dgttrs, DGTTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, 1, DL, D, DU, DU2, pipvt, 
+			     Bx, b_nr, err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0)
+		    {
+		      (*current_liboctave_error_handler)
+			("SparseMatrix::solve solve failed");
+
+		      err = -1;
+		      break;
+		    }
+
+		  F77_XFCN (dgttrs, DGTTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, 1, DL, D, DU, DU2, pipvt, 
+			     Bz, b_nr, err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0)
+		    {
+		      (*current_liboctave_error_handler)
+			("SparseMatrix::solve solve failed");
+
+		      err = -1;
+		      break;
+		    }
+
+		  // Count non-zeros in work vector and adjust 
+		  // space in retval if needed
+		  octave_idx_type new_nnz = 0;
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (Bx[i] != 0. || Bz[i] != 0.)
+		      new_nnz++;
+
+		  if (ii + new_nnz > x_nz)
+		    {
+		      // Resize the sparse matrix
+		      octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+		      retval.change_capacity (sz);
+		      x_nz = sz;
+		    }
+
+		  for (octave_idx_type i = 0; i < nr; i++)
+		    if (Bx[i] != 0. || Bz[i] != 0.)
+		      {
+			retval.xridx(ii) = i;
+			retval.xdata(ii++) = 
+			  Complex (Bx[i], Bz[i]);
+		      }
+
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+	    }
+	}
+      else if (typ != MatrixType::Tridiagonal_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+Matrix
+SparseMatrix::bsolve (MatrixType &mattype, const Matrix& b,
+		      octave_idx_type& err, double& rcond,
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      // Matrix is not positive definite!! Fall through to
+	      // unsymmetric banded solver.
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+	      rcond = 0.0;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpbcon, DPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  retval = b;
+		  double *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  F77_XFCN (dpbtrs, DPBTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, n_lower, b_nc, tmp_data,
+			     ldm, result, b.rows(), err
+			     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseMatrix::solve solve failed");
+		      err = -1;
+		    }
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  // Throw-away extra info LAPACK gives so as to not 
+	  // change output.
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dgbcon, DGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  retval = b;
+		  double *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  char job = 'N';
+		  F77_XFCN (dgbtrs, DGBTRS, 
+			    (F77_CONST_CHAR_ARG2 (&job, 1),
+			     nr, n_lower, n_upper, b_nc, tmp_data,
+			     ldm, pipvt, result, b.rows(), err
+			     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::bsolve (MatrixType &mattype, const SparseMatrix& b,
+		      octave_idx_type& err, double& rcond, 
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+	      rcond = 0.0;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpbcon, DPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  octave_idx_type b_nr = b.rows ();
+		  octave_idx_type b_nc = b.cols ();
+		  OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+
+		  // Take a first guess that the number of non-zero terms
+		  // will be as many as in b
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  volatile octave_idx_type ii = 0;
+		  retval = SparseMatrix (b_nr, b_nc, x_nz);
+
+		  retval.xcidx(0) = 0;
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			Bx[i] = b.elem (i, j);
+
+		      F77_XFCN (dpbtrs, DPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bx, b_nr, err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler) 
+			    ("SparseMatrix::solve solve failed");
+			  err = -1;
+			  break;
+			}
+
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			{
+			  double tmp = Bx[i];
+			  if (tmp != 0.0)
+			    {
+			      if (ii == x_nz)
+				{
+				  // Resize the sparse matrix
+				  octave_idx_type sz = x_nz * 
+				    (b_nc - j) / b_nc;
+				  sz = (sz > 10 ? sz : 10) + x_nz;
+				  retval.change_capacity (sz);
+				  x_nz = sz;
+				}
+			      retval.xdata(ii) = tmp;
+			      retval.xridx(ii++) = i;
+			    }
+			}
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dgbcon, DGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  char job = 'N';
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  octave_idx_type b_nc = b.cols ();
+		  retval = SparseMatrix (nr, b_nc, x_nz);
+		  retval.xcidx(0) = 0;
+		  volatile octave_idx_type ii = 0;
+
+		  OCTAVE_LOCAL_BUFFER (double, work, nr);
+
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < nr; i++)
+			work[i] = 0.;
+		      for (octave_idx_type i = b.cidx(j); 
+			   i < b.cidx(j+1); i++)
+			work[b.ridx(i)] = b.data(i);
+
+		      F77_XFCN (dgbtrs, DGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, work, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      // Count non-zeros in work vector and adjust 
+		      // space in retval if needed
+		      octave_idx_type new_nnz = 0;
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (work[i] != 0.)
+			  new_nnz++;
+
+		      if (ii + new_nnz > x_nz)
+			{
+			  // Resize the sparse matrix
+			  octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+			  retval.change_capacity (sz);
+			  x_nz = sz;
+			}
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (work[i] != 0.)
+			  {
+			    retval.xridx(ii) = i;
+			    retval.xdata(ii++) = work[i];
+			  }
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::bsolve (MatrixType &mattype, const ComplexMatrix& b, 
+		      octave_idx_type& err, double& rcond, 
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      // Matrix is not positive definite!! Fall through to
+	      // unsymmetric banded solver.
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+	      rcond = 0.0;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpbcon, DPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  octave_idx_type b_nr = b.rows ();
+		  octave_idx_type b_nc = b.cols ();
+
+		  OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+		  OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+
+		  retval.resize (b_nr, b_nc);
+
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			{
+			  Complex c = b (i,j);
+			  Bx[i] = std::real (c);
+			  Bz[i] = std::imag (c);
+			}
+
+		      F77_XFCN (dpbtrs, DPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bx, b_nr, err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler) 
+			    ("SparseMatrix::solve solve failed");
+			  err = -1;
+			  break;
+			}
+
+		      F77_XFCN (dpbtrs, DPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bz, b.rows(), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler) 
+			    ("SparseMatrix::solve solve failed");
+			  err = -1;
+			  break;
+			}
+
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			retval (i, j) = Complex (Bx[i], Bz[i]);
+		    }
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		sing_handler (rcond);
+		mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpbcon, DPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			sing_handler (rcond);
+			mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  char job = 'N';
+		  octave_idx_type b_nc = b.cols ();
+		  retval.resize (nr,b_nc);
+
+		  OCTAVE_LOCAL_BUFFER (double, Bz, nr);
+		  OCTAVE_LOCAL_BUFFER (double, Bx, nr);
+
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < nr; i++)
+			{
+			  Complex c = b (i, j);
+			  Bx[i] = std::real (c);
+			  Bz[i] = std::imag  (c);
+			}
+
+		      F77_XFCN (dgbtrs, DGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, Bx, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      F77_XFCN (dgbtrs, DGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, Bz, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			retval (i, j) = Complex (Bx[i], Bz[i]);
+		    }
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::bsolve (MatrixType &mattype, const SparseComplexMatrix& b,
+		      octave_idx_type& err, double& rcond, 
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Banded_Hermitian)
+	{
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      {
+		octave_idx_type ri = ridx (i);
+		if (ri >= j)
+		  m_band(ri - j, j) = data(i);
+	      }
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    anorm = m_band.abs().sum().row(0).max();
+
+	  char job = 'L';
+	  F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nr, n_lower, tmp_data, ldm, err
+				     F77_CHAR_ARG_LEN (1)));
+	    
+	  if (err != 0) 
+	    {
+	      // Matrix is not positive definite!! Fall through to
+	      // unsymmetric banded solver.
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Banded;
+
+	      rcond = 0.0;
+	      err = 0;
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dpbcon, DPBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nr, n_lower, tmp_data, ldm,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		  if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  octave_idx_type b_nr = b.rows ();
+		  octave_idx_type b_nc = b.cols ();
+		  OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+		  OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+
+		  // Take a first guess that the number of non-zero terms
+		  // will be as many as in b
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  volatile octave_idx_type ii = 0;
+		  retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+		  retval.xcidx(0) = 0;
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+
+		      for (octave_idx_type i = 0; i < b_nr; i++)
+			{
+			  Complex c = b (i,j);
+			  Bx[i] = std::real (c);
+			  Bz[i] = std::imag (c);
+			}
+
+		      F77_XFCN (dpbtrs, DPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bx, b_nr, err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler) 
+			    ("SparseMatrix::solve solve failed");
+			  err = -1;
+			  break;
+			}
+
+		      F77_XFCN (dpbtrs, DPBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, 1, tmp_data,
+				 ldm, Bz, b_nr, err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      if (err != 0)
+			{
+			  (*current_liboctave_error_handler)
+			    ("SparseMatrix::solve solve failed");
+
+			  err = -1;
+			  break;
+			}
+
+		      // Count non-zeros in work vector and adjust 
+		      // space in retval if needed
+		      octave_idx_type new_nnz = 0;
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0. || Bz[i] != 0.)
+			  new_nnz++;
+
+		      if (ii + new_nnz > x_nz)
+			{
+			  // Resize the sparse matrix
+			  octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+			  retval.change_capacity (sz);
+			  x_nz = sz;
+			}
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0. || Bz[i] != 0.)
+			  {
+			    retval.xridx(ii) = i;
+			    retval.xdata(ii++) = 
+			      Complex (Bx[i], Bz[i]);
+			  }
+
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Banded)
+	{
+	  // Create the storage for the banded form of the sparse matrix
+	  octave_idx_type n_upper = mattype.nupper ();
+	  octave_idx_type n_lower = mattype.nlower ();
+	  octave_idx_type ldm = n_upper + 2 * n_lower + 1;
+
+	  Matrix m_band (ldm, nc);
+	  double *tmp_data = m_band.fortran_vec ();
+	      
+	  if (! mattype.is_dense ()) 
+	    {
+	      octave_idx_type ii = 0;
+
+	      for (octave_idx_type j = 0; j < ldm; j++)
+		for (octave_idx_type i = 0; i < nc; i++)
+		  tmp_data[ii++] = 0.;
+	    }
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+	      m_band(ridx(i) - j + n_lower + n_upper, j) = data(i);
+
+	  // Calculate the norm of the matrix, for later use.
+	  double anorm;
+	  if (calc_cond)
+	    {
+	      for (octave_idx_type j = 0; j < nr; j++)
+		{
+		  double atmp = 0.;
+		  for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+		    atmp += fabs(data(i));
+		  if (atmp > anorm)
+		    anorm = atmp;
+		}
+	    }
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, 
+				     ldm, pipvt, err));
+	    
+	  if (err != 0) 
+	    {
+	      err = -2;
+	      rcond = 0.0;
+
+	      if (sing_handler)
+		{
+		  sing_handler (rcond);
+		  mattype.mark_as_rectangular ();
+		}
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  char job = '1';
+		  Array<double> z (3 * nr);
+		  double *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nr);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (dgbcon, DGBCON, 
+		    (F77_CONST_CHAR_ARG2 (&job, 1),
+		     nc, n_lower, n_upper, tmp_data, ldm, pipvt,
+		     anorm, rcond, pz, piz, err
+		     F77_CHAR_ARG_LEN (1)));
+
+		   if (err != 0) 
+		    err = -2;
+
+		  volatile double rcond_plus_one = rcond + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcond))
+		    {
+		      err = -2;
+
+		      if (sing_handler)
+			{
+			  sing_handler (rcond);
+			  mattype.mark_as_rectangular ();
+			}
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcond);
+		    }
+		}
+	      else
+		rcond = 1.;
+
+	      if (err == 0)
+		{
+		  char job = 'N';
+		  volatile octave_idx_type x_nz = b.nnz ();
+		  octave_idx_type b_nc = b.cols ();
+		  retval = SparseComplexMatrix (nr, b_nc, x_nz);
+		  retval.xcidx(0) = 0;
+		  volatile octave_idx_type ii = 0;
+
+		  OCTAVE_LOCAL_BUFFER (double, Bx, nr);
+		  OCTAVE_LOCAL_BUFFER (double, Bz, nr);
+
+		  for (volatile octave_idx_type j = 0; j < b_nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < nr; i++)
+			{
+			  Bx[i] = 0.;
+			  Bz[i] = 0.;
+			}
+		      for (octave_idx_type i = b.cidx(j); 
+			   i < b.cidx(j+1); i++)
+			{
+			  Complex c = b.data(i);
+			  Bx[b.ridx(i)] = std::real (c);
+			  Bz[b.ridx(i)] = std::imag (c);
+			}
+
+		      F77_XFCN (dgbtrs, DGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, Bx, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      F77_XFCN (dgbtrs, DGBTRS, 
+				(F77_CONST_CHAR_ARG2 (&job, 1),
+				 nr, n_lower, n_upper, 1, tmp_data,
+				 ldm, pipvt, Bz, b.rows (), err
+				 F77_CHAR_ARG_LEN (1)));
+
+		      // Count non-zeros in work vector and adjust 
+		      // space in retval if needed
+		      octave_idx_type new_nnz = 0;
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0. || Bz[i] != 0.)
+			  new_nnz++;
+
+		      if (ii + new_nnz > x_nz)
+			{
+			  // Resize the sparse matrix
+			  octave_idx_type sz = new_nnz * (b_nc - j) + x_nz;
+			  retval.change_capacity (sz);
+			  x_nz = sz;
+			}
+
+		      for (octave_idx_type i = 0; i < nr; i++)
+			if (Bx[i] != 0. || Bz[i] != 0.)
+			  {
+			    retval.xridx(ii) = i;
+			    retval.xdata(ii++) = 
+			      Complex (Bx[i], Bz[i]);
+			  }
+		      retval.xcidx(j+1) = ii;
+		    }
+
+		  retval.maybe_compress ();
+		}
+	    }
+	}
+      else if (typ != MatrixType::Banded_Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+void *
+SparseMatrix::factorize (octave_idx_type& err, double &rcond, Matrix &Control,
+			 Matrix &Info, solve_singularity_handler sing_handler,
+			 bool calc_cond) const
+{
+  // The return values
+  void *Numeric = 0;
+  err = 0;
+
+#ifdef HAVE_UMFPACK
+  // Setup the control parameters
+  Control = Matrix (UMFPACK_CONTROL, 1);
+  double *control = Control.fortran_vec ();
+  UMFPACK_DNAME (defaults) (control);
+
+  double tmp = octave_sparse_params::get_key ("spumoni");
+  if (!xisnan (tmp))
+    Control (UMFPACK_PRL) = tmp;
+  tmp = octave_sparse_params::get_key ("piv_tol");
+  if (!xisnan (tmp))
+    {
+      Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
+      Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
+    }
+
+  // Set whether we are allowed to modify Q or not
+  tmp = octave_sparse_params::get_key ("autoamd");
+  if (!xisnan (tmp))
+    Control (UMFPACK_FIXQ) = tmp;
+
+  UMFPACK_DNAME (report_control) (control);
+
+  const octave_idx_type *Ap = cidx ();
+  const octave_idx_type *Ai = ridx ();
+  const double *Ax = data ();
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control);
+
+  void *Symbolic;
+  Info = Matrix (1, UMFPACK_INFO);
+  double *info = Info.fortran_vec ();
+  int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, 0,
+				     &Symbolic, control, info);
+
+  if (status < 0)
+    {
+      (*current_liboctave_error_handler) 
+	("SparseMatrix::solve symbolic factorization failed");
+      err = -1;
+
+      UMFPACK_DNAME (report_status) (control, status);
+      UMFPACK_DNAME (report_info) (control, info);
+
+      UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+    }
+  else
+    {
+      UMFPACK_DNAME (report_symbolic) (Symbolic, control);
+
+      status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic,
+				   &Numeric, control, info) ;
+      UMFPACK_DNAME (free_symbolic) (&Symbolic) ;
+
+      if (calc_cond)
+	rcond = Info (UMFPACK_RCOND);
+      else
+	rcond = 1.;
+      volatile double rcond_plus_one = rcond + 1.0;
+
+      if (status == UMFPACK_WARNING_singular_matrix || 
+	  rcond_plus_one == 1.0 || xisnan (rcond))
+	{
+	  UMFPACK_DNAME (report_numeric) (Numeric, control);
+
+	  err = -2;
+
+	  if (sing_handler)
+	    sing_handler (rcond);
+	  else
+	    (*current_liboctave_error_handler)
+	      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+	       rcond);
+
+	}
+      else if (status < 0)
+	  {
+	    (*current_liboctave_error_handler) 
+	      ("SparseMatrix::solve numeric factorization failed");
+
+	    UMFPACK_DNAME (report_status) (control, status);
+	    UMFPACK_DNAME (report_info) (control, info);
+	      
+	    err = -1;
+	  }
+	else
+	  {
+	    UMFPACK_DNAME (report_numeric) (Numeric, control);
+	  }
+    }
+
+  if (err != 0)
+    UMFPACK_DNAME (free_numeric) (&Numeric);
+
+#else
+  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+
+  return Numeric;
+}
+
+Matrix
+SparseMatrix::fsolve (MatrixType &mattype, const Matrix& b,
+		      octave_idx_type& err, double& rcond, 
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  Matrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = Matrix (nc, b.cols (), 0.0);
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_REAL;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_dense Bstore;
+	  cholmod_dense *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->d = B->nrow;
+	  B->nzmax = B->nrow * B->ncol;
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->xtype = CHOLMOD_REAL;
+	  if (nc < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    // We won't alter it, honest :-)
+	    B->x = const_cast<double *>(b.fortran_vec());
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.0;
+
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_dense *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(solve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval.resize (b.rows (), b.cols());
+	      for (octave_idx_type j = 0; j < b.cols(); j++)
+		{
+		  octave_idx_type jr = j * b.rows();
+		  for (octave_idx_type i = 0; i < b.rows(); i++)
+		    retval.xelem(i,j) = static_cast<double *>(X->x)[jr + i];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_dense) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = 
+	    factorize (err, rcond, Control, Info, sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      const double *Bx = b.fortran_vec ();
+	      retval.resize (b.rows (), b.cols());
+	      double *result = retval.fortran_vec ();
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const double *Ax = data ();
+
+	      for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr)
+		{
+		  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, 
+					     Ai, Ax, &result[iidx], &Bx[iidx],
+					     Numeric, control, info);
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseMatrix::solve solve failed");
+
+		      UMFPACK_DNAME (report_status) (control, status);
+		      
+		      err = -1;
+		  
+		      break;
+		    }
+		}
+
+	      UMFPACK_DNAME (report_info) (control, info);
+		
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::fsolve (MatrixType &mattype, const SparseMatrix& b,
+		      octave_idx_type& err, double& rcond,
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  SparseMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_REAL;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_sparse Bstore;
+	  cholmod_sparse *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->p = b.cidx();
+	  B->i = b.ridx();
+	  B->nzmax = b.nnz();
+	  B->packed = true;
+	  B->sorted = true;
+	  B->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  B->itype = CHOLMOD_LONG;
+#else
+	  B->itype = CHOLMOD_INT;
+#endif
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->stype = 0;
+	  B->xtype = CHOLMOD_REAL;
+
+	  if (b.rows() < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    B->x = b.data();
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_sparse *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval = SparseMatrix (static_cast<octave_idx_type>(X->nrow), 
+				     static_cast<octave_idx_type>(X->ncol),
+				     static_cast<octave_idx_type>(X->nzmax));
+	      for (octave_idx_type j = 0; 
+		   j <= static_cast<octave_idx_type>(X->ncol); j++)
+		retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j];
+	      for (octave_idx_type j = 0; 
+		   j < static_cast<octave_idx_type>(X->nzmax); j++)
+		{
+		  retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j];
+		  retval.xdata(j) = static_cast<double *>(X->x)[j];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_sparse) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info, 
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const double *Ax = data ();
+
+	      OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Xx, b_nr);
+
+	      // Take a first guess that the number of non-zero terms
+	      // will be as many as in b
+	      octave_idx_type x_nz = b.nnz ();
+	      octave_idx_type ii = 0;
+	      retval = SparseMatrix (b_nr, b_nc, x_nz);
+
+	      retval.xcidx(0) = 0;
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    Bx[i] = b.elem (i, j);
+
+		  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, 
+					     Ai, Ax, Xx, Bx, Numeric, control, 
+					     info);
+		  if (status < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseMatrix::solve solve failed");
+
+		      UMFPACK_DNAME (report_status) (control, status);
+		  
+		      err = -1;
+
+		      break;
+		    }
+	      
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      double tmp = Xx[i];
+		      if (tmp != 0.0)
+			{
+			  if (ii == x_nz)
+			    {
+			      // Resize the sparse matrix
+			      octave_idx_type sz = x_nz * (b_nc - j) / b_nc;
+			      sz = (sz > 10 ? sz : 10) + x_nz;
+			      retval.change_capacity (sz);
+			      x_nz = sz;
+			    }
+			  retval.xdata(ii) = tmp;
+			  retval.xridx(ii++) = i;
+			}
+		    }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      UMFPACK_DNAME (report_info) (control, info);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::fsolve (MatrixType &mattype, const ComplexMatrix& b, 
+		      octave_idx_type& err, double& rcond,
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  ComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0));
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_REAL;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_dense Bstore;
+	  cholmod_dense *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->d = B->nrow;
+	  B->nzmax = B->nrow * B->ncol;
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->xtype = CHOLMOD_COMPLEX;
+	  if (nc < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    // We won't alter it, honest :-)
+	    B->x = const_cast<Complex *>(b.fortran_vec());
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.0;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_dense *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(solve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval.resize (b.rows (), b.cols());
+	      for (octave_idx_type j = 0; j < b.cols(); j++)
+		{
+		  octave_idx_type jr = j * b.rows();
+		  for (octave_idx_type i = 0; i < b.rows(); i++)
+		    retval.xelem(i,j) = static_cast<Complex *>(X->x)[jr + i];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_dense) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info, 
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const double *Ax = data ();
+
+	      OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+
+	      retval.resize (b_nr, b_nc);
+
+	      OCTAVE_LOCAL_BUFFER (double, Xx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Xz, b_nr);
+	      
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      Complex c = b (i,j);
+		      Bx[i] = std::real (c);
+		      Bz[i] = std::imag (c);
+		    }
+
+		  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, 
+					     Ai, Ax, Xx, Bx, Numeric, control, 
+					     info);
+		  int status2 = UMFPACK_DNAME (solve) (UMFPACK_A,
+						  Ap, Ai, Ax, Xz, Bz, Numeric, 
+						  control, info) ;
+
+		  if (status < 0 || status2 < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseMatrix::solve solve failed");
+
+		      UMFPACK_DNAME (report_status) (control, status);
+		      
+		      err = -1;
+
+		      break;
+		    }
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    retval (i, j) = Complex (Xx[i], Xz[i]);
+		}
+
+	      UMFPACK_DNAME (report_info) (control, info);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::fsolve (MatrixType &mattype, const SparseComplexMatrix& b, 
+		      octave_idx_type& err, double& rcond,
+		      solve_singularity_handler sing_handler,
+		      bool calc_cond) const
+{
+  SparseComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  err = 0;
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = SparseComplexMatrix (nc, b.cols ());
+  else
+    {
+      // Print spparms("spumoni") info if requested
+      volatile int typ = mattype.type ();
+      mattype.info ();
+
+      if (typ == MatrixType::Hermitian)
+	{
+#ifdef HAVE_CHOLMOD
+	  cholmod_common Common;
+	  cholmod_common *cm = &Common;
+
+	  // Setup initial parameters
+	  CHOLMOD_NAME(start) (cm);
+	  cm->prefer_zomplex = false;
+
+	  double spu = octave_sparse_params::get_key ("spumoni");
+	  if (spu == 0.)
+	    {
+	      cm->print = -1;
+	      cm->print_function = 0;
+	    }
+	  else
+	    {
+	      cm->print = static_cast<int> (spu) + 2;
+	      cm->print_function =&SparseCholPrint;
+	    }
+
+	  cm->error_handler = &SparseCholError;
+	  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+	  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+	  cm->final_ll = true;
+
+	  cholmod_sparse Astore;
+	  cholmod_sparse *A = &Astore;
+	  double dummy;
+	  A->nrow = nr;
+	  A->ncol = nc;
+
+	  A->p = cidx();
+	  A->i = ridx();
+	  A->nzmax = nnz();
+	  A->packed = true;
+	  A->sorted = true;
+	  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  A->itype = CHOLMOD_LONG;
+#else
+	  A->itype = CHOLMOD_INT;
+#endif
+	  A->dtype = CHOLMOD_DOUBLE;
+	  A->stype = 1;
+	  A->xtype = CHOLMOD_REAL;
+
+	  if (nr < 1)
+	    A->x = &dummy;
+	  else
+	    A->x = data();
+
+	  cholmod_sparse Bstore;
+	  cholmod_sparse *B = &Bstore;
+	  B->nrow = b.rows();
+	  B->ncol = b.cols();
+	  B->p = b.cidx();
+	  B->i = b.ridx();
+	  B->nzmax = b.nnz();
+	  B->packed = true;
+	  B->sorted = true;
+	  B->nz = 0;
+#ifdef IDX_TYPE_LONG
+	  B->itype = CHOLMOD_LONG;
+#else
+	  B->itype = CHOLMOD_INT;
+#endif
+	  B->dtype = CHOLMOD_DOUBLE;
+	  B->stype = 0;
+	  B->xtype = CHOLMOD_COMPLEX;
+
+	  if (b.rows() < 1 || b.cols() < 1)
+	    B->x = &dummy;
+	  else
+	    B->x = b.data();
+
+	  cholmod_factor *L;
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  L = CHOLMOD_NAME(analyze) (A, cm);
+	  CHOLMOD_NAME(factorize) (A, L, cm);
+	  if (calc_cond)
+	    rcond = CHOLMOD_NAME(rcond)(L, cm);
+	  else
+	    rcond = 1.0;
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	  if (rcond == 0.0)
+	    {
+	      // Either its indefinite or singular. Try UMFPACK
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else
+	    {
+	      volatile double rcond_plus_one = rcond + 1.0;
+
+	      if (rcond_plus_one == 1.0 || xisnan (rcond))
+		{
+		  err = -2;
+
+		  if (sing_handler)
+		    {
+		      sing_handler (rcond);
+		      mattype.mark_as_rectangular ();
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
+		       rcond);
+	      
+		  return retval;
+		}
+
+	      cholmod_sparse *X;
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+	      retval = SparseComplexMatrix 
+		(static_cast<octave_idx_type>(X->nrow), 
+		 static_cast<octave_idx_type>(X->ncol),
+		 static_cast<octave_idx_type>(X->nzmax));
+	      for (octave_idx_type j = 0; 
+		   j <= static_cast<octave_idx_type>(X->ncol); j++)
+		retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j];
+	      for (octave_idx_type j = 0; 
+		   j < static_cast<octave_idx_type>(X->nzmax); j++)
+		{
+		  retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j];
+		  retval.xdata(j) = static_cast<Complex *>(X->x)[j];
+		}
+
+	      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	      CHOLMOD_NAME(free_sparse) (&X, cm);
+	      CHOLMOD_NAME(free_factor) (&L, cm);
+	      CHOLMOD_NAME(finish) (cm);
+	      static char tmp[] = " ";
+	      CHOLMOD_NAME(print_common) (tmp, cm);
+	      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	    }
+#else
+	  (*current_liboctave_warning_handler)
+	    ("CHOLMOD not installed");
+
+	  mattype.mark_as_unsymmetric ();
+	  typ = MatrixType::Full;
+#endif
+	}
+
+      if (typ == MatrixType::Full)
+	{
+#ifdef HAVE_UMFPACK
+	  Matrix Control, Info;
+	  void *Numeric = factorize (err, rcond, Control, Info, 
+				     sing_handler, calc_cond);
+
+	  if (err == 0)
+	    {
+	      octave_idx_type b_nr = b.rows ();
+	      octave_idx_type b_nc = b.cols ();
+	      int status = 0;
+	      double *control = Control.fortran_vec ();
+	      double *info = Info.fortran_vec ();
+	      const octave_idx_type *Ap = cidx ();
+	      const octave_idx_type *Ai = ridx ();
+	      const double *Ax = data ();
+
+	      OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
+
+	      // Take a first guess that the number of non-zero terms
+	      // will be as many as in b
+	      octave_idx_type x_nz = b.nnz ();
+	      octave_idx_type ii = 0;
+	      retval = SparseComplexMatrix (b_nr, b_nc, x_nz);
+
+	      OCTAVE_LOCAL_BUFFER (double, Xx, b_nr);
+	      OCTAVE_LOCAL_BUFFER (double, Xz, b_nr);
+	      
+	      retval.xcidx(0) = 0;
+	      for (octave_idx_type j = 0; j < b_nc; j++)
+		{
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      Complex c = b (i,j);
+		      Bx[i] = std::real (c);
+		      Bz[i] = std::imag (c);
+		    }
+
+		  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap,
+					     Ai, Ax, Xx, Bx, Numeric, control, 
+					     info);
+		  int status2 = UMFPACK_DNAME (solve) (UMFPACK_A,
+						  Ap, Ai, Ax, Xz, Bz, Numeric, 
+						  control, info) ;
+
+		  if (status < 0 || status2 < 0)
+		    {
+		      (*current_liboctave_error_handler) 
+			("SparseMatrix::solve solve failed");
+
+		      UMFPACK_DNAME (report_status) (control, status);
+		      
+		      err = -1;
+
+		      break;
+		    }
+
+		  for (octave_idx_type i = 0; i < b_nr; i++)
+		    {
+		      Complex tmp = Complex (Xx[i], Xz[i]);
+		      if (tmp != 0.0)
+			{
+			  if (ii == x_nz)
+			    {
+			      // Resize the sparse matrix
+			      octave_idx_type sz = x_nz * (b_nc - j) / b_nc;
+			      sz = (sz > 10 ? sz : 10) + x_nz;
+			      retval.change_capacity (sz);
+			      x_nz = sz;
+			    }
+			  retval.xdata(ii) = tmp;
+			  retval.xridx(ii++) = i;
+			}
+		    }
+		  retval.xcidx(j+1) = ii;
+		}
+
+	      retval.maybe_compress ();
+
+	      UMFPACK_DNAME (report_info) (control, info);
+
+	      UMFPACK_DNAME (free_numeric) (&Numeric);
+	    }
+	  else
+	    mattype.mark_as_rectangular ();
+#else
+	  (*current_liboctave_error_handler) ("UMFPACK not installed");
+#endif
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+  
+  return retval;
+}
+
+Matrix
+SparseMatrix::solve (MatrixType &mattype, const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+Matrix
+SparseMatrix::solve (MatrixType &mattype, const Matrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+Matrix
+SparseMatrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, 
+		     double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+Matrix
+SparseMatrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& err, 
+		     double& rcond, solve_singularity_handler sing_handler,
+		     bool singular_fallback) const
+{
+  Matrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  // Only calculate the condition number for CHOLMOD/UMFPACK
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return Matrix ();
+    }
+
+  // Rectangular or one of the above solvers flags a singular matrix
+  if (singular_fallback && mattype.type (false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<Matrix, SparseMatrix, Matrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b, 
+		     octave_idx_type& err, double& rcond,
+		     solve_singularity_handler sing_handler,
+		     bool singular_fallback) const
+{
+  SparseMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return SparseMatrix ();
+    }
+
+  if (singular_fallback && mattype.type (false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<SparseMatrix, SparseMatrix, 
+	SparseMatrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+ComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, 
+		     octave_idx_type& err, double& rcond, 
+		     solve_singularity_handler sing_handler,
+		     bool singular_fallback) const
+{
+  ComplexMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return ComplexMatrix ();
+    }
+
+  if (singular_fallback && mattype.type(false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<ComplexMatrix, SparseMatrix, 
+	ComplexMatrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, 
+		     octave_idx_type& err, double& rcond,
+		     solve_singularity_handler sing_handler,
+		     bool singular_fallback) const
+{
+  SparseComplexMatrix retval;
+  int typ = mattype.type (false);
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Diagonal || typ == MatrixType::Permuted_Diagonal)
+    retval = dsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian)
+    retval = bsolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Tridiagonal || 
+	   typ == MatrixType::Tridiagonal_Hermitian)
+    retval = trisolve (mattype, b, err, rcond, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, err, rcond, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return SparseComplexMatrix ();
+    }
+
+  if (singular_fallback && mattype.type(false) == MatrixType::Rectangular)
+    {
+      rcond = 1.;
+#ifdef USE_QRSOLVE
+      retval = qrsolve (*this, b, err);
+#else
+      retval = dmsolve<SparseComplexMatrix, SparseMatrix, 
+	SparseComplexMatrix> (*this, b, err);
+#endif
+    }
+
+  return retval;
+}
+
+ColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ColumnVector& b) const
+{
+  octave_idx_type info; double rcond;
+  return solve (mattype, b, info, rcond);
+}
+
+ColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ColumnVector& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond);
+}
+
+ColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ColumnVector& b, octave_idx_type& info, double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ColumnVector& b, octave_idx_type& info, double& rcond,
+	       solve_singularity_handler sing_handler) const
+{
+  Matrix tmp (b);
+  return solve (mattype, tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+ComplexColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b, octave_idx_type& info, 
+		     double& rcond) const
+{
+  return solve (mattype, b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b, octave_idx_type& info, double& rcond,
+	       solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (b);
+  return solve (mattype, tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+Matrix
+SparseMatrix::solve (const Matrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+Matrix
+SparseMatrix::solve (const Matrix& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+Matrix
+SparseMatrix::solve (const Matrix& b, octave_idx_type& info, 
+		     double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+Matrix
+SparseMatrix::solve (const Matrix& b, octave_idx_type& err, 
+		     double& rcond, 
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+SparseMatrix
+SparseMatrix::solve (const SparseMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseMatrix
+SparseMatrix::solve (const SparseMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseMatrix
+SparseMatrix::solve (const SparseMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+SparseMatrix
+SparseMatrix::solve (const SparseMatrix& b, 
+		     octave_idx_type& err, double& rcond,
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+ComplexMatrix
+SparseMatrix::solve (const ComplexMatrix& b, 
+			    octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseMatrix::solve (const ComplexMatrix& b, 
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ComplexMatrix
+SparseMatrix::solve (const ComplexMatrix& b, 
+		     octave_idx_type& err, double& rcond, 
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (const SparseComplexMatrix& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (const SparseComplexMatrix& b, 
+		     octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (const SparseComplexMatrix& b,
+		     octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+SparseComplexMatrix
+SparseMatrix::solve (const SparseComplexMatrix& b, 
+		     octave_idx_type& err, double& rcond,
+		     solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, err, rcond, sing_handler);
+}
+
+ColumnVector
+SparseMatrix::solve (const ColumnVector& b) const
+{
+  octave_idx_type info; double rcond;
+  return solve (b, info, rcond);
+}
+
+ColumnVector
+SparseMatrix::solve (const ColumnVector& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond);
+}
+
+ColumnVector
+SparseMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ColumnVector
+SparseMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond,
+	       solve_singularity_handler sing_handler) const
+{
+  Matrix tmp (b);
+  return solve (tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+ComplexColumnVector
+SparseMatrix::solve (const ComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const
+{
+  double rcond;
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, 
+		     double& rcond) const
+{
+  return solve (b, info, rcond, 0);
+}
+
+ComplexColumnVector
+SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, double& rcond,
+	       solve_singularity_handler sing_handler) const
+{
+  ComplexMatrix tmp (b);
+  return solve (tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0));
+}
+
+// other operations.
+
+bool
+SparseMatrix::any_element_is_negative (bool neg_zero) const
+{
+  octave_idx_type nel = nnz ();
+
+  if (neg_zero)
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (lo_ieee_signbit (data (i)))
+	  return true;
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (data (i) < 0)
+	  return true;
+    }
+
+  return false;
+}
+
+bool
+SparseMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = data (i);
+      if (xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+SparseMatrix::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = data (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+SparseMatrix::all_elements_are_zero (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    if (data (i) != 0)
+      return false;
+
+  return true;
+}
+
+bool
+SparseMatrix::all_elements_are_int_or_inf_or_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = data (i);
+      if (xisnan (val) || D_NINT (val) == val)
+	continue;
+      else
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of M is not an integer.  Also extract
+// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
+
+bool
+SparseMatrix::all_integers (double& max_val, double& min_val) const
+{
+  octave_idx_type nel = nnz ();
+
+  if (nel == 0)
+    return false;
+
+  max_val = data (0);
+  min_val = data (0);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = data (i);
+
+      if (val > max_val)
+	max_val = val;
+
+      if (val < min_val)
+	min_val = val;
+
+      if (D_NINT (val) != val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+SparseMatrix::too_large_for_float (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = data (i);
+
+      if (val > FLT_MAX || val < FLT_MIN)
+	return true;
+    }
+
+  return false;
+}
+
+SparseBoolMatrix 
+SparseMatrix::operator ! (void) const 
+{ 
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz1 = nnz ();
+  octave_idx_type nz2 = nr*nc - nz1;
+   
+  SparseBoolMatrix r (nr, nc, nz2);
+   
+  octave_idx_type ii = 0;
+  octave_idx_type jj = 0;
+  r.cidx (0) = 0;
+  for (octave_idx_type i = 0; i < nc; i++)
+    {
+      for (octave_idx_type j = 0; j < nr; j++)
+	{
+	  if (jj < cidx(i+1) && ridx(jj) == j)
+	    jj++;
+	  else
+	    {
+	      r.data(ii) = true;
+	      r.ridx(ii++) = j;
+	    }
+	}
+      r.cidx (i+1) = ii;
+    }
+
+  return r;
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+SparseBoolMatrix
+SparseMatrix::all (int dim) const
+{
+  SPARSE_ALL_OP (dim);
+}
+
+SparseBoolMatrix
+SparseMatrix::any (int dim) const
+{
+  SPARSE_ANY_OP (dim);
+}
+
+SparseMatrix
+SparseMatrix::cumprod (int dim) const
+{
+  SPARSE_CUMPROD (SparseMatrix, double, cumprod);
+}
+
+SparseMatrix
+SparseMatrix::cumsum (int dim) const
+{
+  SPARSE_CUMSUM (SparseMatrix, double, cumsum);
+}
+
+SparseMatrix
+SparseMatrix::prod (int dim) const
+{
+  if ((rows() == 1 && dim == -1) || dim == 1)
+    return transpose (). prod (0). transpose();
+  else
+    {
+      SPARSE_REDUCTION_OP (SparseMatrix, double, *=, 
+			   (cidx(j+1) - cidx(j) < nr ? 0.0 : 1.0), 1.0);
+    }
+}
+
+SparseMatrix
+SparseMatrix::sum (int dim) const
+{
+  SPARSE_REDUCTION_OP (SparseMatrix, double, +=, 0.0, 0.0);
+}
+
+SparseMatrix
+SparseMatrix::sumsq (int dim) const
+{
+#define ROW_EXPR \
+  double d = data (i); \
+  tmp[ridx(i)] += d * d
+
+#define COL_EXPR \
+  double d = data (i); \
+  tmp[j] += d * d
+
+  SPARSE_BASE_REDUCTION_OP (SparseMatrix, double, ROW_EXPR, COL_EXPR, 
+			    0.0, 0.0);
+
+#undef ROW_EXPR
+#undef COL_EXPR
+}
+
+SparseMatrix
+SparseMatrix::abs (void) const
+{
+  octave_idx_type nz = nnz ();
+
+  SparseMatrix retval (*this);
+
+  for (octave_idx_type i = 0; i < nz; i++)
+    retval.data(i) = fabs(retval.data(i));
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::diag (octave_idx_type k) const
+{
+  return MSparse<double>::diag (k);
+}
+
+Matrix
+SparseMatrix::matrix_value (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  Matrix retval (nr, nc, 0.0);
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+      retval.elem (ridx(i), j) = data (i);
+
+  return retval;
+}
+
+SparseMatrix
+SparseMatrix::map (dmapper fcn) const
+{
+  return MSparse<double>::map<double> (func_ptr (fcn));
+}
+
+SparseComplexMatrix
+SparseMatrix::map (cmapper fcn) const
+{
+  return MSparse<double>::map<Complex> (func_ptr (fcn));
+}
+
+SparseBoolMatrix
+SparseMatrix::map (bmapper fcn) const
+{
+  return MSparse<double>::map<bool> (func_ptr (fcn));
+}
+
+std::ostream&
+operator << (std::ostream& os, const SparseMatrix& a)
+{
+  octave_idx_type nc = a.cols ();
+
+   // add one to the printed indices to go from
+   //  zero-based to one-based arrays
+   for (octave_idx_type j = 0; j < nc; j++)  {
+      OCTAVE_QUIT;
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++) {
+	os << a.ridx(i) + 1 << " "  << j + 1 << " ";
+	octave_write_double (os, a.data(i));
+	os << "\n";
+      }
+   }
+
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, SparseMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type nz = a.nzmax ();
+
+  if (nr > 0 && nc > 0)
+    {
+      octave_idx_type itmp, jtmp, jold = 0;
+      double tmp;
+      octave_idx_type ii = 0;
+       
+      a.cidx (0) = 0;
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  is >> itmp;
+	  itmp--;
+	  is >> jtmp;
+	  jtmp--;
+	  tmp = octave_read_double (is);
+	  
+	  if (is)
+	    {
+	      if (jold != jtmp)
+		{
+		  for (octave_idx_type j = jold; j < jtmp; j++)
+		    a.cidx(j+1) = ii;
+		  
+		  jold = jtmp;
+		}
+	      a.data (ii) = tmp;
+	      a.ridx (ii++) = itmp;
+	    }
+	  else
+	    goto done;
+	}
+
+      for (octave_idx_type j = jold; j < nc; j++)
+	a.cidx(j+1) = ii;
+    }
+  
+ done:
+
+  return is;
+}
+
+SparseMatrix
+SparseMatrix::squeeze (void) const 
+{ 
+  return MSparse<double>::squeeze (); 
+}
+
+SparseMatrix
+SparseMatrix::index (idx_vector& i, int resize_ok) const 
+{ 
+  return MSparse<double>::index (i, resize_ok); 
+}
+
+SparseMatrix
+SparseMatrix::index (idx_vector& i, idx_vector& j, int resize_ok) const 
+{ 
+  return MSparse<double>::index (i, j, resize_ok); 
+}
+  
+SparseMatrix
+SparseMatrix::index (Array<idx_vector>& ra_idx, int resize_ok) const 
+{ 
+  return MSparse<double>::index (ra_idx, resize_ok); 
+}
+
+SparseMatrix
+SparseMatrix::reshape (const dim_vector& new_dims) const
+{
+  return MSparse<double>::reshape (new_dims);
+}
+
+SparseMatrix
+SparseMatrix::permute (const Array<octave_idx_type>& vec, bool inv) const
+{
+  return MSparse<double>::permute (vec, inv);
+}
+
+SparseMatrix
+SparseMatrix::ipermute (const Array<octave_idx_type>& vec) const
+{
+  return MSparse<double>::ipermute (vec);
+}
+
+// matrix by matrix -> matrix operations
+
+SparseMatrix
+operator * (const SparseMatrix& m, const SparseMatrix& a)
+{
+  SPARSE_SPARSE_MUL (SparseMatrix, double, double);
+}
+
+Matrix
+operator * (const Matrix& m, const SparseMatrix& a)
+{
+  FULL_SPARSE_MUL (Matrix, double, 0.);
+}
+
+Matrix
+mul_trans (const Matrix& m, const SparseMatrix& a)
+{
+  FULL_SPARSE_MUL_TRANS (Matrix, double, 0., );
+}
+
+Matrix
+operator * (const SparseMatrix& m, const Matrix& a)
+{
+  SPARSE_FULL_MUL (Matrix, double, 0.);
+}
+
+Matrix
+trans_mul (const SparseMatrix& m, const Matrix& a)
+{
+  SPARSE_FULL_TRANS_MUL (Matrix, double, 0., );
+}
+
+// diag * sparse and sparse * diag
+
+SparseMatrix
+operator * (const DiagMatrix& d, const SparseMatrix& a)
+{
+  return do_mul_dm_sm<SparseMatrix> (d, a);
+}
+
+SparseMatrix
+operator * (const SparseMatrix& a, const DiagMatrix& d)
+{
+  return do_mul_sm_dm<SparseMatrix> (a, d);
+}
+
+SparseMatrix
+operator + (const DiagMatrix& d, const SparseMatrix& a)
+{
+  return do_add_dm_sm<SparseMatrix> (d, a);
+}
+
+SparseMatrix
+operator - (const DiagMatrix& d, const SparseMatrix& a)
+{
+  return do_sub_dm_sm<SparseMatrix> (d, a);
+}
+
+SparseMatrix
+operator + (const SparseMatrix& a, const DiagMatrix& d)
+{
+  return do_add_sm_dm<SparseMatrix> (a, d);
+}
+
+SparseMatrix
+operator - (const SparseMatrix& a, const DiagMatrix& d)
+{
+  return do_sub_sm_dm<SparseMatrix> (a, d);
+}
+
+// perm * sparse and sparse * perm
+
+SparseMatrix
+operator * (const PermMatrix& p, const SparseMatrix& a)
+{
+  return octinternal_do_mul_pm_sm (p, a);
+}
+
+SparseMatrix
+operator * (const SparseMatrix& a, const PermMatrix& p)
+{
+  return octinternal_do_mul_sm_pm (a, p);
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nr == 0 || nc == 0) \
+    return T (nr, nc);
+
+SparseMatrix
+min (double d, const SparseMatrix& m)
+{
+  SparseMatrix result;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (SparseMatrix);
+
+  // Count the number of non-zero elements
+  if (d < 0.)
+    {
+      result = SparseMatrix (nr, nc, d);
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	  {
+	    double tmp = xmin (d, m.data (i));
+	    if (tmp != 0.)
+	      {
+		octave_idx_type idx = m.ridx(i) + j * nr;
+		result.xdata(idx) = tmp;
+		result.xridx(idx) = m.ridx(i);
+	      }
+	  }
+    }
+  else
+    {
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	  if (xmin (d, m.data (i)) != 0.)
+	    nel++;
+
+      result = SparseMatrix (nr, nc, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx(0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	    {
+	      double tmp = xmin (d, m.data (i));
+
+	      if (tmp != 0.)
+		{
+		  result.xdata(ii) = tmp;
+		  result.xridx(ii++) = m.ridx(i);
+		}
+	    }
+	  result.xcidx(j+1) = ii;
+	}
+    }
+
+  return result;
+}
+
+SparseMatrix
+min (const SparseMatrix& m, double d)
+{
+  return min (d, m);
+}
+
+SparseMatrix
+min (const SparseMatrix& a, const SparseMatrix& b)
+{
+  SparseMatrix r;
+
+  if ((a.rows() == b.rows()) && (a.cols() == b.cols())) 
+    {
+      octave_idx_type a_nr = a.rows ();
+      octave_idx_type a_nc = a.cols ();
+
+      octave_idx_type b_nr = b.rows ();
+      octave_idx_type b_nc = b.cols ();
+
+      if (a_nr != b_nr || a_nc != b_nc)
+	gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+      else
+	{
+	  r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+       
+	  octave_idx_type jx = 0;
+	  r.cidx (0) = 0;
+	  for (octave_idx_type i = 0 ; i < a_nc ; i++)
+	    {
+	      octave_idx_type  ja = a.cidx(i);
+	      octave_idx_type  ja_max = a.cidx(i+1);
+	      bool ja_lt_max= ja < ja_max;
+           
+	      octave_idx_type  jb = b.cidx(i);
+	      octave_idx_type  jb_max = b.cidx(i+1);
+	      bool jb_lt_max = jb < jb_max;
+           
+	      while (ja_lt_max || jb_lt_max )
+		{
+		  OCTAVE_QUIT;
+		  if ((! jb_lt_max) ||
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb))))
+		    {
+		      double tmp = xmin (a.data(ja), 0.);
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = a.ridx(ja);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		    }
+		  else if (( !ja_lt_max ) ||
+			   (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) )
+		    {
+		      double tmp = xmin (0., b.data(jb));
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = b.ridx(jb);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		  else
+		    {
+		      double tmp = xmin (a.data(ja), b.data(jb));
+		      if (tmp != 0.)
+			{
+                          r.data(jx) = tmp;
+                          r.ridx(jx) = a.ridx(ja);
+                          jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		}
+	      r.cidx(i+1) = jx;
+	    }
+	  
+	  r.maybe_compress ();
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("matrix size mismatch");
+
+  return r;
+}
+
+SparseMatrix
+max (double d, const SparseMatrix& m)
+{
+  SparseMatrix result;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (SparseMatrix);
+
+  // Count the number of non-zero elements
+  if (d > 0.)
+    {
+      result = SparseMatrix (nr, nc, d);
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	  {
+	    double tmp = xmax (d, m.data (i));
+
+	    if (tmp != 0.)
+	      {
+		octave_idx_type idx = m.ridx(i) + j * nr;
+		result.xdata(idx) = tmp;
+		result.xridx(idx) = m.ridx(i);
+	      }
+	  }
+    }
+  else
+    {
+      octave_idx_type nel = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	  if (xmax (d, m.data (i)) != 0.)
+	    nel++;
+
+      result = SparseMatrix (nr, nc, nel);
+
+      octave_idx_type ii = 0;
+      result.xcidx(0) = 0;
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	    {
+	      double tmp = xmax (d, m.data (i));
+	      if (tmp != 0.)
+		{
+		  result.xdata(ii) = tmp;
+		  result.xridx(ii++) = m.ridx(i);
+		}
+	    }
+	  result.xcidx(j+1) = ii;
+	}
+    }
+
+  return result;
+}
+
+SparseMatrix
+max (const SparseMatrix& m, double d)
+{
+  return max (d, m);
+}
+
+SparseMatrix
+max (const SparseMatrix& a, const SparseMatrix& b)
+{
+  SparseMatrix r;
+
+  if ((a.rows() == b.rows()) && (a.cols() == b.cols())) 
+    {
+      octave_idx_type a_nr = a.rows ();
+      octave_idx_type a_nc = a.cols ();
+
+      octave_idx_type b_nr = b.rows ();
+      octave_idx_type b_nc = b.cols ();
+
+      if (a_nr != b_nr || a_nc != b_nc)
+	gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+      else
+	{
+	  r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+       
+	  octave_idx_type jx = 0;
+	  r.cidx (0) = 0;
+	  for (octave_idx_type i = 0 ; i < a_nc ; i++)
+	    {
+	      octave_idx_type  ja = a.cidx(i);
+	      octave_idx_type  ja_max = a.cidx(i+1);
+	      bool ja_lt_max= ja < ja_max;
+           
+	      octave_idx_type  jb = b.cidx(i);
+	      octave_idx_type  jb_max = b.cidx(i+1);
+	      bool jb_lt_max = jb < jb_max;
+           
+	      while (ja_lt_max || jb_lt_max )
+		{
+		  OCTAVE_QUIT;
+		  if ((! jb_lt_max) ||
+                      (ja_lt_max && (a.ridx(ja) < b.ridx(jb))))
+		    {
+		      double tmp = xmax (a.data(ja), 0.);
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = a.ridx(ja);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		    }
+		  else if (( !ja_lt_max ) ||
+			   (jb_lt_max && (b.ridx(jb) < a.ridx(ja)) ) )
+		    {
+		      double tmp = xmax (0., b.data(jb));
+		      if (tmp != 0.)
+			{
+			  r.ridx(jx) = b.ridx(jb);
+			  r.data(jx) = tmp;
+			  jx++;
+			}
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		  else
+		    {
+		      double tmp = xmax (a.data(ja), b.data(jb));
+		      if (tmp != 0.)
+			{
+                          r.data(jx) = tmp;
+                          r.ridx(jx) = a.ridx(ja);
+                          jx++;
+			}
+		      ja++;
+		      ja_lt_max= ja < ja_max;
+		      jb++;
+		      jb_lt_max= jb < jb_max;
+		    }
+		}
+	      r.cidx(i+1) = jx;
+	    }
+	  
+	  r.maybe_compress ();
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("matrix size mismatch");
+
+  return r;
+}
+
+SPARSE_SMS_CMP_OPS (SparseMatrix, 0.0, , double, 0.0, )
+SPARSE_SMS_BOOL_OPS (SparseMatrix, double, 0.0)
+
+SPARSE_SSM_CMP_OPS (double, 0.0, , SparseMatrix, 0.0, )
+SPARSE_SSM_BOOL_OPS (double, SparseMatrix, 0.0)
+
+SPARSE_SMSM_CMP_OPS (SparseMatrix, 0.0, , SparseMatrix, 0.0, )
+SPARSE_SMSM_BOOL_OPS (SparseMatrix, SparseMatrix, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dSparse.h b/liboctave/dSparse.h
new file mode 100644
index 0000000..5da6ece
--- /dev/null
+++ b/liboctave/dSparse.h
@@ -0,0 +1,497 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dSparse_h)
+#define octave_dSparse_h 1
+
+#include "dMatrix.h"
+#include "dNDArray.h"
+#include "CMatrix.h"
+#include "dColVector.h"
+#include "CColVector.h"
+
+#include "DET.h"
+#include "MSparse.h"
+#include "MSparse-defs.h"
+#include "Sparse-op-defs.h"
+#include "MatrixType.h"
+
+class PermMatrix;
+class DiagMatrix;
+class SparseComplexMatrix;
+class SparseBoolMatrix;
+
+class
+OCTAVE_API
+SparseMatrix : public MSparse<double>
+{
+ public:
+
+  typedef void (*solve_singularity_handler) (double rcond);
+
+  SparseMatrix (void) : MSparse<double> () { }
+
+  SparseMatrix (octave_idx_type r, octave_idx_type c) : MSparse<double> (r, c) { }
+
+  SparseMatrix (const dim_vector& dv, octave_idx_type nz = 0) : 
+    MSparse<double> (dv, nz) { }
+
+  explicit SparseMatrix (octave_idx_type r, octave_idx_type c, double val) 
+    : MSparse<double> (r, c, val) { }
+
+  SparseMatrix (const SparseMatrix& a) : MSparse<double> (a) { }
+
+  SparseMatrix (const SparseMatrix& a, const dim_vector& dv) 
+    : MSparse<double> (a, dv) { }
+
+  SparseMatrix (const MSparse<double>& a) : MSparse<double> (a) { }
+
+  explicit SparseMatrix (const SparseBoolMatrix& a);
+
+  explicit SparseMatrix (const Matrix& a) : MSparse<double> (a) { }
+
+  explicit SparseMatrix (const NDArray& a) : MSparse<double> (a) { }
+
+  explicit SparseMatrix (const Array<double> a, const Array<octave_idx_type>& r, 
+			 const Array<octave_idx_type>& c, octave_idx_type nr = -1, 
+			 octave_idx_type nc = -1, bool sum_terms = true)
+    : MSparse<double> (a, r, c, nr, nc, sum_terms) { }
+
+  explicit SparseMatrix (const Array<double> a, const Array<double>& r, 
+			 const Array<double>& c, octave_idx_type nr = -1, 
+			 octave_idx_type nc = -1, bool sum_terms = true)
+    : MSparse<double> (a, r, c, nr, nc, sum_terms) { }
+
+  explicit SparseMatrix (const DiagMatrix& a);
+
+  explicit SparseMatrix (const PermMatrix& a);
+
+  SparseMatrix (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : MSparse<double> (r, c, num_nz) { }
+
+  SparseMatrix& operator = (const SparseMatrix& a)
+    {
+      MSparse<double>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const SparseMatrix& a) const;
+  bool operator != (const SparseMatrix& a) const;
+
+  bool is_symmetric (void) const;
+
+  SparseMatrix max (int dim = 0) const;
+  SparseMatrix max (Array2<octave_idx_type>& index, int dim = 0) const;
+  SparseMatrix min (int dim = 0) const;
+  SparseMatrix min (Array2<octave_idx_type>& index, int dim = 0) const;
+  
+  // destructive insert/delete/reorder operations
+
+  SparseMatrix& insert (const SparseMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  SparseMatrix& insert (const SparseMatrix& a, const Array<octave_idx_type>& indx);
+
+  SparseMatrix concat (const SparseMatrix& rb, const Array<octave_idx_type>& ra_idx);
+  SparseComplexMatrix concat (const SparseComplexMatrix& rb,
+			      const Array<octave_idx_type>& ra_idx);
+
+  friend OCTAVE_API SparseMatrix real (const SparseComplexMatrix& a);
+  friend OCTAVE_API SparseMatrix imag (const SparseComplexMatrix& a);
+
+  friend OCTAVE_API SparseMatrix atan2 (const double& x, const SparseMatrix& y);
+  friend OCTAVE_API SparseMatrix atan2 (const SparseMatrix& x, const double& y);
+  friend OCTAVE_API SparseMatrix atan2 (const SparseMatrix& x, const SparseMatrix& y);
+
+  SparseMatrix transpose (void) const 
+    { 
+      return MSparse<double>::transpose (); 
+    }
+  SparseMatrix hermitian (void) const { return transpose (); }
+
+  // extract row or column i.
+
+  RowVector row (octave_idx_type i) const;
+
+  ColumnVector column (octave_idx_type i) const;
+
+private:
+  SparseMatrix dinverse (MatrixType &mattyp, octave_idx_type& info, 
+			 double& rcond, const bool force = false, 
+			 const bool calccond = true) const;
+
+  SparseMatrix tinverse (MatrixType &mattyp, octave_idx_type& info, 
+			 double& rcond, const bool force = false, 
+			 const bool calccond = true) const;
+
+public:
+  SparseMatrix inverse (void) const;
+  SparseMatrix inverse (MatrixType& mattype) const;
+  SparseMatrix inverse (MatrixType& mattype, octave_idx_type& info) const;
+  SparseMatrix inverse (MatrixType& mattype, octave_idx_type& info, 
+		        double& rcond, int force = 0, int calc_cond = 1) const;
+
+  DET determinant (void) const;
+  DET determinant (octave_idx_type& info) const;
+  DET determinant (octave_idx_type& info, double& rcond, int calc_cond = 1) const;
+
+private:
+  // Diagonal matrix solvers
+  Matrix dsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix dsolve (MatrixType &typ, const ComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler, 
+		bool calc_cond = false) const;
+
+  SparseMatrix dsolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix dsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Upper triangular matrix solvers
+  Matrix utsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix utsolve (MatrixType &typ, const ComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseMatrix utsolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond,
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix utsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Lower triangular matrix solvers
+  Matrix ltsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix ltsolve (MatrixType &typ, const ComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseMatrix ltsolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix ltsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Tridiagonal matrix solvers
+  Matrix trisolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix trisolve (MatrixType &typ, const ComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseMatrix trisolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond,
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix trisolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Banded matrix solvers (umfpack/cholesky)
+  Matrix bsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix bsolve (MatrixType &typ, const ComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseMatrix bsolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix bsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  // Full matrix solvers (umfpack/cholesky)
+  void * factorize (octave_idx_type& err, double &rcond, Matrix &Control,
+		    Matrix &Info, solve_singularity_handler sing_handler,
+		    bool calc_cond = false) const;
+
+  Matrix fsolve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  ComplexMatrix fsolve (MatrixType &typ, const ComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseMatrix fsolve (MatrixType &typ, const SparseMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+  SparseComplexMatrix fsolve (MatrixType &typ, const SparseComplexMatrix& b,
+		octave_idx_type& info, double& rcond, 
+		solve_singularity_handler sing_handler,
+		bool calc_cond = false) const;
+
+public:
+  // Generic interface to solver with no probing of type
+  Matrix solve (MatrixType &typ, const Matrix& b) const;
+  Matrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info) const;
+  Matrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, 
+		double& rcond) const;
+  Matrix solve (MatrixType &typ, const Matrix& b, octave_idx_type& info,
+		double& rcond, solve_singularity_handler sing_handler,
+		bool singular_fallback = true) const;
+
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b, 
+		       octave_idx_type& info, double& rcond) const;
+  ComplexMatrix solve (MatrixType &typ, const ComplexMatrix& b,
+		       octave_idx_type& info, double& rcond, 
+		       solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  SparseMatrix solve (MatrixType &typ, const SparseMatrix& b) const;
+  SparseMatrix solve (MatrixType &typ, const SparseMatrix& b, 
+		      octave_idx_type& info) const;
+  SparseMatrix solve (MatrixType &typ, const SparseMatrix& b,
+		      octave_idx_type& info, double& rcond) const;
+  SparseMatrix solve (MatrixType &typ, const SparseMatrix& b,
+		      octave_idx_type& info, double& rcond, 
+		      solve_singularity_handler sing_handler,
+		      bool singular_fallback = true) const;
+
+  SparseComplexMatrix solve (MatrixType &typ, 
+			     const SparseComplexMatrix& b) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseComplexMatrix& b, 
+			     octave_idx_type& info) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseComplexMatrix& b, 
+			     octave_idx_type& info, double& rcond) const;
+  SparseComplexMatrix solve (MatrixType &typ, const SparseComplexMatrix& b,
+			     octave_idx_type& info, double& rcond, 
+			     solve_singularity_handler sing_handler,
+			     bool singular_fallabck = true) const;
+
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b) const;
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info) const;
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b, 
+		      octave_idx_type& info, double& rcond) const;
+  ColumnVector solve (MatrixType &typ, const ColumnVector& b,
+		      octave_idx_type& info, double& rcond, 
+		      solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (MatrixType &typ, 
+			     const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b,
+			     octave_idx_type& info, double& rcond) const;
+  ComplexColumnVector solve (MatrixType &typ, const ComplexColumnVector& b,
+			     octave_idx_type& info, double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  // Generic interface to solver with probing of type
+  Matrix solve (const Matrix& b) const;
+  Matrix solve (const Matrix& b, octave_idx_type& info) const;
+  Matrix solve (const Matrix& b, octave_idx_type& info, double& rcond) const;
+  Matrix solve (const Matrix& b, octave_idx_type& info, double& rcond,
+		solve_singularity_handler sing_handler) const;
+
+  ComplexMatrix solve (const ComplexMatrix& b) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, 
+		       double& rcond) const;
+  ComplexMatrix solve (const ComplexMatrix& b, octave_idx_type& info, double& rcond,
+		       solve_singularity_handler sing_handler) const;
+
+  SparseMatrix solve (const SparseMatrix& b) const;
+  SparseMatrix solve (const SparseMatrix& b, octave_idx_type& info) const;
+  SparseMatrix solve (const SparseMatrix& b, octave_idx_type& info, 
+		      double& rcond) const;
+  SparseMatrix solve (const SparseMatrix& b, octave_idx_type& info, double& rcond,
+		solve_singularity_handler sing_handler) const;
+
+  SparseComplexMatrix solve (const SparseComplexMatrix& b) const;
+  SparseComplexMatrix solve (const SparseComplexMatrix& b, octave_idx_type& info) const;
+  SparseComplexMatrix solve (const SparseComplexMatrix& b, octave_idx_type& info, 
+			     double& rcond) const;
+  SparseComplexMatrix solve (const SparseComplexMatrix& b, octave_idx_type& info, 
+			     double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  ColumnVector solve (const ColumnVector& b) const;
+  ColumnVector solve (const ColumnVector& b, octave_idx_type& info) const;
+  ColumnVector solve (const ColumnVector& b, octave_idx_type& info, double& rcond) const;
+  ColumnVector solve (const ColumnVector& b, octave_idx_type& info, double& rcond,
+		      solve_singularity_handler sing_handler) const;
+
+  ComplexColumnVector solve (const ComplexColumnVector& b) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcond) const;
+  ComplexColumnVector solve (const ComplexColumnVector& b, octave_idx_type& info,
+			     double& rcond,
+			     solve_singularity_handler sing_handler) const;
+
+  // other operations
+
+  bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool all_elements_are_zero (void) const;
+  bool all_elements_are_int_or_inf_or_nan (void) const;
+  bool all_integers (double& max_val, double& min_val) const;
+  bool too_large_for_float (void) const;
+ 
+  SparseBoolMatrix operator ! (void) const;
+
+  SparseBoolMatrix all (int dim = -1) const;
+  SparseBoolMatrix any (int dim = -1) const;
+
+  SparseMatrix cumprod (int dim = -1) const;
+  SparseMatrix cumsum (int dim = -1) const;
+  SparseMatrix prod (int dim = -1) const;
+  SparseMatrix sum (int dim = -1) const;
+  SparseMatrix sumsq (int dim = -1) const;
+  SparseMatrix abs (void) const;
+
+  SparseMatrix diag (octave_idx_type k = 0) const;
+
+  Matrix matrix_value (void) const;
+
+  SparseMatrix squeeze (void) const;
+
+  SparseMatrix index (idx_vector& i, int resize_ok) const;
+
+  SparseMatrix index (idx_vector& i, idx_vector& j, int resize_ok) const;
+  
+  SparseMatrix index (Array<idx_vector>& ra_idx, int resize_ok) const;
+
+  SparseMatrix reshape (const dim_vector& new_dims) const;
+
+  SparseMatrix permute (const Array<octave_idx_type>& vec, bool inv = false) const;
+
+  SparseMatrix ipermute (const Array<octave_idx_type>& vec) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const SparseMatrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, SparseMatrix& a);
+
+  typedef double (*dmapper) (double);
+  typedef Complex (*cmapper) (const Complex&);
+  typedef bool (*bmapper) (double);
+  SparseMatrix map (dmapper fcn) const;
+  SparseComplexMatrix map (cmapper fcn) const;
+  SparseBoolMatrix map (bmapper fcn) const;
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API SparseMatrix real (const SparseComplexMatrix& a);
+extern OCTAVE_API SparseMatrix imag (const SparseComplexMatrix& a);
+
+// Other operators.
+
+extern OCTAVE_API SparseMatrix operator * (const SparseMatrix& a, 
+				const SparseMatrix& b);
+extern OCTAVE_API Matrix operator * (const Matrix& a, 
+				const SparseMatrix& b);
+extern OCTAVE_API Matrix mul_trans (const Matrix& a, 
+				const SparseMatrix& b);
+extern OCTAVE_API Matrix operator * (const SparseMatrix& a, 
+				const Matrix& b);
+extern OCTAVE_API Matrix trans_mul (const SparseMatrix& a, 
+				const Matrix& b);
+
+extern OCTAVE_API SparseMatrix operator * (const DiagMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseMatrix operator * (const SparseMatrix&, const DiagMatrix&);
+
+extern OCTAVE_API SparseMatrix operator + (const DiagMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseMatrix operator + (const SparseMatrix&, const DiagMatrix&);
+extern OCTAVE_API SparseMatrix operator - (const DiagMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseMatrix operator - (const SparseMatrix&, const DiagMatrix&);
+
+extern OCTAVE_API SparseMatrix operator * (const PermMatrix&, const SparseMatrix&);
+extern OCTAVE_API SparseMatrix operator * (const SparseMatrix&, const PermMatrix&);
+
+extern OCTAVE_API SparseMatrix min (double d, const SparseMatrix& m);
+extern OCTAVE_API SparseMatrix min (const SparseMatrix& m, double d);
+extern OCTAVE_API SparseMatrix min (const SparseMatrix& a, const SparseMatrix& b);
+
+extern OCTAVE_API SparseMatrix max (double d, const SparseMatrix& m);
+extern OCTAVE_API SparseMatrix max (const SparseMatrix& m, double d);
+extern OCTAVE_API SparseMatrix max (const SparseMatrix& a, const SparseMatrix& b);
+
+SPARSE_SMS_CMP_OP_DECLS (SparseMatrix, double, OCTAVE_API)
+SPARSE_SMS_BOOL_OP_DECLS (SparseMatrix, double, OCTAVE_API)
+
+SPARSE_SSM_CMP_OP_DECLS (double, SparseMatrix, OCTAVE_API)
+SPARSE_SSM_BOOL_OP_DECLS (double, SparseMatrix, OCTAVE_API)
+
+SPARSE_SMSM_CMP_OP_DECLS (SparseMatrix, SparseMatrix, OCTAVE_API)
+SPARSE_SMSM_BOOL_OP_DECLS (SparseMatrix, SparseMatrix, OCTAVE_API)
+
+SPARSE_FORWARD_DEFS (MSparse, SparseMatrix, Matrix, double)
+
+#ifdef IDX_TYPE_LONG
+#define UMFPACK_DNAME(name) umfpack_dl_ ## name
+#else
+#define UMFPACK_DNAME(name) umfpack_di_ ## name
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/data-conv.cc b/liboctave/data-conv.cc
new file mode 100644
index 0000000..081f8aa
--- /dev/null
+++ b/liboctave/data-conv.cc
@@ -0,0 +1,1219 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cstdlib>
+
+#include <iostream>
+#include <vector>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "oct-locbuf.h"
+
+template void swap_bytes<2> (volatile void *, int);
+template void swap_bytes<4> (volatile void *, int);
+template void swap_bytes<8> (volatile void *, int);
+
+#if defined HAVE_LONG_LONG_INT
+#define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
+  do \
+    { \
+      int sz = BITS / CHAR_BIT; \
+      if (sizeof (TQ char) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## char; \
+      else if (sizeof (TQ short) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## short; \
+      else if (sizeof (TQ int) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## int; \
+      else if (sizeof (TQ long) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## long; \
+      else if (sizeof (TQ long long) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## longlong; \
+      else \
+        VAL = oct_data_conv::dt_unknown; \
+    } \
+  while (0)
+#else
+#define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
+  do \
+    { \
+      int sz = BITS / CHAR_BIT; \
+      if (sizeof (TQ char) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## char; \
+      else if (sizeof (TQ short) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## short; \
+      else if (sizeof (TQ int) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## int; \
+      else if (sizeof (TQ long) == sz) \
+	VAL = oct_data_conv::dt_ ## Q ## long; \
+      else \
+        VAL = oct_data_conv::dt_unknown; \
+    } \
+  while (0)
+#endif
+
+#define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \
+  do \
+    { \
+      int sz = BITS / CHAR_BIT; \
+      if (sizeof (float) == sz) \
+	VAL = oct_data_conv::dt_float; \
+      else if (sizeof (double) == sz) \
+	VAL = oct_data_conv::dt_double; \
+      else \
+        VAL = oct_data_conv::dt_unknown; \
+    } \
+  while (0)
+
+// I'm not sure it is worth the trouble, but let's use a lookup table
+// for the types that are supposed to be a specific number of bits
+// wide.  Given the macros above, this should work as long as CHAR_BIT
+// is a multiple of 8 and there are types with the right sizes.
+//
+// The sized data type lookup table has the following format:
+//
+//                            bits
+//                    +----+----+----+----+
+//                    |  8 | 16 | 32 | 64 |
+//                    +----+----+----+----+
+//     signed integer |    |    |    |    |
+//                    +----+----+----+----+
+//   unsigned integer |    |    |    |    |
+//                    +----+----+----+----+
+//     floating point |    |    |    |    |
+//                    +----+----+----+----+
+//
+// So, the 0,3 element is supposed to contain the oct_data_conv enum
+// value corresponding to the correct native data type for a signed
+// 32-bit integer.
+
+static void
+init_sized_type_lookup_table (oct_data_conv::data_type table[3][4])
+{
+  int bits = 8;
+
+  for (int i = 0; i < 4; i++)
+    {
+      FIND_SIZED_INT_TYPE (table[0][i], bits, , );
+
+      FIND_SIZED_INT_TYPE (table[1][i], bits, unsigned, u);
+
+      FIND_SIZED_FLOAT_TYPE (table[2][i], bits);
+
+      bits *= 2;
+    }
+}
+
+static std::string
+strip_spaces (const std::string& str)
+{
+  int n = str.length ();
+
+  int k = 0;
+
+  std::string s (n, ' ');
+
+  for (int i = 0; i < n; i++)
+    if (! isspace (str[i]))
+      s[k++] = tolower (str[i]);
+
+  s.resize (k);
+
+  return s;
+}
+
+#define GET_SIZED_INT_TYPE(T, U) \
+  do \
+    { \
+      switch (sizeof (T)) \
+	{ \
+	case 1: \
+	  retval = dt_ ## U ## int8; \
+	  break; \
+ \
+	case 2: \
+	  retval = dt_ ## U ## int16; \
+	  break; \
+ \
+	case 4: \
+	  retval = dt_ ## U ## int32; \
+	  break; \
+ \
+	case 8: \
+	  retval = dt_ ## U ## int64; \
+	  break; \
+ \
+	default: \
+	  retval = dt_unknown; \
+	  break; \
+	} \
+    } \
+  while (0)
+
+oct_data_conv::data_type
+oct_data_conv::string_to_data_type (const std::string& str)
+{
+  data_type retval = dt_unknown;
+
+  static bool initialized = false;
+
+  static data_type sized_type_table[3][4];
+
+  if (! initialized)
+    {
+      init_sized_type_lookup_table (sized_type_table);
+
+      initialized = true;
+    }
+
+  std::string s = strip_spaces (str);
+
+  if (s == "int8" || s == "integer*1")
+    retval = dt_int8;
+  else if (s == "uint8")
+    retval = dt_uint8;
+  else if (s == "int16" || s == "integer*2")
+    retval = dt_int16;
+  else if (s == "uint16")
+    retval = dt_uint16;
+  else if (s == "int32" || s == "integer*4")
+    retval = dt_int32;
+  else if (s == "uint32")
+    retval = dt_uint32;
+  else if (s == "int64" || s == "integer*8")
+    retval = dt_int64;
+  else if (s == "uint64")
+    retval = dt_uint64;
+  else if (s == "single" || s == "float32" || s == "real*4")
+    retval = dt_single;
+  else if (s == "double" || s == "float64" || s == "real*8")
+    retval = dt_double;
+  else if (s == "char" || s == "char*1")
+    retval = dt_char;
+  else if (s == "schar" || s == "signedchar")
+    retval = dt_schar;
+  else if (s == "uchar" || s == "unsignedchar")
+    retval = dt_uchar;
+  else if (s == "short")
+    GET_SIZED_INT_TYPE (short, );
+  else if (s == "ushort" || s == "unsignedshort")
+    GET_SIZED_INT_TYPE (unsigned short, u);
+  else if (s == "int")
+    GET_SIZED_INT_TYPE (int, );
+  else if (s == "uint" || s == "unsignedint")
+    GET_SIZED_INT_TYPE (unsigned int, u);
+  else if (s == "long")
+    GET_SIZED_INT_TYPE (long, );
+  else if (s == "ulong" || s == "unsignedlong")
+    GET_SIZED_INT_TYPE (unsigned long, u);
+  else if (s == "longlong")
+    GET_SIZED_INT_TYPE (long long, );
+  else if (s == "ulonglong" || s == "unsignedlonglong")
+    GET_SIZED_INT_TYPE (unsigned long long, u);
+  else if (s == "float")
+    {
+      if (sizeof (float) == sizeof (double))
+	retval = dt_double;
+      else
+	retval = dt_single;
+    }
+  else if (s == "logical")
+    retval = dt_logical;
+  else
+    (*current_liboctave_error_handler) ("invalid data type specified");
+
+  if (retval == dt_unknown)
+    (*current_liboctave_error_handler)
+      ("unable to find matching native data type for %s", s.c_str ());
+
+  return retval;
+}
+
+void
+oct_data_conv::string_to_data_type
+  (const std::string& str, int& block_size,
+   oct_data_conv::data_type& input_type,
+   oct_data_conv::data_type& output_type)
+{
+  block_size = 1;
+  input_type = dt_uchar;
+  output_type = dt_double;
+
+  bool input_is_output = false;
+
+  std::string s = strip_spaces (str);
+
+  size_t pos = 0;
+
+  if (s[0] == '*')
+    input_is_output = true;
+  else
+    {
+      size_t len = s.length ();
+
+      while (pos < len && isdigit (s[pos]))
+	pos++;
+
+      if (pos > 0)
+	{
+	  if (s[pos] == '*')
+	    {
+	      block_size = atoi (s.c_str ());
+	      s = s.substr (pos+1);
+	    }
+	  else
+	    {
+	      (*current_liboctave_error_handler)
+		("invalid repeat count in `%s'", str.c_str ());
+
+	      return;
+	    }
+	}
+    }
+
+  pos = s.find ('=');
+
+  if (pos != std::string::npos)
+    {
+      if (s[pos+1] == '>')
+	{
+	  std::string s1;
+
+	  if (input_is_output)
+	    {
+	      input_is_output = false;
+
+	      s1 = s.substr (1, pos-1);
+
+	      (*current_liboctave_warning_handler)
+		("warning: ignoring leading * in fread precision");
+	    }
+	  else
+	    s1 = s.substr (0, pos);
+
+	  input_type = string_to_data_type (s1);
+	  output_type = string_to_data_type (s.substr (pos+2));
+	}
+      else
+	(*current_liboctave_error_handler)
+	  ("fread: invalid precision specified");
+    }
+  else
+    {
+      if (input_is_output)
+	s = s.substr (1);
+
+      input_type = string_to_data_type (s);
+
+      if (input_is_output)
+	output_type = input_type;
+    }
+}
+
+void
+oct_data_conv::string_to_data_type
+  (const std::string& str, int& block_size,
+   oct_data_conv::data_type& output_type)
+{
+  block_size = 1;
+  output_type = dt_double;
+
+  std::string s = strip_spaces (str);
+
+  size_t pos = 0;
+
+  size_t len = s.length ();
+
+  while (pos < len && isdigit (s[pos]))
+    pos++;
+
+  if (pos > 0)
+    {
+      if (s[pos] == '*')
+	{
+	  block_size = atoi (s.c_str ());
+	  s = s.substr (pos+1);
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("invalid repeat count in `%s'", str.c_str ());
+
+	  return;
+	}
+    }
+
+  output_type = string_to_data_type (s);
+}
+
+std::string
+oct_data_conv::data_type_as_string (oct_data_conv::data_type dt)
+{
+  std::string retval;
+
+  switch (dt)
+    {
+    case oct_data_conv::dt_int8:
+      retval = "int8";
+      break;
+
+    case oct_data_conv::dt_uint8:
+      retval = "uint8";
+      break;
+
+    case oct_data_conv::dt_int16:
+      retval = "int16";
+      break;
+
+    case oct_data_conv::dt_uint16:
+      retval = "uint16";
+      break;
+
+    case oct_data_conv::dt_int32:
+      retval = "int32";
+      break;
+
+    case oct_data_conv::dt_uint32:
+      retval = "uint32";
+      break;
+
+    case oct_data_conv::dt_int64:
+      retval = "int64";
+      break;
+
+    case oct_data_conv::dt_uint64:
+      retval = "uint64";
+      break;
+
+    case oct_data_conv::dt_single:
+      retval = "single";
+      break;
+
+    case oct_data_conv::dt_double:
+      retval = "double";
+      break;
+
+    case oct_data_conv::dt_char:
+      retval = "char";
+      break;
+
+    case oct_data_conv::dt_schar:
+      retval = "signed char";
+      break;
+
+    case oct_data_conv::dt_uchar:
+      retval = "usigned char";
+      break;
+
+    case oct_data_conv::dt_short:
+      retval = "short";
+      break;
+
+    case oct_data_conv::dt_ushort:
+      retval = "unsigned short";
+      break;
+
+    case oct_data_conv::dt_int:
+      retval = "int";
+      break;
+
+    case oct_data_conv::dt_uint:
+      retval = "usigned int";
+      break;
+
+    case oct_data_conv::dt_long:
+      retval = "long";
+      break;
+
+    case oct_data_conv::dt_ulong:
+      retval = "usigned long";
+      break;
+
+    case oct_data_conv::dt_longlong:
+      retval = "long long";
+      break;
+
+    case oct_data_conv::dt_ulonglong:
+      retval = "unsigned long long";
+      break;
+
+    case oct_data_conv::dt_float:
+      retval = "float";
+      break;
+
+    case oct_data_conv::dt_logical:
+      retval = "logical";
+      break;
+
+    case oct_data_conv::dt_unknown:
+    default:
+      retval = "unknown";
+      break;
+    }
+
+  return retval;
+}
+
+#define LS_DO_READ(TYPE, swap, data, size, len, stream) \
+  do \
+    { \
+      if (len > 0) \
+	{ \
+	  OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
+	  stream.read (reinterpret_cast<char *>  (ptr), size * len); \
+	  if (swap) \
+	    swap_bytes< size > (ptr, len); \
+	  for (int i = 0; i < len; i++) \
+	    data[i] = ptr[i]; \
+	} \
+    } \
+  while (0)
+
+// Have to use copy here to avoid writing over data accessed via
+// Matrix::data().
+
+#define LS_DO_WRITE(TYPE, data, size, len, stream) \
+  do \
+    { \
+      if (len > 0) \
+	{ \
+	  char tmp_type = type; \
+	  stream.write (&tmp_type, 1); \
+	  OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
+	  for (int i = 0; i < len; i++) \
+	    ptr[i] = static_cast <TYPE> (data[i]);	   \
+	  stream.write (reinterpret_cast<char *> (ptr), size * len); \
+	} \
+    } \
+  while (0)
+
+// Loading variables from files.
+
+static void
+gripe_unrecognized_float_fmt (void)
+{
+  (*current_liboctave_error_handler)
+    ("unrecognized floating point format requested");
+}
+
+static void
+gripe_data_conversion (const char *from, const char *to)
+{
+  (*current_liboctave_error_handler)
+    ("unable to convert from %s to %s format", from, to);
+}
+
+// But first, some data conversion routines.
+
+// Currently, we only handle conversions for the IEEE types.  To fix
+// that, make more of the following routines work.
+
+// FIXME -- assumes sizeof (Complex) == 8
+// FIXME -- assumes sizeof (double) == 8
+// FIXME -- assumes sizeof (float) == 4
+
+static void
+IEEE_big_double_to_IEEE_little_double (void *d, int len)
+{
+  swap_bytes<8> (d, len);
+}
+
+static void
+VAX_D_double_to_IEEE_little_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE little endian format");
+}
+
+static void
+VAX_G_double_to_IEEE_little_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE little endian format");
+}
+
+static void
+Cray_to_IEEE_little_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE little endian format");
+}
+
+static void
+IEEE_big_float_to_IEEE_little_float (void *d, int len)
+{
+  swap_bytes<4> (d, len);
+}
+
+static void
+VAX_D_float_to_IEEE_little_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE little endian format");
+}
+
+static void
+VAX_G_float_to_IEEE_little_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE little endian format");
+}
+
+static void
+Cray_to_IEEE_little_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE little endian format");
+}
+
+static void
+IEEE_little_double_to_IEEE_big_double (void *d, int len)
+{
+  swap_bytes<8> (d, len);
+}
+
+static void
+VAX_D_double_to_IEEE_big_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE big endian format");
+}
+
+static void
+VAX_G_double_to_IEEE_big_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE big endian format");
+}
+
+static void
+Cray_to_IEEE_big_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE big endian format");
+}
+
+static void
+IEEE_little_float_to_IEEE_big_float (void *d, int len)
+{
+  swap_bytes<4> (d, len);
+}
+
+static void
+VAX_D_float_to_IEEE_big_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE big endian format");
+}
+
+static void
+VAX_G_float_to_IEEE_big_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE big endian format");
+}
+
+static void
+Cray_to_IEEE_big_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE big endian format");
+}
+
+static void
+IEEE_little_double_to_VAX_D_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX D");
+}
+
+static void
+IEEE_big_double_to_VAX_D_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX D");
+}
+
+static void
+VAX_G_double_to_VAX_D_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX D");
+}
+
+static void
+Cray_to_VAX_D_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "VAX D");
+}
+
+static void
+IEEE_little_float_to_VAX_D_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX D");
+}
+
+static void
+IEEE_big_float_to_VAX_D_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX D");
+}
+
+static void
+VAX_G_float_to_VAX_D_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX D");
+}
+
+static void
+Cray_to_VAX_D_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "VAX D");
+}
+
+static void
+IEEE_little_double_to_VAX_G_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX G");
+}
+
+static void
+IEEE_big_double_to_VAX_G_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX G");
+}
+
+static void
+VAX_D_double_to_VAX_G_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "VAX G");
+}
+
+static void
+Cray_to_VAX_G_double (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX G");
+}
+
+static void
+IEEE_little_float_to_VAX_G_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX G");
+}
+
+static void
+IEEE_big_float_to_VAX_G_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX G");
+}
+
+static void
+VAX_D_float_to_VAX_G_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "VAX G");
+}
+
+static void
+Cray_to_VAX_G_float (void * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX G");
+}
+
+void
+do_double_format_conversion (void *data, int len,
+			     oct_mach_info::float_format from_fmt,
+			     oct_mach_info::float_format to_fmt)
+{
+  switch (to_fmt)
+    {
+    case oct_mach_info::flt_fmt_ieee_little_endian:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  IEEE_big_double_to_IEEE_little_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  VAX_D_double_to_IEEE_little_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  VAX_G_double_to_IEEE_little_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_IEEE_little_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case oct_mach_info::flt_fmt_ieee_big_endian:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  IEEE_little_double_to_IEEE_big_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  VAX_D_double_to_IEEE_big_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  VAX_G_double_to_IEEE_big_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_IEEE_big_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case oct_mach_info::flt_fmt_vax_d:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  IEEE_little_double_to_VAX_D_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  IEEE_big_double_to_VAX_D_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  VAX_G_double_to_VAX_D_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_VAX_D_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case oct_mach_info::flt_fmt_vax_g:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  IEEE_little_double_to_VAX_G_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  IEEE_big_double_to_VAX_G_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  VAX_D_double_to_VAX_G_double (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_VAX_G_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("impossible state reached in file `%s' at line %d",
+	 __FILE__, __LINE__);
+      break;
+    }
+}
+
+void
+do_float_format_conversion (void *data, int len,
+			    oct_mach_info::float_format from_fmt,
+			    oct_mach_info::float_format to_fmt)
+{
+  switch (to_fmt)
+    {
+    case oct_mach_info::flt_fmt_ieee_little_endian:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  IEEE_big_float_to_IEEE_little_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  VAX_D_float_to_IEEE_little_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  VAX_G_float_to_IEEE_little_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_IEEE_little_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case oct_mach_info::flt_fmt_ieee_big_endian:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  IEEE_little_float_to_IEEE_big_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  VAX_D_float_to_IEEE_big_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  VAX_G_float_to_IEEE_big_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_IEEE_big_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case oct_mach_info::flt_fmt_vax_d:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  IEEE_little_float_to_VAX_D_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  IEEE_big_float_to_VAX_D_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  VAX_G_float_to_VAX_D_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_VAX_D_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case oct_mach_info::flt_fmt_vax_g:
+      switch (from_fmt)
+	{
+	case oct_mach_info::flt_fmt_ieee_little_endian:
+	  IEEE_little_float_to_VAX_G_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_ieee_big_endian:
+	  IEEE_big_float_to_VAX_G_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_d:
+	  VAX_D_float_to_VAX_G_float (data, len);
+	  break;
+
+	case oct_mach_info::flt_fmt_vax_g:
+	  break;
+
+	case oct_mach_info::flt_fmt_cray:
+	  Cray_to_VAX_G_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("impossible state reached in file `%s' at line %d",
+	 __FILE__, __LINE__);
+      break;
+    }
+}
+
+void
+do_float_format_conversion (void *data, size_t sz, int len,
+			    oct_mach_info::float_format from_fmt,
+			    oct_mach_info::float_format to_fmt)
+{
+  switch (sz)
+    {
+    case sizeof (float):
+      do_float_format_conversion (data, len, from_fmt, to_fmt);
+      break;
+
+    case sizeof (double):
+      do_double_format_conversion (data, len, from_fmt, to_fmt);
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("impossible state reached in file `%s' at line %d",
+	 __FILE__, __LINE__);
+      break;
+    }
+}
+
+
+void
+read_doubles (std::istream& is, double *data, save_type type, int len,
+	      bool swap, oct_mach_info::float_format fmt)
+{
+  switch (type)
+    {
+    case LS_U_CHAR:
+      LS_DO_READ (uint8_t, swap, data, 1, len, is);
+      break;
+
+    case LS_U_SHORT:
+      LS_DO_READ (uint16_t, swap, data, 2, len, is);
+      break;
+
+    case LS_U_INT:
+      LS_DO_READ (uint32_t, swap, data, 4, len, is);
+      break;
+
+    case LS_CHAR:
+      LS_DO_READ (int8_t, swap, data, 1, len, is);
+      break;
+
+    case LS_SHORT:
+      LS_DO_READ (int16_t, swap, data, 2, len, is);
+      break;
+
+    case LS_INT:
+      LS_DO_READ (int32_t, swap, data, 4, len, is);
+      break;
+
+    case LS_FLOAT:
+      {
+	OCTAVE_LOCAL_BUFFER (float, ptr, len);
+	is.read (reinterpret_cast<char *> (ptr), 4 * len);
+	do_float_format_conversion (ptr, len, fmt);
+	for (int i = 0; i < len; i++)
+	  data[i] = ptr[i];
+      }
+      break;
+
+    case LS_DOUBLE: // No conversion necessary.
+      {
+	is.read (reinterpret_cast<char *> (data), 8 * len);
+	do_double_format_conversion (data, len, fmt);
+
+	for (int i = 0; i < len; i++)
+	  data[i] = __lo_ieee_replace_old_NA (data[i]);
+      }
+      break;
+
+    default:
+      is.clear (std::ios::failbit|is.rdstate ());
+      break;
+    }
+}
+
+void
+read_floats (std::istream& is, float *data, save_type type, int len,
+	      bool swap, oct_mach_info::float_format fmt)
+{
+  switch (type)
+    {
+    case LS_U_CHAR:
+      LS_DO_READ (uint8_t, swap, data, 1, len, is);
+      break;
+
+    case LS_U_SHORT:
+      LS_DO_READ (uint16_t, swap, data, 2, len, is);
+      break;
+
+    case LS_U_INT:
+      LS_DO_READ (uint32_t, swap, data, 4, len, is);
+      break;
+
+    case LS_CHAR:
+      LS_DO_READ (int8_t, swap, data, 1, len, is);
+      break;
+
+    case LS_SHORT:
+      LS_DO_READ (int16_t, swap, data, 2, len, is);
+      break;
+
+    case LS_INT:
+      LS_DO_READ (int32_t, swap, data, 4, len, is);
+      break;
+
+    case LS_FLOAT: // No conversion necessary.
+      is.read (reinterpret_cast<char *> (data), 4 * len);
+      do_float_format_conversion (data, len, fmt);
+      break;
+
+    case LS_DOUBLE:
+      {
+	OCTAVE_LOCAL_BUFFER (double, ptr, len);
+	is.read (reinterpret_cast<char *> (ptr), 8 * len);
+	do_double_format_conversion (ptr, len, fmt);
+	for (int i = 0; i < len; i++)
+	  data[i] = ptr[i];
+      }
+      break;
+
+    default:
+      is.clear (std::ios::failbit|is.rdstate ());
+      break;
+    }
+}
+
+void
+write_doubles (std::ostream& os, const double *data, save_type type, int len)
+{
+  switch (type)
+    {
+    case LS_U_CHAR:
+      LS_DO_WRITE (uint8_t, data, 1, len, os);
+      break;
+
+    case LS_U_SHORT:
+      LS_DO_WRITE (uint16_t, data, 2, len, os);
+      break;
+
+    case LS_U_INT:
+      LS_DO_WRITE (uint32_t, data, 4, len, os);
+      break;
+
+    case LS_CHAR:
+      LS_DO_WRITE (int8_t, data, 1, len, os);
+      break;
+
+    case LS_SHORT:
+      LS_DO_WRITE (int16_t, data, 2, len, os);
+      break;
+
+    case LS_INT:
+      LS_DO_WRITE (int32_t, data, 4, len, os);
+      break;
+
+    case LS_FLOAT:
+      LS_DO_WRITE (float, data, 4, len, os);
+      break;
+
+    case LS_DOUBLE: // No conversion necessary.
+      {
+	char tmp_type = static_cast<char> (type);
+	os.write (&tmp_type, 1);
+	os.write (reinterpret_cast <const char *> (data), 8 * len);
+      }
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("unrecognized data format requested");
+      break;
+    }
+}
+
+void
+write_floats (std::ostream& os, const float *data, save_type type, int len)
+{
+  switch (type)
+    {
+    case LS_U_CHAR:
+      LS_DO_WRITE (uint8_t, data, 1, len, os);
+      break;
+
+    case LS_U_SHORT:
+      LS_DO_WRITE (uint16_t, data, 2, len, os);
+      break;
+
+    case LS_U_INT:
+      LS_DO_WRITE (uint32_t, data, 4, len, os);
+      break;
+
+    case LS_CHAR:
+      LS_DO_WRITE (int8_t, data, 1, len, os);
+      break;
+
+    case LS_SHORT:
+      LS_DO_WRITE (int16_t, data, 2, len, os);
+      break;
+
+    case LS_INT:
+      LS_DO_WRITE (int32_t, data, 4, len, os);
+      break;
+
+    case LS_FLOAT: // No conversion necessary.
+      {
+	char tmp_type = static_cast<char> (type);
+	os.write (&tmp_type, 1);
+	os.write (reinterpret_cast <const char *> (data), 4 * len);
+      }
+      break;
+
+    case LS_DOUBLE:
+      LS_DO_WRITE (double, data, 8, len, os);
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("unrecognized data format requested");
+      break;
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/data-conv.h b/liboctave/data-conv.h
new file mode 100644
index 0000000..0e4576e
--- /dev/null
+++ b/liboctave/data-conv.h
@@ -0,0 +1,130 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_data_conv_h)
+#define octave_data_conv_h 1
+
+#include <climits>
+
+#include "mach-info.h"
+
+class
+OCTAVE_API
+oct_data_conv
+{
+public:
+
+  enum data_type
+    {
+      dt_int8      =  0,
+      dt_uint8     =  1,
+      dt_int16     =  2,
+      dt_uint16    =  3,
+      dt_int32     =  4,
+      dt_uint32    =  5,
+      dt_int64     =  6,
+      dt_uint64    =  7,
+      dt_single    =  8,
+      dt_double    =  9,
+      dt_char      = 10,
+      dt_schar     = 11,
+      dt_uchar     = 12,
+      dt_logical   = 13,
+      dt_short     = 14,
+      dt_ushort    = 15,
+      dt_int       = 16,
+      dt_uint      = 17,
+      dt_long      = 18,
+      dt_ulong     = 19,
+      dt_longlong  = 20,
+      dt_ulonglong = 21,
+      dt_float     = 22,
+      dt_unknown   = 23 // Must be last, have largest value!
+    };
+
+  static data_type string_to_data_type (const std::string& s);
+
+  static void string_to_data_type (const std::string& s, int& block_size,
+				   data_type& input_type,
+				   data_type& output_type);
+
+  static void string_to_data_type (const std::string& s, int& block_size,
+				   data_type& output_type);
+
+  static std::string data_type_as_string (data_type dt);
+};
+
+// Add new entries to the end of this enum, otherwise Octave will not
+// be able to read binary data files stored in Octave's binary data
+// format that were created with previous versions of Octave.
+
+enum save_type
+  {
+    LS_U_CHAR  = 0,
+    LS_U_SHORT = 1,
+    LS_U_INT   = 2,
+    LS_CHAR    = 3,
+    LS_SHORT   = 4,
+    LS_INT     = 5,
+    LS_FLOAT   = 6,
+    LS_DOUBLE  = 7,
+    LS_U_LONG  = 8,
+    LS_LONG    = 9
+  };
+
+extern OCTAVE_API void
+do_double_format_conversion (void *data, int len,
+			     oct_mach_info::float_format from_fmt,
+			     oct_mach_info::float_format to_fmt
+			       = oct_mach_info::native_float_format ());
+
+extern OCTAVE_API void
+do_float_format_conversion (void *data, int len,
+			    oct_mach_info::float_format from_fmt,
+			    oct_mach_info::float_format to_fmt
+			      = oct_mach_info::native_float_format ());
+
+extern OCTAVE_API void
+do_float_format_conversion (void *data, size_t sz, int len,
+			    oct_mach_info::float_format from_fmt,
+			    oct_mach_info::float_format to_fmt
+			      = oct_mach_info::native_float_format ());
+
+extern OCTAVE_API void
+read_doubles (std::istream& is, double *data, save_type type, int len,
+	      bool swap, oct_mach_info::float_format fmt);
+extern OCTAVE_API void
+write_doubles (std::ostream& os, const double *data, save_type type, int len);
+
+extern OCTAVE_API void
+read_floats (std::istream& is, float *data, save_type type, int len,
+	      bool swap, oct_mach_info::float_format fmt);
+extern OCTAVE_API void
+write_floats (std::ostream& os, const float *data, save_type type, int len);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleAEPBAL.cc b/liboctave/dbleAEPBAL.cc
new file mode 100644
index 0000000..1cd89dd
--- /dev/null
+++ b/liboctave/dbleAEPBAL.cc
@@ -0,0 +1,107 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007 John W. Eaton
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "dbleAEPBAL.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgebal, DGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgebak, DGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             const double*, const octave_idx_type&, double*,
+                             const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+AEPBALANCE::AEPBALANCE (const Matrix& a, bool noperm, bool noscal)
+  : base_aepbal<Matrix, ColumnVector> ()
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("AEPBALANCE requires square matrix");
+      return;
+    }
+
+  octave_idx_type info;
+
+  scale = ColumnVector (n);
+  double *pscale = scale.fortran_vec ();
+
+  balanced_mat = a;
+  double *p_balanced_mat = balanced_mat.fortran_vec ();
+
+  job = noperm ? (noscal ? 'N' : 'S') : (noscal ? 'P' : 'B');
+
+  F77_XFCN (dgebal, DGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, ilo, ihi, pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+}
+
+Matrix
+AEPBALANCE::balancing_matrix (void) const
+{
+  octave_idx_type n = balanced_mat.rows ();
+  Matrix balancing_mat (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    balancing_mat.elem (i ,i) = 1.0;
+
+  double *p_balancing_mat = balancing_mat.fortran_vec ();
+  const double *pscale = scale.fortran_vec ();
+
+  octave_idx_type info;
+
+  char side = 'R';
+
+  F77_XFCN (dgebak, DGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n,
+			     p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return balancing_mat;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleAEPBAL.h b/liboctave/dbleAEPBAL.h
new file mode 100644
index 0000000..7ce4bde
--- /dev/null
+++ b/liboctave/dbleAEPBAL.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_AEPBALANCE_h)
+#define octave_AEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "base-aepbal.h"
+#include "dMatrix.h"
+#include "dColVector.h"
+
+class
+OCTAVE_API
+AEPBALANCE : public base_aepbal<Matrix, ColumnVector>
+{
+public:
+
+  AEPBALANCE (void) : base_aepbal<Matrix, ColumnVector> () { }
+
+  AEPBALANCE (const Matrix& a, bool noperm = false,
+              bool noscal = false);
+
+  AEPBALANCE (const AEPBALANCE& a) 
+    : base_aepbal<Matrix, ColumnVector> (a) { }
+
+  Matrix balancing_matrix (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleCHOL.cc b/liboctave/dbleCHOL.cc
new file mode 100644
index 0000000..8bf7be8
--- /dev/null
+++ b/liboctave/dbleCHOL.cc
@@ -0,0 +1,450 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "dRowVector.h"
+#include "dbleCHOL.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#ifndef HAVE_QRUPDATE
+#include "dbleQR.h"
+#endif
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dpotrf, DPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpotri, DPOTRI) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dpocon, DPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     double*, const octave_idx_type&, const double&,
+			     double&, double*, octave_idx_type*, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (dch1up, DCH1UP) (const octave_idx_type&, double*, const octave_idx_type&,
+                             double*, double*);
+
+  F77_RET_T
+  F77_FUNC (dch1dn, DCH1DN) (const octave_idx_type&, double*, const octave_idx_type&,
+                             double*, double*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dchinx, DCHINX) (const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, double*, double*, 
+                             octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dchdex, DCHDEX) (const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, double*);
+
+  F77_RET_T
+  F77_FUNC (dchshx, DCHSHX) (const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&, 
+                             double*);
+#endif
+}
+
+octave_idx_type
+CHOL::init (const Matrix& a, bool calc_cond)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) ("CHOL requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type n = a_nc;
+  octave_idx_type info;
+
+  chol_mat = a;
+  double *h = chol_mat.fortran_vec ();
+
+  // Calculate the norm of the matrix, for later use.
+  double anorm = 0;
+  if (calc_cond) 
+    anorm = chol_mat.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+  F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 ("U", 1),
+			     n, h, n, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  xrcond = 0.0;
+  if (info != 0)
+    info = -1;
+  else if (calc_cond) 
+    {
+      octave_idx_type dpocon_info = 0;
+
+      // Now calculate the condition number for non-singular matrix.
+      Array<double> z (3*n);
+      double *pz = z.fortran_vec ();
+      Array<octave_idx_type> iz (n);
+      octave_idx_type *piz = iz.fortran_vec ();
+      F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 ("U", 1), n, h,
+				 n, anorm, xrcond, pz, piz, dpocon_info
+				 F77_CHAR_ARG_LEN (1)));
+
+      if (dpocon_info != 0) 
+	info = -1;
+    }
+  else
+    {
+      // If someone thinks of a more graceful way of doing this (or
+      // faster for that matter :-)), please let me know!
+
+      if (n > 1)
+	for (octave_idx_type j = 0; j < a_nc; j++)
+	  for (octave_idx_type i = j+1; i < a_nr; i++)
+	    chol_mat.xelem (i, j) = 0.0;
+    }
+
+  return info;
+}
+
+static Matrix
+chol2inv_internal (const Matrix& r)
+{
+  Matrix retval;
+
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.cols ();
+
+  if (r_nr == r_nc)
+    {
+      octave_idx_type n = r_nc;
+      octave_idx_type info = 0;
+
+      Matrix tmp = r;
+      double *v = tmp.fortran_vec();
+
+      if (info == 0)
+	{
+	  F77_XFCN (dpotri, DPOTRI, (F77_CONST_CHAR_ARG2 ("U", 1), n,
+				     v, n, info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  // If someone thinks of a more graceful way of doing this (or
+	  // faster for that matter :-)), please let me know!
+
+	  if (n > 1)
+	    for (octave_idx_type j = 0; j < r_nc; j++)
+	      for (octave_idx_type i = j+1; i < r_nr; i++)
+		tmp.xelem (i, j) = tmp.xelem (j, i);
+
+	  retval = tmp;
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("chol2inv requires square matrix");
+
+  return retval;
+}
+
+// Compute the inverse of a matrix using the Cholesky factorization.
+Matrix
+CHOL::inverse (void) const
+{
+  return chol2inv_internal (chol_mat);
+}
+
+void
+CHOL::set (const Matrix& R)
+{
+  if (R.is_square ()) 
+    chol_mat = R;
+  else
+    (*current_liboctave_error_handler) ("CHOL requires square matrix");
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+CHOL::update (const ColumnVector& u)
+{
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      ColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (double, w, n);
+
+      F77_XFCN (dch1up, DCH1UP, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), w));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+octave_idx_type
+CHOL::downdate (const ColumnVector& u)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      ColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (double, w, n);
+
+      F77_XFCN (dch1dn, DCH1DN, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), w, info));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+CHOL::insert_sym (const ColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      ColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (double, w, n);
+
+      chol_mat.resize (n+1, n+1);
+
+      F77_XFCN (dchinx, DCHINX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 j + 1, utmp.fortran_vec (), w, info));
+    }
+
+  return info;
+}
+
+void
+CHOL::delete_sym (octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, n);
+
+      F77_XFCN (dchdex, DCHDEX, (n, chol_mat.fortran_vec (), chol_mat.rows (), 
+                                 j + 1, w));
+
+      chol_mat.resize (n-1, n-1);
+    }
+}
+
+void
+CHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, 2*n);
+
+      F77_XFCN (dchshx, DCHSHX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 i + 1, j + 1, w));
+    }
+}
+
+#else
+
+void
+CHOL::update (const ColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      init (chol_mat.transpose () * chol_mat 
+            + Matrix (u) * Matrix (u).transpose (), false);
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+static bool
+singular (const Matrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    if (a(i,i) == 0.0) return true;
+  return false;
+}
+
+octave_idx_type
+CHOL::downdate (const ColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else
+        {
+          info = init (chol_mat.transpose () * chol_mat 
+                - Matrix (u) * Matrix (u).transpose (), false);
+          if (info) info = 1;
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+CHOL::insert_sym (const ColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else
+        {
+          Matrix a = chol_mat.transpose () * chol_mat;
+          Matrix a1 (n+1, n+1);
+          for (octave_idx_type k = 0; k < n+1; k++)
+            for (octave_idx_type l = 0; l < n+1; l++)
+              {
+                if (l == j)
+                  a1(k, l) = u(k);
+                else if (k == j)
+                  a1(k, l) = u(l);
+                else
+                  a1(k, l) = a(k < j ? k : k-1, l < j ? l : l-1);
+              }
+          info = init (a1, false);
+          if (info) info = 1;
+        }
+    }
+
+  return info;
+}
+
+void
+CHOL::delete_sym (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      Matrix a = chol_mat.transpose () * chol_mat;
+      a.delete_elements (1, idx_vector (j));
+      a.delete_elements (0, idx_vector (j));
+      init (a, false);
+    }
+}
+
+void
+CHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      Matrix a = chol_mat.transpose () * chol_mat;
+      Array<octave_idx_type> p (n);
+      for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+      if (i < j)
+        {
+          for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+          p(j) = i;
+        }
+      else if (j < i)
+        {
+          p(j) = i;
+          for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+        }
+
+      init (a.index (idx_vector (p), idx_vector (p)), false);
+    }
+}
+
+#endif
+
+Matrix
+chol2inv (const Matrix& r)
+{
+  return chol2inv_internal (r);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleCHOL.h b/liboctave/dbleCHOL.h
new file mode 100644
index 0000000..58ae951
--- /dev/null
+++ b/liboctave/dbleCHOL.h
@@ -0,0 +1,96 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_CHOL_h)
+#define octave_CHOL_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "dColVector.h"
+
+class
+OCTAVE_API
+CHOL
+{
+public:
+
+  CHOL (void) : chol_mat () { }
+
+  CHOL (const Matrix& a, bool calc_cond = false) { init (a, calc_cond); }
+
+  CHOL (const Matrix& a, octave_idx_type& info, bool calc_cond = false) 
+    { info = init (a, calc_cond); }
+
+  CHOL (const CHOL& a) : chol_mat (a.chol_mat), xrcond (a.xrcond) { }
+
+  CHOL& operator = (const CHOL& a)
+    {
+      if (this != &a)
+	{
+	  chol_mat = a.chol_mat;
+	  xrcond = a.xrcond;
+	}
+      return *this;
+    }
+
+  Matrix chol_matrix (void) const { return chol_mat; }
+
+  double rcond (void) const { return xrcond; }
+
+  // Compute the inverse of a matrix using the Cholesky factorization.
+  Matrix inverse (void) const;
+
+  void set (const Matrix& R);
+
+  void update (const ColumnVector& u);
+
+  octave_idx_type downdate (const ColumnVector& u);
+
+  octave_idx_type insert_sym (const ColumnVector& u, octave_idx_type j);
+
+  void delete_sym (octave_idx_type j);
+
+  void shift_sym (octave_idx_type i, octave_idx_type j);
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const CHOL& a);
+
+private:
+
+  Matrix chol_mat;
+
+  double xrcond;
+
+  octave_idx_type init (const Matrix& a, bool calc_cond);
+};
+
+Matrix OCTAVE_API chol2inv (const Matrix& r);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleGEPBAL.cc b/liboctave/dbleGEPBAL.cc
new file mode 100644
index 0000000..b71f51d
--- /dev/null
+++ b/liboctave/dbleGEPBAL.cc
@@ -0,0 +1,131 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "dbleGEPBAL.h"
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dggbal, DGGBAL) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type& N,
+			     double* A, const octave_idx_type& LDA, double* B,
+			     const octave_idx_type& LDB, octave_idx_type& ILO, octave_idx_type& IHI,
+			     double* LSCALE, double* RSCALE,
+			     double* WORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dggbak, DGGBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO,
+			     const octave_idx_type& IHI, const double* LSCALE,
+			     const double* RSCALE, octave_idx_type& M, double* V,
+			     const octave_idx_type& LDV, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+}
+
+octave_idx_type
+GEPBALANCE::init (const Matrix& a, const Matrix& b, 
+		  const std::string& balance_job)
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("GEPBALANCE requires square matrix");
+      return -1;
+    }
+
+  if (a.dims() != b.dims ())
+    {
+      gripe_nonconformant ("GEPBALANCE", n, n, b.rows(), b.cols());
+      return -1;
+    } 
+
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  OCTAVE_LOCAL_BUFFER (double, plscale, n);
+  OCTAVE_LOCAL_BUFFER (double, prscale, n);
+  OCTAVE_LOCAL_BUFFER (double, pwork, 6 * n);
+
+  balanced_mat = a;
+  double *p_balanced_mat = balanced_mat.fortran_vec ();
+  balanced_mat2 = b;
+  double *p_balanced_mat2 = balanced_mat2.fortran_vec ();
+
+  char job = balance_job[0];
+
+  F77_XFCN (dggbal, DGGBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, p_balanced_mat2,
+			     n, ilo, ihi, plscale, prscale, pwork, info
+			     F77_CHAR_ARG_LEN  (1)));
+
+  balancing_mat = Matrix (n, n, 0.0);
+  balancing_mat2 = Matrix (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      OCTAVE_QUIT;
+      balancing_mat.elem (i ,i) = 1.0;
+      balancing_mat2.elem (i ,i) = 1.0;
+    }
+
+  double *p_balancing_mat = balancing_mat.fortran_vec ();
+  double *p_balancing_mat2 = balancing_mat2.fortran_vec ();
+
+  // first left
+  F77_XFCN (dggbak, DGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+      
+  // then right
+  F77_XFCN (dggbak, DGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("R", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat2, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleGEPBAL.h b/liboctave/dbleGEPBAL.h
new file mode 100644
index 0000000..37dffc6
--- /dev/null
+++ b/liboctave/dbleGEPBAL.h
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_GEPBALANCE_h)
+#define octave_GEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "dMatrix.h"
+
+class
+OCTAVE_API
+GEPBALANCE
+{
+public:
+
+  GEPBALANCE (void) : balanced_mat (), balancing_mat () { }
+
+  GEPBALANCE (const Matrix& a, const Matrix& b, const std::string& balance_job)
+    {
+      init (a, b, balance_job); 
+    }
+
+  GEPBALANCE (const GEPBALANCE& a)
+    : balanced_mat (a.balanced_mat), balanced_mat2 (a.balanced_mat2),
+    balancing_mat (a.balancing_mat), balancing_mat2 (a.balancing_mat2) { }
+
+  GEPBALANCE& operator = (const GEPBALANCE& a)
+    {
+      if (this != &a)
+	{
+	  balanced_mat = a.balanced_mat;
+	  balanced_mat2 = a.balanced_mat2;
+	  balancing_mat = a.balancing_mat;
+	  balancing_mat2 = a.balancing_mat2;
+	}
+      return *this;
+    }
+
+  ~GEPBALANCE (void) { }
+
+  Matrix balanced_matrix (void) const { return balanced_mat; }
+
+  Matrix balanced_matrix2 (void) const { return balanced_mat2; }
+
+  Matrix balancing_matrix (void) const { return balancing_mat; }
+
+  Matrix balancing_matrix2 (void) const { return balancing_mat2; }
+
+  friend std::ostream& operator << (std::ostream& os, const GEPBALANCE& a);
+
+private:
+
+  Matrix balanced_mat;
+  Matrix balanced_mat2;
+  Matrix balancing_mat;
+  Matrix balancing_mat2;
+
+  octave_idx_type init (const Matrix& a, const Matrix& b, 
+			const std::string& balance_job);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleHESS.cc b/liboctave/dbleHESS.cc
new file mode 100644
index 0000000..8f6bedd
--- /dev/null
+++ b/liboctave/dbleHESS.cc
@@ -0,0 +1,128 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dbleHESS.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgebal, DGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, double*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgehrd, DGEHRD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     double*, const octave_idx_type&, double*, double*,
+			     const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dorghr, DORGHR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     double*, const octave_idx_type&, double*, double*,
+			     const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dgebak, DGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+octave_idx_type
+HESS::init (const Matrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) ("HESS requires square matrix");
+      return -1;
+    }
+
+  char job = 'N';
+  char side = 'R';
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 32 * n;
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  hess_mat = a;
+  double *h = hess_mat.fortran_vec ();
+
+  Array<double> scale (n);
+  double *pscale = scale.fortran_vec ();
+
+  F77_XFCN (dgebal, DGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, h, n, ilo, ihi, pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  Array<double> tau (n-1);
+  double *ptau = tau.fortran_vec ();
+
+  Array<double> work (lwork);
+  double *pwork = work.fortran_vec ();
+
+  F77_XFCN (dgehrd, DGEHRD, (n, ilo, ihi, h, n, ptau, pwork,
+			     lwork, info));
+
+  unitary_hess_mat = hess_mat;
+  double *z = unitary_hess_mat.fortran_vec ();
+
+  F77_XFCN (dorghr, DORGHR, (n, ilo, ihi, z, n, ptau, pwork,
+			     lwork, info));
+
+  F77_XFCN (dgebak, DGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n, z,
+			     n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  // If someone thinks of a more graceful way of doing
+  // this (or faster for that matter :-)), please let
+  // me know!
+
+  if (n > 2)
+    for (octave_idx_type j = 0; j < a_nc; j++)
+      for (octave_idx_type i = j+2; i < a_nr; i++)
+	hess_mat.elem (i, j) = 0;
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleHESS.h b/liboctave/dbleHESS.h
new file mode 100644
index 0000000..8b949d3
--- /dev/null
+++ b/liboctave/dbleHESS.h
@@ -0,0 +1,78 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_HESS_h)
+#define octave_HESS_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+
+class
+OCTAVE_API
+HESS
+{
+public:
+
+  HESS (void) : hess_mat (), unitary_hess_mat () { }
+
+  HESS (const Matrix& a) { init (a); }
+
+  HESS (const Matrix& a, octave_idx_type& info) { info = init (a); }
+
+  HESS (const HESS& a)
+    : hess_mat (a.hess_mat), unitary_hess_mat (a.unitary_hess_mat) { }
+
+  HESS& operator = (const HESS& a)
+    {
+      if (this != &a)
+	{
+	  hess_mat = a.hess_mat;
+	  unitary_hess_mat = a.unitary_hess_mat;
+	}
+      return *this;
+    }
+
+  ~HESS (void) { }
+
+  Matrix hess_matrix (void) const { return hess_mat; }
+
+  Matrix unitary_hess_matrix (void) const { return unitary_hess_mat; }
+
+  friend std::ostream& operator << (std::ostream& os, const HESS& a);
+
+private:
+
+  Matrix hess_mat;
+  Matrix unitary_hess_mat;
+
+  octave_idx_type init (const Matrix& a);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleLU.cc b/liboctave/dbleLU.cc
new file mode 100644
index 0000000..066cd34
--- /dev/null
+++ b/liboctave/dbleLU.cc
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dbleLU.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+// Instantiate the base LU class for the types we need.
+
+#include <base-lu.h>
+#include <base-lu.cc>
+
+template class base_lu <Matrix>;
+
+// Define the constructor for this particular derivation.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgetrf, DGETRF) (const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, octave_idx_type*, octave_idx_type&);
+}
+
+LU::LU (const Matrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+  ipvt.resize (mn);
+  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+  a_fact = a;
+  double *tmp_data = a_fact.fortran_vec ();
+
+  octave_idx_type info = 0;
+
+  F77_XFCN (dgetrf, DGETRF, (a_nr, a_nc, tmp_data, a_nr, pipvt, info));
+
+  ipvt -= static_cast<octave_idx_type> (1);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleLU.h b/liboctave/dbleLU.h
new file mode 100644
index 0000000..6e79905
--- /dev/null
+++ b/liboctave/dbleLU.h
@@ -0,0 +1,59 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_LU_h)
+#define octave_LU_h 1
+
+#include "base-lu.h"
+#include "dMatrix.h"
+
+class
+OCTAVE_API
+LU : public base_lu <Matrix>
+{
+public:
+
+  LU (void) : base_lu <Matrix> () { }
+
+  LU (const Matrix& a);
+
+  LU (const LU& a) : base_lu <Matrix> (a) { }
+
+  LU& operator = (const LU& a)
+    {
+      if (this != &a)
+	base_lu <Matrix> :: operator = (a);
+
+      return *this;
+    }
+
+  ~LU (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleQR.cc b/liboctave/dbleQR.cc
new file mode 100644
index 0000000..055cb26
--- /dev/null
+++ b/liboctave/dbleQR.cc
@@ -0,0 +1,726 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dbleQR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "Range.h"
+#include "idx-vector.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgeqrf, DGEQRF) (const octave_idx_type&, const octave_idx_type&, double*, const octave_idx_type&,
+			     double*, double*, const octave_idx_type&, octave_idx_type&); 
+
+  F77_RET_T
+  F77_FUNC (dorgqr, DORGQR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, double*, double*, const octave_idx_type&, octave_idx_type&);
+
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (dqr1up, DQR1UP) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             double*, const octave_idx_type&, double*, const octave_idx_type&,
+                             double*, double*, double*);
+
+  F77_RET_T
+  F77_FUNC (dqrinc, DQRINC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             double*, const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, const double*, double*);
+
+  F77_RET_T
+  F77_FUNC (dqrdec, DQRDEC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             double*, const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, double*);
+
+  F77_RET_T
+  F77_FUNC (dqrinr, DQRINR) (const octave_idx_type&, const octave_idx_type&, 
+                             double*, const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, const double*, double*);
+
+  F77_RET_T
+  F77_FUNC (dqrder, DQRDER) (const octave_idx_type&, const octave_idx_type&, 
+                             double*, const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, double*);
+
+  F77_RET_T
+  F77_FUNC (dqrshc, DQRSHC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+                             double*, const octave_idx_type&, double*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&,
+                             double*);
+
+#endif
+}
+
+QR::QR (const Matrix& a, QR::type qr_type)
+  : q (), r ()
+{
+  init (a, qr_type);
+}
+
+void
+QR::init (const Matrix& a, QR::type qr_type)
+{
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (double, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  Matrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  if (m > 0)
+    {
+      // workspace query.
+      double rlwork;
+      F77_XFCN (dgeqrf, DGEQRF, (m, n, afact.fortran_vec (), m, tau, &rlwork, -1, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = rlwork;
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (double, work, lwork);
+      F77_XFCN (dgeqrf, DGEQRF, (m, n, afact.fortran_vec (), m, tau, work, lwork, info));
+    }
+
+  form (n, afact, tau, qr_type);
+}
+
+void QR::form (octave_idx_type n, Matrix& afact, 
+               double *tau, QR::type qr_type)
+{
+  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type info;
+
+  if (qr_type == QR::raw)
+    {
+      for (octave_idx_type j = 0; j < min_mn; j++)
+	{
+	  octave_idx_type limit = j < min_mn - 1 ? j : min_mn - 1;
+	  for (octave_idx_type i = limit + 1; i < m; i++)
+	    afact.elem (i, j) *= tau[j];
+	}
+
+      r = afact;
+    }
+  else
+    {
+      // Attempt to minimize copying.
+      if (m >= n)
+        {
+          // afact will become q.
+          q = afact;
+          octave_idx_type k = qr_type == QR::economy ? n : m;
+          r = Matrix (k, n);
+          for (octave_idx_type j = 0; j < n; j++)
+            {
+              octave_idx_type i = 0;
+              for (; i <= j; i++)
+                r.xelem (i, j) = afact.xelem (i, j);
+              for (;i < k; i++)
+                r.xelem (i, j) = 0;
+            }
+          afact = Matrix (); // optimize memory
+        }
+      else
+        {
+          // afact will become r.
+          q = Matrix (m, m);
+          for (octave_idx_type j = 0; j < m; j++)
+            for (octave_idx_type i = j + 1; i < m; i++)
+              {
+                q.xelem (i, j) = afact.xelem (i, j);
+                afact.xelem (i, j) = 0;
+              }
+          r = afact;
+        }
+
+
+      if (m > 0)
+        {
+          octave_idx_type k = q.columns ();
+          // workspace query.
+          double rlwork;
+          F77_XFCN (dorgqr, DORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     &rlwork, -1, info));
+
+          // allocate buffer and do the job.
+          octave_idx_type lwork = rlwork;
+	  lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+          OCTAVE_LOCAL_BUFFER (double, work, lwork);
+          F77_XFCN (dorgqr, DORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     work, lwork, info));
+        }
+    }
+}
+
+QR::QR (const Matrix& q_arg, const Matrix& r_arg)
+{
+  octave_idx_type qr = q_arg.rows (), qc = q_arg.columns ();
+  octave_idx_type rr = r_arg.rows (), rc = r_arg.columns ();
+  if (qc == rr && (qr == qc || (qr > qc && rr == rc)))
+    {
+      q = q_arg;
+      r = r_arg;
+    }
+  else
+    (*current_liboctave_error_handler) ("QR dimensions mismatch");
+}
+
+QR::type
+QR::get_type (void) const
+{
+  QR::type retval;
+  if (!q.is_empty () && q.is_square ())
+    retval = QR::std;
+  else if (q.rows () > q.columns () && r.is_square ())
+    retval = QR::economy;
+  else
+    retval = QR::raw;
+  return retval;
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+QR::update (const ColumnVector& u, const ColumnVector& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      ColumnVector utmp = u, vtmp = v;
+      OCTAVE_LOCAL_BUFFER (double, w, 2*k);
+      F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                 utmp.fortran_vec (), vtmp.fortran_vec (), w));
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+QR::update (const Matrix& u, const Matrix& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, 2*k);
+      for (volatile octave_idx_type i = 0; i < u.cols (); i++)
+        {
+          ColumnVector utmp = u.column (i), vtmp = v.column (i);
+          F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                     utmp.fortran_vec (), vtmp.fortran_vec (), w));
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+QR::insert_col (const ColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      if (k < m)
+        {
+          q.resize (m, k+1);
+          r.resize (k+1, n+1);
+        }
+      else
+        {
+          r.resize (k, n+1);
+        }
+
+      ColumnVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (double, w, k);
+      F77_XFCN (dqrinc, DQRINC, (m, n, k, q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (), j + 1, 
+                                 utmp.data (), w));
+    }
+}
+
+void
+QR::insert_col (const Matrix& u, const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      octave_idx_type kmax = std::min (k + nj, m);
+      if (k < m)
+        {
+          q.resize (m, kmax);
+          r.resize (kmax, n + nj);
+        }
+      else
+        {
+          r.resize (k, n + nj);
+        }
+
+      OCTAVE_LOCAL_BUFFER (double, w, kmax);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          ColumnVector utmp = u.column (jsi(i));
+          F77_XFCN (dqrinc, DQRINC, (m, n + ii, std::min (kmax, k + ii), 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, 
+                                     utmp.data (), w));
+        }
+    }
+}
+
+void
+QR::delete_col (octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, k);
+      F77_XFCN (dqrdec, DQRDEC, (m, n, k, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1, w));
+
+      if (k < m)
+        {
+          q.resize (m, k-1);
+          r.resize (k-1, n-1);
+        }
+      else
+        {
+          r.resize (k, n-1);
+        }
+    }
+}
+
+void
+QR::delete_col (const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, k);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          F77_XFCN (dqrdec, DQRDEC, (m, n - ii, k == m ? k : k - ii, 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, w));
+        }
+      if (k < m)
+        {
+          q.resize (m, k - nj);
+          r.resize (k - nj, n - nj);
+        }
+      else
+        {
+          r.resize (k, n - nj);
+        }
+
+    }
+}
+
+void
+QR::insert_row (const RowVector& u, octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = std::min (m, n);
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      q.resize (m + 1, m + 1);
+      r.resize (m + 1, n);
+      RowVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (double, w, k);
+      F77_XFCN (dqrinr, DQRINR, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), 
+                                 j + 1, utmp.fortran_vec (), w));
+
+    }
+}
+
+void
+QR::delete_row (octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, 2*m);
+      F77_XFCN (dqrder, DQRDER, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1,
+                                 w));
+
+      q.resize (m - 1, m - 1);
+      r.resize (m - 1, n);
+    }
+}
+
+void
+QR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (double, w, 2*k);
+      F77_XFCN (dqrshc, DQRSHC, (m, n, k, 
+                                 q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (),
+                                 i + 1, j + 1, w));
+    }
+}
+
+#else
+
+// Replacement update methods.
+
+void
+QR::update (const ColumnVector& u, const ColumnVector& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      init(q*r + Matrix (u) * Matrix (v).transpose (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+QR::update (const Matrix& u, const Matrix& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      init(q*r + u * v.transpose (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+static
+Matrix insert_col (const Matrix& a, octave_idx_type i,
+                        const ColumnVector& x)
+{
+  Matrix retval (a.rows (), a.columns () + 1);
+  retval.assign (idx_vector::colon, idx_vector (0, i),
+                 a.index (idx_vector::colon, idx_vector (0, i)));
+  retval.assign (idx_vector::colon, idx_vector (i), x);
+  retval.assign (idx_vector::colon, idx_vector (i+1, retval.columns ()),
+                 a.index (idx_vector::colon, idx_vector (i, a.columns ())));
+  return retval;
+}
+
+static
+Matrix insert_row (const Matrix& a, octave_idx_type i,
+                        const RowVector& x)
+{
+  Matrix retval (a.rows () + 1, a.columns ());
+  retval.assign (idx_vector (0, i), idx_vector::colon,
+                 a.index (idx_vector (0, i), idx_vector::colon));
+  retval.assign (idx_vector (i), idx_vector::colon, x);
+  retval.assign (idx_vector (i+1, retval.rows ()), idx_vector::colon,
+                 a.index (idx_vector (i, a.rows ()), idx_vector::colon));
+  return retval;
+}
+
+static
+Matrix delete_col (const Matrix& a, octave_idx_type i)
+{
+  Matrix retval = a;
+  retval.delete_elements (1, idx_vector (i));
+  return retval;
+}
+
+static
+Matrix delete_row (const Matrix& a, octave_idx_type i)
+{
+  Matrix retval = a;
+  retval.delete_elements (0, idx_vector (i));
+  return retval;
+}
+
+static
+Matrix shift_cols (const Matrix& a, 
+                        octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = a.columns ();
+  Array<octave_idx_type> p (n);
+  for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+  if (i < j)
+    {
+      for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+      p(j) = i;
+    }
+  else if (j < i)
+    {
+      p(j) = i;
+      for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+    }
+
+  return a.index (idx_vector::colon, idx_vector (p));
+}
+
+void
+QR::insert_col (const ColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_col (q*r, j, u), get_type ());
+    }
+}
+
+void
+QR::insert_col (const Matrix& u, const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      Matrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::insert_col (a, js(i), u.column (i));
+      init (a, get_type ());
+    }
+}
+
+void
+QR::delete_col (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_col (q*r, j), get_type ());
+    }
+}
+
+void
+QR::delete_col (const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      Matrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::delete_col (a, js(i));
+      init (a, get_type ());
+    }
+}
+
+void
+QR::insert_row (const RowVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_row (q*r, j, u), get_type ());
+    }
+}
+
+void
+QR::delete_row (octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_row (q*r, j), get_type ());
+    }
+}
+
+void
+QR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      init (::shift_cols (q*r, i, j), get_type ());
+    }
+}
+
+void warn_qrupdate_once (void)
+{
+  static bool warned = false;
+  if (! warned)
+    {
+      (*current_liboctave_warning_handler)
+        ("In this version of Octave, QR & Cholesky updating routines\n"
+         "simply update the matrix and recalculate factorizations.\n"
+         "To use fast algorithms, link Octave with the qrupdate library.\n"
+         "See <http://sourceforge.net/projects/qrupdate>.\n");
+      warned = true;
+    }
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleQR.h b/liboctave/dbleQR.h
new file mode 100644
index 0000000..d256c8b
--- /dev/null
+++ b/liboctave/dbleQR.h
@@ -0,0 +1,114 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek              
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_QR_h)
+#define octave_QR_h 1
+
+#include <iosfwd>
+
+#include "dMatrix.h"
+#include "dColVector.h"
+#include "dRowVector.h"
+
+class
+OCTAVE_API
+QR
+{
+public:
+
+  enum type
+    {
+      std,
+      raw,
+      economy
+    };
+
+  QR (void) : q (), r () { }
+
+  QR (const Matrix&, QR::type = QR::std);
+
+  QR (const Matrix& q, const Matrix& r);
+
+  QR (const QR& a) : q (a.q), r (a.r) { }
+
+  QR& operator = (const QR& a)
+    {
+      if (this != &a)
+	{
+	  q = a.q;
+	  r = a.r;
+	}
+      return *this;
+    }
+
+  ~QR (void) { }
+
+  void init (const Matrix&, QR::type);
+
+  Matrix Q (void) const { return q; }
+
+  Matrix R (void) const { return r; }
+
+  QR::type get_type (void) const;
+
+  void update (const ColumnVector& u, const ColumnVector& v);
+
+  void update (const Matrix& u, const Matrix& v);
+
+  void insert_col (const ColumnVector& u, octave_idx_type j);
+
+  void insert_col (const Matrix& u, const Array<octave_idx_type>& j);
+
+  void delete_col (octave_idx_type j);
+
+  void delete_col (const Array<octave_idx_type>& j);
+
+  void insert_row (const RowVector& u, octave_idx_type j);
+
+  void delete_row (octave_idx_type j);
+
+  void shift_cols (octave_idx_type i, octave_idx_type j);
+
+  friend std::ostream&  operator << (std::ostream&, const QR&);
+
+protected:
+
+  void form (octave_idx_type n, Matrix& afact, 
+             double *tau, QR::type qr_type);
+
+  Matrix q;
+  Matrix r;
+};
+
+#ifndef HAVE_QRUPDATE
+void warn_qrupdate_once (void);
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleQRP.cc b/liboctave/dbleQRP.cc
new file mode 100644
index 0000000..2e63906
--- /dev/null
+++ b/liboctave/dbleQRP.cc
@@ -0,0 +1,109 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "dbleQRP.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgeqp3, DGEQP3) (const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, octave_idx_type*, double*, double*,
+                             const octave_idx_type&, octave_idx_type&);
+}
+
+// It would be best to share some of this code with QR class...
+
+QRP::QRP (const Matrix& a, QR::type qr_type)
+  : QR (), p ()
+{
+  init (a, qr_type);
+}
+
+void
+QRP::init (const Matrix& a, QR::type qr_type)
+{
+  assert (qr_type != QR::raw);
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (double, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  Matrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  MArray<octave_idx_type> jpvt (n, 0);
+
+  if (m > 0)
+    {
+      // workspace query.
+      double rlwork;
+      F77_XFCN (dgeqp3, DGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, &rlwork, -1, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = rlwork;
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (double, work, lwork);
+      F77_XFCN (dgeqp3, DGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, work, lwork, info));
+    }
+  else
+    for (octave_idx_type i = 0; i < n; i++) jpvt(i) = i+1;
+
+  // Form Permutation matrix (if economy is requested, return the
+  // indices only!)
+
+  jpvt -= static_cast<octave_idx_type> (1);
+  p = PermMatrix (jpvt, true);
+
+
+  form (n, afact, tau, qr_type);
+}
+
+ColumnVector
+QRP::Pvec (void) const
+{
+  Array<double> pa (p.pvec ());
+  ColumnVector pv (MArray<double> (pa) + 1.0);
+  return pv;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleQRP.h b/liboctave/dbleQRP.h
new file mode 100644
index 0000000..6a033a0
--- /dev/null
+++ b/liboctave/dbleQRP.h
@@ -0,0 +1,77 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_QRP_h)
+#define octave_QRP_h 1
+
+#include <iosfwd>
+
+#include "dbleQR.h"
+#include "PermMatrix.h"
+#include "dColVector.h"
+
+class
+OCTAVE_API
+QRP : public QR
+{
+public:
+
+  QRP (void) : QR (), p () { }
+
+  QRP (const Matrix&, QR::type = QR::std);
+
+  QRP (const QRP& a) : QR (a), p (a.p) { }
+
+  QRP& operator = (const QRP& a)
+    {
+      if (this != &a)
+	{
+	  QR::operator = (a);
+	  p = a.p;
+	}
+
+      return *this;
+    }
+
+  ~QRP (void) { }
+
+  void init (const Matrix&, QR::type = QR::std);
+
+  PermMatrix P (void) const { return p; }
+
+  ColumnVector Pvec (void) const;
+
+  friend std::ostream&  operator << (std::ostream&, const QRP&);
+
+protected:
+
+  PermMatrix p;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleSCHUR.cc b/liboctave/dbleSCHUR.cc
new file mode 100644
index 0000000..d6d8efc
--- /dev/null
+++ b/liboctave/dbleSCHUR.cc
@@ -0,0 +1,156 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "dbleSCHUR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgeesx, DGEESX) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     SCHUR::select_function,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&,
+			     double*, double*, double*, const octave_idx_type&,
+			     double&, double&, double*, const octave_idx_type&,
+			     octave_idx_type*, const octave_idx_type&, octave_idx_type*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+static octave_idx_type
+select_ana (const double& a, const double&)
+{
+   return (a < 0.0);
+}
+
+static octave_idx_type
+select_dig (const double& a, const double& b)
+{
+  return (hypot (a, b) < 1.0);
+}
+
+octave_idx_type
+SCHUR::init (const Matrix& a, const std::string& ord, bool calc_unitary)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) ("SCHUR requires square matrix");
+      return -1;
+    }
+
+  // Workspace requirements may need to be fixed if any of the
+  // following change.
+
+  char jobvs;
+  char sense = 'N';
+  char sort = 'N';
+
+  if (calc_unitary)
+    jobvs = 'V';
+  else
+    jobvs = 'N';
+
+  char ord_char = ord.empty () ? 'U' : ord[0];
+
+  if (ord_char == 'A' || ord_char == 'D' || ord_char == 'a' || ord_char == 'd')
+    sort = 'S';
+
+  if (ord_char == 'A' || ord_char == 'a')
+    selector = select_ana;
+  else if (ord_char == 'D' || ord_char == 'd')
+    selector = select_dig;
+  else
+    selector = 0;
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 8 * n;
+  octave_idx_type liwork = 1;
+  octave_idx_type info;
+  octave_idx_type sdim;
+  double rconde;
+  double rcondv;
+
+  schur_mat = a;
+
+  if (calc_unitary)
+    unitary_mat.resize (n, n);
+
+  double *s = schur_mat.fortran_vec ();
+  double *q = unitary_mat.fortran_vec ();
+
+  Array<double> wr (n);
+  double *pwr = wr.fortran_vec ();
+
+  Array<double> wi (n);
+  double *pwi = wi.fortran_vec ();
+
+  Array<double> work (lwork);
+  double *pwork = work.fortran_vec ();
+
+  // BWORK is not referenced for the non-ordered Schur routine.
+  Array<octave_idx_type> bwork ((ord_char == 'N' || ord_char == 'n') ? 0 : n);
+  octave_idx_type *pbwork = bwork.fortran_vec ();
+
+  Array<octave_idx_type> iwork (liwork);
+  octave_idx_type *piwork = iwork.fortran_vec ();
+
+  F77_XFCN (dgeesx, DGEESX, (F77_CONST_CHAR_ARG2 (&jobvs, 1),
+			     F77_CONST_CHAR_ARG2 (&sort, 1),
+			     selector,
+			     F77_CONST_CHAR_ARG2 (&sense, 1),
+			     n, s, n, sdim, pwr, pwi, q, n, rconde, rcondv,
+			     pwork, lwork, piwork, liwork, pbwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+std::ostream&
+operator << (std::ostream& os, const SCHUR& a)
+{
+  os << a.schur_matrix () << "\n";
+  os << a.unitary_matrix () << "\n";
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleSCHUR.h b/liboctave/dbleSCHUR.h
new file mode 100644
index 0000000..ea370de
--- /dev/null
+++ b/liboctave/dbleSCHUR.h
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_SCHUR_h)
+#define octave_SCHUR_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "dMatrix.h"
+
+class
+OCTAVE_API
+SCHUR
+{
+public:
+
+  SCHUR (void)
+    : schur_mat (), unitary_mat () { }
+
+  SCHUR (const Matrix& a, const std::string& ord, bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { init (a, ord, calc_unitary); }
+
+  SCHUR (const Matrix& a, const std::string& ord, int& info, 
+	 bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { info = init (a, ord, calc_unitary); }
+
+  SCHUR (const SCHUR& a)
+    : schur_mat (a.schur_mat), unitary_mat (a.unitary_mat) { }
+
+  SCHUR& operator = (const SCHUR& a)
+    {
+      if (this != &a)
+	{
+	  schur_mat = a.schur_mat;
+	  unitary_mat = a.unitary_mat;
+	}
+      return *this;
+    }
+
+  ~SCHUR (void) { }
+
+  Matrix schur_matrix (void) const { return schur_mat; }
+
+  Matrix unitary_matrix (void) const { return unitary_mat; }
+
+  friend std::ostream& operator << (std::ostream& os, const SCHUR& a);
+
+  typedef octave_idx_type (*select_function) (const double&, const double&);
+
+private:
+
+  Matrix schur_mat;
+  Matrix unitary_mat;
+
+  select_function selector;
+
+  octave_idx_type init (const Matrix& a, const std::string& ord, bool calc_unitary);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleSVD.cc b/liboctave/dbleSVD.cc
new file mode 100644
index 0000000..0ab20f2
--- /dev/null
+++ b/liboctave/dbleSVD.cc
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "dbleSVD.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgesvd, DGESVD) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, double*,
+			     const octave_idx_type&, double*, double*,
+			     const octave_idx_type&, double*, const octave_idx_type&,
+			     double*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+Matrix
+SVD::left_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("SVD: U not computed because type == SVD::sigma_only");
+      return Matrix ();
+    }
+  else
+    return left_sm;
+}
+
+Matrix
+SVD::right_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("SVD: V not computed because type == SVD::sigma_only");
+      return Matrix ();
+    }
+  else
+    return right_sm;
+}
+
+octave_idx_type
+SVD::init (const Matrix& a, SVD::type svd_type)
+{
+  octave_idx_type info;
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  Matrix atmp = a;
+  double *tmp_data = atmp.fortran_vec ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+
+  char jobu = 'A';
+  char jobv = 'A';
+
+  octave_idx_type ncol_u = m;
+  octave_idx_type nrow_vt = n;
+  octave_idx_type nrow_s = m;
+  octave_idx_type ncol_s = n;
+
+  switch (svd_type)
+    {
+    case SVD::economy:
+      jobu = jobv = 'S';
+      ncol_u = nrow_vt = nrow_s = ncol_s = min_mn;
+      break;
+
+    case SVD::sigma_only:
+
+      // Note:  for this case, both jobu and jobv should be 'N', but
+      // there seems to be a bug in dgesvd from Lapack V2.0.  To
+      // demonstrate the bug, set both jobu and jobv to 'N' and find
+      // the singular values of [eye(3), eye(3)].  The result is
+      // [-sqrt(2), -sqrt(2), -sqrt(2)].
+      //
+      // For Lapack 3.0, this problem seems to be fixed.
+
+      jobu = 'N';
+      jobv = 'N';
+      ncol_u = nrow_vt = 1;
+      break;
+
+    default:
+      break;
+    }
+
+  type_computed = svd_type;
+
+  if (! (jobu == 'N' || jobu == 'O'))
+    left_sm.resize (m, ncol_u);
+
+  double *u = left_sm.fortran_vec ();
+
+  sigma.resize (nrow_s, ncol_s);
+  double *s_vec  = sigma.fortran_vec ();
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm.resize (nrow_vt, n);
+
+  double *vt = right_sm.fortran_vec ();
+
+  // Ask DGESVD what the dimension of WORK should be.
+
+  octave_idx_type lwork = -1;
+
+  Array<double> work (1);
+
+  F77_XFCN (dgesvd, DGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  lwork = static_cast<octave_idx_type> (work(0));
+  work.resize (lwork);
+
+  F77_XFCN (dgesvd, DGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm = right_sm.transpose ();
+
+  return info;
+}
+
+std::ostream&
+operator << (std::ostream& os, const SVD& a)
+{
+  os << a.left_singular_matrix () << "\n";
+  os << a.singular_values () << "\n";
+  os << a.right_singular_matrix () << "\n";
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dbleSVD.h b/liboctave/dbleSVD.h
new file mode 100644
index 0000000..c0c8622
--- /dev/null
+++ b/liboctave/dbleSVD.h
@@ -0,0 +1,98 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_SVD_h)
+#define octave_SVD_h 1
+
+#include <iosfwd>
+
+#include "dDiagMatrix.h"
+#include "dMatrix.h"
+
+class
+OCTAVE_API
+SVD
+{
+public:
+
+  enum type
+    {
+      std,
+      economy,
+      sigma_only
+    };
+
+  SVD (void) : sigma (), left_sm (), right_sm () { }
+
+  SVD (const Matrix& a, type svd_type = SVD::std) { init (a, svd_type); }
+
+  SVD (const Matrix& a, octave_idx_type& info, type svd_type = SVD::std)
+    {
+      info = init (a, svd_type);
+    }
+
+  SVD (const SVD& a)
+    : type_computed (a.type_computed),
+      sigma (a.sigma), left_sm (a.left_sm), right_sm (a.right_sm) { }
+
+  SVD& operator = (const SVD& a)
+    {
+      if (this != &a)
+	{
+	  type_computed = a.type_computed;
+	  sigma = a.sigma;
+	  left_sm = a.left_sm;
+	  right_sm = a.right_sm;
+	}
+
+      return *this;
+    }
+
+  ~SVD (void) { }
+
+  DiagMatrix singular_values (void) const { return sigma; }
+
+  Matrix left_singular_matrix (void) const;
+
+  Matrix right_singular_matrix (void) const;
+
+  friend std::ostream&  operator << (std::ostream& os, const SVD& a);
+
+private:
+
+  SVD::type type_computed;
+
+  DiagMatrix sigma;
+  Matrix left_sm;
+  Matrix right_sm;
+
+  octave_idx_type init (const Matrix& a, type svd_type = std);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dim-vector.h b/liboctave/dim-vector.h
new file mode 100644
index 0000000..e771907
--- /dev/null
+++ b/liboctave/dim-vector.h
@@ -0,0 +1,561 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dim_vector_h)
+#define octave_dim_vector_h 1
+
+#include <cassert>
+
+#include <sstream>
+#include <string>
+
+#include "lo-error.h"
+#include "oct-types.h"
+
+class
+dim_vector
+{
+protected:
+
+  class dim_vector_rep
+  {
+  public:
+
+    octave_idx_type *dims;
+    int ndims;
+    int count;
+
+    dim_vector_rep (void)
+      : dims (new octave_idx_type [2]), ndims (2), count (1)
+    {
+      dims[0] = 0;
+      dims[1] = 0;
+    }
+
+
+    dim_vector_rep (octave_idx_type n)
+      : dims (new octave_idx_type [2]), ndims (2), count (1)
+    {
+      dims[0] = n;
+      dims[1] = 1;
+    }
+
+    dim_vector_rep (octave_idx_type r, octave_idx_type c)
+      : dims (new octave_idx_type [2]), ndims (2), count (1)
+    {
+      dims[0] = r;
+      dims[1] = c;
+    }
+
+    dim_vector_rep (octave_idx_type r, octave_idx_type c, octave_idx_type p)
+      : dims (new octave_idx_type [3]), ndims (3), count (1)
+    {
+      dims[0] = r;
+      dims[1] = c;
+      dims[2] = p;
+    }
+
+    dim_vector_rep (const dim_vector_rep& dv)
+      : dims (new octave_idx_type [dv.ndims]),
+	ndims (dv.ndims), count (1)
+    {
+      if (dims)
+	{
+	  for (int i = 0; i < ndims; i++)
+	    dims[i] = dv.dims[i];
+	}
+    }
+
+    dim_vector_rep (octave_idx_type n, const dim_vector_rep *dv,
+		    int fill_value = 0)
+      : dims (new octave_idx_type [n < 2 ? 2 : n]),
+	ndims (n < 2 ? 2 : n), count (1)
+    {
+      if (n == 0)
+	{
+	  // Result is 0x0.
+	  dims[0] = 0;
+	  dims[1] = 0;
+	}
+      else if (n == 1)
+	{
+	  // Result is a column vector.
+	  dims[0] = dv->dims[0];
+	  dims[1] = 1;
+	}
+      else
+	{
+	  int dv_ndims = dv ? dv->ndims : 0;
+
+	  int min_len = n < dv_ndims ? n : dv_ndims;
+
+	  for (int i = 0; i < min_len; i++)
+	    dims[i] = dv->dims[i];
+
+	  for (int i = dv_ndims; i < n; i++)
+	    dims[i] = fill_value;
+	}
+    }
+
+    ~dim_vector_rep (void) { delete [] dims; }
+
+    int length (void) const { return ndims; }
+
+    octave_idx_type& elem (int i)
+    {
+      assert (i >= 0 && i < ndims);
+      return dims[i];
+    }
+
+    octave_idx_type elem (int i) const
+    {
+      assert (i >= 0 && i < ndims);
+      return dims[i];
+    }
+
+    void chop_trailing_singletons (void)
+    {
+      for (int i = ndims - 1; i > 1; i--)
+	{
+	  if (dims[i] == 1)
+	    ndims--;
+	  else
+	    break;
+	}
+    }
+
+    void chop_all_singletons (void)
+    {
+      int j = 0;
+
+      for (int i = 0; i < ndims; i++)
+	{
+	  if (dims[i] != 1)
+            dims[j++] = dims[i];
+	}
+
+      if (j == 1)
+	dims[1] = 1;
+
+      ndims = j > 2 ? j : 2;
+    }
+
+  private:
+
+    // No assignment!
+
+    dim_vector_rep& operator = (const dim_vector_rep& dv);
+  };
+
+  dim_vector_rep *rep;
+
+  void make_unique (void)
+  {
+    if (rep->count > 1)
+      {
+	--rep->count;
+	rep = new dim_vector_rep (*rep);
+      }
+  }
+
+private:
+
+  dim_vector_rep *nil_rep (void) const
+  {
+    static dim_vector_rep *nr = new dim_vector_rep ();
+
+    return nr;
+  }
+
+public:
+
+  explicit dim_vector (void)
+    : rep (nil_rep ()) { rep->count++; }
+
+  explicit dim_vector (octave_idx_type n)
+    : rep (new dim_vector_rep (n)) { }
+
+  explicit dim_vector (octave_idx_type r, octave_idx_type c)
+    : rep (new dim_vector_rep (r, c)) { }
+
+  explicit dim_vector (octave_idx_type r, octave_idx_type c, octave_idx_type p)
+    : rep (new dim_vector_rep (r, c, p)) { }
+
+  dim_vector (const dim_vector& dv)
+    : rep (dv.rep) { rep->count++; }
+
+  dim_vector& operator = (const dim_vector& dv)
+  {
+    if (&dv != this)
+      {
+	if (--rep->count <= 0)
+	  delete rep;
+
+	rep = dv.rep;
+	rep->count++;
+      }
+
+    return *this;
+  }
+
+  ~dim_vector (void)
+  {
+    if (--rep->count <= 0)
+      delete rep;
+  }
+
+  int length (void) const { return rep->length (); }
+
+  octave_idx_type& elem (int i) { make_unique (); return rep->elem (i); }
+
+  octave_idx_type elem (int i) const { return rep->elem (i); }
+
+  octave_idx_type& operator () (int i) { return elem (i); }
+
+  octave_idx_type operator () (int i) const { return elem (i); }
+
+  void resize (int n, int fill_value = 0)
+  {
+    int len = length ();
+
+    if (n != len)
+      {
+	dim_vector_rep *old_rep = rep;
+
+	rep = new dim_vector_rep (n, old_rep, fill_value);
+
+	if (--old_rep->count <= 0)
+	  delete old_rep;
+      }
+  }
+
+  std::string str (char sep = 'x') const
+  {
+    std::ostringstream buf;
+
+    for (int i = 0; i < length (); i++)
+      {
+	buf << elem (i);
+
+	if (i < length () - 1)
+	  buf << sep;
+      }
+
+    std::string retval = buf.str ();
+
+    return retval;
+  }
+
+  bool all_zero (void) const
+  {
+    bool retval = true;
+
+    for (int i = 0; i < length (); i++)
+      {
+	if (elem (i) != 0)
+	  {
+	    retval = false;
+	    break;
+	  }
+      }
+
+    return retval;
+  }
+
+  bool any_zero (void) const
+  {
+    bool retval = false;
+
+    for (int i = 0; i < length (); i++)
+      {
+	if (elem (i) == 0)
+	  {
+	    retval = true;
+	    break;
+	  }
+      }
+
+    return retval;
+  }
+
+  int
+  num_ones (void) const
+  {
+    int retval = 0;
+
+    for (int i = 0; i < length (); i++)
+      if (elem (i) == 1)
+	retval++;
+
+    return retval;
+  }
+
+  bool
+  all_ones (void) const
+  {
+    return (num_ones () == length ());
+  }
+
+  // This is the number of elements that a matrix with this dimension
+  // vector would have, NOT the number of dimensions (elements in the
+  // dimension vector).
+
+  octave_idx_type numel (int n = 0) const
+  {
+    int n_dims = length ();
+
+    octave_idx_type retval = 1;
+
+    for (int i = n; i < n_dims; i++)
+      retval *= elem (i);
+
+    return retval;
+  }
+
+  bool any_neg (void) const
+  {
+    int n_dims = length (), i;
+    for (i = 0; i < n_dims; i++)
+      if (elem (i) < 0) break;
+    return i < n_dims;
+  }
+
+  void chop_trailing_singletons (void)
+  {
+    make_unique ();
+    rep->chop_trailing_singletons ();
+  }
+
+  void chop_all_singletons (void)
+  {
+    make_unique ();
+    rep->chop_all_singletons ();
+  }
+
+  dim_vector squeeze (void) const
+  {
+    dim_vector new_dims = *this;
+
+    bool dims_changed = 1;
+
+    int k = 0;
+
+    for (int i = 0; i < length (); i++)
+      {
+	if (elem (i) == 1)
+	  dims_changed = true;
+	else
+	  new_dims(k++) = elem (i);
+      }
+
+    if (dims_changed)
+      {
+	if (k == 0)
+	  new_dims = dim_vector (1, 1);
+	else if (k == 1)
+	  {
+	    // There is one non-singleton dimension, so we need
+	    // to decide the correct orientation.
+
+	    if (elem (0) == 1)
+	      {
+		// The original dimension vector had a leading
+		// singleton dimension.
+
+		octave_idx_type tmp = new_dims(0);
+	
+		new_dims.resize (2);
+
+ 		new_dims(0) = 1;
+		new_dims(1) = tmp;
+	      }
+	    else
+	      {
+		// The first element of the original dimension vector
+		// was not a singleton dimension.
+
+		new_dims.resize (2);
+
+		new_dims(1) = 1;
+	      }
+	  }
+	else
+	  new_dims.resize(k);
+      }
+ 
+    return new_dims;
+  }
+
+  bool concat (const dim_vector& dvb, int dim = 0)
+  {
+    if (all_zero ())
+      {
+	*this = dvb;
+	return true;
+      }
+
+    if (dvb.all_zero ())
+      return true;
+
+    int na = length ();
+    int nb = dvb.length ();
+  
+    // Find the max and min value of na and nb
+    int n_max = na > nb ? na : nb;
+    int n_min = na < nb ? na : nb;
+  
+    // The elements of the dimension vectors can only differ
+    // if the dim variable differs from the actual dimension
+    // they differ.
+
+    for (int i = 0; i < n_min; i++)
+      {
+	if (elem(i) != dvb(i) && dim != i)
+	    return false;
+      }
+  
+    // Ditto.
+    for (int i = n_min; i < n_max; i++)
+      {
+	if (na > n_min)
+	  {
+	    if (elem(i) != 1 && dim != i)
+	      return false;
+	  }
+	else 
+	  {
+	    if (dvb(i) != 1 && dim != i)
+	      return false;
+	  }
+      }
+    
+    // If we want to add the dimension vectors at a dimension
+    // larger than both, then we need to set n_max to this number
+    // so that we resize *this to the right dimension.
+    
+    n_max = n_max > (dim + 1) ? n_max : (dim + 1);
+    
+    // Resize *this to the appropriate dimensions.
+    
+    if (n_max > na)
+      {
+	dim_vector_rep *old_rep = rep;
+
+	rep = new dim_vector_rep (n_max, old_rep, 1);
+
+	if (--old_rep->count <= 0)
+	  delete old_rep;
+      }
+  
+    // Larger or equal since dim has been decremented by one.
+
+    if (dim >= nb)
+      elem (dim)++;
+    else
+      elem (dim) += dvb(dim);
+
+    return true;
+  }
+
+  // Forces certain dimensionality, preserving numel (). Missing dimensions are
+  // set to 1, redundant are folded into the trailing one. If n = 1, the result
+  // is 2d and the second dim is 1 (dim_vectors are always at least 2D).
+  // If the original dimensions were all zero, the padding value is zero.
+  dim_vector redim (int n) const
+    {
+      int n_dims = length ();
+      if (n_dims == n)
+        return *this;
+      else
+        {
+          dim_vector retval;
+          retval.resize (n == 1 ? 2 : n, 1);
+          
+          bool zeros = true;
+          for (int i = 0; i < n && i < n_dims; i++)
+            {
+              retval(i) = elem (i);
+              zeros = zeros && elem (i) == 0;
+            }
+
+          if (n < n_dims)
+            {
+              octave_idx_type k = 1;
+              for (int i = n; i < n_dims; i++)
+                k *= elem (i);
+              retval(n - 1) *= k;
+            }
+          else if (zeros)
+            {
+              for (int i = n_dims; i < n; i++)
+                retval.elem (i) = 0;
+            }
+
+          return retval;
+        }
+    }
+
+  bool is_vector (void) const
+    {
+      return (length () == 2 && (elem (0) == 1 || elem (1) == 1));
+    }
+
+};
+
+static inline bool
+operator == (const dim_vector& a, const dim_vector& b)
+{
+  bool retval = true;
+
+  int a_len = a.length ();
+  int b_len = b.length ();
+
+  if (a_len != b_len)
+    retval = false;
+  else
+    {
+      for (int i = 0; i < a_len; i++)
+	{
+	  if (a(i) != b(i))
+	    {
+	      retval = false;
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+operator != (const dim_vector& a, const dim_vector& b)
+{
+  return ! operator == (a, b);
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dir-ops.cc b/liboctave/dir-ops.cc
new file mode 100644
index 0000000..b9c7ea2
--- /dev/null
+++ b/liboctave/dir-ops.cc
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+
+#include <list>
+#include <string>
+
+#include "sysdir.h"
+
+#include "dir-ops.h"
+#include "file-ops.h"
+#include "lo-error.h"
+#include "lo-sysdep.h"
+#include "str-vec.h"
+
+bool
+dir_entry::open (const std::string& n)
+{
+  fail = true;
+
+  if (! n.empty ())
+    name = n;
+
+  if (! name.empty ())
+    {
+      close ();
+      
+      std::string fullname = file_ops::tilde_expand (name);
+
+      dir = static_cast<void *> (opendir (fullname.c_str ()));
+
+      if (dir)
+	fail = false;
+      else
+	{
+	  using namespace std;
+	  errmsg = strerror (errno);
+	}
+    }
+  else
+    errmsg = "dir_entry::open: empty file name";
+
+  return ! fail;
+}
+
+string_vector
+dir_entry::read (void)
+{
+  string_vector retval;
+
+  if (ok ())
+    {
+      std::list<std::string> dirlist;
+
+      struct dirent *dir_ent;
+
+      while ((dir_ent = readdir (static_cast<DIR *> (dir))))
+	{
+	  if (dir_ent)
+	    dirlist.push_back (dir_ent->d_name);
+	  else
+	    break;
+	}
+
+      retval = string_vector (dirlist);
+    }
+
+  return retval;
+}
+
+void
+dir_entry::close (void)
+{
+  if (dir)
+    closedir (static_cast<DIR *> (dir));
+
+  dir = 0;
+}
+
+void
+dir_entry::copy (const dir_entry& de)
+{
+  name = de.name;
+  dir = de.dir;
+  fail = de.fail;
+  errmsg = de.errmsg;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/dir-ops.h b/liboctave/dir-ops.h
new file mode 100644
index 0000000..c9b1c71
--- /dev/null
+++ b/liboctave/dir-ops.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dir_ops_h)
+#define octave_dir_ops_h 1
+
+#include <string>
+
+#include "str-vec.h"
+
+class
+OCTAVE_API
+dir_entry
+{
+public:
+
+  dir_entry (const std::string& n = std::string ()) : name (n), dir (0)
+    {
+      if (! name.empty ())
+        open ();
+    }
+
+  dir_entry (const dir_entry& d) { copy (d); }
+
+  dir_entry& operator = (const dir_entry& d)
+    {
+      if (this != &d)
+	copy (d);
+
+      return *this;
+    }
+
+  ~dir_entry (void) { close (); }
+
+  bool open (const std::string& = std::string ());
+
+  string_vector read (void);
+
+  void close (void);
+
+  bool ok (void) const { return dir && ! fail; }
+
+  operator bool () const { return ok (); }
+
+  std::string error (void) const { return ok () ? std::string () : errmsg; }
+
+private:
+
+  // Name of the directory.
+  std::string name;
+
+  // A pointer to the contents of the directory.  We use void here to
+  // avoid possible conflicts with the way some systems declare the
+  // type DIR.
+  void *dir;
+
+  // TRUE means the open for this directory failed.
+  bool fail;
+
+  // If a failure occurs, this contains the system error text.
+  std::string errmsg;
+
+  void copy (const dir_entry&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/eigs-base.cc b/liboctave/eigs-base.cc
new file mode 100755
index 0000000..bd3c3ae
--- /dev/null
+++ b/liboctave/eigs-base.cc
@@ -0,0 +1,3840 @@
+/*
+
+Copyright (C) 2005, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cmath>
+#include <vector>
+#include <iostream>
+
+#include "f77-fcn.h"
+#include "quit.h"
+#include "SparsedbleLU.h"
+#include "SparseCmplxLU.h"
+#include "dSparse.h"
+#include "CSparse.h"
+#include "MatrixType.h"
+#include "SparsedbleCHOL.h"
+#include "SparseCmplxCHOL.h"
+#include "oct-rand.h"
+#include "dbleCHOL.h"
+#include "CmplxCHOL.h"
+#include "dbleLU.h"
+#include "CmplxLU.h"
+
+#ifdef HAVE_ARPACK
+typedef ColumnVector (*EigsFunc) (const ColumnVector &x, int &eigs_error);
+typedef ComplexColumnVector (*EigsComplexFunc) 
+  (const ComplexColumnVector &x, int &eigs_error);
+
+// Arpack and blas fortran functions we call.
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dsaupd, DSAUPD) (octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const double&,
+			     double*, const octave_idx_type&, double*,
+			     const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type*, double*, double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dseupd, DSEUPD) (const int&, F77_CONST_CHAR_ARG_DECL,
+			     octave_idx_type*, double*, double*,
+			     const octave_idx_type&, const double&,
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const double&, double*, const octave_idx_type&, 
+			     double*, const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type*, double*, double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dnaupd, DNAUPD) (octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, F77_CONST_CHAR_ARG_DECL, 
+			     octave_idx_type&, const double&,
+			     double*, const octave_idx_type&, double*,
+			     const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type*, double*, double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dneupd, DNEUPD) (const int&, F77_CONST_CHAR_ARG_DECL,
+			     octave_idx_type*, double*, double*,
+			     double*, const octave_idx_type&, const double&,
+			     const double&, double*, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, F77_CONST_CHAR_ARG_DECL, 
+			     octave_idx_type&, const double&, double*, 
+			     const octave_idx_type&, double*, 
+			     const octave_idx_type&, octave_idx_type*, 
+			     octave_idx_type*, double*, double*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (znaupd, ZNAUPD) (octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const double&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type*, Complex*, Complex*, 
+			     const octave_idx_type&, double *, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (zneupd, ZNEUPD) (const int&, F77_CONST_CHAR_ARG_DECL,
+			     octave_idx_type*, Complex*, Complex*, 
+			     const octave_idx_type&, const Complex&,
+			     Complex*, F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const double&,
+			     Complex*, const octave_idx_type&, Complex*,
+			     const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type*, Complex*, Complex*, 
+			     const octave_idx_type&, double *, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const double&,
+			   const double*, const octave_idx_type&, const double*,
+			   const octave_idx_type&, const double&, double*,
+			   const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+
+
+  F77_RET_T
+  F77_FUNC (zgemv, ZGEMV) (F77_CONST_CHAR_ARG_DECL,
+                           const octave_idx_type&, const octave_idx_type&, const Complex&,
+                           const Complex*, const octave_idx_type&, const Complex*,
+                           const octave_idx_type&, const Complex&, Complex*, const octave_idx_type&
+                           F77_CHAR_ARG_LEN_DECL);
+
+}
+
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static octave_idx_type
+lusolve (const SparseMatrix&, const SparseMatrix&, Matrix&);
+
+static octave_idx_type
+lusolve (const SparseComplexMatrix&, const SparseComplexMatrix&, 
+	 ComplexMatrix&);
+
+static octave_idx_type
+lusolve (const Matrix&, const Matrix&, Matrix&);
+
+static octave_idx_type
+lusolve (const ComplexMatrix&, const ComplexMatrix&, ComplexMatrix&);
+
+static ComplexMatrix
+ltsolve (const SparseComplexMatrix&, const ColumnVector&, 
+		const ComplexMatrix&);
+
+static Matrix
+ltsolve (const SparseMatrix&, const ColumnVector&, const Matrix&,);
+
+static ComplexMatrix
+ltsolve (const ComplexMatrix&, const ColumnVector&, const ComplexMatrix&);
+
+static Matrix
+ltsolve (const Matrix&, const ColumnVector&, const Matrix&,);
+
+static ComplexMatrix
+utsolve (const SparseComplexMatrix&, const ColumnVector&, const ComplexMatrix&);
+
+static Matrix
+utsolve (const SparseMatrix&, const ColumnVector&, const Matrix&);
+
+static ComplexMatrix
+utsolve (const ComplexMatrix&, const ColumnVector&, const ComplexMatrix&);
+
+static Matrix
+utsolve (const Matrix&, const ColumnVector&, const Matrix&);
+
+#endif
+
+template <class M, class SM>
+static octave_idx_type
+lusolve (const SM& L, const SM& U, M& m)
+{
+  octave_idx_type err = 0;
+  double rcond;
+  MatrixType utyp (MatrixType::Upper);
+
+  // Sparse L is lower triangular, Dense L is permuted lower triangular!!!
+  m = L.solve (m, err, rcond, 0);
+  if (err)
+    return err;
+
+  m = U.solve (utyp, m, err, rcond, 0);
+
+  return err;
+}
+
+template <class SM, class M>
+static M
+ltsolve (const SM& L, const ColumnVector& Q, const M& m)
+{
+  octave_idx_type n = L.cols();
+  octave_idx_type b_nc = m.cols();
+  octave_idx_type err = 0;
+  double rcond;
+  MatrixType ltyp (MatrixType::Lower);
+  M tmp = L.solve (ltyp, m, err, rcond, 0);
+  M retval;
+  const double* qv = Q.fortran_vec();
+
+  if (!err)
+    {
+      retval.resize (n, b_nc);
+      for (octave_idx_type j = 0; j < b_nc; j++)
+	{
+	  for (octave_idx_type i = 0; i < n; i++)
+	    retval.elem(static_cast<octave_idx_type>(qv[i]), j)  = 
+	      tmp.elem(i,j);
+	}
+    }
+
+  return retval;
+}
+
+template <class SM, class M>
+static M
+utsolve (const SM& U, const ColumnVector& Q, const M& m)
+{
+  octave_idx_type n = U.cols();
+  octave_idx_type b_nc = m.cols();
+  octave_idx_type err = 0;
+  double rcond;
+  MatrixType utyp (MatrixType::Upper);
+
+  M retval (n, b_nc);
+  const double* qv = Q.fortran_vec();
+  for (octave_idx_type j = 0; j < b_nc; j++)
+    {
+      for (octave_idx_type i = 0; i < n; i++)
+	retval.elem(i,j) = m.elem(static_cast<octave_idx_type>(qv[i]), j);
+    }
+  return U.solve (utyp, retval, err, rcond, 0);
+}
+
+static bool
+vector_product (const SparseMatrix& m, const double* x, double* y)
+{
+  octave_idx_type nc = m.cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    y[j] = 0.;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+      y[m.ridx(i)] += m.data(i) * x[j];
+
+  return true;
+}
+
+static bool
+vector_product (const Matrix& m, const double *x, double *y)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   nr, nc, 1.0,  m.data (), nr,
+			   x, 1, 0.0, y, 1
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecoverable error in dgemv");
+      return false;
+    }
+  else
+    return true;
+}
+
+static bool
+vector_product (const SparseComplexMatrix& m, const Complex* x, 
+			Complex* y)
+{
+  octave_idx_type nc = m.cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    y[j] = 0.;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+      y[m.ridx(i)] += m.data(i) * x[j];
+
+  return true;
+}
+
+static bool
+vector_product (const ComplexMatrix& m, const Complex *x, Complex *y)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   nr, nc, 1.0,  m.data (), nr,
+			   x, 1, 0.0, y, 1
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecoverable error in zgemv");
+      return false;
+    }
+  else
+    return true;
+}
+
+static bool
+make_cholb (Matrix& b, Matrix& bt, ColumnVector& permB)
+{
+  octave_idx_type info;
+  CHOL fact (b, info);
+  octave_idx_type n = b.cols();
+
+  if (info != 0)
+    return false;
+  else
+    {
+      bt = fact.chol_matrix ();
+      b =  bt.transpose();
+      permB = ColumnVector(n);
+      for (octave_idx_type i = 0; i < n; i++)
+	permB(i) = i;
+      return true;
+    }
+}
+
+static bool
+make_cholb (SparseMatrix& b, SparseMatrix& bt, ColumnVector& permB)
+{
+  octave_idx_type info;
+  SparseCHOL fact (b, info, false);
+
+  if (fact.P() != 0)
+    return false;
+  else
+    {
+      b = fact.L();
+      bt = b.transpose();
+      permB = fact.perm() - 1.0;
+      return true;
+    }
+}
+
+static bool
+make_cholb (ComplexMatrix& b, ComplexMatrix& bt, ColumnVector& permB)
+{
+  octave_idx_type info;
+  ComplexCHOL fact (b, info);
+  octave_idx_type n = b.cols();
+
+  if (info != 0)
+    return false;
+  else
+    {
+      bt = fact.chol_matrix ();
+      b =  bt.hermitian();
+      permB = ColumnVector(n);
+      for (octave_idx_type i = 0; i < n; i++)
+	permB(i) = i;
+      return true;
+    }
+}
+
+static bool
+make_cholb (SparseComplexMatrix& b, SparseComplexMatrix& bt, 
+	    ColumnVector& permB)
+{
+  octave_idx_type info;
+  SparseComplexCHOL fact (b, info, false);
+
+  if (fact.P() != 0)
+    return false;
+  else
+    {
+      b = fact.L();
+      bt = b.hermitian();
+      permB = fact.perm() - 1.0;
+      return true;
+    }
+}
+
+static bool
+LuAminusSigmaB (const SparseMatrix &m, const SparseMatrix &b, 
+		bool cholB, const ColumnVector& permB, double sigma,
+		SparseMatrix &L, SparseMatrix &U, octave_idx_type *P, 
+		octave_idx_type *Q)
+{
+  bool have_b = ! b.is_empty ();
+  octave_idx_type n = m.rows();
+
+  // Caclulate LU decomposition of 'A - sigma * B'
+  SparseMatrix AminusSigmaB (m);
+
+  if (have_b)
+    {
+      if (cholB)
+	{
+	  if (permB.length())
+	    {
+	      SparseMatrix tmp(n,n,n);
+	      for (octave_idx_type i = 0; i < n; i++)
+		{
+		  tmp.xcidx(i) = i;
+		  tmp.xridx(i) = 
+		    static_cast<octave_idx_type>(permB(i));
+		  tmp.xdata(i) = 1;
+		}
+	      tmp.xcidx(n) = n;
+
+	      AminusSigmaB = AminusSigmaB - sigma * tmp *
+		b.transpose() * b * tmp.transpose();
+	    }
+	  else
+	    AminusSigmaB = AminusSigmaB - sigma *
+	      b.transpose() * b;
+	}
+      else
+	AminusSigmaB = AminusSigmaB - sigma * b;
+    }
+  else
+    {
+      SparseMatrix sigmat (n, n, n);
+
+	  // Create sigma * speye(n,n)
+	  sigmat.xcidx (0) = 0;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      sigmat.xdata(i) = sigma;
+	      sigmat.xridx(i) = i;
+	      sigmat.xcidx(i+1) = i + 1;
+	    }
+
+	  AminusSigmaB = AminusSigmaB - sigmat;
+	}
+
+  SparseLU fact (AminusSigmaB);
+
+  L = fact.L ();
+  U = fact.U ();
+  const octave_idx_type *P2 = fact.row_perm ();
+  const octave_idx_type *Q2 = fact.col_perm ();
+
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      P[j] = P2[j];
+      Q[j] = Q2[j];
+    }
+
+  // Test condition number of LU decomposition
+  double minU = octave_NaN;
+  double maxU = octave_NaN;
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      double d = 0.;
+      if (U.xcidx(j+1) > U.xcidx(j) &&
+	  U.xridx (U.xcidx(j+1)-1) == j)
+	d = std::abs (U.xdata (U.xcidx(j+1)-1));
+
+      if (xisnan (minU) || d < minU)
+	minU = d;
+
+      if (xisnan (maxU) || d > maxU)
+	maxU = d;
+    }
+
+  double rcond = (minU / maxU);
+  volatile double rcond_plus_one = rcond + 1.0;
+
+  if (rcond_plus_one == 1.0 || xisnan (rcond))
+    {
+      (*current_liboctave_warning_handler)
+	("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
+      (*current_liboctave_warning_handler)
+	("       an eigenvalue. Convergence is not guaranteed");
+    }
+
+  return true;
+}
+
+static bool
+LuAminusSigmaB (const Matrix &m, const Matrix &b, 
+		bool cholB, const ColumnVector& permB, double sigma,
+		Matrix &L, Matrix &U, octave_idx_type *P, 
+		octave_idx_type *Q)
+{
+  bool have_b = ! b.is_empty ();
+  octave_idx_type n = m.cols();
+
+  // Caclulate LU decomposition of 'A - sigma * B'
+  Matrix AminusSigmaB (m);
+
+  if (have_b)
+    {
+      if (cholB)
+	{
+	  Matrix tmp = sigma * b.transpose() * b;
+	  const double *pB = permB.fortran_vec();
+	  double *p = AminusSigmaB.fortran_vec();
+
+	  if (permB.length())
+	    {
+	      for (octave_idx_type j = 0; 
+		   j < b.cols(); j++)
+		for (octave_idx_type i = 0; 
+		     i < b.rows(); i++)
+		  *p++ -=  tmp.xelem (static_cast<octave_idx_type>(pB[i]),
+				      static_cast<octave_idx_type>(pB[j]));
+	    }
+	  else
+	    AminusSigmaB = AminusSigmaB - tmp;
+	}
+      else
+	AminusSigmaB = AminusSigmaB - sigma * b;
+    }
+  else
+    {
+      double *p = AminusSigmaB.fortran_vec();
+
+      for (octave_idx_type i = 0; i < n; i++)
+	p[i*(n+1)] -= sigma;
+    }
+
+  LU fact (AminusSigmaB);
+
+  L = fact.P().transpose() * fact.L ();
+  U = fact.U ();
+  for (octave_idx_type j = 0; j < n; j++)
+    P[j] = Q[j] = j;  
+
+  // Test condition number of LU decomposition
+  double minU = octave_NaN;
+  double maxU = octave_NaN;
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      double d = std::abs (U.xelem(j,j));
+      if (xisnan (minU) || d < minU)
+	minU = d;
+
+      if (xisnan (maxU) || d > maxU)
+	maxU = d;
+    }
+
+  double rcond = (minU / maxU);
+  volatile double rcond_plus_one = rcond + 1.0;
+
+  if (rcond_plus_one == 1.0 || xisnan (rcond))
+    {
+      (*current_liboctave_warning_handler) 
+	("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
+      (*current_liboctave_warning_handler) 
+	("       an eigenvalue. Convergence is not guaranteed");
+    }
+
+  return true;
+}
+
+static bool
+LuAminusSigmaB (const SparseComplexMatrix &m, const SparseComplexMatrix &b, 
+		bool cholB, const ColumnVector& permB, Complex sigma,
+		SparseComplexMatrix &L, SparseComplexMatrix &U,
+		octave_idx_type *P, octave_idx_type *Q)
+{
+  bool have_b = ! b.is_empty ();
+  octave_idx_type n = m.rows();
+
+  // Caclulate LU decomposition of 'A - sigma * B'
+  SparseComplexMatrix AminusSigmaB (m);
+
+  if (have_b)
+    {
+      if (cholB)
+	{
+	  if (permB.length())
+	    {
+	      SparseMatrix tmp(n,n,n);
+	      for (octave_idx_type i = 0; i < n; i++)
+		{
+		  tmp.xcidx(i) = i;
+		  tmp.xridx(i) = 
+		    static_cast<octave_idx_type>(permB(i));
+		  tmp.xdata(i) = 1;
+		}
+	      tmp.xcidx(n) = n;
+
+	      AminusSigmaB = AminusSigmaB - tmp * b.hermitian() * b * 
+		tmp.transpose() * sigma;
+	    }
+	  else
+	    AminusSigmaB = AminusSigmaB - sigma * b.hermitian() * b;
+	}
+      else
+	AminusSigmaB = AminusSigmaB - sigma * b;
+    }
+  else
+    {
+      SparseComplexMatrix sigmat (n, n, n);
+
+      // Create sigma * speye(n,n)
+      sigmat.xcidx (0) = 0;
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  sigmat.xdata(i) = sigma;
+	  sigmat.xridx(i) = i;
+	  sigmat.xcidx(i+1) = i + 1;
+	}
+
+      AminusSigmaB = AminusSigmaB - sigmat;
+    }
+
+  SparseComplexLU fact (AminusSigmaB);
+
+  L = fact.L ();
+  U = fact.U ();
+  const octave_idx_type *P2 = fact.row_perm ();
+  const octave_idx_type *Q2 = fact.col_perm ();
+
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      P[j] = P2[j];
+      Q[j] = Q2[j];
+    }
+
+  // Test condition number of LU decomposition
+  double minU = octave_NaN;
+  double maxU = octave_NaN;
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      double d = 0.;
+      if (U.xcidx(j+1) > U.xcidx(j) &&
+	  U.xridx (U.xcidx(j+1)-1) == j)
+	d = std::abs (U.xdata (U.xcidx(j+1)-1));
+
+      if (xisnan (minU) || d < minU)
+	minU = d;
+
+      if (xisnan (maxU) || d > maxU)
+	maxU = d;
+    }
+
+  double rcond = (minU / maxU);
+  volatile double rcond_plus_one = rcond + 1.0;
+
+  if (rcond_plus_one == 1.0 || xisnan (rcond))
+    {
+      (*current_liboctave_warning_handler)
+	("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
+      (*current_liboctave_warning_handler)
+	("       an eigenvalue. Convergence is not guaranteed");
+    }
+
+  return true;
+}
+
+static bool
+LuAminusSigmaB (const ComplexMatrix &m, const ComplexMatrix &b, 
+		bool cholB, const ColumnVector& permB, Complex sigma,
+		ComplexMatrix &L, ComplexMatrix &U, octave_idx_type *P, 
+		octave_idx_type *Q)
+{
+  bool have_b = ! b.is_empty ();
+  octave_idx_type n = m.cols();
+
+  // Caclulate LU decomposition of 'A - sigma * B'
+  ComplexMatrix AminusSigmaB (m);
+
+  if (have_b)
+    {
+      if (cholB)
+	{
+	  ComplexMatrix tmp = sigma * b.hermitian() * b;
+	  const double *pB = permB.fortran_vec();
+	  Complex *p = AminusSigmaB.fortran_vec();
+
+	  if (permB.length())
+	    {
+	      for (octave_idx_type j = 0; 
+		   j < b.cols(); j++)
+		for (octave_idx_type i = 0; 
+		     i < b.rows(); i++)
+		  *p++ -=  tmp.xelem (static_cast<octave_idx_type>(pB[i]),
+				      static_cast<octave_idx_type>(pB[j]));
+	    }
+	  else
+	    AminusSigmaB = AminusSigmaB - tmp;
+	}
+      else
+	AminusSigmaB = AminusSigmaB - sigma * b;
+    }
+  else
+    {
+      Complex *p = AminusSigmaB.fortran_vec();
+
+      for (octave_idx_type i = 0; i < n; i++)
+	p[i*(n+1)] -= sigma;
+    }
+
+  ComplexLU fact (AminusSigmaB);
+
+  L = fact.P().transpose() * fact.L ();
+  U = fact.U ();
+  for (octave_idx_type j = 0; j < n; j++)
+    P[j] = Q[j] = j;  
+
+  // Test condition number of LU decomposition
+  double minU = octave_NaN;
+  double maxU = octave_NaN;
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      double d = std::abs (U.xelem(j,j));
+      if (xisnan (minU) || d < minU)
+	minU = d;
+
+      if (xisnan (maxU) || d > maxU)
+	maxU = d;
+    }
+
+  double rcond = (minU / maxU);
+  volatile double rcond_plus_one = rcond + 1.0;
+
+  if (rcond_plus_one == 1.0 || xisnan (rcond))
+    {
+      (*current_liboctave_warning_handler) 
+	("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
+      (*current_liboctave_warning_handler) 
+	("       an eigenvalue. Convergence is not guaranteed");
+    }
+
+  return true;
+}
+
+template <class M>
+octave_idx_type
+EigsRealSymmetricMatrix (const M& m, const std::string typ, 
+			 octave_idx_type k, octave_idx_type p,
+			 octave_idx_type &info, Matrix &eig_vec,
+			 ColumnVector &eig_val, const M& _b,
+			 ColumnVector &permB, ColumnVector &resid, 
+			 std::ostream& os, double tol, int rvec, 
+			 bool cholB, int disp, int maxit)
+{
+  M b(_b);
+  octave_idx_type n = m.cols ();
+  octave_idx_type mode = 1;
+  bool have_b = ! b.is_empty();
+  bool note3 = false;
+  char bmat = 'I';
+  double sigma = 0.;
+  M bt;
+
+  if (m.rows() != m.cols())
+    {
+      (*current_liboctave_error_handler) ("eigs: A must be square");
+      return -1;
+    }
+  if (have_b && (m.rows() != b.rows() || m.rows() != b.cols()))
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: B must be square and the same size as A");
+      return -1;
+    }
+
+  if (resid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      resid = ColumnVector (octave_rand::vector(n));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+  
+  if (k < 1 || k > n - 2)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1-1).\n"
+	 "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (have_b && cholB && permB.length() != 0) 
+    {
+      // Check the we really have a permutation vector
+      if (permB.length() != n)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: permB vector invalid");
+	  return -1;
+	}
+      else
+	{
+	  Array<bool> checked(n,false);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      octave_idx_type bidx = 
+		static_cast<octave_idx_type> (permB(i));
+	      if (checked(bidx) || bidx < 0 ||
+		  bidx >= n || D_NINT (bidx) != bidx)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("eigs: permB vector invalid");
+		  return -1;
+		}
+	    }
+	}
+    }
+
+  if (typ != "LM" && typ != "SM" && typ != "LA" && typ != "SA" && 
+      typ != "BE" && typ != "LR" && typ != "SR" && typ != "LI" &&
+      typ != "SI")
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecognized sigma value");
+      return -1;
+    }
+  
+  if (typ == "LI" || typ == "SI" || typ == "LR" || typ == "SR")
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: invalid sigma value for real symmetric problem");
+      return -1;
+    }
+
+  if (have_b)
+    {
+      // See Note 3 dsaupd
+      note3 = true;
+      if (cholB)
+	{
+	  bt = b;
+	  b = b.transpose();
+	  if (permB.length() == 0)
+	    {
+	      permB = ColumnVector(n);
+	      for (octave_idx_type i = 0; i < n; i++)
+		permB(i) = i;
+	    }
+	}
+      else
+	{
+	  if (! make_cholb(b, bt, permB))
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: The matrix B is not positive definite");
+	      return -1;
+	    }
+	}
+    }
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+ 
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  octave_idx_type lwork = p * (p + 8);
+
+  OCTAVE_LOCAL_BUFFER (double, v, n * p);
+  OCTAVE_LOCAL_BUFFER (double, workl, lwork);
+  OCTAVE_LOCAL_BUFFER (double, workd, 3 * n);
+  double *presid = resid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (dsaupd, DSAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in dsaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  if (have_b)
+	    {
+	      Matrix mtmp (n,1);
+	      for (octave_idx_type i = 0; i < n; i++)
+		mtmp(i,0) = workd[i + iptr(0) - 1];
+	      
+	      mtmp = utsolve(bt, permB, m * ltsolve(b, permB, mtmp));
+
+	      for (octave_idx_type i = 0; i < n; i++)
+		workd[i+iptr(1)-1] = mtmp(i,0);
+	    }
+	  else if (!vector_product (m, workd + iptr(0) - 1, 
+				    workd + iptr(1) - 1))
+	    break;
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+
+  eig_vec.resize (n, k);
+  double *z = eig_vec.fortran_vec ();
+
+  eig_val.resize (k);
+  double *d = eig_val.fortran_vec ();
+
+  F77_FUNC (dseupd, DSEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, d, z, n, sigma, 
+     F77_CONST_CHAR_ARG2 (&bmat, 1), n, 
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2), k, tol, presid, p, v, n, iparam,
+     ipntr, workd, workl, lwork, info2 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) 
+     F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: unrecoverable exception encountered in dseupd");
+      return -1;
+    }
+  else
+    {
+      if (info2 == 0)
+	{
+	  octave_idx_type k2 = k / 2;
+	  if (typ != "SM" && typ != "BE")
+	    {
+	      for (octave_idx_type i = 0; i < k2; i++)
+		{
+		  double dtmp = d[i];
+		  d[i] = d[k - i - 1];
+		  d[k - i - 1] = dtmp;
+		}
+	    }
+
+	  if (rvec)
+	    {
+	      if (typ != "SM" && typ != "BE")
+		{
+		  OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+		  for (octave_idx_type i = 0; i < k2; i++)
+		    {
+		      octave_idx_type off1 = i * n;
+		      octave_idx_type off2 = (k - i - 1) * n;
+
+		      if (off1 == off2)
+			continue;
+
+		      for (octave_idx_type j = 0; j < n; j++)
+			dtmp[j] = z[off1 + j];
+
+		      for (octave_idx_type j = 0; j < n; j++)
+			z[off1 + j] = z[off2 + j];
+
+		      for (octave_idx_type j = 0; j < n; j++)
+			z[off2 + j] = dtmp[j];
+		    }
+		}
+
+	      if (note3)
+		eig_vec = ltsolve(b, permB, eig_vec);
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: error %d in dseupd", info2);
+	  return -1;
+	}
+    }
+
+  return ip(4);
+}
+
+template <class M>
+octave_idx_type
+EigsRealSymmetricMatrixShift (const M& m, double sigma,
+			      octave_idx_type k, octave_idx_type p, 
+			      octave_idx_type &info, Matrix &eig_vec, 
+			      ColumnVector &eig_val, const M& _b,
+			      ColumnVector &permB, ColumnVector &resid, 
+			      std::ostream& os, double tol, int rvec, 
+			      bool cholB, int disp, int maxit)
+{
+  M b(_b);
+  octave_idx_type n = m.cols ();
+  octave_idx_type mode = 3;
+  bool have_b = ! b.is_empty();
+  std::string typ = "LM";
+
+  if (m.rows() != m.cols())
+    {
+      (*current_liboctave_error_handler) ("eigs: A must be square");
+      return -1;
+    }
+  if (have_b && (m.rows() != b.rows() || m.rows() != b.cols()))
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: B must be square and the same size as A");
+      return -1;
+    }
+
+  // FIXME: The "SM" type for mode 1 seems unstable though faster!!
+  //if (! std::abs (sigma))
+  //  return EigsRealSymmetricMatrix (m, "SM", k, p, info, eig_vec, eig_val,
+  //				    _b, permB, resid, os, tol, rvec, cholB,
+  //				    disp, maxit);
+
+  if (resid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      resid = ColumnVector (octave_rand::vector(n));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1-1).\n"
+	     "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+  
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (have_b && cholB && permB.length() != 0) 
+    {
+      // Check the we really have a permutation vector
+      if (permB.length() != n)
+	{
+	  (*current_liboctave_error_handler) ("eigs: permB vector invalid");
+	  return -1;
+	}
+      else
+	{
+	  Array<bool> checked(n,false);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      octave_idx_type bidx = 
+		static_cast<octave_idx_type> (permB(i));
+	      if (checked(bidx) || bidx < 0 ||
+		  bidx >= n || D_NINT (bidx) != bidx)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("eigs: permB vector invalid");
+		  return -1;
+		}
+	    }
+	}
+    }
+
+  char bmat = 'I';
+  if (have_b)
+    bmat = 'G';
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  M L, U;
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, P, (have_b ? b.rows() : m.rows()));
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Q, (have_b ? b.cols() : m.cols()));
+
+  if (! LuAminusSigmaB(m, b, cholB, permB, sigma, L, U, P, Q))
+    return -1;
+
+  octave_idx_type lwork = p * (p + 8);
+
+  OCTAVE_LOCAL_BUFFER (double, v, n * p);
+  OCTAVE_LOCAL_BUFFER (double, workl, lwork);
+  OCTAVE_LOCAL_BUFFER (double, workd, 3 * n);
+  double *presid = resid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (dsaupd, DSAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in dsaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  if (have_b)
+	    {
+	      if (ido == -1)
+		{
+		  OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+		  vector_product (m, workd+iptr(0)-1, dtmp);
+
+		  Matrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = dtmp[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  double *ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	      else if (ido == 2)
+		vector_product (b, workd+iptr(0)-1, workd+iptr(1)-1);
+	      else
+		{
+		  double *ip2 = workd+iptr(2)-1;
+		  Matrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ip2[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	    }
+	  else
+	    {
+	      if (ido == 2)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    workd[iptr(0) + i - 1] = workd[iptr(1) + i - 1];
+		}
+	      else
+		{
+		  double *ip2 = workd+iptr(0)-1;
+		  Matrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ip2[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	    }
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+			
+  eig_vec.resize (n, k);
+  double *z = eig_vec.fortran_vec ();
+
+  eig_val.resize (k);
+  double *d = eig_val.fortran_vec ();
+
+  F77_FUNC (dseupd, DSEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, d, z, n, sigma, 
+     F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2),
+     k, tol, presid, p, v, n, iparam, ipntr, workd, workl, lwork, info2
+     F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: unrecoverable exception encountered in dseupd");
+      return -1;
+    }
+  else
+    {
+      if (info2 == 0)
+	{
+	  octave_idx_type k2 = k / 2;
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      double dtmp = d[i];
+	      d[i] = d[k - i - 1];
+	      d[k - i - 1] = dtmp;
+	    }
+
+	  if (rvec)
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+	      for (octave_idx_type i = 0; i < k2; i++)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (k - i - 1) * n;
+
+		  if (off1 == off2)
+		    continue;
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    dtmp[j] = z[off1 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off1 + j] = z[off2 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off2 + j] = dtmp[j];
+		}
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("eigs: error %d in dseupd", info2);
+	  return -1;
+	}
+    }
+
+  return ip(4);
+}
+
+octave_idx_type
+EigsRealSymmetricFunc (EigsFunc fun, octave_idx_type n,
+		       const std::string &_typ, double sigma,
+		       octave_idx_type k, octave_idx_type p, 
+		       octave_idx_type &info, Matrix &eig_vec, 
+		       ColumnVector &eig_val, ColumnVector &resid, 
+		       std::ostream& os, double tol, int rvec,
+		       bool /* cholB */, int disp, int maxit)
+{
+  std::string typ (_typ);
+  bool have_sigma = (sigma ? true : false);
+  char bmat = 'I';
+  octave_idx_type mode = 1;
+  int err = 0;
+
+  if (resid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      resid = ColumnVector (octave_rand::vector(n));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+  
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	     "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (! have_sigma)
+    {
+      if (typ != "LM" && typ != "SM" && typ != "LA" && typ != "SA" && 
+	  typ != "BE" && typ != "LR" && typ != "SR" && typ != "LI" &&
+	  typ != "SI")
+	(*current_liboctave_error_handler) 
+	  ("eigs: unrecognized sigma value");
+
+      if (typ == "LI" || typ == "SI" || typ == "LR" || typ == "SR")
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: invalid sigma value for real symmetric problem");
+	  return -1;
+	}
+
+      if (typ == "SM")
+	{
+	  typ = "LM";
+	  sigma = 0.;
+	  mode = 3;
+	}
+    }
+  else if (! std::abs (sigma))
+    typ = "SM";
+  else
+    {
+      typ = "LM";
+      mode = 3;
+    }
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+ 
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  octave_idx_type lwork = p * (p + 8);
+
+  OCTAVE_LOCAL_BUFFER (double, v, n * p);
+  OCTAVE_LOCAL_BUFFER (double, workl, lwork);
+  OCTAVE_LOCAL_BUFFER (double, workd, 3 * n);
+  double *presid = resid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (dsaupd, DSAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in dsaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  double *ip2 = workd + iptr(0) - 1;
+	  ColumnVector x(n);
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    x(i) = *ip2++;
+
+	  ColumnVector y = fun (x, err);
+
+	  if (err)
+	    return false;
+
+	  ip2 = workd + iptr(1) - 1;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    *ip2++ = y(i);
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+			
+  eig_vec.resize (n, k);
+  double *z = eig_vec.fortran_vec ();
+
+  eig_val.resize (k);
+  double *d = eig_val.fortran_vec ();
+
+  F77_FUNC (dseupd, DSEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, d, z, n, sigma, 
+     F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2),
+     k, tol, presid, p, v, n, iparam, ipntr, workd, workl, lwork, info2
+     F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: unrecoverable exception encountered in dseupd");
+      return -1;
+    }
+  else
+    {
+      if (info2 == 0)
+	{
+	  octave_idx_type k2 = k / 2;
+	  if (typ != "SM" && typ != "BE")
+	    {
+	      for (octave_idx_type i = 0; i < k2; i++)
+		{
+		  double dtmp = d[i];
+		  d[i] = d[k - i - 1];
+		  d[k - i - 1] = dtmp;
+		}
+	    }
+
+	  if (rvec)
+	    {
+	      if (typ != "SM" && typ != "BE")
+		{
+		  OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+		  for (octave_idx_type i = 0; i < k2; i++)
+		    {
+		      octave_idx_type off1 = i * n;
+		      octave_idx_type off2 = (k - i - 1) * n;
+
+		      if (off1 == off2)
+			continue;
+
+		      for (octave_idx_type j = 0; j < n; j++)
+			dtmp[j] = z[off1 + j];
+
+		      for (octave_idx_type j = 0; j < n; j++)
+			z[off1 + j] = z[off2 + j];
+
+		      for (octave_idx_type j = 0; j < n; j++)
+			z[off2 + j] = dtmp[j];
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("eigs: error %d in dseupd", info2);
+	  return -1;
+	}
+    }
+
+  return ip(4);
+}
+
+template <class M>
+octave_idx_type
+EigsRealNonSymmetricMatrix (const M& m, const std::string typ, 
+			    octave_idx_type k, octave_idx_type p,
+			    octave_idx_type &info, ComplexMatrix &eig_vec,
+			    ComplexColumnVector &eig_val, const M& _b,
+			    ColumnVector &permB, ColumnVector &resid, 
+			    std::ostream& os, double tol, int rvec, 
+			    bool cholB, int disp, int maxit)
+{
+  M b(_b);
+  octave_idx_type n = m.cols ();
+  octave_idx_type mode = 1;
+  bool have_b = ! b.is_empty();
+  bool note3 = false;
+  char bmat = 'I';
+  double sigmar = 0.;
+  double sigmai = 0.;
+  M bt;
+
+  if (m.rows() != m.cols())
+    {
+      (*current_liboctave_error_handler) ("eigs: A must be square");
+      return -1;
+    }
+  if (have_b && (m.rows() != b.rows() || m.rows() != b.cols()))
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: B must be square and the same size as A");
+      return -1;
+    }
+
+  if (resid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      resid = ColumnVector (octave_rand::vector(n));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2 + 1;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	 "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (have_b && cholB && permB.length() != 0) 
+    {
+      // Check the we really have a permutation vector
+      if (permB.length() != n)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: permB vector invalid");
+	  return -1;
+	}
+      else
+	{
+	  Array<bool> checked(n,false);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      octave_idx_type bidx = 
+		static_cast<octave_idx_type> (permB(i));
+	      if (checked(bidx) || bidx < 0 ||
+		  bidx >= n || D_NINT (bidx) != bidx)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("eigs: permB vector invalid");
+		  return -1;
+		}
+	    }
+	}
+    }
+
+  if (typ != "LM" && typ != "SM" && typ != "LA" && typ != "SA" && 
+      typ != "BE" && typ != "LR" && typ != "SR" && typ != "LI" &&
+      typ != "SI")
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecognized sigma value");
+      return -1;
+    }
+  
+  if (typ == "LA" || typ == "SA" || typ == "BE")
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: invalid sigma value for unsymmetric problem");
+      return -1;
+    }
+
+  if (have_b)
+    {
+      // See Note 3 dsaupd
+      note3 = true;
+      if (cholB)
+	{
+	  bt = b;
+	  b = b.transpose();
+	  if (permB.length() == 0)
+	    {
+	      permB = ColumnVector(n);
+	      for (octave_idx_type i = 0; i < n; i++)
+		permB(i) = i;
+	    }
+	}
+      else
+	{
+	  if (! make_cholb(b, bt, permB))
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: The matrix B is not positive definite");
+	      return -1;
+	    }
+	}
+    }
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+ 
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  octave_idx_type lwork = 3 * p * (p + 2);
+
+  OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1));
+  OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1);
+  OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1);
+  double *presid = resid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (dnaupd, DNAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in dnaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  if (have_b)
+	    {
+	      Matrix mtmp (n,1);
+	      for (octave_idx_type i = 0; i < n; i++)
+		mtmp(i,0) = workd[i + iptr(0) - 1];
+	      
+	      mtmp = utsolve(bt, permB, m * ltsolve(b, permB, mtmp));
+
+	      for (octave_idx_type i = 0; i < n; i++)
+		workd[i+iptr(1)-1] = mtmp(i,0);
+	    }
+	  else if (!vector_product (m, workd + iptr(0) - 1, 
+				    workd + iptr(1) - 1))
+	    break;
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dnaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+
+  Matrix eig_vec2 (n, k + 1);
+  double *z = eig_vec2.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (double, dr, k + 1);
+  OCTAVE_LOCAL_BUFFER (double, di, k + 1);
+  OCTAVE_LOCAL_BUFFER (double, workev, 3 * p);
+  for (octave_idx_type i = 0; i < k+1; i++)
+    dr[i] = di[i] = 0.;
+
+  F77_FUNC (dneupd, DNEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, dr, di, z, n, sigmar, 
+     sigmai, workev,  F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2), k, tol, presid, p, v, n, iparam,
+     ipntr, workd, workl, lwork, info2 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) 
+     F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: unrecoverable exception encountered in dneupd");
+      return -1;
+    }
+  else
+    {
+      eig_val.resize (k+1);
+      Complex *d = eig_val.fortran_vec ();
+
+      if (info2 == 0)
+	{
+	  octave_idx_type jj = 0;
+	  for (octave_idx_type i = 0; i < k+1; i++)
+	    {
+	      if (dr[i] == 0.0 && di[i] == 0.0 && jj == 0)
+		jj++;
+	      else
+		d [i-jj] = Complex (dr[i], di[i]);
+	    }
+	  if (jj == 0 && !rvec)
+	    for (octave_idx_type i = 0; i < k; i++)
+	      d[i] = d[i+1];
+
+	  octave_idx_type k2 = k / 2;
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      Complex dtmp = d[i];
+	      d[i] = d[k - i - 1];
+	      d[k - i - 1] = dtmp;
+	    }
+	  eig_val.resize(k);
+
+	  if (rvec)
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+	      for (octave_idx_type i = 0; i < k2; i++)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (k - i - 1) * n;
+
+		  if (off1 == off2)
+		    continue;
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    dtmp[j] = z[off1 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off1 + j] = z[off2 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off2 + j] = dtmp[j];
+		}
+
+	      eig_vec.resize (n, k);
+	      octave_idx_type i = 0;
+	      while (i < k)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (i+1) * n;
+		  if (std::imag(eig_val(i)) == 0)
+		    {
+		      for (octave_idx_type j = 0; j < n; j++)
+			eig_vec(j,i) = 
+			  Complex(z[j+off1],0.);
+		      i++;
+		    }
+		  else
+		    {
+		      for (octave_idx_type j = 0; j < n; j++)
+			{
+			  eig_vec(j,i) = 
+			    Complex(z[j+off1],z[j+off2]);
+			  if (i < k - 1)
+			    eig_vec(j,i+1) = 
+			      Complex(z[j+off1],-z[j+off2]);
+			}
+		      i+=2;
+		    }
+		}
+
+	      if (note3)
+		eig_vec = ltsolve(M (b), permB, eig_vec);
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: error %d in dneupd", info2);
+	  return -1;
+	}
+    }
+
+  return ip(4);
+}
+
+template <class M>
+octave_idx_type
+EigsRealNonSymmetricMatrixShift (const M& m, double sigmar,
+				 octave_idx_type k, octave_idx_type p, 
+				 octave_idx_type &info, 
+				 ComplexMatrix &eig_vec, 
+				 ComplexColumnVector &eig_val, const M& _b,
+				 ColumnVector &permB, ColumnVector &resid, 
+				 std::ostream& os, double tol, int rvec, 
+				 bool cholB, int disp, int maxit)
+{
+  M b(_b);
+  octave_idx_type n = m.cols ();
+  octave_idx_type mode = 3;
+  bool have_b = ! b.is_empty();
+  std::string typ = "LM";
+  double sigmai = 0.;
+
+  if (m.rows() != m.cols())
+    {
+      (*current_liboctave_error_handler) ("eigs: A must be square");
+      return -1;
+    }
+  if (have_b && (m.rows() != b.rows() || m.rows() != b.cols()))
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: B must be square and the same size as A");
+      return -1;
+    }
+
+  // FIXME: The "SM" type for mode 1 seems unstable though faster!!
+  //if (! std::abs (sigmar))
+  //  return EigsRealNonSymmetricMatrix (m, "SM", k, p, info, eig_vec, eig_val,
+  //				       _b, permB, resid, os, tol, rvec, cholB,
+  //				       disp, maxit);
+
+  if (resid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      resid = ColumnVector (octave_rand::vector(n));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2 + 1;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	     "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (have_b && cholB && permB.length() != 0) 
+    {
+      // Check that we really have a permutation vector
+      if (permB.length() != n)
+	{
+	  (*current_liboctave_error_handler) ("eigs: permB vector invalid");
+	  return -1;
+	}
+      else
+	{
+	  Array<bool> checked(n,false);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      octave_idx_type bidx = 
+		static_cast<octave_idx_type> (permB(i));
+	      if (checked(bidx) || bidx < 0 ||
+		  bidx >= n || D_NINT (bidx) != bidx)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("eigs: permB vector invalid");
+		  return -1;
+		}
+	    }
+	}
+    }
+
+  char bmat = 'I';
+  if (have_b)
+    bmat = 'G';
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  M L, U;
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, P, (have_b ? b.rows() : m.rows()));
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Q, (have_b ? b.cols() : m.cols()));
+
+  if (! LuAminusSigmaB(m, b, cholB, permB, sigmar, L, U, P, Q))
+    return -1;
+
+  octave_idx_type lwork = 3 * p * (p + 2);
+
+  OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1));
+  OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1);
+  OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1);
+  double *presid = resid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (dnaupd, DNAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in dsaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  if (have_b)
+	    {
+	      if (ido == -1)
+		{
+		  OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+		  vector_product (m, workd+iptr(0)-1, dtmp);
+
+		  Matrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = dtmp[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  double *ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	      else if (ido == 2)
+		vector_product (b, workd+iptr(0)-1, workd+iptr(1)-1);
+	      else
+		{
+		  double *ip2 = workd+iptr(2)-1;
+		  Matrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ip2[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	    }
+	  else
+	    {
+	      if (ido == 2)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    workd[iptr(0) + i - 1] = workd[iptr(1) + i - 1];
+		}
+	      else
+		{
+		  double *ip2 = workd+iptr(0)-1;
+		  Matrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ip2[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	    }
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+			
+  Matrix eig_vec2 (n, k + 1);
+  double *z = eig_vec2.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (double, dr, k + 1);
+  OCTAVE_LOCAL_BUFFER (double, di, k + 1);
+  OCTAVE_LOCAL_BUFFER (double, workev, 3 * p);
+  for (octave_idx_type i = 0; i < k+1; i++)
+    dr[i] = di[i] = 0.;
+
+  F77_FUNC (dneupd, DNEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, dr, di, z, n, sigmar, 
+     sigmai, workev,  F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2), k, tol, presid, p, v, n, iparam,
+     ipntr, workd, workl, lwork, info2 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) 
+     F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: unrecoverable exception encountered in dneupd");
+      return -1;
+    }
+  else
+    {
+      eig_val.resize (k+1);
+      Complex *d = eig_val.fortran_vec ();
+
+      if (info2 == 0)
+	{
+	  octave_idx_type jj = 0;
+	  for (octave_idx_type i = 0; i < k+1; i++)
+	    {
+	      if (dr[i] == 0.0 && di[i] == 0.0 && jj == 0)
+		jj++;
+	      else
+		d [i-jj] = Complex (dr[i], di[i]);
+	    }
+	  if (jj == 0 && !rvec)
+	    for (octave_idx_type i = 0; i < k; i++)
+	      d[i] = d[i+1];
+
+	  octave_idx_type k2 = k / 2;
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      Complex dtmp = d[i];
+	      d[i] = d[k - i - 1];
+	      d[k - i - 1] = dtmp;
+	    }
+	  eig_val.resize(k);
+
+	  if (rvec)
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+	      for (octave_idx_type i = 0; i < k2; i++)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (k - i - 1) * n;
+
+		  if (off1 == off2)
+		    continue;
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    dtmp[j] = z[off1 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off1 + j] = z[off2 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off2 + j] = dtmp[j];
+		}
+
+	      eig_vec.resize (n, k);
+	      octave_idx_type i = 0;
+	      while (i < k)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (i+1) * n;
+		  if (std::imag(eig_val(i)) == 0)
+		    {
+		      for (octave_idx_type j = 0; j < n; j++)
+			eig_vec(j,i) = 
+			  Complex(z[j+off1],0.);
+		      i++;
+		    }
+		  else
+		    {
+		      for (octave_idx_type j = 0; j < n; j++)
+			{
+			  eig_vec(j,i) = 
+			    Complex(z[j+off1],z[j+off2]);
+			  if (i < k - 1)
+			    eig_vec(j,i+1) = 
+			      Complex(z[j+off1],-z[j+off2]);
+			}
+		      i+=2;
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: error %d in dneupd", info2);
+	  return -1;
+	}
+    }
+
+  return ip(4);
+}
+
+octave_idx_type
+EigsRealNonSymmetricFunc (EigsFunc fun, octave_idx_type n,
+			  const std::string &_typ, double sigmar,
+			  octave_idx_type k, octave_idx_type p, 
+			  octave_idx_type &info, ComplexMatrix &eig_vec, 
+			  ComplexColumnVector &eig_val, ColumnVector &resid, 
+			  std::ostream& os, double tol, int rvec,
+			  bool /* cholB */, int disp, int maxit)
+{
+  std::string typ (_typ);
+  bool have_sigma = (sigmar ? true : false);
+  char bmat = 'I';
+  double sigmai = 0.;
+  octave_idx_type mode = 1;
+  int err = 0;
+
+  if (resid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      resid = ColumnVector (octave_rand::vector(n));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2 + 1;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	     "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+
+  if (! have_sigma)
+    {
+      if (typ != "LM" && typ != "SM" && typ != "LA" && typ != "SA" && 
+	  typ != "BE" && typ != "LR" && typ != "SR" && typ != "LI" &&
+	  typ != "SI")
+	(*current_liboctave_error_handler) 
+	  ("eigs: unrecognized sigma value");
+
+      if (typ == "LA" || typ == "SA" || typ == "BE")
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: invalid sigma value for unsymmetric problem");
+	  return -1;
+	}
+
+      if (typ == "SM")
+	{
+	  typ = "LM";
+	  sigmar = 0.;
+	  mode = 3;
+	}
+    }
+  else if (! std::abs (sigmar))
+    typ = "SM";
+  else
+    {
+      typ = "LM";
+      mode = 3;
+    }
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+ 
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  octave_idx_type lwork = 3 * p * (p + 2);
+
+  OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1));
+  OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1);
+  OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1);
+  double *presid = resid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (dnaupd, DNAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in dnaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  double *ip2 = workd + iptr(0) - 1;
+	  ColumnVector x(n);
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    x(i) = *ip2++;
+
+	  ColumnVector y = fun (x, err);
+
+	  if (err)
+	    return false;
+
+	  ip2 = workd + iptr(1) - 1;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    *ip2++ = y(i);
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+
+  Matrix eig_vec2 (n, k + 1);
+  double *z = eig_vec2.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (double, dr, k + 1);
+  OCTAVE_LOCAL_BUFFER (double, di, k + 1);
+  OCTAVE_LOCAL_BUFFER (double, workev, 3 * p);
+  for (octave_idx_type i = 0; i < k+1; i++)
+    dr[i] = di[i] = 0.;
+
+  F77_FUNC (dneupd, DNEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, dr, di, z, n, sigmar, 
+     sigmai, workev,  F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2), k, tol, presid, p, v, n, iparam,
+     ipntr, workd, workl, lwork, info2 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) 
+     F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: unrecoverable exception encountered in dneupd");
+      return -1;
+    }
+  else
+    {
+      eig_val.resize (k+1);
+      Complex *d = eig_val.fortran_vec ();
+
+      if (info2 == 0)
+	{
+	  octave_idx_type jj = 0;
+	  for (octave_idx_type i = 0; i < k+1; i++)
+	    {
+	      if (dr[i] == 0.0 && di[i] == 0.0 && jj == 0)
+		jj++;
+	      else
+		d [i-jj] = Complex (dr[i], di[i]);
+	    }
+	  if (jj == 0 && !rvec)
+	    for (octave_idx_type i = 0; i < k; i++)
+	      d[i] = d[i+1];
+
+	  octave_idx_type k2 = k / 2;
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      Complex dtmp = d[i];
+	      d[i] = d[k - i - 1];
+	      d[k - i - 1] = dtmp;
+	    }
+	  eig_val.resize(k);
+
+	  if (rvec)
+	    {
+	      OCTAVE_LOCAL_BUFFER (double, dtmp, n);
+
+	      for (octave_idx_type i = 0; i < k2; i++)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (k - i - 1) * n;
+
+		  if (off1 == off2)
+		    continue;
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    dtmp[j] = z[off1 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off1 + j] = z[off2 + j];
+
+		  for (octave_idx_type j = 0; j < n; j++)
+		    z[off2 + j] = dtmp[j];
+		}
+
+	      eig_vec.resize (n, k);
+	      octave_idx_type i = 0;
+	      while (i < k)
+		{
+		  octave_idx_type off1 = i * n;
+		  octave_idx_type off2 = (i+1) * n;
+		  if (std::imag(eig_val(i)) == 0)
+		    {
+		      for (octave_idx_type j = 0; j < n; j++)
+			eig_vec(j,i) = 
+			  Complex(z[j+off1],0.);
+		      i++;
+		    }
+		  else
+		    {
+		      for (octave_idx_type j = 0; j < n; j++)
+			{
+			  eig_vec(j,i) = 
+			    Complex(z[j+off1],z[j+off2]);
+			  if (i < k - 1)
+			    eig_vec(j,i+1) = 
+			      Complex(z[j+off1],-z[j+off2]);
+			}
+		      i+=2;
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: error %d in dneupd", info2);
+	  return -1;
+	}
+    }
+
+  return ip(4);
+}
+
+template <class M>
+octave_idx_type
+EigsComplexNonSymmetricMatrix (const M& m, const std::string typ, 
+			       octave_idx_type k, octave_idx_type p,
+			       octave_idx_type &info, ComplexMatrix &eig_vec,
+			       ComplexColumnVector &eig_val, const M& _b,
+			       ColumnVector &permB, 
+			       ComplexColumnVector &cresid, 
+			       std::ostream& os, double tol, int rvec, 
+			       bool cholB, int disp, int maxit)
+{
+  M b(_b);
+  octave_idx_type n = m.cols ();
+  octave_idx_type mode = 1;
+  bool have_b = ! b.is_empty();
+  bool note3 = false;
+  char bmat = 'I';
+  Complex sigma = 0.;
+  M bt;
+
+  if (m.rows() != m.cols())
+    {
+      (*current_liboctave_error_handler) ("eigs: A must be square");
+      return -1;
+    }
+  if (have_b && (m.rows() != b.rows() || m.rows() != b.cols()))
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: B must be square and the same size as A");
+      return -1;
+    }
+
+  if (cresid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      Array<double> rr (octave_rand::vector(n));
+      Array<double> ri (octave_rand::vector(n));
+      cresid = ComplexColumnVector (n);
+      for (octave_idx_type i = 0; i < n; i++)
+	cresid(i) = Complex(rr(i),ri(i));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2 + 1;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	 "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (have_b && cholB && permB.length() != 0) 
+    {
+      // Check the we really have a permutation vector
+      if (permB.length() != n)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: permB vector invalid");
+	  return -1;
+	}
+      else
+	{
+	  Array<bool> checked(n,false);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      octave_idx_type bidx = 
+		static_cast<octave_idx_type> (permB(i));
+	      if (checked(bidx) || bidx < 0 ||
+		  bidx >= n || D_NINT (bidx) != bidx)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("eigs: permB vector invalid");
+		  return -1;
+		}
+	    }
+	}
+    }
+
+  if (typ != "LM" && typ != "SM" && typ != "LA" && typ != "SA" && 
+      typ != "BE" && typ != "LR" && typ != "SR" && typ != "LI" &&
+      typ != "SI")
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecognized sigma value");
+      return -1;
+    }
+  
+  if (typ == "LA" || typ == "SA" || typ == "BE")
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: invalid sigma value for complex problem");
+      return -1;
+    }
+
+  if (have_b)
+    {
+      // See Note 3 dsaupd
+      note3 = true;
+      if (cholB)
+	{
+	  bt = b;
+	  b = b.hermitian();
+	  if (permB.length() == 0)
+	    {
+	      permB = ColumnVector(n);
+	      for (octave_idx_type i = 0; i < n; i++)
+		permB(i) = i;
+	    }
+	}
+      else
+	{
+	  if (! make_cholb(b, bt, permB))
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: The matrix B is not positive definite");
+	      return -1;
+	    }
+	}
+    }
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+ 
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  octave_idx_type lwork = p * (3 * p + 5);
+	      
+  OCTAVE_LOCAL_BUFFER (Complex, v, n * p);
+  OCTAVE_LOCAL_BUFFER (Complex, workl, lwork);
+  OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n);
+  OCTAVE_LOCAL_BUFFER (double, rwork, p);
+  Complex *presid = cresid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (znaupd, ZNAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, rwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in znaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+			  
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  if (have_b)
+	    {
+	      ComplexMatrix mtmp (n,1);
+	      for (octave_idx_type i = 0; i < n; i++)
+		mtmp(i,0) = workd[i + iptr(0) - 1];
+	      mtmp = utsolve(bt, permB, m * ltsolve(b, permB, mtmp));
+	      for (octave_idx_type i = 0; i < n; i++)
+		workd[i+iptr(1)-1] = mtmp(i,0);
+
+	    }
+	  else if (!vector_product (m, workd + iptr(0) - 1, 
+				    workd + iptr(1) - 1))
+	    break;
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in znaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+
+  eig_vec.resize (n, k);
+  Complex *z = eig_vec.fortran_vec ();
+
+  eig_val.resize (k+1);
+  Complex *d = eig_val.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, workev, 2 * p);
+
+  F77_FUNC (zneupd, ZNEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, d, z, n, sigma, workev,
+     F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2),
+     k, tol, presid, p, v, n, iparam, ipntr, workd, workl, lwork, rwork, info2
+     F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecoverable exception encountered in zneupd");
+      return -1;
+    }
+
+  if (info2 == 0)
+    {
+      octave_idx_type k2 = k / 2;
+      for (octave_idx_type i = 0; i < k2; i++)
+	{
+	  Complex ctmp = d[i];
+	  d[i] = d[k - i - 1];
+	  d[k - i - 1] = ctmp;
+	}
+      eig_val.resize(k);
+
+      if (rvec)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, ctmp, n);
+
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      octave_idx_type off1 = i * n;
+	      octave_idx_type off2 = (k - i - 1) * n;
+
+	      if (off1 == off2)
+		continue;
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		ctmp[j] = z[off1 + j];
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		z[off1 + j] = z[off2 + j];
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		z[off2 + j] = ctmp[j];
+	    }
+
+	  if (note3)
+	    eig_vec = ltsolve(b, permB, eig_vec);
+	}
+    }
+  else
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: error %d in zneupd", info2);
+      return -1;
+    }
+
+  return ip(4);
+}
+
+template <class M>
+octave_idx_type
+EigsComplexNonSymmetricMatrixShift (const M& m, Complex sigma,
+				    octave_idx_type k, octave_idx_type p, 
+				    octave_idx_type &info, 
+				    ComplexMatrix &eig_vec, 
+				    ComplexColumnVector &eig_val, const M& _b,
+				    ColumnVector &permB, 
+				    ComplexColumnVector &cresid, 
+				    std::ostream& os, double tol, int rvec, 
+				    bool cholB, int disp, int maxit)
+{
+  M b(_b);
+  octave_idx_type n = m.cols ();
+  octave_idx_type mode = 3;
+  bool have_b = ! b.is_empty();
+  std::string typ = "LM";
+
+  if (m.rows() != m.cols())
+    {
+      (*current_liboctave_error_handler) ("eigs: A must be square");
+      return -1;
+    }
+  if (have_b && (m.rows() != b.rows() || m.rows() != b.cols()))
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: B must be square and the same size as A");
+      return -1;
+    }
+
+  // FIXME: The "SM" type for mode 1 seems unstable though faster!!
+  //if (! std::abs (sigma))
+  //  return EigsComplexNonSymmetricMatrix (m, "SM", k, p, info, eig_vec,
+  //					  eig_val, _b, permB, cresid, os, tol,
+  //					  rvec, cholB, disp, maxit);
+
+  if (cresid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      Array<double> rr (octave_rand::vector(n));
+      Array<double> ri (octave_rand::vector(n));
+      cresid = ComplexColumnVector (n);
+      for (octave_idx_type i = 0; i < n; i++)
+	cresid(i) = Complex(rr(i),ri(i));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2 + 1;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	     "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (have_b && cholB && permB.length() != 0) 
+    {
+      // Check that we really have a permutation vector
+      if (permB.length() != n)
+	{
+	  (*current_liboctave_error_handler) ("eigs: permB vector invalid");
+	  return -1;
+	}
+      else
+	{
+	  Array<bool> checked(n,false);
+	  for (octave_idx_type i = 0; i < n; i++)
+	    {
+	      octave_idx_type bidx = 
+		static_cast<octave_idx_type> (permB(i));
+	      if (checked(bidx) || bidx < 0 ||
+		  bidx >= n || D_NINT (bidx) != bidx)
+		{
+		  (*current_liboctave_error_handler) 
+		    ("eigs: permB vector invalid");
+		  return -1;
+		}
+	    }
+	}
+    }
+
+  char bmat = 'I';
+  if (have_b)
+    bmat = 'G';
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  M L, U;
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, P, (have_b ? b.rows() : m.rows()));
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Q, (have_b ? b.cols() : m.cols()));
+
+  if (! LuAminusSigmaB(m, b, cholB, permB, sigma, L, U, P, Q))
+    return -1;
+
+  octave_idx_type lwork = p * (3 * p + 5);
+	      
+  OCTAVE_LOCAL_BUFFER (Complex, v, n * p);
+  OCTAVE_LOCAL_BUFFER (Complex, workl, lwork);
+  OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n);
+  OCTAVE_LOCAL_BUFFER (double, rwork, p);
+  Complex *presid = cresid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (znaupd, ZNAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, rwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in znaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+			  
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  if (have_b)
+	    {
+	      if (ido == -1)
+		{
+		  OCTAVE_LOCAL_BUFFER (Complex, ctmp, n);
+
+		  vector_product (m, workd+iptr(0)-1, ctmp);
+
+		  ComplexMatrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ctmp[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  Complex *ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	      else if (ido == 2)
+		vector_product (b, workd + iptr(0) - 1, workd + iptr(1) - 1);
+	      else
+		{
+		  Complex *ip2 = workd+iptr(2)-1;
+		  ComplexMatrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ip2[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	    }
+	  else
+	    {
+	      if (ido == 2)
+		{
+		  for (octave_idx_type i = 0; i < n; i++)
+		    workd[iptr(0) + i - 1] =
+		      workd[iptr(1) + i - 1];
+		}
+	      else
+		{
+		  Complex *ip2 = workd+iptr(0)-1;
+		  ComplexMatrix tmp(n, 1);
+
+		  for (octave_idx_type i = 0; i < n; i++)
+		    tmp(i,0) = ip2[P[i]];
+				  
+		  lusolve (L, U, tmp);
+
+		  ip2 = workd+iptr(1)-1;
+		  for (octave_idx_type i = 0; i < n; i++)
+		    ip2[Q[i]] = tmp(i,0);
+		}
+	    }
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+
+  eig_vec.resize (n, k);
+  Complex *z = eig_vec.fortran_vec ();
+
+  eig_val.resize (k+1);
+  Complex *d = eig_val.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, workev, 2 * p);
+
+  F77_FUNC (zneupd, ZNEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, d, z, n, sigma, workev,
+     F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2),
+     k, tol, presid, p, v, n, iparam, ipntr, workd, workl, lwork, rwork, info2
+     F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecoverable exception encountered in zneupd");
+      return -1;
+    }
+
+  if (info2 == 0)
+    {
+      octave_idx_type k2 = k / 2;
+      for (octave_idx_type i = 0; i < k2; i++)
+	{
+	  Complex ctmp = d[i];
+	  d[i] = d[k - i - 1];
+	  d[k - i - 1] = ctmp;
+	}
+      eig_val.resize(k);
+
+      if (rvec)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, ctmp, n);
+
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      octave_idx_type off1 = i * n;
+	      octave_idx_type off2 = (k - i - 1) * n;
+
+	      if (off1 == off2)
+		continue;
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		ctmp[j] = z[off1 + j];
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		z[off1 + j] = z[off2 + j];
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		z[off2 + j] = ctmp[j];
+	    }
+	}
+    }
+  else
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: error %d in zneupd", info2);
+      return -1;
+    }
+
+  return ip(4);
+}
+
+octave_idx_type
+EigsComplexNonSymmetricFunc (EigsComplexFunc fun, octave_idx_type n,
+			     const std::string &_typ, Complex sigma,
+			     octave_idx_type k, octave_idx_type p, 
+			     octave_idx_type &info, ComplexMatrix &eig_vec, 
+			     ComplexColumnVector &eig_val, 
+			     ComplexColumnVector &cresid, std::ostream& os, 
+			     double tol, int rvec, bool /* cholB */,
+			     int disp, int maxit)
+{
+  std::string typ (_typ);
+  bool have_sigma = (std::abs(sigma) ? true : false);
+  char bmat = 'I';
+  octave_idx_type mode = 1;
+  int err = 0;
+
+  if (cresid.is_empty())
+    {
+      std::string rand_dist = octave_rand::distribution();
+      octave_rand::distribution("uniform");
+      Array<double> rr (octave_rand::vector(n));
+      Array<double> ri (octave_rand::vector(n));
+      cresid = ComplexColumnVector (n);
+      for (octave_idx_type i = 0; i < n; i++)
+	cresid(i) = Complex(rr(i),ri(i));
+      octave_rand::distribution(rand_dist);
+    }
+
+  if (n < 3)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: n must be at least 3");
+      return -1;
+    }
+
+  if (p < 0)
+    {
+      p = k * 2 + 1;
+
+      if (p < 20)
+	p = 20;
+      
+      if (p > n - 1)
+	p = n - 1 ;
+    }
+
+  if (k <= 0 || k >= n - 1)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: Invalid number of eigenvalues to extract (must be 0 < k < n-1).\n"
+	     "      Use 'eig(full(A))' instead");
+      return -1;
+    }
+
+  if (p <= k || p >= n)
+    {
+      (*current_liboctave_error_handler)
+	("eigs: opts.p must be greater than k and less than n");
+      return -1;
+    }
+
+  if (! have_sigma)
+    {
+      if (typ != "LM" && typ != "SM" && typ != "LA" && typ != "SA" && 
+	  typ != "BE" && typ != "LR" && typ != "SR" && typ != "LI" &&
+	  typ != "SI")
+	(*current_liboctave_error_handler) 
+	  ("eigs: unrecognized sigma value");
+
+      if (typ == "LA" || typ == "SA" || typ == "BE")
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: invalid sigma value for complex problem");
+	  return -1;
+	}
+
+      if (typ == "SM")
+	{
+	  typ = "LM";
+	  sigma = 0.;
+	  mode = 3;
+	}
+    }
+  else if (! std::abs (sigma))
+    typ = "SM";
+  else
+    {
+      typ = "LM";
+      mode = 3;
+    }
+
+  Array<octave_idx_type> ip (11);
+  octave_idx_type *iparam = ip.fortran_vec ();
+
+  ip(0) = 1; //ishift
+  ip(1) = 0;   // ip(1) not referenced
+  ip(2) = maxit; // mxiter, maximum number of iterations
+  ip(3) = 1; // NB blocksize in recurrence
+  ip(4) = 0; // nconv, number of Ritz values that satisfy convergence
+  ip(5) = 0; //ip(5) not referenced
+  ip(6) = mode; // mode
+  ip(7) = 0;
+  ip(8) = 0;
+  ip(9) = 0;
+  ip(10) = 0;
+  // ip(7) to ip(10) return values
+ 
+  Array<octave_idx_type> iptr (14);
+  octave_idx_type *ipntr = iptr.fortran_vec ();
+
+  octave_idx_type ido = 0;
+  int iter = 0;
+  octave_idx_type lwork = p * (3 * p + 5);
+	      
+  OCTAVE_LOCAL_BUFFER (Complex, v, n * p);
+  OCTAVE_LOCAL_BUFFER (Complex, workl, lwork);
+  OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n);
+  OCTAVE_LOCAL_BUFFER (double, rwork, p);
+  Complex *presid = cresid.fortran_vec ();
+
+  do 
+    {
+      F77_FUNC (znaupd, ZNAUPD) 
+	(ido, F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+	 F77_CONST_CHAR_ARG2 ((typ.c_str()), 2),
+	 k, tol, presid, p, v, n, iparam,
+	 ipntr, workd, workl, lwork, rwork, info
+	 F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+      if (f77_exception_encountered)
+	{
+	  (*current_liboctave_error_handler) 
+	    ("eigs: unrecoverable exception encountered in znaupd");
+	  return -1;
+	}
+
+      if (disp > 0 && !xisnan(workl[iptr(5)-1]))
+	{
+	  if (iter++)
+	    {
+	      os << "Iteration " << iter - 1 << 
+		": a few Ritz values of the " << p << "-by-" <<
+		p << " matrix\n";
+	      for (int i = 0 ; i < k; i++)
+		os << "    " << workl[iptr(5)+i-1] << "\n";
+	    }
+			  
+	  // This is a kludge, as ARPACK doesn't give its
+	  // iteration pointer. But as workl[iptr(5)-1] is
+	  // an output value updated at each iteration, setting
+	  // a value in this array to NaN and testing for it
+	  // is a way of obtaining the iteration counter.
+	  if (ido != 99)
+	    workl[iptr(5)-1] = octave_NaN; 
+	}
+
+      if (ido == -1 || ido == 1 || ido == 2)
+	{
+	  Complex *ip2 = workd + iptr(0) - 1;
+	  ComplexColumnVector x(n);
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    x(i) = *ip2++;
+
+	  ComplexColumnVector y = fun (x, err);
+
+	  if (err)
+	    return false;
+
+	  ip2 = workd + iptr(1) - 1;
+	  for (octave_idx_type i = 0; i < n; i++)
+	    *ip2++ = y(i);
+	}
+      else
+	{
+	  if (info < 0)
+	    {
+	      (*current_liboctave_error_handler) 
+		("eigs: error %d in dsaupd", info);
+	      return -1;
+	    }
+	  break;
+	}
+    } 
+  while (1);
+
+  octave_idx_type info2;
+
+  // We have a problem in that the size of the C++ bool 
+  // type relative to the fortran logical type. It appears 
+  // that fortran uses 4- or 8-bytes per logical and C++ 1-byte 
+  // per bool, though this might be system dependent. As 
+  // long as the HOWMNY arg is not "S", the logical array
+  // is just workspace for ARPACK, so use int type to 
+  // avoid problems.
+  Array<octave_idx_type> s (p);
+  octave_idx_type *sel = s.fortran_vec ();
+
+  eig_vec.resize (n, k);
+  Complex *z = eig_vec.fortran_vec ();
+
+  eig_val.resize (k+1);
+  Complex *d = eig_val.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (Complex, workev, 2 * p);
+
+  F77_FUNC (zneupd, ZNEUPD) 
+    (rvec, F77_CONST_CHAR_ARG2 ("A", 1), sel, d, z, n, sigma, workev,
+     F77_CONST_CHAR_ARG2 (&bmat, 1), n,
+     F77_CONST_CHAR_ARG2 ((typ.c_str ()), 2),
+     k, tol, presid, p, v, n, iparam, ipntr, workd, workl, lwork, rwork, info2
+     F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(1) F77_CHAR_ARG_LEN(2));
+
+  if (f77_exception_encountered)
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: unrecoverable exception encountered in zneupd");
+      return -1;
+    }
+
+  if (info2 == 0)
+    {
+      octave_idx_type k2 = k / 2;
+      for (octave_idx_type i = 0; i < k2; i++)
+	{
+	  Complex ctmp = d[i];
+	  d[i] = d[k - i - 1];
+	  d[k - i - 1] = ctmp;
+	}
+      eig_val.resize(k);
+
+      if (rvec)
+	{
+	  OCTAVE_LOCAL_BUFFER (Complex, ctmp, n);
+
+	  for (octave_idx_type i = 0; i < k2; i++)
+	    {
+	      octave_idx_type off1 = i * n;
+	      octave_idx_type off2 = (k - i - 1) * n;
+
+	      if (off1 == off2)
+		continue;
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		ctmp[j] = z[off1 + j];
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		z[off1 + j] = z[off2 + j];
+
+	      for (octave_idx_type j = 0; j < n; j++)
+		z[off2 + j] = ctmp[j];
+	    }
+	}
+    }
+  else
+    {
+      (*current_liboctave_error_handler) 
+	("eigs: error %d in zneupd", info2);
+      return -1;
+    }
+
+  return ip(4);
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern octave_idx_type
+EigsRealSymmetricMatrix (const Matrix& m, const std::string typ, 
+			 octave_idx_type k, octave_idx_type p,
+			 octave_idx_type &info, Matrix &eig_vec,
+			 ColumnVector &eig_val, const Matrix& b,
+			 ColumnVector &permB, ColumnVector &resid, 
+			 std::ostream &os, double tol = DBL_EPSILON,
+			 int rvec = 0, bool cholB = 0, int disp = 0,
+			 int maxit = 300);
+
+extern octave_idx_type
+EigsRealSymmetricMatrix (const SparseMatrix& m, const std::string typ, 
+			 octave_idx_type k, octave_idx_type p,
+			 octave_idx_type &info, Matrix &eig_vec,
+			 ColumnVector &eig_val, const SparseMatrix& b,
+			 ColumnVector &permB, ColumnVector &resid, 
+			 std::ostream& os, double tol = DBL_EPSILON,
+			 int rvec = 0, bool cholB = 0, int disp = 0, 
+			 int maxit = 300);
+
+extern octave_idx_type
+EigsRealSymmetricMatrixShift (const Matrix& m, double sigma,
+			      octave_idx_type k, octave_idx_type p, 
+			      octave_idx_type &info, Matrix &eig_vec, 
+			      ColumnVector &eig_val, const Matrix& b,
+			      ColumnVector &permB, ColumnVector &resid, 
+			      std::ostream &os, double tol = DBL_EPSILON,
+			      int rvec = 0, bool cholB = 0, int disp = 0, 
+			      int maxit = 300);
+
+extern octave_idx_type
+EigsRealSymmetricMatrixShift (const SparseMatrix& m, double sigma,
+			      octave_idx_type k, octave_idx_type p, 
+			      octave_idx_type &info, Matrix &eig_vec, 
+			      ColumnVector &eig_val, const SparseMatrix& b,
+			      ColumnVector &permB, ColumnVector &resid, 
+			      std::ostream &os, double tol = DBL_EPSILON,
+			      int rvec = 0, bool cholB = 0, int disp = 0, 
+			      int maxit = 300);
+
+extern octave_idx_type
+EigsRealSymmetricFunc (EigsFunc fun, octave_idx_type n,
+		       const std::string &typ, double sigma,
+		       octave_idx_type k, octave_idx_type p, 
+		       octave_idx_type &info,
+		       Matrix &eig_vec, ColumnVector &eig_val, 
+		       ColumnVector &resid, std::ostream &os,
+		       double tol = DBL_EPSILON, int rvec = 0,
+		       bool cholB = 0, int disp = 0, int maxit = 300);
+
+extern octave_idx_type
+EigsRealNonSymmetricMatrix (const Matrix& m, const std::string typ, 
+			    octave_idx_type k, octave_idx_type p,
+			    octave_idx_type &info, ComplexMatrix &eig_vec,
+			    ComplexColumnVector &eig_val, const Matrix& b,
+			    ColumnVector &permB, ColumnVector &resid, 
+			    std::ostream &os, double tol = DBL_EPSILON,
+			    int rvec = 0, bool cholB = 0, int disp = 0,
+			    int maxit = 300);
+
+extern octave_idx_type
+EigsRealNonSymmetricMatrix (const SparseMatrix& m, const std::string typ, 
+			    octave_idx_type k, octave_idx_type p,
+			    octave_idx_type &info, ComplexMatrix &eig_vec,
+			    ComplexColumnVector &eig_val, 
+			    const SparseMatrix& b,
+			    ColumnVector &permB, ColumnVector &resid, 
+			    std::ostream &os, double tol = DBL_EPSILON,
+			    int rvec = 0, bool cholB = 0, int disp = 0,
+			    int maxit = 300);
+
+extern octave_idx_type
+EigsRealNonSymmetricMatrixShift (const Matrix& m, double sigma,
+				 octave_idx_type k, octave_idx_type p, 
+				 octave_idx_type &info,
+				 ComplexMatrix &eig_vec, 
+				 ComplexColumnVector &eig_val, const Matrix& b,
+				 ColumnVector &permB, ColumnVector &resid, 
+				 std::ostream &os, double tol = DBL_EPSILON,
+				 int rvec = 0, bool cholB = 0, int disp = 0, 
+				 int maxit = 300);
+
+extern octave_idx_type
+EigsRealNonSymmetricMatrixShift (const SparseMatrix& m, double sigma,
+				 octave_idx_type k, octave_idx_type p, 
+				 octave_idx_type &info,
+				 ComplexMatrix &eig_vec, 
+				 ComplexColumnVector &eig_val, 
+				 const SparseMatrix& b,
+				 ColumnVector &permB, ColumnVector &resid, 
+				 std::ostream &os, double tol = DBL_EPSILON,
+				 int rvec = 0, bool cholB = 0, int disp = 0, 
+				 int maxit = 300);
+
+extern octave_idx_type
+EigsRealNonSymmetricFunc (EigsFunc fun, octave_idx_type n,
+			  const std::string &_typ, double sigma,
+			  octave_idx_type k, octave_idx_type p, 
+			  octave_idx_type &info, ComplexMatrix &eig_vec, 
+			  ComplexColumnVector &eig_val, 
+			  ColumnVector &resid, std::ostream& os, 
+			  double tol = DBL_EPSILON, int rvec = 0,
+			  bool cholB = 0, int disp = 0, int maxit = 300);
+
+extern octave_idx_type
+EigsComplexNonSymmetricMatrix (const ComplexMatrix& m, const std::string typ, 
+			       octave_idx_type k, octave_idx_type p,
+			       octave_idx_type &info, ComplexMatrix &eig_vec,
+			       ComplexColumnVector &eig_val, 
+			       const ComplexMatrix& b, ColumnVector &permB, 
+			       ComplexColumnVector &resid, 
+			       std::ostream &os, double tol = DBL_EPSILON,
+			       int rvec = 0, bool cholB = 0, int disp = 0, 
+			       int maxit = 300);
+
+extern octave_idx_type
+EigsComplexNonSymmetricMatrix (const SparseComplexMatrix& m, 
+			       const std::string typ, octave_idx_type k, 
+			       octave_idx_type p, octave_idx_type &info, 
+			       ComplexMatrix &eig_vec,
+			       ComplexColumnVector &eig_val, 
+			       const SparseComplexMatrix& b,
+			       ColumnVector &permB,
+			       ComplexColumnVector &resid, 
+			       std::ostream &os, double tol = DBL_EPSILON,
+			       int rvec = 0, bool cholB = 0, int disp = 0, 
+			       int maxit = 300);
+
+extern octave_idx_type
+EigsComplexNonSymmetricMatrixShift (const ComplexMatrix& m, Complex sigma,
+				    octave_idx_type k, octave_idx_type p, 
+				    octave_idx_type &info, 
+				    ComplexMatrix &eig_vec, 
+				    ComplexColumnVector &eig_val,
+				    const ComplexMatrix& b,
+				    ColumnVector &permB,
+				    ComplexColumnVector &resid, 
+				    std::ostream &os, double tol = DBL_EPSILON,
+				    int rvec = 0, bool cholB = 0,
+				    int disp = 0, int maxit = 300);
+
+extern octave_idx_type
+EigsComplexNonSymmetricMatrixShift (const SparseComplexMatrix& m,
+				    Complex sigma,
+				    octave_idx_type k, octave_idx_type p, 
+				    octave_idx_type &info, 
+				    ComplexMatrix &eig_vec, 
+				    ComplexColumnVector &eig_val, 
+				    const SparseComplexMatrix& b,
+				    ColumnVector &permB,
+				    ComplexColumnVector &resid, 
+				    std::ostream &os, double tol = DBL_EPSILON,
+				    int rvec = 0, bool cholB = 0,
+				    int disp = 0, int maxit = 300);
+
+extern octave_idx_type
+EigsComplexNonSymmetricFunc (EigsComplexFunc fun, octave_idx_type n,
+			     const std::string &_typ, Complex sigma,
+			     octave_idx_type k, octave_idx_type p, 
+			     octave_idx_type &info, ComplexMatrix &eig_vec, 
+			     ComplexColumnVector &eig_val, 
+			     ComplexColumnVector &resid, std::ostream& os, 
+			     double tol = DBL_EPSILON, int rvec = 0,
+			     bool cholB = 0, int disp = 0, int maxit = 300);
+#endif
+
+#ifndef _MSC_VER
+template static octave_idx_type
+lusolve (const SparseMatrix&, const SparseMatrix&, Matrix&);
+
+template static octave_idx_type
+lusolve (const SparseComplexMatrix&, const SparseComplexMatrix&, 
+	 ComplexMatrix&);
+
+template static octave_idx_type
+lusolve (const Matrix&, const Matrix&, Matrix&);
+
+template static octave_idx_type
+lusolve (const ComplexMatrix&, const ComplexMatrix&, ComplexMatrix&);
+
+template static ComplexMatrix
+ltsolve (const SparseComplexMatrix&, const ColumnVector&, 
+	 const ComplexMatrix&);
+
+template static Matrix
+ltsolve (const SparseMatrix&, const ColumnVector&, const Matrix&);
+
+template static ComplexMatrix
+ltsolve (const ComplexMatrix&, const ColumnVector&, const ComplexMatrix&);
+
+template static Matrix
+ltsolve (const Matrix&, const ColumnVector&, const Matrix&);
+
+template static ComplexMatrix
+utsolve (const SparseComplexMatrix&, const ColumnVector&,
+	 const ComplexMatrix&);
+
+template static Matrix
+utsolve (const SparseMatrix&, const ColumnVector&, const Matrix&);
+
+template static ComplexMatrix
+utsolve (const ComplexMatrix&, const ColumnVector&, const ComplexMatrix&);
+
+template static Matrix
+utsolve (const Matrix&, const ColumnVector&, const Matrix&);
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/f2c-main.c b/liboctave/f2c-main.c
new file mode 100644
index 0000000..9d163c5
--- /dev/null
+++ b/liboctave/f2c-main.c
@@ -0,0 +1,42 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <assert.h>
+
+
+/* Dummy Fortran main declaration, needed in order to link to some
+   Fortran libraries.  See the AC_F77_DUMMY_MAIN macro documentation. 
+   This function should never be called. */
+
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+extern "C"
+#  endif
+int F77_DUMMY_MAIN() { assert(0); return 1; }
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/fCColVector.cc b/liboctave/fCColVector.cc
new file mode 100644
index 0000000..d61b005
--- /dev/null
+++ b/liboctave/fCColVector.cc
@@ -0,0 +1,546 @@
+// ColumnVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgemv, CGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const FloatComplex&,
+			   const FloatComplex*, const octave_idx_type&, const FloatComplex*,
+			   const octave_idx_type&, const FloatComplex&, FloatComplex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+}
+
+// FloatComplex Column Vector class
+
+FloatComplexColumnVector::FloatComplexColumnVector (const FloatColumnVector& a)
+   : MArray<FloatComplex> (a.length ())
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i) = a.elem (i);
+}
+
+bool
+FloatComplexColumnVector::operator == (const FloatComplexColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+FloatComplexColumnVector::operator != (const FloatComplexColumnVector& a) const
+{
+  return !(*this == a);
+}
+
+// destructive insert/delete/reorder operations
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::insert (const FloatColumnVector& a, octave_idx_type r)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::insert (const FloatComplexColumnVector& a, octave_idx_type r)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::fill (float val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::fill (const FloatComplex& val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+
+  return *this;
+}
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::fill (float val, octave_idx_type r1, octave_idx_type r2)
+{
+  octave_idx_type len = length ();
+
+  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  if (r2 >= r1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = r1; i <= r2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::fill (const FloatComplex& val, octave_idx_type r1, octave_idx_type r2)
+{
+  octave_idx_type len = length ();
+
+  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  if (r2 >= r1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = r1; i <= r2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexColumnVector
+FloatComplexColumnVector::stack (const FloatColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nr_insert = len;
+  FloatComplexColumnVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nr_insert);
+  return retval;
+}
+
+FloatComplexColumnVector
+FloatComplexColumnVector::stack (const FloatComplexColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nr_insert = len;
+  FloatComplexColumnVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nr_insert);
+  return retval;
+}
+
+FloatComplexRowVector 
+FloatComplexColumnVector::hermitian (void) const
+{
+  return MArray<FloatComplex>::hermitian (std::conj);
+}
+
+FloatComplexRowVector 
+FloatComplexColumnVector::transpose (void) const
+{
+  return MArray<FloatComplex>::transpose ();
+}
+
+FloatComplexColumnVector
+conj (const FloatComplexColumnVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  FloatComplexColumnVector retval;
+  if (a_len > 0)
+    retval = FloatComplexColumnVector (mx_inline_conj_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+// resize is the destructive equivalent for this one
+
+FloatComplexColumnVector
+FloatComplexColumnVector::extract (octave_idx_type r1, octave_idx_type r2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+
+  FloatComplexColumnVector result (new_r);
+
+  for (octave_idx_type i = 0; i < new_r; i++)
+    result.elem (i) = elem (r1+i);
+
+  return result;
+}
+
+FloatComplexColumnVector
+FloatComplexColumnVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  FloatComplexColumnVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.elem (i) = elem (r1+i);
+
+  return result;
+}
+
+// column vector by column vector -> column vector operations
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::operator += (const FloatColumnVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator +=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), len);
+  return *this;
+}
+
+FloatComplexColumnVector&
+FloatComplexColumnVector::operator -= (const FloatColumnVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator -=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_subtract2 (d, a.data (), len);
+  return *this;
+}
+
+// matrix by column vector -> column vector operations
+
+FloatComplexColumnVector
+operator * (const FloatComplexMatrix& m, const FloatColumnVector& a)
+{
+  FloatComplexColumnVector tmp (a);
+  return m * tmp;
+}
+
+FloatComplexColumnVector
+operator * (const FloatComplexMatrix& m, const FloatComplexColumnVector& a)
+{
+  FloatComplexColumnVector retval;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+  else
+    {
+      if (nc == 0 || nr == 0)
+	retval.resize (nr, 0.0);
+      else
+	{
+	  octave_idx_type ld = nr;
+
+	  retval.resize (nr);
+	  FloatComplex *y = retval.fortran_vec ();
+
+	  F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
+				   nr, nc, 1.0, m.data (), ld,
+				   a.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+// matrix by column vector -> column vector operations
+
+FloatComplexColumnVector
+operator * (const FloatMatrix& m, const FloatComplexColumnVector& a)
+{
+  FloatComplexMatrix tmp (m);
+  return tmp * a;
+}
+
+// diagonal matrix by column vector -> column vector operations
+
+FloatComplexColumnVector
+operator * (const FloatDiagMatrix& m, const FloatComplexColumnVector& a)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+      return FloatComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return FloatComplexColumnVector (0);
+
+  FloatComplexColumnVector result (nr);
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (octave_idx_type i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
+
+FloatComplexColumnVector
+operator * (const FloatComplexDiagMatrix& m, const FloatColumnVector& a)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+      return FloatComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return FloatComplexColumnVector (0);
+
+  FloatComplexColumnVector result (nr);
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (octave_idx_type i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
+
+FloatComplexColumnVector
+operator * (const FloatComplexDiagMatrix& m, const FloatComplexColumnVector& a)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    {
+      gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+      return FloatComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return FloatComplexColumnVector (0);
+
+  FloatComplexColumnVector result (nr);
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (octave_idx_type i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
+
+// other operations
+
+FloatColumnVector
+FloatComplexColumnVector::map (dmapper fcn) const
+{
+  return MArray<FloatComplex>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexColumnVector
+FloatComplexColumnVector::map (cmapper fcn) const
+{
+  return MArray<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
+}
+
+FloatComplex
+FloatComplexColumnVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  FloatComplex res = elem (0);
+  float absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) < absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+FloatComplex
+FloatComplexColumnVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  FloatComplex res = elem (0);
+  float absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) > absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const FloatComplexColumnVector& a)
+{
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << /* setw (field_width) << */ a.elem (i) << "\n";
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatComplexColumnVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      float tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCColVector.h b/liboctave/fCColVector.h
new file mode 100644
index 0000000..ff0bd51
--- /dev/null
+++ b/liboctave/fCColVector.h
@@ -0,0 +1,144 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexColumnVector_h)
+#define octave_FloatComplexColumnVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+FloatComplexColumnVector : public MArray<FloatComplex>
+{
+friend class FloatComplexMatrix;
+friend class FloatComplexRowVector;
+
+public:
+
+  FloatComplexColumnVector (void) : MArray<FloatComplex> () { }
+
+  explicit FloatComplexColumnVector (octave_idx_type n) : MArray<FloatComplex> (n) { }
+
+  FloatComplexColumnVector (octave_idx_type n, const FloatComplex& val)
+    : MArray<FloatComplex> (n, val) { }
+
+  FloatComplexColumnVector (const FloatComplexColumnVector& a) : MArray<FloatComplex> (a) { }
+
+  FloatComplexColumnVector (const MArray<FloatComplex>& a) : MArray<FloatComplex> (a) { }
+
+  explicit FloatComplexColumnVector (const FloatColumnVector& a);
+
+  FloatComplexColumnVector& operator = (const FloatComplexColumnVector& a)
+    {
+      MArray<FloatComplex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatComplexColumnVector& a) const;
+  bool operator != (const FloatComplexColumnVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  FloatComplexColumnVector& insert (const FloatColumnVector& a, octave_idx_type r);
+  FloatComplexColumnVector& insert (const FloatComplexColumnVector& a, octave_idx_type r);
+
+  FloatComplexColumnVector& fill (float val);
+  FloatComplexColumnVector& fill (const FloatComplex& val);
+  FloatComplexColumnVector& fill (float val, octave_idx_type r1, octave_idx_type r2);
+  FloatComplexColumnVector& fill (const FloatComplex& val, octave_idx_type r1, octave_idx_type r2);
+
+  FloatComplexColumnVector stack (const FloatColumnVector& a) const;
+  FloatComplexColumnVector stack (const FloatComplexColumnVector& a) const;
+
+  FloatComplexRowVector hermitian (void) const;
+  FloatComplexRowVector transpose (void) const;
+
+  friend OCTAVE_API FloatComplexColumnVector conj (const FloatComplexColumnVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  FloatComplexColumnVector extract (octave_idx_type r1, octave_idx_type r2) const;
+
+  FloatComplexColumnVector extract_n (octave_idx_type r1, octave_idx_type n) const;
+
+  // column vector by column vector -> column vector operations
+
+  FloatComplexColumnVector& operator += (const FloatColumnVector& a);
+  FloatComplexColumnVector& operator -= (const FloatColumnVector& a);
+
+  // matrix by column vector -> column vector operations
+
+  friend OCTAVE_API FloatComplexColumnVector operator * (const FloatComplexMatrix& a,
+					 const FloatColumnVector& b);
+
+  friend OCTAVE_API FloatComplexColumnVector operator * (const FloatComplexMatrix& a,
+					 const FloatComplexColumnVector& b);
+
+  // matrix by column vector -> column vector operations
+
+  friend OCTAVE_API FloatComplexColumnVector operator * (const FloatMatrix& a,
+					 const FloatComplexColumnVector& b);
+
+  // diagonal matrix by column vector -> column vector operations
+
+  friend OCTAVE_API FloatComplexColumnVector operator * (const FloatDiagMatrix& a,
+					 const FloatComplexColumnVector& b);
+
+  friend OCTAVE_API FloatComplexColumnVector operator * (const FloatComplexDiagMatrix& a,
+					 const ColumnVector& b);
+
+  friend OCTAVE_API FloatComplexColumnVector operator * (const FloatComplexDiagMatrix& a,
+					 const FloatComplexColumnVector& b);
+
+  // other operations
+
+  typedef float (*dmapper) (const FloatComplex&);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+
+  FloatColumnVector map (dmapper fcn) const;
+  FloatComplexColumnVector map (cmapper fcn) const;
+
+  FloatComplex min (void) const;
+  FloatComplex max (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexColumnVector& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatComplexColumnVector& a);
+
+private:
+
+  FloatComplexColumnVector (FloatComplex *d, octave_idx_type l) : MArray<FloatComplex> (d, l) { }
+};
+
+MARRAY_FORWARD_DEFS (MArray, FloatComplexColumnVector, FloatComplex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCDiagMatrix.cc b/liboctave/fCDiagMatrix.cc
new file mode 100644
index 0000000..dd69425
--- /dev/null
+++ b/liboctave/fCDiagMatrix.cc
@@ -0,0 +1,605 @@
+// DiagMatrix manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// FloatComplex Diagonal Matrix class
+
+FloatComplexDiagMatrix::FloatComplexDiagMatrix (const FloatDiagMatrix& a)
+  : MDiagArray2<FloatComplex> (a.rows (), a.cols ())
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+bool
+FloatComplexDiagMatrix::operator == (const FloatComplexDiagMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return 0;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+FloatComplexDiagMatrix::operator != (const FloatComplexDiagMatrix& a) const
+{
+  return !(*this == a);
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (float val)
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = val;
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatComplex& val)
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = val;
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (float val, octave_idx_type beg, octave_idx_type end)
+{
+  if (beg < 0 || end >= length () || end < beg)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = beg; i <= end; i++)
+    elem (i, i) = val;
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatComplex& val, octave_idx_type beg, octave_idx_type end)
+{
+  if (beg < 0 || end >= length () || end < beg)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = beg; i <= end; i++)
+    elem (i, i) = val;
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatColumnVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatComplexColumnVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatRowVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatComplexRowVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatColumnVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatComplexColumnVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatRowVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::fill (const FloatComplexRowVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+FloatDiagMatrix
+FloatComplexDiagMatrix::abs (void) const
+{
+  FloatDiagMatrix retval (rows (), cols ());
+  for (octave_idx_type i = 0; i < rows (); i++)
+    retval(i, i) = std::abs (elem (i, i));
+  return retval;
+}
+
+FloatComplexDiagMatrix
+conj (const FloatComplexDiagMatrix& a)
+{
+  FloatComplexDiagMatrix retval;
+  octave_idx_type a_len = a.length ();
+  if (a_len > 0)
+    retval = FloatComplexDiagMatrix (mx_inline_conj_dup (a.data (), a_len),
+				a.rows (), a.cols ());
+  return retval;
+}
+
+// resize is the destructive analog for this one
+
+FloatComplexMatrix
+FloatComplexDiagMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  FloatComplexMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.elem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+FloatComplexRowVector
+FloatComplexDiagMatrix::row (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= r)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return FloatComplexRowVector (); 
+    }
+
+  FloatComplexRowVector retval (c, 0.0);
+  if (r <= c || (r > c && i < c))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+FloatComplexRowVector
+FloatComplexDiagMatrix::row (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return FloatComplexRowVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return row (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return row (rows () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return FloatComplexRowVector ();
+    }
+}
+
+FloatComplexColumnVector
+FloatComplexDiagMatrix::column (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= c)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return FloatComplexColumnVector (); 
+    }
+
+  FloatComplexColumnVector retval (r, 0.0);
+  if (r >= c || (r < c && i < r))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+FloatComplexColumnVector
+FloatComplexDiagMatrix::column (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return FloatComplexColumnVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return column (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return column (cols () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return FloatComplexColumnVector (); 
+    }
+}
+
+FloatComplexDiagMatrix
+FloatComplexDiagMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  return inverse (info);
+}
+
+FloatComplexDiagMatrix
+FloatComplexDiagMatrix::inverse (octave_idx_type& info) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (r != c)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return FloatComplexDiagMatrix ();
+    }
+
+  FloatComplexDiagMatrix retval (r, c);
+
+  info = 0;
+  for (octave_idx_type i = 0; i < length (); i++)
+    {
+      if (elem (i, i) == static_cast<float> (0.0))
+	{
+	  info = -1;
+	  return *this;
+	}
+      else
+	retval.elem (i, i) = static_cast<float> (1.0) / elem (i, i);
+    }
+
+  return retval;
+}
+
+FloatComplexDiagMatrix
+FloatComplexDiagMatrix::pseudo_inverse (void) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  octave_idx_type len = length ();
+
+  FloatComplexDiagMatrix retval (c, r);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      if (elem (i, i) != 0.0f)
+        retval.elem (i, i) = 1.0f / elem (i, i);
+      else
+        retval.elem (i, i) = 0.0f;
+    }
+
+  return retval;
+}
+
+bool
+FloatComplexDiagMatrix::all_elements_are_real (void) const
+{
+  octave_idx_type len = length ();
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      float ip = std::imag (elem (i, i));
+
+      if (ip != 0.0 || lo_ieee_signbit (ip))
+        return false;
+    }
+
+  return true;
+}
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+FloatComplexDiagMatrix&
+FloatComplexDiagMatrix::operator += (const FloatDiagMatrix& a)
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r != a_nr || c != a_nc)
+    {
+      gripe_nonconformant ("operator +=", r, c, a_nr, a_nc);
+      return *this;
+    }
+
+  if (r == 0 || c == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), length ());
+  return *this;
+}
+
+FloatComplexDiagMatrix
+operator * (const FloatComplexDiagMatrix& a, const FloatDiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return FloatComplexDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return FloatComplexDiagMatrix (a_nr, a_nc, 0.0);
+
+  FloatComplexDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      FloatComplex a_element = a.elem (i, i);
+      float b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+FloatComplexDiagMatrix
+operator * (const FloatDiagMatrix& a, const FloatComplexDiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return FloatComplexDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return FloatComplexDiagMatrix (a_nr, a_nc, 0.0);
+
+  FloatComplexDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      float a_element = a.elem (i, i);
+      FloatComplex b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+FloatComplexDiagMatrix
+operator * (const FloatComplexDiagMatrix& a, const FloatComplexDiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+      return FloatComplexDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return FloatComplexDiagMatrix (a_nr, a_nc, 0.0);
+
+  FloatComplexDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      FloatComplex a_element = a.elem (i, i);
+      FloatComplex b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+// other operations
+
+FloatComplexDET
+FloatComplexDiagMatrix::determinant (void) const
+{
+  FloatComplexDET det (1.0f);
+  if (rows () != cols ())
+    {
+      (*current_liboctave_error_handler) ("determinant requires square matrix");
+      det = FloatComplexDET (0.0);
+    }
+  else
+    {
+      octave_idx_type len = length ();
+      for (octave_idx_type i = 0; i < len; i++)
+        det *= elem (i, i);
+    }
+
+  return det;
+}
+
+float
+FloatComplexDiagMatrix::rcond (void) const
+{
+  FloatColumnVector av = diag (0).map (std::abs);
+  float amx = av.max (), amn = av.min ();
+  return amx == 0 ? 0.0f : amn / amx;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const FloatComplexDiagMatrix& a)
+{
+  FloatComplex ZERO (0.0);
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  if (i == j)
+	    os << " " /* setw (field_width) */ << a.elem (i, i);
+	  else
+	    os << " " /* setw (field_width) */ << ZERO;
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCDiagMatrix.h b/liboctave/fCDiagMatrix.h
new file mode 100644
index 0000000..f0fe6b1
--- /dev/null
+++ b/liboctave/fCDiagMatrix.h
@@ -0,0 +1,164 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexDiagMatrix_h)
+#define octave_FloatComplexDiagMatrix_h 1
+
+#include "MDiagArray2.h"
+
+#include "fRowVector.h"
+#include "fCRowVector.h"
+#include "fColVector.h"
+#include "fCColVector.h"
+#include "DET.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+FloatComplexDiagMatrix : public MDiagArray2<FloatComplex>
+{
+public:
+
+  FloatComplexDiagMatrix (void) : MDiagArray2<FloatComplex> () { }
+
+  FloatComplexDiagMatrix (octave_idx_type r, octave_idx_type c) : MDiagArray2<FloatComplex> (r, c) { }
+
+  FloatComplexDiagMatrix (octave_idx_type r, octave_idx_type c, const FloatComplex& val)
+    : MDiagArray2<FloatComplex> (r, c, val) { }
+
+  explicit FloatComplexDiagMatrix (const FloatRowVector& a)
+    : MDiagArray2<FloatComplex> (FloatComplexRowVector (a)) { }
+
+  explicit FloatComplexDiagMatrix (const FloatComplexRowVector& a)
+    : MDiagArray2<FloatComplex> (a) { }
+
+  explicit FloatComplexDiagMatrix (const FloatColumnVector& a)
+    : MDiagArray2<FloatComplex> (FloatComplexColumnVector (a)) { }
+
+  explicit FloatComplexDiagMatrix (const FloatComplexColumnVector& a)
+    : MDiagArray2<FloatComplex> (a) { }
+
+  explicit FloatComplexDiagMatrix (const FloatDiagMatrix& a);
+
+  FloatComplexDiagMatrix (const MDiagArray2<FloatComplex>& a)
+    : MDiagArray2<FloatComplex> (a) { }
+
+  FloatComplexDiagMatrix (const FloatComplexDiagMatrix& a)
+    : MDiagArray2<FloatComplex> (a) { }
+
+  template <class U>
+  FloatComplexDiagMatrix (const DiagArray2<U>& a) 
+    : MDiagArray2<FloatComplex> (a) { }
+
+  FloatComplexDiagMatrix& operator = (const FloatComplexDiagMatrix& a)
+    {
+      MDiagArray2<FloatComplex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatComplexDiagMatrix& a) const;
+  bool operator != (const FloatComplexDiagMatrix& a) const;
+
+  FloatComplexDiagMatrix& fill (float val);
+  FloatComplexDiagMatrix& fill (const FloatComplex& val);
+  FloatComplexDiagMatrix& fill (float val, octave_idx_type beg, octave_idx_type end);
+  FloatComplexDiagMatrix& fill (const FloatComplex& val, octave_idx_type beg, octave_idx_type end);
+  FloatComplexDiagMatrix& fill (const FloatColumnVector& a);
+  FloatComplexDiagMatrix& fill (const FloatComplexColumnVector& a);
+  FloatComplexDiagMatrix& fill (const FloatRowVector& a);
+  FloatComplexDiagMatrix& fill (const FloatComplexRowVector& a);
+  FloatComplexDiagMatrix& fill (const FloatColumnVector& a, octave_idx_type beg);
+  FloatComplexDiagMatrix& fill (const FloatComplexColumnVector& a, octave_idx_type beg);
+  FloatComplexDiagMatrix& fill (const FloatRowVector& a, octave_idx_type beg);
+  FloatComplexDiagMatrix& fill (const FloatComplexRowVector& a, octave_idx_type beg);
+
+  FloatComplexDiagMatrix hermitian (void) const { return MDiagArray2<FloatComplex>::hermitian (std::conj); }
+  FloatComplexDiagMatrix transpose (void) const { return MDiagArray2<FloatComplex>::transpose(); }
+  FloatDiagMatrix abs (void) const; 
+
+  friend OCTAVE_API FloatComplexDiagMatrix conj (const FloatComplexDiagMatrix& a);
+
+  // resize is the destructive analog for this one
+
+  FloatComplexMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  // extract row or column i
+
+  FloatComplexRowVector row (octave_idx_type i) const;
+  FloatComplexRowVector row (char *s) const;
+
+  FloatComplexColumnVector column (octave_idx_type i) const;
+  FloatComplexColumnVector column (char *s) const;
+
+  FloatComplexDiagMatrix inverse (octave_idx_type& info) const;
+  FloatComplexDiagMatrix inverse (void) const;
+  FloatComplexDiagMatrix pseudo_inverse (void) const;
+
+  bool all_elements_are_real (void) const;
+
+  // diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+  FloatComplexDiagMatrix& operator += (const FloatDiagMatrix& a);
+  FloatComplexDiagMatrix& operator -= (const FloatDiagMatrix& a);
+
+  // other operations
+
+  FloatComplexColumnVector diag (octave_idx_type k = 0) const
+    { return MDiagArray2<FloatComplex>::diag (k); }
+
+  FloatComplexDET determinant (void) const;
+  float rcond (void) const;
+
+  // i/o
+
+  friend std::ostream& operator << (std::ostream& os, const FloatComplexDiagMatrix& a);
+
+private:
+
+  FloatComplexDiagMatrix (FloatComplex *d, octave_idx_type nr, octave_idx_type nc)
+    : MDiagArray2<FloatComplex> (d, nr, nc) { }
+};
+
+OCTAVE_API FloatComplexDiagMatrix conj (const FloatComplexDiagMatrix& a);
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+OCTAVE_API FloatComplexDiagMatrix
+operator * (const FloatComplexDiagMatrix& a, const FloatComplexDiagMatrix& b);
+
+OCTAVE_API FloatComplexDiagMatrix
+operator * (const FloatComplexDiagMatrix& a, const FloatDiagMatrix& b);
+
+OCTAVE_API FloatComplexDiagMatrix
+operator * (const FloatDiagMatrix& a, const FloatComplexDiagMatrix& b);
+
+MDIAGARRAY2_FORWARD_DEFS (MDiagArray2, FloatComplexDiagMatrix, FloatComplex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCMatrix.cc b/liboctave/fCMatrix.cc
new file mode 100644
index 0000000..48e5917
--- /dev/null
+++ b/liboctave/fCMatrix.cc
@@ -0,0 +1,4083 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <vector>
+
+// FIXME
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "Array-util.h"
+#include "fCMatrix.h"
+#include "DET.h"
+#include "fCmplxSCHUR.h"
+#include "fCmplxSVD.h"
+#include "fCmplxCHOL.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "mx-fcm-fdm.h"
+#include "mx-fdm-fcm.h"
+#include "mx-fcm-fs.h"
+#include "mx-inlines.cc"
+#include "mx-op-defs.h"
+#include "oct-cmplx.h"
+#include "oct-norm.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#endif
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (xilaenv, XILAENV) (const octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			       F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&,
+			       const octave_idx_type&, const octave_idx_type&,
+			       octave_idx_type&
+			       F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgebal, CGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, FloatComplex*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgebak, SGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgemm, CGEMM) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			   const FloatComplex&, const FloatComplex*, const octave_idx_type&,
+			   const FloatComplex*, const octave_idx_type&, const FloatComplex&,
+			   FloatComplex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgemv, CGEMV) (F77_CONST_CHAR_ARG_DECL,
+                           const octave_idx_type&, const octave_idx_type&, const FloatComplex&,
+                           const FloatComplex*, const octave_idx_type&, const FloatComplex*,
+                           const octave_idx_type&, const FloatComplex&, FloatComplex*, const octave_idx_type&
+                           F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xcdotu, XCDOTU) (const octave_idx_type&, const FloatComplex*, const octave_idx_type&,
+			     const FloatComplex*, const octave_idx_type&, FloatComplex&);
+
+  F77_RET_T
+  F77_FUNC (xcdotc, XCDOTC) (const octave_idx_type&, const FloatComplex*, const octave_idx_type&,
+			     const FloatComplex*, const octave_idx_type&, FloatComplex&);
+
+  F77_RET_T
+  F77_FUNC (csyrk, CSYRK) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, 
+			   const FloatComplex&, const FloatComplex*, const octave_idx_type&,
+			   const FloatComplex&, FloatComplex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cherk, CHERK) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, 
+			   const FloatComplex&, const FloatComplex*, const octave_idx_type&,
+			   const FloatComplex&, FloatComplex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgetrf, CGETRF) (const octave_idx_type&, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+			     octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cgetrs, CGETRS) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+			     const octave_idx_type*, FloatComplex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgetri, CGETRI) (const octave_idx_type&, FloatComplex*, const octave_idx_type&, const octave_idx_type*,
+			     FloatComplex*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cgecon, CGECON) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, FloatComplex*, 
+			     const octave_idx_type&, const float&, float&, 
+			     FloatComplex*, float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgelsy, CGELSY) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, octave_idx_type*, float&, octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, float*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cgelsd, CGELSD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, float*, float&, octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, float*, 
+			     octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cpotrf, CPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     FloatComplex*, const octave_idx_type&, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cpocon, CPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     FloatComplex*, const octave_idx_type&, const float&,
+			     float&, FloatComplex*, float*,
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cpotrs, CPOTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const FloatComplex*, 
+			     const octave_idx_type&, FloatComplex*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ctrtri, CTRTRI) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const FloatComplex*, 
+			     const octave_idx_type&, octave_idx_type& 
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ctrcon, CTRCON) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const FloatComplex*, const octave_idx_type&, float&,
+			     FloatComplex*, float*, octave_idx_type& 
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ctrtrs, CTRTRS) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const FloatComplex*, 
+			     const octave_idx_type&, FloatComplex*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cffti, CFFTI) (const octave_idx_type&, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftf, CFFTF) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftb, CFFTB) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (clartg, CLARTG) (const FloatComplex&, const FloatComplex&,
+			     float&, FloatComplex&, FloatComplex&);
+
+  F77_RET_T
+  F77_FUNC (ctrsyl, CTRSYL) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     const FloatComplex*, const octave_idx_type&,
+			     const FloatComplex*, const octave_idx_type&,
+			     const FloatComplex*, const octave_idx_type&, float&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xclange, XCLANGE) (F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&, const FloatComplex*,
+			       const octave_idx_type&, float*, float&
+			       F77_CHAR_ARG_LEN_DECL);
+}
+
+static const FloatComplex FloatComplex_NaN_result (octave_Float_NaN, octave_Float_NaN);
+
+// FloatComplex Matrix class
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatMatrix& a)
+  : MArray2<FloatComplex> (a.rows (), a.cols ())
+{
+  for (octave_idx_type j = 0; j < cols (); j++)
+    for (octave_idx_type i = 0; i < rows (); i++)
+      elem (i, j) = a.elem (i, j);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatRowVector& rv)
+  : MArray2<FloatComplex> (1, rv.length (), 0.0)
+{
+  for (octave_idx_type i = 0; i < rv.length (); i++)
+    elem (0, i) = rv.elem (i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatColumnVector& cv)
+  : MArray2<FloatComplex> (cv.length (), 1, 0.0)
+{
+  for (octave_idx_type i = 0; i < cv.length (); i++)
+    elem (i, 0) = cv.elem (i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatDiagMatrix& a)
+  : MArray2<FloatComplex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatComplexRowVector& rv)
+  : MArray2<FloatComplex> (Array2<FloatComplex> (rv, 1, rv.length ()))
+{
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatComplexColumnVector& cv)
+  : MArray2<FloatComplex> (Array2<FloatComplex> (cv, cv.length (), 1))
+{
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const FloatComplexDiagMatrix& a)
+  : MArray2<FloatComplex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+// FIXME -- could we use a templated mixed-type copy function
+// here?
+
+FloatComplexMatrix::FloatComplexMatrix (const boolMatrix& a)
+  : MArray2<FloatComplex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = a.elem (i, j);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const charMatrix& a)
+  : MArray2<FloatComplex> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = static_cast<unsigned char> (a.elem (i, j));
+}
+
+bool
+FloatComplexMatrix::operator == (const FloatComplexMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return false;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+FloatComplexMatrix::operator != (const FloatComplexMatrix& a) const
+{
+  return !(*this == a);
+}
+
+bool
+FloatComplexMatrix::is_hermitian (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (is_square () && nr > 0)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	for (octave_idx_type j = i; j < nc; j++)
+	  if (elem (i, j) != conj (elem (j, i)))
+	    return false;
+
+      return true;
+    }
+
+  return false;
+}
+
+// destructive insert/delete/reorder operations
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_nr >0 && a_nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < a_nc; j++)
+	for (octave_idx_type i = 0; i < a_nr; i++)
+	  xelem (r+i, c+j) = a.elem (i, j);
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatRowVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r, c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatColumnVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatDiagMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
+
+  octave_idx_type a_len = a.length ();
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c+i) = a.elem (i, i);
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatComplexMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Array2<FloatComplex>::insert (a, r, c);
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatComplexRowVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+  if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (r, c+i) = a.elem (i);
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatComplexColumnVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::insert (const FloatComplexDiagMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
+
+  octave_idx_type a_len = a.length ();
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c+i) = a.elem (i, i);
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::fill (float val)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::fill (const FloatComplex& val)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::fill (float val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
+      || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (r2 >= r1 && c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = c1; j <= c2; j++)
+	for (octave_idx_type i = r1; i <= r2; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::fill (const FloatComplex& val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
+      || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (r2 >= r1 && c2 >=c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = c1; j <= c2; j++)
+	for (octave_idx_type i = r1; i <= r2; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != 1)
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + a.length ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.length ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + 1);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatComplexMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatComplexRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != 1)
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + a.length ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatComplexColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.length ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + 1);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::append (const FloatComplexDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatComplexMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + 1, nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != 1)
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + a.length (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatComplexMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatComplexRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + 1, nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatComplexColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != 1)
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + a.length (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::stack (const FloatComplexDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatComplexMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatComplexMatrix
+conj (const FloatComplexMatrix& a)
+{
+  return FloatComplexMatrix (mx_inline_conj_dup (a.data (), a.length ()),
+                             a.rows (), a.cols ());
+}
+
+// resize is the destructive equivalent for this one
+
+FloatComplexMatrix
+FloatComplexMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  FloatComplexMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const
+{
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+FloatComplexRowVector
+FloatComplexMatrix::row (octave_idx_type i) const
+{
+  return MArray<FloatComplex> (index (idx_vector (i), idx_vector::colon));
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::column (octave_idx_type i) const
+{
+  return MArray<FloatComplex> (index (idx_vector::colon, idx_vector (i)));
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  float rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::inverse (octave_idx_type& info) const
+{
+  float rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::inverse (octave_idx_type& info, float& rcon, int force,
+			int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, force, calc_cond);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::inverse (MatrixType &mattype) const
+{
+  octave_idx_type info;
+  float rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::inverse (MatrixType &mattype, octave_idx_type& info) const
+{
+  float rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::tinverse (MatrixType &mattype, octave_idx_type& info,
+			 float& rcon, int force, int calc_cond) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr == 0 || nc == 0)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      int typ = mattype.type ();
+      char uplo = (typ == MatrixType::Lower ? 'L' : 'U');
+      char udiag = 'N';
+      retval = *this;
+      FloatComplex *tmp_data = retval.fortran_vec ();
+
+      F77_XFCN (ctrtri, CTRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+				 F77_CONST_CHAR_ARG2 (&udiag, 1),
+				 nr, tmp_data, nr, info 
+				 F77_CHAR_ARG_LEN (1)
+				 F77_CHAR_ARG_LEN (1)));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  octave_idx_type ztrcon_info = 0;
+	  char job = '1';
+
+	  OCTAVE_LOCAL_BUFFER (FloatComplex, cwork, 2*nr);
+	  OCTAVE_LOCAL_BUFFER (float, rwork, nr);
+
+	  F77_XFCN (ctrcon, CTRCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     F77_CONST_CHAR_ARG2 (&uplo, 1),
+				     F77_CONST_CHAR_ARG2 (&udiag, 1),
+				     nr, tmp_data, nr, rcon, 
+				     cwork, rwork, ztrcon_info 
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (ztrcon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this; // Restore matrix contents.
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::finverse (MatrixType &mattype, octave_idx_type& info,
+			 float& rcon, int force, int calc_cond) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      Array<octave_idx_type> ipvt (nr);
+      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+      retval = *this;
+      FloatComplex *tmp_data = retval.fortran_vec ();
+
+      Array<FloatComplex> z(1);
+      octave_idx_type lwork = -1;
+
+      // Query the optimum work array size.
+
+      F77_XFCN (cgetri, CGETRI, (nc, tmp_data, nr, pipvt, 
+				 z.fortran_vec (), lwork, info));
+
+      lwork = static_cast<octave_idx_type> (std::real(z(0)));
+      lwork = (lwork <  2 *nc ? 2*nc : lwork);
+      z.resize (lwork);
+      FloatComplex *pz = z.fortran_vec ();
+
+      info = 0;
+
+      // Calculate the norm of the matrix, for later use.
+      float anorm;
+      if (calc_cond)
+	anorm  = retval.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+      F77_XFCN (cgetrf, CGETRF, (nc, nc, tmp_data, nr, pipvt, info));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  // Now calculate the condition number for non-singular matrix.
+	  octave_idx_type zgecon_info = 0;
+	  char job = '1';
+	  Array<float> rz (2 * nc);
+	  float *prz = rz.fortran_vec ();
+	  F77_XFCN (cgecon, CGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nc, tmp_data, nr, anorm, 
+				     rcon, pz, prz, zgecon_info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (zgecon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this;  // Restore contents.
+      else
+	{
+	  octave_idx_type zgetri_info = 0;
+
+	  F77_XFCN (cgetri, CGETRI, (nc, tmp_data, nr, pipvt,
+				     pz, lwork, zgetri_info));
+
+	  if (zgetri_info != 0) 
+	    info = -1;
+	}
+
+      if (info != 0)
+	mattype.mark_as_rectangular();
+    }
+  
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::inverse (MatrixType &mattype, octave_idx_type& info,
+			float& rcon, int force, int calc_cond) const
+{
+  int typ = mattype.type (false);
+  FloatComplexMatrix ret;
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Upper || typ == MatrixType::Lower)
+    ret = tinverse (mattype, info, rcon, force, calc_cond);
+  else
+    {
+      if (mattype.is_hermitian ())
+	{
+	  FloatComplexCHOL chol (*this, info, calc_cond);
+	  if (info == 0)
+	    {
+	      if (calc_cond)
+		rcon = chol.rcond();
+	      else
+		rcon = 1.0;
+	      ret = chol.inverse ();
+	    }
+	  else
+	    mattype.mark_as_unsymmetric ();
+	}
+
+      if (!mattype.is_hermitian ())
+	ret = finverse(mattype, info, rcon, force, calc_cond);
+
+      if ((mattype.is_hermitian () || calc_cond) && rcon == 0.)
+	ret = FloatComplexMatrix (rows (), columns (), FloatComplex (octave_Float_Inf, 0.));
+    }
+
+  return ret;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::pseudo_inverse (float tol) const
+{
+  FloatComplexMatrix retval;
+
+  FloatComplexSVD result (*this, SVD::economy);
+
+  FloatDiagMatrix S = result.singular_values ();
+  FloatComplexMatrix U = result.left_singular_matrix ();
+  FloatComplexMatrix V = result.right_singular_matrix ();
+
+  FloatColumnVector sigma = S.diag ();
+
+  octave_idx_type r = sigma.length () - 1;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (tol <= 0.0)
+    {
+      if (nr > nc)
+	tol = nr * sigma.elem (0) * DBL_EPSILON;
+      else
+	tol = nc * sigma.elem (0) * DBL_EPSILON;
+    }
+
+  while (r >= 0 && sigma.elem (r) < tol)
+    r--;
+
+  if (r < 0)
+    retval = FloatComplexMatrix (nc, nr, 0.0);
+  else
+    {
+      FloatComplexMatrix Ur = U.extract (0, 0, nr-1, r);
+      FloatDiagMatrix D = FloatDiagMatrix (sigma.extract (0, r)) . inverse ();
+      FloatComplexMatrix Vr = V.extract (0, 0, nc-1, r);
+      retval = Vr * D * Ur.hermitian ();
+    }
+
+  return retval;
+}
+
+#if defined (HAVE_FFTW3)
+
+FloatComplexMatrix
+FloatComplexMatrix::fourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  const FloatComplex *in (data ());
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::fft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::ifourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  const FloatComplex *in (data ());
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::ifft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::fourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  FloatComplexMatrix retval (rows (), cols ());
+  const FloatComplex *in (data ());
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::fftNd (in, out, 2, dv);
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::ifourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  FloatComplexMatrix retval (rows (), cols ());
+  const FloatComplex *in (data ());
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (in, out, 2, dv);
+
+  return retval;
+}
+
+#else
+
+FloatComplexMatrix
+FloatComplexMatrix::fourier (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::ifourier (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<float> (npts);
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::fourier2d (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<FloatComplex> tmp (npts);
+  FloatComplex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i];
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::ifourier2d (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = *this;
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<float> (npts);
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<FloatComplex> tmp (npts);
+  FloatComplex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i] / static_cast<float> (npts);
+    }
+
+  return retval;
+}
+
+#endif
+
+FloatComplexDET
+FloatComplexMatrix::determinant (void) const
+{
+  octave_idx_type info;
+  float rcon;
+  return determinant (info, rcon, 0);
+}
+
+FloatComplexDET
+FloatComplexMatrix::determinant (octave_idx_type& info) const
+{
+  float rcon;
+  return determinant (info, rcon, 0);
+}
+
+FloatComplexDET
+FloatComplexMatrix::determinant (octave_idx_type& info, float& rcon, int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return determinant (mattype, info, rcon, calc_cond);
+}
+
+FloatComplexDET
+FloatComplexMatrix::determinant (MatrixType& mattype,
+                                 octave_idx_type& info, float& rcon, int calc_cond) const
+{
+  FloatComplexDET retval (1.0);
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+        typ = mattype.type (*this);
+
+      if (typ == MatrixType::Lower || typ == MatrixType::Upper)
+        {
+          for (octave_idx_type i = 0; i < nc; i++) 
+            retval *= elem (i,i);
+        }
+      else if (typ == MatrixType::Hermitian)
+        {
+          FloatComplexMatrix atmp = *this;
+          FloatComplex *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+          float anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+
+          char job = 'L';
+          F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+                                     tmp_data, nr, info
+                                     F77_CHAR_ARG_LEN (1)));
+
+          if (info != 0) 
+            {
+              rcon = 0.0;
+              mattype.mark_as_unsymmetric ();
+              typ = MatrixType::Full;
+            }
+          else 
+            {
+              Array<FloatComplex> z (2 * nc);
+              FloatComplex *pz = z.fortran_vec ();
+              Array<float> rz (nc);
+              float *prz = rz.fortran_vec ();
+
+              F77_XFCN (cpocon, CPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                         nr, tmp_data, nr, anorm,
+                                         rcon, pz, prz, info
+                                         F77_CHAR_ARG_LEN (1)));
+
+              if (info != 0) 
+                rcon = 0.0;
+
+              for (octave_idx_type i = 0; i < nc; i++) 
+                retval *= atmp (i,i);
+
+              retval = retval.square ();
+            }
+        }
+      else if (typ != MatrixType::Full)
+        (*current_liboctave_error_handler) ("det: invalid dense matrix type");
+
+      if (typ == MatrixType::Full)
+        {
+          Array<octave_idx_type> ipvt (nr);
+          octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+          FloatComplexMatrix atmp = *this;
+          FloatComplex *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+
+          // Calculate the norm of the matrix, for later use.
+          float anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+          F77_XFCN (cgetrf, CGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+          // Throw-away extra info LAPACK gives so as to not change output.
+          rcon = 0.0;
+          if (info != 0) 
+            {
+              info = -1;
+              retval = FloatComplexDET ();
+            } 
+          else 
+            {
+              if (calc_cond) 
+                {
+                  // Now calc the condition number for non-singular matrix.
+                  char job = '1';
+                  Array<FloatComplex> z (2 * nc);
+                  FloatComplex *pz = z.fortran_vec ();
+                  Array<float> rz (2 * nc);
+                  float *prz = rz.fortran_vec ();
+
+                  F77_XFCN (cgecon, CGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                             nc, tmp_data, nr, anorm, 
+                                             rcon, pz, prz, info
+                                             F77_CHAR_ARG_LEN (1)));
+                }
+
+              if (info != 0) 
+                {
+                  info = -1;
+                  retval = FloatComplexDET ();
+                } 
+              else 
+                {
+                  for (octave_idx_type i = 0; i < nc; i++) 
+                    {
+                      FloatComplex c = atmp(i,i);
+                      retval *= (ipvt(i) != (i+1)) ? -c : c;
+                    }
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+float
+FloatComplexMatrix::rcond (void) const
+{
+  MatrixType mattype (*this);
+  return rcond (mattype);
+}
+
+float
+FloatComplexMatrix::rcond (MatrixType &mattype) const
+{
+  float rcon;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else if (nr == 0 || nc == 0)
+    rcon = octave_Inf;
+  else
+    {
+      int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+	typ = mattype.type (*this);
+
+      // Only calculate the condition number for LU/Cholesky
+      if (typ == MatrixType::Upper)
+	{
+	  const FloatComplex *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'U';
+	  char dia = 'N';
+
+	  Array<FloatComplex> z (2 * nc);
+	  FloatComplex *pz = z.fortran_vec ();
+	  Array<float> rz (nc);
+	  float *prz = rz.fortran_vec ();
+
+	  F77_XFCN (ctrcon, CTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, prz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0;
+	}
+      else if  (typ == MatrixType::Permuted_Upper)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Lower)
+	{
+	  const FloatComplex *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'L';
+	  char dia = 'N';
+
+	  Array<FloatComplex> z (2 * nc);
+	  FloatComplex *pz = z.fortran_vec ();
+	  Array<float> rz (nc);
+	  float *prz = rz.fortran_vec ();
+
+	  F77_XFCN (ctrcon, CTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, prz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0.0;
+	}
+      else if (typ == MatrixType::Permuted_Lower)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+	{
+	  float anorm = -1.0;
+	  FloatComplexMatrix atmp = *this;
+	  FloatComplex *tmp_data = atmp.fortran_vec ();
+
+	  if (typ == MatrixType::Hermitian)
+	    {
+	      octave_idx_type info = 0;
+	      char job = 'L';
+	      anorm = atmp.abs().sum().
+		row(static_cast<octave_idx_type>(0)).max();
+
+	      F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+					 tmp_data, nr, info
+					 F77_CHAR_ARG_LEN (1)));
+
+	      if (info != 0) 
+		{
+		  rcon = 0.0;
+
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}
+	      else 
+		{
+		  Array<FloatComplex> z (2 * nc);
+		  FloatComplex *pz = z.fortran_vec ();
+		  Array<float> rz (nc);
+		  float *prz = rz.fortran_vec ();
+
+		  F77_XFCN (cpocon, CPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+
+
+	  if (typ == MatrixType::Full)
+	    {
+	      octave_idx_type info = 0;
+
+	      Array<octave_idx_type> ipvt (nr);
+	      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	      if(anorm < 0.)
+		anorm = atmp.abs().sum().
+		  row(static_cast<octave_idx_type>(0)).max();
+
+	      Array<FloatComplex> z (2 * nc);
+	      FloatComplex *pz = z.fortran_vec ();
+	      Array<float> rz (2 * nc);
+	      float *prz = rz.fortran_vec ();
+
+	      F77_XFCN (cgetrf, CGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	      if (info != 0) 
+		{ 
+		  rcon = 0.0;
+		  mattype.mark_as_rectangular ();
+		} 
+	      else 
+		{
+		  char job = '1';
+		  F77_XFCN (cgecon, CGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+	}
+      else
+	rcon = 0.0;
+    }
+
+  return rcon;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::utsolve (MatrixType &mattype, const FloatComplexMatrix& b, 
+			octave_idx_type& info, float& rcon, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = FloatComplexMatrix (nc, b.cols (), FloatComplex (0.0, 0.0));
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const FloatComplex *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'U';
+		  char dia = 'N';
+
+		  Array<FloatComplex> z (2 * nc);
+		  FloatComplex *pz = z.fortran_vec ();
+		  Array<float> rz (nc);
+		  float *prz = rz.fortran_vec ();
+
+		  F77_XFCN (ctrcon, CTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, prz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  FloatComplex *result = retval.fortran_vec ();
+
+		  char uplo = 'U';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (ctrtrs, CTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::ltsolve (MatrixType &mattype, const FloatComplexMatrix& b, 
+			octave_idx_type& info, float& rcon, 
+			solve_singularity_handler sing_handler,
+			bool calc_cond) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = FloatComplexMatrix (nc, b.cols (), FloatComplex (0.0, 0.0));
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const FloatComplex *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'L';
+		  char dia = 'N';
+
+		  Array<FloatComplex> z (2 * nc);
+		  FloatComplex *pz = z.fortran_vec ();
+		  Array<float> rz (nc);
+		  float *prz = rz.fortran_vec ();
+
+		  F77_XFCN (ctrcon, CTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, prz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  FloatComplex *result = retval.fortran_vec ();
+
+		  char uplo = 'L';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (ctrtrs, CTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::fsolve (MatrixType &mattype, const FloatComplexMatrix& b, 
+		       octave_idx_type& info, float& rcon,
+		       solve_singularity_handler sing_handler,
+		       bool calc_cond) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = FloatComplexMatrix (nc, b.cols (), FloatComplex (0.0, 0.0));
+  else
+    {
+      volatile int typ = mattype.type ();
+ 
+     // Calculate the norm of the matrix, for later use.
+      float anorm = -1.;
+
+      if (typ == MatrixType::Hermitian)
+	{
+	  info = 0;
+	  char job = 'L';
+	  FloatComplexMatrix atmp = *this;
+	  FloatComplex *tmp_data = atmp.fortran_vec ();
+	  anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+				     tmp_data, nr, info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    {
+	      info = -2;
+
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<FloatComplex> z (2 * nc);
+		  FloatComplex *pz = z.fortran_vec ();
+		  Array<float> rz (nc);
+		  float *prz = rz.fortran_vec ();
+
+		  F77_XFCN (cpocon, CPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  FloatComplex *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  F77_XFCN (cpotrs, CPOTRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	      else
+		{
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}
+	    }
+	}
+
+      if (typ == MatrixType::Full)
+	{
+	  info = 0;
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  FloatComplexMatrix atmp = *this;
+	  FloatComplex *tmp_data = atmp.fortran_vec ();
+
+	  Array<FloatComplex> z (2 * nc);
+	  FloatComplex *pz = z.fortran_vec ();
+	  Array<float> rz (2 * nc);
+	  float *prz = rz.fortran_vec ();
+
+	  // Calculate the norm of the matrix, for later use.
+	  if (anorm < 0.)
+	    anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  F77_XFCN (cgetrf, CGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    { 
+	      info = -2;
+
+	      if (sing_handler)
+		sing_handler (rcon);
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	      mattype.mark_as_rectangular ();
+	    } 
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  // Now calculate the condition number for 
+		  // non-singular matrix.
+		  char job = '1';
+		  F77_XFCN (cgecon, CGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, prz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  FloatComplex *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  char job = 'N';
+		  F77_XFCN (cgetrs, CGETRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     pipvt, result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1))); 
+		}
+	      else
+		mattype.mark_as_rectangular ();		    
+	    }
+	}
+    }
+  
+  return retval;
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatMatrix& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatMatrix& b, 
+		      octave_idx_type& info) const
+{
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info,
+		      float& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info, 
+		      float& rcon, solve_singularity_handler sing_handler,
+		      bool singular_fallback) const
+{
+  FloatComplexMatrix tmp (b);
+  return solve (typ, tmp, info, rcon, sing_handler, singular_fallback);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		      octave_idx_type& info) const
+{
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		      octave_idx_type& info, float& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (MatrixType &mattype, const FloatComplexMatrix& b, 
+		      octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler,
+		      bool singular_fallback) const
+{
+  FloatComplexMatrix retval;
+  int typ = mattype.type ();
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  // Only calculate the condition number for LU/Cholesky
+  if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, info, rcon, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return FloatComplexMatrix ();
+    }
+
+  // Rectangular or one of the above solvers flags a singular matrix
+  if (singular_fallback && mattype.type () == MatrixType::Rectangular)
+    {
+      octave_idx_type rank;
+      retval = lssolve (b, info, rank, rcon);
+    }
+
+  return retval;
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatColumnVector& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (typ, FloatComplexColumnVector (b), info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatColumnVector& b, 
+		      octave_idx_type& info) const
+{
+  float rcon;
+  return solve (typ, FloatComplexColumnVector (b), info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatColumnVector& b, 
+		      octave_idx_type& info, float& rcon) const
+{
+  return solve (typ, FloatComplexColumnVector (b), info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatColumnVector& b, 
+		      octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  return solve (typ, FloatComplexColumnVector (b), info, rcon, sing_handler);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+		      octave_idx_type& info) const
+{
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b,
+		      octave_idx_type& info, float& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b,
+		      octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+
+  FloatComplexMatrix tmp (b);
+  return solve (typ, tmp, info, rcon, sing_handler).column(static_cast<octave_idx_type> (0));
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatMatrix& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatMatrix& b, octave_idx_type& info) const
+{
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatMatrix& b, octave_idx_type& info, float& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatMatrix& b, octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  FloatComplexMatrix tmp (b);
+  return solve (tmp, info, rcon, sing_handler);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatComplexMatrix& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatComplexMatrix& b, octave_idx_type& info) const
+{
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatColumnVector& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (FloatComplexColumnVector (b), info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatColumnVector& b, octave_idx_type& info) const
+{
+  float rcon;
+  return solve (FloatComplexColumnVector (b), info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatColumnVector& b, octave_idx_type& info, 
+		      float& rcon) const
+{
+  return solve (FloatComplexColumnVector (b), info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatColumnVector& b, octave_idx_type& info, 
+		      float& rcon, 
+		      solve_singularity_handler sing_handler) const
+{
+  return solve (FloatComplexColumnVector (b), info, rcon, sing_handler);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatComplexColumnVector& b, octave_idx_type& info) const
+{
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatComplexColumnVector& b, octave_idx_type& info,
+		      float& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::solve (const FloatComplexColumnVector& b, octave_idx_type& info,
+		      float& rcon,
+		      solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatMatrix& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (FloatComplexMatrix (b), info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatMatrix& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (FloatComplexMatrix (b), info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatMatrix& b, octave_idx_type& info,
+			octave_idx_type& rank) const
+{
+  float rcon;
+  return lssolve (FloatComplexMatrix (b), info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatMatrix& b, octave_idx_type& info,
+			octave_idx_type& rank, float& rcon) const
+{
+  return lssolve (FloatComplexMatrix (b), info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatComplexMatrix& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatComplexMatrix& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatComplexMatrix& b, octave_idx_type& info,
+			octave_idx_type& rank) const
+{
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::lssolve (const FloatComplexMatrix& b, octave_idx_type& info, 
+			octave_idx_type& rank, float& rcon) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nrhs = b.cols ();
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m== 0 || n == 0 || b.cols () == 0)
+    retval = FloatComplexMatrix (n, b.cols (), FloatComplex (0.0, 0.0));
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+
+      if (m != n)
+	{
+	  retval = FloatComplexMatrix (maxmn, nrhs);
+
+	  for (octave_idx_type j = 0; j < nrhs; j++)
+	    for (octave_idx_type i = 0; i < m; i++)
+	      retval.elem (i, j) = b.elem (i, j);
+	}
+      else
+	retval = b;
+
+      FloatComplexMatrix atmp = *this;
+      FloatComplex *tmp_data = atmp.fortran_vec ();
+
+      FloatComplex *pretval = retval.fortran_vec ();
+      Array<float> s (minmn);
+      float *ps = s.fortran_vec ();
+
+      // Ask ZGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<FloatComplex> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("CGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      octave_idx_type mnthr;
+      F77_FUNC (xilaenv, XILAENV) (6, F77_CONST_CHAR_ARG2 ("CGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   m, n, nrhs, -1, mnthr
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of rwork and iwork because ZGELSD in
+      // older versions of LAPACK does not return them on a query
+      // call.
+      float dminmn = static_cast<float> (minmn);
+      float dsmlsizp1 = static_cast<float> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      float tmp = log2 (dminmn / dsmlsizp1);
+#else
+      float tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type lrwork = minmn*(10 + 2*smlsiz + 8*nlvl)
+	+ 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
+      if (lrwork < 1)
+	lrwork = 1;
+      Array<float> rwork (lrwork);
+      float *prwork = rwork.fortran_vec ();
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (cgelsd, CGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, prwork, piwork, info));
+
+      // The workspace query is broken in at least LAPACK 3.0.0
+      // through 3.1.1 when n >= mnthr.  The obtuse formula below
+      // should provide sufficient workspace for ZGELSD to operate
+      // efficiently.
+      if (n >= mnthr)
+	{
+	  octave_idx_type addend = m;
+
+	  if (2*m-4 > addend)
+	    addend = 2*m-4;
+
+	  if (nrhs > addend)
+	    addend = nrhs;
+
+	  if (n-3*m > addend)
+	    addend = n-3*m;
+
+	  const octave_idx_type lworkaround = 4*m + m*m + addend;
+
+	  if (std::real (work(0)) < lworkaround)
+	    work(0) = lworkaround;
+	}
+      else if (m >= n)
+	{
+	  octave_idx_type lworkaround = 2*m + m*nrhs;
+
+	  if (std::real (work(0)) < lworkaround)
+	    work(0) = lworkaround;
+	}
+
+      lwork = static_cast<octave_idx_type> (std::real (work(0)));
+      work.resize (lwork);
+
+      F77_XFCN (cgelsd, CGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 prwork, piwork, info));
+
+      if (rank < minmn)
+	(*current_liboctave_warning_handler) 
+	  ("zgelsd: rank deficient %dx%d matrix, rank = %d, tol = %e",
+	   m, n, rank, rcon);
+
+      if (s.elem (0) == 0.0)
+	rcon = 0.0;
+      else
+	rcon = s.elem (minmn - 1) / s.elem (0);
+
+      retval.resize (n, nrhs);
+    }
+
+  return retval;
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatColumnVector& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (FloatComplexColumnVector (b), info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatColumnVector& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (FloatComplexColumnVector (b), info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatColumnVector& b, octave_idx_type& info, 
+			octave_idx_type& rank) const
+{
+  float rcon;
+  return lssolve (FloatComplexColumnVector (b), info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatColumnVector& b, octave_idx_type& info, 
+			octave_idx_type& rank, float& rcon) const
+{
+  return lssolve (FloatComplexColumnVector (b), info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatComplexColumnVector& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatComplexColumnVector& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatComplexColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank) const
+{
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::lssolve (const FloatComplexColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank, float& rcon) const
+{
+  FloatComplexColumnVector retval;
+
+  octave_idx_type nrhs = 1;
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.length ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m == 0 || n == 0 || b.cols () == 0)
+    retval = FloatComplexColumnVector (n, FloatComplex (0.0, 0.0));
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+
+      if (m != n)
+	{
+	  retval = FloatComplexColumnVector (maxmn);
+
+	  for (octave_idx_type i = 0; i < m; i++)
+	    retval.elem (i) = b.elem (i);
+	}
+      else
+	retval = b;
+
+      FloatComplexMatrix atmp = *this;
+      FloatComplex *tmp_data = atmp.fortran_vec ();
+
+      FloatComplex *pretval = retval.fortran_vec ();
+      Array<float> s (minmn);
+      float *ps = s.fortran_vec ();
+
+      // Ask ZGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<FloatComplex> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("CGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of rwork and iwork because ZGELSD in
+      // older versions of LAPACK does not return them on a query
+      // call.
+      float dminmn = static_cast<float> (minmn);
+      float dsmlsizp1 = static_cast<float> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      float tmp = log2 (dminmn / dsmlsizp1);
+#else
+      float tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type lrwork = minmn*(10 + 2*smlsiz + 8*nlvl)
+	+ 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
+      if (lrwork < 1)
+	lrwork = 1;
+      Array<float> rwork (lrwork);
+      float *prwork = rwork.fortran_vec ();
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (cgelsd, CGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, prwork, piwork, info));
+
+      lwork = static_cast<octave_idx_type> (std::real (work(0)));
+      work.resize (lwork);
+      rwork.resize (static_cast<octave_idx_type> (rwork(0)));
+      iwork.resize (iwork(0));
+
+      F77_XFCN (cgelsd, CGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 prwork, piwork, info));
+
+      if (rank < minmn)
+	{
+	  if (rank < minmn)
+	    (*current_liboctave_warning_handler) 
+	      ("zgelsd: rank deficient %dx%d matrix, rank = %d, tol = %e",
+	       m, n, rank, rcon);
+
+	  if (s.elem (0) == 0.0)
+	    rcon = 0.0;
+	  else
+	    rcon = s.elem (minmn - 1) / s.elem (0);
+
+	  retval.resize (n, nrhs);
+	}
+    }
+
+  return retval;
+}
+
+// column vector by row vector -> matrix operations
+
+FloatComplexMatrix
+operator * (const FloatColumnVector& v, const FloatComplexRowVector& a)
+{
+  FloatComplexColumnVector tmp (v);
+  return tmp * a;
+}
+
+FloatComplexMatrix
+operator * (const FloatComplexColumnVector& a, const FloatRowVector& b)
+{
+  FloatComplexRowVector tmp (b);
+  return a * tmp;
+}
+
+FloatComplexMatrix
+operator * (const FloatComplexColumnVector& v, const FloatComplexRowVector& a)
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type len = v.length ();
+
+  if (len != 0)
+    {
+      octave_idx_type a_len = a.length ();
+
+      retval = FloatComplexMatrix (len, a_len);
+      FloatComplex *c = retval.fortran_vec ();
+
+      F77_XFCN (cgemm, CGEMM, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 ("N", 1),
+			       len, a_len, 1, 1.0, v.data (), len,
+			       a.data (), 1, 0.0, c, len
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+    }
+
+  return retval;
+}
+
+// matrix by diagonal matrix -> matrix operations
+
+FloatComplexMatrix&
+FloatComplexMatrix::operator += (const FloatDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::operator -= (const FloatDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::operator += (const FloatComplexDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::operator -= (const FloatComplexDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = rows ();
+  octave_idx_type a_nc = cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+// matrix by matrix -> matrix operations
+
+FloatComplexMatrix&
+FloatComplexMatrix::operator += (const FloatMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  if (nr == 0 || nc == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), length ());
+  return *this;
+}
+
+FloatComplexMatrix&
+FloatComplexMatrix::operator -= (const FloatMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  if (nr == 0 || nc == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_subtract2 (d, a.data (), length ());
+  return *this;
+}
+
+// unary operations
+
+boolMatrix
+FloatComplexMatrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  boolMatrix b (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      b.elem (i, j) = elem (i, j) == static_cast<float> (0.0);
+
+  return b;
+}
+
+// other operations
+
+FloatMatrix
+FloatComplexMatrix::map (dmapper fcn) const
+{
+  return MArray2<FloatComplex>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::map (cmapper fcn) const
+{
+  return MArray2<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
+}
+
+boolMatrix
+FloatComplexMatrix::map (bmapper fcn) const
+{
+  return MArray2<FloatComplex>::map<bool> (func_ptr (fcn));
+}
+
+bool
+FloatComplexMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	FloatComplex val = elem (i, j);
+	if (xisnan (val))
+	  return true;
+      }
+
+  return false;
+}
+
+bool
+FloatComplexMatrix::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	FloatComplex val = elem (i, j);
+	if (xisinf (val) || xisnan (val))
+	  return true;
+      }
+
+  return false;
+}
+
+// Return true if no elements have imaginary components.
+
+bool
+FloatComplexMatrix::all_elements_are_real (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  float ip = std::imag (elem (i, j));
+
+	  if (ip != 0.0 || lo_ieee_signbit (ip))
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of CM has a non-integer real or
+// imaginary part.  Also extract the largest and smallest (real or
+// imaginary) values and return them in MAX_VAL and MIN_VAL. 
+
+bool
+FloatComplexMatrix::all_integers (float& max_val, float& min_val) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      FloatComplex val = elem (0, 0);
+
+      float r_val = std::real (val);
+      float i_val = std::imag (val);
+
+      max_val = r_val;
+      min_val = r_val;
+
+      if (i_val > max_val)
+	max_val = i_val;
+
+      if (i_val < max_val)
+	min_val = i_val;
+    }
+  else
+    return false;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	FloatComplex val = elem (i, j);
+
+	float r_val = std::real (val);
+	float i_val = std::imag (val);
+
+	if (r_val > max_val)
+	  max_val = r_val;
+
+	if (i_val > max_val)
+	  max_val = i_val;
+
+	if (r_val < min_val)
+	  min_val = r_val;
+
+	if (i_val < min_val)
+	  min_val = i_val;
+
+	if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
+	  return false;
+      }
+
+  return true;
+}
+
+bool
+FloatComplexMatrix::too_large_for_float (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	FloatComplex val = elem (i, j);
+
+	float r_val = std::real (val);
+	float i_val = std::imag (val);
+
+	if ((! (xisnan (r_val) || xisinf (r_val))
+	     && fabs (r_val) > FLT_MAX)
+	    || (! (xisnan (i_val) || xisinf (i_val))
+		&& fabs (i_val) > FLT_MAX))
+	  return true;
+      }
+
+  return false;
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+boolMatrix
+FloatComplexMatrix::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, FloatComplex> (*this, dim, mx_inline_all);
+}
+
+boolMatrix
+FloatComplexMatrix::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, FloatComplex> (*this, dim, mx_inline_any);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::cumprod (int dim) const
+{
+  return do_mx_cum_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_cumprod);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::cumsum (int dim) const
+{
+  return do_mx_cum_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_cumsum);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::prod (int dim) const
+{
+  return do_mx_red_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_prod);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::sum (int dim) const
+{
+  return do_mx_red_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_sum);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::sumsq (int dim) const
+{
+  return do_mx_red_op<FloatMatrix, FloatComplex> (*this, dim, mx_inline_sumsq);
+}
+
+FloatMatrix FloatComplexMatrix::abs (void) const
+{
+  return FloatMatrix (mx_inline_cabs_dup (data (), length ()),
+                      rows (), cols ());
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::diag (octave_idx_type k) const
+{
+  return MArray2<FloatComplex>::diag (k);
+}
+
+bool
+FloatComplexMatrix::row_is_real_only (octave_idx_type i) const
+{
+  bool retval = true;
+
+  octave_idx_type nc = columns ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      if (std::imag (elem (i, j)) != 0.0)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;	      
+}
+
+bool
+FloatComplexMatrix::column_is_real_only (octave_idx_type j) const
+{
+  bool retval = true;
+
+  octave_idx_type nr = rows ();
+
+  for (octave_idx_type i = 0; i < nr; i++)
+    {
+      if (std::imag (elem (i, j)) != 0.0)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;	      
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::row_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_min (dummy_idx);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::row_min (Array<octave_idx_type>& idx_arg) const
+{
+  FloatComplexColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  bool real_only = row_is_real_only (i);
+
+	  octave_idx_type idx_j;
+
+	  FloatComplex tmp_min;
+
+	  float abs_min = octave_Float_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_min = elem (i, idx_j);
+
+	      if (! xisnan (tmp_min))
+		{
+		  abs_min = real_only ? std::real (tmp_min) : std::abs (tmp_min);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      FloatComplex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      float abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp < abs_min)
+		{
+		  idx_j = j;
+		  tmp_min = tmp;
+		  abs_min = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_min))
+	    {
+	      result.elem (i) = FloatComplex_NaN_result;
+	      idx_arg.elem (i) = 0;
+	    }
+	  else
+	    {
+	      result.elem (i) = tmp_min;
+	      idx_arg.elem (i) = idx_j;
+	    }
+        }
+    }
+
+  return result;
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::row_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_max (dummy_idx);
+}
+
+FloatComplexColumnVector
+FloatComplexMatrix::row_max (Array<octave_idx_type>& idx_arg) const
+{
+  FloatComplexColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  bool real_only = row_is_real_only (i);
+
+	  octave_idx_type idx_j;
+
+	  FloatComplex tmp_max;
+
+	  float abs_max = octave_Float_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_max = elem (i, idx_j);
+
+	      if (! xisnan (tmp_max))
+		{
+		  abs_max = real_only ? std::real (tmp_max) : std::abs (tmp_max);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      FloatComplex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      float abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp > abs_max)
+		{
+		  idx_j = j;
+		  tmp_max = tmp;
+		  abs_max = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_max))
+	    {
+	      result.elem (i) = FloatComplex_NaN_result;
+	      idx_arg.elem (i) = 0;
+	    }
+	  else
+	    {
+	      result.elem (i) = tmp_max;
+	      idx_arg.elem (i) = idx_j;
+	    }
+        }
+    }
+
+  return result;
+}
+
+FloatComplexRowVector
+FloatComplexMatrix::column_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_min (dummy_idx);
+}
+
+FloatComplexRowVector
+FloatComplexMatrix::column_min (Array<octave_idx_type>& idx_arg) const
+{
+  FloatComplexRowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  bool real_only = column_is_real_only (j);
+
+	  octave_idx_type idx_i;
+
+	  FloatComplex tmp_min;
+
+	  float abs_min = octave_Float_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_min = elem (idx_i, j);
+
+	      if (! xisnan (tmp_min))
+		{
+		  abs_min = real_only ? std::real (tmp_min) : std::abs (tmp_min);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      FloatComplex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      float abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp < abs_min)
+		{
+		  idx_i = i;
+		  tmp_min = tmp;
+		  abs_min = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_min))
+	    {
+	      result.elem (j) = FloatComplex_NaN_result;
+	      idx_arg.elem (j) = 0;
+	    }
+	  else
+	    {
+	      result.elem (j) = tmp_min;
+	      idx_arg.elem (j) = idx_i;
+	    }
+        }
+    }
+
+  return result;
+}
+
+FloatComplexRowVector
+FloatComplexMatrix::column_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_max (dummy_idx);
+}
+
+FloatComplexRowVector
+FloatComplexMatrix::column_max (Array<octave_idx_type>& idx_arg) const
+{
+  FloatComplexRowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  bool real_only = column_is_real_only (j);
+
+	  octave_idx_type idx_i;
+
+	  FloatComplex tmp_max;
+
+	  float abs_max = octave_Float_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_max = elem (idx_i, j);
+
+	      if (! xisnan (tmp_max))
+		{
+		  abs_max = real_only ? std::real (tmp_max) : std::abs (tmp_max);
+		  break;
+		}
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      FloatComplex tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+
+	      float abs_tmp = real_only ? std::real (tmp) : std::abs (tmp);
+
+	      if (abs_tmp > abs_max)
+		{
+		  idx_i = i;
+		  tmp_max = tmp;
+		  abs_max = abs_tmp;
+		}
+	    }
+
+	  if (xisnan (tmp_max))
+	    {
+	      result.elem (j) = FloatComplex_NaN_result;
+	      idx_arg.elem (j) = 0;
+	    }
+	  else
+	    {
+	      result.elem (j) = tmp_max;
+	      idx_arg.elem (j) = idx_i;
+	    }
+        }
+    }
+
+  return result;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const FloatComplexMatrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  os << " ";
+	  octave_write_complex (os, a.elem (i, j));
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatComplexMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      FloatComplex tmp;
+      for (octave_idx_type i = 0; i < nr; i++)
+	for (octave_idx_type j = 0; j < nc; j++)
+	  {
+	    tmp = octave_read_complex (is);
+	    if (is)
+	      a.elem (i, j) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+done:
+
+  return is;
+}
+
+FloatComplexMatrix
+Givens (const FloatComplex& x, const FloatComplex& y)
+{
+  float cc;
+  FloatComplex cs, temp_r;
+ 
+  F77_FUNC (clartg, CLARTG) (x, y, cc, cs, temp_r);
+
+  FloatComplexMatrix g (2, 2);
+
+  g.elem (0, 0) = cc;
+  g.elem (1, 1) = cc;
+  g.elem (0, 1) = cs;
+  g.elem (1, 0) = -conj (cs);
+
+  return g;
+}
+
+FloatComplexMatrix
+Sylvester (const FloatComplexMatrix& a, const FloatComplexMatrix& b,
+	   const FloatComplexMatrix& c)
+{
+  FloatComplexMatrix retval;
+
+  // FIXME -- need to check that a, b, and c are all the same
+  // size.
+
+  // Compute Schur decompositions
+
+  FloatComplexSCHUR as (a, "U");
+  FloatComplexSCHUR bs (b, "U");
+  
+  // Transform c to new coordinates.
+
+  FloatComplexMatrix ua = as.unitary_matrix ();
+  FloatComplexMatrix sch_a = as.schur_matrix ();
+
+  FloatComplexMatrix ub = bs.unitary_matrix ();
+  FloatComplexMatrix sch_b = bs.schur_matrix ();
+  
+  FloatComplexMatrix cx = ua.hermitian () * c * ub;
+
+  // Solve the sylvester equation, back-transform, and return the
+  // solution.
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type b_nr = b.rows ();
+
+  float scale;
+  octave_idx_type info;
+
+  FloatComplex *pa = sch_a.fortran_vec ();
+  FloatComplex *pb = sch_b.fortran_vec ();
+  FloatComplex *px = cx.fortran_vec ();
+  
+  F77_XFCN (ctrsyl, CTRSYL, (F77_CONST_CHAR_ARG2 ("N", 1),
+			     F77_CONST_CHAR_ARG2 ("N", 1),
+			     1, a_nr, b_nr, pa, a_nr, pb,
+			     b_nr, px, a_nr, scale, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  // FIXME -- check info?
+
+  retval = -ua * cx * ub.hermitian ();
+
+  return retval;
+}
+
+FloatComplexMatrix
+operator * (const FloatComplexMatrix& m, const FloatMatrix& a)
+{
+  FloatComplexMatrix tmp (a);
+  return m * tmp;
+}
+
+FloatComplexMatrix
+operator * (const FloatMatrix& m, const FloatComplexMatrix& a)
+{
+  FloatComplexMatrix tmp (m);
+  return tmp * a;
+}
+
+/* Simple Dot Product, Matrix-Vector and Matrix-Matrix Unit tests
+%!assert(single([1+i 2+i 3+i]) * single([ 4+i ; 5+i ; 6+i]), single(29+21i), 5e-7)
+%!assert(single([1+i 2+i ; 3+i 4+i ]) * single([5+i ; 6+i]), single([15 + 14i ; 37 + 18i]), 5e-7)
+%!assert(single([1+i 2+i ; 3+i 4+i ]) * single([5+i 6+i ; 7+i 8+i]), single([17 + 15i 20 + 17i; 41 + 19i 48 + 21i]), 5e-7)
+%!assert(single([1 i])*single([i 0])', single(-i));
+*/
+
+/* Test some simple identities
+%!shared M, cv, rv
+%! M = single(randn(10,10))+i*single(rand(10,10));
+%! cv = single(randn(10,1))+i*single(rand(10,1));
+%! rv = single(randn(1,10))+i*single(rand(1,10));
+%!assert([M*cv,M*cv],M*[cv,cv],5e-6)
+%!assert([M.'*cv,M.'*cv],M.'*[cv,cv],5e-6)
+%!assert([M'*cv,M'*cv],M'*[cv,cv],5e-6)
+%!assert([rv*M;rv*M],[rv;rv]*M,5e-6)
+%!assert([rv*M.';rv*M.'],[rv;rv]*M.',5e-6)
+%!assert([rv*M';rv*M'],[rv;rv]*M',5e-6)
+%!assert(2*rv*cv,[rv,rv]*[cv;cv],5e-6)
+*/
+
+static const char *
+get_blas_trans_arg (bool trans, bool conj)
+{
+  static char blas_notrans = 'N', blas_trans = 'T', blas_conj_trans = 'C';
+  return trans ? (conj ? &blas_conj_trans : &blas_trans) : &blas_notrans;
+}
+
+// the general GEMM operation
+
+FloatComplexMatrix
+xgemm (bool transa, bool conja, const FloatComplexMatrix& a, 
+       bool transb, bool conjb, const FloatComplexMatrix& b)
+{
+  FloatComplexMatrix retval;
+
+  // conjugacy is ignored if no transpose
+  conja = conja && transa;
+  conjb = conjb && transb;
+
+  octave_idx_type a_nr = transa ? a.cols () : a.rows ();
+  octave_idx_type a_nc = transa ? a.rows () : a.cols ();
+
+  octave_idx_type b_nr = transb ? b.cols () : b.rows ();
+  octave_idx_type b_nc = transb ? b.rows () : b.cols ();
+
+  if (a_nc != b_nr)
+    gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+  else
+    {
+      if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+	retval = FloatComplexMatrix (a_nr, b_nc, 0.0);
+      else if (a.data () == b.data () && a_nr == b_nc && transa != transb)
+        {
+	  octave_idx_type lda = a.rows ();
+
+          retval = FloatComplexMatrix (a_nr, b_nc);
+	  FloatComplex *c = retval.fortran_vec ();
+
+          const char *ctransa = get_blas_trans_arg (transa, conja);
+          if (conja || conjb)
+            {
+              F77_XFCN (cherk, CHERK, (F77_CONST_CHAR_ARG2 ("U", 1),
+                                       F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                       a_nr, a_nc, 1.0,
+                                       a.data (), lda, 0.0, c, a_nr
+                                       F77_CHAR_ARG_LEN (1)
+                                       F77_CHAR_ARG_LEN (1)));
+              for (int j = 0; j < a_nr; j++)
+                for (int i = 0; i < j; i++)
+                  retval.xelem (j,i) = std::conj (retval.xelem (i,j));
+            }
+          else
+            {
+              F77_XFCN (csyrk, CSYRK, (F77_CONST_CHAR_ARG2 ("U", 1),
+                                       F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                       a_nr, a_nc, 1.0,
+                                       a.data (), lda, 0.0, c, a_nr
+                                       F77_CHAR_ARG_LEN (1)
+                                       F77_CHAR_ARG_LEN (1)));
+              for (int j = 0; j < a_nr; j++)
+                for (int i = 0; i < j; i++)
+                  retval.xelem (j,i) = retval.xelem (i,j);
+
+            }
+
+        }
+      else
+	{
+	  octave_idx_type lda = a.rows (), tda = a.cols ();
+	  octave_idx_type ldb = b.rows (), tdb = b.cols ();
+
+	  retval = FloatComplexMatrix (a_nr, b_nc);
+	  FloatComplex *c = retval.fortran_vec ();
+
+	  if (b_nc == 1 && a_nr == 1)
+	    {
+              if (conja == conjb)
+                {
+                  F77_FUNC (xcdotu, XCDOTU) (a_nc, a.data (), 1, b.data (), 1, *c);
+                  if (conja) *c = std::conj (*c);
+                }
+              else if (conja)
+                  F77_FUNC (xcdotc, XCDOTC) (a_nc, a.data (), 1, b.data (), 1, *c);
+              else
+                  F77_FUNC (xcdotc, XCDOTC) (a_nc, b.data (), 1, a.data (), 1, *c);
+            }
+          else if (b_nc == 1 && ! conjb)
+            {
+              const char *ctransa = get_blas_trans_arg (transa, conja);
+              F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                       lda, tda, 1.0,  a.data (), lda,
+                                       b.data (), 1, 0.0, c, 1
+                                       F77_CHAR_ARG_LEN (1)));
+            }
+          else if (a_nr == 1 && ! conja && ! conjb)
+            {
+              const char *crevtransb = get_blas_trans_arg (! transb, conjb);
+              F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 (crevtransb, 1),
+                                       ldb, tdb, 1.0,  b.data (), ldb,
+                                       a.data (), 1, 0.0, c, 1
+                                       F77_CHAR_ARG_LEN (1)));
+            }
+	  else
+	    {
+              const char *ctransa = get_blas_trans_arg (transa, conja);
+              const char *ctransb = get_blas_trans_arg (transb, conjb);
+	      F77_XFCN (cgemm, CGEMM, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+				       F77_CONST_CHAR_ARG2 (ctransb, 1),
+				       a_nr, b_nc, a_nc, 1.0, a.data (),
+				       lda, b.data (), ldb, 0.0, c, a_nr
+				       F77_CHAR_ARG_LEN (1)
+				       F77_CHAR_ARG_LEN (1)));
+	    }
+	}
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+operator * (const FloatComplexMatrix& a, const FloatComplexMatrix& b)
+{
+  return xgemm (false, false, a, false, false, b);
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nr == 0 || nc == 0) \
+    return T (nr, nc);
+
+FloatComplexMatrix
+min (const FloatComplex& c, const FloatComplexMatrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatComplexMatrix);
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (c, m (i, j));
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+min (const FloatComplexMatrix& m, const FloatComplex& c)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatComplexMatrix);
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (m (i, j), c);
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+min (const FloatComplexMatrix& a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return FloatComplexMatrix ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatComplexMatrix);
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      int columns_are_real_only = 1;
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+	    {
+	      columns_are_real_only = 0;
+	      break;
+	    }
+	}
+
+      if (columns_are_real_only)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    result (i, j) = xmin (std::real (a (i, j)), std::real (b (i, j)));
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = xmin (a (i, j), b (i, j));
+	    }
+	}
+    }
+
+  return result;
+}
+
+FloatComplexMatrix
+max (const FloatComplex& c, const FloatComplexMatrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatComplexMatrix);
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (c, m (i, j));
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+max (const FloatComplexMatrix& m, const FloatComplex& c)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatComplexMatrix);
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (m (i, j), c);
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+max (const FloatComplexMatrix& a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return FloatComplexMatrix ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatComplexMatrix);
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      int columns_are_real_only = 1;
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+	    {
+	      columns_are_real_only = 0;
+	      break;
+	    }
+	}
+
+      if (columns_are_real_only)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = xmax (std::real (a (i, j)), std::real (b (i, j)));
+	    }
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = xmax (a (i, j), b (i, j));
+	    }
+	}
+    }
+
+  return result;
+}
+
+MS_CMP_OPS(FloatComplexMatrix, std::real, FloatComplex, std::real)
+MS_BOOL_OPS(FloatComplexMatrix, FloatComplex, static_cast<float> (0.0))
+
+SM_CMP_OPS(FloatComplex, std::real, FloatComplexMatrix, std::real)
+SM_BOOL_OPS(FloatComplex, FloatComplexMatrix, static_cast<float> (0.0))
+
+MM_CMP_OPS(FloatComplexMatrix, std::real, FloatComplexMatrix, std::real)
+MM_BOOL_OPS(FloatComplexMatrix, FloatComplexMatrix, static_cast<float> (0.0))
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCMatrix.h b/liboctave/fCMatrix.h
new file mode 100644
index 0000000..a9766f9
--- /dev/null
+++ b/liboctave/fCMatrix.h
@@ -0,0 +1,428 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexMatrix_h)
+#define octave_FloatComplexMatrix_h 1
+
+#include "MArray2.h"
+#include "MDiagArray2.h"
+#include "MatrixType.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+#include "oct-cmplx.h"
+#include "DET.h"
+
+class
+OCTAVE_API
+FloatComplexMatrix : public MArray2<FloatComplex>
+{
+public:
+ 
+  typedef void (*solve_singularity_handler) (float rcon);
+
+  FloatComplexMatrix (void) : MArray2<FloatComplex> () { }
+
+  FloatComplexMatrix (octave_idx_type r, octave_idx_type c) : MArray2<FloatComplex> (r, c) { }
+
+  FloatComplexMatrix (octave_idx_type r, octave_idx_type c, const FloatComplex& val)
+    : MArray2<FloatComplex> (r, c, val) { }
+
+  FloatComplexMatrix (const dim_vector& dv) : MArray2<FloatComplex> (dv) { }
+
+  FloatComplexMatrix (const dim_vector& dv, const FloatComplex& val) 
+    : MArray2<FloatComplex> (dv, val) { }
+
+  FloatComplexMatrix (const FloatComplexMatrix& a) : MArray2<FloatComplex> (a) { }
+
+  template <class U>
+  FloatComplexMatrix (const MArray2<U>& a) : MArray2<FloatComplex> (a) { }
+
+  template <class U>
+  FloatComplexMatrix (const Array2<U>& a) : MArray2<FloatComplex> (a) { }
+
+  explicit FloatComplexMatrix (const FloatMatrix& a);
+
+  explicit FloatComplexMatrix (const FloatRowVector& rv);
+
+  explicit FloatComplexMatrix (const FloatColumnVector& cv);
+
+  explicit FloatComplexMatrix (const FloatDiagMatrix& a);
+
+  explicit FloatComplexMatrix (const FloatComplexRowVector& rv);
+
+  explicit FloatComplexMatrix (const FloatComplexColumnVector& cv);
+
+  explicit FloatComplexMatrix (const FloatComplexDiagMatrix& a);
+
+  explicit FloatComplexMatrix (const boolMatrix& a);
+
+  explicit FloatComplexMatrix (const charMatrix& a);
+
+  FloatComplexMatrix& operator = (const FloatComplexMatrix& a)
+    {
+      MArray2<FloatComplex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatComplexMatrix& a) const;
+  bool operator != (const FloatComplexMatrix& a) const;
+
+  bool is_hermitian (void) const;
+
+  // destructive insert/delete/reorder operations
+
+  FloatComplexMatrix& insert (const FloatMatrix& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexMatrix& insert (const FloatRowVector& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexMatrix& insert (const FloatColumnVector& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexMatrix& insert (const FloatDiagMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  FloatComplexMatrix& insert (const FloatComplexMatrix& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexMatrix& insert (const FloatComplexRowVector& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexMatrix& insert (const FloatComplexColumnVector& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexMatrix& insert (const FloatComplexDiagMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  FloatComplexMatrix& fill (float val);
+  FloatComplexMatrix& fill (const FloatComplex& val);
+  FloatComplexMatrix& fill (float val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+  FloatComplexMatrix& fill (const FloatComplex& val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+
+  FloatComplexMatrix append (const FloatMatrix& a) const;
+  FloatComplexMatrix append (const FloatRowVector& a) const;
+  FloatComplexMatrix append (const FloatColumnVector& a) const;
+  FloatComplexMatrix append (const FloatDiagMatrix& a) const;
+
+  FloatComplexMatrix append (const FloatComplexMatrix& a) const;
+  FloatComplexMatrix append (const FloatComplexRowVector& a) const;
+  FloatComplexMatrix append (const FloatComplexColumnVector& a) const;
+  FloatComplexMatrix append (const FloatComplexDiagMatrix& a) const;
+
+  FloatComplexMatrix stack (const FloatMatrix& a) const;
+  FloatComplexMatrix stack (const FloatRowVector& a) const;
+  FloatComplexMatrix stack (const FloatColumnVector& a) const;
+  FloatComplexMatrix stack (const FloatDiagMatrix& a) const;
+
+  FloatComplexMatrix stack (const FloatComplexMatrix& a) const;
+  FloatComplexMatrix stack (const FloatComplexRowVector& a) const;
+  FloatComplexMatrix stack (const FloatComplexColumnVector& a) const;
+  FloatComplexMatrix stack (const FloatComplexDiagMatrix& a) const;
+
+  FloatComplexMatrix hermitian (void) const
+    { return MArray2<FloatComplex>::hermitian (std::conj); }
+  FloatComplexMatrix transpose (void) const
+    { return MArray2<FloatComplex>::transpose (); }
+
+  friend OCTAVE_API FloatComplexMatrix conj (const FloatComplexMatrix& a);
+
+  // resize is the destructive equivalent for this one
+
+  FloatComplexMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  FloatComplexMatrix extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const;
+
+  // extract row or column i.
+
+  FloatComplexRowVector row (octave_idx_type i) const;
+
+  FloatComplexColumnVector column (octave_idx_type i) const;
+
+private:
+  FloatComplexMatrix tinverse (MatrixType &mattype, octave_idx_type& info,
+			  float& rcon, int force, int calc_cond) const;
+
+  FloatComplexMatrix finverse (MatrixType &mattype, octave_idx_type& info,
+			  float& rcon, int force, int calc_cond) const;
+
+public:
+  FloatComplexMatrix inverse (void) const;
+  FloatComplexMatrix inverse (octave_idx_type& info) const;
+  FloatComplexMatrix inverse (octave_idx_type& info, float& rcon, int force = 0, 
+			 int calc_cond = 1) const;
+
+  FloatComplexMatrix inverse (MatrixType &mattype) const;
+  FloatComplexMatrix inverse (MatrixType &mattype, octave_idx_type& info) const;
+  FloatComplexMatrix inverse (MatrixType &mattype, octave_idx_type& info,
+			 float& rcon, int force = 0, 
+			 int calc_cond = 1) const;
+
+  FloatComplexMatrix pseudo_inverse (float tol = 0.0) const;
+
+  FloatComplexMatrix fourier (void) const;
+  FloatComplexMatrix ifourier (void) const;
+
+  FloatComplexMatrix fourier2d (void) const;
+  FloatComplexMatrix ifourier2d (void) const;
+
+  FloatComplexDET determinant (void) const;
+  FloatComplexDET determinant (octave_idx_type& info) const;
+  FloatComplexDET determinant (octave_idx_type& info, float& rcon, int calc_cond = 1) const;
+  FloatComplexDET determinant (MatrixType &mattype, octave_idx_type& info, 
+                               float& rcon, int calc_cond = 1) const;
+
+  float rcond (void) const;
+  float rcond (MatrixType &mattype) const;
+
+private:
+  // Upper triangular matrix solvers
+  FloatComplexMatrix utsolve (MatrixType &typ, const FloatComplexMatrix& b,
+		  octave_idx_type& info, float& rcon, 
+		  solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Lower triangular matrix solvers
+  FloatComplexMatrix ltsolve (MatrixType &typ, const FloatComplexMatrix& b,
+		  octave_idx_type& info, float& rcon, 
+		  solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Full matrix solvers (umfpack/cholesky)
+  FloatComplexMatrix fsolve (MatrixType &typ, const FloatComplexMatrix& b,
+		 octave_idx_type& info, float& rcon, 
+		 solve_singularity_handler sing_handler,
+		 bool calc_cond = false) const;
+
+public:
+  // Generic interface to solver with no probing of type
+  FloatComplexMatrix solve (MatrixType &typ, const FloatMatrix& b) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatMatrix& b, 
+		       octave_idx_type& info) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatMatrix& b, 
+		       octave_idx_type& info, float& rcon) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info,
+		       float& rcon, solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		       octave_idx_type& info) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		       octave_idx_type& info, float& rcon) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		       octave_idx_type& info, float& rcon,
+		       solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatColumnVector& b) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatColumnVector& b, 
+			     octave_idx_type& info) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatColumnVector& b, 
+			     octave_idx_type& info, float& rcon) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatColumnVector& b, 
+			     octave_idx_type& info, float& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  FloatComplexColumnVector solve (MatrixType &typ, 
+			     const FloatComplexColumnVector& b) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+			     octave_idx_type& info, float& rcon) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+			     octave_idx_type& info, float& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  // Generic interface to solver with probing of type
+  FloatComplexMatrix solve (const FloatMatrix& b) const;
+  FloatComplexMatrix solve (const FloatMatrix& b, octave_idx_type& info) const;
+  FloatComplexMatrix solve (const FloatMatrix& b, octave_idx_type& info, float& rcon) const;
+  FloatComplexMatrix solve (const FloatMatrix& b, octave_idx_type& info, float& rcon,
+		       solve_singularity_handler sing_handler) const;
+
+  FloatComplexMatrix solve (const FloatComplexMatrix& b) const;
+  FloatComplexMatrix solve (const FloatComplexMatrix& b, octave_idx_type& info) const;
+  FloatComplexMatrix solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon) const;
+  FloatComplexMatrix solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon,
+		       solve_singularity_handler sing_handler) const;
+
+  FloatComplexColumnVector solve (const FloatColumnVector& b) const;
+  FloatComplexColumnVector solve (const FloatColumnVector& b, octave_idx_type& info) const;
+  FloatComplexColumnVector solve (const FloatColumnVector& b, octave_idx_type& info,
+			     float& rcon) const;
+  FloatComplexColumnVector solve (const FloatColumnVector& b, octave_idx_type& info, float& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b) const;
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b, octave_idx_type& info) const;
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b, octave_idx_type& info,
+			     float& rcon) const;
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b, octave_idx_type& info,
+			     float& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  FloatComplexMatrix lssolve (const FloatMatrix& b) const;
+  FloatComplexMatrix lssolve (const FloatMatrix& b, octave_idx_type& info) const;
+  FloatComplexMatrix lssolve (const FloatMatrix& b, octave_idx_type& info, 
+			 octave_idx_type& rank) const;
+  FloatComplexMatrix lssolve (const FloatMatrix& b, octave_idx_type& info, 
+			 octave_idx_type& rank, float& rcon) const;
+
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b) const;
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b, octave_idx_type& info) const;
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank) const;
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank, float& rcon) const;
+
+  FloatComplexColumnVector lssolve (const FloatColumnVector& b) const;
+  FloatComplexColumnVector lssolve (const FloatColumnVector& b,
+			       octave_idx_type& info) const;
+  FloatComplexColumnVector lssolve (const FloatColumnVector& b, octave_idx_type& info,
+			       octave_idx_type& rank) const;
+  FloatComplexColumnVector lssolve (const FloatColumnVector& b, octave_idx_type& info,
+			       octave_idx_type& rank, float& rcon) const;
+
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b) const;
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b,
+			       octave_idx_type& info) const;
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b,
+			       octave_idx_type& info,
+			       octave_idx_type& rank) const;
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b,
+			       octave_idx_type& info,
+			       octave_idx_type& rank, float& rcon) const;
+
+  // matrix by diagonal matrix -> matrix operations
+
+  FloatComplexMatrix& operator += (const FloatDiagMatrix& a);
+  FloatComplexMatrix& operator -= (const FloatDiagMatrix& a);
+
+  FloatComplexMatrix& operator += (const FloatComplexDiagMatrix& a);
+  FloatComplexMatrix& operator -= (const FloatComplexDiagMatrix& a);
+
+  // matrix by matrix -> matrix operations
+
+  FloatComplexMatrix& operator += (const FloatMatrix& a);
+  FloatComplexMatrix& operator -= (const FloatMatrix& a);
+
+  // unary operations
+
+  boolMatrix operator ! (void) const;
+
+  // other operations
+
+  typedef float (*dmapper) (const FloatComplex&);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+  typedef bool (*bmapper) (const FloatComplex&);
+
+  FloatMatrix map (dmapper fcn) const;
+  FloatComplexMatrix map (cmapper fcn) const;
+  boolMatrix map (bmapper fcn) const;
+
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool all_elements_are_real (void) const;
+  bool all_integers (float& max_val, float& min_val) const;
+  bool too_large_for_float (void) const;
+
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+  FloatComplexMatrix cumprod (int dim = -1) const;
+  FloatComplexMatrix cumsum (int dim = -1) const;
+  FloatComplexMatrix prod (int dim = -1) const;
+  FloatComplexMatrix sum (int dim = -1) const;
+  FloatComplexMatrix sumsq (int dim = -1) const;
+  FloatMatrix abs (void) const;
+
+  FloatComplexMatrix diag (octave_idx_type k = 0) const;
+
+  bool row_is_real_only (octave_idx_type) const;
+  bool column_is_real_only (octave_idx_type) const;
+
+  FloatComplexColumnVector row_min (void) const;
+  FloatComplexColumnVector row_max (void) const;
+
+  FloatComplexColumnVector row_min (Array<octave_idx_type>& index) const; 
+  FloatComplexColumnVector row_max (Array<octave_idx_type>& index) const;
+
+  FloatComplexRowVector column_min (void) const;
+  FloatComplexRowVector column_max (void) const;
+
+  FloatComplexRowVector column_min (Array<octave_idx_type>& index) const;
+  FloatComplexRowVector column_max (Array<octave_idx_type>& index) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexMatrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatComplexMatrix& a);
+
+  static FloatComplex resize_fill_value (void) { return FloatComplex (0.0, 0.0); }
+
+private:
+
+  FloatComplexMatrix (FloatComplex *d, octave_idx_type r, octave_idx_type c) : MArray2<FloatComplex> (d, r, c) { }
+};
+
+extern OCTAVE_API FloatComplexMatrix conj (const FloatComplexMatrix& a);
+
+// column vector by row vector -> matrix operations
+
+extern OCTAVE_API FloatComplexMatrix
+operator * (const FloatColumnVector& a, const FloatComplexRowVector& b);
+
+extern OCTAVE_API FloatComplexMatrix
+operator * (const FloatComplexColumnVector& a, const FloatRowVector& b);
+
+extern OCTAVE_API FloatComplexMatrix
+operator * (const FloatComplexColumnVector& a, const FloatComplexRowVector& b);
+
+extern OCTAVE_API FloatComplexMatrix
+Givens (const FloatComplex&, const FloatComplex&);
+
+extern OCTAVE_API FloatComplexMatrix
+Sylvester (const FloatComplexMatrix&, const FloatComplexMatrix&, const FloatComplexMatrix&);
+
+extern OCTAVE_API FloatComplexMatrix 
+xgemm (bool transa, bool conja, const FloatComplexMatrix& a, 
+       bool transb, bool conjb, const FloatComplexMatrix& b);
+
+extern OCTAVE_API FloatComplexMatrix operator * (const FloatMatrix&,        const FloatComplexMatrix&);
+extern OCTAVE_API FloatComplexMatrix operator * (const FloatComplexMatrix&, const FloatMatrix&);
+extern OCTAVE_API FloatComplexMatrix operator * (const FloatComplexMatrix&, const FloatComplexMatrix&);
+
+extern OCTAVE_API FloatComplexMatrix min (const FloatComplex& c, const FloatComplexMatrix& m);
+extern OCTAVE_API FloatComplexMatrix min (const FloatComplexMatrix& m, const FloatComplex& c);
+extern OCTAVE_API FloatComplexMatrix min (const FloatComplexMatrix& a, const FloatComplexMatrix& b);
+
+extern OCTAVE_API FloatComplexMatrix max (const FloatComplex& c, const FloatComplexMatrix& m);
+extern OCTAVE_API FloatComplexMatrix max (const FloatComplexMatrix& m, const FloatComplex& c);
+extern OCTAVE_API FloatComplexMatrix max (const FloatComplexMatrix& a, const FloatComplexMatrix& b);
+
+MS_CMP_OP_DECLS (FloatComplexMatrix, FloatComplex, OCTAVE_API)
+MS_BOOL_OP_DECLS (FloatComplexMatrix, FloatComplex, OCTAVE_API)
+
+SM_CMP_OP_DECLS (FloatComplex, FloatComplexMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (FloatComplex, FloatComplexMatrix, OCTAVE_API)
+
+MM_CMP_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArray2, FloatComplexMatrix, FloatComplex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCNDArray.cc b/liboctave/fCNDArray.cc
new file mode 100644
index 0000000..7c16471
--- /dev/null
+++ b/liboctave/fCNDArray.cc
@@ -0,0 +1,1080 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <vector>
+
+#include "Array-util.h"
+#include "fCNDArray.h"
+#include "mx-base.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+#include "mx-op-defs.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#else
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cffti, CFFTI) (const octave_idx_type&, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftf, CFFTF) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftb, CFFTB) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+}
+#endif
+
+FloatComplexNDArray::FloatComplexNDArray (const charNDArray& a)
+  : MArrayN<FloatComplex> (a.dims ())
+{
+  octave_idx_type n = a.numel ();
+  for (octave_idx_type i = 0; i < n; i++)
+    xelem (i) = static_cast<unsigned char> (a(i));
+}
+
+#if defined (HAVE_FFTW3)
+FloatComplexNDArray
+FloatComplexNDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  const FloatComplex *in (fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::fft (in + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  const FloatComplex *in (fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::ifft (in + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::fourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return FloatComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  const FloatComplex *in = fortran_vec ();
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return FloatComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  const FloatComplex *in = fortran_vec ();
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::ifftNd (in + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  const FloatComplex *in (fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::fftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  const FloatComplex *in (fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+#else
+FloatComplexNDArray
+FloatComplexNDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  FloatComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (cfftf, CFFTF) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i];
+	}
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  FloatComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (cfftb, CFFTB) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i] /
+	      static_cast<float> (npts);
+	}
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::fourier2d (void) const
+{
+  dim_vector dv = dims ();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] /
+		  static_cast<float> (npts);
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] /
+		  static_cast<float> (npts);
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+#endif
+
+// unary operations
+
+boolNDArray
+FloatComplexNDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (octave_idx_type i = 0; i < length (); i++)
+    b.elem (i) = elem (i) == static_cast<float> (0.0);
+
+  return b;
+}
+
+// FIXME -- this is not quite the right thing.
+
+bool
+FloatComplexNDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      FloatComplex val = elem (i);
+      if (xisnan (val))
+	return true;
+    }
+  return false;
+}
+
+bool
+FloatComplexNDArray::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      FloatComplex val = elem (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+  return false;
+}
+
+// Return true if no elements have imaginary components.
+
+bool
+FloatComplexNDArray::all_elements_are_real (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float ip = std::imag (elem (i));
+
+      if (ip != 0.0 || lo_ieee_signbit (ip))
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of CM has a non-integer real or
+// imaginary part.  Also extract the largest and smallest (real or
+// imaginary) values and return them in MAX_VAL and MIN_VAL. 
+
+bool
+FloatComplexNDArray::all_integers (float& max_val, float& min_val) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (nel > 0)
+    {
+      FloatComplex val = elem (0);
+
+      float r_val = std::real (val);
+      float i_val = std::imag (val);
+      
+      max_val = r_val;
+      min_val = r_val;
+
+      if (i_val > max_val)
+	max_val = i_val;
+
+      if (i_val < max_val)
+	min_val = i_val;
+    }
+  else
+    return false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      FloatComplex val = elem (i);
+
+      float r_val = std::real (val);
+      float i_val = std::imag (val);
+
+      if (r_val > max_val)
+	max_val = r_val;
+
+      if (i_val > max_val)
+	max_val = i_val;
+
+      if (r_val < min_val)
+	min_val = r_val;
+
+      if (i_val < min_val)
+	min_val = i_val;
+
+      if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+FloatComplexNDArray::too_large_for_float (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      FloatComplex val = elem (i);
+
+      float r_val = std::real (val);
+      float i_val = std::imag (val);
+
+      if ((! (xisnan (r_val) || xisinf (r_val))
+	   && fabs (r_val) > FLT_MAX)
+	  || (! (xisnan (i_val) || xisinf (i_val))
+	      && fabs (i_val) > FLT_MAX))
+	return true;
+    }
+
+  return false;
+}
+
+boolNDArray
+FloatComplexNDArray::all (int dim) const
+{
+  return do_mx_red_op<boolNDArray, FloatComplex> (*this, dim, mx_inline_all);
+}
+
+boolNDArray
+FloatComplexNDArray::any (int dim) const
+{
+  return do_mx_red_op<boolNDArray, FloatComplex> (*this, dim, mx_inline_any);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cumprod (int dim) const
+{
+  return do_mx_cum_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_cumprod);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cumsum (int dim) const
+{
+  return do_mx_cum_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_cumsum);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::prod (int dim) const
+{
+  return do_mx_red_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_prod);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::sum (int dim) const
+{
+  return do_mx_red_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_sum);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::sumsq (int dim) const
+{
+  return do_mx_red_op<FloatNDArray, FloatComplex> (*this, dim, mx_inline_sumsq);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::concat (const FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  FloatComplexNDArray tmp (rb);
+  if (rb.numel () > 0)
+    insert (tmp, ra_idx);
+  return *this;
+}
+
+FloatComplexNDArray
+concat (NDArray& ra, FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  FloatComplexNDArray retval (ra);
+  if (rb.numel () > 0)
+    retval.insert (rb, ra_idx);
+  return retval;
+}
+
+static const FloatComplex FloatComplex_NaN_result (octave_Float_NaN, octave_Float_NaN);
+
+FloatComplexNDArray
+FloatComplexNDArray::max (int dim) const
+{
+  return do_mx_minmax_op<FloatComplexNDArray> (*this, dim, mx_inline_max);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_max);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::min (int dim) const
+{
+  return do_mx_minmax_op<FloatComplexNDArray> (*this, dim, mx_inline_min);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_min);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cummax (int dim) const
+{
+  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, dim, mx_inline_cummax);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_cummax);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cummin (int dim) const
+{
+  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, dim, mx_inline_cummin);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_cummin);
+}
+
+FloatNDArray
+FloatComplexNDArray::abs (void) const
+{
+  return FloatNDArray (mx_inline_cabs_dup (data (), length ()),
+                       dims ());
+}
+
+boolNDArray
+FloatComplexNDArray::isnan (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisnan));
+}
+
+boolNDArray
+FloatComplexNDArray::isinf (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisinf));
+}
+
+boolNDArray
+FloatComplexNDArray::isfinite (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xfinite));
+}
+
+FloatComplexNDArray
+conj (const FloatComplexNDArray& a)
+{
+  return FloatComplexNDArray (mx_inline_conj_dup (a.data (), a.length ()),
+                              a.dims ());
+}
+
+FloatComplexNDArray&
+FloatComplexNDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  dim_vector a_dv = a.dims ();
+  
+  int n = a_dv.length ();
+  
+  if (n == dimensions.length ())
+    {
+      Array<octave_idx_type> a_ra_idx (a_dv.length (), 0);
+      
+      a_ra_idx.elem (0) = r;
+      a_ra_idx.elem (1) = c;
+      
+      for (int i = 0; i < n; i++)
+	{
+	  if (a_ra_idx (i) < 0 || (a_ra_idx (i) + a_dv (i)) > dimensions (i))
+	    {
+	      (*current_liboctave_error_handler)
+		("Array<T>::insert: range error for insert");
+	      return *this;
+	    }
+	}
+      
+      a_ra_idx.elem (0) = 0;
+      a_ra_idx.elem (1) = 0;
+      
+      octave_idx_type n_elt = a.numel ();
+      
+      // IS make_unique () NECCESSARY HERE??
+
+      for (octave_idx_type i = 0; i < n_elt; i++)
+	{
+	  Array<octave_idx_type> ra_idx = a_ra_idx;
+	  
+	  ra_idx.elem (0) = a_ra_idx (0) + r;
+	  ra_idx.elem (1) = a_ra_idx (1) + c;
+	  
+	  elem (ra_idx) = a.elem (a_ra_idx);
+
+	  increment_index (a_ra_idx, a_dv);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::insert: invalid indexing operation");
+
+  return *this;
+}
+
+FloatComplexNDArray&
+FloatComplexNDArray::insert (const FloatComplexNDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<FloatComplex>::insert (a, r, c);
+  return *this;
+}
+
+FloatComplexNDArray&
+FloatComplexNDArray::insert (const FloatComplexNDArray& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<FloatComplex>::insert (a, ra_idx);
+  return *this;
+}
+
+FloatComplexMatrix
+FloatComplexNDArray::matrix_value (void) const
+{
+  FloatComplexMatrix retval;
+
+  if (ndims () == 2)
+      retval = FloatComplexMatrix (Array2<FloatComplex> (*this));
+  else
+    (*current_liboctave_error_handler)
+      ("invalid conversion of FloatComplexNDArray to FloatComplexMatrix");
+
+  return retval;
+}
+
+void
+FloatComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx,
+				 const dim_vector& dimensions,
+				 int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+octave_idx_type 
+FloatComplexNDArray::compute_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::diag (octave_idx_type k) const
+{
+  return MArrayN<FloatComplex>::diag (k);
+}
+
+FloatNDArray
+FloatComplexNDArray::map (dmapper fcn) const
+{
+  return MArrayN<FloatComplex>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::map (cmapper fcn) const
+{
+  return MArrayN<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
+}
+
+boolNDArray
+FloatComplexNDArray::map (bmapper fcn) const
+{
+  return MArrayN<FloatComplex>::map<bool> (func_ptr (fcn));
+}
+
+// This contains no information on the array structure !!!
+std::ostream&
+operator << (std::ostream& os, const FloatComplexNDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      os << " ";
+      octave_write_complex (os, a.elem (i));
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatComplexNDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  if (nel > 0)
+    {
+      FloatComplex tmp;
+      for (octave_idx_type i = 0; i < nel; i++)
+	  {
+	    tmp = octave_read_complex (is);
+	    if (is)
+	      a.elem (i) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+ done:
+
+  return is;
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nel == 0)	\
+    return T (dv);
+
+FloatComplexNDArray
+min (const FloatComplex& c, const FloatComplexNDArray& m)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatComplexNDArray);
+
+  FloatComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (c, m (i));
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+min (const FloatComplexNDArray& m, const FloatComplex& c)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatComplexNDArray);
+
+  FloatComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (c, m (i));
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+min (const FloatComplexNDArray& a, const FloatComplexNDArray& b)
+{
+  dim_vector dv = a.dims ();
+  int nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return FloatComplexNDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatComplexNDArray);
+
+  FloatComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (a (i), b (i));
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+max (const FloatComplex& c, const FloatComplexNDArray& m)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatComplexNDArray);
+
+  FloatComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (c, m (i));
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+max (const FloatComplexNDArray& m, const FloatComplex& c)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatComplexNDArray);
+
+  FloatComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (c, m (i));
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+max (const FloatComplexNDArray& a, const FloatComplexNDArray& b)
+{
+  dim_vector dv = a.dims ();
+  int nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return FloatComplexNDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatComplexNDArray);
+
+  FloatComplexNDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (a (i), b (i));
+    }
+
+  return result;
+}
+
+NDS_CMP_OPS(FloatComplexNDArray, std::real, FloatComplex, std::real)
+NDS_BOOL_OPS(FloatComplexNDArray, FloatComplex, static_cast<float> (0.0))
+
+SND_CMP_OPS(FloatComplex, std::real, FloatComplexNDArray, std::real)
+SND_BOOL_OPS(FloatComplex, FloatComplexNDArray, static_cast<float> (0.0))
+
+NDND_CMP_OPS(FloatComplexNDArray, std::real, FloatComplexNDArray, std::real)
+NDND_BOOL_OPS(FloatComplexNDArray, FloatComplexNDArray, static_cast<float> (0.0))
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCNDArray.h b/liboctave/fCNDArray.h
new file mode 100644
index 0000000..d8b30d5
--- /dev/null
+++ b/liboctave/fCNDArray.h
@@ -0,0 +1,180 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexNDArray_h)
+#define octave_FloatComplexNDArray_h 1
+
+#include "MArrayN.h"
+#include "fCMatrix.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+class
+OCTAVE_API
+FloatComplexNDArray : public MArrayN<FloatComplex>
+{
+public:
+
+  FloatComplexNDArray (void) : MArrayN<FloatComplex> () { }
+
+  FloatComplexNDArray (const dim_vector& dv) : MArrayN<FloatComplex> (dv) { }
+
+  FloatComplexNDArray (const dim_vector& dv, const FloatComplex& val)
+    : MArrayN<FloatComplex> (dv, val) { }
+  
+  FloatComplexNDArray (const FloatComplexNDArray& a) : MArrayN<FloatComplex> (a) { }
+
+  FloatComplexNDArray (const FloatComplexMatrix& a) : MArrayN<FloatComplex> (a) { }
+
+  template <class U>
+  FloatComplexNDArray (const MArrayN<U>& a) : MArrayN<FloatComplex> (a) { }
+
+  template <class U>
+  FloatComplexNDArray (const ArrayN<U>& a) : MArrayN<FloatComplex> (a) { }
+
+  FloatComplexNDArray (const charNDArray&); 
+
+  FloatComplexNDArray& operator = (const FloatComplexNDArray& a)
+    {
+      MArrayN<FloatComplex>::operator = (a);
+      return *this;
+    }
+
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
+  // FIXME -- this is not quite the right thing.
+
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool all_elements_are_real (void) const;
+  bool all_integers (float& max_val, float& min_val) const;
+  bool too_large_for_float (void) const;
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+
+  FloatComplexNDArray cumprod (int dim = -1) const;
+  FloatComplexNDArray cumsum (int dim = -1) const;
+  FloatComplexNDArray prod (int dim = -1) const;
+  FloatComplexNDArray sum (int dim = -1) const;
+  FloatComplexNDArray sumsq (int dim = -1) const;
+  FloatComplexNDArray concat (const FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx);
+  FloatComplexNDArray concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx);
+
+  FloatComplexNDArray max (int dim = 0) const;
+  FloatComplexNDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  FloatComplexNDArray min (int dim = 0) const;
+  FloatComplexNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const;
+
+  FloatComplexNDArray cummax (int dim = 0) const;
+  FloatComplexNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  FloatComplexNDArray cummin (int dim = 0) const;
+  FloatComplexNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const;
+
+  FloatComplexNDArray& insert (const NDArray& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexNDArray& insert (const FloatComplexNDArray& a, octave_idx_type r, octave_idx_type c);
+  FloatComplexNDArray& insert (const FloatComplexNDArray& a, const Array<octave_idx_type>& ra_idx);
+  
+  FloatNDArray abs (void) const;
+  boolNDArray isnan (void) const;
+  boolNDArray isinf (void) const;
+  boolNDArray isfinite (void) const;
+
+  friend OCTAVE_API FloatComplexNDArray conj (const FloatComplexNDArray& a);
+
+  FloatComplexNDArray fourier (int dim = 1) const;
+  FloatComplexNDArray ifourier (int dim = 1) const;
+
+  FloatComplexNDArray fourier2d (void) const;
+  FloatComplexNDArray ifourier2d (void) const;
+
+  FloatComplexNDArray fourierNd (void) const;
+  FloatComplexNDArray ifourierNd (void) const;
+
+  FloatComplexMatrix matrix_value (void) const;
+
+  FloatComplexNDArray squeeze (void) const { return MArrayN<FloatComplex>::squeeze (); }
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexNDArray& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatComplexNDArray& a);
+
+  static FloatComplex resize_fill_value (void) { return FloatComplex (0.0, 0.0); }
+
+  //  bool all_elements_are_real (void) const;
+  //  bool all_integers (float& max_val, float& min_val) const;
+
+  FloatComplexNDArray diag (octave_idx_type k = 0) const;
+
+  typedef float (*dmapper) (const FloatComplex&);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+  typedef bool (*bmapper) (const FloatComplex&);
+
+  FloatNDArray map (dmapper fcn) const;
+  FloatComplexNDArray map (cmapper fcn) const;
+  boolNDArray map (bmapper fcn) const;
+
+private:
+
+  FloatComplexNDArray (FloatComplex *d, const dim_vector& dv)
+    : MArrayN<FloatComplex> (d, dv) { }
+};
+
+extern OCTAVE_API FloatComplexNDArray conj (const FloatComplexNDArray& a);
+
+extern OCTAVE_API FloatComplexNDArray min (const FloatComplex& c, const FloatComplexNDArray& m);
+extern OCTAVE_API FloatComplexNDArray min (const FloatComplexNDArray& m, const FloatComplex& c);
+extern OCTAVE_API FloatComplexNDArray min (const FloatComplexNDArray& a, const FloatComplexNDArray& b);
+
+extern OCTAVE_API FloatComplexNDArray max (const FloatComplex& c, const FloatComplexNDArray& m);
+extern OCTAVE_API FloatComplexNDArray max (const FloatComplexNDArray& m, const FloatComplex& c);
+extern OCTAVE_API FloatComplexNDArray max (const FloatComplexNDArray& a, const FloatComplexNDArray& b);
+
+NDS_CMP_OP_DECLS (FloatComplexNDArray, FloatComplex, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatComplexNDArray, FloatComplex, OCTAVE_API)
+
+SND_CMP_OP_DECLS (FloatComplex, FloatComplexNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (FloatComplex, FloatComplexNDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (FloatComplexNDArray, FloatComplexNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatComplexNDArray, FloatComplexNDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, FloatComplexNDArray, FloatComplex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCRowVector.cc b/liboctave/fCRowVector.cc
new file mode 100644
index 0000000..d5b5281
--- /dev/null
+++ b/liboctave/fCRowVector.cc
@@ -0,0 +1,509 @@
+// RowVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgemv, CGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const FloatComplex&,
+			   const FloatComplex*, const octave_idx_type&, const FloatComplex*,
+			   const octave_idx_type&, const FloatComplex&, FloatComplex*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xcdotu, XCDOTU) (const octave_idx_type&, const FloatComplex*, const octave_idx_type&,
+			     const FloatComplex*, const octave_idx_type&, FloatComplex&);
+}
+
+// FloatComplex Row Vector class
+
+FloatComplexRowVector::FloatComplexRowVector (const FloatRowVector& a)
+  : MArray<FloatComplex> (a.length ())
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i) = a.elem (i);
+}
+
+bool
+FloatComplexRowVector::operator == (const FloatComplexRowVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+FloatComplexRowVector::operator != (const FloatComplexRowVector& a) const
+{
+  return !(*this == a);
+}
+
+// destructive insert/delete/reorder operations
+
+FloatComplexRowVector&
+FloatComplexRowVector::insert (const FloatRowVector& a, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (c < 0 || c + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexRowVector&
+FloatComplexRowVector::insert (const FloatComplexRowVector& a, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (c < 0 || c + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatComplexRowVector&
+FloatComplexRowVector::fill (float val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexRowVector&
+FloatComplexRowVector::fill (const FloatComplex& val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexRowVector&
+FloatComplexRowVector::fill (float val, octave_idx_type c1, octave_idx_type c2)
+{
+  octave_idx_type len = length ();
+
+  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = c1; i <= c2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexRowVector&
+FloatComplexRowVector::fill (const FloatComplex& val, octave_idx_type c1, octave_idx_type c2)
+{
+  octave_idx_type len = length ();
+
+  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = c1; i <= c2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatComplexRowVector
+FloatComplexRowVector::append (const FloatRowVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nc_insert = len;
+  FloatComplexRowVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nc_insert);
+  return retval;
+}
+
+FloatComplexRowVector
+FloatComplexRowVector::append (const FloatComplexRowVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nc_insert = len;
+  FloatComplexRowVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nc_insert);
+  return retval;
+}
+
+FloatComplexColumnVector 
+FloatComplexRowVector::hermitian (void) const
+{
+  return MArray<FloatComplex>::hermitian (std::conj);
+}
+
+FloatComplexColumnVector 
+FloatComplexRowVector::transpose (void) const
+{
+  return MArray<FloatComplex>::transpose ();
+}
+
+FloatComplexRowVector
+conj (const FloatComplexRowVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  FloatComplexRowVector retval;
+  if (a_len > 0)
+    retval = FloatComplexRowVector (mx_inline_conj_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+// resize is the destructive equivalent for this one
+
+FloatComplexRowVector
+FloatComplexRowVector::extract (octave_idx_type c1, octave_idx_type c2) const
+{
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  FloatComplexRowVector result (new_c);
+
+  for (octave_idx_type i = 0; i < new_c; i++)
+    result.elem (i) = elem (c1+i);
+
+  return result;
+}
+
+FloatComplexRowVector
+FloatComplexRowVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  FloatComplexRowVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.elem (i) = elem (r1+i);
+
+  return result;
+}
+
+// row vector by row vector -> row vector operations
+
+FloatComplexRowVector&
+FloatComplexRowVector::operator += (const FloatRowVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator +=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_add2 (d, a.data (), len);
+  return *this;
+}
+
+FloatComplexRowVector&
+FloatComplexRowVector::operator -= (const FloatRowVector& a)
+{
+  octave_idx_type len = length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    {
+      gripe_nonconformant ("operator -=", len, a_len);
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  FloatComplex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  mx_inline_subtract2 (d, a.data (), len);
+  return *this;
+}
+
+// row vector by matrix -> row vector
+
+FloatComplexRowVector
+operator * (const FloatComplexRowVector& v, const FloatComplexMatrix& a)
+{
+  FloatComplexRowVector retval;
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != len)
+    gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
+  else
+    {
+      if (len == 0)
+	retval.resize (a_nc, 0.0);
+      else
+	{
+	  // Transpose A to form A'*x == (x'*A)'
+
+	  octave_idx_type ld = a_nr;
+
+	  retval.resize (a_nc);
+	  FloatComplex *y = retval.fortran_vec ();
+
+	  F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
+				   a_nr, a_nc, 1.0, a.data (),
+				   ld, v.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+FloatComplexRowVector
+operator * (const FloatRowVector& v, const FloatComplexMatrix& a)
+{
+  FloatComplexRowVector tmp (v);
+  return tmp * a;
+}
+
+// other operations
+
+FloatRowVector
+FloatComplexRowVector::map (dmapper fcn) const
+{
+  return MArray<FloatComplex>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexRowVector
+FloatComplexRowVector::map (cmapper fcn) const
+{
+  return MArray<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
+}
+
+FloatComplex
+FloatComplexRowVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return FloatComplex (0.0);
+
+  FloatComplex res = elem (0);
+  float absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) < absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+FloatComplex
+FloatComplexRowVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return FloatComplex (0.0);
+
+  FloatComplex res = elem (0);
+  float absres = std::abs (res);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (std::abs (elem (i)) > absres)
+      {
+	res = elem (i);
+	absres = std::abs (res);
+      }
+
+  return res;
+}
+
+// i/o
+
+std::ostream&
+operator << (std::ostream& os, const FloatComplexRowVector& a)
+{
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << " " /* setw (field_width) */ << a.elem (i);
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatComplexRowVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      FloatComplex tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+// row vector by column vector -> scalar
+
+// row vector by column vector -> scalar
+
+FloatComplex
+operator * (const FloatComplexRowVector& v, const FloatColumnVector& a)
+{
+  FloatComplexColumnVector tmp (a);
+  return v * tmp;
+}
+
+FloatComplex
+operator * (const FloatComplexRowVector& v, const FloatComplexColumnVector& a)
+{
+  FloatComplex retval (0.0, 0.0);
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    gripe_nonconformant ("operator *", len, a_len);
+  else if (len != 0)
+    F77_FUNC (xcdotu, XCDOTU) (len, v.data (), 1, a.data (), 1, retval);
+
+  return retval;
+}
+
+// other operations
+
+FloatComplexRowVector
+linspace (const FloatComplex& x1, const FloatComplex& x2, octave_idx_type n)
+{
+  FloatComplexRowVector retval;
+
+  if (n > 0)
+    {
+      retval.resize (n);
+      FloatComplex delta = (x2 - x1) / static_cast<float> (n - 1.0);
+      retval.elem (0) = x1;
+      for (octave_idx_type i = 1; i < n-1; i++)
+	retval.elem (i) = x1 +  static_cast<float> (1.0) * i * delta;
+      retval.elem (n-1) = x2;
+    }
+  else
+    {
+      retval.resize (1);
+      retval.elem (0) = x2;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCRowVector.h b/liboctave/fCRowVector.h
new file mode 100644
index 0000000..98fcf57
--- /dev/null
+++ b/liboctave/fCRowVector.h
@@ -0,0 +1,136 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexRowVector_h)
+#define octave_FloatComplexRowVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+FloatComplexRowVector : public MArray<FloatComplex>
+{
+friend class FloatComplexColumnVector;
+
+public:
+
+  FloatComplexRowVector (void) : MArray<FloatComplex> () { }
+
+  explicit FloatComplexRowVector (octave_idx_type n) : MArray<FloatComplex> (n) { }
+
+  FloatComplexRowVector (octave_idx_type n, const FloatComplex& val) : MArray<FloatComplex> (n, val) { }
+
+  FloatComplexRowVector (const FloatComplexRowVector& a) : MArray<FloatComplex> (a) { }
+
+  FloatComplexRowVector (const MArray<FloatComplex>& a) : MArray<FloatComplex> (a) { }
+
+  explicit FloatComplexRowVector (const FloatRowVector& a);
+
+  FloatComplexRowVector& operator = (const FloatComplexRowVector& a)
+    {
+      MArray<FloatComplex>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatComplexRowVector& a) const;
+  bool operator != (const FloatComplexRowVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  FloatComplexRowVector& insert (const FloatRowVector& a, octave_idx_type c);
+  FloatComplexRowVector& insert (const FloatComplexRowVector& a, octave_idx_type c);
+
+  FloatComplexRowVector& fill (float val);
+  FloatComplexRowVector& fill (const FloatComplex& val);
+  FloatComplexRowVector& fill (float val, octave_idx_type c1, octave_idx_type c2);
+  FloatComplexRowVector& fill (const FloatComplex& val, octave_idx_type c1, octave_idx_type c2);
+
+  FloatComplexRowVector append (const FloatRowVector& a) const;
+  FloatComplexRowVector append (const FloatComplexRowVector& a) const;
+
+  FloatComplexColumnVector hermitian (void) const;
+  FloatComplexColumnVector transpose (void) const;
+
+  friend FloatComplexRowVector conj (const FloatComplexRowVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  FloatComplexRowVector extract (octave_idx_type c1, octave_idx_type c2) const;
+
+  FloatComplexRowVector extract_n (octave_idx_type c1, octave_idx_type n) const;
+
+  // row vector by row vector -> row vector operations
+
+  FloatComplexRowVector& operator += (const FloatRowVector& a);
+  FloatComplexRowVector& operator -= (const FloatRowVector& a);
+
+  // row vector by matrix -> row vector
+
+  friend FloatComplexRowVector operator * (const FloatComplexRowVector& a,
+				      const FloatComplexMatrix& b);
+
+  friend FloatComplexRowVector operator * (const FloatRowVector& a,
+				      const FloatComplexMatrix& b);
+
+  // other operations
+
+  typedef float (*dmapper) (const FloatComplex&);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+
+  FloatRowVector map (dmapper fcn) const;
+  FloatComplexRowVector map (cmapper fcn) const;
+
+  FloatComplex min (void) const;
+  FloatComplex max (void) const;
+
+  // i/o
+
+  friend std::ostream& operator << (std::ostream& os, const FloatComplexRowVector& a);
+  friend std::istream& operator >> (std::istream& is, FloatComplexRowVector& a);
+
+private:
+
+  FloatComplexRowVector (FloatComplex *d, octave_idx_type l) : MArray<FloatComplex> (d, l) { }
+};
+
+// row vector by column vector -> scalar
+
+FloatComplex operator * (const FloatComplexRowVector& a, const ColumnVector& b);
+
+FloatComplex operator * (const FloatComplexRowVector& a, const FloatComplexColumnVector& b);
+
+// other operations
+
+OCTAVE_API FloatComplexRowVector linspace (const FloatComplex& x1, const FloatComplex& x2, octave_idx_type n);
+
+MARRAY_FORWARD_DEFS (MArray, FloatComplexRowVector, FloatComplex)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxAEPBAL.cc b/liboctave/fCmplxAEPBAL.cc
new file mode 100644
index 0000000..4124cbe
--- /dev/null
+++ b/liboctave/fCmplxAEPBAL.cc
@@ -0,0 +1,109 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007 John W. Eaton
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "fCmplxAEPBAL.h"
+#include "fMatrix.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgebal, CGEBAL) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&,
+			     octave_idx_type&, octave_idx_type&, float*,
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+ 
+  F77_RET_T
+  F77_FUNC (cgebak, CGEBAK) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&,
+			     const octave_idx_type&, const float*,
+			     const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL  F77_CHAR_ARG_LEN_DECL);
+}
+
+FloatComplexAEPBALANCE::FloatComplexAEPBALANCE (const FloatComplexMatrix& a, 
+                                                bool noperm, bool noscal)
+ : base_aepbal<FloatComplexMatrix, FloatColumnVector> ()
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("AEPBALANCE requires square matrix");
+      return;
+    }
+
+  octave_idx_type info;
+
+  scale = FloatColumnVector (n);
+  float *pscale = scale.fortran_vec ();
+
+  balanced_mat = a;
+  FloatComplex *p_balanced_mat = balanced_mat.fortran_vec ();
+
+  job = noperm ? (noscal ? 'N' : 'S') : (noscal ? 'P' : 'B');
+
+  F77_XFCN (cgebal, CGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, ilo, ihi,
+			     pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+}
+
+FloatComplexMatrix
+FloatComplexAEPBALANCE::balancing_matrix (void) const
+{
+  octave_idx_type n = balanced_mat.rows ();
+  FloatComplexMatrix balancing_mat (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    balancing_mat.elem (i, i) = 1.0;
+
+  FloatComplex *p_balancing_mat = balancing_mat.fortran_vec ();
+  const float *pscale = scale.fortran_vec ();
+
+  octave_idx_type info;
+
+  char side = 'R';
+
+  F77_XFCN (cgebak, CGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n,
+			     p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return balancing_mat;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxAEPBAL.h b/liboctave/fCmplxAEPBAL.h
new file mode 100644
index 0000000..ed1f88f
--- /dev/null
+++ b/liboctave/fCmplxAEPBAL.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexAEPBALANCE_h)
+#define octave_FloatComplexAEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "base-aepbal.h"
+#include "fCMatrix.h"
+#include "fColVector.h"
+
+class
+OCTAVE_API
+FloatComplexAEPBALANCE : public base_aepbal<FloatComplexMatrix, FloatColumnVector>
+{
+public:
+
+  FloatComplexAEPBALANCE (void) : base_aepbal<FloatComplexMatrix, FloatColumnVector> () { }
+
+  FloatComplexAEPBALANCE (const FloatComplexMatrix& a, bool noperm = false,
+                          bool noscal = false);
+
+  FloatComplexAEPBALANCE (const FloatComplexAEPBALANCE& a) 
+    : base_aepbal<FloatComplexMatrix, FloatColumnVector> (a) { }
+
+  FloatComplexMatrix balancing_matrix (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxCHOL.cc b/liboctave/fCmplxCHOL.cc
new file mode 100644
index 0000000..c768fc3
--- /dev/null
+++ b/liboctave/fCmplxCHOL.cc
@@ -0,0 +1,449 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "fMatrix.h"
+#include "fRowVector.h"
+#include "fCmplxCHOL.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#ifndef HAVE_QRUPDATE
+#include "dbleQR.h"
+#endif
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cpotrf, CPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (cpotri, CPOTRI) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cpocon, CPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, const float&,
+			     float&, FloatComplex*, float*, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (cch1up, CCH1UP) (const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             FloatComplex*, float*);
+
+  F77_RET_T
+  F77_FUNC (cch1dn, CCH1DN) (const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             FloatComplex*, float*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cchinx, CCHINX) (const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, FloatComplex*, float*, 
+                             octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cchdex, CCHDEX) (const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, float*);
+
+  F77_RET_T
+  F77_FUNC (cchshx, CCHSHX) (const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&, 
+                             FloatComplex*, float*);
+#endif
+}
+
+octave_idx_type
+FloatComplexCHOL::init (const FloatComplexMatrix& a, bool calc_cond)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler)
+	("FloatComplexCHOL requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type n = a_nc;
+  octave_idx_type info;
+
+  chol_mat = a;
+  FloatComplex *h = chol_mat.fortran_vec ();
+
+  // Calculate the norm of the matrix, for later use.
+  float anorm = 0;
+  if (calc_cond) 
+    anorm = chol_mat.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+  F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 ("U", 1), n, h, n, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  xrcond = 0.0;
+  if (info != 0)
+    info = -1;
+  else if (calc_cond) 
+    {
+      octave_idx_type cpocon_info = 0;
+
+      // Now calculate the condition number for non-singular matrix.
+      Array<FloatComplex> z (2*n);
+      FloatComplex *pz = z.fortran_vec ();
+      Array<float> rz (n);
+      float *prz = rz.fortran_vec ();
+      F77_XFCN (cpocon, CPOCON, (F77_CONST_CHAR_ARG2 ("U", 1), n, h,
+				 n, anorm, xrcond, pz, prz, cpocon_info
+				 F77_CHAR_ARG_LEN (1)));
+
+      if (cpocon_info != 0) 
+	info = -1;
+    }
+  else
+    {
+      // If someone thinks of a more graceful way of doing this (or
+      // faster for that matter :-)), please let me know!
+
+      if (n > 1)
+	for (octave_idx_type j = 0; j < a_nc; j++)
+	  for (octave_idx_type i = j+1; i < a_nr; i++)
+	    chol_mat.xelem (i, j) = 0.0;
+    }
+
+  return info;
+}
+
+static FloatComplexMatrix
+chol2inv_internal (const FloatComplexMatrix& r)
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.cols ();
+
+  if (r_nr == r_nc)
+    {
+      octave_idx_type n = r_nc;
+      octave_idx_type info;
+
+      FloatComplexMatrix tmp = r;
+
+      F77_XFCN (cpotri, CPOTRI, (F77_CONST_CHAR_ARG2 ("U", 1), n,
+				 tmp.fortran_vec (), n, info
+				 F77_CHAR_ARG_LEN (1)));
+
+      // If someone thinks of a more graceful way of doing this (or
+      // faster for that matter :-)), please let me know!
+
+      if (n > 1)
+	for (octave_idx_type j = 0; j < r_nc; j++)
+	  for (octave_idx_type i = j+1; i < r_nr; i++)
+	    tmp.xelem (i, j) = std::conj (tmp.xelem (j, i));
+
+      retval = tmp;
+    }
+  else
+    (*current_liboctave_error_handler) ("chol2inv requires square matrix");
+
+  return retval;
+}
+
+// Compute the inverse of a matrix using the Cholesky factorization.
+FloatComplexMatrix
+FloatComplexCHOL::inverse (void) const
+{
+  return chol2inv_internal (chol_mat);
+}
+
+void
+FloatComplexCHOL::set (const FloatComplexMatrix& R)
+{
+  if (R.is_square ()) 
+    chol_mat = R;
+  else
+    (*current_liboctave_error_handler) ("CHOL requires square matrix");
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+FloatComplexCHOL::update (const FloatComplexColumnVector& u)
+{
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      FloatComplexColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (float, rw, n);
+
+      F77_XFCN (cch1up, CCH1UP, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), rw));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+octave_idx_type
+FloatComplexCHOL::downdate (const FloatComplexColumnVector& u)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      FloatComplexColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (float, rw, n);
+
+      F77_XFCN (cch1dn, CCH1DN, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), rw, info));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+FloatComplexCHOL::insert_sym (const FloatComplexColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      FloatComplexColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (float, rw, n);
+
+      chol_mat.resize (n+1, n+1);
+
+      F77_XFCN (cchinx, CCHINX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 j + 1, utmp.fortran_vec (), rw, info));
+    }
+
+  return info;
+}
+
+void
+FloatComplexCHOL::delete_sym (octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, rw, n);
+
+      F77_XFCN (cchdex, CCHDEX, (n, chol_mat.fortran_vec (), chol_mat.rows (), 
+                                 j + 1, rw));
+
+      chol_mat.resize (n-1, n-1);
+    }
+}
+
+void
+FloatComplexCHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (FloatComplex, w, n);
+      OCTAVE_LOCAL_BUFFER (float, rw, n);
+
+      F77_XFCN (cchshx, CCHSHX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 i + 1, j + 1, w, rw));
+    }
+}
+
+#else
+
+void
+FloatComplexCHOL::update (const FloatComplexColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      init (chol_mat.hermitian () * chol_mat 
+            + FloatComplexMatrix (u) * FloatComplexMatrix (u).hermitian (), false);
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+static bool
+singular (const FloatComplexMatrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    if (a(i,i) == 0.0f) return true;
+  return false;
+}
+
+octave_idx_type
+FloatComplexCHOL::downdate (const FloatComplexColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else
+        {
+          info = init (chol_mat.hermitian () * chol_mat 
+                       - FloatComplexMatrix (u) * FloatComplexMatrix (u).hermitian (), false);
+          if (info) info = 1;
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+FloatComplexCHOL::insert_sym (const FloatComplexColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else if (u(j).imag () != 0.0)
+        info = 3;
+      else
+        {
+          FloatComplexMatrix a = chol_mat.hermitian () * chol_mat;
+          FloatComplexMatrix a1 (n+1, n+1);
+          for (octave_idx_type k = 0; k < n+1; k++)
+            for (octave_idx_type l = 0; l < n+1; l++)
+              {
+                if (l == j)
+                  a1(k, l) = u(k);
+                else if (k == j)
+                  a1(k, l) = std::conj (u(l));
+                else
+                  a1(k, l) = a(k < j ? k : k-1, l < j ? l : l-1);
+              }
+          info = init (a1, false);
+          if (info) info = 1;
+        }
+    }
+
+  return info;
+}
+
+void
+FloatComplexCHOL::delete_sym (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      FloatComplexMatrix a = chol_mat.hermitian () * chol_mat;
+      a.delete_elements (1, idx_vector (j));
+      a.delete_elements (0, idx_vector (j));
+      init (a, false);
+    }
+}
+
+void
+FloatComplexCHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      FloatComplexMatrix a = chol_mat.hermitian () * chol_mat;
+      Array<octave_idx_type> p (n);
+      for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+      if (i < j)
+        {
+          for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+          p(j) = i;
+        }
+      else if (j < i)
+        {
+          p(j) = i;
+          for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+        }
+
+      init (a.index (idx_vector (p), idx_vector (p)), false);
+    }
+}
+
+#endif
+
+FloatComplexMatrix
+chol2inv (const FloatComplexMatrix& r)
+{
+  return chol2inv_internal (r);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxCHOL.h b/liboctave/fCmplxCHOL.h
new file mode 100644
index 0000000..58159bc
--- /dev/null
+++ b/liboctave/fCmplxCHOL.h
@@ -0,0 +1,99 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexCHOL_h)
+#define octave_FloatComplexCHOL_h 1
+
+#include <iosfwd>
+
+#include "fCMatrix.h"
+#include "fCColVector.h"
+
+class
+OCTAVE_API
+FloatComplexCHOL
+{
+public:
+
+  FloatComplexCHOL (void) : chol_mat () { }
+
+  FloatComplexCHOL (const FloatComplexMatrix& a, bool calc_cond = false) { init (a, calc_cond); }
+
+  FloatComplexCHOL (const FloatComplexMatrix& a, octave_idx_type& info, bool calc_cond = false)
+    {
+      info = init (a, calc_cond);
+    }
+
+  FloatComplexCHOL (const FloatComplexCHOL& a)
+    : chol_mat (a.chol_mat), xrcond (a.xrcond) { }
+
+  FloatComplexCHOL& operator = (const FloatComplexCHOL& a)
+    {
+      if (this != &a)
+	{
+	  chol_mat = a.chol_mat;
+	  xrcond = a.xrcond;
+	}
+
+      return *this;
+    }
+
+  FloatComplexMatrix chol_matrix (void) const { return chol_mat; }
+
+  float rcond (void) const { return xrcond; }
+
+  FloatComplexMatrix inverse (void) const;
+
+  void set (const FloatComplexMatrix& R);
+
+  void update (const FloatComplexColumnVector& u);
+
+  octave_idx_type downdate (const FloatComplexColumnVector& u);
+
+  octave_idx_type insert_sym (const FloatComplexColumnVector& u, octave_idx_type j);
+
+  void delete_sym (octave_idx_type j);
+
+  void shift_sym (octave_idx_type i, octave_idx_type j);
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexCHOL& a);
+
+private:
+
+  FloatComplexMatrix chol_mat;
+
+  float xrcond;
+
+  octave_idx_type init (const FloatComplexMatrix& a, bool calc_cond);
+};
+
+FloatComplexMatrix OCTAVE_API chol2inv (const FloatComplexMatrix& r);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxGEPBAL.cc b/liboctave/fCmplxGEPBAL.cc
new file mode 100644
index 0000000..43e5549
--- /dev/null
+++ b/liboctave/fCmplxGEPBAL.cc
@@ -0,0 +1,131 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "fCmplxGEPBAL.h"
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cggbal, CGGBAL) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type& N,
+			     FloatComplex* A, const octave_idx_type& LDA, FloatComplex* B,
+			     const octave_idx_type& LDB, octave_idx_type& ILO, octave_idx_type& IHI,
+			     float* LSCALE, float* RSCALE,
+			     float* WORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sggbak, SGGBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO,
+			     const octave_idx_type& IHI, const float* LSCALE,
+			     const float* RSCALE, octave_idx_type& M, float* V,
+			     const octave_idx_type& LDV, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+}
+
+octave_idx_type
+FloatComplexGEPBALANCE::init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, 
+		  const std::string& balance_job)
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("FloatComplexGEPBALANCE requires square matrix");
+      return -1;
+    }
+
+  if (a.dims() != b.dims ())
+    {
+      gripe_nonconformant ("FloatComplexGEPBALANCE", n, n, b.rows(), b.cols());
+      return -1;
+    } 
+
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  OCTAVE_LOCAL_BUFFER (float, plscale, n);
+  OCTAVE_LOCAL_BUFFER (float, prscale, n);
+  OCTAVE_LOCAL_BUFFER (float, pwork, 6 * n);
+
+  balanced_mat = a;
+  FloatComplex *p_balanced_mat = balanced_mat.fortran_vec ();
+  balanced_mat2 = b;
+  FloatComplex *p_balanced_mat2 = balanced_mat2.fortran_vec ();
+
+  char job = balance_job[0];
+
+  F77_XFCN (cggbal, CGGBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, p_balanced_mat2,
+			     n, ilo, ihi, plscale,prscale, pwork, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  balancing_mat = FloatMatrix (n, n, 0.0);
+  balancing_mat2 = FloatMatrix (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      OCTAVE_QUIT;
+      balancing_mat.elem (i ,i) = 1.0;
+      balancing_mat2.elem (i ,i) = 1.0;
+    }
+
+  float *p_balancing_mat = balancing_mat.fortran_vec ();
+  float *p_balancing_mat2 = balancing_mat2.fortran_vec ();
+
+  // first left
+  F77_XFCN (sggbak, SGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+      
+  // then right
+  F77_XFCN (sggbak, SGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("R", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat2, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxGEPBAL.h b/liboctave/fCmplxGEPBAL.h
new file mode 100644
index 0000000..a678cd6
--- /dev/null
+++ b/liboctave/fCmplxGEPBAL.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexGEPBALANCE_h)
+#define octave_FloatComplexGEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "fMatrix.h"
+#include "fCMatrix.h"
+
+class
+OCTAVE_API
+FloatComplexGEPBALANCE
+{
+public:
+
+  FloatComplexGEPBALANCE (void) : balanced_mat (), balancing_mat () { }
+
+  FloatComplexGEPBALANCE (const FloatComplexMatrix& a, const FloatComplexMatrix& b, const std::string& balance_job)
+    {
+      init (a, b, balance_job); 
+    }
+
+  FloatComplexGEPBALANCE (const FloatComplexGEPBALANCE& a)
+    : balanced_mat (a.balanced_mat), balanced_mat2 (a.balanced_mat2),
+    balancing_mat (a.balancing_mat), balancing_mat2 (a.balancing_mat2) { }
+
+  FloatComplexGEPBALANCE& operator = (const FloatComplexGEPBALANCE& a)
+    {
+      if (this != &a)
+	{
+	  balanced_mat = a.balanced_mat;
+	  balanced_mat2 = a.balanced_mat2;
+	  balancing_mat = a.balancing_mat;
+	  balancing_mat2 = a.balancing_mat2;
+	}
+      return *this;
+    }
+
+  ~FloatComplexGEPBALANCE (void) { }
+
+  FloatComplexMatrix balanced_matrix (void) const { return balanced_mat; }
+
+  FloatComplexMatrix balanced_matrix2 (void) const { return balanced_mat2; }
+
+  FloatMatrix balancing_matrix (void) const { return balancing_mat; }
+
+  FloatMatrix balancing_matrix2 (void) const { return balancing_mat2; }
+
+  friend std::ostream& operator << (std::ostream& os, const FloatComplexGEPBALANCE& a);
+
+private:
+
+  FloatComplexMatrix balanced_mat;
+  FloatComplexMatrix balanced_mat2;
+  FloatMatrix balancing_mat;
+  FloatMatrix balancing_mat2;
+
+  octave_idx_type init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, 
+			const std::string& balance_job);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxHESS.cc b/liboctave/fCmplxHESS.cc
new file mode 100644
index 0000000..d28a090
--- /dev/null
+++ b/liboctave/fCmplxHESS.cc
@@ -0,0 +1,127 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fCmplxHESS.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgebal, CGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+			     octave_idx_type&, octave_idx_type&, float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+ 
+  F77_RET_T
+  F77_FUNC (cgehrd, CGEHRD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, FloatComplex*,
+			     FloatComplex*, const octave_idx_type&, octave_idx_type&);
+ 
+  F77_RET_T
+  F77_FUNC (cunghr, CUNGHR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, FloatComplex*,
+			     FloatComplex*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cgebak, CGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, FloatComplex*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+octave_idx_type
+FloatComplexHESS::init (const FloatComplexMatrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler)
+	("FloatComplexHESS requires square matrix");
+      return -1;
+    }
+
+  char job = 'N';
+  char side = 'R';
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 32 * n;
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  hess_mat = a;
+  FloatComplex *h = hess_mat.fortran_vec ();
+
+  Array<float> scale (n);
+  float *pscale = scale.fortran_vec ();
+
+  F77_XFCN (cgebal, CGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, h, n, ilo, ihi, pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  Array<FloatComplex> tau (n-1);
+  FloatComplex *ptau = tau.fortran_vec ();
+
+  Array<FloatComplex> work (lwork);
+  FloatComplex *pwork = work.fortran_vec ();
+
+  F77_XFCN (cgehrd, CGEHRD, (n, ilo, ihi, h, n, ptau, pwork, lwork, info));
+
+  unitary_hess_mat = hess_mat;
+  FloatComplex *z = unitary_hess_mat.fortran_vec ();
+
+  F77_XFCN (cunghr, CUNGHR, (n, ilo, ihi, z, n, ptau, pwork,
+			     lwork, info));
+
+  F77_XFCN (cgebak, CGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n, z, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  // If someone thinks of a more graceful way of
+  // doing this (or faster for that matter :-)),
+  // please let me know!
+
+  if (n > 2)
+    for (octave_idx_type j = 0; j < a_nc; j++)
+      for (octave_idx_type i = j+2; i < a_nr; i++)
+	hess_mat.elem (i, j) = 0;
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxHESS.h b/liboctave/fCmplxHESS.h
new file mode 100644
index 0000000..d439a17
--- /dev/null
+++ b/liboctave/fCmplxHESS.h
@@ -0,0 +1,81 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexHESS_h)
+#define octave_FloatComplexHESS_h 1
+
+#include <iosfwd>
+
+#include "fCMatrix.h"
+
+class
+OCTAVE_API
+FloatComplexHESS
+{
+public:
+
+  FloatComplexHESS (void) : hess_mat (), unitary_hess_mat () { }
+
+  FloatComplexHESS (const FloatComplexMatrix& a) { init (a); }
+
+  FloatComplexHESS (const FloatComplexMatrix& a, octave_idx_type& info) { info = init (a); }
+
+  FloatComplexHESS (const FloatComplexHESS& a)
+    : hess_mat (a.hess_mat), unitary_hess_mat (a.unitary_hess_mat) { }
+
+  FloatComplexHESS& operator = (const FloatComplexHESS& a)
+    {
+      if (this != &a)
+	{
+	  hess_mat = a.hess_mat;
+	  unitary_hess_mat = a.unitary_hess_mat;
+	}
+      return *this;
+    }
+
+  ~FloatComplexHESS (void) { }
+
+  FloatComplexMatrix hess_matrix (void) const { return hess_mat; }
+
+  FloatComplexMatrix unitary_hess_matrix (void) const
+    {
+      return unitary_hess_mat;
+    }
+
+  friend std::ostream& operator << (std::ostream& os, const FloatComplexHESS& a);
+
+private:
+
+  FloatComplexMatrix hess_mat;
+  FloatComplexMatrix unitary_hess_mat;
+
+  octave_idx_type init (const FloatComplexMatrix& a);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxLU.cc b/liboctave/fCmplxLU.cc
new file mode 100644
index 0000000..a592ae2
--- /dev/null
+++ b/liboctave/fCmplxLU.cc
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fCmplxLU.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+// Instantiate the base LU class for the types we need.
+
+#include <base-lu.h>
+#include <base-lu.cc>
+
+template class base_lu <FloatComplexMatrix>;
+
+// Define the constructor for this particular derivation.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgetrf, CGETRF) (const octave_idx_type&, const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, octave_idx_type*, octave_idx_type&);
+}
+
+FloatComplexLU::FloatComplexLU (const FloatComplexMatrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+  ipvt.resize (mn);
+  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+  a_fact = a;
+  FloatComplex *tmp_data = a_fact.fortran_vec ();
+
+  octave_idx_type info = 0;
+
+  F77_XFCN (cgetrf, CGETRF, (a_nr, a_nc, tmp_data, a_nr, pipvt, info));
+
+  ipvt -= static_cast<octave_idx_type> (1);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxLU.h b/liboctave/fCmplxLU.h
new file mode 100644
index 0000000..b6d077c
--- /dev/null
+++ b/liboctave/fCmplxLU.h
@@ -0,0 +1,62 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexLU_h)
+#define octave_FloatComplexLU_h 1
+
+#include "base-lu.h"
+#include "dMatrix.h"
+#include "fCMatrix.h"
+
+class
+OCTAVE_API
+FloatComplexLU : public base_lu <FloatComplexMatrix>
+{
+public:
+
+  FloatComplexLU (void)
+    : base_lu <FloatComplexMatrix> () { }
+
+  FloatComplexLU (const FloatComplexMatrix& a);
+
+  FloatComplexLU (const FloatComplexLU& a)
+    : base_lu <FloatComplexMatrix> (a) { }
+
+  FloatComplexLU& operator = (const FloatComplexLU& a)
+    {
+      if (this != &a)
+	base_lu <FloatComplexMatrix> :: operator = (a);
+
+      return *this;
+    }
+
+  ~FloatComplexLU (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxQR.cc b/liboctave/fCmplxQR.cc
new file mode 100644
index 0000000..4b17130
--- /dev/null
+++ b/liboctave/fCmplxQR.cc
@@ -0,0 +1,719 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fCmplxQR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "Range.h"
+#include "idx-vector.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgeqrf, CGEQRF) (const octave_idx_type&, const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, FloatComplex*, FloatComplex*,
+			     const octave_idx_type&, octave_idx_type&); 
+
+  F77_RET_T
+  F77_FUNC (cungqr, CUNGQR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, FloatComplex*,
+			     FloatComplex*, const octave_idx_type&, octave_idx_type&);
+
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (cqr1up, CQR1UP) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             FloatComplex*, FloatComplex*, FloatComplex*, float*);
+
+  F77_RET_T
+  F77_FUNC (cqrinc, CQRINC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, const FloatComplex*, float*);
+
+  F77_RET_T
+  F77_FUNC (cqrdec, CQRDEC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, float*);
+
+  F77_RET_T
+  F77_FUNC (cqrinr, CQRINR) (const octave_idx_type&, const octave_idx_type&, 
+                             FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, const FloatComplex*, float*);
+
+  F77_RET_T
+  F77_FUNC (cqrder, CQRDER) (const octave_idx_type&, const octave_idx_type&, 
+                             FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, FloatComplex*, float*);
+
+  F77_RET_T
+  F77_FUNC (cqrshc, CQRSHC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+                             FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&,
+                             FloatComplex*, float*);
+
+#endif
+}
+
+FloatComplexQR::FloatComplexQR (const FloatComplexMatrix& a, QR::type qr_type)
+  : q (), r ()
+{
+  init (a, qr_type);
+}
+
+void
+FloatComplexQR::init (const FloatComplexMatrix& a, QR::type qr_type)
+{
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (FloatComplex, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  FloatComplexMatrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  if (m > 0)
+    {
+      // workspace query.
+      FloatComplex clwork;
+      F77_XFCN (cgeqrf, CGEQRF, (m, n, afact.fortran_vec (), m, tau, &clwork, -1, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = clwork.real ();
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (FloatComplex, work, lwork);
+      F77_XFCN (cgeqrf, CGEQRF, (m, n, afact.fortran_vec (), m, tau, work, lwork, info));
+    }
+
+  form (n, afact, tau, qr_type);
+}
+
+void FloatComplexQR::form (octave_idx_type n, FloatComplexMatrix& afact, 
+                           FloatComplex *tau, QR::type qr_type)
+{
+  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type info;
+
+  if (qr_type == QR::raw)
+    {
+      for (octave_idx_type j = 0; j < min_mn; j++)
+	{
+	  octave_idx_type limit = j < min_mn - 1 ? j : min_mn - 1;
+	  for (octave_idx_type i = limit + 1; i < m; i++)
+	    afact.elem (i, j) *= tau[j];
+	}
+
+      r = afact;
+    }
+  else
+    {
+      // Attempt to minimize copying.
+      if (m >= n)
+        {
+          // afact will become q.
+          q = afact;
+          octave_idx_type k = qr_type == QR::economy ? n : m;
+          r = FloatComplexMatrix (k, n);
+          for (octave_idx_type j = 0; j < n; j++)
+            {
+              octave_idx_type i = 0;
+              for (; i <= j; i++)
+                r.xelem (i, j) = afact.xelem (i, j);
+              for (;i < k; i++)
+                r.xelem (i, j) = 0;
+            }
+          afact = FloatComplexMatrix (); // optimize memory
+        }
+      else
+        {
+          // afact will become r.
+          q = FloatComplexMatrix (m, m);
+          for (octave_idx_type j = 0; j < m; j++)
+            for (octave_idx_type i = j + 1; i < m; i++)
+              {
+                q.xelem (i, j) = afact.xelem (i, j);
+                afact.xelem (i, j) = 0;
+              }
+          r = afact;
+        }
+
+
+      if (m > 0)
+        {
+          octave_idx_type k = q.columns ();
+          // workspace query.
+          FloatComplex clwork;
+          F77_XFCN (cungqr, CUNGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     &clwork, -1, info));
+
+          // allocate buffer and do the job.
+          octave_idx_type lwork = clwork.real ();
+	  lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+          OCTAVE_LOCAL_BUFFER (FloatComplex, work, lwork);
+          F77_XFCN (cungqr, CUNGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     work, lwork, info));
+        }
+    }
+}
+
+FloatComplexQR::FloatComplexQR (const FloatComplexMatrix& q_arg, const FloatComplexMatrix& r_arg)
+{
+  octave_idx_type qr = q_arg.rows (), qc = q_arg.columns ();
+  octave_idx_type rr = r_arg.rows (), rc = r_arg.columns ();
+  if (qc == rr && (qr == qc || (qr > qc && rr == rc)))
+    {
+      q = q_arg;
+      r = r_arg;
+    }
+  else
+    (*current_liboctave_error_handler) ("QR dimensions mismatch");
+}
+
+QR::type
+FloatComplexQR::get_type (void) const
+{
+  QR::type retval;
+  if (!q.is_empty () && q.is_square ())
+    retval = QR::std;
+  else if (q.rows () > q.columns () && r.is_square ())
+    retval = QR::economy;
+  else
+    retval = QR::raw;
+  return retval;
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+FloatComplexQR::update (const FloatComplexColumnVector& u, const FloatComplexColumnVector& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      FloatComplexColumnVector utmp = u, vtmp = v;
+      OCTAVE_LOCAL_BUFFER (FloatComplex, w, k);
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      F77_XFCN (cqr1up, CQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                 utmp.fortran_vec (), vtmp.fortran_vec (), w, rw));
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+FloatComplexQR::update (const FloatComplexMatrix& u, const FloatComplexMatrix& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      OCTAVE_LOCAL_BUFFER (FloatComplex, w, k);
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      for (volatile octave_idx_type i = 0; i < u.cols (); i++)
+        {
+          FloatComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          F77_XFCN (cqr1up, CQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                     utmp.fortran_vec (), vtmp.fortran_vec (), w, rw));
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+FloatComplexQR::insert_col (const FloatComplexColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      if (k < m)
+        {
+          q.resize (m, k+1);
+          r.resize (k+1, n+1);
+        }
+      else
+        {
+          r.resize (k, n+1);
+        }
+
+      FloatComplexColumnVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      F77_XFCN (cqrinc, CQRINC, (m, n, k, q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (), j + 1, 
+                                 utmp.data (), rw));
+    }
+}
+
+void
+FloatComplexQR::insert_col (const FloatComplexMatrix& u, const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      octave_idx_type kmax = std::min (k + nj, m);
+      if (k < m)
+        {
+          q.resize (m, kmax);
+          r.resize (kmax, n + nj);
+        }
+      else
+        {
+          r.resize (k, n + nj);
+        }
+
+      OCTAVE_LOCAL_BUFFER (float, rw, kmax);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          F77_XFCN (cqrinc, CQRINC, (m, n + ii, std::min (kmax, k + ii), 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, 
+                                     u.column (jsi(i)).data (), rw));
+        }
+    }
+}
+
+void
+FloatComplexQR::delete_col (octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      F77_XFCN (cqrdec, CQRDEC, (m, n, k, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1, rw));
+
+      if (k < m)
+        {
+          q.resize (m, k-1);
+          r.resize (k-1, n-1);
+        }
+      else
+        {
+          r.resize (k, n-1);
+        }
+    }
+}
+
+void
+FloatComplexQR::delete_col (const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          F77_XFCN (cqrdec, CQRDEC, (m, n - ii, k == m ? k : k - ii, 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, rw));
+        }
+      if (k < m)
+        {
+          q.resize (m, k - nj);
+          r.resize (k - nj, n - nj);
+        }
+      else
+        {
+          r.resize (k, n - nj);
+        }
+
+    }
+}
+
+void
+FloatComplexQR::insert_row (const FloatComplexRowVector& u, octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = std::min (m, n);
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      q.resize (m + 1, m + 1);
+      r.resize (m + 1, n);
+      FloatComplexRowVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      F77_XFCN (cqrinr, CQRINR, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), 
+                                 j + 1, utmp.fortran_vec (), rw));
+
+    }
+}
+
+void
+FloatComplexQR::delete_row (octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (FloatComplex, w, m);
+      OCTAVE_LOCAL_BUFFER (float, rw, m);
+      F77_XFCN (cqrder, CQRDER, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1,
+                                 w, rw));
+
+      q.resize (m - 1, m - 1);
+      r.resize (m - 1, n);
+    }
+}
+
+void
+FloatComplexQR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (FloatComplex, w, k);
+      OCTAVE_LOCAL_BUFFER (float, rw, k);
+      F77_XFCN (cqrshc, CQRSHC, (m, n, k, 
+                                 q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (),
+                                 i + 1, j + 1, w, rw));
+    }
+}
+
+#else
+
+// Replacement update methods.
+
+void
+FloatComplexQR::update (const FloatComplexColumnVector& u, const FloatComplexColumnVector& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      init(q*r + FloatComplexMatrix (u) * FloatComplexMatrix (v).hermitian (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+FloatComplexQR::update (const FloatComplexMatrix& u, const FloatComplexMatrix& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      init(q*r + u * v.hermitian (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+static
+FloatComplexMatrix insert_col (const FloatComplexMatrix& a, octave_idx_type i,
+                               const FloatComplexColumnVector& x)
+{
+  FloatComplexMatrix retval (a.rows (), a.columns () + 1);
+  retval.assign (idx_vector::colon, idx_vector (0, i),
+                 a.index (idx_vector::colon, idx_vector (0, i)));
+  retval.assign (idx_vector::colon, idx_vector (i), x);
+  retval.assign (idx_vector::colon, idx_vector (i+1, retval.columns ()),
+                 a.index (idx_vector::colon, idx_vector (i, a.columns ())));
+  return retval;
+}
+
+static
+FloatComplexMatrix insert_row (const FloatComplexMatrix& a, octave_idx_type i,
+                               const FloatComplexRowVector& x)
+{
+  FloatComplexMatrix retval (a.rows () + 1, a.columns ());
+  retval.assign (idx_vector (0, i), idx_vector::colon,
+                 a.index (idx_vector (0, i), idx_vector::colon));
+  retval.assign (idx_vector (i), idx_vector::colon, x);
+  retval.assign (idx_vector (i+1, retval.rows ()), idx_vector::colon,
+                 a.index (idx_vector (i, a.rows ()), idx_vector::colon));
+  return retval;
+}
+
+static
+FloatComplexMatrix delete_col (const FloatComplexMatrix& a, octave_idx_type i)
+{
+  FloatComplexMatrix retval = a;
+  retval.delete_elements (1, idx_vector (i));
+  return retval;
+}
+
+static
+FloatComplexMatrix delete_row (const FloatComplexMatrix& a, octave_idx_type i)
+{
+  FloatComplexMatrix retval = a;
+  retval.delete_elements (0, idx_vector (i));
+  return retval;
+}
+
+static
+FloatComplexMatrix shift_cols (const FloatComplexMatrix& a, 
+                               octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = a.columns ();
+  Array<octave_idx_type> p (n);
+  for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+  if (i < j)
+    {
+      for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+      p(j) = i;
+    }
+  else if (j < i)
+    {
+      p(j) = i;
+      for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+    }
+
+  return a.index (idx_vector::colon, idx_vector (p));
+}
+
+void
+FloatComplexQR::insert_col (const FloatComplexColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_col (q*r, j, u), get_type ());
+    }
+}
+
+void
+FloatComplexQR::insert_col (const FloatComplexMatrix& u, const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      FloatComplexMatrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::insert_col (a, js(i), u.column (i));
+      init (a, get_type ());
+    }
+}
+
+void
+FloatComplexQR::delete_col (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_col (q*r, j), get_type ());
+    }
+}
+
+void
+FloatComplexQR::delete_col (const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      FloatComplexMatrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::delete_col (a, js(i));
+      init (a, get_type ());
+    }
+}
+
+void
+FloatComplexQR::insert_row (const FloatComplexRowVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_row (q*r, j, u), get_type ());
+    }
+}
+
+void
+FloatComplexQR::delete_row (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_row (q*r, j), get_type ());
+    }
+}
+
+void
+FloatComplexQR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      init (::shift_cols (q*r, i, j), get_type ());
+    }
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxQR.h b/liboctave/fCmplxQR.h
new file mode 100644
index 0000000..d55c69b
--- /dev/null
+++ b/liboctave/fCmplxQR.h
@@ -0,0 +1,106 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// updating/downdating by Jaroslav Hajek 2008
+
+#if !defined (octave_FloatComplexQR_h)
+#define octave_FloatComplexQR_h 1
+
+#include <iosfwd>
+
+#include "fCMatrix.h"
+#include "fCColVector.h"
+#include "fCRowVector.h"
+#include "dbleQR.h"
+
+class
+OCTAVE_API
+FloatComplexQR
+{
+public:
+
+  FloatComplexQR (void) : q (), r () { }
+
+  FloatComplexQR (const FloatComplexMatrix&, QR::type = QR::std);
+
+  FloatComplexQR (const FloatComplexMatrix& q, const FloatComplexMatrix& r);
+
+  FloatComplexQR (const FloatComplexQR& a) : q (a.q), r (a.r) { }
+
+  FloatComplexQR& operator = (const FloatComplexQR& a)
+    {
+      if (this != &a)
+	{
+	  q = a.q;
+	  r = a.r;
+	}
+      return *this;
+    }
+
+  ~FloatComplexQR (void) { }
+
+  void init (const FloatComplexMatrix&, QR::type = QR::std);
+
+  FloatComplexMatrix Q (void) const { return q; }
+
+  FloatComplexMatrix R (void) const { return r; }
+
+  QR::type get_type (void) const;
+
+  void update (const FloatComplexColumnVector& u, const FloatComplexColumnVector& v);
+
+  void update (const FloatComplexMatrix& u, const FloatComplexMatrix& v);
+
+  void insert_col (const FloatComplexColumnVector& u, octave_idx_type j);
+
+  void insert_col (const FloatComplexMatrix& u, const Array<octave_idx_type>& j);
+
+  void delete_col (octave_idx_type j);
+
+  void delete_col (const Array<octave_idx_type>& j);
+
+  void insert_row (const FloatComplexRowVector& u, octave_idx_type j);
+
+  void delete_row (octave_idx_type j);
+
+  void shift_cols (octave_idx_type i, octave_idx_type j);
+
+  friend std::ostream&  operator << (std::ostream&, const FloatComplexQR&);
+
+protected:
+
+  void form (octave_idx_type n, FloatComplexMatrix& afact, 
+             FloatComplex *tau, QR::type qr_type);
+
+  FloatComplexMatrix q;
+  FloatComplexMatrix r;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxQRP.cc b/liboctave/fCmplxQRP.cc
new file mode 100644
index 0000000..f8946de
--- /dev/null
+++ b/liboctave/fCmplxQRP.cc
@@ -0,0 +1,111 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "fCmplxQRP.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgeqp3, CGEQP3) (const octave_idx_type&, const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, octave_idx_type*, FloatComplex*, FloatComplex*,
+			     const octave_idx_type&, float*, octave_idx_type&);
+}
+
+// It would be best to share some of this code with FloatComplexQR class...
+
+FloatComplexQRP::FloatComplexQRP (const FloatComplexMatrix& a, QR::type qr_type)
+  : FloatComplexQR (), p ()
+{
+  init (a, qr_type);
+}
+
+void
+FloatComplexQRP::init (const FloatComplexMatrix& a, QR::type qr_type)
+{
+  assert (qr_type != QR::raw);
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (FloatComplex, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  FloatComplexMatrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  MArray<octave_idx_type> jpvt (n, 0);
+
+  if (m > 0)
+    {
+      OCTAVE_LOCAL_BUFFER (float, rwork, 2*n);
+
+      // workspace query.
+      FloatComplex clwork;
+      F77_XFCN (cgeqp3, CGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, &clwork, -1, rwork, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = clwork.real ();
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (FloatComplex, work, lwork);
+      F77_XFCN (cgeqp3, CGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, work, lwork, rwork, info));
+    }
+  else
+    for (octave_idx_type i = 0; i < n; i++) jpvt(i) = i+1;
+
+  // Form Permutation matrix (if economy is requested, return the
+  // indices only!)
+
+  jpvt -= static_cast<octave_idx_type> (1);
+  p = PermMatrix (jpvt, true);
+
+
+  form (n, afact, tau, qr_type);
+}
+
+FloatColumnVector
+FloatComplexQRP::Pvec (void) const
+{
+  Array<float> pa (p.pvec ());
+  FloatColumnVector pv (MArray<float> (pa) + 1.0f);
+  return pv;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxQRP.h b/liboctave/fCmplxQRP.h
new file mode 100644
index 0000000..7d384d1
--- /dev/null
+++ b/liboctave/fCmplxQRP.h
@@ -0,0 +1,76 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexQRP_h)
+#define octave_FloatComplexQRP_h 1
+
+#include <iosfwd>
+
+#include "fCmplxQR.h"
+#include "PermMatrix.h"
+#include "fColVector.h"
+
+class
+OCTAVE_API
+FloatComplexQRP : public FloatComplexQR
+{
+public:
+
+  FloatComplexQRP (void) : FloatComplexQR (), p () { }
+
+  FloatComplexQRP (const FloatComplexMatrix&, QR::type = QR::std);
+
+  FloatComplexQRP (const FloatComplexQRP& a) : FloatComplexQR (a), p (a.p) { }
+
+  FloatComplexQRP& operator = (const FloatComplexQRP& a)
+    {
+      if (this != &a)
+	{
+	  FloatComplexQR::operator = (a);
+	  p = a.p;
+	}
+      return *this;
+    }
+
+  ~FloatComplexQRP (void) { }
+
+  void init (const FloatComplexMatrix&, QR::type = QR::std);
+
+  PermMatrix P (void) const { return p; }
+
+  FloatColumnVector Pvec (void) const;
+
+  friend std::ostream&  operator << (std::ostream&, const FloatComplexQRP&);
+
+private:
+
+  PermMatrix p;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxSCHUR.cc b/liboctave/fCmplxSCHUR.cc
new file mode 100644
index 0000000..ae6931d
--- /dev/null
+++ b/liboctave/fCmplxSCHUR.cc
@@ -0,0 +1,142 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fCmplxSCHUR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgeesx, CGEESX) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     FloatComplexSCHUR::select_function,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, FloatComplex*, const octave_idx_type&, octave_idx_type&,
+			     FloatComplex*, FloatComplex*, const octave_idx_type&, float&,
+			     float&, FloatComplex*, const octave_idx_type&, float*, octave_idx_type*,
+			     octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+static octave_idx_type
+select_ana (const FloatComplex& a)
+{
+  return a.real () < 0.0;
+}
+
+static octave_idx_type
+select_dig (const FloatComplex& a)
+{
+  return (abs (a) < 1.0);
+}
+
+octave_idx_type
+FloatComplexSCHUR::init (const FloatComplexMatrix& a, const std::string& ord, 
+		    bool calc_unitary)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler)
+	("FloatComplexSCHUR requires square matrix");
+      return -1;
+    }
+
+  // Workspace requirements may need to be fixed if any of the
+  // following change.
+
+  char jobvs;
+  char sense = 'N';
+  char sort = 'N';
+
+  if (calc_unitary)
+    jobvs = 'V';
+  else
+    jobvs = 'N';
+
+  char ord_char = ord.empty () ? 'U' : ord[0];
+
+  if (ord_char == 'A' || ord_char == 'D' || ord_char == 'a' || ord_char == 'd')
+    sort = 'S';
+
+  if (ord_char == 'A' || ord_char == 'a')
+    selector = select_ana;
+  else if (ord_char == 'D' || ord_char == 'd')
+    selector = select_dig;
+  else
+    selector = 0;
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 8 * n;
+  octave_idx_type info;
+  octave_idx_type sdim;
+  float rconde;
+  float rcondv;
+
+  schur_mat = a;
+  if (calc_unitary)
+    unitary_mat.resize (n, n);
+
+  FloatComplex *s = schur_mat.fortran_vec ();
+  FloatComplex *q = unitary_mat.fortran_vec ();
+
+  Array<float> rwork (n);
+  float *prwork = rwork.fortran_vec ();
+
+  Array<FloatComplex> w (n);
+  FloatComplex *pw = w.fortran_vec ();
+
+  Array<FloatComplex> work (lwork);
+  FloatComplex *pwork = work.fortran_vec ();
+
+  // BWORK is not referenced for non-ordered Schur.
+  Array<octave_idx_type> bwork ((ord_char == 'N' || ord_char == 'n') ? 0 : n);
+  octave_idx_type *pbwork = bwork.fortran_vec ();
+
+  F77_XFCN (cgeesx, CGEESX, (F77_CONST_CHAR_ARG2 (&jobvs, 1),
+			     F77_CONST_CHAR_ARG2 (&sort, 1),
+			     selector,
+			     F77_CONST_CHAR_ARG2 (&sense, 1),
+			     n, s, n, sdim, pw, q, n, rconde, rcondv,
+			     pwork, lwork, prwork, pbwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxSCHUR.h b/liboctave/fCmplxSCHUR.h
new file mode 100644
index 0000000..2862b19
--- /dev/null
+++ b/liboctave/fCmplxSCHUR.h
@@ -0,0 +1,88 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexSCHUR_h)
+#define octave_FloatComplexSCHUR_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "fCMatrix.h"
+
+class
+OCTAVE_API
+FloatComplexSCHUR
+{
+public:
+
+  FloatComplexSCHUR (void)
+    : schur_mat (), unitary_mat () { }
+
+  FloatComplexSCHUR (const FloatComplexMatrix& a, const std::string& ord,
+		bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { init (a, ord, calc_unitary); }
+
+  FloatComplexSCHUR (const FloatComplexMatrix& a, const std::string& ord, octave_idx_type& info,
+		bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { info = init (a, ord, calc_unitary); }
+
+  FloatComplexSCHUR (const FloatComplexSCHUR& a)
+    : schur_mat (a.schur_mat), unitary_mat (a.unitary_mat) { }
+
+  FloatComplexSCHUR& operator = (const FloatComplexSCHUR& a)
+    {
+      if (this != &a)
+	{
+	  schur_mat = a.schur_mat;
+	  unitary_mat = a.unitary_mat;
+	}
+      return *this;
+    }
+
+  ~FloatComplexSCHUR (void) { }
+
+  FloatComplexMatrix schur_matrix (void) const { return schur_mat; }
+
+  FloatComplexMatrix unitary_matrix (void) const { return unitary_mat; }
+
+  friend std::ostream& operator << (std::ostream& os, const FloatComplexSCHUR& a);
+
+  typedef octave_idx_type (*select_function) (const FloatComplex&);
+
+private:
+
+  FloatComplexMatrix schur_mat;
+  FloatComplexMatrix unitary_mat;
+
+  select_function selector;
+
+  octave_idx_type init (const FloatComplexMatrix& a, const std::string& ord, bool calc_unitary);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxSVD.cc b/liboctave/fCmplxSVD.cc
new file mode 100644
index 0000000..2cd6e90
--- /dev/null
+++ b/liboctave/fCmplxSVD.cc
@@ -0,0 +1,173 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fCmplxSVD.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (cgesvd, CGESVD) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, FloatComplex*,
+			     const octave_idx_type&, float*, FloatComplex*, const octave_idx_type&,
+			     FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+			     float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+FloatComplexMatrix
+FloatComplexSVD::left_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("FloatComplexSVD: U not computed because type == SVD::sigma_only");
+      return FloatComplexMatrix ();
+    }
+  else
+    return left_sm;
+}
+
+FloatComplexMatrix
+FloatComplexSVD::right_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("FloatComplexSVD: V not computed because type == SVD::sigma_only");
+      return FloatComplexMatrix ();
+    }
+  else
+    return right_sm;
+}
+
+octave_idx_type
+FloatComplexSVD::init (const FloatComplexMatrix& a, SVD::type svd_type)
+{
+  octave_idx_type info;
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  FloatComplexMatrix atmp = a;
+  FloatComplex *tmp_data = atmp.fortran_vec ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  octave_idx_type max_mn = m > n ? m : n;
+
+  char jobu = 'A';
+  char jobv = 'A';
+
+  octave_idx_type ncol_u = m;
+  octave_idx_type nrow_vt = n;
+  octave_idx_type nrow_s = m;
+  octave_idx_type ncol_s = n;
+
+  switch (svd_type)
+    {
+    case SVD::economy:
+      jobu = jobv = 'S';
+      ncol_u = nrow_vt = nrow_s = ncol_s = min_mn;
+      break;
+
+    case SVD::sigma_only:
+
+      // Note:  for this case, both jobu and jobv should be 'N', but
+      // there seems to be a bug in dgesvd from Lapack V2.0.  To
+      // demonstrate the bug, set both jobu and jobv to 'N' and find
+      // the singular values of [eye(3), eye(3)].  The result is
+      // [-sqrt(2), -sqrt(2), -sqrt(2)].
+      //
+      // For Lapack 3.0, this problem seems to be fixed.
+
+      jobu = 'N';
+      jobv = 'N';
+      ncol_u = nrow_vt = 1;
+      break;
+
+    default:
+      break;
+    }
+
+  type_computed = svd_type;
+
+  if (! (jobu == 'N' || jobu == 'O'))
+    left_sm.resize (m, ncol_u);
+
+  FloatComplex *u = left_sm.fortran_vec ();
+
+  sigma.resize (nrow_s, ncol_s);
+  float *s_vec = sigma.fortran_vec ();
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm.resize (nrow_vt, n);
+
+  FloatComplex *vt = right_sm.fortran_vec ();
+
+  octave_idx_type lrwork = 5*max_mn;
+
+  Array<float> rwork (lrwork);
+
+  // Ask ZGESVD what the dimension of WORK should be.
+
+  octave_idx_type lwork = -1;
+
+  Array<FloatComplex> work (1);
+
+  F77_XFCN (cgesvd, CGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork,
+			     rwork.fortran_vec (), info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  lwork = static_cast<octave_idx_type> (work(0).real ());
+  work.resize (lwork);
+
+  F77_XFCN (cgesvd, CGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork,
+			     rwork.fortran_vec (), info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm = right_sm.hermitian ();
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fCmplxSVD.h b/liboctave/fCmplxSVD.h
new file mode 100644
index 0000000..dc77780
--- /dev/null
+++ b/liboctave/fCmplxSVD.h
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatComplexSVD_h)
+#define octave_FloatComplexSVD_h 1
+
+#include <iosfwd>
+
+#include "fDiagMatrix.h"
+#include "fCMatrix.h"
+#include "dbleSVD.h"
+
+class
+OCTAVE_API
+FloatComplexSVD
+{
+public:
+
+  FloatComplexSVD (void) { }
+
+  FloatComplexSVD (const FloatComplexMatrix& a, SVD::type svd_type = SVD::std)
+    {
+      init (a, svd_type);
+    }
+
+  FloatComplexSVD (const FloatComplexMatrix& a, octave_idx_type& info,
+	      SVD::type svd_type = SVD::std)
+    {
+      info = init (a, svd_type);
+    }
+
+  FloatComplexSVD (const FloatComplexSVD& a)
+    : type_computed (a.type_computed),
+      sigma (a.sigma), left_sm (a.left_sm), right_sm (a.right_sm) { }
+
+  FloatComplexSVD& operator = (const FloatComplexSVD& a)
+    {
+      if (this != &a)
+	{
+	  type_computed = a.type_computed;
+	  sigma = a.sigma;
+	  left_sm = a.left_sm;
+	  right_sm = a.right_sm;
+	}
+      return *this;
+    }
+
+  ~FloatComplexSVD (void) { }
+
+  FloatDiagMatrix singular_values (void) const { return sigma; }
+
+  FloatComplexMatrix left_singular_matrix (void) const;
+
+  FloatComplexMatrix right_singular_matrix (void) const;
+
+  friend std::ostream&  operator << (std::ostream& os, const FloatComplexSVD& a);
+
+private:
+
+  SVD::type type_computed;
+
+  FloatDiagMatrix sigma;
+  FloatComplexMatrix left_sm;
+  FloatComplexMatrix right_sm;
+
+  octave_idx_type init (const FloatComplexMatrix& a, SVD::type svd_type = SVD::std);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fColVector.cc b/liboctave/fColVector.cc
new file mode 100644
index 0000000..038d504
--- /dev/null
+++ b/liboctave/fColVector.cc
@@ -0,0 +1,343 @@
+// ColumnVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgemv, SGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const float&,
+			   const float*, const octave_idx_type&, const float*,
+			   const octave_idx_type&, const float&, float*,
+			   const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+}
+
+// Column Vector class.
+
+bool
+FloatColumnVector::operator == (const FloatColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+FloatColumnVector::operator != (const FloatColumnVector& a) const
+{
+  return !(*this == a);
+}
+
+FloatColumnVector&
+FloatColumnVector::insert (const FloatColumnVector& a, octave_idx_type r)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatColumnVector&
+FloatColumnVector::fill (float val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatColumnVector&
+FloatColumnVector::fill (float val, octave_idx_type r1, octave_idx_type r2)
+{
+  octave_idx_type len = length ();
+
+  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  if (r2 >= r1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = r1; i <= r2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatColumnVector
+FloatColumnVector::stack (const FloatColumnVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nr_insert = len;
+  FloatColumnVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nr_insert);
+  return retval;
+}
+
+FloatRowVector
+FloatColumnVector::transpose (void) const
+{
+  return MArray<float>::transpose();
+}
+
+FloatColumnVector
+real (const FloatComplexColumnVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  FloatColumnVector retval;
+  if (a_len > 0)
+    retval = FloatColumnVector (mx_inline_real_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+FloatColumnVector
+imag (const FloatComplexColumnVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  FloatColumnVector retval;
+  if (a_len > 0)
+    retval = FloatColumnVector (mx_inline_imag_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+// resize is the destructive equivalent for this one
+
+FloatColumnVector
+FloatColumnVector::extract (octave_idx_type r1, octave_idx_type r2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+
+  FloatColumnVector result (new_r);
+
+  for (octave_idx_type i = 0; i < new_r; i++)
+    result.xelem (i) = elem (r1+i);
+
+  return result;
+}
+
+FloatColumnVector
+FloatColumnVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  FloatColumnVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.xelem (i) = elem (r1+i);
+
+  return result;
+}
+
+// matrix by column vector -> column vector operations
+
+FloatColumnVector
+operator * (const FloatMatrix& m, const FloatColumnVector& a)
+{
+  FloatColumnVector retval;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+  else
+    {
+      if (nr == 0 || nc == 0)
+	retval.resize (nr, 0.0);
+      else
+	{
+	  octave_idx_type ld = nr;
+
+	  retval.resize (nr);
+	  float *y = retval.fortran_vec ();
+
+	  F77_XFCN (sgemv, SGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
+				   nr, nc, 1.0, m.data (), ld,
+				   a.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+// diagonal matrix by column vector -> column vector operations
+
+FloatColumnVector
+operator * (const FloatDiagMatrix& m, const FloatColumnVector& a)
+{
+  FloatColumnVector retval;
+
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.cols ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (nc != a_len)
+    gripe_nonconformant ("operator *", nr, nc, a_len, 1);
+  else
+    {
+      if (nr == 0 || nc == 0)
+	retval.resize (nr, 0.0);
+      else
+	{
+	  retval.resize (nr);
+
+	  for (octave_idx_type i = 0; i < a_len; i++)
+	    retval.elem (i) = a.elem (i) * m.elem (i, i);
+
+	  for (octave_idx_type i = a_len; i < nr; i++)
+	    retval.elem (i) = 0.0;
+	}
+    }
+
+  return retval;
+}
+
+// other operations
+
+FloatColumnVector
+FloatColumnVector::map (dmapper fcn) const
+{
+  return MArray<float>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexColumnVector
+FloatColumnVector::map (cmapper fcn) const
+{
+  return MArray<float>::map<FloatComplex> (func_ptr (fcn));
+}
+
+float
+FloatColumnVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  float res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) < res)
+      res = elem (i);
+
+  return res;
+}
+
+float
+FloatColumnVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0.0;
+
+  float res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) > res)
+      res = elem (i);
+
+  return res;
+}
+
+std::ostream&
+operator << (std::ostream& os, const FloatColumnVector& a)
+{
+//  int field_width = os.precision () + 7;
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << /* setw (field_width) << */ a.elem (i) << "\n";
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatColumnVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      float tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fColVector.h b/liboctave/fColVector.h
new file mode 100644
index 0000000..ea53468
--- /dev/null
+++ b/liboctave/fColVector.h
@@ -0,0 +1,118 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatColumnVector_h)
+#define octave_FloatColumnVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+FloatColumnVector : public MArray<float>
+{
+public:
+
+  FloatColumnVector (void) : MArray<float> () { }
+
+  explicit FloatColumnVector (octave_idx_type n) : MArray<float> (n) { }
+
+  FloatColumnVector (octave_idx_type n, float val) : MArray<float> (n, val) { }
+
+  FloatColumnVector (const FloatColumnVector& a) : MArray<float> (a) { }
+
+  FloatColumnVector (const MArray<float>& a) : MArray<float> (a) { }
+
+  FloatColumnVector& operator = (const FloatColumnVector& a)
+    {
+      MArray<float>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatColumnVector& a) const;
+  bool operator != (const FloatColumnVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  FloatColumnVector& insert (const FloatColumnVector& a, octave_idx_type r);
+
+  FloatColumnVector& fill (float val);
+  FloatColumnVector& fill (float val, octave_idx_type r1, octave_idx_type r2);
+
+  FloatColumnVector stack (const FloatColumnVector& a) const;
+
+  FloatRowVector transpose (void) const;
+
+  friend OCTAVE_API FloatColumnVector real (const FloatComplexColumnVector& a);
+  friend OCTAVE_API FloatColumnVector imag (const FloatComplexColumnVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  FloatColumnVector extract (octave_idx_type r1, octave_idx_type r2) const;
+
+  FloatColumnVector extract_n (octave_idx_type r1, octave_idx_type n) const;
+
+  // matrix by column vector -> column vector operations
+
+  friend OCTAVE_API FloatColumnVector operator * (const FloatMatrix& a, const FloatColumnVector& b);
+
+  // diagonal matrix by column vector -> column vector operations
+
+  friend OCTAVE_API FloatColumnVector operator * (const FloatDiagMatrix& a, const FloatColumnVector& b);
+
+  // other operations
+
+  typedef float (*dmapper) (float);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+
+  FloatColumnVector map (dmapper fcn) const;
+  FloatComplexColumnVector map (cmapper fcn) const;
+
+  float min (void) const;
+  float max (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatColumnVector& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatColumnVector& a);
+
+private:
+
+  FloatColumnVector (float *d, octave_idx_type l) : MArray<float> (d, l) { }
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API FloatColumnVector real (const FloatComplexColumnVector& a);
+extern OCTAVE_API FloatColumnVector imag (const FloatComplexColumnVector& a);
+
+MARRAY_FORWARD_DEFS (MArray, FloatColumnVector, float)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fDiagMatrix.cc b/liboctave/fDiagMatrix.cc
new file mode 100644
index 0000000..fe94f0d
--- /dev/null
+++ b/liboctave/fDiagMatrix.cc
@@ -0,0 +1,415 @@
+// FloatDiagMatrix manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
+              2005, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Diagonal Matrix class.
+
+bool
+FloatDiagMatrix::operator == (const FloatDiagMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return 0;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+FloatDiagMatrix::operator != (const FloatDiagMatrix& a) const
+{
+  return !(*this == a);
+}
+
+FloatDiagMatrix&
+FloatDiagMatrix::fill (float val)
+{
+  for (octave_idx_type i = 0; i < length (); i++)
+    elem (i, i) = val;
+  return *this;
+}
+
+FloatDiagMatrix&
+FloatDiagMatrix::fill (float val, octave_idx_type beg, octave_idx_type end)
+{
+  if (beg < 0 || end >= length () || end < beg)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = beg; i <= end; i++)
+    elem (i, i) = val;
+
+  return *this;
+}
+
+FloatDiagMatrix&
+FloatDiagMatrix::fill (const FloatColumnVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+FloatDiagMatrix&
+FloatDiagMatrix::fill (const FloatRowVector& a)
+{
+  octave_idx_type len = length ();
+  if (a.length () != len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
+  return *this;
+}
+
+FloatDiagMatrix&
+FloatDiagMatrix::fill (const FloatColumnVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+FloatDiagMatrix&
+FloatDiagMatrix::fill (const FloatRowVector& a, octave_idx_type beg)
+{
+  octave_idx_type a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
+  return *this;
+}
+
+FloatDiagMatrix
+FloatDiagMatrix::abs (void) const
+{
+  FloatDiagMatrix retval (rows (), cols ());
+  for (octave_idx_type i = 0; i < rows (); i++)
+    retval(i, i) = std::abs (elem (i, i));
+  return retval;
+}
+
+FloatDiagMatrix
+real (const FloatComplexDiagMatrix& a)
+{
+  FloatDiagMatrix retval;
+  octave_idx_type a_len = a.length ();
+  if (a_len > 0)
+    retval = FloatDiagMatrix (mx_inline_real_dup (a.data (), a_len), a.rows (),
+			 a.cols ());
+  return retval;
+}
+
+FloatDiagMatrix
+imag (const FloatComplexDiagMatrix& a)
+{
+  FloatDiagMatrix retval;
+  octave_idx_type a_len = a.length ();
+  if (a_len > 0)
+    retval = FloatDiagMatrix (mx_inline_imag_dup (a.data (), a_len), a.rows (),
+			 a.cols ());
+  return retval;
+}
+
+FloatMatrix
+FloatDiagMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  FloatMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.elem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+FloatRowVector
+FloatDiagMatrix::row (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= r)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return FloatRowVector (); 
+    }
+
+  FloatRowVector retval (c, 0.0);
+  if (r <= c || (r > c && i < c))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+FloatRowVector
+FloatDiagMatrix::row (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return FloatRowVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return row (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return row (rows () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return FloatRowVector (); 
+    }
+}
+
+FloatColumnVector
+FloatDiagMatrix::column (octave_idx_type i) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  if (i < 0 || i >= c)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return FloatColumnVector (); 
+    }
+
+  FloatColumnVector retval (r, 0.0);
+  if (r >= c || (r < c && i < r))
+    retval.elem (i) = elem (i, i);
+
+  return retval;
+}
+
+FloatColumnVector
+FloatDiagMatrix::column (char *s) const
+{
+  if (! s)
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return FloatColumnVector (); 
+    }
+
+  char c = *s;
+  if (c == 'f' || c == 'F')
+    return column (static_cast<octave_idx_type>(0));
+  else if (c == 'l' || c == 'L')
+    return column (cols () - 1);
+  else
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return FloatColumnVector (); 
+    }
+}
+
+FloatDiagMatrix
+FloatDiagMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  return inverse (info);
+}
+
+FloatDiagMatrix
+FloatDiagMatrix::inverse (octave_idx_type &info) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  octave_idx_type len = length ();
+  if (r != c)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return FloatDiagMatrix ();
+    }
+
+  FloatDiagMatrix retval (r, c);
+
+  info = 0;
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      if (elem (i, i) == 0.0)
+	{
+	  info = -1;
+	  return *this;
+	}
+      else
+	retval.elem (i, i) = 1.0 / elem (i, i);
+    }
+
+  return retval;
+}
+
+FloatDiagMatrix
+FloatDiagMatrix::pseudo_inverse (void) const
+{
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
+  octave_idx_type len = length ();
+
+  FloatDiagMatrix retval (c, r);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      if (elem (i, i) != 0.0f)
+        retval.elem (i, i) = 1.0f / elem (i, i);
+      else
+        retval.elem (i, i) = 0.0f;
+    }
+
+  return retval;
+}
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+FloatDiagMatrix
+operator * (const FloatDiagMatrix& a, const FloatDiagMatrix& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nr)
+    {
+      gripe_nonconformant ("operaotr *", a_nr, a_nc, b_nr, b_nc);
+      return FloatDiagMatrix ();
+    }
+
+  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+    return FloatDiagMatrix (a_nr, a_nc, 0.0);
+
+  FloatDiagMatrix c (a_nr, b_nc);
+
+  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      float a_element = a.elem (i, i);
+      float b_element = b.elem (i, i);
+
+      c.elem (i, i) = a_element * b_element;
+    }
+
+  return c;
+}
+
+// other operations
+
+FloatDET
+FloatDiagMatrix::determinant (void) const
+{
+  FloatDET det (1.0f);
+  if (rows () != cols ())
+    {
+      (*current_liboctave_error_handler) ("determinant requires square matrix");
+      det = 0.0f;
+    }
+  else
+    {
+      octave_idx_type len = length ();
+      for (octave_idx_type i = 0; i < len; i++)
+        det *= elem (i, i);
+    }
+
+  return det;
+}
+
+float
+FloatDiagMatrix::rcond (void) const
+{
+  FloatColumnVector av = diag (0).map (fabsf);
+  float amx = av.max (), amn = av.min ();
+  return amx == 0 ? 0.0f : amn / amx;
+}
+
+std::ostream&
+operator << (std::ostream& os, const FloatDiagMatrix& a)
+{
+//  int field_width = os.precision () + 7;
+
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  if (i == j)
+	    os << " " /* setw (field_width) */ << a.elem (i, i);
+	  else
+	    os << " " /* setw (field_width) */ << 0.0;
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fDiagMatrix.h b/liboctave/fDiagMatrix.h
new file mode 100644
index 0000000..0a456bc
--- /dev/null
+++ b/liboctave/fDiagMatrix.h
@@ -0,0 +1,132 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatDiagMatrix_h)
+#define octave_FloatDiagMatrix_h 1
+
+#include "MDiagArray2.h"
+
+#include "fRowVector.h"
+#include "fColVector.h"
+#include "DET.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+FloatDiagMatrix : public MDiagArray2<float>
+{
+friend class FloatSVD;
+friend class FloatComplexSVD;
+
+public:
+
+  FloatDiagMatrix (void) : MDiagArray2<float> () { }
+
+  FloatDiagMatrix (octave_idx_type r, octave_idx_type c) : MDiagArray2<float> (r, c) { }
+
+  FloatDiagMatrix (octave_idx_type r, octave_idx_type c, float val) : MDiagArray2<float> (r, c, val) { }
+
+  FloatDiagMatrix (const FloatDiagMatrix& a) : MDiagArray2<float> (a) { }
+
+  FloatDiagMatrix (const MDiagArray2<float>& a) : MDiagArray2<float> (a) { }
+
+  template <class U>
+  FloatDiagMatrix (const DiagArray2<U>& a) : MDiagArray2<float> (a) { }
+
+  explicit FloatDiagMatrix (const FloatRowVector& a) : MDiagArray2<float> (a) { }
+
+  explicit FloatDiagMatrix (const FloatColumnVector& a) : MDiagArray2<float> (a) { }
+
+  FloatDiagMatrix& operator = (const FloatDiagMatrix& a)
+    {
+      MDiagArray2<float>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatDiagMatrix& a) const;
+  bool operator != (const FloatDiagMatrix& a) const;
+
+  FloatDiagMatrix& fill (float val);
+  FloatDiagMatrix& fill (float val, octave_idx_type beg, octave_idx_type end);
+  FloatDiagMatrix& fill (const FloatColumnVector& a);
+  FloatDiagMatrix& fill (const FloatRowVector& a);
+  FloatDiagMatrix& fill (const FloatColumnVector& a, octave_idx_type beg);
+  FloatDiagMatrix& fill (const FloatRowVector& a, octave_idx_type beg);
+
+  FloatDiagMatrix transpose (void) const { return MDiagArray2<float>::transpose(); }
+  FloatDiagMatrix abs (void) const; 
+
+  friend OCTAVE_API FloatDiagMatrix real (const FloatComplexDiagMatrix& a);
+  friend OCTAVE_API FloatDiagMatrix imag (const FloatComplexDiagMatrix& a);
+
+  // resize is the destructive analog for this one
+
+  FloatMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  // extract row or column i.
+
+  FloatRowVector row (octave_idx_type i) const;
+  FloatRowVector row (char *s) const;
+
+  FloatColumnVector column (octave_idx_type i) const;
+  FloatColumnVector column (char *s) const;
+
+  FloatDiagMatrix inverse (void) const;
+  FloatDiagMatrix inverse (octave_idx_type& info) const;
+  FloatDiagMatrix pseudo_inverse (void) const;
+
+  // other operations
+
+  FloatColumnVector diag (octave_idx_type k = 0) const
+    { return MDiagArray2<float>::diag (k); }
+
+  FloatDET determinant (void) const;
+  float rcond (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatDiagMatrix& a);
+
+private:
+
+  FloatDiagMatrix (float *d, octave_idx_type nr, octave_idx_type nc) : MDiagArray2<float> (d, nr, nc) { }
+};
+
+OCTAVE_API FloatDiagMatrix real (const FloatComplexDiagMatrix& a);
+OCTAVE_API FloatDiagMatrix imag (const FloatComplexDiagMatrix& a);
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+OCTAVE_API FloatDiagMatrix
+operator * (const FloatDiagMatrix& a, const FloatDiagMatrix& b);
+
+MDIAGARRAY2_FORWARD_DEFS (MDiagArray2, FloatDiagMatrix, float)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fEIG.cc b/liboctave/fEIG.cc
new file mode 100644
index 0000000..bb9c5f5
--- /dev/null
+++ b/liboctave/fEIG.cc
@@ -0,0 +1,868 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fEIG.h"
+#include "fColVector.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgeev, SGEEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, float*, const octave_idx_type&, float*,
+			   float*, float*, const octave_idx_type&, float*,
+			   const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cgeev, CGEEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, FloatComplex*, const octave_idx_type&, FloatComplex*,
+			   FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+			   FloatComplex*, const octave_idx_type&, float*, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ssyev, SSYEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, float*, const octave_idx_type&, float*,
+			   float*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cheev, CHEEV) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, FloatComplex*, const octave_idx_type&, float*,
+			   FloatComplex*, const octave_idx_type&, float*, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (spotrf, SPOTRF) (F77_CONST_CHAR_ARG_DECL, 
+			   const octave_idx_type&, 
+			   float*, const octave_idx_type&,
+			   octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cpotrf, CPOTRF) (F77_CONST_CHAR_ARG_DECL, 
+			   const octave_idx_type&, 
+			   FloatComplex*, const octave_idx_type&,
+			   octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sggev, SGGEV) (F77_CONST_CHAR_ARG_DECL, 
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   float*, const octave_idx_type&,
+			   float*, const octave_idx_type&,
+			   float*, float*, float*,
+			   float*, const octave_idx_type&, float*, const octave_idx_type&,
+			   float*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (ssygv, SSYGV) (const octave_idx_type&,
+			   F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   float*, const octave_idx_type&,
+			   float*, const octave_idx_type&,
+			   float*, float*, const octave_idx_type&, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (cggev, CGGEV) (F77_CONST_CHAR_ARG_DECL, 
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   FloatComplex*, const octave_idx_type&,
+			   FloatComplex*, const octave_idx_type&,
+			   FloatComplex*, FloatComplex*,
+			   FloatComplex*, const octave_idx_type&, FloatComplex*, const octave_idx_type&,
+			   FloatComplex*, const octave_idx_type&, float*, octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (chegv, CHEGV) (const octave_idx_type&,
+			   F77_CONST_CHAR_ARG_DECL, 
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, 
+			   FloatComplex*, const octave_idx_type&,
+			   FloatComplex*, const octave_idx_type&,
+			   float*, FloatComplex*, const octave_idx_type&, float*, 
+			   octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+}
+
+octave_idx_type
+FloatEIG::init (const FloatMatrix& a, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  if (a.is_symmetric ())
+    return symmetric_init (a, calc_ev);
+
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatMatrix atmp = a;
+  float *tmp_data = atmp.fortran_vec ();
+
+  Array<float> wr (n);
+  float *pwr = wr.fortran_vec ();
+
+  Array<float> wi (n);
+  float *pwi = wi.fortran_vec ();
+
+  volatile octave_idx_type nvr = calc_ev ? n : 0;
+  FloatMatrix vr (nvr, nvr);
+  float *pvr = vr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  float dummy_work;
+
+  float *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (sgeev, SGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, tmp_data, n, pwr, pwi, dummy,
+			   idummy, pvr, n, &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<float> work (lwork);
+      float *pwork = work.fortran_vec ();
+
+      F77_XFCN (sgeev, SGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, tmp_data, n, pwr, pwi, dummy,
+			       idummy, pvr, n, pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in sgeev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("sgeev failed to converge");
+	  return info;
+	}
+
+      lambda.resize (n);
+      v.resize (nvr, nvr);
+
+      for (octave_idx_type j = 0; j < n; j++)
+	{
+	  if (wi.elem (j) == 0.0)
+	    {
+	      lambda.elem (j) = FloatComplex (wr.elem (j));
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		v.elem (i, j) = vr.elem (i, j);
+	    }
+	  else
+	    {
+	      if (j+1 >= n)
+		{
+		  (*current_liboctave_error_handler) ("EIG: internal error");
+		  return -1;
+		}
+
+	      lambda.elem(j) = FloatComplex (wr.elem(j), wi.elem(j));
+	      lambda.elem(j+1) = FloatComplex (wr.elem(j+1), wi.elem(j+1));
+
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		{
+		  float real_part = vr.elem (i, j);
+		  float imag_part = vr.elem (i, j+1);
+		  v.elem (i, j) = FloatComplex (real_part, imag_part);
+		  v.elem (i, j+1) = FloatComplex (real_part, -imag_part);
+		}
+	      j++;
+	    }
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("sgeev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type 
+FloatEIG::symmetric_init (const FloatMatrix& a, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatMatrix atmp = a;
+  float *tmp_data = atmp.fortran_vec ();
+
+  FloatColumnVector wr (n);
+  float *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  float dummy_work;
+
+  F77_XFCN (ssyev, SSYEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, tmp_data, n, pwr, &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<float> work (lwork);
+      float *pwork = work.fortran_vec ();
+
+      F77_XFCN (ssyev, SSYEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, tmp_data, n, pwr, pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in ssyev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("ssyev failed to converge");
+	  return info;
+	}
+
+      lambda = FloatComplexColumnVector (wr);
+      v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("ssyev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+FloatEIG::init (const FloatComplexMatrix& a, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  if (a.is_hermitian ())
+    return hermitian_init (a, calc_ev);
+
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatComplexMatrix atmp = a;
+  FloatComplex *tmp_data = atmp.fortran_vec ();
+
+  FloatComplexColumnVector w (n);
+  FloatComplex *pw = w.fortran_vec ();
+
+  octave_idx_type nvr = calc_ev ? n : 0;
+  FloatComplexMatrix vtmp (nvr, nvr);
+  FloatComplex *pv = vtmp.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  FloatComplex dummy_work;
+
+  octave_idx_type lrwork = 2*n;
+  Array<float> rwork (lrwork);
+  float *prwork = rwork.fortran_vec ();
+
+  FloatComplex *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (cgeev, CGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, tmp_data, n, pw, dummy, idummy,
+			   pv, n, &dummy_work, lwork, prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<FloatComplex> work (lwork);
+      FloatComplex *pwork = work.fortran_vec ();
+
+      F77_XFCN (cgeev, CGEEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, tmp_data, n, pw, dummy, idummy,
+			       pv, n, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in cgeev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("cgeev failed to converge");
+	  return info;
+	}
+
+      lambda = w;
+      v = vtmp;
+    }
+  else
+    (*current_liboctave_error_handler) ("cgeev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+FloatEIG::hermitian_init (const FloatComplexMatrix& a, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+
+  if (n != a.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatComplexMatrix atmp = a;
+  FloatComplex *tmp_data = atmp.fortran_vec ();
+
+  FloatColumnVector wr (n);
+  float *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  FloatComplex dummy_work;
+
+  octave_idx_type lrwork = 3*n;
+  Array<float> rwork (lrwork);
+  float *prwork = rwork.fortran_vec ();
+
+  F77_XFCN (cheev, CHEEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, tmp_data, n, pwr, &dummy_work, lwork,
+			   prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<FloatComplex> work (lwork);
+      FloatComplex *pwork = work.fortran_vec ();
+
+      F77_XFCN (cheev, CHEEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, tmp_data, n, pwr, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in cheev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("cheev failed to converge");
+	  return info;
+	}
+
+      lambda = FloatComplexColumnVector (wr);
+      v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("cheev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+FloatEIG::init (const FloatMatrix& a, const FloatMatrix& b, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatMatrix tmp = b;
+  float *tmp_data = tmp.fortran_vec ();
+
+  F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, tmp_data, n, 
+			     info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (a.is_symmetric () && b.is_symmetric () && info == 0)
+    return symmetric_init (a, b, calc_ev);
+
+  FloatMatrix atmp = a;
+  float *atmp_data = atmp.fortran_vec ();
+
+  FloatMatrix btmp = b;
+  float *btmp_data = btmp.fortran_vec ();
+
+  Array<float> ar (n);
+  float *par = ar.fortran_vec ();
+
+  Array<float> ai (n);
+  float *pai = ai.fortran_vec ();
+
+  Array<float> beta (n);
+  float *pbeta = beta.fortran_vec ();
+
+  volatile octave_idx_type nvr = calc_ev ? n : 0;
+  FloatMatrix vr (nvr, nvr);
+  float *pvr = vr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  float dummy_work;
+
+  float *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (sggev, SGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, atmp_data, n, btmp_data, n, 
+			   par, pai, pbeta,
+			   dummy, idummy, pvr, n,
+			   &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<float> work (lwork);
+      float *pwork = work.fortran_vec ();
+
+      F77_XFCN (sggev, SGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, atmp_data, n, btmp_data, n, 
+			       par, pai, pbeta,
+			       dummy, idummy, pvr, n,
+			       pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in sggev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("sggev failed to converge");
+	  return info;
+	}
+
+      lambda.resize (n);
+      v.resize (nvr, nvr);
+
+      for (octave_idx_type j = 0; j < n; j++)
+	{
+	  if (ai.elem (j) == 0.0)
+	    {
+	      lambda.elem (j) = FloatComplex (ar.elem (j) / beta.elem (j));
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		v.elem (i, j) = vr.elem (i, j);
+	    }
+	  else
+	    {
+	      if (j+1 >= n)
+		{
+		  (*current_liboctave_error_handler) ("EIG: internal error");
+		  return -1;
+		}
+
+	      lambda.elem(j) = FloatComplex (ar.elem(j) / beta.elem (j), 
+	                                     ai.elem(j) / beta.elem (j));
+	      lambda.elem(j+1) = FloatComplex (ar.elem(j+1) / beta.elem (j+1), 
+	                                       ai.elem(j+1) / beta.elem (j+1));
+
+	      for (octave_idx_type i = 0; i < nvr; i++)
+		{
+		  float real_part = vr.elem (i, j);
+		  float imag_part = vr.elem (i, j+1);
+		  v.elem (i, j) = FloatComplex (real_part, imag_part);
+		  v.elem (i, j+1) = FloatComplex (real_part, -imag_part);
+		}
+	      j++;
+	    }
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("sggev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type 
+FloatEIG::symmetric_init (const FloatMatrix& a, const FloatMatrix& b, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatMatrix atmp = a;
+  float *atmp_data = atmp.fortran_vec ();
+
+  FloatMatrix btmp = b;
+  float *btmp_data = btmp.fortran_vec ();
+
+  FloatColumnVector wr (n);
+  float *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  float dummy_work;
+
+  F77_XFCN (ssygv, SSYGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, atmp_data, n, 
+			   btmp_data, n, 
+			   pwr, &dummy_work, lwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work);
+      Array<float> work (lwork);
+      float *pwork = work.fortran_vec ();
+
+      F77_XFCN (ssygv, SSYGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, atmp_data, n, 
+			       btmp_data, n, 
+			       pwr, pwork, lwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in ssygv");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("ssygv failed to converge");
+	  return info;
+	}
+
+      lambda = FloatComplexColumnVector (wr);
+      v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("ssygv workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+FloatEIG::init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, bool calc_ev)
+{
+  if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ())
+    {
+      (*current_liboctave_error_handler)
+	("EIG: matrix contains Inf or NaN values");
+      return -1;
+    }
+
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatComplexMatrix tmp = b;
+  FloatComplex *tmp_data = tmp.fortran_vec ();
+
+  F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, tmp_data, n, 
+			     info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (a.is_hermitian () && b.is_hermitian () && info == 0)
+    return hermitian_init (a, calc_ev);
+
+  FloatComplexMatrix atmp = a;
+  FloatComplex *atmp_data = atmp.fortran_vec ();
+
+  FloatComplexMatrix btmp = b;
+  FloatComplex *btmp_data = btmp.fortran_vec ();
+
+  FloatComplexColumnVector alpha (n);
+  FloatComplex *palpha = alpha.fortran_vec ();
+
+  FloatComplexColumnVector beta (n);
+  FloatComplex *pbeta = beta.fortran_vec ();
+
+  octave_idx_type nvr = calc_ev ? n : 0;
+  FloatComplexMatrix vtmp (nvr, nvr);
+  FloatComplex *pv = vtmp.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  FloatComplex dummy_work;
+
+  octave_idx_type lrwork = 8*n;
+  Array<float> rwork (lrwork);
+  float *prwork = rwork.fortran_vec ();
+
+  FloatComplex *dummy = 0;
+  octave_idx_type idummy = 1;
+
+  F77_XFCN (cggev, CGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			   F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   n, atmp_data, n, btmp_data, n, 
+			   palpha, pbeta, dummy, idummy,
+			   pv, n, &dummy_work, lwork, prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<FloatComplex> work (lwork);
+      FloatComplex *pwork = work.fortran_vec ();
+
+      F77_XFCN (cggev, CGGEV, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       n, atmp_data, n, btmp_data, n, 
+			       palpha, pbeta, dummy, idummy,
+			       pv, n, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+      
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in cggev");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("cggev failed to converge");
+	  return info;
+	}
+
+      lambda.resize (n);
+
+      for (octave_idx_type j = 0; j < n; j++)
+        lambda.elem (j) = alpha.elem (j) / beta.elem(j);
+
+      v = vtmp;
+    }
+  else
+    (*current_liboctave_error_handler) ("cggev workspace query failed");
+
+  return info;
+}
+
+octave_idx_type
+FloatEIG::hermitian_init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, bool calc_ev)
+{
+  octave_idx_type n = a.rows ();
+  octave_idx_type nb = b.rows ();
+
+  if (n != a.cols () || nb != b.cols ())
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
+
+  if (n != nb)
+    {
+      (*current_liboctave_error_handler) ("EIG requires same size matrices");
+      return -1;
+    }
+
+  octave_idx_type info = 0;
+
+  FloatComplexMatrix atmp = a;
+  FloatComplex *atmp_data = atmp.fortran_vec ();
+
+  FloatComplexMatrix btmp = b;
+  FloatComplex *btmp_data = btmp.fortran_vec ();
+
+  FloatColumnVector wr (n);
+  float *pwr = wr.fortran_vec ();
+
+  octave_idx_type lwork = -1;
+  FloatComplex dummy_work;
+
+  octave_idx_type lrwork = 3*n;
+  Array<float> rwork (lrwork);
+  float *prwork = rwork.fortran_vec ();
+
+  F77_XFCN (chegv, CHEGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			   F77_CONST_CHAR_ARG2 ("U", 1),
+			   n, atmp_data, n, 
+			   btmp_data, n,
+			   pwr, &dummy_work, lwork,
+			   prwork, info
+			   F77_CHAR_ARG_LEN (1)
+			   F77_CHAR_ARG_LEN (1)));
+
+  if (info == 0)
+    {
+      lwork = static_cast<octave_idx_type> (dummy_work.real ());
+      Array<FloatComplex> work (lwork);
+      FloatComplex *pwork = work.fortran_vec ();
+
+      F77_XFCN (chegv, CHEGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1),
+			       F77_CONST_CHAR_ARG2 ("U", 1),
+			       n, atmp_data, n, 
+			       btmp_data, n, 
+			       pwr, pwork, lwork, prwork, info
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+
+      if (info < 0)
+	{
+	  (*current_liboctave_error_handler) ("unrecoverable error in zhegv");
+	  return info;
+	}
+
+      if (info > 0)
+	{
+	  (*current_liboctave_error_handler) ("zhegv failed to converge");
+	  return info;
+	}
+
+      lambda = FloatComplexColumnVector (wr);
+      v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix ();
+    }
+  else
+    (*current_liboctave_error_handler) ("zhegv workspace query failed");
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fEIG.h b/liboctave/fEIG.h
new file mode 100644
index 0000000..e00cc32
--- /dev/null
+++ b/liboctave/fEIG.h
@@ -0,0 +1,112 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_EIG_h)
+#define octave_float_EIG_h 1
+
+#include <iosfwd>
+
+#include "fMatrix.h"
+#include "fCMatrix.h"
+#include "fCColVector.h"
+
+class
+OCTAVE_API
+FloatEIG
+{
+friend class FloatMatrix;
+friend class FloatComplexMatrix;
+
+public:
+
+  FloatEIG (void)
+    : lambda (), v () { }
+
+  FloatEIG (const FloatMatrix& a, bool calc_eigenvectors = true)
+    { init (a, calc_eigenvectors); }
+
+  FloatEIG (const FloatMatrix& a, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, calc_eigenvectors); }
+
+  FloatEIG (const FloatMatrix& a, const FloatMatrix& b, bool calc_eigenvectors = true)
+    { init (a, b, calc_eigenvectors); }
+
+  FloatEIG (const FloatMatrix& a, const FloatMatrix& b, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, b, calc_eigenvectors); }
+
+  FloatEIG (const FloatComplexMatrix& a, bool calc_eigenvectors = true)
+    { init (a, calc_eigenvectors); }
+
+  FloatEIG (const FloatComplexMatrix& a, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, calc_eigenvectors); }
+
+  FloatEIG (const FloatComplexMatrix& a, const FloatComplexMatrix& b, bool calc_eigenvectors = true)
+    { init (a, b, calc_eigenvectors); }
+
+  FloatEIG (const FloatComplexMatrix& a, const FloatComplexMatrix& b, octave_idx_type& info, bool calc_eigenvectors = true)
+    { info = init (a, b, calc_eigenvectors); }
+
+  FloatEIG (const FloatEIG& a)
+    : lambda (a.lambda), v (a.v) { }
+
+  FloatEIG& operator = (const FloatEIG& a)
+    {
+      if (this != &a)
+	{
+	  lambda = a.lambda;
+	  v = a.v;
+	}
+      return *this;
+    }
+
+  ~FloatEIG (void) { }
+
+  FloatComplexColumnVector eigenvalues (void) const { return lambda; }
+
+  FloatComplexMatrix eigenvectors (void) const { return v; }
+
+  friend std::ostream&  operator << (std::ostream& os, const FloatEIG& a);
+
+private:
+
+  FloatComplexColumnVector lambda;
+  FloatComplexMatrix v;
+
+  octave_idx_type init (const FloatMatrix& a, bool calc_eigenvectors);
+  octave_idx_type init (const FloatMatrix& a, const FloatMatrix& b, bool calc_eigenvectors);
+  octave_idx_type init (const FloatComplexMatrix& a, bool calc_eigenvectors);
+  octave_idx_type init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, bool calc_eigenvectors);
+
+  octave_idx_type symmetric_init (const FloatMatrix& a, bool calc_eigenvectors);
+  octave_idx_type symmetric_init (const FloatMatrix& a, const FloatMatrix& b, bool calc_eigenvectors);
+  octave_idx_type hermitian_init (const FloatComplexMatrix& a, bool calc_eigenvectors);
+  octave_idx_type hermitian_init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, bool calc_eigenvectors);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fMatrix.cc b/liboctave/fMatrix.cc
new file mode 100644
index 0000000..b5141fe
--- /dev/null
+++ b/liboctave/fMatrix.cc
@@ -0,0 +1,3418 @@
+// Matrix manipulations.
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <iostream>
+#include <vector>
+
+#include "Array-util.h"
+#include "byte-swap.h"
+#include "fMatrix.h"
+#include "DET.h"
+#include "floatSCHUR.h"
+#include "floatSVD.h"
+#include "floatCHOL.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "mx-fm-fdm.h"
+#include "mx-fdm-fm.h"
+#include "mx-inlines.cc"
+#include "mx-op-defs.h"
+#include "oct-cmplx.h"
+#include "oct-norm.h"
+#include "quit.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#endif
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (xilaenv, XILAENV) (const octave_idx_type&, F77_CONST_CHAR_ARG_DECL,
+			       F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&,
+			       const octave_idx_type&, const octave_idx_type&,
+			       octave_idx_type&
+			       F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgebal, SGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgebak, SGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+
+  F77_RET_T
+  F77_FUNC (sgemm, SGEMM) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			   const float&, const float*, const octave_idx_type&,
+			   const float*, const octave_idx_type&, const float&,
+			   float*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgemv, SGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const float&,
+			   const float*, const octave_idx_type&, const float*,
+			   const octave_idx_type&, const float&, float*,
+			   const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xsdot, XSDOT) (const octave_idx_type&, const float*, const octave_idx_type&,
+			   const float*, const octave_idx_type&, float&);
+
+  F77_RET_T
+  F77_FUNC (ssyrk, SSYRK) (F77_CONST_CHAR_ARG_DECL,
+			   F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, 
+			   const float&, const float*, const octave_idx_type&,
+			   const float&, float*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL
+			   F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgetrf, SGETRF) (const octave_idx_type&, const octave_idx_type&, float*, const octave_idx_type&,
+		      octave_idx_type*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (sgetrs, SGETRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, const octave_idx_type&, 
+			     const float*, const octave_idx_type&,
+			     const octave_idx_type*, float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgetri, SGETRI) (const octave_idx_type&, float*, const octave_idx_type&, const octave_idx_type*,
+			     float*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (sgecon, SGECON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, float*, 
+			     const octave_idx_type&, const float&, float&, 
+			     float*, octave_idx_type*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgelsy, SGELSY) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     float*, const octave_idx_type&, float*,
+			     const octave_idx_type&, octave_idx_type*, float&, octave_idx_type&,
+			     float*, const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (sgelsd, SGELSD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     float*, const octave_idx_type&, float*,
+			     const octave_idx_type&, float*, float&, octave_idx_type&,
+			     float*, const octave_idx_type&, octave_idx_type*,
+			     octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (spotrf, SPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     float *, const octave_idx_type&, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (spocon, SPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     float*, const octave_idx_type&, const float&,
+			     float&, float*, octave_idx_type*,
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (spotrs, SPOTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const float*, 
+			     const octave_idx_type&, float*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (strtri, STRTRI) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     const octave_idx_type&, const float*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (strcon, STRCON) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const float*, const octave_idx_type&, float&,
+			     float*, octave_idx_type*, octave_idx_type& 
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (strtrs, STRTRS) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, 
+			     F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, 
+			     const octave_idx_type&, const float*, 
+			     const octave_idx_type&, float*, 
+			     const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  // Note that the original complex fft routines were not written for
+  // float complex arguments.  They have been modified by adding an
+  // implicit float precision (a-h,o-z) statement at the beginning of
+  // each subroutine.
+
+  F77_RET_T
+  F77_FUNC (cffti, CFFTI) (const octave_idx_type&, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftf, CFFTF) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftb, CFFTB) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (slartg, SLARTG) (const float&, const float&, float&,
+			     float&, float&);
+
+  F77_RET_T
+  F77_FUNC (strsyl, STRSYL) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     const float*, const octave_idx_type&, const float*,
+			     const octave_idx_type&, const float*, const octave_idx_type&,
+			     float&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xslange, XSLANGE) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			       const octave_idx_type&, const float*,
+			       const octave_idx_type&, float*, float&
+			       F77_CHAR_ARG_LEN_DECL); 
+}
+
+// Matrix class.
+
+FloatMatrix::FloatMatrix (const FloatRowVector& rv)
+  : MArray2<float> (Array2<float> (rv, 1, rv.length ()))
+{
+}
+
+FloatMatrix::FloatMatrix (const FloatColumnVector& cv)
+  : MArray2<float> (Array2<float> (cv, cv.length (), 1))
+{
+}
+
+FloatMatrix::FloatMatrix (const FloatDiagMatrix& a)
+  : MArray2<float> (a.rows (), a.cols (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatMatrix::FloatMatrix (const PermMatrix& a)
+  : MArray2<float> (a.rows (), a.cols (), 0.0)
+{
+  const Array<octave_idx_type> ia (a.pvec ());
+  octave_idx_type len = a.rows ();
+  if (a.is_col_perm ())
+    for (octave_idx_type i = 0; i < len; i++)
+      elem (ia(i), i) = 1.0;
+  else
+    for (octave_idx_type i = 0; i < len; i++)
+      elem (i, ia(i)) = 1.0;
+}
+
+// FIXME -- could we use a templated mixed-type copy function
+// here?
+
+FloatMatrix::FloatMatrix (const boolMatrix& a)
+  : MArray2<float> (a.rows (), a.cols ())
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = a.elem (i, j);
+}
+
+FloatMatrix::FloatMatrix (const charMatrix& a)
+  : MArray2<float> (a.rows (), a.cols ())
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    for (octave_idx_type j = 0; j < a.cols (); j++)
+      elem (i, j) = static_cast<unsigned char> (a.elem (i, j));
+}
+
+bool
+FloatMatrix::operator == (const FloatMatrix& a) const
+{
+  if (rows () != a.rows () || cols () != a.cols ())
+    return false;
+
+  return mx_inline_equal (data (), a.data (), length ());
+}
+
+bool
+FloatMatrix::operator != (const FloatMatrix& a) const
+{
+  return !(*this == a);
+}
+
+bool
+FloatMatrix::is_symmetric (void) const
+{
+  if (is_square () && rows () > 0)
+    {
+      for (octave_idx_type i = 0; i < rows (); i++)
+	for (octave_idx_type j = i+1; j < cols (); j++)
+	  if (elem (i, j) != elem (j, i))
+	    return false;
+
+      return true;
+    }
+
+  return false;
+}
+
+FloatMatrix&
+FloatMatrix::insert (const FloatMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  Array2<float>::insert (a, r, c);
+  return *this;
+}
+
+FloatMatrix&
+FloatMatrix::insert (const FloatRowVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r, c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatMatrix&
+FloatMatrix::insert (const FloatColumnVector& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatMatrix&
+FloatMatrix::insert (const FloatDiagMatrix& a, octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
+
+  octave_idx_type a_len = a.length ();
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (r+i, c+i) = a.elem (i, i);
+    }
+
+  return *this;
+}
+
+FloatMatrix&
+FloatMatrix::fill (float val)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+FloatMatrix&
+FloatMatrix::fill (float val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
+      || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (r2 >= r1 && c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type j = c1; j <= c2; j++)
+	for (octave_idx_type i = r1; i <= r2; i++)
+	  xelem (i, j) = val;
+    }
+
+  return *this;
+}
+
+FloatMatrix
+FloatMatrix::append (const FloatMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::append (const FloatRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != 1)
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatMatrix retval (nr, nc + a.length ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::append (const FloatColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.length ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatMatrix retval (nr, nc + 1);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::append (const FloatDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nr != a.rows ())
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
+
+  octave_idx_type nc_insert = nc;
+  FloatMatrix retval (nr, nc + a.cols ());
+  retval.insert (*this, 0, 0);
+  retval.insert (a, 0, nc_insert);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::stack (const FloatMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::stack (const FloatRowVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatMatrix retval (nr + 1, nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::stack (const FloatColumnVector& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != 1)
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatMatrix retval (nr + a.length (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::stack (const FloatDiagMatrix& a) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  if (nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return FloatMatrix ();
+    }
+
+  octave_idx_type nr_insert = nr;
+  FloatMatrix retval (nr + a.rows (), nc);
+  retval.insert (*this, 0, 0);
+  retval.insert (a, nr_insert, 0);
+  return retval;
+}
+
+FloatMatrix
+real (const FloatComplexMatrix& a)
+{
+  return FloatMatrix (mx_inline_real_dup (a.data (), a.length ()),
+                      a.rows (), a.cols ());
+}
+
+FloatMatrix
+imag (const FloatComplexMatrix& a)
+{
+  return FloatMatrix (mx_inline_imag_dup (a.data (), a.length ()),
+                      a.rows (), a.cols ());
+}
+
+FloatMatrix
+FloatMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
+{
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  FloatMatrix result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+FloatMatrix
+FloatMatrix::extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const
+{
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      result.xelem (i, j) = elem (r1+i, c1+j);
+
+  return result;
+}
+
+// extract row or column i.
+
+FloatRowVector
+FloatMatrix::row (octave_idx_type i) const
+{
+  return MArray<float> (index (idx_vector (i), idx_vector::colon));
+}
+
+FloatColumnVector
+FloatMatrix::column (octave_idx_type i) const
+{
+  return MArray<float> (index (idx_vector::colon, idx_vector (i)));
+}
+
+FloatMatrix
+FloatMatrix::inverse (void) const
+{
+  octave_idx_type info;
+  float rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatMatrix
+FloatMatrix::inverse (octave_idx_type& info) const
+{
+  float rcon;
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatMatrix
+FloatMatrix::inverse (octave_idx_type& info, float& rcon, int force,
+		 int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return inverse (mattype, info, rcon, force, calc_cond);
+}
+
+FloatMatrix
+FloatMatrix::inverse (MatrixType& mattype) const
+{
+  octave_idx_type info;
+  float rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatMatrix
+FloatMatrix::inverse (MatrixType &mattype, octave_idx_type& info) const
+{
+  float rcon;
+  return inverse (mattype, info, rcon, 0, 0);
+}
+
+FloatMatrix
+FloatMatrix::tinverse (MatrixType &mattype, octave_idx_type& info, float& rcon, 
+		  int force, int calc_cond) const
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr == 0 || nc == 0)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      int typ = mattype.type ();
+      char uplo = (typ == MatrixType::Lower ? 'L' : 'U');
+      char udiag = 'N';
+      retval = *this;
+      float *tmp_data = retval.fortran_vec ();
+
+      F77_XFCN (strtri, STRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+				 F77_CONST_CHAR_ARG2 (&udiag, 1),
+				 nr, tmp_data, nr, info 
+				 F77_CHAR_ARG_LEN (1)
+				 F77_CHAR_ARG_LEN (1)));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  octave_idx_type dtrcon_info = 0;
+	  char job = '1';
+
+	  OCTAVE_LOCAL_BUFFER (float, work, 3 * nr);
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, nr);
+
+	  F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     F77_CONST_CHAR_ARG2 (&uplo, 1),
+				     F77_CONST_CHAR_ARG2 (&udiag, 1),
+				     nr, tmp_data, nr, rcon, 
+				     work, iwork, dtrcon_info 
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (dtrcon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this; // Restore matrix contents.
+    }
+
+  return retval;
+}
+
+
+FloatMatrix
+FloatMatrix::finverse (MatrixType &mattype, octave_idx_type& info, float& rcon, 
+		  int force, int calc_cond) const
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr == 0 || nc == 0)
+    (*current_liboctave_error_handler) ("inverse requires square matrix");
+  else
+    {
+      Array<octave_idx_type> ipvt (nr);
+      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+      retval = *this;
+      float *tmp_data = retval.fortran_vec ();
+
+      Array<float> z(1);
+      octave_idx_type lwork = -1;
+
+      // Query the optimum work array size.
+      F77_XFCN (sgetri, SGETRI, (nc, tmp_data, nr, pipvt, 
+				 z.fortran_vec (), lwork, info));
+
+      lwork = static_cast<octave_idx_type> (z(0));
+      lwork = (lwork < 2 *nc ? 2*nc : lwork);
+      z.resize (lwork);
+      float *pz = z.fortran_vec ();
+
+      info = 0;
+
+      // Calculate the norm of the matrix, for later use.
+      float anorm = 0;
+      if (calc_cond) 
+	anorm = retval.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+      F77_XFCN (sgetrf, SGETRF, (nc, nc, tmp_data, nr, pipvt, info));
+
+      // Throw-away extra info LAPACK gives so as to not change output.
+      rcon = 0.0;
+      if (info != 0) 
+	info = -1;
+      else if (calc_cond) 
+	{
+	  octave_idx_type dgecon_info = 0;
+
+	  // Now calculate the condition number for non-singular matrix.
+	  char job = '1';
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+	  F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+				     nc, tmp_data, nr, anorm, 
+				     rcon, pz, piz, dgecon_info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (dgecon_info != 0) 
+	    info = -1;
+	}
+
+      if (info == -1 && ! force)
+	retval = *this; // Restore matrix contents.
+      else
+	{
+	  octave_idx_type dgetri_info = 0;
+
+	  F77_XFCN (sgetri, SGETRI, (nc, tmp_data, nr, pipvt,
+				     pz, lwork, dgetri_info));
+
+	  if (dgetri_info != 0) 
+	    info = -1;
+	}
+
+      if (info != 0)
+	mattype.mark_as_rectangular();
+    }
+
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::inverse (MatrixType &mattype, octave_idx_type& info, float& rcon, 
+		 int force, int calc_cond) const
+{
+  int typ = mattype.type (false);
+  FloatMatrix ret;
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  if (typ == MatrixType::Upper || typ == MatrixType::Lower)
+    ret = tinverse (mattype, info, rcon, force, calc_cond);
+  else
+    {
+      if (mattype.is_hermitian ())
+	{
+	  FloatCHOL chol (*this, info, calc_cond);
+	  if (info == 0)
+	    {
+	      if (calc_cond)
+		rcon = chol.rcond ();
+	      else
+		rcon = 1.0;
+	      ret = chol.inverse ();
+	    }
+	  else
+	    mattype.mark_as_unsymmetric ();
+	}
+
+      if (!mattype.is_hermitian ())
+	ret = finverse(mattype, info, rcon, force, calc_cond);
+
+      if ((mattype.is_hermitian () || calc_cond) && rcon == 0.)
+	ret = FloatMatrix (rows (), columns (), octave_Float_Inf);
+    }
+
+  return ret;
+}
+
+FloatMatrix
+FloatMatrix::pseudo_inverse (float tol) const
+{
+  FloatSVD result (*this, SVD::economy);
+
+  FloatDiagMatrix S = result.singular_values ();
+  FloatMatrix U = result.left_singular_matrix ();
+  FloatMatrix V = result.right_singular_matrix ();
+
+  FloatColumnVector sigma = S.diag ();
+
+  octave_idx_type r = sigma.length () - 1;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (tol <= 0.0)
+    {
+      if (nr > nc)
+	tol = nr * sigma.elem (0) * DBL_EPSILON;
+      else
+	tol = nc * sigma.elem (0) * DBL_EPSILON;
+    }
+
+  while (r >= 0 && sigma.elem (r) < tol)
+    r--;
+
+  if (r < 0)
+    return FloatMatrix (nc, nr, 0.0);
+  else
+    {
+      FloatMatrix Ur = U.extract (0, 0, nr-1, r);
+      FloatDiagMatrix D = FloatDiagMatrix (sigma.extract (0, r)) . inverse ();
+      FloatMatrix Vr = V.extract (0, 0, nc-1, r);
+      return Vr * D * Ur.transpose ();
+    }
+}
+
+#if defined (HAVE_FFTW3)
+
+FloatComplexMatrix
+FloatMatrix::fourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  const float *in (fortran_vec ());
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::fft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::ifourier (void) const
+{
+  size_t nr = rows ();
+  size_t nc = cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  size_t npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  FloatComplexMatrix tmp (*this);
+  FloatComplex *in (tmp.fortran_vec ());
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::ifft (in, out, npts, nsamples); 
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::fourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  const float *in = fortran_vec ();
+  FloatComplexMatrix retval (rows (), cols ());
+  octave_fftw::fftNd (in, retval.fortran_vec (), 2, dv);
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::ifourier2d (void) const
+{
+  dim_vector dv(rows (), cols ());
+
+  FloatComplexMatrix retval (*this);
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (out, out, 2, dv);
+
+  return retval;
+}
+
+#else
+
+FloatComplexMatrix
+FloatMatrix::fourier (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = FloatComplexMatrix (*this);
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::ifourier (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = FloatComplexMatrix (*this);
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<float> (npts);
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::fourier2d (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = FloatComplexMatrix (*this);
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<FloatComplex> tmp (npts);
+  FloatComplex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i];
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::ifourier2d (void) const
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type npts, nsamples;
+
+  if (nr == 1 || nc == 1)
+    {
+      npts = nr > nc ? nr : nc;
+      nsamples = 1;
+    }
+  else
+    {
+      npts = nr;
+      nsamples = nc;
+    }
+
+  octave_idx_type nn = 4*npts+15;
+
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  retval = FloatComplexMatrix (*this);
+  FloatComplex *tmp_data = retval.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      F77_FUNC (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave);
+    }
+
+  for (octave_idx_type j = 0; j < npts*nsamples; j++)
+    tmp_data[j] = tmp_data[j] / static_cast<float> (npts);
+
+  npts = nc;
+  nsamples = nr;
+  nn = 4*npts+15;
+
+  wsave.resize (nn);
+  pwsave = wsave.fortran_vec ();
+
+  Array<FloatComplex> tmp (npts);
+  FloatComplex *prow = tmp.fortran_vec ();
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type j = 0; j < nsamples; j++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	prow[i] = tmp_data[i*nr + j];
+
+      F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
+
+      for (octave_idx_type i = 0; i < npts; i++)
+	tmp_data[i*nr + j] = prow[i] / static_cast<float> (npts);
+    }
+
+  return retval;
+}
+
+#endif
+
+FloatDET
+FloatMatrix::determinant (void) const
+{
+  octave_idx_type info;
+  float rcon;
+  return determinant (info, rcon, 0);
+}
+
+FloatDET
+FloatMatrix::determinant (octave_idx_type& info) const
+{
+  float rcon;
+  return determinant (info, rcon, 0);
+}
+
+FloatDET
+FloatMatrix::determinant (octave_idx_type& info, float& rcon, int calc_cond) const
+{
+  MatrixType mattype (*this);
+  return determinant (mattype, info, rcon, calc_cond);
+}
+
+FloatDET
+FloatMatrix::determinant (MatrixType& mattype,
+                          octave_idx_type& info, float& rcon, int calc_cond) const
+{
+  FloatDET retval (1.0);
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+        typ = mattype.type (*this);
+
+      if (typ == MatrixType::Lower || typ == MatrixType::Upper)
+        {
+          for (octave_idx_type i = 0; i < nc; i++) 
+            retval *= elem (i,i);
+        }
+      else if (typ == MatrixType::Hermitian)
+        {
+          FloatMatrix atmp = *this;
+          float *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+          float anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+
+          char job = 'L';
+          F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+                                     tmp_data, nr, info
+                                     F77_CHAR_ARG_LEN (1)));
+
+          if (info != 0) 
+            {
+              rcon = 0.0;
+              mattype.mark_as_unsymmetric ();
+              typ = MatrixType::Full;
+            }
+          else 
+            {
+              Array<float> z (3 * nc);
+              float *pz = z.fortran_vec ();
+              Array<octave_idx_type> iz (nc);
+              octave_idx_type *piz = iz.fortran_vec ();
+
+              F77_XFCN (spocon, SPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                         nr, tmp_data, nr, anorm,
+                                         rcon, pz, piz, info
+                                         F77_CHAR_ARG_LEN (1)));
+
+              if (info != 0) 
+                rcon = 0.0;
+
+              for (octave_idx_type i = 0; i < nc; i++) 
+                retval *= atmp (i,i);
+
+              retval = retval.square ();
+            }
+        }
+      else if (typ != MatrixType::Full)
+        (*current_liboctave_error_handler) ("det: invalid dense matrix type");
+
+      if (typ == MatrixType::Full)
+        {
+          Array<octave_idx_type> ipvt (nr);
+          octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+          FloatMatrix atmp = *this;
+          float *tmp_data = atmp.fortran_vec ();
+
+          info = 0;
+
+          // Calculate the norm of the matrix, for later use.
+          float anorm = 0;
+          if (calc_cond) anorm = xnorm (*this, 1);
+
+          F77_XFCN (sgetrf, SGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+          // Throw-away extra info LAPACK gives so as to not change output.
+          rcon = 0.0;
+          if (info != 0) 
+            {
+              info = -1;
+              retval = FloatDET ();
+            } 
+          else 
+            {
+              if (calc_cond) 
+                {
+                  // Now calc the condition number for non-singular matrix.
+                  char job = '1';
+                  Array<float> z (4 * nc);
+                  float *pz = z.fortran_vec ();
+                  Array<octave_idx_type> iz (nc);
+                  octave_idx_type *piz = iz.fortran_vec ();
+
+                  F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+                                             nc, tmp_data, nr, anorm, 
+                                             rcon, pz, piz, info
+                                             F77_CHAR_ARG_LEN (1)));
+                }
+
+              if (info != 0) 
+                {
+                  info = -1;
+                  retval = FloatDET ();
+                } 
+              else 
+                {
+                  for (octave_idx_type i = 0; i < nc; i++) 
+                    {
+                      float c = atmp(i,i);
+                      retval *= (ipvt(i) != (i+1)) ? -c : c;
+                    }
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+float
+FloatMatrix::rcond (void) const
+{
+  MatrixType mattype (*this);
+  return rcond (mattype);
+}
+
+float
+FloatMatrix::rcond (MatrixType &mattype) const
+{
+  float rcon;
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc)
+    (*current_liboctave_error_handler) ("matrix must be square");
+  else if (nr == 0 || nc == 0)
+    rcon = octave_Inf;
+  else
+    {
+      int typ = mattype.type ();
+
+      if (typ == MatrixType::Unknown)
+	typ = mattype.type (*this);
+
+      // Only calculate the condition number for LU/Cholesky
+      if (typ == MatrixType::Upper)
+	{
+	  const float *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'U';
+	  char dia = 'N';
+
+	  Array<float> z (3 * nc);
+	  float *pz = z.fortran_vec ();
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+
+	  F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, piz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0.0;
+	}
+      else if  (typ == MatrixType::Permuted_Upper)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Lower)
+	{
+	  const float *tmp_data = fortran_vec ();
+	  octave_idx_type info = 0;
+	  char norm = '1';
+	  char uplo = 'L';
+	  char dia = 'N';
+
+	  Array<float> z (3 * nc);
+	  float *pz = z.fortran_vec ();
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+
+	  F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+				     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+				     F77_CONST_CHAR_ARG2 (&dia, 1), 
+				     nr, tmp_data, nr, rcon,
+				     pz, piz, info
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)
+				     F77_CHAR_ARG_LEN (1)));
+
+	  if (info != 0) 
+	    rcon = 0.0;
+	}
+      else if (typ == MatrixType::Permuted_Lower)
+	(*current_liboctave_error_handler)
+	  ("permuted triangular matrix not implemented");
+      else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+	{
+	  float anorm = -1.0;
+	  FloatMatrix atmp = *this;
+	  float *tmp_data = atmp.fortran_vec ();
+
+	  if (typ == MatrixType::Hermitian)
+	    {
+	      octave_idx_type info = 0;
+	      char job = 'L';
+	      anorm = atmp.abs().sum().
+		row(static_cast<octave_idx_type>(0)).max();
+
+	      F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+					 tmp_data, nr, info
+					 F77_CHAR_ARG_LEN (1)));
+
+	      if (info != 0) 
+		{
+		  rcon = 0.0;
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}
+	      else 
+		{
+		  Array<float> z (3 * nc);
+		  float *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (spocon, SPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+
+	  if (typ == MatrixType::Full)
+	    {
+	      octave_idx_type info = 0;
+
+	      Array<octave_idx_type> ipvt (nr);
+	      octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	      if(anorm < 0.)
+		anorm = atmp.abs().sum().
+		  row(static_cast<octave_idx_type>(0)).max();
+
+	      Array<float> z (4 * nc);
+	      float *pz = z.fortran_vec ();
+	      Array<octave_idx_type> iz (nc);
+	      octave_idx_type *piz = iz.fortran_vec ();
+
+	      F77_XFCN (sgetrf, SGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	      if (info != 0) 
+		{
+		  rcon = 0.0;
+		  mattype.mark_as_rectangular ();
+		}
+	      else 
+		{
+		  char job = '1';
+		  F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    rcon = 0.0;
+		}
+	    }
+	}
+      else
+	rcon = 0.0;
+    }
+
+  return rcon;
+}
+
+FloatMatrix
+FloatMatrix::utsolve (MatrixType &mattype, const FloatMatrix& b, octave_idx_type& info,
+		float& rcon, solve_singularity_handler sing_handler,
+		bool calc_cond) const
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = FloatMatrix (nc, b.cols (), 0.0);
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Upper ||
+	  typ == MatrixType::Upper)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Upper)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const float *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'U';
+		  char dia = 'N';
+
+		  Array<float> z (3 * nc);
+		  float *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, piz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  float *result = retval.fortran_vec ();
+
+		  char uplo = 'U';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (strtrs, STRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::ltsolve (MatrixType &mattype, const FloatMatrix& b, octave_idx_type& info,
+		float& rcon, solve_singularity_handler sing_handler,
+		bool calc_cond) const
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || nc == 0 || b.cols () == 0)
+    retval = FloatMatrix (nc, b.cols (), 0.0);
+  else
+    {
+      volatile int typ = mattype.type ();
+
+      if (typ == MatrixType::Permuted_Lower ||
+	  typ == MatrixType::Lower)
+	{
+	  octave_idx_type b_nc = b.cols ();
+	  rcon = 1.;
+	  info = 0;
+
+	  if (typ == MatrixType::Permuted_Lower)
+	    {
+	      (*current_liboctave_error_handler)
+		("permuted triangular matrix not implemented");
+	    }
+	  else
+	    {
+	      const float *tmp_data = fortran_vec ();
+
+	      if (calc_cond)
+		{
+		  char norm = '1';
+		  char uplo = 'L';
+		  char dia = 'N';
+
+		  Array<float> z (3 * nc);
+		  float *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), 
+					     F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, tmp_data, nr, rcon,
+					     pz, piz, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  float *result = retval.fortran_vec ();
+
+		  char uplo = 'L';
+		  char trans = 'N';
+		  char dia = 'N';
+
+		  F77_XFCN (strtrs, STRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), 
+					     F77_CONST_CHAR_ARG2 (&trans, 1), 
+					     F77_CONST_CHAR_ARG2 (&dia, 1), 
+					     nr, b_nc, tmp_data, nr,
+					     result, nr, info
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	    }
+	}
+      else
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::fsolve (MatrixType &mattype, const FloatMatrix& b, octave_idx_type& info,
+		float& rcon, solve_singularity_handler sing_handler,
+		bool calc_cond) const
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr != nc || nr != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (nr == 0 || b.cols () == 0)
+    retval = FloatMatrix (nc, b.cols (), 0.0);
+  else
+    {
+      volatile int typ = mattype.type ();
+ 
+     // Calculate the norm of the matrix, for later use.
+      float anorm = -1.;
+
+      if (typ == MatrixType::Hermitian)
+	{
+	  info = 0;
+	  char job = 'L';
+	  FloatMatrix atmp = *this;
+	  float *tmp_data = atmp.fortran_vec ();
+	  anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 
+				     tmp_data, nr, info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    {
+	      info = -2;
+
+	      mattype.mark_as_unsymmetric ();
+	      typ = MatrixType::Full;
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  Array<float> z (3 * nc);
+		  float *pz = z.fortran_vec ();
+		  Array<octave_idx_type> iz (nc);
+		  octave_idx_type *piz = iz.fortran_vec ();
+
+		  F77_XFCN (spocon, SPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, tmp_data, nr, anorm,
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  float *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  F77_XFCN (spotrs, SPOTRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	      else
+		{
+		  mattype.mark_as_unsymmetric ();
+		  typ = MatrixType::Full;
+		}		    
+	    }
+	}
+
+      if (typ == MatrixType::Full)
+	{
+	  info = 0;
+
+	  Array<octave_idx_type> ipvt (nr);
+	  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+	  FloatMatrix atmp = *this;
+	  float *tmp_data = atmp.fortran_vec ();
+	  if(anorm < 0.)
+	    anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+	  Array<float> z (4 * nc);
+	  float *pz = z.fortran_vec ();
+	  Array<octave_idx_type> iz (nc);
+	  octave_idx_type *piz = iz.fortran_vec ();
+
+	  F77_XFCN (sgetrf, SGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+
+	  // Throw-away extra info LAPACK gives so as to not change output.
+	  rcon = 0.0;
+	  if (info != 0) 
+	    {
+	      info = -2;
+
+	      if (sing_handler)
+		sing_handler (rcon);
+	      else
+		(*current_liboctave_error_handler)
+		  ("matrix singular to machine precision");
+
+	      mattype.mark_as_rectangular ();
+	    }
+	  else 
+	    {
+	      if (calc_cond)
+		{
+		  // Now calculate the condition number for 
+		  // non-singular matrix.
+		  char job = '1';
+		  F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nc, tmp_data, nr, anorm, 
+					     rcon, pz, piz, info
+					     F77_CHAR_ARG_LEN (1)));
+
+		  if (info != 0) 
+		    info = -2;
+
+		  volatile float rcond_plus_one = rcon + 1.0;
+
+		  if (rcond_plus_one == 1.0 || xisnan (rcon))
+		    {
+		      info = -2;
+
+		      if (sing_handler)
+			sing_handler (rcon);
+		      else
+			(*current_liboctave_error_handler)
+			  ("matrix singular to machine precision, rcond = %g",
+			   rcon);
+		    }
+		}
+
+	      if (info == 0)
+		{
+		  retval = b;
+		  float *result = retval.fortran_vec ();
+
+		  octave_idx_type b_nc = b.cols ();
+
+		  char job = 'N';
+		  F77_XFCN (sgetrs, SGETRS, (F77_CONST_CHAR_ARG2 (&job, 1),
+					     nr, b_nc, tmp_data, nr,
+					     pipvt, result, b.rows(), info
+					     F77_CHAR_ARG_LEN (1)));
+		}
+	      else
+		mattype.mark_as_rectangular ();
+	    }
+	}
+      else if (typ != MatrixType::Hermitian)
+	(*current_liboctave_error_handler) ("incorrect matrix type");
+    }
+
+  return retval;
+}
+
+FloatMatrix
+FloatMatrix::solve (MatrixType &typ, const FloatMatrix& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatMatrix
+FloatMatrix::solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info, 
+	       float& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatMatrix
+FloatMatrix::solve (MatrixType &mattype, const FloatMatrix& b, octave_idx_type& info,
+	       float& rcon, solve_singularity_handler sing_handler,
+	       bool singular_fallback) const
+{
+  FloatMatrix retval;
+  int typ = mattype.type ();
+
+  if (typ == MatrixType::Unknown)
+    typ = mattype.type (*this);
+
+  // Only calculate the condition number for LU/Cholesky
+  if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
+    retval = utsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, false);
+  else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
+    retval = fsolve (mattype, b, info, rcon, sing_handler, true);
+  else if (typ != MatrixType::Rectangular)
+    {
+      (*current_liboctave_error_handler) ("unknown matrix type");
+      return FloatMatrix ();
+    }
+
+  // Rectangular or one of the above solvers flags a singular matrix
+  if (singular_fallback && mattype.type () == MatrixType::Rectangular)
+    {
+      octave_idx_type rank;
+      retval = lssolve (b, info, rank, rcon);
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b, 
+  octave_idx_type& info) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b, octave_idx_type& info,
+	       float& rcon) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info, rcon);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (MatrixType &typ, const FloatComplexMatrix& b, octave_idx_type& info,
+	       float& rcon, solve_singularity_handler sing_handler,
+	       bool singular_fallback) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info, rcon, sing_handler, singular_fallback);
+}
+
+FloatColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatColumnVector& b) const
+{
+  octave_idx_type info; float rcon;
+  return solve (typ, b, info, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatColumnVector& b, 
+	       octave_idx_type& info) const
+{
+  float rcon;
+  return solve (typ, b, info, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatColumnVector& b, octave_idx_type& info,
+	       float& rcon) const
+{
+  return solve (typ, b, info, rcon, 0);
+}
+
+FloatColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatColumnVector& b, octave_idx_type& info,
+	       float& rcon, solve_singularity_handler sing_handler) const
+{
+  FloatMatrix tmp (b);
+  return solve (typ, tmp, info, rcon, sing_handler).column(static_cast<octave_idx_type> (0));
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+	       octave_idx_type& info) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+	       octave_idx_type& info, float& rcon) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (typ, b, info, rcon);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+	       octave_idx_type& info, float& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve(typ, b, info, rcon, sing_handler);
+}
+
+FloatMatrix
+FloatMatrix::solve (const FloatMatrix& b) const
+{
+  octave_idx_type info;
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatMatrix
+FloatMatrix::solve (const FloatMatrix& b, octave_idx_type& info) const
+{
+  float rcon;
+  return solve (b, info, rcon, 0);
+}
+
+FloatMatrix
+FloatMatrix::solve (const FloatMatrix& b, octave_idx_type& info, float& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+FloatMatrix
+FloatMatrix::solve (const FloatMatrix& b, octave_idx_type& info,
+	       float& rcon, solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (const FloatComplexMatrix& b) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (const FloatComplexMatrix& b, octave_idx_type& info) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b, info);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon);
+}
+
+FloatComplexMatrix
+FloatMatrix::solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon, sing_handler);
+}
+
+FloatColumnVector
+FloatMatrix::solve (const FloatColumnVector& b) const
+{
+  octave_idx_type info; float rcon;
+  return solve (b, info, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::solve (const FloatColumnVector& b, octave_idx_type& info) const
+{
+  float rcon;
+  return solve (b, info, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::solve (const FloatColumnVector& b, octave_idx_type& info, float& rcon) const
+{
+  return solve (b, info, rcon, 0);
+}
+
+FloatColumnVector
+FloatMatrix::solve (const FloatColumnVector& b, octave_idx_type& info, float& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  MatrixType mattype (*this);
+  return solve (mattype, b, info, rcon, sing_handler);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (const FloatComplexColumnVector& b) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (const FloatComplexColumnVector& b, octave_idx_type& info) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b, info);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (const FloatComplexColumnVector& b, octave_idx_type& info, float& rcon) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon);
+}
+
+FloatComplexColumnVector
+FloatMatrix::solve (const FloatComplexColumnVector& b, octave_idx_type& info, float& rcon,
+	       solve_singularity_handler sing_handler) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.solve (b, info, rcon, sing_handler);
+}
+
+FloatMatrix
+FloatMatrix::lssolve (const FloatMatrix& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatMatrix
+FloatMatrix::lssolve (const FloatMatrix& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatMatrix
+FloatMatrix::lssolve (const FloatMatrix& b, octave_idx_type& info,
+		 octave_idx_type& rank) const
+{
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatMatrix
+FloatMatrix::lssolve (const FloatMatrix& b, octave_idx_type& info,
+		 octave_idx_type& rank, float &rcon) const
+{
+  FloatMatrix retval;
+
+  octave_idx_type nrhs = b.cols ();
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.rows ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m == 0 || n == 0 || b.cols () == 0)
+    retval = FloatMatrix (n, b.cols (), 0.0);
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+      if (m != n)
+	{
+	  retval = FloatMatrix (maxmn, nrhs, 0.0);
+
+	  for (octave_idx_type j = 0; j < nrhs; j++)
+	    for (octave_idx_type i = 0; i < m; i++)
+	      retval.elem (i, j) = b.elem (i, j);
+	}
+      else
+	retval = b;
+
+      FloatMatrix atmp = *this;
+      float *tmp_data = atmp.fortran_vec ();
+
+      float *pretval = retval.fortran_vec ();
+      Array<float> s (minmn);
+      float *ps = s.fortran_vec ();
+
+      // Ask DGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<float> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("SGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      octave_idx_type mnthr;
+      F77_FUNC (xilaenv, XILAENV) (6, F77_CONST_CHAR_ARG2 ("SGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   m, n, nrhs, -1, mnthr
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of iwork because DGELSD in older versions
+      // of LAPACK does not return it on a query call.
+      float dminmn = static_cast<float> (minmn);
+      float dsmlsizp1 = static_cast<float> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      float tmp = log2 (dminmn / dsmlsizp1);
+#else
+      float tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (sgelsd, SGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, piwork, info));
+
+      // The workspace query is broken in at least LAPACK 3.0.0
+      // through 3.1.1 when n >= mnthr.  The obtuse formula below
+      // should provide sufficient workspace for DGELSD to operate
+      // efficiently.
+      if (n >= mnthr)
+	{
+	  const octave_idx_type wlalsd
+	    = 9*m + 2*m*smlsiz + 8*m*nlvl + m*nrhs + (smlsiz+1)*(smlsiz+1);
+
+	  octave_idx_type addend = m;
+
+	  if (2*m-4 > addend)
+	    addend = 2*m-4;
+
+	  if (nrhs > addend)
+	    addend = nrhs;
+
+	  if (n-3*m > addend)
+	    addend = n-3*m;
+
+	  if (wlalsd > addend)
+	    addend = wlalsd;
+
+	  const octave_idx_type lworkaround = 4*m + m*m + addend;
+
+	  if (work(0) < lworkaround)
+	    work(0) = lworkaround;
+	}
+      else if (m >= n)
+	{
+	  octave_idx_type lworkaround
+	    = 12*n + 2*n*smlsiz + 8*n*nlvl + n*nrhs + (smlsiz+1)*(smlsiz+1);
+
+	  if (work(0) < lworkaround)
+	    work(0) = lworkaround;
+	}
+
+      lwork = static_cast<octave_idx_type> (work(0));
+      work.resize (lwork);
+
+      F77_XFCN (sgelsd, SGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 piwork, info));
+
+      if (rank < minmn)
+	(*current_liboctave_warning_handler) 
+	  ("dgelsd: rank deficient %dx%d matrix, rank = %d", m, n, rank);
+      if (s.elem (0) == 0.0)
+	rcon = 0.0;
+      else
+	rcon = s.elem (minmn - 1) / s.elem (0);
+
+      retval.resize (n, nrhs);
+    }
+
+  return retval;
+}
+
+FloatComplexMatrix
+FloatMatrix::lssolve (const FloatComplexMatrix& b) const
+{
+  FloatComplexMatrix tmp (*this);
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatMatrix::lssolve (const FloatComplexMatrix& b, octave_idx_type& info) const
+{
+  FloatComplexMatrix tmp (*this);
+  octave_idx_type rank;
+  float rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatMatrix::lssolve (const FloatComplexMatrix& b, octave_idx_type& info, 
+		 octave_idx_type& rank) const
+{
+  FloatComplexMatrix tmp (*this);
+  float rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatComplexMatrix
+FloatMatrix::lssolve (const FloatComplexMatrix& b, octave_idx_type& info, 
+		 octave_idx_type& rank, float& rcon) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::lssolve (const FloatColumnVector& b) const
+{
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::lssolve (const FloatColumnVector& b, octave_idx_type& info) const
+{
+  octave_idx_type rank;
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::lssolve (const FloatColumnVector& b, octave_idx_type& info,
+		 octave_idx_type& rank) const
+{
+  float rcon;
+  return lssolve (b, info, rank, rcon);
+}
+
+FloatColumnVector
+FloatMatrix::lssolve (const FloatColumnVector& b, octave_idx_type& info,
+		 octave_idx_type& rank, float &rcon) const
+{
+  FloatColumnVector retval;
+
+  octave_idx_type nrhs = 1;
+
+  octave_idx_type m = rows ();
+  octave_idx_type n = cols ();
+
+  if (m != b.length ())
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch solution of linear equations");
+  else if (m == 0 || n == 0)
+    retval = FloatColumnVector (n, 0.0);
+  else
+    {
+      volatile octave_idx_type minmn = (m < n ? m : n);
+      octave_idx_type maxmn = m > n ? m : n;
+      rcon = -1.0;
+ 
+      if (m != n)
+	{
+	  retval = FloatColumnVector (maxmn, 0.0);
+
+	  for (octave_idx_type i = 0; i < m; i++)
+	    retval.elem (i) = b.elem (i);
+	}
+      else
+	retval = b;
+
+      FloatMatrix atmp = *this;
+      float *tmp_data = atmp.fortran_vec ();
+
+      float *pretval = retval.fortran_vec ();
+      Array<float> s (minmn);
+      float *ps = s.fortran_vec ();
+
+      // Ask DGELSD what the dimension of WORK should be.
+      octave_idx_type lwork = -1;
+
+      Array<float> work (1);
+
+      octave_idx_type smlsiz;
+      F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("SGELSD", 6),
+				   F77_CONST_CHAR_ARG2 (" ", 1),
+				   0, 0, 0, 0, smlsiz
+				   F77_CHAR_ARG_LEN (6)
+				   F77_CHAR_ARG_LEN (1));
+
+      // We compute the size of iwork because DGELSD in older versions
+      // of LAPACK does not return it on a query call.
+      float dminmn = static_cast<float> (minmn);
+      float dsmlsizp1 = static_cast<float> (smlsiz+1);
+#if defined (HAVE_LOG2)
+      float tmp = log2 (dminmn / dsmlsizp1);
+#else
+      float tmp = log (dminmn / dsmlsizp1) / log (2.0);
+#endif
+      octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1;
+      if (nlvl < 0)
+	nlvl = 0;
+
+      octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn;
+      if (liwork < 1)
+	liwork = 1;
+      Array<octave_idx_type> iwork (liwork);
+      octave_idx_type* piwork = iwork.fortran_vec ();
+
+      F77_XFCN (sgelsd, SGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn,
+				 ps, rcon, rank, work.fortran_vec (),
+				 lwork, piwork, info));
+
+      lwork = static_cast<octave_idx_type> (work(0));
+      work.resize (lwork);
+
+      F77_XFCN (sgelsd, SGELSD, (m, n, nrhs, tmp_data, m, pretval,
+				 maxmn, ps, rcon, rank,
+				 work.fortran_vec (), lwork, 
+				 piwork, info));
+
+      if (rank < minmn)
+	{
+	  if (rank < minmn)
+	    (*current_liboctave_warning_handler) 
+	      ("dgelsd: rank deficient %dx%d matrix, rank = %d", m, n, rank);
+	  if (s.elem (0) == 0.0)
+	    rcon = 0.0;
+	  else
+	    rcon = s.elem (minmn - 1) / s.elem (0);
+	}
+
+      retval.resize (n, nrhs);
+    }
+
+  return retval;
+}
+
+FloatComplexColumnVector
+FloatMatrix::lssolve (const FloatComplexColumnVector& b) const
+{
+  FloatComplexMatrix tmp (*this);
+  octave_idx_type info;
+  octave_idx_type rank;
+  float rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatMatrix::lssolve (const FloatComplexColumnVector& b, octave_idx_type& info) const
+{
+  FloatComplexMatrix tmp (*this);
+  octave_idx_type rank;
+  float rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatMatrix::lssolve (const FloatComplexColumnVector& b, octave_idx_type& info, 
+		 octave_idx_type& rank) const
+{
+  FloatComplexMatrix tmp (*this);
+  float rcon;
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatComplexColumnVector
+FloatMatrix::lssolve (const FloatComplexColumnVector& b, octave_idx_type& info, 
+		 octave_idx_type& rank, float &rcon) const
+{
+  FloatComplexMatrix tmp (*this);
+  return tmp.lssolve (b, info, rank, rcon);
+}
+
+FloatMatrix&
+FloatMatrix::operator += (const FloatDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+FloatMatrix&
+FloatMatrix::operator -= (const FloatDiagMatrix& a)
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr != a_nr || nc != a_nc)
+    {
+      gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc);
+      return *this;
+    }
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+// unary operations
+
+boolMatrix
+FloatMatrix::operator ! (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  boolMatrix b (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      b.elem (i, j) = ! elem (i, j);
+
+  return b;
+}
+
+// column vector by row vector -> matrix operations
+
+FloatMatrix
+operator * (const FloatColumnVector& v, const FloatRowVector& a)
+{
+  FloatMatrix retval;
+
+  octave_idx_type len = v.length ();
+
+  if (len != 0)
+    {
+      octave_idx_type a_len = a.length ();
+
+      retval = FloatMatrix (len, a_len);
+      float *c = retval.fortran_vec ();
+	  
+      F77_XFCN (sgemm, SGEMM, (F77_CONST_CHAR_ARG2 ("N", 1),
+			       F77_CONST_CHAR_ARG2 ("N", 1),
+			       len, a_len, 1, 1.0, v.data (), len,
+			       a.data (), 1, 0.0, c, len
+			       F77_CHAR_ARG_LEN (1)
+			       F77_CHAR_ARG_LEN (1)));
+    }
+
+  return retval;
+}
+
+// other operations.
+
+FloatMatrix
+FloatMatrix::map (dmapper fcn) const
+{
+  return MArray2<float>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexMatrix
+FloatMatrix::map (cmapper fcn) const
+{
+  return MArray2<float>::map<FloatComplex> (func_ptr (fcn));
+}
+
+boolMatrix
+FloatMatrix::map (bmapper fcn) const
+{
+  return MArray2<float>::map<bool> (func_ptr (fcn));
+}
+
+bool
+FloatMatrix::any_element_is_negative (bool neg_zero) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (neg_zero)
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (lo_ieee_signbit (elem (i)))
+	  return true;
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (elem (i) < 0)
+	  return true;
+    }
+
+  return false;
+}
+
+bool
+FloatMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+FloatMatrix::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+FloatMatrix::any_element_not_one_or_zero (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (val != 0 && val != 1)
+	return true;
+    }
+
+  return false;
+}
+
+bool
+FloatMatrix::all_elements_are_int_or_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisnan (val) || D_NINT (val) == val)
+	continue;
+      else
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of M is not an integer.  Also extract
+// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
+
+bool
+FloatMatrix::all_integers (float& max_val, float& min_val) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (nel > 0)
+    {
+      max_val = elem (0);
+      min_val = elem (0);
+    }
+  else
+    return false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+
+      if (val > max_val)
+	max_val = val;
+
+      if (val < min_val)
+	min_val = val;
+
+      if (D_NINT (val) != val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+FloatMatrix::too_large_for_float (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+
+      if (! (xisnan (val) || xisinf (val))
+	  && fabs (val) > FLT_MAX)
+	return true;
+    }
+
+  return false;
+}
+
+// FIXME Do these really belong here?  Maybe they should be
+// in a base class?
+
+boolMatrix
+FloatMatrix::all (int dim) const
+{
+  return do_mx_red_op<boolMatrix, float> (*this, dim, mx_inline_all);
+}
+
+boolMatrix
+FloatMatrix::any (int dim) const
+{
+  return do_mx_red_op<boolMatrix, float> (*this, dim, mx_inline_any);
+}
+
+FloatMatrix
+FloatMatrix::cumprod (int dim) const
+{
+  return do_mx_cum_op<FloatMatrix, float> (*this, dim, mx_inline_cumprod);
+}
+
+FloatMatrix
+FloatMatrix::cumsum (int dim) const
+{
+  return do_mx_cum_op<FloatMatrix, float> (*this, dim, mx_inline_cumsum);
+}
+
+FloatMatrix
+FloatMatrix::prod (int dim) const
+{
+  return do_mx_red_op<FloatMatrix, float> (*this, dim, mx_inline_prod);
+}
+
+FloatMatrix
+FloatMatrix::sum (int dim) const
+{
+  return do_mx_red_op<FloatMatrix, float> (*this, dim, mx_inline_sum);
+}
+
+FloatMatrix
+FloatMatrix::sumsq (int dim) const
+{
+  return do_mx_red_op<FloatMatrix, float> (*this, dim, mx_inline_sumsq);
+}
+
+FloatMatrix
+FloatMatrix::abs (void) const
+{
+  return FloatMatrix (mx_inline_fabs_dup (data (), length ()),
+                      rows (), cols ());
+}
+
+FloatMatrix
+FloatMatrix::diag (octave_idx_type k) const
+{
+  return MArray2<float>::diag (k);
+}
+
+FloatColumnVector
+FloatMatrix::row_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_min (dummy_idx);
+}
+
+FloatColumnVector
+FloatMatrix::row_min (Array<octave_idx_type>& idx_arg) const
+{
+  FloatColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  octave_idx_type idx_j;
+
+	  float tmp_min = octave_Float_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_min = elem (i, idx_j);
+
+	      if (! xisnan (tmp_min))
+		break;
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      float tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp < tmp_min)
+		{
+		  idx_j = j;
+		  tmp_min = tmp;
+		}
+	    }
+
+	  result.elem (i) = tmp_min;
+	  idx_arg.elem (i) = xisnan (tmp_min) ? 0 : idx_j;
+        }
+    }
+
+  return result;
+}
+
+FloatColumnVector
+FloatMatrix::row_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return row_max (dummy_idx);
+}
+
+FloatColumnVector
+FloatMatrix::row_max (Array<octave_idx_type>& idx_arg) const
+{
+  FloatColumnVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nr);
+      idx_arg.resize (nr);
+
+      for (octave_idx_type i = 0; i < nr; i++)
+        {
+	  octave_idx_type idx_j;
+
+	  float tmp_max = octave_Float_NaN;
+
+	  for (idx_j = 0; idx_j < nc; idx_j++)
+	    {
+	      tmp_max = elem (i, idx_j);
+
+	      if (! xisnan (tmp_max))
+		break;
+	    }
+
+	  for (octave_idx_type j = idx_j+1; j < nc; j++)
+	    {
+	      float tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp > tmp_max)
+		{
+		  idx_j = j;
+		  tmp_max = tmp;
+		}
+	    }
+
+	  result.elem (i) = tmp_max;
+	  idx_arg.elem (i) = xisnan (tmp_max) ? 0 : idx_j;
+        }
+    }
+
+  return result;
+}
+
+FloatRowVector
+FloatMatrix::column_min (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_min (dummy_idx);
+}
+
+FloatRowVector
+FloatMatrix::column_min (Array<octave_idx_type>& idx_arg) const
+{
+  FloatRowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  octave_idx_type idx_i;
+
+	  float tmp_min = octave_Float_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_min = elem (idx_i, j);
+
+	      if (! xisnan (tmp_min))
+		break;
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      float tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp < tmp_min)
+		{
+		  idx_i = i;
+		  tmp_min = tmp;
+		}
+	    }
+
+	  result.elem (j) = tmp_min;
+	  idx_arg.elem (j) = xisnan (tmp_min) ? 0 : idx_i;
+        }
+    }
+
+  return result;
+}
+
+FloatRowVector
+FloatMatrix::column_max (void) const
+{
+  Array<octave_idx_type> dummy_idx;
+  return column_max (dummy_idx);
+}
+
+FloatRowVector
+FloatMatrix::column_max (Array<octave_idx_type>& idx_arg) const
+{
+  FloatRowVector result;
+
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      result.resize (nc);
+      idx_arg.resize (nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+        {
+	  octave_idx_type idx_i;
+
+	  float tmp_max = octave_Float_NaN;
+
+	  for (idx_i = 0; idx_i < nr; idx_i++)
+	    {
+	      tmp_max = elem (idx_i, j);
+
+	      if (! xisnan (tmp_max))
+		break;
+	    }
+
+	  for (octave_idx_type i = idx_i+1; i < nr; i++)
+	    {
+	      float tmp = elem (i, j);
+
+	      if (xisnan (tmp))
+		continue;
+	      else if (tmp > tmp_max)
+		{
+		  idx_i = i;
+		  tmp_max = tmp;
+		}
+	    }
+
+	  result.elem (j) = tmp_max;
+	  idx_arg.elem (j) = xisnan (tmp_max) ? 0 : idx_i;
+        }
+    }
+
+  return result;
+}
+
+std::ostream&
+operator << (std::ostream& os, const FloatMatrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    {
+      for (octave_idx_type j = 0; j < a.cols (); j++)
+	{
+	  os << " ";
+	  octave_write_float (os, a.elem (i, j));
+	}
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr > 0 && nc > 0)
+    {
+      float tmp;
+      for (octave_idx_type i = 0; i < nr; i++)
+	for (octave_idx_type j = 0; j < nc; j++)
+	  {
+	    tmp = octave_read_float (is);
+	    if (is)
+	      a.elem (i, j) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+ done:
+
+  return is;
+}
+
+FloatMatrix
+Givens (float x, float y)
+{
+  float cc, s, temp_r;
+
+  F77_FUNC (slartg, SLARTG) (x, y, cc, s, temp_r);
+
+  FloatMatrix g (2, 2);
+
+  g.elem (0, 0) = cc;
+  g.elem (1, 1) = cc;
+  g.elem (0, 1) = s;
+  g.elem (1, 0) = -s;
+
+  return g;
+}
+
+FloatMatrix
+Sylvester (const FloatMatrix& a, const FloatMatrix& b, const FloatMatrix& c)
+{
+  FloatMatrix retval;
+
+  // FIXME -- need to check that a, b, and c are all the same
+  // size.
+
+  // Compute Schur decompositions.
+
+  FloatSCHUR as (a, "U");
+  FloatSCHUR bs (b, "U");
+  
+  // Transform c to new coordinates.
+
+  FloatMatrix ua = as.unitary_matrix ();
+  FloatMatrix sch_a = as.schur_matrix ();
+
+  FloatMatrix ub = bs.unitary_matrix ();
+  FloatMatrix sch_b = bs.schur_matrix ();
+  
+  FloatMatrix cx = ua.transpose () * c * ub;
+  
+  // Solve the sylvester equation, back-transform, and return the
+  // solution.
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type b_nr = b.rows ();
+
+  float scale;
+  octave_idx_type info;
+
+  float *pa = sch_a.fortran_vec ();
+  float *pb = sch_b.fortran_vec ();
+  float *px = cx.fortran_vec ();
+
+  F77_XFCN (strsyl, STRSYL, (F77_CONST_CHAR_ARG2 ("N", 1),
+			     F77_CONST_CHAR_ARG2 ("N", 1),
+			     1, a_nr, b_nr, pa, a_nr, pb,
+			     b_nr, px, a_nr, scale, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+
+  // FIXME -- check info?
+  
+  retval = -ua*cx*ub.transpose ();
+
+  return retval;
+}
+
+// matrix by matrix -> matrix operations
+
+/* Simple Dot Product, Matrix-Vector and Matrix-Matrix Unit tests
+%!assert(single([1 2 3]) * single([ 4 ; 5 ; 6]), single(32), 5e-7)
+%!assert(single([1 2 ; 3 4 ]) * single([5 ; 6]), single([17 ; 39 ]), 5e-7)
+%!assert(single([1 2 ; 3 4 ]) * single([5 6 ; 7 8]), single([19 22; 43 50]), 5e-7)
+*/
+
+/* Test some simple identities
+%!shared M, cv, rv
+%! M = single(randn(10,10));
+%! cv = single(randn(10,1));
+%! rv = single(randn(1,10));
+%!assert([M*cv,M*cv],M*[cv,cv],5e-6)
+%!assert([M'*cv,M'*cv],M'*[cv,cv],5e-6)
+%!assert([rv*M;rv*M],[rv;rv]*M,5e-6)
+%!assert([rv*M';rv*M'],[rv;rv]*M',5e-6)
+%!assert(2*rv*cv,[rv,rv]*[cv;cv],5e-6)
+*/
+
+static const char *
+get_blas_trans_arg (bool trans)
+{
+  static char blas_notrans = 'N', blas_trans = 'T';
+  return (trans) ? &blas_trans : &blas_notrans;
+}
+
+// the general GEMM operation
+
+FloatMatrix 
+xgemm (bool transa, const FloatMatrix& a, bool transb, const FloatMatrix& b)
+{
+  FloatMatrix retval;
+
+  octave_idx_type a_nr = transa ? a.cols () : a.rows ();
+  octave_idx_type a_nc = transa ? a.rows () : a.cols ();
+
+  octave_idx_type b_nr = transb ? b.cols () : b.rows ();
+  octave_idx_type b_nc = transb ? b.rows () : b.cols ();
+
+  if (a_nc != b_nr)
+    gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
+  else
+    {
+      if (a_nr == 0 || a_nc == 0 || b_nc == 0)
+	retval = FloatMatrix (a_nr, b_nc, 0.0);
+      else if (a.data () == b.data () && a_nr == b_nc && transa != transb)
+        {
+	  octave_idx_type lda = a.rows ();
+
+          retval = FloatMatrix (a_nr, b_nc);
+	  float *c = retval.fortran_vec ();
+
+          const char *ctransa = get_blas_trans_arg (transa);
+          F77_XFCN (ssyrk, SSYRK, (F77_CONST_CHAR_ARG2 ("U", 1),
+                                   F77_CONST_CHAR_ARG2 (ctransa, 1),
+                                   a_nr, a_nc, 1.0,
+                                   a.data (), lda, 0.0, c, a_nr
+                                   F77_CHAR_ARG_LEN (1)
+                                   F77_CHAR_ARG_LEN (1)));
+          for (int j = 0; j < a_nr; j++)
+            for (int i = 0; i < j; i++)
+              retval.xelem (j,i) = retval.xelem (i,j);
+
+        }
+      else
+	{
+	  octave_idx_type lda = a.rows (), tda = a.cols ();
+	  octave_idx_type ldb = b.rows (), tdb = b.cols ();
+
+	  retval = FloatMatrix (a_nr, b_nc);
+	  float *c = retval.fortran_vec ();
+
+	  if (b_nc == 1)
+	    {
+	      if (a_nr == 1)
+		F77_FUNC (xsdot, XSDOT) (a_nc, a.data (), 1, b.data (), 1, *c);
+	      else
+		{
+                  const char *ctransa = get_blas_trans_arg (transa);
+		  F77_XFCN (sgemv, SGEMV, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+					   lda, tda, 1.0,  a.data (), lda,
+					   b.data (), 1, 0.0, c, 1
+					   F77_CHAR_ARG_LEN (1)));
+		}
+            }
+          else if (a_nr == 1)
+            {
+              const char *crevtransb = get_blas_trans_arg (! transb);
+              F77_XFCN (sgemv, SGEMV, (F77_CONST_CHAR_ARG2 (crevtransb, 1),
+                                       ldb, tdb, 1.0,  b.data (), ldb,
+                                       a.data (), 1, 0.0, c, 1
+                                       F77_CHAR_ARG_LEN (1)));
+            }
+	  else
+	    {
+              const char *ctransa = get_blas_trans_arg (transa);
+              const char *ctransb = get_blas_trans_arg (transb);
+	      F77_XFCN (sgemm, SGEMM, (F77_CONST_CHAR_ARG2 (ctransa, 1),
+				       F77_CONST_CHAR_ARG2 (ctransb, 1),
+				       a_nr, b_nc, a_nc, 1.0, a.data (),
+				       lda, b.data (), ldb, 0.0, c, a_nr
+				       F77_CHAR_ARG_LEN (1)
+				       F77_CHAR_ARG_LEN (1)));
+	    }
+	}
+    }
+
+  return retval;
+}
+
+FloatMatrix
+operator * (const FloatMatrix& a, const FloatMatrix& b)
+{
+  return xgemm (false, a, false, b);
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nr == 0 || nc == 0) \
+    return T (nr, nc);
+
+FloatMatrix
+min (float d, const FloatMatrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatMatrix);
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (d, m (i, j));
+      }
+
+  return result;
+}
+
+FloatMatrix
+min (const FloatMatrix& m, float d)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatMatrix);
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (m (i, j), d);
+      }
+
+  return result;
+}
+
+FloatMatrix
+min (const FloatMatrix& a, const FloatMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return FloatMatrix ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatMatrix);
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmin (a (i, j), b (i, j));
+      }
+
+  return result;
+}
+
+FloatMatrix
+max (float d, const FloatMatrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatMatrix);
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (d, m (i, j));
+      }
+
+  return result;
+}
+
+FloatMatrix
+max (const FloatMatrix& m, float d)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  EMPTY_RETURN_CHECK (FloatMatrix);
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (m (i, j), d);
+      }
+
+  return result;
+}
+
+FloatMatrix
+max (const FloatMatrix& a, const FloatMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
+
+  if (nr != b.rows () || nc != b.columns ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return FloatMatrix ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatMatrix);
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = xmax (a (i, j), b (i, j));
+      }
+
+  return result;
+}
+
+MS_CMP_OPS(FloatMatrix, , float, )
+MS_BOOL_OPS(FloatMatrix, float, 0.0)
+
+SM_CMP_OPS(float, , FloatMatrix, )
+SM_BOOL_OPS(float, FloatMatrix, 0.0)
+
+MM_CMP_OPS(FloatMatrix, , FloatMatrix, )
+MM_BOOL_OPS(FloatMatrix, FloatMatrix, 0.0)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fMatrix.h b/liboctave/fMatrix.h
new file mode 100644
index 0000000..0ec9bf7
--- /dev/null
+++ b/liboctave/fMatrix.h
@@ -0,0 +1,381 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatMatrix_int_h)
+#define octave_FloatMatrix_int_h 1
+
+#include "MArray2.h"
+#include "MDiagArray2.h"
+#include "MatrixType.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+#include "DET.h"
+
+class
+OCTAVE_API
+FloatMatrix : public MArray2<float>
+{
+public:
+
+  typedef void (*solve_singularity_handler) (float rcon);
+
+  FloatMatrix (void) : MArray2<float> () { }
+
+  FloatMatrix (octave_idx_type r, octave_idx_type c) : MArray2<float> (r, c) { }
+
+  FloatMatrix (octave_idx_type r, octave_idx_type c, float val) : MArray2<float> (r, c, val) { }
+
+  FloatMatrix (const dim_vector& dv) : MArray2<float> (dv) { }
+
+  FloatMatrix (const dim_vector& dv, float val) : MArray2<float> (dv, val) { }
+
+  FloatMatrix (const FloatMatrix& a) : MArray2<float> (a) { }
+
+  template <class U>
+  FloatMatrix (const MArray2<U>& a) : MArray2<float> (a) { }
+
+  template <class U>
+  FloatMatrix (const Array2<U>& a) : MArray2<float> (a) { }
+
+  explicit FloatMatrix (const FloatRowVector& rv);
+
+  explicit FloatMatrix (const FloatColumnVector& cv);
+
+  explicit FloatMatrix (const FloatDiagMatrix& a);
+
+  explicit FloatMatrix (const PermMatrix& a);
+
+  explicit FloatMatrix (const boolMatrix& a);
+
+  explicit FloatMatrix (const charMatrix& a);
+
+
+  FloatMatrix& operator = (const FloatMatrix& a)
+    {
+      MArray2<float>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatMatrix& a) const;
+  bool operator != (const FloatMatrix& a) const;
+
+  bool is_symmetric (void) const;
+
+  // destructive insert/delete/reorder operations
+
+  FloatMatrix& insert (const FloatMatrix& a, octave_idx_type r, octave_idx_type c);
+  FloatMatrix& insert (const FloatRowVector& a, octave_idx_type r, octave_idx_type c);
+  FloatMatrix& insert (const FloatColumnVector& a, octave_idx_type r, octave_idx_type c);
+  FloatMatrix& insert (const FloatDiagMatrix& a, octave_idx_type r, octave_idx_type c);
+
+  FloatMatrix& fill (float val);
+  FloatMatrix& fill (float val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+
+  FloatMatrix append (const FloatMatrix& a) const;
+  FloatMatrix append (const FloatRowVector& a) const;
+  FloatMatrix append (const FloatColumnVector& a) const;
+  FloatMatrix append (const FloatDiagMatrix& a) const;
+
+  FloatMatrix stack (const FloatMatrix& a) const;
+  FloatMatrix stack (const FloatRowVector& a) const;
+  FloatMatrix stack (const FloatColumnVector& a) const;
+  FloatMatrix stack (const FloatDiagMatrix& a) const;
+
+  friend OCTAVE_API FloatMatrix real (const FloatComplexMatrix& a);
+  friend OCTAVE_API FloatMatrix imag (const FloatComplexMatrix& a);
+
+  friend class FloatComplexMatrix;
+
+  FloatMatrix transpose (void) const { return MArray2<float>::transpose (); }
+
+  // resize is the destructive equivalent for this one
+
+  FloatMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
+
+  FloatMatrix extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const;
+
+  // extract row or column i.
+
+  FloatRowVector row (octave_idx_type i) const;
+
+  FloatColumnVector column (octave_idx_type i) const;
+
+private:
+  FloatMatrix tinverse (MatrixType &mattype, octave_idx_type& info, float& rcon, 
+		   int force, int calc_cond) const;
+
+  FloatMatrix finverse (MatrixType &mattype, octave_idx_type& info, float& rcon, 
+		   int force, int calc_cond) const;
+
+public:
+  FloatMatrix inverse (void) const;
+  FloatMatrix inverse (octave_idx_type& info) const;
+  FloatMatrix inverse (octave_idx_type& info, float& rcon, int force = 0,
+		  int calc_cond = 1) const;
+
+  FloatMatrix inverse (MatrixType &mattype) const;
+  FloatMatrix inverse (MatrixType &mattype, octave_idx_type& info) const;
+  FloatMatrix inverse (MatrixType &mattype, octave_idx_type& info, float& rcon,
+		  int force = 0, int calc_cond = 1) const;
+
+  FloatMatrix pseudo_inverse (float tol = 0.0) const;
+
+  FloatComplexMatrix fourier (void) const;
+  FloatComplexMatrix ifourier (void) const;
+
+  FloatComplexMatrix fourier2d (void) const;
+  FloatComplexMatrix ifourier2d (void) const;
+
+  FloatDET determinant (void) const;
+  FloatDET determinant (octave_idx_type& info) const;
+  FloatDET determinant (octave_idx_type& info, float& rcon, int calc_cond = 1) const;
+  FloatDET determinant (MatrixType &mattype, octave_idx_type& info, 
+                        float& rcon, int calc_cond = 1) const;
+
+  float rcond (void) const;
+  float rcond (MatrixType &mattype) const;
+
+private:
+  // Upper triangular matrix solvers
+  FloatMatrix utsolve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info,
+		  float& rcon, solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Lower triangular matrix solvers
+  FloatMatrix ltsolve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info,
+		  float& rcon, solve_singularity_handler sing_handler,
+		  bool calc_cond = false) const;
+
+  // Full matrix solvers (lu/cholesky)
+  FloatMatrix fsolve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info,
+		 float& rcon, solve_singularity_handler sing_handler,
+		 bool calc_cond = false) const;
+
+public:
+  // Generic interface to solver with no probing of type
+  FloatMatrix solve (MatrixType &typ, const FloatMatrix& b) const;
+  FloatMatrix solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info) const;
+  FloatMatrix solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info, 
+		float& rcon) const;
+  FloatMatrix solve (MatrixType &typ, const FloatMatrix& b, octave_idx_type& info,
+		float& rcon, solve_singularity_handler sing_handler,
+		bool singular_fallback = true) const;
+
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		       octave_idx_type& info) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		       octave_idx_type& info, float& rcon) const;
+  FloatComplexMatrix solve (MatrixType &typ, const FloatComplexMatrix& b, 
+		       octave_idx_type& info, float& rcon,
+		       solve_singularity_handler sing_handler,
+		       bool singular_fallback = true) const;
+
+  FloatColumnVector solve (MatrixType &typ, const FloatColumnVector& b) const;
+  FloatColumnVector solve (MatrixType &typ, const FloatColumnVector& b, 
+		      octave_idx_type& info) const;
+  FloatColumnVector solve (MatrixType &typ, const FloatColumnVector& b, 
+		      octave_idx_type& info, float& rcon) const;
+  FloatColumnVector solve (MatrixType &typ, const FloatColumnVector& b, 
+		      octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler) const;
+
+  FloatComplexColumnVector solve (MatrixType &typ, 
+			     const FloatComplexColumnVector& b) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+			     octave_idx_type& info) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+			     octave_idx_type& info, float& rcon) const;
+  FloatComplexColumnVector solve (MatrixType &typ, const FloatComplexColumnVector& b, 
+			     octave_idx_type& info, float& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  // Generic interface to solver with probing of type
+  FloatMatrix solve (const FloatMatrix& b) const;
+  FloatMatrix solve (const FloatMatrix& b, octave_idx_type& info) const;
+  FloatMatrix solve (const FloatMatrix& b, octave_idx_type& info, float& rcon) const;
+  FloatMatrix solve (const FloatMatrix& b, octave_idx_type& info, float& rcon,
+		solve_singularity_handler sing_handler) const;
+
+  FloatComplexMatrix solve (const FloatComplexMatrix& b) const;
+  FloatComplexMatrix solve (const FloatComplexMatrix& b, octave_idx_type& info) const;
+  FloatComplexMatrix solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon) const;
+  FloatComplexMatrix solve (const FloatComplexMatrix& b, octave_idx_type& info, float& rcon,
+		       solve_singularity_handler sing_handler) const;
+
+  FloatColumnVector solve (const FloatColumnVector& b) const;
+  FloatColumnVector solve (const FloatColumnVector& b, octave_idx_type& info) const;
+  FloatColumnVector solve (const FloatColumnVector& b, octave_idx_type& info, float& rcon) const;
+  FloatColumnVector solve (const FloatColumnVector& b, octave_idx_type& info, float& rcon,
+		      solve_singularity_handler sing_handler) const;
+
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b) const;
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b, octave_idx_type& info) const;
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b, octave_idx_type& info,
+			     float& rcon) const;
+  FloatComplexColumnVector solve (const FloatComplexColumnVector& b, octave_idx_type& info,
+			     float& rcon,
+			     solve_singularity_handler sing_handler) const;
+
+  // Singular solvers
+  FloatMatrix lssolve (const FloatMatrix& b) const;
+  FloatMatrix lssolve (const FloatMatrix& b, octave_idx_type& info) const;
+  FloatMatrix lssolve (const FloatMatrix& b, octave_idx_type& info, 
+		  octave_idx_type& rank) const;
+  FloatMatrix lssolve (const FloatMatrix& b, octave_idx_type& info, 
+		  octave_idx_type& rank, float& rcon) const;
+
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b) const;
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b, octave_idx_type& info) const;
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank) const;
+  FloatComplexMatrix lssolve (const FloatComplexMatrix& b, octave_idx_type& info,
+			 octave_idx_type& rank, float &rcon) const;
+
+  FloatColumnVector lssolve (const FloatColumnVector& b) const;
+  FloatColumnVector lssolve (const FloatColumnVector& b, octave_idx_type& info) const;
+  FloatColumnVector lssolve (const FloatColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank) const;
+  FloatColumnVector lssolve (const FloatColumnVector& b, octave_idx_type& info,
+			octave_idx_type& rank, float& rcon) const;
+
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b) const;
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b, 
+			       octave_idx_type& info) const;
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b,
+			       octave_idx_type& info,
+			       octave_idx_type& rank) const;
+  FloatComplexColumnVector lssolve (const FloatComplexColumnVector& b, 
+			       octave_idx_type& info,
+			       octave_idx_type& rank, float& rcon) const;
+
+  FloatMatrix& operator += (const FloatDiagMatrix& a);
+  FloatMatrix& operator -= (const FloatDiagMatrix& a);
+
+  // unary operations
+
+  boolMatrix operator ! (void) const;
+
+  // other operations
+
+  typedef float (*dmapper) (float);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+  typedef bool (*bmapper) (float);
+
+  FloatMatrix map (dmapper fcn) const;
+  FloatComplexMatrix map (cmapper fcn) const;
+  boolMatrix map (bmapper fcn) const;
+
+  bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool any_element_not_one_or_zero (void) const;
+  bool all_elements_are_int_or_inf_or_nan (void) const;
+  bool all_integers (float& max_val, float& min_val) const;
+  bool too_large_for_float (void) const;
+ 
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+  FloatMatrix cumprod (int dim = -1) const;
+  FloatMatrix cumsum (int dim = -1) const;
+  FloatMatrix prod (int dim = -1) const;
+  FloatMatrix sum (int dim = -1) const;
+  FloatMatrix sumsq (int dim = -1) const;
+  FloatMatrix abs (void) const;
+
+  FloatMatrix diag (octave_idx_type k = 0) const;
+
+  FloatColumnVector row_min (void) const;
+  FloatColumnVector row_max (void) const;
+
+  FloatColumnVector row_min (Array<octave_idx_type>& index) const;
+  FloatColumnVector row_max (Array<octave_idx_type>& index) const;
+
+  FloatRowVector column_min (void) const;
+  FloatRowVector column_max (void) const;
+
+  FloatRowVector column_min (Array<octave_idx_type>& index) const;
+  FloatRowVector column_max (Array<octave_idx_type>& index) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatMatrix& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatMatrix& a);
+
+  static float resize_fill_value (void) { return 0; }
+
+private:
+
+  FloatMatrix (float *d, octave_idx_type r, octave_idx_type c) : MArray2<float> (d, r, c) { }
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API FloatMatrix real (const FloatComplexMatrix& a);
+extern OCTAVE_API FloatMatrix imag (const FloatComplexMatrix& a);
+
+// column vector by row vector -> matrix operations
+
+extern OCTAVE_API FloatMatrix operator * (const FloatColumnVector& a, const FloatRowVector& b);
+
+// Other functions.
+
+extern OCTAVE_API FloatMatrix Givens (float, float);
+
+extern OCTAVE_API FloatMatrix Sylvester (const FloatMatrix&, const FloatMatrix&, const FloatMatrix&);
+
+extern OCTAVE_API FloatMatrix xgemm (bool transa, const FloatMatrix& a, bool transb, const FloatMatrix& b);
+
+extern OCTAVE_API FloatMatrix operator * (const FloatMatrix& a, const FloatMatrix& b);
+
+extern OCTAVE_API FloatMatrix min (float d, const FloatMatrix& m);
+extern OCTAVE_API FloatMatrix min (const FloatMatrix& m, float d);
+extern OCTAVE_API FloatMatrix min (const FloatMatrix& a, const FloatMatrix& b);
+
+extern OCTAVE_API FloatMatrix max (float d, const FloatMatrix& m);
+extern OCTAVE_API FloatMatrix max (const FloatMatrix& m, float d);
+extern OCTAVE_API FloatMatrix max (const FloatMatrix& a, const FloatMatrix& b);
+
+MS_CMP_OP_DECLS (FloatMatrix, float, OCTAVE_API)
+MS_BOOL_OP_DECLS (FloatMatrix, float, OCTAVE_API)
+
+SM_CMP_OP_DECLS (float, FloatMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (float, FloatMatrix, OCTAVE_API)
+
+MM_CMP_OP_DECLS (FloatMatrix, FloatMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (FloatMatrix, FloatMatrix, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArray2, FloatMatrix, float)
+
+template <class T>
+void read_int (std::istream& is, bool swap_bytes, T& val);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fNDArray.cc b/liboctave/fNDArray.cc
new file mode 100644
index 0000000..33a526a
--- /dev/null
+++ b/liboctave/fNDArray.cc
@@ -0,0 +1,1089 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include <vector>
+
+#include "Array-util.h"
+#include "fNDArray.h"
+#include "functor.h"
+#include "mx-base.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+#include "mx-op-defs.h"
+
+FloatNDArray::FloatNDArray (const charNDArray& a)
+  : MArrayN<float> (a.dims ())
+{
+  octave_idx_type n = a.numel ();
+  for (octave_idx_type i = 0; i < n; i++)
+    xelem (i) = static_cast<unsigned char> (a(i));
+}
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+
+FloatComplexNDArray
+FloatNDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  const float *in (fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::fft (in + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  octave_idx_type stride = 1;
+  octave_idx_type n = dv(dim);
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / dv (dim);
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
+  octave_idx_type dist = (stride == 1 ? n : 1);
+
+  FloatComplexNDArray retval (*this);
+  FloatComplex *out (retval.fortran_vec ());
+
+  // Need to be careful here about the distance between fft's
+  for (octave_idx_type k = 0; k < nloop; k++)
+    octave_fftw::ifft (out + k * stride * n, out + k * stride * n, 
+		      n, howmany, stride, dist);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::fourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return FloatComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  const float *in = fortran_vec ();
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  if (dv.length () < 2)
+    return FloatComplexNDArray ();
+
+  dim_vector dv2(dv(0), dv(1));
+  FloatComplexNDArray retval (*this);
+  FloatComplex *out = retval.fortran_vec ();
+  octave_idx_type howmany = numel() / dv(0) / dv(1);
+  octave_idx_type dist = dv(0) * dv(1);
+
+  for (octave_idx_type i=0; i < howmany; i++)
+    octave_fftw::ifftNd (out + i*dist, out + i*dist, 2, dv2);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  const float *in (fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::fftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+
+  FloatComplexNDArray tmp (*this);
+  FloatComplex *in (tmp.fortran_vec ());
+  FloatComplexNDArray retval (dv);
+  FloatComplex *out (retval.fortran_vec ());
+
+  octave_fftw::ifftNd (in, out, rank, dv);
+
+  return retval;
+}
+
+#else
+
+extern "C"
+{
+  // Note that the original complex fft routines were not written for
+  // float complex arguments.  They have been modified by adding an
+  // implicit float precision (a-h,o-z) statement at the beginning of
+  // each subroutine.
+
+  F77_RET_T
+  F77_FUNC (cffti, CFFTI) (const octave_idx_type&, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftf, CFFTF) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+
+  F77_RET_T
+  F77_FUNC (cfftb, CFFTB) (const octave_idx_type&, FloatComplex*, FloatComplex*);
+}
+
+FloatComplexNDArray
+FloatNDArray::fourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  FloatComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (cfftf, CFFTF) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i];
+	}
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::ifourier (int dim) const
+{
+  dim_vector dv = dims ();
+
+  if (dim > dv.length () || dim < 0)
+    return FloatComplexNDArray ();
+
+  FloatComplexNDArray retval (dv);
+  octave_idx_type npts = dv(dim);
+  octave_idx_type nn = 4*npts+15;
+  Array<FloatComplex> wsave (nn);
+  FloatComplex *pwsave = wsave.fortran_vec ();
+
+  OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
+
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < dim; i++)
+    stride *= dv(i);
+
+  octave_idx_type howmany = numel () / npts;
+  howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
+  octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+  octave_idx_type dist = (stride == 1 ? npts : 1);
+
+  F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+  for (octave_idx_type k = 0; k < nloop; k++)
+    {
+      for (octave_idx_type j = 0; j < howmany; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    tmp[i] = elem((i + k*npts)*stride + j*dist);
+
+	  F77_FUNC (cfftb, CFFTB) (npts, tmp, pwsave);
+
+	  for (octave_idx_type i = 0; i < npts; i++)
+	    retval ((i + k*npts)*stride + j*dist) = tmp[i] / 
+	      static_cast<float> (npts);
+	}
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::fourier2d (void) const
+{
+  dim_vector dv = dims();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::ifourier2d (void) const
+{
+  dim_vector dv = dims();
+  dim_vector dv2 (dv(0), dv(1));
+  int rank = 2;
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv2(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] / 
+		  static_cast<float> (npts);
+	    }
+	}
+
+      stride *= dv2(i);
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::fourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l];
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+FloatComplexNDArray
+FloatNDArray::ifourierNd (void) const
+{
+  dim_vector dv = dims ();
+  int rank = dv.length ();
+  FloatComplexNDArray retval (*this);
+  octave_idx_type stride = 1;
+
+  for (int i = 0; i < rank; i++)
+    {
+      octave_idx_type npts = dv(i);
+      octave_idx_type nn = 4*npts+15;
+      Array<FloatComplex> wsave (nn);
+      FloatComplex *pwsave = wsave.fortran_vec ();
+      Array<FloatComplex> row (npts);
+      FloatComplex *prow = row.fortran_vec ();
+
+      octave_idx_type howmany = numel () / npts;
+      howmany = (stride == 1 ? howmany : 
+		 (howmany > stride ? stride : howmany));
+      octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
+      octave_idx_type dist = (stride == 1 ? npts : 1);
+
+      F77_FUNC (cffti, CFFTI) (npts, pwsave);
+
+      for (octave_idx_type k = 0; k < nloop; k++)
+	{
+	  for (octave_idx_type j = 0; j < howmany; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		prow[l] = retval ((l + k*npts)*stride + j*dist);
+
+	      F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
+
+	      for (octave_idx_type l = 0; l < npts; l++)
+		retval ((l + k*npts)*stride + j*dist) = prow[l] /
+		  static_cast<float> (npts);
+	    }
+	}
+
+      stride *= dv(i);
+    }
+
+  return retval;
+}
+
+#endif
+
+// unary operations
+
+boolNDArray
+FloatNDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (octave_idx_type i = 0; i < length (); i++)
+    b.elem (i) = ! elem (i);
+
+  return b;
+}
+
+bool
+FloatNDArray::any_element_is_negative (bool neg_zero) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (neg_zero)
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (lo_ieee_signbit (elem (i)))
+	  return true;
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < nel; i++)
+	if (elem (i) < 0)
+	  return true;
+    }
+
+  return false;
+}
+
+bool
+FloatNDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+FloatNDArray::any_element_is_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisinf (val) || xisnan (val))
+	return true;
+    }
+
+  return false;
+}
+
+bool
+FloatNDArray::any_element_not_one_or_zero (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (val != 0 && val != 1)
+	return true;
+    }
+
+  return false;
+}
+
+bool
+FloatNDArray::all_elements_are_zero (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    if (elem (i) != 0)
+      return false;
+
+  return true;
+}
+
+bool
+FloatNDArray::all_elements_are_int_or_inf_or_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisnan (val) || D_NINT (val) == val)
+	continue;
+      else
+	return false;
+    }
+
+  return true;
+}
+
+// Return nonzero if any element of M is not an integer.  Also extract
+// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
+
+bool
+FloatNDArray::all_integers (float& max_val, float& min_val) const
+{
+  octave_idx_type nel = nelem ();
+
+  if (nel > 0)
+    {
+      max_val = elem (0);
+      min_val = elem (0);
+    }
+  else
+    return false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+
+      if (val > max_val)
+	max_val = val;
+
+      if (val < min_val)
+	min_val = val;
+
+      if (D_NINT (val) != val)
+	return false;
+    }
+
+  return true;
+}
+
+bool
+FloatNDArray::too_large_for_float (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+
+      if (! (xisnan (val) || xisinf (val))
+	  && fabs (val) > FLT_MAX)
+	return true;
+    }
+
+  return false;
+}
+
+// FIXME -- this is not quite the right thing.
+
+boolNDArray
+FloatNDArray::all (int dim) const
+{
+  return do_mx_red_op<boolNDArray, float> (*this, dim, mx_inline_all);
+}
+
+boolNDArray
+FloatNDArray::any (int dim) const
+{
+  return do_mx_red_op<boolNDArray, float> (*this, dim, mx_inline_any);
+}
+
+FloatNDArray
+FloatNDArray::cumprod (int dim) const
+{
+  return do_mx_cum_op<FloatNDArray, float> (*this, dim, mx_inline_cumprod);
+}
+
+FloatNDArray
+FloatNDArray::cumsum (int dim) const
+{
+  return do_mx_cum_op<FloatNDArray, float> (*this, dim, mx_inline_cumsum);
+}
+
+FloatNDArray
+FloatNDArray::prod (int dim) const
+{
+  return do_mx_red_op<FloatNDArray, float> (*this, dim, mx_inline_prod);
+}
+
+FloatNDArray
+FloatNDArray::sum (int dim) const
+{
+  return do_mx_red_op<FloatNDArray, float> (*this, dim, mx_inline_sum);
+}
+
+FloatNDArray
+FloatNDArray::sumsq (int dim) const
+{
+  return do_mx_red_op<FloatNDArray, float> (*this, dim, mx_inline_sumsq);
+}
+
+FloatNDArray
+FloatNDArray::max (int dim) const
+{
+  return do_mx_minmax_op<FloatNDArray> (*this, dim, mx_inline_max);
+}
+
+FloatNDArray
+FloatNDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_max);
+}
+
+FloatNDArray
+FloatNDArray::min (int dim) const
+{
+  return do_mx_minmax_op<FloatNDArray> (*this, dim, mx_inline_min);
+}
+
+FloatNDArray
+FloatNDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_min);
+}
+
+FloatNDArray
+FloatNDArray::cummax (int dim) const
+{
+  return do_mx_cumminmax_op<FloatNDArray> (*this, dim, mx_inline_cummax);
+}
+
+FloatNDArray
+FloatNDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_cummax);
+}
+
+FloatNDArray
+FloatNDArray::cummin (int dim) const
+{
+  return do_mx_cumminmax_op<FloatNDArray> (*this, dim, mx_inline_cummin);
+}
+
+FloatNDArray
+FloatNDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_cummin);
+}
+
+FloatNDArray
+FloatNDArray::concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+FloatComplexNDArray
+FloatNDArray::concat (const FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  FloatComplexNDArray retval (*this);
+  if (rb.numel () > 0)
+    retval.insert (rb, ra_idx);
+  return retval;
+}
+
+charNDArray
+FloatNDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx)
+{
+  charNDArray retval (dims ());
+  octave_idx_type nel = numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float d = elem (i);
+
+      if (xisnan (d))
+	{
+	  (*current_liboctave_error_handler)
+	    ("invalid conversion from NaN to character");
+	  return retval;
+	}
+      else
+	{
+	  octave_idx_type ival = NINTbig (d);
+
+	  if (ival < 0 || ival > UCHAR_MAX)
+	    // FIXME -- is there something
+	    // better we could do? Should we warn the user?
+	    ival = 0;
+
+	  retval.elem (i) = static_cast<char>(ival);
+	}
+    }
+
+  if (rb.numel () == 0)
+    return retval;
+
+  retval.insert (rb, ra_idx);
+  return retval;
+}
+
+FloatNDArray
+real (const FloatComplexNDArray& a)
+{
+  return FloatNDArray (mx_inline_real_dup (a.data (), a.length ()),
+                       a.dims ());
+}
+
+FloatNDArray
+imag (const FloatComplexNDArray& a)
+{
+  return FloatNDArray (mx_inline_imag_dup (a.data (), a.length ()),
+                       a.dims ());
+}
+
+FloatNDArray&
+FloatNDArray::insert (const FloatNDArray& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<float>::insert (a, r, c);
+  return *this;
+}
+
+FloatNDArray&
+FloatNDArray::insert (const FloatNDArray& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<float>::insert (a, ra_idx);
+  return *this;
+}
+
+FloatNDArray
+FloatNDArray::abs (void) const
+{
+  return FloatNDArray (mx_inline_fabs_dup (data (), length ()),
+                       dims ());
+}
+
+boolNDArray
+FloatNDArray::isnan (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisnan));
+}
+
+boolNDArray
+FloatNDArray::isinf (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xisinf));
+}
+
+boolNDArray
+FloatNDArray::isfinite (void) const
+{
+  return ArrayN<bool> (fastmap<bool> (xfinite));
+}
+
+FloatMatrix
+FloatNDArray::matrix_value (void) const
+{
+  FloatMatrix retval;
+
+  if (ndims () == 2)
+      retval = FloatMatrix (Array2<float> (*this));
+  else
+    (*current_liboctave_error_handler)
+      ("invalid conversion of FloatNDArray to FloatMatrix");
+
+  return retval;
+}
+
+void
+FloatNDArray::increment_index (Array<octave_idx_type>& ra_idx,
+			  const dim_vector& dimensions,
+			  int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+octave_idx_type
+FloatNDArray::compute_index (Array<octave_idx_type>& ra_idx,
+			const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+FloatNDArray
+FloatNDArray::diag (octave_idx_type k) const
+{
+  return MArrayN<float>::diag (k);
+}
+
+FloatNDArray
+FloatNDArray::map (dmapper fcn) const
+{
+  return MArrayN<float>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexNDArray
+FloatNDArray::map (cmapper fcn) const
+{
+  return MArrayN<float>::map<FloatComplex> (func_ptr (fcn));
+}
+
+boolNDArray
+FloatNDArray::map (bmapper fcn) const
+{
+  return MArrayN<float>::map<bool> (func_ptr (fcn));
+}
+
+// This contains no information on the array structure !!!
+std::ostream&
+operator << (std::ostream& os, const FloatNDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      os << " ";
+      octave_write_float (os, a.elem (i));
+      os << "\n";
+    }
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatNDArray& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  if (nel > 0)
+    {
+      float tmp;
+      for (octave_idx_type i = 0; i < nel; i++)
+	  {
+	    tmp = octave_read_float (is);
+	    if (is)
+	      a.elem (i) = tmp;
+	    else
+	      goto done;
+	  }
+    }
+
+ done:
+
+  return is;
+}
+
+// FIXME -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nel == 0)	\
+    return T (dv);
+
+FloatNDArray
+min (float d, const FloatNDArray& m)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatNDArray);
+
+  FloatNDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (d, m (i));
+    }
+
+  return result;
+}
+
+FloatNDArray
+min (const FloatNDArray& m, float d)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatNDArray);
+
+  FloatNDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (d, m (i));
+    }
+
+  return result;
+}
+
+FloatNDArray
+min (const FloatNDArray& a, const FloatNDArray& b)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return FloatNDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatNDArray);
+
+  FloatNDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (a (i), b (i));
+    }
+
+  return result;
+}
+
+FloatNDArray
+max (float d, const FloatNDArray& m)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatNDArray);
+
+  FloatNDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (d, m (i));
+    }
+
+  return result;
+}
+
+FloatNDArray
+max (const FloatNDArray& m, float d)
+{
+  dim_vector dv = m.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (FloatNDArray);
+
+  FloatNDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (d, m (i));
+    }
+
+  return result;
+}
+
+FloatNDArray
+max (const FloatNDArray& a, const FloatNDArray& b)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return FloatNDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (FloatNDArray);
+
+  FloatNDArray result (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (a (i), b (i));
+    }
+
+  return result;
+}
+
+NDS_CMP_OPS(FloatNDArray, , float, )
+NDS_BOOL_OPS(FloatNDArray, float, static_cast<float> (0.0))
+
+SND_CMP_OPS(float, , FloatNDArray, )
+SND_BOOL_OPS(float, FloatNDArray, static_cast<float> (0.0))
+
+NDND_CMP_OPS(FloatNDArray, , FloatNDArray, )
+NDND_BOOL_OPS(FloatNDArray, FloatNDArray, static_cast<float> (0.0))
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fNDArray.h b/liboctave/fNDArray.h
new file mode 100644
index 0000000..bf6bd92
--- /dev/null
+++ b/liboctave/fNDArray.h
@@ -0,0 +1,190 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatNDArray_h)
+#define octave_FloatNDArray_h 1
+
+#include "MArrayN.h"
+#include "fMatrix.h"
+#include "intNDArray.h"
+
+#include "mx-defs.h"
+#include "mx-op-decl.h"
+
+class
+OCTAVE_API
+FloatNDArray : public MArrayN<float>
+{
+public:
+
+  FloatNDArray (void) : MArrayN<float> () { }
+
+  FloatNDArray (const dim_vector& dv) : MArrayN<float> (dv) { }
+
+  FloatNDArray (const dim_vector& dv, float val)
+    : MArrayN<float> (dv, val) { }
+  
+  FloatNDArray (const FloatNDArray& a) : MArrayN<float> (a) { }
+
+  FloatNDArray (const FloatMatrix& a) : MArrayN<float> (a) { }
+
+  template <class U>
+  FloatNDArray (const MArrayN<U>& a) : MArrayN<float> (a) { }
+
+  template <class U>
+  FloatNDArray (const ArrayN<U>& a) : MArrayN<float> (a) { }
+
+  template <class U>
+  explicit FloatNDArray (const intNDArray<U>& a) : MArrayN<float> (a) { }
+
+  FloatNDArray (const charNDArray&); 
+
+  FloatNDArray& operator = (const FloatNDArray& a)
+    {
+      MArrayN<float>::operator = (a);
+      return *this;
+    }
+
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
+  bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
+  bool any_element_is_inf_or_nan (void) const;
+  bool any_element_not_one_or_zero (void) const;
+  bool all_elements_are_zero (void) const;
+  bool all_elements_are_int_or_inf_or_nan (void) const;
+  bool all_integers (float& max_val, float& min_val) const;
+  bool too_large_for_float (void) const;
+
+  // FIXME -- this is not quite the right thing.
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+
+  FloatNDArray cumprod (int dim = -1) const;
+  FloatNDArray cumsum (int dim = -1) const;
+  FloatNDArray prod (int dim = -1) const;
+  FloatNDArray sum (int dim = -1) const;  
+  FloatNDArray sumsq (int dim = -1) const;
+  FloatNDArray concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx);
+  FloatComplexNDArray concat (const FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx);
+  charNDArray concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx);
+
+  FloatNDArray max (int dim = 0) const;
+  FloatNDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  FloatNDArray min (int dim = 0) const;
+  FloatNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  
+  FloatNDArray cummax (int dim = 0) const;
+  FloatNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  FloatNDArray cummin (int dim = 0) const;
+  FloatNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const;
+
+  FloatNDArray& insert (const FloatNDArray& a, octave_idx_type r, octave_idx_type c);
+  FloatNDArray& insert (const FloatNDArray& a, const Array<octave_idx_type>& ra_idx);
+
+  FloatNDArray abs (void) const;
+  boolNDArray isnan (void) const;
+  boolNDArray isinf (void) const;
+  boolNDArray isfinite (void) const;
+
+  FloatComplexNDArray fourier (int dim = 1) const;
+  FloatComplexNDArray ifourier (int dim = 1) const;
+
+  FloatComplexNDArray fourier2d (void) const;
+  FloatComplexNDArray ifourier2d (void) const;
+
+  FloatComplexNDArray fourierNd (void) const;
+  FloatComplexNDArray ifourierNd (void) const;
+
+  friend OCTAVE_API FloatNDArray real (const FloatComplexNDArray& a);
+  friend OCTAVE_API FloatNDArray imag (const FloatComplexNDArray& a);
+
+  friend class FloatComplexNDArray;
+
+  FloatMatrix matrix_value (void) const;
+
+  FloatNDArray squeeze (void) const { return MArrayN<float>::squeeze (); }
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatNDArray& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatNDArray& a);
+
+  static float resize_fill_value (void) { return 0; }
+
+  FloatNDArray diag (octave_idx_type k = 0) const;
+
+  typedef float (*dmapper) (float);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+  typedef bool (*bmapper) (float);
+
+  FloatNDArray map (dmapper fcn) const;
+  FloatComplexNDArray map (cmapper fcn) const;
+  boolNDArray map (bmapper fcn) const;
+
+private:
+
+  FloatNDArray (float *d, const dim_vector& dv) : MArrayN<float> (d, dv) { }
+};
+
+// Publish externally used friend functions.
+
+extern OCTAVE_API FloatNDArray real (const FloatComplexNDArray& a);
+extern OCTAVE_API FloatNDArray imag (const FloatComplexNDArray& a);
+
+extern OCTAVE_API FloatNDArray min (float d, const FloatNDArray& m);
+extern OCTAVE_API FloatNDArray min (const FloatNDArray& m, float d);
+extern OCTAVE_API FloatNDArray min (const FloatNDArray& a, const FloatNDArray& b);
+
+extern OCTAVE_API FloatNDArray max (float d, const FloatNDArray& m);
+extern OCTAVE_API FloatNDArray max (const FloatNDArray& m, float d);
+extern OCTAVE_API FloatNDArray max (const FloatNDArray& a, const FloatNDArray& b);
+
+NDS_CMP_OP_DECLS (FloatNDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, float, OCTAVE_API)
+
+SND_CMP_OP_DECLS (float, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, FloatNDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (FloatNDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, FloatNDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, FloatNDArray, float)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fRowVector.cc b/liboctave/fRowVector.cc
new file mode 100644
index 0000000..ef064b0
--- /dev/null
+++ b/liboctave/fRowVector.cc
@@ -0,0 +1,364 @@
+// RowVector manipulations.
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "functor.h"
+#include "lo-error.h"
+#include "mx-base.h"
+#include "mx-inlines.cc"
+#include "oct-cmplx.h"
+
+// Fortran functions we call.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgemv, SGEMV) (F77_CONST_CHAR_ARG_DECL,
+			   const octave_idx_type&, const octave_idx_type&, const float&,
+			   const float*, const octave_idx_type&, const float*,
+			   const octave_idx_type&, const float&, float*, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+  F77_RET_T
+  F77_FUNC (xsdot, XSDOT) (const octave_idx_type&, const float*, const octave_idx_type&,
+			   const float*, const octave_idx_type&, float&);
+}
+
+// Row Vector class.
+
+bool
+FloatRowVector::operator == (const FloatRowVector& a) const
+{
+  octave_idx_type len = length ();
+  if (len != a.length ())
+    return 0;
+  return mx_inline_equal (data (), a.data (), len);
+}
+
+bool
+FloatRowVector::operator != (const FloatRowVector& a) const
+{
+  return !(*this == a);
+}
+
+FloatRowVector&
+FloatRowVector::insert (const FloatRowVector& a, octave_idx_type c)
+{
+  octave_idx_type a_len = a.length ();
+
+  if (c < 0 || c + a_len > length ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  if (a_len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < a_len; i++)
+	xelem (c+i) = a.elem (i);
+    }
+
+  return *this;
+}
+
+FloatRowVector&
+FloatRowVector::fill (float val)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatRowVector&
+FloatRowVector::fill (float val, octave_idx_type c1, octave_idx_type c2)
+{
+  octave_idx_type len = length ();
+
+  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
+
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  if (c2 >= c1)
+    {
+      make_unique ();
+
+      for (octave_idx_type i = c1; i <= c2; i++)
+	xelem (i) = val;
+    }
+
+  return *this;
+}
+
+FloatRowVector
+FloatRowVector::append (const FloatRowVector& a) const
+{
+  octave_idx_type len = length ();
+  octave_idx_type nc_insert = len;
+  FloatRowVector retval (len + a.length ());
+  retval.insert (*this, 0);
+  retval.insert (a, nc_insert);
+  return retval;
+}
+
+FloatColumnVector
+FloatRowVector::transpose (void) const
+{
+  return MArray<float>::transpose();
+}
+
+FloatRowVector
+real (const FloatComplexRowVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  FloatRowVector retval;
+  if (a_len > 0)
+    retval = FloatRowVector (mx_inline_real_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+FloatRowVector
+imag (const FloatComplexRowVector& a)
+{
+  octave_idx_type a_len = a.length ();
+  FloatRowVector retval;
+  if (a_len > 0)
+    retval = FloatRowVector (mx_inline_imag_dup (a.data (), a_len), a_len);
+  return retval;
+}
+
+FloatRowVector
+FloatRowVector::extract (octave_idx_type c1, octave_idx_type c2) const
+{
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  FloatRowVector result (new_c);
+
+  for (octave_idx_type i = 0; i < new_c; i++)
+    result.xelem (i) = elem (c1+i);
+
+  return result;
+}
+
+FloatRowVector
+FloatRowVector::extract_n (octave_idx_type r1, octave_idx_type n) const
+{
+  FloatRowVector result (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    result.xelem (i) = elem (r1+i);
+
+  return result;
+}
+
+// row vector by matrix -> row vector
+
+FloatRowVector
+operator * (const FloatRowVector& v, const FloatMatrix& a)
+{
+  FloatRowVector retval;
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != len)
+    gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
+  else
+    {
+      if (len == 0)
+	retval.resize (a_nc, 0.0);
+      else
+	{
+	  // Transpose A to form A'*x == (x'*A)'
+
+	  octave_idx_type ld = a_nr;
+
+	  retval.resize (a_nc);
+	  float *y = retval.fortran_vec ();
+
+	  F77_XFCN (sgemv, SGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
+				   a_nr, a_nc, 1.0, a.data (),
+				   ld, v.data (), 1, 0.0, y, 1
+				   F77_CHAR_ARG_LEN (1)));
+	}
+    }
+
+  return retval;
+}
+
+// other operations
+
+FloatRowVector
+FloatRowVector::map (dmapper fcn) const
+{
+  return MArray<float>::map<float> (func_ptr (fcn));
+}
+
+FloatComplexRowVector
+FloatRowVector::map (cmapper fcn) const
+{
+  return MArray<float>::map<FloatComplex> (func_ptr (fcn));
+}
+
+float
+FloatRowVector::min (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0;
+
+  float res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) < res)
+      res = elem (i);
+
+  return res;
+}
+
+float
+FloatRowVector::max (void) const
+{
+  octave_idx_type len = length ();
+  if (len == 0)
+    return 0;
+
+  float res = elem (0);
+
+  for (octave_idx_type i = 1; i < len; i++)
+    if (elem (i) > res)
+      res = elem (i);
+
+  return res;
+}
+
+std::ostream&
+operator << (std::ostream& os, const FloatRowVector& a)
+{
+//  int field_width = os.precision () + 7;
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    os << " " /* setw (field_width) */ << a.elem (i);
+  return os;
+}
+
+std::istream&
+operator >> (std::istream& is, FloatRowVector& a)
+{
+  octave_idx_type len = a.length();
+
+  if (len > 0)
+    {
+      float tmp;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          is >> tmp;
+          if (is)
+            a.elem (i) = tmp;
+          else
+            break;
+        }
+    }
+  return is;
+}
+
+// other operations
+
+FloatRowVector
+linspace (float x1, float x2, octave_idx_type n)
+{
+  FloatRowVector retval;
+
+  if (n > 1)
+    {
+      retval.resize (n);
+      float delta = (x2 - x1) / (n - 1);
+      retval.elem (0) = x1;
+      for (octave_idx_type i = 1; i < n-1; i++)
+	retval.elem (i) = x1 + i * delta;
+      retval.elem (n-1) = x2;
+    }
+  else
+    {
+      retval.resize (1);
+      retval.elem (0) = x2;
+    }
+
+  return retval;
+}
+
+// row vector by column vector -> scalar
+
+float
+operator * (const FloatRowVector& v, const FloatColumnVector& a)
+{
+  float retval = 0.0;
+
+  octave_idx_type len = v.length ();
+
+  octave_idx_type a_len = a.length ();
+
+  if (len != a_len)
+    gripe_nonconformant ("operator *", len, a_len);
+  else if (len != 0)
+    F77_FUNC (xsdot, XSDOT) (len, v.data (), 1, a.data (), 1, retval);
+
+  return retval;
+}
+
+FloatComplex
+operator * (const FloatRowVector& v, const FloatComplexColumnVector& a)
+{
+  FloatComplexRowVector tmp (v);
+  return tmp * a;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/fRowVector.h b/liboctave/fRowVector.h
new file mode 100644
index 0000000..b218ac0
--- /dev/null
+++ b/liboctave/fRowVector.h
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatRowVector_h)
+#define octave_FloatRowVector_h 1
+
+#include "MArray.h"
+
+#include "mx-defs.h"
+
+class
+OCTAVE_API
+FloatRowVector : public MArray<float>
+{
+public:
+
+  FloatRowVector (void) : MArray<float> () { }
+
+  explicit FloatRowVector (octave_idx_type n) : MArray<float> (n) { }
+
+  FloatRowVector (octave_idx_type n, float val) : MArray<float> (n, val) { }
+
+  FloatRowVector (const FloatRowVector& a) : MArray<float> (a) { }
+
+  FloatRowVector (const MArray<float>& a) : MArray<float> (a) { }
+
+  FloatRowVector& operator = (const FloatRowVector& a)
+    {
+      MArray<float>::operator = (a);
+      return *this;
+    }
+
+  bool operator == (const FloatRowVector& a) const;
+  bool operator != (const FloatRowVector& a) const;
+
+  // destructive insert/delete/reorder operations
+
+  FloatRowVector& insert (const FloatRowVector& a, octave_idx_type c);
+
+  FloatRowVector& fill (float val);
+  FloatRowVector& fill (float val, octave_idx_type c1, octave_idx_type c2);
+
+  FloatRowVector append (const FloatRowVector& a) const;
+
+  FloatColumnVector transpose (void) const;
+
+  friend OCTAVE_API FloatRowVector real (const FloatComplexRowVector& a);
+  friend OCTAVE_API FloatRowVector imag (const FloatComplexRowVector& a);
+
+  // resize is the destructive equivalent for this one
+
+  FloatRowVector extract (octave_idx_type c1, octave_idx_type c2) const;
+
+  FloatRowVector extract_n (octave_idx_type c1, octave_idx_type n) const;
+
+  // row vector by matrix -> row vector
+
+  friend OCTAVE_API FloatRowVector operator * (const FloatRowVector& a, const FloatMatrix& b);
+
+  // other operations
+
+  typedef float (*dmapper) (float);
+  typedef FloatComplex (*cmapper) (const FloatComplex&);
+
+  FloatRowVector map (dmapper fcn) const;
+  FloatComplexRowVector map (cmapper fcn) const;
+
+  float min (void) const;
+  float max (void) const;
+
+  // i/o
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatRowVector& a);
+  friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatRowVector& a);
+
+private:
+
+  FloatRowVector (float *d, octave_idx_type l) : MArray<float> (d, l) { }
+};
+
+// row vector by column vector -> scalar
+
+float OCTAVE_API operator * (const FloatRowVector& a, const FloatColumnVector& b);
+
+Complex OCTAVE_API operator * (const FloatRowVector& a, const ComplexColumnVector& b);
+
+// other operations
+
+OCTAVE_API FloatRowVector linspace (float x1, float x2, octave_idx_type n);
+
+MARRAY_FORWARD_DEFS (MArray, FloatRowVector, float)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/file-ops.cc b/liboctave/file-ops.cc
new file mode 100644
index 0000000..9f5ae71
--- /dev/null
+++ b/liboctave/file-ops.cc
@@ -0,0 +1,886 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <iostream>
+#include <vector>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "dir-ops.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+#include "oct-passwd.h"
+#include "pathlen.h"
+#include "quit.h"
+#include "statdefs.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+file_ops::static_members *file_ops::static_members::instance = 0;
+
+file_ops::static_members::static_members (void)
+  :
+#if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
+  xdir_sep_char ('\\'),
+  xdir_sep_str ("\\"),
+#else
+  xdir_sep_char ('/'),
+  xdir_sep_str ("/"), 
+#endif
+#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
+  xdir_sep_chars ("/\\")
+#else
+  xdir_sep_chars (xdir_sep_str)
+#endif
+{ }
+
+bool
+file_ops::static_members::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new static_members ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create file_ops::static_members object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+#define NOT_SUPPORTED(nm) \
+  nm ": not supported on this system"
+
+// We provide a replacement for mkdir().
+
+int
+file_ops::mkdir (const std::string& name, mode_t mode)
+{
+  std::string msg;
+  return mkdir (name, mode, msg);
+}
+
+int
+file_ops::mkdir (const std::string& name, mode_t mode, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_MKDIR)
+
+#if defined (MKDIR_TAKES_ONE_ARG)
+  status = ::mkdir (name.c_str ());
+#else
+  status = ::mkdir (name.c_str (), mode);
+#endif
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("mkdir");
+#endif
+
+  return status;
+}
+
+// I don't know how to emulate this on systems that don't provide it.
+
+int
+file_ops::mkfifo (const std::string& name, mode_t mode)
+{
+  std::string msg;
+  return mkfifo (name, mode, msg);
+}
+
+int
+file_ops::mkfifo (const std::string& name, mode_t mode, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_MKFIFO)
+  status = ::mkfifo (name.c_str (), mode);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("mkfifo");
+#endif
+
+  return status;
+}
+
+// I don't know how to emulate this on systems that don't provide it.
+
+int
+file_ops::link (const std::string& old_name, const std::string& new_name)
+{
+  std::string msg;
+  return link (old_name, new_name, msg);
+}
+
+int
+file_ops::link (const std::string& old_name,
+		const std::string& new_name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_LINK)
+  status = ::link (old_name.c_str (), new_name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("link");
+#endif
+
+  return status;
+}
+
+// I don't know how to emulate this on systems that don't provide it.
+
+int
+file_ops::symlink (const std::string& old_name, const std::string& new_name)
+{
+  std::string msg;
+  return symlink (old_name, new_name, msg);
+}
+
+int
+file_ops::symlink (const std::string& old_name,
+		   const std::string& new_name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_SYMLINK)
+
+  status = ::symlink (old_name.c_str (), new_name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("symlink");
+#endif
+
+  return status;
+}
+
+// We provide a replacement for rename().
+
+int
+file_ops::readlink (const std::string& path, std::string& result)
+{
+  std::string msg;
+  return readlink (path, result, msg);
+}
+
+int
+file_ops::readlink (const std::string& path, std::string& result,
+		    std::string& msg)
+{
+  int status = -1;
+
+  msg = std::string ();
+
+#if defined (HAVE_READLINK)
+  char buf[MAXPATHLEN+1];
+
+  status = ::readlink (path.c_str (), buf, MAXPATHLEN);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+  else
+    {
+      buf[status] = '\0';
+      result = std::string (buf);
+      status = 0;
+    }
+#else
+  msg = NOT_SUPPORTED ("rename");
+#endif
+
+  return status;
+}
+
+// We provide a replacement for rename().
+
+int
+file_ops::rename (const std::string& from, const std::string& to)
+{
+  std::string msg;
+  return rename (from, to, msg);
+}
+
+int
+file_ops::rename (const std::string& from, const std::string& to,
+		  std::string& msg)
+{
+  int status = -1;
+
+  msg = std::string ();
+
+#if defined (HAVE_RENAME)
+  status = ::rename (from.c_str (), to.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("rename");
+#endif
+
+  return status;
+}
+
+// We provide a replacement for rmdir().
+
+int
+file_ops::rmdir (const std::string& name)
+{
+  std::string msg;
+  return rmdir (name, msg);
+}
+
+int
+file_ops::rmdir (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_RMDIR)
+  status = ::rmdir (name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("rmdir");
+#endif
+
+  return status;
+}
+
+// And a version that works recursively.
+
+int
+file_ops::recursive_rmdir (const std::string& name)
+{
+  std::string msg;
+  return recursive_rmdir (name, msg);
+}
+
+int
+file_ops::recursive_rmdir (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = 0;
+
+  dir_entry dir (name);
+
+  if (dir)
+    {
+      string_vector dirlist = dir.read ();
+
+      for (octave_idx_type i = 0; i < dirlist.length (); i++)
+	{
+	  OCTAVE_QUIT;
+
+	  std::string nm = dirlist[i];
+
+	  // Skip current directory and parent.
+	  if (nm == "." || nm == "..")
+	    continue;
+
+	  std::string fullnm = name + file_ops::dir_sep_str () + nm;
+
+	  // Get info about the file.  Don't follow links.
+	  file_stat fs (fullnm, false);
+
+	  if (fs)
+	    {
+	      if (fs.is_dir ())
+		{
+		  status = recursive_rmdir (fullnm, msg);
+
+		  if (status < 0)
+		    break;
+		}
+	      else
+		{
+		  status = unlink (fullnm, msg);
+
+		  if (status < 0)
+		    break;
+		}
+	    }
+	  else
+	    {
+	      msg = fs.error ();
+	      break;
+	    }
+	}
+
+      if (status >= 0)
+	{
+	  dir.close ();
+	  status = file_ops::rmdir (name, msg);
+	}
+    }
+  else
+    {
+      status = -1;
+
+      msg = dir.error ();
+    }
+
+  return status;
+}
+
+std::string
+file_ops::canonicalize_file_name (const std::string& name)
+{
+  std::string msg;
+  return canonicalize_file_name (name, msg);
+}
+
+std::string
+file_ops::canonicalize_file_name (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  std::string retval;
+
+#if defined (HAVE_CANONICALIZE_FILE_NAME)
+
+  char *tmp = ::canonicalize_file_name (name.c_str ());
+
+  if (tmp)
+    {
+      retval = tmp;
+      ::free (tmp);
+    }
+
+#elif defined (HAVE_RESOLVEPATH)
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#if !defined (__set_errno)
+# define __set_errno(Val) errno = (Val)
+#endif
+
+  if (name.empty ())
+    {
+      __set_errno (ENOENT);
+      return retval;
+    }
+
+  // All known hosts with resolvepath (e.g. Solaris 7) don't turn
+  // relative names into absolute ones, so prepend the working
+  // directory if the path is not absolute.
+
+  std::string absolute_name
+    = octave_env::make_absolute (name, octave_env::getcwd ());
+
+  size_t resolved_size = absolute_name.length ();
+
+  while (true)
+    {
+      resolved_size = 2 * resolved_size + 1;
+
+      OCTAVE_LOCAL_BUFFER (char, resolved, resolved_size);
+
+      int resolved_len
+	= ::resolvepath (absolute_name.c_str (), resolved, resolved_size);
+
+      if (resolved_len < 0)
+	break;
+
+      if (resolved_len < resolved_size)
+	{
+	  retval = resolved;
+	  break;
+	}
+    }
+
+#elif defined (__WIN32__)
+
+  int n = 1024;
+
+  std::string win_path (n, '\0');
+
+  while (true)
+    {
+      int status = GetFullPathName (name.c_str (), n, &win_path[0], 0);
+
+      if (status == 0)
+        break;
+      else if (status < n)
+        {
+          win_path.resize (status);
+	  retval = win_path;
+	  break;
+        }
+      else
+        {
+          n *= 2;
+	  win_path.resize (n);
+        }
+    }
+
+#elif defined (HAVE_REALPATH)
+
+#if !defined (__set_errno)
+# define __set_errno(Val) errno = (Val)
+#endif
+
+  if (name.empty ())
+    {
+      __set_errno (ENOENT);
+      return retval;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, buf, PATH_MAX);
+
+  if (::realpath (name.c_str (), buf))
+    retval = buf;
+
+#else
+
+  // FIXME -- provide replacement here...
+  retval = name;
+
+#endif
+
+  if (retval.empty ())
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+
+  return retval;
+}
+
+// We provide a replacement for tempnam().
+
+std::string
+file_ops::tempnam (const std::string& dir, const std::string& pfx)
+{
+  std::string msg;
+  return tempnam (dir, pfx, msg);
+}
+
+std::string
+file_ops::tempnam (const std::string& dir, const std::string& pfx,
+		   std::string& msg)
+{
+  msg = std::string ();
+
+  std::string retval;
+  
+  const char *pdir = dir.empty () ? 0 : dir.c_str ();
+
+  const char *ppfx = pfx.empty () ? 0 : pfx.c_str ();
+
+  char *tmp = ::tempnam (pdir, ppfx);
+
+  if (tmp)
+    {
+      retval = tmp;
+
+      ::free (tmp);
+    }
+  else
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+
+  return retval;
+}
+
+// The following tilde-expansion code was stolen and adapted from
+// readline.
+
+// The default value of tilde_additional_prefixes.  This is set to
+// whitespace preceding a tilde so that simple programs which do not
+// perform any word separation get desired behaviour.
+static const char *default_prefixes[] = { " ~", "\t~", ":~", 0 };
+
+// The default value of tilde_additional_suffixes.  This is set to
+// whitespace or newline so that simple programs which do not perform
+// any word separation get desired behaviour.
+static const char *default_suffixes[] = { " ", "\n", ":", 0 };
+
+// If non-null, this contains the address of a function that the
+// application wants called before trying the standard tilde
+// expansions.  The function is called with the text sans tilde, and
+// returns a malloc()'ed string which is the expansion, or a NULL
+// pointer if the expansion fails.
+file_ops::tilde_expansion_hook file_ops::tilde_expansion_preexpansion_hook = 0;
+
+// If non-null, this contains the address of a function to call if the
+// standard meaning for expanding a tilde fails.  The function is
+// called with the text (sans tilde, as in "foo"), and returns a
+// malloc()'ed string which is the expansion, or a NULL pointer if
+// there is no expansion.
+file_ops::tilde_expansion_hook file_ops::tilde_expansion_failure_hook = 0;
+
+// When non-null, this is a NULL terminated array of strings which are
+// duplicates for a tilde prefix.  Bash uses this to expand `=~' and
+// `:~'.
+string_vector file_ops::tilde_additional_prefixes = default_prefixes;
+
+// When non-null, this is a NULL terminated array of strings which
+// match the end of a username, instead of just "/".  Bash sets this
+// to `:' and `=~'.
+string_vector file_ops::tilde_additional_suffixes = default_suffixes;
+
+// Find the start of a tilde expansion in S, and return the index
+// of the tilde which starts the expansion.  Place the length of the
+// text which identified this tilde starter in LEN, excluding the
+// tilde itself.
+
+static size_t
+tilde_find_prefix (const std::string& s, size_t& len)
+{
+  len = 0;
+
+  size_t s_len = s.length ();
+
+  if (s_len == 0 || s[0] == '~')
+    return 0;
+
+  string_vector prefixes = file_ops::tilde_additional_prefixes;
+
+  if (! prefixes.empty ())
+    {
+      for (size_t i = 0; i < s_len; i++)
+	{
+	  for (int j = 0; j < prefixes.length (); j++)
+	    {
+	      size_t pfx_len = prefixes[j].length ();
+
+	      if (prefixes[j].compare (s.substr (i, pfx_len)) == 0)
+		{
+		  len = pfx_len - 1;
+		  return i + len;
+		}
+	    }
+	}
+    }
+
+  return s_len;
+}
+
+// Find the end of a tilde expansion in S, and return the index
+// of the character which ends the tilde definition.
+
+static size_t
+tilde_find_suffix (const std::string& s)
+{
+  size_t s_len = s.length ();
+
+  string_vector suffixes = file_ops::tilde_additional_suffixes;
+
+  size_t i = 0;
+
+  for ( ; i < s_len; i++)
+    {
+      if (file_ops::is_dir_sep (s[i]))
+	break;
+
+      if (! suffixes.empty ())
+	{
+	  for (int j = 0; j < suffixes.length (); j++)
+	    {
+	      size_t sfx_len = suffixes[j].length ();
+
+	      if (suffixes[j].compare (s.substr (i, sfx_len)) == 0)
+		return i;
+	    }
+	}
+    }
+
+  return i;
+}
+
+// Take FNAME and return the tilde prefix we want expanded.
+
+static std::string
+isolate_tilde_prefix (const std::string& fname)
+{
+  size_t f_len = fname.length ();
+
+  size_t len = 1;
+
+  while (len < f_len && ! file_ops::is_dir_sep (fname[len]))
+    len++;
+
+  return fname.substr (1, len);
+}
+
+// Do the work of tilde expansion on FILENAME.  FILENAME starts with a
+// tilde.
+
+static std::string
+tilde_expand_word (const std::string& filename)
+{
+  size_t f_len = filename.length ();
+
+  if (f_len == 0 || filename[0] != '~')
+    return filename;
+
+  // A leading `~/' or a bare `~' is *always* translated to the value
+  // of $HOME or the home directory of the current user, regardless of
+  // any preexpansion hook.
+
+  if (f_len == 1 || file_ops::is_dir_sep (filename[1]))
+    return octave_env::get_home_directory () + filename.substr (1);
+
+  std::string username = isolate_tilde_prefix (filename);
+
+  size_t user_len = username.length ();
+
+  std::string dirname;
+
+  if (file_ops::tilde_expansion_preexpansion_hook)
+    {
+      std::string expansion
+	= file_ops::tilde_expansion_preexpansion_hook (username);
+
+      if (! expansion.empty ())
+	return expansion + filename.substr (user_len+1);
+    }
+
+  // No preexpansion hook, or the preexpansion hook failed.  Look in the
+  // password database.
+
+  octave_passwd pw = octave_passwd::getpwnam (username);
+
+  if (! pw)
+    {
+      // If the calling program has a special syntax for expanding tildes,
+      // and we couldn't find a standard expansion, then let them try.
+
+      if (file_ops::tilde_expansion_failure_hook)
+	{
+	  std::string expansion
+	    = file_ops::tilde_expansion_failure_hook (username);
+
+	  if (! expansion.empty ())
+	    dirname = expansion + filename.substr (user_len+1);
+	}
+
+      // If we don't have a failure hook, or if the failure hook did not
+      // expand the tilde, return a copy of what we were passed.
+
+      if (dirname.length () == 0)
+	dirname = filename;
+    }
+  else
+    dirname = pw.dir () + filename.substr (user_len+1);
+
+  return dirname;
+}
+
+// If NAME has a leading ~ or ~user, Unix-style, expand it to the
+// user's home directory.  If no ~, or no <pwd.h>, just return NAME.
+
+std::string
+file_ops::tilde_expand (const std::string& name)
+{
+  if (name.find ('~') == std::string::npos)
+    return name;
+  else
+    {
+      std::string result;
+
+      size_t name_len = name.length ();
+
+      // Scan through S expanding tildes as we come to them.
+
+      size_t pos = 0;
+
+      while (1)
+	{
+	  if (pos > name_len)
+	    break;
+
+	  size_t len;
+
+	  // Make START point to the tilde which starts the expansion.
+
+	  size_t start = tilde_find_prefix (name.substr (pos), len);
+
+	  result.append (name.substr (pos, start));
+
+	  // Advance STRING to the starting tilde.
+
+	  pos += start;
+
+	  // Make FINI be the index of one after the last character of the
+	  // username.
+
+	  size_t fini = tilde_find_suffix (name.substr (pos));
+
+	  // If both START and FINI are zero, we are all done.
+
+	  if (! (start || fini))
+	    break;
+
+	  // Expand the entire tilde word, and copy it into RESULT.
+
+	  std::string tilde_word = name.substr (pos, fini);
+
+	  pos += fini;
+
+	  std::string expansion = tilde_expand_word (tilde_word);
+
+	  result.append (expansion);
+	}
+
+      return result;
+    }
+}
+
+// A vector version of the above.
+
+string_vector
+file_ops::tilde_expand (const string_vector& names)
+{
+  string_vector retval;
+
+  int n = names.length ();
+
+  retval.resize (n);
+
+  for (int i = 0; i < n; i++)
+    retval[i] = file_ops::tilde_expand (names[i]);
+
+  return retval;
+}
+
+int
+file_ops::umask (mode_t mode)
+{
+#if defined (HAVE_UMASK)
+  return ::umask (mode);
+#else
+  return 0;
+#endif
+}
+
+int
+file_ops::unlink (const std::string& name)
+{
+  std::string msg;
+  return unlink (name, msg);
+}
+
+int
+file_ops::unlink (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_UNLINK)
+  status = ::unlink (name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("unlink");
+#endif
+
+  return status;
+}
+
+std::string
+file_ops::concat (const std::string& dir, const std::string& file)
+{
+  return dir.empty ()
+    ? file
+    : (is_dir_sep (dir[dir.length()-1])
+       ? dir + file
+       : dir + file_ops::dir_sep_char () + file);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/file-ops.h b/liboctave/file-ops.h
new file mode 100644
index 0000000..05c1400
--- /dev/null
+++ b/liboctave/file-ops.h
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_file_ops_h)
+#define octave_file_ops_h 1
+
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "str-vec.h"
+
+struct
+OCTAVE_API
+file_ops
+{
+public:
+
+  static int mkdir (const std::string&, mode_t);
+  static int mkdir (const std::string&, mode_t, std::string&);
+
+  static int mkfifo (const std::string&, mode_t);
+  static int mkfifo (const std::string&, mode_t, std::string&);
+
+  static int link (const std::string&, const std::string&);
+  static int link (const std::string&, const std::string&, std::string&);
+
+  static int symlink (const std::string&, const std::string&);
+  static int symlink (const std::string&, const std::string&, std::string&);
+
+  static int readlink (const std::string&, std::string&);
+  static int readlink (const std::string&, std::string&, std::string&);
+
+  static int rename (const std::string&, const std::string&);
+  static int rename (const std::string&, const std::string&, std::string&);
+
+  static int rmdir (const std::string&);
+  static int rmdir (const std::string&, std::string&);
+
+  static int recursive_rmdir (const std::string&);
+  static int recursive_rmdir (const std::string&, std::string&);
+
+  static std::string canonicalize_file_name (const std::string&);
+  static std::string canonicalize_file_name (const std::string&, std::string&);
+
+  static std::string tempnam (const std::string&, const std::string&);
+  static std::string tempnam (const std::string&, const std::string&,
+			      std::string&);
+
+  typedef std::string (*tilde_expansion_hook) (const std::string&);
+
+  static tilde_expansion_hook tilde_expansion_preexpansion_hook;
+
+  static tilde_expansion_hook tilde_expansion_failure_hook;
+
+  static string_vector tilde_additional_prefixes;
+
+  static string_vector tilde_additional_suffixes;
+
+  static std::string tilde_expand (const std::string&);
+  static string_vector tilde_expand (const string_vector&);
+
+  static int umask (mode_t);
+
+  static int unlink (const std::string&);
+  static int unlink (const std::string&, std::string&);
+
+  static bool is_dir_sep (char c)
+  {
+    std::string tmp = dir_sep_chars ();
+    return tmp.find (c) != std::string::npos;
+  }
+
+  static std::string concat (const std::string&, const std::string&);
+
+  static char dir_sep_char (void)
+  {
+    return static_members::dir_sep_char ();
+  }
+
+  static std::string dir_sep_str (void)
+  {
+    return static_members::dir_sep_str ();
+  }
+
+  static std::string dir_sep_chars (void)
+  {
+    return static_members::dir_sep_chars ();
+  }
+
+  // Return the tail member of a path.
+  static std::string tail (std::string path)
+  {
+    size_t ipos = path.find_last_of (dir_sep_chars ());
+
+    if (ipos != std::string::npos)
+      ipos++;
+    else
+      ipos = 0;
+
+    return path.substr (ipos);
+  }
+
+private:
+
+  // Use a singleton class for these data members instead of just
+  // making them static members of the dir_path class so that we can
+  // ensure proper initialization.
+
+  class static_members
+  {
+  public:
+
+    static_members (void);
+
+    static char dir_sep_char (void)
+    {
+      return instance_ok () ? instance->xdir_sep_char : 0;
+    }
+
+    static std::string dir_sep_str (void)
+    {
+      return instance_ok () ? instance->xdir_sep_str : std::string ();
+    }
+
+    static std::string dir_sep_chars (void)
+    {
+      return instance_ok () ? instance->xdir_sep_chars : std::string ();
+    }
+
+  private:
+
+    // The real thing.
+    static static_members *instance;
+
+    // No copying!
+
+    static_members (const static_members&);
+
+    static_members& operator = (const static_members&);
+
+    static bool instance_ok (void);
+
+    char xdir_sep_char;
+    std::string xdir_sep_str;
+    std::string xdir_sep_chars;
+  };
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/file-stat.cc b/liboctave/file-stat.cc
new file mode 100644
index 0000000..999853d
--- /dev/null
+++ b/liboctave/file-stat.cc
@@ -0,0 +1,316 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstring>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "file-ops.h"
+#include "file-stat.h"
+#include "statdefs.h"
+
+#if !defined (HAVE_LSTAT)
+static inline int
+lstat (const char *name, struct stat *buf)
+{
+  return stat (name, buf);
+}
+#endif
+
+// FIXME -- the is_* and mode_as_string functions are only valid
+// for initialized objects.  If called for an object that is not
+// initialized, they should throw an exception.
+
+bool
+base_file_stat::is_blk (void) const
+{
+  return exists () && is_blk (fs_mode);
+}
+
+bool
+base_file_stat::is_chr (void) const
+{
+  return exists () && is_chr (fs_mode);
+}
+
+bool
+base_file_stat::is_dir (void) const
+{ 
+  return exists () && is_dir (fs_mode);
+}
+
+bool
+base_file_stat::is_fifo (void) const
+{ 
+  return exists () && is_fifo (fs_mode);
+}
+
+bool
+base_file_stat::is_lnk (void) const
+{ 
+  return exists () && is_lnk (fs_mode);
+}
+
+bool
+base_file_stat::is_reg (void) const
+{ 
+  return exists () && is_reg (fs_mode);
+}
+
+bool
+base_file_stat::is_sock (void) const
+{ 
+  return exists () && is_sock (fs_mode);
+}
+
+bool
+base_file_stat::is_blk (mode_t mode)
+{
+#ifdef S_ISBLK
+  return S_ISBLK (mode);
+#else
+  return false;
+#endif
+}
+
+bool
+base_file_stat::is_chr (mode_t mode)
+{
+#ifdef S_ISCHR
+  return S_ISCHR (mode);
+#else
+  return false;
+#endif
+}
+
+bool
+base_file_stat::is_dir (mode_t mode)
+{ 
+#ifdef S_ISDIR
+  return S_ISDIR (mode);
+#else
+  return false;
+#endif
+}
+
+bool
+base_file_stat::is_fifo (mode_t mode)
+{ 
+#ifdef S_ISFIFO
+  return S_ISFIFO (mode);
+#else
+  return false;
+#endif
+}
+
+bool
+base_file_stat::is_lnk (mode_t mode)
+{ 
+#ifdef S_ISLNK
+  return S_ISLNK (mode);
+#else
+  return false;
+#endif
+}
+
+bool
+base_file_stat::is_reg (mode_t mode)
+{ 
+#ifdef S_ISREG
+  return S_ISREG (mode);
+#else
+  return false;
+#endif
+}
+
+bool
+base_file_stat::is_sock (mode_t mode)
+{ 
+#ifdef S_ISSOCK
+  return S_ISSOCK (mode);
+#else
+  return false;
+#endif
+}
+
+extern "C" void mode_string (unsigned short, char *);
+
+std::string
+base_file_stat::mode_as_string (void) const
+{
+  char buf[11];
+
+  mode_string (fs_mode, buf);
+
+  buf[10] = '\0';
+
+  return std::string (buf);
+}
+
+// Has FILE been modified since TIME?  Returns 1 for yes, 0 for no,
+// and -1 for any error.
+
+int
+base_file_stat::is_newer (const std::string& file, const octave_time& time)
+{
+  file_stat fs (file);
+
+  return fs ? fs.is_newer (time) : -1;
+}
+
+// Private stuff:
+
+void
+file_stat::update_internal (bool force)
+{
+  if (! initialized || force)
+    {
+      initialized = false;
+      fail = false;
+      
+      std::string full_file_name = file_ops::tilde_expand (file_name);
+
+#if defined (__WIN32__)
+      // Remove trailing slash.
+      if (file_ops::is_dir_sep (full_file_name[full_file_name.length () - 1])
+	  && full_file_name.length () != 1
+          && ! (full_file_name.length() == 3 && full_file_name[1] == ':'))
+        full_file_name.resize (full_file_name.length () - 1);
+#endif
+
+      const char *cname = full_file_name.c_str ();
+
+      struct stat buf;
+
+      int status = follow_links ? stat (cname, &buf) : lstat (cname, &buf);
+
+      if (status < 0)
+	{
+	  using namespace std;
+
+	  fail = true;
+	  errmsg = strerror (errno);
+	}
+      else
+	{
+	  fs_mode = buf.st_mode;
+	  fs_ino = buf.st_ino;
+	  fs_dev = buf.st_dev;
+	  fs_nlink = buf.st_nlink;
+	  fs_uid = buf.st_uid;
+	  fs_gid = buf.st_gid;
+	  fs_size = buf.st_size;
+	  fs_atime = buf.st_atime;
+	  fs_mtime = buf.st_mtime;
+	  fs_ctime = buf.st_ctime;
+
+#if defined (HAVE_STRUCT_STAT_ST_RDEV)
+	  fs_rdev = buf.st_rdev;
+#endif
+
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+	  fs_blksize = buf.st_blksize;
+#endif
+
+#if defined (HAVE_STRUCT_STAT_ST_BLOCKS)
+	  fs_blocks = buf.st_blocks;
+#endif
+	}
+
+      initialized = true;
+    }
+}
+
+void
+file_fstat::update_internal (bool force)
+{
+  if (! initialized || force)
+    {
+      initialized = false;
+      fail = false;
+
+#if defined (HAVE_FSTAT)
+
+      struct stat buf;
+
+      int status = fstat (fid, &buf);
+
+      if (status < 0)
+	{
+	  using namespace std;
+
+	  fail = true;
+	  errmsg = strerror (errno);
+	}
+      else
+	{
+	  fs_mode = buf.st_mode;
+	  fs_ino = buf.st_ino;
+	  fs_dev = buf.st_dev;
+	  fs_nlink = buf.st_nlink;
+	  fs_uid = buf.st_uid;
+	  fs_gid = buf.st_gid;
+	  fs_size = buf.st_size;
+	  fs_atime = buf.st_atime;
+	  fs_mtime = buf.st_mtime;
+	  fs_ctime = buf.st_ctime;
+
+#if defined (HAVE_STRUCT_STAT_ST_RDEV)
+	  fs_rdev = buf.st_rdev;
+#endif
+
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+	  fs_blksize = buf.st_blksize;
+#endif
+
+#if defined (HAVE_STRUCT_STAT_ST_BLOCKS)
+	  fs_blocks = buf.st_blocks;
+#endif
+	}
+
+#else
+
+      fail = true;
+      errmsg = "fstat not available on this system";
+
+#endif
+
+      initialized = true;
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/file-stat.h b/liboctave/file-stat.h
new file mode 100644
index 0000000..431aa26
--- /dev/null
+++ b/liboctave/file-stat.h
@@ -0,0 +1,314 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_file_stat_h)
+#define octave_file_stat_h 1
+
+#include <string>
+
+#include "oct-time.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+class
+OCTAVE_API
+base_file_stat
+{
+public:
+
+  base_file_stat (void)
+    : initialized (false), fail (false), errmsg (), fs_mode (),
+      fs_ino (), fs_dev (), fs_nlink (), fs_uid (), fs_gid (),
+      fs_size (), fs_atime (), fs_mtime (), fs_ctime (), fs_rdev (),
+      fs_blksize (), fs_blocks () { }
+
+  base_file_stat (const base_file_stat& fs)
+    : initialized (fs.initialized), fail (fs.fail), errmsg (fs.errmsg),
+      fs_mode (fs.fs_mode), fs_ino (fs.fs_ino), fs_dev (fs.fs_dev),
+      fs_nlink (fs.fs_nlink), fs_uid (fs.fs_uid), fs_gid (fs.fs_gid),
+      fs_size (fs.fs_size), fs_atime (fs.fs_atime), fs_mtime (fs.fs_mtime),
+      fs_ctime (fs.fs_ctime), fs_rdev (fs.fs_rdev),
+      fs_blksize (fs.fs_blksize), fs_blocks (fs.fs_blocks) { }
+
+  base_file_stat& operator = (const base_file_stat& fs)
+  {
+    if (this != &fs)
+      {
+	initialized = fs.initialized;
+	fail = fs.fail;
+	errmsg = fs.errmsg;
+	fs_mode = fs.fs_mode;
+	fs_ino = fs.fs_ino;
+	fs_dev = fs.fs_dev;
+	fs_nlink = fs.fs_nlink;
+	fs_uid = fs.fs_uid;
+	fs_gid = fs.fs_gid;
+	fs_size = fs.fs_size;
+	fs_atime = fs.fs_atime;
+	fs_mtime = fs.fs_mtime;
+	fs_ctime = fs.fs_ctime;
+	fs_rdev = fs.fs_rdev;
+	fs_blksize = fs.fs_blksize;
+	fs_blocks = fs.fs_blocks;
+      }
+
+    return *this;
+  }
+
+  ~base_file_stat (void) { }
+
+  // File status and info.  The is_XXX functions will return false for
+  // file_stat objects that are not properly initialized.  The others
+  // should all return 0 (or the equivalent, for the given object)
+  // which is likely not meaningful.
+
+  bool is_blk (void) const;
+  bool is_chr (void) const;
+  bool is_dir (void) const;
+  bool is_fifo (void) const;
+  bool is_lnk (void) const;
+  bool is_reg (void) const;
+  bool is_sock (void) const;
+
+  static bool is_blk (mode_t mode);
+  static bool is_chr (mode_t mode);
+  static bool is_dir (mode_t mode);
+  static bool is_fifo (mode_t mode);
+  static bool is_lnk (mode_t mode);
+  static bool is_reg (mode_t mode);
+  static bool is_sock (mode_t mode);
+
+  ino_t ino (void) const { return fs_ino; }
+  dev_t dev (void) const { return fs_dev; }
+
+  nlink_t nlink (void) const { return fs_nlink; }
+
+  uid_t uid (void) const { return fs_uid; }
+  gid_t gid (void) const { return fs_gid; }
+
+  off_t size (void) const { return fs_size; }
+
+  octave_time atime (void) const { return fs_atime; }
+  octave_time mtime (void) const { return fs_mtime; }
+  octave_time ctime (void) const { return fs_ctime; }
+
+  dev_t rdev (void) const { return fs_rdev; }
+
+  long blksize (void) const { return fs_blksize; }
+  long blocks (void) const { return fs_blocks; }
+
+  mode_t mode (void) const { return fs_mode; }
+
+  std::string mode_as_string (void) const;
+
+  bool ok (void) const { return initialized && ! fail; }
+
+  operator bool () const { return ok (); }
+
+  bool exists (void) const { return ok (); }
+
+  std::string error (void) const { return ok () ? std::string () : errmsg; }
+
+  // Has the file referenced by this object been modified since TIME?
+  bool is_newer (const octave_time& time) const { return fs_mtime > time; }
+
+  // It's nice to be able to hide the file_stat object if we don't
+  // really care about it.
+  static int is_newer (const std::string&, const octave_time&);
+
+protected:
+
+  // TRUE means we have already called stat.
+  bool initialized;
+
+  // TRUE means the stat for this file failed.
+  bool fail;
+
+  // If a failure occurs, this contains the system error text.
+  std::string errmsg;
+
+  // file type and permissions
+  mode_t fs_mode;
+
+  // serial number
+  ino_t fs_ino;
+
+  // device number
+  dev_t fs_dev;
+
+  // number of links
+  nlink_t fs_nlink;
+
+  // user ID of owner
+  uid_t fs_uid;
+
+  // group ID of owner
+  gid_t fs_gid;
+
+  // size in bytes, for regular files
+  off_t fs_size;
+
+  // time of last access
+  octave_time fs_atime;
+
+  // time of last modification
+  octave_time fs_mtime;
+
+  // time of last file status change
+  octave_time fs_ctime;
+
+  // device number for special files
+  dev_t fs_rdev;
+
+  // best I/O block size
+  long fs_blksize;
+
+  // number of 512-byte blocks allocated
+  long fs_blocks;
+};
+
+class
+OCTAVE_API
+file_stat : public base_file_stat
+{
+public:
+
+  file_stat (const std::string& n = std::string (), bool fl = true)
+    : base_file_stat (), file_name (n), follow_links (fl)
+  {
+    if (! file_name.empty ())
+      update_internal ();
+  }
+
+  file_stat (const file_stat& fs)
+    : base_file_stat (fs), file_name (fs.file_name),
+      follow_links (fs.follow_links) { }
+
+  file_stat& operator = (const file_stat& fs)
+  {
+    if (this != &fs)
+      {
+	base_file_stat::operator = (fs);
+
+	file_name = fs.file_name;
+	follow_links = fs.follow_links;
+      }
+
+    return *this;
+  }
+
+  ~file_stat (void) { }
+
+  void get_stats (bool force = false)
+  {
+    if (! initialized || force)
+      update_internal (force);
+  }
+
+  void get_stats (const std::string& n, bool force = false)
+  {
+    if (n != file_name || ! initialized  || force)
+      {
+	initialized = false;
+
+	file_name = n;
+
+	update_internal (force);
+      }
+  }
+
+private:
+
+  // Name of the file.
+  std::string file_name;
+
+  // TRUE means follow symbolic links to the ultimate file (stat).
+  // FALSE means get information about the link itself (lstat).
+  bool follow_links;
+
+  void update_internal (bool force = false);
+};
+
+class
+OCTAVE_API
+file_fstat : public base_file_stat
+{
+public:
+
+  file_fstat (int n) : base_file_stat (), fid (n)
+  {
+    update_internal ();
+  }
+
+  file_fstat (const file_fstat& fs)
+    : base_file_stat (fs), fid (fs.fid) { }
+
+  file_fstat& operator = (const file_fstat& fs)
+  {
+    if (this != &fs)
+      {
+	base_file_stat::operator = (fs);
+
+	fid = fs.fid;
+      }
+
+    return *this;
+  }
+
+  ~file_fstat (void) { }
+
+  void get_stats (bool force = false)
+  {
+    if (! initialized || force)
+      update_internal (force);
+  }
+
+  void get_stats (int n, bool force = false)
+  {
+    if (n != fid || ! initialized  || force)
+      {
+	initialized = false;
+
+	fid = n;
+
+	update_internal (force);
+      }
+  }
+
+private:
+
+  // Open file descriptor.
+  int fid;
+
+  void update_internal (bool force = false);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/filemode.c b/liboctave/filemode.c
new file mode 100644
index 0000000..94b224f
--- /dev/null
+++ b/liboctave/filemode.c
@@ -0,0 +1,258 @@
+/* filemode.c -- make a string describing file modes
+   Copyright (C) 1985, 1990, 1993 Free Software Foundation, Inc.
+
+   This program is free software; you can 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+
+#if !S_IRUSR
+# if S_IREAD
+#  define S_IRUSR S_IREAD
+# else
+#  define S_IRUSR 00400
+# endif
+#endif
+
+#if !S_IWUSR
+# if S_IWRITE
+#  define S_IWUSR S_IWRITE
+# else
+#  define S_IWUSR 00200
+# endif
+#endif
+
+#if !S_IXUSR
+# if S_IEXEC
+#  define S_IXUSR S_IEXEC
+# else
+#  define S_IXUSR 00100
+# endif
+#endif
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISBLK
+#undef S_ISCHR
+#undef S_ISDIR
+#undef S_ISFIFO
+#undef S_ISLNK
+#undef S_ISMPB
+#undef S_ISMPC
+#undef S_ISNWK
+#undef S_ISREG
+#undef S_ISSOCK
+#endif /* STAT_MACROS_BROKEN.  */
+
+#if !defined(S_ISBLK) && defined(S_IFBLK)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#endif
+#if !defined(S_ISCHR) && defined(S_IFCHR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISFIFO) && defined(S_IFIFO)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
+#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
+#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
+#endif
+#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
+#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
+#endif
+
+void mode_string ();
+static char ftypelet ();
+static void rwx ();
+static void setst ();
+
+/* filemodestring - fill in string STR with an ls-style ASCII
+   representation of the st_mode field of file stats block STATP.
+   10 characters are stored in STR; no terminating null is added.
+   The characters stored in STR are:
+
+   0	File type.  'd' for directory, 'c' for character
+	special, 'b' for block special, 'm' for multiplex,
+	'l' for symbolic link, 's' for socket, 'p' for fifo,
+	'-' for regular, '?' for any other file type
+
+   1	'r' if the owner may read, '-' otherwise.
+
+   2	'w' if the owner may write, '-' otherwise.
+
+   3	'x' if the owner may execute, 's' if the file is
+	set-user-id, '-' otherwise.
+	'S' if the file is set-user-id, but the execute
+	bit isn't set.
+
+   4	'r' if group members may read, '-' otherwise.
+
+   5	'w' if group members may write, '-' otherwise.
+
+   6	'x' if group members may execute, 's' if the file is
+	set-group-id, '-' otherwise.
+	'S' if it is set-group-id but not executable.
+
+   7	'r' if any user may read, '-' otherwise.
+
+   8	'w' if any user may write, '-' otherwise.
+
+   9	'x' if any user may execute, 't' if the file is "sticky"
+	(will be retained in swap space after execution), '-'
+	otherwise.
+	'T' if the file is sticky but not executable.  */
+
+void
+filemodestring (statp, str)
+     struct stat *statp;
+     char *str;
+{
+  mode_string (statp->st_mode, str);
+}
+
+/* Like filemodestring, but only the relevant part of the `struct stat'
+   is given as an argument.  */
+
+void
+mode_string (mode, str)
+     unsigned short mode;
+     char *str;
+{
+  str[0] = ftypelet ((long) mode);
+  rwx ((mode & 0700) << 0, &str[1]);
+  rwx ((mode & 0070) << 3, &str[4]);
+  rwx ((mode & 0007) << 6, &str[7]);
+  setst (mode, str);
+}
+
+/* Return a character indicating the type of file described by
+   file mode BITS:
+   'd' for directories
+   'b' for block special files
+   'c' for character special files
+   'm' for multiplexor files
+   'l' for symbolic links
+   's' for sockets
+   'p' for fifos
+   '-' for regular files
+   '?' for any other file type.  */
+
+static char
+ftypelet (bits)
+     long bits;
+{
+#ifdef S_ISBLK
+  if (S_ISBLK (bits))
+    return 'b';
+#endif
+  if (S_ISCHR (bits))
+    return 'c';
+  if (S_ISDIR (bits))
+    return 'd';
+  if (S_ISREG (bits))
+    return '-';
+#ifdef S_ISFIFO
+  if (S_ISFIFO (bits))
+    return 'p';
+#endif
+#ifdef S_ISLNK
+  if (S_ISLNK (bits))
+    return 'l';
+#endif
+#ifdef S_ISSOCK
+  if (S_ISSOCK (bits))
+    return 's';
+#endif
+#ifdef S_ISMPC
+  if (S_ISMPC (bits))
+    return 'm';
+#endif
+#ifdef S_ISNWK
+  if (S_ISNWK (bits))
+    return 'n';
+#endif
+  return '?';
+}
+
+/* Look at read, write, and execute bits in BITS and set
+   flags in CHARS accordingly.  */
+
+static void
+rwx (bits, chars)
+     unsigned short bits;
+     char *chars;
+{
+  chars[0] = (bits & S_IRUSR) ? 'r' : '-';
+  chars[1] = (bits & S_IWUSR) ? 'w' : '-';
+  chars[2] = (bits & S_IXUSR) ? 'x' : '-';
+}
+
+/* Set the 's' and 't' flags in file attributes string CHARS,
+   according to the file mode BITS.  */
+
+static void
+setst (bits, chars)
+     unsigned short bits;
+     char *chars;
+{
+#ifdef S_ISUID
+  if (bits & S_ISUID)
+    {
+      if (chars[3] != 'x')
+	/* Set-uid, but not executable by owner.  */
+	chars[3] = 'S';
+      else
+	chars[3] = 's';
+    }
+#endif
+#ifdef S_ISGID
+  if (bits & S_ISGID)
+    {
+      if (chars[6] != 'x')
+	/* Set-gid, but not executable by group.  */
+	chars[6] = 'S';
+      else
+	chars[6] = 's';
+    }
+#endif
+#ifdef S_ISVTX
+  if (bits & S_ISVTX)
+    {
+      if (chars[9] != 'x')
+	/* Sticky, but not executable by others.  */
+	chars[9] = 'T';
+      else
+	chars[9] = 't';
+    }
+#endif
+}
diff --git a/liboctave/floatAEPBAL.cc b/liboctave/floatAEPBAL.cc
new file mode 100644
index 0000000..1beb91d
--- /dev/null
+++ b/liboctave/floatAEPBAL.cc
@@ -0,0 +1,108 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007 John W. Eaton
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "floatAEPBAL.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgebal, SGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgebak, SGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             const float*, const octave_idx_type&, float*,
+                             const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+FloatAEPBALANCE::FloatAEPBALANCE (const FloatMatrix& a, 
+                                  bool noperm, bool noscal)
+  : base_aepbal<FloatMatrix, FloatColumnVector> ()
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("AEPBALANCE requires square matrix");
+      return;
+    }
+
+  octave_idx_type info;
+
+  scale = FloatColumnVector (n);
+  float *pscale = scale.fortran_vec ();
+
+  balanced_mat = a;
+  float *p_balanced_mat = balanced_mat.fortran_vec ();
+
+  job = noperm ? (noscal ? 'N' : 'S') : (noscal ? 'P' : 'B');
+
+  F77_XFCN (sgebal, SGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, ilo, ihi, pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+}
+
+FloatMatrix
+FloatAEPBALANCE::balancing_matrix (void) const
+{
+  octave_idx_type n = balanced_mat.rows ();
+  FloatMatrix balancing_mat (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    balancing_mat.elem (i ,i) = 1.0;
+
+  float *p_balancing_mat = balancing_mat.fortran_vec ();
+  const float *pscale = scale.fortran_vec ();
+
+  octave_idx_type info;
+
+  char side = 'R';
+
+  F77_XFCN (sgebak, SGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n,
+			     p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return balancing_mat;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatAEPBAL.h b/liboctave/floatAEPBAL.h
new file mode 100644
index 0000000..c5400b3
--- /dev/null
+++ b/liboctave/floatAEPBAL.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatAEPBALANCE_h)
+#define octave_FloatAEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "base-aepbal.h"
+#include "fMatrix.h"
+#include "fColVector.h"
+
+class
+OCTAVE_API
+FloatAEPBALANCE : public base_aepbal<FloatMatrix, FloatColumnVector>
+{
+public:
+
+  FloatAEPBALANCE (void) : base_aepbal<FloatMatrix, FloatColumnVector> () { }
+
+  FloatAEPBALANCE (const FloatMatrix& a, bool noperm = false,
+                   bool noscal = false);
+
+  FloatAEPBALANCE (const FloatAEPBALANCE& a) 
+    : base_aepbal<FloatMatrix, FloatColumnVector> (a) { }
+
+  FloatMatrix balancing_matrix (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatCHOL.cc b/liboctave/floatCHOL.cc
new file mode 100644
index 0000000..6bf1a48
--- /dev/null
+++ b/liboctave/floatCHOL.cc
@@ -0,0 +1,450 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "fRowVector.h"
+#include "floatCHOL.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+#ifndef HAVE_QRUPDATE
+#include "dbleQR.h"
+#endif
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (spotrf, SPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (spotri, SPOTRI) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (spocon, SPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&,
+			     float*, const octave_idx_type&, const float&,
+			     float&, float*, octave_idx_type*, 
+			     octave_idx_type& F77_CHAR_ARG_LEN_DECL);
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (sch1up, SCH1UP) (const octave_idx_type&, float*, const octave_idx_type&,
+                             float*, float*);
+
+  F77_RET_T
+  F77_FUNC (sch1dn, SCH1DN) (const octave_idx_type&, float*, const octave_idx_type&,
+                             float*, float*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (schinx, SCHINX) (const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, float*, float*, 
+                             octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (schdex, SCHDEX) (const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, float*);
+
+  F77_RET_T
+  F77_FUNC (schshx, SCHSHX) (const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&, 
+                             float*);
+#endif
+}
+
+octave_idx_type
+FloatCHOL::init (const FloatMatrix& a, bool calc_cond)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) ("FloatCHOL requires square matrix");
+      return -1;
+    }
+
+  octave_idx_type n = a_nc;
+  octave_idx_type info;
+
+  chol_mat = a;
+  float *h = chol_mat.fortran_vec ();
+
+  // Calculate the norm of the matrix, for later use.
+  float anorm = 0;
+  if (calc_cond) 
+    anorm = chol_mat.abs().sum().row(static_cast<octave_idx_type>(0)).max();
+
+  F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 ("U", 1),
+			     n, h, n, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  xrcond = 0.0;
+  if (info != 0)
+    info = -1;
+  else if (calc_cond) 
+    {
+      octave_idx_type spocon_info = 0;
+
+      // Now calculate the condition number for non-singular matrix.
+      Array<float> z (3*n);
+      float *pz = z.fortran_vec ();
+      Array<octave_idx_type> iz (n);
+      octave_idx_type *piz = iz.fortran_vec ();
+      F77_XFCN (spocon, SPOCON, (F77_CONST_CHAR_ARG2 ("U", 1), n, h,
+				 n, anorm, xrcond, pz, piz, spocon_info
+				 F77_CHAR_ARG_LEN (1)));
+
+      if (spocon_info != 0) 
+	info = -1;
+    }
+  else
+    {
+      // If someone thinks of a more graceful way of doing this (or
+      // faster for that matter :-)), please let me know!
+
+      if (n > 1)
+	for (octave_idx_type j = 0; j < a_nc; j++)
+	  for (octave_idx_type i = j+1; i < a_nr; i++)
+	    chol_mat.xelem (i, j) = 0.0;
+    }
+
+  return info;
+}
+
+static FloatMatrix
+chol2inv_internal (const FloatMatrix& r)
+{
+  FloatMatrix retval;
+
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.cols ();
+
+  if (r_nr == r_nc)
+    {
+      octave_idx_type n = r_nc;
+      octave_idx_type info = 0;
+
+      FloatMatrix tmp = r;
+      float *v = tmp.fortran_vec();
+
+      if (info == 0)
+	{
+	  F77_XFCN (spotri, SPOTRI, (F77_CONST_CHAR_ARG2 ("U", 1), n,
+				     v, n, info
+				     F77_CHAR_ARG_LEN (1)));
+
+	  // If someone thinks of a more graceful way of doing this (or
+	  // faster for that matter :-)), please let me know!
+
+	  if (n > 1)
+	    for (octave_idx_type j = 0; j < r_nc; j++)
+	      for (octave_idx_type i = j+1; i < r_nr; i++)
+		tmp.xelem (i, j) = tmp.xelem (j, i);
+
+	  retval = tmp;
+	}
+    }
+  else
+    (*current_liboctave_error_handler) ("chol2inv requires square matrix");
+
+  return retval;
+}
+
+// Compute the inverse of a matrix using the Cholesky factorization.
+FloatMatrix
+FloatCHOL::inverse (void) const
+{
+  return chol2inv_internal (chol_mat);
+}
+
+void
+FloatCHOL::set (const FloatMatrix& R)
+{
+  if (R.is_square ()) 
+    chol_mat = R;
+  else
+    (*current_liboctave_error_handler) ("FloatCHOL requires square matrix");
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+FloatCHOL::update (const FloatColumnVector& u)
+{
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      FloatColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (float, w, n);
+
+      F77_XFCN (sch1up, SCH1UP, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), w));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+octave_idx_type
+FloatCHOL::downdate (const FloatColumnVector& u)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      FloatColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (float, w, n);
+
+      F77_XFCN (sch1dn, SCH1DN, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 utmp.fortran_vec (), w, info));
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+FloatCHOL::insert_sym (const FloatColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      FloatColumnVector utmp = u;
+
+      OCTAVE_LOCAL_BUFFER (float, w, n);
+
+      chol_mat.resize (n+1, n+1);
+
+      F77_XFCN (schinx, SCHINX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 j + 1, utmp.fortran_vec (), w, info));
+    }
+
+  return info;
+}
+
+void
+FloatCHOL::delete_sym (octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, n);
+
+      F77_XFCN (schdex, SCHDEX, (n, chol_mat.fortran_vec (), chol_mat.rows (), 
+                                 j + 1, w));
+
+      chol_mat.resize (n-1, n-1);
+    }
+}
+
+void
+FloatCHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = chol_mat.rows ();
+  
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, 2*n);
+
+      F77_XFCN (schshx, SCHSHX, (n, chol_mat.fortran_vec (), chol_mat.rows (),
+                                 i + 1, j + 1, w));
+    }
+}
+
+#else
+
+void
+FloatCHOL::update (const FloatColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      init (chol_mat.transpose () * chol_mat 
+            + FloatMatrix (u) * FloatMatrix (u).transpose (), false);
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+}
+
+static bool
+singular (const FloatMatrix& a)
+{
+  for (octave_idx_type i = 0; i < a.rows (); i++)
+    if (a(i,i) == 0.0f) return true;
+  return false;
+}
+
+octave_idx_type
+FloatCHOL::downdate (const FloatColumnVector& u)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () == n)
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else
+        {
+          info = init (chol_mat.transpose () * chol_mat 
+                - FloatMatrix (u) * FloatMatrix (u).transpose (), false);
+          if (info) info = 1;
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("cholupdate: dimension mismatch");
+
+  return info;
+}
+
+octave_idx_type
+FloatCHOL::insert_sym (const FloatColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type info = -1;
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (u.length () != n + 1)
+    (*current_liboctave_error_handler) ("cholinsert: dimension mismatch");
+  else if (j < 0 || j > n)
+    (*current_liboctave_error_handler) ("cholinsert: index out of range");
+  else
+    {
+      if (singular (chol_mat))
+        info = 2;
+      else
+        {
+          FloatMatrix a = chol_mat.transpose () * chol_mat;
+          FloatMatrix a1 (n+1, n+1);
+          for (octave_idx_type k = 0; k < n+1; k++)
+            for (octave_idx_type l = 0; l < n+1; l++)
+              {
+                if (l == j)
+                  a1(k, l) = u(k);
+                else if (k == j)
+                  a1(k, l) = u(l);
+                else
+                  a1(k, l) = a(k < j ? k : k-1, l < j ? l : l-1);
+              }
+          info = init (a1, false);
+          if (info) info = 1;
+        }
+    }
+
+  return info;
+}
+
+void
+FloatCHOL::delete_sym (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (j < 0 || j > n-1)
+    (*current_liboctave_error_handler) ("choldelete: index out of range");
+  else
+    {
+      FloatMatrix a = chol_mat.transpose () * chol_mat;
+      a.delete_elements (1, idx_vector (j));
+      a.delete_elements (0, idx_vector (j));
+      init (a, false);
+    }
+}
+
+void
+FloatCHOL::shift_sym (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type n = chol_mat.rows ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("cholshift: index out of range");
+  else
+    {
+      FloatMatrix a = chol_mat.transpose () * chol_mat;
+      Array<octave_idx_type> p (n);
+      for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+      if (i < j)
+        {
+          for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+          p(j) = i;
+        }
+      else if (j < i)
+        {
+          p(j) = i;
+          for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+        }
+
+      init (a.index (idx_vector (p), idx_vector (p)), false);
+    }
+}
+
+#endif
+
+FloatMatrix
+chol2inv (const FloatMatrix& r)
+{
+  return chol2inv_internal (r);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatCHOL.h b/liboctave/floatCHOL.h
new file mode 100644
index 0000000..564df8d
--- /dev/null
+++ b/liboctave/floatCHOL.h
@@ -0,0 +1,96 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatCHOL_h)
+#define octave_FloatCHOL_h 1
+
+#include <iosfwd>
+
+#include "fMatrix.h"
+#include "fColVector.h"
+
+class
+OCTAVE_API
+FloatCHOL
+{
+public:
+
+  FloatCHOL (void) : chol_mat () { }
+
+  FloatCHOL (const FloatMatrix& a, bool calc_cond = false) { init (a, calc_cond); }
+
+  FloatCHOL (const FloatMatrix& a, octave_idx_type& info, bool calc_cond = false) 
+    { info = init (a, calc_cond); }
+
+  FloatCHOL (const FloatCHOL& a) : chol_mat (a.chol_mat), xrcond (a.xrcond) { }
+
+  FloatCHOL& operator = (const FloatCHOL& a)
+    {
+      if (this != &a)
+	{
+	  chol_mat = a.chol_mat;
+	  xrcond = a.xrcond;
+	}
+      return *this;
+    }
+
+  FloatMatrix chol_matrix (void) const { return chol_mat; }
+
+  float rcond (void) const { return xrcond; }
+
+  // Compute the inverse of a matrix using the Cholesky factorization.
+  FloatMatrix inverse (void) const;
+
+  void set (const FloatMatrix& R);
+
+  void update (const FloatColumnVector& u);
+
+  octave_idx_type downdate (const FloatColumnVector& u);
+
+  octave_idx_type insert_sym (const FloatColumnVector& u, octave_idx_type j);
+
+  void delete_sym (octave_idx_type j);
+
+  void shift_sym (octave_idx_type i, octave_idx_type j);
+
+  friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatCHOL& a);
+
+private:
+
+  FloatMatrix chol_mat;
+
+  float xrcond;
+
+  octave_idx_type init (const FloatMatrix& a, bool calc_cond);
+};
+
+FloatMatrix OCTAVE_API chol2inv (const FloatMatrix& r);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatGEPBAL.cc b/liboctave/floatGEPBAL.cc
new file mode 100644
index 0000000..12c7f28
--- /dev/null
+++ b/liboctave/floatGEPBAL.cc
@@ -0,0 +1,131 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "floatGEPBAL.h"
+#include "Array-util.h"
+#include "f77-fcn.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sggbal, SGGBAL) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type& N,
+			     float* A, const octave_idx_type& LDA, float* B,
+			     const octave_idx_type& LDB, octave_idx_type& ILO, octave_idx_type& IHI,
+			     float* LSCALE, float* RSCALE,
+			     float* WORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sggbak, SGGBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO,
+			     const octave_idx_type& IHI, const float* LSCALE,
+			     const float* RSCALE, octave_idx_type& M, float* V,
+			     const octave_idx_type& LDV, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+}
+
+octave_idx_type
+FloatGEPBALANCE::init (const FloatMatrix& a, const FloatMatrix& b, 
+		  const std::string& balance_job)
+{
+  octave_idx_type n = a.cols ();
+
+  if (a.rows () != n)
+    {
+      (*current_liboctave_error_handler) ("FloatGEPBALANCE requires square matrix");
+      return -1;
+    }
+
+  if (a.dims() != b.dims ())
+    {
+      gripe_nonconformant ("FloatGEPBALANCE", n, n, b.rows(), b.cols());
+      return -1;
+    } 
+
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  OCTAVE_LOCAL_BUFFER (float, plscale, n);
+  OCTAVE_LOCAL_BUFFER (float, prscale, n);
+  OCTAVE_LOCAL_BUFFER (float, pwork, 6 * n);
+
+  balanced_mat = a;
+  float *p_balanced_mat = balanced_mat.fortran_vec ();
+  balanced_mat2 = b;
+  float *p_balanced_mat2 = balanced_mat2.fortran_vec ();
+
+  char job = balance_job[0];
+
+  F77_XFCN (sggbal, SGGBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, p_balanced_mat, n, p_balanced_mat2,
+			     n, ilo, ihi, plscale, prscale, pwork, info
+			     F77_CHAR_ARG_LEN  (1)));
+
+  balancing_mat = FloatMatrix (n, n, 0.0);
+  balancing_mat2 = FloatMatrix (n, n, 0.0);
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      OCTAVE_QUIT;
+      balancing_mat.elem (i ,i) = 1.0;
+      balancing_mat2.elem (i ,i) = 1.0;
+    }
+
+  float *p_balancing_mat = balancing_mat.fortran_vec ();
+  float *p_balancing_mat2 = balancing_mat2.fortran_vec ();
+
+  // first left
+  F77_XFCN (sggbak, SGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("L", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+      
+  // then right
+  F77_XFCN (sggbak, SGGBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 ("R", 1),
+			     n, ilo, ihi, plscale, prscale,
+			     n, p_balancing_mat2, n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatGEPBAL.h b/liboctave/floatGEPBAL.h
new file mode 100644
index 0000000..6732050
--- /dev/null
+++ b/liboctave/floatGEPBAL.h
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatGEPBALANCE_h)
+#define octave_FloatGEPBALANCE_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "fMatrix.h"
+
+class
+OCTAVE_API
+FloatGEPBALANCE
+{
+public:
+
+  FloatGEPBALANCE (void) : balanced_mat (), balancing_mat () { }
+
+  FloatGEPBALANCE (const FloatMatrix& a, const FloatMatrix& b, const std::string& balance_job)
+    {
+      init (a, b, balance_job); 
+    }
+
+  FloatGEPBALANCE (const FloatGEPBALANCE& a)
+    : balanced_mat (a.balanced_mat), balanced_mat2 (a.balanced_mat2),
+    balancing_mat (a.balancing_mat), balancing_mat2 (a.balancing_mat2) { }
+
+  FloatGEPBALANCE& operator = (const FloatGEPBALANCE& a)
+    {
+      if (this != &a)
+	{
+	  balanced_mat = a.balanced_mat;
+	  balanced_mat2 = a.balanced_mat2;
+	  balancing_mat = a.balancing_mat;
+	  balancing_mat2 = a.balancing_mat2;
+	}
+      return *this;
+    }
+
+  ~FloatGEPBALANCE (void) { }
+
+  FloatMatrix balanced_matrix (void) const { return balanced_mat; }
+
+  FloatMatrix balanced_matrix2 (void) const { return balanced_mat2; }
+
+  FloatMatrix balancing_matrix (void) const { return balancing_mat; }
+
+  FloatMatrix balancing_matrix2 (void) const { return balancing_mat2; }
+
+  friend std::ostream& operator << (std::ostream& os, const FloatGEPBALANCE& a);
+
+private:
+
+  FloatMatrix balanced_mat;
+  FloatMatrix balanced_mat2;
+  FloatMatrix balancing_mat;
+  FloatMatrix balancing_mat2;
+
+  octave_idx_type init (const FloatMatrix& a, const FloatMatrix& b, 
+			const std::string& balance_job);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatHESS.cc b/liboctave/floatHESS.cc
new file mode 100644
index 0000000..f887032
--- /dev/null
+++ b/liboctave/floatHESS.cc
@@ -0,0 +1,128 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "floatHESS.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgebal, SGEBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&,
+			     octave_idx_type&, float*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (sgehrd, SGEHRD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     float*, const octave_idx_type&, float*, float*,
+			     const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (sorghr, SORGHR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+			     float*, const octave_idx_type&, float*, float*,
+			     const octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (sgebak, SGEBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+octave_idx_type
+FloatHESS::init (const FloatMatrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) ("FloatHESS requires square matrix");
+      return -1;
+    }
+
+  char job = 'N';
+  char side = 'R';
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 32 * n;
+  octave_idx_type info;
+  octave_idx_type ilo;
+  octave_idx_type ihi;
+
+  hess_mat = a;
+  float *h = hess_mat.fortran_vec ();
+
+  Array<float> scale (n);
+  float *pscale = scale.fortran_vec ();
+
+  F77_XFCN (sgebal, SGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     n, h, n, ilo, ihi, pscale, info
+			     F77_CHAR_ARG_LEN (1)));
+
+  Array<float> tau (n-1);
+  float *ptau = tau.fortran_vec ();
+
+  Array<float> work (lwork);
+  float *pwork = work.fortran_vec ();
+
+  F77_XFCN (sgehrd, SGEHRD, (n, ilo, ihi, h, n, ptau, pwork,
+			     lwork, info));
+
+  unitary_hess_mat = hess_mat;
+  float *z = unitary_hess_mat.fortran_vec ();
+
+  F77_XFCN (sorghr, SORGHR, (n, ilo, ihi, z, n, ptau, pwork,
+			     lwork, info));
+
+  F77_XFCN (sgebak, SGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
+			     F77_CONST_CHAR_ARG2 (&side, 1),
+			     n, ilo, ihi, pscale, n, z,
+			     n, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  // If someone thinks of a more graceful way of doing
+  // this (or faster for that matter :-)), please let
+  // me know!
+
+  if (n > 2)
+    for (octave_idx_type j = 0; j < a_nc; j++)
+      for (octave_idx_type i = j+2; i < a_nr; i++)
+	hess_mat.elem (i, j) = 0;
+
+  return info;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatHESS.h b/liboctave/floatHESS.h
new file mode 100644
index 0000000..3975bf4
--- /dev/null
+++ b/liboctave/floatHESS.h
@@ -0,0 +1,78 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatHESS_h)
+#define octave_FloatHESS_h 1
+
+#include <iosfwd>
+
+#include "fMatrix.h"
+
+class
+OCTAVE_API
+FloatHESS
+{
+public:
+
+  FloatHESS (void) : hess_mat (), unitary_hess_mat () { }
+
+  FloatHESS (const FloatMatrix& a) { init (a); }
+
+  FloatHESS (const FloatMatrix& a, octave_idx_type& info) { info = init (a); }
+
+  FloatHESS (const FloatHESS& a)
+    : hess_mat (a.hess_mat), unitary_hess_mat (a.unitary_hess_mat) { }
+
+  FloatHESS& operator = (const FloatHESS& a)
+    {
+      if (this != &a)
+	{
+	  hess_mat = a.hess_mat;
+	  unitary_hess_mat = a.unitary_hess_mat;
+	}
+      return *this;
+    }
+
+  ~FloatHESS (void) { }
+
+  FloatMatrix hess_matrix (void) const { return hess_mat; }
+
+  FloatMatrix unitary_hess_matrix (void) const { return unitary_hess_mat; }
+
+  friend std::ostream& operator << (std::ostream& os, const FloatHESS& a);
+
+private:
+
+  FloatMatrix hess_mat;
+  FloatMatrix unitary_hess_mat;
+
+  octave_idx_type init (const FloatMatrix& a);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatLU.cc b/liboctave/floatLU.cc
new file mode 100644
index 0000000..b7e1ad9
--- /dev/null
+++ b/liboctave/floatLU.cc
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "floatLU.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+// Instantiate the base LU class for the types we need.
+
+#include <base-lu.h>
+#include <base-lu.cc>
+
+template class base_lu <FloatMatrix>;
+
+// Define the constructor for this particular derivation.
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgetrf, SGETRF) (const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, octave_idx_type*, octave_idx_type&);
+}
+
+FloatLU::FloatLU (const FloatMatrix& a)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+  ipvt.resize (mn);
+  octave_idx_type *pipvt = ipvt.fortran_vec ();
+
+  a_fact = a;
+  float *tmp_data = a_fact.fortran_vec ();
+
+  octave_idx_type info = 0;
+
+  F77_XFCN (sgetrf, SGETRF, (a_nr, a_nc, tmp_data, a_nr, pipvt, info));
+
+  ipvt -= static_cast<octave_idx_type> (1);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatLU.h b/liboctave/floatLU.h
new file mode 100644
index 0000000..b866624
--- /dev/null
+++ b/liboctave/floatLU.h
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatLU_h)
+#define octave_FloatLU_h 1
+
+#include "base-lu.h"
+#include "dMatrix.h"
+#include "fMatrix.h"
+
+class
+OCTAVE_API
+FloatLU : public base_lu <FloatMatrix>
+{
+public:
+
+  FloatLU (void) : base_lu <FloatMatrix> () { }
+
+  FloatLU (const FloatMatrix& a);
+
+  FloatLU (const FloatLU& a) : base_lu <FloatMatrix> (a) { }
+
+  FloatLU& operator = (const FloatLU& a)
+    {
+      if (this != &a)
+	base_lu <FloatMatrix> :: operator = (a);
+
+      return *this;
+    }
+
+  ~FloatLU (void) { }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatQR.cc b/liboctave/floatQR.cc
new file mode 100644
index 0000000..e08a143
--- /dev/null
+++ b/liboctave/floatQR.cc
@@ -0,0 +1,715 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "floatQR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "Range.h"
+#include "idx-vector.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgeqrf, SGEQRF) (const octave_idx_type&, const octave_idx_type&, float*, const octave_idx_type&,
+			     float*, float*, const octave_idx_type&, octave_idx_type&); 
+
+  F77_RET_T
+  F77_FUNC (sorgqr, SORGQR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, float*, float*, const octave_idx_type&, octave_idx_type&);
+
+#ifdef HAVE_QRUPDATE
+
+  F77_RET_T
+  F77_FUNC (sqr1up, SQR1UP) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             float*, const octave_idx_type&, float*, const octave_idx_type&,
+                             float*, float*, float*);
+
+  F77_RET_T
+  F77_FUNC (sqrinc, SQRINC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             float*, const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, const float*, float*);
+
+  F77_RET_T
+  F77_FUNC (sqrdec, SQRDEC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             float*, const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, float*);
+
+  F77_RET_T
+  F77_FUNC (sqrinr, SQRINR) (const octave_idx_type&, const octave_idx_type&, 
+                             float*, const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, const float*, float*);
+
+  F77_RET_T
+  F77_FUNC (sqrder, SQRDER) (const octave_idx_type&, const octave_idx_type&, 
+                             float*, const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, float*);
+
+  F77_RET_T
+  F77_FUNC (sqrshc, SQRSHC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
+                             float*, const octave_idx_type&, float*, const octave_idx_type&,
+                             const octave_idx_type&, const octave_idx_type&,
+                             float*);
+
+#endif
+}
+
+FloatQR::FloatQR (const FloatMatrix& a, QR::type qr_type)
+  : q (), r ()
+{
+  init (a, qr_type);
+}
+
+void
+FloatQR::init (const FloatMatrix& a, QR::type qr_type)
+{
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (float, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  FloatMatrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  if (m > 0)
+    {
+      // workspace query.
+      float rlwork;
+      F77_XFCN (sgeqrf, SGEQRF, (m, n, afact.fortran_vec (), m, tau, &rlwork, -1, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = rlwork;
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (float, work, lwork);
+      F77_XFCN (sgeqrf, SGEQRF, (m, n, afact.fortran_vec (), m, tau, work, lwork, info));
+    }
+
+  form (n, afact, tau, qr_type);
+}
+
+void FloatQR::form (octave_idx_type n, FloatMatrix& afact, 
+                    float *tau, QR::type qr_type)
+{
+  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type info;
+
+  if (qr_type == QR::raw)
+    {
+      for (octave_idx_type j = 0; j < min_mn; j++)
+	{
+	  octave_idx_type limit = j < min_mn - 1 ? j : min_mn - 1;
+	  for (octave_idx_type i = limit + 1; i < m; i++)
+	    afact.elem (i, j) *= tau[j];
+	}
+
+      r = afact;
+    }
+  else
+    {
+      // Attempt to minimize copying.
+      if (m >= n)
+        {
+          // afact will become q.
+          q = afact;
+          octave_idx_type k = qr_type == QR::economy ? n : m;
+          r = FloatMatrix (k, n);
+          for (octave_idx_type j = 0; j < n; j++)
+            {
+              octave_idx_type i = 0;
+              for (; i <= j; i++)
+                r.xelem (i, j) = afact.xelem (i, j);
+              for (;i < k; i++)
+                r.xelem (i, j) = 0;
+            }
+          afact = FloatMatrix (); // optimize memory
+        }
+      else
+        {
+          // afact will become r.
+          q = FloatMatrix (m, m);
+          for (octave_idx_type j = 0; j < m; j++)
+            for (octave_idx_type i = j + 1; i < m; i++)
+              {
+                q.xelem (i, j) = afact.xelem (i, j);
+                afact.xelem (i, j) = 0;
+              }
+          r = afact;
+        }
+
+
+      if (m > 0)
+        {
+          octave_idx_type k = q.columns ();
+          // workspace query.
+          float rlwork;
+          F77_XFCN (sorgqr, SORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     &rlwork, -1, info));
+
+          // allocate buffer and do the job.
+          octave_idx_type lwork = rlwork;
+	  lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+          OCTAVE_LOCAL_BUFFER (float, work, lwork);
+          F77_XFCN (sorgqr, SORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
+                                     work, lwork, info));
+        }
+    }
+}
+
+FloatQR::FloatQR (const FloatMatrix& q_arg, const FloatMatrix& r_arg)
+{
+  octave_idx_type qr = q_arg.rows (), qc = q_arg.columns ();
+  octave_idx_type rr = r_arg.rows (), rc = r_arg.columns ();
+  if (qc == rr && (qr == qc || (qr > qc && rr == rc)))
+    {
+      q = q_arg;
+      r = r_arg;
+    }
+  else
+    (*current_liboctave_error_handler) ("QR dimensions mismatch");
+}
+
+QR::type
+FloatQR::get_type (void) const
+{
+  QR::type retval;
+  if (!q.is_empty () && q.is_square ())
+    retval = QR::std;
+  else if (q.rows () > q.columns () && r.is_square ())
+    retval = QR::economy;
+  else
+    retval = QR::raw;
+  return retval;
+}
+
+#ifdef HAVE_QRUPDATE
+
+void
+FloatQR::update (const FloatColumnVector& u, const FloatColumnVector& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      FloatColumnVector utmp = u, vtmp = v;
+      OCTAVE_LOCAL_BUFFER (float, w, 2*k);
+      F77_XFCN (sqr1up, SQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                 utmp.fortran_vec (), vtmp.fortran_vec (), w));
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+FloatQR::update (const FloatMatrix& u, const FloatMatrix& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, 2*k);
+      for (volatile octave_idx_type i = 0; i < u.cols (); i++)
+        {
+          FloatColumnVector utmp = u.column (i), vtmp = v.column (i);
+          F77_XFCN (sqr1up, SQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
+                                     utmp.fortran_vec (), vtmp.fortran_vec (), w));
+        }
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+FloatQR::insert_col (const FloatColumnVector& u, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      if (k < m)
+        {
+          q.resize (m, k+1);
+          r.resize (k+1, n+1);
+        }
+      else
+        {
+          r.resize (k, n+1);
+        }
+
+      FloatColumnVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (float, w, k);
+      F77_XFCN (sqrinc, SQRINC, (m, n, k, q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (), j + 1, 
+                                 utmp.data (), w));
+    }
+}
+
+void
+FloatQR::insert_col (const FloatMatrix& u, const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      octave_idx_type kmax = std::min (k + nj, m);
+      if (k < m)
+        {
+          q.resize (m, kmax);
+          r.resize (kmax, n + nj);
+        }
+      else
+        {
+          r.resize (k, n + nj);
+        }
+
+      OCTAVE_LOCAL_BUFFER (float, w, kmax);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          FloatColumnVector utmp = u.column (jsi(i));
+          F77_XFCN (sqrinc, SQRINC, (m, n + ii, std::min (kmax, k + ii), 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, 
+                                     utmp.data (), w));
+        }
+    }
+}
+
+void
+FloatQR::delete_col (octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, k);
+      F77_XFCN (sqrdec, SQRDEC, (m, n, k, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1, w));
+
+      if (k < m)
+        {
+          q.resize (m, k-1);
+          r.resize (k-1, n-1);
+        }
+      else
+        {
+          r.resize (k, n-1);
+        }
+    }
+}
+
+void
+FloatQR::delete_col (const Array<octave_idx_type>& j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, k);
+      for (volatile octave_idx_type i = 0; i < js.length (); i++)
+        {
+	  octave_idx_type ii = i;
+          F77_XFCN (sqrdec, SQRDEC, (m, n - ii, k == m ? k : k - ii, 
+                                     q.fortran_vec (), q.rows (),
+                                     r.fortran_vec (), r.rows (), js(ii) + 1, w));
+        }
+      if (k < m)
+        {
+          q.resize (m, k - nj);
+          r.resize (k - nj, n - nj);
+        }
+      else
+        {
+          r.resize (k, n - nj);
+        }
+
+    }
+}
+
+void
+FloatQR::insert_row (const FloatRowVector& u, octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = std::min (m, n);
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      q.resize (m + 1, m + 1);
+      r.resize (m + 1, n);
+      FloatRowVector utmp = u;
+      OCTAVE_LOCAL_BUFFER (float, w, k);
+      F77_XFCN (sqrinr, SQRINR, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), 
+                                 j + 1, utmp.fortran_vec (), w));
+
+    }
+}
+
+void
+FloatQR::delete_row (octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, 2*m);
+      F77_XFCN (sqrder, SQRDER, (m, n, q.fortran_vec (), q.rows (),
+				 r.fortran_vec (), r.rows (), j + 1,
+                                 w));
+
+      q.resize (m - 1, m - 1);
+      r.resize (m - 1, n);
+    }
+}
+
+void
+FloatQR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (float, w, 2*k);
+      F77_XFCN (sqrshc, SQRSHC, (m, n, k, 
+                                 q.fortran_vec (), q.rows (),
+                                 r.fortran_vec (), r.rows (),
+                                 i + 1, j + 1, w));
+    }
+}
+
+#else
+
+// Replacement update methods.
+
+void
+FloatQR::update (const FloatColumnVector& u, const FloatColumnVector& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () == m && v.length () == n)
+    {
+      init(q*r + FloatMatrix (u) * FloatMatrix (v).transpose (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+void
+FloatQR::update (const FloatMatrix& u, const FloatMatrix& v)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
+    {
+      init(q*r + u * v.transpose (), get_type ());
+    }
+  else
+    (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
+}
+
+static
+FloatMatrix insert_col (const FloatMatrix& a, octave_idx_type i,
+                        const FloatColumnVector& x)
+{
+  FloatMatrix retval (a.rows (), a.columns () + 1);
+  retval.assign (idx_vector::colon, idx_vector (0, i),
+                 a.index (idx_vector::colon, idx_vector (0, i)));
+  retval.assign (idx_vector::colon, idx_vector (i), x);
+  retval.assign (idx_vector::colon, idx_vector (i+1, retval.columns ()),
+                 a.index (idx_vector::colon, idx_vector (i, a.columns ())));
+  return retval;
+}
+
+static
+FloatMatrix insert_row (const FloatMatrix& a, octave_idx_type i,
+                        const FloatRowVector& x)
+{
+  FloatMatrix retval (a.rows () + 1, a.columns ());
+  retval.assign (idx_vector (0, i), idx_vector::colon,
+                 a.index (idx_vector (0, i), idx_vector::colon));
+  retval.assign (idx_vector (i), idx_vector::colon, x);
+  retval.assign (idx_vector (i+1, retval.rows ()), idx_vector::colon,
+                 a.index (idx_vector (i, a.rows ()), idx_vector::colon));
+  return retval;
+}
+
+static
+FloatMatrix delete_col (const FloatMatrix& a, octave_idx_type i)
+{
+  FloatMatrix retval = a;
+  retval.delete_elements (1, idx_vector (i));
+  return retval;
+}
+
+static
+FloatMatrix delete_row (const FloatMatrix& a, octave_idx_type i)
+{
+  FloatMatrix retval = a;
+  retval.delete_elements (0, idx_vector (i));
+  return retval;
+}
+
+static
+FloatMatrix shift_cols (const FloatMatrix& a, 
+                        octave_idx_type i, octave_idx_type j)
+{
+  octave_idx_type n = a.columns ();
+  Array<octave_idx_type> p (n);
+  for (octave_idx_type k = 0; k < n; k++) p(k) = k;
+  if (i < j)
+    {
+      for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
+      p(j) = i;
+    }
+  else if (j < i)
+    {
+      p(j) = i;
+      for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
+    }
+
+  return a.index (idx_vector::colon, idx_vector (p));
+}
+
+void
+FloatQR::insert_col (const FloatColumnVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > n) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_col (q*r, j, u), get_type ());
+    }
+}
+
+void
+FloatQR::insert_col (const FloatMatrix& u, const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (u.length () != m || u.columns () != nj)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      FloatMatrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::insert_col (a, js(i), u.column (i));
+      init (a, get_type ());
+    }
+}
+
+void
+FloatQR::delete_col (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_col (q*r, j), get_type ());
+    }
+}
+
+void
+FloatQR::delete_col (const Array<octave_idx_type>& j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  Array<octave_idx_type> jsi;
+  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
+  octave_idx_type nj = js.length ();
+  bool dups = false;
+  for (octave_idx_type i = 0; i < nj - 1; i++)
+    dups = dups && js(i) == js(i+1);
+
+  if (dups)
+    (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
+  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else if (nj > 0)
+    {
+      FloatMatrix a = q*r;
+      for (octave_idx_type i = 0; i < js.length (); i++)
+        a = ::delete_col (a, js(i));
+      init (a, get_type ());
+    }
+}
+
+void
+FloatQR::insert_row (const FloatRowVector& u, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
+  else if (j < 0 || j > m) 
+    (*current_liboctave_error_handler) ("qrinsert: index out of range");
+  else
+    {
+      init (::insert_row (q*r, j, u), get_type ());
+    }
+}
+
+void
+FloatQR::delete_row (octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
+  else if (j < 0 || j > m-1) 
+    (*current_liboctave_error_handler) ("qrdelete: index out of range");
+  else
+    {
+      init (::delete_row (q*r, j), get_type ());
+    }
+}
+
+void
+FloatQR::shift_cols (octave_idx_type i, octave_idx_type j)
+{
+  warn_qrupdate_once ();
+
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (i < 0 || i > n-1 || j < 0 || j > n-1) 
+    (*current_liboctave_error_handler) ("qrshift: index out of range");
+  else
+    {
+      init (::shift_cols (q*r, i, j), get_type ());
+    }
+}
+
+#endif
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatQR.h b/liboctave/floatQR.h
new file mode 100644
index 0000000..fa88355
--- /dev/null
+++ b/liboctave/floatQR.h
@@ -0,0 +1,104 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatQR_h)
+#define octave_FloatQR_h 1
+
+#include <iosfwd>
+
+#include "fMatrix.h"
+#include "fColVector.h"
+#include "fRowVector.h"
+#include "dbleQR.h"
+
+class
+OCTAVE_API
+FloatQR
+{
+public:
+
+  FloatQR (void) : q (), r () { }
+
+  FloatQR (const FloatMatrix&, QR::type = QR::std);
+
+  FloatQR (const FloatMatrix& q, const FloatMatrix& r);
+
+  FloatQR (const FloatQR& a) : q (a.q), r (a.r) { }
+
+  FloatQR& operator = (const FloatQR& a)
+    {
+      if (this != &a)
+	{
+	  q = a.q;
+	  r = a.r;
+	}
+      return *this;
+    }
+
+  ~FloatQR (void) { }
+
+  void init (const FloatMatrix&, QR::type);
+
+  FloatMatrix Q (void) const { return q; }
+
+  FloatMatrix R (void) const { return r; }
+
+  QR::type get_type (void) const;
+
+  void update (const FloatColumnVector& u, const FloatColumnVector& v);
+
+  void update (const FloatMatrix& u, const FloatMatrix& v);
+
+  void insert_col (const FloatColumnVector& u, octave_idx_type j);
+
+  void insert_col (const FloatMatrix& u, const Array<octave_idx_type>& j);
+
+  void delete_col (octave_idx_type j);
+
+  void delete_col (const Array<octave_idx_type>& j);
+
+  void insert_row (const FloatRowVector& u, octave_idx_type j);
+
+  void delete_row (octave_idx_type j);
+
+  void shift_cols (octave_idx_type i, octave_idx_type j);
+
+  friend std::ostream&  operator << (std::ostream&, const FloatQR&);
+
+protected:
+
+  void form (octave_idx_type n, FloatMatrix& afact, 
+             float *tau, QR::type qr_type);
+
+  FloatMatrix q;
+  FloatMatrix r;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatQRP.cc b/liboctave/floatQRP.cc
new file mode 100644
index 0000000..63af5a2
--- /dev/null
+++ b/liboctave/floatQRP.cc
@@ -0,0 +1,108 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "floatQRP.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgeqp3, SGEQP3) (const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, octave_idx_type*, float*, float*,
+                             const octave_idx_type&, octave_idx_type&);
+}
+
+// It would be best to share some of this code with QR class...
+
+FloatQRP::FloatQRP (const FloatMatrix& a, QR::type qr_type)
+  : FloatQR (), p ()
+{
+  init (a, qr_type);
+}
+
+void
+FloatQRP::init (const FloatMatrix& a, QR::type qr_type)
+{
+  assert (qr_type != QR::raw);
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+  OCTAVE_LOCAL_BUFFER (float, tau, min_mn);
+
+  octave_idx_type info = 0;
+
+  FloatMatrix afact = a;
+  if (m > n && qr_type == QR::std)
+    afact.resize (m, m);
+
+  MArray<octave_idx_type> jpvt (n, 0);
+
+  if (m > 0)
+    {
+      // workspace query.
+      float rlwork;
+      F77_XFCN (sgeqp3, SGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, &rlwork, -1, info));
+
+      // allocate buffer and do the job.
+      octave_idx_type lwork = rlwork;
+      lwork = std::max (lwork, static_cast<octave_idx_type> (1));
+      OCTAVE_LOCAL_BUFFER (float, work, lwork);
+      F77_XFCN (sgeqp3, SGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
+                                 tau, work, lwork, info));
+    }
+  else
+    for (octave_idx_type i = 0; i < n; i++) jpvt(i) = i+1;
+
+  // Form Permutation matrix (if economy is requested, return the
+  // indices only!)
+
+  jpvt -= static_cast<octave_idx_type> (1);
+  p = PermMatrix (jpvt, true);
+
+
+  form (n, afact, tau, qr_type);
+}
+
+FloatColumnVector
+FloatQRP::Pvec (void) const
+{
+  Array<float> pa (p.pvec ());
+  FloatColumnVector pv (MArray<float> (pa) + 1.0f);
+  return pv;
+}
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatQRP.h b/liboctave/floatQRP.h
new file mode 100644
index 0000000..d965276
--- /dev/null
+++ b/liboctave/floatQRP.h
@@ -0,0 +1,77 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatQRP_h)
+#define octave_FloatQRP_h 1
+
+#include <iosfwd>
+
+#include "floatQR.h"
+#include "PermMatrix.h"
+#include "fColVector.h"
+
+class
+OCTAVE_API
+FloatQRP : public FloatQR
+{
+public:
+
+  FloatQRP (void) : FloatQR (), p () { }
+
+  FloatQRP (const FloatMatrix&, QR::type = QR::std);
+
+  FloatQRP (const FloatQRP& a) : FloatQR (a), p (a.p) { }
+
+  FloatQRP& operator = (const FloatQRP& a)
+    {
+      if (this != &a)
+	{
+	  FloatQR::operator = (a);
+	  p = a.p;
+	}
+
+      return *this;
+    }
+
+  ~FloatQRP (void) { }
+
+  void init (const FloatMatrix&, QR::type = QR::std);
+
+  PermMatrix P (void) const { return p; }
+
+  FloatColumnVector Pvec (void) const;
+
+  friend std::ostream&  operator << (std::ostream&, const FloatQRP&);
+
+protected:
+
+  PermMatrix p;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatSCHUR.cc b/liboctave/floatSCHUR.cc
new file mode 100644
index 0000000..053f371
--- /dev/null
+++ b/liboctave/floatSCHUR.cc
@@ -0,0 +1,156 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "floatSCHUR.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgeesx, SGEESX) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     FloatSCHUR::select_function,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, float*, const octave_idx_type&, octave_idx_type&,
+			     float*, float*, float*, const octave_idx_type&,
+			     float&, float&, float*, const octave_idx_type&,
+			     octave_idx_type*, const octave_idx_type&, octave_idx_type*, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+static octave_idx_type
+select_ana (const float& a, const float&)
+{
+   return (a < 0.0);
+}
+
+static octave_idx_type
+select_dig (const float& a, const float& b)
+{
+  return (hypot (a, b) < 1.0);
+}
+
+octave_idx_type
+FloatSCHUR::init (const FloatMatrix& a, const std::string& ord, bool calc_unitary)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) ("FloatSCHUR requires square matrix");
+      return -1;
+    }
+
+  // Workspace requirements may need to be fixed if any of the
+  // following change.
+
+  char jobvs;
+  char sense = 'N';
+  char sort = 'N';
+
+  if (calc_unitary)
+    jobvs = 'V';
+  else
+    jobvs = 'N';
+
+  char ord_char = ord.empty () ? 'U' : ord[0];
+
+  if (ord_char == 'A' || ord_char == 'D' || ord_char == 'a' || ord_char == 'd')
+    sort = 'S';
+
+  if (ord_char == 'A' || ord_char == 'a')
+    selector = select_ana;
+  else if (ord_char == 'D' || ord_char == 'd')
+    selector = select_dig;
+  else
+    selector = 0;
+
+  octave_idx_type n = a_nc;
+  octave_idx_type lwork = 8 * n;
+  octave_idx_type liwork = 1;
+  octave_idx_type info;
+  octave_idx_type sdim;
+  float rconde;
+  float rcondv;
+
+  schur_mat = a;
+
+  if (calc_unitary)
+    unitary_mat.resize (n, n);
+
+  float *s = schur_mat.fortran_vec ();
+  float *q = unitary_mat.fortran_vec ();
+
+  Array<float> wr (n);
+  float *pwr = wr.fortran_vec ();
+
+  Array<float> wi (n);
+  float *pwi = wi.fortran_vec ();
+
+  Array<float> work (lwork);
+  float *pwork = work.fortran_vec ();
+
+  // BWORK is not referenced for the non-ordered Schur routine.
+  Array<octave_idx_type> bwork ((ord_char == 'N' || ord_char == 'n') ? 0 : n);
+  octave_idx_type *pbwork = bwork.fortran_vec ();
+
+  Array<octave_idx_type> iwork (liwork);
+  octave_idx_type *piwork = iwork.fortran_vec ();
+
+  F77_XFCN (sgeesx, SGEESX, (F77_CONST_CHAR_ARG2 (&jobvs, 1),
+			     F77_CONST_CHAR_ARG2 (&sort, 1),
+			     selector,
+			     F77_CONST_CHAR_ARG2 (&sense, 1),
+			     n, s, n, sdim, pwr, pwi, q, n, rconde, rcondv,
+			     pwork, lwork, piwork, liwork, pbwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  return info;
+}
+
+std::ostream&
+operator << (std::ostream& os, const FloatSCHUR& a)
+{
+  os << a.schur_matrix () << "\n";
+  os << a.unitary_matrix () << "\n";
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatSCHUR.h b/liboctave/floatSCHUR.h
new file mode 100644
index 0000000..0a0f6b3
--- /dev/null
+++ b/liboctave/floatSCHUR.h
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatSCHUR_h)
+#define octave_FloatSCHUR_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "fMatrix.h"
+
+class
+OCTAVE_API
+FloatSCHUR
+{
+public:
+
+  FloatSCHUR (void)
+    : schur_mat (), unitary_mat () { }
+
+  FloatSCHUR (const FloatMatrix& a, const std::string& ord, bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { init (a, ord, calc_unitary); }
+
+  FloatSCHUR (const FloatMatrix& a, const std::string& ord, int& info, 
+	 bool calc_unitary = true)
+    : schur_mat (), unitary_mat () { info = init (a, ord, calc_unitary); }
+
+  FloatSCHUR (const FloatSCHUR& a)
+    : schur_mat (a.schur_mat), unitary_mat (a.unitary_mat) { }
+
+  FloatSCHUR& operator = (const FloatSCHUR& a)
+    {
+      if (this != &a)
+	{
+	  schur_mat = a.schur_mat;
+	  unitary_mat = a.unitary_mat;
+	}
+      return *this;
+    }
+
+  ~FloatSCHUR (void) { }
+
+  FloatMatrix schur_matrix (void) const { return schur_mat; }
+
+  FloatMatrix unitary_matrix (void) const { return unitary_mat; }
+
+  friend std::ostream& operator << (std::ostream& os, const FloatSCHUR& a);
+
+  typedef octave_idx_type (*select_function) (const float&, const float&);
+
+private:
+
+  FloatMatrix schur_mat;
+  FloatMatrix unitary_mat;
+
+  select_function selector;
+
+  octave_idx_type init (const FloatMatrix& a, const std::string& ord, bool calc_unitary);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatSVD.cc b/liboctave/floatSVD.cc
new file mode 100644
index 0000000..40d2861
--- /dev/null
+++ b/liboctave/floatSVD.cc
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "floatSVD.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (sgesvd, SGESVD) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type&, const octave_idx_type&, float*,
+			     const octave_idx_type&, float*, float*,
+			     const octave_idx_type&, float*, const octave_idx_type&,
+			     float*, const octave_idx_type&, octave_idx_type&
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+}
+
+FloatMatrix
+FloatSVD::left_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("FloatSVD: U not computed because type == SVD::sigma_only");
+      return FloatMatrix ();
+    }
+  else
+    return left_sm;
+}
+
+FloatMatrix
+FloatSVD::right_singular_matrix (void) const
+{
+  if (type_computed == SVD::sigma_only)
+    {
+      (*current_liboctave_error_handler)
+	("FloatSVD: V not computed because type == SVD::sigma_only");
+      return FloatMatrix ();
+    }
+  else
+    return right_sm;
+}
+
+octave_idx_type
+FloatSVD::init (const FloatMatrix& a, SVD::type svd_type)
+{
+  octave_idx_type info;
+
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = a.cols ();
+
+  FloatMatrix atmp = a;
+  float *tmp_data = atmp.fortran_vec ();
+
+  octave_idx_type min_mn = m < n ? m : n;
+
+  char jobu = 'A';
+  char jobv = 'A';
+
+  octave_idx_type ncol_u = m;
+  octave_idx_type nrow_vt = n;
+  octave_idx_type nrow_s = m;
+  octave_idx_type ncol_s = n;
+
+  switch (svd_type)
+    {
+    case SVD::economy:
+      jobu = jobv = 'S';
+      ncol_u = nrow_vt = nrow_s = ncol_s = min_mn;
+      break;
+
+    case SVD::sigma_only:
+
+      // Note:  for this case, both jobu and jobv should be 'N', but
+      // there seems to be a bug in dgesvd from Lapack V2.0.  To
+      // demonstrate the bug, set both jobu and jobv to 'N' and find
+      // the singular values of [eye(3), eye(3)].  The result is
+      // [-sqrt(2), -sqrt(2), -sqrt(2)].
+      //
+      // For Lapack 3.0, this problem seems to be fixed.
+
+      jobu = 'N';
+      jobv = 'N';
+      ncol_u = nrow_vt = 1;
+      break;
+
+    default:
+      break;
+    }
+
+  type_computed = svd_type;
+
+  if (! (jobu == 'N' || jobu == 'O'))
+    left_sm.resize (m, ncol_u);
+
+  float *u = left_sm.fortran_vec ();
+
+  sigma.resize (nrow_s, ncol_s);
+  float *s_vec  = sigma.fortran_vec ();
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm.resize (nrow_vt, n);
+
+  float *vt = right_sm.fortran_vec ();
+
+  // Ask DGESVD what the dimension of WORK should be.
+
+  octave_idx_type lwork = -1;
+
+  Array<float> work (1);
+
+  F77_XFCN (sgesvd, SGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  lwork = static_cast<octave_idx_type> (work(0));
+  work.resize (lwork);
+
+  F77_XFCN (sgesvd, SGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
+			     F77_CONST_CHAR_ARG2 (&jobv, 1),
+			     m, n, tmp_data, m, s_vec, u, m, vt,
+			     nrow_vt, work.fortran_vec (), lwork, info
+			     F77_CHAR_ARG_LEN (1)
+			     F77_CHAR_ARG_LEN (1)));
+
+  if (! (jobv == 'N' || jobv == 'O'))
+    right_sm = right_sm.transpose ();
+
+  return info;
+}
+
+std::ostream&
+operator << (std::ostream& os, const FloatSVD& a)
+{
+  os << a.left_singular_matrix () << "\n";
+  os << a.singular_values () << "\n";
+  os << a.right_singular_matrix () << "\n";
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/floatSVD.h b/liboctave/floatSVD.h
new file mode 100644
index 0000000..004a89e
--- /dev/null
+++ b/liboctave/floatSVD.h
@@ -0,0 +1,92 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_FloatSVD_h)
+#define octave_FloatSVD_h 1
+
+#include <iosfwd>
+
+#include "fDiagMatrix.h"
+#include "fMatrix.h"
+#include "dbleSVD.h"
+
+class
+OCTAVE_API
+FloatSVD
+{
+public:
+
+  FloatSVD (void) : sigma (), left_sm (), right_sm () { }
+
+  FloatSVD (const FloatMatrix& a, SVD::type svd_type = SVD::std) { init (a, svd_type); }
+
+  FloatSVD (const FloatMatrix& a, octave_idx_type& info, SVD::type svd_type = SVD::std)
+    {
+      info = init (a, svd_type);
+    }
+
+  FloatSVD (const FloatSVD& a)
+    : type_computed (a.type_computed),
+      sigma (a.sigma), left_sm (a.left_sm), right_sm (a.right_sm) { }
+
+  FloatSVD& operator = (const FloatSVD& a)
+    {
+      if (this != &a)
+	{
+	  type_computed = a.type_computed;
+	  sigma = a.sigma;
+	  left_sm = a.left_sm;
+	  right_sm = a.right_sm;
+	}
+
+      return *this;
+    }
+
+  ~FloatSVD (void) { }
+
+  FloatDiagMatrix singular_values (void) const { return sigma; }
+
+  FloatMatrix left_singular_matrix (void) const;
+
+  FloatMatrix right_singular_matrix (void) const;
+
+  friend std::ostream&  operator << (std::ostream& os, const FloatSVD& a);
+
+private:
+
+  SVD::type type_computed;
+
+  FloatDiagMatrix sigma;
+  FloatMatrix left_sm;
+  FloatMatrix right_sm;
+
+  octave_idx_type init (const FloatMatrix& a, SVD::type svd_type = SVD::std);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/functor.h b/liboctave/functor.h
new file mode 100644
index 0000000..1eb17c4
--- /dev/null
+++ b/liboctave/functor.h
@@ -0,0 +1,81 @@
+/*
+
+Copyright (C) 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_functor_h)
+#define octave_functor_h 1
+
+template <typename RT, typename PT>
+class fcn_ptr
+{
+public:
+  typedef RT (*TYPE) (PT);
+};
+
+template <typename RT, typename PT>
+class functor
+{
+private:
+  typedef typename fcn_ptr<RT, PT>::TYPE fcn_ptr_type;
+  fcn_ptr_type fptr;
+
+public:
+
+  functor (fcn_ptr_type p) : fptr (p) { }
+
+  RT operator () (PT arg) { return fptr (arg); }
+};
+
+template <typename CT, typename RT, typename PT>
+class functor_with_conversion
+{
+private:
+  typedef typename fcn_ptr<RT, PT>::TYPE fcn_ptr_type;
+  fcn_ptr_type fptr;
+
+public:
+
+  functor_with_conversion (fcn_ptr_type p) : fptr (p) { }
+
+  CT operator () (PT arg) { return CT (fptr (arg)); }
+};
+
+template <typename RT, typename PT>
+functor<RT, PT>
+func_ptr (RT (*f) (PT))
+{
+  return functor<RT, PT> (f);
+}
+
+template <typename CT, typename RT, typename PT>
+functor_with_conversion<CT, RT, PT>
+func_ptr_with_conversion (RT (*f) (PT))
+{
+  return functor_with_conversion<CT, RT, PT> (f);
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/getopt.c b/liboctave/getopt.c
new file mode 100644
index 0000000..362d744
--- /dev/null
+++ b/liboctave/getopt.c
@@ -0,0 +1,1001 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland at gnu.org
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
+   	Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc., 51 Franklin
+   Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef	__GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#include <unistd.h>
+#endif	/* GNU C library.  */
+
+#ifdef VMS
+#include <unixlib.h>
+#if HAVE_STRING_H - 0
+#include <string.h>
+#endif
+#endif
+
+#if defined (WIN32) && !defined (__CYGWIN__)
+/* It's not Unix, really.  See?  Capital letters.  */
+#include <stdlib.h>
+#include <windows.h>
+#define getpid() GetCurrentProcessId()
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+   When compiling libc, the _ macro is predefined.  */
+#ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid)	gettext (msgid)
+#else
+# define _(msgid)	(msgid)
+#endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+
+#if defined(__GNU_LIBRARY__) || defined(WIN32)
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define	my_index	strchr
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+	return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+#if !defined (__STDC__) || !__STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+static const char *nonoption_flags;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void store_args (int argc, char *const *argv) __attribute__ ((unused));
+static void
+store_args (int argc, char *const *argv)
+{
+  /* FIXME: This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+text_set_element (__libc_subinit, store_args);
+#endif
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined (__STDC__) && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+	{
+	  /* Bottom segment is the short one.  */
+	  int len = middle - bottom;
+	  register int i;
+
+	  /* Swap it with the top part of the top segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[top - (middle - bottom) + i];
+	      argv[top - (middle - bottom) + i] = tem;
+	    }
+	  /* Exclude the moved bottom segment from further swapping.  */
+	  top -= len;
+	}
+      else
+	{
+	  /* Top segment is the short one.  */
+	  int len = top - middle;
+	  register int i;
+
+	  /* Swap it with the bottom part of the bottom segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[middle + i];
+	      argv[middle + i] = tem;
+	    }
+	  /* Exclude the moved top segment from further swapping.  */
+	  bottom += len;
+	}
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined (__STDC__) && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind = 1;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#ifdef _LIBC
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      /* Bash 2.0 puts a special variable in the environment for each
+	 command it runs, specifying which ARGV elements are the results of
+	 file name wildcard expansion and therefore should not be
+	 considered as options.  */
+      char var[100];
+      sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ());
+      nonoption_flags = getenv (var);
+      if (nonoption_flags == NULL)
+	nonoption_flags_len = 0;
+      else
+	nonoption_flags_len = strlen (nonoption_flags);
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  optarg = NULL;
+
+  if (!__getopt_initialized || optind == 0)
+    {
+      optstring = _getopt_initialize (argc, argv, optstring);
+      optind = 1;		/* Don't scan ARGV[0], the program name.  */
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#ifdef _LIBC
+#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
+		     || (optind < nonoption_flags_len			      \
+			 && nonoption_flags[optind] == '1'))
+#else
+#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+	 moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+	last_nonopt = optind;
+      if (first_nonopt > optind)
+	first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+	{
+	  /* If we have just processed some options following some non-options,
+	     exchange them so that the options come first.  */
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (last_nonopt != optind)
+	    first_nonopt = optind;
+
+	  /* Skip any additional non-options
+	     and extend the range of non-options previously skipped.  */
+
+	  while (optind < argc && NONOPTION_P)
+	    optind++;
+	  last_nonopt = optind;
+	}
+
+      /* The special ARGV-element `--' means premature end of options.
+	 Skip it like a null option,
+	 then exchange with previous non-options as if it were an option,
+	 then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+	{
+	  optind++;
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (first_nonopt == last_nonopt)
+	    first_nonopt = optind;
+	  last_nonopt = argc;
+
+	  optind = argc;
+	}
+
+      /* If we have done all the ARGV-elements, stop the scan
+	 and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+	{
+	  /* Set the next-arg-index to point at the non-options
+	     that we previously skipped, so the caller will digest them.  */
+	  if (first_nonopt != last_nonopt)
+	    optind = first_nonopt;
+	  return -1;
+	}
+
+      /* If we have come to a non-option and did not permute it,
+	 either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+	{
+	  if (ordering == REQUIRE_ORDER)
+	    return -1;
+	  optarg = argv[optind++];
+	  return 1;
+	}
+
+      /* We have found another option-ARGV-element.
+	 Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+		  + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+	/* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+	 or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	if (!strncmp (p->name, nextchar, nameend - nextchar))
+	  {
+	    if ((unsigned int) (nameend - nextchar)
+		== (unsigned int) strlen (p->name))
+	      {
+		/* Exact match found.  */
+		pfound = p;
+		indfound = option_index;
+		exact = 1;
+		break;
+	      }
+	    else if (pfound == NULL)
+	      {
+		/* First nonexact match found.  */
+		pfound = p;
+		indfound = option_index;
+	      }
+	    else
+	      /* Second or later nonexact match found.  */
+	      ambig = 1;
+	  }
+
+      if (ambig && !exact)
+	{
+	  if (opterr)
+	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+		     argv[0], argv[optind]);
+	  nextchar += strlen (nextchar);
+	  optind++;
+	  optopt = 0;
+	  return '?';
+	}
+
+      if (pfound != NULL)
+	{
+	  option_index = indfound;
+	  optind++;
+	  if (*nameend)
+	    {
+	      /* Don't test has_arg with >, because some C compilers don't
+		 allow it to be used on enums.  */
+	      if (pfound->has_arg)
+		optarg = nameend + 1;
+	      else
+		{
+		  if (opterr)
+		   if (argv[optind - 1][1] == '-')
+		    /* --option */
+		    fprintf (stderr,
+		     _("%s: option `--%s' doesn't allow an argument\n"),
+		     argv[0], pfound->name);
+		   else
+		    /* +option or -option */
+		    fprintf (stderr,
+		     _("%s: option `%c%s' doesn't allow an argument\n"),
+		     argv[0], argv[optind - 1][0], pfound->name);
+
+		  nextchar += strlen (nextchar);
+
+		  optopt = pfound->val;
+		  return '?';
+		}
+	    }
+	  else if (pfound->has_arg == 1)
+	    {
+	      if (optind < argc)
+		optarg = argv[optind++];
+	      else
+		{
+		  if (opterr)
+		    fprintf (stderr,
+			   _("%s: option `%s' requires an argument\n"),
+			   argv[0], argv[optind - 1]);
+		  nextchar += strlen (nextchar);
+		  optopt = pfound->val;
+		  return optstring[0] == ':' ? ':' : '?';
+		}
+	    }
+	  nextchar += strlen (nextchar);
+	  if (longind != NULL)
+	    *longind = option_index;
+	  if (pfound->flag)
+	    {
+	      *(pfound->flag) = pfound->val;
+	      return 0;
+	    }
+	  return pfound->val;
+	}
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+	 or the option starts with '--' or is not a valid short
+	 option, then it's an error.
+	 Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+	  || my_index (optstring, *nextchar) == NULL)
+	{
+	  if (opterr)
+	    {
+	      if (argv[optind][1] == '-')
+		/* --option */
+		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+			 argv[0], nextchar);
+	      else
+		/* +option or -option */
+		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+			 argv[0], argv[optind][0], nextchar);
+	    }
+	  nextchar = (char *) "";
+	  optind++;
+	  optopt = 0;
+	  return '?';
+	}
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+	if (opterr)
+	  {
+	    if (posixly_correct)
+	      /* 1003.2 specifies the format of this message.  */
+	      fprintf (stderr, _("%s: illegal option -- %c\n"),
+		       argv[0], c);
+	    else
+	      fprintf (stderr, _("%s: invalid option -- %c\n"),
+		       argv[0], c);
+	  }
+	optopt = c;
+	return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+	char *nameend;
+	const struct option *p;
+	const struct option *pfound = NULL;
+	int exact = 0;
+	int ambig = 0;
+	int indfound = 0;
+	int option_index;
+
+	/* This is an option that requires an argument.  */
+	if (*nextchar != '\0')
+	  {
+	    optarg = nextchar;
+	    /* If we end this ARGV-element by taking the rest as an arg,
+	       we must advance to the next element now.  */
+	    optind++;
+	  }
+	else if (optind == argc)
+	  {
+	    if (opterr)
+	      {
+		/* 1003.2 specifies the format of this message.  */
+		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+			 argv[0], c);
+	      }
+	    optopt = c;
+	    if (optstring[0] == ':')
+	      c = ':';
+	    else
+	      c = '?';
+	    return c;
+	  }
+	else
+	  /* We already incremented `optind' once;
+	     increment it again when taking next ARGV-elt as argument.  */
+	  optarg = argv[optind++];
+
+	/* optarg is now the argument, see if it's in the
+	   table of longopts.  */
+
+	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+	  /* Do nothing.  */ ;
+
+	/* Test all long options for either exact match
+	   or abbreviated matches.  */
+	for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	  if (!strncmp (p->name, nextchar, nameend - nextchar))
+	    {
+	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+		{
+		  /* Exact match found.  */
+		  pfound = p;
+		  indfound = option_index;
+		  exact = 1;
+		  break;
+		}
+	      else if (pfound == NULL)
+		{
+		  /* First nonexact match found.  */
+		  pfound = p;
+		  indfound = option_index;
+		}
+	      else
+		/* Second or later nonexact match found.  */
+		ambig = 1;
+	    }
+	if (ambig && !exact)
+	  {
+	    if (opterr)
+	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+		       argv[0], argv[optind]);
+	    nextchar += strlen (nextchar);
+	    optind++;
+	    return '?';
+	  }
+	if (pfound != NULL)
+	  {
+	    option_index = indfound;
+	    if (*nameend)
+	      {
+		/* Don't test has_arg with >, because some C compilers don't
+		   allow it to be used on enums.  */
+		if (pfound->has_arg)
+		  optarg = nameend + 1;
+		else
+		  {
+		    if (opterr)
+		      fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+			       argv[0], pfound->name);
+
+		    nextchar += strlen (nextchar);
+		    return '?';
+		  }
+	      }
+	    else if (pfound->has_arg == 1)
+	      {
+		if (optind < argc)
+		  optarg = argv[optind++];
+		else
+		  {
+		    if (opterr)
+		      fprintf (stderr,
+			       _("%s: option `%s' requires an argument\n"),
+			       argv[0], argv[optind - 1]);
+		    nextchar += strlen (nextchar);
+		    return optstring[0] == ':' ? ':' : '?';
+		  }
+	      }
+	    nextchar += strlen (nextchar);
+	    if (longind != NULL)
+	      *longind = option_index;
+	    if (pfound->flag)
+	      {
+		*(pfound->flag) = pfound->val;
+		return 0;
+	      }
+	    return pfound->val;
+	  }
+	  nextchar = NULL;
+	  return 'W';	/* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+	if (temp[2] == ':')
+	  {
+	    /* This is an option that accepts an argument optionally.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		optind++;
+	      }
+	    else
+	      optarg = NULL;
+	    nextchar = NULL;
+	  }
+	else
+	  {
+	    /* This is an option that requires an argument.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		/* If we end this ARGV-element by taking the rest as an arg,
+		   we must advance to the next element now.  */
+		optind++;
+	      }
+	    else if (optind == argc)
+	      {
+		if (opterr)
+		  {
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr,
+			   _("%s: option requires an argument -- %c\n"),
+			   argv[0], c);
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = '?';
+	      }
+	    else
+	      /* We already incremented `optind' once;
+		 increment it again when taking next ARGV-elt as argument.  */
+	      optarg = argv[optind++];
+	    nextchar = NULL;
+	  }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+			   (const struct option *) 0,
+			   (int *) 0,
+			   0);
+}
+
+#endif	/* Not ELIDE_CODE.  */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/liboctave/getopt.h b/liboctave/getopt.h
new file mode 100644
index 0000000..da4ca9f
--- /dev/null
+++ b/liboctave/getopt.h
@@ -0,0 +1,139 @@
+/* Declarations for getopt.
+   Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc., 51 Franklin
+   Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#if !defined(WIN32) || (defined(_DLL) && !defined(_IMPORT)) || !defined(_DLL)
+#define DllImport
+#else
+#define DllImport __declspec(dllimport)
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern DllImport char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern DllImport int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern DllImport int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern DllImport int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/liboctave/getopt1.c b/liboctave/getopt1.c
new file mode 100644
index 0000000..5be411d
--- /dev/null
+++ b/liboctave/getopt1.c
@@ -0,0 +1,189 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc., 51 Franklin
+   Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef	NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif	/* Not ELIDE_CODE.  */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+	{"add", 1, 0, 0},
+	{"append", 0, 0, 0},
+	{"delete", 1, 0, 0},
+	{"verbose", 0, 0, 0},
+	{"create", 0, 0, 0},
+	{"file", 1, 0, 0},
+	{0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+		       long_options, &option_index);
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case 0:
+	  printf ("option %s", long_options[option_index].name);
+	  if (optarg)
+	    printf (" with arg %s", optarg);
+	  printf ("\n");
+	  break;
+
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case 'd':
+	  printf ("option d with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/liboctave/glob-match.cc b/liboctave/glob-match.cc
new file mode 100644
index 0000000..0e028e4
--- /dev/null
+++ b/liboctave/glob-match.cc
@@ -0,0 +1,136 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <fnmatch.h>
+#include <glob.h>
+
+#include <iostream>
+#include <string>
+
+#include "file-stat.h"
+#include "glob-match.h"
+#include "str-vec.h"
+
+bool
+glob_match::match (const std::string& s)
+{
+  int npat = pat.length ();
+
+  const char *str = s.c_str ();
+
+  int fnmatch_flags = 0;
+
+  if (flags & pathname)
+    fnmatch_flags |= FNM_PATHNAME;
+
+  if (flags & noescape)
+    fnmatch_flags |= FNM_NOESCAPE;
+
+  if (flags & period)
+    fnmatch_flags |= FNM_PERIOD;
+
+  for (int i = 0; i < npat; i++)
+    if (fnmatch (pat(i).c_str (), str, fnmatch_flags) != FNM_NOMATCH)
+      return true;
+
+  return false;
+}
+
+Array<bool>
+glob_match::match (const string_vector& s)
+{
+  int n = s.length ();
+
+  Array<bool> retval (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = match (s[i]);
+
+  return retval;
+}
+
+static bool
+single_match_exists (const std::string& file)
+{
+  file_stat s (file);
+
+  return s.exists ();
+}
+
+string_vector
+glob_match::glob (void)
+{
+  string_vector retval;
+
+  int npat = pat.length ();
+
+  int k = 0;
+
+  for (int i = 0; i < npat; i++)
+    {
+      std::string xpat = pat(i);
+
+      if (! xpat.empty ())
+	{
+	  glob_t glob_info;
+
+	  int err = ::glob (xpat.c_str (), GLOB_NOSORT, 0, &glob_info);
+
+	  if (! err)
+	    {
+	      int n = glob_info.gl_pathc;
+
+	      const char * const *matches = glob_info.gl_pathv;
+
+	      // FIXME -- we shouldn't have to check to see if
+	      // a single match exists, but it seems that glob() won't
+	      // check for us unless the pattern contains globbing
+	      // characters.  Hmm.
+
+	      if (n > 1
+		  || (n == 1
+		      && single_match_exists (std::string (matches[0]))))
+		{
+		  retval.resize (k+n);
+
+		  for (int j = 0; j < n; j++)
+		    retval[k++] = matches[j];
+		}
+
+	      globfree (&glob_info);
+	    }
+	}
+    }
+
+  return retval.sort ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/glob-match.h b/liboctave/glob-match.h
new file mode 100644
index 0000000..486f6a5
--- /dev/null
+++ b/liboctave/glob-match.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_glob_match_h)
+#define octave_glob_match_h 1
+
+#include <string>
+
+#include "Array.h"
+#include "str-vec.h"
+
+class
+OCTAVE_API
+glob_match
+{
+public:
+
+  enum opts
+    {
+      pathname = 1,  // No wildcard can ever match `/'.
+      noescape = 2,  // Backslashes don't quote special chars.
+      period = 4     // Leading `.' is matched only explicitly.
+   };
+
+  glob_match (const std::string& p,
+	      unsigned int f = pathname|noescape|period)
+    : pat (p), flags (f) { }
+
+  glob_match (const string_vector& p = string_vector (),
+	      unsigned int f = pathname|noescape|period)
+    : pat (p), flags (f) { }
+
+  glob_match (const glob_match& gm) : pat (gm.pat), flags (gm.flags) { }
+
+  glob_match& operator = (const glob_match& gm)
+    {
+      if (this != &gm)
+	{
+	  pat = gm.pat;
+	  flags = gm.flags;
+	}
+      return *this;
+    }
+
+  ~glob_match (void) { }
+
+  void set_pattern (const std::string& p) { pat = p; }
+
+  void set_pattern (const string_vector& p) { pat = p; }
+
+  bool match (const std::string&);
+
+  Array<bool> match (const string_vector&);
+
+  string_vector glob (void);
+
+private:
+
+  // Globbing pattern(s).
+  string_vector pat;
+
+  // Option flags.
+  unsigned int flags;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/idx-vector.cc b/liboctave/idx-vector.cc
new file mode 100644
index 0000000..61b12be
--- /dev/null
+++ b/liboctave/idx-vector.cc
@@ -0,0 +1,645 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <iostream>
+
+#include "idx-vector.h"
+#include "Array.h"
+#include "Sparse.h"
+#include "Range.h"
+
+#include "oct-locbuf.h"
+#include "lo-error.h"
+#include "lo-mappers.h"
+
+static void
+gripe_invalid_index (void)
+{
+  (*current_liboctave_error_handler)
+    ("subscript indices must be either positive integers or logicals.");
+}
+
+static void
+gripe_invalid_range (void)
+{
+  (*current_liboctave_error_handler)
+    ("invalid range used as index.");
+}
+
+static void
+gripe_index_out_of_range (void)
+{
+  (*current_liboctave_error_handler)
+    ("internal error: idx_vector index out of range.");
+}
+
+DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_colon_rep);
+
+idx_vector::idx_colon_rep::idx_colon_rep (char c)
+{
+  if (c != ':')
+    {
+      (*current_liboctave_error_handler)
+        ("internal error: invalid character converted to idx_vector. Must be ':'.");
+      err = true;
+    }
+}
+
+octave_idx_type
+idx_vector::idx_colon_rep::checkelem (octave_idx_type i) const
+{
+  if (i < 0)
+    {
+      gripe_index_out_of_range ();
+      return 0;
+    }
+  else
+    return i;
+}
+
+std::ostream& 
+idx_vector::idx_colon_rep::print (std::ostream& os) const
+{
+  return os << ":";
+}
+
+DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_range_rep);
+
+idx_vector::idx_range_rep::idx_range_rep (octave_idx_type _start, octave_idx_type _limit,
+                                          octave_idx_type _step)
+ : start(_start), len (_step ? (_limit - _start) / _step : -1), step (_step)
+{
+  if (len < 0)
+    {
+      gripe_invalid_range ();
+      err = true;
+    }
+  else if (start < 0)
+    {
+      gripe_invalid_index ();
+      err = true;
+    }
+}
+
+idx_vector::idx_range_rep::idx_range_rep (const Range& r)
+  : start (0), len (r.nelem ()), step (1)
+{
+  if (len < 0)
+    {
+      gripe_invalid_range ();
+      err = true;
+    }
+  else if (len > 0)
+    {
+      if (r.all_elements_are_ints ())
+        {    
+          start = static_cast<octave_idx_type> (r.base ()) - 1;
+          step = static_cast<octave_idx_type> (r.inc ());
+          if (start < 0 || (step < 0 && start + (len-1)*step < 0))
+            {
+              gripe_invalid_index ();
+              err = true;
+            }
+        }
+      else
+        {
+          gripe_invalid_index ();
+          err = true;
+        }
+    }
+}
+
+octave_idx_type
+idx_vector::idx_range_rep::checkelem (octave_idx_type i) const
+{
+  if (i < 0 || i >= len)
+    {
+      gripe_index_out_of_range ();
+      return 0;
+    }
+  else
+    return start + i*step;
+}
+
+idx_vector::idx_base_rep *
+idx_vector::idx_range_rep::sort_uniq_clone (bool)
+{
+  if (step < 0)
+    return new idx_range_rep (start + (len - 1)*step, len, -step, DIRECT);
+  else
+    {
+      count++;
+      return this;
+    }
+}
+
+std::ostream& 
+idx_vector::idx_range_rep::print (std::ostream& os) const
+{
+  os << start << ':' << step << ':' << start + len*step;
+  return os;
+}
+
+inline octave_idx_type
+convert_index (octave_idx_type i, bool& conv_error, 
+               octave_idx_type& ext)
+{
+  if (i <= 0) 
+    conv_error = true;
+  if (ext < i) ext = i;
+  return i - 1;
+}
+
+inline octave_idx_type
+convert_index (double x, bool& conv_error, octave_idx_type& ext)
+{
+  octave_idx_type i = static_cast<octave_idx_type> (x);
+  if (static_cast<double> (i) != x)
+    conv_error = true;
+
+  return convert_index (i, conv_error, ext);
+}
+
+inline octave_idx_type
+convert_index (float x, bool& conv_error, octave_idx_type& ext)
+{
+  return convert_index (static_cast<double> (x), conv_error, ext);
+}
+
+template <class T>
+inline octave_idx_type
+convert_index (octave_int<T> x, bool& conv_error, 
+               octave_idx_type& ext)
+{
+  octave_idx_type i = octave_int<octave_idx_type> (x).value ();
+  return convert_index (i, conv_error, ext);
+}
+
+DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_scalar_rep);
+
+template <class T>
+idx_vector::idx_scalar_rep::idx_scalar_rep (T x)
+{
+  octave_idx_type dummy;
+  data = convert_index (x, err, dummy);
+  if (err) gripe_invalid_index ();
+}
+
+idx_vector::idx_scalar_rep::idx_scalar_rep (octave_idx_type i) 
+  : data (i)
+{
+  if (data < 0) 
+    {
+      gripe_invalid_index ();
+      err = true;
+    }
+}
+
+octave_idx_type
+idx_vector::idx_scalar_rep::checkelem (octave_idx_type i) const
+{
+  if (i != 0) gripe_index_out_of_range ();
+  return data;
+}
+
+std::ostream& idx_vector::idx_scalar_rep::print (std::ostream& os) const
+{
+  return os << data;
+}
+
+DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_vector_rep);
+
+template <class T>
+idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>& nda)
+  : data (0), len (nda.numel ()), ext (0), aowner (0), orig_dims (nda.dims ())
+{
+  if (len != 0)
+    {
+      octave_idx_type *d = new octave_idx_type[len];
+      for (octave_idx_type i = 0; i < len; i++)
+        d[i] = convert_index (nda.xelem (i), err, ext);
+      data = d;
+
+      if (err) gripe_invalid_index ();
+    }
+}
+
+// Note that this makes a shallow copy of the index array.
+
+idx_vector::idx_vector_rep::idx_vector_rep (const Array<octave_idx_type>& inda)
+  : data (inda.data ()), len (inda.numel ()), ext (0), 
+  aowner (new Array<octave_idx_type> (inda)), orig_dims (inda.dims ())
+{
+  if (len != 0)
+    {
+      octave_idx_type max = -1;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          octave_idx_type k = inda.xelem (i);
+          if (k < 0) 
+            err = true;
+          else if (k > max) 
+            max = k;
+        }
+
+      ext = max + 1;
+
+      if (err) gripe_invalid_index ();
+    }
+}
+
+idx_vector::idx_vector_rep::idx_vector_rep (bool b)
+  : data (0), len (b ? 1 : 0), ext (0), aowner (0), orig_dims (len, len)
+{
+  if (len != 0)
+    {
+      octave_idx_type *d = new octave_idx_type [1];
+      d[0] = 0;
+      data = d;
+      ext = 1;
+    }
+}
+
+idx_vector::idx_vector_rep::idx_vector_rep (const Array<bool>& bnda)
+  : data (0), len (0), ext (0), aowner (0), orig_dims ()
+{
+  for (octave_idx_type i = 0, l = bnda.numel (); i < l; i++)
+    if (bnda.xelem (i)) len++;
+
+  const dim_vector dv = bnda.dims ();
+
+  if (! dv.all_zero ())
+    orig_dims = ((dv.length () == 2 && dv(0) == 1) 
+                 ? dim_vector (1, len) : dim_vector (len, 1));
+
+  if (len != 0)
+    {
+      octave_idx_type *d = new octave_idx_type [len];
+
+      octave_idx_type ntot = bnda.length ();
+
+      octave_idx_type k = 0;
+      for (octave_idx_type i = 0; i < ntot; i++)
+	if (bnda.xelem (i)) d[k++] = i;
+
+      data = d;
+
+      ext = d[k-1] + 1;
+    }
+}
+
+idx_vector::idx_vector_rep::idx_vector_rep (const Sparse<bool>& bnda)
+  : data (0), len (0), ext (0), aowner (0), orig_dims ()
+{
+  for (octave_idx_type i = 0, l = bnda.nnz (); i < l; i++)
+    if (bnda.data (i)) len++;
+
+  dim_vector dv = bnda.dims ();
+
+  orig_dims = ((dv.length () == 2 && dv(0) == 1)
+	       ? dim_vector (1, len) : orig_dims = dim_vector (len, 1));
+
+  if (len != 0)
+    {
+      octave_idx_type *d = new octave_idx_type [len];
+
+      octave_idx_type nnz = bnda.nnz ();
+
+      octave_idx_type k = 0;
+      // FIXME: I hope this is OK, i.e. the element iterated this way are correctly ordered.
+      for (octave_idx_type i = 0; i < nnz; i++)
+        {
+          if (bnda.data (i)) 
+            d[k++] = bnda.cidx (i) + bnda.rows () * bnda.ridx (i);
+        }
+
+      data = d;
+
+      ext = d[k-1] + 1;
+    }
+}
+
+idx_vector::idx_vector_rep::~idx_vector_rep (void)
+{ 
+  if (aowner) 
+    delete aowner;
+  else
+    delete [] data; 
+}
+
+octave_idx_type
+idx_vector::idx_vector_rep::checkelem (octave_idx_type n) const
+{
+  if (n < 0 || n >= len)
+    {
+      gripe_invalid_index ();
+      return 0;
+    }
+
+  return xelem (n);
+}
+
+idx_vector::idx_base_rep *
+idx_vector::idx_vector_rep::sort_uniq_clone (bool uniq)
+{
+  octave_idx_type *new_data = new octave_idx_type[len];
+  std::copy (data, data + len, new_data);
+  std::sort (new_data, new_data + len);
+  octave_idx_type new_len;
+  if (uniq)
+    new_len = std::unique (new_data, new_data + len) - new_data;
+  else 
+    new_len = len;
+
+  return new idx_vector_rep (new_data, new_len, ext, orig_dims, DIRECT);
+}
+
+std::ostream& 
+idx_vector::idx_vector_rep::print (std::ostream& os) const
+{
+  os << '[';
+  for (octave_idx_type ii = 0; ii < len - 1; ii++)
+    os << data[ii] << ',' << ' ';
+  if (len > 0) os << data[len-1]; os << ']';
+
+  return os;
+}
+
+const idx_vector idx_vector::colon (new idx_vector::idx_colon_rep ());
+
+bool idx_vector::maybe_reduce (octave_idx_type n, const idx_vector& j,
+                               octave_idx_type nj)
+{
+  bool reduced = false;
+
+  // Empty index always reduces.
+  if (rep->length (n) == 0)
+    {
+      *this = idx_vector ();
+      return true;
+    }
+
+  // Possibly skip singleton dims.
+  if (n == 1 && rep->is_colon_equiv (n))
+    {
+      *this = j;
+      return true;
+    }
+
+  if (nj == 1 && j.is_colon_equiv (nj))
+    return true;
+
+  switch (j.idx_class ())
+    {
+    case class_colon:
+      if (rep->is_colon_equiv (n))
+        {
+          // (:,:) reduces to (:)
+          *this = colon;
+          reduced = true;
+        }
+      else if (rep->idx_class () == class_scalar)
+        {
+          // (i,:) reduces to a range.
+          idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+          octave_idx_type k = r->get_data ();
+          *this = new idx_range_rep (k, nj, n, DIRECT);
+          reduced = true;
+        }
+      break;
+    case class_range:
+      if (rep->is_colon_equiv (n))
+        {
+          // (:,i:j) reduces to a range (the step must be 1)
+          idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep);
+          if (rj->get_step () == 1)
+            {
+              octave_idx_type s = rj->get_start (), l = rj->length (nj);
+              *this = new idx_range_rep (s * n, l * n, 1, DIRECT);
+              reduced = true;
+            }
+        }
+      else if (rep->idx_class () == class_scalar)
+        {
+          // (k,i:d:j) reduces to a range.
+          idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+          idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep);
+          octave_idx_type k = r->get_data ();
+          octave_idx_type s = rj->get_start (), l = rj->length (nj);
+          octave_idx_type t = rj->get_step ();
+          *this = new idx_range_rep (n * s + k, l, n * t, DIRECT);
+          reduced = true;
+        }
+      break;
+    case class_scalar:
+      switch (rep->idx_class ())
+        {
+        case class_scalar:
+          {
+            // (i,j) reduces to a single index.
+            idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+            idx_scalar_rep * rj = dynamic_cast<idx_scalar_rep *> (j.rep);
+            octave_idx_type k = r->get_data () + n * rj->get_data ();
+            *this = new idx_scalar_rep (k, DIRECT);
+            reduced = true;
+          }
+          break;
+        case class_range:
+          {
+            // (i:d:j,k) reduces to a range.
+            idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+            idx_scalar_rep * rj = dynamic_cast<idx_scalar_rep *> (j.rep);
+            octave_idx_type s = r->get_start (), l = r->length (nj);
+            octave_idx_type t = r->get_step ();
+            octave_idx_type k = rj->get_data ();
+            *this = new idx_range_rep (n * k + s, l, t, DIRECT);
+            reduced = true;
+          }
+          break;
+        case class_colon:
+          {
+            // (:,k) reduces to a range.
+            idx_scalar_rep * rj = dynamic_cast<idx_scalar_rep *> (j.rep);
+            octave_idx_type k = rj->get_data ();
+            *this = new idx_range_rep (n * k, n, 1, DIRECT);
+            reduced = true;
+          }
+          break;
+        default:
+          break;
+        }
+      break;
+    default:
+      break;
+    }
+
+  return reduced;
+}
+
+bool
+idx_vector::is_cont_range (octave_idx_type n,
+			   octave_idx_type& l, octave_idx_type& u) const
+{
+  bool res = false;
+  switch (rep->idx_class ())
+    {
+    case class_colon:
+      l = 0; u = n;
+      res = true;
+      break;
+    case class_range:
+      {
+        idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+        if (r->get_step () == 1)
+          {
+            l = r->get_start ();
+            u = l + r->length (n);
+            res = true;
+          }
+      }
+      break;
+    case class_scalar:
+      {
+        idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+        l = r->get_data ();
+        u = l + 1;
+        res = true;
+      }
+      break;
+    default:
+      break;
+    }
+
+  return res;
+}
+
+idx_vector
+idx_vector::complement (octave_idx_type n) const
+{
+  OCTAVE_LOCAL_BUFFER_INIT (bool, left, n, true);
+
+  octave_idx_type cnt = n;
+
+  for (octave_idx_type i = 0, len = length (); i < len; i++)
+    { 
+      octave_idx_type k = xelem (i);
+      if (k < n && left[k])
+        {
+          left[k] = false;
+          cnt--;
+        }
+    }
+
+  octave_idx_type len = cnt, *data = new octave_idx_type[len];
+  for (octave_idx_type i = 0, j = 0; i < n; i++)
+    if (left[i]) data[j++] = i;
+
+  return new idx_vector_rep (data, len, 
+                             len ? data[len-1]+1 : 0, 
+                             dim_vector (1, len), DIRECT);
+}
+
+bool
+idx_vector::is_permutation (octave_idx_type n) const
+{
+  bool retval = false;
+
+  if (is_colon_equiv (n))
+    retval = true;
+  else if (length (n) == n && extent(n) == n)
+    {
+      OCTAVE_LOCAL_BUFFER_INIT (bool, left, n, true);
+
+      retval = true;
+
+      for (octave_idx_type i = 0, len = length (); i < len; i++)
+        { 
+          octave_idx_type k = xelem (i);
+          if (left[k])
+              left[k] = false;
+          else
+            {
+              retval = false;
+              break;
+            }
+        }
+
+    }
+
+  return retval;
+}
+
+octave_idx_type 
+idx_vector::freeze (octave_idx_type z_len, const char *, bool resize_ok)
+{
+  if (! resize_ok && extent (z_len) > z_len)
+    {
+      (*current_liboctave_error_handler)
+        ("invalid matrix index = %d", extent (z_len));
+      rep->err = true;
+      chkerr ();
+    }
+
+  return length (z_len);
+}
+
+octave_idx_type 
+idx_vector::ones_count () const
+{
+  octave_idx_type n = 0;
+  if (is_colon ())
+    n = 1;
+  else
+    for (octave_idx_type i = 0; i < length (1); i++)
+      if (xelem (i) == 0) n++;
+  return n;
+}
+
+// Instantiate the octave_int constructors we want.
+#define INSTANTIATE_SCALAR_VECTOR_REP_CONST(T) \
+  template OCTAVE_API idx_vector::idx_scalar_rep::idx_scalar_rep (T); \
+  template OCTAVE_API idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>&);
+
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (float)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (double)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int8)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int16)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int32)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int64)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint8)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint16)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint32)
+INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint64)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/idx-vector.h b/liboctave/idx-vector.h
new file mode 100644
index 0000000..1d3cea1
--- /dev/null
+++ b/liboctave/idx-vector.h
@@ -0,0 +1,824 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_idx_vector_h)
+#define octave_idx_vector_h 1
+
+#include <cassert>
+
+#include <algorithm>
+#include <iosfwd>
+
+#include "dim-vector.h"
+#include "oct-inttypes.h"
+#include "oct-alloc.h"
+
+template<class T> class Array;
+template<class T> class Sparse;
+class Range;
+
+// Design rationale:
+// idx_vector is a reference-counting, polymorphic pointer, that can contain
+// 4 types of index objects: a magic colon, a range, a scalar, or an index vector.
+// Polymorphic methods for single element access are provided, as well as
+// templates implementing "early dispatch", i.e. hoisting the checks for index
+// type out of loops.
+
+class
+OCTAVE_API
+idx_vector
+{
+public:
+  
+  enum idx_class_type
+    {
+      class_invalid = -1,
+      class_colon = 0,
+      class_range,
+      class_scalar,
+      class_vector
+    };
+
+private:
+
+  class OCTAVE_API idx_base_rep
+  {
+  public:
+    idx_base_rep (void) : count (1), err (false) { }
+
+    virtual ~idx_base_rep (void) { }
+
+    // Non-range-checking element query.
+    virtual octave_idx_type xelem (octave_idx_type i) const = 0;
+
+    // Range-checking element query.
+    virtual octave_idx_type checkelem (octave_idx_type i) const = 0;
+
+    // Length of the index vector.
+    virtual octave_idx_type length (octave_idx_type n) const = 0;
+
+    // The maximum index + 1. The actual dimension is passed in.
+    virtual octave_idx_type extent (octave_idx_type n) const = 0;
+
+    // Index class.
+    virtual idx_class_type idx_class (void) const { return class_invalid; }
+
+    // Sorts, maybe uniqifies, and returns a clone object pointer.
+    virtual idx_base_rep *sort_uniq_clone (bool uniq = false) = 0;
+
+    // Checks whether the index is colon or a range equivalent to colon.
+    virtual bool is_colon_equiv (octave_idx_type) const
+      { return false; }
+
+    // The original dimensions of this object (used when subscribing by matrices).
+    virtual dim_vector orig_dimensions (void) const
+      { return dim_vector (); }
+
+    // i/o
+    virtual std::ostream& print (std::ostream& os) const = 0;
+
+    int count;
+
+    bool err;
+
+  private:
+
+    // No copying!
+    idx_base_rep (const idx_base_rep&);
+  };
+
+  // The magic colon index.
+  class OCTAVE_API idx_colon_rep : public idx_base_rep
+  {
+  public:
+    idx_colon_rep (void) { }
+
+    idx_colon_rep (char c);
+
+    octave_idx_type xelem (octave_idx_type i) const
+      { return i; }
+
+    octave_idx_type checkelem (octave_idx_type i) const;
+
+    octave_idx_type length (octave_idx_type n) const
+      { return n; }
+
+    octave_idx_type extent (octave_idx_type n) const
+      { return n; }
+
+    idx_class_type idx_class (void) const { return class_colon; }
+
+    idx_base_rep *sort_uniq_clone (bool = false) 
+      { count++; return this; }
+
+    bool is_colon_equiv (octave_idx_type) const
+      { return true; }
+
+    std::ostream& print (std::ostream& os) const;
+
+  private:
+
+    DECLARE_OCTAVE_ALLOCATOR
+
+    // No copying!
+    idx_colon_rep (const idx_colon_rep& idx);
+  };
+
+  // To distinguish the "direct" constructors that blindly trust the data.
+  enum direct { DIRECT };
+
+  // The integer range index.
+  class OCTAVE_API idx_range_rep : public idx_base_rep
+  {
+  public:
+    idx_range_rep (octave_idx_type _start, octave_idx_type _len,
+                   octave_idx_type _step, direct) 
+      : idx_base_rep (), start(_start), len(_len), step(_step) { }
+
+    idx_range_rep (void) 
+      : start(0), len(0), step(1) { }
+
+    // Zero-based constructor.
+    idx_range_rep (octave_idx_type _start, octave_idx_type _limit,
+                   octave_idx_type _step); 
+
+    idx_range_rep (const Range&);
+
+    octave_idx_type xelem (octave_idx_type i) const
+      { return start + i * step; }
+
+    octave_idx_type checkelem (octave_idx_type i) const;
+
+    octave_idx_type length (octave_idx_type) const
+      { return len; }
+
+    octave_idx_type extent (octave_idx_type n) const
+      { return len ? std::max (n, (start + 1 + (step < 0 ? 0 : step * (len - 1)))) : n; }
+
+    idx_class_type idx_class (void) const { return class_range; }
+
+    idx_base_rep *sort_uniq_clone (bool uniq = false);
+
+    bool is_colon_equiv (octave_idx_type n) const
+      { return start == 0 && step == 1 && len == n; }
+
+    dim_vector orig_dimensions (void) const
+      { return dim_vector (1, len); }
+
+    octave_idx_type get_start (void) const { return start; }
+
+    octave_idx_type get_step (void) const { return step; }
+
+    std::ostream& print (std::ostream& os) const;
+
+  private:
+
+    DECLARE_OCTAVE_ALLOCATOR
+
+    // No copying!
+    idx_range_rep (const idx_range_rep& idx);
+
+    octave_idx_type start, len, step;
+
+  };
+
+  // The integer scalar index.
+  class OCTAVE_API idx_scalar_rep : public idx_base_rep
+  {
+  public:
+    idx_scalar_rep (octave_idx_type i, direct)
+      : data (i) { }
+
+    idx_scalar_rep (void)
+      : data (0) { }
+
+    // Zero-based constructor.
+    idx_scalar_rep (octave_idx_type i);
+
+    template <class T>
+    idx_scalar_rep (T x);
+
+    octave_idx_type xelem (octave_idx_type) const
+      { return data; }
+
+    octave_idx_type checkelem (octave_idx_type i) const;
+
+    octave_idx_type length (octave_idx_type) const
+      { return 1; }
+
+    octave_idx_type extent (octave_idx_type n) const
+      { return std::max (n, data + 1); }
+
+    idx_class_type idx_class (void) const { return class_scalar; }
+
+    idx_base_rep *sort_uniq_clone (bool = false)
+      { count++; return this; }
+
+    bool is_colon_equiv (octave_idx_type n) const
+      { return n == 1 && data == 0; }
+
+    dim_vector orig_dimensions (void) const
+      { return dim_vector (1, 1); }
+
+    octave_idx_type get_data (void) const { return data; }
+
+    std::ostream& print (std::ostream& os) const;
+
+  private:
+
+    DECLARE_OCTAVE_ALLOCATOR
+
+    // No copying!
+    idx_scalar_rep (const idx_scalar_rep& idx);
+
+    octave_idx_type data;
+
+  };
+
+  // The integer vector index.
+  class OCTAVE_API idx_vector_rep : public idx_base_rep
+  {
+  public:
+    // Direct constructor.
+    idx_vector_rep (octave_idx_type *_data, octave_idx_type _len, 
+                    octave_idx_type _ext, const dim_vector& od, direct)
+      : data (_data), len (_len), ext (_ext), aowner (0), orig_dims (od) { }
+
+    idx_vector_rep (void) 
+      : data (0), len (0), aowner (0)
+      { }
+
+    // Zero-based constructor.
+    idx_vector_rep (const Array<octave_idx_type>& inda);
+
+    template <class T>
+    idx_vector_rep (const Array<T>&);
+
+    idx_vector_rep (bool);
+
+    idx_vector_rep (const Array<bool>&);
+
+    idx_vector_rep (const Sparse<bool>&);
+
+    ~idx_vector_rep (void);
+
+    octave_idx_type xelem (octave_idx_type i) const
+      { return data[i]; }
+
+    octave_idx_type checkelem (octave_idx_type i) const;
+
+    octave_idx_type length (octave_idx_type) const
+      { return len; }
+
+    octave_idx_type extent (octave_idx_type n) const
+      { return std::max (n, ext); }
+
+    idx_class_type idx_class (void) const { return class_vector; }
+
+    idx_base_rep *sort_uniq_clone (bool uniq = false);
+
+    dim_vector orig_dimensions (void) const
+      { return orig_dims; }
+
+    const octave_idx_type *get_data (void) const { return data; }
+
+    std::ostream& print (std::ostream& os) const;
+
+  private:
+
+    DECLARE_OCTAVE_ALLOCATOR
+
+    // No copying!
+    idx_vector_rep (const idx_vector_rep& idx);
+
+    const octave_idx_type *data;
+    octave_idx_type len, ext;
+
+    // This is a trick to allow user-given zero-based arrays to be used as indices
+    // without copying. If the following pointer is nonzero, we do not own the data,
+    // but rather have an Array<octave_idx_type> object that provides us the data.
+    // Note that we need a pointer because we deferred the Array<T> declaration and
+    // we do not want it yet to be defined.
+    
+    Array<octave_idx_type> *aowner;
+
+    dim_vector orig_dims;
+  };
+
+
+  idx_vector (idx_base_rep *r) : rep (r) { }
+
+  // The shared empty vector representation (for fast default constructor)
+  static idx_vector_rep *nil_rep (void)
+    {
+      static idx_vector_rep ivr;
+      return &ivr;
+    }
+
+  // The shared empty vector representation with the error flag set.
+  static idx_vector_rep *err_rep (void)
+    {
+      static idx_vector_rep ivr;
+      ivr.err = true;
+      return &ivr;
+    }
+
+  // If there was an error in constructing the rep, replace it with empty vector
+  // for safety.
+  void chkerr (void)
+    {
+      if (rep->err)
+        {
+          if (--rep->count == 0)
+            delete rep;
+          rep = err_rep ();
+          rep->count++;
+        }
+    }
+
+public:
+
+  // Fast empty constructor.
+  idx_vector (void) : rep (nil_rep ()) { rep->count++; }
+
+  // Zero-based constructors (for use from C++).
+  idx_vector (octave_idx_type i) : rep (new idx_scalar_rep (i)) 
+    { chkerr (); }
+
+  idx_vector (octave_idx_type start, octave_idx_type limit,
+              octave_idx_type step = 1)
+    : rep (new idx_range_rep (start, limit, step)) 
+    { chkerr (); }
+
+  idx_vector (const Array<octave_idx_type>& inda) 
+    : rep (new idx_vector_rep (inda))
+    { chkerr (); }
+
+  // Colon is best constructed by simply copying (or referencing) this member.
+  static const idx_vector colon;
+
+  // or passing ':' here
+  idx_vector (char c) : rep (new idx_colon_rep (c)) { chkerr (); }
+
+  // Conversion constructors (used by interpreter).
+
+  template <class T>
+  idx_vector (octave_int<T> x) : rep (new idx_scalar_rep (x)) { chkerr (); }
+
+  idx_vector (double x) : rep (new idx_scalar_rep (x)) { chkerr (); }
+
+  idx_vector (float x) : rep (new idx_scalar_rep (x)) { chkerr (); }
+
+  // A scalar bool does not necessarily map to scalar index.
+  idx_vector (bool x) : rep (new idx_vector_rep (x)) { chkerr (); }
+
+  template <class T>
+  idx_vector (const Array<octave_int<T> >& nda) : rep (new idx_vector_rep (nda))
+    { chkerr (); }
+
+  idx_vector (const Array<double>& nda) : rep (new idx_vector_rep (nda))
+    { chkerr (); }
+
+  idx_vector (const Array<float>& nda) : rep (new idx_vector_rep (nda))
+    { chkerr (); }
+
+  idx_vector (const Array<bool>& nda) : rep (new idx_vector_rep (nda))
+    { chkerr (); }
+
+  idx_vector (const Range& r) 
+    : rep (new idx_range_rep (r))
+    { chkerr (); }
+
+  idx_vector (const Sparse<bool>& nda) : rep (new idx_vector_rep (nda))
+    { chkerr (); }
+
+  idx_vector (const idx_vector& a) : rep (a.rep) { rep->count++; }
+
+  ~idx_vector (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+  idx_vector& operator = (const idx_vector& a)
+    {
+      if (this != &a)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = a.rep;
+	  rep->count++;
+	}
+      return *this;
+    }
+
+  idx_class_type idx_class (void) const { return rep->idx_class (); }
+
+  octave_idx_type length (octave_idx_type n = 0) const 
+    { return rep->length (n); }
+
+  octave_idx_type extent (octave_idx_type n) const 
+    { return rep->extent (n); }
+
+  octave_idx_type xelem (octave_idx_type n) const 
+    { return rep->xelem (n); }
+
+  octave_idx_type checkelem (octave_idx_type n) const 
+    { return rep->checkelem (n); }
+
+  octave_idx_type operator () (octave_idx_type n) const 
+    {
+#if defined (BOUNDS_CHECKING)
+      return rep->checkelem (n); 
+#else
+      return rep->xelem (n);
+#endif
+    }
+
+  operator bool (void) const
+    { return ! rep->err; }
+
+  bool is_colon (void) const 
+    { return rep->idx_class () == class_colon; }
+
+  bool is_scalar (void) const 
+    { return rep->idx_class () == class_scalar; }
+
+  bool is_colon_equiv (octave_idx_type n) const
+    { return rep->is_colon_equiv (n); }
+
+  idx_vector sorted (bool uniq = false) const
+    { return idx_vector (rep->sort_uniq_clone (uniq)); }
+
+  dim_vector orig_dimensions (void) const { return rep->orig_dimensions (); }
+
+  octave_idx_type orig_rows (void) const
+    { return orig_dimensions () (0); }
+
+  octave_idx_type orig_columns (void) const
+    { return orig_dimensions () (1); }
+
+  int orig_empty (void) const
+    { return (! is_colon () && orig_dimensions().any_zero ()); }
+
+  // i/o
+
+  std::ostream& print (std::ostream& os) const { return rep->print (os); }
+
+  friend std::ostream& operator << (std::ostream& os, const idx_vector& a)
+    { return a.print (os); }
+
+  // Slice with specializations. No checking of bounds!
+  //
+  // This is equivalent to the following loop (but much faster):
+  //
+  // for (octave_idx_type i = 0; i < idx->length (n); i++)
+  //   dest[i] = src[idx(i)];
+  // return i;
+  //
+  template <class T>
+  octave_idx_type
+  index (const T *src, octave_idx_type n, T *dest) const
+    {
+      octave_idx_type len = rep->length (n);
+      switch (rep->idx_class ())
+        {
+        case class_colon:
+          std::copy (src, src + len, dest);
+          break;
+        case class_range:
+          {
+            idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+            octave_idx_type start = r->get_start (), step = r->get_step ();
+            const T *ssrc = src + start;
+            if (step == 1)
+              std::copy (ssrc, ssrc + len, dest);
+            else if (step == -1)
+              std::reverse_copy (ssrc - len + 1, ssrc + 1, dest);
+            else if (step == 0)
+              std::fill_n (dest, len, *ssrc);
+            else
+              {
+                for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                  dest[i] = ssrc[j];
+              }
+          }
+          break;
+        case class_scalar:
+          {
+            idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+            dest[0] = src[r->get_data ()];
+          }
+          break;
+        case class_vector:
+          {
+            idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++)
+              dest[i] = src[data[i]];
+          }
+          break;
+        default:
+          assert (false);
+          break;
+        }
+
+      return len;
+    }
+
+  // Slice assignment with specializations. No checking of bounds!
+  //
+  // This is equivalent to the following loop (but much faster):
+  //
+  // for (octave_idx_type i = 0; i < idx->length (n); i++)
+  //   dest[idx(i)] = src[i];
+  // return i;
+  //
+  template <class T>
+  octave_idx_type
+  assign (const T *src, octave_idx_type n, T *dest) const
+    {
+      octave_idx_type len = rep->length (n);
+      switch (rep->idx_class ())
+        {
+        case class_colon:
+          std::copy (src, src + len, dest);
+          break;
+        case class_range:
+          {
+            idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+            octave_idx_type start = r->get_start (), step = r->get_step ();
+            T *sdest = dest + start;
+            if (step == 1)
+              std::copy (src, src + len, sdest);
+            else if (step == -1)
+              std::reverse_copy (src, src + len, sdest - len + 1);
+            else
+              {
+                for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                  sdest[j] = src[i];
+              }
+          }
+          break;
+        case class_scalar:
+          {
+            idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+            dest[r->get_data ()] = src[0];
+          }
+          break;
+        case class_vector:
+          {
+            idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++)
+              dest[data[i]] = src[i];
+          }
+          break;
+        default:
+          assert (false);
+          break;
+        }
+
+      return len;
+    }
+
+  // Slice fill with specializations. No checking of bounds!
+  //
+  // This is equivalent to the following loop (but much faster):
+  //
+  // for (octave_idx_type i = 0; i < idx->length (n); i++)
+  //   dest[idx(i)] = val;
+  // return i;
+  //
+  template <class T>
+  octave_idx_type
+  fill (const T& val, octave_idx_type n, T *dest) const
+    {
+      octave_idx_type len = rep->length (n);
+      switch (rep->idx_class ())
+        {
+        case class_colon:
+          std::fill (dest, dest + len, val);
+          break;
+        case class_range:
+          {
+            idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+            octave_idx_type start = r->get_start (), step = r->get_step ();
+            T *sdest = dest + start;
+            if (step == 1)
+              std::fill (sdest, sdest + len, val);
+            else if (step == -1)
+              std::fill (sdest - len + 1, sdest + 1, val);
+            else
+              {
+                for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                  sdest[j] = val;
+              }
+          }
+          break;
+        case class_scalar:
+          {
+            idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+            dest[r->get_data ()] = val;
+          }
+          break;
+        case class_vector:
+          {
+            idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++)
+              dest[data[i]] = val;
+          }
+          break;
+        default:
+          assert (false);
+          break;
+        }
+
+      return len;
+    }
+
+  // Generic non-breakable indexed loop. The loop body should be encapsulated in a
+  // single functor body. 
+  // This is equivalent to the following loop (but faster, at least for simple
+  // inlined bodies):
+  //
+  // for (octave_idx_type i = 0; i < idx->length (n); i++) body (idx(i));
+  // 
+
+  template <class Functor>
+  void
+  loop (octave_idx_type n, Functor body) const
+    {
+      octave_idx_type len = rep->length (n);
+      switch (rep->idx_class ())
+        {
+        case class_colon:
+          for (octave_idx_type i = 0; i < len; i++) body (i);
+          break;
+        case class_range:
+          {
+            idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+            octave_idx_type start = r->get_start (), step = r->get_step ();
+            octave_idx_type i, j;
+            if (step == 1)
+              for (i = start, j = start + len; i < j; i++) body (i);
+            else if (step == -1)
+              for (i = start, j = start - len; i > j; i--) body (i);
+            else
+              for (i = 0, j = start; i < len; i++, j += step) body (j);
+          }
+          break;
+        case class_scalar:
+          {
+            idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+            body (r->get_data ());
+          }
+          break;
+        case class_vector:
+          {
+            idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++) body (data[i]);
+          }
+          break;
+        default:
+          assert (false);
+          break;
+        }
+
+    }
+
+  // Generic breakable indexed loop. The loop body should be encapsulated in a
+  // single functor body. 
+  // This is equivalent to the following loop (but faster, at least for simple
+  // inlined bodies):
+  //
+  // for (octave_idx_type i = 0; i < idx->length (n); i++)
+  //   if (body (idx(i))) break;
+  // return i;
+  // 
+
+  template <class Functor>
+  octave_idx_type
+  bloop (octave_idx_type n, Functor body) const
+    {
+      octave_idx_type len = rep->length (n), ret;
+      switch (rep->idx_class ())
+        {
+        case class_colon:
+          {
+            octave_idx_type i;
+            for (i = 0; i < len && body (i); i++) ;
+            ret = i;
+          }
+          break;
+        case class_range:
+          {
+            idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
+            octave_idx_type start = r->get_start (), step = r->get_step ();
+            octave_idx_type i, j;
+            if (step == 1)
+              for (i = start, j = start + len; i < j && body (i); i++) ;
+            else if (step == -1)
+              for (i = start, j = start - len; i > j && body (i); i--) ;
+            else
+              for (i = 0, j = start; i < len && body (j); i++, j += step) ;
+            ret = i;
+          }
+          break;
+        case class_scalar:
+          {
+            idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
+            ret = body (r->get_data ()) ? 1 : 0;
+          }
+          break;
+        case class_vector:
+          {
+            idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
+            const octave_idx_type *data = r->get_data ();
+            octave_idx_type i;
+            for (i = 0; i < len && body (data[i]); i++) ;
+            ret = i;
+          }
+          break;
+        default:
+          assert (false);
+          break;
+        }
+
+      return ret;
+    }
+
+  // Rationale: 
+  // This method is the key to "smart indexing". When indexing cartesian
+  // arrays, sometimes consecutive index vectors can be reduced into a single
+  // index. If rows (A) = k and i.maybe_reduce (j) gives k, then A(i,j)(:) is
+  // equal to A(k)(:).
+
+  // If the next index can be reduced, returns true and updates this.
+  bool maybe_reduce (octave_idx_type n, const idx_vector& j,
+                     octave_idx_type nj);
+
+  bool is_cont_range (octave_idx_type n,
+                      octave_idx_type& l, octave_idx_type& u) const;
+
+  idx_vector
+  complement (octave_idx_type n) const;
+
+  bool is_permutation (octave_idx_type n) const;
+
+  // FIXME -- these are here for compatibility.  They should be removed
+  // when no longer in use.
+
+  octave_idx_type elem (octave_idx_type n) const 
+    { return (*this) (n); }
+
+  bool is_colon_equiv (octave_idx_type n, int) const
+    { return is_colon_equiv (n); }
+
+  octave_idx_type
+  freeze (octave_idx_type z_len, const char *tag, bool resize_ok = false);
+
+  void sort (bool uniq = false)
+    { *this = sorted (uniq); }
+
+  octave_idx_type ones_count (void) const;
+
+  octave_idx_type max (void) const { return extent (1) - 1; }
+  
+private:
+
+  idx_base_rep *rep;
+
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int16NDArray.cc b/liboctave/int16NDArray.cc
new file mode 100644
index 0000000..5b5a3c2
--- /dev/null
+++ b/liboctave/int16NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "int16NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_int16>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_int16>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_int16>& a);
+
+NDS_CMP_OPS (int16NDArray, , octave_int16, )
+NDS_BOOL_OPS (int16NDArray, octave_int16, octave_int16 (0))
+
+SND_CMP_OPS (octave_int16, , int16NDArray, )
+SND_BOOL_OPS (octave_int16, int16NDArray, octave_int16 (0))
+
+NDND_CMP_OPS (int16NDArray, , int16NDArray, )
+NDND_BOOL_OPS (int16NDArray, int16NDArray, octave_int16 (0))
+
+MINMAX_FCNS (int16)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int16NDArray.h b/liboctave/int16NDArray.h
new file mode 100644
index 0000000..c2cc372
--- /dev/null
+++ b/liboctave/int16NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int16NDArray_h)
+#define octave_int16NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_int16> int16NDArray;
+
+NDS_CMP_OP_DECLS (int16NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_int16, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_int16, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, int16NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (int16NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, int16NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, int16NDArray, octave_int16)
+
+MINMAX_DECLS (int16)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int32NDArray.cc b/liboctave/int32NDArray.cc
new file mode 100644
index 0000000..9059069
--- /dev/null
+++ b/liboctave/int32NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "int32NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_int32>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_int32>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_int32>& a);
+
+NDS_CMP_OPS (int32NDArray, , octave_int32, )
+NDS_BOOL_OPS (int32NDArray, octave_int32, octave_int32 (0))
+
+SND_CMP_OPS (octave_int32, , int32NDArray, )
+SND_BOOL_OPS (octave_int32, int32NDArray, octave_int32 (0))
+
+NDND_CMP_OPS (int32NDArray, , int32NDArray, )
+NDND_BOOL_OPS (int32NDArray, int32NDArray, octave_int32 (0))
+
+MINMAX_FCNS (int32)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int32NDArray.h b/liboctave/int32NDArray.h
new file mode 100644
index 0000000..012be03
--- /dev/null
+++ b/liboctave/int32NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int32NDArray_h)
+#define octave_int32NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_int32> int32NDArray;
+
+NDS_CMP_OP_DECLS (int32NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_int32, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_int32, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, int32NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (int32NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, int32NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, int32NDArray, octave_int32)
+
+MINMAX_DECLS (int32)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int64NDArray.cc b/liboctave/int64NDArray.cc
new file mode 100644
index 0000000..452d8b3
--- /dev/null
+++ b/liboctave/int64NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "int64NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_int64>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_int64>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_int64>& a);
+
+NDS_CMP_OPS (int64NDArray, , octave_int64, )
+NDS_BOOL_OPS (int64NDArray, octave_int64, octave_int64 (0))
+
+SND_CMP_OPS (octave_int64, , int64NDArray, )
+SND_BOOL_OPS (octave_int64, int64NDArray, octave_int64 (0))
+
+NDND_CMP_OPS (int64NDArray, , int64NDArray, )
+NDND_BOOL_OPS (int64NDArray, int64NDArray, octave_int64 (0))
+
+MINMAX_FCNS (int64)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int64NDArray.h b/liboctave/int64NDArray.h
new file mode 100644
index 0000000..f12049c
--- /dev/null
+++ b/liboctave/int64NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int64NDArray_h)
+#define octave_int64NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_int64> int64NDArray;
+
+NDS_CMP_OP_DECLS (int64NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_int64, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_int64, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, int64NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (int64NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, int64NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, int64NDArray, octave_int64)
+
+MINMAX_DECLS (int64)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int8NDArray.cc b/liboctave/int8NDArray.cc
new file mode 100644
index 0000000..e929a6e
--- /dev/null
+++ b/liboctave/int8NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "int8NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_int8>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_int8>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_int8>& a);
+
+NDS_CMP_OPS (int8NDArray, , octave_int8, )
+NDS_BOOL_OPS (int8NDArray, octave_int8, octave_int8 (0))
+
+SND_CMP_OPS (octave_int8, , int8NDArray, )
+SND_BOOL_OPS (octave_int8, int8NDArray, octave_int8 (0))
+
+NDND_CMP_OPS (int8NDArray, , int8NDArray, )
+NDND_BOOL_OPS (int8NDArray, int8NDArray, octave_int8 (0))
+
+MINMAX_FCNS (int8)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/int8NDArray.h b/liboctave/int8NDArray.h
new file mode 100644
index 0000000..7f6219d
--- /dev/null
+++ b/liboctave/int8NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int8NDArray_h)
+#define octave_int8NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_int8> int8NDArray;
+
+NDS_CMP_OP_DECLS (int8NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_int8, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_int8, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, int8NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (int8NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, int8NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, int8NDArray, octave_int8)
+
+MINMAX_DECLS (int8)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/intNDArray.cc b/liboctave/intNDArray.cc
new file mode 100644
index 0000000..0e35347
--- /dev/null
+++ b/liboctave/intNDArray.cc
@@ -0,0 +1,277 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array-util.h"
+#include "mx-base.h"
+#include "lo-ieee.h"
+#include "mx-inlines.cc"
+
+// unary operations
+
+template <class T>
+boolNDArray
+intNDArray<T>::operator ! (void) const
+{
+  boolNDArray b (this->dims ());
+
+  for (octave_idx_type i = 0; i < this->length (); i++)
+    b.elem (i) = ! this->elem (i);
+
+  return b;
+}
+
+template <class T>
+bool
+intNDArray<T>::any_element_not_one_or_zero (void) const
+{
+  octave_idx_type nel = this->nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      T val = this->elem (i);
+
+      if (val != 0.0 && val != 1.0)
+	return true;
+    }
+
+  return false;
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::diag (octave_idx_type k) const
+{
+  return MArrayN<T>::diag (k);
+}
+
+// FIXME -- this is not quite the right thing.
+
+template <class T>
+boolNDArray
+intNDArray<T>::all (int dim) const
+{
+  return do_mx_red_op<boolNDArray, T > (*this, dim, mx_inline_all);
+}
+
+template <class T>
+boolNDArray
+intNDArray<T>::any (int dim) const
+{
+  return do_mx_red_op<boolNDArray, T > (*this, dim, mx_inline_any);
+}
+
+template <class T>
+void
+intNDArray<T>::increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension)
+{
+  ::increment_index (ra_idx, dimensions, start_dimension);
+}
+
+template <class T>
+octave_idx_type 
+intNDArray<T>::compute_index (Array<octave_idx_type>& ra_idx,
+			      const dim_vector& dimensions)
+{
+  return ::compute_index (ra_idx, dimensions);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::concat (const intNDArray<T>& rb, const Array<octave_idx_type>& ra_idx)
+{
+  if (rb.numel () > 0)
+    insert (rb, ra_idx);
+  return *this;
+}
+
+template <class T>
+intNDArray<T>&
+intNDArray<T>::insert (const intNDArray<T>& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<T>::insert (a, r, c);
+  return *this;
+}
+
+template <class T>
+intNDArray<T>&
+intNDArray<T>::insert (const intNDArray<T>& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<T>::insert (a, ra_idx);
+  return *this;
+}
+
+// This contains no information on the array structure !!!
+
+template <class T>
+std::ostream&
+operator << (std::ostream& os, const intNDArray<T>& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    os << " " << a.elem (i) << "\n";
+
+  return os;
+}
+
+template <class T>
+std::istream&
+operator >> (std::istream& is, intNDArray<T>& a)
+{
+  octave_idx_type nel = a.nelem ();
+
+  if (nel > 0)
+    {
+      T tmp;
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  is >> tmp;
+
+	  if (is)
+	    a.elem (i) = tmp;
+	  else
+	    goto done;
+	}
+    }
+
+ done:
+
+  return is;
+}
+
+// FIXME -- should abs and signum just be mapper functions?
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::abs (void) const
+{
+  octave_idx_type nel = this->nelem ();
+  intNDArray<T> ret (*this);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      T val = this->elem (i);
+      ret.xelem (i) = val.abs ();
+    }
+
+  return ret;
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::signum (void) const
+{
+  octave_idx_type nel = this->nelem ();
+  intNDArray<T> ret (*this);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      T val = this->elem (i);
+      ret.xelem (i) = val.signum ();
+    }
+
+  return ret;
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::sum (int dim) const
+{
+  return do_mx_red_op<intNDArray<T> , T > (*this, dim, mx_inline_sum);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::cumsum (int dim) const
+{
+  return do_mx_cum_op<intNDArray<T> , T > (*this, dim, mx_inline_cumsum);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::max (int dim) const
+{
+  return do_mx_minmax_op<intNDArray<T> > (*this, dim, mx_inline_max);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::max (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_max);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::min (int dim) const
+{
+  return do_mx_minmax_op<intNDArray<T> > (*this, dim, mx_inline_min);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::min (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_minmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_min);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::cummax (int dim) const
+{
+  return do_mx_cumminmax_op<intNDArray<T> > (*this, dim, mx_inline_cummax);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_cummax);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::cummin (int dim) const
+{
+  return do_mx_cumminmax_op<intNDArray<T> > (*this, dim, mx_inline_cummin);
+}
+
+template <class T>
+intNDArray<T>
+intNDArray<T>::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const
+{
+  return do_mx_cumminmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_cummin);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/intNDArray.h b/liboctave/intNDArray.h
new file mode 100644
index 0000000..8812146
--- /dev/null
+++ b/liboctave/intNDArray.h
@@ -0,0 +1,131 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_intNDArray_h)
+#define octave_intNDArray_h 1
+
+#include "MArrayN.h"
+#include "boolNDArray.h"
+
+template <class T>
+class
+intNDArray : public MArrayN<T>
+{
+public:
+
+  using MArrayN<T>::element_type;
+  
+  intNDArray (void) : MArrayN<T> () { }
+
+  intNDArray (T val) : MArrayN<T> (dim_vector (1, 1), val) { }
+
+  intNDArray (const dim_vector& dv) : MArrayN<T> (dv) { }
+  
+  intNDArray (const dim_vector& dv, T val)
+    : MArrayN<T> (dv, val) { }
+  
+  template <class U>
+  explicit intNDArray (const Array<U>& a) : MArrayN<T> (a) { }
+
+  template <class U>
+  explicit intNDArray (const ArrayN<U>& a) : MArrayN<T> (a) { }
+
+  template <class U>
+  intNDArray (const MArrayN<U>& a) : MArrayN<T> (a) { }
+
+  template <class U>
+  intNDArray (const intNDArray<U>& a) : MArrayN<T> (a) { }
+
+  intNDArray& operator = (const intNDArray<T>& a)
+    {
+      MArrayN<T>::operator = (a);
+      return *this;
+    }
+
+  boolNDArray operator ! (void) const;
+
+  bool any_element_is_nan (void) const { return false; }
+  bool any_element_not_one_or_zero (void) const;
+
+  intNDArray diag (octave_idx_type k = 0) const;
+
+  // FIXME -- this is not quite the right thing.
+
+  boolNDArray all (int dim = -1) const;
+  boolNDArray any (int dim = -1) const;
+
+  intNDArray max (int dim = 0) const;
+  intNDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  intNDArray min (int dim = 0) const;
+  intNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  
+  intNDArray cummax (int dim = 0) const;
+  intNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  intNDArray cummin (int dim = 0) const;
+  intNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const;
+  
+  intNDArray sum (int dim) const;
+  intNDArray cumsum (int dim) const;
+
+  intNDArray abs (void) const;
+  intNDArray signum (void) const;
+
+  intNDArray squeeze (void) const
+    { return intNDArray<T> (MArrayN<T>::squeeze ()); }
+
+  intNDArray transpose (void) const
+    { return intNDArray<T> (MArrayN<T>::transpose ()); }
+
+  intNDArray concat (const intNDArray<T>& rb, const Array<octave_idx_type>& ra_idx);
+
+  intNDArray& insert (const intNDArray<T>& a, octave_idx_type r, octave_idx_type c);
+  intNDArray& insert (const intNDArray<T>& a, const Array<octave_idx_type>& ra_idx);
+
+  static void increment_index (Array<octave_idx_type>& ra_idx,
+			       const dim_vector& dimensions,
+			       int start_dimension = 0);
+
+  static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
+			    const dim_vector& dimensions);
+
+  static T resize_fill_value (void) { return 0; }
+
+protected:
+
+  intNDArray (T *d, dim_vector& dv) : MArrayN<T> (d, dv) { }
+};
+
+// i/o
+
+template <class T>
+std::ostream& operator << (std::ostream& os, const intNDArray<T>& a);
+
+template <class T>
+std::istream& operator >> (std::istream& is, intNDArray<T>& a);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/kpse-xfns.c b/liboctave/kpse-xfns.c
new file mode 100644
index 0000000..ebe66f4
--- /dev/null
+++ b/liboctave/kpse-xfns.c
@@ -0,0 +1,63 @@
+/*
+
+Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+Copyright (C) 1993, 94, 95, 96, 97, 98 Karl Berry.
+Copyright (C) 1994, 95, 96, 97 Karl Berry & Olaf Weber.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "kpse-xfns.h"
+
+/* Return the last element in a path.  */
+
+#ifndef HAVE_BASENAME
+
+/* Return NAME with any leading path stripped off.  This returns a
+   pointer into NAME.  For example, `basename ("/foo/bar.baz")'
+   returns "bar.baz".  */
+
+static const char *
+basename (const char *name)
+{
+  const char *base = NULL;
+  unsigned len = strlen (name);
+  
+  for (len = strlen (name); len > 0; len--) {
+    if (IS_DIR_SEP (name[len - 1]) || IS_DEVICE_SEP (name[len - 1])) {
+      base = name + len;
+      break;
+    }
+  }
+
+  if (!base)
+    base = name;
+  
+  return base;
+}
+
+#endif
+
+const char *
+octave_basename (const char *name)
+{
+  return (const char *) basename (name);
+}
diff --git a/liboctave/kpse-xfns.h b/liboctave/kpse-xfns.h
new file mode 100644
index 0000000..5e670e2
--- /dev/null
+++ b/liboctave/kpse-xfns.h
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+Copyright (C) 1993, 94, 95, 96 Karl Berry.
+Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#if !defined (octave_kpse_xfns_h)
+#define octave_kpse_xfns_h 1
+
+/* Define the characters which separate components of
+   filenames and environment variable paths.  */
+
+/* What separates filename components?  */
+#ifndef DIR_SEP
+#ifdef DOSISH
+/* Either \'s or 's work.  Wayne Sullivan's web2pc prefers /, so we'll
+   go with that.  */
+#define DIR_SEP '/'
+#define DIR_SEP_STRING "/"
+#define IS_DEVICE_SEP(ch) ((ch) == ':')
+#define NAME_BEGINS_WITH_DEVICE(name) ((name.length()>0) && IS_DEVICE_SEP((name)[1]))
+/* On DOS, it's good to allow both \ and / between directories.  */
+#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
+#else
+#define DIR_SEP '/'
+#define DIR_SEP_STRING "/"
+#endif /* not DOSISH */
+#endif /* not DIR_SEP */
+
+#ifndef IS_DIR_SEP
+#define IS_DIR_SEP(ch) ((ch) == DIR_SEP)
+#endif
+#ifndef IS_DEVICE_SEP /* No `devices' on, e.g., Unix.  */
+#define IS_DEVICE_SEP(ch) 0 
+#endif
+#ifndef NAME_BEGINS_WITH_DEVICE
+#define NAME_BEGINS_WITH_DEVICE(name) 0 
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char *octave_basename (const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/liboctave/kpse.cc b/liboctave/kpse.cc
new file mode 100644
index 0000000..eeb0dde
--- /dev/null
+++ b/liboctave/kpse.cc
@@ -0,0 +1,2652 @@
+// This file is not compiled to a separate object file.  It is
+// included in pathsearch.cc.
+
+/* Look up a filename in a path.
+
+Copyright (C) 1993, 94, 95, 96, 97, 98 Karl Berry.
+Copyright (C) 1993, 94, 95, 96, 97 Karl Berry & O. Weber.
+Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <map>
+#include <string>
+
+/* System defines are for non-Unix systems only.  (Testing for all Unix
+   variations should be done in configure.)  Presently the defines used
+   are: DOS OS2 WIN32.  I do not use any of these systems
+   myself; if you do, I'd be grateful for any changes. --kb at mail.tug.org */
+
+/* If we have either DOS or OS2, we are DOSISH.  */
+#if defined (DOS) || defined (OS2) || defined (WIN32) || defined(__MSDOS__)
+#define DOSISH
+#endif
+
+#if defined (DOSISH)
+#define MONOCASE_FILENAMES	/* case-insensitive filename comparisons */
+#endif
+
+extern "C" {
+#if defined(__MINGW32__)
+#include <windows.h>
+#include <fcntl.h>
+#include <dirent.h>
+#elif defined(WIN32)
+#define __STDC__ 1
+#ifndef _MSC_VER
+#include "win32lib.h"
+#endif
+#endif /* not WIN32 */
+
+#ifdef __DJGPP__
+#include <fcntl.h>	/* for long filenames' stuff */
+#include <dir.h>	/* for `getdisk' */
+#include <io.h>		/* for `setmode' */
+#endif
+}
+
+/* Some drivers have partially integrated kpathsea changes.  */
+#ifndef KPATHSEA
+#define KPATHSEA 32
+#endif
+ 
+/* System dependencies that are figured out by `configure'.  If we are
+   compiling standalone, we get our c-auto.h.  Otherwise, the package
+   containing us must provide this (unless it can somehow generate ours
+   from c-auto.in).  We use <...> instead of "..." so that the current
+   cpp directory (i.e., kpathsea/) won't be searched. */
+
+/* If you want to find subdirectories in a directory with non-Unix
+   semantics (specifically, if a directory with no subdirectories does
+   not have exactly two links), define this.  */
+#if defined(__DJGPP__) || ! defined (DOSISH)
+/* Surprise!  DJGPP returns st_nlink exactly like on Unix.  */
+#define ST_NLINK_TRICK
+#endif /* either not DOSISH or __DJGPP__ */
+
+#ifdef OS2
+#define access ln_access
+#define fopen ln_fopen
+#define rename ln_rename
+#define stat ln_stat
+#endif /* OS2 */
+
+#include "kpse-xfns.h"
+
+#include "lo-error.h"
+#include "oct-env.h"
+#include "oct-passwd.h"
+#include "str-vec.h"
+
+/* Header files that essentially all of our sources need, and
+   that all implementations have.  We include these first, to help with
+   NULL being defined multiple times.  */
+#include <cstdio>
+#include <cstdarg>
+#include <cstdlib>
+#include <climits>
+#include <cerrno>
+#include <cassert>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "sysdir.h"
+#include "statdefs.h"
+
+/* define NAME_MAX, the maximum length of a single
+   component in a filename.  No such limit may exist, or may vary
+   depending on the filesystem.  */
+
+/* Most likely the system will truncate filenames if it is not POSIX,
+   and so we can use the BSD value here.  */
+#ifndef _POSIX_NAME_MAX
+#define _POSIX_NAME_MAX 255
+#endif
+
+#ifndef NAME_MAX
+#define NAME_MAX _POSIX_NAME_MAX
+#endif
+
+#include <cctype>
+
+/* What separates elements in environment variable path lists?  */
+#ifndef ENV_SEP
+#if defined (SEPCHAR) && defined (SEPCHAR_STR)
+#define ENV_SEP SEPCHAR
+#define ENV_SEP_STRING SEPCHAR_STR
+#elif defined (DOSISH)
+#define ENV_SEP ';'
+#define ENV_SEP_STRING ";"
+#else
+#define ENV_SEP ':'
+#define ENV_SEP_STRING ":"
+#endif /* not DOS */
+#endif /* not ENV_SEP */
+
+#ifndef IS_ENV_SEP
+#define IS_ENV_SEP(ch) ((ch) == ENV_SEP)
+#endif
+
+/* define PATH_MAX, the maximum length of a filename.  Since no such
+   limit may exist, it's preferable to dynamically grow filenames as
+   needed.  */
+
+/* Cheat and define this as a manifest constant no matter what, instead
+   of using pathconf.  I forget why we want to do this.  */
+
+#ifndef _POSIX_PATH_MAX
+#define _POSIX_PATH_MAX 255
+#endif
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX _POSIX_PATH_MAX
+#endif
+#endif /* not PATH_MAX */
+
+/* If NO_DEBUG is defined (not recommended), skip all this.  */
+#ifndef NO_DEBUG
+
+/* OK, we'll have tracing support.  */
+#define KPSE_DEBUG
+
+/* Test if a bit is on.  */
+#define KPSE_DEBUG_P(bit) (kpathsea_debug & (1 << (bit)))
+
+#define KPSE_DEBUG_STAT 0		/* stat calls */
+#define KPSE_DEBUG_HASH 1		/* hash lookups */
+#define KPSE_DEBUG_FOPEN 2		/* fopen/fclose calls */
+#define KPSE_DEBUG_PATHS 3		/* search path initializations */
+#define KPSE_DEBUG_EXPAND 4		/* path element expansion */
+#define KPSE_DEBUG_SEARCH 5		/* searches */
+#define KPSE_DEBUG_VARS 6		/* variable values */
+#define KPSE_LAST_DEBUG KPSE_DEBUG_VARS
+
+/* A printf for the debugging.  */
+#define DEBUGF_START() do { fputs ("kdebug:", stderr)
+#define DEBUGF_END()        fflush (stderr); } while (0)
+
+#define DEBUGF(str)							\
+  DEBUGF_START (); fputs (str, stderr); DEBUGF_END ()
+#define DEBUGF1(str, e1)						\
+  DEBUGF_START (); fprintf (stderr, str, e1); DEBUGF_END ()
+#define DEBUGF2(str, e1, e2)						\
+  DEBUGF_START (); fprintf (stderr, str, e1, e2); DEBUGF_END ()
+#define DEBUGF3(str, e1, e2, e3)					\
+  DEBUGF_START (); fprintf (stderr, str, e1, e2, e3); DEBUGF_END ()
+#define DEBUGF4(str, e1, e2, e3, e4)					\
+  DEBUGF_START (); fprintf (stderr, str, e1, e2, e3, e4); DEBUGF_END ()
+
+#undef fopen
+#define fopen kpse_fopen_trace
+static FILE *fopen (const char *filename, const char *mode);
+
+#endif /* not NO_DEBUG */
+
+#ifdef KPSE_DEBUG
+static unsigned int kpathsea_debug = 0;
+#endif
+
+#if defined (WIN32) && !defined (__MINGW32__)
+
+/* System description file for Windows NT.  */
+
+/*
+ *      Define symbols to identify the version of Unix this is.
+ *      Define all the symbols that apply correctly.
+ */
+
+#ifndef DOSISH
+#define DOSISH
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN      _MAX_PATH
+#endif
+
+/* These have to be defined because our compilers treat __STDC__ as being
+   defined (most of them anyway). */
+
+#define access  _access
+#define stat    _stat
+#define strdup  _strdup
+
+#define S_IFMT   _S_IFMT
+#define S_IFDIR  _S_IFDIR
+
+/* Define this so that winsock.h definitions don't get included when
+   windows.h is...  For this to have proper effect, config.h must
+   always be included before windows.h.  */
+#define _WINSOCKAPI_    1
+
+#include <windows.h>
+
+/* For proper declaration of environ.  */
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+
+/* ============================================================ */
+
+#endif /* WIN32 */
+
+/* Define common sorts of messages.  */
+
+/* This should be called only after a system call fails.  Don't exit
+   with status `errno', because that might be 256, which would mean
+   success (exit statuses are truncated to eight bits).  */
+#define FATAL_PERROR(str) \
+  do \
+    { \
+      fputs ("pathsearch: ", stderr); \
+      perror (str); exit (EXIT_FAILURE); \
+    } \
+  while (0)
+
+#define FATAL(str) \
+  do \
+    { \
+      fputs ("pathsearch: fatal: ", stderr); \
+      fputs (str, stderr); \
+      fputs (".\n", stderr); \
+      exit (1); \
+    } \
+  while (0)
+
+#ifndef WIN32
+static void xclosedir (DIR *d);
+#endif
+
+/* It's a little bizarre to be using the same type for the list and the
+   elements of the list, but no reason not to in this case, I think --
+   we never need a NULL string in the middle of the list, and an extra
+   NULL/NULL element always at the end is inconsequential.  */
+
+struct str_llist_elt
+{
+  std::string str;
+  int moved;
+  struct str_llist_elt *next;
+};
+
+typedef str_llist_elt str_llist_elt_type;
+typedef str_llist_elt *str_llist_type;
+
+#define STR_LLIST(sl) ((sl).str)
+#define STR_LLIST_MOVED(sl) ((sl).moved)
+#define STR_LLIST_NEXT(sl) ((sl).next)
+
+static void str_llist_add (str_llist_type *l, const std::string& str);
+
+static void str_llist_float (str_llist_type *l, str_llist_elt_type *mover);
+
+static std::string kpse_var_expand (const std::string& src);
+
+static str_llist_type *kpse_element_dirs (const std::string& elt);
+
+static std::string kpse_expand (const std::string& s);
+
+static std::string kpse_expand_default (const std::string& path,
+					const std::string& dflt);
+
+static string_vector kpse_db_search (const std::string& name,
+				     const std::string& path_elt, bool all);
+
+#include <ctime> /* for `time' */
+
+static bool
+kpse_is_env_sep (char c)
+{
+  return IS_ENV_SEP (c);
+}
+
+/* These routines just check the return status from standard library
+   routines and abort if an error happens.  */
+
+static FILE *
+xfopen (const std::string& filename, const char *mode)
+{
+  FILE *f;
+
+  assert (! filename.empty () && mode);
+
+  f = fopen (filename.c_str (), mode);
+
+  if (! f)
+    FATAL_PERROR (filename.c_str ());
+
+  return f;
+}
+
+/* A single (key,value) pair.  */
+
+struct hash_element_type
+{
+  std::string key;
+  std::string value;
+  struct hash_element_type *next;
+};
+
+/* The usual arrangement of buckets initialized to null.  */
+
+struct hash_table_type
+{
+  hash_element_type **buckets;
+  unsigned size;
+};
+
+static unsigned
+kpse_hash (hash_table_type table, const std::string& key)
+{
+  unsigned n = 0;
+
+  /* Our keys aren't often anagrams of each other, so no point in
+     weighting the characters.  */
+  size_t len = key.length ();
+  for (size_t i = 0; i < len; i++)
+    n = (n + n + key[i]) % table.size;
+
+  return n;
+}
+
+/* Look up STR in MAP.  Return a (dynamically-allocated) list of the
+   corresponding strings or NULL if no match.  */
+
+static string_vector
+hash_lookup (hash_table_type table, const std::string& key)
+{
+  hash_element_type *p;
+  string_vector ret;
+  unsigned n = kpse_hash (table, key);
+
+  /* Look at everything in this bucket.  */
+  for (p = table.buckets[n]; p; p = p->next)
+    if (key == p->key)
+      ret.append (p->value);
+
+#ifdef KPSE_DEBUG
+  if (KPSE_DEBUG_P (KPSE_DEBUG_HASH))
+    {
+      DEBUGF1 ("hash_lookup (%s) =>", key.c_str ());
+      if (ret.empty ())
+        fputs (" (nil)\n", stderr);
+      else
+        {
+	  int len = ret.length ();
+	  for (int i = 0; i < len; i++)
+            {
+              putc (' ', stderr);
+	      fputs (ret[i].c_str (), stderr);
+            }
+          putc ('\n', stderr);
+        }
+      fflush (stderr);
+    }
+#endif
+
+  return ret;
+}
+
+/* A way to step through a path, extracting one directory name at a
+   time.  */
+
+class kpse_path_iterator
+{
+public:
+
+  kpse_path_iterator (const std::string& p)
+    : path (p), b (0), e (0), len (path.length ()) { set_end (); }
+
+  kpse_path_iterator (const kpse_path_iterator& pi)
+    : path (pi.path), b (pi.b), e (pi.e), len (pi.len) { }
+
+  kpse_path_iterator operator ++ (int)
+    {
+      kpse_path_iterator retval (*this);
+      next ();
+      return retval;
+    }
+
+  std::string operator * (void) { return path.substr (b, e-b); }
+
+  bool operator != (const size_t sz) { return b != sz; }
+
+private:
+
+  const std::string& path;
+  size_t b;
+  size_t e;
+  size_t len;
+
+  void set_end (void)
+    {
+      e = b + 1;
+
+      if (e == len)
+	; /* OK, we have found the last element.  */
+      else if (e > len)
+	b = e = std::string::npos;
+      else
+	{
+	  /* Find the next colon not enclosed by braces (or the end of
+	     the path).  */
+
+	  int brace_level = 0;
+	  while (e < len && ! (brace_level == 0 && kpse_is_env_sep (path[e])))
+	    e++;
+	}
+    }
+
+  void next (void)
+    {
+      b = e + 1;
+
+      /* Skip any consecutive colons.  */
+      while (b < len && kpse_is_env_sep (path[b]))
+	b++;
+
+      if (b >= len)
+	b = e = std::string::npos;
+      else
+	set_end ();
+    }
+
+  // No assignment.
+  kpse_path_iterator& operator = (const kpse_path_iterator&);
+};
+
+/* Here's the simple one, when a program just wants a value.  */
+
+static std::string
+kpse_var_value (const std::string& var)
+{
+  std::string ret;
+
+  std::string tmp = octave_env::getenv (var);
+
+  if (! tmp.empty ())
+    ret = kpse_var_expand (tmp);
+
+#ifdef KPSE_DEBUG
+  if (KPSE_DEBUG_P (KPSE_DEBUG_VARS))
+    DEBUGF2 ("variable: %s = %s\n", var.c_str (),
+	     tmp.empty () ? "(nil)" :  tmp.c_str ());
+#endif
+
+  return ret;
+}
+
+/* Truncate any too-long components in NAME, returning the result.  It's
+   too bad this is necessary.  See comments in readable.c for why.  */
+
+static std::string
+kpse_truncate_filename (const std::string& name)
+{
+  unsigned c_len = 0;        /* Length of current component.  */
+  unsigned ret_len = 0;      /* Length of constructed result.  */
+
+  std::string ret = name;
+
+  size_t len = name.length ();
+
+  for (size_t i = 0; i < len; i++)
+    {
+      if (IS_DIR_SEP (name[i]) || IS_DEVICE_SEP (name[i]))
+        {
+	  /* At a directory delimiter, reset component length.  */
+          c_len = 0;
+        }
+      else if (c_len > NAME_MAX)
+        {
+	  /* If past the max for a component, ignore this character.  */
+          continue;
+        }
+
+      /* Copy this character.  */
+      ret[ret_len++] = name[i];
+      c_len++;
+    }
+
+  ret.resize (ret_len);
+
+  return ret;
+}
+
+/* If access can read FN, run stat (assigning to stat buffer ST) and
+   check that fn is not a directory.  Don't check for just being a
+   regular file, as it is potentially useful to read fifo's or some
+   kinds of devices.  */
+
+#ifdef WIN32
+static inline bool
+READABLE (const std::string& fn, struct stat&)
+{
+  const char *t = fn.c_str ();
+  return (GetFileAttributes (t) != 0xFFFFFFFF
+	  && ! (GetFileAttributes (t) & FILE_ATTRIBUTE_DIRECTORY));
+}
+#else
+static inline bool
+READABLE (const std::string& fn, struct stat& st)
+{
+  const char *t = fn.c_str ();
+  return (access (t, R_OK) == 0
+	  && stat (t, &(st)) == 0 && ! S_ISDIR (st.st_mode));
+}
+#endif
+
+/* POSIX invented the brain-damage of not necessarily truncating
+   filename components; the system's behavior is defined by the value of
+   the symbol _POSIX_NO_TRUNC, but you can't change it dynamically!
+
+   Generic const return warning.  See extend-fname.c.  */
+
+static std::string
+kpse_readable_file (const std::string& name)
+{
+  struct stat st;
+  std::string ret;
+
+  if (READABLE (name, st))
+    {
+      ret = name;
+
+#ifdef ENAMETOOLONG
+    }
+  else if (errno == ENAMETOOLONG)
+    {
+      ret = kpse_truncate_filename (name);
+
+      /* Perhaps some other error will occur with the truncated name,
+	 so let's call access again.  */
+
+      if (! READABLE (ret, st))
+	{
+	  /* Failed.  */
+	  ret = std::string ();
+	}
+#endif /* ENAMETOOLONG */
+
+    }
+  else
+    {
+      /* Some other error.  */
+      if (errno == EACCES)
+	{
+	  /* Maybe warn them if permissions are bad.  */
+	  perror (name.c_str ());
+	}
+
+      ret = std::string ();
+    }
+
+  return ret;
+}
+
+/* Sorry this is such a system-dependent mess, but I can't see any way
+   to usefully generalize.  */
+
+static bool
+kpse_absolute_p (const std::string& filename, int relative_ok)
+{
+  size_t len = filename.length ();
+
+  int absolute = (len > 0 && IS_DIR_SEP (filename[0]))
+#ifdef DOSISH
+                     /* Novell allows non-alphanumeric drive letters. */
+    || (len > 0 && IS_DEVICE_SEP (filename[1]))
+#endif /* DOSISH */
+#ifdef WIN32
+                     /* UNC names */
+    || (len > 1 && filename[0] == '\\' && filename[1] == '\\')
+#endif
+    ;
+
+  int explicit_relative
+    = relative_ok
+      && (len > 1
+	  && filename[0] == '.'
+	  && (IS_DIR_SEP (filename[1])
+	      || (len > 2 && filename[1] == '.' && IS_DIR_SEP (filename[2]))));
+
+  return absolute || explicit_relative;
+}
+
+/* The very first search is for texmf.cnf, called when someone tries to
+   initialize the TFM path or whatever.  init_path calls kpse_cnf_get
+   which calls kpse_all_path_search to find all the texmf.cnf's.  We
+   need to do various special things in this case, since we obviously
+   don't yet have the configuration files when we're searching for the
+   configuration files.  */
+static bool first_search = true;
+
+/* This function is called after every search (except the first, since
+   we definitely want to allow enabling the logging in texmf.cnf) to
+   record the filename(s) found in $TEXMFLOG.  */
+
+static void
+log_search (const string_vector& filenames)
+{
+  static FILE *log_file = 0;
+  static bool first_time = true; /* Need to open the log file?  */
+
+  if (first_time)
+    {
+      first_time = false;
+
+      /* Get name from either envvar or config file.  */
+      std::string log_name = kpse_var_value ("TEXMFLOG");
+
+      if (! log_name.empty ())
+	{
+	  log_file = xfopen (log_name.c_str (), "a");
+
+	  if (! log_file)
+	    perror (log_name.c_str ());
+	}
+    }
+
+  if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH) || log_file)
+    {
+      /* FILENAMES should never be null, but safety doesn't hurt.  */
+      for (int e = 0; e < filenames.length () && ! filenames[e].empty (); e++)
+	{
+	  std::string filename = filenames[e];
+
+	  /* Only record absolute filenames, for privacy.  */
+	  if (log_file && kpse_absolute_p (filename.c_str (), false))
+	    fprintf (log_file, "%lu %s\n",
+		     static_cast<unsigned long> (time (0)),
+		     filename.c_str ());
+
+	  /* And show them online, if debugging.  We've already started
+	     the debugging line in `search', where this is called, so
+	     just print the filename here, don't use DEBUGF.  */
+	  if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+	    fputs (filename.c_str (), stderr);
+	}
+    }
+}
+
+/* Concatenate each element in DIRS with NAME (assume each ends with a
+   /, to save time).  If SEARCH_ALL is false, return the first readable
+   regular file.  Else continue to search for more.  In any case, if
+   none, return a list containing just NULL.
+
+   We keep a single buffer for the potential filenames and reallocate
+   only when necessary.  I'm not sure it's noticeably faster, but it
+   does seem cleaner.  (We do waste a bit of space in the return
+   value, though, since we don't shrink it to the final size returned.)  */
+
+static string_vector
+dir_list_search (str_llist_type *dirs, const std::string& name,
+		 bool search_all)
+{
+  str_llist_elt_type *elt;
+  string_vector ret;
+
+  for (elt = *dirs; elt; elt = STR_LLIST_NEXT (*elt))
+    {
+      const std::string dir = STR_LLIST (*elt);
+
+      std::string potential = dir + name;
+
+      std::string tmp = kpse_readable_file (potential);
+
+      if (! tmp.empty ())
+        {
+          ret.append (potential);
+
+          /* Move this element towards the top of the list.  */
+          str_llist_float (dirs, elt);
+
+          if (! search_all)
+            return ret;
+        }
+    }
+
+  return ret;
+}
+
+/* This is called when NAME is absolute or explicitly relative; if it's
+   readable, return (a list containing) it; otherwise, return NULL.  */
+
+static string_vector
+absolute_search (const std::string& name)
+{
+  string_vector ret_list;
+  std::string found = kpse_readable_file (name);
+
+  /* Add `found' to the return list even if it's null; that tells
+     the caller we didn't find anything.  */
+  ret_list.append (found);
+
+  return ret_list;
+}
+
+/* This is the hard case -- look for NAME in PATH.  If ALL is false,
+   return the first file found.  Otherwise, search all elements of PATH.  */
+
+static string_vector
+path_search (const std::string& path, const std::string& name,
+	     bool /* must_exist */, bool all)
+{
+  string_vector ret_list;
+  bool done = false;
+
+  for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++)
+    {
+      std::string elt = *pi;
+
+      string_vector found;
+      bool allow_disk_search = true;
+
+      if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!')
+	{
+	  /* Those magic leading chars in a path element means don't
+	     search the disk for this elt.  And move past the magic to
+	     get to the name.  */
+	  allow_disk_search = false;
+	  elt = elt.substr (2);
+	}
+
+      /* Do not touch the device if present */
+      if (NAME_BEGINS_WITH_DEVICE (elt))
+	{
+	  while (elt.length () > 3
+		 && IS_DIR_SEP (elt[2]) && IS_DIR_SEP (elt[3]))
+	    {
+	      elt[2] = elt[1];
+	      elt[1] = elt[0];
+	      elt = elt.substr (1);
+	    }
+	}
+      else
+	{
+	  /* We never want to search the whole disk.  */
+	  while (elt.length () > 1
+		 && IS_DIR_SEP (elt[0]) && IS_DIR_SEP (elt[1]))
+	    elt = elt.substr (1);
+	}
+
+      /* Try ls-R, unless we're searching for texmf.cnf.  Our caller
+	 (search), also tests first_search, and does the resetting.  */
+      found = first_search
+	? string_vector () : kpse_db_search (name, elt, all);
+
+      /* Search the filesystem if (1) the path spec allows it, and either
+         (2a) we are searching for texmf.cnf ; or
+         (2b) no db exists; or
+         (2c) no db's are relevant to this elt; or
+         (3) MUST_EXIST && NAME was not in the db.
+	 In (2*), `found' will be NULL.
+	 In (3),  `found' will be an empty list. */
+
+      if (allow_disk_search && found.empty ())
+	{
+	  str_llist_type *dirs = kpse_element_dirs (elt);
+
+	  if (dirs && *dirs)
+	    found = dir_list_search (dirs, name, all);
+	}
+
+      /* Did we find anything anywhere?  */
+      if (! found.empty ())
+	{
+	  if (all)
+	    ret_list.append (found);
+	  else
+	    {
+	      ret_list.append (found[0]);
+	      done = true;
+	    }
+	}
+    }
+
+  return ret_list;
+}
+
+/* Search PATH for ORIGINAL_NAME.  If ALL is false, or ORIGINAL_NAME is
+   absolute_p, check ORIGINAL_NAME itself.  Otherwise, look at each
+   element of PATH for the first readable ORIGINAL_NAME.
+
+   Always return a list; if no files are found, the list will
+   contain just NULL.  If ALL is true, the list will be
+   terminated with NULL.  */
+
+static string_vector
+search (const std::string& path, const std::string& original_name,
+	bool must_exist, bool all)
+{
+  string_vector ret_list;
+  bool absolute_p;
+
+  /* Make a leading ~ count as an absolute filename, and expand $FOO's.  */
+  std::string name = kpse_expand (original_name);
+
+  /* If the first name is absolute or explicitly relative, no need to
+     consider PATH at all.  */
+  absolute_p = kpse_absolute_p (name, true);
+
+  if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+    DEBUGF4 ("start search (file=%s, must_exist=%d, find_all=%d, path=%s).\n",
+             name.c_str (), must_exist, all, path.c_str ());
+
+  /* Find the file(s). */
+  ret_list = absolute_p ? absolute_search (name)
+                        : path_search (path, name, must_exist, all);
+
+  /* The very first search is for texmf.cnf.  We can't log that, since
+     we want to allow setting TEXMFLOG in texmf.cnf.  */
+  if (first_search)
+    {
+      first_search = false;
+    }
+  else
+    {
+      /* Record the filenames we found, if desired.  And wrap them in a
+	 debugging line if we're doing that.  */
+
+      if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+	DEBUGF1 ("search (%s) =>", original_name.c_str ());
+
+      log_search (ret_list);
+
+      if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+	putc ('\n', stderr);
+    }
+
+  return ret_list;
+}
+
+/* Search PATH for the first NAME.  */
+
+/* Call `kpse_expand' on NAME.  If the result is an absolute or
+   explicitly relative filename, check whether it is a readable
+   (regular) file.
+   
+   Otherwise, look in each of the directories specified in PATH (also do
+   tilde and variable expansion on elements in PATH), using a prebuilt
+   db (see db.h) if it's relevant for a given path element.
+   
+   If the prebuilt db doesn't exist, or if MUST_EXIST is true and NAME
+   isn't found in the prebuilt db, look on the filesystem.  (I.e., if
+   MUST_EXIST is false, and NAME isn't found in the db, do *not* look on
+   the filesystem.)
+   
+   The caller must expand PATH. This is because it makes more sense to
+   do this once, in advance, instead of for every search using it.
+   
+   In any case, return the complete filename if found, otherwise NULL.  */
+
+static std::string
+kpse_path_search (const std::string& path, const std::string& name,
+		  bool must_exist)
+{
+  string_vector ret_list = search (path, name, must_exist, false);
+
+  return ret_list.empty () ? std::string () : ret_list[0];
+}
+
+/* Search all elements of PATH for files named NAME.  Not sure if it's
+   right to assert `must_exist' here, but it suffices now.  */
+
+/* Like `kpse_path_search' with MUST_EXIST true, but return a list of
+   all the filenames (or NULL if none), instead of taking the first.  */
+
+static string_vector
+kpse_all_path_search (const std::string& path, const std::string& name)
+{
+  return search (path, name, true, true);
+}
+
+/* This is the hard case -- look in each element of PATH for each
+   element of NAMES.  If ALL is false, return the first file found.
+   Otherwise, search all elements of PATH.  */
+
+static string_vector
+path_find_first_of (const std::string& path, const string_vector& names,
+		    bool /* must_exist */, bool all)
+{
+  string_vector ret_list;
+  bool done = false;
+
+  for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++)
+    {
+      std::string elt = *pi;
+
+      str_llist_type *dirs;
+      str_llist_elt_type *dirs_elt;
+      string_vector found;
+      bool allow_disk_search = true;
+
+      if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!')
+	{
+	  /* Those magic leading chars in a path element means don't
+	     search the disk for this elt.  And move past the magic to
+	     get to the name.  */
+
+	  allow_disk_search = false;
+	  elt = elt.substr (2);
+	}
+
+      /* Do not touch the device if present */
+
+      if (NAME_BEGINS_WITH_DEVICE (elt))
+	{
+	  while (elt.length () > 3
+		 && IS_DIR_SEP (elt[2]) && IS_DIR_SEP (elt[3]))
+	    {
+	      elt[2] = elt[1];
+	      elt[1] = elt[0];
+	      elt = elt.substr (1);
+	    }
+	}
+      else
+	{
+	  /* We never want to search the whole disk.  */
+	  while (elt.length () > 1
+		 && IS_DIR_SEP (elt[0]) && IS_DIR_SEP (elt[1]))
+	    elt = elt.substr (1);
+	}
+
+      /* We have to search one directory at a time.  */
+      dirs = kpse_element_dirs (elt);
+      for (dirs_elt = *dirs; dirs_elt; dirs_elt = STR_LLIST_NEXT (*dirs_elt))
+	{
+	  const std::string dir = STR_LLIST (*dirs_elt);
+
+	  int len = names.length ();
+	  for (int i = 0; i < len && !done; i++)
+	    {
+	      std::string name = names[i];
+
+	      /* Try ls-R, unless we're searching for texmf.cnf.  Our caller
+		 (find_first_of), also tests first_search, and does the
+		 resetting.  */
+	      found = first_search
+		? string_vector () : kpse_db_search (name, dir.c_str (), all);
+
+	      /* Search the filesystem if (1) the path spec allows it,
+		 and either
+
+		   (2a) we are searching for texmf.cnf ; or
+		   (2b) no db exists; or
+		   (2c) no db's are relevant to this elt; or
+		   (3) MUST_EXIST && NAME was not in the db.
+
+		 In (2*), `found' will be NULL.
+		 In (3),  `found' will be an empty list. */
+
+	      if (allow_disk_search && found.empty ())
+		{
+		  static str_llist_type *tmp = 0;
+
+		  if (! tmp)
+		    {
+		      tmp = new str_llist_type;
+		      *tmp = 0;
+		      str_llist_add (tmp, "");
+		    }
+
+		  STR_LLIST (*(*tmp)) = dir;
+
+		  found = dir_list_search (tmp, name, all);
+		}
+
+	      /* Did we find anything anywhere?  */
+	      if (! found.empty ())
+		{
+		  if (all)
+		    ret_list.append (found);
+		  else
+		    {
+		      ret_list.append (found[0]);
+		      done = true;
+		    }
+		}
+	    }
+	}
+    }
+
+  return ret_list;
+}
+
+static string_vector
+find_first_of (const std::string& path, const string_vector& names,
+	       bool must_exist, bool all)
+{
+  string_vector ret_list;
+
+  if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+    {
+      fputs ("start find_first_of ((", stderr);
+
+      int len = names.length ();
+
+      for (int i = 0; i < len; i++)
+	{
+	  if (i == 0)
+	    fputs (names[i].c_str (), stderr);
+	  else
+	    fprintf (stderr, ", %s", names[i].c_str ());
+	}
+
+      fprintf (stderr, "), path=%s, must_exist=%d).\n",
+	       path.c_str (), must_exist);
+    }
+
+  for (int i = 0; i < names.length (); i++)
+    {
+      std::string name = names[i];
+
+      if (kpse_absolute_p (name, true))
+	{
+	  /* If the name is absolute or explicitly relative, no need
+	     to consider PATH at all.  If we find something, then we
+	     are done.  */
+
+	  ret_list = absolute_search (name);
+
+	  if (! ret_list.empty ())
+	    return ret_list;
+	}
+    }
+
+  /* Find the file. */
+  ret_list = path_find_first_of (path, names, must_exist, all);
+
+  /* The very first search is for texmf.cnf.  We can't log that, since
+     we want to allow setting TEXMFLOG in texmf.cnf.  */
+  if (first_search)
+    {
+      first_search = false;
+    }
+  else
+    {
+      /* Record the filenames we found, if desired.  And wrap them in a
+	 debugging line if we're doing that.  */
+
+      if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+	{
+	  fputs ("find_first_of (", stderr);
+
+	  int len = names.length ();
+
+	  for (int i = 0; i < len; i++)
+	    {
+	      if (i == 0)
+		fputs (names[i].c_str (), stderr);
+	      else
+		fprintf (stderr, ", %s", names[i].c_str ());
+	    }
+	  fputs (") =>", stderr);
+	}
+
+      log_search (ret_list);
+
+      if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+	putc ('\n', stderr);
+    }
+
+  return ret_list;
+}
+
+/* Search each element of PATH for each element of NAMES.  Return the
+   first one found.  */
+
+/* Search each element of PATH for each element in the list of NAMES.
+   Return the first one found.  */
+
+static std::string
+kpse_path_find_first_of (const std::string& path, const string_vector& names,
+			 bool must_exist)
+{
+  string_vector ret_list = find_first_of (path, names, must_exist, false);
+
+  return ret_list.empty () ? std::string () : ret_list[0];
+}
+
+/* Search each element of PATH for each element of NAMES and return a
+   list containing everything found, in the order found.  */
+
+/* Like `kpse_path_find_first_of' with MUST_EXIST true, but return a
+   list of all the filenames (or NULL if none), instead of taking the
+   first.  */
+
+static string_vector
+kpse_all_path_find_first_of (const std::string& path,
+			     const string_vector& names)
+{
+  return find_first_of (path, names, true, true);
+}
+
+/* General expansion.  Some of this file (the brace-expansion
+   code from bash) is covered by the GPL; this is the only GPL-covered
+   code in kpathsea.  The part of the file that I wrote (the first
+   couple of functions) is covered by the LGPL.  */
+
+/* If NAME has a leading ~ or ~user, Unix-style, expand it to the user's
+   home directory, and return a new malloced string.  If no ~, or no
+   <pwd.h>, just return NAME.  */
+
+static std::string
+kpse_tilde_expand (const std::string& name)
+{
+  std::string expansion;
+
+  /* If no leading tilde, do nothing.  */
+  if (name.empty () || name[0] != '~')
+    {
+      expansion = name;
+
+      /* If a bare tilde, return the home directory or `.'.  (Very
+	 unlikely that the directory name will do anyone any good, but
+	 ...  */
+    }
+  else if (name.length () == 1)
+    {
+      expansion = octave_env::getenv ("HOME");
+
+      if (expansion.empty ())
+	expansion = ".";
+
+      /* If `~/', remove any trailing / or replace leading // in $HOME.
+	 Should really check for doubled intermediate slashes, too.  */
+    }
+  else if (IS_DIR_SEP (name[1]))
+    {
+      unsigned c = 1;
+      std::string home = octave_env::getenv ("HOME");
+
+      if (home.empty ())
+	home = ".";
+
+      size_t home_len = home.length ();
+
+      /* handle leading // */
+      if (home_len > 1 && IS_DIR_SEP (home[0]) && IS_DIR_SEP (home[1]))
+	home = home.substr (1);
+
+      /* omit / after ~ */
+      if (IS_DIR_SEP (home[home_len - 1]))
+	c++;
+
+      expansion = home + name.substr (c);
+
+      /* If `~user' or `~user/', look up user in the passwd database (but
+	 OS/2 doesn't have this concept.  */
+    }
+  else
+#ifdef HAVE_PWD_H
+    {
+      unsigned c = 2;
+
+      /* find user name */
+      while (name.length () > c && ! IS_DIR_SEP (name[c]))
+        c++;
+
+      std::string user = name.substr (1, c-1);
+
+      /* We only need the cast here for (deficient) systems
+         which do not declare `getpwnam' in <pwd.h>.  */
+      octave_passwd p = octave_passwd::getpwnam (user);
+
+      /* If no such user, just use `.'.  */
+      std::string home = p ? p.dir () : std::string (".");
+
+      if (home.empty ())
+	home = ".";
+
+      /* handle leading // */
+      if (home.length () > 1 && IS_DIR_SEP (home[0]) && IS_DIR_SEP (home[1]))
+        home = home.substr (1);
+
+      /* If HOME ends in /, omit the / after ~user. */
+      if (name.length () > c && IS_DIR_SEP (home[home.length () - 1]))
+        c++;
+
+      expansion = name.length () > c ? home : home + name.substr (c);
+    }
+#else /* not HAVE_PWD_H */
+  expansion = name;
+#endif /* not HAVE_PWD_H */
+
+  return expansion;
+}
+
+/* Do variable expansion first so ~${USER} works.  (Besides, it's what the
+   shells do.)  */
+
+/* Call kpse_var_expand and kpse_tilde_expand (in that order).  Result
+   is always in fresh memory, even if no expansions were done.  */
+
+static std::string
+kpse_expand (const std::string& s)
+{
+  std::string var_expansion = kpse_var_expand (s);
+  return kpse_tilde_expand (var_expansion);
+}
+
+/* Forward declarations of functions from the original expand.c  */
+static string_vector brace_expand (const std::string&);
+
+/* If $KPSE_DOT is defined in the environment, prepend it to any relative
+   path components. */
+
+static std::string
+kpse_expand_kpse_dot (const std::string& path)
+{
+  std::string ret;
+  std::string kpse_dot = octave_env::getenv ("KPSE_DOT");
+
+  if (kpse_dot.empty ())
+    return path;
+
+  for (kpse_path_iterator pi (path); pi != std::string::npos; pi++)
+    {
+      std::string elt = *pi;
+
+      /* We assume that the !! magic is only used on absolute components.
+	 Single "." get special treatment, as does "./" or its  equivalent.  */
+
+      size_t elt_len = elt.length ();
+
+      if (kpse_absolute_p (elt, false)
+	  || (elt_len > 1 && elt[0] == '!' && elt[1] == '!'))
+	ret += elt + ENV_SEP_STRING;
+      else if (elt_len == 1 && elt[0] == '.')
+	ret += kpse_dot + ENV_SEP_STRING;
+      else if (elt_len > 1 && elt[0] == '.' && IS_DIR_SEP (elt[1]))
+	ret += kpse_dot + elt.substr (1) + ENV_SEP_STRING;
+      else
+	ret += kpse_dot + DIR_SEP_STRING + elt + ENV_SEP_STRING;
+    }
+
+  int len = ret.length ();
+  if (len > 0)
+    ret.resize (len-1);
+
+  return ret;
+}
+
+/* Do brace expansion on ELT; then do variable and ~ expansion on each
+   element of the result; then do brace expansion again, in case a
+   variable definition contained braces (e.g., $TEXMF).  Return a
+   string comprising all of the results separated by ENV_SEP_STRING.  */
+
+static std::string
+kpse_brace_expand_element (const std::string& elt)
+{
+  std::string ret;
+
+  string_vector expansions = brace_expand (elt);
+
+  for (int i = 0; i < expansions.length (); i++)
+    {
+      /* Do $ and ~ expansion on each element.  */
+      std::string x = kpse_expand (expansions[i]);
+
+      if (x != expansions[i])
+	{
+	  /* If we did any expansions, do brace expansion again.  Since
+	     recursive variable definitions are not allowed, this recursion
+	     must terminate.  (In practice, it's unlikely there will ever be
+	     more than one level of recursion.)  */
+	  x = kpse_brace_expand_element (x);
+	}
+
+      ret += x + ENV_SEP_STRING;
+    }
+
+  ret.resize (ret.length () - 1);
+
+  return ret;
+}
+
+/* Do brace expansion and call `kpse_expand' on each element of the
+   result; return the final expansion (always in fresh memory, even if
+   no expansions were done).  We don't call `kpse_expand_default'
+   because there is a whole sequence of defaults to run through; see
+   `kpse_init_format'.  */
+
+static std::string
+kpse_brace_expand (const std::string& path)
+{
+  /* Must do variable expansion first because if we have
+       foo = .:~
+       TEXINPUTS = $foo
+     we want to end up with TEXINPUTS = .:/home/karl.
+     Since kpse_path_element is not reentrant, we must get all
+     the path elements before we start the loop.  */
+  std::string tmp = kpse_var_expand (path);
+
+  std::string ret;
+
+  for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++)
+    {
+      std::string elt = *pi;
+
+      /* Do brace expansion first, so tilde expansion happens in {~ka,~kb}.  */
+      std::string expansion = kpse_brace_expand_element (elt);
+      ret += expansion + ENV_SEP_STRING;
+    }
+
+  size_t len = ret.length ();
+  if (len > 0)
+    ret.resize (len-1);
+
+  return kpse_expand_kpse_dot (ret);
+}
+
+/* Expand all special constructs in a path, and include only the actually
+   existing directories in the result. */
+
+/* Do brace expansion and call `kpse_expand' on each argument of the
+   result, then expand any `//' constructs.  The final expansion (always
+   in fresh memory) is a path of all the existing directories that match
+   the pattern. */
+
+static std::string
+kpse_path_expand (const std::string& path)
+{
+  std::string ret;
+  unsigned len;
+
+  len = 0;
+
+  /* Expand variables and braces first.  */
+  std::string tmp = kpse_brace_expand (path);
+
+  /* Now expand each of the path elements, printing the results */
+  for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++)
+    {
+      std::string elt = *pi;
+
+      str_llist_type *dirs;
+
+      /* Skip and ignore magic leading chars.  */
+      if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!')
+	elt = elt.substr (2);
+
+      /* Do not touch the device if present */
+      if (NAME_BEGINS_WITH_DEVICE (elt))
+	{
+	  while (elt.length () > 3
+		 && IS_DIR_SEP (elt[2]) && IS_DIR_SEP (elt[3]))
+	    {
+	      elt[2] = elt[1];
+	      elt[1] = elt[0];
+	      elt = elt.substr (1);
+	    }
+	}
+      else
+	{
+	  /* We never want to search the whole disk.  */
+	  while (elt.length () > 1
+		 && IS_DIR_SEP (elt[0]) && IS_DIR_SEP (elt[1]))
+	    elt = elt.substr (1);
+	}
+
+      /* Search the disk for all dirs in the component specified.
+	 Be faster to check the database, but this is more reliable.  */
+      dirs = kpse_element_dirs (elt);
+
+      if (dirs && *dirs)
+	{
+	  str_llist_elt_type *dir;
+
+	  for (dir = *dirs; dir; dir = STR_LLIST_NEXT (*dir))
+	    {
+	      const std::string thedir = STR_LLIST (*dir);
+	      unsigned dirlen = thedir.length ();
+
+	      ret += thedir;
+	      len += dirlen;
+
+	      /* Retain trailing slash if that's the root directory.  */
+	      if (dirlen == 1
+		  || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (thedir)
+		      && IS_DIR_SEP (thedir[2])))
+		{
+		  ret += ENV_SEP_STRING;
+		  len++;
+		}
+
+	      ret[len-1] = ENV_SEP;
+	    }
+	}
+    }
+
+  if (len > 0)
+    ret.resize (len-1);
+
+  return ret;
+}
+
+/* braces.c -- code for doing word expansion in curly braces. Taken from
+   bash 1.14.5.  [Ans subsequently modified for kpatshea.]
+
+   Copyright (C) 1987,1991 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define brace_whitespace(c) (! (c) || (c) == ' ' || (c) == '\t' || (c) == '\n')
+
+/* Basic idea:
+
+   Segregate the text into 3 sections: preamble (stuff before an open brace),
+   postamble (stuff after the matching close brace) and amble (stuff after
+   preamble, and before postamble).  Expand amble, and then tack on the
+   expansions to preamble.  Expand postamble, and tack on the expansions to
+   the result so far.  */
+
+/* Return a new array of strings which is the result of appending each
+   string in ARR2 to each string in ARR1.  The resultant array is
+   len (arr1) * len (arr2) long.  For convenience, ARR1 (and its contents)
+   are free ()'ed.  ARR1 can be NULL, in that case, a new version of ARR2
+   is returned. */
+
+static string_vector
+array_concat (const string_vector& arr1, const string_vector& arr2)
+{
+  string_vector result;
+
+  if (arr1.empty ())
+    result = arr2;
+  else if (arr2.empty ())
+    result = arr1;
+  else
+    {
+      int len1 = arr1.length ();
+      int len2 = arr2.length ();
+
+      result = string_vector (len1 * len2);
+
+      int k = 0;
+      for (int i = 0; i < len2; i++)
+	for (int j = 0; j < len1; j++)
+	  result[k++] = arr1[j] + arr2[i];
+    }
+
+  return result;
+}
+
+static int brace_gobbler (const std::string&, int&, int);
+static string_vector expand_amble (const std::string&);
+
+/* Return an array of strings; the brace expansion of TEXT. */
+static string_vector
+brace_expand (const std::string& text)
+{
+  /* Find the text of the preamble. */
+  int i = 0;
+  int c = brace_gobbler (text, i, '{');
+
+  std::string preamble = text.substr (0, i);
+
+  string_vector result = string_vector (preamble);
+
+  if (c == '{')
+    {
+      /* Find the amble.  This is the stuff inside this set of braces. */
+      int start = ++i;
+      c = brace_gobbler (text, i, '}');
+
+      /* What if there isn't a matching close brace? */
+      if (! c)
+	{
+	  (*current_liboctave_warning_handler)
+	    ("%s: Unmatched {", text.c_str ());
+
+	  result = string_vector (text);
+	}
+      else
+	{
+	  std::string amble = text.substr (start, i-start);
+	  result = array_concat (result, expand_amble (amble));
+
+	  std::string postamble = text.substr (i+1);
+	  result = array_concat (result, brace_expand (postamble));
+	}
+    }
+
+  return result;
+}
+
+/* The character which is used to separate arguments. */
+static int brace_arg_separator = ',';
+
+/* Expand the text found inside of braces.  We simply try to split the
+   text at BRACE_ARG_SEPARATORs into separate strings.  We then brace
+   expand each slot which needs it, until there are no more slots which
+   need it. */
+static string_vector
+expand_amble (const std::string& text)
+{
+  string_vector result;
+
+  size_t text_len = text.length ();
+  size_t start;
+  int i, c;
+
+  for (start = 0, i = 0, c = 1; c && start < text_len; start = ++i)
+    {
+      int i0 = i;
+      int c0 = brace_gobbler (text, i0, brace_arg_separator);
+      int i1 = i;
+      int c1 = brace_gobbler (text, i1, ENV_SEP);
+      c = c0 | c1;
+      i = (i0 < i1 ? i0 : i1);
+
+      std::string tem = text.substr (start, i-start);
+
+      string_vector partial = brace_expand (tem);
+
+      if (result.empty ())
+	result = partial;
+      else
+	result.append (partial);
+    }
+
+  return result;
+}
+
+/* Start at INDEX, and skip characters in TEXT. Set INDEX to the
+   index of the character matching SATISFY.  This understands about
+   quoting.  Return the character that caused us to stop searching;
+   this is either the same as SATISFY, or 0. */
+static int
+brace_gobbler (const std::string& text, int& indx, int satisfy)
+{
+  int c = 0, level = 0, quoted = 0, pass_next = 0;
+
+  size_t text_len = text.length ();
+
+  size_t i = indx;
+
+  for (; i < text_len; i++)
+    {
+      c = text[i];
+
+      if (pass_next)
+	{
+	  pass_next = 0;
+	  continue;
+	}
+
+      /* A backslash escapes the next character.  This allows backslash to
+	 escape the quote character in a double-quoted string. */
+      if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
+        {
+          pass_next = 1;
+          continue;
+        }
+
+      if (quoted)
+	{
+	  if (c == quoted)
+	    quoted = 0;
+	  continue;
+	}
+
+      if (c == '"' || c == '\'' || c == '`')
+	{
+	  quoted = c;
+	  continue;
+	}
+
+      if (c == satisfy && !level && !quoted)
+	{
+	  /* We ignore an open brace surrounded by whitespace, and also
+	     an open brace followed immediately by a close brace, that
+	     was preceded with whitespace.  */
+	  if (c == '{' &&
+	      ((i == 0 || brace_whitespace (text[i-1])) &&
+	       (i+1 < text_len &&
+		(brace_whitespace (text[i+1]) || text[i+1] == '}'))))
+	    continue;
+	  /* If this is being compiled as part of bash, ignore the `{'
+	     in a `${}' construct */
+	  if ((c != '{') || i == 0 || (text[i-1] != '$'))
+	    break;
+	}
+
+      if (c == '{')
+	level++;
+      else if (c == '}' && level)
+	level--;
+    }
+
+  indx = i;
+  return c;
+}
+
+/* For each file format, we record the following information.  The main
+   thing that is not part of this structure is the environment variable
+   lists. They are used directly in tex-file.c. We could incorporate
+   them here, but it would complicate the code a bit. We could also do
+   it via variable expansion, but not now, maybe not ever:
+   ${PKFONTS-${TEXFONTS-/usr/local/lib/texmf/fonts//}}.  */
+
+struct kpse_format_info_type
+{
+  std::string type;	     /* Human-readable description.  */
+  std::string path;	     /* The search path to use.  */
+  std::string raw_path;	     /* Pre-$~ (but post-default) expansion.  */
+  std::string path_source;   /* Where the path started from.  */
+  std::string override_path; /* From client environment variable.  */
+  std::string client_path;   /* E.g., from dvips's config.ps.  */
+  std::string cnf_path;	     /* From texmf.cnf.  */
+  std::string default_path;  /* If all else fails.  */
+  string_vector suffix;	     /* For kpse_find_file to check for/append.  */
+};
+
+/* The sole variable of that type, indexed by `kpse_file_format_type'.
+   Initialized by calls to `kpse_find_file' for `kpse_init_format'.  */
+static kpse_format_info_type kpse_format_info;
+
+/* And EXPAND_DEFAULT calls kpse_expand_default on try_path and the
+   present info->path.  */
+#define EXPAND_DEFAULT(try_path, source_string) \
+  do \
+    { \
+      if (! try_path.empty ()) \
+        { \
+          info.raw_path = try_path;	\
+          info.path = kpse_expand_default (try_path, info.path); \
+          info.path_source = source_string;	\
+        } \
+    } \
+  while (0)
+
+static hash_table_type db; /* The hash table for all the ls-R's.  */
+
+static hash_table_type alias_db;
+
+static string_vector db_dir_list;
+
+/* Return true if FILENAME could be in PATH_ELT, i.e., if the directory
+   part of FILENAME matches PATH_ELT.  Have to consider // wildcards, but
+   $ and ~ expansion have already been done.  */
+
+static bool
+match (const std::string& filename_arg, const std::string& path_elt_arg)
+{
+  const char *filename = filename_arg.c_str ();
+  const char *path_elt = path_elt_arg.c_str ();
+
+  const char *original_filename = filename;
+  bool matched = false;
+
+  for (; *filename && *path_elt; filename++, path_elt++)
+    {
+      if (*filename == *path_elt) /* normal character match */
+	;
+
+      else if (IS_DIR_SEP (*path_elt)  /* at // */
+	       && original_filename < filename && IS_DIR_SEP (path_elt[-1]))
+	{
+	  while (IS_DIR_SEP (*path_elt))
+	    path_elt++; /* get past second and any subsequent /'s */
+
+	  if (*path_elt == 0)
+	    {
+	      /* Trailing //, matches anything. We could make this
+		 part of the other case, but it seems pointless to do
+		 the extra work.  */
+	      matched = true;
+	      break;
+	    }
+	  else
+	    {
+	      /* Intermediate //, have to match rest of PATH_ELT.  */
+	      for (; !matched && *filename; filename++)
+		{
+		  /* Try matching at each possible character.  */
+		  if (IS_DIR_SEP (filename[-1]) && *filename == *path_elt)
+		    matched = match (filename, path_elt);
+		}
+
+	      /* Prevent filename++ when *filename='\0'. */
+	      break;
+	    }
+	}
+      else
+	/* normal character nonmatch, quit */
+	break;
+    }
+
+  /* If we've reached the end of PATH_ELT, check that we're at the last
+     component of FILENAME, we've matched.  */
+  if (! matched && *path_elt == 0)
+    {
+      /* Probably PATH_ELT ended with `vf' or some such, and FILENAME
+	 ends with `vf/ptmr.vf'.  In that case, we'll be at a
+	 directory separator.  On the other hand, if PATH_ELT ended
+	 with a / (as in `vf/'), FILENAME being the same `vf/ptmr.vf',
+	 we'll be at the `p'.  Upshot: if we're at a dir separator in
+	 FILENAME, skip it.  But if not, that's ok, as long as there
+	 are no more dir separators.  */
+
+      if (IS_DIR_SEP (*filename))
+	filename++;
+
+      while (*filename && !IS_DIR_SEP (*filename))
+	filename++;
+
+      matched = *filename == 0;
+    }
+
+  return matched;
+}
+
+/* If DB_DIR is a prefix of PATH_ELT, return true; otherwise false.
+   That is, the question is whether to try the db for a file looked up
+   in PATH_ELT.  If PATH_ELT == ".", for example, the answer is no. If
+   PATH_ELT == "/usr/local/lib/texmf/fonts//tfm", the answer is yes.
+
+   In practice, ls-R is only needed for lengthy subdirectory
+   comparisons, but there's no gain to checking PATH_ELT to see if it is
+   a subdir match, since the only way to do that is to do a string
+   search in it, which is all we do anyway.  */
+
+static bool
+elt_in_db (const std::string& db_dir, const std::string& path_elt)
+{
+  bool found = false;
+
+  size_t db_dir_len = db_dir.length ();
+  size_t path_elt_len = path_elt.length ();
+
+  size_t i = 0;
+
+  while (! found && db_dir[i] == path_elt[i])
+    {
+      i++;
+      /* If we've matched the entire db directory, it's good.  */
+      if (i == db_dir_len)
+	found = true;
+
+    /* If we've reached the end of PATH_ELT, but not the end of the db
+       directory, it's no good.  */
+      else if (i == path_elt_len)
+	break;
+    }
+
+  return found;
+}
+
+/* Avoid doing anything if this PATH_ELT is irrelevant to the databases. */
+
+/* Return list of matches for NAME in the ls-R file matching PATH_ELT.  If
+   ALL is set, return (null-terminated list) of all matches, else just
+   the first.  If no matches, return a pointer to an empty list.  If no
+   databases can be read, or PATH_ELT is not in any of the databases,
+   return NULL.  */
+
+static string_vector
+kpse_db_search (const std::string& name_arg,
+		const std::string& orig_path_elt, bool all)
+{
+  bool done;
+  string_vector ret;
+  string_vector aliases;
+  bool relevant = false;
+
+  std::string name = name_arg;
+
+  /* If we failed to build the database (or if this is the recursive
+     call to build the db path), quit.  */
+  if (! db.buckets)
+    return ret;
+
+  /* When tex-glyph.c calls us looking for, e.g., dpi600/cmr10.pk, we
+     won't find it unless we change NAME to just `cmr10.pk' and append
+     `/dpi600' to PATH_ELT.  We are justified in using a literal `/'
+     here, since that's what tex-glyph.c unconditionally uses in
+     DPI_BITMAP_SPEC.  But don't do anything if the / begins NAME; that
+     should never happen.  */
+  std::string path_elt;
+  size_t last_slash = name.rfind ('/');
+  if (last_slash != std::string::npos && last_slash != 0)
+    {
+      std::string dir_part = name.substr (0, last_slash);
+      name = name.substr (last_slash + 1);
+    }
+  else
+    path_elt = orig_path_elt;
+
+  /* Don't bother doing any lookups if this `path_elt' isn't covered by
+     any of database directories.  We do this not so much because the
+     extra couple of hash lookups matter -- they don't -- but rather
+     because we want to return NULL in this case, so path_search can
+     know to do a disk search.  */
+  for (int e = 0; ! relevant && e < db_dir_list.length (); e++)
+    relevant = elt_in_db (db_dir_list[e], path_elt);
+
+  if (! relevant)
+    return ret;
+
+  /* If we have aliases for this name, use them.  */
+  if (alias_db.buckets)
+    aliases = hash_lookup (alias_db, name);
+
+  /* Push aliases up by one and insert the original name at the front.  */
+  int len = aliases.length ();
+  aliases.resize (len+1);
+  for (int i = len; i > 0; i--)
+    aliases[i] = aliases[i - 1];
+  aliases[0] = name;
+
+  done = false;
+  len = aliases.length ();
+  for (int i = 0; i < len && !done; i++)
+    {
+      std::string atry = aliases[i];
+
+      /* We have an ls-R db.  Look up `atry'.  */
+      string_vector db_dirs = hash_lookup (db, atry);
+
+      /* For each filename found, see if it matches the path element.  For
+	 example, if we have .../cx/cmr10.300pk and .../ricoh/cmr10.300pk,
+	 and the path looks like .../cx, we don't want the ricoh file.  */
+
+      int db_dirs_len = db_dirs.length ();
+      for (int j = 0; j < db_dirs_len && !done; j++)
+	{
+	  std::string db_file = db_dirs[j] + atry;
+	  bool matched = match (db_file, path_elt);
+
+#ifdef KPSE_DEBUG
+	  if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
+	    DEBUGF3 ("db:match (%s,%s) = %d\n", db_file.c_str (), path_elt.c_str (), matched);
+#endif
+
+	  /* We got a hit in the database.  Now see if the file actually
+	     exists, possibly under an alias.  */
+	  if (matched)
+	    {
+	      std::string found;
+	      std::string tmp = kpse_readable_file (db_file);
+	      if (! tmp.empty ())
+		found = db_file;
+	      else
+		{
+		  /* The hit in the DB doesn't exist in disk.  Now try
+		     all its aliases.  For example, suppose we have a
+		     hierarchy on CD, thus `mf.bas', but ls-R contains
+		     `mf.base'.  Find it anyway.  Could probably work
+		     around this with aliases, but this is pretty easy
+		     and shouldn't hurt.  The upshot is that if one of
+		     the aliases actually exists, we use that.  */
+
+		  int aliases_len = aliases.length ();
+
+		  for (int k = 1; k < aliases_len && found.empty (); k++)
+		    {
+		      std::string aatry = db_dirs[j] + aliases[k];
+		      tmp = kpse_readable_file (aatry);
+		      if (! tmp.empty ())
+			found = aatry;
+		    }
+		}
+
+	      /* If we have a real file, add it to the list, maybe done.  */
+	      if (! found.empty ())
+		{
+		  ret.append (found);
+
+		  if (! (all || found.empty ()))
+		    done = true;
+		}
+	    }
+	}
+    }
+
+  return ret;
+}
+
+/* Expand extra colons.  */
+
+/* Check for leading colon first, then trailing, then doubled, since
+   that is fastest.  Usually it will be leading or trailing.  */
+
+/* Replace a leading or trailing or doubled : in PATH with DFLT.  If
+   no extra colons, return PATH.  Only one extra colon is replaced.
+   DFLT may not be NULL.  */
+
+static std::string
+kpse_expand_default (const std::string& path, const std::string& fallback)
+{
+  std::string expansion;
+
+  size_t path_len = path.length ();
+
+  if (path_len == 0)
+    expansion = fallback;
+
+  /* Solitary or leading :?  */
+  else if (IS_ENV_SEP (path[0]))
+    {
+      expansion = path_len == 1 ? fallback : fallback + path;
+    }
+
+  /* Sorry about the assignment in the middle of the expression, but
+     conventions were made to be flouted and all that.  I don't see the
+     point of calling strlen twice or complicating the logic just to
+     avoid the assignment (especially now that I've pointed it out at
+     such great length).  */
+  else if (IS_ENV_SEP (path[path_len-1]))
+    expansion = path + fallback;
+
+  /* OK, not leading or trailing.  Check for doubled.  */
+  else
+    {
+      /* What we'll return if we find none.  */
+      expansion = path;
+
+      for (size_t i = 0; i < path_len; i++)
+        {
+          if (i + 1 < path_len
+	      && IS_ENV_SEP (path[i]) && IS_ENV_SEP (path[i+1]))
+            {
+	      /* We have a doubled colon.  */
+
+              /* Copy stuff up to and including the first colon.  */
+              /* Copy in FALLBACK, and then the rest of PATH.  */
+	      expansion = path.substr (0, i+1) + fallback + path.substr (i+1);
+
+	      break;
+            }
+        }
+    }
+
+  return expansion;
+}
+
+/* Translate a path element to its corresponding director{y,ies}.  */
+
+/* To avoid giving prototypes for all the routines and then their real
+   definitions, we give all the subroutines first.  The entry point is
+   the last routine in the file.  */
+
+/* Make a copy of DIR (unless it's null) and save it in L.  Ensure that
+   DIR ends with a DIR_SEP for the benefit of later searches.  */
+
+static void
+dir_list_add (str_llist_type *l, const std::string& dir)
+{
+  char last_char = dir[dir.length () - 1];
+
+  std::string saved_dir = dir;
+
+  if (! (IS_DIR_SEP (last_char) || IS_DEVICE_SEP (last_char)))
+    saved_dir += DIR_SEP_STRING;
+
+  str_llist_add (l, saved_dir);
+}
+
+/* Return true if FN is a directory or a symlink to a directory,
+   false if not. */
+
+static bool
+dir_p (const std::string& fn)
+{
+#ifdef WIN32
+  unsigned int fa = GetFileAttributes (fn.c_str ());
+  return (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
+#else
+  struct stat stats;
+  return stat (fn.c_str (), &stats) == 0 && S_ISDIR (stats.st_mode);
+#endif
+}
+
+/* If DIR is a directory, add it to the list L.  */
+
+static void
+checked_dir_list_add (str_llist_type *l, const std::string& dir)
+{
+  if (dir_p (dir))
+    dir_list_add (l, dir);
+}
+
+/* The cache.  Typically, several paths have the same element; for
+   example, /usr/local/lib/texmf/fonts//.  We don't want to compute the
+   expansion of such a thing more than once.  Even though we also cache
+   the dir_links call, that's not enough -- without this path element
+   caching as well, the execution time doubles.  */
+
+struct cache_entry
+{
+  std::string key;
+  str_llist_type *value;
+};
+
+static cache_entry *the_cache = 0;
+static unsigned cache_length = 0;
+
+/* Associate KEY with VALUE.  We implement the cache as a simple linear
+   list, since it's unlikely to ever be more than a dozen or so elements
+   long.  We don't bother to check here if PATH has already been saved;
+   we always add it to our list.  We copy KEY but not VALUE; not sure
+   that's right, but it seems to be all that's needed.  */
+
+static void
+cache (const std::string key, str_llist_type *value)
+{
+  cache_entry *new_cache = new cache_entry [cache_length+1];
+
+  for (unsigned i = 0; i < cache_length; i++)
+    {
+      new_cache[i].key = the_cache[i].key;
+      new_cache[i].value = the_cache[i].value;
+    }
+
+  delete [] the_cache;
+
+  the_cache = new_cache;
+
+  the_cache[cache_length].key = key;
+  the_cache[cache_length].value = value;
+
+  cache_length++;
+}
+
+/* To retrieve, just check the list in order.  */
+
+static str_llist_type *
+cached (const std::string& key)
+{
+  unsigned p;
+
+  for (p = 0; p < cache_length; p++)
+    {
+      if (key == the_cache[p].key)
+        return the_cache[p].value;
+    }
+
+  return 0;
+}
+
+/* Handle the magic path constructs.  */
+
+/* Declare recursively called routine.  */
+static void expand_elt (str_llist_type *, const std::string&, unsigned);
+
+/* POST is a pointer into the original element (which may no longer be
+   ELT) to just after the doubled DIR_SEP, perhaps to the null.  Append
+   subdirectories of ELT (up to ELT_LENGTH, which must be a /) to
+   STR_LIST_PTR.  */
+
+#ifdef WIN32
+
+/* Shared across recursive calls, it acts like a stack. */
+static std::string dirname;
+
+#else /* WIN32 */
+
+/* Return -1 if FN isn't a directory, else its number of links.
+   Duplicate the call to stat; no need to incur overhead of a function
+   call for that little bit of cleanliness. */
+
+static int
+dir_links (const std::string& fn)
+{
+  std::map<std::string, long> link_table;
+
+  long ret;
+
+  if (link_table.find (fn) != link_table.end ())
+    ret = link_table[fn];
+  else
+    {
+      struct stat stats;
+
+      ret = stat (fn.c_str (), &stats) == 0 && S_ISDIR (stats.st_mode)
+	? stats.st_nlink : static_cast<unsigned> (-1);
+
+      link_table[fn] = ret;
+
+#ifdef KPSE_DEBUG
+      if (KPSE_DEBUG_P (KPSE_DEBUG_STAT))
+        DEBUGF2 ("dir_links (%s) => %ld\n", fn.c_str (), ret);
+#endif
+    }
+
+  return ret;
+}
+
+#endif /* WIN32 */
+
+static void
+do_subdir (str_llist_type *str_list_ptr, const std::string& elt,
+	   unsigned elt_length, const std::string& post)
+{
+#ifdef WIN32
+  WIN32_FIND_DATA find_file_data;
+  HANDLE hnd;
+  int proceed;
+#else
+  DIR *dir;
+  struct dirent *e;
+#endif /* not WIN32 */
+
+  std::string name = elt.substr (0, elt_length);
+
+  assert (IS_DIR_SEP (elt[elt_length - 1])
+          || IS_DEVICE_SEP (elt[elt_length - 1]));
+
+#if defined (WIN32)
+
+  dirname = name + "/*.*";         /* "*.*" or "*" -- seems equivalent. */
+
+  hnd = FindFirstFile (dirname.c_str (), &find_file_data);
+
+  if (hnd == INVALID_HANDLE_VALUE)
+    return;
+
+  /* Include top level before subdirectories, if nothing to match.  */
+  if (post.empty ())
+    dir_list_add (str_list_ptr, name);
+  else
+    {
+      /* If we do have something to match, see if it exists.  For
+	 example, POST might be `pk/ljfour', and they might have a
+	 directory `$TEXMF/fonts/pk/ljfour' that we should find.  */
+      name += post;
+      expand_elt (str_list_ptr, name, elt_length);
+      name.resize (elt_length);
+    }
+
+  proceed = 1;
+
+  while (proceed)
+    {
+      if (find_file_data.cFileName[0] != '.')
+	{
+	  /* Construct the potential subdirectory name.  */
+	  name += find_file_data.cFileName;
+
+	  if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+	    {
+	      /* It's a directory, so append the separator.  */
+	      name += DIR_SEP_STRING;
+	      unsigned potential_len = name.length ();
+
+	      do_subdir (str_list_ptr, name, potential_len, post);
+	    }
+	  name.resize (elt_length);
+	}
+
+      proceed = FindNextFile (hnd, &find_file_data);
+    }
+
+  FindClose (hnd);
+
+#else /* not WIN32 */
+
+  /* If we can't open it, quit.  */
+  dir = opendir (name.c_str ());
+
+  if (! dir)
+    return;
+
+  /* Include top level before subdirectories, if nothing to match.  */
+  if (post.empty ())
+    dir_list_add (str_list_ptr, name);
+  else
+    {
+      /* If we do have something to match, see if it exists.  For
+         example, POST might be `pk/ljfour', and they might have a
+         directory `$TEXMF/fonts/pk/ljfour' that we should find.  */
+      name += post;
+      expand_elt (str_list_ptr, name, elt_length);
+      name.resize (elt_length);
+    }
+
+  while ((e = readdir (dir)))
+    {
+      /* If it begins with a `.', never mind.  (This allows ``hidden''
+         directories that the algorithm won't find.)  */
+
+      if (e->d_name[0] != '.')
+        {
+          int links;
+
+          /* Construct the potential subdirectory name.  */
+          name += e->d_name;
+
+          /* If we can't stat it, or if it isn't a directory, continue.  */
+          links = dir_links (name);
+
+          if (links >= 0)
+            {
+              /* It's a directory, so append the separator.  */
+              name += DIR_SEP_STRING;
+              unsigned potential_len = name.length ();
+
+              /* Should we recurse?  To see if the subdirectory is a
+                 leaf, check if it has two links (one for . and one for
+                 ..).  This means that symbolic links to directories do
+                 not affect the leaf-ness.  This is arguably wrong, but
+                 the only alternative I know of is to stat every entry
+                 in the directory, and that is unacceptably slow.
+
+                 The #ifdef here makes all this configurable at
+                 compile-time, so that if we're using VMS directories or
+                 some such, we can still find subdirectories, even if it
+                 is much slower.  */
+#ifdef ST_NLINK_TRICK
+              if (links != 2)
+#endif /* not ST_NLINK_TRICK */
+                /* All criteria are met; find subdirectories.  */
+                do_subdir (str_list_ptr, name, potential_len, post);
+#ifdef ST_NLINK_TRICK
+              else if (post.empty ())
+                /* Nothing to match, no recursive subdirectories to
+                   look for: we're done with this branch.  Add it.  */
+                dir_list_add (str_list_ptr, name);
+#endif
+            }
+
+          /* Remove the directory entry we just checked from `name'.  */
+          name.resize (elt_length);
+        }
+    }
+
+  xclosedir (dir);
+#endif /* not WIN32 */
+}
+
+/* Assume ELT is non-empty and non-NULL.  Return list of corresponding
+   directories (with no terminating NULL entry) in STR_LIST_PTR.  Start
+   looking for magic constructs at START.  */
+
+static void
+expand_elt (str_llist_type *str_list_ptr, const std::string& elt,
+	    unsigned /* start */)
+{
+#if 0
+  // We don't want magic constructs.
+
+  size_t elt_len = elt.length ();
+
+  size_t dir = start;
+
+
+  while (dir < elt_len)
+    {
+      if (IS_DIR_SEP (elt[dir]))
+        {
+          /* If two or more consecutive /'s, find subdirectories.  */
+          if (++dir < elt_len && IS_DIR_SEP (elt[dir]))
+            {
+	      size_t i = dir;
+	      while (i < elt_len && IS_DIR_SEP (elt[i]))
+		i++;
+
+	      std::string post = elt.substr (i);
+
+              do_subdir (str_list_ptr, elt, dir, post);
+
+	      return;
+            }
+
+          /* No special stuff at this slash.  Keep going.  */
+        }
+      else
+	dir++;
+    }
+#endif
+
+  /* When we reach the end of ELT, it will be a normal filename.  */
+  checked_dir_list_add (str_list_ptr, elt);
+}
+
+/* Here is the entry point.  Returns directory list for ELT.  */
+
+/* Given a path element ELT, return a pointer to a NULL-terminated list
+   of the corresponding (existing) directory or directories, with
+   trailing slashes, or NULL.  If ELT is the empty string, check the
+   current working directory.
+   
+   It's up to the caller to expand ELT.  This is because this routine is
+   most likely only useful to be called from `kpse_path_search', which
+   has already assumed expansion has been done.  */
+
+static str_llist_type *
+kpse_element_dirs (const std::string& elt)
+{
+  str_llist_type *ret;
+
+  /* If given nothing, return nothing.  */
+  if (elt.empty ())
+    return 0;
+
+  /* If we've already cached the answer for ELT, return it.  */
+  ret = cached (elt);
+  if (ret)
+    return ret;
+
+  /* We're going to have a real directory list to return.  */
+  ret = new str_llist_type;
+  *ret = 0;
+
+  /* We handle the hard case in a subroutine.  */
+  expand_elt (ret, elt, 0);
+
+  /* Remember the directory list we just found, in case future calls are
+     made with the same ELT.  */
+  cache (elt, ret);
+
+#ifdef KPSE_DEBUG
+  if (KPSE_DEBUG_P (KPSE_DEBUG_EXPAND))
+    {
+      DEBUGF1 ("path element %s =>", elt.c_str ());
+      if (ret)
+        {
+          str_llist_elt_type *e;
+          for (e = *ret; e; e = STR_LLIST_NEXT (*e))
+            fprintf (stderr, " %s", (STR_LLIST (*e)).c_str ());
+        }
+      putc ('\n', stderr);
+      fflush (stderr);
+    }
+#endif /* KPSE_DEBUG */
+
+  return ret;
+}
+
+#ifndef WIN32
+void
+xclosedir (DIR *d)
+{
+#ifdef CLOSEDIR_VOID
+  closedir (d);
+#else
+  int ret = closedir (d);
+
+  if (ret != 0)
+    FATAL ("closedir failed");
+#endif
+}
+#endif
+
+/* Help the user discover what's going on.  */
+
+#ifdef KPSE_DEBUG
+
+/* If the real definitions of fopen or fclose are macros, we lose -- the
+   #undef won't restore them. */
+
+static FILE *
+fopen (const char *filename, const char *mode)
+{
+#undef fopen
+  FILE *ret = fopen (filename, mode);
+
+  if (KPSE_DEBUG_P (KPSE_DEBUG_FOPEN))
+    DEBUGF3 ("fopen (%s, %s) => 0x%lx\n", filename, mode,
+	     reinterpret_cast<unsigned long> (ret));
+
+  return ret;
+}
+
+#endif
+
+/* Implementation of a linked list of strings.  */
+
+/* Add the new string STR to the end of the list L.  */
+
+static void
+str_llist_add (str_llist_type *l, const std::string& str)
+{
+  str_llist_elt_type *e;
+  str_llist_elt_type *new_elt = new str_llist_elt_type;
+
+  /* The new element will be at the end of the list.  */
+  STR_LLIST (*new_elt) = str;
+  STR_LLIST_MOVED (*new_elt) = 0;
+  STR_LLIST_NEXT (*new_elt) = 0;
+
+  /* Find the current end of the list.  */
+  for (e = *l; e && STR_LLIST_NEXT (*e); e = STR_LLIST_NEXT (*e))
+    ;
+
+  if (! e)
+    *l = new_elt;
+  else
+    STR_LLIST_NEXT (*e) = new_elt;
+}
+
+/* Move an element towards the top. The idea is that when a file is
+   found in a given directory, later files will likely be in that same
+   directory, and looking for the file in all the directories in between
+   is thus a waste.  */
+
+static void
+str_llist_float (str_llist_type *l, str_llist_elt_type *mover)
+{
+  str_llist_elt_type *last_moved, *unmoved;
+
+  /* If we've already moved this element, never mind.  */
+  if (STR_LLIST_MOVED (*mover))
+    return;
+
+  /* Find the first unmoved element (to insert before).  We're
+     guaranteed this will terminate, since MOVER itself is currently
+     unmoved, and it must be in L (by hypothesis).  */
+  for (last_moved = 0, unmoved = *l; STR_LLIST_MOVED (*unmoved);
+       last_moved = unmoved, unmoved = STR_LLIST_NEXT (*unmoved))
+    ;
+
+  /* If we are the first unmoved element, nothing to relink.  */
+  if (unmoved != mover)
+    { /* Remember `mover's current successor, so we can relink `mover's
+         predecessor to it.  */
+      str_llist_elt_type *before_mover;
+      str_llist_elt_type *after_mover = STR_LLIST_NEXT (*mover);
+
+      /* Find `mover's predecessor.  */
+      for (before_mover = unmoved; STR_LLIST_NEXT (*before_mover) != mover;
+           before_mover = STR_LLIST_NEXT (*before_mover))
+        ;
+
+      /* `before_mover' now links to `after_mover'.  */
+      STR_LLIST_NEXT (*before_mover) = after_mover;
+
+      /* Insert `mover' before `unmoved' and after `last_moved' (or at
+         the head of the list).  */
+      STR_LLIST_NEXT (*mover) = unmoved;
+      if (! last_moved)
+        *l = mover;
+      else
+        STR_LLIST_NEXT (*last_moved) = mover;
+    }
+
+  /* We've moved it.  */
+  STR_LLIST_MOVED (*mover) = 1;
+}
+
+/* Variable expansion.  */
+
+/* We have to keep track of variables being expanded, otherwise
+   constructs like TEXINPUTS = $TEXINPUTS result in an infinite loop.
+   (Or indirectly recursive variables, etc.)  Our simple solution is to
+   add to a list each time an expansion is started, and check the list
+   before expanding.  */
+
+static std::map <std::string, bool> expansions;
+
+static void
+expanding (const std::string& var, bool xp)
+{
+  expansions[var] = xp;
+}
+
+/* Return whether VAR is currently being expanding.  */
+
+static bool
+expanding_p (const std::string& var)
+{
+  return (expansions.find (var) != expansions.end ())
+    ? expansions[var] : false;
+}
+
+/* Append the result of value of `var' to EXPANSION, where `var' begins
+   at START and ends at END.  If `var' is not set, do not complain.
+   This is a subroutine for the more complicated expansion function.  */
+
+static void
+expand (std::string &expansion, const std::string& var)
+{
+  if (expanding_p (var))
+    {
+      (*current_liboctave_warning_handler)
+	("kpathsea: variable `%s' references itself (eventually)",
+	 var.c_str ());
+    }
+  else
+    {
+      /* Check for an environment variable.  */
+      std::string value = octave_env::getenv (var);
+
+      if (! value.empty ())
+	{
+	  expanding (var, true);
+	  std::string tmp = kpse_var_expand (value);
+	  expanding (var, false);
+	  expansion += tmp;
+	}
+    }
+}
+
+/* Can't think of when it would be useful to change these (and the
+   diagnostic messages assume them), but ... */
+#ifndef IS_VAR_START /* starts all variable references */
+#define IS_VAR_START(c) ((c) == '$')
+#endif
+#ifndef IS_VAR_CHAR  /* variable name constituent */
+#define IS_VAR_CHAR(c) (isalnum (c) || (c) == '_')
+#endif
+#ifndef IS_VAR_BEGIN_DELIMITER /* start delimited variable name (after $) */
+#define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{')
+#endif
+#ifndef IS_VAR_END_DELIMITER
+#define IS_VAR_END_DELIMITER(c) ((c) == '}')
+#endif
+
+/* Maybe we should support some or all of the various shell ${...}
+   constructs, especially ${var-value}.  */
+
+static std::string
+kpse_var_expand (const std::string& src)
+{
+  std::string expansion;
+
+  size_t src_len = src.length ();
+
+  /* Copy everything but variable constructs.  */
+  for (size_t i = 0; i < src_len; i++)
+    {
+      if (IS_VAR_START (src[i]))
+	{
+	  i++;
+
+	  /* Three cases: `$VAR', `${VAR}', `$<anything-else>'.  */
+	  if (IS_VAR_CHAR (src[i]))
+	    {
+	      /* $V: collect name constituents, then expand.  */
+	      size_t var_end = i;
+
+	      do
+		{
+		  var_end++;
+		}
+	      while (IS_VAR_CHAR (src[var_end]));
+
+	      var_end--; /* had to go one past */
+	      expand (expansion, src.substr (i, var_end - i + 1));
+	      i = var_end;
+
+	    }
+	  else if (IS_VAR_BEGIN_DELIMITER (src[i]))
+	    {
+	      /* ${: scan ahead for matching delimiter, then expand.  */
+	      size_t var_end = ++i;
+
+	      while (var_end < src_len && !IS_VAR_END_DELIMITER (src[var_end]))
+		var_end++;
+
+	      if (var_end == src_len)
+		{
+		  (*current_liboctave_warning_handler)
+		    ("%s: No matching } for ${", src.c_str ());
+		  i = var_end - 1; /* will incr to eos at top of loop */
+		}
+	      else
+		{
+		  expand (expansion, src.substr (i, var_end - i));
+		  i = var_end; /* will incr past } at top of loop*/
+		}
+	    }
+	  else
+	    {
+	      /* $<something-else>: error.  */
+	      (*current_liboctave_warning_handler)
+		("%s: Unrecognized variable construct `$%c'",
+		 src.c_str (), src[i]);
+
+	      /* Just ignore those chars and keep going.  */
+	    }
+	}
+      else
+	expansion += src[i];
+    }
+
+  return expansion;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-cieee.c b/liboctave/lo-cieee.c
new file mode 100644
index 0000000..bf76cea
--- /dev/null
+++ b/liboctave/lo-cieee.c
@@ -0,0 +1,328 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <float.h>
+
+#if defined (HAVE_FLOATINGPOINT_H)
+#include <floatingpoint.h>
+#endif
+
+#if defined (HAVE_IEEEFP_H)
+#include <ieeefp.h>
+#endif
+
+#if defined (HAVE_NAN_H)
+#if defined (SCO)
+#define _IEEE 1
+#endif
+#include <nan.h>
+#if defined (SCO)
+#undef _IEEE
+#endif
+#endif
+
+#include "lo-ieee.h"
+#include "lo-math.h"
+
+#if ! defined (HAVE_ISNAN) && defined (HAVE__ISNAN)
+#define isnan _isnan
+#define HAVE_ISNAN 1
+#endif
+
+#if ! defined (HAVE_FINITE) && defined (HAVE__FINITE)
+#define finite _finite
+#define HAVE_FINITE 1
+#endif
+
+#if ! defined (HAVE_COPYSIGN) && defined (HAVE__COPYSIGN)
+#define copysign _copysign
+#define HAVE_COPYSIGN 1
+#endif
+
+#if defined (_AIX) && defined (__GNUG__)
+#undef finite
+#define finite(x) ((x) < DBL_MAX && (x) > -DBL_MAX)
+#endif
+
+/* Octave's idea of infinity.  */
+double octave_Inf;
+float octave_Float_Inf;
+
+/* Octave's idea of a missing value.  */
+double octave_NA;
+float octave_Float_NA;
+
+/* Octave's idea of not a number.  */
+double octave_NaN;
+float octave_Float_NaN;
+
+int lo_ieee_hw;
+int lo_ieee_lw;
+
+#if defined (SCO)
+
+int
+__isnan (double x)
+{
+  return (IsNANorINF (x) && NaN (x) && ! IsINF (x)) ? 1 : 0;
+}
+
+int
+__isinf (double x)
+{
+  return (IsNANorINF (x) && IsINF (x)) ? 1 : 0;
+}
+
+int
+__isnanf (float x)
+{
+  return (IsNANorINF (x) && NaN (x) && ! IsINF (x)) ? 1 : 0;
+}
+
+int
+__isinff (float x)
+{
+  return (IsNANorINF (x) && IsINF (x)) ? 1 : 0;
+}
+
+#endif
+
+int
+__lo_ieee_isnan (double x)
+{
+#if defined (HAVE_ISNAN)
+  return isnan (x);
+#else
+  return 0;
+#endif
+}
+
+int
+__lo_ieee_finite (double x)
+{
+#if defined (HAVE_FINITE)
+  return finite (x) != 0 && ! __lo_ieee_isnan (x);
+#elif defined (HAVE_ISINF)
+  return (! isinf (x) && ! __lo_ieee_isnan (x));
+#else
+  return ! __lo_ieee_isnan (x);
+#endif
+}
+
+int
+__lo_ieee_isinf (double x)
+{
+#if defined (HAVE_ISINF)
+  return isinf (x);
+#elif defined (HAVE_FINITE)
+  return (! (finite (x) || __lo_ieee_isnan (x)));
+#else
+  return 0;
+#endif
+}
+
+int
+__lo_ieee_is_NA (double x)
+{
+#if defined (HAVE_ISNAN)
+  lo_ieee_double t;
+  t.value = x;
+  return (isnan (x) && t.word[lo_ieee_hw] == LO_IEEE_NA_HW 
+	  && t.word[lo_ieee_lw] == LO_IEEE_NA_LW) ? 1 : 0;
+#else
+  return 0;
+#endif
+}
+
+int
+__lo_ieee_is_old_NA (double x)
+{
+#if defined (HAVE_ISNAN)
+  lo_ieee_double t;
+  t.value = x;
+  return (isnan (x) && t.word[lo_ieee_lw] == LO_IEEE_NA_LW_OLD 
+	  && t.word[lo_ieee_hw] == LO_IEEE_NA_HW_OLD) ? 1 : 0;
+#else
+  return 0;
+#endif
+}
+
+double
+__lo_ieee_replace_old_NA (double x)
+{
+  if (__lo_ieee_is_old_NA (x))
+    return lo_ieee_na_value ();
+  else
+    return x;
+}
+
+int
+__lo_ieee_is_NaN_or_NA (double x)
+{
+  return __lo_ieee_isnan (x);
+}
+
+double
+lo_ieee_inf_value (void)
+{
+  return octave_Inf;
+}
+
+double
+lo_ieee_na_value (void)
+{
+  return octave_NA;
+}
+
+double
+lo_ieee_nan_value (void)
+{
+  return octave_NaN;
+}
+
+#if ! (defined (signbit) || defined (HAVE_DECL_SIGNBIT)) && defined (HAVE_SIGNBIT)
+extern int signbit (double);
+#endif
+
+int
+__lo_ieee_signbit (double x)
+{
+/* In the following definitions, only check x < 0 explicitly to avoid
+   a function call when it looks like signbit or copysign are actually
+   functions.  */
+
+#if defined (signbit)
+  return signbit (x);
+#elif defined (HAVE_SIGNBIT)
+  return (x < 0 || signbit (x));
+#elif defined (copysign)
+  return (copysign (1.0, x) < 0);
+#elif defined (HAVE_COPYSIGN)
+  return (x < 0 || copysign (1.0, x) < 0);
+#else
+  return x < 0;
+#endif
+}
+
+int
+__lo_ieee_float_isnan (float x)
+{
+#if defined (HAVE_ISNAN)
+  return isnan (x);
+#else
+  return 0;
+#endif
+}
+
+int
+__lo_ieee_float_finite (float x)
+{
+#if defined (HAVE_FINITE)
+  return finite (x) != 0 && ! __lo_ieee_float_isnan (x);
+#elif defined (HAVE_ISINF)
+  return (! isinf (x) && ! __lo_ieee_float_isnan (x));
+#else
+  return ! __lo_ieee_float_isnan (x);
+#endif
+}
+
+int
+__lo_ieee_float_isinf (float x)
+{
+#if defined (HAVE_ISINF)
+  return isinf (x);
+#elif defined (HAVE_FINITE)
+  return (! (finite (x) || __lo_ieee_float_isnan (x)));
+#else
+  return 0;
+#endif
+}
+
+int
+__lo_ieee_float_is_NA (float x)
+{
+#if defined (HAVE_ISNAN)
+  lo_ieee_float t;
+  t.value = x;
+  return (isnan (x) && (t.word == LO_IEEE_NA_FLOAT)) ? 1 : 0;
+#else
+  return 0;
+#endif
+}
+
+int
+__lo_ieee_float_is_NaN_or_NA (float x)
+{
+  return __lo_ieee_float_isnan (x);
+}
+
+float
+lo_ieee_float_inf_value (void)
+{
+  return octave_Float_Inf;
+}
+
+float
+lo_ieee_float_na_value (void)
+{
+  return octave_Float_NA;
+}
+
+float
+lo_ieee_float_nan_value (void)
+{
+  return octave_Float_NaN;
+}
+
+#if ! (defined (signbit) || defined (HAVE_DECL_SIGNBIT)) && defined (HAVE_SIGNBIT)
+extern int signbit (float);
+#endif
+
+int
+__lo_ieee_float_signbit (float x)
+{
+/* In the following definitions, only check x < 0 explicitly to avoid
+   a function call when it looks like signbit or copysign are actually
+   functions.  */
+
+#if defined (signbit)
+  return signbit (x);
+#elif defined (HAVE_SIGNBIT)
+  return (x < 0 || signbit (x));
+#elif defined (copysign)
+  return (copysign (1.0, x) < 0);
+#elif defined (HAVE_COPYSIGN)
+  return (x < 0 || copysign (1.0, x) < 0);
+#else
+  return x < 0;
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-cutils.c b/liboctave/lo-cutils.c
new file mode 100644
index 0000000..5d51239
--- /dev/null
+++ b/liboctave/lo-cutils.c
@@ -0,0 +1,133 @@
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+The function gethostname was adapted from a similar function from GNU
+Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free
+Software Foundation, Inc.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* This gives us a better chance of finding a prototype for strptime
+   on some systems.  */
+
+#if ! defined (_XOPEN_SOURCE)
+#define _XOPEN_SOURCE
+#endif
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "syswait.h"
+
+OCTAVE_API void
+octave_qsort (void *base, size_t n, size_t size,
+	      int (*cmp) (const void *, const void *))
+{
+  qsort (base, n, size, cmp);
+}
+
+OCTAVE_API char *
+oct_strptime (const char *buf, const char *format, struct tm *tm)
+{
+  return (char *) strptime (buf, format, tm);
+}
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+
+#include <winsock.h>
+
+#elif ! defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
+
+#include <sys/utsname.h>
+
+int
+gethostname (char *name, int namelen)
+{
+  int i;
+  struct utsname ut;
+
+  --namelen;
+
+  uname (&ut);
+  i = strlen (ut.nodename) + 1;
+  strncpy (name, ut.nodename, i < namelen ? i : namelen);
+  name[namelen] = '\0';
+
+  return 0;
+}
+
+#endif
+
+OCTAVE_API int
+octave_strcasecmp (const char *s1, const char *s2)
+{
+  return strcasecmp (s1, s2);
+}
+
+OCTAVE_API int
+octave_strncasecmp (const char *s1, const char *s2, size_t n)
+{
+  return strncasecmp (s1, s2, n);
+}
+
+OCTAVE_API int
+octave_gethostname (char *name, int namelen)
+{
+  return gethostname (name, namelen);
+}
+
+#ifdef HAVE_LOADLIBRARY_API
+#include <windows.h>
+
+/* Need this since in C++ can't cast from int(*)() to void* */
+OCTAVE_API void *
+octave_w32_library_search (HINSTANCE handle, const char * name)
+{
+  return (GetProcAddress (handle, name));
+}
+#endif
+
+OCTAVE_API pid_t
+octave_waitpid (pid_t pid, int *status, int options)
+{
+  return WAITPID (pid, status, options);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-ieee.cc b/liboctave/lo-ieee.cc
new file mode 100644
index 0000000..8e38533
--- /dev/null
+++ b/liboctave/lo-ieee.cc
@@ -0,0 +1,174 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstdlib>
+
+#if defined (HAVE_FLOATINGPOINT_H)
+#include <floatingpoint.h>
+#endif
+
+#if defined (HAVE_IEEEFP_H)
+#include <ieeefp.h>
+#endif
+
+#if defined (HAVE_NAN_H)
+#if defined (SCO)
+#define _IEEE 1
+#endif
+#include <nan.h>
+#if defined (SCO)
+#undef _IEEE
+#endif
+#endif
+
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-math.h"
+#include "mach-info.h"
+
+void
+octave_ieee_init (void)
+{
+  // Default values.  DBL_MAX is not right for NaN and NA, but do you
+  // have a better suggestion?  If you don't have IEEE floating point
+  // values, there are many parts of Octave that will not work
+  // correctly.
+
+  octave_Inf = octave_NaN = octave_NA = DBL_MAX;
+  octave_Float_Inf = octave_Float_NaN = octave_Float_NA = FLT_MAX;
+
+  oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
+
+  switch (ff)
+    {
+    case oct_mach_info::flt_fmt_ieee_big_endian:
+    case oct_mach_info::flt_fmt_ieee_little_endian:
+      {
+	// Don't optimize away tmp_inf / tmp_inf to generate octave_NaN.
+
+	volatile double tmp_inf;
+
+#if defined (SCO)
+	volatile double tmp = 1.0;
+	tmp_inf = 1.0 / (tmp - tmp);
+#elif defined (__alpha__) && defined (__osf__)
+	extern unsigned int DINFINITY[2];
+	tmp_inf =  (*(X_CAST(double *, DINFINITY)));
+#else
+	double tmp = 1e+10;
+	tmp_inf = tmp;
+	for (;;)
+	  {
+	    tmp_inf *= 1e+10;
+	    if (tmp_inf == tmp)
+	      break;
+	    tmp = tmp_inf;
+	  }
+#endif
+
+#if defined (__alpha__) && defined (__osf__)
+	extern unsigned int DQNAN[2];
+	octave_NaN = (*(X_CAST(double *, DQNAN)));
+#elif defined (__NetBSD__)
+	octave_NaN = nan ("");
+#else
+	octave_NaN = tmp_inf / tmp_inf;
+        // try to ensure that lo_ieee_sign gives false for a NaN.
+        if (lo_ieee_signbit (octave_NaN))
+          octave_NaN = -octave_NaN;
+
+#endif
+
+	octave_Inf = tmp_inf;
+
+	// This is patterned after code in R.
+
+	if (ff == oct_mach_info::flt_fmt_ieee_big_endian)
+	  {
+	    lo_ieee_hw = 0;
+	    lo_ieee_lw = 1;
+	  }
+	else
+	  {
+	    lo_ieee_hw = 1;
+	    lo_ieee_lw = 0;
+	  }
+
+	lo_ieee_double t;
+	t.word[lo_ieee_hw] = LO_IEEE_NA_HW;
+	t.word[lo_ieee_lw] = LO_IEEE_NA_LW;
+
+	octave_NA = t.value;
+
+	volatile float float_tmp_inf;
+
+#if defined (SCO)
+	volatile float float_tmp = 1.0;
+	float_tmp_inf = 1.0 / (float_tmp - float_tmp);
+#else
+	float float_tmp = 1e+10;
+	float_tmp_inf = float_tmp;
+	for (;;)
+	  {
+	    float_tmp_inf *= 1e+10;
+	    if (float_tmp_inf == float_tmp)
+	      break;
+	    float_tmp = float_tmp_inf;
+	  }
+#endif
+
+#if defined (__NetBSD__)
+	octave_Float_NaN = nanf ("");
+#else
+	octave_Float_NaN = float_tmp_inf / float_tmp_inf;
+#endif
+	octave_Float_Inf = float_tmp_inf;
+
+	lo_ieee_float tf;
+	tf.word = LO_IEEE_NA_FLOAT;
+	octave_Float_NA = tf.value;
+      }
+      break;
+
+    case oct_mach_info::flt_fmt_cray:
+    case oct_mach_info::flt_fmt_vax_d:
+    case oct_mach_info::flt_fmt_vax_g:
+    default:
+      // If the format is unknown, then you will probably not have a
+      // useful system, but we will just issue a warning and go on...
+      (*current_liboctave_error_handler)
+	("lo_ieee_init: floating point format is not IEEE!  Maybe DLAMCH is miscompiled, or you are using some strange system without IEEE floating point math?");
+      abort ();
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-ieee.h b/liboctave/lo-ieee.h
new file mode 100644
index 0000000..d7439be
--- /dev/null
+++ b/liboctave/lo-ieee.h
@@ -0,0 +1,139 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_ieee_h)
+#define octave_liboctave_ieee_h 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*  Octave's idea of infinity.  */
+extern OCTAVE_API double octave_Inf;
+
+/* Octave's idea of a missing value.  */
+extern OCTAVE_API double octave_NA;
+
+/* Octave's idea of not a number.  */
+extern OCTAVE_API double octave_NaN;
+
+/*  Octave's idea of infinity.  */
+extern OCTAVE_API float octave_Float_Inf;
+
+/* Octave's idea of a missing value.  */
+extern OCTAVE_API float octave_Float_NA;
+
+/* Octave's idea of not a number.  */
+extern OCTAVE_API float octave_Float_NaN;
+
+/* FIXME -- this code assumes that a double has twice the
+   number of bits as an int */
+
+extern OCTAVE_API int lo_ieee_hw;
+extern OCTAVE_API int lo_ieee_lw;
+
+typedef union
+{
+  double value;
+  unsigned int word[2];
+} lo_ieee_double;
+
+typedef union
+{
+  float value;
+  unsigned int word;
+} lo_ieee_float;
+
+#define LO_IEEE_NA_HW_OLD 0x7ff00000
+#define LO_IEEE_NA_LW_OLD 1954
+#define LO_IEEE_NA_HW 0x7FF840F4
+#define LO_IEEE_NA_LW 0x40000000
+#define LO_IEEE_NA_FLOAT   0x7FC207A2
+ 
+
+extern OCTAVE_API void octave_ieee_init (void);
+
+#if defined (SCO)
+extern int __isnan (double);
+extern int __isinf (double);
+extern int __isnanf (float);
+extern int __isinff (float);
+
+#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x))
+#define isinf(x) (sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x))
+#endif
+
+extern OCTAVE_API int __lo_ieee_isnan (double x);
+extern OCTAVE_API int __lo_ieee_finite (double x);
+extern OCTAVE_API int __lo_ieee_isinf (double x);
+
+extern OCTAVE_API int __lo_ieee_is_NA (double);
+extern OCTAVE_API int __lo_ieee_is_old_NA (double);
+extern OCTAVE_API int __lo_ieee_is_NaN_or_NA (double) GCC_ATTR_DEPRECATED;
+extern OCTAVE_API double __lo_ieee_replace_old_NA (double);
+
+extern OCTAVE_API double lo_ieee_inf_value (void);
+extern OCTAVE_API double lo_ieee_na_value (void);
+extern OCTAVE_API double lo_ieee_nan_value (void);
+
+extern OCTAVE_API int __lo_ieee_signbit (double);
+
+extern OCTAVE_API int __lo_ieee_float_isnan (float x);
+extern OCTAVE_API int __lo_ieee_float_finite (float x);
+extern OCTAVE_API int __lo_ieee_float_isinf (float x);
+
+extern OCTAVE_API int __lo_ieee_float_is_NA (float);
+extern OCTAVE_API int __lo_ieee_float_is_NaN_or_NA (float) GCC_ATTR_DEPRECATED;
+
+extern OCTAVE_API float lo_ieee_float_inf_value (void);
+extern OCTAVE_API float lo_ieee_float_na_value (void);
+extern OCTAVE_API float lo_ieee_float_nan_value (void);
+
+extern OCTAVE_API int __lo_ieee_float_signbit (float);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#define lo_ieee_isnan(x) (sizeof (x) == sizeof (float) ? \
+			 __lo_ieee_float_isnan (x) : __lo_ieee_isnan (x))
+#define lo_ieee_finite(x) (sizeof (x) == sizeof (float) ? \
+			   __lo_ieee_float_finite (x) : __lo_ieee_finite (x))
+#define lo_ieee_isinf(x) (sizeof (x) == sizeof (float) ? \
+			  __lo_ieee_float_isinf (x) : __lo_ieee_isinf (x))
+
+
+#define lo_ieee_is_NA(x) (sizeof (x) == sizeof (float) ? \
+			  __lo_ieee_float_is_NA (x) : __lo_ieee_is_NA (x))
+#define lo_ieee_is_NaN_or_NA(x) (sizeof (x) == sizeof (float) ? \
+			  __lo_ieee_float_is_NaN_or_NA (x) : __lo_ieee_is_NaN_or_NA (x))
+#define lo_ieee_signbit(x) (sizeof (x) == sizeof (float) ? \
+			  __lo_ieee_float_signbit (x) : __lo_ieee_signbit (x))
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-mappers.cc b/liboctave/lo-mappers.cc
new file mode 100644
index 0000000..4836de1
--- /dev/null
+++ b/liboctave/lo-mappers.cc
@@ -0,0 +1,679 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-math.h"
+#include "lo-specfun.h"
+#include "lo-utils.h"
+#include "oct-cmplx.h"
+
+#include "f77-fcn.h"
+
+// double -> double mappers.
+
+double
+arg (double x)
+{
+  return atan2 (0.0, x);
+}
+
+double
+conj (double x)
+{
+  return x;
+}
+
+double
+fix (double x)
+{
+  return x > 0 ? floor (x) : ceil (x);
+}
+
+double
+imag (double)
+{
+  return 0.0;
+}
+
+double
+real (double x)
+{
+  return x;
+}
+
+double
+xround (double x)
+{
+#if defined (HAVE_ROUND)
+  return round (x);
+#else
+  if (x >= 0)
+    {
+      double y = floor (x);
+
+      if ((x - y) >= 0.5)
+	y += 1.0;
+
+      return y;
+    }
+  else
+    {
+      double y = ceil (x);
+
+      if ((y - x) >= 0.5)
+	y -= 1.0;
+
+      return y;
+    }
+#endif
+}
+
+double
+xtrunc (double x)
+{
+#if defined (HAVE_TRUNC)
+  return trunc (x);
+#else
+  return x > 0 ? floor (x) : ceil (x);
+#endif
+}
+
+double 
+xroundb (double x)
+{
+  double t = xround (x);
+
+  if (fabs (x - t) == 0.5)
+    t = 2 * xtrunc (0.5 * t);
+
+  return t;
+}
+
+double
+signum (double x)
+{
+  double tmp = 0.0;
+
+  if (x < 0.0)
+    tmp = -1.0;
+  else if (x > 0.0)
+    tmp = 1.0;
+
+  return xisnan (x) ? octave_NaN : tmp;
+}
+
+double
+xlog2 (double x)
+{
+#if defined (HAVE_LOG2)
+  return log2 (x);
+#else
+#if defined (M_LN2)
+  static double ln2 = M_LN2;
+#else
+  static double ln2 = log (2);
+#endif
+
+  return log (x) / ln2;
+#endif
+}
+
+Complex
+xlog2 (const Complex& x)
+{
+#if defined (M_LN2)
+  static double ln2 = M_LN2;
+#else
+  static double ln2 = log (2);
+#endif
+
+  return std::log (x) / ln2;
+}
+
+double
+xexp2 (double x)
+{
+#if defined (HAVE_EXP2)
+  return exp2 (x);
+#else
+#if defined (M_LN2)
+  static double ln2 = M_LN2;
+#else
+  static double ln2 = log (2);
+#endif
+
+  return exp (x * ln2);
+#endif
+}
+
+double
+xlog2 (double x, int& exp)
+{
+  return frexp (x, &exp);
+}
+
+Complex
+xlog2 (const Complex& x, int& exp)
+{
+  double ax = std::abs (x);
+  double lax = xlog2 (ax, exp);
+  return (ax != lax) ? (x / ax) * lax : x;
+}
+
+// double -> bool mappers.
+
+#if ! defined(HAVE_CMATH_ISNAN)
+bool
+xisnan (double x)
+{
+  return lo_ieee_isnan (x);
+}
+#endif
+
+#if ! defined(HAVE_CMATH_ISFINITE)
+bool
+xfinite (double x)
+{
+  return lo_ieee_finite (x);
+}
+#endif
+
+#if ! defined(HAVE_CMATH_ISINF)
+bool
+xisinf (double x)
+{
+  return lo_ieee_isinf (x);
+}
+#endif
+
+bool
+octave_is_NA (double x)
+{
+  return lo_ieee_is_NA (x);
+}
+
+bool
+octave_is_NaN_or_NA (double x)
+{
+  return lo_ieee_isnan (x);
+}
+
+// (double, double) -> double mappers.
+
+// According to Matlab, is both args are NaN, the first one is returned.
+
+double
+xmin (double x, double y)
+{
+  return  xisnan (y) ? x : (x <= y ? x : y);
+}
+
+double
+xmax (double x, double y)
+{
+  return  xisnan (y) ? x : (x >= y ? x : y);
+}
+
+// complex -> complex mappers.
+
+Complex
+acos (const Complex& x)
+{
+  static Complex i (0, 1);
+
+  return -i * (log (x + i * (sqrt (1.0 - x*x))));
+}
+
+Complex
+acosh (const Complex& x)
+{
+  return log (x + sqrt (x*x - 1.0));
+}
+
+Complex
+asin (const Complex& x)
+{
+  static Complex i (0, 1);
+
+  return -i * log (i*x + sqrt (1.0 - x*x));
+}
+
+Complex
+asinh (const Complex& x)
+{
+  return log (x + sqrt (x*x + 1.0));
+}
+
+Complex
+atan (const Complex& x)
+{
+  static Complex i (0, 1);
+
+  return i * log ((i + x) / (i - x)) / 2.0;
+}
+
+Complex
+atanh (const Complex& x)
+{
+  return log ((1.0 + x) / (1.0 - x)) / 2.0;
+}
+
+Complex
+ceil (const Complex& x)
+{
+  return Complex (ceil (real (x)), ceil (imag (x)));
+}
+
+Complex
+fix (const Complex& x)
+{
+  return Complex (fix (real (x)), fix (imag (x)));
+}
+
+Complex
+floor (const Complex& x)
+{
+  return Complex (floor (real (x)), floor (imag (x)));
+}
+
+Complex
+xround (const Complex& x)
+{
+  return Complex (xround (real (x)), xround (imag (x)));
+}
+
+Complex
+xroundb (const Complex& x)
+{
+  return Complex (xroundb (real (x)), xroundb (imag (x)));
+}
+
+Complex
+signum (const Complex& x)
+{
+  double tmp = abs (x);
+
+  return tmp == 0 ? 0.0 : x / tmp;
+}
+
+// complex -> bool mappers.
+
+bool
+octave_is_NA (const Complex& x)
+{
+  return (octave_is_NA (real (x)) || octave_is_NA (imag (x)));
+}
+
+bool
+octave_is_NaN_or_NA (const Complex& x)
+{
+  return (xisnan (real (x)) || xisnan (imag (x)));
+}
+
+// (complex, complex) -> complex mappers.
+
+// FIXME -- need to handle NA too?
+
+Complex
+xmin (const Complex& x, const Complex& y)
+{
+  return abs (x) <= abs (y) ? x : (xisnan (x) ? x : y);
+}
+
+Complex
+xmax (const Complex& x, const Complex& y)
+{
+  return abs (x) >= abs (y) ? x : (xisnan (x) ? x : y);
+}
+
+
+// float -> float mappers.
+
+float
+arg (float x)
+{
+  return atan2 (0.0f, x);
+}
+
+float
+conj (float x)
+{
+  return x;
+}
+
+float
+fix (float x)
+{
+  return x > 0 ? floor (x) : ceil (x);
+}
+
+float
+imag (float)
+{
+  return 0.0;
+}
+
+float
+real (float x)
+{
+  return x;
+}
+
+float
+xround (float x)
+{
+#if defined (HAVE_ROUND)
+  return round (x);
+#else
+  if (x >= 0)
+    {
+      float y = floor (x);
+
+      if ((x - y) >= 0.5)
+	y += 1.0;
+
+      return y;
+    }
+  else
+    {
+      float y = ceil (x);
+
+      if ((y - x) >= 0.5)
+	y -= 1.0;
+
+      return y;
+    }
+#endif
+}
+
+float
+xtrunc (float x)
+{
+#if defined (HAVE_TRUNC)
+  return trunc (x);
+#else
+  return x > 0 ? floor (x) : ceil (x);
+#endif
+}
+
+float 
+xroundb (float x)
+{
+  float t = xround (x);
+
+  if (fabs (x - t) == 0.5)
+    t = 2 * xtrunc (0.5 * t);
+
+  return t;
+}
+
+float
+signum (float x)
+{
+  float tmp = 0.0;
+
+  if (x < 0.0)
+    tmp = -1.0;
+  else if (x > 0.0)
+    tmp = 1.0;
+
+  return xisnan (x) ? octave_Float_NaN : tmp;
+}
+
+float
+xlog2 (float x)
+{
+#if defined (HAVE_LOG2)
+  return log2 (x);
+#else
+#if defined (M_LN2)
+  static float ln2 = M_LN2;
+#else
+  static float ln2 = log2 (2);
+#endif
+
+  return log (x) / ln2;
+#endif
+}
+
+FloatComplex
+xlog2 (const FloatComplex& x)
+{
+#if defined (M_LN2)
+  static float ln2 = M_LN2;
+#else
+  static float ln2 = log (2);
+#endif
+
+  return std::log (x) / ln2;
+}
+
+float
+xexp2 (float x)
+{
+#if defined (HAVE_EXP2)
+  return exp2 (x);
+#else
+#if defined (M_LN2)
+  static float ln2 = M_LN2;
+#else
+  static float ln2 = log2 (2);
+#endif
+
+  return exp (x * ln2);
+#endif
+}
+
+float
+xlog2 (float x, int& exp)
+{
+  return frexpf (x, &exp);
+}
+
+FloatComplex
+xlog2 (const FloatComplex& x, int& exp)
+{
+  float ax = std::abs (x);
+  float lax = xlog2 (ax, exp);
+  return (ax != lax) ? (x / ax) * lax : x;
+}
+
+// float -> bool mappers.
+
+#if ! defined(HAVE_CMATH_ISNANF)
+bool
+xisnan (float x)
+{
+  return lo_ieee_isnan (x);
+}
+#endif
+
+#if ! defined(HAVE_CMATH_ISFINITEF)
+bool
+xfinite (float x)
+{
+  return lo_ieee_finite (x);
+}
+#endif
+
+#if ! defined(HAVE_CMATH_ISINFF)
+bool
+xisinf (float x)
+{
+  return lo_ieee_isinf (x);
+}
+#endif
+
+bool
+octave_is_NA (float x)
+{
+  return lo_ieee_is_NA (x);
+}
+
+bool
+octave_is_NaN_or_NA (float x)
+{
+  return lo_ieee_isnan (x);
+}
+
+// (float, float) -> float mappers.
+
+// FIXME -- need to handle NA too?
+
+float
+xmin (float x, float y)
+{
+  return  xisnan (y) ? x : (x <= y ? x : y);
+}
+
+float
+xmax (float x, float y)
+{
+  return  xisnan (y) ? x : (x >= y ? x : y);
+}
+
+// complex -> complex mappers.
+
+FloatComplex
+acos (const FloatComplex& x)
+{
+  static FloatComplex i (0, 1);
+
+  return -i * (log (x + i * (sqrt (static_cast<float>(1.0) - x*x))));
+}
+
+FloatComplex
+acosh (const FloatComplex& x)
+{
+  return log (x + sqrt (x*x - static_cast<float>(1.0)));
+}
+
+FloatComplex
+asin (const FloatComplex& x)
+{
+  static FloatComplex i (0, 1);
+
+  return -i * log (i*x + sqrt (static_cast<float>(1.0) - x*x));
+}
+
+FloatComplex
+asinh (const FloatComplex& x)
+{
+  return log (x + sqrt (x*x + static_cast<float>(1.0)));
+}
+
+FloatComplex
+atan (const FloatComplex& x)
+{
+  static FloatComplex i (0, 1);
+
+  return i * log ((i + x) / (i - x)) / static_cast<float>(2.0);
+}
+
+FloatComplex
+atanh (const FloatComplex& x)
+{
+  return log ((static_cast<float>(1.0) + x) / (static_cast<float>(1.0) - x)) / static_cast<float>(2.0);
+}
+
+FloatComplex
+ceil (const FloatComplex& x)
+{
+  return FloatComplex (ceil (real (x)), ceil (imag (x)));
+}
+
+FloatComplex
+fix (const FloatComplex& x)
+{
+  return FloatComplex (fix (real (x)), fix (imag (x)));
+}
+
+FloatComplex
+floor (const FloatComplex& x)
+{
+  return FloatComplex (floor (real (x)), floor (imag (x)));
+}
+
+FloatComplex
+xround (const FloatComplex& x)
+{
+  return FloatComplex (xround (real (x)), xround (imag (x)));
+}
+
+FloatComplex
+xroundb (const FloatComplex& x)
+{
+  return FloatComplex (xroundb (real (x)), xroundb (imag (x)));
+}
+
+FloatComplex
+signum (const FloatComplex& x)
+{
+  float tmp = abs (x);
+
+  return tmp == 0 ? 0.0 : x / tmp;
+}
+
+// complex -> bool mappers.
+
+bool
+octave_is_NA (const FloatComplex& x)
+{
+  return (octave_is_NA (real (x)) || octave_is_NA (imag (x)));
+}
+
+bool
+octave_is_NaN_or_NA (const FloatComplex& x)
+{
+  return (xisnan (real (x)) || xisnan (imag (x)));
+}
+
+// (complex, complex) -> complex mappers.
+
+// FIXME -- need to handle NA too?
+
+FloatComplex
+xmin (const FloatComplex& x, const FloatComplex& y)
+{
+  return abs (x) <= abs (y) ? x : (xisnan (x) ? x : y);
+}
+
+FloatComplex
+xmax (const FloatComplex& x, const FloatComplex& y)
+{
+  return abs (x) >= abs (y) ? x : (xisnan (x) ? x : y);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-mappers.h b/liboctave/lo-mappers.h
new file mode 100644
index 0000000..ddfb3ef
--- /dev/null
+++ b/liboctave/lo-mappers.h
@@ -0,0 +1,183 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_mappers_h)
+#define octave_liboctave_mappers_h 1
+
+#include "oct-cmplx.h"
+#include "lo-math.h"
+
+// Double Precision 
+extern OCTAVE_API double arg (double x);
+extern OCTAVE_API double conj (double x);
+extern OCTAVE_API double fix (double x);
+extern OCTAVE_API double imag (double x);
+extern OCTAVE_API double real (double x);
+extern OCTAVE_API double xround (double x);
+extern OCTAVE_API double xroundb (double x);
+extern OCTAVE_API double signum (double x);
+extern OCTAVE_API double xtrunc (double x);
+extern OCTAVE_API double xlog2 (double x); 
+extern OCTAVE_API Complex xlog2 (const Complex& x); 
+extern OCTAVE_API double xlog2 (double x, int& exp);
+extern OCTAVE_API Complex xlog2 (const Complex& x, int& exp);
+extern OCTAVE_API double xexp2 (double x);
+
+// These are used by the BOOL_OP macros in mx-op-defs.h.
+inline bool xisnan (bool) { return false; }
+inline bool xisnan (char) { return false; }
+
+#if defined (HAVE_CMATH_ISNAN)
+inline bool xisnan (double x)
+{ return std::isnan (x); }
+#else
+extern OCTAVE_API bool xisnan (double x);
+#endif
+#if defined (HAVE_CMATH_ISFINITE)
+inline bool xfinite (double x)
+{ return std::isfinite (x); }
+#else
+extern OCTAVE_API bool xfinite (double x);
+#endif
+#if defined (HAVE_CMATH_ISINF)
+inline bool xisinf (double x)
+{ return std::isinf (x); }
+#else
+extern OCTAVE_API bool xisinf (double x);
+#endif
+
+extern OCTAVE_API bool octave_is_NA (double x);
+extern OCTAVE_API bool octave_is_NaN_or_NA (double x) GCC_ATTR_DEPRECATED;
+
+extern OCTAVE_API double xmin (double x, double y);
+extern OCTAVE_API double xmax (double x, double y);
+
+extern OCTAVE_API Complex acos (const Complex& x);
+extern OCTAVE_API Complex acosh (const Complex& x);
+extern OCTAVE_API Complex asin (const Complex& x);
+extern OCTAVE_API Complex asinh (const Complex& x);
+extern OCTAVE_API Complex atan (const Complex& x);
+extern OCTAVE_API Complex atanh (const Complex& x);
+
+extern OCTAVE_API Complex ceil (const Complex& x);
+extern OCTAVE_API Complex fix (const Complex& x);
+extern OCTAVE_API Complex floor (const Complex& x);
+extern OCTAVE_API Complex xround (const Complex& x);
+extern OCTAVE_API Complex xroundb (const Complex& x);
+extern OCTAVE_API Complex signum (const Complex& x);
+
+inline bool
+xisnan (const Complex& x)
+{ return (xisnan (real (x)) || xisnan (imag (x))); }
+inline bool
+xfinite (const Complex& x)
+{ return (xfinite (real (x)) && xfinite (imag (x))); }
+inline bool
+xisinf (const Complex& x)
+{ return (xisinf (real (x)) || xisinf (imag (x))); }
+
+extern OCTAVE_API bool octave_is_NA (const Complex& x);
+extern OCTAVE_API bool octave_is_NaN_or_NA (const Complex& x);
+
+extern OCTAVE_API Complex xmin (const Complex& x, const Complex& y);
+extern OCTAVE_API Complex xmax (const Complex& x, const Complex& y);
+
+// Single Precision 
+extern OCTAVE_API float arg (float x);
+extern OCTAVE_API float conj (float x);
+extern OCTAVE_API float fix (float x);
+extern OCTAVE_API float imag (float x);
+extern OCTAVE_API float real (float x);
+extern OCTAVE_API float xround (float x);
+extern OCTAVE_API float xroundb (float x);
+extern OCTAVE_API float signum (float x);
+extern OCTAVE_API float xtrunc (float x);
+extern OCTAVE_API float xlog2 (float x); 
+extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x); 
+extern OCTAVE_API float xlog2 (float x, int& exp);
+extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x, int& exp);
+extern OCTAVE_API float xexp2 (float x);
+
+#if defined (HAVE_CMATH_ISNANF)
+inline bool xisnan (float x)
+{ return std::isnan (x); }
+#else
+extern OCTAVE_API bool xisnan (float x);
+#endif
+#if defined (HAVE_CMATH_ISFINITEF)
+inline bool xfinite (float x)
+{ return std::isfinite (x); }
+#else
+extern OCTAVE_API bool xfinite (float x);
+#endif
+#if defined (HAVE_CMATH_ISINFF)
+inline bool xisinf (float x)
+{ return std::isinf (x); }
+#else
+extern OCTAVE_API bool xisinf (float x);
+#endif
+
+
+extern OCTAVE_API bool octave_is_NA (float x);
+extern OCTAVE_API bool octave_is_NaN_or_NA (float x) GCC_ATTR_DEPRECATED;
+
+extern OCTAVE_API float xmin (float x, float y);
+extern OCTAVE_API float xmax (float x, float y);
+
+extern OCTAVE_API FloatComplex acos (const FloatComplex& x);
+extern OCTAVE_API FloatComplex acosh (const FloatComplex& x);
+extern OCTAVE_API FloatComplex asin (const FloatComplex& x);
+extern OCTAVE_API FloatComplex asinh (const FloatComplex& x);
+extern OCTAVE_API FloatComplex atan (const FloatComplex& x);
+extern OCTAVE_API FloatComplex atanh (const FloatComplex& x);
+
+extern OCTAVE_API FloatComplex ceil (const FloatComplex& x);
+extern OCTAVE_API FloatComplex fix (const FloatComplex& x);
+extern OCTAVE_API FloatComplex floor (const FloatComplex& x);
+extern OCTAVE_API FloatComplex xround (const FloatComplex& x);
+extern OCTAVE_API FloatComplex xroundb (const FloatComplex& x);
+extern OCTAVE_API FloatComplex signum (const FloatComplex& x);
+
+inline bool
+xisnan (const FloatComplex& x)
+{ return (xisnan (real (x)) || xisnan (imag (x))); }
+inline bool
+xfinite (const FloatComplex& x)
+{ return (xfinite (real (x)) && xfinite (imag (x))); }
+inline bool
+xisinf (const FloatComplex& x)
+{ return (xisinf (real (x)) || xisinf (imag (x))); }
+
+extern OCTAVE_API bool octave_is_NA (const FloatComplex& x);
+extern OCTAVE_API bool octave_is_NaN_or_NA (const FloatComplex& x);
+
+extern OCTAVE_API FloatComplex xmin (const FloatComplex& x, const FloatComplex& y);
+extern OCTAVE_API FloatComplex xmax (const FloatComplex& x, const FloatComplex& y);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-math.h b/liboctave/lo-math.h
new file mode 100644
index 0000000..15dafe8
--- /dev/null
+++ b/liboctave/lo-math.h
@@ -0,0 +1,46 @@
+/*
+
+Copyright (C) 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_math_h)
+#define octave_liboctave_math_h 1
+
+#if defined (__cplusplus)
+#include <cmath>
+// if #undef log2 is missing in cmath, undef it here
+#if defined (log2)
+#undef log2
+#endif
+#else
+#include <math.h>
+#endif
+
+#if defined (HAVE_SUNMATH_H)
+#include <sunmath.h>
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-specfun.cc b/liboctave/lo-specfun.cc
new file mode 100644
index 0000000..6f16d2b
--- /dev/null
+++ b/liboctave/lo-specfun.cc
@@ -0,0 +1,3099 @@
+/*
+
+Copyright (C) 1996, 1998, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Range.h"
+#include "CColVector.h"
+#include "CMatrix.h"
+#include "dRowVector.h"
+#include "dMatrix.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
+#include "fCColVector.h"
+#include "fCMatrix.h"
+#include "fRowVector.h"
+#include "fMatrix.h"
+#include "fNDArray.h"
+#include "fCNDArray.h"
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-specfun.h"
+#include "mx-inlines.cc"
+#include "lo-mappers.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (zbesj, ZBESJ) (const double&, const double&, const double&,
+			   const octave_idx_type&, const octave_idx_type&, double*, double*,
+			   octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zbesy, ZBESY) (const double&, const double&, const double&,
+			   const octave_idx_type&, const octave_idx_type&, double*, double*,
+			   octave_idx_type&, double*, double*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zbesi, ZBESI) (const double&, const double&, const double&,
+			   const octave_idx_type&, const octave_idx_type&, double*, double*,
+			   octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zbesk, ZBESK) (const double&, const double&, const double&,
+			   const octave_idx_type&, const octave_idx_type&, double*, double*,
+			   octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zbesh, ZBESH) (const double&, const double&, const double&,
+			   const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
+			   double*, octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cbesj, cBESJ) (const FloatComplex&, const float&,
+			   const octave_idx_type&, const octave_idx_type&,
+			   FloatComplex*, octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cbesy, CBESY) (const FloatComplex&, const float&,
+			   const octave_idx_type&, const octave_idx_type&,
+			   FloatComplex*, octave_idx_type&,
+			   FloatComplex*, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cbesi, CBESI) (const FloatComplex&, const float&,
+			   const octave_idx_type&, const octave_idx_type&,
+			   FloatComplex*, octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cbesk, CBESK) (const FloatComplex&, const float&,
+			   const octave_idx_type&, const octave_idx_type&,
+			   FloatComplex*, octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cbesh, CBESH) (const FloatComplex&, const float&,
+			   const octave_idx_type&, const octave_idx_type&,
+			   const octave_idx_type&, FloatComplex*,
+			   octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zairy, ZAIRY) (const double&, const double&, const octave_idx_type&,
+			   const octave_idx_type&, double&, double&, octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cairy, CAIRY) (const float&, const float&, const octave_idx_type&,
+			   const octave_idx_type&, float&, float&, octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (zbiry, ZBIRY) (const double&, const double&, const octave_idx_type&,
+			   const octave_idx_type&, double&, double&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (cbiry, CBIRY) (const float&, const float&, const octave_idx_type&,
+			   const octave_idx_type&, float&, float&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (xdacosh, XDACOSH) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xacosh, XACOSH) (const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xdasinh, XDASINH) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xasinh, XASINH) (const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xdatanh, XDATANH) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xatanh, XATANH) (const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xderf, XDERF) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xerf, XERF) (const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xderfc, XDERFC) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xerfc, XERFC) (const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xdbetai, XDBETAI) (const double&, const double&,
+			       const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xbetai, XBETAI) (const float&, const float&,
+			     const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xdgamma, XDGAMMA) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xgamma, XGAMMA) (const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (xgammainc, XGAMMAINC) (const double&, const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (xsgammainc, XSGAMMAINC) (const float&, const float&, float&);
+
+  F77_RET_T
+  F77_FUNC (dlgams, DLGAMS) (const double&, double&, double&);
+
+  F77_RET_T
+  F77_FUNC (algams, ALGAMS) (const float&, float&, float&);
+}
+
+#if !defined (HAVE_ACOSH)
+double
+acosh (double x)
+{
+  double retval;
+  F77_XFCN (xdacosh, XDACOSH, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ACOSHF)
+float
+acoshf (float x)
+{
+  float retval;
+  F77_XFCN (xacosh, XACOSH, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ASINH)
+double
+asinh (double x)
+{
+  double retval;
+  F77_XFCN (xdasinh, XDASINH, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ASINHF)
+float
+asinhf (float x)
+{
+  float retval;
+  F77_XFCN (xasinh, XASINH, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ATANH)
+double
+atanh (double x)
+{
+  double retval;
+  F77_XFCN (xdatanh, XDATANH, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ATANHF)
+float
+atanhf (float x)
+{
+  float retval;
+  F77_XFCN (xatanh, XATANH, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ERF)
+double
+erf (double x)
+{
+  double retval;
+  F77_XFCN (xderf, XDERF, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ERFF)
+float
+erff (float x)
+{
+  float retval;
+  F77_XFCN (xerf, XERF, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ERFC)
+double
+erfc (double x)
+{
+  double retval;
+  F77_XFCN (xderfc, XDERFC, (x, retval));
+  return retval;
+}
+#endif
+
+#if !defined (HAVE_ERFCF)
+float
+erfcf (float x)
+{
+  float retval;
+  F77_XFCN (xerfc, XERFC, (x, retval));
+  return retval;
+}
+#endif
+
+double
+xgamma (double x)
+{
+#if defined (HAVE_TGAMMA)
+  return tgamma (x);
+#else
+  double result;
+
+  if (xisnan (x))
+    result = x;
+  else if ((x <= 0 && D_NINT (x) == x) || xisinf (x))
+    result = octave_Inf;
+  else
+    F77_XFCN (xdgamma, XDGAMMA, (x, result));
+
+  return result;
+#endif
+}
+
+double
+xlgamma (double x)
+{
+#if defined (HAVE_LGAMMA)
+  return lgamma (x);
+#else
+  double result;
+  double sgngam;
+
+  if (xisnan (x))
+    result = x;
+  else if (xisinf (x))
+    result = octave_Inf;
+  else
+    F77_XFCN (dlgams, DLGAMS, (x, result, sgngam));
+
+  return result;
+#endif
+}
+
+Complex
+xlgamma (const Complex& xc)
+{
+  // Can only be called with a real value of x.
+  double x = xc.real ();
+  double result;
+
+#if defined (HAVE_LGAMMA_R)
+  int sgngam;
+  result = lgamma_r (x, &sgngam);    
+#else
+  double sgngam;
+
+  if (xisnan (x))
+    result = x;
+  else if (xisinf (x))
+    result = octave_Inf;
+  else
+    F77_XFCN (dlgams, DLGAMS, (x, result, sgngam));
+
+#endif
+
+  if (sgngam < 0)
+    return result + Complex (0., M_PI);
+  else
+    return result;
+}
+
+float
+xgamma (float x)
+{
+#if defined (HAVE_TGAMMAF)
+  return tgammaf (x);
+#else
+  float result;
+
+  if (xisnan (x))
+    result = x;
+  else if ((x <= 0 && D_NINT (x) == x) || xisinf (x))
+    result = octave_Float_Inf;
+  else
+    F77_XFCN (xgamma, XGAMMA, (x, result));
+
+  return result;
+#endif
+}
+
+float
+xlgamma (float x)
+{
+#if defined (HAVE_LGAMMAF)
+  return lgammaf (x);
+#else
+  float result;
+  float sgngam;
+
+  if (xisnan (x))
+    result = x;
+  else if (xisinf (x))
+    result = octave_Float_Inf;
+  else
+    F77_XFCN (algams, ALGAMS, (x, result, sgngam));
+
+  return result;
+#endif
+}
+
+FloatComplex
+xlgamma (const FloatComplex& xc)
+{
+  // Can only be called with a real value of x.
+  float x = xc.real ();
+  float result;
+
+#if defined (HAVE_LGAMMAF_R)
+  int sgngam;
+  result = lgammaf_r (x, &sgngam);    
+#else
+  float sgngam;
+
+  if (xisnan (x))
+    result = x;
+  else if (xisinf (x))
+    result = octave_Float_Inf;
+  else
+    F77_XFCN (algams, ALGAMS, (x, result, sgngam));
+
+#endif
+
+  if (sgngam < 0)
+    return result + FloatComplex (0., M_PI);
+  else
+    return result;
+}
+
+#if !defined (HAVE_EXPM1)
+double
+expm1 (double x)
+{
+  double retval;
+
+  double ax = fabs (x);
+
+  if (ax < 0.1)
+    {
+      ax /= 16;
+
+      // use Taylor series to calculate exp(x)-1.
+      double t = ax;
+      double s = 0; 
+      for (int i = 2; i < 7; i++)
+        s += (t *= ax/i);
+      s += ax;
+
+      // use the identity (a+1)^2-1 = a*(a+2)
+      double e = s;
+      for (int i = 0; i < 4; i++)
+        {
+          s *= e + 2;
+          e *= e + 2;
+        }
+
+      retval = (x > 0) ? s : -s / (1+s);
+    }
+  else
+    retval = exp (x) - 1;
+
+  return retval;
+}
+#endif
+
+Complex 
+expm1(const Complex& x)
+{
+  Complex retval;
+
+  if (std:: abs (x) < 1)
+    {
+      double im = x.imag();
+      double u = expm1 (x.real ());
+      double v = sin (im/2);
+      v = -2*v*v;
+      retval = Complex (u*v + u + v, (u+1) * sin (im));
+    }
+  else
+    retval = std::exp (x) - Complex (1);
+
+  return retval;
+}
+
+#if !defined (HAVE_EXPM1F)
+float
+expm1f (float x)
+{
+  float retval;
+
+  float ax = fabs (x);
+
+  if (ax < 0.1)
+    {
+      ax /= 16;
+
+      // use Taylor series to calculate exp(x)-1.
+      float t = ax;
+      float s = 0; 
+      for (int i = 2; i < 7; i++)
+        s += (t *= ax/i);
+      s += ax;
+
+      // use the identity (a+1)^2-1 = a*(a+2)
+      float e = s;
+      for (int i = 0; i < 4; i++)
+        {
+          s *= e + 2;
+          e *= e + 2;
+        }
+
+      retval = (x > 0) ? s : -s / (1+s);
+    }
+  else
+    retval = exp (x) - 1;
+
+  return retval;
+}
+#endif
+
+FloatComplex 
+expm1f(const FloatComplex& x)
+{
+  FloatComplex retval;
+
+  if (std:: abs (x) < 1)
+    {
+      float im = x.imag();
+      float u = expm1 (x.real ());
+      float v = sin (im/2);
+      v = -2*v*v;
+      retval = FloatComplex (u*v + u + v, (u+1) * sin (im));
+    }
+  else
+    retval = std::exp (x) - FloatComplex (1);
+
+  return retval;
+}
+
+#if !defined (HAVE_LOG1P)
+double
+log1p (double x)
+{
+  double retval;
+
+  double ax = fabs (x);
+
+  if (ax < 0.2)
+    {
+      // use approximation log (1+x) ~ 2*sum ((x/(2+x)).^ii ./ ii), ii = 1:2:2n+1
+      double u = x / (2 + x), t = 1, s = 0;
+      for (int i = 2; i < 12; i += 2)
+        s += (t *= u*u) / (i+1);
+
+      retval = 2 * (s + 1) * u;
+    }
+  else
+    retval = log (1 + x);
+
+  return retval;
+}
+#endif
+
+Complex 
+log1p (const Complex& x)
+{
+  Complex retval;
+
+  double r = x.real (), i = x.imag();
+
+  if (fabs (r) < 0.5 && fabs (i) < 0.5)
+    {
+      double u = 2*r + r*r + i*i;
+      retval = Complex (log1p (u / (1+sqrt (u+1))),
+			atan2 (1 + r, i));
+    }
+  else
+    retval = std::log (Complex(1) + x);
+
+  return retval;
+}
+
+#if !defined (HAVE_LOG1PF)
+float
+log1pf (float x)
+{
+  float retval;
+
+  float ax = fabs (x);
+
+  if (ax < 0.2)
+    {
+      // use approximation log (1+x) ~ 2*sum ((x/(2+x)).^ii ./ ii), ii = 1:2:2n+1
+      float u = x / (2 + x), t = 1, s = 0;
+      for (int i = 2; i < 12; i += 2)
+        s += (t *= u*u) / (i+1);
+
+      retval = 2 * (s + 1) * u;
+    }
+  else
+    retval = log (1 + x);
+
+  return retval;
+}
+#endif
+
+FloatComplex 
+log1pf (const FloatComplex& x)
+{
+  FloatComplex retval;
+
+  float r = x.real (), i = x.imag();
+
+  if (fabs (r) < 0.5 && fabs (i) < 0.5)
+    {
+      float u = 2*r + r*r + i*i;
+      retval = FloatComplex (log1p (u / (1+sqrt (u+1))),
+			atan2 (1 + r, i));
+    }
+  else
+    retval = std::log (FloatComplex(1) + x);
+
+  return retval;
+}
+
+static inline Complex
+zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
+
+static inline Complex
+zbesy (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
+
+static inline Complex
+zbesi (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
+
+static inline Complex
+zbesk (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
+
+static inline Complex
+zbesh1 (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
+
+static inline Complex
+zbesh2 (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
+
+static inline Complex
+bessel_return_value (const Complex& val, octave_idx_type ierr)
+{
+  static const Complex inf_val = Complex (octave_Inf, octave_Inf);
+  static const Complex nan_val = Complex (octave_NaN, octave_NaN);
+
+  Complex retval;
+
+  switch (ierr)
+    {
+    case 0:
+    case 3:
+      retval = val;
+      break;
+
+    case 2:
+      retval = inf_val;
+      break;
+
+    default:
+      retval = nan_val;
+      break;
+    }
+
+  return retval;
+}
+
+static inline bool
+is_integer_value (double x)
+{
+  return x == static_cast<double> (static_cast<long> (x));
+}
+
+static inline Complex
+zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  if (alpha >= 0.0)
+    {
+      double yr = 0.0;
+      double yi = 0.0;
+
+      octave_idx_type nz;
+
+      double zr = z.real ();
+      double zi = z.imag ();
+
+      F77_FUNC (zbesj, ZBESJ) (zr, zi, alpha, 2, 1, &yr, &yi, nz, ierr);
+
+      if (kode != 2)
+	{
+	  double expz = exp (std::abs (zi)); 
+	  yr *= expz;
+	  yi *= expz;
+	}
+
+      if (zi == 0.0 && zr >= 0.0)
+	yi = 0.0;
+
+      retval = bessel_return_value (Complex (yr, yi), ierr);
+    }
+  else if (is_integer_value (alpha))
+    {
+      // zbesy can overflow as z->0, and cause troubles for generic case below
+      alpha = -alpha;
+      Complex tmp = zbesj (z, alpha, kode, ierr);
+      if ((static_cast <long> (alpha)) & 1) 
+	tmp = - tmp;
+      retval = bessel_return_value (tmp, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      Complex tmp = cos (M_PI * alpha) * zbesj (z, alpha, kode, ierr);
+
+      if (ierr == 0 || ierr == 3)
+	{
+	  tmp -= sin (M_PI * alpha) * zbesy (z, alpha, kode, ierr);
+
+	  retval = bessel_return_value (tmp, ierr);
+	}
+      else
+	retval = Complex (octave_NaN, octave_NaN);
+    }
+
+  return retval;
+}
+
+static inline Complex
+zbesy (const Complex& z, double alpha, int kode, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  if (alpha >= 0.0)
+    {
+      double yr = 0.0;
+      double yi = 0.0;
+
+      octave_idx_type nz;
+
+      double wr, wi;
+
+      double zr = z.real ();
+      double zi = z.imag ();
+
+      ierr = 0;
+
+      if (zr == 0.0 && zi == 0.0)
+	{
+	  yr = -octave_Inf;
+	  yi = 0.0;
+	}
+      else
+	{
+	  F77_FUNC (zbesy, ZBESY) (zr, zi, alpha, 2, 1, &yr, &yi, nz,
+				   &wr, &wi, ierr);
+
+	  if (kode != 2)
+	    {
+	      double expz = exp (std::abs (zi));
+	      yr *= expz;
+	      yi *= expz;
+	    }
+
+	  if (zi == 0.0 && zr >= 0.0)
+	    yi = 0.0;
+	}
+
+      return bessel_return_value (Complex (yr, yi), ierr);
+    }
+  else if (is_integer_value (alpha - 0.5))
+    {
+      // zbesy can overflow as z->0, and cause troubles for generic case below
+      alpha = -alpha;
+      Complex tmp = zbesj (z, alpha, kode, ierr);
+      if ((static_cast <long> (alpha - 0.5)) & 1) 
+	tmp = - tmp;
+      retval = bessel_return_value (tmp, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      Complex tmp = cos (M_PI * alpha) * zbesy (z, alpha, kode, ierr);
+
+      if (ierr == 0 || ierr == 3)
+	{
+	  tmp += sin (M_PI * alpha) * zbesj (z, alpha, kode, ierr);
+
+	  retval = bessel_return_value (tmp, ierr);
+	}
+      else
+	retval = Complex (octave_NaN, octave_NaN);
+    }
+
+  return retval;
+}
+
+static inline Complex
+zbesi (const Complex& z, double alpha, int kode, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  if (alpha >= 0.0)
+    {
+      double yr = 0.0;
+      double yi = 0.0;
+
+      octave_idx_type nz;
+
+      double zr = z.real ();
+      double zi = z.imag ();
+
+      F77_FUNC (zbesi, ZBESI) (zr, zi, alpha, 2, 1, &yr, &yi, nz, ierr);
+
+      if (kode != 2)
+	{
+	  double expz = exp (std::abs (zr));
+	  yr *= expz;
+	  yi *= expz;
+	}
+
+      if (zi == 0.0 && zr >= 0.0)
+	yi = 0.0;
+
+      retval = bessel_return_value (Complex (yr, yi), ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      Complex tmp = zbesi (z, alpha, kode, ierr);
+
+      if (ierr == 0 || ierr == 3)
+	{
+	  Complex tmp2 = (2.0 / M_PI) * sin (M_PI * alpha)
+	    * zbesk (z, alpha, kode, ierr);
+	
+	  if (kode == 2) 
+	    {
+	      // Compensate for different scaling factor of besk.
+	      tmp2 *= exp(-z - std::abs(z.real()));
+	    }
+	  
+	  tmp += tmp2;
+
+	  retval = bessel_return_value (tmp, ierr);
+	}
+      else
+	retval = Complex (octave_NaN, octave_NaN);
+    }
+
+  return retval;
+}
+
+static inline Complex
+zbesk (const Complex& z, double alpha, int kode, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  if (alpha >= 0.0)
+    {
+      double yr = 0.0;
+      double yi = 0.0;
+
+      octave_idx_type nz;
+
+      double zr = z.real ();
+      double zi = z.imag ();
+
+      ierr = 0;
+
+      if (zr == 0.0 && zi == 0.0)
+	{
+	  yr = octave_Inf;
+	  yi = 0.0;
+	}
+      else
+	{
+	  F77_FUNC (zbesk, ZBESK) (zr, zi, alpha, 2, 1, &yr, &yi, nz, ierr);
+
+	  if (kode != 2)
+	    {
+	      Complex expz = exp (-z);
+
+	      double rexpz = real (expz);
+	      double iexpz = imag (expz);
+
+	      double tmp = yr*rexpz - yi*iexpz;
+
+	      yi = yr*iexpz + yi*rexpz;
+	      yr = tmp;
+	    }
+
+	  if (zi == 0.0 && zr >= 0.0)
+	    yi = 0.0;
+	}
+
+      retval = bessel_return_value (Complex (yr, yi), ierr);
+    }
+  else
+    {
+      Complex tmp = zbesk (z, -alpha, kode, ierr);
+
+      retval = bessel_return_value (tmp, ierr);
+    }
+
+  return retval;
+}
+
+static inline Complex
+zbesh1 (const Complex& z, double alpha, int kode, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  if (alpha >= 0.0)
+    {
+      double yr = 0.0;
+      double yi = 0.0;
+
+      octave_idx_type nz;
+
+      double zr = z.real ();
+      double zi = z.imag ();
+
+      F77_FUNC (zbesh, ZBESH) (zr, zi, alpha, 2, 1, 1, &yr, &yi, nz, ierr);
+
+      if (kode != 2)
+	{
+	  Complex expz = exp (Complex (0.0, 1.0) * z);
+
+	  double rexpz = real (expz);
+	  double iexpz = imag (expz);
+
+	  double tmp = yr*rexpz - yi*iexpz;
+
+	  yi = yr*iexpz + yi*rexpz;
+	  yr = tmp;
+	}
+
+      retval = bessel_return_value (Complex (yr, yi), ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      static const Complex eye = Complex (0.0, 1.0);
+
+      Complex tmp = exp (M_PI * alpha * eye) * zbesh1 (z, alpha, kode, ierr);
+
+      retval = bessel_return_value (tmp, ierr);
+    }
+
+  return retval;
+}
+
+static inline Complex
+zbesh2 (const Complex& z, double alpha, int kode, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  if (alpha >= 0.0)
+    {
+      double yr = 0.0;
+      double yi = 0.0;
+
+      octave_idx_type nz;
+
+      double zr = z.real ();
+      double zi = z.imag ();
+
+      F77_FUNC (zbesh, ZBESH) (zr, zi, alpha, 2, 2, 1, &yr, &yi, nz, ierr);
+
+      if (kode != 2)
+	{
+	  Complex expz = exp (-Complex (0.0, 1.0) * z);
+
+	  double rexpz = real (expz);
+	  double iexpz = imag (expz);
+
+	  double tmp = yr*rexpz - yi*iexpz;
+
+	  yi = yr*iexpz + yi*rexpz;
+	  yr = tmp;
+	}
+
+      retval = bessel_return_value (Complex (yr, yi), ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      static const Complex eye = Complex (0.0, 1.0);
+
+      Complex tmp = exp (-M_PI * alpha * eye) * zbesh2 (z, alpha, kode, ierr);
+
+      retval = bessel_return_value (tmp, ierr);
+    }
+
+  return retval;
+}
+
+typedef Complex (*dptr) (const Complex&, double, int, octave_idx_type&);
+
+static inline Complex
+do_bessel (dptr f, const char *, double alpha, const Complex& x,
+	   bool scaled, octave_idx_type& ierr)
+{
+  Complex retval;
+
+  retval = f (x, alpha, (scaled ? 2 : 1), ierr);
+
+  return retval;
+}
+
+static inline ComplexMatrix
+do_bessel (dptr f, const char *, double alpha, const ComplexMatrix& x,
+	   bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = f (x(i,j), alpha, (scaled ? 2 : 1), ierr(i,j));
+
+  return retval;
+}
+
+static inline ComplexMatrix
+do_bessel (dptr f, const char *, const Matrix& alpha, const Complex& x,
+	   bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = alpha.rows ();
+  octave_idx_type nc = alpha.cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = f (x, alpha(i,j), (scaled ? 2 : 1), ierr(i,j));
+
+  return retval;
+}
+
+static inline ComplexMatrix
+do_bessel (dptr f, const char *fn, const Matrix& alpha,
+	   const ComplexMatrix& x, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  ComplexMatrix retval;
+
+  octave_idx_type x_nr = x.rows ();
+  octave_idx_type x_nc = x.cols ();
+
+  octave_idx_type alpha_nr = alpha.rows ();
+  octave_idx_type alpha_nc = alpha.cols ();
+
+  if (x_nr == alpha_nr && x_nc == alpha_nc)
+    {
+      octave_idx_type nr = x_nr;
+      octave_idx_type nc = x_nc;
+
+      retval.resize (nr, nc);
+
+      ierr.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = f (x(i,j), alpha(i,j), (scaled ? 2 : 1), ierr(i,j));
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("%s: the sizes of alpha and x must conform", fn);
+
+  return retval;
+}
+
+static inline ComplexNDArray
+do_bessel (dptr f, const char *, double alpha, const ComplexNDArray& x,
+	   bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+  ComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+      retval(i) = f (x(i), alpha, (scaled ? 2 : 1), ierr(i));
+
+  return retval;
+}
+
+static inline ComplexNDArray
+do_bessel (dptr f, const char *, const NDArray& alpha, const Complex& x,
+	   bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = alpha.dims ();
+  octave_idx_type nel = dv.numel ();
+  ComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval(i) = f (x, alpha(i), (scaled ? 2 : 1), ierr(i));
+
+  return retval;
+}
+
+static inline ComplexNDArray
+do_bessel (dptr f, const char *fn, const NDArray& alpha,
+	   const ComplexNDArray& x, bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = x.dims ();
+  ComplexNDArray retval;
+
+  if (dv == alpha.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+      ierr.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval(i) = f (x(i), alpha(i), (scaled ? 2 : 1), ierr(i));
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("%s: the sizes of alpha and x must conform", fn);
+
+  return retval;
+}
+
+static inline ComplexMatrix
+do_bessel (dptr f, const char *, const RowVector& alpha,
+	   const ComplexColumnVector& x, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = x.length ();
+  octave_idx_type nc = alpha.length ();
+
+  ComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = f (x(i), alpha(j), (scaled ? 2 : 1), ierr(i,j));
+
+  return retval;
+}
+
+#define SS_BESSEL(name, fcn) \
+  Complex \
+  name (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define SM_BESSEL(name, fcn) \
+  ComplexMatrix \
+  name (double alpha, const ComplexMatrix& x, bool scaled, \
+	Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define MS_BESSEL(name, fcn) \
+  ComplexMatrix \
+  name (const Matrix& alpha, const Complex& x, bool scaled, \
+	Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define MM_BESSEL(name, fcn) \
+  ComplexMatrix \
+  name (const Matrix& alpha, const ComplexMatrix& x, bool scaled, \
+	Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define SN_BESSEL(name, fcn) \
+  ComplexNDArray \
+  name (double alpha, const ComplexNDArray& x, bool scaled, \
+	ArrayN<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define NS_BESSEL(name, fcn) \
+  ComplexNDArray \
+  name (const NDArray& alpha, const Complex& x, bool scaled, \
+	ArrayN<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define NN_BESSEL(name, fcn) \
+  ComplexNDArray \
+  name (const NDArray& alpha, const ComplexNDArray& x, bool scaled, \
+	ArrayN<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define RC_BESSEL(name, fcn) \
+  ComplexMatrix \
+  name (const RowVector& alpha, const ComplexColumnVector& x, bool scaled, \
+        Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define ALL_BESSEL(name, fcn) \
+  SS_BESSEL (name, fcn) \
+  SM_BESSEL (name, fcn) \
+  MS_BESSEL (name, fcn) \
+  MM_BESSEL (name, fcn) \
+  SN_BESSEL (name, fcn) \
+  NS_BESSEL (name, fcn) \
+  NN_BESSEL (name, fcn) \
+  RC_BESSEL (name, fcn)
+
+ALL_BESSEL (besselj, zbesj)
+ALL_BESSEL (bessely, zbesy)
+ALL_BESSEL (besseli, zbesi)
+ALL_BESSEL (besselk, zbesk)
+ALL_BESSEL (besselh1, zbesh1)
+ALL_BESSEL (besselh2, zbesh2)
+
+#undef ALL_BESSEL
+#undef SS_BESSEL
+#undef SM_BESSEL
+#undef MS_BESSEL
+#undef MM_BESSEL
+#undef SN_BESSEL
+#undef NS_BESSEL
+#undef NN_BESSEL
+#undef RC_BESSEL
+
+static inline FloatComplex
+cbesj (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr);
+
+static inline FloatComplex
+cbesy (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr);
+
+static inline FloatComplex
+cbesi (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr);
+
+static inline FloatComplex
+cbesk (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr);
+
+static inline FloatComplex
+cbesh1 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr);
+
+static inline FloatComplex
+cbesh2 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr);
+
+static inline FloatComplex
+bessel_return_value (const FloatComplex& val, octave_idx_type ierr)
+{
+  static const FloatComplex inf_val = FloatComplex (octave_Float_Inf, octave_Float_Inf);
+  static const FloatComplex nan_val = FloatComplex (octave_Float_NaN, octave_Float_NaN);
+
+  FloatComplex retval;
+
+  switch (ierr)
+    {
+    case 0:
+    case 3:
+      retval = val;
+      break;
+
+    case 2:
+      retval = inf_val;
+      break;
+
+    default:
+      retval = nan_val;
+      break;
+    }
+
+  return retval;
+}
+
+static inline bool
+is_integer_value (float x)
+{
+  return x == static_cast<float> (static_cast<long> (x));
+}
+
+static inline FloatComplex
+cbesj (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  if (alpha >= 0.0)
+    {
+      FloatComplex y = 0.0;
+
+      octave_idx_type nz;
+
+      F77_FUNC (cbesj, CBESJ) (z, alpha, 2, 1, &y, nz, ierr);
+
+      if (kode != 2)
+	{
+	  float expz = exp (std::abs (imag (z)));
+	  y *= expz;
+	}
+
+      if (imag (z) == 0.0 && real (z) >= 0.0)
+	y = FloatComplex (y.real (), 0.0);
+
+      retval = bessel_return_value (y, ierr);
+    }
+  else if (is_integer_value (alpha))
+    {
+      // zbesy can overflow as z->0, and cause troubles for generic case below
+      alpha = -alpha;
+      FloatComplex tmp = cbesj (z, alpha, kode, ierr);
+      if ((static_cast <long> (alpha)) & 1) 
+	tmp = - tmp;
+      retval = bessel_return_value (tmp, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      FloatComplex tmp = cosf (static_cast<float> (M_PI) * alpha) * cbesj (z, alpha, kode, ierr);
+
+      if (ierr == 0 || ierr == 3)
+	{
+	  tmp -= sinf (static_cast<float> (M_PI) * alpha) * cbesy (z, alpha, kode, ierr);
+
+	  retval = bessel_return_value (tmp, ierr);
+	}
+      else
+	retval = FloatComplex (octave_Float_NaN, octave_Float_NaN);
+    }
+
+  return retval;
+}
+
+static inline FloatComplex
+cbesy (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  if (alpha >= 0.0)
+    {
+      FloatComplex y = 0.0;
+
+      octave_idx_type nz;
+
+      FloatComplex w;
+
+      ierr = 0;
+
+      if (real (z) == 0.0 && imag (z) == 0.0)
+	{
+	  y = FloatComplex (-octave_Float_Inf, 0.0);
+	}
+      else
+	{
+	  F77_FUNC (cbesy, CBESY) (z, alpha, 2, 1, &y, nz, &w, ierr);
+
+	  if (kode != 2)
+	    {
+	      float expz = exp (std::abs (imag (z)));
+	      y *= expz;
+	    }
+
+	  if (imag (z) == 0.0 && real (z) >= 0.0)
+	    y = FloatComplex (y.real (), 0.0);
+	}
+
+      return bessel_return_value (y, ierr);
+    }
+  else if (is_integer_value (alpha - 0.5))
+    {
+      // zbesy can overflow as z->0, and cause troubles for generic case below
+      alpha = -alpha;
+      FloatComplex tmp = cbesj (z, alpha, kode, ierr);
+      if ((static_cast <long> (alpha - 0.5)) & 1) 
+	tmp = - tmp;
+      retval = bessel_return_value (tmp, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      FloatComplex tmp = cosf (static_cast<float> (M_PI) * alpha) * cbesy (z, alpha, kode, ierr);
+
+      if (ierr == 0 || ierr == 3)
+	{
+	  tmp += sinf (static_cast<float> (M_PI) * alpha) * cbesj (z, alpha, kode, ierr);
+
+	  retval = bessel_return_value (tmp, ierr);
+	}
+      else
+	retval = FloatComplex (octave_Float_NaN, octave_Float_NaN);
+    }
+
+  return retval;
+}
+
+static inline FloatComplex
+cbesi (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  if (alpha >= 0.0)
+    {
+      FloatComplex y = 0.0;
+
+      octave_idx_type nz;
+
+      F77_FUNC (cbesi, CBESI) (z, alpha, 2, 1, &y, nz, ierr);
+
+      if (kode != 2)
+	{
+	  float expz = exp (std::abs (real (z)));
+	  y *= expz;
+	}
+
+      if (imag (z) == 0.0 && real (z) >= 0.0)
+	y = FloatComplex (y.real (), 0.0);
+
+      retval = bessel_return_value (y, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      FloatComplex tmp = cbesi (z, alpha, kode, ierr);
+
+      if (ierr == 0 || ierr == 3)
+	{
+	  FloatComplex tmp2 = static_cast<float> (2.0 / M_PI) * sinf (static_cast<float> (M_PI) * alpha)
+	    * cbesk (z, alpha, kode, ierr);
+	  
+	  if (kode == 2) 
+	    {
+	      // Compensate for different scaling factor of besk.
+	      tmp2 *= exp(-z - std::abs(z.real()));
+	    }
+
+	  tmp += tmp2;
+
+	  retval = bessel_return_value (tmp, ierr);
+	}
+      else
+	retval = FloatComplex (octave_Float_NaN, octave_Float_NaN);
+    }
+
+  return retval;
+}
+
+static inline FloatComplex
+cbesk (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  if (alpha >= 0.0)
+    {
+      FloatComplex y = 0.0;
+
+      octave_idx_type nz;
+
+      ierr = 0;
+
+      if (real (z) == 0.0 && imag (z) == 0.0)
+	{
+	  y = FloatComplex (octave_Float_Inf, 0.0);
+	}
+      else
+	{
+	  F77_FUNC (cbesk, CBESK) (z, alpha, 2, 1, &y, nz, ierr);
+
+	  if (kode != 2)
+	    {
+	      FloatComplex expz = exp (-z);
+
+	      float rexpz = real (expz);
+	      float iexpz = imag (expz);
+
+	      float tmp_r = real (y) * rexpz - imag (y) * iexpz;
+	      float tmp_i = real (y) * iexpz + imag (y) * rexpz;
+
+	      y = FloatComplex (tmp_r, tmp_i);
+	    }
+
+	  if (imag (z) == 0.0 && real (z) >= 0.0)
+	    y = FloatComplex (y.real (), 0.0);
+	}
+
+      retval = bessel_return_value (y, ierr);
+    }
+  else
+    {
+      FloatComplex tmp = cbesk (z, -alpha, kode, ierr);
+
+      retval = bessel_return_value (tmp, ierr);
+    }
+
+  return retval;
+}
+
+static inline FloatComplex
+cbesh1 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  if (alpha >= 0.0)
+    {
+      FloatComplex y = 0.0;
+
+      octave_idx_type nz;
+
+      F77_FUNC (cbesh, CBESH) (z, alpha, 2, 1, 1, &y, nz, ierr);
+
+      if (kode != 2)
+	{
+	  FloatComplex expz = exp (FloatComplex (0.0, 1.0) * z);
+
+	  float rexpz = real (expz);
+	  float iexpz = imag (expz);
+
+	  float tmp_r = real (y) * rexpz - imag (y) * iexpz;
+	  float tmp_i = real (y) * iexpz + imag (y) * rexpz;
+
+	  y = FloatComplex (tmp_r, tmp_i);
+	}
+
+      retval = bessel_return_value (y, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      static const FloatComplex eye = FloatComplex (0.0, 1.0);
+
+      FloatComplex tmp = exp (static_cast<float> (M_PI) * alpha * eye) * cbesh1 (z, alpha, kode, ierr);
+
+      retval = bessel_return_value (tmp, ierr);
+    }
+
+  return retval;
+}
+
+static inline FloatComplex
+cbesh2 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  if (alpha >= 0.0)
+    {
+      FloatComplex y = 0.0;
+
+      octave_idx_type nz;
+
+      F77_FUNC (cbesh, CBESH) (z, alpha, 2, 2, 1, &y, nz, ierr);
+
+      if (kode != 2)
+	{
+	  FloatComplex expz = exp (-FloatComplex (0.0, 1.0) * z);
+
+	  float rexpz = real (expz);
+	  float iexpz = imag (expz);
+
+	  float tmp_r = real (y) * rexpz - imag (y) * iexpz;
+	  float tmp_i = real (y) * iexpz + imag (y) * rexpz;
+
+	  y = FloatComplex (tmp_r, tmp_i);
+	}
+
+      retval = bessel_return_value (y, ierr);
+    }
+  else
+    {
+      alpha = -alpha;
+
+      static const FloatComplex eye = FloatComplex (0.0, 1.0);
+
+      FloatComplex tmp = exp (-static_cast<float> (M_PI) * alpha * eye) * cbesh2 (z, alpha, kode, ierr);
+
+      retval = bessel_return_value (tmp, ierr);
+    }
+
+  return retval;
+}
+
+typedef FloatComplex (*fptr) (const FloatComplex&, float, int, octave_idx_type&);
+
+static inline FloatComplex
+do_bessel (fptr f, const char *, float alpha, const FloatComplex& x,
+	   bool scaled, octave_idx_type& ierr)
+{
+  FloatComplex retval;
+
+  retval = f (x, alpha, (scaled ? 2 : 1), ierr);
+
+  return retval;
+}
+
+static inline FloatComplexMatrix
+do_bessel (fptr f, const char *, float alpha, const FloatComplexMatrix& x,
+	   bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = f (x(i,j), alpha, (scaled ? 2 : 1), ierr(i,j));
+
+  return retval;
+}
+
+static inline FloatComplexMatrix
+do_bessel (fptr f, const char *, const FloatMatrix& alpha, const FloatComplex& x,
+	   bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = alpha.rows ();
+  octave_idx_type nc = alpha.cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = f (x, alpha(i,j), (scaled ? 2 : 1), ierr(i,j));
+
+  return retval;
+}
+
+static inline FloatComplexMatrix
+do_bessel (fptr f, const char *fn, const FloatMatrix& alpha,
+	   const FloatComplexMatrix& x, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  FloatComplexMatrix retval;
+
+  octave_idx_type x_nr = x.rows ();
+  octave_idx_type x_nc = x.cols ();
+
+  octave_idx_type alpha_nr = alpha.rows ();
+  octave_idx_type alpha_nc = alpha.cols ();
+
+  if (x_nr == alpha_nr && x_nc == alpha_nc)
+    {
+      octave_idx_type nr = x_nr;
+      octave_idx_type nc = x_nc;
+
+      retval.resize (nr, nc);
+
+      ierr.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = f (x(i,j), alpha(i,j), (scaled ? 2 : 1), ierr(i,j));
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("%s: the sizes of alpha and x must conform", fn);
+
+  return retval;
+}
+
+static inline FloatComplexNDArray
+do_bessel (fptr f, const char *, float alpha, const FloatComplexNDArray& x,
+	   bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+  FloatComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+      retval(i) = f (x(i), alpha, (scaled ? 2 : 1), ierr(i));
+
+  return retval;
+}
+
+static inline FloatComplexNDArray
+do_bessel (fptr f, const char *, const FloatNDArray& alpha, const FloatComplex& x,
+	   bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = alpha.dims ();
+  octave_idx_type nel = dv.numel ();
+  FloatComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval(i) = f (x, alpha(i), (scaled ? 2 : 1), ierr(i));
+
+  return retval;
+}
+
+static inline FloatComplexNDArray
+do_bessel (fptr f, const char *fn, const FloatNDArray& alpha,
+	   const FloatComplexNDArray& x, bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = x.dims ();
+  FloatComplexNDArray retval;
+
+  if (dv == alpha.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+      ierr.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval(i) = f (x(i), alpha(i), (scaled ? 2 : 1), ierr(i));
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("%s: the sizes of alpha and x must conform", fn);
+
+  return retval;
+}
+
+static inline FloatComplexMatrix
+do_bessel (fptr f, const char *, const FloatRowVector& alpha,
+	   const FloatComplexColumnVector& x, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = x.length ();
+  octave_idx_type nc = alpha.length ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = f (x(i), alpha(j), (scaled ? 2 : 1), ierr(i,j));
+
+  return retval;
+}
+
+#define SS_BESSEL(name, fcn) \
+  FloatComplex \
+  name (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define SM_BESSEL(name, fcn) \
+  FloatComplexMatrix \
+  name (float alpha, const FloatComplexMatrix& x, bool scaled, \
+	Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define MS_BESSEL(name, fcn) \
+  FloatComplexMatrix \
+  name (const FloatMatrix& alpha, const FloatComplex& x, bool scaled, \
+	Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define MM_BESSEL(name, fcn) \
+  FloatComplexMatrix \
+  name (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled, \
+	Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define SN_BESSEL(name, fcn) \
+  FloatComplexNDArray \
+  name (float alpha, const FloatComplexNDArray& x, bool scaled, \
+	ArrayN<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define NS_BESSEL(name, fcn) \
+  FloatComplexNDArray \
+  name (const FloatNDArray& alpha, const FloatComplex& x, bool scaled, \
+	ArrayN<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define NN_BESSEL(name, fcn) \
+  FloatComplexNDArray \
+  name (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled, \
+	ArrayN<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define RC_BESSEL(name, fcn) \
+  FloatComplexMatrix \
+  name (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled, \
+        Array2<octave_idx_type>& ierr) \
+  { \
+    return do_bessel (fcn, #name, alpha, x, scaled, ierr); \
+  }
+
+#define ALL_BESSEL(name, fcn) \
+  SS_BESSEL (name, fcn) \
+  SM_BESSEL (name, fcn) \
+  MS_BESSEL (name, fcn) \
+  MM_BESSEL (name, fcn) \
+  SN_BESSEL (name, fcn) \
+  NS_BESSEL (name, fcn) \
+  NN_BESSEL (name, fcn) \
+  RC_BESSEL (name, fcn)
+
+ALL_BESSEL (besselj, cbesj)
+ALL_BESSEL (bessely, cbesy)
+ALL_BESSEL (besseli, cbesi)
+ALL_BESSEL (besselk, cbesk)
+ALL_BESSEL (besselh1, cbesh1)
+ALL_BESSEL (besselh2, cbesh2)
+
+#undef ALL_BESSEL
+#undef SS_BESSEL
+#undef SM_BESSEL
+#undef MS_BESSEL
+#undef MM_BESSEL
+#undef SN_BESSEL
+#undef NS_BESSEL
+#undef NN_BESSEL
+#undef RC_BESSEL
+
+Complex
+airy (const Complex& z, bool deriv, bool scaled, octave_idx_type& ierr)
+{
+  double ar = 0.0;
+  double ai = 0.0;
+
+  octave_idx_type nz;
+
+  double zr = z.real ();
+  double zi = z.imag ();
+
+  octave_idx_type id = deriv ? 1 : 0;
+
+  F77_FUNC (zairy, ZAIRY) (zr, zi, id, 2, ar, ai, nz, ierr);
+
+  if (! scaled)
+    {
+      Complex expz = exp (- 2.0 / 3.0 * z * sqrt(z));
+
+      double rexpz = real (expz);
+      double iexpz = imag (expz);
+
+      double tmp = ar*rexpz - ai*iexpz;
+
+      ai = ar*iexpz + ai*rexpz;
+      ar = tmp;
+    }
+
+  if (zi == 0.0 && (! scaled || zr >= 0.0))
+    ai = 0.0;
+
+  return bessel_return_value (Complex (ar, ai), ierr);
+}
+
+Complex
+biry (const Complex& z, bool deriv, bool scaled, octave_idx_type& ierr)
+{
+  double ar = 0.0;
+  double ai = 0.0;
+
+  double zr = z.real ();
+  double zi = z.imag ();
+
+  octave_idx_type id = deriv ? 1 : 0;
+
+  F77_FUNC (zbiry, ZBIRY) (zr, zi, id, 2, ar, ai, ierr);
+
+  if (! scaled)
+    {
+      Complex expz = exp (std::abs (real (2.0 / 3.0 * z * sqrt (z))));
+
+      double rexpz = real (expz);
+      double iexpz = imag (expz);
+
+      double tmp = ar*rexpz - ai*iexpz;
+
+      ai = ar*iexpz + ai*rexpz;
+      ar = tmp;
+    }
+
+  if (zi == 0.0 && (! scaled || zr >= 0.0))
+    ai = 0.0;
+
+  return bessel_return_value (Complex (ar, ai), ierr);
+}
+
+ComplexMatrix
+airy (const ComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = z.rows ();
+  octave_idx_type nc = z.cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = airy (z(i,j), deriv, scaled, ierr(i,j));
+
+  return retval;
+}
+
+ComplexMatrix
+biry (const ComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = z.rows ();
+  octave_idx_type nc = z.cols ();
+
+  ComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = biry (z(i,j), deriv, scaled, ierr(i,j));
+
+  return retval;
+}
+
+ComplexNDArray
+airy (const ComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = z.dims ();
+  octave_idx_type nel = dv.numel ();
+  ComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = airy (z(i), deriv, scaled, ierr(i));
+
+  return retval;
+}
+
+ComplexNDArray
+biry (const ComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = z.dims ();
+  octave_idx_type nel = dv.numel ();
+  ComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = biry (z(i), deriv, scaled, ierr(i));
+
+  return retval;
+}
+
+FloatComplex
+airy (const FloatComplex& z, bool deriv, bool scaled, octave_idx_type& ierr)
+{
+  float ar = 0.0;
+  float ai = 0.0;
+
+  octave_idx_type nz;
+
+  float zr = z.real ();
+  float zi = z.imag ();
+
+  octave_idx_type id = deriv ? 1 : 0;
+
+  F77_FUNC (cairy, CAIRY) (zr, zi, id, 2, ar, ai, nz, ierr);
+
+  if (! scaled)
+    {
+      FloatComplex expz = exp (- static_cast<float> (2.0 / 3.0) * z * sqrt(z));
+
+      float rexpz = real (expz);
+      float iexpz = imag (expz);
+
+      float tmp = ar*rexpz - ai*iexpz;
+
+      ai = ar*iexpz + ai*rexpz;
+      ar = tmp;
+    }
+
+  if (zi == 0.0 && (! scaled || zr >= 0.0))
+    ai = 0.0;
+
+  return bessel_return_value (FloatComplex (ar, ai), ierr);
+}
+
+FloatComplex
+biry (const FloatComplex& z, bool deriv, bool scaled, octave_idx_type& ierr)
+{
+  float ar = 0.0;
+  float ai = 0.0;
+
+  float zr = z.real ();
+  float zi = z.imag ();
+
+  octave_idx_type id = deriv ? 1 : 0;
+
+  F77_FUNC (cbiry, CBIRY) (zr, zi, id, 2, ar, ai, ierr);
+
+  if (! scaled)
+    {
+      FloatComplex expz = exp (std::abs (real (static_cast<float> (2.0 / 3.0) * z * sqrt (z))));
+
+      float rexpz = real (expz);
+      float iexpz = imag (expz);
+
+      float tmp = ar*rexpz - ai*iexpz;
+
+      ai = ar*iexpz + ai*rexpz;
+      ar = tmp;
+    }
+
+  if (zi == 0.0 && (! scaled || zr >= 0.0))
+    ai = 0.0;
+
+  return bessel_return_value (FloatComplex (ar, ai), ierr);
+}
+
+FloatComplexMatrix
+airy (const FloatComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = z.rows ();
+  octave_idx_type nc = z.cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = airy (z(i,j), deriv, scaled, ierr(i,j));
+
+  return retval;
+}
+
+FloatComplexMatrix
+biry (const FloatComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr)
+{
+  octave_idx_type nr = z.rows ();
+  octave_idx_type nc = z.cols ();
+
+  FloatComplexMatrix retval (nr, nc);
+
+  ierr.resize (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = biry (z(i,j), deriv, scaled, ierr(i,j));
+
+  return retval;
+}
+
+FloatComplexNDArray
+airy (const FloatComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = z.dims ();
+  octave_idx_type nel = dv.numel ();
+  FloatComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = airy (z(i), deriv, scaled, ierr(i));
+
+  return retval;
+}
+
+FloatComplexNDArray
+biry (const FloatComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr)
+{
+  dim_vector dv = z.dims ();
+  octave_idx_type nel = dv.numel ();
+  FloatComplexNDArray retval (dv);
+
+  ierr.resize (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = biry (z(i), deriv, scaled, ierr(i));
+
+  return retval;
+}
+
+static void
+gripe_betainc_nonconformant (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2, octave_idx_type r3,
+			     octave_idx_type c3)
+{
+  (*current_liboctave_error_handler)
+   ("betainc: nonconformant arguments (x is %dx%d, a is %dx%d, b is %dx%d)",
+     r1, c1, r2, c2, r3, c3);
+}
+
+static dim_vector null_dims (0);
+
+static void
+gripe_betainc_nonconformant (const dim_vector& d1, const dim_vector& d2,
+			     const dim_vector& d3)
+{
+  std::string d1_str = d1.str ();
+  std::string d2_str = d2.str ();
+  std::string d3_str = d3.str ();
+
+  (*current_liboctave_error_handler)
+  ("betainc: nonconformant arguments (x is %s, a is %s, b is %s)",
+   d1_str.c_str (), d2_str.c_str (), d3_str.c_str ());
+}
+
+double
+betainc (double x, double a, double b)
+{
+  double retval;
+  F77_XFCN (xdbetai, XDBETAI, (x, a, b, retval));
+  return retval;
+}
+
+Matrix
+betainc (double x, double a, const Matrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  Matrix retval (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = betainc (x, a, b(i,j));
+
+  return retval;
+}
+
+Matrix
+betainc (double x, const Matrix& a, double b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  Matrix retval (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = betainc (x, a(i,j), b);
+
+  return retval;
+}
+
+Matrix
+betainc (double x, const Matrix& a, const Matrix& b)
+{
+  Matrix retval;
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
+    {
+      retval.resize (a_nr, a_nc);
+
+      for (octave_idx_type j = 0; j < a_nc; j++)
+	for (octave_idx_type i = 0; i < a_nr; i++)
+	  retval(i,j) = betainc (x, a(i,j), b(i,j));
+    }
+  else
+    gripe_betainc_nonconformant (1, 1, a_nr, a_nc, b_nr, b_nc);
+
+  return retval;
+}
+
+NDArray
+betainc (double x, double a, const NDArray& b)
+{
+  dim_vector dv = b.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  NDArray retval (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = betainc (x, a, b(i));
+
+  return retval;
+}
+
+NDArray
+betainc (double x, const NDArray& a, double b)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  NDArray retval (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = betainc (x, a(i), b);
+
+  return retval;
+}
+
+NDArray
+betainc (double x, const NDArray& a, const NDArray& b)
+{
+  NDArray retval;
+  dim_vector dv = a.dims ();
+
+  if (dv == b.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x, a(i), b(i));
+    }
+  else
+    gripe_betainc_nonconformant (dim_vector (0), dv, b.dims ());
+  
+  return retval;
+}
+
+
+Matrix
+betainc (const Matrix& x, double a, double b)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  Matrix retval (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = betainc (x(i,j), a, b);
+
+  return retval;
+}
+
+Matrix
+betainc (const Matrix& x, double a, const Matrix& b)
+{
+  Matrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr == b_nr && nc == b_nc)
+    {
+      retval.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = betainc (x(i,j), a, b(i,j));
+    }
+  else
+    gripe_betainc_nonconformant (nr, nc, 1, 1, b_nr, b_nc);
+
+  return retval;
+}
+
+Matrix
+betainc (const Matrix& x, const Matrix& a, double b)
+{
+  Matrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr == a_nr && nc == a_nc)
+    {
+      retval.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = betainc (x(i,j), a(i,j), b);
+    }
+  else
+    gripe_betainc_nonconformant (nr, nc, a_nr, a_nc, 1, 1);
+
+  return retval;
+}
+
+Matrix
+betainc (const Matrix& x, const Matrix& a, const Matrix& b)
+{
+  Matrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr == a_nr && nr == b_nr && nc == a_nc && nc == b_nc)
+    {
+      retval.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = betainc (x(i,j), a(i,j), b(i,j));
+    }
+  else
+    gripe_betainc_nonconformant (nr, nc, a_nr, a_nc, b_nr, b_nc);
+
+  return retval;
+}
+
+NDArray
+betainc (const NDArray& x, double a, double b)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  NDArray retval (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = betainc (x(i), a, b);
+
+  return retval;
+}
+
+NDArray
+betainc (const NDArray& x, double a, const NDArray& b)
+{
+  NDArray retval;
+  dim_vector dv = x.dims ();
+
+  if (dv == b.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x(i), a, b(i));
+    }
+  else
+    gripe_betainc_nonconformant (dv, dim_vector (0), b.dims ());
+  
+  return retval;
+}
+
+NDArray
+betainc (const NDArray& x, const NDArray& a, double b)
+{
+  NDArray retval;
+  dim_vector dv = x.dims ();
+
+  if (dv == a.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x(i), a(i), b);
+    }
+  else
+    gripe_betainc_nonconformant (dv, a.dims (), dim_vector (0));
+  
+  return retval;
+}
+
+NDArray
+betainc (const NDArray& x, const NDArray& a, const NDArray& b)
+{
+  NDArray retval;
+  dim_vector dv = x.dims ();
+
+  if (dv == a.dims () && dv == b.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x(i), a(i), b(i));
+    }
+  else
+    gripe_betainc_nonconformant (dv, a.dims (), b.dims ());
+
+  return retval;
+}
+
+float
+betainc (float x, float a, float b)
+{
+  float retval;
+  F77_XFCN (xbetai, XBETAI, (x, a, b, retval));
+  return retval;
+}
+
+FloatMatrix
+betainc (float x, float a, const FloatMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  FloatMatrix retval (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = betainc (x, a, b(i,j));
+
+  return retval;
+}
+
+FloatMatrix
+betainc (float x, const FloatMatrix& a, float b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  FloatMatrix retval (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = betainc (x, a(i,j), b);
+
+  return retval;
+}
+
+FloatMatrix
+betainc (float x, const FloatMatrix& a, const FloatMatrix& b)
+{
+  FloatMatrix retval;
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
+    {
+      retval.resize (a_nr, a_nc);
+
+      for (octave_idx_type j = 0; j < a_nc; j++)
+	for (octave_idx_type i = 0; i < a_nr; i++)
+	  retval(i,j) = betainc (x, a(i,j), b(i,j));
+    }
+  else
+    gripe_betainc_nonconformant (1, 1, a_nr, a_nc, b_nr, b_nc);
+
+  return retval;
+}
+
+FloatNDArray
+betainc (float x, float a, const FloatNDArray& b)
+{
+  dim_vector dv = b.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  FloatNDArray retval (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = betainc (x, a, b(i));
+
+  return retval;
+}
+
+FloatNDArray
+betainc (float x, const FloatNDArray& a, float b)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  FloatNDArray retval (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = betainc (x, a(i), b);
+
+  return retval;
+}
+
+FloatNDArray
+betainc (float x, const FloatNDArray& a, const FloatNDArray& b)
+{
+  FloatNDArray retval;
+  dim_vector dv = a.dims ();
+
+  if (dv == b.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x, a(i), b(i));
+    }
+  else
+    gripe_betainc_nonconformant (dim_vector (0), dv, b.dims ());
+  
+  return retval;
+}
+
+
+FloatMatrix
+betainc (const FloatMatrix& x, float a, float b)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  FloatMatrix retval (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      retval(i,j) = betainc (x(i,j), a, b);
+
+  return retval;
+}
+
+FloatMatrix
+betainc (const FloatMatrix& x, float a, const FloatMatrix& b)
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr == b_nr && nc == b_nc)
+    {
+      retval.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = betainc (x(i,j), a, b(i,j));
+    }
+  else
+    gripe_betainc_nonconformant (nr, nc, 1, 1, b_nr, b_nc);
+
+  return retval;
+}
+
+FloatMatrix
+betainc (const FloatMatrix& x, const FloatMatrix& a, float b)
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr == a_nr && nc == a_nc)
+    {
+      retval.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = betainc (x(i,j), a(i,j), b);
+    }
+  else
+    gripe_betainc_nonconformant (nr, nc, a_nr, a_nc, 1, 1);
+
+  return retval;
+}
+
+FloatMatrix
+betainc (const FloatMatrix& x, const FloatMatrix& a, const FloatMatrix& b)
+{
+  FloatMatrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr == a_nr && nr == b_nr && nc == a_nc && nc == b_nc)
+    {
+      retval.resize (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  retval(i,j) = betainc (x(i,j), a(i,j), b(i,j));
+    }
+  else
+    gripe_betainc_nonconformant (nr, nc, a_nr, a_nc, b_nr, b_nc);
+
+  return retval;
+}
+
+FloatNDArray
+betainc (const FloatNDArray& x, float a, float b)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  FloatNDArray retval (dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval (i) = betainc (x(i), a, b);
+
+  return retval;
+}
+
+FloatNDArray
+betainc (const FloatNDArray& x, float a, const FloatNDArray& b)
+{
+  FloatNDArray retval;
+  dim_vector dv = x.dims ();
+
+  if (dv == b.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x(i), a, b(i));
+    }
+  else
+    gripe_betainc_nonconformant (dv, dim_vector (0), b.dims ());
+  
+  return retval;
+}
+
+FloatNDArray
+betainc (const FloatNDArray& x, const FloatNDArray& a, float b)
+{
+  FloatNDArray retval;
+  dim_vector dv = x.dims ();
+
+  if (dv == a.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x(i), a(i), b);
+    }
+  else
+    gripe_betainc_nonconformant (dv, a.dims (), dim_vector (0));
+  
+  return retval;
+}
+
+FloatNDArray
+betainc (const FloatNDArray& x, const FloatNDArray& a, const FloatNDArray& b)
+{
+  FloatNDArray retval;
+  dim_vector dv = x.dims ();
+
+  if (dv == a.dims () && dv == b.dims ())
+    {
+      octave_idx_type nel = dv.numel ();
+
+      retval.resize (dv);
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval (i) = betainc (x(i), a(i), b(i));
+    }
+  else
+    gripe_betainc_nonconformant (dv, a.dims (), b.dims ());
+
+  return retval;
+}
+
+// FIXME -- there is still room for improvement here...
+
+double
+gammainc (double x, double a, bool& err)
+{
+  double retval;
+
+  err = false;
+
+  if (a < 0.0 || x < 0.0)
+    {
+      (*current_liboctave_error_handler)
+	("gammainc: A and X must be non-negative");
+
+      err = true;
+    }
+  else
+    F77_XFCN (xgammainc, XGAMMAINC, (a, x, retval));
+
+  return retval;
+}
+
+Matrix
+gammainc (double x, const Matrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  Matrix result (nr, nc);
+  Matrix retval;
+
+  bool err;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	result(i,j) = gammainc (x, a(i,j), err);
+
+	if (err)
+	  goto done;
+      }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+Matrix
+gammainc (const Matrix& x, double a)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  Matrix result (nr, nc);
+  Matrix retval;
+
+  bool err;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	result(i,j) = gammainc (x(i,j), a, err);
+
+	if (err)
+	  goto done;
+      }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+Matrix
+gammainc (const Matrix& x, const Matrix& a)
+{
+  Matrix result;
+  Matrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr == a_nr && nc == a_nc)
+    {
+      result.resize (nr, nc);
+
+      bool err;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    result(i,j) = gammainc (x(i,j), a(i,j), err);
+
+	    if (err)
+	      goto done;
+	  }
+
+      retval = result;
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("gammainc: nonconformant arguments (arg 1 is %dx%d, arg 2 is %dx%d)",
+       nr, nc, a_nr, a_nc);
+
+ done:
+
+  return retval;
+}
+
+NDArray
+gammainc (double x, const NDArray& a)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  NDArray retval;
+  NDArray result (dv);
+
+  bool err;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      result (i) = gammainc (x, a(i), err);
+
+      if (err)
+	goto done;
+    }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+NDArray
+gammainc (const NDArray& x, double a)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  NDArray retval;
+  NDArray result (dv);
+
+  bool err;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      result (i) = gammainc (x(i), a, err);
+
+      if (err)
+	goto done;
+    }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+NDArray
+gammainc (const NDArray& x, const NDArray& a)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  NDArray retval;
+  NDArray result;
+
+  if (dv == a.dims ())
+    {
+      result.resize (dv);
+
+      bool err;
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  result (i) = gammainc (x(i), a(i), err);
+	  
+	  if (err)
+	    goto done;
+	}
+
+      retval = result;
+    }
+  else
+    {
+      std::string x_str = dv.str ();
+      std::string a_str = a.dims ().str ();
+
+      (*current_liboctave_error_handler)
+	("gammainc: nonconformant arguments (arg 1 is %s, arg 2 is %s)",
+	 x_str.c_str (), a_str. c_str ());
+    }
+
+ done:
+
+  return retval;
+}
+
+float
+gammainc (float x, float a, bool& err)
+{
+  float retval;
+
+  err = false;
+
+  if (a < 0.0 || x < 0.0)
+    {
+      (*current_liboctave_error_handler)
+	("gammainc: A and X must be non-negative");
+
+      err = true;
+    }
+  else
+    F77_XFCN (xsgammainc, XSGAMMAINC, (a, x, retval));
+
+  return retval;
+}
+
+FloatMatrix
+gammainc (float x, const FloatMatrix& a)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  FloatMatrix result (nr, nc);
+  FloatMatrix retval;
+
+  bool err;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	result(i,j) = gammainc (x, a(i,j), err);
+
+	if (err)
+	  goto done;
+      }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+FloatMatrix
+gammainc (const FloatMatrix& x, float a)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  FloatMatrix result (nr, nc);
+  FloatMatrix retval;
+
+  bool err;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	result(i,j) = gammainc (x(i,j), a, err);
+
+	if (err)
+	  goto done;
+      }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+FloatMatrix
+gammainc (const FloatMatrix& x, const FloatMatrix& a)
+{
+  FloatMatrix result;
+  FloatMatrix retval;
+
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.cols ();
+
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (nr == a_nr && nc == a_nc)
+    {
+      result.resize (nr, nc);
+
+      bool err;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    result(i,j) = gammainc (x(i,j), a(i,j), err);
+
+	    if (err)
+	      goto done;
+	  }
+
+      retval = result;
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("gammainc: nonconformant arguments (arg 1 is %dx%d, arg 2 is %dx%d)",
+       nr, nc, a_nr, a_nc);
+
+ done:
+
+  return retval;
+}
+
+FloatNDArray
+gammainc (float x, const FloatNDArray& a)
+{
+  dim_vector dv = a.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  FloatNDArray retval;
+  FloatNDArray result (dv);
+
+  bool err;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      result (i) = gammainc (x, a(i), err);
+
+      if (err)
+	goto done;
+    }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+FloatNDArray
+gammainc (const FloatNDArray& x, float a)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  FloatNDArray retval;
+  FloatNDArray result (dv);
+
+  bool err;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      result (i) = gammainc (x(i), a, err);
+
+      if (err)
+	goto done;
+    }
+
+  retval = result;
+
+ done:
+
+  return retval;
+}
+
+FloatNDArray
+gammainc (const FloatNDArray& x, const FloatNDArray& a)
+{
+  dim_vector dv = x.dims ();
+  octave_idx_type nel = dv.numel ();
+
+  FloatNDArray retval;
+  FloatNDArray result;
+
+  if (dv == a.dims ())
+    {
+      result.resize (dv);
+
+      bool err;
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  result (i) = gammainc (x(i), a(i), err);
+	  
+	  if (err)
+	    goto done;
+	}
+
+      retval = result;
+    }
+  else
+    {
+      std::string x_str = dv.str ();
+      std::string a_str = a.dims ().str ();
+
+      (*current_liboctave_error_handler)
+	("gammainc: nonconformant arguments (arg 1 is %s, arg 2 is %s)",
+	 x_str.c_str (), a_str. c_str ());
+    }
+
+ done:
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-specfun.h b/liboctave/lo-specfun.h
new file mode 100644
index 0000000..d5ae6db
--- /dev/null
+++ b/liboctave/lo-specfun.h
@@ -0,0 +1,591 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2002, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_specfun_h)
+#define octave_liboctave_specfun_h 1
+
+#include "oct-cmplx.h"
+#include "oct-types.h"
+#include "ArrayN.h"
+
+template <class T> class Array2;
+class Matrix;
+class ComplexMatrix;
+class NDArray;
+class ComplexNDArray;
+class RowVector;
+class ComplexColumnVector;
+class FloatMatrix;
+class FloatComplexMatrix;
+class FloatNDArray;
+class FloatComplexNDArray;
+class FloatRowVector;
+class FloatComplexColumnVector;
+class Range;
+
+#if !defined (HAVE_ACOSH)
+extern OCTAVE_API double acosh (double);
+#endif
+
+#if !defined (HAVE_ASINH)
+extern OCTAVE_API double asinh (double);
+#endif
+
+#if !defined (HAVE_ATANH)
+extern OCTAVE_API double atanh (double);
+#endif
+
+#if !defined (HAVE_ERF)
+extern OCTAVE_API double erf (double);
+#endif
+
+#if !defined (HAVE_ERFC)
+extern OCTAVE_API double erfc (double);
+#endif
+
+#if !defined (HAVE_ACOSHF)
+extern OCTAVE_API float acoshf (float);
+#endif
+
+#if !defined (HAVE_ASINHF)
+extern OCTAVE_API float asinhf (float);
+#endif
+
+#if !defined (HAVE_ATANHF)
+extern OCTAVE_API float atanhf (float);
+#endif
+
+#if !defined (HAVE_ERFF)
+extern OCTAVE_API float erff (float);
+#endif
+
+#if !defined (HAVE_ERFCF)
+extern OCTAVE_API float erfcf (float);
+#endif
+
+#if !defined (HAVE_EXPM1)
+extern OCTAVE_API double expm1 (double x);
+#endif
+extern OCTAVE_API Complex expm1 (const Complex& x);
+
+#if !defined (HAVE_EXPM1F)
+extern OCTAVE_API float expm1f (float x);
+#endif
+extern OCTAVE_API FloatComplex expm1f (const FloatComplex& x);
+
+#if !defined (HAVE_LOG1P)
+extern OCTAVE_API double log1p (double x);
+#endif
+extern OCTAVE_API Complex log1p (const Complex& x);
+
+#if !defined (HAVE_LOG1PF)
+extern OCTAVE_API float log1pf (float x);
+#endif
+extern OCTAVE_API FloatComplex log1pf (const FloatComplex& x);
+
+extern OCTAVE_API double xgamma (double x);
+extern OCTAVE_API double xlgamma (double x);
+extern OCTAVE_API Complex xlgamma (const Complex& x);
+
+extern OCTAVE_API float xgamma (float x);
+extern OCTAVE_API float xlgamma (float x);
+extern OCTAVE_API FloatComplex xlgamma (const FloatComplex& x);
+
+extern OCTAVE_API Complex
+besselj (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API Complex
+bessely (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API Complex
+besseli (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API Complex
+besselk (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API Complex
+besselh1 (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API Complex
+besselh2 (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselj (double alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+bessely (double alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besseli (double alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselk (double alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh1 (double alpha, const ComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh2 (double alpha, const ComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselj (const Matrix& alpha, const Complex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+bessely (const Matrix& alpha, const Complex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besseli (const Matrix& alpha, const Complex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselk (const Matrix& alpha, const Complex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh1 (const Matrix& alpha, const Complex& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh2 (const Matrix& alpha, const Complex& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselj (const Matrix& alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+bessely (const Matrix& alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besseli (const Matrix& alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselk (const Matrix& alpha, const ComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh1 (const Matrix& alpha, const ComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh2 (const Matrix& alpha, const ComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselj (double alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+bessely (double alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besseli (double alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselk (double alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselh1 (double alpha, const ComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselh2 (double alpha, const ComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselj (const NDArray& alpha, const Complex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+bessely (const NDArray& alpha, const Complex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besseli (const NDArray& alpha, const Complex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselk (const NDArray& alpha, const Complex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselh1 (const NDArray& alpha, const Complex& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselh2 (const NDArray& alpha, const Complex& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselj (const NDArray& alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+bessely (const NDArray& alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besseli (const NDArray& alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselk (const NDArray& alpha, const ComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselh1 (const NDArray& alpha, const ComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+besselh2 (const NDArray& alpha, const ComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselj (const RowVector& alpha, const ComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+bessely (const RowVector& alpha, const ComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besseli (const RowVector& alpha, const ComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselk (const RowVector& alpha, const ComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh1 (const RowVector& alpha, const ComplexColumnVector& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+besselh2 (const RowVector& alpha, const ComplexColumnVector& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplex
+besselj (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplex
+bessely (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplex
+besseli (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplex
+besselk (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplex
+besselh1 (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplex
+besselh2 (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselj (float alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+bessely (float alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besseli (float alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselk (float alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh1 (float alpha, const FloatComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh2 (float alpha, const FloatComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselj (const FloatMatrix& alpha, const FloatComplex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+bessely (const FloatMatrix& alpha, const FloatComplex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besseli (const FloatMatrix& alpha, const FloatComplex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselk (const FloatMatrix& alpha, const FloatComplex& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh1 (const FloatMatrix& alpha, const FloatComplex& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh2 (const FloatMatrix& alpha, const FloatComplex& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselj (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+bessely (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besseli (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselk (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh1 (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh2 (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselj (float alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+bessely (float alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besseli (float alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselk (float alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselh1 (float alpha, const FloatComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselh2 (float alpha, const FloatComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselj (const FloatNDArray& alpha, const FloatComplex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+bessely (const FloatNDArray& alpha, const FloatComplex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besseli (const FloatNDArray& alpha, const FloatComplex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselk (const FloatNDArray& alpha, const FloatComplex& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselh1 (const FloatNDArray& alpha, const FloatComplex& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselh2 (const FloatNDArray& alpha, const FloatComplex& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselj (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+bessely (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besseli (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselk (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled,
+	 ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselh1 (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+besselh2 (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled,
+	  ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselj (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+bessely (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besseli (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselk (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled,
+	 Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh1 (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+besselh2 (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled,
+	  Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API Complex airy (const Complex& z, bool deriv, bool scaled, octave_idx_type& ierr);
+extern OCTAVE_API Complex biry (const Complex& z, bool deriv, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API ComplexMatrix
+airy (const ComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexMatrix
+biry (const ComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+airy (const ComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API ComplexNDArray
+biry (const ComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplex airy (const FloatComplex& z, bool deriv, bool scaled, octave_idx_type& ierr);
+extern OCTAVE_API FloatComplex biry (const FloatComplex& z, bool deriv, bool scaled, octave_idx_type& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+airy (const FloatComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexMatrix
+biry (const FloatComplexMatrix& z, bool deriv, bool scaled, Array2<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+airy (const FloatComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API FloatComplexNDArray
+biry (const FloatComplexNDArray& z, bool deriv, bool scaled, ArrayN<octave_idx_type>& ierr);
+
+extern OCTAVE_API double betainc (double x, double a, double b);
+extern OCTAVE_API Matrix betainc (double x, double a, const Matrix& b);
+extern OCTAVE_API Matrix betainc (double x, const Matrix& a, double b);
+extern OCTAVE_API Matrix betainc (double x, const Matrix& a, const Matrix& b);
+
+extern OCTAVE_API NDArray betainc (double x, double a, const NDArray& b);
+extern OCTAVE_API NDArray betainc (double x, const NDArray& a, double b);
+extern OCTAVE_API NDArray betainc (double x, const NDArray& a, const NDArray& b);
+
+extern OCTAVE_API Matrix betainc (const Matrix& x, double a, double b);
+extern OCTAVE_API Matrix betainc (const Matrix& x, double a, const Matrix& b);
+extern OCTAVE_API Matrix betainc (const Matrix& x, const Matrix& a, double b);
+extern OCTAVE_API Matrix betainc (const Matrix& x, const Matrix& a, const Matrix& b);
+
+extern OCTAVE_API NDArray betainc (const NDArray& x, double a, double b);
+extern OCTAVE_API NDArray betainc (const NDArray& x, double a, const NDArray& b);
+extern OCTAVE_API NDArray betainc (const NDArray& x, const NDArray& a, double b);
+extern OCTAVE_API NDArray betainc (const NDArray& x, const NDArray& a, const NDArray& b);
+
+extern OCTAVE_API float betainc (float x, float a, float b);
+extern OCTAVE_API FloatMatrix betainc (float x, float a, const FloatMatrix& b);
+extern OCTAVE_API FloatMatrix betainc (float x, const FloatMatrix& a, float b);
+extern OCTAVE_API FloatMatrix betainc (float x, const FloatMatrix& a, const FloatMatrix& b);
+
+extern OCTAVE_API FloatNDArray betainc (float x, float a, const FloatNDArray& b);
+extern OCTAVE_API FloatNDArray betainc (float x, const FloatNDArray& a, float b);
+extern OCTAVE_API FloatNDArray betainc (float x, const FloatNDArray& a, const FloatNDArray& b);
+
+extern OCTAVE_API FloatMatrix betainc (const FloatMatrix& x, float a, float b);
+extern OCTAVE_API FloatMatrix betainc (const FloatMatrix& x, float a, const FloatMatrix& b);
+extern OCTAVE_API FloatMatrix betainc (const FloatMatrix& x, const FloatMatrix& a, float b);
+extern OCTAVE_API FloatMatrix betainc (const FloatMatrix& x, const FloatMatrix& a, const FloatMatrix& b);
+
+extern OCTAVE_API FloatNDArray betainc (const FloatNDArray& x, float a, float b);
+extern OCTAVE_API FloatNDArray betainc (const FloatNDArray& x, float a, const FloatNDArray& b);
+extern OCTAVE_API FloatNDArray betainc (const FloatNDArray& x, const FloatNDArray& a, float b);
+extern OCTAVE_API FloatNDArray betainc (const FloatNDArray& x, const FloatNDArray& a, const FloatNDArray& b);
+
+extern OCTAVE_API double gammainc (double x, double a, bool& err);
+extern OCTAVE_API Matrix gammainc (double x, const Matrix& a);
+extern OCTAVE_API Matrix gammainc (const Matrix& x, double a);
+extern OCTAVE_API Matrix gammainc (const Matrix& x, const Matrix& a);
+
+extern OCTAVE_API NDArray gammainc (double x, const NDArray& a);
+extern OCTAVE_API NDArray gammainc (const NDArray& x, double a);
+extern OCTAVE_API NDArray gammainc (const NDArray& x, const NDArray& a);
+
+inline double gammainc (double x, double a)
+{
+  bool err;
+  return gammainc (x, a, err);
+}
+
+extern OCTAVE_API float gammainc (float x, float a, bool& err);
+extern OCTAVE_API FloatMatrix gammainc (float x, const FloatMatrix& a);
+extern OCTAVE_API FloatMatrix gammainc (const FloatMatrix& x, float a);
+extern OCTAVE_API FloatMatrix gammainc (const FloatMatrix& x, const FloatMatrix& a);
+
+extern OCTAVE_API FloatNDArray gammainc (float x, const FloatNDArray& a);
+extern OCTAVE_API FloatNDArray gammainc (const FloatNDArray& x, float a);
+extern OCTAVE_API FloatNDArray gammainc (const FloatNDArray& x, const FloatNDArray& a);
+
+inline float gammainc (float x, float a)
+{
+  bool err;
+  return gammainc (x, a, err);
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-sysdep.cc b/liboctave/lo-sysdep.cc
new file mode 100644
index 0000000..f500ce6
--- /dev/null
+++ b/liboctave/lo-sysdep.cc
@@ -0,0 +1,245 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#include <windows.h>
+#endif
+
+#include "file-ops.h"
+#include "lo-error.h"
+#include "pathlen.h"
+#include "lo-sysdep.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+std::string
+octave_getcwd (void)
+{
+  std::string retval;
+
+  char buf[MAXPATHLEN];
+
+  char *tmp = 0;
+
+#if defined (__EMX__)
+  tmp = _getcwd2 (buf, MAXPATHLEN);
+#elif defined (HAVE_GETCWD)
+  tmp = getcwd (buf, MAXPATHLEN);
+#elif defined (HAVE_GETWD)
+  tmp = getwd (buf);
+#endif
+
+  if (tmp)
+    retval = tmp;
+  else
+    (*current_liboctave_error_handler) ("unable to find current directory");
+
+  return retval;
+}
+
+int
+octave_chdir (const std::string& path_arg)
+{
+  std::string path = file_ops::tilde_expand (path_arg);
+
+#if defined (__EMX__)
+  int retval = -1;
+
+  char *tmp_path = strsave (path.c_str ());
+
+  if (path.length () == 2 && path[1] == ':')
+    {
+      char *upper_case_dir_name = strupr (tmp_path);
+      _chdrive (upper_case_dir_name[0]);
+      if (_getdrive () == upper_case_dir_name[0])
+	retval = _chdir2 ("/");
+    }
+  else
+    retval = _chdir2 (tmp_path);
+
+  delete [] tmp_path;
+
+  return retval;
+#else
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+  if (path.length() == 2 && path[1] == ':')
+    path += "\\";
+#endif
+
+  return chdir (path.c_str ());
+#endif
+}
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+
+pid_t
+octave_popen2 (const std::string& cmd, const string_vector& args, bool sync_mode,
+    int *fildes, std::string& msg)
+{
+  pid_t pid;
+  PROCESS_INFORMATION pi;
+  STARTUPINFO si;
+  std::string command = "\"" + cmd + "\"";
+  HANDLE hProcess = GetCurrentProcess(), childRead, childWrite, parentRead, parentWrite;
+  DWORD pipeMode;
+
+  ZeroMemory (&pi, sizeof (pi));
+  ZeroMemory (&si, sizeof (si));
+  si.cb = sizeof (si);
+
+  if (! CreatePipe (&childRead, &parentWrite, 0, 0) ||
+      ! DuplicateHandle (hProcess, childRead, hProcess, &childRead, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
+    {
+      msg = "popen2: pipe creation failed";
+      return -1;
+    }
+  if (! CreatePipe (&parentRead, &childWrite, 0, 0) ||
+      ! DuplicateHandle (hProcess, childWrite, hProcess, &childWrite, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
+    {
+      msg = "popen2: pipe creation failed";
+      return -1;
+    }
+  if (! sync_mode)
+    {
+      pipeMode = PIPE_NOWAIT;
+      SetNamedPipeHandleState (parentRead, &pipeMode, 0, 0);
+    }
+  fildes[1] = _open_osfhandle (reinterpret_cast<long> (parentRead), _O_RDONLY | _O_BINARY);
+  fildes[0] = _open_osfhandle (reinterpret_cast<long> (parentWrite), _O_WRONLY | _O_BINARY);
+  si.dwFlags |= STARTF_USESTDHANDLES;
+  si.hStdInput = childRead;
+  si.hStdOutput = childWrite;
+
+  // Ignore first arg as it is the command
+  for (int k=1; k<args.length(); k++)
+    command += " \"" + args[k] + "\"";
+  OCTAVE_LOCAL_BUFFER (char, c_command, command.length () + 1);
+  strcpy (c_command, command.c_str ());
+  if (! CreateProcess (0, c_command, 0, 0, TRUE, 0, 0, 0, &si, &pi))
+    {
+      msg = "popen2: process creation failed";
+      return -1;
+    }
+  pid = pi.dwProcessId;
+
+  CloseHandle (childRead);
+  CloseHandle (childWrite);
+  CloseHandle (pi.hProcess);
+  CloseHandle (pi.hThread);
+
+  return pid;
+}
+
+#endif
+
+#if defined (_MSC_VER) && ! defined (HAVE_DIRENT_H)
+
+// FIXME -- it would probably be better to adapt the versions of
+// opendir, readdir, and closedir from Emacs as they appear to be more
+// complete implementations (do the functions below work for network
+// paths, for example)?  We can probably get along without rewinddir.
+
+struct __DIR
+{
+  HANDLE hnd;
+  WIN32_FIND_DATA fd;
+  int dirty;
+  struct direct d;
+  const char *current;
+};
+
+DIR *
+opendir (const char *name)
+{
+  DIR *d = static_cast<DIR *> (malloc (sizeof (DIR)));
+  static char buffer[MAX_PATH];
+
+  strncpy (buffer, name, MAX_PATH);
+  if (buffer[strnlen(buffer, MAX_PATH)-1] != '\\')
+    strncat (buffer, "\\*", MAX_PATH);
+  else
+    strncat (buffer, "*", MAX_PATH);
+  d->current = buffer;
+  d->hnd = FindFirstFile (buffer, &(d->fd));
+  if (d->hnd == INVALID_HANDLE_VALUE)
+    return 0;
+  d->dirty = 1;
+  return d;
+}
+
+void
+rewinddir (DIR *d)
+{
+  if (d->hnd != INVALID_HANDLE_VALUE)
+    FindClose (d->hnd);
+  d->hnd = FindFirstFile (d->current, &(d->fd));
+  d->dirty = 1;
+}
+
+void
+closedir (DIR *d)
+{
+  if (d->hnd != INVALID_HANDLE_VALUE)
+    FindClose (d->hnd);
+  free (d);
+}
+
+struct direct *
+readdir (DIR *d)
+{
+  if (! d->dirty)
+    {
+      if (! FindNextFile(d->hnd, &(d->fd)))
+	return 0;
+    }
+  d->d.d_name = d->fd.cFileName;
+  d->dirty = 0;
+  return &(d->d);
+}
+
+#endif
+ 
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-sysdep.h b/liboctave/lo-sysdep.h
new file mode 100644
index 0000000..e8e8b51
--- /dev/null
+++ b/liboctave/lo-sysdep.h
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_sysdep_h)
+#define octave_liboctave_sysdep_h 1
+
+#include <string>
+
+#include "lo-ieee.h"
+class string_vector;
+
+extern std::string octave_getcwd (void);
+
+extern int octave_chdir (const std::string&);
+
+#if ! defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
+extern int gethostname (char *, int);
+#endif
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+extern pid_t octave_popen2 (const std::string&, const string_vector&,
+    bool, int *, std::string&);
+#endif
+
+#if defined (_MSC_VER) && ! defined (HAVE_DIRENT_H)
+
+// FIXME -- it would probably be better to adapt the versions of
+// opendir, readdir, and closedir from Emacs as they appear to be more
+// complete implementations.  We can probably get along without
+// rewinddir.
+
+struct direct
+{
+  char *d_name;
+};
+
+typedef struct __DIR DIR;
+
+extern DIR* opendir (const char *name);
+extern void rewinddir (DIR *d);
+extern void closedir (DIR *d);
+extern struct direct *readdir (DIR *d);
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-traits.h b/liboctave/lo-traits.h
new file mode 100644
index 0000000..d6a09b3
--- /dev/null
+++ b/liboctave/lo-traits.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_traits_h)
+#define octave_liboctave_traits_h 1
+
+// Ideas for these classes taken from C++ Templates, The Complete
+// Guide by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley
+// (2003).
+
+// Select a type based on the value of a constant expression.
+
+template <bool cond, typename T1, typename T2>
+class if_then_else;
+
+template<typename T1, typename T2>
+class if_then_else<true, T1, T2>
+{
+public:
+
+  typedef T1 result;
+};
+
+template<typename T1, typename T2>
+class if_then_else<false, T1, T2>
+{
+public:
+
+  typedef T2 result;
+};
+
+// Determine whether a template paramter is a class type.
+
+template<typename T1>
+class is_class_type
+{
+private:
+
+  typedef char one;
+  typedef struct { char c[2]; } two;
+
+  // Classes can have pointers to members.
+  template<typename T2> static one is_class_type_test (int T2::*);
+
+  // Catch everything else.
+  template<typename T2> static two is_class_type_test (...);
+
+public:
+
+  enum { yes = sizeof (is_class_type_test<T1> (0)) == 1 };
+  enum { no = ! yes };
+};
+
+// Define typename ref_param<T>::type as T const& if T is a class
+// type.  Otherwise, define it to be T.
+
+template<typename T>
+class ref_param
+{
+public:
+
+  typedef typename if_then_else<is_class_type<T>::no, T, T const&>::result type;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-utils.cc b/liboctave/lo-utils.cc
new file mode 100644
index 0000000..29c1b2e
--- /dev/null
+++ b/liboctave/lo-utils.cc
@@ -0,0 +1,607 @@
+// utils.cc
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+#include <limits>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+
+// Convert X to the nearest integer value.  Should not pass NaN to
+// this function.
+
+// Sometimes you need a large integer, but not always.
+
+octave_idx_type
+NINTbig (double x)
+{
+  if (x > std::numeric_limits<octave_idx_type>::max ())
+    return std::numeric_limits<octave_idx_type>::max ();
+  else if (x < std::numeric_limits<octave_idx_type>::min ())
+    return std::numeric_limits<octave_idx_type>::min ();
+  else
+    return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+octave_idx_type
+NINTbig (float x)
+{
+  if (x > std::numeric_limits<octave_idx_type>::max ())
+    return std::numeric_limits<octave_idx_type>::max ();
+  else if (x < std::numeric_limits<octave_idx_type>::min ())
+    return std::numeric_limits<octave_idx_type>::min ();
+  else
+    return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+int
+NINT (double x)
+{
+  if (x > std::numeric_limits<int>::max ())
+    return std::numeric_limits<int>::max ();
+  else if (x < std::numeric_limits<int>::min ())
+    return std::numeric_limits<int>::min ();
+  else
+    return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+int
+NINT (float x)
+{
+  if (x > std::numeric_limits<int>::max ())
+    return std::numeric_limits<int>::max ();
+  else if (x < std::numeric_limits<int>::min ())
+    return std::numeric_limits<int>::min ();
+  else
+    return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+double
+D_NINT (double x)
+{
+  if (xisinf (x) || xisnan (x))
+    return x;
+  else
+    return floor (x + 0.5);
+}
+
+float
+F_NINT (float x)
+{
+  if (xisinf (x) || xisnan (x))
+    return x;
+  else
+    return floor (x + 0.5);
+}
+
+// Save a string.
+
+char *
+strsave (const char *s)
+{
+  if (! s)
+    return 0;
+
+  int len = strlen (s);
+  char *tmp = new char [len+1];
+  tmp = strcpy (tmp, s);
+  return tmp;
+}
+
+// This function was adapted from xputenv from Karl Berry's kpathsearch
+// library.
+
+// FIXME -- make this do the right thing if we don't have a
+// SMART_PUTENV.
+
+void
+octave_putenv (const std::string& name, const std::string& value)
+{
+  int new_len = name.length () + value.length () + 2;
+
+  char *new_item = static_cast<char*> (malloc (new_len));
+
+  sprintf (new_item, "%s=%s", name.c_str (), value.c_str ());
+
+  // As far as I can see there's no way to distinguish between the
+  // various errors; putenv doesn't have errno values.
+
+  if (putenv (new_item) < 0)
+    (*current_liboctave_error_handler) ("putenv (%s) failed", new_item);
+}
+
+std::string
+octave_fgets (FILE *f)
+{
+  bool eof;
+  return octave_fgets (f, eof);
+}
+
+std::string
+octave_fgets (FILE *f, bool& eof)
+{
+  eof = false;
+
+  std::string retval;
+
+  int grow_size = 1024;
+  int max_size = grow_size;
+
+  char *buf = static_cast<char *> (malloc (max_size));
+  char *bufptr = buf;
+  int len = 0;
+
+  do
+    {
+      if (fgets (bufptr, grow_size, f))
+	{
+	  len = strlen (bufptr);
+
+	  if (len == grow_size - 1)
+	    {
+	      int tmp = bufptr - buf + grow_size - 1;
+	      grow_size *= 2;
+	      max_size += grow_size;
+	      buf = static_cast<char *> (realloc (buf, max_size));
+	      bufptr = buf + tmp;
+
+	      if (*(bufptr-1) == '\n')
+		{
+		  *bufptr = '\0';
+		  retval = buf;
+		}
+	    }
+	  else if (bufptr[len-1] != '\n')
+	    {
+	      bufptr[len++] = '\n';
+	      bufptr[len] = '\0';
+	      retval = buf;
+	    }
+	  else
+	    retval = buf;
+	}
+      else
+	{
+	  if (len == 0)
+	    {
+	      eof = true;
+
+	      free (buf);
+
+	      buf = 0;
+	    }
+
+	  break;
+	}
+    }
+  while (retval.empty ());
+
+  if (buf)
+    free (buf);
+
+  return retval;
+}
+
+std::string
+octave_fgetl (FILE *f)
+{
+  bool eof;
+  return octave_fgetl (f, eof);
+}
+
+std::string
+octave_fgetl (FILE *f, bool& eof)
+{
+  std::string retval = octave_fgets (f, eof);
+
+  size_t len = retval.length ();
+
+  if (retval[len-1] == '\n')
+    retval.resize (len-1);
+
+  return retval;
+}
+
+static inline double
+read_inf_nan_na (std::istream& is, char c, char sign = '+')
+{
+  double d = 0.0;
+
+  switch (c)
+    {
+    case 'i': case 'I':
+      {
+	c = is.get ();
+	if (c == 'n' || c == 'N')
+	  {
+	    c = is.get ();
+	    if (c == 'f' || c == 'F')
+	      d = sign == '-' ? -octave_Inf : octave_Inf;
+	    else
+	      is.putback (c);
+	  }
+	else
+	  is.putback (c);
+      }
+      break;
+
+    case 'n': case 'N':
+      {
+	c = is.get ();
+	if (c == 'a' || c == 'A')
+	  {
+	    c = is.get ();
+	    if (c == 'n' || c == 'N')
+	      d = octave_NaN;
+	    else
+	      {
+		is.putback (c);
+		d = octave_NA;
+	      }
+	  }
+	else
+	  is.putback (c);
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return d;
+}
+
+double
+octave_read_double (std::istream& is)
+{
+  double d = 0.0;
+
+  char c1 = ' ';
+
+  while (isspace (c1))
+    c1 = is.get ();
+
+  switch (c1)
+    {
+    case '-':
+      {
+	char c2 = 0;
+	c2 = is.get ();
+	if (c2 == 'i' || c2 == 'I')
+	  d = read_inf_nan_na (is, c2, c1);
+	else
+	  {
+	    is.putback (c2);
+	    is.putback (c1);
+	    is >> d;
+	  }
+      }
+      break;
+
+    case '+':
+      {
+	char c2 = 0;
+	c2 = is.get ();
+	if (c2 == 'i' || c2 == 'I')
+	  d = read_inf_nan_na (is, c2, c1);
+	else
+	  {
+	    is.putback (c2);
+	    is.putback (c1);
+	    is >> d;
+	  }
+      }
+      break;
+
+    case 'i': case 'I':
+    case 'n': case 'N':
+      d = read_inf_nan_na (is, c1);
+      break;
+
+    default:
+      is.putback (c1);
+      is >> d;
+    }
+
+  return d;
+}
+
+Complex
+octave_read_complex (std::istream& is)
+{
+  double re = 0.0, im = 0.0;
+
+  Complex cx = 0.0;
+
+  char ch = ' ';
+
+  while (isspace (ch))
+    ch = is.get ();
+
+  if (ch == '(')
+    {
+      re = octave_read_double (is);
+      ch = is.get ();
+
+      if (ch == ',')
+	{
+	  im = octave_read_double (is);
+	  ch = is.get ();
+
+	  if (ch == ')')
+	    cx = Complex (re, im);
+	  else
+	    is.setstate (std::ios::failbit);
+	}
+      else if (ch == ')')
+	cx = re;
+      else
+	is.setstate (std::ios::failbit);
+    }
+  else
+    {
+      is.putback (ch);
+      cx = octave_read_double (is);
+    }
+
+  return cx;
+
+}
+
+void
+octave_write_double (std::ostream& os, double d)
+{
+  if (lo_ieee_is_NA (d))
+    os << "NA";
+  else if (lo_ieee_isnan (d))
+    os << "NaN";
+  else if (lo_ieee_isinf (d))
+    os << (d < 0 ? "-Inf" : "Inf");
+  else
+    os << d;
+}
+
+void
+octave_write_complex (std::ostream& os, const Complex& c)
+{
+  os << "(";
+  octave_write_double (os, real (c));
+  os << ",";
+  octave_write_double (os, imag (c));
+  os << ")";
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static inline float
+read_float_inf_nan_na (std::istream& is, char c, char sign = '+')
+{
+  float d = 0.0;
+
+  switch (c)
+    {
+    case 'i': case 'I':
+      {
+	c = is.get ();
+	if (c == 'n' || c == 'N')
+	  {
+	    c = is.get ();
+	    if (c == 'f' || c == 'F')
+	      d = sign == '-' ? -octave_Inf : octave_Inf;
+	    else
+	      is.putback (c);
+	  }
+	else
+	  is.putback (c);
+      }
+      break;
+
+    case 'n': case 'N':
+      {
+	c = is.get ();
+	if (c == 'a' || c == 'A')
+	  {
+	    c = is.get ();
+	    if (c == 'n' || c == 'N')
+	      d = octave_NaN;
+	    else
+	      {
+		is.putback (c);
+		d = octave_NA;
+	      }
+	  }
+	else
+	  is.putback (c);
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return d;
+}
+
+float
+octave_read_float (std::istream& is)
+{
+  float d = 0.0;
+
+  char c1 = ' ';
+
+  while (isspace (c1))
+    c1 = is.get ();
+
+  switch (c1)
+    {
+    case '-':
+      {
+	char c2 = 0;
+	c2 = is.get ();
+	if (c2 == 'i' || c2 == 'I')
+	  d = read_float_inf_nan_na (is, c2, c1);
+	else
+	  {
+	    is.putback (c2);
+	    is.putback (c1);
+	    is >> d;
+	  }
+      }
+      break;
+
+    case '+':
+      {
+	char c2 = 0;
+	c2 = is.get ();
+	if (c2 == 'i' || c2 == 'I')
+	  d = read_float_inf_nan_na (is, c2, c1);
+	else
+	  {
+	    is.putback (c2);
+	    is.putback (c1);
+	    is >> d;
+	  }
+      }
+      break;
+
+    case 'i': case 'I':
+    case 'n': case 'N':
+      d = read_float_inf_nan_na (is, c1);
+      break;
+
+    default:
+      is.putback (c1);
+      is >> d;
+    }
+
+  return d;
+}
+
+FloatComplex
+octave_read_float_complex (std::istream& is)
+{
+  float re = 0.0, im = 0.0;
+
+  FloatComplex cx = 0.0;
+
+  char ch = ' ';
+
+  while (isspace (ch))
+    ch = is.get ();
+
+  if (ch == '(')
+    {
+      re = octave_read_float (is);
+      ch = is.get ();
+
+      if (ch == ',')
+	{
+	  im = octave_read_float (is);
+	  ch = is.get ();
+
+	  if (ch == ')')
+	    cx = FloatComplex (re, im);
+	  else
+	    is.setstate (std::ios::failbit);
+	}
+      else if (ch == ')')
+	cx = re;
+      else
+	is.setstate (std::ios::failbit);
+    }
+  else
+    {
+      is.putback (ch);
+      cx = octave_read_float (is);
+    }
+
+  return cx;
+
+}
+
+void
+octave_write_float (std::ostream& os, float d)
+{
+  if (lo_ieee_is_NA (d))
+    os << "NA";
+  else if (lo_ieee_isnan (d))
+    os << "NaN";
+  else if (lo_ieee_isinf (d))
+    os << (d < 0 ? "-Inf" : "Inf");
+  else
+    os << d;
+}
+
+void
+octave_write_float_complex (std::ostream& os, const FloatComplex& c)
+{
+  os << "(";
+  octave_write_float (os, real (c));
+  os << ",";
+  octave_write_float (os, imag (c));
+  os << ")";
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/lo-utils.h b/liboctave/lo-utils.h
new file mode 100644
index 0000000..18c20eb
--- /dev/null
+++ b/liboctave/lo-utils.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_utils_h)
+#define octave_liboctave_utils_h 1
+
+#include <cstdio>
+
+#include <iosfwd>
+#include <string>
+
+#include "oct-cmplx.h"
+#include "oct-types.h"
+#include "syswait.h"
+
+extern OCTAVE_API octave_idx_type NINTbig (double x);
+extern OCTAVE_API octave_idx_type NINTbig (float x);
+extern OCTAVE_API int NINT (double x);
+extern OCTAVE_API int NINT (float x);
+extern OCTAVE_API double D_NINT (double x);
+extern OCTAVE_API float F_NINT (float x);
+
+extern OCTAVE_API char *strsave (const char *);
+
+extern OCTAVE_API void octave_putenv (const std::string&, const std::string&);
+
+extern OCTAVE_API std::string octave_fgets (std::FILE *);
+extern OCTAVE_API std::string octave_fgetl (std::FILE *);
+
+extern OCTAVE_API std::string octave_fgets (std::FILE *, bool& eof);
+extern OCTAVE_API std::string octave_fgetl (std::FILE *, bool& eof);
+
+extern "C" OCTAVE_API int octave_gethostname (char *, int);
+
+extern "C" OCTAVE_API void octave_qsort (void *base, size_t n, size_t size,
+			      int (*cmp) (const void *, const void *));
+
+extern "C" OCTAVE_API char *oct_strptime (const char *buf, const char *format,
+			       struct tm *tm);
+
+extern "C" OCTINTERP_API int octave_strcasecmp (const char *s1, const char *s2);
+
+extern "C" OCTINTERP_API int octave_strncasecmp (const char *s1, const char *s2, size_t n);
+
+extern OCTAVE_API double octave_read_double (std::istream& is);
+extern OCTAVE_API Complex octave_read_complex (std::istream& is);
+
+extern OCTAVE_API void octave_write_double (std::ostream& os, double dval);
+extern OCTAVE_API void octave_write_complex (std::ostream& os, const Complex& cval);
+
+extern OCTAVE_API float octave_read_float (std::istream& is);
+extern OCTAVE_API FloatComplex octave_read_float_complex (std::istream& is);
+
+extern OCTAVE_API void octave_write_float (std::ostream& os, float dval);
+extern OCTAVE_API void octave_write_float_complex (std::ostream& os, const FloatComplex& cval);
+
+#ifdef HAVE_LOADLIBRARY_API
+#include <windows.h>
+extern "C" OCTAVE_API void * octave_w32_library_search (HINSTANCE handle, const char *name);
+#undef min
+#undef max
+#endif
+#endif
+
+extern "C" OCTAVE_API pid_t octave_waitpid (pid_t pid, int *status, int options);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mach-info.cc b/liboctave/mach-info.cc
new file mode 100644
index 0000000..c08c4ea
--- /dev/null
+++ b/liboctave/mach-info.cc
@@ -0,0 +1,264 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "mach-info.h"
+#include "oct-types.h"
+
+extern "C"
+{
+  double F77_FUNC (d1mach, D1MACH) (const octave_idx_type&);
+}
+
+oct_mach_info *oct_mach_info::instance = 0;
+
+union equiv
+{
+  double d;
+  int i[2];
+};
+
+struct
+float_params
+{
+  oct_mach_info::float_format fp_fmt;
+  equiv fp_par[4];
+};
+
+#define INIT_FLT_PAR(fp, fmt, sm1, sm2, lrg1, lrg2, rt1, rt2, dv1, dv2) \
+  do \
+    { \
+      fp.fp_fmt = (fmt); \
+      fp.fp_par[0].i[0] = (sm1);  fp.fp_par[0].i[1] = (sm2); \
+      fp.fp_par[1].i[0] = (lrg1); fp.fp_par[1].i[1] = (lrg2); \
+      fp.fp_par[2].i[0] = (rt1);  fp.fp_par[2].i[1] = (rt2); \
+      fp.fp_par[3].i[0] = (dv1);  fp.fp_par[3].i[1] = (dv2); \
+    } \
+  while (0)
+
+static int
+equiv_compare (const equiv *std, const equiv *v, int len)
+{
+  int i;
+  for (i = 0; i < len; i++)
+    if (v[i].i[0] != std[i].i[0] || v[i].i[1] != std[i].i[1])
+      return 0;
+  return 1;
+}
+
+void
+oct_mach_info::init_float_format (void) const
+{
+#if defined (CRAY)
+
+  // FIXME -- this should be determined automatically.
+
+  native_float_fmt = oct_mach_info::flt_fmt_cray;
+
+#else
+
+  float_params fp[5];
+
+  INIT_FLT_PAR (fp[0], oct_mach_info::flt_fmt_ieee_big_endian,
+		   1048576,  0,
+		2146435071, -1,
+		1017118720,  0,
+		1018167296,  0);
+
+  INIT_FLT_PAR (fp[1], oct_mach_info::flt_fmt_ieee_little_endian,
+		 0,    1048576,
+		-1, 2146435071,
+		 0, 1017118720,
+		 0, 1018167296);
+
+  INIT_FLT_PAR (fp[2], oct_mach_info::flt_fmt_vax_d,
+		   128,  0,
+		-32769, -1,
+		  9344,  0,
+		  9344,  0);
+
+  INIT_FLT_PAR (fp[3], oct_mach_info::flt_fmt_vax_g,
+		    16,  0,
+		-32769, -1,
+		 15552,  0,
+		 15552,  0);
+
+  INIT_FLT_PAR (fp[4], oct_mach_info::flt_fmt_unknown,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0);
+
+  equiv mach_fp_par[4];
+
+  mach_fp_par[0].d = F77_FUNC (d1mach, D1MACH) (1);
+  mach_fp_par[1].d = F77_FUNC (d1mach, D1MACH) (2);
+  mach_fp_par[2].d = F77_FUNC (d1mach, D1MACH) (3);
+  mach_fp_par[3].d = F77_FUNC (d1mach, D1MACH) (4);
+
+  int i = 0;
+  do
+    {
+      if (equiv_compare (fp[i].fp_par, mach_fp_par, 4))
+	{
+	  native_float_fmt = fp[i].fp_fmt;
+	  break;
+	}
+    }
+  while (fp[++i].fp_fmt != oct_mach_info::flt_fmt_unknown);
+
+#endif
+}
+
+void
+oct_mach_info::ten_little_endians (void) const
+{
+  // Are we little or big endian?  From Harbison & Steele.
+
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+
+  u.l = 1;
+
+  big_chief = (u.c[sizeof (long) - 1] == 1);
+}
+
+oct_mach_info::oct_mach_info (void)
+{
+  init_float_format ();
+  ten_little_endians ();
+}
+
+bool
+oct_mach_info::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new oct_mach_info ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create command history object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+oct_mach_info::float_format
+oct_mach_info::native_float_format (void)
+{
+  return (instance_ok ())
+    ? instance->native_float_fmt : oct_mach_info::flt_fmt_unknown;
+}
+
+bool
+oct_mach_info::words_big_endian (void)
+{
+  return (instance_ok ())
+    ? instance->big_chief : false;
+}
+
+bool
+oct_mach_info::words_little_endian (void)
+{
+  return (instance_ok ())
+    ? (! instance->big_chief) : false;
+}
+
+oct_mach_info::float_format
+oct_mach_info::string_to_float_format (const std::string& s)
+{
+  oct_mach_info::float_format retval = oct_mach_info::flt_fmt_unknown;
+
+  if (s == "native" || s == "n")
+    retval = oct_mach_info::native_float_format ();
+  else if (s == "ieee-be" || s == "b")
+    retval = oct_mach_info::flt_fmt_ieee_big_endian;
+  else if (s == "ieee-le" || s == "l")
+    retval = oct_mach_info::flt_fmt_ieee_little_endian;
+  else if (s == "vaxd" || s == "d")
+    retval = oct_mach_info::flt_fmt_vax_d;
+  else if (s == "vaxg" || s == "g")
+    retval = oct_mach_info::flt_fmt_vax_g;
+  else if (s == "cray" || s == "c")
+    retval = oct_mach_info::flt_fmt_cray;
+  else if (s == "unknown")
+    retval = oct_mach_info::flt_fmt_unknown;
+  else
+    (*current_liboctave_error_handler)
+      ("invalid architecture type specified");
+
+  return retval;
+}
+
+std::string
+oct_mach_info::float_format_as_string (float_format flt_fmt)
+{
+  std::string retval = "unknown";
+
+  switch (flt_fmt)
+    {
+    case flt_fmt_ieee_big_endian:
+      retval = "ieee_big_endian";
+      break;
+
+    case flt_fmt_ieee_little_endian:
+      retval = "ieee_little_endian";
+      break;
+
+    case flt_fmt_vax_d:
+      retval = "vax_d_float";
+      break;
+
+    case flt_fmt_vax_g:
+      retval = "vax_g_float";
+      break;
+
+    case flt_fmt_cray:
+      retval = "cray";
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mach-info.h b/liboctave/mach-info.h
new file mode 100644
index 0000000..fd82094
--- /dev/null
+++ b/liboctave/mach-info.h
@@ -0,0 +1,88 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2003, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mach_info_h)
+#define octave_mach_info_h 1
+
+#include <string>
+
+class
+OCTAVE_API
+oct_mach_info
+{
+protected:
+
+  oct_mach_info (void);
+
+public:
+
+  enum float_format
+    {
+      flt_fmt_unknown,
+      flt_fmt_ieee_little_endian,
+      flt_fmt_ieee_big_endian,
+      flt_fmt_vax_d,
+      flt_fmt_vax_g,
+      flt_fmt_cray
+    };
+
+  static bool instance_ok (void);
+
+  static float_format native_float_format (void);
+
+  static bool words_big_endian (void);
+
+  static bool words_little_endian (void);
+
+  static float_format string_to_float_format (const std::string&);
+
+  static std::string float_format_as_string (float_format);
+
+private:
+
+  static oct_mach_info *instance;
+
+  void init_float_format (void) const;
+
+  void ten_little_endians (void) const;
+
+  // The floating point format for the current machine.
+  mutable float_format native_float_fmt;
+
+  // TRUE if the byte order on this system is big endian.
+  mutable bool big_chief;
+
+  // No copying!
+
+  oct_mach_info (const oct_mach_info&);
+
+  oct_mach_info& operator = (const oct_mach_info&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/md5.c b/liboctave/md5.c
new file mode 100644
index 0000000..b5890ba
--- /dev/null
+++ b/liboctave/md5.c
@@ -0,0 +1,381 @@
+/*
+  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+ */
+/* $Id: md5.c,v 1.1 2007-03-01 17:23:39 dbateman Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+	either statically or dynamically; added missing #include <string.h>
+	in library.
+  2002-03-11 lpd Corrected argument list for main(), and added int return
+	type, in test program and T value program.
+  2002-02-21 lpd Added missing #include <stdio.h> in test program.
+  2000-07-03 lpd Patched to eliminate warnings about "constant is
+	unsigned in ANSI C, signed in traditional"; made test program
+	self-checking.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+#include "md5.h"
+#include <string.h>
+
+#undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+#  define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3    0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6    0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9    0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13    0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16    0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19    0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22    0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25    0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28    0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31    0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35    0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38    0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41    0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44    0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47    0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50    0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53    0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57    0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60    0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63    0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+    md5_word_t
+	a = pms->abcd[0], b = pms->abcd[1],
+	c = pms->abcd[2], d = pms->abcd[3];
+    md5_word_t t;
+#if BYTE_ORDER > 0
+    /* Define storage only for big-endian CPUs. */
+    md5_word_t X[16];
+#else
+    /* Define storage for little-endian or both types of CPUs. */
+    md5_word_t xbuf[16];
+    const md5_word_t *X;
+#endif
+
+    {
+#if BYTE_ORDER == 0
+	/*
+	 * Determine dynamically whether this is a big-endian or
+	 * little-endian machine, since we can use a more efficient
+	 * algorithm on the latter.
+	 */
+	static const int w = 1;
+
+	if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0		/* little-endian */
+	{
+	    /*
+	     * On little-endian machines, we can process properly aligned
+	     * data without copying it.
+	     */
+	    if (!((data - (const md5_byte_t *)0) & 3)) {
+		/* data are properly aligned */
+		X = (const md5_word_t *)data;
+	    } else {
+		/* not aligned */
+		memcpy(xbuf, data, 64);
+		X = xbuf;
+	    }
+	}
+#endif
+#if BYTE_ORDER == 0
+	else			/* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0		/* big-endian */
+	{
+	    /*
+	     * On big-endian machines, we must arrange the bytes in the
+	     * right order.
+	     */
+	    const md5_byte_t *xp = data;
+	    int i;
+
+#  if BYTE_ORDER == 0
+	    X = xbuf;		/* (dynamic only) */
+#  else
+#    define xbuf X		/* (static only) */
+#  endif
+	    for (i = 0; i < 16; ++i, xp += 4)
+		xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+	}
+#endif
+    }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+    /* Round 1. */
+    /* Let [abcd k s i] denote the operation
+       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + F(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  7,  T1);
+    SET(d, a, b, c,  1, 12,  T2);
+    SET(c, d, a, b,  2, 17,  T3);
+    SET(b, c, d, a,  3, 22,  T4);
+    SET(a, b, c, d,  4,  7,  T5);
+    SET(d, a, b, c,  5, 12,  T6);
+    SET(c, d, a, b,  6, 17,  T7);
+    SET(b, c, d, a,  7, 22,  T8);
+    SET(a, b, c, d,  8,  7,  T9);
+    SET(d, a, b, c,  9, 12, T10);
+    SET(c, d, a, b, 10, 17, T11);
+    SET(b, c, d, a, 11, 22, T12);
+    SET(a, b, c, d, 12,  7, T13);
+    SET(d, a, b, c, 13, 12, T14);
+    SET(c, d, a, b, 14, 17, T15);
+    SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+     /* Round 2. */
+     /* Let [abcd k s i] denote the operation
+          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + G(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  1,  5, T17);
+    SET(d, a, b, c,  6,  9, T18);
+    SET(c, d, a, b, 11, 14, T19);
+    SET(b, c, d, a,  0, 20, T20);
+    SET(a, b, c, d,  5,  5, T21);
+    SET(d, a, b, c, 10,  9, T22);
+    SET(c, d, a, b, 15, 14, T23);
+    SET(b, c, d, a,  4, 20, T24);
+    SET(a, b, c, d,  9,  5, T25);
+    SET(d, a, b, c, 14,  9, T26);
+    SET(c, d, a, b,  3, 14, T27);
+    SET(b, c, d, a,  8, 20, T28);
+    SET(a, b, c, d, 13,  5, T29);
+    SET(d, a, b, c,  2,  9, T30);
+    SET(c, d, a, b,  7, 14, T31);
+    SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+     /* Round 3. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + H(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  5,  4, T33);
+    SET(d, a, b, c,  8, 11, T34);
+    SET(c, d, a, b, 11, 16, T35);
+    SET(b, c, d, a, 14, 23, T36);
+    SET(a, b, c, d,  1,  4, T37);
+    SET(d, a, b, c,  4, 11, T38);
+    SET(c, d, a, b,  7, 16, T39);
+    SET(b, c, d, a, 10, 23, T40);
+    SET(a, b, c, d, 13,  4, T41);
+    SET(d, a, b, c,  0, 11, T42);
+    SET(c, d, a, b,  3, 16, T43);
+    SET(b, c, d, a,  6, 23, T44);
+    SET(a, b, c, d,  9,  4, T45);
+    SET(d, a, b, c, 12, 11, T46);
+    SET(c, d, a, b, 15, 16, T47);
+    SET(b, c, d, a,  2, 23, T48);
+#undef SET
+
+     /* Round 4. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + I(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  6, T49);
+    SET(d, a, b, c,  7, 10, T50);
+    SET(c, d, a, b, 14, 15, T51);
+    SET(b, c, d, a,  5, 21, T52);
+    SET(a, b, c, d, 12,  6, T53);
+    SET(d, a, b, c,  3, 10, T54);
+    SET(c, d, a, b, 10, 15, T55);
+    SET(b, c, d, a,  1, 21, T56);
+    SET(a, b, c, d,  8,  6, T57);
+    SET(d, a, b, c, 15, 10, T58);
+    SET(c, d, a, b,  6, 15, T59);
+    SET(b, c, d, a, 13, 21, T60);
+    SET(a, b, c, d,  4,  6, T61);
+    SET(d, a, b, c, 11, 10, T62);
+    SET(c, d, a, b,  2, 15, T63);
+    SET(b, c, d, a,  9, 21, T64);
+#undef SET
+
+     /* Then perform the following additions. (That is increment each
+        of the four registers by the value it had before this block
+        was started.) */
+    pms->abcd[0] += a;
+    pms->abcd[1] += b;
+    pms->abcd[2] += c;
+    pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+    pms->count[0] = pms->count[1] = 0;
+    pms->abcd[0] = 0x67452301;
+    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+    pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+    const md5_byte_t *p = data;
+    int left = nbytes;
+    int offset = (pms->count[0] >> 3) & 63;
+    md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+    if (nbytes <= 0)
+	return;
+
+    /* Update the message length. */
+    pms->count[1] += nbytes >> 29;
+    pms->count[0] += nbits;
+    if (pms->count[0] < nbits)
+	pms->count[1]++;
+
+    /* Process an initial partial block. */
+    if (offset) {
+	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+	memcpy(pms->buf + offset, p, copy);
+	if (offset + copy < 64)
+	    return;
+	p += copy;
+	left -= copy;
+	md5_process(pms, pms->buf);
+    }
+
+    /* Process full blocks. */
+    for (; left >= 64; p += 64, left -= 64)
+	md5_process(pms, p);
+
+    /* Process a final partial block. */
+    if (left)
+	memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+    static const md5_byte_t pad[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    md5_byte_t data[8];
+    int i;
+
+    /* Save the length before padding. */
+    for (i = 0; i < 8; ++i)
+	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+    /* Pad to 56 bytes mod 64. */
+    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+    /* Append the length. */
+    md5_append(pms, data, 8);
+    for (i = 0; i < 16; ++i)
+	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/liboctave/md5.h b/liboctave/md5.h
new file mode 100644
index 0000000..313dce4
--- /dev/null
+++ b/liboctave/md5.h
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+ */
+/* $Id: md5.h,v 1.1 2007-03-01 17:23:39 dbateman Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+	references to Ghostscript; clarified derivation from RFC 1321;
+	now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <purschke at bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+#  define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+    md5_word_t count[2];	/* message length in bits, lsw first */
+    md5_word_t abcd[4];		/* digest buffer */
+    md5_byte_t buf[64];		/* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/* Initialize the algorithm. */
+void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
diff --git a/liboctave/mk-ops.awk b/liboctave/mk-ops.awk
new file mode 100644
index 0000000..3790cd9
--- /dev/null
+++ b/liboctave/mk-ops.awk
@@ -0,0 +1,273 @@
+# Copyright (C) 2003, 2004, 2006, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+BEGIN {
+  declare_types = 0;
+  generate_ops = 0;
+  ntypes = 0;
+} {
+  if (NR == 1 && make_inclusive_header)
+    {
+      print "// DO NOT EDIT -- generated by mk-ops";
+      tmp = make_inclusive_header;
+      gsub (/[\.-]/, "_", tmp);
+      printf ("#if !defined (octave_%s)\n", tmp);
+      printf ("#define octave_%s 1\n", tmp);
+    }
+}
+/^#/ {
+  if ($2 == "types")
+    declare_types = 1;
+  else if ($2 == "ops")
+    {
+      generate_ops = 1;
+      declare_types = 0;
+    }
+  next;
+} {
+  if (declare_types)
+    {
+      ntypes++;
+
+      if (NF == 6 || NF == 7)
+        {
+	  if (NF == 7)
+	    core_type[ntypes] = $7;
+
+          scalar_zero_val[ntypes] = $6;
+          fwd_decl_ok[ntypes] = $5 == "YES";
+          header[ntypes] = $4 == "NONE" ? "" : $4;
+          class[ntypes] = $3;
+          type[ntypes] = $2;
+          tag[ntypes] = $1;
+          rev_tag[$1] = ntypes;
+        }
+      else
+        printf ("skipping line %d: %s\n", NR, $0); 
+    }
+  else if (generate_ops)
+    {
+      if (NF >= 4)
+        {
+          result_tag = $1;
+          lhs_tag = $2;
+          rhs_tag = $3;
+	  op_type = $4;
+
+	  bin_ops = index (op_type, "B") != 0;
+	  cmp_ops = index (op_type, "C") != 0;
+	  bool_ops = index (op_type, "L") != 0;
+
+          n = 4;
+
+          lhs_conv = cmp_ops ? $(++n) : "";
+          rhs_conv = cmp_ops ? $(++n) : "";
+
+	  if (lhs_conv == "NONE")
+	    lhs_conv = "";
+
+	  if (rhs_conv == "NONE")
+	    rhs_conv = "";
+
+	  k = 0
+	  while (NF > n)
+	    bool_headers[k++] = $(++n);
+
+	  cc_file = sprintf ("%s-%s-%s.cc", prefix, lhs_tag, rhs_tag);
+	  h_file = sprintf ("%s-%s-%s.h", prefix, lhs_tag, rhs_tag);
+
+	  if (list_cc_files)
+	    {
+	      print cc_file;
+	      next;
+	    }
+
+	  if (list_h_files)
+	    {
+	      print h_file;
+	      next;
+	    }
+
+	  if (make_inclusive_header)
+	    {
+              printf ("#include \"%s\"\n", h_file);
+              next;
+            }
+
+	  h_guard = sprintf ("octave_%s_%s_%s_h", prefix, lhs_tag, rhs_tag);
+
+	  result_num = rev_tag[result_tag];
+	  lhs_num = rev_tag[lhs_tag];
+	  rhs_num = rev_tag[rhs_tag];
+
+	  result_type = type[result_num];
+	  lhs_type = type[lhs_num];
+          rhs_type = type[rhs_num];
+
+	  lhs_core_type = core_type[lhs_num];
+	  rhs_core_type = core_type[rhs_num];
+
+	  result_scalar_zero_val = scalar_zero_val[result_num];
+          lhs_scalar_zero_val = scalar_zero_val[lhs_num];
+          rhs_scalar_zero_val = scalar_zero_val[rhs_num];
+
+	  result_header = header[result_num];
+	  lhs_header = header[lhs_num];
+          rhs_header = header[rhs_num];
+
+	  lhs_class = class[lhs_num];
+	  rhs_class = class[rhs_num];
+
+	  print "// DO NOT EDIT -- generated by mk-ops" > h_file;
+
+	  printf ("#if !defined (%s)\n", h_guard) >> h_file;
+	  printf ("#define %s 1\n", h_guard) >> h_file;
+
+          if (result_header)
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", result_type) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", result_header) >> h_file;
+	    }
+
+          if (lhs_header && ! (lhs_header == result_header))
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", lhs_type) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", lhs_header) >> h_file;
+	    }
+
+          if (rhs_header && ! (rhs_header == lhs_header || rhs_header == result_header))
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", rhs_type) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", rhs_header) >> h_file;
+	    }
+
+          printf ("#include \"mx-op-decl.h\"\n") >> h_file;
+
+          if (bin_ops)
+            printf ("%s%s_BIN_OP_DECLS (%s, %s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, result_type, lhs_type, rhs_type) >> h_file
+
+          if (cmp_ops)
+            printf ("%s%s_CMP_OP_DECLS (%s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, lhs_type, rhs_type) >> h_file
+
+          if (bool_ops)
+            printf ("%s%s_BOOL_OP_DECLS (%s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, lhs_type, rhs_type) >> h_file
+
+
+          print "#endif" >> h_file;
+
+	  close (h_file);
+
+
+	  print "// DO NOT EDIT -- generated by mk-ops" > cc_file;
+
+	  print "#ifdef HAVE_CONFIG_H" >> cc_file;
+	  print "#include <config.h>" >> cc_file;
+	  print "#endif" >> cc_file;
+
+	  print "#include \"Array-util.h\"" >> cc_file;
+
+	  printf ("#include \"%s\"\n", h_file) >> cc_file;
+
+          printf ("#include \"mx-op-defs.h\"\n") >> cc_file;
+
+	  for (i in bool_headers)
+	    {
+	      printf ("#include \"%s\"\n", bool_headers[i]) >> cc_file;
+	      delete bool_headers[i];
+	    }
+
+          if (result_header)
+	    printf ("#include \"%s\"\n", result_header) >> cc_file;
+
+          if (lhs_header && ! (lhs_header == result_header))
+	    printf ("#include \"%s\"\n", lhs_header) >> cc_file;
+
+          if (rhs_header && ! (rhs_header == lhs_header || rhs_header == result_header))
+	    printf ("#include \"%s\"\n", rhs_header) >> cc_file;
+
+	  if (bin_ops)
+            {
+              if ((lhs_class == "DM" && rhs_class == "M") || (lhs_class == "M" && rhs_class == "DM"))
+                printf ("%s%s_BIN_OPS (%s, %s, %s, %s)\n",
+		        lhs_class, rhs_class, result_type,
+		        lhs_type, rhs_type, result_scalar_zero_val) >> cc_file
+              else
+                printf ("%s%s_BIN_OPS (%s, %s, %s)\n",
+		        lhs_class, rhs_class, result_type,
+			lhs_type, rhs_type) >> cc_file
+            }
+
+          if (cmp_ops)
+	    {
+	      if (lhs_class == "S" || rhs_class == "S")
+	        {
+		  if (lhs_core_type)
+		    {
+		      if (rhs_core_type)
+			printf ("%s%s_CMP_OPS2 (%s, %s, %s, %s, %s, %s)\n",
+				lhs_class, rhs_class, lhs_type, lhs_conv,
+				rhs_type, rhs_conv,
+				lhs_core_type, rhs_core_type) >> cc_file
+		      else
+			printf ("%s%s_CMP_OPS1 (%s, %s, %s, %s, %s)\n",
+				lhs_class, rhs_class, lhs_type, lhs_conv,
+				rhs_type, rhs_conv, lhs_core_type) >> cc_file
+		    }
+		  else
+		    {
+		      if (rhs_core_type)
+			printf ("%s%s_CMP_OPS1 (%s, %s, %s, %s, %s)\n",
+				lhs_class, rhs_class, lhs_type, lhs_conv,
+				rhs_type, rhs_conv, rhs_core_type) >> cc_file
+		      else
+			printf ("%s%s_CMP_OPS (%s, %s, %s, %s)\n",
+				lhs_class, rhs_class, lhs_type, lhs_conv,
+				rhs_type, rhs_conv) >> cc_file
+		    }
+		}
+	      else
+		printf ("%s%s_CMP_OPS (%s, %s, %s, %s)\n",
+			lhs_class, rhs_class, lhs_type, lhs_conv,
+			rhs_type, rhs_conv) >> cc_file
+	    }
+
+          if (bool_ops)
+            printf ("%s%s_BOOL_OPS2 (%s, %s, %s, %s)\n", lhs_class, rhs_class,
+	            lhs_type, rhs_type, lhs_scalar_zero_val,
+	            rhs_scalar_zero_val) >> cc_file
+
+
+          close (cc_file);
+        }
+      else
+        printf ("skipping line %d: %s\n", NR, $0); 
+    }
+}
+END {
+  if (make_inclusive_header)
+    print "#endif";
+}
diff --git a/liboctave/mkdir.c b/liboctave/mkdir.c
new file mode 100644
index 0000000..0269adc
--- /dev/null
+++ b/liboctave/mkdir.c
@@ -0,0 +1,106 @@
+/* mkdir.c -- BSD compatible make directory function for System V
+   Copyright (C) 1988, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_MKDIR
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISDIR
+#endif
+
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#include "safe-stat.h"
+
+/* mkdir adapted from GNU tar.  */
+
+/* Make directory DPATH, with permission mode DMODE.
+
+   Written by Robert Rother, Mariah Corporation, August 1985
+   (sdcsvax!rmr or rmr at uscd).  If you want it, it's yours.
+
+   Severely hacked over by John Gilmore to make a 4.2BSD compatible
+   subroutine.	11Mar86; hoptoad!gnu
+
+   Modified by rmtodd at uokmax 6-28-87 -- when making an already existing dir,
+   subroutine didn't return EEXIST.  It does now.  */
+
+int
+mkdir (dpath, dmode)
+     char *dpath;
+     int dmode;
+{
+  int cpid, status;
+  struct stat statbuf;
+
+  if (SAFE_STAT (dpath, &statbuf) == 0)
+    {
+      errno = EEXIST;		/* stat worked, so it already exists.  */
+      return -1;
+    }
+
+  /* If stat fails for a reason other than non-existence, return error.  */
+  if (errno != ENOENT)
+    return -1;
+
+  cpid = fork ();
+  switch (cpid)
+    {
+    case -1:			/* Cannot fork.  */
+      return -1;		/* errno is already set.  */
+
+    case 0:			/* Child process.  */
+      /* Cheap hack to set mode of new directory.  Since this child
+	 process is going away anyway, we zap its umask.
+	 This won't suffice to set SUID, SGID, etc. on this
+	 directory, so the parent process calls chmod afterward.  */
+      status = umask (0);	/* Get current umask.  */
+      umask (status | (0777 & ~dmode));	/* Set for mkdir.  */
+      execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
+      _exit (1);
+
+    default:			/* Parent process.  */
+      /* Wait for kid to finish.  */
+      while (wait (&status) != cpid)
+	/* Do nothing.  */ ;
+
+      if (status & 0xFFFF)
+	{
+	  /* /bin/mkdir failed.  */
+	  errno = EIO;
+	  return -1;
+	}
+      return chmod (dpath, dmode);
+    }
+}
+
+#endif
diff --git a/liboctave/mx-base.h b/liboctave/mx-base.h
new file mode 100644
index 0000000..c2e2439
--- /dev/null
+++ b/liboctave/mx-base.h
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mx_base_h)
+#define octave_mx_base_h 1
+
+// Matrix Type class
+
+#include "MatrixType.h"
+
+// Matrix classes.
+
+#include "boolMatrix.h"
+#include "chMatrix.h"
+#include "dMatrix.h"
+#include "CMatrix.h"
+#include "fMatrix.h"
+#include "fCMatrix.h"
+
+// Column Vector classes.
+
+#include "dColVector.h"
+#include "CColVector.h"
+#include "fColVector.h"
+#include "fCColVector.h"
+
+// Row Vector classes.
+
+#include "dRowVector.h"
+#include "CRowVector.h"
+#include "fRowVector.h"
+#include "fCRowVector.h"
+
+// Diagonal Matrix classes.
+
+#include "dDiagMatrix.h"
+#include "CDiagMatrix.h"
+#include "fDiagMatrix.h"
+#include "fCDiagMatrix.h"
+
+// Permutation matrix class
+#include "PermMatrix.h"
+
+// Sparse Matrix classes.
+
+#include "boolSparse.h"
+#include "dSparse.h"
+#include "CSparse.h"
+
+// N-d Array classes.
+
+#include "boolNDArray.h"
+#include "chNDArray.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
+#include "fNDArray.h"
+#include "fCNDArray.h"
+
+#include "int8NDArray.h"
+#include "int16NDArray.h"
+#include "int32NDArray.h"
+#include "int64NDArray.h"
+
+#include "uint8NDArray.h"
+#include "uint16NDArray.h"
+#include "uint32NDArray.h"
+#include "uint64NDArray.h"
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mx-cdm-cm.cc b/liboctave/mx-cdm-cm.cc
new file mode 100644
index 0000000..651a8ed
--- /dev/null
+++ b/liboctave/mx-cdm-cm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cdm-cm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+DMM_BIN_OPS (ComplexMatrix, ComplexDiagMatrix, ComplexMatrix, 0.0)
diff --git a/liboctave/mx-cdm-cm.h b/liboctave/mx-cdm-cm.h
new file mode 100644
index 0000000..6679f8c
--- /dev/null
+++ b/liboctave/mx-cdm-cm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cdm_cm_h)
+#define octave_mx_cdm_cm_h 1
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (ComplexMatrix, ComplexDiagMatrix, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cdm-cs.cc b/liboctave/mx-cdm-cs.cc
new file mode 100644
index 0000000..e3dcca5
--- /dev/null
+++ b/liboctave/mx-cdm-cs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cdm-cs.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "oct-cmplx.h"
+DMS_BIN_OPS (ComplexMatrix, ComplexDiagMatrix, Complex)
diff --git a/liboctave/mx-cdm-cs.h b/liboctave/mx-cdm-cs.h
new file mode 100644
index 0000000..6ef8be5
--- /dev/null
+++ b/liboctave/mx-cdm-cs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cdm_cs_h)
+#define octave_mx_cdm_cs_h 1
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (ComplexMatrix, ComplexDiagMatrix, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cdm-dm.cc b/liboctave/mx-cdm-dm.cc
new file mode 100644
index 0000000..ff184a2
--- /dev/null
+++ b/liboctave/mx-cdm-dm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cdm-dm.h"
+#include "mx-op-defs.h"
+#include "CDiagMatrix.h"
+#include "dDiagMatrix.h"
+DMDM_BIN_OPS (ComplexDiagMatrix, ComplexDiagMatrix, DiagMatrix)
diff --git a/liboctave/mx-cdm-dm.h b/liboctave/mx-cdm-dm.h
new file mode 100644
index 0000000..1a8515a
--- /dev/null
+++ b/liboctave/mx-cdm-dm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cdm_dm_h)
+#define octave_mx_cdm_dm_h 1
+#include "CDiagMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+DMDM_BIN_OP_DECLS (ComplexDiagMatrix, ComplexDiagMatrix, DiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cdm-m.cc b/liboctave/mx-cdm-m.cc
new file mode 100644
index 0000000..0068506
--- /dev/null
+++ b/liboctave/mx-cdm-m.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cdm-m.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "dMatrix.h"
+DMM_BIN_OPS (ComplexMatrix, ComplexDiagMatrix, Matrix, 0.0)
diff --git a/liboctave/mx-cdm-m.h b/liboctave/mx-cdm-m.h
new file mode 100644
index 0000000..6d79497
--- /dev/null
+++ b/liboctave/mx-cdm-m.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cdm_m_h)
+#define octave_mx_cdm_m_h 1
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "dMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (ComplexMatrix, ComplexDiagMatrix, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cdm-s.cc b/liboctave/mx-cdm-s.cc
new file mode 100644
index 0000000..809f6b9
--- /dev/null
+++ b/liboctave/mx-cdm-s.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cdm-s.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+DMS_BIN_OPS (ComplexMatrix, ComplexDiagMatrix, double)
diff --git a/liboctave/mx-cdm-s.h b/liboctave/mx-cdm-s.h
new file mode 100644
index 0000000..c71c38a
--- /dev/null
+++ b/liboctave/mx-cdm-s.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cdm_s_h)
+#define octave_mx_cdm_s_h 1
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (ComplexMatrix, ComplexDiagMatrix, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cm-cdm.cc b/liboctave/mx-cm-cdm.cc
new file mode 100644
index 0000000..d18dcf0
--- /dev/null
+++ b/liboctave/mx-cm-cdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cm-cdm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+MDM_BIN_OPS (ComplexMatrix, ComplexMatrix, ComplexDiagMatrix, 0.0)
diff --git a/liboctave/mx-cm-cdm.h b/liboctave/mx-cm-cdm.h
new file mode 100644
index 0000000..8d3dfd5
--- /dev/null
+++ b/liboctave/mx-cm-cdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cm_cdm_h)
+#define octave_mx_cm_cdm_h 1
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (ComplexMatrix, ComplexMatrix, ComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cm-dm.cc b/liboctave/mx-cm-dm.cc
new file mode 100644
index 0000000..6d8dcae
--- /dev/null
+++ b/liboctave/mx-cm-dm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cm-dm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "dDiagMatrix.h"
+MDM_BIN_OPS (ComplexMatrix, ComplexMatrix, DiagMatrix, 0.0)
diff --git a/liboctave/mx-cm-dm.h b/liboctave/mx-cm-dm.h
new file mode 100644
index 0000000..ccc9fb1
--- /dev/null
+++ b/liboctave/mx-cm-dm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cm_dm_h)
+#define octave_mx_cm_dm_h 1
+#include "CMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (ComplexMatrix, ComplexMatrix, DiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cm-m.cc b/liboctave/mx-cm-m.cc
new file mode 100644
index 0000000..e01e568
--- /dev/null
+++ b/liboctave/mx-cm-m.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cm-m.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "CMatrix.h"
+#include "dMatrix.h"
+MM_BIN_OPS (ComplexMatrix, ComplexMatrix, Matrix)
+MM_CMP_OPS (ComplexMatrix, real, Matrix, )
+MM_BOOL_OPS2 (ComplexMatrix, Matrix, 0.0, 0.0)
diff --git a/liboctave/mx-cm-m.h b/liboctave/mx-cm-m.h
new file mode 100644
index 0000000..99c9c75
--- /dev/null
+++ b/liboctave/mx-cm-m.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cm_m_h)
+#define octave_mx_cm_m_h 1
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "mx-op-decl.h"
+MM_BIN_OP_DECLS (ComplexMatrix, ComplexMatrix, Matrix, OCTAVE_API)
+MM_CMP_OP_DECLS (ComplexMatrix, Matrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (ComplexMatrix, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cm-pm.cc b/liboctave/mx-cm-pm.cc
new file mode 100644
index 0000000..46a89df
--- /dev/null
+++ b/liboctave/mx-cm-pm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cm-pm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "PermMatrix.h"
+MPM_BIN_OPS (ComplexMatrix, ComplexMatrix, PermMatrix)
diff --git a/liboctave/mx-cm-pm.h b/liboctave/mx-cm-pm.h
new file mode 100644
index 0000000..0baf12a
--- /dev/null
+++ b/liboctave/mx-cm-pm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cm_pm_h)
+#define octave_mx_cm_pm_h 1
+#include "CMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+MPM_BIN_OP_DECLS (ComplexMatrix, ComplexMatrix, PermMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cm-s.cc b/liboctave/mx-cm-s.cc
new file mode 100644
index 0000000..6d54bd1
--- /dev/null
+++ b/liboctave/mx-cm-s.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cm-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "CMatrix.h"
+MS_BIN_OPS (ComplexMatrix, ComplexMatrix, double)
+MS_CMP_OPS (ComplexMatrix, real, double, )
+MS_BOOL_OPS2 (ComplexMatrix, double, 0.0, 0.0)
diff --git a/liboctave/mx-cm-s.h b/liboctave/mx-cm-s.h
new file mode 100644
index 0000000..7c859d5
--- /dev/null
+++ b/liboctave/mx-cm-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cm_s_h)
+#define octave_mx_cm_s_h 1
+#include "CMatrix.h"
+#include "mx-op-decl.h"
+MS_BIN_OP_DECLS (ComplexMatrix, ComplexMatrix, double, OCTAVE_API)
+MS_CMP_OP_DECLS (ComplexMatrix, double, OCTAVE_API)
+MS_BOOL_OP_DECLS (ComplexMatrix, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cnda-nda.cc b/liboctave/mx-cnda-nda.cc
new file mode 100644
index 0000000..8dfd6ae
--- /dev/null
+++ b/liboctave/mx-cnda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cnda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (ComplexNDArray, ComplexNDArray, NDArray)
+NDND_CMP_OPS (ComplexNDArray, real, NDArray, )
+NDND_BOOL_OPS2 (ComplexNDArray, NDArray, 0.0, 0.0)
diff --git a/liboctave/mx-cnda-nda.h b/liboctave/mx-cnda-nda.h
new file mode 100644
index 0000000..18f3b07
--- /dev/null
+++ b/liboctave/mx-cnda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cnda_nda_h)
+#define octave_mx_cnda_nda_h 1
+#include "CNDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (ComplexNDArray, ComplexNDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (ComplexNDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (ComplexNDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cnda-s.cc b/liboctave/mx-cnda-s.cc
new file mode 100644
index 0000000..5b1b0a8
--- /dev/null
+++ b/liboctave/mx-cnda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cnda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
+NDS_BIN_OPS (ComplexNDArray, ComplexNDArray, double)
+NDS_CMP_OPS (ComplexNDArray, real, double, )
+NDS_BOOL_OPS2 (ComplexNDArray, double, 0.0, 0.0)
diff --git a/liboctave/mx-cnda-s.h b/liboctave/mx-cnda-s.h
new file mode 100644
index 0000000..de46338
--- /dev/null
+++ b/liboctave/mx-cnda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cnda_s_h)
+#define octave_mx_cnda_s_h 1
+#include "CNDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (ComplexNDArray, ComplexNDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (ComplexNDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (ComplexNDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cs-cdm.cc b/liboctave/mx-cs-cdm.cc
new file mode 100644
index 0000000..6f18fe4
--- /dev/null
+++ b/liboctave/mx-cs-cdm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cs-cdm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "oct-cmplx.h"
+#include "CDiagMatrix.h"
+SDM_BIN_OPS (ComplexMatrix, Complex, ComplexDiagMatrix)
diff --git a/liboctave/mx-cs-cdm.h b/liboctave/mx-cs-cdm.h
new file mode 100644
index 0000000..e67c8e8
--- /dev/null
+++ b/liboctave/mx-cs-cdm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cs_cdm_h)
+#define octave_mx_cs_cdm_h 1
+#include "CMatrix.h"
+#include "oct-cmplx.h"
+#include "CDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (ComplexMatrix, Complex, ComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cs-dm.cc b/liboctave/mx-cs-dm.cc
new file mode 100644
index 0000000..0776777
--- /dev/null
+++ b/liboctave/mx-cs-dm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cs-dm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "oct-cmplx.h"
+#include "dDiagMatrix.h"
+SDM_BIN_OPS (ComplexMatrix, Complex, DiagMatrix)
diff --git a/liboctave/mx-cs-dm.h b/liboctave/mx-cs-dm.h
new file mode 100644
index 0000000..06e7fe8
--- /dev/null
+++ b/liboctave/mx-cs-dm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cs_dm_h)
+#define octave_mx_cs_dm_h 1
+#include "CMatrix.h"
+#include "oct-cmplx.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (ComplexMatrix, Complex, DiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cs-m.cc b/liboctave/mx-cs-m.cc
new file mode 100644
index 0000000..9b89094
--- /dev/null
+++ b/liboctave/mx-cs-m.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cs-m.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "CMatrix.h"
+#include "oct-cmplx.h"
+#include "dMatrix.h"
+SM_BIN_OPS (ComplexMatrix, Complex, Matrix)
+SM_CMP_OPS (Complex, real, Matrix, )
+SM_BOOL_OPS2 (Complex, Matrix, 0.0, 0.0)
diff --git a/liboctave/mx-cs-m.h b/liboctave/mx-cs-m.h
new file mode 100644
index 0000000..2da6ac0
--- /dev/null
+++ b/liboctave/mx-cs-m.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cs_m_h)
+#define octave_mx_cs_m_h 1
+#include "CMatrix.h"
+#include "oct-cmplx.h"
+#include "dMatrix.h"
+#include "mx-op-decl.h"
+SM_BIN_OP_DECLS (ComplexMatrix, Complex, Matrix, OCTAVE_API)
+SM_CMP_OP_DECLS (Complex, Matrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (Complex, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-cs-nda.cc b/liboctave/mx-cs-nda.cc
new file mode 100644
index 0000000..36b5978
--- /dev/null
+++ b/liboctave/mx-cs-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-cs-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
+#include "oct-cmplx.h"
+#include "dNDArray.h"
+SND_BIN_OPS (ComplexNDArray, Complex, NDArray)
+SND_CMP_OPS (Complex, real, NDArray, )
+SND_BOOL_OPS2 (Complex, NDArray, 0.0, 0.0)
diff --git a/liboctave/mx-cs-nda.h b/liboctave/mx-cs-nda.h
new file mode 100644
index 0000000..70d3fe4
--- /dev/null
+++ b/liboctave/mx-cs-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_cs_nda_h)
+#define octave_mx_cs_nda_h 1
+#include "CNDArray.h"
+#include "oct-cmplx.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (ComplexNDArray, Complex, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (Complex, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (Complex, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-defs.h b/liboctave/mx-defs.h
new file mode 100644
index 0000000..29c5c58
--- /dev/null
+++ b/liboctave/mx-defs.h
@@ -0,0 +1,137 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2003, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mx_defs_h)
+#define octave_mx_defs_h 1
+
+// Classes we declare.
+
+class Matrix;
+class ComplexMatrix;
+class FloatMatrix;
+class FloatComplexMatrix;
+class boolMatrix;
+class charMatrix;
+
+class NDArray;
+class ComplexNDArray;
+class FloatNDArray;
+class FloatComplexNDArray;
+class boolNDArray;
+class charNDArray;
+
+class ColumnVector;
+class ComplexColumnVector;
+class FloatColumnVector;
+class FloatComplexColumnVector;
+
+class RowVector;
+class ComplexRowVector;
+class FloatRowVector;
+class FloatComplexRowVector;
+
+class DiagMatrix;
+class ComplexDiagMatrix;
+class FloatDiagMatrix;
+class FloatComplexDiagMatrix;
+
+class PermMatrix;
+
+class AEPBALANCE;
+class ComplexAEPBALANCE;
+class FloatAEPBALANCE;
+class FloatComplexAEPBALANCE;
+
+class GEPBALANCE;
+class ComplexGEPBALANCE;
+class FloatGEPBALANCE;
+class FloatComplexGEPBALANCE;
+
+class CHOL;
+class ComplexCHOL;
+class FloatCHOL;
+class FloatComplexCHOL;
+
+class EIG;
+
+class HESS;
+class ComplexHESS;
+class FloatHESS;
+class FloatComplexHESS;
+
+class SCHUR;
+class ComplexSCHUR;
+class FloatSCHUR;
+class FloatComplexSCHUR;
+
+class SVD;
+class ComplexSVD;
+class FloatSVD;
+class FloatComplexSVD;
+
+class LU;
+class ComplexLU;
+class FloatLU;
+class FloatComplexLU;
+
+class QR;
+class ComplexQR;
+class FloatQR;
+class FloatComplexQR;
+
+class QRP;
+class ComplexQRP;
+class FloatQRP;
+class FloatComplexQRP;
+
+// Other data types we use but that don't always need to have full
+// declarations.
+
+#include "oct-cmplx.h"
+
+#ifndef MAPPER_FCN_TYPEDEFS
+#define MAPPER_FCN_TYPEDEFS 1
+
+typedef bool (*b_d_Mapper)(double);
+typedef bool (*b_c_Mapper)(const Complex&);
+
+typedef double (*d_d_Mapper)(double);
+typedef double (*d_c_Mapper)(const Complex&);
+typedef Complex (*c_c_Mapper)(const Complex&);
+
+typedef bool (*b_f_Mapper)(float);
+typedef bool (*b_fc_Mapper)(const FloatComplex&);
+
+typedef float (*f_f_Mapper)(float);
+typedef float (*f_fc_Mapper)(const FloatComplex&);
+typedef FloatComplex (*fc_fc_Mapper)(const FloatComplex&);
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mx-dm-cdm.cc b/liboctave/mx-dm-cdm.cc
new file mode 100644
index 0000000..8b80139
--- /dev/null
+++ b/liboctave/mx-dm-cdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-dm-cdm.h"
+#include "mx-op-defs.h"
+#include "CDiagMatrix.h"
+#include "dDiagMatrix.h"
+DMDM_BIN_OPS (ComplexDiagMatrix, DiagMatrix, ComplexDiagMatrix)
diff --git a/liboctave/mx-dm-cdm.h b/liboctave/mx-dm-cdm.h
new file mode 100644
index 0000000..7103bd1
--- /dev/null
+++ b/liboctave/mx-dm-cdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_dm_cdm_h)
+#define octave_mx_dm_cdm_h 1
+#include "CDiagMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+DMDM_BIN_OP_DECLS (ComplexDiagMatrix, DiagMatrix, ComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-dm-cm.cc b/liboctave/mx-dm-cm.cc
new file mode 100644
index 0000000..db71dd2
--- /dev/null
+++ b/liboctave/mx-dm-cm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-dm-cm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "dDiagMatrix.h"
+DMM_BIN_OPS (ComplexMatrix, DiagMatrix, ComplexMatrix, 0.0)
diff --git a/liboctave/mx-dm-cm.h b/liboctave/mx-dm-cm.h
new file mode 100644
index 0000000..8e114cd
--- /dev/null
+++ b/liboctave/mx-dm-cm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_dm_cm_h)
+#define octave_mx_dm_cm_h 1
+#include "CMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (ComplexMatrix, DiagMatrix, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-dm-cs.cc b/liboctave/mx-dm-cs.cc
new file mode 100644
index 0000000..56adb99
--- /dev/null
+++ b/liboctave/mx-dm-cs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-dm-cs.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "dDiagMatrix.h"
+#include "oct-cmplx.h"
+DMS_BIN_OPS (ComplexMatrix, DiagMatrix, Complex)
diff --git a/liboctave/mx-dm-cs.h b/liboctave/mx-dm-cs.h
new file mode 100644
index 0000000..141aec0
--- /dev/null
+++ b/liboctave/mx-dm-cs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_dm_cs_h)
+#define octave_mx_dm_cs_h 1
+#include "CMatrix.h"
+#include "dDiagMatrix.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (ComplexMatrix, DiagMatrix, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-dm-m.cc b/liboctave/mx-dm-m.cc
new file mode 100644
index 0000000..2ccef9a
--- /dev/null
+++ b/liboctave/mx-dm-m.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-dm-m.h"
+#include "mx-op-defs.h"
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+DMM_BIN_OPS (Matrix, DiagMatrix, Matrix, 0.0)
diff --git a/liboctave/mx-dm-m.h b/liboctave/mx-dm-m.h
new file mode 100644
index 0000000..174c915
--- /dev/null
+++ b/liboctave/mx-dm-m.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_dm_m_h)
+#define octave_mx_dm_m_h 1
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (Matrix, DiagMatrix, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-dm-s.cc b/liboctave/mx-dm-s.cc
new file mode 100644
index 0000000..a38fe23
--- /dev/null
+++ b/liboctave/mx-dm-s.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-dm-s.h"
+#include "mx-op-defs.h"
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+DMS_BIN_OPS (Matrix, DiagMatrix, double)
diff --git a/liboctave/mx-dm-s.h b/liboctave/mx-dm-s.h
new file mode 100644
index 0000000..f54d57f
--- /dev/null
+++ b/liboctave/mx-dm-s.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_dm_s_h)
+#define octave_mx_dm_s_h 1
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (Matrix, DiagMatrix, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ext.h b/liboctave/mx-ext.h
new file mode 100644
index 0000000..c06839d
--- /dev/null
+++ b/liboctave/mx-ext.h
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2002, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mx_ext_h)
+#define octave_mx_ext_h 1
+
+// Result of a AEP Balance operation.
+
+#include "dbleAEPBAL.h"
+#include "CmplxAEPBAL.h"
+
+// Result of a Determinant calculation.
+
+#include "DET.h"
+
+// Result of a Cholesky Factorization
+
+#include "dbleCHOL.h"
+#include "CmplxCHOL.h"
+#include "floatCHOL.h"
+#include "fCmplxCHOL.h"
+
+// Result of a Hessenberg Decomposition
+
+#include "dbleHESS.h"
+#include "CmplxHESS.h"
+
+// Result of a Schur Decomposition
+
+#include "dbleSCHUR.h"
+#include "CmplxSCHUR.h"
+#include "floatSCHUR.h"
+#include "fCmplxSCHUR.h"
+
+// Result of a Singular Value Decomposition.
+
+#include "dbleSVD.h"
+#include "CmplxSVD.h"
+#include "floatSVD.h"
+#include "fCmplxSVD.h"
+
+// Result of an Eigenvalue computation.
+
+#include "EIG.h"
+
+// Result of an LU decomposition.
+
+#include "dbleLU.h"
+#include "CmplxLU.h"
+#include "floatLU.h"
+#include "fCmplxLU.h"
+
+// Result of a QR decomposition.
+
+#include "dbleQR.h"
+#include "CmplxQR.h"
+
+#include "dbleQRP.h"
+#include "CmplxQRP.h"
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mx-fcdm-fcm.cc b/liboctave/mx-fcdm-fcm.cc
new file mode 100644
index 0000000..ce01634
--- /dev/null
+++ b/liboctave/mx-fcdm-fcm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcdm-fcm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+DMM_BIN_OPS (FloatComplexMatrix, FloatComplexDiagMatrix, FloatComplexMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fcdm-fcm.h b/liboctave/mx-fcdm-fcm.h
new file mode 100644
index 0000000..f423684
--- /dev/null
+++ b/liboctave/mx-fcdm-fcm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcdm_fcm_h)
+#define octave_mx_fcdm_fcm_h 1
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexDiagMatrix, FloatComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcdm-fcs.cc b/liboctave/mx-fcdm-fcs.cc
new file mode 100644
index 0000000..882546c
--- /dev/null
+++ b/liboctave/mx-fcdm-fcs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcdm-fcs.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "oct-cmplx.h"
+DMS_BIN_OPS (FloatComplexMatrix, FloatComplexDiagMatrix, FloatComplex)
diff --git a/liboctave/mx-fcdm-fcs.h b/liboctave/mx-fcdm-fcs.h
new file mode 100644
index 0000000..d0573cd
--- /dev/null
+++ b/liboctave/mx-fcdm-fcs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcdm_fcs_h)
+#define octave_mx_fcdm_fcs_h 1
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexDiagMatrix, FloatComplex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcdm-fdm.cc b/liboctave/mx-fcdm-fdm.cc
new file mode 100644
index 0000000..34396b4
--- /dev/null
+++ b/liboctave/mx-fcdm-fdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcdm-fdm.h"
+#include "mx-op-defs.h"
+#include "fCDiagMatrix.h"
+#include "fDiagMatrix.h"
+DMDM_BIN_OPS (FloatComplexDiagMatrix, FloatComplexDiagMatrix, FloatDiagMatrix)
diff --git a/liboctave/mx-fcdm-fdm.h b/liboctave/mx-fcdm-fdm.h
new file mode 100644
index 0000000..b491aee
--- /dev/null
+++ b/liboctave/mx-fcdm-fdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcdm_fdm_h)
+#define octave_mx_fcdm_fdm_h 1
+#include "fCDiagMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+DMDM_BIN_OP_DECLS (FloatComplexDiagMatrix, FloatComplexDiagMatrix, FloatDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcdm-fm.cc b/liboctave/mx-fcdm-fm.cc
new file mode 100644
index 0000000..c632c8d
--- /dev/null
+++ b/liboctave/mx-fcdm-fm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcdm-fm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "fMatrix.h"
+DMM_BIN_OPS (FloatComplexMatrix, FloatComplexDiagMatrix, FloatMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fcdm-fm.h b/liboctave/mx-fcdm-fm.h
new file mode 100644
index 0000000..0ef7e6d
--- /dev/null
+++ b/liboctave/mx-fcdm-fm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcdm_fm_h)
+#define octave_mx_fcdm_fm_h 1
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "fMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexDiagMatrix, FloatMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcdm-fs.cc b/liboctave/mx-fcdm-fs.cc
new file mode 100644
index 0000000..d2a49eb
--- /dev/null
+++ b/liboctave/mx-fcdm-fs.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcdm-fs.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+DMS_BIN_OPS (FloatComplexMatrix, FloatComplexDiagMatrix, float)
diff --git a/liboctave/mx-fcdm-fs.h b/liboctave/mx-fcdm-fs.h
new file mode 100644
index 0000000..08ae7cb
--- /dev/null
+++ b/liboctave/mx-fcdm-fs.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcdm_fs_h)
+#define octave_mx_fcdm_fs_h 1
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexDiagMatrix, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcm-fcdm.cc b/liboctave/mx-fcm-fcdm.cc
new file mode 100644
index 0000000..323c0ce
--- /dev/null
+++ b/liboctave/mx-fcm-fcdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcm-fcdm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+MDM_BIN_OPS (FloatComplexMatrix, FloatComplexMatrix, FloatComplexDiagMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fcm-fcdm.h b/liboctave/mx-fcm-fcdm.h
new file mode 100644
index 0000000..8aee05a
--- /dev/null
+++ b/liboctave/mx-fcm-fcdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcm_fcdm_h)
+#define octave_mx_fcm_fcdm_h 1
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, FloatComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcm-fdm.cc b/liboctave/mx-fcm-fdm.cc
new file mode 100644
index 0000000..eaf7acb
--- /dev/null
+++ b/liboctave/mx-fcm-fdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcm-fdm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fDiagMatrix.h"
+MDM_BIN_OPS (FloatComplexMatrix, FloatComplexMatrix, FloatDiagMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fcm-fdm.h b/liboctave/mx-fcm-fdm.h
new file mode 100644
index 0000000..33195ec
--- /dev/null
+++ b/liboctave/mx-fcm-fdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcm_fdm_h)
+#define octave_mx_fcm_fdm_h 1
+#include "fCMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, FloatDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcm-fm.cc b/liboctave/mx-fcm-fm.cc
new file mode 100644
index 0000000..527fa0f
--- /dev/null
+++ b/liboctave/mx-fcm-fm.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcm-fm.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "fCMatrix.h"
+#include "fMatrix.h"
+MM_BIN_OPS (FloatComplexMatrix, FloatComplexMatrix, FloatMatrix)
+MM_CMP_OPS (FloatComplexMatrix, real, FloatMatrix, )
+MM_BOOL_OPS2 (FloatComplexMatrix, FloatMatrix, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fcm-fm.h b/liboctave/mx-fcm-fm.h
new file mode 100644
index 0000000..9d23128
--- /dev/null
+++ b/liboctave/mx-fcm-fm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcm_fm_h)
+#define octave_mx_fcm_fm_h 1
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "mx-op-decl.h"
+MM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, FloatMatrix, OCTAVE_API)
+MM_CMP_OP_DECLS (FloatComplexMatrix, FloatMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (FloatComplexMatrix, FloatMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcm-fs.cc b/liboctave/mx-fcm-fs.cc
new file mode 100644
index 0000000..f838ce6
--- /dev/null
+++ b/liboctave/mx-fcm-fs.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcm-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "fCMatrix.h"
+MS_BIN_OPS (FloatComplexMatrix, FloatComplexMatrix, float)
+MS_CMP_OPS (FloatComplexMatrix, real, float, )
+MS_BOOL_OPS2 (FloatComplexMatrix, float, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fcm-fs.h b/liboctave/mx-fcm-fs.h
new file mode 100644
index 0000000..e0b63de
--- /dev/null
+++ b/liboctave/mx-fcm-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcm_fs_h)
+#define octave_mx_fcm_fs_h 1
+#include "fCMatrix.h"
+#include "mx-op-decl.h"
+MS_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, float, OCTAVE_API)
+MS_CMP_OP_DECLS (FloatComplexMatrix, float, OCTAVE_API)
+MS_BOOL_OP_DECLS (FloatComplexMatrix, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcm-pm.cc b/liboctave/mx-fcm-pm.cc
new file mode 100644
index 0000000..1def28a
--- /dev/null
+++ b/liboctave/mx-fcm-pm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcm-pm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "PermMatrix.h"
+MPM_BIN_OPS (FloatComplexMatrix, FloatComplexMatrix, PermMatrix)
diff --git a/liboctave/mx-fcm-pm.h b/liboctave/mx-fcm-pm.h
new file mode 100644
index 0000000..1e48dab
--- /dev/null
+++ b/liboctave/mx-fcm-pm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcm_pm_h)
+#define octave_mx_fcm_pm_h 1
+#include "fCMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+MPM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplexMatrix, PermMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcnda-fnda.cc b/liboctave/mx-fcnda-fnda.cc
new file mode 100644
index 0000000..ac96275
--- /dev/null
+++ b/liboctave/mx-fcnda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcnda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "fCNDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (FloatComplexNDArray, FloatComplexNDArray, FloatNDArray)
+NDND_CMP_OPS (FloatComplexNDArray, real, FloatNDArray, )
+NDND_BOOL_OPS2 (FloatComplexNDArray, FloatNDArray, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fcnda-fnda.h b/liboctave/mx-fcnda-fnda.h
new file mode 100644
index 0000000..7e5695f
--- /dev/null
+++ b/liboctave/mx-fcnda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcnda_fnda_h)
+#define octave_mx_fcnda_fnda_h 1
+#include "fCNDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (FloatComplexNDArray, FloatComplexNDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatComplexNDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatComplexNDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcnda-fs.cc b/liboctave/mx-fcnda-fs.cc
new file mode 100644
index 0000000..2421083
--- /dev/null
+++ b/liboctave/mx-fcnda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcnda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "fCNDArray.h"
+NDS_BIN_OPS (FloatComplexNDArray, FloatComplexNDArray, float)
+NDS_CMP_OPS (FloatComplexNDArray, real, float, )
+NDS_BOOL_OPS2 (FloatComplexNDArray, float, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fcnda-fs.h b/liboctave/mx-fcnda-fs.h
new file mode 100644
index 0000000..0b8372d
--- /dev/null
+++ b/liboctave/mx-fcnda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcnda_fs_h)
+#define octave_mx_fcnda_fs_h 1
+#include "fCNDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (FloatComplexNDArray, FloatComplexNDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatComplexNDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatComplexNDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcs-fcdm.cc b/liboctave/mx-fcs-fcdm.cc
new file mode 100644
index 0000000..60d904f
--- /dev/null
+++ b/liboctave/mx-fcs-fcdm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcs-fcdm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "oct-cmplx.h"
+#include "fCDiagMatrix.h"
+SDM_BIN_OPS (FloatComplexMatrix, FloatComplex, FloatComplexDiagMatrix)
diff --git a/liboctave/mx-fcs-fcdm.h b/liboctave/mx-fcs-fcdm.h
new file mode 100644
index 0000000..da84db0
--- /dev/null
+++ b/liboctave/mx-fcs-fcdm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcs_fcdm_h)
+#define octave_mx_fcs_fcdm_h 1
+#include "fCMatrix.h"
+#include "oct-cmplx.h"
+#include "fCDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplex, FloatComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcs-fdm.cc b/liboctave/mx-fcs-fdm.cc
new file mode 100644
index 0000000..23abcc6
--- /dev/null
+++ b/liboctave/mx-fcs-fdm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcs-fdm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "oct-cmplx.h"
+#include "fDiagMatrix.h"
+SDM_BIN_OPS (FloatComplexMatrix, FloatComplex, FloatDiagMatrix)
diff --git a/liboctave/mx-fcs-fdm.h b/liboctave/mx-fcs-fdm.h
new file mode 100644
index 0000000..6d76bb4
--- /dev/null
+++ b/liboctave/mx-fcs-fdm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcs_fdm_h)
+#define octave_mx_fcs_fdm_h 1
+#include "fCMatrix.h"
+#include "oct-cmplx.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplex, FloatDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcs-fm.cc b/liboctave/mx-fcs-fm.cc
new file mode 100644
index 0000000..1499e5c
--- /dev/null
+++ b/liboctave/mx-fcs-fm.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcs-fm.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "fCMatrix.h"
+#include "oct-cmplx.h"
+#include "fMatrix.h"
+SM_BIN_OPS (FloatComplexMatrix, FloatComplex, FloatMatrix)
+SM_CMP_OPS (FloatComplex, real, FloatMatrix, )
+SM_BOOL_OPS2 (FloatComplex, FloatMatrix, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fcs-fm.h b/liboctave/mx-fcs-fm.h
new file mode 100644
index 0000000..e66542b
--- /dev/null
+++ b/liboctave/mx-fcs-fm.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcs_fm_h)
+#define octave_mx_fcs_fm_h 1
+#include "fCMatrix.h"
+#include "oct-cmplx.h"
+#include "fMatrix.h"
+#include "mx-op-decl.h"
+SM_BIN_OP_DECLS (FloatComplexMatrix, FloatComplex, FloatMatrix, OCTAVE_API)
+SM_CMP_OP_DECLS (FloatComplex, FloatMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (FloatComplex, FloatMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fcs-fnda.cc b/liboctave/mx-fcs-fnda.cc
new file mode 100644
index 0000000..5ffe4cb
--- /dev/null
+++ b/liboctave/mx-fcs-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fcs-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "fCNDArray.h"
+#include "oct-cmplx.h"
+#include "fNDArray.h"
+SND_BIN_OPS (FloatComplexNDArray, FloatComplex, FloatNDArray)
+SND_CMP_OPS (FloatComplex, real, FloatNDArray, )
+SND_BOOL_OPS2 (FloatComplex, FloatNDArray, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fcs-fnda.h b/liboctave/mx-fcs-fnda.h
new file mode 100644
index 0000000..02021a8
--- /dev/null
+++ b/liboctave/mx-fcs-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fcs_fnda_h)
+#define octave_mx_fcs_fnda_h 1
+#include "fCNDArray.h"
+#include "oct-cmplx.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (FloatComplexNDArray, FloatComplex, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (FloatComplex, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (FloatComplex, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fdm-fcdm.cc b/liboctave/mx-fdm-fcdm.cc
new file mode 100644
index 0000000..a8451ca
--- /dev/null
+++ b/liboctave/mx-fdm-fcdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fdm-fcdm.h"
+#include "mx-op-defs.h"
+#include "fCDiagMatrix.h"
+#include "fDiagMatrix.h"
+DMDM_BIN_OPS (FloatComplexDiagMatrix, FloatDiagMatrix, FloatComplexDiagMatrix)
diff --git a/liboctave/mx-fdm-fcdm.h b/liboctave/mx-fdm-fcdm.h
new file mode 100644
index 0000000..5589be3
--- /dev/null
+++ b/liboctave/mx-fdm-fcdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fdm_fcdm_h)
+#define octave_mx_fdm_fcdm_h 1
+#include "fCDiagMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+DMDM_BIN_OP_DECLS (FloatComplexDiagMatrix, FloatDiagMatrix, FloatComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fdm-fcm.cc b/liboctave/mx-fdm-fcm.cc
new file mode 100644
index 0000000..943cb80
--- /dev/null
+++ b/liboctave/mx-fdm-fcm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fdm-fcm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fDiagMatrix.h"
+DMM_BIN_OPS (FloatComplexMatrix, FloatDiagMatrix, FloatComplexMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fdm-fcm.h b/liboctave/mx-fdm-fcm.h
new file mode 100644
index 0000000..48d621b
--- /dev/null
+++ b/liboctave/mx-fdm-fcm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fdm_fcm_h)
+#define octave_mx_fdm_fcm_h 1
+#include "fCMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (FloatComplexMatrix, FloatDiagMatrix, FloatComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fdm-fcs.cc b/liboctave/mx-fdm-fcs.cc
new file mode 100644
index 0000000..b6da939
--- /dev/null
+++ b/liboctave/mx-fdm-fcs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fdm-fcs.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fDiagMatrix.h"
+#include "oct-cmplx.h"
+DMS_BIN_OPS (FloatComplexMatrix, FloatDiagMatrix, FloatComplex)
diff --git a/liboctave/mx-fdm-fcs.h b/liboctave/mx-fdm-fcs.h
new file mode 100644
index 0000000..a0ac960
--- /dev/null
+++ b/liboctave/mx-fdm-fcs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fdm_fcs_h)
+#define octave_mx_fdm_fcs_h 1
+#include "fCMatrix.h"
+#include "fDiagMatrix.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (FloatComplexMatrix, FloatDiagMatrix, FloatComplex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fdm-fm.cc b/liboctave/mx-fdm-fm.cc
new file mode 100644
index 0000000..630e429
--- /dev/null
+++ b/liboctave/mx-fdm-fm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fdm-fm.h"
+#include "mx-op-defs.h"
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+DMM_BIN_OPS (FloatMatrix, FloatDiagMatrix, FloatMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fdm-fm.h b/liboctave/mx-fdm-fm.h
new file mode 100644
index 0000000..26b339c
--- /dev/null
+++ b/liboctave/mx-fdm-fm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fdm_fm_h)
+#define octave_mx_fdm_fm_h 1
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+DMM_BIN_OP_DECLS (FloatMatrix, FloatDiagMatrix, FloatMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fdm-fs.cc b/liboctave/mx-fdm-fs.cc
new file mode 100644
index 0000000..c8227fa
--- /dev/null
+++ b/liboctave/mx-fdm-fs.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fdm-fs.h"
+#include "mx-op-defs.h"
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+DMS_BIN_OPS (FloatMatrix, FloatDiagMatrix, float)
diff --git a/liboctave/mx-fdm-fs.h b/liboctave/mx-fdm-fs.h
new file mode 100644
index 0000000..195b838
--- /dev/null
+++ b/liboctave/mx-fdm-fs.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fdm_fs_h)
+#define octave_mx_fdm_fs_h 1
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+DMS_BIN_OP_DECLS (FloatMatrix, FloatDiagMatrix, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fm-fcdm.cc b/liboctave/mx-fm-fcdm.cc
new file mode 100644
index 0000000..376d00c
--- /dev/null
+++ b/liboctave/mx-fm-fcdm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fm-fcdm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "fCDiagMatrix.h"
+MDM_BIN_OPS (FloatComplexMatrix, FloatMatrix, FloatComplexDiagMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fm-fcdm.h b/liboctave/mx-fm-fcdm.h
new file mode 100644
index 0000000..b00749d
--- /dev/null
+++ b/liboctave/mx-fm-fcdm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fm_fcdm_h)
+#define octave_mx_fm_fcdm_h 1
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "fCDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (FloatComplexMatrix, FloatMatrix, FloatComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fm-fcm.cc b/liboctave/mx-fm-fcm.cc
new file mode 100644
index 0000000..bf71155
--- /dev/null
+++ b/liboctave/mx-fm-fcm.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fm-fcm.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "fCMatrix.h"
+#include "fMatrix.h"
+MM_BIN_OPS (FloatComplexMatrix, FloatMatrix, FloatComplexMatrix)
+MM_CMP_OPS (FloatMatrix, , FloatComplexMatrix, real)
+MM_BOOL_OPS2 (FloatMatrix, FloatComplexMatrix, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fm-fcm.h b/liboctave/mx-fm-fcm.h
new file mode 100644
index 0000000..1d48970
--- /dev/null
+++ b/liboctave/mx-fm-fcm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fm_fcm_h)
+#define octave_mx_fm_fcm_h 1
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "mx-op-decl.h"
+MM_BIN_OP_DECLS (FloatComplexMatrix, FloatMatrix, FloatComplexMatrix, OCTAVE_API)
+MM_CMP_OP_DECLS (FloatMatrix, FloatComplexMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (FloatMatrix, FloatComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fm-fcs.cc b/liboctave/mx-fm-fcs.cc
new file mode 100644
index 0000000..bf09d18
--- /dev/null
+++ b/liboctave/mx-fm-fcs.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fm-fcs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "oct-cmplx.h"
+MS_BIN_OPS (FloatComplexMatrix, FloatMatrix, FloatComplex)
+MS_CMP_OPS (FloatMatrix, , FloatComplex, real)
+MS_BOOL_OPS2 (FloatMatrix, FloatComplex, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fm-fcs.h b/liboctave/mx-fm-fcs.h
new file mode 100644
index 0000000..0ce1a33
--- /dev/null
+++ b/liboctave/mx-fm-fcs.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fm_fcs_h)
+#define octave_mx_fm_fcs_h 1
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+MS_BIN_OP_DECLS (FloatComplexMatrix, FloatMatrix, FloatComplex, OCTAVE_API)
+MS_CMP_OP_DECLS (FloatMatrix, FloatComplex, OCTAVE_API)
+MS_BOOL_OP_DECLS (FloatMatrix, FloatComplex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fm-fdm.cc b/liboctave/mx-fm-fdm.cc
new file mode 100644
index 0000000..6e3dde4
--- /dev/null
+++ b/liboctave/mx-fm-fdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fm-fdm.h"
+#include "mx-op-defs.h"
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+MDM_BIN_OPS (FloatMatrix, FloatMatrix, FloatDiagMatrix, static_cast<float>(0.0))
diff --git a/liboctave/mx-fm-fdm.h b/liboctave/mx-fm-fdm.h
new file mode 100644
index 0000000..bd501c1
--- /dev/null
+++ b/liboctave/mx-fm-fdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fm_fdm_h)
+#define octave_mx_fm_fdm_h 1
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (FloatMatrix, FloatMatrix, FloatDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fm-pm.cc b/liboctave/mx-fm-pm.cc
new file mode 100644
index 0000000..fb36c41
--- /dev/null
+++ b/liboctave/mx-fm-pm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fm-pm.h"
+#include "mx-op-defs.h"
+#include "fMatrix.h"
+#include "PermMatrix.h"
+MPM_BIN_OPS (FloatMatrix, FloatMatrix, PermMatrix)
diff --git a/liboctave/mx-fm-pm.h b/liboctave/mx-fm-pm.h
new file mode 100644
index 0000000..927d37f
--- /dev/null
+++ b/liboctave/mx-fm-pm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fm_pm_h)
+#define octave_mx_fm_pm_h 1
+#include "fMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+MPM_BIN_OP_DECLS (FloatMatrix, FloatMatrix, PermMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-fcnda.cc b/liboctave/mx-fnda-fcnda.cc
new file mode 100644
index 0000000..7c913f1
--- /dev/null
+++ b/liboctave/mx-fnda-fcnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-fcnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "fCNDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (FloatComplexNDArray, FloatNDArray, FloatComplexNDArray)
+NDND_CMP_OPS (FloatNDArray, , FloatComplexNDArray, real)
+NDND_BOOL_OPS2 (FloatNDArray, FloatComplexNDArray, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fnda-fcnda.h b/liboctave/mx-fnda-fcnda.h
new file mode 100644
index 0000000..48b585b
--- /dev/null
+++ b/liboctave/mx-fnda-fcnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_fcnda_h)
+#define octave_mx_fnda_fcnda_h 1
+#include "fCNDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (FloatComplexNDArray, FloatNDArray, FloatComplexNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, FloatComplexNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, FloatComplexNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-fcs.cc b/liboctave/mx-fnda-fcs.cc
new file mode 100644
index 0000000..9796827
--- /dev/null
+++ b/liboctave/mx-fnda-fcs.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-fcs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "fCNDArray.h"
+#include "fNDArray.h"
+#include "oct-cmplx.h"
+NDS_BIN_OPS (FloatComplexNDArray, FloatNDArray, FloatComplex)
+NDS_CMP_OPS (FloatNDArray, , FloatComplex, real)
+NDS_BOOL_OPS2 (FloatNDArray, FloatComplex, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fnda-fcs.h b/liboctave/mx-fnda-fcs.h
new file mode 100644
index 0000000..e661d94
--- /dev/null
+++ b/liboctave/mx-fnda-fcs.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_fcs_h)
+#define octave_mx_fnda_fcs_h 1
+#include "fCNDArray.h"
+#include "fNDArray.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (FloatComplexNDArray, FloatNDArray, FloatComplex, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, FloatComplex, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, FloatComplex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i16.cc b/liboctave/mx-fnda-i16.cc
new file mode 100644
index 0000000..bee23f0
--- /dev/null
+++ b/liboctave/mx-fnda-i16.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int16NDArray, FloatNDArray, octave_int16)
+NDS_CMP_OPS1 (FloatNDArray, , octave_int16, , int16_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_int16, static_cast<float>(0.0), octave_int16::zero)
diff --git a/liboctave/mx-fnda-i16.h b/liboctave/mx-fnda-i16.h
new file mode 100644
index 0000000..fd0edad
--- /dev/null
+++ b/liboctave/mx-fnda-i16.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i16_h)
+#define octave_mx_fnda_i16_h 1
+#include "int16NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int16NDArray, FloatNDArray, octave_int16, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i16nda.cc b/liboctave/mx-fnda-i16nda.cc
new file mode 100644
index 0000000..03c3060
--- /dev/null
+++ b/liboctave/mx-fnda-i16nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int16NDArray, FloatNDArray, int16NDArray)
+NDND_CMP_OPS (FloatNDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, int16NDArray, static_cast<float>(0.0), octave_int16::zero)
diff --git a/liboctave/mx-fnda-i16nda.h b/liboctave/mx-fnda-i16nda.h
new file mode 100644
index 0000000..e7e5c2b
--- /dev/null
+++ b/liboctave/mx-fnda-i16nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i16nda_h)
+#define octave_mx_fnda_i16nda_h 1
+#include "int16NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int16NDArray, FloatNDArray, int16NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i32.cc b/liboctave/mx-fnda-i32.cc
new file mode 100644
index 0000000..adca962
--- /dev/null
+++ b/liboctave/mx-fnda-i32.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int32NDArray, FloatNDArray, octave_int32)
+NDS_CMP_OPS1 (FloatNDArray, , octave_int32, , int32_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_int32, static_cast<float>(0.0), octave_int32::zero)
diff --git a/liboctave/mx-fnda-i32.h b/liboctave/mx-fnda-i32.h
new file mode 100644
index 0000000..c6f6cad
--- /dev/null
+++ b/liboctave/mx-fnda-i32.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i32_h)
+#define octave_mx_fnda_i32_h 1
+#include "int32NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int32NDArray, FloatNDArray, octave_int32, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i32nda.cc b/liboctave/mx-fnda-i32nda.cc
new file mode 100644
index 0000000..809263d
--- /dev/null
+++ b/liboctave/mx-fnda-i32nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int32NDArray, FloatNDArray, int32NDArray)
+NDND_CMP_OPS (FloatNDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, int32NDArray, static_cast<float>(0.0), octave_int32::zero)
diff --git a/liboctave/mx-fnda-i32nda.h b/liboctave/mx-fnda-i32nda.h
new file mode 100644
index 0000000..0e06df0
--- /dev/null
+++ b/liboctave/mx-fnda-i32nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i32nda_h)
+#define octave_mx_fnda_i32nda_h 1
+#include "int32NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int32NDArray, FloatNDArray, int32NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i64.cc b/liboctave/mx-fnda-i64.cc
new file mode 100644
index 0000000..a938105
--- /dev/null
+++ b/liboctave/mx-fnda-i64.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int64NDArray, FloatNDArray, octave_int64)
+NDS_CMP_OPS1 (FloatNDArray, , octave_int64, , int64_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_int64, static_cast<float>(0.0), octave_int64::zero)
diff --git a/liboctave/mx-fnda-i64.h b/liboctave/mx-fnda-i64.h
new file mode 100644
index 0000000..0faac77
--- /dev/null
+++ b/liboctave/mx-fnda-i64.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i64_h)
+#define octave_mx_fnda_i64_h 1
+#include "int64NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int64NDArray, FloatNDArray, octave_int64, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i64nda.cc b/liboctave/mx-fnda-i64nda.cc
new file mode 100644
index 0000000..ecd7718
--- /dev/null
+++ b/liboctave/mx-fnda-i64nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int64NDArray, FloatNDArray, int64NDArray)
+NDND_CMP_OPS (FloatNDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, int64NDArray, static_cast<float>(0.0), octave_int64::zero)
diff --git a/liboctave/mx-fnda-i64nda.h b/liboctave/mx-fnda-i64nda.h
new file mode 100644
index 0000000..7431867
--- /dev/null
+++ b/liboctave/mx-fnda-i64nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i64nda_h)
+#define octave_mx_fnda_i64nda_h 1
+#include "int64NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int64NDArray, FloatNDArray, int64NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i8.cc b/liboctave/mx-fnda-i8.cc
new file mode 100644
index 0000000..24b0b10
--- /dev/null
+++ b/liboctave/mx-fnda-i8.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int8NDArray, FloatNDArray, octave_int8)
+NDS_CMP_OPS1 (FloatNDArray, , octave_int8, , int8_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_int8, static_cast<float>(0.0), octave_int8::zero)
diff --git a/liboctave/mx-fnda-i8.h b/liboctave/mx-fnda-i8.h
new file mode 100644
index 0000000..06da55f
--- /dev/null
+++ b/liboctave/mx-fnda-i8.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i8_h)
+#define octave_mx_fnda_i8_h 1
+#include "int8NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int8NDArray, FloatNDArray, octave_int8, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-i8nda.cc b/liboctave/mx-fnda-i8nda.cc
new file mode 100644
index 0000000..9ea6c73
--- /dev/null
+++ b/liboctave/mx-fnda-i8nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int8NDArray, FloatNDArray, int8NDArray)
+NDND_CMP_OPS (FloatNDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, int8NDArray, static_cast<float>(0.0), octave_int8::zero)
diff --git a/liboctave/mx-fnda-i8nda.h b/liboctave/mx-fnda-i8nda.h
new file mode 100644
index 0000000..41b923e
--- /dev/null
+++ b/liboctave/mx-fnda-i8nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_i8nda_h)
+#define octave_mx_fnda_i8nda_h 1
+#include "int8NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int8NDArray, FloatNDArray, int8NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui16.cc b/liboctave/mx-fnda-ui16.cc
new file mode 100644
index 0000000..4cb543b
--- /dev/null
+++ b/liboctave/mx-fnda-ui16.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint16NDArray, FloatNDArray, octave_uint16)
+NDS_CMP_OPS1 (FloatNDArray, , octave_uint16, , uint16_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_uint16, static_cast<float>(0.0), octave_uint16::zero)
diff --git a/liboctave/mx-fnda-ui16.h b/liboctave/mx-fnda-ui16.h
new file mode 100644
index 0000000..d0c5108
--- /dev/null
+++ b/liboctave/mx-fnda-ui16.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui16_h)
+#define octave_mx_fnda_ui16_h 1
+#include "uint16NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint16NDArray, FloatNDArray, octave_uint16, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui16nda.cc b/liboctave/mx-fnda-ui16nda.cc
new file mode 100644
index 0000000..6c423e9
--- /dev/null
+++ b/liboctave/mx-fnda-ui16nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint16NDArray, FloatNDArray, uint16NDArray)
+NDND_CMP_OPS (FloatNDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, uint16NDArray, static_cast<float>(0.0), octave_uint16::zero)
diff --git a/liboctave/mx-fnda-ui16nda.h b/liboctave/mx-fnda-ui16nda.h
new file mode 100644
index 0000000..ff92fa5
--- /dev/null
+++ b/liboctave/mx-fnda-ui16nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui16nda_h)
+#define octave_mx_fnda_ui16nda_h 1
+#include "uint16NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint16NDArray, FloatNDArray, uint16NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui32.cc b/liboctave/mx-fnda-ui32.cc
new file mode 100644
index 0000000..3724abd
--- /dev/null
+++ b/liboctave/mx-fnda-ui32.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint32NDArray, FloatNDArray, octave_uint32)
+NDS_CMP_OPS1 (FloatNDArray, , octave_uint32, , uint32_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_uint32, static_cast<float>(0.0), octave_uint32::zero)
diff --git a/liboctave/mx-fnda-ui32.h b/liboctave/mx-fnda-ui32.h
new file mode 100644
index 0000000..042873d
--- /dev/null
+++ b/liboctave/mx-fnda-ui32.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui32_h)
+#define octave_mx_fnda_ui32_h 1
+#include "uint32NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint32NDArray, FloatNDArray, octave_uint32, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui32nda.cc b/liboctave/mx-fnda-ui32nda.cc
new file mode 100644
index 0000000..4a0ed40
--- /dev/null
+++ b/liboctave/mx-fnda-ui32nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint32NDArray, FloatNDArray, uint32NDArray)
+NDND_CMP_OPS (FloatNDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, uint32NDArray, static_cast<float>(0.0), octave_uint32::zero)
diff --git a/liboctave/mx-fnda-ui32nda.h b/liboctave/mx-fnda-ui32nda.h
new file mode 100644
index 0000000..f953b3b
--- /dev/null
+++ b/liboctave/mx-fnda-ui32nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui32nda_h)
+#define octave_mx_fnda_ui32nda_h 1
+#include "uint32NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint32NDArray, FloatNDArray, uint32NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui64.cc b/liboctave/mx-fnda-ui64.cc
new file mode 100644
index 0000000..b7290a2
--- /dev/null
+++ b/liboctave/mx-fnda-ui64.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint64NDArray, FloatNDArray, octave_uint64)
+NDS_CMP_OPS1 (FloatNDArray, , octave_uint64, , uint64_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_uint64, static_cast<float>(0.0), octave_uint64::zero)
diff --git a/liboctave/mx-fnda-ui64.h b/liboctave/mx-fnda-ui64.h
new file mode 100644
index 0000000..a7c3d48
--- /dev/null
+++ b/liboctave/mx-fnda-ui64.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui64_h)
+#define octave_mx_fnda_ui64_h 1
+#include "uint64NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint64NDArray, FloatNDArray, octave_uint64, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui64nda.cc b/liboctave/mx-fnda-ui64nda.cc
new file mode 100644
index 0000000..697d88a
--- /dev/null
+++ b/liboctave/mx-fnda-ui64nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint64NDArray, FloatNDArray, uint64NDArray)
+NDND_CMP_OPS (FloatNDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, uint64NDArray, static_cast<float>(0.0), octave_uint64::zero)
diff --git a/liboctave/mx-fnda-ui64nda.h b/liboctave/mx-fnda-ui64nda.h
new file mode 100644
index 0000000..ef00755
--- /dev/null
+++ b/liboctave/mx-fnda-ui64nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui64nda_h)
+#define octave_mx_fnda_ui64nda_h 1
+#include "uint64NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint64NDArray, FloatNDArray, uint64NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui8.cc b/liboctave/mx-fnda-ui8.cc
new file mode 100644
index 0000000..3c496e5
--- /dev/null
+++ b/liboctave/mx-fnda-ui8.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint8NDArray, FloatNDArray, octave_uint8)
+NDS_CMP_OPS1 (FloatNDArray, , octave_uint8, , uint8_t)
+NDS_BOOL_OPS2 (FloatNDArray, octave_uint8, static_cast<float>(0.0), octave_uint8::zero)
diff --git a/liboctave/mx-fnda-ui8.h b/liboctave/mx-fnda-ui8.h
new file mode 100644
index 0000000..85b0b86
--- /dev/null
+++ b/liboctave/mx-fnda-ui8.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui8_h)
+#define octave_mx_fnda_ui8_h 1
+#include "uint8NDArray.h"
+#include "fNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint8NDArray, FloatNDArray, octave_uint8, OCTAVE_API)
+NDS_CMP_OP_DECLS (FloatNDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (FloatNDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fnda-ui8nda.cc b/liboctave/mx-fnda-ui8nda.cc
new file mode 100644
index 0000000..f45f5fe
--- /dev/null
+++ b/liboctave/mx-fnda-ui8nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fnda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint8NDArray, FloatNDArray, uint8NDArray)
+NDND_CMP_OPS (FloatNDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (FloatNDArray, uint8NDArray, static_cast<float>(0.0), octave_uint8::zero)
diff --git a/liboctave/mx-fnda-ui8nda.h b/liboctave/mx-fnda-ui8nda.h
new file mode 100644
index 0000000..82f8290
--- /dev/null
+++ b/liboctave/mx-fnda-ui8nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fnda_ui8nda_h)
+#define octave_mx_fnda_ui8nda_h 1
+#include "uint8NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint8NDArray, FloatNDArray, uint8NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (FloatNDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (FloatNDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-fcdm.cc b/liboctave/mx-fs-fcdm.cc
new file mode 100644
index 0000000..1e9e750
--- /dev/null
+++ b/liboctave/mx-fs-fcdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-fcdm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+SDM_BIN_OPS (FloatComplexMatrix, float, FloatComplexDiagMatrix)
diff --git a/liboctave/mx-fs-fcdm.h b/liboctave/mx-fs-fcdm.h
new file mode 100644
index 0000000..ccda81a
--- /dev/null
+++ b/liboctave/mx-fs-fcdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_fcdm_h)
+#define octave_mx_fs_fcdm_h 1
+#include "fCMatrix.h"
+#include "fCDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (FloatComplexMatrix, float, FloatComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-fcm.cc b/liboctave/mx-fs-fcm.cc
new file mode 100644
index 0000000..b563c0c
--- /dev/null
+++ b/liboctave/mx-fs-fcm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-fcm.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "fCMatrix.h"
+SM_BIN_OPS (FloatComplexMatrix, float, FloatComplexMatrix)
+SM_CMP_OPS (float, , FloatComplexMatrix, real)
+SM_BOOL_OPS2 (float, FloatComplexMatrix, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fs-fcm.h b/liboctave/mx-fs-fcm.h
new file mode 100644
index 0000000..eba779c
--- /dev/null
+++ b/liboctave/mx-fs-fcm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_fcm_h)
+#define octave_mx_fs_fcm_h 1
+#include "fCMatrix.h"
+#include "mx-op-decl.h"
+SM_BIN_OP_DECLS (FloatComplexMatrix, float, FloatComplexMatrix, OCTAVE_API)
+SM_CMP_OP_DECLS (float, FloatComplexMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (float, FloatComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-fcnda.cc b/liboctave/mx-fs-fcnda.cc
new file mode 100644
index 0000000..3aef373
--- /dev/null
+++ b/liboctave/mx-fs-fcnda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-fcnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "fCNDArray.h"
+SND_BIN_OPS (FloatComplexNDArray, float, FloatComplexNDArray)
+SND_CMP_OPS (float, , FloatComplexNDArray, real)
+SND_BOOL_OPS2 (float, FloatComplexNDArray, static_cast<float>(0.0), static_cast<float>(0.0))
diff --git a/liboctave/mx-fs-fcnda.h b/liboctave/mx-fs-fcnda.h
new file mode 100644
index 0000000..e51b7fb
--- /dev/null
+++ b/liboctave/mx-fs-fcnda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_fcnda_h)
+#define octave_mx_fs_fcnda_h 1
+#include "fCNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (FloatComplexNDArray, float, FloatComplexNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, FloatComplexNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, FloatComplexNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-fdm.cc b/liboctave/mx-fs-fdm.cc
new file mode 100644
index 0000000..f0e2717
--- /dev/null
+++ b/liboctave/mx-fs-fdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-fdm.h"
+#include "mx-op-defs.h"
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+SDM_BIN_OPS (FloatMatrix, float, FloatDiagMatrix)
diff --git a/liboctave/mx-fs-fdm.h b/liboctave/mx-fs-fdm.h
new file mode 100644
index 0000000..cb2266d
--- /dev/null
+++ b/liboctave/mx-fs-fdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_fdm_h)
+#define octave_mx_fs_fdm_h 1
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (FloatMatrix, float, FloatDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-i16nda.cc b/liboctave/mx-fs-i16nda.cc
new file mode 100644
index 0000000..451d9fa
--- /dev/null
+++ b/liboctave/mx-fs-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+SND_BIN_OPS (int16NDArray, float, int16NDArray)
+SND_CMP_OPS1 (float, , int16NDArray, , int16_t)
+SND_BOOL_OPS2 (float, int16NDArray, static_cast<float>(0.0), octave_int16::zero)
diff --git a/liboctave/mx-fs-i16nda.h b/liboctave/mx-fs-i16nda.h
new file mode 100644
index 0000000..0337da3
--- /dev/null
+++ b/liboctave/mx-fs-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_i16nda_h)
+#define octave_mx_fs_i16nda_h 1
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int16NDArray, float, int16NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-i32nda.cc b/liboctave/mx-fs-i32nda.cc
new file mode 100644
index 0000000..7b04698
--- /dev/null
+++ b/liboctave/mx-fs-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+SND_BIN_OPS (int32NDArray, float, int32NDArray)
+SND_CMP_OPS1 (float, , int32NDArray, , int32_t)
+SND_BOOL_OPS2 (float, int32NDArray, static_cast<float>(0.0), octave_int32::zero)
diff --git a/liboctave/mx-fs-i32nda.h b/liboctave/mx-fs-i32nda.h
new file mode 100644
index 0000000..4fd5844
--- /dev/null
+++ b/liboctave/mx-fs-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_i32nda_h)
+#define octave_mx_fs_i32nda_h 1
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int32NDArray, float, int32NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-i64nda.cc b/liboctave/mx-fs-i64nda.cc
new file mode 100644
index 0000000..797831e
--- /dev/null
+++ b/liboctave/mx-fs-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+SND_BIN_OPS (int64NDArray, float, int64NDArray)
+SND_CMP_OPS1 (float, , int64NDArray, , int64_t)
+SND_BOOL_OPS2 (float, int64NDArray, static_cast<float>(0.0), octave_int64::zero)
diff --git a/liboctave/mx-fs-i64nda.h b/liboctave/mx-fs-i64nda.h
new file mode 100644
index 0000000..ca0d1a5
--- /dev/null
+++ b/liboctave/mx-fs-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_i64nda_h)
+#define octave_mx_fs_i64nda_h 1
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int64NDArray, float, int64NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-i8nda.cc b/liboctave/mx-fs-i8nda.cc
new file mode 100644
index 0000000..baad1e6
--- /dev/null
+++ b/liboctave/mx-fs-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+SND_BIN_OPS (int8NDArray, float, int8NDArray)
+SND_CMP_OPS1 (float, , int8NDArray, , int8_t)
+SND_BOOL_OPS2 (float, int8NDArray, static_cast<float>(0.0), octave_int8::zero)
diff --git a/liboctave/mx-fs-i8nda.h b/liboctave/mx-fs-i8nda.h
new file mode 100644
index 0000000..94d4802
--- /dev/null
+++ b/liboctave/mx-fs-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_i8nda_h)
+#define octave_mx_fs_i8nda_h 1
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int8NDArray, float, int8NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-ui16nda.cc b/liboctave/mx-fs-ui16nda.cc
new file mode 100644
index 0000000..a49ffb1
--- /dev/null
+++ b/liboctave/mx-fs-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+SND_BIN_OPS (uint16NDArray, float, uint16NDArray)
+SND_CMP_OPS1 (float, , uint16NDArray, , uint16_t)
+SND_BOOL_OPS2 (float, uint16NDArray, static_cast<float>(0.0), octave_uint16::zero)
diff --git a/liboctave/mx-fs-ui16nda.h b/liboctave/mx-fs-ui16nda.h
new file mode 100644
index 0000000..3325429
--- /dev/null
+++ b/liboctave/mx-fs-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_ui16nda_h)
+#define octave_mx_fs_ui16nda_h 1
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint16NDArray, float, uint16NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-ui32nda.cc b/liboctave/mx-fs-ui32nda.cc
new file mode 100644
index 0000000..71cb06b
--- /dev/null
+++ b/liboctave/mx-fs-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+SND_BIN_OPS (uint32NDArray, float, uint32NDArray)
+SND_CMP_OPS1 (float, , uint32NDArray, , uint32_t)
+SND_BOOL_OPS2 (float, uint32NDArray, static_cast<float>(0.0), octave_uint32::zero)
diff --git a/liboctave/mx-fs-ui32nda.h b/liboctave/mx-fs-ui32nda.h
new file mode 100644
index 0000000..2c844ab
--- /dev/null
+++ b/liboctave/mx-fs-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_ui32nda_h)
+#define octave_mx_fs_ui32nda_h 1
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint32NDArray, float, uint32NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-ui64nda.cc b/liboctave/mx-fs-ui64nda.cc
new file mode 100644
index 0000000..978d356
--- /dev/null
+++ b/liboctave/mx-fs-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+SND_BIN_OPS (uint64NDArray, float, uint64NDArray)
+SND_CMP_OPS1 (float, , uint64NDArray, , uint64_t)
+SND_BOOL_OPS2 (float, uint64NDArray, static_cast<float>(0.0), octave_uint64::zero)
diff --git a/liboctave/mx-fs-ui64nda.h b/liboctave/mx-fs-ui64nda.h
new file mode 100644
index 0000000..2178da1
--- /dev/null
+++ b/liboctave/mx-fs-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_ui64nda_h)
+#define octave_mx_fs_ui64nda_h 1
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint64NDArray, float, uint64NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-fs-ui8nda.cc b/liboctave/mx-fs-ui8nda.cc
new file mode 100644
index 0000000..a2360d2
--- /dev/null
+++ b/liboctave/mx-fs-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-fs-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+SND_BIN_OPS (uint8NDArray, float, uint8NDArray)
+SND_CMP_OPS1 (float, , uint8NDArray, , uint8_t)
+SND_BOOL_OPS2 (float, uint8NDArray, static_cast<float>(0.0), octave_uint8::zero)
diff --git a/liboctave/mx-fs-ui8nda.h b/liboctave/mx-fs-ui8nda.h
new file mode 100644
index 0000000..3c1bcdb
--- /dev/null
+++ b/liboctave/mx-fs-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_fs_ui8nda_h)
+#define octave_mx_fs_ui8nda_h 1
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint8NDArray, float, uint8NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (float, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (float, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-fnda.cc b/liboctave/mx-i16-fnda.cc
new file mode 100644
index 0000000..09c3054
--- /dev/null
+++ b/liboctave/mx-i16-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (int16NDArray, octave_int16, FloatNDArray)
+SND_CMP_OPS1 (octave_int16, , FloatNDArray, , int16_t)
+SND_BOOL_OPS2 (octave_int16, FloatNDArray, octave_int16::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i16-fnda.h b/liboctave/mx-i16-fnda.h
new file mode 100644
index 0000000..ef0f862
--- /dev/null
+++ b/liboctave/mx-i16-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_fnda_h)
+#define octave_mx_i16_fnda_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int16NDArray, octave_int16, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int16, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-i32nda.cc b/liboctave/mx-i16-i32nda.cc
new file mode 100644
index 0000000..402496d
--- /dev/null
+++ b/liboctave/mx-i16-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_int16, , int32NDArray, , int16_t, int32_t)
+SND_BOOL_OPS2 (octave_int16, int32NDArray, octave_int16::zero, octave_int32::zero)
diff --git a/liboctave/mx-i16-i32nda.h b/liboctave/mx-i16-i32nda.h
new file mode 100644
index 0000000..be32c0f
--- /dev/null
+++ b/liboctave/mx-i16-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_i32nda_h)
+#define octave_mx_i16_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-i64nda.cc b/liboctave/mx-i16-i64nda.cc
new file mode 100644
index 0000000..2ecc572
--- /dev/null
+++ b/liboctave/mx-i16-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_int16, , int64NDArray, , int16_t, int64_t)
+SND_BOOL_OPS2 (octave_int16, int64NDArray, octave_int16::zero, octave_int64::zero)
diff --git a/liboctave/mx-i16-i64nda.h b/liboctave/mx-i16-i64nda.h
new file mode 100644
index 0000000..920821f
--- /dev/null
+++ b/liboctave/mx-i16-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_i64nda_h)
+#define octave_mx_i16_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-i8nda.cc b/liboctave/mx-i16-i8nda.cc
new file mode 100644
index 0000000..ad9ad81
--- /dev/null
+++ b/liboctave/mx-i16-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_int16, , int8NDArray, , int16_t, int8_t)
+SND_BOOL_OPS2 (octave_int16, int8NDArray, octave_int16::zero, octave_int8::zero)
diff --git a/liboctave/mx-i16-i8nda.h b/liboctave/mx-i16-i8nda.h
new file mode 100644
index 0000000..3ad9241
--- /dev/null
+++ b/liboctave/mx-i16-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_i8nda_h)
+#define octave_mx_i16_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-nda.cc b/liboctave/mx-i16-nda.cc
new file mode 100644
index 0000000..e422bc2
--- /dev/null
+++ b/liboctave/mx-i16-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (int16NDArray, octave_int16, NDArray)
+SND_CMP_OPS1 (octave_int16, , NDArray, , int16_t)
+SND_BOOL_OPS2 (octave_int16, NDArray, octave_int16::zero, 0.0)
diff --git a/liboctave/mx-i16-nda.h b/liboctave/mx-i16-nda.h
new file mode 100644
index 0000000..e3dc93b
--- /dev/null
+++ b/liboctave/mx-i16-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_nda_h)
+#define octave_mx_i16_nda_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int16NDArray, octave_int16, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int16, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-ui16nda.cc b/liboctave/mx-i16-ui16nda.cc
new file mode 100644
index 0000000..336c8fb
--- /dev/null
+++ b/liboctave/mx-i16-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_int16, , uint16NDArray, , int16_t, uint16_t)
+SND_BOOL_OPS2 (octave_int16, uint16NDArray, octave_int16::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i16-ui16nda.h b/liboctave/mx-i16-ui16nda.h
new file mode 100644
index 0000000..cfa1ef4
--- /dev/null
+++ b/liboctave/mx-i16-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_ui16nda_h)
+#define octave_mx_i16_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-ui32nda.cc b/liboctave/mx-i16-ui32nda.cc
new file mode 100644
index 0000000..19d8964
--- /dev/null
+++ b/liboctave/mx-i16-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_int16, , uint32NDArray, , int16_t, uint32_t)
+SND_BOOL_OPS2 (octave_int16, uint32NDArray, octave_int16::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i16-ui32nda.h b/liboctave/mx-i16-ui32nda.h
new file mode 100644
index 0000000..d0036b5
--- /dev/null
+++ b/liboctave/mx-i16-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_ui32nda_h)
+#define octave_mx_i16_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-ui64nda.cc b/liboctave/mx-i16-ui64nda.cc
new file mode 100644
index 0000000..0c199e3
--- /dev/null
+++ b/liboctave/mx-i16-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_int16, , uint64NDArray, , int16_t, uint64_t)
+SND_BOOL_OPS2 (octave_int16, uint64NDArray, octave_int16::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i16-ui64nda.h b/liboctave/mx-i16-ui64nda.h
new file mode 100644
index 0000000..253ed45
--- /dev/null
+++ b/liboctave/mx-i16-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_ui64nda_h)
+#define octave_mx_i16_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16-ui8nda.cc b/liboctave/mx-i16-ui8nda.cc
new file mode 100644
index 0000000..2207fda
--- /dev/null
+++ b/liboctave/mx-i16-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_int16, , uint8NDArray, , int16_t, uint8_t)
+SND_BOOL_OPS2 (octave_int16, uint8NDArray, octave_int16::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i16-ui8nda.h b/liboctave/mx-i16-ui8nda.h
new file mode 100644
index 0000000..5251597
--- /dev/null
+++ b/liboctave/mx-i16-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16_ui8nda_h)
+#define octave_mx_i16_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int16, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int16, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-fnda.cc b/liboctave/mx-i16nda-fnda.cc
new file mode 100644
index 0000000..e055942
--- /dev/null
+++ b/liboctave/mx-i16nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int16NDArray, int16NDArray, FloatNDArray)
+NDND_CMP_OPS (int16NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (int16NDArray, FloatNDArray, octave_int16::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i16nda-fnda.h b/liboctave/mx-i16nda-fnda.h
new file mode 100644
index 0000000..5ecbaa0
--- /dev/null
+++ b/liboctave/mx-i16nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_fnda_h)
+#define octave_mx_i16nda_fnda_h 1
+#include "int16NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int16NDArray, int16NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int16NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-fs.cc b/liboctave/mx-i16nda-fs.cc
new file mode 100644
index 0000000..c364416
--- /dev/null
+++ b/liboctave/mx-i16nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+NDS_BIN_OPS (int16NDArray, int16NDArray, float)
+NDS_CMP_OPS1 (int16NDArray, , float, , int16_t)
+NDS_BOOL_OPS2 (int16NDArray, float, octave_int16::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i16nda-fs.h b/liboctave/mx-i16nda-fs.h
new file mode 100644
index 0000000..0b667e1
--- /dev/null
+++ b/liboctave/mx-i16nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_fs_h)
+#define octave_mx_i16nda_fs_h 1
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int16NDArray, int16NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (int16NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-i32.cc b/liboctave/mx-i16nda-i32.cc
new file mode 100644
index 0000000..0327155
--- /dev/null
+++ b/liboctave/mx-i16nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_int32, , int16_t, int32_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_int32, octave_int16::zero, octave_int32::zero)
diff --git a/liboctave/mx-i16nda-i32.h b/liboctave/mx-i16nda-i32.h
new file mode 100644
index 0000000..5bcd57d
--- /dev/null
+++ b/liboctave/mx-i16nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_i32_h)
+#define octave_mx_i16nda_i32_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-i32nda.cc b/liboctave/mx-i16nda-i32nda.cc
new file mode 100644
index 0000000..0cdff7c
--- /dev/null
+++ b/liboctave/mx-i16nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (int16NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, int32NDArray, octave_int16::zero, octave_int32::zero)
diff --git a/liboctave/mx-i16nda-i32nda.h b/liboctave/mx-i16nda-i32nda.h
new file mode 100644
index 0000000..6683104
--- /dev/null
+++ b/liboctave/mx-i16nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_i32nda_h)
+#define octave_mx_i16nda_i32nda_h 1
+#include "int16NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-i64.cc b/liboctave/mx-i16nda-i64.cc
new file mode 100644
index 0000000..d7b8ff6
--- /dev/null
+++ b/liboctave/mx-i16nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_int64, , int16_t, int64_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_int64, octave_int16::zero, octave_int64::zero)
diff --git a/liboctave/mx-i16nda-i64.h b/liboctave/mx-i16nda-i64.h
new file mode 100644
index 0000000..bc63428
--- /dev/null
+++ b/liboctave/mx-i16nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_i64_h)
+#define octave_mx_i16nda_i64_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-i64nda.cc b/liboctave/mx-i16nda-i64nda.cc
new file mode 100644
index 0000000..6de892b
--- /dev/null
+++ b/liboctave/mx-i16nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (int16NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, int64NDArray, octave_int16::zero, octave_int64::zero)
diff --git a/liboctave/mx-i16nda-i64nda.h b/liboctave/mx-i16nda-i64nda.h
new file mode 100644
index 0000000..1d3211a
--- /dev/null
+++ b/liboctave/mx-i16nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_i64nda_h)
+#define octave_mx_i16nda_i64nda_h 1
+#include "int16NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-i8.cc b/liboctave/mx-i16nda-i8.cc
new file mode 100644
index 0000000..363ac2d
--- /dev/null
+++ b/liboctave/mx-i16nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_int8, , int16_t, int8_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_int8, octave_int16::zero, octave_int8::zero)
diff --git a/liboctave/mx-i16nda-i8.h b/liboctave/mx-i16nda-i8.h
new file mode 100644
index 0000000..23ccea8
--- /dev/null
+++ b/liboctave/mx-i16nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_i8_h)
+#define octave_mx_i16nda_i8_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-i8nda.cc b/liboctave/mx-i16nda-i8nda.cc
new file mode 100644
index 0000000..93bc633
--- /dev/null
+++ b/liboctave/mx-i16nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (int16NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, int8NDArray, octave_int16::zero, octave_int8::zero)
diff --git a/liboctave/mx-i16nda-i8nda.h b/liboctave/mx-i16nda-i8nda.h
new file mode 100644
index 0000000..b3283b2
--- /dev/null
+++ b/liboctave/mx-i16nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_i8nda_h)
+#define octave_mx_i16nda_i8nda_h 1
+#include "int16NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-nda.cc b/liboctave/mx-i16nda-nda.cc
new file mode 100644
index 0000000..1c46b8c
--- /dev/null
+++ b/liboctave/mx-i16nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int16NDArray, int16NDArray, NDArray)
+NDND_CMP_OPS (int16NDArray, , NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, NDArray, octave_int16::zero, 0.0)
diff --git a/liboctave/mx-i16nda-nda.h b/liboctave/mx-i16nda-nda.h
new file mode 100644
index 0000000..666e207
--- /dev/null
+++ b/liboctave/mx-i16nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_nda_h)
+#define octave_mx_i16nda_nda_h 1
+#include "int16NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int16NDArray, int16NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int16NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-s.cc b/liboctave/mx-i16nda-s.cc
new file mode 100644
index 0000000..2a73a3c
--- /dev/null
+++ b/liboctave/mx-i16nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+NDS_BIN_OPS (int16NDArray, int16NDArray, double)
+NDS_CMP_OPS1 (int16NDArray, , double, , int16_t)
+NDS_BOOL_OPS2 (int16NDArray, double, octave_int16::zero, 0.0)
diff --git a/liboctave/mx-i16nda-s.h b/liboctave/mx-i16nda-s.h
new file mode 100644
index 0000000..f19ca4c
--- /dev/null
+++ b/liboctave/mx-i16nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_s_h)
+#define octave_mx_i16nda_s_h 1
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int16NDArray, int16NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (int16NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui16.cc b/liboctave/mx-i16nda-ui16.cc
new file mode 100644
index 0000000..96bb4e2
--- /dev/null
+++ b/liboctave/mx-i16nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_uint16, , int16_t, uint16_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_uint16, octave_int16::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i16nda-ui16.h b/liboctave/mx-i16nda-ui16.h
new file mode 100644
index 0000000..600a1ca
--- /dev/null
+++ b/liboctave/mx-i16nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui16_h)
+#define octave_mx_i16nda_ui16_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui16nda.cc b/liboctave/mx-i16nda-ui16nda.cc
new file mode 100644
index 0000000..9c37a22
--- /dev/null
+++ b/liboctave/mx-i16nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (int16NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, uint16NDArray, octave_int16::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i16nda-ui16nda.h b/liboctave/mx-i16nda-ui16nda.h
new file mode 100644
index 0000000..7277afc
--- /dev/null
+++ b/liboctave/mx-i16nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui16nda_h)
+#define octave_mx_i16nda_ui16nda_h 1
+#include "int16NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui32.cc b/liboctave/mx-i16nda-ui32.cc
new file mode 100644
index 0000000..9724b42
--- /dev/null
+++ b/liboctave/mx-i16nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_uint32, , int16_t, uint32_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_uint32, octave_int16::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i16nda-ui32.h b/liboctave/mx-i16nda-ui32.h
new file mode 100644
index 0000000..378f54c
--- /dev/null
+++ b/liboctave/mx-i16nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui32_h)
+#define octave_mx_i16nda_ui32_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui32nda.cc b/liboctave/mx-i16nda-ui32nda.cc
new file mode 100644
index 0000000..6c99b10
--- /dev/null
+++ b/liboctave/mx-i16nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (int16NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, uint32NDArray, octave_int16::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i16nda-ui32nda.h b/liboctave/mx-i16nda-ui32nda.h
new file mode 100644
index 0000000..ef47128
--- /dev/null
+++ b/liboctave/mx-i16nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui32nda_h)
+#define octave_mx_i16nda_ui32nda_h 1
+#include "int16NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui64.cc b/liboctave/mx-i16nda-ui64.cc
new file mode 100644
index 0000000..4c3df5b
--- /dev/null
+++ b/liboctave/mx-i16nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_uint64, , int16_t, uint64_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_uint64, octave_int16::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i16nda-ui64.h b/liboctave/mx-i16nda-ui64.h
new file mode 100644
index 0000000..6ff705f
--- /dev/null
+++ b/liboctave/mx-i16nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui64_h)
+#define octave_mx_i16nda_ui64_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui64nda.cc b/liboctave/mx-i16nda-ui64nda.cc
new file mode 100644
index 0000000..5a68327
--- /dev/null
+++ b/liboctave/mx-i16nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (int16NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, uint64NDArray, octave_int16::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i16nda-ui64nda.h b/liboctave/mx-i16nda-ui64nda.h
new file mode 100644
index 0000000..a7c3c7d
--- /dev/null
+++ b/liboctave/mx-i16nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui64nda_h)
+#define octave_mx_i16nda_ui64nda_h 1
+#include "int16NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui8.cc b/liboctave/mx-i16nda-ui8.cc
new file mode 100644
index 0000000..67d5e94
--- /dev/null
+++ b/liboctave/mx-i16nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int16NDArray, , octave_uint8, , int16_t, uint8_t)
+NDS_BOOL_OPS2 (int16NDArray, octave_uint8, octave_int16::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i16nda-ui8.h b/liboctave/mx-i16nda-ui8.h
new file mode 100644
index 0000000..fb8df02
--- /dev/null
+++ b/liboctave/mx-i16nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui8_h)
+#define octave_mx_i16nda_ui8_h 1
+#include "int16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int16NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int16NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i16nda-ui8nda.cc b/liboctave/mx-i16nda-ui8nda.cc
new file mode 100644
index 0000000..a6a820c
--- /dev/null
+++ b/liboctave/mx-i16nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i16nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (int16NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (int16NDArray, uint8NDArray, octave_int16::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i16nda-ui8nda.h b/liboctave/mx-i16nda-ui8nda.h
new file mode 100644
index 0000000..a99d804
--- /dev/null
+++ b/liboctave/mx-i16nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i16nda_ui8nda_h)
+#define octave_mx_i16nda_ui8nda_h 1
+#include "int16NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int16NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int16NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-fnda.cc b/liboctave/mx-i32-fnda.cc
new file mode 100644
index 0000000..f98c61c
--- /dev/null
+++ b/liboctave/mx-i32-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (int32NDArray, octave_int32, FloatNDArray)
+SND_CMP_OPS1 (octave_int32, , FloatNDArray, , int32_t)
+SND_BOOL_OPS2 (octave_int32, FloatNDArray, octave_int32::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i32-fnda.h b/liboctave/mx-i32-fnda.h
new file mode 100644
index 0000000..8295aa3
--- /dev/null
+++ b/liboctave/mx-i32-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_fnda_h)
+#define octave_mx_i32_fnda_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int32NDArray, octave_int32, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int32, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-i16nda.cc b/liboctave/mx-i32-i16nda.cc
new file mode 100644
index 0000000..f03b0bf
--- /dev/null
+++ b/liboctave/mx-i32-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_int32, , int16NDArray, , int32_t, int16_t)
+SND_BOOL_OPS2 (octave_int32, int16NDArray, octave_int32::zero, octave_int16::zero)
diff --git a/liboctave/mx-i32-i16nda.h b/liboctave/mx-i32-i16nda.h
new file mode 100644
index 0000000..9ffa787
--- /dev/null
+++ b/liboctave/mx-i32-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_i16nda_h)
+#define octave_mx_i32_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-i64nda.cc b/liboctave/mx-i32-i64nda.cc
new file mode 100644
index 0000000..2694c32
--- /dev/null
+++ b/liboctave/mx-i32-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_int32, , int64NDArray, , int32_t, int64_t)
+SND_BOOL_OPS2 (octave_int32, int64NDArray, octave_int32::zero, octave_int64::zero)
diff --git a/liboctave/mx-i32-i64nda.h b/liboctave/mx-i32-i64nda.h
new file mode 100644
index 0000000..14e3bcc
--- /dev/null
+++ b/liboctave/mx-i32-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_i64nda_h)
+#define octave_mx_i32_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-i8nda.cc b/liboctave/mx-i32-i8nda.cc
new file mode 100644
index 0000000..d66286e
--- /dev/null
+++ b/liboctave/mx-i32-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_int32, , int8NDArray, , int32_t, int8_t)
+SND_BOOL_OPS2 (octave_int32, int8NDArray, octave_int32::zero, octave_int8::zero)
diff --git a/liboctave/mx-i32-i8nda.h b/liboctave/mx-i32-i8nda.h
new file mode 100644
index 0000000..dde5fed
--- /dev/null
+++ b/liboctave/mx-i32-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_i8nda_h)
+#define octave_mx_i32_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-nda.cc b/liboctave/mx-i32-nda.cc
new file mode 100644
index 0000000..53a14a6
--- /dev/null
+++ b/liboctave/mx-i32-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (int32NDArray, octave_int32, NDArray)
+SND_CMP_OPS1 (octave_int32, , NDArray, , int32_t)
+SND_BOOL_OPS2 (octave_int32, NDArray, octave_int32::zero, 0.0)
diff --git a/liboctave/mx-i32-nda.h b/liboctave/mx-i32-nda.h
new file mode 100644
index 0000000..14cd1c0
--- /dev/null
+++ b/liboctave/mx-i32-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_nda_h)
+#define octave_mx_i32_nda_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int32NDArray, octave_int32, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int32, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-ui16nda.cc b/liboctave/mx-i32-ui16nda.cc
new file mode 100644
index 0000000..4ba907d
--- /dev/null
+++ b/liboctave/mx-i32-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_int32, , uint16NDArray, , int32_t, uint16_t)
+SND_BOOL_OPS2 (octave_int32, uint16NDArray, octave_int32::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i32-ui16nda.h b/liboctave/mx-i32-ui16nda.h
new file mode 100644
index 0000000..a22a75a
--- /dev/null
+++ b/liboctave/mx-i32-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_ui16nda_h)
+#define octave_mx_i32_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-ui32nda.cc b/liboctave/mx-i32-ui32nda.cc
new file mode 100644
index 0000000..2db820a
--- /dev/null
+++ b/liboctave/mx-i32-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_int32, , uint32NDArray, , int32_t, uint32_t)
+SND_BOOL_OPS2 (octave_int32, uint32NDArray, octave_int32::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i32-ui32nda.h b/liboctave/mx-i32-ui32nda.h
new file mode 100644
index 0000000..ffc3a97
--- /dev/null
+++ b/liboctave/mx-i32-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_ui32nda_h)
+#define octave_mx_i32_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-ui64nda.cc b/liboctave/mx-i32-ui64nda.cc
new file mode 100644
index 0000000..c8dd105
--- /dev/null
+++ b/liboctave/mx-i32-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_int32, , uint64NDArray, , int32_t, uint64_t)
+SND_BOOL_OPS2 (octave_int32, uint64NDArray, octave_int32::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i32-ui64nda.h b/liboctave/mx-i32-ui64nda.h
new file mode 100644
index 0000000..81470ea
--- /dev/null
+++ b/liboctave/mx-i32-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_ui64nda_h)
+#define octave_mx_i32_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32-ui8nda.cc b/liboctave/mx-i32-ui8nda.cc
new file mode 100644
index 0000000..c5d3c18
--- /dev/null
+++ b/liboctave/mx-i32-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_int32, , uint8NDArray, , int32_t, uint8_t)
+SND_BOOL_OPS2 (octave_int32, uint8NDArray, octave_int32::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i32-ui8nda.h b/liboctave/mx-i32-ui8nda.h
new file mode 100644
index 0000000..d99f262
--- /dev/null
+++ b/liboctave/mx-i32-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32_ui8nda_h)
+#define octave_mx_i32_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int32, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int32, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-fnda.cc b/liboctave/mx-i32nda-fnda.cc
new file mode 100644
index 0000000..31ab495
--- /dev/null
+++ b/liboctave/mx-i32nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int32NDArray, int32NDArray, FloatNDArray)
+NDND_CMP_OPS (int32NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (int32NDArray, FloatNDArray, octave_int32::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i32nda-fnda.h b/liboctave/mx-i32nda-fnda.h
new file mode 100644
index 0000000..0e744df
--- /dev/null
+++ b/liboctave/mx-i32nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_fnda_h)
+#define octave_mx_i32nda_fnda_h 1
+#include "int32NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int32NDArray, int32NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int32NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-fs.cc b/liboctave/mx-i32nda-fs.cc
new file mode 100644
index 0000000..83ca97e
--- /dev/null
+++ b/liboctave/mx-i32nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+NDS_BIN_OPS (int32NDArray, int32NDArray, float)
+NDS_CMP_OPS1 (int32NDArray, , float, , int32_t)
+NDS_BOOL_OPS2 (int32NDArray, float, octave_int32::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i32nda-fs.h b/liboctave/mx-i32nda-fs.h
new file mode 100644
index 0000000..4c13b33
--- /dev/null
+++ b/liboctave/mx-i32nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_fs_h)
+#define octave_mx_i32nda_fs_h 1
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int32NDArray, int32NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (int32NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-i16.cc b/liboctave/mx-i32nda-i16.cc
new file mode 100644
index 0000000..708e883
--- /dev/null
+++ b/liboctave/mx-i32nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_int16, , int32_t, int16_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_int16, octave_int32::zero, octave_int16::zero)
diff --git a/liboctave/mx-i32nda-i16.h b/liboctave/mx-i32nda-i16.h
new file mode 100644
index 0000000..0fdd933
--- /dev/null
+++ b/liboctave/mx-i32nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_i16_h)
+#define octave_mx_i32nda_i16_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-i16nda.cc b/liboctave/mx-i32nda-i16nda.cc
new file mode 100644
index 0000000..835574f
--- /dev/null
+++ b/liboctave/mx-i32nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (int32NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, int16NDArray, octave_int32::zero, octave_int16::zero)
diff --git a/liboctave/mx-i32nda-i16nda.h b/liboctave/mx-i32nda-i16nda.h
new file mode 100644
index 0000000..3494018
--- /dev/null
+++ b/liboctave/mx-i32nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_i16nda_h)
+#define octave_mx_i32nda_i16nda_h 1
+#include "int32NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-i64.cc b/liboctave/mx-i32nda-i64.cc
new file mode 100644
index 0000000..71cbb6d
--- /dev/null
+++ b/liboctave/mx-i32nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_int64, , int32_t, int64_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_int64, octave_int32::zero, octave_int64::zero)
diff --git a/liboctave/mx-i32nda-i64.h b/liboctave/mx-i32nda-i64.h
new file mode 100644
index 0000000..c7d7300
--- /dev/null
+++ b/liboctave/mx-i32nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_i64_h)
+#define octave_mx_i32nda_i64_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-i64nda.cc b/liboctave/mx-i32nda-i64nda.cc
new file mode 100644
index 0000000..4ff77bf
--- /dev/null
+++ b/liboctave/mx-i32nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (int32NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, int64NDArray, octave_int32::zero, octave_int64::zero)
diff --git a/liboctave/mx-i32nda-i64nda.h b/liboctave/mx-i32nda-i64nda.h
new file mode 100644
index 0000000..30f0e14
--- /dev/null
+++ b/liboctave/mx-i32nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_i64nda_h)
+#define octave_mx_i32nda_i64nda_h 1
+#include "int32NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-i8.cc b/liboctave/mx-i32nda-i8.cc
new file mode 100644
index 0000000..af1c76b
--- /dev/null
+++ b/liboctave/mx-i32nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_int8, , int32_t, int8_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_int8, octave_int32::zero, octave_int8::zero)
diff --git a/liboctave/mx-i32nda-i8.h b/liboctave/mx-i32nda-i8.h
new file mode 100644
index 0000000..1157a65
--- /dev/null
+++ b/liboctave/mx-i32nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_i8_h)
+#define octave_mx_i32nda_i8_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-i8nda.cc b/liboctave/mx-i32nda-i8nda.cc
new file mode 100644
index 0000000..b013642
--- /dev/null
+++ b/liboctave/mx-i32nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (int32NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, int8NDArray, octave_int32::zero, octave_int8::zero)
diff --git a/liboctave/mx-i32nda-i8nda.h b/liboctave/mx-i32nda-i8nda.h
new file mode 100644
index 0000000..05b7133
--- /dev/null
+++ b/liboctave/mx-i32nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_i8nda_h)
+#define octave_mx_i32nda_i8nda_h 1
+#include "int32NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-nda.cc b/liboctave/mx-i32nda-nda.cc
new file mode 100644
index 0000000..9a49ac2
--- /dev/null
+++ b/liboctave/mx-i32nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int32NDArray, int32NDArray, NDArray)
+NDND_CMP_OPS (int32NDArray, , NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, NDArray, octave_int32::zero, 0.0)
diff --git a/liboctave/mx-i32nda-nda.h b/liboctave/mx-i32nda-nda.h
new file mode 100644
index 0000000..6c2f652
--- /dev/null
+++ b/liboctave/mx-i32nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_nda_h)
+#define octave_mx_i32nda_nda_h 1
+#include "int32NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int32NDArray, int32NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int32NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-s.cc b/liboctave/mx-i32nda-s.cc
new file mode 100644
index 0000000..4577621
--- /dev/null
+++ b/liboctave/mx-i32nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+NDS_BIN_OPS (int32NDArray, int32NDArray, double)
+NDS_CMP_OPS1 (int32NDArray, , double, , int32_t)
+NDS_BOOL_OPS2 (int32NDArray, double, octave_int32::zero, 0.0)
diff --git a/liboctave/mx-i32nda-s.h b/liboctave/mx-i32nda-s.h
new file mode 100644
index 0000000..1bdfcd5
--- /dev/null
+++ b/liboctave/mx-i32nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_s_h)
+#define octave_mx_i32nda_s_h 1
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int32NDArray, int32NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (int32NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui16.cc b/liboctave/mx-i32nda-ui16.cc
new file mode 100644
index 0000000..fb3067f
--- /dev/null
+++ b/liboctave/mx-i32nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_uint16, , int32_t, uint16_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_uint16, octave_int32::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i32nda-ui16.h b/liboctave/mx-i32nda-ui16.h
new file mode 100644
index 0000000..6ea3331
--- /dev/null
+++ b/liboctave/mx-i32nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui16_h)
+#define octave_mx_i32nda_ui16_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui16nda.cc b/liboctave/mx-i32nda-ui16nda.cc
new file mode 100644
index 0000000..dad0062
--- /dev/null
+++ b/liboctave/mx-i32nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (int32NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, uint16NDArray, octave_int32::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i32nda-ui16nda.h b/liboctave/mx-i32nda-ui16nda.h
new file mode 100644
index 0000000..e5e10fa
--- /dev/null
+++ b/liboctave/mx-i32nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui16nda_h)
+#define octave_mx_i32nda_ui16nda_h 1
+#include "int32NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui32.cc b/liboctave/mx-i32nda-ui32.cc
new file mode 100644
index 0000000..23c3358
--- /dev/null
+++ b/liboctave/mx-i32nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_uint32, , int32_t, uint32_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_uint32, octave_int32::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i32nda-ui32.h b/liboctave/mx-i32nda-ui32.h
new file mode 100644
index 0000000..20ce3b8
--- /dev/null
+++ b/liboctave/mx-i32nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui32_h)
+#define octave_mx_i32nda_ui32_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui32nda.cc b/liboctave/mx-i32nda-ui32nda.cc
new file mode 100644
index 0000000..2de4e3b
--- /dev/null
+++ b/liboctave/mx-i32nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (int32NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, uint32NDArray, octave_int32::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i32nda-ui32nda.h b/liboctave/mx-i32nda-ui32nda.h
new file mode 100644
index 0000000..1ea2e3d
--- /dev/null
+++ b/liboctave/mx-i32nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui32nda_h)
+#define octave_mx_i32nda_ui32nda_h 1
+#include "int32NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui64.cc b/liboctave/mx-i32nda-ui64.cc
new file mode 100644
index 0000000..1eca613
--- /dev/null
+++ b/liboctave/mx-i32nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_uint64, , int32_t, uint64_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_uint64, octave_int32::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i32nda-ui64.h b/liboctave/mx-i32nda-ui64.h
new file mode 100644
index 0000000..783c731
--- /dev/null
+++ b/liboctave/mx-i32nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui64_h)
+#define octave_mx_i32nda_ui64_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui64nda.cc b/liboctave/mx-i32nda-ui64nda.cc
new file mode 100644
index 0000000..2aa2ca5
--- /dev/null
+++ b/liboctave/mx-i32nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (int32NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, uint64NDArray, octave_int32::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i32nda-ui64nda.h b/liboctave/mx-i32nda-ui64nda.h
new file mode 100644
index 0000000..6239f14
--- /dev/null
+++ b/liboctave/mx-i32nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui64nda_h)
+#define octave_mx_i32nda_ui64nda_h 1
+#include "int32NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui8.cc b/liboctave/mx-i32nda-ui8.cc
new file mode 100644
index 0000000..72d9b60
--- /dev/null
+++ b/liboctave/mx-i32nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int32NDArray, , octave_uint8, , int32_t, uint8_t)
+NDS_BOOL_OPS2 (int32NDArray, octave_uint8, octave_int32::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i32nda-ui8.h b/liboctave/mx-i32nda-ui8.h
new file mode 100644
index 0000000..6d997a9
--- /dev/null
+++ b/liboctave/mx-i32nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui8_h)
+#define octave_mx_i32nda_ui8_h 1
+#include "int32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int32NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int32NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i32nda-ui8nda.cc b/liboctave/mx-i32nda-ui8nda.cc
new file mode 100644
index 0000000..2dcba8b
--- /dev/null
+++ b/liboctave/mx-i32nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i32nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (int32NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (int32NDArray, uint8NDArray, octave_int32::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i32nda-ui8nda.h b/liboctave/mx-i32nda-ui8nda.h
new file mode 100644
index 0000000..f89c297
--- /dev/null
+++ b/liboctave/mx-i32nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i32nda_ui8nda_h)
+#define octave_mx_i32nda_ui8nda_h 1
+#include "int32NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int32NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int32NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-fnda.cc b/liboctave/mx-i64-fnda.cc
new file mode 100644
index 0000000..32d2a32
--- /dev/null
+++ b/liboctave/mx-i64-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (int64NDArray, octave_int64, FloatNDArray)
+SND_CMP_OPS1 (octave_int64, , FloatNDArray, , int64_t)
+SND_BOOL_OPS2 (octave_int64, FloatNDArray, octave_int64::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i64-fnda.h b/liboctave/mx-i64-fnda.h
new file mode 100644
index 0000000..fcc9e7c
--- /dev/null
+++ b/liboctave/mx-i64-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_fnda_h)
+#define octave_mx_i64_fnda_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int64NDArray, octave_int64, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int64, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-i16nda.cc b/liboctave/mx-i64-i16nda.cc
new file mode 100644
index 0000000..e3cbd42
--- /dev/null
+++ b/liboctave/mx-i64-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_int64, , int16NDArray, , int64_t, int16_t)
+SND_BOOL_OPS2 (octave_int64, int16NDArray, octave_int64::zero, octave_int16::zero)
diff --git a/liboctave/mx-i64-i16nda.h b/liboctave/mx-i64-i16nda.h
new file mode 100644
index 0000000..cf8e97a
--- /dev/null
+++ b/liboctave/mx-i64-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_i16nda_h)
+#define octave_mx_i64_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-i32nda.cc b/liboctave/mx-i64-i32nda.cc
new file mode 100644
index 0000000..34102c5
--- /dev/null
+++ b/liboctave/mx-i64-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_int64, , int32NDArray, , int64_t, int32_t)
+SND_BOOL_OPS2 (octave_int64, int32NDArray, octave_int64::zero, octave_int32::zero)
diff --git a/liboctave/mx-i64-i32nda.h b/liboctave/mx-i64-i32nda.h
new file mode 100644
index 0000000..634a3ff
--- /dev/null
+++ b/liboctave/mx-i64-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_i32nda_h)
+#define octave_mx_i64_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-i8nda.cc b/liboctave/mx-i64-i8nda.cc
new file mode 100644
index 0000000..65e87dc
--- /dev/null
+++ b/liboctave/mx-i64-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_int64, , int8NDArray, , int64_t, int8_t)
+SND_BOOL_OPS2 (octave_int64, int8NDArray, octave_int64::zero, octave_int8::zero)
diff --git a/liboctave/mx-i64-i8nda.h b/liboctave/mx-i64-i8nda.h
new file mode 100644
index 0000000..d9a3133
--- /dev/null
+++ b/liboctave/mx-i64-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_i8nda_h)
+#define octave_mx_i64_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-nda.cc b/liboctave/mx-i64-nda.cc
new file mode 100644
index 0000000..061a358
--- /dev/null
+++ b/liboctave/mx-i64-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (int64NDArray, octave_int64, NDArray)
+SND_CMP_OPS1 (octave_int64, , NDArray, , int64_t)
+SND_BOOL_OPS2 (octave_int64, NDArray, octave_int64::zero, 0.0)
diff --git a/liboctave/mx-i64-nda.h b/liboctave/mx-i64-nda.h
new file mode 100644
index 0000000..d0f6425
--- /dev/null
+++ b/liboctave/mx-i64-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_nda_h)
+#define octave_mx_i64_nda_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int64NDArray, octave_int64, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int64, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-ui16nda.cc b/liboctave/mx-i64-ui16nda.cc
new file mode 100644
index 0000000..eae73a2
--- /dev/null
+++ b/liboctave/mx-i64-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_int64, , uint16NDArray, , int64_t, uint16_t)
+SND_BOOL_OPS2 (octave_int64, uint16NDArray, octave_int64::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i64-ui16nda.h b/liboctave/mx-i64-ui16nda.h
new file mode 100644
index 0000000..70faaa6
--- /dev/null
+++ b/liboctave/mx-i64-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_ui16nda_h)
+#define octave_mx_i64_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-ui32nda.cc b/liboctave/mx-i64-ui32nda.cc
new file mode 100644
index 0000000..753920e
--- /dev/null
+++ b/liboctave/mx-i64-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_int64, , uint32NDArray, , int64_t, uint32_t)
+SND_BOOL_OPS2 (octave_int64, uint32NDArray, octave_int64::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i64-ui32nda.h b/liboctave/mx-i64-ui32nda.h
new file mode 100644
index 0000000..aa84ae1
--- /dev/null
+++ b/liboctave/mx-i64-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_ui32nda_h)
+#define octave_mx_i64_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-ui64nda.cc b/liboctave/mx-i64-ui64nda.cc
new file mode 100644
index 0000000..9f7a15a
--- /dev/null
+++ b/liboctave/mx-i64-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_int64, , uint64NDArray, , int64_t, uint64_t)
+SND_BOOL_OPS2 (octave_int64, uint64NDArray, octave_int64::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i64-ui64nda.h b/liboctave/mx-i64-ui64nda.h
new file mode 100644
index 0000000..be544c7
--- /dev/null
+++ b/liboctave/mx-i64-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_ui64nda_h)
+#define octave_mx_i64_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64-ui8nda.cc b/liboctave/mx-i64-ui8nda.cc
new file mode 100644
index 0000000..fa7c2b8
--- /dev/null
+++ b/liboctave/mx-i64-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_int64, , uint8NDArray, , int64_t, uint8_t)
+SND_BOOL_OPS2 (octave_int64, uint8NDArray, octave_int64::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i64-ui8nda.h b/liboctave/mx-i64-ui8nda.h
new file mode 100644
index 0000000..e0b649c
--- /dev/null
+++ b/liboctave/mx-i64-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64_ui8nda_h)
+#define octave_mx_i64_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int64, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int64, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-fnda.cc b/liboctave/mx-i64nda-fnda.cc
new file mode 100644
index 0000000..b788dcc
--- /dev/null
+++ b/liboctave/mx-i64nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int64NDArray, int64NDArray, FloatNDArray)
+NDND_CMP_OPS (int64NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (int64NDArray, FloatNDArray, octave_int64::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i64nda-fnda.h b/liboctave/mx-i64nda-fnda.h
new file mode 100644
index 0000000..e84c17b
--- /dev/null
+++ b/liboctave/mx-i64nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_fnda_h)
+#define octave_mx_i64nda_fnda_h 1
+#include "int64NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int64NDArray, int64NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int64NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-fs.cc b/liboctave/mx-i64nda-fs.cc
new file mode 100644
index 0000000..82af683
--- /dev/null
+++ b/liboctave/mx-i64nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+NDS_BIN_OPS (int64NDArray, int64NDArray, float)
+NDS_CMP_OPS1 (int64NDArray, , float, , int64_t)
+NDS_BOOL_OPS2 (int64NDArray, float, octave_int64::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i64nda-fs.h b/liboctave/mx-i64nda-fs.h
new file mode 100644
index 0000000..bd89142
--- /dev/null
+++ b/liboctave/mx-i64nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_fs_h)
+#define octave_mx_i64nda_fs_h 1
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int64NDArray, int64NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (int64NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-i16.cc b/liboctave/mx-i64nda-i16.cc
new file mode 100644
index 0000000..610e588
--- /dev/null
+++ b/liboctave/mx-i64nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_int16, , int64_t, int16_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_int16, octave_int64::zero, octave_int16::zero)
diff --git a/liboctave/mx-i64nda-i16.h b/liboctave/mx-i64nda-i16.h
new file mode 100644
index 0000000..84f5ad4
--- /dev/null
+++ b/liboctave/mx-i64nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_i16_h)
+#define octave_mx_i64nda_i16_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-i16nda.cc b/liboctave/mx-i64nda-i16nda.cc
new file mode 100644
index 0000000..081f3f2
--- /dev/null
+++ b/liboctave/mx-i64nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (int64NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, int16NDArray, octave_int64::zero, octave_int16::zero)
diff --git a/liboctave/mx-i64nda-i16nda.h b/liboctave/mx-i64nda-i16nda.h
new file mode 100644
index 0000000..0ae3260
--- /dev/null
+++ b/liboctave/mx-i64nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_i16nda_h)
+#define octave_mx_i64nda_i16nda_h 1
+#include "int64NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-i32.cc b/liboctave/mx-i64nda-i32.cc
new file mode 100644
index 0000000..af23820
--- /dev/null
+++ b/liboctave/mx-i64nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_int32, , int64_t, int32_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_int32, octave_int64::zero, octave_int32::zero)
diff --git a/liboctave/mx-i64nda-i32.h b/liboctave/mx-i64nda-i32.h
new file mode 100644
index 0000000..1a5a67e
--- /dev/null
+++ b/liboctave/mx-i64nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_i32_h)
+#define octave_mx_i64nda_i32_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-i32nda.cc b/liboctave/mx-i64nda-i32nda.cc
new file mode 100644
index 0000000..a8aa386
--- /dev/null
+++ b/liboctave/mx-i64nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (int64NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, int32NDArray, octave_int64::zero, octave_int32::zero)
diff --git a/liboctave/mx-i64nda-i32nda.h b/liboctave/mx-i64nda-i32nda.h
new file mode 100644
index 0000000..112738e
--- /dev/null
+++ b/liboctave/mx-i64nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_i32nda_h)
+#define octave_mx_i64nda_i32nda_h 1
+#include "int64NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-i8.cc b/liboctave/mx-i64nda-i8.cc
new file mode 100644
index 0000000..8898ba5
--- /dev/null
+++ b/liboctave/mx-i64nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_int8, , int64_t, int8_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_int8, octave_int64::zero, octave_int8::zero)
diff --git a/liboctave/mx-i64nda-i8.h b/liboctave/mx-i64nda-i8.h
new file mode 100644
index 0000000..cc03199
--- /dev/null
+++ b/liboctave/mx-i64nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_i8_h)
+#define octave_mx_i64nda_i8_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-i8nda.cc b/liboctave/mx-i64nda-i8nda.cc
new file mode 100644
index 0000000..a158830
--- /dev/null
+++ b/liboctave/mx-i64nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (int64NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, int8NDArray, octave_int64::zero, octave_int8::zero)
diff --git a/liboctave/mx-i64nda-i8nda.h b/liboctave/mx-i64nda-i8nda.h
new file mode 100644
index 0000000..1014850
--- /dev/null
+++ b/liboctave/mx-i64nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_i8nda_h)
+#define octave_mx_i64nda_i8nda_h 1
+#include "int64NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-nda.cc b/liboctave/mx-i64nda-nda.cc
new file mode 100644
index 0000000..3b3ac8e
--- /dev/null
+++ b/liboctave/mx-i64nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int64NDArray, int64NDArray, NDArray)
+NDND_CMP_OPS (int64NDArray, , NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, NDArray, octave_int64::zero, 0.0)
diff --git a/liboctave/mx-i64nda-nda.h b/liboctave/mx-i64nda-nda.h
new file mode 100644
index 0000000..971a399
--- /dev/null
+++ b/liboctave/mx-i64nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_nda_h)
+#define octave_mx_i64nda_nda_h 1
+#include "int64NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int64NDArray, int64NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int64NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-s.cc b/liboctave/mx-i64nda-s.cc
new file mode 100644
index 0000000..107b2a4
--- /dev/null
+++ b/liboctave/mx-i64nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+NDS_BIN_OPS (int64NDArray, int64NDArray, double)
+NDS_CMP_OPS1 (int64NDArray, , double, , int64_t)
+NDS_BOOL_OPS2 (int64NDArray, double, octave_int64::zero, 0.0)
diff --git a/liboctave/mx-i64nda-s.h b/liboctave/mx-i64nda-s.h
new file mode 100644
index 0000000..a1c0c7e
--- /dev/null
+++ b/liboctave/mx-i64nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_s_h)
+#define octave_mx_i64nda_s_h 1
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int64NDArray, int64NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (int64NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui16.cc b/liboctave/mx-i64nda-ui16.cc
new file mode 100644
index 0000000..acac303
--- /dev/null
+++ b/liboctave/mx-i64nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_uint16, , int64_t, uint16_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_uint16, octave_int64::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i64nda-ui16.h b/liboctave/mx-i64nda-ui16.h
new file mode 100644
index 0000000..11c5e55
--- /dev/null
+++ b/liboctave/mx-i64nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui16_h)
+#define octave_mx_i64nda_ui16_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui16nda.cc b/liboctave/mx-i64nda-ui16nda.cc
new file mode 100644
index 0000000..c1af902
--- /dev/null
+++ b/liboctave/mx-i64nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (int64NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, uint16NDArray, octave_int64::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i64nda-ui16nda.h b/liboctave/mx-i64nda-ui16nda.h
new file mode 100644
index 0000000..116a01c
--- /dev/null
+++ b/liboctave/mx-i64nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui16nda_h)
+#define octave_mx_i64nda_ui16nda_h 1
+#include "int64NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui32.cc b/liboctave/mx-i64nda-ui32.cc
new file mode 100644
index 0000000..0bd3c50
--- /dev/null
+++ b/liboctave/mx-i64nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_uint32, , int64_t, uint32_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_uint32, octave_int64::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i64nda-ui32.h b/liboctave/mx-i64nda-ui32.h
new file mode 100644
index 0000000..e94200a
--- /dev/null
+++ b/liboctave/mx-i64nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui32_h)
+#define octave_mx_i64nda_ui32_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui32nda.cc b/liboctave/mx-i64nda-ui32nda.cc
new file mode 100644
index 0000000..c926992
--- /dev/null
+++ b/liboctave/mx-i64nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (int64NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, uint32NDArray, octave_int64::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i64nda-ui32nda.h b/liboctave/mx-i64nda-ui32nda.h
new file mode 100644
index 0000000..8d8f1eb
--- /dev/null
+++ b/liboctave/mx-i64nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui32nda_h)
+#define octave_mx_i64nda_ui32nda_h 1
+#include "int64NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui64.cc b/liboctave/mx-i64nda-ui64.cc
new file mode 100644
index 0000000..111f630
--- /dev/null
+++ b/liboctave/mx-i64nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_uint64, , int64_t, uint64_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_uint64, octave_int64::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i64nda-ui64.h b/liboctave/mx-i64nda-ui64.h
new file mode 100644
index 0000000..270e94f
--- /dev/null
+++ b/liboctave/mx-i64nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui64_h)
+#define octave_mx_i64nda_ui64_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui64nda.cc b/liboctave/mx-i64nda-ui64nda.cc
new file mode 100644
index 0000000..4847821
--- /dev/null
+++ b/liboctave/mx-i64nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (int64NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, uint64NDArray, octave_int64::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i64nda-ui64nda.h b/liboctave/mx-i64nda-ui64nda.h
new file mode 100644
index 0000000..de3009d
--- /dev/null
+++ b/liboctave/mx-i64nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui64nda_h)
+#define octave_mx_i64nda_ui64nda_h 1
+#include "int64NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui8.cc b/liboctave/mx-i64nda-ui8.cc
new file mode 100644
index 0000000..3d7fdca
--- /dev/null
+++ b/liboctave/mx-i64nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int64NDArray, , octave_uint8, , int64_t, uint8_t)
+NDS_BOOL_OPS2 (int64NDArray, octave_uint8, octave_int64::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i64nda-ui8.h b/liboctave/mx-i64nda-ui8.h
new file mode 100644
index 0000000..8dc7096
--- /dev/null
+++ b/liboctave/mx-i64nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui8_h)
+#define octave_mx_i64nda_ui8_h 1
+#include "int64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int64NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int64NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i64nda-ui8nda.cc b/liboctave/mx-i64nda-ui8nda.cc
new file mode 100644
index 0000000..7d1be2e
--- /dev/null
+++ b/liboctave/mx-i64nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i64nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (int64NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (int64NDArray, uint8NDArray, octave_int64::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i64nda-ui8nda.h b/liboctave/mx-i64nda-ui8nda.h
new file mode 100644
index 0000000..9eda40b
--- /dev/null
+++ b/liboctave/mx-i64nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i64nda_ui8nda_h)
+#define octave_mx_i64nda_ui8nda_h 1
+#include "int64NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int64NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int64NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-fnda.cc b/liboctave/mx-i8-fnda.cc
new file mode 100644
index 0000000..bc36322
--- /dev/null
+++ b/liboctave/mx-i8-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (int8NDArray, octave_int8, FloatNDArray)
+SND_CMP_OPS1 (octave_int8, , FloatNDArray, , int8_t)
+SND_BOOL_OPS2 (octave_int8, FloatNDArray, octave_int8::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i8-fnda.h b/liboctave/mx-i8-fnda.h
new file mode 100644
index 0000000..4747c92
--- /dev/null
+++ b/liboctave/mx-i8-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_fnda_h)
+#define octave_mx_i8_fnda_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int8NDArray, octave_int8, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int8, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-i16nda.cc b/liboctave/mx-i8-i16nda.cc
new file mode 100644
index 0000000..b9f0183
--- /dev/null
+++ b/liboctave/mx-i8-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_int8, , int16NDArray, , int8_t, int16_t)
+SND_BOOL_OPS2 (octave_int8, int16NDArray, octave_int8::zero, octave_int16::zero)
diff --git a/liboctave/mx-i8-i16nda.h b/liboctave/mx-i8-i16nda.h
new file mode 100644
index 0000000..d0969e9
--- /dev/null
+++ b/liboctave/mx-i8-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_i16nda_h)
+#define octave_mx_i8_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-i32nda.cc b/liboctave/mx-i8-i32nda.cc
new file mode 100644
index 0000000..b9baba5
--- /dev/null
+++ b/liboctave/mx-i8-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_int8, , int32NDArray, , int8_t, int32_t)
+SND_BOOL_OPS2 (octave_int8, int32NDArray, octave_int8::zero, octave_int32::zero)
diff --git a/liboctave/mx-i8-i32nda.h b/liboctave/mx-i8-i32nda.h
new file mode 100644
index 0000000..2a47f2d
--- /dev/null
+++ b/liboctave/mx-i8-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_i32nda_h)
+#define octave_mx_i8_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-i64nda.cc b/liboctave/mx-i8-i64nda.cc
new file mode 100644
index 0000000..0d30536
--- /dev/null
+++ b/liboctave/mx-i8-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_int8, , int64NDArray, , int8_t, int64_t)
+SND_BOOL_OPS2 (octave_int8, int64NDArray, octave_int8::zero, octave_int64::zero)
diff --git a/liboctave/mx-i8-i64nda.h b/liboctave/mx-i8-i64nda.h
new file mode 100644
index 0000000..d435546
--- /dev/null
+++ b/liboctave/mx-i8-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_i64nda_h)
+#define octave_mx_i8_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-nda.cc b/liboctave/mx-i8-nda.cc
new file mode 100644
index 0000000..cd16be5
--- /dev/null
+++ b/liboctave/mx-i8-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (int8NDArray, octave_int8, NDArray)
+SND_CMP_OPS1 (octave_int8, , NDArray, , int8_t)
+SND_BOOL_OPS2 (octave_int8, NDArray, octave_int8::zero, 0.0)
diff --git a/liboctave/mx-i8-nda.h b/liboctave/mx-i8-nda.h
new file mode 100644
index 0000000..b9ae828
--- /dev/null
+++ b/liboctave/mx-i8-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_nda_h)
+#define octave_mx_i8_nda_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int8NDArray, octave_int8, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_int8, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-ui16nda.cc b/liboctave/mx-i8-ui16nda.cc
new file mode 100644
index 0000000..1254946
--- /dev/null
+++ b/liboctave/mx-i8-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_int8, , uint16NDArray, , int8_t, uint16_t)
+SND_BOOL_OPS2 (octave_int8, uint16NDArray, octave_int8::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i8-ui16nda.h b/liboctave/mx-i8-ui16nda.h
new file mode 100644
index 0000000..4431e61
--- /dev/null
+++ b/liboctave/mx-i8-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_ui16nda_h)
+#define octave_mx_i8_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-ui32nda.cc b/liboctave/mx-i8-ui32nda.cc
new file mode 100644
index 0000000..0496403
--- /dev/null
+++ b/liboctave/mx-i8-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_int8, , uint32NDArray, , int8_t, uint32_t)
+SND_BOOL_OPS2 (octave_int8, uint32NDArray, octave_int8::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i8-ui32nda.h b/liboctave/mx-i8-ui32nda.h
new file mode 100644
index 0000000..b7a71c7
--- /dev/null
+++ b/liboctave/mx-i8-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_ui32nda_h)
+#define octave_mx_i8_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-ui64nda.cc b/liboctave/mx-i8-ui64nda.cc
new file mode 100644
index 0000000..861d38a
--- /dev/null
+++ b/liboctave/mx-i8-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_int8, , uint64NDArray, , int8_t, uint64_t)
+SND_BOOL_OPS2 (octave_int8, uint64NDArray, octave_int8::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i8-ui64nda.h b/liboctave/mx-i8-ui64nda.h
new file mode 100644
index 0000000..4830f79
--- /dev/null
+++ b/liboctave/mx-i8-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_ui64nda_h)
+#define octave_mx_i8_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8-ui8nda.cc b/liboctave/mx-i8-ui8nda.cc
new file mode 100644
index 0000000..525c7ff
--- /dev/null
+++ b/liboctave/mx-i8-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_int8, , uint8NDArray, , int8_t, uint8_t)
+SND_BOOL_OPS2 (octave_int8, uint8NDArray, octave_int8::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i8-ui8nda.h b/liboctave/mx-i8-ui8nda.h
new file mode 100644
index 0000000..93a86fa
--- /dev/null
+++ b/liboctave/mx-i8-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8_ui8nda_h)
+#define octave_mx_i8_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_int8, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_int8, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-fnda.cc b/liboctave/mx-i8nda-fnda.cc
new file mode 100644
index 0000000..1c32ee0
--- /dev/null
+++ b/liboctave/mx-i8nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (int8NDArray, int8NDArray, FloatNDArray)
+NDND_CMP_OPS (int8NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (int8NDArray, FloatNDArray, octave_int8::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i8nda-fnda.h b/liboctave/mx-i8nda-fnda.h
new file mode 100644
index 0000000..172b711
--- /dev/null
+++ b/liboctave/mx-i8nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_fnda_h)
+#define octave_mx_i8nda_fnda_h 1
+#include "int8NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int8NDArray, int8NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int8NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-fs.cc b/liboctave/mx-i8nda-fs.cc
new file mode 100644
index 0000000..8ae3c96
--- /dev/null
+++ b/liboctave/mx-i8nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+NDS_BIN_OPS (int8NDArray, int8NDArray, float)
+NDS_CMP_OPS1 (int8NDArray, , float, , int8_t)
+NDS_BOOL_OPS2 (int8NDArray, float, octave_int8::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-i8nda-fs.h b/liboctave/mx-i8nda-fs.h
new file mode 100644
index 0000000..9feee97
--- /dev/null
+++ b/liboctave/mx-i8nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_fs_h)
+#define octave_mx_i8nda_fs_h 1
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int8NDArray, int8NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (int8NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-i16.cc b/liboctave/mx-i8nda-i16.cc
new file mode 100644
index 0000000..3a73041
--- /dev/null
+++ b/liboctave/mx-i8nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_int16, , int8_t, int16_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_int16, octave_int8::zero, octave_int16::zero)
diff --git a/liboctave/mx-i8nda-i16.h b/liboctave/mx-i8nda-i16.h
new file mode 100644
index 0000000..3d6f3c5
--- /dev/null
+++ b/liboctave/mx-i8nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_i16_h)
+#define octave_mx_i8nda_i16_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-i16nda.cc b/liboctave/mx-i8nda-i16nda.cc
new file mode 100644
index 0000000..028357c
--- /dev/null
+++ b/liboctave/mx-i8nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (int8NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, int16NDArray, octave_int8::zero, octave_int16::zero)
diff --git a/liboctave/mx-i8nda-i16nda.h b/liboctave/mx-i8nda-i16nda.h
new file mode 100644
index 0000000..a238d6b
--- /dev/null
+++ b/liboctave/mx-i8nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_i16nda_h)
+#define octave_mx_i8nda_i16nda_h 1
+#include "int8NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-i32.cc b/liboctave/mx-i8nda-i32.cc
new file mode 100644
index 0000000..503e078
--- /dev/null
+++ b/liboctave/mx-i8nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_int32, , int8_t, int32_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_int32, octave_int8::zero, octave_int32::zero)
diff --git a/liboctave/mx-i8nda-i32.h b/liboctave/mx-i8nda-i32.h
new file mode 100644
index 0000000..d48184e
--- /dev/null
+++ b/liboctave/mx-i8nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_i32_h)
+#define octave_mx_i8nda_i32_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-i32nda.cc b/liboctave/mx-i8nda-i32nda.cc
new file mode 100644
index 0000000..b4f1edd
--- /dev/null
+++ b/liboctave/mx-i8nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (int8NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, int32NDArray, octave_int8::zero, octave_int32::zero)
diff --git a/liboctave/mx-i8nda-i32nda.h b/liboctave/mx-i8nda-i32nda.h
new file mode 100644
index 0000000..5bc7885
--- /dev/null
+++ b/liboctave/mx-i8nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_i32nda_h)
+#define octave_mx_i8nda_i32nda_h 1
+#include "int8NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-i64.cc b/liboctave/mx-i8nda-i64.cc
new file mode 100644
index 0000000..a43bb8d
--- /dev/null
+++ b/liboctave/mx-i8nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_int64, , int8_t, int64_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_int64, octave_int8::zero, octave_int64::zero)
diff --git a/liboctave/mx-i8nda-i64.h b/liboctave/mx-i8nda-i64.h
new file mode 100644
index 0000000..83e910f
--- /dev/null
+++ b/liboctave/mx-i8nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_i64_h)
+#define octave_mx_i8nda_i64_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-i64nda.cc b/liboctave/mx-i8nda-i64nda.cc
new file mode 100644
index 0000000..4936a49
--- /dev/null
+++ b/liboctave/mx-i8nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (int8NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, int64NDArray, octave_int8::zero, octave_int64::zero)
diff --git a/liboctave/mx-i8nda-i64nda.h b/liboctave/mx-i8nda-i64nda.h
new file mode 100644
index 0000000..e7272ee
--- /dev/null
+++ b/liboctave/mx-i8nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_i64nda_h)
+#define octave_mx_i8nda_i64nda_h 1
+#include "int8NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-nda.cc b/liboctave/mx-i8nda-nda.cc
new file mode 100644
index 0000000..43605a7
--- /dev/null
+++ b/liboctave/mx-i8nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int8NDArray, int8NDArray, NDArray)
+NDND_CMP_OPS (int8NDArray, , NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, NDArray, octave_int8::zero, 0.0)
diff --git a/liboctave/mx-i8nda-nda.h b/liboctave/mx-i8nda-nda.h
new file mode 100644
index 0000000..893048b
--- /dev/null
+++ b/liboctave/mx-i8nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_nda_h)
+#define octave_mx_i8nda_nda_h 1
+#include "int8NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int8NDArray, int8NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (int8NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-s.cc b/liboctave/mx-i8nda-s.cc
new file mode 100644
index 0000000..06897a1
--- /dev/null
+++ b/liboctave/mx-i8nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+NDS_BIN_OPS (int8NDArray, int8NDArray, double)
+NDS_CMP_OPS1 (int8NDArray, , double, , int8_t)
+NDS_BOOL_OPS2 (int8NDArray, double, octave_int8::zero, 0.0)
diff --git a/liboctave/mx-i8nda-s.h b/liboctave/mx-i8nda-s.h
new file mode 100644
index 0000000..dc7cdff
--- /dev/null
+++ b/liboctave/mx-i8nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_s_h)
+#define octave_mx_i8nda_s_h 1
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int8NDArray, int8NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (int8NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui16.cc b/liboctave/mx-i8nda-ui16.cc
new file mode 100644
index 0000000..a03f6c6
--- /dev/null
+++ b/liboctave/mx-i8nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_uint16, , int8_t, uint16_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_uint16, octave_int8::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i8nda-ui16.h b/liboctave/mx-i8nda-ui16.h
new file mode 100644
index 0000000..9c59521
--- /dev/null
+++ b/liboctave/mx-i8nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui16_h)
+#define octave_mx_i8nda_ui16_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui16nda.cc b/liboctave/mx-i8nda-ui16nda.cc
new file mode 100644
index 0000000..ced99f3
--- /dev/null
+++ b/liboctave/mx-i8nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (int8NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, uint16NDArray, octave_int8::zero, octave_uint16::zero)
diff --git a/liboctave/mx-i8nda-ui16nda.h b/liboctave/mx-i8nda-ui16nda.h
new file mode 100644
index 0000000..119b14a
--- /dev/null
+++ b/liboctave/mx-i8nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui16nda_h)
+#define octave_mx_i8nda_ui16nda_h 1
+#include "int8NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui32.cc b/liboctave/mx-i8nda-ui32.cc
new file mode 100644
index 0000000..cd53212
--- /dev/null
+++ b/liboctave/mx-i8nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_uint32, , int8_t, uint32_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_uint32, octave_int8::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i8nda-ui32.h b/liboctave/mx-i8nda-ui32.h
new file mode 100644
index 0000000..d09d6f7
--- /dev/null
+++ b/liboctave/mx-i8nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui32_h)
+#define octave_mx_i8nda_ui32_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui32nda.cc b/liboctave/mx-i8nda-ui32nda.cc
new file mode 100644
index 0000000..a55d5d2
--- /dev/null
+++ b/liboctave/mx-i8nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (int8NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, uint32NDArray, octave_int8::zero, octave_uint32::zero)
diff --git a/liboctave/mx-i8nda-ui32nda.h b/liboctave/mx-i8nda-ui32nda.h
new file mode 100644
index 0000000..165c480
--- /dev/null
+++ b/liboctave/mx-i8nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui32nda_h)
+#define octave_mx_i8nda_ui32nda_h 1
+#include "int8NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui64.cc b/liboctave/mx-i8nda-ui64.cc
new file mode 100644
index 0000000..d32f459
--- /dev/null
+++ b/liboctave/mx-i8nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_uint64, , int8_t, uint64_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_uint64, octave_int8::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i8nda-ui64.h b/liboctave/mx-i8nda-ui64.h
new file mode 100644
index 0000000..5d19901
--- /dev/null
+++ b/liboctave/mx-i8nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui64_h)
+#define octave_mx_i8nda_ui64_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui64nda.cc b/liboctave/mx-i8nda-ui64nda.cc
new file mode 100644
index 0000000..cc130fa
--- /dev/null
+++ b/liboctave/mx-i8nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (int8NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, uint64NDArray, octave_int8::zero, octave_uint64::zero)
diff --git a/liboctave/mx-i8nda-ui64nda.h b/liboctave/mx-i8nda-ui64nda.h
new file mode 100644
index 0000000..1a4c525
--- /dev/null
+++ b/liboctave/mx-i8nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui64nda_h)
+#define octave_mx_i8nda_ui64nda_h 1
+#include "int8NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui8.cc b/liboctave/mx-i8nda-ui8.cc
new file mode 100644
index 0000000..572063b
--- /dev/null
+++ b/liboctave/mx-i8nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (int8NDArray, , octave_uint8, , int8_t, uint8_t)
+NDS_BOOL_OPS2 (int8NDArray, octave_uint8, octave_int8::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i8nda-ui8.h b/liboctave/mx-i8nda-ui8.h
new file mode 100644
index 0000000..94719bc
--- /dev/null
+++ b/liboctave/mx-i8nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui8_h)
+#define octave_mx_i8nda_ui8_h 1
+#include "int8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (int8NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (int8NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-i8nda-ui8nda.cc b/liboctave/mx-i8nda-ui8nda.cc
new file mode 100644
index 0000000..2d6669a
--- /dev/null
+++ b/liboctave/mx-i8nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-i8nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (int8NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (int8NDArray, uint8NDArray, octave_int8::zero, octave_uint8::zero)
diff --git a/liboctave/mx-i8nda-ui8nda.h b/liboctave/mx-i8nda-ui8nda.h
new file mode 100644
index 0000000..7de5f69
--- /dev/null
+++ b/liboctave/mx-i8nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_i8nda_ui8nda_h)
+#define octave_mx_i8nda_ui8nda_h 1
+#include "int8NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (int8NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (int8NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-inlines.cc b/liboctave/mx-inlines.cc
new file mode 100644
index 0000000..2141e4a
--- /dev/null
+++ b/liboctave/mx-inlines.cc
@@ -0,0 +1,1012 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+Copyright (C) 2009 Jaroslav Hajek
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mx_inlines_h)
+#define octave_mx_inlines_h 1
+
+#include <cstddef>
+#include <cmath>
+
+#include "quit.h"
+
+#include "oct-cmplx.h"
+#include "oct-locbuf.h"
+#include "oct-inttypes.h"
+
+template <class R, class S>
+inline void
+mx_inline_fill_vs (R *r, size_t n, S s)
+{
+  for (size_t i = 0; i < n; i++)
+    r[i] = s;
+}
+
+#define VS_OP_FCN(F, OP) \
+  template <class R, class V, class S> \
+  inline void \
+  F ## _vs (R *r, const V *v, size_t n, S s) \
+  { \
+    for (size_t i = 0; i < n; i++) \
+      r[i] = v[i] OP s; \
+  }
+
+VS_OP_FCN (mx_inline_add,      +)
+VS_OP_FCN (mx_inline_subtract, -)
+VS_OP_FCN (mx_inline_multiply, *)
+VS_OP_FCN (mx_inline_divide,   /)
+
+#define VS_OP(F, OP, R, V, S) \
+  static inline R * \
+  F (const V *v, size_t n, S s) \
+  { \
+    R *r = 0; \
+    if (n > 0) \
+      { \
+	r = new R [n]; \
+	F ## _vs (r, v, n, s); \
+      } \
+    return r; \
+  }
+
+#define VS_OPS(R, V, S) \
+  VS_OP (mx_inline_add,      +, R, V, S) \
+  VS_OP (mx_inline_subtract, -, R, V, S) \
+  VS_OP (mx_inline_multiply, *, R, V, S) \
+  VS_OP (mx_inline_divide,   /, R, V, S)
+
+VS_OPS (double,  double,  double)
+VS_OPS (Complex, double,  Complex)
+VS_OPS (Complex, Complex, double)
+VS_OPS (Complex, Complex, Complex)
+
+VS_OPS (float,  float,  float)
+VS_OPS (FloatComplex, float,  FloatComplex)
+VS_OPS (FloatComplex, FloatComplex, float)
+VS_OPS (FloatComplex, FloatComplex, FloatComplex)
+
+#define SV_OP_FCN(F, OP) \
+  template <class R, class S, class V> \
+  inline void \
+  F ## _sv (R *r, S s, const V *v, size_t n) \
+  { \
+    for (size_t i = 0; i < n; i++) \
+      r[i] = s OP v[i]; \
+  } \
+
+SV_OP_FCN (mx_inline_add,      +)
+SV_OP_FCN (mx_inline_subtract, -)
+SV_OP_FCN (mx_inline_multiply, *)
+SV_OP_FCN (mx_inline_divide,   /)
+
+#define SV_OP(F, OP, R, S, V) \
+  static inline R * \
+  F (S s, const V *v, size_t n) \
+  { \
+    R *r = 0; \
+    if (n > 0) \
+      { \
+	r = new R [n]; \
+        F ## _sv (r, s, v, n); \
+      } \
+    return r; \
+  }
+
+#define SV_OPS(R, S, V) \
+  SV_OP (mx_inline_add,      +, R, S, V) \
+  SV_OP (mx_inline_subtract, -, R, S, V) \
+  SV_OP (mx_inline_multiply, *, R, S, V) \
+  SV_OP (mx_inline_divide,   /, R, S, V)
+
+SV_OPS (double,  double,  double)
+SV_OPS (Complex, double,  Complex)
+SV_OPS (Complex, Complex, double)
+SV_OPS (Complex, Complex, Complex)
+
+SV_OPS (float,  float,  float)
+SV_OPS (FloatComplex, float,  FloatComplex)
+SV_OPS (FloatComplex, FloatComplex, float)
+SV_OPS (FloatComplex, FloatComplex, FloatComplex)
+
+#define VV_OP_FCN(F, OP) \
+  template <class R, class T1, class T2> \
+  inline void \
+  F ## _vv (R *r, const T1 *v1, const T2 *v2, size_t n) \
+  { \
+    for (size_t i = 0; i < n; i++) \
+      r[i] = v1[i] OP v2[i]; \
+  } \
+
+VV_OP_FCN (mx_inline_add,      +)
+VV_OP_FCN (mx_inline_subtract, -)
+VV_OP_FCN (mx_inline_multiply, *)
+VV_OP_FCN (mx_inline_divide,   /)
+
+#define VV_OP(F, OP, R, T1, T2) \
+  static inline R * \
+  F (const T1 *v1, const T2 *v2, size_t n) \
+  { \
+    R *r = 0; \
+    if (n > 0) \
+      { \
+	r = new R [n]; \
+	F ## _vv (r, v1, v2, n); \
+      } \
+    return r; \
+  }
+
+#define VV_OPS(R, T1, T2) \
+  VV_OP (mx_inline_add,      +, R, T1, T2) \
+  VV_OP (mx_inline_subtract, -, R, T1, T2) \
+  VV_OP (mx_inline_multiply, *, R, T1, T2) \
+  VV_OP (mx_inline_divide,   /, R, T1, T2)
+
+VV_OPS (double,  double,  double)
+VV_OPS (Complex, double,  Complex)
+VV_OPS (Complex, Complex, double)
+VV_OPS (Complex, Complex, Complex)
+
+VV_OPS (float,  float,  float)
+VV_OPS (FloatComplex, float,  FloatComplex)
+VV_OPS (FloatComplex, FloatComplex, float)
+VV_OPS (FloatComplex, FloatComplex, FloatComplex)
+
+#define VS_OP2(F, OP, V, S) \
+  static inline V * \
+  F (V *v, size_t n, S s) \
+  { \
+    for (size_t i = 0; i < n; i++) \
+      v[i] OP s; \
+    return v; \
+  }
+
+#define VS_OP2S(V, S) \
+  VS_OP2 (mx_inline_add2,      +=, V, S) \
+  VS_OP2 (mx_inline_subtract2, -=, V, S) \
+  VS_OP2 (mx_inline_multiply2, *=, V, S) \
+  VS_OP2 (mx_inline_divide2,   /=, V, S) \
+  VS_OP2 (mx_inline_copy,       =, V, S)
+
+VS_OP2S (double,  double)
+VS_OP2S (Complex, double)
+VS_OP2S (Complex, Complex)
+
+VS_OP2S (float,  float)
+VS_OP2S (FloatComplex, float)
+VS_OP2S (FloatComplex, FloatComplex)
+
+#define VV_OP2(F, OP, T1, T2) \
+  static inline T1 * \
+  F (T1 *v1, const T2 *v2, size_t n) \
+  { \
+    for (size_t i = 0; i < n; i++) \
+      v1[i] OP v2[i]; \
+    return v1; \
+  }
+
+#define VV_OP2S(T1, T2) \
+  VV_OP2 (mx_inline_add2,      +=, T1, T2) \
+  VV_OP2 (mx_inline_subtract2, -=, T1, T2) \
+  VV_OP2 (mx_inline_multiply2, *=, T1, T2) \
+  VV_OP2 (mx_inline_divide2,   /=, T1, T2) \
+  VV_OP2 (mx_inline_copy,       =, T1, T2)
+
+VV_OP2S (double,  double)
+VV_OP2S (Complex, double)
+VV_OP2S (Complex, Complex)
+
+VV_OP2S (float,  float)
+VV_OP2S (FloatComplex, float)
+VV_OP2S (FloatComplex, FloatComplex)
+
+#define OP_EQ_FCN(T1, T2) \
+  static inline bool \
+  mx_inline_equal (const T1 *x, const T2 *y, size_t n) \
+  { \
+    for (size_t i = 0; i < n; i++) \
+      if (x[i] != y[i]) \
+	return false; \
+    return true; \
+  }
+
+OP_EQ_FCN (bool,    bool)
+OP_EQ_FCN (char,    char)
+OP_EQ_FCN (double,  double)
+OP_EQ_FCN (Complex, Complex)
+OP_EQ_FCN (float,  float)
+OP_EQ_FCN (FloatComplex, FloatComplex)
+
+#define OP_DUP_FCN(OP, F, R, T) \
+  static inline R * \
+  F (const T *x, size_t n) \
+  { \
+    R *r = 0; \
+    if (n > 0) \
+      { \
+	r = new R [n]; \
+	for (size_t i = 0; i < n; i++) \
+	  r[i] = OP (x[i]); \
+      } \
+    return r; \
+  }
+
+OP_DUP_FCN (, mx_inline_dup, double,  double)
+OP_DUP_FCN (, mx_inline_dup, Complex, Complex)
+OP_DUP_FCN (, mx_inline_dup, float, float)
+OP_DUP_FCN (, mx_inline_dup, FloatComplex, FloatComplex)
+
+// These should really return a bool *.  Also, they should probably be
+// in with a collection of other element-by-element boolean ops.
+OP_DUP_FCN (0.0 ==, mx_inline_not, double, double)
+OP_DUP_FCN (0.0 ==, mx_inline_not, double, Complex)
+
+OP_DUP_FCN (, mx_inline_make_complex, Complex, double)
+
+OP_DUP_FCN (-, mx_inline_change_sign, double,  double)
+OP_DUP_FCN (-, mx_inline_change_sign, Complex, Complex)
+
+OP_DUP_FCN (std::abs, mx_inline_fabs_dup, double,  double)
+OP_DUP_FCN (std::abs, mx_inline_cabs_dup, double,  Complex)
+OP_DUP_FCN (real, mx_inline_real_dup, double,  Complex)
+OP_DUP_FCN (imag, mx_inline_imag_dup, double,  Complex)
+OP_DUP_FCN (conj, mx_inline_conj_dup, Complex, Complex)
+
+OP_DUP_FCN (0.0 ==, mx_inline_not, float, float)
+OP_DUP_FCN (static_cast<float>(0.0) ==, mx_inline_not, float, FloatComplex)
+
+OP_DUP_FCN (, mx_inline_make_complex, FloatComplex, float)
+
+OP_DUP_FCN (-, mx_inline_change_sign, float,  float)
+OP_DUP_FCN (-, mx_inline_change_sign, FloatComplex, FloatComplex)
+
+OP_DUP_FCN (std::abs, mx_inline_fabs_dup, float,  float)
+OP_DUP_FCN (std::abs, mx_inline_cabs_dup, float,  FloatComplex)
+OP_DUP_FCN (real, mx_inline_real_dup, float,  FloatComplex)
+OP_DUP_FCN (imag, mx_inline_imag_dup, float,  FloatComplex)
+OP_DUP_FCN (conj, mx_inline_conj_dup, FloatComplex, FloatComplex)
+
+// FIXME: Due to a performance defect in g++ (<= 4.3), std::norm is slow unless
+// ffast-math is on (not by default even with -O3). The following helper function
+// gives the expected straightforward implementation of std::norm.
+template <class T>
+inline T cabsq (const std::complex<T>& c) 
+{ return c.real () * c.real () + c.imag () * c.imag (); }
+
+#define OP_RED_SUM(ac, el) ac += el
+#define OP_RED_PROD(ac, el) ac *= el
+#define OP_RED_SUMSQ(ac, el) ac += el*el
+#define OP_RED_SUMSQC(ac, el) ac += cabsq (el)
+
+// default. works for integers and bool.
+template <class T>
+inline bool xis_true (T x) { return x; }
+template <class T>
+inline bool xis_false (T x) { return ! x; }
+// for octave_ints
+template <class T>
+inline bool xis_true (const octave_int<T>& x) { return x.value (); }
+template <class T>
+inline bool xis_false (const octave_int<T>& x) { return ! x.value (); }
+// for reals, we want to ignore NaNs.
+inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; }
+inline bool xis_false (double x) { return x == 0.0; }
+inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; }
+inline bool xis_false (float x) { return x == 0.0f; }
+// Ditto for complex.
+inline bool xis_true (const Complex& x) { return ! xisnan (x) && x != 0.0; }
+inline bool xis_false (const Complex& x) { return x == 0.0; }
+inline bool xis_true (const FloatComplex& x) { return ! xisnan (x) && x != 0.0f; }
+inline bool xis_false (const FloatComplex& x) { return x == 0.0f; }
+
+// The following two implement a simple short-circuiting.
+#define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue
+#define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue
+
+#define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \
+template <class T> \
+inline TRES \
+F (const TSRC* v, octave_idx_type n) \
+{ \
+  TRES ac = ZERO; \
+  for (octave_idx_type i = 0; i < n; i++) \
+    OP(ac, v[i]); \
+  return ac; \
+}
+
+OP_RED_FCN (mx_inline_sum, T, T, OP_RED_SUM, 0)
+OP_RED_FCN (mx_inline_count, bool, T, OP_RED_SUM, 0)
+OP_RED_FCN (mx_inline_prod, T, T, OP_RED_PROD, 1)
+OP_RED_FCN (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0)
+OP_RED_FCN (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
+OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false)
+OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true)
+
+
+#define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \
+template <class T> \
+inline void \
+F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \
+{ \
+  for (octave_idx_type i = 0; i < m; i++) \
+    r[i] = ZERO; \
+  for (octave_idx_type j = 0; j < n; j++) \
+    { \
+      for (octave_idx_type i = 0; i < m; i++) \
+        OP(r[i], v[i]); \
+      v += m; \
+    } \
+}
+
+OP_RED_FCN2 (mx_inline_sum, T, T, OP_RED_SUM, 0)
+OP_RED_FCN2 (mx_inline_count, bool, T, OP_RED_SUM, 0)
+OP_RED_FCN2 (mx_inline_prod, T, T, OP_RED_PROD, 1)
+OP_RED_FCN2 (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0)
+OP_RED_FCN2 (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
+
+// Using the general code for any/all would sacrifice short-circuiting.
+// OTOH, going by rows would sacrifice cache-coherence. The following algorithm
+// will achieve both, at the cost of a temporary octave_idx_type array.
+
+#define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \
+template <class T> \
+inline void \
+F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \
+{ \
+  /* FIXME: it may be sub-optimal to allocate the buffer here. */ \
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, iact, m); \
+  for (octave_idx_type i = 0; i < m; i++) iact[i] = i; \
+  octave_idx_type nact = m; \
+  for (octave_idx_type j = 0; j < n; j++) \
+    { \
+      octave_idx_type k = 0; \
+      for (octave_idx_type i = 0; i < nact; i++) \
+        { \
+          octave_idx_type ia = iact[i]; \
+          if (! PRED (v[ia])) \
+            iact[k++] = ia; \
+        } \
+      nact = k; \
+      v += m; \
+    } \
+  for (octave_idx_type i = 0; i < m; i++) r[i] = ! ZERO; \
+  for (octave_idx_type i = 0; i < nact; i++) r[iact[i]] = ZERO; \
+}
+
+OP_ROW_SHORT_CIRCUIT (mx_inline_any, xis_true, false)
+OP_ROW_SHORT_CIRCUIT (mx_inline_all, xis_false, true)
+
+#define OP_RED_FCNN(F, TSRC, TRES) \
+template <class T> \
+inline void \
+F (const TSRC *v, TRES *r, octave_idx_type l, \
+   octave_idx_type n, octave_idx_type u) \
+{ \
+  if (l == 1) \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          r[i] = F<T> (v, n); \
+          v += n; \
+        } \
+    } \
+  else \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, l, n); \
+          v += l*n; \
+          r += l; \
+        } \
+    } \
+}
+
+OP_RED_FCNN (mx_inline_sum, T, T)
+OP_RED_FCNN (mx_inline_count, bool, T)
+OP_RED_FCNN (mx_inline_prod, T, T)
+OP_RED_FCNN (mx_inline_sumsq, T, T)
+OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T)
+OP_RED_FCNN (mx_inline_any, T, bool)
+OP_RED_FCNN (mx_inline_all, T, bool)
+
+#define OP_CUM_FCN(F, TSRC, TRES, OP) \
+template <class T> \
+inline void \
+F (const TSRC *v, TRES *r, octave_idx_type n) \
+{ \
+  if (n) \
+    { \
+      TRES t = r[0] = v[0]; \
+      for (octave_idx_type i = 1; i < n; i++) \
+        r[i] = t = t OP v[i]; \
+    } \
+}
+
+OP_CUM_FCN (mx_inline_cumsum, T, T, +)
+OP_CUM_FCN (mx_inline_cumprod, T, T, *)
+OP_CUM_FCN (mx_inline_cumcount, bool, T, +)
+
+#define OP_CUM_FCN2(F, TSRC, TRES, OP) \
+template <class T> \
+inline void \
+F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \
+{ \
+  if (n) \
+    { \
+      for (octave_idx_type i = 0; i < m; i++) \
+        r[i] = v[i]; \
+      const T *r0 = r; \
+      for (octave_idx_type j = 1; j < n; j++) \
+        { \
+          r += m; v += m; \
+          for (octave_idx_type i = 0; i < m; i++) \
+            r[i] = r0[i] OP v[i]; \
+          r0 += m; \
+        } \
+    } \
+}
+
+OP_CUM_FCN2 (mx_inline_cumsum, T, T, +)
+OP_CUM_FCN2 (mx_inline_cumprod, T, T, *)
+OP_CUM_FCN2 (mx_inline_cumcount, bool, T, *)
+
+#define OP_CUM_FCNN(F, TSRC, TRES) \
+template <class T> \
+inline void \
+F (const TSRC *v, TRES *r, octave_idx_type l, \
+   octave_idx_type n, octave_idx_type u) \
+{ \
+  if (l == 1) \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, n); \
+          v += n; r += n; \
+        } \
+    } \
+  else \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, l, n); \
+          v += l*n; \
+          r += l*n; \
+        } \
+    } \
+}
+
+OP_CUM_FCNN (mx_inline_cumsum, T, T)
+OP_CUM_FCNN (mx_inline_cumprod, T, T)
+OP_CUM_FCNN (mx_inline_cumcount, bool, T)
+
+#define OP_MINMAX_FCN(F, OP) \
+template <class T> \
+void F (const T *v, T *r, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  T tmp = v[0]; \
+  octave_idx_type i = 1; \
+  if (xisnan (tmp)) \
+    { \
+      for (; i < n && xisnan (v[i]); i++) ; \
+      if (i < n) tmp = v[i]; \
+    } \
+  for (; i < n; i++) \
+    if (v[i] OP tmp) tmp = v[i]; \
+  *r = tmp; \
+} \
+template <class T> \
+void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  T tmp = v[0]; \
+  octave_idx_type tmpi = 0; \
+  octave_idx_type i = 1; \
+  if (xisnan (tmp)) \
+    { \
+      for (; i < n && xisnan (v[i]); i++) ; \
+      if (i < n) { tmp = v[i]; tmpi = i; } \
+    } \
+  for (; i < n; i++) \
+    if (v[i] OP tmp) { tmp = v[i]; tmpi = i; }\
+  *r = tmp; \
+  *ri = tmpi; \
+}
+
+OP_MINMAX_FCN (mx_inline_min, <)
+OP_MINMAX_FCN (mx_inline_max, >)
+
+// Row reductions will be slightly complicated.  We will proceed with checks
+// for NaNs until we detect that no row will yield a NaN, in which case we
+// proceed to a faster code.
+
+#define OP_MINMAX_FCN2(F, OP) \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  bool nan = false; \
+  octave_idx_type j = 0; \
+  for (octave_idx_type i = 0; i < m; i++) \
+    {  \
+      r[i] = v[i]; \
+      if (xisnan (v[i])) nan = true;  \
+    } \
+  j++; v += m; \
+  while (nan && j < n) \
+    { \
+      nan = false; \
+      for (octave_idx_type i = 0; i < m; i++) \
+        {  \
+          if (xisnan (v[i])) \
+            nan = true;  \
+          else if (xisnan (r[i]) || v[i] OP r[i]) \
+            r[i] = v[i]; \
+        } \
+      j++; v += m; \
+    } \
+  while (j < n) \
+    { \
+      for (octave_idx_type i = 0; i < m; i++) \
+        if (v[i] OP r[i]) r[i] = v[i]; \
+      j++; v += m; \
+    } \
+} \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type *ri, \
+   octave_idx_type m, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  bool nan = false; \
+  octave_idx_type j = 0; \
+  for (octave_idx_type i = 0; i < m; i++) \
+    {  \
+      r[i] = v[i]; ri[i] = j; \
+      if (xisnan (v[i])) nan = true;  \
+    } \
+  j++; v += m; \
+  while (nan && j < n) \
+    { \
+      nan = false; \
+      for (octave_idx_type i = 0; i < m; i++) \
+        {  \
+          if (xisnan (v[i])) \
+            nan = true;  \
+          else if (xisnan (r[i]) || v[i] OP r[i]) \
+            { r[i] = v[i]; ri[i] = j; } \
+        } \
+      j++; v += m; \
+    } \
+  while (j < n) \
+    { \
+      for (octave_idx_type i = 0; i < m; i++) \
+        if (v[i] OP r[i]) \
+          { r[i] = v[i]; ri[i] = j; } \
+      j++; v += m; \
+    } \
+}
+
+OP_MINMAX_FCN2 (mx_inline_min, <)
+OP_MINMAX_FCN2 (mx_inline_max, >)
+
+#define OP_MINMAX_FCNN(F) \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type l, \
+   octave_idx_type n, octave_idx_type u) \
+{ \
+  if (! n) return; \
+  if (l == 1) \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, n); \
+          v += n; r++; \
+        } \
+    } \
+  else \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, l, n); \
+          v += l*n; \
+          r += l; \
+        } \
+    } \
+} \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type *ri, \
+   octave_idx_type l, octave_idx_type n, octave_idx_type u) \
+{ \
+  if (! n) return; \
+  if (l == 1) \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, ri, n); \
+          v += n; r++; ri++; \
+        } \
+    } \
+  else \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, ri, l, n); \
+          v += l*n; \
+          r += l; ri += l; \
+        } \
+    } \
+}
+
+OP_MINMAX_FCNN (mx_inline_min)
+OP_MINMAX_FCNN (mx_inline_max)
+
+#define OP_CUMMINMAX_FCN(F, OP) \
+template <class T> \
+void F (const T *v, T *r, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  T tmp = v[0]; \
+  octave_idx_type i = 1, j = 0; \
+  if (xisnan (tmp)) \
+    { \
+      for (; i < n && xisnan (v[i]); i++) ; \
+      for (; j < i; j++) r[j] = tmp; \
+      if (i < n) tmp = v[i]; \
+    } \
+  for (; i < n; i++) \
+    if (v[i] OP tmp) \
+      { \
+        for (; j < i; j++) r[j] = tmp; \
+        tmp = v[i]; \
+      } \
+  for (; j < i; j++) r[j] = tmp; \
+} \
+template <class T> \
+void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  T tmp = v[0]; octave_idx_type tmpi = 0; \
+  octave_idx_type i = 1, j = 0; \
+  if (xisnan (tmp)) \
+    { \
+      for (; i < n && xisnan (v[i]); i++) ; \
+      for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
+      if (i < n) { tmp = v[i]; tmpi = i; } \
+    } \
+  for (; i < n; i++) \
+    if (v[i] OP tmp) \
+      { \
+        for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
+        tmp = v[i]; tmpi = i; \
+      } \
+  for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
+}
+
+OP_CUMMINMAX_FCN (mx_inline_cummin, <)
+OP_CUMMINMAX_FCN (mx_inline_cummax, >)
+
+// Row reductions will be slightly complicated.  We will proceed with checks
+// for NaNs until we detect that no row will yield a NaN, in which case we
+// proceed to a faster code.
+
+#define OP_CUMMINMAX_FCN2(F, OP) \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  bool nan = false; \
+  const T *r0; \
+  octave_idx_type j = 0; \
+  for (octave_idx_type i = 0; i < m; i++) \
+    {  \
+      r[i] = v[i]; \
+      if (xisnan (v[i])) nan = true;  \
+    } \
+  j++; v += m; r0 = r; r += m; \
+  while (nan && j < n) \
+    { \
+      nan = false; \
+      for (octave_idx_type i = 0; i < m; i++) \
+        {  \
+          if (xisnan (v[i])) \
+            { r[i] = r0[i]; nan = true; } \
+          else if (xisnan (r0[i]) || v[i] OP r0[i]) \
+            r[i] = v[i]; \
+        } \
+      j++; v += m; r0 = r; r += m; \
+    } \
+  while (j < n) \
+    { \
+      for (octave_idx_type i = 0; i < m; i++) \
+        if (v[i] OP r0[i]) \
+          r[i] = v[i]; \
+        else \
+          r[i] = r0[i]; \
+      j++; v += m; r0 = r; r += m; \
+    } \
+} \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type *ri, \
+   octave_idx_type m, octave_idx_type n) \
+{ \
+  if (! n) return; \
+  bool nan = false; \
+  const T *r0; const octave_idx_type *r0i; \
+  octave_idx_type j = 0; \
+  for (octave_idx_type i = 0; i < m; i++) \
+    {  \
+      r[i] = v[i]; ri[i] = 0; \
+      if (xisnan (v[i])) nan = true;  \
+    } \
+  j++; v += m; r0 = r; r += m; r0i = ri; ri += m;  \
+  while (nan && j < n) \
+    { \
+      nan = false; \
+      for (octave_idx_type i = 0; i < m; i++) \
+        {  \
+          if (xisnan (v[i])) \
+            { r[i] = r0[i]; ri[i] = r0i[i]; nan = true; } \
+          else if (xisnan (r0[i]) || v[i] OP r0[i]) \
+            { r[i] = v[i]; ri[i] = j; }\
+        } \
+      j++; v += m; r0 = r; r += m; r0i = ri; ri += m;  \
+    } \
+  while (j < n) \
+    { \
+      for (octave_idx_type i = 0; i < m; i++) \
+        if (v[i] OP r0[i]) \
+          { r[i] = v[i]; ri[i] = j; } \
+        else \
+          { r[i] = r0[i]; ri[i] = r0i[i]; } \
+      j++; v += m; r0 = r; r += m; r0i = ri; ri += m;  \
+    } \
+}
+
+OP_CUMMINMAX_FCN2 (mx_inline_cummin, <)
+OP_CUMMINMAX_FCN2 (mx_inline_cummax, >)
+
+#define OP_CUMMINMAX_FCNN(F) \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type l, \
+   octave_idx_type n, octave_idx_type u) \
+{ \
+  if (! n) return; \
+  if (l == 1) \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, n); \
+          v += n; r += n; \
+        } \
+    } \
+  else \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, l, n); \
+          v += l*n; \
+          r += l*n; \
+        } \
+    } \
+} \
+template <class T> \
+inline void \
+F (const T *v, T *r, octave_idx_type *ri, \
+   octave_idx_type l, octave_idx_type n, octave_idx_type u) \
+{ \
+  if (! n) return; \
+  if (l == 1) \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, ri, n); \
+          v += n; r += n; ri += n; \
+        } \
+    } \
+  else \
+    { \
+      for (octave_idx_type i = 0; i < u; i++) \
+        { \
+          F (v, r, ri, l, n); \
+          v += l*n; \
+          r += l*n; ri += l*n; \
+        } \
+    } \
+}
+
+OP_CUMMINMAX_FCNN (mx_inline_cummin)
+OP_CUMMINMAX_FCNN (mx_inline_cummax)
+
+// Assistant function
+
+inline void
+get_extent_triplet (const dim_vector& dims, int& dim,
+                    octave_idx_type& l, octave_idx_type& n,
+                    octave_idx_type& u)
+{
+  octave_idx_type ndims = dims.length ();
+  if (dim >= ndims)
+    {
+      l = dims.numel ();
+      n = 1;
+      u = 1;
+    }
+  else
+    {
+      if (dim < 0)
+        {
+          // find first non-singleton dim
+          for (dim = 0; dims(dim) == 1 && dim < ndims - 1; dim++) ;
+        }
+      // calculate extent triplet.
+      l = 1, n = dims(dim), u = 1;
+      for (octave_idx_type i = 0; i < dim; i++) 
+        l *= dims (i);
+      for (octave_idx_type i = dim + 1; i < ndims; i++)
+        u *= dims (i);
+    }
+}
+
+// Appliers.
+// FIXME: is this the best design? C++ gives a lot of options here...
+// maybe it can be done without an explicit parameter?
+
+template <class ArrayType, class T>
+inline ArrayType
+do_mx_red_op (const Array<T>& src, int dim,
+              void (*mx_red_op) (const T *, typename ArrayType::element_type *,
+                                 octave_idx_type, octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  // M*b inconsistency: sum([]) = 0 etc.
+  if (dims.length () == 2 && dims(0) == 0 && dims(1) == 0)
+    dims (1) = 1;
+
+  get_extent_triplet (dims, dim, l, n, u);
+
+  // Reduction operation reduces the array size.
+  if (dim < dims.length ()) dims(dim) = 1;
+  dims.chop_trailing_singletons ();
+
+  ArrayType ret (dims);
+  mx_red_op (src.data (), ret.fortran_vec (), l, n, u);
+
+  return ret;
+}
+
+template <class ArrayType, class T>
+inline ArrayType
+do_mx_cum_op (const Array<T>& src, int dim,
+              void (*mx_cum_op) (const T *, typename ArrayType::element_type *,
+                                 octave_idx_type, octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  // Cumulative operation doesn't reduce the array size.
+  ArrayType ret (dims);
+  mx_cum_op (src.data (), ret.fortran_vec (), l, n, u);
+
+  return ret;
+}
+
+template <class ArrayType>
+inline ArrayType
+do_mx_minmax_op (const ArrayType& src, int dim,
+                 void (*mx_minmax_op) (const typename ArrayType::element_type *, 
+                                       typename ArrayType::element_type *,
+                                       octave_idx_type, octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  // If the dimension is zero, we don't do anything.
+  if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
+  dims.chop_trailing_singletons ();
+
+  ArrayType ret (dims);
+  mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u);
+
+  return ret;
+}
+
+template <class ArrayType>
+inline ArrayType
+do_mx_minmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim,
+                 void (*mx_minmax_op) (const typename ArrayType::element_type *, 
+                                       typename ArrayType::element_type *,
+                                       octave_idx_type *,
+                                       octave_idx_type, octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  // If the dimension is zero, we don't do anything.
+  if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
+  dims.chop_trailing_singletons ();
+
+  ArrayType ret (dims);
+  if (idx.dims () != dims) idx = Array<octave_idx_type> (dims);
+
+  mx_minmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (),
+                l, n, u);
+
+  return ret;
+}
+
+template <class ArrayType>
+inline ArrayType
+do_mx_cumminmax_op (const ArrayType& src, int dim,
+                    void (*mx_cumminmax_op) (const typename ArrayType::element_type *, 
+                                             typename ArrayType::element_type *,
+                                             octave_idx_type, octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  ArrayType ret (dims);
+  mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u);
+
+  return ret;
+}
+
+template <class ArrayType>
+inline ArrayType
+do_mx_cumminmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim,
+                    void (*mx_cumminmax_op) (const typename ArrayType::element_type *, 
+                                             typename ArrayType::element_type *,
+                                             octave_idx_type *,
+                                             octave_idx_type, octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  ArrayType ret (dims);
+  if (idx.dims () != dims) idx = Array<octave_idx_type> (dims);
+
+  mx_cumminmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (),
+                   l, n, u);
+
+  return ret;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mx-m-cdm.cc b/liboctave/mx-m-cdm.cc
new file mode 100644
index 0000000..6550a8a
--- /dev/null
+++ b/liboctave/mx-m-cdm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-m-cdm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "CDiagMatrix.h"
+MDM_BIN_OPS (ComplexMatrix, Matrix, ComplexDiagMatrix, 0.0)
diff --git a/liboctave/mx-m-cdm.h b/liboctave/mx-m-cdm.h
new file mode 100644
index 0000000..59b33cb
--- /dev/null
+++ b/liboctave/mx-m-cdm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_m_cdm_h)
+#define octave_mx_m_cdm_h 1
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "CDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (ComplexMatrix, Matrix, ComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-m-cm.cc b/liboctave/mx-m-cm.cc
new file mode 100644
index 0000000..4b33f65
--- /dev/null
+++ b/liboctave/mx-m-cm.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-m-cm.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "CMatrix.h"
+#include "dMatrix.h"
+MM_BIN_OPS (ComplexMatrix, Matrix, ComplexMatrix)
+MM_CMP_OPS (Matrix, , ComplexMatrix, real)
+MM_BOOL_OPS2 (Matrix, ComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/mx-m-cm.h b/liboctave/mx-m-cm.h
new file mode 100644
index 0000000..009416a
--- /dev/null
+++ b/liboctave/mx-m-cm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_m_cm_h)
+#define octave_mx_m_cm_h 1
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "mx-op-decl.h"
+MM_BIN_OP_DECLS (ComplexMatrix, Matrix, ComplexMatrix, OCTAVE_API)
+MM_CMP_OP_DECLS (Matrix, ComplexMatrix, OCTAVE_API)
+MM_BOOL_OP_DECLS (Matrix, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-m-cs.cc b/liboctave/mx-m-cs.cc
new file mode 100644
index 0000000..286c99f
--- /dev/null
+++ b/liboctave/mx-m-cs.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-m-cs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "oct-cmplx.h"
+MS_BIN_OPS (ComplexMatrix, Matrix, Complex)
+MS_CMP_OPS (Matrix, , Complex, real)
+MS_BOOL_OPS2 (Matrix, Complex, 0.0, 0.0)
diff --git a/liboctave/mx-m-cs.h b/liboctave/mx-m-cs.h
new file mode 100644
index 0000000..ea3400c
--- /dev/null
+++ b/liboctave/mx-m-cs.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_m_cs_h)
+#define octave_mx_m_cs_h 1
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+MS_BIN_OP_DECLS (ComplexMatrix, Matrix, Complex, OCTAVE_API)
+MS_CMP_OP_DECLS (Matrix, Complex, OCTAVE_API)
+MS_BOOL_OP_DECLS (Matrix, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-m-dm.cc b/liboctave/mx-m-dm.cc
new file mode 100644
index 0000000..d7f8241
--- /dev/null
+++ b/liboctave/mx-m-dm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-m-dm.h"
+#include "mx-op-defs.h"
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+MDM_BIN_OPS (Matrix, Matrix, DiagMatrix, 0.0)
diff --git a/liboctave/mx-m-dm.h b/liboctave/mx-m-dm.h
new file mode 100644
index 0000000..590c06c
--- /dev/null
+++ b/liboctave/mx-m-dm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_m_dm_h)
+#define octave_mx_m_dm_h 1
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+MDM_BIN_OP_DECLS (Matrix, Matrix, DiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-m-pm.cc b/liboctave/mx-m-pm.cc
new file mode 100644
index 0000000..5950e38
--- /dev/null
+++ b/liboctave/mx-m-pm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-m-pm.h"
+#include "mx-op-defs.h"
+#include "dMatrix.h"
+#include "PermMatrix.h"
+MPM_BIN_OPS (Matrix, Matrix, PermMatrix)
diff --git a/liboctave/mx-m-pm.h b/liboctave/mx-m-pm.h
new file mode 100644
index 0000000..f049fa5
--- /dev/null
+++ b/liboctave/mx-m-pm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_m_pm_h)
+#define octave_mx_m_pm_h 1
+#include "dMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+MPM_BIN_OP_DECLS (Matrix, Matrix, PermMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-cnda.cc b/liboctave/mx-nda-cnda.cc
new file mode 100644
index 0000000..950c918
--- /dev/null
+++ b/liboctave/mx-nda-cnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-cnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (ComplexNDArray, NDArray, ComplexNDArray)
+NDND_CMP_OPS (NDArray, , ComplexNDArray, real)
+NDND_BOOL_OPS2 (NDArray, ComplexNDArray, 0.0, 0.0)
diff --git a/liboctave/mx-nda-cnda.h b/liboctave/mx-nda-cnda.h
new file mode 100644
index 0000000..aa49f5a
--- /dev/null
+++ b/liboctave/mx-nda-cnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_cnda_h)
+#define octave_mx_nda_cnda_h 1
+#include "CNDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (ComplexNDArray, NDArray, ComplexNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, ComplexNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, ComplexNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-cs.cc b/liboctave/mx-nda-cs.cc
new file mode 100644
index 0000000..41e0e43
--- /dev/null
+++ b/liboctave/mx-nda-cs.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-cs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
+#include "dNDArray.h"
+#include "oct-cmplx.h"
+NDS_BIN_OPS (ComplexNDArray, NDArray, Complex)
+NDS_CMP_OPS (NDArray, , Complex, real)
+NDS_BOOL_OPS2 (NDArray, Complex, 0.0, 0.0)
diff --git a/liboctave/mx-nda-cs.h b/liboctave/mx-nda-cs.h
new file mode 100644
index 0000000..892ef30
--- /dev/null
+++ b/liboctave/mx-nda-cs.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_cs_h)
+#define octave_mx_nda_cs_h 1
+#include "CNDArray.h"
+#include "dNDArray.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (ComplexNDArray, NDArray, Complex, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, Complex, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i16.cc b/liboctave/mx-nda-i16.cc
new file mode 100644
index 0000000..b41677c
--- /dev/null
+++ b/liboctave/mx-nda-i16.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int16NDArray, NDArray, octave_int16)
+NDS_CMP_OPS1 (NDArray, , octave_int16, , int16_t)
+NDS_BOOL_OPS2 (NDArray, octave_int16, 0.0, octave_int16::zero)
diff --git a/liboctave/mx-nda-i16.h b/liboctave/mx-nda-i16.h
new file mode 100644
index 0000000..15cca15
--- /dev/null
+++ b/liboctave/mx-nda-i16.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i16_h)
+#define octave_mx_nda_i16_h 1
+#include "int16NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int16NDArray, NDArray, octave_int16, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i16nda.cc b/liboctave/mx-nda-i16nda.cc
new file mode 100644
index 0000000..c0f81d5
--- /dev/null
+++ b/liboctave/mx-nda-i16nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int16NDArray, NDArray, int16NDArray)
+NDND_CMP_OPS (NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (NDArray, int16NDArray, 0.0, octave_int16::zero)
diff --git a/liboctave/mx-nda-i16nda.h b/liboctave/mx-nda-i16nda.h
new file mode 100644
index 0000000..f64b4f7
--- /dev/null
+++ b/liboctave/mx-nda-i16nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i16nda_h)
+#define octave_mx_nda_i16nda_h 1
+#include "int16NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int16NDArray, NDArray, int16NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i32.cc b/liboctave/mx-nda-i32.cc
new file mode 100644
index 0000000..34092e3
--- /dev/null
+++ b/liboctave/mx-nda-i32.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int32NDArray, NDArray, octave_int32)
+NDS_CMP_OPS1 (NDArray, , octave_int32, , int32_t)
+NDS_BOOL_OPS2 (NDArray, octave_int32, 0.0, octave_int32::zero)
diff --git a/liboctave/mx-nda-i32.h b/liboctave/mx-nda-i32.h
new file mode 100644
index 0000000..9b6a538
--- /dev/null
+++ b/liboctave/mx-nda-i32.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i32_h)
+#define octave_mx_nda_i32_h 1
+#include "int32NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int32NDArray, NDArray, octave_int32, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i32nda.cc b/liboctave/mx-nda-i32nda.cc
new file mode 100644
index 0000000..776cc01
--- /dev/null
+++ b/liboctave/mx-nda-i32nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int32NDArray, NDArray, int32NDArray)
+NDND_CMP_OPS (NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (NDArray, int32NDArray, 0.0, octave_int32::zero)
diff --git a/liboctave/mx-nda-i32nda.h b/liboctave/mx-nda-i32nda.h
new file mode 100644
index 0000000..47d18a7
--- /dev/null
+++ b/liboctave/mx-nda-i32nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i32nda_h)
+#define octave_mx_nda_i32nda_h 1
+#include "int32NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int32NDArray, NDArray, int32NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i64.cc b/liboctave/mx-nda-i64.cc
new file mode 100644
index 0000000..a2aebfa
--- /dev/null
+++ b/liboctave/mx-nda-i64.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int64NDArray, NDArray, octave_int64)
+NDS_CMP_OPS1 (NDArray, , octave_int64, , int64_t)
+NDS_BOOL_OPS2 (NDArray, octave_int64, 0.0, octave_int64::zero)
diff --git a/liboctave/mx-nda-i64.h b/liboctave/mx-nda-i64.h
new file mode 100644
index 0000000..0138fb1
--- /dev/null
+++ b/liboctave/mx-nda-i64.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i64_h)
+#define octave_mx_nda_i64_h 1
+#include "int64NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int64NDArray, NDArray, octave_int64, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i64nda.cc b/liboctave/mx-nda-i64nda.cc
new file mode 100644
index 0000000..58c696b
--- /dev/null
+++ b/liboctave/mx-nda-i64nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int64NDArray, NDArray, int64NDArray)
+NDND_CMP_OPS (NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (NDArray, int64NDArray, 0.0, octave_int64::zero)
diff --git a/liboctave/mx-nda-i64nda.h b/liboctave/mx-nda-i64nda.h
new file mode 100644
index 0000000..bb693eb
--- /dev/null
+++ b/liboctave/mx-nda-i64nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i64nda_h)
+#define octave_mx_nda_i64nda_h 1
+#include "int64NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int64NDArray, NDArray, int64NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i8.cc b/liboctave/mx-nda-i8.cc
new file mode 100644
index 0000000..a7ad919
--- /dev/null
+++ b/liboctave/mx-nda-i8.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (int8NDArray, NDArray, octave_int8)
+NDS_CMP_OPS1 (NDArray, , octave_int8, , int8_t)
+NDS_BOOL_OPS2 (NDArray, octave_int8, 0.0, octave_int8::zero)
diff --git a/liboctave/mx-nda-i8.h b/liboctave/mx-nda-i8.h
new file mode 100644
index 0000000..14929a3
--- /dev/null
+++ b/liboctave/mx-nda-i8.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i8_h)
+#define octave_mx_nda_i8_h 1
+#include "int8NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (int8NDArray, NDArray, octave_int8, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-i8nda.cc b/liboctave/mx-nda-i8nda.cc
new file mode 100644
index 0000000..67aaa3f
--- /dev/null
+++ b/liboctave/mx-nda-i8nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (int8NDArray, NDArray, int8NDArray)
+NDND_CMP_OPS (NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (NDArray, int8NDArray, 0.0, octave_int8::zero)
diff --git a/liboctave/mx-nda-i8nda.h b/liboctave/mx-nda-i8nda.h
new file mode 100644
index 0000000..447cd7e
--- /dev/null
+++ b/liboctave/mx-nda-i8nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_i8nda_h)
+#define octave_mx_nda_i8nda_h 1
+#include "int8NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (int8NDArray, NDArray, int8NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui16.cc b/liboctave/mx-nda-ui16.cc
new file mode 100644
index 0000000..1b8ba47
--- /dev/null
+++ b/liboctave/mx-nda-ui16.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint16NDArray, NDArray, octave_uint16)
+NDS_CMP_OPS1 (NDArray, , octave_uint16, , uint16_t)
+NDS_BOOL_OPS2 (NDArray, octave_uint16, 0.0, octave_uint16::zero)
diff --git a/liboctave/mx-nda-ui16.h b/liboctave/mx-nda-ui16.h
new file mode 100644
index 0000000..8f5423b
--- /dev/null
+++ b/liboctave/mx-nda-ui16.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui16_h)
+#define octave_mx_nda_ui16_h 1
+#include "uint16NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint16NDArray, NDArray, octave_uint16, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui16nda.cc b/liboctave/mx-nda-ui16nda.cc
new file mode 100644
index 0000000..a342598
--- /dev/null
+++ b/liboctave/mx-nda-ui16nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint16NDArray, NDArray, uint16NDArray)
+NDND_CMP_OPS (NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (NDArray, uint16NDArray, 0.0, octave_uint16::zero)
diff --git a/liboctave/mx-nda-ui16nda.h b/liboctave/mx-nda-ui16nda.h
new file mode 100644
index 0000000..1bdcc40
--- /dev/null
+++ b/liboctave/mx-nda-ui16nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui16nda_h)
+#define octave_mx_nda_ui16nda_h 1
+#include "uint16NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint16NDArray, NDArray, uint16NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui32.cc b/liboctave/mx-nda-ui32.cc
new file mode 100644
index 0000000..cc4c655
--- /dev/null
+++ b/liboctave/mx-nda-ui32.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint32NDArray, NDArray, octave_uint32)
+NDS_CMP_OPS1 (NDArray, , octave_uint32, , uint32_t)
+NDS_BOOL_OPS2 (NDArray, octave_uint32, 0.0, octave_uint32::zero)
diff --git a/liboctave/mx-nda-ui32.h b/liboctave/mx-nda-ui32.h
new file mode 100644
index 0000000..48ab1f7
--- /dev/null
+++ b/liboctave/mx-nda-ui32.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui32_h)
+#define octave_mx_nda_ui32_h 1
+#include "uint32NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint32NDArray, NDArray, octave_uint32, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui32nda.cc b/liboctave/mx-nda-ui32nda.cc
new file mode 100644
index 0000000..ed36843
--- /dev/null
+++ b/liboctave/mx-nda-ui32nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint32NDArray, NDArray, uint32NDArray)
+NDND_CMP_OPS (NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (NDArray, uint32NDArray, 0.0, octave_uint32::zero)
diff --git a/liboctave/mx-nda-ui32nda.h b/liboctave/mx-nda-ui32nda.h
new file mode 100644
index 0000000..1eacd90
--- /dev/null
+++ b/liboctave/mx-nda-ui32nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui32nda_h)
+#define octave_mx_nda_ui32nda_h 1
+#include "uint32NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint32NDArray, NDArray, uint32NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui64.cc b/liboctave/mx-nda-ui64.cc
new file mode 100644
index 0000000..1514555
--- /dev/null
+++ b/liboctave/mx-nda-ui64.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint64NDArray, NDArray, octave_uint64)
+NDS_CMP_OPS1 (NDArray, , octave_uint64, , uint64_t)
+NDS_BOOL_OPS2 (NDArray, octave_uint64, 0.0, octave_uint64::zero)
diff --git a/liboctave/mx-nda-ui64.h b/liboctave/mx-nda-ui64.h
new file mode 100644
index 0000000..0489b88
--- /dev/null
+++ b/liboctave/mx-nda-ui64.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui64_h)
+#define octave_mx_nda_ui64_h 1
+#include "uint64NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint64NDArray, NDArray, octave_uint64, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui64nda.cc b/liboctave/mx-nda-ui64nda.cc
new file mode 100644
index 0000000..695c225
--- /dev/null
+++ b/liboctave/mx-nda-ui64nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint64NDArray, NDArray, uint64NDArray)
+NDND_CMP_OPS (NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (NDArray, uint64NDArray, 0.0, octave_uint64::zero)
diff --git a/liboctave/mx-nda-ui64nda.h b/liboctave/mx-nda-ui64nda.h
new file mode 100644
index 0000000..5e468e4
--- /dev/null
+++ b/liboctave/mx-nda-ui64nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui64nda_h)
+#define octave_mx_nda_ui64nda_h 1
+#include "uint64NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint64NDArray, NDArray, uint64NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui8.cc b/liboctave/mx-nda-ui8.cc
new file mode 100644
index 0000000..3cb76ca
--- /dev/null
+++ b/liboctave/mx-nda-ui8.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+NDS_BIN_OPS (uint8NDArray, NDArray, octave_uint8)
+NDS_CMP_OPS1 (NDArray, , octave_uint8, , uint8_t)
+NDS_BOOL_OPS2 (NDArray, octave_uint8, 0.0, octave_uint8::zero)
diff --git a/liboctave/mx-nda-ui8.h b/liboctave/mx-nda-ui8.h
new file mode 100644
index 0000000..c6f834e
--- /dev/null
+++ b/liboctave/mx-nda-ui8.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui8_h)
+#define octave_mx_nda_ui8_h 1
+#include "uint8NDArray.h"
+#include "dNDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint8NDArray, NDArray, octave_uint8, OCTAVE_API)
+NDS_CMP_OP_DECLS (NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-nda-ui8nda.cc b/liboctave/mx-nda-ui8nda.cc
new file mode 100644
index 0000000..d52e6f9
--- /dev/null
+++ b/liboctave/mx-nda-ui8nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint8NDArray, NDArray, uint8NDArray)
+NDND_CMP_OPS (NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (NDArray, uint8NDArray, 0.0, octave_uint8::zero)
diff --git a/liboctave/mx-nda-ui8nda.h b/liboctave/mx-nda-ui8nda.h
new file mode 100644
index 0000000..c7903d0
--- /dev/null
+++ b/liboctave/mx-nda-ui8nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_nda_ui8nda_h)
+#define octave_mx_nda_ui8nda_h 1
+#include "uint8NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint8NDArray, NDArray, uint8NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-op-decl.h b/liboctave/mx-op-decl.h
new file mode 100644
index 0000000..0d6992a
--- /dev/null
+++ b/liboctave/mx-op-decl.h
@@ -0,0 +1,308 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mx_op_decl_h)
+#define octave_mx_op_decl_h 1
+
+#include "oct-types.h"
+
+#define BIN_OP_DECL(R, OP, X, Y, API) \
+  extern API R OP (const X&, const Y&)
+
+class boolMatrix;
+class boolNDArray;
+
+#define CMP_OP_DECL(OP, X, Y, API) \
+  extern API boolMatrix OP (const X&, const Y&)
+
+#define NDCMP_OP_DECL(OP, X, Y, API) \
+  extern API boolNDArray OP (const X&, const Y&)
+
+#define BOOL_OP_DECL(OP, X, Y, API) \
+  extern API boolMatrix OP (const X&, const Y&)
+
+#define NDBOOL_OP_DECL(OP, X, Y, API) \
+  extern API boolNDArray OP (const X&, const Y&)
+
+// vector by scalar operations.
+
+#define VS_BIN_OP_DECLS(R, V, S, API) \
+  BIN_OP_DECL (R, operator +, V, S, API); \
+  BIN_OP_DECL (R, operator -, V, S, API); \
+  BIN_OP_DECL (R, operator *, V, S, API); \
+  BIN_OP_DECL (R, operator /, V, S, API);
+
+#define VS_OP_DECLS(R, V, S, API) \
+  VS_BIN_OP_DECLS(R, V, S, API)
+
+// scalar by vector by operations.
+
+#define SV_BIN_OP_DECLS(R, S, V, API) \
+  BIN_OP_DECL (R, operator +, S, V, API); \
+  BIN_OP_DECL (R, operator -, S, V, API); \
+  BIN_OP_DECL (R, operator *, S, V, API); \
+  BIN_OP_DECL (R, operator /, S, V, API);
+
+#define SV_OP_DECLS(R, S, V, API) \
+  SV_BIN_OP_DECLS(R, S, V, API)
+
+// vector by vector operations.
+
+#define VV_BIN_OP_DECLS(R, V1, V2, API) \
+  BIN_OP_DECL (R, operator +, V1, V2, API); \
+  BIN_OP_DECL (R, operator -, V1, V2, API); \
+  BIN_OP_DECL (R, product,    V1, V2, API); \
+  BIN_OP_DECL (R, quotient,   V1, V2, API);
+
+#define VV_OP_DECLS(R, V1, V2, API) \
+  VV_BIN_OP_DECLS(R, V1, V2, API)
+
+// matrix by scalar operations.
+
+#define MS_BIN_OP_DECLS(R, M, S, API) \
+  BIN_OP_DECL (R, operator +, M, S, API); \
+  BIN_OP_DECL (R, operator -, M, S, API); \
+  BIN_OP_DECL (R, operator *, M, S, API); \
+  BIN_OP_DECL (R, operator /, M, S, API);
+
+#define MS_CMP_OP_DECLS(M, S, API) \
+  CMP_OP_DECL (mx_el_lt, M, S, API); \
+  CMP_OP_DECL (mx_el_le, M, S, API); \
+  CMP_OP_DECL (mx_el_ge, M, S, API); \
+  CMP_OP_DECL (mx_el_gt, M, S, API); \
+  CMP_OP_DECL (mx_el_eq, M, S, API); \
+  CMP_OP_DECL (mx_el_ne, M, S, API);
+
+#define MS_BOOL_OP_DECLS(M, S, API) \
+  BOOL_OP_DECL (mx_el_and, M, S, API); \
+  BOOL_OP_DECL (mx_el_or,  M, S, API); \
+
+#define MS_OP_DECLS(R, M, S, API) \
+  MS_BIN_OP_DECLS (R, M, S, API) \
+  MS_CMP_OP_DECLS (M, S, API) \
+  MS_BOOL_OP_DECLS (M, S, API) \
+
+// scalar by matrix operations.
+
+#define SM_BIN_OP_DECLS(R, S, M, API) \
+  BIN_OP_DECL (R, operator +, S, M, API); \
+  BIN_OP_DECL (R, operator -, S, M, API); \
+  BIN_OP_DECL (R, operator *, S, M, API); \
+  BIN_OP_DECL (R, operator /, S, M, API);
+
+#define SM_CMP_OP_DECLS(S, M, API) \
+  CMP_OP_DECL (mx_el_lt, S, M, API); \
+  CMP_OP_DECL (mx_el_le, S, M, API); \
+  CMP_OP_DECL (mx_el_ge, S, M, API); \
+  CMP_OP_DECL (mx_el_gt, S, M, API); \
+  CMP_OP_DECL (mx_el_eq, S, M, API); \
+  CMP_OP_DECL (mx_el_ne, S, M, API);
+
+#define SM_BOOL_OP_DECLS(S, M, API) \
+  BOOL_OP_DECL (mx_el_and, S, M, API); \
+  BOOL_OP_DECL (mx_el_or,  S, M, API); \
+
+#define SM_OP_DECLS(R, S, M, API) \
+  SM_BIN_OP_DECLS (R, S, M, API) \
+  SM_CMP_OP_DECLS (S, M, API) \
+  SM_BOOL_OP_DECLS (S, M, API) \
+
+// matrix by matrix operations.
+
+#define MM_BIN_OP_DECLS(R, M1, M2, API) \
+  BIN_OP_DECL (R, operator +, M1, M2, API); \
+  BIN_OP_DECL (R, operator -, M1, M2, API); \
+  BIN_OP_DECL (R, product,    M1, M2, API); \
+  BIN_OP_DECL (R, quotient,   M1, M2, API);
+
+#define MM_CMP_OP_DECLS(M1, M2, API) \
+  CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define MM_BOOL_OP_DECLS(M1, M2, API) \
+  BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+#define MM_OP_DECLS(R, M1, M2, API) \
+  MM_BIN_OP_DECLS (R, M1, M2, API) \
+  MM_CMP_OP_DECLS (M1, M2, API) \
+  MM_BOOL_OP_DECLS (M1, M2, API)
+
+// N-d matrix by scalar operations.
+
+#define NDS_BIN_OP_DECLS(R, ND, S, API) \
+  BIN_OP_DECL (R, operator +, ND, S, API); \
+  BIN_OP_DECL (R, operator -, ND, S, API); \
+  BIN_OP_DECL (R, operator *, ND, S, API); \
+  BIN_OP_DECL (R, operator /, ND, S, API);
+
+#define NDS_CMP_OP_DECLS(ND, S, API) \
+  NDCMP_OP_DECL (mx_el_lt, ND, S, API); \
+  NDCMP_OP_DECL (mx_el_le, ND, S, API); \
+  NDCMP_OP_DECL (mx_el_ge, ND, S, API); \
+  NDCMP_OP_DECL (mx_el_gt, ND, S, API); \
+  NDCMP_OP_DECL (mx_el_eq, ND, S, API); \
+  NDCMP_OP_DECL (mx_el_ne, ND, S, API);
+
+#define NDS_BOOL_OP_DECLS(ND, S, API) \
+  NDBOOL_OP_DECL (mx_el_and, ND, S, API); \
+  NDBOOL_OP_DECL (mx_el_or,  ND, S, API); \
+  NDBOOL_OP_DECL (mx_el_not_and, ND, S, API); \
+  NDBOOL_OP_DECL (mx_el_not_or,  ND, S, API);
+
+#define NDS_OP_DECLS(R, ND, S, API) \
+  NDS_BIN_OP_DECLS (R, ND, S, API) \
+  NDS_CMP_OP_DECLS (ND, S, API) \
+  NDS_BOOL_OP_DECLS (ND, S, API)
+
+// scalar by N-d matrix operations.
+
+#define SND_BIN_OP_DECLS(R, S, ND, API) \
+  BIN_OP_DECL (R, operator +, S, ND, API); \
+  BIN_OP_DECL (R, operator -, S, ND, API); \
+  BIN_OP_DECL (R, operator *, S, ND, API); \
+  BIN_OP_DECL (R, operator /, S, ND, API);
+
+#define SND_CMP_OP_DECLS(S, ND, API) \
+  NDCMP_OP_DECL (mx_el_lt, S, ND, API); \
+  NDCMP_OP_DECL (mx_el_le, S, ND, API); \
+  NDCMP_OP_DECL (mx_el_ge, S, ND, API); \
+  NDCMP_OP_DECL (mx_el_gt, S, ND, API); \
+  NDCMP_OP_DECL (mx_el_eq, S, ND, API); \
+  NDCMP_OP_DECL (mx_el_ne, S, ND, API);
+
+#define SND_BOOL_OP_DECLS(S, ND, API) \
+  NDBOOL_OP_DECL (mx_el_and, S, ND, API); \
+  NDBOOL_OP_DECL (mx_el_or,  S, ND, API); \
+  NDBOOL_OP_DECL (mx_el_and_not, S, ND, API); \
+  NDBOOL_OP_DECL (mx_el_or_not,  S, ND, API);
+
+#define SND_OP_DECLS(R, S, ND, API) \
+  SND_BIN_OP_DECLS (R, S, ND, API) \
+  SND_CMP_OP_DECLS (S, ND, API) \
+  SND_BOOL_OP_DECLS (S, ND, API)
+
+// N-d matrix by N-d matrix operations.
+
+#define NDND_BIN_OP_DECLS(R, ND1, ND2, API) \
+  BIN_OP_DECL (R, operator +, ND1, ND2, API); \
+  BIN_OP_DECL (R, operator -, ND1, ND2, API); \
+  BIN_OP_DECL (R, product,    ND1, ND2, API); \
+  BIN_OP_DECL (R, quotient,   ND1, ND2, API);
+
+#define NDND_CMP_OP_DECLS(ND1, ND2, API) \
+  NDCMP_OP_DECL (mx_el_lt, ND1, ND2, API); \
+  NDCMP_OP_DECL (mx_el_le, ND1, ND2, API); \
+  NDCMP_OP_DECL (mx_el_ge, ND1, ND2, API); \
+  NDCMP_OP_DECL (mx_el_gt, ND1, ND2, API); \
+  NDCMP_OP_DECL (mx_el_eq, ND1, ND2, API); \
+  NDCMP_OP_DECL (mx_el_ne, ND1, ND2, API);
+
+#define NDND_BOOL_OP_DECLS(ND1, ND2, API) \
+  NDBOOL_OP_DECL (mx_el_and, ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_or,  ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_and_not, ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_or_not,  ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_not_and, ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_not_or,  ND1, ND2, API);
+
+#define NDND_OP_DECLS(R, ND1, ND2, API) \
+  NDND_BIN_OP_DECLS (R, ND1, ND2, API) \
+  NDND_CMP_OP_DECLS (ND1, ND2, API) \
+  NDND_BOOL_OP_DECLS (ND1, ND2, API)
+
+// scalar by diagonal matrix operations.
+
+#define SDM_BIN_OP_DECLS(R, S, DM, API) \
+  BIN_OP_DECL (R, operator +, S, DM, API); \
+  BIN_OP_DECL (R, operator -, S, DM, API);
+
+#define SDM_OP_DECLS(R, S, DM, API) \
+  SDM_BIN_OP_DECLS(R, S, DM, API)
+
+// diagonal matrix by scalar operations.
+
+#define DMS_BIN_OP_DECLS(R, DM, S, API) \
+  BIN_OP_DECL (R, operator +, DM, S, API); \
+  BIN_OP_DECL (R, operator -, DM, S, API);
+
+#define DMS_OP_DECLS(R, DM, S, API) \
+  DMS_BIN_OP_DECLS(R, DM, S, API)
+
+// matrix by diagonal matrix operations.
+
+#define MDM_BIN_OP_DECLS(R, M, DM, API) \
+  BIN_OP_DECL (R, operator +, M, DM, API); \
+  BIN_OP_DECL (R, operator -, M, DM, API); \
+  BIN_OP_DECL (R, operator *, M, DM, API);
+
+#define MDM_OP_DECLS(R, M, DM, API) \
+  MDM_BIN_OP_DECLS(R, M, DM, API)
+
+// diagonal matrix by matrix operations.
+
+#define DMM_BIN_OP_DECLS(R, DM, M, API) \
+  BIN_OP_DECL (R, operator +, DM, M, API); \
+  BIN_OP_DECL (R, operator -, DM, M, API); \
+  BIN_OP_DECL (R, operator *, DM, M, API);
+
+#define DMM_OP_DECLS(R, DM, M, API) \
+  DMM_BIN_OP_DECLS(R, DM, M, API)
+
+// diagonal matrix by diagonal matrix operations.
+
+#define DMDM_BIN_OP_DECLS(R, DM1, DM2, API) \
+  BIN_OP_DECL (R, operator +, DM1, DM2, API); \
+  BIN_OP_DECL (R, operator -, DM1, DM2, API); \
+  BIN_OP_DECL (R, product, DM1, DM2, API);
+
+#define DMDM_OP_DECLS(R, DM1, DM2, API) \
+  DMDM_BIN_OP_DECLS (R, DM1, DM2, API)
+
+// scalar by N-d array min/max ops
+
+#define MINMAX_DECLS(T) \
+  extern OCTAVE_API T ## NDArray min (octave_ ## T d, const T ## NDArray& m); \
+  extern OCTAVE_API T ## NDArray min (const T ## NDArray& m, octave_ ## T d); \
+  extern OCTAVE_API T ## NDArray min (const T ## NDArray& a,  \
+				       const T ## NDArray& b); \
+  extern OCTAVE_API T ## NDArray max (octave_ ## T d, const T ## NDArray& m); \
+  extern OCTAVE_API T ## NDArray max (const T ## NDArray& m, octave_ ## T d); \
+  extern OCTAVE_API T ## NDArray max (const T ## NDArray& a, \
+				       const T ## NDArray& b);
+
+// permutation matrix by matrix ops and vice versa
+
+#define PMM_BIN_OP_DECLS(R, PM, M, API) \
+  BIN_OP_DECL (R, operator *, PM, M, API);
+
+#define MPM_BIN_OP_DECLS(R, M, PM, API) \
+  BIN_OP_DECL (R, operator *, M, PM, API);
+
+#endif
+
diff --git a/liboctave/mx-op-defs.h b/liboctave/mx-op-defs.h
new file mode 100644
index 0000000..a4ec295
--- /dev/null
+++ b/liboctave/mx-op-defs.h
@@ -0,0 +1,1137 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mx_op_defs_h)
+#define octave_mx_op_defs_h 1
+
+#include "mx-op-decl.h"
+#include "mx-inlines.cc"
+
+// vector by scalar operations.
+
+#define VS_BIN_OP(R, F, OP, V, S) \
+  R \
+  F (const V& v, const S& s) \
+  { \
+    octave_idx_type len = v.length (); \
+ \
+    R r (len); \
+ \
+    for (octave_idx_type i = 0; i < len; i++) \
+      r.elem(i) = v.elem(i) OP s; \
+ \
+    return r; \
+  }
+
+#define VS_BIN_OPS(R, V, S) \
+  VS_BIN_OP (R, operator +, +, V, S) \
+  VS_BIN_OP (R, operator -, -, V, S) \
+  VS_BIN_OP (R, operator *, *, V, S) \
+  VS_BIN_OP (R, operator /, /, V, S)
+
+// scalar by vector by operations.
+
+#define SV_BIN_OP(R, F, OP, S, V) \
+  R \
+  F (const S& s, const V& v) \
+  { \
+    octave_idx_type len = v.length (); \
+ \
+    R r (len); \
+ \
+    for (octave_idx_type i = 0; i < len; i++) \
+      r.elem(i) = s OP v.elem(i); \
+ \
+    return r; \
+  }
+
+#define SV_BIN_OPS(R, S, V) \
+  SV_BIN_OP (R, operator +, +, S, V) \
+  SV_BIN_OP (R, operator -, -, S, V) \
+  SV_BIN_OP (R, operator *, *, S, V) \
+  SV_BIN_OP (R, operator /, /, S, V)
+
+// vector by vector operations.
+
+#define VV_BIN_OP(R, F, OP, V1, V2) \
+  R \
+  F (const V1& v1, const V2& v2) \
+  { \
+    R r; \
+ \
+    octave_idx_type v1_len = v1.length (); \
+    octave_idx_type v2_len = v2.length (); \
+ \
+    if (v1_len != v2_len) \
+      gripe_nonconformant (#OP, v1_len, v2_len); \
+    else \
+      { \
+	r.resize (v1_len); \
+ \
+	for (octave_idx_type i = 0; i < v1_len; i++) \
+	  r.elem(i) = v1.elem(i) OP v2.elem(i); \
+      } \
+ \
+    return r; \
+  }
+
+#define VV_BIN_OPS(R, V1, V2) \
+  VV_BIN_OP (R, operator +, +, V1, V2) \
+  VV_BIN_OP (R, operator -, -, V1, V2) \
+  VV_BIN_OP (R, product,    *, V1, V2) \
+  VV_BIN_OP (R, quotient,   /, V1, V2)
+
+// matrix by scalar operations.
+
+#define MS_BIN_OP(R, OP, M, S, F) \
+  R \
+  OP (const M& m, const S& s) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    R r (nr, nc); \
+ \
+    if (nr > 0 && nc > 0) \
+      F ## _vs (r.fortran_vec (), m.data (), nr * nc, s); \
+ \
+    return r; \
+  }
+
+#define MS_BIN_OPS(R, M, S) \
+  MS_BIN_OP (R, operator +, M, S, mx_inline_add) \
+  MS_BIN_OP (R, operator -, M, S, mx_inline_subtract) \
+  MS_BIN_OP (R, operator *, M, S, mx_inline_multiply) \
+  MS_BIN_OP (R, operator /, M, S, mx_inline_divide)
+
+#define MS_CMP_OP(F, OP, M, MC, S, SC) \
+  boolMatrix \
+  F (const M& m, const S& s) \
+  { \
+    boolMatrix r; \
+ \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    r.resize (nr, nc); \
+ \
+    if (nr > 0 && nc > 0) \
+      { \
+        for (octave_idx_type j = 0; j < nc; j++) \
+          for (octave_idx_type i = 0; i < nr; i++) \
+	    r.elem(i, j) = MC (m.elem(i, j)) OP SC (s); \
+      } \
+ \
+    return r; \
+  }
+
+#define MS_CMP_OPS(M, CM, S, CS) \
+  MS_CMP_OP (mx_el_lt, <,  M, CM, S, CS) \
+  MS_CMP_OP (mx_el_le, <=, M, CM, S, CS) \
+  MS_CMP_OP (mx_el_ge, >=, M, CM, S, CS) \
+  MS_CMP_OP (mx_el_gt, >,  M, CM, S, CS) \
+  MS_CMP_OP (mx_el_eq, ==, M,   , S,   ) \
+  MS_CMP_OP (mx_el_ne, !=, M,   , S,   )
+
+#define MS_BOOL_OP(F, OP, M, S, LHS_ZERO, RHS_ZERO) \
+  boolMatrix \
+  F (const M& m, const S& s) \
+  { \
+    boolMatrix r; \
+ \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    if (nr != 0 && nc != 0) \
+      { \
+        r.resize (nr, nc); \
+ \
+	if (xisnan (s)) \
+	  gripe_nan_to_logical_conversion (); \
+	else \
+	  { \
+ \
+	    for (octave_idx_type j = 0; j < nc; j++) \
+	      for (octave_idx_type i = 0; i < nr; i++) \
+		if (xisnan (m.elem(i, j))) \
+		  { \
+		    gripe_nan_to_logical_conversion (); \
+		    return r; \
+		  } \
+		else \
+		  r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \
+	    } \
+      } \
+ \
+    return r; \
+  }
+
+#define MS_BOOL_OPS2(M, S, LHS_ZERO, RHS_ZERO) \
+  MS_BOOL_OP (mx_el_and, &&, M, S, LHS_ZERO, RHS_ZERO) \
+  MS_BOOL_OP (mx_el_or,  ||, M, S, LHS_ZERO, RHS_ZERO)
+
+#define MS_BOOL_OPS(M, S, ZERO) \
+  MS_BOOL_OPS2(M, S, ZERO, ZERO)
+
+// scalar by matrix operations.
+
+#define SM_BIN_OP(R, OP, S, M, F) \
+  R \
+  OP (const S& s, const M& m) \
+  { \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    R r (nr, nc); \
+ \
+    if (nr > 0 && nc > 0) \
+      F ## _sv (r.fortran_vec (), s, m.data (), nr * nc); \
+ \
+    return r; \
+  }
+
+#define SM_BIN_OPS(R, S, M) \
+  SM_BIN_OP (R, operator +, S, M, mx_inline_add) \
+  SM_BIN_OP (R, operator -, S, M, mx_inline_subtract) \
+  SM_BIN_OP (R, operator *, S, M, mx_inline_multiply) \
+  SM_BIN_OP (R, operator /, S, M, mx_inline_divide)
+
+#define SM_CMP_OP(F, OP, S, SC, M, MC) \
+  boolMatrix \
+  F (const S& s, const M& m) \
+  { \
+    boolMatrix r; \
+ \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    r.resize (nr, nc); \
+ \
+    if (nr > 0 && nc > 0) \
+      { \
+        for (octave_idx_type j = 0; j < nc; j++) \
+          for (octave_idx_type i = 0; i < nr; i++) \
+	    r.elem(i, j) = SC (s) OP MC (m.elem(i, j)); \
+      } \
+ \
+    return r; \
+  }
+
+#define SM_CMP_OPS(S, CS, M, CM) \
+  SM_CMP_OP (mx_el_lt, <,  S, CS, M, CM) \
+  SM_CMP_OP (mx_el_le, <=, S, CS, M, CM) \
+  SM_CMP_OP (mx_el_ge, >=, S, CS, M, CM) \
+  SM_CMP_OP (mx_el_gt, >,  S, CS, M, CM) \
+  SM_CMP_OP (mx_el_eq, ==, S,   , M,   ) \
+  SM_CMP_OP (mx_el_ne, !=, S,   , M,   )
+
+#define SM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO) \
+  boolMatrix \
+  F (const S& s, const M& m) \
+  { \
+    boolMatrix r; \
+ \
+    octave_idx_type nr = m.rows (); \
+    octave_idx_type nc = m.cols (); \
+ \
+    if (nr != 0 && nc != 0) \
+      { \
+        r.resize (nr, nc); \
+ \
+	if (xisnan (s)) \
+	  gripe_nan_to_logical_conversion (); \
+	else \
+	  { \
+	    for (octave_idx_type j = 0; j < nc; j++) \
+	      for (octave_idx_type i = 0; i < nr; i++) \
+		if (xisnan (m.elem(i, j))) \
+		  { \
+		    gripe_nan_to_logical_conversion (); \
+		    return r; \
+		  } \
+		else \
+		  r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \
+	  } \
+      } \
+ \
+    return r; \
+  }
+
+#define SM_BOOL_OPS2(S, M, LHS_ZERO, RHS_ZERO) \
+  SM_BOOL_OP (mx_el_and, &&, S, M, LHS_ZERO, RHS_ZERO) \
+  SM_BOOL_OP (mx_el_or,  ||, S, M, LHS_ZERO, RHS_ZERO)
+
+#define SM_BOOL_OPS(S, M, ZERO) \
+  SM_BOOL_OPS2(S, M, ZERO, ZERO)
+
+// matrix by matrix operations.
+
+#define MM_BIN_OP(R, OP, M1, M2, F) \
+  R \
+  OP (const M1& m1, const M2& m2) \
+  { \
+    R r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+      gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \
+    else \
+      { \
+	r.resize (m1_nr, m1_nc); \
+ \
+	if (m1_nr > 0 && m1_nc > 0) \
+	  F ## _vv (r.fortran_vec (), m1.data (), m2.data (), m1_nr * m1_nc); \
+      } \
+ \
+    return r; \
+  }
+
+#define MM_BIN_OPS(R, M1, M2) \
+  MM_BIN_OP (R, operator +, M1, M2, mx_inline_add) \
+  MM_BIN_OP (R, operator -, M1, M2, mx_inline_subtract) \
+  MM_BIN_OP (R, product,    M1, M2, mx_inline_multiply) \
+  MM_BIN_OP (R, quotient,   M1, M2, mx_inline_divide)
+
+#define MM_CMP_OP(F, OP, M1, C1, M2, C2) \
+  boolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    boolMatrix r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	r.resize (m1_nr, m1_nc); \
+ \
+	for (octave_idx_type j = 0; j < m1_nc; j++) \
+	  for (octave_idx_type i = 0; i < m1_nr; i++) \
+	    r.elem(i, j) = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \
+      } \
+    else \
+      gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+ \
+    return r; \
+  }
+
+#define MM_CMP_OPS(M1, C1, M2, C2) \
+  MM_CMP_OP (mx_el_lt, <,  M1, C1, M2, C2) \
+  MM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \
+  MM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \
+  MM_CMP_OP (mx_el_gt, >,  M1, C1, M2, C2) \
+  MM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
+  MM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+
+#define MM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
+  boolMatrix \
+  F (const M1& m1, const M2& m2) \
+  { \
+    boolMatrix r; \
+ \
+    octave_idx_type m1_nr = m1.rows (); \
+    octave_idx_type m1_nc = m1.cols (); \
+ \
+    octave_idx_type m2_nr = m2.rows (); \
+    octave_idx_type m2_nc = m2.cols (); \
+ \
+    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+      { \
+	if (m1_nr != 0 || m1_nc != 0) \
+	  { \
+	    r.resize (m1_nr, m1_nc); \
+ \
+	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+	      for (octave_idx_type i = 0; i < m1_nr; i++) \
+		if (xisnan (m1.elem(i, j)) || xisnan (m2.elem(i, j))) \
+		  { \
+		    gripe_nan_to_logical_conversion (); \
+		    return r; \
+		  } \
+		else \
+		  r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \
+		    OP (m2.elem(i, j) != RHS_ZERO); \
+	  } \
+      } \
+    else \
+      { \
+	if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
+	  gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
+      } \
+ \
+    return r; \
+  }
+
+#define MM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \
+  MM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \
+  MM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO)
+
+#define MM_BOOL_OPS(M1, M2, ZERO) \
+  MM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+
+// N-d matrix by scalar operations.
+
+#define NDS_BIN_OP(R, OP, ND, S, F) \
+  R \
+  OP (const ND& m, const S& s) \
+  { \
+    R r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    if (len > 0) \
+      F ## _vs (r.fortran_vec (), m.data (), len, s); \
+ \
+    return r; \
+  }
+
+#define NDS_BIN_OPS(R, ND, S) \
+  NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \
+  NDS_BIN_OP (R, operator -, ND, S, mx_inline_subtract) \
+  NDS_BIN_OP (R, operator *, ND, S, mx_inline_multiply) \
+  NDS_BIN_OP (R, operator /, ND, S, mx_inline_divide)
+
+#define NDS_CMP_OP(F, OP, ND, NDC, S, SC) \
+  boolNDArray \
+  F (const ND& m, const S& s) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    if (s == S ()) \
+      { \
+        for (octave_idx_type i = 0; i < len; i++) \
+        r.xelem(i) = NDC (m.elem(i)) OP SC (S ()); \
+      } \
+    else \
+      { \
+        for (octave_idx_type i = 0; i < len; i++) \
+          r.xelem(i) = NDC (m.elem(i)) OP SC (s); \
+      } \
+ \
+    return r; \
+  }
+
+#define NDS_CMP_OPS(ND, NDC, S, SC) \
+  NDS_CMP_OP (mx_el_lt, <,  ND, NDC, S, SC) \
+  NDS_CMP_OP (mx_el_le, <=, ND, NDC, S, SC) \
+  NDS_CMP_OP (mx_el_ge, >=, ND, NDC, S, SC) \
+  NDS_CMP_OP (mx_el_gt, >,  ND, NDC, S, SC) \
+  NDS_CMP_OP (mx_el_eq, ==, ND,    , S,   ) \
+  NDS_CMP_OP (mx_el_ne, !=, ND,    , S,   )
+
+#define NDS_CMP_OP1(F, OP, ND, NDC, S, SC, SPEC) \
+  boolNDArray \
+  F (const ND& m, const S& s) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    for (octave_idx_type i = 0; i < len; i++) \
+      r.elem(i) = operator OP <SPEC> (NDC (m.elem(i)), SC (s)); \
+ \
+    return r; \
+  }
+
+#define NDS_CMP_OPS1(ND, NDC, S, SC, SPEC) \
+  NDS_CMP_OP1 (mx_el_lt, <,  ND, NDC, S, SC, SPEC) \
+  NDS_CMP_OP1 (mx_el_le, <=, ND, NDC, S, SC, SPEC) \
+  NDS_CMP_OP1 (mx_el_ge, >=, ND, NDC, S, SC, SPEC) \
+  NDS_CMP_OP1 (mx_el_gt, >,  ND, NDC, S, SC, SPEC) \
+  NDS_CMP_OP1 (mx_el_eq, ==, ND,    , S,   , SPEC) \
+  NDS_CMP_OP1 (mx_el_ne, !=, ND,    , S,   , SPEC)
+
+#define NDS_CMP_OP2(F, OP, ND, NDC, S, SC, SPEC1, SPEC2) \
+  boolNDArray \
+  F (const ND& m, const S& s) \
+  { \
+    boolNDArray r; \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    r.resize (m.dims ()); \
+ \
+    for (octave_idx_type i = 0; i < len; i++) \
+      r.elem(i) = operator OP <SPEC1,SPEC2> (NDC (m.elem(i)), SC (s)); \
+ \
+    return r; \
+  }
+
+#define NDS_CMP_OPS2(ND, NDC, S, SC, SPEC1, SPEC2) \
+  NDS_CMP_OP2 (mx_el_lt, <,  ND, NDC, S, SC, SPEC1, SPEC2) \
+  NDS_CMP_OP2 (mx_el_le, <=, ND, NDC, S, SC, SPEC1, SPEC2) \
+  NDS_CMP_OP2 (mx_el_ge, >=, ND, NDC, S, SC, SPEC1, SPEC2) \
+  NDS_CMP_OP2 (mx_el_gt, >,  ND, NDC, S, SC, SPEC1, SPEC2) \
+  NDS_CMP_OP2 (mx_el_eq, ==, ND,    , S,   , SPEC1, SPEC2) \
+  NDS_CMP_OP2 (mx_el_ne, !=, ND,    , S,   , SPEC1, SPEC2)
+
+#define NDS_BOOL_OP(F, EQ, OP, ND, S, LHS_ZERO, RHS_ZERO) \
+  boolNDArray \
+  F (const ND& m, const S& s) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    if (len > 0) \
+      { \
+	if (xisnan (s)) \
+	  gripe_nan_to_logical_conversion (); \
+	else \
+	  { \
+	    for (octave_idx_type i = 0; i < len; i++) \
+	      if (xisnan (m.elem(i))) \
+		{ \
+		  gripe_nan_to_logical_conversion (); \
+		  return r; \
+		} \
+	      else \
+		r.xelem(i) = (m.elem(i) EQ LHS_ZERO) OP (s != RHS_ZERO); \
+	  } \
+      } \
+ \
+    return r; \
+  }
+
+#define NDS_BOOL_OPS2(ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_and, !=, &&, ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_or,  !=, ||, ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_not_and, ==, &&, ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_not_or,  ==, ||, ND, S, LHS_ZERO, RHS_ZERO)
+
+#define NDS_BOOL_OPS(ND, S, ZERO) \
+  NDS_BOOL_OPS2(ND, S, ZERO, ZERO)
+
+// scalar by N-d matrix operations.
+
+#define SND_BIN_OP(R, OP, S, ND, F) \
+  R \
+  OP (const S& s, const ND& m) \
+  { \
+    R r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    if (len > 0) \
+      F ## _sv (r.fortran_vec (), s, m.data (), len); \
+ \
+    return r; \
+  }
+
+#define SND_BIN_OPS(R, S, ND) \
+  SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \
+  SND_BIN_OP (R, operator -, S, ND, mx_inline_subtract) \
+  SND_BIN_OP (R, operator *, S, ND, mx_inline_multiply) \
+  SND_BIN_OP (R, operator /, S, ND, mx_inline_divide)
+
+#define SND_CMP_OP(F, OP, S, SC, ND, NDC) \
+  boolNDArray \
+  F (const S& s, const ND& m) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    if (s == S ()) \
+      { \
+        for (octave_idx_type i = 0; i < len; i++) \
+        r.xelem(i) = SC (S ()) OP NDC (m.elem(i)); \
+      } \
+    else \
+      { \
+        for (octave_idx_type i = 0; i < len; i++) \
+          r.xelem(i) = SC (s) OP NDC (m.elem(i)); \
+      } \
+ \
+    return r; \
+  }
+
+#define SND_CMP_OPS(S, CS, ND, CND) \
+  SND_CMP_OP (mx_el_lt, <,  S, CS, ND, CND) \
+  SND_CMP_OP (mx_el_le, <=, S, CS, ND, CND) \
+  SND_CMP_OP (mx_el_ge, >=, S, CS, ND, CND) \
+  SND_CMP_OP (mx_el_gt, >,  S, CS, ND, CND) \
+  SND_CMP_OP (mx_el_eq, ==, S,   , ND,    ) \
+  SND_CMP_OP (mx_el_ne, !=, S,   , ND,    )
+
+#define SND_CMP_OP1(F, OP, S, SC, ND, NDC, SPEC) \
+  boolNDArray \
+  F (const S& s, const ND& m) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    for (octave_idx_type i = 0; i < len; i++) \
+      r.elem(i) = operator OP <SPEC> (SC (s), NDC (m.elem(i))); \
+ \
+    return r; \
+  }
+
+#define SND_CMP_OPS1(S, CS, ND, CND, SPEC) \
+  SND_CMP_OP1 (mx_el_lt, <,  S, CS, ND, CND, SPEC) \
+  SND_CMP_OP1 (mx_el_le, <=, S, CS, ND, CND, SPEC) \
+  SND_CMP_OP1 (mx_el_ge, >=, S, CS, ND, CND, SPEC) \
+  SND_CMP_OP1 (mx_el_gt, >,  S, CS, ND, CND, SPEC) \
+  SND_CMP_OP1 (mx_el_eq, ==, S,   , ND,    , SPEC) \
+  SND_CMP_OP1 (mx_el_ne, !=, S,   , ND,    , SPEC)
+
+#define SND_CMP_OP2(F, OP, S, SC, ND, NDC, SPEC1, SPEC2) \
+  boolNDArray \
+  F (const S& s, const ND& m) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    for (octave_idx_type i = 0; i < len; i++) \
+      r.elem(i) = operator OP <SPEC1, SPEC2> (SC (s), NDC (m.elem(i))); \
+ \
+    return r; \
+  }
+
+#define SND_CMP_OPS2(S, CS, ND, CND, SPEC1, SPEC2) \
+  SND_CMP_OP2 (mx_el_lt, <,  S, CS, ND, CND, SPEC1, SPEC2) \
+  SND_CMP_OP2 (mx_el_le, <=, S, CS, ND, CND, SPEC1, SPEC2) \
+  SND_CMP_OP2 (mx_el_ge, >=, S, CS, ND, CND, SPEC1, SPEC2) \
+  SND_CMP_OP2 (mx_el_gt, >,  S, CS, ND, CND, SPEC1, SPEC2) \
+  SND_CMP_OP2 (mx_el_eq, ==, S,   , ND,    , SPEC1, SPEC2) \
+  SND_CMP_OP2 (mx_el_ne, !=, S,   , ND,    , SPEC1, SPEC2)
+
+#define SND_BOOL_OP(F, OP, EQ, S, ND, LHS_ZERO, RHS_ZERO) \
+  boolNDArray \
+  F (const S& s, const ND& m) \
+  { \
+    boolNDArray r (m.dims ()); \
+ \
+    octave_idx_type len = m.length (); \
+ \
+    if (len > 0) \
+      { \
+	if (xisnan (s)) \
+	  gripe_nan_to_logical_conversion (); \
+	else \
+	  { \
+	    for (octave_idx_type i = 0; i < len; i++) \
+	      if (xisnan (m.elem(i))) \
+		{ \
+	          gripe_nan_to_logical_conversion (); \
+		  return r; \
+		} \
+	      else \
+		r.xelem(i) = (s != LHS_ZERO) OP (m.elem(i) EQ RHS_ZERO); \
+	    } \
+      } \
+ \
+    return r; \
+  }
+
+#define SND_BOOL_OPS2(S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_and, &&, !=, S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_or,  ||, !=, S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_and_not, &&, ==, S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_or_not,  ||, ==, S, ND, LHS_ZERO, RHS_ZERO)
+
+#define SND_BOOL_OPS(S, ND, ZERO) \
+  SND_BOOL_OPS2(S, ND, ZERO, ZERO)
+
+// N-d matrix by N-d matrix operations.
+
+#define NDND_BIN_OP(R, OP, ND1, ND2, F) \
+  R \
+  OP (const ND1& m1, const ND2& m2) \
+  { \
+    R r; \
+ \
+    dim_vector m1_dims = m1.dims (); \
+    dim_vector m2_dims = m2.dims (); \
+ \
+    if (m1_dims != m2_dims) \
+      gripe_nonconformant (#OP, m1_dims, m2_dims); \
+    else \
+      { \
+	r = R (m1_dims); \
+ \
+	octave_idx_type len = m1.length (); \
+ \
+	if (len > 0) \
+	  F ## _vv (r.fortran_vec (), m1.data (), m2.data (), len); \
+      } \
+ \
+    return r; \
+  }
+
+#define NDND_BIN_OPS(R, ND1, ND2) \
+  NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \
+  NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_subtract) \
+  NDND_BIN_OP (R, product,    ND1, ND2, mx_inline_multiply) \
+  NDND_BIN_OP (R, quotient,   ND1, ND2, mx_inline_divide)
+
+#define NDND_CMP_OP(F, OP, ND1, C1, ND2, C2) \
+  boolNDArray \
+  F (const ND1& m1, const ND2& m2) \
+  { \
+    boolNDArray r; \
+ \
+    dim_vector m1_dims = m1.dims (); \
+    dim_vector m2_dims = m2.dims (); \
+ \
+    if (m1_dims == m2_dims) \
+      { \
+	r = boolNDArray (m1_dims); \
+ \
+	for (octave_idx_type i = 0; i < m1.length (); i++) \
+	  r.xelem(i) = C1 (m1.elem(i)) OP C2 (m2.elem(i)); \
+      } \
+    else \
+      gripe_nonconformant (#F, m1_dims, m2_dims); \
+ \
+    return r; \
+  }
+
+#define NDND_CMP_OPS(ND1, C1, ND2, C2) \
+  NDND_CMP_OP (mx_el_lt, <,  ND1, C1, ND2, C2) \
+  NDND_CMP_OP (mx_el_le, <=, ND1, C1, ND2, C2) \
+  NDND_CMP_OP (mx_el_ge, >=, ND1, C1, ND2, C2) \
+  NDND_CMP_OP (mx_el_gt, >,  ND1, C1, ND2, C2) \
+  NDND_CMP_OP (mx_el_eq, ==, ND1,   , ND2,   ) \
+  NDND_CMP_OP (mx_el_ne, !=, ND1,   , ND2,   )
+
+#define NDND_BOOL_OP(F, EQ1, OP, EQ2, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  boolNDArray \
+  F (const ND1& m1, const ND2& m2) \
+  { \
+    boolNDArray r; \
+ \
+    dim_vector m1_dims = m1.dims (); \
+    dim_vector m2_dims = m2.dims (); \
+ \
+    if (m1_dims == m2_dims) \
+      { \
+	if (! m1_dims.all_zero ()) \
+	  { \
+	    r = boolNDArray (m1_dims); \
+ \
+	    for (octave_idx_type i = 0; i < m1.length (); i++) \
+	      if (xisnan (m1.elem(i)) || xisnan (m2.elem(i))) \
+		{ \
+	          gripe_nan_to_logical_conversion (); \
+		  return r; \
+		} \
+	      else \
+		r.xelem(i) = (m1.elem(i) EQ1 LHS_ZERO) OP (m2.elem(i) EQ2 RHS_ZERO); \
+	  } \
+      } \
+    else \
+      gripe_nonconformant (#F, m1_dims, m2_dims); \
+ \
+    return r; \
+  }
+
+#define NDND_BOOL_OPS2(ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_and, !=, &&, !=, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_or,  !=, ||, !=, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_and_not, != , &&, ==, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_or_not, !=, ||, ==, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_not_and, ==, &&, !=, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_not_or,  ==, ||, !=, ND1, ND2, LHS_ZERO, RHS_ZERO)
+
+#define NDND_BOOL_OPS(ND1, ND2, ZERO) \
+  NDND_BOOL_OPS2(ND1, ND2, ZERO, ZERO)
+
+// scalar by diagonal matrix operations.
+
+#define SDM_BIN_OP(R, OP, S, DM, OPEQ) \
+  R \
+  OP (const S& s, const DM& dm) \
+  { \
+    octave_idx_type nr = dm.rows (); \
+    octave_idx_type nc = dm.cols (); \
+ \
+    R r (nr, nc, s); \
+ \
+    for (octave_idx_type i = 0; i < dm.length (); i++) \
+      r.elem(i, i) OPEQ dm.elem(i, i); \
+ \
+    return r; \
+}
+
+#define SDM_BIN_OPS(R, S, DM) \
+  SDM_BIN_OP (R, operator +, S, DM, +=) \
+  SDM_BIN_OP (R, operator -, S, DM, -=)
+
+// diagonal matrix by scalar operations.
+
+#define DMS_BIN_OP(R, OP, DM, S, SGN) \
+  R \
+  OP (const DM& dm, const S& s) \
+  { \
+    octave_idx_type nr = dm.rows (); \
+    octave_idx_type nc = dm.cols (); \
+ \
+    R r (nr, nc, SGN s); \
+ \
+    for (octave_idx_type i = 0; i < dm.length (); i++) \
+      r.elem(i, i) += dm.elem(i, i); \
+ \
+    return r; \
+  }
+
+#define DMS_BIN_OPS(R, DM, S) \
+  DMS_BIN_OP (R, operator +, DM, S, ) \
+  DMS_BIN_OP (R, operator -, DM, S, -)
+
+// matrix by diagonal matrix operations.
+
+#define MDM_BIN_OP(R, OP, M, DM, OPEQ) \
+R \
+OP (const M& m, const DM& dm) \
+{ \
+  R r; \
+ \
+  octave_idx_type m_nr = m.rows (); \
+  octave_idx_type m_nc = m.cols (); \
+ \
+  octave_idx_type dm_nr = dm.rows (); \
+  octave_idx_type dm_nc = dm.cols (); \
+ \
+  if (m_nr != dm_nr || m_nc != dm_nc) \
+    gripe_nonconformant (#OP, m_nr, m_nc, dm_nr, dm_nc); \
+  else \
+    { \
+      r.resize (m_nr, m_nc); \
+ \
+      if (m_nr > 0 && m_nc > 0) \
+	{ \
+	  r = R (m); \
+ \
+	  octave_idx_type len = dm.length (); \
+ \
+	  for (octave_idx_type i = 0; i < len; i++) \
+	    r.elem(i, i) OPEQ dm.elem(i, i); \
+	} \
+    } \
+ \
+  return r; \
+}
+
+#define MDM_MULTIPLY_OP(R, M, DM, R_ZERO) \
+R \
+operator * (const M& m, const DM& dm) \
+{ \
+  R r; \
+ \
+  octave_idx_type m_nr = m.rows (); \
+  octave_idx_type m_nc = m.cols (); \
+ \
+  octave_idx_type dm_nr = dm.rows (); \
+  octave_idx_type dm_nc = dm.cols (); \
+ \
+  if (m_nc != dm_nr) \
+    gripe_nonconformant ("operator *", m_nr, m_nc, dm_nr, dm_nc); \
+  else \
+    { \
+      r = R (m_nr, dm_nc); \
+      R::element_type *rd = r.fortran_vec (); \
+      const M::element_type *md = m.data (); \
+      const DM::element_type *dd = dm.data (); \
+ \
+      octave_idx_type len = dm.length (); \
+      for (octave_idx_type i = 0; i < len; i++) \
+        { \
+          mx_inline_multiply_vs (rd, md, m_nr, dd[i]); \
+          rd += m_nr; md += m_nr; \
+        } \
+      mx_inline_fill_vs (rd, m_nr * (dm_nc - len), R_ZERO); \
+    } \
+ \
+  return r; \
+}
+
+#define MDM_BIN_OPS(R, M, DM, R_ZERO) \
+  MDM_BIN_OP (R, operator +, M, DM, +=) \
+  MDM_BIN_OP (R, operator -, M, DM, -=) \
+  MDM_MULTIPLY_OP (R, M, DM, R_ZERO)
+
+// diagonal matrix by matrix operations.
+
+#define DMM_BIN_OP(R, OP, DM, M, OPEQ, PREOP) \
+R \
+OP (const DM& dm, const M& m) \
+{ \
+  R r; \
+ \
+  octave_idx_type dm_nr = dm.rows (); \
+  octave_idx_type dm_nc = dm.cols (); \
+ \
+  octave_idx_type m_nr = m.rows (); \
+  octave_idx_type m_nc = m.cols (); \
+ \
+  if (dm_nr != m_nr || dm_nc != m_nc) \
+    gripe_nonconformant (#OP, dm_nr, dm_nc, m_nr, m_nc); \
+  else \
+    { \
+      if (m_nr > 0 && m_nc > 0) \
+	{ \
+	  r = R (PREOP m); \
+ \
+	  octave_idx_type len = dm.length (); \
+ \
+	  for (octave_idx_type i = 0; i < len; i++) \
+	    r.elem(i, i) OPEQ dm.elem(i, i); \
+	} \
+      else \
+	r.resize (m_nr, m_nc); \
+    } \
+ \
+  return r; \
+}
+
+#define DMM_MULTIPLY_OP(R, DM, M, R_ZERO) \
+R \
+operator * (const DM& dm, const M& m) \
+{ \
+  R r; \
+ \
+  octave_idx_type dm_nr = dm.rows (); \
+  octave_idx_type dm_nc = dm.cols (); \
+ \
+  octave_idx_type m_nr = m.rows (); \
+  octave_idx_type m_nc = m.cols (); \
+ \
+  if (dm_nc != m_nr) \
+    gripe_nonconformant ("operator *", dm_nr, dm_nc, m_nr, m_nc); \
+  else \
+    { \
+      r = R (dm_nr, m_nc); \
+      R::element_type *rd = r.fortran_vec (); \
+      const M::element_type *md = m.data (); \
+      const DM::element_type *dd = dm.data (); \
+ \
+      octave_idx_type len = dm.length (); \
+      for (octave_idx_type i = 0; i < m_nc; i++) \
+        { \
+          mx_inline_multiply_vv (rd, md, dd, len); \
+          rd += len; md += m_nr; \
+          mx_inline_fill_vs (rd, dm_nr - len, R_ZERO); \
+          rd += dm_nr - len; \
+        } \
+    } \
+ \
+  return r; \
+}
+
+#define DMM_BIN_OPS(R, DM, M, R_ZERO) \
+  DMM_BIN_OP (R, operator +, DM, M, +=, ) \
+  DMM_BIN_OP (R, operator -, DM, M, +=, -) \
+  DMM_MULTIPLY_OP (R, DM, M, R_ZERO)
+
+// diagonal matrix by diagonal matrix operations.
+
+#define DMDM_BIN_OP(R, OP, DM1, DM2, F) \
+  R \
+  OP (const DM1& dm1, const DM2& dm2) \
+  { \
+    R r; \
+ \
+    octave_idx_type dm1_nr = dm1.rows (); \
+    octave_idx_type dm1_nc = dm1.cols (); \
+ \
+    octave_idx_type dm2_nr = dm2.rows (); \
+    octave_idx_type dm2_nc = dm2.cols (); \
+ \
+    if (dm1_nr != dm2_nr || dm1_nc != dm2_nc) \
+      gripe_nonconformant (#OP, dm1_nr, dm1_nc, dm2_nr, dm2_nc); \
+    else \
+      { \
+	r.resize (dm1_nr, dm1_nc); \
+ \
+	if (dm1_nr > 0 && dm1_nc > 0) \
+	  F ## _vv (r.fortran_vec (), dm1.data (), dm2.data (), \
+		    dm1.length ()); \
+      } \
+ \
+    return r; \
+  }
+
+#define DMDM_BIN_OPS(R, DM1, DM2) \
+  DMDM_BIN_OP (R, operator +, DM1, DM2, mx_inline_add) \
+  DMDM_BIN_OP (R, operator -, DM1, DM2, mx_inline_subtract) \
+  DMDM_BIN_OP (R, product,    DM1, DM2, mx_inline_multiply)
+
+// scalar by N-d array min/max ops
+
+#define SND_MINMAX_FCN(FCN, OP, T) \
+T ## NDArray \
+FCN (octave_ ## T d, const T ## NDArray& m) \
+{ \
+  dim_vector dv = m.dims (); \
+  octave_idx_type nel = dv.numel (); \
+\
+  if (nel == 0)	\
+    return T ## NDArray (dv); \
+\
+  T ## NDArray result (dv); \
+\
+  for (octave_idx_type i = 0; i < nel; i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = d OP m (i) ? d : m(i); \
+    } \
+\
+  return result; \
+}
+
+#define NDS_MINMAX_FCN(FCN, OP, T) \
+T ## NDArray \
+FCN (const T ## NDArray& m, octave_ ## T d) \
+{ \
+  dim_vector dv = m.dims (); \
+  octave_idx_type nel = dv.numel (); \
+\
+  if (nel == 0)	\
+    return T ## NDArray (dv); \
+\
+  T ## NDArray result (dv); \
+\
+  for (octave_idx_type i = 0; i < nel; i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = m (i) OP d ? m(i) : d; \
+    } \
+\
+  return result; \
+}
+
+#define NDND_MINMAX_FCN(FCN, OP, T) \
+T ## NDArray \
+FCN (const T ## NDArray& a, const T ## NDArray& b) \
+{ \
+  dim_vector dv = a.dims (); \
+  octave_idx_type nel = dv.numel (); \
+\
+  if (dv != b.dims ()) \
+    { \
+      (*current_liboctave_error_handler) \
+	("two-arg min expecting args of same size"); \
+      return T ## NDArray (); \
+    } \
+\
+  if (nel == 0)	\
+    return T ## NDArray (dv); \
+\
+  T ## NDArray result (dv); \
+\
+  for (octave_idx_type i = 0; i < nel; i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = a(i) OP b(i) ? a(i) : b(i); \
+    } \
+\
+  return result; \
+}
+
+#define MINMAX_FCNS(T) \
+  SND_MINMAX_FCN (min, <, T) \
+  NDS_MINMAX_FCN (min, <, T) \
+  NDND_MINMAX_FCN (min, <, T) \
+  SND_MINMAX_FCN (max, >, T) \
+  NDS_MINMAX_FCN (max, >, T) \
+  NDND_MINMAX_FCN (max, >, T)
+
+// permutation matrix by matrix ops and vice versa
+
+#define PMM_MULTIPLY_OP(PM, M) \
+M operator * (const PM& p, const M& x) \
+{ \
+  octave_idx_type nr = x.rows (), nc = x.columns (); \
+  M result; \
+  if (p.columns () != nr) \
+    gripe_nonconformant ("operator *", p.rows (), p.columns (), nr, nc); \
+  else \
+    { \
+      if (p.is_col_perm ()) \
+        { \
+          result = M (nr, nc); \
+          result.assign (p.pvec (), idx_vector::colon, x); \
+        } \
+      else \
+        result = x.index (p.pvec (), idx_vector::colon); \
+    } \
+  \
+  return result; \
+}
+
+#define MPM_MULTIPLY_OP(M, PM) \
+M operator * (const M& x, const PM& p) \
+{ \
+  octave_idx_type nr = x.rows (), nc = x.columns (); \
+  M result; \
+  if (p.rows () != nc) \
+    gripe_nonconformant ("operator *", nr, nc, p.rows (), p.columns ()); \
+  else \
+    { \
+      if (p.is_col_perm ()) \
+        result = x.index (idx_vector::colon, p.pvec ()); \
+      else \
+        { \
+          result = M (nr, nc); \
+          result.assign (idx_vector::colon, p.pvec (), x); \
+        } \
+    } \
+  \
+  return result; \
+}
+
+#define PMM_BIN_OPS(R, PM, M) \
+  PMM_MULTIPLY_OP(PM, M);
+
+#define MPM_BIN_OPS(R, M, PM) \
+  MPM_MULTIPLY_OP(M, PM);
+
+#define NDND_MAPPER_BODY(R, NAME) \
+  R retval (dims ()); \
+  octave_idx_type n = numel (); \
+  for (octave_idx_type i = 0; i < n; i++) \
+    retval.xelem (i) = NAME (elem (i)); \
+  return retval;
+
+#endif
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/mx-ops b/liboctave/mx-ops
new file mode 100644
index 0000000..f019860
--- /dev/null
+++ b/liboctave/mx-ops
@@ -0,0 +1,443 @@
+# Copyright (C) 2003, 2004, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# types
+#
+# key typename object-type header fwd-decl-ok scalar-zero core-type
+#
+# object-type is one of
+#
+#   S:  scalar
+#   M:  matrix
+#   DM: diagonal matrix
+#   ND: N-d array
+#   FS:  scalar
+#   FM:  matrix
+#   FDM: diagonal matrix
+#   FND: N-d array
+#
+# core-type is only used for the octave_int types, and is the template
+# parameter: octave_int8 is octave_int<int8_t>
+#
+x NONE NONE NONE NO 0
+b bool S NONE NO false
+bm boolMatrix ND boolMatrix.h YES false
+bnda boolNDArray ND boolNDArray.h YES false
+cdm ComplexDiagMatrix DM CDiagMatrix.h YES 0.0
+cm ComplexMatrix M CMatrix.h YES 0.0
+cnda ComplexNDArray ND CNDArray.h YES 0.0
+cs Complex S oct-cmplx.h NO 0.0
+dm DiagMatrix DM dDiagMatrix.h YES 0.0
+m Matrix M dMatrix.h YES 0.0
+nda NDArray ND dNDArray.h YES 0.0
+s double S NONE NO 0.0
+fcdm FloatComplexDiagMatrix DM fCDiagMatrix.h YES static_cast<float>(0.0)
+fcm FloatComplexMatrix M fCMatrix.h YES static_cast<float>(0.0)
+fcnda FloatComplexNDArray ND fCNDArray.h YES static_cast<float>(0.0)
+fcs FloatComplex S oct-cmplx.h NO static_cast<float>(0.0)
+fdm FloatDiagMatrix DM fDiagMatrix.h YES static_cast<float>(0.0)
+fm FloatMatrix M fMatrix.h YES static_cast<float>(0.0)
+fnda FloatNDArray ND fNDArray.h YES static_cast<float>(0.0)
+fs float S NONE NO static_cast<float>(0.0)
+i8 octave_int8 S oct-inttypes.h YES octave_int8::zero int8_t
+ui8 octave_uint8 S oct-inttypes.h YES octave_uint8::zero uint8_t
+i16 octave_int16 S oct-inttypes.h YES octave_int16::zero int16_t
+ui16 octave_uint16 S oct-inttypes.h YES octave_uint16::zero uint16_t
+i32 octave_int32 S oct-inttypes.h YES octave_int32::zero int32_t
+ui32 octave_uint32 S oct-inttypes.h YES octave_uint32::zero uint32_t
+i64 octave_int64 S oct-inttypes.h YES octave_int64::zero int64_t
+ui64 octave_uint64 S oct-inttypes.h YES octave_uint64::zero uint64_t
+i8nda int8NDArray ND int8NDArray.h YES octave_int8::zero int8_t
+ui8nda uint8NDArray ND uint8NDArray.h YES octave_uint8::zero uint8_t
+i16nda int16NDArray ND int16NDArray.h YES octave_int16::zero int16_t
+ui16nda uint16NDArray ND uint16NDArray.h YES octave_uint16::zero uint16_t
+i32nda int32NDArray ND int32NDArray.h YES octave_int32::zero int32_t
+ui32nda uint32NDArray ND uint32NDArray.h YES octave_uint32::zero uint32_t
+i64nda int64NDArray ND int64NDArray.h YES octave_int64::zero int64_t
+ui64nda uint64NDArray ND uint64NDArray.h YES octave_uint64::zero uint64_t
+pm PermMatrix PM PermMatrix.h YES static_cast<octave_idx_type>(0)
+# ops
+# result_t lhs_t rhs_t op-type lhs_conv rhs_conv headers ...
+#
+# op-type is one of
+#
+#  B: binary ops, + - * /
+#  C: comparison ops, < <= == != >= >
+#  L: logical ops, & |
+#
+cdm cdm dm B
+cdm dm cdm B
+cm cs cdm B
+cm cs dm B
+cm cs m BCL real NONE boolMatrix.h
+cnda cs nda BCL real NONE boolMatrix.h boolNDArray.h
+cm cdm cs B
+cm cdm cm B
+cm cdm m B
+cm cdm s B
+cm cm cdm B
+cm cm dm B
+cm cm m BCL real NONE boolMatrix.h
+cnda cnda nda BCL real NONE boolMatrix.h boolNDArray.h
+cm cm s BCL real NONE boolMatrix.h
+cnda cnda s BCL real NONE boolMatrix.h boolNDArray.h
+cm dm cs B
+cm dm cm B
+cm m cs BCL NONE real boolMatrix.h
+cnda nda cs BCL NONE real boolMatrix.h boolNDArray.h
+cm m cdm B
+cm m cm BCL NONE real boolMatrix.h
+cnda nda cnda BCL NONE real boolMatrix.h boolNDArray.h
+cm s cdm B
+cm s cm BCL NONE real boolMatrix.h
+cnda s cnda BCL NONE real boolMatrix.h boolNDArray.h
+m dm m B
+m dm s B
+m m dm B
+m s dm B
+#
+fcdm fcdm fdm B
+fcdm fdm fcdm B
+fcm fcs fcdm B
+fcm fcs fdm B
+fcm fcs fm BCL real NONE boolMatrix.h
+fcnda fcs fnda BCL real NONE boolMatrix.h boolNDArray.h
+fcm fcdm fcs B
+fcm fcdm fcm B
+fcm fcdm fm B
+fcm fcdm fs B
+fcm fcm fcdm B
+fcm fcm fdm B
+fcm fcm fm BCL real NONE boolMatrix.h
+fcnda fcnda fnda BCL real NONE boolMatrix.h boolNDArray.h
+fcm fcm fs BCL real NONE boolMatrix.h
+fcnda fcnda fs BCL real NONE boolMatrix.h boolNDArray.h
+fcm fdm fcs B
+fcm fdm fcm B
+fcm fm fcs BCL NONE real boolMatrix.h
+fcnda fnda fcs BCL NONE real boolMatrix.h boolNDArray.h
+fcm fm fcdm B
+fcm fm fcm BCL NONE real boolMatrix.h
+fcnda fnda fcnda BCL NONE real boolMatrix.h boolNDArray.h
+fcm fs fcdm B
+fcm fs fcm BCL NONE real boolMatrix.h
+fcnda fs fcnda BCL NONE real boolMatrix.h boolNDArray.h
+fm fdm fm B
+fm fdm fs B
+fm fm fdm B
+fm fs fdm B
+#
+m pm m B
+m m pm B
+cm pm cm B
+cm cm pm B
+fm pm fm B
+fm fm pm B
+fcm pm fcm B
+fcm fcm pm B
+#
+i8nda s i8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda i8nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda s ui8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda ui8nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda s i16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda i16nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda s ui16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda ui16nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda s i32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda i32nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda s ui32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda ui32nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda s i64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda i64nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda s ui64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda ui64nda s BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda fs i8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda i8nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda fs ui8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda ui8nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda fs i16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda i16nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda fs ui16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda ui16nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda fs i32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda i32nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda fs ui32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda ui32nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda fs i64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda i64nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda fs ui64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda ui64nda fs BCL NONE NONE boolMatrix.h boolNDArray.h
+#
+i8nda nda i8 BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda i8 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda nda ui8 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda ui8 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda nda i16 BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda i16 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda nda ui16 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda ui16 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda nda i32 BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda i32 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda nda ui32 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda ui32 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda nda i64 BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda i64 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda nda ui64 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda ui64 nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda fnda i8 BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda i8 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda fnda ui8 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda ui8 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda fnda i16 BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda i16 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda fnda ui16 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda ui16 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda fnda i32 BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda i32 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda fnda ui32 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda ui32 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda fnda i64 BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda i64 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda fnda ui64 BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda ui64 fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+#
+i8nda nda i8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda i8nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda nda ui8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda ui8nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda nda i16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda i16nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda nda ui16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda ui16nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda nda i32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda i32nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda nda ui32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda ui32nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda nda i64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda i64nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda nda ui64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda ui64nda nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda fnda i8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i8nda i8nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda fnda ui8nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui8nda ui8nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda fnda i16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i16nda i16nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda fnda ui16nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui16nda ui16nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda fnda i32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i32nda i32nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda fnda ui32nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui32nda ui32nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda fnda i64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+i64nda i64nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda fnda ui64nda BCL NONE NONE boolMatrix.h boolNDArray.h
+ui64nda ui64nda fnda BCL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i8nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i16nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i32nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i64nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui8nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui16nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui32nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda ui64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui64nda i8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda ui8 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda i16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda ui16 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda i32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda ui32 CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda i64 CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i8 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i16 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i32 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i64 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui8 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui16 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui32 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32 ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui64 i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64 ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64 i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64 ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64 i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64 ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64 i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i8nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i8nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i16nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i16nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i32nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i32nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x i64nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x i64nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui8nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui8nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui16nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui16nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui32nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui32nda ui64nda CL NONE NONE boolMatrix.h boolNDArray.h
+#
+x ui64nda i8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda ui8nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda i16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda ui16nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda i32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda ui32nda CL NONE NONE boolMatrix.h boolNDArray.h
+x ui64nda i64nda CL NONE NONE boolMatrix.h boolNDArray.h
diff --git a/liboctave/mx-ops.h b/liboctave/mx-ops.h
new file mode 100644
index 0000000..31aa1cb
--- /dev/null
+++ b/liboctave/mx-ops.h
@@ -0,0 +1,336 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ops_h)
+#define octave_mx_ops_h 1
+#include "mx-cdm-dm.h"
+#include "mx-dm-cdm.h"
+#include "mx-cs-cdm.h"
+#include "mx-cs-dm.h"
+#include "mx-cs-m.h"
+#include "mx-cs-nda.h"
+#include "mx-cdm-cs.h"
+#include "mx-cdm-cm.h"
+#include "mx-cdm-m.h"
+#include "mx-cdm-s.h"
+#include "mx-cm-cdm.h"
+#include "mx-cm-dm.h"
+#include "mx-cm-m.h"
+#include "mx-cnda-nda.h"
+#include "mx-cm-s.h"
+#include "mx-cnda-s.h"
+#include "mx-dm-cs.h"
+#include "mx-dm-cm.h"
+#include "mx-m-cs.h"
+#include "mx-nda-cs.h"
+#include "mx-m-cdm.h"
+#include "mx-m-cm.h"
+#include "mx-nda-cnda.h"
+#include "mx-s-cdm.h"
+#include "mx-s-cm.h"
+#include "mx-s-cnda.h"
+#include "mx-dm-m.h"
+#include "mx-dm-s.h"
+#include "mx-m-dm.h"
+#include "mx-s-dm.h"
+#include "mx-fcdm-fdm.h"
+#include "mx-fdm-fcdm.h"
+#include "mx-fcs-fcdm.h"
+#include "mx-fcs-fdm.h"
+#include "mx-fcs-fm.h"
+#include "mx-fcs-fnda.h"
+#include "mx-fcdm-fcs.h"
+#include "mx-fcdm-fcm.h"
+#include "mx-fcdm-fm.h"
+#include "mx-fcdm-fs.h"
+#include "mx-fcm-fcdm.h"
+#include "mx-fcm-fdm.h"
+#include "mx-fcm-fm.h"
+#include "mx-fcnda-fnda.h"
+#include "mx-fcm-fs.h"
+#include "mx-fcnda-fs.h"
+#include "mx-fdm-fcs.h"
+#include "mx-fdm-fcm.h"
+#include "mx-fm-fcs.h"
+#include "mx-fnda-fcs.h"
+#include "mx-fm-fcdm.h"
+#include "mx-fm-fcm.h"
+#include "mx-fnda-fcnda.h"
+#include "mx-fs-fcdm.h"
+#include "mx-fs-fcm.h"
+#include "mx-fs-fcnda.h"
+#include "mx-fdm-fm.h"
+#include "mx-fdm-fs.h"
+#include "mx-fm-fdm.h"
+#include "mx-fs-fdm.h"
+#include "mx-pm-m.h"
+#include "mx-m-pm.h"
+#include "mx-pm-cm.h"
+#include "mx-cm-pm.h"
+#include "mx-pm-fm.h"
+#include "mx-fm-pm.h"
+#include "mx-pm-fcm.h"
+#include "mx-fcm-pm.h"
+#include "mx-s-i8nda.h"
+#include "mx-i8nda-s.h"
+#include "mx-s-ui8nda.h"
+#include "mx-ui8nda-s.h"
+#include "mx-s-i16nda.h"
+#include "mx-i16nda-s.h"
+#include "mx-s-ui16nda.h"
+#include "mx-ui16nda-s.h"
+#include "mx-s-i32nda.h"
+#include "mx-i32nda-s.h"
+#include "mx-s-ui32nda.h"
+#include "mx-ui32nda-s.h"
+#include "mx-s-i64nda.h"
+#include "mx-i64nda-s.h"
+#include "mx-s-ui64nda.h"
+#include "mx-ui64nda-s.h"
+#include "mx-fs-i8nda.h"
+#include "mx-i8nda-fs.h"
+#include "mx-fs-ui8nda.h"
+#include "mx-ui8nda-fs.h"
+#include "mx-fs-i16nda.h"
+#include "mx-i16nda-fs.h"
+#include "mx-fs-ui16nda.h"
+#include "mx-ui16nda-fs.h"
+#include "mx-fs-i32nda.h"
+#include "mx-i32nda-fs.h"
+#include "mx-fs-ui32nda.h"
+#include "mx-ui32nda-fs.h"
+#include "mx-fs-i64nda.h"
+#include "mx-i64nda-fs.h"
+#include "mx-fs-ui64nda.h"
+#include "mx-ui64nda-fs.h"
+#include "mx-nda-i8.h"
+#include "mx-i8-nda.h"
+#include "mx-nda-ui8.h"
+#include "mx-ui8-nda.h"
+#include "mx-nda-i16.h"
+#include "mx-i16-nda.h"
+#include "mx-nda-ui16.h"
+#include "mx-ui16-nda.h"
+#include "mx-nda-i32.h"
+#include "mx-i32-nda.h"
+#include "mx-nda-ui32.h"
+#include "mx-ui32-nda.h"
+#include "mx-nda-i64.h"
+#include "mx-i64-nda.h"
+#include "mx-nda-ui64.h"
+#include "mx-ui64-nda.h"
+#include "mx-fnda-i8.h"
+#include "mx-i8-fnda.h"
+#include "mx-fnda-ui8.h"
+#include "mx-ui8-fnda.h"
+#include "mx-fnda-i16.h"
+#include "mx-i16-fnda.h"
+#include "mx-fnda-ui16.h"
+#include "mx-ui16-fnda.h"
+#include "mx-fnda-i32.h"
+#include "mx-i32-fnda.h"
+#include "mx-fnda-ui32.h"
+#include "mx-ui32-fnda.h"
+#include "mx-fnda-i64.h"
+#include "mx-i64-fnda.h"
+#include "mx-fnda-ui64.h"
+#include "mx-ui64-fnda.h"
+#include "mx-nda-i8nda.h"
+#include "mx-i8nda-nda.h"
+#include "mx-nda-ui8nda.h"
+#include "mx-ui8nda-nda.h"
+#include "mx-nda-i16nda.h"
+#include "mx-i16nda-nda.h"
+#include "mx-nda-ui16nda.h"
+#include "mx-ui16nda-nda.h"
+#include "mx-nda-i32nda.h"
+#include "mx-i32nda-nda.h"
+#include "mx-nda-ui32nda.h"
+#include "mx-ui32nda-nda.h"
+#include "mx-nda-i64nda.h"
+#include "mx-i64nda-nda.h"
+#include "mx-nda-ui64nda.h"
+#include "mx-ui64nda-nda.h"
+#include "mx-fnda-i8nda.h"
+#include "mx-i8nda-fnda.h"
+#include "mx-fnda-ui8nda.h"
+#include "mx-ui8nda-fnda.h"
+#include "mx-fnda-i16nda.h"
+#include "mx-i16nda-fnda.h"
+#include "mx-fnda-ui16nda.h"
+#include "mx-ui16nda-fnda.h"
+#include "mx-fnda-i32nda.h"
+#include "mx-i32nda-fnda.h"
+#include "mx-fnda-ui32nda.h"
+#include "mx-ui32nda-fnda.h"
+#include "mx-fnda-i64nda.h"
+#include "mx-i64nda-fnda.h"
+#include "mx-fnda-ui64nda.h"
+#include "mx-ui64nda-fnda.h"
+#include "mx-i8nda-ui8.h"
+#include "mx-i8nda-i16.h"
+#include "mx-i8nda-ui16.h"
+#include "mx-i8nda-i32.h"
+#include "mx-i8nda-ui32.h"
+#include "mx-i8nda-i64.h"
+#include "mx-i8nda-ui64.h"
+#include "mx-i16nda-i8.h"
+#include "mx-i16nda-ui8.h"
+#include "mx-i16nda-ui16.h"
+#include "mx-i16nda-i32.h"
+#include "mx-i16nda-ui32.h"
+#include "mx-i16nda-i64.h"
+#include "mx-i16nda-ui64.h"
+#include "mx-i32nda-i8.h"
+#include "mx-i32nda-ui8.h"
+#include "mx-i32nda-i16.h"
+#include "mx-i32nda-ui16.h"
+#include "mx-i32nda-ui32.h"
+#include "mx-i32nda-i64.h"
+#include "mx-i32nda-ui64.h"
+#include "mx-i64nda-i8.h"
+#include "mx-i64nda-ui8.h"
+#include "mx-i64nda-i16.h"
+#include "mx-i64nda-ui16.h"
+#include "mx-i64nda-i32.h"
+#include "mx-i64nda-ui32.h"
+#include "mx-i64nda-ui64.h"
+#include "mx-ui8nda-i8.h"
+#include "mx-ui8nda-i16.h"
+#include "mx-ui8nda-ui16.h"
+#include "mx-ui8nda-i32.h"
+#include "mx-ui8nda-ui32.h"
+#include "mx-ui8nda-i64.h"
+#include "mx-ui8nda-ui64.h"
+#include "mx-ui16nda-i8.h"
+#include "mx-ui16nda-ui8.h"
+#include "mx-ui16nda-i16.h"
+#include "mx-ui16nda-i32.h"
+#include "mx-ui16nda-ui32.h"
+#include "mx-ui16nda-i64.h"
+#include "mx-ui16nda-ui64.h"
+#include "mx-ui32nda-i8.h"
+#include "mx-ui32nda-ui8.h"
+#include "mx-ui32nda-i16.h"
+#include "mx-ui32nda-ui16.h"
+#include "mx-ui32nda-i32.h"
+#include "mx-ui32nda-i64.h"
+#include "mx-ui32nda-ui64.h"
+#include "mx-ui64nda-i8.h"
+#include "mx-ui64nda-ui8.h"
+#include "mx-ui64nda-i16.h"
+#include "mx-ui64nda-ui16.h"
+#include "mx-ui64nda-i32.h"
+#include "mx-ui64nda-ui32.h"
+#include "mx-ui64nda-i64.h"
+#include "mx-i8-ui8nda.h"
+#include "mx-i8-i16nda.h"
+#include "mx-i8-ui16nda.h"
+#include "mx-i8-i32nda.h"
+#include "mx-i8-ui32nda.h"
+#include "mx-i8-i64nda.h"
+#include "mx-i8-ui64nda.h"
+#include "mx-i16-i8nda.h"
+#include "mx-i16-ui8nda.h"
+#include "mx-i16-ui16nda.h"
+#include "mx-i16-i32nda.h"
+#include "mx-i16-ui32nda.h"
+#include "mx-i16-i64nda.h"
+#include "mx-i16-ui64nda.h"
+#include "mx-i32-i8nda.h"
+#include "mx-i32-ui8nda.h"
+#include "mx-i32-i16nda.h"
+#include "mx-i32-ui16nda.h"
+#include "mx-i32-ui32nda.h"
+#include "mx-i32-i64nda.h"
+#include "mx-i32-ui64nda.h"
+#include "mx-i64-i8nda.h"
+#include "mx-i64-ui8nda.h"
+#include "mx-i64-i16nda.h"
+#include "mx-i64-ui16nda.h"
+#include "mx-i64-i32nda.h"
+#include "mx-i64-ui32nda.h"
+#include "mx-i64-ui64nda.h"
+#include "mx-ui8-i8nda.h"
+#include "mx-ui8-i16nda.h"
+#include "mx-ui8-ui16nda.h"
+#include "mx-ui8-i32nda.h"
+#include "mx-ui8-ui32nda.h"
+#include "mx-ui8-i64nda.h"
+#include "mx-ui8-ui64nda.h"
+#include "mx-ui16-i8nda.h"
+#include "mx-ui16-ui8nda.h"
+#include "mx-ui16-i16nda.h"
+#include "mx-ui16-i32nda.h"
+#include "mx-ui16-ui32nda.h"
+#include "mx-ui16-i64nda.h"
+#include "mx-ui16-ui64nda.h"
+#include "mx-ui32-i8nda.h"
+#include "mx-ui32-ui8nda.h"
+#include "mx-ui32-i16nda.h"
+#include "mx-ui32-ui16nda.h"
+#include "mx-ui32-i32nda.h"
+#include "mx-ui32-i64nda.h"
+#include "mx-ui32-ui64nda.h"
+#include "mx-ui64-i8nda.h"
+#include "mx-ui64-ui8nda.h"
+#include "mx-ui64-i16nda.h"
+#include "mx-ui64-ui16nda.h"
+#include "mx-ui64-i32nda.h"
+#include "mx-ui64-ui32nda.h"
+#include "mx-ui64-i64nda.h"
+#include "mx-i8nda-ui8nda.h"
+#include "mx-i8nda-i16nda.h"
+#include "mx-i8nda-ui16nda.h"
+#include "mx-i8nda-i32nda.h"
+#include "mx-i8nda-ui32nda.h"
+#include "mx-i8nda-i64nda.h"
+#include "mx-i8nda-ui64nda.h"
+#include "mx-i16nda-i8nda.h"
+#include "mx-i16nda-ui8nda.h"
+#include "mx-i16nda-ui16nda.h"
+#include "mx-i16nda-i32nda.h"
+#include "mx-i16nda-ui32nda.h"
+#include "mx-i16nda-i64nda.h"
+#include "mx-i16nda-ui64nda.h"
+#include "mx-i32nda-i8nda.h"
+#include "mx-i32nda-ui8nda.h"
+#include "mx-i32nda-i16nda.h"
+#include "mx-i32nda-ui16nda.h"
+#include "mx-i32nda-ui32nda.h"
+#include "mx-i32nda-i64nda.h"
+#include "mx-i32nda-ui64nda.h"
+#include "mx-i64nda-i8nda.h"
+#include "mx-i64nda-ui8nda.h"
+#include "mx-i64nda-i16nda.h"
+#include "mx-i64nda-ui16nda.h"
+#include "mx-i64nda-i32nda.h"
+#include "mx-i64nda-ui32nda.h"
+#include "mx-i64nda-ui64nda.h"
+#include "mx-ui8nda-i8nda.h"
+#include "mx-ui8nda-i16nda.h"
+#include "mx-ui8nda-ui16nda.h"
+#include "mx-ui8nda-i32nda.h"
+#include "mx-ui8nda-ui32nda.h"
+#include "mx-ui8nda-i64nda.h"
+#include "mx-ui8nda-ui64nda.h"
+#include "mx-ui16nda-i8nda.h"
+#include "mx-ui16nda-ui8nda.h"
+#include "mx-ui16nda-i16nda.h"
+#include "mx-ui16nda-i32nda.h"
+#include "mx-ui16nda-ui32nda.h"
+#include "mx-ui16nda-i64nda.h"
+#include "mx-ui16nda-ui64nda.h"
+#include "mx-ui32nda-i8nda.h"
+#include "mx-ui32nda-ui8nda.h"
+#include "mx-ui32nda-i16nda.h"
+#include "mx-ui32nda-ui16nda.h"
+#include "mx-ui32nda-i32nda.h"
+#include "mx-ui32nda-i64nda.h"
+#include "mx-ui32nda-ui64nda.h"
+#include "mx-ui64nda-i8nda.h"
+#include "mx-ui64nda-ui8nda.h"
+#include "mx-ui64nda-i16nda.h"
+#include "mx-ui64nda-ui16nda.h"
+#include "mx-ui64nda-i32nda.h"
+#include "mx-ui64nda-ui32nda.h"
+#include "mx-ui64nda-i64nda.h"
+#endif
diff --git a/liboctave/mx-pm-cm.cc b/liboctave/mx-pm-cm.cc
new file mode 100644
index 0000000..7117798
--- /dev/null
+++ b/liboctave/mx-pm-cm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-pm-cm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "PermMatrix.h"
+PMM_BIN_OPS (ComplexMatrix, PermMatrix, ComplexMatrix)
diff --git a/liboctave/mx-pm-cm.h b/liboctave/mx-pm-cm.h
new file mode 100644
index 0000000..11929e0
--- /dev/null
+++ b/liboctave/mx-pm-cm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_pm_cm_h)
+#define octave_mx_pm_cm_h 1
+#include "CMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+PMM_BIN_OP_DECLS (ComplexMatrix, PermMatrix, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-pm-fcm.cc b/liboctave/mx-pm-fcm.cc
new file mode 100644
index 0000000..2ff888b
--- /dev/null
+++ b/liboctave/mx-pm-fcm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-pm-fcm.h"
+#include "mx-op-defs.h"
+#include "fCMatrix.h"
+#include "PermMatrix.h"
+PMM_BIN_OPS (FloatComplexMatrix, PermMatrix, FloatComplexMatrix)
diff --git a/liboctave/mx-pm-fcm.h b/liboctave/mx-pm-fcm.h
new file mode 100644
index 0000000..fa1586e
--- /dev/null
+++ b/liboctave/mx-pm-fcm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_pm_fcm_h)
+#define octave_mx_pm_fcm_h 1
+#include "fCMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+PMM_BIN_OP_DECLS (FloatComplexMatrix, PermMatrix, FloatComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-pm-fm.cc b/liboctave/mx-pm-fm.cc
new file mode 100644
index 0000000..1ef4c03
--- /dev/null
+++ b/liboctave/mx-pm-fm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-pm-fm.h"
+#include "mx-op-defs.h"
+#include "fMatrix.h"
+#include "PermMatrix.h"
+PMM_BIN_OPS (FloatMatrix, PermMatrix, FloatMatrix)
diff --git a/liboctave/mx-pm-fm.h b/liboctave/mx-pm-fm.h
new file mode 100644
index 0000000..59d75bd
--- /dev/null
+++ b/liboctave/mx-pm-fm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_pm_fm_h)
+#define octave_mx_pm_fm_h 1
+#include "fMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+PMM_BIN_OP_DECLS (FloatMatrix, PermMatrix, FloatMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-pm-m.cc b/liboctave/mx-pm-m.cc
new file mode 100644
index 0000000..d031121
--- /dev/null
+++ b/liboctave/mx-pm-m.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-pm-m.h"
+#include "mx-op-defs.h"
+#include "dMatrix.h"
+#include "PermMatrix.h"
+PMM_BIN_OPS (Matrix, PermMatrix, Matrix)
diff --git a/liboctave/mx-pm-m.h b/liboctave/mx-pm-m.h
new file mode 100644
index 0000000..686762f
--- /dev/null
+++ b/liboctave/mx-pm-m.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_pm_m_h)
+#define octave_mx_pm_m_h 1
+#include "dMatrix.h"
+#include "PermMatrix.h"
+#include "mx-op-decl.h"
+PMM_BIN_OP_DECLS (Matrix, PermMatrix, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-cdm.cc b/liboctave/mx-s-cdm.cc
new file mode 100644
index 0000000..8647993
--- /dev/null
+++ b/liboctave/mx-s-cdm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-cdm.h"
+#include "mx-op-defs.h"
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+SDM_BIN_OPS (ComplexMatrix, double, ComplexDiagMatrix)
diff --git a/liboctave/mx-s-cdm.h b/liboctave/mx-s-cdm.h
new file mode 100644
index 0000000..438b503
--- /dev/null
+++ b/liboctave/mx-s-cdm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_cdm_h)
+#define octave_mx_s_cdm_h 1
+#include "CMatrix.h"
+#include "CDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (ComplexMatrix, double, ComplexDiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-cm.cc b/liboctave/mx-s-cm.cc
new file mode 100644
index 0000000..c09f2f7
--- /dev/null
+++ b/liboctave/mx-s-cm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-cm.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "CMatrix.h"
+SM_BIN_OPS (ComplexMatrix, double, ComplexMatrix)
+SM_CMP_OPS (double, , ComplexMatrix, real)
+SM_BOOL_OPS2 (double, ComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/mx-s-cm.h b/liboctave/mx-s-cm.h
new file mode 100644
index 0000000..4180ec5
--- /dev/null
+++ b/liboctave/mx-s-cm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_cm_h)
+#define octave_mx_s_cm_h 1
+#include "CMatrix.h"
+#include "mx-op-decl.h"
+SM_BIN_OP_DECLS (ComplexMatrix, double, ComplexMatrix, OCTAVE_API)
+SM_CMP_OP_DECLS (double, ComplexMatrix, OCTAVE_API)
+SM_BOOL_OP_DECLS (double, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-cnda.cc b/liboctave/mx-s-cnda.cc
new file mode 100644
index 0000000..7e7fea6
--- /dev/null
+++ b/liboctave/mx-s-cnda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-cnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
+SND_BIN_OPS (ComplexNDArray, double, ComplexNDArray)
+SND_CMP_OPS (double, , ComplexNDArray, real)
+SND_BOOL_OPS2 (double, ComplexNDArray, 0.0, 0.0)
diff --git a/liboctave/mx-s-cnda.h b/liboctave/mx-s-cnda.h
new file mode 100644
index 0000000..542328e
--- /dev/null
+++ b/liboctave/mx-s-cnda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_cnda_h)
+#define octave_mx_s_cnda_h 1
+#include "CNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (ComplexNDArray, double, ComplexNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, ComplexNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, ComplexNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-dm.cc b/liboctave/mx-s-dm.cc
new file mode 100644
index 0000000..39037e4
--- /dev/null
+++ b/liboctave/mx-s-dm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-dm.h"
+#include "mx-op-defs.h"
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+SDM_BIN_OPS (Matrix, double, DiagMatrix)
diff --git a/liboctave/mx-s-dm.h b/liboctave/mx-s-dm.h
new file mode 100644
index 0000000..1dd89ac
--- /dev/null
+++ b/liboctave/mx-s-dm.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_dm_h)
+#define octave_mx_s_dm_h 1
+#include "dMatrix.h"
+#include "dDiagMatrix.h"
+#include "mx-op-decl.h"
+SDM_BIN_OP_DECLS (Matrix, double, DiagMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-i16nda.cc b/liboctave/mx-s-i16nda.cc
new file mode 100644
index 0000000..02d5eab
--- /dev/null
+++ b/liboctave/mx-s-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int16NDArray.h"
+SND_BIN_OPS (int16NDArray, double, int16NDArray)
+SND_CMP_OPS1 (double, , int16NDArray, , int16_t)
+SND_BOOL_OPS2 (double, int16NDArray, 0.0, octave_int16::zero)
diff --git a/liboctave/mx-s-i16nda.h b/liboctave/mx-s-i16nda.h
new file mode 100644
index 0000000..e0a7af9
--- /dev/null
+++ b/liboctave/mx-s-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_i16nda_h)
+#define octave_mx_s_i16nda_h 1
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int16NDArray, double, int16NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-i32nda.cc b/liboctave/mx-s-i32nda.cc
new file mode 100644
index 0000000..4753652
--- /dev/null
+++ b/liboctave/mx-s-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int32NDArray.h"
+SND_BIN_OPS (int32NDArray, double, int32NDArray)
+SND_CMP_OPS1 (double, , int32NDArray, , int32_t)
+SND_BOOL_OPS2 (double, int32NDArray, 0.0, octave_int32::zero)
diff --git a/liboctave/mx-s-i32nda.h b/liboctave/mx-s-i32nda.h
new file mode 100644
index 0000000..62e933e
--- /dev/null
+++ b/liboctave/mx-s-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_i32nda_h)
+#define octave_mx_s_i32nda_h 1
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int32NDArray, double, int32NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-i64nda.cc b/liboctave/mx-s-i64nda.cc
new file mode 100644
index 0000000..7d13a22
--- /dev/null
+++ b/liboctave/mx-s-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int64NDArray.h"
+SND_BIN_OPS (int64NDArray, double, int64NDArray)
+SND_CMP_OPS1 (double, , int64NDArray, , int64_t)
+SND_BOOL_OPS2 (double, int64NDArray, 0.0, octave_int64::zero)
diff --git a/liboctave/mx-s-i64nda.h b/liboctave/mx-s-i64nda.h
new file mode 100644
index 0000000..d0950ce
--- /dev/null
+++ b/liboctave/mx-s-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_i64nda_h)
+#define octave_mx_s_i64nda_h 1
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int64NDArray, double, int64NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-i8nda.cc b/liboctave/mx-s-i8nda.cc
new file mode 100644
index 0000000..77e00ec
--- /dev/null
+++ b/liboctave/mx-s-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "int8NDArray.h"
+SND_BIN_OPS (int8NDArray, double, int8NDArray)
+SND_CMP_OPS1 (double, , int8NDArray, , int8_t)
+SND_BOOL_OPS2 (double, int8NDArray, 0.0, octave_int8::zero)
diff --git a/liboctave/mx-s-i8nda.h b/liboctave/mx-s-i8nda.h
new file mode 100644
index 0000000..dab18c1
--- /dev/null
+++ b/liboctave/mx-s-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_i8nda_h)
+#define octave_mx_s_i8nda_h 1
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (int8NDArray, double, int8NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-ui16nda.cc b/liboctave/mx-s-ui16nda.cc
new file mode 100644
index 0000000..4c865b2
--- /dev/null
+++ b/liboctave/mx-s-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+SND_BIN_OPS (uint16NDArray, double, uint16NDArray)
+SND_CMP_OPS1 (double, , uint16NDArray, , uint16_t)
+SND_BOOL_OPS2 (double, uint16NDArray, 0.0, octave_uint16::zero)
diff --git a/liboctave/mx-s-ui16nda.h b/liboctave/mx-s-ui16nda.h
new file mode 100644
index 0000000..cd9814a
--- /dev/null
+++ b/liboctave/mx-s-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_ui16nda_h)
+#define octave_mx_s_ui16nda_h 1
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint16NDArray, double, uint16NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-ui32nda.cc b/liboctave/mx-s-ui32nda.cc
new file mode 100644
index 0000000..c6a10d6
--- /dev/null
+++ b/liboctave/mx-s-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+SND_BIN_OPS (uint32NDArray, double, uint32NDArray)
+SND_CMP_OPS1 (double, , uint32NDArray, , uint32_t)
+SND_BOOL_OPS2 (double, uint32NDArray, 0.0, octave_uint32::zero)
diff --git a/liboctave/mx-s-ui32nda.h b/liboctave/mx-s-ui32nda.h
new file mode 100644
index 0000000..9c23d8f
--- /dev/null
+++ b/liboctave/mx-s-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_ui32nda_h)
+#define octave_mx_s_ui32nda_h 1
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint32NDArray, double, uint32NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-ui64nda.cc b/liboctave/mx-s-ui64nda.cc
new file mode 100644
index 0000000..173e7df
--- /dev/null
+++ b/liboctave/mx-s-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+SND_BIN_OPS (uint64NDArray, double, uint64NDArray)
+SND_CMP_OPS1 (double, , uint64NDArray, , uint64_t)
+SND_BOOL_OPS2 (double, uint64NDArray, 0.0, octave_uint64::zero)
diff --git a/liboctave/mx-s-ui64nda.h b/liboctave/mx-s-ui64nda.h
new file mode 100644
index 0000000..8451dcd
--- /dev/null
+++ b/liboctave/mx-s-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_ui64nda_h)
+#define octave_mx_s_ui64nda_h 1
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint64NDArray, double, uint64NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-s-ui8nda.cc b/liboctave/mx-s-ui8nda.cc
new file mode 100644
index 0000000..8933ee5
--- /dev/null
+++ b/liboctave/mx-s-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-s-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+SND_BIN_OPS (uint8NDArray, double, uint8NDArray)
+SND_CMP_OPS1 (double, , uint8NDArray, , uint8_t)
+SND_BOOL_OPS2 (double, uint8NDArray, 0.0, octave_uint8::zero)
diff --git a/liboctave/mx-s-ui8nda.h b/liboctave/mx-s-ui8nda.h
new file mode 100644
index 0000000..d888ac8
--- /dev/null
+++ b/liboctave/mx-s-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_s_ui8nda_h)
+#define octave_mx_s_ui8nda_h 1
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint8NDArray, double, uint8NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (double, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (double, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-fnda.cc b/liboctave/mx-ui16-fnda.cc
new file mode 100644
index 0000000..22458a5
--- /dev/null
+++ b/liboctave/mx-ui16-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (uint16NDArray, octave_uint16, FloatNDArray)
+SND_CMP_OPS1 (octave_uint16, , FloatNDArray, , uint16_t)
+SND_BOOL_OPS2 (octave_uint16, FloatNDArray, octave_uint16::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui16-fnda.h b/liboctave/mx-ui16-fnda.h
new file mode 100644
index 0000000..fcb4f67
--- /dev/null
+++ b/liboctave/mx-ui16-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_fnda_h)
+#define octave_mx_ui16_fnda_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint16NDArray, octave_uint16, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint16, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-i16nda.cc b/liboctave/mx-ui16-i16nda.cc
new file mode 100644
index 0000000..5b4633b
--- /dev/null
+++ b/liboctave/mx-ui16-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , int16NDArray, , uint16_t, int16_t)
+SND_BOOL_OPS2 (octave_uint16, int16NDArray, octave_uint16::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui16-i16nda.h b/liboctave/mx-ui16-i16nda.h
new file mode 100644
index 0000000..4cc99b9
--- /dev/null
+++ b/liboctave/mx-ui16-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_i16nda_h)
+#define octave_mx_ui16_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-i32nda.cc b/liboctave/mx-ui16-i32nda.cc
new file mode 100644
index 0000000..513d256
--- /dev/null
+++ b/liboctave/mx-ui16-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , int32NDArray, , uint16_t, int32_t)
+SND_BOOL_OPS2 (octave_uint16, int32NDArray, octave_uint16::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui16-i32nda.h b/liboctave/mx-ui16-i32nda.h
new file mode 100644
index 0000000..41e4b66
--- /dev/null
+++ b/liboctave/mx-ui16-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_i32nda_h)
+#define octave_mx_ui16_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-i64nda.cc b/liboctave/mx-ui16-i64nda.cc
new file mode 100644
index 0000000..5e501bd
--- /dev/null
+++ b/liboctave/mx-ui16-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , int64NDArray, , uint16_t, int64_t)
+SND_BOOL_OPS2 (octave_uint16, int64NDArray, octave_uint16::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui16-i64nda.h b/liboctave/mx-ui16-i64nda.h
new file mode 100644
index 0000000..de365f5
--- /dev/null
+++ b/liboctave/mx-ui16-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_i64nda_h)
+#define octave_mx_ui16_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-i8nda.cc b/liboctave/mx-ui16-i8nda.cc
new file mode 100644
index 0000000..d8d4b42
--- /dev/null
+++ b/liboctave/mx-ui16-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , int8NDArray, , uint16_t, int8_t)
+SND_BOOL_OPS2 (octave_uint16, int8NDArray, octave_uint16::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui16-i8nda.h b/liboctave/mx-ui16-i8nda.h
new file mode 100644
index 0000000..4ad227f
--- /dev/null
+++ b/liboctave/mx-ui16-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_i8nda_h)
+#define octave_mx_ui16_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-nda.cc b/liboctave/mx-ui16-nda.cc
new file mode 100644
index 0000000..639ee67
--- /dev/null
+++ b/liboctave/mx-ui16-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (uint16NDArray, octave_uint16, NDArray)
+SND_CMP_OPS1 (octave_uint16, , NDArray, , uint16_t)
+SND_BOOL_OPS2 (octave_uint16, NDArray, octave_uint16::zero, 0.0)
diff --git a/liboctave/mx-ui16-nda.h b/liboctave/mx-ui16-nda.h
new file mode 100644
index 0000000..51137e5
--- /dev/null
+++ b/liboctave/mx-ui16-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_nda_h)
+#define octave_mx_ui16_nda_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint16NDArray, octave_uint16, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint16, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-ui32nda.cc b/liboctave/mx-ui16-ui32nda.cc
new file mode 100644
index 0000000..9995634
--- /dev/null
+++ b/liboctave/mx-ui16-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , uint32NDArray, , uint16_t, uint32_t)
+SND_BOOL_OPS2 (octave_uint16, uint32NDArray, octave_uint16::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui16-ui32nda.h b/liboctave/mx-ui16-ui32nda.h
new file mode 100644
index 0000000..158b90e
--- /dev/null
+++ b/liboctave/mx-ui16-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_ui32nda_h)
+#define octave_mx_ui16_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-ui64nda.cc b/liboctave/mx-ui16-ui64nda.cc
new file mode 100644
index 0000000..2e350b6
--- /dev/null
+++ b/liboctave/mx-ui16-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , uint64NDArray, , uint16_t, uint64_t)
+SND_BOOL_OPS2 (octave_uint16, uint64NDArray, octave_uint16::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui16-ui64nda.h b/liboctave/mx-ui16-ui64nda.h
new file mode 100644
index 0000000..d834317
--- /dev/null
+++ b/liboctave/mx-ui16-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_ui64nda_h)
+#define octave_mx_ui16_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16-ui8nda.cc b/liboctave/mx-ui16-ui8nda.cc
new file mode 100644
index 0000000..1b8f6c5
--- /dev/null
+++ b/liboctave/mx-ui16-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_uint16, , uint8NDArray, , uint16_t, uint8_t)
+SND_BOOL_OPS2 (octave_uint16, uint8NDArray, octave_uint16::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui16-ui8nda.h b/liboctave/mx-ui16-ui8nda.h
new file mode 100644
index 0000000..d4c69b0
--- /dev/null
+++ b/liboctave/mx-ui16-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16_ui8nda_h)
+#define octave_mx_ui16_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint16, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-fnda.cc b/liboctave/mx-ui16nda-fnda.cc
new file mode 100644
index 0000000..5498bf1
--- /dev/null
+++ b/liboctave/mx-ui16nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint16NDArray, uint16NDArray, FloatNDArray)
+NDND_CMP_OPS (uint16NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, FloatNDArray, octave_uint16::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui16nda-fnda.h b/liboctave/mx-ui16nda-fnda.h
new file mode 100644
index 0000000..e893996
--- /dev/null
+++ b/liboctave/mx-ui16nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_fnda_h)
+#define octave_mx_ui16nda_fnda_h 1
+#include "uint16NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint16NDArray, uint16NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint16NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-fs.cc b/liboctave/mx-ui16nda-fs.cc
new file mode 100644
index 0000000..d71107d
--- /dev/null
+++ b/liboctave/mx-ui16nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+NDS_BIN_OPS (uint16NDArray, uint16NDArray, float)
+NDS_CMP_OPS1 (uint16NDArray, , float, , uint16_t)
+NDS_BOOL_OPS2 (uint16NDArray, float, octave_uint16::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui16nda-fs.h b/liboctave/mx-ui16nda-fs.h
new file mode 100644
index 0000000..52d9f6c
--- /dev/null
+++ b/liboctave/mx-ui16nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_fs_h)
+#define octave_mx_ui16nda_fs_h 1
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint16NDArray, uint16NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint16NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i16.cc b/liboctave/mx-ui16nda-i16.cc
new file mode 100644
index 0000000..b66ab75
--- /dev/null
+++ b/liboctave/mx-ui16nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_int16, , uint16_t, int16_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_int16, octave_uint16::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui16nda-i16.h b/liboctave/mx-ui16nda-i16.h
new file mode 100644
index 0000000..8664ac7
--- /dev/null
+++ b/liboctave/mx-ui16nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i16_h)
+#define octave_mx_ui16nda_i16_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i16nda.cc b/liboctave/mx-ui16nda-i16nda.cc
new file mode 100644
index 0000000..b90aa74
--- /dev/null
+++ b/liboctave/mx-ui16nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, int16NDArray, octave_uint16::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui16nda-i16nda.h b/liboctave/mx-ui16nda-i16nda.h
new file mode 100644
index 0000000..6640d4c
--- /dev/null
+++ b/liboctave/mx-ui16nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i16nda_h)
+#define octave_mx_ui16nda_i16nda_h 1
+#include "uint16NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i32.cc b/liboctave/mx-ui16nda-i32.cc
new file mode 100644
index 0000000..f60db8c
--- /dev/null
+++ b/liboctave/mx-ui16nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_int32, , uint16_t, int32_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_int32, octave_uint16::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui16nda-i32.h b/liboctave/mx-ui16nda-i32.h
new file mode 100644
index 0000000..425d022
--- /dev/null
+++ b/liboctave/mx-ui16nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i32_h)
+#define octave_mx_ui16nda_i32_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i32nda.cc b/liboctave/mx-ui16nda-i32nda.cc
new file mode 100644
index 0000000..498549e
--- /dev/null
+++ b/liboctave/mx-ui16nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, int32NDArray, octave_uint16::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui16nda-i32nda.h b/liboctave/mx-ui16nda-i32nda.h
new file mode 100644
index 0000000..66e740f
--- /dev/null
+++ b/liboctave/mx-ui16nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i32nda_h)
+#define octave_mx_ui16nda_i32nda_h 1
+#include "uint16NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i64.cc b/liboctave/mx-ui16nda-i64.cc
new file mode 100644
index 0000000..20a3aa9
--- /dev/null
+++ b/liboctave/mx-ui16nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_int64, , uint16_t, int64_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_int64, octave_uint16::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui16nda-i64.h b/liboctave/mx-ui16nda-i64.h
new file mode 100644
index 0000000..0008ce2
--- /dev/null
+++ b/liboctave/mx-ui16nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i64_h)
+#define octave_mx_ui16nda_i64_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i64nda.cc b/liboctave/mx-ui16nda-i64nda.cc
new file mode 100644
index 0000000..dedcffe
--- /dev/null
+++ b/liboctave/mx-ui16nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, int64NDArray, octave_uint16::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui16nda-i64nda.h b/liboctave/mx-ui16nda-i64nda.h
new file mode 100644
index 0000000..f52640b
--- /dev/null
+++ b/liboctave/mx-ui16nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i64nda_h)
+#define octave_mx_ui16nda_i64nda_h 1
+#include "uint16NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i8.cc b/liboctave/mx-ui16nda-i8.cc
new file mode 100644
index 0000000..bf89000
--- /dev/null
+++ b/liboctave/mx-ui16nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_int8, , uint16_t, int8_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_int8, octave_uint16::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui16nda-i8.h b/liboctave/mx-ui16nda-i8.h
new file mode 100644
index 0000000..b7eb598
--- /dev/null
+++ b/liboctave/mx-ui16nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i8_h)
+#define octave_mx_ui16nda_i8_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-i8nda.cc b/liboctave/mx-ui16nda-i8nda.cc
new file mode 100644
index 0000000..95e560c
--- /dev/null
+++ b/liboctave/mx-ui16nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, int8NDArray, octave_uint16::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui16nda-i8nda.h b/liboctave/mx-ui16nda-i8nda.h
new file mode 100644
index 0000000..bc60b37
--- /dev/null
+++ b/liboctave/mx-ui16nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_i8nda_h)
+#define octave_mx_ui16nda_i8nda_h 1
+#include "uint16NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-nda.cc b/liboctave/mx-ui16nda-nda.cc
new file mode 100644
index 0000000..cda5c03
--- /dev/null
+++ b/liboctave/mx-ui16nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint16NDArray, uint16NDArray, NDArray)
+NDND_CMP_OPS (uint16NDArray, , NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, NDArray, octave_uint16::zero, 0.0)
diff --git a/liboctave/mx-ui16nda-nda.h b/liboctave/mx-ui16nda-nda.h
new file mode 100644
index 0000000..17d8ecf
--- /dev/null
+++ b/liboctave/mx-ui16nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_nda_h)
+#define octave_mx_ui16nda_nda_h 1
+#include "uint16NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint16NDArray, uint16NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint16NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-s.cc b/liboctave/mx-ui16nda-s.cc
new file mode 100644
index 0000000..4c29e12
--- /dev/null
+++ b/liboctave/mx-ui16nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+NDS_BIN_OPS (uint16NDArray, uint16NDArray, double)
+NDS_CMP_OPS1 (uint16NDArray, , double, , uint16_t)
+NDS_BOOL_OPS2 (uint16NDArray, double, octave_uint16::zero, 0.0)
diff --git a/liboctave/mx-ui16nda-s.h b/liboctave/mx-ui16nda-s.h
new file mode 100644
index 0000000..d641180
--- /dev/null
+++ b/liboctave/mx-ui16nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_s_h)
+#define octave_mx_ui16nda_s_h 1
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint16NDArray, uint16NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint16NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-ui32.cc b/liboctave/mx-ui16nda-ui32.cc
new file mode 100644
index 0000000..1ec0640
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_uint32, , uint16_t, uint32_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_uint32, octave_uint16::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui16nda-ui32.h b/liboctave/mx-ui16nda-ui32.h
new file mode 100644
index 0000000..b8b9529
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_ui32_h)
+#define octave_mx_ui16nda_ui32_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-ui32nda.cc b/liboctave/mx-ui16nda-ui32nda.cc
new file mode 100644
index 0000000..e14ab64
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, uint32NDArray, octave_uint16::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui16nda-ui32nda.h b/liboctave/mx-ui16nda-ui32nda.h
new file mode 100644
index 0000000..e3aaa75
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_ui32nda_h)
+#define octave_mx_ui16nda_ui32nda_h 1
+#include "uint16NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-ui64.cc b/liboctave/mx-ui16nda-ui64.cc
new file mode 100644
index 0000000..6ef9055
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_uint64, , uint16_t, uint64_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_uint64, octave_uint16::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui16nda-ui64.h b/liboctave/mx-ui16nda-ui64.h
new file mode 100644
index 0000000..0c7450c
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_ui64_h)
+#define octave_mx_ui16nda_ui64_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-ui64nda.cc b/liboctave/mx-ui16nda-ui64nda.cc
new file mode 100644
index 0000000..74338cd
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, uint64NDArray, octave_uint16::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui16nda-ui64nda.h b/liboctave/mx-ui16nda-ui64nda.h
new file mode 100644
index 0000000..8794fb9
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_ui64nda_h)
+#define octave_mx_ui16nda_ui64nda_h 1
+#include "uint16NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-ui8.cc b/liboctave/mx-ui16nda-ui8.cc
new file mode 100644
index 0000000..6efb713
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint16NDArray, , octave_uint8, , uint16_t, uint8_t)
+NDS_BOOL_OPS2 (uint16NDArray, octave_uint8, octave_uint16::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui16nda-ui8.h b/liboctave/mx-ui16nda-ui8.h
new file mode 100644
index 0000000..eec9da8
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_ui8_h)
+#define octave_mx_ui16nda_ui8_h 1
+#include "uint16NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint16NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui16nda-ui8nda.cc b/liboctave/mx-ui16nda-ui8nda.cc
new file mode 100644
index 0000000..b8a1795
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui16nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint16NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (uint16NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (uint16NDArray, uint8NDArray, octave_uint16::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui16nda-ui8nda.h b/liboctave/mx-ui16nda-ui8nda.h
new file mode 100644
index 0000000..aa09fc2
--- /dev/null
+++ b/liboctave/mx-ui16nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui16nda_ui8nda_h)
+#define octave_mx_ui16nda_ui8nda_h 1
+#include "uint16NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint16NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-fnda.cc b/liboctave/mx-ui32-fnda.cc
new file mode 100644
index 0000000..2d54912
--- /dev/null
+++ b/liboctave/mx-ui32-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (uint32NDArray, octave_uint32, FloatNDArray)
+SND_CMP_OPS1 (octave_uint32, , FloatNDArray, , uint32_t)
+SND_BOOL_OPS2 (octave_uint32, FloatNDArray, octave_uint32::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui32-fnda.h b/liboctave/mx-ui32-fnda.h
new file mode 100644
index 0000000..e097db0
--- /dev/null
+++ b/liboctave/mx-ui32-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_fnda_h)
+#define octave_mx_ui32_fnda_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint32NDArray, octave_uint32, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint32, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-i16nda.cc b/liboctave/mx-ui32-i16nda.cc
new file mode 100644
index 0000000..50cade9
--- /dev/null
+++ b/liboctave/mx-ui32-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , int16NDArray, , uint32_t, int16_t)
+SND_BOOL_OPS2 (octave_uint32, int16NDArray, octave_uint32::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui32-i16nda.h b/liboctave/mx-ui32-i16nda.h
new file mode 100644
index 0000000..f3fb3a0
--- /dev/null
+++ b/liboctave/mx-ui32-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_i16nda_h)
+#define octave_mx_ui32_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-i32nda.cc b/liboctave/mx-ui32-i32nda.cc
new file mode 100644
index 0000000..c5abe85
--- /dev/null
+++ b/liboctave/mx-ui32-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , int32NDArray, , uint32_t, int32_t)
+SND_BOOL_OPS2 (octave_uint32, int32NDArray, octave_uint32::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui32-i32nda.h b/liboctave/mx-ui32-i32nda.h
new file mode 100644
index 0000000..573322d
--- /dev/null
+++ b/liboctave/mx-ui32-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_i32nda_h)
+#define octave_mx_ui32_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-i64nda.cc b/liboctave/mx-ui32-i64nda.cc
new file mode 100644
index 0000000..1d59b76
--- /dev/null
+++ b/liboctave/mx-ui32-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , int64NDArray, , uint32_t, int64_t)
+SND_BOOL_OPS2 (octave_uint32, int64NDArray, octave_uint32::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui32-i64nda.h b/liboctave/mx-ui32-i64nda.h
new file mode 100644
index 0000000..7332433
--- /dev/null
+++ b/liboctave/mx-ui32-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_i64nda_h)
+#define octave_mx_ui32_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-i8nda.cc b/liboctave/mx-ui32-i8nda.cc
new file mode 100644
index 0000000..d58e235
--- /dev/null
+++ b/liboctave/mx-ui32-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , int8NDArray, , uint32_t, int8_t)
+SND_BOOL_OPS2 (octave_uint32, int8NDArray, octave_uint32::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui32-i8nda.h b/liboctave/mx-ui32-i8nda.h
new file mode 100644
index 0000000..5436a8b
--- /dev/null
+++ b/liboctave/mx-ui32-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_i8nda_h)
+#define octave_mx_ui32_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-nda.cc b/liboctave/mx-ui32-nda.cc
new file mode 100644
index 0000000..0660fb1
--- /dev/null
+++ b/liboctave/mx-ui32-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (uint32NDArray, octave_uint32, NDArray)
+SND_CMP_OPS1 (octave_uint32, , NDArray, , uint32_t)
+SND_BOOL_OPS2 (octave_uint32, NDArray, octave_uint32::zero, 0.0)
diff --git a/liboctave/mx-ui32-nda.h b/liboctave/mx-ui32-nda.h
new file mode 100644
index 0000000..df410b4
--- /dev/null
+++ b/liboctave/mx-ui32-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_nda_h)
+#define octave_mx_ui32_nda_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint32NDArray, octave_uint32, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint32, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-ui16nda.cc b/liboctave/mx-ui32-ui16nda.cc
new file mode 100644
index 0000000..15df89f
--- /dev/null
+++ b/liboctave/mx-ui32-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , uint16NDArray, , uint32_t, uint16_t)
+SND_BOOL_OPS2 (octave_uint32, uint16NDArray, octave_uint32::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui32-ui16nda.h b/liboctave/mx-ui32-ui16nda.h
new file mode 100644
index 0000000..fe99c19
--- /dev/null
+++ b/liboctave/mx-ui32-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_ui16nda_h)
+#define octave_mx_ui32_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-ui64nda.cc b/liboctave/mx-ui32-ui64nda.cc
new file mode 100644
index 0000000..1fcd7cd
--- /dev/null
+++ b/liboctave/mx-ui32-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , uint64NDArray, , uint32_t, uint64_t)
+SND_BOOL_OPS2 (octave_uint32, uint64NDArray, octave_uint32::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui32-ui64nda.h b/liboctave/mx-ui32-ui64nda.h
new file mode 100644
index 0000000..f591727
--- /dev/null
+++ b/liboctave/mx-ui32-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_ui64nda_h)
+#define octave_mx_ui32_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32-ui8nda.cc b/liboctave/mx-ui32-ui8nda.cc
new file mode 100644
index 0000000..b19a460
--- /dev/null
+++ b/liboctave/mx-ui32-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_uint32, , uint8NDArray, , uint32_t, uint8_t)
+SND_BOOL_OPS2 (octave_uint32, uint8NDArray, octave_uint32::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui32-ui8nda.h b/liboctave/mx-ui32-ui8nda.h
new file mode 100644
index 0000000..9ed1f8c
--- /dev/null
+++ b/liboctave/mx-ui32-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32_ui8nda_h)
+#define octave_mx_ui32_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint32, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-fnda.cc b/liboctave/mx-ui32nda-fnda.cc
new file mode 100644
index 0000000..0be249b
--- /dev/null
+++ b/liboctave/mx-ui32nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint32NDArray, uint32NDArray, FloatNDArray)
+NDND_CMP_OPS (uint32NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, FloatNDArray, octave_uint32::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui32nda-fnda.h b/liboctave/mx-ui32nda-fnda.h
new file mode 100644
index 0000000..a6377dc
--- /dev/null
+++ b/liboctave/mx-ui32nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_fnda_h)
+#define octave_mx_ui32nda_fnda_h 1
+#include "uint32NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint32NDArray, uint32NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint32NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-fs.cc b/liboctave/mx-ui32nda-fs.cc
new file mode 100644
index 0000000..6336646
--- /dev/null
+++ b/liboctave/mx-ui32nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+NDS_BIN_OPS (uint32NDArray, uint32NDArray, float)
+NDS_CMP_OPS1 (uint32NDArray, , float, , uint32_t)
+NDS_BOOL_OPS2 (uint32NDArray, float, octave_uint32::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui32nda-fs.h b/liboctave/mx-ui32nda-fs.h
new file mode 100644
index 0000000..7c5d121
--- /dev/null
+++ b/liboctave/mx-ui32nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_fs_h)
+#define octave_mx_ui32nda_fs_h 1
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint32NDArray, uint32NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint32NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i16.cc b/liboctave/mx-ui32nda-i16.cc
new file mode 100644
index 0000000..38f476b
--- /dev/null
+++ b/liboctave/mx-ui32nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_int16, , uint32_t, int16_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_int16, octave_uint32::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui32nda-i16.h b/liboctave/mx-ui32nda-i16.h
new file mode 100644
index 0000000..673c2f4
--- /dev/null
+++ b/liboctave/mx-ui32nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i16_h)
+#define octave_mx_ui32nda_i16_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i16nda.cc b/liboctave/mx-ui32nda-i16nda.cc
new file mode 100644
index 0000000..f54ca3e
--- /dev/null
+++ b/liboctave/mx-ui32nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, int16NDArray, octave_uint32::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui32nda-i16nda.h b/liboctave/mx-ui32nda-i16nda.h
new file mode 100644
index 0000000..acee197
--- /dev/null
+++ b/liboctave/mx-ui32nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i16nda_h)
+#define octave_mx_ui32nda_i16nda_h 1
+#include "uint32NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i32.cc b/liboctave/mx-ui32nda-i32.cc
new file mode 100644
index 0000000..2da0a21
--- /dev/null
+++ b/liboctave/mx-ui32nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_int32, , uint32_t, int32_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_int32, octave_uint32::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui32nda-i32.h b/liboctave/mx-ui32nda-i32.h
new file mode 100644
index 0000000..f9d3c3d
--- /dev/null
+++ b/liboctave/mx-ui32nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i32_h)
+#define octave_mx_ui32nda_i32_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i32nda.cc b/liboctave/mx-ui32nda-i32nda.cc
new file mode 100644
index 0000000..f68bb0b
--- /dev/null
+++ b/liboctave/mx-ui32nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, int32NDArray, octave_uint32::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui32nda-i32nda.h b/liboctave/mx-ui32nda-i32nda.h
new file mode 100644
index 0000000..f590bb0
--- /dev/null
+++ b/liboctave/mx-ui32nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i32nda_h)
+#define octave_mx_ui32nda_i32nda_h 1
+#include "uint32NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i64.cc b/liboctave/mx-ui32nda-i64.cc
new file mode 100644
index 0000000..00b220a
--- /dev/null
+++ b/liboctave/mx-ui32nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_int64, , uint32_t, int64_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_int64, octave_uint32::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui32nda-i64.h b/liboctave/mx-ui32nda-i64.h
new file mode 100644
index 0000000..42ef79e
--- /dev/null
+++ b/liboctave/mx-ui32nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i64_h)
+#define octave_mx_ui32nda_i64_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i64nda.cc b/liboctave/mx-ui32nda-i64nda.cc
new file mode 100644
index 0000000..d51dab8
--- /dev/null
+++ b/liboctave/mx-ui32nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, int64NDArray, octave_uint32::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui32nda-i64nda.h b/liboctave/mx-ui32nda-i64nda.h
new file mode 100644
index 0000000..9c42ca1
--- /dev/null
+++ b/liboctave/mx-ui32nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i64nda_h)
+#define octave_mx_ui32nda_i64nda_h 1
+#include "uint32NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i8.cc b/liboctave/mx-ui32nda-i8.cc
new file mode 100644
index 0000000..c73a23b
--- /dev/null
+++ b/liboctave/mx-ui32nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_int8, , uint32_t, int8_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_int8, octave_uint32::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui32nda-i8.h b/liboctave/mx-ui32nda-i8.h
new file mode 100644
index 0000000..7e55995
--- /dev/null
+++ b/liboctave/mx-ui32nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i8_h)
+#define octave_mx_ui32nda_i8_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-i8nda.cc b/liboctave/mx-ui32nda-i8nda.cc
new file mode 100644
index 0000000..8b56663
--- /dev/null
+++ b/liboctave/mx-ui32nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, int8NDArray, octave_uint32::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui32nda-i8nda.h b/liboctave/mx-ui32nda-i8nda.h
new file mode 100644
index 0000000..f570b05
--- /dev/null
+++ b/liboctave/mx-ui32nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_i8nda_h)
+#define octave_mx_ui32nda_i8nda_h 1
+#include "uint32NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-nda.cc b/liboctave/mx-ui32nda-nda.cc
new file mode 100644
index 0000000..9d6db10
--- /dev/null
+++ b/liboctave/mx-ui32nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint32NDArray, uint32NDArray, NDArray)
+NDND_CMP_OPS (uint32NDArray, , NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, NDArray, octave_uint32::zero, 0.0)
diff --git a/liboctave/mx-ui32nda-nda.h b/liboctave/mx-ui32nda-nda.h
new file mode 100644
index 0000000..8fe245e
--- /dev/null
+++ b/liboctave/mx-ui32nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_nda_h)
+#define octave_mx_ui32nda_nda_h 1
+#include "uint32NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint32NDArray, uint32NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint32NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-s.cc b/liboctave/mx-ui32nda-s.cc
new file mode 100644
index 0000000..e3dfb6b
--- /dev/null
+++ b/liboctave/mx-ui32nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+NDS_BIN_OPS (uint32NDArray, uint32NDArray, double)
+NDS_CMP_OPS1 (uint32NDArray, , double, , uint32_t)
+NDS_BOOL_OPS2 (uint32NDArray, double, octave_uint32::zero, 0.0)
diff --git a/liboctave/mx-ui32nda-s.h b/liboctave/mx-ui32nda-s.h
new file mode 100644
index 0000000..8cdcb73
--- /dev/null
+++ b/liboctave/mx-ui32nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_s_h)
+#define octave_mx_ui32nda_s_h 1
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint32NDArray, uint32NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint32NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-ui16.cc b/liboctave/mx-ui32nda-ui16.cc
new file mode 100644
index 0000000..1ebc315
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_uint16, , uint32_t, uint16_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_uint16, octave_uint32::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui32nda-ui16.h b/liboctave/mx-ui32nda-ui16.h
new file mode 100644
index 0000000..ae0ae78
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_ui16_h)
+#define octave_mx_ui32nda_ui16_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-ui16nda.cc b/liboctave/mx-ui32nda-ui16nda.cc
new file mode 100644
index 0000000..9910485
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, uint16NDArray, octave_uint32::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui32nda-ui16nda.h b/liboctave/mx-ui32nda-ui16nda.h
new file mode 100644
index 0000000..5800127
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_ui16nda_h)
+#define octave_mx_ui32nda_ui16nda_h 1
+#include "uint32NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-ui64.cc b/liboctave/mx-ui32nda-ui64.cc
new file mode 100644
index 0000000..e82603a
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_uint64, , uint32_t, uint64_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_uint64, octave_uint32::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui32nda-ui64.h b/liboctave/mx-ui32nda-ui64.h
new file mode 100644
index 0000000..a2e7c5d
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_ui64_h)
+#define octave_mx_ui32nda_ui64_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-ui64nda.cc b/liboctave/mx-ui32nda-ui64nda.cc
new file mode 100644
index 0000000..15740ad
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, uint64NDArray, octave_uint32::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui32nda-ui64nda.h b/liboctave/mx-ui32nda-ui64nda.h
new file mode 100644
index 0000000..77c5143
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_ui64nda_h)
+#define octave_mx_ui32nda_ui64nda_h 1
+#include "uint32NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-ui8.cc b/liboctave/mx-ui32nda-ui8.cc
new file mode 100644
index 0000000..e1710d5
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint32NDArray, , octave_uint8, , uint32_t, uint8_t)
+NDS_BOOL_OPS2 (uint32NDArray, octave_uint8, octave_uint32::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui32nda-ui8.h b/liboctave/mx-ui32nda-ui8.h
new file mode 100644
index 0000000..b18a930
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_ui8_h)
+#define octave_mx_ui32nda_ui8_h 1
+#include "uint32NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint32NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui32nda-ui8nda.cc b/liboctave/mx-ui32nda-ui8nda.cc
new file mode 100644
index 0000000..a719757
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui32nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint32NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (uint32NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (uint32NDArray, uint8NDArray, octave_uint32::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui32nda-ui8nda.h b/liboctave/mx-ui32nda-ui8nda.h
new file mode 100644
index 0000000..51158eb
--- /dev/null
+++ b/liboctave/mx-ui32nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui32nda_ui8nda_h)
+#define octave_mx_ui32nda_ui8nda_h 1
+#include "uint32NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint32NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-fnda.cc b/liboctave/mx-ui64-fnda.cc
new file mode 100644
index 0000000..41b22a8
--- /dev/null
+++ b/liboctave/mx-ui64-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (uint64NDArray, octave_uint64, FloatNDArray)
+SND_CMP_OPS1 (octave_uint64, , FloatNDArray, , uint64_t)
+SND_BOOL_OPS2 (octave_uint64, FloatNDArray, octave_uint64::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui64-fnda.h b/liboctave/mx-ui64-fnda.h
new file mode 100644
index 0000000..8cb419b
--- /dev/null
+++ b/liboctave/mx-ui64-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_fnda_h)
+#define octave_mx_ui64_fnda_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint64NDArray, octave_uint64, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint64, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-i16nda.cc b/liboctave/mx-ui64-i16nda.cc
new file mode 100644
index 0000000..e9ed314
--- /dev/null
+++ b/liboctave/mx-ui64-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , int16NDArray, , uint64_t, int16_t)
+SND_BOOL_OPS2 (octave_uint64, int16NDArray, octave_uint64::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui64-i16nda.h b/liboctave/mx-ui64-i16nda.h
new file mode 100644
index 0000000..f2a3a9c
--- /dev/null
+++ b/liboctave/mx-ui64-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_i16nda_h)
+#define octave_mx_ui64_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-i32nda.cc b/liboctave/mx-ui64-i32nda.cc
new file mode 100644
index 0000000..de2ea92
--- /dev/null
+++ b/liboctave/mx-ui64-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , int32NDArray, , uint64_t, int32_t)
+SND_BOOL_OPS2 (octave_uint64, int32NDArray, octave_uint64::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui64-i32nda.h b/liboctave/mx-ui64-i32nda.h
new file mode 100644
index 0000000..6c9dace
--- /dev/null
+++ b/liboctave/mx-ui64-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_i32nda_h)
+#define octave_mx_ui64_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-i64nda.cc b/liboctave/mx-ui64-i64nda.cc
new file mode 100644
index 0000000..826174e
--- /dev/null
+++ b/liboctave/mx-ui64-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , int64NDArray, , uint64_t, int64_t)
+SND_BOOL_OPS2 (octave_uint64, int64NDArray, octave_uint64::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui64-i64nda.h b/liboctave/mx-ui64-i64nda.h
new file mode 100644
index 0000000..c2831b2
--- /dev/null
+++ b/liboctave/mx-ui64-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_i64nda_h)
+#define octave_mx_ui64_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-i8nda.cc b/liboctave/mx-ui64-i8nda.cc
new file mode 100644
index 0000000..aeb0f5b
--- /dev/null
+++ b/liboctave/mx-ui64-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , int8NDArray, , uint64_t, int8_t)
+SND_BOOL_OPS2 (octave_uint64, int8NDArray, octave_uint64::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui64-i8nda.h b/liboctave/mx-ui64-i8nda.h
new file mode 100644
index 0000000..bf1b969
--- /dev/null
+++ b/liboctave/mx-ui64-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_i8nda_h)
+#define octave_mx_ui64_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-nda.cc b/liboctave/mx-ui64-nda.cc
new file mode 100644
index 0000000..fc08938
--- /dev/null
+++ b/liboctave/mx-ui64-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (uint64NDArray, octave_uint64, NDArray)
+SND_CMP_OPS1 (octave_uint64, , NDArray, , uint64_t)
+SND_BOOL_OPS2 (octave_uint64, NDArray, octave_uint64::zero, 0.0)
diff --git a/liboctave/mx-ui64-nda.h b/liboctave/mx-ui64-nda.h
new file mode 100644
index 0000000..7c937f2
--- /dev/null
+++ b/liboctave/mx-ui64-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_nda_h)
+#define octave_mx_ui64_nda_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint64NDArray, octave_uint64, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint64, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-ui16nda.cc b/liboctave/mx-ui64-ui16nda.cc
new file mode 100644
index 0000000..6a5cd93
--- /dev/null
+++ b/liboctave/mx-ui64-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , uint16NDArray, , uint64_t, uint16_t)
+SND_BOOL_OPS2 (octave_uint64, uint16NDArray, octave_uint64::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui64-ui16nda.h b/liboctave/mx-ui64-ui16nda.h
new file mode 100644
index 0000000..aa4344a
--- /dev/null
+++ b/liboctave/mx-ui64-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_ui16nda_h)
+#define octave_mx_ui64_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-ui32nda.cc b/liboctave/mx-ui64-ui32nda.cc
new file mode 100644
index 0000000..41d75d6
--- /dev/null
+++ b/liboctave/mx-ui64-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , uint32NDArray, , uint64_t, uint32_t)
+SND_BOOL_OPS2 (octave_uint64, uint32NDArray, octave_uint64::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui64-ui32nda.h b/liboctave/mx-ui64-ui32nda.h
new file mode 100644
index 0000000..b3c9554
--- /dev/null
+++ b/liboctave/mx-ui64-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_ui32nda_h)
+#define octave_mx_ui64_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64-ui8nda.cc b/liboctave/mx-ui64-ui8nda.cc
new file mode 100644
index 0000000..472464d
--- /dev/null
+++ b/liboctave/mx-ui64-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+SND_CMP_OPS2 (octave_uint64, , uint8NDArray, , uint64_t, uint8_t)
+SND_BOOL_OPS2 (octave_uint64, uint8NDArray, octave_uint64::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui64-ui8nda.h b/liboctave/mx-ui64-ui8nda.h
new file mode 100644
index 0000000..1488fdb
--- /dev/null
+++ b/liboctave/mx-ui64-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64_ui8nda_h)
+#define octave_mx_ui64_ui8nda_h 1
+#include "oct-inttypes.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint64, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-fnda.cc b/liboctave/mx-ui64nda-fnda.cc
new file mode 100644
index 0000000..c7e866b
--- /dev/null
+++ b/liboctave/mx-ui64nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint64NDArray, uint64NDArray, FloatNDArray)
+NDND_CMP_OPS (uint64NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, FloatNDArray, octave_uint64::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui64nda-fnda.h b/liboctave/mx-ui64nda-fnda.h
new file mode 100644
index 0000000..5087f09
--- /dev/null
+++ b/liboctave/mx-ui64nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_fnda_h)
+#define octave_mx_ui64nda_fnda_h 1
+#include "uint64NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint64NDArray, uint64NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint64NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-fs.cc b/liboctave/mx-ui64nda-fs.cc
new file mode 100644
index 0000000..800ee27
--- /dev/null
+++ b/liboctave/mx-ui64nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+NDS_BIN_OPS (uint64NDArray, uint64NDArray, float)
+NDS_CMP_OPS1 (uint64NDArray, , float, , uint64_t)
+NDS_BOOL_OPS2 (uint64NDArray, float, octave_uint64::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui64nda-fs.h b/liboctave/mx-ui64nda-fs.h
new file mode 100644
index 0000000..af0b34a
--- /dev/null
+++ b/liboctave/mx-ui64nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_fs_h)
+#define octave_mx_ui64nda_fs_h 1
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint64NDArray, uint64NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint64NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i16.cc b/liboctave/mx-ui64nda-i16.cc
new file mode 100644
index 0000000..1a2231a
--- /dev/null
+++ b/liboctave/mx-ui64nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_int16, , uint64_t, int16_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_int16, octave_uint64::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui64nda-i16.h b/liboctave/mx-ui64nda-i16.h
new file mode 100644
index 0000000..231b756
--- /dev/null
+++ b/liboctave/mx-ui64nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i16_h)
+#define octave_mx_ui64nda_i16_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i16nda.cc b/liboctave/mx-ui64nda-i16nda.cc
new file mode 100644
index 0000000..561eecc
--- /dev/null
+++ b/liboctave/mx-ui64nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, int16NDArray, octave_uint64::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui64nda-i16nda.h b/liboctave/mx-ui64nda-i16nda.h
new file mode 100644
index 0000000..1744c95
--- /dev/null
+++ b/liboctave/mx-ui64nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i16nda_h)
+#define octave_mx_ui64nda_i16nda_h 1
+#include "uint64NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i32.cc b/liboctave/mx-ui64nda-i32.cc
new file mode 100644
index 0000000..2831ab3
--- /dev/null
+++ b/liboctave/mx-ui64nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_int32, , uint64_t, int32_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_int32, octave_uint64::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui64nda-i32.h b/liboctave/mx-ui64nda-i32.h
new file mode 100644
index 0000000..ee2d1ac
--- /dev/null
+++ b/liboctave/mx-ui64nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i32_h)
+#define octave_mx_ui64nda_i32_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i32nda.cc b/liboctave/mx-ui64nda-i32nda.cc
new file mode 100644
index 0000000..68b7b3b
--- /dev/null
+++ b/liboctave/mx-ui64nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, int32NDArray, octave_uint64::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui64nda-i32nda.h b/liboctave/mx-ui64nda-i32nda.h
new file mode 100644
index 0000000..6594416
--- /dev/null
+++ b/liboctave/mx-ui64nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i32nda_h)
+#define octave_mx_ui64nda_i32nda_h 1
+#include "uint64NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i64.cc b/liboctave/mx-ui64nda-i64.cc
new file mode 100644
index 0000000..9bddd2d
--- /dev/null
+++ b/liboctave/mx-ui64nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_int64, , uint64_t, int64_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_int64, octave_uint64::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui64nda-i64.h b/liboctave/mx-ui64nda-i64.h
new file mode 100644
index 0000000..2f1ee3e
--- /dev/null
+++ b/liboctave/mx-ui64nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i64_h)
+#define octave_mx_ui64nda_i64_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i64nda.cc b/liboctave/mx-ui64nda-i64nda.cc
new file mode 100644
index 0000000..8f1c957
--- /dev/null
+++ b/liboctave/mx-ui64nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, int64NDArray, octave_uint64::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui64nda-i64nda.h b/liboctave/mx-ui64nda-i64nda.h
new file mode 100644
index 0000000..caf189c
--- /dev/null
+++ b/liboctave/mx-ui64nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i64nda_h)
+#define octave_mx_ui64nda_i64nda_h 1
+#include "uint64NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i8.cc b/liboctave/mx-ui64nda-i8.cc
new file mode 100644
index 0000000..40e561f
--- /dev/null
+++ b/liboctave/mx-ui64nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_int8, , uint64_t, int8_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_int8, octave_uint64::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui64nda-i8.h b/liboctave/mx-ui64nda-i8.h
new file mode 100644
index 0000000..72bd827
--- /dev/null
+++ b/liboctave/mx-ui64nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i8_h)
+#define octave_mx_ui64nda_i8_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-i8nda.cc b/liboctave/mx-ui64nda-i8nda.cc
new file mode 100644
index 0000000..b880ffa
--- /dev/null
+++ b/liboctave/mx-ui64nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, int8NDArray, octave_uint64::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui64nda-i8nda.h b/liboctave/mx-ui64nda-i8nda.h
new file mode 100644
index 0000000..7df9a1a
--- /dev/null
+++ b/liboctave/mx-ui64nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_i8nda_h)
+#define octave_mx_ui64nda_i8nda_h 1
+#include "uint64NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-nda.cc b/liboctave/mx-ui64nda-nda.cc
new file mode 100644
index 0000000..01eb8d4
--- /dev/null
+++ b/liboctave/mx-ui64nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint64NDArray, uint64NDArray, NDArray)
+NDND_CMP_OPS (uint64NDArray, , NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, NDArray, octave_uint64::zero, 0.0)
diff --git a/liboctave/mx-ui64nda-nda.h b/liboctave/mx-ui64nda-nda.h
new file mode 100644
index 0000000..f364948
--- /dev/null
+++ b/liboctave/mx-ui64nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_nda_h)
+#define octave_mx_ui64nda_nda_h 1
+#include "uint64NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint64NDArray, uint64NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint64NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-s.cc b/liboctave/mx-ui64nda-s.cc
new file mode 100644
index 0000000..06e6618
--- /dev/null
+++ b/liboctave/mx-ui64nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+NDS_BIN_OPS (uint64NDArray, uint64NDArray, double)
+NDS_CMP_OPS1 (uint64NDArray, , double, , uint64_t)
+NDS_BOOL_OPS2 (uint64NDArray, double, octave_uint64::zero, 0.0)
diff --git a/liboctave/mx-ui64nda-s.h b/liboctave/mx-ui64nda-s.h
new file mode 100644
index 0000000..cf879bb
--- /dev/null
+++ b/liboctave/mx-ui64nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_s_h)
+#define octave_mx_ui64nda_s_h 1
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint64NDArray, uint64NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint64NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-ui16.cc b/liboctave/mx-ui64nda-ui16.cc
new file mode 100644
index 0000000..8f77596
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_uint16, , uint64_t, uint16_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_uint16, octave_uint64::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui64nda-ui16.h b/liboctave/mx-ui64nda-ui16.h
new file mode 100644
index 0000000..3e8d61e
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_ui16_h)
+#define octave_mx_ui64nda_ui16_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-ui16nda.cc b/liboctave/mx-ui64nda-ui16nda.cc
new file mode 100644
index 0000000..f973b24
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, uint16NDArray, octave_uint64::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui64nda-ui16nda.h b/liboctave/mx-ui64nda-ui16nda.h
new file mode 100644
index 0000000..849d065
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_ui16nda_h)
+#define octave_mx_ui64nda_ui16nda_h 1
+#include "uint64NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-ui32.cc b/liboctave/mx-ui64nda-ui32.cc
new file mode 100644
index 0000000..3935a05
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_uint32, , uint64_t, uint32_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_uint32, octave_uint64::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui64nda-ui32.h b/liboctave/mx-ui64nda-ui32.h
new file mode 100644
index 0000000..5342372
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_ui32_h)
+#define octave_mx_ui64nda_ui32_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-ui32nda.cc b/liboctave/mx-ui64nda-ui32nda.cc
new file mode 100644
index 0000000..23acafa
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, uint32NDArray, octave_uint64::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui64nda-ui32nda.h b/liboctave/mx-ui64nda-ui32nda.h
new file mode 100644
index 0000000..e8bc257
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_ui32nda_h)
+#define octave_mx_ui64nda_ui32nda_h 1
+#include "uint64NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-ui8.cc b/liboctave/mx-ui64nda-ui8.cc
new file mode 100644
index 0000000..9025bff
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-ui8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint64NDArray, , octave_uint8, , uint64_t, uint8_t)
+NDS_BOOL_OPS2 (uint64NDArray, octave_uint8, octave_uint64::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui64nda-ui8.h b/liboctave/mx-ui64nda-ui8.h
new file mode 100644
index 0000000..e613750
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_ui8_h)
+#define octave_mx_ui64nda_ui8_h 1
+#include "uint64NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint64NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_uint8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui64nda-ui8nda.cc b/liboctave/mx-ui64nda-ui8nda.cc
new file mode 100644
index 0000000..04cf60b
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui64nda-ui8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint64NDArray.h"
+#include "uint8NDArray.h"
+NDND_CMP_OPS (uint64NDArray, , uint8NDArray, )
+NDND_BOOL_OPS2 (uint64NDArray, uint8NDArray, octave_uint64::zero, octave_uint8::zero)
diff --git a/liboctave/mx-ui64nda-ui8nda.h b/liboctave/mx-ui64nda-ui8nda.h
new file mode 100644
index 0000000..230f3a4
--- /dev/null
+++ b/liboctave/mx-ui64nda-ui8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui64nda_ui8nda_h)
+#define octave_mx_ui64nda_ui8nda_h 1
+#include "uint64NDArray.h"
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint64NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, uint8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-fnda.cc b/liboctave/mx-ui8-fnda.cc
new file mode 100644
index 0000000..aa90893
--- /dev/null
+++ b/liboctave/mx-ui8-fnda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+SND_BIN_OPS (uint8NDArray, octave_uint8, FloatNDArray)
+SND_CMP_OPS1 (octave_uint8, , FloatNDArray, , uint8_t)
+SND_BOOL_OPS2 (octave_uint8, FloatNDArray, octave_uint8::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui8-fnda.h b/liboctave/mx-ui8-fnda.h
new file mode 100644
index 0000000..80d1f9c
--- /dev/null
+++ b/liboctave/mx-ui8-fnda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_fnda_h)
+#define octave_mx_ui8_fnda_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint8NDArray, octave_uint8, FloatNDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint8, FloatNDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-i16nda.cc b/liboctave/mx-ui8-i16nda.cc
new file mode 100644
index 0000000..6f7905c
--- /dev/null
+++ b/liboctave/mx-ui8-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , int16NDArray, , uint8_t, int16_t)
+SND_BOOL_OPS2 (octave_uint8, int16NDArray, octave_uint8::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui8-i16nda.h b/liboctave/mx-ui8-i16nda.h
new file mode 100644
index 0000000..1d21af4
--- /dev/null
+++ b/liboctave/mx-ui8-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_i16nda_h)
+#define octave_mx_ui8_i16nda_h 1
+#include "oct-inttypes.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, int16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-i32nda.cc b/liboctave/mx-ui8-i32nda.cc
new file mode 100644
index 0000000..67560b8
--- /dev/null
+++ b/liboctave/mx-ui8-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , int32NDArray, , uint8_t, int32_t)
+SND_BOOL_OPS2 (octave_uint8, int32NDArray, octave_uint8::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui8-i32nda.h b/liboctave/mx-ui8-i32nda.h
new file mode 100644
index 0000000..417c19a
--- /dev/null
+++ b/liboctave/mx-ui8-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_i32nda_h)
+#define octave_mx_ui8_i32nda_h 1
+#include "oct-inttypes.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, int32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-i64nda.cc b/liboctave/mx-ui8-i64nda.cc
new file mode 100644
index 0000000..844ab7e
--- /dev/null
+++ b/liboctave/mx-ui8-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , int64NDArray, , uint8_t, int64_t)
+SND_BOOL_OPS2 (octave_uint8, int64NDArray, octave_uint8::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui8-i64nda.h b/liboctave/mx-ui8-i64nda.h
new file mode 100644
index 0000000..0d1fabe
--- /dev/null
+++ b/liboctave/mx-ui8-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_i64nda_h)
+#define octave_mx_ui8_i64nda_h 1
+#include "oct-inttypes.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, int64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-i8nda.cc b/liboctave/mx-ui8-i8nda.cc
new file mode 100644
index 0000000..b00a1e7
--- /dev/null
+++ b/liboctave/mx-ui8-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , int8NDArray, , uint8_t, int8_t)
+SND_BOOL_OPS2 (octave_uint8, int8NDArray, octave_uint8::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui8-i8nda.h b/liboctave/mx-ui8-i8nda.h
new file mode 100644
index 0000000..35e9792
--- /dev/null
+++ b/liboctave/mx-ui8-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_i8nda_h)
+#define octave_mx_ui8_i8nda_h 1
+#include "oct-inttypes.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, int8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-nda.cc b/liboctave/mx-ui8-nda.cc
new file mode 100644
index 0000000..50b2c93
--- /dev/null
+++ b/liboctave/mx-ui8-nda.cc
@@ -0,0 +1,15 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+SND_BIN_OPS (uint8NDArray, octave_uint8, NDArray)
+SND_CMP_OPS1 (octave_uint8, , NDArray, , uint8_t)
+SND_BOOL_OPS2 (octave_uint8, NDArray, octave_uint8::zero, 0.0)
diff --git a/liboctave/mx-ui8-nda.h b/liboctave/mx-ui8-nda.h
new file mode 100644
index 0000000..8be1a12
--- /dev/null
+++ b/liboctave/mx-ui8-nda.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_nda_h)
+#define octave_mx_ui8_nda_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+SND_BIN_OP_DECLS (uint8NDArray, octave_uint8, NDArray, OCTAVE_API)
+SND_CMP_OP_DECLS (octave_uint8, NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-ui16nda.cc b/liboctave/mx-ui8-ui16nda.cc
new file mode 100644
index 0000000..06f164b
--- /dev/null
+++ b/liboctave/mx-ui8-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , uint16NDArray, , uint8_t, uint16_t)
+SND_BOOL_OPS2 (octave_uint8, uint16NDArray, octave_uint8::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui8-ui16nda.h b/liboctave/mx-ui8-ui16nda.h
new file mode 100644
index 0000000..7e83b5d
--- /dev/null
+++ b/liboctave/mx-ui8-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_ui16nda_h)
+#define octave_mx_ui8_ui16nda_h 1
+#include "oct-inttypes.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-ui32nda.cc b/liboctave/mx-ui8-ui32nda.cc
new file mode 100644
index 0000000..72aec6b
--- /dev/null
+++ b/liboctave/mx-ui8-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , uint32NDArray, , uint8_t, uint32_t)
+SND_BOOL_OPS2 (octave_uint8, uint32NDArray, octave_uint8::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui8-ui32nda.h b/liboctave/mx-ui8-ui32nda.h
new file mode 100644
index 0000000..906a5cd
--- /dev/null
+++ b/liboctave/mx-ui8-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_ui32nda_h)
+#define octave_mx_ui8_ui32nda_h 1
+#include "oct-inttypes.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8-ui64nda.cc b/liboctave/mx-ui8-ui64nda.cc
new file mode 100644
index 0000000..40f741b
--- /dev/null
+++ b/liboctave/mx-ui8-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+SND_CMP_OPS2 (octave_uint8, , uint64NDArray, , uint8_t, uint64_t)
+SND_BOOL_OPS2 (octave_uint8, uint64NDArray, octave_uint8::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui8-ui64nda.h b/liboctave/mx-ui8-ui64nda.h
new file mode 100644
index 0000000..72edb54
--- /dev/null
+++ b/liboctave/mx-ui8-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8_ui64nda_h)
+#define octave_mx_ui8_ui64nda_h 1
+#include "oct-inttypes.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+SND_CMP_OP_DECLS (octave_uint8, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-fnda.cc b/liboctave/mx-ui8nda-fnda.cc
new file mode 100644
index 0000000..8522ee1
--- /dev/null
+++ b/liboctave/mx-ui8nda-fnda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-fnda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "fNDArray.h"
+NDND_BIN_OPS (uint8NDArray, uint8NDArray, FloatNDArray)
+NDND_CMP_OPS (uint8NDArray, , FloatNDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, FloatNDArray, octave_uint8::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui8nda-fnda.h b/liboctave/mx-ui8nda-fnda.h
new file mode 100644
index 0000000..6642bc6
--- /dev/null
+++ b/liboctave/mx-ui8nda-fnda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_fnda_h)
+#define octave_mx_ui8nda_fnda_h 1
+#include "uint8NDArray.h"
+#include "fNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint8NDArray, uint8NDArray, FloatNDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint8NDArray, FloatNDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, FloatNDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-fs.cc b/liboctave/mx-ui8nda-fs.cc
new file mode 100644
index 0000000..996d342
--- /dev/null
+++ b/liboctave/mx-ui8nda-fs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-fs.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+NDS_BIN_OPS (uint8NDArray, uint8NDArray, float)
+NDS_CMP_OPS1 (uint8NDArray, , float, , uint8_t)
+NDS_BOOL_OPS2 (uint8NDArray, float, octave_uint8::zero, static_cast<float>(0.0))
diff --git a/liboctave/mx-ui8nda-fs.h b/liboctave/mx-ui8nda-fs.h
new file mode 100644
index 0000000..3fca885
--- /dev/null
+++ b/liboctave/mx-ui8nda-fs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_fs_h)
+#define octave_mx_ui8nda_fs_h 1
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint8NDArray, uint8NDArray, float, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint8NDArray, float, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, float, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i16.cc b/liboctave/mx-ui8nda-i16.cc
new file mode 100644
index 0000000..dec74a9
--- /dev/null
+++ b/liboctave/mx-ui8nda-i16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_int16, , uint8_t, int16_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_int16, octave_uint8::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui8nda-i16.h b/liboctave/mx-ui8nda-i16.h
new file mode 100644
index 0000000..74a088b
--- /dev/null
+++ b/liboctave/mx-ui8nda-i16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i16_h)
+#define octave_mx_ui8nda_i16_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_int16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_int16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i16nda.cc b/liboctave/mx-ui8nda-i16nda.cc
new file mode 100644
index 0000000..5965f69
--- /dev/null
+++ b/liboctave/mx-ui8nda-i16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "int16NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , int16NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, int16NDArray, octave_uint8::zero, octave_int16::zero)
diff --git a/liboctave/mx-ui8nda-i16nda.h b/liboctave/mx-ui8nda-i16nda.h
new file mode 100644
index 0000000..63eeb44
--- /dev/null
+++ b/liboctave/mx-ui8nda-i16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i16nda_h)
+#define octave_mx_ui8nda_i16nda_h 1
+#include "uint8NDArray.h"
+#include "int16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, int16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, int16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i32.cc b/liboctave/mx-ui8nda-i32.cc
new file mode 100644
index 0000000..d5cd3b8
--- /dev/null
+++ b/liboctave/mx-ui8nda-i32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_int32, , uint8_t, int32_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_int32, octave_uint8::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui8nda-i32.h b/liboctave/mx-ui8nda-i32.h
new file mode 100644
index 0000000..76d3d6c
--- /dev/null
+++ b/liboctave/mx-ui8nda-i32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i32_h)
+#define octave_mx_ui8nda_i32_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_int32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_int32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i32nda.cc b/liboctave/mx-ui8nda-i32nda.cc
new file mode 100644
index 0000000..79886b8
--- /dev/null
+++ b/liboctave/mx-ui8nda-i32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "int32NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , int32NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, int32NDArray, octave_uint8::zero, octave_int32::zero)
diff --git a/liboctave/mx-ui8nda-i32nda.h b/liboctave/mx-ui8nda-i32nda.h
new file mode 100644
index 0000000..ab518ca
--- /dev/null
+++ b/liboctave/mx-ui8nda-i32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i32nda_h)
+#define octave_mx_ui8nda_i32nda_h 1
+#include "uint8NDArray.h"
+#include "int32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, int32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, int32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i64.cc b/liboctave/mx-ui8nda-i64.cc
new file mode 100644
index 0000000..9e8e0d3
--- /dev/null
+++ b/liboctave/mx-ui8nda-i64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_int64, , uint8_t, int64_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_int64, octave_uint8::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui8nda-i64.h b/liboctave/mx-ui8nda-i64.h
new file mode 100644
index 0000000..5bd8963
--- /dev/null
+++ b/liboctave/mx-ui8nda-i64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i64_h)
+#define octave_mx_ui8nda_i64_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_int64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_int64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i64nda.cc b/liboctave/mx-ui8nda-i64nda.cc
new file mode 100644
index 0000000..73b10f9
--- /dev/null
+++ b/liboctave/mx-ui8nda-i64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "int64NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , int64NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, int64NDArray, octave_uint8::zero, octave_int64::zero)
diff --git a/liboctave/mx-ui8nda-i64nda.h b/liboctave/mx-ui8nda-i64nda.h
new file mode 100644
index 0000000..b25c5ae
--- /dev/null
+++ b/liboctave/mx-ui8nda-i64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i64nda_h)
+#define octave_mx_ui8nda_i64nda_h 1
+#include "uint8NDArray.h"
+#include "int64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, int64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, int64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i8.cc b/liboctave/mx-ui8nda-i8.cc
new file mode 100644
index 0000000..e347d7d
--- /dev/null
+++ b/liboctave/mx-ui8nda-i8.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i8.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_int8, , uint8_t, int8_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_int8, octave_uint8::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui8nda-i8.h b/liboctave/mx-ui8nda-i8.h
new file mode 100644
index 0000000..e8df97a
--- /dev/null
+++ b/liboctave/mx-ui8nda-i8.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i8_h)
+#define octave_mx_ui8nda_i8_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_int8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_int8, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-i8nda.cc b/liboctave/mx-ui8nda-i8nda.cc
new file mode 100644
index 0000000..ccc8ba0
--- /dev/null
+++ b/liboctave/mx-ui8nda-i8nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-i8nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "int8NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , int8NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, int8NDArray, octave_uint8::zero, octave_int8::zero)
diff --git a/liboctave/mx-ui8nda-i8nda.h b/liboctave/mx-ui8nda-i8nda.h
new file mode 100644
index 0000000..c2357bf
--- /dev/null
+++ b/liboctave/mx-ui8nda-i8nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_i8nda_h)
+#define octave_mx_ui8nda_i8nda_h 1
+#include "uint8NDArray.h"
+#include "int8NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, int8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, int8NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-nda.cc b/liboctave/mx-ui8nda-nda.cc
new file mode 100644
index 0000000..10b1f4b
--- /dev/null
+++ b/liboctave/mx-ui8nda-nda.cc
@@ -0,0 +1,14 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "dNDArray.h"
+NDND_BIN_OPS (uint8NDArray, uint8NDArray, NDArray)
+NDND_CMP_OPS (uint8NDArray, , NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, NDArray, octave_uint8::zero, 0.0)
diff --git a/liboctave/mx-ui8nda-nda.h b/liboctave/mx-ui8nda-nda.h
new file mode 100644
index 0000000..38b81e3
--- /dev/null
+++ b/liboctave/mx-ui8nda-nda.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_nda_h)
+#define octave_mx_ui8nda_nda_h 1
+#include "uint8NDArray.h"
+#include "dNDArray.h"
+#include "mx-op-decl.h"
+NDND_BIN_OP_DECLS (uint8NDArray, uint8NDArray, NDArray, OCTAVE_API)
+NDND_CMP_OP_DECLS (uint8NDArray, NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-s.cc b/liboctave/mx-ui8nda-s.cc
new file mode 100644
index 0000000..480a2d3
--- /dev/null
+++ b/liboctave/mx-ui8nda-s.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-s.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+NDS_BIN_OPS (uint8NDArray, uint8NDArray, double)
+NDS_CMP_OPS1 (uint8NDArray, , double, , uint8_t)
+NDS_BOOL_OPS2 (uint8NDArray, double, octave_uint8::zero, 0.0)
diff --git a/liboctave/mx-ui8nda-s.h b/liboctave/mx-ui8nda-s.h
new file mode 100644
index 0000000..de9f5bd
--- /dev/null
+++ b/liboctave/mx-ui8nda-s.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_s_h)
+#define octave_mx_ui8nda_s_h 1
+#include "uint8NDArray.h"
+#include "mx-op-decl.h"
+NDS_BIN_OP_DECLS (uint8NDArray, uint8NDArray, double, OCTAVE_API)
+NDS_CMP_OP_DECLS (uint8NDArray, double, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, double, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-ui16.cc b/liboctave/mx-ui8nda-ui16.cc
new file mode 100644
index 0000000..7c66074
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui16.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-ui16.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_uint16, , uint8_t, uint16_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_uint16, octave_uint8::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui8nda-ui16.h b/liboctave/mx-ui8nda-ui16.h
new file mode 100644
index 0000000..f7ce56b
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui16.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_ui16_h)
+#define octave_mx_ui8nda_ui16_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_uint16, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-ui16nda.cc b/liboctave/mx-ui8nda-ui16nda.cc
new file mode 100644
index 0000000..86d9f68
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui16nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-ui16nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "uint16NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , uint16NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, uint16NDArray, octave_uint8::zero, octave_uint16::zero)
diff --git a/liboctave/mx-ui8nda-ui16nda.h b/liboctave/mx-ui8nda-ui16nda.h
new file mode 100644
index 0000000..4e02042
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui16nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_ui16nda_h)
+#define octave_mx_ui8nda_ui16nda_h 1
+#include "uint8NDArray.h"
+#include "uint16NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, uint16NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-ui32.cc b/liboctave/mx-ui8nda-ui32.cc
new file mode 100644
index 0000000..fe4bf4f
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui32.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-ui32.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_uint32, , uint8_t, uint32_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_uint32, octave_uint8::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui8nda-ui32.h b/liboctave/mx-ui8nda-ui32.h
new file mode 100644
index 0000000..f9c5601
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui32.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_ui32_h)
+#define octave_mx_ui8nda_ui32_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_uint32, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-ui32nda.cc b/liboctave/mx-ui8nda-ui32nda.cc
new file mode 100644
index 0000000..b0c4515
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui32nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-ui32nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "uint32NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , uint32NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, uint32NDArray, octave_uint8::zero, octave_uint32::zero)
diff --git a/liboctave/mx-ui8nda-ui32nda.h b/liboctave/mx-ui8nda-ui32nda.h
new file mode 100644
index 0000000..5e3d73a
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui32nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_ui32nda_h)
+#define octave_mx_ui8nda_ui32nda_h 1
+#include "uint8NDArray.h"
+#include "uint32NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, uint32NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-ui64.cc b/liboctave/mx-ui8nda-ui64.cc
new file mode 100644
index 0000000..632520a
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui64.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-ui64.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+NDS_CMP_OPS2 (uint8NDArray, , octave_uint64, , uint8_t, uint64_t)
+NDS_BOOL_OPS2 (uint8NDArray, octave_uint64, octave_uint8::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui8nda-ui64.h b/liboctave/mx-ui8nda-ui64.h
new file mode 100644
index 0000000..688ec7f
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui64.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_ui64_h)
+#define octave_mx_ui8nda_ui64_h 1
+#include "uint8NDArray.h"
+#include "oct-inttypes.h"
+#include "mx-op-decl.h"
+NDS_CMP_OP_DECLS (uint8NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_uint64, OCTAVE_API)
+#endif
diff --git a/liboctave/mx-ui8nda-ui64nda.cc b/liboctave/mx-ui8nda-ui64nda.cc
new file mode 100644
index 0000000..85c8a30
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui64nda.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "mx-ui8nda-ui64nda.h"
+#include "mx-op-defs.h"
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "uint8NDArray.h"
+#include "uint64NDArray.h"
+NDND_CMP_OPS (uint8NDArray, , uint64NDArray, )
+NDND_BOOL_OPS2 (uint8NDArray, uint64NDArray, octave_uint8::zero, octave_uint64::zero)
diff --git a/liboctave/mx-ui8nda-ui64nda.h b/liboctave/mx-ui8nda-ui64nda.h
new file mode 100644
index 0000000..3eb0d2e
--- /dev/null
+++ b/liboctave/mx-ui8nda-ui64nda.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_mx_ui8nda_ui64nda_h)
+#define octave_mx_ui8nda_ui64nda_h 1
+#include "uint8NDArray.h"
+#include "uint64NDArray.h"
+#include "mx-op-decl.h"
+NDND_CMP_OP_DECLS (uint8NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, uint64NDArray, OCTAVE_API)
+#endif
diff --git a/liboctave/oct-alloc.cc b/liboctave/oct-alloc.cc
new file mode 100644
index 0000000..8d78cb6
--- /dev/null
+++ b/liboctave/oct-alloc.cc
@@ -0,0 +1,111 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <new>
+
+#include "oct-alloc.h"
+
+void *
+octave_allocator::alloc (size_t size)
+{
+  if (size != item_size)
+    return ::new char [size];
+
+  if (! head)
+    {
+      if (! grow ())
+	return 0;
+    }
+
+  link *tmp = head;
+  head = head->next;
+  return tmp;
+}
+
+// FIXME -- if we free the last item on the list, shouldn't we
+// also free the underlying character array used for storage?
+
+void
+octave_allocator::free (void *p, size_t size)
+{
+  if (size != item_size)
+    ::delete [] (static_cast<char *> (p));
+  else
+    {
+      link *tmp = static_cast<link *> (p);
+      tmp->next = head;
+      head = tmp;
+    }
+}
+
+// Return TRUE for successful allocation, FALSE otherwise.
+
+bool
+octave_allocator::grow (void)
+{
+  bool retval = true;
+
+  char *start = new char [grow_size * item_size];
+
+  if (start)
+    {
+      char *last = &start[(grow_size - 1) * item_size];
+
+      char *p = start;
+      while (p < last)
+	{
+	  char *next = p + item_size;
+	  (reinterpret_cast<link *> (p)) -> next
+	    = reinterpret_cast<link *> (next);
+	  p = next;
+	}
+
+      (reinterpret_cast<link *> (last)) -> next = 0;
+
+      head = reinterpret_cast<link *> (start);
+    }
+  else
+    {
+      typedef void (*error_handler_function) (void);
+
+      error_handler_function f = std::set_new_handler (0);
+      std::set_new_handler (f);
+
+      if (f)
+	f ();
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-alloc.h b/liboctave/oct-alloc.h
new file mode 100644
index 0000000..13fb9f0
--- /dev/null
+++ b/liboctave/oct-alloc.h
@@ -0,0 +1,96 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2002, 2003, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_alloc_h)
+#define octave_oct_alloc_h 1
+
+class
+OCTAVE_API
+octave_allocator
+{
+public:
+
+  octave_allocator (size_t item_sz, int grow_sz = 256)
+    : head (0), grow_size (grow_sz),
+      item_size (item_sz > sizeof (link *) ? item_sz : sizeof (link *))
+  { }
+
+  // Get an object from the free list, possibly increasing the size of
+  // the free list.
+  void *alloc (size_t size);
+
+  // Put objects back on the free list.
+  void free (void *p, size_t size);
+
+private:
+
+  // Structure for internal free list management.
+  struct link { link *next; };
+
+  // Front of the free list.
+  link *head;
+
+  // How many objects to get each time we call the global operator new.
+  int grow_size;
+
+  // The size of each item on the list (or, if that is smaller than
+  // the size of list*, the size of list*.
+  size_t item_size;
+
+  // How to grow the free list.
+  bool grow (void);
+};
+
+#if defined (HAVE_PLACEMENT_DELETE)
+#define DECLARE_OCTAVE_ALLOCATOR_PLACEMENT_DELETE \
+    void operator delete (void *p, void *) \
+      { ::operator delete (p, static_cast<void*> (0)); }
+#else
+#define DECLARE_OCTAVE_ALLOCATOR_PLACEMENT_DELETE \
+    void operator delete (void *p, void *) \
+      { ::operator delete (p); }
+#endif
+
+#define DECLARE_OCTAVE_ALLOCATOR \
+  public: \
+    void *operator new (size_t size, void *p) \
+      { return ::operator new (size, p); } \
+    DECLARE_OCTAVE_ALLOCATOR_PLACEMENT_DELETE \
+    void *operator new (size_t size) { return allocator.alloc (size); } \
+    void operator delete (void *p, size_t size) { allocator.free (p, size); } \
+  private: \
+    static octave_allocator allocator;
+
+#define DEFINE_OCTAVE_ALLOCATOR(t) \
+  octave_allocator t::allocator (sizeof (t))
+
+#define DEFINE_OCTAVE_ALLOCATOR2(t, s) \
+  octave_allocator t::allocator (sizeof (t), s)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-cmplx.h b/liboctave/oct-cmplx.h
new file mode 100644
index 0000000..0f671f5
--- /dev/null
+++ b/liboctave/oct-cmplx.h
@@ -0,0 +1,56 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2000, 2001, 2004, 2005, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_cmplx_h)
+#define octave_oct_cmplx_h 1
+
+#include <complex>
+
+typedef std::complex<double> Complex;
+typedef std::complex<float> FloatComplex;
+
+// The default comparison of complex number is to compare by abs, then by arg.
+// FIXME: this could be speeded up significantly.
+template <class T>
+inline bool operator < (const std::complex<T>& a,
+                        const std::complex<T>& b)
+{
+  T ax = std::abs (a), bx = std::abs (b);
+  return ax < bx || (ax == bx && std::arg (a) < std::arg (b));
+}
+
+template <class T>
+inline bool operator > (const std::complex<T>& a,
+                        const std::complex<T>& b)
+{
+  T ax = std::abs (a), bx = std::abs (b);
+  return ax > bx || (ax == bx && std::arg (a) > std::arg (b));
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-env.cc b/liboctave/oct-env.cc
new file mode 100644
index 0000000..7e590c2
--- /dev/null
+++ b/liboctave/oct-env.cc
@@ -0,0 +1,550 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+The functions listed below were adapted from a similar functions
+from GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991
+Free Software Foundation, Inc.
+
+  octave_env::do_absolute_pathname
+  octave_env::do_base_pathname
+  octave_env::do_chdir
+  octave_env::do_getcwd
+  octave_env::do_make_absolute
+  octave_env::do_polite_directory_format
+  octave_env::pathname_backup
+
+*/ 
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "file-ops.h"
+#include "lo-error.h"
+#include "lo-sysdep.h"
+#include "lo-utils.h"
+#include "oct-env.h"
+#include "oct-passwd.h"
+#include "oct-syscalls.h"
+
+octave_env::octave_env (void)
+  : follow_symbolic_links (true), verbatim_pwd (true),
+    current_directory (), program_name (), program_invocation_name (),
+    user_name (), host_name ()
+{
+  // Get a real value for the current directory.
+  do_getcwd ();
+
+  // Etc.
+  do_get_user_name ();
+
+  do_get_host_name ();
+}
+
+octave_env *octave_env::instance = 0;
+
+bool
+octave_env::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_env ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create current working directory object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+std::string
+octave_env::polite_directory_format (const std::string& name)
+{
+  return (instance_ok ())
+    ? instance->do_polite_directory_format (name) : std::string ();
+}
+
+bool
+octave_env::absolute_pathname (const std::string& s)
+{
+  return (instance_ok ())
+    ? instance->do_absolute_pathname (s) : false;
+}
+
+bool
+octave_env::rooted_relative_pathname (const std::string& s)
+{
+  return (instance_ok ())
+    ? instance->do_rooted_relative_pathname (s) : false;
+}
+
+std::string
+octave_env::base_pathname (const std::string& s)
+{
+  return (instance_ok ())
+    ? instance->do_base_pathname (s) : std::string ();
+}
+
+std::string
+octave_env::make_absolute (const std::string& s, const std::string& dot_path)
+{
+  return (instance_ok ())
+    ? instance->do_make_absolute (s, dot_path) : std::string ();
+}
+
+std::string
+octave_env::getcwd ()
+{
+  return (instance_ok ())
+    ? instance->do_getcwd () : std::string ();
+}
+
+std::string
+octave_env::get_home_directory ()
+{
+  return (instance_ok ())
+    ? instance->do_get_home_directory () : std::string ();
+}
+
+std::string
+octave_env::get_program_name (void)
+{
+  return (instance_ok ())
+    ? instance->program_name : std::string ();
+}
+
+std::string
+octave_env::get_program_invocation_name (void)
+{
+  return (instance_ok ())
+    ? instance->program_invocation_name : std::string ();
+}
+
+void
+octave_env::set_program_name (const std::string& s)
+{
+  if (instance_ok ())
+    instance->do_set_program_name (s);
+}
+
+std::string
+octave_env::get_user_name (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_user_name () : std::string ();
+}
+
+std::string
+octave_env::get_host_name (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_host_name () : std::string ();
+}
+
+// FIXME -- this leaves no way to distinguish between a
+// variable that is not set and one that is set to the empty string.
+// Is this a problem?
+
+std::string
+octave_env::getenv (const std::string& name)
+{
+  return (instance_ok ())
+    ? instance->do_getenv (name) : std::string ();
+}
+
+void
+octave_env::putenv (const std::string& name, const std::string& value)
+{
+  octave_putenv (name, value);
+}
+
+bool
+octave_env::have_x11_display (void)
+{
+  std::string display = getenv ("DISPLAY");
+
+  return ! display.empty ();
+}
+
+bool
+octave_env::chdir (const std::string& newdir)
+{
+  return (instance_ok ())
+    ? instance->do_chdir (newdir) : false;
+}
+
+void
+octave_env::do_set_program_name (const std::string& s) const
+{
+  program_invocation_name = s;
+
+  size_t pos
+    = program_invocation_name.find_last_of (file_ops::dir_sep_chars ());
+
+  program_name = (pos == std::string::npos)
+    ? program_invocation_name : program_invocation_name.substr (pos+1);
+}
+
+// Return a pretty pathname.  If the first part of the pathname is the
+// same as $HOME, then replace that with `~'.
+
+std::string
+octave_env::do_polite_directory_format (const std::string& name) const
+{
+  std::string retval;
+
+  std::string home_dir = do_get_home_directory ();
+
+  size_t len = home_dir.length ();
+
+  if (len > 1 && home_dir == name.substr (0, len)
+      && (name.length () == len || file_ops::is_dir_sep (name[len])))
+    {
+      retval = "~";
+      retval.append (name.substr (len));
+    }
+  else
+    retval = name;
+
+  return retval;
+}
+
+bool
+octave_env::do_absolute_pathname (const std::string& s) const
+{
+  size_t len = s.length ();
+
+  if (len == 0)
+    return false;
+
+  if (file_ops::is_dir_sep (s[0]))
+    return true;
+
+#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
+  if ((len == 2 && isalpha (s[0]) && s[1] == ':')
+      || (len > 2 && isalpha (s[0]) && s[1] == ':'
+	  && file_ops::is_dir_sep (s[2])))
+    return true;
+#endif
+
+  return false;
+}
+
+bool
+octave_env::do_rooted_relative_pathname (const std::string& s) const
+{
+  size_t len = s.length ();
+
+  if (len == 0)
+    return false;
+
+  if (len == 1 && s[0] == '.')
+    return true;
+
+  if (len > 1 && s[0] == '.' && file_ops::is_dir_sep (s[1]))
+    return true;
+
+  if (len == 2 && s[0] == '.' && s[1] == '.')
+    return true;
+
+  if (len > 2 && s[0] == '.' && s[1] == '.' && file_ops::is_dir_sep (s[2]))
+    return true;
+
+  return false;
+}
+
+// Return the `basename' of the pathname in STRING (the stuff after
+// the last directory separator).  If STRING is not a full pathname,
+// simply return it.
+
+std::string
+octave_env::do_base_pathname (const std::string& s) const
+{
+  if (! (do_absolute_pathname (s) || do_rooted_relative_pathname (s)))
+    return s;
+
+  size_t pos = s.find_last_of (file_ops::dir_sep_chars ());
+
+  if (pos == std::string::npos)
+    return s;
+  else
+    return s.substr (pos+1);
+}
+
+// Turn STRING (a pathname) into an absolute pathname, assuming that
+// DOT_PATH contains the symbolic location of the current directory.
+
+std::string
+octave_env::do_make_absolute (const std::string& s,
+			      const std::string& dot_path) const
+{
+#if defined (__EMX__)
+  if (s.length () > 1 && s[1] == ':')
+    return s;
+#endif
+
+  if (dot_path.empty () || s.empty () || do_absolute_pathname (s))
+    return s;
+
+  std::string current_dir = dot_path;
+
+  if (current_dir.empty ())
+    current_dir = do_getcwd ();
+
+  size_t pos = current_dir.length () - 1;
+
+  if (! file_ops::is_dir_sep (current_dir[pos]))
+    current_dir.append (file_ops::dir_sep_str ());
+
+  // FIXME -- this is probably not correct for all systems.
+
+  size_t i = 0;
+  size_t slen = s.length ();
+
+  while (i < slen)
+    {
+      if (s[i] == '.')
+	{
+	  if (i + 1 == slen)
+	    return current_dir;
+
+	  if (file_ops::is_dir_sep (s[i+1]))
+	    {
+	      i += 2;
+	      continue;
+	    }
+
+	  if (s[i+1] == '.'
+	      && (i + 2 == slen || file_ops::is_dir_sep (s[i+2])))
+	    {
+	      i += 2;
+
+	      if (i != slen)
+		i++;
+
+	      pathname_backup (current_dir, 1);
+
+	      continue;
+	    }
+	}
+
+      size_t tmp = s.find_first_of (file_ops::dir_sep_chars (), i);
+
+      if (tmp == std::string::npos)
+	{
+	  current_dir.append (s, i, tmp-i);
+	  break;
+	}
+      else
+	{
+	  current_dir.append (s, i, tmp-i+1);
+	  i = tmp + 1;
+	}
+    }
+
+  return current_dir;
+}
+
+// Return a string which is the current working directory.
+
+std::string
+octave_env::do_getcwd () const
+{
+  if (! follow_symbolic_links)
+    current_directory = "";
+
+  if (verbatim_pwd || current_directory.empty ())
+    current_directory = ::octave_getcwd ();
+
+  return current_directory;
+}
+
+// This value is not cached because it can change while Octave is
+// running.
+
+std::string
+octave_env::do_get_home_directory (void) const
+{
+  std::string hd = do_getenv ("HOME");
+
+#if defined (__MINGW32__) || defined (_MSC_VER)
+  // Maybe we are started directly from cmd.exe.
+  if (hd.empty ())
+    {
+      std::string drv = do_getenv ("HOMEDRIVE");
+      if (drv.empty ())
+	hd = do_getenv ("HOMEPATH");
+      else
+	hd = drv + do_getenv ("HOMEPATH");
+    }
+#endif
+
+  if (hd.empty ())
+    {
+      octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
+
+      hd = pw ? pw.dir () : std::string (file_ops::dir_sep_str ());
+    }
+
+  return hd;
+}
+
+std::string
+octave_env::do_get_user_name (void) const
+{
+  if (user_name.empty ())
+    {
+      octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
+
+      user_name = pw ? pw.name () : std::string ("unknown");
+    }
+
+  return user_name;
+}
+
+std::string
+octave_env::do_get_host_name (void) const
+{
+  if (host_name.empty ())
+    {
+      char hostname[256];
+
+      int status = octave_gethostname (hostname, 255);
+
+      host_name = (status < 0) ? "unknown" : hostname;
+    }
+
+  return host_name;
+}
+
+std::string
+octave_env::do_getenv (const std::string& name) const
+{
+  char *value = ::getenv (name.c_str ());
+
+  return value ? value : "";
+}
+
+// Do the work of changing to the directory NEWDIR.  Handle symbolic
+// link following, etc.
+
+bool
+octave_env::do_chdir (const std::string& newdir)
+{
+  bool retval = false;
+
+  std::string tmp;
+
+  if (follow_symbolic_links)
+    {
+      if (current_directory.empty ())
+	do_getcwd ();
+
+      if (current_directory.empty ())
+	tmp = newdir;
+      else
+	tmp = do_make_absolute (newdir, current_directory);
+
+      // Get rid of trailing directory separator.
+
+      size_t len = tmp.length ();
+
+      if (len > 1)
+	{
+	  if (file_ops::is_dir_sep (tmp[--len]))
+	    tmp.resize (len);
+	}
+
+      if (! ::octave_chdir (tmp))
+	{
+	  current_directory = tmp;
+	  retval = true;
+	}
+    }
+  else
+    retval = (! ::octave_chdir (newdir));
+
+  return retval;
+}
+
+// Remove the last N directories from PATH.
+
+void
+octave_env::pathname_backup (std::string& path, int n) const
+{
+  if (path.empty ())
+    return;
+
+  size_t i = path.length () - 1;
+
+  while (n--)
+    {
+      while (file_ops::is_dir_sep (path[i]) && i > 0)
+	i--;
+
+      while (! file_ops::is_dir_sep (path[i]) && i > 0)
+	i--;
+
+      i++;
+    }
+
+  path.resize (i);
+}
+
+void
+octave_env::error (int err_num) const
+{
+  (*current_liboctave_error_handler) ("%s", strerror (err_num));
+}
+
+void
+octave_env::error (const std::string& s) const
+{
+  (*current_liboctave_error_handler) ("%s", s.c_str ());
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-env.h b/liboctave/oct-env.h
new file mode 100644
index 0000000..dad7a38
--- /dev/null
+++ b/liboctave/oct-env.h
@@ -0,0 +1,144 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_env_h)
+#define octave_env_h 1
+
+#include <string>
+
+class
+OCTAVE_API
+octave_env
+{
+protected:
+
+  octave_env (void);
+
+public:
+
+  static std::string polite_directory_format (const std::string& name);
+
+  static bool absolute_pathname (const std::string& s);
+
+  static bool rooted_relative_pathname (const std::string& s);
+
+  static std::string base_pathname (const std::string& s);
+
+  static std::string make_absolute (const std::string& s,
+				    const std::string& dot_path);
+
+  static std::string getcwd (void);
+
+  static std::string get_home_directory (void);
+
+  static std::string get_program_name (void);
+
+  static std::string get_program_invocation_name (void);
+
+  static std::string get_user_name (void);
+
+  static std::string get_host_name (void);
+
+  static std::string getenv (const std::string& name);
+
+  static void putenv (const std::string& name, const std::string& value);
+
+  static bool have_x11_display (void);
+
+  static bool chdir (const std::string& newdir);
+
+  static void set_program_name (const std::string& s);
+
+private:
+
+  static bool instance_ok (void);
+
+  std::string do_polite_directory_format (const std::string& name) const;
+
+  bool do_absolute_pathname (const std::string& s) const;
+
+  bool do_rooted_relative_pathname (const std::string& s) const;
+
+  std::string do_base_pathname (const std::string& s) const;
+
+  std::string do_make_absolute (const std::string& s,
+				const std::string& dot_path) const;
+
+  std::string do_getcwd (void) const;
+
+  std::string do_get_home_directory (void) const;
+
+  std::string do_get_user_name (void) const;
+
+  std::string do_get_host_name (void) const;
+
+  std::string do_getenv (const std::string& name) const;
+
+  void do_putenv (const std::string& name, const std::string& value) const;
+
+  bool do_chdir (const std::string& newdir);
+
+  void do_set_program_name (const std::string& s) const;
+
+  void pathname_backup (std::string& path, int n) const;
+
+  void error (int) const;
+
+  void error (const std::string&) const;
+
+  // No copying!
+
+  octave_env (const octave_env&);
+
+  octave_env& operator = (const octave_env&);
+
+  // The real thing.
+  static octave_env *instance;
+
+  // TRUE means follow symbolic links that point to directories just
+  // as if they are real directories.
+  bool follow_symbolic_links;
+
+  // TRUE means that pwd always give verbatim directory, regardless
+  // of symbolic link following.
+  bool verbatim_pwd;
+
+  // Where are we?
+  mutable std::string current_directory;
+
+  // Etc.
+  mutable std::string program_name;
+
+  mutable std::string program_invocation_name;
+
+  mutable std::string user_name;
+
+  mutable std::string host_name;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-fftw.cc b/liboctave/oct-fftw.cc
new file mode 100644
index 0000000..b4947e4
--- /dev/null
+++ b/liboctave/oct-fftw.cc
@@ -0,0 +1,972 @@
+/*
+
+Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (HAVE_FFTW3)
+
+#include <iostream>
+#include <vector>
+
+#include "lo-error.h"
+#include "oct-fftw.h"
+#include "quit.h"
+#include "oct-locbuf.h"
+
+// Helper class to create and cache fftw plans for both 1d and
+// 2d. This implementation defaults to using FFTW_ESTIMATE to create
+// the plans, which in theory is suboptimal, but provides quit
+// reasonable performance.
+
+// Also note that if FFTW_ESTIMATE is not used the planner in FFTW3
+// destroys the input and output arrays. We must therefore create a
+// temporary input array with the same size and 16-byte alignment as
+// the original array and use that for the planner. Note that we also
+// use any wisdom that is available, either in a FFTW3 system wide file
+//  or as supplied by the user.
+
+// FIXME -- if we can ensure 16 byte alignment in Array<T>
+// (<T> *data) the FFTW3 can use SIMD instructions for further
+// acceleration.
+
+// Note that it is profitable to store the FFTW3 plans, for small
+// ffts.
+
+octave_fftw_planner::octave_fftw_planner (void)
+{
+  meth = ESTIMATE;
+
+  plan[0] = plan[1] = 0;
+  d[0] = d[1] = s[0] = s[1] = r[0] = r[1] = h[0] = h[1] = 0;
+  simd_align[0] = simd_align[1] = false;
+  inplace[0] = inplace[1] = false;
+  n[0] = n[1] = dim_vector ();
+
+  rplan = 0;
+  rd = rs = rr = rh = 0;
+  rsimd_align = false;
+  rn = dim_vector ();
+  
+  // If we have a system wide wisdom file, import it.
+  fftw_import_system_wisdom ();
+}
+
+octave_fftw_planner::FftwMethod
+octave_fftw_planner::method (void)
+{
+  return meth;
+}
+
+octave_fftw_planner::FftwMethod
+octave_fftw_planner::method (FftwMethod _meth)
+{
+  FftwMethod ret = meth;
+  if (_meth == ESTIMATE || _meth == MEASURE || 
+      _meth == PATIENT || _meth == EXHAUSTIVE ||
+      _meth == HYBRID)
+    {
+      if (meth != _meth) 
+	{
+	  meth = _meth;
+	  if (rplan)
+	    fftw_destroy_plan (rplan);
+	  if (plan[0])
+	    fftw_destroy_plan (plan[0]);
+	  if (plan[1])
+	    fftw_destroy_plan (plan[1]);
+	  rplan = plan[0] = plan[1] = 0;
+	}
+    }
+  else
+    ret = UNKNOWN;
+  return ret;
+}
+
+#define CHECK_SIMD_ALIGNMENT(x) \
+  (((reinterpret_cast<ptrdiff_t> (x)) & 0xF) == 0)
+
+fftw_plan
+octave_fftw_planner::create_plan (int dir, const int rank,
+				  const dim_vector dims, octave_idx_type howmany,
+				  octave_idx_type stride, octave_idx_type dist, 
+				  const Complex *in, Complex *out)
+{
+  int which = (dir == FFTW_FORWARD) ? 0 : 1;
+  fftw_plan *cur_plan_p = &plan[which];
+  bool create_new_plan = false;
+  bool ioalign = CHECK_SIMD_ALIGNMENT (in) && CHECK_SIMD_ALIGNMENT (out);
+  bool ioinplace = (in == out);
+
+  // Don't create a new plan if we have a non SIMD plan already but
+  // can do SIMD.  This prevents endlessly recreating plans if we
+  // change the alignment.
+
+  if (plan[which] == 0 || d[which] != dist || s[which] != stride
+      || r[which] != rank || h[which] != howmany 
+      || ioinplace != inplace[which]
+      || ((ioalign != simd_align[which]) ? !ioalign : false))
+    create_new_plan = true;
+  else
+    {
+      // We still might not have the same shape of array.
+
+      for (int i = 0; i < rank; i++)
+	if (dims(i) != n[which](i))
+	  {
+	    create_new_plan = true;
+	    break;
+	  }
+    }
+
+  if (create_new_plan)
+    {
+      d[which] = dist;
+      s[which] = stride;
+      r[which] = rank;
+      h[which] = howmany;
+      simd_align[which] = ioalign;
+      inplace[which] = ioinplace;
+      n[which] = dims;
+
+      // Note reversal of dimensions for column major storage in FFTW.
+      octave_idx_type nn = 1;
+      OCTAVE_LOCAL_BUFFER (int, tmp, rank);
+
+      for (int i = 0, j = rank-1; i < rank; i++, j--)
+	{
+	  tmp[i] = dims(j);
+	  nn *= dims(j);
+	}
+
+      int plan_flags = 0;
+      bool plan_destroys_in = true;
+
+      switch (meth) 
+	{
+	case UNKNOWN:
+	case ESTIMATE:
+	  plan_flags |= FFTW_ESTIMATE;
+	  plan_destroys_in = false;
+	  break;
+	case MEASURE:
+	  plan_flags |= FFTW_MEASURE;
+	  break;
+	case PATIENT:
+	  plan_flags |= FFTW_PATIENT;
+	  break;
+	case EXHAUSTIVE:
+	  plan_flags |= FFTW_EXHAUSTIVE;
+	  break;
+	case HYBRID:
+	  if (nn < 8193)
+	    plan_flags |= FFTW_MEASURE;
+	  else
+	    {
+	      plan_flags |= FFTW_ESTIMATE;
+	      plan_destroys_in = false;
+	    }
+	  break;
+	}
+
+      if (ioalign)
+	plan_flags &= ~FFTW_UNALIGNED;
+      else
+	plan_flags |= FFTW_UNALIGNED;
+
+      if (*cur_plan_p)
+	fftw_destroy_plan (*cur_plan_p);
+
+      if (plan_destroys_in)
+	{
+	  // Create matrix with the same size and 16-byte alignment as input
+	  OCTAVE_LOCAL_BUFFER (Complex, itmp, nn * howmany + 32);
+	  itmp = reinterpret_cast<Complex *>
+	    (((reinterpret_cast<ptrdiff_t>(itmp) + 15) & ~ 0xF) + 
+	     ((reinterpret_cast<ptrdiff_t> (in)) & 0xF));
+
+	  *cur_plan_p =
+	    fftw_plan_many_dft (rank, tmp, howmany,
+	      reinterpret_cast<fftw_complex *> (itmp),
+	      0, stride, dist, reinterpret_cast<fftw_complex *> (out),
+	      0, stride, dist, dir, plan_flags);
+	}
+      else
+	{
+	  *cur_plan_p =
+	    fftw_plan_many_dft (rank, tmp, howmany,
+	      reinterpret_cast<fftw_complex *> (const_cast<Complex *> (in)),
+	      0, stride, dist, reinterpret_cast<fftw_complex *> (out),
+	      0, stride, dist, dir, plan_flags);
+	}
+
+      if (*cur_plan_p == 0)
+	(*current_liboctave_error_handler) ("Error creating fftw plan");
+    }
+
+  return *cur_plan_p;
+}
+ 
+fftw_plan
+octave_fftw_planner::create_plan (const int rank, const dim_vector dims, 
+				  octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, 
+				  const double *in, Complex *out)
+{
+  fftw_plan *cur_plan_p = &rplan;
+  bool create_new_plan = false;
+  bool ioalign = CHECK_SIMD_ALIGNMENT (in) && CHECK_SIMD_ALIGNMENT (out);
+
+  // Don't create a new plan if we have a non SIMD plan already but
+  // can do SIMD.  This prevents endlessly recreating plans if we
+  // change the alignment.
+
+  if (rplan == 0 || rd != dist || rs != stride || rr != rank
+      || rh != howmany || ((ioalign != rsimd_align) ? !ioalign : false))
+    create_new_plan = true;
+  else
+    {
+      // We still might not have the same shape of array.
+
+      for (int i = 0; i < rank; i++)
+	if (dims(i) != rn(i))
+	  {
+	    create_new_plan = true;
+	    break;
+	  }
+    }
+
+  if (create_new_plan)
+    {
+      rd = dist;
+      rs = stride;
+      rr = rank;
+      rh = howmany;
+      rsimd_align = ioalign;
+      rn = dims;
+
+      // Note reversal of dimensions for column major storage in FFTW.
+      octave_idx_type nn = 1;
+      OCTAVE_LOCAL_BUFFER (int, tmp, rank);
+
+      for (int i = 0, j = rank-1; i < rank; i++, j--)
+	{
+	  tmp[i] = dims(j);
+	  nn *= dims(j);
+	}
+
+      int plan_flags = 0;
+      bool plan_destroys_in = true;
+
+      switch (meth) 
+	{
+	case UNKNOWN:
+	case ESTIMATE:
+	  plan_flags |= FFTW_ESTIMATE;
+	  plan_destroys_in = false;
+	  break;
+	case MEASURE:
+	  plan_flags |= FFTW_MEASURE;
+	  break;
+	case PATIENT:
+	  plan_flags |= FFTW_PATIENT;
+	  break;
+	case EXHAUSTIVE:
+	  plan_flags |= FFTW_EXHAUSTIVE;
+	  break;
+	case HYBRID:
+	  if (nn < 8193)
+	    plan_flags |= FFTW_MEASURE;
+	  else
+	    {
+	      plan_flags |= FFTW_ESTIMATE;
+	      plan_destroys_in = false;
+	    }
+	  break;
+	}
+
+      if (ioalign)
+	plan_flags &= ~FFTW_UNALIGNED;
+      else
+	plan_flags |= FFTW_UNALIGNED;
+
+      if (*cur_plan_p)
+	fftw_destroy_plan (*cur_plan_p);
+
+      if (plan_destroys_in)
+	{
+	  // Create matrix with the same size and 16-byte alignment as input
+	  OCTAVE_LOCAL_BUFFER (double, itmp, nn + 32);
+	  itmp = reinterpret_cast<double *>
+	    (((reinterpret_cast<ptrdiff_t>(itmp) + 15) & ~ 0xF) + 
+	     ((reinterpret_cast<ptrdiff_t> (in)) & 0xF));
+
+	  *cur_plan_p =
+	    fftw_plan_many_dft_r2c (rank, tmp, howmany, itmp,
+	      0, stride, dist, reinterpret_cast<fftw_complex *> (out),
+	      0, stride, dist, plan_flags);
+	}
+      else
+	{
+	  *cur_plan_p =
+	    fftw_plan_many_dft_r2c (rank, tmp, howmany,
+	      (const_cast<double *> (in)),
+	      0, stride, dist, reinterpret_cast<fftw_complex *> (out),
+	      0, stride, dist, plan_flags);
+	}
+
+      if (*cur_plan_p == 0)
+	(*current_liboctave_error_handler) ("Error creating fftw plan");
+    }
+
+  return *cur_plan_p;
+}
+
+
+octave_float_fftw_planner::octave_float_fftw_planner (void)
+{
+  meth = ESTIMATE;
+
+  plan[0] = plan[1] = 0;
+  d[0] = d[1] = s[0] = s[1] = r[0] = r[1] = h[0] = h[1] = 0;
+  simd_align[0] = simd_align[1] = false;
+  inplace[0] = inplace[1] = false;
+  n[0] = n[1] = dim_vector ();
+
+  rplan = 0;
+  rd = rs = rr = rh = 0;
+  rsimd_align = false;
+  rn = dim_vector ();
+  
+  // If we have a system wide wisdom file, import it.
+  fftwf_import_system_wisdom ();
+}
+
+octave_float_fftw_planner::FftwMethod
+octave_float_fftw_planner::method (void)
+{
+  return meth;
+}
+
+octave_float_fftw_planner::FftwMethod
+octave_float_fftw_planner::method (FftwMethod _meth)
+{
+  FftwMethod ret = meth;
+  if (_meth == ESTIMATE || _meth == MEASURE || 
+      _meth == PATIENT || _meth == EXHAUSTIVE ||
+      _meth == HYBRID)
+    {
+      if (meth != _meth) 
+	{
+	  meth = _meth;
+	  if (rplan)
+	    fftwf_destroy_plan (rplan);
+	  if (plan[0])
+	    fftwf_destroy_plan (plan[0]);
+	  if (plan[1])
+	    fftwf_destroy_plan (plan[1]);
+	  rplan = plan[0] = plan[1] = 0;
+	}
+    }
+  else
+    ret = UNKNOWN;
+  return ret;
+}
+
+fftwf_plan
+octave_float_fftw_planner::create_plan (int dir, const int rank,
+				  const dim_vector dims, octave_idx_type howmany,
+				  octave_idx_type stride, octave_idx_type dist, 
+				  const FloatComplex *in, FloatComplex *out)
+{
+  int which = (dir == FFTW_FORWARD) ? 0 : 1;
+  fftwf_plan *cur_plan_p = &plan[which];
+  bool create_new_plan = false;
+  bool ioalign = CHECK_SIMD_ALIGNMENT (in) && CHECK_SIMD_ALIGNMENT (out);
+  bool ioinplace = (in == out);
+
+  // Don't create a new plan if we have a non SIMD plan already but
+  // can do SIMD.  This prevents endlessly recreating plans if we
+  // change the alignment.
+
+  if (plan[which] == 0 || d[which] != dist || s[which] != stride
+      || r[which] != rank || h[which] != howmany 
+      || ioinplace != inplace[which]
+      || ((ioalign != simd_align[which]) ? !ioalign : false))
+    create_new_plan = true;
+  else
+    {
+      // We still might not have the same shape of array.
+
+      for (int i = 0; i < rank; i++)
+	if (dims(i) != n[which](i))
+	  {
+	    create_new_plan = true;
+	    break;
+	  }
+    }
+
+  if (create_new_plan)
+    {
+      d[which] = dist;
+      s[which] = stride;
+      r[which] = rank;
+      h[which] = howmany;
+      simd_align[which] = ioalign;
+      inplace[which] = ioinplace;
+      n[which] = dims;
+
+      // Note reversal of dimensions for column major storage in FFTW.
+      octave_idx_type nn = 1;
+      OCTAVE_LOCAL_BUFFER (int, tmp, rank);
+
+      for (int i = 0, j = rank-1; i < rank; i++, j--)
+	{
+	  tmp[i] = dims(j);
+	  nn *= dims(j);
+	}
+
+      int plan_flags = 0;
+      bool plan_destroys_in = true;
+
+      switch (meth) 
+	{
+	case UNKNOWN:
+	case ESTIMATE:
+	  plan_flags |= FFTW_ESTIMATE;
+	  plan_destroys_in = false;
+	  break;
+	case MEASURE:
+	  plan_flags |= FFTW_MEASURE;
+	  break;
+	case PATIENT:
+	  plan_flags |= FFTW_PATIENT;
+	  break;
+	case EXHAUSTIVE:
+	  plan_flags |= FFTW_EXHAUSTIVE;
+	  break;
+	case HYBRID:
+	  if (nn < 8193)
+	    plan_flags |= FFTW_MEASURE;
+	  else
+	    {
+	      plan_flags |= FFTW_ESTIMATE;
+	      plan_destroys_in = false;
+	    }
+	  break;
+	}
+
+      if (ioalign)
+	plan_flags &= ~FFTW_UNALIGNED;
+      else
+	plan_flags |= FFTW_UNALIGNED;
+
+      if (*cur_plan_p)
+	fftwf_destroy_plan (*cur_plan_p);
+
+      if (plan_destroys_in)
+	{
+	  // Create matrix with the same size and 16-byte alignment as input
+	  OCTAVE_LOCAL_BUFFER (FloatComplex, itmp, nn * howmany + 32);
+	  itmp = reinterpret_cast<FloatComplex *>
+	    (((reinterpret_cast<ptrdiff_t>(itmp) + 15) & ~ 0xF) + 
+	     ((reinterpret_cast<ptrdiff_t> (in)) & 0xF));
+
+	  *cur_plan_p =
+	    fftwf_plan_many_dft (rank, tmp, howmany,
+	      reinterpret_cast<fftwf_complex *> (itmp),
+	      0, stride, dist, reinterpret_cast<fftwf_complex *> (out),
+	      0, stride, dist, dir, plan_flags);
+	}
+      else
+	{
+	  *cur_plan_p =
+	    fftwf_plan_many_dft (rank, tmp, howmany,
+	      reinterpret_cast<fftwf_complex *> (const_cast<FloatComplex *> (in)),
+	      0, stride, dist, reinterpret_cast<fftwf_complex *> (out),
+	      0, stride, dist, dir, plan_flags);
+	}
+
+      if (*cur_plan_p == 0)
+	(*current_liboctave_error_handler) ("Error creating fftw plan");
+    }
+
+  return *cur_plan_p;
+}
+ 
+fftwf_plan
+octave_float_fftw_planner::create_plan (const int rank, const dim_vector dims, 
+				  octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, 
+				  const float *in, FloatComplex *out)
+{
+  fftwf_plan *cur_plan_p = &rplan;
+  bool create_new_plan = false;
+  bool ioalign = CHECK_SIMD_ALIGNMENT (in) && CHECK_SIMD_ALIGNMENT (out);
+
+  // Don't create a new plan if we have a non SIMD plan already but
+  // can do SIMD.  This prevents endlessly recreating plans if we
+  // change the alignment.
+
+  if (rplan == 0 || rd != dist || rs != stride || rr != rank
+      || rh != howmany || ((ioalign != rsimd_align) ? !ioalign : false))
+    create_new_plan = true;
+  else
+    {
+      // We still might not have the same shape of array.
+
+      for (int i = 0; i < rank; i++)
+	if (dims(i) != rn(i))
+	  {
+	    create_new_plan = true;
+	    break;
+	  }
+    }
+
+  if (create_new_plan)
+    {
+      rd = dist;
+      rs = stride;
+      rr = rank;
+      rh = howmany;
+      rsimd_align = ioalign;
+      rn = dims;
+
+      // Note reversal of dimensions for column major storage in FFTW.
+      octave_idx_type nn = 1;
+      OCTAVE_LOCAL_BUFFER (int, tmp, rank);
+
+      for (int i = 0, j = rank-1; i < rank; i++, j--)
+	{
+	  tmp[i] = dims(j);
+	  nn *= dims(j);
+	}
+
+      int plan_flags = 0;
+      bool plan_destroys_in = true;
+
+      switch (meth) 
+	{
+	case UNKNOWN:
+	case ESTIMATE:
+	  plan_flags |= FFTW_ESTIMATE;
+	  plan_destroys_in = false;
+	  break;
+	case MEASURE:
+	  plan_flags |= FFTW_MEASURE;
+	  break;
+	case PATIENT:
+	  plan_flags |= FFTW_PATIENT;
+	  break;
+	case EXHAUSTIVE:
+	  plan_flags |= FFTW_EXHAUSTIVE;
+	  break;
+	case HYBRID:
+	  if (nn < 8193)
+	    plan_flags |= FFTW_MEASURE;
+	  else
+	    {
+	      plan_flags |= FFTW_ESTIMATE;
+	      plan_destroys_in = false;
+	    }
+	  break;
+	}
+
+      if (ioalign)
+	plan_flags &= ~FFTW_UNALIGNED;
+      else
+	plan_flags |= FFTW_UNALIGNED;
+
+      if (*cur_plan_p)
+	fftwf_destroy_plan (*cur_plan_p);
+
+      if (plan_destroys_in)
+	{
+	  // Create matrix with the same size and 16-byte alignment as input
+	  OCTAVE_LOCAL_BUFFER (float, itmp, nn + 32);
+	  itmp = reinterpret_cast<float *>
+	    (((reinterpret_cast<ptrdiff_t>(itmp) + 15) & ~ 0xF) + 
+	     ((reinterpret_cast<ptrdiff_t> (in)) & 0xF));
+
+	  *cur_plan_p =
+	    fftwf_plan_many_dft_r2c (rank, tmp, howmany, itmp,
+	      0, stride, dist, reinterpret_cast<fftwf_complex *> (out),
+	      0, stride, dist, plan_flags);
+	}
+      else
+	{
+	  *cur_plan_p =
+	    fftwf_plan_many_dft_r2c (rank, tmp, howmany,
+	      (const_cast<float *> (in)),
+	      0, stride, dist, reinterpret_cast<fftwf_complex *> (out),
+	      0, stride, dist, plan_flags);
+	}
+
+      if (*cur_plan_p == 0)
+	(*current_liboctave_error_handler) ("Error creating fftw plan");
+    }
+
+  return *cur_plan_p;
+}
+
+octave_fftw_planner fftw_planner;
+octave_float_fftw_planner float_fftw_planner;
+
+template <class T>
+static inline void
+convert_packcomplex_1d (T *out, size_t nr, size_t nc,
+			octave_idx_type stride, octave_idx_type dist)
+{
+  OCTAVE_QUIT;
+
+  // Fill in the missing data.
+
+  for (size_t i = 0; i < nr; i++)
+    for (size_t j = nc/2+1; j < nc; j++)
+      out[j*stride + i*dist] = conj(out[(nc - j)*stride + i*dist]);
+
+  OCTAVE_QUIT;
+}
+
+template <class T>
+static inline void
+convert_packcomplex_Nd (T *out, const dim_vector &dv)
+{
+  size_t nc = dv(0);
+  size_t nr = dv(1);
+  size_t np = (dv.length () > 2 ? dv.numel () / nc / nr : 1);
+  size_t nrp = nr * np;
+  T *ptr1, *ptr2;
+
+  OCTAVE_QUIT;
+
+  // Create space for the missing elements.
+
+  for (size_t i = 0; i < nrp; i++)
+    {
+      ptr1 = out + i * (nc/2 + 1) + nrp*((nc-1)/2);
+      ptr2 = out + i * nc;
+      for (size_t j = 0; j < nc/2+1; j++)
+	*ptr2++ = *ptr1++;
+    }
+
+  OCTAVE_QUIT;
+
+  // Fill in the missing data for the rank = 2 case directly for speed.
+
+  for (size_t i = 0; i < np; i++)
+    {
+      for (size_t j = 1; j < nr; j++)
+	for (size_t k = nc/2+1; k < nc; k++)
+	  out[k + (j + i*nr)*nc] = conj(out[nc - k + ((i+1)*nr - j)*nc]);
+
+      for (size_t j = nc/2+1; j < nc; j++)
+	out[j + i*nr*nc] = conj(out[(i*nr+1)*nc - j]);
+    }
+
+  OCTAVE_QUIT;
+
+  // Now do the permutations needed for rank > 2 cases.
+
+  size_t jstart = dv(0) * dv(1);
+  size_t kstep = dv(0);
+  size_t nel = dv.numel ();
+
+  for (int inner = 2; inner < dv.length (); inner++) 
+    {
+      size_t jmax = jstart * dv(inner);
+      for (size_t i = 0; i < nel; i+=jmax)
+	for (size_t j = jstart, jj = jmax-jstart; j < jj; 
+	     j+=jstart, jj-=jstart)
+	  for (size_t k = 0; k < jstart; k+= kstep)
+	    for (size_t l = nc/2+1; l < nc; l++)
+	      {
+		T tmp = out[i+ j + k + l];
+		out[i + j + k + l] =  out[i + jj + k + l];
+		out[i + jj + k + l] = tmp;
+	      }
+      jstart = jmax;
+    }
+
+  OCTAVE_QUIT;
+}
+
+int
+octave_fftw::fft (const double *in, Complex *out, size_t npts, 
+		  size_t nsamples, octave_idx_type stride, octave_idx_type dist)
+{
+  dist = (dist < 0 ? npts : dist);
+
+  dim_vector dv (npts);
+  fftw_plan plan = fftw_planner.create_plan (1, dv, nsamples, stride, dist,
+					      in, out);
+
+  fftw_execute_dft_r2c (plan, (const_cast<double *>(in)),
+			 reinterpret_cast<fftw_complex *> (out));
+
+  // Need to create other half of the transform.
+
+  convert_packcomplex_1d (out, nsamples, npts, stride, dist);
+
+  return 0;
+}
+
+int
+octave_fftw::fft (const Complex *in, Complex *out, size_t npts, 
+		  size_t nsamples, octave_idx_type stride, octave_idx_type dist)
+{
+  dist = (dist < 0 ? npts : dist);
+
+  dim_vector dv (npts);
+  fftw_plan plan = fftw_planner.create_plan (FFTW_FORWARD, 1, dv, nsamples,
+					     stride, dist, in, out);
+
+  fftw_execute_dft (plan, 
+	reinterpret_cast<fftw_complex *> (const_cast<Complex *>(in)),
+	reinterpret_cast<fftw_complex *> (out));
+
+  return 0;
+}
+
+int
+octave_fftw::ifft (const Complex *in, Complex *out, size_t npts, 
+		   size_t nsamples, octave_idx_type stride, octave_idx_type dist)
+{
+  dist = (dist < 0 ? npts : dist);
+
+  dim_vector dv (npts);
+  fftw_plan plan = fftw_planner.create_plan (FFTW_BACKWARD, 1, dv, nsamples,
+					     stride, dist, in, out);
+
+  fftw_execute_dft (plan, 
+	reinterpret_cast<fftw_complex *> (const_cast<Complex *>(in)),
+	reinterpret_cast<fftw_complex *> (out));
+
+  const Complex scale = npts;
+  for (size_t j = 0; j < nsamples; j++)
+    for (size_t i = 0; i < npts; i++)
+      out[i*stride + j*dist] /= scale;
+
+  return 0;
+}
+
+int
+octave_fftw::fftNd (const double *in, Complex *out, const int rank, 
+		    const dim_vector &dv)
+{
+  octave_idx_type dist = 1;
+  for (int i = 0; i < rank; i++)
+    dist *= dv(i);
+
+  // Fool with the position of the start of the output matrix, so that
+  // creating other half of the matrix won't cause cache problems.
+
+  octave_idx_type offset = (dv.numel () / dv(0)) * ((dv(0) - 1) / 2); 
+  
+  fftw_plan plan = fftw_planner.create_plan (rank, dv, 1, 1, dist,
+					     in, out + offset);
+
+  fftw_execute_dft_r2c (plan, (const_cast<double *>(in)),
+			reinterpret_cast<fftw_complex *> (out+ offset));
+
+  // Need to create other half of the transform.
+
+  convert_packcomplex_Nd (out, dv);
+
+  return 0;
+}
+
+int
+octave_fftw::fftNd (const Complex *in, Complex *out, const int rank, 
+		    const dim_vector &dv)
+{
+  octave_idx_type dist = 1;
+  for (int i = 0; i < rank; i++)
+    dist *= dv(i);
+
+  fftw_plan plan = fftw_planner.create_plan (FFTW_FORWARD, rank, dv, 1, 1,
+					     dist, in, out);
+
+  fftw_execute_dft (plan, 
+	reinterpret_cast<fftw_complex *> (const_cast<Complex *>(in)),
+	reinterpret_cast<fftw_complex *> (out));
+
+  return 0;
+}
+
+int
+octave_fftw::ifftNd (const Complex *in, Complex *out, const int rank, 
+		     const dim_vector &dv)
+{
+  octave_idx_type dist = 1;
+  for (int i = 0; i < rank; i++)
+    dist *= dv(i);
+
+  fftw_plan plan = fftw_planner.create_plan (FFTW_BACKWARD, rank, dv, 1, 1,
+					     dist, in, out);
+
+  fftw_execute_dft (plan, 
+	reinterpret_cast<fftw_complex *> (const_cast<Complex *>(in)),
+	reinterpret_cast<fftw_complex *> (out));
+
+  const size_t npts = dv.numel ();
+  const Complex scale = npts;
+  for (size_t i = 0; i < npts; i++)
+    out[i] /= scale;
+
+  return 0;
+}
+
+int
+octave_fftw::fft (const float *in, FloatComplex *out, size_t npts, 
+		  size_t nsamples, octave_idx_type stride, octave_idx_type dist)
+{
+  dist = (dist < 0 ? npts : dist);
+
+  dim_vector dv (npts);
+  fftwf_plan plan = float_fftw_planner.create_plan (1, dv, nsamples, stride, dist,
+					     in, out);
+
+  fftwf_execute_dft_r2c (plan, (const_cast<float *>(in)),
+			reinterpret_cast<fftwf_complex *> (out));
+
+  // Need to create other half of the transform.
+
+  convert_packcomplex_1d (out, nsamples, npts, stride, dist);
+
+  return 0;
+}
+
+int
+octave_fftw::fft (const FloatComplex *in, FloatComplex *out, size_t npts, 
+		  size_t nsamples, octave_idx_type stride, octave_idx_type dist)
+{
+  dist = (dist < 0 ? npts : dist);
+
+  dim_vector dv (npts);
+  fftwf_plan plan = float_fftw_planner.create_plan (FFTW_FORWARD, 1, dv, nsamples,
+					     stride, dist, in, out);
+
+  fftwf_execute_dft (plan, 
+	reinterpret_cast<fftwf_complex *> (const_cast<FloatComplex *>(in)),
+	reinterpret_cast<fftwf_complex *> (out));
+
+  return 0;
+}
+
+int
+octave_fftw::ifft (const FloatComplex *in, FloatComplex *out, size_t npts, 
+		   size_t nsamples, octave_idx_type stride, octave_idx_type dist)
+{
+  dist = (dist < 0 ? npts : dist);
+
+  dim_vector dv (npts);
+  fftwf_plan plan = float_fftw_planner.create_plan (FFTW_BACKWARD, 1, dv, nsamples,
+					     stride, dist, in, out);
+
+  fftwf_execute_dft (plan, 
+	reinterpret_cast<fftwf_complex *> (const_cast<FloatComplex *>(in)),
+	reinterpret_cast<fftwf_complex *> (out));
+
+  const FloatComplex scale = npts;
+  for (size_t j = 0; j < nsamples; j++)
+    for (size_t i = 0; i < npts; i++)
+      out[i*stride + j*dist] /= scale;
+
+  return 0;
+}
+
+int
+octave_fftw::fftNd (const float *in, FloatComplex *out, const int rank, 
+		    const dim_vector &dv)
+{
+  octave_idx_type dist = 1;
+  for (int i = 0; i < rank; i++)
+    dist *= dv(i);
+
+  // Fool with the position of the start of the output matrix, so that
+  // creating other half of the matrix won't cause cache problems.
+
+  octave_idx_type offset = (dv.numel () / dv(0)) * ((dv(0) - 1) / 2); 
+  
+  fftwf_plan plan = float_fftw_planner.create_plan (rank, dv, 1, 1, dist,
+					     in, out + offset);
+
+  fftwf_execute_dft_r2c (plan, (const_cast<float *>(in)),
+			reinterpret_cast<fftwf_complex *> (out+ offset));
+
+  // Need to create other half of the transform.
+
+  convert_packcomplex_Nd (out, dv);
+
+  return 0;
+}
+
+int
+octave_fftw::fftNd (const FloatComplex *in, FloatComplex *out, const int rank, 
+		    const dim_vector &dv)
+{
+  octave_idx_type dist = 1;
+  for (int i = 0; i < rank; i++)
+    dist *= dv(i);
+
+  fftwf_plan plan = float_fftw_planner.create_plan (FFTW_FORWARD, rank, dv, 1, 1,
+					     dist, in, out);
+
+  fftwf_execute_dft (plan, 
+	reinterpret_cast<fftwf_complex *> (const_cast<FloatComplex *>(in)),
+	reinterpret_cast<fftwf_complex *> (out));
+
+  return 0;
+}
+
+int
+octave_fftw::ifftNd (const FloatComplex *in, FloatComplex *out, const int rank, 
+		     const dim_vector &dv)
+{
+  octave_idx_type dist = 1;
+  for (int i = 0; i < rank; i++)
+    dist *= dv(i);
+
+  fftwf_plan plan = float_fftw_planner.create_plan (FFTW_BACKWARD, rank, dv, 1, 1,
+					     dist, in, out);
+
+  fftwf_execute_dft (plan, 
+	reinterpret_cast<fftwf_complex *> (const_cast<FloatComplex *>(in)),
+	reinterpret_cast<fftwf_complex *> (out));
+
+  const size_t npts = dv.numel ();
+  const FloatComplex scale = npts;
+  for (size_t i = 0; i < npts; i++)
+    out[i] /= scale;
+
+  return 0;
+}
+
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/oct-fftw.h b/liboctave/oct-fftw.h
new file mode 100644
index 0000000..497ef94
--- /dev/null
+++ b/liboctave/oct-fftw.h
@@ -0,0 +1,234 @@
+/*
+
+Copyright (C) 2001, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_fftw_h)
+#define octave_oct_fftw_h 1
+
+#include <cstddef>
+#include <fftw3.h>
+
+#include "oct-cmplx.h"
+#include "dim-vector.h"
+
+class
+OCTAVE_API
+octave_fftw_planner
+{
+public:
+
+  octave_fftw_planner (void);
+
+  fftw_plan create_plan (int dir, const int rank, const dim_vector dims, 
+			 octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, 
+			 const Complex *in, Complex *out);
+
+  fftw_plan create_plan (const int rank, const dim_vector dims, 
+			 octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, 
+			 const double *in, Complex *out);
+
+  enum FftwMethod {
+    UNKNOWN = -1,
+    ESTIMATE,
+    MEASURE,
+    PATIENT,
+    EXHAUSTIVE,
+    HYBRID
+  };
+
+  FftwMethod method (void);
+
+  FftwMethod method (FftwMethod _meth);
+
+private:
+
+  FftwMethod meth;
+
+  // FIXME -- perhaps this should be split into two classes?
+
+  // Plan for fft and ifft of complex values
+  fftw_plan plan[2];
+
+  // dist
+  octave_idx_type d[2];
+
+  // stride
+  octave_idx_type s[2];
+
+  // rank
+  int r[2];
+
+  // howmany
+  octave_idx_type h[2];
+
+  // dims
+  dim_vector n[2];
+
+  bool simd_align[2];
+  bool inplace[2];
+
+  // Plan for fft of real values
+  fftw_plan rplan;
+
+  // dist
+  octave_idx_type rd;
+
+  // stride
+  octave_idx_type rs;
+
+  // rank
+  int rr;
+
+  // howmany
+  octave_idx_type rh;
+
+  // dims
+  dim_vector rn;
+
+  bool rsimd_align;
+};
+
+class
+OCTAVE_API
+octave_float_fftw_planner
+{
+public:
+
+  octave_float_fftw_planner (void);
+
+  fftwf_plan create_plan (int dir, const int rank, const dim_vector dims, 
+			 octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, 
+			 const FloatComplex *in, FloatComplex *out);
+
+  fftwf_plan create_plan (const int rank, const dim_vector dims, 
+			 octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, 
+			 const float *in, FloatComplex *out);
+
+  enum FftwMethod {
+    UNKNOWN = -1,
+    ESTIMATE,
+    MEASURE,
+    PATIENT,
+    EXHAUSTIVE,
+    HYBRID
+  };
+
+  FftwMethod method (void);
+
+  FftwMethod method (FftwMethod _meth);
+
+private:
+
+  FftwMethod meth;
+
+  // FIXME -- perhaps this should be split into two classes?
+
+  // Plan for fft and ifft of complex values
+  fftwf_plan plan[2];
+
+  // dist
+  octave_idx_type d[2];
+
+  // stride
+  octave_idx_type s[2];
+
+  // rank
+  int r[2];
+
+  // howmany
+  octave_idx_type h[2];
+
+  // dims
+  dim_vector n[2];
+
+  bool simd_align[2];
+  bool inplace[2];
+
+  // Plan for fft of real values
+  fftwf_plan rplan;
+
+  // dist
+  octave_idx_type rd;
+
+  // stride
+  octave_idx_type rs;
+
+  // rank
+  int rr;
+
+  // howmany
+  octave_idx_type rh;
+
+  // dims
+  dim_vector rn;
+
+  bool rsimd_align;
+};
+
+// FIXME -- maybe octave_fftw_planner should be a singleton object?
+extern OCTAVE_API octave_fftw_planner fftw_planner;
+extern OCTAVE_API octave_float_fftw_planner float_fftw_planner;
+
+class
+OCTAVE_API
+octave_fftw
+{
+public:
+  static int fft (const double *in, Complex *out, size_t npts, 
+		  size_t nsamples = 1, octave_idx_type stride = 1, octave_idx_type dist = -1);
+  static int fft (const Complex *in, Complex *out, size_t npts, 
+		  size_t nsamples = 1, octave_idx_type stride = 1, octave_idx_type dist = -1);
+  static int ifft (const Complex *in, Complex *out, size_t npts,
+		   size_t nsamples = 1, octave_idx_type stride = 1, octave_idx_type dist = -1);
+
+  static int fftNd (const double*, Complex*, const int, const dim_vector &);
+  static int fftNd (const Complex*, Complex*, const int, 
+		    const dim_vector &);
+  static int ifftNd (const Complex*, Complex*, const int, 
+		     const dim_vector &);
+
+  static int fft (const float *in, FloatComplex *out, size_t npts, 
+		  size_t nsamples = 1, octave_idx_type stride = 1, octave_idx_type dist = -1);
+  static int fft (const FloatComplex *in, FloatComplex *out, size_t npts, 
+		  size_t nsamples = 1, octave_idx_type stride = 1, octave_idx_type dist = -1);
+  static int ifft (const FloatComplex *in, FloatComplex *out, size_t npts,
+		   size_t nsamples = 1, octave_idx_type stride = 1, octave_idx_type dist = -1);
+
+  static int fftNd (const float*, FloatComplex*, const int, const dim_vector &);
+  static int fftNd (const FloatComplex*, FloatComplex*, const int, 
+		    const dim_vector &);
+  static int ifftNd (const FloatComplex*, FloatComplex*, const int, 
+		     const dim_vector &);
+
+private:
+  octave_fftw ();
+  octave_fftw (const octave_fftw&);
+  octave_fftw& operator = (const octave_fftw&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/oct-getopt.c b/liboctave/oct-getopt.c
new file mode 100644
index 0000000..2cf2b42
--- /dev/null
+++ b/liboctave/oct-getopt.c
@@ -0,0 +1,47 @@
+/*
+
+Copyright (C) 2000, 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+int
+octave_getopt (int argc, char *const *argv, const char *optstring)
+{
+  return getopt (argc, argv, optstring);
+}
+
+int
+octave_getopt_long (int argc, char *const *argv, const char *options,
+		    const struct option *long_options, int *opt_index)
+{
+  return getopt_long (argc, argv, options, long_options, opt_index);
+}
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-getopt.h b/liboctave/oct-getopt.h
new file mode 100644
index 0000000..c944f5c
--- /dev/null
+++ b/liboctave/oct-getopt.h
@@ -0,0 +1,52 @@
+/*
+
+Copyright (C) 2000, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_getopt_h)
+#define octave_getopt_h 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern int
+octave_getopt (int, char *const *, const char *);
+
+extern int
+octave_getopt_long (int, char *const *, const char *,
+		    const struct option *, int *);
+
+extern char *optarg;
+
+extern int optind;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-group.cc b/liboctave/oct-group.cc
new file mode 100644
index 0000000..5ef9d1a
--- /dev/null
+++ b/liboctave/oct-group.cc
@@ -0,0 +1,231 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#include "lo-error.h"
+#include "oct-group.h"
+#include "str-vec.h"
+
+#define NOT_SUPPORTED(nm) \
+  nm ": not supported on this system"
+
+std::string
+octave_group::name (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return gr_name;
+}
+
+std::string
+octave_group::passwd (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return gr_passwd;
+}
+
+gid_t
+octave_group::gid (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return gr_gid;
+}
+
+string_vector
+octave_group::mem (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return gr_mem;
+}
+
+octave_group
+octave_group::getgrent (void)
+{
+  std::string msg;
+  return getgrent (msg);
+}
+
+octave_group
+octave_group::getgrent (std::string& msg)
+{
+#if defined (HAVE_GETGRENT)
+  msg = std::string ();
+  return octave_group (::getgrent (), msg);
+#else
+  msg = NOT_SUPPORTED ("getgrent");
+  return octave_group ();
+#endif
+}
+
+octave_group
+octave_group::getgrgid (gid_t gid)
+{
+  std::string msg;
+  return getgrgid (gid, msg);
+}
+
+octave_group
+octave_group::getgrgid (gid_t gid, std::string& msg)
+{
+#if defined (HAVE_GETGRGID)
+  msg = std::string ();
+  return octave_group (::getgrgid (gid), msg);
+#else
+  msg = NOT_SUPPORTED ("getgruid");
+  return octave_group ();
+#endif
+}
+
+octave_group
+octave_group::getgrnam (const std::string& nm)
+{
+  std::string msg;
+  return getgrnam (nm, msg);
+}
+
+octave_group
+octave_group::getgrnam (const std::string& nm, std::string& msg)
+{
+#if defined (HAVE_GETGRNAM)
+  msg = std::string ();
+  return octave_group (::getgrnam (nm.c_str ()), msg);
+#else
+  msg = NOT_SUPPORTED ("getgrnam");
+  return octave_group ();
+#endif
+}
+
+int
+octave_group::setgrent (void)
+{
+  std::string msg;
+  return setgrent (msg);
+}
+
+int
+octave_group::setgrent (std::string& msg)
+{
+#if defined (HAVE_SETGRENT)
+  msg = std::string ();
+  ::setgrent ();
+  return 0;
+#else
+  msg = NOT_SUPPORTED ("setgrent");
+  return -1;
+#endif
+}
+
+int
+octave_group::endgrent (void)
+{
+  std::string msg;
+  return endgrent (msg);
+}
+
+int
+octave_group::endgrent (std::string& msg)
+{
+#if defined (HAVE_ENDGRENT)
+  msg = std::string ();
+  ::endgrent ();
+  return 0;
+#else
+  msg = NOT_SUPPORTED ("endgrent");
+  return -1;
+#endif
+}
+
+octave_group::octave_group (void *p, std::string& msg)
+  : gr_name (), gr_passwd (), gr_gid (0), gr_mem (), valid (false)
+{
+#if defined (HAVE_GRP_H)
+  msg = std::string ();
+
+  if (p)
+    {
+      struct group *gr = static_cast<struct group *> (p);
+
+      gr_name = gr->gr_name;
+
+#if defined (HAVE_GR_PASSWD)
+      gr_passwd = gr->gr_passwd;
+#endif
+
+      gr_gid = gr->gr_gid;
+
+      // FIXME -- maybe there should be a string_vector
+      // constructor that takes a NUL terminated list of C
+      // strings.
+
+      const char * const *tmp = gr->gr_mem;
+
+      int k = 0;
+      while (*tmp++)
+	k++;
+
+      if (k > 0)
+	{
+	  tmp = gr->gr_mem;
+
+	  gr_mem.resize (k);
+
+	  for (int i = 0; i < k; i++)
+	    gr_mem[i] = tmp[i];
+	}
+
+      valid = true;
+    }
+#else
+  msg = NOT_SUPPORTED ("group functions");
+#endif
+}
+
+void
+octave_group::gripe_invalid (void) const
+{
+  (*current_liboctave_error_handler) ("invalid group object");
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-group.h b/liboctave/oct-group.h
new file mode 100644
index 0000000..0b7977f
--- /dev/null
+++ b/liboctave/oct-group.h
@@ -0,0 +1,120 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_group_h)
+#define octave_group_h 1
+
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "str-vec.h"
+
+class
+OCTAVE_API
+octave_group
+{
+public:
+
+  octave_group (void)
+    : gr_name (), gr_passwd (), gr_gid (0), gr_mem (), valid (false)
+  { }
+
+  octave_group (const octave_group& gr)
+    : gr_name (gr.gr_name), gr_passwd (gr.gr_passwd),
+      gr_gid (gr.gr_gid), gr_mem (gr.gr_mem), valid (gr.valid) 
+  { }
+
+  octave_group& operator = (const octave_group& gr)
+  {
+    if (this != &gr)
+      {
+	gr_name  = gr.gr_name;
+	gr_passwd = gr.gr_passwd;
+	gr_gid = gr.gr_gid;
+	gr_mem = gr.gr_mem;
+	valid = gr.valid;
+      }
+
+    return *this;
+  }
+
+  std::string name (void) const;
+
+  std::string passwd (void) const;
+
+  gid_t gid (void) const;
+
+  string_vector mem (void) const;
+
+  bool ok (void) const { return valid; }
+
+  operator bool () const { return ok (); }
+
+  static octave_group getgrent (void);
+  static octave_group getgrent (std::string& msg);
+
+  static octave_group getgrgid (gid_t gid);
+  static octave_group getgrgid (gid_t gid, std::string& msg);
+
+  static octave_group getgrnam (const std::string& nm);
+  static octave_group getgrnam (const std::string& nm, std::string& msg);
+
+  static int setgrent (void);
+  static int setgrent (std::string& msg);
+
+  static int endgrent (void);
+  static int endgrent (std::string& msg);
+
+private:
+
+  // The group name.
+  std::string gr_name;
+
+  // The group password.
+  std::string gr_passwd;
+
+  // The numeric group id.
+  gid_t gr_gid;
+
+  // The members of the group;
+  string_vector gr_mem;
+
+  // Flag that says whether we have been properly initialized.
+  bool valid;
+
+  // This is how we will create an octave_group object from a pointer
+  // to a struct group.
+  octave_group (void *p, std::string& msg);
+
+  void gripe_invalid (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-inttypes.cc b/liboctave/oct-inttypes.cc
new file mode 100644
index 0000000..aa0958a
--- /dev/null
+++ b/liboctave/oct-inttypes.cc
@@ -0,0 +1,659 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek 
+Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-error.h"
+
+#include "oct-inttypes.h"
+
+template<class T>
+const octave_int<T> octave_int<T>::zero (static_cast<T> (0));
+
+template<class T>
+const octave_int<T> octave_int<T>::one (static_cast<T> (1));
+
+// define type names. 
+#define DECLARE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME) \
+  template <> \
+  OCTAVE_API const char * \
+  octave_int<TYPE>::type_name () { return TYPENAME; }
+
+DECLARE_OCTAVE_INT_TYPENAME (int8_t, "int8")
+DECLARE_OCTAVE_INT_TYPENAME (int16_t, "int16")
+DECLARE_OCTAVE_INT_TYPENAME (int32_t, "int32")
+DECLARE_OCTAVE_INT_TYPENAME (int64_t, "int64")
+DECLARE_OCTAVE_INT_TYPENAME (uint8_t, "uint8")
+DECLARE_OCTAVE_INT_TYPENAME (uint16_t, "uint16")
+DECLARE_OCTAVE_INT_TYPENAME (uint32_t, "uint32")
+DECLARE_OCTAVE_INT_TYPENAME (uint64_t, "uint64")
+
+#ifndef OCTAVE_INT_USE_LONG_DOUBLE
+
+// Define comparison operators
+
+template <class xop> 
+bool 
+octave_int_cmp_op::emulate_mop (uint64_t x, double y)
+{
+  static const double xxup = std::numeric_limits<uint64_t>::max ();
+  // This converts to the nearest double. Unless there's an equality, the
+  // result is clear.
+  double xx = x;
+  if (xx != y)
+    return xop::op (xx, y);
+  else
+    {
+      // If equality occured we compare as integers.
+      if (xx == xxup)
+        return xop::gtval;
+      else
+        return xop::op (x, static_cast<uint64_t> (xx));
+    }
+}
+
+template <class xop> 
+bool 
+octave_int_cmp_op::emulate_mop (int64_t x, double y)
+{
+  static const double xxup = std::numeric_limits<int64_t>::max ();
+  static const double xxlo = std::numeric_limits<int64_t>::min ();
+  // This converts to the nearest double. Unless there's an equality, the
+  // result is clear.
+  double xx = x;
+  if (xx != y)
+    return xop::op (xx, y);
+  else
+    {
+      // If equality occured we compare as integers.
+      if (xx == xxup)
+        return xop::gtval;
+      else if (xx == xxlo)
+        return xop::ltval;
+      else
+        return xop::op (x, static_cast<int64_t> (xx));
+    }
+
+}
+
+// We define double-int operations by reverting the operator
+
+// A trait class reverting the operator
+template <class xop>
+class rev_op
+{
+public:
+  typedef xop op;
+};
+
+#define DEFINE_REVERTED_OPERATOR(OP1,OP2) \
+  template <> \
+  class rev_op<octave_int_cmp_op::OP1> \
+  { \
+  public: \
+    typedef octave_int_cmp_op::OP2 op; \
+  }
+
+DEFINE_REVERTED_OPERATOR(lt,gt);
+DEFINE_REVERTED_OPERATOR(gt,lt);
+DEFINE_REVERTED_OPERATOR(le,ge);
+DEFINE_REVERTED_OPERATOR(ge,le);
+
+template <class xop> 
+bool 
+octave_int_cmp_op::emulate_mop (double x, uint64_t y)
+{
+  typedef typename rev_op<xop>::op rop;
+  return mop<rop> (y, x);
+}
+
+template <class xop> 
+bool 
+octave_int_cmp_op::emulate_mop (double x, int64_t y)
+{
+  typedef typename rev_op<xop>::op rop;
+  return mop<rop> (y, x);
+}
+
+
+// Define handlers for int64 multiplication
+
+template <>
+uint64_t 
+octave_int_arith_base<uint64_t, false>::mul (uint64_t x, uint64_t y)
+{ 
+  // Get upper words
+  uint64_t ux = x >> 32, uy = y >> 32;
+  uint64_t res;
+  if (ux)
+    {
+      if (uy) 
+        goto overflow;
+      else
+        {
+          uint64_t ly = static_cast<uint32_t> (y), uxly = ux*ly;
+          if (uxly >> 32) 
+            goto overflow;
+          uxly <<= 32; // never overflows
+          uint64_t lx = static_cast<uint32_t> (x), lxly = lx*ly;
+          res = add (uxly, lxly);
+        }
+    }
+  else if (uy)
+    {
+      uint64_t lx = static_cast<uint32_t> (x), uylx = uy*lx;
+      if (uylx >> 32) 
+        goto overflow;
+      uylx <<= 32; // never overflows
+      uint64_t ly = static_cast<uint32_t> (y), lylx = ly*lx;
+      res = add (uylx, lylx);
+    }
+  else
+    {
+      uint64_t lx = static_cast<uint32_t> (x);
+      uint64_t ly = static_cast<uint32_t> (y);
+      res = lx*ly;
+    }
+
+  return res;
+
+overflow:
+  ftrunc = true;
+  return max_val ();
+}
+
+template <>
+int64_t 
+octave_int_arith_base<int64_t, true>::mul (int64_t x, int64_t y)
+{ 
+  // The signed case is far worse. The problem is that
+  // even if neither integer fits into signed 32-bit range, the result may
+  // still be OK. Uh oh.
+  
+  // Essentially, what we do is compute sign, multiply absolute values
+  // (as above) and impose the sign.
+  // FIXME -- can we do something faster if we HAVE_FAST_INT_OPS?
+
+  uint64_t usx = octave_int_abs (x), usy = octave_int_abs (y);
+  bool positive = (x < 0) == (y < 0);
+
+  // Get upper words
+  uint64_t ux = usx >> 32, uy = usy >> 32;
+  uint64_t res;
+  if (ux)
+    {
+      if (uy) 
+        goto overflow;
+      else
+        {
+          uint64_t ly = static_cast<uint32_t> (usy), uxly = ux*ly;
+          if (uxly >> 32) 
+            goto overflow;
+          uxly <<= 32; // never overflows
+          uint64_t lx = static_cast<uint32_t> (usx), lxly = lx*ly;
+          res = uxly + lxly;
+          if (res < uxly)
+            goto overflow;
+        }
+    }
+  else if (uy)
+    {
+      uint64_t lx = static_cast<uint32_t> (usx), uylx = uy*lx;
+      if (uylx >> 32) 
+        goto overflow;
+      uylx <<= 32; // never overflows
+      uint64_t ly = static_cast<uint32_t> (usy), lylx = ly*lx;
+      res = uylx + lylx;
+      if (res < uylx)
+        goto overflow;
+    }
+  else
+    {
+      uint64_t lx = static_cast<uint32_t> (usx);
+      uint64_t ly = static_cast<uint32_t> (usy);
+      res = lx*ly;
+    }
+
+  if (positive)
+    {
+      if (res > static_cast<uint64_t> (max_val ()))
+        {
+          ftrunc = true;
+          return max_val ();
+        }
+      else
+        return static_cast<int64_t> (res);
+    }
+  else
+    {
+      if (res > static_cast<uint64_t> (-min_val ()))
+        {
+          ftrunc = true;
+          return min_val ();
+        }
+      else
+        return -static_cast<int64_t> (res);
+    }
+
+
+overflow:
+  ftrunc = true;
+  return positive ? max_val () : min_val ();
+
+}
+
+#define INT_DOUBLE_BINOP_DECL(OP,SUFFIX) \
+  template <> \
+  OCTAVE_API octave_ ## SUFFIX \
+  operator OP (const octave_ ## SUFFIX & x, const double& y)
+
+#define DOUBLE_INT_BINOP_DECL(OP,SUFFIX) \
+  template <> \
+  OCTAVE_API octave_ ## SUFFIX \
+  operator OP (const double& x, const octave_ ## SUFFIX & y)
+
+INT_DOUBLE_BINOP_DECL (+, uint64)
+{
+  return (y < 0) ? x - octave_uint64(-y) : x + octave_uint64(y);
+}
+
+DOUBLE_INT_BINOP_DECL (+, uint64)
+{ return y + x; }
+
+INT_DOUBLE_BINOP_DECL (+, int64)
+{
+  if (fabs (y) < static_cast<double> (octave_int64::max ()))
+    return x + octave_int64 (y);
+  else
+    {
+      // If the number is within the int64 range (the most common case,
+      // probably), the above will work as expected. If not, it's more
+      // complicated - as long as y is within _twice_ the signed range, the
+      // result may still be an integer. An instance of such an operation is
+      // 3*2**62 + (1+intmin('int64')) that should yield int64(2**62) + 1.  So
+      // what we do is to try to convert y/2 and add it twice. Note that if y/2
+      // overflows, the result must overflow as well, and that y/2 cannot be a
+      // fractional number.
+      octave_int64 y2 (y / 2); 
+      return (x + y2) + y2;
+    }
+}
+
+DOUBLE_INT_BINOP_DECL (+, int64)
+{ 
+  return y + x; 
+}
+
+INT_DOUBLE_BINOP_DECL (-, uint64)
+{
+  return x + (-y);
+}
+
+DOUBLE_INT_BINOP_DECL (-, uint64)
+{
+  if (x <= static_cast<double> (octave_uint64::max ()))
+    return octave_uint64(x) - y; 
+  else
+    {
+      // Again a trick to get the corner cases right. Things like 
+      // 3**2**63 - intmax('uint64') should produce the correct result, i.e.
+      // int64(2**63) + 1.
+      const double p2_64 = std::pow (2.0, 64);
+      if (y.bool_value ())
+        {
+          const uint64_t p2_64my = (~y.value ()) + 1; // Equals 2**64 - y
+          return octave_uint64 (x - p2_64) + octave_uint64 (p2_64my);
+        }
+      else
+        return octave_uint64 (p2_64);
+    }
+}
+
+INT_DOUBLE_BINOP_DECL (-, int64)
+{
+  return x + (-y);
+}
+
+DOUBLE_INT_BINOP_DECL (-, int64)
+{
+  static const bool twosc = (std::numeric_limits<int64_t>::min () 
+                             < -std::numeric_limits<int64_t>::max ());
+  // In case of symmetric integers (not two's complement), this will probably
+  // be eliminated at compile time.
+  if (twosc && y.value () == std::numeric_limits<int64_t>::min ())
+    {
+      return octave_int64 (x + std::pow(2.0, 63));
+    }
+  else
+    return x + (-y); 
+}
+
+// NOTE:
+// Emulated mixed multiplications are tricky due to possible precision loss.
+// Here, after sorting out common cases for speed, we follow the strategy
+// of converting the double number into the form sign * 64-bit integer* 2**exponent,
+// multiply the 64-bit integers to get a 128-bit number, split that number into 32-bit words
+// and form 4 double-valued summands (none of which loases precision), then convert these
+// into integers and sum them. Though it is not immediately obvious, this should work
+// even w.r.t. rounding (none of the summands lose precision).
+
+// Multiplies two unsigned 64-bit ints to get a 128-bit number represented
+// as four 32-bit words.
+static void 
+umul128 (uint64_t x, uint64_t y, uint32_t w[4])
+{
+  uint64_t lx = static_cast<uint32_t> (x), ux = x >> 32;
+  uint64_t ly = static_cast<uint32_t> (y), uy = y >> 32;
+  uint64_t a = lx * ly;
+  w[0] = a; a >>= 32;
+  uint64_t uxly = ux*ly, uylx = uy*lx;
+  a += static_cast<uint32_t> (uxly); uxly >>= 32;
+  a += static_cast<uint32_t> (uylx); uylx >>= 32;
+  w[1] = a; a >>= 32;
+  uint64_t uxuy = ux * uy;
+  a += uxly; a += uylx; a += uxuy;
+  w[2] = a; a >>= 32;
+  w[3] = a;
+}
+
+// Splits a double into bool sign, unsigned 64-bit mantissa and int exponent
+static void 
+dblesplit (double x, bool& sign, uint64_t& mtis, int& exp)
+{
+  sign = x < 0; x = fabs (x);
+  x = frexp (x, &exp);
+  exp -= 52;
+  mtis = static_cast<uint64_t> (ldexp (x, 52));
+}
+
+// Gets a double number from a 32-bit unsigned integer mantissa, exponent and sign.
+static double
+dbleget (bool sign, uint32_t mtis, int exp)
+{
+  double x = ldexp (static_cast<double> (mtis), exp);
+  return sign ? -x : x;
+}
+
+
+INT_DOUBLE_BINOP_DECL (*, uint64)
+{
+  if (y >= 0 && y < octave_uint64::max () && y == xround (y))
+    {
+      return x * octave_uint64 (static_cast<uint64_t> (y));
+    }
+  else if (y == 0.5)
+    {
+      return x / octave_uint64 (static_cast<uint64_t> (2));
+    }
+  else if (y < 0 || xisnan (y) || xisinf (y))
+    {
+      return octave_uint64 (x.value () * y); 
+    }
+  else
+    {
+      bool sign;
+      uint64_t my;
+      int e;
+      dblesplit (y, sign, my, e);
+      uint32_t w[4];
+      umul128 (x.value (), my, w);
+      octave_uint64 res = octave_uint64::zero;
+      for (short i = 0; i < 4; i++)
+        {
+          res += octave_uint64 (dbleget (sign, w[i], e));
+          e += 32;
+        }          
+      return res;
+    }
+}
+
+DOUBLE_INT_BINOP_DECL (*, uint64)
+{ return y * x; }
+
+INT_DOUBLE_BINOP_DECL (*, int64)
+{
+  if (fabs (y) < octave_int64::max () && y == xround (y))
+    {
+      return x * octave_int64 (static_cast<int64_t> (y));
+    }
+  else if (fabs (y) == 0.5)
+    {
+      return x / octave_int64 (static_cast<uint64_t> (4*y));
+    }
+  else if (xisnan (y) || xisinf (y))
+    {
+      return octave_int64 (x.value () * y); 
+    }
+  else
+    {
+      bool sign;
+      uint64_t my;
+      int e;
+      dblesplit (y, sign, my, e);
+      uint32_t w[4];
+      sign = (sign != (x.value () < 0));
+      umul128 (octave_int_abs (x.value ()), my, w);
+      octave_int64 res = octave_int64::zero;
+      for (short i = 0; i < 4; i++)
+        {
+          res += octave_int64 (dbleget (sign, w[i], e));
+          e += 32;
+        }          
+      return res;
+    }
+}
+
+DOUBLE_INT_BINOP_DECL (*, int64)
+{ return y * x; }
+
+DOUBLE_INT_BINOP_DECL (/, uint64)
+{
+  return octave_uint64 (x / static_cast<double> (y));
+}
+
+DOUBLE_INT_BINOP_DECL (/, int64)
+{
+  return octave_int64 (x / static_cast<double> (y));
+}
+
+INT_DOUBLE_BINOP_DECL (/, uint64)
+{
+  if (y >= 0 && y < octave_uint64::max () && y == xround (y))
+    {
+      return x / octave_uint64 (y);
+    }
+  else
+    return x * (1.0/y);
+}
+
+INT_DOUBLE_BINOP_DECL (/, int64)
+{
+  if (fabs (y) < octave_int64::max () && y == xround (y))
+    {
+      return x / octave_int64 (y);
+    }
+  else
+    return x * (1.0/y);
+}
+
+#define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP,T1,T2) \
+  template OCTAVE_API bool \
+  octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
+
+#define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
+  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, int64_t); \
+  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, uint64_t); \
+  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, int64_t, double); \
+  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, uint64_t, double)
+
+INSTANTIATE_INT64_DOUBLE_CMP_OP(lt);
+INSTANTIATE_INT64_DOUBLE_CMP_OP(le);
+INSTANTIATE_INT64_DOUBLE_CMP_OP(gt);
+INSTANTIATE_INT64_DOUBLE_CMP_OP(ge);
+INSTANTIATE_INT64_DOUBLE_CMP_OP(eq);
+INSTANTIATE_INT64_DOUBLE_CMP_OP(ne);
+
+#endif
+
+//template <class T>
+//bool
+//xisnan (const octave_int<T>&)
+//{
+//  return false;
+//}
+
+template <class T>
+octave_int<T>
+pow (const octave_int<T>& a, const octave_int<T>& b)
+{
+  octave_int<T> retval;
+
+  octave_int<T> zero = static_cast<T> (0);
+  octave_int<T> one = static_cast<T> (1);
+
+  if (b == zero || a == one)
+    retval = one;
+  else if (b < zero)
+    {
+      if (a == -one)
+        retval = (b.value () % 2) ? a : one;
+      else
+        retval = zero;
+    }
+  else
+    {
+      octave_int<T> a_val = a;
+      T b_val = b; // no need to do saturation on b
+
+      retval = a;
+
+      b_val -= 1;
+
+      while (b_val != 0)
+	{
+	  if (b_val & 1)
+	    retval = retval * a_val;
+
+	  b_val = b_val >> 1;
+
+	  if (b_val)
+	    a_val = a_val * a_val;
+	}
+    }
+
+  return retval;
+}
+
+template <class T>
+octave_int<T>
+pow (const double& a, const octave_int<T>& b)
+{ return octave_int<T> (pow (a, b.double_value ())); }
+
+template <class T>
+octave_int<T>
+pow (const octave_int<T>& a, const double& b)
+{ 
+  return ((b >= 0 && b < std::numeric_limits<T>::digits && b == xround (b))
+          ? pow (a, octave_int<T> (static_cast<T> (b)))
+          : octave_int<T> (pow (a.double_value (), b))); 
+}
+
+template <class T>
+octave_int<T>
+powf (const float& a, const octave_int<T>& b)
+{ return octave_int<T> (pow (a, b.float_value ())); }
+
+template <class T>
+octave_int<T>
+powf (const octave_int<T>& a, const float& b)
+{
+  return ((b >= 0 && b < std::numeric_limits<T>::digits && b == xround (b))
+          ? pow (a, octave_int<T> (static_cast<T> (b)))
+          : octave_int<T> (pow (a.double_value (), static_cast<double> (b)))); 
+}
+
+#define INSTANTIATE_INTTYPE(T) \
+  template class OCTAVE_API octave_int<T>; \
+  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \
+  template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \
+  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \
+  template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \
+  template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \
+  template OCTAVE_API octave_int<T> \
+  bitshift (const octave_int<T>&, int, const octave_int<T>&); \
+
+INSTANTIATE_INTTYPE (int8_t);
+INSTANTIATE_INTTYPE (int16_t);
+INSTANTIATE_INTTYPE (int32_t);
+INSTANTIATE_INTTYPE (int64_t);
+
+INSTANTIATE_INTTYPE (uint8_t);
+INSTANTIATE_INTTYPE (uint16_t);
+INSTANTIATE_INTTYPE (uint32_t);
+INSTANTIATE_INTTYPE (uint64_t);
+
+
+// Tests follow.
+
+/*
+
+%!assert(intmax("int64")/intmin("int64"),int64(-1))
+%!assert(intmin("int64")/int64(-1),intmax("int64"))
+%!assert(int64(2**63),intmax("int64"))
+%!test
+%! wstate = warning("query", "Octave:int-convert-overflow");
+%! warning("on", "Octave:int-convert-overflow");
+%! fail("int64(2**63)","warning",".*")
+%! warning(wstate.state, "Octave:int-convert-overflow");
+%!assert(uint64(2**64),intmax("uint64"))
+%!test
+%! a = 1.9*2^61; b = uint64(a); b++; assert(b > a)
+%!test
+%! a = -1.9*2^61; b = int64(a); b++; assert(b > a)
+%!test
+%! a = int64(-2**60) + 2; assert(1.25*a == (5*a)/4)
+%!test
+%! a = uint64(2**61) + 2; assert(1.25*a == (5*a)/4)
+%!assert(int32(2**31+0.5),intmax('int32'))
+%!test
+%! wstate = warning("query", "Octave:int-convert-overflow");
+%! warning("on", "Octave:int-convert-overflow");
+%! fail("int32(2**31+0.5)","warning",".*")
+%! warning(wstate.state, "Octave:int-convert-overflow");
+%!assert(int32(-2**31-0.5),intmin('int32'))
+%!test
+%! wstate = warning("query", "Octave:int-convert-overflow");
+%! warning("on", "Octave:int-convert-overflow");
+%! fail("int32(-2**31-0.5)","warning",".*")
+%! warning(wstate.state, "Octave:int-convert-overflow");
+%!assert((int64(2**62)+1)**1, int64(2**62)+1)
+%!assert((int64(2**30)+1)**2, int64(2**60+2**31) + 1)
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-inttypes.h b/liboctave/oct-inttypes.h
new file mode 100644
index 0000000..bb757ca
--- /dev/null
+++ b/liboctave/oct-inttypes.h
@@ -0,0 +1,1100 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_inttypes_h)
+#define octave_inttypes_h 1
+
+#include <climits>
+#include <cstdlib>
+
+#include <limits>
+#include <iosfwd>
+
+#include "lo-traits.h"
+#include "lo-math.h"
+#include "oct-types.h"
+#include "lo-mappers.h"
+
+#ifdef OCTAVE_INT_USE_LONG_DOUBLE
+inline long double xround (long double x) { return roundl (x); }
+inline long double xisnan (long double x) { return xisnan (static_cast<double> (x)); }
+#endif
+
+// Undefine min/max if needed (this may happen under Windows)
+#ifdef min
+#undef min
+#undef max
+#endif
+
+// FIXME -- we define this by our own because some compilers, such as
+// MSVC, do not provide std::abs (int64_t) and std::abs (uint64_t).  In
+// the future, it should go away in favor of std::abs.
+template <class T>
+inline T octave_int_abs (T x) { return x >= 0 ? x : -x; }
+
+// Query for an integer type of certain sizeof, and signedness.
+template<int qsize, bool qsigned>
+struct query_integer_type
+{
+public:
+  static const bool registered = false;
+  typedef void type; // Void shall result in a compile-time error if we 
+                     // attempt to use it in computations.
+};
+
+#define REGISTER_INT_TYPE(TYPE) \
+template <> \
+class query_integer_type<sizeof (TYPE), std::numeric_limits<TYPE>::is_signed> \
+{ \
+public: \
+  static const bool registered = true; \
+  typedef TYPE type; \
+}
+
+// No two registered integers can share sizeof and signedness.
+REGISTER_INT_TYPE (int8_t);
+REGISTER_INT_TYPE (uint8_t);
+REGISTER_INT_TYPE (int16_t);
+REGISTER_INT_TYPE (uint16_t);
+REGISTER_INT_TYPE (int32_t);
+REGISTER_INT_TYPE (uint32_t);
+REGISTER_INT_TYPE (int64_t);
+REGISTER_INT_TYPE (uint64_t);
+
+// Rationale: Comparators have a single static method, rel(), that returns the
+// result of the binary relation. They also have two static boolean fields:
+// ltval, gtval determine the value of x OP y if x < y, x > y, respectively. 
+#define REGISTER_OCTAVE_CMP_OP(NM,OP) \
+  class NM \
+    { \
+    public: \
+      static const bool ltval = (0 OP 1), gtval = (1 OP 0); \
+      template <class T> \
+      static bool op (T x, T y) { return x OP y; } \
+    }
+
+// We also provide two special relations: ct, yielding always true, and cf,
+// yielding always false.
+#define REGISTER_OCTAVE_CONST_OP(NM,value) \
+  class NM \
+    { \
+    public: \
+      static const bool ltval = value, gtval = value; \
+      template <class T> \
+      static bool op (T, T) { return value; } \
+    }
+
+// Handles non-homogeneous integer comparisons. Avoids doing useless tests.
+class octave_int_cmp_op
+{
+  // This determines a suitable promotion type for T1 when meeting T2 in a
+  // binary relation. If promotion to int or T2 is safe, it is used. Otherwise,
+  // the signedness of T1 is preserved and it is widened if T2 is wider.
+  // Notice that if this is applied to both types, they must end up with equal
+  // size.
+  template <class T1, class T2>
+  class prom
+    {
+      // Promote to int?
+      static const bool pint = (sizeof (T1) < sizeof (int) 
+                                && sizeof (T2) < sizeof (int));
+      static const bool t1sig = std::numeric_limits<T1>::is_signed;
+      static const bool t2sig = std::numeric_limits<T2>::is_signed;
+      static const bool psig = 
+        (pint || (sizeof (T2) > sizeof (T1) && t2sig) || t1sig);
+      static const int psize =
+        (pint ? sizeof (int) : (sizeof (T2) > sizeof (T1) 
+                                ? sizeof (T2) : sizeof (T1)));
+    public:
+      typedef typename query_integer_type<psize, psig>::type type;
+    };
+
+  // Implements comparisons between two types of equal size but
+  // possibly different signedness.
+  template<class xop, int size>
+  class uiop
+    {
+      typedef typename query_integer_type<size, false>::type utype;
+      typedef typename query_integer_type<size, true>::type stype;
+    public:
+      static bool op (utype x, utype y) 
+        { return xop::op (x, y); }
+      static bool op (stype x, stype y) 
+        { return xop::op (x, y); }
+      static bool op (stype x, utype y) 
+        { return (x < 0) ? xop::ltval : xop::op (static_cast<utype> (x), y); }
+      static bool op (utype x, stype y) 
+        { return (y < 0) ? xop::gtval : xop::op (x, static_cast<utype> (y)); }
+    };
+
+public:
+  REGISTER_OCTAVE_CMP_OP (lt, <);
+  REGISTER_OCTAVE_CMP_OP (le, <=);
+  REGISTER_OCTAVE_CMP_OP (gt, >);
+  REGISTER_OCTAVE_CMP_OP (ge, >=);
+  REGISTER_OCTAVE_CMP_OP (eq, ==);
+  REGISTER_OCTAVE_CMP_OP (ne, !=);
+  REGISTER_OCTAVE_CONST_OP (ct, true);
+  REGISTER_OCTAVE_CONST_OP (cf, false);
+
+  // Universal comparison operation.
+  template<class xop, class T1, class T2>
+  static bool
+  op (T1 x, T2 y)
+    {
+      typedef typename prom<T1, T2>::type PT1;
+      typedef typename prom<T2, T1>::type PT2;
+      return uiop<xop, sizeof (PT1)>::op (static_cast<PT1> (x), 
+                                          static_cast<PT2> (y));
+    }
+  
+public:
+
+  // Mixed comparisons
+  template <class xop, class T>
+  static bool
+  mop (T x, double y)
+    { return xop::op (static_cast<double> (x), y); }
+
+  template <class xop, class T>
+  static bool
+  mop (double x, T y)
+    { return xop::op (x, static_cast<double> (y)); }
+
+  // Typecasting to doubles won't work properly for 64-bit integers - they lose precision.
+  // If we have long doubles, use them...
+#ifdef OCTAVE_INT_USE_LONG_DOUBLE
+#define DEFINE_LONG_DOUBLE_CMP_OP(T1, T2) \
+  template <class xop> \
+  static bool \
+  mop (T1 x, T2 y) \
+    { \
+      return xop::op (static_cast<long double> (x), \
+                      static_cast<long double> (y)); \
+    }
+#else 
+  // ... otherwise, use external handlers
+
+  // FIXME: We could declare directly the mop methods as external,
+  // but we can't do this because bugs in gcc (<= 4.3) prevent
+  // explicit instantiations later in that case.
+#define DEFINE_LONG_DOUBLE_CMP_OP(T1, T2) \
+  template <class xop> static OCTAVE_API bool \
+  emulate_mop (T1, T2); \
+  template <class xop> \
+  static bool \
+  mop (T1 x, T2 y) \
+    { \
+      return emulate_mop<xop> (x, y); \
+    }
+#endif
+
+  DEFINE_LONG_DOUBLE_CMP_OP(double, uint64_t)
+  DEFINE_LONG_DOUBLE_CMP_OP(double, int64_t)
+  DEFINE_LONG_DOUBLE_CMP_OP(int64_t, double)
+  DEFINE_LONG_DOUBLE_CMP_OP(uint64_t, double)
+
+#undef DEFINE_LONG_DOUBLE_CMP_OP
+};
+
+// Base integer class. No data, just conversion methods and exception flags.
+template <class T> 
+class octave_int_base
+{
+protected:
+
+  static T min_val () { return std::numeric_limits<T>:: min (); }
+  static T max_val () { return std::numeric_limits<T>:: max (); }
+
+public:
+
+  // Convert integer value.
+  template <class S>
+  static T 
+  truncate_int (const S& value)
+    { 
+      // An exhaustive test whether the max and/or min check can be omitted.
+      static const bool t_is_signed = std::numeric_limits<T>::is_signed;
+      static const bool s_is_signed = std::numeric_limits<S>::is_signed;
+      static const int t_size = sizeof (T), s_size = sizeof (S);
+      static const bool omit_chk_min = 
+        (! s_is_signed || (t_is_signed && t_size >= s_size));
+      static const bool omit_chk_max = 
+        (t_size > s_size || (t_size == s_size 
+         && (! t_is_signed || s_is_signed)));
+      // If the check can be omitted, substitute constant false relation.
+      typedef octave_int_cmp_op::cf cf;
+      typedef octave_int_cmp_op::lt lt;
+      typedef octave_int_cmp_op::gt gt;
+      typedef typename if_then_else<omit_chk_min, cf, lt>::result chk_min;
+      typedef typename if_then_else<omit_chk_max, cf, gt>::result chk_max;
+
+      // Efficiency of the following depends on inlining and dead code
+      // elimination, but that should be a piece of cake for most compilers.
+      if (chk_min::op (value, static_cast<S> (min_val ())))
+        {
+          ftrunc = true;
+          return min_val ();
+        }
+      else if (chk_max::op (value, static_cast<S> (max_val ())))
+        {
+          ftrunc = true;
+          return max_val ();
+        }
+      else
+        return static_cast<T> (value);
+    }
+
+private:
+
+  // Computes a real-valued threshold for a max/min check. 
+  template <class S>
+  static S 
+  compute_threshold (S val, T orig_val)
+    { 
+      val = xround (val); // Fool optimizations (maybe redundant)
+      // If val is even, but orig_val is odd, we're one unit off.
+      if (orig_val % 2 && val / 2 == xround (val / 2))
+        // FIXME -- is this always correct?
+        val *= (static_cast<S>(1) - (std::numeric_limits<S>::epsilon () / 2)); 
+      return val;
+    }
+  
+public:
+  // Convert a real number (check NaN and non-int).
+  template <class S>
+  static T 
+  convert_real (const S& value)
+    {
+      // Compute proper thresholds.
+      static const S thmin = compute_threshold (static_cast<S> (min_val ()), min_val ());
+      static const S thmax = compute_threshold (static_cast<S> (max_val ()), max_val ());
+      if (xisnan (value))
+        {
+          fnan = true;
+          return static_cast<T> (0);
+        }
+      else if (value < thmin)
+        {
+          ftrunc = true;
+          return min_val ();
+        }
+      else if (value > thmax)
+        {
+          ftrunc = true;
+          return max_val ();
+        }
+      else
+        {
+          S rvalue = xround (value);
+          if (rvalue != value) fnon_int = true;
+          return static_cast<T> (rvalue);
+        }
+    }
+
+  // Exception flags rationale:
+  // There is little reason to distinguish math and conversion exceptions at
+  // octave_int level. Doing this would require special constructors for
+  // intermediate int results in math computations.
+  // 
+  // Boolean flags are used rather than a single flag, because raising a boolean
+  // flag is faster than masking an int flag (single mov versus mov, or, mov).
+  // Also, it is atomic, and thus thread-safe (but there is *one* flag for all
+  // threads).
+
+  static bool get_trunc_flag () { return ftrunc; }
+  static bool get_nan_flag () { return fnan; }
+  static bool get_non_int_flag () { return fnon_int; }
+  static void clear_conv_flags () 
+    { 
+      ftrunc = false;
+      fnan = false;
+      fnon_int = false;
+    }
+  // For compatibility.
+  static bool get_math_trunc_flag () { return ftrunc || fnan; }
+  static void clear_conv_flag () { clear_conv_flags (); }
+
+protected:
+
+  // Conversion flags.
+  static bool ftrunc;
+  static bool fnon_int;
+  static bool fnan;
+};
+
+template<class T> bool octave_int_base<T>::ftrunc = false;
+template<class T> bool octave_int_base<T>::fnon_int = false;
+template<class T> bool octave_int_base<T>::fnan = false;
+
+// Saturated (homogeneous) integer arithmetics. The signed and unsigned
+// implementations are significantly different, so we implement another layer
+// and completely specialize. Arithmetics inherits from octave_int_base so that
+// it can use its exceptions and truncation functions.
+
+template <class T, bool is_signed>
+class octave_int_arith_base
+{ };
+
+// Unsigned arithmetics. C++ standard requires it to be modular, so the
+// overflows can be handled efficiently and reliably.
+template <class T>
+class octave_int_arith_base<T, false> : octave_int_base<T>
+{
+public:
+
+  static T
+  abs (T x) { return x; }
+
+  static T
+  signum (T x) { return x ? static_cast<T> (1) : static_cast<T> (0); }
+
+  // Shifts do not overflow.
+  static T
+  rshift (T x, int n) { return x >> n; }
+
+  static T
+  lshift (T x, int n) { return x << n; }
+
+  static T
+  minus (T x)
+    {
+      if (x != 0) octave_int_base<T>::ftrunc = true;
+      return static_cast<T> (0);
+    }
+
+  // the overflow behaviour for unsigned integers is guaranteed by C/C++,
+  // so the following should always work.
+  static T 
+  add (T x, T y)
+    {
+      T u = x + y;
+      if (u < x)
+        {
+          u = octave_int_base<T>::max_val ();
+          octave_int_base<T>::ftrunc = true; 
+        }
+      return u;
+    }
+
+  static T 
+  sub (T x, T y)
+    {
+      T u = x - y;
+      if (u > x)
+        {
+          u = 0;
+          octave_int_base<T>::ftrunc = true; 
+        }
+      return u;
+    }
+
+  // Multiplication is done using promotion to wider integer type. If there is
+  // no suitable promotion type, this operation *MUST* be specialized. 
+  static T 
+  mul (T x, T y)
+    {
+      // Promotion type for multiplication (if exists).
+      typedef typename query_integer_type<2*sizeof (T), false>::type mptype;
+      return truncate_int (static_cast<mptype> (x) 
+                           * static_cast<mptype> (y));
+    }
+
+  // Division with rounding to nearest. Note that / and % are probably
+  // computed by a single instruction.
+  static T 
+  div (T x, T y)
+    {
+      if (y != 0)
+        {
+          T z = x / y, w = x % y;
+          if (w >= y-w) z += 1;
+          return z;
+        }
+      else
+        {
+          octave_int_base<T>::ftrunc = true; 
+          return x ? octave_int_base<T>::max_val () : 0;
+        }
+    }
+};
+
+#ifdef OCTAVE_INT_USE_LONG_DOUBLE
+// Handle 64-bit multiply using long double
+template <>
+inline uint64_t
+octave_int_arith_base<uint64_t, false>:: mul (uint64_t x, uint64_t y)
+{
+  long double p = static_cast<long double> (x) * static_cast<long double> (y);
+  if (p > static_cast<long double> (octave_int_base<uint64_t>::max_val ()))
+    {
+      octave_int_base<uint64_t>::ftrunc = true;
+      return octave_int_base<uint64_t>::max_val ();
+    }
+  else
+    return static_cast<uint64_t> (p);
+}
+#else
+// Special handler for 64-bit integer multiply.
+template <>
+OCTAVE_API uint64_t 
+octave_int_arith_base<uint64_t, false>::mul (uint64_t, uint64_t);
+#endif
+
+// Signed integer arithmetics.
+// Rationale: If HAVE_FAST_INT_OPS is defined, the following conditions
+// should hold:
+// 1. Signed numbers are represented by twos complement
+//    (see <http://en.wikipedia.org/wiki/Two%27s_complement>)
+// 2. static_cast to unsigned int counterpart works like interpreting
+//    the signed bit pattern as unsigned (and is thus zero-cost).
+// 3. Signed addition and subtraction yield the same bit results as unsigned.
+//    (We use casts to prevent optimization interference, so there is no
+//     need for things like -ftrapv).
+// 4. Bit operations on signed integers work like on unsigned integers,
+//    except for the shifts. Shifts are arithmetic.
+//
+// The above conditions are satisfied by most modern platforms. If
+// HAVE_FAST_INT_OPS is defined, bit tricks and wraparound arithmetics are used
+// to avoid conditional jumps as much as possible, thus being friendly to modern
+// pipeline processor architectures.
+// Otherwise, we fall back to a bullet-proof code that only uses assumptions 
+// guaranteed by the standard.
+
+template <class T>
+class octave_int_arith_base<T, true> : octave_int_base<T>
+{
+  // The corresponding unsigned type.
+  typedef typename query_integer_type<sizeof (T), false>::type UT;
+public:
+
+  // Returns 1 for negative number, 0 otherwise.
+  static T
+  signbit (T x) 
+    { 
+#ifdef HAVE_FAST_INT_OPS
+      return static_cast<UT> (x) >> std::numeric_limits<T>::digits;
+#else
+      return (x < 0) ? 1 : 0; 
+#endif
+    }
+
+  static T
+  abs (T x)
+    {
+#ifdef HAVE_FAST_INT_OPS
+      // This is close to how GCC does std::abs, but we can't just use std::abs,
+      // because its behaviour for INT_MIN is undefined and the compiler could
+      // discard the following test.
+      T m = x >> std::numeric_limits<T>::digits;
+      T y = (x ^ m) - m;
+      if (y < 0) 
+        {
+          y = octave_int_base<T>::max_val ();
+          octave_int_base<T>::ftrunc = true;
+        }
+      return y;
+#else
+      // -INT_MAX is safe because C++ actually allows only three implementations
+      // of integers: sign & magnitude, ones complement and twos complement.
+      // The first test will, with modest optimizations, evaluate at compile
+      // time, and maybe eliminate the branch completely.
+      T y;
+      if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
+          && x == octave_int_base<T>::min_val ())
+        {
+          y = octave_int_base<T>::max_val ();
+          octave_int_base<T>::ftrunc = true;
+        }
+      else
+        y = (x < 0) ? -x : x;
+      return y;
+#endif
+    }
+
+  static T
+  signum (T x) 
+    { 
+      // With modest optimizations, this will compile without a jump.
+      return ((x > 0) ? 1 : 0) - signbit (x); 
+    }
+
+  // FIXME -- we do not have an authority what signed shifts should
+  // exactly do, so we define them the easy way. Note that Matlab does
+  // not define signed shifts.
+
+  static T
+  rshift (T x, int n) { return x >> n; }
+
+  static T
+  lshift (T x, int n) { return x << n; }
+
+  // Minus has problems similar to abs.
+  static T
+  minus (T x)
+    {
+#ifdef HAVE_FAST_INT_OPS
+      T y = -x;
+      if (y == octave_int_base<T>::min_val ())
+        {
+          --y;
+          octave_int_base<T>::ftrunc = false;
+        }
+      return y;
+#else
+      T y;
+      if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
+          && x == octave_int_base<T>::min_val ())
+        {
+          y = octave_int_base<T>::max_val ();
+          octave_int_base<T>::ftrunc = true;
+        }
+      else
+        y = -x;
+      return y;
+#endif
+    }
+
+  static T 
+  add (T x, T y)
+    {
+#ifdef HAVE_FAST_INT_OPS
+    // The typecasts do nothing, but they are here to prevent an optimizing
+    // compiler from interfering. Also, the signed operations on small types
+    // actually return int.
+      T u = static_cast<UT> (x) + static_cast<UT> (y);
+      T ux = u ^ x, uy = u ^ y; 
+      if ((ux & uy) < 0) 
+        {
+          u = octave_int_base<T>::max_val () + signbit (~u);
+          octave_int_base<T>::ftrunc = true;
+        }
+      return u;
+#else
+      // We shall carefully avoid anything that may overflow.
+      T u;
+      if (y < 0)
+        {
+          if (x < octave_int_base<T>::min_val () - y)
+            {
+              u = octave_int_base<T>::min_val ();
+              octave_int_base<T>::ftrunc = true;
+            }
+          else
+            u = x + y;
+        }
+      else
+        {
+          if (x > octave_int_base<T>::max_val () - y)
+            {
+              u = octave_int_base<T>::max_val ();
+              octave_int_base<T>::ftrunc = true;
+            }
+          else
+            u = x + y;
+        }
+
+      return u;
+#endif
+    }
+
+  // This is very similar to addition.
+  static T 
+  sub (T x, T y)
+    {
+#ifdef HAVE_FAST_INT_OPS
+    // The typecasts do nothing, but they are here to prevent an optimizing
+    // compiler from interfering. Also, the signed operations on small types
+    // actually return int.
+      T u = static_cast<UT> (x) - static_cast<UT> (y);
+      T ux = u ^ x, uy = u ^ ~y; 
+      if ((ux & uy) < 0) 
+        {
+          u = octave_int_base<T>::max_val () + signbit (~u);
+          octave_int_base<T>::ftrunc = true;
+        }
+      return u;
+#else
+      // We shall carefully avoid anything that may overflow.
+      T u;
+      if (y < 0)
+        {
+          if (x > octave_int_base<T>::max_val () + y)
+            {
+              u = octave_int_base<T>::max_val ();
+              octave_int_base<T>::ftrunc = true;
+            }
+          else
+            u = x - y;
+        }
+      else
+        {
+          if (x < octave_int_base<T>::min_val () + y)
+            {
+              u = octave_int_base<T>::min_val ();
+              octave_int_base<T>::ftrunc = true;
+            }
+          else
+            u = x - y;
+        }
+
+      return u;
+#endif
+    }
+
+  // Multiplication is done using promotion to wider integer type. If there is
+  // no suitable promotion type, this operation *MUST* be specialized. 
+  static T 
+  mul (T x, T y)
+    {
+      // Promotion type for multiplication (if exists).
+      typedef typename query_integer_type<2*sizeof (T), true>::type mptype;
+      return truncate_int (static_cast<mptype> (x) 
+                           * static_cast<mptype> (y));
+    }
+
+  // Division.
+  static T 
+  div (T x, T y)
+    {
+      T z;
+      if (y == 0)
+        {
+          octave_int_base<T>::ftrunc = true;
+          if (x < 0)
+            z = octave_int_base<T>::min_val ();
+          else if (x != 0)
+            z = octave_int_base<T>::max_val ();
+          else
+            z = 0;
+        }
+      else if (y < 0)
+        {
+          // This is a special case that overflows as well.
+          if (y == -1 && x == octave_int_base<T>::min_val ())
+            {
+              octave_int_base<T>::ftrunc = true;
+              z = octave_int_base<T>::max_val ();
+            }
+          else
+            {
+              z = x / y;
+              T w = -octave_int_abs (x % y); // Can't overflow, but std::abs (x) can!
+              if (w <= y - w) 
+                z -= 1 - (signbit (x) << 1);
+            }
+        }
+      else
+        {
+          z = x / y;
+          // FIXME -- this is a workaround due to MSVC's absence of
+          // std::abs (int64_t).  The call to octave_int_abs can't
+          // overflow, but std::abs (x) can!
+	  T w = octave_int_abs (x % y);
+
+          if (w >= y - w) 
+            z += 1 - (signbit (x) << 1);
+        }
+      return z;
+    }
+
+};
+
+#ifdef OCTAVE_INT_USE_LONG_DOUBLE
+// Handle 64-bit multiply using long double
+template <>
+inline int64_t
+octave_int_arith_base<int64_t, true>:: mul (int64_t x, int64_t y)
+{
+  long double p = static_cast<long double> (x) * static_cast<long double> (y);
+  // NOTE: We could maybe do it with a single branch if HAVE_FAST_INT_OPS, but it
+  // would require one more runtime conversion, so the question is whether it would
+  // really be faster.
+  if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ()))
+    {
+      octave_int_base<int64_t>::ftrunc = true;
+      return octave_int_base<int64_t>::max_val ();
+    }
+  else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ()))
+    {
+      octave_int_base<int64_t>::ftrunc = true;
+      return octave_int_base<int64_t>::min_val ();
+    }
+  else
+    return static_cast<int64_t> (p);
+}
+#else
+// Special handler for 64-bit integer multiply.
+template <>
+OCTAVE_API int64_t 
+octave_int_arith_base<int64_t, true>::mul (int64_t, int64_t);
+#endif
+
+// This class simply selects the proper arithmetics.
+template<class T>
+class octave_int_arith 
+ : public octave_int_arith_base<T, std::numeric_limits<T>::is_signed>
+{};
+
+template <class T>
+class
+octave_int : public octave_int_base<T>
+{
+public:
+  typedef T val_type;
+
+  octave_int (void) : ival () { }
+
+  octave_int (T i) : ival (i) { }
+
+  octave_int (double d) : ival (octave_int_base<T>::convert_real (d)) { } 
+
+  octave_int (float d) : ival (octave_int_base<T>::convert_real (d)) { } 
+
+#ifdef OCTAVE_INT_USE_LONG_DOUBLE
+  octave_int (long double d) : ival (octave_int_base<T>::convert_real (d)) { } 
+#endif
+
+  octave_int (bool b) : ival (b) { }
+
+  template <class U>
+  octave_int (const U& i) : ival(octave_int_base<T>::truncate_int (i)) { }
+
+  template <class U>
+  octave_int (const octave_int<U>& i)
+    : ival (octave_int_base<T>::truncate_int (i.value ())) { }
+
+  octave_int (const octave_int<T>& i) : ival (i.ival) { }
+
+  octave_int& operator = (const octave_int<T>& i)
+  {
+    ival = i.ival;
+    return *this;
+  }
+
+  T value (void) const { return ival; }
+
+  const unsigned char * iptr (void) const
+  { return reinterpret_cast<const unsigned char *> (& ival); }
+
+  bool operator ! (void) const { return ! ival; }
+
+  bool bool_value (void) const { return static_cast<bool> (value ()); }
+
+  char char_value (void) const { return static_cast<char> (value ()); }
+
+  double double_value (void) const { return static_cast<double> (value ()); }
+
+  float float_value (void) const { return static_cast<float> (value ()); }
+
+  operator T (void) const { return value (); }
+
+  // char and bool operators intentionally omitted.
+
+  operator double (void) const { return double_value (); }
+
+  operator float (void) const { return float_value (); }
+
+  octave_int<T>
+  operator + () const
+    { return *this; }
+
+  // unary operators & mappers
+#define OCTAVE_INT_UN_OP(OPNAME,NAME) \
+  inline octave_int<T> \
+  OPNAME () const \
+  { return octave_int_arith<T>::NAME (ival); }
+
+  OCTAVE_INT_UN_OP(operator -, minus)
+  OCTAVE_INT_UN_OP(abs, abs)
+  OCTAVE_INT_UN_OP(signum, signum)
+
+#undef OCTAVE_INT_UN_OP
+
+// Homogeneous binary integer operations.
+#define OCTAVE_INT_BIN_OP(OP, NAME, ARGT) \
+  inline octave_int<T> \
+  operator OP (const ARGT& y) const \
+  { return octave_int_arith<T>::NAME (ival, y); } \
+  inline octave_int<T>& \
+  operator OP##= (const ARGT& y) \
+  { \
+    ival = octave_int_arith<T>::NAME (ival, y); \
+    return *this; \
+  }
+
+  OCTAVE_INT_BIN_OP(+, add, octave_int<T>)
+  OCTAVE_INT_BIN_OP(-, sub, octave_int<T>)
+  OCTAVE_INT_BIN_OP(*, mul, octave_int<T>)
+  OCTAVE_INT_BIN_OP(/, div, octave_int<T>)
+  OCTAVE_INT_BIN_OP(<<, lshift, int)
+  OCTAVE_INT_BIN_OP(>>, rshift, int)
+
+#undef OCTAVE_INT_BIN_OP
+
+  static octave_int<T> min (void) { return std::numeric_limits<T>::min (); }
+  static octave_int<T> max (void) { return std::numeric_limits<T>::max (); }
+
+  static int nbits (void) { return std::numeric_limits<T>::digits; }
+
+  static int byte_size (void) { return sizeof(T); }
+
+  static const char *type_name ();
+
+  // The following are provided for convenience.
+  static const octave_int zero, one;
+  
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return const_cast<T *> (&ival); }
+
+private:
+
+  T ival;
+};
+
+// No mixed integer binary operations!
+
+template <class T>
+inline bool
+xisnan (const octave_int<T>&)
+{ return false; }
+
+// FIXME -- can/should any of these be inline?
+
+template <class T>
+extern OCTAVE_API octave_int<T>
+pow (const octave_int<T>&, const octave_int<T>&);
+
+template <class T>
+extern OCTAVE_API octave_int<T>
+pow (const double& a, const octave_int<T>& b);
+
+template <class T>
+extern OCTAVE_API octave_int<T>
+pow (const octave_int<T>& a, const double& b);
+
+template <class T>
+extern OCTAVE_API octave_int<T>
+powf (const float& a, const octave_int<T>& b);
+
+template <class T>
+extern OCTAVE_API octave_int<T>
+powf (const octave_int<T>& a, const float& b);
+
+// Binary relations
+
+#define OCTAVE_INT_CMP_OP(OP, NAME) \
+  template<class T1, class T2> \
+  inline bool \
+  operator OP (const octave_int<T1>& x, const octave_int<T2>& y) \
+  { return octave_int_cmp_op::op<octave_int_cmp_op::NAME, T1, T2> \
+    (x.value (), y.value ()); }
+
+OCTAVE_INT_CMP_OP (<, lt)
+OCTAVE_INT_CMP_OP (<=, le)
+OCTAVE_INT_CMP_OP (>, gt)
+OCTAVE_INT_CMP_OP (>=, ge)
+OCTAVE_INT_CMP_OP (==, eq)
+OCTAVE_INT_CMP_OP (!=, ne)
+
+#undef OCTAVE_INT_CMP_OP
+
+template <class T>
+inline std::ostream&
+operator << (std::ostream& os, const octave_int<T>& ival)
+{
+  os << ival.value ();
+  return os;
+}
+
+template <class T>
+inline std::istream&
+operator >> (std::istream& is, octave_int<T>& ival)
+{
+  T tmp = 0;
+  is >> tmp;
+  ival = tmp;
+  return is;
+}
+
+// Bitwise operations
+
+#define OCTAVE_INT_BITCMP_OP(OP) \
+  template <class T> \
+  octave_int<T> \
+  operator OP (const octave_int<T>& x, const octave_int<T>& y) \
+  { return x.value () OP y.value (); }
+
+OCTAVE_INT_BITCMP_OP (&)
+OCTAVE_INT_BITCMP_OP (|)
+OCTAVE_INT_BITCMP_OP (^)
+
+#undef OCTAVE_INT_BITCMP_OP
+
+// General bit shift.
+template <class T>
+octave_int<T>
+bitshift (const octave_int<T>& a, int n,
+	  const octave_int<T>& mask = std::numeric_limits<T>::max ())
+{
+  if (n > 0)
+    return (a << n) & mask;
+  else if (n < 0)
+    return (a >> -n) & mask;
+  else
+    return a & mask;
+}
+
+typedef octave_int<int8_t> octave_int8;
+typedef octave_int<int16_t> octave_int16;
+typedef octave_int<int32_t> octave_int32;
+typedef octave_int<int64_t> octave_int64;
+
+typedef octave_int<uint8_t> octave_uint8;
+typedef octave_int<uint16_t> octave_uint16;
+typedef octave_int<uint32_t> octave_uint32;
+typedef octave_int<uint64_t> octave_uint64;
+
+#define OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
+  template <class T> \
+  inline octave_int<T> \
+  operator OP (const octave_int<T>& x, const double& y) \
+  { return octave_int<T> (static_cast<double> (x) OP y); } \
+  template <class T> \
+  inline octave_int<T> \
+  operator OP (const double& x, const octave_int<T>& y) \
+  { return octave_int<T> (x OP static_cast<double> (y)); } \
+
+#ifdef OCTAVE_INT_USE_LONG_DOUBLE
+// Handle mixed op using long double
+#define OCTAVE_INT_DOUBLE_BIN_OP(OP) \
+  OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
+  template <> \
+  inline octave_int64 \
+  operator OP (const double& x, const octave_int64& y) \
+  { return octave_int64 (x OP static_cast<long double> (y.value ())); } \
+  template <> \
+  inline octave_uint64 \
+  operator OP (const double& x, const octave_uint64& y) \
+  { return octave_uint64 (x OP static_cast<long double> (y.value ())); } \
+  template <> \
+  inline octave_int64 \
+  operator OP (const octave_int64& x, const double& y) \
+  { return octave_int64 (static_cast<long double> (x.value ()) OP y); } \
+  template <> \
+  inline octave_uint64 \
+  operator OP (const octave_uint64& x, const double& y) \
+  { return octave_uint64 (static_cast<long double> (x.value ()) OP y); }
+
+#else
+// external handlers
+#define OCTAVE_INT_DOUBLE_BIN_OP(OP) \
+  OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
+  template <> \
+  OCTAVE_API octave_int64 \
+  operator OP (const double&, const octave_int64&); \
+  template <> \
+  OCTAVE_API octave_uint64 \
+  operator OP (const double&, const octave_uint64&); \
+  template <> \
+  OCTAVE_API octave_int64 \
+  operator OP (const octave_int64&, const double&); \
+  template <> \
+  OCTAVE_API octave_uint64 \
+  operator OP (const octave_uint64&, const double&);
+
+#endif
+
+OCTAVE_INT_DOUBLE_BIN_OP (+)
+OCTAVE_INT_DOUBLE_BIN_OP (-)
+OCTAVE_INT_DOUBLE_BIN_OP (*)
+OCTAVE_INT_DOUBLE_BIN_OP (/)
+
+#undef OCTAVE_INT_DOUBLE_BIN_OP0
+#undef OCTAVE_INT_DOUBLE_BIN_OP
+
+#define OCTAVE_INT_DOUBLE_CMP_OP(OP,NAME) \
+  template <class T> \
+  inline bool \
+  operator OP (const octave_int<T>& x, const double& y) \
+  { return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x.value (), y); } \
+  template <class T> \
+  inline bool \
+  operator OP (const double& x, const octave_int<T>& y) \
+  { return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x, y.value ()); }
+
+OCTAVE_INT_DOUBLE_CMP_OP (<, lt)
+OCTAVE_INT_DOUBLE_CMP_OP (<=, le)
+OCTAVE_INT_DOUBLE_CMP_OP (>=, ge)
+OCTAVE_INT_DOUBLE_CMP_OP (>, gt)
+OCTAVE_INT_DOUBLE_CMP_OP (==, eq)
+OCTAVE_INT_DOUBLE_CMP_OP (!=, ne)
+
+#undef OCTAVE_INT_DOUBLE_CMP_OP
+
+// Floats are handled by simply converting to doubles.
+
+#define OCTAVE_INT_FLOAT_BIN_OP(OP) \
+  template <class T> \
+  inline octave_int<T> \
+  operator OP (const octave_int<T>& x, float y) \
+  { return x OP static_cast<double> (y); } \
+  template <class T> \
+  inline octave_int<T> \
+  operator OP (float x, const octave_int<T>& y) \
+  { return static_cast<double> (x) OP y; }
+
+OCTAVE_INT_FLOAT_BIN_OP (+)
+OCTAVE_INT_FLOAT_BIN_OP (-)
+OCTAVE_INT_FLOAT_BIN_OP (*)
+OCTAVE_INT_FLOAT_BIN_OP (/)
+
+#undef OCTAVE_INT_FLOAT_BIN_OP
+
+#define OCTAVE_INT_FLOAT_CMP_OP(OP) \
+  template <class T> \
+  inline bool \
+  operator OP (const octave_int<T>& x, const float& y) \
+  { return x OP static_cast<double> (y); } \
+  template <class T> \
+  bool \
+  operator OP (const float& x, const octave_int<T>& y) \
+  { return static_cast<double> (x) OP y; }
+
+OCTAVE_INT_FLOAT_CMP_OP (<)
+OCTAVE_INT_FLOAT_CMP_OP (<=)
+OCTAVE_INT_FLOAT_CMP_OP (>=)
+OCTAVE_INT_FLOAT_CMP_OP (>)
+OCTAVE_INT_FLOAT_CMP_OP (==)
+OCTAVE_INT_FLOAT_CMP_OP (!=)
+
+#undef OCTAVE_INT_FLOAT_CMP_OP
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-locbuf.cc b/liboctave/oct-locbuf.cc
new file mode 100644
index 0000000..041831a
--- /dev/null
+++ b/liboctave/oct-locbuf.cc
@@ -0,0 +1,104 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include "oct-locbuf.h"
+
+// Query for configured chunk size, and if not defined, set it to 32 MB.
+// FIXME: 32MB is hard-coded. Maybe we could use something better, like
+// querying for available physical memory.
+#ifndef OCTAVE_LOCBUF_CHUNKSIZE_MB
+#define OCTAVE_LOCBUF_CHUNKSIZE_MB 32
+#endif
+
+// Each chunk will be at least this big. 
+const size_t octave_chunk_buffer::chunk_size = 
+  static_cast<size_t> (OCTAVE_LOCBUF_CHUNKSIZE_MB) << 20;
+
+char *octave_chunk_buffer::top = 0, *octave_chunk_buffer::chunk = 0;
+size_t octave_chunk_buffer::left = 0;
+
+octave_chunk_buffer::octave_chunk_buffer (size_t size) : cnk (0), dat (0) 
+{
+  // Alignment mask. The size of double or long int, whichever is greater.
+  // All data will be aligned to this size. If it's not enough for a type,
+  // that type should not be declared as POD. 
+  static const size_t align_mask = (sizeof (long) < sizeof (double)
+                                    ? sizeof (double)
+                                    : sizeof (long)) - 1;
+
+  if (! size) return;
+  // Align size. Note that size_t is unsigned, so size-1 must correctly
+  // wrap around.
+  size = ((size - 1) | align_mask) + 1;
+
+  if (size > left)
+    {
+      // Big buffers (> 1/8 chunk) will be allocated as stand-alone and
+      // won't disrupt the chain.
+      if (size > chunk_size >> 3)
+        {
+          // Use new [] to get std::bad_alloc if out of memory. Could as
+          // well be std::malloc and handle that ourselves.
+          dat = new char [size];
+          return;
+        }
+
+      dat = new char [chunk_size];
+      chunk = top = dat;
+      left = chunk_size;
+    }
+
+  // Now allocate memory from the chunk and update state.
+  cnk = chunk;
+  dat = top;
+  left -= size;
+  top += size;
+}
+
+octave_chunk_buffer::~octave_chunk_buffer (void)
+{
+  if (cnk == chunk)
+    {
+      // Our chunk is still the active one. Just restore the state.
+      left += top - dat;
+      top = dat;
+    }
+  else if (! cnk)
+    {
+      // We were a stand-alone buffer.
+      delete [] dat;
+    }
+  else
+    {
+      // Responsible for deletion.
+      delete [] chunk;
+      chunk = cnk;
+      top = dat;
+      // FIXME: This will only work if chunk_size is constant.
+      left = chunk_size - (dat - cnk);
+    }
+}
diff --git a/liboctave/oct-locbuf.h b/liboctave/oct-locbuf.h
new file mode 100644
index 0000000..727e58a
--- /dev/null
+++ b/liboctave/oct-locbuf.h
@@ -0,0 +1,164 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_local_buffer_h)
+#define octave_local_buffer_h 1
+
+#include <cstddef>
+#include "oct-cmplx.h"
+
+// The default local buffer simply encapsulates an *array* pointer that gets
+// delete[]d automatically. For common POD types, we provide specializations.
+
+template <class T>
+class octave_local_buffer
+{
+public:
+  octave_local_buffer (size_t size)
+    : data (0) 
+    { 
+      if (size) 
+        data = new T[size]; 
+    }
+  ~octave_local_buffer (void) { delete [] data; }
+  operator T *() const { return data; }
+private:
+  T *data;
+};
+
+// For buffers of POD types, we'll be more smart. There is one thing that
+// differentiates a local buffer from a dynamic array - the local buffers, if
+// not manipulated improperly, have a FIFO semantics, meaning that if buffer B
+// is allocated after buffer A, B *must* be deallocated before A. This is
+// *guaranteed* if you use local buffer exclusively through the
+// OCTAVE_LOCAL_BUFFER macro, because the C++ standard *mandates* explicit
+// local objects be destroyed in reverse order of declaration.
+// Therefore, we can avoid memory fragmentation by allocating fairly large
+// chunks of memory and serving local buffers from them in a stack-like manner.
+// The first returning buffer in previous chunk will be responsible for
+// deallocating the chunk.
+
+class octave_chunk_buffer
+{
+  static const size_t chunk_size;
+
+  static char *top, *chunk;
+  static size_t left;
+
+  char *cnk;
+  char *dat;
+
+public:
+
+  OCTAVE_API octave_chunk_buffer (size_t size);
+
+  OCTAVE_API ~octave_chunk_buffer (void);
+
+  char *data (void) const { return dat; }
+};
+
+// This specializes octave_local_buffer to use the chunked buffer mechanism
+// for POD types.
+#define SPECIALIZE_POD_BUFFER(TYPE) \
+template <> \
+class octave_local_buffer<TYPE> : private octave_chunk_buffer \
+{ \
+public: \
+  octave_local_buffer (size_t size) : octave_chunk_buffer (size * sizeof (TYPE)) { } \
+  operator TYPE *() const { return reinterpret_cast<TYPE *> (this->data ()); } \
+}
+
+SPECIALIZE_POD_BUFFER (bool);
+SPECIALIZE_POD_BUFFER (char);
+SPECIALIZE_POD_BUFFER (unsigned short);
+SPECIALIZE_POD_BUFFER (short);
+SPECIALIZE_POD_BUFFER (int);
+SPECIALIZE_POD_BUFFER (unsigned int);
+SPECIALIZE_POD_BUFFER (long);
+SPECIALIZE_POD_BUFFER (unsigned long);
+SPECIALIZE_POD_BUFFER (float);
+SPECIALIZE_POD_BUFFER (double);
+// FIXME: Are these guaranteed to be POD and satisfy alignment?
+SPECIALIZE_POD_BUFFER (Complex);
+SPECIALIZE_POD_BUFFER (FloatComplex);
+// MORE ?
+
+// All pointers and const pointers are also POD types.
+template <class T>
+class octave_local_buffer<T *> : private octave_chunk_buffer
+{
+public:
+  octave_local_buffer (size_t size) : octave_chunk_buffer (size * sizeof (T *)) { }
+  operator T **() const { return reinterpret_cast<T **> (this->data ()); }
+};
+
+template <class T>
+class octave_local_buffer<const T *> : private octave_chunk_buffer
+{
+public:
+  octave_local_buffer (size_t size) : octave_chunk_buffer (size * sizeof (const T *)) { }
+  operator const T **() const { return reinterpret_cast<const T **> (this->data ()); }
+};
+
+// If the compiler supports dynamic stack arrays, we can use the attached hack
+// to place small buffer arrays on the stack. It may be even faster than our
+// obstack-like optimization, but is dangerous because stack is a very limited
+// resource, so we disable it.
+#if 0 //defined (HAVE_DYNAMIC_AUTO_ARRAYS)
+
+// Maximum buffer size (in bytes) to be placed on the stack.
+
+#define OCTAVE_LOCAL_BUFFER_MAX_STACK_SIZE 8192
+
+// If we have automatic arrays, we use an automatic array if the size is small
+// enough.  To avoid possibly evaluating `size' multiple times, we first cache
+// it.  Note that we always construct both the stack array and the
+// octave_local_buffer object, but only one of them will be nonempty.
+
+#define OCTAVE_LOCAL_BUFFER(T, buf, size) \
+  const size_t _bufsize_ ## buf = size; \
+  const bool _lbufaut_ ## buf = _bufsize_ ## buf * sizeof (T) \
+     <= OCTAVE_LOCAL_BUFFER_MAX_STACK_SIZE; \
+  T _bufaut_ ## buf [_lbufaut_ ## buf ? _bufsize_ ## buf : 0]; \
+  octave_local_buffer<T> _bufheap_ ## buf (!_lbufaut_ ## buf ? _bufsize_ ## buf : 0); \
+  T *buf = _lbufaut_ ## buf ? _bufaut_ ## buf : static_cast<T *> (_bufheap_ ## buf)
+
+#else
+
+// If we don't have automatic arrays, we simply always use octave_local_buffer.
+
+#define OCTAVE_LOCAL_BUFFER(T, buf, size) \
+  octave_local_buffer<T> _buffer_ ## buf (size); \
+  T *buf = _buffer_ ## buf
+
+#endif 
+
+// Yeah overloading macros would be nice.
+// Note: we use weird variables in the for loop to avoid warnings about
+// shadowed parameters.
+#define OCTAVE_LOCAL_BUFFER_INIT(T, buf, size, value) \
+  OCTAVE_LOCAL_BUFFER(T, buf, size); \
+  for (size_t _buf_iter = 0, _buf_size = size; \
+       _buf_iter < _buf_size; _buf_iter++) buf[_buf_iter] = value
+
+#endif
+
diff --git a/liboctave/oct-md5.cc b/liboctave/oct-md5.cc
new file mode 100644
index 0000000..3a0b6fd
--- /dev/null
+++ b/liboctave/oct-md5.cc
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+
+#include <string>
+#include <vector>
+
+#include "lo-error.h"
+#include "oct-md5.h"
+#include "md5.h"
+#include "oct-locbuf.h"
+ 
+std::string
+oct_md5 (const std::string str)
+{
+  md5_state_t state;
+
+  OCTAVE_LOCAL_BUFFER (md5_byte_t, digest, 16);
+  md5_init (&state);
+  md5_append (&state, reinterpret_cast<const md5_byte_t *>(str.c_str()),
+	      str.length());
+  md5_finish (&state, digest);
+
+  OCTAVE_LOCAL_BUFFER (char, tmp, 33);
+  for (octave_idx_type i = 0; i < 16; i++)
+    sprintf (&tmp[2*i], "%02x", digest[i]);
+  tmp[32] = 0;
+  return std::string (tmp);
+}
+	  
+std::string
+oct_md5_file (const std::string file)
+{
+  FILE *ifile = fopen (file.c_str (), "rb");
+
+  if (! ifile)
+    {
+      (*current_liboctave_error_handler) ("unable to open file `%s' for writing",
+					  file.c_str());
+      return std::string();
+    }
+  else
+    {
+      md5_state_t state;
+      size_t nel;
+
+      OCTAVE_LOCAL_BUFFER (md5_byte_t, digest, 16);
+      OCTAVE_LOCAL_BUFFER (md5_byte_t, buf, 1024);
+
+      md5_init (&state);
+
+      while ((nel = fread (buf, 1, 1024, ifile)))
+	md5_append (&state, buf, nel);
+
+      fclose (ifile);
+
+      md5_finish (&state, digest);
+
+      OCTAVE_LOCAL_BUFFER (char, tmp, 33);
+      for (octave_idx_type i = 0; i < 16; i++)
+	sprintf (&tmp[2*i], "%02x", digest[i]);
+      tmp[32] = 0;
+      return std::string (tmp);
+    }
+}
+	  
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-md5.h b/liboctave/oct-md5.h
new file mode 100644
index 0000000..9bf1cfb
--- /dev/null
+++ b/liboctave/oct-md5.h
@@ -0,0 +1,31 @@
+/*
+
+Copyright (C) 2007 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+extern OCTAVE_API std::string oct_md5 (const std::string str);
+
+extern OCTAVE_API std::string oct_md5_file (const std::string file);
+	  
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-mutex.cc b/liboctave/oct-mutex.cc
new file mode 100644
index 0000000..7f96d80
--- /dev/null
+++ b/liboctave/oct-mutex.cc
@@ -0,0 +1,126 @@
+/*
+
+Copyright (C) 2008, 2009 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-mutex.h"
+#include "lo-error.h"
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#include <windows.h>
+#elif defined (HAVE_PTHREAD_H)
+#include <pthread.h>
+#endif
+
+void
+octave_base_mutex::lock (void)
+{
+  (*current_liboctave_error_handler) ("mutex not supported on this platform");
+}
+
+void
+octave_base_mutex::unlock (void)
+{
+  (*current_liboctave_error_handler) ("mutex not supported on this platform");
+}
+
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+
+class
+octave_w32_mutex : public octave_base_mutex
+{
+public:
+  octave_w32_mutex (void)
+    : octave_base_mutex ()
+  {
+    InitializeCriticalSection (&cs);
+  }
+
+  ~octave_w32_mutex (void)
+  {
+    DeleteCriticalSection (&cs);
+  }
+
+  void lock (void)
+  {
+    EnterCriticalSection (&cs);
+  }
+
+  void unlock (void)
+  {
+    LeaveCriticalSection (&cs);
+  }
+
+private:
+  CRITICAL_SECTION cs;
+};
+
+#elif defined (HAVE_PTHREAD_H)
+
+class
+octave_pthread_mutex : public octave_base_mutex
+{
+public:
+  octave_pthread_mutex (void)
+    : octave_base_mutex ()
+  {
+    pthread_mutexattr_t attr;
+
+    pthread_mutexattr_init (&attr);
+    pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init (&pm, &attr);
+    pthread_mutexattr_destroy (&attr);
+  }
+
+  ~octave_pthread_mutex (void)
+  {
+    pthread_mutex_destroy (&pm);
+  }
+
+  void lock (void)
+  {
+    pthread_mutex_lock (&pm);
+  }
+
+  void unlock (void)
+  {
+    pthread_mutex_unlock (&pm);
+  }
+
+private:
+  pthread_mutex_t pm;
+};
+
+#endif
+
+octave_mutex::octave_mutex (void)
+{
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+  rep = new octave_w32_mutex ();
+#elif defined (HAVE_PTHREAD_H)
+  rep = new octave_pthread_mutex ();
+#else
+  rep = new octave_base_mutex ();
+#endif
+}
diff --git a/liboctave/oct-mutex.h b/liboctave/oct-mutex.h
new file mode 100644
index 0000000..dcbb535
--- /dev/null
+++ b/liboctave/oct-mutex.h
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 2008 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_mutex_h)
+#define octave_octave_mutex_h 1
+
+class octave_mutex;
+
+class
+octave_base_mutex
+{
+public:
+  friend class octave_mutex;
+
+  octave_base_mutex (void) : count (1) { }
+
+  virtual ~octave_base_mutex (void) { }
+
+  virtual void lock (void);
+
+  virtual void unlock (void);
+
+private:
+  int count;
+};
+
+class
+OCTAVE_API
+octave_mutex
+{
+public:
+  octave_mutex (void);
+
+  octave_mutex (const octave_mutex& m)
+  {
+    rep = m.rep;
+    rep->count++;
+  }
+
+  ~octave_mutex (void)
+  {
+    if (--rep->count == 0)
+      delete rep;
+  }
+
+  octave_mutex& operator = (const octave_mutex& m)
+  {
+    if (rep != m.rep)
+      {
+	if (--rep->count == 0)
+	  delete rep;
+
+	rep = m.rep;
+	rep->count++;
+      }
+
+    return *this;
+  }
+
+  void lock (void)
+  {
+    rep->lock ();
+  }
+
+  void unlock (void)
+  {
+    rep->unlock ();
+  }
+
+protected:
+  octave_base_mutex *rep;
+};
+
+class
+octave_autolock
+{
+public:
+  octave_autolock (const octave_mutex& m)
+    : mutex (m)
+  {
+    mutex.lock ();
+  }
+
+  ~octave_autolock (void)
+  {
+    mutex.unlock ();
+  }
+
+private:
+
+  // No copying or default constructor!
+  octave_autolock (void);
+  octave_autolock (const octave_autolock&);
+  octave_autolock& operator = (const octave_autolock&);
+
+private:
+  octave_mutex mutex;
+};
+
+#endif
diff --git a/liboctave/oct-norm.cc b/liboctave/oct-norm.cc
new file mode 100644
index 0000000..b2cfa31
--- /dev/null
+++ b/liboctave/oct-norm.cc
@@ -0,0 +1,563 @@
+/*
+
+Copyright (C) 2008, 2009 VZLU Prague, a.s.
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// author: Jaroslav Hajek <highegg at gmail.com>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cfloat>
+#include <cmath>
+
+#include <iostream>
+#include <vector>
+
+#include "oct-cmplx.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "Array.h"
+#include "Array-util.h"
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "CColVector.h"
+#include "dColVector.h"
+#include "CRowVector.h"
+#include "dRowVector.h"
+#include "fCColVector.h"
+#include "fColVector.h"
+#include "fCRowVector.h"
+#include "fRowVector.h"
+#include "CSparse.h"
+#include "dSparse.h"
+#include "dbleSVD.h"
+#include "CmplxSVD.h"
+#include "floatSVD.h"
+#include "fCmplxSVD.h"
+
+// Theory: norm accumulator is an object that has an accum method able to handle
+// both real and complex element, and a cast operator returning the intermediate
+// norm.
+
+// norm accumulator for the p-norm
+template <class R>
+class norm_accumulator_p
+{
+  R p,scl,sum;
+public:
+  norm_accumulator_p () {} // we need this one for Array
+  norm_accumulator_p (R pp) : p(pp), scl(0), sum(1) {}
+
+  template<class U> 
+  void accum (U val)
+    {
+      R t = std::abs (val);
+      if (scl == t) // we need this to handle Infs properly
+        sum += 1;
+      else if (scl < t)
+        {
+          sum *= std::pow (scl/t, p);
+          sum += 1;
+          scl = t;
+        }
+      else if (t != 0)
+        sum += std::pow (t/scl, p);
+    }
+  operator R () { return scl * std::pow (sum, 1/p); }
+};
+
+// norm accumulator for the minus p-pseudonorm
+template <class R>
+class norm_accumulator_mp
+{
+  R p,scl,sum;
+public:
+  norm_accumulator_mp () {} // we need this one for Array
+  norm_accumulator_mp (R pp) : p(pp), scl(0), sum(1) {}
+
+  template<class U> 
+  void accum (U val)
+    {
+      R t = 1 / std::abs (val);
+      if (scl == t)
+        sum += 1;
+      else if (scl < t)
+        {
+          sum *= std::pow (scl/t, p);
+          sum += 1;
+          scl = t;
+        }
+      else if (t != 0)
+        sum += std::pow (t/scl, p);
+    }
+  operator R () { return scl * std::pow (sum, -1/p); }
+};
+
+// norm accumulator for the 2-norm (euclidean)
+template <class R>
+class norm_accumulator_2
+{
+  R scl,sum;
+  static R pow2 (R x) { return x*x; }
+public:
+  norm_accumulator_2 () : scl(0), sum(1) {}
+
+  void accum (R val)
+    {
+      R t = std::abs (val);
+      if (scl == t)
+        sum += 1;
+      else if (scl < t)
+        {
+          sum *= pow2 (scl/t);
+          sum += 1;
+          scl = t;
+        }
+      else if (t != 0)
+        sum += pow2 (t/scl);
+    }
+
+  void accum (std::complex<R> val)
+    {
+      accum (val.real ());
+      accum (val.imag ());
+    }
+
+  operator R () { return scl * std::sqrt (sum); }
+};
+
+// norm accumulator for the 1-norm (city metric)
+template <class R>
+class norm_accumulator_1
+{
+  R sum;
+public:
+  norm_accumulator_1 () : sum (0) {}
+  template<class U> 
+  void accum (U val)
+    {
+      sum += std::abs (val); 
+    }
+  operator R () { return sum; }
+};
+
+// norm accumulator for the inf-norm (max metric)
+template <class R>
+class norm_accumulator_inf
+{
+  R max;
+public:
+  norm_accumulator_inf () : max (0) {}
+  template<class U> 
+  void accum (U val)
+    {
+      max = std::max (max, std::abs (val));
+    }
+  operator R () { return max; }
+};
+
+// norm accumulator for the -inf pseudonorm (min abs value)
+template <class R>
+class norm_accumulator_minf
+{
+  R min;
+public:
+  norm_accumulator_minf () : min (octave_Inf) {}
+  template<class U> 
+  void accum (U val)
+    {
+      min = std::min (min, std::abs (val));
+    }
+  operator R () { return min; }
+};
+
+// norm accumulator for the 0-pseudonorm (hamming distance)
+template <class R>
+class norm_accumulator_0
+{
+  unsigned int num;
+public:
+  norm_accumulator_0 () : num (0) {}
+  template<class U> 
+  void accum (U val)
+    {
+      if (val != static_cast<U> (0)) ++num;
+    }
+  operator R () { return num; }
+};
+
+
+// OK, we're armed :) Now let's go for the fun
+
+template <class T, class R, class ACC>
+inline void vector_norm (const Array<T>& v, R& res, ACC acc)
+{
+  for (octave_idx_type i = 0; i < v.numel (); i++)
+    acc.accum (v(i));
+
+  res = acc;
+}
+
+// dense versions
+template <class T, class R, class ACC>
+void column_norms (const MArray2<T>& m, MArray<R>& res, ACC acc)
+{
+  res = MArray2<R> (1, m.columns ());
+  for (octave_idx_type j = 0; j < m.columns (); j++)
+    {
+      ACC accj = acc;
+      for (octave_idx_type i = 0; i < m.rows (); i++)
+        accj.accum (m(i, j));
+
+      res.xelem (j) = accj;
+    }
+}
+
+template <class T, class R, class ACC>
+void row_norms (const MArray2<T>& m, MArray<R>& res, ACC acc)
+{
+  res = MArray2<R> (m.rows (), 1);
+  std::vector<ACC> acci (m.rows (), acc); 
+  for (octave_idx_type j = 0; j < m.columns (); j++)
+    {
+      for (octave_idx_type i = 0; i < m.rows (); i++)
+        acci[i].accum (m(i, j));
+    }
+
+  for (octave_idx_type i = 0; i < m.rows (); i++)
+    res.xelem (i) = acci[i];
+}
+
+// sparse versions
+template <class T, class R, class ACC>
+void column_norms (const MSparse<T>& m, MArray<R>& res, ACC acc)
+{
+  res = MArray2<R> (1, m.columns ());
+  for (octave_idx_type j = 0; j < m.columns (); j++)
+    {
+      ACC accj = acc;
+      for (octave_idx_type k = m.cidx (j); k < m.cidx (j+1); k++)
+        accj.accum (m.data (k));
+
+      res.xelem (j) = accj;
+    }
+}
+
+template <class T, class R, class ACC>
+void row_norms (const MSparse<T>& m, MArray<R>& res, ACC acc)
+{
+  res = MArray2<R> (m.rows (), 1);
+  std::vector<ACC> acci (m.rows (), acc); 
+  for (octave_idx_type j = 0; j < m.columns (); j++)
+    {
+      for (octave_idx_type k = m.cidx (j); k < m.cidx (j+1); k++)
+        acci[m.ridx (k)].accum (m.data (k));
+    }
+
+  for (octave_idx_type i = 0; i < m.rows (); i++)
+    res.xelem (i) = acci[i];
+}
+
+// now the dispatchers
+#define DEFINE_DISPATCHER(FUNC_NAME, ARG_TYPE, RES_TYPE) \
+template <class T, class R> \
+RES_TYPE FUNC_NAME (const ARG_TYPE& v, R p) \
+{ \
+  RES_TYPE res; \
+  if (p == 2) \
+    FUNC_NAME (v, res, norm_accumulator_2<R> ()); \
+  else if (p == 1) \
+    FUNC_NAME (v, res, norm_accumulator_1<R> ()); \
+  else if (lo_ieee_isinf (p)) \
+    { \
+      if (p > 0) \
+        FUNC_NAME (v, res, norm_accumulator_inf<R> ()); \
+      else \
+        FUNC_NAME (v, res, norm_accumulator_minf<R> ()); \
+    } \
+  else if (p == 0) \
+    FUNC_NAME (v, res, norm_accumulator_0<R> ()); \
+  else if (p > 0) \
+    FUNC_NAME (v, res, norm_accumulator_p<R> (p)); \
+  else \
+    FUNC_NAME (v, res, norm_accumulator_mp<R> (p)); \
+  return res; \
+}
+
+DEFINE_DISPATCHER (vector_norm, MArray<T>, R)
+DEFINE_DISPATCHER (vector_norm, MArray2<T>, R)
+DEFINE_DISPATCHER (column_norms, MArray2<T>, MArray<R>)
+DEFINE_DISPATCHER (row_norms, MArray2<T>, MArray<R>)
+DEFINE_DISPATCHER (column_norms, MSparse<T>, MArray<R>)
+DEFINE_DISPATCHER (row_norms, MSparse<T>, MArray<R>)
+
+// The approximate subproblem in Higham's method. Find lambda and mu such that
+// norm ([lambda, mu], p) == 1 and norm (y*lambda + col*mu, p) is maximized.
+// Real version. As in Higham's paper.
+template <class ColVectorT, class R>
+static void 
+higham_subp (const ColVectorT& y, const ColVectorT& col, 
+             octave_idx_type nsamp, R p, R& lambda, R& mu)
+{
+  R nrm = 0;
+  for (octave_idx_type i = 0; i < nsamp; i++)
+    {
+      R fi = i*M_PI/nsamp, lambda1 = cos (fi), mu1 = sin (fi);
+      R lmnr = std::pow (std::pow (std::abs (lambda1), p) + 
+                         std::pow (std::abs (mu1), p), 1/p);
+      lambda1 /= lmnr; mu1 /= lmnr;
+      R nrm1 = vector_norm (lambda1 * y + mu1 * col, p);
+      if (nrm1 > nrm)
+        {
+          lambda = lambda1;
+          mu = mu1;
+          nrm = nrm1;
+        }
+    }
+}
+
+// Complex version. Higham's paper does not deal with complex case, so we use a simple
+// extension. First, guess the magnitudes as in real version, then try to rotate lambda
+// to improve further.
+template <class ColVectorT, class R>
+static void 
+higham_subp (const ColVectorT& y, const ColVectorT& col, 
+             octave_idx_type nsamp, R p, 
+             std::complex<R>& lambda, std::complex<R>& mu)
+{
+  typedef std::complex<R> CR;
+  R nrm = 0;
+  lambda = 1.0;
+  CR lamcu = lambda / std::abs (lambda);
+  // Probe magnitudes
+  for (octave_idx_type i = 0; i < nsamp; i++)
+    {
+      R fi = i*M_PI/nsamp, lambda1 = cos (fi), mu1 = sin (fi);
+      R lmnr = std::pow (std::pow (std::abs (lambda1), p) + 
+                         std::pow (std::abs (mu1), p), 1/p);
+      lambda1 /= lmnr; mu1 /= lmnr;
+      R nrm1 = vector_norm (lambda1 * lamcu * y + mu1 * col, p);
+      if (nrm1 > nrm)
+        {
+          lambda = lambda1 * lamcu;
+          mu = mu1;
+          nrm = nrm1;
+        }
+    }
+  R lama = std::abs (lambda);
+  // Probe orientation
+  for (octave_idx_type i = 0; i < nsamp; i++)
+    {
+      R fi = i*M_PI/nsamp;
+      lamcu = CR (cos (fi), sin (fi));
+      R nrm1 = vector_norm (lama * lamcu * y + mu * col, p);
+      if (nrm1 > nrm)
+        {
+          lambda = lama * lamcu;
+          nrm = nrm1;
+        }
+    }
+}
+
+// the p-dual element (should work for both real and complex)
+template <class T, class R>
+inline T elem_dual_p (T x, R p)
+{
+  return signum (x) * std::pow (std::abs (x), p-1);
+}
+
+// the VectorT is used for vectors, but actually it has to be
+// a Matrix type to allow all the operations. For instance SparseMatrix
+// does not support multiplication with column/row vectors.
+// the dual vector
+template <class VectorT, class R>
+VectorT dual_p (const VectorT& x, R p, R q)
+{
+  VectorT res (x.dims ());
+  for (octave_idx_type i = 0; i < x.numel (); i++)
+    res.xelem (i) = elem_dual_p (x(i), p);
+  return res / vector_norm (res, q);
+}
+
+// Higham's hybrid method
+template <class MatrixT, class VectorT, class R>
+R higham (const MatrixT& m, R p, R tol, int maxiter,
+          VectorT& x)
+{
+  x.resize (m.columns (), 1);
+  // the OSE part
+  VectorT y(m.rows (), 1, 0), z(m.rows (), 1);
+  typedef typename VectorT::element_type RR;
+  RR lambda = 0, mu = 0;
+  for (octave_idx_type k = 0; k < m.columns (); k++)
+    {
+      OCTAVE_QUIT;
+      VectorT col (m.column (k));
+      if (k > 0)
+        higham_subp (y, col, 4*k, p, lambda, mu);
+      for (octave_idx_type i = 0; i < k; i++)
+        x(i) *= lambda;
+      x(k) = mu;
+      y = lambda * y + mu * col;
+    }
+  
+  // the PM part
+  x = x / vector_norm (x, p);
+  R q = p/(p-1);
+
+  R gamma = 0, gamma1;
+  int iter = 0;
+  while (iter < maxiter)
+    {
+      OCTAVE_QUIT;
+      y = m*x;
+      gamma1 = gamma;
+      gamma = vector_norm (y, p);
+      z = dual_p (y, p, q);
+      z = z.hermitian ();
+      z = z * m;
+
+      if (iter > 0 && (vector_norm (z, q) <= gamma
+                       || (gamma - gamma1) <= tol*gamma))
+        break;
+
+      z = z.hermitian ();
+      x = dual_p (z, q, p);
+      iter ++;
+    }
+
+  return gamma;
+}
+
+// derive column vector and SVD types 
+
+static const char *p_less1_gripe = "xnorm: p must be at least 1";
+
+// Static constant to control the maximum number of iterations. 100 seems to be a good value.
+// Eventually, we can provide a means to change this constant from Octave.
+static int max_norm_iter = 100;
+
+// version with SVD for dense matrices
+template <class MatrixT, class VectorT, class SVDT, class R>
+R matrix_norm (const MatrixT& m, R p, VectorT, SVDT)
+{
+  R res = 0;
+  if (p == 2)
+    {
+      SVDT svd (m, SVD::sigma_only);
+      res = svd.singular_values () (0,0);
+    }
+  else if (p == 1)
+    res = xcolnorms (m, 1).max ();
+  else if (lo_ieee_isinf (p))
+    res = xrownorms (m, 1).max ();
+  else if (p > 1)
+    {
+      VectorT x;
+      const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
+      res = higham (m, p, sqrteps, max_norm_iter, x);
+    }
+  else
+    (*current_liboctave_error_handler) (p_less1_gripe); 
+
+  return res;
+}
+
+// SVD-free version for sparse matrices
+template <class MatrixT, class VectorT, class R>
+R matrix_norm (const MatrixT& m, R p, VectorT)
+{
+  R res = 0;
+  if (p == 1)
+    res = xcolnorms (m, 1).max ();
+  else if (lo_ieee_isinf (p))
+    res = xrownorms (m, 1).max ();
+  else if (p > 1)
+    {
+      VectorT x;
+      const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
+      res = higham (m, p, sqrteps, max_norm_iter, x);
+    }
+  else
+    (*current_liboctave_error_handler) (p_less1_gripe); 
+
+  return res;
+}
+
+// and finally, here's what we've promised in the header file
+
+#define DEFINE_XNORM_FUNCS(PREFIX, RTYPE) \
+  OCTAVE_API RTYPE xnorm (const PREFIX##ColumnVector& x, RTYPE p) \
+  { return vector_norm (x, p); } \
+  OCTAVE_API RTYPE xnorm (const PREFIX##RowVector& x, RTYPE p) \
+  { return vector_norm (x, p); } \
+  OCTAVE_API RTYPE xnorm (const PREFIX##Matrix& x, RTYPE p) \
+  { return matrix_norm (x, p, PREFIX##Matrix (), PREFIX##SVD ()); } \
+  OCTAVE_API RTYPE xfrobnorm (const PREFIX##Matrix& x) \
+  { return vector_norm (x, static_cast<RTYPE> (2)); }
+
+DEFINE_XNORM_FUNCS(, double)
+DEFINE_XNORM_FUNCS(Complex, double)
+DEFINE_XNORM_FUNCS(Float, float)
+DEFINE_XNORM_FUNCS(FloatComplex, float)
+
+// this is needed to avoid copying the sparse matrix for xfrobnorm
+template <class T, class R>
+inline void array_norm_2 (const T* v, octave_idx_type n, R& res)
+{
+  norm_accumulator_2<R> acc;
+  for (octave_idx_type i = 0; i < n; i++)
+    acc.accum (v[i]);
+
+  res = acc;
+}
+
+#define DEFINE_XNORM_SPARSE_FUNCS(PREFIX, RTYPE) \
+  OCTAVE_API RTYPE xnorm (const Sparse##PREFIX##Matrix& x, RTYPE p) \
+  { return matrix_norm (x, p, PREFIX##Matrix ()); } \
+  OCTAVE_API RTYPE xfrobnorm (const Sparse##PREFIX##Matrix& x) \
+  { \
+    RTYPE res; \
+    array_norm_2 (x.data (), x.nnz (), res); \
+    return res; \
+  }
+
+DEFINE_XNORM_SPARSE_FUNCS(, double)
+DEFINE_XNORM_SPARSE_FUNCS(Complex, double)
+
+#define DEFINE_COLROW_NORM_FUNCS(PREFIX, RPREFIX, RTYPE) \
+  extern OCTAVE_API RPREFIX##RowVector xcolnorms (const PREFIX##Matrix& m, RTYPE p) \
+  { return column_norms (m, p); } \
+  extern OCTAVE_API RPREFIX##ColumnVector xrownorms (const PREFIX##Matrix& m, RTYPE p) \
+  { return row_norms (m, p); } \
+
+DEFINE_COLROW_NORM_FUNCS(, , double)
+DEFINE_COLROW_NORM_FUNCS(Complex, , double)
+DEFINE_COLROW_NORM_FUNCS(Float, Float, float)
+DEFINE_COLROW_NORM_FUNCS(FloatComplex, Float, float)
+
+DEFINE_COLROW_NORM_FUNCS(Sparse, , double)
+DEFINE_COLROW_NORM_FUNCS(SparseComplex, , double)
+
diff --git a/liboctave/oct-norm.h b/liboctave/oct-norm.h
new file mode 100644
index 0000000..558602d
--- /dev/null
+++ b/liboctave/oct-norm.h
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 2008 VZLU Prague, a.s.
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// author: Jaroslav Hajek <highegg at gmail.com>
+
+#if !defined (octave_xnorm_h)
+#define octave_xnorm_h 1
+
+#include "oct-cmplx.h"
+
+#define DECLARE_XNORM_FUNCS(PREFIX, RTYPE) \
+  class PREFIX##Matrix; \
+  class PREFIX##ColumnVector; \
+  class PREFIX##RowVector; \
+  \
+  extern OCTAVE_API RTYPE xnorm (const PREFIX##ColumnVector&, RTYPE p = 2); \
+  extern OCTAVE_API RTYPE xnorm (const PREFIX##RowVector&, RTYPE p = 2); \
+  extern OCTAVE_API RTYPE xnorm (const PREFIX##Matrix&, RTYPE p = 2); \
+  extern OCTAVE_API RTYPE xfrobnorm (const PREFIX##Matrix&); 
+
+DECLARE_XNORM_FUNCS(, double)
+DECLARE_XNORM_FUNCS(Complex, double)
+DECLARE_XNORM_FUNCS(Float, float)
+DECLARE_XNORM_FUNCS(FloatComplex, float)
+
+DECLARE_XNORM_FUNCS(Sparse, double)
+DECLARE_XNORM_FUNCS(SparseComplex, double)
+
+#define DECLARE_COLROW_NORM_FUNCS(PREFIX, RPREFIX, RTYPE) \
+  extern OCTAVE_API RPREFIX##RowVector xcolnorms (const PREFIX##Matrix&, RTYPE p = 2); \
+  extern OCTAVE_API RPREFIX##ColumnVector xrownorms (const PREFIX##Matrix&, RTYPE p = 2); \
+
+DECLARE_COLROW_NORM_FUNCS(, , double)
+DECLARE_COLROW_NORM_FUNCS(Complex, , double)
+DECLARE_COLROW_NORM_FUNCS(Float, Float, float)
+DECLARE_COLROW_NORM_FUNCS(FloatComplex, Float, float)
+
+DECLARE_COLROW_NORM_FUNCS(Sparse, , double)
+DECLARE_COLROW_NORM_FUNCS(SparseComplex, , double)
+
+#endif
diff --git a/liboctave/oct-passwd.cc b/liboctave/oct-passwd.cc
new file mode 100644
index 0000000..a3a3010
--- /dev/null
+++ b/liboctave/oct-passwd.cc
@@ -0,0 +1,237 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include "lo-error.h"
+#include "oct-passwd.h"
+
+#define NOT_SUPPORTED(nm) \
+  nm ": not supported on this system"
+
+std::string
+octave_passwd::name (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_name;
+}
+
+std::string
+octave_passwd::passwd (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_passwd;
+}
+
+uid_t
+octave_passwd::uid (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_uid;
+}
+
+gid_t
+octave_passwd::gid (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_gid;
+}
+
+std::string
+octave_passwd::gecos (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_gecos;
+}
+
+std::string
+octave_passwd::dir (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_dir;
+}
+
+std::string
+octave_passwd::shell (void) const
+{
+  if (! ok ())
+    gripe_invalid ();
+
+  return pw_shell;
+}
+
+octave_passwd
+octave_passwd::getpwent (void)
+{
+  std::string msg;
+  return getpwent (msg);
+}
+
+octave_passwd
+octave_passwd::getpwent (std::string& msg)
+{
+#if defined HAVE_GETPWENT
+  msg = std::string ();
+  return octave_passwd (::getpwent (), msg);
+#else
+  msg = NOT_SUPPORTED ("getpwent");
+  return octave_passwd ();
+#endif
+}
+
+octave_passwd
+octave_passwd::getpwuid (uid_t uid)
+{
+  std::string msg;
+  return getpwuid (uid, msg);
+}
+
+octave_passwd
+octave_passwd::getpwuid (uid_t uid, std::string& msg)
+{
+#if defined (HAVE_GETPWUID)
+  msg = std::string ();
+  return octave_passwd (::getpwuid (uid), msg);
+#else
+  msg = NOT_SUPPORTED ("getpwuid");
+  return octave_passwd ();
+#endif
+}
+
+octave_passwd
+octave_passwd::getpwnam (const std::string& nm)
+{
+  std::string msg;
+  return getpwnam (nm, msg);
+}
+
+octave_passwd
+octave_passwd::getpwnam (const std::string& nm, std::string& msg)
+{
+#if defined (HAVE_GETPWNAM)
+  msg = std::string ();
+  return octave_passwd (::getpwnam (nm.c_str ()), msg);
+#else
+  msg = NOT_SUPPORTED ("getpwnam");
+  return octave_passwd ();
+#endif
+}
+
+int
+octave_passwd::setpwent (void)
+{
+  std::string msg;
+  return setpwent (msg);
+}
+
+int
+octave_passwd::setpwent (std::string& msg)
+{
+#if defined (HAVE_SETPWENT)
+  msg = std::string ();
+  ::setpwent ();
+  return 0;
+#else
+  msg = NOT_SUPPORTED ("setpwent");
+  return -1;
+#endif
+}
+
+int
+octave_passwd::endpwent (void)
+{
+  std::string msg;
+  return endpwent (msg);
+}
+
+int
+octave_passwd::endpwent (std::string& msg)
+{
+#if defined (HAVE_ENDPWENT)
+  msg = std::string ();
+  ::endpwent ();
+  return 0;
+#else
+  msg = NOT_SUPPORTED ("endpwent");
+  return -1;
+#endif
+}
+
+octave_passwd::octave_passwd (void *p, std::string& msg)
+  : pw_name (), pw_passwd (), pw_uid (0), pw_gid (0), pw_gecos (),
+    pw_dir (), pw_shell (), valid (false)
+{
+#if defined (HAVE_PWD_H)
+  msg = std::string ();
+
+  if (p)
+    {
+      struct passwd *pw = static_cast<struct passwd *> (p);
+
+      pw_name = pw->pw_name;
+      pw_passwd = pw->pw_passwd;
+      pw_uid = pw->pw_uid;
+      pw_gid = pw->pw_gid;
+      pw_gecos = pw->pw_gecos;
+      pw_dir = pw->pw_dir;
+      pw_shell = pw->pw_shell;
+
+      valid = true;
+    }
+#else
+  msg = NOT_SUPPORTED ("password functions");
+#endif
+}
+
+void
+octave_passwd::gripe_invalid (void) const
+{
+  (*current_liboctave_error_handler) ("invalid password object");
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-passwd.h b/liboctave/oct-passwd.h
new file mode 100644
index 0000000..88d8755
--- /dev/null
+++ b/liboctave/oct-passwd.h
@@ -0,0 +1,140 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_passwd_h)
+#define octave_passwd_h 1
+
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+class
+OCTAVE_API
+octave_passwd
+{
+public:
+
+  octave_passwd (void)
+    : pw_name (), pw_passwd (), pw_uid (0), pw_gid (0), pw_gecos (),
+      pw_dir (), pw_shell (), valid (false)
+  { }
+
+  octave_passwd (const octave_passwd& pw)
+    : pw_name (pw.pw_name), pw_passwd (pw.pw_passwd),
+      pw_uid (pw.pw_uid), pw_gid (pw.pw_gid), pw_gecos (pw.pw_gecos),
+      pw_dir (pw.pw_dir), pw_shell (pw.pw_shell), valid (pw.valid)
+  { }
+
+  octave_passwd& operator = (const octave_passwd& pw)
+  {
+    if (this != &pw)
+      {
+	pw_name = pw.pw_name;
+	pw_passwd = pw.pw_passwd;
+	pw_uid = pw.pw_uid;
+	pw_gid = pw.pw_gid;
+	pw_gecos = pw.pw_gecos;
+	pw_dir = pw.pw_dir;
+	pw_shell = pw.pw_shell;
+	valid = pw.valid;
+      }
+
+    return *this;
+  }
+
+  ~octave_passwd (void) { }
+
+  std::string name (void) const;
+
+  std::string passwd (void) const;
+
+  uid_t uid (void) const;
+
+  gid_t gid (void) const;
+
+  std::string gecos (void) const;
+
+  std::string dir (void) const;
+
+  std::string shell (void) const;
+
+  bool ok (void) const { return valid; }
+
+  operator bool () const { return ok (); }
+
+  static octave_passwd getpwent (void);
+  static octave_passwd getpwent (std::string& msg);
+
+  static octave_passwd getpwuid (uid_t uid);
+  static octave_passwd getpwuid (uid_t uid, std::string& msg);
+
+  static octave_passwd getpwnam (const std::string& nm);
+  static octave_passwd getpwnam (const std::string& nm, std::string& msg);
+
+  static int setpwent (void);
+  static int setpwent (std::string& msg);
+
+  static int endpwent (void);
+  static int endpwent (std::string& msg);
+
+private:
+
+  // User name.
+  std::string pw_name;
+
+  // Encrypted password.
+  std::string pw_passwd;
+
+  // Numeric user id.
+  uid_t pw_uid;
+
+  // Numeric group id.
+  gid_t pw_gid;
+
+  // Miscellaneous junk.
+  std::string pw_gecos;
+
+  // Home directory.
+  std::string pw_dir;
+
+  // Login shell.
+  std::string pw_shell;
+
+  // Flag that says whether we have been properly initialized.
+  bool valid;
+
+  // This is how we will create an octave_passwd object from a pointer
+  // to a struct passwd.
+  octave_passwd (void *p, std::string& msg);
+
+  void gripe_invalid (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-rand.cc b/liboctave/oct-rand.cc
new file mode 100644
index 0000000..b384235
--- /dev/null
+++ b/liboctave/oct-rand.cc
@@ -0,0 +1,665 @@
+/*
+
+Copyright (C) 2003, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <map>
+#include <vector>
+
+#include "f77-fcn.h"
+#include "lo-ieee.h"
+#include "lo-error.h"
+#include "lo-mappers.h"
+#include "oct-rand.h"
+#include "oct-time.h"
+#include "data-conv.h"
+#include "randmtzig.h"
+#include "randpoisson.h"
+#include "randgamma.h"
+#include "mach-info.h"
+#include "oct-locbuf.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dgennor, DGENNOR) (const double&, const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (dgenunf, DGENUNF) (const double&, const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (dgenexp, DGENEXP) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (dignpoi, DIGNPOI) (const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (dgengam, DGENGAM) (const double&, const double&, double&);
+
+  F77_RET_T
+  F77_FUNC (setall, SETALL) (const octave_idx_type&, const octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (getsd, GETSD) (octave_idx_type&, octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (setsd, SETSD) (const octave_idx_type&, const octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (setcgn, SETCGN) (const octave_idx_type&);
+}
+
+octave_rand *octave_rand::instance = 0;
+
+octave_rand::octave_rand (void)
+  : current_distribution (uniform_dist), use_old_generators (false),
+    rand_states ()
+{
+  initialize_ranlib_generators ();
+
+  initialize_mersenne_twister ();
+}
+
+bool
+octave_rand::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_rand ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create octave_rand object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+double
+octave_rand::do_seed (void)
+{
+  union d2i { double d; octave_idx_type i[2]; };
+  union d2i u;
+    
+  oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
+
+  switch (ff)
+    {
+    case oct_mach_info::flt_fmt_ieee_big_endian:
+      F77_FUNC (getsd, GETSD) (u.i[1], u.i[0]);
+      break;
+    default:
+      F77_FUNC (getsd, GETSD) (u.i[0], u.i[1]);
+      break;
+    }
+
+  return u.d;
+}
+
+static octave_idx_type
+force_to_fit_range (octave_idx_type i, octave_idx_type lo, octave_idx_type hi)
+{
+  assert (hi > lo && lo >= 0 && hi > lo);
+
+  i = i > 0 ? i : -i;
+
+  if (i < lo)
+    i = lo;
+  else if (i > hi)
+    i = i % hi;
+
+  return i;
+}
+
+void
+octave_rand::do_seed (double s)
+{
+  use_old_generators = true;
+
+  int i0, i1;
+  union d2i { double d; octave_idx_type i[2]; };
+  union d2i u;
+  u.d = s;
+
+  oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
+
+  switch (ff)
+    {
+    case oct_mach_info::flt_fmt_ieee_big_endian:
+      i1 = force_to_fit_range (u.i[0], 1, 2147483563);
+      i0 = force_to_fit_range (u.i[1], 1, 2147483399);
+      break;
+    default:
+      i0 = force_to_fit_range (u.i[0], 1, 2147483563);
+      i1 = force_to_fit_range (u.i[1], 1, 2147483399);
+      break;
+    }
+
+  F77_FUNC (setsd, SETSD) (i0, i1);
+}
+
+ColumnVector
+octave_rand::do_state (const std::string& d)
+{
+  return rand_states[d.empty () ? current_distribution : get_dist_id (d)];
+}
+
+void
+octave_rand::do_state (const ColumnVector& s, const std::string& d)
+{
+  use_old_generators = false;
+
+  int old_dist = current_distribution;
+
+  int new_dist = d.empty () ? current_distribution : get_dist_id (d);
+
+  ColumnVector saved_state;
+
+  if (old_dist != new_dist)
+    saved_state = get_internal_state ();
+
+  set_internal_state (s);
+
+  rand_states[new_dist] = get_internal_state ();
+
+  if (old_dist != new_dist)
+    rand_states[old_dist] = saved_state;
+}
+
+std::string
+octave_rand::do_distribution (void)
+{
+  std::string retval;
+
+  switch (current_distribution)
+    {
+    case uniform_dist:
+      retval = "uniform";
+      break;
+
+    case normal_dist:
+      retval = "normal";
+      break;
+
+    case expon_dist:
+      retval = "exponential";
+      break;
+
+    case poisson_dist:
+      retval = "poisson";
+      break;
+
+    case gamma_dist:
+      retval = "gamma";
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("rand: invalid distribution ID = %d", current_distribution);
+      break;
+    }
+
+  return retval;
+}
+
+void
+octave_rand::do_distribution (const std::string& d)
+{
+  int id = get_dist_id (d);
+
+  switch (id)
+    {
+    case uniform_dist:
+      octave_rand::uniform_distribution ();
+      break;
+
+    case normal_dist:
+      octave_rand::normal_distribution ();
+      break;
+
+    case expon_dist:
+      octave_rand::exponential_distribution ();
+      break;
+
+    case poisson_dist:
+      octave_rand::poisson_distribution ();
+      break;
+
+    case gamma_dist:
+      octave_rand::gamma_distribution ();
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("rand: invalid distribution ID = %d", id);
+      break;
+    }
+}
+
+void
+octave_rand::do_uniform_distribution (void)
+{
+  switch_to_generator (uniform_dist);
+
+  F77_FUNC (setcgn, SETCGN) (uniform_dist);
+}
+
+void
+octave_rand::do_normal_distribution (void)
+{
+  switch_to_generator (normal_dist);
+
+  F77_FUNC (setcgn, SETCGN) (normal_dist);
+}
+
+void
+octave_rand::do_exponential_distribution (void)
+{
+  switch_to_generator (expon_dist);
+
+  F77_FUNC (setcgn, SETCGN) (expon_dist);
+}
+
+void
+octave_rand::do_poisson_distribution (void)
+{
+  switch_to_generator (poisson_dist);
+
+  F77_FUNC (setcgn, SETCGN) (poisson_dist);
+}
+
+void
+octave_rand::do_gamma_distribution (void)
+{
+  switch_to_generator (gamma_dist);
+
+  F77_FUNC (setcgn, SETCGN) (gamma_dist);
+}
+
+
+double
+octave_rand::do_scalar (double a)
+{
+  double retval = 0.0;
+
+  if (use_old_generators)
+    {
+      switch (current_distribution)
+	{
+	case uniform_dist:
+	  F77_FUNC (dgenunf, DGENUNF) (0.0, 1.0, retval);
+	  break;
+
+	case normal_dist:
+	  F77_FUNC (dgennor, DGENNOR) (0.0, 1.0, retval);
+	  break;
+
+	case expon_dist:
+	  F77_FUNC (dgenexp, DGENEXP) (1.0, retval);
+	  break;
+
+	case poisson_dist:
+	  if (a < 0.0 || xisnan(a) || xisinf(a))
+	    retval = octave_NaN;
+	  else
+	    {
+	      // workaround bug in ignpoi, by calling with different Mu
+	      F77_FUNC (dignpoi, DIGNPOI) (a + 1, retval);
+	      F77_FUNC (dignpoi, DIGNPOI) (a, retval);
+	    }
+	  break;
+
+	case gamma_dist:
+	  if (a <= 0.0 || xisnan(a) || xisinf(a))
+	    retval = octave_NaN;
+	  else
+	    F77_FUNC (dgengam, DGENGAM) (1.0, a, retval);
+	  break;
+
+	default:
+	  (*current_liboctave_error_handler) 
+	    ("rand: invalid distribution ID = %d", current_distribution);
+	  break;
+	}
+    }
+  else
+    {
+      switch (current_distribution)
+	{
+	case uniform_dist:
+	  retval = oct_randu ();
+	  break;
+
+	case normal_dist:
+	  retval = oct_randn ();
+	  break;
+
+	case expon_dist:
+	  retval = oct_rande ();
+	  break;
+
+	case poisson_dist:
+	  retval = oct_randp (a);
+	  break;
+
+	case gamma_dist:
+	  retval = oct_randg (a);
+	  break;
+
+	default:
+	  (*current_liboctave_error_handler)
+	    ("rand: invalid distribution ID = %d", current_distribution);
+	  break;
+	}
+
+      save_state ();
+    }
+
+  return retval;
+}
+
+Matrix
+octave_rand::do_matrix (octave_idx_type n, octave_idx_type m, double a)
+{
+  Matrix retval;
+
+  if (n >= 0 && m >= 0)
+    {
+      retval.resize (n, m);
+
+      if (n > 0 && m > 0)
+	fill (retval.capacity(), retval.fortran_vec(), a);
+    }
+  else
+    (*current_liboctave_error_handler) ("rand: invalid negative argument");
+
+  return retval;
+}
+
+NDArray
+octave_rand::do_nd_array (const dim_vector& dims, double a)
+{
+  NDArray retval;
+
+  if (! dims.all_zero ())
+    {
+      retval.resize (dims);
+
+      fill (retval.capacity(), retval.fortran_vec(), a);
+    }
+
+  return retval;
+}
+
+Array<double>
+octave_rand::do_vector (octave_idx_type n, double a)
+{
+  Array<double> retval;
+
+  if (n > 0)
+    {
+      retval.resize (n);
+
+      fill (retval.capacity (), retval.fortran_vec (), a);
+    }
+  else if (n < 0)
+    (*current_liboctave_error_handler) ("rand: invalid negative argument");
+
+  return retval;
+}
+
+// Make the random number generator give us a different sequence every
+// time we start octave unless we specifically set the seed.  The
+// technique used below will cycle monthly, but it it does seem to
+// work ok to give fairly different seeds each time Octave starts.
+
+void
+octave_rand::initialize_ranlib_generators (void)
+{
+  octave_localtime tm;
+  int stored_distribution = current_distribution;
+  F77_FUNC (setcgn, SETCGN) (uniform_dist);
+
+  int hour = tm.hour() + 1;
+  int minute = tm.min() + 1;
+  int second = tm.sec() + 1;
+
+  octave_idx_type s0 = tm.mday() * hour * minute * second;
+  octave_idx_type s1 = hour * minute * second;
+
+  s0 = force_to_fit_range (s0, 1, 2147483563);
+  s1 = force_to_fit_range (s1, 1, 2147483399);
+
+  F77_FUNC (setall, SETALL) (s0, s1);
+  F77_FUNC (setcgn, SETCGN) (stored_distribution);
+}
+
+void
+octave_rand::initialize_mersenne_twister (void)
+{
+  oct_init_by_entropy ();
+
+  ColumnVector s = get_internal_state ();
+
+  rand_states[uniform_dist] = s;
+
+  oct_init_by_entropy ();
+  s = get_internal_state ();
+  rand_states[normal_dist] = s;
+
+  oct_init_by_entropy ();
+  s = get_internal_state ();
+  rand_states[expon_dist] = s;
+
+  oct_init_by_entropy ();
+  s = get_internal_state ();
+  rand_states[poisson_dist] = s;
+
+  oct_init_by_entropy ();
+  s = get_internal_state ();
+  rand_states[gamma_dist] = s;
+}
+
+ColumnVector
+octave_rand::get_internal_state (void)
+{
+  ColumnVector s (MT_N + 1);
+
+  OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1);
+
+  oct_get_state (tmp);
+
+  for (octave_idx_type i = 0; i <= MT_N; i++)
+    s.elem (i) = static_cast<double> (tmp [i]);
+
+  return s;
+}
+
+void
+octave_rand::save_state (void)
+{
+  rand_states[current_distribution] = get_internal_state ();;
+}
+
+int
+octave_rand::get_dist_id (const std::string& d)
+{
+  int retval = unknown_dist;
+
+  if (d == "uniform" || d == "rand")
+    retval = uniform_dist;
+  else if (d == "normal" || d == "randn")
+    retval = normal_dist;
+  else if (d == "exponential" || d == "rande")
+    retval = expon_dist;
+  else if (d == "poisson" || d == "randp")
+    retval = poisson_dist;
+  else if (d == "gamma" || d == "randg")
+    retval = gamma_dist;
+  else
+    (*current_liboctave_error_handler)
+      ("rand: invalid distribution `%s'", d.c_str ());
+
+  return retval;
+}
+
+void
+octave_rand::set_internal_state (const ColumnVector& s)
+{
+  octave_idx_type len = s.length ();
+  octave_idx_type n = len < MT_N + 1 ? len : MT_N + 1;
+
+  OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    tmp[i] = static_cast<uint32_t> (s.elem(i));
+
+  if (len == MT_N + 1 && tmp[MT_N] <= MT_N && tmp[MT_N] > 0)
+    oct_set_state (tmp);
+  else
+    oct_init_by_array (tmp, len);
+}
+
+void
+octave_rand::switch_to_generator (int dist)
+{
+  if (dist != current_distribution)
+    {
+      current_distribution = dist;
+
+      set_internal_state (rand_states[dist]);
+    }
+}
+
+#define MAKE_RAND(len) \
+  do \
+    { \
+      double val; \
+      for (volatile octave_idx_type i = 0; i < len; i++) \
+	{ \
+	  OCTAVE_QUIT; \
+	  RAND_FUNC (val); \
+	  v[i] = val; \
+	} \
+    } \
+  while (0)
+
+void
+octave_rand::fill (octave_idx_type len, double *v, double a)
+{
+  if (len < 1)
+    return;
+
+  switch (current_distribution)
+    {
+    case uniform_dist:
+      if (use_old_generators)
+	{
+#define RAND_FUNC(x) F77_FUNC (dgenunf, DGENUNF) (0.0, 1.0, x)
+	  MAKE_RAND (len);
+#undef RAND_FUNC
+	}
+      else
+	oct_fill_randu (len, v);
+      break;
+
+    case normal_dist:
+      if (use_old_generators)
+	{
+#define RAND_FUNC(x) F77_FUNC (dgennor, DGENNOR) (0.0, 1.0, x)
+	  MAKE_RAND (len);
+#undef RAND_FUNC
+	}
+      else
+	oct_fill_randn (len, v);
+      break;
+
+    case expon_dist:
+      if (use_old_generators)
+	{
+#define RAND_FUNC(x) F77_FUNC (dgenexp, DGENEXP) (1.0, x)
+	  MAKE_RAND (len);
+#undef RAND_FUNC
+	}
+      else
+	oct_fill_rande (len, v);
+      break;
+
+    case poisson_dist:
+      if (use_old_generators)
+	{
+	  if (a < 0.0 || xisnan(a) || xisinf(a))
+#define RAND_FUNC(x) x = octave_NaN;
+	    MAKE_RAND (len);
+#undef RAND_FUNC
+	  else
+	    {
+	      // workaround bug in ignpoi, by calling with different Mu
+	      double tmp;
+	      F77_FUNC (dignpoi, DIGNPOI) (a + 1, tmp);
+#define RAND_FUNC(x) F77_FUNC (dignpoi, DIGNPOI) (a, x)
+		MAKE_RAND (len);
+#undef RAND_FUNC
+	    }
+	}
+      else
+	oct_fill_randp (a, len, v);
+      break;
+
+    case gamma_dist:
+      if (use_old_generators)
+	{
+	  if (a <= 0.0 || xisnan(a) || xisinf(a))
+#define RAND_FUNC(x) x = octave_NaN;
+	    MAKE_RAND (len);
+#undef RAND_FUNC
+	  else
+#define RAND_FUNC(x) F77_FUNC (dgengam, DGENGAM) (1.0, a, x)
+	    MAKE_RAND (len);
+#undef RAND_FUNC
+	}
+      else
+	oct_fill_randg (a, len, v);
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("rand: invalid distribution ID = %d", current_distribution);
+      break;
+    }
+
+  save_state ();
+
+  return;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-rand.h b/liboctave/oct-rand.h
new file mode 100644
index 0000000..9197e58
--- /dev/null
+++ b/liboctave/oct-rand.h
@@ -0,0 +1,237 @@
+/*
+
+Copyright (C) 2003, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_rand_h)
+#define octave_rand_h 1
+
+#include <map>
+#include <string>
+
+#include "dColVector.h"
+#include "dMatrix.h"
+#include "dNDArray.h"
+#include "lo-ieee.h"
+
+class
+OCTAVE_API
+octave_rand
+{
+protected:
+
+  octave_rand (void);
+
+public:
+
+  ~octave_rand (void) { }
+
+  static bool instance_ok (void);
+
+  // Return the current seed.
+  static double seed (void)
+  {
+    return instance_ok () ? instance->do_seed () : octave_NaN;
+  }
+
+  // Set the seed.
+  static void seed (double s)
+  {
+    if (instance_ok ())
+      instance->do_seed (s);
+  }
+
+  // Return the current state.
+  static ColumnVector state (const std::string& d = std::string ())
+  {
+    return instance_ok () ? instance->do_state (d) : ColumnVector ();
+  }
+
+  // Set the current state/
+  static void state (const ColumnVector &s,
+		     const std::string& d = std::string ())
+  {
+    if (instance_ok ())
+      instance->do_state (s, d);
+  }
+  
+  // Return the current distribution.
+  static std::string distribution (void)
+  {
+    return instance_ok () ? instance->do_distribution () : std::string ();
+  }
+
+  // Set the current distribution.  May be either "uniform" (the
+  // default), "normal", "exponential", "poisson", or "gamma".
+  static void distribution (const std::string& d)
+  {
+    if (instance_ok ())
+      instance->do_distribution (d);
+  }
+
+  static void uniform_distribution (void)
+  {
+    if (instance_ok ())
+      instance->do_uniform_distribution ();
+  }
+
+  static void normal_distribution (void)
+  {
+    if (instance_ok ())
+      instance->do_normal_distribution ();
+  }
+
+  static void exponential_distribution (void)
+  {
+    if (instance_ok ())
+      instance->do_exponential_distribution ();
+  }
+
+  static void poisson_distribution (void)
+  {
+    if (instance_ok ())
+      instance->do_poisson_distribution ();
+  }
+
+  static void gamma_distribution (void)
+  {
+    if (instance_ok ())
+      instance->do_gamma_distribution ();
+  }
+
+  // Return the next number from the sequence.
+  static double scalar (double a = 1.0)
+  {
+    return instance_ok () ? instance->do_scalar (a) : octave_NaN;
+  }
+
+  // Return a matrix of numbers from the sequence, filled in column
+  // major order.
+  static Matrix matrix (octave_idx_type r, octave_idx_type c, double a = 1.0)
+  {
+    return instance_ok () ? instance->do_matrix (r, c, a) : Matrix ();
+  }
+
+  // Return an N-dimensional array of numbers from the sequence,
+  // filled in column major order.
+  static NDArray nd_array (const dim_vector& dims, double a = 1.0)
+  {
+    return instance_ok () ? instance->do_nd_array (dims, a) : NDArray ();
+  }
+
+  // Return an array of numbers from the sequence.
+  static Array<double> vector (octave_idx_type n, double a = 1.0)
+  {
+    return instance_ok () ? instance->do_vector (n, a) : Array<double> ();
+  }
+
+private:
+
+  static octave_rand *instance;
+
+  enum
+  {
+    unknown_dist,
+    uniform_dist,
+    normal_dist,
+    expon_dist,
+    poisson_dist,
+    gamma_dist
+  };
+
+  // Current distribution of random numbers.
+  int current_distribution;
+
+  // If TRUE, use old RANLIB generators.  Otherwise, use Mersenne
+  // Twister generator.
+  bool use_old_generators;
+
+  // Saved MT states.
+  std::map<int, ColumnVector> rand_states;
+
+  // Return the current seed.
+  double do_seed (void);
+
+  // Set the seed.
+  void do_seed (double s);
+
+  // Return the current state.
+  ColumnVector do_state (const std::string& d);
+
+  // Set the current state/
+  void do_state (const ColumnVector &s, const std::string& d);
+  
+  // Return the current distribution.
+  std::string do_distribution (void);
+
+  // Set the current distribution.  May be either "uniform" (the
+  // default), "normal", "exponential", "poisson", or "gamma".
+  void do_distribution (const std::string& d);
+
+  void do_uniform_distribution (void);
+
+  void do_normal_distribution (void);
+
+  void do_exponential_distribution (void);
+
+  void do_poisson_distribution (void);
+
+  void do_gamma_distribution (void);
+
+  // Return the next number from the sequence.
+  double do_scalar (double a = 1.);
+
+  // Return a matrix of numbers from the sequence, filled in column
+  // major order.
+  Matrix do_matrix (octave_idx_type r, octave_idx_type c, double a = 1.);
+
+  // Return an N-dimensional array of numbers from the sequence,
+  // filled in column major order.
+  NDArray do_nd_array (const dim_vector& dims, double a = 1.);
+
+  // Return an array of numbers from the sequence.
+  Array<double> do_vector (octave_idx_type n, double a = 1.);
+
+  // Some helper functions.
+
+  void initialize_ranlib_generators (void);
+
+  void initialize_mersenne_twister (void);
+
+  ColumnVector get_internal_state (void);
+
+  void save_state (void);
+
+  int get_dist_id (const std::string& d);
+
+  void set_internal_state (const ColumnVector& s);
+
+  void switch_to_generator (int dist);
+
+  void fill (octave_idx_type len, double *v, double a);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-rl-edit.c b/liboctave/oct-rl-edit.c
new file mode 100644
index 0000000..003cee6
--- /dev/null
+++ b/liboctave/oct-rl-edit.c
@@ -0,0 +1,388 @@
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (USE_READLINE)
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <readline/readline.h>
+
+#include "oct-rl-edit.h"
+
+#define OCTAVE_RL_SAVE_STRING(ss, s) \
+  static char *ss = 0; \
+ \
+  if (ss) \
+    { \
+      free (ss); \
+      ss = 0; \
+    } \
+ \
+  ss = malloc (strlen (s) + 1); \
+ \
+  strcpy (ss, s)
+
+void
+octave_rl_redisplay (void)
+{
+  rl_redisplay ();
+}
+
+int
+octave_rl_screen_height (void)
+{
+  int rows, cols;
+  rl_get_screen_size (&rows, &cols);
+  return rows;
+}
+
+int
+octave_rl_screen_width (void)
+{
+  int rows, cols;
+  rl_get_screen_size (&rows, &cols);
+  return cols;
+}
+
+void
+octave_rl_enable_paren_matching (int val)
+{
+  rl_variable_bind ("blink-matching-paren", val ? "1" : "0");
+}
+
+/* It would be much simpler if we could just call _rl_clear_screen to
+   only clear the screen, but it is not a public function, and on some
+   systems, it is not exported from shared library versions of
+   readline, so we can't use it.
+
+   Instead, temporarily redefine the redisplay function to do nothing.
+
+   FIXME -- It would be safer to do this when protected from
+   interrupts... */
+
+static void
+flush_stdout (void)
+{
+  fflush (stdout);
+}
+
+void
+octave_rl_clear_screen (void)
+{
+  int ignore1 = 0;
+  int ignore2 = 0;
+
+  rl_voidfunc_t *saved_redisplay_function = rl_redisplay_function;
+  rl_redisplay_function = flush_stdout;
+
+  rl_clear_screen (ignore1, ignore2);
+
+  rl_redisplay_function = saved_redisplay_function;
+}
+
+void
+octave_rl_resize_terminal (void)
+{
+  rl_resize_terminal ();
+}
+
+void
+octave_rl_restore_terminal_state ()
+{
+  if (rl_deprep_term_function)
+    rl_deprep_term_function ();
+}
+
+void
+octave_rl_insert_text (const char *s)
+{
+  rl_insert_text (s);
+}
+
+int
+octave_rl_newline (int count, int key)
+{
+  return rl_newline (count, key);
+}
+
+const char *
+octave_rl_line_buffer (void)
+{
+  return rl_line_buffer;
+}
+
+void
+octave_rl_clear_undo_list (void)
+{
+  if (rl_undo_list)
+    {
+      rl_free_undo_list ();
+
+      rl_undo_list = 0;
+    }
+}
+
+void
+octave_rl_set_name (const char *n)
+{
+  OCTAVE_RL_SAVE_STRING (nm, n);
+
+  rl_readline_name = nm;
+
+  /* Since we've already called rl_initialize, we need to re-read the
+     init file to take advantage of the conditional parsing feature
+     based on rl_readline_name; */
+
+  rl_re_read_init_file (0, 0);
+}
+
+char *
+octave_rl_readline (const char *prompt)
+{
+  return readline (prompt);
+}
+
+void
+octave_rl_set_input_stream (FILE *f)
+{
+  rl_instream = f;
+}
+
+FILE *
+octave_rl_get_input_stream (void)
+{
+  return rl_instream;
+}
+
+void
+octave_rl_set_output_stream (FILE *f)
+{
+  rl_outstream = f;
+}
+
+FILE *
+octave_rl_get_output_stream (void)
+{
+  return rl_outstream;
+}
+
+void
+octave_rl_read_init_file (const char *f)
+{
+  rl_read_init_file (f);
+}
+
+void
+octave_rl_re_read_init_file (void)
+{
+  rl_re_read_init_file (0, 0);
+}
+
+int
+octave_rl_filename_completion_desired (int arg)
+{
+  int retval = rl_filename_completion_desired;
+  rl_filename_completion_desired = arg;
+  return retval;
+}
+
+int
+octave_rl_filename_quoting_desired (int arg)
+{
+  int retval = rl_filename_quoting_desired;
+  rl_filename_quoting_desired = arg;
+  return retval;
+}
+
+char *
+octave_rl_filename_completion_function (const char *text, int state)
+{
+  return rl_filename_completion_function (text, state);
+}
+
+void
+octave_rl_set_basic_word_break_characters (const char *s)
+{
+  OCTAVE_RL_SAVE_STRING (ss, s);
+
+  rl_basic_word_break_characters = ss;
+}
+
+void
+octave_rl_set_completer_word_break_characters (const char *s)
+{
+  OCTAVE_RL_SAVE_STRING (ss, s);
+
+  rl_completer_word_break_characters = ss;
+}
+
+void
+octave_rl_set_basic_quote_characters (const char *s)
+{
+  OCTAVE_RL_SAVE_STRING (ss, s);
+
+  rl_basic_quote_characters = ss;
+}
+
+void
+octave_rl_set_filename_quote_characters (const char *s)
+{
+  OCTAVE_RL_SAVE_STRING (ss, s);
+
+  rl_filename_quote_characters = ss;
+}
+
+void
+octave_rl_set_completer_quote_characters (const char *s)
+{
+  OCTAVE_RL_SAVE_STRING (ss, s);
+
+  rl_completer_quote_characters = ss;
+}
+
+void
+octave_rl_set_completion_append_character (char c)
+{
+  rl_completion_append_character = c;
+}
+
+void
+octave_rl_set_completion_function (rl_attempted_completion_fcn_ptr f)
+{
+  rl_attempted_completion_function = f;
+}
+
+void
+octave_rl_set_quoting_function (rl_quoting_fcn_ptr f)
+{
+  rl_filename_quoting_function = f;
+}
+
+void
+octave_rl_set_dequoting_function (rl_dequoting_fcn_ptr f)
+{
+  rl_filename_dequoting_function = f;
+}
+
+void
+octave_rl_set_char_is_quoted_function (rl_char_is_quoted_fcn_ptr f)
+{
+  rl_char_is_quoted_p = f;
+}
+
+void
+octave_rl_set_startup_hook (rl_startup_hook_fcn_ptr f)
+{
+  rl_startup_hook = f;
+}
+
+rl_startup_hook_fcn_ptr
+octave_rl_get_startup_hook (void)
+{
+  return rl_startup_hook;
+}
+
+void
+octave_rl_set_event_hook (rl_event_hook_fcn_ptr f)
+{
+  rl_event_hook = f;
+}
+
+rl_event_hook_fcn_ptr
+octave_rl_get_event_hook (void)
+{
+  return rl_event_hook;
+}
+
+char **
+octave_rl_completion_matches (const char *text, rl_completer_fcn_ptr f)
+{
+  return rl_completion_matches (text, f);
+}
+
+char
+octave_rl_prompt_start_ignore (void)
+{
+  return RL_PROMPT_START_IGNORE;
+}
+
+char
+octave_rl_prompt_end_ignore (void)
+{
+  return RL_PROMPT_END_IGNORE;
+}
+
+void
+octave_rl_add_defun (const char *name, rl_fcn_ptr f, char key)
+{
+  rl_add_defun (name, f, key);
+}
+
+void
+octave_rl_set_terminal_name (const char *term)
+{
+  rl_terminal_name = term;
+}
+
+void
+octave_rl_initialize (void)
+{
+  rl_initialize ();
+}
+
+int
+octave_rl_history_search_forward (int count, int ignore)
+{
+  return rl_history_search_forward (count, ignore);
+}
+
+int
+octave_rl_history_search_backward (int count, int ignore)
+{
+  return rl_history_search_backward (count, ignore);
+}
+
+char
+octave_rl_ctrl (char c)
+{
+  return CTRL (c);
+}
+
+char
+octave_rl_meta (char c)
+{
+  return META (c);
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-rl-edit.h b/liboctave/oct-rl-edit.h
new file mode 100644
index 0000000..46b62c3
--- /dev/null
+++ b/liboctave/oct-rl-edit.h
@@ -0,0 +1,157 @@
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_rl_edit_h)
+#define octave_rl_edit_h 1
+
+typedef int (*rl_startup_hook_fcn_ptr) (void);
+
+typedef int (*rl_event_hook_fcn_ptr) (void);
+
+typedef int (*rl_fcn_ptr) (int, int);
+
+typedef char ** (*rl_attempted_completion_fcn_ptr) (const char *, int, int);
+
+typedef char * (*rl_completer_fcn_ptr) (const char *, int);
+
+typedef char * (*rl_quoting_fcn_ptr) (char *, int, char *);
+
+typedef char * (*rl_dequoting_fcn_ptr) (char *, int);
+
+typedef int (*rl_char_is_quoted_fcn_ptr) (char *, int);
+
+typedef int (*rl_command_fcn_ptr) (int, int);
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+  extern void octave_rl_redisplay (void);
+
+extern int octave_rl_screen_height (void);
+
+extern int octave_rl_screen_width (void);
+
+extern void octave_rl_enable_paren_matching (int);
+
+extern void octave_rl_init (void);
+
+extern void octave_rl_clear_screen (void);
+
+extern void octave_rl_resize_terminal (void);
+
+extern void octave_rl_restore_terminal_state (void);
+
+extern void octave_rl_insert_text (const char *);
+
+extern int octave_rl_newline (int, int);
+
+extern const char *octave_rl_line_buffer (void);
+
+extern void octave_rl_clear_undo_list (void);
+
+extern void octave_rl_set_name (const char *);
+
+extern char *octave_rl_readline (const char *);
+
+extern void octave_rl_set_input_stream (FILE *);
+
+extern FILE *octave_rl_get_input_stream (void);
+
+extern void octave_rl_set_output_stream (FILE *);
+
+extern FILE *octave_rl_get_output_stream (void);
+
+extern void octave_rl_read_init_file (const char *);
+
+extern void octave_rl_re_read_init_file (void);
+
+extern int octave_rl_filename_completion_desired (int);
+
+extern int octave_rl_filename_quoting_desired (int);
+
+extern char *octave_rl_filename_completion_function (const char *, int);
+
+extern void octave_rl_set_basic_word_break_characters (const char *);
+
+extern void octave_rl_set_completer_word_break_characters (const char *);
+
+extern void octave_rl_set_basic_quote_characters (const char *);
+
+extern void octave_rl_set_filename_quote_characters (const char *);
+
+extern void octave_rl_set_completer_quote_characters (const char *);
+
+extern void octave_rl_set_completion_append_character (char);
+
+extern void
+octave_rl_set_completion_function (rl_attempted_completion_fcn_ptr);
+
+extern void
+octave_rl_set_quoting_function (rl_quoting_fcn_ptr);
+
+extern void
+octave_rl_set_dequoting_function (rl_dequoting_fcn_ptr);
+
+extern void octave_rl_set_char_is_quoted_function (rl_char_is_quoted_fcn_ptr);
+
+extern void octave_rl_set_startup_hook (rl_startup_hook_fcn_ptr);
+
+extern rl_startup_hook_fcn_ptr octave_rl_get_startup_hook (void);
+
+extern void octave_rl_set_event_hook (rl_event_hook_fcn_ptr f);
+
+extern rl_event_hook_fcn_ptr octave_rl_get_event_hook (void);
+
+extern char **
+octave_rl_completion_matches (const char *, rl_completer_fcn_ptr);
+
+extern char octave_rl_prompt_start_ignore (void);
+
+extern char octave_rl_prompt_end_ignore (void);
+
+extern void octave_rl_add_defun (const char *, rl_fcn_ptr, char);
+
+extern void octave_rl_set_terminal_name (const char *);
+
+extern void octave_rl_initialize (void);
+
+extern int octave_rl_history_search_forward (int, int);
+
+extern int octave_rl_history_search_backward (int, int);
+
+extern char octave_rl_ctrl (char);
+
+extern char octave_rl_meta (char);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-rl-hist.c b/liboctave/oct-rl-hist.c
new file mode 100644
index 0000000..d11e1b2
--- /dev/null
+++ b/liboctave/oct-rl-hist.c
@@ -0,0 +1,248 @@
+/*
+
+Copyright (C) 2000, 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (USE_READLINE)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <readline/history.h>
+
+void
+octave_add_history (const char *line)
+{
+  add_history (line);
+}
+
+int
+octave_where_history (void)
+{
+  return where_history ();
+}
+
+int
+octave_history_length (void)
+{
+  return history_length;
+}
+
+int
+octave_max_input_history (void)
+{
+  return max_input_history;
+}
+
+int
+octave_history_base (void)
+{
+  return history_base;
+}
+
+void
+octave_stifle_history (int n)
+{
+  stifle_history (n);
+}
+
+int
+octave_unstifle_history (void)
+{
+  return unstifle_history ();
+}
+
+int
+octave_history_is_stifled (void)
+{
+  return history_is_stifled ();
+}
+
+int
+octave_history_set_pos (int n)
+{
+  return history_set_pos (n);
+}
+
+int
+octave_read_history (const char *f)
+{
+  return read_history (f);
+}
+
+void
+octave_using_history (void)
+{
+  using_history ();
+}
+
+int
+octave_read_history_range (const char *f, int b, int e)
+{
+  return read_history_range (f, b, e);
+}
+
+int
+octave_write_history (const char *f)
+{
+  return write_history (f);
+}
+
+int
+octave_append_history (int n, const char *f)
+{
+  return append_history (n, f);
+}
+
+int
+octave_history_truncate_file (const char *f, int n)
+{
+  return history_truncate_file (f, n);
+}
+
+void
+octave_remove_history (int n)
+{
+  HIST_ENTRY *discard = remove_history (n);
+
+  if (discard)
+    {
+      if (discard->line)
+	free (discard->line);
+
+      free (discard);
+    }
+}
+
+char *
+octave_history_goto_mark (int n)
+{
+  HIST_ENTRY *h;
+
+  char *retval = 0;
+
+  if (history_set_pos (n))
+    {
+      h = current_history ();
+
+      if (h)
+	retval = h->line;
+    }
+
+  return retval;
+}
+
+char *
+octave_history_get (int n)
+{
+  char *retval = 0;
+
+  HIST_ENTRY *h = history_get (n);
+
+  if (h)
+    retval = h->line;
+
+  return retval;
+}
+
+char **
+octave_history_list (int limit, int number_lines)
+{
+  static char **retval = 0;
+
+  HIST_ENTRY **hlist = 0;
+
+  if (retval)
+    {
+      char **p = retval;
+
+      while (*p)
+	free (*p++);
+
+      free (retval);
+
+      retval = 0;
+    }
+
+  hlist = history_list ();
+
+  if (hlist)
+    {
+      int i, k;
+
+      int beg = 0;
+      int end = 0;
+      while (hlist[end])
+	end++;
+
+      beg = (limit < 0 || end < limit) ? 0 : (end - limit);
+
+      retval = malloc ((end - beg + 1) * sizeof (char **));
+
+      k = 0;
+      for (i = beg; i < end; i++)
+	{
+	  char *line = hlist[i]->line;
+	  int len = line ? strlen (line) : 0;
+	  char *tmp = malloc (len + 64);
+
+	  if (number_lines)
+	    sprintf (tmp, "%5d%c%s", i + history_base,
+		     hlist[i]->data ? '*' : ' ',
+		     line ? line : "");
+	  else
+	    sprintf (tmp, "%c%s", hlist[i]->data ? '*' : ' ',
+		     line ? line : "");
+
+	  retval[k++] = tmp;
+	}
+
+      retval[k] = 0;
+    }
+
+  return retval;
+}
+
+void
+octave_replace_history_entry (int which, const char *line)
+{
+  HIST_ENTRY *discard = replace_history_entry (which, line, 0);
+
+  if (discard)
+    {
+      if (discard->line)
+	free (discard->line);
+
+      free (discard);
+    }
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-rl-hist.h b/liboctave/oct-rl-hist.h
new file mode 100644
index 0000000..4df2dc6
--- /dev/null
+++ b/liboctave/oct-rl-hist.h
@@ -0,0 +1,81 @@
+/*
+
+Copyright (C) 2000, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_rl_hist_h)
+#define octave_rl_hist_h 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void octave_add_history (const char *);
+
+extern int octave_where_history (void);
+
+extern int octave_history_length (void);
+
+extern int octave_max_input_history (void);
+
+extern int octave_history_base (void);
+
+extern void octave_stifle_history (int);
+
+extern int octave_unstifle_history (void);
+
+extern int octave_history_is_stifled (void);
+
+extern int octave_history_set_pos (int);
+
+extern int octave_read_history (const char *);
+
+extern void octave_using_history (void);
+
+extern int octave_read_history_range (const char *, int, int);
+
+extern int octave_write_history (const char *);
+
+extern int octave_append_history (int, const char *);
+
+extern int octave_history_truncate_file (const char *, int);
+
+extern void octave_remove_history (int);
+
+extern char *octave_history_goto_mark (int n);
+
+extern char *octave_history_get (int n);
+
+extern char **octave_history_list (int, int);
+
+extern void octave_replace_history_entry (int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-shlib.cc b/liboctave/oct-shlib.cc
new file mode 100644
index 0000000..b05373a
--- /dev/null
+++ b/liboctave/oct-shlib.cc
@@ -0,0 +1,710 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <map>
+
+#if defined (HAVE_SHL_LOAD_API)
+#include <cerrno>
+#include <cstring>
+#endif
+
+#if defined (HAVE_DYLD_API)
+#include <mach-o/dyld.h>
+#endif
+
+extern "C"
+{
+#if defined (HAVE_DLOPEN_API)
+#if defined (HAVE_DLFCN_H)
+#include <dlfcn.h>
+#else
+extern void *dlopen (const char *, int);
+extern const char *dlerror (void);
+extern void *dlsym (void *, const char *);
+extern int dlclose (void *);
+#endif
+#elif defined (HAVE_SHL_LOAD_API)
+#include <dl.h>
+#elif defined (HAVE_LOADLIBRARY_API)
+#include <windows.h>
+#undef min
+#undef max
+#endif
+}
+
+#include "file-stat.h"
+#include "lo-error.h"
+#include "oct-shlib.h"
+#include "str-vec.h"
+
+class
+octave_base_shlib : public octave_shlib
+{
+public:
+
+  octave_base_shlib (void)
+    : octave_shlib (octave_xshlib ()), file (), fcn_names (),
+      tm_loaded (static_cast<time_t> (0))
+  { count = 1; }
+
+  octave_base_shlib (const std::string& f)
+    : octave_shlib (octave_xshlib ()), file (f), fcn_names (),
+      tm_loaded (static_cast<time_t> (0))
+  { count = 1; }
+
+  ~octave_base_shlib (void) { }
+
+  void open (const std::string&) { }
+
+  // FIXME -- instead of returning a direct pointer to a function,
+  // perhaps this should return an object containing the pointer.
+  // Then we could do the reference counting without relying on users
+  // of this class to call remove at the appropriate time.  However,
+  // when users accessed the internal pointer, they would still need
+  // to know that the pointer is only valid while the container is
+  // valid (similar to the std::string::c_str method).
+
+  void *search (const std::string&, name_mangler = 0) { return 0; }
+
+  void close (octave_shlib::close_hook = 0) { }
+
+  bool remove (const std::string& fcn_name);
+
+  bool is_open (void) const { return false; }
+
+  bool is_out_of_date (void) const;
+
+  size_t number_of_functions_loaded (void) const { return fcn_names.size (); }
+
+  std::string file_name (void) const { return file; }
+
+  octave_time time_loaded (void) const { return tm_loaded; }
+
+protected:
+
+  typedef std::map<std::string, size_t>::iterator fcn_names_iterator;
+  typedef std::map<std::string, size_t>::const_iterator fcn_names_const_iterator;
+
+  std::string file;
+
+  std::map<std::string, size_t> fcn_names;
+
+  octave_time tm_loaded;
+
+  void stamp_time (void);
+
+  void add_to_fcn_names (const std::string& name);
+
+  void do_close_hook (octave_shlib::close_hook = 0);
+
+  void tabula_rasa (void);
+
+  // No copying!
+
+  octave_base_shlib (const octave_base_shlib&);
+
+  octave_base_shlib& operator = (const octave_base_shlib&);
+};
+
+bool
+octave_base_shlib::remove (const std::string& fcn_name)
+{
+  bool retval = false;
+
+  fcn_names_iterator p = fcn_names.find (fcn_name);
+
+  if (p != fcn_names.end () && --(p->second) == 0)
+    {
+      fcn_names.erase (fcn_name);
+      retval = true;
+    }
+
+  return retval;
+}
+
+bool
+octave_base_shlib::is_out_of_date (void) const
+{
+  file_stat fs (file);
+
+  return fs.is_newer (tm_loaded);
+}
+
+void
+octave_base_shlib::stamp_time (void)
+{
+  tm_loaded.stamp ();
+
+  file_stat fs (file);
+
+  if (fs.is_newer (tm_loaded))
+    (*current_liboctave_warning_with_id_handler)
+      ("Octave:warn-future-time-stamp",
+       "timestamp on file %s is in the future", file.c_str ());
+}
+
+void
+octave_base_shlib::add_to_fcn_names (const std::string& name)
+{
+  fcn_names_iterator p = fcn_names.find (name);
+
+  if (p == fcn_names.end ())
+    fcn_names[name] = 1;
+  else
+    ++(p->second);
+}
+
+void
+octave_base_shlib::do_close_hook (octave_shlib::close_hook cl_hook)
+{
+  for (fcn_names_iterator p = fcn_names.begin (); p != fcn_names.end (); p++)
+    cl_hook (p->first);
+}
+
+void
+octave_base_shlib::tabula_rasa (void)
+{
+  file = "";
+
+  fcn_names.clear ();
+
+  tm_loaded = static_cast<time_t> (0);
+}
+
+#if defined (HAVE_DLOPEN_API)
+
+class
+octave_dlopen_shlib : public octave_base_shlib
+{
+public:
+
+  octave_dlopen_shlib (void);
+
+  ~octave_dlopen_shlib (void);
+
+  void open (const std::string& f);
+
+  void *search (const std::string& name, name_mangler mangler = 0);
+
+  void close (octave_shlib::close_hook cl_hook = 0);
+
+  bool is_open (void) const { return (library != 0); }
+
+private:
+
+  // No copying!
+
+  octave_dlopen_shlib (const octave_dlopen_shlib&);
+
+  octave_dlopen_shlib& operator = (const octave_dlopen_shlib&);
+
+  void *library;
+};
+
+octave_dlopen_shlib::octave_dlopen_shlib (void)
+  : octave_base_shlib (), library (0)
+{
+}
+
+octave_dlopen_shlib::~octave_dlopen_shlib (void)
+{
+  close ();
+}
+
+void
+octave_dlopen_shlib::open (const std::string& f)
+{
+  if (! is_open ())
+    {
+      file = f;
+
+      int flags = 0;
+
+      // Use RTLD_NOW to resolve all symbols before dlopen returns.
+      // By using this option, dlopen will detect errors and Octave
+      // won't exit if there are unresolved symbols in the file we are
+      // loading, and we may even get a useful diagnostic.
+#if defined (RTLD_NOW)
+      flags |= RTLD_NOW;
+#endif
+
+#if defined (RTLD_GLOBAL)
+      flags |= RTLD_GLOBAL;
+#endif
+      
+      library = dlopen (file.c_str (), flags);
+
+      if (library)
+	stamp_time ();
+      else
+	{
+	  const char *msg = dlerror ();
+
+	  if (msg)
+	    (*current_liboctave_error_handler) ("%s", msg);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("shared library %s is already open", file.c_str ());
+}
+
+void *
+octave_dlopen_shlib::search (const std::string& name,
+			     octave_shlib::name_mangler mangler)
+{
+  void *function = 0;
+
+  if (is_open ())
+    {
+      std::string sym_name = name;
+
+      if (mangler)
+	sym_name = mangler (name);
+
+      function = dlsym (library, sym_name.c_str ());
+
+      if (function)
+	add_to_fcn_names (name);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("shared library %s is not open", file.c_str ());
+
+  return function;
+}
+
+void
+octave_dlopen_shlib::close (octave_shlib::close_hook cl_hook)
+{
+  if (is_open ())
+    {
+      if (cl_hook)
+	do_close_hook (cl_hook);
+
+      dlclose (library);
+
+      library = 0;
+
+      tabula_rasa ();
+    }
+}
+
+#elif defined (HAVE_SHL_LOAD_API)
+
+class
+octave_shl_load_shlib : public octave_base_shlib
+{
+public:
+
+  octave_shl_load_shlib (void);
+
+  ~octave_shl_load_shlib (void);
+
+  void open (const std::string& f);
+
+  void *search (const std::string& name, name_mangler mangler = 0);
+
+  void close (octave_shlib::close_hook cl_hook = 0);
+
+  bool is_open (void) const { return (library != 0); }
+
+private:
+
+  // No copying!
+
+  octave_shl_load_shlib (const octave_shl_load_shlib&);
+
+  octave_shl_load_shlib& operator = (const octave_shl_load_shlib&);
+
+  shl_t library;
+};
+
+octave_shl_load_shlib::octave_shl_load_shlib (void)
+  : octave_base_shlib (), library (0)
+{
+}
+
+octave_shl_load_shlib::~octave_shl_load_shlib (void)
+{
+  close ();
+}
+
+void
+octave_shl_load_shlib::open (const std::string& f)
+{
+  if (! is_open ())
+    {
+      file = f;
+
+      library = shl_load (file.c_str (), BIND_DEFERRED, 0L);
+
+      if (library)
+	stamp_time ();
+      else
+	{
+	  using namespace std;
+	  (*current_liboctave_error_handler) ("%s", strerror (errno));
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("shared library %s is already open", file.c_str ());
+}
+
+void *
+octave_shl_load_shlib::search (const std::string& name,
+			       octave_shlib::name_mangler mangler)
+{
+  void *function = 0;
+
+  if (is_open ())
+    {
+      std::string sym_name = name;
+
+      if (mangler)
+	sym_name = mangler (name);
+	
+      int status = shl_findsym (&library, sym_name.c_str (),
+				TYPE_UNDEFINED, &function);
+
+      if (status == 0)
+	add_to_fcn_names (name);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("shared library %s is not open", file.c_str ());
+
+  return function;
+}
+
+void
+octave_shl_load_shlib::close (octave_shlib::close_hook cl_hook)
+{
+  if (is_open ())
+    {
+      if (cl_hook)
+	do_close_hook (cl_hook);
+
+      shl_unload (library);
+
+      library = 0;
+
+      tabula_rasa ();
+    }
+}
+
+#elif defined (HAVE_LOADLIBRARY_API)
+
+class
+octave_w32_shlib: public octave_base_shlib
+{
+public:
+
+  octave_w32_shlib (void);
+
+  ~octave_w32_shlib (void);
+
+  void open (const std::string& f);
+
+  void *search (const std::string& name, name_mangler mangler = 0);
+
+  void close (octave_shlib::close_hook cl_hook = 0);
+
+  bool is_open (void) const { return (handle != 0); }
+
+private:
+
+  // No copying!
+
+  octave_w32_shlib (const octave_w32_shlib&);
+
+  octave_w32_shlib& operator = (const octave_w32_shlib&);
+
+  HINSTANCE handle; 
+};
+
+octave_w32_shlib::octave_w32_shlib (void)
+  : octave_base_shlib (), handle (0)
+{
+}
+
+octave_w32_shlib::~octave_w32_shlib (void)
+{
+  close ();
+}
+
+void
+octave_w32_shlib::open (const std::string& f)
+{
+  if (! is_open ())
+    {
+      file = f;
+
+      handle = LoadLibrary (file.c_str ());
+
+      if (handle)
+	stamp_time ();
+      else
+	{
+	  DWORD lastError = GetLastError ();
+	  char *msg;
+
+	  switch (lastError)
+	    {
+	    case ERROR_MOD_NOT_FOUND:
+	    case ERROR_DLL_NOT_FOUND:
+	      msg = "could not find library or dependents";
+	      break;
+
+	    case ERROR_INVALID_DLL:
+	      msg = "library or its dependents are damaged";
+	      break;
+
+	    case ERROR_DLL_INIT_FAILED:
+	      msg = "library initialization routine failed";
+	      break;
+
+	    default:
+	      msg = "library open failed";
+	    }
+
+	  (*current_liboctave_error_handler) ("%s: %s", msg, file.c_str ());
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("shared library %s is already open", file.c_str ());
+}
+
+extern "C"
+{
+  void * octave_w32_search (HINSTANCE handle, const char * name);
+}
+
+void *
+octave_w32_shlib::search (const std::string& name,
+			  octave_shlib::name_mangler mangler)
+{
+  void *function = 0;
+
+  if (is_open ())
+    {
+      std::string sym_name = name;
+
+      if (mangler)
+	sym_name = mangler (name);
+
+      function = octave_w32_library_search (handle, sym_name.c_str ());
+
+      if (function)
+	add_to_fcn_names (name);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("shared library %s is not open", file.c_str ());
+
+  return function;
+}
+
+void
+octave_w32_shlib::close (octave_shlib::close_hook cl_hook)
+{
+  if (is_open ())
+    {
+      if (cl_hook)
+	do_close_hook (cl_hook);
+
+      FreeLibrary (handle);
+
+      handle = 0;
+
+      tabula_rasa ();
+    }
+}
+
+#elif defined (HAVE_DYLD_API)
+
+class
+octave_dyld_shlib : public octave_base_shlib
+{
+public:
+
+  octave_dyld_shlib (void);
+
+  ~octave_dyld_shlib (void);
+
+  void open (const std::string& f);
+
+  void *search (const std::string& name, name_mangler mangler = 0);
+
+  void close (octave_shlib::close_hook cl_hook = 0);
+
+  bool is_open (void) const {return (isOpen); }
+
+private:
+
+  // No copying!
+
+  octave_dyld_shlib (const octave_dyld_shlib&);
+
+  octave_dyld_shlib& operator = (const octave_dyld_shlib&);
+
+  bool isOpen;
+  NSObjectFileImage img;
+  NSModule handle;
+};
+
+octave_dyld_shlib::octave_dyld_shlib (void)
+  : octave_base_shlib (), isOpen (false), handle (0)
+{
+}
+
+octave_dyld_shlib::~octave_dyld_shlib (void)
+{
+  close ();
+}
+
+void
+octave_dyld_shlib::open (const std::string& f)
+{
+  int returnCode;
+
+  if (! is_open ())
+    {
+      file = f;
+
+      returnCode = NSCreateObjectFileImageFromFile (file.c_str (), &img);
+
+      if (NSObjectFileImageSuccess == returnCode)
+	{
+	  handle = NSLinkModule (img, file.c_str (),
+				 (NSLINKMODULE_OPTION_RETURN_ON_ERROR
+				  | NSLINKMODULE_OPTION_PRIVATE));
+	  if (handle)
+	    {
+	      stamp_time ();
+	      isOpen = true;
+	    }
+	  else
+	    {
+	      NSLinkEditErrors ler;
+	      int lerno;
+	      const char *file2;
+	      const char *errstr = 0;
+
+	      NSLinkEditError (&ler, &lerno, &file2, &errstr);
+
+	      if (errstr)
+		(*current_liboctave_error_handler)
+		  ("%s: %s", file.c_str (), errstr);	
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("got NSObjectFileImageReturnCode %d", returnCode);
+
+	  // FIXME -- should use NSLinkEditError () to get
+	  // more info on what went wrong.
+	}
+    }
+  else
+    {
+      (*current_liboctave_error_handler)
+	("bundle %s is already open", file.c_str ());
+    }
+}
+
+void *
+octave_dyld_shlib::search (const std::string& name,
+			   octave_shlib::name_mangler mangler)
+{
+  void *function = 0;
+
+  if (is_open ())
+    {
+      std::string sym_name = name;
+
+      if (mangler)
+	sym_name = mangler (name);
+
+      NSSymbol symbol = NSLookupSymbolInModule (handle, sym_name.c_str ());
+
+      if (symbol)
+	{
+	  function = NSAddressOfSymbol (symbol);
+	  add_to_fcn_names (name);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("bundle %s is not open", file.c_str ());
+
+  return function;
+}
+
+void
+octave_dyld_shlib::close (octave_shlib::close_hook cl_hook)
+{
+  if (is_open ())
+    {
+      do_close_hook (cl_hook);
+
+      NSUnLinkModule (handle, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
+
+      handle = 0;
+
+      if (NSDestroyObjectFileImage (img))
+	isOpen = false;
+
+      tabula_rasa ();
+    }
+}
+
+#endif
+
+octave_shlib *
+octave_shlib::make_shlib (void)
+{
+#if defined (HAVE_DLOPEN_API)
+  return new octave_dlopen_shlib ();
+#elif defined (HAVE_SHL_LOAD_API)
+  return new octave_shl_load_shlib ();
+#elif defined (HAVE_LOADLIBRARY_API)
+  return new octave_w32_shlib ();
+#elif defined (HAVE_DYLD_API)
+  return new octave_dyld_shlib ();
+#else
+  return new octave_base_shlib ();
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-shlib.h b/liboctave/oct-shlib.h
new file mode 100644
index 0000000..b9318c2
--- /dev/null
+++ b/liboctave/oct-shlib.h
@@ -0,0 +1,142 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_shlib_h)
+#define octave_shlib_h 1
+
+#include <string>
+
+#include "oct-time.h"
+
+// This just provides a way to avoid infinite recursion when building
+// octave_shlib objects.
+
+class
+OCTAVE_API
+octave_xshlib
+{
+public:
+
+  octave_xshlib (void) { }
+};
+
+class
+OCTAVE_API
+octave_shlib
+{
+public:
+
+  typedef std::string (*name_mangler) (const std::string&);
+
+  typedef void (*close_hook) (const std::string&);
+
+  octave_shlib (void) : relative (false), rep (make_shlib ()) { }
+
+  octave_shlib (const std::string& f)
+    : relative (false), rep (make_shlib ()) { open (f); }
+
+  virtual ~octave_shlib (void)
+    {
+      if (rep && --rep->count == 0)
+	{
+	  delete rep;
+	  rep = 0;
+	}
+    }
+
+  octave_shlib (const octave_shlib& sl)
+    {
+      rep = sl.rep;
+      rep->count++;
+    }
+
+  octave_shlib& operator = (const octave_shlib& sl)
+    {
+      if (rep != sl.rep)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = sl.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+  bool operator == (const octave_shlib& sl) const
+    { return (rep == sl.rep); }
+
+  operator bool () const { return is_open (); }
+
+  virtual void open (const std::string& f) { rep->open (f); }
+
+  virtual void *search (const std::string& nm, name_mangler mangler = 0)
+    { return rep->search (nm, mangler); }
+
+  virtual void close (close_hook cl_hook = 0)
+    { rep->close (cl_hook); }
+
+  virtual bool remove (const std::string& fcn_name)
+    { return rep->remove (fcn_name); }
+
+  virtual bool is_out_of_date (void) const
+    { return rep->is_out_of_date (); }
+
+  void mark_relative (void) { relative = true; }
+
+  bool is_relative (void) const { return relative; }
+
+  virtual size_t number_of_functions_loaded (void) const
+    { return rep->number_of_functions_loaded (); }
+
+  virtual std::string file_name (void) const
+    { return rep->file_name (); }
+
+  virtual octave_time time_loaded (void) const
+    { return rep->time_loaded (); }
+
+protected:
+
+  octave_shlib (const octave_xshlib&) : rep (0) { }
+
+  virtual bool is_open (void) const { return rep->is_open (); }
+
+  static octave_shlib *make_shlib (void);
+
+  // TRUE if this function was found from a relative path element.
+  bool relative;
+
+  union
+    {
+      octave_shlib *rep;
+      int count;
+    };
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-sort.cc b/liboctave/oct-sort.cc
new file mode 100644
index 0000000..231c9be
--- /dev/null
+++ b/liboctave/oct-sort.cc
@@ -0,0 +1,1948 @@
+/*
+Copyright (C) 2003, 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+Code stolen in large part from Python's, listobject.c, which itself had
+no license header. However, thanks to Tim Peters for the parts of the
+code I ripped-off.
+
+As required in the Python license the short description of the changes
+made are
+
+* convert the sorting code in listobject.cc into a generic class, 
+  replacing PyObject* with the type of the class T.
+
+* replaced usages of malloc, free, memcpy and memmove by standard C++
+  new [], delete [] and std::copy and std::copy_backward. Note that replacing
+  memmove by std::copy is possible if the destination starts before the source.
+  If not, std::copy_backward needs to be used.
+  
+* templatize comparison operator in most methods, provide possible dispatch
+
+* duplicate methods to avoid by-the-way indexed sorting
+
+* add methods for verifying sortedness of array
+
+* row sorting via breadth-first tree subsorting
+
+* binary lookup and sequential binary lookup optimized for dense downsampling.
+
+* NOTE: the memory management routines rely on the fact that delete [] silently
+  ignores null pointers. Don't gripe about the missing checks - they're there.
+
+
+The Python license is
+
+  PSF LICENSE AGREEMENT FOR PYTHON 2.3
+  --------------------------------------
+
+  1. This LICENSE AGREEMENT is between the Python Software Foundation
+  ("PSF"), and the Individual or Organization ("Licensee") accessing and
+  otherwise using Python 2.3 software in source or binary form and its
+  associated documentation.
+
+  2. Subject to the terms and conditions of this License Agreement, PSF
+  hereby grants Licensee a nonexclusive, royalty-free, world-wide
+  license to reproduce, analyze, test, perform and/or display publicly,
+  prepare derivative works, distribute, and otherwise use Python 2.3
+  alone or in any derivative version, provided, however, that PSF's
+  License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+  2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are
+  retained in Python 2.3 alone or in any derivative version prepared by
+  Licensee.
+
+  3. In the event Licensee prepares a derivative work that is based on
+  or incorporates Python 2.3 or any part thereof, and wants to make
+  the derivative work available to others as provided herein, then
+  Licensee hereby agrees to include in any such work a brief summary of
+  the changes made to Python 2.3.
+
+  4. PSF is making Python 2.3 available to Licensee on an "AS IS"
+  basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+  IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+  DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+  FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
+  INFRINGE ANY THIRD PARTY RIGHTS.
+
+  5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+  2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+  A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
+  OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+  6. This License Agreement will automatically terminate upon a material
+  breach of its terms and conditions.
+
+  7. Nothing in this License Agreement shall be deemed to create any
+  relationship of agency, partnership, or joint venture between PSF and
+  Licensee.  This License Agreement does not grant permission to use PSF
+  trademarks or trade name in a trademark sense to endorse or promote
+  products or services of Licensee, or any third party.
+
+  8. By copying, installing or otherwise using Python 2.3, Licensee
+  agrees to be bound by the terms and conditions of this License
+  Agreement.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <algorithm>
+#include <functional>
+#include <cstring>
+#include <stack>
+
+#include "lo-mappers.h"
+#include "quit.h"
+#include "oct-sort.h"
+#include "oct-locbuf.h"
+
+template <class T>
+octave_sort<T>::octave_sort (void) : 
+  compare (ascending_compare), ms (0)
+{ 
+}
+
+template <class T>
+octave_sort<T>::octave_sort (compare_fcn_type comp) 
+  : compare (comp), ms (0)
+{ 
+}
+
+template <class T>
+octave_sort<T>::~octave_sort () 
+{ 
+  delete ms;
+}
+
+template <class T>
+void
+octave_sort<T>::set_compare (sortmode mode)
+{
+  if (mode == ASCENDING)
+    compare = ascending_compare;
+  else if (mode == DESCENDING)
+    compare = descending_compare;
+  else
+    compare = 0;
+}
+
+template <class T>
+template <class Comp>
+void
+octave_sort<T>::binarysort (T *data, octave_idx_type nel, 
+                            octave_idx_type start, Comp comp)
+{
+  if (start == 0)
+    ++start;
+
+  for (; start < nel; ++start) 
+    {
+      /* set l to where *start belongs */
+      octave_idx_type l = 0, r = start;
+      T pivot = data[start];
+      /* Invariants:
+       * pivot >= all in [lo, l).
+       * pivot  < all in [r, start).
+       * The second is vacuously true at the start.
+       */
+      do 
+	{
+	  octave_idx_type p = l + ((r - l) >> 1);
+	  if (comp (pivot, data[p]))
+	    r = p;
+	  else
+	    l = p+1;
+	} 
+      while (l < r);
+      /* The invariants still hold, so pivot >= all in [lo, l) and
+	 pivot < all in [l, start), so pivot belongs at l.  Note
+	 that if there are elements equal to pivot, l points to the
+	 first slot after them -- that's why this sort is stable.
+	 Slide over to make room.
+	 Caution: using memmove is much slower under MSVC 5;
+	 we're not usually moving many slots. */
+      // NOTE: using swap and going upwards appears to be faster.
+      for (octave_idx_type p = l; p < start; p++)
+        std::swap (pivot, data[p]);
+      data[start] = pivot;
+    }
+
+  return;
+}
+
+template <class T>
+template <class Comp>
+void
+octave_sort<T>::binarysort (T *data, octave_idx_type *idx, octave_idx_type nel, 
+                            octave_idx_type start, Comp comp)
+{
+  if (start == 0)
+    ++start;
+
+  for (; start < nel; ++start) 
+    {
+      /* set l to where *start belongs */
+      octave_idx_type l = 0, r = start;
+      T pivot = data[start];
+      /* Invariants:
+       * pivot >= all in [lo, l).
+       * pivot  < all in [r, start).
+       * The second is vacuously true at the start.
+       */
+      do 
+	{
+	  octave_idx_type p = l + ((r - l) >> 1);
+	  if (comp (pivot, data[p]))
+	    r = p;
+	  else
+	    l = p+1;
+	} 
+      while (l < r);
+      /* The invariants still hold, so pivot >= all in [lo, l) and
+	 pivot < all in [l, start), so pivot belongs at l.  Note
+	 that if there are elements equal to pivot, l points to the
+	 first slot after them -- that's why this sort is stable.
+	 Slide over to make room.
+	 Caution: using memmove is much slower under MSVC 5;
+	 we're not usually moving many slots. */
+      // NOTE: using swap and going upwards appears to be faster.
+      for (octave_idx_type p = l; p < start; p++)
+        std::swap (pivot, data[p]);
+      data[start] = pivot;
+      octave_idx_type ipivot = idx[start];
+      for (octave_idx_type p = l; p < start; p++)
+        std::swap (ipivot, idx[p]);
+      idx[start] = ipivot;
+    }
+
+  return;
+}
+
+/*
+Return the length of the run beginning at lo, in the slice [lo, hi).  lo < hi
+is required on entry.  "A run" is the longest ascending sequence, with
+
+    lo[0] <= lo[1] <= lo[2] <= ...
+
+or the longest descending sequence, with
+
+    lo[0] > lo[1] > lo[2] > ...
+
+DESCENDING is set to false in the former case, or to true in the latter.
+For its intended use in a stable mergesort, the strictness of the defn of
+"descending" is needed so that the caller can safely reverse a descending
+sequence without violating stability (strict > ensures there are no equal
+elements to get out of order).
+
+Returns -1 in case of error.
+*/
+template <class T>
+template <class Comp>
+octave_idx_type
+octave_sort<T>::count_run (T *lo, octave_idx_type nel, bool& descending, Comp comp)
+{
+  octave_idx_type n;
+  T *hi = lo + nel;
+
+  descending = false;
+  ++lo;
+  if (lo == hi)
+    return 1;
+
+  n = 2;
+
+  if (comp (*lo, *(lo-1)))
+    {
+      descending = true;
+      for (lo = lo+1; lo < hi; ++lo, ++n) 
+	{
+	  if (comp (*lo, *(lo-1)))
+	    ;
+	  else
+	    break;
+	}
+    }
+  else 
+    {
+      for (lo = lo+1; lo < hi; ++lo, ++n) 
+	{
+	  if (comp (*lo, *(lo-1)))
+	    break;
+	}
+    }
+
+  return n;
+}
+
+/*
+Locate the proper position of key in a sorted vector; if the vector contains
+an element equal to key, return the position immediately to the left of
+the leftmost equal element.  [gallop_right() does the same except returns
+the position to the right of the rightmost equal element (if any).]
+
+"a" is a sorted vector with n elements, starting at a[0].  n must be > 0.
+
+"hint" is an index at which to begin the search, 0 <= hint < n.  The closer
+hint is to the final result, the faster this runs.
+
+The return value is the int k in 0..n such that
+
+    a[k-1] < key <= a[k]
+
+pretending that *(a-1) is minus infinity and a[n] is plus infinity.  IOW,
+key belongs at index k; or, IOW, the first k elements of a should precede
+key, and the last n-k should follow key.
+
+Returns -1 on error.  See listsort.txt for info on the method.
+*/
+template <class T>
+template <class Comp>
+octave_idx_type
+octave_sort<T>::gallop_left (T key, T *a, octave_idx_type n, octave_idx_type hint,
+                             Comp comp)
+{
+  octave_idx_type ofs;
+  octave_idx_type lastofs;
+  octave_idx_type k;
+
+  a += hint;
+  lastofs = 0;
+  ofs = 1;
+  if (comp (*a, key))
+    {
+      /* a[hint] < key -- gallop right, until
+       * a[hint + lastofs] < key <= a[hint + ofs]
+       */
+      const octave_idx_type maxofs = n - hint;	/* &a[n-1] is highest */
+      while (ofs < maxofs) 
+	{
+	  if (comp (a[ofs], key))
+	    {
+	      lastofs = ofs;
+	      ofs = (ofs << 1) + 1;
+	      if (ofs <= 0)	/* int overflow */
+		ofs = maxofs;
+	    }
+	  else	/* key <= a[hint + ofs] */
+	    break;
+	}
+      if (ofs > maxofs)
+	ofs = maxofs;
+      /* Translate back to offsets relative to &a[0]. */
+      lastofs += hint;
+      ofs += hint;
+    }
+  else 
+    {
+      /* key <= a[hint] -- gallop left, until
+       * a[hint - ofs] < key <= a[hint - lastofs]
+       */
+      const octave_idx_type maxofs = hint + 1;	/* &a[0] is lowest */
+      while (ofs < maxofs) 
+	{
+	  if (comp (*(a-ofs), key))
+	    break;
+	  /* key <= a[hint - ofs] */
+	  lastofs = ofs;
+	  ofs = (ofs << 1) + 1;
+	  if (ofs <= 0)	/* int overflow */
+	    ofs = maxofs;
+	}
+      if (ofs > maxofs)
+	ofs = maxofs;
+      /* Translate back to positive offsets relative to &a[0]. */
+      k = lastofs;
+      lastofs = hint - ofs;
+      ofs = hint - k;
+    }
+  a -= hint;
+
+  /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
+   * right of lastofs but no farther right than ofs.  Do a binary
+   * search, with invariant a[lastofs-1] < key <= a[ofs].
+   */
+  ++lastofs;
+  while (lastofs < ofs) 
+    {
+      octave_idx_type m = lastofs + ((ofs - lastofs) >> 1);
+
+      if (comp (a[m], key))
+	lastofs = m+1;	/* a[m] < key */
+      else
+	ofs = m;	/* key <= a[m] */
+    }
+
+  return ofs;
+}
+
+/*
+Exactly like gallop_left(), except that if key already exists in a[0:n],
+finds the position immediately to the right of the rightmost equal value.
+
+The return value is the int k in 0..n such that
+
+    a[k-1] <= key < a[k]
+
+or -1 if error.
+
+The code duplication is massive, but this is enough different given that
+we're sticking to "<" comparisons that it's much harder to follow if
+written as one routine with yet another "left or right?" flag.
+*/
+template <class T>
+template <class Comp>
+octave_idx_type
+octave_sort<T>::gallop_right (T key, T *a, octave_idx_type n, octave_idx_type hint,
+                              Comp comp)
+{
+  octave_idx_type ofs;
+  octave_idx_type lastofs;
+  octave_idx_type k;
+
+  a += hint;
+  lastofs = 0;
+  ofs = 1;
+  if (comp (key, *a))
+    {
+      /* key < a[hint] -- gallop left, until
+       * a[hint - ofs] <= key < a[hint - lastofs]
+       */
+      const octave_idx_type maxofs = hint + 1;	/* &a[0] is lowest */
+      while (ofs < maxofs) 
+	{
+	  if (comp (key, *(a-ofs)))
+	    {
+	      lastofs = ofs;
+	      ofs = (ofs << 1) + 1;
+	      if (ofs <= 0)	/* int overflow */
+		ofs = maxofs;
+	    }
+	  else	/* a[hint - ofs] <= key */
+	    break;
+	}
+      if (ofs > maxofs)
+	ofs = maxofs;
+      /* Translate back to positive offsets relative to &a[0]. */
+      k = lastofs;
+      lastofs = hint - ofs;
+      ofs = hint - k;
+    }
+  else 
+    {
+      /* a[hint] <= key -- gallop right, until
+       * a[hint + lastofs] <= key < a[hint + ofs]
+       */
+      const octave_idx_type maxofs = n - hint;	/* &a[n-1] is highest */
+      while (ofs < maxofs) 
+	{
+	  if (comp (key, a[ofs]))
+	    break;
+	  /* a[hint + ofs] <= key */
+	  lastofs = ofs;
+	  ofs = (ofs << 1) + 1;
+	  if (ofs <= 0)	/* int overflow */
+	    ofs = maxofs;
+	}
+      if (ofs > maxofs)
+	ofs = maxofs;
+      /* Translate back to offsets relative to &a[0]. */
+      lastofs += hint;
+      ofs += hint;
+    }
+  a -= hint;
+
+  /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
+   * right of lastofs but no farther right than ofs.  Do a binary
+   * search, with invariant a[lastofs-1] <= key < a[ofs].
+   */
+  ++lastofs;
+  while (lastofs < ofs) 
+    {
+      octave_idx_type m = lastofs + ((ofs - lastofs) >> 1);
+
+      if (comp (key, a[m]))
+	ofs = m;	/* key < a[m] */
+      else
+	lastofs = m+1;	/* a[m] <= key */
+    }
+
+  return ofs;
+}
+
+static inline octave_idx_type
+roundupsize (octave_idx_type n)
+{
+  unsigned int nbits = 3;
+  octave_idx_type n2 = static_cast<octave_idx_type> (n) >> 8;
+
+  /* Round up:
+   * If n <       256, to a multiple of        8.
+   * If n <      2048, to a multiple of       64.
+   * If n <     16384, to a multiple of      512.
+   * If n <    131072, to a multiple of     4096.
+   * If n <   1048576, to a multiple of    32768.
+   * If n <   8388608, to a multiple of   262144.
+   * If n <  67108864, to a multiple of  2097152.
+   * If n < 536870912, to a multiple of 16777216.
+   * ...
+   * If n < 2**(5+3*i), to a multiple of 2**(3*i).
+   *
+   * This over-allocates proportional to the list size, making room
+   * for additional growth.  The over-allocation is mild, but is
+   * enough to give linear-time amortized behavior over a long
+   * sequence of appends() in the presence of a poorly-performing
+   * system realloc() (which is a reality, e.g., across all flavors
+   * of Windows, with Win9x behavior being particularly bad -- and
+   * we've still got address space fragmentation problems on Win9x
+   * even with this scheme, although it requires much longer lists to
+   * provoke them than it used to).
+   */
+  while (n2)
+    {
+      n2 >>= 3;
+      nbits += 3;
+    }
+
+  return ((n >> nbits) + 1) << nbits;
+}
+
+/* Ensure enough temp memory for 'need' array slots is available.
+ * Returns 0 on success and -1 if the memory can't be gotten.
+ */
+template <class T>
+void
+octave_sort<T>::MergeState::getmem (octave_idx_type need)
+{
+  if (need <= alloced)
+    return;
+
+  need = roundupsize (need); 
+  /* Don't realloc!  That can cost cycles to copy the old data, but
+   * we don't care what's in the block.
+   */
+  delete [] a;
+  delete [] ia; // Must do this or fool possible next getmemi.
+  a = new T[need];
+  alloced = need;
+
+}
+
+template <class T>
+void
+octave_sort<T>::MergeState::getmemi (octave_idx_type need)
+{
+  if (ia && need <= alloced)
+    return;
+
+  need = roundupsize (need); 
+  /* Don't realloc!  That can cost cycles to copy the old data, but
+   * we don't care what's in the block.
+   */
+  delete [] a;
+  delete [] ia;
+
+  a = new T[need];
+  ia = new octave_idx_type[need];
+  alloced = need;
+}
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na <= nb.  See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_lo (T *pa, octave_idx_type na, 
+                          T *pb, octave_idx_type nb,
+                          Comp comp)
+{
+  octave_idx_type k;
+  T *dest;
+  int result = -1;	/* guilty until proved innocent */
+  octave_idx_type min_gallop = ms->min_gallop;
+
+  ms->getmem (na);
+
+  std::copy (pa, pa + na, ms->a);
+  dest = pa;
+  pa = ms->a;
+
+  *dest++ = *pb++;
+  --nb;
+  if (nb == 0)
+    goto Succeed;
+  if (na == 1)
+    goto CopyB;
+
+  for (;;)
+    {
+      octave_idx_type acount = 0;	/* # of times A won in a row */
+      octave_idx_type bcount = 0;	/* # of times B won in a row */
+
+      /* Do the straightforward thing until (if ever) one run
+       * appears to win consistently.
+       */
+      for (;;)
+	{
+
+          // FIXME: these loops are candidates for further optimizations.
+          // Rather than testing everything in each cycle, it may be more
+          // efficient to do it in hunks. 
+	  if (comp (*pb, *pa))
+	    {
+	      *dest++ = *pb++;
+	      ++bcount;
+	      acount = 0;
+	      --nb;
+	      if (nb == 0)
+		goto Succeed;
+	      if (bcount >= min_gallop)
+		break;
+	    }
+	  else
+	    {
+	      *dest++ = *pa++;
+	      ++acount;
+	      bcount = 0;
+	      --na;
+	      if (na == 1)
+		goto CopyB;
+	      if (acount >= min_gallop)
+		break;
+	    }
+	}
+
+      /* One run is winning so consistently that galloping may
+       * be a huge win.  So try that, and continue galloping until
+       * (if ever) neither run appears to be winning consistently
+       * anymore.
+       */
+      ++min_gallop;
+      do
+	{
+	  min_gallop -= min_gallop > 1;
+	  ms->min_gallop = min_gallop;
+	  k = gallop_right (*pb, pa, na, 0, comp);
+	  acount = k;
+	  if (k)
+	    {
+	      if (k < 0)
+		goto Fail;
+              dest = std::copy (pa, pa + k, dest);
+	      pa += k;
+	      na -= k;
+	      if (na == 1)
+		goto CopyB;
+	      /* na==0 is impossible now if the comparison
+	       * function is consistent, but we can't assume
+	       * that it is.
+	       */
+	      if (na == 0)
+		goto Succeed;
+	    }
+	  *dest++ = *pb++;
+	  --nb;
+	  if (nb == 0)
+	    goto Succeed;
+
+	  k = gallop_left (*pa, pb, nb, 0, comp);
+	  bcount = k;
+	  if (k)
+	    {
+	      if (k < 0)
+		goto Fail;
+              dest = std::copy (pb, pb + k, dest);
+	      pb += k;
+	      nb -= k;
+	      if (nb == 0)
+		goto Succeed;
+	    }
+	  *dest++ = *pa++;
+	  --na;
+	  if (na == 1)
+	    goto CopyB;
+	}
+      while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+
+      ++min_gallop;	/* penalize it for leaving galloping mode */
+      ms->min_gallop = min_gallop;
+    }
+
+ Succeed:
+  result = 0;
+
+ Fail:
+  if (na)
+    std::copy (pa, pa + na, dest);
+  return result;
+
+ CopyB:
+  /* The last element of pa belongs at the end of the merge. */
+  std::copy (pb, pb + nb, dest);
+  dest[nb] = *pa;
+
+  return 0;
+}
+
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_lo (T *pa, octave_idx_type *ipa, octave_idx_type na, 
+                          T *pb, octave_idx_type *ipb, octave_idx_type nb,
+                          Comp comp)
+{
+  octave_idx_type k;
+  T *dest;
+  octave_idx_type *idest;
+  int result = -1;	/* guilty until proved innocent */
+  octave_idx_type min_gallop = ms->min_gallop;
+
+  ms->getmemi (na);
+
+  std::copy (pa, pa + na, ms->a);
+  std::copy (ipa, ipa + na, ms->ia);
+  dest = pa; idest = ipa;
+  pa = ms->a; ipa = ms->ia;
+
+  *dest++ = *pb++; *idest++ = *ipb++;
+  --nb;
+  if (nb == 0)
+    goto Succeed;
+  if (na == 1)
+    goto CopyB;
+
+  for (;;)
+    {
+      octave_idx_type acount = 0;	/* # of times A won in a row */
+      octave_idx_type bcount = 0;	/* # of times B won in a row */
+
+      /* Do the straightforward thing until (if ever) one run
+       * appears to win consistently.
+       */
+      for (;;)
+	{
+
+	  if (comp (*pb, *pa))
+	    {
+	      *dest++ = *pb++; *idest++ = *ipb++;
+	      ++bcount;
+	      acount = 0;
+	      --nb;
+	      if (nb == 0)
+		goto Succeed;
+	      if (bcount >= min_gallop)
+		break;
+	    }
+	  else
+	    {
+	      *dest++ = *pa++; *idest++ = *ipa++;
+	      ++acount;
+	      bcount = 0;
+	      --na;
+	      if (na == 1)
+		goto CopyB;
+	      if (acount >= min_gallop)
+		break;
+	    }
+	}
+
+      /* One run is winning so consistently that galloping may
+       * be a huge win.  So try that, and continue galloping until
+       * (if ever) neither run appears to be winning consistently
+       * anymore.
+       */
+      ++min_gallop;
+      do
+	{
+	  min_gallop -= min_gallop > 1;
+	  ms->min_gallop = min_gallop;
+	  k = gallop_right (*pb, pa, na, 0, comp);
+	  acount = k;
+	  if (k)
+	    {
+	      if (k < 0)
+		goto Fail;
+              dest = std::copy (pa, pa + k, dest);
+              idest = std::copy (ipa, ipa + k, idest);
+	      pa += k; ipa += k;
+	      na -= k;
+	      if (na == 1)
+		goto CopyB;
+	      /* na==0 is impossible now if the comparison
+	       * function is consistent, but we can't assume
+	       * that it is.
+	       */
+	      if (na == 0)
+		goto Succeed;
+	    }
+	  *dest++ = *pb++; *idest++ = *ipb++;
+	  --nb;
+	  if (nb == 0)
+	    goto Succeed;
+
+	  k = gallop_left (*pa, pb, nb, 0, comp);
+	  bcount = k;
+	  if (k)
+	    {
+	      if (k < 0)
+		goto Fail;
+              dest = std::copy (pb, pb + k, dest);
+              idest = std::copy (ipb, ipb + k, idest);
+	      pb += k; ipb += k;
+	      nb -= k;
+	      if (nb == 0)
+		goto Succeed;
+	    }
+	  *dest++ = *pa++; *idest++ = *ipa++;
+	  --na;
+	  if (na == 1)
+	    goto CopyB;
+	}
+      while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+
+      ++min_gallop;	/* penalize it for leaving galloping mode */
+      ms->min_gallop = min_gallop;
+    }
+
+ Succeed:
+  result = 0;
+
+ Fail:
+  if (na)
+    {
+      std::copy (pa, pa + na, dest);
+      std::copy (ipa, ipa + na, idest);
+    }
+  return result;
+
+ CopyB:
+  /* The last element of pa belongs at the end of the merge. */
+  std::copy (pb, pb + nb, dest);
+  std::copy (ipb, ipb + nb, idest);
+  dest[nb] = *pa;
+  idest[nb] = *ipa;
+
+  return 0;
+}
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na >= nb.  See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_hi (T *pa, octave_idx_type na, 
+                          T *pb, octave_idx_type nb,
+                          Comp comp)
+{
+  octave_idx_type k;
+  T *dest;
+  int result = -1;	/* guilty until proved innocent */
+  T *basea, *baseb;
+  octave_idx_type min_gallop = ms->min_gallop;
+
+  ms->getmem (nb);
+
+  dest = pb + nb - 1;
+  std::copy (pb, pb + nb, ms->a);
+  basea = pa;
+  baseb = ms->a;
+  pb = ms->a + nb - 1;
+  pa += na - 1;
+
+  *dest-- = *pa--;
+  --na;
+  if (na == 0)
+    goto Succeed;
+  if (nb == 1)
+    goto CopyA;
+
+  for (;;) 
+    {
+      octave_idx_type acount = 0;	/* # of times A won in a row */
+      octave_idx_type bcount = 0;	/* # of times B won in a row */
+
+      /* Do the straightforward thing until (if ever) one run
+       * appears to win consistently.
+       */
+      for (;;) 
+	{
+	  if (comp (*pb, *pa))
+	    {
+	      *dest-- = *pa--;
+	      ++acount;
+	      bcount = 0;
+	      --na;
+	      if (na == 0)
+		goto Succeed;
+	      if (acount >= min_gallop)
+		break;
+	    }
+	  else 
+	    {
+	      *dest-- = *pb--;
+	      ++bcount;
+	      acount = 0;
+	      --nb;
+	      if (nb == 1)
+		goto CopyA;
+	      if (bcount >= min_gallop)
+		break;
+	    }
+	}
+
+      /* One run is winning so consistently that galloping may
+       * be a huge win.  So try that, and continue galloping until
+       * (if ever) neither run appears to be winning consistently
+       * anymore.
+       */
+      ++min_gallop;
+      do 
+	{
+	  min_gallop -= min_gallop > 1;
+	  ms->min_gallop = min_gallop;
+	  k = gallop_right (*pb, basea, na, na-1, comp);
+	  if (k < 0)
+	    goto Fail;
+	  k = na - k;
+	  acount = k;
+	  if (k) 
+	    {
+              dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
+	      pa -= k;
+	      na -= k;
+	      if (na == 0)
+		goto Succeed;
+	    }
+	  *dest-- = *pb--;
+	  --nb;
+	  if (nb == 1)
+	    goto CopyA;
+
+	  k = gallop_left (*pa, baseb, nb, nb-1, comp);
+	  if (k < 0)
+	    goto Fail;
+	  k = nb - k;
+	  bcount = k;
+	  if (k) 
+	    {
+	      dest -= k;
+	      pb -= k;
+              std::copy (pb+1, pb+1 + k, dest+1);
+	      nb -= k;
+	      if (nb == 1)
+		goto CopyA;
+	      /* nb==0 is impossible now if the comparison
+	       * function is consistent, but we can't assume
+	       * that it is.
+	       */
+	      if (nb == 0)
+		goto Succeed;
+	    }
+	  *dest-- = *pa--;
+	  --na;
+	  if (na == 0)
+	    goto Succeed;
+	} while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+      ++min_gallop;	/* penalize it for leaving galloping mode */
+      ms->min_gallop = min_gallop;
+    }
+
+Succeed:
+  result = 0;
+
+Fail:
+  if (nb)
+    std::copy (baseb, baseb + nb, dest-(nb-1));
+  return result;
+
+CopyA:
+  /* The first element of pb belongs at the front of the merge. */
+  dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
+  pa -= na;
+  *dest = *pb;
+
+  return 0;
+}
+
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_hi (T *pa, octave_idx_type *ipa, octave_idx_type na, 
+                          T *pb, octave_idx_type *ipb, octave_idx_type nb,
+                          Comp comp)
+{
+  octave_idx_type k;
+  T *dest;
+  octave_idx_type *idest;
+  int result = -1;	/* guilty until proved innocent */
+  T *basea, *baseb;
+  octave_idx_type *ibasea, *ibaseb;
+  octave_idx_type min_gallop = ms->min_gallop;
+
+  ms->getmemi (nb);
+
+  dest = pb + nb - 1;
+  idest = ipb + nb - 1;
+  std::copy (pb, pb + nb, ms->a);
+  std::copy (ipb, ipb + nb, ms->ia);
+  basea = pa; ibasea = ipa;
+  baseb = ms->a; ibaseb = ms->ia;
+  pb = ms->a + nb - 1; ipb = ms->ia + nb - 1;
+  pa += na - 1; ipa += na - 1;
+
+  *dest-- = *pa--; *idest-- = *ipa--;
+  --na;
+  if (na == 0)
+    goto Succeed;
+  if (nb == 1)
+    goto CopyA;
+
+  for (;;) 
+    {
+      octave_idx_type acount = 0;	/* # of times A won in a row */
+      octave_idx_type bcount = 0;	/* # of times B won in a row */
+
+      /* Do the straightforward thing until (if ever) one run
+       * appears to win consistently.
+       */
+      for (;;) 
+	{
+	  if (comp (*pb, *pa))
+	    {
+	      *dest-- = *pa--; *idest-- = *ipa--;
+	      ++acount;
+	      bcount = 0;
+	      --na;
+	      if (na == 0)
+		goto Succeed;
+	      if (acount >= min_gallop)
+		break;
+	    }
+	  else 
+	    {
+	      *dest-- = *pb--; *idest-- = *ipb--;
+	      ++bcount;
+	      acount = 0;
+	      --nb;
+	      if (nb == 1)
+		goto CopyA;
+	      if (bcount >= min_gallop)
+		break;
+	    }
+	}
+
+      /* One run is winning so consistently that galloping may
+       * be a huge win.  So try that, and continue galloping until
+       * (if ever) neither run appears to be winning consistently
+       * anymore.
+       */
+      ++min_gallop;
+      do 
+	{
+	  min_gallop -= min_gallop > 1;
+	  ms->min_gallop = min_gallop;
+	  k = gallop_right (*pb, basea, na, na-1, comp);
+	  if (k < 0)
+	    goto Fail;
+	  k = na - k;
+	  acount = k;
+	  if (k) 
+	    {
+              dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
+              idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1;
+	      pa -= k; ipa -= k;
+	      na -= k;
+	      if (na == 0)
+		goto Succeed;
+	    }
+	  *dest-- = *pb--; *idest-- = *ipb--;
+	  --nb;
+	  if (nb == 1)
+	    goto CopyA;
+
+	  k = gallop_left (*pa, baseb, nb, nb-1, comp);
+	  if (k < 0)
+	    goto Fail;
+	  k = nb - k;
+	  bcount = k;
+	  if (k) 
+	    {
+	      dest -= k; idest -= k;
+	      pb -= k; ipb -= k;
+              std::copy (pb+1, pb+1 + k, dest+1);
+              std::copy (ipb+1, ipb+1 + k, idest+1);
+	      nb -= k;
+	      if (nb == 1)
+		goto CopyA;
+	      /* nb==0 is impossible now if the comparison
+	       * function is consistent, but we can't assume
+	       * that it is.
+	       */
+	      if (nb == 0)
+		goto Succeed;
+	    }
+	  *dest-- = *pa--; *idest-- = *ipa--;
+	  --na;
+	  if (na == 0)
+	    goto Succeed;
+	} while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+      ++min_gallop;	/* penalize it for leaving galloping mode */
+      ms->min_gallop = min_gallop;
+    }
+
+Succeed:
+  result = 0;
+
+Fail:
+  if (nb)
+    {
+      std::copy (baseb, baseb + nb, dest-(nb-1));
+      std::copy (ibaseb, ibaseb + nb, idest-(nb-1));
+    }
+  return result;
+
+CopyA:
+  /* The first element of pb belongs at the front of the merge. */
+  dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
+  idest = std::copy_backward (ipa+1 - na, ipa+1, idest+1) - 1;
+  pa -= na; ipa -= na;
+  *dest = *pb; *idest = *ipb;
+
+  return 0;
+}
+
+/* Merge the two runs at stack indices i and i+1.
+ * Returns 0 on success, -1 on error.
+ */
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_at (octave_idx_type i, T *data,
+                          Comp comp)
+{
+  T *pa, *pb;
+  octave_idx_type na, nb;
+  octave_idx_type k;
+
+  pa = data + ms->pending[i].base;
+  na = ms->pending[i].len;
+  pb = data + ms->pending[i+1].base;
+  nb = ms->pending[i+1].len;
+
+  /* Record the length of the combined runs; if i is the 3rd-last
+   * run now, also slide over the last run (which isn't involved
+   * in this merge).  The current run i+1 goes away in any case.
+   */
+  ms->pending[i].len = na + nb;
+  if (i == ms->n - 3)
+    ms->pending[i+1] = ms->pending[i+2];
+  ms->n--;
+
+  /* Where does b start in a?  Elements in a before that can be
+   * ignored (already in place).
+   */
+  k = gallop_right (*pb, pa, na, 0, comp);
+  if (k < 0)
+    return -1;
+  pa += k;
+  na -= k;
+  if (na == 0)
+    return 0;
+
+  /* Where does a end in b?  Elements in b after that can be
+   * ignored (already in place).
+   */
+  nb = gallop_left (pa[na-1], pb, nb, nb-1, comp);
+  if (nb <= 0)
+    return nb;
+
+  /* Merge what remains of the runs, using a temp array with
+   * min(na, nb) elements.
+   */
+  if (na <= nb)
+    return merge_lo (pa, na, pb, nb, comp);
+  else
+    return merge_hi (pa, na, pb, nb, comp);
+}
+
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_at (octave_idx_type i, T *data, octave_idx_type *idx,
+                          Comp comp)
+{
+  T *pa, *pb;
+  octave_idx_type *ipa, *ipb;
+  octave_idx_type na, nb;
+  octave_idx_type k;
+
+  pa = data + ms->pending[i].base;
+  ipa = idx + ms->pending[i].base;
+  na = ms->pending[i].len;
+  pb = data + ms->pending[i+1].base;
+  ipb = idx + ms->pending[i+1].base;
+  nb = ms->pending[i+1].len;
+
+  /* Record the length of the combined runs; if i is the 3rd-last
+   * run now, also slide over the last run (which isn't involved
+   * in this merge).  The current run i+1 goes away in any case.
+   */
+  ms->pending[i].len = na + nb;
+  if (i == ms->n - 3)
+    ms->pending[i+1] = ms->pending[i+2];
+  ms->n--;
+
+  /* Where does b start in a?  Elements in a before that can be
+   * ignored (already in place).
+   */
+  k = gallop_right (*pb, pa, na, 0, comp);
+  if (k < 0)
+    return -1;
+  pa += k; ipa += k;
+  na -= k;
+  if (na == 0)
+    return 0;
+
+  /* Where does a end in b?  Elements in b after that can be
+   * ignored (already in place).
+   */
+  nb = gallop_left (pa[na-1], pb, nb, nb-1, comp);
+  if (nb <= 0)
+    return nb;
+
+  /* Merge what remains of the runs, using a temp array with
+   * min(na, nb) elements.
+   */
+  if (na <= nb)
+    return merge_lo (pa, ipa, na, pb, ipb, nb, comp);
+  else
+    return merge_hi (pa, ipa, na, pb, ipb, nb, comp);
+}
+
+/* Examine the stack of runs waiting to be merged, merging adjacent runs
+ * until the stack invariants are re-established:
+ *
+ * 1. len[-3] > len[-2] + len[-1]
+ * 2. len[-2] > len[-1]
+ *
+ * See listsort.txt for more info.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_collapse (T *data, Comp comp)
+{
+  struct s_slice *p = ms->pending;
+
+  while (ms->n > 1) 
+    {
+      octave_idx_type n = ms->n - 2;
+      if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) 
+	{
+	  if (p[n-1].len < p[n+1].len)
+	    --n;
+	  if (merge_at (n, data, comp) < 0)
+	    return -1;
+	}
+      else if (p[n].len <= p[n+1].len) 
+	{
+	  if (merge_at (n, data, comp) < 0)
+	    return -1;
+	}
+      else
+	break;
+    }
+
+  return 0;
+}
+
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_collapse (T *data, octave_idx_type *idx, Comp comp)
+{
+  struct s_slice *p = ms->pending;
+
+  while (ms->n > 1) 
+    {
+      octave_idx_type n = ms->n - 2;
+      if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) 
+	{
+	  if (p[n-1].len < p[n+1].len)
+	    --n;
+	  if (merge_at (n, data, idx, comp) < 0)
+	    return -1;
+	}
+      else if (p[n].len <= p[n+1].len) 
+	{
+	  if (merge_at (n, data, idx, comp) < 0)
+	    return -1;
+	}
+      else
+	break;
+    }
+
+  return 0;
+}
+
+/* Regardless of invariants, merge all runs on the stack until only one
+ * remains.  This is used at the end of the mergesort.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_force_collapse (T *data, Comp comp)
+{
+  struct s_slice *p = ms->pending;
+
+  while (ms->n > 1) 
+    {
+      octave_idx_type n = ms->n - 2;
+      if (n > 0 && p[n-1].len < p[n+1].len)
+	--n;
+      if (merge_at (n, data, comp) < 0)
+	return -1;
+    }
+
+  return 0;
+}
+
+template <class T>
+template <class Comp>
+int
+octave_sort<T>::merge_force_collapse (T *data, octave_idx_type *idx, Comp comp)
+{
+  struct s_slice *p = ms->pending;
+
+  while (ms->n > 1) 
+    {
+      octave_idx_type n = ms->n - 2;
+      if (n > 0 && p[n-1].len < p[n+1].len)
+	--n;
+      if (merge_at (n, data, idx, comp) < 0)
+	return -1;
+    }
+
+  return 0;
+}
+
+/* Compute a good value for the minimum run length; natural runs shorter
+ * than this are boosted artificially via binary insertion.
+ *
+ * If n < 64, return n (it's too small to bother with fancy stuff).
+ * Else if n is an exact power of 2, return 32.
+ * Else return an int k, 32 <= k <= 64, such that n/k is close to, but
+ * strictly less than, an exact power of 2.
+ *
+ * See listsort.txt for more info.
+ */
+template <class T>
+octave_idx_type
+octave_sort<T>::merge_compute_minrun (octave_idx_type n)
+{
+  octave_idx_type r = 0;	/* becomes 1 if any 1 bits are shifted off */
+
+  while (n >= 64)
+    {
+      r |= n & 1;
+      n >>= 1;
+    }
+
+  return n + r;
+}
+
+template <class T>
+template <class Comp>
+void
+octave_sort<T>::sort (T *data, octave_idx_type nel, Comp comp)
+{
+  /* Re-initialize the Mergestate as this might be the second time called */
+  if (! ms) ms = new MergeState;
+
+  ms->reset ();
+  ms->getmem (1024);
+
+  if (nel > 1)
+    {
+      octave_idx_type nremaining = nel; 
+      octave_idx_type lo = 0;
+
+      /* March over the array once, left to right, finding natural runs,
+       * and extending short natural runs to minrun elements.
+       */
+      octave_idx_type minrun = merge_compute_minrun (nremaining);
+      do 
+	{
+	  bool descending;
+	  octave_idx_type n;
+
+	  /* Identify next run. */
+	  n = count_run (data + lo, nremaining, descending, comp);
+	  if (n < 0)
+	    goto fail;
+	  if (descending)
+            std::reverse (data + lo, data + lo + n);
+	  /* If short, extend to min(minrun, nremaining). */
+	  if (n < minrun) 
+	    {
+	      const octave_idx_type force = nremaining <= minrun ? nremaining : minrun;
+	      binarysort (data + lo, force, n, comp);
+	      n = force;
+	    }
+	  /* Push run onto pending-runs stack, and maybe merge. */
+	  assert (ms->n < MAX_MERGE_PENDING);
+	  ms->pending[ms->n].base = lo;
+	  ms->pending[ms->n].len = n;
+	  ms->n++;
+	  if (merge_collapse (data, comp) < 0)
+	    goto fail;
+	  /* Advance to find next run. */
+	  lo += n;
+	  nremaining -= n;
+	}
+      while (nremaining);
+
+      merge_force_collapse (data, comp);
+    }
+
+fail:
+  return;
+}
+
+template <class T>
+template <class Comp>
+void
+octave_sort<T>::sort (T *data, octave_idx_type *idx, octave_idx_type nel, 
+                      Comp comp)
+{
+  /* Re-initialize the Mergestate as this might be the second time called */
+  if (! ms) ms = new MergeState;
+
+  ms->reset ();
+  ms->getmemi (1024);
+
+  if (nel > 1)
+    {
+      octave_idx_type nremaining = nel; 
+      octave_idx_type lo = 0;
+
+      /* March over the array once, left to right, finding natural runs,
+       * and extending short natural runs to minrun elements.
+       */
+      octave_idx_type minrun = merge_compute_minrun (nremaining);
+      do 
+	{
+	  bool descending;
+	  octave_idx_type n;
+
+	  /* Identify next run. */
+	  n = count_run (data + lo, nremaining, descending, comp);
+	  if (n < 0)
+	    goto fail;
+	  if (descending)
+            {
+              std::reverse (data + lo, data + lo + n);
+              std::reverse (idx + lo, idx + lo + n);
+            }
+	  /* If short, extend to min(minrun, nremaining). */
+	  if (n < minrun) 
+	    {
+	      const octave_idx_type force = nremaining <= minrun ? nremaining : minrun;
+	      binarysort (data + lo, idx + lo, force, n, comp);
+	      n = force;
+	    }
+	  /* Push run onto pending-runs stack, and maybe merge. */
+	  assert (ms->n < MAX_MERGE_PENDING);
+	  ms->pending[ms->n].base = lo;
+	  ms->pending[ms->n].len = n;
+	  ms->n++;
+	  if (merge_collapse (data, idx, comp) < 0)
+	    goto fail;
+	  /* Advance to find next run. */
+	  lo += n;
+	  nremaining -= n;
+	}
+      while (nremaining);
+
+      merge_force_collapse (data, idx, comp);
+    }
+
+fail:
+  return;
+}
+
+template <class T>
+void
+octave_sort<T>::sort (T *data, octave_idx_type nel)
+{
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    sort (data, nel, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      sort (data, nel, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      sort (data, nel, compare);
+}
+
+template <class T>
+void
+octave_sort<T>::sort (T *data, octave_idx_type *idx, octave_idx_type nel)
+{
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    sort (data, idx, nel, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      sort (data, idx, nel, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      sort (data, idx, nel, compare);
+}
+
+template <class T> template <class Comp>
+bool 
+octave_sort<T>::is_sorted (const T *data, octave_idx_type nel, Comp comp)
+{
+  const T *end = data + nel;
+  if (data != end)
+    {
+      const T *next = data;
+      while (++next != end)
+        {
+          if (comp (*next, *data))
+            break;
+          data = next;
+        }
+      data = next;
+    }
+
+  return data == end;
+}
+
+template <class T> 
+bool 
+octave_sort<T>::is_sorted (const T *data, octave_idx_type nel)
+{
+  bool retval = false;
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    retval = is_sorted (data, nel, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      retval = is_sorted (data, nel, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      retval = is_sorted (data, nel, compare);
+
+  return retval;
+}
+
+// FIXME: is there really no way to make this local to the following function?
+struct sortrows_run_t
+{
+  sortrows_run_t (octave_idx_type c, octave_idx_type o, octave_idx_type n)
+    : col (c), ofs (o), nel (n) { }
+  octave_idx_type col, ofs, nel;
+};
+
+
+template <class T> template <class Comp>
+void 
+octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx,
+                           octave_idx_type rows, octave_idx_type cols,
+                           Comp comp)
+{
+  OCTAVE_LOCAL_BUFFER (T, buf, rows);
+  for (octave_idx_type i = 0; i < rows; i++)
+    idx[i] = i;
+
+  if (cols == 0 || rows <= 1)
+    return;
+
+
+  // This is a breadth-first traversal.
+  typedef sortrows_run_t run_t;
+  std::stack<run_t> runs;
+
+  runs.push (run_t (0, 0, rows));
+
+  while (! runs.empty ())
+    {
+      octave_idx_type col  = runs.top ().col;
+      octave_idx_type ofs  = runs.top ().ofs;
+      octave_idx_type nel  = runs.top ().nel;
+      runs.pop ();
+      assert (nel > 1);
+
+      T *lbuf = buf + ofs;
+      const T *ldata = data + rows*col;
+      octave_idx_type *lidx = idx + ofs;
+
+      // Gather.
+      for (octave_idx_type i = 0; i < nel; i++)
+        lbuf[i] = ldata[lidx[i]];
+
+      // Sort.
+      sort (lbuf, lidx, nel, comp);
+
+      // Identify constant runs and schedule subsorts.
+      if (col < cols-1)
+        {
+          octave_idx_type lst = 0;
+          for (octave_idx_type i = 0; i < nel; i++)
+            {
+              if (comp (lbuf[lst], lbuf[i]))
+                {
+                  if (i > lst + 1)
+                    runs.push (run_t (col+1, ofs + lst, i - lst));
+                  lst = i;
+                }
+            }
+          if (nel > lst + 1)
+            runs.push (run_t (col+1, ofs + lst, nel - lst));
+        }
+    }
+}
+
+template <class T>
+void 
+octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx,
+                           octave_idx_type rows, octave_idx_type cols)
+{
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    sort_rows (data, idx, rows, cols, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      sort_rows (data, idx, rows, cols, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      sort_rows (data, idx, rows, cols, compare);
+}
+
+template <class T> template <class Comp>
+bool 
+octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, 
+                                octave_idx_type cols, Comp comp)
+{
+  if (rows <= 1 || cols == 0)
+    return true;
+    
+  // This is a breadth-first traversal.
+  const T *lastrow = data + rows*(cols - 1);
+  typedef std::pair<const T *, octave_idx_type> run_t;
+  std::stack<run_t> runs;
+
+  bool sorted = true;
+  runs.push (run_t (data, rows));
+  while (sorted && ! runs.empty ())
+    {
+      const T *lo = runs.top ().first;
+      octave_idx_type n = runs.top ().second;
+      runs.pop ();
+      if (lo < lastrow)
+        {
+          // Not the final column.
+          assert (n > 1);
+          const T *hi = lo + n, *lst = lo;
+          for (lo++; lo < hi; lo++)
+            {
+              if (comp (*lst, *lo))
+                {
+                  if (lo > lst + 1)
+                      runs.push (run_t (lst + rows, lo - lst));
+                  lst = lo;
+                }
+              else if (comp (*lo, *lst))
+                break;
+
+            }
+          if (lo == hi)
+            {
+              if (lo > lst + 1)
+                runs.push (run_t (lst + rows, lo - lst));
+            }
+          else
+            {
+              sorted = false;
+              break;
+            }
+        }
+      else
+        // The final column - use fast code.
+        sorted = is_sorted (lo, n, comp);
+    }
+      
+  return sorted;
+}
+
+template <class T>
+bool 
+octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, 
+                                octave_idx_type cols)
+{
+  bool retval = false;
+
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    retval = is_sorted_rows (data, rows, cols, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      retval = is_sorted_rows (data, rows, cols, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      retval = is_sorted_rows (data, rows, cols, compare);
+
+  return retval;
+}
+
+
+template <class T> template <class Comp>
+octave_idx_type 
+octave_sort<T>::lookup (const T *data, octave_idx_type nel,
+                        const T& value, Comp comp)
+{
+  return std::upper_bound (data, data + nel, value, comp) - data;
+}
+
+template <class T>
+octave_idx_type 
+octave_sort<T>::lookup (const T *data, octave_idx_type nel,
+                        const T& value)
+{
+  octave_idx_type retval = 0;
+
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    retval = lookup (data, nel, value, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      retval = lookup (data, nel, value, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      retval = lookup (data, nel, value, std::ptr_fun (compare));
+
+  return retval;
+}
+
+// a unary functor that checks whether a value is outside [a,b) range
+template<class T, class Comp>
+class out_of_range_pred : public std::unary_function<T, bool>
+{
+public:
+  out_of_range_pred (const T& aa, const T& bb, Comp c) 
+    : a (aa), b (bb), comp (c) { }
+  bool operator () (const T& x) { return comp (x, a) || ! comp (x, b); }
+
+private:
+  T a, b;
+  Comp comp;
+};
+
+// a unary functor that checks whether a value is < a
+template<class T, class Comp>
+class less_than_pred : public std::unary_function<T, bool>
+{
+  typedef typename ref_param<T>::type param_type;
+public:
+  less_than_pred (param_type aa, Comp c) 
+    : a (aa), comp (c) { }
+  bool operator () (const T& x) { return comp (x, a); }
+
+private:
+  T a;
+  Comp comp;
+};
+
+// a unary functor that checks whether a value is >= a
+template<class T, class Comp>
+class greater_or_equal_pred : public std::unary_function<T, bool>
+{
+public:
+  greater_or_equal_pred (const T& aa, Comp c) 
+    : a (aa), comp (c) { }
+  bool operator () (const T& x) { return ! comp (x, a); }
+
+private:
+  T a;
+  Comp comp;
+};
+
+// conveniently constructs the above functors.
+// NOTE: with SGI extensions, this one can be written as
+// compose2 (logical_and<bool>(), bind2nd (less<T>(), a),
+//           not1 (bind2nd (less<T>(), b)))
+template<class T, class Comp>
+inline out_of_range_pred<T, Comp> 
+out_of_range (const T& a, 
+              const T& b, Comp comp)
+{
+  return out_of_range_pred<T, Comp> (a, b, comp);
+}
+
+// Note: these could be written as
+//    std::not1 (std::bind2nd (comp, *cur))
+// and
+//    std::bind2nd (comp, *(cur-1)));
+// but that doesn't work for functions with reference parameters in g++ 4.3.
+template<class T, class Comp>
+inline less_than_pred<T, Comp> 
+less_than (const T& a, Comp comp)
+{
+  return less_than_pred<T, Comp> (a, comp);
+}
+template<class T, class Comp>
+inline greater_or_equal_pred<T, Comp> 
+greater_or_equal (const T& a, Comp comp)
+{
+  return greater_or_equal_pred<T, Comp> (a, comp);
+}
+
+
+template <class T> template <class Comp>
+void 
+octave_sort<T>::lookup (const T *data, octave_idx_type nel,
+                        const T *values, octave_idx_type nvalues,
+                        octave_idx_type *idx, octave_idx_type offset, Comp comp)
+{
+  if (nel == 0)
+    // the trivial case of empty table
+    std::fill_n (idx, nvalues, offset);
+  else
+    {
+      const T *vcur = values;
+      const T *vend = values + nvalues;
+
+      const T *cur = data;
+      const T *end = data + nel;
+
+      while (vcur != vend)
+        {
+          // determine the enclosing interval for next value, trying
+          // ++cur as a special case;
+          if (cur == end || comp (*vcur, *cur))
+            cur = std::upper_bound (data, cur, *vcur, comp);
+          else
+            {
+              ++cur;
+              if (cur != end && ! comp (*vcur, *cur))
+                cur = std::upper_bound (cur + 1, end, *vcur, comp);
+            }
+
+          octave_idx_type vidx = cur - data + offset;
+          // store index of the current interval.
+          *(idx++) = vidx;
+          ++vcur;
+
+          // find first value not in current subrange
+          const T *vnew;
+          if (cur != end)
+            if (cur != data)
+              // inner interval
+              vnew = std::find_if (vcur, vend,
+                                   out_of_range (*(cur-1), *cur, comp));
+            else
+              // special case: lowermost range (-Inf, min) 
+              vnew = std::find_if (vcur, vend, greater_or_equal (*cur, comp));
+          else
+            // special case: uppermost range [max, Inf)
+            vnew = std::find_if (vcur, vend, less_than (*(cur-1), comp));
+
+          // store index of the current interval.
+          std::fill_n (idx, vnew - vcur, vidx);
+          idx += (vnew - vcur);
+          vcur = vnew;
+        }
+    }
+}
+
+template <class T>
+void 
+octave_sort<T>::lookup (const T *data, octave_idx_type nel,
+                        const T* values, octave_idx_type nvalues,
+                        octave_idx_type *idx, octave_idx_type offset)
+{
+#ifdef INLINE_ASCENDING_SORT
+  if (compare == ascending_compare)
+    lookup (data, nel, values, nvalues, idx, offset, std::less<T> ());
+  else
+#endif
+#ifdef INLINE_DESCENDING_SORT    
+    if (compare == descending_compare)
+      lookup (data, nel, values, nvalues, idx, offset, std::greater<T> ());
+  else
+#endif
+    if (compare)
+      lookup (data, nel, values, nvalues, idx, offset, std::ptr_fun (compare));
+}
+
+template <class T>
+bool 
+octave_sort<T>::ascending_compare (typename ref_param<T>::type x,
+				   typename ref_param<T>::type y)
+{
+  return x < y;
+}
+
+template <class T>
+bool 
+octave_sort<T>::descending_compare (typename ref_param<T>::type x,
+				    typename ref_param<T>::type y)
+{
+  return x > y;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-sort.h b/liboctave/oct-sort.h
new file mode 100644
index 0000000..69a17f2
--- /dev/null
+++ b/liboctave/oct-sort.h
@@ -0,0 +1,321 @@
+/*
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+Code stolen in large part from Python's, listobject.c, which itself had
+no license header. However, thanks to Tim Peters for the parts of the
+code I ripped-off.
+
+As required in the Python license the short description of the changes
+made are
+
+* convert the sorting code in listobject.cc into a generic class, 
+  replacing PyObject* with the type of the class T.
+
+The Python license is
+
+  PSF LICENSE AGREEMENT FOR PYTHON 2.3
+  --------------------------------------
+
+  1. This LICENSE AGREEMENT is between the Python Software Foundation
+  ("PSF"), and the Individual or Organization ("Licensee") accessing and
+  otherwise using Python 2.3 software in source or binary form and its
+  associated documentation.
+
+  2. Subject to the terms and conditions of this License Agreement, PSF
+  hereby grants Licensee a nonexclusive, royalty-free, world-wide
+  license to reproduce, analyze, test, perform and/or display publicly,
+  prepare derivative works, distribute, and otherwise use Python 2.3
+  alone or in any derivative version, provided, however, that PSF's
+  License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+  2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are
+  retained in Python 2.3 alone or in any derivative version prepared by
+  Licensee.
+
+  3. In the event Licensee prepares a derivative work that is based on
+  or incorporates Python 2.3 or any part thereof, and wants to make
+  the derivative work available to others as provided herein, then
+  Licensee hereby agrees to include in any such work a brief summary of
+  the changes made to Python 2.3.
+
+  4. PSF is making Python 2.3 available to Licensee on an "AS IS"
+  basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+  IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+  DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+  FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
+  INFRINGE ANY THIRD PARTY RIGHTS.
+
+  5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+  2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+  A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
+  OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+  6. This License Agreement will automatically terminate upon a material
+  breach of its terms and conditions.
+
+  7. Nothing in this License Agreement shall be deemed to create any
+  relationship of agency, partnership, or joint venture between PSF and
+  Licensee.  This License Agreement does not grant permission to use PSF
+  trademarks or trade name in a trademark sense to endorse or promote
+  products or services of Licensee, or any third party.
+
+  8. By copying, installing or otherwise using Python 2.3, Licensee
+  agrees to be bound by the terms and conditions of this License
+  Agreement.
+*/
+
+#if !defined (octave_sort_h)
+#define octave_sort_h 1
+
+#include "lo-traits.h"
+
+// The maximum number of entries in a MergeState's pending-runs stack.
+// This is enough to sort arrays of size up to about
+//     32 * phi ** MAX_MERGE_PENDING
+// where phi ~= 1.618.  85 is ridiculously large enough, good for an array
+// with 2**64 elements.
+#define MAX_MERGE_PENDING 85
+
+// When we get into galloping mode, we stay there until both runs win less
+// often than MIN_GALLOP consecutive times.  See listsort.txt for more info.
+#define MIN_GALLOP 7
+
+// Avoid malloc for small temp arrays.
+#define MERGESTATE_TEMP_SIZE 1024
+
+// Enum for type of sort function
+enum sortmode { UNSORTED = 0, ASCENDING, DESCENDING };
+
+template <class T>
+class
+octave_sort
+{
+public:
+
+  typedef bool (*compare_fcn_type) (typename ref_param<T>::type,
+				    typename ref_param<T>::type);
+
+  octave_sort (void);
+
+  octave_sort (compare_fcn_type);
+  
+  ~octave_sort (void); 
+
+  void set_compare (compare_fcn_type comp) { compare = comp; }
+
+  void set_compare (sortmode mode);
+
+  // Sort an array in-place.
+  void sort (T *data, octave_idx_type nel);
+
+  // Ditto, but also permute the passed indices (may not be valid indices).
+  void sort (T *data, octave_idx_type *idx, octave_idx_type nel);
+
+  // Check whether an array is sorted.
+  bool is_sorted (const T *data, octave_idx_type nel);
+
+  // Sort a matrix by rows, return a permutation
+  // vector.
+  void sort_rows (const T *data, octave_idx_type *idx,
+                  octave_idx_type rows, octave_idx_type cols);
+
+  // Determine whether a matrix (as a contiguous block) is sorted by rows.
+  bool is_sorted_rows (const T *data, 
+                       octave_idx_type rows, octave_idx_type cols);
+
+  // Do a binary lookup in a sorted array.
+  octave_idx_type lookup (const T *data, octave_idx_type nel,
+                          const T& value);
+
+  // Ditto, but for an array of values, specializing on long runs.
+  // Adds offset to all indices.
+  void lookup (const T *data, octave_idx_type nel,
+               const T* values, octave_idx_type nvalues,
+               octave_idx_type *idx, octave_idx_type offset = 0);
+
+  static bool ascending_compare (typename ref_param<T>::type,
+				 typename ref_param<T>::type);
+
+  static bool descending_compare (typename ref_param<T>::type,
+				  typename ref_param<T>::type);
+
+private:
+
+  // One MergeState exists on the stack per invocation of mergesort.
+  // It's just a convenient way to pass state around among the helper
+  // functions.
+  //
+  // DGB: This isn't needed with mergesort in a class, but it doesn't
+  // slow things up, and it is likely to make my life easier for any
+  // potential backporting of changes in the Python code.
+  
+  struct s_slice 
+  {
+    octave_idx_type base, len;
+  };
+  
+  struct MergeState 
+  {
+    MergeState (void) 
+      : a (0), ia (0), alloced (0) 
+      { reset (); }
+    
+    ~MergeState (void) 
+      { delete [] a; delete [] ia; }
+    
+    void reset (void) 
+      { min_gallop = MIN_GALLOP; n = 0; }
+
+    void getmem (octave_idx_type need);
+
+    void getmemi (octave_idx_type need);
+
+    // This controls when we get *into* galloping mode.  It's
+    // initialized to MIN_GALLOP.  merge_lo and merge_hi tend to nudge
+    // it higher for random data, and lower for highly structured
+    // data.
+    octave_idx_type min_gallop;
+
+    // 'a' is temp storage to help with merges.  It contains room for
+    // alloced entries.
+    T *a;               // may point to temparray below
+    octave_idx_type *ia;
+    octave_idx_type alloced;
+    
+    // A stack of n pending runs yet to be merged.  Run #i starts at
+    // address base[i] and extends for len[i] elements.  It's always
+    // true (so long as the indices are in bounds) that
+    //
+    //   pending[i].base + pending[i].len == pending[i+1].base
+    //
+    // so we could cut the storage for this, but it's a minor amount,
+    // and keeping all the info explicit simplifies the code.
+    octave_idx_type n;
+    struct s_slice pending[MAX_MERGE_PENDING];
+  };
+
+  compare_fcn_type compare;
+  
+  MergeState *ms;
+  
+    
+  template <class Comp>
+  void binarysort (T *data, octave_idx_type nel, 
+              octave_idx_type start, Comp comp);
+    
+  template <class Comp>
+  void binarysort (T *data, octave_idx_type *idx, octave_idx_type nel, 
+              octave_idx_type start, Comp comp);
+    
+  template <class Comp>
+  octave_idx_type count_run (T *lo, octave_idx_type n, bool& descending, Comp comp);
+
+  template <class Comp>
+  octave_idx_type gallop_left (T key, T *a, octave_idx_type n, octave_idx_type hint,
+                               Comp comp);
+
+  template <class Comp>
+  octave_idx_type gallop_right (T key, T *a, octave_idx_type n, octave_idx_type hint,
+                                Comp comp);
+
+  template <class Comp>
+  int merge_lo (T *pa, octave_idx_type na, 
+                T *pb, octave_idx_type nb,
+                Comp comp);
+
+  template <class Comp>
+  int merge_lo (T *pa, octave_idx_type *ipa, octave_idx_type na, 
+                T *pb, octave_idx_type *ipb, octave_idx_type nb,
+                Comp comp);
+
+  template <class Comp>
+  int merge_hi (T *pa, octave_idx_type na, 
+                T *pb, octave_idx_type nb,
+                Comp comp);
+
+  template <class Comp>
+  int merge_hi (T *pa, octave_idx_type *ipa, octave_idx_type na, 
+                T *pb, octave_idx_type *ipb, octave_idx_type nb,
+                Comp comp);
+
+  template <class Comp>
+  int merge_at (octave_idx_type i, T *data,
+                Comp comp);
+
+  template <class Comp>
+  int merge_at (octave_idx_type i, T *data, octave_idx_type *idx,
+                Comp comp);
+
+  template <class Comp>
+  int merge_collapse (T *data, Comp comp);
+
+  template <class Comp>
+  int merge_collapse (T *data, octave_idx_type *idx, Comp comp);
+
+  template <class Comp>
+  int merge_force_collapse (T *data, Comp comp);
+
+  template <class Comp>
+  int merge_force_collapse (T *data, octave_idx_type *idx, Comp comp);
+
+  octave_idx_type merge_compute_minrun (octave_idx_type n);
+
+  template <class Comp>
+  void sort (T *data, octave_idx_type nel, Comp comp);
+
+  template <class Comp>
+  void sort (T *data, octave_idx_type *idx, octave_idx_type nel, Comp comp);
+
+  template <class Comp>
+  bool is_sorted (const T *data, octave_idx_type nel, Comp comp);
+
+  template <class Comp>
+  void sort_rows (const T *data, octave_idx_type *idx,
+                  octave_idx_type rows, octave_idx_type cols,
+                  Comp comp);
+
+  template <class Comp>
+  bool is_sorted_rows (const T *data, octave_idx_type rows, 
+                       octave_idx_type cols, Comp comp);
+
+  template <class Comp>
+  octave_idx_type lookup (const T *data, octave_idx_type nel,
+                          const T& value, Comp comp);
+
+  template <class Comp>
+  void lookup (const T *data, octave_idx_type nel,
+               const T* values, octave_idx_type nvalues,
+               octave_idx_type *idx, octave_idx_type offset, Comp comp);
+
+};
+
+template <class T>
+class
+vec_index
+{
+public:
+  T vec;
+  octave_idx_type indx;
+};
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-sparse.h b/liboctave/oct-sparse.h
new file mode 100644
index 0000000..f97adf0
--- /dev/null
+++ b/liboctave/oct-sparse.h
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (oct_sparse_h)
+#define oct_sparse_h 1
+
+#if defined (HAVE_SUITESPARSE_AMD_H)
+#include <suitesparse/amd.h>
+#elif defined (HAVE_UFSPARSE_AMD_H)
+#include <ufsparse/amd.h>
+#elif defined (HAVE_AMD_AMD_H)
+#include <amd/amd.h>
+#elif defined (HAVE_AMD_H)
+#include <amd.h>
+#endif
+
+#if defined (HAVE_SUITESPARSE_UMFPACK_H)
+#include <suitesparse/umfpack.h>
+#elif defined (HAVE_UFSPARSE_UMFPACK_H)
+#include <ufsparse/umfpack.h>
+#elif defined (HAVE_UMFPACK_UMFPACK_H)
+#include <umfpack/umfpack.h>
+#elif defined (HAVE_UMFPACK_H)
+#include <umfpack.h>
+#endif
+
+#if defined (HAVE_SUITESPARSE_COLAMD_H)
+#include <suitesparse/colamd.h>
+#elif defined (HAVE_UFSPARSE_COLAMD_H)
+#include <ufsparse/colamd.h>
+#elif defined (HAVE_COLAMD_COLAMD_H)
+#include <colamd/colamd.h>
+#elif defined (HAVE_COLAMD_H)
+#include <colamd.h>
+#endif
+
+#if defined (HAVE_SUITESPARSE_CCOLAMD_H)
+#include <suitesparse/ccolamd.h>
+#elif defined (HAVE_UFSPARSE_CCOLAMD_H)
+#include <ufsparse/ccolamd.h>
+#elif defined (HAVE_CCOLAMD_CCOLAMD_H)
+#include <ccolamd/ccolamd.h>
+#elif defined (HAVE_CCOLAMD_H)
+#include <ccolamd.h>
+#endif
+
+#if defined (HAVE_SUITESPARSE_CHOLMOD_H)
+#include <suitesparse/cholmod.h>
+#elif defined (HAVE_UFSPARSE_CHOLMOD_H)
+#include <ufsparse/cholmod.h>
+#elif defined (HAVE_CHOLMOD_CHOLMOD_H)
+#include <cholmod/cholmod.h>
+#elif defined (HAVE_CHOLMOD_H)
+#include <cholmod.h>
+#endif
+
+#if defined (HAVE_SUITESPARSE_CS_H)
+#include <suitesparse/cs.h>
+#elif defined (HAVE_UFSPARSE_CS_H)
+#include <ufsparse/cs.h>
+#elif defined (HAVE_CXSPARSE_CS_H)
+#include <cxsparse/cs.h>
+#elif defined (HAVE_CS_H)
+#include <cs.h>
+#endif
+
+#if (defined (HAVE_SUITESPARSE_CHOLMOD_H) \
+     || defined (HAVE_UFSPARSE_CHOLMOD_H) \
+     || defined (HAVE_CHOLMOD_CHOLMOD_H) \
+     || defined (HAVE_CHOLMOD_H))
+#ifdef IDX_TYPE_LONG
+#define CHOLMOD_NAME(name) cholmod_l_ ## name
+#else
+#define CHOLMOD_NAME(name) cholmod_ ## name
+#endif
+#endif
+
+#endif
diff --git a/liboctave/oct-spparms.cc b/liboctave/oct-spparms.cc
new file mode 100644
index 0000000..34a0311
--- /dev/null
+++ b/liboctave/oct-spparms.cc
@@ -0,0 +1,231 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-error.h"
+#include "lo-ieee.h"
+
+#include "oct-spparms.h"
+
+octave_sparse_params *octave_sparse_params::instance = 0;
+
+bool
+octave_sparse_params::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_sparse_params ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create octave_sparse_params object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+octave_sparse_params::defaults (void)
+{
+  if (instance_ok ())
+    instance->do_defaults ();
+}
+
+void
+octave_sparse_params::tight (void)
+{
+  if (instance_ok ())
+    instance->do_tight ();
+}
+
+string_vector
+octave_sparse_params::get_keys (void)
+{
+  return instance_ok () ? instance->do_get_keys () : string_vector ();
+}
+
+ColumnVector
+octave_sparse_params::get_vals (void)
+{
+  return instance_ok () ? instance->do_get_vals () : ColumnVector ();
+}
+
+bool
+octave_sparse_params::set_vals (const NDArray& vals)
+{
+  return instance_ok () ? instance->do_set_vals (vals) : false;
+}
+
+bool
+octave_sparse_params::set_key (const std::string& key, const double& val)
+{
+  return instance_ok () ? instance->do_set_key (key, val) : false;
+}
+
+double
+octave_sparse_params::get_key (const std::string& key)
+{
+  return instance_ok () ? instance->do_get_key (key) : octave_NaN;
+}
+
+double
+octave_sparse_params::get_bandden (void)
+{
+  return instance_ok () ? instance->do_get_bandden () : 0.0;
+}
+
+void
+octave_sparse_params::print_info (std::ostream& os, const std::string& prefix)
+{
+  if (instance_ok ())
+    instance->do_print_info (os, prefix);
+}
+
+void
+octave_sparse_params::do_defaults (void)
+{
+  params(0) = 0;      // spumoni
+  params(1) = 1;      // ths_rel
+  params(2) = 1;      // ths_abs
+  params(3) = 0;      // exact_d
+  params(4) = 3;      // supernd
+  params(5) = 3;      // rreduce
+  params(6) = 0.5;    // wh_frac
+  params(7) = 1;      // autommd
+  params(8) = 1;      // autoamd
+  params(9) = 0.1;    // piv_tol
+  params(10) = 0.5;   // bandden
+  params(11) = 1;     // umfpack
+  params(12) = 0.001; // sym_tol
+}
+
+void
+octave_sparse_params::do_tight (void)
+{
+  params(0) = 0;      // spumoni
+  params(1) = 1;      // ths_rel
+  params(2) = 0;      // ths_abs
+  params(3) = 1;      // exact_d
+  params(4) = 1;      // supernd
+  params(5) = 1;      // rreduce
+  params(6) = 0.5;    // wh_frac
+  params(7) = 1;      // autommd
+  params(8) = 1;      // autoamd
+  params(9) = 0.1;    // piv_tol
+  params(10) = 0.5;   // bandden
+  params(11) = 1;     // umfpack
+  params(12) = 0.001; // sym_tol
+}
+  
+void
+octave_sparse_params::init_keys (void)
+{
+  keys(0) = "spumoni";
+  keys(1) = "ths_rel";
+  keys(2) = "ths_abs";
+  keys(3) = "exact_d";
+  keys(4) = "supernd";
+  keys(5) = "rreduce";
+  keys(6) = "wh_frac";
+  keys(7) = "autommd";
+  keys(8) = "autoamd";
+  keys(9) = "piv_tol";
+  keys(10) = "bandden";
+  keys(11) = "umfpack";
+  keys(12) = "sym_tol";
+}
+
+double
+octave_sparse_params::do_get_bandden (void)
+{
+  return params(10);
+}
+
+bool
+octave_sparse_params::do_set_vals (const NDArray& vals)
+{
+  octave_idx_type len = vals.length ();
+
+  if (len > OCTAVE_SPARSE_CONTROLS_SIZE)
+    {
+      (*current_liboctave_error_handler)
+	("octave_sparse_params::do_set_vals: too many values");
+
+      return false;
+    }
+  else
+    {
+      for (int i = 0; i < len; i++)
+	params(i) = vals(i);
+
+      return true;
+    }
+}
+
+bool
+octave_sparse_params::do_set_key (const std::string& key, const double& val)
+{
+  for (int i = 0; i < OCTAVE_SPARSE_CONTROLS_SIZE; i++)
+    {
+      if (keys (i) == key)
+	{
+	  params(i) = val;
+	  return true;
+	}
+    }
+
+  return false;
+}
+
+double
+octave_sparse_params::do_get_key (const std::string& key)
+{
+  for (int i = 0; i < OCTAVE_SPARSE_CONTROLS_SIZE; i++)
+    {
+      if (keys (i) == key)
+	return params(i);
+    }
+
+  return octave_NaN;
+}
+
+void
+octave_sparse_params::do_print_info (std::ostream& os,
+				     const std::string& prefix) const
+{
+  for (int i = 0; i < OCTAVE_SPARSE_CONTROLS_SIZE; i++)
+    os << prefix << keys(i) << ": " << params(i) << "\n";
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-spparms.h b/liboctave/oct-spparms.h
new file mode 100644
index 0000000..c230a7f
--- /dev/null
+++ b/liboctave/oct-spparms.h
@@ -0,0 +1,125 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_spparms_h)
+#define octave_oct_spparms_h 1
+
+#include <cassert>
+#include <cstddef>
+
+#include <iosfwd>
+
+#include "str-vec.h"
+#include "dColVector.h"
+#include "dNDArray.h"
+
+#define OCTAVE_SPARSE_CONTROLS_SIZE 13
+
+class
+OCTAVE_API
+octave_sparse_params
+{
+protected:
+
+  octave_sparse_params (void)
+    : params (OCTAVE_SPARSE_CONTROLS_SIZE),
+      keys (OCTAVE_SPARSE_CONTROLS_SIZE) 
+  {
+    init_keys ();
+    do_defaults ();
+  }
+
+public:
+
+  octave_sparse_params (const octave_sparse_params& a)
+    : params (a.params), keys (a.keys) { }
+
+  octave_sparse_params& operator = (const octave_sparse_params& a)
+  {
+    if (&a != this)
+      {
+	params = a.params;
+	keys = a.keys;
+      }
+    
+    return *this;
+  }
+
+  ~octave_sparse_params (void) { }
+
+  static bool instance_ok (void);
+
+  static void defaults (void);
+
+  static void tight (void);
+  
+  static string_vector get_keys (void);
+
+  static ColumnVector get_vals (void);
+
+  static bool set_vals (const NDArray& vals);
+
+  static bool set_key (const std::string& key, const double& val);
+
+  static double get_key (const std::string& key);
+
+  static double get_bandden (void);
+
+  static void print_info (std::ostream& os, const std::string& prefix);
+
+private:
+
+  ColumnVector params;
+
+  string_vector keys;
+
+  static octave_sparse_params *instance;
+
+  void do_defaults (void);
+
+  void do_tight (void);
+  
+  string_vector do_get_keys (void) const { return keys; }
+
+  ColumnVector do_get_vals (void) const { return params; }
+
+  bool do_set_vals (const NDArray& vals);
+
+  bool do_set_key (const std::string& key, const double& val);
+
+  double do_get_key (const std::string& key);
+
+  double do_get_bandden (void);
+
+  void do_print_info (std::ostream& os, const std::string& prefix) const;
+  
+  void init_keys (void);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-syscalls.cc b/liboctave/oct-syscalls.cc
new file mode 100644
index 0000000..16a4217
--- /dev/null
+++ b/liboctave/oct-syscalls.cc
@@ -0,0 +1,459 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstdlib>
+
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+// We can't use csignal as kill is not in the std namespace, and picky
+// compiler runtimes will also exclude it from global scope as well.
+
+#include <signal.h>
+
+#include "lo-utils.h"
+#include "lo-sysdep.h"
+#include "oct-syscalls.h"
+#include "str-vec.h"
+
+#define NOT_SUPPORTED(nm) \
+  nm ": not supported on this system"
+
+int
+octave_syscalls::dup2 (int old_fd, int new_fd)
+{
+  std::string msg;
+  return dup2 (old_fd, new_fd, msg);
+}
+
+int
+octave_syscalls::dup2 (int old_fd, int new_fd, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_DUP2)
+  status = ::dup2 (old_fd, new_fd);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("dup2");
+#endif
+
+  return status;
+}
+
+int
+octave_syscalls::execvp (const std::string& file, const string_vector& argv)
+{
+  std::string msg;
+  return execvp (file, argv, msg);
+}
+
+int
+octave_syscalls::execvp (const std::string& file, const string_vector& args,
+			 std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_EXECVP)
+  char **argv = args.c_str_vec ();
+
+  status = ::execvp (file.c_str (), argv);
+
+  string_vector::delete_c_str_vec (argv);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("execvp");
+#endif
+
+  return status;
+}
+
+int
+octave_syscalls::fcntl (int fd, int cmd, long arg)
+{
+  std::string msg;
+  return fcntl (fd, cmd, arg, msg);
+}
+
+int
+octave_syscalls::fcntl (int fd, int cmd, long arg, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_FCNTL)
+  status = ::fcntl (fd, cmd, arg);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("fcntl");
+#endif
+
+  return status;
+}
+
+pid_t
+octave_syscalls::fork (std::string& msg)
+{
+  pid_t status = -1;
+
+#if defined (HAVE_FORK)
+  status = ::fork ();
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("fork");
+#endif
+
+  return status;
+}
+
+pid_t
+octave_syscalls::vfork (std::string& msg)
+{
+  pid_t status = -1;
+
+#if defined (HAVE_VFORK) || defined (HAVE_FORK)
+#if defined (HAVE_VFORK)
+  status = ::vfork ();
+#else
+  status = ::fork ();
+#endif
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("vfork");
+#endif
+
+  return status;
+}
+
+pid_t
+octave_syscalls::getpgrp (std::string& msg)
+{
+  pid_t status = -1;
+
+#if defined (HAVE_GETPGRP)
+  status = ::getpgrp ();
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("getpgrp");
+#endif
+
+  return status;
+}
+
+pid_t
+octave_syscalls::getpid (void)
+{
+#if defined (HAVE_GETPID)
+  return ::getpid ();
+#else
+  return 0;
+#endif
+}
+
+pid_t
+octave_syscalls::getppid (void)
+{
+#if defined (HAVE_GETPPID)
+  return ::getppid ();
+#else
+  return 0;
+#endif
+}
+
+gid_t
+octave_syscalls::getgid (void)
+{
+#if defined (HAVE_GETGID)
+  return ::getgid ();
+#else
+  return 0;
+#endif
+}
+
+gid_t
+octave_syscalls::getegid (void)
+{
+#if defined (HAVE_GETEGID)
+  return ::getegid ();
+#else
+  return 0;
+#endif
+}
+
+uid_t
+octave_syscalls::getuid (void)
+{
+#if defined (HAVE_GETUID)
+  return ::getuid ();
+#else
+  return 0;
+#endif
+}
+
+uid_t
+octave_syscalls::geteuid (void)
+{
+#if defined (HAVE_GETEUID)
+  return ::geteuid ();
+#else
+  return 0;
+#endif
+}
+
+int
+octave_syscalls::pipe (int *fildes)
+{
+  std::string msg;
+  return pipe (fildes, msg);
+}
+
+int
+octave_syscalls::pipe (int *fildes, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_PIPE)
+  status = ::pipe (fildes);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("pipe");
+#endif
+
+  return status;
+}
+
+pid_t
+octave_syscalls::waitpid (pid_t pid, int *status, int options)
+{
+  std::string msg;
+  return waitpid (pid, status, options, msg);
+}
+
+pid_t
+octave_syscalls::waitpid (pid_t pid, int *status, int options,
+			  std::string& msg)
+{
+  pid_t retval = -1;
+  msg = std::string ();
+
+#if defined (HAVE_WAITPID)
+  retval = ::octave_waitpid (pid, status, options);
+
+  if (retval < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("waitpid");
+#endif
+
+  return retval;
+}
+
+int
+octave_syscalls::kill (pid_t pid, int sig)
+{
+  std::string msg;
+  return kill (pid, sig, msg);
+}
+
+int
+octave_syscalls::kill (pid_t pid, int sig, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+#if defined (HAVE_KILL)
+  status = ::kill (pid, sig);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+#else
+  msg = NOT_SUPPORTED ("kill");
+#endif
+
+  return status;
+}
+
+pid_t
+octave_syscalls::popen2 (const std::string& cmd, const string_vector& args,
+    bool sync_mode, int *fildes)
+{
+  std::string msg;
+  bool interactive = false;
+  return popen2 (cmd, args, sync_mode, fildes, msg, interactive);
+}
+
+pid_t
+octave_syscalls::popen2 (const std::string& cmd, const string_vector& args,
+    bool sync_mode, int *fildes, std::string& msg)
+{
+  bool interactive = false;
+  return popen2 (cmd, args, sync_mode, fildes, msg, interactive);
+}
+
+pid_t
+octave_syscalls::popen2 (const std::string& cmd, const string_vector& args,
+    bool sync_mode, int *fildes, std::string& msg, bool &interactive)
+{
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+  return ::octave_popen2 (cmd, args, sync_mode, fildes, msg);
+#else
+  pid_t pid;
+  int child_stdin[2], child_stdout[2];
+
+  if (pipe (child_stdin, msg) == 0)
+    {
+      if (pipe (child_stdout, msg) == 0)
+        {
+          pid = fork (msg);
+          if (pid < 0)
+            msg = "popen2: process creation failed -- " + msg;
+          else if (pid == 0)
+            {
+	      std::string child_msg;
+
+	      interactive = false;
+
+              // Child process
+              ::close (child_stdin[1]);
+              ::close (child_stdout[0]);
+
+              if (dup2 (child_stdin[0], STDIN_FILENO) >= 0)
+                {
+                  ::close (child_stdin[0]);
+                  if (dup2 (child_stdout[1], STDOUT_FILENO) >= 0)
+                    {
+                      ::close (child_stdout[1]);
+                      if (execvp (cmd, args, child_msg) < 0)
+                        child_msg = "popen2 (child): unable to start process -- " + child_msg;
+                    }
+                  else
+                    child_msg = "popen2 (child): file handle duplication failed -- " + child_msg;
+                }
+              else
+                child_msg = "popen2 (child): file handle duplication failed -- " + child_msg;
+	      
+	      (*current_liboctave_error_handler)(child_msg.c_str());
+	      
+	      exit(0);
+            }
+          else
+            {
+              // Parent process
+              ::close (child_stdin[0]);
+              ::close (child_stdout[1]);
+#if defined (F_SETFL) && defined (O_NONBLOCK)
+              if (! sync_mode && fcntl (child_stdout[0], F_SETFL, O_NONBLOCK, msg) < 0)
+                msg = "popen2: error setting file mode -- " + msg;
+              else
+#endif
+                {
+                  fildes[0] = child_stdin [1];
+                  fildes[1] = child_stdout [0];
+                  return pid;
+                }
+            }
+          ::close (child_stdout[0]);
+          ::close (child_stdout[1]);
+        }
+      else
+        msg = "popen2: pipe creation failed -- " + msg;
+      ::close (child_stdin[0]);
+      ::close (child_stdin[1]);
+    }
+  else
+    msg = "popen2: pipe creation failed -- " + msg;
+
+  return -1;
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-syscalls.h b/liboctave/oct-syscalls.h
new file mode 100644
index 0000000..9104e8f
--- /dev/null
+++ b/liboctave/oct-syscalls.h
@@ -0,0 +1,82 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2003, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_syscalls_h)
+#define octave_syscalls_h 1
+
+#include <string>
+
+class string_vector;
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+struct
+OCTAVE_API
+octave_syscalls
+{
+  static int dup2 (int, int);
+  static int dup2 (int, int, std::string&);
+
+  static int execvp (const std::string&, const string_vector&);
+  static int execvp (const std::string&, const string_vector&, std::string&);
+
+  static int fcntl (int, int, long);
+  static int fcntl (int, int, long, std::string&);
+
+  static pid_t fork (std::string&);
+  static pid_t vfork (std::string&);
+
+  static pid_t getpgrp (std::string&);
+
+  static pid_t getpid (void);
+  static pid_t getppid (void);
+
+  static gid_t getgid (void);
+  static gid_t getegid (void);
+
+  static uid_t getuid (void);
+  static uid_t geteuid (void);
+
+  static int pipe (int *);
+  static int pipe (int *, std::string&);
+
+  static pid_t waitpid (pid_t, int *status, int);
+  static pid_t waitpid (pid_t, int *status, int, std::string&);
+
+  static int kill (pid_t, int);
+  static int kill (pid_t, int, std::string&);
+
+  static pid_t popen2 (const std::string&, const string_vector&, bool, int *);
+  static pid_t popen2 (const std::string&, const string_vector&, bool, int *, std::string&);
+  static pid_t popen2 (const std::string&, const string_vector&, bool, int *, std::string&, bool &interactive);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-time.cc b/liboctave/oct-time.cc
new file mode 100644
index 0000000..32b84ae
--- /dev/null
+++ b/liboctave/oct-time.cc
@@ -0,0 +1,394 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+#include <ctime>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#if defined (OCTAVE_USE_WINDOWS_API)
+#include <windows.h>
+#undef min
+#undef max
+#endif
+
+#include "lo-error.h"
+#include "lo-math.h"
+#include "lo-utils.h"
+#include "oct-time.h"
+
+#ifndef HAVE_STRFTIME
+// Override any previous definition and use local version.
+extern "C" size_t
+strftime (char *s, size_t maxsize, const char *format, const struct tm *tp);
+#endif
+
+octave_time::octave_time (const octave_base_tm& tm)
+{
+  struct tm t;
+  
+  t.tm_sec = tm.sec ();
+  t.tm_min = tm.min ();
+  t.tm_hour = tm.hour ();
+  t.tm_mday = tm.mday ();
+  t.tm_mon = tm.mon ();
+  t.tm_year = tm.year ();
+  t.tm_wday = tm.wday ();
+  t.tm_yday = tm.yday ();
+  t.tm_isdst = tm.isdst ();
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+  std::string s = tm.zone ();
+  char *ps = strsave (s.c_str ());
+  t.tm_zone = ps;
+#endif
+
+  ot_unix_time = mktime (&t);
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+  delete [] ps;
+#endif
+
+  ot_usec = tm.usec ();
+}
+
+std::string
+octave_time::ctime (void) const
+{
+  return octave_localtime (*this) . asctime ();
+}
+
+void
+octave_time::stamp (void)
+{
+#if defined (HAVE_GETTIMEOFDAY)
+
+  struct timeval tp;
+
+#if defined  (GETTIMEOFDAY_NO_TZ)
+  gettimeofday (&tp);
+#else
+  gettimeofday (&tp, 0);
+#endif
+
+  ot_unix_time = tp.tv_sec;
+  ot_usec = tp.tv_usec;
+
+#elif defined (OCTAVE_USE_WINDOWS_API)
+
+  // Loosely based on the code from Cygwin
+  // Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+  // Licenced under the GPL.
+
+  const LONGLONG TIME_OFFSET = 0x19db1ded53e8000LL;
+
+  static int init = 1;
+  static LARGE_INTEGER base;
+  static LARGE_INTEGER t0;
+  static double dt;
+
+  if (init)
+    {
+      LARGE_INTEGER ifreq;
+
+      if (QueryPerformanceFrequency (&ifreq))
+        {
+	  // Get clock frequency
+	  dt = (double) 1000000.0 / (double) ifreq.QuadPart;
+
+	  // Get base time as microseconds from Jan 1. 1970
+	  int priority = GetThreadPriority (GetCurrentThread ());
+	  SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+	  if (QueryPerformanceCounter (&base))
+	    {
+	      FILETIME f;
+
+	      GetSystemTimeAsFileTime (&f);
+
+	      t0.HighPart = f.dwHighDateTime;
+	      t0.LowPart = f.dwLowDateTime;
+	      t0.QuadPart -= TIME_OFFSET;
+	      t0.QuadPart /= 10;
+
+	      init = 0;
+	    }
+
+	  SetThreadPriority (GetCurrentThread (), priority);
+	}
+
+      if (! init)
+	{
+	  ot_unix_time = time (0);
+	  ot_usec = 0;
+
+	  return;
+	}
+    }
+
+  LARGE_INTEGER now;
+
+  if (QueryPerformanceCounter (&now))
+    {
+      now.QuadPart = (LONGLONG) (dt * (double)(now.QuadPart - base.QuadPart));
+      now.QuadPart += t0.QuadPart;
+
+      ot_unix_time = now.QuadPart / 1000000LL;
+      ot_usec = now.QuadPart % 1000000LL;
+    }
+  else
+    {
+      ot_unix_time = time (0);
+      ot_usec = 0;
+    }
+
+#else
+
+  ot_unix_time = time (0);
+
+#endif
+}
+
+// From the mktime() manual page:
+//
+//     The  mktime()  function converts a broken-down time structure,
+//     expressed as local time, to calendar time representation.
+//
+//     <snip>
+//
+//     If structure members are outside  their	legal interval, they
+//     will be normalized (so that, e.g., 40 October is changed into
+//     9 November).
+//
+// So, we no longer check limits here.
+
+#if 0
+#define DEFINE_SET_INT_FIELD_FCN(f, lo, hi) \
+  octave_base_tm& \
+  octave_base_tm::f (int v) \
+  { \
+    if (v < lo || v > hi) \
+      (*current_liboctave_error_handler) \
+	("invalid value specified for " #f); \
+ \
+    tm_ ## f = v; \
+ \
+    return *this; \
+  }
+#else
+#define DEFINE_SET_INT_FIELD_FCN(f, lo, hi) \
+  octave_base_tm& \
+  octave_base_tm::f (int v) \
+  { \
+    tm_ ## f = v; \
+ \
+    return *this; \
+  }
+#endif
+
+DEFINE_SET_INT_FIELD_FCN (usec, 0, 1000000)
+DEFINE_SET_INT_FIELD_FCN (sec, 0, 61)
+DEFINE_SET_INT_FIELD_FCN (min, 0, 59)
+DEFINE_SET_INT_FIELD_FCN (hour, 0, 23)
+DEFINE_SET_INT_FIELD_FCN (mday, 1, 31)
+DEFINE_SET_INT_FIELD_FCN (mon, 0, 11)
+DEFINE_SET_INT_FIELD_FCN (year, INT_MIN, INT_MAX)
+DEFINE_SET_INT_FIELD_FCN (wday, 0, 6)
+DEFINE_SET_INT_FIELD_FCN (yday, 0, 365)
+DEFINE_SET_INT_FIELD_FCN (isdst, 0, 1)
+
+octave_base_tm&
+octave_base_tm::zone (const std::string& s)
+{
+  tm_zone = s;
+  return *this;
+}
+
+#if !defined STRFTIME_BUF_INITIAL_SIZE
+#define STRFTIME_BUF_INITIAL_SIZE 128
+#endif
+
+std::string
+octave_base_tm::strftime (const std::string& fmt) const
+{
+  std::string retval;
+
+  if (! fmt.empty ())
+    {
+      struct tm t;
+  
+      t.tm_sec = tm_sec;
+      t.tm_min = tm_min;
+      t.tm_hour = tm_hour;
+      t.tm_mday = tm_mday;
+      t.tm_mon = tm_mon;
+      t.tm_year = tm_year;
+      t.tm_wday = tm_wday;
+      t.tm_yday = tm_yday;
+      t.tm_isdst = tm_isdst;
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+      char *ps = strsave (tm_zone.c_str ());
+      t.tm_zone = ps;
+#endif
+
+      const char *fmt_str = fmt.c_str ();
+
+      char *buf = 0;
+      size_t bufsize = STRFTIME_BUF_INITIAL_SIZE;
+      size_t chars_written = 0;
+
+      while (chars_written == 0)
+	{
+	  delete [] buf;
+	  buf = new char[bufsize];
+	  buf[0] = '\0';
+
+	  chars_written = ::strftime (buf, bufsize, fmt_str, &t);
+
+	  bufsize *= 2;
+	}
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+      delete [] ps;
+#endif
+
+      retval = buf;
+
+      delete [] buf;
+    }
+
+  return retval;
+}
+
+void
+octave_base_tm::init (void *p)
+{
+  if (! p)
+    return;
+
+  struct tm *t = static_cast<struct tm*> (p);
+  
+  tm_sec = t->tm_sec;
+  tm_min = t->tm_min;
+  tm_hour = t->tm_hour;
+  tm_mday = t->tm_mday;
+  tm_mon = t->tm_mon;
+  tm_year = t->tm_year;
+  tm_wday = t->tm_wday;
+  tm_yday = t->tm_yday;
+  tm_isdst = t->tm_isdst;
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+  if (t->tm_zone)
+    tm_zone = t->tm_zone;
+#elif defined (HAVE_TZNAME)
+  if (t->tm_isdst == 0 || t->tm_isdst == 1)
+    tm_zone = tzname[t->tm_isdst];
+#endif
+}
+
+void
+octave_localtime::init (const octave_time& ot)
+{
+  tm_usec = ot.usec ();
+
+  time_t t = ot.unix_time ();
+
+  octave_base_tm::init (localtime (&t));
+}
+
+void
+octave_gmtime::init (const octave_time& ot)
+{
+  tm_usec = ot.usec ();
+
+  time_t t = ot.unix_time ();
+
+  octave_base_tm::init (gmtime (&t));
+}
+
+void
+octave_strptime::init (const std::string& str, const std::string& fmt)
+{
+  struct tm t;
+
+  t.tm_sec = 0;
+  t.tm_min = 0;
+  t.tm_hour = 0;
+  t.tm_mday = 0;
+  t.tm_mon = -1;
+  t.tm_year = INT_MIN;
+  t.tm_wday = 0;
+  t.tm_yday = 0;
+  t.tm_isdst = 0;
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+  char *ps = strsave ("");
+  t.tm_zone = ps;
+#endif
+
+  char *p = strsave (str.c_str ());
+
+  char *q = oct_strptime (p, fmt.c_str (), &t);
+
+  // Fill in wday and yday, but only if mday is valid and the mon and year
+  // are filled in, avoiding issues with mktime and invalid dates.
+  if (t.tm_mday != 0 && t.tm_mon >= 0 && t.tm_year != INT_MIN)
+    {
+      t.tm_isdst = -1;
+      mktime (&t);
+    }
+
+  if (t.tm_mon < 0)
+    t.tm_mon = 0;
+
+  if (t.tm_year == INT_MIN)
+    t.tm_year = 0;
+
+  if (q)
+    nchars = q - p + 1;
+  else
+    nchars = 0;
+
+  delete [] p;
+
+  octave_base_tm::init (&t);
+
+#if defined (HAVE_STRUCT_TM_TM_ZONE)
+  delete [] ps;
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-time.h b/liboctave/oct-time.h
new file mode 100644
index 0000000..74abfc6
--- /dev/null
+++ b/liboctave/oct-time.h
@@ -0,0 +1,336 @@
+/*
+
+Copyright (C) 1999, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_time_h)
+#define octave_time_h 1
+
+#include <string>
+
+#include "lo-math.h"
+#include "systime.h"
+
+class octave_base_tm;
+
+class
+OCTAVE_API
+octave_time
+{
+public:
+
+  octave_time (void)
+    : ot_unix_time (0), ot_usec (0) { stamp (); }
+
+  octave_time (time_t t)
+    : ot_unix_time (t), ot_usec (0) { }
+
+  octave_time (double d)
+    : ot_unix_time (static_cast<time_t> (d)), ot_usec (0)
+  {
+    double ip;
+    ot_usec = static_cast<int> (std::modf (d, &ip) * 1e6);
+  }
+
+  octave_time (const octave_base_tm& tm);
+
+  octave_time (const octave_time& ot)
+    : ot_unix_time (ot.ot_unix_time), ot_usec (ot.ot_usec) { }
+
+  octave_time& operator = (const octave_time& ot)
+  {
+    if (this != &ot)
+      {
+	ot_unix_time = ot.ot_unix_time;
+	ot_usec = ot.ot_usec;
+      }
+
+    return *this;
+  }
+
+  ~octave_time (void) { }
+
+  void stamp (void);
+
+  double double_value (void) const { return ot_unix_time + ot_usec / 1e6; }
+
+  time_t unix_time (void) const { return ot_unix_time; }
+
+  int usec (void) const { return ot_usec; }
+
+  std::string ctime (void) const;
+
+private:
+
+  // Seconds since the epoch.
+  time_t ot_unix_time;
+
+  // Additional microseconds.
+  int ot_usec;
+};
+
+inline bool
+operator == (const octave_time& t1, const octave_time& t2)
+{
+  return (t1.unix_time () == t2.unix_time () && t1.usec () == t2.usec ());
+}
+
+inline bool
+operator != (const octave_time& t1, const octave_time& t2)
+{
+  return ! (t1 == t2);
+}
+
+inline bool
+operator < (const octave_time& t1, const octave_time& t2)
+{
+  if (t1.unix_time () < t2.unix_time ())
+    return true;
+  else if (t1.unix_time () > t2.unix_time ())
+    return false;
+  else if (t1.usec () < t2.usec ())
+    return true;
+  else
+    return false;
+}
+
+inline bool
+operator <= (const octave_time& t1, const octave_time& t2)
+{
+  return (t1 < t2 || t1 == t2);
+}
+
+inline bool
+operator > (const octave_time& t1, const octave_time& t2)
+{
+  if (t1.unix_time () > t2.unix_time ())
+    return true;
+  else if (t1.unix_time () < t2.unix_time ())
+    return false;
+  else if (t1.usec () > t2.usec ())
+    return true;
+  else
+    return false;
+}
+
+inline bool
+operator >= (const octave_time& t1, const octave_time& t2)
+{
+  return (t1 > t2 || t1 == t2);
+}
+
+class
+OCTAVE_API
+octave_base_tm
+{
+public:
+
+  octave_base_tm (void)
+    : tm_usec (0), tm_sec (0), tm_min (0), tm_hour (0),
+      tm_mday (0), tm_mon (0), tm_year (0), tm_wday (0),
+      tm_yday (0), tm_isdst (0), tm_zone ("unknown")
+  { }
+
+  octave_base_tm (const octave_base_tm& tm)
+    : tm_usec (tm.tm_usec), tm_sec (tm.tm_sec), tm_min (tm.tm_min),
+      tm_hour (tm.tm_hour), tm_mday (tm.tm_mday), tm_mon (tm.tm_mon),
+      tm_year (tm.tm_year), tm_wday (tm.tm_wday), tm_yday (tm.tm_yday),
+      tm_isdst (tm.tm_isdst), tm_zone (tm.tm_zone)
+  { }
+
+  octave_base_tm& operator = (const octave_base_tm& tm)
+  {
+    if (this != &tm)
+      {
+	tm_usec = tm.tm_usec;
+	tm_sec = tm.tm_sec;
+	tm_min = tm.tm_min;
+	tm_hour = tm.tm_hour;
+	tm_mday = tm.tm_mday;
+	tm_mon = tm.tm_mon;
+	tm_year = tm.tm_year;
+	tm_wday = tm.tm_wday;
+	tm_yday = tm.tm_yday;
+	tm_isdst = tm.tm_isdst;
+	tm_zone = tm.tm_zone;
+      }
+
+    return *this;
+  }
+
+  virtual ~octave_base_tm (void) { }
+
+  int usec (void) const { return tm_usec; }
+  int sec (void) const { return tm_sec; }
+  int min (void) const { return tm_min; }
+  int hour (void) const { return tm_hour; }
+  int mday (void) const { return tm_mday; }
+  int mon (void) const { return tm_mon; }
+  int year (void) const { return tm_year; }
+  int wday (void) const { return tm_wday; }
+  int yday (void) const { return tm_yday; }
+  int isdst (void) const { return tm_isdst; }
+  std::string zone (void) const { return tm_zone; }
+
+  octave_base_tm& usec (int v);
+  octave_base_tm& sec (int v);
+  octave_base_tm& min (int v);
+  octave_base_tm& hour (int v);
+  octave_base_tm& mday (int v);
+  octave_base_tm& mon (int v);
+  octave_base_tm& year (int v);
+  octave_base_tm& wday (int v);
+  octave_base_tm& yday (int v);
+  octave_base_tm& isdst (int v);
+  octave_base_tm& zone (const std::string& s);
+
+  std::string strftime (const std::string& fmt) const;
+
+  std::string asctime (void) const
+    { return strftime ("%a %b %d %H:%M:%S %Y\n"); }
+
+protected:
+
+  // Microseconds after the second (0, 999999).
+  int tm_usec;
+
+  // Seconds after the minute (0, 61).
+  int tm_sec;
+
+  // Minutes after the hour (0, 59).
+  int tm_min;
+
+  // Hours since midnight (0, 23).
+  int tm_hour;
+
+  // Day of the month (1, 31).
+  int tm_mday;
+
+  // Months since January (0, 11).
+  int tm_mon;
+
+  // Years since 1900.
+  int tm_year;
+
+  // Days since Sunday (0, 6).
+  int tm_wday;
+
+  // Days since January 1 (0, 365).
+  int tm_yday;
+
+  // Daylight Savings Time flag.
+  int tm_isdst;
+
+  // Time zone.
+  std::string tm_zone;
+
+  void init (void *p);
+};
+
+class
+OCTAVE_API
+octave_localtime : public octave_base_tm
+{
+public:
+
+  octave_localtime (void)
+    : octave_base_tm () { init (octave_time ()); }
+
+  octave_localtime (const octave_time& ot)
+    : octave_base_tm () { init (ot); }
+
+  octave_localtime (const octave_localtime& t)
+    : octave_base_tm (t) { }
+
+  octave_localtime& operator = (const octave_localtime& t)
+  {
+    octave_base_tm::operator = (t);
+    return *this;
+  }
+
+  ~octave_localtime (void) { }
+
+private:
+
+  void init (const octave_time& ot);
+};
+
+class
+OCTAVE_API
+octave_gmtime : public octave_base_tm
+{
+public:
+
+  octave_gmtime (void)
+    : octave_base_tm () { init (octave_time ()); }
+
+  octave_gmtime (const octave_time& ot)
+    : octave_base_tm () { init (ot); }
+
+  octave_gmtime& operator = (const octave_gmtime& t)
+  {
+    octave_base_tm::operator = (t);
+    return *this;
+  }
+
+  ~octave_gmtime (void) { }
+
+private:
+
+  void init (const octave_time& ot);
+};
+
+class
+OCTAVE_API
+octave_strptime : public octave_base_tm
+{
+public:
+
+  octave_strptime (const std::string& str, const std::string& fmt)
+    : octave_base_tm () { init (str, fmt); }
+
+  octave_strptime (const octave_strptime& s)
+    : octave_base_tm (s) { nchars = s.nchars; }
+
+  octave_strptime& operator = (const octave_strptime& s)
+  {
+    octave_base_tm::operator = (s);
+    nchars = s.nchars;
+    return *this;
+  }
+
+  int characters_converted (void) const { return nchars; }
+
+  ~octave_strptime (void) { }
+
+private:
+
+  int nchars;
+
+  void init (const std::string& str, const std::string& fmt);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-types.h b/liboctave/oct-types.h
new file mode 100644
index 0000000..ee4a172
--- /dev/null
+++ b/liboctave/oct-types.h
@@ -0,0 +1,81 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_types_h)
+#define octave_oct_types_h 1
+
+typedef int octave_idx_type;
+
+#if defined (HAVE_STDINT_H)
+#include <stdint.h>
+#elif defined (HAVE_INTTYPES_H)
+#include <inttypes.h>
+#else
+
+#if defined (HAVE_LIMITS_H)
+#include <limits.h>
+#endif
+
+#if CHAR_BIT == 8
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+#else
+#error "CHAR_BIT is not 8!"
+#endif
+
+#if SIZEOF_SHORT == 2
+typedef short int16_t;
+typedef unsigned short uint16_t;
+#elif SIZEOF_INT == 2
+typedef long int16_t;
+typedef unsigned long uint16_t;
+#else
+#error "No 2 byte integer type found!"
+#endif
+
+#if SIZEOF_INT == 4
+typedef int int32_t;
+typedef unsigned int uint32_t;
+#elif SIZEOF_LONG == 4
+typedef long int32_t;
+typedef unsigned long uint32_t;
+#else
+#error "No 4 byte integer type found!"
+#endif
+
+#if SIZEOF_LONG == 8
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#elif SIZEOF_LONG_LONG == 8
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-types.h.in b/liboctave/oct-types.h.in
new file mode 100644
index 0000000..03fc545
--- /dev/null
+++ b/liboctave/oct-types.h.in
@@ -0,0 +1,81 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_types_h)
+#define octave_oct_types_h 1
+
+typedef @OCTAVE_IDX_TYPE@ octave_idx_type;
+
+#if defined (HAVE_STDINT_H)
+#include <stdint.h>
+#elif defined (HAVE_INTTYPES_H)
+#include <inttypes.h>
+#else
+
+#if defined (HAVE_LIMITS_H)
+#include <limits.h>
+#endif
+
+#if CHAR_BIT == 8
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+#else
+#error "CHAR_BIT is not 8!"
+#endif
+
+#if SIZEOF_SHORT == 2
+typedef short int16_t;
+typedef unsigned short uint16_t;
+#elif SIZEOF_INT == 2
+typedef long int16_t;
+typedef unsigned long uint16_t;
+#else
+#error "No 2 byte integer type found!"
+#endif
+
+#if SIZEOF_INT == 4
+typedef int int32_t;
+typedef unsigned int uint32_t;
+#elif SIZEOF_LONG == 4
+typedef long int32_t;
+typedef unsigned long uint32_t;
+#else
+#error "No 4 byte integer type found!"
+#endif
+
+#if SIZEOF_LONG == 8
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#elif SIZEOF_LONG_LONG == 8
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-uname.cc b/liboctave/oct-uname.cc
new file mode 100644
index 0000000..36d5d9b
--- /dev/null
+++ b/liboctave/oct-uname.cc
@@ -0,0 +1,64 @@
+/*
+
+Copyright (C) 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstring>
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#include "oct-uname.h"
+
+void
+octave_uname::init (void)
+{
+#if defined (HAVE_UNAME) && defined (HAVE_SYS_UTSNAME_H)
+  struct utsname unm;
+
+  err = ::uname (&unm);
+
+  if (err < 0)
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+  else
+    {
+      utsname_sysname = unm.sysname;
+      utsname_nodename = unm.nodename;
+      utsname_release = unm.release;
+      utsname_version = unm.version;
+      utsname_machine = unm.machine;
+    }
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/oct-uname.h b/liboctave/oct-uname.h
new file mode 100644
index 0000000..f6655b3
--- /dev/null
+++ b/liboctave/oct-uname.h
@@ -0,0 +1,98 @@
+/*
+
+Copyright (C) 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uame_h)
+#define octave_uname_h 1
+
+#include <string>
+
+class
+OCTAVE_API
+octave_uname
+{
+public:
+
+  octave_uname (void)
+    : utsname_sysname ("unknown"), utsname_nodename ("unknown"),
+      utsname_release ("unknown"), utsname_version ("unknown"),
+      utsname_machine ("unknown"),
+      msg ("uname not supported on this system"), err (-1)
+  { init (); }
+
+  octave_uname (const octave_uname& unm)
+    : utsname_sysname (unm.utsname_sysname),
+      utsname_nodename (unm.utsname_nodename),
+      utsname_release (unm.utsname_release),
+      utsname_version (unm.utsname_version),
+      utsname_machine (unm.utsname_machine),
+      msg (unm.msg), err (unm.err)
+  { }
+
+  octave_uname& operator = (const octave_uname& unm)
+  {
+    if (this != &unm)
+      {
+	utsname_sysname = unm.utsname_sysname;
+	utsname_nodename = unm.utsname_nodename;
+	utsname_release = unm.utsname_release;
+	utsname_version = unm.utsname_version;
+	utsname_machine = unm.utsname_machine;
+
+	msg = unm.msg;
+	err = unm.err;
+      }
+
+    return *this;
+  }
+
+  ~octave_uname (void) { }
+
+  std::string sysname (void) const { return utsname_sysname; }
+  std::string nodename (void) const { return utsname_nodename; }
+  std::string release (void) const { return utsname_release; }
+  std::string version (void) const { return utsname_version; }
+  std::string machine (void) const { return utsname_machine; }
+
+  std::string message (void) const { return msg; }
+  int error (void) const { return err; }
+
+private:
+
+  std::string utsname_sysname;
+  std::string utsname_nodename;
+  std::string utsname_release;
+  std::string utsname_version;
+  std::string utsname_machine;
+
+  std::string msg;
+  int err;
+
+  void init (void);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/pathlen.h b/liboctave/pathlen.h
new file mode 100644
index 0000000..ca87a68
--- /dev/null
+++ b/liboctave/pathlen.h
@@ -0,0 +1,40 @@
+/*
+
+Copyright (C) 1996, 1997, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_pathlen_h)
+#define octave_pathlen_h 1
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/pathsearch.cc b/liboctave/pathsearch.cc
new file mode 100644
index 0000000..ae36e60
--- /dev/null
+++ b/liboctave/pathsearch.cc
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+
+#include "lo-utils.h"
+#include "oct-env.h"
+#include "pathsearch.h"
+#include "str-vec.h"
+#include "str-vec.h"
+
+#include "kpse.cc"
+
+dir_path::static_members *dir_path::static_members::instance = 0;
+
+dir_path::static_members::static_members (void)
+  : xpath_sep_char (SEPCHAR), xpath_sep_str (SEPCHAR_STR) { }
+
+bool
+dir_path::static_members::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new static_members ();
+
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+	("unable to create dir_path::static_members object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+string_vector
+dir_path::elements (void)
+{
+  return initialized ? pv : string_vector ();
+}
+
+string_vector
+dir_path::all_directories (void)
+{
+  int count = 0;
+  string_vector retval;
+
+  if (initialized)
+    {
+      int len = pv.length ();
+
+      int nmax = len > 32 ? len : 32;
+
+      retval.resize (len);
+
+      for (int i = 0; i < len; i++)
+	{
+	  str_llist_type *elt_dirs = kpse_element_dirs (pv[i]);
+
+	  if (elt_dirs)
+	    {
+	      str_llist_elt_type *dir;
+
+	      for (dir = *elt_dirs; dir; dir = STR_LLIST_NEXT (*dir))
+		{
+		  const std::string elt_dir = STR_LLIST (*dir);
+
+		  if (! elt_dir.empty ())
+		    {
+		      if (count == nmax)
+			nmax *= 2;
+
+		      retval.resize (nmax);
+
+		      retval[count++] = elt_dir;
+		    }
+		}
+	    }
+	}
+
+      retval.resize (count);
+    }
+
+  return retval;
+}
+
+std::string
+dir_path::find_first (const std::string& nm)
+{
+  return initialized ? kpse_path_search (p, nm, true) : std::string ();
+}
+
+string_vector
+dir_path::find_all (const std::string& nm)
+{
+  return initialized ? kpse_all_path_search (p, nm) : string_vector ();
+}
+
+std::string
+dir_path::find_first_of (const string_vector& names)
+{
+  return initialized
+    ? kpse_path_find_first_of (p, names, true) : std::string ();
+}
+
+string_vector
+dir_path::find_all_first_of (const string_vector& names)
+{
+  return initialized
+    ? kpse_all_path_find_first_of (p, names) : string_vector ();
+}
+
+void
+dir_path::init (void)
+{
+  static bool octave_kpathsea_initialized = false;
+
+  if (! octave_kpathsea_initialized)
+    {
+      std::string val = octave_env::getenv ("KPATHSEA_DEBUG");
+
+      if (! val.empty ())
+	kpathsea_debug |= atoi (val.c_str ());
+
+      octave_kpathsea_initialized = true;
+    }
+
+  p = kpse_path_expand (p_default.empty ()
+			? p_orig : kpse_expand_default (p_orig, p_default));
+
+  int count = 0;
+  for (kpse_path_iterator pi (p); pi != std::string::npos; pi++)
+    count++;
+
+  pv.resize (count);
+
+  kpse_path_iterator pi (p);
+
+  for (int i = 0; i < count; i++)
+    pv[i] = *pi++;
+
+  initialized = true;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/pathsearch.h b/liboctave/pathsearch.h
new file mode 100644
index 0000000..078899b
--- /dev/null
+++ b/liboctave/pathsearch.h
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_pathsearch_h)
+#define octave_pathsearch_h 1
+
+#include <string>
+
+#include "str-vec.h"
+
+class
+OCTAVE_API
+dir_path
+{
+public:
+
+  dir_path (const std::string& s = std::string (),
+	    const std::string& d = std::string ())
+    : p_orig (s), p_default (d), initialized (false)
+    {
+      if (! p_orig.empty ())
+	init ();
+    }
+
+  dir_path (const dir_path& dp)
+    : p_orig (dp.p_orig), p_default (dp.p_default),
+      initialized (dp.initialized), p (dp.p), pv (dp.pv)
+  { }
+
+  dir_path& operator = (const dir_path& dp)
+    {
+      p_orig = dp.p_orig;
+      p_default = dp.p_default;
+      initialized = dp.initialized;
+      p = dp.p;
+      pv = dp.pv;
+      return *this;
+    }
+
+  ~dir_path (void) { }
+
+  void set (const std::string& s)
+    {
+      initialized = false;
+      p_orig = s;
+      init ();
+    }
+
+  string_vector elements (void);
+  string_vector all_directories (void);
+
+  std::string find_first (const std::string&);
+  std::string find (const std::string& nm) { return find_first (nm); }
+
+  string_vector find_all (const std::string&);
+
+  std::string find_first_of (const string_vector& names);
+  string_vector find_all_first_of (const string_vector& names);
+
+  void rehash (void)
+    {
+      initialized = false;
+      init ();
+    }
+
+  static char path_sep_char (void)
+  {
+    return static_members::path_sep_char ();
+  }
+
+  static void path_sep_char (char c)
+  {
+    static_members::path_sep_char (c);
+  }
+
+  static std::string path_sep_str (void)
+  {
+    return static_members::path_sep_str ();
+  }
+
+  static bool is_path_sep (char c) { return c == path_sep_char (); }
+
+private:
+
+  // The colon separated list that we were given.
+  std::string p_orig;
+
+  // The default path.  If specified, replaces leading, trailing, or
+  // doubled colons in p_orig.
+  std::string p_default;
+
+  // TRUE means we've unpacked p.
+  bool initialized;
+
+  // A version of the colon separate list on which we have performed
+  // tilde, variable, and possibly default path expansion.
+  std::string p;
+
+  // The elements of the list.
+  string_vector pv;
+
+  void init (void);
+
+  // Use a singleton class for these data members instead of just
+  // making them static members of the dir_path class so that we can
+  // ensure proper initialization.
+
+  class OCTAVE_API static_members
+  {
+  public:
+
+    static_members (void);
+
+    static char path_sep_char (void)
+    {
+      return instance_ok () ? instance->xpath_sep_char : 0;
+    }
+
+    static void path_sep_char (char c)
+    {
+      if (instance_ok ())
+	{
+	  instance->xpath_sep_char = c;
+	  instance->xpath_sep_str = std::string (1, c);
+	}
+    }
+
+    static std::string path_sep_str (void)
+    {
+      return instance_ok () ? instance->xpath_sep_str : std::string ();
+    }
+
+  private:
+
+    static static_members *instance;
+
+    static bool instance_ok (void);
+
+    // No copying!
+
+    static_members (const static_members&);
+
+    static_members& operator = (const static_members&);
+
+    char xpath_sep_char;
+
+    std::string xpath_sep_str;
+  };
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/prog-args.cc b/liboctave/prog-args.cc
new file mode 100644
index 0000000..ccc141d
--- /dev/null
+++ b/liboctave/prog-args.cc
@@ -0,0 +1,68 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-getopt.h"
+
+#include "prog-args.h"
+
+int
+prog_args::getopt (void)
+{
+  if (long_opts)
+    return ::octave_getopt_long
+      (xargc, xargv, short_opts,
+       reinterpret_cast<const struct option *> (long_opts), 0);
+  else
+    return ::octave_getopt (xargc, xargv, short_opts);
+}
+
+const char *
+prog_args::optarg (void)
+{
+  return ::optarg;
+}
+
+int
+prog_args::optind (void)
+{
+  return ::optind;
+}
+
+// This is intended to communicate to getopt that it is supposed to
+// start over on the next call, but it may not be portable.  See the
+// comments in getopt.c for more information.
+
+void
+prog_args::init (void)
+{
+  ::optind = 0;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/prog-args.h b/liboctave/prog-args.h
new file mode 100644
index 0000000..1ad006d
--- /dev/null
+++ b/liboctave/prog-args.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1996, 1997, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_prog_args_h)
+#define octave_prog_args_h 1
+
+struct
+long_options
+{
+  const char *name;
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+class
+OCTAVE_API
+prog_args
+{
+public:
+
+  // These values must match the corresponding defines in getopt.h.
+  enum option_argument
+    {
+      no_arg = 0,
+      required_arg = 1,
+      optional_arg = 2
+    };
+
+  prog_args (int argc, char *const *argv, const char *s_opts, const
+	     long_options* l_opts = 0)
+    : xargc (argc), xargv (argv), short_opts (s_opts), long_opts (l_opts)
+      {
+	init ();
+      }
+
+  ~prog_args (void) { }
+
+  int getopt (void);
+
+  const char *optarg (void);
+
+  int optind (void);
+
+private:
+
+  // Number of args.
+  int xargc;
+
+  // Program args.
+  char *const *xargv;
+
+  // Single character options.
+  const char *short_opts;
+
+  // Long options.
+  const long_options *long_opts;
+
+  void init (void);
+
+  prog_args (const prog_args&);
+
+  prog_args& operator = (const prog_args&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/randgamma.c b/liboctave/randgamma.c
new file mode 100644
index 0000000..ef07d4f
--- /dev/null
+++ b/liboctave/randgamma.c
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/* Original version written by Paul Kienzle distributed as free
+   software in the in the public domain.  */
+
+/*
+
+double randg(a) 
+void fill_randg(a,n,x)
+
+Generate a series of standard gamma distributions.
+
+See: Marsaglia G and Tsang W (2000), "A simple method for generating
+gamma variables", ACM Transactions on Mathematical Software 26(3) 363-372
+
+Needs the following defines: 
+* NAN: value to return for Not-A-Number
+* RUNI: uniform generator on (0,1)
+* RNOR: normal generator
+* REXP: exponential generator, or -log(RUNI) if one isn't available
+* INFINITE: function to test whether a value is infinite
+
+Test using:
+  mean = a
+  variance = a
+  skewness = 2/sqrt(a)
+  kurtosis = 3 + 6/sqrt(a)
+
+Note that randg can be used to generate many distributions:
+
+gamma(a,b) for a>0, b>0 (from R)
+  r = b*randg(a)
+beta(a,b) for a>0, b>0
+  r1 = randg(a,1)
+  r = r1 / (r1 + randg(b,1))
+Erlang(a,n)
+  r = a*randg(n)
+chisq(df) for df>0
+  r = 2*randg(df/2)
+t(df) for 0<df<inf (use randn if df is infinite)
+  r = randn() / sqrt(2*randg(df/2)/df)
+F(n1,n2) for 0<n1, 0<n2
+  r1 = 2*randg(n1/2)/n1 or 1 if n1 is infinite
+  r2 = 2*randg(n2/2)/n2 or 1 if n2 is infinite
+  r = r1 / r2
+negative binonial (n, p) for n>0, 0<p<=1
+  r = randp((1-p)/p * randg(n))
+  (from R, citing Devroye(1986), Non-Uniform Random Variate Generation)
+non-central chisq(df,L), for df>=0 and L>0 (use chisq if L=0)
+  r = randp(L/2)
+  r(r>0) = 2*randg(r(r>0))
+  r(df>0) += 2*randg(df(df>0)/2)
+  (from R, citing formula 29.5b-c in Johnson, Kotz, Balkrishnan(1995))
+Dirichlet(a1,...,ak) for ai > 0
+  r = (randg(a1),...,randg(ak))
+  r = r / sum(r)
+  (from GSL, citing Law & Kelton(1991), Simulation Modeling and Analysis)
+*/
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "lo-ieee.h"
+#include "lo-math.h"
+#include "randmtzig.h"
+#include "randgamma.h"
+
+#undef NAN
+#define NAN octave_NaN
+#define INFINITE lo_ieee_isinf
+#define RUNI oct_randu()
+#define RNOR oct_randn()
+#define REXP oct_rande()
+
+void 
+oct_fill_randg (double a, octave_idx_type n, double *r)
+{
+  octave_idx_type i;
+  /* If a < 1, start by generating gamma(1+a) */
+  const double d =  (a < 1. ? 1.+a : a) - 1./3.;
+  const double c = 1./sqrt(9.*d);
+
+  /* Handle invalid cases */
+  if (a <= 0 || INFINITE(a)) 
+    {
+      for (i=0; i < n; i++) 
+	r[i] = NAN;
+      return;
+    }
+
+  for (i=0; i < n; i++) 
+    {
+      double x, xsq, v, u;
+    restart:
+      x = RNOR;
+      v = (1+c*x);
+      v *= v*v;
+      if (v <= 0) 
+	goto restart; /* rare, so don't bother moving up */
+      u = RUNI;
+      xsq = x*x;
+      if (u >= 1.-0.0331*xsq*xsq && log(u) >= 0.5*xsq + d*(1-v+log(v)))
+	goto restart;
+      r[i] = d*v;
+    }
+  if (a < 1) 
+    { /* Use gamma(a) = gamma(1+a)*U^(1/a) */
+      /* Given REXP = -log(U) then U^(1/a) = exp(-REXP/a) */
+      for (i = 0; i < n; i++) 
+	r[i] *= exp(-REXP/a);
+    }
+}
+
+double 
+oct_randg (double a)
+{
+  double ret;
+  oct_fill_randg(a,1,&ret);
+  return ret;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/liboctave/randgamma.h b/liboctave/randgamma.h
new file mode 100644
index 0000000..a06516d
--- /dev/null
+++ b/liboctave/randgamma.h
@@ -0,0 +1,46 @@
+/*
+
+Copyright (C) 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/* Original version written by Paul Kienzle distributed as free
+   software in the in the public domain.  */
+
+#ifndef _RANDGAMMA_H
+
+#include "oct-types.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+extern double oct_randg (double a);
+extern void oct_fill_randg (double a, octave_idx_type n, double *p);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/liboctave/randmtzig.c b/liboctave/randmtzig.c
new file mode 100644
index 0000000..d6fcbe2
--- /dev/null
+++ b/liboctave/randmtzig.c
@@ -0,0 +1,709 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/* 
+   A C-program for MT19937, with initialization improved 2002/2/10.
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+   This is a faster version by taking Shawn Cokus's optimization,
+   Matthe Bellew's simplification, Isaku Wada's real version.
+   David Bateman added normal and exponential distributions following
+   Marsaglia and Tang's Ziggurat algorithm.
+
+   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+   Copyright (C) 2004, David Bateman
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote 
+        products derived from this software without specific prior written 
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 
+   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.
+
+
+   Any feedback is very welcome.
+   http://www.math.keio.ac.jp/matumoto/emt.html
+   email: matumoto at math.keio.ac.jp
+
+   * 2006-04-01 David Bateman
+   * * convert for use in octave, declaring static functions only used
+   *   here and adding oct_ to functions visible externally
+   * * inverse sense of ALLBITS
+   * 2004-01-19 Paul Kienzle
+   * * comment out main
+   * add init_by_entropy, get_state, set_state
+   * * converted to allow compiling by C++ compiler
+   *
+   * 2004-01-25 David Bateman
+   * * Add Marsaglia and Tsang Ziggurat code
+   *
+   * 2004-07-13 Paul Kienzle
+   * * make into an independent library with some docs.
+   * * introduce new main and test code.
+   *
+   * 2004-07-28 Paul Kienzle & David Bateman
+   * * add -DALLBITS flag for 32 vs. 53 bits of randomness in mantissa
+   * * make the naming scheme more uniform
+   * * add -DHAVE_X86 for faster support of 53 bit mantissa on x86 arch.
+   *
+   * 2005-02-23 Paul Kienzle
+   * * fix -DHAVE_X86_32 flag and add -DUSE_X86_32=0|1 for explicit control
+   */
+
+/*
+   === Build instructions ===
+
+   Compile with -DHAVE_GETTIMEOFDAY if the gettimeofday function is 
+   available.  This is not necessary if your architecture has
+   /dev/urandom defined.
+
+   Compile with -DALLBITS to disable 53-bit random numbers. This is about
+   50% slower than using 32-bit random numbers.
+
+   Uses implicit -Di386 or explicit -DHAVE_X86_32 to determine if CPU=x86.  
+   You can force X86 behaviour with -DUSE_X86_32=1, or suppress it with 
+   -DUSE_X86_32=0. You should also consider -march=i686 or similar for 
+   extra performance. Check whether -DUSE_X86_32=0 is faster on 64-bit
+   x86 architectures.
+
+   If you want to replace the Mersenne Twister with another
+   generator then redefine randi32 appropriately.
+
+   === Usage instructions ===
+   Before using any of the generators, initialize the state with one of
+   oct_init_by_int, oct_init_by_array or oct_init_by_entropy.
+
+   All generators share the same state vector.
+
+   === Mersenne Twister ===
+   void oct_init_by_int(uint32_t s)           32-bit initial state
+   void oct_init_by_array(uint32_t k[],int m) m*32-bit initial state
+   void oct_init_by_entropy(void)             random initial state
+   void oct_get_state(uint32_t save[MT_N+1])  saves state in array
+   void oct_set_state(uint32_t save[MT_N+1])  restores state from array
+   static uint32_t randmt(void)               returns 32-bit unsigned int
+
+   === inline generators ===
+   static uint32_t randi32(void)   returns 32-bit unsigned int
+   static uint64_t randi53(void)   returns 53-bit unsigned int
+   static uint64_t randi54(void)   returns 54-bit unsigned int
+   static uint64_t randi64(void)   returns 64-bit unsigned int
+   static double randu32(void)     returns 32-bit uniform in (0,1)
+   static double randu53(void)     returns 53-bit uniform in (0,1)
+
+   double oct_randu(void)       returns M-bit uniform in (0,1)
+   double oct_randn(void)       returns M-bit standard normal
+   double oct_rande(void)       returns N-bit standard exponential
+
+   === Array generators ===
+   void oct_fill_randi32(octave_idx_type, uint32_t [])
+   void oct_fill_randi64(octave_idx_type, uint64_t [])
+   void oct_fill_randu(octave_idx_type, double [])
+   void oct_fill_randn(octave_idx_type, double [])
+   void oct_fill_rande(octave_idx_type, double [])
+
+*/
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+
+#include "lo-math.h"
+#include "randmtzig.h"
+   
+/* FIXME may want to suppress X86 if sizeof(long)>4 */
+#if !defined(USE_X86_32)
+# if defined(i386) || defined(HAVE_X86_32)
+#  define USE_X86_32 1
+# else
+#  define USE_X86_32 0
+# endif
+#endif
+
+/* ===== Mersenne Twister 32-bit generator ===== */  
+
+#define MT_M 397
+#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
+#define UMASK 0x80000000UL /* most significant w-r bits */
+#define LMASK 0x7fffffffUL /* least significant r bits */
+#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
+#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
+
+static uint32_t *next;
+static uint32_t state[MT_N]; /* the array for the state vector  */
+static int left = 1;
+static int initf = 0;
+static int initt = 1;
+
+/* initializes state[MT_N] with a seed */
+void 
+oct_init_by_int (uint32_t s)
+{
+    int j;
+    state[0] = s & 0xffffffffUL;
+    for (j = 1; j < MT_N; j++) {
+        state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j); 
+        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+        /* In the previous versions, MSBs of the seed affect   */
+        /* only MSBs of the array state[].                        */
+        /* 2002/01/09 modified by Makoto Matsumoto             */
+        state[j] &= 0xffffffffUL;  /* for >32 bit machines */
+    }
+    left = 1; 
+    initf = 1;
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+void 
+oct_init_by_array (uint32_t *init_key, int key_length)
+{
+  int i, j, k;
+  oct_init_by_int (19650218UL);
+  i = 1;
+  j = 0;
+  k = (MT_N > key_length ? MT_N : key_length);
+  for (; k; k--)
+    {
+      state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))
+	+ init_key[j] + j; /* non linear */
+      state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+      i++;
+      j++;
+      if (i >= MT_N)
+	{
+	  state[0] = state[MT_N-1];
+	  i = 1;
+	}
+      if (j >= key_length)
+	j = 0;
+    }
+  for (k = MT_N - 1; k; k--)
+    {
+      state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))
+	- i; /* non linear */
+      state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+      i++;
+      if (i >= MT_N)
+	{
+	  state[0] = state[MT_N-1];
+	  i = 1;
+	}
+    }
+
+  state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+  left = 1;
+  initf = 1;
+}
+
+void 
+oct_init_by_entropy (void)
+{
+    uint32_t entropy[MT_N];
+    int n = 0;
+
+    /* Look for entropy in /dev/urandom */
+    FILE* urandom =fopen("/dev/urandom", "rb");
+    if (urandom) 
+      {
+	while (n < MT_N) 
+	  {
+	    unsigned char word[4];
+	    if (fread(word, 4, 1, urandom) != 1) 
+	      break;
+	    entropy[n++] = word[0]+(word[1]<<8)+(word[2]<<16)+(word[3]<<24);
+	  }
+	fclose(urandom);
+      }
+
+    /* If there isn't enough entropy, gather some from various sources */
+    if (n < MT_N) 
+      entropy[n++] = time(NULL); /* Current time in seconds */
+    if (n < MT_N) 
+      entropy[n++] = clock();    /* CPU time used (usec) */
+#ifdef HAVE_GETTIMEOFDAY
+    if (n < MT_N) 
+      {
+	struct timeval tv;
+	if (gettimeofday(&tv, NULL) != -1)
+	  entropy[n++] = tv.tv_usec;   /* Fractional part of current time */
+      }
+#endif
+    /* Send all the entropy into the initial state vector */
+    oct_init_by_array(entropy,n);
+}
+
+void 
+oct_set_state (uint32_t *save)
+{
+  int i;
+  for (i = 0; i < MT_N; i++) 
+    state[i] = save[i];
+  left = save[MT_N];
+  next = state + (MT_N - left + 1);
+}
+
+void 
+oct_get_state (uint32_t *save)
+{
+  int i;
+  for (i = 0; i < MT_N; i++) 
+    save[i] = state[i];
+  save[MT_N] = left;
+}
+
+static void 
+next_state (void)
+{
+  uint32_t *p = state;
+  int j;
+
+  /* if init_by_int() has not been called, */
+  /* a default initial seed is used         */
+  /* if (initf==0) init_by_int(5489UL); */
+  /* Or better yet, a random seed! */
+  if (initf == 0) 
+    oct_init_by_entropy();
+
+  left = MT_N;
+  next = state;
+    
+  for (j = MT_N - MT_M + 1; --j; p++) 
+    *p = p[MT_M] ^ TWIST(p[0], p[1]);
+
+  for (j = MT_M; --j; p++) 
+    *p = p[MT_M-MT_N] ^ TWIST(p[0], p[1]);
+
+  *p = p[MT_M-MT_N] ^ TWIST(p[0], state[0]);
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+static uint32_t
+randmt (void)
+{
+  register uint32_t y;
+
+  if (--left == 0) 
+    next_state();
+  y = *next++;
+
+  /* Tempering */
+  y ^= (y >> 11);
+  y ^= (y << 7) & 0x9d2c5680UL;
+  y ^= (y << 15) & 0xefc60000UL;
+  return (y ^ (y >> 18));
+}
+
+/* ===== Uniform generators ===== */
+
+/* Select which 32 bit generator to use */
+#define randi32 randmt
+
+static uint64_t 
+randi53 (void)
+{
+  const uint32_t lo = randi32();
+  const uint32_t hi = randi32()&0x1FFFFF;
+#if HAVE_X86_32
+  uint64_t u;
+  uint32_t *p = (uint32_t *)&u;
+  p[0] = lo;
+  p[1] = hi;
+  return u;
+#else
+  return (((uint64_t)hi<<32)|lo);
+#endif
+}
+
+static uint64_t 
+randi54 (void)
+{
+  const uint32_t lo = randi32();
+  const uint32_t hi = randi32()&0x3FFFFF;
+#if HAVE_X86_32
+  uint64_t u;
+  uint32_t *p = (uint32_t *)&u;
+  p[0] = lo;
+  p[1] = hi;
+  return u;
+#else
+  return (((uint64_t)hi<<32)|lo);
+#endif
+}
+
+#if 0
+// FIXME -- this doesn't seem to be used anywhere; should it be removed?
+static uint64_t 
+randi64 (void)
+{
+  const uint32_t lo = randi32();
+  const uint32_t hi = randi32();
+#if HAVE_X86_32
+  uint64_t u;
+  uint32_t *p = (uint32_t *)&u;
+  p[0] = lo;
+  p[1] = hi;
+  return u;
+#else
+  return (((uint64_t)hi<<32)|lo);
+#endif
+}
+#endif
+
+#ifdef ALLBITS
+/* generates a random number on (0,1)-real-interval */
+static double
+randu32 (void)
+{
+  return ((double)randi32() + 0.5) * (1.0/4294967296.0); 
+  /* divided by 2^32 */
+}
+#else
+/* generates a random number on (0,1) with 53-bit resolution */
+static double
+randu53 (void) 
+{ 
+  const uint32_t a=randi32()>>5;
+  const uint32_t b=randi32()>>6; 
+  return (a*67108864.0+b+0.4) * (1.0/9007199254740992.0);
+} 
+#endif
+
+/* Determine mantissa for uniform doubles */
+double
+oct_randu (void)
+{
+#ifdef ALLBITS
+  return randu32 ();
+#else
+  return randu53 ();
+#endif
+}
+
+/* ===== Ziggurat normal and exponential generators ===== */
+#ifdef ALLBITS
+# define ZIGINT uint32_t
+# define EMANTISSA 4294967296.0 /* 32 bit mantissa */
+# define ERANDI randi32() /* 32 bits for mantissa */
+# define NMANTISSA 2147483648.0 /* 31 bit mantissa */
+# define NRANDI randi32() /* 31 bits for mantissa + 1 bit sign */
+# define RANDU randu32()
+#else
+# define ZIGINT uint64_t
+# define EMANTISSA 9007199254740992.0  /* 53 bit mantissa */
+# define ERANDI randi53() /* 53 bits for mantissa */
+# define NMANTISSA EMANTISSA  
+# define NRANDI randi54() /* 53 bits for mantissa + 1 bit sign */
+# define RANDU randu53()
+#endif
+
+#define ZIGGURAT_TABLE_SIZE 256
+
+#define ZIGGURAT_NOR_R 3.6541528853610088
+#define ZIGGURAT_NOR_INV_R 0.27366123732975828
+#define NOR_SECTION_AREA 0.00492867323399
+
+#define ZIGGURAT_EXP_R 7.69711747013104972
+#define ZIGGURAT_EXP_INV_R 0.129918765548341586
+#define EXP_SECTION_AREA 0.0039496598225815571993
+
+static ZIGINT ki[ZIGGURAT_TABLE_SIZE];
+static double wi[ZIGGURAT_TABLE_SIZE], fi[ZIGGURAT_TABLE_SIZE];
+static ZIGINT ke[ZIGGURAT_TABLE_SIZE];
+static double we[ZIGGURAT_TABLE_SIZE], fe[ZIGGURAT_TABLE_SIZE];
+
+/*
+This code is based on the paper Marsaglia and Tsang, "The ziggurat method
+for generating random variables", Journ. Statistical Software. Code was
+presented in this paper for a Ziggurat of 127 levels and using a 32 bit
+integer random number generator. This version of the code, uses the 
+Mersenne Twister as the integer generator and uses 256 levels in the 
+Ziggurat. This has several advantages.
+
+  1) As Marsaglia and Tsang themselves states, the more levels the few 
+     times the expensive tail algorithm must be called
+  2) The cycle time of the generator is determined by the integer 
+     generator, thus the use of a Mersenne Twister for the core random 
+     generator makes this cycle extremely long.
+  3) The license on the original code was unclear, thus rewriting the code 
+     from the article means we are free of copyright issues.
+  4) Compile flag for full 53-bit random mantissa.
+
+It should be stated that the authors made my life easier, by the fact that
+the algorithm developed in the text of the article is for a 256 level
+ziggurat, even if the code itself isn't...
+
+One modification to the algorithm developed in the article, is that it is
+assumed that 0 <= x < Inf, and "unsigned long"s are used, thus resulting in
+terms like 2^32 in the code. As the normal distribution is defined between
+-Inf < x < Inf, we effectively only have 31 bit integers plus a sign. Thus
+in Marsaglia and Tsang, terms like 2^32 become 2^31. We use NMANTISSA for
+this term.  The exponential distribution is one sided so we use the 
+full 32 bits.  We use EMANTISSA for this term.
+
+It appears that I'm slightly slower than the code in the article, this
+is partially due to a better generator of random integers than they
+use. But might also be that the case of rapid return was optimized by
+inlining the relevant code with a #define. As the basic Mersenne
+Twister is only 25% faster than this code I suspect that the main
+reason is just the use of the Mersenne Twister and not the inlining,
+so I'm not going to try and optimize further.
+*/
+
+static void 
+create_ziggurat_tables (void)
+{
+  int i;
+  double x, x1;
+ 
+  /* Ziggurat tables for the normal distribution */
+  x1 = ZIGGURAT_NOR_R;
+  wi[255] = x1 / NMANTISSA;
+  fi[255] = exp (-0.5 * x1 * x1);
+
+  /* Index zero is special for tail strip, where Marsaglia and Tsang 
+   * defines this as 
+   * k_0 = 2^31 * r * f(r) / v, w_0 = 0.5^31 * v / f(r), f_0 = 1,
+   * where v is the area of each strip of the ziggurat. 
+   */
+  ki[0] = (ZIGINT) (x1 * fi[255] / NOR_SECTION_AREA * NMANTISSA);
+  wi[0] = NOR_SECTION_AREA / fi[255] / NMANTISSA;
+  fi[0] = 1.;
+
+  for (i = 254; i > 0; i--)
+    {
+      /* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
+       * need inverse operator of y = exp(-0.5*x*x) -> x = sqrt(-2*ln(y))
+       */
+      x = sqrt(-2. * log(NOR_SECTION_AREA / x1 + fi[i+1]));
+      ki[i+1] = (ZIGINT)(x / x1 * NMANTISSA);
+      wi[i] = x / NMANTISSA;
+      fi[i] = exp (-0.5 * x * x);
+      x1 = x;
+    }
+
+  ki[1] = 0;
+
+  /* Zigurrat tables for the exponential distribution */
+  x1 = ZIGGURAT_EXP_R;
+  we[255] = x1 / EMANTISSA;
+  fe[255] = exp (-x1);
+
+  /* Index zero is special for tail strip, where Marsaglia and Tsang 
+   * defines this as 
+   * k_0 = 2^32 * r * f(r) / v, w_0 = 0.5^32 * v / f(r), f_0 = 1,
+   * where v is the area of each strip of the ziggurat. 
+   */
+  ke[0] = (ZIGINT) (x1 * fe[255] / EXP_SECTION_AREA * EMANTISSA);
+  we[0] = EXP_SECTION_AREA / fe[255] / EMANTISSA;
+  fe[0] = 1.;
+
+  for (i = 254; i > 0; i--)
+    {
+      /* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
+       * need inverse operator of y = exp(-x) -> x = -ln(y)
+       */
+      x = - log(EXP_SECTION_AREA / x1 + fe[i+1]);
+      ke[i+1] = (ZIGINT)(x / x1 * EMANTISSA);
+      we[i] = x / EMANTISSA;
+      fe[i] = exp (-x);
+      x1 = x;
+    }
+  ke[1] = 0;
+
+  initt = 0;
+}
+
+/*
+ * Here is the guts of the algorithm. As Marsaglia and Tsang state the
+ * algorithm in their paper
+ *
+ * 1) Calculate a random signed integer j and let i be the index
+ *     provided by the rightmost 8-bits of j
+ * 2) Set x = j * w_i. If j < k_i return x
+ * 3) If i = 0, then return x from the tail
+ * 4) If [f(x_{i-1}) - f(x_i)] * U < f(x) - f(x_i), return x
+ * 5) goto step 1
+ *
+ * Where f is the functional form of the distribution, which for a normal
+ * distribution is exp(-0.5*x*x)
+ */
+
+double
+oct_randn (void)
+{
+  if (initt) 
+    create_ziggurat_tables();
+
+  while (1)
+    {
+      /* The following code is specialized for 32-bit mantissa.
+       * Compared to the arbitrary mantissa code, there is a performance
+       * gain for 32-bits:  PPC: 2%, MIPS: 8%, x86: 40%
+       * There is a bigger performance gain compared to using a full
+       * 53-bit mantissa:  PPC: 60%, MIPS: 65%, x86: 240%
+       * Of course, different compilers and operating systems may
+       * have something to do with this.
+       */
+#if !defined(ALLBITS)
+# if HAVE_X86_32
+      /* 53-bit mantissa, 1-bit sign, x86 32-bit architecture */
+      double x;
+      int si,idx;
+      register uint32_t lo, hi;
+      int64_t rabs;
+      uint32_t *p = (uint32_t *)&rabs;
+      lo = randi32();
+      idx = lo&0xFF;
+      hi = randi32();
+      si = hi&UMASK;
+      p[0] = lo;
+      p[1] = hi&0x1FFFFF;
+      x = ( si ? -rabs : rabs ) * wi[idx];
+# else /* !HAVE_X86_32 */
+      /* arbitrary mantissa (selected by NRANDI, with 1 bit for sign) */
+      const uint64_t r = NRANDI;
+      const int64_t rabs=r>>1;
+      const int idx = (int)(rabs&0xFF);
+      const double x = ( r&1 ? -rabs : rabs) * wi[idx];
+# endif /* !HAVE_X86_32 */
+      if (rabs < (int64_t)ki[idx])
+#else /* ALLBITS */
+      /* 32-bit mantissa */
+      const uint32_t r = randi32();
+      const uint32_t rabs = r&LMASK;
+      const int idx = (int)(r&0xFF);
+      const double x = ((int32_t)r) * wi[idx];
+      if (rabs < ki[idx])
+#endif /* ALLBITS */
+	return x;        /* 99.3% of the time we return here 1st try */
+      else if (idx == 0)
+	{
+	  /* As stated in Marsaglia and Tsang
+	   * 
+	   * For the normal tail, the method of Marsaglia[5] provides:
+	   * generate x = -ln(U_1)/r, y = -ln(U_2), until y+y > x*x,
+	   * then return r+x. Except that r+x is always in the positive 
+	   * tail!!!! Any thing random might be used to determine the
+	   * sign, but as we already have r we might as well use it
+	   *
+	   * [PAK] but not the bottom 8 bits, since they are all 0 here!
+	   */
+	  double xx, yy;
+	  do
+	    {
+	      xx = - ZIGGURAT_NOR_INV_R * log (RANDU);
+	      yy = - log (RANDU);
+	    } 
+	  while ( yy+yy <= xx*xx);
+	  return (rabs&0x100 ? -ZIGGURAT_NOR_R-xx : ZIGGURAT_NOR_R+xx);
+	}
+      else if ((fi[idx-1] - fi[idx]) * RANDU + fi[idx] < exp(-0.5*x*x))
+	return x;
+    }
+}
+
+double
+oct_rande (void)
+{
+  if (initt) 
+    create_ziggurat_tables();
+
+  while (1)
+    {
+      ZIGINT ri = ERANDI;
+      const int idx = (int)(ri & 0xFF);
+      const double x = ri * we[idx];
+      if (ri < ke[idx])
+	return x;		// 98.9% of the time we return here 1st try
+      else if (idx == 0)
+	{
+	  /* As stated in Marsaglia and Tsang
+	   * 
+	   * For the exponential tail, the method of Marsaglia[5] provides:
+           * x = r - ln(U);
+	   */
+	  return ZIGGURAT_EXP_R - log(RANDU);
+	}
+      else if ((fe[idx-1] - fe[idx]) * RANDU + fe[idx] < exp(-x))
+	return x;
+    }
+}
+
+/* Array generators */
+void 
+oct_fill_randu (octave_idx_type n, double *p)
+{
+  octave_idx_type i;
+  for (i = 0; i < n; i++) 
+    p[i] = oct_randu();
+}
+
+void 
+oct_fill_randn (octave_idx_type n, double *p)
+{
+  octave_idx_type i;
+  for (i = 0; i < n; i++) 
+    p[i] = oct_randn();
+}
+
+void 
+oct_fill_rande (octave_idx_type n, double *p)
+{
+  octave_idx_type i;
+  for (i = 0; i < n; i++) 
+    p[i] = oct_rande();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/liboctave/randmtzig.h b/liboctave/randmtzig.h
new file mode 100644
index 0000000..ac47df5
--- /dev/null
+++ b/liboctave/randmtzig.h
@@ -0,0 +1,102 @@
+/*
+
+Copyright (C) 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/* 
+   A C-program for MT19937, with initialization improved 2002/2/10.
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+   This is a faster version by taking Shawn Cokus's optimization,
+   Matthe Bellew's simplification, Isaku Wada's real version.
+   David Bateman added normal and exponential distributions following
+   Marsaglia and Tang's Ziggurat algorithm.
+
+   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+   Copyright (C) 2004, David Bateman
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote 
+        products derived from this software without specific prior written 
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 
+   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.
+
+*/
+
+#ifndef _RANDMTZIG_H
+#define _RANDMTZIG_H
+
+#include "oct-types.h"
+
+#define MT_N 624
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* === Mersenne Twister === */
+extern void oct_init_by_int (uint32_t s);
+extern void oct_init_by_array (uint32_t init_key[], int key_length);
+extern void oct_init_by_entropy (void);
+extern void oct_set_state (uint32_t save[]);
+extern void oct_get_state (uint32_t save[]);
+
+/* === Array generators === */
+extern double oct_randu (void);
+extern double oct_randn (void);
+extern double oct_rande (void);
+
+/* === Array generators === */
+extern void oct_fill_randu (octave_idx_type n, double *p);
+extern void oct_fill_randn (octave_idx_type n, double *p);
+extern void oct_fill_rande (octave_idx_type n, double *p);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
+
diff --git a/liboctave/randpoisson.c b/liboctave/randpoisson.c
new file mode 100644
index 0000000..2a9e42e
--- /dev/null
+++ b/liboctave/randpoisson.c
@@ -0,0 +1,471 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/* Original version written by Paul Kienzle distributed as free
+   software in the in the public domain.  */
+
+/* Needs the following defines: 
+ * NAN: value to return for Not-A-Number
+ * RUNI: uniform generator on (0,1)
+ * RNOR: normal generator
+ * LGAMMA: log gamma function
+ * INFINITE: function to test whether a value is infinite
+ */
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "f77-fcn.h"
+#include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-math.h"
+#include "randmtzig.h"
+#include "randpoisson.h"
+
+#undef NAN
+#define NAN octave_NaN
+#undef INFINITE
+#define INFINITE lo_ieee_isinf
+#define RUNI oct_randu()
+#define RNOR oct_randn()
+#define LGAMMA xlgamma
+
+F77_RET_T
+F77_FUNC (dlgams, DLGAMS) (const double *, double *, double *);
+
+static double
+xlgamma (double x)
+{
+  double result;
+#ifdef HAVE_LGAMMA
+  result = lgamma (x);
+#else
+  double sgngam;
+
+  if (lo_ieee_isnan (x))
+    result = x;
+  else if (x <= 0 || lo_ieee_isinf (x))
+    result = octave_Inf;
+  else
+    F77_XFCN (dlgams, DLGAMS, (&x, &result, &sgngam));
+#endif
+  return result;
+}
+
+/* ---- pprsc.c from Stadloeber's winrand --- */
+
+/* flogfak(k) = ln(k!) */
+static double 
+flogfak (double k)
+{
+#define       C0      9.18938533204672742e-01
+#define       C1      8.33333333333333333e-02
+#define       C3     -2.77777777777777778e-03
+#define       C5      7.93650793650793651e-04
+#define       C7     -5.95238095238095238e-04
+
+  static double logfak[30L] = {
+    0.00000000000000000,   0.00000000000000000,   0.69314718055994531,
+    1.79175946922805500,   3.17805383034794562,   4.78749174278204599,
+    6.57925121201010100,   8.52516136106541430,  10.60460290274525023,
+    12.80182748008146961,  15.10441257307551530,  17.50230784587388584,
+    19.98721449566188615,  22.55216385312342289,  25.19122118273868150,
+    27.89927138384089157,  30.67186010608067280,  33.50507345013688888,
+    36.39544520803305358,  39.33988418719949404,  42.33561646075348503,
+    45.38013889847690803,  48.47118135183522388,  51.60667556776437357,
+    54.78472939811231919,  58.00360522298051994,  61.26170176100200198,
+    64.55753862700633106,  67.88974313718153498,  71.25703896716800901
+  };
+  
+  double  r, rr;
+  
+  if (k >= 30.0) 
+    {
+      r  = 1.0 / k;
+      rr = r * r;
+      return ((k + 0.5)*log(k) - k + C0 + r*(C1 + rr*(C3 + rr*(C5 + rr*C7))));
+    }
+  else
+    return (logfak[(int)k]);
+}
+
+
+/******************************************************************
+ *                                                                *
+ * Poisson Distribution - Patchwork Rejection/Inversion  *
+ *                                                                *
+ ******************************************************************
+ *                                                                *
+ * For parameter  my < 10  Tabulated Inversion is applied.        *
+ * For my >= 10  Patchwork Rejection is employed:                 *
+ * The area below the histogram function f(x) is rearranged in    *
+ * its body by certain point reflections. Within a large center   *
+ * interval variates are sampled efficiently by rejection from    *
+ * uniform hats. Rectangular immediate acceptance regions speed   *
+ * up the generation. The remaining tails are covered by          *
+ * exponential functions.                                         *
+ *                                                                *
+ ******************************************************************
+ *                                                                *
+ * FUNCTION :   - pprsc samples a random number from the Poisson  *
+ *                distribution with parameter my > 0.             *
+ * REFERENCE :  - H. Zechner (1994): Efficient sampling from      *
+ *                continuous and discrete unimodal distributions, *
+ *                Doctoral Dissertation, 156 pp., Technical       *
+ *                University Graz, Austria.                       *
+ * SUBPROGRAM : - drand(seed) ... (0,1)-Uniform generator with    *
+ *                unsigned long integer *seed.                    *
+ *                                                                *
+ * Implemented by H. Zechner, January 1994                        *
+ * Revised by F. Niederl, July 1994                               *
+ *                                                                *
+ ******************************************************************/
+
+static double 
+f (double k, double l_nu, double c_pm)
+{
+  return exp(k * l_nu - flogfak(k) - c_pm);
+}
+
+static double 
+pprsc (double my)
+{
+  static double        my_last = -1.0;
+  static double        m,  k2, k4, k1, k5;
+  static double        dl, dr, r1, r2, r4, r5, ll, lr, l_my, c_pm,
+    f1, f2, f4, f5, p1, p2, p3, p4, p5, p6;
+  double               Dk, X, Y;
+  double               Ds, U, V, W;
+  
+  if (my != my_last)
+    {                               /* set-up           */
+      my_last = my;
+      /* approximate deviation of reflection points k2, k4 from my - 1/2 */
+      Ds = sqrt(my + 0.25);
+      
+      /* mode m, reflection points k2 and k4, and points k1 and k5,      */
+      /* which delimit the centre region of h(x)                         */
+      m  = floor(my);
+      k2 = ceil(my - 0.5 - Ds);
+      k4 = floor(my - 0.5 + Ds);
+      k1 = k2 + k2 - m + 1L;
+      k5 = k4 + k4 - m;
+      
+      /* range width of the critical left and right centre region        */
+      dl = (k2 - k1);
+      dr = (k5 - k4);
+      
+      /* recurrence constants r(k)=p(k)/p(k-1) at k = k1, k2, k4+1, k5+1 */
+      r1 = my / k1;
+      r2 = my / k2;
+      r4 = my / (k4 + 1.0);
+      r5 = my / (k5 + 1.0);
+
+      /* reciprocal values of the scale parameters of exp. tail envelope */
+      ll =  log(r1);                                 /* expon. tail left */
+      lr = -log(r5);                                 /* expon. tail right*/
+      
+      /* Poisson constants, necessary for computing function values f(k) */
+      l_my = log(my);
+      c_pm = m * l_my - flogfak(m);
+      
+      /* function values f(k) = p(k)/p(m) at k = k2, k4, k1, k5          */
+      f2 = f(k2, l_my, c_pm);
+      f4 = f(k4, l_my, c_pm);
+      f1 = f(k1, l_my, c_pm);
+      f5 = f(k5, l_my, c_pm);
+      
+      /* area of the two centre and the two exponential tail regions     */
+      /* area of the two immediate acceptance regions between k2, k4     */
+      p1 = f2 * (dl + 1.0);                            /* immed. left    */
+      p2 = f2 * dl         + p1;                       /* centre left    */
+      p3 = f4 * (dr + 1.0) + p2;                       /* immed. right   */
+      p4 = f4 * dr         + p3;                       /* centre right   */
+      p5 = f1 / ll         + p4;                       /* exp. tail left */
+      p6 = f5 / lr         + p5;                       /* exp. tail right*/
+    }
+  
+  for (;;)
+    {
+      /* generate uniform number U -- U(0, p6)                           */
+      /* case distinction corresponding to U                             */
+      if ((U = RUNI * p6) < p2)
+	{                                            /* centre left      */
+	  
+	  /* immediate acceptance region 
+	     R2 = [k2, m) *[0, f2),  X = k2, ... m -1 */
+	  if ((V = U - p1) < 0.0)  return(k2 + floor(U/f2));
+	  /* immediate acceptance region 
+	     R1 = [k1, k2)*[0, f1),  X = k1, ... k2-1 */
+	  if ((W = V / dl) < f1 )  return(k1 + floor(V/f1));
+	  
+	  /* computation of candidate X < k2, and its counterpart Y > k2 */
+	  /* either squeeze-acceptance of X or acceptance-rejection of Y */
+	  Dk = floor(dl * RUNI) + 1.0;
+	  if (W <= f2 - Dk * (f2 - f2/r2))
+	    {                                        /* quick accept of  */
+	      return(k2 - Dk);                       /* X = k2 - Dk      */
+	    }
+	  if ((V = f2 + f2 - W) < 1.0)
+	    {                                        /* quick reject of Y*/
+	      Y = k2 + Dk;
+	      if (V <= f2 + Dk * (1.0 - f2)/(dl + 1.0))
+		{                                    /* quick accept of  */
+		  return(Y);                         /* Y = k2 + Dk      */
+		}
+	      if (V <= f(Y, l_my, c_pm))  return(Y); /* final accept of Y*/
+	    }
+	  X = k2 - Dk;
+	}
+      else if (U < p4)
+	{                                            /* centre right     */
+	  /*  immediate acceptance region 
+	      R3 = [m, k4+1)*[0, f4), X = m, ... k4    */
+	  if ((V = U - p3) < 0.0)  return(k4 - floor((U - p2)/f4));
+	  /* immediate acceptance region 
+	     R4 = [k4+1, k5+1)*[0, f5)                */
+	  if ((W = V / dr) < f5 )  return(k5 - floor(V/f5));
+	  
+	  /* computation of candidate X > k4, and its counterpart Y < k4 */
+	  /* either squeeze-acceptance of X or acceptance-rejection of Y */
+	  Dk = floor(dr * RUNI) + 1.0;
+	  if (W <= f4 - Dk * (f4 - f4*r4))
+	    {                                        /* quick accept of  */
+	      return(k4 + Dk);                       /* X = k4 + Dk      */
+	    }
+	  if ((V = f4 + f4 - W) < 1.0)
+	    {                                        /* quick reject of Y*/
+	      Y = k4 - Dk;
+	      if (V <= f4 + Dk * (1.0 - f4)/ dr)
+		{                                    /* quick accept of  */
+		  return(Y);                         /* Y = k4 - Dk      */
+		}
+	      if (V <= f(Y, l_my, c_pm))  return(Y); /* final accept of Y*/
+	    }
+	  X = k4 + Dk;
+	}
+      else
+	{
+	  W = RUNI;
+	  if (U < p5)
+	    {                                        /* expon. tail left */
+	      Dk = floor(1.0 - log(W)/ll);
+	      if ((X = k1 - Dk) < 0L)  continue;     /* 0 <= X <= k1 - 1 */
+	      W *= (U - p4) * ll;                    /* W -- U(0, h(x))  */
+	      if (W <= f1 - Dk * (f1 - f1/r1))  
+		return(X);                           /* quick accept of X*/
+	    }
+	  else
+	    {                                        /* expon. tail right*/
+	      Dk = floor(1.0 - log(W)/lr);
+	      X  = k5 + Dk;                          /* X >= k5 + 1      */
+	      W *= (U - p5) * lr;                    /* W -- U(0, h(x))  */
+	      if (W <= f5 - Dk * (f5 - f5*r5))  
+		return(X);                           /* quick accept of X*/
+	    }
+	}
+      
+      /* acceptance-rejection test of candidate X from the original area */
+      /* test, whether  W <= f(k),    with  W = U*h(x)  and  U -- U(0, 1)*/
+      /* log f(X) = (X - m)*log(my) - log X! + log m!                    */
+      if (log(W) <= X * l_my - flogfak(X) - c_pm)  return(X);
+    }
+}
+/* ---- pprsc.c end ------ */
+
+
+/* The remainder of the file is by Paul Kienzle */
+
+/* Given uniform u, find x such that CDF(L,x)==u.  Return x. */
+static void 
+poisson_cdf_lookup(double lambda, double *p, size_t n)
+{
+  /* Table size is predicated on the maximum value of lambda
+   * we want to store in the table, and the maximum value of
+   * returned by the uniform random number generator on [0,1).
+   * With lambda==10 and u_max = 1 - 1/(2^32+1), we
+   * have poisson_pdf(lambda,36) < 1-u_max.  If instead our
+   * generator uses more bits of mantissa or returns a value
+   * in the range [0,1], then for lambda==10 we need a table 
+   * size of 46 instead.  For long doubles, the table size 
+   * will need to be longer still.  */
+#define TABLESIZE 46
+  double t[TABLESIZE];
+  
+  /* Precompute the table for the u up to and including 0.458.
+   * We will almost certainly need it. */
+  int intlambda = (int)floor(lambda);
+  double P;
+  int tableidx;
+  size_t i = n;
+  
+  t[0] = P = exp(-lambda);
+  for (tableidx = 1; tableidx <= intlambda; tableidx++) {
+    P = P*lambda/(double)tableidx;
+    t[tableidx] = t[tableidx-1] + P;
+  }
+
+  while (i-- > 0) {
+    double u = RUNI;
+    
+    /* If u > 0.458 we know we can jump to floor(lambda) before
+     * comparing (this observation is based on Stadlober's winrand
+     * code). For lambda >= 1, this will be a win.  Lambda < 1
+     * is already fast, so adding an extra comparison is not a
+     * problem. */
+    int k = (u > 0.458 ? intlambda : 0);
+
+    /* We aren't using a for loop here because when we find the
+     * right k we want to jump to the next iteration of the
+     * outer loop, and the continue statement will only work for 
+     * the inner loop. */
+  nextk:
+    if ( u <= t[k] ) {
+      p[i] = (double) k;
+      continue;
+    }
+    if (++k < tableidx) goto nextk;
+    
+    /* We only need high values of the table very rarely so we 
+     * don't automatically compute the entire table. */
+    while (tableidx < TABLESIZE) {
+      P = P*lambda/(double)tableidx;
+      t[tableidx] = t[tableidx-1] + P;
+      /* Make sure we converge to 1.0 just in case u is uniform
+       * on [0,1] rather than [0,1). */
+      if (t[tableidx] == t[tableidx-1]) t[tableidx] = 1.0;
+      tableidx++;
+      if (u <= t[tableidx-1]) break;
+    }
+    
+    /* We are assuming that the table size is big enough here.
+     * This should be true even if RUNI is returning values in
+     * the range [0,1] rather than [0,1).
+     */
+    p[i] = (double)(tableidx-1);
+  }
+}
+
+/* From Press, et al., Numerical Recipes */
+static void
+poisson_rejection (double lambda, double *p, size_t n)
+{
+  double sq = sqrt(2.0*lambda);
+  double alxm = log(lambda);
+  double g = lambda*alxm - LGAMMA(lambda+1.0);
+  size_t i;
+  
+  for (i = 0; i < n; i++) 
+    {
+      double y, em, t;
+      do {
+	do {
+	  y = tan(M_PI*RUNI);
+	  em = sq * y + lambda;
+	} while (em < 0.0);
+	em = floor(em);
+	t = 0.9*(1.0+y*y)*exp(em*alxm-flogfak(em)-g);
+      } while (RUNI > t);
+      p[i] = em;
+    }
+}
+
+/* The cutoff of L <= 1e8 in the following two functions before using 
+ * the normal approximation is based on:
+ *   > L=1e8; x=floor(linspace(0,2*L,1000));
+ *   > max(abs(normal_pdf(x,L,L)-poisson_pdf(x,L)))
+ *   ans =  1.1376e-28
+ * For L=1e7, the max is around 1e-9, which is within the step size of RUNI.
+ * For L>1e10 the pprsc function breaks down, as I saw from the histogram
+ * of a large sample, so 1e8 is both small enough and large enough. */
+
+/* Generate a set of poisson numbers with the same distribution */
+void 
+oct_fill_randp (double L, octave_idx_type n, double *p)
+{
+  octave_idx_type i;
+  if (L < 0.0 || INFINITE(L)) 
+    {
+      for (i=0; i<n; i++) 
+	p[i] = NAN;
+    } 
+  else if (L <= 10.0) 
+    {
+      poisson_cdf_lookup(L, p, n);
+    } 
+  else if (L <= 1e8) 
+    {
+      for (i=0; i<n; i++) 
+	p[i] = pprsc(L);
+    } 
+  else 
+    {
+      /* normal approximation: from Phys. Rev. D (1994) v50 p1284 */
+      const double sqrtL = sqrt(L);
+      for (i = 0; i < n; i++) 
+	{
+	  p[i] = floor(RNOR*sqrtL + L + 0.5);
+	  if (p[i] < 0.0) 
+	    p[i] = 0.0; /* will probably never happen */
+	}
+    }
+}
+
+/* Generate one poisson variate */
+double 
+oct_randp (double L)
+{
+  double ret;
+  if (L < 0.0) ret = NAN;
+  else if (L <= 12.0) {
+    /* From Press, et al. Numerical recipes */
+    double g = exp(-L);
+    int em = -1;
+    double t = 1.0;
+    do {
+      ++em;
+      t *= RUNI;
+    } while (t > g);
+    ret = em;
+  } else if (L <= 1e8) {
+    /* numerical recipes */
+    poisson_rejection(L, &ret, 1);
+  } else if (INFINITE(L)) {
+    /* FIXME R uses NaN, but the normal approx. suggests that as
+     * limit should be inf. Which is correct? */
+    ret = NAN;
+  } else {
+    /* normal approximation: from Phys. Rev. D (1994) v50 p1284 */
+    ret = floor(RNOR*sqrt(L) + L + 0.5);
+    if (ret < 0.0) ret = 0.0; /* will probably never happen */
+  }
+  return ret;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/liboctave/randpoisson.h b/liboctave/randpoisson.h
new file mode 100644
index 0000000..4bdf269
--- /dev/null
+++ b/liboctave/randpoisson.h
@@ -0,0 +1,47 @@
+/*
+
+Copyright (C) 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/* Original version written by Paul Kienzle distributed as free
+   software in the in the public domain.  */
+
+#ifndef _RANDPOISSON_H
+
+#include "oct-types.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+extern double oct_randp (double L);
+extern void oct_fill_randp (double L, octave_idx_type n, double *p);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
+
diff --git a/liboctave/regex-match.cc b/liboctave/regex-match.cc
new file mode 100644
index 0000000..e45654d
--- /dev/null
+++ b/liboctave/regex-match.cc
@@ -0,0 +1,157 @@
+/*
+
+Copyright (C) 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+#include <iostream>
+#include <string>
+
+#include "regex-match.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+regex_match& 
+regex_match::operator = (const regex_match& gm)
+{
+  if (this != &gm)
+    {
+#if HAVE_REGEX
+      for (int i = 0; i < pat.length (); i++)
+	regfree (compiled +i);
+      delete [] compiled;
+#endif
+      pat = gm.pat;
+      case_insen = gm.case_insen;
+      init ();
+    }
+  return *this;
+}
+
+regex_match::~regex_match (void)
+{
+#if HAVE_REGEX
+  for (int i = 0; i < pat.length (); i++)
+    regfree (compiled +i);
+  delete [] compiled;
+#endif
+}
+
+
+void 
+regex_match::set_pattern (const std::string& p) 
+{ 
+#if HAVE_REGEX
+  for (int i = 0; i < pat.length (); i++)
+    regfree (compiled +i);
+  delete [] compiled;
+#endif
+  pat = p; 
+  init ();
+}
+
+void 
+regex_match::set_pattern (const string_vector& p) 
+{ 
+#if HAVE_REGEX
+  for (int i = 0; i < pat.length (); i++)
+    regfree (compiled +i);
+  delete [] compiled;
+#endif
+  pat = p; 
+  init ();
+}
+
+void
+regex_match::init (void)
+{
+#ifdef HAVE_REGEX
+  int npat = pat.length ();
+  int err = 0;
+  int i;
+
+  compiled = new regex_t [npat];
+
+  for (i = 0; i < npat; i++)
+    {
+      err = regcomp (compiled + i, pat(i).c_str (), 
+		     (REG_NOSUB | REG_EXTENDED |
+		      (case_insen ? REG_ICASE : 0)));
+      if (err)
+	break;
+    }
+  
+  if (err)
+    {
+      int len = regerror (err, compiled + i, 0, 0);
+      OCTAVE_LOCAL_BUFFER (char, errmsg, len);
+      regerror(err, compiled + i, errmsg, len);
+      (*current_liboctave_error_handler) ("%s in pattern (%s)", errmsg, 
+					  pat(i).c_str());
+
+      for (int j = 0; j < i + 1; j++)
+	regfree (compiled + j);
+    }
+#else
+  (*current_liboctave_error_handler) 
+    ("regex not available in this version of Octave"); 
+#endif
+}
+
+bool
+regex_match::match (const std::string& s)
+{
+#if HAVE_REGEX
+  int npat = pat.length ();
+
+  const char *str = s.c_str ();
+
+  for (int i = 0; i < npat; i++)
+    if (regexec (compiled + i, str, 0, 0, 0) == 0) 
+      return true;
+#endif
+
+  return false;
+}
+
+Array<bool>
+regex_match::match (const string_vector& s)
+{
+  int n = s.length ();
+
+  Array<bool> retval (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = match (s[i]);
+
+  return retval;
+}
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/regex-match.h b/liboctave/regex-match.h
new file mode 100644
index 0000000..d757918
--- /dev/null
+++ b/liboctave/regex-match.h
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2008  David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_regex_match_h)
+#define octave_regex_match_h 1
+
+#include <string>
+
+#if defined (HAVE_REGEX)
+#if defined (__MINGW32__)
+#define __restrict
+#endif
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#include <regex.h>
+#endif
+
+#include "Array.h"
+#include "str-vec.h"
+
+class
+OCTAVE_API
+regex_match
+{
+public:
+
+  regex_match (const std::string& p, bool insen = false) 
+    : pat (p), case_insen (insen) { init (); }
+
+  regex_match (const string_vector& p = string_vector (), bool insen = false) 
+    : pat (p), case_insen (insen) { init (); }
+
+  regex_match (const regex_match& gm) 
+    : pat (gm.pat), case_insen (gm.case_insen) { init (); }
+
+  regex_match& operator = (const regex_match& gm);
+
+  ~regex_match (void);
+
+  void set_pattern (const std::string& p);
+
+  void set_pattern (const string_vector& p);
+
+  bool match (const std::string&);
+
+  Array<bool> match (const string_vector&);
+
+private:
+
+  void init (void);
+
+  // Regex pattern(s).
+  string_vector pat;
+
+  // Should match be case insensitive
+  bool case_insen;
+
+#if HAVE_REGEX
+  regex_t *compiled;
+#endif
+
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/rename.c b/liboctave/rename.c
new file mode 100644
index 0000000..8a5ee80
--- /dev/null
+++ b/liboctave/rename.c
@@ -0,0 +1,112 @@
+/* rename.c -- BSD compatible directory function for System V
+   Copyright (C) 1988, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_RENAME
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISDIR
+#endif /* STAT_MACROS_BROKEN.  */
+
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#include "safe-stat.h"
+
+/* Rename file FROM to file TO.
+   Return 0 if successful, -1 if not. */
+
+int
+rename (from, to)
+     char *from;
+     char *to;
+{
+  struct stat from_stats, to_stats;
+  int pid, status;
+
+  if (SAFE_STAT (from, &from_stats))
+    return -1;
+
+  /* Be careful not to unlink `from' if it happens to be equal to `to' or
+     (on filesystems that silently truncate filenames after 14 characters)
+     if `from' and `to' share the significant characters. */
+  if (SAFE_STAT (to, &to_stats))
+    {
+      if (errno != ENOENT)
+        return -1;
+    }
+  else
+    {
+      if ((from_stats.st_dev == to_stats.st_dev)
+          && (from_stats.st_ino == to_stats.st_dev))
+        /* `from' and `to' designate the same file on that filesystem. */
+        return 0;
+
+      if (unlink (to) && errno != ENOENT)
+        return -1;
+    }
+
+  if (S_ISDIR (from_stats.st_mode))
+    {
+      /* Need a setuid root process to link and unlink directories. */
+      pid = fork ();
+      switch (pid)
+	{
+	case -1:		/* Error. */
+	  error (1, errno, "cannot fork");
+
+	case 0:			/* Child. */
+	  execl (MVDIR, "mvdir", from, to, (char *) 0);
+	  error (255, errno, "cannot run `%s'", MVDIR);
+
+	default:		/* Parent. */
+	  while (wait (&status) != pid)
+	    /* Do nothing. */ ;
+
+	  errno = 0;		/* mvdir printed the system error message. */
+	  if (status)
+	    return -1;
+	}
+    }
+  else
+    {
+      if (link (from, to))
+	return -1;
+      if (unlink (from) && errno != ENOENT)
+	{
+	  unlink (to);
+	  return -1;
+	}
+    }
+  return 0;
+}
+
+#endif
diff --git a/liboctave/rmdir.c b/liboctave/rmdir.c
new file mode 100644
index 0000000..25f65b5
--- /dev/null
+++ b/liboctave/rmdir.c
@@ -0,0 +1,95 @@
+/* rmdir.c -- BSD compatible remove directory function for System V
+   Copyright (C) 1988, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_RMDIR
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISDIR
+#endif
+
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#include "safe-stat.h"
+
+/* rmdir adapted from GNU tar.  */
+
+/* Remove directory DPATH.
+   Return 0 if successful, -1 if not.  */
+
+int
+rmdir (dpath)
+     char *dpath;
+{
+  int cpid, status;
+  struct stat statbuf;
+
+  if (SAFE_STAT (dpath, &statbuf) != 0)
+    return -1;			/* errno already set */
+
+  if (!S_ISDIR (statbuf.st_mode))
+    {
+      errno = ENOTDIR;
+      return -1;
+    }
+
+  cpid = fork ();
+  switch (cpid)
+    {
+    case -1:			/* cannot fork */
+      return -1;		/* errno already set */
+
+    case 0:			/* child process */
+      execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
+      _exit (1);
+
+    default:			/* parent process */
+
+      /* Wait for kid to finish.  */
+
+      while (wait (&status) != cpid)
+	/* Do nothing.  */ ;
+
+      if (status & 0xFFFF)
+	{
+
+	  /* /bin/rmdir failed.  */
+
+	  errno = EIO;
+	  return -1;
+	}
+      return 0;
+    }
+}
+
+#endif
diff --git a/liboctave/smx-bm-sbm.cc b/liboctave/smx-bm-sbm.cc
new file mode 100644
index 0000000..4416571
--- /dev/null
+++ b/liboctave/smx-bm-sbm.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-bm-sbm.h"
+#include "boolMatrix.h"
+#include "boolSparse.h"
+#include "boolSparse.h"
+SPARSE_MSM_EQNE_OPS (boolMatrix, false, , SparseBoolMatrix, false, )
+SPARSE_MSM_BOOL_OPS2 (boolMatrix, SparseBoolMatrix, false, false)
diff --git a/liboctave/smx-bm-sbm.h b/liboctave/smx-bm-sbm.h
new file mode 100644
index 0000000..df56274
--- /dev/null
+++ b/liboctave/smx-bm-sbm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_bm_sbm_h)
+#define octave_smx_bm_sbm_h 1
+#include "boolMatrix.h"
+#include "boolSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_MSM_EQNE_OP_DECLS (boolMatrix, SparseBoolMatrix, OCTAVE_API)
+SPARSE_MSM_BOOL_OP_DECLS (boolMatrix, SparseBoolMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-cm-scm.cc b/liboctave/smx-cm-scm.cc
new file mode 100644
index 0000000..b33e1d7
--- /dev/null
+++ b/liboctave/smx-cm-scm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-cm-scm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "CSparse.h"
+SPARSE_MSM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, ComplexMatrix, SparseComplexMatrix)
+SPARSE_MSM_CMP_OPS (ComplexMatrix, 0.0, real, SparseComplexMatrix, 0.0, real)
+SPARSE_MSM_BOOL_OPS2 (ComplexMatrix, SparseComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-cm-scm.h b/liboctave/smx-cm-scm.h
new file mode 100644
index 0000000..1792ad6
--- /dev/null
+++ b/liboctave/smx-cm-scm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_cm_scm_h)
+#define octave_smx_cm_scm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_MSM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, ComplexMatrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_MSM_CMP_OP_DECLS (ComplexMatrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_MSM_BOOL_OP_DECLS (ComplexMatrix, SparseComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-cm-sm.cc b/liboctave/smx-cm-sm.cc
new file mode 100644
index 0000000..339447d
--- /dev/null
+++ b/liboctave/smx-cm-sm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-cm-sm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dSparse.h"
+SPARSE_MSM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, ComplexMatrix, SparseMatrix)
+SPARSE_MSM_CMP_OPS (ComplexMatrix, 0.0, real, SparseMatrix, 0.0, )
+SPARSE_MSM_BOOL_OPS2 (ComplexMatrix, SparseMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-cm-sm.h b/liboctave/smx-cm-sm.h
new file mode 100644
index 0000000..d7472cb
--- /dev/null
+++ b/liboctave/smx-cm-sm.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_cm_sm_h)
+#define octave_smx_cm_sm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_MSM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, ComplexMatrix, SparseMatrix, OCTAVE_API)
+SPARSE_MSM_CMP_OP_DECLS (ComplexMatrix, SparseMatrix, OCTAVE_API)
+SPARSE_MSM_BOOL_OP_DECLS (ComplexMatrix, SparseMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-cs-sm.cc b/liboctave/smx-cs-sm.cc
new file mode 100644
index 0000000..130e411
--- /dev/null
+++ b/liboctave/smx-cs-sm.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-cs-sm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "oct-cmplx.h"
+#include "dSparse.h"
+SPARSE_SSM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, Complex, SparseMatrix)
+SPARSE_SSM_CMP_OPS (Complex, 0.0, real, SparseMatrix, 0.0, )
+SPARSE_SSM_BOOL_OPS2 (Complex, SparseMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-cs-sm.h b/liboctave/smx-cs-sm.h
new file mode 100644
index 0000000..16f38da
--- /dev/null
+++ b/liboctave/smx-cs-sm.h
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_cs_sm_h)
+#define octave_smx_cs_sm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "oct-cmplx.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SSM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, Complex, SparseMatrix, OCTAVE_API)
+SPARSE_SSM_CMP_OP_DECLS (Complex, SparseMatrix, OCTAVE_API)
+SPARSE_SSM_BOOL_OP_DECLS (Complex, SparseMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-m-scm.cc b/liboctave/smx-m-scm.cc
new file mode 100644
index 0000000..f242a12
--- /dev/null
+++ b/liboctave/smx-m-scm.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-m-scm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dMatrix.h"
+#include "CSparse.h"
+SPARSE_MSM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, Matrix, SparseComplexMatrix)
+SPARSE_MSM_CMP_OPS (Matrix, 0.0, , SparseComplexMatrix, 0.0, real)
+SPARSE_MSM_BOOL_OPS2 (Matrix, SparseComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-m-scm.h b/liboctave/smx-m-scm.h
new file mode 100644
index 0000000..861879b
--- /dev/null
+++ b/liboctave/smx-m-scm.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_m_scm_h)
+#define octave_smx_m_scm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dMatrix.h"
+#include "Sparse-op-defs.h"
+SPARSE_MSM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, Matrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_MSM_CMP_OP_DECLS (Matrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_MSM_BOOL_OP_DECLS (Matrix, SparseComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-m-sm.cc b/liboctave/smx-m-sm.cc
new file mode 100644
index 0000000..e668e00
--- /dev/null
+++ b/liboctave/smx-m-sm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-m-sm.h"
+#include "boolSparse.h"
+#include "dMatrix.h"
+#include "dSparse.h"
+#include "dSparse.h"
+SPARSE_MSM_BIN_OPS (Matrix, SparseMatrix, Matrix, SparseMatrix)
+SPARSE_MSM_CMP_OPS (Matrix, 0.0, , SparseMatrix, 0.0, )
+SPARSE_MSM_BOOL_OPS2 (Matrix, SparseMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-m-sm.h b/liboctave/smx-m-sm.h
new file mode 100644
index 0000000..7f89e8b
--- /dev/null
+++ b/liboctave/smx-m-sm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_m_sm_h)
+#define octave_smx_m_sm_h 1
+#include "dMatrix.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_MSM_BIN_OP_DECLS (Matrix, SparseMatrix, Matrix, SparseMatrix, OCTAVE_API)
+SPARSE_MSM_CMP_OP_DECLS (Matrix, SparseMatrix, OCTAVE_API)
+SPARSE_MSM_BOOL_OP_DECLS (Matrix, SparseMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-s-scm.cc b/liboctave/smx-s-scm.cc
new file mode 100644
index 0000000..be8d53f
--- /dev/null
+++ b/liboctave/smx-s-scm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-s-scm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "CSparse.h"
+SPARSE_SSM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, double, SparseComplexMatrix)
+SPARSE_SSM_CMP_OPS (double, 0.0, , SparseComplexMatrix, 0.0, real)
+SPARSE_SSM_BOOL_OPS2 (double, SparseComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-s-scm.h b/liboctave/smx-s-scm.h
new file mode 100644
index 0000000..87e88c5
--- /dev/null
+++ b/liboctave/smx-s-scm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_s_scm_h)
+#define octave_smx_s_scm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SSM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, double, SparseComplexMatrix, OCTAVE_API)
+SPARSE_SSM_CMP_OP_DECLS (double, SparseComplexMatrix, OCTAVE_API)
+SPARSE_SSM_BOOL_OP_DECLS (double, SparseComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-sbm-bm.cc b/liboctave/smx-sbm-bm.cc
new file mode 100644
index 0000000..f85f62f
--- /dev/null
+++ b/liboctave/smx-sbm-bm.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-sbm-bm.h"
+#include "boolMatrix.h"
+#include "boolSparse.h"
+SPARSE_SMM_EQNE_OPS (SparseBoolMatrix, false, , boolMatrix, false, )
+SPARSE_SMM_BOOL_OPS2 (SparseBoolMatrix, boolMatrix, false, false)
diff --git a/liboctave/smx-sbm-bm.h b/liboctave/smx-sbm-bm.h
new file mode 100644
index 0000000..69567ae
--- /dev/null
+++ b/liboctave/smx-sbm-bm.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_sbm_bm_h)
+#define octave_smx_sbm_bm_h 1
+#include "boolMatrix.h"
+#include "boolSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMM_EQNE_OP_DECLS (SparseBoolMatrix, boolMatrix, OCTAVE_API)
+SPARSE_SMM_BOOL_OP_DECLS (SparseBoolMatrix, boolMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-scm-cm.cc b/liboctave/smx-scm-cm.cc
new file mode 100644
index 0000000..ad5884a
--- /dev/null
+++ b/liboctave/smx-scm-cm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-scm-cm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+SPARSE_SMM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, ComplexMatrix)
+SPARSE_SMM_CMP_OPS (SparseComplexMatrix, 0.0, real, ComplexMatrix, 0.0, real)
+SPARSE_SMM_BOOL_OPS2 (SparseComplexMatrix, ComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-scm-cm.h b/liboctave/smx-scm-cm.h
new file mode 100644
index 0000000..e8d65e9
--- /dev/null
+++ b/liboctave/smx-scm-cm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_scm_cm_h)
+#define octave_smx_scm_cm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, ComplexMatrix, OCTAVE_API)
+SPARSE_SMM_CMP_OP_DECLS (SparseComplexMatrix, ComplexMatrix, OCTAVE_API)
+SPARSE_SMM_BOOL_OP_DECLS (SparseComplexMatrix, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-scm-m.cc b/liboctave/smx-scm-m.cc
new file mode 100644
index 0000000..1eccd51
--- /dev/null
+++ b/liboctave/smx-scm-m.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-scm-m.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dMatrix.h"
+SPARSE_SMM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, Matrix)
+SPARSE_SMM_CMP_OPS (SparseComplexMatrix, 0.0, real, Matrix, 0.0, )
+SPARSE_SMM_BOOL_OPS2 (SparseComplexMatrix, Matrix, 0.0, 0.0)
diff --git a/liboctave/smx-scm-m.h b/liboctave/smx-scm-m.h
new file mode 100644
index 0000000..a8158a0
--- /dev/null
+++ b/liboctave/smx-scm-m.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_scm_m_h)
+#define octave_smx_scm_m_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dMatrix.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, Matrix, OCTAVE_API)
+SPARSE_SMM_CMP_OP_DECLS (SparseComplexMatrix, Matrix, OCTAVE_API)
+SPARSE_SMM_BOOL_OP_DECLS (SparseComplexMatrix, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-scm-s.cc b/liboctave/smx-scm-s.cc
new file mode 100644
index 0000000..f36185b
--- /dev/null
+++ b/liboctave/smx-scm-s.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-scm-s.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+SPARSE_SMS_BIN_OPS (ComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, double)
+SPARSE_SMS_CMP_OPS (SparseComplexMatrix, 0.0, real, double, 0.0, )
+SPARSE_SMS_BOOL_OPS2 (SparseComplexMatrix, double, 0.0, 0.0)
diff --git a/liboctave/smx-scm-s.h b/liboctave/smx-scm-s.h
new file mode 100644
index 0000000..65e6bc6
--- /dev/null
+++ b/liboctave/smx-scm-s.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_scm_s_h)
+#define octave_smx_scm_s_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMS_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, double, OCTAVE_API)
+SPARSE_SMS_CMP_OP_DECLS (SparseComplexMatrix, double, OCTAVE_API)
+SPARSE_SMS_BOOL_OP_DECLS (SparseComplexMatrix, double, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-scm-sm.cc b/liboctave/smx-scm-sm.cc
new file mode 100644
index 0000000..32d57e8
--- /dev/null
+++ b/liboctave/smx-scm-sm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-scm-sm.h"
+#include "boolSparse.h"
+#include "CSparse.h"
+#include "dSparse.h"
+SPARSE_SMSM_BIN_OPS (SparseComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, SparseMatrix)
+SPARSE_SMSM_CMP_OPS (SparseComplexMatrix, 0.0, real, SparseMatrix, 0.0, )
+SPARSE_SMSM_BOOL_OPS2 (SparseComplexMatrix, SparseMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-scm-sm.h b/liboctave/smx-scm-sm.h
new file mode 100644
index 0000000..7a9ad5e
--- /dev/null
+++ b/liboctave/smx-scm-sm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_scm_sm_h)
+#define octave_smx_scm_sm_h 1
+#include "CSparse.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMSM_BIN_OP_DECLS (SparseComplexMatrix, SparseComplexMatrix, SparseComplexMatrix, SparseMatrix, OCTAVE_API)
+SPARSE_SMSM_CMP_OP_DECLS (SparseComplexMatrix, SparseMatrix, OCTAVE_API)
+SPARSE_SMSM_BOOL_OP_DECLS (SparseComplexMatrix, SparseMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-sm-cm.cc b/liboctave/smx-sm-cm.cc
new file mode 100644
index 0000000..5dd97dc
--- /dev/null
+++ b/liboctave/smx-sm-cm.cc
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-sm-cm.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dSparse.h"
+SPARSE_SMM_BIN_OPS (ComplexMatrix, SparseComplexMatrix, SparseMatrix, ComplexMatrix)
+SPARSE_SMM_CMP_OPS (SparseMatrix, 0.0, , ComplexMatrix, 0.0, real)
+SPARSE_SMM_BOOL_OPS2 (SparseMatrix, ComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-sm-cm.h b/liboctave/smx-sm-cm.h
new file mode 100644
index 0000000..57b2aa9
--- /dev/null
+++ b/liboctave/smx-sm-cm.h
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_sm_cm_h)
+#define octave_smx_sm_cm_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMM_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, SparseMatrix, ComplexMatrix, OCTAVE_API)
+SPARSE_SMM_CMP_OP_DECLS (SparseMatrix, ComplexMatrix, OCTAVE_API)
+SPARSE_SMM_BOOL_OP_DECLS (SparseMatrix, ComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-sm-cs.cc b/liboctave/smx-sm-cs.cc
new file mode 100644
index 0000000..c6cf88b
--- /dev/null
+++ b/liboctave/smx-sm-cs.cc
@@ -0,0 +1,13 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-sm-cs.h"
+#include "boolSparse.h"
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dSparse.h"
+#include "oct-cmplx.h"
+SPARSE_SMS_BIN_OPS (ComplexMatrix, SparseComplexMatrix, SparseMatrix, Complex)
+SPARSE_SMS_CMP_OPS (SparseMatrix, 0.0, , Complex, 0.0, real)
+SPARSE_SMS_BOOL_OPS2 (SparseMatrix, Complex, 0.0, 0.0)
diff --git a/liboctave/smx-sm-cs.h b/liboctave/smx-sm-cs.h
new file mode 100644
index 0000000..4d838c2
--- /dev/null
+++ b/liboctave/smx-sm-cs.h
@@ -0,0 +1,12 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_sm_cs_h)
+#define octave_smx_sm_cs_h 1
+#include "CMatrix.h"
+#include "CSparse.h"
+#include "dSparse.h"
+#include "oct-cmplx.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMS_BIN_OP_DECLS (ComplexMatrix, SparseComplexMatrix, SparseMatrix, Complex, OCTAVE_API)
+SPARSE_SMS_CMP_OP_DECLS (SparseMatrix, Complex, OCTAVE_API)
+SPARSE_SMS_BOOL_OP_DECLS (SparseMatrix, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-sm-m.cc b/liboctave/smx-sm-m.cc
new file mode 100644
index 0000000..8e79c1c
--- /dev/null
+++ b/liboctave/smx-sm-m.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-sm-m.h"
+#include "boolSparse.h"
+#include "dMatrix.h"
+#include "dSparse.h"
+SPARSE_SMM_BIN_OPS (Matrix, SparseMatrix, SparseMatrix, Matrix)
+SPARSE_SMM_CMP_OPS (SparseMatrix, 0.0, , Matrix, 0.0, )
+SPARSE_SMM_BOOL_OPS2 (SparseMatrix, Matrix, 0.0, 0.0)
diff --git a/liboctave/smx-sm-m.h b/liboctave/smx-sm-m.h
new file mode 100644
index 0000000..3f5119d
--- /dev/null
+++ b/liboctave/smx-sm-m.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_sm_m_h)
+#define octave_smx_sm_m_h 1
+#include "dMatrix.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMM_BIN_OP_DECLS (Matrix, SparseMatrix, SparseMatrix, Matrix, OCTAVE_API)
+SPARSE_SMM_CMP_OP_DECLS (SparseMatrix, Matrix, OCTAVE_API)
+SPARSE_SMM_BOOL_OP_DECLS (SparseMatrix, Matrix, OCTAVE_API)
+#endif
diff --git a/liboctave/smx-sm-scm.cc b/liboctave/smx-sm-scm.cc
new file mode 100644
index 0000000..dc5c350
--- /dev/null
+++ b/liboctave/smx-sm-scm.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#include <config.h>
+#include "Array-util.h"
+#include "quit.h"
+#include "smx-sm-scm.h"
+#include "boolSparse.h"
+#include "CSparse.h"
+#include "dSparse.h"
+SPARSE_SMSM_BIN_OPS (SparseComplexMatrix, SparseComplexMatrix, SparseMatrix, SparseComplexMatrix)
+SPARSE_SMSM_CMP_OPS (SparseMatrix, 0.0, , SparseComplexMatrix, 0.0, real)
+SPARSE_SMSM_BOOL_OPS2 (SparseMatrix, SparseComplexMatrix, 0.0, 0.0)
diff --git a/liboctave/smx-sm-scm.h b/liboctave/smx-sm-scm.h
new file mode 100644
index 0000000..cca9c0a
--- /dev/null
+++ b/liboctave/smx-sm-scm.h
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by sparse-mk-ops
+#if !defined (octave_smx_sm_scm_h)
+#define octave_smx_sm_scm_h 1
+#include "CSparse.h"
+#include "dSparse.h"
+#include "Sparse-op-defs.h"
+SPARSE_SMSM_BIN_OP_DECLS (SparseComplexMatrix, SparseComplexMatrix, SparseMatrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_SMSM_CMP_OP_DECLS (SparseMatrix, SparseComplexMatrix, OCTAVE_API)
+SPARSE_SMSM_BOOL_OP_DECLS (SparseMatrix, SparseComplexMatrix, OCTAVE_API)
+#endif
diff --git a/liboctave/sparse-base-chol.cc b/liboctave/sparse-base-chol.cc
new file mode 100644
index 0000000..3b13bf8
--- /dev/null
+++ b/liboctave/sparse-base-chol.cc
@@ -0,0 +1,297 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "sparse-base-chol.h"
+#include "sparse-util.h"
+#include "lo-error.h"
+#include "oct-sparse.h"
+#include "oct-spparms.h"
+#include "quit.h"
+#include "MatrixType.h"
+
+#ifdef HAVE_CHOLMOD
+// Can't use CHOLMOD_NAME(drop)(0.0, S, cm). It doesn't treat complex matrices
+template <class chol_type, class chol_elt, class p_type>
+void 
+sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep::drop_zeros 
+  (const cholmod_sparse* S)
+{
+  chol_elt sik;
+  octave_idx_type *Sp, *Si;
+  chol_elt *Sx;
+  octave_idx_type pdest, k, ncol, p, pend;
+
+  if (! S)
+    return;
+
+  Sp = static_cast<octave_idx_type *>(S->p);
+  Si = static_cast<octave_idx_type *>(S->i);
+  Sx = static_cast<chol_elt *>(S->x);
+  pdest = 0;
+  ncol = S->ncol;
+
+  for (k = 0; k < ncol; k++)
+    {
+      p = Sp [k];
+      pend = Sp [k+1];
+      Sp [k] = pdest;
+      for (; p < pend; p++)
+	{
+	  sik = Sx [p];
+	  if (CHOLMOD_IS_NONZERO (sik))
+	    {
+	      if (p != pdest)
+		{
+		  Si [pdest] = Si [p];
+		  Sx [pdest] = sik;
+		}
+	      pdest++;
+	    }
+	}
+    }
+  Sp [ncol] = pdest;
+}
+#endif
+
+template <class chol_type, class chol_elt, class p_type>
+octave_idx_type
+sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep::init 
+  (const chol_type& a, bool natural)
+{
+  volatile octave_idx_type info = 0;
+#ifdef HAVE_CHOLMOD
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+
+  if (a_nr != a_nc)
+    {
+      (*current_liboctave_error_handler) 
+	("SparseCHOL requires square matrix");
+      return -1;
+    }
+
+  cholmod_common *cm = &Common;
+
+  // Setup initial parameters
+  CHOLMOD_NAME(start) (cm);
+  cm->prefer_zomplex = false;
+
+  double spu = octave_sparse_params::get_key ("spumoni");
+  if (spu == 0.)
+    {
+      cm->print = -1;
+      cm->print_function = 0;
+    }
+  else
+    {
+      cm->print = static_cast<int> (spu) + 2;
+      cm->print_function =&SparseCholPrint;
+    }
+
+  cm->error_handler = &SparseCholError;
+  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+  cm->final_asis = false;
+  cm->final_super = false;
+  cm->final_ll = true;
+  cm->final_pack = true;
+  cm->final_monotonic = true;
+  cm->final_resymbol = false;
+
+  cholmod_sparse A;
+  cholmod_sparse *ac = &A;
+  double dummy;
+  ac->nrow = a_nr;
+  ac->ncol = a_nc;
+
+  ac->p = a.cidx();
+  ac->i = a.ridx();
+  ac->nzmax = a.nnz();
+  ac->packed = true;
+  ac->sorted = true;
+  ac->nz = 0;
+#ifdef IDX_TYPE_LONG
+  ac->itype = CHOLMOD_LONG;
+#else
+  ac->itype = CHOLMOD_INT;
+#endif
+  ac->dtype = CHOLMOD_DOUBLE;
+  ac->stype = 1;
+#ifdef OCTAVE_CHOLMOD_TYPE
+  ac->xtype = OCTAVE_CHOLMOD_TYPE;
+#else
+  ac->xtype = CHOLMOD_REAL;
+#endif
+
+  if (a_nr < 1)
+    ac->x = &dummy;
+  else
+    ac->x = a.data();
+
+  // use natural ordering if no q output parameter
+  if (natural)
+    {
+      cm->nmethods = 1 ;
+      cm->method [0].ordering = CHOLMOD_NATURAL ;
+      cm->postorder = false ;
+    }
+
+  cholmod_factor *Lfactor;
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+  Lfactor = CHOLMOD_NAME(analyze) (ac, cm);
+  CHOLMOD_NAME(factorize) (ac, Lfactor, cm);
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  is_pd = cm->status == CHOLMOD_OK;
+  info = (is_pd ? 0 : cm->status);
+
+  if (is_pd)
+    {
+      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+      cond = CHOLMOD_NAME(rcond) (Lfactor, cm);
+      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+      minor_p = Lfactor->minor;
+
+      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+      Lsparse = CHOLMOD_NAME(factor_to_sparse) (Lfactor, cm);
+      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+      if (minor_p > 0 && minor_p < a_nr)
+	{
+	  size_t n1 = a_nr + 1;
+	  Lsparse->p = CHOLMOD_NAME(realloc) (minor_p+1,
+					      sizeof(octave_idx_type),
+					      Lsparse->p, &n1, cm);
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  CHOLMOD_NAME(reallocate_sparse) 
+	    (static_cast<octave_idx_type *>(Lsparse->p)[minor_p], Lsparse, cm);
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	  Lsparse->ncol = minor_p;
+	}
+
+      drop_zeros (Lsparse);
+
+      if (! natural)
+	{
+	  perms.resize (a_nr);
+	  for (octave_idx_type i = 0; i < a_nr; i++)
+	    perms(i) = static_cast<octave_idx_type *>(Lfactor->Perm)[i];
+	}
+
+      static char tmp[] = " ";
+
+      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+      CHOLMOD_NAME(free_factor) (&Lfactor, cm);
+      CHOLMOD_NAME(finish) (cm);
+      CHOLMOD_NAME(print_common) (tmp, cm);
+      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+    }
+#else
+  (*current_liboctave_error_handler) 
+    ("Missing CHOLMOD. Sparse cholesky factorization disabled");
+#endif
+  return info;
+}
+
+template <class chol_type, class chol_elt, class p_type>
+chol_type 
+sparse_base_chol<chol_type, chol_elt, p_type>::L (void) const
+{
+#ifdef HAVE_CHOLMOD
+  cholmod_sparse *m = rep->L();
+  octave_idx_type nc = m->ncol;
+  octave_idx_type nnz = m->nzmax;
+  chol_type ret (m->nrow, nc, nnz);
+  for (octave_idx_type j = 0; j < nc+1; j++)
+    ret.xcidx(j) = static_cast<octave_idx_type *>(m->p)[j];
+  for (octave_idx_type i = 0; i < nnz; i++)
+    {
+      ret.xridx(i) = static_cast<octave_idx_type *>(m->i)[i];
+      ret.xdata(i) = static_cast<chol_elt *>(m->x)[i];
+    }
+  return ret;
+#else
+  return chol_type();
+#endif
+}
+
+template <class chol_type, class chol_elt, class p_type>
+p_type 
+sparse_base_chol<chol_type, chol_elt, p_type>::
+sparse_base_chol_rep::Q (void) const
+{
+#ifdef HAVE_CHOLMOD
+  octave_idx_type n = Lsparse->nrow;
+  p_type p (n, n, n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      p.xcidx(i) = i;
+      p.xridx(i) = static_cast<octave_idx_type>(perms(i));
+      p.xdata(i) = 1;
+    }
+  p.xcidx(n) = n;
+
+  return p;
+#else
+  return p_type();
+#endif
+}
+
+template <class chol_type, class chol_elt, class p_type>
+chol_type 
+sparse_base_chol<chol_type, chol_elt, p_type>::inverse (void) const
+{
+  chol_type retval;
+#ifdef HAVE_CHOLMOD
+  cholmod_sparse *m = rep->L();
+  octave_idx_type n = m->ncol;
+  ColumnVector perms = rep->perm();
+  chol_type ret;
+  double rcond2;
+  octave_idx_type info;
+  MatrixType mattype (MatrixType::Upper);
+  chol_type linv = L().hermitian().inverse(mattype, info, rcond2, 1, 0);
+
+  if (perms.length() == n)
+    {
+      p_type Qc = Q();
+      retval = Qc * linv * linv.hermitian() * Qc.transpose();
+    }
+  else
+    retval = linv * linv.hermitian ();
+#endif
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-base-chol.h b/liboctave/sparse-base-chol.h
new file mode 100644
index 0000000..2d7a775
--- /dev/null
+++ b/liboctave/sparse-base-chol.h
@@ -0,0 +1,196 @@
+/*
+
+Copyright (C) 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_base_chol_h)
+#define octave_sparse_base_chol_h 1
+
+#include "oct-sparse.h"
+#include "dColVector.h"
+
+template <class chol_type, class chol_elt, class p_type>
+class
+sparse_base_chol
+{
+protected:
+#ifdef HAVE_CHOLMOD
+  class sparse_base_chol_rep
+  {
+  public:
+    sparse_base_chol_rep (void) : count (1), Lsparse (0), 
+				  is_pd (false), minor_p (0) { }
+
+    sparse_base_chol_rep (const chol_type& a, 
+			  const bool natural) : count (1)
+      { init (a, natural); }
+
+    sparse_base_chol_rep (const chol_type& a, octave_idx_type& info, 
+			  const bool natural) : count (1)
+      { info = init (a, natural); }
+
+    ~sparse_base_chol_rep (void)
+      { if (is_pd) CHOLMOD_NAME(free_sparse) (&Lsparse, &Common); }
+
+    cholmod_sparse * L (void) const { return Lsparse; }
+
+    octave_idx_type P (void) const 
+      { return (minor_p == static_cast<octave_idx_type>(Lsparse->ncol) ? 
+		0 : minor_p + 1); }
+
+    ColumnVector perm (void) const { return perms + 1; }
+
+    p_type Q (void) const;
+
+    bool is_positive_definite (void) const { return is_pd; }
+
+    double rcond (void) const { return cond; }
+
+    int count;
+
+  private:
+    cholmod_sparse *Lsparse;
+
+    cholmod_common Common;
+
+    bool is_pd;
+
+    octave_idx_type minor_p;
+
+    ColumnVector perms;
+
+    double cond;
+
+    octave_idx_type init (const chol_type& a, bool natural = true);
+
+    void drop_zeros (const cholmod_sparse* S);
+
+    // No assignment
+    sparse_base_chol_rep& operator = (const sparse_base_chol_rep& a);
+  };
+#else
+  class sparse_base_chol_rep
+  {
+  public:
+    sparse_base_chol_rep (void) : count (1), is_pd (false), minor_p (0) { }
+
+    sparse_base_chol_rep (const chol_type& a, 
+			  const bool natural) : count (1)
+      { init (a, natural); }
+
+    sparse_base_chol_rep (const chol_type& a, octave_idx_type& info, 
+			  const bool natural) : count (1)
+      { info = init (a, natural); }
+
+    ~sparse_base_chol_rep (void) { }
+
+    octave_idx_type P (void) const { return 0; }
+
+    ColumnVector perm (void) const { return perms + 1; }
+
+    p_type Q (void) const;
+
+    bool is_positive_definite (void) const { return is_pd; }
+
+    double rcond (void) const { return cond; }
+
+    int count;
+
+  private:
+    bool is_pd;
+
+    octave_idx_type minor_p;
+
+    ColumnVector perms;
+
+    double cond;
+
+    octave_idx_type init (const chol_type& a, bool natural = true);
+
+    // No assignment
+    sparse_base_chol_rep& operator = (const sparse_base_chol_rep& a);
+  };
+#endif
+
+ private:
+  sparse_base_chol_rep *rep;
+  
+public:
+
+  sparse_base_chol (void) : rep (new typename 
+    sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep ()) { }
+
+  sparse_base_chol (const chol_type& a, const bool n) : rep (new typename 
+    sparse_base_chol<chol_type, chol_elt, p_type>::
+	sparse_base_chol_rep (a, n)) { }
+
+  sparse_base_chol (const chol_type& a, octave_idx_type& info, const bool n) :
+    rep (new typename sparse_base_chol<chol_type, chol_elt, p_type>::
+	sparse_base_chol_rep (a, info, n)) { }
+
+  sparse_base_chol (const sparse_base_chol<chol_type, chol_elt, p_type>& a) : 
+    rep (a.rep) { rep->count++; }
+
+  ~sparse_base_chol (void) 
+    {
+      if (--rep->count <= 0)
+	delete rep;
+    }
+
+  sparse_base_chol& operator = (const sparse_base_chol& a)
+    {
+      if (this != &a)
+	{
+	  if (--rep->count <= 0)
+	    delete rep;
+
+	  rep = a.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+  chol_type L (void) const;
+
+  chol_type R (void) const { return L().hermitian (); }
+
+  octave_idx_type P (void) const { return rep->P(); }
+
+  ColumnVector perm (void) const { return rep->perm(); }
+
+  p_type Q (void) const { return rep->Q(); }
+
+  bool is_positive_definite (void) const 
+    { return rep->is_positive_definite(); }
+
+  double rcond (void) const { return rep->rcond(); }
+
+  chol_type inverse (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-base-lu.cc b/liboctave/sparse-base-lu.cc
new file mode 100644
index 0000000..4aca584
--- /dev/null
+++ b/liboctave/sparse-base-lu.cc
@@ -0,0 +1,152 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "sparse-base-lu.h"
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+lu_type
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Y (void) const
+{
+  octave_idx_type nr = Lfact.rows ();
+  octave_idx_type nc = Ufact.rows ();
+  octave_idx_type rcmin = (nr > nc ? nr : nc);
+
+  lu_type Yout (nr, nc, Lfact.nnz() + Ufact.nnz());
+  octave_idx_type ii = 0;
+  Yout.xcidx(0) = 0;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = Ufact.cidx (j); i < Ufact.cidx(j + 1); i++)
+	{
+	  Yout.xridx (ii) = Ufact.ridx(i);
+	  Yout.xdata (ii++) = Ufact.data(i);
+	}
+      if (j < rcmin)
+	{
+	  // Note the +1 skips the 1.0 on the diagonal 
+	  for (octave_idx_type i = Lfact.cidx (j) + 1; 
+	       i < Lfact.cidx(j +1); i++)
+	    {
+	      Yout.xridx (ii) = Lfact.ridx(i);
+	      Yout.xdata (ii++) = Lfact.data(i);
+	    }
+	}
+      Yout.xcidx(j + 1) = ii;
+    }
+
+  return Yout;
+}
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+p_type
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Pr (void) const
+{
+
+  octave_idx_type nr = Lfact.rows ();
+
+  p_type Pout (nr, nr, nr);
+
+  for (octave_idx_type i = 0; i < nr; i++)
+    {
+      Pout.cidx (i) = i;
+      Pout.ridx (P (i)) = i;
+      Pout.data (i) = 1;
+    }
+  Pout.cidx (nr) = nr;
+
+  return Pout;
+}
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+ColumnVector
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Pr_vec (void) const
+{
+
+  octave_idx_type nr = Lfact.rows ();
+
+  ColumnVector Pout (nr);
+
+  for (octave_idx_type i = 0; i < nr; i++)
+    Pout.xelem (i) = static_cast<double> (P(i) + 1);
+
+  return Pout;
+}
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+PermMatrix
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Pr_mat (void) const
+{
+  return PermMatrix (P, false);
+}
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+p_type
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Pc (void) const
+{
+  octave_idx_type nc = Ufact.cols ();
+
+  p_type Pout (nc, nc, nc);
+
+  for (octave_idx_type i = 0; i < nc; i++)
+    {
+      Pout.cidx (i) = i;
+      Pout.ridx (i) = Q (i);
+      Pout.data (i) = 1;
+    }
+  Pout.cidx (nc) = nc;
+
+  return Pout;
+}
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+ColumnVector
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Pc_vec (void) const
+{
+
+  octave_idx_type nc = Ufact.cols ();
+
+  ColumnVector Pout (nc);
+
+  for (octave_idx_type i = 0; i < nc; i++)
+    Pout.xelem (i) = static_cast<double> (Q(i) + 1);
+
+  return Pout;
+}
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+PermMatrix
+sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Pc_mat (void) const
+{
+  return PermMatrix (Q, true);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-base-lu.h b/liboctave/sparse-base-lu.h
new file mode 100644
index 0000000..9ad1a5e
--- /dev/null
+++ b/liboctave/sparse-base-lu.h
@@ -0,0 +1,101 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+
+#if !defined (octave_sparse_base_lu_h)
+#define octave_sparse_base_lu_h 1
+
+#include "MArray.h"
+#include "dSparse.h"
+
+template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
+class
+sparse_base_lu
+{
+public:
+
+  sparse_base_lu (void) { }
+
+  sparse_base_lu (const sparse_base_lu& a) 
+    : Lfact (a.Lfact), Ufact (a.Ufact), cond (a.cond), P (a.P), Q (a.Q) { }
+
+  sparse_base_lu& operator = (const sparse_base_lu& a)
+    {
+      if (this != &a)
+	{
+	  Lfact = a.Lfact;
+	  Ufact = a.Ufact;
+	  cond = a.cond;
+	  P = a.P;
+	  Q = a.Q;
+	}
+      return *this;
+    }
+
+  ~sparse_base_lu (void) { }
+
+  lu_type L (void) const { return Lfact; }
+
+  lu_type U (void) const { return Ufact; }
+
+  SparseMatrix R (void) const { return Rfact; }
+
+  lu_type Y (void) const;
+
+  p_type Pc (void) const;
+
+  p_type Pr (void) const;
+
+  ColumnVector Pc_vec (void) const;
+
+  ColumnVector Pr_vec (void) const;
+
+  PermMatrix Pc_mat (void) const;
+
+  PermMatrix Pr_mat (void) const;
+
+  const octave_idx_type * row_perm (void) const { return P.fortran_vec (); }
+
+  const octave_idx_type * col_perm (void) const { return Q.fortran_vec (); }
+
+  double rcond (void) const { return cond; }
+
+protected:
+
+  lu_type Lfact;
+  lu_type Ufact;
+  SparseMatrix Rfact;
+
+  double cond;
+
+  MArray<octave_idx_type> P;
+  MArray<octave_idx_type> Q;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-dmsolve.cc b/liboctave/sparse-dmsolve.cc
new file mode 100644
index 0000000..1f934fd
--- /dev/null
+++ b/liboctave/sparse-dmsolve.cc
@@ -0,0 +1,518 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "MArray2.h"
+#include "MSparse.h"
+#include "SparseQR.h"
+#include "SparseCmplxQR.h"
+#include "MatrixType.h"
+#include "oct-sort.h"
+#include "oct-locbuf.h"
+
+template <class T>
+static MSparse<T>
+dmsolve_extract (const MSparse<T> &A, const octave_idx_type *Pinv, 
+		const octave_idx_type *Q, octave_idx_type rst, 
+		octave_idx_type rend, octave_idx_type cst, 
+		octave_idx_type cend, octave_idx_type maxnz = -1,
+		bool lazy = false)
+{
+  octave_idx_type nz = (rend - rst) * (cend - cst);
+  maxnz = (maxnz < 0 ? A.nnz () : maxnz);
+  MSparse<T> B (rend - rst, cend - cst, (nz < maxnz ? nz : maxnz));
+  // Some sparse functions can support lazy indexing (where elements
+  // in the row are in no particular order), even though octave in 
+  // general can't. For those functions that can using it is a big 
+  // win here in terms of speed.
+  if (lazy)
+    {
+      nz = 0;
+      for (octave_idx_type j = cst ; j < cend ; j++)
+	{
+	  octave_idx_type qq = (Q ? Q [j] : j);
+	  B.xcidx (j - cst) = nz;
+	  for (octave_idx_type p = A.cidx(qq) ; p < A.cidx (qq+1) ; p++)
+	    {
+	      OCTAVE_QUIT;
+	      octave_idx_type r = (Pinv ? Pinv [A.ridx (p)] : A.ridx (p));
+	      if (r >= rst && r < rend)
+		{
+		  B.xdata (nz) = A.data (p);
+		  B.xridx (nz++) =  r - rst ;
+		}
+	    }
+	}
+      B.xcidx (cend - cst) = nz ;
+    }
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (T, X, rend - rst);
+      octave_sort<octave_idx_type> sort;
+      octave_idx_type *ri = B.xridx();
+      nz = 0;
+      for (octave_idx_type j = cst ; j < cend ; j++)
+	{
+	  octave_idx_type qq = (Q ? Q [j] : j);
+	  B.xcidx (j - cst) = nz;
+	  for (octave_idx_type p = A.cidx(qq) ; p < A.cidx (qq+1) ; p++)
+	    {
+	      OCTAVE_QUIT;
+	      octave_idx_type r = (Pinv ? Pinv [A.ridx (p)] : A.ridx (p));
+	      if (r >= rst && r < rend)
+		{
+		  X [r-rst] = A.data (p);
+		  B.xridx (nz++) =  r - rst ;
+		}
+	    }
+	  sort.sort (ri + B.xcidx (j - cst), nz - B.xcidx (j - cst));
+	  for (octave_idx_type p = B.cidx (j - cst); p < nz; p++)
+	    B.xdata (p) = X [B.xridx (p)]; 
+	}
+      B.xcidx (cend - cst) = nz ;
+    }
+
+  return B;
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static MSparse<double>
+dmsolve_extract (const MSparse<double> &A, const octave_idx_type *Pinv, 
+		const octave_idx_type *Q, octave_idx_type rst, 
+		octave_idx_type rend, octave_idx_type cst, 
+		octave_idx_type cend, octave_idx_type maxnz,
+		bool lazy);
+
+static MSparse<Complex>
+dmsolve_extract (const MSparse<Complex> &A, const octave_idx_type *Pinv, 
+		const octave_idx_type *Q, octave_idx_type rst, 
+		octave_idx_type rend, octave_idx_type cst, 
+		octave_idx_type cend, octave_idx_type maxnz,
+		bool lazy);
+#endif
+
+template <class T>
+static MArray2<T>
+dmsolve_extract (const MArray2<T> &m, const octave_idx_type *, 
+		 const octave_idx_type *, octave_idx_type r1, 
+		 octave_idx_type r2, octave_idx_type c1, 
+		 octave_idx_type c2)
+{
+  r2 -= 1;
+  c2 -= 1;
+  if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
+  if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
+
+  octave_idx_type new_r = r2 - r1 + 1;
+  octave_idx_type new_c = c2 - c1 + 1;
+
+  MArray2<T> result (new_r, new_c);
+
+  for (octave_idx_type j = 0; j < new_c; j++)
+    for (octave_idx_type i = 0; i < new_r; i++)
+      result.xelem (i, j) = m.elem (r1+i, c1+j);
+
+  return result;
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static MArray2<double>
+dmsolve_extract (const MArray2<double> &m, const octave_idx_type *, 
+		 const octave_idx_type *, octave_idx_type r1, 
+		 octave_idx_type r2, octave_idx_type c1, 
+		 octave_idx_type c2)
+
+static MArray2<Complex>
+dmsolve_extract (const MArray2<Complex> &m, const octave_idx_type *, 
+		 const octave_idx_type *, octave_idx_type r1, 
+		 octave_idx_type r2, octave_idx_type c1, 
+		 octave_idx_type c2)
+#endif
+
+template <class T>
+static void
+dmsolve_insert (MArray2<T> &a, const MArray2<T> &b, const octave_idx_type *Q,
+	       octave_idx_type r, octave_idx_type c)
+{
+  T *ax = a.fortran_vec();
+  const T *bx = b.fortran_vec();
+  octave_idx_type anr = a.rows();
+  octave_idx_type nr = b.rows();
+  octave_idx_type nc = b.cols();
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      octave_idx_type aoff = (c + j) * anr;
+      octave_idx_type boff = j * nr;
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  ax [Q [r + i] + aoff] = bx [i + boff];
+	}
+    }
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static void
+dmsolve_insert (MArray2<double> &a, const MArray2<double> &b, 
+	       const octave_idx_type *Q, octave_idx_type r, octave_idx_type c);
+
+static void
+dmsolve_insert (MArray2<Complex> &a, const MArray2<Complex> &b,
+	       const octave_idx_type *Q, octave_idx_type r, octave_idx_type c);
+#endif
+
+template <class T>
+static void
+dmsolve_insert (MSparse<T> &a, const MSparse<T> &b, const octave_idx_type *Q,
+	       octave_idx_type r, octave_idx_type c)
+{
+  octave_idx_type b_rows = b.rows ();
+  octave_idx_type b_cols = b.cols ();
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Qinv, nr);
+  for (octave_idx_type i = 0; i < nr; i++)
+    Qinv [Q [i]] = i;
+
+  // First count the number of elements in the final array
+  octave_idx_type nel = a.xcidx(c) + b.nnz ();
+
+  if (c + b_cols < nc)
+    nel += a.xcidx(nc) - a.xcidx(c + b_cols);
+
+  for (octave_idx_type i = c; i < c + b_cols; i++)
+    for (octave_idx_type j = a.xcidx(i); j < a.xcidx(i+1); j++)
+      if (Qinv [a.xridx(j)] < r || Qinv [a.xridx(j)] >= r + b_rows)
+	nel++;
+
+  OCTAVE_LOCAL_BUFFER (T, X, nr);
+  octave_sort<octave_idx_type> sort;
+  MSparse<T> tmp (a);
+  a = MSparse<T> (nr, nc, nel);
+  octave_idx_type *ri = a.xridx();
+
+  for (octave_idx_type i = 0; i < tmp.cidx(c); i++)
+    {
+      a.xdata(i) = tmp.xdata(i);
+      a.xridx(i) = tmp.xridx(i);
+    }
+  for (octave_idx_type i = 0; i < c + 1; i++)
+    a.xcidx(i) = tmp.xcidx(i);
+
+  octave_idx_type ii = a.xcidx(c);
+
+  for (octave_idx_type i = c; i < c + b_cols; i++)
+    {
+      OCTAVE_QUIT;
+
+      for (octave_idx_type j = tmp.xcidx(i); j < tmp.xcidx(i+1); j++)
+	if (Qinv [tmp.xridx(j)] < r || 	Qinv [tmp.xridx(j)] >= r + b_rows)
+	  {
+	    X [tmp.xridx(j)] = tmp.xdata(j);
+	    a.xridx(ii++) = tmp.xridx(j);
+	  }
+
+      OCTAVE_QUIT;
+
+      for (octave_idx_type j = b.cidx(i-c); j < b.cidx(i-c+1); j++)
+	{
+	  X [Q [r + b.ridx(j)]] = b.data(j);
+	  a.xridx(ii++) = Q [r + b.ridx(j)];
+	}
+
+      sort.sort (ri + a.xcidx (i), ii - a.xcidx (i));
+      for (octave_idx_type p = a.xcidx (i); p < ii; p++)
+	a.xdata (p) = X [a.xridx (p)]; 
+      a.xcidx(i+1) = ii;
+    }
+
+  for (octave_idx_type i = c + b_cols; i < nc; i++)
+    {
+      for (octave_idx_type j = tmp.xcidx(i); j < tmp.cidx(i+1); j++)
+	{
+	  a.xdata(ii) = tmp.xdata(j);
+	  a.xridx(ii++) = tmp.xridx(j);
+	}
+      a.xcidx(i+1) = ii;
+    }
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static void
+dmsolve_insert (MSparse<double> &a, const SparseMatrix &b, 
+	       const octave_idx_type *Q, octave_idx_type r, octave_idx_type c);
+
+static void
+dmsolve_insert (MSparse<Complex> &a, const MSparse<Complex> &b,
+	       const octave_idx_type *Q, octave_idx_type r, octave_idx_type c);
+#endif
+
+template <class T, class RT>
+static void
+dmsolve_permute (MArray2<RT> &a, const MArray2<T>& b, const octave_idx_type *p)
+{
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+  const T *Bx = b.fortran_vec();
+  a.resize(b_nr, b_nc);
+  RT *Btx = a.fortran_vec();
+  for (octave_idx_type j = 0; j < b_nc; j++)
+    {
+      octave_idx_type off = j * b_nr;
+      for (octave_idx_type i = 0; i < b_nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  Btx [p [i] + off] = Bx [ i + off];
+	}
+    }
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static void
+dmsolve_permute (MArray2<double> &a, const MArray2<double>& b,
+		 const octave_idx_type *p);
+
+static void
+dmsolve_permute (MArray2<Complex> &a, const MArray2<double>& b,
+		 const octave_idx_type *p);
+
+static void
+dmsolve_permute (MArray2<Complex> &a, const MArray2<Complex>& b,
+		 const octave_idx_type *p);
+#endif
+
+template <class T, class RT>
+static void
+dmsolve_permute (MSparse<RT> &a, const MSparse<T>& b, const octave_idx_type *p)
+{
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+  octave_idx_type b_nz = b.nnz ();
+  octave_idx_type nz = 0;
+  a = MSparse<RT> (b_nr, b_nc, b_nz);
+  octave_sort<octave_idx_type> sort;
+  octave_idx_type *ri = a.xridx();
+  OCTAVE_LOCAL_BUFFER (RT, X, b_nr);
+  a.xcidx(0) = 0;
+  for (octave_idx_type j = 0; j < b_nc; j++)
+    {
+      for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+	{
+	  OCTAVE_QUIT;
+	  octave_idx_type r = p [b.ridx (i)];
+	  X [r] = b.data (i);
+	  a.xridx(nz++) = p [b.ridx (i)];
+	}
+      sort.sort (ri + a.xcidx (j), nz - a.xcidx (j));
+      for (octave_idx_type i = a.cidx (j); i < nz; i++)
+	{
+	  OCTAVE_QUIT;
+	  a.xdata (i) = X [a.xridx (i)]; 
+	}
+      a.xcidx(j+1) = nz;
+    }
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+static void
+dmsolve_permute (MSparse<double> &a, const MSparse<double>& b, 
+		 const octave_idx_type *p);
+
+static void
+dmsolve_permute (MSparse<Complex> &a, const MSparse<double>& b,
+		 const octave_idx_type *p);
+
+static void
+dmsolve_permute (MSparse<Complex> &a, const MSparse<Complex>& b,
+		 const octave_idx_type *p);
+#endif
+
+static void
+solve_singularity_warning (double)
+{
+  // Dummy singularity handler so that LU solver doesn't flag
+  // an error for numerically rank defficient matrices
+}
+
+template <class RT, class ST, class T>
+RT
+dmsolve (const ST &a, const T &b, octave_idx_type &info)
+{
+#ifdef HAVE_CXSPARSE
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+  RT retval;
+
+  if (nr < 0 || nc < 0 || nr != b_nr)
+    (*current_liboctave_error_handler)
+      ("matrix dimension mismatch in solution of minimum norm problem");
+  else if (nr == 0 || nc == 0 || b_nc == 0)
+    retval = RT (nc, b_nc, 0.0);
+  else
+    {
+      octave_idx_type nnz_remaining = a.nnz ();
+      CXSPARSE_DNAME () csm;
+      csm.m = nr;
+      csm.n = nc;
+      csm.x = 0;
+      csm.nz = -1;
+      csm.nzmax = a.nnz ();
+      // Cast away const on A, with full knowledge that CSparse won't touch it.
+      // Prevents the methods below making a copy of the data.
+      csm.p = const_cast<octave_idx_type *>(a.cidx ());
+      csm.i = const_cast<octave_idx_type *>(a.ridx ());
+
+#if defined(CS_VER) && (CS_VER >= 2)
+      CXSPARSE_DNAME (d) *dm = CXSPARSE_DNAME(_dmperm) (&csm, 0);
+      octave_idx_type *p = dm->p;
+      octave_idx_type *q = dm->q;
+#else
+      CXSPARSE_DNAME (d) *dm = CXSPARSE_DNAME(_dmperm) (&csm);
+      octave_idx_type *p = dm->P;
+      octave_idx_type *q = dm->Q;
+#endif
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, pinv, nr);
+      for (octave_idx_type i = 0; i < nr; i++)
+	pinv [p [i]] = i;
+      RT btmp;
+      dmsolve_permute (btmp, b, pinv);
+      info = 0;
+      retval.resize (nc, b_nc);
+
+      // Leading over-determined block
+      if (dm->rr [2] < nr && dm->cc [3] < nc)
+	{
+	  ST m = dmsolve_extract (a, pinv, q, dm->rr [2], nr, dm->cc [3], nc, 
+				  nnz_remaining, true);
+	  nnz_remaining -= m.nnz();
+	  RT mtmp = 
+	    qrsolve (m, dmsolve_extract (btmp, 0, 0, dm->rr[2], b_nr, 0,
+					 b_nc), info);
+	  dmsolve_insert (retval, mtmp, q, dm->cc [3], 0);
+	  if (dm->rr [2] > 0 && !info)
+	    {
+	      m = dmsolve_extract (a, pinv, q, 0, dm->rr [2], 
+				   dm->cc [3], nc, nnz_remaining, true);
+	      nnz_remaining -= m.nnz();
+	      RT ctmp = dmsolve_extract (btmp, 0, 0, 0, 
+					 dm->rr[2], 0, b_nc);
+	      btmp.insert (ctmp - m * mtmp, 0, 0);
+	    }
+	}
+      
+      // Structurally non-singular blocks
+      // FIXME Should use fine Dulmange-Mendelsohn decomposition here.
+      if (dm->rr [1] < dm->rr [2] && dm->cc [2] < dm->cc [3] && !info)
+	{
+	  ST m = dmsolve_extract (a, pinv, q, dm->rr [1], dm->rr [2], 
+				  dm->cc [2], dm->cc [3], nnz_remaining, false);
+	  nnz_remaining -= m.nnz();
+	  RT btmp2 = dmsolve_extract (btmp, 0, 0, dm->rr [1], dm->rr [2], 
+				      0, b_nc);
+	  double rcond = 0.0;
+	  MatrixType mtyp (MatrixType::Full);
+	  RT mtmp = m.solve (mtyp, btmp2, info, rcond, 
+			     solve_singularity_warning, false);	
+	  if (info != 0)
+	    {
+	      info = 0;
+	      mtmp = qrsolve (m, btmp2, info);
+	    }
+
+	  dmsolve_insert (retval, mtmp, q, dm->cc [2], 0);
+	  if (dm->rr [1] > 0 && !info)
+	    {
+	      m = dmsolve_extract (a, pinv, q, 0, dm->rr [1], dm->cc [2],
+				   dm->cc [3], nnz_remaining, true);
+	      nnz_remaining -= m.nnz();
+	      RT ctmp = dmsolve_extract (btmp, 0, 0, 0,
+					 dm->rr[1], 0, b_nc);
+	      btmp.insert (ctmp - m * mtmp, 0, 0);
+	    }
+	}
+
+      // Trailing under-determined block
+      if (dm->rr [1] > 0 && dm->cc [2] > 0 && !info)
+	{
+	  ST m = dmsolve_extract (a, pinv, q, 0, dm->rr [1], 0, 
+				  dm->cc [2], nnz_remaining, true);
+	  RT mtmp = 
+	    qrsolve (m, dmsolve_extract(btmp, 0, 0, 0, dm->rr [1] , 0, 
+					b_nc), info);
+	  dmsolve_insert (retval, mtmp, q, 0, 0);
+	}
+
+      CXSPARSE_DNAME (_dfree) (dm);
+    }
+  return retval;
+#else
+  return RT ();
+#endif
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern Matrix
+dmsolve (const SparseMatrix &a, const Matrix &b, 
+	 octave_idx_type &info);
+
+extern ComplexMatrix
+dmsolve (const SparseMatrix &a, const ComplexMatrix &b, 
+	 octave_idx_type &info);
+
+extern ComplexMatrix
+dmsolve (const SparseComplexMatrix &a, const Matrix &b, 
+	 octave_idx_type &info);
+
+extern ComplexMatrix
+dmsolve (const SparseComplexMatrix &a, const ComplexMatrix &b, 
+	 octave_idx_type &info);
+
+extern SparseMatrix
+dmsolve (const SparseMatrix &a, const SparseMatrix &b, 
+	 octave_idx_type &info);
+
+extern SparseComplexMatrix
+dmsolve (const SparseMatrix &a, const SparseComplexMatrix &b, 
+	 octave_idx_type &info);
+
+extern SparseComplexMatrix
+dmsolve (const SparseComplexMatrix &a, const SparseMatrix &b, 
+	 octave_idx_type &info);
+
+extern SparseComplexMatrix
+dmsolve (const SparseComplexMatrix &a, const SparseComplexMatrix &b, 
+	 octave_idx_type &info);
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-mk-ops.awk b/liboctave/sparse-mk-ops.awk
new file mode 100644
index 0000000..0b6bdc8
--- /dev/null
+++ b/liboctave/sparse-mk-ops.awk
@@ -0,0 +1,257 @@
+# Copyright (C) 2004, 2005, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+BEGIN {
+  declare_types = 0;
+  generate_ops = 0;
+  ntypes = 0;
+} {
+  if (NR == 1 && make_inclusive_header)
+    {
+      print "// DO NOT EDIT -- generated by sparse-mk-ops";
+      tmp = make_inclusive_header;
+      gsub (/[\.-]/, "_", tmp);
+      printf ("#if !defined (octave_%s)\n", tmp);
+      printf ("#define octave_%s 1\n", tmp);
+    }
+}
+/^#/ {
+  if ($2 == "types")
+    declare_types = 1;
+  else if ($2 == "ops")
+    {
+      generate_ops = 1;
+      declare_types = 0;
+    }
+  next;
+} {
+  if (declare_types)
+    {
+      ntypes++;
+
+      if (NF == 6)
+        {
+          scalar_zero_val[ntypes] = $6;
+          fwd_decl_ok[ntypes] = $5 == "YES";
+          header[ntypes] = $4 == "NONE" ? "" : $4;
+          class[ntypes] = $3;
+          type[ntypes] = $2;
+          tag[ntypes] = $1;
+          rev_tag[$1] = ntypes;
+        }
+      else
+        printf ("skipping line %d: %s\n", NR, $0); 
+    }
+  else if (generate_ops)
+    {
+      if (NF >= 5)
+        {
+          result_tag_1 = $1;
+          result_tag_2 = $2;
+          lhs_tag = $3;
+          rhs_tag = $4;
+	  op_type = $5;
+
+	  bin_ops = index (op_type, "B") != 0;
+	  cmp_ops = index (op_type, "C") != 0;
+	  eqne_ops = index (op_type, "E") != 0;
+	  bool_ops = index (op_type, "L") != 0;
+
+          n = 5;
+
+          lhs_conv = cmp_ops ? $(++n) : "";
+          rhs_conv = cmp_ops ? $(++n) : "";
+
+	  if (lhs_conv == "NONE")
+	    lhs_conv = "";
+
+	  if (rhs_conv == "NONE")
+	    rhs_conv = "";
+
+	  k = 0
+	  while (NF > n)
+	    bool_headers[k++] = $(++n);
+
+	  cc_file = sprintf ("%s-%s-%s.cc", prefix, lhs_tag, rhs_tag);
+	  h_file = sprintf ("%s-%s-%s.h", prefix, lhs_tag, rhs_tag);
+
+	  if (list_cc_files)
+	    {
+	      print cc_file;
+	      next;
+	    }
+
+	  if (list_h_files)
+	    {
+	      print h_file;
+	      next;
+	    }
+
+	  if (make_inclusive_header)
+	    {
+              printf ("#include \"%s\"\n", h_file);
+              next;
+            }
+
+	  h_guard = sprintf ("octave_%s_%s_%s_h", prefix, lhs_tag, rhs_tag);
+
+	  result_num_1 = rev_tag[result_tag_1];
+	  result_num_2 = rev_tag[result_tag_2];
+	  lhs_num = rev_tag[lhs_tag];
+	  rhs_num = rev_tag[rhs_tag];
+
+	  result_type_1 = type[result_num_1];
+	  result_type_2 = type[result_num_2];
+	  lhs_type = type[lhs_num];
+          rhs_type = type[rhs_num];
+
+	  result_scalar_zero_val_1 = scalar_zero_val[result_num_1];
+	  result_scalar_zero_val_2 = scalar_zero_val[result_num_2];
+          lhs_scalar_zero_val = scalar_zero_val[lhs_num];
+          rhs_scalar_zero_val = scalar_zero_val[rhs_num];
+
+	  result_header_1 = header[result_num_1];
+	  result_header_2 = header[result_num_2];
+	  lhs_header = header[lhs_num];
+          rhs_header = header[rhs_num];
+
+	  lhs_class = class[lhs_num];
+	  rhs_class = class[rhs_num];
+
+	  print "// DO NOT EDIT -- generated by sparse-mk-ops" > h_file;
+
+	  printf ("#if !defined (%s)\n", h_guard) >> h_file;
+	  printf ("#define %s 1\n", h_guard) >> h_file;
+
+          if (result_header_1)
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", result_type_1) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", result_header_1) >> h_file;
+	    }
+
+          if (result_header_2 && ! (result_header_2 == result_header_1))
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", result_type_2) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", result_header_2) >> h_file;
+	    }
+
+          if (lhs_header && ! (lhs_header == result_header_1 || lhs_header == result_header_2))
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", lhs_type) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", lhs_header) >> h_file;
+	    }
+
+          if (rhs_header && ! (rhs_header == lhs_header || rhs_header == result_header_1 || rhs_header == result_header_2))
+	    {
+	      if (result_fwd_decl_ok)
+	        printf ("class %s\n", rhs_type) >> h_file;
+	      else
+	        printf ("#include \"%s\"\n", rhs_header) >> h_file;
+	    }
+
+          printf ("#include \"Sparse-op-defs.h\"\n") >> h_file;
+
+          if (bin_ops)
+            printf ("SPARSE_%s%s_BIN_OP_DECLS (%s, %s, %s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, result_type_1, result_type_2, lhs_type, 
+		    rhs_type) >> h_file
+
+          if (cmp_ops)
+            printf ("SPARSE_%s%s_CMP_OP_DECLS (%s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, lhs_type, rhs_type) >> h_file
+
+          if (eqne_ops)
+            printf ("SPARSE_%s%s_EQNE_OP_DECLS (%s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, lhs_type, rhs_type) >> h_file
+
+          if (bool_ops)
+            printf ("SPARSE_%s%s_BOOL_OP_DECLS (%s, %s, OCTAVE_API)\n", lhs_class,
+		    rhs_class, lhs_type, rhs_type) >> h_file
+
+
+          print "#endif" >> h_file;
+
+	  close (h_file);
+
+
+	  print "// DO NOT EDIT -- generated by sparse-mk-ops" > cc_file;
+
+	  ## print "#ifdef HAVE_CONFIG_H" >> cc_file;
+	  print "#include <config.h>" >> cc_file;
+	  ## print "#endif" >> cc_file;
+
+	  print "#include \"Array-util.h\"" >> cc_file;
+	  print "#include \"quit.h\"" >> cc_file;
+
+	  printf ("#include \"%s\"\n", h_file) >> cc_file;
+
+	  for (i in bool_headers)
+	    {
+	      printf ("#include \"%s\"\n", bool_headers[i]) >> cc_file;
+	      delete bool_headers[i];
+	    }
+
+          if (result_header_1)
+	    printf ("#include \"%s\"\n", result_header_1) >> cc_file;
+
+          if (result_header_2 && ! (result_header_2 == result_header_1))
+	    printf ("#include \"%s\"\n", result_header_2) >> cc_file;
+
+          if (lhs_header && ! (lhs_header == result_header_1 || lhs_header == result_header_2))
+	    printf ("#include \"%s\"\n", lhs_header) >> cc_file;
+
+          if (rhs_header && ! (rhs_header == lhs_header || rhs_header == result_header_1 || rhs_heaer == result_header_2))
+	    printf ("#include \"%s\"\n", rhs_header) >> cc_file;
+
+	  if (bin_ops)
+            printf ("SPARSE_%s%s_BIN_OPS (%s, %s, %s, %s)\n", lhs_class, 
+		    rhs_class, result_type_1, result_type_2, lhs_type, 
+		    rhs_type) >> cc_file
+
+          if (cmp_ops)
+            printf ("SPARSE_%s%s_CMP_OPS (%s, %s, %s, %s, %s, %s)\n", 
+		    lhs_class, rhs_class, lhs_type, lhs_scalar_zero_val,
+		    lhs_conv, rhs_type, rhs_scalar_zero_val, rhs_conv) >> cc_file
+
+          if (eqne_ops)
+            printf ("SPARSE_%s%s_EQNE_OPS (%s, %s, %s, %s, %s, %s)\n", 
+		    lhs_class, rhs_class, lhs_type, lhs_scalar_zero_val,
+		    lhs_conv, rhs_type, rhs_scalar_zero_val, rhs_conv) >> cc_file
+
+          if (bool_ops)
+            printf ("SPARSE_%s%s_BOOL_OPS2 (%s, %s, %s, %s)\n", lhs_class, 
+		    rhs_class, lhs_type, rhs_type, lhs_scalar_zero_val,
+	            rhs_scalar_zero_val) >> cc_file
+
+
+          close (cc_file);
+        }
+      else
+        printf ("skipping line %d: %s\n", NR, $0); 
+    }
+}
+END {
+  if (make_inclusive_header)
+    print "#endif";
+}
diff --git a/liboctave/sparse-mx-ops b/liboctave/sparse-mx-ops
new file mode 100644
index 0000000..263088d
--- /dev/null
+++ b/liboctave/sparse-mx-ops
@@ -0,0 +1,63 @@
+# Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# types
+#
+# key typename object-type header fwd-decl-ok scalar-zero
+#
+#   S:  scalar
+#   M:  matrix
+#   DM: diagonal matrix
+#   ND: N-d array
+#   SM: sparse matrix
+#
+sm SparseMatrix SM dSparse.h YES 0.0
+scm SparseComplexMatrix SM CSparse.h YES 0.0
+sbm SparseBoolMatrix SM boolSparse.h YES false
+b bool S NONE NO false
+bm boolMatrix M boolMatrix.h YES false
+s double S NONE NO 0.0
+cs Complex S oct-cmplx.h NO 0.0
+m Matrix M dMatrix.h YES 0.0
+cm ComplexMatrix M CMatrix.h YES 0.0
+# ops
+# result_t_1 result_t_2 lhs_t rhs_t op-type lhs_conv rhs_conv headers ...
+#
+# op-type is one of
+#
+#  B: binary ops, + - * /
+#  C: comparison ops, < <= == != >= >
+#  E: == != (Only one of C or E can be used!!)
+#  L: logical ops, & |
+#
+cm scm sm cs BCL NONE real boolSparse.h
+cm scm cs sm BCL real NONE boolSparse.h
+cm scm scm s BCL real NONE boolSparse.h
+cm scm s scm BCL NONE real boolSparse.h
+scm scm scm sm BCL real NONE boolSparse.h
+scm scm sm scm BCL NONE real boolSparse.h
+m sm m sm BCL NONE NONE boolSparse.h
+cm scm m scm BCL NONE real boolSparse.h
+cm scm cm sm BCL real NONE boolSparse.h
+cm scm cm scm BCL real real boolSparse.h
+m sm sm m BCL NONE NONE boolSparse.h
+cm scm scm m BCL real NONE boolSparse.h
+cm scm sm cm BCL NONE real boolSparse.h
+cm scm scm cm BCL real real boolSparse.h
+bm sbm bm sbm EL
+bm sbm sbm bm EL
diff --git a/liboctave/sparse-sort.cc b/liboctave/sparse-sort.cc
new file mode 100644
index 0000000..2fa8e4e
--- /dev/null
+++ b/liboctave/sparse-sort.cc
@@ -0,0 +1,69 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cstring>
+
+#include "oct-sort.cc"
+#include "quit.h"
+
+#include "sparse-sort.h"
+
+// A simple class and instantiation of the octave merge sort class
+// to sort sparse data before matrix creation. This is significantly
+// faster than using octave_qsort.
+
+bool
+octave_sparse_sidxl_comp (octave_sparse_sort_idxl* i, 
+			  octave_sparse_sort_idxl* j)
+{
+  octave_idx_type tmp = i->c - j->c;
+  if (tmp < 0)
+    return true;
+  else if (tmp > 0)
+    return false;
+  return  (i->r < j->r);
+}
+
+template class octave_sort<octave_sparse_sort_idxl *>;
+
+// Need to know the original order of the sorted indexes in
+// sparse assignments, and this class does that
+bool
+octave_idx_vector_comp (octave_idx_vector_sort* i,
+			octave_idx_vector_sort* j)
+{
+  return (i->i < j->i);
+}
+
+template class octave_sort<octave_idx_vector_sort *>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-sort.h b/liboctave/sparse-sort.h
new file mode 100644
index 0000000..554b4d8
--- /dev/null
+++ b/liboctave/sparse-sort.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_sort_h)
+#define octave_sparse_sort_h
+
+#include "oct-sort.h"
+
+class
+octave_sparse_sort_idxl
+{
+public:
+  octave_idx_type r;
+  octave_idx_type c;
+  octave_idx_type idx; 
+};
+
+bool octave_sparse_sidxl_comp (octave_sparse_sort_idxl* i,
+			       octave_sparse_sort_idxl* j);
+
+class
+octave_idx_vector_sort
+{
+public:
+  octave_idx_type i;
+  octave_idx_type idx;
+};
+
+bool octave_idx_vector_comp (octave_idx_vector_sort* i,
+			     octave_idx_vector_sort* j);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-util.cc b/liboctave/sparse-util.cc
new file mode 100644
index 0000000..e76ab86
--- /dev/null
+++ b/liboctave/sparse-util.cc
@@ -0,0 +1,65 @@
+/*
+
+Copyright (C) 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "lo-error.h"
+#include "sparse-util.h"
+
+// FIXME this overload is here due to API change in SuiteSparse (3.1 -> 3.2)
+void
+SparseCholError (int status, char *file, int line, char *message)
+{
+  SparseCholError (status, file, line, message);
+}
+
+void
+SparseCholError (int status, const char *file, int line, const char *message)
+{
+  (*current_liboctave_warning_handler)("warning %i, at line %i in file %s",
+				     status, line, file);
+
+  (*current_liboctave_warning_handler)(message);
+}
+
+int
+SparseCholPrint (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  int ret = vfprintf (stderr, fmt, args);
+  fflush (stderr);
+  va_end (args);
+  return ret;
+}
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/sparse-util.h b/liboctave/sparse-util.h
new file mode 100644
index 0000000..dc95446
--- /dev/null
+++ b/liboctave/sparse-util.h
@@ -0,0 +1,40 @@
+/*
+
+Copyright (C) 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_util_h)
+#define octave_sparse_util_h 1
+
+// FIXME this overload is here due to API change in SuiteSparse (3.1 -> 3.2)
+extern OCTAVE_API void SparseCholError (int status, char *file, 
+                                        int line, char *message);
+extern OCTAVE_API void SparseCholError (int status, const char *file, 
+                                        int line, const char *message);
+extern OCTAVE_API int SparseCholPrint (const char *fmt, ...);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/statdefs.h b/liboctave/statdefs.h
new file mode 100644
index 0000000..c83159b
--- /dev/null
+++ b/liboctave/statdefs.h
@@ -0,0 +1,79 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_statdefs_h)
+#define octave_statdefs_h 1
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifndef S_ISREG			/* Doesn't have POSIX.1 stat stuff. */
+#ifndef mode_t
+#define mode_t unsigned short
+#endif
+#endif
+#if !defined(S_ISBLK) && defined(S_IFBLK)
+#define	S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#endif
+#if !defined(S_ISCHR) && defined(S_IFCHR)
+#define	S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG) && defined(S_IFREG)
+#define	S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISFIFO) && defined(S_IFIFO)
+#define	S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define	S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+#define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
+#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
+#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
+#endif
+#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
+#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
+#endif
+
+#ifndef S_ISLNK
+#undef HAVE_LSTAT
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/liboctave/str-vec.cc b/liboctave/str-vec.cc
new file mode 100644
index 0000000..caec3f7
--- /dev/null
+++ b/liboctave/str-vec.cc
@@ -0,0 +1,253 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+The function string_vector::list_in_columns was adapted from a similar
+function distributed in the GNU file utilities, copyright (C) 85, 88,
+90, 91, 95, 1996 Free Software Foundation, Inc.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "cmd-edit.h"
+#include "lo-utils.h"
+#include "str-vec.h"
+
+string_vector::string_vector (const std::list<std::string>& lst)
+  : Array<std::string> ()
+{
+  size_t n = lst.size ();
+
+  resize (n);
+
+  octave_idx_type i = 0;
+
+  for (std::list<std::string>::const_iterator p = lst.begin ();
+       p != lst.end ();
+       p++)
+    elem(i++) = *p;
+}
+
+// Create a string vector from a NULL terminated list of C strings.
+
+string_vector::string_vector (const char * const *s)
+  : Array<std::string> ()
+{
+  octave_idx_type n = 0;
+
+  const char * const *t = s;
+
+  while (*t++)
+    n++;
+
+  resize (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    elem (i) = s[i];
+}
+
+// Create a string vector from up to N C strings.  Assumes that N is
+// nonnegative.
+
+string_vector::string_vector (const char * const *s, octave_idx_type n)
+  : Array<std::string> (n)
+{
+  for (octave_idx_type i = 0; i < n; i++)
+    elem (i) = s[i];
+}
+
+string_vector&
+string_vector::sort (bool make_uniq)
+{
+  // Don't use Array<std::string>::sort () to allow sorting in place.
+  octave_sort<std::string> lsort;
+  lsort.sort (Array<std::string>::fortran_vec (), length ());
+
+  if (make_uniq)
+    uniq ();
+
+  return *this;
+}
+string_vector&
+string_vector::uniq (void)
+{
+  octave_idx_type len = length ();
+
+  if (len > 0)
+    {
+      octave_idx_type k = 0;
+
+      for (octave_idx_type i = 1; i < len; i++)
+	if (elem(i) != elem(k))
+	  if (++k != i)
+	    elem(k) = elem(i);
+
+      if (len != ++k)
+	resize (k);
+    }
+
+  return *this;
+}
+
+string_vector&
+string_vector::append (const std::string& s)
+{
+  octave_idx_type len = length ();
+
+  resize (len + 1);
+
+  elem(len) = s;
+
+  return *this;
+}
+
+string_vector&
+string_vector::append (const string_vector& sv)
+{
+  octave_idx_type len = length ();
+  octave_idx_type sv_len = sv.length ();
+  octave_idx_type new_len = len + sv_len;
+
+  resize (new_len);
+
+  for (octave_idx_type i = 0; i < sv_len; i++)
+    elem(len + i) = sv[i];
+
+  return *this;
+}
+
+char **
+string_vector::c_str_vec (void) const
+{
+  octave_idx_type len = length ();
+
+  char **retval = new char * [len + 1];
+
+  retval [len] = 0;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    retval[i] = strsave (elem(i).c_str ());
+
+  return retval;
+}
+
+void
+string_vector::delete_c_str_vec (const char * const *v)
+{
+  const char * const *p = v;
+
+  while (*p)
+    delete [] *p++;
+
+  delete [] v;
+}
+
+// Format a list in neat columns.
+
+std::ostream&
+string_vector::list_in_columns (std::ostream& os, int width) const
+{
+  // Compute the maximum name length.
+
+  octave_idx_type max_name_length = 0;
+  octave_idx_type total_names = length ();
+
+  if (total_names == 0)
+    {
+      // List empty, remember to end output with a newline.
+
+      os << "\n";
+      return os;
+    }
+
+  for (octave_idx_type i = 0; i < total_names; i++)
+    {
+      octave_idx_type name_length = elem (i).length ();
+      if (name_length > max_name_length)
+	max_name_length = name_length;
+    }
+
+  // Allow at least two spaces between names.
+
+  max_name_length += 2;
+
+  // Calculate the maximum number of columns that will fit.
+
+  octave_idx_type line_length
+    = (width <= 0) ? command_editor::terminal_cols () : width;
+
+  octave_idx_type nc = line_length / max_name_length;
+  if (nc == 0)
+    nc = 1;
+
+  // Calculate the number of rows that will be in each column except
+  // possibly  for a short column on the right.
+
+  octave_idx_type nr = total_names / nc + (total_names % nc != 0);
+
+  // Recalculate columns based on rows.
+
+  nc = total_names / nr + (total_names % nr != 0);
+
+  octave_idx_type count;
+  for (octave_idx_type row = 0; row < nr; row++)
+    {
+      count = row;
+      octave_idx_type pos = 0;
+
+      // Print the next row.
+
+      while (1)
+	{
+	  std::string nm = elem (count);
+
+	  os << nm;
+	  octave_idx_type name_length = nm.length ();
+
+	  count += nr;
+	  if (count >= total_names)
+	    break;
+
+	  octave_idx_type spaces_to_pad = max_name_length - name_length;
+	  for (octave_idx_type i = 0; i < spaces_to_pad; i++)
+	    os << " ";
+	  pos += max_name_length;
+	}
+      os << "\n";
+    }
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/str-vec.h b/liboctave/str-vec.h
new file mode 100644
index 0000000..2bebd83
--- /dev/null
+++ b/liboctave/str-vec.h
@@ -0,0 +1,108 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_str_vec_h)
+#define octave_str_vec_h 1
+
+#include <iosfwd>
+#include <list>
+#include <string>
+
+#include "Array.h"
+
+class
+OCTAVE_API
+string_vector : public Array<std::string>
+{
+public:
+
+  string_vector (void) : Array<std::string> () { }
+
+  explicit string_vector (octave_idx_type n) : Array<std::string> (n) { }
+
+  string_vector (const char *s) : Array<std::string> (1, s) { }
+
+  string_vector (const std::string& s) : Array<std::string> (1, s) { }
+
+  string_vector (const string_vector& s) : Array<std::string> (s) { }
+
+  string_vector (const std::list<std::string>& lst);
+
+  string_vector (const char * const *s);
+
+  string_vector (const char * const *s, octave_idx_type n);
+
+  string_vector& operator = (const string_vector& s)
+  {
+    if (this != &s)
+      Array<std::string>::operator = (s);
+
+    return *this;
+  }
+
+  ~string_vector (void) { }
+
+  bool empty (void) const { return length () == 0; }
+
+  octave_idx_type max_length (void) const
+  {
+    octave_idx_type n = length ();
+    octave_idx_type longest = 0;
+
+    for (octave_idx_type i = 0; i < n; i++)
+      {
+	octave_idx_type tmp = elem(i).length ();
+
+	if (tmp > longest)
+	  longest = tmp;
+      }
+
+    return longest;
+  }
+
+  std::string& operator[] (octave_idx_type i) { return Array<std::string>::elem (i); }
+
+  std::string operator[] (octave_idx_type i) const { return Array<std::string>::elem (i); }
+
+  string_vector& sort (bool make_uniq = false);
+
+  string_vector& uniq (void);
+
+  string_vector& append (const std::string& s);
+
+  string_vector& append (const string_vector& sv);
+
+  char **c_str_vec (void) const;
+
+  static void delete_c_str_vec (const char * const*);
+
+  std::ostream& list_in_columns (std::ostream&, int width = 0) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/strcasecmp.c b/liboctave/strcasecmp.c
new file mode 100644
index 0000000..859f930
--- /dev/null
+++ b/liboctave/strcasecmp.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can 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.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with the GNU C Library; see the file COPYING.  If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA  02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_STRCASECMP
+
+#include <ctype.h>
+#include <string.h>
+
+/* Compare S1 and S2, ignoring case, returning less than, equal to or
+   greater than zero if S1 is lexiographically less than,
+   equal to or greater than S2.  */
+int
+strcasecmp (const char *s1, const char *s2)
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2)
+    return 0;
+
+  do
+    {
+      c1 = tolower (*p1++);
+      c2 = tolower (*p2++);
+      if (c1 == '\0')
+	break;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
+
+#endif
diff --git a/liboctave/strftime.c b/liboctave/strftime.c
new file mode 100644
index 0000000..4911d6b
--- /dev/null
+++ b/liboctave/strftime.c
@@ -0,0 +1,895 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
+
+   NOTE: The canonical source of this file is maintained with the GNU C
+   Library.  Bugs can be reported to bug-glibc at gnu.org.
+
+   This program is free software; you can 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, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef HAVE_STRFTIME
+
+#ifdef _LIBC
+# define HAVE_LIMITS_H 1
+# define HAVE_MBLEN 1
+# define HAVE_MBRLEN 1
+# define HAVE_STRUCT_ERA_ENTRY 1
+# define HAVE_TM_GMTOFF 1
+# define HAVE_STRUCT_TM_TM_ZONE 1
+# define MULTIBYTE_IS_FORMAT_SAFE 1
+# define STDC_HEADERS 1
+# include <ansidecl.h>
+# include "../locale/localeinfo.h"
+#endif
+
+#include <sys/types.h>		/* Some systems define `time_t' here.  */
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#if HAVE_TZNAME && !HAVE_DECL_TZNAME
+extern OCTAVE_IMPORT char *tzname[];
+#endif
+
+/* Do multibyte processing if multibytes are supported, unless
+   multibyte sequences are safe in formats.  Multibyte sequences are
+   safe if they cannot contain byte sequences that look like format
+   conversion specifications.  The GNU C Library uses UTF8 multibyte
+   encoding, which is safe for formats, but strftime.c can be used
+   with other C libraries that use unsafe encodings.  */
+#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
+
+#if DO_MULTIBYTE
+# if HAVE_MBRLEN
+#  include <wchar.h>
+# else
+   /* Simulate mbrlen with mblen as best we can.  */
+#  define mbstate_t int
+#  define mbrlen(s, n, ps) mblen (s, n)
+#  define mbsinit(ps) (*(ps) == 0)
+# endif
+  static const mbstate_t mbstate_zero;
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#if STDC_HEADERS
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# define memcpy(d, s, n) bcopy (s, d, n)
+#endif
+
+#ifndef __P
+#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif  /* GCC.  */
+#endif  /* Not __P.  */
+
+#ifndef PTR
+#ifdef __STDC__
+#define PTR void *
+#else
+#define PTR char *
+#endif
+#endif
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#define TYPE_SIGNED(t) ((t) -1 < 0)
+
+/* Bound on length of the string representing an integer value of type t.
+   Subtract one for the sign bit if t is signed;
+   302 / 1000 is log10 (2) rounded up;
+   add one for integer division truncation;
+   add one more for a minus sign if t is signed.  */
+#define INT_STRLEN_BOUND(t) \
+  ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
+
+#define TM_YEAR_BASE 1900
+
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+   except every 100th isn't, and every 400th is).  */
+#define __isleap(year)	\
+  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+
+#ifdef _LIBC
+# define gmtime_r __gmtime_r
+# define localtime_r __localtime_r
+#else
+# if ! HAVE_LOCALTIME_R
+#  if ! HAVE_TM_GMTOFF
+/* Approximate gmtime_r as best we can in its absence.  */
+#define gmtime_r my_gmtime_r
+static struct tm *gmtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+gmtime_r (t, tp)
+     const time_t *t;
+     struct tm *tp;
+{
+  struct tm *l = gmtime (t);
+  if (! l)
+    return 0;
+  *tp = *l;
+  return tp;
+}
+#  endif /* ! HAVE_TM_GMTOFF */
+
+/* Approximate localtime_r as best we can in its absence.  */
+#define localtime_r my_localtime_r
+static struct tm *localtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+localtime_r (t, tp)
+     const time_t *t;
+     struct tm *tp;
+{
+  struct tm *l = localtime (t);
+  if (! l)
+    return 0;
+  *tp = *l;
+  return tp;
+}
+# endif /* ! HAVE_LOCALTIME_R */
+#endif /* ! defined (_LIBC) */
+
+
+#define	add(n, f)							      \
+  do									      \
+    {									      \
+      i += (n);								      \
+      if (i >= maxsize)							      \
+	return 0;							      \
+      else								      \
+	if (p)								      \
+	  {								      \
+	    f;								      \
+	    p += (n);							      \
+	  }								      \
+    } while (0)
+#define	cpy(n, s)	add ((n), memcpy((PTR) p, (PTR) (s), (n)))
+
+#if ! HAVE_TM_GMTOFF
+/* Yield the difference between *A and *B,
+   measured in seconds, ignoring leap seconds.  */
+static int tm_diff __P ((const struct tm *, const struct tm *));
+static int
+tm_diff (a, b)
+     const struct tm *a;
+     const struct tm *b;
+{
+  /* Compute intervening leap days correctly even if year is negative.
+     Take care to avoid int overflow in leap day calculations,
+     but it's OK to assume that A and B are close to each other.  */
+  int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
+  int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+  int a100 = a4 / 25 - (a4 % 25 < 0);
+  int b100 = b4 / 25 - (b4 % 25 < 0);
+  int a400 = a100 >> 2;
+  int b400 = b100 >> 2;
+  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+  int years = a->tm_year - b->tm_year;
+  int days = (365 * years + intervening_leap_days
+	      + (a->tm_yday - b->tm_yday));
+  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+		+ (a->tm_min - b->tm_min))
+	  + (a->tm_sec - b->tm_sec));
+}
+#endif /* ! HAVE_TM_GMTOFF */
+
+
+
+/* The number of days from the first day of the first ISO week of this
+   year to the year day YDAY with week day WDAY.  ISO weeks start on
+   Monday; the first ISO week has the year's first Thursday.  YDAY may
+   be as small as YDAY_MINIMUM.  */
+#define ISO_WEEK_START_WDAY 1 /* Monday */
+#define ISO_WEEK1_WDAY 4 /* Thursday */
+#define YDAY_MINIMUM (-366)
+static int iso_week_days __P ((int, int));
+#ifdef __GNUC__
+inline
+#endif
+static int
+iso_week_days (yday, wday)
+     int yday;
+     int wday;
+{
+  /* Add enough to the first operand of % to make it nonnegative.  */
+  int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
+  return (yday
+	  - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
+	  + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
+}
+
+
+#ifndef _NL_CURRENT
+static char const weekday_name[][10] =
+  {
+    "Sunday", "Monday", "Tuesday", "Wednesday",
+    "Thursday", "Friday", "Saturday"
+  };
+static char const month_name[][10] =
+  {
+    "January", "February", "March", "April", "May", "June",
+    "July", "August", "September", "October", "November", "December"
+  };
+#endif
+
+/* Write information from TP into S according to the format
+   string FORMAT, writing no more that MAXSIZE characters
+   (including the terminating '\0') and returning number of
+   characters written.  If S is NULL, nothing will be written
+   anywhere, so to determine how many characters would be
+   written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */
+size_t
+strftime (s, maxsize, format, tp)
+      char *s;
+      size_t maxsize;
+      const char *format;
+      register const struct tm *tp;
+{
+  int hour12 = tp->tm_hour;
+#ifdef _NL_CURRENT
+  const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
+  const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
+  const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
+  const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
+  const char *const ampm = _NL_CURRENT (LC_TIME,
+					hour12 > 11 ? PM_STR : AM_STR);
+  size_t aw_len = strlen (a_wkday);
+  size_t am_len = strlen (a_month);
+  size_t ap_len = strlen (ampm);
+#else
+  const char *const f_wkday = weekday_name[tp->tm_wday];
+  const char *const f_month = month_name[tp->tm_mon];
+  const char *const a_wkday = f_wkday;
+  const char *const a_month = f_month;
+  const char *const ampm = "AMPM" + 2 * (hour12 > 11);
+  size_t aw_len = 3;
+  size_t am_len = 3;
+  size_t ap_len = 2;
+#endif
+  size_t wkday_len = strlen (f_wkday);
+  size_t month_len = strlen (f_month);
+  const char *zone;
+  size_t zonelen;
+  register size_t i = 0;
+  register char *p = s;
+  register const char *f;
+
+  zone = 0;
+#if HAVE_STRUCT_TM_TM_ZONE
+  zone = (const char *) tp->tm_zone;
+#endif
+#if HAVE_TZNAME
+  if (!(zone && *zone) && tp->tm_isdst >= 0)
+    zone = tzname[tp->tm_isdst];
+#endif
+  if (! zone)
+    zone = "";		/* POSIX.2 requires the empty string here.  */
+
+  zonelen = strlen (zone);
+
+  if (hour12 > 12)
+    hour12 -= 12;
+  else
+    if (hour12 == 0) hour12 = 12;
+
+  for (f = format; *f != '\0'; ++f)
+    {
+      int pad;			/* Padding for number ('-', '_', or 0).  */
+      int modifier;		/* Field modifier ('E', 'O', or 0).  */
+      int digits;		/* Max digits for numeric format.  */
+      int number_value; 	/* Numeric value to be printed.  */
+      int negative_number;	/* 1 if the number is negative.  */
+      const char *subfmt;
+      char *bufp;
+      char buf[1 + (sizeof (int) < sizeof (time_t)
+		    ? INT_STRLEN_BOUND (time_t)
+		    : INT_STRLEN_BOUND (int))];
+
+#if DO_MULTIBYTE
+
+       switch (*f)
+	{
+	case '%':
+	  break;
+
+	case '\a': case '\b': case '\t': case '\n':
+	case '\v': case '\f': case '\r':
+	case ' ': case '!': case '"': case '#': case '&': case'\'':
+	case '(': case ')': case '*': case '+': case ',': case '-':
+	case '.': case '/': case '0': case '1': case '2': case '3':
+	case '4': case '5': case '6': case '7': case '8': case '9':
+	case ':': case ';': case '<': case '=': case '>': case '?':
+	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+	case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+	case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+	case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+	case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
+	case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
+	case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
+	case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
+	case 'r': case 's': case 't': case 'u': case 'v': case 'w':
+	case 'x': case 'y': case 'z': case '{': case '|': case '}':
+	case '~':
+	  /* The C Standard requires these 98 characters (plus '%') to
+	     be in the basic execution character set.  None of these
+	     characters can start a multibyte sequence, so they need
+	     not be analyzed further.  */
+	  add (1, *p = *f);
+	  continue;
+
+	default:
+	  /* Copy this multibyte sequence until we reach its end, find
+	     an error, or come back to the initial shift state.  */
+	  {
+	    mbstate_t mbstate = mbstate_zero;
+	    size_t len = 0;
+
+	    do
+	      {
+		size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
+
+		if (bytes == 0)
+		  break;
+
+		if (bytes == (size_t) -2 || bytes == (size_t) -1)
+		  {
+		    len++;
+		    break;
+		  }
+
+		len += bytes;
+	      }
+	    while (! mbsinit (&mbstate));
+
+	    cpy (len, f);
+	    continue;
+	  }
+	}
+
+#else /* ! DO_MULTIBYTE */
+
+      /* Either multibyte encodings are not supported, or they are
+	 safe for formats, so any non-'%' byte can be copied through.  */
+      if (*f != '%')
+	{
+	  add (1, *p = *f);
+	  continue;
+	}
+
+#endif /* ! DO_MULTIBYTE */
+
+      /* Check for flags that can modify a number format.  */
+      ++f;
+      switch (*f)
+	{
+	case '_':
+	case '-':
+	  pad = *f++;
+	  break;
+
+	default:
+	  pad = 0;
+	  break;
+	}
+
+      /* Check for modifiers.  */
+      switch (*f)
+	{
+	case 'E':
+	case 'O':
+	  modifier = *f++;
+	  break;
+
+	default:
+	  modifier = 0;
+	  break;
+	}
+
+      /* Now do the specified format.  */
+      switch (*f)
+	{
+#define DO_NUMBER(d, v) \
+	  digits = d; number_value = v; goto do_number
+#define DO_NUMBER_SPACEPAD(d, v) \
+	  digits = d; number_value = v; goto do_number_spacepad
+
+	case '%':
+	  if (modifier != 0)
+	    goto bad_format;
+	  add (1, *p = *f);
+	  break;
+
+	case 'a':
+	  if (modifier != 0)
+	    goto bad_format;
+	  cpy (aw_len, a_wkday);
+	  break;
+
+	case 'A':
+	  if (modifier != 0)
+	    goto bad_format;
+	  cpy (wkday_len, f_wkday);
+	  break;
+
+	case 'b':
+	case 'h':		/* POSIX.2 extension.  */
+	  if (modifier != 0)
+	    goto bad_format;
+	  cpy (am_len, a_month);
+	  break;
+
+	case 'B':
+	  if (modifier != 0)
+	    goto bad_format;
+	  cpy (month_len, f_month);
+	  break;
+
+	case 'c':
+	  if (modifier == 'O')
+	    goto bad_format;
+#ifdef _NL_CURRENT
+	  if (! (modifier == 'E'
+		 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
+	    subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
+#else
+	  subfmt = "%a %b %e %H:%M:%S %Y";
+#endif
+
+	subformat:
+	  {
+	    size_t len = strftime (p, maxsize - i, subfmt, tp);
+	    if (len == 0 && *subfmt)
+	      return 0;
+	    add (len, ;);
+	  }
+	  break;
+
+	case 'C':		/* POSIX.2 extension.  */
+	  if (modifier == 'O')
+	    goto bad_format;
+#if HAVE_STRUCT_ERA_ENTRY
+	  if (modifier == 'E')
+	    {
+	      struct era_entry *era = _nl_get_era_entry (tp);
+	      if (era)
+		{
+		  size_t len = strlen (era->name_fmt);
+		  cpy (len, era->name_fmt);
+		  break;
+		}
+	    }
+#endif
+	  {
+	    int year = tp->tm_year + TM_YEAR_BASE;
+	    DO_NUMBER (1, year / 100 - (year % 100 < 0));
+	  }
+
+	case 'x':
+	  if (modifier == 'O')
+	    goto bad_format;
+#ifdef _NL_CURRENT
+	  if (! (modifier == 'E'
+		 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
+	    subfmt = _NL_CURRENT (LC_TIME, D_FMT);
+	  goto subformat;
+#endif
+	  /* Fall through.  */
+	case 'D':		/* POSIX.2 extension.  */
+	  if (modifier != 0)
+	    goto bad_format;
+	  subfmt = "%m/%d/%y";
+	  goto subformat;
+
+	case 'd':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_mday);
+
+	case 'e':		/* POSIX.2 extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER_SPACEPAD (2, tp->tm_mday);
+
+	  /* All numeric formats set DIGITS and NUMBER_VALUE and then
+	     jump to one of these two labels.  */
+
+	do_number_spacepad:
+	  /* Force `_' flag.  */
+	  pad = '_';
+
+	do_number:
+	  /* Format the number according to the MODIFIER flag.  */
+
+#ifdef _NL_CURRENT
+	  if (modifier == 'O' && 0 <= number_value)
+	    {
+	      /* Get the locale specific alternate representation of
+		 the number NUMBER_VALUE.  If none exist NULL is returned.  */
+	      const char *cp = _nl_get_alt_digit (number_value);
+
+	      if (cp != NULL)
+		{
+		  size_t digitlen = strlen (cp);
+		  if (digitlen != 0)
+		    {
+		      cpy (digitlen, cp);
+		      break;
+		    }
+		}
+	    }
+#endif
+	  {
+	    unsigned int u = number_value;
+
+	    bufp = buf + sizeof (buf);
+	    negative_number = number_value < 0;
+
+	    if (negative_number)
+	      u = -u;
+
+	    do
+	      *--bufp = u % 10 + '0';
+	    while ((u /= 10) != 0);
+  	  }
+
+	do_number_sign_and_padding:
+	  if (negative_number)
+	    *--bufp = '-';
+
+	  if (pad != '-')
+	    {
+	      int padding = digits - (buf + sizeof (buf) - bufp);
+
+	      if (pad == '_')
+		{
+		  while (0 < padding--)
+		    *--bufp = ' ';
+		}
+	      else
+		{
+		  bufp += negative_number;
+		  while (0 < padding--)
+		    *--bufp = '0';
+		  if (negative_number)
+		    *--bufp = '-';
+		}
+	    }
+
+	  cpy (buf + sizeof (buf) - bufp, bufp);
+	  break;
+
+
+	case 'H':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_hour);
+
+	case 'I':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, hour12);
+
+	case 'k':		/* GNU extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER_SPACEPAD (2, tp->tm_hour);
+
+	case 'l':		/* GNU extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER_SPACEPAD (2, hour12);
+
+	case 'j':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (3, 1 + tp->tm_yday);
+
+	case 'M':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_min);
+
+	case 'm':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_mon + 1);
+
+	case 'n':		/* POSIX.2 extension.  */
+	  add (1, *p = '\n');
+	  break;
+
+	case 'p':
+	  cpy (ap_len, ampm);
+	  break;
+
+	case 'R':		/* GNU extension.  */
+	  subfmt = "%H:%M";
+	  goto subformat;
+
+	case 'r':		/* POSIX.2 extension.  */
+#ifdef _NL_CURRENT
+	  if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
+#endif
+	    subfmt = "%I:%M:%S %p";
+	  goto subformat;
+
+	case 'S':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_sec);
+
+	case 's':		/* GNU extension.  */
+  	  {
+	    struct tm ltm;
+	    time_t t;
+
+	    ltm = *tp;
+	    t = mktime (&ltm);
+
+	    /* Generate string value for T using time_t arithmetic;
+	       this works even if sizeof (long) < sizeof (time_t).  */
+
+	    bufp = buf + sizeof (buf);
+	    negative_number = t < 0;
+
+	    do
+	      {
+		int d = t % 10;
+		t /= 10;
+
+		if (negative_number)
+		  {
+		    d = -d;
+
+		    /* Adjust if division truncates to minus infinity.  */
+		    if (0 < -1 % 10 && d < 0)
+		      {
+			t++;
+			d += 10;
+		      }
+		  }
+
+		*--bufp = d + '0';
+	      }
+	    while (t != 0);
+
+	    digits = 1;
+	    goto do_number_sign_and_padding;
+	  }
+
+	case 'X':
+	  if (modifier == 'O')
+	    goto bad_format;
+#ifdef _NL_CURRENT
+	  if (! (modifier == 'E'
+		 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
+	    subfmt = _NL_CURRENT (LC_TIME, T_FMT);
+	  goto subformat;
+#endif
+	  /* Fall through.  */
+	case 'T':		/* POSIX.2 extension.  */
+	  subfmt = "%H:%M:%S";
+	  goto subformat;
+
+	case 't':		/* POSIX.2 extension.  */
+	  add (1, *p = '\t');
+	  break;
+
+	case 'u':		/* POSIX.2 extension.  */
+	  DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
+
+	case 'U':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
+
+	case 'V':
+	case 'g':		/* GNU extension.  */
+	case 'G':		/* GNU extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+	  {
+	    int year = tp->tm_year + TM_YEAR_BASE;
+	    int days = iso_week_days (tp->tm_yday, tp->tm_wday);
+
+	    if (days < 0)
+	      {
+		/* This ISO week belongs to the previous year.  */
+		year--;
+		days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
+				      tp->tm_wday);
+	      }
+	    else
+	      {
+		int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
+				       tp->tm_wday);
+		if (0 <= d)
+		  {
+		    /* This ISO week belongs to the next year.  */
+		    year++;
+		    days = d;
+		  }
+	      }
+
+	    switch (*f)
+	      {
+	      case 'g':
+		DO_NUMBER (2, (year % 100 + 100) % 100);
+
+	      case 'G':
+		DO_NUMBER (1, year);
+
+	      default:
+		DO_NUMBER (2, days / 7 + 1);
+	      }
+	  }
+
+	case 'W':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
+
+	case 'w':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (1, tp->tm_wday);
+
+	case 'Y':
+#if HAVE_STRUCT_ERA_ENTRY
+	  if (modifier == 'E')
+	    {
+	      struct era_entry *era = _nl_get_era_entry (tp);
+	      if (era)
+		{
+		  subfmt = strchr (era->name_fmt, '\0') + 1;
+		  goto subformat;
+		}
+	    }
+#endif
+	  if (modifier == 'O')
+	    goto bad_format;
+	  else
+	    DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
+
+	case 'y':
+#if HAVE_STRUCT_ERA_ENTRY
+	  if (modifier == 'E')
+	    {
+	      struct era_entry *era = _nl_get_era_entry (tp);
+	      if (era)
+		{
+		  int delta = tp->tm_year - era->start_date[0];
+		  DO_NUMBER (1, (era->offset
+				 + (era->direction == '-' ? -delta : delta)));
+		}
+	    }
+#endif
+	  DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
+
+	case 'Z':
+	  cpy (zonelen, zone);
+	  break;
+
+	case 'z':		/* GNU extension.  */
+	  if (tp->tm_isdst < 0)
+	    break;
+
+	  {
+	    int diff;
+#if HAVE_TM_GMTOFF
+	    diff = tp->tm_gmtoff;
+#else
+	    struct tm gtm;
+	    struct tm ltm;
+	    time_t lt;
+
+	    ltm = *tp;
+	    lt = mktime (&ltm);
+
+	    if (lt == (time_t) -1)
+	      {
+		/* mktime returns -1 for errors, but -1 is also a
+		   valid time_t value.  Check whether an error really
+		   occurred.  */
+		struct tm tm;
+		localtime_r (&lt, &tm);
+
+		if ((ltm.tm_sec ^ tm.tm_sec)
+		    | (ltm.tm_min ^ tm.tm_min)
+		    | (ltm.tm_hour ^ tm.tm_hour)
+		    | (ltm.tm_mday ^ tm.tm_mday)
+		    | (ltm.tm_mon ^ tm.tm_mon)
+		    | (ltm.tm_year ^ tm.tm_year))
+		  break;
+	      }
+
+	    if (! gmtime_r (&lt, &gtm))
+	      break;
+
+	    diff = tm_diff (&ltm, &gtm);
+#endif
+
+	    if (diff < 0)
+	      {
+		add (1, *p = '-');
+		diff = -diff;
+	      }
+	    else
+	      add (1, *p = '+');
+
+	    diff /= 60;
+	    DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
+	  }
+
+	case '\0':		/* GNU extension: % at end of format.  */
+	    --f;
+	    /* Fall through.  */
+	default:
+	  /* Unknown format; output the format, including the '%',
+	     since this is most likely the right thing to do if a
+	     multibyte string has been misparsed.  */
+	bad_format:
+	  {
+	    int flen;
+	    for (flen = 1; f[1 - flen] != '%'; flen++)
+	      continue;
+	    cpy (flen, &f[1 - flen]);
+	  }
+	  break;
+	}
+    }
+
+  if (p)
+    *p = '\0';
+  return i;
+}
+
+#endif
diff --git a/liboctave/strncase.c b/liboctave/strncase.c
new file mode 100644
index 0000000..09f4359
--- /dev/null
+++ b/liboctave/strncase.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can 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.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with the GNU C Library; see the file COPYING.  If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA  02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_STRNCASECMP
+
+#include <ctype.h>
+#include <string.h>
+
+/* Compare no more than N characters of S1 and S2,
+   ignoring case, returning less than, equal to or
+   greater than zero if S1 is lexicographically less
+   than, equal to or greater than S2.  */
+int
+strncasecmp (const char *s1, const char *s2, size_t n)
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2 || n == 0)
+    return 0;
+
+  do
+    {
+      c1 = tolower (*p1++);
+      c2 = tolower (*p2++);
+      if (c1 == '\0' || c1 != c2)
+	return c1 - c2;
+    } while (--n > 0);
+
+  return c1 - c2;
+}
+
+#endif
diff --git a/liboctave/strptime.c b/liboctave/strptime.c
new file mode 100644
index 0000000..d04b8f5
--- /dev/null
+++ b/liboctave/strptime.c
@@ -0,0 +1,875 @@
+/* Convert a string representation of time to a time value.
+   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper at cygnus.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 51 Franklin Street,
+   Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* FIXME: This version of the implementation is not really complete.
+   Some of the fields cannot add information alone.  But if seeing
+   some of them in the same format (such as year, week and weekday)
+   this is enough information for determining the date.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if ! defined (HAVE_STRPTIME) || defined (OCTAVE_HAVE_BROKEN_STRPTIME)
+
+#include <ctype.h>
+#ifdef _LIBC
+#  include <langinfo.h>
+#endif
+#include <limits.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef _LIBC
+# include "../locale/localeinfo.h"
+#endif
+
+
+#ifndef __P
+# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#  define __P(args) args
+# else
+#  define __P(args) ()
+# endif  /* GCC.  */
+#endif  /* Not __P.  */
+
+
+#if ! HAVE_LOCALTIME_R && ! defined localtime_r
+# ifdef _LIBC
+#  define localtime_r __localtime_r
+# else
+/* Approximate localtime_r as best we can in its absence.  */
+#  define localtime_r my_localtime_r
+static struct tm *localtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+localtime_r (t, tp)
+     const time_t *t;
+     struct tm *tp;
+{
+  struct tm *l = localtime (t);
+  if (! l)
+    return 0;
+  *tp = *l;
+  return tp;
+}
+# endif /* ! _LIBC */
+#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
+
+
+#define match_char(ch1, ch2) if (ch1 != ch2) return NULL
+#if defined __GNUC__ && __GNUC__ >= 2
+# define match_string(cs1, s2) \
+  ({ size_t len = strlen (cs1);						      \
+     int result = strncasecmp ((cs1), (s2), len) == 0;			      \
+     if (result) (s2) += len;						      \
+     result; })
+#else
+/* Oh come on.  Get a reasonable compiler.  */
+# define match_string(cs1, s2) \
+  (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
+#endif
+/* We intentionally do not use isdigit() for testing because this will
+   lead to problems with the wide character version.  */
+#define get_number(from, to, n) \
+  do {									      \
+    int __n = n;							      \
+    val = 0;								      \
+    while (*rp == ' ')							      \
+      ++rp;								      \
+    if (*rp < '0' || *rp > '9')						      \
+      return NULL;							      \
+    do {								      \
+      val *= 10;							      \
+      val += *rp++ - '0';						      \
+    } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9');	      \
+    if (val < from || val > to)						      \
+      return NULL;							      \
+  } while (0)
+#ifdef _NL_CURRENT
+# define get_alt_number(from, to, n) \
+  ({									      \
+    __label__ do_normal;						      \
+    if (*decided != raw)						      \
+      {									      \
+	const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS);		      \
+	int __n = n;							      \
+	int any = 0;							      \
+	while (*rp == ' ')						      \
+	  ++rp;								      \
+	val = 0;							      \
+	do {								      \
+	  val *= 10;							      \
+	  while (*alts != '\0')						      \
+	    {								      \
+	      size_t len = strlen (alts);				      \
+	      if (strncasecmp (alts, rp, len) == 0)			      \
+	        break;							      \
+	      alts += len + 1;						      \
+	      ++val;							      \
+	    }								      \
+	  if (*alts == '\0')						      \
+	    {								      \
+	      if (*decided == not && ! any)				      \
+		goto do_normal;						      \
+	      /* If we haven't read anything it's an error.  */		      \
+	      if (! any)						      \
+		return NULL;						      \
+	      /* Correct the premature multiplication.  */		      \
+	      val /= 10;						      \
+	      break;							      \
+	    }								      \
+	  else								      \
+	    *decided = loc;						      \
+	} while (--__n > 0 && val * 10 <= to);				      \
+	if (val < from || val > to)					      \
+	  return NULL;							      \
+      }									      \
+    else								      \
+      {									      \
+       do_normal:							      \
+        get_number (from, to, n);					      \
+      }									      \
+    0;									      \
+  })
+#else
+# define get_alt_number(from, to, n) \
+  /* We don't have the alternate representation.  */			      \
+  get_number(from, to, n)
+#endif
+#define recursive(new_fmt) \
+  (*(new_fmt) != '\0'							      \
+   && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
+
+
+#ifdef _LIBC
+/* This is defined in locale/C-time.c in the GNU libc.  */
+extern const struct locale_data _nl_C_LC_TIME;
+extern const unsigned short int __mon_yday[2][13];
+
+# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
+# define ab_weekday_name \
+  (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
+# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
+# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
+# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
+# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
+# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
+# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
+# define HERE_T_FMT_AMPM \
+  (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
+# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
+
+# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
+#else
+static char const weekday_name[][10] =
+  {
+    "Sunday", "Monday", "Tuesday", "Wednesday",
+    "Thursday", "Friday", "Saturday"
+  };
+static char const ab_weekday_name[][4] =
+  {
+    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+  };
+static char const month_name[][10] =
+  {
+    "January", "February", "March", "April", "May", "June",
+    "July", "August", "September", "October", "November", "December"
+  };
+static char const ab_month_name[][4] =
+  {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+  };
+# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
+# define HERE_D_FMT "%m/%d/%y"
+# define HERE_AM_STR "AM"
+# define HERE_PM_STR "PM"
+# define HERE_T_FMT_AMPM "%I:%M:%S %p"
+# define HERE_T_FMT "%H:%M:%S"
+
+const unsigned short int __mon_yday[2][13] =
+  {
+    /* Normal years.  */
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+    /* Leap years.  */
+    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+  };
+#endif
+
+/* Status of lookup: do we use the locale data or the raw data?  */
+enum locale_status { not, loc, raw };
+
+
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+   except every 100th isn't, and every 400th is).  */
+# define __isleap(year)	\
+  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+/* Compute the day of the week.  */
+static void
+day_of_the_week (struct tm *tm)
+{
+  /* We know that January 1st 1970 was a Thursday (= 4).  Compute the
+     the difference between this data in the one on TM and so determine
+     the weekday.  */
+  int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
+  int wday = (-473
+	      + (365 * (tm->tm_year - 70))
+	      + (corr_year / 4)
+	      - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
+	      + (((corr_year / 4) / 25) / 4)
+	      + __mon_yday[0][tm->tm_mon]
+	      + tm->tm_mday - 1);
+  tm->tm_wday = ((wday % 7) + 7) % 7;
+}
+
+/* Compute the day of the year.  */
+static void
+day_of_the_year (struct tm *tm)
+{
+  tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
+		 + (tm->tm_mday - 1));
+}
+
+static char *
+#ifdef _LIBC
+internal_function
+#endif
+strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
+			enum locale_status *decided));
+
+static char *
+#ifdef _LIBC
+internal_function
+#endif
+strptime_internal (buf, format, tm, decided)
+     const char *buf;
+     const char *format;
+     struct tm *tm;
+     enum locale_status *decided;
+{
+  const char *rp;
+  const char *fmt;
+  int cnt;
+  size_t val;
+  int have_I, is_pm;
+  int century, want_century;
+  int have_wday, want_xday;
+  int have_yday;
+  int have_mon, have_mday;
+
+  rp = buf;
+  fmt = format;
+  have_I = is_pm = 0;
+  century = -1;
+  want_century = 0;
+  have_wday = want_xday = have_yday = have_mon = have_mday = 0;
+
+  while (*fmt != '\0')
+    {
+      /* A white space in the format string matches 0 more or white
+	 space in the input string.  */
+      if (isspace (*fmt))
+	{
+	  while (isspace (*rp))
+	    ++rp;
+	  ++fmt;
+	  continue;
+	}
+
+      /* Any character but `%' must be matched by the same character
+	 in the iput string.  */
+      if (*fmt != '%')
+	{
+	  match_char (*fmt++, *rp++);
+	  continue;
+	}
+
+      ++fmt;
+#ifndef _NL_CURRENT
+      /* We need this for handling the `E' modifier.  */
+    start_over:
+#endif
+      switch (*fmt++)
+	{
+	case '%':
+	  /* Match the `%' character itself.  */
+	  match_char ('%', *rp++);
+	  break;
+	case 'a':
+	case 'A':
+	  /* Match day of week.  */
+	  for (cnt = 0; cnt < 7; ++cnt)
+	    {
+#ifdef _NL_CURRENT
+	      if (*decided !=raw)
+		{
+		  if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
+		    {
+		      if (*decided == not
+			  && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
+				     weekday_name[cnt]))
+			*decided = loc;
+		      break;
+		    }
+		  if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
+		    {
+		      if (*decided == not
+			  && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
+				     ab_weekday_name[cnt]))
+			*decided = loc;
+		      break;
+		    }
+		}
+#endif
+	      if (*decided != loc
+		  && (match_string (weekday_name[cnt], rp)
+		      || match_string (ab_weekday_name[cnt], rp)))
+		{
+		  *decided = raw;
+		  break;
+		}
+	    }
+	  if (cnt == 7)
+	    /* Does not match a weekday name.  */
+	    return NULL;
+	  tm->tm_wday = cnt;
+	  have_wday = 1;
+	  break;
+	case 'b':
+	case 'B':
+	case 'h':
+	  /* Match month name.  */
+	  for (cnt = 0; cnt < 12; ++cnt)
+	    {
+#ifdef _NL_CURRENT
+	      if (*decided !=raw)
+		{
+		  if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
+		    {
+		      if (*decided == not
+			  && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
+				     month_name[cnt]))
+			*decided = loc;
+		      break;
+		    }
+		  if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
+		    {
+		      if (*decided == not
+			  && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
+				     ab_month_name[cnt]))
+			*decided = loc;
+		      break;
+		    }
+		}
+#endif
+	      if (match_string (month_name[cnt], rp)
+		  || match_string (ab_month_name[cnt], rp))
+		{
+		  *decided = raw;
+		  break;
+		}
+	    }
+	  if (cnt == 12)
+	    /* Does not match a month name.  */
+	    return NULL;
+	  tm->tm_mon = cnt;
+	  want_xday = 1;
+	  break;
+	case 'c':
+	  /* Match locale's date and time format.  */
+#ifdef _NL_CURRENT
+	  if (*decided != raw)
+	    {
+	      if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
+		{
+		  if (*decided == loc)
+		    return NULL;
+		}
+	      else
+		{
+		  if (*decided == not &&
+		      strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
+		    *decided = loc;
+		  want_xday = 1;
+		  break;
+		}
+	      *decided = raw;
+	    }
+#endif
+	  if (!recursive (HERE_D_T_FMT))
+	    return NULL;
+	  want_xday = 1;
+	  break;
+	case 'C':
+	  /* Match century number.  */
+	  get_number (0, 99, 2);
+	  century = val;
+	  want_xday = 1;
+	  break;
+	case 'd':
+	case 'e':
+	  /* Match day of month.  */
+	  get_number (1, 31, 2);
+	  tm->tm_mday = val;
+	  have_mday = 1;
+	  want_xday = 1;
+	  break;
+	case 'F':
+	  if (!recursive ("%Y-%m-%d"))
+	    return NULL;
+	  want_xday = 1;
+	  break;
+	case 'x':
+#ifdef _NL_CURRENT
+	  if (*decided != raw)
+	    {
+	      if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
+		{
+		  if (*decided == loc)
+		    return NULL;
+		}
+	      else
+		{
+		  if (decided == not
+		      && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
+		    *decided = loc;
+		  want_xday = 1;
+		  break;
+		}
+	      *decided = raw;
+	    }
+#endif
+	  /* Fall through.  */
+	case 'D':
+	  /* Match standard day format.  */
+	  if (!recursive (HERE_D_FMT))
+	    return NULL;
+	  want_xday = 1;
+	  break;
+	case 'k':
+	case 'H':
+	  /* Match hour in 24-hour clock.  */
+	  get_number (0, 23, 2);
+	  tm->tm_hour = val;
+	  have_I = 0;
+	  break;
+	case 'I':
+	  /* Match hour in 12-hour clock.  */
+	  get_number (1, 12, 2);
+	  tm->tm_hour = val % 12;
+	  have_I = 1;
+	  break;
+	case 'j':
+	  /* Match day number of year.  */
+	  get_number (1, 366, 3);
+	  tm->tm_yday = val - 1;
+	  have_yday = 1;
+	  break;
+	case 'm':
+	  /* Match number of month.  */
+	  get_number (1, 12, 2);
+	  tm->tm_mon = val - 1;
+	  have_mon = 1;
+	  want_xday = 1;
+	  break;
+	case 'M':
+	  /* Match minute.  */
+	  get_number (0, 59, 2);
+	  tm->tm_min = val;
+	  break;
+	case 'n':
+	case 't':
+	  /* Match any white space.  */
+	  while (isspace (*rp))
+	    ++rp;
+	  break;
+	case 'p':
+	  /* Match locale's equivalent of AM/PM.  */
+#ifdef _NL_CURRENT
+	  if (*decided != raw)
+	    {
+	      if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
+		{
+		  if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
+		    *decided = loc;
+		  break;
+		}
+	      if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
+		{
+		  if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
+		    *decided = loc;
+		  is_pm = 1;
+		  break;
+		}
+	      *decided = raw;
+	    }
+#endif
+	  if (!match_string (HERE_AM_STR, rp))
+	    if (match_string (HERE_PM_STR, rp))
+	      is_pm = 1;
+	    else
+	      return NULL;
+	  break;
+	case 'r':
+#ifdef _NL_CURRENT
+	  if (*decided != raw)
+	    {
+	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
+		{
+		  if (*decided == loc)
+		    return NULL;
+		}
+	      else
+		{
+		  if (*decided == not &&
+		      strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
+			      HERE_T_FMT_AMPM))
+		    *decided = loc;
+		  break;
+		}
+	      *decided = raw;
+	    }
+#endif
+	  if (!recursive (HERE_T_FMT_AMPM))
+	    return NULL;
+	  break;
+	case 'R':
+	  if (!recursive ("%H:%M"))
+	    return NULL;
+	  break;
+	case 's':
+	  {
+	    /* The number of seconds may be very high so we cannot use
+	       the `get_number' macro.  Instead read the number
+	       character for character and construct the result while
+	       doing this.  */
+	    time_t secs = 0;
+	    if (*rp < '0' || *rp > '9')
+	      /* We need at least one digit.  */
+	      return NULL;
+
+	    do
+	      {
+		secs *= 10;
+		secs += *rp++ - '0';
+	      }
+	    while (*rp >= '0' && *rp <= '9');
+
+	    if (localtime_r (&secs, tm) == NULL)
+	      /* Error in function.  */
+	      return NULL;
+	  }
+	  break;
+	case 'S':
+	  get_number (0, 61, 2);
+	  tm->tm_sec = val;
+	  break;
+	case 'X':
+#ifdef _NL_CURRENT
+	  if (*decided != raw)
+	    {
+	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
+		{
+		  if (*decided == loc)
+		    return NULL;
+		}
+	      else
+		{
+		  if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
+		    *decided = loc;
+		  break;
+		}
+	      *decided = raw;
+	    }
+#endif
+	  /* Fall through.  */
+	case 'T':
+	  if (!recursive (HERE_T_FMT))
+	    return NULL;
+	  break;
+	case 'u':
+	  get_number (1, 7, 1);
+	  tm->tm_wday = val % 7;
+	  have_wday = 1;
+	  break;
+	case 'g':
+	  get_number (0, 99, 2);
+	  /* FIXME: This cannot determine any field in TM.  */
+	  break;
+	case 'G':
+	  if (*rp < '0' || *rp > '9')
+	    return NULL;
+	  /* FIXME: Ignore the number since we would need some more
+	     information to compute a real date.  */
+	  do
+	    ++rp;
+	  while (*rp >= '0' && *rp <= '9');
+	  break;
+	case 'U':
+	case 'V':
+	case 'W':
+	  get_number (0, 53, 2);
+	  /* FIXME: This cannot determine any field in TM without some
+	     information.  */
+	  break;
+	case 'w':
+	  /* Match number of weekday.  */
+	  get_number (0, 6, 1);
+	  tm->tm_wday = val;
+	  have_wday = 1;
+	  break;
+	case 'y':
+	  /* Match year within century.  */
+	  get_number (0, 99, 2);
+	  /* The "Year 2000: The Millennium Rollover" paper suggests that
+	     values in the range 69-99 refer to the twentieth century.  */
+	  tm->tm_year = val >= 69 ? val : val + 100;
+	  /* Indicate that we want to use the century, if specified.  */
+	  want_century = 1;
+	  want_xday = 1;
+	  break;
+	case 'Y':
+	  /* Match year including century number.  */
+	  get_number (0, 9999, 4);
+	  tm->tm_year = val - 1900;
+	  want_century = 0;
+	  want_xday = 1;
+	  break;
+	case 'Z':
+	  /* FIXME: How to handle this?  */
+	  break;
+	case 'E':
+#ifdef _NL_CURRENT
+	  switch (*fmt++)
+	    {
+	    case 'c':
+	      /* Match locale's alternate date and time format.  */
+	      if (*decided != raw)
+		{
+		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
+
+		  if (*fmt == '\0')
+		    fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
+
+		  if (!recursive (fmt))
+		    {
+		      if (*decided == loc)
+			return NULL;
+		    }
+		  else
+		    {
+		      if (strcmp (fmt, HERE_D_T_FMT))
+			*decided = loc;
+		      want_xday = 1;
+		      break;
+		    }
+		  *decided = raw;
+		}
+	      /* The C locale has no era information, so use the
+		 normal representation.  */
+	      if (!recursive (HERE_D_T_FMT))
+		return NULL;
+	      want_xday = 1;
+	      break;
+	    case 'C':
+	    case 'y':
+	    case 'Y':
+	      /* Match name of base year in locale's alternate
+		 representation.  */
+	      /* FIXME: This is currently not implemented.  It should
+		 use the value _NL_CURRENT (LC_TIME, ERA).  */
+	      break;
+	    case 'x':
+	      if (*decided != raw)
+		{
+		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
+
+		  if (*fmt == '\0')
+		    fmt = _NL_CURRENT (LC_TIME, D_FMT);
+
+		  if (!recursive (fmt))
+		    {
+		      if (*decided == loc)
+			return NULL;
+		    }
+		  else
+		    {
+		      if (strcmp (fmt, HERE_D_FMT))
+			*decided = loc;
+		      break;
+		    }
+		  *decided = raw;
+		}
+	      if (!recursive (HERE_D_FMT))
+		return NULL;
+	      break;
+	    case 'X':
+	      if (*decided != raw)
+		{
+		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
+
+		  if (*fmt == '\0')
+		    fmt = _NL_CURRENT (LC_TIME, T_FMT);
+
+		  if (!recursive (fmt))
+		    {
+		      if (*decided == loc)
+			return NULL;
+		    }
+		  else
+		    {
+		      if (strcmp (fmt, HERE_T_FMT))
+			*decided = loc;
+		      break;
+		    }
+		  *decided = raw;
+		}
+	      if (!recursive (HERE_T_FMT))
+		return NULL;
+	      break;
+	    default:
+	      return NULL;
+	    }
+	  break;
+#else
+	  /* We have no information about the era format.  Just use
+	     the normal format.  */
+	  if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
+	      && *fmt != 'x' && *fmt != 'X')
+	    /* This is an illegal format.  */
+	    return NULL;
+
+	  goto start_over;
+#endif
+	case 'O':
+	  switch (*fmt++)
+	    {
+	    case 'd':
+	    case 'e':
+	      /* Match day of month using alternate numeric symbols.  */
+	      get_alt_number (1, 31, 2);
+	      tm->tm_mday = val;
+	      have_mday = 1;
+	      want_xday = 1;
+	      break;
+	    case 'H':
+	      /* Match hour in 24-hour clock using alternate numeric
+		 symbols.  */
+	      get_alt_number (0, 23, 2);
+	      tm->tm_hour = val;
+	      have_I = 0;
+	      break;
+	    case 'I':
+	      /* Match hour in 12-hour clock using alternate numeric
+		 symbols.  */
+	      get_alt_number (1, 12, 2);
+	      tm->tm_hour = val - 1;
+	      have_I = 1;
+	      break;
+	    case 'm':
+	      /* Match month using alternate numeric symbols.  */
+	      get_alt_number (1, 12, 2);
+	      tm->tm_mon = val - 1;
+	      have_mon = 1;
+	      want_xday = 1;
+	      break;
+	    case 'M':
+	      /* Match minutes using alternate numeric symbols.  */
+	      get_alt_number (0, 59, 2);
+	      tm->tm_min = val;
+	      break;
+	    case 'S':
+	      /* Match seconds using alternate numeric symbols.  */
+	      get_alt_number (0, 61, 2);
+	      tm->tm_sec = val;
+	      break;
+	    case 'U':
+	    case 'V':
+	    case 'W':
+	      get_alt_number (0, 53, 2);
+	      /* FIXME: This cannot determine any field in TM without
+		 further information.  */
+	      break;
+	    case 'w':
+	      /* Match number of weekday using alternate numeric symbols.  */
+	      get_alt_number (0, 6, 1);
+	      tm->tm_wday = val;
+	      have_wday = 1;
+	      break;
+	    case 'y':
+	      /* Match year within century using alternate numeric symbols.  */
+	      get_alt_number (0, 99, 2);
+	      tm->tm_year = val >= 69 ? val : val + 100;
+	      want_xday = 1;
+	      break;
+	    default:
+	      return NULL;
+	    }
+	  break;
+	default:
+	  return NULL;
+	}
+    }
+
+  if (have_I && is_pm)
+    tm->tm_hour += 12;
+
+  if (want_century && century != -1)
+    tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
+
+  if (want_xday && !have_wday) {
+      if ( !(have_mon && have_mday) && have_yday)  {
+	  /* we don't have tm_mon and/or tm_mday, compute them */
+	  int t_mon = 0;
+	  while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
+	      t_mon++;
+	  if (!have_mon)
+	      tm->tm_mon = t_mon - 1;
+	  if (!have_mday)
+	      tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
+      }
+      day_of_the_week (tm);
+  }
+  if (want_xday && !have_yday)
+    day_of_the_year (tm);
+
+  return (char *) rp;
+}
+
+
+char *
+strptime (buf, format, tm)
+     const char *buf;
+     const char *format;
+     struct tm *tm;
+{
+  enum locale_status decided;
+#ifdef _NL_CURRENT
+  decided = not;
+#else
+  decided = raw;
+#endif
+  return strptime_internal (buf, format, tm, &decided);
+}
+
+#endif
diff --git a/liboctave/sun-utils.h b/liboctave/sun-utils.h
new file mode 100644
index 0000000..c1585de
--- /dev/null
+++ b/liboctave/sun-utils.h
@@ -0,0 +1,69 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sun_utils_h)
+#define octave_sun_utils_h 1
+
+// This is only needed to dereference pointers to doubles if mixing
+// GCC and Sun SPARC f77/cc compiled code.  See the GCC manual (where the
+// function access_double() is described) and the Sun f77 manual,
+// which explains that doubles are not always aligned on 8 byte
+// boundaries.
+
+#if defined (__sparc) && defined (__GNUC__)
+
+inline double
+access_double (double *unaligned_ptr)
+{
+  union d2i { double d; int i[2]; };
+
+  union d2i *p = (union d2i *) unaligned_ptr;
+  union d2i u;
+
+  u.i[0] = p->i[0];
+  u.i[1] = p->i[1];
+
+  return u.d;
+}
+
+inline void
+assign_double (double *unaligned_ptr, double value)
+{
+  union d2i { double d; int i[2]; };
+
+  double *ptr = &value;
+  union d2i *v = (union d2i *) ptr;
+  union d2i *p = (union d2i *) unaligned_ptr;
+
+  p->i[0] = v->i[0];
+  p->i[1] = v->i[1];
+}
+
+#endif
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/liboctave/sysdir.h b/liboctave/sysdir.h
new file mode 100644
index 0000000..451cf58
--- /dev/null
+++ b/liboctave/sysdir.h
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sysdir_h)
+#define octave_sysdir_h 1
+
+// This mess suggested by the autoconf manual.
+
+// unistd.h defines _POSIX_VERSION on POSIX.1 systems.
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#if defined (HAVE_DIRENT_H) || defined (_POSIX_VERSION)
+#include <dirent.h>
+#define NLENGTH(dirent) (strlen((dirent)->d_name))
+#else
+#define dirent direct
+#define NLENGTH(dirent) ((dirent)->d_namlen)
+#if defined (HAVE_SYS_NDIR_H)
+#include <sys/ndir.h>
+#endif
+#if defined (HAVE_SYS_DIR_H)
+#include <sys/dir.h>
+#endif
+#if defined (HAVE_NDIR_H)
+#include <ndir.h>
+#endif
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/systime.h b/liboctave/systime.h
new file mode 100644
index 0000000..378cea4
--- /dev/null
+++ b/liboctave/systime.h
@@ -0,0 +1,43 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_systime_h)
+#define octave_systime_h 1
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/syswait.h b/liboctave/syswait.h
new file mode 100644
index 0000000..5523b2b
--- /dev/null
+++ b/liboctave/syswait.h
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 1996, 1997, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_syswait_h)
+#define octave_syswait_h 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This mess suggested by the autoconf manual.  */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined (NeXT) && ! defined (_POSIX_SOURCE)
+#define HAVE_SYS_WAIT_H
+#endif
+
+#if defined HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if defined (NeXT)
+#define HAVE_WAITPID 1
+#define WAITPID(a, b, c) \
+  wait4 ((a) == -1 ? 0 : (a), (union wait *)(b), c, 0)
+
+/* Use the defaults below.  */
+#undef WIFEXITED
+#undef WEXITSTATUS
+#undef WIFSIGNALLED
+#endif
+
+/* NeXT has sys/wait.h, but it is not compatible with POSIX.1, so we
+   try to define waitpid in terms of wait4.  */
+
+#if defined (NeXT)
+#include <sys/wait.h>
+#define waitpid(a, b, c) \
+  wait4 ((a) == -1 ? 0 : (a), (union wait *)(b), c, 0)
+#endif
+
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+
+#ifndef WIFSIGNALLED
+#define WIFSIGNALLED(stat_val) \
+  (((stat_val) & 0177) != 0177 && ((stat_val) & 0177) != 0)
+#endif
+
+#if defined (__MINGW32__) || defined (_MSC_VER)
+#define HAVE_WAITPID 1
+#include <process.h>
+#define WAITPID(a, b, c) _cwait (b, a, c)
+/* Action argument is ignored for _cwait, so arbitrary definition.  */
+#define WNOHANG 0
+#else
+#define WAITPID(a, b, c) waitpid (a, b, c)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/tempnam.c b/liboctave/tempnam.c
new file mode 100644
index 0000000..ae85658
--- /dev/null
+++ b/liboctave/tempnam.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA  02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_TEMPNAM
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern char *__stdio_gen_tempname (const char *dir, const char *pfx,
+				   int dir_search, size_t *lenptr,
+				   FILE **streamptr);
+
+/* Generate a unique temporary filename using up to five characters of PFX
+   if it is not NULL.  The directory to put this file in is searched for
+   as follows: First the environment variable "TMPDIR" is checked.
+   If it contains the name of a writable directory, that directory is used.
+   If not and if DIR is not NULL, that value is checked.  If that fails,
+   P_tmpdir is tried and finally "/tmp".  The storage for the filename
+   is allocated by `malloc'.  */
+char *
+tempnam (const char *dir, const char *pfx)
+{
+  size_t len;
+  register char *s;
+  register char *t = __stdio_gen_tempname(dir, pfx, 1, &len, (FILE **) NULL);
+
+  if (t == NULL)
+    return NULL;
+
+  s = (char *) malloc(len);
+  if (s == NULL)
+    return NULL;
+
+  (void) memcpy(s, t, len);
+  return s;
+}
+
+#endif
diff --git a/liboctave/tempname.c b/liboctave/tempname.c
new file mode 100644
index 0000000..60267d1
--- /dev/null
+++ b/liboctave/tempname.c
@@ -0,0 +1,211 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can 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.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with the GNU C Library; see the file COPYING.  If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA  02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_TEMPNAM
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include <fcntl.h>
+
+#include "statdefs.h"
+
+#ifndef FILENAME_MAX
+#ifdef MAXPATHLEN
+#define FILENAME_MAX MAXPATHLEN
+#else
+#define FILENAME_MAX 1024
+#endif
+#endif
+
+#ifndef P_tmpdir
+#define P_tmpdir "/usr/tmp/"
+#endif
+
+/* Return nonzero if DIR is an existent directory.  */
+static int
+diraccess (const char *dir)
+{
+  struct stat buf;
+  return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
+}
+
+/* Return nonzero if FILE exists.  */
+static int
+exists (const char *file)
+{
+  /* We can stat the file even if we can't read its data.  */
+  struct stat st;
+  int save = errno;
+  if (stat (file, &st) == 0)
+    return 1;
+  else
+    {
+      /* We report that the file exists if stat failed for a reason other
+	 than nonexistence.  In this case, it may or may not exist, and we
+	 don't know; but reporting that it does exist will never cause any
+	 trouble, while reporting that it doesn't exist when it does would
+	 violate the interface of __stdio_gen_tempname.  */
+      int exists = errno != ENOENT;
+      errno = save;
+      return exists;
+    }
+}
+
+
+/* These are the characters used in temporary filenames.  */
+static const char letters[] =
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary filename and return it (in a static buffer).  If
+   STREAMPTR is not NULL, open a stream "w+b" on the file and set
+   *STREAMPTR to it.  If DIR_SEARCH is nonzero, DIR and PFX are used as
+   described for tempnam.  If not, a temporary filename in P_tmpdir with no
+   special prefix is generated.  If LENPTR is not NULL, *LENPTR is set the
+   to length (including the terminating '\0') of the resultant filename,
+   which is returned.  This goes through a cyclic pattern of all possible
+   filenames consisting of five decimal digits of the current pid and three
+   of the characters in `letters'.  Data for tempnam and tmpnam is kept
+   separate, but when tempnam is using P_tmpdir and no prefix (i.e, it is
+   identical to tmpnam), the same data is used.  Each potential filename is
+   tested for an already-existing file of the same name, and no name of an
+   existing file will be returned.  When the cycle reaches its end
+   (12345ZZZ), NULL is returned.  */
+char *
+__stdio_gen_tempname (const char *dir, const char *pfx,
+		      int dir_search, size_t *lenptr,
+		      FILE **streamptr)
+{
+  int saverrno = errno;
+  static const char tmpdir[] = P_tmpdir;
+  static size_t indices[2];
+  size_t *idx;
+  static char buf[FILENAME_MAX];
+  static pid_t oldpid = (pid_t) 0;
+  pid_t pid = getpid();
+  register size_t len, plen, dlen;
+
+  if (dir_search)
+    {
+      register const char *d = getenv("TMPDIR");
+      if (d != NULL && !diraccess(d))
+	d = NULL;
+      if (d == NULL && dir != NULL && diraccess(dir))
+	d = dir;
+      if (d == NULL && diraccess(tmpdir))
+	d = tmpdir;
+      if (d == NULL && diraccess("/tmp"))
+	d = "/tmp";
+      if (d == NULL)
+	{
+	  errno = ENOENT;
+	  return NULL;
+	}
+      dir = d;
+    }
+  else
+    dir = tmpdir;
+
+  dlen = strlen (dir);
+
+  /* Remove trailing slashes from the directory name.  */
+  while (dlen > 1 && dir[dlen - 1] == '/')
+    --dlen;
+
+  if (pfx != NULL && *pfx != '\0')
+    {
+      plen = strlen(pfx);
+      if (plen > 5)
+	plen = 5;
+    }
+  else
+    plen = 0;
+
+  if (dir != tmpdir && !strcmp(dir, tmpdir))
+    dir = tmpdir;
+  idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0];
+
+  if (pid != oldpid)
+    {
+      oldpid = pid;
+      indices[0] = indices[1] = 0;
+    }
+
+  len = dlen + 1 + plen + 5 + 3;
+  for (; *idx < ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
+		 (sizeof (letters) - 1));
+       ++*idx)
+    {
+      /* Construct a file name and see if it already exists.
+
+	 We use a single counter in *IDX to cycle each of three
+	 character positions through each of 62 possible letters.  */
+
+      if (sizeof (buf) < len)
+	return NULL;
+
+      sprintf (buf, "%.*s/%.*s%.5d%c%c%c",
+	       (int) dlen, dir, (int) plen,
+	       pfx, pid % 100000,
+	       letters[*idx
+		       % (sizeof (letters) - 1)],
+	       letters[(*idx / (sizeof (letters) - 1))
+		       % (sizeof (letters) - 1)],
+	       letters[(*idx / ((sizeof (letters) - 1) *
+				(sizeof (letters) - 1)))
+		       % (sizeof (letters) - 1)]
+	       );
+
+      if (! buf || strlen (buf) != (int) len)
+	return NULL;
+  
+      if (streamptr != NULL)
+	abort ();
+      else if (exists (buf))
+	continue;
+
+      /* If the file already existed we have continued the loop above,
+	 so we only get here when we have a winning name to return.  */
+
+      errno = saverrno;
+
+      if (lenptr != NULL)
+	*lenptr = len + 1;
+      return buf;
+    }
+
+  /* We got out of the loop because we ran out of combinations to try.  */
+  errno = EEXIST;		/* ? */
+  return NULL;
+}
+
+#endif
diff --git a/liboctave/uint16NDArray.cc b/liboctave/uint16NDArray.cc
new file mode 100644
index 0000000..8083430
--- /dev/null
+++ b/liboctave/uint16NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "uint16NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_uint16>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_uint16>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_uint16>& a);
+
+NDS_CMP_OPS (uint16NDArray, , octave_uint16, )
+NDS_BOOL_OPS (uint16NDArray, octave_uint16, octave_uint16 (0))
+
+SND_CMP_OPS (octave_uint16, , uint16NDArray, )
+SND_BOOL_OPS (octave_uint16, uint16NDArray, octave_uint16 (0))
+
+NDND_CMP_OPS (uint16NDArray, , uint16NDArray, )
+NDND_BOOL_OPS (uint16NDArray, uint16NDArray, octave_uint16 (0))
+
+MINMAX_FCNS (uint16)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint16NDArray.h b/liboctave/uint16NDArray.h
new file mode 100644
index 0000000..b74ae4a
--- /dev/null
+++ b/liboctave/uint16NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint16NDArray_h)
+#define octave_uint16NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_uint16> uint16NDArray;
+
+NDS_CMP_OP_DECLS (uint16NDArray, octave_uint16, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint16NDArray, octave_uint16, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_uint16, uint16NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint16, uint16NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (uint16NDArray, uint16NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint16NDArray, uint16NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, uint16NDArray, octave_uint16)
+
+MINMAX_DECLS (uint16)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint32NDArray.cc b/liboctave/uint32NDArray.cc
new file mode 100644
index 0000000..aa9e988
--- /dev/null
+++ b/liboctave/uint32NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "uint32NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_uint32>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_uint32>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_uint32>& a);
+
+NDS_CMP_OPS (uint32NDArray, , octave_uint32, )
+NDS_BOOL_OPS (uint32NDArray, octave_uint32, octave_uint32 (0))
+
+SND_CMP_OPS (octave_uint32, , uint32NDArray, )
+SND_BOOL_OPS (octave_uint32, uint32NDArray, octave_uint32 (0))
+
+NDND_CMP_OPS (uint32NDArray, , uint32NDArray, )
+NDND_BOOL_OPS (uint32NDArray, uint32NDArray, octave_uint32 (0))
+
+MINMAX_FCNS (uint32)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint32NDArray.h b/liboctave/uint32NDArray.h
new file mode 100644
index 0000000..e8126f6
--- /dev/null
+++ b/liboctave/uint32NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint32NDArray_h)
+#define octave_uint32NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_uint32> uint32NDArray;
+
+NDS_CMP_OP_DECLS (uint32NDArray, octave_uint32, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint32NDArray, octave_uint32, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_uint32, uint32NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint32, uint32NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (uint32NDArray, uint32NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint32NDArray, uint32NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, uint32NDArray, octave_uint32)
+
+MINMAX_DECLS (uint32)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint64NDArray.cc b/liboctave/uint64NDArray.cc
new file mode 100644
index 0000000..c18182d
--- /dev/null
+++ b/liboctave/uint64NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "uint64NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_uint64>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_uint64>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_uint64>& a);
+
+NDS_CMP_OPS (uint64NDArray, , octave_uint64, )
+NDS_BOOL_OPS (uint64NDArray, octave_uint64, octave_uint64 (0))
+
+SND_CMP_OPS (octave_uint64, , uint64NDArray, )
+SND_BOOL_OPS (octave_uint64, uint64NDArray, octave_uint64 (0))
+
+NDND_CMP_OPS (uint64NDArray, , uint64NDArray, )
+NDND_BOOL_OPS (uint64NDArray, uint64NDArray, octave_uint64 (0))
+
+MINMAX_FCNS (uint64)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint64NDArray.h b/liboctave/uint64NDArray.h
new file mode 100644
index 0000000..d9591b4
--- /dev/null
+++ b/liboctave/uint64NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint64NDArray_h)
+#define octave_uint64NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_uint64> uint64NDArray;
+
+NDS_CMP_OP_DECLS (uint64NDArray, octave_uint64, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint64NDArray, octave_uint64, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_uint64, uint64NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint64, uint64NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (uint64NDArray, uint64NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint64NDArray, uint64NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, uint64NDArray, octave_uint64)
+
+MINMAX_DECLS (uint64)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint8NDArray.cc b/liboctave/uint8NDArray.cc
new file mode 100644
index 0000000..fd6c79e
--- /dev/null
+++ b/liboctave/uint8NDArray.cc
@@ -0,0 +1,57 @@
+// N-D Array  manipulations.
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "uint8NDArray.h"
+#include "mx-op-defs.h"
+#include "intNDArray.cc"
+
+template class OCTAVE_API intNDArray<octave_uint8>;
+
+template OCTAVE_API
+std::ostream&
+operator << (std::ostream& os, const intNDArray<octave_uint8>& a);
+
+template OCTAVE_API
+std::istream&
+operator >> (std::istream& is, intNDArray<octave_uint8>& a);
+
+NDS_CMP_OPS (uint8NDArray, , octave_uint8, )
+NDS_BOOL_OPS (uint8NDArray, octave_uint8, octave_uint8 (0))
+
+SND_CMP_OPS (octave_uint8, , uint8NDArray, )
+SND_BOOL_OPS (octave_uint8, uint8NDArray, octave_uint8 (0))
+
+NDND_CMP_OPS (uint8NDArray, , uint8NDArray, )
+NDND_BOOL_OPS (uint8NDArray, uint8NDArray, octave_uint8 (0))
+
+MINMAX_FCNS (uint8)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/uint8NDArray.h b/liboctave/uint8NDArray.h
new file mode 100644
index 0000000..fc7e97f
--- /dev/null
+++ b/liboctave/uint8NDArray.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint8NDArray_h)
+#define octave_uint8NDArray_h 1
+
+#include "intNDArray.h"
+#include "mx-op-decl.h"
+#include "oct-inttypes.h"
+
+typedef intNDArray<octave_uint8> uint8NDArray;
+
+NDS_CMP_OP_DECLS (uint8NDArray, octave_uint8, OCTAVE_API)
+NDS_BOOL_OP_DECLS (uint8NDArray, octave_uint8, OCTAVE_API)
+
+SND_CMP_OP_DECLS (octave_uint8, uint8NDArray, OCTAVE_API)
+SND_BOOL_OP_DECLS (octave_uint8, uint8NDArray, OCTAVE_API)
+
+NDND_CMP_OP_DECLS (uint8NDArray, uint8NDArray, OCTAVE_API)
+NDND_BOOL_OP_DECLS (uint8NDArray, uint8NDArray, OCTAVE_API)
+
+MARRAY_FORWARD_DEFS (MArrayN, uint8NDArray, octave_uint8)
+
+MINMAX_DECLS (uint8)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/liboctave/vx-ccv-cv.cc b/liboctave/vx-ccv-cv.cc
new file mode 100644
index 0000000..a464f77
--- /dev/null
+++ b/liboctave/vx-ccv-cv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-ccv-cv.h"
+#include "mx-op-defs.h"
+#include "CColVector.h"
+#include "dColVector.h"
+VV_BIN_OPS (ComplexColumnVector, ComplexColumnVector, ColumnVector)
diff --git a/liboctave/vx-ccv-cv.h b/liboctave/vx-ccv-cv.h
new file mode 100644
index 0000000..509b126
--- /dev/null
+++ b/liboctave/vx-ccv-cv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_ccv_cv_h)
+#define octave_vx_ccv_cv_h 1
+#include "CColVector.h"
+#include "dColVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (ComplexColumnVector, ComplexColumnVector, ColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-ccv-s.cc b/liboctave/vx-ccv-s.cc
new file mode 100644
index 0000000..5536f4d
--- /dev/null
+++ b/liboctave/vx-ccv-s.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-ccv-s.h"
+#include "mx-op-defs.h"
+#include "CColVector.h"
+VS_BIN_OPS (ComplexColumnVector, ComplexColumnVector, double)
diff --git a/liboctave/vx-ccv-s.h b/liboctave/vx-ccv-s.h
new file mode 100644
index 0000000..8d9ee14
--- /dev/null
+++ b/liboctave/vx-ccv-s.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_ccv_s_h)
+#define octave_vx_ccv_s_h 1
+#include "CColVector.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (ComplexColumnVector, ComplexColumnVector, double, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-crv-rv.cc b/liboctave/vx-crv-rv.cc
new file mode 100644
index 0000000..6205083
--- /dev/null
+++ b/liboctave/vx-crv-rv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-crv-rv.h"
+#include "mx-op-defs.h"
+#include "CRowVector.h"
+#include "dRowVector.h"
+VV_BIN_OPS (ComplexRowVector, ComplexRowVector, RowVector)
diff --git a/liboctave/vx-crv-rv.h b/liboctave/vx-crv-rv.h
new file mode 100644
index 0000000..864615d
--- /dev/null
+++ b/liboctave/vx-crv-rv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_crv_rv_h)
+#define octave_vx_crv_rv_h 1
+#include "CRowVector.h"
+#include "dRowVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (ComplexRowVector, ComplexRowVector, RowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-crv-s.cc b/liboctave/vx-crv-s.cc
new file mode 100644
index 0000000..79c0584
--- /dev/null
+++ b/liboctave/vx-crv-s.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-crv-s.h"
+#include "mx-op-defs.h"
+#include "CRowVector.h"
+VS_BIN_OPS (ComplexRowVector, ComplexRowVector, double)
diff --git a/liboctave/vx-crv-s.h b/liboctave/vx-crv-s.h
new file mode 100644
index 0000000..4a7ea5f
--- /dev/null
+++ b/liboctave/vx-crv-s.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_crv_s_h)
+#define octave_vx_crv_s_h 1
+#include "CRowVector.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (ComplexRowVector, ComplexRowVector, double, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-cs-cv.cc b/liboctave/vx-cs-cv.cc
new file mode 100644
index 0000000..650b985
--- /dev/null
+++ b/liboctave/vx-cs-cv.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-cs-cv.h"
+#include "mx-op-defs.h"
+#include "CColVector.h"
+#include "oct-cmplx.h"
+#include "dColVector.h"
+SV_BIN_OPS (ComplexColumnVector, Complex, ColumnVector)
diff --git a/liboctave/vx-cs-cv.h b/liboctave/vx-cs-cv.h
new file mode 100644
index 0000000..22702cd
--- /dev/null
+++ b/liboctave/vx-cs-cv.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_cs_cv_h)
+#define octave_vx_cs_cv_h 1
+#include "CColVector.h"
+#include "oct-cmplx.h"
+#include "dColVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (ComplexColumnVector, Complex, ColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-cs-rv.cc b/liboctave/vx-cs-rv.cc
new file mode 100644
index 0000000..ed49d5e
--- /dev/null
+++ b/liboctave/vx-cs-rv.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-cs-rv.h"
+#include "mx-op-defs.h"
+#include "CRowVector.h"
+#include "oct-cmplx.h"
+#include "dRowVector.h"
+SV_BIN_OPS (ComplexRowVector, Complex, RowVector)
diff --git a/liboctave/vx-cs-rv.h b/liboctave/vx-cs-rv.h
new file mode 100644
index 0000000..eb4c503
--- /dev/null
+++ b/liboctave/vx-cs-rv.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_cs_rv_h)
+#define octave_vx_cs_rv_h 1
+#include "CRowVector.h"
+#include "oct-cmplx.h"
+#include "dRowVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (ComplexRowVector, Complex, RowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-cv-ccv.cc b/liboctave/vx-cv-ccv.cc
new file mode 100644
index 0000000..99102ce
--- /dev/null
+++ b/liboctave/vx-cv-ccv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-cv-ccv.h"
+#include "mx-op-defs.h"
+#include "CColVector.h"
+#include "dColVector.h"
+VV_BIN_OPS (ComplexColumnVector, ColumnVector, ComplexColumnVector)
diff --git a/liboctave/vx-cv-ccv.h b/liboctave/vx-cv-ccv.h
new file mode 100644
index 0000000..eca040b
--- /dev/null
+++ b/liboctave/vx-cv-ccv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_cv_ccv_h)
+#define octave_vx_cv_ccv_h 1
+#include "CColVector.h"
+#include "dColVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (ComplexColumnVector, ColumnVector, ComplexColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-cv-cs.cc b/liboctave/vx-cv-cs.cc
new file mode 100644
index 0000000..61f5a6d
--- /dev/null
+++ b/liboctave/vx-cv-cs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-cv-cs.h"
+#include "mx-op-defs.h"
+#include "CColVector.h"
+#include "dColVector.h"
+#include "oct-cmplx.h"
+VS_BIN_OPS (ComplexColumnVector, ColumnVector, Complex)
diff --git a/liboctave/vx-cv-cs.h b/liboctave/vx-cv-cs.h
new file mode 100644
index 0000000..4f13ed7
--- /dev/null
+++ b/liboctave/vx-cv-cs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_cv_cs_h)
+#define octave_vx_cv_cs_h 1
+#include "CColVector.h"
+#include "dColVector.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (ComplexColumnVector, ColumnVector, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fccv-fcv.cc b/liboctave/vx-fccv-fcv.cc
new file mode 100644
index 0000000..15eeef6
--- /dev/null
+++ b/liboctave/vx-fccv-fcv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fccv-fcv.h"
+#include "mx-op-defs.h"
+#include "fCColVector.h"
+#include "fColVector.h"
+VV_BIN_OPS (FloatComplexColumnVector, FloatComplexColumnVector, FloatColumnVector)
diff --git a/liboctave/vx-fccv-fcv.h b/liboctave/vx-fccv-fcv.h
new file mode 100644
index 0000000..9154526
--- /dev/null
+++ b/liboctave/vx-fccv-fcv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fccv_fcv_h)
+#define octave_vx_fccv_fcv_h 1
+#include "fCColVector.h"
+#include "fColVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (FloatComplexColumnVector, FloatComplexColumnVector, FloatColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fccv-fs.cc b/liboctave/vx-fccv-fs.cc
new file mode 100644
index 0000000..42f6d22
--- /dev/null
+++ b/liboctave/vx-fccv-fs.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fccv-fs.h"
+#include "mx-op-defs.h"
+#include "fCColVector.h"
+VS_BIN_OPS (FloatComplexColumnVector, FloatComplexColumnVector, float)
diff --git a/liboctave/vx-fccv-fs.h b/liboctave/vx-fccv-fs.h
new file mode 100644
index 0000000..583e638
--- /dev/null
+++ b/liboctave/vx-fccv-fs.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fccv_fs_h)
+#define octave_vx_fccv_fs_h 1
+#include "fCColVector.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (FloatComplexColumnVector, FloatComplexColumnVector, float, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fcrv-frv.cc b/liboctave/vx-fcrv-frv.cc
new file mode 100644
index 0000000..2d57009
--- /dev/null
+++ b/liboctave/vx-fcrv-frv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fcrv-frv.h"
+#include "mx-op-defs.h"
+#include "fCRowVector.h"
+#include "fRowVector.h"
+VV_BIN_OPS (FloatComplexRowVector, FloatComplexRowVector, FloatRowVector)
diff --git a/liboctave/vx-fcrv-frv.h b/liboctave/vx-fcrv-frv.h
new file mode 100644
index 0000000..909f23b
--- /dev/null
+++ b/liboctave/vx-fcrv-frv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fcrv_frv_h)
+#define octave_vx_fcrv_frv_h 1
+#include "fCRowVector.h"
+#include "fRowVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (FloatComplexRowVector, FloatComplexRowVector, FloatRowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fcrv-fs.cc b/liboctave/vx-fcrv-fs.cc
new file mode 100644
index 0000000..9f6243d
--- /dev/null
+++ b/liboctave/vx-fcrv-fs.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fcrv-fs.h"
+#include "mx-op-defs.h"
+#include "fCRowVector.h"
+VS_BIN_OPS (FloatComplexRowVector, FloatComplexRowVector, float)
diff --git a/liboctave/vx-fcrv-fs.h b/liboctave/vx-fcrv-fs.h
new file mode 100644
index 0000000..9ec9af8
--- /dev/null
+++ b/liboctave/vx-fcrv-fs.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fcrv_fs_h)
+#define octave_vx_fcrv_fs_h 1
+#include "fCRowVector.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (FloatComplexRowVector, FloatComplexRowVector, float, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fcs-fcv.cc b/liboctave/vx-fcs-fcv.cc
new file mode 100644
index 0000000..1b71f59
--- /dev/null
+++ b/liboctave/vx-fcs-fcv.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fcs-fcv.h"
+#include "mx-op-defs.h"
+#include "fCColVector.h"
+#include "oct-cmplx.h"
+#include "fColVector.h"
+SV_BIN_OPS (FloatComplexColumnVector, FloatComplex, FloatColumnVector)
diff --git a/liboctave/vx-fcs-fcv.h b/liboctave/vx-fcs-fcv.h
new file mode 100644
index 0000000..0cb9312
--- /dev/null
+++ b/liboctave/vx-fcs-fcv.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fcs_fcv_h)
+#define octave_vx_fcs_fcv_h 1
+#include "fCColVector.h"
+#include "oct-cmplx.h"
+#include "fColVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (FloatComplexColumnVector, FloatComplex, FloatColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fcs-frv.cc b/liboctave/vx-fcs-frv.cc
new file mode 100644
index 0000000..d30d65e
--- /dev/null
+++ b/liboctave/vx-fcs-frv.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fcs-frv.h"
+#include "mx-op-defs.h"
+#include "fCRowVector.h"
+#include "oct-cmplx.h"
+#include "fRowVector.h"
+SV_BIN_OPS (FloatComplexRowVector, FloatComplex, FloatRowVector)
diff --git a/liboctave/vx-fcs-frv.h b/liboctave/vx-fcs-frv.h
new file mode 100644
index 0000000..e953c75
--- /dev/null
+++ b/liboctave/vx-fcs-frv.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fcs_frv_h)
+#define octave_vx_fcs_frv_h 1
+#include "fCRowVector.h"
+#include "oct-cmplx.h"
+#include "fRowVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (FloatComplexRowVector, FloatComplex, FloatRowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fcv-fccv.cc b/liboctave/vx-fcv-fccv.cc
new file mode 100644
index 0000000..bef9838
--- /dev/null
+++ b/liboctave/vx-fcv-fccv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fcv-fccv.h"
+#include "mx-op-defs.h"
+#include "fCColVector.h"
+#include "fColVector.h"
+VV_BIN_OPS (FloatComplexColumnVector, FloatColumnVector, FloatComplexColumnVector)
diff --git a/liboctave/vx-fcv-fccv.h b/liboctave/vx-fcv-fccv.h
new file mode 100644
index 0000000..e1a9f90
--- /dev/null
+++ b/liboctave/vx-fcv-fccv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fcv_fccv_h)
+#define octave_vx_fcv_fccv_h 1
+#include "fCColVector.h"
+#include "fColVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (FloatComplexColumnVector, FloatColumnVector, FloatComplexColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fcv-fcs.cc b/liboctave/vx-fcv-fcs.cc
new file mode 100644
index 0000000..f5753ae
--- /dev/null
+++ b/liboctave/vx-fcv-fcs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fcv-fcs.h"
+#include "mx-op-defs.h"
+#include "fCColVector.h"
+#include "fColVector.h"
+#include "oct-cmplx.h"
+VS_BIN_OPS (FloatComplexColumnVector, FloatColumnVector, FloatComplex)
diff --git a/liboctave/vx-fcv-fcs.h b/liboctave/vx-fcv-fcs.h
new file mode 100644
index 0000000..0664400
--- /dev/null
+++ b/liboctave/vx-fcv-fcs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fcv_fcs_h)
+#define octave_vx_fcv_fcs_h 1
+#include "fCColVector.h"
+#include "fColVector.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (FloatComplexColumnVector, FloatColumnVector, FloatComplex, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-frv-fcrv.cc b/liboctave/vx-frv-fcrv.cc
new file mode 100644
index 0000000..136a1e1
--- /dev/null
+++ b/liboctave/vx-frv-fcrv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-frv-fcrv.h"
+#include "mx-op-defs.h"
+#include "fCRowVector.h"
+#include "fRowVector.h"
+VV_BIN_OPS (FloatComplexRowVector, FloatRowVector, FloatComplexRowVector)
diff --git a/liboctave/vx-frv-fcrv.h b/liboctave/vx-frv-fcrv.h
new file mode 100644
index 0000000..7f2495b
--- /dev/null
+++ b/liboctave/vx-frv-fcrv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_frv_fcrv_h)
+#define octave_vx_frv_fcrv_h 1
+#include "fCRowVector.h"
+#include "fRowVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (FloatComplexRowVector, FloatRowVector, FloatComplexRowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-frv-fcs.cc b/liboctave/vx-frv-fcs.cc
new file mode 100644
index 0000000..353cf28
--- /dev/null
+++ b/liboctave/vx-frv-fcs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-frv-fcs.h"
+#include "mx-op-defs.h"
+#include "fCRowVector.h"
+#include "fRowVector.h"
+#include "oct-cmplx.h"
+VS_BIN_OPS (FloatComplexRowVector, FloatRowVector, FloatComplex)
diff --git a/liboctave/vx-frv-fcs.h b/liboctave/vx-frv-fcs.h
new file mode 100644
index 0000000..0969596
--- /dev/null
+++ b/liboctave/vx-frv-fcs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_frv_fcs_h)
+#define octave_vx_frv_fcs_h 1
+#include "fCRowVector.h"
+#include "fRowVector.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (FloatComplexRowVector, FloatRowVector, FloatComplex, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fs-fccv.cc b/liboctave/vx-fs-fccv.cc
new file mode 100644
index 0000000..bde8fc7
--- /dev/null
+++ b/liboctave/vx-fs-fccv.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fs-fccv.h"
+#include "mx-op-defs.h"
+#include "fCColVector.h"
+SV_BIN_OPS (FloatComplexColumnVector, float, FloatComplexColumnVector)
diff --git a/liboctave/vx-fs-fccv.h b/liboctave/vx-fs-fccv.h
new file mode 100644
index 0000000..270e9e9
--- /dev/null
+++ b/liboctave/vx-fs-fccv.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fs_fccv_h)
+#define octave_vx_fs_fccv_h 1
+#include "fCColVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (FloatComplexColumnVector, float, FloatComplexColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-fs-fcrv.cc b/liboctave/vx-fs-fcrv.cc
new file mode 100644
index 0000000..b92fd28
--- /dev/null
+++ b/liboctave/vx-fs-fcrv.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-fs-fcrv.h"
+#include "mx-op-defs.h"
+#include "fCRowVector.h"
+SV_BIN_OPS (FloatComplexRowVector, float, FloatComplexRowVector)
diff --git a/liboctave/vx-fs-fcrv.h b/liboctave/vx-fs-fcrv.h
new file mode 100644
index 0000000..b56ee94
--- /dev/null
+++ b/liboctave/vx-fs-fcrv.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_fs_fcrv_h)
+#define octave_vx_fs_fcrv_h 1
+#include "fCRowVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (FloatComplexRowVector, float, FloatComplexRowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-ops b/liboctave/vx-ops
new file mode 100644
index 0000000..32c46fd
--- /dev/null
+++ b/liboctave/vx-ops
@@ -0,0 +1,56 @@
+# Copyright (C) 2003, 2004, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# types
+ccv ComplexColumnVector V CColVector.h YES 0.0
+crv ComplexRowVector V CRowVector.h YES 0.0
+cs Complex S oct-cmplx.h NO 0.0
+cv ColumnVector V dColVector.h YES 0.0
+rv RowVector V dRowVector.h YES 0.0
+s double S NONE NO 0.0
+fccv FloatComplexColumnVector V fCColVector.h YES 0.0
+fcrv FloatComplexRowVector V fCRowVector.h YES 0.0
+fcs FloatComplex S oct-cmplx.h NO 0.0
+fcv FloatColumnVector V fColVector.h YES 0.0
+frv FloatRowVector V fRowVector.h YES 0.0
+fs float S NONE NO 0.0
+# ops
+ccv ccv cv B
+ccv ccv s B
+crv crv rv B
+crv crv s B
+ccv cs cv B
+crv cs rv B
+ccv cv ccv B
+ccv cv cs B
+crv rv crv B
+crv rv cs B
+ccv s ccv B
+crv s crv B
+fccv fccv fcv B
+fccv fccv fs B
+fcrv fcrv frv B
+fcrv fcrv fs B
+fccv fcs fcv B
+fcrv fcs frv B
+fccv fcv fccv B
+fccv fcv fcs B
+fcrv frv fcrv B
+fcrv frv fcs B
+fccv fs fccv B
+fcrv fs fcrv B
diff --git a/liboctave/vx-rv-crv.cc b/liboctave/vx-rv-crv.cc
new file mode 100644
index 0000000..5053853
--- /dev/null
+++ b/liboctave/vx-rv-crv.cc
@@ -0,0 +1,10 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-rv-crv.h"
+#include "mx-op-defs.h"
+#include "CRowVector.h"
+#include "dRowVector.h"
+VV_BIN_OPS (ComplexRowVector, RowVector, ComplexRowVector)
diff --git a/liboctave/vx-rv-crv.h b/liboctave/vx-rv-crv.h
new file mode 100644
index 0000000..8455a48
--- /dev/null
+++ b/liboctave/vx-rv-crv.h
@@ -0,0 +1,8 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_rv_crv_h)
+#define octave_vx_rv_crv_h 1
+#include "CRowVector.h"
+#include "dRowVector.h"
+#include "mx-op-decl.h"
+VV_BIN_OP_DECLS (ComplexRowVector, RowVector, ComplexRowVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-rv-cs.cc b/liboctave/vx-rv-cs.cc
new file mode 100644
index 0000000..ca34def
--- /dev/null
+++ b/liboctave/vx-rv-cs.cc
@@ -0,0 +1,11 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-rv-cs.h"
+#include "mx-op-defs.h"
+#include "CRowVector.h"
+#include "dRowVector.h"
+#include "oct-cmplx.h"
+VS_BIN_OPS (ComplexRowVector, RowVector, Complex)
diff --git a/liboctave/vx-rv-cs.h b/liboctave/vx-rv-cs.h
new file mode 100644
index 0000000..ed14beb
--- /dev/null
+++ b/liboctave/vx-rv-cs.h
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_rv_cs_h)
+#define octave_vx_rv_cs_h 1
+#include "CRowVector.h"
+#include "dRowVector.h"
+#include "oct-cmplx.h"
+#include "mx-op-decl.h"
+VS_BIN_OP_DECLS (ComplexRowVector, RowVector, Complex, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-s-ccv.cc b/liboctave/vx-s-ccv.cc
new file mode 100644
index 0000000..de26362
--- /dev/null
+++ b/liboctave/vx-s-ccv.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-s-ccv.h"
+#include "mx-op-defs.h"
+#include "CColVector.h"
+SV_BIN_OPS (ComplexColumnVector, double, ComplexColumnVector)
diff --git a/liboctave/vx-s-ccv.h b/liboctave/vx-s-ccv.h
new file mode 100644
index 0000000..bddb391
--- /dev/null
+++ b/liboctave/vx-s-ccv.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_s_ccv_h)
+#define octave_vx_s_ccv_h 1
+#include "CColVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (ComplexColumnVector, double, ComplexColumnVector, OCTAVE_API)
+#endif
diff --git a/liboctave/vx-s-crv.cc b/liboctave/vx-s-crv.cc
new file mode 100644
index 0000000..899d130
--- /dev/null
+++ b/liboctave/vx-s-crv.cc
@@ -0,0 +1,9 @@
+// DO NOT EDIT -- generated by mk-ops
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Array-util.h"
+#include "vx-s-crv.h"
+#include "mx-op-defs.h"
+#include "CRowVector.h"
+SV_BIN_OPS (ComplexRowVector, double, ComplexRowVector)
diff --git a/liboctave/vx-s-crv.h b/liboctave/vx-s-crv.h
new file mode 100644
index 0000000..8814148
--- /dev/null
+++ b/liboctave/vx-s-crv.h
@@ -0,0 +1,7 @@
+// DO NOT EDIT -- generated by mk-ops
+#if !defined (octave_vx_s_crv_h)
+#define octave_vx_s_crv_h 1
+#include "CRowVector.h"
+#include "mx-op-decl.h"
+SV_BIN_OP_DECLS (ComplexRowVector, double, ComplexRowVector, OCTAVE_API)
+#endif
diff --git a/missing b/missing
new file mode 100755
index 0000000..bc500ed
--- /dev/null
+++ b/missing
@@ -0,0 +1,163 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can 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, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+fail_missing=false
+
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  gperf
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing - GNU libit 0.0"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`configure.in'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    fail_missing=true
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`configure.in'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    fail_missing=true
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`configure.in'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    fail_missing=true
+    ;;
+
+  automake)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    fail_missing=true
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    fail_missing=true
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    fail_missing=true
+    ;;
+
+  gperf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.gperf' file.  You may need the \`gperf' package
+         in order for those modifications to take effect.  You can get
+         \`gperf' from any GNU archive site."
+    fail_missing=true
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    fail_missing=true
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    fail_missing=true
+    ;;
+esac
+
+if $fail_missing; then
+  echo 1>&2 "\
+
+         You may also need \`$1' if you obtained this package from the CVS
+         archive because files that can be automatically generated are not
+         considered source files and are not checked in to the CVS archive.
+
+         You may also need \`$1' if you ran make maintainer-clean and
+         removed files that can be automatically generated but that are
+         normally distributed as part of the package for convenience."
+  exit 1
+fi
+
+exit 0
diff --git a/mk-opts.pl b/mk-opts.pl
new file mode 100644
index 0000000..209e961
--- /dev/null
+++ b/mk-opts.pl
@@ -0,0 +1,1031 @@
+#! /usr/bin/perl
+#
+# Copyright (C) 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Generate option handling code from a simpler input files for
+# Octave's functions like lsode, dassl, etc.
+
+# FIXME:
+#
+# * Improve default documentation and/or individual documentation
+#   in data files. 
+#
+# * Fix print/show code to display/return something more informative
+#   for special values (for example, -1 ==> infinite in some cases).
+#   Probably need more information in the data files for this.
+
+# Input file format:
+#
+# CLASS = string
+# FCN_NAME = string
+# INCLUDE = file
+# DOC_STRING doc END_DOC_STRING
+# OPTION
+#   NAME = string
+#   DOC_ITEM doc END_DOC_ITEM
+#   TYPE = string
+#   SET_ARG_TYPE = string   (optional, defaults to TYPE)
+#   INIT_VALUE = string | INIT_BODY code END_INIT_BODY
+#   SET_EXPR = string | SET_BODY code END_SET_BODY | SET_CODE code END_SET_CODE
+# END_OPTION
+#
+# END_* must appear at beginning of line (whitespace ignored).
+
+use Getopt::Long;
+
+$opt_emit_opt_class_header = 0;
+$opt_emit_opt_handler_fcns = 0;
+$opt_debug = 0;
+
+GetOptions ("opt-class-header" => \$opt_emit_opt_class_header,
+            "opt-handler-fcns" => \$opt_emit_opt_handler_fcns,
+            "debug" => \$opt_debug);
+
+if (@ARGV == 1)
+  {
+    $INFILE = shift @ARGV;
+    open (INFILE) || die "unable to open input file $INFILE";
+  }
+else
+  {
+    die "usage: mk-opts.pl [options] FILE";
+  }
+
+$opt_num = 0;
+
+&parse_input;
+
+&process_data;
+
+FOO:
+  {
+    $opt_emit_opt_class_header && do { &emit_opt_class_header; last FOO; };
+
+    $opt_emit_opt_handler_fcns && do { &emit_opt_handler_fcns; last FOO; };
+
+    $opt_debug && do { &emit_options_debug; last FOO; };
+  }
+
+sub parse_input
+{
+  local ($have_doc_string);
+
+  while (<INFILE>)
+    {
+      next if (/^\s*$/);
+      next if (/^\s*#.*$/);
+
+      if (/^\s*OPTION\s*$/)
+        {
+          &parse_option_block;
+        }
+      elsif (/^\s*CLASS\s*=\s*"(\w+)"\s*$/)
+        {
+          die "duplicate CLASS" if ($class ne "");
+          $CLASS = $1;
+          $class_name = "${CLASS}_options";
+          $struct_name = "${class_name}_struct";
+          $static_table_name = "${class_name}_table";
+        }
+      elsif (/^\s*FCN_NAME\s*=\s*"(\w+)"\s*$/)
+        {
+          die "duplicate FCN_NAME" if ($fcn_name ne "");
+          $fcn_name = $1;
+        }
+      elsif (/^\s*INCLUDE\s*=\s*"(\S+)"\s*$/)
+        {
+          $include = "${include}#include <$1>\n";
+	}
+      elsif (/^\s*DOC_STRING\s*$/)
+        {
+          die "duplicate DOC_STRING" if ($have_doc_string);
+          &parse_doc_string;
+          $have_doc_string = 1;
+        }
+      else
+        {
+	  die "mk-opts.pl: unknown command: $_\n"
+	}
+    }
+}
+
+sub parse_option_block
+{
+  local ($have_doc_item, $have_init_body, $have_set_body, $have_set_code);
+
+  while (<INFILE>)
+    {
+      next if (/^\s*$/);
+
+      die "missing END_OPTION" if (/^\s*OPTION\s*$/);
+
+      last if (/^\s*END_OPTION\s*$/);
+
+      if (/^\s*NAME\s*=\s*"(.*)"\s*$/)
+        {
+          die "duplicate NAME" if ($name[$opt_num] ne "");
+          $name[$opt_num] = $1;
+          ($opt[$opt_num] = $name[$opt_num]) =~ s/\s+/_/g;
+          $optvar[$opt_num] = "x_$opt[$opt_num]";
+          $kw_tok[$opt_num] = [ split (/\s+/, $name[$opt_num]) ];
+          $n_toks[$opt_num] = @{$kw_tok[$opt_num]};
+        }
+      elsif (/^\s*DOC_ITEM\s*$/)
+        {
+          die "duplicate DOC_ITEM" if ($have_doc_item);
+          &parse_doc_item;
+          $have_doc_item = 1;
+        }
+      elsif (/^\s*TYPE\s*=\s*"(.*)"\s*$/)
+        {
+          die "duplicate TYPE" if ($type[$opt_num] ne "");
+          $type[$opt_num] = $1;
+        }
+      elsif (/^\s*SET_ARG_TYPE\s*=\s*"(.*)"\s*$/)
+        {
+          die "duplicate SET_ARG_TYPE" if ($set_arg_type[$opt_num] ne "");
+          $set_arg_type[$opt_num] = $1;
+        }
+      elsif (/^\s*INIT_VALUE\s*=\s*"(.*)"\s*$/)
+        {
+          die "duplicate INIT_VALUE" if ($init_value[$opt_num] ne "");
+          $init_value[$opt_num] = $1;
+        }
+      elsif (/^\s*SET_EXPR\s*=\s*"(.*)"\s*$/)
+        {
+          die "duplicate SET_EXPR" if ($set_expr[$opt_num] ne "");
+          $set_expr[$opt_num] = $1;
+        }
+      elsif (/^\s*INIT_BODY\s*$/)
+        {
+          die "duplicate INIT_BODY" if ($have_init_body);
+          &parse_init_body;
+          $have_init_body = 1;
+        }
+      elsif (/^\s*SET_BODY\s*$/)
+        {
+          die "duplicate SET_BODY" if ($have_set_body);
+          &parse_set_body;
+          $have_set_body = 1;
+        }
+      elsif (/^\s*SET_CODE\s*$/)
+        {
+          die "duplicate SET_CODE" if ($have_set_code);
+          &parse_set_code;
+          $have_set_code = 1;
+        }
+    }
+
+  if ($set_arg_type[$opt_num] eq "")
+    {
+      $set_arg_type[$opt_num] = $type[$opt_num]
+    }
+  else
+    {
+      $set_arg_type[$opt_num]
+        = &substopt ($set_arg_type[$opt_num], $optvar[$opt_num],
+                     $opt[$opt_num], $type[$opt_num]);
+    }
+
+  $opt_num++;
+}
+
+sub process_data
+{
+  $max_tokens = &max (@n_toks);
+
+  &get_min_match_len_info ($max_tokens);
+
+  $fcn_name = lc ($CLASS) if ($fcn_name eq "");
+    
+  $opt_fcn_name = "${fcn_name}_options" if ($opt_fcn_name eq "");
+
+  $static_object_name = "${fcn_name}_opts";
+
+  if ($doc_string eq "")
+    {
+      $doc_string = "When called with two arguments, this function\\n\\
+allows you set options parameters for the function \@code{$fcn_name}.\\n\\
+Given one argument, \@code{$opt_fcn_name} returns the value of the\\n\\
+corresponding option.  If no arguments are supplied, the names of all\\n\\
+the available options and their current values are displayed.\\n\\\n";
+    }
+}
+
+sub get_min_match_len_info
+{
+  local ($max_tokens) = @_;
+
+  local ($i, $j, $k);
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      for ($j = 0; $j < $max_tokens; $j++)
+        {
+	  $min_tok_len_to_match[$i][$j] = 0;
+        }
+
+      $min_toks_to_match[$i] = 1;
+
+    L1: for ($k = 0; $k < $opt_num; $k++)
+        {
+	  local ($duplicate) = 1;
+
+          if ($i != $k)
+            {
+            L2: for ($j = 0; $j < $max_tokens; $j++)
+                {
+                  if ($j < $n_toks[$i])
+                    {
+                      if ($kw_tok[$i][$j] eq $kw_tok[$k][$j])
+                        {
+                          if ($min_tok_len_to_match[$i][$j] == 0)
+                            {
+                              $min_tok_len_to_match[$i][$j] = 1;
+                            }
+
+                          $min_toks_to_match[$i]++;
+                        }
+                      else
+                        {
+			  $duplicate = 0;
+
+			  if ($min_tok_len_to_match[$i][$j] == 0)
+			    {
+			      $min_tok_len_to_match[$i][$j] = 1;
+			    }
+
+                          local (@s) = split (//, $kw_tok[$i][$j]);
+                          local (@t) = split (//, $kw_tok[$k][$j]);
+
+                          local ($n, $ii);
+                          $n = scalar (@s);
+                          $n = scalar (@t) if (@t < $n);
+
+                          for ($ii = 0; $ii < $n; $ii++)
+                            {
+                              if ("$s[$ii]" eq "$t[$ii]")
+                                {
+				  if ($ii + 2 > $min_tok_len_to_match[$i][$j])
+				    {
+				      $min_tok_len_to_match[$i][$j]++;
+				    }
+                                }
+                              else
+                                {
+                                  last L2;
+                                }
+                            }
+
+                          last L1;
+                        }
+                    }
+		  else
+		    {
+		      die "ambiguous options \"$name[$i]\" and \"$name[$k]\"" if ($duplicate);
+		    }
+                }
+            }
+        }
+    }
+}
+
+sub parse_doc_string
+{
+  while (<INFILE>)
+    {
+      last if (/^\s*END_DOC_STRING\s*$/);
+
+      $doc_string .= $_;
+    }
+
+  $doc_string =~ s/\n/\\n\\\n/g;
+}
+
+sub parse_doc_item
+{
+  while (<INFILE>)
+    {
+      last if (/^\s*END_DOC_ITEM\s*$/);
+
+      $doc_item[$opt_num] .= $_;
+    }
+
+  $doc_item[$opt_num] =~ s/\n/\\n\\\n/g;
+}
+
+sub parse_init_body
+{
+  while (<INFILE>)
+    {
+      last if (/^\s*END_INIT_BODY\s*$/);
+
+      $init_body[$opt_num] .= $_;
+    }
+}
+
+sub parse_set_body
+{
+  while (<INFILE>)
+    {
+      last if (/^\s*END_SET_BODY\s*$/);
+
+      $set_body[$opt_num] .= $_;
+    }
+}
+
+sub parse_set_code
+{
+  while (<INFILE>)
+    {
+      last if (/^\s*END_SET_CODE\s*$/);
+
+      $set_code[$opt_num] .= $_;
+    }
+}
+
+sub emit_opt_class_header
+{
+  local ($i, $s);
+
+  print "// DO NOT EDIT!
+// Generated automatically from $INFILE.
+
+#if !defined (octave_${class_name}_h)
+#define octave_${class_name}_h 1
+
+#include <cfloat>
+#include <cmath>
+
+${include}
+
+class
+${class_name}
+{
+public:
+
+  ${class_name} (void) { init (); }
+
+  ${class_name} (const ${class_name}& opt) { copy (opt); }
+
+  ${class_name}& operator = (const ${class_name}& opt)
+    {
+      if (this != &opt)
+        copy (opt);
+
+      return *this;
+    }
+
+  ~${class_name} (void) { }\n";
+
+  print "\n  void init (void)\n    {\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      if ($init_value[$i])
+        {
+          print "      $optvar[$i] = $init_value[$i];\n";
+        }
+      elsif ($init_body[$i])
+        {
+          $s = &substopt ($init_body[$i], $optvar[$i], $opt[$i], $type[$i]);
+          chop ($s);
+          $s =~ s/^\s*/      /g;
+          $s =~ s/\n\s*/\n      /g;
+          print "$s\n";
+        }
+    }
+
+  print "      reset = true;
+    }\n";
+
+  print "\n  void copy (const ${class_name}& opt)\n    {\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      print "      $optvar[$i] = opt.$optvar[$i];\n";
+    }
+
+  print "      reset = opt.reset;
+    }\n";
+
+  ## For backward compatibility and because set_options is probably
+  ## a better name in some contexts:
+
+  print "\n  void set_options (const ${class_name}& opt) { copy (opt); }\n";
+
+  print "\n  void set_default_options (void) { init (); }\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      if ($set_expr[$i])
+        {
+          &emit_set_decl ($i);
+
+          print "\n    { $optvar[$i] = $set_expr[$i]; reset = true; }\n";
+        }
+      elsif ($set_body[$i])
+        {
+          &emit_set_decl ($i);
+
+          $s = &substopt ($set_body[$i], $optvar[$i], $opt[$i], $type[$i]);
+          chop ($s);
+          $s =~ s/^/  /g;
+          $s =~ s/\n/\n  /g;
+          print "\n    {\n$s\n      reset = true;\n    }\n";
+        }
+      elsif ($set_code[$i])
+        {
+          $s = &substopt ($set_code[$i], $optvar[$i], $opt[$i], $type[$i]);
+          chop ($s);
+          $s =~ s/^  //g;
+          $s =~ s/\n  /\n/g;
+          print "\n$s\n";
+        }
+    }
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      print "  $type[$i] $opt[$i] (void) const\n    { return $optvar[$i]; }\n\n";
+    }
+
+  print "private:\n\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      print "  $type[$i] $optvar[$i];\n";
+    }
+
+  print "\nprotected:\n\n  bool reset;\n};\n\n#endif\n";
+}
+
+sub emit_set_decl
+{
+  local ($i) = @_;
+
+  print "
+  void set_$opt[$i] ($set_arg_type[$i] val)";
+}
+
+sub emit_opt_handler_fcns
+{
+  local ($i);
+  my $header = $INFILE;
+  $header =~ s/[.]\w*$/.h/; # replace .in with .h
+  $header =~ s|^.*/([^/]*)$|$1|; # strip directory part
+
+  print "// DO NOT EDIT!\n// Generated automatically from $INFILE.\n\n";
+
+  print "#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include \"$header\"
+
+#include \"defun-dld.h\"
+#include \"pr-output.h\"
+
+#include \"oct-obj.h\"
+#include \"utils.h\"
+#include \"pager.h\"
+
+static ${class_name} ${static_object_name};\n\n";
+
+  &emit_struct_decl;
+
+  &emit_struct_def;
+
+  &emit_print_function;
+
+  &emit_set_functions;
+
+  &emit_show_function;
+
+  &emit_options_function;
+}
+
+sub emit_struct_decl
+{
+  local ($i);
+
+  print "#define MAX_TOKENS $max_tokens\n\n";
+
+  print "struct ${struct_name}\n{\n";
+
+  print "  const char *keyword;\n";
+  print "  const char *kw_tok[MAX_TOKENS + 1];\n";
+  print "  int min_len[MAX_TOKENS + 1];\n";
+  print "  int min_toks_to_match;\n";
+
+  print "};\n\n";
+}
+
+sub emit_struct_def
+{
+  local ($i);
+
+  print "#define NUM_OPTIONS $opt_num\n\n";
+
+  print "static ${struct_name} ${static_table_name} [] =\n{\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      &emit_option_table_entry ($i, 0);
+
+      if ($i < $opt_num - 1)
+	{
+	  print "\n";
+	}
+    }
+
+  print "};\n\n";
+}
+
+sub emit_option_table_entry
+{
+  local ($i, $empty) = @_;
+
+  local ($k);
+
+  if ($empty)
+    {
+      print "  { 0,\n";
+    }
+  else
+    {
+      print "  { \"$name[$i]\",\n";
+    }
+
+  local ($n) = scalar $#{$kw_tok[$i]};
+  print "    {";
+  for $k (0 .. $max_tokens)
+    {
+      if ($empty || $k > $n)
+        {
+          print " 0,";
+        }
+      else
+        {
+          print " \"$kw_tok[$i][$k]\",";
+        }
+    }
+  print " },\n";
+
+  print "    {";
+  for $k (0 .. $max_tokens)
+    {
+      if ($empty || $k > $n)
+        {
+          print " 0,";
+        }
+      else
+        {
+          print " $min_tok_len_to_match[$i][$k],";
+        }
+    }
+  print " }, $min_toks_to_match[$i], ";
+
+  print "},\n";
+}
+
+sub emit_print_function
+{
+  local ($i);
+
+  ## FIXME -- determine the width of the table automatically.
+
+  print "static void
+print_${class_name} (std::ostream& os)
+{
+  std::ostringstream buf;
+
+  os << \"\\n\"
+     << \"Options for $CLASS include:\\n\\n\"
+     << \"  keyword                                             value\\n\"
+     << \"  -------                                             -----\\n\";
+
+  $struct_name *list = $static_table_name;\n\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      print "  {\n    os << \"  \"
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[$i].keyword
+        << std::resetiosflags (std::ios::left)
+        << \"  \";\n\n";
+
+      if ($type[$i] eq "double")
+        {
+          print "    double val = $static_object_name.$opt[$i] ();\n\n";
+          print "    os << val << \"\\n\";\n";
+        }
+      elsif ($type[$i] eq "float")
+        {
+          print "    float val = $static_object_name.$opt[$i] ();\n\n";
+          print "    os << val << \"\\n\";\n";
+        }
+      elsif ($type[$i] eq "int" || $type[$i] eq "octave_idx_type")
+        {
+          print "    int val = $static_object_name.$opt[$i] ();\n\n";
+          print "    os << val << \"\\n\";\n";
+        }
+      elsif ($type[$i] eq "std::string")
+        {
+          print "    os << $static_object_name.$opt[$i] () << \"\\n\";\n";
+        }
+      elsif ($type[$i] eq "Array<int>" || $type[$i] eq "Array<octave_idx_type>")
+        {
+	  if ($type[$i] eq "Array<int>")
+            {
+              $elt_type = "int";
+            }
+          else
+            {
+              $elt_type = "octave_idx_type";
+            }
+          print "    Array<$elt_type> val = $static_object_name.$opt[$i] ();\n\n";
+          print "    if (val.length () == 1)
+      {
+        os << val(0) << \"\\n\";
+      }
+    else
+      {
+        os << \"\\n\\n\";
+	octave_idx_type len = val.length ();
+	Matrix tmp (len, 1);
+	for (octave_idx_type i = 0; i < len; i++)
+	  tmp(i,0) = val(i);
+        octave_print_internal (os, tmp, false, 2);
+        os << \"\\n\\n\";
+      }\n";
+        }
+      elsif ($type[$i] eq "Array<double>")
+        {
+          print "    Array<double> val = $static_object_name.$opt[$i] ();\n\n";
+          print "    if (val.length () == 1)
+      {
+        os << val(0) << \"\\n\";
+      }
+    else
+      {
+        os << \"\\n\\n\";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << \"\\n\\n\";
+      }\n";
+        }
+      elsif ($type[$i] eq "Array<float>")
+        {
+          print "    Array<float> val = $static_object_name.$opt[$i] ();\n\n";
+          print "    if (val.length () == 1)
+      {
+        os << val(0) << \"\\n\";
+      }
+    else
+      {
+        os << \"\\n\\n\";
+        FloatMatrix tmp = FloatMatrix (FloatColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << \"\\n\\n\";
+      }\n";
+        }
+      else
+        {
+          die ("unknown type $type[$i]");
+        }
+
+      print "  }\n\n";
+    }
+
+  print "  os << \"\\n\";\n}\n\n";
+}
+
+sub emit_set_functions
+{
+  print "static void
+set_${class_name} (const std::string& keyword, const octave_value& val)
+{
+  $struct_name *list = $static_table_name;\n\n";
+
+  $iftok = "if";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      $iftok = "else if" if ($i > 0);
+
+      print "  $iftok (keyword_almost_match (list[$i].kw_tok, list[$i].min_len,
+           keyword, list[$i].min_toks_to_match, MAX_TOKENS))
+    {\n";
+
+      if ($type[$i] eq "double")
+        {
+          print "      double tmp = val.double_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      elsif ($type[$i] eq "float")
+        {
+          print "      float tmp = val.float_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      elsif ($type[$i] eq "int" || $type[$i] eq "octave_idx_type")
+        {
+          print "      int tmp = val.int_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      elsif ($type[$i] eq "std::string")
+        {
+          print "      std::string tmp = val.string_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      elsif ($type[$i] eq "Array<int>" || $type[$i] eq "Array<octave_idx_type>")
+        {
+          print "      Array<int> tmp = val.int_vector_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      elsif ($type[$i] eq "Array<double>")
+        {
+          print "      Array<double> tmp = val.vector_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      elsif ($type[$i] eq "Array<float>")
+        {
+          print "      Array<float> tmp = val.float_vector_value ();\n\n";
+          print "      if (! error_state)
+        $static_object_name.set_$opt[$i] (tmp);\n";
+        }
+      else
+        {
+          die ("unknown type $type[$i]");
+        }
+
+      print "    }\n";
+    }
+
+  print "  else
+    {
+      warning (\"$opt_fcn_name: no match for `%s'\", keyword.c_str ());
+    }
+}\n\n";
+}
+
+sub emit_show_function
+{
+  local ($i, $iftok);
+
+  print "static octave_value_list
+show_${class_name} (const std::string& keyword)
+{
+  octave_value retval;
+
+  $struct_name *list = $static_table_name;\n\n";
+
+  $iftok = "if";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      $iftok = "else if" if ($i > 0);
+
+      print "  $iftok (keyword_almost_match (list[$i].kw_tok, list[$i].min_len,
+           keyword, list[$i].min_toks_to_match, MAX_TOKENS))
+    {\n";
+
+      if ($type[$i] eq "double")
+        {
+          print "      double val = $static_object_name.$opt[$i] ();\n\n";
+          print "      retval = val;\n";
+        }
+      elsif ($type[$i] eq "float")
+        {
+          print "      float val = $static_object_name.$opt[$i] ();\n\n";
+          print "      retval = val;\n";
+        }
+      elsif ($type[$i] eq "int" || $type[$i] eq "octave_idx_type")
+        {
+          print "      int val = $static_object_name.$opt[$i] ();\n\n";
+          print "      retval = static_cast<double> (val);\n";
+        }
+      elsif ($type[$i] eq "std::string")
+        {
+          print "      retval = $static_object_name.$opt[$i] ();\n";
+        }
+      elsif ($type[$i] eq "Array<int>" || $type[$i] eq "Array<octave_idx_type>")
+        {
+	  if ($type[$i] eq "Array<int>")
+            {
+              $elt_type = "int";
+            }
+          else
+            {
+              $elt_type = "octave_idx_type";
+            }
+          print "      Array<$elt_type> val = $static_object_name.$opt[$i] ();\n\n";
+          print "      if (val.length () == 1)
+        {
+          retval = static_cast<double> (val(0));
+        }
+      else
+        {
+	  octave_idx_type len = val.length ();
+	  ColumnVector tmp (len);
+	  for (octave_idx_type i = 0; i < len; i++)
+	    tmp(i) = val(i);
+          retval = tmp;
+        }\n";
+        }
+      elsif ($type[$i] eq "Array<double>")
+        {
+          print "      Array<double> val = $static_object_name.$opt[$i] ();\n\n";
+          print "      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }\n";
+        }
+      elsif ($type[$i] eq "Array<float>")
+        {
+          print "      Array<float> val = $static_object_name.$opt[$i] ();\n\n";
+          print "      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = FloatColumnVector (val);
+        }\n";
+        }
+      else
+        {
+          die ("unknown type $type[$i]");
+        }
+
+      print "    }\n";
+    }
+
+  print "  else
+    {
+      warning (\"$opt_fcn_name: no match for `%s'\", keyword.c_str ());
+    }
+
+  return retval;\n}\n\n";
+}
+
+sub emit_options_function
+{
+  print "DEFUN_DLD ($opt_fcn_name, args, ,
+  \"-*- texinfo -*-\\n\\
+\@deftypefn {Loadable Function} {} $opt_fcn_name (\@var{opt}, \@var{val})\\n\\
+$doc_string\\n\\
+Options include\\n\\
+\\n\\
+\@table \@code\\n\\\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      print "\@item \\\"$name[$i]\\\"\\n\\\n";
+      if ($doc_item[$i] ne "")
+	{
+	  print "$doc_item[$i]";
+	}
+    }
+
+  print "\@end table\\n\\\n\@end deftypefn\")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_${class_name} (octave_stdout);
+    }
+  else if (nargin == 1 || nargin == 2)
+    {
+      std::string keyword = args(0).string_value ();
+
+      if (! error_state)
+        {
+          if (nargin == 1)
+            retval = show_${class_name} (keyword);
+          else
+            set_${class_name} (keyword, args(1));
+        }
+      else
+        error (\"$opt_fcn_name: expecting keyword as first argument\");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}\n";  
+}
+
+sub emit_options_debug
+{
+  print "CLASS = \"$class\"\n";
+
+  for ($i = 0; $i < $opt_num; $i++)
+    {
+      $NAME = $name[$i];
+      ($OPT = $NAME) =~ s/\s+/_/g;
+      $OPTVAR = "x_$OPT";
+      $TYPE = $type[$i];
+      print "\n";
+      print "OPTION\n";
+      print "  NAME = \"$NAME\"\n";
+      print "  TYPE = \"$TYPE\"\n";
+      if ($set_arg_type[$i])
+        {
+          print eval ("\"  SET_ARG_TYPE = \\\"$set_arg_type[$i]\\\"\"") . "\n";
+        }
+      if ($init_value[$i])
+        {
+          print "  INIT_VALUE = \"$init_value[$i]\"\n";
+        }
+      if ($init_body[$i])
+        {
+          print "  INIT_BODY\n";
+          print &substopt ($init_body[$i]);
+          print "  END_INIT_BODY\n";
+        }
+      if ($set_expr[$i])
+        {
+          print "  SET_EXPR = \"$set_expr[$i]\"\n";
+        }
+      if ($set_body[$i])
+        {
+          print "  SET_BODY\n";
+          print &substopt ($set_body[$i]);
+          print "  END_SET_BODY\n";
+        }
+      if ($set_code[$i])
+        {
+          print "  SET_CODE\n";
+          print &substopt ($set_code[$i]);
+          print "  END_SET_CODE\n";
+        }
+      print "END_OPTION\n";
+    }
+}
+
+sub substopt
+{
+  local ($string, $OPTVAR, $OPT, $TYPE) = @_;
+
+  $string =~ s/\$OPTVAR/$OPTVAR/g;
+  $string =~ s/\$OPT/$OPT/g;
+  $string =~ s/\$TYPE/$TYPE/g;
+
+  $string;
+}
+
+sub print_assoc_array
+{
+  local (%t) = @_;
+
+  local ($k);
+
+  foreach $k (keys (%t))
+    {
+      print "$k: $t{$k}\n";
+    }
+}
+
+sub max
+{
+  local ($max) = shift;
+
+  foreach (@_)
+    {
+      $max = $_ if $max < $_;
+    }
+
+  $max;
+}
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..2a66feb
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,36 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at gnu.org>
+# Created: 1993-05-16
+# Last modified: Wed Jan 25 09:35:21 1995
+# Public domain
+
+errstatus=0
+
+dirmode=0755
+
+for file in ${1+"$@"} ; do 
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" || errstatus=$?
+        echo "chmod $dirmode $pathcomp" 1>&2
+        chmod $dirmode "$pathcomp" || errstatus=$?
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/mkoctfile.cc.in b/mkoctfile.cc.in
new file mode 100644
index 0000000..65a3f6b
--- /dev/null
+++ b/mkoctfile.cc.in
@@ -0,0 +1,760 @@
+/*
+
+Copyright (C) 2008, 2009 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <string>
+#include <map>
+#include <list>
+#include <algorithm>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <cstdlib>
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+#include <windows.h>
+#ifdef _MSC_VER
+#define popen _popen
+#define pclose _pclose
+#endif
+#endif
+
+using namespace std;
+
+static bool initialized = false;
+static map<string,string> vars;
+
+static string OCTAVE_VERSION = %OCTAVE_CONF_VERSION%;
+
+static std::string
+substitute_prefix (const std::string& s, const std::string& prefix,
+		   const std::string& new_prefix)
+{
+  std::string retval = s;
+
+  if (!prefix.empty () && new_prefix != prefix)
+    {
+      int len = prefix.length ();
+      if (retval.find (prefix) == 0)
+	retval.replace (0, len, new_prefix);
+    }
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  std::replace (retval.begin (), retval.end (), '/', '\\');
+#endif
+
+  return retval;
+}
+
+static string
+get_line (FILE *fp)
+{
+  static vector<char> buf (100);
+  int idx = 0;
+  char c;
+
+  while (true)
+    {
+      c = static_cast<char> (fgetc (fp));
+      if (c == '\n' || c == EOF)
+	break;
+      if (buf.size () <= idx)
+	buf.resize (buf.size () + 100);
+      buf[idx++] = c;
+    }
+  if (idx == 0)
+    return string ("");
+  else
+    return string (&buf[0], idx);
+}
+
+
+static string
+get_variable (const char *name, const string& defval)
+{
+  const char *val = getenv (name);
+  if (val == NULL || val[0] == '\0')
+    return defval;
+  else
+    return string (val);
+}
+
+static string
+quote_path (const string& s)
+{
+  if (s.find (' ') != string::npos && s[0] != '"')
+    return "\"" + s + "\"";
+  else
+    return s;
+}
+
+static void
+initialize (void)
+{
+  if (initialized)
+    return;
+
+  initialized = true;
+
+  vars["OCTAVE_HOME"] = get_variable ("OCTAVE_HOME", "");
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  int n = 1024;
+
+  std::string bin_dir (n, '\0');
+
+  while (true)
+    {
+      int status = GetModuleFileName (0, &bin_dir[0], n);
+
+      if (status < n)
+	{
+	  bin_dir.resize (status);
+	  break;
+	}
+      else
+	{
+	  n *= 2;
+	  bin_dir.resize (n);
+	}
+    }
+
+  if (! bin_dir.empty ())
+    {
+      size_t pos = bin_dir.rfind ("\\bin\\");
+
+      if (pos != string::npos)
+	vars["OCTAVE_HOME"] = bin_dir.substr (0, pos);
+    }
+#endif
+
+  vars["SED"] = get_variable ("SED", %OCTAVE_CONF_SED%);
+
+  vars["OCTAVE_PREFIX"] = %OCTAVE_CONF_PREFIX%;
+
+  std::string DEFAULT_OCTINCLUDEDIR = %OCTAVE_CONF_OCTINCLUDEDIR%;
+  std::string DEFAULT_INCLUDEDIR = %OCTAVE_CONF_INCLUDEDIR%;
+  std::string DEFAULT_LIBDIR = %OCTAVE_CONF_LIBDIR%;
+  std::string DEFAULT_OCTLIBDIR = %OCTAVE_CONF_OCTLIBDIR%;
+
+  if (! vars["OCTAVE_HOME"].empty ())
+    {
+      DEFAULT_OCTINCLUDEDIR
+	= substitute_prefix (DEFAULT_OCTINCLUDEDIR, vars["OCTAVE_PREFIX"],
+			     vars["OCTAVE_HOME"]);
+
+      DEFAULT_INCLUDEDIR
+	= substitute_prefix (DEFAULT_INCLUDEDIR, vars["OCTAVE_PREFIX"],
+			     vars["OCTAVE_HOME"]);
+
+      DEFAULT_LIBDIR
+	= substitute_prefix (DEFAULT_LIBDIR, vars["OCTAVE_PREFIX"],
+			     vars["OCTAVE_HOME"]);
+
+      DEFAULT_OCTLIBDIR
+	= substitute_prefix (DEFAULT_OCTLIBDIR, vars["OCTAVE_PREFIX"],
+			     vars["OCTAVE_HOME"]);
+    }
+
+  vars["OCTINCLUDEDIR"] = get_variable ("OCTINCLUDEDIR", DEFAULT_OCTINCLUDEDIR);
+  vars["INCLUDEDIR"] = get_variable ("INCLUDEDIR", DEFAULT_INCLUDEDIR);
+  vars["LIBDIR"] = get_variable ("LIBDIR", DEFAULT_LIBDIR);
+  vars["OCTLIBDIR"] = get_variable ("OCTLIBDIR", DEFAULT_OCTLIBDIR);
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  std::string DEFAULT_INCFLAGS = "-I" + quote_path (vars["OCTINCLUDEDIR"])
+    + " -I" + quote_path (vars["OCTINCLUDEDIR"] + "\\octave");
+#else
+  std::string DEFAULT_INCFLAGS = "-I" + quote_path (vars["OCTINCLUDEDIR"])
+ + " -I" + quote_path (vars["OCTINCLUDEDIR"] + "/octave");
+#endif
+  if (vars["INCLUDEDIR"] != "/usr/include")
+    DEFAULT_INCFLAGS += " -I" + quote_path (vars["INCLUDEDIR"]);
+
+  std::string DEFAULT_LFLAGS = "-L" + quote_path (vars["OCTLIBDIR"]);
+  if (vars["LIBDIR"] != "/usr/lib")
+    DEFAULT_LFLAGS += " -L" + quote_path (vars["LIBDIR"]);
+
+  vars["CPPFLAGS"] = get_variable ("CPPFLAGS", %OCTAVE_CONF_CPPFLAGS%);
+  vars["INCFLAGS"] = get_variable ("INCFLAGS", DEFAULT_INCFLAGS);
+  vars["F77"] = get_variable ("F77", %OCTAVE_CONF_F77%);
+  vars["FFLAGS"] = get_variable ("FFLAGS", %OCTAVE_CONF_FFLAGS%);
+  vars["FPICFLAG"] = get_variable ("FPICFLAG", %OCTAVE_CONF_FPICFLAG%);
+  vars["CC"] = get_variable ("CC", %OCTAVE_CONF_CC%);
+  vars["CFLAGS"] = get_variable ("CFLAGS", %OCTAVE_CONF_CFLAGS%);
+  vars["CPICFLAG"] = get_variable ("CPICFLAG", %OCTAVE_CONF_CPICFLAG%);
+  vars["CXX"] = get_variable ("CXX", %OCTAVE_CONF_CXX%);
+  vars["CXXFLAGS"] = get_variable ("CXXFLAGS", %OCTAVE_CONF_CXXFLAGS%);
+  vars["CXXPICFLAG"] = get_variable ("CXXPICFLAG", %OCTAVE_CONF_CXXPICFLAG%);
+  vars["XTRA_CFLAGS"] = get_variable ("XTRA_CFLAGS", %OCTAVE_CONF_XTRA_CFLAGS%);
+  vars["XTRA_CXXFLAGS"] = get_variable ("XTRA_CXXFLAGS", %OCTAVE_CONF_XTRA_CXXFLAGS%);
+
+  vars["DEPEND_FLAGS"] = get_variable ("DEPEND_FLAGS", %OCTAVE_CONF_DEPEND_FLAGS%);
+  vars["DEPEND_EXTRA_SED_PATTERN"] = get_variable ("DEPEND_EXTRA_SED_PATTERN", %OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%);
+
+  vars["DL_LD"] = get_variable ("DL_LD", %OCTAVE_CONF_DL_LD%);
+  vars["DL_LDFLAGS"] = get_variable ("DL_LDFLAGS", %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%);
+
+  vars["RLD_FLAG"] = get_variable ("RLD_FLAG", %OCTAVE_CONF_RLD_FLAG%);
+  vars["RDYNAMIC_FLAG"] = get_variable ("RDYNAMIC_FLAG", %OCTAVE_CONF_RDYNAMIC_FLAG%);
+  vars["LIBOCTAVE"] = "-loctave";
+  vars["LIBOCTINTERP"] = "-loctinterp";
+  vars["LIBREADLINE"] = "-lreadline";
+  vars["LIBCRUFT"] = "-lcruft";
+  vars["BLAS_LIBS"] = get_variable ("BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%);
+  vars["FFTW_LIBS"] = get_variable ("FFTW_LIBS", %OCTAVE_CONF_FFTW_LIBS%);
+  vars["LIBS"] = get_variable ("LIBS", %OCTAVE_CONF_LIBS%);
+  vars["FLIBS"] = get_variable ("FLIBS", %OCTAVE_CONF_FLIBS%);
+  vars["LD_CXX"] = get_variable ("LD_CXX", %OCTAVE_CONF_LD_CXX%);
+  vars["LDFLAGS"] = get_variable ("LDFLAGS", %OCTAVE_CONF_LDFLAGS%);
+  vars["LD_STATIC_FLAG"] = get_variable ("LD_STATIC_FLAG", %OCTAVE_CONF_LD_STATIC_FLAG%);
+  vars["LFLAGS"] = get_variable ("LFLAGS", DEFAULT_LFLAGS);
+
+  vars["ALL_FFLAGS"] = vars["FFLAGS"];
+
+  vars["ALL_CFLAGS"] = vars["INCFLAGS"] + " " + vars["XTRA_CFLAGS"]
+    + " " + vars["CFLAGS"];
+
+  vars["ALL_CXXFLAGS"] = vars["INCFLAGS"] + " " + vars["XTRA_CXXFLAGS"]
+    + " " + vars["CXXFLAGS"];
+
+  vars["ALL_LDFLAGS"] = vars["LD_STATIC_FLAG"] + " " + vars["CPICFLAG"]
+    + " " + vars["LDFLAGS"];
+
+  vars["OCTAVE_LIBS"] = vars["LIBOCTINTERP"] + " " + vars["LIBOCTAVE"]
+    + " " + vars["SPECIAL_MATH_LIB"] + " " + vars["LIBCRUFT"];
+}
+
+static string usage_msg = "usage: mkoctfile [options] file ...";
+static string version_msg = "mkoctfile, version " + OCTAVE_VERSION;
+static bool debug = false;
+static string help_msg =
+"\n"
+"Options:\n"
+"\n"
+"  -h, -?, --help          Print this message.\n"
+"\n"
+"  -IDIR                   Add -IDIR to compile commands.\n"
+"\n"
+"  -idirafter DIR          Add -idirafter DIR to compile commands.\n"
+"\n"
+"  -DDEF                   Add -DDEF to compile commands.\n"
+"\n"
+"  -lLIB                   Add library LIB to link command.\n"
+"\n"
+"  -LDIR                   Add -LDIR to link command.\n"
+"\n"
+"  -M, --depend            Generate dependency files (.d) for C and C++\n"
+"                          source files.\n"
+"\n"
+"  -RDIR                   Add -RDIR to link command.\n"
+"\n"
+"  -Wl,...                 Pass flags though the linker like -Wl,-rpath=...\n"
+"\n"
+"  -W...                   Pass flags though the compiler like -Wa,OPTION.\n"
+"\n"
+"  -c, --compile           Compile, but do not link.\n"
+"\n"
+"  -o FILE, --output FILE  Output file name.  Default extension is .oct\n"
+"                          (or .mex if --mex is specified) unless linking\n"
+"                          a stand-alone executable.\n"
+"\n"
+"  -g                      Enable debugging options for compilers.\n"
+"\n"
+"  -p VAR, --print VAR     Print configuration variable VAR.  Recognized\n"
+"                          variables are:\n"
+"\n"
+"			    ALL_CFLAGS                FLIBS\n"
+"			    ALL_CXXFLAGS              FPICFLAG\n"
+"			    ALL_FFLAGS                INCFLAGS\n"
+"			    ALL_LDFLAGS               LDFLAGS\n"
+"			    BLAS_LIBS                 LD_CXX\n"
+"			    CC                        LD_STATIC_FLAG\n"
+"			    CFLAGS                    LFLAGS\n"
+"			    CPICFLAG                  LIBCRUFT\n"
+"			    CPPFLAGS                  LIBOCTAVE\n"
+"			    CXX                       LIBOCTINTERP\n"
+"			    CXXFLAGS                  LIBREADLINE\n"
+"			    CXXPICFLAG                LIBS\n"
+"			    DEPEND_EXTRA_SED_PATTERN  OCTAVE_LIBS\n"
+"			    DEPEND_FLAGS              RDYNAMIC_FLAG\n"
+"			    DL_LD                     RLD_FLAG\n"
+"			    DL_LDFLAGS                SED\n"
+"			    F77                       XTRA_CFLAGS\n"
+"			    FFLAGS                    XTRA_CXXFLAGS\n"
+"			    FFTW_LIBS\n"
+"\n"
+"  --link-stand-alone      Link a stand-alone executable file.\n"
+"\n"
+"  --mex                   Assume we are creating a MEX file.  Set the\n"
+"                          default output extension to \".mex\".\n"
+"\n"
+"  -s, --strip             Strip output file.\n"
+"\n"
+"  -v, --verbose           Echo commands as they are executed.\n"
+"\n"
+"  FILE                    Compile or link FILE.  Recognized file types are:\n"
+"\n"
+"                            .c    C source\n"
+"                            .cc   C++ source\n"
+"                            .C    C++ source\n"
+"                            .cpp  C++ source\n"
+"                            .f    Fortran source (fixed form)\n"
+"                            .F    Fortran source (fixed form)\n"
+"                            .f90  Fortran source (free form)\n"
+"                            .F90  Fortran source (free form)\n"
+"                            .o    object file\n"
+"                            .a    library file\n"
+#ifdef _MSC_VER
+"                            .lib  library file\n"
+#endif
+"\n";
+
+static string
+basename (const string& s, bool strip_path = false)
+{
+  size_t pos = s.rfind ('.');
+  string retval;
+
+  if (pos == string::npos)
+    retval = s;
+  else
+    retval = s.substr (0, pos);
+  if (strip_path)
+    {
+      size_t p1 = retval.rfind ('/'), p2 = retval.rfind ('\\');
+      pos = (p1 != string::npos && p2 != string::npos
+	     ? max (p1, p2) : (p2 != string::npos ? p2 : p1));
+      if (pos != string::npos)
+	retval = retval.substr (0, pos);
+    }
+  return retval;
+}
+
+inline bool
+starts_with (const string& s, const string& prefix)
+{
+  return (s.length () >= prefix.length () && s.find (prefix) == 0);
+}
+
+inline bool
+ends_with (const string& s, const string& suffix)
+{
+  return (s.length () >= suffix.length ()
+	  && s.rfind (suffix) == s.length () - suffix.length ());
+}
+
+static int
+run_command (const string& cmd)
+{
+  if (debug)
+    cout << cmd << endl;
+  return system (cmd.c_str ());
+}
+
+int
+main (int argc, char **argv)
+{
+  initialize ();
+
+  string file, output_option;
+  list<string> cfiles, ccfiles, f77files;
+  int result = 0;
+
+  string objfiles = "";
+  string libfiles = "";
+  string octfile = "";
+  string outputfile = "";
+  string incflags = "";
+  string defs = "";
+  string ldflags = "";
+  string pass_on_options = "";
+  bool strip = false;
+  bool no_oct_file_strip_on_this_platform = %NO_OCT_FILE_STRIP%;
+  bool link = true;
+  bool link_stand_alone = false;
+  string output_ext = ".oct";
+  bool depend = false;
+  bool compile = true;
+
+  if (argc == 1)
+    {
+      cout << usage_msg << endl;
+      return 1;
+    }
+
+  if (argc == 2 && (!strcmp (argv[1], "-v") || !strcmp (argv[1], "--version")))
+    {
+      cout << version_msg << endl;
+      return 0;
+    }
+
+  for (int i = 1; i < argc; i++)
+    {
+      string arg = argv[i];
+      size_t len = arg.length ();
+
+      if (ends_with (arg, ".c"))
+	{
+	  file = arg;
+	  cfiles.push_back (file);
+	}
+      else if (ends_with (arg, ".cc") || ends_with (arg, ".C")
+	       || ends_with (arg, ".cpp"))
+	{
+	  file = arg;
+	  ccfiles.push_back (file);
+	}
+      else if (ends_with (arg, ".f") || ends_with (arg, ".F")
+	       || ends_with (arg, "f90") || ends_with (arg, ".F90"))
+	{
+	  file = arg;
+	  f77files.push_back (file);
+	}
+      else if (ends_with (arg, ".o") || ends_with (arg, ".obj"))
+	{
+	  file = arg;
+	  objfiles += (" " + quote_path (arg));
+	}
+      else if (ends_with (arg, ".lib") || ends_with (arg, ".a"))
+	{
+	  file = arg;
+	  libfiles += (" " + quote_path (arg));
+	}
+      else if (arg == "-d" || arg == "--debug" || arg == "-v"
+	       || arg == "--verbose")
+	{
+	  debug = true;
+	  if (vars["CC"] == "cc-msvc")
+	    vars["CC"] += " -d";
+	  if (vars["CXX"] == "cc-msvc")
+	    vars["CXX"] += " -d";
+	  if (vars["DL_LD"] == "cc-msvc")
+	    vars["DL_LD"] += " -d";
+	}
+      else if (arg == "-h" || arg == "-?" || arg == "--help")
+	{
+	  cout << usage_msg << endl;
+	  cout << help_msg << endl;
+	  return 0;
+	}
+      else if (starts_with (arg, "-I"))
+	{
+	  incflags += (" " + quote_path (arg));
+	}
+      else if (arg == "-idirafter")
+	{
+	  if (i < argc-1)
+	    {
+	      arg = argv[++i];
+	      incflags += (" -idirafter " + arg);
+	    }
+	  else
+	    cerr << "mkoctfile: include directory name missing" << endl;
+	}
+      else if (starts_with (arg, "-D"))
+	{
+	  defs += (" " + arg);
+	}
+      else if (starts_with (arg, "-Wl,") || starts_with (arg, "-l")
+	       || starts_with (arg, "-L") || starts_with (arg, "-R"))
+	{
+	  ldflags += (" " + arg);
+	}
+      else if (arg == "-M" || arg == "--depend")
+	{
+	  depend = true;
+	  compile = false;
+	}
+      else if (arg == "-o" || arg == "--output")
+	{
+	  if (i < argc-1)
+	    {
+	      arg = argv[++i];
+	      outputfile = arg;
+	    }
+	  else
+	    cerr << "mkoctfile: output file name missing" << endl;
+	}
+      else if (arg == "-p" || arg == "--print")
+	{
+	  if (i < argc-1)
+	    {
+	      arg = argv[++i];
+	      cout << vars[arg] << endl;
+	      return 0;
+	    }
+	  else
+	    cerr << "mkoctfile: --print requires argument" << endl;
+	}
+      else if (arg == "-s" || arg == "--strip")
+	{
+	  if (no_oct_file_strip_on_this_platform)
+	    cerr << "mkoctfile: stripping disabled on this platform" << endl;
+	  else
+	    strip = true;
+	}
+      else if (arg == "-c" || arg == "--compile")
+	{
+	  link = false;
+	}
+      else if (arg == "-g")
+	{
+	  vars["ALL_CFLAGS"] += " -g";
+	  vars["ALL_CXXFLAGS"] += " -g";
+	  vars["ALL_FFLAGS"] += " -g";
+	}
+      else if (arg == "--link-stand-alone")
+	{
+	  link_stand_alone = true;
+	}
+      else if (arg == "--mex")
+	{
+	  incflags += " -I.";
+#ifdef _MSC_VER
+	  ldflags += " -Wl,-export:mexFunction";
+#endif
+	  output_ext = ".mex";
+	}
+      else if (starts_with (arg, "-W"))
+	{
+	  pass_on_options += (" " + arg);
+	}
+      else
+	{
+	  cerr << "mkoctfile: unrecognized argument " << arg;
+	  return 1;
+	}
+
+      if (!file.empty () && octfile.empty ())
+	octfile = file;
+    }
+
+  if (link_stand_alone)
+    {
+      if (!outputfile.empty ())
+	output_option = "-o " + outputfile;
+    }
+  else
+    {
+      if (!outputfile.empty ())
+	octfile = outputfile;
+      else
+	octfile = basename (octfile, true) + output_ext;
+    }
+
+  list<string>::const_iterator it;
+
+  if (depend)
+    {
+      for (it = cfiles.begin (); it != cfiles.end (); ++it)
+	{
+	  string f = *it, dfile = basename (f) + ".d", line;
+
+	  unlink (dfile.c_str ());
+	  string cmd = vars["CC"] + " " + vars["DEPEND_FLAGS"] + " "
+	    + vars["CPPFLAGS"] + " " + vars["ALL_CFLAGS"] + " "
+	    + incflags  + " " + defs + " " + quote_path (f);
+
+	  FILE *fd = popen (cmd.c_str (), "r");
+	  ofstream fo (dfile.c_str ());
+	  int pos;
+	  while (!feof (fd))
+	    {
+	      line = get_line (fd);
+	      if ((pos = line.rfind (".o:")) != string::npos)
+		{
+		  int spos = line.rfind ('/', pos);
+		  string ofile = (spos == string::npos ? line.substr (0, pos+2) : line.substr (spos+1, pos-spos+1));
+		  fo << "pic/" << ofile << " " << ofile << " " << dfile << line.substr (pos) << endl;
+		}
+	      else
+		fo << line << endl;
+	    }
+	  pclose (fd);
+	  fo.close ();
+	}
+
+      for (it = ccfiles.begin (); it != ccfiles.end (); ++it)
+	{
+	  string f = *it, dfile = basename (f) + ".d", line;
+
+	  unlink (dfile.c_str ());
+	  string cmd = vars["CC"] + " " + vars["DEPEND_FLAGS"] + " "
+	    + vars["CPPFLAGS"] + " " + vars["ALL_CXXFLAGS"] + " "
+	    + incflags  + " " + defs + " " + quote_path (f);
+
+	  FILE *fd = popen (cmd.c_str (), "r");
+	  ofstream fo (dfile.c_str ());
+	  int pos;
+	  while (!feof (fd))
+	    {
+	      line = get_line (fd);
+	      if ((pos = line.rfind (".o:")) != string::npos)
+		{
+		  int spos = line.rfind ('/', pos);
+		  string ofile = (spos == string::npos ? line.substr (0, pos+2) : line.substr (spos+1, pos-spos+1));
+		  fo << "pic/" << ofile << " " << ofile << " " << dfile << line.substr (pos+2) << endl;
+		}
+	      else
+		fo << line << endl;
+	    }
+	  pclose (fd);
+	  fo.close ();
+	}
+
+      return 0;
+    }
+
+  for (it = f77files.begin (); it != f77files.end (); ++it)
+    {
+      string f = *it, b = basename (f);
+      if (!vars["F77"].empty ())
+	{
+	  string o;
+	  if (!outputfile.empty ())
+	    {
+	      if (link)
+		o = b + ".o";
+	      else
+		o = outputfile;
+	    }
+	  else
+	    o = b + ".o";
+	  objfiles += (" " + o);
+	  string cmd = vars["F77"] + " -c " + vars["FPICFLAG"] + " "
+	    + vars["ALL_FFLAGS"] + " " + incflags + " " + defs + " "
+	    + pass_on_options + " " + f + " -o " + o;
+	  result = run_command (cmd);
+	}
+      else
+	{
+	  cerr << "mkoctfile: no way to compile Fortran file " << f << endl;
+	  return 1;
+	}
+    }
+
+  for (it = cfiles.begin (); it != cfiles.end (); ++it)
+    {
+      string f = *it;
+      if (!vars["CC"].empty ())
+	{
+	  string b = basename (f), o;
+	  if (!outputfile.empty ())
+	    {
+	      if (link)
+		o = b + ".o";
+	      else
+		o = outputfile;
+	    }
+	  else
+	    o = b + ".o";
+	  objfiles += (" " + o);
+	  string cmd = vars["CC"] + " -c " + vars["CPPFLAGS"] + " "
+	    + vars["CPICFLAG"] + " " + vars["ALL_CFLAGS"] + " "
+	    + pass_on_options + " " + incflags + " " + defs + " "
+	    + quote_path (f) + " -o " + quote_path (o);
+	  result = run_command (cmd);
+	}
+      else
+	{
+	  cerr << "mkoctfile: no way to compile C file " << f << endl;
+	  return 1;
+	}
+    }
+	
+  for (it = ccfiles.begin (); it != ccfiles.end (); ++it)
+    {
+      string f = *it;
+      if (!vars["CXX"].empty ())
+	{
+	  string b = basename (f), o;
+	  if (!outputfile.empty ())
+	    {
+	      if (link)
+		o = b + ".o";
+	      else
+		o = outputfile;
+	    }
+	  else
+	    o = b + ".o";
+	  objfiles += (" " + o);
+	  string cmd = vars["CXX"] + " -c " + vars["CPPFLAGS"] + " "
+	    + vars["CXXPICFLAG"] + " " + vars["ALL_CXXFLAGS"] + " "
+	    + pass_on_options + " " + incflags + " " + defs + " "
+	    + quote_path (f) + " -o " + quote_path (o);
+	  result = run_command (cmd);
+	}
+      else
+	{
+	  cerr << "mkoctfile: no way to compile C++ file " << f << endl;
+	  return 1;
+	}
+    }
+
+  if (link && !objfiles.empty ())
+    {
+      if (link_stand_alone)
+	{
+	  if (!vars["LD_CXX"].empty ())
+	    {
+	      string cmd = vars["LD_CXX"] + " " + vars["CPPFLAGS"] + " "
+		+ vars["ALL_CXXFLAGS"] + " " + vars["RDYNAMIC_FLAG"]
+		+ " " + vars["ALL_LDFLAGS"] + " " +  pass_on_options
+		+ " " + output_option + " " + objfiles + " " + libfiles
+		+ " " + ldflags + " " + vars["LFLAGS"] + " "
+		+ vars["RLD_FLAG"] + " " + vars["OCTAVE_LIBS"] + " "
+		+ vars["BLAS_LIBS"] + " " + vars["FFTW_LIBS"] + " "
+		+ vars["LIBREADLINE"] + " " + vars["LIBS"] + " "
+		+ vars["FLIBS"];
+	      result = run_command (cmd);
+	    }
+	  else
+	    {
+	      cerr << "mkoctfile: no way to link stand-alone executable file"
+		   << endl;
+	      return 1;
+	    }
+	}
+      else
+	{
+	  string LINK_DEPS = vars["LFLAGS"] + " " + vars["OCTAVE_LIBS"]
+	    + " " + vars["LDFLAGS"] + " " + vars["BLAS_LIBS"] + " "
+	    + vars["FFTW_LIBS"] + " " + vars["LIBS"] + " " + vars["FLIBS"];
+	  string cmd = vars["DL_LD"] + " " + vars["DL_LDFLAGS"] + " "
+	    + pass_on_options + " -o " + octfile + " " + objfiles + " "
+	    + libfiles + " " + ldflags + " " + LINK_DEPS;
+	  result = run_command (cmd);
+	}
+
+      if (strip)
+	{
+	  string cmd = "strip " + octfile;
+	  result = run_command (cmd);
+	}
+    }
+
+  return result;
+}
diff --git a/mkoctfile.in b/mkoctfile.in
new file mode 100644
index 0000000..f6d46ba
--- /dev/null
+++ b/mkoctfile.in
@@ -0,0 +1,534 @@
+#! /bin/sh
+##
+## mkoctfile -- create a .oct file suitable for dynamic linking by
+## Octave.
+##
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005,
+##               2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+# Exit immediately on any error.
+
+set -e
+
+: ${SED=%OCTAVE_CONF_SED%}
+
+OCTAVE_VERSION=%OCTAVE_CONF_VERSION%
+OCTAVE_PREFIX=%OCTAVE_CONF_PREFIX%
+
+DEFAULT_BINDIR=%OCTAVE_BINDIR%
+DEFAULT_INCLUDEDIR=%OCTAVE_CONF_INCLUDEDIR%
+DEFAULT_LIBDIR=%OCTAVE_CONF_LIBDIR%
+DEFAULT_OCTINCLUDEDIR=%OCTAVE_CONF_OCTINCLUDEDIR%
+DEFAULT_OCTLIBDIR=%OCTAVE_CONF_OCTLIBDIR%
+
+if [ -n "$OCTAVE_HOME" ]; then
+  DEFAULT_BINDIR="`echo $DEFAULT_BINDIR | $SED "s,^$OCTAVE_PREFIX,$OCTAVE_HOME,"`"
+  DEFAULT_INCLUDEDIR="`echo $DEFAULT_INCLUDEDIR | $SED "s,^$OCTAVE_PREFIX,$OCTAVE_HOME,"`"
+  DEFAULT_LIBDIR="`echo $DEFAULT_LIBDIR | $SED "s,^$OCTAVE_PREFIX,$OCTAVE_HOME,"`"
+  DEFAULT_OCTINCLUDEDIR="`echo $DEFAULT_OCTINCLUDEDIR | $SED "s,^$OCTAVE_PREFIX,$OCTAVE_HOME,"`"
+  DEFAULT_OCTLIBDIR="`echo $DEFAULT_OCTLIBDIR | $SED "s,^$OCTAVE_PREFIX,$OCTAVE_HOME,"`"
+fi
+
+: ${BINDIR=$DEFAULT_BINDIR}
+: ${INCLUDEDIR=$DEFAULT_INCLUDEDIR}
+: ${LIBDIR=$DEFAULT_LIBDIR}
+: ${OCTINCLUDEDIR=$DEFAULT_OCTINCLUDEDIR}
+: ${OCTLIBDIR=$DEFAULT_OCTLIBDIR}
+
+DEFAULT_INCFLAGS="-I$OCTINCLUDEDIR -I$OCTINCLUDEDIR/octave"
+if [ "$INCLUDEDIR" != /usr/include ]; then
+  DEFAULT_INCFLAGS="$DEFAULT_INCFLAGS -I$INCLUDEDIR"
+fi
+
+DEFAULT_LFLAGS="-L$OCTLIBDIR"
+if [ "$LIBDIR" != /usr/lib ]; then
+  DEFAULT_LFLAGS="$DEFAULT_LFLAGS -L$LIBDIR"
+fi
+
+# Default values for these variables are filled in when Octave is
+# compiled.
+
+: ${EXEEXT=%OCTAVE_CONF_EXEEXT%}
+
+: ${CPPFLAGS=%OCTAVE_CONF_CPPFLAGS%}
+: ${INCFLAGS=$DEFAULT_INCFLAGS}
+: ${F77=%OCTAVE_CONF_F77%}
+: ${FFLAGS=%OCTAVE_CONF_FFLAGS%}
+: ${FPICFLAG=%OCTAVE_CONF_FPICFLAG%}
+: ${CC=%OCTAVE_CONF_CC%}
+: ${CFLAGS=%OCTAVE_CONF_CFLAGS%}
+: ${CPICFLAG=%OCTAVE_CONF_CPICFLAG%}
+: ${CXX=%OCTAVE_CONF_CXX%}
+: ${CXXFLAGS=%OCTAVE_CONF_CXXFLAGS%}
+: ${CXXPICFLAG=%OCTAVE_CONF_CXXPICFLAG%}
+: ${XTRA_CFLAGS=%OCTAVE_CONF_XTRA_CFLAGS%}
+: ${XTRA_CXXFLAGS=%OCTAVE_CONF_XTRA_CXXFLAGS%}
+
+: ${DEPEND_FLAGS=%OCTAVE_CONF_DEPEND_FLAGS%}
+: ${DEPEND_EXTRA_SED_PATTERN=%OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%}
+
+: ${DL_LD=%OCTAVE_CONF_DL_LD%}
+: ${DL_LDFLAGS=%OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%}
+
+: ${RLD_FLAG=%OCTAVE_CONF_RLD_FLAG%}
+: ${RDYNAMIC_FLAG=%OCTAVE_CONF_RDYNAMIC_FLAG%}
+: ${LIBOCTAVE=-loctave}
+: ${LIBOCTINTERP=-loctinterp}
+: ${LIBREADLINE=-lreadline}
+: ${LIBCRUFT=-lcruft}
+: ${BLAS_LIBS=%OCTAVE_CONF_BLAS_LIBS%}
+: ${FFTW_LIBS=%OCTAVE_CONF_FFTW_LIBS%}
+: ${LIBS=%OCTAVE_CONF_LIBS%}
+: ${FLIBS=%OCTAVE_CONF_FLIBS%}
+: ${LD_CXX=%OCTAVE_CONF_LD_CXX%}
+: ${LDFLAGS=%OCTAVE_CONF_LDFLAGS%}
+: ${LD_STATIC_FLAG=%OCTAVE_CONF_LD_STATIC_FLAG%}
+: ${LFLAGS=$DEFAULT_LFLAGS}
+
+: ${ALL_FFLAGS="$FFLAGS"}
+
+: ${ALL_CFLAGS="$INCFLAGS $XTRA_CFLAGS $CFLAGS"}
+
+: ${ALL_CXXFLAGS="$INCFLAGS $XTRA_CXXFLAGS $CXXFLAGS"}
+
+: ${ALL_LDFLAGS="$LD_STATIC_FLAG $CPICFLAG $LDFLAGS"}
+
+: ${OCTAVE_LIBS="$LIBOCTINTERP $LIBOCTAVE $SPECIAL_MATH_LIB $LIBCRUFT"}
+
+# Local variables.
+
+usage_msg="usage: mkoctfile [options] file ..."
+
+version_msg="mkoctfile, version $OCTAVE_VERSION"
+
+cfiles=
+ccfiles=
+f77files=
+objfiles=
+libfiles=
+octfiles=
+octfile=
+outputfile=
+incflags=
+defs=
+ldflags=
+dbg=:
+pass_on_options=
+strip=false
+no_oct_file_strip_on_this_platform=%NO_OCT_FILE_STRIP%
+link=true
+link_stand_alone=false
+output_ext=".oct"
+depend=false
+compile=true
+
+if [ $# -eq 0 ]; then
+  echo $usage_msg 1>&2
+  exit 1
+fi
+
+if [ $# -eq 1 ]; then
+  case "$1" in
+    -v | --version)
+      echo $version_msg 1>&2
+      exit 0
+    ;;
+  esac
+fi
+
+while [ $# -gt 0 ]; do
+  file=
+  case "$1" in
+    *.c)
+      file=$1
+      cfiles="$cfiles $file"
+    ;;
+    *.cc | *.C | *.cpp)
+      file=$1
+      ccfiles="$ccfiles $file"
+    ;;
+    *.f | *.F | *.f90 | *.F90)
+      file=$1
+      f77files="$f77files $file"
+    ;;
+    *.o)
+      file=$1
+      objfiles="$objfiles $file"
+    ;;
+    *.a)
+      file=$1
+      libfiles="$libfiles $file"
+    ;;
+    -d | --debug | -v | --verbose)
+      dbg=echo
+    ;;
+    -h | -\? | --help)
+      echo $usage_msg 1>&2
+      cat << EOF
+
+Options:
+
+  -h, -?, --help          Print this message.
+
+  -IDIR                   Add -IDIR to compile commands.
+
+  -idirafter DIR          Add -idirafter DIR to compile commands.
+
+  -DDEF                   Add -DDEF to compile commands.
+
+  -lLIB                   Add library LIB to link command.
+
+  -LDIR                   Add -LDIR to link command.
+
+  -M, --depend            Generate dependency files (.d) for C and C++
+                          source files.
+
+  -RDIR                   Add -RDIR to link command.
+
+  -Wl,...                 Pass flags though the linker like -Wl,-rpath=...
+
+  -W...                   Pass flags though the compiler like -Wa,OPTION.
+
+  -c, --compile           Compile, but do not link.
+
+  -o FILE, --output FILE  Output file name.  Default extension is .oct
+                          (or .mex if --mex is specified) unless linking
+                          a stand-alone executable.
+
+  -g                      Enable debugging options for compilers.
+
+  -p VAR, --print VAR     Print configuration variable VAR.  Recognized
+                          variables are:
+
+			    ALL_CFLAGS                FLIBS
+			    ALL_CXXFLAGS              FPICFLAG
+			    ALL_FFLAGS                INCFLAGS
+			    ALL_LDFLAGS               LDFLAGS
+			    BLAS_LIBS                 LD_CXX
+			    CC                        LD_STATIC_FLAG
+			    CFLAGS                    LFLAGS
+			    CPICFLAG                  LIBCRUFT
+			    CPPFLAGS                  LIBOCTAVE
+			    CXX                       LIBOCTINTERP
+			    CXXFLAGS                  LIBREADLINE
+			    CXXPICFLAG                LIBS
+			    DEPEND_EXTRA_SED_PATTERN  OCTAVE_LIBS
+			    DEPEND_FLAGS              RDYNAMIC_FLAG
+			    DL_LD                     RLD_FLAG
+			    DL_LDFLAGS                SED
+			    F77                       XTRA_CFLAGS
+			    FFLAGS                    XTRA_CXXFLAGS
+			    FFTW_LIBS
+
+  --link-stand-alone      Link a stand-alone executable file.
+
+  --mex                   Assume we are creating a MEX file.  Set the
+                          default output extension to ".mex".
+
+  -s, --strip             Strip output file.
+
+  -v, --verbose           Echo commands as they are executed.
+
+  FILE                    Compile or link FILE.  Recognized file types are:
+
+                            .c    C source
+                            .cc   C++ source
+                            .C    C++ source
+                            .cpp  C++ source
+                            .f    Fortran source (fixed form)
+                            .F    Fortran source (fixed form)
+                            .f90  Fortran source (free form)
+                            .F90  Fortran source (free form)
+                            .o    object file
+                            .a    library file
+
+EOF
+      exit 0
+    ;;
+    -I*)
+      incflags="$incflags $1"
+    ;;
+    -idirafter)
+      shift
+      if [ $# -gt 0 ]; then
+        incflags="$incflags -idirafter $1"
+      else
+        echo "mkoctfile: include directory name missing" 1>&2
+      fi
+    ;;
+    -D*)
+      defs="$defs $1"
+    ;;
+    -[lLR]* | -Wl,*)
+      ldflags="$ldflags $1"
+    ;;
+    -M | --depend)
+      depend=true
+      compile=false
+    ;;
+    -o | --output)
+      shift
+      if [ $# -gt 0 ]; then
+        outputfile="$1"
+      else
+        echo "mkoctfile: output file name missing" 1>&2
+      fi
+    ;;
+    -p | --print)
+      shift
+      if [ $# -gt 0 ]; then
+        eval echo \${$1}
+        exit 0
+      else
+        echo "mkoctfile: --print requires argument" 1>&2
+        exit 1
+      fi
+    ;;
+    -s | --strip)
+      if $no_oct_file_strip_on_this_platform; then
+        echo "mkoctfile: stripping disabled on this platform" 1>&2
+      else
+        strip=true
+      fi
+    ;;
+    -c | --compile)
+      link=false
+    ;;
+    -g)
+      ALL_CFLAGS="$ALL_CFLAGS -g"
+      ALL_CXXFLAGS="$ALL_CXXFLAGS -g"
+      ALL_FFLAGS="$ALL_FFLAGS -g"
+    ;;
+    --link-stand-alone)
+      link_stand_alone=true
+    ;;
+    --mex)
+      incflags="$incflags -I."
+      output_ext=".mex"
+    ;;
+    -W*)
+      pass_on_options="$pass_on_options $1"
+    ;;
+    *)
+      echo "mkoctfile: unrecognized argument $1" 1>&2
+      exit 1
+    ;;
+  esac
+  if [ -n "$file" ]; then
+    if [ -z "$octfile" ]; then
+      octfile="$file"
+    fi
+  fi
+  shift
+done
+
+if $link_stand_alone; then
+  if [ -n "$outputfile" ]; then
+    output_option="-o $outputfile"
+  fi
+else
+  if [ -n "$outputfile" ]; then
+    octfile="$outputfile"
+  else
+    octfile=`basename $octfile`
+    octfile=`echo $octfile | $SED 's,\.[^.]*$,,'`$output_ext
+  fi
+fi
+
+# Generate dependency files for C and C++ files.
+
+if $depend; then
+  if [ -n "$cfiles" ]; then
+    for f in $cfiles; do
+      b=`echo $f | $SED 's,\.c$,,'`
+      d=$b.d
+      cmd="rm -f $d"
+      $dbg $cmd
+      eval $cmd
+      cmd="$CC $DEPEND_FLAGS $CPPFLAGS $ALL_CFLAGS $incflags $def $f | $SED $DEPEND_EXTRA_SED_PATTERN -e 's,^[^:]*/\(.*\.o\):,\1:,' -e 's,$b\.o,pic/& & $d,g' > $d-t && mv $d-t $d"
+      $dbg $cmd
+      eval $cmd
+    done
+  fi
+
+  if [ -n "$ccfiles" ]; then
+    for f in $ccfiles; do
+      case $f in
+        *.cc)
+          b=`echo $f | $SED 's,\.cc$,,'`
+        ;;
+        *.C)
+          b=`echo $f | $SED 's,\.C$,,'`
+        ;;
+        *.cpp)
+          b=`echo $f | $SED 's,\.cpp$,,'`
+        ;;
+      esac
+      d=$b.d
+      cmd="rm -f $d"
+      $dbg $cmd
+      eval $cmd
+      cmd="$CXX $DEPEND_FLAGS $CPPFLAGS $ALL_CXXFLAGS $incflags $defs $f | $SED $DEPEND_EXTRA_SED_PATTERN -e 's,^[^:]*/\(.*\.o\):,\1:,' -e 's,$b\.o,pic/& & $d,g' > $d-t && mv $d-t $d"
+      $dbg $cmd
+      eval $cmd
+    done
+  fi
+  # If generating dependencies, that's all we do.
+  exit 0
+fi
+
+# Compile Fortran, C, and C++ files.  Add the name of each object file
+# that is produced to the overall list of object files.
+
+if [ -n "$f77files" ]; then
+  for f in $f77files; do
+    case $f in
+      *.f)
+        b=`echo $f | $SED 's,\.f$,,'`
+      ;;
+      *.F)
+        b=`echo $f | $SED 's,\.F$,,'`
+      ;;
+      *.f90)
+        b=`echo $f | $SED 's,\.f90$,,'`
+      ;;
+      *.F90)
+        b=`echo $f | $SED 's,\.F90$,,'`
+      ;;
+    esac
+    if [ -n "$F77" ]; then
+      if [ -n "$outputfile" ]; then
+	if $link; then
+	  o=$b.o
+	else
+	  o=$outputfile
+	fi
+      else
+        o=$b.o
+      fi
+      objfiles="$objfiles $o"
+      cmd="$F77 -c $FPICFLAG $ALL_FFLAGS $incflags $defs $pass_on_options $f -o $o"
+      $dbg $cmd
+      eval $cmd
+    else
+      echo "mkoctfile: no way to compile Fortran file $f" 1>&2
+    fi
+  done
+fi
+
+if [ -n "$cfiles" ]; then
+  for f in $cfiles; do
+    if [ -n  "$CC" ]; then
+      b=`echo $f | $SED 's,\.c$,,'`
+      if [ -n "$outputfile" ]; then
+	if $link; then
+	  o=$b.o
+	else
+	  o=$outputfile
+	fi
+      else
+	o=$b.o
+      fi
+      objfiles="$objfiles $o"
+      cmd="$CC -c $CPPFLAGS $CPICFLAG $ALL_CFLAGS $pass_on_options $incflags $defs $f -o $o"
+      $dbg $cmd
+      eval $cmd
+    else
+      echo "mkoctfile: no way to compile C++ file $f" 1>&2
+    fi
+  done
+fi
+
+if [ -n "$ccfiles" ]; then
+  for f in $ccfiles; do
+    if [ -n "$CXX" ]; then
+      case $f in
+	*.cc)
+	  b=`echo $f | $SED 's,\.cc$,,'`
+	;;
+	*.C)
+	  b=`echo $f | $SED 's,\.C$,,'`
+	;;
+	*.cpp)
+	  b=`echo $f | $SED 's,\.cpp$,,'`
+	;;
+      esac
+      if [ -n "$outputfile" ]; then
+	if $link; then
+	  o=$b.o
+	else
+	  o=$outputfile
+	fi
+      else
+	o=$b.o
+      fi
+      objfiles="$objfiles $o"
+      cmd="$CXX -c $CPPFLAGS $CXXPICFLAG $ALL_CXXFLAGS $pass_on_options $incflags $defs $f -o $o"
+      $dbg $cmd
+      eval $cmd
+    else
+      echo "mkoctfile: no way to compile C++ file $f" 1>&2
+    fi
+  done
+fi
+
+## Uncomment the following group of lines if you get `Text file busy'
+## errors from ld.  This may happen if the .oct file is currently
+## running while you are trying to recompile it.  We try moving first,
+## since on some systems (HP-UX, maybe others) it is possible to
+## rename running programs but not remove them.
+
+## if [ -f "$octfile" ]; then
+##   cmd="mv $octfile $octfile.bak"
+##   $dbg $cmd
+##   eval $cmd
+##   cmd="rm -f $octfile.bak"
+##   $dbg $cmd
+##   eval $cmd
+## fi
+
+# Link all the object files.
+
+if $link && [ -n "$objfiles" ]; then
+  if $link_stand_alone; then
+    if [ -n "$LD_CXX" ]; then
+      cmd="$LD_CXX $CPPFLAGS $ALL_CXXFLAGS $RDYNAMIC_FLAG $ALL_LDFLAGS $pass_on_options $output_option $objfiles $libfiles $ldflags $LFLAGS $RLD_FLAG $OCTAVE_LIBS $BLAS_LIBS $FFTW_LIBS $LIBREADLINE $LIBS $FLIBS"
+      $dbg $cmd
+      eval $cmd
+    else
+      echo "mkoctfile: no way to link stand-alone executable file" 1>&2
+      exit 1
+    fi
+  else
+    LINK_DEPS="$LFLAGS $OCTAVE_LIBS $LDFLAGS $BLAS_LIBS $FFTW_LIBS $LIBS $FLIBS"
+    cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $libfiles $ldflags $LINK_DEPS"
+    $dbg $cmd
+    eval $cmd
+  fi
+
+# Maybe strip it.
+
+  if $strip; then
+    cmd="strip $octfile"
+    $dbg $cmd
+    eval $cmd
+  fi
+fi
+
+exit 0
diff --git a/move-if-change b/move-if-change
new file mode 100755
index 0000000..008440c
--- /dev/null
+++ b/move-if-change
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Like mv $1 $2, but if the files are the same, just delete $1.
+# Status is 0 if $2 is changed, 1 otherwise.
+
+if test -r $2; then
+  if cmp $1 $2 > /dev/null; then
+    echo $2 is unchanged
+    rm -f $1
+  else
+    mv -f $1 $2
+  fi
+else
+  mv -f $1 $2
+fi
diff --git a/octMakefile.in b/octMakefile.in
new file mode 100644
index 0000000..19a6574
--- /dev/null
+++ b/octMakefile.in
@@ -0,0 +1,310 @@
+# Makefile for octave
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+#               2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = .
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+abs_top_srcdir = @abs_top_srcdir@
+VPATH = @srcdir@
+
+SCRIPTS_EXE_SUFFIX = @SCRIPTS_EXE_SUFFIX@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_DATA = @INSTALL_DATA@
+
+CONF_DISTFILES = Makefile octMakefile.in Makeconf.in \
+	configure configure.in config.guess config.sub aclocal.m4 \
+	acx_blas.m4 acx_lapack.m4 acx_blas_f77_func.m4 acx_pthread.m4 \
+	config.h.in install-sh autogen.sh
+
+BUILT_DISTFILES = BUGS INSTALL.OCTAVE
+
+DISTFILES = $(CONF_DISTFILES) \
+	COPYING INSTALL NEWS \
+	NEWS.[0-9] PROJECTS README README.Linux README.Windows \
+	README.Cygwin README.MSVC README.kpathsea ROADMAP SENDING-PATCHES \
+	move-if-change octave-sh octave-bug.in octave-bug.cc.in \
+	octave-config.in octave-config.cc.in missing mk-opts.pl mkinstalldirs \
+	mkoctfile.in mkoctfile.cc.in run-octave.in ChangeLog ChangeLog.[0-9]
+
+# Subdirectories in which to run `make all'.
+SUBDIRS = libcruft liboctave src scripts doc examples
+
+# Subdirectories in which to run `make all'.
+INSTALL_SUBDIRS = libcruft liboctave src scripts doc examples
+
+# Subdirectories in which to run `make conf-dist'.
+CONF_DISTSUBDIRS = src
+
+# Subdirectories in which to run `make dist'.
+DISTSUBDIRS = $(sort $(SUBDIRS) test emacs)
+
+# Subdirectories in which to run clean targets.
+CLEANSUBDIRS = $(DISTSUBDIRS)
+
+DIRS_TO_MAKE = $(bindir) $(datadir) $(libdir) $(octincludedir)/octave \
+  $(fcnfiledir) $(localfcnfiledir) $(localapifcnfiledir) \
+  $(localverfcnfiledir) $(octetcdir) $(octfiledir) $(localoctfiledir) \
+  $(localapioctfiledir) $(localveroctfiledir) $(imagedir) $(archlibdir) \
+  $(localarchlibdir) $(localapiarchlibdir) $(localverarchlibdir)
+
+SHELL_SCRIPTS = octave-bug$(SCRIPTS_EXE_SUFFIX) octave-config$(SCRIPTS_EXE_SUFFIX) \
+		mkoctfile$(SCRIPTS_EXE_SUFFIX)  run-octave
+
+CONFIG_FILES = @ac_config_files@
+
+M4_FILES = $(wildcard *.m4)
+
+all: $(SHELL_SCRIPTS) $(filter-out libcruft liboctave, $(SUBDIRS)) dist-info-files
+	@echo ""
+	@echo "Octave successfully built.  Now choose from the following:"
+	@echo ""
+	@echo "   ./run-octave    - to run in place to test before installing"
+	@echo "   make check      - to run the tests"
+	@echo "   make install    - to install (PREFIX=$(prefix))"
+	@echo ""
+.PHONY: all
+
+configfiles: $(CONFIG_FILES)
+	for dir in $(CONFIG_SUBDIRS); do \
+	  $(MAKE) -C $$dir configfiles; \
+	done
+.PHONY: configfiles
+
+$(CONFIG_FILES): %: %.in config.status
+	./config.status $@
+
+config.status: configure
+	./config.status --recheck
+
+configure: configure.in $(M4_FILES)
+	(cd $(top_srcdir); autoconf --force)
+	(cd $(top_srcdir); autoheader --force)
+
+src: liboctave
+
+liboctave: libcruft
+
+$(SUBDIRS):
+	$(MAKE) -C $@ all
+.PHONY: $(SUBDIRS)
+
+octave-bug: octave-bug.in Makeconf octMakefile $(top_srcdir)/src/version.h
+	@$(do-subst-config-vals)
+	chmod a+rx $@
+
+octave-bug.cc: octave-bug.cc.in Makeconf octMakefile
+	@$(do-subst-config-vals)
+
+ifneq ($(EXEEXT),)
+octave-bug$(EXEEXT): octave-bug.o
+	$(LD_CXX) $(CPPFLAGS) $(ALL_CXXFLAGS) $(RDYNAMIC_FLAG) \
+	    $(ALL_LDFLAGS) -o $@ octave-bug.o
+endif
+
+octave-config: octave-config.in Makeconf octMakefile $(top_srcdir)/src/version.h
+	@$(do-subst-default-vals)
+	chmod a+rx $@
+
+octave-config.cc: octave-config.cc.in Makeconf octMakefile
+	@$(do-subst-default-vals)
+
+ifneq ($(EXEEXT),)
+octave-config$(EXEEXT): octave-config.o
+	$(LD_CXX) $(CPPFLAGS) $(ALL_CXXFLAGS) $(RDYNAMIC_FLAG) \
+	    $(ALL_LDFLAGS) -o $@ octave-config.o
+endif
+
+mkoctfile: mkoctfile.in Makeconf octMakefile $(top_srcdir)/src/version.h
+	@$(do-subst-config-vals)
+	chmod a+rx $@
+
+mkoctfile.cc: mkoctfile.cc.in Makeconf octMakefile
+	@$(do-subst-config-vals)
+
+ifneq ($(EXEEXT),)
+mkoctfile$(EXEEXT): mkoctfile.o
+	$(LD_CXX) $(CPPFLAGS) $(ALL_CXXFLAGS) $(RDYNAMIC_FLAG) \
+	    $(ALL_LDFLAGS) -o $@ mkoctfile.o
+endif
+
+run-octave: run-octave.in Makeconf octMakefile
+	@$(do-subst-script-vals)
+	chmod a+rx "$@"
+
+check:
+	$(MAKE) -C test $@
+.PHONY: check
+
+octave.info:
+	$(MAKE) -C doc/interpreter octave.info
+.PHONY: octave.info
+
+BUGS INSTALL.OCTAVE:
+	$(MAKE) -C doc ../$@
+.PHONY: BUGS INSTALL.OCTAVE
+
+install install-strip ::
+	$(top_srcdir)/mkinstalldirs $(addprefix $(DESTDIR), $(DIRS_TO_MAKE))
+	rm -f $(DESTDIR)$(bindir)/octave-bug$(SCRIPTS_EXE_SUFFIX)
+	$(INSTALL_SCRIPT) octave-bug$(SCRIPTS_EXE_SUFFIX) \
+	    $(DESTDIR)$(bindir)/octave-bug-$(version)$(SCRIPTS_EXE_SUFFIX)
+	(cd $(DESTDIR)$(bindir); $(LN_S) octave-bug-$(version)$(SCRIPTS_EXE_SUFFIX) \
+	    $(DESTDIR)$(bindir)/octave-bug$(SCRIPTS_EXE_SUFFIX))
+	rm -f $(DESTDIR)$(bindir)/octave-config$(SCRIPTS_EXE_SUFFIX)
+	$(INSTALL_SCRIPT) \
+	  octave-config$(SCRIPTS_EXE_SUFFIX) $(DESTDIR)$(bindir)/octave-config-$(version)$(SCRIPTS_EXE_SUFFIX)
+	(cd $(DESTDIR)$(bindir); $(LN_S) octave-config-$(version)$(SCRIPTS_EXE_SUFFIX) \
+	    $(DESTDIR)$(bindir)/octave-config$(SCRIPTS_EXE_SUFFIX))
+	rm -f $(DESTDIR)$(bindir)/mkoctfile$(SCRIPTS_EXE_SUFFIX)
+	$(INSTALL_SCRIPT) mkoctfile$(SCRIPTS_EXE_SUFFIX) \
+	    $(DESTDIR)$(bindir)/mkoctfile-$(version)$(SCRIPTS_EXE_SUFFIX)
+	(cd $(DESTDIR)$(bindir); $(LN_S) mkoctfile-$(version)$(SCRIPTS_EXE_SUFFIX) \
+	    $(DESTDIR)$(bindir)/mkoctfile$(SCRIPTS_EXE_SUFFIX))
+	$(INSTALL_DATA) config.h $(DESTDIR)$(octincludedir)/octave/config.h
+	$(INSTALL_DATA) $(srcdir)/NEWS $(DESTDIR)$(octetcdir)/NEWS
+
+uninstall::
+	rm -f $(DESTDIR)$(bindir)/octave-bug$(SCRIPTS_EXE_SUFFIX)
+	rm -f $(DESTDIR)$(bindir)/octave-bug-$(version)$(SCRIPTS_EXE_SUFFIX)
+	rm -f $(DESTDIR)$(bindir)/octave-config$(SCRIPTS_EXE_SUFFIX)
+	rm -f $(DESTDIR)$(bindir)/octave-config-$(version)$(SCRIPTS_EXE_SUFFIX)
+	rm -f $(DESTDIR)$(bindir)/mkoctfile$(SCRIPTS_EXE_SUFFIX)
+	rm -f $(DESTDIR)$(bindir)/mkoctfile-$(version)$(SCRIPTS_EXE_SUFFIX)
+	rm -f $(DESTDIR)$(octincludedir)/octave/config.h
+	rm -f $(DESTDIR)$(octetcdir)/NEWS
+
+maintainer-clean::
+	@echo ""
+	@echo "************************************************************"
+	@echo "*                                                          *"
+	@echo "* This command is intended for maintainers to use; it      *"
+	@echo "* deletes files that may require special tools to rebuild. *"
+	@echo "*                                                          *"
+	@echo "************************************************************"
+	@echo ""
+
+install install-strip uninstall tags TAGS::
+	$(foreach d, $(INSTALL_SUBDIRS), $(do-subdir-for-command))
+.PHONY: install install-strip uninstall tags
+
+clean mostlyclean distclean maintainer-clean::
+	$(foreach d, $(CLEANSUBDIRS), $(do-subdir-for-command))
+.PHONY: clean mostlyclean distclean maintainer-clean
+
+maintainer-clean distclean::
+	rm -f octMakefile Makeconf
+	rm -f config.cache config.h config.log config.status
+	rm -rf autom4te.cache
+	rm -f $(SHELL_SCRIPTS)
+	rm -f mkoctfile.cc octave-config.cc octave-bug.cc
+	rm -f unistd.h
+
+maintainer-clean::
+	rm -f configure config.h.in BUGS INSTALL.OCTAVE
+
+maintainer-clean distclean clean::
+	rm -f mkoctfile$(EXEEXT) octave-config$(EXEEXT) octave-bug$(EXEEXT)
+	rm -f mkoctfile.o octave-config.o octave-bug.o
+
+# Rules for making a source distribution.
+
+dist-info-files: INSTALL.OCTAVE BUGS
+.PHONY: dist-info-files
+
+# The dist target depends on all because we use Octave to build some
+# figures for the manual.  It's best to create those figures with the
+# version of Octave that we are distributing (it may even be required).
+
+dist: all
+	echo octave-$(version) > .fname
+	rm -rf `cat .fname`
+	mkdir `cat .fname`
+	ln $(addprefix $(srcdir)/, $(DISTFILES)) `cat .fname`
+	ln $(BUILT_DISTFILES) `cat .fname`
+	for dir in $(DISTSUBDIRS); do \
+	  mkdir `cat .fname`/$$dir; \
+	  $(MAKE) -C $$dir dist; \
+	done
+	tar chf `cat .fname`.tar `cat .fname`
+	rm -rf `cat .fname`
+	tar xf `cat .fname`.tar
+	find `cat .fname` \( \( -name RCS -a -type d \) \
+	  -o \( -name CVS -a -type d \) -o \( -name OLD -a -type d \) \
+	  -o \( -name autom4te.cache -a -type d \) \
+	  -o -name "=*" -o -name '*~' -o -name '#*#' -o -name config.log \
+	  -o -name config.status -o -name config.cache -o -name stamp-h \
+	  -o -name klibtool.config -o -name stamp-auto \
+	  -o -name c-auto.h \) -print | xargs rm -rf
+	rm -f `cat .fname`/test/octave.test/*.m
+	chmod -R a+rwX `cat .fname`
+	tar cf `cat .fname`.tar `cat .fname`
+	rm -rf `cat .fname`
+	gzip -9 --stdout `cat .fname`.tar > `cat .fname`.tar.gz
+	bzip2 -9 --stdout `cat .fname`.tar > `cat .fname`.tar.bz2
+	date -u > md5sum
+	md5sum `cat .fname`.tar.gz `cat .fname`.tar.bz2 >> md5sum
+	touch `cat .fname`.tar.gz `cat .fname`.tar.bz2 md5sum
+	rm -f .fname
+	@echo "*******************"
+	@echo "Tag the CVS archive"
+	@echo "*******************"
+.PHONY: dist
+
+# Rules for making a snapshot.
+
+snapshot-version:
+	@echo "creating src/version.h"
+	@gawk '/#define OCTAVE_VERSION[ \t]*/ { \
+	  datestring = strftime("%y%m%d", systime()); \
+	  printf("#define OCTAVE_VERSION \"ss-%s\"\n", datestring); \
+	  next; \
+	} { print $$0 }' src/version.h > src/version.h.new
+	@$(top_srcdir)/move-if-change src/version.h.new src/version.h
+.PHONY: snapshot-version
+
+snapshot: snapshot-version
+	$(MAKE) dist
+.PHONY: snapshot
+
+# Rules for making a dist of just the stuff needed to run configure.
+
+conf-dist:
+	echo config-dist-$(version) > .fname
+	rm -rf `cat .fname`
+	mkdir `cat .fname`
+	ln $(CONF_DISTFILES) `cat .fname`
+	for dir in $(CONF_DISTSUBDIRS); do \
+	  mkdir `cat .fname`/$$dir; \
+	  $(MAKE) -C $$dir conf-dist; \
+	done
+	tar chf `cat .fname`.tar `cat .fname`
+	rm -rf `cat .fname`
+	gzip --best `cat .fname`.tar
+	rm -f .fname
+.PHONY: conf-dist
+
+.NOTPARALLEL:
diff --git a/octave-bug.cc.in b/octave-bug.cc.in
new file mode 100644
index 0000000..f297e38
--- /dev/null
+++ b/octave-bug.cc.in
@@ -0,0 +1,323 @@
+/*
+
+Copyright (C) 2008, 2009 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <string>
+#include <map>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <windows.h>
+#include <mapi.h>
+#include <unistd.h>
+
+using namespace std;
+
+static map<string,string> vars;
+
+static void
+usage (void)
+{
+  cerr << "usage: octave-bug [-s subject]" << endl;
+  exit (-1);
+}
+
+static void
+error (const string& msg)
+{
+  cerr << "error: " << msg << endl;
+  exit (-1);
+}
+
+static void
+warning (const string& msg)
+{
+  cerr << "warning: " << msg << endl;
+}
+
+static string
+get_env_variable (const char *name)
+{
+  char *value = ::getenv (name);
+  if (value)
+    return string (value);
+  else
+    return string ("");
+}
+
+inline bool
+starts_with (const string& s, const string& prefix)
+{
+  return (s.length () >= prefix.length () && s.find (prefix) == 0);
+}
+
+int
+main (int argc, char **argv)
+{
+  int arg_idx = 1;
+
+  vars["config_optvars"] = %OCTAVE_CONF_config_opts%;
+  vars["VERSION"] = %OCTAVE_CONF_VERSION%;
+  vars["SED"] = %OCTAVE_CONF_SED%;
+  vars["MACHINE"] = %OCTAVE_CONF_CANONICAL_HOST_TYPE%;
+  vars["F77"] = %OCTAVE_CONF_F77%;
+  vars["FFLAGS"] = %OCTAVE_CONF_FFLAGS%;
+  vars["FPICFLAG"] = %OCTAVE_CONF_FPICFLAG%;
+  vars["FLIBS"] = %OCTAVE_CONF_FLIBS%;
+  vars["CPPFLAGS"] = %OCTAVE_CONF_CPPFLAGS%;
+  vars["INCFLAGS"] = %OCTAVE_CONF_INCFLAGS%;
+  vars["CC"] = %OCTAVE_CONF_CC%;
+  vars["CC_VERSION"] = %OCTAVE_CONF_CC_VERSION%;
+  vars["CFLAGS"] = %OCTAVE_CONF_CFLAGS%;
+  vars["CPICFLAG"] = %OCTAVE_CONF_CPICFLAG%;
+  vars["CXX"] = %OCTAVE_CONF_CXX%;
+  vars["CXX_VERSION"] = %OCTAVE_CONF_CXX_VERSION%;
+  vars["CXXFLAGS"] = %OCTAVE_CONF_CXXFLAGS%;
+  vars["CXXPICFLAG"] = %OCTAVE_CONF_CXXPICFLAG%;
+  vars["LD_CXX"] = %OCTAVE_CONF_LD_CXX%;
+  vars["LDFLAGS"] = %OCTAVE_CONF_LDFLAGS%;
+  vars["LIBFLAGS"] = %OCTAVE_CONF_LIBFLAGS%;
+  vars["RLD_FLAG"] = %OCTAVE_CONF_RLD_FLAG%;
+  vars["LIBS"] = %OCTAVE_CONF_LIBS%;
+  vars["BLAS_LIBS"] = %OCTAVE_CONF_BLAS_LIBS%;
+  vars["FFTW_LIBS"] = %OCTAVE_CONF_FFTW_LIBS%;
+  vars["LEXLIB"] = %OCTAVE_CONF_LEXLIB%;
+  vars["LIBGLOB"] = %OCTAVE_CONF_LIBGLOB%;
+  vars["DEFS"] = %OCTAVE_CONF_DEFS%;
+
+  vars["USER"] = get_env_variable ("LOGNAME");
+  if (vars["USER"].empty ())
+    vars["USER"] = get_env_variable ("USERNAME");
+
+  vars["CC_AND_VERSION"] = (vars["CC"] + ", version" + vars["CC_VERSION"]);
+  
+  vars["CXX_AND_VERSION"] = (vars["CXX"] + ", version" + vars["CXX_VERSION"]);
+
+  // FIXME -- could be obtained from OS.
+  vars["UN"] = "Windows";
+
+  // FIXME -- the shell script also checks the minor version number,
+  // and if it is greater than or equal to 90, it is assumed that this
+  // version of Octave is a test release and bugs should go to the
+  // maintainers at octave.org list instead of bugs.
+  if (starts_with (vars["VERSION"], "ss"))
+    vars["BUGADDR"] = "maintainers at octave.org";
+  else
+    vars["BUGADDR"] = "bug at octave.org";
+
+  vars["SUBJECT"] = "[50 character or so descriptive subject here (for reference)]";
+  if (arg_idx < argc && strcmp (argv[arg_idx], "-s") == 0)
+    {
+      arg_idx++;
+      if (arg_idx < argc)
+	vars["SUBJECT"] = argv[arg_idx++];
+      else
+	usage ();
+    }
+
+  ostringstream os;
+
+  os << "Bug report for Octave " << vars["VERSION"] << " configured for " << vars["MACHINE"] << endl;
+  os << endl;
+  os << "Description:" << endl;
+  os << "-----------" << endl;
+  os << endl;
+  os << "  * Please replace this item with a detailed description of the" << endl;
+  os << "    problem.  Suggestions or general comments are also welcome." << endl;
+  os << endl;
+  os << "Repeat-By:" << endl;
+  os << "---------" << endl;
+  os << endl;
+  os << "  * Please replace this item with a description of the sequence of" << endl;
+  os << "    events that causes the problem to occur. " << endl;
+  os << endl;
+  os << "Fix:" << endl;
+  os << "---" << endl;
+  os << endl;
+  os << "  * If possible, replace this item with a description of how to" << endl;
+  os << "    fix the problem (if you don't have a fix for the problem, don't" << endl;
+  os << "    include this section, but please do submit your report anyway)." << endl;
+  os << endl;
+  os << endl;
+  os << endl;
+  os << "Configuration (please do not edit this section):" << endl;
+  os << "-----------------------------------------------" << endl;
+  os << endl;
+  os << "uname output:     " << vars["UN"] << endl;
+  os << "configure opts:   " << vars["config_opts"] << endl;
+  os << "Fortran compiler: " << vars["F77"] << endl;
+  os << "FFLAGS:           " << vars["FFLAGS"] << endl;
+  os << "FLIBS:            " << vars["FLIBS"] << endl;
+  os << "CPPFLAGS:         " << vars["CPPFLAGS"] << endl;
+  os << "INCFLAGS:         " << vars["INCFLAGS"] << endl;
+  os << "C compiler:       " << vars["CC_AND_VERSION"] << endl;
+  os << "CFLAGS:           " << vars["CFLAGS"] << endl;
+  os << "CPICFLAG:         " << vars["CPICFLAG"] << endl;
+  os << "C++ compiler:     " << vars["CXX_AND_VERSION"] << endl;
+  os << "CXXFLAGS:         " << vars["CXXFLAGS"] << endl;
+  os << "CXXPICFLAG:       " << vars["CXXPICFLAG"] << endl;
+  os << "LD_CXX:           " << vars["LD_CXX"] << endl;
+  os << "LDFLAGS:          " << vars["LDFLAGS"] << endl;
+  os << "LIBFLAGS:         " << vars["LIBFLAGS"] << endl;
+  os << "RLD_FLAG:         " << vars["RLD_FLAG"] << endl;
+  os << "BLAS_LIBS:        " << vars["BLAS_LIBS"] << endl;
+  os << "FFTW_LIBS:        " << vars["FFTW_LIBS"] << endl;
+  os << "LIBS:             " << vars["LIBS"] << endl;
+  os << "LEXLIB:           " << vars["LEXLIB"] << endl;
+  os << "LIBGLOB:          " << vars["LIBGLOB"] << endl;
+  os << "SED:              " << vars["SED"] << endl;
+  os << "DEFS:" << endl << vars["DEFS"] << endl;
+  os << endl;
+
+  if (arg_idx < argc)
+    {
+      os << endl;
+      os << "User-preferences (please do not edit this section):" << endl;
+      os << endl;
+
+      ifstream is (argv[arg_idx++]);
+
+      if (! is.fail ())
+	{
+	  string line;
+
+	  while (! is.eof ())
+	    {
+	      getline (is, line);
+	      os << line << endl;
+	    }
+	}
+      else
+	{
+	  string msg ("unable to open file for reading: ");
+
+	  msg += argv[arg_idx-1];
+	  warning (msg);
+	}
+    }
+
+  string content = os.str (), msg;
+
+  // Now go for MAPI stuff.
+
+  HMODULE hMapi;
+  LHANDLE session;
+  LPMAPILOGON mapiLogon;
+  LPMAPILOGOFF mapiLogoff;
+  LPMAPISENDMAIL mapiSendMail;
+
+  hMapi = LoadLibrary ("mapi32.dll");
+  if (hMapi != NULL)
+    {
+      mapiLogon = (LPMAPILOGON) GetProcAddress (hMapi, "MAPILogon");
+      mapiLogoff = (LPMAPILOGOFF) GetProcAddress (hMapi, "MAPILogoff");
+      mapiSendMail = (LPMAPISENDMAIL) GetProcAddress (hMapi, "MAPISendMail");
+
+      if (mapiLogon != NULL && mapiLogoff != NULL
+	  && mapiSendMail != NULL)
+	{
+	  ULONG result = 0;
+
+	  if ((result = mapiLogon (0, "", "", MAPI_LOGON_UI, 0, &session)) == SUCCESS_SUCCESS)
+	    {
+	      MapiMessage mmsg;
+	      MapiRecipDesc mrecip[2];
+
+	      ZeroMemory (&mmsg, sizeof (mmsg));
+	      ZeroMemory (&mrecip, sizeof (mrecip));
+
+	      mmsg.lpszSubject = strdup (vars["SUBJECT"].c_str ());
+	      mmsg.lpszNoteText = strdup (content.c_str ());
+	      mmsg.nRecipCount = 1;
+	      mmsg.lpRecips = mrecip;
+
+	      mrecip[0].ulRecipClass = MAPI_TO;
+	      mrecip[0].lpszName = "Octave";
+	      mrecip[0].lpszAddress = strdup (vars["BUGADDR"].c_str ());
+
+	      if (! vars["USER"].empty ())
+		{
+		  mmsg.nRecipCount = 2;
+		  mrecip[1].ulRecipClass = MAPI_CC;
+		  mrecip[1].lpszName = strdup (vars["USER"].c_str ());
+		}
+
+	      if ((result = mapiSendMail (session, 0, &mmsg, MAPI_DIALOG, 0)) != SUCCESS_SUCCESS
+		  && result != MAPI_USER_ABORT)
+		msg = "mail not sent";
+
+	      free (mmsg.lpszSubject);
+	      free (mmsg.lpszNoteText);
+	      free (mrecip[0].lpszAddress);
+	      if (mmsg.nRecipCount > 1)
+		free (mrecip[1].lpszName);
+
+	      mapiLogoff (session, 0, 0, 0);
+	    }
+	  else
+	    msg = "cannot logon to MAPI service";
+
+	  if (! msg.empty ())
+	    {
+	      char buf[64];
+	      _snprintf (buf, 63, "%08x", result);
+	      msg += (" (result: " + string (buf) + ")");
+	    }
+	}
+      else
+	msg = "cannot find entry points in MAPI library";
+
+      FreeLibrary (hMapi);
+    }
+  else
+    msg = "unable to find MAPI service";
+
+  if (! msg.empty ())
+    {
+      warning (msg);
+
+      string tmpfile = _tempnam (NULL, "octave-");
+      ofstream ofs (tmpfile.c_str ());
+
+      if (! ofs.fail ())
+	{
+	  ofs << content;
+	  ofs.close ();
+      
+	  warning ("");
+	  warning ("the mail could not be sent to octave; a text editor should appear");
+	  warning ("with the content of the bug report; please copy it and paste it");
+	  warning ("manually into your mail client and send it to the following");
+	  warning ("address: " + vars["BUGADDR"]);
+
+	  string cmd ("notepad ");
+
+	  cmd += tmpfile;
+	  ::system (cmd.c_str ());
+	  ::unlink (tmpfile.c_str ());
+	}
+      else
+	error ("unable to open file for writing: " + tmpfile);
+    }
+
+  return 0;
+}
diff --git a/octave-bug.in b/octave-bug.in
new file mode 100755
index 0000000..f0c7a7c
--- /dev/null
+++ b/octave-bug.in
@@ -0,0 +1,393 @@
+#! /bin/sh -
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004,
+#               2005, 2006, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# octave-bug - create a bug report and mail it to the bug-octave
+# mailing list.
+#
+# Patterned after the bashbug script from bash 1.14.
+
+# Configuration:  these variables are filled in when running make to
+# compile Octave.
+
+config_opts=%OCTAVE_CONF_config_opts%
+VERSION=%OCTAVE_CONF_VERSION%
+SED=%OCTAVE_CONF_SED%
+MACHINE=%OCTAVE_CONF_CANONICAL_HOST_TYPE%
+F77=%OCTAVE_CONF_F77%
+FFLAGS=%OCTAVE_CONF_FFLAGS%
+FPICFLAG=%OCTAVE_CONF_FPICFLAG%
+FLIBS=%OCTAVE_CONF_FLIBS%
+CPPFLAGS=%OCTAVE_CONF_CPPFLAGS%
+INCFLAGS=%OCTAVE_CONF_INCFLAGS%
+CC=%OCTAVE_CONF_CC%
+CC_VERSION=%OCTAVE_CONF_CC_VERSION%
+CFLAGS=%OCTAVE_CONF_CFLAGS%
+CPICFLAG=%OCTAVE_CONF_CPICFLAG%
+CXX=%OCTAVE_CONF_CXX%
+CXX_VERSION=%OCTAVE_CONF_CXX_VERSION%
+CXXFLAGS=%OCTAVE_CONF_CXXFLAGS%
+CXXPICFLAG=%OCTAVE_CONF_CXXPICFLAG%
+LD_CXX=%OCTAVE_CONF_LD_CXX%
+LDFLAGS=%OCTAVE_CONF_LDFLAGS%
+LIBFLAGS=%OCTAVE_CONF_LIBFLAGS%
+RLD_FLAG=%OCTAVE_CONF_RLD_FLAG%
+LIBS=%OCTAVE_CONF_LIBS%
+BLAS_LIBS=%OCTAVE_CONF_BLAS_LIBS%
+FFTW_LIBS=%OCTAVE_CONF_FFTW_LIBS%
+LEXLIB=%OCTAVE_CONF_LEXLIB%
+LIBGLOB=%OCTAVE_CONF_LIBGLOB%
+DEFS=%OCTAVE_CONF_DEFS%
+
+: ${USER=$LOGNAME}
+
+CC_AND_VERSION=
+if test -n "$CC_VERSION"; then
+  CC_AND_VERSION="$CC, version $CC_VERSION"
+fi
+
+CXX_AND_VERSION=
+if test -n "$CXX_VERSION"; then
+  CXX_AND_VERSION="$CXX, version $CXX_VERSION"
+fi
+
+PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$PATH
+export PATH
+
+TEMP=/tmp/octave-bug.$$
+
+if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
+  if [ -x /usr/bin/editor ]; then
+    DEFEDITOR=editor
+  elif [ -x /usr/local/bin/ce ]; then
+    DEFEDITOR=ce
+  elif [ -x /usr/local/bin/emacs ]; then
+    DEFEDITOR=emacs
+  elif [ -x /usr/contrib/bin/emacs ]; then
+    DEFEDITOR=emacs
+  elif [ -x /usr/bin/emacs ]; then
+    DEFEDITOR=emacs
+  elif [ -x /usr/bin/xemacs ]; then
+    DEFEDITOR=xemacs
+  elif [ -x /usr/contrib/bin/jove ]; then
+    DEFEDITOR=jove
+  elif [ -x /usr/local/bin/jove ]; then
+    DEFEDITOR=jove
+  elif [ -x /usr/bin/vi ]; then
+    DEFEDITOR=vi
+  else
+    echo "octave-bug: No default editor found: attempting to use vi" >&2
+    DEFEDITOR=vi
+  fi
+fi
+
+: ${EDITOR=$DEFEDITOR}
+
+if [ -z "$DEFPAGER" ] && [ -z "$PAGER" ]; then
+  if [ -x /usr/bin/pager ]; then
+    DEFPAGER=pager
+  elif [ -x /usr/bin/less ]; then
+    DEFPAGER=less
+  elif [ -x /bin/less ]; then
+    DEFPAGER=less
+  elif [ -x /usr/local/bin/less ]; then
+    DEFPAGER=less
+  elif [ -x /usr/bin/more ]; then
+    DEFPAGER=more
+  elif [ -x /bin/more ]; then
+    DEFPAGER=more
+  elif [ -x /usr/bin/pg ]; then
+    DEFPAGER=pg
+  elif [ -x /bin/pg ]; then
+    DEFPAGER=pg
+  else
+    echo "octave-bug: No default pager found: attempting to use more" >&2
+    DEFPAGER=more
+  fi
+fi
+
+: ${PAGER=$DEFPAGER}
+
+trap 'rm -f $TEMP $TEMP.x; exit 1' 1 2 3 13 15
+trap 'rm -f $TEMP $TEMP.x' 0
+
+UN=
+if (uname) > /dev/null 2>&1; then
+  UN=`uname -a`
+fi
+
+HAVE_FMT=false
+if (fmt < /dev/null) > /dev/null 2>&1; then
+  HAVE_FMT=true
+fi
+
+# Check whether to use -n or \c to keep echo from printing a newline
+# character.  Stolen from autoconf, which borrowed the idea from dist 3.0.
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi at caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | $SED s/-n/xn/ | grep xn >/dev/null; then
+    echo_n=
+    echo_c='
+'
+  else
+    echo_n=-n
+    echo_c=
+  fi
+else
+  echo_n=
+  echo_c='\c'
+fi
+
+ss_p=`echo $VERSION | grep "^ss-"`
+if test -n "$ss_p"; then
+  BUGADDR="maintainers at octave.org"
+else
+  pretest_p=`echo $VERSION \
+    | $SED 's,.*\.\([0-9]*\).*,\1,' \
+    | grep -v '\.' \
+    | grep '[0-9]'`
+
+  if test -n "$pretest_p" && test "$pretest_p" -ge 90; then
+    BUGADDR="maintainers at octave.org"
+  else
+    BUGADDR="bug at octave.org"
+  fi
+fi
+
+SUBJECT="[50 character or so descriptive subject here (for reference)]"
+if test $# -gt 0; then
+  case "$1" in
+    -s)
+      shift
+      if test $# -gt 0; then
+        SUBJECT="$1"
+        shift
+      else
+        echo "usage: octave-bug [-s subject]"
+        exit 1
+      fi
+    ;;
+  esac
+fi
+
+cat > $TEMP << EOF
+To: $BUGADDR
+EOF
+if test -n "$USER"; then
+cat >> $TEMP << EOF
+Cc: $USER
+EOF
+fi
+cat >> $TEMP << EOF
+Subject: $SUBJECT
+--------
+Bug report for Octave $VERSION configured for $MACHINE
+
+Description:
+-----------
+
+  * Please replace this item with a detailed description of the
+    problem.  Suggestions or general comments are also welcome.
+
+Repeat-By:
+---------
+
+  * Please replace this item with a description of the sequence of
+    events that causes the problem to occur. 
+
+Fix:
+---
+
+  * If possible, replace this item with a description of how to
+    fix the problem (if you don't have a fix for the problem, don't
+    include this section, but please do submit your report anyway).
+
+
+
+Configuration (please do not edit this section):
+-----------------------------------------------
+
+uname output:     $UN
+configure opts:   $config_opts
+Fortran compiler: $F77
+FFLAGS:           $FFLAGS
+FLIBS:            $FLIBS
+CPPFLAGS:         $CPPFLAGS
+INCFLAGS:         $INCFLAGS
+C compiler:       $CC_AND_VERSION
+CFLAGS:           $CFLAGS
+CPICFLAG:         $CPICFLAG
+C++ compiler:     $CXX_AND_VERSION
+CXXFLAGS:         $CXXFLAGS
+CXXPICFLAG:       $CXXPICFLAG
+LD_CXX:           $LD_CXX
+LDFLAGS:          $LDFLAGS
+LIBFLAGS:         $LIBFLAGS
+RLD_FLAG:         $RLD_FLAG
+BLAS_LIBS:        $BLAS_LIBS
+FFTW_LIBS:        $FFTW_LIBS
+LIBS:             $LIBS
+LEXLIB:           $LEXLIB
+LIBGLOB:          $LIBGLOB
+SED:              $SED
+DEFS:
+
+EOF
+
+if $HAVE_FMT; then
+  echo $DEFS | fmt | $SED 's/^/  /' >> $TEMP
+else
+  echo $DEFS >> $TEMP
+fi
+
+if test $# -gt 0; then
+  if test -f "$1"; then
+    cat >> $TEMP << EOF
+
+User-preferences (please do not edit this section):
+--------------------------------------------------
+
+EOF
+    cat $1 >> $TEMP
+  fi
+fi
+
+chmod u+w $TEMP
+cp $TEMP $TEMP.x
+
+status=0
+
+editing=true
+
+while $editing; do
+  if $EDITOR $TEMP; then
+    while $editing; do
+      echo $echo_n "(a)bort, (e)dit, (l)ist, (s)end? $echo_c"
+      read ans
+      case "$ans" in
+        a* | A*)
+          status=1
+          editing=false
+        ;;
+        e* | E*)
+          break;
+        ;;
+        l* | L*)
+          $PAGER $TEMP
+        ;;
+        s* | S*)
+          editing=false
+        ;;
+      esac
+    done
+  else
+    echo "problems with edit -- no bug report submitted"
+    status=1
+    editing=false
+  fi
+done
+
+if test $status -eq 0; then
+  if cmp -s $TEMP $TEMP.x; then
+    echo "file not changed -- no bug report submitted"
+    status=1
+  elif test `wc $TEMP | awk '{print $1}'` -eq 0; then
+    echo "empty bug report file -- not submitted"
+    status=1
+  else
+
+# Try to extract the recipient address, in case the To: line in the
+# message template has been changed.  Also get cc: lines.
+
+    TO_ADDR=`$SED -e '/^--------[ \t]*$/q' $TEMP | $SED -n -e 's/^[Tt][Oo]://p'`
+    CC_ADDR=`$SED -e '/^--------[ \t]*$/q' $TEMP | $SED -n -e 's/^[Cc][Cc]://p'`
+
+    if test -z "$TO_ADDR"; then
+      echo "no valid \`To:' field found in header -- using $BUGADDR instead"
+    else
+      BUGADDR="$TO_ADDR"      
+    fi
+
+    BUGADDR="$BUGADDR $CC_ADDR"
+
+    TMP_SUB=`$SED -e '/^--------[ \t]*$/q' $TEMP | $SED -n -e 's/^Subject://p'`
+
+    if test -n "$TMP_SUB"; then
+      SUBJECT="$TMP_SUB"
+    fi
+
+# Delete the `--------' separator in the message.
+
+# Don't pretty-print this.  Odd whitespace kills Ultrix AWK!
+
+    awk 'BEGIN{in_header=1;} /^--------[ \t]*$/ {
+      if (in_header) { in_header=0; print ""; next; }
+    } { print $0; }' $TEMP > $TEMP.x
+
+# Now try to mail it.
+
+    # indicate that we have not yet sent email successfully
+    status=11
+
+    if test $status -ne 0; then
+      ( mailx -s "$SUBJECT" $BUGADDR < $TEMP.x ) > /dev/null 2>&1
+      status=$?
+      if test $status -ne 0; then
+        ( Mail -s "$SUBJECT" $BUGADDR < $TEMP.x ) > /dev/null 2>&1
+        status=$?
+        if test $status -ne 0; then
+          ( /usr/ucb/mail -s "$SUBJECT" $BUGADDR < $TEMP.x ) > /dev/null 2>&1
+          status=$?
+          # make /bin/mail our last resort -- it ignores the subject line
+          if test $status -ne 0; then
+            ( /bin/mail $BUGADDR < $TEMP.x ) > /dev/null 2>&1
+            status=$?
+            if test $status -ne 0; then
+              echo "unable to send mail..."
+            fi
+          fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+if test $status -ne 0; then
+  dead_bug_file=$HOME/dead-octave-bug
+  looking_for_file=true;
+  n=1
+  while $looking_for_file; do
+    if test -f "$dead_bug_file-$n"; then
+      n=`expr $n + 1`
+    else
+      looking_for_file=false
+      dead_bug_file=$dead_bug_file-$n
+    fi
+  done
+  echo "saving message in $dead_bug_file";
+  cat $TEMP >> $dead_bug_file;
+  exit 1
+else
+  echo "bug report sent to: $TO_ADDR"
+  echo "             cc to: $CC_ADDR"
+fi
+
+exit $status
diff --git a/octave-config.cc.in b/octave-config.cc.in
new file mode 100644
index 0000000..be6b5dc
--- /dev/null
+++ b/octave-config.cc.in
@@ -0,0 +1,224 @@
+/*
+
+Copyright (C) 2008 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <string>
+#include <map>
+#include <iostream>
+#include <algorithm>
+#include <cstdlib>
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+#include <windows.h>
+#endif
+
+static bool initialized = false;
+static std::map<std::string,std::string> vars;
+static std::string OCTAVE_HOME, PREFIX;
+static std::string usage_msg = "usage: octave-config [options]";
+static std::string help_msg =
+"\n"
+"Options:\n"
+"\n"
+"  -h, -?, --help        Print this message.\n"
+"\n"
+"  --m-site-dir          Print the name of the directory where Octave\n"
+"                        expects to find locally installed .m files.\n"
+"\n"
+"  --oct-site-dir        Print the name of the directory where Octave\n"
+"                        expects to find locally installed .oct files.\n"
+"\n"
+"  -p VAR, --print VAR   Print the value of the given configuration\n"
+"		        variable VAR.  Recognized variables are:\n"
+"\n"
+"			  API_VERSION	         LOCALAPIARCHLIBDIR\n"
+"			  CANONICAL_HOST_TYPE	 LOCALAPIFCNFILEDIR\n"
+"			  DEFAULT_PAGER	         LOCALAPIOCTFILEDIR\n"
+"			  ARCHLIBDIR	         LOCALARCHLIBDIR\n"
+"			  BINDIR	         LOCALFCNFILEDIR\n"
+"			  DATADIR	         LOCALOCTFILEDIR\n"
+"			  DATAROOTDIR	         LOCALSTARTUPFILEDIR\n"
+"			  EXEC_PREFIX	         LOCALVERARCHLIBDIR\n"
+"			  FCNFILEDIR		 LOCALVERFCNFILEDIR\n"
+"			  LOCALVEROCTFILEDIR	 MAN1DIR\n"
+"			  IMAGEDIR	         MANDIR\n"
+"			  MAN1EXT	         OCTFILEDIR\n"
+"			  INCLUDEDIR	         OCTINCLUDEDIR\n"
+"			  INFODIR	         OCTLIBDIR\n"
+"			  INFOFILE	         PREFIX\n"
+"			  LIBDIR	         STARTUPFILEDIR\n"
+"			  LIBEXECDIR		 VERSION\n"
+"\n"
+"  -v, --version         Print the Octave version number.\n"
+"\n";
+
+static std::string
+substitute_prefix (const std::string& s, const std::string& prefix,
+		   const std::string new_prefix)
+{
+  std::string retval = s;
+
+  if (!prefix.empty () && new_prefix != prefix)
+    {
+      int len = prefix.length ();
+      if (retval.find (prefix) == 0)
+	retval.replace (0, len, new_prefix);
+    }
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  std::replace (retval.begin (), retval.end (), '/', '\\');
+#endif
+
+  return retval;
+}
+
+static void
+initialize (void)
+{
+  if (initialized)
+    return;
+
+  initialized = true;
+
+  const char *homestr = getenv ("OCTAVE_HOME");
+  OCTAVE_HOME = (homestr ? homestr : "");
+  PREFIX = %OCTAVE_PREFIX%;
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  int n = 1024;
+
+  std::string bin_dir (n, '\0');
+
+  while (true)
+    {
+      int status = GetModuleFileName (0, &bin_dir[0], n);
+
+      if (status < n)
+	{
+	  bin_dir.resize (status);
+	  break;
+	}
+      else
+	{
+	  n *= 2;
+	  bin_dir.resize (n);
+	}
+    }
+
+  if (! bin_dir.empty ())
+    {
+      size_t pos = bin_dir.rfind ("\\bin\\");
+
+      if (pos != std::string::npos)
+	OCTAVE_HOME = bin_dir.substr (0, pos);
+    }
+#endif
+
+  vars["API_VERSION"] = %OCTAVE_API_VERSION%;
+  vars["CANONICAL_HOST_TYPE"] = %OCTAVE_CANONICAL_HOST_TYPE%;
+  vars["DEFAULT_PAGER"] = %OCTAVE_DEFAULT_PAGER%;
+  vars["ARCHLIBDIR"] = substitute_prefix (%OCTAVE_ARCHLIBDIR%, PREFIX, OCTAVE_HOME);
+  vars["BINDIR"] = substitute_prefix (%OCTAVE_BINDIR%, PREFIX, OCTAVE_HOME);
+  vars["DATADIR"] =substitute_prefix (%OCTAVE_DATADIR%, PREFIX, OCTAVE_HOME);
+  vars["DATAROOTDIR"] =substitute_prefix (%OCTAVE_DATAROOTDIR%, PREFIX, OCTAVE_HOME);
+  vars["EXEC_PREFIX"] =substitute_prefix (%OCTAVE_EXEC_PREFIX%, PREFIX, OCTAVE_HOME);
+  vars["FCNFILEDIR"] =substitute_prefix (%OCTAVE_FCNFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["IMAGEDIR"] =substitute_prefix (%OCTAVE_IMAGEDIR%, PREFIX, OCTAVE_HOME);
+  vars["INCLUDEDIR"] =substitute_prefix (%OCTAVE_INCLUDEDIR%, PREFIX, OCTAVE_HOME);
+  vars["INFODIR"] =substitute_prefix (%OCTAVE_INFODIR%, PREFIX, OCTAVE_HOME);
+  vars["INFOFILE"] =substitute_prefix (%OCTAVE_INFOFILE%, PREFIX, OCTAVE_HOME);
+  vars["LIBDIR"] =substitute_prefix (%OCTAVE_LIBDIR%, PREFIX, OCTAVE_HOME);
+  vars["LIBEXECDIR"] =substitute_prefix (%OCTAVE_LIBEXECDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALAPIARCHLIBDIR"] =substitute_prefix (%OCTAVE_LOCALAPIARCHLIBDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALAPIFCNFILEDIR"] =substitute_prefix (%OCTAVE_LOCALAPIFCNFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALAPIOCTFILEDIR"] =substitute_prefix (%OCTAVE_LOCALAPIOCTFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALARCHLIBDIR"] =substitute_prefix (%OCTAVE_LOCALARCHLIBDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALFCNFILEDIR"] =substitute_prefix (%OCTAVE_LOCALFCNFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALOCTFILEDIR"] =substitute_prefix (%OCTAVE_LOCALOCTFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALSTARTUPFILEDIR"] =substitute_prefix (%OCTAVE_LOCALSTARTUPFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALVERARCHLIBDIR"] =substitute_prefix (%OCTAVE_LOCALVERARCHLIBDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALVERFCNFILEDIR"] =substitute_prefix (%OCTAVE_LOCALVERFCNFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["LOCALVEROCTFILEDIR"] =substitute_prefix (%OCTAVE_LOCALVEROCTFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["MAN1DIR"] =substitute_prefix (%OCTAVE_MAN1DIR%, PREFIX, OCTAVE_HOME);
+  vars["MAN1EXT"] = %OCTAVE_MAN1EXT%;
+  vars["MANDIR"] =substitute_prefix (%OCTAVE_MANDIR%, PREFIX, OCTAVE_HOME);
+  vars["OCTFILEDIR"] =substitute_prefix (%OCTAVE_OCTFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["OCTINCLUDEDIR"] =substitute_prefix (%OCTAVE_OCTINCLUDEDIR%, PREFIX, OCTAVE_HOME);
+  vars["OCTLIBDIR"] =substitute_prefix (%OCTAVE_OCTLIBDIR%, PREFIX, OCTAVE_HOME);
+  vars["PREFIX"] = (OCTAVE_HOME.empty() ? PREFIX : OCTAVE_HOME);
+  vars["STARTUPFILEDIR"] =substitute_prefix (%OCTAVE_STARTUPFILEDIR%, PREFIX, OCTAVE_HOME);
+  vars["VERSION"] = %OCTAVE_VERSION%;
+}
+
+int
+main (int argc, char **argv)
+{
+  initialize ();
+
+  if (argc == 1)
+    {
+      std::cout << usage_msg << std::endl;
+      return 1;
+    }
+
+  for (int i = 1; i < argc; i++)
+    {
+      std::string arg (argv[i]);
+
+      if (arg == "-h" || arg == "-?" || arg == "--help")
+	{
+	  std::cout << usage_msg << std::endl;
+	  std::cout << help_msg;
+	  return 0;
+	}
+      else if (arg == "--m-site-dir")
+	std::cout << vars["LOCALVERFCNFILEDIR"] << std::endl;
+      else if (arg == "--oct-site-dir")
+	std::cout << vars["LOCALVEROCTFILEDIR"] << std::endl;
+      else if (arg == "-v" || arg == "--version")
+	std::cout << vars["VERSION"] << std::endl;
+      else if (arg == "-p" || arg == "--print")
+	{
+	  if (i < argc-1)
+	    {
+	      arg = argv[++i];
+	      std::cout << vars[arg] << std::endl;
+	    }
+	  else
+	    {
+	      std::cerr << "octave-config: " << arg
+			<< " options requires argument" << std::endl;
+	      return 1;
+	    }
+	}
+      else
+	{
+	  std::cerr << "octave-config: unrecognized argument " << arg << std::endl;
+	  return 1;
+	}
+    }
+  
+  return 0;
+}
diff --git a/octave-config.in b/octave-config.in
new file mode 100644
index 0000000..1893334
--- /dev/null
+++ b/octave-config.in
@@ -0,0 +1,168 @@
+#! /bin/sh -
+##
+## octave-config - reports some configuration values for Octave
+##
+## Copyright (C) 2001, 2003, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+## 
+## Original version by Rafael Laboissiere <rafael at laboissiere.net>
+## distributed as free software in the public domain.
+
+API_VERSION=%OCTAVE_API_VERSION%
+CANONICAL_HOST_TYPE=%OCTAVE_CANONICAL_HOST_TYPE%
+DEFAULT_PAGER=%OCTAVE_DEFAULT_PAGER%
+ARCHLIBDIR=%OCTAVE_ARCHLIBDIR%
+BINDIR=%OCTAVE_BINDIR%
+DATADIR=%OCTAVE_DATADIR%
+DATAROOTDIR=%OCTAVE_DATAROOTDIR%
+EXEC_PREFIX=%OCTAVE_EXEC_PREFIX%
+FCNFILEDIR=%OCTAVE_FCNFILEDIR%
+IMAGEDIR=%OCTAVE_IMAGEDIR%
+INCLUDEDIR=%OCTAVE_INCLUDEDIR%
+INFODIR=%OCTAVE_INFODIR%
+INFOFILE=%OCTAVE_INFOFILE%
+LIBDIR=%OCTAVE_LIBDIR%
+LIBEXECDIR=%OCTAVE_LIBEXECDIR%
+LOCALAPIARCHLIBDIR=%OCTAVE_LOCALAPIARCHLIBDIR%
+LOCALAPIFCNFILEDIR=%OCTAVE_LOCALAPIFCNFILEDIR%
+LOCALAPIOCTFILEDIR=%OCTAVE_LOCALAPIOCTFILEDIR%
+LOCALARCHLIBDIR=%OCTAVE_LOCALARCHLIBDIR%
+LOCALFCNFILEDIR=%OCTAVE_LOCALFCNFILEDIR%
+LOCALOCTFILEDIR=%OCTAVE_LOCALOCTFILEDIR%
+LOCALSTARTUPFILEDIR=%OCTAVE_LOCALSTARTUPFILEDIR%
+LOCALVERARCHLIBDIR=%OCTAVE_LOCALVERARCHLIBDIR%
+LOCALVERFCNFILEDIR=%OCTAVE_LOCALVERFCNFILEDIR%
+LOCALVEROCTFILEDIR=%OCTAVE_LOCALVEROCTFILEDIR%
+MAN1DIR=%OCTAVE_MAN1DIR%
+MAN1EXT=%OCTAVE_MAN1EXT%
+MANDIR=%OCTAVE_MANDIR%
+OCTFILEDIR=%OCTAVE_OCTFILEDIR%
+OCTINCLUDEDIR=%OCTAVE_OCTINCLUDEDIR%
+OCTLIBDIR=%OCTAVE_OCTLIBDIR%
+PREFIX=%OCTAVE_PREFIX%
+STARTUPFILEDIR=%OCTAVE_STARTUPFILEDIR%
+VERSION=%OCTAVE_VERSION%
+
+if [ -n "$OCTAVE_HOME" ]; then
+  ARCHLIBDIR="`echo $ARCHLIBDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  BINDIR="`echo $BINDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  DATADIR="`echo $DATADIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  DATAROOTDIR="`echo $DATAROOTDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  EXEC_PREFIX="`echo $EXEC_PREFIX | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  FCNFILEDIR="`echo $FCNFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  IMAGEDIR="`echo $IMAGEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  INCLUDEDIR="`echo $INCLUDEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  INFODIR="`echo $INFODIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  INFOFILE="`echo $INFOFILE | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LIBDIR="`echo $LIBDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LIBEXECDIR="`echo $LIBEXECDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALAPIARCHLIBDIR="`echo $LOCALAPIARCHLIBDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALAPIFCNFILEDIR="`echo $LOCALAPIFCNFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALAPIOCTFILEDIR="`echo $LOCALAPIOCTFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALARCHLIBDIR="`echo $LOCALARCHLIBDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALFCNFILEDIR="`echo $LOCALFCNFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALOCTFILEDIR="`echo $LOCALOCTFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALSTARTUPFILEDIR="`echo $LOCALSTARTUPFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALVERARCHLIBDIR="`echo $LOCALVERARCHLIBDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALVERFCNFILEDIR="`echo $LOCALVERFCNFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  LOCALVEROCTFILEDIR="`echo $LOCALVEROCTFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  MAN1DIR="`echo $MAN1DIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  MANDIR="`echo $MANDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  OCTFILEDIR="`echo $OCTFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  OCTINCLUDEDIR="`echo $OCTINCLUDEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  OCTLIBDIR="`echo $OCTLIBDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+  STARTUPFILEDIR="`echo $STARTUPFILEDIR | sed "s,^$PREFIX,$OCTAVE_HOME,"`"
+
+  PREFIX="$OCTAVE_HOME"
+fi
+
+usage_msg="usage: octave-config [options]"
+
+if [ $# -eq 0 ]; then
+  echo "$usage_msg" 1>&2
+  exit 1
+fi
+
+while [ $# -gt 0 ]
+do
+  case "$1" in
+    -h | -\? | --help)
+      echo "$usage_msg"
+      cat << EOF
+
+Options:
+
+  -h, -?, --help        Print this message.
+
+  --m-site-dir          Print the name of the directory where Octave
+                        expects to find locally installed .m files.
+
+  --oct-site-dir        Print the name of the directory where Octave
+                        expects to find locally installed .oct files.
+
+  -p VAR, --print VAR   Print the value of the given configuration
+		        variable VAR.  Recognized variables are:
+
+			  API_VERSION	         LOCALAPIARCHLIBDIR
+			  CANONICAL_HOST_TYPE	 LOCALAPIFCNFILEDIR
+			  DEFAULT_PAGER	         LOCALAPIOCTFILEDIR
+			  ARCHLIBDIR	         LOCALARCHLIBDIR
+			  BINDIR	         LOCALFCNFILEDIR
+			  DATADIR	         LOCALOCTFILEDIR
+			  EXEC_PREFIX	         LOCALSTARTUPFILEDIR
+			  FCNFILEDIR	         LOCALVERARCHLIBDIR
+			  LOCALVEROCTFILEDIR	 LOCALVERFCNFILEDIR
+			  IMAGEDIR	         MAN1DIR
+			  MAN1EXT	         MANDIR
+			  INCLUDEDIR	         OCTFILEDIR
+			  INFODIR	         OCTINCLUDEDIR
+			  INFOFILE	         OCTLIBDIR
+			  LIBDIR	         PREFIX
+			  LIBEXECDIR	         STARTUPFILEDIR
+			  LIBEXECDIR		 VERSION
+
+  -v, --version         Print the Octave version number.
+
+EOF
+      exit 0
+    ;;
+    --m-site-dir)
+      echo $LOCALVERFCNFILEDIR
+    ;;
+    --oct-site-dir)
+      echo $LOCALVEROCTFILEDIR
+    ;;
+    -v | --version)
+      echo $VERSION
+    ;;
+    -p | --print)
+      opt="$1"
+      shift
+      if [ $# -eq 0 ]; then
+        echo "octave-config: $opt option requires argument" 1>&2
+        exit 1
+      fi
+      eval echo \${$1}
+    ;;
+    *)
+      echo "octave-config: unrecognized argument $1" 2>&1
+      exit 1
+    ;;
+  esac
+  shift
+done
diff --git a/octave-sh b/octave-sh
new file mode 100755
index 0000000..862820c
--- /dev/null
+++ b/octave-sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Wrapper for octave for binary installations that can't install
+# octave in /usr/local/bin.
+#
+# The real binary should be installed in as octave.bin, and this file
+# should be installed in the same directory as octave.
+
+if test -n "$LD_LIBRARY_PATH"; then
+  LD_LIBRARY_PATH="@LD_LIBRARY_PATH@:$LD_LIBRARY_PATH"
+else
+  LD_LIBRARY_PATH="@LD_LIBRARY_PATH@"
+fi
+export LD_LIBRARY_PATH
+
+OCTAVE_HOME=@OCTAVE_HOME@
+export OCTAVE_HOME
+
+exec $OCTAVE_HOME/bin/octave.bin $*
diff --git a/run-octave.in b/run-octave.in
new file mode 100755
index 0000000..3edaa03
--- /dev/null
+++ b/run-octave.in
@@ -0,0 +1,74 @@
+#! /bin/sh
+##
+## run-octave -- run Octave in the build tree.
+## 
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+## 
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+## 
+## Octave is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+AWK=%AWK%
+FIND=%FIND%
+SED=%SED%
+
+# FIXME -- is there a better way to handle the possibility of spaces
+# in these names? 
+
+top_srcdir='%abs_top_srcdir%'
+builddir='%builddir%'
+
+liboctinterp="$builddir/src/%liboctinterp%"
+liboctave="$builddir/liboctave/%liboctave%"
+libcruft="$builddir/libcruft/%libcruft%"
+
+d1="$top_srcdir/test"
+d2="$top_srcdir/scripts"
+d3="$builddir/scripts"
+d4="$builddir/src"
+
+d1_list=`$FIND "$d1" -type d -a ! \( \( -name CVS -o -name private \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
+d2_list=`$FIND "$d2" -type d -a ! \( \( -name CVS -o -name private \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
+d3_list=`$FIND "$d3" -type d -a ! \( \( -name CVS -o -name private \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
+d4_list=`$FIND "$d4" -type d -a ! \( \( -name CVS -o -name private \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
+
+d1_path=`echo "$d1_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
+d2_path=`echo "$d2_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
+d3_path=`echo "$d3_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
+d4_path=`echo "$d4_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
+
+LOADPATH="$d1_path:$d2_path:$d3_path:$d4_path"
+IMAGEPATH="$top_srcdir/scripts/image"
+DOCFILE="$builddir/doc/interpreter/doc-cache"
+INFOFILE="$builddir/doc/interpreter/octave.info"
+
+if [ $# -gt 0 ]; then
+  if [ "x$1" = "x-g" ]; then
+    driver="gdb --args"
+    shift
+  elif [ "x$1" = "x-valgrind" ]; then
+    driver="valgrind --tool=memcheck"
+    shift
+  elif [ "x$1" = "x-strace" ]; then
+    driver="strace -o octave.trace"
+    shift
+  fi
+fi
+
+OCTAVE_SITE_INITFILE="$top_srcdir/scripts/startup/main-rcfile" \
+LD_PRELOAD="$liboctinterp $liboctave $libcruft" \
+%library_path_var%="$builddir/src:$builddir/liboctave:$builddir/libcruft:$%library_path_var%" \
+  exec $driver "$builddir/src/octave" --no-init-path --path="$LOADPATH" --image-path="$IMAGEPATH" --doc-cache-file="$DOCFILE" --info-file="$INFOFILE" "$@"
+
diff --git a/scripts/ChangeLog b/scripts/ChangeLog
new file mode 100644
index 0000000..7cbef6a
--- /dev/null
+++ b/scripts/ChangeLog
@@ -0,0 +1,12611 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+2009-11-18  Ben Abbott <bpabbott at mac.com>
+
+	* plot/orient.m: Flip papersize and paperposition when orientation
+	changes. Add support for 'tall' option. Add tests.
+
+2009-11-26  David Grundberg <individ at acc.umu.se>
+
+	* linear-algebra/dot.m: Conjugate first argument.
+
+2009-11-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/expm.m: Fix typo.
+
+2009-11-22  Michael Goffioul <michael.goffioul at gmail.com>
+
+	* plot/print.m: Properly set the default ghostscript_binary
+	under Windows. Modify the search for the ghostscript binary
+	so that it works for Win32, mingw, Cygwin, and Unix systems.
+
+2009-11-08  Petr Mikulik <mikulik at physics.muni.cz>
+
+	* plot/gnuplot_drawnow.m: Support gnuplot's dumb terminal.
+
+2009-11-02  Stefan Hepp  <stefan at stefant.org>
+
+	* plot/gnuplot_drawnow.m (gnuplot_default_term): Don't set term to
+	x11 unless DISPLAY is set.
+
+2009-11-11  John W. Eaton  <jwe at octave.org>
+
+	* plot/stairs.m (__stairs__): Correct nargin check.  New demos.
+	From Jakub Kasse <jakub.kasse at tul.cz>.
+
+2009-09-01  Christophe Tournery  <christophe.tournery at illusonic.com>
+
+	* audio/wavread.m: Rename data_size from obsolete ck_size.
+
+2009-07-23  John W. Eaton  <jwe at octave.org>
+
+	* plot/legend.m: Process arguments in order, child objects in
+	reverse.  Remove special case for single label.  New demos.
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+2009-07-23  John W. Eaton  <jwe at octave.org>
+
+	* image/imread.m: Fix test.
+
+2009-06-23  Alexander Mamonov  <mamonov at gmail.com>
+
+	* image/imread.m: New test.
+
+2009-09-09  Tatsuro Matsuoka <tmacchant at yahoo.co.jp>
+
+	* plot/gnuplot_drawnow.m: Avoid flickering windows by avoding
+	'set multiplot' / 'unset multiplot' for gnuplot's windows and
+	wxt terminals.
+
+2009-09-08  John W. Eaton  <jwe at octave.org>
+
+	* io/dlmwrite.m: Fix typo.
+
+2009-09-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/hold.m: Correctly toggle hold state.  Set both figure and
+	axes "nextplot" property when turning hold state on.
+	* plot/ishold.m: Check figure and axes nextplot properties.
+	Accept axes or figure handle argument.
+
+2009-08-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/int2str.m: Convert to double before calling log10.
+
+2009-08-29  John W. Eaton  <jwe at octave.org>
+
+	* time/datestr.m: Add missing semicolon.
+
+2009-08-26  E. Joshua Rigler  <relgire at gmail.com>
+
+	* time/datestr.m: Set tm.isdst to -1 before calling mktime.
+
+2009-08-06  John W. Eaton  <jwe at octave.org>
+
+	* statistics/base/std.m: Correctly work along singleton dimension.
+	From Christoph Ellenberger <C.Ellenberger at gmx.net>.
+
+2009-08-06  Olaf Till <olaf.till at uni-jena.de>
+
+	* geometry/griddata.m: Linearize arrays.
+
+2009-08-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/__gnuplot_open_stream__.m: Save pid in __plot_stream__ property.
+	* plot/gnuplot_drawnow.m: Wait for gnuplot subprocess when printing.
+	From Ben Abbott <bpabbott at mac.com>, Rob Mahurin <rob at utk.edu>, and
+	Dmitri Sergatskov <dasergatskov at gmail.com>.
+
+2009-08-22  David Bateman  <dbateman at free.fr>
+
+	* plot/__add_datasource__.m: Correct test for "datasource" argument
+	* plot/__countour__.m: Add edgecolor properties and make it an alias
+	for linecolor with the value "auto" being "flat" for the edgecolor.
+
+2009-08-04  Pieter Eendebak <pieter.eendebak at gmail.com> 
+
+	* set/setxor.m: Support cell arrays of strings.
+
+2009-08-05  Olli Saarela  <olli.saarela at gmail.com>
+
+	* plot/__gnuplot_get_var__.m: If read fails to return data, sleep
+	before trying again.
+
+2009-08-02  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Avoid the flickering x11 window seen with
+	rapid replots by avoidng setting multiplot mode. This fix only
+	functions for a single axes with no image objects.
+	* plot/__go_draw_figure__.m: Move 'set multiplot' to gnuplot_drawnow.
+
+2009-07-29  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Fix ticklabels specified as 2D character
+	array.
+
+2009-07-17  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Use "layer" property to decide whether
+	to send "set border front" or "set border layerdefault" to plot
+	stream.  Don't send "set border front" to plot stream for image data.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-06-25  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Apply feature 'wxt_has_size'.
+	* plot/__gnuplot_has_feature__.m: Add feature 'wxt_has_size' for
+	gnuplot >= 4.3.0.
+
+2009-06-24  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_figure__.m: Modify the implicit margin when gnuplot's
+	output is landscape.
+	* plot/gnuplot_drawnow.m: Simplify handling of the figure's paper
+	properties, and rely upon listeners for units conversion. Minor code
+	improvements.
+	* plot/print.m: Reimplement -landscape and -portrait to modify the
+	properties papersize and paperposition. Produce compatible results
+	when paperpositionmode=='auto'. Simplfy units conversion and
+	restoration of initial figure properties.
+
+2009-06-24  Marco Caliari  <marco.caliari at univr.it>
+
+	* general/repmat.m: Call kron, not spkron.
+
+2009-06-24  Alexander Mamonov  <mamonov at gmail.com>
+
+	* plot/plot3.m: Correctly compute offsets for property/value pairs.
+
+2009-06-22  Ben Abbott <bpabbott at mac.com>
+
+	* plot/grid.m: Add missing semi-colon. Allow grid to be toggled
+	on/off for each axis independently. Gnuplot requires that minor
+	ticks accompany minor ticks. Add demo.
+	* plot/__go_draw_axes__.m: For {x,y,z}scale == 'log' use 10 minor
+	ticks.
+
+2009-06-22  John W. Eaton  <jwe at octave.org>
+
+	* statistics/base/var.m: Return zero for scalar case.  Handle
+	empty arguments in a Matlab compatible way.  New tests.
+
+2009-06-18  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Change the default x11 fontspec from '*,0'
+	to ',0' to avoid delays searching the fontpath for a font named '*'.
+
+2009-06-18  Daniel Gualberto <daniel at alacer.com.br>
+
+	* polynomial/mpoles.m: Fix infinite loop for a multiplicity of
+	poles at zero. Test added.
+
+2009-06-17  Bertrand Roessli <bertrand.roessli at psi.ch>
+
+	* plot/axis.m: Fix bug for 'axis tight' with multiple surface plots,
+	add demo.
+
+2009-06-14  Ben Abbott <bpabbott at mac.com>
+
+	* plot/quiver.m: Add 'clf' to demos.
+	* plot/plotyy.m: Fix compatibility with subplot, add listeners for
+	dataaspectratio, and add a demo.
+
+2009-06-14  Eric Chassande-Mottin <echassandemottin at gmail.com>
+
+	* plot/plotyy.m: Correct behavior when there is no currentfigure.
+
+2009-06-11  Ben Abbott <bpabbott at mac.com>
+
+	* plot/print.m: Fix logic associated with 'have_ghostscript'.
+	* plot/gnuplot_drawnow.m: Add support for pdfcairo and pngcairo
+	terminals. Minor code improvements.
+	* plot/print.m: Associate '-mono' with devices ps, ps2, eps, & eps2.
+	Have '-mono' render all objects in monochrome.
+	For pdf or png output, favor gnuplot's cairo terminals.
+
+2009-06-10  Marco Caliari <marco.caliari at univr.it>
+
+	* plot/hold.m: Add demo including a hggroup.
+	* plot/__go_draw_axes__.m: Fix order when pushing group children onto
+	the axes kid list.
+	* general/quadgk.m: Better waypoint transform.
+
+2009-06-09  David Bateman  <dbateman at free.fr>
+
+	* general/quadgk.m: Add test case and fixed doubly infinite 
+	waypoint transform for x = 0 case.
+
+2009-06-09  Marco Caliari <marco.caliari at univr.it>
+
+	* general/quadgk.m: Fix doubly infinite transformation to the finite
+	interval.
+
+2009-06-08  Ben Abbott <bpabbott at mac.com>
+
+	* plot/axis.m: Fix bug for 'axis tight' with multiple lines, modify
+	demo.
+
+2009-06-07  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* testfun/assert.m: Fix texinfo bug.
+
+2009-06-04  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Change strncmpi(scale,'lo') to 
+	strcmp(scale,'log').
+	* plot/__go_draw_axes__.m: For log-scale axes use format '10^{%T}'.
+
+2009-06-03  Ben Abbott <bpabbott at mac.com>
+
+	* plot/colorbar.m: Colorbar 'handlevisibility' should be 'on'.
+	Add additional demos which illustrate problems with the present
+	implementation.
+	* plot/__gnuplot_has_feature__.m: Change version for 
+	"x11_figure_position" from ">=4.3.0" to ">=4.2.5".
+	* plot/__scatter__.m: If the color spec is empty, set using
+	__next_line_color__.
+	* plot/scatter3.m: Add demos.
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-06-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* polynomial/polyfit.m: Fix test.
+
+2009-06-02  Rafael Laboissiere  <rafael at debian.org>
+
+	* help/doc.m: In test, look also for the gzipped version of the
+	info_file
+
+2009-05-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/__gnuplot_get_var__.m: Insert missing semicolon.
+
+2009-05-28  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Set x2range when xaxislocation=='top' and set
+	y2range when yaxislocation=='right'. Simplified support for ticklabel
+	separator '|'.
+	* plot/__go_draw_figure__.m: Change 'autoscale fix' to 'autoscale keepfix'.
+	* plot/colorbar.m: Add demos.
+
+2009-05-28  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Add support for ticklabel separator '|'.
+
+2009-05-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* sparse/bicgstab.m: Improve preconditioning; avoid explicit inverse.
+	* sparse/cgs.m: Improve preconditioning; avoid explicit inverse.
+
+2009-05-28  Radek Salac  <salac.r at gmail.com>
+
+	* sparse/bicgstab.m: New output when calling without arguments.
+	Time optimization - remove certain checks linked to preconditioner which
+	are unacceptably slow.
+	* sparse/cgs.m: New output when calling without arguments.
+	Time optimization - remove certain checks linked to preconditioner which
+	are unacceptably slow. Rename internal variable to match bicgstab.
+
+2009-05-27  Rik Wehbring  <rdrider0-list at yahoo.com>
+
+	* plot/axis.m: Update documentation to reflect addition of "tight" option.
+
+2009-05-27  Rik Wehbring  <rdrider0-list at yahoo.com>
+
+	* ismember.m: Update examples to remove incorrect reference to residue function
+
+2009-05-27  John W. Eaton  <jwe at octave.org>
+
+	* image/imwrite.m: Convert indexed images to RGB before calling
+	__magick_write__.
+
+	* image/imshow.m: In demo, convert image to rgb before scaling
+	components.  Use imread instead of loadimage.
+
+2009-05-26  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Fix rendering of overlaping images and
+	line objects. Add demos as well.
+
+2009-05-27 S�ren Hauberg  <hauberg at gmail.com>
+
+	* geometry/delaunay.m: Support cellstr's as options. 
+
+2009-05-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* plot/imshow.m: Fix handling of indexed images.
+
+2009-05-26 S�ren Hauberg  <hauberg at gmail.com>
+
+	* help/__makeinfo__.m: Support several @seealso's in one text. 
+
+2009-05-26  John W. Eaton  <jwe at octave.org>
+
+	* plot/colorbar.m: Downcase location argument.
+
+2009-05-26 Carlo de Falco  <kingcrimson at tiscali.it>
+
+	* pkg/pkg.m: Add "version" field to the structure returned by "pkg
+	describe". 
+
+2009-05-25  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Properly render TeX symbols for x11, when
+	using the anonymous fontname="*".
+
+2009-05-24 Benjamin Lindner <lindnerb at users.sourceforge.net>
+
+	* plot/gnuplot_drawnow.m: single-quote output name to allow backslash
+	characters as filesep under windows
+	* plot/print.m: Support ps->pdf using ghostscript under windows, check
+	for %GSC% environment variable.
+
+2009-05-24 Benjamin Lindner <lindnerb at users.sourceforge.net>
+
+	* plot/__gnuplot_version__.m: quote gnuplot_binary to allow spaces
+	in file name
+
+2009-05-22  John W. Eaton  <jwe at octave.org>
+
+	* general/interp3.m: Don't require interpolation grid to have same
+	size as data.  From Kris Thielemans <kris.thielemans at imperial.ac.uk>.
+
+2009-05-19 Carlo de Falco  <kingcrimson at tiscali.it>
+
+	* pkg/pkg.m: Fix a bug when quering only one non installed package
+	with "pkg describe".
+
+2009-05-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/__fdjac__.m: Support central differences.
+	* optimization/fsolve.m: Support central differences. Add FinDiffType
+	option.
+	* optimization/fminunc.m: Ditto.
+
+2009-05-17  Rik Wehbring  <rdrider0-list at yahoo.com>
+
+	* *.m: Simplify Texinfo documentation in .m scripts by removing 
+	redundant @iftex calls
+
+2009-05-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fminunc.m: Improve TR updating strategy.
+	* optimization/fsolve.m: Ditto.
+
+2009-05-15  John W. Eaton  <jwe at octave.org>
+
+	* general/nargchk.m: Don't generate error if output is struct.
+	Uncomment some additional tests.
+	From Alois Schloegl <alois.schloegl at tugraz.at>
+
+2009-05-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fminunc.m: Import the step adaptation strategy
+	improvements from fsolve.
+
+2009-05-08  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__gnuplot_has_feature__.m: Add feature "key_has_font_properties".
+	* plot/__go_draw_axes__.m: Have legend inherit the axis font-name/size.
+
+2009-05-04  Peter O'Gorman  <pogma at thewrittenword.com>
+
+	* miscellaneous/tar.m, miscellaneous/unpack.m:
+	Pass "xvf" to tar instead of "-x -v -f".
+
+2009-04-30  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__gnuplot_has_feature__.m: Change version for 
+	"x11_figure_position", >4.2.4 to >=4.3.0.
+
+2009-04-30  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: For figure position, treat 'wxt' as 'x11'.
+
+2009-04-30  Jaroslav Hajek <highegg at gmail.com>
+
+	* statistics/base/range.m: Fix behavior when dim is specified.
+
+2009-04-28  Ben Abbott <bpabbott at mac.com>
+
+	* plot/print.m: Fix typo: 'gswin23c' -> 'gswin32c'. Suppress stderr
+	when printing. New sub-function: fix_eps_bbox(). Add option, "-tight",
+	to replace the gnuplot bbox with a tight bbox for eps-files.
+
+2009-04-23  Ben Abbott <bpabbott at mac.com>
+
+	* plot/print.m: Use Ghostscript rather than ImageMagick's 'convert'.
+	Support printing to non-postscript printers. Do not change the output
+	filename when using Ghostscript. When using lpr to print the output,
+	send it without filtering (unix), or as if it were binary (pc).
+
+2009-04-22  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* general/isa.m: Correctly report multiple layers of class hierarchy.
+
+2009-04-20  John W. Eaton  <jwe at octave.org>
+
+	* special-matrix/vander.m: Update tests.
+
+2009-04-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* special-matrix/vander.m: Allow second argument.
+	* special-matrix/polyfit.m: Simplify.
+
+2009-04-17  Rik  <rdrider0-list at yahoo.com>
+
+	* plot/__marching_cube__.m: Correct help Texinfo so manual will compile
+
+2009-04-16  Marco Caliari <marco.caliari at univr.it>
+
+	* toeplitz.m: Treat separately the sparse case.
+
+2009-04-14  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* plot/__marching_cube__.m: Add help text.
+	* plot/isonormals.m: Add help text and tests.
+
+2009-04-14  David Bateman  <dbateman at free.fr>
+
+	* plot/__patch__.m: Set default facecolor to [0,1,0].
+	
+2009-04-12  Aravindh Krishnamoorthy <aravindh.k.dev at gmail.com>
+       * special-matrix/hadamard.m: Fix a documentation mistake.
+
+2009-04-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* polynomial/polyaffine.m: New function.
+	* polynomial/polyscale.m: Remove.
+	* polynomial/polytrans.m: Remove.
+
+2009-04-12  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__gnuplot_open_stream__.m: New function.
+	* plot/__gnuplot_get_var__.m: If not open, open the gnuplot plot stream.
+	* plot/gnuplot_drawnow.m: Replace internal function open_gnuplot_stream
+	with new __gnuplot_open_stream__.
+
+2009-04-11  David Bateman  <dbateman at free.fr>
+
+	* geometry/trisurf.m: New file.
+	* geometry/Makefile.in (SOURCES): Add it here.
+	* geometry/trimesh.m: Convert to using 3D patches.
+	* plot/__go_draw_axes__.m: Allow 3D filled triangular patches.
+	* plot/__patch__.m: Rewrite to allow update of dependent variables
+	with listener functions amongst themselves.
+	* plot/patch.m: Add 3D demo. Update the documentation.
+
+2009-04-11  Martin Helm  <martinh at sirius.mhelm.de>
+
+	* plot/__interp_cube__.m, plot/__marching_cube__.m, isocolors.m,
+	isonnormals.m, isosurface.m: New files.
+	* plot/Makefile.in (SOURCES): Add them here.
+
+2009-04-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* set/intersect.m: Add missing branch.
+
+2009-04-10  Ben Abbott <bpabbott at mac.com>
+
+	* plot/print.m: If no pdf support in gnuplot, then "convert" from
+	postscript to pdf. For gnuplot 4.2.x use "convert", if it is present,
+	to produce pdf output. Only render a full page for ps/pdf output.
+	Rename variable, "size" to "canvas_size". Reformat help text to
+	eliminate unintended spaces. Minor improvements to the code.
+	* plot/gnuplot_drawnow.m: Place canvas size at the end of the terminal
+	spec, and remove trailing semicolon. Minor improvments to the code.
+	* plot/__gnuplot_get_var__.m: If fifo fails to open, try 2nd time.
+
+2009-04-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* special-matrix/vander.m: Optimize.
+
+2009-04-07  Ben Abbott <bpabbott at mac.com>
+
+	* plot/Makefile.in: Remove __gnuplot_default_font__.m from SOURCES.
+
+2009-04-06  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__gnuplot_get_var__.m: Correct misleading error messages, and
+	remove dangling/commented code.
+	* plot/__gnuplot_default_font__.m: Remove file from archive.
+	* plot/__go_draw_axes__.m, plot/__go_draw_figure__.m: Allow
+	fontsize to be specified for all terminals with fontname == "*".
+
+2009-04-06  Jaroslav Hajek <highegg at gmail.com>
+
+	* polynomial/polyscale.m: New function.
+	* polynomial/polytrans.m: New function.
+
+2009-04-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* special-matrix/pascal.m: Fix, optimize & extend.
+
+2009-04-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/vech.m: Optimize.
+
+2009-04-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* special-matrix/toeplitz.m: Optimize.
+
+2008-04-03  David Bateman  <dbateman at free.fr>
+
+	* plot/__scatter__.m: correct indexing of cdata.x
+
+2009-04-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fminunc.m: New function.
+	* optimization/Makefile.in: Update.
+	* optimization/__dogleg__: Allow general quadratics.
+
+2009-04-02  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Include gnuplot command termination when
+	plotting image.
+
+2009-04-02  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Fix title placement for gnuplot 4.2.x.
+
+2009-04-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Fix test.
+
+2009-03-30  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: New subfunction create_fontspec(). Allow
+	fontsize to be specified when the fontname is anonymous.
+
+2009-03-30  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__gnuplot_default_font__.m: New function: determine gnuplot's
+	terminal dependent default font.
+	* plot/__go_draw_figure__.m: Substitute gnuplot default font when
+	"fontname" = "*".
+
+2009-03-29  John W. Eaton  <jwe at octave.org>
+
+	* testfun/Makefile.in (SOURCES): Add rundemos.m to the list.
+
+2009-03-29  Ben Abbott <bpabbott at mac.com>
+
+	* plot/print.m: For eps output the bounding box should represent the
+	figure's position.
+
+2009-03-28  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Always set figure property "__plot_stream__"
+	to the active gnuplot steam. Permits __gnuplot_get_var__ to return to
+	proper result for all gnuplot streams.
+
+2009-03-27  Ben Abbott <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Properly position the title for 3D plots
+	when using the gnuplot (v4.3+) backend.
+
+2009-03-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/expm.m: Fix order of outputs from balance.
+
+2009-03-25  Kai Habel  <kai.habel at gmx.de>
+
+	* general/gradient.m: Fix calculation for more than two
+	dimensions.  Change interpretation of vector arguments from
+	spacing to coordinates.  New tests.
+
+2009-03-25  John W. Eaton  <jwe at octave.org>
+
+	* mkdoc: Pass full file name to gethelp.
+	* gethelp.cc (main): Handle second argument.  Write comment with
+	full file name to output.
+
+2009-03-24  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: When printing, pass scalar plot_stream
+	to __gnuplot_draw_figure__, and close all plot streams when done.
+
+2009-03-24  John W. Eaton  <jwe at octave.org>
+
+	* general/isa.m: Handle parent classes.
+
+2009-03-23  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Check that gnuplot has internal variable
+	"GPVAL_TERMINALS".
+	* plot/__gnuplot_has_feature__.m: Add "variable_GPVAL_TERMINALS".
+
+2009-03-21  Ben Abbott <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Verify the gnuplot terminal is supported.
+	* plot/__gnuplot_get_var__.m: Add function to get gnuplot variables.
+	* plot/print.m: Restore the behavior for option -S<num>,<num>.
+
+2009-03-19  Jaroslav Hajek <highegg at gmail.com>
+
+	* optimization/fsolve.m (guarded_eval): Simplify & fix missing
+	semicolon.
+
+2009-03-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/__fdjac__.m: Pass in fvec to save one evaluation.
+	* optimization/fsolve.m: Avoid redundant reevaluation when using
+	FD jacobians. Document how it can be done with user jacobians.  Make
+	first iteration special and call outputfcn after it. Skip updates
+	unless two successful iterations have occured.
+	* optimization/__dogleg__.m: Add missing alpha in the zero-gradient
+	case.
+	* optimization/fsolve.m: Remove autodg (not used), simplify.
+
+2009-03-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* statistics/base/var.m: a -> x.
+
+2009-03-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* statistics/base/mean.m: Simplify.
+	* statistics/base/meansq.m: Optimize.
+	* statistics/base/center.m: Fix behvaior with vectors, simplify.
+	* statistics/base/std.m: Simplify using `center'.
+	* statistics/base/var.m: Ditto.
+	* statistics/base/cov.m: Ditto.
+
+2009-03-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/repmat.m: Use subscript pairs rather than forming Kronecker
+	products.
+
+2009-03-11  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Unset the {x,y,z}ticks when initializing
+	each axis. Set ticklabels when the ticklabels are empty and when
+	ticklabelmode=="manual".
+
+2009-03-11  Marco Caliari  <marco.caliari at univr.it>
+
+	* plot/axis.m: Implement "square" and "equal" options, conditional
+	on how octave positions gnuplot axes. Place the "title()" and
+	"axis()" commands after "plot()" in the demos.
+
+2009-03-09  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m (do_tics): Fix typo (xaxislocation ->
+	yaxislocation).
+
+2009-03-09  John W. Eaton  <jwe at octave.org>
+
+	* help/lookfor.m (search_cache): Also match function names.
+
+	* pkg/pkg.m, help/gen_doc_cache.m, help/lookfor.m:
+	Use doc-cache instead of DOC for doc cache file.
+
+2009-03-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/accumarray.m: Reorder tests. Call either "sparse" or
+	__accumarray_sum__ for the default summation case.
+	* statistics/base/histc.m: Reimplement using lookup & accumarray.
+
+2009-03-08  S�ren Hauberg <hauberg at gmail.com>
+
+	* statistics/base/histc.m: New function.
+
+2009-03-06  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Preserve the order of axes' children
+	when pruning the handles for the {x,y,z}labels and title.
+	* plot/legend.m: Change demo to add colors to lines. This change
+	reveals the problem (above) with the ordering of the axes' children.
+
+2009-03-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/condest.m: Use lu rather than splu. Use relative tols
+	for tests.
+
+2009-03-05  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/spdiag.m: Ensure sparse result.
+
+2009-03-05  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Preserve column vector orientation for
+	the axes children while removing the axis label & title handles.
+
+2009-03-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* polynomial/polyval.m: Implement using Horner scheme.
+
+2009-03-03  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Fix unintended shift of plot image for
+	the gnuplot postscript+eps terminal.
+
+2009-03-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pkg/pkg.m (fix_depends): Fix & simplify splitting the string.
+
+2009-03-02  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* set/complement.m, set/union.m: Remove reference to deprecated
+	function create_set.
+
+2009-03-01  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Do not render axis labels twice when
+	their handles are visible, but do render objects with hidden
+	handles.
+
+2009-03-01  Ben Abbott  <bpabbott at mac.com>
+
+	* general/num2str.m: Trivial bug fix. Recent switch from split()
+	to strsplit() produced cells rather than character data.
+
+2009-03-01  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/colorbar.m: Bug fix. Allow hidden colorbars to be deleted,
+	and replace existing colorbar when a new one is created. Additional
+	demos are included to verify these behaviors.
+
+2009-02-28  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__actual_axis_position__.m: Include file missed in prior
+	changeset.
+
+2009-02-28  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/print.m, plot/gnuplot_drawnow.m: Add compatible support for
+	specificying resolution of bitmap terminals, "-r<num>".
+
+	* plot/gnuplot_drawnow.m: Check that canvas size is only specified
+	one time.
+
+	* plot/gnuplot_drawnow.m, plot/__go_draw_figure__.m: Support papersize,
+	paperposition properties. Accommodate gnuplot's implicit margins for
+	postscript terminals. Remove internal function get_canvassize().
+
+	* plot/gnuplot_drawnow.m:
+	Terminate gnuplot "set term ..." with semicolon.
+	Specify vector terminals sizes in floating point.
+	Rename internal function isbackend() to output_to_screen().
+	Rename internal function gnuplot_term() to gnuplot_default_term().
+	Rename internal function isbitmap() to term_units_are_pixels().
+	Minor changes for coding conventions.
+
+	* plot/__actual_axis_position__.m, Makefile.in: New function to
+	determine position of rendered axes, including the effect of the
+	aspect ratio.
+	* plot/__gnuplot_has_feature__.m: Add new feature
+	"screen_coordinates_for_{lrtb}margin".
+	* plot/__go_draw_axes__.m, plot/colorbar.m: Enable axes to be positioned
+	using {lrtb}margins.
+	* plot/colorbar.m: Add to, and modify, demos.
+
+	* plot/print.m: Remove non-functional/commented code.
+	* plot/__go_draw_figure__.m: Remove non-functional code.
+	* plot/__gnuplot_has_feature__.m: Remove non-functional code.
+
+	* plot/quiver3.m: Add "clf" and "colormap(jet(64))" to demo.
+
+2009-02-27  John W. Eaton  <jwe at octave.org>
+
+	* set/complement.m: Call unique, not create_set.
+	* set/unique.m: Style fix for docstring.
+	* deprecated/create_set.m: Move here from set/create_set.m.
+	Always return a row vector, as documented.
+
+	* set/Makefile.in (SOURCES): Remove create_set.m from the list.
+	* deprecated/Makefile.in (SOURCES): Add create_set.m to the list.
+
+	* general/num2str.m: Call strsplit instead of split.
+
+	* strings/strsplit.m: Style fixes.
+
+2009-02-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* strings/strsplit.m: Check also nargin.
+
+2009-02-26  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/split.m: Add warning, not about version.
+
+2009-02-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* strings/strsplit.m: New function.
+	* strings/split.m: Move to deprecated/.
+	* strings/Makefile.in: Update.
+	* deprecated/Makefile.in: Update.
+
+	* general/int2str.m: Use strsplit instead of split.
+	* general/num2str.m: Ditto.
+	* help/__makeinfo__.m: Ditto.
+	* help/lookfor.m: Ditto.
+	* miscellaneous/compare_versions.m: Ditto.
+	* miscellaneous/tar.m: Ditto.
+	* miscellaneous/unpack.m: Ditto.
+	* miscellaneous/what.m: Ditto.
+	* miscellaneous/zip.m: Ditto.
+	* pkg/pkg.m: Ditto.
+	* strings/strtok.m: Ditto.
+	* testfun/rundemos.m: Ditto.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (distclean maintainer-clean): Remove tags and TAGS
+	in distclean target.
+
+2009-02-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* help/lookfor.m: Vectorize the path splitting using mat2cell.
+	Extract new path elements using setdiff.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/pie.m: Use numel to check sizes of X and LABELS instead of
+	using size_equal.  From Andy Buckle <andybuckle at gmail.com>.
+
+	* help/lookfor.m: Split original path into cell array and compare
+	elements with strcmp.  Suppress warnings and errors when getting
+	help text from function files.
+
+2009-02-24  John W. Eaton  <jwe at octave.org>
+
+	* help/gen_doc_cache.m: Don't compress output file.  By default,
+	write to DOC, not DOC.gz.  Don't save empty cache.
+
+	* help/lookfor.m: Use doc_cache_file to get location of DOC file.
+
+2009-02-24  Jason Riedy  <jason at acm.org>
+
+	* pkg/pkg.m (generate_lookfor_cache): Generate a DOC file for each
+	directory.
+
+	* help/gen_doc_cache.m: Call __makeinfo__, not makeinfo.
+
+2009-02-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Update niter after each iteration, not just
+	a succesful one.
+
+2009-02-08  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* configure.in: AC_SUBST ac_config_files
+
+	* Makefile.in:  Add make targets for configuration files
+	and config.status.
+
+2009-02-23  John W. Eaton  <jwe at octave.org>
+
+	* plot/fplot.m: Fix nargin check.
+	From Joel Parker <Joel.Parker at radiancetech.com>.
+
+2009-02-20  Steffen Groot  <steffen.groot at technolution.eu>
+
+	* plot/__patch__.m: Correct indexing of varargin.
+
+2009-02-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/dmult.m: Remove.
+	* linear-algebra/Makefile.in: Update.
+	* deprecated/dmult.m: Move here; revert to the 3.0.x version.
+	* deprecated/Makefile.in: Update.
+	* statistics/models/logistic_regression_derivatives.m: Replace dmult
+	by diagonal matrices.
+
+2009-02-19  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Only send figure position info to gnuplot
+	when the plot stream is first opened. Revert usage of hidden axes 
+	to store prior figure "position" property.
+
+2009-02-19  John W. Eaton  <jwe at octave.org>
+
+	* general/__isequal__.m, general/__splinen__.m, image/__img__.m,
+	image/__img_via_file__.m, miscellaneous/__xzip__.m,
+	optimization/__all_opts__.m, optimization/__dogleg__.m,
+	optimization/__fdjac__.m, path/__extractpath__.m,
+	plot/__add_datasource__.m, plot/__area__.m,
+	plot/__axes_limits__.m, plot/__axis_label__.m, plot/__bar__.m,
+	plot/__bars__.m, plot/__clabel__.m, plot/__contour__.m,
+	plot/__default_plot_options__.m, plot/__errcomm__.m,
+	plot/__errplot__.m, plot/__ezplot__.m,
+	plot/__gnuplot_has_feature__.m, plot/__gnuplot_version__.m,
+	plot/__go_close_all__.m, plot/__go_draw_axes__.m,
+	plot/__go_draw_figure__.m, plot/__line__.m,
+	plot/__next_line_color__.m, plot/__patch__.m, plot/__plr1__.m,
+	plot/__plr2__.m, plot/__plt1__.m, plot/__plt2__.m,
+	plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m,
+	plot/__plt2sv__.m, plot/__plt2vm__.m, plot/__plt2vs__.m,
+	plot/__plt2vv__.m, plot/__plt__.m, plot/__plt_get_axis_arg__.m,
+	plot/__pltopt1__.m, plot/__pltopt__.m, plot/__quiver__.m,
+	plot/__scatter__.m, plot/__stem__.m, startup/__finish__.m,
+	statistics/base/__quantile__.m: Consistent doc strings for
+	internal fucntions.
+
+2009-02-18  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/subplot.m: Fix unintended deletion of axes.
+
+2009-02-18  Frederick Umminger  <Frederick_Umminger at playstation.sony.com>
+
+	* audio/wavread.m: Improve search for data chunks.
+
+2009-02-18  Ivan Sutoris  <ivan.sutoris at gmail.com>
+
+	* miscellaneous/edit.m: Expand documentation about editor mode.
+
+2009-02-18  John W. Eaton  <jwe at octave.org>
+
+	* plot/__gnuplot_version__.m: Don't use regexp to extract version
+	number.
+
+2009-02-18  John W. Eaton  <jwe at octave.org>
+
+	* plot/gnuplot_drawnow.m (gnuplot_set_term):
+	Adjust nargin checks for new signature.
+
+2009-02-17  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/contourc.m: Convert demo to test.
+	* plot/surfnorm.m: Add another demo.
+	* plot/surfnorm.m, plot/pareto.m: Add "colormap(jet)" to 1st demo.
+	* plot/plotyy.m, plot/patch.m, plot/pareto.m, plot/legend.m,
+	plot/fill.m, plot/comet.m, plot/colorbar.m, plot/clabel.m:
+	Replace "close all" with "clf" in demo.
+
+2009-02-17  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Only close the gnuplot window and send
+	position/size info when the figure's position property has changed.
+	(gnuplot_set_term): New arg, NEW_STREAM.  Change all uses.
+	(open_gnuplot_stream): Delete unused output ENHANCED.
+
+2009-02-17  John W. Eaton  <jwe at octave.org>
+
+	* plot/plotyy.m: Handle case of existing figure with no axes.
+
+2009-02-16  John W. Eaton  <jwe at octave.org>
+
+	* help/__makeinfo__.m: Rename from help/makeinfo.m.  Delete tmp file.
+	* help/Makefile.in (SOURCES): Add __makeinfo__.m, delete makeinfo.m.
+	* help/get_first_help_sentence.m, help/help.m, help/lookfor.m,
+	help/print_usage.m: Call __makeinfo__ instead of makeinfo.
+	* help/__strip_html_tags__.m, help/__additional_help_message__.m:
+	Doc fix.
+
+2009-02-16  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/shading.m: No new figure windows for the demos.
+	* plot/surfl.m: Clear figure before running demos.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/expm.m: Fix invalid unscaling.
+	* help/which.m: Do not add "function" here.
+	* optimization/fsolve.m: Update comments.
+
+2009-02-16  John W. Eaton  <jwe at octave.org>
+
+	* help/help.m: Shorten default help text.
+
+2009-02-15  John W. Eaton  <jwe at octave.org>
+
+	* help/doc.m, help/help.m, help/lookfor.m, help/type.m,
+	help/which.m, image/colormap.m, miscellaneous/delete.m,
+	miscellaneous/dir.m, miscellaneous/edit.m,
+	miscellaneous/intwarning.m, miscellaneous/ls.m,
+	miscellaneous/mex.m, miscellaneous/mkoctfile.m,
+	miscellaneous/run.m, miscellaneous/what.m, path/savepath.m,
+	pkg/pkg.m, plot/axis.m, plot/box.m, plot/caxis.m, plot/cla.m,
+	plot/close.m, plot/colorbar.m, plot/grid.m, plot/hidden.m,
+	plot/hold.m, plot/legend.m, plot/orient.m, plot/print.m,
+	plot/shading.m, plot/title.m, plot/xlabel.m, plot/ylabel.m,
+	plot/zlabel.m, testfun/demo.m, testfun/example.m, testfun/fail.m,
+	testfun/rundemos.m, testfun/test.m:
+	Delete "PKG_ADD: mark_as_command" directive.
+
+	* scripts/edit.m: Avoid command-style function call syntax when
+	assigning results in tests.
+
+	* deprecated/mark_as_rawcommand.m, deprecated/unmark_rawcommand.m,
+	deprecated/israwcommand.m, deprecated/mark_as_command.m,
+	deprecated/unmark_command.m, deprecated/iscommand.m:
+	New functions.
+	* deprecated/Makefile.in (SOURCES): Add them to the list.
+
+2009-02-15  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/subplot.m: Compatible placement of subplots.
+
+2009-02-13 Ben Abbott  <bpabott at mac.com>
+
+	* plot/__go_draw_axes__.m: Respect axes ticklength property.
+
+2009-02-12  John W. Eaton  <jwe at octave.org>
+
+	* general/sortrows.m: Call __sort_rows_idx__, not __sortrows_idx__.
+
+2009-02-12  Soren Hauberg  <hauberg at gmail.com>
+
+	* help/gen_doc_cache.m: Change API so we only handle one directory per
+        call to this function.
+
+2009-02-12  Soren Hauberg  <hauberg at gmail.com>
+
+	* help/lookfor.m: Adapt to new cache scheme.
+
+2009-02-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/sortrows.m: Employ __sortrows_idx__ when applicable,
+	gripe for sparse matrices.
+
+2009-02-11  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/news.m: Look in octetcdir for NEWS file.
+
+2009-02-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/interp2.m: Added support for pchip bicubic interpolation.
+	Also simplified code and added support for natural extrapolation via
+	"extrap".
+
+2009-02-09  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/Makefile.in (SOURCES): Include __xzip__.m in the list.
+
+	* testfun/rundemos.m: Error if fopen fails.
+
+2009-02-08  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (install install-strip): Don't install ls-R file.
+	(uninstall): Don't uninstall ls-R file.
+
+2009-02-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Document support for complex holomorphic
+	systems. Improve guarded evaluation.
+
+2009-02-05  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/news.m: Use puts instead of printf.
+
+2009-02-05  Thomas D. Dean  <tomdean at speakeasy.org>
+
+	* polynomial/polyout.m: Replace com2str with num2str, and minor
+	style changes.
+
+2009-02-04  John W. Eaton  <jwe at octave.org>
+
+	* help/which.m: Still print something sensible if type is empty.
+
+2009-02-04  Soren Hauberg  <hauberg at gmail.com>
+            Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* miscellaneous/Makefile.in (SOURCES): Add bzip2.m to the list.
+
+2009-02-04  Frederick Umminger  <Frederick_Umminger at playstation.sony.com>
+
+	* signal/freqz.m: Ensure causal phase response.
+	Handle long input correctly.
+
+2009-02-04  Petr Mikulik  <mikulik at physics.muni.cz>
+
+	* plot/__go_draw_axes__.m: Pass "interpolate 0, 0" to gnuplot
+	instead of "interpolate 4, 4".
+
+2009-02-04  John W. Eaton  <jwe at octave.org>
+
+	* audio/wavwrite.m, deprecated/splu.m, general/bitcmp.m,
+	general/fliplr.m, general/flipud.m, general/genvarname.m,
+	general/nargchk.m, general/nargoutchk.m, general/quadgk.m,
+	general/rot90.m, geometry/griddata.m, geometry/rectint.m,
+	geometry/voronoi.m, geometry/voronoin.m,
+	help/__strip_html_tags__.m, image/brighten.m, image/imfinfo.m,
+	image/imread.m, linear-algebra/cond.m, linear-algebra/condest.m,
+	linear-algebra/dmult.m, linear-algebra/dot.m,
+	linear-algebra/expm.m, linear-algebra/housh.m,
+	linear-algebra/onenormest.m, linear-algebra/subspace.m,
+	miscellaneous/compare_versions.m, optimization/__all_opts__.m,
+	optimization/optimget.m, pkg/pkg.m, plot/__bar__.m,
+	plot/__plr2__.m, plot/ribbon.m, plot/slice.m, polynomial/pchip.m,
+	polynomial/roots.m, set/unique.m, signal/fractdiff.m,
+	signal/hurst.m, specfun/beta.m, specfun/legendre.m,
+	statistics/base/__quantile__.m, statistics/base/quantile.m,
+	statistics/tests/cor_test.m,
+	statistics/tests/kolmogorov_smirnov_test_2.m, strings/base2dec.m,
+	strings/dec2base.m, strings/strcat.m, strings/validatestring.m,
+	time/addtodate.m: Style fixes.
+
+2009-02-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: remove redundant line.
+
+2009-02-03  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* optimization/Makefile.in: Add missing source.
+
+2009-02-02  Rob Mahurin <rob at utk.edu>
+
+	* general/interpft.m: Increase tolerance in tests, for FFTPACK.
+	
+2009-02-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/__all_opts__.m: Yield empty list in recursive calls.
+	mlock to avoid unloading.
+
+2009-01-30  John W. Eaton  <jwe at octave.org>
+
+	* optimization/PKG_ADD: Delete.
+	* optimization/fsolve.m, optimization/fzero.m,
+	optimization/lsqnonneg.m: Use PKG_ADD: comment to call __all_opts__.
+
+2009-01-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/__all_opts__.m: New source.
+	* optimization/optimset.m: Implement checking for registered options.
+	* optimization/optimget.m: Ditto.
+	* optimization/fsolve.m: Fix misspelled option.
+	* optimization/PKG_ADD: New startup file.
+
+2009-01-30  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/__go_draw_axes__.m: Add support for transparent surfaces.
+	* plot/__gnuplot_has_feature__.m: Add feature 'transparent_surface',
+	Require gnuplot 4.3 for transparent patches and surfaces.
+
+2009-01-30  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* time/datestr.m: Convert YYYY to %Y instead of %C%y.
+	Convert [Dd][Dd] to %d instead of %e.
+
+2009-01-30  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/print.m: Use __gnuplot_has_feature__ instead of
+	compare_versions.
+
+	* plot/gnuplot_drawnow.m: Respect x11 figure position property.
+
+2009-01-29  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/fileparts.m: Match all possible file separators.
+
+2009-01-29  Kai Habel <kai.habel at gmx.de>
+
+        * plot/__go_draw_axes__.m: Add support for transparent patches.
+
+2009-01-29  S�ren Hauberg  <hauberg at gmail.com>
+
+	* help/help.m, help/print_usage.m, help/get_first_help_sentence.m:
+	print sensible error message when function is found but not documented.
+
+	* help/help.m: Allow displaying 'Contents.m' files.
+
+2009-01-29  Kai Habel <kai.habel at gmx.de>
+
+        * plot/Makefile.in (SOURCES): Include diffuse.m, specular.m, and
+	surfl.m in the list.
+
+2009-01-28  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Style fixes.
+
+	* plot/__gnuplot_has_feature__.m: New file, checks for supported
+	feature.
+
+2009-01-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Don't use pivoting at all (for the time
+	being).
+
+2009-01-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Use more adaptive rescaling.
+	Put back the default tolerances based on machine eps respecting
+	the used precision. Partially reflect this in the default optimset
+	values.
+
+2009-01-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* miscellaneous/ordefields.m: Use indexed assignment instead of a
+	loop. Fix for multidimensional cases.
+
+2009-01-27  John W. Eaton  <jwe at octave.org>
+
+	* general/arrayfun.m, image/imwrite.m, plot/axis.m, plot/clf.m,
+	plot/ribbon.m, plot/gnuplot_drawnow.m, plot/cla.m, set/unique.m:
+	Use endif or endfor instead of "end".
+
+	* path/savepath.m: Call command_line_path instead of commandlinepath.
+
+2009-01-27  Jason Riedy  <jason at acm.org>
+
+	* miscellaneous/orderfields.m: Really fix the indexing for struct
+	arrays.
+
+2009-01-27  Carlo de Falco  <kingcrimson at tsicali.it>
+
+	* polynomial/spline.m: Doc fix.
+
+2009-01-27  S�ren Hauberg  <hauberg at gmail.com>
+
+	* general/gradient.m: Handle computing the gradient of a function
+	handle.
+
+2009-01-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/lsqnonneg.m: Reimplement using QR updating for
+	square and overdetermined systems.
+
+2009-01-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Provide default values on request.
+	Adjust some defaults.
+	* optimization/fzero.m: Ditto.
+	* optimization/optimset.m: Query optimal values via the M*b way.
+
+2009-01-26  Jason Riedy  <jason at acm.org>
+
+	* miscellaneous/orderfields.m: Also avoid loop for non-empty structs.
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Disable Broyden updates for sparse jacobians.
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/__fsolve_defopts__.m: Remove.
+	* optimization/Makefile.in: Reflect change.
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/__fdjac__.m: Fix setting up h.
+	* optimization/fsolve.m: Allow underdetermined systems. Use QR for
+	large enough square and overdetermined systems, with pivoting in the
+	first step. Simplify options. Adjust defaults - make TR radius
+	tolerance less stringent. Support DisplayFcn.
+
+2008-12-24 Ben Abbott  <bpabbott at mac.com>
+
+	* path/savepath.m: Respect cmd-line and env paths.
+
+2009-01-24 Ben Abbott  <bpabbott at mac.com>
+
+	* sparse/svds.m: svds.m: skip tests if ARPACK is missing.
+
+2009-01-23  S�ren Hauberg  <hauberg at gmail.com>
+
+	* help/type.m: Make 'type X' work, when X is the name of a variable.
+
+2009-01-22  John W. Eaton  <jwe at octave.org>
+
+	* help/which.m: New function.
+	* help/Makefile.in (SOURCES): Add it to the list.
+
+	* help/help.m: Also display location of the file before the help text.
+	* help/print_usage: Also display additional help text.
+	* help/__additional_help_message__.m: Return message instead of
+	displaying it.
+
+2009-01-22  S�ren Hauberg  <hauberg at gmail.com>
+
+	* help: New directory.
+	* configure.in (AC_CONFIG_FILES): Add help/Makefile to the list.
+	* Makefile.in (SUBDIRS): Add it to the list.
+	* help/__additional_help_message__.m, help/__strip_html_tags__.m,
+	help/gen_doc_cache.m, help/get_first_help_sentence.m, help/help.m,
+	help/lookfor.m, help/makeinfo.m, help/print_usage.m, help/type.m:
+	New functions.
+	* help/Makefile.in (SOURCES): Add them to the list.
+	* help/doc.m: Move here from miscellaneous/doc.m.
+	* miscellaneous/Makefile.in (SOURCES): Remove doc.m from the list.
+	* miscellaneous/pkg.m: Generate documentation cache during install.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Undo the last change.
+
+2009-01-18  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* miscellaneous/doc.m: Add test for existence of info file.
+	
+2009-01-21  John W. Eaton  <jwe at octave.org>
+
+	* plot/__axis_label__.m: Set properties in existing axis label
+	object instead of creating a new text object.
+	* plot/ylabel.m: Don't set rotation property here.
+	* plot/title.m: Don't set horizontalalignment property here.
+
+	* plot/ylabel.m: Insert rotation property in varargin before
+	passing it on to __axis_label__.
+	* plot/__axis_label__.m: Don't set rotation for ylabel here.
+
+	* plot/title.m: Insert horizontalalignment property in varargin
+	before passing it on to __axis_label__.
+
+2009-01-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* strings/strchr.m: New function.
+	* strings/Makefile.in: Add it.
+
+2009-01-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Only use qrupdate if available.
+
+2009-01-20  John W. Eaton  <jwe at octave.org>
+
+	* general/postpad.m: Doc fix.
+	* general/prepad.m: Doc fix.
+	* image/pink.m: Spelling fix.
+	* image/hsv.m: Doc fix.
+	From Francesco Potorti` <Potorti at isti.cnr.it>.
+
+	* testfun/assert.m: Use isfield instead of struct_contains.
+
+2009-01-17 Ben Abbott  <bpabbott at mac.com>
+
+	* general/cart2sph.m, cart2pol.m, sph2cart.m pol2cart.m:
+	Permit scalars when transforming coordinates.
+
+2009-01-17  Steven Verstoep <isgoed at hotmail.com>
+
+	* plot/__quiver__.m: __quiver__.m: Fix auto-size of (x,y) coord.
+
+2009-01-16  Daniel J Sebald <daniel.sebald at ieee.org>
+
+	* plot/gnuplot_drawnow.m: Fix for handling options.
+
+2009-01-16  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/legend.m: Fix legend order for both horizontal and
+	vertical string cell.
+
+2008-01-15  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/grid.m: Document handle argument.
+
+2009-01-15  Peter L. S�ndergaard  <peter at sonderport.dk>
+
+	* general/nargoutchk.m: Doc fix.
+	* general/nargchk.m: Improve compatibility.  New tests.
+
+2008-01-15  Rafael Laboissiere  <rafael at debian.org>
+
+	* gethelp.cc: Include <cstdio>.
+
+2009-01-14  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m (ticklabel_to_cell): New function.
+	Use it to handle non-cell ticklabels.
+
+2009-01-14  S�ren Hauberg  <hauberg at gmail.com>
+
+	* general/diff.m, general/logspace.m, general/nextpow2.m,
+	linear-algebra/commutation_matrix.m,
+	linear-algebra/duplication_matrix.m, linear-algebra/expm.m,
+	miscellaneous/bincoeff.m, miscellaneous/list_primes.m,
+	optimization/fsolve.m, plot/subplot.m, polynomial/pchip.m,
+	polynomial/polyout.m, polynomial/residue.m, polynomial/spline.m,
+	signal/freqz.m, signal/sinc.m, specfun/beta.m, specfun/betaln.m,
+	specfun/nchoosek.m, specfun/pow2.m, special-matrix/hankel.m,
+	special-matrix/hilb.m, special-matrix/invhilb.m
+	special-matrix/sylvester_matrix.m, special-matrix/toeplitz.m,
+	special-matrix/vander.m, statistics/base/gls.m,
+	statistics/base/kendall.m, statistics/base/kurtosis.m,
+	statistics/base/mean.m, statistics/base/median.m,
+	statistics/base/ols.m, statistics/base/skewness.m,
+	statistics/distributions/kolmogorov_smirnov_cdf.m:
+	Use ifnottex instead of ifinfo.
+
+2009-01-14  John W. Eaton  <jwe at octave.org>
+
+	* linear-algebra/expm.m: 
+
+	* optimization/fsolve.m: Doc fix.
+
+	* plot/__go_draw_axes__.m: Scale markersize by 1/3, not 1/6.
+
+	* io/dlmwrite.m: Use '%c' format for character data.
+
+2009-01-13  John W. Eaton  <jwe at octave.org>
+
+	* general/repmat.m: Handle negative row or column dimension.
+
+	* elfun/lcm.m, general/accumarray.m, general/bicubic.m,
+	general/cellidx.m, general/cplxpair.m, general/dblquad.m,
+	general/gradient.m, general/interp1.m , general/pol2cart.m,
+	general/quadgk.m, general/quadv.m, general/repmat.m,
+	general/structfun.m, geometry/griddata.m, geometry/inpolygon.m,
+	image/brighten.m, image/hsv2rgb.m, image/imread.m,
+	image/imwrite.m, linear-algebra/dmult.m,
+	linear-algebra/onenormest.m, miscellaneous/getfield.m,
+	miscellaneous/setfield.m, miscellaneous/what.m,
+	optimization/fsolve.m, optimization/fzero.m,
+	optimization/lsqnonneg.m, optimization/qp.m, pkg/pkg.m,
+	plot/__area__.m, plot/__clabel__.m, plot/__stem__.m, plot/axis.m,
+	plot/colorbar.m, plot/contour3.m, plot/findall.m, plot/findobj.m,
+	plot/fplot.m, plot/grid.m, plot/hist.m, polynomial/convn.m,
+	polynomial/polyreduce.m, set/intersect.m, set/setxor.m,
+	set/union.m, signal/arch_fit.m, signal/durbinlevinson.m,
+	signal/fftshift.m, signal/freqz_plot.m, signal/ifftshift.m,
+	signal/spectral_adf.m, sparse/bicgstab.m, sparse/cgs.m,
+	sparse/gplot.m, sparse/normest.m, sparse/pcg.m, sparse/pcr.m,
+	sparse/spy.m, sparse/svds.m, sparse/treelayout.m,
+	sparse/treeplot.m, specfun/primes.m, special-matrix/hadamard.m,
+	statistics/base/center.m, statistics/base/quantile.m,
+	statistics/base/ranks.m, statistics/base/std.m,
+	statistics/distributions/hygepdf.m,
+	statistics/tests/kruskal_wallis_test.m, strings/index.m,
+	strings/mat2str.m, strings/str2double.m, strings/strrep.m,
+	testfun/assert.m, testfun/example.m, testfun/fail.m,
+	testfun/speed.m, testfun/test.m: Style fixes.
+
+	* audio/wavread.m, general/__splinen__.m, general/bicubic.m,
+	general/rat.m, linear-algebra/expm.m, linear-algebra/krylov.m,
+	linear-algebra/onenormest.m, miscellaneous/edit.m,
+	optimization/__dogleg__.m, pkg/pkg.m, plot/__errplot__.m,
+	plot/__go_draw_axes__.m, plot/__stem__.m, plot/findobj.m,
+	set/ismember.m, signal/arma_rnd.m, signal/freqz.m, signal/stft.m,
+	sparse/pcg.m, sparse/sprandsym.m, sparse/treelayout.m,
+	specfun/factor.m, specfun/nchoosek.m, specfun/primes.m,
+	statistics/base/quantile.m, statistics/base/values.m,
+	strings/findstr.m, strings/str2double.m, strings/strrep.m,
+	testfun/assert.m, testfun/fail.m, testfun/speed.m, testfun/test.m,
+	time/datestr.m, time/datevec.m: Comment style fixes.
+
+2009-01-13  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* set/unique.m: Fix for vertical array inputs.
+
+2009-01-12  John W. Eaton  <jwe at octave.org>
+
+	* optimization/fzero.m, optimization/fsolve.m: Style fixes.
+	Use strcmpi to compare options.
+
+2009-01-12  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* strings/strvcat.m: Remove.
+	* strings/Makefile.in (SOURCES): Remove strvcat.m.
+	
+2009-01-12  John W. Eaton  <jwe at octave.org>
+
+	* plot/diffuse.m, plot/surfl.m, plot/specular.m: Style fixes.
+
+2009-01-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/sortrows.m: Fix invalid `{x:y} = z' assignment.
+	* miscellaneous/orderfields.m: Ditto.
+	* miscellaneous/what.m: Ditto.
+	* pkg/pkg.m: Ditto.
+	* plot/ndgrid.m: Ditto.
+	* strings/strcat.m: Ditto.
+
+2009-01-09  Kai Habel <kai.habel at gmx.de>
+
+        * plot/surfl.m: New function
+        * plot/diffuse.m: Ditto.
+        * plot/specular.m: Ditto.
+
+2009-01-05  John W. Eaton  <jwe at octave.org>
+
+	* mkdoc: Set defaults for FIND and PERL.  Check usage.
+
+2009-01-01  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* miscellaneous/__xzip__.m: Fix error messages, add tests.
+	
+2008-12-26  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* general/int2str.m, general/num2str.m, strings/base2dec.m,
+	strings/blanks.m, strings/cstrcat.m, strings/findstr.m,
+	strings/isstrprop.m, strings/mat2str.m, strings/regexptranslate.m,
+	strings/split.m, strings/str2double.m, strings/str2num.m,
+	strings/strcat.m, strings/strcmpi.m, strings/strfind.m,
+	strings/strjust.m, strings/strmatch.m, strings/strncmpi.m,
+	strings/strrep.m, strings/strtok.m, strings/strtrim.m,
+	strings/strtrunc.m, strings/strvcat.m, strings/substr.m: 
+	Fix documentation strings, add examples, references and tests.
+	* scripts/general/int2str.m: Add missing semicolon.
+	* scripts/strings/regexptranslate.m: add nargin check.
+	* scripts/strings/str2double.m: fix nargin check.
+	
+2008-12-29  David Bateman  <dbateman at free.fr>
+
+	* goemetry/voronoi.m: Speed up and handle dense grids.
+
+2008-12-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* miscellaneous/delete.m: Allow filename globs. Display warnings if
+	operation fails.
+
+2008-12-26  Francesco Potortì  <pot at gnu.org>
+
+	* general/prepad.m: Add reference to postpad.
+
+	* miscellaneous/bincoeff.m: Make reference to nchoosek.
+
+	* general/postpad.m: Use @seealso.  Add reference to resize.
+
+	* statistics/base/statistics.m: Correct help string.
+
+	* plot/hist.m: Doc string now mentions matrix input argument.
+	Correct error message.
+
+2008-12-30  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__contour__.m: __contour__.m: correct order of patches
+
+2008-12-30  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__contour__.m: __contour__.m: correct order of patches
+
+2008-12-24  Doug Stewart  <dastew at sympatico.ca>
+
+	* plot/grid.m: Handle "minor" option.
+
+2008-12-24  John W. Eaton  <jwe at octave.org>
+
+	* testfun/test.m: Print "has no tests" message if there are demos
+	but no tests instead of printing PASSES 0 out of 0 tests.
+
+2008-12-23  David Bateman  <dbateman at free.fr>
+
+	* sparse/svds.m: New function.
+	* sparse/Makefile.in (SOURCES): Add it here.
+
+2008-11-21  Radek Salac  <salac.r at gmail.com>
+
+	* sparse/bicgstab.m: New function.
+	* sparse/Makefile.in (SOURCES): Add it here.
+
+2008-12-18  Daniel J Sebald <daniel.sebald at ieee.org>
+
+	* time/datevec.m (__date_vfmt2sfmt__): New helper function.
+	(datevec): Avoid repeated parsing of the format string.
+	* set/unique.m: Only check for options if nargin > 1.
+
+2008-12-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/lsqnonneg.m: Preprocess using QR for over-determined
+	systems. Simplify & fix indexing. Use left division for step problem.
+	Fix output args.
+
+2008-12-13  Francesco Potort�  <pot at gnu.org>
+
+	* specfun/nchoosek.m: Check for input arguments, signal loss of
+	precision, correctly handle k==0 and k==n cases, add proper tests.
+
+2008-12-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fsolve.m: Optionally allow pivoted qr factorization.
+
+2008-12-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/expm.m: New source.
+
+2008-12-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* specfun/nchoosek.m: Use a recursionless approach.
+
+2008-12-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/repmat.m: Optimize & simplify the scalar & 2d matrix case.
+
+2008-12-07  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * strings/lower.m: Remove
+        * strings/upper.m: Remove
+        * strings/Makefile.in: Remove lower.m, upper.m
+        
+2008-12-02  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * strings/str2mat.m: Make it a simple wrapper around
+        char() and move it to scripts/deprecated/str2mat.m, remove
+        obsolete tests, move remaining test to src/strfns.cc (Fchar).
+        * strings/Makefile.in: Remove str2mat.m.
+        * deprecated/Makefile.in: Add str2mat.m.
+        * strings/strvcat.m: Remove reference to str2mat.
+        
+2008-11-28  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Set two point clipping mode to be on.
+
+2008-11-26  Francesco Potortì  <pot at gnu.org>
+
+	* specfun/nchoosek.m: Set max_recursion_depth and use a subfunction.
+
+2008-11-29  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * miscellaneous/gzip.m: Remove @seealso reference to __xzip__,
+          improve tests
+          miscellaneous/bzip2.m: Remove @seealso reference to __xzip__,
+          fix handling of output argument, add test
+          miscellaneous/__xzip__.m: Improve error messages, fix cleanup
+          of temporary directories, remove tab characters
+
+2008-11-24  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/legend.m: Correct ording of legend labels.
+
+2008-11-24  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Correct order for rendering children.
+
+2008-11-21  Radek Salac  <salac.r at gmail.com>
+
+	* sparse/cgs.m, sparse/treelayout.m: New functions.
+	* sparse/Makefile.in (SOURCES): Add them here.
+
+2008-11-14  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m (do_tics_1): Support the minorick properties
+	of the axis object.
+
+2008-11-14  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/gnuplot_drawnow.m: Add support of properites to gp backend.
+
+2008-11-13  John W. Eaton  <jwe at octave.org>
+
+	* statistics/distributions/chi2rnd.m: Fix another missing semicolon.
+	From sven.mattisson at insatnet.nu.
+
+2008-11-12  David Bateman  <dbateman at free.fr>
+
+	* plot/__quiver__.m: Only autoscale if more than one element to
+	plot. Modify callbacks for change in order of children.
+	* plot/__stem__.m: Modify callbacks for change in order of children.
+
+2008-11-10  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/spline.m: Delete debugging statements.  From
+	Sebastian Sch�ps <sebastian at schoeps.org>.
+
+2008-11-07  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * mkdoc: do not remove white space before @ within @example
+          environment
+
+2008-11-05  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * plot/subplot.m: fix texi bug
+
+2008-11-04  Thorsten Meyer <thorsten.meyier at gmx.de>
+
+        * miscellaneous/unpack.m: return directly after recursive handling
+          of cell-strings
+          
+2008-11-03  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: xticklabel should accept a numeric vector.
+
+2008-09-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* optimization/__fdjac__.m: New function file.
+	* optimization/__dogleg__.m: New function file.
+	* optimization/fsolve.m: New function file.
+	* optimization/Makefile.in: Include the new sources.
+	
+2008-09-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* optimization/fzero.m: Replace tabs by spaces.
+
+2008-09-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* optimization/fzero.m: Simplify exception handling.
+
+2008-10-31  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/fzero.m: New function file.
+	* optimization/Makefile.in: Add it.
+
+2008-10-31  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/optimset.m: Don't include empty options in option
+	structure.
+	* optimization/optimget.m: New function file.
+	* optimization/Makefile.in: Add it.
+	* optimization/lsqnonneg.m: Query options using optimget.
+
+2008-10-31  Jaroslav Hajek <highegg at gmail.com>
+
+	* linear-algebra/__norm__.m: Remove.
+
+2008-10-25  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * miscellaneous/bzip2.m, miscellaneous/__xzip__.m: new commands.
+        * miscellaneous/gzip.m: change to use __xzip__ for actual compression,
+          add tests.
+                  
+2008-10-31  David Bateman  <dbateman at free.fr>
+
+	* plot/__contour__.m: Exclude infinite values when calculating contour
+	levels.
+	* plot/clabel.m: Close previous plots in demos to avoid pollution
+	between other plot demos.
+	* plot/plotyy.m: Ditto.
+
+2008-10-30  David Bateman  <dbateman at free.fr>
+
+	* plot/legend.m: Add support for the "left" and "right" options.
+	* plot/__go_draw_axes__.m: If the axes property keyreverse is set,
+	reverse the key and labelling text.
+	
+	* plot/__clabel__.m, plot/clabel.m: New functions.
+	* plot/Makefile.in (SOURCES): Add them here.
+	* plot/__contour__.m: Rewrite to use contour groups.
+	* plot/contourf.m: Call __contour__ instead of using specific code.
+	* plot/contour.m, plot/contour3.m: Minor modification to allow for
+	new interface to __contour__.
+
+2008-10-29  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* set/create_set.m, set/ismember.m, set/union.m, set/complement.m:
+	Fix @seealso references to deprecated function intersection.
+	* polynomial/polyvalm.m, polynomial/polyout.m,
+	polynomial/polyint.m, polynomial/polygcd.m,
+	deprecated/polyinteg.m: Remove "and" from @seealso string.
+	* specfun/betaln.m: Change @seealso reference from deprecated
+	betai to betainc.
+	* plot/plot.m, plot/xlabel.m, plot/ylabel.m, plot/zlabel.m, 
+	plot/plot3.m: Fix @seealso references to ylabel and zlabel.
+	* general/issymmetric.m, image/imagesc.m, specfun/realpow.m,
+	polynomial/polyfit.m, time/eomday.m: Remove @seealso references to
+	non-existent functions.
+
+2008-10-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/cla.m: In test, set visible off when creating figure.
+
+2008-10-28  Gabriele Pannocchia  <g.pannocchia at ing.unipi.it>
+
+	* optimization/qp.m: Convert bounds of the form b <= x <= b and
+	constraints of the form b <= A*x <= b to equality constraints.
+
+2008-10-27  S�ren Hauberg  <hauberg at gmail.com>
+
+	* plot/ellipsoid.m: Check nargin == 6, not nargin == 5.
+
+2008-10-22  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/cla.m: Fix error when no children to clear.
+
+	* plot/findobj.m: Allow handle to be empty.
+
+2008-10-22  John W. Eaton  <jwe at octave.org>
+
+	* plot/allchild.m: Move call to get showhiddenhandles outside of
+	unwind_protect block.
+
+2008-10-22  David Bateman  <dbateman at free.fr>
+
+	* plot/refreshdata.m: Modify demo so that "y" is evaluated in the
+	"caller" workspace.
+
+	* plot/__errplot__.m: Add errorbar series objects.
+	* plot/errbar.m: Add some demos.
+	
+	* plot/__add_line_series__.m: Remove
+	* plot/Makefile.in (SOURCES): Remove it here too.
+	* plot/__add_datasource__.m: Allow for more than one character in
+	source name.
+	* plot/refreshdata.m: Ditto.
+	* plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m, 
+	plot/__plt2sv__.m, plot/__plt2vm__.m, plot/__plt2vv__.m, 
+	plot/__plt2vs__.m, plot3.m: Remove previous line series changes.
+	* plot/__scatter__.m: Add scatter series objects and data sources.
+	* plot/legend.m: Update type in loop and remove debugging messages.
+	
+2008-10-21  Ben Abbott  <bpabbott at mac.com>
+
+	* specfun/legendre.m: Warn once on under/overflow.
+
+	* plot/clf.m: Improve Matlab compatibility.
+
+2008-10-21  John W. Eaton  <jwe at octave.org>
+
+	* plot/quiver3.m: Turn hold off after demo.
+
+	* plot/newplot.m: Delete stray debugging code.
+
+	* plot/gnuplot_drawnow.m: Pass handle to __go_draw_figure__, not
+	struct.  Use get instead of examining struct fields directly.
+	* plot/__go_draw_figure__.m: First arg is now handle, not figure
+	object struct.  Use get instead of examining struct elements
+	directly.  Use allhild instead of looking at children field of
+	figure object struct.
+
+2008-10-20  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/orient.m: Fix syntax error.
+
+2008-10-20  David Bateman  <dbateman at free.fr>
+
+	* testfun/rundemos.m: Pause between files, as demo itself doesn't.
+	
+	* plot/fill.m, plot/quiver.m: Quiet the demos.
+	* plot/stair.m: Treat a line style argument correctly.
+
+2008-10-20  John W. Eaton  <jwe at octave.org>
+
+	* plot/surfnorm.m: Save and restore hold state.
+	From Daniel J. Sebald <daniel.sebald at ieee.org> and
+	Ben Abbott <bpabbott at mac.com>.
+
+2008-10-20  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/closereq.m: Respect property tag.
+
+	* plot/__stem__.m: Respect new ordering of children when setting
+	baseline.
+
+	* plot/orient.m, plot/print.m: Properly validate figure handle.
+
+	* plot/hold.m, plot/comet.m: Properly validate axes handle.
+
+	* plot/__go_draw_axes__.m: Fix for binary xfer of suface plots.
+
+2008-10-20  David Bateman  <dbateman at free.fr>
+
+	* plot/plotyy.m: Test that an axes handle actually is one before
+	setting it.
+
+2008-10-17  David Bateman  <dbateman at free.fr>
+
+	* plot/__plt_get_axis_arg__.m: Exclude non-numeric and root figure
+	from potential axis handles.
+	* plot/colorbar.m: Remove debug output.
+	* plot/comet.m: Close plot before demo
+	* plot/contourc.m: No output if nargout == 0.
+
+2008-10-16  David Bateman  <dbateman at free.fr>
+
+	* plot/subplot.m: Allow for column vector of children for figure.
+
+2008-10-16  John W. Eaton  <jwe at octave.org>
+
+	* testfun/rundemos.m: New function.
+
+2008-10-16  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/contourf.m: Correct order of patch object handles.
+
+2008-10-16  David Bateman  <dbateman at free.fr>
+
+	* plot/colorbar.m (colorbar:resetaxis): Uncomment the reseting of
+	the axes.
+
+	* plot/newplot.m: Don't preserve axes properties here, but rather
+	do it in the graphics handle code so that the preservation can be
+	done after callbacks are executed.
+	
+	* plot/__go_draw_axes__.m: If current plot is an image, don't flag
+	the plot as binary, as the binary specification is already in the
+	"usingclause".
+	
+	* plot/__go_draw_figure__.m: Always use multiplot and create an 
+	enclosing axis to ensure bounding box of postscript is correct.
+
+2008-10-16  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m (do_tics_1): New arg, interpreter.
+	(do_tics): Pass interpreter to do_tics_1.
+
+2008-10-15  David Bateman  <dbateman at free.fr>
+
+	* general/colon.m: Small typo.
+	* general/loadobj.m: Ditto.
+
+2008-10-14  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m (do_tics_1): New args, fontname and fontsize.
+	Pass fontspec for tic marks to gnuplot.
+	(do_tics): Pass axes fontname and fontsize to do_tics_1.
+	
+	* plot/newplot.m: Perserve fontangle, fontname, fontsize,
+	fontunits, fontweight, position, outerposition, and
+	activepositionproperty axes properties when replacing plot.
+
+2008-10-15  Daniel J. Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__go_draw_axes__.m: Make previous change work for surface
+	plots.
+
+2008-10-14  Daniel J. Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__go_draw_axes__.m: Send binary data to gnuplot.
+
+2008-10-13  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Fix concatenation of handles.
+
+2008-10-12  David Bateman  <dbateman at free.fr>
+
+	* general/colon..m: New function.
+	* general/Makefile.in (SOURCES): Add it here.
+
+2008-10-10  David Bateman  <dbateman at free.fr>
+
+	* image/__img__.m: Manually set the limits of th eimage
+	* plot/__go_draw_axes__.m: Base window position in the axis
+	position property and not the outerposition property. Remove
+	colorbar code based on the gnuplot colorbox. Allow images to be a
+	vector to support image based colorbars. Also check labelmode for
+	manual tics.
+	* plot/__go_draw_figure__.m: Remove gnuplot colorbox based
+	colorbar code.
+	* plot/colorbar.m: Rewrite to use an image and callbacks to link
+	it to the principal axis.
+	* plot/legend.m: Support an axis handle as the first
+	argument. Support hggroups.
+	* plot/pareto.m: Don't support an axis handle as the first
+	argument as the plotyy command in fact needs two axis handles.
+	* plot/plotyy.m: Rewrite to use listeners and callbacks to
+	synchronize the two axes.
+	* plot/subplot.m: Also skip axes that are tagged as being a
+	colorbar. Don't break in search of overlapping axes to delete. Set
+	both the position and the outerposition.
+	
+2008-10-09  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__axis_label__.m: Inherit font properties from axes.
+
+2008-10-09  David Bateman  <dbateman at free.fr>
+
+	* general/loadobj.m, general/saveobj.m, general/display: New functions
+	* general/Makefile.in (SOURCES): Add then here.
+	
+2008-10-08  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/fileparts.m: Handle "/file" properly.
+	Improve compatibility.
+
+2008-10-07  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/cla.m: New function.
+	* plot/Makefile.in (SOURCES): Add it to the list.
+
+2008-10-07  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/delete.m: Pass array of handles to __go_delete__.
+
+2008-10-06  John W. Eaton  <jwe at octave.org>
+
+	* plot/__add_datasource__.m, plot/__axes_limits__.m,
+	plot/__bar__.m, plot/__bars__.m, plot/__contour__.m,
+	plot/__go_draw_axes__.m, plot/__go_draw_figure__.m,
+	plot/__patch__.m, plot/__quiver__.m, plot/__scatter__.m,
+	plot/__stem__.m, plot/ancestor.m, plot/axis.m, plot/box.m,
+	plot/caxis.m, plot/close.m, plot/colorbar.m, plot/fill.m,
+	plot/findobj.m, plot/grid.m, plot/hidden.m, plot/hold.m,
+	plot/ishold.m, plot/legend.m, plot/linkprop.m, plot/orient.m,
+	plot/plotmatrix.m, plot/shading.m: Use case-insensitive comparison
+	for properties.  Misc style fixes.
+
+2008-10-06  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/orient.m: Figure handle must be scalar.
+	* plot/hold.m: Axis handle must be scalar.
+	* plot/axes.m: Axis handle must be scalar.
+	* plot/__plt_get_axis_arg__.m: Handle must be scalar.
+
+	* miscellaneous/delete.m: Permit a vector of handles to be deleted.
+
+2008-10-02  John W. Eaton  <jwe at octave.org>
+
+	* pkg/pkg.m (configure_make): Handle filenames with spaces.
+
+2008-10-02  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* pkg.m (configure_make): Enclose building directory in quotes.
+
+2008-10-02  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Remove depdenence on gnuplot version.
+
+2008-09-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* string/split.m: New tests.
+
+2008-09-30  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/__go_draw_axes__.m: Fix interpolation of facecolors.
+
+	* plot/shading.m: New demo.
+
+2008-09-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Eliminate have_newer_gnuplot variable.
+
+	* plot/__gnuplot_version__.m: Also include patchlevel.
+
+2008-09-29  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/deconv.m: Fix row/col orientation & length of output.
+
+	* polynomial/conv.m: Correct row/col orientation of output.
+
+2008-09-27  Ivan Sutoris  <ivan.sutoris at gmail.com>
+
+	* optimization/sqp.m: Document additional parameters.
+
+2008-09-26  David Bateman  <dbateman at free.fr>
+
+	* general/subsindex.m: Dummy subsindex function for help string
+	and to throw error for use outside of a class
+	* general/Makefile.in (SOURCES): Include it here.
+
+2008-09-26  John W. Eaton  <jwe at octave.org>
+
+	* image/imfinfo.m: Delete temporary file.
+
+2008-09-25  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/imread.m, image/imwrite.m: Doc fix.
+
+2008-09-24  John W. Eaton  <jwe at octave.org>
+
+	* plot/fplot.m: Call axis after calling plot.
+
+2008-09-24  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/imfinfo.m: New function.
+	* image/Makefile.in (SOURCES): Add it to the list.
+
+2008-09-24  Ben Abbott  <bpabbott at mac.com>
+
+	* strings/strcat.m: Improve Matlab compatibility for non-character
+	data.
+
+2008-09-24  John W. Eaton  <jwe at octave.org>
+
+	* general/interpft.m: Increase tolerance in tests.
+
+2008-09-23  Francesco Potorti`  <Potorti at isti.cnr.it>
+
+	* plot/pcolor.m: Improve doc string.
+
+2008-09-22 Ben Abbott  <bpabbott at mac.com>
+
+	* plot/comet.m: New file.
+	* plot/Makefile.in (SOURCES): Add it here.
+
+2008-09-22  David Bateman  <dbateman at free.fr>
+
+	* plot/plotmatrix.m: New function.
+	* plot/Makefile.in (SOURCES): Add it here.
+
+	* general/quadgk.m: No function count in quadgk and so don't try and
+	print it when given trace argument.
+
+2008-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/blkdiag.m: Skip assignment if rhs is empty.
+
+2008-09-18  Kris Thielemans  <kris.thielemans at csc.mrc.ac.uk>
+
+	* image/imshow.m: Fix for display_range.
+	
+	* general/interpn.m: Fixe for extrapval and documentation of 
+	extrapval.
+
+2008-09-17  David Bateman  <dbateman at free.fr>
+
+	* time/datetick.m: New function.
+	* time/Makefile.in (SOURCES): Add it here.
+	* time/datestr.m: More careful check for datevec format with 6
+	column arguments.
+	* plot/__go_draw_axes__ (do_tics_1): Use %.15g format rather than
+	%g format. Also use manual mode if xlabelmode is manual.
+
+	* general/cell2mat.m: Backout previous change. Special case 2D
+	case for speed.
+
+2008-09-11  David Bateman  <dbateman at free.fr>
+
+	* general/cell2mat.m: Improve the speed.
+
+2008-09-09  John W. Eaton  <jwe at octave.org>
+
+	* time/datestr.m: Convert format and use strftime to do most of
+	the actual conversion.
+
+2008-09-08  Tatsuro MATSUOKA  <tmacchant at yahoo.co.jp>
+
+	* plot/plot.m: Doc fix.
+
+2008-09-08  Mark van Rossum  <mvanross at inf.ed.ac.uk>
+
+	* statistics/distributions/binornd.m: Handle zero values of n
+	correctly.
+
+2008-09-08  Kai Habel  <kai.habel at gmx.de>
+
+        * plot/contourf.m: Fix case for equal-sized matrices
+        of X and Y.
+
+2008-09-02  David Bateman  <dbateman at free.fr>
+
+	* plot/__add_datasource__.m: Fix indexing of varargin.
+
+	* plot/__line__.m: Remove empty clause fof if/then/else test
+	* plot/plot3.m: Correctly plot matrices.
+
+2008-08-31  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m,
+	plot/__plt2sv__.m, plot/__plt2vm__.m, plot/__plt2vs__.m,
+	plot/__plt2vv__.m: Do not call "set" with empty arguments.
+
+2008-08-29  David Bateman  <dbateman at free.fr>
+
+	* plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m,
+	plot/__plt2sv__.m, plot/__plt2vm__.m, plot/__plt2vs__.m,
+	plot/__plt2vv__.m, plot/plot3.m, plot/__area__.m, plot/__bars__.m,
+	plot/__quiver__.m, plot/__stem__.m, plot/stairs.m :
+	Pass additional prop/val pairs to hggroup rather than underlying
+	objects. If a baseline existings specifically associate it with
+	the parent of the created hggroup to allow things like "stem(...,
+	'parent', hg)" to work correctly.
+	* plot/hold.m: If currentaxes if figure doesn't exist, create it.
+
+	* plot/plot3.m: Pass hline to __add_line_series__.
+	* plot/__add_datasource__.m: Fix off by one error.
+
+2008-08-28  David Bateman  <dbateman at free.fr>
+
+	* plot/__add_line_series__.m, plot/ishghandle.m, plot/linkprop.m,
+	plot/refresh.m, plot/refreshdata.m: New functions
+	* Makefile.in (SOURCES): Add them here.
+	
+	* plot/__area__.m, plot/__bars__.m, plot/__quiver__.m,
+	plot/__stem__.m, plot/stairs.m, plot/stem.m: Add data sources.
+
+	* plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m,
+	plot/__plt2sv__.m, plot/__plt2vm__.m, plot/__plt2vs__.m,
+	plot/__plt2vv__.m, plot/plot3.m: Add line series and data sources.
+
+2008-08-28  Martin Weiser  <weiser2 at natur.cuni.cz>
+
+	* plot/scatter3.m: Doc fix.
+
+2008-08-26  John W. Eaton  <jwe at octave.org>
+
+	* plot/hold.m: If hold is applied to a figure, set state for all
+	child axes objects.
+
+2008-08-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/backend.m: New function to handle backend switch.
+	* plot/Makefile.in: Add it.
+
+2008-08-26  David Bateman  <dbateman at free.fr>
+
+	* plot/__area__.m: Use __next_line_color__ rather than fixed set
+	of colors. Convert to use area series objects.
+	* plot/area.m: Update documentation to correspond to
+	the area series usage.
+	* plot/__bar.m: Pass the original rather than scaled width to
+	__bars__. 
+	* plot/__bars__.m: Convert to use bar series objects.
+	* plot/bar.m, plor/barh.m:  Update documentation to correspond to
+	the bar series usage.
+	* plot/__quiver__.m: Convert to use quiver series objects. Change
+	the default scaling and arrowsize for compatibility.
+	* plot/quiver.m:  Update documentation to correspond to
+	the quiver series usage.
+	* plot/stairs.m: Convert to use stair series objects.
+	* plot/stem.m: Don't include baseline in xlim calculation. Correct
+	test of whether baseline xdata needs updating in the update_xlim
+	callback.
+
+2008-08-25  Thomas L. Scofield  <scofield at calvin.edu>
+
+	* image/imwrite.m: Add ras and tiff to the list of accepted formats.
+	Handle parameter-value options.  Untabify.
+	
+2008-08-25  David Bateman  <dbateman at free.fr>
+
+	* plot/__stem__.m: Use property inheritance and don't explicitly
+	call drawnow.
+
+	* plot/__go_draw_axes__.m: Respect the "visible" property of object and
+	don't draw them if the object is not visible.
+
+	* plot/__stem__.m: Convert to use stem series object.
+	* plot/stem.m, plot/stem3.m: Update documentation to correspond to
+	the stem series usage.
+
+2008-08-22  John W. Eaton  <jwe at octave.org>
+
+	* statistics/distributions/chi2rnd.m: Fix missing semicolon.
+
+2008-08-21  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Fix test for have_data.
+	(__gnuplot_write_data__): Write "Inf Inf\n" if all data pairs
+	contain NaN values.
+
+2008-08-21  Thomas Treichl  <Thomas.Treichl at gmx.net>
+	
+	* optimization/sqp.m: Increase test script tolerance.
+
+2008-08-21  David Bateman  <dbateman at free.fr>
+
+	* plot/ezplot.m : New function.
+	* plot/Makefile.in (SOURCES): Add ezplot.m to the list.
+	* plot/__ezplot__.m: Adapt to allow for use with the ezplot function.
+	
+2008-08-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pkg/pkg.m (configure_make): Pass handle to is_architecture_dependent
+	directly.
+
+2008-08-20  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Don't set pm3d implicit if the plot
+	contains a surface. Fixes things like meshc(peaks()).
+
+2008-08-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* optimization/glpk.m: Fix invalid call to zeros.
+
+2008-08-19  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/intwarning.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it here.
+
+	* statistics/base/ranks.m: Doc fix.
+
+2008-08-08  John W. Eaton  <jwe at octave.org>
+
+	* general/Makefile.in (SOURCES): Add cellidx.m to the list.
+
+2008-08-07  John W. Eaton  <jwe at octave.org>
+
+	* gethelp.cc: Delete definition of NPOS.
+
+2008-08-04  John W. Eaton  <jwe at octave.org>
+
+	* strings/strtok.m: Include TAB, LF, VT, FF, and CR in default
+	list of delim characters.  Update tests.
+
+2008-07-29  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* general/arrayfun.m: Minor bug fixes, update help text and tests
+
+2008-07-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/axis.m (__get_tight_lims__): Use strcat instead of [].
+	Don't fail if data is not a vector.
+
+2008-07-29  David Bateman  <dbateman at free.fr>
+
+	* general/cellidx.m: reinclude from control toolbox, as used by
+	print command. Replace is_signal_list with iscellstr.
+	* general/quadqk.m, linear-algebra/planeror.m,
+	miscellaneous/namelengthmax.m, specfun/realpow.m: Miscellaneous
+	documentation fixes.
+
+	* control, finance, quaternion: Remove directories and all of the
+	files they contain.
+	* Makefile.in: Remove all references to the above directories.
+	* configure.in: ditto.
+
+2008-07-28  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/hold.m: Clarify help text.
+
+	* specfun/reallog.m: Fix help string.
+
+2008-07-28  David Bateman  <dbateman at free.fr>
+
+	* strings/regexptranslate.m: Add real documentation.
+
+	* plot/contourf.m: Allow X,Y to be unequal vectors.
+
+	* plot/shading.m: Clarify help string.
+	
+	* general/genvarname.m: Trivial documentation fix.
+
+2008-07-28  John W. Eaton  <jwe at octave.org>
+
+	* image/imwrite.m: New function.
+	* image/Makefile.in (SOURCES): Add it to the list.
+
+2008-07-24  Ben Abbott  <bpabbott at mac.com>
+
+	* time/datestr.m: New xtest.
+
+2008-07-21  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/closereq.m: Use first gcbf to get the handle of the figure to
+	be closed.
+	* plot/close.m: Call __go_execute_callback__.
+
+2008-07-17  John W. Eaton  <jwe at octave.org>
+
+	* general/fliplr.m: Fix usage test.
+	* testfun/test.m: Fix usage tests.
+
+2008-07-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* statistics/base/cov.m: Fix test that should no longer work.
+
+2008-07-16  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/gcbo.m, plot/gcbf.m: New functions.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+
+2008-07-16  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/loadimage.m: New file.
+	* deprecated/Makefile.in (SOURCES): Add it to the list.
+	* image/loadimage.m: Delete.	
+	* image/Makefile.in (SOURCES): Remove it from the list.
+	* image/imread.m: Incorporate loadimage functionality here.
+	Simplify.
+	* image/imshow.m: Call imread, not loadimage.
+
+	* image/__img__.m: Set clim for true-color integer data.
+
+	* image/imshow.m: Don't convert integer true-color data to double.
+
+	* plot/__go_draw_axes__.m: Recognize 3-d cdata as a true-color image.
+
+2008-07-14  John W. Eaton  <jwe at octave.org>
+
+	* image/Makefile.in (SOURCES): Add imread.m to the list.
+
+2008-07-14  Thomas L. Scofield  <scofield at calvin.edu>
+
+	* image/imread.m: New file from Octave Forge.
+
+2008-07-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* set/unique.m: Implement 'first' and 'last', some simplifications.
+	* set/union.m: Implement output indices.
+	* set/intersect.m: Implement 'rows'.
+	* set/setdiff.m: Implement output indices.
+	* set/setxor.m: Implement 'rows' and output indices.
+	Add tests and adjust docs in all of the above.
+
+2008-06-11  John W. Eaton  <jwe at octave.org>
+
+	* set/ismember.m: Fix fail tests.
+
+	* general/rat.m: Properly initialize steps when all elements of
+	input array are integers.  Append spaces as necessary when
+	building  character array.
+
+2008-06-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* plot/__go_draw_axes__.m: Use fprintf for formatted output.
+
+2008-06-04  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/__go_draw_axes__.m: Support hggroup objects.
+	* plot/hggroup.m: New file.
+	* plot/Makefile.in: Handle it.
+
+2008-06-02  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/debug.m: New file..
+	* Makefile.in (SOURCES): Add it to the list.
+
+	* general/interp1q.m: Remove spaces between functions and args in
+	[]. Fix test code to actually test interp1q.
+
+2008-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* strings/strcat.m: Add tests.
+
+2008-06-02  Kim Hansen  <kimhanse at gmail.com>
+
+	* strings/mat2str.m: Change is_complex to iscomplex, add tests, add
+	missing ;
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/single.m: Remove.
+	* Makefile.in (SOURCES): Remove it here as well.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* general/interp1q.m: New function.
+	* general/Makefile.in (SOURCES): Add it here.
+
+2008-05-20  Bill Denney  <bill at denney.ws>
+
+	* time/datenum.m: Allow mixed scalar and vector/matrix input.
+	New tests.
+
+2008-05-19  John W. Eaton  <jwe at octave.org>
+
+	* general/isa.m: Fix tests.
+
+2008-05-13  Bill Denney  <bill at denney.ws>
+
+	* general/isa.m: Use persistent cell arrays to hold class names
+	instead of multiple strcmp calls.
+
+2008-05-12  David Bateman  <dbateman at free.fr>
+
+	* control/base/__stepimp__.m, control/base/bode_bounds.m,
+	control/base/damp.m, control/base/dlqr.m, control/base/lsim.m,
+	control/base/tzero.m, control/hinf/hinfsyn.m,
+	control/hinf/is_dgkf.m, control/system/d2c.m,
+	control/system/is_controllable.m, control/system/is_detectable.m,
+	control/system/is_stabilizable.m, control/system/is_stable.m,
+	control/system/sysconnect.m, general/bicubic.m,
+	general/cplxpair.m, general/isdefinite.m, general/issymmetric.m,
+	general/quadgk.m, general/quadl.m, general/quadv.m,
+	geometry/delaunayn.m, linear-algebra/krylov.m,
+	linear-algebra/null.m, linear-algebra/onenormest.m,
+	linear-algebra/orth.m, linear-algebra/rank.m,
+	linear-algebra/rref.m, optimization/qp.m, optimization/sqp.m,
+	polynomial/polygcd.m, polynomial/residue.m, sparse/normest.m,
+	specfun/erfinv.m, statistics/distributions/betainv.m,
+	statistics/distributions/gaminv.m,
+	statistics/distributions/kolmogorov_smirnov_cdf.m,
+	statistics/tests/manova.m: Modify calls to eps to allow for single
+	precision types.
+
+	* general/isa.m: Also treat "float: and "numeric" as the class
+	argument.
+
+	* general/dblquad.m, general/quadgk.m, general/quadv.m,
+	general/triplequad.m: New functions.
+
+	* testfun/assert.m: Allow assert(cond, errmsg, ...) and
+	assert(cond, msgid, errmsg, ...) syntax for compatibility.
+
+2008-05-09  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* miscellaneous/news.m: Replace deprecated isstr call.
+
+2008-05-06  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/symvar.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+2008-05-04  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dbstack.m: Delete.
+	* miscellaneous/Makefile.in (SOURCES): Remove it from the list.
+
+2008-05-03  Rafael Laboissiere <rafael at debian.org>
+
+	* linear-algebra/cond.m, miscellaneous/version.m,
+	miscellaneous/version.m, plot/feather.m, plot/__bar__.m,
+	plot/compass.m, plot/__quiver__.m, plot/__scatter__.m: Use ischar
+	instead of deprecated isstr.
+
+2008-05-01  David Bateman  <dbateman at free.fr>
+
+	* plot/plot.m: Remove documentation of 'L' option.
+	* plot/stairs.m: Allow axis handles, properties and linespecs to
+	be passed.
+
+2008-04-30  John W. Eaton  <jwe at octave.org>
+
+	* elfun/acot.m, elfun/acsc.m, elfun/acsch.m, elfun/asec.m,
+	elfun/asech.m, specfun/pow2.m: Fix tests.
+
+2008-04-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* specfun/log2.m: Delete. 
+	* specfun/Makefile.in (SOURCES): Delete it from the list.
+
+2008-04-29  David Bateman  <dbateman at free.fr>
+
+	pkg/pkg.m: Also set archprefix with the -local and -global options.
+
+2008-04-29  Jonathan Stickel  <jjstickel at vcn.com>
+
+	* statistics/distributions/tcdf.m, statistics/distributions/tinv.m:
+	Doc fix.
+
+2008-04-25  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dbstack.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+2008-04-21  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m (gnuplot_position_colorbox): New arg, obj.
+	Change caller.  Improve sizing and position of colorbox for subplots.
+	* plot/colorbar.m: New demos.
+
+2008-04-16  S�ren Hauberg  <hauberg at gmail.com>
+
+	* plot/__gnuplot_version__.m: Display error if gnuplot is not found.
+
+2008-04-15  John W. Eaton  <jwe at octave.org>
+
+	* plot/view.m: Get values from current axes if nargin == 0.
+
+2008-04-15  David Bateman  <dbateman at free.fr>
+
+	* plot/__patch__.m: Fix for NaN values in faces of patches.
+	
+2008-04-14  David Bateman  <dbateman at free.fr>
+
+	* plot/rose.m: Add missing comment mark that causes issues with
+	octave-forge function referencing.
+	* deprecated/lchol.m, deprecated/splchol.m: Fix texinfo errors.
+
+2008-04-09  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/beta_cdf.m, deprecated/beta_inv.m,
+	deprecated/beta_pdf.m, deprecated/beta_rnd.m,
+	deprecated/binomial_cdf.m, deprecated/binomial_inv.m,
+	deprecated/binomial_pdf.m, deprecated/binomial_rnd.m,
+	deprecated/chisquare_cdf.m, deprecated/chisquare_inv.m,
+	deprecated/chisquare_pdf.m, deprecated/chisquare_rnd.m,
+	deprecated/clearplot.m, deprecated/clg.m, deprecated/com2str.m,
+	deprecated/exponential_cdf.m, deprecated/exponential_inv.m,
+	deprecated/exponential_pdf.m, deprecated/exponential_rnd.m,
+	deprecated/f_cdf.m, deprecated/f_inv.m, deprecated/f_pdf.m,
+	deprecated/f_rnd.m, deprecated/gamma_cdf.m,
+	deprecated/gamma_inv.m, deprecated/gamma_pdf.m,
+	deprecated/gamma_rnd.m, deprecated/geometric_cdf.m,
+	deprecated/geometric_inv.m, deprecated/geometric_pdf.m,
+	deprecated/geometric_rnd.m, deprecated/hypergeometric_cdf.m,
+	deprecated/hypergeometric_inv.m, deprecated/hypergeometric_pdf.m,
+	deprecated/hypergeometric_rnd.m, deprecated/intersection.m,
+	deprecated/is_bool.m, deprecated/is_complex.m,
+	deprecated/is_list.m, deprecated/is_matrix.m,
+	deprecated/is_scalar.m, deprecated/is_square.m,
+	deprecated/is_stream.m, deprecated/is_struct.m,
+	deprecated/is_symmetric.m, deprecated/is_vector.m,
+	deprecated/isstr.m, deprecated/lchol.m,
+	deprecated/lognormal_cdf.m, deprecated/lognormal_inv.m,
+	deprecated/lognormal_pdf.m, deprecated/lognormal_rnd.m,
+	deprecated/meshdom.m, deprecated/normal_cdf.m,
+	deprecated/normal_inv.m, deprecated/normal_pdf.m,
+	deprecated/normal_rnd.m, deprecated/pascal_cdf.m,
+	deprecated/pascal_inv.m, deprecated/pascal_pdf.m,
+	deprecated/pascal_rnd.m, deprecated/poisson_cdf.m,
+	deprecated/poisson_inv.m, deprecated/poisson_pdf.m,
+	deprecated/poisson_rnd.m, deprecated/polyinteg.m,
+	deprecated/setstr.m, deprecated/spatan2.m, deprecated/spchol.m,
+	deprecated/spchol2inv.m, deprecated/spcholinv.m,
+	deprecated/spcumprod.m, deprecated/spcumsum.m, deprecated/spdet.m,
+	deprecated/spdiag.m, deprecated/spfind.m, deprecated/spinv.m,
+	deprecated/spkron.m, deprecated/splchol.m, deprecated/splu.m,
+	deprecated/spmax.m, deprecated/spmin.m, deprecated/spprod.m,
+	deprecated/spqr.m, deprecated/spsum.m, deprecated/spsumsq.m,
+	deprecated/struct_contains.m, deprecated/struct_elements.m,
+	deprecated/t_cdf.m, deprecated/t_inv.m, deprecated/t_pdf.m,
+	deprecated/t_rnd.m, deprecated/uniform_cdf.m,
+	deprecated/uniform_inv.m, deprecated/uniform_pdf.m,
+	deprecated/uniform_rnd.m, deprecated/weibcdf.m,
+	deprecated/weibinv.m, deprecated/weibpdf.m, deprecated/weibrnd.m,
+	deprecated/weibull_cdf.m, deprecated/weibull_inv.m,
+	deprecated/weibull_pdf.m, deprecated/weibull_rnd.m,
+	deprecated/wiener_rnd.m: Don't embed newline in warning message.
+
+2008-04-09  David Bateman  <dbateman at free.fr>
+
+	* testfun/assert.m: Don't allow cond and expected to be lists.
+
+2008-04-04  John W. Eaton  <jwe at octave.org>
+
+	* strings/Makefile.in (SOURCES): Add isstrprop.m to the list.
+
+	* Makefile.in, audio/Makefile.in, control/Makefile.in,
+	* Makefile.incontrol/base/Makefile.in, control/hinf/Makefile.in,
+	* Makefile.incontrol/obsolete/Makefile.in,
+	* Makefile.incontrol/system/Makefile.in, control/util/Makefile.in,
+	* Makefile.indeprecated/Makefile.in, elfun/Makefile.in,
+	* Makefile.infinance/Makefile.in, general/Makefile.in,
+	* Makefile.ingeometry/Makefile.in, image/Makefile.in,
+	* Makefile.inio/Makefile.in, linear-algebra/Makefile.in,
+	* Makefile.inmiscellaneous/Makefile.in, optimization/Makefile.in,
+	* Makefile.inpath/Makefile.in, pkg/Makefile.in, plot/Makefile.in,
+	* Makefile.inpolynomial/Makefile.in, quaternion/Makefile.in,
+	* Makefile.inset/Makefile.in, signal/Makefile.in,
+	* Makefile.insparse/Makefile.in, specfun/Makefile.in,
+	* Makefile.inspecial-matrix/Makefile.in, startup/Makefile.in,
+	* Makefile.instatistics/Makefile.in, statistics/base/Makefile.in,
+	* Makefile.instatistics/distributions/Makefile.in,
+	* Makefile.instatistics/models/Makefile.in,
+	* Makefile.instatistics/tests/Makefile.in, strings/Makefile.in,
+	* Makefile.intestfun/Makefile.in, time/Makefile.in
+	* Makefile.in(check-m-sources): New target.
+
+2008-04-04  Bill Denney  <bill at denney.ws>
+
+	* optimization/lsqnonneg.m: Use optimset, correctly index
+	Z and P in main loop.
+
+2008-04-04  David Bateman  <dbateman at free.fr>
+
+	* deprecated/beta_cdf.m deprecated/beta_inv.m
+	deprecated/beta_pdf.m deprecated/beta_rnd.m
+	deprecated/binomial_cdf.m deprecated/binomial_inv.m
+	deprecated/binomial_pdf.m deprecated/binomial_rnd.m
+	deprecated/chisquare_cdf.m deprecated/chisquare_inv.m
+	deprecated/chisquare_pdf.m deprecated/chisquare_rnd.m
+	deprecated/clearplot.m deprecated/clg.m deprecated/com2str.m
+	deprecated/exponential_cdf.m deprecated/exponential_inv.m
+	deprecated/exponential_pdf.m deprecated/exponential_rnd.m
+	deprecated/f_cdf.m deprecated/f_inv.m deprecated/f_pdf.m
+	deprecated/f_rnd.m deprecated/gamma_cdf.m deprecated/gamma_inv.m
+	deprecated/gamma_pdf.m deprecated/gamma_rnd.m
+	deprecated/geometric_cdf.m deprecated/geometric_inv.m
+	deprecated/geometric_pdf.m deprecated/geometric_rnd.m
+	deprecated/hypergeometric_cdf.m deprecated/hypergeometric_inv.m
+	deprecated/hypergeometric_pdf.m deprecated/hypergeometric_rnd.m
+	deprecated/intersection.m deprecated/is_bool.m
+	deprecated/is_complex.m deprecated/is_list.m
+	deprecated/is_matrix.m deprecated/is_scalar.m
+	deprecated/is_square.m deprecated/is_stream.m deprecated/isstr.m
+	deprecated/is_struct.m deprecated/is_symmetric.m
+	deprecated/is_vector.m deprecated/lognormal_cdf.m
+	deprecated/lognormal_inv.m deprecated/lognormal_pdf.m
+	deprecated/lognormal_rnd.m deprecated/meshdom.m
+	deprecated/normal_cdf.m deprecated/normal_inv.m
+	deprecated/normal_pdf.m deprecated/normal_rnd.m
+	deprecated/pascal_cdf.m deprecated/pascal_inv.m
+	deprecated/pascal_pdf.m deprecated/pascal_rnd.m
+	deprecated/poisson_cdf.m deprecated/poisson_inv.m
+	deprecated/poisson_pdf.m deprecated/poisson_rnd.m
+	deprecated/polyinteg.m deprecated/setstr.m
+	deprecated/struct_contains.m deprecated/struct_elements.m
+	deprecated/t_cdf.m deprecated/t_inv.m deprecated/t_pdf.m
+	deprecated/t_rnd.m deprecated/uniform_cdf.m
+	deprecated/uniform_inv.m deprecated/uniform_pdf.m
+	deprecated/uniform_rnd.m deprecated/weibcdf.m deprecated/weibinv.m
+	deprecated/weibpdf.m deprecated/weibrnd.m deprecated/weibull_cdf.m
+	deprecated/weibull_inv.m deprecated/weibull_pdf.m
+	deprecated/weibull_rnd.m deprecated/wiener_rnd.m: Add warning that
+	function will be removed in a future version.
+
+2008-04-03  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/beta_cdf.m, deprecated/beta_inv.m,
+	deprecated/beta_pdf.m, deprecated/beta_rnd.m,
+	deprecated/binomial_cdf.m, deprecated/binomial_inv.m,
+	deprecated/binomial_pdf.m, deprecated/binomial_rnd.m,
+	deprecated/chisquare_cdf.m, deprecated/chisquare_inv.m,
+	deprecated/chisquare_pdf.m, deprecated/chisquare_rnd.m,
+	deprecated/clearplot.m, deprecated/clg.m, deprecated/com2str.m,
+	deprecated/exponential_cdf.m, deprecated/exponential_inv.m,
+	deprecated/exponential_pdf.m, deprecated/exponential_rnd.m,
+	deprecated/f_cdf.m, deprecated/f_inv.m, deprecated/f_pdf.m,
+	deprecated/f_rnd.m, deprecated/gamma_cdf.m,
+	deprecated/gamma_inv.m, deprecated/gamma_pdf.m,
+	deprecated/gamma_rnd.m, deprecated/geometric_cdf.m,
+	deprecated/geometric_inv.m, deprecated/geometric_pdf.m,
+	deprecated/geometric_rnd.m, deprecated/hypergeometric_cdf.m,
+	deprecated/hypergeometric_inv.m, deprecated/hypergeometric_pdf.m,
+	deprecated/hypergeometric_rnd.m, deprecated/intersection.m,
+	deprecated/is_bool.m, deprecated/is_complex.m,
+	deprecated/is_list.m, deprecated/is_matrix.m,
+	deprecated/is_scalar.m, deprecated/is_square.m,
+	deprecated/is_stream.m, deprecated/is_struct.m,
+	deprecated/is_symmetric.m, deprecated/is_vector.m,
+	deprecated/isstr.m, deprecated/lchol.m,
+	deprecated/lognormal_cdf.m, deprecated/lognormal_inv.m,
+	deprecated/lognormal_pdf.m, deprecated/lognormal_rnd.m,
+	deprecated/meshdom.m, deprecated/normal_cdf.m,
+	deprecated/normal_inv.m, deprecated/normal_pdf.m,
+	deprecated/normal_rnd.m, deprecated/pascal_cdf.m,
+	deprecated/pascal_inv.m, deprecated/pascal_pdf.m,
+	deprecated/pascal_rnd.m, deprecated/poisson_cdf.m,
+	deprecated/poisson_inv.m, deprecated/poisson_pdf.m,
+	deprecated/poisson_rnd.m, deprecated/polyinteg.m,
+	deprecated/setstr.m, deprecated/spatan2.m, deprecated/spchol.m,
+	deprecated/spchol2inv.m, deprecated/spcholinv.m,
+	deprecated/spcumprod.m, deprecated/spcumsum.m, deprecated/spdet.m,
+	deprecated/spdiag.m, deprecated/spfind.m, deprecated/spinv.m,
+	deprecated/spkron.m, deprecated/splchol.m, deprecated/splu.m,
+	deprecated/spmax.m, deprecated/spmin.m, deprecated/spprod.m,
+	deprecated/spqr.m, deprecated/spsum.m, deprecated/spsumsq.m,
+	deprecated/struct_contains.m, deprecated/struct_elements.m,
+	deprecated/t_cdf.m, deprecated/t_inv.m, deprecated/t_pdf.m,
+	deprecated/t_rnd.m, deprecated/uniform_cdf.m,
+	deprecated/uniform_inv.m, deprecated/uniform_pdf.m,
+	deprecated/uniform_rnd.m, deprecated/weibcdf.m,
+	deprecated/weibinv.m, deprecated/weibpdf.m, deprecated/weibrnd.m,
+	deprecated/weibull_cdf.m, deprecated/weibull_inv.m,
+	deprecated/weibull_pdf.m, deprecated/weibull_rnd.m,
+	deprecated/wiener_rnd.m:
+	Note version when function was deprecated.
+
+2008-04-03  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Conditionally "set pm3d implict" for 2D
+	plot or 3D plots with more than one line.
+	
+	* deprecated/splchol.m deprecated/lchol.m deprecated/spfind.m
+	deprecated/spchol.m deprecated/spmin.m deprecated/spmax.m
+	deprecated/spdet.m deprecated/splu.m deprecated/spqr.m
+	deprecated/spatan2.m deprecated/spchol2inv.m
+	deprecated/spcholinv.m deprecated/spcumprod.m deprecated/spdiag.m
+	deprecated/spinv.m deprecated/spcumsum.m deprecated/spprod.m
+	deprecated/spsum.m deprecated/spsumsq.m: New files
+	* deprecated/Makefile.in (SOURCES): Add them here.
+
+2008-04-03  Ben Abbott  <bpabbott at mac.com>
+
+	* sparse/spaugment.m: Increase test script tolerance.
+
+2008-04-02  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/Makefile.in (SOURCES): Add spkron.m to the list.
+
+	* general/Makefile.in (SOURCES): Add runlength.m to the list.
+
+2008-04-02  Bill Denney  <bill at denney.ws>
+
+	* optimization/lsqnonneg.m: New function.
+	* optimization/Makefile.in (SOURCES): Add it to the list.
+
+2008-04-02  David Bateman  <dbateman at free.fr>
+
+	* sparse/spaugment.m: New function
+	* sparse/Makefile.in (SOURCES): Add it here.
+	
+	* plot/__gnuplot_ginput__.m: Use the gnuplot stream itself for
+	communication rather than a chat file if mkfifo is not available.
+	* plot/gnuplot_drawnow.m: Open stream with popen2 to allow two way
+	communication with the gnuplot process.
+
+2008-04-01  Richard Bovey  <Richard.Bovey at baesystems.com>
+
+	* general/sortrows.m: Handle negative column arguments.
+
+2008-04-01  Julian Schnidder  <j.schnidder at gmx.de>
+
+	* miscellaneous/perl.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+2008-03-31  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Set the tick direction in the main call
+	the set tics rather than separately to avoid issues with multiple
+	ticks in plotyy.
+	
+	* plot/gtext.m: New function to place text on a plot.
+	* plot/waitforbuttonpress.m: New function.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+	* plot/__gnuplot_ginput__.m: Bug fix for nargin==1. Workaround for
+	missing mkfifo under Windows.
+	* plot/ginput.m: Eliminate setting of n.
+	
+	* plot/ginput.m: New function.
+	* plot/__gnuplot_ginput__.m: New function based on a version of
+	ginput.m from Petr Mikulik <mikulik at physics.muni.cz>.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+
+2008-03-31  Dmitri A. Sergatskov  <dasergatskov at gmail.com>
+
+	* miscellaneous/run.m: Fix check for existence of file.
+
+2008-03-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/lookup.m: Remove (lookup moved to DLD-FUNCTIONS).
+	* general/Makefile.in (SOURCES): Delete lookup.m from the list.
+	* general/interp1.m, general/interp2.m, general/interpn.m,
+	polynomial/ppval.m: Fix buggy lookup calls.
+	* general/interp1.m: New test.
+
+2008-03-28  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* miscellaneous/tempdir.m: Use correct function name in texinfo
+	documentation.
+
+2008-03-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* general/del2.m: Missing semicolon.
+
+2008-03-28  Julian Schnidder  <j.schnidder at gmx.de>
+
+	* miscellaneous/info.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+2008-03-27  S�ren Hauberg  <hauberg at gmail.com>
+
+	* plot/xlim.m, plot/ylim.m, plot/zlim.m, strings/strtrim.m:
+	Doc fixes.
+
+2008-03-27  David Bateman  <dbateman at free.fr>
+
+	* plot/__plt2__.m: Test if args are empty first so that
+	plot(zeros(1,0),zeros(1,0)) works as expected.
+
+	* plot/plotyy.m: The axis handle is a two element vector and
+	so needs special treatment. Call newplot for the second axis.
+
+2008-03-27  Bill Denney  <bill at denney.ws>
+
+	* time/datenum.m: Allow vector inputs in any orientation.
+
+	* strings/validatestring.m: New function.
+	* strings/Makefile.in (SOURCES): Add it to the list.
+
+	* general/nargoutchk.m: New function.
+	* general/Makefile.in (SOURCES): Add it to the list.
+
+	* general/genvarname.m: New function.
+	* general/Makefile.in (SOURCES): Add it to the list.
+
+	* time/addtodate.m: New function.
+	* time/Makefile.in (SOURCES): Add it to the list.
+
+	* geometry/rectint.m: Vectorize and add more tests.
+
+2008-03-27  John W. Eaton  <jwe at octave.org>
+
+	* plot/__axis_label__.m: Use name of caller in error message.
+
+2008-03-27  David Bateman  <dbateman at free.fr>
+
+	* linear-algebra/planerot.m: Givens rotation function.
+
+2008-03-26  John W. Eaton  <jwe at octave.org>
+
+	* set/ismember.m: Set size of idx output correctly for empty args.
+	New tests.
+
+	* general/logical.m: Correctly handle empty args.  New tests.
+
+	* control/hinf/h2syn.m, general/__splinen__.m, general/gradient.m,
+	geometry/inpolygon.m, geometry/trimesh.m, geometry/triplot.m,
+	image/imagesc.m, io/csvread.m, io/csvwrite.m,
+	miscellaneous/edit.m, miscellaneous/tempname.m, plot/fill.m,
+	plot/patch.m, plot/ribbon.m, plot/surface.m, polynomial/mkpp.m,
+	polynomial/pchip.m, polynomial/spline.m, set/unique.m:
+	Texinfo fixes.
+
+2008-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/dmult.m: Handle scaling along arbitrary dimension.
+
+2008-03-26  S�ren Hauberg  <hauberg at gmail.com>
+
+	* polynomial/convn.m: New tests.
+
+2008-03-20  Ben Abbott  <bpabbott at mac.com>
+
+	* statistics/base/statistics.m: Calculate median and quantiles in
+	a manner consistent with method #7 used by GNU R.
+	* statistics/base/__quantile__.m, statistics/base/quantile.m,
+	statistics/base/prctile.m: New functions.
+	* statistics/base/Makefile.in (SOURCES): Add them to the list.
+ 
+2008-03-25  S�ren Hauberg  <hauberg at gmail.com>
+
+	* polynomial/convn.m: New function.
+	* polynomial/Makefile.in (SOURCES): Add it to the list.
+
+2008-03-25  David Bateman  <dbateman at free.fr>
+
+	* image/contrast.m: New function.
+	* image/Makefile.in (SOURCES): Add it to the list.
+	
+2008-03-24  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* pkg/pkg.m: Allow installation of already extracted packages.
+
+2008-03-24  David Bateman  <dbateman at free.fr>
+
+	* general/idivide.m: New function.
+	* general/Makefile.in (SOURCES): Add it to the list.
+
+	* miscellaneous/namelengthmax.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+	* strings/regexptranslate.m: New function.
+	* strings/Makefile.in (SOURCES): Add it to the list.
+
+2008-03-21  David Bateman  <dbateman at free.fr>
+
+	* specfun/reallog.m, specfun/realpow.m, specfun/realsqrt.m:
+	New functions.
+	* specfun/Makefile.in (SOURCES): Add them to the list.
+
+2008-03-20  David Bateman  <dbateman at free.fr>
+
+	* general/tril.m, general/triu.m: Fail if input is a structure.
+
+	* miscellaneous/cast.m: Also allow cast to "char".
+
+	* general/rotdim.m: Ensure k is an integer scale.
+
+	* general/circshift.m: If matrix is empty fast return.
+
+2008-03-20  Jaroslav Hajek  <highegg at localhost.localdomain>
+
+	* linear-algebra/subspace.m: Check number of arguments, number
+	of dimensions of arguments and matching dimensions.
+
+2008-03-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* linear-algebra/subspace.m: New function.
+	* linear-algebra/subspace.m: New function.
+
+2008-03-19  Emil Lucretiu  <emil at la.mine.nu>
+
+	* signal/sinetone.m: Ensure integral number of samples.
+
+2008-03-19  Michael D. Godfrey  <godfrey at isl.stanford.edu>
+
+	* plot/__go_draw_axes__.m: Additional correction for symbol codes.
+
+2008-03-19  Ben Abbott  <bpabbott at mac.com>
+	
+	* statistics/base/mode.m: Add NDArray tests.
+
+2008-03-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* statistics/distributions/exppdf.m,
+	statistics/distributions/expcdf.m,
+	statistics/distributions/expinv.m,
+	statistics/distributions/exprnd.m: Doc fix.
+
+2008-03-19  David Bateman  <dbateman at free.fr>
+
+	* statistics/base/mode.m: Fix for row vectors.
+
+	* plot/__scatter__.m: Modify for change of markersize in
+	__go_draw_axes__.m and for compatibility.
+	* plot/__go_draw_axes__.m: Don't divide the marker size by 6
+	twice.
+	* plot/scatter3.m: Doc fix.
+
+2008-03-18  Ben Abbott  <bpabbott at mac.com>
+
+	* specfun/beta.m: Fix for negative inputs.
+
+2008-03-18  Michael D. Godfrey  <godfrey at isl.stanford.edu>
+
+	* plot/__go_draw_axes__.m: Use correct symbol codes.
+
+2008-03-14  Kai Habel  <kai.habel at gmx.de>
+
+        * plot/__go_draw_axes__.m: Expicitly set gnuplot user
+        style to default to avoid wrong mesh color in some cases.
+
+2008-03-12  David Bateman  <dbateman at free.fr>
+
+	* geometry/griddata3.m: Use griddatan and not griddata
+	internally. Return vi and not yi. Add test code.
+
+2008-03-11  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Use get to access hidden properties.
+	Use strcmpi when comparing string properties.
+
+	* io/csread.m, io/csvwrite.m, io/dlmwrite.m: Style fixes.
+
+2008-03-11  Kai Habel  <kai.habel at gmx.de>
+
+        * plot/__go_draw_axes__.m: Plot surfaces in front of axes.
+        Allow plotting of uniform colored mesh plots with and
+        w/o hidden line removal.
+
+2008-03-11  David Bateman  <dbateman at free.fr>
+
+	* io/dlmwrite.m, io/csvread.m, io/csvwrite.m: Files ported from
+	octave-forge.
+	* io/Makefile.in (SOURCES): Add them here.
+
+2008-03-07  John W. Eaton  <jwe at octave.org>
+
+	* plot/contourf.m: Set axes layer property to "top".
+
+	* plot/__go_draw_axes__.m: Handle tickdir property.
+
+2008-03-06  John W. Eaton  <jwe at octave.org>
+
+	* plot/hist.m: Avoid temporaries.
+	Allow matrix arguments when number of bins > 30.
+	From Robert S. Mahurin <rob at utk.edu>.
+
+	* plot/ChangeLog: Handle axes linewidth property.
+
+	* plot/__go_draw_axes__.m: Adjust markersize by a factor of 1/6.
+
+	* general/interpn.m: New test.
+
+2008-03-05  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/roots.m: Catch Infs and/or NaNs.
+
+2008-03-05  Sebastien Loisel  <loisel at temple.edu>
+
+	* polynomial/roots.m: Apply a scaling factor to the removal of the
+	leading zeros.
+
+2008-03-04  John W. Eaton  <jwe at octave.org>
+
+	* plot/print.m: Fix oops in applying last change.
+
+2008-03-04  Bill Denney  <bill at denney.ws>
+
+	* plot/allchild.m, plot/findall.m: New functions.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+
+	* geometry/rectint.m: New function.
+	* geometry/Makefile.in (SOURCES): Add it to the list.
+
+2008-03-04  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* pkg/pkg.m (pkg:configure_make): Make it work with recent changes in
+	isspace handling with cell arrays of strings.
+
+2008-03-04  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/polyfit.m: Modified tests to respect a relative tolerance.
+
+	* plot/print.m: Accept a figure handle as an optional input.
+ 
+2008-02-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/print.m: Handle gif and jpg devices.
+
+2008-02-28  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (get_old_gnuplot_color): New subfunction.
+	Use it to replace repeated if/elseif blocks.
+
+2008-02-28  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/__go_draw_axes__.m: If facecolor property of a surface is
+	"none", don't use pm3d mode and set linestyle correctly. 
+
+2008-02-25  Ben Abbott  <bpabbott at mac.com>
+
+	* control/system/zpout.m, finance/irr.m, general/int2str.m,
+	general/num2str.m, miscellaneous/bug_report.m,
+	miscellaneous/copyfile.m, miscellaneous/dir.m,
+	miscellaneous/edit.m, miscellaneous/fullfile.m,
+	miscellaneous/mkoctfile.m, miscellaneous/movefile.m,
+	miscellaneous/tempdir.m, miscellaneous/unpack.m,
+	path/__extractpath__.m, pkg/pkg.m, plot/__ezplot__.m,
+	plot/__go_draw_axes__.m, plot/legend.m, plot/print.m,
+	signal/spectral_adf.m, signal/spectral_xdf.m,
+	statistics/tests/z_test.m, statistics/tests/z_test_2.m,
+	strings/Makefile.in, strings/strcat.m, strings/strvcat.m,
+	testfun/assert.m, testfun/demo.m, testfun/speed.m,
+	testfun/test.m: Use cstrcat instead of strcat.
+
+	* strings/strcat.m: New compatible version.
+
+	* strings/cstrcat.m: Rename from strings/strcat.m.
+
+2008-02-25  John W. Eaton  <jwe at octave.org>
+
+	* strings/isstrprop.m: New file.
+
+2008-02-25  Ryan Hinton  <rwh4s at virginia.edu>
+
+	* miscellaneous/unpack.m: Use "-f -" args for tar.
+
+2008-02-24  John W. Eaton  <jwe at octave.org>
+
+	* specfun/log2.m: Ensure returned value of F strictly less than 1.
+	From Dave Hawthorne <davehawthorne at ieee.org>.
+
+2008-02-22  Ben Abbott  <bpabbott at mac.com>
+
+	* specfun/legendre.m: Doc fix.
+
+2008-02-22  David Bateman  <dbateman at free.fr>
+
+	* sparse/pcg.m, sparse/spdiags, spstats.m: Remove references to
+	spdiag.
+	
+2008-02-22  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/fullfile.m: Improve handling of empty args and
+	args ending with filesep.
+
+	* control/base/__stepimp__.m: Don't use subplot for just one plot.
+
+2008-02-21  John W. Eaton  <jwe at octave.org>
+
+	* image/imshow.m: Call axis ("image").
+	From Michael G. Ross <mgross at MIT.EDU>.
+
+	* plot/errorbar.m: If nargout > 0, return vector of handles to
+	line objects.
+	* plot/__go_draw_axes__.m: Improve handling of line style for
+	errorbar plots.
+
+2008-02-20  Marco Caliari  <marco.caliari at univr.it>
+
+	* specfun/legendre.m: Accept normalization options ("sch", "norm"),
+	and improve stability for higher orders.
+
+2008-02-20  John W. Eaton  <jwe at octave.org>
+
+	* strings/strcat.m: Detect cellstr args.
+
+2008-02-20  David Bateman  <dbateman at free.fr>
+
+	* sparse/colperm.m, sparse/nonzero.m, sparse/spdiags.m,
+	sparse/spfun.m, sparse/spones.m, sparse/sprand.m,
+	sparse/sprandn.m, sparse/sprandsym.m, sparse/spy.m: Use generic
+	version of find rather than spfind.
+
+2008-02-19  Ben Abbott  <bpabbott at mac.com>
+
+	* miscellaneous/edit.m: New option EDITINPLACE.  Prefer file list
+	rather than path list.  Return option structure with "get all".
+
+	* polynomial/polyfit.m: Use QR decomposition.  Handle
+	normalization option.
+	* polynomial/polyval.m: Normalize dependent variable.  Optionally
+	generate 50% prediction intervals.
+
+	* miscellaneous/ver.m: Include package version information in
+	output.  Improve consistency with Matlab.
+
+2008-02-19  John W. Eaton  <jwe at octave.org>
+
+	* pkg/pkg.m: Style fixes.
+
+2008-02-19  Carlo de Falco  <carlo.defalco at gmail.com>
+
+	* pkg/pkg.m: Handle 'describe' command.
+	(parse_pkg_idx, print_package_description): New subfunctions.
+	
+2008-02-19  Bill Denney  <bill at denney.ws>
+
+	* time/datestr.m: Avoid confusion for datenum vectors that are 6
+	elements wide.
+
+2008-02-18  David Bateman  <dbateman at free.fr>
+
+	* general/rem.m, general/mod.m: Treat integer types correctly.
+
+2008-02-15  Timo Lindfors  <timo.lindfors at iki.fi>
+
+	* statistics/tests/kruskal_wallis_test.m: Handle ties.
+	* general/runlength.m: New function from Paul Kienzle.
+
+2008-02-15  Rolf Fabian  <r.fabian at jacobs-university.de>
+
+	* linear-algebra/cond.m: New optional second argument to
+	specify 1-norm, inf-norm, or frobenius-norm. 
+
+2008-02-12  Kostas Poulios  <poulios.konstantinos at googlemail.com>
+
+	* plot/__quiver__.m: make arrow head be in z-plane of the arrow
+	body. Allow the linespec to specify the arrow color.
+
+2008-02-12  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/cast.m: Also treat the logical type.
+
+	* plot/__go_draw_axes__.m: Set pm3d implict to fix colorbars on
+	contour plots.
+
+ 	* plot/__go_draw_axes__.m: Use the cdatamapping property to set
+	the cbrange.
+	* plot/__img__.m: Set cdatamapping to "direct".
+	* plot/imagesc.m: Set cdatamapping to "scaled".
+
+2008-02-08  Julien Pommier  <pommier at pianoteq.com>
+
+	* audio/wavread.m: Limit data read to end of data chunk.
+
+2008-02-08  David Bateman  <dbateman at free.fr>
+
+	* plot/__contour__.m: Respect the graphic handle options that are
+	passed.
+	* plot/__go_draw_axes__.m: Respect the linewidth for patch objects.
+
+2008-02-01  Dave Goel  <deego3 at gmail.com>
+
+	* signal/arch_rnd.m: Correctly index E and Y vectors.
+
+2008-02-01  Bill Denney  <bill at denney.ws>
+
+	* time/weekday.m: Allow vector inputs and speed up.
+	* time/eomday.m: Return column vector for column vector inputs.
+
+2008-01-30  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/edit.m: Use "## Created: DATE" instead of "initial
+	revision".
+
+	* plot/Makefile.in (SOURCES): Include __plt2sv__.m and
+	__plt2vs__.m in the list.
+
+	* miscellaneous/tempdir.m: Append filesep to name for
+	compatibility.  Warn if not a directory or directory does not
+	exist.
+
+	* strings/deblank.m: Improve compatibility.
+
+2008-01-29  John W. Eaton  <jwe at octave.org>
+
+	* strings/str2double.m: Delete unused variable FLAG_OCTAVE.
+
+2008-01-28  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/xlabel.m, plot/ylabel.m, plot/zlabel.m:
+	Return the label handle, not the current axis handle.
+
+2008-01-25  Alexander Barth  <barth.alexander at gmail.com>
+
+	* general/interpn.m: Compatibility fix. Don't ndgrid vector
+	abscissa.
+	
+2008-01-25  David Bateman  <dbateman at free.fr>
+
+	* general/__splinen__.m: Treat mixed orientation vectors.
+	* plot/__scatter__.m: Remove NaN values from data.
+	* plot/__patch__.m: Vectorize treatment of trailing NaN values.
+
+2008-01-25  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* linear-algebra/trace.m: Test cases for non 2-d args.
+
+2008-01-25  James Packer  <james.packer at wadh.ox.ac.uk>
+
+	* geometry/griddata3.m: Call griddata, not gridata.
+
+2008-01-24  Schloegl Alois  <alois.schloegl at tugraz.at>
+
+	* linear-algebra/trace.m: Require 2-d args.  Handle vectors properly.
+
+2008-01-22  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* linear-algebra/cond.m, linear-algebra/trace.m:
+	Move tests here from test/test_linalg.m.
+	
+	* general/diff.m, general/fliplr.m, general/flipud.m,
+	general/logspace.m, general/rot90.m, general/shift.m, general/tril.m,
+	general/triu.m, linear-algebra/vec.m, linear-algebra/vech.m,
+	special-matrix/hankel.m, special-matrix/hilb.m,
+	special-matrix/invhilb.m, special-matrix/sylvester_matrix.m,
+	special-matrix/toeplitz.m, special-matrix/vander.m:
+	Move tests here from test/test_matrix.m.
+	
+	* general/isscalar.m, general/issquare.m, general/isvector.m:
+	Move tests here from test/test_number.m.
+	
+	* deprecated/polyinteg.m, polynomial/compan.m, polynomial/conv.m,
+	polynomial/deconv.m, polynomial/poly.m, polynomial/polyderiv.m,
+	polynomial/polyfit.m, polynomial/polyreduce.m, polynomial/polyval.m,
+	polynomial/polyvalm.m, polynomial/roots.m:
+	Move tests here from test/test_poly.m.
+
+	* signal/unwrap.m:
+	Move tests here from test/test_signal.m.
+
+	* statistics/base/corrcoef.m, statistics/base/cov.m,
+	statistics/base/kurtosis.m, statistics/base/mahalanobis.m,
+	statistics/base/mean.m, statistics/base/median.m,
+	statistics/base/skewness.m, statistics/base/std.m:
+	Move tests here from test/test_stats.m.
+
+	* general/int2str.m, general/num2str.m, strings/bin2dec.m,
+	strings/blanks.m, strings/deblank.m, strings/dec2bin.m,
+	strings/dec2hex.m, strings/findstr.m, strings/hex2dec.m,
+	strings/index.m, strings/rindex.m, strings/split.m, strings/str2mat.m,
+	strings/str2num.m, strings/strcat.m, strings/strrep.m,
+	strings/substr.m:
+	Move tests here from test/test_string.m.
+
+	* miscellaneous/computer.m, miscellaneous/ls.m,
+	miscellaneous/version.m, time/asctime.m, time/clock.m, time/ctime.m,
+	time/date.m, time/etime.m, time/is_leap_year.m:
+	Move tests here from test/test_system.m.
+
+2008-01-22  Schloegl Alois  <alois.schloegl at tugraz.at>
+
+	* specfun/erfinv.m: Replace z_old and z_new by a single variable z.
+	Simplify initial checks on argument values.
+
+2008-01-22  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/gnuplot_drawnow.m: New function corresponding to the
+	implementation of the gnuplot-based graphics backend (derived from
+	drawnow.m).
+	* plot/drawnow.m: Deleted (converted to C++).
+
+2008-01-15  Rolf Fabian  <Rolf.Fabian at gmx.de>
+
+	* linear-algebra/__norm__.m: Only scale if inf norm is finite.
+	New tests.
+
+2008-01-18  John W. Eaton  <jwe at octave.org>
+
+	* optimization/sqp.m: End each function with endfunction.
+
+2008-01-18  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/residue.m: For each group of pole multiplicity, set
+	the poles of the group to the value of the group's average.
+
+2008-01-17  Tetsuro KURITA  <tkurita at mac.com>
+
+	* plot/print.m: Handle PDF output.
+	* plot/drawnow.m: Add "PDF" in a list of enhanced_terminals. 
+
+2008-01-17  John W. Eaton  <jwe at octave.org>
+
+	* path/savepath.m: Print newline before initial comment line.
+	Double up single quote characters.
+	* path/__extractpath__.m: Return just the path as a string.
+	Undo single quote character doubling.
+
+	* path/pathdef.m: Avoid eval.  Simplify.
+
+	* path/pathdef.m: Use fullfile instead of concatenating with filesep.
+	* path/__extractpath__.m, path/savepath.m: Use unwind_protect to
+	avoid possible file descriptor leak.
+
+2008-01-17  Ben Abbott  <bpabbott at mac.com>
+
+	* path/savepath.m: Warn if modified file is not explicitly specified.
+	* startup/main-rcfile: Call atexit ("__finish__").
+
+2008-01-16  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (__do_enhanced_option__): New subfunction.
+	Use it to disable enhanced mode for individual labels and titles.
+
+	* startup/Makefile.in (SOURCES): Add __finish__.m to the list.
+	(install install-strip, uninstall): Handle function files.
+
+2008-01-16  Ben Abbott  <bpabbott at mac.com>
+
+	* startup/__finish__.m: New file.
+	* path/__extractpath__.m, path/matlabroot.m,
+	path/pathdef.m: New files.
+	* path/Makefile.in (SOURCES): Add them to the list.
+
+2008-01-15  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* special-matrix/vander.m: Vectorize.  New test.
+
+	* elfun/acot.m, elfun/acoth.m, elfun/acsc.m, elfun/acsch.m,
+	elfun/asec.m, elfun/asech.m, elfun/cot.m, elfun/coth.m,
+	elfun/csc.m,elfun/csch.m, elfun/lcm.m, elfun/sec.m, elfun/sech.m,
+	general/rem.m, miscellaneous/bincoeff.m, miscellaneous/xor.m,
+	specfun/beta.m, specfun/log2.m, specfun/pow2.m:
+	Move tests here from test/test_arith.m.
+
+2008-01-15  John W. Eaton  <jwe at octave.org>
+
+	* linear-algebra/__norm__.m: Use sum(abs(x),2), not sum(abs(x.')).
+
+2008-01-15  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/drawnow.m, plot/__go_draw_figure__.m, plot/__go_draw_axes__.m: 
+	Call __get__ instead of get.
+
+2008-01-15  Ben Abbott  <bpabbott at mac.com>
+
+	* linear-algebra/__norm__.m: Avoid divide by zero error for
+	Frobenius norm if matrix is all zeros.  Use transpose instead of
+	hermitian operator.
+
+2008-01-14  Bill Denney  <bill at denney.ws>
+
+	* plot/axis.m: Correctly handle "tight" and "image" options.
+
+2008-01-14  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/hsv2rgb.m, image/ntsc2rgb.m, image/rgb2hsv.m,
+	image/rgb2ntsc.m: Also accept images as input.
+
+	* image/gray2ind.m: Handle image type other than double.
+	Improve error checking and documentation.
+
+2008-01-14  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (get_fontname_and_size): Use strcmpi
+	instead of calling tolower on first arg.  Default font name is
+	Helvetica, not helvetica.  Don't downcase user-specified font name.
+	(__maybe_munge_text__): Fix typo.
+
+	* optimization/sqp.m: Fix function definitions in test code.
+
+2008-01-12  John W. Eaton  <jwe at octave.org>
+
+	* plot/gnuplot_binary.in: New file.
+	* plot/gnuplot_binary.m: Delete.
+	* plot/Makefile.in (SOURCES): Remove gnuplot_binary.m from the list.
+	(SOURCES_IN, GEN_M): New macros.
+	(DISTFILES): Include $(SOURCES_IN) in the list.
+	(FCN_FILES): Include $(GEN_M) in the list.
+	(all): Depend on $(GEN_M).
+	($(GEN_M): %.m : $(TOPDIR)/Makeconf): New pattern rule.
+	(distclean): Also remove $(GEN_M).
+
+2008-01-11  John W. Eaton  <jwe at octave.org>
+
+	* optimization/sqp.m: New test from example in doc string.
+
+2008-01-10  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/mpoles.m: Avoid cases where poles could be assigned
+	to more than one multiplicity group.
+
+2008-01-10  John W. Eaton  <jwe at octave.org>
+
+	* plot/gnuplot_binary.m: New file.
+	* plot/Makefile.in (SOURCES): Add it to the list.
+
+2008-01-09  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: Fail if filename includes a directory part that
+	does not exist.
+
+2008-01-07  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/copyfile.m, miscellaneous/movefile.m:
+	Error if glob call fails to match any files.
+
+2008-01-04  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* strings/strtrim.m: Doc fix.
+
+2008-01-04  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* general/sub2ind.m, general/ind2sub.m: Doc fix.
+
+2008-01-04  S�ren Hauberg   <hauberg at gmail.com>
+
+	* set/create_set.m, set/union.m: Accept "rows" argument.
+
+2008-01-02  John W. Eaton  <jwe at octave.org>
+
+	* plot/print.m: Correctly handle pbm terminal.
+
+2007-12-28  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/edit.m: Use strcat instead of fullfile to add file
+	extensions.
+
+2007-12-28  David Bateman  <dbateman at free.fr>
+
+	* ezcontourf.m, ezcontour.m, ezmeshc.m, ezmesh.m, ezplot3.m,
+	__ezplot__.m, ezpolar.m, ezsurfc.m, ezsurf.m: New functions.
+	* Makefile.in (SOURCES): Add to the sources.
+
+2007-12-28  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/pcolor.m: Swap 1st and 2nd argument in call to meshgrid.
+	Remove unnecessary call of size function.
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+2007-12-21  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/imshow.m: Accept empty value for display_range.
+
+2007-12-20  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* pkg/pkg.m: Add .lib as architecture-dependent suffix.
+
+2007-12-19  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/imshow.m: Store uint8 images as doubles.  Handle default
+	display ranges correctly.
+
+2007-12-19  Alexander Barth  <barth.alexander at gmail.com>
+	    Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/contourc.m: Allow usage of irregular spaced x, y data.
+
+2007-12-19  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/edit.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+2007-12-19  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/__bar__.m: Handle "basevalue" option.
+	* plot/__bars__.m: New arg, base_value.
+
+2007-12-17  David Bateman  <dbateman at free.fr>
+
+	* plot/rose.m, plot/feather.m, plot/compass.m: New functions
+	* plot/Makefiles (SOURCES): Add them to the sources
+	* plot/polar.m: Set the x and y limits to the maximum polar
+	radius. Set the axes to be square.
+	* plot/__go_draw_axes__.m: Allow {x|y}axislocation to be "zero"
+	and print axis at zero if this is used.
+
+	* plot/__go_draw_axes__.m: Use "set pm3d explicit" so that
+	contours can overlay pcolor plots. Priveldge no hidden line
+	removal when there are multiple objects in the plot.
+
+2007-12-17  Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m:  Fix mirrored tics and borders for
+	set (gca (), "[xy]axislocation", "{right|top}", "box", "off").
+
+2007-12-17  Ben Abbott  <bpabbott at mac.com>
+
+         * miscellaneous/run.m: Replace script with f when looking for
+	 file to run.
+
+2007-12-14  David Bateman  <dbateman at free.fr>
+
+	* plot/contour3.m, plot/__contour__.m: Handle linespec.
+	* plot/contour.m: Doc fix.
+	* plot/__go_draw_axes__.m (case "patch"): Include "lt" in lt string.
+	Include linetype in withclause.
+
+	* plot/__go_draw_axes__.m (__calc_dimensions__): New function.
+	Use it to determine dimensions.  Consolidate all 3-d settings.
+
+2007-12-13  John W. Eaton  <jwe at octave.org>
+
+	* image/imshow.m: Turn axis visibility off.
+	Don't scale true color images.
+	* image/image.m: Set axis layer property to "top".
+
+2007-12-12  John W. Eaton  <jwe at octave.org>
+
+	* image/loadimage.m: Avoid calling eval.  Avoid calling exist.
+
+	* plot/pie.m: Avoid calling "exist".
+
+	* linear-algebra/condest.m: Use nargin instead of size(varargin,2).	
+	Condense argument processing logic.  Allow 6 arguments.
+	Use issquare.  Avoid calling "exist".
+
+	* plot/__go_draw_axes__.m: Handle the axes layer property.
+
+2007-12-12  David Bateman  <dbateman at free.fr>
+
+	* plot/ellipsoid.m: Port from octave-forge, editing for style.
+	* plot/Makefile.in (SOURCES): Add to the sources.
+
+2007-12-11  John W. Eaton  <jwe at octave.org>
+
+	* plot/surf.m: Set xgrid, ygrid, and zgrid on here.
+	* plot/surface.m: Not here.
+
+	* plot/__go_draw_axes__.m: Always use "set grid front".  Send a
+	subsequent "unset grid" if there is no grid.
+
+	* plot/__go_draw_axes__.m: Include "front" in "set label" options.
+
+	* plot/surface.m: Don't set facecolor property in call to
+	__go_surface__.
+
+	* plot/__plt2vs__.m, plot/__plt2sv__.m: New functions.
+	* plot/__plt2__.m: Handle scalar-vector and vector-scalar cases.
+
+2007-12-11  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/__patch__.m: Fix typo. Improve argument checking, so that a
+	color string is not taken as z value.
+
+	* plot/slice.m: Remove unused variable, set xgrid, ygrid, and
+	zgrid to "on" and box to "off" for used axes.
+
+	* plot/__go_draw_axes__.m, plot/plot3.m, plot/ribbon.m,
+	plot/slice.m: Use size_equal(var1,var2,...) when possible.
+
+2007-12-11  David Bateman  <dbateman at free.fr>
+
+	* miscelleaneous/fullfile.m: Ignore empty arguments.
+
+	* sparse/spstats.m: Drop argument to Fsparse to force mutation.
+	* statistics/base/mode.m: Ditto.
+
+	* plot/__plt_get_axis_arg__.m: Ignore integer valued handles as
+	object handles are all now non integer.
+
+2007-12-10  John W. Eaton  <jwe at octave.org>
+
+	* plot/sombrero.m, plot/peaks.m: Use surf instead of mesh.
+
+	* general/issymmetric.m: Use ' instead of .' for compatibility
+	with previous versions of Octave.
+	* general/ishermitian.m: Delete.
+	* general/Makefile.in (SOURCES): Remove ishermitian.m from the list.
+
+	* plot/fplot.m: In N is not specified, increase initial number of
+	points from 3 and 5 to 5 and 8.
+
+	* signal/detrend.m: Move tests here from test/test_signal.m.
+	Loosen tolerance on first test from 10*eps to 20*eps.
+
+	* finance/rate.m: Don't request info from fsolve.
+
+2007-12-10  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/__line__.m: Pass initial property/value pairs to __go_line__.
+	* plot/surface.m: Pass initial property/value pairs to __go_surface__.
+
+2007-12-10  David Bateman  <dbateman at free.fr>
+
+	* image/image.m: Rewritten to allow trailing properties to be
+	passed to underlying image object.
+	* image/__img__.m: Pass additional arguments to __go_image__.
+	* plot/__patch__.m: Don't set clim, rely on autoscaling.
+
+2007-12-10  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: If we have a grid, send "set grid
+	front" to gnuplot.
+
+2007-12-10  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Issue "set view map" for pcolor, and "set
+	border front" from images.
+	* plot/__go_draw_figure__.m: Issue "set autoscale fix" for gnuplot.
+	* plot/pcolor.m: Set axis "box" property.
+	* plot/title.m, plot/xlabel.m, plot/ylabel.m, plot/xlabel.m:
+	Mark as commands.
+
+2007-12-07  David Bateman  <dbateman at free.fr>
+
+	* plot/surf.m: Don't set facecolor property.
+
+2007-12-06  John W. Eaton  <jwe at octave.org>
+
+	* plot/print.m: Pass mono to drawnow.
+	* plot/drawnow.m: New arg, mono.  Pass it to __go_draw_figure__.
+	* plot/__go_draw_figure__.m: New arg, mono.  Pass it to __go_draw_axes.
+	* plot/__go_draw_axes__.m: New arg, mono.  If mono is true,
+	disable color specifications.
+
+	* general/issymmetric.m: Move tests here from test/test_number.m
+
+2007-12-06  Jason Riedy  <ejr at cs.berkeley.edu>
+
+	* general/issymmetric.m: To keep its argument sparse and the
+	function quick, use the infinity norm rather than the 2-norm.
+	Also measure the symmetric part rather than the Hermitian part.
+	* general/ishermitian.m: New file.  Measure the Hermitian part.
+	* general/Makefile.in: Add ishermitian.m to SOURCES.
+
+2007-12-04  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Omit "font \"NAME,SIZE\"" in gnuplot
+	text and label commands if font is "*".
+
+	* linear-algebra/krylov.m: Doc fixes.
+	From Marco Caliari <caliari at sci.univr.it>.
+
+2007-12-04  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/shading.m: Use __plt_get_axis_arg__ for optional axes argument.
+	Add "## PKG_ADD: mark_as_command axis" line.
+
+2007-12-03  John W. Eaton  <jwe at octave.org>
+
+	* contour.m, contour3.m, contourc.m, contourf.m, cylinder.m,
+	fplot.m, plot3.m, plotyy.m, quiver3.m, scatter.m, scatter3.m,
+	slice.m, sombrero.m, stairs.m, stem.m, stem3.m:
+	Generate demos from examples.
+
+2007-12-03  David Bateman  <dbateman at free.fr>
+
+	* testfun/test.m: Disable "testif" test block to avoid spurious
+	skipped test for "make check". Avoid printing variables for
+	skipped tests.
+
+	* testfun/test.m: Add "testif" type to allow for conditional tests.
+
+	* plot/plotyy.m: Use activepositionproperty property of axes
+	object. Set second axis color to "none".
+	* plot/__go_draw_axes__.m: Respect the activepositionproperty
+	property of the axis objects.
+
+2007-12-03  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* linear-algebra/condest.m: Loosen tolerance in test.
+
+2007-12-02  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Remove unnecessary call to
+	get_data_limits.
+
+2007-11-30  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Don't compute data or axis limits.
+	(get_data_limits, get_axis_limits): Delete.
+
+2007-11-30  David Bateman  <dbateman at free.fr>
+
+	* plot/__scatter__.m: Avoid out of bounds varargin element access.
+
+	* plot/__go_draw_axes__.m (do_tics_1): regexprep the cell array of
+	tick labels rather than one by one on the labels themselves.
+	* plot/pareto.m: Bug in numerical labels fixed. Bug in search for
+	95% crossing fixed.
+
+2007-11-29  David Bateman  <dbateman at free.fr>
+
+	* plot/pareto.m: New file.
+	* plot/Makefile.in (SOURCES): Add it to the sources.
+	* plot/__go_draw_axes__.m (do_tics1): Replace "%" with "%%" in tic
+	marks to avoid gnuplot error about formating. More colorspec to
+	after the tics.
+	* plot/plotyy.m: More generic check for appropriate axis color.
+
+	* plot/__stem__.m: New file based on old stem.m expanded to treat
+	2- and 3-D.
+	* plot/stem3.m: New function.
+	* plot/Makefile.in (SOURCES): Add them to the sources.
+	* plot/stem.m: Adapt to use __stem__.
+
+2007-11-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/contour.m, plot/contour3.m, plot/fill.m, plot/patch.m,
+	plot/surf.m, plot/surface.m: Don't return handle value unless
+	requested.
+
+	* plot/patch.m: Omit isnan check on handle returned from
+	__plt_get_axis_arg__.
+
+	* plot/__plt_get_axis_arg__.m: Don't fail if current figure exists
+	but has no axes.
+
+2007-11-28  David Bateman  <dbateman at free.fr>
+
+	* __plt_get_axis_handle__.m: Also allow hggroup and return axes
+	ancestor. If leading argument is logical set variable nogca to see
+	if gca() should be called if there is no active handle found.
+	* __bar__.m, caxis.m, scatter.m, contourf.m, __axes_limits__.m,
+	fill.m,  surf.m, meshz.m, axis.m, pie.m, contour.m,
+	quiver.m, area.m, grid.m, cylinder.m, contour3.m, surface.m,
+	patch.m, scatter3.m, plot.m, sphere.m, quiver3.m, plotyy.m,
+	xlabel.m, ylabel.m, surfnorm.m, zlabel.m: Adapt to use
+	__plt__get_axis_arg__ to find axis handle.
+	* polar.m: Typo.
+
+2007-11-28  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (get_data_limits): Delete unused arg TX.
+
+2007-11-28  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/drawnow.m: Fix typo.
+
+2007-11-27  David Bateman  <dbateman at free.fr>
+
+	* plot/errorbar.m, plot/loglog.m, plot/loglogerr.m, plot/polar.m,
+	plot/semilogx.m, plot/semilogxerr.m, plot/semilogy.m,
+	plot/semilogyerr.m: Treat an axis handle as the first argument.
+
+	* plot/meshz.m: New function.
+	* plot/Makefile.in (SOURCES): Add it to the list.
+	* plot/surface.m: Allow surface to accept an axis handle as the
+	first argument.
+	* plot/meshc.m: Extract z from the the surface object rather than
+	varargin so that we can rely on code in surface to treat leading
+	axis handles.
+
+	* plot/__go_draw_axes__.m: Add nomirror to "set ytics" and "set
+	y2tics" in the case of a plotyy plot.
+	* plot/plotyy.m: ensure the position property is set correct for
+	the second axis, by setting it after the plot itself. In the case
+	of a plot that returns multiple handles, base the color selection
+	on the first.
+
+2007-11-27  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/__go_draw_axes__.m: Set quadrilateral color according to
+	z-value of vertex 'c3'.
+
+2007-11-27  John W. Eaton  <jwe at octave.org>
+
+	* image/image.m: Allow nargin == 0 case to work again.
+
+2007-11-27  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_figure__.m: Force a multiplot mode with a
+	colorbar, to ensure that the colorbar is on the canvas for png and
+	postscipt outputs.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* sparse/spstats.m, statistics/base/mode.m: More care with sparse
+	return values.
+
+	* plot/plotyy.m: New function
+	* plot/Makefile.in (SOURCES): Add it here.
+	* plot/__go_draw_axes__.m: Force axis margins for plotyy. Set text
+	color for {x|y|z}label and {x|y|z}tics. Also force the label of 
+	{x|y}label to respect the axis position.
+	* plot/xlabel.m, plot/ylabel.m, plot/zlabel.m: Accept an axis
+	handle as the first argument.
+	
+	* pkg/pkg.m (pkg:install): When loading the installed packages
+	index into installed_pkgs_lst and not descriptions..
+
+	* plot/quiver3.m, plot/surfnorm.m, plot/__quiver__.m: New functions.
+	* plot/Makefile.in (SOURCES): Add them to the sources.
+	* plot/quiver.m: Modify to use __quiver__.m.
+
+	* plot/hist.m: Avoid saturation when the x values are in an
+	inetger type.
+
+2007-11-26  Jason Riedy  <ejr at cs.berkeley.edu>
+
+	* linear-algebra/condest.m, linear-algebra/onenormest.m: New
+	functions.
+	* linear-algebra/Makefile.in (SOURCES): Add them to the sources.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Prevent the cbrange from being of zero
+	extent.
+
+	* plot/colorbar.m: New function.
+	* plot/Makefile.in (SOURCES): Add it to the sources.
+	* plot/__go_draw_axes__.m: Calculate the colorbar position,
+	precalculate the clim, set pm3d except for mesh.
+	* plot/__contour__.m: Don't scale the contours to clim, but rather
+	save the real values so that colorbar corresponds to the contour
+	levels.
+
+	* plot/stem.m: Set marker color the same as the line color. Draw 
+	a single discontinous line object for the stems.
+
+	* plot/sphere.m: New function ported from JHandles.
+	* plot/Makefile.in (SOURCES): Add it to the sources.
+
+	* plot/__go_draw_axes__.m: Pass the have_newer_gnuplot arg to
+	__maybe_munge_text__. Use it to reforce fontname for gnuplot 4.0
+	to get enhanced mode to work correctly for the X11 terminal.
+
+	* plot/imagesc.m, plot/image.m: Scale colormap to image and not
+	the reverse. Allow an axes handle to be passed and/or returned.
+	* plot/__go_draw_axes__.m: Autoscale colormap for images.
+
+	* plot/__go_draw_axes__.m: Add depthorder flag to "set pm3d" to
+	sort surface patches by their depth and not the order they are
+	rendered in.
+
+	* plot/__patch__.m: Set clim correctly.
+	* plot__go_draw_axes__.m: Allow patch objects to have markers, and 
+	the marker color is determined by the cmap.
+	* plot/scatter.m: New function to 2D scatter plots.
+	* plot/scatter3.m: New function to 3D scatter plots.
+	* plot/__scatter__.m: Support function for scatter plots
+	* Makefile.in (SOURCES): Ad dnew functions here.
+
+	* plot/drawnow.m (open_gnuplot_stream, init_gnuplot_stream):
+	Return whether the terminal supports enhanced text or not.
+	(drawnow:enhanced_term): New sub-function to determine if terminal
+	supports enhanced mode.
+	* plot/__go_draw_figure__.m: Accept enhanced flag and pass to
+	__go_draw_axes__.
+	* plot/__go_draw_axes__.m: Accept enhanced flag and munge text if
+	needed to support the enhanced mode.
+	* plot/print.m: Remove "enhanced" option as this is now treated in
+	drawnow.m.
+
+
+	* plot/caxis.m: New function to control the color axis limits.
+	* plot/Makefile.in (SOURCES): Include it.
+	* plot/axis.m: Allow the first argument to be an axes handle.
+	* plot/__go_draw_axes__.m: Move the setting of the caxis, also
+	autoscale caxis for patches. If any(isinf(clim)) don't set the
+	caxis limits.
+
+	* image/gmap40.m: New gnuplot 4.0 specific colormap fucntion.
+	* image/Makefile.in (SOURCES): Include it.
+	* plot/__bar__.h: Allow axis handles to be passed. Set the color
+	of the bars for the colormap. 
+	* plot/bar.m, plot/barh.m: Document that axis handles can be
+	passed.
+	* plot/__contour.m: Avoid possible divide by zero error.
+	* plot/contour.m: Missing semicolon.
+	* plot/surface.m: Don't attempt to set additional arguments if
+	there are none.
+	* plot/Makefile.in (SOURCES): Include __bars__.m
+	
+2007-11-19  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/__bar__.m: put bar creation code into separate function
+	to allow easy hook up from other graphic backends
+
+	* plot/__bars__.m: new function containing bar creation code
+
+2007-11-26  Alexander Barth  <barth.alexander at gmail.com>
+
+	* general/accumarray.m: Correct dimension check.
+
+2007-11-26  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/residue.m: Prepad along second dimension.
+	From Doug Stewart <dastew at sympatico.ca>.
+
+2007-11-26  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/cylinder.m, plot/slice.m: New functions.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+
+2007-11-14  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/patch.m: Handle arg may also be hggroup object.
+	Use ancestor to find parent axes object.
+
+2007-11-14  David Bateman  <dbateman at free.fr>
+
+	* plot/__contour__.m: Treat unclosed contours by adding NaN to
+	flag to patch that it is not closed. Allow z to take string
+	arguments and use it to flag that the contours are placed at the
+	z level of the contour itself.
+	* plot/__go_draw_axes__.m: Treat hidden line removal in patch
+	objects as well. Let hidden removal take precedence in case of a
+	conflict.
+	* plot/surface.m: Allow surface to treat handles being passed or
+	returned. Any additional arguments arr used to set the surface
+	handle.
+	* plot/contour3.m: New function
+	* plot/Makefile.in (SOURCES): Add it to the sources.
+
+2007-11-14  John W. Eaton  <jwe at octave.org>
+
+	* specfun/bessel.m: Update doc string from
+	src/DLD-FUNCTIONS/besselj.cc.
+
+2007-11-12  David Bateman  <dbateman at free.fr>
+
+	* plot/contour.m: Allow handles to be passed and returned. Split
+	the countour function itself into __contour__.m to be shared with
+	surfc and meshc.
+	* plot/__contour__.m: New file
+	* plot/Makefile.in (SOURCES): Add it to the sources.
+	* plot/__go_draw_axes.m: For patch objects don't attempt to patch
+	the face or edge if the facecolor or edge color are marked as
+	"none". Allow the edgecolor to be determined by the cdata in the
+	same manner as the facecolor. Fail if facecolor is not "none" and
+	a 3-D plot is desired, rather than ignoring zdata. Make the
+	storage of 3D/4D data consistent between line, surface and patch 
+	objects.
+	* plot/meshc.m: Use new __contour__.m to plot the contours.
+	* plot/surfc.m: Use new __contour__.m to plot the contours.
+
+	* plot/__go_draw_axes__.m (get_fontname_and_size):
+	Handle fontweight and fontangle properties.
+
+2007-11-12  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/spinmap.m, plot/ribbon.m: New functions.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+
+2007-11-12  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (get_fontname_and_size): New subfunction.
+	Use it to avoid duplicated code.
+
+2007-11-12  David Bateman  <dbateman at free.fr>
+
+	* plot/title.m: Fix return value for nargout > 0.
+
+	* plot/__go_draw_axes.m: Allow the font and fontsize to be
+	specified for the title, xlabel, ylabel and text objects.
+
+	* plot/__go_draw_axes.m: Allow arbitrary colormaps with gnuplot
+	4.0 and surface plots.
+
+2007-11-12  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/__patch__.m: Fix computation of faces when patch is defined
+	with X/Y/Z data.
+
+2007-11-09  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Correct test for have_data.
+	Correct logic in setting palette data.
+
+	* audio/wavread.m, control/base/__bodquist__.m,
+	control/base/dare.m, control/base/dlqr.m, control/hinf/h2norm.m,
+	control/system/c2d.m, control/system/is_detectable.m,
+	control/system/is_signal_list.m, control/system/is_stabilizable.m,
+	control/system/tfout.m, general/isdefinite.m,
+	linear-algebra/krylov.m, miscellaneous/compare_versions.m,
+	optimization/glpk.m, path/savepath.m, plot/findobj.m,
+	plot/shading.m, polynomial/mpoles.m, polynomial/polyint.m,
+	signal/freqz.m, signal/hurst.m, sparse/spfun.m, sparse/spones.m,
+	sparse/spstats.m, testfun/assert.m, testfun/fail.m,
+	testfun/test.m: Use specific end keywords.
+
+	* plot/surfc.m, plot/meshc.m: Don't change view if hold is on.
+
+2007-11-09  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/mesh.m, plot/pcolor.m, plot/surf.m, plot/surface.m:
+	Don't change view if hold is on.
+
+2007-11-09  David Bateman  <dbateman at free.fr>
+
+	* plot/hidden.m: New function.
+	* plot/Makefile.in (SOURCES): Add it here.
+	* plot/meshc.m, plot/mesh.m: Set facecolor to White for hidden
+	line removal.
+	* plot/__go_draw_axes__.m: If facecolor is white flag hidden line
+	removal and if it is "none" don't do hidden line removal.
+
+	* plot/legend.m: Also allow labels for surface and patch types.
+	* plot/__bar__.m: Split into separate patch pbjects to allow
+	setting of the legend.
+	* plot/__go_draw_axes__.m: Set titlespec from keylabel for patch
+	objects as well.
+
+	* plot/area.m, plot/__area__.m: New functions
+	* plot/Makefile.in (SOURCES): Add them to the list of files.
+
+	* plot/patch.m: Correctly handle case of axis handle as first arg.
+
+2007-11-09  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* sparse/spdiags.m: Tweak documentation entries to match other uses.
+
+2007-11-08  John W. Eaton  <jwe at octave.org>
+
+	* control/base/dcgain.m, control/base/dre.m,
+	control/base/impulse.m, control/base/step.m,
+	control/system/dmr2d.m, control/system/ord2.m,
+	control/system/sys2ss.m, control/system/sysdimensions.m,
+	control/system/sysgetsignals.m, control/system/sysout.m,
+	control/system/tfout.m, control/system/ugain.m,
+	control/system/zpout.m, control/util/strappend.m:
+	Don't fail with usage message if nargout is too large.
+
+	* control/hinf/h2syn.m, control/hinf/hinf_ctr.m,
+	control/hinf/hinfnorm.m, control/hinf/hinfsyn.m,
+	control/hinf/hinfsyn_chk.m, control/hinf/is_dgkf.m,
+	control/hinf/wgt1o.m, control/obsolete/dezero.m,
+	control/obsolete/dlqg.m, control/obsolete/minfo.m,
+	control/obsolete/packsys.m, control/obsolete/qzval.m,
+	control/obsolete/rotg.m, control/obsolete/series.m,
+	control/obsolete/swapcols.m, control/obsolete/swaprows.m,
+	control/obsolete/syschnames.m, control/obsolete/unpacksys.m,
+	control/system/__syschnamesl__.m,
+	control/system/__syscont_disc__.m,
+	control/system/__sysdefioname__.m, control/system/__sysgroupn__.m,
+	control/system/__tf2sysl__.m, control/system/__zp2ssg2__.m,
+	control/system/abcddim.m, control/system/buildssic.m,
+	control/system/c2d.m, control/system/cellidx.m,
+	control/system/d2c.m, control/system/dmr2d.m,
+	control/system/fir2sys.m, control/system/is_abcd.m,
+	control/system/is_controllable.m, control/system/is_detectable.m,
+	control/system/is_digital.m, control/system/is_observable.m,
+	control/system/is_stabilizable.m, control/system/is_stable.m,
+	control/system/jet707.m, control/system/listidx.m,
+	control/system/parallel.m, control/system/ss.m,
+	control/system/ss2sys.m, control/system/ss2zp.m,
+	control/system/starp.m, control/system/sys2ss.m,
+	control/system/sys2tf.m, control/system/sys2zp.m,
+	control/system/sysadd.m, control/system/sysappend.m,
+	control/system/sysconnect.m, control/system/syscont.m,
+	control/system/sysdimensions.m, control/system/sysdisc.m,
+	control/system/sysdup.m, control/system/sysgetsignals.m,
+	control/system/sysgroup.m, control/system/sysmin.m,
+	control/system/sysmult.m, control/system/sysout.m,
+	control/system/sysprune.m, control/system/sysreorder.m,
+	control/system/sysscale.m, control/system/syssetsignals.m,
+	control/system/syssub.m, control/system/sysupdate.m,
+	control/system/tf.m, control/system/tf2ss.m,
+	control/system/tf2sys.m, control/system/tfout.m,
+	control/system/zp.m, control/system/zp2ss.m,
+	control/system/zp2sys.m, control/system/zp2tf.m,
+	control/system/zpout.m, control/util/__outlist__.m,
+	control/util/__zgpbal__.m, control/util/axis2dlim.m,
+	control/util/prompt.m, control/util/sortcom.m,
+	control/util/zgfmul.m, control/util/zgfslv.m,
+	control/util/zginit.m, control/util/zgreduce.m,
+	control/util/zgrownorm.m, control/util/zgscal.m: Style fixes.
+
+2007-11-08  David Bateman  <dbateman at free.fr>
+
+	* plot/quiver.m: Fix arrowheads.
+
+2007-11-07  Ben Abbott  <bpabbott at mac.com>
+
+	* set/ismember.m: Call cell_ismember to handle cellstr args.
+	Handle "rows" argument.  New tests.
+	(cell_ismember): New function.
+
+2007-11-07  John W. Eaton  <jwe at octave.org>
+
+	* control/base/__bodquist__.m, control/base/__freqresp__.m,
+	control/base/__stepimp__.m, control/base/are.m,
+	control/base/ctrb.m, control/base/damp.m, control/base/dare.m,
+	control/base/dcgain.m, control/base/dgram.m, control/base/dlqr.m,
+	control/base/dre.m, control/base/impulse.m, control/base/lqe.m,
+	control/base/lqg.m, control/base/lqr.m, control/base/lsim.m,
+	control/base/ltifr.m, control/base/nichols.m,
+	control/base/nyquist.m, control/base/obsv.m, control/base/place.m,
+	control/base/rlocus.m, control/base/step.m, control/base/tzero.m:
+	Style fixes.
+
+2007-11-07  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* control/base/bode_bounds.m, control/base/dgram.m,
+	control/base/dlyap.m, control/base/freqchkw.m,
+	control/base/gram.m, control/base/place.m,
+	control/hinf/hinf_ctr.m, control/hinf/hinfsyn_chk.m,
+	control/hinf/hinfsyn_ric.m, control/system/is_sample.m,
+	control/system/is_signal_list.m, control/system/ss2tf.m,
+	control/system/sys2fir.m, control/system/sysgettsam.m,
+	control/system/sysgettype.m, control/system/sysreorder.m,
+	control/system/tf2sys.m, control/system/zp2tf.m,
+	control/util/axis2dlim.m, control/util/swap.m,
+	control/util/zgfmul.m, control/util/zgfslv.m,
+	control/util/zginit.m, control/util/zgreduce.m,
+	control/util/zgrownorm.m, control/util/zgscal.m,
+	control/util/zgsgiv.m, control/util/zgshsr.m, general/isa.m,
+	geometry/inpolygon.m, linear-algebra/housh.m,
+	miscellaneous/compare_versions.m, miscellaneous/inputname.m,
+	miscellaneous/run.m, quaternion/qconj.m,
+	quaternion/qcoordinate_plot.m, quaternion/qderiv.m,
+	quaternion/qderivmat.m, quaternion/qinv.m, quaternion/qmult.m,
+	quaternion/qtrans.m, quaternion/qtransvmat.m, signal/fractdiff.m,
+	signal/freqz_plot.m, signal/periodogram.m, signal/rectangle_lw.m,
+	signal/rectangle_sw.m, signal/sinc.m, signal/triangle_lw.m,
+	signal/triangle_sw.m, signal/yulewalker.m, sparse/colperm.m,
+	sparse/etreeplot.m, sparse/nonzeros.m, sparse/spalloc.m,
+	sparse/spones.m, sparse/spy.m, specfun/isprime.m,
+	statistics/distributions/empirical_cdf.m,
+	statistics/distributions/empirical_inv.m,
+	statistics/distributions/empirical_pdf.m,
+	statistics/models/logistic_regression_derivatives.m,
+	statistics/models/logistic_regression_likelihood.m: Check nargin.
+
+2007-11-07  David Bateman  <dbateman at free.fr>
+
+	* general/gradient.m: Correctly convert deltax and deltay scalar
+	values are scalars to vectors.
+
+	* plot/__go_draw_axes__.m: Fix surfaces for gnuplot 4.0 and for
+	the meshc.m function.
+	* plot/meshc.m: Also use the surface function.
+	
+	* plot/meshc.m, plot/quiver.m, plot/surfc.m, : New files.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+	Also add pcolor.m, shading.m, surf.m, and surface.m to the list.
+
+2007-11-07  Michael Zeising  <michael at michaels-website.de>
+
+	* audio/wavwrite.m, audio/wavwrite.m: Correct sample scaling.
+
+2007-11-07  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Also set have_data to false if any of
+	the data limits are infinite.
+	(get_data_limits): Don't do anything if xdat or tx are empty.
+	(get_axis_limits): Don't do anything if min_val or max_val are
+	infinite.
+
+2007-11-06  David Bateman  <dbateman at free.fr>
+
+	* plot/hist.m: Pass any additional arguments to bar for
+	treatment. Create a default x value that is always a vector.
+
+2007-11-06  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* pkg/pkg.m.m: Check for environment variables CC, CXX, AR, RANLIB
+	when calling ./configure and add quotes to preserve spaces.
+
+2007-11-06  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/pcolor.m, plot/shading.m, plot/surf.m, plot/surface.m:
+	New files.
+	* plot/mesh.m: Call surface to do the real work.
+	* plot/__go_draw_axes__.m: Use pm3d mode to handle new surface
+	properties.
+
+	* image/colormap.m: Also return current colormap if nargout and
+	nargin are both 0.
+
+2007-11-05  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* startup/inputrc: Delete key bindings starting with \340 code.
+
+2007-11-05  David Bateman  <dbateman at free.fr>
+
+	* linear-algebra/__norm__.m: Scale frobenius norm by infinity norm
+	to avoid issues of over- and underflow.  From Rolf Fabian
+	<Rolf.Fabian at gmx.de>.
+
+2007-11-02  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* time/asctime.m, general/structfun.m: Fix broken @examples in
+	help texts.
+
+2007-11-02  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/bar.m, plot/barh.m: Doc fix.
+
+2007-10-31  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Call undo_string_escapes on obj.keylabel.
+
+2007-10-31  Michael goffioul  <michael.goffioul at gmail.com>
+
+	* plot/subplot.m: Ignore legend objects when parsing existing axes
+	objects and legend objects are implemented with a separate axes
+	object.
+
+2007-10-30  David Bateman  <dbateman at free.fr>
+
+	* control/base/DEMOcontrol.m: Doc fixes for small book format.
+
+	* plot/__go_draw_axes__.m (do_linestyle_command):
+	Use point type 0 for ".".
+
+2007-10-26  John W. Eaton  <jwe at octave.org>
+
+	* image/imshow.m: Improve compatibility.
+	* image/image.m: Return handle if nargou > 0.
+
+	* pkg/pkg.m: Delete PKG_ADD directive for autoloading packes.
+
+2007-10-25  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/compare_versions.m: Style fixes.
+
+2007-10-24  John W. Eaton  <jwe at octave.org>
+
+	* image/saveimage.m: Use functional form of save instead of eval.
+	Use -text instead of -ascii.
+
+	* plot/__go_draw_axes__.m: Handle visible = "off" for axes objects.
+
+2007-10-23  Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/legend.m: Also extract location string from varargin (lost
+	when 2007-10-08 patch was applied).
+
+2007-10-23  David Bateman  <dbateman at free.fr>
+
+	* plot/xlim.m, plot/ylim.m, plot/zlim.m, plot/__axes_limits__.m,
+	miscellaneous/what.m: New functions
+	* plot/Makefile.in, miscellaneous/Makefile.in (SOURCES): Add new
+	functions.
+
+2007-10-22  David Bateman  <dbateman at free.fr>
+
+        * miscellaneous/cputime.m, time/tic.m, time/toc.m: Delete.
+	* miscellaneous/Makefile.in (SOURCES): remove cputim.m
+	* time/Makefile.in (SOURCES): Remov tic.m and toc.m
+
+2007-10-19  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/contourf.m: New function.
+	* plot/Makefile.in (SOURCES): Add it to the list.
+
+2007-10-19  John W. Eaton  <jwe at octave.org>
+
+	* plot/subplot.m: Doc fix.
+
+2007-10-19  David Bateman  <dbateman at free.fr>
+
+	* plot/__bar__.m, plot/fill.m: Call newplot as needed.
+
+2007-10-17  Carlo de Falco  <kingcrimson at tiscali.it>
+
+	* plot/print.m: Handle -textspecial and -textnormal flags for fig
+	output.
+
+2007-10-15  S�ren Hauberg  <hauberg at gmail.com>
+
+	* general/rat.m, sparse/pcg.m, sparse/pcr.m, optimization/sqp.m,
+	statistics/models/logistic_regression.m, polynomial/polygcd.m,
+	control/system/ss.m, signal/arch_rnd.m, control/system/ss2sys.m,
+	control/system/syssetsignals.m, control/base/lqg.m,
+	strings/str2double.m, control/system/sysscale.m,
+	control/hinf/hinfdemo.m, general/cplxpair.m:
+	Make help text fit on pages when using smallbook.
+
+2007-10-15  David Bateman  <dbateman at free.fr>
+
+	* plot/print.m: Call drawnow before printing to ensure the plot is
+	on the screen.
+
+	* testfun/test.m: In error/warning blocks test for an error before
+	a warning to avoid unexpected failures.
+
+2007-10-15  Kim Hansen  i<kimhanse at gmail.com>
+
+	* testfun/assert.m: Correct documentation of absolution versus 
+	relative error tolerance and add tests.
+
+2007-10-14  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (pkg:configure_make): Treat case of no files to install in
+	src directory.
+	* plot/Makefile.in (SOURCES): Add fill.m.
+
+2007-10-13  David Bateman  <dbateman at free.fr>
+
+	* plot/__patch__.m: Allow multiple patches to be defined and
+	return a single patch object. Allow Faces/Vertices form of
+	patch. Flag failure so the patch can call print_usage.
+	* plot/patch.m: Update help string for Faces/Vertices
+	call. Respect the fail flag returned by __patch__. Add demo code
+	that tests the functionality of patch.
+	* plot/__go_draw_axes__.m: Treat an array of patches in a single
+	patch object.
+	* plot/fill.m: New function.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+2007-10-11  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (get_axis_limits):
+	Return lim = [] if logscale and no positive values.
+	(__go_draw_axes__): Skip plotting if computed axis limits are empty.
+	Set initial min and min positive values to Inf, max values to -Inf.
+	(get_data_limits): Correctly handle xminp when no positive values
+	are found.
+
+2007-10-11  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/residue.m: New optional input for pole multiplicity.
+	Doc fix.  Fix tests.
+
+2007-10-11  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+         * toplev.cc (Foctave_config_info): Add field "mac".
+
+	* miscellaneous/ismac.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+	* miscellaneous/ispc.m, miscellaneous/isunix.m: Doc fix.
+
+2007-10-11  Arno Onken  <asnelt at asnelt.org>
+
+	* statistics/distributions/hygernd.m: Allow size to be specified
+	as a scalar.  Handle three argument case.  Allow T, M, and N to be
+	scalars or matrices of a common size.
+
+2007-10-11  Brian Gough  <bjg at network-theory.co.uk>
+
+	* control/csrefcard.lt, control/system/is_detectable.m,
+	control/system/sysgroup.m, geometry/voronoin.m,
+	miscellaneous/dir.m, sparse/pcg.m, sparse/treeplot.m,
+	statistics/base/mode.m, statistics/distributions/betarnd.m,
+	statistics/distributions/binornd.m,
+	statistics/distributions/cauchy_rnd.m,
+	statistics/distributions/chi2rnd.m,
+	statistics/distributions/discrete_rnd.m,
+	statistics/distributions/exprnd.m,
+	statistics/distributions/frnd.m,
+	statistics/distributions/gamrnd.m,
+	statistics/distributions/geornd.m,
+	statistics/distributions/laplace_rnd.m,
+	statistics/distributions/logistic_rnd.m,
+	statistics/distributions/lognrnd.m,
+	statistics/distributions/nbinrnd.m,
+	statistics/distributions/normrnd.m,
+	statistics/distributions/poissrnd.m,
+	statistics/distributions/stdnormal_rnd.m,
+	statistics/distributions/trnd.m,
+	statistics/distributions/unifrnd.m,
+	statistics/distributions/wblrnd.m: Spelling fixes.
+
+2007-10-10  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* time/tic.m: New optional output value.
+
+	* general/int2str.m: Doc fix.
+
+2007-10-10  Arno Onken  <asnelt at asnelt.org>
+
+	* statistics/distributions/hygecdf.m,
+	statistics/distributions/hygeinv.m,
+	statistics/distributions/hygepdf.m,
+	statistics/distributions/hygernd.m:
+	Swap order of T and M args for compatibility.
+
+2007-10-10  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* control/hinf/hinfsyn.m, control/hinf/wgt1o.m,
+	control/system/buildssic.m, control/system/c2d.m,
+	control/system/d2c.m, control/system/ord2.m, control/system/ss.m,
+	control/system/ss2sys.m, control/system/ss2tf.m,
+	control/system/syscont.m, control/system/sysdimensions.m,
+	control/system/sysdisc.m, control/system/sysmult.m,
+	control/system/sysrepdemo.m, control/system/tf2ss.m, elfun/lcm.m,
+	finance/fv.m, general/cumtrapz.m, general/gradient.m,
+	general/interp1.m, general/interp2.m, general/interp3.m,
+	general/interpft.m, general/interpn.m, general/polyarea.m,
+	general/rat.m, general/structfun.m, general/trapz.m,
+	geometry/tsearchn.m, image/rgb2hsv.m, linear-algebra/krylov.m,
+	miscellaneous/ans.m, miscellaneous/gzip.m, optimization/glpk.m,
+	optimization/sqp.m, plot/findobj.m, plot/legend.m, plot/peaks.m,
+	plot/plot3.m, plot/stem.m, polynomial/deconv.m,
+	polynomial/pchip.m, polynomial/spline.m, polynomial/unmkpp.m,
+	sparse/pcr.m, sparse/spalloc.m, sparse/spconvert.m,
+	specfun/factor.m, specfun/legendre.m, statistics/base/mean.m,
+	statistics/base/meansq.m, statistics/base/var.m,
+	statistics/tests/chisquare_test_independence.m,
+	statistics/tests/t_test.m, statistics/tests/u_test.m,
+	strings/dec2base.m, strings/mat2str.m, testfun/speed.m,
+	testfun/test.m: Spelling fixes.
+
+2007-10-10  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/mpoles.m: Return indx = ordr(indx), not indx(ordr).
+
+2007-10-10  John W. Eaton  <jwe at octave.org>
+
+	* general/num2str.m: Always allow for sign for automatically
+	computed format widths.
+
+2007-10-09  David Bateman  <dbateman at free.fr>
+
+	* plot/patch.m: Accept a handle as the first argument.
+
+2007-10-09:  Kim Hansen  <kimhanse at gmail.com>
+
+	* general/repmat.m: Handle sparse input.  Add tests.
+
+2007-10-09  John W. Eaton  <jwe at octave.org>
+
+	* audio/wavwrite.m: Accept arguments in compatible order.
+
+2007-10-08  David Bateman  <dbateman at free.fr>
+
+	* general/interp2.m: Relax test for values outside the grid to
+	allow monotonically decreasing abscissa as well.
+
+2007-10-08  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/residue.m: Doc fix.  Add tests.  Restore multiplicity
+	as output parameter.
+
+2007-10-08  Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m, plot/legend.m:
+	Handle compatible position specifiers as strings.
+
+2007-10-08  John Swensen  <jpswensen at comcast.net>
+
+	* general/num2str.m: Eliminate extra whitespace in output.
+	* strings/strtrim.m: New function.
+	* strings/Makefile.in (SOURCES): Add it to the list.
+
+2007-10-06  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/residue.m: New test from test/test_poly.m.
+
+2007-10-06  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/saveimage.m: Handle saving color images without a colormap.
+	* image/__img_via_file__.m: Add missing semicolon.
+
+2007-10-06  Bill Denney  <wsloand at gmail.com>
+
+	* general/__splinen__.m, general/isscalar.m, general/rat.m,
+	strings/dec2base.m: Use numel(x) instead of prod(size(x)).
+
+2007-10-06  Francesco Potorti`  <Potorti at isti.cnr.it>
+
+	* plot/print.m: Handle svg output type.  Accept new -S option to
+	specify size for PNG and SVG output types.
+
+2007-10-05  Ben Abbott  <bpabbott at mac.com>
+
+	* polynomial/mpoles.m: New function.
+	* polynomial/residue.m: Modified to behave in reciprocal
+	manner.  No longer compute 4th output, "e".  No longer accept
+	tolerance input.  Explicitly set tolerance parameter to 0.001.
+	Respect maximum relative difference in poles when determining
+	their multiplicity.  Use mpoles to determine the multiplicity of
+	poles.
+
+2007-10-05  Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m: Add cbrange to the plot stream 
+	for surface plots.
+
+2007-10-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/__next_line_color__.m: Get color_rotation from axes
+	colororder property.
+
+2007-10-03  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dir.m: Handle symbolic links in compatible way.
+	Use S_ISDIR (st.mode) instead of checking st.modestr(1) == "d".
+
+	* linear-algebra/Makefile.in (SOURCES): Rename norm.m to __norm__.m.
+	* linear-algebra/__norm__.m: Rename from norm.m.  Eliminate
+	special for __vnorm__.
+
+2007-10-03  Quentin Spencer  <qspencer at ieee.org>
+
+	* linear-algebra/norm.m: Special case vector 1-norm and 2-norm.
+
+2007-10-03  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (is_architecture_dependent): New function to identify
+	if a file is architecture dependent based on a list of file
+	extensions.
+	(configure_make): Simplify the search for architecture dependent
+	files based on this function.
+	(load_pakages_and_dependencies): Also look for bin directory in
+	the architecture dependent directory.
+
+2007-10-03  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dir.m: Create empty struct with field names.
+	Include datenum in struct.
+	
+2007-10-02  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/ls.m: If nargout return string array of files
+	returned by ls.
+
+2007-10-01  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Use %.15e instead of %.15g when setting
+	range values.
+
+2007-10-01  David Bateman  <dbateman at free.fr>
+
+	* linear-algebra/norm.m: Inline the isvector(x) calculation for
+	speed with small vectors.
+	* pkg/pkg.m (archprefix): Set using octave_config_info("libexecdir") 
+	rather than OCTAVE_HOME().
+
+2007-09-30  Ben Abbott  <bpabbott at mac.com>
+
+	* plot/findobj.m: New function.
+	* plot/Makefile.m (SOURCES): Add it to SOURCES.
+
+2007-09-26  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Add second argument to setting for prefix for
+	architecture dependent files. Use throughout.
+	(pkg:issuperuser): New function, use through to check for
+	root user.
+	(pkg:getarchprefix): function to give the archiecture dependent
+	prefix for a package.
+	(pkg:getarchdir): New function giving location of architetcure
+	dependent directory. Use through out.
+	(pkg:install): Treat architecture dependent directory separately
+	as in might not be a sub-directory of the package directory.
+	(pkg:uninstall): ditto.
+	(pkg:create_pkgadddel): Check for global or local install for
+	architecture dependent directory.
+	(pkg:finish_installation): ditto.
+	(pkg:write_INDEX): ditto.
+	(pkg:load_packages_and_dependencies): ditto.
+	(pkg:copy_files): ditto. Add step to copy architecture dependent
+	files to a new location if user is root.
+	(pkg:rm_rf): Check if file or directory exists before removing.
+	(pkg:dirempty): Check if directory exists before checking.
+	
+	* plot/___patch__.m: Allow face colors to be passed as strings
+
+	* plot/__plt_get_axis_arg__.m: Treat case of empty "varargin"
+	needed for calls to "hold" without an argument.
+
+2007-09-21  John W. Eaton  <jwe at octave.org>
+
+	* optimization/sqp.m: Fix typo.
+
+	* plot/__go_draw_axes__.m (do_tics_1): Use %g, not %.15g here.
+
+2007-09-21  Luther Tychonievich  <lty at cs.byu.edu>
+
+	* control/hinf/h2norm: Compute d*d', not d'*d.
+
+2007-09-21  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* statistics/distributions/Makefile.in (SOURCES): Add unidcdf.m,
+	unidpdf.m and unidinv.m
+
+2007-09-18  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Use %.15g throughout.
+	(do_tics_1): Set numeric axes formats to "%.15g".
+
+2007-09-18  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m (__gnuplot_write_data__): Use %e instead
+	of %g when writing data.
+
+2007-09-17  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Omit linestyle clause for errorbar plots.
+
+2007-09-14  Ulrich Tipp  <ulrich.tipp at hsnr.de>
+
+	* miscellaneous/bincoeff.m: Fix calculation of bincoeff (n, k) for
+	noninteger N with N-K < 1.
+
+2007-08-04  Jean-Francois Cardoso  <cardoso at tsi.enst.fr>
+
+	* strings/index.m: Correct for strings differing after the third
+	position (bug reported by Maude Martin).
+
+2007-09-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/__default_colormap__.m: Delete.
+	* plot/Makefile (SOURCES): Remove from the list.
+
+2007-09-13  Christof Zeile  <cz-oct07 at cvmx.com>
+
+	* pol2cart.m: Make it work with mixed scalar/nonscalar arguments.
+
+2007-09-10  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Allow gnuplot 4.0 with patches, but
+	limit the selection of colors in the same way as for lines.
+	* plot/__patch__.m: Allow matrix arguments with one patch per
+	column.
+	* plot/__bar__.m: Adapt to use "patch".
+
+2007-09-06  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m (drawnow): New arg, debug_file.
+	(init_plot_stream): Split from open_plot_stream.
+	* plot/print.m: Accept -debug=FILE argument.
+
+2007-09-06  David Bateman  <dbateman at free.fr>
+
+	* general/celldisp.m: New function.
+	* general/Makefile.in (SOURCES): Add celldisp.m.
+	* miscellaneous/swapbytes.m: New function.
+	* miscellaneous/gzip.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add swapbytes.m and gzip.m.
+
+2007-09-05  David Bateman  <dbateman at free.fr>
+
+	* general/structfun.m: New function.
+	* general/Makefile.in (SOURCES): Add it to sources.
+	* miscellaneous/run.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to sources.
+	* statistics/base/mode.m: New function.
+	* statistics/base//Makefile.in (SOURCES): Add it to sources.
+
+2007-09-05  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/orderfields.m: Use numel instead of length.
+
+2007-09-05  Michael goffioul  <michael.goffioul at gmail.com>
+
+	* miscellaneous/orderfields.m: Handle empty structs.
+
+2007-09-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Consistently index PARAMETRIC with
+	DATA_IDX.
+
+2007-09-04  David Bateman  <dbateman at free.fr>
+
+	* general/isdir.m: Return a logical value.
+
+2007-09-04  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions/chi2pdf.m,
+	statistics/distributions/chi2cdf.m,
+	statistics/distributions/chi2inv.m: Modifiy the call to the gamma
+	distribution functions to account for inverse of scale factor in
+	gamma functions.
+
+2007-09-01  John W. Eaton  <jwe at octave.org>
+
+	* plot/Makefile.in (SOURCES): Add ancestor.m to the list.
+
+2007-09-01  David Bateman  <dbateman at free.fr>
+
+	* polynomial/polyint.m: New function like polyinteg but with
+	explicit integration constant.
+	* polynomial/polyinteg.m: Remove.
+	* polynomial/Makefile.in (SOURCES): Add polyint.m and remove
+	polyinteg.m.
+	* deprecated/polyinteg.m: Move version here.
+	* deprecated/Makefile.in (SOURCES): Add polyinteg.m.
+	
+	* geometry/voronoi.m: Add large box around data to get a good
+	approximation of the rays to infinity.
+
+2007-08-31  Michael goffioul  <michael.goffioul at gmail.com>
+
+	* plot/axes.m: Allow parent to be specified when creating axes
+	objects.  Support non-figure parents.
+
+2007-08-31  John W. Eaton  <jwe at octave.org>
+
+	* plot/ancestor.m: New function, adapted from Octave Forge.
+
+2007-08-31  S�ren Hauberg  <hauberg at gmail.com>
+
+	* polynomial/polygcd.m: Better layout of example.
+	* polynomial/compan.m: Remove unnecessary check.
+	* polynomial/roots.m: Added example to help text.
+	* polynomial/polyderiv.m: Change 'polyder' to 'polyderiv' in help text.
+	* polynomial/poly.m: Added example to help text.
+
+2007-08-30  John W. Eaton  <jwe at octave.org>
+
+	* optimization/qp.m: Increase maxit to 200.
+
+2007-08-30  David Bateman  <dbateman at free.fr>
+
+	* geometry/inpolygon.m: New file.
+	* geometry/Makefile.in (SOURCES): Add inpolygon.m.
+	
+2007-08-29  Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m: Disable linetype in do_linestyle_command.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Treat text color property.
+
+2007-08-24  John W. Eaton  <jwe at octave.org>
+
+	* plot/subplot.m, plot/plot.m, plot/grid.m:
+	Use p = get (h, "prop") instead of obj = get (h); p = obj.prop.
+
+	* miscellaneous/movefile.m: Separate second and third args and
+	use p1 and p2, not f1 and f2 when constructing arguments for
+	calls to system.  From Michael Goffioul <michael.goffioul at gmail.com>.
+
+2007-08-24  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* set/intersect.m: Make it work with cell arrays of strings.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+	* geometry/convhull.m, geometry/delaunay.m, geometry/delaunay3.m, 
+        geometry/griddata.m, geometry/voronoi.m, geometry/voronoin.m: New 
+        functions ported from octave-forge.
+	* geometry/delaunayn.m, geometry/dsearch.m, geometry/dsearchn.m,
+        geometry/griddata3.m, geometry/griddatan.m, geometry/trimesh.m, 
+        geometry/triplot.m, geometry/tsearchn.m:
+        New functions.
+	* geometry/voronoi.m: Remove duplicate edges from Voronoi diagram.
+	* geometry/Makefile.in (SOURCES): Add functions above.
+	* configure.in (AC_CONFIG_FILES): Add new file geometry/Makefile.
+        
+2007-08-23  John W. Eaton  <jwe at octave.org>
+
+	* pkg/pkg.m: Avoid using installed_packages for both function and
+	variable name.
+
+2007-08-23  David Bateman  <dbateman at free.fr>
+
+	* plot/plot.m: Allow first arg to be axes handle.
+
+2007-08-22  David Bateman  <dbateman at free.fr>
+
+	* control/base/nichols.m: Correct for misnamed variable, and ensure
+	outputs are returned only if requested.
+
+2007-08-22  Donald Parsons  <dparsons at brightdsl.net>
+
+	* control/base/nichols.m: Fix typo.
+
+2007-08-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/meshgrid.m: Use repmat instead of multiplication.
+
+2007-08-10  Peter A. Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m: Add axes position to the usingclause,
+	use axes position in each appropriate gnuplot set statement.
+
+2007-08-10  John W. Eaton  <jwe at octave.org>
+
+	* image/Makefile.in (DISTFILES): Also include $(IMAGES) in the list.
+	(install install-strip): Use $(IMAGES), not $(IMAGE_FILES_NO_DIR).
+	(uninstall): Use $(IMAGES), not $(IMAGE_FILES_NO_DIR).
+	(IMAGE_FILES, IMAGE_FILES_NO_DIR): Delete obsolete variables.
+
+2007-08-10  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/patch.m, plot/__patch__.m: New files.
+	* plot/Makefile.in (SOURCES): Add them to the list.
+
+2007-08-07  John W. Eaton  <jwe at octave.org>
+
+	* path/savepath.m: Use single quotes for argument to PATH command
+	that is inserted in file.
+
+2007-07-27  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: Only set default value for term if GNUTERM is
+	not set in the environment.
+
+2007-07-25  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in, audio/Makefile.in, control/Makefile.in,
+	control/base/Makefile.in, control/hinf/Makefile.in,
+	control/obsolete/Makefile.in, control/system/Makefile.in, 
+	control/util/Makefile.in, deprecated/Makefile.in,
+	elfun/Makefile.in, finance/Makefile.in, general/Makefile.in,
+	image/Makefile.in, io/Makefile.in, linear-algebra/Makefile.in,
+	miscellaneous/Makefile.in, optimizaton/Makefile.in,
+	path/Makefile.in, pkg/Makefile.in, plot/Makefile.in,
+	polynomial/Makefile.in, quaternion/Makefile.in,
+	set/Makefile.in, signal/Makefile.in, sparse/Makefile.in,
+	specfun/Makefile.in, special-matrix/Makefile.in,
+	startup/Makefile.in, statistics/Makefile.in,
+	statistics/base/Makefile.in, statistics/distributions/Makefile.in,
+	statistics/models/Makefile.in, statistics/tests/Makefile.in,
+	strings/Makefile.in, testfun/Makefile.in, time/Makefile.in:
+	Adjust DISTFILES to allow out of tree "make dist" to work.
+
+2007-07-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt2__.m: Return [](0x1) if both X and Y are empty.
+
+2007-07-24  David Bateman  <dbateman at free.fr>
+
+	* image/flag.m: New colormap function.
+	* images/Makefile.in: Include it in SOURCES.
+
+	* image/autumn.m image/bone.m image/cool.m image/copper.m 
+	image/hot.m image/hsv.m image/jet.m image/pink.m image/prism.m 
+	image/rainbow.m image/spring.m image/summer.m image/white.m 
+	image/winter.m, image/brighten.m: Use isscalar and not is_scalar.
+	* image/gray.m, image/ocean.m: Use the same means of finding the
+	number of colormap elements as the other colormap functions.
+
+2007-07-24  Kai Habel  <kai.habel at gmx.de>
+
+	* plot/__go_draw_axes__.m: Handle patch.
+
+2007-07-23  David Bateman  <dbateman at free.fr>
+
+	* general/rat.m: New function for ration approximation imported
+	from octave-forge.
+	* general/del2.m: New function for discrete laplacian operator.
+	* general/Makefile.in: Include rat.m and del2.m  in SOURCES.
+
+	 * image/autumn.m image/bone.m image/cool.m image/copper.m 
+	image/hot.m image/hsv.m image/jet.m image/pink.m image/prism.m 
+	image/rainbow.m image/spring.m image/summer.m image/white.m 
+	image/winter.m, image/brighten.m: Port image functions from
+	octave-forge.
+	* image/Makefile.in: Add ported functions to SOURCES.
+	* image/gray.m, image/ocean.m: Don't set the colormap for
+	compatibility with matlab.
+	
+	* plot/meshc.m, plot/peaks.m: Port plotting function from
+	octave-forge
+	* plot/Makefile.in: Add ported functions to SOURCES.
+	* plot/__go_draw_axes__.m: Set the palette for the surfaces if
+	using gnuplot 4.2 or greater.
+	
+2007-07-23  Claudio Belotti  <c.belotti at imperial.ac.uk>
+
+	* general/cart2sph.m: Fix unbalanced paranthesis.
+
+2007-07-19  David Bateman  <dbateman at free.fr>
+
+	* plot/fplot.m: More compatible version.
+
+2007-07-18  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/clf.m: Check for valid handle before deleting.
+
+	* plot/figure.m: Pass "figure" property/value pairs directly to
+	__go_figure__ instead of using regular "set" call.
+
+2007-07-18  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* plot/drawnow.m: Prefer GNUTERM to DISPLAY when choosing terminal
+	type for gnuplot.
+
+2007-07-18  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Unconditionally send "unset label" to
+	gnuplot for each set of axes.
+
+2007-07-18  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions/gamcdf.m, statistics/distributions/gaminv.m,
+	statistics/distributions/gampdf.m, statistics/distributions/gamrnd.m,
+	statistics/distributions/expcdf.m, statistics/distributions/expinv.m,
+	statistics/distributions/exppdf.m, statistics/distributions/exprnd.m:
+	Use standard scale factor rather than one on the scale factor for
+	compatibility.
+
+	* deprecated/gamma_cdf.m, deprecated/gamma_inv.m,
+	deprecated/gamma_pdf.m, deprecated/gamma_rnd.m,  
+	deprecated/exponential_cdf.m, deprecated/exponential_inv.m,
+	deprecated/exponential_pdf.m, deprecated/exponential_rnd.m:
+	Preserve backward compatibility.
+
+2007-07-17  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* pkg/pkg.m (pkg:installed_packages): Use findstr rather than regexp
+	to avoid issues with regexp special characters in the path strings.
+
+2007-07-06  David Bateman  <dbateman at free.fr>
+
+	* general/accumarray.m: New function to create an array by 
+	accumulating the elements.
+
+2007-06-29  Marcus W. Reble  <reble at wisc.edu>
+
+	* optimization/sqp.m (sqp): New args, lb, ub, maxiter, and tolerance.
+	(fdjac): Set nx outside of if block.
+	(cf_ub_lb, cigrad_ub_lb): New subfunctons.
+
+2007-06-28  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* plot/subplot.m: Add 'ishandle' check when parsing the existing axes.
+
+	* plot/axis.m: Also set "visible" property when setting axes to
+	on/off.
+
+2007-06-27  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* image/colormap.m: Only return colormap if nargout > 0.
+	Mark as command.
+
+2007-06-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m, plot/__go_draw_axes__.m: Use strcmpi instead of
+	strcmp for selected property comparisons.
+
+2007-06-25  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/imshow.m: Fix check for colormap arguments.
+
+2007-06-25  Joel Keay  <keay at nhn.ou.edu>
+
+	* plot/drawnow.m: Handle GNUTERM=aqua if DISPLAY is not set.
+
+2007-06-25  S�ren Hauberg  <hauberg at gmail.com>
+
+	* statistics/base/median.m: Update help text to mention 'dim'
+	argument, and note that the data should be sorted for the
+	definition of the median to be correct.
+
+	* statistics/base/std.m: Add missing square to definition of
+	standard deviation.
+
+	* statistics/base/cov.m: Add definition of covariance to the help text.
+
+	* statistics/base/kurtosis.m, statistics/base/skewness.m,
+	statistics/base/std.m:
+	Note that \bar{x} is the mean value of x in the help text.
+
+	* specfun/nchoosek.m: Add alternative definition of the binomial
+	coefficient to the help text.
+
+	* specfun/perms.m, statistics/base/values.m: Add example in help text.
+
+	* statistics/base/var.m: Put N in @math in help text.
+
+	* statistics/base/qqplot.m, statistics/base/ppplot.m, 
+	statistics/tests/kolmogorov_smirnov_test.m:
+	Write about possible values of 'dist' in help text.
+
+	* statistics/base/corrcoef.m, statistics/base/cor.m:
+	Add definition of correlation to the help text.
+
+	* statistics/base/logit.m, statistics/base/kendall.m,
+	statistics/base/cloglog.m, statistics/tests/hotelling_test_2.m,
+	statistics/distributions/wblcdf.m, statistics/distributions/wblpdf.m:
+	TeXification of help text.
+
+	* statistics/tests/hotelling_test.m: Write T^2 in @math in help text.
+
+	* statistics/tests/var_test.m, statistics/tests/welch_test.m:
+	Add missing @var's to help text.
+
+	* statistics/models/logistic_regression.m: Fix typos in help text.
+
+	* statistics/distributions/kolmogorov_smirnov_cdf.m: Fix TeX part
+	of help text.
+
+	* statistics/distributions/unidinv.m: Add a missing 'discrete' to
+	help text.
+
+	* statistics/distributions/unidpdf.m,
+	statistics/distributions/discrete_pdf.m:
+	Replace 'pDF' with 'PDF' in help text.
+
+2007-06-25  John W. Eaton  <jwe at octave.org>
+
+	* strings/substr.m: Use offset consistently in code and doc string.
+	From Rafael Laboissiere <rafael at debian.org>.
+
+2007-06-25  Pete Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m: Handle units for text objects.
+
+2007-06-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Handle char arrays for tic labels.
+	Recycle tic labels if necessary.  From Juhani Saastamoinen
+	<juhani at cs.joensuu.fi>.
+
+2007-06-20  John W. Eaton  <jwe at octave.org>
+
+	* strings/index.m: Allow strings to be empty.
+	From Hartmut Wziontek <hwz at hwz.bv.TU-Berlin.DE>
+
+	* plot/__go_draw_axes__.m (do_tics_1): Fix typo (xtic -> tics).
+
+2007-06-19  Vittoria Rezzonico  <vittoria.rezzonico at epfl.ch>
+
+	* sparse/pcg.m: Allow the preconditioner to be passed as two
+	separate matrices.
+
+2007-06-19  David Bateman  <dbateman at free.fr>
+
+	* plot/axis.m: Prefer to use legend rather than the older Octave
+	only ";;" legend syntax.
+	* polynomial/mkpp.m: ditto.
+	* polynomial/pchip.m: ditto.
+	* signal/freqz_plot.m: ditto.
+	* sparse/gplot.m: ditto.
+	* sparse/treeplot.m: ditto.
+
+2007-06-19  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (do_tics, do_tics_1): New functions.
+	(__go_draw_axes__): Call do_tics to handle tic marks.
+
+2007-06-18  S�ren Hauberg  <hauberg at gmail.com>
+
+	* general/interp1.m, general/interp2.m, general/interp3.m,
+	general/interpn.m: Replace, NaN with NA.  Use isna instead of ==
+	to check for NA.
+
+2007-06-18  S�ren Hauberg  <hauberg at gmail.com>
+
+	* optimization/glpk.m: TeXified the help text.
+	* optimization/qp.m: TeXified the help text.
+	* optimization/sqp.m: TeXified the help text.
+
+2007-06-16  S�ren Hauberg  <hauberg at gmail.com>
+
+	* plot/legend.m: Replace 'vargin' with 'varargin'.
+
+2007-06-15  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Only attempt label rotation if
+	have_newer_gnuplot is true.
+
+2007-06-15  Pete Gustafson  <petegus at umich.edu>
+
+	* plot/__go_draw_axes__.m  Handle rotation arg for axis labels.
+	* plot/__axis_label__.m  Assign ylabel default rotation property
+	to 90, all others 0.
+
+	* plot/__errplot__.m: Set ifmt from fmt.linestyle.
+	* plot/__go_draw_axes__.m: Removed undefined tx from call to
+	get_data_limits.
+	* plot/__plotopt1__.m: Intercept and strip format string when
+	called by __errplot__.
+
+2007-06-15  John W. Eaton  <jwe at octave.org>
+
+	* testfun/test.m: Also return number of expected failures.
+
+2007-06-14  John W. Eaton  <jwe at octave.org>
+
+	* set/ismember.m: Mark two tests known to fail with xtest.
+
+	* plot/__go_draw_axes__.m: Handle text rotation property.
+
+2007-06-14  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* testfun/test.m: Add xtest support for tests known to fail.
+
+2007-06-14  Sebastian Schubert  <sebastian-schubert at gmx.de>
+
+	* plot/print.m: Handle pstex, pslatex, epslatex, and
+	epslatexstandalone terminals.
+
+2007-06-14  David Bateman  <dbateman at free.fr>
+
+	* general/__splinen__.m: Check also for ND vectors. Fix for N > 2,
+	as permutation of results was incorrect.
+	* general/interp1.m: Add demo on second derivative
+	* general/interpn.m: Convert "y" to vectors for __splinen__
+	call. Add 3D demo. Fix typos
+	* general/interp3.m: Fix typos. Correct permutation for use of
+	interpn.
+	* polynomial/mkpp.m: Correction for matrices of 3 or more dimensions.
+
+2007-06-13  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/mkoctfile.m: Quote args too.
+
+2007-06-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* miscellaneous/mkoctfile.m: Quote script name for call to system.
+
+2007-06-12  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* plot/__pltopt1__.m: Set linestyle to "none" instead of "".
+	Set have_linestyle to true if two character linestyle is found.
+
+2007-06-12  David Bateman  <dbateman at free.fr>
+
+	* general/Makefile.in (SOURCES): Include __spline__.m, interp3.m
+	and interpn.m.
+
+	* pkg/pkg.m (pkg:load_package_dirs): Check for field "loaded" in
+	structure before using it.
+
+2007-06-12  David Bateman  <dbateman at free.fr>
+
+	* general/interp1.m: Change examples to use new graphics interface.
+	* general/__splinen__.m: New support function for N-dimensional
+	spline interpolation.
+	* general/bicubic.m: Allow definition of extrapolation
+	value. Adapt tests to use new graphics interface
+	* general/interp2.m: Call __splinen__ for 2-D spline
+	interpolation. Make the lookup table code only be called for
+	linear and nearest methods.
+	* general/interpn.m: New function for N-dimensional, linear, nearest
+	and spline interpolation.
+	* general/interp3.m: New function for 3-dimensional, linear, nearest
+	and spline interpolation.
+	* polynomial/spline.m: Change examples to use new graphics interface.
+	
+2007-06-12  Steve M. Robbins  <steve at sumost.ca>
+
+	* statistics/tests/wilcoxon_test.m: Error if N <= 25.
+
+2007-06-12  S�ren Hauberg  <soren at hauberg.org>
+
+	* plot/fplot.m: If function is inline, vectorize it.
+
+2007-06-10  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (pkg:installed_packages): truncate start of package
+	directory if need to, so that it fits on a line.
+	
+2007-06-07  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (pkg): For rebuild target, force package order in
+	saved file so that dependent packages are loaded first, and if
+	nargout==0 don't return any arguments.
+	(pkg:install): Only load packages that are marked autoload after
+	install. Various fixes. Save in order.
+	(pkg:uninstall): Save in order
+	(pkg:load_packages): Use load_package_and_dependencies to load
+	packages.
+	(pkg:save_order): New function to sort package list with dependent
+	packages first.
+	(pkg:load_packages_and_dependencies): New function to load both a
+	list of packages and their dependencies.
+	(pkg:load_package_dirs): New function that returns a vector of the
+	indexes into the installed package list indicating the packages to
+	load and the order to load them in to respect the dependencies.
+
+2007-06-03  S�ren Hauberg  <soren at hauberg.org>
+
+	* plot/axes.m: Eliminate redundant else clause.
+
+2007-06-03  David Bateman  <dbateman at free.fr>
+
+	* polynomial/spline.m: Add a small tolerance to spline tests.
+	* pkg/pkg.m: Protect against multiple actions being define.
+	
+2007-06-01  David Bateman  <dbateman at free.fr>
+
+	* pkg.m (pkg:is_superuser): Remove function used in one place and
+	incorporate into main pkg function.
+	(pkg:install): Check for existence of files to install before
+	globbing and warn the user if they don't exist.
+
+2007-05-31  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/copyfile.m: Split copying of multiple files to a 
+	directory over several copy command to limit the line length.
+	* miscellaneous/movefile.m: Ditto.
+	
+	* pkg.m: Add build option to allow binary Octave packages to be
+	built from source packages. Probe absolute path of prefix, global
+	and local lists. Use strcat, rather that [] for strings.
+	(pkg:build): New function to binary binary package.
+	(pkg:absolute_pathname): Use fileattrib to probe absolute path.
+	(pkg:repackage): Package binary Octave package from installation.
+	(pkg:create_pkgadddel): Extract PKG_ADD and PKG_DEL directives
+	from m-files into main installation directory.
+	(pkg:shell): Suppress verbose messages from shell and only display
+	them with the verbose flag.
+	(pkg:installed_packages): Also include the loaded flag in the
+	local and global packages.
+	(pkg:uninstall): On uninstall, only rmpath the package if it is
+	flagged as loaded.
+
+2007-05-31  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* pkg.m (pkg:load_packages): Correctly load a mix of packages
+	with and without architecture dependent directories.
+	(pkg:installed_packages): Probe the global_list file even if it is
+	the same as the local_list. 
+
+2007-05-29  John W. Eaton  <jwe at octave.org>
+
+	* sparse/spy.m: Set axis to "ij" mode.
+
+2007-05-24  John W. Eaton  <jwe at octave.org>
+
+	* set/ismember.m: Quote first arg of "fail" tests.
+
+2007-05-24  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (pkg:rebuild): Thinko in rebuild logic.
+
+2007-05-22  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Use rethrow(lasterror()) throughout rather than
+	error(lasterr()(8:end)).
+	(pkg:install): Warning for empty packages being removed. Suppress
+	spurious output. Warning rather than error for uninstalling a
+	package that is not installed to avoid RPM issue.
+	(pkg:configure_make): Fix for parsing of src/FILES. Don't create
+	inst or architecture dependent directory if it exists.
+
+2007-05-22  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* ChangeLog, control/system/is_stabilizable.m, general/bicubic.m,
+	image/ind2gray.m, image/saveimage.m, plot/box.m, plot/grid.m,
+	signal/freqz.m: Fix typos.
+
+2007-05-21  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Add rebuild target, and -local, -global option to
+	force installation location.
+	(rebuild): New subfunction to rebuild package database from
+	installed packages. Also allows changing of autoload status
+	(install): Warn use if attempting to install from non existent
+	file. 
+	(issuperuser): Use 'geteuid() == 0' instead of 'strcmp (getenv(
+	"USER", "root"))' for root test.
+
+2007-05-21  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* miscellaneous/copyfile.m: check for cp.exe on Windows platforms
+	and replace "\" characters with "/".
+	* pkg/pkg.m: Use shell rather than system throughout. Replace "\" 
+	characters with "/" throughout.
+	(shell): New subfunction that wraps system and is careful with the
+	shell on windows platforms.
+	(configure_make): Explictly pass complier etc to configure
+	process.
+	(issuperuser): Force default to global install for Windows machines.
+	
+2007-05-19  Kristan Onu
+
+	* plot/Makefile.in (SOURCES): Remove hbar.m and add barh.m.
+
+2007-05-18  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (install): More verbosity. 
+	(configure_make): Ditto.
+	(create_pkgadddel): Install in architecture dependent directory if
+	it exists to address issues with autoload/mfilename.
+	(write_INDEX): Check in archiecture dependent directories as well.
+
+2007-05-17  David Bateman  <dbateman at free.fr>
+
+	* plot/hbar.m: Remove.
+	* plot/barh.m: and move it here.
+
+2007-05-16  S�ren Hauberg  <soren at hauberg.org>
+
+	* general/sub2ind.m, general/ind2sub.m: Doc fix.
+
+2007-05-16  John W. Eaton  <jwe at octave.org>
+
+	* general/logspace.m: Return second arg if fewer than two values
+	are requested.
+
+2007-05-14  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_figure__.m: Ensure that a reset commands starts
+	on a new line.
+
+2007-05-14  Tarmigan Casebolt  <tarmigan+list at gmail.com>
+
+	* statistics/distributions/norminv.m,
+	statistics/distributions/norminv.m,
+	statistics/distributions/normpdf.m,
+	statistics/distributions/normrnd.m:
+	Use standard deviation, not variance.
+	* statistics/distributions/lognpdf.m: Adapt to change in norminv.
+	* statistics/distributions/logninv.m: Refer to norminv, not normal_inv.
+	* deprecated/normal_cdf.m, deprecated/normal_inv.m,
+	deprecated/normal_pdf.m, deprecated/normal_rnd.m: Preserve
+	backward compatibility.
+
+2007-05-14  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Mark loaded packages with "*".
+
+2007-05-13  S�ren Hauberg  <soren at hauberg.org>
+
+	* miscellaneous/single.m: Doc fix.
+	Convert to double instead of returning argument unchanged.
+
+	* miscellaneous/doc.m: Doc fix.
+
+	* miscellaneous/ver.m: Doc fix.
+	Don't display information about Octave Forge.
+
+2007-05-12  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Add a "-verbose" option that allows all output of an
+	install to be printed. An error in the on_uninstall script causes
+	a failure to uninstall. Place oct- and mex-files in an
+	architecture dependent directory.
+
+2007-05-09  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Break plot command over multiple lines.
+
+2007-05-09  G. D. McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* statistics/distributions/normcdf.m: Use standard deviation
+	instead of variance for compatibility.
+
+2007-05-08  John W. Eaton  <jwe at octave.org>
+
+
+	* set/unique.m, set/ismember.m: Use numel(x) instead of prod(size(x)).
+
+	* set/ismember.m: Always return logical values.
+
+	* set/ismember.m: Return early if no matches are found.  New tests.
+	From David Grohmann <grohmann at arlut.utexas.edu>.
+
+	* general/__isequal__.m: Allow numeric values of different classes
+	to compare equal.
+
+2007-05-07  David Bateman  <dbateman at free.fr>
+
+	* sparse/spy.m: Reverse Y axis for new graphics code. Make more
+	compatiable, accepting LineSpec and markersize arguments.
+
+2007-05-02  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Convert NA to NaN before writing.
+
+2007-05-02  G. D. McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* contour.m: Rewrite help string.
+
+2007-04-28  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/unzip.m, miscellaneous/untar.m,
+	miscellaneous/bunzip2.m, miscellaneous/gunzip.m:
+	Special case nargout == 0.
+
+2007-04-27  Kim Hansen  <kimhanse at gmail.com>
+
+	* general/sub2ind.m: Handle empty input, add tests.
+
+2007-04-27  G. D. McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* plot/contourc.m: Doc fix.
+
+2007-04-26  David Bateman  <dbateman at free.fr>
+
+	* plot/hist.m: Partially remove previous patch.
+
+2007-04-26  David Bateman  <dbateman at free.fr>
+
+	* plot/hist.m: Support returning of handle
+	* plot/__bar__.m: __pltopt__ should only be called on strings or
+	cells.
+
+2007-04-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: For images, set titlespec{data_idx} to
+	"title \"\"", not "".
+
+	* plot/legend.m: Initialize WARNED to false.
+
+2007-04-24  John W. Eaton  <jwe at octave.org>
+
+	* io/beep.m: Fix cut and paste error.
+	From S�ren Hauberg  <soren at hauberg.org>.
+
+2007-04-23  John W. Eaton  <jwe at octave.org>
+
+	* plot/box.m: Delete extra endfunction keyword.
+
+2007-04-23  David Bateman  <dbateman at free.fr>
+
+	* plot/plot3.m: Call newplot.
+
+2007-04-20  John W. Eaton  <jwe at octave.org>
+
+	* plot/Makefile.in (SOURCES): Fix typo in adding __bar__.m to the list.
+
+2007-04-19  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/unpack.m: Use gzip -d and bzip2 -d instead of
+	gunzip and bunzip.  From Michael Goffioul <michael.goffioul at swing.be>.
+
+2007-04-19  A. S. Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* control/util/axis2dlim.m: Delete extraneous line.
+
+2007-04-18  John W. Eaton  <jwe at octave.org>
+
+	* specfun/factorial.m: Increase tolerance in large value test.
+
+2007-04-18  David Bateman  <dbateman at free.fr>
+
+	* __bar__.m: New support function for bar/hbar to support graphic
+	handles, and additional arguments.
+	* bar.m: Convert to use __bar__.
+	* hbar.m: New function
+	* hist.m: Explicitly set the width of the bar plot.
+	
+2007-04-17  John W. Eaton  <jwe at octave.org>
+
+	* plot/stem.m (stem_line_spec): Pass false as third arg to __pltopt__.
+
+	* set/ismember.m: New tests.
+	From David Grohmann <grohmann at arlut.utexas.edu>
+
+2007-04-17  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* specfun/factorial.m: Use gamma function instead of cumprod.
+	Add tests.
+
+2007-04-16  John W. Eaton  <jwe at octave.org>
+
+	* gethelp.cc (looks_like_octave_copyright): Use same logic as in
+	looks_like_copyright in src/help.cc.
+	From S�ren Hauberg <soren at hauberg.org>.
+
+	* plot/__go_draw_axes__.m: For log plots, omit zero values too.
+
+2007-04-13  John W. Eaton  <jwe at octave.org>
+
+	* optimization/sqp.m: Initialize info to 0.
+
+	* optimization/qp.m: Undo previous change.
+
+2007-04-13  Geordie McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* spdiags.m: Fixed the four-argument case to work for columns of
+	length one.
+
+2007-04-12  John W. Eaton  <jwe at octave.org>
+
+	* optimization/qp.m: Avoid Octave indexing bug.
+
+2007-04-12  Carlo de Falco  <kingcrimson at tiscali.it>
+
+	* miscellaneous/menu.m, control/base/bddemo.m,
+	control/hinf/dgkfdemo.m, control/system/packedform.m,
+	control/system/sysrepdemo.m:
+	Adapt to page_screen_output as a function.
+
+2007-04-11  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/not.m: Delete.
+	* miscellaneous/Makefile.in (SOURCES): Delete it from the list.
+
+2007-04-11  A. S. Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* control/util/axis2dlim.m: Try harder to handle min and max vals
+	that are close but not exactly equal.
+
+2007-04-11  David Bateman  <dbateman at free.fr>
+
+	* general/bitcmp.m: Make it work again.
+
+2007-04-10  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Try harder to handle min and max vals
+	that are close but not exactly equal.
+
+2007-04-09  Daniel J. Sebald  <daniel.sebald at ieee.org>
+
+	* plot/stem.m: Add back the baseline line and let it be not adjustable
+	in response to a change in x limits for now.
+
+2007-04-09  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m (__gnuplot_write_data__): New function.
+	(__go_draw_axes__): Use it to write data to plot stream.
+
+2007-04-09  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/stem.m: Fix typos in doc string.  Fix typo in call to
+	zeros.  Set markerfacecolor property in call to plot.
+
+2007-04-06  John W. Eaton  <jwe at octave.org>
+
+	* linear-algebra/norm.m: Use new __vnorm__ function for vector args.
+
+2007-04-06  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/stem.m: Use plot instead of a series of calls to line.
+
+2007-04-05  John W. Eaton  <jwe at octave.org>
+
+	* sparse/nonzeros.m, sparse/normest.m, sparse/spconvert.m,
+	sparse/spdiags.m, sparse/speye.m, sparse/spfun.m, sparse/spones.m,
+	sparse/sprand.m, sparse/sprandn.m, sparse/sprandsym.m,
+	sparse/spstats.m, sparse/treeplot.m: Style fixes.
+
+	* pkg/pkg.m: Use "strcat (...)" instead of "[...]".
+	Use strcmpi instead of strcmp+tolower.
+	Style fixes.
+
+	* testfun/speed.m: Use "strcat (...)" instead of "[...]".
+	Plotting fixes.  Style fixes.
+
+	* testfun/test.m: Use "strcat (...)" instead of "[...]".
+	Style fixes.
+
+	* testfun/fail.m: No need to check for evalin and lastwarn.
+	Style fixes.
+
+	* testfun/demo.m, testfun/example.m: Style fixes.
+	Use "strcat (...)" instead of "[...]".
+	Use format specifiers in calls to warning.
+
+	* testfun/assert.m: Use "numel (x)" instead of "prod (size (x))".
+	Use "strcat (...)" instead of "[...]".
+	Use "x(end)" instead of "x(length (x))".
+	Check NA before NaN.
+	Style fixes.
+
+2007-03-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/stem.m (stem, set_default_values): Use RGB triple for color.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in, audio/Makefile.in, control/Makefile.in,
+	control/base/Makefile.in, control/hinf/Makefile.in,
+	control/obsolete/Makefile.in, control/system/Makefile.in,
+	control/util/Makefile.in, deprecated/Makefile.in,
+	elfun/Makefile.in, finance/Makefile.in, general/Makefile.in,
+	image/Makefile.in, io/Makefile.in, linear-algebra/Makefile.in,
+	miscellaneous/Makefile.in, optimization/Makefile.in,
+	path/Makefile.in, pkg/Makefile.in, plot/Makefile.in,
+	polynomial/Makefile.in, quaternion/Makefile.in, set/Makefile.in,
+	signal/Makefile.in, sparse/Makefile.in, specfun/Makefile.in,
+	special-matrix/Makefile.in, startup/Makefile.in,
+	statistics/Makefile.in, statistics/base/Makefile.in,
+	statistics/distributions/Makefile.in,
+	statistics/models/Makefile.in, statistics/tests/Makefile.in,
+	strings/Makefile.in, testfun/Makefile.in, time/Makefile.in:
+	Use ln instead of $(LN_S) in dist target.
+
+2007-03-27  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Allow linewidth settings to work with
+	gnuplot 4.0.
+
+2007-03-26  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Send image data to gnuplot via plot stream.
+
+2007-03-26  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__go_draw_axes__.m: Always end palette data to gnuplot via
+	plot stream and using binary data.
+
+2007-03-26  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt1__.m, plot/__plt2__.m, plot/__plt2mm__.m,
+	lot/__plt2mv__.m, plot/__plt2ss__.m, plot/__plt2vm__.m,
+	plot/__plt2vv__.m: Accept properties in addtition to options struct.
+
+2007-03-26  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Send "set ticslevel 0" to plot stream.
+
+	* plot/plot3.m: Handle line properties.
+	* plot/plot.m: Update docstring.
+	* plot/__plotopt__.m, plot/__pltopt1__.m: New arg, err_on_invalid.
+	* plot/__plt__.m: Also gather properties.
+
+2007-03-26  Kim Hansen  <kimhanse at gmail.com>
+
+	* testfun/assert.m: Delete special check for empty objects.
+	Add test.
+
+2007-03-26  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: Exit early if call is recursive.
+
+	* plot/__go_draw_axes__.m (get_data_limits): New function.
+	Check for Inf too.
+	(__go_draw_axes__): Use get_data_limits.
+
+2007-03-24  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: If GNUTERM is set to wxt in the environment,
+	send terminal setting command with title option to plot stream.
+
+	* plot/legend.m: Correctly increment index into list of children..
+
+2007-03-23  John W. Eaton  <jwe at octave.org>
+
+	* general/interp2.m, general/bicubic.m, control/base/rldemo.m,
+	control/hinf/hinfdemo.m, control/hinf/dhinfdemo.m,
+	control/base/nyquist.m, control/base/nichols.m,
+	control/base/frdemo.m, signal/freqz_plot.m,
+	control/base/__stepimp__.m, control/base/bode.m,
+	quaternion/demoquat.m, quaternion/qcoordinate_plot.m,
+	statistics/base/qqplot.m, statistics/base/ppplot.m, sparse/spy.m:
+	Update plotting code.
+
+	* control/base/bode.m: Unwrap phase angle.
+
+	* miscellaneous/dump_prefs.m: Remove automatic_replot from the list.
+
+	* plot/axis.m: Don't check automatic_replot, or call replot.
+
+	* quaternion/demoquat.m: Delete comments with obsolete plotting
+	commands.
+
+	* plot/__pltopt1__.m: Handle "@" marker same as "+".
+	Handle numeric color specs.
+	* plot/plot.m: Remove "-@" and "@" from docstring.
+
+	* plot/orient.m: Fix tests to avoid creating a plot window.
+
+	* elfun/acosd.m, elfun/acotd.m, elfun/acscd.m, elfun/asecd.m,
+	elfun/asind.m, elfun/atand.m, elfun/cosd.m, elfun/cotd.m,
+	elfun/cscd.m, elfun/secd.m, elfun/sind.m, elfun/tand.m,
+	general/arrayfun.m, miscellaneous/compare_versions.m,
+	path/savepath.m, pkg/pkg.m, plot/__gnuplot_version__.m,
+	plot/contour.m, plot/contourc.m, plot/legend.m, plot/stem.m,
+	polynomial/pchip.m: Fix copyright notice, correct FSF address.
+
+	* plot/__go_draw_figure__.m: Send reset to gnuplot before every
+	plot, not just multiplots.
+
+	* plot/__go_draw_axes__.m: Use %g for label coordinates, not %d.
+
+	* plot/contour.m: Don't call drawnow.
+
+2007-03-22  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: Check and optionally, set, the __modified__
+	property of each figure.
+
+	* plot/__go_draw_axes__.m: If no real data, plot a point at Inf,
+	Inf to show axes.  From Daniel J Sebald <daniel.sebald at ieee.org>.
+
+2007-03-21  John W. Eaton  <jwe at octave.org>
+
+	* linear-algebra/null.m: Set elements of retval with magnitudes
+	less than eps to 0.
+
+2007-03-21  David Bateman  <dbateman at free.fr>
+
+	* plot/__go_draw_axes__.m: Handle some colors with older gnuplot.
+	* testfun/speed.m: Documentation and example fix.
+	
+2007-03-21  John W. Eaton  <jwe at octave.org>
+
+	* plot/subplot.m: If we find an existing subplot region, set
+	it to be the "currentaxes" property for the current figure.
+	Delete old axes objects if the new axes object overlaps the old.
+
+2007-03-20  David Bateman  <dbateman at free.fr>
+
+	* general/Makefile.in: Include arrayfun.m in SOURCES.
+
+2007-03-20  Bill Denney  <denney at seas.upenn.edu>
+
+	* general/arrayfun.m: New function.
+
+2007-03-20  John W. Eaton  <jwe at octave.org>
+
+	* plot/newplot.m: Call __request_drawnow__ after initializing axes.
+	* plot/text.m: Call __request_drawnow__ after creating text objects.
+
+	* plot/clf.m: Don't call drawnow.
+
+2007-03-20  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* image/__img__.m: Maybe set yaxis to reverse for images.
+	* plot/__go_draw_axes__.m: Don't add flipy to gnuplot command for
+	images.
+
+	* plot/drawnow.m: Make __go_close_all_registered__ persistent
+	instead of global.  Only register __go_close_all__ with atexit if
+	the plot stream is successfully opened.
+
+2007-03-15  John W. Eaton  <jwe at octave.org>
+
+	* plot/__go_draw_axes__.m: Make have_newer_gnuplot persistent.
+	From Daniel J Sebald <daniel.sebald at ieee.org>.
+
+2007-03-15  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__go_draw_axes__.m (do_linestyle_command): Fix marker types.
+	Use numeric line types.
+
+	* control/base/rlocus.m: Add asymptotes to the plot.  Use wider
+	lines and larger markers.  Remove key titles from line type
+	properties.
+
+2007-03-14  John W. Eaton  <jwe at octave.org>
+
+	* plot/__axis_label__.m: Accept additional property-value pairs
+	and pass them to __go_text__.  Simply return the handle obtained
+	from __go_text__ instead of calling get on the current axis.
+	* plot/xlabel.m, plot/zlabel.m, plot/zlabel.m: Check args here.
+	Allow for extra property value pairs to be passed along.
+	* plot/title.m: Implement with __axis_label__ since it does all
+	that title needs to do.
+
+	* plot/clf.m: Set currentaxes property for current figure to [].
+
+	* plot/__axis_label__.m: Convert arg to text handle before calling set.
+
+	* plot/__plt__.m: Return line handles from all calls to __plt1__
+	and __plt2__, not just the last.
+
+	* plot/Makefile.in (SOURCES): Rename from SOURCES_M.
+	(SOURCES_IN, GEN_M): Delete.
+	(FCN_FILES): Don't include $(GEN_M).
+	(all): Don't depend on $(GEN_M).
+	($(GEN_M) : %.m : %.in): Delete pattern rule.
+
+	* plot/text.m: Use __go_text__ instead of __uiboject_text_ctor__.
+
+	* plot/newplot.m: Call __go_axes_init__ instead of
+	__uiobject_axes_init__.
+
+	* plot/mesh.m: Use __go_surface__ instead of
+	__uiobject_surface_ctor__.  Don't access object fields directly.
+
+	* plot/line.m: Use __line__ to do actual work.
+	* plot/__line__.m: New function.
+
+	* plot/axes.m: Use __go_axes__ to create axes graphics handle.
+	Use get and set instead of accessing object fields directly.
+
+	* plot/figure.m: Use __go_figure__ to create figure graphics
+	handle.
+
+	* plot/drawnow.m: Register __go_close_all__ with atexit instead of
+	__uiobject_close_all.  Call __go_draw_figure__ instead of
+	__uiobject_draw_figure__.
+
+	* plot/clf.m: Use get instead of accessing object fields
+	directly.  Simply delete children.  Don't set currentaxes.
+
+	* plot/close.m (close_all_figures): New subfunction.
+	Use it instead of getting list of figures to close from
+	__uiobject_figures__.
+
+	* plot/closereq.m: Simply delete the current figure.  Don't set
+	currentfigure.
+
+	* plot/__errplot__.m: Call __line__ instead of
+	__uiobject_line_ctor__.  Use set instead of accesing object fields
+	directly.  Don't call __uiobject_adopt__.
+
+	* plot/__uiobject_adopt__.m, plot/__uiobject_alloc__.in,
+	plot/__uiobject_axes_ctor__.m, plot/__uiobject_axes_dtor__.m,
+	plot/__uiobject_axes_init__.in, plot/__uiobject_axes_setr__.m,
+	plot/__uiobject_delete__.m, plot/__uiobject_figure_ctor__.m,
+	plot/__uiobject_figures__.in, plot/__uiobject_free__.in,
+	plot/__uiobject_get_handle__.in, plot/__uiobject_globals__.m,
+	plot/__uiobject_grow_list__.in, plot/__uiobject_handle2idx__.in,
+	plot/__uiobject_image_ctor__.m, plot/__uiobject_init_figure__.in,
+	plot/__uiobject_init_root_figure__.in,
+	plot/__uiobject_line_ctor__.m, plot/__uiobject_make_handle__.in,
+	plot/__uiobject_root_figure_ctor__.m,
+	plot/__uiobject_surface_ctor__.m, plot/__uiobject_text_ctor__.m:
+	plot/get.in, plot/include-globals.awk, plot/ishandle.m,
+	plot/set.in: Delete.
+	* plot/Makefile.in (SOURCES_M, SOURCES_IN): Remove from lists.
+
+	* plot/__go_close_all__.m: Rename from __uiobject_close_all.m.
+	Pass "hidden" as second arg to close.
+	* plot/__go_draw_axes__.m: Rename from __uiobject_draw_axes.m.
+	* plot/__go_draw_figure__.m: Rename from __uiobject_draw_figure.m.
+	* plot/Makefile.in (SOURCES_M): Rename in list.
+	
+	* image/__img__.m: Use __go_image__ to create image graphics
+	handle.
+
+	* miscellaneous/delete.m: Call __go_delete__, not
+	__uiobject_delete__.  Check that arg is a graphics handle before
+	calling __go_delete__.
+
+2007-03-13  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/cast.m: Use feval and strcmp with cell to check
+	arg instead of switch statement.
+	From S�ren Hauberg <soren at hauberg.org>.
+
+2007-03-12  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/cast.m: New function.
+
+	* miscellaneous/delete.m: Call __go_delete__, not __uiobject_delete__.
+
+2007-03-08  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/copyfile.m, miscellaneous/movefile.m: Perform
+	tilde expansion on target filename before passing it to the shell.
+
+	* statistics/base/Makefile.in (SOURCES): Remove unidrnd.m from list.
+	* statistics/distributions/Makefile.in (SOURCES): Add it here.
+
+2007-03-08  David Bateman  <dbateman at free.fr>
+
+	* statistics/base/unidrnd.m: Move to statistics/distributions
+	replacing slower version based on dicrete_rnd.
+
+2007-03-07  John W. Eaton  <jwe at octave.org>
+
+	* control/base/rlocus.m: Update for current plotting functions.
+
+2007-03-07  A. S. Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* control/base/rlocus.m: Improve display.
+
+2007-03-07  John W. Eaton  <jwe at octave.org>
+
+	* plot/legend.m: Only handle positions -1:4.
+	* plot/__pltopt1__.m: Don't set linestyle if only marker style is
+	found in option string
+	* plot/__uiobject_draw_axes__.m: Handle key position.
+
+	* plot/newplot.m: Always reset next line color.
+
+	* testfun/assert.m: Check that number of dimensions match before
+	checking dimensions.
+
+2007-03-07  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* specfun/perms.m, specfun/factorial.m: Check args.
+
+2007-03-07  John W. Eaton  <jwe at octave.org>
+
+	* plot/mesh.m: Call newplot before doing anything.
+
+	* plot/__uiobject_draw_axes__.m: Send "e\n" at end of data, not
+	just "e".  Only flush plot stream once.
+	From Daniel J Sebald <daniel.sebald at ieee.org>.
+
+	* strings/blanks.m: Omit first index in assignment.
+
+2007-03-07  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* set/setdiff.m: Some code cleanup and a fix for setdiff on rows.
+
+2007-03-06  David Bateman  <dbateman at free.fr>
+	    John W. Eaton  <jwe at octave.org>
+
+	* set/setdiff.m: Ignore "rows" for cell array args.
+	Handle cellstr args.
+
+2007-03-05  John W. Eaton  <jwe at octave.org>
+
+	* optimization/sqp.m: Defer first call to obj_hess until after
+	calling obj_fun.
+
+2007-03-02  Bob Weigel  <rweigel at gmu.edu>
+
+	* specfun/nchoosek.m: Fix nargin check.
+
+2007-03-01  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* image/__img__.m: Don't set xlim and ylim properties.
+
+2007-03-01  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* general/interp1.m: Fix *style cases for decreasing x.
+
+2007-03-01  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* polynomial/roots.m: Check nargin before accessing arg.
+
+2007-02-28  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: If looking at image data, Don't
+	increment data_idx unless using gnuplot for display.
+
+2007-02-28  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__uiobject_draw_axes__.m: Improve calculation of limits for
+	plots with images.
+	* image/image.m, image/imagesc.m, image/imshow.m:
+	Deprecate zoom argument.
+
+2007-02-28  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Use fullfile to generate
+	temporary file names.  Keep image and colormap file ids separate.
+
+	* general/interp1.m: Correctly compute min and max values when
+	values are decreasing and not evenly spaced.
+	From Ricardo Marranita <ricardo.marranita at gmail.com>.
+
+2007-02-27  John W. Eaton  <jwe at octave.org>
+
+	* testfun/test.m (test): Handle possibility of file_in_loadpath
+	returning an empty cell array.
+
+2007-02-27  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* pkg/pkg.m: Use fullfile to create filenames from parts.
+
+2007-02-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in, audio/Makefile.in, control/Makefile.in,
+	control/base/Makefile.in, control/hinf/Makefile.in,
+	control/obsolete/Makefile.in, control/system/Makefile.in,
+	control/util/Makefile.in, deprecated/Makefile.in,
+	elfun/Makefile.in, finance/Makefile.in, general/Makefile.in,
+	image/Makefile.in, io/Makefile.in, linear-algebra/Makefile.in,
+	miscellaneous/Makefile.in, optimization/Makefile.in,
+	path/Makefile.in, pkg/Makefile.in, plot/Makefile.in,
+	polynomial/Makefile.in, quaternion/Makefile.in, set/Makefile.in,
+	signal/Makefile.in, sparse/Makefile.in, specfun/Makefile.in,
+	special-matrix/Makefile.in, startup/Makefile.in,
+	statistics/Makefile.in, statistics/base/Makefile.in,
+	statistics/distributions/Makefile.in,
+	statistics/models/Makefile.in, statistics/tests/Makefile.in,
+	strings/Makefile.in, testfun/Makefile.in, time/Makefile.in:
+	Use $(LN_S) instead of ln or ln -s.
+
+2007-02-24  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (configure_make): Ignore blank lines and trailing
+	'\n' in FILES file.
+	(configure_make): Also install any mex files.
+
+2007-02-24  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions (SOURCES): Add nbincdf.m,
+	nbininv.m, nbinpdf.m and nbinrnd.m.
+
+2007-02-23  John W. Eaton  <jwe at octave.org>
+
+	* statistics/distributions/Makefile.in (SOURCES): Remove
+	pascal_cdf.m pascal_inv.m pascal_pdf.m pascal_rnd.m from the list.
+
+	* deprecated/Makefile.in (SOURCES): Add pascal_cdf.m,
+	pascal_inv.m, pascal_pdf.m, and pascal_rnd.m to the list.
+
+2007-02-23  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions/discrete_rnd.m, 
+	statistics/distributions/geornd.m, 
+	statistics/distributions/lognnd.m, 
+	statistics/distributions/nbinrnd.m, 
+	statistics/distributions/wblrnd.m:  Accelerate distributions.
+	 
+	* statistics/distributions/unidcdf.m, 
+	statistics/distributions/unidinv.m, 
+	statistics/distributions/unidpdf.m, 
+	statistics/distributions/unidrnd.m: New functions based on 
+	discrete_cdf, etc.
+
+	* statistics/distributions/pascal_cdf.m,
+	statistics/distributions/pascal_inv.m,
+	statistics/distributions/pascal_pdf.m,
+	statistics/distributions/pascal_rnd.m: Remove.
+	* statistics/distributions/nbincdf.m,
+	statistics/distributions/nbininv.m,
+	statistics/distributions/nbinpdf.m,
+	statistics/distributions/nbinrnd.m: Replace with matlab
+	compatible functions.
+	* deprecated/pascal_cdf.m, deprecated/pascal_inv.m,
+	deprecated/pascal_pdf.m, deprecated/pascal_rnd.m: Use the new
+	nbincdf, etc functions to implement these.
+
+2007-02-22  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__uiobject_draw_axes__.m: Insert newline between plot
+	command and data.
+
+2007-02-22  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/doc.m: If index search fails, try again without
+	the index search option.
+
+2007-02-22  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/doc.m: Find doc.info file correctly in user directories.
+
+	* statistics/distributions/frnd.m, statistics/distributions/exprnd.m, 
+	statistics/distributions/gamrnd.m, statistics/distributions/trnd.m, 
+	statistics/distributions/poissrnd.m, statistics/distributions/chi2rnd.m,
+	statistics/distributions/betarnd.m: Convert to use randg, rande
+	and randp to accelerate.
+
+	* pkg/pkg.m (fix_depends): Support > and < operators as well. 
+
+2007-02-22  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: If not using gnuplot for images,
+	cache data and display after xlim and ylim have been determined.
+
+2007-02-22  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__uiobject_draw_axes__.m:
+	Allow multiple images to be displayed with gnuplot.
+
+2007-02-20  Rafael Laboissiere  <rafael at debian.org>
+
+	* optimization/glpk.m: Document the fact that extra.mem does not work
+	for versions of GLPK 4.15 and later.
+
+2007-02-19  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_alloc__.in: If next available element in
+	__uiobject_list__ is 0, grow list before doing anything else.
+	* plot/__uiobject_grow_list__.in: Only set __uiobject_head__ on
+	first call when size of __uiobject_list__ is 0.
+
+2007-02-16  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/Makefile.in (SOURCES): Remove popen2.m from the list.
+
+2007-02-16  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* miscellaneous/popen2.m: Remove as replaced with builtin.
+
+2007-02-16  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* specfun/nchoosek.m: Check nargin.
+
+2007-02-15  John W. Eaton  <jwe at octave.org>
+
+	* path/addpath.m, path/rmpath.m: Delete
+	* path/Makefile.in (SOURCES): Remove them from the list.
+
+	* plot/__uiobject_axes_init__.in, plot/__uiobject_axes_setr__.m:
+	Delete title, xlabel, ylabel, and zlabel properties before
+	reassigning.
+	* plot/__uiobject_axes_init__.in: New arg, mode.
+	Don't init outerposition if "mode" is "replace".
+	* plot/newplot.m: Check both figure and axes nextplot properties.
+	If axes nextplot property is replace, pass "replace" as mode arg
+	to __uiobject_axes_init__.
+
+2007-02-15  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* image/imshow.m: Don't restore old colormap.
+
+	* plot/__uiobject_image_ctor__.m: Set xdata and ydata properties.
+	* image/__img__.m: New file containing common parts of image.m and
+	imshow.m.
+	* image/Makefile.in (SOURCES): Add __img__.m to the list.
+	* image/image.m, image/imshow.m: Call __img__.
+	* plot/__uiobject_draw_axes__.m:
+	Handle rgb imaged data stored in 3-d arrays.
+
+	* plot/figure.m: Doc fix.
+
+2007-02-14  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* audio/wavread.m, audio/wavwrite.m: Use types with specific sizes
+	for reading and writing data.  New tests.  Improve rounding.
+
+2007-02-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/stem.m: New file, adapted from OctPlot.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+
+	* plot/__errcomm__.m, plot/__plr1__.m, plot/__plr2__.m,
+	plot/__plt1__.m, plot/__plt2__.m, plot/__plt2mm__.m,
+	plot/__plt2mv__.m, plot/__plt2ss__.m, plot/__plt2vm__.m,
+	plot/__plt2vv__.m, plot/__plt__.m, plot/loglog.m,
+	plot/loglogerr.m, plot/plot.m, plot/plot3.m, plot/polar.m,
+	plot/semilogx.m, plot/semilogxerr.m, plot/semilogy.m,
+	plot/semilogyerr.m: Return handles to line objects.
+
+2007-02-11  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_close_all.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+
+2007-02-10  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: Arrange for plot streams to be close on exit.
+	* plot/__uiobject_globals__.m: Don't call mlock.
+
+	* plot/drawnow.m: Only check for DISPLAY if isunix returns true.
+	* plot/__uiobject_delete__.m: Send quit command and flush stream
+	before calling pclose.
+
+2007-02-09  John W. Eaton  <jwe at octave.org>
+
+	* plot/subplot.m: Delete spurious call to axes.
+
+	* plot/figure.m: Call drawnow for current figure before creating
+	or switching to a new figure.
+	* plot/__uiobject_init_figure__.in: Handle empty arg the same as
+	nargin == 0 case.
+
+	* testfun/assert.m: Try to avoid problems when comparisons involve
+	strange values like Inf+NaNi.
+
+2007-02-08  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow.m: Use gnuplot_binary() instead of just "gnuplot"
+	and check gnuplot_use_title_option instead of just assuming -title
+	works.  From Michael Goffioul <michael.goffioul at swing.be>.
+
+	* Makefile.in (DISTFILES): Add move-if-change to the list.
+
+	* audio/Makefile.in, control/base/Makefile.in,
+	control/hinf/Makefile.in, control/obsolete/Makefile.in,
+	control/system/Makefile.in, control/util/Makefile.in,
+	deprecated/Makefile.in, elfun/Makefile.in, finance/Makefile.in,
+	general/Makefile.in, image/Makefile.in, io/Makefile.in,
+	linear-algebra/Makefile.in, miscellaneous/Makefile.in,
+	optimization/Makefile.in, plot/Makefile.in,
+	polynomial/Makefile.in, quaternion/Makefile.in, set/Makefile.in,
+	signal/Makefile.in, sparse/Makefile.in, specfun/Makefile.in,
+	special-matrix/Makefile.in, startup/Makefile.in,
+	statistics/base/Makefile.in, statistics/distributions/Makefile.in,
+	statistics/models/Makefile.in, statistics/tests/Makefile.in,
+	strings/Makefile.in, testfun/Makefile.in, time/Makefile.in,
+	path/Makefile.in, pkg/Makefile.in: Explicitly list source files.
+
+	* plot/figure.m: Don't call drawnow.  Correctly init figure when
+	only given property list.
+
+2007-02-07  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Handle xdir, ydir, and zdir axis
+	properties.
+
+	* plot/sombrero.m: Call box ("off") after mesh.
+
+	* plot/__uiobject_draw_axes__.m: Avoid rgb colors and "set style
+	line default" commands with older versions of gnuplot.
+
+	* plot/close.m: Use get (0, "currentifgure") instead of gcf.
+
+2007-02-06  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Set pt to 0 if marker is ".".
+	* sparse/gplot.m: Use line style - instead of 1.
+
+2007-02-05  Rafael Laboissiere  <rafael at debian.org>
+
+	* plot/print.m: Avoid error message from cellidx.
+
+2007-02-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/legend.m: Fix check for data.
+
+2007-02-05  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* plot/__uiobject_draw_axes__.m (do_linestyle_command):
+	Always set lt and pt.
+
+2007-02-05  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* plot/contourc.m: Correctly compute X and Y.
+
+2007-02-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Use title "" if no explicit title.
+	When setting {x,y,z}lim, also set {x,y,z}limmode to "auto.
+
+2007-02-01  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m:
+	Don't try to set axis limits unless we have data.
+
+	*  plot/__plt1__.m, plot/__plt2__.m, plot/__plt2mm__.m,
+	plot/__plt2mv__.m, plot/__plt2ss__.m, plot/__plt2vm__.m,
+	plot/__plt2vv__.m, plot/__plt__.m, plot/__pltopt1__.m,
+	plot/__pltopt__.m, plot/plot3.m: Set and use options struct
+	instead of of key and fmt strings.
+
+	* plot/__pltopt1__.m: Greatly simplify.
+
+	* plot/__next_line_color__.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+	* plot/newplot.m: Call __next_line_color__ here to reset rotation.
+
+	* plot/__default_plot_options__.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+
+	* plot/__plt3__.m: Delete.
+	* plot/Makefile.in (SOURCES_M): Remove it from the list.
+
+2007-01-31  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Set defaults for color,
+	linestyle, linewidth, marker, and markersize properties.
+	* plot/__uiobject_draw_axes__.m: Attempt to handle line and marker
+	colors and widths, and line styles.
+
+	* plot/__plt__.m, image/image.m: Don't call drawnow.
+
+	* plot/__gnuplot_version__.m: Restore from CVS Attic.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+
+	* plot/__uiobject_draw_axes__.m: Delete useless call to
+	__gnuplot_save_data__.
+
+	* image/image.m: Accept 2 args, but ignore the second for now.
+
+2007-01-30  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (pkg, isautoload, install, load_packages): Add ability
+	to flag a package as to be autoloaded. Add install flags -noauto, 
+	-auto to force autoload behavior.
+	(installed_packages): Make list of installed packages unique.
+
+2007-01-30  John W. Eaton  <jwe at octave.org>
+
+	* Merge of changes from graphics-branch:
+
+	2007-01-29  John W. Eaton  <jwe at octave.org>
+
+	* plot/subplot.m: Set nextplot property of current figure to "add".
+
+	* plot/__uiobject_draw_axes__.m: Only handle outerposition
+	property if it exists.
+
+	2007-01-26  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Move initialization of max and
+	min values outside of loop over child objects.
+
+	* plot/contour.m, plot/contourc.m: New files.
+	* plot/Makefile.in (SOURCES_M): Add them to the list.
+
+	* image/image_viewer.m: Set view_fcn to "gnuplot_internal" if we
+	find a gnuplot version newer than 4.0.
+	* image/__img_gnuplot__.m: Delete.
+	* image/image.m: Create image graphics object.
+	Call newplot to setup and drawnow to finish.
+	Eliminate ZOOM arg.
+
+	* plot/__uiobject_draw_axes__.m: Handle image data.
+
+	* plot/legend.m: Eliminate useless variable "warned".
+
+	* plot/__uiobject_image_ctor__.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+
+	* plot/gcf.m: Also create new figure if currentfigure is 0.
+	* plot/drawnow.m: Use get (0, "currentfigure") instead of gcf.
+
+	* plot/__uiobject_root_figure_ctor__.m: Set visible property.
+
+	* plot/__default_colormap__.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+	* plot/__uiobject_figure_ctor__.m: Use it to set default colormap
+	property.
+	* image/colormap.m: Use colormap property of current figure
+	to store colormap instead of using persistent variable.
+	Call __default_colormap__ to get default map value.
+	* image/ocean.m, image/gray.m: Set colormap for current figure.
+
+	* plot/__uiobject_draw_axes__.m: Handle aspect ratio property.
+	Handle some tick mark options.
+
+	* plot/__uiobject_axes_setr__.m: If we see xtick, ytick, or ztick,
+	set corresponding *mode to "manual".  If we set dataaspectratio,
+	set dataaspectratiomode to "manual".
+
+	* plot/__uiobject_axes_init__.m: Include *tick, *tickmode,
+	*ticklabelmode, dataaspectratio, dataaspectratiomode properties.
+
+	* plot/axis.m: New file.
+	* plot/Makefile.in (SOURCES_M): Include it in the list.
+
+	* plot/__uiobject_axes_setr__.m: If we see xlim, ylim, or zlim,
+	set corresponding *limmode to "manual".
+	* plot/__uiobject_draw_axes__.m	(get_axis_limits): New subfunction.
+	Use it to compute autosclaled limits.
+	Arg is now handle, not object.  Change all callers.
+	Compute data limits.
+
+	2007-01-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/drawnow: Fix visibility check for zero args.
+
+	* plot/text.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+	* plot/__uiobject_draw_axes__.m: Handle text objects.
+	* plot/__uiobject_text_ctor__.m: Include units, position, and
+	horizontalalignment properties.
+
+	* plot/figure.m: Set options for f we just constructed or were
+	given as an argument, not gcf.  Only return handle if nargout > 0.	
+
+	* plot/drawnow.m: Handle visible field for figure here.
+	* plot/__uiobject_figure_ctor__.m: Set default visible field.
+
+	* plot/__uiobject_draw_axes__.m: Call undo_string_escapes on
+	title and axis labels.
+
+	* plot/plot3.m, plot/mesh.m: Set default 3-d view here.
+	* plot/__uiobject_draw_axes__.m: Handle view for 3-d plots.
+	* plot/__uiobject_axes_init__.in: Set default view field for object.
+	* plot/view.m: New file.
+	* plot/Makefile.in (SOURCES_M): Add it to the list.
+
+	* plot/__uiobject_make_handle__.in, plot/set.m, plot/drawnow.m:
+	Call __request_drawnow__.
+
+	* plot/newplot.m: For "replace" action, call __uiobject_axes_init__.
+
+	* plot/__uiobject_axes_ctor__.m, plot/__uiobject_text_ctor__.m:
+	Call set to set properties.  Return handle instead of structure.
+	Change all callers.
+
+	* plot/__uiobject_axes_setr__.m: New file.
+	* plot/set.in: Check for __setter__ field.
+
+	* plot/__uiobject_axes_init__.in:
+	Rename from plot/__uiobject_axes_init__.m.
+	Include __uiobject_globals__.
+	Accept handle as arg instead of structure
+	* plot/Makefile.in (SOURCES_M): Remove __uiobject_axes_init__.m
+	from the list.
+	(SOURCES_IN): Add __uiobject_axes_init__.in to the list.
+
+	2007-01-24  John W. Eaton  <jwe at octave.org>
+
+	* plot/Makefile.in ($(GEN_M)): Depend on __uiobject_globals__.m.
+
+	* plot/__uiobject_globals__.m: Call __lock_global__ when
+	initializing each global variable.
+
+	2007-01-18  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_globals__.m (__uiobject_handles_free_list__,
+	__uiobject_figure_handles_free_list__): New global variables.
+	* plot/__uiobject_get_handle__.m, plot/__uiobject_free__.m:
+	Place unused handles on the free list.
+
+	* plot/__uiobject_get_figure_handle__.in: Delete.
+	* plot/Makefile.in: Delete it from the SOURCES_IN list.
+
+	* plot/__uiobject_init_figure__.in: Perform allocation of figure
+	handles here.  Return figure handle.
+	* plot/figure.m: Call __uiobject_init_figure__ to allocate handle.
+
+	2007-01-11  John W. Eaton  <jwe at octave.org>
+
+	* plot/__uiobject_draw_axes__.m: Use "%g", not "%.4g" when writing
+	data for gnuplot.
+
+	* plot/Makefile.in (SOURCES_M, SOURCES_IN, GEN_M): New lists of
+	files.
+	(SOURCES): Include $(SOURCES_M) and $(SOURCES_M) in the list.
+	(DISTFILES): Include include-globals.awk in the list.
+	(FCN_FILES): Define using $(SOURCES_M) and $(GEN_M).
+	($(GEN_M) : %.m : %.in): New rule.
+
+	* include-globals.awk: New file.
+
+	* plot/__uiobject_alloc__.in, plot/__uiobject_figures__.in, 
+	plot/__uiobject_free__.in, plot/__uiobject_get_figure_handle__.in, 
+	plot/__uiobject_get_handle__.in, plot/__uiobject_grow_list__.in, 
+	plot/__uiobject_handle2idx__.in, plot/__uiobject_init_figure__.in, 
+	plot/__uiobject_init_root_figure__.in,
+	plot/__uiobject_make_handle__.in,  plot/get.in, plot/set.in:
+	Rename from corresponding .m files.
+
+	* move-if-change: New file.
+
+	* plot/__uiobject_delete__.m: New file.
+	* plot/delete.m, plot/__uiobject_delete_children__.m,
+	plot/__uiobject_delete_child__.m: Delete.
+	* miscellaneous/delete.m: Forward to __uiobject_delete__ if arg is
+	not a character string.
+	* plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2vm__.m:
+	Fix assignment to tmp key value in loop.
+	* plot/__uiobject_axes_dtor__.m: No need to Call __uiobject_free__
+	for obj.title, obj.xlabel, obj.ylabel, obj.zlabel.
+	* plot/__uiobject_axes_dtor__.m, plot/__uiobject_axis_init__.m:
+	Inline code to delete children.
+	* plot/__uiobject_free__.m: Arg is now handle, not index into
+	__uiobject_list__.
+	* plot/clf.m, plot/closereq.m, plot/newplot.m: No need to remove
+	and free child.
+
+	2006-12-08  John W. Eaton  <jwe at octave.org>
+
+	* plot/gcf.m: Check if the root figure object's currentfigure
+	handle is empty, not 0.
+	* plot/__uiobject_root_figure_ctor__.m:
+	Set currentfigure to [], not 0.
+
+	* plot/stairs.m: Handle matrix arguments.  Improve compatibility.
+
+	2006-12-07  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt_get_axis_arg__.m, plot/__uiobject_adopt__.m,
+	plot/__uiobject_alloc__.m, plot/__uiobject_axes_ctor__.m,
+	plot/__uiobject_axes_dtor__.m, plot/__uiobject_axes_init__.m,
+	plot/__uiobject_delete_children__.m,
+	plot/__uiobject_draw_axes__.m, plot/__uiobject_draw_figure__.m,
+	plot/__uiobject_figure_ctor__.m, plot/__uiobject_figures__.m,
+	plot/__uiobject_free__.m, plot/__uiobject_get_figure_handle__.m,
+	plot/__uiobject_get_handle__.m, plot/__uiobject_globals__.m,
+	plot/__uiobject_grow_list__.m, plot/__uiobject_handle2idx__.m,
+	plot/__uiobject_init_figure__.m,
+	plot/__uiobject_init_root_figure__.m,
+	plot/__uiobject_line_ctor__.m, plot/__uiobject_make_handle__.m,
+	plot/__uiobject_remove_child__.m,
+	plot/__uiobject_root_figure_ctor__.m,
+	plot/__uiobject_surface_ctor__.m, plot/__uiobject_text_ctor__.m,
+	plot/axes.m, plot/box.m, plot/closereq.m, plot/delete.m,
+	plot/drawnow.m, plot/gca.m, plot/gcf.m, plot/get.m,
+	plot/isfigure.m, plot/ishandle.m, plot/line.m, plot/newplot.m,
+	plot/set.m: New files.
+
+	* plot/__plt3__.m, plot/errorbar.m, plot/__axis_label__.m,
+	plot/__plr1__.m, plot/__errcomm__.m, plot/print.m, plot/zlabel.m,
+	plot/__plt1__.m, plot/__plt2__.m, plot/sombrero.m, plot/shg.m,
+	plot/fplot.m, plot/ndgrid.m, plot/clf.m, plot/hold.m,
+	plot/ishold.m, plot/meshdom.m, plot/ylabel.m, plot/__plt2ss__.m,
+	plot/__plt2vv__.m, plot/__plr2__.m, plot/__plt2mm__.m,
+	plot/__pltopt1__.m, plot/meshgrid.m, plot/__plt2mv__.m,
+	plot/figure.m, plot/xlabel.m, plot/stairs.m, plot/__plt2vm__.m,
+	plot/bar.m, plot/__errplot__.m, plot/semilogx.m, plot/semilogy.m,
+	plot/loglog.m, plot/polar.m, plot/legend.m, plot/orient.m,
+	plot/title.m, plot/__pltopt__.m, plot/grid.m, plot/hist.m,
+	plot/subplot.m, plot/plot.m, plot/mesh.m, plot/__plt__.m,
+	plot/close.m, plot/loglogerr.m, plot/plot3.m, plot/semilogxerr.m,
+	plot/semilogyerr.m, plot/replot.m:
+	Adapt to new graphics data structure.
+
+	* plot/__do_legend__.m, plot/__gnuplot_version__.m,
+	plot/__init_plot_vars__.m, plot/__make_using_clause__.m,
+	plot/__plot_globals__.m, plot/__plr__.m, plot/__render_plot1__.m,
+	plot/__render_plot__.m, plot/__setup_plot__.m, plot/axis.m,
+	plot/contour.m, plot/mplot.m, plot/multiplot.m, plot/oneplot.m,
+	plot/plot_border.m, plot/subwindow.m: Delete.
+
+2007-01-24  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Install ChangeLog file if it exists.
+	Delete bare newline in string passed to write_INDEX.
+
+	* sparse/sprandsym.m: Make work for even values of N.
+
+2007-01-24  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/news.m: New file.
+
+2007-01-23  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* strings/strncmpi.m: Use strncmp instead of calling strtrunc on args.
+
+	* strings/strncmp.m: Delete (we now have a built-in version).
+
+2007-01-22  Bob Weigel  <rweigel at gmu.edu>
+
+	* testfun/test.m: Check for all files in path, use first found.
+
+2007-01-22  David Bateman  <dbateman at free.fr>
+
+	* polynomial/spline.m: Make DG a column instead of a row vector.
+
+2007-01-18  S�ren Hauberg  <hauberg at gmail.com>
+
+	* pkg/pkg.m (copy_files): Call write_INDEX with correct target
+	file name.
+
+	* image/ind2rgb.m: Better input checking.  Return 3-d array if
+	nargout is 1.  Handle colormaps that have too few colors.
+
+	* pkg/pkg.m (create_pkgadddel): Call fullfile with nm, not "nm".
+	(configure_make): Use fullfile instead of concatenating with "/".
+
+2007-01-10  Baylis Shanks  <bshanks3 at hotmail.com>
+
+	* set/ismember.m: Handle N-d arrays.
+
+2007-01-10  David Bateman  <dbateman at free.fr>
+
+	* elfun/acosd.m, elfun/acotd.m, elfun/acscd.m, elfun/asecd.m,
+	elfun/asind.m, elfun/atand.m, elfun/cosd.m, elfun/cotd.m,
+	elfun/cscd.m, elfun/secd.m, elfun/sind.m, elfun/tand.m:
+	New files.
+
+2007-01-09  S�ren Hauberg  <hauberg at gmail.com>
+
+	 * pkg/pkg.m: Allow filenames to contain glob patterns.
+
+2007-01-08  S�ren Hauberg  <hauberg at gmail.com>
+
+	* pkg/pkg.m: Use copyfile instead of calling system.  Use fullfile
+	instead of concatenating with "/".  Use mlock to ensure that
+	persistent variables are not clobbered if user types clear all.
+
+2007-01-08  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/copyfile.m, miscellaneous/movefile.m:
+	Improve handling of file names containing globbing characters.
+	From S�ren Hauberg <hauberg at gmail.com>.
+
+2007-01-05  John W. Eaton  <jwe at octave.org>
+
+	* optimization/optimset.m, optimization/__fsolve_defopts__.m:
+	New files.
+
+2006-12-30  John W. Eaton  <jwe at octave.org>
+
+	* sparse/spfun.m: Check for "function_handle" not "function handle".
+	* plot/fplot.m: Likewise.  Use isa instead of strcmp + class.
+
+2006-12-27  S�ren Hauberg  <hauberg at gmail.com>
+
+	* image/imshow.m: Strip NaNs from image.
+
+2006-12-08  David Bateman  <dbateman at free.fr>
+
+	* sparse/normest.m: New file.
+
+2006-12-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* miscellaneous/copyfile.m, miscellaneous/movefile.m:
+	Work on Windows systems without cp or mv.
+
+	* startup/inputrc: Include sequences for Windows.
+
+2006-12-06  S�ren Hauberg  <hauberg at gmail.com>
+
+	* pkg/pkg.m (unload_packages): New function.
+	(pkg): Handle unload action.
+
+	* __errplot__.m: Add missing semicolon.
+
+2006-11-30  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/mexext.m: New file.
+
+2006-11-29  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m: Add local_list and global_list options that allow the
+	location of package lists to be probed and set.
+
+2006-11-17  John W. Eaton  <jwe at octave.org>
+
+	* plot/__render_plot1__.m: Reverse y axis for images.
+
+	* plot/__render_plot__.m: New args, terminal and output.
+	* plot/print.m: Don't set output and term here.  Instead, call
+	__render_plot__ with terminal and output.
+
+2006-11-16  John W. Eaton  <jwe at octave.org>
+
+	* plot/__render_plot1__.m: New file.
+	* plot/__render_plot__.m: Use it.  Loop over multiplots.
+	* plot/print.m, plot/subplot.m: Don't send "set multiplot" to
+	gnuplot.  Let __render_plot__ do that.
+
+2006-11-16  Francesco Potorti`  <Potorti at isti.cnr.it>
+
+	* plot/plot.m: Fix doc string.
+
+2006-11-16  John W. Eaton  <jwe at octave.org>
+
+	* plot/__render_plot__.m: Check for mix of 2-d and 3-d plots
+	before sending anything to the plotter.
+
+2006-11-15  John W. Eaton  <jwe at octave.org>
+
+	* image/__img_gnuplot__.m: Store more info in global plot
+	structures and use __render_plot__ to build plot command to
+	display image.
+
+	* plot/__plt3__.m: New arg, parametric.  Change all callers.
+
+	* plot/__plot_globals__.m (__plot_line_offset__, __plot_command__,
+	__plot_command_sep__): Delete.
+	(__plot_data_type__, __plot_data_parametric__,
+	__plot_image_colormap__, __plot_image_dims__, __plot_fmtstr__,
+	__plot_usingstr__, __plot_withstr__): New variables.
+	* plot/__init_plot_vars__.m: Initialize them.
+
+	* plot/__init_plot_vars__.m, plot/__setup_plot__.m:
+	Don't handle sep or cmd.
+
+	* plot/__render_plot__.m: New function.
+	* plot/__plt__.m, plot/__plt3__.m, plot/__errplot__.m:
+	Store more info in global plot structures and use __render_plot__
+	to build plot command.
+	* plot/replot.m: Simply call __render_plot__.
+
+	* plot/contour.m, plot/mesh.m, plot/plot3.m:
+	Set __plot_data_parametric__ here.
+
+2006-11-14  John W. Eaton  <jwe at octave.org>
+
+	* plot/bottom_title.m, plot/top_title.m: Delete.
+
+	* image/image_viewer.m: Set default values here.
+	* image/image.m: Not here.
+
+	* image/image_viewer.m: Always return old values.  Check arguments.
+	* image/__img_gnuplot__.m: Rename from __img__m.
+
+2006-11-14  S�ren Hauberg  <soren at hauberg.org>
+
+	* image/image_viewer.m: New function.
+	* image/__img_via_file__.m: New function.
+	* image/image.m: Use image_viewer to determine which program to
+	use for image viewing.
+	* image/__img__.m: Silently accept more than 3 args.
+
+2006-11-14  John W. Eaton  <jwe at octave.org>
+
+	* plot/__do_legend__.m, plot/__errplot__.m,
+	plot/__init_plot_vars__.m, plot/__plot_globals__.m,
+	plot/__plt3__.m, plot/__plt__.m, plot/__setup_plot__.m,
+	plot/legend.m, plot/mplot.m, plot/multiplot.m, plot/oneplot.m,
+	plot/replot.m, plot/subplot.m, plot/subwindow.m:
+	Use __plot_globals__ for multiplot variables.  Keep track of
+	multiplot info for each figure.  Eliminate __multiplot_xscale__.
+
+2006-11-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/mesh.m: Use proper dimensions for y in call to repmat.
+
+	* miscellaneous/substruct.m: New function.
+
+	* testfun/assert.m: Force orientation to match when comparing
+	struct elements.
+
+	* general/__isequal__.m: Avoid assignment of comma-separated lists
+	when comparing structs.
+
+2006-11-13  S�ren Hauberg  <hauberg at gmail.com>
+
+	* general/bicubic.m, general/cart2pol.m, general/cart2sph.m,
+	plot/contour.m, linear-algebra/cross.m, general/cumtrapz.m,
+	linear-algebra/dot.m, image/imshow.m, general/interp2.m,
+	general/mod.m, plot/plot3.m, plot/__plr2__.m, plot/__plr__.m,
+	general/pol2cart.m, general/polyarea.m, polynomial/polyfit.m,
+	general/rem.m, image/rgb2ind.m, general/sph2cart.m,
+	general/trapz.m, miscellaneous/xor.m: Use size_equal.
+
+2006-11-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/mesh.m: Use size_equal to compare dimensions.
+
+2006-11-13  S�ren Hauberg  <soren at hauberg.org>
+
+	* plot/mesh.m: Simplify.  Set hidden3d for the plot.
+
+2006-11-11  S�ren Hauberg  <soren at hauberg.org>
+
+	* miscellaneous/copyfile.m: Fix docs to match function.
+
+2006-11-08  John W. Eaton  <jwe at octave.org>
+
+	* plot/legend.m: New function, adapted from Octave Forge.
+
+	* plot/__do_legend__.m: New function.
+	* plot/__errplot__.m, plot/__plt3__.m, plot/__plt__.m,
+	plot/replot.m: Call it before plotting.
+
+	* plot/plot3.m, plot/mesh.m, plot/contour.m: Don't send "set
+	noparametric" to gnuplot..
+	
+	* plot/__plotopt__.m, plot/__pltopt1__.m, plot/__plt1__.m,
+	plot/__plt2__.m, plot/__plt2mm__.m, plot/__plt2mv__.m,
+	plot/__plt2ss__.m, plot/__plt2vm__.m, plot/__plt2vv__.m: Accept
+	and return key title separate from line format.  Accept format and
+	key as cellstr.  Always return data as cell array.  Return format
+	and key title as cellstr.
+	* plot/__errplot__.m, plot/__plt3__.m, plot/__plt__.m:
+	Handle line format and key titles separately.
+	* plot/__plt3__.m, plot/__plt__.m: Handle data as cell array only.
+
+	* plot/__plot_globals__.m (__plot_line_offset__,
+	__plot_key_labels__, __plot_key_properties__): New global
+	variables.  Initialize them.
+	* plot/__init_plot_vars__.m (__plot_line_offset__,
+	__plot_key_labels__, __plot_key_properties__): Initialize.
+	* plot/__errplot__.m, plot/__plt3__.m, plot/__plt__.m
+	(__plot_line_offset__, __plot_key_labels__,
+	__plot_key_properties__): Store information about plot key titles.
+
+	* plot/__errplot__.m, plot/__init_plot_vars__.m, plot/__plt3__.m,
+	plot/__plt__.m: Use cf, mxi, and myi as shorthand for
+	__current_figure__, __multiplot_xi__, and __multiplot_yi__,
+	respectively.
+
+	* plot/__errcomm__.m: Allow fmt to be cellstr.
+
+	* strings/strcat.m: Disable Octave:empty-list-elements warning
+	whle concatenating args.
+
+2006-11-07  John W. Eaton  <jwe at octave.org>
+
+	* startup/main-rcfile: Conditionally set PAGER_FLAGS.
+
+2006-11-06  S�ren Hauberg  <soren at hauberg.org>
+
+	* pkg/pkg.m (extract_pkg): No need to pass "dotexceptnewline"
+	option to regexp.
+
+	* image/__img__.m: Send "set size ratio -1" before plotting.
+
+2006-11-03  Bill Denney  <denney at seas.upenn.edu>
+
+	* strings/index.m: New arg, direction.  Simplify and speed up.
+	* strings/rindex.m: Implement using index (..., "last");
+
+	* blanks.m, strcat.m: Simplify.  Add tests.
+
+2006-11-01  Bill Denney  <denney at seas.upenn.edu>
+
+	* general/__isequal__.m: Test size and class more consistently.
+
+2006-10-27  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/ls_command.m: Use /D instead of /w.
+	From Michael Goffioul <michael.goffioul at swing.be>.
+
+	* miscellaneous/ls.m, miscellaneous/ls_command.m: New files.
+	* miscellaneous/dir.m: Mark as a command.
+
+2006-10-27  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* miscellaneous/unpack.m: Fix missing comma in strcat call.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* image/image.m: Set x = y = [] when nargin == 0;
+
+2006-10-25  Quentin Spencer  <qspencer at ieee.org>
+
+	* image/image.m: Call __img__ if gnuplot version is > 4.0.
+	* image/__img__.m: New file, originally from
+	Daniel J Sebald <daniel.sebald at ieee.org>.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/__gnuplot_version__.m: New function, originally from
+	Daniel J Sebald <daniel.sebald at ieee.org> by way of 
+	Quentin Spencer <qspencer at ieee.org>.
+
+2006-10-25  S�ren Hauberg  <soren at hauberg.org>
+
+	* plot/__pltopt__.m: Update symbol marker id numbers for gnuplot 4.
+
+2006-10-24  Bill Denney  <denney at seas.upenn.edu>
+
+	* miscellaneous/unpack.m, miscellaneous/bunzip2.m,
+	miscellaneous/gunzip.m: New files.
+	* miscellaneous/untar.m, miscellaneous/unzip.m:
+	Call unpack to do the real work.
+
+2006-10-24  John W. Eaton  <jwe at octave.org>
+
+	* plot/plot3.m: If we have a format string, then also pass using
+	string to __plt3__.
+
+	* plot/sombrero.m: Don't return anything if nargout == 0.
+
+	* plot/__plt3__.m: Create using clause if none is supplied.
+	* plot/mesh.m: Always pass empty using string to __plt3__.
+
+2006-10-20  Bill Denney  <denney at seas.upenn.edu>
+
+	* movefile.m, copyfile.m: Handle cellstr lists of files.
+	Quote filenames in shell commands.
+
+2006-10-17  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (uninstall): Allow the uninstall to proceed even if
+	the package directory is missing.
+
+2006-10-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/box.m: New function.
+
+2006-10-13  Etienne Grossmann  <etienne at tyzx.com>
+
+	* general/ind2sub.m, general/sub2ind.m: Handle empty indices.
+
+2006-10-12  Quentin Spencer  <qspencer at ieee.org>
+
+	* plot/sombrero.m: Only plot if nargout == 0.  Otherwise, return data.
+
+2006-10-10  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/copyfile.m, miscellaneous/movefile.m: New functions.
+
+2006-10-10  Bill Denney  <denney at seas.upenn.edu>
+
+	* audio/lin2mu.m, audio/loadaudio.m, audio/mu2lin.m,
+	audio/playaudio.m, audio/record.m, audio/saveaudio.m,
+	audio/setaudio.m, audio/wavread.m, audio/wavwrite.m,
+	control/base/__bodquist__.m, control/base/__freqresp__.m,
+	control/base/are.m, control/base/bode.m, control/base/ctrb.m,
+	control/base/damp.m, control/base/dare.m, control/base/dcgain.m,
+	control/base/dre.m, control/base/impulse.m, control/base/lqg.m,
+	control/base/lsim.m, control/base/lyap.m, control/base/nichols.m,
+	control/base/nyquist.m, control/base/obsv.m, control/base/pzmap.m,
+	control/base/rlocus.m, control/base/step.m, control/base/tzero.m,
+	control/hinf/h2norm.m, control/hinf/h2syn.m,
+	control/hinf/hinfnorm.m, control/hinf/hinfsyn.m,
+	control/hinf/is_dgkf.m, control/hinf/wgt1o.m,
+	control/obsolete/dezero.m, control/system/__sysdefioname__.m,
+	control/system/buildssic.m, control/system/c2d.m,
+	control/system/cellidx.m, control/system/d2c.m,
+	control/system/dmr2d.m, control/system/fir2sys.m,
+	control/system/is_abcd.m, control/system/is_controllable.m,
+	control/system/is_detectable.m, control/system/is_digital.m,
+	control/system/is_observable.m, control/system/is_siso.m,
+	control/system/is_stabilizable.m, control/system/is_stable.m,
+	control/system/jet707.m, control/system/listidx.m,
+	control/system/ord2.m, control/system/parallel.m,
+	control/system/ss.m, control/system/ss2zp.m,
+	control/system/starp.m, control/system/sys2ss.m,
+	control/system/sys2tf.m, control/system/sys2zp.m,
+	control/system/sysadd.m, control/system/sysappend.m,
+	control/system/syschtsam.m, control/system/sysconnect.m,
+	control/system/syscont.m, control/system/sysdimensions.m,
+	control/system/sysdisc.m, control/system/sysdup.m,
+	control/system/sysgetsignals.m, control/system/sysgettsam.m,
+	control/system/sysgroup.m, control/system/sysidx.m,
+	control/system/sysmin.m, control/system/sysmult.m,
+	control/system/sysout.m, control/system/sysprune.m,
+	control/system/sysscale.m, control/system/syssetsignals.m,
+	control/system/syssub.m, control/system/sysupdate.m,
+	control/system/tf.m, control/system/tfout.m,
+	control/system/ugain.m, control/system/zp.m,
+	control/system/zpout.m, control/util/__outlist__.m,
+	control/util/__zgpbal__.m, control/util/prompt.m,
+	control/util/sortcom.m, control/util/strappend.m,
+	deprecated/com2str.m, elfun/acot.m, elfun/acoth.m, elfun/acsc.m,
+	elfun/acsch.m, elfun/asec.m, elfun/asech.m, elfun/cot.m,
+	elfun/coth.m, elfun/csc.m, elfun/csch.m, elfun/lcm.m, elfun/sec.m,
+	elfun/sech.m, finance/fv.m, finance/fvl.m, finance/irr.m,
+	finance/nper.m, finance/npv.m, finance/pmt.m, finance/pv.m,
+	finance/pvl.m, finance/rate.m, finance/vol.m,
+	general/__isequal__.m, general/bitcmp.m, general/bitget.m,
+	general/bitset.m, general/blkdiag.m, general/cart2sph.m,
+	general/cell2mat.m, general/circshift.m, general/cplxpair.m,
+	general/cumtrapz.m, general/deal.m, general/diff.m,
+	general/flipdim.m, general/fliplr.m, general/flipud.m,
+	general/ind2sub.m, general/int2str.m,
+	general/is_duplicate_entry.m, general/isdefinite.m,
+	general/isequal.m, general/isequalwithequalnans.m,
+	general/isscalar.m, general/issquare.m, general/issymmetric.m,
+	general/isvector.m, general/logical.m, general/logspace.m,
+	general/mod.m, general/nargchk.m, general/nextpow2.m,
+	general/perror.m, general/postpad.m, general/prepad.m,
+	general/randperm.m, general/rem.m, general/repmat.m,
+	general/rot90.m, general/rotdim.m, general/shift.m,
+	general/shiftdim.m, general/sph2cart.m, general/strerror.m,
+	general/sub2ind.m, general/trapz.m, general/tril.m,
+	general/triu.m, image/gray.m, image/gray2ind.m, image/hsv2rgb.m,
+	image/image.m, image/imagesc.m, image/ind2gray.m, image/ind2rgb.m,
+	image/loadimage.m, image/ntsc2rgb.m, image/ocean.m,
+	image/rgb2hsv.m, image/rgb2ntsc.m, image/saveimage.m, io/beep.m,
+	linear-algebra/commutation_matrix.m, linear-algebra/cond.m,
+	linear-algebra/cross.m, linear-algebra/dmult.m,
+	linear-algebra/dot.m, linear-algebra/duplication_matrix.m,
+	linear-algebra/krylov.m, linear-algebra/krylovb.m,
+	linear-algebra/logm.m, linear-algebra/norm.m,
+	linear-algebra/null.m, linear-algebra/orth.m,
+	linear-algebra/qzhess.m, linear-algebra/rank.m,
+	linear-algebra/trace.m, linear-algebra/vec.m,
+	linear-algebra/vech.m, miscellaneous/bincoeff.m,
+	miscellaneous/delete.m, miscellaneous/dir.m, miscellaneous/dos.m,
+	miscellaneous/fileattrib.m, miscellaneous/fileparts.m,
+	miscellaneous/flops.m, miscellaneous/fullfile.m,
+	miscellaneous/ispc.m, miscellaneous/isunix.m,
+	miscellaneous/menu.m, miscellaneous/not.m, miscellaneous/popen2.m,
+	miscellaneous/single.m, miscellaneous/unix.m, miscellaneous/ver.m,
+	miscellaneous/xor.m, optimization/glpk.m, optimization/glpkmex.m,
+	optimization/qp.m, optimization/sqp.m, plot/__axis_label__.m,
+	plot/__errplot__.m, plot/__plr1__.m, plot/__plr2__.m,
+	plot/__plr__.m, plot/__plt1__.m, plot/__plt2__.m,
+	plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m,
+	plot/__plt2vm__.m, plot/__plt2vv__.m, plot/__pltopt1__.m,
+	plot/__pltopt__.m, plot/bar.m, plot/bottom_title.m, plot/close.m,
+	plot/contour.m, plot/errorbar.m, plot/figure.m, plot/fplot.m,
+	plot/grid.m, plot/hist.m, plot/hold.m, plot/ishold.m,
+	plot/loglogerr.m, plot/mesh.m, plot/meshdom.m, plot/meshgrid.m,
+	plot/multiplot.m, plot/orient.m, plot/polar.m, plot/replot.m,
+	plot/semilogxerr.m, plot/semilogyerr.m, plot/sombrero.m,
+	plot/stairs.m, plot/subplot.m, plot/subwindow.m, plot/title.m,
+	plot/top_title.m, polynomial/compan.m, polynomial/conv.m,
+	polynomial/deconv.m, polynomial/mkpp.m, polynomial/poly.m,
+	polynomial/polyder.m, polynomial/polyderiv.m,
+	polynomial/polyfit.m, polynomial/polygcd.m,
+	polynomial/polyinteg.m, polynomial/polyout.m,
+	polynomial/polyreduce.m, polynomial/polyval.m,
+	polynomial/polyvalm.m, polynomial/ppval.m, polynomial/residue.m,
+	polynomial/roots.m, polynomial/unmkpp.m, quaternion/quaternion.m,
+	set/complement.m, set/create_set.m, set/intersect.m,
+	set/ismember.m, set/setdiff.m, set/setxor.m, set/union.m,
+	set/unique.m, signal/arch_fit.m, signal/arch_rnd.m,
+	signal/arma_rnd.m, signal/autocor.m, signal/autoreg_matrix.m,
+	signal/bartlett.m, signal/blackman.m, signal/detrend.m,
+	signal/diffpara.m, signal/durbinlevinson.m, signal/fftconv.m,
+	signal/fftfilt.m, signal/fftshift.m, signal/filter2.m,
+	signal/freqz.m, signal/hamming.m, signal/hanning.m,
+	signal/hurst.m, signal/ifftshift.m, signal/sinetone.m,
+	signal/sinewave.m, signal/spencer.m, signal/stft.m,
+	signal/synthesis.m, signal/unwrap.m, sparse/gplot.m,
+	sparse/spfun.m, sparse/sprand.m, sparse/sprandn.m,
+	sparse/sprandsym.m, sparse/spstats.m, specfun/beta.m,
+	specfun/betai.m, specfun/betaln.m, specfun/erfinv.m,
+	specfun/gammai.m, specfun/log2.m, specfun/pow2.m,
+	special-matrix/hankel.m, special-matrix/hilb.m,
+	special-matrix/invhilb.m, special-matrix/sylvester_matrix.m,
+	special-matrix/toeplitz.m, special-matrix/vander.m,
+	statistics/base/center.m, statistics/base/cloglog.m,
+	statistics/base/cor.m, statistics/base/corrcoef.m,
+	statistics/base/cov.m, statistics/base/cut.m,
+	statistics/base/gls.m, statistics/base/iqr.m,
+	statistics/base/kendall.m, statistics/base/kurtosis.m,
+	statistics/base/logit.m, statistics/base/mahalanobis.m,
+	statistics/base/mean.m, statistics/base/meansq.m,
+	statistics/base/median.m, statistics/base/moment.m,
+	statistics/base/ols.m, statistics/base/ppplot.m,
+	statistics/base/probit.m, statistics/base/qqplot.m,
+	statistics/base/range.m, statistics/base/ranks.m,
+	statistics/base/run_count.m, statistics/base/skewness.m,
+	statistics/base/spearman.m, statistics/base/statistics.m,
+	statistics/base/std.m, statistics/base/studentize.m,
+	statistics/base/table.m, statistics/base/values.m,
+	statistics/base/var.m, statistics/distributions/betacdf.m,
+	statistics/distributions/betainv.m,
+	statistics/distributions/betapdf.m,
+	statistics/distributions/betarnd.m,
+	statistics/distributions/binocdf.m,
+	statistics/distributions/binoinv.m,
+	statistics/distributions/binopdf.m,
+	statistics/distributions/binornd.m,
+	statistics/distributions/cauchy_cdf.m,
+	statistics/distributions/cauchy_inv.m,
+	statistics/distributions/cauchy_pdf.m,
+	statistics/distributions/cauchy_rnd.m,
+	statistics/distributions/chi2cdf.m,
+	statistics/distributions/chi2inv.m,
+	statistics/distributions/chi2pdf.m,
+	statistics/distributions/chi2rnd.m,
+	statistics/distributions/discrete_cdf.m,
+	statistics/distributions/discrete_inv.m,
+	statistics/distributions/discrete_pdf.m,
+	statistics/distributions/discrete_rnd.m,
+	statistics/distributions/empirical_rnd.m,
+	statistics/distributions/expcdf.m,
+	statistics/distributions/expinv.m,
+	statistics/distributions/exppdf.m,
+	statistics/distributions/exprnd.m,
+	statistics/distributions/fcdf.m, statistics/distributions/finv.m,
+	statistics/distributions/fpdf.m, statistics/distributions/frnd.m,
+	statistics/distributions/gamcdf.m,
+	statistics/distributions/gaminv.m,
+	statistics/distributions/gampdf.m,
+	statistics/distributions/gamrnd.m,
+	statistics/distributions/geocdf.m,
+	statistics/distributions/geoinv.m,
+	statistics/distributions/geopdf.m,
+	statistics/distributions/geornd.m,
+	statistics/distributions/hygecdf.m,
+	statistics/distributions/hygeinv.m,
+	statistics/distributions/hygepdf.m,
+	statistics/distributions/hygernd.m,
+	statistics/distributions/kolmogorov_smirnov_cdf.m,
+	statistics/distributions/laplace_cdf.m,
+	statistics/distributions/laplace_inv.m,
+	statistics/distributions/laplace_pdf.m,
+	statistics/distributions/laplace_rnd.m,
+	statistics/distributions/logistic_cdf.m,
+	statistics/distributions/logistic_inv.m,
+	statistics/distributions/logistic_pdf.m,
+	statistics/distributions/logistic_rnd.m,
+	statistics/distributions/logncdf.m,
+	statistics/distributions/logninv.m,
+	statistics/distributions/lognpdf.m,
+	statistics/distributions/lognrnd.m,
+	statistics/distributions/normcdf.m,
+	statistics/distributions/norminv.m,
+	statistics/distributions/normpdf.m,
+	statistics/distributions/normrnd.m,
+	statistics/distributions/pascal_cdf.m,
+	statistics/distributions/pascal_inv.m,
+	statistics/distributions/pascal_pdf.m,
+	statistics/distributions/pascal_rnd.m,
+	statistics/distributions/poisscdf.m,
+	statistics/distributions/poissinv.m,
+	statistics/distributions/poisspdf.m,
+	statistics/distributions/poissrnd.m,
+	statistics/distributions/stdnormal_cdf.m,
+	statistics/distributions/stdnormal_inv.m,
+	statistics/distributions/stdnormal_pdf.m,
+	statistics/distributions/stdnormal_rnd.m,
+	statistics/distributions/tcdf.m, statistics/distributions/tinv.m,
+	statistics/distributions/tpdf.m, statistics/distributions/trnd.m,
+	statistics/distributions/unifcdf.m,
+	statistics/distributions/unifinv.m,
+	statistics/distributions/unifpdf.m,
+	statistics/distributions/unifrnd.m,
+	statistics/distributions/wblcdf.m,
+	statistics/distributions/wblinv.m,
+	statistics/distributions/wblpdf.m,
+	statistics/distributions/wblrnd.m,
+	statistics/distributions/wienrnd.m, statistics/tests/anova.m,
+	statistics/tests/bartlett_test.m,
+	statistics/tests/chisquare_test_homogeneity.m,
+	statistics/tests/chisquare_test_independence.m,
+	statistics/tests/cor_test.m, statistics/tests/f_test_regression.m,
+	statistics/tests/hotelling_test.m,
+	statistics/tests/hotelling_test_2.m,
+	statistics/tests/kolmogorov_smirnov_test.m,
+	statistics/tests/kolmogorov_smirnov_test_2.m,
+	statistics/tests/kruskal_wallis_test.m, statistics/tests/manova.m,
+	statistics/tests/mcnemar_test.m, statistics/tests/prop_test_2.m,
+	statistics/tests/run_test.m, statistics/tests/sign_test.m,
+	statistics/tests/t_test.m, statistics/tests/t_test_2.m,
+	statistics/tests/t_test_regression.m, statistics/tests/u_test.m,
+	statistics/tests/var_test.m, statistics/tests/welch_test.m,
+	statistics/tests/wilcoxon_test.m, statistics/tests/z_test.m,
+	statistics/tests/z_test_2.m, strings/base2dec.m, strings/blanks.m,
+	strings/deblank.m, strings/dec2base.m, strings/dec2bin.m,
+	strings/dec2hex.m, strings/findstr.m, strings/hex2dec.m,
+	strings/index.m, strings/isletter.m, strings/lower.m,
+	strings/rindex.m, strings/split.m, strings/str2mat.m,
+	strings/str2num.m, strings/strcat.m, strings/strcmpi.m,
+	strings/strfind.m, strings/strjust.m, strings/strmatch.m,
+	strings/strncmp.m, strings/strncmpi.m, strings/strrep.m,
+	strings/strtrunc.m, strings/strvcat.m, strings/substr.m,
+	strings/upper.m, testfun/assert.m, testfun/demo.m,
+	testfun/example.m, testfun/fail.m, testfun/speed.m,
+	testfun/test.m, time/asctime.m, time/calendar.m, time/ctime.m,
+	time/datenum.m, time/datestr.m, time/datevec.m, time/eomday.m,
+	time/etime.m, time/is_leap_year.m:
+	Use print_usage instead of usage.
+
+2006-10-09  David Bateman  <dbateman at free.fr>
+
+	* time/datevec.m: Add additional compatible default parsing strings.
+
+2006-10-09  Bill Denney  <denney at seas.upenn.edu>
+
+	* pkg/pkg.m: Remove trailing "\n" from error messages.
+	Remove compare_versions subfunction.
+
+	* miscellaneous/compare_versions.m: New function to compare
+	version numbers as strings with any boolean operators.
+
+	* miscellaneous/untar.m: Check more rigorously to see if the tar
+	file exists.
+
+2006-10-04  John W. Eaton  <jwe at octave.org>
+
+	* pkg/pkg.m: Use fullfile to concatenate directory and file names.
+
+2006-10-04  S�ren Hauberg  <soren at hauberg.org>
+
+	* pkg/pkg.m: Update docs.  Handle prefix option.
+	Handle dependencies for load option.
+
+2006-10-04  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/clearplot.m, deprecated/clg.m: New functions.
+
+	* plot/clg.m: Delete.
+	* plot/__init_plot_vars__.m: New function.
+	* plot/__setup_plot__.m: Use __init_plot_vars__.
+
+2006-10-03  S�ren Hauberg  <soren at hauberg.org>
+
+	* pkg/pkg.m: Avoid calling addpath with no args.
+
+2006-10-03  Bill Denney  <denney at seas.upenn.edu>
+
+ 	* audio/loadaudio.m, control/base/nyquist.m,
+ 	control/system/__zp2ssg2__.m, linear-algebra/cross.m,
+ 	linear-algebra/krylov.m, statistics/base/center.m,
+ 	statistics/base/median.m, statistics/base/std.m,
+ 	statistics/base/var.m, testfun/test.m: 	Use the new find syntax to
+	find first or last element matching a condition.
+
+2006-10-02  Bill Denney  <denney at seas.upenn.edu>
+
+	* strings/deblank.m, strings/upper.m, strings/lower.m,
+	general/__isequal__.m: Minimize looping using cellfun.
+
+2006-10-02  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (copy_files): always create installation directory.
+
+2006-10-02  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* miscellaneous/doc.m: Swap file and directory args to info.
+
+2006-10-01  Arno Onken  <whyly at gmx.net>
+
+	* statistics/distributions/exprnd.m: Fix typo.
+
+2006-09-30  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* polynomial/ppval.m: Use .' instead of '.
+	* polynomial/spline.m: Likewise.  New tests.
+
+2006-09-26  David Bateman  <dbateman at free.fr>
+
+	* __plt3__.m: Using global variables __plot_data__,
+	__plot_data_offset__ and __plot_command__ to store plots and
+	correctly handle multiplots, and hold state. Only accept a single
+	data parameter plus, using, format and with strings. Remove
+	setting of gnuplot parameters.
+	* __make_using_clause__.m: New function extracted from __plt__.m.
+	* __setup_plot__.m: Convert to a function and pass the plotting
+	command to use.
+	* __plt__.m: Change call to __setup_plot__ and __make_using_clause__.
+	* contour.m: Use unwind protect on the parametric state of plot
+	and __plt3__ instead of calling __gnuplot_splot__ directly.
+	* mesh.m: ditto.
+	* plot3.m: Error checking, setting of parametric state and
+	formation of matrix to plot moved from old __plt3__.
+
+2006-09-22  Michael Creel  <michael.creel at uab.es>
+
+	* deprecated/chisquare_pdf.m: Typo in documentation. 
+
+2006-09-22  S�ren Hauberg  <soren at hauberg.org>
+
+	* signal/filter2.m: Correct texinfo doc.
+
+2006-09-22  David Bateman  <dbateman at free.fr>
+
+	* miscellaneous/parseparams.m: Correct texinfo doc.
+	
+2006-09-15  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (prepare_installation): Don't create package
+	installation directory here.
+	(copy_files): Create it here instead, to avoid issues with
+	upgrades. Also install the COPYING file in packinfo.
+
+2006-09-13  John W. Eaton  <jwe at octave.org>
+
+	* general/blkdiag.m: Adjust to new cellfun rules.
+
+2006-08-30  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (install): Disallow bundles of packages. More verbose
+	error message for archive name not matching package name.
+	(installed_packages): Size header of printed results to
+	arguments. Sort the list of installed packages before printing
+	them.
+
+2006-09-11  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* signal/freqz.m: Update tests.
+
+2006-09-11  Ken Kouno  <kouno at mk.ecei.tohoku.ac.jp>
+
+	* signal/freqz.m: Corretly postpad arrays.
+	Don't call fliplr on a column vector.
+
+2006-09-11  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* general/shiftdim.m: Use permute instead of reshape.
+
+2006-09-05  Alexander Barth  <abarth93 at users.sourceforge.net>
+
+	* miscellaneous/parseparams.m: New function.
+
+2006-09-05  Rafael Laboissiere  <rafael at debian.org>
+
+	* miscellaneous/doc.m: Swap order of --file and --directory
+	options for info program invocation.
+
+2006-08-30  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (create_pkgadddel): Resolve variable name-clash from
+	previous change.
+
+2006-08-26  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (install, uninstall, installed_packages): Allow for
+	absence of trailing "/" in OCTAVE_HOME.
+
+2006-08-25  Alexander Barth  <abarth at marine.usf.edu>
+
+	* time/datenum.m: Allow arg to be character string.
+
+2006-08-25  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (install): Verify that package name correponds to the
+	archive name. Treat both PKG_ADD and PKG_DEL and remove them if
+	they are empty. If package directory is empty, remove it to fail
+	gracefully for system specific packages.
+	(extract_pkgadd, create_pkgadd): delete.
+	(extract_pkg, create_pkg): Generalized versions of deleted functions
+	(copy_files): Install both bin/ and doc/ directories, adding the
+	bin/ to the EXEC_PATH when the package is loaded.
+	
+2006-08-24  John W. Eaton  <jwe at octave.org>
+
+	* image/saveimage.m: Use logical indexing instead of
+	indices computed by calling find on the logical index.
+
+2006-08-24  S�ren Hauberg  <soren at hauberg.org>
+
+	* miscellaneous/bincoeff.m, specfun/factorial.m:
+	Use logical indexing instead of indices computed by calling find
+	on the logical index.
+
+	* linear-algebra/krylov.m: Delete unused local var nzidx.
+
+2006-08-23  Quentin Spencer  <qspencer at ieee.org>
+
+	* control/system/tf2zp.m: Simplify gain calculation.
+
+2006-08-23  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt__.m: Insert using clauses for all plots.
+
+2006-08-23  A S Hodel  <hodelas at auburn.edu>
+
+	* control/system/sysscale.m: Call tf and zp with correct number of
+	args.
+
+2006-08-22  David Bateman  <dbateman at free.fr>
+
+	* pkg/pkg.m (extract_pkgadd, create_pkgadd): New functions to 
+	Search inst/*.m and src/*.m files in the package for
+	PKG_ADD directives and append user supplied PKG_ADD.
+	(pkg): Call create_pkgadd after copying files.
+
+2006-08-21  S�ren Hauberg  <soren at hauberg.org>
+
+	* pkg/pkg.m: Handle multiple packages in a single file.
+	Insert directory separator between OCTAVE_HOME and rest of package
+	installation directory.
+
+2006-08-21  John W. Eaton  <jwe at octave.org>
+
+	* general/num2str.m: Early return if arg is empty.
+	From Thomas Treichl <Thomas.Treichl at gmx.net>.
+
+2006-08-21  David Bateman  <dbateman at free.fr>
+
+	* strings/mat2str.m: Compute NC before using.
+
+2006-08-17  John W. Eaton  <jwe at octave.org>
+
+	* audio/wavread.m: Fix calculation of sample count.
+
+2006-08-14  S�ren Hauberg  <soren at hauberg.org>
+
+	* image/imshow.m: New Matlab-compatible version.
+
+2006-08-15  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/is_global.m: Delete.
+
+2006-08-14  John W. Eaton  <jwe at octave.org>
+
+	* pkg/Makefile.in (script_sub_dir): Change from plot to pkg.
+
+2006-08-14  Dmitri A. Sergatskov  <dasergatskov at gmail.com>
+
+	* sparse/spy.m, control/base/bode.m, control/base/__stepimp__.m,
+	signal/freqz_plot.m: Adapt to new automatic_replot definition.
+	
+2006-08-14  S�ren Hauberg  <soren at hauberg.org>
+
+	* pkg/pkg.m: Don't pass function name to print_usage.
+	Use addpath and rmpath instead of manipulating LOADPATH.
+	Handle changes to system function.
+	(rm_rf): New subfunction.  Use it to avoid confirmation dialog for
+	recursive directory removal.
+
+	* strings/bin2dec.m: Ignore spaces in input for compatibility.
+
+	* colormap.m: Change global variable to persistent.
+
+	* rgb2ind.m: Handle single 3-d array as rgb image.
+
+2006-08-14  John W. Eaton  <jwe at octave.org>
+
+	* strings/str2double.m: Fix missing semicolon.
+
+2006-07-27  Jim Peterson  <jpeterson at annapmicro.com>
+
+	* plot/plot3.m: Accept one complex or one real and one complex
+	argument and plot real and imaginary components for y and z.
+
+2006-07-27  John W. Eaton  <jwe at octave.org>
+
+	* testfun/test.m: Call fflush after each block of calls to
+	fprintf, fputs, or fdisp.
+
+2006-07-26  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/mex.m: New function.
+
+2006-07-22  John W. Eaton  <jwe at octave.org>
+
+	* special-matrix/hadamard.m: Coerce bool matrix to double.
+
+2006-07-07  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/orderfields.m: New file.
+
+2006-06-30  John W. Eaton  <jwe at octave.org>
+
+	* time/datevec.m: Make another attempt to account for precision of
+	datenum format.
+
+2006-06-29  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dump_prefs.m: Remove obsolete symbols from the list.
+	Use feval instead of "type -q" to get values now that all the
+	symbols are functions.
+
+2006-06-16  John W. Eaton  <jwe at octave.org>
+
+	* time/datevec.m: Avoid computing log of non-positive values.
+
+2006-06-14  John W. Eaton  <jwe at octave.org>
+
+	* time/datevec.m: Attempt to account for precision of datenum format.
+
+2006-06-01  Quentin H. Spencer  <qspencer at ieee.org>
+
+	* audio/wavread.m: Fix file range error and add read support for
+	24-bit WAV files.
+
+2006-06-01  David Bateman  <dbateman at free.fr>
+
+	* general/interpft.m, general/quadl.m, general/polyarea.m,
+	general/interp1.m, general/gradient.m, general/interp2.m,
+	general/bicubic.m, miscellaneous/inputname.m, plot/__plt3__.m,
+	plot/ndgrid.m, plot/plot3.m, polynomial/pchip.m, sparse/pcg.m,
+	sparse/pcr.m, strings/mat2str.m: New files from Octave Forge.
+
+2006-05-31  Bill Denney  <bill at givebillmoney.com>
+
+ 	* miscellaneous/fileparts.m, miscellaneous/fullfile.m: Add seealso.
+ 	* miscellaneous/texas_lotto.m: Fix warning message.
+
+2006-05-26  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/doc.m: Also handle nargin == 0.
+
+2006-05-23  John W. Eaton  <jwe at octave.org>
+
+	* plot/mesh.m: Use __gnupot_raw__ except where __gnuplot_set__ is
+	really needed.
+
+2006-05-22  John W. Eaton  <jwe at octave.org>
+
+	* general/lookup.m: New file from Octave Forge.
+
+2006-05-22  David Bateman  <dbateman at free.fr>
+
+	* general/nthroot.m, linear-algebra/rref.m, specfun/isprime.m,
+	specfun/primes.m, specfun/factor.m, specfun/nchoosek.m,
+	specfun/legendre.m, specfun/perms.m, special-matrix/rosser.m,
+	special-matrix/wilkinson.m, special-matrix/pascal.m,
+	special-matrix/magic.m, special-matrix/hadamard.m,
+	strings/strtok.m: New files from Octave Forge.
+
+2006-05-19  David Bateman  <dbateman at free.fr>
+
+	* polynomial/unmkpp.m, polynomial/mkpp.m, polynomial/spline.m,
+	polynomial/ppval.m, set/setxor.m: New files from Octave Forge.
+
+2006-05-17  John W. Eaton  <jwe at octave.org>
+
+	* set/intersection.m: Delete
+	* deprecated/intersection.m: New file.
+
+2006-05-17  David Bateman  <dbateman at free.fr>
+
+	* general/cplxpair.m, general/trapz.m, general/cumtrapz.m,
+	general/isdir.m, miscellaneous/dos.m, miscellaneous/getfield.m,
+	miscellaneous/setfield.m, plot/fplot.m, set/intersect.m,
+	signal/ifftshift.m, signal/filter2.m, specfun/betaln.m,
+	specfun/factorial.m, strings/strvcat.m: New files from Octave
+	Forge.
+
+2006-05-11  John W. Eaton  <jwe at octave.org>
+
+	* path/path.m: Delete (now a built-in function).
+
+	* pkg/Makefile.in: New file.
+	* configure.in (AC_CONFIG_FILES): Add pkg/Makefile to the list.
+	* Makefile.in (SUBDIRS): Add pkg to the list.
+
+2006-05-10  John W. Eaton  <jwe at octave.org>
+
+	* tar.m, untar.m, unzip.m: Adapt to Octave coding style.
+	* tar.m, untar.m: Only tar; don't compress or uncompress.
+
+2006-05-10  S�ren Hauberg  <hauberg at gmail.com>
+
+	* tar.m, untar.m, unzip.m: New files.
+
+2006-05-10  John W. Eaton  <jwe at octave.org>
+
+	* path/addpath.m, path/rmpath.m: Improve compatibility.
+	* path/setpath.m: Delete.
+
+	* pkg/pkg.m: New file.
+
+2006-05-09  Keith Goodman  <kwgoodman at gmail.com>
+
+	* plot/plot.m: Doc string fix.
+
+2006-05-09  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* testfun/speeed.m: Use new interface to unique and assert.
+	Improve documentation.  Approximate time complexity from log-log
+	plot.  Return time complexity and raw times if requested.  The
+	mean ratio is no longer returned.  Provide complete control over
+	which n are computed.
+
+2006-05-09  John W. Eaton  <jwe at octave.org>
+
+	* path/path.m: Move here from miscellaneous.
+	Adapt to new LOADPATH definition.
+
+2006-05-03  David Bateman  <dbateman at free.fr>
+
+	* path/rmpath.m, path/addpath.m, miscellaneous/path.m: Replace all
+	explicit uses of a path seperation character with pathsep().
+
+2006-05-03  Bob Weigel  <rweigel at gmu.edu>
+
+	* set/setdiff.m: New arg, byrows.  New tests.
+
+2006-04-29  John W. Eaton  <jwe at octave.org>
+
+	* startup/main-rcfile: Disable some warnings.
+
+2006-04-14  Bill Denney  <denney at seas.upenn.edu>
+
+ 	* strings/strcmpi.m: Return false instead of error if args are not
+	char or cellstr.
+
+2006-04-10  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dir.m: Ensure that returned structure array is
+	Nx1, not 1xN.
+
+2006-04-06  Olli Saarela  <olli.saarela at kcl.fi>
+
+	* plot/hist.m: Ignore NaN in inputs.
+
+2006-04-06  Keith Goodman  <kwgoodman at gmail.com>
+
+	* miscellaneous/mkoctfile.m: Doc string fix.
+
+2006-04-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt2__.m: Return data = [] and fmtstr = "" if x1 and x2
+	are both empty.
+	* plot/__plt__.m: Ignore empty data and format strings returned
+	from __plt1__ or __plt2__.
+
+2006-04-04  Bob Weigel  <rweigel at gmu.edu>
+
+	* set/unique.m: Properly handle single column input when
+	"rows" is specified.
+
+2006-04-04  John W. Eaton  <jwe at octave.org>
+
+	* path/setpath.m: New file.
+	* path/savepath.m: Use setpath to set path instead of assigning
+	directly to LOADPATH.
+
+	* path/Makefile.in, path/addpath.m, path/rmpath.m, path/savepath.m:
+	New files, adapted from Octave Forge by Keith Goodman
+	<kwgoodman at gmail.com>.
+	* path: New directory.
+	* Makefile.in (SUBDIRS): Add it to the list.
+	* configure.in (AC_CONFIG_FILES): Include path/Makefile here.
+
+2006-04-02  David Bateman  <dbateman at free.fr>
+
+	* general/tril.m, general.triu.m:
+	Use resize (resize (x, 0), nr, nc) rather than zeros (nr, nc)
+	to allow user types to work correctly.
+	* special-matrix/hankel.m, special-matrix/toeplitz.m: Ditto.
+
+2006-04-03  David Bateman  <dbateman at free.fr>
+
+	* plot/grid.m: Cache the state of the grid to allow toggling.
+	Accept keyword "minor" for minor grid.
+
+2006-03-28  John W. Eaton  <jwe at octave.org>
+
+	* general/isscalar.m: Only require that all dimensions are 1 for
+	compatiblity.
+
+2006-03-28  Bill Denney  <bill at givebillmoney.com>
+
+	* general/isvector.m: Allow non-numeric objects to be vectors for
+	compatibility.
+
+2006-03-28  Keith Goodman  <kwgoodman at gmail.com>
+
+	* plot/__errplot__.m: Doc string fix.
+
+	* miscellaneous/doc.m: Mark as command.
+
+	* general/isequal.m, general/__isequal__.m, general/cell2mat.m,
+	general/isequalwithequalnans.m, general/blkdiag.m,
+	strings/strfind.m, miscellaneous/doc.m: Update FSF address.
+	
+2006-03-27  Don Bindner  <dbindner at truman.edu>
+
+	* plot/meshgrid.m: If nargout == 3 and vectors are supplied,
+	return 3d matrices.
+
+2006-03-27  Keith Goodman  <kwgoodman at gmail.com>
+
+	* time/toc.m: Don't print "Elapsed time..." if tic has not been set.
+
+2006-03-22  John W. Eaton  <jwe at octave.org>
+
+	* plot/print.m: Don't replot after popping terminal setting.
+
+2006-03-20  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/mkoctfile.m: Use version-specific name of
+	mkoctfile.  Use fullfile to construct file name.
+
+2006-03-20  Keith Goodman  <kwgoodman at gmail.com>
+
+	* miscellaneous/mkoctfile.m: Make it possible to call mkoctfile
+	shell script from Octave prompt.
+
+2006-03-17  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/weibcdf.m, deprecated/weibinv.m,
+	deprecated/weibpdf.m, deprecated/weibrnd.m: New functions.
+
+	* deprecated/weibull_cdf.m, deprecated/weibull_inv.m,
+	deprecated/weibull_pdf.m, deprecated/weibull_rnd.m:
+	Call new wbl functions to do the real work.
+	Swap args and provide default values as necessary to preserve
+	compatibility with old version of Octave.
+
+	* statistics/distributions/wblcdf.m: Rename from weibcdf.m.
+	statistics/distributions/wblinv.m: Rename from weibinv.m.
+	statistics/distributions/wblpdf.m: Rename from weibpdf.m.
+	statistics/distributions/wblrnd.m: Rename from weibrnd.m.
+	Swap scale and shape args for compatibility.
+
+	* deprecated/lognormal_cdf.m, deprecated/lognormal_inv.m,
+	deprecated/lognormal_pdf.m, deprecated/lognormal_rnd.m:
+	Preserve compatibility with old versions of Octave given new
+	definitions of logncdf, logninv, lognpdf, and lognrnd.
+
+	* statistics/distributions/logncdf.m,
+	statistics/distributions/logninv.m,
+	statistics/distributions/lognpdf.m,
+	statistics/distributions/lognrnd.m: Compatibility fixes.
+	From Ben Barrowes  <barrowes at alum.mit.edu>
+
+	* deprecated/hypergeometric_rnd.m: Update interface to match
+	current 2.1.x version.
+
+	* deprecated/t_rnd.m: Call trnd, not t_rnd.
+
+	* miscellaneous/dir.m: Use readdir instead of glob.
+	Special case for "." to avoid globbing.  Use list_in_columns.
+	Eliminate unused variables len and finfo.
+
+2006-03-16  Bill Denney  <bill at givebillmoney.com>
+
+	* miscellaneous/dir.m: Improve compatibility.
+
+2006-03-15  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* time/calendar.m, time/datestr.m, time/datevec.m, time/eomday.m,
+	time/now.m, time/weekday.m: New functions from Octave Forge.
+
+2006-03-16  John W. Eaton  <jwe at octave.org>
+
+	* control/base/bode_bounds.m: Check for iip and iiz empty instead
+	of looking at sum of max dimensions.
+
+2006-03-16  David Bateman  <dbateman at free.fr>
+
+	* testfun/test.m: Clear last warning before warning test to avoid
+	issues with previously set warnings.
+	* build_sparse_test.sh: Tests for multiple RHS for rectanguar
+	sparse matrices. Force matrix type from spqr solution to be
+	singular to force QR solvers to be used for assert.
+
+2006-03-16  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* strings/strfind.m: New file.
+
+2006-03-16  John W. Eaton  <jwe at octave.org>
+
+	* general/rows.m, general/columns.m: Delete.
+
+2006-03-15  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* strings/strcmpi.m: Simplify.
+	* strings/strncmpi.m: Import from octave-forge, simplify.
+	* strings/strtrunc.m: New file.
+
+	* strings/lower.m, strings/upper.m: Handle cellstr arguments.
+
+2006-03-15  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/doc.m: New file.
+	From S�ren Hauberg <soren at hauberg.org>.
+
+2006-03-15  Keith Goodman  <kwgoodman at gmail.com>
+
+	* miscellaneous/mkoctfile.m: New file.
+
+2006-03-15  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/residue.m: Use & instead of && to generate arg for find.
+
+2006-03-14  Keith Goodman  <kwgoodman at gmail.com>
+
+	* strings/bin2dec.m: Doc fix.
+
+2006-03-10  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* time/etime.m: Use datenum to support times spanning year boundaries.
+	* time/datenum.m: New function to compute day number from time.
+
+2006-03-09  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/unix.m, plot/print.m:
+	Swap order of outputs from system.
+
+2006-03-06  Keith Goodman  <kwgoodman at gmail.com>
+
+	* audio/lin2mu.m, audio/loadaudio.m, audio/mu2lin.m,
+	audio/playaudio.m, audio/record.m, audio/saveaudio.m,
+	audio/wavread.m, audio/wavwrite.m, control/base/DEMOcontrol.m,
+	control/base/__stepimp__.m, control/base/are.m,
+	control/base/controldemo.m, control/base/damp.m,
+	control/base/dare.m, control/base/impulse.m, control/base/lqg.m,
+	control/base/step.m, control/system/abcddim.m,
+	control/system/is_abcd.m, control/system/is_controllable.m,
+	control/system/is_detectable.m, control/system/is_observable.m,
+	control/system/is_stabilizable.m, control/system/is_stable.m,
+	control/system/jet707.m, control/system/sys2fir.m,
+	control/system/sysdimensions.m, control/system/sysupdate.m,
+	control/system/tfout.m, control/system/ugain.m,
+	control/system/zpout.m, elfun/lcm.m, finance/irr.m,
+	finance/nper.m, finance/npv.m, finance/pmt.m, finance/pv.m,
+	finance/rate.m, general/__isequal__.m, general/bitcmp.m,
+	general/bitget.m, general/bitset.m, general/blkdiag.m,
+	general/cart2pol.m, general/cart2sph.m, general/cell2mat.m,
+	general/circshift.m, general/columns.m, general/flipdim.m,
+	general/fliplr.m, general/flipud.m, general/ind2sub.m,
+	general/int2str.m, general/isdefinite.m, general/isequal.m,
+	general/isequalwithequalnans.m, general/isscalar.m,
+	general/issquare.m, general/issymmetric.m, general/isvector.m,
+	general/logspace.m, general/mod.m, general/nextpow2.m,
+	general/num2str.m, general/perror.m, general/pol2cart.m,
+	general/rem.m, general/rot90.m, general/rotdim.m, general/rows.m,
+	general/shiftdim.m, general/sph2cart.m, general/sub2ind.m,
+	general/tril.m, image/hsv2rgb.m, image/image.m, image/imagesc.m,
+	image/imshow.m, image/ind2gray.m, image/ind2rgb.m,
+	image/loadimage.m, image/rgb2hsv.m, image/rgb2ind.m,
+	image/saveimage.m, io/beep.m, linear-algebra/cond.m,
+	linear-algebra/norm.m, miscellaneous/comma.m, miscellaneous/dir.m,
+	miscellaneous/license.m, miscellaneous/menu.m,
+	miscellaneous/semicolon.m, miscellaneous/texas_lotto.m,
+	miscellaneous/unix.m, miscellaneous/ver.m, optimization/sqp.m,
+	plot/__errcomm__.m, plot/__errplot__.m, plot/__pltopt1__.m,
+	plot/__pltopt__.m, plot/bar.m, plot/contour.m, plot/errorbar.m,
+	plot/grid.m, plot/hist.m, plot/loglog.m, plot/loglogerr.m,
+	plot/mesh.m, plot/meshgrid.m, plot/plot.m, plot/polar.m,
+	plot/semilogx.m, plot/semilogxerr.m, plot/semilogy.m,
+	plot/semilogyerr.m, plot/shg.m, plot/stairs.m, plot/title.m,
+	plot/xlabel.m, polynomial/compan.m, polynomial/conv.m,
+	polynomial/deconv.m, polynomial/polyderiv.m, polynomial/polygcd.m,
+	polynomial/polyinteg.m, polynomial/polyout.m,
+	polynomial/polyreduce.m, polynomial/polyval.m,
+	polynomial/polyvalm.m, polynomial/residue.m, set/complement.m,
+	set/create_set.m, set/intersection.m, set/ismember.m,
+	set/setdiff.m, set/union.m, set/unique.m, sparse/etreeplot.m,
+	sparse/gplot.m, sparse/spalloc.m, sparse/sphcat.m,
+	sparse/sprand.m, sparse/sprandn.m, sparse/sprandsym.m,
+	sparse/spvcat.m, sparse/treeplot.m, specfun/erfinv.m,
+	specfun/log2.m, specfun/pow2.m, special-matrix/hankel.m,
+	special-matrix/hilb.m, special-matrix/invhilb.m,
+	special-matrix/sylvester_matrix.m, special-matrix/toeplitz.m,
+	special-matrix/vander.m, statistics/base/median.m,
+	statistics/base/std.m, statistics/distributions/gamcdf.m,
+	statistics/distributions/gaminv.m,
+	statistics/distributions/gampdf.m,
+	statistics/distributions/gamrnd.m, strings/base2dec.m,
+	strings/bin2dec.m, strings/dec2base.m, strings/dec2bin.m,
+	strings/dec2hex.m, strings/hex2dec.m, strings/isletter.m,
+	strings/lower.m, strings/upper.m, testfun/assert.m,
+	testfun/demo.m, testfun/example.m, testfun/test.m, time/etime.m:
+	Move @seealso inside @defXXX macro.  Remove "and" from @seealso.
+
+2006-02-27  John W. Eaton  <jwe at octave.org>
+
+	* time/tic.m: Move here from miscellaneous/tic.m.
+	* time/toc.m: Move here from miscellaneous/toc.m.
+
+2006-02-26  Keith Goodman  <kwgoodman at gmail.com>
+ 
+ 	* miscellaneous/toc.m: Display "Elapsed time is X seconds" if user
+	does not assign output of toc to a variable.
+
+2006-02-16  Bill Denney  <denney at seas.upenn.edu>
+
+ 	* axis.m: Catch limits that are the same and return an error.
+
+2006-02-15  Dmitri A. Sergatskov  <dasergatskov at gmail.com>
+
+	* plot/print.m: Accept emf device option to support Enhanced
+	Metafile format.
+
+2006-02-15  A S Hodel  <hodelas at auburn.edu>
+
+	* control/base/lqe.m: Doc fix.
+
+2006-02-15  Keith Goodman  <kwgoodman at gmail.com>
+ 
+ 	* statistics/distributions/gamcdf.m: Doc fix.
+ 	* statistics/distributions/gaminv.m: Doc fix.
+ 	* statistics/distributions/gampdf.m: Doc fix.
+ 	* statistics/distributions/gamrnd.m: Doc fix.
+
+2006-02-09  David Bateman  <dbateman at free.fr>
+
+	* general/triu.m: Minimum change to allow sparse matrix. More needed
+	for arbitrary user type.
+	* general/tril.m: ditto.
+	* sparse/sprand.m: Doc fix.
+	* sparse/sprandn.m: Ditto.
+	* sparse/sprandsym.m: New function.
+	* audio/setaudio.m, general/cart2pol.m, general/cart2sph.m,
+	general/pol2cart.m, general/sph2cart.m, signal/freqz_plot.m:
+	Update for syntax error for latest texinfo.tex file.
+
+2006-02-02  John W. Eaton  <jwe at octave.org>
+
+	* plot/grid.m: Append ";\n" to "set grid" command.
+
+2006-02-02  A S Hodel  <hodelas at auburn.edu>
+
+	* control/base/rlocus.m: Don't atttempt to plot rlzer if it is empty.
+
+2006-01-13  John W. Eaton  <jwe at octave.org>
+
+	* audio/Makefile.in, control/base/Makefile.in,
+	control/hinf/Makefile.in, control/obsolete/Makefile.in,
+	control/system/Makefile.in, control/util/Makefile.in,
+	deprecated/Makefile.in, elfun/Makefile.in, finance/Makefile.in,
+	general/Makefile.in, image/Makefile.in, io/Makefile.in,
+	linear-algebra/Makefile.in, miscellaneous/Makefile.in,
+	optimization/Makefile.in, plot/Makefile.in,
+	polynomial/Makefile.in, quaternion/Makefile.in, set/Makefile.in,
+	signal/Makefile.in, sparse/Makefile.in, specfun/Makefile.in,
+	special-matrix/Makefile.in, startup/Makefile.in,
+	statistics/base/Makefile.in, statistics/distributions/Makefile.in,
+	statistics/models/Makefile.in, statistics/tests/Makefile.in,
+	strings/Makefile.in, time/Makefile.in, testfun/Makefile.in:
+	(all): Depend on PKG_ADD.
+	(PKG_ADD): New target.
+
+2006-01-13  Bill Denney  <bill at givebillmoney.com>
+
+ 	* miscellaneous/dir.m: Add @seealso{} to docstring.
+
+2006-01-13  John W. Eaton  <jwe at octave.org>
+
+	* time/etime.m: Move here from miscellaneous/etime.m.
+	* time/is_leap_year.m: Move here from miscellaneous/is_leap_year.m.
+
+2006-01-13  Bill Denney  <bill at givebillmoney.com>
+
+	 * miscellaneous/dir.m: Use filesep instead of "/" where needed.
+	 * miscellaneous/fullfile.m: Likewise.
+
+2006-01-12  David Bateman  <dbateman at free.fr>
+
+	* general/blkdiag.m: Compatible behavior for empty matrices 
+	* statistics/base/unidrnd.m: Documentation buglet.
+
+2005-12-14  David Bateman  <dbateman at free.fr>
+
+	* testfun/assert.m, testfun/fail.m, testfun/test.m, testfun/demo.m,
+	testfun/speed.m, testfun/example.m, Makefile.in: New files.
+
+	* Makefile.in (SUBDIRS): Include testfun.
+	* configure.in (AC_CONFIG_FILES): Include testfun/Makefile.
+
+	* miscellaneous/dir.m: Transpose sub-assignment for cleanness.
+
+	* general/__isequal__.m: Remove reference to getfield.
+
+	* plot/hist.m: Update test code for row/column discrepencies.
+	* signal/freqz.m: Alter output row/column for matlab compatibility.
+	Update the test code for this.
+	* sparse/spstats.m: Fix small bug in the dimension of output.
+
+2005-12-13  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* cell/cell2mat.m: New file, from octave-forge.
+
+2005-12-13  Ivana Varekova  <varekova at redhat.com>
+
+	* sparse/treeplot.m, sparse/etreeplot.m, sparse/gplot.m:
+	New graph theory functions.
+
+2005-12-13  John W. Eaton  <jwe at octave.org>
+
+	* general/blkdiag.m: Use "isempty" instead of @isempty.
+
+	* control/system/ss.m: Doc fix.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-12-12  Michael Zeising  <michael at michaels-website.de>
+
+	* audio/wavread.m, audio/wavwrite.m: 
+	Correct scaling for 8-bit linear pcm samples.
+	Improve scaling for all other linear pcm resolutions.
+
+2005-12-07  John W. Eaton  <jwe at octave.org>
+
+	* statistics/base/moment.m: Don't save and restore warn_str_to_num.
+
+	* sparse/spdiags.m: Don't save and restore warn_fortran_indexing.
+	* strings/strjust.m: Likewise.
+
+	* general/shift.m: Don't save and restore warn_empty_list_elements.
+	* signal/arma_rnd.m: Likewise.
+	* strings/strcat.m: Likewise.
+	* control/base/__freqresp__.m: Likewise.
+	* control/base/place.m: Likewise.
+	* control/base/pzmap.m: Likewise.
+	* control/base/pzmap.m: Likewise.
+	* control/system/sysappend.m: Likewise.
+	* control/system/syscont.m: Likewise.
+	* control/system/sysdisc.m: Likewise.
+	* control/system/sysgroup.m: Likewise.
+	* control/system/tfout.m: Likewise.
+	* control/system/zpout.m: Likewise.
+	* control/util/__outlist__.m: Likewise.
+
+2005-12-06  John W. Eaton  <jwe at octave.org>
+
+	* audio/wavread.m, audio/wavwrite.m: Adapt to Octave coding style.
+	Avoid for loop in interleave/deinterleave steps.
+
+2005-12-06  Michael Zeising  <michael at michaels-website.de>
+
+	* audio/wavread.m, audio/wavwrite.m: New files.
+
+2005-12-06  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dir.m: Return Nx1 instead of 1xN struct array.
+
+2005-12-05  John W. Eaton  <jwe at octave.org>
+
+	* plot/axis.m: Add "## PKG_ADD: mark_as_command axis" line.
+
+2005-12-02  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/fileattrib.m: New function.
+
+2005-12-01  John W. Eaton  <jwe at octave.org>
+
+	* general/columns.m: Use size (x, 2) instead of [nr, nc] = size (x).
+	* general/rows.m: Use size (x, 1) instead of [nr, nc] = size (x).
+	From William Poetra Yoga Hadisoeseno <williampoetra at yahoo.com>.
+
+2005-11-30  John W. Eaton  <jwe at octave.org>
+
+	* linear-algebra/krylov.m: Format doc string.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-11-23  William Poetra Yoga Hadisoeseno  <williampoetra at yahoo.com>
+
+	* general/blkdiag.m: Import from octave-forge.
+	Ignore empty matrices in the input.  Add tests.
+
+	* general/isequal.m, general/isequalwithequalnans.m:
+	New wrapper scripts for general/__isequal__.m.
+	* general/__isequal__.m: Rename from general/isequal.m.
+	New arg, nans_compare_equal.
+
+2005-11-29  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/ver.m: Use new uname built-in function instead of
+	calling system.  Only append octave_forge_string if
+	OCTAVE_FORGE_VERSION exists.  Use puts instead of disp.
+	Call license instead of hard-coding license info here.
+
+	* miscellaneous/license.m: Use persistent instead of global for
+	__octave_licenses__.  Use puts instead of disp.
+	Use getuid and getpwuid instead of calling unix ("id -un").
+	If nargout = 1, return license info instead of printing usage message.
+
+2005-11-29  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* miscellaneous/ver.m: New file.
+	* miscellaneous/license.m: New file.
+
+2005-11-22  John W. Eaton  <jwe at octave.org>
+
+	* plot/axis.m: Use %.16g instead of just %g to format ranges for
+	gnuplot set command.
+
+2005-11-15  John W. Eaton  <jwe at octave.org>
+
+	* general/shiftdim.m: Doc fix.
+
+2005-11-07  Keith Goodman  <kwgoodman at gmail.com>
+
+	* set/unique.m: Doc string fix.
+
+2005-11-01  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (distclean, maintainer-clean):
+	Also remove autom4te.cache directory.
+	From Quentin Spencer  <qspencer at ieee.org>.
+
+2005-10-28  John W. Eaton  <jwe at octave.org>
+
+	* general/shiftdim.m: Compatibility fix for row vectors.
+	Correct check for non-scalar non-integer shift.  For positive
+	N, shift is remainder of N and number of dims.  Always return NS.
+	Simplify.
+
+2005-10-18  Keith Goodman  <kwgoodman at gmail.com>
+
+	* general/randperm.m: Improve compatibility by allowing input
+	value of zero.
+
+2005-10-13  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt__.m, plot/__errplot__.m, plot/replot.m:
+	If in multiplot mode, clear plot before issuing new plot command.
+
+	* plot/__setup_plot__.m: New function.
+	* plot/__plt__.m, plot__errplot__.m: Use it.
+	Handle multiplot data and offsets here.
+
+	* plot/__plot_globals__.m: Also keep track of multiplot options.
+	Move initialization to __setup_plot__.m.
+
+	* plot/subplot.m: Multiplot globals now in __plot_globals__.m.
+	Don't reset gnuplot_command_replot.
+
+	* plot/replot.m: Handle multiplot data and offsets here.
+	* plot__axis_label__.m, plot/axis.m, plot/grid.m,
+	plot/plot_border.m, plot/plot.m, plot/plot_title.m,
+	plot/top_title.m: Call replot, not __gnuplot_replot__.
+
+2005-10-12  John W. Eaton  <jwe at octave.org>
+
+	* plot/figure.m: Handle __current_figure__, not gnuplot details.
+
+2005-10-04  Rafael Laboissiere  <rafael at debian.org>
+
+	* binoinv.m, chi2pdf.m, frnd.m, poissinv.m, tinv.m, trnd.m,
+	weibrnd.m: Removed calls and references to deprecated _pdf and
+	_inv functions.
+	* chi2pdf.m: Fixed typos in the documentation.
+
+2005-09-28  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/single.m: New function.
+
+	* statistics/base/unidrnd.m: New function.
+
+2005-09-27  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/dir.m: Filename never includes directory part.
+
+2005-09-22  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/residue.m: Use logical indexing instead of find..
+
+2005-09-22  Julius Smith  <jos at ccrma.stanford.edu>
+
+	* polynomial/residue.m: Avoid division by zero for pure imaginary
+	and zero poles.
+
+2005-09-22  Bill Denney  <denney at seas.upenn.edu>
+
+	* strings/deblank.m: Handle cell arrays.
+	* strings/split.m: New argument, N, to limit number of splits.
+
+2005-09-22  Miroslaw Kwasniak  <mirek at zind.ikem.pwr.wroc.pl>
+
+	* plot/__pltopt1__.m: Handle plot colors "w" and "k" separately.
+
+2005-09-20  "Orestes Mas"  <orestes at tsc.upc.edu>
+
+	* control/base/rlocus.m: Doc fix.
+
+2005-09-20  John W. Eaton  <jwe at octave.org>
+
+	* general/isvector.m: Improve compatibility.
+
+	* general/postpad.m: Allow first argument to be a scalar.
+	Allow padding to extend dimensionality.
+	* general/prepad.m: Likewise.
+
+2005-09-14  Daniel  <durbano at shbano.com>
+
+	* statistics/tests/bartlett_test.m, linear-algebra/cross.m,
+	statistics/distributions/discrete_cdf.m, general/fliplr.m,
+	/control/base/dgram.m: Doc string fixes.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-09-12  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* saveimage.m: Do not ignore most significant bit when writing
+	black and white images to file.
+
+2005-09-07  Bill Denney  <denney at seas.upenn.edu>
+
+	* audio/playaudio.m, control/base/__bodquist__.m,
+	control/base/lqg.m, control/obsolete/dezero.m,
+	control/system/__syschnamesl__.m, control/system/__sysconcat__.m,
+	control/system/c2d.m, control/system/cellidx.m,
+	control/system/d2c.m, control/system/dmr2d.m,
+	control/system/is_signal_list.m, control/system/listidx.m,
+	control/system/ss.m, control/system/sysappend.m,
+	control/system/sysconnect.m, control/system/sysdup.m,
+	control/system/sysgetsignals.m, control/system/sysidx.m,
+	control/system/sysprune.m, control/system/syssetsignals.m,
+	control/system/tfout.m, control/system/zpout.m,
+	control/util/prompt.m, control/util/sortcom.m,
+	control/util/strappend.m, finance/fv.m, finance/nper.m,
+	finance/pmt.m, finance/pv.m, finance/rate.m, general/diff.m,
+	general/num2str.m, general/repmat.m, general/sortrows.m,
+	general/strerror.m, image/colormap.m, image/imshow.m,
+	image/loadimage.m, image/saveimage.m, linear-algebra/norm.m,
+	miscellaneous/fileparts.m, miscellaneous/popen2.m,
+	plot/__axis_label__.m, plot/__errcomm__.m, plot/__plt1__.m,
+	plot/__plt2__.m, plot/__plt__.m, plot/__pltopt1__.m,
+	plot/__pltopt__.m, plot/axis.m, plot/bottom_title.m, plot/close.m,
+	plot/grid.m, plot/hist.m, plot/plot_border.m, plot/polar.m,
+	plot/print.m, plot/title.m, plot/top_title.m,
+	polynomial/polyout.m, set/unique.m, signal/freqz.m, signal/stft.m,
+	statistics/base/mean.m, statistics/base/moment.m,
+	statistics/tests/cor_test.m,
+	statistics/tests/kolmogorov_smirnov_test.m,
+	statistics/tests/kolmogorov_smirnov_test_2.m,
+	statistics/tests/prop_test_2.m, statistics/tests/sign_test.m,
+	statistics/tests/t_test.m, statistics/tests/t_test_2.m,
+	statistics/tests/t_test_regression.m, statistics/tests/u_test.m,
+	statistics/tests/var_test.m, statistics/tests/welch_test.m,
+	statistics/tests/wilcoxon_test.m, statistics/tests/z_test.m,
+	statistics/tests/z_test_2.m, strings/base2dec.m, strings/blanks.m,
+	strings/deblank.m, strings/dec2base.m, strings/index.m,
+	strings/rindex.m, strings/split.m, strings/str2mat.m,
+	strings/str2num.m, strings/strcat.m, strings/strcmpi.m,
+	strings/strncmp.m, strings/strrep.m, strings/substr.m:
+	Avoid deprecated functions.  Use ischar instead of isstr.  Use
+	isvector instead of is_vector.  Use isstruct instead of
+	is_struct.  Use char instead of setstr.
+
+2005-08-31  Daniel  <durbano at shbano.com>
+
+	* special-matrix/invhilb.m, statistics/base/iqr.m,
+	control/system/is_controllable.m, set/ismember.m: Doc fixes.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-08-29  Bill Denney  <denney at seas.upenn.edu>
+
+	* image/saveimage.m: Open output file in binary mode.
+
+	* miscellaneous/bug_report.m: Open prefs file in text mode.
+
+2005-08-16  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/computer.m: Handle optional maxsize and endian
+	outputs.
+
+2005-08-15  John W. Eaton  <jwe at octave.org>
+
+	* strings/strcat.m: Allow single argument.
+
+2005-07-18  John W. Eaton  <jwe at octave.org>
+
+	* strings/strcmp.m: Delete.
+
+2005-07-13  John W. Eaton  <jwe at octave.org>
+
+	* deprecated/hypergeometric_rnd.m: Preserve compatibility with old
+	versions of Octave.
+
+2005-07-13  Ben Barrowes  <barrowes at alum.mit.edu>
+
+	* statistics/distributions/betacdf.m: Rename from beta_cdf.m.
+	* statistics/distributions/betainv.m: Rename from beta_inv.m.
+	* statistics/distributions/betapdf.m: Rename from beta_pdf.m.
+	* statistics/distributions/betarnd.m: Rename from beta_rnd.m.
+	* statistics/distributions/binocdf.m: Rename from binomial_cdf.m.
+	* statistics/distributions/binoinv.m: Rename from binomial_inv.m.
+	* statistics/distributions/binopdf.m: Rename from binomial_pdf.m.
+	* statistics/distributions/binornd.m: Rename from binomial_rnd.m.
+	* statistics/distributions/chi2cdf.m: Rename from chisquare_cdf.m.
+	* statistics/distributions/chi2inv.m: Rename from chisquare_inv.m.
+	* statistics/distributions/chi2pdf.m: Rename from chisquare_pdf.m.
+	* statistics/distributions/chi2rnd.m: Rename from chisquare_rnd.m.
+	* statistics/distributions/expcdf.m: Rename from exponential_cdf.m.
+	* statistics/distributions/expinv.m: Rename from exponential_inv.m.
+	* statistics/distributions/exppdf.m: Rename from exponential_pdf.m.
+	* statistics/distributions/exprnd.m: Rename from exponential_rnd.m.
+	* statistics/distributions/fcdf.m: Rename from f_cdf.m.
+	* statistics/distributions/finv.m: Rename from f_inv.m.
+	* statistics/distributions/fpdf.m: Rename from f_pdf.m.
+	* statistics/distributions/frnd.m: Rename from f_rnd.m.
+	* statistics/distributions/gamcdf.m: Rename from gamma_cdf.m.
+	* statistics/distributions/gaminv.m: Rename from gamma_inv.m.
+	* statistics/distributions/gampdf.m: Rename from gamma_pdf.m.
+	* statistics/distributions/gamrnd.m: Rename from gamma_rnd.m.
+	* statistics/distributions/geocdf.m: Rename from geometric_cdf.m.
+	* statistics/distributions/geoinv.m: Rename from geometric_inv.m.
+	* statistics/distributions/geopdf.m: Rename from geometric_pdf.m.
+	* statistics/distributions/geornd.m: Rename from geometric_rnd.m.
+	* statistics/distributions/hygecdf.m: Rename from hypergeometric_cdf.m.
+	* statistics/distributions/hygeinv.m: Rename from hypergeometric_inv.m.
+	* statistics/distributions/hygepdf.m: Rename from hypergeometric_pdf.m.
+	* statistics/distributions/hygernd.m: Rename from hypergeometric_rnd.m.
+	* statistics/distributions/logncdf.m: Rename from lognormal_cdf.m.
+	* statistics/distributions/logninv.m: Rename from lognormal_inv.m.
+	* statistics/distributions/lognpdf.m: Rename from lognormal_pdf.m.
+	* statistics/distributions/lognrnd.m: Rename from lognormal_rnd.m.
+	* statistics/distributions/normcdf.m: Rename from normal_cdf.m.
+	* statistics/distributions/norminv.m: Rename from normal_inv.m.
+	* statistics/distributions/normpdf.m: Rename from normal_pdf.m.
+	* statistics/distributions/normrnd.m: Rename from normal_rnd.m.
+	* statistics/distributions/poisscdf.m: Rename from poisson_cdf.m.
+	* statistics/distributions/poissinv.m: Rename from poisson_inv.m.
+	* statistics/distributions/poisspdf.m: Rename from poisson_pdf.m.
+	* statistics/distributions/poissrnd.m: Rename from poisson_rnd.m.
+	* statistics/distributions/tcdf.m: Rename from t_cdf.m.
+	* statistics/distributions/tinv.m: Rename from t_inv.m.
+	* statistics/distributions/tpdf.m: Rename from t_pdf.m.
+	* statistics/distributions/trnd.m: Rename from t_rnd.m.
+	* statistics/distributions/unifcdf.m: Rename from unifoxorm_cdf.m.
+	* statistics/distributions/unifinv.m: Rename from uniform_inv.m.
+	* statistics/distributions/unifpdf.m: Rename from uniform_pdf.m.
+	* statistics/distributions/unifrnd.m: Rename from uniform_rnd.m.
+	* statistics/distributions/weibcdf.m: Rename from weibull_cdf.m.
+	* statistics/distributions/weibinv.m: Rename from weibull_inv.m.
+	* statistics/distributions/weibpdf.m: Rename from weibull_pdf.m.
+	* statistics/distributions/wienrnd.m: Rename from wiener_rnd.m.
+
+	* deprecated/beta_cdf.m, deprecated/beta_inv.m,
+	deprecated/beta_pdf.m, deprecated/beta_rnd.m,
+	deprecated/binomial_cdf.m, deprecated/binomial_inv.m,
+	deprecated/binomial_pdf.m, deprecated/binomial_rnd.m,
+	deprecated/chisquare_cdf.m, deprecated/chisquare_inv.m,
+	deprecated/chisquare_pdf.m, deprecated/chisquare_rnd.m,
+	deprecated/exponential_cdf.m, deprecated/exponential_inv.m,
+	deprecated/exponential_pdf.m, deprecated/exponential_rnd.m,
+	deprecated/f_cdf.m, deprecated/f_inv.m, deprecated/f_pdf.m,
+	deprecated/f_rnd.m, deprecated/gamma_cdf.m,
+	deprecated/gamma_inv.m, deprecated/gamma_pdf.m,
+	deprecated/gamma_rnd.m, deprecated/geometric_cdf.m,
+	deprecated/geometric_inv.m, deprecated/geometric_pdf.m,
+	deprecated/geometric_rnd.m, deprecated/hypergeometric_cdf.m,
+	deprecated/hypergeometric_inv.m, deprecated/hypergeometric_pdf.m,
+	deprecated/hypergeometric_rnd.m, deprecated/lognormal_cdf.m,
+	deprecated/lognormal_inv.m, deprecated/lognormal_pdf.m,
+	deprecated/lognormal_rnd.m, deprecated/normal_cdf.m,
+	deprecated/normal_inv.m, deprecated/normal_pdf.m,
+	deprecated/normal_rnd.m, deprecated/poisson_cdf.m,
+	deprecated/poisson_inv.m, deprecated/poisson_pdf.m,
+	deprecated/poisson_rnd.m, deprecated/t_cdf.m, deprecated/t_inv.m,
+	deprecated/t_pdf.m, deprecated/t_rnd.m, deprecated/uniform_cdf.m,
+	deprecated/uniform_inv.m, deprecated/uniform_pdf.m,
+	deprecated/uniform_rnd.m, deprecated/weibull_cdf.m,
+	deprecated/weibull_inv.m, deprecated/weibull_pdf.m,
+	deprecated/wiener_rnd.m: New files.
+
+2005-07-08  John W. Eaton  <jwe at octave.org>
+
+	* statistics/distributions/weibrnd.m: Rename from weibull_rnd.m.
+	* deprecated/weibull_rnd.m: New file.
+
+2005-07-08  cctsim  <cctsim at yahoo.co.uk>
+
+	* strings/dec2base.m: Allow matrix arguments.
+
+2005-07-08  John W. Eaton  <jwe at octave.org>
+
+	* plot/__errplot__.m: Use __plot_globals__.
+	* plot/__plt__.m: Likewise.
+	* plot/figure.m: Likewise.
+
+	* plot/hold.m: New file.
+	* plot/ishold.m: New file.
+	* plot/__plot_globals__.m: New file.
+
+2005-07-05  cctsim  <cctsim at yahoo.co.uk>
+
+	* strings/dec2base.m: Don't remove all leading zeros if result is zero.
+
+2005-07-05  John W. Eaton  <jwe at octave.org>
+
+	* strings/findstr.m: Return [] for no matches.
+
+2005-06-17  Keith Goodman  <kwgoodman at gmail.com>
+
+	* miscellaneous/tic.m: Fix doc string.
+
+2005-06-15  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/polyfit.m: Force return value to be a row vector.
+
+2005-06-15  Tom Holroyd  <tomh at kurage.nimh.nih.gov>
+
+	* general/isequal.m: Correct nargin check.
+
+2005-06-14  John W. Eaton  <jwe at octave.org>
+
+	* general/isvector.m: Handle N-d arrays.
+	From Bill Denney <denney at seas.upenn.edu>.
+
+2005-06-02  Ben Barrowes  <barrowes at alum.mit.edu>
+
+	* plot/meshgrid.m: Handle 3 input arguments.
+
+2005-06-02  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* signal/freqz.m: Use correct calculations when given a vector of
+	frequencies.  Improve accuracy of returned frequency vector.
+	Improve speed for medium length filters (at a slight cost for slow
+	filters).  Add test cases.
+
+2005-05-27  "Dmitri A. Sergatskov"  <dasergatskov at gmail.com>
+
+	* plot/loglog.m: Fix set commands.
+
+2005-05-25  John W. Eaton  <jwe at octave.org>
+
+	* plot/sombrero.m: Default n to 41 if nargin == 0.
+
+2005-05-24  John W. Eaton  <jwe at octave.org>
+
+	* statistics/tests/anova.m: Use mean (y(:)) to compute total_mean.
+
+	* strings/strncmp.m: New file, from Tom Holroyd
+	<tomh at kurage.nimh.nih.gov>.
+
+	* strings/strcmp.m: Return logical values in all cases.
+
+2005-05-23  John W. Eaton  <jwe at octave.org>
+
+	* plot/orient.m: New file.  Adapt to Octave coding style.
+	Texinfoize doc string.
+
+	* plot/print.m: New file.  Adapt to Octave coding style. Include
+	PKG_ADD command.  Use set terminal consistently	throughout.  Use
+	set terminal push/pop and unconditionally set output to screen
+	when done to avoid requiring gget.  Use a cell array for dev_list
+	and cellidx to search for items in the list.  Delete local
+	variable endl.  Don't set and restore automatic_replot.  Use {}
+	instead of nth to index varargin.  Delete local variable
+	va_arg_cnt.
+
+2005-05-18  John W. Eaton  <jwe at octave.org>
+
+	* general/num2str.m: Return early if X is a character string.
+
+2005-05-11  John W. Eaton  <jwe at octave.org>
+
+	* strings/findstr.m: Allow non-string arguments for compatiblity.
+	From Tom Holroyd <tomh at kurage.nimh.nih.gov>.
+
+	* plot/polar.m: Don't call __pltopt__ here.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* mkdoc: Print header message.
+
+2005-04-28  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_CONFIG_SRCDIR): Look for startup/inputrc, not
+	startup/octaverc.
+
+2005-04-28  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* image/imshow.m: Handle various image depths and 3d RGB images.
+	(__im_numeric_limits__): New internal function.
+
+2005-04-28  toni saarela  <toni.saarela at helsinki.fi>
+
+	* statistics/tests/anova.m: Compute total_mean as mean of all
+	data, not mean of group_mean.
+
+2005-04-28  John W. Eaton  <jwe at octave.org>
+
+	* startup/local-rcfile: New file.
+	* startup/main-rcfile: Rename from startup/octaverc.
+	* startup/Makefile.in (SOURCES): Add inputrc to the list.
+	(install install-strip): Install main-rcfile in $(fcnfiledir)/startup.
+	Install local-rcfile in $(localfcnfiledir)/startup.
+
+2005-04-28  Keith Goodman  <kwgoodman at gmail.com>
+
+	* startup/inputrc: New file.
+	* startup/octaverc: Configure readline using inputrc from
+	startupfiledir.
+	* startup/Makefile.in (install, install-strip): Install octaverc
+	in $(fcnfiledir)/startup.
+
+2005-04-27  John W. Eaton  <jwe at octave.org>
+
+	* optimization/qp.m: Define n_in after removing -Inf bounds from Ain.
+
+2005-04-21  John W. Eaton  <jwe at octave.org>
+
+	* optimization/glpk.m: Handle SENSE argument.
+
+	* optimization/qp.m, optimization/sqp.m: New files.
+
+2005-04-08  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (clean, distclean, maintainer-clean):
+	Avoid duplication in rules.
+
+2005-03-28  John W. Eaton  <jwe at octave.org>
+
+	* plot/contour.m, plot/mesh.m: Continue to use __gnuplot_raw__ for
+	setting {no,}parametric.
+	* plot/figure.m: Likewise, for setting terminal type.
+
+	*  __axis_label__.m:, plot/axis.m, plot/bottom_title.m,
+	plot/contour.m, plot/figure.m, plot/multiplot.m, plot/mplot.m,
+	plot/plot_border.m, plot/subplot.m, plot/subwindow.m,
+	plot/title.m, plot/top_title.m: Avoid eval.
+
+2005-03-28  Dmitri A. Sergatskov  <dasergatskov at gmail.com>
+
+	* plot/__axis_label__.m, plot/axis.m, plot/grid.m,
+	plot/plot_border.m, plot/replot.m, plot/title.m, plot/top_title.m:
+	Use __gnuplot_replot__ instead of replot.
+
+	* plot/__axis_label__.m, plot/axis.m, plot/bottom_title.m,
+	plot/contour.m, plot/errorbar.m, plot/figure.m, plot/grid.m,
+	plot/loglogerr.m, plot/loglog.m, plot/mesh.m, plot/mplot.m,
+	plot/multiplot.m, plot/oneplot.m, plot/plot_border.m, plot/plot.m,
+	plot/polar.m, plot/semilogxerr.m, plot/semilogx.m,
+	plot/semilogyerr.m, plot/semilogy.m, plot/shg.m, plot/subplot.m,
+	plot/subwindow.m, plot/title.m, plot/top_title.m:
+	Use __gnuplot_raw__ instead of __gnuplot_set__.
+
+	* plot/replot.m: Use __gnuplot_replot__, not __greplot__.
+
+2005-03-24  John W. Eaton  <jwe at octave.org>
+
+	* optimization/glpkmex.m: Texinfoize Doc string.
+	* optimization/glpk.m: Likewise.
+	Allow VARTYPE and CTYPE to be row or column vectors of characters
+	(row vectors are orginary character strings).
+	* optimization/glpkparam.m: Delete.
+
+2005-03-24  Quentin Spencer  <qspencer at ieee.org>
+
+	* statistics/base/mean.m: Allow DIMS arg greater than the number
+	of dimensions of X.
+
+2005-03-23  John W. Eaton  <jwe at octave.org>
+
+	* general/tril.m, general/triu.m: Return value of same class as
+	argument.
+
+	* optimization/glpk.m: Simplify interface.  By default, solve
+	standard LP min C'*x s.t. A*x = b, x >= 0.
+	* optimization/glpkmex.m: New file.
+
+2005-03-22  John W. Eaton  <jwe at octave.org>
+
+	* configure.in (AC_CONFIG_FILES): Add optimization/Makefile to the
+	list.
+
+	* optimization/glpk.m: Adapt to Octave coding style.
+	No need for varargout or varargin.
+	Print usage message if nargin > 11.
+	Allow any value of nargout.
+	Use repmat (C, nr, nc) instead of char (C * ones (nr, nc)).
+	Avoid looping when checking character classes.
+
+	* optimization: New directory.
+	* Makefile.in (SUBDIRS): Add it to the list.
+	* optimization/Makefile.in: New file.
+	* optimization/glpk.m, optimization/glpkparams.m,
+	optimization/glpktest1, optimization/glpktest2: New files.
+
+2005-03-16  S�ren Hauberg  <soren at hauberg.org>
+
+	* strings/split.m: Quick return for empty second arg.
+	Improve warning for multi-line strings.
+	Speed up by avoiding sprintf in loop and eval.
+
+2005-03-16  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* polynomial/polyderiv.m : Accept a*b, a/b.  Auto-reduce common terms.
+	* polynomial/polyder.m: Ditto.
+	* polynomial/polygcd.m: New function.
+
+2005-03-16  John W. Eaton  <jwe at octave.org>
+
+	* control/base/__stepimp__.m, control/base/bode.m,
+	control/base/frdemo.m, control/base/nichols.m,
+	control/base/nyquist.m, control/base/pzmap.m,
+	control/base/rldemo.m, control/base/rlocus.m,
+	control/hinf/dhinfdemo.m, control/hinf/hinfdemo.m,
+	plot/__axis_label__.m, plot/__errplot__.m, plot/__plt__.m,
+	plot/axis.m, plot/bar.m, plot/bottom_title.m, plot/contour.m,
+	plot/errorbar.m, plot/figure.m, plot/grid.m, plot/loglog.m,
+	plot/loglogerr.m, plot/mesh.m, plot/meshgrid.m, plot/mplot.m,
+	plot/multiplot.m, plot/oneplot.m, plot/plot.m, plot/plot_border.m,
+	plot/polar.m, plot/semilogx.m, plot/semilogxerr.m,
+	plot/semilogy.m, plot/semilogyerr.m, plot/shg.m, plot/stairs.m,
+	plot/subplot.m, plot/subwindow.m, plot/title.m, plot/top_title.m,
+	plot/xlabel.m, quaternion/demoquat.m,
+	quaternion/qcoordinate_plot.m, signal/freqz_plot.m, sparse/spy.m,
+	statistics/base/ppplot.m, statistics/base/qqplot.m:
+	Use __gnuplot_plot__ instead of gplot, __gnuplot_splot__ instead
+	of gsplot, and __gnuplot_set__ instead of gset. Remove gplot,
+	gsplot from @seealso docs.
+
+	* plot/replot.m: New file.
+
+2005-03-15  David Bateman  <dbateman at free.fr>
+
+	* set/unique.m, set/ismember.m: Handle cell arrays.
+
+2005-03-09  John W. Eaton  <jwe at octave.org>
+
+	* statistics/Makefile.in (bin-dist): Delete target.
+	(BINDISTSUBDIRS): Delete variable.
+	* control/Makefile.in: Likewise.
+
+	* audio/Makefile.in (bin-dist): Delete target.
+	(BINDISTFILES): Delete variable.
+	* control/base/Makefile.in: Likewise.
+	* control/hinf/Makefile.in: Likewise.
+	* control/obsolete/Makefile.in: Likewise.
+	* control/system/Makefile.in: Likewise.
+	* control/util/Makefile.in: Likewise.
+	* deprecated/Makefile.in: Likewise.
+	* elfun/Makefile.in: Likewise.
+	* finance/Makefile.in: Likewise.
+	* general/Makefile.in: Likewise.
+	* image/Makefile.in: Likewise.
+	* sparse/Makefile.in: Likewise.
+	* io/Makefile.in: Likewise.
+	* plot/Makefile.in: Likewise.
+	* Makefile.in: Likewise.
+	* miscellaneous/Makefile.in: Likewise.
+	* linear-algebra/Makefile.in: Likewise.
+	* polynomial/Makefile.in: Likewise.
+	* quaternion/Makefile.in: Likewise.
+	* set/Makefile.in: Likewise.
+	* signal/Makefile.in: Likewise.
+	* specfun/Makefile.in: Likewise.
+	* special-matrix/Makefile.in: Likewise.
+	* startup/Makefile.in: Likewise.
+	* statistics/base/Makefile.in: Likewise.
+	* statistics/distributions/Makefile.in: Likewise.
+	* statistics/models/Makefile.in: Likewise.
+	* statistics/tests/Makefile.in: Likewise.
+	* strings/Makefile.in: Likewise.
+	* time/Makefile.in: Likewise.
+
+2005-03-08  John W. Eaton  <jwe at octave.org>
+
+	* general/repmat.m: Correctly diagnose 3-argument non-scalar
+	dimensions case.  From Matthew A Swabey <mas01r at ecs.soton.ac.uk>.
+
+2005-03-04  John W. Eaton  <jwe at octave.org>
+
+	* plot/clg.m: New file.
+
+2005-03-03  John W. Eaton  <jwe at octave.org>
+
+	* general/isequal.m, general/sortrows.m, set/ismember.m,
+	set/setdiff.m, strings/str2double.m, strings/strmatch.m,
+	strings/strcmpi.m:
+	New files from Octave-forge.  Adapt to Octave coding standards.
+
+2005-03-03  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* statistics/distributions/binomial_pdf.m: Extend the feasible
+	computation range.
+
+2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	Sparse merge.
+
+	2005-01-23  David Bateman  <dbateman at free.fr>
+
+	* sparse/randperm.m: Delete duplicate randperm.m.
+
+	2005-01-10  John W. Eaton  <jwe at octave.org>
+
+	* sparse/Makefile.in: New file.
+	* configure.in (AC_CONFIG_FILES): Add sparse/Makefile to the list.
+
+	2005-01-07  David Bateman  <dbateman at free.fr>
+
+	* set/unique.m: import file from octave-forge.
+
+	2005-01-05  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: include sparse directory in SUBDIRS.
+	
+	2004-12-30  John W. Eaton  <jwe at octave.org>
+
+	* sparse/nzmax.m: Delete (there is an nzmax function in
+	src/DLD-FUNCTIONS/sparse.cc).
+
+	2004-12-28  John W. Eaton  <jwe at octave.org>
+
+	Merge of sparse code from David Bateman <dbateman at free.fr> and 
+	Andy Adler <adler at site.uottawa.ca>.
+
+	* sparse/colperm.m, sparse/nonzeros.m, sparse/nzmax.m,
+	sparse/randperm.m, sparse/spalloc.m, sparse/spconvert.m,
+	sparse/spdiags.m, sparse/speye.m, sparse/spfun.m, sparse/sphcat.m,
+	sparse/spones.m, sparse/sprand.m, sparse/sprandn.m,
+	sparse/spstats.m, sparse/spvcat.m, sparse/spy.m: New files.
+
+	* sparse: New directory.
+
+2005-02-22  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/residue.m: Force prepad to always create row vectors.
+
+	* polynomial/poly.m: Quick return if m is 0.
+	From Carmen Navarrete <carmen.navarrete at uam.es>.
+
+2005-02-21  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions/poisson_rnd.m: fix for lambda of zero.
+	From Mark van Rossum <mvanross at inf.ed.ac.uk>.
+	Fix for row vectors with at least one element of lambda not in
+	(0, Inf).
+
+2005-02-21  John W. Eaton  <jwe at octave.org>
+
+	* statistics/base/qqplot.m: Use feval instead of eval.
+
+	* plot/grid.m, plot/plot_border.m, plot/title.m, plot/top_title.m,
+	plot/__axis_label__.m: Issue replot command.
+
+2005-02-09  John W. Eaton  <jwe at octave.org>
+
+	* polynomial/polyderiv.m: Force P to be a row vector.
+
+2005-02-08  John W. Eaton  <jwe at octave.org>
+
+	* strings/dec2base.m: Don't delete leading zero if third arg is
+	provided and len <= computed max_len.
+
+2005-01-27  David Bateman  <dbateman at free.fr>
+
+	* strings/dec2base.m: Be even more careful about handling all digits.
+
+2005-01-27  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* strings/dec2base.m: Use integer arithmetic to count number of digits.
+
+2005-01-27  Benjamin Hall  <benjamin.hall at pw.utc.com>
+
+	* statistics/base/median.m: Make it work for the scalar case too.
+
+2005-01-25  Daniel J Sebald  <daniel.sebald at ieee.org>
+
+	* plot/__plt__.m: Initialize fmt and sep outside of loop.
+	Simplify logic for decoding args.
+
+2005-01-24  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plr__.m, plot/__plr2__.m: Pass name of caller to __plt__.
+
+	* plot/__plt__.m: No need to save and reset hold state now.
+	(first_plot): Delete unused variable.
+
+	* plot/__plr2__.m, plot/__plt2__.m: Improve diagnostics.
+
+	* plot/__plr__.m: Use __plt__, not specific __pltXX__ functions.
+	* plot/__plt1__.m, plot/__plt2__.m, plot/__plt2mm__.m,
+	plot/__plt2mv__.m, plot/__plt2ss__.m, plot/__plt2vm__.m,
+	plot/__plt2vv__.m:
+	Return data and gnuplot commands instead of evaluating them.
+	* plot/__plt__.m: Handle evaluation of all gnuplot commands here.
+	Based on changes from Daniel J Sebald <daniel.sebald at ieee.org>.
+
+2005-01-18  John W. Eaton  <jwe at octave.org>
+
+	* linear-algebra/cross.m: Allocate idx1 before use.
+
+2004-12-08  Heikki Junes  <Heikki.Junes at hut.fi>
+
+	* statistics/base/range.m: Fix varargin usage.
+
+2004-12-02  Pascal A. Dupuis  <Pascal.Dupuis at esat.kuleuven.ac.be>
+
+	* strings/deblank.m: Remove all trailing whitespace (check with
+	isspace), not just SPC.
+
+2004-12-02  Balint Reczey  <balint_reczey at yahoo.com>
+
+	* statistics/base/moment.m: Fix argument parsing for N-d arrays.
+
+2004-11-09  John W. Eaton  <jwe at octave.org>
+
+	* miscellaneous/fileparts.m: Allow filenames with no extension.
+	From Julius Smith <jos at ccrma.stanford.edu>.
+ 
+2004-11-08  John W. Eaton  <jwe at octave.org>
+
+	* plot/__plt2vm__.m: Delete debugging statement.
+	From Dmitri A. Sergatskov <dmitri at unm.edu>.
+
+2004-11-04  John W. Eaton  <jwe at octave.org>
+
+	* plot/hist.m: Always return row vectors for vector args.
+
+2004-09-23  John W. Eaton  <jwe at octave.org>
+
+	* strings/strcmp.m: If args are not strings or cell arrays of
+	strings, return zero instead of reporting an error.
+
+2004-09-22  Federico Zenith  <zenith at chemeng.ntnu.no>
+
+	* control/base/analdemo.m, control/base/are.m, control/base/bddemo.m,
+	control/base/controldemo.m, control/base/damp.m, control/base/dare.m, 
+	control/base/dcgain.m, control/base/dgram.m, control/base/dlyap.m,
+	control/base/dre.m, control/base/frdemo.m, control/base/gram.m,
+	control/base/impulse.m, control/base/lqp.m, control/base/obsv.m,
+	control/base/pzmap.m, control/base/rldemo.m, control/hinf/h2norm.m,
+	control/hinf/hinfsyn.m, control/hinf/hinfsyn_ric.m,
+	control/hinf/is_dgkf.m, control/system/c2d.m, 
+	control/system/is_detectable.m, control/system/is_sample.m,
+	control/system/is_siso.m, control/system/is_stable.m,
+	control/system/ss2sys.m, control/system/ss.m, control/system/sys2ss.m,
+	control/system/sys2tf.m, control/system/sys2zp.m, 
+	control/system/sysappend.m, control/system/sysconnect.m,
+	control/system/sysdisc.m, control/system/sysdup.m,
+	control/system/sysgetsignals.m, control/system/sysmult.m,
+	control/system/syssetsignals.m, control/system/syssub.m,
+	control/system/tf2sys.m, control/system/ugain.m,
+	control/system/zp2ss.m, control/system/zp2sys.m, 
+	control/system/zp2tf.m, control/util/axis2dlim.m, polynomial/roots.m,
+	special-matrix/toeplitz.m: Fix typos in doc strings.
+
+	* control/base/are.m, control/base/dare.m, control/base/lsim.m,
+	control/base/ltifr.m, control/base/place.m,control/base/tzero2.m,
+	control/base/tzero.m, control/hinf/hinf_ctr.m, control/hinf/wgt1o.m,
+	ontrol/system/is_abcd.m, control/system/parallel.m,
+	control/system/ss2tf.m, control/system/ss2zp.m, control/system/ss.m,
+	control/system/sysappend.m, control/system/sysconnect.m,
+	control/system/sysdup.m, control/system/sysgroup.m,
+	control/system/sysprune.m, control/system/sysreorder.m,
+	control/system/sysscale.m, control/system/syssub.m,
+	control/system/tf2ss.m, control/system/tf2zp.m, control/util/zgfmul.m,
+	control/util/zginit.m, control/util/zgscal.m, elfun/acoth.m,
+	polynomial/polyout.m, specfun/log2.m:
+	Add output arguments in doc strings.
+
+	* control/base/are.m, control/base/bode_bounds, control/base/bode.m,
+	control/base/__bodquist__.m, control/base/ctrb.m, control/base/dare.m,
+	control/base/DEMOcontrol.m, control/base/dlyap.m, control/base/dre.m,
+	control/base/freqchkw.m, control/base/__freqresp__.m,
+	control/base/__freqresp__.m, control/base/lqp.m, control/base/lqr.m,
+	contol/base/lsim.m, control/base/lyap.m, control/base/nyquist.m,
+	control/base/obsv.m, control/base/place.m, control/base/pzmap.m,
+	control/base/__stepimp__.m, control/base/step.m, control/base/tzero2.m
+	control/base/tzero.m, control/hinf/dhinfdemo.m, control/hinf/h2norm.m,
+	control/hinf/h2syn.m, control/hinf/hinfdemo.m, 
+	control/hinf/hinfnorm.m, control/hinf/hinfsyn_chk.m, 
+	control/hinf/hinfsyn.m, control/hinf/is_dgkf.m, 
+	control/obsolete/syschnames.m, control/obsolete/syschnames.m,
+	control/system/c2d.m, control/system/is_abcd.m, 
+	control/system/is_controllable.m, control/system/is_detectable.m,
+	control/system/is_observable.m, control/system/is_stable.m,
+	control/system/jet707.m, control/system/ord2.m, 
+	control/system/starp.m, control/system/sys2fir.m, 
+	control/system/sys2ss.m, control/system/sys2tf.m, 
+	control/system/sys2zp.m, control/system/syscont.m, 
+	control/system/sysdisc.m, control/system/sysdup.m,
+	control/system/sysgettype.m, control/system/sysgroup.m,
+	control/system/sysmult.m, control/system/sysprune.m,
+	control/system/sysreorder.m, control/system/sysscale.m,
+	control/system/syssetsignals.m, control/system/sysupdate.m,
+	control/system/tf2ss.m, control/system/tf2sys.m, 
+	control/system/zp2ss.m, control/system/zp2sys.m, 
+	control/util/axis2dlim.m, control/util/prompt.m,
+	control/util/zgfmul.m, control/util/zginit.m, 
+	control/util/__zgpbal__.m, control/util/zgscal.m: 
+	Use @var, @strong, @command, @math, @acronym, @table and @cite 
+	in doc strings.
+
+	* control/base/bode_bounds.m, control/base/ctrb.m, control/base/dre.m, 
+	control/base/dgram.m, control/base/dlyap.m, control/base/ltifr.m,
+	control/base/nyquist.m, control/base/obsv.m, control/base/tzero.m,
+	control/hinf/dgkfdemo.m, control/hinf/dhinfdemo.m,
+	control/hinf/h2norm.m, control/hinf/h2syn.m, control/hinf/hinf_ctr.m,
+	control/hinf/hinfdemo.m, control/hinf/hinfnorm.m, 
+	control/hinf/hinfsyn_chk.m, control/hinf/hinfsyn.m,
+	control/hinf/wgt1o.m, control/obsolete/syschnames.m,
+	control/system/c2d.m, control/system/fir2sys.m,
+	control/system/is_stabilizable.m, control/system/jet707.m,
+	control/system/ord2.m, control/system/ss2tf.m, control/system/tf2ss.m,
+	control/util/zgshsr.m, polynomial/polyout.m:
+	New @tex section(s) in doc strings for better formating of printed
+	output.
+
+	* control/base/__freqresp__.m, control/base/nyquist.m, 
+	control/base/__stepimp__.m, control/hinf/hinfdemo.m,
+	control/obsolete/syschnames.m, control/system/sysprune.m:
+ 	Use proper double quote marks for TeX.
+
+	* control/base/DEMOcontrol.m: Add missing ;
+
+	* control/base/nichols.m, control/base/rlocus.m, 
+	control/obsolete/minfo.m, control/system/is_digital.m,
+	control/system/ss2zp.m, control/system/sysmin.m, 
+	control/system/tf2zp.m, control/util/sortcom.m: 
+	Convert documentation to use or more completely use Texinfo.
+
+	* control/base/rlocus.m, control/hinf/dhinfdemo.m, 
+	control/hinf/hinfdemo.m, control/system/ord2.m, 
+	control/system/parallel.m, control/system/ss2tf.m,
+	control/system/starp.m: Use "@group ... @end group" to avoid ascii
+	art splitting over a page boundary.
+	
+	* control/hinf/dgkfdemo.m, control/hinf/dhinfdemo.m, 
+	control/hinf/h2norm.m, control/hinf/h2syn.m, control/hinf/hinf_ctr.m, 
+	control/hinf/hinfdemo.m, control/hinf/hinfnorm.m, 
+	control/hinf/hinfsyn_chk.m, control/hinf/hinfsyn.m,
+	control/hinf/wgt1o.m, control/system/buildssic.m:
+	Use {\cal H}_\infty for H-infinity and likewise for H-2 to
+	the TeX documentation.
+	
+	* control/system/is_stabilizable.m:
+	Add Copyright so that help is displayed correctly.
+
+	* special-matrix/vander.m: Octave indexes start at 1.
+
+2004-09-21  David Bateman  <dbateman at free.fr>
+
+	* general/rotdim.m: New function for rotation of an N-d array in an
+	arbitrary plane.
+
+	* general/flipdim.m: New function to flip an N-d array about an 
+	arbitrary axis.
+
+2004-09-15  David Bateman  <dbateman at free.fr>
+
+	* general/bitget.m: Replace Bmax, which is undefined with bitmax
+
+2004-09-15  John W. Eaton  <jwe at octave.org>
+
+	* strings/strcmp.m: Fix typo in cell/string array case.
+	Use iscellstr to check for cells rather than iscell.
+	Improve diagnostics for invalid args.
+
+2004-09-10  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions/binomial_rnd.m: Fix error for scalar n
+	and p with n > 1, and fix for matrix n and p with n == 1.
+
+	* statistics/distributions/poisson_rnd.m: Fix for matrix length,
+	due to row vs. column vector operations.
+
+2004-09-03  David Bateman  <dbateman at free.fr>
+
+	* general/repmat.m: Fix to allow logical classes.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* general/isa.m: New function, from Octave-forge.
+
+2004-08-31  David Bateman  <dbateman at free.fr>
+
+	* general/bitcmp.m, general/bitget.m, general/bitset.m: Remove 
+	limitation on the use of int64 and uint64 types, and the use
+	of the eval.
+
+	* general/bitset.m: Remove superfluous cast to return type, as bug
+	in .^ with integer types is fixed.
+
+	* general/repmat.m: Adapt to allow integer types.
+
+2004-08-31  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* plot/axis.m: Don't reset axes when querying them.
+
+2004-08-27  David Bateman  <dbateman at free.fr>
+
+	* statistics/base/ranks.m: Handle non-consecutive ties.
+	Eliminate loop.
+
+2004-07-27  David Bateman  <dbateman at free.fr>
+
+	* general/num2str.m: Also insert spaces in output when precision
+	argument is supplied.
+
+2004-07-23  David Bateman  <dbateman at free.fr>
+
+	* general/bitcmp.m, general/bitget.m, general/bitset.m: New functions.
+
+2004-07-22  Etienne Grossmann  <etienne at cs.uky.edu>
+
+	* general/sub2ind.m: Make reshaping index list unnecessary.
+
+2004-07-22  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* miscellaneous/unix.m: Fix doc string.
+
+2004-07-22  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* plot/figure.m: Clarification of documentation.
+
+	* image/imshow.m: Warn for complex images.
+	Only estimate colourmap for images in [0, 65536].
+
+2004-07-22  David Bateman  <dbateman at free.fr>
+
+	* general/num2str.m: Fix the case of an all zero input.
+
+2004-06-22  Etienne Grossmann  <etienne at cs.uky.edu>
+
+	* general/ind2sub.m: Doc fix.
+
+2004-06-08  John W. Eaton  <jwe at octave.org>
+
+	* statistics/tests/kolmogorov_smirnov_test.m: Use func2str to
+	convert function handle to string for eval.
+
+2004-06-04  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* plot/errorbar.m: Remove debugging output.
+
+2004-06-03  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* plot/__pltopt__.m: Properly escape @ symbols in doc string.
+
+2004-06-03  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* deprecated/com2str.m: Include 'i' suffix for pure imaginary numbers.
+
+	* polynomial/polyout.m: Use parenthesis if necessary around
+	complex polynomial coefficient.
+
+	* plot/__errcomm__.m, plot/__errplot__.m: Simplify code and fix
+	the bug which causes __errplot__ to ignore the last argument.
+
+2004-06-03  David Bateman  <dbateman at free.fr>
+
+	* general/shiftdim.m: New function based on JWE code snippet.
+
+	* general/circdim.m: New function.
+
+2004-05-06  David Bateman  <dbateman at free.fr>
+
+	* general/issquare.m: Fail if ndim(x) > 2.
+
+	* linear-algebra/norm.m, linear-algebra/norm.m: Fail if ndim(x) > 2.
+
+	* linear-alegbra/cross.m, linear-algebra/dot.m: Allow matrix and
+	N-d array arguments.  Add optional dim argument to define
+	dimension along which to operate.
+
+	* linear-algebra/dmult.m: Allow N-d arrays.
+
+	* linear-algebra/vec.m: Use v(:) and not reshape.
+
+2004-04-29  David Bateman  <dbateman at free.fr>
+
+	* statistics/base/ranks.m, statistics/base/run_count.m,
+	statistics/base/studentize.m, statistics/base/kurtosis.m
+	statistics/base/statistics.m, statistics/base/skewness.m
+	statistics/base/iqr.m:
+	Make N-d array aware.  Allow optional argument to define the
+	dimension along which to operate.  Update the documentation.
+
+	* statistics/base/ranks.m: Change algorithm to use sort,
+	and adjust for the ties after.
+
+	* statistics/base/run_counts.m: Change algorithm to use
+	the a combination of diff and find, rather than a for-loop.
+
+2004-04-23  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* plot/hist.m: Correctly determine cutoffs.  New tests.
+
+2004-04-23  David Bateman  <dbateman at free.fr>
+
+	* general/int2str.m: Treat only real part of argument, and treat
+	NDArrays by stacking the slices through the matrix vertically.
+
+	* general/num2str.m: Improve format of integer matrices, and the
+	conversion of complex matrices added. Treat NDArrays by stacking
+	the slices through the matrix vertically.
+
+	* deprecated/com2str.m: Moved here from general subdirectory.
+
+2004-04-22  John W. Eaton  <jwe at octave.org>
+
+	* quaternion/qtransvmat.m: Use continuation characters to make
+	sure result is a matrix instead of a vector.  From <aklark at atdot.it>.
+
+2004-04-21  David Bateman  <dbateman at free.fr>
+
+	* elfun/lcm.m: Make N-d aware.
+
+	* general/diff.m: Make the code N-d array aware.  Allow an
+	optional argument to define the dimension along which to perform
+	the differences and allow the order of the differences to be larger
+	than the dimension itself.
+
+	* general/rot90.m, general/fliplr.m, general/flipud.m: Limit the
+	use of these functions to 1- and 2-d arrays.
+
+2004-04-16  John W. Eaton  <jwe at octave.org>
+
+	* elfun/gcd.m: Delete.
+
+2004-04-15  David Bateman  <dbateman at free.fr>
+
+	* set/create_set.m, general/is_duplicate_entry.m: Make N-d array aware.
+
+	* general/shift.m, general/prepad.m, general/postpad.m: Make N-d
+	array aware and and optional argument for the dimension along
+	which to operate.
+
+	* signal/unwrap.m: Make N-d array aware and fix optional
+	argument for the dimension to be consistent with other N-d array
+	functions.
+
+2004-04-08  David Bateman  <dbateman at free.fr>
+
+	* statistics/distributions/discrete_cdf.m,
+	statistics/distributions/discrete_inv.m,
+	statistics/distributions/discrete_pdf.m,
+	statistics/distributions/discrete_rnd.m,
+	statistics/distributions/exponential_cdf.m,
+	statistics/distributions/exponential_inv.m,
+	statistics/distributions/exponential_pdf.m,
+	statistics/distributions/exponential_rnd.m,
+	statistics/distributions/f_cdf.m,
+	statistics/distributions/f_inv.m,
+	statistics/distributions/f_pdf.m,
+	statistics/distributions/f_rnd.m,
+	statistics/distributions/geometric_cdf.m,
+	statistics/distributions/geometric_inv.m,
+	statistics/distributions/geometric_pdf.m,
+	statistics/distributions/geometric_rnd.m,
+	statistics/distributions/hypergeometric_rnd.m,
+	statistics/distributions/kolmogorov_smirnov_cdf.m,
+	statistics/distributions/laplace_cdf.m,
+	statistics/distributions/laplace_inv.m,
+	statistics/distributions/laplace_pdf.m,
+	statistics/distributions/laplace_rnd.m,
+	statistics/distributions/logistic_inv.m,
+	statistics/distributions/logistic_rnd.m,
+	statistics/distributions/lognormal_cdf.m,
+	statistics/distributions/lognormal_inv.m,
+	statistics/distributions/lognormal_pdf.m,
+	statistics/distributions/lognormal_rnd.m,
+	statistics/distributions/pascal_cdf.m,
+	statistics/distributions/pascal_inv.m,
+	statistics/distributions/pascal_pdf.m,
+	statistics/distributions/pascal_rnd.m,
+	statistics/distributions/poisson_cdf.m,
+	statistics/distributions/poisson_inv.m,
+	statistics/distributions/poisson_pdf.m,
+	statistics/distributions/poisson_rnd.m,
+	statistics/distributions/t_cdf.m,
+	statistics/distributions/t_inv.m,
+	statistics/distributions/t_pdf.m,
+	statistics/distributions/t_rnd.m,
+	statistics/distributions/weibull_cdf.m,
+	statistics/distributions/weibull_inv.m,
+	statistics/distributions/weibull_pdf.m,
+	statistics/distributions/weibull_rnd.m:
+	Allow N-d arrays.
+
+	* statistics/distributions/discrete_inv.m: Fix bug in indexing,
+	that results in NaN in places where it should not have had.
+
+	* statistics/distributions/discrete_rnd.m: New argument formats to
+	allow creating arbitrary matrices, compatiable with the other 
+	*_rnd.m functions. Maintain compatibility with previous format.
+
+	* statistics/distributions/empirical_rnd.m: New argument formats
+	to allow creating arbitrary matrices, compatiable with the other
+	*_rnd.m functions. Maintain compatibility with previous
+	format.  Allow N-d arrays.
+
+	* statistics/distributions/hypergeometric_cdf.m,
+	statistics/distributions/hypergeometric_inv.m,
+	statistics/distributions/hypergeometric_pdf.m,
+	statistics/distributions/wiener_rnd.m:
+	Error for non-scalar arguments.
+	
+	* statistics/distributions/pascal_rnd.m:
+	Correct for n = 1 bug, where all elements were equal.
+
+2004-04-06  David Bateman  <dbateman at free.fr>
+
+	* general/common_size.m, miscellaneous/bincoeff.m,
+	statistics/distributions/beta_cdf.m,
+	statistics/distributions/beta_inv.m,
+	statistics/distributions/beta_pdf.m,
+	statistics/distributions/beta_rnd.m,
+	statistics/distributions/binomial_cdf.m,
+	statistics/distributions/binomial_inv.m,
+	statistics/distributions/binomial_pdf.m,
+	statistics/distributions/binomial_rnd.m,
+	statistics/distributions/cauchy_cdf.m,
+	statistics/distributions/cauchy_inv.m,
+	statistics/distributions/cauchy_pdf.m,
+	statistics/distributions/cauchy_rnd.m,
+	statistics/distributions/chisquare_cdf.m,
+	statistics/distributions/chisquare_inv.m,
+	statistics/distributions/chisquare_pdf.m,
+	statistics/distributions/chisquare_rnd.m,
+	statistics/distributions/gamma_cdf.m,
+	statistics/distributions/gamma_inv.m,
+	statistics/distributions/gamma_pdf.m,
+	statistics/distributions/gamma_rnd.m,
+	statistics/distributions/normal_cdf.m,
+	statistics/distributions/normal_inv.m,
+	statistics/distributions/normal_pdf.m,
+	statistics/distributions/normal_rnd.m,
+	statistics/distributions/stdnormal_cdf.m,
+	statistics/distributions/stdnormal_pdf.m,
+	statistics/distributions/stdnormal_rnd.m,
+	statistics/distributions/uniform_cdf.m,
+	statistics/distributions/uniform_inv.m,
+	statistics/distributions/uniform_pdf.m,
+	statistics/distributions/uniform_rnd.m:
+	Allow the inputs to be N-d arrays.
+
+	* statistics/base/var.m: Update for N-d arrays.  Allow dimension arg.
+	* statistics/base/median.m: Likewise.
+
+2004-04-02  David Bateman  <dbateman at free.fr>
+
+	* statistics/base/std.m: Allow optional args for type and dim.
+	* statistics/base/center.m, statistics/base/meansq.m,
+	statistics/base/moment.m, statistics/base/range.m:
+	Update for N-d arrays.
+	* signal/fftshift.m: Fix dimensioning error.
+	
+	* statistics/base/std.m: Use repmat not ones(nr,1)*mean to allow
+	N-d arrays.
+	
+	* general/mod.m, general/mod.m: Allow N-d arrays with one scalar arg.
+
+	* signal/fftshift.m: Update for N-d arrays, allow optional dim arg.
+	
+	* specfun/erfinv.m, general/repmat.m: Update for N-d arrays.
+	
+	* control/base/bode.m, control/base/lqg.m, control/system/ss2sys.m,
+	control/system/cellidx.m, control/system/dmr2d.m control/system/ss.m,
+	control/system/sysprune.m: Doc update for usage of cell arrays.
+
+	* control/system/sysidx.m: Use cellidx and not listidx.
+
+2004-03-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__pltopt1__.m: Always add title clause to plot command with
+	default of "" (so it is off unless explicitly set by the user).
+
+2004-03-12  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* image/imshow.m: Accept "truesize" argument.
+	Ignore current colormap.  New tests and demos.
+
+2004-03-10  Volker Kuhlmann  <VolkerKuhlmann at gmx.de>
+
+	* signal/sinewave.m: Allow N to default to M.
+
+2004-03-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* signal/unwrap.m: Use "isempty (tol)" instead of "tol == []".
+
+2004-03-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/deal.m: New function.
+	Add tests from Paul Kienzle.
+
+2004-03-03  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* plot/hist.m: Compute histogram correctly for n>=30.
+
+2004-03-02  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* signal/sinc.m: Use i(:) instead of i when checking for any nonzeros.
+
+2004-03-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/horzcat.m: Delete.
+	* miscellaneous/vertcat.m: Delete.
+
+2004-02-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/figure.m: Also look for GNUTERM in the environment and use
+	that if it is set (for OS X).  From Per Persson <persquare at mac.com>.
+
+2004-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/__stepimp__.m: Only call clearplot if we will be
+	doing multiple plots in the same gnuplot frame.
+
+2004-02-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/system/__sysconcat__.m, control/system/__tfl__.m,
+	control/system/cellidx.m, control/system/ss.m,
+	control/system/tf.m, control/system/zp.m: New functions.
+
+2004-02-16  Glenn Golden  <gdg at zplane.com>
+
+	* statistics/distributions/discrete_inv.m:
+	Reduce memory requirements.
+
+2004-02-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__errcomm__.m: Fix thinko in previous change.
+	From Teemu Ikonen  <tpikonen at pcu.helsinki.fi>.
+
+2004-02-16  A S Hodel  <a.s.hodel at Eng.Auburn.EDU>
+
+	* control/base/__bodquist__.m, control/base/__stepimp__.m,
+	control/base/analdemo.m, control/base/bddemo.m,
+	control/base/bode.m, control/base/dre.m, control/base/frdemo.m,
+	control/base/lqg.m, control/base/nyquist.m, control/base/place.m,
+	control/base/rldemo.m, control/base/rlocus.m,
+	control/base/tzero.m, control/hinf/dgkfdemo.m,
+	control/hinf/dhinfdemo.m, control/hinf/h2syn.m,
+	control/hinf/hinf_ctr.m, control/hinf/hinfsyn.m,
+	control/hinf/wgt1o.m, control/obsolete/dlqg.m,
+	control/obsolete/packsys.m, control/obsolete/series.m,
+	control/system/__sysdefioname__.m,
+	control/system/__sysdefstname__.m, control/system/__sysgroupn__.m,
+	control/system/__tf2sysl__.m, control/system/buildssic.m,
+	control/system/c2d.m, control/system/d2c.m,
+	control/system/dmr2d.m, control/system/fir2sys.m,
+	control/system/is_signal_list.m, control/system/is_siso.m,
+	control/system/jet707.m, control/system/listidx.m,
+	control/system/moddemo.m, control/system/ord2.m,
+	control/system/packedform.m, control/system/parallel.m,
+	control/system/ss2sys.m, control/system/sys2tf.m,
+	control/system/sys2zp.m, control/system/sysadd.m,
+	control/system/sysappend.m, control/system/sysconnect.m,
+	control/system/syscont.m, control/system/sysdimensions.m,
+	control/system/sysdisc.m, control/system/sysdup.m,
+	control/system/sysgetsignals.m, control/system/sysgettype.m,
+	control/system/sysgroup.m, control/system/sysmin.m,
+	control/system/sysmult.m, control/system/sysprune.m,
+	control/system/sysrepdemo.m, control/system/sysscale.m,
+	control/system/syssetsignals.m, control/system/syssub.m,
+	control/system/sysupdate.m, control/system/tf2sys.m,
+	control/system/ugain.m, control/system/zp2ss.m,
+	control/system/zp2sys.m, control/util/__outlist__.m,
+	control/util/__zgpbal__.m, control/util/strappend.m:
+	Use cell arrays instead of lists.
+
+2004-01-23  Stefan van der Walt  <stefan at sun.ac.za>
+
+	* plot/bar.m: Increase size of cutoff vector from xlen-1 to xlen
+	so that bar (1, 1) will work.
+
+2004-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__errcomm__.m: Cope with nargin now being a function.
+	* plot/__errplot__.m: Likewise.
+	* plot/__plt__.m: Likewise.
+	* plot/plot_border.m: Likewise.
+
+	* Makefile.in (distclean, maintainer-clean): Remove DOCSTRINGS,
+	not $(DOCSTRINGS).
+
+2004-01-21  Quentin Spencer  <qspencer at ieee.org>
+
+	* linear-algebra/rank.m: Allow rank ([]) to return 0, same as
+	rank ([], tol).
+
+2004-01-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* elfun/acot.m: Return atan (1./z).
+	From Gregory Vanuxem <g.vanuxem at wanadoo.fr>.
+
+	* miscellaneous/dir.m: New file.
+
+	* general/num2str.m: Use "%d" as format if values are ints with
+	magnitude less than 1e10.
+
+2004-01-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/num2str.m: If single arg is string, return it.
+
+	* miscellaneous/not.m: New file.
+
+	* miscellaneous/unix.m: New file.
+
+	* miscellaneous/isunix.m: New file.
+	* miscellaneous/ispc.m: New file.
+
+	* miscellaneous/computer.m: New file.
+
+	* miscellaneous/delete.m: New file.
+
+2004-01-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/tests/kolmogorov_smirnov_test_2.m: Fix test for ties.
+
+2004-01-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/path.m: Handle DEFAULT_LOADPATH substitution.
+	Always return substituted version of LOADPATH if nargout != 0.
+
+2003-12-21  Schloegl Alois  <alois.schloegl at tugraz.at>
+
+	* miscellaneous/fullfile.m: If filename is empty, set it to "."
+	before continuing.
+
+	* miscellaneous/fileparts.m: Allow name to start with ".".
+
+2003-12-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/ind2sub.m: New file.
+	* general/sub2ind.m: New file.
+
+2003-12-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/system/zp2ss.m: Don't save and restore
+	warn_empty_list_elements.
+
+2003-12-15  Gabriele Pannocchia  <g.pannocchia at ing.unipi.it>
+
+	* control/system/zp2ss.m: Correct definition of pure gain system.
+
+2003-12-10  Quentin Spencer  <qspencer at ieee.org>
+
+	* statistics/base/mean.m: Remove special case for row vectors.
+
+2003-11-19  Quentin Spencer  <qspencer at ieee.org>
+
+	* signal/freqz_plot.m: Save and restore automatic_replot too.
+
+2003-11-18  Danilo Piazzalunga  <danilopiazza at libero.it>
+
+	* statistics/base/iqr.m: Handle matrices.
+
+2003-11-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/issymmetric.m: Don't fail if norm (x) == 0.
+
+2003-11-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/path.m: Fix thinko in previous change.
+
+2003-11-14  Gabriele Pannocchia  <g.pannocchia at ing.unipi.it>
+
+	* control/base/dare.m: Check positive (semi)definiteness and
+	dimensions of r (and q). 
+	* control/base/dlqr.m: Check stabilizability of (A,B),
+	detectability of (A,Q), and whether (A,Q) has non minimal modes
+	near unit circle.
+
+	* control/system/is_detectable.m: Use Hautus Lemma.
+	Correct the behavior for discrete-time systems.
+	* control/system/is_stabilizable.m: Likewise.
+
+	* linear-algebra/krylov.m: Return H = [] in Vnrm == 0 case.
+
+	* linear-algebra/krylovb.m: Fix typo in usage message.
+
+	* general/isdefinite.m: New function.
+
+2003-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/reshape: Delete.
+
+2003-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/numel.m: Delete.
+
+2003-10-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/horzcat.m, miscellaneous/vartcat.m: New files.
+
+	* deprecated/isstr.m: New file.
+
+2003-10-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__axis_label__.m, plot/xlabel.m, plot/ylabel.m,
+	plot/zlabel.m, plot/title.m: Return a value if nargout > 0.
+
+2003-10-02  Quentin Spencer  <qspencer at ieee.org>
+
+	* statistics/base/mean.m: Fix missing semicolon problem.
+
+2003-09-08  Al Niessner  <Al.Niessner at jpl.nasa.gov>
+
+	* plot/subplot.m: New global variable, __multiplot_scale__.
+
+2003-08-29  David Castelow  <DCastelow at Airspan.com>
+
+	* strings/dec2base.m, strings/dec2bin.m, strings/dec2hex.m:
+	Allow optional length argument.
+
+2003-08-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Avoid calling flipud.
+	From Pascal A. Dupuis <Pascal.Dupuis at esat.kuleuven.ac.be>.
+	Return structure as second output value for improved Matlab
+	compatibility.
+
+2003-07-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/cond.m: Behave as though old built-in variable
+	propagate_empty_matrices is always 1.  Also handle empty matrices
+	with one non-zero dimension.
+
+	* miscellaneous/dump_prefs.m: Add warn_separator_insert and
+	warn_single_quote_string to the list.
+	Delete whitespace_in_literal_matrix and propagate_empty_matrices
+	from the list.
+
+2003-07-25  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* signal/autocov.m: Transpose result of conj because diag returns
+	a column vector, not a row vector.
+
+	* audio/playaudio.m, audio/record.m, image/image.m,
+	miscellaneous/bug_report.m: Protect spaces in filenames
+	with quotes.
+
+2003-07-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* io/printf.m, io/puts.m: Delete.
+
+	* miscellaneous/dump_prefs.m: Delete define_all_return_values and
+	default_return_value from the list.
+	Add warn_undefined_return_values to the list.
+	
+
+2003-07-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/dump_prefs.m: Delete default_global_variable_value
+	and initialize_global_variables from the list.
+
+2003-07-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/colormap.m: Don't save and restore default_eval_print_flag.
+
+	* miscellaneous/dump_prefs.m: Delete default_eval_print_flag.
+
+	* control/util/zgshsr.m: Use x OP= y instead of x = x OP y.
+	* control/system/sys2fir.m: Likewise.
+
+	* control/system/is_siso.m: Use && instead of & where appropriate.
+	* control/system/__tf2sysl__.m: Likewise.
+
+	* control/system/__tf2sysl__.m: Use end instead of length(X).
+
+	* control/freqchkw.m: Use %-escapes for error instead of num2str
+	and [] concatenation.
+	* control/system/sys2fir.m: Likewise.
+
+	* control/base/dgram.m, control/base/freqchkw.m,
+	control/base/gram.m, control/system/__abcddims__.m,
+	control/system/__sysdefstname__.m, control/system/__tf2sysl__.m,
+	control/system/is_sample.m, control/system/is_signal_list.m,
+	control/system/is_siso.m, control/system/sys2fir.m,
+	control/system/syschtsam.m, control/system/sysgettsam.m,
+	control/system/sysgettype.m, control/system/tf2zp.m,
+	control/system/ugain.m, control/util/prompt.m,
+	control/util/run_cmd.m, control/util/zgrownorm.m,
+	control/util/zgshsr.m:
+	Improve conformance to Octave coding style.	
+
+	* miscellaneous/dump_prefs.m: Add warn_resize_on_reange_error to
+	the list.
+	Delete resize_on_range_error from the list.
+
+	* control/base/pzmap.m, control/base/place.m,
+	control/base/__freqresp__.m, control/system/sysappend.m,
+	control/system/syscont.m, control/system/sysdisc.m,
+	control/system/sysgroup.m, control/system/tfout.m,
+	control/system/zp2ss.m, control/system/zpout.m,
+	control/util/__outlist__.m, signal/arma_rnd.m, general/shift.m,
+	strings/strcat.m: Save and restore warn_empty_list_elements, not
+	empty_list_elements_ok.
+
+	* miscellaneous/dump_prefs.m: Add warn_empty_list_elements to the list.
+	Delete empty_list_elements_ok from the list.
+
+2003-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/dump_prefs.m: Include warn_neg_dim_as_zero in the
+	list.
+	Delete treat_neg_dim_as_zero from the list.
+
+	* strings/blanks.m: Don't check treat_neg_dim_as_zero.
+
+2003-07-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/reshape.m: Omit do_fortran_indexing from doc string (it
+	was not used in the code in any case).
+
+	* strings/strjust.m: Temporarily set warn_fortran_indexing, not
+	do_fortran_indexing.
+
+	* statistics/base/moment.m: Temporarily set warn_str_to_num, not
+	implict_str_to_num_ok.  Use unwind_protect block to do it.
+
+	* miscellaneous/dump_prefs.m: Include DEFAULT_EXEC_PATH,
+	DEFAULT_LOAD_PATH, crash_dumps_octave_core,
+	sighup_dumps_octave_core, sigterm_dumps_octave_core,
+	warn_imag_to_real, warn_num_to_str, warn_str_to_num, and
+	warn_fortran_indexing in the list.
+	Delete ok_to_lose_imaginary_part, implicit_num_to_str_ok,
+	implicit_str_to_num_ok, do_fortran_indexing, and
+	prefer_column_vectors from list.
+
+2003-07-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (distclean, maintainer-clean): Also remove
+	gethelp$(BUILD_EXEEXT), $(DOCSTRINGS), and autom4te.cache
+	directory.
+
+2003-06-17  Aaron A. King  <king at quercus.tiem.utk.edu>
+
+	* plot/hist.m: Don't forget to define n if x is a vector.
+
+2003-06-13  Alois Schloegl  <alois.schloegl at tugraz.at>
+
+	* miscellaneous/fileparts.m: For compatibility with Matlab,
+	return "." with extension.
+
+2003-06-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/__stepimp__.m, control/base/nichols.m,
+	control/base/nyquist.m, miscellaneous/dump_prefs.m,
+	plot/bottom_title.m, plot/mplot.m, plot/multiplot.m,
+	plot/oneplot.m, plot/plot_border.m, plot/subplot.m,
+	plot/subwindow.m, plot/top_title.m, signal/freqz_plot.m:
+	Eliminate gnuplot_has_multiplot (assume it is always true).
+
+2003-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, image/Makefile.in, startup/Makefile.in: Handle DESTDIR.
+
+2003-05-05  Andy Adler  <adler at site.uottawa.ca>
+
+	* plot/hist.m: Improve performance by using different algorithms
+	depending on number of bins.
+
+2003-05-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/system/sysadd.m: If systems are not "tf", convert before
+	adding.
+
+2003-05-01  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* image/imagesc.m: Accept data limits parameter for colormap.
+
+2003-04-11  Doug Stewart  <dastew at sympatico.ca>
+
+	* control/base/__stepimp__.m: If digital impulse, reduce gain of
+	the impulse by t_step.
+
+2003-04-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/__bodquist__.m: Don't convert pdbig and fdbig to
+	column vectors.
+
+2003-03-24  Quentin Spencer  <qspencer at ieee.org>
+
+	* linear-algebra/null.m: Handle empty matrix arg.
+
+2003-03-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/shift.m: Force empty_list_elements_ok to 1.
+
+2003-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* deprecated/struct_contains.m, deprecated/struct_elements.m:
+	New files.
+
+2003-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/tests/kolmogorov_smirnov_test.m: Use str2func to make
+	function handle to pass to feval.
+	* statistics/base/qqplot.m: Likewise.
+	* statistics/base/ppplot.m: Likewise.
+	* signal/spectral_xdf.m: Likewise.
+	* signal/spectral_adf.m: Likewise.
+
+2003-02-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/axis.m: Avoid whitespace in literal matrix problem.
+
+2003-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/logm.m: New file.
+
+2003-02-18  David Bateman  <dbateman at free.fr>
+
+ 	* mkpkgadd: Scan C++ files as well
+
+2003-02-13  Alois Schloegl  <alois.schloegl at tugraz.at>
+
+	* strings/findstr.m: Return empty set for zero-length target.
+
+2003-02-11  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* set/union.m: Preserve the orientation of inputs.
+
+2003-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/int2str.m: Eliminate leading spaces.
+
+2003-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/int2str.m: Do a better job with 0, Inf, and NaN, 
+
+2003-01-11  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in (gethelp$(BUILD_EXEEXT)): Pass $(BUILD_CXXFLAGS) and
+	$(BUILD_LDFLAGS) to compiler.
+
+2003-01-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/num2str.m: Don't specify field width for scalars.
+
+2003-01-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTFILES): Don't forget mkpkgadd.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* gethelp.cc: Define __USE_STD_IOSTREAM if using Compaq C++.
+
+	* miscellaneous/tempname.m: New file.
+
+	* miscellaneous/tempdir.m: New file.
+
+	* miscellaneous/fullfile.m: New file.
+
+2003-01-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/fileparts.m: New file.
+
+	* io/beep.m: New file.
+
+	* plot/__pltopt1__.m: Call undo_string_escapes for title part of
+	format only.
+
+2003-01-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/strcmp.m: Handle cell arrays of strings.
+
+2002-12-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/int2str.m: Handle matrices.
+	* general/num2str.m: Likewise.
+	Also handle optional precision, and format args.
+
+2002-12-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* audio/Makefile.in, control/base/Makefile.in,
+	control/hinf/Makefile.in, control/obsolete/Makefile.in,
+	control/system/Makefile.in, elfun/Makefile.in,
+	finance/Makefile.in, general/Makefile.in, image/Makefile.in,
+	io/Makefile.in, linear-algebra/Makefile.in,
+	miscellaneous/Makefile.in, polynomial/Makefile.in,
+	quaternion/Makefile.in, set/Makefile.in, signal/Makefile.in,
+	specfun/Makefile.in, special-matrix/Makefile.in,
+	statistics/base/Makefile.in, statistics/distributions/Makefile.in,
+	statistics/models/Makefile.in, statistics/tests/Makefile.in,
+	strings/Makefile.in, time/Makefile.in, plot/Makefile.in,
+	deprecated/Makefile.in: Use new do-script-install and
+	do-script-uninstall macros.
+
+	* mkpkgadd: New script.
+
+	* plot/close.m: New file.
+
+2002-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/image.m: Use -raw option for xv.
+	From Remy Bruno <remy.bruno at libertysurf.fr>
+
+2002-11-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/lsim.m: Use approximate test for step size change.
+
+	* signal/bartlett.m: Avoid row/column mismatch error.
+
+2002-11-12  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* statistics/base/var.m: Use better formula for improved accuracy.
+
+2002-11-04  Nicholas Piper  <nick-octave at nickpiper.co.uk>
+
+	* control/base/lsim.m: Correct doc string.
+
+2002-11-04  A S Hodel  <a.s.hodel at Eng.Auburn.EDU>
+
+	* control/system/syssub.m: Call tf2sys with Gnum-Hnum, not Gnum+Hnum.
+
+2002-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/contour.m: Handle x and y as matrices too.
+
+2002-11-01  Joseph P. Skudlarek  <jskud at jskud.com>
+
+	* plot/contour.m: Fix error and usage messages.
+
+2002-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/contour.m: Correct orientation of plot.
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/analdemo.m: Fix typo.
+
+2002-10-31  Francesco Potorti`  <pot at gnu.org>
+
+	* statistics/distributions/discrete_pdf.m: Fix typo.
+
+2002-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkdoc: Exit immediately on errors.
+	Exit with error if gethelp does not exist.
+
+	* Makefile.in: Use $(BUILD_EXEEXT) as appropriate.
+
+2002-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (gethelp): Use $(BUILD_CXX), not $(CXX).
+
+2002-09-27  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* statistics/distributions/normal_cdf.m: Handle variance == 0.
+	* statistics/distributions/normal_pdf.m: Likewise.
+	* statistics/distributions/normal_inv.m: Likewise.
+
+2002-09-27  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* specfun/erfinv.m: Return NaN for NaN inputs.
+
+2002-09-26  Jeff Cunningham  <jeffrey at cunningham.net>
+
+	* statistics/base/var.m: Handle complex values.
+
+2002-08-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_CONFIG_FILES): Add deprecated/Makefile to the
+	list.
+	* deprecated/Makefile.in: New file.
+
+2002-08-09  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* statistics/distributions/beta_cdf.m: Replace betai with betainc.
+	* statistics/distributions/binomial_cdf.m: Likewise.
+	* statistics/distributions/f_cdf.m: Likewise.
+	* statistics/distributions/t_cdf.m: Likewise.
+
+	* miscellaneous/bincoeff.m: Replace lgamma with gammaln.
+	* specfun/beta.m: Likewise.
+	* special-matrix/invhilb.m: Likewise (but it is only in a comment).
+	* statistics/distributions/gamma_pdf.m: Likewise.
+	* statistics/distributions/poisson_pdf.m: Likewise.
+
+	* statistics/distributions/gamma_cdf.m: replace gammai with gammainc
+	* statistics/distributions/poisson_cdf.m: Likewise.
+
+2002-08-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* deprecated/is_bool.m: New file.
+	* deprecated/is_complex.m: New file.
+	* deprecated/is_global.m: New file.
+	* deprecated/is_list.m: New file.
+	* deprecated/is_matrix.m: New file.
+	* deprecated/is_scalar.m: New file.
+	* deprecated/is_square.m: New file.
+	* deprecated/is_stream.m: New file.
+	* deprecated/is_struct.m: New file.
+	* deprecated/is_symmetric.m: New file.
+	* deprecated/is_vector.m: New file.
+	* Change all callers of these functions to use the new names.
+
+	* deprecated: New directory.
+	* Makefile.in (SUBDIRS): Add it to the list.
+
+	* general/isscalar.m: Rename from is_scalar.m.
+	* general/issquare.m: Rename from is_square.m.
+	* general/issymmetric.m: Rename from is_symmetric.m.
+	* general/isvector.m: Rename from is_vector.m.
+
+2002-08-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/base/mean.m: Allow empty matrices.
+	Handle DIM arg.
+
+2002-08-05  Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* plot/__errcomm__.m: If format is not specified, default to error
+	bar format.
+
+2002-08-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/popen2.m: Use F_SETFL and O_NONBLOCK, not
+	__F_SETFL__ and __O_NONBLOCK__.
+
+	* image/saveimage.m: Use OCTAVE_VERSION, not __OCTAVE_VERSION__.
+	* miscellaneous/bug_report.m: Likewise.
+
+2002-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/mod.m: Use isreal (x), not any (any (imag (x))).
+	* general/rem.m: Likewise.
+
+	* plot/loglogerr.m: Use varargin instead of old style varargs.
+	* plot/semilogxerr.m: Likewise.
+	* plot/semilogyerr.m: Likewise.
+
+2002-07-25  Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* plot/__errcomm__.m: New file.  Common functionality for error plots.
+	* plot/loglogerr.m: New file.  Double logarithm plots with errorbars.
+	* plot/semilogxerr.m: New file.  Semilogarithm plots with errorbars.
+	* plot/semilogyerr.m: New file.  Semilogarithm plots with errorbars
+
+	* plot/errorbar.m: Use __errcomm__.m.
+	* plot/__errplot__.m: Minor cleanups.
+	* plot/__pltopt__.m: Handle boxxyerrorbars plot style. 
+	* plot/__pltopt1__.m: Likewise.
+
+2002-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/rem.m: Delete redundant call to usage.
+
+	* general/mod.m: Additional error checks, Texinfoize doc string.
+
+2002-04-29  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* general/mod.m: New function.
+
+2002-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/system/sysmult.m: Use varargin instead of old style varargs.
+	* control/system/sysadd.m: Likewise.
+	* control/system/sysgroup.m: Likewise.
+	* control/system/syssub.m: Likewise.
+	* elfun/gcd.m: Likewise.
+	* elfun/lcm.m: Likewise.
+	* general/common_size.m: Likewise.
+	* io/printf.m: Likewise.
+	* miscellaneous/menu.m: Likewise.
+	* miscellaneous/path.m: Likewise.
+	* plot/__errplot__.m: Likewise.
+	* plot/__plt__.m: Likewise.
+	* plot/axis.m: Likewise.
+	* plot/errorbar.m: Likewise.
+	* plot/mplot.m: Likewise.
+	* plot/loglog.m: Likewise.
+	* plot/plot.m: Likewise.
+	* plot/plot_border.m: Likewise.
+	* plot/semilogx.m: Likewise.
+	* plot/semilogy.m: Likewise.
+	* plot/xlabel.m: Likewise.
+	* plot/ylabel.m: Likewise.
+	* plot/zlabel.m: Likewise.
+	* statistics/base/ppplot.m: Likewise.
+	* statistics/base/qqplot.m: Likewise.
+	* statistics/tests/bartlett_test.m: Likewise.
+	* statistics/tests/kolmogorov_smirnov_test.m: Likewise.
+	* statistics/tests/kruskal_wallis_test.m: Likewise.
+	* strings/str2mat.m: Likewise.
+	* strings/strcat.m: Likewise.
+
+2002-06-27  Paul Kienzle  <pkienzle at jazz.ncnr.nist.gov>
+
+	* statistics/distributions/gamma_pdf.m: Avoid overflow in more cases.
+
+2002-05-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* skip-autoheader: New file, for autogen.sh.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+2002-04-29  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* general/repmat.m: New function.
+
+2002-04-25  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* audio/lin2mu.m: Accept matrices and [-1,1] normalized audio.
+	Use optional parameter to specify the number of bits in the input.
+	* audio/mu2lin.m: Accept matrices, return n-bit integers or 
+	floats in the range [-1,1], 2x speedup.
+
+	* strings/index.m, strings/rindex.m: Vectorize for speed.
+
+2002-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/kron.m: Delete.
+
+2002-04-24  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* signal/freqz.m: If nargout is zero, plot results instead of
+	returning them.
+	* signal/freqz_plot.m: New file.
+
+2002-04-24  Bill Lash  <lash at tellabs.com>
+
+	* signal/unwrap.m: New file.
+
+2002-04-23  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* image/rgb2hsv.m: Faster, more accurate, remove the
+	divide by zero warning.
+
+2002-04-09  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* strings/deblank.m: Trim \0 as well as blank.
+
+	* freqz.m: Evaluate a specific range of frequencies
+	expressed in radians or Hz relative to a supplied sample rate.
+
+2002-04-04  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* signal/fftfilt.m: Filter columns if called with a matrix.
+
+	* strings/findstr.m: Vectorize as much as possible.
+
+2002-04-04  Dirk Laurie  <dirk at calvyn.puk.ac.za>
+
+	* special-matrix/invhilb.m: New version that is faster and more
+	accurate.
+
+2002-04-03  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* configure.in: Update for autoconf 2.5x.
+
+2002-04-03  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* special-matrix/vander.m: Code tidy and vectorize.
+
+2002-04-02  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* linear-algebra/cross.m: Accept nx3 and 3xn matrices, in addition
+	to vectors.  Issue a warning in the case x matches y' but return a
+	column vector as Octave currently does.
+
+	* plot/contour.m: Set default number of levels for contour(x,y,z).
+
+	* control/system/starp.m: Leave more of the documentation
+	processing to texinfo and less to the @format block.
+
+	* image/imagesc.m: Only display image if no output is requested.
+	Code tidying.
+
+2002-03-07  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+ 
+ 	* statistics/base/center.m: Accept and return empty matrix.
+ 	
+2002-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/erfinv.m: Fix usage message.
+
+2002-02-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* elfun/coth.m: Use 1 ./ tanh(z) instead of cosh(z) ./ sinh(z).
+	From "Michael O'Brien" <mobrien at kento.unm.edu>.
+
+2001-06-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/distributions/discrete_cdf.m: Downcase incorrectly
+	capitalized variable names.
+
+2001-05-30  Jean-Francois Cardoso  <cardoso at tsi.enst.fr>
+
+	* m/image/saveimage.m: fix saving an image to Postscript format.
+
+2001-04-18  A. Scottedward Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* control/system/is_stabilizable.m: Pass a to sys2ss, not sys.
+
+2001-02-28  Kai Habel  <kai.habel at gmx.de>
+
+	* general/cart2pol.m: New file.
+	* general/pol2cart.m: New file.
+	* general/cart2sph.m: New file.
+	* general/sph2cart.m: New file.
+	* image/rgb2hsv.m: New file.
+	* image/hsv2rgb.m: New file.
+
+2001-02-26  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* plot/meshgrid.m: Avoid for loops.
+	* plot/meshdom.m: Likewise.
+
+2001-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/norm.m: Use sqrt instead of ^0.5.
+
+2001-02-22  Heinz Bauschke  <bauschke at cecm.sfu.ca>
+
+	* linear-algebra/norm.m: Use more efficient method for Frobenius
+	norm.
+
+2001-02-09  David Livings  <david.livings at asa.co.uk>
+
+	* statistics/tests/welch_test.m: Fix typo.
+
+	* statistics/distributions/chisquare_cdf.m:
+	Don't restrict inputs to be only positive integers.
+	* statistics/distributions/chisquare_inv.m: Likewise.
+	* statistics/distributions/chisquare_pdf.m: Likewise.
+	* statistics/distributions/chisquare_rnd.m: Likewise.
+	* statistics/distributions/f_cdf.m: Likewise.
+	* statistics/distributions/f_inv.m: Likewise.
+	* statistics/distributions/f_pdf.m: Likewise.
+	* statistics/distributions/f_rnd.m: Likewise.
+	* statistics/distributions/t_cdf.m: Likewise.
+	* statistics/distributions/t_inv.m: Likewise.
+	* statistics/distributions/t_pdf.m: Likewise.
+	* statistics/distributions/t_rnd.m: Likewise.
+
+2001-02-08  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* strings/dec2base.m: New file.
+	* strings/base2dec.m: New file.
+	* strings/strjust.m: New file.
+	* strings/dec2hex.m: Replace with version that just calls 2dec2base.
+	* strings/dec2bin.m: Likewise.
+	* strings/hex2dec.m: Replace with version that just calls base2dec.
+	* strings/bin2dec.m: Likewise.
+
+2001-02-07  David Livings  <david.livings at asa.co.uk>
+
+	* statistics/base/ppplot.m: Use gset, not set.
+	* statistics/base/qqplot.m: Likewise.
+
+2001-02-05  Ondrej Popp  <ondrej at geocities.com>
+
+	* control/system/c2d.m: Add missing endif.
+
+2000-12-15  Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* strings/index.m: Return 0 if either string is empty.
+
+2000-12-15  Ben Sapp  <bsapp at lanl.gov>
+
+	* control/system/c2d.m: Allow option of matched pole/zero
+	equivalent for conversion.  
+
+2000-12-15  Matthew W. Roberts  <matt at lehi.tamu.edu>
+
+	* strings/findstr.m: Return empty matrix if search string is empty.
+
+2000-12-15  Kai Habel  <kai.habel at gmx.de>
+
+	* saveimage.m: Do create rawbit image for black and white images,
+	but do it correctly.
+
+2000-12-13   Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* polynomial/deconv.m: For compatibility with Matlab, don't reduce
+	result polynomials.
+
+2000-12-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: Don't try to create rawbit image.
+
+2000-11-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (bin-dist): Pass -C to $(MAKE), not -c.
+
+2000-11-16  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* plot/contour.m: Reorder args for Matlab compatibility.
+
+2000-10-27  Mats Jansson  <mats.e.jansson at home.se>
+
+	* set/create_set.m: Avoid empty matrix in matrix list warning.
+
+2000-09-08  Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* plot/errorbar.m, plot/__errplot__.m: New functions.
+
+	* plot/mesh.m: Also set nologscale before plotting.
+	* plot/__pltopt1__.m: Handle xerrorbars, yerrorbars, and
+	xyerrorbars instead of just errorbars.
+
+2000-08-25  Thomas Walter  <walter at pctc.chemie.uni-erlangen.de>
+
+	* image/image.m: Try display (from ImageMagick) first.
+
+2000-08-01  Rolf Fabian  <fabian at tu-cottbus.de>
+
+	* plot/meshgrid.m: Use transpose to reorient vectors, not complex
+	conjugate transpose.
+
+2000-07-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/str2mat.m: Apply setstr to each argument.
+
+2000-07-17  Gabriele Pannocchia  <pannocchia at ing.unipi.it>
+
+	* control/base/dkalman.m: New file.
+	* control/base/dlqe.m: Handle singular A matrix.
+	* control/base/dlqr.m: Likewise.
+
+2000-07-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/strcmp.m: Return 0 instead of an error if row and column
+	dimensions don't match.
+
+2000-06-30  Kai Habel  <kahacjde at calvados.zrz.TU-Berlin.DE>
+
+	* plot/hist.m: Allow 3 argument form to work.
+
+2000-06-27  Matthew W. Roberts  <matt at lehi.tamu.edu>
+
+	* plot/plot.m: Add examples in doc string.
+
+2000-06-08  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* control/base/__stepimp__.m: Reset multiplot state when done.
+	Do the right thing even if automatic_replot is not zero.
+	Avoid failure if system has pure imaginary poles.
+
+2000-06-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/logical.m: Return arg if it is empty.  Better error
+	message for non-numeric types.	
+
+2000-05-31  A. Scottedward Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* control/base/dlqe.m: Update documentation.  Fix typo.  Warn
+	about difference with Matlab dlqe function.
+
+	* control/system/sysmult.m: Fix typo in argument dimensions checking.
+
+2000-05-24  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* strings/strrep.m: Fix typo.
+
+2000-05-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/strrep.m: Don't transpose result for case of jump > 0.
+
+2000-05-13  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* strings/strrep.m: Avoid for loop for speed.
+	* plot/axis.m: Handle string options for Matlab compatibility. 
+
+2000-04-04  John Smith  <john at arrows.demon.co.uk>
+
+	* statistics/distributions/beta_inv.m: Provide better(?) initial
+	guess for iteration.
+
+2000-03-31   Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* image/image.m: Allow image (A) or image (x, y, A).
+	* image/imagesc.m: Likewise.
+
+	* image/image.m: If zoom is not supplied, or if it is an empty
+	matrix, autoscale the image.
+
+2000-03-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/title.m, plot/bottom_title.m, plot/top_title.m: 
+	Undo string escapes in text twice(!) before sending to gnuplot.
+
+	* image/saveimage.m: Add comment to file saying who created it and
+	when it was created.  Suggested by Stephen Eglen
+	<stephen at cogsci.ed.ac.uk>.
+
+2000-03-21  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* polynomial/polyreduce.m: Simplify by looking for the first
+	non-zero element rather than the last of the first set of zero
+	elements.
+
+	* plot/__pltopt1__.m: Accept "--", "-.", and ":" line styles.
+
+2000-03-21  Kai Habel  <kahacjde at calvados.zrz.TU-Berlin.DE>
+
+	* image/saveimage.m: Swap black and white colormaps so zero is
+	displayed as black and 1 is displayed as white.
+	Fix indexing bug in ppm case.
+
+2000-03-06  Stephen Eglen  <stephen at anc.ed.ac.uk>
+
+	* statistics/tests/kolmogorov_smirnov_test_2.m: Account for ties
+	between the two distributions (took same approach as ks.test() in R.)
+
+2000-02-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/bode.m: Temporarily disable automatic_replot.
+
+2000-02-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (clean): Also remove gethelp.
+
+	* specfun/erfinv.m: Use z_new in convergence test, not z_old.
+
+2000-02-11  Georg Thimm  <mgeorg at SGraphicsWS1.mpe.ntu.edu.sg>
+
+	* set/create_set.m: Use find to avoid while loop.
+
+2000-02-11  Stephen Eglen  <stephen at cogsci.ed.ac.uk>
+
+	* plot/hist.m: New optional third argument.
+
+2000-02-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/bug_report.m: Use octave-bug script with version
+	number appended.
+
+2000-02-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* gethelp.cc: Sprinkle with std:: qualifier.
+
+2000-01-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: Delete some debugging code.
+
+2000-01-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* signal/sinc.m: Avoid reshaping.
+
+	* image/rgb2ind.m: No longer needs to reset do_fortran_indexing.
+	* image/ind2rgb.m: Ditto.
+	* image/ind2gray.m: Ditto.
+	* general/reshape.m: Ditto.  Also no longer needs to reset
+	implicit_str_to_num_ok.
+
+2000-01-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/popen2.m: Deal with the fact that pipe now returns
+	a list of file structures, not a vector of numeric file ids.
+
+2000-01-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__axis_label__.m: New function.
+	Undo string escapes in text twice(!) before sending to gnuplot.
+	* plot/xlabel.m: Use it.
+	* plot/ylabel.m: Ditto.
+	* plot/zlabel.m: Ditto.
+
+	* plot/mesh.m: Fix error message to reflect reality.
+
+2000-01-24  Cyril Humbert  <humbert at phobos.univ-mlv.fr>
+
+	* statistics/distributions/weibull_pdf.m: Use correct formula.
+
+2000-01-22  Michael Reifenberger  <mike at Plaut.de>
+
+	* audio/saveaudio.m: Also accept files with .ul extension.
+	* audio/loadaudio.m: Ditto.
+	* audio/playaudio.m: Ditto.
+
+2000-01-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/distributions/beta_cdf.m: Texinfoize doc string.
+	* statistics/distributions/beta_inv.m: Ditto.
+	* statistics/distributions/beta_pdf.m: Ditto.
+	* statistics/distributions/beta_rnd.m: Ditto.
+	* statistics/distributions/binomial_cdf.m: Ditto.
+	* statistics/distributions/binomial_inv.m: Ditto.
+	* statistics/distributions/binomial_pdf.m: Ditto.
+	* statistics/distributions/binomial_rnd.m: Ditto.
+	* statistics/distributions/cauchy_cdf.m: Ditto.
+	* statistics/distributions/cauchy_inv.m: Ditto.
+	* statistics/distributions/cauchy_pdf.m: Ditto.
+	* statistics/distributions/cauchy_rnd.m: Ditto.
+	* statistics/distributions/chisquare_cdf.m: Ditto.
+	* statistics/distributions/chisquare_inv.m: Ditto.
+	* statistics/distributions/chisquare_pdf.m: Ditto.
+	* statistics/distributions/chisquare_rnd.m: Ditto.
+	* statistics/distributions/discrete_cdf.m: Ditto.
+	* statistics/distributions/discrete_inv.m: Ditto.
+	* statistics/distributions/discrete_pdf.m: Ditto.
+	* statistics/distributions/discrete_rnd.m: Ditto.
+	* statistics/distributions/empirical_cdf.m: Ditto.
+	* statistics/distributions/empirical_inv.m: Ditto.
+	* statistics/distributions/empirical_pdf.m: Ditto.
+	* statistics/distributions/empirical_rnd.m: Ditto.
+	* statistics/distributions/exponential_cdf.m: Ditto.
+	* statistics/distributions/exponential_inv.m: Ditto.
+	* statistics/distributions/exponential_pdf.m: Ditto.
+	* statistics/distributions/exponential_rnd.m: Ditto.
+	* statistics/distributions/f_cdf.m: Ditto.
+	* statistics/distributions/f_inv.m: Ditto.
+	* statistics/distributions/f_pdf.m: Ditto.
+	* statistics/distributions/f_rnd.m: Ditto.
+	* statistics/distributions/gamma_cdf.m: Ditto.
+	* statistics/distributions/gamma_inv.m: Ditto.
+	* statistics/distributions/gamma_pdf.m: Ditto.
+	* statistics/distributions/gamma_rnd.m: Ditto.
+	* statistics/distributions/geometric_cdf.m: Ditto.
+	* statistics/distributions/geometric_inv.m: Ditto.
+	* statistics/distributions/geometric_pdf.m: Ditto.
+	* statistics/distributions/geometric_rnd.m: Ditto.
+	* statistics/distributions/hypergeometric_cdf.m: Ditto.
+	* statistics/distributions/hypergeometric_inv.m: Ditto.
+	* statistics/distributions/hypergeometric_pdf.m: Ditto.
+	* statistics/distributions/hypergeometric_rnd.m: Ditto.
+	* statistics/distributions/kolmogorov_smirnov_cdf.m: Ditto.
+	* statistics/distributions/laplace_cdf.m: Ditto.
+	* statistics/distributions/laplace_inv.m: Ditto.
+	* statistics/distributions/laplace_pdf.m: Ditto.
+	* statistics/distributions/laplace_rnd.m: Ditto.
+	* statistics/distributions/logistic_cdf.m: Ditto.
+	* statistics/distributions/logistic_inv.m: Ditto.
+	* statistics/distributions/logistic_pdf.m: Ditto.
+	* statistics/distributions/logistic_rnd.m: Ditto.
+	* statistics/distributions/lognormal_cdf.m: Ditto.
+	* statistics/distributions/lognormal_inv.m: Ditto.
+	* statistics/distributions/lognormal_pdf.m: Ditto.
+	* statistics/distributions/lognormal_rnd.m: Ditto.
+	* statistics/distributions/normal_cdf.m: Ditto.
+	* statistics/distributions/normal_inv.m: Ditto.
+	* statistics/distributions/normal_pdf.m: Ditto.
+	* statistics/distributions/normal_rnd.m: Ditto.
+	* statistics/distributions/pascal_cdf.m: Ditto.
+	* statistics/distributions/pascal_inv.m: Ditto.
+	* statistics/distributions/pascal_pdf.m: Ditto.
+	* statistics/distributions/pascal_rnd.m: Ditto.
+	* statistics/distributions/poisson_cdf.m: Ditto.
+	* statistics/distributions/poisson_inv.m: Ditto.
+	* statistics/distributions/poisson_pdf.m: Ditto.
+	* statistics/distributions/poisson_rnd.m: Ditto.
+	* statistics/distributions/stdnormal_cdf.m: Ditto.
+	* statistics/distributions/stdnormal_inv.m: Ditto.
+	* statistics/distributions/stdnormal_pdf.m: Ditto.
+	* statistics/distributions/stdnormal_rnd.m: Ditto.
+	* statistics/distributions/t_cdf.m: Ditto.
+	* statistics/distributions/t_inv.m: Ditto.
+	* statistics/distributions/t_pdf.m: Ditto.
+	* statistics/distributions/t_rnd.m: Ditto.
+	* statistics/distributions/uniform_cdf.m: Ditto.
+	* statistics/distributions/uniform_inv.m: Ditto.
+	* statistics/distributions/uniform_pdf.m: Ditto.
+	* statistics/distributions/uniform_rnd.m: Ditto.
+	* statistics/distributions/weibull_cdf.m: Ditto.
+	* statistics/distributions/weibull_inv.m: Ditto.
+	* statistics/distributions/weibull_pdf.m: Ditto.
+	* statistics/distributions/weibull_rnd.m: Ditto.
+	* statistics/distributions/wiener_rnd.m: Ditto.
+
+2000-01-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/base/values.m: Texinfoize doc string.
+	* statistics/base/var.m: Ditto.
+	* statistics/base/table.m: Ditto.
+	* statistics/base/studentize.m: Ditto.
+	* statistics/base/statistics.m: Ditto.
+	* statistics/base/spearman.m: Ditto.
+	* statistics/base/run_count.m: Ditto.
+	* statistics/base/ranks.m: Ditto.
+	* statistics/base/range.m: Ditto.
+	* statistics/base/qqplot.m: Ditto.
+	* statistics/base/probit.m: Ditto.
+	* statistics/base/ppplot.m: Ditto.
+	* statistics/base/moment.m: Ditto.
+	* statistics/base/meansq.m: Ditto.
+	* statistics/base/logit.m: Ditto.
+	* statistics/base/kendall.m: Ditto.
+	* statistics/base/iqr.m: Ditto.
+	* statistics/base/cut.m: Ditto.
+	* statistics/base/cor.m: Ditto.
+	* statistics/base/cloglog.m: Ditto.
+	* statistics/base/center.m: Ditto.
+	* statistics/models/logistic_regression.m: Ditto.
+	* statistics/models/logistic_regression_derivative.m: Ditto.
+	* statistics/models/logistic_regression_likelihood.m: Ditto.
+	* statistics/tests/anova.m: Ditto.
+	* statistics/tests/bartlett_test.m: Ditto.
+	* statistics/tests/chisquare_test_homogeneity.m: Ditto.
+	* statistics/tests/chisquare_test_independence.m: Ditto.
+	* statistics/tests/cor_test.m: Ditto.
+	* statistics/tests/f_test_regression.m: Ditto.
+	* statistics/tests/hotelling_test.m: Ditto.
+	* statistics/tests/hotelling_test_2.m: Ditto.
+	* statistics/tests/kolmogorov_smirnov_test.m: Ditto.
+	* statistics/tests/kolmogorov_smirnov_test_2.m: Ditto.
+	* statistics/tests/kruskal_wallis_test.m: Ditto.
+	* statistics/tests/manova.m: Ditto.
+	* statistics/tests/mcnemar_test.m: Ditto.
+	* statistics/tests/prop_test_2.m: Ditto.
+	* statistics/tests/run_test.m: Ditto.
+	* statistics/tests/sign_test.m: Ditto.
+	* statistics/tests/t_test.m: Ditto.
+	* statistics/tests/t_test_2.m: Ditto.
+	* statistics/tests/t_test_regression.m: Ditto.
+	* statistics/tests/u_test.m: Ditto.
+	* statistics/tests/var_test.m: Ditto.
+	* statistics/tests/welch_test.m: Ditto.
+	* statistics/tests/wilcoxon_test.m: Ditto.
+	* statistics/tests/z_test.m: Ditto.
+	* statistics/tests/z_test_2.m: Ditto.
+
+2000-01-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/bin2dec.m: Texinfoize doc string.
+	* plot/__plr1__.m: Ditto.
+	* plot/__pltopt__.m: Ditto.
+	* plot/__plt__.m: Ditto.
+	* plot/__plt2vv__.m: Ditto.
+	* plot/__plr2__.m: Ditto.
+	* plot/__plr__.m: Ditto.
+	* plot/__plt1__.m: Ditto.
+	* plot/__plt2__.m: Ditto.
+	* plot/__plt2mm__.m: Ditto.
+	* plot/__plt2mv__.m: Ditto.
+	* plot/__plt2ss__.m: Ditto.
+	* miscellaneous/paren.m: Ditto.
+	* miscellaneous/comma.m: Ditto.
+	* miscellaneous/semicolon.m: Ditto.
+	* miscellaneous/path.m: Ditto.
+	* miscellaneous/list_primes.m: Ditto.
+	* miscellaneous/flops.m: Ditto.
+	* miscellaneous/dump_prefs.m: Ditto.
+	* miscellaneous/bug_report.m: Ditto.
+	* linear-algebra/dot.m: Ditto
+	* linear-algebra/dmult.m: Ditto.
+	* general/randperm.m: Ditto.
+	* general/logical.m: Ditto.
+	* general/is_duplicate_entry.m: Ditto.
+	* signal/arch_fit.m: Ditto.
+	* signal/arch_rnd.m: Ditto.
+	* signal/arch_test.m: Ditto.
+	* signal/arma_rnd.m: Ditto.
+	* signal/autocor.m: Ditto.
+	* signal/autocov.m: Ditto.
+	* signal/autoreg_matrix.m: Ditto.
+	* signal/bartlett.m: Ditto.
+	* signal/blackman.m: Ditto.
+	* signal/detrend.m: Ditto.
+	* signal/diffpara.m: Ditto.
+	* signal/durbinlevinson.m: Ditto.
+	* signal/fftconv.m: Ditto.
+	* signal/fftfilt.m: Ditto.
+	* signal/fftshift.m: Ditto.
+	* signal/fractdiff.m: Ditto.
+	* signal/freqz.m: Ditto.
+	* signal/hamming.m: Ditto.
+	* signal/hanning.m: Ditto.
+	* signal/hurst.m: Ditto.
+	* signal/periodogram.m: Ditto.
+	* signal/rectangle_lw.m: Ditto.
+	* signal/rectangle_sw.m: Ditto.
+	* signal/sinc.m: Ditto.
+	* signal/sinetone.m: Ditto.
+	* signal/sinewave.m: Ditto.
+	* signal/spectral_adf.m: Ditto.
+	* signal/spectral_xdf.m: Ditto.
+	* signal/spencer.m: Ditto.
+	* signal/stft.m: Ditto.
+	* signal/synthesis.m: Ditto.
+	* signal/triangle_lw.m: Ditto.
+	* signal/triangle_sw.m: Ditto.
+	* signal/yulewalker.m: Ditto.
+	* control/util/strappend.m: Ditto.
+	* control/base/nichols.m: Ditto.
+	* control/system/is_signal_list.m: Ditto.
+	* control/system/listidx.m: Ditto.
+	* control/system/sysgettsam.m: Ditto.
+	* control/system/sysidx.m: Ditto.
+
+2000-01-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/system/__abcddims__.m: Rename from
+	control/system/abcddims.m, change all callers.
+	* control/base/__bodquist__.m: Likewise.
+	* control/base/__freqresp__.m: Likewise.
+	* control/util/__outlist__.m: Likewise.
+	* control/base/__stepimp__.m: Likewise.
+	* control/system/__syschnamesl__.m: Likewise.
+	* control/system/__syscont_disc__.m: Likewise.
+	* control/system/__sysdefioname__.m: Likewise.
+	* control/system/__sysdefstname__.m: Likewise.
+	* control/system/__sysgroupn__.m: Likewise.
+	* control/system/__tf2sysl__.m: Likewise.
+	* control/util/__zgpbal__.m: Likewise.
+	* control/system/__zp2ssg2__.m: Likewise.
+
+	* quaternion/demoquat.m: Add copyright notice, Texinfoize doc string.
+	* quaternion/qconj.m: Ditto.
+	* quaternion/qcoordinate_plot.m: Ditto.
+	* quaternion/qderiv.m: Ditto.
+	* quaternion/qderivmat.m: Ditto.
+	* quaternion/qinv.m: Ditto.
+	* quaternion/qmult.m: Ditto.
+	* quaternion/qtrans.m: Ditto.
+	* quaternion/qtransv.m: Ditto.
+	* quaternion/qtransvmat.m: Ditto.
+	* quaternion/quaternion.m: Ditto.
+
+2000-01-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/base/Makefile.in: Ditto.
+	* control/hinf/Makefile.in: New file.
+	* control/marsyas/Makefile.in: Ditto.
+	* control/obsolete/Makefile.in: Ditto.
+	* control/system/Makefile.in: Ditto.
+	* control/util/Makefile.in: Ditto.
+
+	* strings/com2str.m: Move here from control directory.
+
+	* control/base: New directory.
+	* control/base/DEMOcontrol.m: Move here from control directory.
+	* control/base/analdemo.m: Ditto.
+	* control/base/are.m: Ditto.
+	* control/base/bddemo.m: Ditto.
+	* control/base/bode.m: Ditto.
+	* control/base/bode_bounds.m: Ditto.
+	* control/base/bodquist.m: Ditto.
+	* control/base/controldemo.m: Ditto.
+	* control/base/ctrb.m: Ditto.
+	* control/base/damp.m: Ditto.
+	* control/base/dare.m: Ditto.
+	* control/base/dcgain.m: Ditto.
+	* control/base/dgram.m: Ditto.
+	* control/base/dlqe.m: Ditto.
+	* control/base/dlqr.m: Ditto.
+	* control/base/dlyap.m: Ditto.
+	* control/base/dre.m: Ditto.
+	* control/base/frdemo.m: Ditto.
+	* control/base/freqchkw.m: Ditto.
+	* control/base/freqresp.m: Ditto.
+	* control/base/gram.m: Ditto.
+	* control/base/impulse.m: Ditto.
+	* control/base/lqe.m: Ditto.
+	* control/base/lqg.m: Ditto.
+	* control/base/lqr.m: Ditto.
+	* control/base/lsim.m: Ditto.
+	* control/base/ltifr.m: Ditto.
+	* control/base/lyap.m: Ditto.
+	* control/base/nichols.m: Ditto.
+	* control/base/nyquist.m: Ditto.
+	* control/base/obsv.m: Ditto.
+	* control/base/place.m: Ditto.
+	* control/base/pzmap.m: Ditto.
+	* control/base/rldemo.m: Ditto.
+	* control/base/rlocus.m: Ditto.
+	* control/base/step.m: Ditto.
+	* control/base/stepimp.m: Ditto.
+	* control/base/tzero.m: Ditto.
+	* control/base/tzero2.m: Ditto.
+
+	* control/hinf: New directory.
+	* control/hinf/dhinfdemo.m: Move here from control directory.
+	* control/hinf/h2norm.m: Ditto.
+	* control/hinf/h2syn.m: Ditto.
+	* control/hinf/hinf_ctr.m: Ditto.
+	* control/hinf/hinfdemo.m: Ditto.
+	* control/hinf/hinfnorm.m: Ditto.
+	* control/hinf/hinfsyn.m: Ditto.
+	* control/hinf/hinfsyn_chk.m: Ditto.
+	* control/hinf/hinfsyn_ric.m: Ditto.
+	* control/hinf/wgt1o.m: Ditto.
+	* control/hinf/dgkfdemo.m: Ditto.
+	* control/hinf/is_dgkf.m: Ditto.
+
+	* control/marsyas: New directory.
+	* control/marsyas/demomarsyas.m: Move here from control directory.
+	* control/marsyas/susball.m: Ditto.
+
+	* control/obsolete/dezero.m: Move here from control directory.
+	* control/obsolete/rotg.m: Ditto.
+
+	* control/system: New directory.
+	* control/system/abcddim.m: Move here from control directory.
+	* control/system/abcddims.m: Ditto.
+	* control/system/buildssic.m: Ditto.
+	* control/system/c2d.m: Ditto.
+	* control/system/d2c.m: Ditto.
+	* control/system/dmr2d.m: Ditto.
+	* control/system/fir2sys.m: Ditto.
+	* control/system/is_abcd.m: Ditto.
+	* control/system/is_digital.m: Ditto.
+	* control/system/is_sample.m: Ditto.
+	* control/system/is_signal_list.m: Ditto.
+	* control/system/is_siso.m: Ditto.
+	* control/system/is_controllable.m: Ditto.
+	* control/system/is_detectable.m: Ditto.
+	* control/system/is_observable.m: Ditto.
+	* control/system/is_stabilizable.m: Ditto.
+	* control/system/is_stable.m: Ditto.
+	* control/system/jet707.m: Ditto.
+	* control/system/listidx.m: Ditto.
+	* control/system/moddemo.m: Ditto.
+	* control/system/ord2.m: Ditto.
+	* control/system/packedform.m: Ditto.
+	* control/system/parallel.m: Ditto.
+	* control/system/ss2sys.m: Ditto.
+	* control/system/ss2tf.m: Ditto.
+	* control/system/ss2zp.m: Ditto.
+	* control/system/starp.m: Ditto.
+	* control/system/sys2fir.m: Ditto.
+	* control/system/sys2ss.m: Ditto.
+	* control/system/sys2tf.m: Ditto.
+	* control/system/sys2zp.m: Ditto.
+	* control/system/sysadd.m: Ditto.
+	* control/system/sysappend.m: Ditto.
+	* control/system/syschnamesl.m: Ditto.
+	* control/system/syschtsam.m: Ditto.
+	* control/system/sysconnect.m: Ditto.
+	* control/system/syscont.m: Ditto.
+	* control/system/syscont_disc.m: Ditto.
+	* control/system/sysdefioname.m: Ditto.
+	* control/system/sysdefstname.m: Ditto.
+	* control/system/sysdimensions.m: Ditto.
+	* control/system/sysdisc.m: Ditto.
+	* control/system/sysdup.m: Ditto.
+	* control/system/sysgetsignals.m: Ditto.
+	* control/system/sysgettsam.m: Ditto.
+	* control/system/sysgettype.m: Ditto.
+	* control/system/sysgroup.m: Ditto.
+	* control/system/sysgroupn.m: Ditto.
+	* control/system/sysidx.m: Ditto.
+	* control/system/sysmin.m: Ditto.
+	* control/system/sysmult.m: Ditto.
+	* control/system/sysout.m: Ditto.
+	* control/system/sysprune.m: Ditto.
+	* control/system/sysreorder.m: Ditto.
+	* control/system/sysrepdemo.m: Ditto.
+	* control/system/sysscale.m: Ditto.
+	* control/system/syssetsignals.m: Ditto.
+	* control/system/syssub.m: Ditto.
+	* control/system/sysupdate.m: Ditto.
+	* control/system/tf2ss.m: Ditto.
+	* control/system/tf2sys.m: Ditto.
+	* control/system/tf2sysl.m: Ditto.
+	* control/system/tf2zp.m: Ditto.
+	* control/system/tfout.m: Ditto.
+	* control/system/ugain.m: Ditto.
+	* control/system/zp2ss.m: Ditto.
+	* control/system/zp2ssg2.m: Ditto.
+	* control/system/zp2sys.m: Ditto.
+	* control/system/zp2tf.m: Ditto.
+	* control/system/zpout.m: Ditto.
+
+	* control/util: New directory.
+	* control/util/axis2dlim.m: Move here from control directory.
+	* control/util/outlist.m: Ditto.
+	* control/util/prompt.m: Ditto.
+	* control/util/run_cmd.m: Ditto.
+	* control/util/sortcom.m: Ditto.
+	* control/util/strappend.m: Ditto.
+	* control/util/swap.m: Ditto.
+	* control/util/zgfmul.m: Ditto.
+	* control/util/zgfslv.m: Ditto.
+	* control/util/zginit.m: Ditto.
+	* control/util/zgpbal.m: Ditto.
+	* control/util/zgreduce.m: Ditto.
+	* control/util/zgrownorm.m: Ditto.
+	* control/util/zgscal.m: Ditto.
+	* control/util/zgsgiv.m: Ditto.
+	* control/util/zgshsr.m: Ditto.
+
+2000-01-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* gethelp.cc (extract_help_text): Discard first space character
+	after consecutive comment characters.
+
+Thu Jan 13 00:56:57 2000  John W. Eaton  <jwe at bahaha.che.wisc.edu>
+
+	* control/obsolete: New directory
+	* control/obsolete/swaprows.m: Move here from control directory.
+	* control/obsolete/swapcols.m: Ditto.
+	* control/obsolete/dlqg.m: Ditto.
+	* control/obsolete/minfo.m: Ditto.
+	* control/obsolete/packsys.m: Ditto.
+	* control/obsolete/qzval.m: Ditto.
+	* control/obsolete/unpacksys.m: Ditto.
+	* control/obsolete/series.m: Ditto.
+	* control/obsolete/syschnames.m: Ditto.
+	* polynomial/polyout.m: Ditto.
+
+2000-01-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/fliplr.m: Eliminate useless copy of arg.
+	* general/flipud.m: Ditto.
+
+2000-01-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/cross.m: Only return a row vector if both args
+	are row vectors.
+	* polynomial/polyfit.m: Likewise.
+
+	* signal/autocov.m: Don't reset prefer_column_vectors.
+
+	* statistics/distributions/discrete_rnd.m:
+	Always generate a row vector.
+	* statistics/distributions/hypergeometric_rnd.m: Likewise.
+
+2000-01-11  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* strings/upper.m: Add missing `-*- texinfo -*-' tag to doc string.
+
+	* audio/setaudio.m: Texinfoize doc string.
+	* control/com2str.m: Likewise.
+	* control/controldemo.m: Likewise.
+	* control/DEMOcontrol.m: Likewise.
+	* control/dezero.m: Likewise.
+	* control/dre.m: Likewise.
+	* control/hinfsyn_ric.m: Likewise.
+
+2000-01-05  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* io/printf.m: Add @seealso{...} to doc string.
+	* io/puts.m: Likewise.
+	* plot/semilogx.m: Likewise.
+	* plot/semilogy.m: Likewise.
+	* plot/__pltopt__.m: Likewise.
+	* plot/bar.m: Likewise.
+	* plot/xlabel.m: Likewise.
+	* plot/grid.m: Likewise.
+	* plot/shg.m: Likewise.
+	* plot/title.m: Likewise.
+	* plot/mesh.m: Likewise.
+	* plot/__pltopt1__.m: Likewise.
+	* plot/contour.m: Likewise.
+	* plot/hist.m: Likewise.
+	* plot/stairs.m: Likewise.
+	* plot/meshgrid.m: Likewise.
+	* plot/polar.m: Likewise.
+	* plot/loglog.m: Likewise.
+	* plot/plot.m: Likewise.
+	* miscellaneous/semicolon.m: Likewise.
+	* miscellaneous/menu.m: Likewise.
+	* miscellaneous/etime.m: Likewise.
+	* miscellaneous/texas_lotto.m: Likewise.
+	* miscellaneous/comma.m: Likewise.
+	* audio/lin2mu.m: Likewise.
+	* audio/playaudio.m: Likewise.
+	* audio/loadaudio.m: Likewise.
+	* audio/saveaudio.m: Likewise.
+	* audio/mu2lin.m: Likewise.
+	* audio/record.m: Likewise.
+	* strings/isletter.m: Likewise.
+	* strings/lower.m: Likewise.
+	* strings/lower.m: Likewise.
+	* strings/upper.m: Likewise.
+	* specfun/erfinv.m: Likewise.
+	* specfun/gammai.m: Likewise.
+	* specfun/log2.m: Likewise.
+	* specfun/pow2.m: Likewise.
+	* elfun/gcd.m: Likewise.
+	* elfun/lcm.m: Likewise.
+	* special-matrix/vander.m: Likewise.
+	* special-matrix/sylvester_matrix.m: Likewise.
+	* special-matrix/hilb.m: Likewise.
+	* special-matrix/hankel.m: Likewise.
+	* special-matrix/toeplitz.m: Likewise.
+	* special-matrix/invhilb.m: Likewise.
+	* statistics/base/std.m: Likewise.
+	* statistics/base/median.m: Likewise.
+	* linear-algebra/cond.m: Likewise.
+	* linear-algebra/norm.m: Likewise.
+	* finance/nper.m: Likewise.
+	* finance/pmt.m: Likewise.
+	* finance/pv.m: Likewise.
+	* finance/rate.m: Likewise.
+	* finance/npv.m: Likewise.
+	* general/fliplr.m: Likewise.
+	* general/flipud.m: Likewise.
+	* general/is_scalar.m: Likewise.
+	* general/rem.m: Likewise.
+	* general/perror.m: Likewise.
+	* general/tril.m: Likewise.
+	* general/rot90.m: Likewise.
+	* general/num2str.m: Likewise.
+	* general/int2str.m: Likewise.
+	* general/reshape.m: Likewise.
+	* general/logspace.m: Likewise.
+	* general/is_symmetric.m: Likewise.
+	* general/is_vector.m: Likewise.
+	* general/nextpow2.m: Likewise.
+	* general/columns.m: Likewise.
+	* general/is_square.m: Likewise.
+	* general/rows.m: Likewise.
+	* control/ugain.m: Likewise.
+	* control/damp.m: Likewise.
+	* control/dare.m: Likewise.
+	* control/are.m: Likewise.
+	* control/sys2fir.m: Likewise.
+	* control/abcddim.m: Likewise.
+	* control/is_abcd.m: Likewise.
+	* control/step.m: Likewise.
+	* control/is_observable.m: Likewise.
+	* control/is_controllable.m: Likewise.
+	* control/jet707.m: Likewise.
+	* control/polyout.m: Likewise.
+	* control/impulse.m: Likewise.
+	* control/lqg.m: Likewise.
+	* control/is_detectable.m: Likewise.
+	* control/sysdimensions.m: Likewise.
+	* control/sysupdate.m: Likewise.
+	* control/stepimp.m: Likewise.
+	* control/is_stable.m: Likewise.
+	* control/tfout.m: Likewise.
+	* control/zpout.m: Likewise.
+
+2000-01-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* set/complement.m: Add @seealso{} stuff.
+	* set/create_set.m: Likewise.
+	* set/intersection.m: Likewise.
+	* set/union.m: Likewise.
+
+1999-12-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/d2c.m: Use double quotes instead of single quotes for
+	string constants.
+	* control/dgkfdemo.m: Likewise.
+	* control/fir2sys.m: Likewise.
+	* control/frdemo.m: Likewise.
+	* control/moddemo.m: Likewise.
+	* control/minfo.m: Likewise.
+	* control/is_stabilizable.m: Likewise.
+	* control/is_dgkf.m: Likewise.
+	* control/polyout.m: Likewise.
+	* control/sysconnect.m: Likewise.
+	* control/sysrepdemo.m: Likewise.
+	* control/tf2sys.m: Likewise.
+	* control/tfout.m: Likewise.
+	* control/zp2sys.m: Likewise.
+	* control/zpout.m: Likewise.
+	* control/tzero.m: Likewise.
+
+	* control/DEMOcontrol.m: Handle moddemo case too.
+
+	* image/loadimage.m: Use double quotes instead of single quotes
+	for string constants.  Use sprintf instead of square brackets to
+	construct string.
+
+	* control/DEMOcontrol.m: Formatting tweaks.
+	* control/fir2sys.m: Likewise.
+
+1999-12-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkdoc: Only delete spaces before @ characters at the beginning
+	of a line.
+
+1999-12-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/bddemo.m: Make it more likely to work with any value of
+	whitespace_in_literal_matrix.
+	* control/analdemo.m: Ditto.
+	* control/dgkfdemo.m: Ditto.
+	* control/frdemo.m: Ditto.
+	* control/sysrepdemo.m: Ditto.
+	* control/moddemo.m: Ditto.
+	* control/zp2ss.m: Ditto.
+	* control/zp2tf.m: Ditto.
+	* control/syssub.m: Ditto.
+	* finance/npv.m: Ditto.
+	* statistics/base/studentize.m: Ditto.
+	* statistics/base/values.m: Ditto.
+	* statistics/distributions/exponential_cdf.m: Ditto.
+	* statistics/distributions/poisson_cdf.m: Ditto.
+
+	* control/dezero.m: Use toascii to convert string to ASCII value
+	instead of multiplying it by 1.
+
+	* control/zp2sys.m: Don't save and restore implicit_str_to_num_ok.
+	* control/zpout.m: Ditto.
+	* control/tfout.m: Ditto.
+	* control/tf2sys.m: Ditto.
+	* control/syssub.m: Ditto.
+	* control/syssetsignals.m: Ditto.
+	* control/sysout.m: Ditto.
+	* control/sysmult.m: Ditto.
+	* control/sysgroup.m: Ditto.
+	* control/sysdup.m: Ditto.
+	* control/sysdisc.m: Ditto.
+	* control/syscont.m: Ditto.
+	* control/sysconnect.m: Ditto.
+	* control/sysappend.m: Ditto.
+	* control/sysadd.m: Ditto.
+	* control/ss2sys.m: Ditto.
+	* control/nyquist.m: Ditto.
+	* control/lqg.m: Ditto.
+	* control/fir2sys.m: Ditto.
+	* control/dmr2d.m: Ditto.
+	* control/dezero.m: Ditto.
+	* control/d2c.m: Ditto.
+	* control/c2d.m: Ditto.
+	* control/bddemo.m: Ditto.
+	* control/pzmap.m: Ditto.
+
+1999-12-08  Daniel Calvelo  <dcalvelo at pharion.univ-lille2.fr>
+
+	* signal/spectral_adf.m: Fix typo.
+
+1999-11-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/cond.m: Texinfoize doc string.
+	* linear-algebra/kron.m: Ditto.
+	* linear-algebra/norm.m: Ditto.
+	* linear-algebra/null.m: Ditto.
+	* linear-algebra/orth.m: Ditto.
+	* linear-algebra/rank.m: Ditto.
+	* linear-algebra/trace.m: Ditto.
+	* linear-algebra/qzhess.m: Ditto.
+	* miscellaneous/menu.m: Ditto.
+	* general/perror.m: Ditto.
+	* general/strerror.m: Ditto.
+	* general/columns.m: Ditto.
+	* general/rows.m: Ditto.
+	* image/colormap.m: Ditto.
+	* image/gray.m: Ditto.
+	* image/gray2ind.m: Ditto.
+	* image/image.m: Ditto.
+	* image/imagesc.m: Ditto.
+	* image/imshow.m: Ditto.
+	* image/ind2gray.m: Ditto.
+	* image/ind2rgb.m: Ditto.
+	* image/loadimage.m: Ditto.
+	* image/rgb2ntsc.m: Ditto.
+	* image/ntsc2rgb.m: Ditto.
+	* image/ocean.m: Ditto.
+	* image/rgb2ind.m: Ditto.
+	* image/saveimage.m: Ditto.
+	* io/printf.m: Ditto.
+	* io/puts.m: Ditto.
+
+1999-11-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* special-matrix/hankel.m: Texinfoize doc string.
+	* special-matrix/hilb.m: Ditto.
+	* special-matrix/invhilb.m: Ditto.
+	* special-matrix/sylvester_matrix.m: Ditto.
+	* special-matrix/toeplitz.m: Ditto.
+	* special-matrix/vander.m: Ditto.
+	* linear-algebra/vec.m: Ditto.
+	* linear-algebra/vech.m: Ditto.
+	* general/common_size.m: Ditto.
+	* general/diff.m: Ditto.
+	* general/fliplr.m: Ditto.
+	* general/flipud.m: Ditto.
+	* general/rot90.m: Ditto.
+	* general/reshape.m: Ditto.
+	* general/shift.m: Ditto.
+	* general/tril.m: Ditto.
+	* general/triu.m: Ditto.
+	* general/logspace.m: Ditto.
+	* general/nargchk.m: Ditto.
+
+1999-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/base/mean: Texinfoize doc string.
+	* statistics/base/median: Ditto.
+	* statistics/base/std: Ditto.
+	* statistics/base/cov: Ditto.
+	* statistics/base/corrcoef: Ditto.
+	* statistics/base/kurtosis: Ditto.
+	* statistics/base/mahalanobis: Ditto.
+	* statistics/base/skewness: Ditto.
+	* statistics/base/gls.m: Ditto.
+	* statistics/base/ols.m: Ditto.
+	* signal/detrend.m: Ditto.
+	* signal/freqz.m: Ditto.
+	* signal/sinc.m: Ditto.
+	* signal/fftconv.m: Ditto.
+	* signal/fftfilt.m: Ditto.
+	* set/create_set.m: Ditto.
+	* set/union.m: Ditto.
+	* set/intersection.m: Ditto.
+	* set/complement.m: Ditto.
+	* poly/compan.m: Ditto.
+	* poly/conv: Ditto.
+	* poly/deconv: Ditto.
+	* poly/poly: Ditto.
+	* poly/polyderiv: Ditto.
+	* poly/polyfit: Ditto.
+	* poly/polyinteg: Ditto.
+	* poly/polyreduce: Ditto.
+	* poly/polyval: Ditto.
+	* poly/polyvalm: Ditto.
+	* poly/residue: Ditto.
+	* poly/roots: Ditto.
+	* plot/top_title.m: Ditto
+	* plot/subwindow.m: Ditto
+	* plot/subplot.m: Ditto
+	* plot/plot_border.m: Ditto
+	* plot/oneplot.m: Ditto
+	* plot/multiplot.m: Ditto
+	* plot/mplot.m: Ditto
+	* plot/xlabel.m: Ditto
+	* plot/figure.m: Ditto
+	* plot/meshdom.m: Ditto
+	* plot/mesh.m: Ditto
+	* plot/stairs.m: Ditto
+	* plot/polar.m: Ditto
+	* plot/loglog.m: Ditto
+	* plot/hist.m: Ditto
+	* plot/contour.m: Ditto
+	* plot/bar.m: Ditto
+	* plot/axis.m: Ditto
+	* plot/plot.m: Ditto.
+
+1999-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/pinv.m: Delete.
+
+	* Makefile.in (DOCSTRINGS): Don't echo $(ALL_M_FILES).
+
+	* strings/blanks.m: Texinfoize doc string.
+	* strings/strcat.m: Ditto.
+	* strings/str2mat.m: Ditto.
+	* strings/deblank.m: Ditto.
+	* strings/findstr.m: Ditto.
+	* strings/index.m: Ditto.
+	* strings/rindex.m: Ditto.
+	* strings/split.m: Ditto.
+	* strings/strcmp.m: Ditto.
+	* strings/strrep.m: Ditto.
+	* strings/substr.m: Ditto.
+	* general/int2str.m: Ditto.
+	* general/num2str.m: Ditto.
+	* strings/dec2bin.m: Ditto.
+	* strings/bin2dec: Ditto.
+	* strings/dec2bin: Ditto.
+	* strings/dec2hex: Ditto.
+	* strings/hex2dec: Ditto.
+	* strings/str2num: Ditto.
+
+1999-11-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTFILES): Include DOCSTRINGS.
+
+1999-11-09  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* control/DEMOcontrol.m: Texinfoize doc string.
+	* control/abcddim.m: Ditto.
+	* control/abcddims.m: Ditto.
+	* control/analdemo.m: Ditto.
+	* control/are.m: Ditto.
+	* control/axis2dlim.m: Ditto.
+	* control/bddemo.m: Ditto.
+	* control/bode.m: Ditto.
+	* control/bode_bounds.m: Ditto.
+	* control/bodquist.m: Ditto.
+	* control/buildssic.m: Ditto.
+	* control/c2d.m: Ditto.
+	* control/ctrb.m: Ditto.
+	* control/d2c.m: Ditto.
+	* control/damp.m: Ditto.
+	* control/dare.m: Ditto.
+	* control/dcgain.m: Ditto.
+	* control/dgkfdemo.m: Ditto.
+	* control/dgram.m: Ditto.
+	* control/dlqe.m: Ditto.
+	* control/dlqr.m: Ditto.
+	* control/dlyap.m: Ditto.
+	* control/dmr2d.m: Ditto.
+	* control/fir2sys.m: Ditto.
+	* control/frdemo.m: Ditto.
+	* control/freqchkw.m: Ditto.
+	* control/freqresp.m: Ditto.
+	* control/gram.m: Ditto.
+	* control/h2norm.m: Ditto.
+	* control/h2syn.m: Ditto.
+	* control/hinf_ctr.m: Ditto.
+	* control/hinfdemo.m: Ditto.
+	* control/hinfnorm.m: Ditto.
+	* control/hinfsyn.m: Ditto.
+	* control/hinfsyn_chk.m: Ditto.
+	* control/impulse.m: Ditto.
+	* control/is_abcd.m: Ditto.
+	* control/is_controllable.m: Ditto.
+	* control/is_detectable.m: Ditto.
+	* control/is_dgkf.m: Ditto.
+	* control/is_digital.m: Ditto.
+	* control/is_observable.m: Ditto.
+	* control/is_sample.m: Ditto.
+	* control/is_signal_list.m: Ditto.
+	* control/is_siso.m: Ditto.
+	* control/is_stabilizable.m: Ditto.
+	* control/is_stable.m: Ditto.
+	* control/jet707.m: Ditto.
+	* control/lqe.m: Ditto.
+	* control/lqg.m: Ditto.
+	* control/lqr.m: Ditto.
+	* control/lsim.m: Ditto.
+	* control/ltifr.m: Ditto.
+	* control/lyap.m: Ditto.
+	* control/moddemo.m: Ditto.
+	* control/nyquist.m: Ditto.
+	* control/obsv.m: Ditto.
+	* control/ord2.m: Ditto.
+	* control/outlist.m: Ditto.
+	* control/pinv.m: Ditto.
+	* control/place.m: Ditto.
+	* control/polyout.m: Ditto.
+	* control/prompt.m: Ditto.
+	* control/pzmap.m: Ditto.
+	* control/qzval.m: Ditto.
+	* control/rldemo.m: Ditto.
+	* control/rlocus.m: Ditto.
+	* control/sortcom.m: Ditto.
+	* control/ss2sys.m: Ditto.
+	* control/ss2tf.m: Ditto.
+	* control/ss2zp.m: Ditto.
+	* control/starp.m: Ditto.
+	* control/step.m: Ditto.
+	* control/stepimp.m: Ditto.
+	* control/susball.m: Ditto.
+	* control/sys2fir.m: Ditto.
+	* control/sys2ss.m: Ditto.
+	* control/sys2tf.m: Ditto.
+	* control/sys2zp.m: Ditto.
+	* control/sysadd.m: Ditto.
+	* control/sysappend.m: Ditto.
+	* control/syschnames.m: Ditto.
+	* control/syschnamesl.m: Ditto.
+	* control/syschtsam.m: Ditto.
+	* control/sysconnect.m: Ditto.
+	* control/syscont.m: Ditto.
+	* control/syscont_disc.m: Ditto.
+	* control/sysdefioname.m: Ditto.
+	* control/sysdefstname.m: Ditto.
+	* control/sysdimensions.m: Ditto.
+	* control/sysdisc.m: Ditto.
+	* control/sysdup.m: Ditto.
+	* control/sysgetsignals.m: Ditto.
+	* control/sysgettype.m: Ditto.
+	* control/sysgroup.m: Ditto.
+	* control/sysgroupn.m: Ditto.
+	* control/sysmult.m: Ditto.
+	* control/sysout.m: Ditto.
+	* control/sysprune.m: Ditto.
+	* control/sysreorder.m: Ditto.
+	* control/sysrepdemo.m: Ditto.
+	* control/sysscale.m: Ditto.
+	* control/syssetsignals.m: Ditto.
+	* control/syssub.m: Ditto.
+	* control/sysupdate.m: Ditto.
+	* control/tf2ss.m: Ditto.
+	* control/tf2sys.m: Ditto.
+	* control/tf2sysl.m: Ditto.
+	* control/tf2zp.m: Ditto.
+	* control/tfout.m: Ditto.
+	* control/tzero.m: Ditto.
+	* control/tzero2.m: Ditto.
+	* control/ugain.m: Ditto.
+	* control/wgt1o.m: Ditto.
+	* control/zgfmul.m: Ditto.
+	* control/zgfslv.m: Ditto.
+	* control/zginit.m: Ditto.
+	* control/zgpbal.m: Ditto.
+	* control/zgreduce.m: Ditto.
+	* control/zgrownorm.m: Ditto.
+	* control/zgscal.m: Ditto.
+	* control/zgsgiv.m: Ditto.
+	* control/zgshsr.m: Ditto.
+	* control/zp2ss.m: Ditto.
+	* control/zp2ssg2.m: Ditto.
+	* control/zp2sys.m: Ditto.
+	* control/zp2tf.m: Ditto.
+	* control/zpout.m: Ditto.
+
+1999-11-02  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* audio/lin2mu.m: Texinfoize doc string.
+	* audio/loadaudio.m: Ditto.
+	* audio/mu2lin.m: Ditto.
+	* audio/playaudio.m: Ditto.
+	* audio/record.m: Ditto.
+	* audio/saveaudio.m: Ditto.
+
+1999-10-26  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* elfun/acot.m: Texinfoize doc string.
+	* elfun/acsc.m: Ditto.
+	* elfun/acsch.m: Ditto.
+	* elfun/asec.m: Ditto.
+	* elfun/asech.m: Ditto.
+	* elfun/cot.m: Ditto.
+	* elfun/coth.m: Ditto.
+	* elfun/csc.m: Ditto.
+	* elfun/csch.m: Ditto.
+	* elfun/gcd.m: Ditto.
+	* elfun/lcm.m: Ditto.
+	* elfun/sec.m: Ditto.
+	* elfun/sech.m: Ditto.
+	* general/nextpow2.m: Ditto.
+	* general/rem.m: Ditto.
+	* linear-algebra/commutation_matrix.m: Ditto.
+	* linear-algebra/cross.m: Ditto.
+	* linear-algebra/duplication_matrix.m: Ditto.
+	* miscellaneous/bincoeff.m: Ditto.
+	* miscellaneous/xor.m: Ditto.
+	* specfun/bessel.m: Ditto.
+	* specfun/beta.m: Ditto.
+	* specfun/betai.m: Ditto.
+	* specfun/erfinv.m: Ditto.
+	* specfun/gammai.m: Ditto.
+	* specfun/log2.m: Ditto.
+	* specfun/pow2.m: Ditto.
+
+1999-10-23  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* general/is_scalar.m: Texinfoize help text.
+	* general/is_square.m: Ditto.
+	* general/is_symmetric.m: Ditto.
+
+1999-10-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/split.m: If the string to be split is empty, just return
+	an empty string.
+
+1999-10-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (ALL_M_FILES): New macro.
+	(DOCSTRINGS): No longer .PHONY; depend on $(ALL_M_FILES).
+
+1999-10-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/bode.m: Don't return anything if nargout == 0.
+
+1999-10-20  James B. Rawlings  <jbraw at bevo.che.wisc.edu>
+
+	* control/bode.m: Don't do axis scaling for magnitude plots.
+
+1999-10-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTFILES): Add move-if-change, mkdoc, and
+	gethelp.cc to the list.
+
+1999-10-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time/asctime.m: Texinfoize help text.
+	* time/clock.m: Ditto.
+	* time/date.m: Ditto.
+	* miscellaneous/cputime.m: Ditto.
+	* miscellaneous/etime.m: Ditto.
+	* miscellaneous/is_leap_year.m: Ditto.
+	* miscellaneous/popen2.m: Ditto.
+	* miscellaneous/version.m: Ditto.
+	* miscellaneous/tic.m: Ditto.
+	* miscellaneous/toc.m: Just refer to tic.m.
+
+	* Makefile.in (dist, bin-dist): Use `$(MAKE) -C dir' instead of
+	`cd dir; $(MAKE); cd ..'.
+	($(SUBDIRS)): Likewise.
+
+	* statistics/Makefile.in ($(SUBDIRS)): Likewise.
+
+	* statistics/Makefile.in (bin-dist): Use `$(MAKE) -C dir' instead
+	of `cd dir; $(MAKE)'.
+
+	* gethelp.cc, mkdoc: New files.
+	* Makefile.in: Use them to create DOCSTRINGS file from .m file
+	sources.
+
+1999-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/kron.m: Fix typo in previous change
+
+1999-10-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/bode.m: Allow optional 5th arg to specify plot style.
+
+Wed Sep 22 22:12:03 1999 A. Scottedward Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* linear-algebra/krylov.m: Correctly handle case of V having full
+	rank when V has more columns than rows.
+
+Mon Sep 20 23:04:57 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/linspace.m, linear-algebra/pinv.m: Delete.
+
+	* statistics/tests/manova.m: Avoid problems if
+	whitespace_in_literal_matrix is set to "traditional".
+	* statistics/tests/t_test_regression.m: Likewise.
+	* statistics/tests/u_test.m: Likewise.
+	* statistics/tests/chisquare_test_homogeneity.m: Likewise.
+	* statistics/tests/anova.m: Likewise.
+	* statistics/tests/kruskal_wallis_test.m: Likewise.
+	* statistics/base/statistics.m: Likewise.
+	* image/saveimage.m: Likewise.
+	* signal/arch_fit.m: Likewise.
+	* signal/autoreg_matrix.m: Likewise.
+	* signal/triangle_lw.m: Likewise.
+	* strings/dec2hex.m: Likewise.
+
+Thu Sep  9 19:31:58 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: Initialize scale.
+
+Sun Sep  5 22:13:47 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/reshape.m: Allow reshape (a, size (b)).
+
+Fri Sep  3 00:01:38 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/erfinv.m: Improve stopping criterion.
+	Add iteration count as second return value.
+
+Mon Aug 30 12:07:00 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/base/mean.m: Use .', not ' to reorient row vectors.
+
+Tue Aug 17 11:11:27 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/pack.m: New function.
+
+Mon Aug 16 07:46:57 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/figure.m: Always return figure number.  With no args,
+ 	figure now creates a new figure window and returns its number.
+	Accept figure (property, value) syntax, but do nothing.
+
+Thu Aug 12 09:28:01 PDT 1999  Tom Poage  <tfpoage at ucdavis.edu>
+
+	* general/shift.m: Avoid printing temporary value for backward shift.
+
+Mon Aug  2 16:39:04 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/bar.m: Compute bar widths correctly when x-values are not
+	evenly spaced.
+
+Mon Jul 12 22:48:34 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/cond.m: Avoid returning NaN for matrices that
+	contain only zeros.
+
+Sun Jun 20 22:24:27 1999  Eduardo Gallestey  <eduardo at faceng.anu.edu.au>
+
+	* linear-algebra/kron.m: Create result matrix and insert blocks
+	instead of appending them.
+
+Sat Jun 19 01:52:18 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/bodquist.m, control/buildssic.m, control/is_digital.m,
+	control/stepimp.m, control/sysmin.m, control/syssetsignals.m:
+	Update from A. S. Hodel.
+
+Fri Jun 18 12:19:22 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Correct previous change.
+
+Wed Apr  7 13:57:26 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/qrhouse.m, linear-algebra/krygetq.m: Delete.
+
+Wed Apr  7 13:22:43 1999  A. S. Hodel  <a.s.hodel at eng.auburn.edu>
+
+	* control/is_controllable.m, control/zgscal.m: Accomodate new
+	version of krylov and krylovb.
+
+	* control/outlist.m, control/sysout.m: Fix typos.
+
+	* control/sysdimensions.m: Add option for total number of states.
+
+	* linear-algebra/krylov.m: Improve robustness by row-pivoting.
+	* linear-algebra/krylovb.m: Just call krylov with appropriate
+	arguments.
+
+Tue Mar 30 00:43:09 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/index.m: Fail with meaningful error message if either
+	arg is a string array.
+
+Wed Mar 24 20:34:48 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/norm.m: Do the right thing for 1- and
+	infinity-norms of complex matrices.  From Sven Khatri
+	<khatri at saturn.vocalpoint.com>.
+
+Tue Mar 16 13:36:36 1999  A. Scottedward Hodel"  <scotte at eng.auburn.edu>
+
+	* linear-algebra/qrhouse.m: Handle default args correctly.
+
+Thu Mar 11 12:52:34 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/split.m: Avoid problems when splitting strings that have
+	\ in them.
+
+Thu Mar 11 12:36:13 1999  Massimo Lorenzin  <maxlorenzin at tin.it>
+
+	* image/colormap.m: Do better arg checking, handle string args
+	that name the colormap function to call (e.g., colormap ("ocean")).
+
+Mon Mar  8 22:23:24 1999  Rolf Fabian  <fabian at TU-Cottbus.De>
+
+	* polynomial/polyfit.m: Use .' transpose operator, not '.
+	* linear-algebra/dot.m: Likewise.
+	* linear-algebra/cross.m: Likewise.
+	* general/rot90.m: Likewise.
+
+Sat Mar  6 01:45:00 1999  A Scott Hodel  <hodel at edalf1.msfc.nasa.gov>
+
+	* linear-algebra/qrhouse.m: Permute columns at each iteration so
+	that the leading column is not all zeros.
+
+Fri Mar  5 00:37:47 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/shift.m: Fix potential problems with
+	whitespace_in_literal_matrix.
+	* signal/arch_rnd.m: Ditto.
+	* signal/autocov.m: Ditto.
+	* signal/diffpara.m: Ditto.
+	* signal/hurst.m: Ditto.
+	* signal/periodogram.m: Ditto.
+	* signal/spectral_adf.m: Ditto.
+	* signal/spectral_xdf.m: Ditto.
+	* signal/spencer.m: Ditto.
+	* signal/synthesis.m: Ditto.
+	* statistics/distributions/wiener_rnd.m: Ditto.
+	* statistics/models/logistic_regression_likelihood.m: Ditto.
+	* statistics/models/logistic_regression.m: Ditto.
+	* statistics/models/logistic_regression_derivatives.m: Ditto.
+	* statistics/tests/run_test.m: Ditto.
+	* statistics/tests/chisquare_test_independence.m: Ditto.
+
+Wed Mar  3 02:25:00 1999  Joao Cardoso  <jcardoso at inescn.pt>
+
+	* plot/__plr2__.m: Fix typo.
+
+Tue Jan 12 10:31:15 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__pltopt1__.m: Accept "k" to mean black.
+
+Fri Dec 11 10:43:19 1998  A Scott Hodel  <hodel at edalf1.msfc.nasa.gov>
+
+	* linear-algebra/krylov.m: Force empty_list_elements_ok for this
+	function.
+
+Thu Dec 10 11:07:00 1998  A Scott Hodel  <hodel at edalf1.msfc.nasa.gov>
+
+	* control/ss2sys.m: Fix typo.
+
+Wed Dec  9 12:42:19 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/subplot.m, plot/oneplot.m: Don't call clearplot.
+
+	* control: Update from A. S. Hodel <a.s.hodel at eng.auburn.edu> for
+	signal names as lists of strings instead of string arrays.
+
+Fri Dec  4 16:08:42 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* quaternion: New directory of functions from A. S. Hodel
+	<a.s.hodel at eng.auburn.edu>.
+	* Makefile.in (SUBDIRS): Add it to the list.
+	* quaternion/Makefile.in: New file.
+	* configure.in (AC_OUTPUT): Add quaternion/Makefile.
+
+Tue Nov 24 21:41:31 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: Make it work again for black and white colormaps.
+
+	* image/imagesc.m: Use rows (colormap), not length (colormap),
+	since there can be fewer rows than columns.  Round values to
+	nearest position in colormap instead of truncating. Correct usage
+	message.
+
+Tue Nov 24 14:50:52 1998  A Scott Hodel  <hodel at edalf1.msfc.nasa.gov>
+
+	* linear-algebra/krylov.m: New arg pflg.  If nonzero, avoid using
+	zero rows of [A,v] as householder pivots; this avoids spurious
+	non-zero entries in returned orthogonal matrix U, but destroys the
+	Householder matrix structure of H.
+
+Fri Nov 20 12:46:46 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/logical.m: Just copy input to output if argument is
+	already a logical object.
+
+Fri Nov  6 10:17:00 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* New files from OCST, in control subdiretory:
+
+	    DEMOcontrol.m      is_siso.m          syschnames.m
+	    abcddim.m          is_stabilizable.m  syschnamesl.m
+	    abcddims.m         is_stable.m        syschtsam.m
+	    analdemo.m         jet707.m           sysconnect.m
+	    are.m              lqe.m              syscont.m
+	    axis2dlim.m        lqg.m              syscont_disc.m
+	    bddemo.m           lqr.m              sysdefioname.m
+	    bode.m             lsim.m             sysdefstname.m
+	    bode_bounds.m      ltifr.m            sysdimensions.m
+	    bodquist.m         lyap.m             sysdisc.m
+	    buildssic.m        mb.m               sysdup.m
+	    c2d.m              minfo.m            sysgetsignals.m
+	    com2str.m          moddemo.m          sysgettsam.m
+	    controldemo.m      nichols.m          sysgettype.m
+	    ctrb.m             nyquist.m          sysgroup.m
+	    d2c.m              obsv.m             sysgroupn.m
+	    damp.m             ord2.m             sysmult.m
+	    dare.m             outlist.m          sysout.m
+	    dcgain.m           packedform.m       sysprune.m
+	    demomarsyas.m      packsys.m          sysreorder.m
+	    dezero.m;          parallel.m         sysrepdemo.m
+	    dgkfdemo.m         place.m            sysscale.m
+	    dgram.m            polyout.m          syssub.m
+	    dhinfdemo.m        prompt.m           sysupdate.m
+	    dlqe.m             pzmap.m            tf2ss.m
+	    dlqg.m             qzval.m            tf2sys.m
+	    dlqr.m             rldemo.m           tf2sysl.m
+	    dlyap.m            rlocus.m           tf2zp.m
+	    dmr2d.m            rotg.m             tfout.m
+	    fir2sys.m          run_cmd.m;         tzero.m
+	    frdemo.m           series.m           tzero2.m
+	    freqchkw.m         sortcom.m          ugain.m
+	    freqresp.m         ss2sys.m           unpacksys.m
+	    gram.m             ss2tf.m            wgt1o.m
+	    h2norm.m           ss2zp.m            zgfmul.m
+	    h2syn.m            starp.m            zgfslv.m
+	    hinf_ctr.m         step.m             zginit.m
+	    hinfdemo.m         stepimp.m          zgpbal.m
+	    hinfnorm.m         strappend.m;       zgreduce.m
+	    hinfsyn.m          susball.m          zgrownorm.m
+	    hinfsyn_chk.m      swap.m             zgscal.m
+	    impulse.m          swapcols.m         zgsgiv.m
+	    is_abcd.m          swaprows.m         zgshsr.m
+	    is_controllable.m  sys2fir.m          zp2ss.m
+	    is_detectable.m    sys2ss.m           zp2ssg2.m
+	    is_dgkf.m          sys2tf.m           zp2sys.m
+	    is_digital.m       sys2zp.m           zp2tf.m
+	    is_observable.m    sysadd.m           zpout.m
+	    is_sample.m        sysappend.m
+
+Thu Nov  5 13:28:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Escape newlinew in macro call with \.
+
+	* strings/deblank.m: Make it work for string arrays too.
+
+Wed Nov  4 21:51:13 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/housh.m: New file from the OCST.
+	* linear-algebra/krygetq.m: Ditto.
+	* linear-algebra/krylov.m: Ditto.
+	* linear-algebra/krylovb.m: Ditto.
+	* linear-algebra/qrhouse.m: Ditto.
+	* general/is_duplicate_entry.m: Ditto.
+
+	* general/is_symmetric.m: Call is_square instead of doing that
+	check in line.
+
+Wed Oct 28 11:51:14 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/is_square.m: 
+
+	* general/isempty.m, general/is_matrix.m: Delete.
+
+	* general/is_symmetric: Delete special case for strings.  Whether
+	the conversion is valid should depend on implicit_str_to_num_ok.
+
+	* general/is_square.m: If arg is not a matrix, don't check size,
+	just return 0.
+	* general/is_symmetric: Likewise.
+	* general/is_vector.m: Likewise.
+	* general/is_scalar.m: Likewise.
+
+	* general/length.m: Delete.
+
+Fri Oct 23 00:21:55 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in: Add finance/Makefile, statistics/base/Makefile,
+	statistics/distributions/Makefile, statistics/models/Makefile, 
+	and statistics/tests/Makefile to the list of files to create.
+
+	* finance/Makefile.in, statistics/base/Makefile.in,
+	statistics/distributions/Makefile.in, statistics/models/Makefile.in,
+  	statistics/tests/Makefile.in: New files.
+	* statistics/Makefile.in: Delete file lists.  Now only handle
+	subdirectories.
+	* Makefile.in (SUBDIRS): Add finance.
+
+	* Move the following files from statistics to statistics/base:
+
+	    corrcoef.m
+	    kurtosis.m
+	    mahalanobis.m
+	    median.m
+	    ols.m
+	    skewness.m
+	    std.m
+	
+	New files, from Kurt Hornik's octave-ci package:
+
+	* finance (new directory):
+
+	    fv.m
+	    fvl.m
+	    irr.m
+	    nper.m
+	    npv.m
+	    pmt.m
+	    pv.m
+	    pvl.m
+	    rate.m
+	    vol.m
+
+	* linear-algebra/dmult.m
+
+	* signal:
+
+	    arch_fit.m
+	    arch_rnd.m
+	    arch_test.m
+	    arma_rnd.m
+	    autocor.m
+	    autocov.m
+	    autoreg_matrix.m
+	    bartlett.m
+	    blackman.m
+	    diffpara.m
+	    durbinlevinson.m
+	    fractdiff.m
+	    hamming.m
+	    hanning.m
+	    hurst.m
+	    periodogram.m
+	    rectangle_lw.m
+	    rectangle_sw.m
+	    sinetone.m
+	    sinewave.m
+	    spectral_adf.m
+	    spectral_xdf.m
+	    spencer.m
+	    stft.m
+	    synthesis.m
+	    triangle_lw.m
+	    triangle_sw.m
+	    yulewalker.m
+
+	* statistics/base (new directory):
+
+	    center.m
+	    cloglog.m
+	    cor.m
+	    cov.m
+	    cut.m
+	    iqr.m
+	    kendall.m
+	    logit.m
+	    mean.m
+	    meansq.m
+	    moment.m
+	    ppplot.m
+	    probit.m
+	    qqplot.m
+	    range.m
+	    ranks.m
+	    run_count.m
+	    spearman.m
+	    statistics.m
+	    studentize.m
+	    table.m
+	    values.m
+	    var.m
+
+	(Replaces cov.m and mean.m with new versions.)
+
+	* statistics/distributions (new directory):
+
+	    beta_cdf.m
+	    beta_inv.m
+	    beta_pdf.m
+	    beta_rnd.m
+	    binomial_cdf.m
+	    binomial_inv.m
+	    binomial_pdf.m
+	    binomial_rnd.m
+	    cauchy_cdf.m
+	    cauchy_inv.m
+	    cauchy_pdf.m
+	    cauchy_rnd.m
+	    chisquare_cdf.m
+	    chisquare_inv.m
+	    chisquare_pdf.m
+	    chisquare_rnd.m
+	    discrete_cdf.m
+	    discrete_inv.m
+	    discrete_pdf.m
+	    discrete_rnd.m
+	    empirical_cdf.m
+	    empirical_inv.m
+	    empirical_pdf.m
+	    empirical_rnd.m
+	    exponential_cdf.m
+	    exponential_inv.m
+	    exponential_pdf.m
+	    exponential_rnd.m
+	    f_cdf.m
+	    f_inv.m
+	    f_pdf.m
+	    f_rnd.m
+	    gamma_cdf.m
+	    gamma_inv.m
+	    gamma_pdf.m
+	    gamma_rnd.m
+	    geometric_cdf.m
+	    geometric_inv.m
+	    geometric_pdf.m
+	    geometric_rnd.m
+	    hypergeometric_cdf.m
+	    hypergeometric_inv.m
+	    hypergeometric_pdf.m
+	    hypergeometric_rnd.m
+	    kolmogorov_smirnov_cdf.m
+	    laplace_cdf.m
+	    laplace_inv.m
+	    laplace_pdf.m
+	    laplace_rnd.m
+	    logistic_cdf.m
+	    logistic_inv.m
+	    logistic_pdf.m
+	    logistic_rnd.m
+	    lognormal_cdf.m
+	    lognormal_inv.m
+	    lognormal_pdf.m
+	    lognormal_rnd.m
+	    normal_cdf.m
+	    normal_inv.m
+	    normal_pdf.m
+	    normal_rnd.m
+	    pascal_cdf.m
+	    pascal_inv.m
+	    pascal_pdf.m
+	    pascal_rnd.m
+	    poisson_cdf.m
+	    poisson_inv.m
+	    poisson_pdf.m
+	    poisson_rnd.m
+	    stdnormal_cdf.m
+	    stdnormal_inv.m
+	    stdnormal_pdf.m
+	    stdnormal_rnd.m
+	    t_cdf.m
+	    t_inv.m
+	    t_pdf.m
+	    t_rnd.m
+	    uniform_cdf.m
+	    uniform_inv.m
+	    uniform_pdf.m
+	    uniform_rnd.m
+	    weibull_cdf.m
+	    weibull_inv.m
+	    weibull_pdf.m
+	    weibull_rnd.m
+	    wiener_rnd.m
+	
+	* statistics/models (new directory):
+
+	    logistic_regression.m
+	    logistic_regression_derivatives.m
+	    logistic_regression_likelihood.m
+
+	* statistics/tests (new directory):
+
+	    anova.m
+	    bartlett_test.m
+	    chisquare_test_homogeneity.m
+	    chisquare_test_independence.m
+	    cor_test.m
+	    f_test_regression.m
+	    hotelling_test.m
+	    hotelling_test_2.m
+	    kolmogorov_smirnov_test.m
+	    kolmogorov_smirnov_test_2.m
+	    kruskal_wallis_test.m
+	    manova.m
+	    mcnemar_test.m
+	    prop_test_2.m
+	    run_test.m
+	    sign_test.m
+	    t_test.m
+	    t_test_2.m
+	    t_test_regression.m
+	    u_test.m
+	    var_test.m
+	    welch_test.m
+	    wilcoxon_test.m
+	    z_test.m
+	    z_test_2.m
+
+Thu Oct 22 12:25:55 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time/date.m: Use %Y, not %y in format string, for Matlab 5
+	compatibility and to avoid Y2K problems.
+
+Mon Oct 19 17:26:35 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Just use the \ operator to handle the
+	least-squares solution.
+
+Thu Sep  3 12:40:47 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/str2num.m: If eval returns a string, return an empty matrix.
+
+	* strings/strrep.m: Don't convert args to numeric values.
+	Prevent warnings for empty string args.
+	From Georg Thimm <thimm at idiap.ch>.
+
+	* strings/strcat.m: Prevent warnings for empty string args.
+
+Wed Sep  2 17:20:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/menu.m: Remove special case for empty string
+	returned from input().  Add second arg to eval() to catch errors.
+
+Thu Jun 18 16:32:15 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__plt__.m: Don't call usleep.
+
+Mon May 18 11:42:36 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/dot.m: New function.
+
+	* strings/lower.m, strings/upper.m: New functions, for Matlab
+	compatibility.
+
+Fri May 15 01:16:53 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/hist.m: Also allow just one output argument.
+
+Sun May 10 23:00:45 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/deblank.m: Make it work if the string is only blanks.
+
+Tue May  5 00:53:36 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__plt2mv__.m: Delete calls to keyboard.
+
+Mon May  4 11:43:31 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/oneplot.m: Fix typo.
+
+Wed Apr 22 12:11:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/flops.m: Allow a single argument too.
+
+Tue Apr 21 10:18:20 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/str2mat.m: Also handle case when there are no empty
+	strings correctly.
+
+Mon Apr 20 22:14:15 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/isletter.m: New function, for Matlab compatibility.
+
+Fri Apr 17 10:53:39 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/str2mat.m: Handle string matrices too.
+
+Wed Apr 15 11:16:01 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* audio/loadaudio.m: Accept "pcm" as another file extension for
+	linear encoding.
+
+	* audio/saveaudio.m, audio/loadaudio.m, audio/playaudio.m,
+	audio/record.m: Open files in binary mode.
+
+Fri Apr 10 10:46:21 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/dump_prefs.m: Use string array for list of values.
+	Move functionality of dump_1_pref here, but use built-in function
+	type to extract value, and put it inside try/catch block.
+	* miscellaneous/dump_1_pref.m: Delete unused function.
+
+Wed Apr  8 13:17:58 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__pltopt1.m__: New file.
+	* plot/__pltopt.m__: Handle opt as a string array by calling
+	__pltopt1__ multiple times and returning a string array with rows
+	corresponding to the rows of opt.
+	* plot/__plt2ss__.m, plot/__plt2vv__.m, plot/__plt2vm__.m,
+	plot/__plt2mv__.m, plot/__plt2mm__.m: Handle fmt as a string
+	array.
+
+Fri Mar 27 03:00:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/mplot.m: Fix misspellings of global variables.
+	Don't call clearplot.
+
+Tue Mar 17 17:45:25 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/subplot.m, plot/multiplot.m: Set gnuplot_command_replot to
+	"cle;rep" when going in ot multiplot mode.
+	* plot/oneplot.m: Reset gnuplot_command_replot to "rep" when
+	switching out of multiplot mode.
+
+Fri Feb 20 01:31:32 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/mplot.m, plot/subplot.m, plot/oneplot.m, plot/multiplot.m,
+	plot/subwindow.m: Call clearplot after setting up multiplot mode.
+
+Tue Feb  3 00:18:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* special-matrix/sylvester_matrix.m: Rename from hadamard.m
+
+	* miscellaneous/bug_report.m: Don't try to get smart with
+	OCTAVE_HOME.  Assume octave-bug can be found in EXEC_PATH.
+
+	* Makefile.in (install): Create separate ls-R files for
+	$(datadir) and $(libexecdir).
+	(uninstall): Remove both ls-R files.
+
+Sat Jan 31 01:09:32 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* signal/fftshift.m: New file.
+
+	* plot/contour.m: Fix for non-square case.
+
+	* general/randperm.m: New file.
+
+Fri Jan 30 15:20:39 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/betai.m: Restore file for compatibility with previous
+	versions.  Call betainc with reordered args.
+	* specfun/gammai.m: Likewise, call gammainc with reordered args.
+
+Wed Jan 28 22:44:59 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/contour.m: Handle discrete contour levels.
+
+Tue Jan 27 04:31:22 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/lyap.m: For compatibility with Matlab, solve
+ 	A*X + X*A' + C = 0 instead of A'*X + X*A + C = 0.
+
+Wed Dec 10 00:14:29 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/bessel.m: New file.
+
+	* specfun/betai.m, specfun/betainc.m, specfun/gammai.m,
+	specfun/gammainc.m: Delete.
+
+Wed Nov 19 00:19:18 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/colormap.m: Initialize __current_color_map__ in global
+	statement.
+	* miscellaneous/toc.m: Initialize __tic_toc_timestamp__ in global
+	statement.
+	* plot/axis.m: Initialize __current_axis__ in global statement.
+	* plot/mplot.m, plot/multiplot.m, plot/oneplot.m, plot/subplot.m,
+	plot/subwindow.m: Initialize __multiplot_mode__ in global statement.
+
+Tue Nov 18 01:35:50 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time/tic.m: Rename _time_tic_called to __tic_toc_timestamp__.
+	* time/toc.m: Likewise.
+
+	* image/colormap.m: Rename CURRENT_COLOR_MAP to __current_color_map__.
+
+	* plot/mplot.m, plot/multiplot.m, plot/subplot.m: Don't do
+	anything special for automatic_replot when in multiplot mode --
+	recent 3.6beta releases handle this correctly.
+
+	* plot/figure.m: Ensure that we are not in multiplot mode before
+	setting the terminal type.
+
+	* plot/mplot.m, plot/multiplot.m, plot/oneplot.m, plot/subplot.m,
+ 	plot/subwindow.m: Use leading and trailing underscores for
+ 	`private' globals.
+
+	* plot/oneplot.m: Don't do anything if gnuplot_has_multiplot is false.
+
+Fri Nov 14 10:53:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__pltopt__.m: Use sprintf instead of strcat when adding TITLE.
+
+Fri Oct 10 11:18:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/gammai.m: Avoid problems with whitespace when
+	constructing matrices.
+
+	* polynomial/polyfit.m: Compute yf correctly.  From Seung Lee
+	<SJL at nrc.gov>.  Also return yf in the same orientation as the
+	original y vector.
+
+Fri Sep 19 17:04:40 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/cross.m: Use direct formula instead of calling
+	det three times in a loop.  If both args are column (row) vectors,
+	return a column (row) vector.  If they don't match, pay attention
+	to the value of prefer_column_vectors.
+
+Thu Aug 28 15:31:20 1997  Rolf Fabian  <fabian at olymp.Umwelt.TU-Cottbus.de>
+
+	* polynomial/polyvalm.m: Don't assume orthogonal eigenvectors for
+	nonsymmetric matrices.
+
+	* general/tril.m: Fix usage message.
+
+	* polynomial/polyvalm.m: Fix error messages.
+	* polynomial/polyderiv.m: Likewise.
+	* polynomial/polyval.m: Likewise.
+
+Wed Aug 13 14:14:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/blanks.m: Allow blanks(0) to return empty string.
+	Allow negative arguments if treat_neg_dim_as_zero is true.
+
+Wed Jun 25 21:26:24 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/mesh.m: Set noparametric plot mode after plotting.
+
+Wed Jun 25 21:06:10 1997  Rick Niles  <niles at axp745.gsfc.nasa.gov>
+
+	* plot/__pltopt__.m: Handle key/legend names.
+	Correctly set colors, line styles, and point styles.
+
+Wed Jun 25 13:34:06 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Return fit y values as second output.
+	Don't use QR factorization to solve least squares problem.
+
+Wed Jun 18 10:24:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/dlqr.m: Use ao, not a, to compute k.
+
+Tue Jun  3 12:16:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/path.m: New file.
+
+Wed May 21 11:45:31 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/bug_report.m: Pass file id to dump_prefs, not file
+	name.
+
+Mon May 12 02:04:01 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/erfinv.m: Add missing semicolon.
+
+Wed Apr  2 22:04:03 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/xor.m: Make type of return value logical.
+
+Fri Mar 28 16:19:53 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/dump_prefs.m: Delete call to dump_1_pref for
+	warn_comma_in_global_decl.
+
+Tue Mar 25 22:00:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/bug_report.m: Use __OCTAVE_HOME__ to find
+	octave-bug script.
+
+Mon Mar 24 16:49:47 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/dump_prefs.m: Delete call to dump_1_pref for
+	prefer_zero_one_indexing.
+
+	* general/logical.m: New file.
+
+Sat Mar 15 15:07:30 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/nextpow2.m: Correctly handle new meaning of is_scalar()
+	and is_vector().
+
+Thu Mar 13 16:36:35 1997  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* specfun/erfinv.m: Scale update by sqrt (pi) / 2.
+	Use tolerance of 2 * eps.
+
+Wed Mar 12 16:57:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-strip): New target.
+	* audio/Makefile.in: Ditto.
+	* control/Makefile.in: Ditto.
+	* elfun/Makefile.in: Ditto.
+	* general/Makefile.in: Ditto.
+	* image/Makefile.in: Ditto.
+	* io/Makefile.in: Ditto.
+	* linear-algebra/Makefile.in: Ditto.
+	* miscellaneous/Makefile.in: Ditto.
+	* plot/Makefile.in: Ditto.
+	* polynomial/Makefile.in: Ditto.
+	* set/Makefile.in: Ditto.
+	* signal/Makefile.in: Ditto.
+	* specfun/Makefile.in: Ditto.
+	* special-matrix/Makefile.in: Ditto.
+	* startup/Makefile.in: Ditto.
+	* statistics/Makefile.in: Ditto.
+	* strings/Makefile.in: Ditto.
+
+Tue Mar 11 10:14:26 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* elfun/coth.m: Write as cosh(x) ./ sinh(x) instead of 1 ./ tanh(x).
+
+Fri Mar  7 23:06:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/corrcoef.m: Make it actually work.
+
+Thu Mar  6 12:36:30 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/corrcoef.m: Don't fail if single argument is a matrix.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.5 released.
+
+Wed Feb 26 01:48:28 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (maintainer-clean): Also remove configure.
+
+	* signal/fftconv.m: Check inputs with is_vector(), not is_matrix().
+
+	* general/is_matrix.m: Return zero for empty matrices.
+
+Tue Feb 25 15:16:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/vech.m: Size result just once.
+
+Sun Feb 23 00:15:57 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/is_square.m: Handle empty matrices correctly.
+	* general/is_symmetric.m: Handle empty matrices and strings.
+
+Sat Feb 22 01:06:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/conv.m: Check inputs with is_vector(), not is_matrix().
+	* polynomial/deconv.m: Likewise.
+	* polynomial/polyderiv.m: Likewise.
+	* polynomial/polyinteg.m: Likewise.
+	* polynomial/polyreduce.m: Likewise.
+	* polynomial/polyval.m: Likewise.
+	* polynomial/polyvalm.m: Likewise.
+	* general/postpad.m: Likewise.
+	* general/prepad.m: Likewise.
+
+	* polynomial/compan.m: Check input with is_vector(), not
+	is_matrix().  Handle scalar case.
+
+Fri Feb 21 13:36:58 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/contour.m: Order data so that it is consistent with
+	meshgrid and mesh.
+
+	* plot/meshdom.m, plot/meshgrid.m: Change help message.
+	* plot/sombrero.m: Use meshgrid, not meshdom.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+Wed Feb 19 10:30:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/paren.m: New file.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.3 released.
+
+Thu Feb 13 19:06:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: Only clip image data that is actually out of
+	range.
+
+Sun Feb  9 19:52:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/is_matrix.m: Scalars, vectors, and empty matrices may
+	also be considered to be matrices.
+
+	* general/is_vector.m: Scalars may also be considered to be vectors.
+
+	* general/isempty.m: Use size(), not rows() and columns().
+
+	* plot/contour.m: Convert set to gset.
+	Set view to 0, 0, 1, 1, not 0, 0, 1.9, 1.
+
+Fri Feb  7 12:55:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/erfinv.m: Fix typo in last change.
+
+Fri Jan 31 09:30:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/loadimage.m: Make it possible to load files with image
+	data named X or img.
+
+	* image/default.img: Change name of image from X to img to match
+	what saveimage does now.
+
+	* image/loadimage.m: Rename X to be img, to match what saveimage
+	does now.
+
+Mon Jan 27 13:48:31 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+	* plot/__plt__.m: Use usleep() instead of replot to try to avoid
+	weird missing-lines bug without creating extra plots unecessarily.
+
+Sat Jan 25 22:37:07 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in, audio/Makefile.in, control/Makefile.in,
+	elfun/Makefile.in, general/Makefile.in, image/Makefile.in,
+	io/Makefile.in, linear-algebra/Makefile.in,
+	miscellaneous/Makefile.in, plot/Makefile.in,
+	polynomial/Makefile.in, set/Makefile.in, signal/Makefile.in,
+	specfun/Makefile.in, special-matrix/Makefile.in,
+	startup/Makefile.in, statistics/Makefile.in, strings/Makefile.in,
+	time/Makefile.in (bin-dist): New target.
+
+Wed Jan 22 11:28:30 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/erfinv.m: Avoid A([]) = X, X != [] error.
+
+Tue Jan 21 11:16:40 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/xor.m: Make it work.
+
+Mon Jan 20 12:28:34 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/sombrero.m: Doc fix.
+
+Tue Jan  7 00:16:52 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Thu Dec 19 22:16:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* elfun/lcm.m: Replace missing if statement.
+
+	* elfun/gcd.m: Report error if no input args.
+	* elfun/lcm.m: Likewise.
+
+Mon Dec 16 15:23:04 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install): Use ls -LR to create ls-R database.
+	Also list contents of $libexecdir/octave in ls-R database.
+
+Tue Dec 10 01:43:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+Fri Dec  6 15:23:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.94.
+
+Sun Dec  1 20:55:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/str2num.m: New file.
+
+Wed Nov 20 01:00:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.93.
+
+Tue Nov 19 15:13:35 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* linear-algebra/commutation_matrix.m, linear-algebra/cross.m,
+	linear-algebra/duplication_matrix.m, linear-algebra/vec.m,
+	linear-algebra/vech.m: New files from Kurt Hornik.
+
+	* general/nextpow2.m, general/shift.m, general/diff.m,
+	general/common_size.m: New files from Kurt Hornik.
+
+	* miscellaneous/bincoeff.m, miscellaneous/xor.m:
+	New files from Kurt Hornik.
+
+	* signal/detrend.m: New file from Kurt Hornik.
+
+	* specfun/betai.m, specfun/gammai.m, specfun/erfinv.m,
+	specfun/pow2.m, specfun/log2.m:
+	New files and updates from Kurt Hornik.
+
+Fri Nov 15 18:13:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/__plt__.m: Add explicit replot after last command is
+	issued, to force all lines to be displayed.  Hmm.
+
+Thu Nov 14 00:06:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/axis.m, plot/bottom_title.m, plot/contour.m,
+	plot/figure.m, plot/grid.m, plot/loglog.m, plot/mesh.m,
+	plot/mplot.m, plot/multiplot.m, plot/oneplot.m, plot/plot.m,
+	plot/plot_border.m, plot/polar.m, plot/semilogx.m,
+	plot/semilogy.m, plot/subplot.m, plot/subwindow.m, plot/title.m,
+	plot/top_title.m, plot/xlabel.m, plot/ylabel.m, plot/zlabel.m:
+	Uset gset, not set.
+
+	* Version 1.92.
+
+Thu Nov  7 12:43:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: When writing PostScript, name Octave as the
+	almighty Creator.  Use single call to fprintf instead of looping.
+
+	* image/Makefile.in: Delete references to octtopnm.
+
+	* general/logspace.m: Doc fix.
+
+	* Version 1.91.
+
+Sat Nov  2 21:06:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/image.m: Use tmpnam() instead of home-brew scheme.
+
+	* audio/record.m, audio/playaudio.m: Use tmpnam() instead of
+	octave_tmp_file_name().  Use unwind_protect to ensure tmp file is
+	deleted.
+	* miscellaneous/bug_report.m: Likewise.  Also use unlink() instead
+	of a system() command to delete the tmp file.
+
+Wed Oct 30 17:19:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* Makefile.in (DISTFILES): Add ChangeLog.
+
+Thu Oct 10 17:31:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/subplot.m, plot/multiplot.m, plot/mplot.m:
+	Don't check for string value of automatic_replot.
+
+	* image/ind2ind.m, image/ind2rgb.m, image/ind2gray.m:
+	Temporarily set do_fortran_indexing to 1, not "true".
+
+	* miscellaneous/menu.m: Temporarily set page_screen_output to 0,
+	not "false".
+
+	* linear-algebra/cond.m: Don't compare propagate_empty_matrices to
+	"false".
+
+Tue Aug 20 18:27:36 1996  Kurt Hornik  <Kurt.Hornik at ci.tuwien.ac.at>
+
+	* strings/substr.m: Allow negative OFFSET.  LEN is now optional.
+
+Mon Jul 15 16:15:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/bug_report.m: Don't redirect output to /dev/tty in
+	system command.
+	
+Fri Jul 12 12:24:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* __plr1__.m: Renamed from polar_int_1.m.
+	* __plr2__.m: Renamed from polar_int_2.m.
+	* __plr__.m: Renamed from polar_int.m.
+	* __plt1__.m: Renamed from plot_int_1.m.
+	* __plt2__.m: Renamed from plot_int_2.m.
+	* __plt2mm__.m: Renamed from plot_2_m_m_.m.
+	* __plt2mv__.m: Renamed from plot_2_m_v_.m.
+	* __plt2ss__.m: Renamed from plot_2_s_s_.m.
+	* __plt2vm__.m: Renamed from plot_2_v_m_.m.
+	* __plt2vv__.m: Renamed from plot_2_v_v_.m.
+	* __plt__.m: Renamed from plot_int.m.
+	* __pltopt__.m: Renamed from plot_opt.m.
+	Change all callers.
+
+Thu Jul 11 17:24:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* All .m files: Add regular Author:, Created:, and Adapted-By:
+	comments like those found in Emacs lisp files.
+
+Mon Jun 24 04:16:41 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* All .m files: Change comment style.
+
+Fri Jun 14 01:42:21 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* bottom_title.m, mplot.m, multiplot.m, oneplot.m, plot_border.m,
+	subplot.m, subwindow.m, top_title.m:
+	Print error message if gnuplot_has_multiplot is not true.
+
+Thu Jun  6 00:18:54 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/figure.m: New function.
+
+Wed Jun  5 18:19:00 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/strrep.m: New function.
+
+Thu May 23 15:04:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strings/bin2dec.m, strings/blanks.m, strings/deblank.m,
+	strings/dec2bin.m, strings/dec2hex.m, strings/findstr.m,
+	strings/hex2dec.m, strings/index.m, strings/rindex.m,
+	strings/split.m, strings/str2mat.m, strings/substr.m:
+	New functions from Kurt Hornik, heavily modified by jwe.
+
+	* general/reshape.m: Allow strings to be reshaped too.
+
+	* strings/strcmp.m: No longer need to set implicit_str_to_num_ok.
+	Always return a scalar.
+
+Wed May 22 19:52:11 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Make orientation of result compatible with
+	Matlab.
+
+Sat May 18 17:32:15 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Add missing close paren.
+
+Thu May 16 10:23:11 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/plot_opt.m: Set compatibility arg in call to sscanf.
+
+	* io/scanf.m: Delete.
+
+Mon May 13 09:37:38 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/median.m: Fix typo in usage message.
+
+Wed Apr 24 02:45:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/popen2.m: New file.
+
+Wed Apr 17 18:34:04 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Add io/Makefile.
+
+	* io: New directory.
+	* Makefile.in (SUBDIRS): Add it to the list.
+
+	* miscellaneous/flops.m: New file.
+
+Fri Mar 22 04:40:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/cputime.m: Return three arguments instead of a
+	vector, for compatibility with previous versions and with Matlab
+	(which only returns one scalar value).
+
+Wed Mar 20 05:09:48 1996  Kurt Hornik  <Kurt.Hornik at tuwien.ac.at>
+
+	* general/triu.m: Compute lower bound on loop index correctly.
+	* general/tril.m: Likewise, for upper bound.
+
+Tue Feb  6 09:29:43 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: For color images, make sure indices into
+	temporary colormap and result matrix have proper orientation.
+	Set grey flag correctly.
+
+Tue Jan  9 00:12:14 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* statistics/std.m: Use better formula (from Jim Van Zandt
+	jrv at vanzandt.mv.com).
+
+Sun Jan  7 20:12:14 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* meshgrid.m: New file (from Jim Van Zandt jrv at vanzandt.mv.com).
+	* mesh.m: Transpose Z if only one arg.
+ 	Handle case of all three args being matrices (from Jim Van Zandt
+	jrv at vanzandt.mv.com).
+	* meshdom.m: Undo previous change.
+
+Wed Dec 20 13:48:12 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* configure.in (AC_OUTPUT): Add audio/Makefile
+
+Thu Nov 16 13:07:07 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* audio: New directory of files from Kurt Hornik and Andreas
+	Weingessel.
+	* audio/Makefile.in: New file.
+	* Makefile.in (SUBDIRS): Add audio to the list.
+
+Mon Nov  6 07:29:35 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/polyfit.m: Use `economy-stle' QR factorization.
+
+Fri Nov  3 00:38:46 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/mesh.m: Require, length (y) == rows (z) and length (x) ==
+	columns (z), not the other way around.
+	* plot/meshdom.m: Don't reverse order of elements in y.
+
+Thu Nov  2 23:56:53 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/axis.m: Return current axis if nargin == 0.
+
+Tue Oct 31 04:11:28 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* polynomial/roots.m: Updates from Kurt Hornik.
+
+	* polynomial/polyder.m: New file.
+
+	* polynomial/polyderiv.m: Give return value and arg different names.
+
+Mon Oct 30 23:27:02 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* specfun/betainc.m: New file.
+	* specfun/gammainc.m: New file.
+
+Wed Oct 18 23:45:52 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* general/strerror.m: New file.
+	* general/perror.m: Implement using strerror().
+
+Thu Oct  5 03:21:36 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/bottom_title.m plot/mplot.m plot/multiplot.m plot/oneplot.m
+	plot/plot_border.m plot/subplot.m plot/subwindow.m
+	plot/top_title.m plot/zlabel.m: New files, from Vinayak Dutt.
+
+	* image/saveimage.m: Round img values first.
+
+Tue Oct  3 03:55:18 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/abcddim.m control/are.m general/tril.m general/triu.m
+	image/saveimage.m linear-algebra/kron.m linear-algebra/norm.m
+	linear-algebra/null.m miscellaneous/etime.m plot/contour.m
+	plot/mesh.m plot/plot_int.m plot/polar_int.m
+	special-matrix/hankel.m special-matrix/toeplitz.m
+	tuwien/strfun/split.m: Add missing semicolons.
+
+	* plot/polar_int.m: Use .', not ' to make vectors conform.
+
+	* image/Makefile.in: Don't build or install octtoppm.
+
+	* image/saveimage.m: Rewrite to avoid using octoppm and pbm
+	routines so that people who don't have the pbm stuff installed
+	can still use this function.
+
+Mon Oct  2 05:10:44 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* image/saveimage.m: Better error checking, clean up a bit.
+
+Tue Sep 26 00:04:56 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* plot/plot_opt.m: Change more to more_opts as a temporary fix to
+	avoid conflict with new built-in text-style function more.
+
+	* linear-algebra/norm.m: Also allow 2nd arg == "inf".
+
+	* startup/Makefile.in (install): Also install octaverc in
+	$localfcnfiledir/startup/octavrc.
+
+Wed Sep 20 00:01:30 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkinstalldirs: New file.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+	* Makefile.in (DISTFILES): Distribute configure.in and configure.
+
+Thu Sep 14 03:56:19 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* special-matrix/hankel.m: Compatibility fix.  Complain if 
+	r(1) != c(nr), not if r(1) != c(1).
+	
+	* signal/filter.m: Doc fix.
+
+Wed Sep 13 03:19:05 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* miscellaneous/cputime.m: Use new resource structure names (no
+	ru_ or tv_ prefixes).
+
+Tue Sep 12 02:20:44 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time/ctime.m: Fix doc string and usage message.
+
+Mon Sep 11 18:43:46 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time/clock.m: Use new time structure names (no tm_ prefix).
+
+Thu Aug 24 20:53:08 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* control/c2d.m: Make function work for any value of
+	whitespace_in_literal_matrix.
+	* control/dare.m: Likewise.
+	* control/tzero.m: Likewise.
+	* elfun/gcd.m: Likewise.
+	* elfun/lcm.m: Likewise.
+	* general/postpad.m: Likewise.
+	* general/prepad.m: Likewise.
+	* linear-algebra/kron.m: Likewise.
+	* miscellaneous/etime.m: Likewise.
+	* polynomial/conv.m: Likewise.
+	* polynomial/deconv.m: Likewise.
+	* polynomial/poly.m: Likewise.
+	* polynomial/roots.m: Likewise.
+	* signal/filter.m: Likewise.
+	* signal/freqz.m: Likewise.
+	* signal/fftfilt.m: Likewise.
+
+Tue Jun  6 22:34:04 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* miscellaneous/is_leap_year.m: Make work for vector args.
+
+Tue May  2 16:18:33 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* plot/polar_int_2.m: Add missing semicolons.
+	Set theta = theta', not rho'.
+
+Sun Apr 30 11:19:11 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* polynomial/roots.m: Make it work for any value of
+	whitespace_in_literal_matrix.
+
+Mon Apr 10 09:37:17 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* configure.in: New file.
+
+Thu Mar 30 13:29:35 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* control/lyap.m: Add missing semicolon.
+
+	* miscellaneous/cputime.m: New function file.
+
+Wed Mar 29 22:50:49 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* time: New directory.
+	* time/asctime.m, time/clock.m, time/ctime.m, time/date.m:
+	New function files.
+	* time/Makefile.in: New file.
+	* Makefile.in (SUBDIRS): Add time.
+
+Thu Mar 23 15:42:26 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* polynomial/polyreduce.m: Make sure initial index is not empty.
+
+Tue Mar 14 23:38:24 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* plot/plot_int_1.m: Transpose data with .', not '.
+
+Fri Mar 10 10:40:13 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (install uninstall clean mostlyclean distclean
+	realclean): Use SUBDIR_FOR_COMMAND.  Combine actions.
+
+Sun Feb 26 22:18:22 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (install): Create ls-R database file.
+	(uninstall): Delete it.
+
+Fri Feb 24 10:36:01 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* image/saveimage.m: Fix typo.
+
+See ChangeLog.1 in the top level directory for earlier changes.
diff --git a/scripts/DOCSTRINGS b/scripts/DOCSTRINGS
new file mode 100644
index 0000000..7c430bc
--- /dev/null
+++ b/scripts/DOCSTRINGS
@@ -0,0 +1,17688 @@
+### DO NOT EDIT!
+###
+### This file is generated automatically from the Octave sources.
+### Edit those files instead and run make to update this file.
+
+geometric_rnd
+ at c ./deprecated/geometric_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geometric_rnd (@var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} geometric_rnd (@var{p}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+geometric distribution with parameter @var{p}, which must be a scalar
+or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+meshdom
+ at c ./deprecated/meshdom.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} meshdom (@var{x}, @var{y})
+This function has been deprecated.  Use @code{meshgrid} instead.
+ at end deftypefn
+is_square
+ at c ./deprecated/is_square.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_square (@var{x})
+This function has been deprecated.  Use issquare instead.
+ at end deftypefn
+poisson_pdf
+ at c ./deprecated/poisson_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poisson_pdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the poisson distribution with parameter @var{lambda}.
+ at end deftypefn
+spkron
+ at c ./deprecated/spkron.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spkron (@var{a}, @var{b})
+This function has been deprecated.  Use @code{kron} instead.
+ at end deftypefn
+spcholinv
+ at c ./deprecated/spcholinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spcholinv (@var{u})
+This function has been deprecated.  Use @code{cholinv} instead.
+ at end deftypefn
+weibull_cdf
+ at c ./deprecated/weibull_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibull_cdf (@var{x}, @var{shape}, @var{scale})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}, which is
+
+ at example
+1 - exp(-(x/shape)^scale)
+ at end example
+
+ at noindent
+for @var{x} >= 0.
+ at end deftypefn
+weibpdf
+ at c ./deprecated/weibpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibpdf (@var{x}, @var{scale}, @var{shape})
+Compute the probability density function (PDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape} which is given by
+
+ at example
+   scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+ at end example
+
+ at noindent
+for @var{x} > 0.
+ at end deftypefn
+normal_cdf
+ at c ./deprecated/normal_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normal_cdf (@var{x}, @var{m}, @var{v})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the normal distribution with mean
+ at var{m} and variance @var{v}.
+
+Default values are @var{m} = 0, @var{v} = 1.
+ at end deftypefn
+chisquare_inv
+ at c ./deprecated/chisquare_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chisquare_inv (@var{x}, @var{n})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the chisquare distribution with @var{n} degrees of
+freedom.
+ at end deftypefn
+splu
+ at c ./deprecated/splu.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}] =} splu (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}] =} splu (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}, @var{Q}] =} splu (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}, @var{Q}] =} splu (@dots{}, @var{thres})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}] =} splu (@dots{}, @var{Q})
+This function has been deprecated.  Use @code{lu} instead.
+ at end deftypefn
+gamma_pdf
+ at c ./deprecated/gamma_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gamma_pdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, return the probability density function
+(PDF) at @var{x} of the Gamma distribution with parameters @var{a}
+and @var{b}.
+ at end deftypefn
+t_inv
+ at c ./deprecated/t_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} t_inv (@var{x}, @var{n})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the t (Student) distribution with parameter
+ at var{n}.
+ at end deftypefn
+pascal_pdf
+ at c ./deprecated/pascal_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pascal_pdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Pascal (negative binomial) distribution with
+parameters @var{n} and @var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution. 
+ at end deftypefn
+isstr
+ at c ./deprecated/isstr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isstr (@var{a})
+This function has been deprecated.  Use ischar instead.
+ at end deftypefn
+is_struct
+ at c ./deprecated/is_struct.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_struct (@var{a})
+This function has been deprecated.  Use isstruct instead.
+ at end deftypefn
+chisquare_pdf
+ at c ./deprecated/chisquare_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chisquare_pdf (@var{x}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the chisquare distribution with @var{n} degrees
+of freedom. 
+ at end deftypefn
+spdiag
+ at c ./deprecated/spdiag.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spdiag (@var{v}, @var{k})
+This function has been deprecated.  Use @code{sparse (diag (@dots{}))} instead.
+ at end deftypefn
+setstr
+ at c ./deprecated/setstr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} setstr (@var{s})
+This function has been deprecated.  Use char instead.
+ at end deftypefn
+spmin
+ at c ./deprecated/spmin.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} spmin (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmin (@var{x})
+This function has been deprecated.  Use @code{min} instead.
+ at end deftypefn
+uniform_cdf
+ at c ./deprecated/uniform_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} uniform_cdf (@var{x}, @var{a}, @var{b})
+Return the CDF at @var{x} of the uniform distribution on [@var{a},
+ at var{b}], i.e., PROB (uniform (@var{a}, @var{b}) <= x).
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+weibull_pdf
+ at c ./deprecated/weibull_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibull_pdf (@var{x}, @var{shape}, @var{scale})
+Compute the probability density function (PDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape} which is given by
+
+ at example
+   scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+ at end example
+
+ at noindent
+for @var{x} > 0.
+ at end deftypefn
+spcumprod
+ at c ./deprecated/spcumprod.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spcumprod (@var{x}, @var{dim})
+This function has been deprecated.  Use @code{cumprod} instead.
+ at end deftypefn
+spprod
+ at c ./deprecated/spprod.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spprod (@var{x}, @var{dim})
+This function has been deprecated.  Use @code{prod} instead.
+ at end deftypefn
+str2mat
+ at c ./deprecated/str2mat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} str2mat (@var{s_1}, @dots{}, @var{s_n})
+Return a matrix containing the strings @var{s_1}, @dots{}, @var{s_n} as
+its rows.  Each string is padded with blanks in order to form a valid
+matrix.
+
+This function is modelled after @sc{matlab}.  In Octave, you can create
+a matrix of strings by @code{[@var{s_1}; @dots{}; @var{s_n}]} even if
+the strings are not all the same length.
+ at end deftypefn
+is_complex
+ at c ./deprecated/is_complex.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_complex (@var{a})
+This function has been deprecated.  Use iscomplex instead.
+ at end deftypefn
+lognormal_inv
+ at c ./deprecated/lognormal_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lognormal_inv (@var{x}, @var{a}, @var{v})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the lognormal distribution with parameters @var{a}
+and @var{v}.  If a random variable follows this distribution, its
+logarithm is normally distributed with mean @code{log (@var{a})} and
+variance @var{v}.
+
+Default values are @var{a} = 1, @var{v} = 1.
+ at end deftypefn
+t_pdf
+ at c ./deprecated/t_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} t_pdf (@var{x}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the @var{t} (Student) distribution with @var{n}
+degrees of freedom. 
+ at end deftypefn
+com2str
+ at c ./deprecated/com2str.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} com2str (@var{zz}, @var{flg})
+This function has been deprecated.  Use num2str instead.
+
+Convert complex number to a string.
+ at strong{Inputs}
+ at table @var
+ at item zz
+complex number
+ at item flg
+format flag
+0 (default):            -1, 0, 1,   1i,   1 + 0.5i
+1 (for use with zpout): -1, 0, + 1, + 1i, + 1 + 0.5i
+ at end table
+ at end deftypefn
+polyinteg
+ at c ./deprecated/polyinteg.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyinteg (@var{c})
+Return the coefficients of the integral of the polynomial whose
+coefficients are represented by the vector @var{c}.
+
+The constant of integration is set to zero.
+ at seealso{polyint, poly, polyderiv, polyreduce, roots, conv, deconv, residue,
+filter, polyval, polyvalm}
+ at end deftypefn
+f_rnd
+ at c ./deprecated/f_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} f_rnd (@var{m}, @var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} f_rnd (@var{m}, @var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the F
+distribution with @var{m} and @var{n} degrees of freedom.  Both
+ at var{m} and @var{n} must be scalar or of size @var{r} by @var{c}.
+If @var{sz} is a vector the random samples are in a matrix of 
+size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{m} and @var{n}.
+ at end deftypefn
+exponential_rnd
+ at c ./deprecated/exponential_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} exponential_rnd (@var{lambda}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} exponential_rnd (@var{lambda}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+exponential distribution with parameter @var{lambda}, which must be a
+scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a vector, 
+create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{lambda}.
+ at end deftypefn
+lognormal_rnd
+ at c ./deprecated/lognormal_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lognormal_rnd (@var{a}, @var{v}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} lognormal_rnd (@var{a}, @var{v}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+lognormal distribution with parameters @var{a} and @var{v}.  Both
+ at var{a} and @var{v} must be scalar or of size @var{r} by @var{c}.
+Or if @var{sz} is a vector, create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{v}.
+ at end deftypefn
+binomial_inv
+ at c ./deprecated/binomial_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binomial_inv (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+binomial distribution with parameters @var{n} and @var{p}.
+ at end deftypefn
+poisson_rnd
+ at c ./deprecated/poisson_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poisson_rnd (@var{lambda}, @var{r}, @var{c})
+Return an @var{r} by @var{c} matrix of random samples from the
+Poisson distribution with parameter @var{lambda}, which must be a 
+scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{lambda}.
+ at end deftypefn
+weibinv
+ at c ./deprecated/weibinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibinv (@var{x}, @var{scale}, @var{shape})
+Compute the quantile (the inverse of the CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}.
+ at end deftypefn
+spcumsum
+ at c ./deprecated/spcumsum.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spcumsum (@var{x}, @var{dim})
+This function has been deprecated.  Use @code{cumsum} instead.
+ at end deftypefn
+is_matrix
+ at c ./deprecated/is_matrix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_matrix (@var{a})
+This function has been deprecated.  Use ismatrix instead.
+ at end deftypefn
+exponential_inv
+ at c ./deprecated/exponential_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} exponential_inv (@var{x}, @var{lambda})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the exponential distribution with parameter
+ at var{lambda}.
+ at end deftypefn
+geometric_inv
+ at c ./deprecated/geometric_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geometric_inv (@var{x}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+geometric distribution with parameter @var{p}.
+ at end deftypefn
+spatan2
+ at c ./deprecated/spatan2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spatan2 (@var{y}, @var{x})
+This function has been deprecated.  Use @code{atan2} instead.
+ at end deftypefn
+lognormal_cdf
+ at c ./deprecated/lognormal_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lognormal_cdf (@var{x}, @var{a}, @var{v})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the lognormal distribution with
+parameters @var{a} and @var{v}.  If a random variable follows this
+distribution, its logarithm is normally distributed with mean
+ at code{log (@var{a})} and variance @var{v}.
+
+Default values are @var{a} = 1, @var{v} = 1.
+ at end deftypefn
+gamma_cdf
+ at c ./deprecated/gamma_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gamma_cdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Gamma distribution with parameters
+ at var{a} and @var{b}.
+ at end deftypefn
+clearplot
+ at c ./deprecated/clearplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} clearplot ()
+This function has been deprecated.  Use clf instead.
+ at end deftypefn
+unmark_command
+ at c ./deprecated/unmark_command.m
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} unmark_command (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+dmult
+ at c ./deprecated/dmult.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dmult (@var{a}, @var{b})
+This function has been deprecated.  Use the direct syntax @code{diag(A)*B}
+which is more readable and now also more efficient.
+ at end deftypefn
+struct_contains
+ at c ./deprecated/struct_contains.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} struct_contains (@var{expr}, @var{name})
+This function has been deprecated.  Use isfield instead.
+ at end deftypefn
+normal_rnd
+ at c ./deprecated/normal_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normal_rnd (@var{m}, @var{v}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} normal_rnd (@var{m}, @var{v}, @var{sz})
+Return an @var{r} by @var{c}  or @code{size (@var{sz})} matrix of
+random samples from the normal distribution with parameters @var{m} 
+and @var{v}.  Both @var{m} and @var{v} must be scalar or of size 
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{m} and @var{v}.
+ at end deftypefn
+spmax
+ at c ./deprecated/spmax.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} spmax (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmax (@var{x})
+This function has been deprecated.  Use @code{max} instead.
+ at end deftypefn
+spchol2inv
+ at c ./deprecated/spchol2inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spchol2inv (@var{u})
+This function has been deprecated.  Use @code{chol2inv} instead.
+ at end deftypefn
+is_bool
+ at c ./deprecated/is_bool.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_bool (@var{a})
+This function has been deprecated.  Use isbool instead.
+ at end deftypefn
+gamma_rnd
+ at c ./deprecated/gamma_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gamma_rnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} gamma_rnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the Gamma distribution with parameters @var{a}
+and @var{b}.  Both @var{a} and @var{b} must be scalar or of size 
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+pascal_inv
+ at c ./deprecated/pascal_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pascal_inv (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+Pascal (negative binomial) distribution with parameters @var{n} and
+ at var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution.
+ at end deftypefn
+uniform_pdf
+ at c ./deprecated/uniform_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} uniform_pdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the PDF at @var{x} of the uniform
+distribution on [@var{a}, @var{b}].
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+exponential_cdf
+ at c ./deprecated/exponential_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} exponential_cdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the exponential distribution with
+parameter @var{lambda}.
+
+The arguments can be of common size or scalar.
+ at end deftypefn
+hypergeometric_inv
+ at c ./deprecated/hypergeometric_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hypergeometric_inv (@var{x}, @var{m}, @var{t}, @var{n})
+For each element of @var{x}, compute the quantile at @var{x} of the
+hypergeometric distribution with parameters @var{m}, @var{t}, and
+ at var{n}.
+
+The parameters @var{m}, @var{t}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+wiener_rnd
+ at c ./deprecated/wiener_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wiener_rnd (@var{t}, @var{d}, @var{n})
+Return a simulated realization of the @var{d}-dimensional Wiener Process
+on the interval [0, @var{t}].  If @var{d} is omitted, @var{d} = 1 is
+used.  The first column of the return matrix contains time, the
+remaining columns contain the Wiener process.
+
+The optional parameter @var{n} gives the number of summands used for
+simulating the process over an interval of length 1.  If @var{n} is
+omitted, @var{n} = 1000 is used.
+ at end deftypefn
+spfind
+ at c ./deprecated/spfind.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} spfind (@var{x})
+ at deftypefnx {Loadable Function} {} spfind (@var{x}, @var{n})
+ at deftypefnx {Loadable Function} {} spfind (@var{x}, @var{n}, @var{direction})
+ at deftypefnx {Loadable Function} {[@var{i}, @var{j}, @var{v}} spfind (@dots{})
+This function has been deprecated.  Use @code{find} instead.
+ at end deftypefn
+iscommand
+ at c ./deprecated/iscommand.m
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} iscommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+lognormal_pdf
+ at c ./deprecated/lognormal_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lognormal_pdf (@var{x}, @var{a}, @var{v})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the lognormal distribution with parameters
+ at var{a} and @var{v}.  If a random variable follows this distribution,
+its logarithm is normally distributed with mean @code{log (@var{a})}
+and variance @var{v}.
+
+Default values are @var{a} = 1, @var{v} = 1.
+ at end deftypefn
+beta_pdf
+ at c ./deprecated/beta_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} beta_pdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, returns the PDF at @var{x} of the beta
+distribution with parameters @var{a} and @var{b}.
+ at end deftypefn
+weibrnd
+ at c ./deprecated/weibrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibrnd (@var{scale}, @var{shape}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} weibrnd (@var{scale}, @var{shape}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+Weibull distribution with parameters @var{scale} and @var{shape}
+which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+is a vector return a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{alpha} and @var{sigma}.
+ at end deftypefn
+intersection
+ at c ./deprecated/intersection.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} intersection (@var{x}, @var{y})
+This function has been deprecated.  Use intersect instead.
+ at end deftypefn
+weibull_inv
+ at c ./deprecated/weibull_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibull_inv (@var{x}, @var{shape}, @var{scale})
+Compute the quantile (the inverse of the CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}.
+ at end deftypefn
+weibcdf
+ at c ./deprecated/weibcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibcdf (@var{x}, @var{scale}, @var{shape})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}, which is
+
+ at example
+1 - exp(-(x/shape)^scale)
+ at end example
+
+ at noindent
+for @var{x} >= 0.
+ at end deftypefn
+t_rnd
+ at c ./deprecated/t_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} t_rnd (@var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} t_rnd (@var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the t
+(Student) distribution with @var{n} degrees of freedom.  @var{n} must
+be a scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a
+vector create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{n}.
+ at end deftypefn
+spchol
+ at c ./deprecated/spchol.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{r} =} spchol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}] =} spchol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} spchol (@var{a})
+This function has been deprecated.  Use @code{chol} instead.
+ at end deftypefn
+hypergeometric_pdf
+ at c ./deprecated/hypergeometric_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hypergeometric_pdf (@var{x}, @var{m}, @var{t}, @var{n})
+Compute the probability density function (PDF) at @var{x} of the
+hypergeometric distribution with parameters @var{m}, @var{t}, and
+ at var{n}.  This is the probability of obtaining @var{x} marked items
+when randomly drawing a sample of size @var{n} without replacement
+from a population of total size @var{t} containing @var{m} marked items.
+
+The arguments must be of common size or scalar.
+ at end deftypefn
+loadimage
+ at c ./deprecated/loadimage.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{map}] =} loadimage (@var{file})
+Load an image file and its associated color map from the specified
+ at var{file}.  The image must be stored in Octave's image format.
+ at seealso{saveimage, load, save}
+ at end deftypefn
+binomial_pdf
+ at c ./deprecated/binomial_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binomial_pdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the binomial distribution with parameters @var{n}
+and @var{p}.
+ at end deftypefn
+spsumsq
+ at c ./deprecated/spsumsq.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spsumsq (@var{x}, @var{dim})
+This function has been deprecated.  Use @code{sumsq} instead.
+ at end deftypefn
+chisquare_rnd
+ at c ./deprecated/chisquare_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chisquare_rnd (@var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} chisquare_rnd (@var{n}, @var{sz})
+Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+random samples from the chisquare distribution with @var{n} degrees 
+of freedom.  @var{n} must be a scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{n}.
+ at end deftypefn
+splchol
+ at c ./deprecated/splchol.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{l} =} splchol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{p}] =} splchol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{p}, @var{q}] =} splchol (@var{a})
+This function has been deprecated.  Use @code{chol (@dots{},'lower')}
+instead.
+ at end deftypefn
+spinv
+ at c ./deprecated/spinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{rcond}] =} spinv (@var{a})
+This function has been deprecated.  Use @code{inv} instead.
+ at end deftypefn
+spsum
+ at c ./deprecated/spsum.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spsum (@var{x}, @var{dim})
+This function has been deprecated.  Use @code{sum} instead.
+ at end deftypefn
+poisson_inv
+ at c ./deprecated/poisson_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poisson_inv (@var{x}, @var{lambda})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Poisson distribution with parameter
+ at var{lambda}.
+ at end deftypefn
+beta_rnd
+ at c ./deprecated/beta_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} beta_rnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} beta_rnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+random samples from the Beta distribution with parameters @var{a} and
+ at var{b}.  Both @var{a} and @var{b} must be scalar or of size @var{r}
+ by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+chisquare_cdf
+ at c ./deprecated/chisquare_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chisquare_cdf (@var{x}, @var{n})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the chisquare distribution with @var{n}
+degrees of freedom.
+ at end deftypefn
+mark_as_command
+ at c ./deprecated/mark_as_command.m
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mark_as_command (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+hypergeometric_cdf
+ at c ./deprecated/hypergeometric_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hypergeometric_cdf (@var{x}, @var{m}, @var{t}, @var{n})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+hypergeometric distribution with parameters @var{m}, @var{t}, and
+ at var{n}.  This is the probability of obtaining not more than @var{x}
+marked items when randomly drawing a sample of size @var{n} without
+replacement from a population of total size @var{t} containing
+ at var{m} marked items.
+
+The parameters @var{m}, @var{t}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+is_scalar
+ at c ./deprecated/is_scalar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_scalar (@var{a})
+This function has been deprecated.  Use isscalar instead.
+ at end deftypefn
+uniform_rnd
+ at c ./deprecated/uniform_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} uniform_rnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} uniform_rnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the uniform distribution on [@var{a}, @var{b}]. 
+Both @var{a} and @var{b} must be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+create_set
+ at c ./deprecated/create_set.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} create_set (@var{x})
+ at deftypefnx{Function File} {} create_set (@var{x}, "rows")
+This function has been deprecated.  Use unique instead.
+ at end deftypefn
+unmark_rawcommand
+ at c ./deprecated/unmark_rawcommand.m
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} unmark_rawcommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+struct_elements
+ at c ./deprecated/struct_elements.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} struct_elements (@var{struct})
+This function has been deprecated.  Use fieldnames instead.
+ at end deftypefn
+beta_inv
+ at c ./deprecated/beta_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} beta_inv (@var{x}, @var{a}, @var{b})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Beta distribution with parameters @var{a}
+and @var{b}.
+ at end deftypefn
+gamma_inv
+ at c ./deprecated/gamma_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gamma_inv (@var{x}, @var{a}, @var{b})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Gamma distribution with parameters @var{a}
+and @var{b}. 
+ at end deftypefn
+split
+ at c ./deprecated/split.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} split (@var{s}, @var{t}, @var{n})
+This function has been deprecated.  Use @code{char (strsplit (s, t))}
+instead.
+ at end deftypefn
+clg
+ at c ./deprecated/clg.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} clg ()
+This function has been deprecated.  Use clf instead.
+ at end deftypefn
+exponential_pdf
+ at c ./deprecated/exponential_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} exponential_pdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the probability density function
+(PDF) of the exponential distribution with parameter @var{lambda}.
+ at end deftypefn
+f_inv
+ at c ./deprecated/f_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} f_inv (@var{x}, @var{m}, @var{n})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the F distribution with parameters @var{m} and
+ at var{n}.
+ at end deftypefn
+normal_pdf
+ at c ./deprecated/normal_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normal_pdf (@var{x}, @var{m}, @var{v})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the normal distribution with mean @var{m} and
+variance @var{v}.
+
+Default values are @var{m} = 0, @var{v} = 1.
+ at end deftypefn
+binomial_rnd
+ at c ./deprecated/binomial_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binomial_rnd (@var{n}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} binomial_rnd (@var{n}, @var{p}, @var{sz})
+Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+random samples from the binomial distribution with parameters @var{n}
+and @var{p}.  Both @var{n} and @var{p} must be scalar or of size
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{n} and @var{p}.
+ at end deftypefn
+pascal_cdf
+ at c ./deprecated/pascal_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pascal_cdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the CDF at x of the Pascal
+(negative binomial) distribution with parameters @var{n} and @var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution.
+ at end deftypefn
+geometric_pdf
+ at c ./deprecated/geometric_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geometric_pdf (@var{x}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the geometric distribution with parameter @var{p}.
+ at end deftypefn
+mark_as_rawcommand
+ at c ./deprecated/mark_as_rawcommand.m
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mark_as_rawcommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+is_vector
+ at c ./deprecated/is_vector.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_vector (@var{a})
+This function has been deprecated.  Use isvector instead.
+ at end deftypefn
+f_cdf
+ at c ./deprecated/f_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} f_cdf (@var{x}, @var{m}, @var{n})
+For each element of @var{x}, compute the CDF at @var{x} of the F
+distribution with @var{m} and @var{n} degrees of freedom, i.e.,
+PROB (F (@var{m}, @var{n}) <= @var{x}). 
+ at end deftypefn
+normal_inv
+ at c ./deprecated/normal_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normal_inv (@var{x}, @var{m}, @var{v})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the normal distribution with mean @var{m} and
+variance @var{v}.
+
+Default values are @var{m} = 0, @var{v} = 1.
+ at end deftypefn
+israwcommand
+ at c ./deprecated/israwcommand.m
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} israwcommand (@var{name})
+This function is obsolete and will be removed from a future
+version of Octave.
+ at end deftypefn
+uniform_inv
+ at c ./deprecated/uniform_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} uniform_inv (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the uniform distribution on [@var{a}, @var{b}].
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+geometric_cdf
+ at c ./deprecated/geometric_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geometric_cdf (@var{x}, @var{p})
+For each element of @var{x}, compute the CDF at @var{x} of the
+geometric distribution with parameter @var{p}.
+ at end deftypefn
+binomial_cdf
+ at c ./deprecated/binomial_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binomial_cdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the CDF at @var{x} of the
+binomial distribution with parameters @var{n} and @var{p}.
+ at end deftypefn
+hypergeometric_rnd
+ at c ./deprecated/hypergeometric_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hypergeometric_rnd (@var{m}, @var{t}, @var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} hygernd (@var{m}, @var{t}, @var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+hypergeometric distribution with parameters @var{m}, @var{t},
+and @var{n}.
+
+The parameters @var{m}, @var{t}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+beta_cdf
+ at c ./deprecated/beta_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} beta_cdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, returns the CDF at @var{x} of the beta
+distribution with parameters @var{a} and @var{b}, i.e.,
+PROB (beta (@var{a}, @var{b}) <= @var{x}).
+ at end deftypefn
+is_symmetric
+ at c ./deprecated/is_symmetric.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} issymmetric (@var{x}, @var{tol})
+This function has been deprecated.  Use issymmetric instead.
+ at end deftypefn
+weibull_rnd
+ at c ./deprecated/weibull_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} weibull_rnd (@var{shape}, @var{scale}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} weibull_rnd (@var{shape}, @var{scale}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+Weibull distribution with parameters @var{scale} and @var{shape}
+which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+is a vector return a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{alpha} and @var{sigma}.
+ at end deftypefn
+lchol
+ at c ./deprecated/lchol.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{l} =} lchol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{p}] =} lchol (@var{a})
+This function has been deprecated.  Use @code{chol (@dots{},'lower')}
+instead.
+ at end deftypefn
+is_list
+ at c ./deprecated/is_list.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_list (@var{a})
+This function has been deprecated.  Use islist instead.
+ at end deftypefn
+spqr
+ at c ./deprecated/spqr.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{r} =} spqr (@var{a})
+ at deftypefnx {Loadable Function} {@var{r} =} spqr (@var{a},0)
+ at deftypefnx {Loadable Function} {[@var{c}, @var{r}] =} spqr (@var{a}, at var{b})
+ at deftypefnx {Loadable Function} {[@var{c}, @var{r}] =} spqr (@var{a}, at var{b},0)
+This function has been deprecated.  Use @code{qr} instead.
+ at end deftypefn
+t_cdf
+ at c ./deprecated/t_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} t_cdf (@var{x}, @var{n})
+For each element of @var{x}, compute the CDF at @var{x} of the
+t (Student) distribution with @var{n} degrees of freedom, i.e.,
+PROB (t(@var{n}) <= @var{x}).
+ at end deftypefn
+poisson_cdf
+ at c ./deprecated/poisson_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poisson_cdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Poisson distribution with parameter
+lambda.
+ at end deftypefn
+f_pdf
+ at c ./deprecated/f_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} f_pdf (@var{x}, @var{m}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the F distribution with @var{m} and @var{n}
+degrees of freedom.
+ at end deftypefn
+spdet
+ at c ./deprecated/spdet.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{d}, @var{rcond}] =} spdet (@var{a})
+This function has been deprecated.  Use @code{det} instead.
+ at end deftypefn
+is_stream
+ at c ./deprecated/is_stream.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_stream (@var{a})
+This function has been deprecated.  Use isstream instead.
+ at end deftypefn
+pascal_rnd
+ at c ./deprecated/pascal_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pascal_rnd (@var{n}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} pascal_rnd (@var{n}, @var{p}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the Pascal
+(negative binomial) distribution with parameters @var{n} and @var{p}.
+Both @var{n} and @var{p} must be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{n} and @var{p}.  Or if @var{sz} is a vector, 
+create a matrix of size @var{sz}.
+ at end deftypefn
+hotelling_test
+ at c ./statistics/tests/hotelling_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{tsq}] =} hotelling_test (@var{x}, @var{m})
+For a sample @var{x} from a multivariate normal distribution with unknown
+mean and covariance matrix, test the null hypothesis that @code{mean
+(@var{x}) == @var{m}}.
+
+Hotelling's @math{T^2} is returned in @var{tsq}.  Under the null,
+ at math{(n-p) T^2 / (p(n-1))} has an F distribution with @math{p} and
+ at math{n-p} degrees of freedom, where @math{n} and @math{p} are the
+numbers of samples and variables, respectively.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+t_test_2
+ at c ./statistics/tests/t_test_2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test_2 (@var{x}, @var{y}, @var{alt})
+For two samples x and y from normal distributions with unknown means
+and unknown equal variances, perform a two-sample t-test of the null
+hypothesis of equal means.  Under the null, the test statistic
+ at var{t} follows a Student distribution with @var{df} degrees of
+freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != mean (@var{y})}.  If @var{alt} is @code{">"},
+the one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is
+used.  Similarly for @code{"<"}, the one-sided alternative @code{mean
+(@var{x}) < mean (@var{y})} is used.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+t_test
+ at c ./statistics/tests/t_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test (@var{x}, @var{m}, @var{alt})
+For a sample @var{x} from a normal distribution with unknown mean and
+variance, perform a t-test of the null hypothesis @code{mean
+(@var{x}) == @var{m}}.  Under the null, the test statistic @var{t}
+follows a Student distribution with @code{@var{df} = length (@var{x})
+- 1} degrees of freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
+Similarly for @var{"<"}, the one-sided alternative @code{mean
+(@var{x}) < @var{m}} is considered.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+cor_test
+ at c ./statistics/tests/cor_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cor_test (@var{x}, @var{y}, @var{alt}, @var{method})
+Test whether two samples @var{x} and @var{y} come from uncorrelated
+populations.
+
+The optional argument string @var{alt} describes the alternative
+hypothesis, and can be @code{"!="} or @code{"<>"} (non-zero),
+ at code{">"} (greater than 0), or @code{"<"} (less than 0).  The
+default is the two-sided case.
+
+The optional argument string @var{method} specifies on which
+correlation coefficient the test should be based.  If @var{method} is
+ at code{"pearson"} (default), the (usual) Pearson's product moment
+correlation coefficient is used.  In this case, the data should come
+from a bivariate normal distribution.  Otherwise, the other two
+methods offer nonparametric alternatives.  If @var{method} is
+ at code{"kendall"}, then Kendall's rank correlation tau is used.  If
+ at var{method} is @code{"spearman"}, then Spearman's rank correlation
+rho is used.  Only the first character is necessary.
+
+The output is a structure with the following elements:
+
+ at table @var
+ at item pval
+The p-value of the test.
+ at item stat
+The value of the test statistic.
+ at item dist
+The distribution of the test statistic.
+ at item params
+The parameters of the null distribution of the test statistic.
+ at item alternative
+The alternative hypothesis.
+ at item method
+The method used for testing.
+ at end table
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+f_test_regression
+ at c ./statistics/tests/f_test_regression.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_num}, @var{df_den}] =} f_test_regression (@var{y}, @var{x}, @var{rr}, @var{r})
+Perform an F test for the null hypothesis rr * b = r in a classical
+normal regression model y = X * b + e.
+
+Under the null, the test statistic @var{f} follows an F distribution
+with @var{df_num} and @var{df_den} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{f}) is
+returned in @var{pval}.
+
+If not given explicitly, @var{r} = 0.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+z_test
+ at c ./statistics/tests/z_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} z_test (@var{x}, @var{m}, @var{v}, @var{alt})
+Perform a Z-test of the null hypothesis @code{mean (@var{x}) ==
+ at var{m}} for a sample @var{x} from a normal distribution with unknown
+mean and known variance @var{v}.  Under the null, the test statistic
+ at var{z} follows a standard normal distribution.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
+Similarly for @code{"<"}, the one-sided alternative @code{mean
+(@var{x}) < @var{m}} is considered.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed
+along with some information.
+ at end deftypefn
+welch_test
+ at c ./statistics/tests/welch_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} welch_test (@var{x}, @var{y}, @var{alt})
+For two samples @var{x} and @var{y} from normal distributions with
+unknown means and unknown and not necessarily equal variances,
+perform a Welch test of the null hypothesis of equal means.
+Under the null, the test statistic @var{t} approximately follows a
+Student distribution with @var{df} degrees of freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+one-sided alternative mean(x) > @var{m} is considered.  Similarly for
+ at code{"<"}, the one-sided alternative mean(x) < @var{m} is
+considered.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+mcnemar_test
+ at c ./statistics/tests/mcnemar_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} mcnemar_test (@var{x})
+For a square contingency table @var{x} of data cross-classified on
+the row and column variables, McNemar's test can be used for testing
+the null hypothesis of symmetry of the classification probabilities.
+
+Under the null, @var{chisq} is approximately distributed as chisquare
+with @var{df} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+anova
+ at c ./statistics/tests/anova.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_b}, @var{df_w}] =} anova (@var{y}, @var{g})
+Perform a one-way analysis of variance (ANOVA).  The goal is to test
+whether the population means of data taken from @var{k} different
+groups are all equal.
+
+Data may be given in a single vector @var{y} with groups specified by
+a corresponding vector of group labels @var{g} (e.g., numbers from 1
+to @var{k}).  This is the general form which does not impose any
+restriction on the number of data in each group or the group labels.
+
+If @var{y} is a matrix and @var{g} is omitted, each column of @var{y}
+is treated as a group.  This form is only appropriate for balanced
+ANOVA in which the numbers of samples from each group are all equal.
+
+Under the null of constant means, the statistic @var{f} follows an F
+distribution with @var{df_b} and @var{df_w} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{f}) is
+returned in @var{pval}.
+
+If no output argument is given, the standard one-way ANOVA table is
+printed.
+ at end deftypefn
+kolmogorov_smirnov_test_2
+ at c ./statistics/tests/kolmogorov_smirnov_test_2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{ks}, @var{d}] =} kolmogorov_smirnov_test_2 (@var{x}, @var{y}, @var{alt})
+Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis
+that the samples @var{x} and @var{y} come from the same (continuous)
+distribution.  I.e., if F and G are the CDFs corresponding to the
+ at var{x} and @var{y} samples, respectively, then the null is that F ==
+G.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative F
+!= G.  In this case, the test statistic @var{ks} follows a two-sided
+Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
+one-sided alternative F > G is considered.  Similarly for @code{"<"},
+the one-sided alternative F < G is considered.  In this case, the
+test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
+distribution.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+The third returned value, @var{d}, is the test statistic, the maximum
+vertical distance between the two cumulative distribution functions.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+chisquare_test_independence
+ at c ./statistics/tests/chisquare_test_independence.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} chisquare_test_independence (@var{x})
+Perform a chi-square test for independence based on the contingency
+table @var{x}.  Under the null hypothesis of independence,
+ at var{chisq} approximately has a chi-square distribution with
+ at var{df} degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at chisq) of the
+test is returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+kruskal_wallis_test
+ at c ./statistics/tests/kruskal_wallis_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{k}, @var{df}] =} kruskal_wallis_test (@var{x1}, @dots{})
+Perform a Kruskal-Wallis one-factor "analysis of variance".
+
+Suppose a variable is observed for @var{k} > 1 different groups, and
+let @var{x1}, @dots{}, @var{xk} be the corresponding data vectors.
+
+Under the null hypothesis that the ranks in the pooled sample are not
+affected by the group memberships, the test statistic @var{k} is
+approximately chi-square with @var{df} = @var{k} - 1 degrees of
+freedom.
+
+If the data contains ties (some value appears more than once)
+ at var{k} is divided by
+
+1 - @var{sum_ties} / (@var{n}^3 - @var{n})
+
+where @var{sum_ties} is the sum of @var{t}^2 - @var{t} over each group
+of ties where @var{t} is the number of ties in the group and @var{n}
+is the total number of values in the input data.  For more info on
+this adjustment see "Use of Ranks in One-Criterion Variance Analysis"
+in Journal of the American Statistical Association, Vol. 47,
+No. 260 (Dec 1952) by William H. Kruskal and W. Allen Wallis.
+
+The p-value (1 minus the CDF of this distribution at @var{k}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+run_test
+ at c ./statistics/tests/run_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}] =} run_test (@var{x})
+Perform a chi-square test with 6 degrees of freedom based on the
+upward runs in the columns of @var{x}.  Can be used to test whether
+ at var{x} contains independent data.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+t_test_regression
+ at c ./statistics/tests/t_test_regression.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test_regression (@var{y}, @var{x}, @var{rr}, @var{r}, @var{alt})
+Perform an t test for the null hypothesis @code{@var{rr} * @var{b} =
+ at var{r}} in a classical normal regression model @code{@var{y} =
+ at var{x} * @var{b} + @var{e}}.  Under the null, the test statistic @var{t}
+follows a @var{t} distribution with @var{df} degrees of freedom.
+
+If @var{r} is omitted, a value of 0 is assumed.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{@var{rr} * @var{b} != @var{r}}.  If @var{alt} is @code{">"}, the
+one-sided alternative @code{@var{rr} * @var{b} > @var{r}} is used.
+Similarly for @var{"<"}, the one-sided alternative @code{@var{rr} *
+ at var{b} < @var{r}} is used.  The default is the two-sided case. 
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+z_test_2
+ at c ./statistics/tests/z_test_2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} z_test_2 (@var{x}, @var{y}, @var{v_x}, @var{v_y}, @var{alt})
+For two samples @var{x} and @var{y} from normal distributions with
+unknown means and known variances @var{v_x} and @var{v_y}, perform a
+Z-test of the hypothesis of equal means.  Under the null, the test
+statistic @var{z} follows a standard normal distribution.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{mean (@var{x}) != mean (@var{y})}.  If alt is @code{">"}, the
+one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is used.
+Similarly for @code{"<"}, the one-sided alternative @code{mean
+(@var{x}) < mean (@var{y})} is used.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed
+along with some information.
+ at end deftypefn
+kolmogorov_smirnov_test
+ at c ./statistics/tests/kolmogorov_smirnov_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{ks}] =} kolmogorov_smirnov_test (@var{x}, @var{dist}, @var{params}, @var{alt})
+Perform a Kolmogorov-Smirnov test of the null hypothesis that the
+sample @var{x} comes from the (continuous) distribution dist.  I.e.,
+if F and G are the CDFs corresponding to the sample and dist,
+respectively, then the null is that F == G.
+
+The optional argument @var{params} contains a list of parameters of
+ at var{dist}.  For example, to test whether a sample @var{x} comes from
+a uniform distribution on [2,4], use
+
+ at example
+kolmogorov_smirnov_test(x, "uniform", 2, 4)
+ at end example
+
+ at noindent
+ at var{dist} can be any string for which a function @var{dist_cdf}
+that calculates the CDF of distribution @var{dist} exists.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative F
+!= G.  In this case, the test statistic @var{ks} follows a two-sided
+Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
+one-sided alternative F > G is considered.  Similarly for @code{"<"},
+the one-sided alternative F > G is considered.  In this case, the
+test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
+distribution.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+u_test
+ at c ./statistics/tests/u_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} u_test (@var{x}, @var{y}, @var{alt})
+For two samples @var{x} and @var{y}, perform a Mann-Whitney U-test of
+the null hypothesis PROB (@var{x} > @var{y}) == 1/2 == PROB (@var{x}
+< @var{y}).  Under the null, the test statistic @var{z} approximately
+follows a standard normal distribution.  Note that this test is
+equivalent to the Wilcoxon rank-sum test.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+PROB (@var{x} > @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+one-sided alternative PROB (@var{x} > @var{y}) > 1/2 is considered.
+Similarly for @code{"<"}, the one-sided alternative PROB (@var{x} >
+ at var{y}) < 1/2 is considered.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+var_test
+ at c ./statistics/tests/var_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_num}, @var{df_den}] =} var_test (@var{x}, @var{y}, @var{alt})
+For two samples @var{x} and @var{y} from normal distributions with
+unknown means and unknown variances, perform an F-test of the null
+hypothesis of equal variances.  Under the null, the test statistic
+ at var{f} follows an F-distribution with @var{df_num} and @var{df_den}
+degrees of freedom.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at code{var (@var{x}) != var (@var{y})}.  If @var{alt} is @code{">"},
+the one-sided alternative @code{var (@var{x}) > var (@var{y})} is
+used.  Similarly for "<", the one-sided alternative @code{var
+(@var{x}) > var (@var{y})} is used.  The default is the two-sided
+case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+sign_test
+ at c ./statistics/tests/sign_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{b}, @var{n}] =} sign_test (@var{x}, @var{y}, @var{alt})
+For two matched-pair samples @var{x} and @var{y}, perform a sign test
+of the null hypothesis PROB (@var{x} > @var{y}) == PROB (@var{x} <
+ at var{y}) == 1/2.  Under the null, the test statistic @var{b} roughly
+follows a binomial distribution with parameters @code{@var{n} = sum
+(@var{x} != @var{y})} and @var{p} = 1/2.
+
+With the optional argument @code{alt}, the alternative of interest
+can be selected.  If @var{alt} is @code{"!="} or @code{"<>"}, the
+null hypothesis is tested against the two-sided alternative PROB
+(@var{x} < @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+one-sided alternative PROB (@var{x} > @var{y}) > 1/2 ("x is
+stochastically greater than y") is considered.  Similarly for
+ at code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) < 1/2
+("x is stochastically less than y") is considered.  The default is
+the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+manova
+ at c ./statistics/tests/manova.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} manova (@var{y}, @var{g})
+Perform a one-way multivariate analysis of variance (MANOVA).  The
+goal is to test whether the p-dimensional population means of data
+taken from @var{k} different groups are all equal.  All data are
+assumed drawn independently from p-dimensional normal distributions
+with the same covariance matrix.
+
+The data matrix is given by @var{y}.  As usual, rows are observations
+and columns are variables.  The vector @var{g} specifies the
+corresponding group labels (e.g., numbers from 1 to @var{k}).
+
+The LR test statistic (Wilks' Lambda) and approximate p-values are
+computed and displayed.
+ at end deftypefn
+wilcoxon_test
+ at c ./statistics/tests/wilcoxon_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} wilcoxon_test (@var{x}, @var{y}, @var{alt})
+For two matched-pair sample vectors @var{x} and @var{y}, perform a
+Wilcoxon signed-rank test of the null hypothesis PROB (@var{x} >
+ at var{y}) == 1/2.  Under the null, the test statistic @var{z}
+approximately follows a standard normal distribution when @var{n} > 25.
+
+ at strong{Warning}: This function assumes a normal distribution for @var{z}
+and thus is invalid for @var{n} <= 25.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+PROB (@var{x} > @var{y}) != 1/2.  If alt is @code{">"}, the one-sided
+alternative PROB (@var{x} > @var{y}) > 1/2 is considered.  Similarly
+for @code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) <
+1/2 is considered.  The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+hotelling_test_2
+ at c ./statistics/tests/hotelling_test_2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{tsq}] =} hotelling_test_2 (@var{x}, @var{y})
+For two samples @var{x} from multivariate normal distributions with
+the same number of variables (columns), unknown means and unknown
+equal covariance matrices, test the null hypothesis @code{mean
+(@var{x}) == mean (@var{y})}.
+
+Hotelling's two-sample @math{T^2} is returned in @var{tsq}.  Under the null,
+
+ at tex
+$$
+{n_x+n_y-p-1) T^2 \over p(n_x+n_y-2)}
+$$
+ at end tex
+ at ifnottex
+ at example
+(n_x+n_y-p-1) T^2 / (p(n_x+n_y-2))
+ at end example
+ at end ifnottex
+
+ at noindent
+has an F distribution with @math{p} and @math{n_x+n_y-p-1} degrees of
+freedom, where @math{n_x} and @math{n_y} are the sample sizes and
+ at math{p} is the number of variables.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+prop_test_2
+ at c ./statistics/tests/prop_test_2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{z}] =} prop_test_2 (@var{x1}, @var{n1}, @var{x2}, @var{n2}, @var{alt})
+If @var{x1} and @var{n1} are the counts of successes and trials in
+one sample, and @var{x2} and @var{n2} those in a second one, test the
+null hypothesis that the success probabilities @var{p1} and @var{p2}
+are the same.  Under the null, the test statistic @var{z}
+approximately follows a standard normal distribution.
+
+With the optional argument string @var{alt}, the alternative of
+interest can be selected.  If @var{alt} is @code{"!="} or
+ at code{"<>"}, the null is tested against the two-sided alternative
+ at var{p1} != @var{p2}.  If @var{alt} is @code{">"}, the one-sided
+alternative @var{p1} > @var{p2} is used.  Similarly for @code{"<"},
+the one-sided alternative @var{p1} < @var{p2} is used.
+The default is the two-sided case.
+
+The p-value of the test is returned in @var{pval}.
+
+If no output argument is given, the p-value of the test is displayed.
+ at end deftypefn
+bartlett_test
+ at c ./statistics/tests/bartlett_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} bartlett_test (@var{x1}, @dots{}) 
+Perform a Bartlett test for the homogeneity of variances in the data
+vectors @var{x1}, @var{x2}, @dots{}, @var{xk}, where @var{k} > 1.
+
+Under the null of equal variances, the test statistic @var{chisq}
+approximately follows a chi-square distribution with @var{df} degrees of
+freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+chisquare_test_homogeneity
+ at c ./statistics/tests/chisquare_test_homogeneity.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} chisquare_test_homogeneity (@var{x}, @var{y}, @var{c})
+Given two samples @var{x} and @var{y}, perform a chisquare test for
+homogeneity of the null hypothesis that @var{x} and @var{y} come from
+the same distribution, based on the partition induced by the
+(strictly increasing) entries of @var{c}.
+
+For large samples, the test statistic @var{chisq} approximately follows a
+chisquare distribution with @var{df} = @code{length (@var{c})}
+degrees of freedom.
+
+The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+returned in @var{pval}.
+
+If no output argument is given, the p-value is displayed.
+ at end deftypefn
+stdnormal_pdf
+ at c ./statistics/distributions/stdnormal_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} stdnormal_pdf (@var{x})
+For each element of @var{x}, compute the probability density function
+(PDF) of the standard normal distribution at @var{x}.
+ at end deftypefn
+binoinv
+ at c ./statistics/distributions/binoinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binoinv (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+binomial distribution with parameters @var{n} and @var{p}.
+ at end deftypefn
+frnd
+ at c ./statistics/distributions/frnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} frnd (@var{m}, @var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} frnd (@var{m}, @var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the F
+distribution with @var{m} and @var{n} degrees of freedom.  Both
+ at var{m} and @var{n} must be scalar or of size @var{r} by @var{c}.
+If @var{sz} is a vector the random samples are in a matrix of 
+size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{m} and @var{n}.
+ at end deftypefn
+gamrnd
+ at c ./statistics/distributions/gamrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gamrnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} gamrnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the Gamma distribution with parameters @var{a}
+and @var{b}.  Both @var{a} and @var{b} must be scalar or of size 
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at seealso{gamma, gammaln, gammainc, gampdf, gamcdf, gaminv}
+ at end deftypefn
+norminv
+ at c ./statistics/distributions/norminv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} norminv (@var{x}, @var{m}, @var{s})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the normal distribution with mean @var{m} and
+standard deviation @var{s}.
+
+Default values are @var{m} = 0, @var{s} = 1.
+ at end deftypefn
+poisscdf
+ at c ./statistics/distributions/poisscdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poisscdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Poisson distribution with parameter
+lambda.
+ at end deftypefn
+poisspdf
+ at c ./statistics/distributions/poisspdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poisspdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the poisson distribution with parameter @var{lambda}.
+ at end deftypefn
+geocdf
+ at c ./statistics/distributions/geocdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geocdf (@var{x}, @var{p})
+For each element of @var{x}, compute the CDF at @var{x} of the
+geometric distribution with parameter @var{p}.
+ at end deftypefn
+empirical_inv
+ at c ./statistics/distributions/empirical_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} empirical_inv (@var{x}, @var{data})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the empirical distribution obtained from the
+univariate sample @var{data}.
+ at end deftypefn
+gaminv
+ at c ./statistics/distributions/gaminv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gaminv (@var{x}, @var{a}, @var{b})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Gamma distribution with parameters @var{a}
+and @var{b}.
+ at seealso{gamma, gammaln, gammainc, gampdf, gamcdf, gamrnd}
+ at end deftypefn
+discrete_cdf
+ at c ./statistics/distributions/discrete_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} discrete_cdf (@var{x}, @var{v}, @var{p})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of a univariate discrete distribution which
+assumes the values in @var{v} with probabilities @var{p}.
+ at end deftypefn
+cauchy_pdf
+ at c ./statistics/distributions/cauchy_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cauchy_pdf (@var{x}, @var{lambda}, @var{sigma})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Cauchy distribution with location parameter
+ at var{lambda} and scale parameter @var{sigma} > 0.  Default values are
+ at var{lambda} = 0, @var{sigma} = 1. 
+ at end deftypefn
+betarnd
+ at c ./statistics/distributions/betarnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} betarnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} betarnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+random samples from the Beta distribution with parameters @var{a} and
+ at var{b}.  Both @var{a} and @var{b} must be scalar or of size @var{r}
+ by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+empirical_rnd
+ at c ./statistics/distributions/empirical_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} empirical_rnd (@var{n}, @var{data})
+ at deftypefnx {Function File} {} empirical_rnd (@var{data}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} empirical_rnd (@var{data}, @var{sz})
+Generate a bootstrap sample of size @var{n} from the empirical
+distribution obtained from the univariate sample @var{data}.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+stdnormal_inv
+ at c ./statistics/distributions/stdnormal_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} stdnormal_inv (@var{x})
+For each component of @var{x}, compute the quantile (the
+inverse of the CDF) at @var{x} of the standard normal distribution.
+ at end deftypefn
+normcdf
+ at c ./statistics/distributions/normcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normcdf (@var{x}, @var{m}, @var{s})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the normal distribution with mean
+ at var{m} and standard deviation @var{s}.
+
+Default values are @var{m} = 0, @var{s} = 1.
+ at end deftypefn
+gampdf
+ at c ./statistics/distributions/gampdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gampdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, return the probability density function
+(PDF) at @var{x} of the Gamma distribution with parameters @var{a}
+and @var{b}.
+ at seealso{gamma, gammaln, gammainc, gamcdf, gaminv, gamrnd}
+ at end deftypefn
+discrete_rnd
+ at c ./statistics/distributions/discrete_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} discrete_rnd (@var{n}, @var{v}, @var{p})
+ at deftypefnx {Function File} {} discrete_rnd (@var{v}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} discrete_rnd (@var{v}, @var{p}, @var{sz})
+Generate a row vector containing a random sample of size @var{n} from
+the univariate distribution which assumes the values in @var{v} with
+probabilities @var{p}.  @var{n} must be a scalar.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+chi2cdf
+ at c ./statistics/distributions/chi2cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chi2cdf (@var{x}, @var{n})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the chisquare distribution with @var{n}
+degrees of freedom.
+ at end deftypefn
+expinv
+ at c ./statistics/distributions/expinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} expinv (@var{x}, @var{lambda})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the exponential distribution with mean
+ at var{lambda}.
+ at end deftypefn
+chi2pdf
+ at c ./statistics/distributions/chi2pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chisquare_pdf (@var{x}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the chisquare distribution with @var{n} degrees
+of freedom.
+ at end deftypefn
+unifcdf
+ at c ./statistics/distributions/unifcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unifcdf (@var{x}, @var{a}, @var{b})
+Return the CDF at @var{x} of the uniform distribution on [@var{a},
+ at var{b}], i.e., PROB (uniform (@var{a}, @var{b}) <= x).
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+betapdf
+ at c ./statistics/distributions/betapdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} betapdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, returns the PDF at @var{x} of the beta
+distribution with parameters @var{a} and @var{b}.
+ at end deftypefn
+stdnormal_rnd
+ at c ./statistics/distributions/stdnormal_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} stdnormal_rnd (@var{r}, @var{c})
+ at deftypefnx {Function File} {} stdnormal_rnd (@var{sz})
+Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+random numbers from the standard normal distribution.
+ at end deftypefn
+unidrnd
+ at c ./statistics/distributions/unidrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unidrnd (@var{mx});
+ at deftypefnx {Function File} {} unidrnd (@var{mx}, @var{v});
+ at deftypefnx {Function File} {} unidrnd (@var{mx}, @var{m}, @var{n}, @dots{});
+Return random values from discrete uniform distribution, with maximum
+value(s) given by the integer @var{mx}, which may be a scalar or
+multidimensional array.
+
+If @var{mx} is a scalar, the size of the result is specified by
+the vector @var{v}, or by the optional arguments @var{m}, @var{n},
+ at dots{}.  Otherwise, the size of the result is the same as the size
+of @var{mx}.
+ at end deftypefn
+hygepdf
+ at c ./statistics/distributions/hygepdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hygepdf (@var{x}, @var{t}, @var{m}, @var{n})
+Compute the probability density function (PDF) at @var{x} of the
+hypergeometric distribution with parameters @var{t}, @var{m}, and
+ at var{n}.  This is the probability of obtaining @var{x} marked items
+when randomly drawing a sample of size @var{n} without replacement
+from a population of total size @var{t} containing @var{m} marked items.
+
+The arguments must be of common size or scalar.
+ at end deftypefn
+wblrnd
+ at c ./statistics/distributions/wblrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wblrnd (@var{scale}, @var{shape}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} wblrnd (@var{scale}, @var{shape}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+Weibull distribution with parameters @var{scale} and @var{shape}
+which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+is a vector return a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{alpha} and @var{sigma}.
+ at end deftypefn
+cauchy_cdf
+ at c ./statistics/distributions/cauchy_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cauchy_cdf (@var{x}, @var{lambda}, @var{sigma})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Cauchy distribution with location
+parameter @var{lambda} and scale parameter @var{sigma}.  Default
+values are @var{lambda} = 0, @var{sigma} = 1. 
+ at end deftypefn
+normrnd
+ at c ./statistics/distributions/normrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normrnd (@var{m}, @var{s}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} normrnd (@var{m}, @var{s}, @var{sz})
+Return an @var{r} by @var{c}  or @code{size (@var{sz})} matrix of
+random samples from the normal distribution with parameters mean @var{m} 
+and standard deviation @var{s}.  Both @var{m} and @var{s} must be scalar 
+or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{m} and @var{s}.
+ at end deftypefn
+exppdf
+ at c ./statistics/distributions/exppdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} exppdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the probability density function
+(PDF) of the exponential distribution with mean @var{lambda}.
+ at end deftypefn
+unidinv
+ at c ./statistics/distributions/unidinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unidinv (@var{x}, @var{v})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the univariate discrete distribution which assumes the
+values in @var{v} with equal probability
+ at end deftypefn
+finv
+ at c ./statistics/distributions/finv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} finv (@var{x}, @var{m}, @var{n})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the F distribution with parameters @var{m} and
+ at var{n}.
+ at end deftypefn
+normpdf
+ at c ./statistics/distributions/normpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} normpdf (@var{x}, @var{m}, @var{s})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the normal distribution with mean @var{m} and
+standard deviation @var{s}.
+
+Default values are @var{m} = 0, @var{s} = 1.
+ at end deftypefn
+logninv
+ at c ./statistics/distributions/logninv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logninv (@var{x}, @var{mu}, @var{sigma})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the lognormal distribution with parameters @var{mu}
+and @var{sigma}.  If a random variable follows this distribution, its
+logarithm is normally distributed with mean @code{log (@var{mu})} and
+variance @var{sigma}.
+
+Default values are @var{mu} = 1, @var{sigma} = 1.
+ at end deftypefn
+expcdf
+ at c ./statistics/distributions/expcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} expcdf (@var{x}, @var{lambda})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the exponential distribution with
+mean @var{lambda}.
+
+The arguments can be of common size or scalar.
+ at end deftypefn
+logncdf
+ at c ./statistics/distributions/logncdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logncdf (@var{x}, @var{mu}, @var{sigma})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the lognormal distribution with
+parameters @var{mu} and @var{sigma}.  If a random variable follows this
+distribution, its logarithm is normally distributed with mean
+ at var{mu} and standard deviation @var{sigma}.
+
+Default values are @var{mu} = 1, @var{sigma} = 1.
+ at end deftypefn
+laplace_pdf
+ at c ./statistics/distributions/laplace_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} laplace_pdf (@var{x})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Laplace distribution.
+ at end deftypefn
+laplace_rnd
+ at c ./statistics/distributions/laplace_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} laplace_rnd (@var{r}, @var{c})
+ at deftypefnx {Function File} {} laplace_rnd (@var{sz});
+Return an @var{r} by @var{c} matrix of random numbers from the
+Laplace distribution.  Or if @var{sz} is a vector, create a matrix of
+ at var{sz}.
+ at end deftypefn
+lognrnd
+ at c ./statistics/distributions/lognrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lognrnd (@var{mu}, @var{sigma}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} lognrnd (@var{mu}, @var{sigma}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+lognormal distribution with parameters @var{mu} and @var{sigma}.  Both
+ at var{mu} and @var{sigma} must be scalar or of size @var{r} by @var{c}.
+Or if @var{sz} is a vector, create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{mu} and @var{sigma}.
+ at end deftypefn
+poissinv
+ at c ./statistics/distributions/poissinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poissinv (@var{x}, @var{lambda})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Poisson distribution with parameter
+ at var{lambda}.
+ at end deftypefn
+hygeinv
+ at c ./statistics/distributions/hygeinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hygeinv (@var{x}, @var{t}, @var{m}, @var{n})
+For each element of @var{x}, compute the quantile at @var{x} of the
+hypergeometric distribution with parameters @var{t}, @var{m}, and
+ at var{n}.
+
+The parameters @var{t}, @var{m}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+fcdf
+ at c ./statistics/distributions/fcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fcdf (@var{x}, @var{m}, @var{n})
+For each element of @var{x}, compute the CDF at @var{x} of the F
+distribution with @var{m} and @var{n} degrees of freedom, i.e.,
+PROB (F (@var{m}, @var{n}) <= @var{x}). 
+ at end deftypefn
+stdnormal_cdf
+ at c ./statistics/distributions/stdnormal_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} stdnormal_cdf (@var{x})
+For each component of @var{x}, compute the CDF of the standard normal
+distribution at @var{x}.
+ at end deftypefn
+nbininv
+ at c ./statistics/distributions/nbininv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nbininv (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+Pascal (negative binomial) distribution with parameters @var{n} and
+ at var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution.
+ at end deftypefn
+logistic_inv
+ at c ./statistics/distributions/logistic_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logistic_inv (@var{x})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the logistic distribution.
+ at end deftypefn
+hygecdf
+ at c ./statistics/distributions/hygecdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hygecdf (@var{x}, @var{t}, @var{m}, @var{n})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+hypergeometric distribution with parameters @var{t}, @var{m}, and
+ at var{n}.  This is the probability of obtaining not more than @var{x}
+marked items when randomly drawing a sample of size @var{n} without
+replacement from a population of total size @var{t} containing
+ at var{m} marked items.
+
+The parameters @var{t}, @var{m}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+ at end deftypefn
+unidpdf
+ at c ./statistics/distributions/unidpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unidpdf (@var{x}, @var{v})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of a univariate discrete distribution which assumes
+the values in @var{v} with equal probability.
+ at end deftypefn
+logistic_cdf
+ at c ./statistics/distributions/logistic_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logistic_cdf (@var{x})
+For each component of @var{x}, compute the CDF at @var{x} of the
+logistic distribution.
+ at end deftypefn
+gamcdf
+ at c ./statistics/distributions/gamcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gamcdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Gamma distribution with parameters
+ at var{a} and @var{b}.
+ at seealso{gamma, gammaln, gammainc, gampdf, gaminv, gamrnd}
+ at end deftypefn
+unifinv
+ at c ./statistics/distributions/unifinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unifinv (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the uniform distribution on [@var{a}, @var{b}].
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+tpdf
+ at c ./statistics/distributions/tpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} tpdf (@var{x}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the @var{t} (Student) distribution with @var{n}
+degrees of freedom. 
+ at end deftypefn
+nbinpdf
+ at c ./statistics/distributions/nbinpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nbinpdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the Pascal (negative binomial) distribution with
+parameters @var{n} and @var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution. 
+ at end deftypefn
+geoinv
+ at c ./statistics/distributions/geoinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geoinv (@var{x}, @var{p})
+For each element of @var{x}, compute the quantile at @var{x} of the
+geometric distribution with parameter @var{p}.
+ at end deftypefn
+discrete_inv
+ at c ./statistics/distributions/discrete_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} discrete_inv (@var{x}, @var{v}, @var{p})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the univariate distribution which assumes the
+values in @var{v} with probabilities @var{p}.
+ at end deftypefn
+unidcdf
+ at c ./statistics/distributions/unidcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unidcdf (@var{x}, @var{v})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of a univariate discrete distribution which
+assumes the values in @var{v} with equal probability.
+ at end deftypefn
+binopdf
+ at c ./statistics/distributions/binopdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binopdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the binomial distribution with parameters @var{n}
+and @var{p}.
+ at end deftypefn
+wblcdf
+ at c ./statistics/distributions/wblcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wblcdf (@var{x}, @var{scale}, @var{shape})
+Compute the cumulative distribution function (CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}, which is
+
+ at tex
+$$ 1 - \exp(-(x/shape)^{scale}) $$
+for $x\geq 0$.
+ at end tex
+ at ifnottex
+ at example
+1 - exp(-(x/shape)^scale)
+ at end example
+for @var{x} >= 0.
+ at end ifnottex
+ at end deftypefn
+hygernd
+ at c ./statistics/distributions/hygernd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hygernd (@var{t}, @var{m}, @var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} hygernd (@var{t}, @var{m}, @var{n}, @var{sz})
+ at deftypefnx {Function File} {} hygernd (@var{t}, @var{m}, @var{n})
+Return an @var{r} by @var{c} matrix of random samples from the
+hypergeometric distribution with parameters @var{t}, @var{m},
+and @var{n}.
+
+The parameters @var{t}, @var{m}, and @var{n} must positive integers
+with @var{m} and @var{n} not greater than @var{t}.
+
+The parameter @var{sz} must be scalar or a vector of matrix
+dimensions.  If @var{sz} is scalar, then a @var{sz} by @var{sz}
+matrix of random samples is generated.
+ at end deftypefn
+trnd
+ at c ./statistics/distributions/trnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} trnd (@var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} trnd (@var{n}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the t
+(Student) distribution with @var{n} degrees of freedom.  @var{n} must
+be a scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a
+vector create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{n}.
+ at end deftypefn
+kolmogorov_smirnov_cdf
+ at c ./statistics/distributions/kolmogorov_smirnov_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} kolmogorov_smirnov_cdf (@var{x}, @var{tol})
+Return the CDF at @var{x} of the Kolmogorov-Smirnov distribution,
+ at tex
+$$ Q(x) = \sum_{k=-\infty}^\infty (-1)^k \exp(-2 k^2 x^2) $$
+ at end tex
+ at ifnottex
+ at example
+ at group
+         Inf
+Q(x) =   SUM    (-1)^k exp(-2 k^2 x^2)
+       k = -Inf
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+for @var{x} > 0.
+
+The optional parameter @var{tol} specifies the precision up to which
+the series should be evaluated;  the default is @var{tol} = @code{eps}.
+ at end deftypefn
+laplace_cdf
+ at c ./statistics/distributions/laplace_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} laplace_cdf (@var{x})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the Laplace distribution.
+ at end deftypefn
+exprnd
+ at c ./statistics/distributions/exprnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} exprnd (@var{lambda}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} exprnd (@var{lambda}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+exponential distribution with mean @var{lambda}, which must be a
+scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a vector, 
+create a matrix of size @var{sz}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{lambda}.
+ at end deftypefn
+poissrnd
+ at c ./statistics/distributions/poissrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poissrnd (@var{lambda}, @var{r}, @var{c})
+Return an @var{r} by @var{c} matrix of random samples from the
+Poisson distribution with parameter @var{lambda}, which must be a 
+scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{lambda}.
+ at end deftypefn
+chi2inv
+ at c ./statistics/distributions/chi2inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chi2inv (@var{x}, @var{n})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the chisquare distribution with @var{n} degrees of
+freedom.
+ at end deftypefn
+unifrnd
+ at c ./statistics/distributions/unifrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unifrnd (@var{a}, @var{b}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} unifrnd (@var{a}, @var{b}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the uniform distribution on [@var{a}, @var{b}]. 
+Both @var{a} and @var{b} must be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{a} and @var{b}.
+ at end deftypefn
+logistic_rnd
+ at c ./statistics/distributions/logistic_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logistic_rnd (@var{r}, @var{c})
+ at deftypefnx {Function File} {} logistic_rnd (@var{sz})
+Return an @var{r} by @var{c} matrix of random numbers from the
+logistic distribution.  Or if @var{sz} is a vector, create a matrix of
+ at var{sz}.
+ at end deftypefn
+cauchy_rnd
+ at c ./statistics/distributions/cauchy_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cauchy_rnd (@var{lambda}, @var{sigma}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} cauchy_rnd (@var{lambda}, @var{sigma}, @var{sz})
+Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+random samples from the Cauchy distribution with parameters @var{lambda} 
+and @var{sigma} which must both be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{lambda} and @var{sigma}.
+ at end deftypefn
+betainv
+ at c ./statistics/distributions/betainv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} betainv (@var{x}, @var{a}, @var{b})
+For each component of @var{x}, compute the quantile (the inverse of
+the CDF) at @var{x} of the Beta distribution with parameters @var{a}
+and @var{b}.
+ at end deftypefn
+unifpdf
+ at c ./statistics/distributions/unifpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unifpdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, compute the PDF at @var{x} of the uniform
+distribution on [@var{a}, @var{b}].
+
+Default values are @var{a} = 0, @var{b} = 1.
+ at end deftypefn
+betacdf
+ at c ./statistics/distributions/betacdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} betacdf (@var{x}, @var{a}, @var{b})
+For each element of @var{x}, returns the CDF at @var{x} of the beta
+distribution with parameters @var{a} and @var{b}, i.e.,
+PROB (beta (@var{a}, @var{b}) <= @var{x}).
+ at end deftypefn
+lognpdf
+ at c ./statistics/distributions/lognpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lognpdf (@var{x}, @var{mu}, @var{sigma})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the lognormal distribution with parameters
+ at var{mu} and @var{sigma}.  If a random variable follows this distribution,
+its logarithm is normally distributed with mean @var{mu}
+and standard deviation @var{sigma}.
+
+Default values are @var{mu} = 1, @var{sigma} = 1.
+ at end deftypefn
+nbincdf
+ at c ./statistics/distributions/nbincdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nbincdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the CDF at x of the Pascal
+(negative binomial) distribution with parameters @var{n} and @var{p}.
+
+The number of failures in a Bernoulli experiment with success
+probability @var{p} before the @var{n}-th success follows this
+distribution.
+ at end deftypefn
+geopdf
+ at c ./statistics/distributions/geopdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geopdf (@var{x}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the geometric distribution with parameter @var{p}.
+ at end deftypefn
+wienrnd
+ at c ./statistics/distributions/wienrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wienrnd (@var{t}, @var{d}, @var{n})
+Return a simulated realization of the @var{d}-dimensional Wiener Process
+on the interval [0, @var{t}].  If @var{d} is omitted, @var{d} = 1 is
+used.  The first column of the return matrix contains time, the
+remaining columns contain the Wiener process.
+
+The optional parameter @var{n} gives the number of summands used for
+simulating the process over an interval of length 1.  If @var{n} is
+omitted, @var{n} = 1000 is used.
+ at end deftypefn
+empirical_cdf
+ at c ./statistics/distributions/empirical_cdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} empirical_cdf (@var{x}, @var{data})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the empirical distribution obtained from
+the univariate sample @var{data}.
+ at end deftypefn
+geornd
+ at c ./statistics/distributions/geornd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} geornd (@var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} geornd (@var{p}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the
+geometric distribution with parameter @var{p}, which must be a scalar
+or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+ at var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+ at var{sz}.
+ at end deftypefn
+binocdf
+ at c ./statistics/distributions/binocdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binocdf (@var{x}, @var{n}, @var{p})
+For each element of @var{x}, compute the CDF at @var{x} of the
+binomial distribution with parameters @var{n} and @var{p}.
+ at end deftypefn
+tinv
+ at c ./statistics/distributions/tinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} tinv (@var{x}, @var{n})
+For each probability value @var{x}, compute the inverse of the
+cumulative distribution function (CDF) of the t (Student)
+distribution with degrees of freedom @var{n}.  This function is
+analogous to looking in a table for the t-value of a single-tailed
+distribution.
+ at end deftypefn
+binornd
+ at c ./statistics/distributions/binornd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} binornd (@var{n}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} binornd (@var{n}, @var{p}, @var{sz})
+Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+random samples from the binomial distribution with parameters @var{n}
+and @var{p}.  Both @var{n} and @var{p} must be scalar or of size
+ at var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{n} and @var{p}.
+ at end deftypefn
+tcdf
+ at c ./statistics/distributions/tcdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} tcdf (@var{x}, @var{n})
+For each element of @var{x}, compute the cumulative distribution
+function (CDF) at @var{x} of the t (Student) distribution with
+ at var{n} degrees of freedom, i.e., PROB (t(@var{n}) <= @var{x}).
+ at end deftypefn
+fpdf
+ at c ./statistics/distributions/fpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fpdf (@var{x}, @var{m}, @var{n})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the F distribution with @var{m} and @var{n}
+degrees of freedom.
+ at end deftypefn
+wblinv
+ at c ./statistics/distributions/wblinv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wblinv (@var{x}, @var{scale}, @var{shape})
+Compute the quantile (the inverse of the CDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape}.
+ at end deftypefn
+cauchy_inv
+ at c ./statistics/distributions/cauchy_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cauchy_inv (@var{x}, @var{lambda}, @var{sigma})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the Cauchy distribution with location parameter
+ at var{lambda} and scale parameter @var{sigma}.  Default values are
+ at var{lambda} = 0, @var{sigma} = 1. 
+ at end deftypefn
+nbinrnd
+ at c ./statistics/distributions/nbinrnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nbinrnd (@var{n}, @var{p}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} nbinrnd (@var{n}, @var{p}, @var{sz})
+Return an @var{r} by @var{c} matrix of random samples from the Pascal
+(negative binomial) distribution with parameters @var{n} and @var{p}.
+Both @var{n} and @var{p} must be scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the common size of @var{n} and @var{p}.  Or if @var{sz} is a vector, 
+create a matrix of size @var{sz}.
+ at end deftypefn
+empirical_pdf
+ at c ./statistics/distributions/empirical_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} empirical_pdf (@var{x}, @var{data})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of the empirical distribution obtained from the
+univariate sample @var{data}.
+ at end deftypefn
+wblpdf
+ at c ./statistics/distributions/wblpdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wblpdf (@var{x}, @var{scale}, @var{shape})
+Compute the probability density function (PDF) at @var{x} of the
+Weibull distribution with shape parameter @var{scale} and scale
+parameter @var{shape} which is given by
+
+ at tex
+$$  scale \cdot shape^{-scale} x^{scale-1} \exp(-(x/shape)^{scale}) $$
+ at end tex
+ at ifnottex
+ at example
+   scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+ at end example
+ at end ifnottex
+
+ at noindent
+for @var{x} > 0.
+ at end deftypefn
+laplace_inv
+ at c ./statistics/distributions/laplace_inv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} laplace_inv (@var{x})
+For each element of @var{x}, compute the quantile (the inverse of the
+CDF) at @var{x} of the Laplace distribution.
+ at end deftypefn
+chi2rnd
+ at c ./statistics/distributions/chi2rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} chi2rnd (@var{n}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} chi2rnd (@var{n}, @var{sz})
+Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+random samples from the chisquare distribution with @var{n} degrees 
+of freedom.  @var{n} must be a scalar or of size @var{r} by @var{c}.
+
+If @var{r} and @var{c} are omitted, the size of the result matrix is
+the size of @var{n}.
+ at end deftypefn
+discrete_pdf
+ at c ./statistics/distributions/discrete_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} discrete_pdf (@var{x}, @var{v}, @var{p})
+For each element of @var{x}, compute the probability density function
+(PDF) at @var{x} of a univariate discrete distribution which assumes
+the values in @var{v} with probabilities @var{p}.
+ at end deftypefn
+logistic_pdf
+ at c ./statistics/distributions/logistic_pdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logistic_pdf (@var{x})
+For each component of @var{x}, compute the PDF at @var{x} of the
+logistic distribution.
+ at end deftypefn
+logistic_regression_derivatives
+ at c ./statistics/models/logistic_regression_derivatives.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{dl}, @var{d2l}] =} logistic_regression_derivatives (@var{x}, @var{z}, @var{z1}, @var{g}, @var{g1}, @var{p})
+Called by logistic_regression.  Calculates derivates of the
+log-likelihood for ordinal logistic regression model.
+ at end deftypefn
+logistic_regression
+ at c ./statistics/models/logistic_regression.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{theta}, @var{beta}, @var{dev}, @var{dl}, @var{d2l}, @var{p}] =} logistic_regression (@var{y}, @var{x}, @var{print}, @var{theta}, @var{beta})
+Perform ordinal logistic regression.
+
+Suppose @var{y} takes values in @var{k} ordered categories, and let
+ at code{gamma_i (@var{x})} be the cumulative probability that @var{y}
+falls in one of the first @var{i} categories given the covariate
+ at var{x}.  Then
+
+ at example
+[theta, beta] = logistic_regression (y, x)
+ at end example
+
+ at noindent
+fits the model
+
+ at example
+logit (gamma_i (x)) = theta_i - beta' * x,   i = 1 @dots{} k-1
+ at end example
+
+The number of ordinal categories, @var{k}, is taken to be the number
+of distinct values of @code{round (@var{y})}.  If @var{k} equals 2,
+ at var{y} is binary and the model is ordinary logistic regression.  The
+matrix @var{x} is assumed to have full column rank.
+
+Given @var{y} only, @code{theta = logistic_regression (y)}
+fits the model with baseline logit odds only.
+
+The full form is
+
+ at example
+ at group
+[theta, beta, dev, dl, d2l, gamma]
+   = logistic_regression (y, x, print, theta, beta)
+ at end group
+ at end example
+
+ at noindent
+in which all output arguments and all input arguments except @var{y}
+are optional.
+
+Setting @var{print} to 1 requests summary information about the fitted
+model to be displayed.  Setting @var{print} to 2 requests information
+about convergence at each iteration.  Other values request no
+information to be displayed.  The input arguments @var{theta} and
+ at var{beta} give initial estimates for @var{theta} and @var{beta}.
+
+The returned value @var{dev} holds minus twice the log-likelihood.
+
+The returned values @var{dl} and @var{d2l} are the vector of first
+and the matrix of second derivatives of the log-likelihood with
+respect to @var{theta} and @var{beta}.
+
+ at var{p} holds estimates for the conditional distribution of @var{y}
+given @var{x}.
+ at end deftypefn
+logistic_regression_likelihood
+ at c ./statistics/models/logistic_regression_likelihood.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{g}, @var{g1}, @var{p}, @var{dev}] =} logistic_regression_likelihood (@var{y}, @var{x}, @var{beta}, @var{z}, @var{z1})
+Calculates likelihood for the ordinal logistic regression model.
+Called by logistic_regression.
+ at end deftypefn
+spearman
+ at c ./statistics/base/spearman.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spearman (@var{x}, @var{y})
+Compute Spearman's rank correlation coefficient @var{rho} for each of
+the variables specified by the input arguments.
+
+For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+ at code{spearman (@var{x})} is equivalent to @code{spearman (@var{x},
+ at var{x})}.
+
+For two data vectors @var{x} and @var{y}, Spearman's @var{rho} is the
+correlation of the ranks of @var{x} and @var{y}.
+
+If @var{x} and @var{y} are drawn from independent distributions,
+ at var{rho} has zero mean and variance @code{1 / (n - 1)}, and is
+asymptotically normally distributed.
+ at end deftypefn
+__quantile__
+ at c ./statistics/base/__quantile__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{q} =} __quantile__ (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{q} =} __quantile__ (@var{x}, @var{p}, @var{method})
+Undocumented internal function.
+ at end deftypefn
+ols
+ at c ./statistics/base/ols.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{beta}, @var{sigma}, @var{r}] =} ols (@var{y}, @var{x})
+Ordinary least squares estimation for the multivariate model
+ at tex
+$y = x b + e$
+with
+$\bar{e} = 0$, and cov(vec($e$)) = kron ($s, I$)
+ at end tex
+ at ifnottex
+ at math{y = x b + e} with
+ at math{mean (e) = 0} and @math{cov (vec (e)) = kron (s, I)}.
+ at end ifnottex
+ where
+ at tex
+$y$ is a $t \times p$ matrix, $x$ is a $t \times k$ matrix,
+$b$ is a $k \times p$ matrix, and $e$ is a $t \times p$ matrix.
+ at end tex
+ at ifnottex
+ at math{y} is a @math{t} by @math{p} matrix, @math{x} is a @math{t} by
+ at math{k} matrix, @math{b} is a @math{k} by @math{p} matrix, and
+ at math{e} is a @math{t} by @math{p} matrix.
+ at end ifnottex
+
+Each row of @var{y} and @var{x} is an observation and each column a
+variable.
+
+The return values @var{beta}, @var{sigma}, and @var{r} are defined as
+follows.
+
+ at table @var
+ at item beta
+The OLS estimator for @var{b}, @code{@var{beta} = pinv (@var{x}) *
+ at var{y}}, where @code{pinv (@var{x})} denotes the pseudoinverse of
+ at var{x}.
+
+ at item sigma
+The OLS estimator for the matrix @var{s},
+
+ at example
+ at group
+ at var{sigma} = (@var{y}- at var{x}*@var{beta})'
+  * (@var{y}- at var{x}*@var{beta})
+  / (@var{t}-rank(@var{x}))
+ at end group
+ at end example
+
+ at item r
+The matrix of OLS residuals, @code{@var{r} = @var{y} - @var{x} *
+ at var{beta}}.
+ at end table
+ at end deftypefn
+mode
+ at c ./statistics/base/mode.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{m}, @var{f}, @var{c}] =} mode (@var{x}, @var{dim})
+Count the most frequently appearing value.  @code{mode} counts the 
+frequency along the first non-singleton dimension and if two or more
+values have the same frequency returns the smallest of the two in
+ at var{m}.  The dimension along which to count can be specified by the
+ at var{dim} parameter.
+
+The variable @var{f} counts the frequency of each of the most frequently 
+occurring elements.  The cell array @var{c} contains all of the elements
+with the maximum frequency .
+ at end deftypefn
+probit
+ at c ./statistics/base/probit.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} probit (@var{p})
+For each component of @var{p}, return the probit (the quantile of the
+standard normal distribution) of @var{p}.
+ at end deftypefn
+ppplot
+ at c ./statistics/base/ppplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{p}, @var{y}] =} ppplot (@var{x}, @var{dist}, @var{params})
+Perform a PP-plot (probability plot).
+
+If F is the CDF of the distribution @var{dist} with parameters
+ at var{params} and @var{x} a sample vector of length @var{n}, the
+PP-plot graphs ordinate @var{y}(@var{i}) = F (@var{i}-th largest
+element of @var{x}) versus abscissa @var{p}(@var{i}) = (@var{i} -
+0.5)/@var{n}.  If the sample comes from F, the pairs will
+approximately follow a straight line.
+
+The default for @var{dist} is the standard normal distribution.  The
+optional argument @var{params} contains a list of parameters of
+ at var{dist}.  For example, for a probability plot of the uniform
+distribution on [2,4] and @var{x}, use
+
+ at example
+ppplot (x, "uniform", 2, 4)
+ at end example
+
+ at noindent
+ at var{dist} can be any string for which a function @var{dist_cdf}
+that calculates the CDF of distribution @var{dist} exists.
+
+If no output arguments are given, the data are plotted directly.
+ at end deftypefn
+qqplot
+ at c ./statistics/base/qqplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{q}, @var{s}] =} qqplot (@var{x}, @var{dist}, @var{params})
+Perform a QQ-plot (quantile plot).
+
+If F is the CDF of the distribution @var{dist} with parameters
+ at var{params} and G its inverse, and @var{x} a sample vector of length
+ at var{n}, the QQ-plot graphs ordinate @var{s}(@var{i}) = @var{i}-th
+largest element of x versus abscissa @var{q}(@var{i}f) = G((@var{i} -
+0.5)/@var{n}).
+
+If the sample comes from F except for a transformation of location
+and scale, the pairs will approximately follow a straight line.
+
+The default for @var{dist} is the standard normal distribution.  The
+optional argument @var{params} contains a list of parameters of
+ at var{dist}.  For example, for a quantile plot of the uniform
+distribution on [2,4] and @var{x}, use
+
+ at example
+qqplot (x, "uniform", 2, 4)
+ at end example
+
+ at noindent
+ at var{dist} can be any string for which a function @var{dist_inv}
+that calculates the inverse CDF of distribution @var{dist} exists.
+
+If no output arguments are given, the data are plotted directly.
+ at end deftypefn
+median
+ at c ./statistics/base/median.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} median (@var{x}, @var{dim})
+If @var{x} is a vector, compute the median value of the elements of
+ at var{x}.  If the elements of @var{x} are sorted, the median is defined
+as
+ at tex
+$$
+{\rm median} (x) =
+  \cases{x(\lceil N/2\rceil), & $N$ odd;\cr
+          (x(N/2)+x(N/2+1))/2, & $N$ even.}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+            x(ceil(N/2)),             N odd
+median(x) =
+            (x(N/2) + x((N/2)+1))/2,  N even
+ at end group
+ at end example
+ at end ifnottex
+If @var{x} is a matrix, compute the median value for each
+column and return them in a row vector.  If the optional @var{dim}
+argument is given, operate along this dimension.
+ at seealso{std, mean}
+ at end deftypefn
+cov
+ at c ./statistics/base/cov.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cov (@var{x}, @var{y})
+Compute covariance.
+
+If each row of @var{x} and @var{y} is an observation and each column is
+a variable, the (@var{i}, @var{j})-th entry of
+ at code{cov (@var{x}, @var{y})} is the covariance between the @var{i}-th
+variable in @var{x} and the @var{j}-th variable in @var{y}.
+ at tex
+$$
+\sigma_{ij} = {1 \over N-1} \sum_{i=1}^N (x_i - \bar{x})(y_i - \bar{y})
+$$
+where $\bar{x}$ and $\bar{y}$ are the mean values of $x$ and $y$.
+ at end tex
+If called with one argument, compute @code{cov (@var{x}, @var{x})}.
+ at end deftypefn
+table
+ at c ./statistics/base/table.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{t}, @var{l_x}] =} table (@var{x})
+ at deftypefnx {Function File} {[@var{t}, @var{l_x}, @var{l_y}] =} table (@var{x}, @var{y})
+Create a contingency table @var{t} from data vectors.  The @var{l}
+vectors are the corresponding levels.
+
+Currently, only 1- and 2-dimensional tables are supported.
+ at end deftypefn
+histc
+ at c ./statistics/base/histc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{n} =} histc (@var{y}, @var{edges})
+ at deftypefnx {Function File} {@var{n} =} histc (@var{y}, @var{edges}, @var{dim})
+ at deftypefnx {Function File} {[@var{n}, @var{idx}] =} histc (@dots{})
+Produce histogram counts.
+
+When @var{y} is a vector, the function counts the number of elements of
+ at var{y} that fall in the histogram bins defined by @var{edges}.  This must be
+a vector of monotonically non-decreasing values that define the edges of the
+histogram bins.  So, @code{@var{n} (k)} contains the number of elements in
+ at var{y} for which @code{@var{edges} (k) <= @var{y} < @var{edges} (k+1)}.
+The final element of @var{n} contains the number of elements of @var{y}
+that was equal to the last element of @var{edges}.
+
+When @var{y} is a @math{N}-dimensional array, the same operation as above is
+repeated along dimension @var{dim}.  If this argument is given, the operation
+is performed along the first non-singleton dimension.
+
+If a second output argument is requested an index matrix is also returned.
+The @var{idx} matrix has same size as @var{y}.  Each element of @var{idx}
+contains the index of the histogram bin in which the corresponding element
+of @var{y} was counted.
+
+ at seealso{hist}
+ at end deftypefn
+std
+ at c ./statistics/base/std.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} std (@var{x})
+ at deftypefnx {Function File} {} std (@var{x}, @var{opt})
+ at deftypefnx {Function File} {} std (@var{x}, @var{opt}, @var{dim})
+If @var{x} is a vector, compute the standard deviation of the elements
+of @var{x}.
+ at tex
+$$
+{\rm std} (x) = \sigma (x) = \sqrt{{\sum_{i=1}^N (x_i - \bar{x})^2 \over N - 1}}
+$$
+where $\bar{x}$ is the mean value of $x$.
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+std (x) = sqrt (sumsq (x - mean (x)) / (n - 1))
+ at end group
+ at end example
+ at end ifnottex
+If @var{x} is a matrix, compute the standard deviation for
+each column and return them in a row vector.
+
+The argument @var{opt} determines the type of normalization to use.  Valid values
+are
+
+ at table @asis 
+ at item 0:
+  normalizes with @math{N-1}, provides the square root of best unbiased estimator of 
+  the variance [default]
+ at item 1:
+  normalizes with @math{N}, this provides the square root of the second moment around 
+  the mean
+ at end table
+
+The third argument @var{dim} determines the dimension along which the standard
+deviation is calculated.
+ at seealso{mean, median}
+ at end deftypefn
+range
+ at c ./statistics/base/range.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} range (@var{x})
+ at deftypefnx {Function File} {} range (@var{x}, @var{dim})
+If @var{x} is a vector, return the range, i.e., the difference
+between the maximum and the minimum, of the input data.
+
+If @var{x} is a matrix, do the above for each column of @var{x}.
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.
+ at end deftypefn
+skewness
+ at c ./statistics/base/skewness.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} skewness (@var{x}, @var{dim})
+If @var{x} is a vector of length @math{n}, return the skewness
+ at tex
+$$
+{\rm skewness} (x) = {1\over N \sigma(x)^3} \sum_{i=1}^N (x_i-\bar{x})^3
+$$
+where $\bar{x}$ is the mean value of $x$.
+ at end tex
+ at ifnottex
+
+ at example
+skewness (x) = N^(-1) std(x)^(-3) sum ((x - mean(x)).^3)
+ at end example
+ at end ifnottex
+
+ at noindent
+of @var{x}.  If @var{x} is a matrix, return the skewness along the
+first non-singleton dimension of the matrix.  If the optional
+ at var{dim} argument is given, operate along this dimension.
+ at end deftypefn
+studentize
+ at c ./statistics/base/studentize.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} studentize (@var{x}, @var{dim})
+If @var{x} is a vector, subtract its mean and divide by its standard
+deviation.
+
+If @var{x} is a matrix, do the above along the first non-singleton
+dimension.  If the optional argument @var{dim} is given then operate
+along this dimension.
+ at end deftypefn
+var
+ at c ./statistics/base/var.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} var (@var{x})
+For vector arguments, return the (real) variance of the values.
+For matrix arguments, return a row vector containing the variance for
+each column.
+
+The argument @var{opt} determines the type of normalization to use.
+Valid values are
+
+ at table @asis 
+ at item 0:
+Normalizes with @math{N-1}, provides the best unbiased estimator of the
+variance [default].
+ at item 1:
+Normalizes with @math{N}, this provides the second moment around the mean.
+ at end table
+
+The third argument @var{dim} determines the dimension along which the 
+variance is calculated.
+ at end deftypefn
+values
+ at c ./statistics/base/values.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} values (@var{x})
+Return the different values in a column vector, arranged in ascending
+order.
+
+As an example, @code{values([1, 2, 3, 1])} returns the vector
+ at code{[1, 2, 3]}.
+ at end deftypefn
+ranks
+ at c ./statistics/base/ranks.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ranks (@var{x}, @var{dim})
+Return the ranks of @var{x} along the first non-singleton dimension
+adjust for ties.  If the optional argument @var{dim} is
+given, operate along this dimension.
+ at end deftypefn
+prctile
+ at c ./statistics/base/prctile.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} prctile (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{q} =} prctile (@var{x}, @var{p}, @var{dim})
+For a sample @var{x}, compute the quantiles, @var{y}, corresponding
+to the cumulative probability values, P, in percent.  All non-numeric
+values (NaNs) of X are ignored.
+
+If @var{x} is a matrix, compute the percentiles for each column and
+return them in a matrix, such that the i-th row of @var{y} contains the 
+ at var{p}(i)th percentiles of each column of @var{x}.
+
+The optional argument @var{dim} determines the dimension along which
+the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
+a vector or matrix, it defaults to 1 (column wise quantiles).  In the 
+instance that @var{x} is a N-d array, @var{dim} defaults to the first 
+dimension whose size greater than unity.
+
+ at end deftypefn
+kendall
+ at c ./statistics/base/kendall.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} kendall (@var{x}, @var{y})
+Compute Kendall's @var{tau} for each of the variables specified by
+the input arguments.
+
+For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+ at code{kendall (@var{x})} is equivalent to @code{kendall (@var{x},
+ at var{x})}.
+
+For two data vectors @var{x}, @var{y} of common length @var{n},
+Kendall's @var{tau} is the correlation of the signs of all rank
+differences of @var{x} and @var{y};  i.e., if both @var{x} and
+ at var{y} have distinct entries, then
+
+ at tex
+$$ \tau = {1 \over n(n-1)} \sum_{i,j} {\rm sign}(q_i-q_j) {\rm sign}(r_i-r_j) $$
+ at end tex
+ at ifnottex
+ at example
+ at group
+         1    
+tau = -------   SUM sign (q(i) - q(j)) * sign (r(i) - r(j))
+      n (n-1)   i,j
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+in which the
+ at tex
+$q_i$ and $r_i$
+ at end tex
+ at ifnottex
+ at var{q}(@var{i}) and @var{r}(@var{i})
+ at end ifnottex
+ are the ranks of
+ at var{x} and @var{y}, respectively.
+
+If @var{x} and @var{y} are drawn from independent distributions,
+Kendall's @var{tau} is asymptotically normal with mean 0 and variance
+ at tex
+${2 (2n+5) \over 9n(n-1)}$.
+ at end tex
+ at ifnottex
+ at code{(2 * (2 at var{n}+5)) / (9 * @var{n} * (@var{n}-1))}.
+ at end ifnottex
+ at end deftypefn
+center
+ at c ./statistics/base/center.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} center (@var{x})
+ at deftypefnx {Function File} {} center (@var{x}, @var{dim})
+If @var{x} is a vector, subtract its mean.
+If @var{x} is a matrix, do the above for each column.
+If the optional argument @var{dim} is given, perform the above
+operation along this dimension
+ at end deftypefn
+iqr
+ at c ./statistics/base/iqr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} iqr (@var{x}, @var{dim})
+If @var{x} is a vector, return the interquartile range, i.e., the
+difference between the upper and lower quartile, of the input data.
+
+If @var{x} is a matrix, do the above for first non-singleton
+dimension of @var{x}.  If the option @var{dim} argument is given,
+then operate along this dimension.
+ at end deftypefn
+statistics
+ at c ./statistics/base/statistics.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} statistics (@var{x})
+If @var{x} is a matrix, return a matrix with the minimum, first
+quartile, median, third quartile, maximum, mean, standard deviation,
+skewness and kurtosis of the columns of @var{x} as its columns.
+
+If @var{x} is a vector, calculate the statistics along the 
+non-singleton dimension.
+ at end deftypefn
+meansq
+ at c ./statistics/base/meansq.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} meansq (@var{x})
+ at deftypefnx {Function File} {} meansq (@var{x}, @var{dim})
+For vector arguments, return the mean square of the values.
+For matrix arguments, return a row vector containing the mean square
+of each column.  With the optional @var{dim} argument, returns the
+mean squared of the values along this dimension.
+ at end deftypefn
+mahalanobis
+ at c ./statistics/base/mahalanobis.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mahalanobis (@var{x}, @var{y})
+Return the Mahalanobis' D-square distance between the multivariate
+samples @var{x} and @var{y}, which must have the same number of
+components (columns), but may have a different number of observations
+(rows).
+ at end deftypefn
+cloglog
+ at c ./statistics/base/cloglog.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cloglog (@var{x})
+Return the complementary log-log function of @var{x}, defined as
+
+ at tex
+$$
+{\rm cloglog}(x) = - \log (- \log (x))
+$$
+ at end tex
+ at ifnottex
+ at example
+cloglog(x) = - log (- log (@var{x}))
+ at end example
+ at end ifnottex
+ at end deftypefn
+quantile
+ at c ./statistics/base/quantile.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{q} =} quantile (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{q} =} quantile (@var{x}, @var{p}, @var{dim})
+ at deftypefnx {Function File} {@var{q} =} quantile (@var{x}, @var{p}, @var{dim}, @var{method})
+For a sample, @var{x}, calculate the quantiles, @var{q}, corresponding to
+the cumulative probability values in @var{p}.  All non-numeric values (NaNs) of
+ at var{x} are ignored.
+
+If @var{x} is a matrix, compute the quantiles for each column and
+return them in a matrix, such that the i-th row of @var{q} contains
+the @var{p}(i)th quantiles of each column of @var{x}.
+
+The optional argument @var{dim} determines the dimension along which 
+the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
+a vector or matrix, it defaults to 1 (column wise quantiles).  In the 
+instance that @var{x} is a N-d array, @var{dim} defaults to the first 
+dimension whose size greater than unity.
+
+The methods available to calculate sample quantiles are the nine methods
+used by R (http://www.r-project.org/).  The default value is METHOD = 5.
+
+Discontinuous sample quantile methods 1, 2, and 3
+
+ at enumerate 1
+ at item Method 1: Inverse of empirical distribution function.
+ at item Method 2: Similar to method 1 but with averaging at discontinuities.
+ at item Method 3: SAS definition: nearest even order statistic.
+ at end enumerate
+
+Continuous sample quantile methods 4 through 9, where p(k) is the linear
+interpolation function respecting each methods' representative cdf.
+
+ at enumerate 4
+ at item Method 4: p(k) = k / n. That is, linear interpolation of the empirical cdf.
+ at item Method 5: p(k) = (k - 0.5) / n. That is a piecewise linear function where 
+the knots are the values midway through the steps of the empirical cdf. 
+ at item Method 6: p(k) = k / (n + 1).
+ at item Method 7: p(k) = (k - 1) / (n - 1).
+ at item Method 8: p(k) = (k - 1/3) / (n + 1/3).  The resulting quantile estimates 
+are approximately median-unbiased regardless of the distribution of @var{x}.
+ at item Method 9: p(k) = (k - 3/8) / (n + 1/4).  The resulting quantile estimates 
+are approximately unbiased for the expected order statistics if @var{x} is 
+normally distributed.
+ at end enumerate
+
+Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R
+(versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS
+use method 6.  @sc{matlab} uses method 5.
+
+References:
+
+ at itemize @bullet
+ at item Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New
+S Language.  Wadsworth & Brooks/Cole.
+
+ at item Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in
+statistical packages, American Statistician, 50, 361--365.
+
+ at item R: A Language and Environment for Statistical Computing;
+ at url{http://cran.r-project.org/doc/manuals/fullrefman.pdf}.
+ at end itemize
+ at end deftypefn
+moment
+ at c ./statistics/base/moment.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} moment (@var{x}, @var{p}, @var{opt}, @var{dim})
+If @var{x} is a vector, compute the @var{p}-th moment of @var{x}.
+
+If @var{x} is a matrix, return the row vector containing the
+ at var{p}-th moment of each column.
+
+With the optional string opt, the kind of moment to be computed can
+be specified.  If opt contains @code{"c"} or @code{"a"}, central
+and/or absolute moments are returned.  For example,
+
+ at example
+moment (x, 3, "ac")
+ at end example
+
+ at noindent
+computes the third central absolute moment of @var{x}.
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.
+ at end deftypefn
+corrcoef
+ at c ./statistics/base/corrcoef.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} corrcoef (@var{x}, @var{y})
+Compute correlation.
+
+If each row of @var{x} and @var{y} is an observation and each column is
+a variable, the (@var{i}, @var{j})-th entry of
+ at code{corrcoef (@var{x}, @var{y})} is the correlation between the
+ at var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}.
+
+ at tex
+$$
+{\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
+$$
+ at end tex
+ at ifnottex
+ at example
+corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+ at end example
+ at end ifnottex
+
+If called with one argument, compute @code{corrcoef (@var{x}, @var{x})}.
+ at end deftypefn
+logit
+ at c ./statistics/base/logit.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logit (@var{p})
+For each component of @var{p}, return the logit of @var{p} defined as
+ at tex
+$$
+{\rm logit}(p) = \log\Big({p \over 1-p}\Big)
+$$
+ at end tex
+ at ifnottex
+ at example
+logit(@var{p}) = log (@var{p} / (1- at var{p}))
+ at end example
+ at end ifnottex
+ at end deftypefn
+cor
+ at c ./statistics/base/cor.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cor (@var{x}, @var{y})
+Compute correlation.
+
+The (@var{i}, @var{j})-th entry of @code{cor (@var{x}, @var{y})} is
+the correlation between the @var{i}-th variable in @var{x} and the
+ at var{j}-th variable in @var{y}.
+
+ at tex
+$$
+{\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
+$$
+ at end tex
+ at ifnottex
+ at example
+corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+ at end example
+ at end ifnottex
+
+For matrices, each row is an observation and each column a variable;
+vectors are always observations and may be row or column vectors.
+
+ at code{cor (@var{x})} is equivalent to @code{cor (@var{x}, @var{x})}.
+
+Note that the @code{corrcoef} function does the same as @code{cor}.
+ at end deftypefn
+kurtosis
+ at c ./statistics/base/kurtosis.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} kurtosis (@var{x}, @var{dim})
+If @var{x} is a vector of length @math{N}, return the kurtosis
+ at tex
+$$
+ {\rm kurtosis} (x) = {1\over N \sigma(x)^4} \sum_{i=1}^N (x_i-\bar{x})^4 - 3
+$$
+where $\bar{x}$ is the mean value of $x$.
+ at end tex
+ at ifnottex
+
+ at example
+kurtosis (x) = N^(-1) std(x)^(-4) sum ((x - mean(x)).^4) - 3
+ at end example
+ at end ifnottex
+
+ at noindent
+of @var{x}.  If @var{x} is a matrix, return the kurtosis over the
+first non-singleton dimension.  The optional argument @var{dim}
+can be given to force the kurtosis to be given over that 
+dimension.
+ at end deftypefn
+cut
+ at c ./statistics/base/cut.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cut (@var{x}, @var{breaks})
+Create categorical data out of numerical or continuous data by
+cutting into intervals.
+
+If @var{breaks} is a scalar, the data is cut into that many
+equal-width intervals.  If @var{breaks} is a vector of break points,
+the category has @code{length (@var{breaks}) - 1} groups.
+
+The returned value is a vector of the same size as @var{x} telling
+which group each point in @var{x} belongs to.  Groups are labelled
+from 1 to the number of groups; points outside the range of
+ at var{breaks} are labelled by @code{NaN}.
+ at end deftypefn
+gls
+ at c ./statistics/base/gls.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{beta}, @var{v}, @var{r}] =} gls (@var{y}, @var{x}, @var{o})
+Generalized least squares estimation for the multivariate model
+ at tex
+$y = x b + e$
+with $\bar{e} = 0$ and cov(vec($e$)) = $(s^2)o$,
+ at end tex
+ at ifnottex
+ at math{y = x b + e} with @math{mean (e) = 0} and
+ at math{cov (vec (e)) = (s^2) o},
+ at end ifnottex
+ where
+ at tex
+$y$ is a $t \times p$ matrix, $x$ is a $t \times k$ matrix, $b$ is a $k
+\times p$ matrix, $e$ is a $t \times p$ matrix, and $o$ is a $tp \times
+tp$ matrix.
+ at end tex
+ at ifnottex
+ at math{y} is a @math{t} by @math{p} matrix, @math{x} is a @math{t} by
+ at math{k} matrix, @math{b} is a @math{k} by @math{p} matrix, @math{e}
+is a @math{t} by @math{p} matrix, and @math{o} is a @math{t p} by
+ at math{t p} matrix.
+ at end ifnottex
+
+ at noindent
+Each row of @var{y} and @var{x} is an observation and each column a
+variable.  The return values @var{beta}, @var{v}, and @var{r} are
+defined as follows.
+
+ at table @var
+ at item beta
+The GLS estimator for @math{b}.
+
+ at item v
+The GLS estimator for @math{s^2}.
+
+ at item r
+The matrix of GLS residuals, @math{r = y - x beta}.
+ at end table
+ at end deftypefn
+run_count
+ at c ./statistics/base/run_count.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} run_count (@var{x}, @var{n})
+Count the upward runs along the first non-singleton dimension of
+ at var{x} of length 1, 2, @dots{}, @var{n}-1 and greater than or equal 
+to @var{n}.  If the optional argument @var{dim} is given operate
+along this dimension
+ at end deftypefn
+mean
+ at c ./statistics/base/mean.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mean (@var{x}, @var{dim}, @var{opt})
+If @var{x} is a vector, compute the mean of the elements of @var{x}
+ at tex
+$$ {\rm mean}(x) = \bar{x} = {1\over N} \sum_{i=1}^N x_i $$
+ at end tex
+ at ifnottex
+
+ at example
+mean (x) = SUM_i x(i) / N
+ at end example
+ at end ifnottex
+If @var{x} is a matrix, compute the mean for each column and return them
+in a row vector.
+
+With the optional argument @var{opt}, the kind of mean computed can be
+selected.  The following options are recognized:
+
+ at table @code
+ at item "a"
+Compute the (ordinary) arithmetic mean.  This is the default.
+
+ at item "g"
+Compute the geometric mean.
+
+ at item "h"
+Compute the harmonic mean.
+ at end table
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.
+
+Both @var{dim} and @var{opt} are optional.  If both are supplied,
+either may appear first.
+ at end deftypefn
+griddatan
+ at c ./geometry/griddatan.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{yi} =} griddatan (@var{x}, @var{y}, @var{xi}, @var{method}, @var{options})
+
+Generate a regular mesh from irregular data using interpolation.
+The function is defined by @code{@var{y} = f (@var{x})}.
+The interpolation points are all @var{xi}.  
+
+The interpolation method can be @code{"nearest"} or @code{"linear"}.
+If method is omitted it defaults to @code{"linear"}.
+ at seealso{griddata, delaunayn}
+ at end deftypefn
+delaunay3
+ at c ./geometry/delaunay3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{T} =} delaunay3 (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {@var{T} =} delaunay3 (@var{x}, @var{y}, @var{z}, @var{opt})
+A matrix of size [n, 4] is returned.  Each row contains a 
+set of tetrahedron which are
+described by the indices to the data point vectors (x,y,z).
+
+A fourth optional argument, which must be a string or cell array of strings,
+contains extra options passed to the underlying qhull command.  See the 
+documentation for the Qhull library for details.
+ at seealso{delaunay,delaunayn}
+ at end deftypefn
+griddata3
+ at c ./geometry/griddata3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{vi} =} griddata3 (@var{x}, @var{y}, @var{z}, @var{v} @var{xi}, @var{yi}, @var{zi}, @var{method}, @var{options})
+
+Generate a regular mesh from irregular data using interpolation.
+The function is defined by @code{@var{y} = f (@var{x}, at var{y}, at var{z})}.
+The interpolation points are all @var{xi}.  
+
+The interpolation method can be @code{"nearest"} or @code{"linear"}.
+If method is omitted it defaults to @code{"linear"}.
+ at seealso{griddata, delaunayn}
+ at end deftypefn
+trisurf
+ at c ./geometry/trisurf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} trisurf (@var{tri}, @var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {@var{h} =} trisurf (@dots{})
+Plot a triangular surface in 3D.  The variable @var{tri} is the triangular
+meshing of the points @code{(@var{x}, @var{y})} which is returned 
+from @code{delaunay}.  The variable @var{z} is value at the point 
+ at code{(@var{x}, @var{y})}.  The output argument @var{h} is the graphic 
+handle to the plot.
+ at seealso{triplot, delaunay3}
+ at end deftypefn
+rectint
+ at c ./geometry/rectint.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{area} =} rectint (@var{a}, @var{b})
+
+Compute the area of intersection of rectangles in @var{a} and
+rectangles in @var{b}.  Rectangles are defined as [x y width height]
+where x and y are the minimum values of the two orthogonal
+dimensions.
+
+If @var{a} or @var{b} are matrices, then the output, @var{area}, is a
+matrix where the i-th row corresponds to the i-th row of a and the j-th
+column corresponds to the j-th row of b.
+
+ at seealso{polyarea}
+ at end deftypefn
+voronoi
+ at c ./geometry/voronoi.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} voronoi (@var{x}, @var{y})
+ at deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle")
+ at deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle", @var{options})
+ at deftypefnx {Function File} {[@var{vx}, @var{vy}] =} voronoi (@dots{})
+plots voronoi diagram of points @code{(@var{x}, @var{y})}.
+The voronoi facets with points at infinity are not drawn.
+[@var{vx}, @var{vy}] = voronoi(@dots{}) returns the vertices instead of plotting the
+diagram. plot (@var{vx}, @var{vy}) shows the voronoi diagram.
+
+A fourth optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+
+ at example
+ at group
+  x = rand (10, 1);
+  y = rand (size (x));
+  h = convhull (x, y);
+  [vx, vy] = voronoi (x, y);
+  plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g")
+  legend ("", "points", "hull");
+ at end group
+ at end example
+
+ at seealso{voronoin, delaunay, convhull}
+ at end deftypefn
+dsearch
+ at c ./geometry/dsearch.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{idx} =} dsearch (@var{x}, @var{y}, @var{tri}, @var{xi}, @var{yi})
+ at deftypefnx {Function File} {@var{idx} =} dsearch (@var{x}, @var{y}, @var{tri}, @var{xi}, @var{yi}, @var{s})
+Returns the index @var{idx} or the closest point in @code{@var{x}, @var{y}}
+to the elements @code{[@var{xi}(:), @var{yi}(:)]}.  The variable @var{s} is
+accepted but ignored for compatibility.
+ at seealso{dsearchn, tsearch}
+ at end deftypefn
+delaunayn
+ at c ./geometry/delaunayn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{T} =} delaunayn (@var{P})
+ at deftypefnx {Function File} {@var{T} =} delaunayn (@var{P}, @var{opt})
+Form the Delaunay triangulation for a set of points.
+The Delaunay triangulation is a tessellation of the convex hull of the
+points such that no n-sphere defined by the n-triangles contains
+any other points from the set.
+The input matrix @var{P} of size @code{[n, dim]} contains @var{n}
+points in a space of dimension dim.  The return matrix @var{T} has the
+size @code{[m, dim+1]}.  It contains for each row a set of indices to
+the points, which describes a simplex of dimension dim.  For example,
+a 2d simplex is a triangle and 3d simplex is a tetrahedron.
+
+Extra options for the underlying Qhull command can be specified by the
+second argument.  This argument is a cell array of strings.  The default
+options depend on the dimension of the input: 
+
+ at itemize 
+ at item 2D and 3D: @var{opt} = @code{@{"Qt", "Qbb", "Qc"@}}
+ at item 4D and higher: @var{opt} = @code{@{"Qt", "Qbb", "Qc", "Qz"@}} 
+ at end itemize
+
+If @var{opt} is [], then the default arguments are used.  If @var{opt}
+is @code{@{"@w{}"@}}, then none of the default arguments are used by Qhull. 
+See the Qhull documentation for the available options. 
+
+All options can also be specified as single string, for example
+ at code{"Qt Qbb Qc Qz"}.
+
+ at end deftypefn
+tsearchn
+ at c ./geometry/tsearchn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{idx}, @var{p}] =} tsearchn (@var{x}, @var{t}, @var{xi})
+Searches for the enclosing Delaunay convex hull.  For @code{@var{t} =
+delaunayn (@var{x})}, finds the index in @var{t} containing the
+points @var{xi}.  For points outside the convex hull, @var{idx} is NaN.
+If requested @code{tsearchn} also returns the Barycentric coordinates @var{p}
+of the enclosing triangles.
+ at seealso{delaunay, delaunayn}
+ at end deftypefn
+convhull
+ at c ./geometry/convhull.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{H} =} convhull (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{H} =} convhull (@var{x}, @var{y}, @var{opt})
+Returns the index vector to the points of the enclosing convex hull.  The
+data points are defined by the x and y vectors.
+
+A third optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the 
+Qhull library for details.
+
+ at seealso{delaunay, convhulln}
+ at end deftypefn
+voronoin
+ at c ./geometry/voronoin.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{C}, @var{F}] =} voronoin (@var{pts})
+ at deftypefnx {Function File} {[@var{C}, @var{F}] =} voronoin (@var{pts}, @var{options})
+computes n- dimensional voronoi facets.  The input matrix @var{pts}
+of size [n, dim] contains n points of dimension dim.
+ at var{C} contains the points of the voronoi facets.  The list @var{F}
+contains for each facet the indices of the voronoi points.
+
+A second optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the
+Qhull library for details.
+ at seealso{voronoin, delaunay, convhull}
+ at end deftypefn
+inpolygon
+ at c ./geometry/inpolygon.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{in}, @var{on}] =} inpolygon (@var{x}, @var{y}, @var{xv}, @var{xy})
+
+For a polygon defined by @code{(@var{xv}, @var{yv})} points, determine
+if the points @code{(@var{x}, @var{y})} are inside or outside the polygon.
+The variables @var{x}, @var{y}, must have the same dimension.  The optional
+output @var{on} gives the points that are on the polygon.
+
+ at end deftypefn
+griddata
+ at c ./geometry/griddata.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{zi} =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
+ at deftypefnx {Function File} {[@var{xi}, @var{yi}, @var{zi}] =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
+
+Generate a regular mesh from irregular data using interpolation.
+The function is defined by @code{@var{z} = f (@var{x}, @var{y})}.
+The interpolation points are all @code{(@var{xi}, @var{yi})}.  If
+ at var{xi}, @var{yi} are vectors then they are made into a 2D mesh.
+
+The interpolation method can be @code{"nearest"}, @code{"cubic"} or
+ at code{"linear"}.  If method is omitted it defaults to @code{"linear"}.
+ at seealso{delaunay}
+ at end deftypefn
+trimesh
+ at c ./geometry/trimesh.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} trimesh (@var{tri}, @var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {@var{h} =} trimesh (@dots{})
+Plot a triangular mesh in 3D.  The variable @var{tri} is the triangular
+meshing of the points @code{(@var{x}, @var{y})} which is returned 
+from @code{delaunay}.  The variable @var{z} is value at the point 
+ at code{(@var{x}, @var{y})}.  The output argument @var{h} is the graphic 
+handle to the plot.
+ at seealso{triplot, delaunay3}
+ at end deftypefn
+dsearchn
+ at c ./geometry/dsearchn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{idx} =} dsearchn (@var{x}, @var{tri}, @var{xi})
+ at deftypefnx {Function File} {@var{idx} =} dsearchn (@var{x}, @var{tri}, @var{xi}, @var{outval})
+ at deftypefnx {Function File} {@var{idx} =} dsearchn (@var{x}, @var{xi})
+ at deftypefnx {Function File} {[@var{idx}, @var{d}] =} dsearchn (@dots{})
+Returns the index @var{idx} or the closest point in @var{x} to the elements
+ at var{xi}.  If @var{outval} is supplied, then the values of @var{xi} that are
+not contained within one of the simplicies @var{tri} are set to 
+ at var{outval}.  Generally, @var{tri} is returned from @code{delaunayn 
+(@var{x})}.
+ at seealso{dsearch, tsearch}
+ at end deftypefn
+triplot
+ at c ./geometry/triplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} triplot (@var{tri}, @var{x}, @var{y})
+ at deftypefnx {Function File} {} triplot (@var{tri}, @var{x}, @var{y}, @var{linespec})
+ at deftypefnx {Function File} {@var{h} =} triplot (@dots{})
+Plot a triangular mesh in 2D.  The variable @var{tri} is the triangular
+meshing of the points @code{(@var{x}, @var{y})} which is returned from
+ at code{delaunay}.  If given, the @var{linespec} determines the properties
+to use for the lines.  The output argument @var{h} is the graphic handle
+to the plot.
+ at seealso{plot, trimesh, delaunay}
+ at end deftypefn
+delaunay
+ at c ./geometry/delaunay.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{tri} =} delaunay (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{tri} =} delaunay (@var{x}, @var{y}, @var{opt})
+The return matrix of size [n, 3] contains a set triangles which are
+described by the indices to the data point x and y vector.
+The triangulation satisfies the Delaunay circum-circle criterion.
+No other data point is in the circum-circle of the defining triangle.
+
+A third optional argument, which must be a string, contains extra options
+passed to the underlying qhull command.  See the documentation for the 
+Qhull library for details.
+
+ at example
+ at group
+x = rand (1, 10);
+y = rand (size (x));
+T = delaunay (x, y);
+X = [x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1))];
+Y = [y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1))];
+axis ([0,1,0,1]);
+plot (X, Y, "b", x, y, "r*");
+ at end group
+ at end example
+ at seealso{voronoi, delaunay3, delaunayn}
+ at end deftypefn
+__plt2mm__
+ at c ./plot/__plt2mm__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2mm__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+isonormals
+ at c ./plot/isonormals.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{n}] =} isonormals (@var{val}, @var{v})
+ at deftypefnx {Function File} {[@var{n}] =} isonormals (@var{val}, @var{p})
+ at deftypefnx {Function File} {[@var{n}] =} isonormals (@var{x}, @var{y}, @var{z}, @var{val}, @var{v})
+ at deftypefnx {Function File} {[@var{n}] =} isonormals (@var{x}, @var{y}, @var{z}, @var{val}, @var{p})
+ at deftypefnx {Function File} {[@var{n}] =} isonormals (@dots{}, "negate")
+ at deftypefnx {Function File} isonormals (@dots{}, @var{p})
+
+If called with one output argument and the first input argument
+ at var{val} is a three--dimensional array that contains the data for an
+isosurface geometry and the second input argument @var{v} keeps the
+vertices of an isosurface then return the normals @var{n} in form of
+a matrix with the same size than @var{v} at computed points
+ at command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}.  The output argument
+ at var{n} can be taken to manually set @var{VertexNormals} of a patch.
+
+If called with further input arguments @var{x}, @var{y} and @var{z}
+which are three--dimensional arrays with the same size than @var{val}
+then the volume data is taken at those given points.  Instead of the
+vertices data @var{v} a patch handle @var{p} can be passed to this
+function.
+
+If given the string input argument "negate" as last input argument
+then compute the reverse vector normals of an isosurface geometry.
+
+If no output argument is given then directly redraw the patch that is
+given by the patch handle @var{p}.
+
+For example,
+ at example
+function [] = isofinish (p)
+  set (gca, "DataAspectRatioMode","manual","DataAspectRatio",[1 1 1]);
+  set (p, "VertexNormals", -get(p,"VertexNormals")); ## Revert normals
+  set (p, "FaceColor", "interp");
+  ## set (p, "FaceLighting", "phong");
+  ## light ("Position", [1 1 5]); ## Available with JHandles
+endfunction
+
+N = 15;    ## Increase number of vertices in each direction
+iso = .4;  ## Change isovalue to .1 to display a sphere
+lin = linspace (0, 2, N);
+[x, y, z] = meshgrid (lin, lin, lin);
+c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
+figure (); ## Open another figure window
+
+subplot (2, 2, 1); view (-38, 20);
+[f, v, cdat] = isosurface (x, y, z, c, iso, y);
+p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+	   "FaceColor", "interp", "EdgeColor", "none");
+isofinish (p); ## Call user function isofinish
+
+subplot (2, 2, 2); view (-38, 20);
+p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+	   "FaceColor", "interp", "EdgeColor", "none");
+isonormals (x, y, z, c, p); ## Directly modify patch
+isofinish (p);
+
+subplot (2, 2, 3); view (-38, 20);
+p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+	   "FaceColor", "interp", "EdgeColor", "none");
+n = isonormals (x, y, z, c, v); ## Compute normals of isosurface
+set (p, "VertexNormals", n);    ## Manually set vertex normals
+isofinish (p);
+
+subplot (2, 2, 4); view (-38, 20);
+p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+	   "FaceColor", "interp", "EdgeColor", "none");
+isonormals (x, y, z, c, v, "negate"); ## Use reverse directly
+isofinish (p);
+ at end example
+
+ at seealso {isosurface, isocolors, isocaps, marching_cube}
+
+ at end deftypefn
+grid
+ at c ./plot/grid.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} grid (@var{arg})
+ at deftypefnx {Function File} {} grid ("minor", @var{arg2})
+ at deftypefnx {Function File} {} grid (@var{hax}, @dots{})
+Force the display of a grid on the plot.
+The argument may be either @code{"on"}, or @code{"off"}.
+If it is omitted, the current grid state is toggled.
+
+If @var{arg} is @code{"minor"} then the minor grid is toggled.  When
+using a minor grid a second argument @var{arg2} is allowed, which can
+be either @code{"on"} or @code{"off"} to explicitly set the state of
+the minor grid.
+
+If the first argument is an axis handle, @var{hax}, operate on the
+specified axis object.
+ at seealso{plot}
+ at end deftypefn
+semilogx
+ at c ./plot/semilogx.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} semilogx (@var{args})
+Produce a two-dimensional plot using a log scale for the @var{x}
+axis.  See the description of @code{plot} for a description of the
+arguments that @code{semilogx} will accept.
+ at seealso{plot, semilogy, loglog}
+ at end deftypefn
+surface
+ at c ./plot/surface.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} surface (@var{x}, @var{y}, @var{z}, @var{c})
+ at deftypefnx {Function File} {} surface (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} surface (@var{z}, @var{c})
+ at deftypefnx {Function File} {} surface (@var{z})
+ at deftypefnx {Function File} {} surface (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} surface (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} surface (@dots{})
+Plot a surface graphic object given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the surface.  If @var{x} and @var{y} are vectors,
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.  If @var{x} and @var{y}
+are missing, they are constructed from size of the matrix @var{z}.
+
+Any additional properties passed are assigned to the surface.
+ at seealso{surf, mesh, patch, line}
+ at end deftypefn
+title
+ at c ./plot/title.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} title (@var{title})
+ at deftypefnx {Function File} {} title (@var{title}, @var{p1}, @var{v1}, @dots{})
+Create a title object and return a handle to it.
+ at end deftypefn
+ellipsoid
+ at c ./plot/ellipsoid.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} ellipsoid (@var{xc}, at var{yc}, @var{zc}, @var{xr}, @var{yr}, @var{zr}, @var{n})
+ at deftypefnx {Function File} {} ellipsoid (@var{h}, @dots{})
+Generate three matrices in @code{meshgrid} format that define an
+ellipsoid.  Called with no return arguments, @code{ellipsoid} calls
+directly @code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle
+is passed as the first argument, the surface is plotted to this
+set of axes.
+ at seealso{sphere}
+ at end deftypefn
+isfigure
+ at c ./plot/isfigure.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isfigure (@var{h})
+Return true if @var{h} is a graphics handle that contains a figure
+object and false otherwise.
+ at end deftypefn
+findobj
+ at c ./plot/findobj.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} findobj ()
+ at deftypefnx {Function File} {@var{h} =} findobj (@var{prop_name}, @var{prop_value})
+ at deftypefnx {Function File} {@var{h} =} findobj ('-property', @var{prop_name})
+ at deftypefnx {Function File} {@var{h} =} findobj ('-regexp', @var{prop_name}, @var{pattern})
+ at deftypefnx {Function File} {@var{h} =} findobj ('flat', @dots{})
+ at deftypefnx {Function File} {@var{h} =} findobj (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} findobj (@var{h}, '-depth', @var{d}, @dots{})
+Find object with specified property values.  The simplest form is
+
+ at example
+findobj (@var{prop_name}, @var{prop_Value})
+ at end example
+
+ at noindent
+which returns all of the handles to the objects with the name 
+ at var{prop_name} and the name @var{prop_Value}.  The search can be limited
+to a particular object or set of objects and their descendants by 
+passing a handle or set of handles @var{h} as the first argument to 
+ at code{findobj}.
+
+The depth of hierarchy of objects to which to search to can be limited
+with the '-depth' argument.  To limit the number depth of the hierarchy
+to search to @var{d} generations of children, and example is
+
+ at example
+findobj (@var{h}, '-depth', @var{d}, @var{prop_Name}, @var{prop_Value})
+ at end example
+
+Specifying a depth @var{d} of 0, limits the search to the set of object
+passed in @var{h}.  A depth @var{d} of 0 is equivalent to the '-flat'
+argument. 
+
+A specified logical operator may be applied to the pairs of @var{prop_Name}
+and @var{prop_Value}.  The supported logical operators are '-and', '-or', 
+'-xor', '-not'.
+
+The objects may also be matched by comparing a regular expression to the 
+property values, where property values that match @code{regexp 
+(@var{prop_Value}, @var{pattern})} are returned.  Finally, objects may be 
+matched by property name only, using the '-property' option.
+ at seealso{get, set}
+ at end deftypefn
+loglogerr
+ at c ./plot/loglogerr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} loglogerr (@var{args})
+Produce two-dimensional plots on double logarithm axis with
+errorbars.  Many different combinations of arguments are possible.
+The most used form is
+
+ at example
+loglogerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+ at end example
+
+ at noindent
+which produces a double logarithm plot of @var{y} versus @var{x} 
+with errors in the @var{y}-scale defined by @var{ey} and the plot
+format defined by @var{fmt}.  See errorbar for available formats and 
+additional information.
+ at seealso{errorbar, semilogxerr, semilogyerr}
+ at end deftypefn
+gcbo
+ at c ./plot/gcbo.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} gcbo ()
+ at deftypefnx {Function File} {[@var{h}, @var{fig}] =} gcbo ()
+Return a handle to the object whose callback is currently
+executing.  If no callback is executing, this function returns the
+empty matrix.  This handle is obtained from the root object property
+"CallbackObject".
+
+Additionally return the handle of the figure containing the
+object whose callback is currently executing.  If no callback is
+executing, the second output is also set to the empty matrix.
+
+ at seealso{gcf, gca, gcbf}
+ at end deftypefn
+__default_plot_options__
+ at c ./plot/__default_plot_options__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{options} =} __default_plot_options__ ()
+Undocumented internal function.
+ at end deftypefn
+stem
+ at c ./plot/stem.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} stem (@var{x}, @var{y}, @var{linespec})
+ at deftypefnx {Function File} {@var{h} =} stem (@dots{}, "filled")
+Plot a stem graph from two vectors of x-y data.  If only one argument
+is given, it is taken as the y-values and the x coordinates are taken
+from the indices of the elements.
+
+If @var{y} is a matrix, then each column of the matrix is plotted as
+a separate stem graph.  In this case @var{x} can either be a vector,
+the same length as the number of rows in @var{y}, or it can be a
+matrix of the same size as @var{y}.
+
+The default color is @code{"r"} (red).  The default line style is
+ at code{"-"} and the default marker is @code{"o"}.  The line style can
+be altered by the @code{linespec} argument in the same manner as the
+ at code{plot} command.  For example
+
+ at example
+ at group
+x = 1:10;
+y = ones (1, length (x))*2.*x;
+stem (x, y, "b");
+ at end group
+ at end example
+
+ at noindent
+plots 10 stems with heights from 2 to 20 in blue;
+
+The return value of @code{stem} is a vector if "stem series" graphics
+handles, with one handle per column of the variable @var{y}.  This
+handle regroups the elements of the stem graph together as the
+children of the "stem series" handle, allowing them to be altered
+together.  For example
+
+ at example
+ at group
+x = [0 : 10].';
+y = [sin(x), cos(x)]
+h = stem (x, y);
+set (h(2), "color", "g");
+set (h(1), "basevalue", -1)
+ at end group
+ at end example
+
+ at noindent
+changes the color of the second "stem series"  and moves the base line
+of the first.
+ at seealso{bar, barh, plot}
+ at end deftypefn
+ezplot
+ at c ./plot/ezplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezplot (@var{f})
+ at deftypefnx {Function File} {} ezplot (@var{fx}, @var{fy})
+ at deftypefnx {Function File} {} ezplot (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezplot (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezplot (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezplot (@dots{})
+
+Plots in two-dimensions the curve defined by @var{f}.  The function
+ at var{f} may be a string, inline function or function handle and can
+have either one or two variables.  If @var{f} has one variable, then 
+the function is plotted over the domain @code{-2*pi < @var{x} < 2*pi}  
+with 500 points. 
+
+If @var{f} has two variables then @code{@var{f}(@var{x}, at var{y}) = 0}
+is calculated over the meshed domain @code{-2*pi < @var{x} | @var{y}
+< 2*pi} with 60 by 60 in the mesh.  For example
+
+ at example
+ezplot (@@(@var{x}, @var{y}) @var{x} .^ 2 - @var{y} .^ 2 - 1)
+ at end example
+
+If two functions are passed as strings, inline functions or function
+handles, then the parametric function
+
+ at example
+ at group
+ at var{x} = @var{fx} (@var{t})
+ at var{y} = @var{fy} (@var{t})
+ at end group
+ at end example
+
+is plotted over the domain @code{-2*pi < @var{t} < 2*pi} with 500
+points. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of @var{x}, @var{y} and @var{t}.  If it is a four element
+vector, then the minimum and maximum values of @var{x} and @var{t}
+are determined by the first two elements and the minimum and maximum
+of @var{y} by the second pair of elements.
+
+ at var{n} is a scalar defining the number of points to use in plotting
+the function.
+
+The optional return value @var{h} provides a list of handles to the 
+the line objects plotted.
+
+ at seealso{plot, ezplot3}
+ at end deftypefn
+ezcontourf
+ at c ./plot/ezcontourf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezcontourf (@var{f})
+ at deftypefnx {Function File} {} ezcontourf (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezcontourf (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezcontourf (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezcontourf (@dots{})
+
+Plots the filled contour lines of a function.  @var{f} is a string, inline 
+function or function handle with two arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and 
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezcontourf (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{ezplot, ezcontour, ezsurfc, ezmeshc}
+ at end deftypefn
+ezcontour
+ at c ./plot/ezcontour.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezcontour (@var{f})
+ at deftypefnx {Function File} {} ezcontour (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezcontour (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezcontour (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezcontour (@dots{})
+
+Plots the contour lines of a function.  @var{f} is a string, inline function
+or function handle with two arguments defining the function.  By default the
+plot is over the domain @code{-2*pi < @var{x} < 2*pi} and @code{-2*pi < 
+ at var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezcontour (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{ezplot, ezcontourf, ezsurfc, ezmeshc}
+ at end deftypefn
+orient
+ at c ./plot/orient.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} orient (@var{orientation})
+Set the default print orientation.  Valid values for
+ at var{orientation} include @code{"landscape"}, @code{"portrait"}, 
+and @code{"tall"}.
+
+The @code{"tall"} option sets the orientation to portait and fills
+the page with the plot, while leaving a 0.25in border.
+
+If called with no arguments, return the default print orientation.
+ at end deftypefn
+ginput
+ at c ./plot/ginput.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} ginput (@var{n})
+Return which mouse buttons were pressed and keys were hit on the current
+figure.  If @var{n} is defined, then wait for @var{n} mouse clicks
+before returning.  If @var{n} is not defined, then @code{ginput} will
+loop until the return key is pressed.
+ at end deftypefn
+__plt2__
+ at c ./plot/__plt2__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2__ (@var{h}, @var{x1}, @var{x2}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+gnuplot_binary
+ at c ./plot/gnuplot_binary.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{val} =} gnuplot_binary ()
+ at deftypefnx {Loadable Function} {@var{old_val} =} gnuplot_binary (@var{new_val})
+Query or set the name of the program invoked by the plot command.
+The default value @code{\"gnuplot\"}.  @xref{Installation}.
+ at end deftypefn
+barh
+ at c ./plot/barh.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} barh (@var{x}, @var{y})
+ at deftypefnx {Function File} {} barh (@var{y})
+ at deftypefnx {Function File} {} barh (@var{x}, @var{y}, @var{w})
+ at deftypefnx {Function File} {} barh (@var{x}, @var{y}, @var{w}, @var{style})
+ at deftypefnx {Function File} {@var{h} =} barh (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} barh (@var{h}, @dots{})
+Produce a horizontal bar graph from two vectors of x-y data.
+
+If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+The default width of 0.8 for the bars can be changed using @var{w}. 
+
+If @var{y} is a matrix, then each column of @var{y} is taken to be a
+separate bar graph plotted on the same graph.  By default the columns
+are plotted side-by-side.  This behavior can be changed by the @var{style}
+argument, which can take the values @code{"grouped"} (the default),
+or @code{"stacked"}.
+
+The optional return value @var{h} provides a handle to the bar series
+object.  See @code{bar} for a description of the use of the bar series.
+
+The optional input handle @var{h} allows an axis handle to be passed.
+Properties of the patch graphics object can be changed using
+ at var{prop}, @var{val} pairs.
+
+ at seealso{bar, plot}
+ at end deftypefn
+ylim
+ at c ./plot/ylim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{xl} =} ylim ()
+ at deftypefnx {Function File} {} ylim (@var{xl})
+ at deftypefnx {Function File} {@var{m} =} ylim ('mode')
+ at deftypefnx {Function File} {} ylim (@var{m})
+ at deftypefnx {Function File} {} ylim (@var{h}, @dots{})
+Get or set the limits of the y-axis of the current plot.  Called without
+arguments @code{ylim} returns the y-axis limits of the current plot.
+If passed a two element vector @var{xl}, the limits of the y-axis are set
+to this value.
+
+The current mode for calculation of the y-axis can be returned with a
+call @code{ylim ('mode')}, and can be either 'auto' or 'manual'.  The 
+current plotting mode can be set by passing either 'auto' or 'manual' 
+as the argument.
+
+If passed an handle as the first argument, then operate on this handle
+rather than the current axes handle.
+ at seealso{xlim, zlim, set, get, gca}
+ at end deftypefn
+__plt__
+ at c ./plot/__plt__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt__ (@var{caller}, @var{h}, @var{varargin})
+Undocumented internal function.
+ at end deftypefn
+scatter3
+ at c ./plot/scatter3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} scatter3 (@var{x}, @var{y}, @var{z}, @var{s}, @var{c})
+ at deftypefnx {Function File} {} scatter3 (@dots{}, 'filled')
+ at deftypefnx {Function File} {} scatter3 (@dots{}, @var{style})
+ at deftypefnx {Function File} {} scatter3 (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} scatter3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} scatter3 (@dots{})
+
+Plot a scatter plot of the data in 3D.  A marker is plotted at each point 
+defined by the points in the vectors @var{x}, @var{y} and @var{z}.  The size
+of the markers used is determined by @var{s}, which can be a scalar or
+a vector of the same length of @var{x}, @var{y} and @var{z}.  If @var{s} is
+not given or is an empty matrix, then the default value of 8 points is used.
+
+The color of the markers is determined by @var{c}, which can be a string
+defining a fixed color, a 3 element vector giving the red, green and blue 
+components of the color, a vector of the same length as @var{x} that gives
+a scaled index into the current colormap, or a @var{n}-by-3 matrix defining
+the colors of each of the markers individually.
+
+The marker to use can be changed with the @var{style} argument, that is a 
+string defining a marker in the same manner as the @code{plot} command. 
+If the argument 'filled' is given then the markers as filled.  All 
+additional arguments are passed to the underlying patch command.
+
+The optional return value @var{h} provides a handle to the patch object
+
+ at example
+ at group
+[x, y, z] = peaks (20);
+scatter3 (x(:), y(:), z(:), [], z(:));
+ at end group
+ at end example
+
+ at seealso{plot, patch, scatter}
+ at end deftypefn
+__bar__
+ at c ./plot/__bar__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __bar__ (@var{vertical}, @var{func}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+patch
+ at c ./plot/patch.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} patch ()
+ at deftypefnx {Function File} {} patch (@var{x}, @var{y}, @var{c})
+ at deftypefnx {Function File} {} patch (@var{x}, @var{y}, @var{z}, @var{c})
+ at deftypefnx {Function File} {} patch (@var{fv})
+ at deftypefnx {Function File} {} patch ('Faces', @var{f}, 'Vertices', @var{v}, @dots{})
+ at deftypefnx {Function File} {} patch (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} patch (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} patch (@dots{})
+Create patch object from @var{x} and @var{y} with color @var{c} and
+insert in the current axes object.  Return handle to patch object.
+
+For a uniform colored patch, @var{c} can be given as an RGB vector,
+scalar value referring to the current colormap, or string value (for
+example, "r" or "red").
+
+If passed a structure @var{fv} contain the fields "vertices", "faces"
+and optionally "facevertexcdata", create the patch based on these 
+properties.
+ at end deftypefn
+allchild
+ at c ./plot/allchild.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} allchild (@var{handles})
+Find all children, including hidden children, of a graphics object.
+
+This function is similar to @code{get (h, "children")}, but also
+returns includes hidden objects.  If @var{handles} is a scalar,
+ at var{h} will be a vector.  Otherwise, @var{h} will be a cell matrix
+of the same size as @var{handles} and each cell will contain a
+vector of handles.
+ at seealso{get, set, findall, findobj}
+ at end deftypefn
+__actual_axis_position__
+ at c ./plot/__actual_axis_position__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __actual_axis_position__ (@var{h})
+ at deftypefnx {Function File} {} __actual_axis_position__ (@var{axis_struct})
+Undocumented internal function.
+ at end deftypefn
+ezsurf
+ at c ./plot/ezsurf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezsurf (@var{f})
+ at deftypefnx {Function File} {} ezsurf (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezsurf (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezsurf (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezsurf (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezsurf (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezsurf (@dots{})
+
+Plots the surface defined by a function.  @var{f} is a string, inline
+function or function handle with two arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezsurf (f, [-3, 3]);
+ at end group
+ at end example
+
+An example of a parametrically defined function is
+
+ at example
+ at group
+fx = @@(s,t) cos (s) .* cos(t);
+fy = @@(s,t) sin (s) .* cos(t);
+fz = @@(s,t) sin(t);
+ezsurf (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+ at end group
+ at end example
+
+ at seealso{ezplot, ezmesh, ezsurfc, ezmeshc}
+ at end deftypefn
+__stem__
+ at c ./plot/__stem__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} __stem__ (@var{have_z}, @var{varargin})
+Undocumented internal function.
+ at end deftypefn
+__gnuplot_version__
+ at c ./plot/__gnuplot_version__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{version} =} __gnuplot_version__ ()
+Undocumented internal function.
+ at end deftypefn
+view
+ at c ./plot/view.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} view (@var{azimuth}, @var{elevation})
+ at deftypefnx {Function File} {} view (@var{dims})
+ at deftypefnx {Function File} {[@var{azimuth}, @var{elevation}] =} view ()
+Set or get the viewpoint for the current axes.
+ at end deftypefn
+findall
+ at c ./plot/findall.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} findall ()
+ at deftypefnx {Function File} {@var{h} =} findall (@var{prop_name}, @var{prop_value})
+ at deftypefnx {Function File} {@var{h} =} findall (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} findall (@var{h}, "-depth", @var{d}, @dots{})
+Find object with specified property values including hidden handles.
+
+This function performs the same function as @code{findobj}, but it
+includes hidden objects in its search.  For full documentation, see
+ at code{findobj}.
+ at seealso{get, set, findobj, allchild}
+ at end deftypefn
+gca
+ at c ./plot/gca.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gca ()
+Return a handle to the current axis object.  If no axis object
+exists, create one and return its handle.  The handle may then be
+used to examine or set properties of the axes.  For example,
+
+ at example
+ at group
+ax = gca ();
+set (ax, "position", [0.5, 0.5, 0.5, 0.5]);
+ at end group
+ at end example
+
+ at noindent
+creates an empty axes object, then changes its location and size in
+the figure window.
+ at seealso{get, set}
+ at end deftypefn
+semilogxerr
+ at c ./plot/semilogxerr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} semilogxerr (@var{args})
+Produce two-dimensional plots on a semilogarithm axis with errorbars.
+Many different combinations of arguments are possible.  The most used
+form is
+
+ at example
+semilogxerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+ at end example
+
+ at noindent
+which produces a semi-logarithm plot of @var{y} versus @var{x}
+with errors in the @var{y}-scale defined by @var{ey} and the plot
+format defined by @var{fmt}.  See errorbar for available formats and 
+additional information.
+ at seealso{errorbar, loglogerr semilogyerr}
+ at end deftypefn
+semilogyerr
+ at c ./plot/semilogyerr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} semilogyerr (@var{args})
+Produce two-dimensional plots on a semilogarithm axis with errorbars.
+Many different combinations of arguments are possible.  The most used
+form is
+
+ at example
+semilogyerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+ at end example
+
+ at noindent
+which produces a semi-logarithm plot of @var{y} versus @var{x}
+with errors in the @var{y}-scale defined by @var{ey} and the plot
+format defined by @var{fmt}.  See errorbar for available formats and 
+additional information.
+ at seealso{errorbar, loglogerr semilogxerr}
+ at end deftypefn
+sphere
+ at c ./plot/sphere.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sphere (@var{n})
+ at deftypefnx {Function File} {} sphere (@var{h}, @dots{})
+Generates three matrices in @code{meshgrid} format, such that 
+ at code{surf (@var{x}, @var{y}, @var{z})} generates a unit sphere. 
+The matrices of @code{@var{n}+1}-by- at code{@var{n}+1}.  If @var{n} is 
+omitted then a default value of 20 is assumed.
+
+Called with no return arguments, @code{sphere} call directly 
+ at code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle is passed
+as the first argument, the surface is plotted to this set of axes.
+ at seealso{peaks}
+ at end deftypefn
+xlabel
+ at c ./plot/xlabel.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} xlabel (@var{string})
+ at deftypefnx {Function File} {} ylabel (@var{string})
+ at deftypefnx {Function File} {} zlabel (@var{string})
+ at deftypefnx {Function File} {} xlabel (@var{h}, @var{string})
+Specify x, y, and z axis labels for the current figure.  If @var{h} is
+specified then label the axis defined by @var{h}.
+ at seealso{plot, semilogx, semilogy, loglog, polar, mesh, contour,
+bar, stairs, title}
+ at end deftypefn
+meshz
+ at c ./plot/meshz.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} meshz (@var{x}, @var{y}, @var{z})
+Plot a curtain mesh given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.
+ at seealso{meshgrid, mesh, contour}
+ at end deftypefn
+__quiver__
+ at c ./plot/__quiver__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{hg} =} __quiver__ (@dots{})
+Undocumented internal function.
+ at end deftypefn
+ezplot3
+ at c ./plot/ezplot3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezplot3 (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezplot3 (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezplot3 (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezplot3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezplot3 (@dots{})
+
+Plots in three-dimensions the curve defined parametrically. 
+ at var{fx}, @var{fy}, and @var{fz} are strings, inline functions
+or function handles with one arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi}  
+with 60 points. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of @var{t}.  @var{n} is a scalar defining the number of points to use.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+fx = @@(t) cos (t);
+fy = @@(t) sin (t);
+fz = @@(t) t;
+ezplot3 (fx, fy, fz, [0, 10*pi], 100);
+ at end group
+ at end example
+
+ at seealso{plot3, ezplot, ezsurf, ezmesh}
+ at end deftypefn
+hidden
+ at c ./plot/hidden.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hidden (@var{mode})
+ at deftypefnx {Function File} {} hidden ()
+Manipulation the mesh hidden line removal.  Called with no argument
+the hidden line removal is toggled.  The argument @var{mode} can be either
+'on' or 'off' and the set of the hidden line removal is set accordingly.
+ at seealso{mesh, meshc, surf}
+ at end deftypefn
+shg
+ at c ./plot/shg.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} shg
+Show the graph window.  Currently, this is the same as executing
+ at code{drawnow}.
+ at seealso{drawnow, figure}
+ at end deftypefn
+specular
+ at c ./plot/specular.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{l}, @var{v})
+ at deftypefnx {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{l}, @var{v}, @var{se})
+Calculate specular reflection strength of a surface defined by the normal
+vector elements @var{sx}, @var{sy}, @var{sz} using Phong's approximation. 
+The light and view vectors can be specified using parameter @var{L} and @var{V} respectively.
+Both can be given as 2-element vectors [azimuth, elevation] in degrees or as 3-element
+vector [x, y, z].  An optional 6th argument describes the specular exponent (spread) @var{se}.
+ at seealso{surfl, diffuse}
+ at end deftypefn
+__plt2ss__
+ at c ./plot/__plt2ss__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2ss__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+__plt2sv__
+ at c ./plot/__plt2sv__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2sv__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+__gnuplot_has_feature__
+ at c ./plot/__gnuplot_has_feature__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{has_feature} =} __gnuplot_has_feature__ (@var{feature})
+Undocumented internal function.
+ at end deftypefn
+gcf
+ at c ./plot/gcf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gcf ()
+Return the current figure handle.  If a figure does not exist, create
+one and return its handle.  The handle may then be used to examine or
+set properties of the figure.  For example,
+
+ at example
+ at group
+fplot (@@sin, [-10, 10]);
+fig = gcf ();
+set (fig, "visible", "off");
+ at end group
+ at end example
+
+ at noindent
+plots a sine wave, finds the handle of the current figure, and then
+makes that figure invisible.  Setting the visible property of the
+figure to @code{"on"} will cause it to be displayed again.
+ at seealso{get, set}
+ at end deftypefn
+__patch__
+ at c ./plot/__patch__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{h}, @var{fail}] =} __patch__ (@var{p}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+ezmesh
+ at c ./plot/ezmesh.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezmesh (@var{f})
+ at deftypefnx {Function File} {} ezmesh (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezmesh (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezmesh (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezmesh (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezmesh (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezmesh (@dots{})
+
+Plots the mesh defined by a function.  @var{f} is a string, inline
+function or function handle with two arguments defining the function.  By 
+default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezmesh (f, [-3, 3]);
+ at end group
+ at end example
+
+An example of a parametrically defined function is
+
+ at example
+ at group
+fx = @@(s,t) cos (s) .* cos(t);
+fy = @@(s,t) sin (s) .* cos(t);
+fz = @@(s,t) sin(t);
+ezmesh (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+ at end group
+ at end example
+
+ at seealso{ezplot, ezsurf, ezsurfc, ezmeshc}
+ at end deftypefn
+bar
+ at c ./plot/bar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bar (@var{x}, @var{y})
+ at deftypefnx {Function File} {} bar (@var{y})
+ at deftypefnx {Function File} {} bar (@var{x}, @var{y}, @var{w})
+ at deftypefnx {Function File} {} bar (@var{x}, @var{y}, @var{w}, @var{style})
+ at deftypefnx {Function File} {@var{h} =} bar (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} bar (@var{h}, @dots{})
+Produce a bar graph from two vectors of x-y data.
+
+If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+The default width of 0.8 for the bars can be changed using @var{w}. 
+
+If @var{y} is a matrix, then each column of @var{y} is taken to be a
+separate bar graph plotted on the same graph.  By default the columns
+are plotted side-by-side.  This behavior can be changed by the @var{style}
+argument, which can take the values @code{"grouped"} (the default),
+or @code{"stacked"}.
+
+The optional return value @var{h} provides a handle to the "bar series"
+object with one handle per column of the variable @var{y}.  This
+series allows common elements of the group of bar series objects to
+be changed in a single bar series and the same properties are changed
+in the other "bar series".  For example
+
+ at example
+ at group
+h = bar (rand (5, 10));
+set (h(1), "basevalue", 0.5);
+ at end group
+ at end example
+
+ at noindent
+changes the position on the base of all of the bar series.
+
+The optional input handle @var{h} allows an axis handle to be passed.
+Properties of the patch graphics object can be changed using
+ at var{prop}, @var{val} pairs.
+
+ at seealso{barh, plot} 
+ at end deftypefn
+waitforbuttonpress
+ at c ./plot/waitforbuttonpress.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{b} =} waitforbuttonpress ()
+Wait for button or mouse press.over a figure window.  The value of
+ at var{b} returns 0 if a mouse button was pressed or 1 is a key was
+pressed.
+ at seealso{ginput}
+ at end deftypefn
+pie
+ at c ./plot/pie.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pie (@var{y})
+ at deftypefnx {Function File} {} pie (@var{y}, @var{explode})
+ at deftypefnx {Function File} {} pie (@dots{}, @var{labels})
+ at deftypefnx {Function File} {} pie (@var{h}, @dots{});
+ at deftypefnx {Function File} {@var{h} =} pie (@dots{});
+Produce a pie chart. 
+
+Called with a single vector argument, produces a pie chart of the
+elements in @var{x}, with the size of the slice determined by percentage
+size of the values of @var{x}.
+
+The variable @var{explode} is a vector of the same length as @var{x} that
+if non zero 'explodes' the slice from the pie chart.
+
+If given @var{labels} is a cell array of strings of the same length as
+ at var{x}, giving the labels of each of the slices of the pie chart. 
+
+The optional return value @var{h} provides a handle to the patch object.
+
+ at seealso{bar, stem}
+ at end deftypefn
+surfc
+ at c ./plot/surfc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} surfc (@var{x}, @var{y}, @var{z})
+Plot a surface and contour given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.
+ at seealso{meshgrid, surf, contour}
+ at end deftypefn
+fplot
+ at c ./plot/fplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fplot (@var{fn}, @var{limits})
+ at deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{tol})
+ at deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{n})
+ at deftypefnx {Function File} {} fplot (@dots{}, @var{fmt})
+Plot a function @var{fn}, within the defined limits.  @var{fn}
+an be either a string, a function handle or an inline function.
+The limits of the plot are given by @var{limits} of the form
+ at code{[@var{xlo}, @var{xhi}]} or @code{[@var{xlo}, @var{xhi},
+ at var{ylo}, @var{yhi}]}.  @var{tol} is the default tolerance to use for the
+plot, and if @var{tol} is an integer it is assumed that it defines the 
+number points to use in the plot.  The @var{fmt} argument is passed
+to the plot command.
+
+ at example
+ at group
+   fplot ("cos", [0, 2*pi])
+   fplot ("[cos(x), sin(x)]", [0, 2*pi])
+ at end group
+ at end example
+ at seealso{plot}
+ at end deftypefn
+ylabel
+ at c ./plot/ylabel.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ylabel (@var{string})
+ at deftypefnx {Function File} {} ylabel (@var{h}, @var{string})
+ at seealso{xlabel}.
+ at end deftypefn
+sombrero
+ at c ./plot/sombrero.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sombrero (@var{n})
+Produce the familiar three-dimensional sombrero plot using @var{n}
+grid lines.  If @var{n} is omitted, a value of 41 is assumed.
+
+The function plotted is
+
+ at example
+z = sin (sqrt (x^2 + y^2)) / (sqrt (x^2 + y^2))
+ at end example
+ at seealso{surf, meshgrid, mesh}
+ at end deftypefn
+pcolor
+ at c ./plot/pcolor.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pcolor (@var{x}, @var{y}, @var{c})
+ at deftypefnx {Function File} {} pcolor (@var{c})
+Density plot for given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{c} corresponding to the @var{x} and @var{y} coordinates of
+the mesh's vertices.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{c}(i,j)).  Thus, columns of @var{c}
+correspond to different @var{x} values and rows of @var{c} correspond
+to different @var{y} values.
+
+The @code{colormap} is scaled to the extents of @var{c}.
+Limits may be placed on the color axis by the
+command @code{caxis}, or by setting the @code{clim} property of the
+parent axis.
+
+The face color of each cell of the mesh is determined by interpolating
+the values of @var{c} for the cell's vertices.  Contrast this with 
+ at code{imagesc} which renders one cell for each element of @var{c}.
+
+ at code{shading} modifies an attribute determining the manner by which the
+face color of each cell is interpolated from the values of @var{c},
+and the visibility of the cells' edges.  By default the attribute is
+"faceted", which renders a single color for each cell's face with the edge
+visible.
+
+ at var{h} is the handle to the surface object.
+
+ at seealso{caxis, contour, meshgrid, imagesc, shading}
+ at end deftypefn
+surfnorm
+ at c ./plot/surfnorm.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} surfnorm (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} surfnorm (@var{z})
+ at deftypefnx {Function File} {[@var{nx}, @var{ny}, @var{nz}] =} surfnorm (@dots{})
+ at deftypefnx {Function File} {} surfnorm (@var{h}, @dots{})
+Find the vectors normal to a meshgridded surface.  The meshed gridded 
+surface is defined by @var{x}, @var{y}, and @var{z}.  If @var{x} and 
+ at var{y} are not defined, then it is assumed that they are given by
+
+ at example
+ at group
+[@var{x}, @var{y}] = meshgrid (1:size(@var{z}, 1), 
+                     1:size(@var{z}, 2));
+ at end group
+ at end example
+
+If no return arguments are requested, a surface plot with the normal 
+vectors to the surface is plotted.  Otherwise the components of the normal
+vectors at the mesh gridded points are returned in @var{nx}, @var{ny},
+and @var{nz}.
+
+The normal vectors are calculated by taking the cross product of the 
+diagonals of each of the quadrilaterals in the meshgrid to find the 
+normal vectors of the centers of these quadrilaterals.  The four nearest
+normal vectors to the meshgrid points are then averaged to obtain the 
+normal to the surface at the meshgridded points.
+
+An example of the use of @code{surfnorm} is
+
+ at example
+surfnorm (peaks (25));
+ at end example
+ at seealso{surf, quiver3}
+ at end deftypefn
+__gnuplot_get_var__
+ at c ./plot/__gnuplot_get_var__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{value} =} __gnuplot_get_var__ (@var{h}, @var{name}, @var{fmt})
+Undocumented internal function.
+ at end deftypefn
+text
+ at c ./plot/text.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{label})
+ at deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{z}, @var{label})
+ at deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{label}, @var{p1}, @var{v1}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{z}, @var{label}, @var{p1}, @var{v1}, @dots{})
+Create a text object with text @var{label} at position @var{x},
+ at var{y}, @var{z} on the current axes.  Property-value pairs following
+ at var{label} may be used to specify the appearance of the text.
+ at end deftypefn
+ezmeshc
+ at c ./plot/ezmeshc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezmeshc (@var{f})
+ at deftypefnx {Function File} {} ezmeshc (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezmeshc (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezmeshc (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezmeshc (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezmeshc (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezmeshc (@dots{})
+
+Plots the mesh and contour lines defined by a function.  @var{f} is a string,
+inline function or function handle with two arguments defining the function.
+By default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+ at code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezmeshc (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{ezplot, ezsurfc, ezsurf, ezmesh}
+ at end deftypefn
+plotyy
+ at c ./plot/plotyy.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} plotyy (@var{x1}, @var{y1}, @var{x2}, @var{y2})
+ at deftypefnx {Function File} {} plotyy (@dots{}, @var{fun})
+ at deftypefnx {Function File} {} plotyy (@dots{}, @var{fun1}, @var{fun2})
+ at deftypefnx {Function File} {} plotyy (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{ax}, @var{h1}, @var{h2}] =} plotyy (@dots{})
+Plots two sets of data with independent y-axes.  The arguments @var{x1} and
+ at var{y1} define the arguments for the first plot and @var{x1} and @var{y2}
+for the second. 
+
+By default the arguments are evaluated with 
+ at code{feval (@@plot, @var{x}, @var{y})}.  However the type of plot can be
+modified with the @var{fun} argument, in which case the plots are
+generated by @code{feval (@var{fun}, @var{x}, @var{y})}.  @var{fun} can be 
+a function handle, an inline function or a string of a function name.
+
+The function to use for each of the plots can be independently defined 
+with @var{fun1} and @var{fun2}.
+
+If given, @var{h} defines the principal axis in which to plot the @var{x1}
+and @var{y1} data.  The return value @var{ax} is a two element vector with
+the axis handles of the two plots.  @var{h1} and @var{h2} are handles to
+the objects generated by the plot commands.
+
+ at example
+ at group
+x = 0:0.1:2*pi; 
+y1 = sin (x);
+y2 = exp (x - 1);
+ax = plotyy (x, y1, x - 1, y2, @@plot, @@semilogy);
+xlabel ("X");
+ylabel (ax(1), "Axis 1");
+ylabel (ax(2), "Axis 2");
+ at end group
+ at end example
+ at end deftypefn
+rose
+ at c ./plot/rose.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rose (@var{th}, @var{r})
+ at deftypefnx {Function File} {} rose (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} rose (@dots{})
+ at deftypefnx {Function File} {[@var{r}, @var{th}] =} rose (@dots{})
+
+Plot an angular histogram.  With one vector argument @var{th}, plots the
+histogram with 20 angular bins.  If @var{th} is a matrix, then each column
+of @var{th} produces a separate histogram.
+
+If @var{r} is given and is a scalar, then the histogram is produced with
+ at var{r} bins.  If @var{r} is a vector, then the center of each bin are 
+defined by the values of @var{r}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+If two output arguments are requested, then rather than plotting the 
+histogram, the polar vectors necessary to plot the histogram are 
+returned.
+
+ at example
+ at group
+[r, t] = rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)]);
+polar (r, t);
+ at end group
+ at end example
+
+
+ at seealso{plot, compass, polar, hist}
+ at end deftypefn
+comet
+ at c ./plot/comet.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} comet (@var{y})
+ at deftypefnx {Function File} {} comet (@var{x}, @var{y})
+ at deftypefnx {Function File} {} comet (@var{x}, @var{y}, @var{p})
+ at deftypefnx {Function File} {} comet (@var{ax}, @dots{})
+Produce a simple comet style animation along the trajectory provided by 
+the input coordinate vectors (@var{x}, @var{y}), where @var{x} will default
+to the indices of @var{y}.
+
+The speed of the comet may be controlled by @var{p}, which represents the
+time which passes as the animation passes from one point to the next.  The
+default for @var{p} is 0.1 seconds.
+
+If @var{ax} is specified the animation is produced in that axis rather than
+the @code{gca}.
+ at end deftypefn
+clabel
+ at c ./plot/clabel.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} clabel (@var{c}, @var{h})
+ at deftypefnx {Function File} {} clabel (@var{c}, @var{h}, @var{v})
+ at deftypefnx {Function File} {} clabel (@var{c}, @var{h}, "manual")
+ at deftypefnx {Function File} {} clabel (@var{c})
+ at deftypefnx {Function File} {} clabel (@var{c}, @var{h})
+ at deftypefnx {Function File} {} clabel (@dots{}, @var{prop}, @var{val}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} clabel (@dots{})
+Adds labels to the contours of a contour plot.  The contour plot is specified
+by the contour matrix @var{c} and optionally the contourgroup object @var{h}
+that are returned by @code{contour}, @code{contourf} and @code{contour3}.
+The contour labels are rotated and placed in the contour itself.
+
+By default, all contours are labelled.  However, the contours to label can be
+specified by the vector @var{v}.  If the "manual" argument is given then
+the contours to label can be selected with the mouse.
+
+Additional property/value pairs that are valid properties of text objects
+can be given and are passed to the underlying text objects.  Additionally,
+the property "LabelSpacing" is available allowing the spacing between labels
+on a contour (in points) to be specified.  The default is 144 points, or 2
+inches.
+
+The returned value @var{h} is the set of text object that represent the
+contour labels.  The "userdata" property of the text objects contains the
+numerical value of the contour label.
+
+An example of the use of @code{clabel} is
+
+ at example
+ at group
+[c, h] = contour (peaks(), -4 : 6);
+clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+ at end group
+ at end example
+
+ at seealso{contour, contourf, contour3, meshc, surfc, text}
+ at end deftypefn
+axis
+ at c ./plot/axis.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} axis (@var{limits})
+Set axis limits for plots.
+
+The argument @var{limits} should be a 2, 4, or 6 element vector.  The
+first and second elements specify the lower and upper limits for the x
+axis.  The third and fourth specify the limits for the y-axis, and the
+fifth and sixth specify the limits for the z-axis.
+
+Without any arguments, @code{axis} turns autoscaling on.  
+
+With one output argument, @code{x = axis} returns the current axes 
+
+The vector argument specifying limits is optional, and additional
+string arguments may be used to specify various axis properties.  For
+example,
+
+ at example
+axis ([1, 2, 3, 4], "square");
+ at end example
+
+ at noindent
+forces a square aspect ratio, and
+
+ at example
+axis ("labely", "tic");
+ at end example
+
+ at noindent
+turns tic marks on for all axes and tic mark labels on for the y-axis
+only.
+
+ at noindent
+The following options control the aspect ratio of the axes.
+
+ at table @code
+ at item "square"
+Force a square aspect ratio.
+ at item "equal"
+Force x distance to equal y-distance.
+ at item "normal"
+Restore the balance.
+ at end table
+
+ at noindent
+The following options control the way axis limits are interpreted.
+
+ at table @code
+ at item "auto" 
+Set the specified axes to have nice limits around the data
+or all if no axes are specified.
+ at item "manual" 
+Fix the current axes limits.
+ at item "tight"
+Fix axes to the limits of the data.
+ at end table
+
+ at noindent
+The option @code{"image"} is equivalent to @code{"tight"} and
+ at code{"equal"}.
+
+ at noindent
+The following options affect the appearance of tic marks.
+
+ at table @code
+ at item "on" 
+Turn tic marks and labels on for all axes.
+ at item "off"
+Turn tic marks off for all axes.
+ at item "tic[xyz]"
+Turn tic marks on for all axes, or turn them on for the
+specified axes and off for the remainder.
+ at item "label[xyz]"
+Turn tic labels on for all axes, or turn them on for the 
+specified axes and off for the remainder.
+ at item "nolabel"
+Turn tic labels off for all axes.
+ at end table
+Note, if there are no tic marks for an axis, there can be no labels.
+
+ at noindent
+The following options affect the direction of increasing values on
+the axes.
+
+ at table @code
+ at item "ij"
+Reverse y-axis, so lower values are nearer the top.
+ at item "xy" 
+Restore y-axis, so higher values are nearer the top. 
+ at end table
+
+If an axes handle is passed as the first argument, then operate on
+this axes rather than the current axes.
+ at end deftypefn
+cla
+ at c ./plot/cla.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cla ()
+ at deftypefnx {Function File} {} cla ("reset")
+ at deftypefnx {Function File} {} cla (@var{hax})
+ at deftypefnx {Function File} {} cla (@var{hax}, "reset")
+Delete the children of the current axes with visible handles.
+If @var{hax} is specified and is an axes object handle, operate on it
+instead of the current axes.  If the optional argument @code{"reset"}
+is specified, also delete the children with hidden handles.
+ at seealso{clf}
+ at end deftypefn
+surfl
+ at c ./plot/surfl.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} surfl (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} surfl (@var{z})
+ at deftypefnx {Function File} {} surfl (@var{x}, @var{y}, @var{z}, @var{L})
+ at deftypefnx {Function File} {} surfl (@var{x}, @var{y}, @var{z}, @var{L}, @var{P})
+ at deftypefnx {Function File} {} surfl (@dots{},"light")
+Plot a lighted surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+correspond to different @var{x} values and rows of @var{z} correspond
+to different @var{y} values.
+
+The light direction can be specified using @var{L}.  It can be
+given as 2-element vector [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz].
+The default value is rotated 45° counter-clockwise from the current view.
+
+The material properties of the surface can specified using a 4-element vector
+ at var{P} = [@var{AM} @var{D} @var{SP} @var{exp}] which defaults to
+ at var{p} = [0.55 0.6 0.4 10]. 
+ at table @code
+ at item "AM" strength of ambient light
+ at item "D" strength of diffuse reflection
+ at item "SP" strength of specular reflection
+ at item "EXP" specular exponent
+ at end table
+
+The default lighting mode "cdata", changes the cdata property to give the impression
+of a lighted surface.  Please note: the alternative "light" mode, which creates a light
+object to illuminate the surface is not implemented (yet).
+
+Example:
+
+ at example
+ at group
+colormap(bone);
+surfl(peaks);
+shading interp;
+ at end group
+ at end example
+ at seealso{surf, diffuse, specular, surface}
+ at end deftypefn
+__plt_get_axis_arg__
+ at c ./plot/__plt_get_axis_arg__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{h}, @var{varargin}, @var{narg}] =} __plt_get_axis_arg__ (@var{caller}, @var{varargin})
+Undocumented internal function.
+ at end deftypefn
+subplot
+ at c ./plot/subplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} subplot (@var{rows}, @var{cols}, @var{index})
+ at deftypefnx {Function File} {} subplot (@var{rcn})
+Set up a plot grid with @var{cols} by @var{rows} subwindows and plot
+in location given by @var{index}.
+
+If only one argument is supplied, then it must be a three digit value
+specifying the location in digits 1 (rows) and 2 (columns) and the plot
+index in digit 3.
+
+The plot index runs row-wise.  First all the columns in a row are filled
+and then the next row is filled.
+
+For example, a plot with 2 by 3 grid will have plot indices running as
+follows:
+ at tex
+\vskip 10pt
+\hfil\vbox{\offinterlineskip\hrule
+\halign{\vrule#&&\qquad\hfil#\hfil\qquad\vrule\cr
+height13pt&1&2&3\cr height12pt&&&\cr\noalign{\hrule}
+height13pt&4&5&6\cr height12pt&&&\cr\noalign{\hrule}}}
+\hfil
+\vskip 10pt
+ at end tex
+ at ifnottex
+ at display
+ at example
+ at group
+
++-----+-----+-----+
+|  1  |  2  |  3  |
++-----+-----+-----+
+|  4  |  5  |  6  |
++-----+-----+-----+
+ at end group
+ at end example
+ at end display
+ at end ifnottex
+ at seealso{plot}
+ at end deftypefn
+__axis_label__
+ at c ./plot/__axis_label__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __axis_label__ (@var{caller}, @var{txt}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+contourc
+ at c ./plot/contourc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{c}, @var{lev}] =}  contourc (@var{x}, @var{y}, @var{z}, @var{vn})
+Compute isolines (contour lines) of the matrix @var{z}. 
+Parameters @var{x}, @var{y} and @var{vn} are optional.
+
+The return value @var{lev} is a vector of the contour levels.
+The return value @var{c} is a 2 by @var{n} matrix containing the
+contour lines in the following format
+
+ at example
+ at group
+ at var{c} = [lev1, x1, x2, @dots{}, levn, x1, x2, @dots{} 
+     len1, y1, y2, @dots{}, lenn, y1, y2, @dots{}]
+ at end group
+ at end example
+
+ at noindent
+in which contour line @var{n} has a level (height) of @var{levn} and
+length of @var{lenn}.
+
+If @var{x} and @var{y} are omitted they are taken as the row/column 
+index of @var{z}.  @var{vn} is either a scalar denoting the number of lines 
+to compute or a vector containing the values of the lines.  If only one 
+value is wanted, set @code{@var{vn} = [val, val]};
+If @var{vn} is omitted it defaults to 10.
+
+For example,
+ at example
+ at group
+x = 0:2;
+y = x;
+z = x' * y;
+contourc (x, y, z, 2:3)
+     @result{}   2.0000   2.0000   1.0000   3.0000   1.5000   2.0000
+     2.0000   1.0000   2.0000   2.0000   2.0000   1.5000
+
+ at end group
+ at end example
+ at seealso{contour}
+ at end deftypefn
+__plt2vv__
+ at c ./plot/__plt2vv__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2vv__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+plot3
+ at c ./plot/plot3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} plot3 (@var{args})
+Produce three-dimensional plots.  Many different combinations of
+arguments are possible.  The simplest form is
+
+ at example
+plot3 (@var{x}, @var{y}, @var{z})
+ at end example
+
+ at noindent
+in which the arguments are taken to be the vertices of the points to
+be plotted in three dimensions.  If all arguments are vectors of the
+same length, then a single continuous line is drawn.  If all arguments
+are matrices, then each column of the matrices is treated as a
+separate line.  No attempt is made to transpose the arguments to make
+the number of rows match.
+
+If only two arguments are given, as
+
+ at example
+plot3 (@var{x}, @var{c})
+ at end example
+
+ at noindent
+the real and imaginary parts of the second argument are used
+as the @var{y} and @var{z} coordinates, respectively.
+
+If only one argument is given, as
+
+ at example
+plot3 (@var{c})
+ at end example
+
+ at noindent
+the real and imaginary parts of the argument are used as the @var{y}
+and @var{z} values, and they are plotted versus their index.
+
+Arguments may also be given in groups of three as
+
+ at example
+plot3 (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2}, @dots{})
+ at end example
+
+ at noindent
+in which each set of three arguments is treated as a separate line or
+set of lines in three dimensions.
+
+To plot multiple one- or two-argument groups, separate each group
+with an empty format string, as
+
+ at example
+plot3 (@var{x1}, @var{c1}, "", @var{c2}, "", @dots{})
+ at end example
+
+An example of the use of @code{plot3} is
+
+ at example
+ at group
+   z = [0:0.05:5];
+   plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+   plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
+ at end group
+ at end example
+ at seealso{plot, xlabel, ylabel, zlabel, title, print}
+ at end deftypefn
+ezpolar
+ at c ./plot/ezpolar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezpolar (@var{f})
+ at deftypefnx {Function File} {} ezpolar (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezpolar (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezpolar (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezpolar (@dots{})
+
+Plots in polar plot defined by a function.  The function @var{f} is either
+a string, inline function or function handle with one arguments defining 
+the function.  By default the plot is over the domain @code{0 < @var{x} < 
+2*pi} with 60 points. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{t}.  @var{n} is a scalar defining the number of points to 
+use.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ezpolar (@@(t) 1 + sin (t));
+ at end example
+
+ at seealso{polar, ezplot, ezsurf, ezmesh}
+ at end deftypefn
+__gnuplot_ginput__
+ at c ./plot/__gnuplot_ginput__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __gnuplot_ginput__ (@var{f}, @var{n})
+Undocumented internal function.
+ at end deftypefn
+ribbon
+ at c ./plot/ribbon.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} ribbon (@var{x}, @var{y}, @var{width})
+ at deftypefnx {Function File} {} ribbon (@var{y})
+ at deftypefnx {Function File} {@var{h} =} ribbon (@dots{})
+Plot a ribbon plot for the columns of @var{y} vs.  @var{x}.  The
+optional parameter @var{width} specifies the width of a single ribbon
+(default is 0.75).  If @var{x} is omitted, a vector containing the
+row numbers is assumed (1:rows(Y)).  If requested, return a vector
+ at var{h} of the handles to the surface objects.
+ at seealso{gca, colorbar}
+ at end deftypefn
+__go_draw_figure__
+ at c ./plot/__go_draw_figure__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __go_draw_figure__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono})
+Undocumented internal function.
+ at end deftypefn
+pareto
+ at c ./plot/pareto.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pareto (@var{x})
+ at deftypefnx {Function File} {} pareto (@var{x}, @var{y})
+ at deftypefnx {Function File} {} pareto (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} pareto (@dots{})
+Draw a Pareto chart, also called ABC chart.  A Pareto chart is a bar graph 
+used to arrange information in such a way that priorities for process 
+improvement can be established.  It organizes and displays information 
+to show the relative importance of data.  The chart is similar to the 
+histogram or bar chart, except that the bars are arranged in decreasing 
+order from left to right along the abscissa.
+
+The fundamental idea (Pareto principle) behind the use of Pareto 
+diagrams is that the majority of an effect is due to a small subset of the
+causes, so for quality improvement the first few (as presented on the 
+diagram) contributing causes to a problem usually account for the majority 
+of the result.  Thus, targeting these "major causes" for elimination 
+results in the most cost-effective improvement scheme.
+
+The data are passed as @var{x} and the abscissa as @var{y}.  If @var{y} is
+absent, then the abscissa are assumed to be @code{1 : length (@var{x})}.
+ at var{y} can be a string array, a cell array of strings or a numerical
+vector.
+
+An example of the use of @code{pareto} is
+
+ at example
+ at group
+Cheese = @{"Cheddar", "Swiss", "Camembert", ...
+          "Munster", "Stilton", "Blue"@};
+Sold = [105, 30, 70, 10, 15, 20];
+pareto(Sold, Cheese);
+ at end group
+ at end example
+ at end deftypefn
+legend
+ at c ./plot/legend.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} legend (@var{st1}, @var{st2}, @dots{})
+ at deftypefnx {Function File} {} legend (@var{st1}, @var{st2}, @dots{}, "location", @var{pos})
+ at deftypefnx {Function File} {} legend (@var{matstr})
+ at deftypefnx {Function File} {} legend (@var{matstr}, "location", @var{pos})
+ at deftypefnx {Function File} {} legend (@var{cell})
+ at deftypefnx {Function File} {} legend (@var{cell}, "location", @var{pos})
+ at deftypefnx {Function File} {} legend ('@var{func}')
+
+Display a legend for the current axes using the specified strings
+as labels.  Legend entries may be specified as individual character
+string arguments, a character array, or a cell array of character
+strings.  Legend works on line graphs, bar graphs, etc.  A plot must
+exist before legend is called.
+
+The optional parameter @var{pos} specifies the location of the legend
+as follows:
+
+ at multitable @columnfractions 0.06 0.14 0.80
+ at item @tab north @tab
+  center top
+ at item @tab south @tab
+  center bottom
+ at item @tab east @tab
+  right center
+ at item @tab west @tab
+  left center
+ at item @tab northeast @tab
+  right top (default)
+ at item @tab northwest @tab
+  left top
+ at item @tab southeast @tab
+  right bottom
+ at item @tab southwest @tab
+  left bottom
+ at item 
+ at item @tab outside @tab
+  can be appended to any location string
+ at end multitable
+
+Some specific functions are directly available using @var{func}:
+
+ at table @asis
+ at item "show"
+  Show legends from the plot
+ at item "hide"
+ at itemx "off"
+  Hide legends from the plot
+ at item "boxon"
+  Draw a box around legends
+ at item "boxoff"
+  Withdraw the box around legends
+ at item "left"
+  Text is to the left of the keys
+ at item "right"
+  Text is to the right of the keys
+ at end table
+ at end deftypefn
+mesh
+ at c ./plot/mesh.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mesh (@var{x}, @var{y}, @var{z})
+Plot a mesh given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+correspond to different @var{x} values and rows of @var{z} correspond
+to different @var{y} values.
+ at seealso{meshgrid, contour}
+ at end deftypefn
+peaks
+ at c ./plot/peaks.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} peaks ()
+ at deftypefnx {Function File} {} peaks (@var{n})
+ at deftypefnx {Function File} {} peaks (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{z} =} peaks (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} peaks (@dots{})
+Generate a function with lots of local maxima and minima.  The function
+has the form
+
+ at tex
+$f(x,y) = 3 (1 - x) ^ 2 e ^ {\left(-x^2 - (y+1)^2\right)} - 10 \left({x \over 5} - x^3 - y^5)\right) - {1 \over 3} e^{\left(-(x+1)^2 - y^2\right)}$
+ at end tex
+ at ifnottex
+ at verbatim
+f(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) ...
+         - 10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) ...
+         - 1/3*exp(-(x+1)^2 - y^2)
+ at end verbatim
+ at end ifnottex
+
+Called without a return argument, @code{peaks} plots the surface of the 
+above function using @code{mesh}.  If @var{n} is a scalar, the @code{peaks}
+returns the values of the above function on a @var{n}-by- at var{n} mesh over
+the range @code{[-3,3]}.  The default value for @var{n} is 49.
+
+If @var{n} is a vector, then it represents the @var{x} and @var{y} values
+of the grid on which to calculate the above function.  The @var{x} and 
+ at var{y} values can be specified separately.
+ at seealso{surf, mesh, meshgrid}
+ at end deftypefn
+contour
+ at c ./plot/contour.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} contour (@var{z})
+ at deftypefnx {Function File} {} contour (@var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} contour (@var{x}, @var{y}, @var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour (@dots{}, @var{style})
+ at deftypefnx {Function File} {} contour (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contour (@dots{})
+Plot level curves (contour lines) of the matrix @var{z}, using the
+contour matrix @var{c} computed by @code{contourc} from the same
+arguments; see the latter for their interpretation.  The set of
+contour levels, @var{c}, is only returned if requested.  For example:
+
+ at example
+ at group
+x = 0:2;
+y = x;
+z = x' * y;
+contour (x, y, z, 2:3)
+ at end group
+ at end example
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+Any markers defined by @var{style} are ignored.
+
+The optional input and output argument @var{h} allows an axis handle to 
+be passed to @code{contour} and the handles to the contour objects to be
+returned.
+ at seealso{contourc, patch, plot}
+ at end deftypefn
+__marching_cube__
+ at c ./plot/__marching_cube__.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+ at deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col})
+Undocumented internal function.
+ at end deftypefn
+isosurface
+ at c ./plot/isosurface.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{fv}] =} isosurface (@var{val}, @var{iso})
+ at deftypefnx {Function File} {[@var{fv}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+ at deftypefnx {Function File} {[@var{fv}] =} isosurface (@dots{}, "noshare", "verbose")
+ at deftypefnx {Function File} {[@var{fvc}] =} isosurface (@dots{}, @var{col})
+ at deftypefnx {Function File} {[@var{f}, @var{v}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+ at deftypefnx {Function File} {[@var{f}, @var{v}, @var{c}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col})
+ at deftypefnx {Function File} {} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}, @var{opt})
+
+If called with one output argument and the first input argument
+ at var{val} is a three--dimensional array that contains the data of an
+isosurface geometry and the second input argument @var{iso} keeps the
+isovalue as a scalar value then return a structure array @var{fv}
+that contains the fields @var{Faces} and @var{Vertices} at computed
+points @command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}.  The output
+argument @var{fv} can directly be taken as an input argument for the 
+ at command{patch} function.
+
+If called with further input arguments @var{x}, @var{y} and @var{z}
+which are three--dimensional arrays with the same size than @var{val}
+then the volume data is taken at those given points.
+
+The string input argument "noshare" is only for compatibility and
+has no effect. If given the string input argument
+"verbose" then print messages to the command line interface about the
+current progress.
+
+If called with the input argument @var{col} which is a
+three-dimensional array of the same size than @var{val} then take
+those values for the interpolation of coloring the isosurface
+geometry.  Add the field @var{FaceVertexCData} to the structure
+array @var{fv}.
+
+If called with two or three output arguments then return the
+information about the faces @var{f}, vertices @var{v} and color data
+ at var{c} as seperate arrays instead of a single structure array.
+
+If called with no output argument then directly process the
+isosurface geometry with the @command{patch} command.
+
+For example
+
+ at example
+[x, y, z] = meshgrid (1:5, 1:5, 1:5);
+val = rand (5, 5, 5);
+isosurface (x, y, z, val, .5);
+ at end example
+
+will directly draw a random isosurface geometry in a graphics window.
+Another example for an isosurface geometry with different additional
+coloring
+
+ at example
+N = 15;    ## Increase number of vertices in each direction
+iso = .4;  ## Change isovalue to .1 to display a sphere
+lin = linspace (0, 2, N);
+[x, y, z] = meshgrid (lin, lin, lin);
+c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); 
+figure (); ## Open another figure window
+
+subplot (2, 2, 1); view (-38, 20); 
+[f, v] = isosurface (x, y, z, c, iso);
+p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+ set (p, "FaceColor", "green", "FaceLighting", "phong");
+ light ("Position", [1 1 5]); ## Available with the JHandles package
+
+subplot (2, 2, 2); view (-38, 20);
+p = patch ("Faces", f, "Vertices", v, "EdgeColor", "blue");
+set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+ set (p, "FaceColor", "none", "FaceLighting", "phong");
+ light ("Position", [1 1 5]);
+
+subplot (2, 2, 3); view (-38, 20);
+[f, v, c] = isosurface (x, y, z, c, iso, y);
+p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \
+           "FaceColor", "interp", "EdgeColor", "none");
+set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+ set (p, "FaceLighting", "phong");
+ light ("Position", [1 1 5]);
+
+subplot (2, 2, 4); view (-38, 20);
+p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \
+           "FaceColor", "interp", "EdgeColor", "blue");
+set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+ set (p, "FaceLighting", "phong");
+ light ("Position", [1 1 5]);
+ at end example
+
+ at seealso{isocolors, isonormals, isocaps}
+
+ at end deftypefn
+isocolors
+ at c ./plot/isocolors.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{cd}] =} isocolors (@var{c}, @var{v})
+ at deftypefnx {Function File} {[@var{cd}] =} isocolors (@var{x}, @var{y}, @var{z}, @var{c}, @var{v})
+ at deftypefnx {Function File} {[@var{cd}] =} isocolors (@var{x}, @var{y}, @var{z}, @var{r}, @var{g}, @var{b}, @var{v})
+ at deftypefnx {Function File} {[@var{cd}] =} isocolors (@var{r}, @var{g}, @var{b}, @var{v})
+ at deftypefnx {Function File} {[@var{cd}] =} isocolors (@dots{}, @var{p})
+ at deftypefnx {Function File} isocolors (@dots{})
+
+If called with one output argument and the first input argument
+ at var{c} is a three--dimensional array that contains color values and
+the second input argument @var{v} keeps the vertices of a geometry
+then return a matrix @var{cd} with color data information for the
+geometry at computed points 
+ at command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}.  The output argument
+ at var{cd} can be taken to manually set FaceVertexCData of a patch.
+
+If called with further input arguments @var{x}, @var{y} and @var{z}
+which are three--dimensional arrays of the same size than @var{c}
+then the color data is taken at those given points.  Instead of the
+color data @var{c} this function can also be called with RGB values
+ at var{r}, @var{g}, @var{b}.  If input argumnets @var{x}, @var{y},
+ at var{z} are not given then again @command{meshgrid} computed values
+are taken.
+
+Optionally, the patch handle @var{p} can be given as the last input
+argument to all variations of function calls instead of the vertices
+data @var{v}.  Finally, if no output argument is given then directly
+change the colors of a patch that is given by the patch handle
+ at var{p}.
+
+For example,
+ at example
+function [] = isofinish (p)
+  set (gca, "DataAspectRatioMode", "manual", \
+       "DataAspectRatio", [1 1 1]);
+  set (p, "FaceColor", "interp");
+  ## set (p, "FaceLighting", "flat");
+  ## light ("Position", [1 1 5]); ## Available with JHandles
+endfunction
+
+N = 15;    ## Increase number of vertices in each direction
+iso = .4;  ## Change isovalue to .1 to display a sphere
+lin = linspace (0, 2, N);
+[x, y, z] = meshgrid (lin, lin, lin);
+c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); 
+figure (); ## Open another figure window
+
+subplot (2, 2, 1); view (-38, 20); 
+[f, v] = isosurface (x, y, z, c, iso);
+p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+cdat = rand (size (c));       ## Compute random patch color data
+isocolors (x, y, z, cdat, p); ## Directly set colors of patch
+isofinish (p);                ## Call user function isofinish
+
+subplot (2, 2, 2); view (-38, 20); 
+p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+[r, g, b] = meshgrid (lin, 2-lin, 2-lin);
+cdat = isocolors (x, y, z, c, v); ## Compute color data vertices
+set (p, "FaceVertexCData", cdat); ## Set color data manually
+isofinish (p);
+
+subplot (2, 2, 3); view (-38, 20); 
+p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+cdat = isocolors (r, g, b, c, p); ## Compute color data patch
+set (p, "FaceVertexCData", cdat); ## Set color data manually
+isofinish (p);
+
+subplot (2, 2, 4); view (-38, 20); 
+p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+r = g = b = repmat ([1:N] / N, [N, 1, N]); ## Black to white
+cdat = isocolors (x, y, z, r, g, b, v);
+set (p, "FaceVertexCData", cdat);
+isofinish (p);
+ at end example
+
+ at seealso{isosurface, isonormals, isocaps}
+
+ at end deftypefn
+gnuplot_drawnow
+ at c ./plot/gnuplot_drawnow.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} drawnow ()
+Update and display the current graphics.
+
+Octave automatically calls drawnow just before printing a prompt,
+when @code{sleep} or @code{pause} is called, or while waiting for
+command-line input.
+ at end deftypefn
+quiver3
+ at c ./plot/quiver3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} quiver3 (@var{u}, @var{v}, @var{w})
+ at deftypefnx {Function File} {} quiver3 (@var{x}, @var{y}, @var{z}, @var{u}, @var{v}, @var{w})
+ at deftypefnx {Function File} {} quiver3 (@dots{}, @var{s})
+ at deftypefnx {Function File} {} quiver3 (@dots{}, @var{style})
+ at deftypefnx {Function File} {} quiver3 (@dots{}, 'filled')
+ at deftypefnx {Function File} {} quiver3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} quiver3 (@dots{})
+
+Plot the @code{(@var{u}, @var{v}, @var{w})} components of a vector field in 
+an @code{(@var{x}, @var{y}), @var{z}} meshgrid.  If the grid is uniform, you 
+can specify @var{x}, @var{y} @var{z} as vectors.
+
+If @var{x}, @var{y} and @var{z} are undefined they are assumed to be
+ at code{(1:@var{m}, 1:@var{n}, 1:@var{p})} where @code{[@var{m}, @var{n}] = 
+size(@var{u})} and @code{@var{p} = max (size (@var{w}))}.
+
+The variable @var{s} is a scalar defining a scaling factor to use for
+ the arrows of the field relative to the mesh spacing.  A value of 0 
+disables all scaling.  The default value is 1.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+If a marker is specified then markers at the grid points of the vectors are
+printed rather than arrows.  If the argument 'filled' is given then the
+markers as filled.
+
+The optional return value @var{h} provides a quiver group that
+regroups the components of the quiver plot (body, arrow and marker),
+and allows them to be changed together
+
+ at example
+ at group
+[x, y, z] = peaks (25);
+surf (x, y, z);
+hold on;
+[u, v, w] = surfnorm (x, y, z / 10);
+h = quiver3 (x, y, z, u, v, w);
+set (h, "maxheadsize", 0.33);
+ at end group
+ at end example
+
+ at seealso{plot}
+ at end deftypefn
+clf
+ at c ./plot/clf.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} clf ()
+ at deftypefnx {Function File} {} clf ("reset")
+ at deftypefnx {Function File} {} clf (@var{hfig})
+ at deftypefnx {Function File} {} clf (@var{hfig}, "reset")
+Clear the current figure window.  @code{clf} operates by deleting child
+graphics objects with visible handles (@code{HandleVisibility} = on).
+If @var{hfig} is specified operate on it instead of the current figure.
+If the optional argument @code{"reset"} is specified, all objects including
+those with hidden handles are deleted.
+ at seealso{cla, close, delete}
+ at end deftypefn
+hggroup
+ at c ./plot/hggroup.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hggroup ()
+ at deftypefnx {Function File} {} hggroup (@var{h})
+ at deftypefnx {Function File} {} hggroup (@dots{}, @var{property}, @var{value}, @dots{})
+Create group object with parent @var{h}.  If no parent is specified,
+the group is created in the current axes.  Return the handle of the
+group object created.
+
+Multiple property-value pairs may be specified for the group, but they
+must appear in pairs.
+ at end deftypefn
+__errcomm__
+ at c ./plot/__errcomm__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __errcomm__ (@var{caller}, @var{p}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+backend
+ at c ./plot/backend.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} backend (@var{name})
+ at deftypefnx {Function File} {} backend (@var{hlist}, @var{name})
+Change the default graphics backend to @var{name}.  If the backend is
+not already loaded, it is first initialized (initialization is done
+through the execution of @code{__init_ at var{name}__}).
+
+When called with a list of figure handles, @var{hlist}, the backend is
+changed only for the listed figures.
+ at seealso{available_backends}
+ at end deftypefn
+__clabel__
+ at c ./plot/__clabel__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} __clabel__ (@var{c}, @var{v}, @var{hparent}, @var{label_spacing}, @var{z}, @var{varargin})
+Undocumented internal function.
+ at end deftypefn
+refreshdata
+ at c ./plot/refreshdata.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} refreshdata ()
+ at deftypefnx {Function File} {} refreshdata (@var{h})
+ at deftypefnx {Function File} {} refreshdata (@var{h}, @var{workspace})
+Evaluate any @samp{datasource} properties of the current figure and update
+the plot if the corresponding data has changed.  If called with one or more
+arguments @var{h} is a scalar or array of figure handles to refresh.  The
+optional second argument @var{workspace} can take the following values.
+
+ at table @code
+ at item "base"
+Evaluate the datasource properties in the base workspace.  (default).
+ at item "caller"
+Evaluate the datasource properties in the workspace of the function
+that called @code{refreshdata}.
+ at end table
+
+An example of the use of @code{refreshdata} is:
+
+ at example
+ at group
+x = 0:0.1:10;
+y = sin (x);
+plot (x, y, "ydatasource", "y");
+for i = 1 : 100
+  pause(0.1)
+  y = sin (x + 0.1 * i);
+  refreshdata();
+endfor
+ at end group
+ at end example
+ at end deftypefn
+line
+ at c ./plot/line.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} line ()
+ at deftypefnx {Function File} {} line (@var{x}, @var{y})
+ at deftypefnx {Function File} {} line (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} line (@var{x}, @var{y}, @var{z}, @var{property}, @var{value}, @dots{})
+Create line object from @var{x} and @var{y} and insert in current
+axes object.  Return a handle (or vector of handles) to the line
+objects created.
+
+Multiple property-value pairs may be specified for the line, but they
+must appear in pairs.
+ at end deftypefn
+ezsurfc
+ at c ./plot/ezsurfc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ezsurfc (@var{f})
+ at deftypefnx {Function File} {} ezsurfc (@var{fx}, @var{fy}, @var{fz})
+ at deftypefnx {Function File} {} ezsurfc (@dots{}, @var{dom})
+ at deftypefnx {Function File} {} ezsurfc (@dots{}, @var{n})
+ at deftypefnx {Function File} {} ezsurfc (@dots{}, 'circ')
+ at deftypefnx {Function File} {} ezsurfc (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} ezsurfc (@dots{})
+
+Plots the surface and contour lines defined by a function.  @var{f} is a
+string, inline function or function handle with two arguments defining the
+function.  By default the plot is over the domain @code{-2*pi < @var{x} <
+2*pi} and @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+
+If @var{dom} is a two element vector, it represents the minimum and maximum
+value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+then the minimum and maximum value of @var{x} and @var{y} are specify
+separately.
+
+ at var{n} is a scalar defining the number of points to use in each dimension.
+
+If three functions are passed, then plot the parametrically defined 
+function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+ at var{fz} (@var{s}, @var{t})]}. 
+
+If the argument 'circ' is given, then the function is plotted over a disk
+centered on the middle of the domain @var{dom}.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+ezsurfc (f, [-3, 3]);
+ at end group
+ at end example
+
+ at seealso{ezplot, ezmeshc, ezsurf, ezmesh}
+ at end deftypefn
+__add_datasource__
+ at c ./plot/__add_datasource__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{newargs} =} __add_datasource__ (@var{fcn}, @var{h}, @var{data}, @var{varargin})
+Undocumented internal function.
+ at end deftypefn
+__next_line_color__
+ at c ./plot/__next_line_color__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{rgb} =} __next_line_color__ (@var{reset})
+Undocumented internal function.
+ at end deftypefn
+refresh
+ at c ./plot/refresh.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} refresh ()
+ at deftypefnx {Function File} {} refresh (@var{h})
+Refresh a figure, forcing it to be redrawn.  Called without an
+argument the current figure is redrawn, otherwise the figure pointed
+to by @var{h} is redrawn.
+ at seealso{drawnow}
+ at end deftypefn
+caxis
+ at c ./plot/caxis.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} caxis (@var{limits})
+ at deftypefnx {Function File} {} caxis (@var{h}, @dots{})
+Set color axis limits for plots.
+
+The argument @var{limits} should be a 2 element vector specifying the 
+lower and upper limits to assign to the first and last value in the
+colormap.  Values outside this range are clamped to the first and last
+colormap entries. 
+
+If @var{limits} is 'auto', then automatic colormap scaling is applied,
+whereas if @var{limits} is 'manual' the colormap scaling is set to manual.
+
+Called without any arguments to current color axis limits are returned.
+
+If an axes handle is passed as the first argument, then operate on
+this axes rather than the current axes.
+ at end deftypefn
+__interp_cube__
+ at c ./plot/__interp_cube__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{vxyz}, @var{idx}, @var{frac}] =} __interp_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{v})
+Undocumented internal function.
+ at end deftypefn
+quiver
+ at c ./plot/quiver.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} quiver (@var{u}, @var{v})
+ at deftypefnx {Function File} {} quiver (@var{x}, @var{y}, @var{u}, @var{v})
+ at deftypefnx {Function File} {} quiver (@dots{}, @var{s})
+ at deftypefnx {Function File} {} quiver (@dots{}, @var{style})
+ at deftypefnx {Function File} {} quiver (@dots{}, 'filled')
+ at deftypefnx {Function File} {} quiver (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} quiver (@dots{})
+
+Plot the @code{(@var{u}, @var{v})} components of a vector field in 
+an @code{(@var{x}, @var{y})} meshgrid.  If the grid is uniform, you can 
+specify @var{x} and @var{y} as vectors.
+
+If @var{x} and @var{y} are undefined they are assumed to be
+ at code{(1:@var{m}, 1:@var{n})} where @code{[@var{m}, @var{n}] = 
+size(@var{u})}.
+
+The variable @var{s} is a scalar defining a scaling factor to use for
+ the arrows of the field relative to the mesh spacing.  A value of 0 
+disables all scaling.  The default value is 1.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+If a marker is specified then markers at the grid points of the vectors are
+printed rather than arrows.  If the argument 'filled' is given then the
+markers as filled.
+
+The optional return value @var{h} provides a quiver group that
+regroups the components of the quiver plot (body, arrow and marker),
+and allows them to be changed together
+
+ at example
+ at group
+[x, y] = meshgrid (1:2:20);
+h = quiver (x, y, sin (2*pi*x/10), sin (2*pi*y/10));
+set (h, "maxheadsize", 0.33);
+ at end group
+ at end example
+
+ at seealso{plot}
+ at end deftypefn
+plot
+ at c ./plot/plot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} plot (@var{y})
+ at deftypefnx {Function File} {} plot (@var{x}, @var{y})
+ at deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
+ at deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{fmt})
+ at deftypefnx {Function File} {} plot (@var{h}, @dots{})
+Produces two-dimensional plots.  Many different combinations of
+arguments are possible.  The simplest form is
+
+ at example
+plot (@var{y})
+ at end example
+
+ at noindent
+where the argument is taken as the set of @var{y} coordinates and the
+ at var{x} coordinates are taken to be the indices of the elements,
+starting with 1.
+
+To save a plot, in one of several image formats such as PostScript
+or PNG, use the @code{print} command.
+
+If more than one argument is given, they are interpreted as
+
+ at example
+plot (@var{y}, @var{property}, @var{value}, @dots{})
+ at end example
+
+ at noindent
+or
+
+ at example
+plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
+ at end example
+
+ at noindent
+or
+
+ at example
+plot (@var{x}, @var{y}, @var{fmt}, @dots{})
+ at end example
+
+ at noindent
+and so on.  Any number of argument sets may appear.  The @var{x} and
+ at var{y} values are interpreted as follows:
+
+ at itemize @bullet
+ at item
+If a single data argument is supplied, it is taken as the set of @var{y}
+coordinates and the @var{x} coordinates are taken to be the indices of
+the elements, starting with 1.
+
+ at item
+If the @var{x} is a vector and @var{y} is a matrix, then
+the columns (or rows) of @var{y} are plotted versus @var{x}.
+(using whichever combination matches, with columns tried first.)
+
+ at item
+If the @var{x} is a matrix and @var{y} is a vector,
+ at var{y} is plotted versus the columns (or rows) of @var{x}.
+(using whichever combination matches, with columns tried first.)
+
+ at item
+If both arguments are vectors, the elements of @var{y} are plotted versus
+the elements of @var{x}.
+
+ at item
+If both arguments are matrices, the columns of @var{y} are plotted
+versus the columns of @var{x}.  In this case, both matrices must have
+the same number of rows and columns and no attempt is made to transpose
+the arguments to make the number of rows match.
+
+If both arguments are scalars, a single point is plotted.
+ at end itemize
+
+Multiple property-value pairs may be specified, but they must appear
+in pairs.  These arguments are applied to the lines drawn by
+ at code{plot}.
+
+If the @var{fmt} argument is supplied, it is interpreted as
+follows.  If @var{fmt} is missing, the default gnuplot line style
+is assumed.
+
+ at table @samp
+ at item -
+Set lines plot style (default).
+
+ at item .
+Set dots plot style.
+
+ at item @var{n}
+Interpreted as the plot color if @var{n} is an integer in the range 1 to
+6.
+
+ at item @var{nm}
+If @var{nm} is a two digit integer and @var{m} is an integer in the
+range 1 to 6, @var{m} is interpreted as the point style.  This is only
+valid in combination with the @code{@@} or @code{-@@} specifiers.
+
+ at item @var{c}
+If @var{c} is one of @code{"k"} (black), @code{"r"} (red), @code{"g"}
+(green), @code{"b"} (blue), @code{"m"} (magenta), @code{"c"} (cyan),
+or @code{"w"} (white), it is interpreted as the line plot color.
+
+ at item ";title;"
+Here @code{"title"} is the label for the key.
+
+ at item +
+ at itemx *
+ at itemx o
+ at itemx x
+ at itemx ^
+Used in combination with the points or linespoints styles, set the point
+style.
+ at end table
+
+The @var{fmt} argument may also be used to assign key titles.
+To do so, include the desired title between semi-colons after the
+formatting sequence described above, e.g., "+3;Key Title;"
+Note that the last semi-colon is required and will generate an error if
+it is left out.
+
+Here are some plot examples:
+
+ at example
+plot (x, y, "@@12", x, y2, x, y3, "4", x, y4, "+")
+ at end example
+
+This command will plot @code{y} with points of type 2 (displayed as
+ at samp{+}) and color 1 (red), @code{y2} with lines, @code{y3} with lines of
+color 4 (magenta) and @code{y4} with points displayed as @samp{+}.
+
+ at example
+plot (b, "*", "markersize", 3)
+ at end example
+
+This command will plot the data in the variable @code{b},
+with points displayed as @samp{*} with a marker size of 3.
+
+ at example
+ at group
+t = 0:0.1:6.3;
+plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+ at end group
+ at end example
+
+This will plot the cosine and sine functions and label them accordingly
+in the key.
+
+If the first argument is an axis handle, then plot into these axes, 
+rather than the current axis handle returned by @code{gca}. 
+ at seealso{semilogx, semilogy, loglog, polar, mesh, contour, bar,
+stairs, errorbar, xlabel, ylabel, title, print}
+ at end deftypefn
+scatter
+ at c ./plot/scatter.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} scatter (@var{x}, @var{y}, @var{s}, @var{c})
+ at deftypefnx {Function File} {} scatter (@dots{}, 'filled')
+ at deftypefnx {Function File} {} scatter (@dots{}, @var{style})
+ at deftypefnx {Function File} {} scatter (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} scatter (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} scatter (@dots{})
+
+Plot a scatter plot of the data.  A marker is plotted at each point 
+defined by the points in the vectors @var{x} and @var{y}.  The size of
+the markers used is determined by the @var{s}, which can be a scalar, 
+a vector of the same length of @var{x} and @var{y}.  If @var{s} is not 
+given or is an empty matrix, then the default value of 8 points is used.
+
+The color of the markers is determined by @var{c}, which can be a string
+defining a fixed color, a 3 element vector giving the red, green and blue 
+components of the color, a vector of the same length as @var{x} that gives
+a scaled index into the current colormap, or a @var{n}-by-3 matrix defining
+the colors of each of the markers individually.
+
+The marker to use can be changed with the @var{style} argument, that is a 
+string defining a marker in the same manner as the @code{plot} command. 
+If the argument 'filled' is given then the markers as filled.  All 
+additional arguments are passed to the underlying patch command.
+
+The optional return value @var{h} provides a handle to the patch object
+
+ at example
+ at group
+x = randn (100, 1);
+y = randn (100, 1);
+scatter (x, y, [], sqrt(x.^2 + y.^2));
+ at end group
+ at end example
+
+ at seealso{plot, patch, scatter3}
+ at end deftypefn
+__axes_limits__
+ at c ./plot/__axes_limits__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __axes_limits__ (@var{fcn}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+surf
+ at c ./plot/surf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} surf (@var{x}, @var{y}, @var{z})
+Plot a surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+correspond to different @var{x} values and rows of @var{z} correspond
+to different @var{y} values.
+ at seealso{mesh, surface}
+ at end deftypefn
+__scatter__
+ at c ./plot/__scatter__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{hg} =} __scatter__ (@dots{})
+Undocumented internal function.
+ at end deftypefn
+feather
+ at c ./plot/feather.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} feather (@var{u}, @var{v})
+ at deftypefnx {Function File} {} feather (@var{z})
+ at deftypefnx {Function File} {} feather (@dots{}, @var{style})
+ at deftypefnx {Function File} {} feather (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} feather (@dots{})
+
+Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
+from equidistant points on the x-axis.  If a single complex argument
+ at var{z} is given, then @code{@var{u} = real (@var{z})} and
+ at code{@var{v} = imag (@var{z})}.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+phi = [0 : 15 : 360] * pi / 180;
+feather (sin (phi), cos (phi))
+ at end group
+ at end example
+
+ at seealso{plot, quiver, compass}
+ at end deftypefn
+__gnuplot_open_stream__
+ at c ./plot/__gnuplot_open_stream__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{stream}} __gnuplot_open_stream__ (@var{npipes}, @var{h})
+Undocumented internal function.
+ at end deftypefn
+newplot
+ at c ./plot/newplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} newplot ()
+Prepare graphics engine to produce a new plot.  This function should
+be called at the beginning of all high-level plotting functions.
+ at end deftypefn
+__area__
+ at c ./plot/__area__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __area__ (@var{ax}, @var{x}, @var{y}, @var{bv}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+__plr2__
+ at c ./plot/__plr2__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plr2__ (@var{h}, @var{theta}, @var{rho}, @var{fmt})
+Undocumented internal function.
+ at end deftypefn
+polar
+ at c ./plot/polar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polar (@var{theta}, @var{rho}, @var{fmt})
+Make a two-dimensional plot given the polar coordinates @var{theta} and
+ at var{rho}.
+
+The optional third argument specifies the line type.
+ at seealso{plot}
+ at end deftypefn
+closereq
+ at c ./plot/closereq.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} closereq ()
+Close the current figure and delete all graphics objects associated
+with it.
+ at seealso{close, delete}
+ at end deftypefn
+area
+ at c ./plot/area.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} area (@var{x}, @var{y})
+ at deftypefnx {Function File} {} area (@var{x}, @var{y}, @var{lvl})
+ at deftypefnx {Function File} {} area (@dots{}, @var{prop}, @var{val}, @dots{})
+ at deftypefnx {Function File} {} area (@var{y}, @dots{})
+ at deftypefnx {Function File} {} area (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} area (@dots{})
+Area plot of cumulative sum of the columns of @var{y}.  This shows the
+contributions of a value to a sum, and is functionally similar to 
+ at code{plot (@var{x}, cumsum (@var{y}, 2))}, except that the area under 
+the curve is shaded.
+
+If the @var{x} argument is omitted it is assumed to be given by
+ at code{1 : rows (@var{y})}.  A value @var{lvl} can be defined that determines
+where the base level of the shading under the curve should be defined.
+
+Additional arguments to the @code{area} function are passed to the 
+ at code{patch}.  The optional return value @var{h} provides a handle to 
+area series object representing the patches of the areas.
+ at seealso{plot, patch}
+ at end deftypefn
+xlim
+ at c ./plot/xlim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{xl} =} xlim ()
+ at deftypefnx {Function File} {} xlim (@var{xl})
+ at deftypefnx {Function File} {@var{m} =} xlim ('mode')
+ at deftypefnx {Function File} {} xlim (@var{m})
+ at deftypefnx {Function File} {} xlim (@var{h}, @dots{})
+Get or set the limits of the x-axis of the current plot.  Called without
+arguments @code{xlim} returns the x-axis limits of the current plot.
+If passed a two element vector @var{xl}, the limits of the x-axis are set
+to this value.
+
+The current mode for calculation of the x-axis can be returned with a
+call @code{xlim ('mode')}, and can be either 'auto' or 'manual'.  The 
+current plotting mode can be set by passing either 'auto' or 'manual' 
+as the argument.
+
+If passed an handle as the first argument, then operate on this handle
+rather than the current axes handle.
+ at seealso{ylim, zlim, set, get, gca}
+ at end deftypefn
+__go_draw_axes__
+ at c ./plot/__go_draw_axes__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __go_draw_axes__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono})
+Undocumented internal function.
+ at end deftypefn
+ancestor
+ at c ./plot/ancestor.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{parent} =} ancestor (@var{h}, @var{type})
+ at deftypefnx {Function File} {@var{parent} =} ancestor (@var{h}, @var{type}, 'toplevel')
+Return the first ancestor of handle object @var{h} whose type matches
+ at var{type}, where @var{type} is a character string.  If @var{type} is a
+cell array of strings, return the first parent whose type matches
+any of the given type strings.
+
+If the handle object @var{h} is of type @var{type}, return @var{h}.
+
+If @code{"toplevel"} is given as a 3rd argument, return the highest
+parent in the object hierarchy that matches the condition, instead
+of the first (nearest) one.
+ at seealso{get, set}
+ at end deftypefn
+gtext
+ at c ./plot/gtext.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} gtext (@var{s})
+ at deftypefnx {Function File} {} gtext (@{@var{s1}; @var{s2}; @dots{}@})
+ at deftypefnx {Function File} {} gtext (@dots{}, @var{prop}, @var{val})
+Place text on the current figure using the mouse.  The text is defined
+by the string @var{s}.  If @var{s} is a cell array, each element of the cell
+array is written to a separate line.  Additional arguments are passed to
+the underlying text object as properties.
+ at seealso{ginput, text}
+ at end deftypefn
+spinmap
+ at c ./plot/spinmap.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spinmap (@var{t}, @var{inc})
+Cycle the colormap for @var{t} seconds with an increment
+of @var{inc}.  Both parameters are optional.  The default cycle time
+is 5 seconds and the default increment is 2.
+
+A higher value of @var{inc} causes a faster cycle through the
+colormap.
+ at seealso{gca, colorbar}
+ at end deftypefn
+__pltopt__
+ at c ./plot/__pltopt__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __pltopt__ (@var{caller}, @var{opt})
+Undocumented internal function.
+ at end deftypefn
+__errplot__
+ at c ./plot/__errplot__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{p}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+ishold
+ at c ./plot/ishold.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ishold
+Return true if the next line will be added to the current plot, or
+false if the plot device will be cleared before drawing the next line.
+ at end deftypefn
+diffuse
+ at c ./plot/diffuse.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} diffuse (@var{sx}, @var{sy}, @var{sz}, @var{l})
+Calculate diffuse reflection strength of a surface defined by the normal
+vector elements @var{sx}, @var{sy}, @var{sz}. 
+The light vector can be specified using parameter @var{L}.  It can be
+given as 2-element vector [azimuth, elevation] in degrees or as 3-element
+vector [lx, ly, lz]. 
+ at seealso{specular, surfl}
+ at end deftypefn
+__bars__
+ at c ./plot/__bars__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __bars__ (@var{ax}, @var{vertical}, @var{x}, @var{y}, @var{xb}, @var{yb}, @var{width}, @var{group}, @var{have_color_spec}, @var{base_value}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+semilogy
+ at c ./plot/semilogy.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} semilogy (@var{args})
+Produce a two-dimensional plot using a log scale for the @var{y}
+axis.  See the description of @code{plot} for a description of the
+arguments that @code{semilogy} will accept.
+ at seealso{plot, semilogx, loglog}
+ at end deftypefn
+figure
+ at c ./plot/figure.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} figure (@var{n})
+ at deftypefnx {Function File} {} figure (@var{n}, @var{property}, @var{value}, @dots{})
+Set the current plot window to plot window @var{n}.  If no arguments are
+specified, the next available window number is chosen.
+
+Multiple property-value pairs may be specified for the figure, but they
+must appear in pairs.
+ at end deftypefn
+stem3
+ at c ./plot/stem3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} stem3 (@var{x}, @var{y}, @var{z}, @var{linespec})
+Plot a three-dimensional stem graph and return the handles of the line
+and marker objects used to draw the stems as "stem series" object.
+The default color is @code{"r"} (red).  The default line style is
+ at code{"-"} and the default marker is @code{"o"}.
+
+For example,
+ at example
+ at group
+theta = 0:0.2:6; 
+stem3 (cos (theta), sin (theta), theta) 
+ at end group
+ at end example
+
+ at noindent
+plots 31 stems with heights from 0 to 6 lying on a circle.  Color 
+definitions with rgb-triples are not valid!
+ at seealso{bar, barh, stem, plot}
+ at end deftypefn
+__go_close_all__
+ at c ./plot/__go_close_all__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __go_close_all__ ()
+Undocumented internal function.
+ at end deftypefn
+zlabel
+ at c ./plot/zlabel.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} zlabel (@var{string})
+ at deftypefnx {Function File} {} zlabel (@var{h}, @var{string})
+ at seealso{xlabel}.
+ at end deftypefn
+__contour__
+ at c ./plot/__contour__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{c}, @var{hg}] =} __contour__ (@dots{})
+Undocumented internal function.
+ at end deftypefn
+print
+ at c ./plot/print.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} print ()
+ at deftypefnx {Function File} {} print (@var{options})
+ at deftypefnx {Function File} {} print (@var{filename}, @var{options})
+ at deftypefnx {Function File} {} print (@var{h}, @var{filename}, @var{options})
+Print a graph, or save it to a file
+
+ at var{filename} defines the file name of the output file.  If no
+filename is specified, the output is sent to the printer.
+
+ at var{h} specifies the figure handle.  If no handle is specified
+the handle for the current figure is used.
+
+ at var{options}:
+ at table @code
+ at item -P at var{printer}
+  Set the @var{printer} name to which the graph is sent if no
+ at var{filename} is specified.
+ at item -G at var{ghostscript_command}
+  Specify the command for calling Ghostscript.  For Unix and Windows,
+the defaults are 'gs' and 'gswin32c', respectively.
+ at item -color
+ at itemx -mono
+  Monochrome or color lines.
+ at item -solid
+ at itemx -dashed
+  Solid or dashed lines.
+ at item -portrait
+ at itemx -landscape
+  Specify the orientation of the plot for printed output.
+ at item -d at var{device}
+  Output device, where @var{device} is one of:
+ at table @code
+ at item ps
+ at itemx ps2
+ at itemx psc
+ at itemx psc2
+    Postscript (level 1 and 2, mono and color)
+ at item eps
+ at itemx eps2
+ at itemx epsc
+ at itemx epsc2
+    Encapsulated postscript (level 1 and 2, mono and color)
+ at item tex
+ at itemx epslatex
+ at itemx epslatexstandalone
+ at itemx pstex
+ at itemx pslatex
+    Generate a @LaTeX{} (or @TeX{}) file for labels, and eps/ps for
+graphics.  The file produced by @code{epslatexstandalone} can be
+processed directly by @LaTeX{}.  The other formats are intended to
+be included in a @LaTeX{} (or @TeX{}) document.  The @code{tex} device
+is the same as the @code{epslatex} device.
+ at item ill
+ at itemx aifm
+    Adobe Illustrator
+ at item cdr
+ at itemx corel
+    CorelDraw
+ at item dxf
+    AutoCAD
+ at item emf
+ at itemx meta
+    Microsoft Enhanced Metafile
+ at item fig
+    XFig.  If this format is selected the additional options
+ at code{-textspecial} or @code{-textnormal} can be used to control
+    whether the special flag should be set for the text in
+    the figure (default is @code{-textnormal}). 
+ at item hpgl
+    HP plotter language
+ at item mf
+    Metafont
+ at item png
+    Portable network graphics
+ at item jpg
+ at itemx jpeg
+    JPEG image
+ at item gif
+    GIF image
+ at item pbm
+    PBMplus
+ at item svg
+    Scalable vector graphics
+ at item pdf
+    Portable document format
+ at end table
+
+  If the device is omitted, it is inferred from the file extension,
+or if there is no filename it is sent to the printer as postscript.
+
+ at item -d at var{gs_device}
+  Additional devices are supported by Ghostscript.
+Some examples are;
+
+ at table @code
+ at item ljet2p 
+    HP LaserJet IIP
+ at item ljet3 
+    HP LaserJet III
+ at item deskjet
+    HP DeskJet and DeskJet Plus
+ at item cdj550
+    HP DeskJet 550C
+ at item paintjet
+    HP PointJet
+ at item pcx24b
+    24-bit color PCX file format
+ at item ppm
+    Portable Pixel Map file format
+ at end table
+
+  For a complete list, type `system ("gs -h")' to see what formats
+and devices are available.
+
+  When the ghostscript is sent to a printer the size is determined
+by the figure's "papersize" property.  When the ghostscript output 
+is sent to a file the size is determined by the figure's
+"paperposition" property.
+
+ at itemx -r at var{NUM}
+  Resolution of bitmaps in pixels per inch.  For both metafiles and 
+SVG the default is the screen resolution, for other it is 150 dpi.
+To specify screen resolution, use "-r0".
+
+ at item -tight
+  Forces a tight bounding box for eps-files.  Since the ghostscript
+devices are conversion of an eps-file, this option works the those
+devices as well.
+
+ at itemx -S at var{xsize}, at var{ysize}
+  Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG.  If
+using the command form of the print function, you must quote the
+ at var{xsize}, at var{ysize} option.  For example, by writing
+ at w{@code{"-S640,480"}}.  The size defaults to that specified by the
+figure's paperposition property.
+
+ at item -F at var{fontname}
+ at itemx -F at var{fontname}:@var{size}
+ at itemx -F:@var{size}
+ at var{fontname} set the postscript font (for use with postscript,
+aifm, corel and fig).  By default, 'Helvetica' is set for PS/Aifm,
+and 'SwitzerlandLight' for Corel.  It can also be 'Times-Roman'.
+ at var{size} is given in points.  @var{fontname} is ignored for the
+fig device.
+ at end table
+
+The filename and options can be given in any order.
+ at end deftypefn
+__ezplot__
+ at c ./plot/__ezplot__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{h}, @var{needusage}] =} __ezplot__ (@var{pfunc}, @var{varargin})
+Undocumented internal function.
+ at end deftypefn
+plotmatrix
+ at c ./plot/plotmatrix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} plotmatrix (@var{x}, @var{y})
+ at deftypefnx {Function File} {} plotmatrix (@var{x})
+ at deftypefnx {Function File} {} plotmatrix (@dots{}, @var{style})
+ at deftypefnx {Function File} {} plotmatrix (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{h}, @var{ax}, @var{bigax}, @var{p}, @var{pax}] =} plotmatrix (@dots{})
+Scatter plot of the columns of one matrix against another.  Given the
+arguments @var{x} and @var{y}, that have a matching number of rows,
+ at code{plotmatrix} plots a set of axes corresponding to
+
+ at example
+plot (@var{x} (:, i), @var{y} (:, j)
+ at end example
+
+Given a single argument @var{x}, then this is equivalent to 
+
+ at example
+plotmatrix (@var{x}, @var{x})
+ at end example
+
+ at noindent
+except that the diagonal of the set of axes will be replaced with the
+histogram @code{hist (@var{x} (:, i))}.
+
+The marker to use can be changed with the @var{style} argument, that is a 
+string defining a marker in the same manner as the @code{plot}
+command.  If a leading axes handle @var{h} is passed to
+ at code{plotmatrix}, then this axis will be used for the plot.
+
+The optional return value @var{h} provides handles to the individual
+graphics objects in the scatter plots, whereas @var{ax} returns the
+handles to the scatter plot axis objects.  @var{bigax} is a hidden
+axis object that surrounds the other axes, such that the commands 
+ at code{xlabel}, @code{title}, etc., will be associated with this hidden
+axis.  Finally @var{p} returns the graphics objects associated with
+the histogram and @var{pax} the corresponding axes objects.
+
+ at example
+ at group
+plotmatrix (randn (100, 3), 'g+')
+ at end group
+ at end example
+
+ at end deftypefn
+fill
+ at c ./plot/fill.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fill (@var{x}, @var{y}, @var{c})
+ at deftypefnx {Function File} {} fill (@var{x1}, @var{y1}, @var{c1}, @var{x2}, @var{y2}, @var{c2})
+ at deftypefnx {Function File} {} fill (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} fill (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} fill (@dots{})
+Create one or more filled patch objects, returning a patch object for each.
+ at end deftypefn
+cylinder
+ at c ./plot/cylinder.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cylinder
+ at deftypefnx {Function File} {} cylinder (@var{r})
+ at deftypefnx {Function File} {} cylinder (@var{r}, @var{n})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} cylinder (@dots{})
+ at deftypefnx {Function File} {} cylinder (@var{ax}, @dots{})
+Generates three matrices in @code{meshgrid} format, such that
+ at code{surf (@var{x}, @var{y}, @var{z})} generates a unit cylinder.
+The matrices are of size @code{@var{n}+1}-by- at code{@var{n}+1}. 
+ at var{r} is a vector containing the radius along the z-axis.
+If @var{n} or @var{r} are omitted then default values of 20 or [1 1]
+are assumed.
+
+Called with no return arguments, @code{cylinder} calls directly
+ at code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle @var{ax}
+is passed as the first argument, the surface is plotted to this set
+of axes.
+
+Examples:
+ at example
+ at group
+disp ("plotting a cone")
+[x, y, z] = cylinder (10:-1:0,50);
+surf (x, y, z);
+ at end group
+ at end example
+ at seealso{sphere}
+ at end deftypefn
+meshc
+ at c ./plot/meshc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} meshc (@var{x}, @var{y}, @var{z})
+Plot a mesh and contour given matrices @var{x}, and @var{y} from 
+ at code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+ at var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+columns of @var{z} correspond to different @var{x} values and rows of 
+ at var{z} correspond to different @var{y} values.
+ at seealso{meshgrid, mesh, contour}
+ at end deftypefn
+box
+ at c ./plot/box.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} box (@var{arg})
+ at deftypefnx {Function File} {} box (@var{h}, @dots{})
+Control the display of a border around the plot.
+The argument may be either @code{"on"} or @code{"off"}.  If it is
+omitted, the current box state is toggled.
+ at seealso{grid}
+ at end deftypefn
+gcbf
+ at c ./plot/gcbf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{fig} =} gcbf ()
+Return a handle to the figure containing the object whose callback
+is currently executing.  If no callback is executing, this function
+returns the empty matrix.  The handle returned by this function is
+the same as the second output argument of gcbo.
+
+ at seealso{gcf, gca, gcbo}
+ at end deftypefn
+compass
+ at c ./plot/compass.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} compass (@var{u}, @var{v})
+ at deftypefnx {Function File} {} compass (@var{z})
+ at deftypefnx {Function File} {} compass (@dots{}, @var{style})
+ at deftypefnx {Function File} {} compass (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} compass (@dots{})
+
+Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
+from the origin of a polar plot.  If a single complex argument @var{z} is 
+given, then @code{@var{u} = real (@var{z})} and @code{@var{v} = imag 
+(@var{z})}.
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+
+The optional return value @var{h} provides a list of handles to the 
+the parts of the vector field (body, arrow and marker).
+
+ at example
+ at group
+a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+compass (eig (a))
+ at end group
+ at end example
+
+ at seealso{plot, polar, quiver, feather}
+ at end deftypefn
+loglog
+ at c ./plot/loglog.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} loglog (@var{args})
+Produce a two-dimensional plot using log scales for both axes.  See
+the description of @code{plot} for a description of the arguments
+that @code{loglog} will accept.
+ at seealso{plot, semilogx, semilogy}
+ at end deftypefn
+meshgrid
+ at c ./plot/meshgrid.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{xx}, @var{yy}, @var{zz}] =} meshgrid (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {[@var{xx}, @var{yy}] =} meshgrid (@var{x}, @var{y})
+ at deftypefnx {Function File} {[@var{xx}, @var{yy}] =} meshgrid (@var{x})
+Given vectors of @var{x} and @var{y} and @var{z} coordinates, and
+returning 3 arguments, return three-dimensional arrays corresponding
+to the @var{x}, @var{y}, and @var{z} coordinates of a mesh.  When
+returning only 2 arguments, return matrices corresponding to the
+ at var{x} and @var{y} coordinates of a mesh.  The rows of @var{xx} are
+copies of @var{x}, and the columns of @var{yy} are copies of @var{y}.
+If @var{y} is omitted, then it is assumed to be the same as @var{x},
+and @var{z} is assumed the same as @var{y}.
+ at seealso{mesh, contour}
+ at end deftypefn
+ndgrid
+ at c ./plot/ndgrid.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{y1}, @var{y2}, @dots{},  @var{y}n] =} ndgrid (@var{x1}, @var{x2}, @dots{}, @var{x}n)
+ at deftypefnx {Function File} {[@var{y1}, @var{y2}, @dots{},  @var{y}n] =} ndgrid (@var{x})
+Given n vectors @var{x1}, @dots{} @var{x}n, @code{ndgrid} returns
+n arrays of dimension n. The elements of the i-th output argument
+contains the elements of the vector @var{x}i repeated over all
+dimensions different from the i-th dimension.  Calling ndgrid with
+only one input argument @var{x} is equivalent of calling ndgrid with
+all n input arguments equal to @var{x}:
+
+[@var{y1}, @var{y2}, @dots{},  @var{y}n] = ndgrid (@var{x}, @dots{}, @var{x})
+ at seealso{meshgrid}
+ at end deftypefn
+hist
+ at c ./plot/hist.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hist (@var{y}, @var{x}, @var{norm})
+Produce histogram counts or plots.
+
+With one vector input argument, plot a histogram of the values with
+10 bins.  The range of the histogram bins is determined by the range
+of the data.  With one matrix input argument, plot a histogram where
+each bin contains a bar per input column.
+
+Given a second scalar argument, use that as the number of bins.
+
+Given a second vector argument, use that as the centers of the bins,
+with the width of the bins determined from the adjacent values in
+the vector.
+
+If third argument is provided, the histogram is normalized such that
+the sum of the bars is equal to @var{norm}.
+
+Extreme values are lumped in the first and last bins.
+
+With two output arguments, produce the values @var{nn} and @var{xx} such
+that @code{bar (@var{xx}, @var{nn})} will plot the histogram.
+ at seealso{bar}
+ at end deftypefn
+errorbar
+ at c ./plot/errorbar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} errorbar (@var{args})
+This function produces two-dimensional plots with errorbars.  Many
+different combinations of arguments are possible.  The simplest form is
+
+ at example
+errorbar (@var{y}, @var{ey})
+ at end example
+
+ at noindent
+where the first argument is taken as the set of @var{y} coordinates
+and the second argument @var{ey} is taken as the errors of the
+ at var{y} values.  @var{x} coordinates are taken to be the indices
+of the elements, starting with 1.
+
+If more than two arguments are given, they are interpreted as
+
+ at example
+errorbar (@var{x}, @var{y}, @dots{}, @var{fmt}, @dots{})
+ at end example
+
+ at noindent
+where after @var{x} and @var{y} there can be up to four error
+parameters such as @var{ey}, @var{ex}, @var{ly}, @var{uy}, etc.,
+depending on the plot type.  Any number of argument sets may appear,
+as long as they are separated with a format string @var{fmt}.
+
+If @var{y} is a matrix, @var{x} and error parameters must also be matrices
+having same dimensions.  The columns of @var{y} are plotted versus the
+corresponding columns of @var{x} and errorbars are drawn from
+the corresponding columns of error parameters.
+
+If @var{fmt} is missing, yerrorbars ("~") plot style is assumed.
+
+If the @var{fmt} argument is supplied, it is interpreted as in
+normal plots.  In addition the following plot styles are supported by
+errorbar:
+
+ at table @samp
+ at item ~
+Set yerrorbars plot style (default).
+
+ at item >
+Set xerrorbars plot style.
+
+ at item ~>
+Set xyerrorbars plot style.
+
+ at item #
+Set boxes plot style.
+
+ at item #~
+Set boxerrorbars plot style.
+
+ at item #~>
+Set boxxyerrorbars plot style.
+ at end table
+
+Examples:
+
+ at example
+errorbar (@var{x}, @var{y}, @var{ex}, ">")
+ at end example
+
+produces an xerrorbar plot of @var{y} versus @var{x} with @var{x}
+errorbars drawn from @var{x}- at var{ex} to @var{x}+ at var{ex}.
+
+ at example
+ at group
+errorbar (@var{x}, @var{y1}, @var{ey}, "~",
+          @var{x}, @var{y2}, @var{ly}, @var{uy})
+ at end group
+ at end example
+
+produces yerrorbar plots with @var{y1} and @var{y2} versus @var{x}.
+Errorbars for @var{y1} are drawn from @var{y1}- at var{ey} to
+ at var{y1}+ at var{ey}, errorbars for @var{y2} from @var{y2}- at var{ly} to
+ at var{y2}+ at var{uy}.
+
+ at example
+ at group
+errorbar (@var{x}, @var{y}, @var{lx}, @var{ux},
+          @var{ly}, @var{uy}, "~>")
+ at end group
+ at end example
+
+produces an xyerrorbar plot of @var{y} versus @var{x} in which
+ at var{x} errorbars are drawn from @var{x}- at var{lx} to @var{x}+ at var{ux}
+and @var{y} errorbars from @var{y}- at var{ly} to @var{y}+ at var{uy}.
+ at seealso{semilogxerr, semilogyerr, loglogerr}
+ at end deftypefn
+__plt2mv__
+ at c ./plot/__plt2mv__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2mv__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+__plt2vs__
+ at c ./plot/__plt2vs__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2vs__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+zlim
+ at c ./plot/zlim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{xl} =} zlim ()
+ at deftypefnx {Function File} {} zlim (@var{xl})
+ at deftypefnx {Function File} {@var{m} =} zlim ('mode')
+ at deftypefnx {Function File} {} zlim (@var{m})
+ at deftypefnx {Function File} {} zlim (@var{h}, @dots{})
+Get or set the limits of the z-axis of the current plot.  Called without
+arguments @code{zlim} returns the z-axis limits of the current plot.
+If passed a two element vector @var{xl}, the limits of the z-axis are set
+to this value.
+
+The current mode for calculation of the z-axis can be returned with a
+call @code{zlim ('mode')}, and can be either 'auto' or 'manual'.  The 
+current plotting mode can be set by passing either 'auto' or 'manual' 
+as the argument.
+
+If passed an handle as the first argument, then operate on this handle
+rather than the current axes handle.
+ at seealso{xlim, ylim, set, get, gca}
+ at end deftypefn
+ishghandle
+ at c ./plot/ishghandle.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ishghandle (@var{h})
+Return true if @var{h} is a graphics handle and false otherwise.
+ at end deftypefn
+contour3
+ at c ./plot/contour3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} contour3 (@var{z})
+ at deftypefnx {Function File} {} contour3 (@var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour3 (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {} contour3 (@var{x}, @var{y}, @var{z}, @var{vn})
+ at deftypefnx {Function File} {} contour3 (@dots{}, @var{style})
+ at deftypefnx {Function File} {} contour3 (@var{h}, @dots{})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contour3 (@dots{})
+Plot level curves (contour lines) of the matrix @var{z}, using the
+contour matrix @var{c} computed by @code{contourc} from the same
+arguments; see the latter for their interpretation.  The contours are
+plotted at the Z level corresponding to their contour.  The set of
+contour levels, @var{c}, is only returned if requested.  For example:
+
+ at example
+ at group
+contour3 (peaks (19));
+hold on
+surface (peaks (19), "facecolor", "none", "EdgeColor", "black")
+colormap hot
+ at end group
+ at end example
+
+The style to use for the plot can be defined with a line style @var{style}
+in a similar manner to the line styles used with the @code{plot} command.
+Any markers defined by @var{style} are ignored.
+
+The optional input and output argument @var{h} allows an axis handle to 
+be passed to @code{contour} and the handles to the contour objects to be
+returned.
+ at seealso{contourc, patch, plot}
+ at end deftypefn
+stairs
+ at c ./plot/stairs.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} stairs (@var{x}, @var{y})
+ at deftypefnx {Function File} {} stairs (@dots{}, @var{style})
+ at deftypefnx {Function File} {} stairs (@dots{}, @var{prop}, @var{val})
+ at deftypefnx {Function File} {} stairs (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} stairs (@dots{})
+Produce a stairstep plot.  The arguments may be vectors or matrices.
+
+If only one argument is given, it is taken as a vector of y-values
+and the x coordinates are taken to be the indices of the elements.
+
+If two output arguments are specified, the data are generated but
+not plotted.  For example,
+
+ at example
+stairs (x, y);
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+[xs, ys] = stairs (x, y);
+plot (xs, ys);
+ at end group
+ at end example
+
+ at noindent
+are equivalent.
+ at seealso{plot, semilogx, semilogy, loglog, polar, mesh, contour,
+bar, xlabel, ylabel, title}
+ at end deftypefn
+__pltopt1__
+ at c ./plot/__pltopt1__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{options}, @var{valid}] =} __pltopt1__ (@var{caller}, @var{opt}, @var{err_on_invalid})
+Undocumented internal function.
+ at end deftypefn
+close
+ at c ./plot/close.m
+-*- texinfo -*-
+ at deftypefn {Command} {} close
+ at deftypefnx {Command} {} close (@var{n})
+ at deftypefnx {Command} {} close all
+ at deftypefnx {Command} {} close all hidden
+Close figure window(s) by calling the function specified by the
+ at code{"closerequestfcn"} property for each figure.  By default, the
+function @code{closereq} is used.
+ at seealso{closereq}
+ at end deftypefn
+axes
+ at c ./plot/axes.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} axes ()
+ at deftypefnx {Function File} {} axes (@var{property}, @var{value}, @dots{})
+ at deftypefnx {Function File} {} axes (@var{h})
+Create an axes object and return a handle to it.
+ at end deftypefn
+colorbar
+ at c ./plot/colorbar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} colorbar (@var{s})
+ at deftypefnx {Function File} {} colorbar ("peer", @var{h}, @dots{})
+Adds a colorbar to the current axes.  Valid values for @var{s} are
+
+ at table @asis
+ at item "EastOutside"
+Place the colorbar outside the plot to the right.  This is the default.
+ at item "East"
+Place the colorbar inside the plot to the right.
+ at item "WestOutside"
+Place the colorbar outside the plot to the left.
+ at item "West"
+Place the colorbar inside the plot to the left.
+ at item "NorthOutside"
+Place the colorbar above the plot.
+ at item "North"
+Place the colorbar at the top of the plot.
+ at item "SouthOutside"
+Place the colorbar under the plot.
+ at item "South"
+Place the colorbar at the bottom of the plot.
+ at item "Off", "None"
+Remove any existing colorbar from the plot.
+ at end table
+
+If the argument "peer" is given, then the following argument is treated
+as the axes handle on which to add the colorbar.
+ at end deftypefn
+shading
+ at c ./plot/shading.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} shading (@var{type})
+ at deftypefnx {Function File} {} shading (@var{ax}, @dots{})
+Set the shading of surface or patch graphic objects.  Valid arguments
+for @var{type} are
+
+ at table @code
+ at item "flat"
+Single colored patches with invisible edges.
+
+ at item "faceted"
+Single colored patches with visible edges.
+
+ at item "interp"
+Color between patch vertices are interpolated and the patch edges are
+invisible.
+ at end table
+
+If @var{ax} is given the shading is applied to axis @var{ax} instead
+of the current axis.
+ at end deftypefn
+contourf
+ at c ./plot/contourf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z}, @var{lvl})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z}, @var{n})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z}, @var{n})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z}, @var{lvl})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{ax}, @dots{})
+ at deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@dots{}, @var{"property"}, @var{val})
+Compute and plot filled contours of the matrix @var{z}.
+Parameters @var{x}, @var{y} and @var{n} or @var{lvl} are optional.
+
+The return value @var{c} is a 2xn matrix containing the contour lines
+as described in the help to the contourc function.
+
+The return value @var{h} is handle-vector to the patch objects creating
+the filled contours.
+
+If @var{x} and @var{y} are omitted they are taken as the row/column
+index of @var{z}.  @var{n} is a scalar denoting the number of lines
+to compute.  Alternatively @var{lvl} is a vector containing the
+contour levels.  If only one value (e.g., lvl0) is wanted, set
+ at var{lvl} to [lvl0, lvl0].  If both @var{n} or @var{lvl} are omitted
+a default value of 10 contour level is assumed.
+
+If provided, the filled contours are added to the axes object
+ at var{ax} instead of the current axis.
+
+The following example plots filled contours of the @code{peaks}
+function.
+ at example
+ at group
+[x, y, z] = peaks (50);
+contourf (x, y, z, -7:9)
+ at end group
+ at end example
+ at seealso{contour, contourc, patch}
+ at end deftypefn
+__plr1__
+ at c ./plot/__plr1__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plr1__ (@var{h}, @var{theta}, @var{fmt})
+Undocumented internal function.
+ at end deftypefn
+__plt2vm__
+ at c ./plot/__plt2vm__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt2vm__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+__line__
+ at c ./plot/__line__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{h} =} __line__ (@var{p}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+replot
+ at c ./plot/replot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} replot ()
+Refresh the plot window.
+ at end deftypefn
+__plt1__
+ at c ./plot/__plt1__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __plt1__ (@var{h}, @var{x1}, @var{options}, @var{properties})
+Undocumented internal function.
+ at end deftypefn
+hold
+ at c ./plot/hold.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} hold
+ at deftypefnx {Function File} {} hold @var{state}
+ at deftypefnx {Function File} {} hold (@var{hax}, @dots{})
+Toggle or set the 'hold' state of the plotting engine which determines
+whether new graphic objects are added to the plot or replace the existing
+objects.  
+
+ at table @code
+ at item hold on
+Retain plot data and settings so that subsequent plot commands are displayed
+on a single graph.
+
+ at item hold off
+Clear plot and restore default graphics settings before each new plot
+command.  (default).
+
+ at item hold
+Toggle the current 'hold' state.
+ at end table
+
+When given the additional argument @var{hax}, the hold state is modified
+only for the given axis handle.
+
+To query the current 'hold' state use the @code{ishold} function.
+ at seealso{ishold, cla, newplot, clf}
+ at end deftypefn
+slice
+ at c ./plot/slice.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} slice (@var{x}, @var{y}, @var{z}, @var{v}, @var{sx}, @var{sy}, @var{sz})
+ at deftypefnx {Function File} {} slice (@var{x}, @var{y}, @var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {} slice (@var{v}, @var{sx}, @var{sy}, @var{sz})
+ at deftypefnx {Function File} {} slice (@var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {@var{h} =} slice (@dots{})
+ at deftypefnx {Function File} {@var{h} =} slice (@dots{}, @var{method})
+Plot slices of 3D data/scalar fields.  Each element of the 3-dimensional 
+array @var{v} represents a scalar value at a location given by the
+parameters @var{x}, @var{y}, and @var{z}.  The parameters @var{x},
+ at var{x}, and @var{z} are either 3-dimensional arrays of the same size
+as the array @var{v} in the "meshgrid" format or vectors.  The
+parameters @var{xi}, etc. respect a similar format to @var{x}, etc.,
+and they represent the points at which the array @var{vi} is
+interpolated using interp3.  The vectors @var{sx}, @var{sy}, and
+ at var{sz} contain points of orthogonal slices of the respective axes.
+
+If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be 
+ at code{x = 1:size (@var{v}, 2)}, @code{y = 1:size (@var{v}, 1)} and
+ at code{z = 1:size (@var{v}, 3)}. 
+
+ at var{Method} is one of:
+
+ at table @code
+ at item "nearest"
+Return the nearest neighbor.
+ at item "linear"
+Linear interpolation from nearest neighbors.
+ at item "cubic"
+Cubic interpolation from four nearest neighbors (not implemented yet).
+ at item "spline"
+Cubic spline interpolation---smooth first and second derivatives
+throughout the curve.
+ at end table
+
+The default method is @code{"linear"}.
+The optional return value @var{h} is a vector of handles to the
+surface graphic objects.
+
+Examples:
+ at example
+ at group
+[x, y, z] = meshgrid (linspace (-8, 8, 32));
+v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+slice (x, y, z, v, [], 0, []);
+[xi, yi] = meshgrid (linspace (-7, 7));
+zi = xi + yi;
+slice (x, y, z, v, xi, yi, zi);
+ at end group
+ at end example
+ at seealso{interp3, surface, pcolor}
+ at end deftypefn
+linkprop
+ at c ./plot/linkprop.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{hlink} =} linkprop (@var{h}, @var{prop})
+Links graphics object properties, such that a change in one is
+propagated to the others.  The properties to link are given as a
+string of cell string array by @var{prop} and the objects containing
+these properties by the handle array @var{h}.
+
+An example of the use of linkprops is
+
+ at example
+ at group
+x = 0:0.1:10;
+subplot (1, 2, 1);
+h1 = plot (x, sin (x));
+subplot (1, 2, 2);
+h2 = plot (x, cos (x));
+hlink = linkprop ([h1, h2], @{"color","linestyle"@});
+set (h1, "color", "green");
+set (h2, "linestyle", "--");
+ at end group
+ at end example
+
+ at end deftypefn
+unpack
+ at c ./miscellaneous/unpack.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{files} =} unpack (@var{file}, @var{dir})
+ at deftypefnx {Function File} {@var{files} =} unpack (@var{file}, @var{dir}, @var{filetype})
+Unpack the archive @var{file} based on its extension to the directory
+ at var{dir}.  If @var{file} is a cellstr, then all files will be
+handled individually.  If @var{dir} is not specified, it defaults to
+the current directory.  It returns a list of @var{files}
+unpacked.  If a directory is in the file list, then the
+ at var{filetype} to unpack must also be specified.
+
+The @var{files} includes the entire path to the output files.
+ at seealso{bunzip2, tar, untar, gzip, gunzip, zip, unzip}
+ at end deftypefn
+orderfields
+ at c ./miscellaneous/orderfields.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2})
+Return a struct with fields arranged alphabetically or as specified
+by @var{s2} and a corresponding permutation vector.
+
+Given one struct, arrange field names in @var{s1} alphabetically.
+
+Given two structs, arrange field names in @var{s1} as they appear
+in @var{s2}.  The second argument may also specify the order in
+a permutation vector or a cell array of strings.
+
+ at seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
+ at end deftypefn
+movefile
+ at c ./miscellaneous/movefile.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@var{f1}, @var{f2})
+Move the file @var{f1} to the new name @var{f2}.  The name @var{f1}
+may contain globbing patterns.  If @var{f1} expands to multiple file
+names, @var{f2} must be a directory.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique\n\
+message identifier.\n\
+ at seealso{glob}
+ at end deftypefn
+tempname
+ at c ./miscellaneous/tempname.m
+-*- texinfo -*-
+ at deftypefn {Function File} {filename =} tempname ()
+This function is an alias for @code{tmpnam}.
+ at end deftypefn
+unzip
+ at c ./miscellaneous/unzip.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unzip (@var{zipfile}, @var{dir})
+Unpack the ZIP archive @var{zipfile} to the directory @var{dir}.
+If @var{dir} is not specified, it defaults to the current directory.
+ at seealso{unpack, bunzip2, tar, untar, gzip, gunzip, zip}
+ at end deftypefn
+perl
+ at c ./miscellaneous/perl.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{output}, @var{status}] =} perl (@var{scriptfile})
+ at deftypefnx {Function File} {[@var{output}, @var{status}] =} perl (@var{scriptfile}, @var{argument1}, @var{argument2}, @dots{})
+Invoke perl script @var{scriptfile} with possibly a list of
+command line arguments.
+Returns output in @var{output} and status
+in @var{status}.
+ at seealso{system}
+ at end deftypefn
+ispc
+ at c ./miscellaneous/ispc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ispc ()
+Return 1 if Octave is running on a Windows system and 0 otherwise.
+ at seealso{ismac, isunix}
+ at end deftypefn
+debug
+ at c ./miscellaneous/debug.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} debug ()
+Summary of the debugging commands.  The debugging commands that are
+available in Octave are
+
+ at table @code
+ at item keyboard
+Force entry into debug mode.
+
+ at item dbstop
+Add a breakpoint.
+
+ at item dbclear
+Remove a breakpoint.
+
+ at item dbstatus
+List all breakpoints.
+
+ at item dbcont
+Continue execution from the debug prompt.
+
+ at item dbstack
+Print a backtrace of the execution stack.
+
+ at item dbstep
+Execute one or more lines and re-enter debug mode
+
+ at item dbtype
+List the function where execution is currently stopped, enumerating
+the lines.
+
+ at item dbup
+The workspace up the execution stack.
+
+ at item dbdown
+The workspace down the execution stack.
+
+ at item dbquit
+Quit debugging mode and return to the main prompt.
+
+ at item debug_on_error
+Flag whether to enter debug mode in case Octave encounters an error.
+
+ at item debug_on_warning
+Flag whether to enter debug mode in case Octave encounters a warning.
+
+ at item debug_on_interrupt
+Flag whether to enter debug mode in case Octave encounters an interupt.
+
+ at end table
+
+ at noindent
+when Octave encounters a breakpoint or other reason to enter debug
+mode, the prompt changes to @code{"debug>"}.  The workspace of the function
+where the breakpoint was encountered becomes available and any Octave
+command that works within that workspace may be executed.
+
+ at seealso{dbstop, dbclear, dbstatus, dbcont, dbstack, dbstep, dbtype,
+dbup, dbdown, dbquit, debug_on_error, debug_on_warning,
+debug_on_interrupt}
+ at end deftypefn
+tar
+ at c ./miscellaneous/tar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{entries} =} tar (@var{tarfile}, @var{files}, @var{root})
+Pack @var{files} @var{files} into the TAR archive @var{tarfile}.  The
+list of files must be a string or a cell array of strings.
+
+The optional argument @var{root} changes the relative path of @var{files}
+from the current directory.
+
+If an output argument is requested the entries in the archive are
+returned in a cell array.
+ at seealso{untar, gzip, gunzip, zip, unzip}
+ at end deftypefn
+warning_ids
+ at c ./miscellaneous/warning_ids.m
+-*- texinfo -*-
+ at table @code
+ at item Octave:array-to-scalar
+If the @code{Octave:array-to-scalar} warning is enabled, Octave will
+warn when an implicit conversion from an array to a scalar value is
+attempted.  By default, the @code{Octave:array-to-scalar} warning is
+disabled.
+
+ at item Octave:array-to-vector
+If the @code{Octave:array-to-vector} warning is enabled, Octave will
+warn when an implicit conversion from an array to a vector value is
+attempted.  By default, the @code{Octave:array-to-vector} warning is
+disabled.
+
+ at item Octave:assign-as-truth-value
+If the @code{Octave:assign-as-truth-value} warning is
+enabled, a warning is issued for statements like
+
+ at example
+ at group
+if (s = t)
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+since such statements are not common, and it is likely that the intent
+was to write
+
+ at example
+ at group
+if (s == t)
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+instead.
+
+There are times when it is useful to write code that contains
+assignments within the condition of a @code{while} or @code{if}
+statement.  For example, statements like
+
+ at example
+ at group
+while (c = getc())
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+are common in C programming.
+
+It is possible to avoid all warnings about such statements by
+disabling the @code{Octave:assign-as-truth-value} warning,
+but that may also let real errors like
+
+ at example
+ at group
+if (x = 1)  # intended to test (x == 1)!
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+slip by.
+
+In such cases, it is possible suppress errors for specific statements by
+writing them with an extra set of parentheses.  For example, writing the
+previous example as
+
+ at example
+ at group
+while ((c = getc()))
+  @dots{}
+ at end group
+ at end example
+
+ at noindent
+will prevent the warning from being printed for this statement, while
+allowing Octave to warn about other assignments used in conditional
+contexts.
+
+By default, the @code{Octave:assign-as-truth-value} warning is enabled.
+
+ at item Octave:associativity-change
+If the @code{Octave:associativity-change} warning is
+enabled, Octave will warn about possible changes in the meaning of
+some code due to changes in associativity for some operators.
+Associativity changes have typically been made for @sc{matlab}
+compatibility.  By default, the @code{Octave:associativity-change}
+warning is enabled.
+
+ at item Octave:divide-by-zero
+If the @code{Octave:divide-by-zero} warning is enabled, a
+warning is issued when Octave encounters a division by zero.  By
+default, the @code{Octave:divide-by-zero} warning is enabled.
+
+ at item Octave:empty-list-elements
+If the @code{Octave:empty-list-elements} warning is enabled, a
+warning is issued when an empty matrix is found in a matrix list.
+For example,
+
+ at example
+a = [1, [], 3, [], 5]
+ at end example
+
+ at noindent
+By default, the @code{Octave:empty-list-elements} warning is enabled.
+
+ at item Octave:fortran-indexing
+If the @code{Octave:fortran-indexing} warning is enabled, a warning is
+printed for expressions which select elements of a two-dimensional matrix
+using a single index.  By default, the @code{Octave:fortran-indexing}
+warning is disabled.
+
+ at item Octave:function-name-clash
+If the @code{Octave:function-name-clash} warning is enabled, a
+warning is issued when Octave finds that the name of a function
+defined in a function file differs from the name of the file.  (If
+the names disagree, the name declared inside the file is ignored.)
+By default, the @code{Octave:function-name-clash} warning is enabled.
+
+ at item Octave:future-time-stamp
+If the @code{Octave:future-time-stamp} warning is enabled, Octave
+will print a warning if it finds a function file with a time stamp
+that is in the future.  By default, the
+ at code{Octave:future-time-stamp} warning is enabled.
+
+ at item Octave:imag-to-real
+If the @code{Octave:imag-to-real} warning is enabled, a warning is
+printed for implicit conversions of complex numbers to real numbers.
+By default, the @code{Octave:imag-to-real} warning is disabled.
+
+ at item Octave:matlab-incompatible
+Print warnings for Octave language features that may cause
+compatibility problems with @sc{matlab}.
+
+ at item Octave:missing-semicolon
+If the @code{Octave:missing-semicolon} warning is enabled, Octave
+will warn when statements in function definitions don't end in
+semicolons.  By default the @code{Octave:missing-semicolon} warning
+is disabled.
+
+ at item Octave:neg-dim-as-zero
+If the @code{Octave:neg-dim-as-zero} warning is enabled, print a warning
+for expressions like
+
+ at example
+eye (-1)
+ at end example
+
+ at noindent
+By default, the @code{Octave:neg-dim-as-zero} warning is disabled.
+
+ at item Octave:num-to-str
+If the @code{Octave:num-to-str} warning is enable, a warning is
+printed for implicit conversions of numbers to their ASCII character
+equivalents when strings are constructed using a mixture of strings and
+numbers in matrix notation.  For example,
+
+ at example
+ at group
+[ "f", 111, 111 ]
+     @result{} "foo"
+ at end group
+ at end example
+elicits a warning if the @code{Octave:num-to-str} warning is
+enabled.  By default, the @code{Octave:num-to-str} warning is enabled.
+
+ at item Octave:precedence-change
+If the @code{Octave:precedence-change} warning is enabled, Octave
+will warn about possible changes in the meaning of some code due to
+changes in precedence for some operators.  Precedence changes have
+typically been made for @sc{matlab} compatibility.  By default, the
+ at code{Octave:precedence-change} warning is enabled.
+
+ at item Octave:reload-forces-clear
+If several functions have been loaded from the same file, Octave must
+clear all the functions before any one of them can be reloaded.  If
+the @code{Octave:reload-forces-clear} warning is enabled, Octave will
+warn you when this happens, and print a list of the additional
+functions that it is forced to clear.  By default, the
+ at code{Octave:reload-forces-clear} warning is enabled.
+
+ at item Octave:resize-on-range-error
+If the @code{Octave:resize-on-range-error} warning is enabled, print a
+warning when a matrix is resized by an indexed assignment with
+indices outside the current bounds.  By default, the
+ at code{Octave:resize-on-range-error} warning is disabled.
+
+ at item Octave:separator-insert
+Print warning if commas or semicolons might be inserted
+automatically in literal matrices.
+
+ at item Octave:single-quote-string
+Print warning if a single quote character is used to introduce a
+string constant.
+
+ at item Octave:str-to-num
+If the @code{Octave:str-to-num} warning is enabled, a warning is printed
+for implicit conversions of strings to their numeric ASCII equivalents.
+For example,
+ at example
+ at group
+"abc" + 0
+     @result{} 97 98 99
+ at end group
+ at end example
+elicits a warning if the @code{Octave:str-to-num} warning is enabled.
+By default, the @code{Octave:str-to-num} warning is disabled.
+
+ at item Octave:string-concat
+If the @code{Octave:string-concat} warning is enabled, print a
+warning when concatenating a mixture of double and single quoted strings.
+By default, the @code{Octave:string-concat} warning is disabled.
+
+ at item Octave:undefined-return-values
+If the @code{Octave:undefined-return-values} warning is disabled,
+print a warning if a function does not define all the values in
+the return list which are expected.  By default, the
+ at code{Octave:undefined-return-values} warning is enabled.
+
+ at item Octave:variable-switch-label
+If the @code{Octave:variable-switch-label} warning is enabled, Octave
+will print a warning if a switch label is not a constant or constant
+expression.  By default, the @code{Octave:variable-switch-label}
+warning is disabled.
+ at end table
+dir
+ at c ./miscellaneous/dir.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dir (@var{directory})
+ at deftypefnx {Function File} {[@var{list}] =} dir (@var{directory})
+Display file listing for directory @var{directory}.  If a return
+value is requested, return a structure array with the fields
+
+ at example
+ at group
+name
+bytes
+date
+isdir
+statinfo
+ at end group
+ at end example
+
+ at noindent
+in which @code{statinfo} is the structure returned from @code{stat}.
+
+If @var{directory} is not a directory, return information about the
+named @var{filename}.  @var{directory} may be a list of directories
+specified either by name or with wildcard characters (like * and ?)
+which will be expanded with glob.
+
+Note that for symbolic links, @code{dir} returns information about
+the file that a symbolic link points to instead of the link itself.
+However, if the link points to a nonexistent file, @code{dir} returns
+information about the link.
+ at seealso{ls, stat, lstat, readdir, glob, filesep}
+ at end deftypefn
+license
+ at c ./miscellaneous/license.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} license
+Display the license of Octave.
+
+ at deftypefnx {Function File} {} license ("inuse")
+Display a list of packages currently being used.
+
+ at deftypefnx {Function File} {@var{retval} =} license ("inuse")
+Return a structure containing the fields @code{feature} and @code{user}.
+
+ at deftypefnx {Function File} {@var{retval} =} license ("test", @var{feature})
+Return 1 if a license exists for the product identified by the string
+ at var{feature} and 0 otherwise.  The argument @var{feature} is case
+insensitive and only the first 27 characters are checked.
+
+ at deftypefnx {Function File} {} license ("test", @var{feature}, @var{toggle})
+Enable or disable license testing for @var{feature}, depending on
+ at var{toggle}, which may be one of:
+
+ at table @samp
+ at item "enable"
+Future tests for the specified license of @var{feature} are conducted
+as usual.
+ at item "disable"
+Future tests for the specified license of @var{feature} return 0.
+ at end table
+
+ at deftypefnx {Function File} {@var{retval} =} license ("checkout", @var{feature})
+Check out a license for @var{feature}, returning 1 on success and 0
+on failure.
+
+This function is provided for compatibility with @sc{matlab}.
+ at seealso{ver, version}
+ at end deftypefn
+xor
+ at c ./miscellaneous/xor.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} xor (@var{x}, @var{y})
+Return the `exclusive or' of the entries of @var{x} and @var{y}.
+For boolean expressions @var{x} and @var{y},
+ at code{xor (@var{x}, @var{y})} is true if and only if @var{x} or @var{y}
+is true, but not if both @var{x} and @var{y} are true.
+ at end deftypefn
+menu
+ at c ./miscellaneous/menu.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} menu (@var{title}, @var{opt1}, @dots{})
+Print a title string followed by a series of options.  Each option will
+be printed along with a number.  The return value is the number of the
+option selected by the user.  This function is useful for interactive
+programs.  There is no limit to the number of options that may be passed
+in, but it may be confusing to present more than will fit easily on one
+screen.
+ at seealso{disp, printf, input}
+ at end deftypefn
+__xzip__
+ at c ./miscellaneous/__xzip__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{entries} =} __xzip__ (@var{commandname}, @var{extension}, @var{commandtemplate}, @var{files}, @var{outdir})
+Undocumented internal function.
+ at end deftypefn
+compare_versions
+ at c ./miscellaneous/compare_versions.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} compare_versions (@var{v1}, @var{v2}, @var{operator})
+Compares to version strings using the given @var{operator}.
+
+This function assumes that versions @var{v1} and @var{v2} are
+arbitrarily long strings made of numeric and period characters
+possibly followed by an arbitrary string (e.g., "1.2.3", "0.3",
+"0.1.2+", or "1.2.3.4-test1").
+
+The version is first split into the numeric and the character parts
+then the parts are padded to be the same length (i.e., "1.1" would be
+padded to be like "1.1.0" when being compared with "1.1.1", and
+separately, the character parts of the strings are padded with
+nulls).
+
+The operator can be any logical operator from the set
+
+ at itemize @bullet
+ at item
+"=="
+equal
+ at item
+"<"
+less than
+ at item
+"<="
+less than or equal to
+ at item
+">"
+greater than
+ at item
+">="
+greater than or equal to
+ at item
+"!="
+not equal
+ at item
+"~="
+not equal
+ at end itemize
+
+Note that version "1.1-test2" would compare as greater than
+"1.1-test10".  Also, since the numeric part is compared first, "a"
+compares less than "1a" because the second string starts with a
+numeric part even though double("a") is greater than double("1").
+ at end deftypefn
+bincoeff
+ at c ./miscellaneous/bincoeff.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} bincoeff (@var{n}, @var{k})
+Return the binomial coefficient of @var{n} and @var{k}, defined as
+ at tex
+$$
+ {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+ /   \
+ | n |    n (n-1) (n-2) @dots{} (n-k+1)
+ |   |  = -------------------------
+ | k |               k!
+ \   /
+ at end group
+ at end example
+ at end ifnottex
+
+For example,
+
+ at example
+ at group
+bincoeff (5, 2)
+     @result{} 10
+ at end group
+ at end example
+
+In most cases, the @code{nchoosek} function is faster for small
+scalar integer arguments.  It also warns about loss of precision for
+big arguments.
+
+ at seealso{nchoosek}
+ at end deftypefn
+delete
+ at c ./miscellaneous/delete.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} delete (@var{file})
+ at deftypefnx {Function File} {} delete (@var{handle})
+Delete the named file or graphics handle.
+
+Deleting graphics objects is the proper way to remove
+features from a plot without clearing the entire figure.
+ at seealso{clf, cla}
+ at end deftypefn
+ans
+ at c ./miscellaneous/ans.m
+-*- texinfo -*-
+ at defvr {Automatic Variable} ans
+The most recently computed result that was not
+explicitly assigned to a variable.  For example, after the expression
+
+ at example
+3^2 + 4^2
+ at end example
+
+ at noindent
+is evaluated, the value returned by @code{ans} is 25.
+ at end defvr
+list_primes
+ at c ./miscellaneous/list_primes.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} list_primes (@var{n})
+List the first @var{n} primes.  If @var{n} is unspecified, the first
+25 primes are listed.
+
+The algorithm used is from page 218 of the @TeX{}book.
+ at seealso{primes, isprime}
+ at end deftypefn
+comma
+ at c ./miscellaneous/comma.m
+-*- texinfo -*-
+ at deffn {Operator} ,
+Array index, function argument, or command separator.
+ at seealso{semicolon}
+ at end deffn
+mkoctfile
+ at c ./miscellaneous/mkoctfile.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mkoctfile [-options] file @dots{}
+
+The @code{mkoctfile} function compiles source code written in C,
+C++, or Fortran.  Depending on the options used with @code{mkoctfile}, the
+compiled code can be called within Octave or can be used as a stand-alone
+application.
+
+ at code{mkoctfile} can be called from the shell prompt or from the Octave
+prompt.
+
+ at code{mkoctfile} accepts the following options, all of which are optional
+except for the file name of the code you wish to compile:
+
+ at table @samp
+ at item -I DIR
+Add the include directory DIR to compile commands.
+
+ at item -D DEF
+Add the definition DEF to the compiler call.
+
+ at item -l LIB
+Add the library LIB to the link command.
+         
+ at item -L DIR
+Add the library directory DIR to the link command.
+
+ at item -M
+ at itemx --depend 
+Generate dependency files (.d) for C and C++ source files.
+         
+ at item -c
+Compile but do not link.
+
+ at item -g
+Enable debugging options for compilers.
+
+ at item -o FILE
+ at itemx --output FILE  
+Output file name.  Default extension is .oct
+(or .mex if --mex is specified) unless linking
+a stand-alone executable.
+
+ at item -p VAR
+ at itemx --print VAR
+Print the configuration variable VAR.  Recognized variables are: 
+
+ at example             
+ at group
+   ALL_CFLAGS                FFTW_LIBS     
+   ALL_CXXFLAGS              FLIBS       
+   ALL_FFLAGS                FPICFLAG      
+   ALL_LDFLAGS               INCFLAGS      
+   BLAS_LIBS                 LDFLAGS             
+   CC                        LD_CXX              
+   CFLAGS                    LD_STATIC_FLAG
+   CPICFLAG                  LFLAGS              
+   CPPFLAGS                  LIBCRUFT      
+   CXX                       LIBOCTAVE     
+   CXXFLAGS                  LIBOCTINTERP  
+   CXXPICFLAG                LIBREADLINE   
+   DEPEND_EXTRA_SED_PATTERN  LIBS        
+   DEPEND_FLAGS              OCTAVE_LIBS   
+   DL_LD                     RDYNAMIC_FLAG 
+   DL_LDFLAGS                RLD_FLAG      
+   F2C                       SED         
+   F2CFLAGS                  XTRA_CFLAGS   
+   F77                       XTRA_CXXFLAGS 
+   FFLAGS
+ at end group
+ at end example
+
+ at item --link-stand-alone
+Link a stand-alone executable file.
+
+ at item --mex
+Assume we are creating a MEX file.  Set the default output extension 
+to ".mex".
+
+ at item -s
+ at itemx --strip
+Strip the output file.
+
+ at item -v
+ at itemx --verbose
+Echo commands as they are executed.
+
+ at item file
+The file to compile or link.  Recognized file types are
+
+ at example
+ at group
+                  .c    C source
+                  .cc   C++ source
+                  .C    C++ source
+                  .cpp  C++ source
+                  .f    Fortran source
+                  .F    Fortran source
+                  .o    object file
+ at end group
+ at end example
+
+ at end table
+ at end deftypefn
+dump_prefs
+ at c ./miscellaneous/dump_prefs.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dump_prefs (@var{file})
+Have Octave dump all the current user preference variables to
+ at var{file} in a format that can be parsed by Octave later.  If
+ at var{file} is omitted, the listing is printed to stdout.
+ at end deftypefn
+untar
+ at c ./miscellaneous/untar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} untar (@var{tarfile}, @var{dir})
+Unpack the TAR archive @var{tarfile} to the directory @var{dir}.
+If @var{dir} is not specified, it defaults to the current directory.
+ at seealso{unpack, bunzip2, tar, gzip, gunzip, zip, unzip}
+ at end deftypefn
+fullfile
+ at c ./miscellaneous/fullfile.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{filename} =} fullfile (@var{dir1}, @var{dir2}, @dots{}, @var{file})
+Return a complete filename constructed from the given components.
+ at seealso{fileparts}
+ at end deftypefn
+fileattrib
+ at c ./miscellaneous/fileattrib.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} fileattrib (@var{file})
+Return information about @var{file}.
+
+If successful, @var{status} is 1, with @var{result} containing a
+structure with the following fields:
+
+ at table @code
+ at item Name
+Full name of @var{file}.
+ at item archive
+True if @var{file} is an archive (Windows).
+ at item system
+True if @var{file} is a system file (Windows).
+ at item hidden
+True if @var{file} is a hidden file (Windows).
+ at item directory
+True if @var{file} is a directory.
+ at item UserRead
+ at itemx GroupRead
+ at itemx OtherRead
+True if the user (group; other users) has read permission for
+ at var{file}.
+ at item UserWrite
+ at itemx GroupWrite
+ at itemx OtherWrite
+True if the user (group; other users) has write permission for
+ at var{file}.
+ at item UserExecute
+ at itemx GroupExecute
+ at itemx OtherExecute
+True if the user (group; other users) has execute permission for
+ at var{file}.
+ at end table
+If an attribute does not apply (i.e., archive on a Unix system) then
+the field is set to NaN.
+
+With no input arguments, return information about the current
+directory.
+
+If @var{file} contains globbing characters, return information about
+all the matching files.
+ at seealso{glob}
+ at end deftypefn
+setfield
+ at c ./miscellaneous/setfield.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{k1}, @dots{}, @var{v1}] =} setfield (@var{s}, @var{k1}, @var{v1}, @dots{})
+Set field members in a structure.
+
+ at example
+ at group
+oo(1,1).f0 = 1;
+oo = setfield (oo, @{1,2@}, "fd", @{3@}, "b", 6);
+oo(1,2).fd(3).b == 6
+ at result{} ans = 1
+ at end group
+ at end example
+
+Note that this function could be written
+
+ at example
+ at group
+i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4 = "b";
+oo(i1@{:@}).(i2)(i3@{:@}).(i4) == 6;
+ at end group
+ at end example
+ at seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
+ at end deftypefn
+what
+ at c ./miscellaneous/what.m
+-*- texinfo -*-
+ at deftypefn {Command} {} what 
+ at deftypefnx {Command} {} what @var{dir}
+ at deftypefnx {Function File} {w =} what (@var{dir})
+List the Octave specific files in a directory.  If the variable @var{dir}
+is given then check that directory rather than the current directory.  If
+a return argument is requested, the files found are returned in the 
+structure @var{w}.
+ at seealso{which}
+ at end deftypefn
+computer
+ at c ./miscellaneous/computer.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{c}, @var{maxsize}, @var{endian}] =} computer ()
+Print or return a string of the form @var{cpu}- at var{vendor}- at var{os}
+that identifies the kind of computer Octave is running on.  If invoked
+with an output argument, the value is returned instead of printed.  For
+example,
+
+ at example
+ at group
+computer ()
+     @print{} i586-pc-linux-gnu
+
+x = computer ()
+     @result{} x = "i586-pc-linux-gnu"
+ at end group
+ at end example
+
+If two output arguments are requested, also return the maximum number
+of elements for an array.
+
+If three output arguments are requested, also return the byte order
+of the current system as a character (@code{"B"} for big-endian or
+ at code{"L"} for little-endian).
+ at end deftypefn
+ls_command
+ at c ./miscellaneous/ls_command.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{old_cmd} =} ls_command (@var{cmd})
+Set or return the shell command used by Octave's @code{ls} command.
+The value of @var{cmd} must be a character string.
+With no arguments, simply return the previous value.
+ at seealso{ls}
+ at end deftypefn
+flops
+ at c ./miscellaneous/flops.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} flops ()
+This function is provided for @sc{matlab} compatibility, but it doesn't
+actually do anything.
+ at end deftypefn
+copyfile
+ at c ./miscellaneous/copyfile.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2}, @var{force})
+Copy the file @var{f1} to the new name @var{f2}.  The name @var{f1}
+may contain globbing patterns.  If @var{f1} expands to multiple file
+names, @var{f2} must be a directory.  If @var{force} is given and equals
+the string "f" the copy operation will be forced.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique\n\
+message identifier.\n\
+ at seealso{glob, movefile}
+ at end deftypefn
+zip
+ at c ./miscellaneous/zip.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files})
+ at deftypefnx {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files}, @var{rootdir})
+Compress the list of files and/or directories specified in @var{files} 
+into the archive @var{zipfiles} in the same directory.  If @var{rootdir} 
+is defined the @var{files} is located relative to @var{rootdir} rather 
+than the current directory
+ at seealso{unzip,tar}
+ at end deftypefn
+tempdir
+ at c ./miscellaneous/tempdir.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{dir} =} tempdir ()
+Return the name of the system's directory for temporary files.
+ at end deftypefn
+intwarning
+ at c ./miscellaneous/intwarning.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} intwarning (@var{action})
+ at deftypefnx {Function File} {} intwarning (@var{s})
+ at deftypefnx {Function File} {@var{s} =} intwarning (@dots{})
+Control the state of the warning for integer conversions and math
+operations.
+
+ at table @asis
+ at item "query"
+The state of the Octave integer conversion and math warnings is
+queried.  If there is no output argument, then the state is printed.
+Otherwise it is returned in a structure with the fields "identifier"
+and "state".
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+ at group
+intwarning ("query")
+The state of warning "Octave:int-convert-nan" is "off"
+The state of warning "Octave:int-convert-non-int-val" is "off"
+The state of warning "Octave:int-convert-overflow" is "off"
+The state of warning "Octave:int-math-overflow" is "off"
+ at end group
+ at end smallexample 
+
+ at item "on"
+Turn integer conversion and math warnings "on".  If there is no output
+argument, then nothing is printed.  Otherwise the original state of
+the state of the integer conversion and math warnings is returned in
+a structure array.
+
+ at item "off"
+Turn integer conversion and math warnings "on".  If there is no output
+argument, then nothing is printed.  Otherwise the original state of
+the state of the integer conversion and math warnings is returned in
+a structure array.
+ at end table
+
+The original state of the integer warnings can be restored by passing
+the structure array returned by @code{intwarning} to a later call to
+ at code{intwarning}.  For example
+
+ at example
+ at group
+s = intwarning ("off");
+ at dots{}
+intwarning (s);
+ at end group
+ at end example
+ at seealso{warning}
+ at end deftypefn
+semicolon
+ at c ./miscellaneous/semicolon.m
+-*- texinfo -*-
+ at deffn {Operator} ;
+Array row or command separator.
+ at seealso{comma}
+ at end deffn
+pack
+ at c ./miscellaneous/pack.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pack ()
+This function is provided for compatibility with @sc{matlab}, but it
+doesn't actually do anything.
+ at end deftypefn
+version
+ at c ./miscellaneous/version.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} version ()
+Return Octave's version number as a string.  This is also the value of
+the built-in variable @w{@code{OCTAVE_VERSION}}.
+ at end deftypefn
+cast
+ at c ./miscellaneous/cast.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cast (@var{val}, @var{type})
+Convert @var{val} to data type @var{type}.
+ at seealso{int8, uint8, int16, uint16, int32, uint32, int64, uint64, double}
+ at end deftypefn
+bunzip2
+ at c ./miscellaneous/bunzip2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bunzip2 (@var{bzfile}, @var{dir})
+Unpack the bzip2 archive @var{bzfile} to the directory @var{dir}.  If
+ at var{dir} is not specified, it defaults to the current directory.
+ at seealso{unpack, bzip2, tar, untar, gzip, gunzip, zip, unzip}
+ at end deftypefn
+bug_report
+ at c ./miscellaneous/bug_report.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bug_report ()
+Have Octave create a bug report template file, invoke your favorite
+editor, and submit the report to the bug-octave mailing list when
+you are finished editing.
+ at end deftypefn
+isunix
+ at c ./miscellaneous/isunix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isunix ()
+Return 1 if Octave is running on a Unix-like system and 0 otherwise.
+ at seealso{ismac, ispc}
+ at end deftypefn
+getfield
+ at c ./miscellaneous/getfield.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{v1}, @dots{}] =} getfield (@var{s}, @var{key}, @dots{}) 
+Extract fields from a structure.  For example
+
+ at example
+ at group
+ss(1,2).fd(3).b = 5;
+getfield (ss, @{1,2@}, "fd", @{3@}, "b")
+ at result{} ans = 5
+ at end group
+ at end example
+
+Note that the function call in the previous example is equivalent to
+the expression
+
+ at example
+ at group
+i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4= "b";
+ss(i1@{:@}).(i2)(i3@{:@}).(i4)
+ at end group
+ at end example
+ at seealso{setfield, rmfield, isfield, isstruct, fieldnames, struct}
+ at end deftypefn
+ver
+ at c ./miscellaneous/ver.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ver ()
+Display a header containing the current Octave version
+number, license string and operating system, followed by 
+the installed package names, versions, and installation
+directories.
+ at deftypefnx {Function File} {v =} ver ()
+Return a vector of structures, respecting Octave and each installed package.
+The structure includes the following fields.
+
+ at table @code
+ at item Name
+  Package name.
+ at item Version
+  Version of the package.
+ at item Revision
+  Revision of the package.
+ at item Date
+  Date respecting the version/revision.
+ at end table
+ at deftypefnx {Function File} {v =} ver (@code{"Octave"})
+Return version information for Octave only..
+ at deftypefnx {Function File} {v =} ver (@var{pkg})
+Return version information for the specified package @var{pkg}.
+ at seealso{license, version}
+ at end deftypefn
+news
+ at c ./miscellaneous/news.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} news ()
+Display the current NEWS file for Octave.
+ at end deftypefn
+gzip
+ at c ./miscellaneous/gzip.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{entries} =} gzip (@var{files})
+ at deftypefnx {Function File} {@var{entries} =} gzip (@var{files}, @var{outdir})
+Compress the list of files and/or directories specified in @var{files}.
+Each file is compressed separately and a new file with a '.gz' extension
+is created.  The original files are not touched.  Existing compressed
+files are silently overwritten.  If @var{outdir} is defined the compressed 
+versions of the files are placed in this directory.
+ at seealso{gunzip, bzip2, zip, tar}
+ at end deftypefn
+parseparams
+ at c ./miscellaneous/parseparams.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{reg}, @var{prop}] =} parseparams (@var{params})
+Return in @var{reg} the cell elements of @var{param} up to the first
+string element and in @var{prop} all remaining elements beginning
+with the first string element.  For example 
+
+ at example
+ at group
+[reg, prop] = parseparams (@{1, 2, "linewidth", 10@})
+reg =
+@{
+  [1,1] = 1
+  [1,2] = 2
+@}
+prop =
+@{
+  [1,1] = linewidth
+  [1,2] = 10
+@}
+ at end group
+ at end example
+
+The parseparams function may be used to separate 'regular'
+arguments and additional arguments given as property/value pairs of
+the @var{varargin} cell array.
+ at seealso{varargin}
+ at end deftypefn
+ls
+ at c ./miscellaneous/ls.m
+-*- texinfo -*-
+ at deffn {Command} ls options
+List directory contents.  For example,
+
+ at example
+ at group
+ls -l
+     @print{} total 12
+     @print{} -rw-r--r--   1 jwe  users  4488 Aug 19 04:02 foo.m
+     @print{} -rw-r--r--   1 jwe  users  1315 Aug 17 23:14 bar.m
+ at end group
+ at end example
+
+The @code{dir} and @code{ls} commands are implemented by calling your
+system's directory listing command, so the available options may vary
+from system to system.
+ at seealso{dir, stat, readdir, glob, filesep, ls_command}
+ at end deffn
+ismac
+ at c ./miscellaneous/ismac.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ismac ()
+Return 1 if Octave is running on a Mac OS X system and 0 otherwise.
+ at seealso{ispc, isunix}
+ at end deftypefn
+unix
+ at c ./miscellaneous/unix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{status}, @var{text}]} unix (@var{command})
+ at deftypefnx {Function File} {[@var{status}, @var{text}]} unix (@var{command}, "-echo")
+Execute a system command if running under a Unix-like operating
+system, otherwise do nothing.  Return the exit status of the program
+in @var{status} and any output sent to the standard output in
+ at var{text}.  If the optional second argument @code{"-echo"} is given,
+then also send the output from the command to the standard output.
+ at seealso{isunix, ispc, system}
+ at end deftypefn
+inputname
+ at c ./miscellaneous/inputname.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} inputname (@var{n})
+Return the text defining @var{n}-th input to the function.
+ at end deftypefn
+fileparts
+ at c ./miscellaneous/fileparts.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{dir}, @var{name}, @var{ext}, @var{ver}] =} fileparts (@var{filename})
+Return the directory, name, extension, and version components of
+ at var{filename}.
+ at seealso{fullfile}
+ at end deftypefn
+substruct
+ at c ./miscellaneous/substruct.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} substruct (@var{type}, @var{subs}, @dots{})
+Create a subscript structure for use with @code{subsref} or
+ at code{subsasgn}.
+ at seealso{subsref, subsasgn}
+ at end deftypefn
+info
+ at c ./miscellaneous/info.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} info ()
+Display contact information for the GNU Octave community.
+ at end deftypefn
+bzip2
+ at c ./miscellaneous/bzip2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{entries} =} bzip2 (@var{files})
+ at deftypefnx {Function File} {@var{entries} =} bzip2 (@var{files}, @var{outdir})
+Compress the list of files specified in @var{files}.
+Each file is compressed separately and a new file with a '.bz2' extension
+is created.  The original files are not touched.  Existing compressed files 
+are silently overwritten.If @var{outdir} is defined the compressed versions 
+of the files are placed in this directory.
+ at seealso{bunzip2, gzip, zip, tar}
+ at end deftypefn
+swapbytes
+ at c ./miscellaneous/swapbytes.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} swapbytes (@var{x})
+Swaps the byte order on values, converting from little endian to big 
+endian and vice versa.  For example
+
+ at example
+ at group
+swapbytes (uint16 (1:4))
+ at result{} [   256   512   768  1024]
+ at end group
+ at end example
+
+ at seealso{typecast, cast}
+ at end deftypefn
+mexext
+ at c ./miscellaneous/mexext.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mexext ()
+Return the filename extension used for MEX files.
+ at end deftypefn
+paren
+ at c ./miscellaneous/paren.m
+-*- texinfo -*-
+ at deffn {Operator} (
+ at deffnx {Operator} )
+Array index or function argument delimeter.
+ at end deffn
+dos
+ at c ./miscellaneous/dos.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{status}, @var{text}] =} dos (@var{command})
+ at deftypefnx {Function File} {[@var{status}, @var{text}] =} dos (@var{command}, "-echo")
+Execute a system command if running under a Windows-like operating
+system, otherwise do nothing.  Return the exit status of the program
+in @var{status} and any output sent to the standard output in
+ at var{text}.  If the optional second argument @code{"-echo"} is given,
+then also send the output from the command to the standard output.
+ at seealso{unix, isunix, ispc, system}
+ at end deftypefn
+run
+ at c ./miscellaneous/run.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} run (@var{f})
+ at deftypefnx {Command} {} run @var{f}
+Run scripts in the current workspace that are not necessarily on the
+path.  If @var{f} is the script to run, including its path, then @code{run}
+change the directory to the directory where @var{f} is found.  @code{run}
+then executes the script, and returns to the original directory.
+ at seealso{system}
+ at end deftypefn
+texas_lotto
+ at c ./miscellaneous/texas_lotto.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} texas_lotto ()
+Pick 6 unique numbers between 1 and 50 that are guaranteed to win
+the Texas Lotto.
+ at seealso{rand}
+ at end deftypefn
+mex
+ at c ./miscellaneous/mex.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mex [options] file @dots{}
+Compile source code written in C, C++, or Fortran, to a MEX file.
+This is equivalent to @code{mkoctfile --mex [options] file}.
+ at seealso{mkoctfile}
+ at end deftypefn
+gunzip
+ at c ./miscellaneous/gunzip.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gunzip (@var{gzfile}, @var{dir})
+Unpack the gzip archive @var{gzfile} to the directory @var{dir}.  If
+ at var{dir} is not specified, it defaults to the current directory.  If
+the @var{gzfile} is a directory, all files in the directory will be
+recursively gunzipped.
+ at seealso{unpack, bunzip2, tar, untar, gzip, gunzip, zip, unzip}
+ at end deftypefn
+namelengthmax
+ at c ./miscellaneous/namelengthmax.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} namelengthmax ()
+Returns the @sc{matlab} compatible maximum variable name length.  Octave is
+capable of storing strings up to 
+ at tex
+$2^{31} - 1$
+ at end tex
+ at ifnottex
+ at code{2 ^ 31 - 1}
+ at end ifnottex
+in length.  However for @sc{matlab} compatibility all variable, function
+and structure field names should be shorter than the length supplied by
+ at code{namelengthmax}.  In particular variables stored to a @sc{matlab} file
+format will have their names truncated to this length.
+ at end deftypefn
+symvar
+ at c ./miscellaneous/symvar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} symvar (@var{s})
+Identifies the argument names in the function defined by a string.
+Common constant names such as @code{pi}, @code{NaN}, @code{Inf},
+ at code{eps}, @code{i} or @code{j} are ignored.  The arguments that are
+found are returned in a cell array of strings.  If no variables are
+found then the returned cell array is empty.
+ at end deftypefn
+edit
+ at c ./miscellaneous/edit.m
+-*- texinfo -*-
+ at deftypefn {Command} edit @var{name}
+ at deftypefnx {Command} edit @var{field} @var{value}
+ at deftypefnx {Command} {@var{value} =} edit get @var{field}
+Edit the named function, or change editor settings.
+
+If @code{edit} is called with the name of a file or function as
+its argument it will be opened in a text editor.
+
+ at itemize @bullet
+ at item
+If the function @var{name} is available in a file on your path and
+that file is modifiable, then it will be edited in place.  If it 
+is a system function, then it will first be copied to the directory
+ at code{HOME} (see further down) and then edited.  
+If no file is found, then the m-file 
+variant, ending with ".m", will be considered.  If still no file
+is found, then variants with a leading "@@" and then with both a
+leading "@@" and trailing ".m" will be considered.
+
+ at item
+If @var{name} is the name of a function defined in the interpreter but 
+not in an m-file, then an m-file will be created in @code{HOME}
+to contain that function along with its current definition.  
+
+ at item
+If @code{name.cc} is specified, then it will search for @code{name.cc}
+in the path and try to modify it, otherwise it will create a new
+ at file{.cc} file in @code{HOME}.  If @var{name} happens to be an
+m-file or interpreter defined function, then the text of that
+function will be inserted into the .cc file as a comment.
+
+ at item
+If @var{name.ext} is on your path then it will be edited, otherwise
+the editor will be started with @file{HOME/name.ext} as the
+filename.  If @file{name.ext} is not modifiable, it will be copied to
+ at code{HOME} before editing.
+
+ at strong{WARNING!} You may need to clear name before the new definition
+is available.  If you are editing a .cc file, you will need
+to mkoctfile @file{name.cc} before the definition will be available.
+ at end itemize
+
+If @code{edit} is called with @var{field} and @var{value} variables,
+the value of the control field @var{field} will be @var{value}.
+If an output argument is requested and the first argument is @code{get}
+then @code{edit} will return the value of the control field @var{field}.
+If the control field does not exist, edit will return a structure 
+containing all fields and values.  Thus, @code{edit get all} returns
+a complete control structure.
+The following control fields are used:
+
+ at table @samp
+ at item editor
+This is the editor to use to modify the functions.  By default it uses
+Octave's @code{EDITOR} built-in function, which comes from 
+ at code{getenv("EDITOR")} and defaults to @code{emacs}.  Use @code{%s}
+In place of the function name.  For example,
+ at table @samp
+ at item [EDITOR, " %s"]
+Use the editor which Octave uses for @code{bug_report}.
+ at item "xedit %s &"           
+pop up simple X11 editor in a separate window
+ at item "gnudoit -q \"(find-file \\\"%s\\\")\""   
+Send it to current Emacs; must have @code{(gnuserv-start)} in @file{.emacs}.
+ at end table
+
+See also field 'mode', which controls how the editor is run by Octave.
+
+On Cygwin, you will need to convert the Cygwin path to a Windows
+path if you are using a native Windows editor.  For example
+ at c Set example in small font to prevent overfull line
+ at smallexample
+'"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+ at end smallexample
+
+ at item home
+This is the location of user local m-files.  Be be sure it is in your
+path.  The default is @file{~/octave}.
+
+ at item author
+This is the name to put after the "## Author:" field of new functions.
+By default it guesses from the @code{gecos} field of password database.
+
+ at item email
+This is the e-mail address to list after the name in the author field.
+By default it guesses @code{<$LOGNAME@@$HOSTNAME>}, and if @code{$HOSTNAME}
+is not defined it uses @code{uname -n}.  You probably want to override this.
+Be sure to use @code{<user@@host>} as your format.
+
+ at item license
+ at table @samp
+ at item gpl
+GNU General Public License (default).
+ at item bsd
+BSD-style license without advertising clause.
+ at item pd
+Public domain.
+ at item "text"
+Your own default copyright and license.
+ at end table
+
+Unless you specify @samp{pd}, edit will prepend the copyright statement 
+with "Copyright (C) yyyy Function Author".
+
+ at item mode
+This value determines whether the editor should be started in async mode
+(editor is started in the background and Octave continues) or sync mode
+(Octave waits until the editor exits).  Set it to "async" to start the editor
+in async mode.  The default is "sync" (see also "system").
+
+ at item editinplace
+Determines whether files should be edited in place, without regard to 
+whether they are modifiable or not.  The default is @code{false}.
+ at end table
+ at end deftypefn
+pkg
+ at c ./pkg/pkg.m
+-*- texinfo -*-
+ at deftypefn  {Command} pkg @var{command} @var{pkg_name}
+ at deftypefnx {Command} pkg @var{command} @var{option} @var{pkg_name}
+This command interacts with the package manager.  Different actions will
+be taken depending on the value of @var{command}.
+
+ at table @samp
+ at item install
+Install named packages.  For example,
+ at example
+pkg install image-1.0.0.tar.gz
+ at end example
+ at noindent
+installs the package found in the file @file{image-1.0.0.tar.gz}.
+
+The @var{option} variable can contain options that affect the manner
+in which a package is installed.  These options can be one or more of
+
+ at table @code
+ at item -nodeps
+The package manager will disable the dependency checking.  That way it 
+is possible to install a package even if it depends on another package 
+that's not installed on the system.  @strong{Use this option with care.}
+
+ at item -noauto
+The package manager will not automatically load the installed package 
+when starting Octave, even if the package requests that it is.
+
+ at item -auto
+The package manager will automatically load the installed package when 
+starting Octave, even if the package requests that it isn't.
+
+ at item -local
+A local installation is forced, even if the user has system privileges.
+
+ at item -global
+A global installation is forced, even if the user doesn't normally have
+system privileges
+
+ at item -verbose
+The package manager will print the output of all of the commands that are 
+performed.
+ at end table
+
+ at item uninstall
+Uninstall named packages.  For example,
+ at example
+pkg uninstall image
+ at end example
+ at noindent
+removes the @code{image} package from the system.  If another installed
+package depends on the @code{image} package an error will be issued.
+The package can be uninstalled anyway by using the @code{-nodeps} option.
+ at item load
+Add named packages to the path.  After loading a package it is
+possible to use the functions provided by the package.  For example,
+ at example
+pkg load image
+ at end example
+ at noindent
+adds the @code{image} package to the path.  It is possible to load all
+installed packages at once with the command
+ at example
+pkg load all
+ at end example
+ at item unload
+Removes named packages from the path.  After unloading a package it is
+no longer possible to use the functions provided by the package.
+This command behaves like the @code{load} command.
+ at item list
+Show a list of the currently installed packages.  By requesting one or two
+output argument it is possible to get a list of the currently installed
+packages.  For example,
+ at example
+installed_packages = pkg list;
+ at end example
+ at noindent
+returns a cell array containing a structure for each installed package.
+The command
+ at example
+[@var{user_packages}, @var{system_packages}] = pkg list
+ at end example
+ at noindent
+splits the list of installed packages into those who are installed by
+the current user, and those installed by the system administrator.
+ at item describe
+Show a short description of the named installed packages, with the option
+'-verbose' also list functions provided by the package, e.g.:
+ at example
+ pkg describe -verbose all
+ at end example
+ at noindent
+will describe all installed packages and the functions they provide.
+If one output is requested a cell of structure containing the
+description and list of functions of each package is returned as
+output rather than printed on screen:
+ at example
+ desc = pkg ("describe", "secs1d", "image")
+ at end example
+ at noindent
+If any of the requested packages is not installed, pkg returns an
+error, unless a second output is requested:
+ at example
+ [ desc, flag] = pkg ("describe", "secs1d", "image")
+ at end example
+ at noindent
+ at var{flag} will take one of the values "Not installed", "Loaded" or
+"Not loaded" for each of the named packages.
+ at item prefix
+Set the installation prefix directory.  For example,
+ at example
+pkg prefix ~/my_octave_packages
+ at end example
+ at noindent
+sets the installation prefix to @file{~/my_octave_packages}.
+Packages will be installed in this directory.
+
+It is possible to get the current installation prefix by requesting an
+output argument.  For example,
+ at example
+p = pkg prefix
+ at end example
+
+The location in which to install the architecture dependent files can be
+independent specified with an addition argument.  For example
+
+ at example
+pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
+ at end example
+ at item local_list
+Set the file in which to look for information on the locally
+installed packages.  Locally installed packages are those that are
+typically available only to the current user.  For example
+ at example
+pkg local_list ~/.octave_packages
+ at end example
+It is possible to get the current value of local_list with the following
+ at example
+pkg local_list
+ at end example
+ at item global_list
+Set the file in which to look for, for information on the globally
+installed packages.  Globally installed packages are those that are
+typically available to all users.  For example
+ at example
+pkg global_list /usr/share/octave/octave_packages
+ at end example
+It is possible to get the current value of global_list with the following
+ at example
+pkg global_list
+ at end example
+ at item rebuild
+Rebuilds the package database from the installed directories.  This can 
+be used in cases where for some reason the package database is corrupted.
+It can also take the @code{-auto} and @code{-noauto} options to allow the
+autoloading state of a package to be changed.  For example
+
+ at example
+pkg rebuild -noauto image
+ at end example
+
+will remove the autoloading status of the image package.
+ at item build
+Builds a binary form of a package or packages.  The binary file produced
+will itself be an Octave package that can be installed normally with
+ at code{pkg}.  The form of the command to build a binary package is
+
+ at example
+pkg build builddir image-1.0.0.tar.gz @dots{}
+ at end example
+
+ at noindent
+where @code{builddir} is the name of a directory where the temporary
+installation will be produced and the binary packages will be found.
+The options @code{-verbose} and @code{-nodeps} are respected, while 
+the other options are ignored.
+ at end table
+ at end deftypefn
+csvread
+ at c ./io/csvread.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} csvread (@var{filename})
+Read the matrix @var{x} from a file.
+
+This function is equivalent to
+ at example
+dlmread (@var{filename}, "," , @dots{})
+ at end example
+
+ at seealso{dlmread, dlmwrite, csvwrite}
+ at end deftypefn
+beep
+ at c ./io/beep.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} beep ()
+Produce a beep from the speaker (or visual bell).
+ at seealso{puts, fputs, printf, fprintf}
+ at end deftypefn
+dlmwrite
+ at c ./io/dlmwrite.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dlmwrite (@var{file}, @var{a})
+ at deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, @var{delim}, @var{r}, @var{c})
+ at deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, @var{key}, @var{val} @dots{})
+ at deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, "-append", @dots{})
+Write the matrix @var{a} to the named file using delimiters.
+
+The parameter @var{delim} specifies the delimiter to use to separate
+values on a row.
+
+The value of @var{r} specifies the number of delimiter-only lines to
+add to the start of the file.
+
+The value of @var{c} specifies the number of delimiters to prepend to
+each line of data.
+
+If the argument @code{"-append"} is given, append to the end of the
+ at var{file}.
+
+In addition, the following keyword value pairs may appear at the end
+of the argument list:
+ at table @code
+ at item "append"
+Either @samp{"on"} or @samp{"off"}.  See @samp{"-append"} above.
+
+ at item "delimiter"
+See @var{delim} above.
+
+ at item "newline"
+The character(s) to use to separate each row.  Three special cases
+exist for this option.  @samp{"unix"} is changed into '\n',
+ at samp{"pc"} is changed into '\r\n', and @samp{"mac"} is changed
+into '\r'.  Other values for this option are kept as is.
+
+ at item "roffset"
+See @var{r} above.
+
+ at item "coffset"
+See @var{c} above.
+
+ at item "precision"
+The precision to use when writing the file.  It can either be a
+format string (as used by fprintf) or a number of significant digits.
+ at end table
+
+ at example
+dlmwrite ("file.csv", reshape (1:16, 4, 4));
+ at end example
+
+ at example
+dlmwrite ("file.tex", a, "delimiter", "&", "newline", "\\n")
+ at end example
+
+ at seealso{dlmread, csvread, csvwrite}
+ at end deftypefn
+csvwrite
+ at c ./io/csvwrite.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} csvwrite (@var{filename}, @var{x})
+Write the matrix @var{x} to a file.
+
+This function is equivalent to
+ at example
+dlmwrite (@var{filename}, @var{x}, ",", @dots{})
+ at end example
+
+ at seealso{dlmread, dlmwrite, csvread}
+ at end deftypefn
+magic
+ at c ./special-matrix/magic.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} magic (@var{n})
+
+Create an @var{n}-by- at var{n} magic square.  Note that @code{magic
+(@var{2})} is undefined since there is no 2-by-2 magic square.
+
+ at end deftypefn
+hankel
+ at c ./special-matrix/hankel.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hankel (@var{c}, @var{r})
+Return the Hankel matrix constructed given the first column @var{c}, and
+(optionally) the last row @var{r}.  If the last element of @var{c} is
+not the same as the first element of @var{r}, the last element of
+ at var{c} is used.  If the second argument is omitted, it is assumed to
+be a vector of zeros with the same size as @var{c}.
+
+A Hankel matrix formed from an m-vector @var{c}, and an n-vector
+ at var{r}, has the elements
+ at tex
+$$
+H (i, j) = \cases{c_{i+j-1},&$i+j-1\le m$;\cr r_{i+j-m},&otherwise.\cr}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+H(i,j) = c(i+j-1),  i+j-1 <= m;
+H(i,j) = r(i+j-m),  otherwise
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{vander, sylvester_matrix, hilb, invhilb, toeplitz}
+ at end deftypefn
+hilb
+ at c ./special-matrix/hilb.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hilb (@var{n})
+Return the Hilbert matrix of order @var{n}.  The
+ at tex
+$i,\,j$
+ at end tex
+ at ifnottex
+i, j
+ at end ifnottex
+element of a Hilbert matrix is defined as
+ at tex
+$$
+H (i, j) = {1 \over (i + j - 1)}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+H (i, j) = 1 / (i + j - 1)
+ at end example
+ at end ifnottex
+ at seealso{hankel, vander, sylvester_matrix, invhilb, toeplitz}
+ at end deftypefn
+pascal
+ at c ./special-matrix/pascal.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pascal (@var{n}, @var{t})
+
+Return the Pascal matrix of order @var{n} if @code{@var{t} = 0}.
+ at var{t} defaults to 0. Return lower triangular Cholesky factor of 
+the Pascal matrix if @code{@var{t} = 1}.  This matrix is its own
+inverse, that is @code{pascal (@var{n}, 1) ^ 2 == eye (@var{n})}.
+If @code{@var{t} = -1}, return its absolute value.  This is the
+standard pascal triangle as a lower-triangular matrix.
+If @code{@var{t} = 2}, return a transposed and permuted version of
+ at code{pascal (@var{n}, 1)}, which is the cube-root of the identity
+matrix.  That is @code{pascal (@var{n}, 2) ^ 3 == eye (@var{n})}.
+
+ at seealso{hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz
+          hadamard, wilkinson, compan, rosser}
+ at end deftypefn
+vander
+ at c ./special-matrix/vander.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} vander (@var{c}, @var{n})
+Return the Vandermonde matrix whose next to last column is @var{c}.
+If @var{n} is specified, it determines the number of columns;
+otherwise, @var{n} is taken to be equal to the length of @var{c}.
+
+A Vandermonde matrix has the form:
+ at tex
+$$
+\left[\matrix{c_1^{n-1}  & \cdots & c_1^2  & c_1    & 1      \cr
+              c_2^{n-1}  & \cdots & c_2^2  & c_2    & 1      \cr
+              \vdots     & \ddots & \vdots & \vdots & \vdots \cr
+              c_n^{n-1}  & \cdots & c_n^2  & c_n    & 1      }\right]
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+c(1)^(n-1) @dots{} c(1)^2  c(1)  1
+c(2)^(n-1) @dots{} c(2)^2  c(2)  1
+    .     .      .      .    .
+    .       .    .      .    .
+    .         .  .      .    .
+c(n)^(n-1) @dots{} c(n)^2  c(n)  1
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{hankel, sylvester_matrix, hilb, invhilb, toeplitz}
+ at end deftypefn
+wilkinson
+ at c ./special-matrix/wilkinson.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wilkinson (@var{n})
+
+Return the Wilkinson matrix of order @var{n}.
+
+ at seealso{hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz
+          hadamard, rosser, compan, pascal}
+ at end deftypefn
+sylvester_matrix
+ at c ./special-matrix/sylvester_matrix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sylvester_matrix (@var{k})
+Return the Sylvester matrix of order
+ at tex
+$n = 2^k$.
+ at end tex
+ at ifnottex
+n = 2^k.
+ at end ifnottex
+ at seealso{hankel, vander, hilb, invhilb, toeplitz}
+ at end deftypefn
+invhilb
+ at c ./special-matrix/invhilb.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} invhilb (@var{n})
+Return the inverse of a Hilbert matrix of order @var{n}.  This can be 
+computed exactly using
+ at tex
+$$\eqalign{
+  A_{ij} &= -1^{i+j} (i+j-1)
+             \left( \matrix{n+i-1 \cr n-j } \right)
+             \left( \matrix{n+j-1 \cr n-i } \right)
+             \left( \matrix{i+j-2 \cr i-2 } \right)^2 \cr
+         &= { p(i)p(j) \over (i+j-1) }
+}$$
+where
+$$
+  p(k) = -1^k \left( \matrix{ k+n-1 \cr k-1 } \right)
+              \left( \matrix{ n \cr k } \right)
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+
+            (i+j)         /n+i-1\  /n+j-1\   /i+j-2\ 2
+ A(i,j) = -1      (i+j-1)(       )(       ) (       )
+                          \ n-j /  \ n-i /   \ i-2 /
+
+        = p(i) p(j) / (i+j-1)
+
+ at end group
+ at end example
+where
+ at example
+ at group
+             k  /k+n-1\   /n\
+    p(k) = -1  (       ) (   )
+                \ k-1 /   \k/
+ at end group
+ at end example
+ at end ifnottex
+
+The validity of this formula can easily be checked by expanding 
+the binomial coefficients in both formulas as factorials.  It can 
+be derived more directly via the theory of Cauchy matrices: 
+see J. W. Demmel, Applied Numerical Linear Algebra, page 92.
+
+Compare this with the numerical calculation of @code{inverse (hilb (n))},
+which suffers from the ill-conditioning of the Hilbert matrix, and the
+finite precision of your computer's floating point arithmetic.
+ at seealso{hankel, vander, sylvester_matrix, hilb, toeplitz}
+ at end deftypefn
+hadamard
+ at c ./special-matrix/hadamard.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hadamard (@var{n})
+Construct a Hadamard matrix @var{Hn} of size @var{n}-by- at var{n}.  The 
+size @var{n} must be of the form @code{2 ^ @var{k} * @var{p}} in which
+ at var{p} is one of 1, 12, 20 or 28.  The returned matrix is normalized,
+meaning @code{Hn(:,1) == 1} and @code{H(1,:) == 1}.
+
+Some of the properties of Hadamard matrices are:
+
+ at itemize @bullet
+ at item
+ at code{kron (@var{Hm}, @var{Hn})} is a Hadamard matrix of size 
+ at var{m}-by- at var{n}.
+ at item
+ at code{Hn * Hn' == @var{n} * eye (@var{n})}.
+ at item
+The rows of @var{Hn} are orthogonal.
+ at item
+ at code{det (@var{A}) <= abs(det (@var{Hn}))} for all @var{A} with
+ at code{abs (@var{A} (@var{i}, @var{j})) <= 1}.
+ at item
+Multiply any row or column by -1 and still have a Hadamard matrix.
+ at end itemize
+
+ at end deftypefn
+rosser
+ at c ./special-matrix/rosser.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rosser ()
+
+Returns the Rosser matrix.  This is a difficult test case used to test
+eigenvalue algorithms.
+
+ at seealso{hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz
+          hadamard, wilkinson, compan, pascal}
+ at end deftypefn
+toeplitz
+ at c ./special-matrix/toeplitz.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} toeplitz (@var{c}, @var{r})
+Return the Toeplitz matrix constructed given the first column @var{c},
+and (optionally) the first row @var{r}.  If the first element of @var{c}
+is not the same as the first element of @var{r}, the first element of
+ at var{c} is used.  If the second argument is omitted, the first row is
+taken to be the same as the first column.
+
+A square Toeplitz matrix has the form:
+ at tex
+$$
+\left[\matrix{c_0    & r_1     & r_2      & \cdots & r_n\cr
+              c_1    & c_0     & r_1      & \cdots & r_{n-1}\cr
+              c_2    & c_1     & c_0      & \cdots & r_{n-2}\cr
+              \vdots & \vdots  & \vdots   & \ddots & \vdots\cr
+              c_n    & c_{n-1} & c_{n-2} & \ldots & c_0}\right]
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+c(0)  r(1)   r(2)  @dots{}  r(n)
+c(1)  c(0)   r(1)  @dots{} r(n-1)
+c(2)  c(1)   c(0)  @dots{} r(n-2)
+ .     ,      ,   .      .
+ .     ,      ,     .    .
+ .     ,      ,       .  .
+c(n) c(n-1) c(n-2) @dots{}  c(0)
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{hankel, vander, sylvester_matrix, hilb, invhilb}
+ at end deftypefn
+logm
+ at c ./linear-algebra/logm.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logm (@var{a})
+Compute the matrix logarithm of the square matrix @var{a}.  Note that
+this is currently implemented in terms of an eigenvalue expansion and
+needs to be improved to be more robust.
+ at end deftypefn
+commutation_matrix
+ at c ./linear-algebra/commutation_matrix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} commutation_matrix (@var{m}, @var{n})
+Return the commutation matrix
+ at tex
+ $K_{m,n}$
+ at end tex
+ at ifnottex
+ K(m,n)
+ at end ifnottex
+ which is the unique
+ at tex
+ $m n \times m n$
+ at end tex
+ at ifnottex
+ at var{m}*@var{n} by @var{m}*@var{n}
+ at end ifnottex
+ matrix such that
+ at tex
+ $K_{m,n} \cdot {\rm vec} (A) = {\rm vec} (A^T)$
+ at end tex
+ at ifnottex
+ at math{K(m,n) * vec(A) = vec(A')}
+ at end ifnottex
+ for all
+ at tex
+ $m\times n$
+ at end tex
+ at ifnottex
+ at math{m} by @math{n}
+ at end ifnottex
+ matrices
+ at tex
+ $A$.
+ at end tex
+ at ifnottex
+ at math{A}.
+ at end ifnottex
+
+If only one argument @var{m} is given,
+ at tex
+ $K_{m,m}$
+ at end tex
+ at ifnottex
+ at math{K(m,m)}
+ at end ifnottex
+ is returned.
+
+See Magnus and Neudecker (1988), Matrix differential calculus with
+applications in statistics and econometrics.
+ at end deftypefn
+expm
+ at c ./linear-algebra/expm.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} expm (@var{a})
+Return the exponential of a matrix, defined as the infinite Taylor
+series
+ at tex
+$$
+ \exp (A) = I + A + {A^2 \over 2!} + {A^3 \over 3!} + \cdots
+$$
+ at end tex
+ at ifnottex
+
+ at example
+expm(a) = I + a + a^2/2! + a^3/3! + @dots{}
+ at end example
+
+ at end ifnottex
+The Taylor series is @emph{not} the way to compute the matrix
+exponential; see Moler and Van Loan, @cite{Nineteen Dubious Ways to
+Compute the Exponential of a Matrix}, SIAM Review, 1978.  This routine
+uses Ward's diagonal
+ at tex
+Pad\'e
+ at end tex
+ at ifnottex
+Pade'
+ at end ifnottex
+approximation method with three step preconditioning (SIAM Journal on
+Numerical Analysis, 1977).  Diagonal
+ at tex
+Pad\'e
+ at end tex
+ at ifnottex
+Pade'
+ at end ifnottex
+ approximations are rational polynomials of matrices
+ at tex
+$D_q(a)^{-1}N_q(a)$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     -1
+D (a)   N (a)
+ at end group
+ at end example
+
+ at end ifnottex
+ whose Taylor series matches the first
+ at tex
+$2 q + 1 $
+ at end tex
+ at ifnottex
+ at code{2q+1}
+ at end ifnottex
+terms of the Taylor series above; direct evaluation of the Taylor series
+(with the same preconditioning steps) may be desirable in lieu of the
+ at tex
+Pad\'e
+ at end tex
+ at ifnottex
+Pade'
+ at end ifnottex
+approximation when
+ at tex
+$D_q(a)$
+ at end tex
+ at ifnottex
+ at code{Dq(a)}
+ at end ifnottex
+is ill-conditioned.
+ at end deftypefn
+dot
+ at c ./linear-algebra/dot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dot (@var{x}, @var{y}, @var{dim})
+Computes the dot product of two vectors.  If @var{x} and @var{y}
+are matrices, calculate the dot-product along the first 
+non-singleton dimension.  If the optional argument @var{dim} is
+given, calculate the dot-product along this dimension.
+ at end deftypefn
+cross
+ at c ./linear-algebra/cross.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} cross (@var{x}, @var{y})
+ at deftypefnx {Function File} {} cross (@var{x}, @var{y}, @var{dim})
+Compute the vector cross product of two 3-dimensional vectors
+ at var{x} and @var{y}.
+
+ at example
+ at group
+cross ([1,1,0], [0,1,1])
+     @result{} [ 1; -1; 1 ]
+ at end group
+ at end example
+
+If @var{x} and @var{y} are matrices, the cross product is applied 
+along the first dimension with 3 elements.  The optional argument 
+ at var{dim} forces the cross product to be calculated along
+the specified dimension.
+ at seealso{dot}
+ at end deftypefn
+cond
+ at c ./linear-algebra/cond.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cond (@var{a}, at var{p})
+Compute the @var{p}-norm condition number of a matrix.  @code{cond (@var{a})} is
+defined as @code{norm (@var{a}, @var{p}) * norm (inv (@var{a}), @var{p})}.
+By default @code{@var{p}=2} is used which implies a (relatively slow)
+singular value decomposition.  Other possible selections are 
+ at code{@var{p}= 1, Inf, inf, 'Inf', 'fro'} which are generally faster.
+ at seealso{condest, rcond, norm, svd}
+ at end deftypefn
+planerot
+ at c ./linear-algebra/planerot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{g}, @var{y}] =} planerot (@var{x})
+Given a two-element column vector, returns the
+ at tex
+$2 \times 2$ orthogonal matrix
+ at end tex
+ at ifnottex
+2 by 2 orthogonal matrix
+ at end ifnottex
+ at var{G} such that
+ at code{@var{y} = @var{g} * @var{x}} and @code{@var{y}(2) = 0}.
+ at seealso{givens}
+ at end deftypefn
+duplication_matrix
+ at c ./linear-algebra/duplication_matrix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} duplication_matrix (@var{n})
+Return the duplication matrix
+ at tex
+ $D_n$
+ at end tex
+ at ifnottex
+ at math{Dn}
+ at end ifnottex
+ which is the unique
+ at tex
+ $n^2 \times n(n+1)/2$
+ at end tex
+ at ifnottex
+ at math{n^2} by @math{n*(n+1)/2}
+ at end ifnottex
+ matrix such that
+ at tex
+ $D_n * {\rm vech} (A) = {\rm vec} (A)$
+ at end tex
+ at ifnottex
+ at math{Dn vech (A) = vec (A)}
+ at end ifnottex
+ for all symmetric
+ at tex
+ $n \times n$
+ at end tex
+ at ifnottex
+ at math{n} by @math{n}
+ at end ifnottex
+ matrices
+ at tex
+ $A$.
+ at end tex
+ at ifnottex
+ at math{A}.
+ at end ifnottex
+
+See Magnus and Neudecker (1988), Matrix differential calculus with
+applications in statistics and econometrics.
+ at end deftypefn
+onenormest
+ at c ./linear-algebra/onenormest.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{a}, @var{t}) 
+ at deftypefnx {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{apply}, @var{apply_t}, @var{n}, @var{t})
+
+Apply Higham and Tisseur's randomized block 1-norm estimator to
+matrix @var{a} using @var{t} test vectors.  If @var{t} exceeds 5, then
+only 5 test vectors are used.
+
+If the matrix is not explicit, e.g., when estimating the norm of 
+ at code{inv (@var{A})} given an LU factorization, @code{onenormest} applies 
+ at var{A} and its conjugate transpose through a pair of functions 
+ at var{apply} and @var{apply_t}, respectively, to a dense matrix of size 
+ at var{n} by @var{t}.  The implicit version requires an explicit dimension 
+ at var{n}.
+
+Returns the norm estimate @var{est}, two vectors @var{v} and
+ at var{w} related by norm
+ at code{(@var{w}, 1) = @var{est} * norm (@var{v}, 1)},
+and the number of iterations @var{iter}.  The number of
+iterations is limited to 10 and is at least 2.
+
+References: 
+ at itemize
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+ at url{http://dx.doi.org/10.1137/S0895479899356080}
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." @url{http://citeseer.ist.psu.edu/223007.html}
+ at end itemize
+
+ at seealso{condest, norm, cond}
+ at end deftypefn
+housh
+ at c ./linear-algebra/housh.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{housv}, @var{beta}, @var{zer}] =} housh (@var{x}, @var{j}, @var{z})
+Compute Householder reflection vector @var{housv} to reflect @var{x}
+to be the j-th column of identity, i.e.,
+
+ at example
+ at group
+(I - beta*housv*housv')x =  norm(x)*e(j) if x(1) < 0,
+(I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0
+ at end group
+ at end example
+
+ at noindent
+Inputs
+
+ at table @var
+ at item x
+vector
+ at item j
+index into vector
+ at item z
+threshold for zero  (usually should be the number 0)
+ at end table
+
+ at noindent
+Outputs (see Golub and Van Loan):
+
+ at table @var
+ at item beta
+If beta = 0, then no reflection need be applied (zer set to 0)
+ at item housv
+householder vector
+ at end table
+ at end deftypefn
+rref
+ at c ./linear-algebra/rref.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{r}, @var{k}] =} rref (@var{a}, @var{tol})
+
+Returns the reduced row echelon form of @var{a}.  @var{tol} defaults
+to @code{eps * max (size (@var{a})) * norm (@var{a}, inf)}.
+
+Called with two return arguments, @var{k} returns the vector of
+"bound variables", which are those columns on which elimination 
+has been performed.
+
+ at end deftypefn
+krylov
+ at c ./linear-algebra/krylov.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{u}, @var{h}, @var{nu}] =} krylov (@var{a}, @var{v}, @var{k}, @var{eps1}, @var{pflg})
+Construct an orthogonal basis @var{u} of block Krylov subspace
+
+ at example
+[v a*v a^2*v @dots{} a^(k+1)*v]
+ at end example
+
+ at noindent
+Using Householder reflections to guard against loss of orthogonality.
+
+If @var{v} is a vector, then @var{h} contains the Hessenberg matrix
+such that @code{a*u == u*h+rk*ek'}, in which @code{rk =
+a*u(:,k)-u*h(:,k)}, and @code{ek'} is the vector
+ at code{[0, 0, @dots{}, 1]} of length @code{k}.  Otherwise, @var{h} is
+meaningless.
+
+If @var{v} is a vector and @var{k} is greater than
+ at code{length(A)-1}, then @var{h} contains the Hessenberg matrix such
+that @code{a*u == u*h}.
+
+The value of @var{nu} is the dimension of the span of the krylov
+subspace (based on @var{eps1}).
+
+If @var{b} is a vector and @var{k} is greater than @var{m-1}, then
+ at var{h} contains the Hessenberg decomposition of @var{a}.
+
+The optional parameter @var{eps1} is the threshold for zero.  The
+default value is 1e-12.
+
+If the optional parameter @var{pflg} is nonzero, row pivoting is used
+to improve numerical behavior.  The default value is 0.
+
+Reference: Hodel and Misra, "Partial Pivoting in the Computation of
+Krylov Subspaces", to be submitted to Linear Algebra and its
+Applications
+ at end deftypefn
+qzhess
+ at c ./linear-algebra/qzhess.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{aa}, @var{bb}, @var{q}, @var{z}] =} qzhess (@var{a}, @var{b})
+Compute the Hessenberg-triangular decomposition of the matrix pencil
+ at code{(@var{a}, @var{b})}, returning
+ at code{@var{aa} = @var{q} * @var{a} * @var{z}},
+ at code{@var{bb} = @var{q} * @var{b} * @var{z}}, with @var{q} and @var{z}
+orthogonal.  For example,
+
+ at example
+ at group
+[aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
+     @result{} aa = [ -3.02244, -4.41741;  0.92998,  0.69749 ]
+     @result{} bb = [ -8.60233, -9.99730;  0.00000, -0.23250 ]
+     @result{}  q = [ -0.58124, -0.81373; -0.81373,  0.58124 ]
+     @result{}  z = [ 1, 0; 0, 1 ]
+ at end group
+ at end example
+
+The Hessenberg-triangular decomposition is the first step in
+Moler and Stewart's QZ decomposition algorithm.
+
+Algorithm taken from Golub and Van Loan, @cite{Matrix Computations, 2nd
+edition}.
+ at end deftypefn
+subspace
+ at c ./linear-algebra/subspace.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{angle} =} subspace (@var{a}, @var{B})
+Determine the largest principal angle between two subspaces
+spanned by columns of matrices @var{a} and @var{b}.
+ at end deftypefn
+vech
+ at c ./linear-algebra/vech.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} vech (@var{x})
+Return the vector obtained by eliminating all supradiagonal elements of
+the square matrix @var{x} and stacking the result one column above the
+other.
+ at end deftypefn
+krylovb
+ at c ./linear-algebra/krylovb.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{u}, @var{ucols}] =} krylovb (@var{a}, @var{v}, @var{k}, @var{eps1}, @var{pflg})
+See @code{krylov}.
+ at end deftypefn
+condest
+ at c ./linear-algebra/condest.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{est}, @var{v}] =} condest (@var{a}, @var{t}) 
+ at deftypefnx {Function File} {[@var{est}, @var{v}] =} condest (@var{a}, @var{solve}, @var{solve_t}, @var{t})
+ at deftypefnx {Function File} {[@var{est}, @var{v}] =} condest (@var{apply}, @var{apply_t}, @var{solve}, @var{solve_t}, @var{n}, @var{t})
+
+Estimate the 1-norm condition number of a matrix @var{A}
+using @var{t} test vectors using a randomized 1-norm estimator.
+If @var{t} exceeds 5, then only 5 test vectors are used.
+
+If the matrix is not explicit, e.g., when estimating the condition 
+number of @var{a} given an LU factorization, @code{condest} uses the 
+following functions:
+
+ at table @var
+ at item apply
+ at code{A*x} for a matrix @code{x} of size @var{n} by @var{t}.
+ at item apply_t
+ at code{A'*x} for a matrix @code{x} of size @var{n} by @var{t}.
+ at item solve
+ at code{A \ b} for a matrix @code{b} of size @var{n} by @var{t}.
+ at item solve_t
+ at code{A' \ b} for a matrix @code{b} of size @var{n} by @var{t}.
+ at end table
+
+The implicit version requires an explicit dimension @var{n}.
+
+ at code{condest} uses a randomized algorithm to approximate
+the 1-norms.
+
+ at code{condest} returns the 1-norm condition estimate @var{est} and
+a vector @var{v} satisfying @code{norm (A*v, 1) == norm (A, 1) * norm
+(@var{v}, 1) / @var{est}}.  When @var{est} is large, @var{v} is an
+approximate null vector.
+
+References: 
+ at itemize
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+ at url{http://dx.doi.org/10.1137/S0895479899356080}
+ at item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+for Matrix 1-Norm Estimation, with an Application to 1-Norm
+Pseudospectra." @url{http://citeseer.ist.psu.edu/223007.html}
+ at end itemize
+
+ at seealso{cond, norm, onenormest}
+ at end deftypefn
+rank
+ at c ./linear-algebra/rank.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rank (@var{a}, @var{tol})
+Compute the rank of @var{a}, using the singular value decomposition.
+The rank is taken to be the number of singular values of @var{a} that
+are greater than the specified tolerance @var{tol}.  If the second
+argument is omitted, it is taken to be
+
+ at example
+tol = max (size (@var{a})) * sigma(1) * eps;
+ at end example
+
+ at noindent
+where @code{eps} is machine precision and @code{sigma(1)} is the largest
+singular value of @var{a}.
+ at end deftypefn
+trace
+ at c ./linear-algebra/trace.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} trace (@var{a})
+Compute the trace of @var{a}, @code{sum (diag (@var{a}))}.
+ at end deftypefn
+null
+ at c ./linear-algebra/null.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} null (@var{a}, @var{tol})
+Return an orthonormal basis of the null space of @var{a}.
+
+The dimension of the null space is taken as the number of singular
+values of @var{a} not greater than @var{tol}.  If the argument @var{tol}
+is missing, it is computed as
+
+ at example
+max (size (@var{a})) * max (svd (@var{a})) * eps
+ at end example
+ at end deftypefn
+orth
+ at c ./linear-algebra/orth.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} orth (@var{a}, @var{tol})
+Return an orthonormal basis of the range space of @var{a}.
+
+The dimension of the range space is taken as the number of singular
+values of @var{a} greater than @var{tol}.  If the argument @var{tol} is
+missing, it is computed as
+
+ at example
+max (size (@var{a})) * max (svd (@var{a})) * eps
+ at end example
+ at end deftypefn
+vec
+ at c ./linear-algebra/vec.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} vec (@var{x})
+Return the vector obtained by stacking the columns of the matrix @var{x}
+one above the other.
+ at end deftypefn
+findstr
+ at c ./strings/findstr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} findstr (@var{s}, @var{t}, @var{overlap})
+Return the vector of all positions in the longer of the two strings
+ at var{s} and @var{t} where an occurrence of the shorter of the two starts.
+If the optional argument @var{overlap} is nonzero, the returned vector
+can include overlapping positions (this is the default).  For example,
+
+ at example
+ at group
+findstr ("ababab", "a")
+     @result{} [1, 3, 5]
+findstr ("abababa", "aba", 0)
+     @result{} [1, 5]
+ at end group
+ at end example
+ at seealso{strfind, strmatch, strcmp, strncmp, strcmpi, strncmpi, find}
+ at end deftypefn
+strtrunc
+ at c ./strings/strtrunc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strtrunc (@var{s}, @var{n})
+Truncate the character string @var{s} to length @var{n}.  If @var{s}
+is a char matrix, then the number of columns is adjusted.
+
+If @var{s} is a cell array of strings, then the operation is performed
+on its members and the new cell array is returned.
+ at end deftypefn
+isstrprop
+ at c ./strings/isstrprop.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isstrprop (@var{str}, @var{pred})
+Test character string properties.  For example,
+
+ at example
+ at group
+isstrprop ("abc123", "alpha")
+ at result{} [1, 1, 1, 0, 0, 0]
+ at end group
+ at end example
+
+If @var{str} is a cell array, @code{isstrpop} is applied recursively
+to each element of the cell array.
+
+Numeric arrays are converted to character strings.
+
+The second argument @var{pred} may be one of
+
+ at table @code
+ at item "alpha"
+True for characters that are alphabetic
+
+ at item "alnum"
+ at itemx "alphanum"
+True for characters that are alphabetic or digits.
+
+ at item "ascii"
+True for characters that are in the range of ASCII encoding.
+
+ at item "cntrl"
+True for control characters.
+
+ at item "digit"
+True for decimal digits.
+
+ at item "graph"
+ at itemx "graphic"
+True for printing characters except space.
+
+ at item "lower"
+True for lower-case letters.
+
+ at item "print"
+True for printing characters including space.
+
+ at item "punct"
+True for printing characters except space or letter or digit.
+
+ at item "space"
+ at itemx "wspace"
+True for whitespace characters (space, formfeed, newline, carriage
+return, tab, vertical tab).
+
+ at item "upper"
+True for upper-case letters.
+
+ at item "xdigit"
+True for hexadecimal digits.
+ at end table
+
+ at seealso{isalnum, isalpha, isascii, iscntrl, isdigit, isgraph,
+islower, isprint, ispunct, isspace, isupper, isxdigit}
+ at end deftypefn
+bin2dec
+ at c ./strings/bin2dec.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bin2dec (@var{s})
+Return the decimal number corresponding to the binary number stored
+in the string @var{s}.  For example,
+
+ at example
+ at group
+bin2dec ("1110")
+     @result{} 14
+ at end group
+ at end example
+
+If @var{s} is a string matrix, returns a column vector of converted
+numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
+ at seealso{dec2hex, base2dec, dec2base, hex2dec, dec2bin}
+ at end deftypefn
+strcmpi
+ at c ./strings/strcmpi.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strcmpi (@var{s1}, @var{s2})
+Ignoring case, return 1 if the character strings (or character
+arrays) @var{s1} and @var{s2} are the same, and 0 otherwise.
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmpi
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{strcmp, strncmp, strncmpi}
+ at end deftypefn
+isletter
+ at c ./strings/isletter.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isletter (@var{s})
+Returns true if @var{s} is a letter, false otherwise.
+ at seealso{isalpha}
+ at end deftypefn
+strsplit
+ at c ./strings/strsplit.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{s}] =} strsplit (@var{p}, @var{sep}, @var{strip_empty})
+Split a single string using one or more delimiters and return a cell
+array of strings.  Consecutive delimiters and delimiters at
+boundaries result in empty strings, unless @var{strip_empty} is true.
+The default value of @var{strip_empty} is false.
+ at seealso{strtok}
+ at end deftypefn
+cstrcat
+ at c ./strings/cstrcat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cstrcat (@var{s1}, @var{s2}, @dots{})
+Return a string containing all the arguments concatenated
+horizontally.  Trailing white space is preserved.  For example,
+
+ at example
+ at group
+cstrcat ("ab   ", "cd")
+     @result{} "ab   cd"
+ at end group
+ at end example
+
+ at example
+ at group
+s = [ "ab"; "cde" ];
+cstrcat (s, s, s)
+     @result{} ans =
+        "ab ab ab "
+        "cdecdecde"
+ at end group
+ at end example
+ at seealso{strcat, char, strvcat}
+ at end deftypefn
+mat2str
+ at c ./strings/mat2str.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{s} =} mat2str (@var{x}, @var{n})
+ at deftypefnx {Function File} {@var{s} =} mat2str (@dots{}, 'class')
+
+Format real/complex numerical matrices as strings.  This function
+returns values that are suitable for the use of the @code{eval}
+function.
+
+The precision of the values is given by @var{n}.  If @var{n} is a
+scalar then both real and imaginary parts of the matrix are printed
+to the same precision.  Otherwise @code{@var{n} (1)} defines the
+precision of the real part and @code{@var{n} (2)} defines the
+precision of the imaginary part.  The default for @var{n} is 17.
+
+If the argument 'class' is given, then the class of @var{x} is
+included in the string in such a way that the eval will result in the
+construction of a matrix of the same class.
+
+ at example
+ at group
+mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
+     @result{} "[-0.3333+0.14i;0.3333-0.14i]"
+
+mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
+     @result{} "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]"
+
+mat2str (int16([1 -1]), 'class')
+     @result{} "int16([1,-1])"
+ at end group
+ at end example
+
+ at seealso{sprintf, num2str, int2str}
+ at end deftypefn
+base2dec
+ at c ./strings/base2dec.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} base2dec (@var{s}, @var{b})
+Convert @var{s} from a string of digits of base @var{b} into an
+integer.
+
+ at example
+ at group
+base2dec ("11120", 3)
+     @result{} 123
+ at end group
+ at end example
+
+If @var{s} is a matrix, returns a column vector with one value per
+row of @var{s}.  If a row contains invalid symbols then the
+corresponding value will be NaN.  Rows are right-justified before
+converting so that trailing spaces are ignored.
+
+If @var{b} is a string, the characters of @var{b} are used as the
+symbols for the digits of @var{s}.  Space (' ') may not be used as a
+symbol.
+
+ at example
+ at group
+base2dec ("yyyzx", "xyz")
+     @result{} 123
+ at end group
+ at end example
+ at seealso{dec2base, dec2bin, bin2dec, hex2dec, dec2hex}
+ at end deftypefn
+strmatch
+ at c ./strings/strmatch.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strmatch (@var{s}, @var{a}, "exact")
+Return indices of entries of @var{a} that match the string @var{s}.
+The second argument @var{a} may be a string matrix or a cell array of
+strings.  If the third argument @code{"exact"} is not given, then
+ at var{s} only needs to match @var{a} up to the length of @var{s}.  Nul
+characters match blanks.  Results are returned as a column vector. 
+For example:
+
+ at example
+ at group
+strmatch ("apple", "apple juice")
+     @result{} 1
+
+strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
+     @result{} [1; 2]
+
+strmatch ("apple", @{"apple pie"; "apple juice"; "tomato"@})
+     @result{} [1; 2]
+ at end group
+ at end example
+ at seealso{strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find}
+ at end deftypefn
+strncmpi
+ at c ./strings/strncmpi.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strncmpi (@var{s1}, @var{s2}, @var{n})
+Ignoring case, return 1 if the first @var{n} characters of character
+strings (or character arrays) @var{s1} and @var{s2} are the same, and
+0 otherwise.
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmpi
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{strcmp, strcmpi, strncmp}
+ at end deftypefn
+strfind
+ at c ./strings/strfind.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{idx} =} strfind (@var{str}, @var{pattern})
+ at deftypefnx {Function File} {@var{idx} =} strfind (@var{cellstr}, @var{pattern})
+Search for @var{pattern} in the string @var{str} and return the
+starting index of every such occurrence in the vector @var{idx}.
+If there is no such occurrence, or if @var{pattern} is longer
+than @var{str}, then @var{idx} is the empty array @code{[]}.
+
+If the cell array of strings @var{cellstr} is specified instead of the
+string @var{str}, then @var{idx} is a cell array of vectors, as specified
+above.  Examples:
+
+ at example
+ at group
+strfind ("abababa", "aba")
+     @result{} [1, 3, 5]
+
+strfind (@{"abababa", "bebebe", "ab"@}, "aba")
+     @result{} ans =
+        @{
+          [1,1] =
+
+             1   3   5
+
+          [1,2] = [](1x0)
+          [1,3] = [](1x0)
+        @}
+ at end group
+ at end example
+ at seealso{findstr, strmatch, strcmp, strncmp, strcmpi, strncmpi, find}
+ at end deftypefn
+validatestring
+ at c ./strings/validatestring.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray})
+ at deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname})
+ at deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname}, @var{varname})
+ at deftypefnx {Function File} {@var{validstr} =} validatestring (@dots{}, @var{position})
+Verify that @var{str} is a string or substring of an element of
+ at var{strarray}.
+
+ at var{str} is a character string to be tested, and @var{strarray} is a
+cellstr of valid values.  @var{validstr} will be the validated form
+of @var{str} where validation is defined as @var{str} being a member
+or substring of @var{validstr}.  If @var{str} is a substring of
+ at var{validstr} and there are multiple matches, the shortest match
+will be returned if all matches are substrings of each other, and an
+error will be raised if the matches are not substrings of each other.
+
+All comparisons are case insensitive.
+ at seealso{strcmp, strcmpi}
+ at end deftypefn
+strtok
+ at c ./strings/strtok.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{tok}, @var{rem}] =} strtok (@var{str}, @var{delim})
+
+Find all characters up to but not including the first character which
+is in the string delim.  If @var{rem} is requested, it contains the
+remainder of the string, starting at the first delimiter.  Leading
+delimiters are ignored.  If @var{delim} is not specified, space is
+assumed.  For example: 
+
+ at example
+ at group
+strtok ("this is the life")
+     @result{} "this"
+
+[tok, rem] = strtok ("14*27+31", "+-*/")
+     @result{}
+        tok = 14
+        rem = *27+31
+ at end group
+ at end example
+ at seealso{index, strsplit}
+ at end deftypefn
+strrep
+ at c ./strings/strrep.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strrep (@var{s}, @var{x}, @var{y})
+Replace all occurrences of the substring @var{x} of the string @var{s}
+with the string @var{y} and return the result.  For example,
+
+ at example
+ at group
+strrep ("This is a test string", "is", "&%$")
+     @result{} "Th&%$ &%$ a test string"
+ at end group
+ at end example
+ at seealso{regexprep, strfind, findstr}
+ at end deftypefn
+dec2base
+ at c ./strings/dec2base.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dec2base (@var{n}, @var{b}, @var{len})
+Return a string of symbols in base @var{b} corresponding to
+the non-negative integer @var{n}.
+
+ at example
+ at group
+dec2base (123, 3)
+     @result{} "11120"
+ at end group
+ at end example
+
+If @var{n} is a vector, return a string matrix with one row per value,
+padded with leading zeros to the width of the largest value.
+
+If @var{b} is a string then the characters of @var{b} are used as
+the symbols for the digits of @var{n}.  Space (' ') may not be used
+as a symbol.
+
+ at example
+ at group
+dec2base (123, "aei")
+     @result{} "eeeia"
+ at end group
+ at end example
+
+The optional third argument, @var{len}, specifies the minimum
+number of digits in the result.
+ at seealso{base2dec, dec2bin, bin2dec, hex2dec, dec2hex}
+ at end deftypefn
+dec2hex
+ at c ./strings/dec2hex.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dec2hex (@var{n}, @var{len})
+Return the hexadecimal string corresponding to the non-negative 
+integer @var{n}.  For example,
+
+ at example
+ at group
+dec2hex (2748)
+     @result{} "ABC"
+ at end group
+ at end example
+
+If @var{n} is a vector, returns a string matrix, one row per value,
+padded with leading zeros to the width of the largest value.
+
+The optional second argument, @var{len}, specifies the minimum
+number of digits in the result.
+ at seealso{hex2dec, dec2base, base2dec, bin2dec, dec2bin}
+ at end deftypefn
+str2double
+ at c ./strings/str2double.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{num}, @var{status}, @var{strarray}] =} str2double (@var{str}, @var{cdelim}, @var{rdelim}, @var{ddelim})
+Convert strings into numeric values.
+
+ at code{str2double} can replace @code{str2num}, but avoids the use of
+ at code{eval} on unknown data.
+
+ at var{str} can be the form @samp{[+-]d[.]dd[[eE][+-]ddd]} in which
+ at samp{d} can be any of digit from 0 to 9, and @samp{[]} indicate
+optional elements.
+
+ at var{num} is the corresponding numeric value.  If the conversion
+fails, status is -1 and @var{num} is NaN.
+
+ at var{status} is 0 if the conversion was successful and -1 otherwise.
+
+ at var{strarray} is a cell array of strings.
+
+Elements which are not defined or not valid return NaN and the
+ at var{status} becomes -1.
+
+If @var{str} is a character array or a cell array of strings, then
+ at var{num} and @var{status} return matrices of appropriate size. 
+
+ at var{str} can also contain multiple elements separated by row and
+column delimiters (@var{cdelim} and @var{rdelim}).
+
+The parameters @var{cdelim}, @var{rdelim}, and @var{ddelim} are
+optional column, row, and decimal delimiters.
+
+The default row-delimiters are newline, carriage return and semicolon
+(ASCII 10, 13 and 59).  The default column-delimiters are tab, space
+and comma (ASCII 9, 32, and 44).  The default decimal delimiter is
+ at samp{.} (ASCII 46).
+
+ at var{cdelim}, @var{rdelim}, and @var{ddelim} must contain only nul,
+newline, carriage return, semicolon, colon, slash, tab, space, comma,
+or @samp{()[]@{@}} (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40,
+41, 44, 47, 58, 59, 91, 93, 123, 124, 125).
+
+Examples:
+
+ at example
+ at group
+str2double ("-.1e-5")
+ at result{} -1.0000e-006
+
+str2double (".314e1, 44.44e-1, .7; -1e+1")
+ at result{}
+   3.1400    4.4440    0.7000
+ -10.0000       NaN       NaN
+
+line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+[x, status] = str2double (line)
+ at result{} x =
+    200   300   NaN  -Inf   NaN   NaN   999   NaN   NaN
+ at result{} status =
+      0     0     0     0    -1    -1     0    -1     0
+ at end group
+ at end example
+ at seealso{str2num}
+ at end deftypefn
+strtrim
+ at c ./strings/strtrim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strtrim (@var{s})
+Remove leading and trailing blanks and nulls from @var{s}.  If
+ at var{s} is a matrix, @var{strtrim} trims each row to the length of
+longest string.  If @var{s} is a cell array, operate recursively on
+each element of the cell array.  For example:
+
+ at example
+ at group
+strtrim ("    abc  ")
+     @result{} "abc"
+
+strtrim ([" abc   "; "   def   "])
+     @result{} ["abc  "; "  def"]
+ at end group
+ at end example
+ at end deftypefn
+substr
+ at c ./strings/substr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} substr (@var{s}, @var{offset}, @var{len})
+Return the substring of @var{s} which starts at character number
+ at var{offset} and is @var{len} characters long.
+
+If @var{offset} is negative, extraction starts that far from the end of
+the string.  If @var{len} is omitted, the substring extends to the end
+of S.
+
+For example,
+
+ at example
+ at group
+substr ("This is a test string", 6, 9)
+     @result{} "is a test"
+ at end group
+ at end example
+
+This function is patterned after AWK.  You can get the same result by
+ at code{@var{s}(@var{offset} : (@var{offset} + @var{len} - 1))}.
+ at end deftypefn
+deblank
+ at c ./strings/deblank.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} deblank (@var{s})
+Remove trailing blanks and nulls from @var{s}.  If @var{s}
+is a matrix, @var{deblank} trims each row to the length of longest
+string.  If @var{s} is a cell array, operate recursively on each
+element of the cell array.
+ at end deftypefn
+dec2bin
+ at c ./strings/dec2bin.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dec2bin (@var{n}, @var{len})
+Return a binary number corresponding to the non-negative decimal number
+ at var{n}, as a string of ones and zeros.  For example,
+
+ at example
+ at group
+dec2bin (14)
+     @result{} "1110"
+ at end group
+ at end example
+
+If @var{n} is a vector, returns a string matrix, one row per value,
+padded with leading zeros to the width of the largest value.
+
+The optional second argument, @var{len}, specifies the minimum
+number of digits in the result.
+ at seealso{bin2dec, dec2base, base2dec, hex2dec, dec2hex}
+ at end deftypefn
+blanks
+ at c ./strings/blanks.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} blanks (@var{n})
+Return a string of @var{n} blanks, for example:
+
+ at example
+ at group
+blanks(10);
+whos ans;
+     @result{}
+      Attr Name        Size                     Bytes  Class
+      ==== ====        ====                     =====  ===== 
+           ans         1x10                        10  char
+ at end group
+ at end example
+ at seealso{repmat}
+ at end deftypefn
+str2num
+ at c ./strings/str2num.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} str2num (@var{s})
+Convert the string (or character array) @var{s} to a number (or an
+array).  Examples:  
+
+ at example
+ at group
+str2num("3.141596")
+     @result{} 3.141596
+
+str2num(["1, 2, 3"; "4, 5, 6"]);
+     @result{} ans =
+        1  2  3
+        4  5  6
+ at end group
+ at end example
+
+ at strong{Caution:} As @code{str2num} uses the @code{eval} function
+to do the conversion, @code{str2num} will execute any code contained
+in the string @var{s}.  Use @code{str2double} instead if you want to
+avoid the use of @code{eval}. 
+ at seealso{str2double, eval}
+ at end deftypefn
+hex2dec
+ at c ./strings/hex2dec.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hex2dec (@var{s})
+Return the integer corresponding to the hexadecimal number stored
+in the string @var{s}.  For example,
+
+ at example
+ at group
+hex2dec ("12B")
+     @result{} 299
+hex2dec ("12b")
+     @result{} 299
+ at end group
+ at end example
+
+If @var{s} is a string matrix, returns a column vector of converted
+numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
+ at seealso{dec2hex, base2dec, dec2base, bin2dec, dec2bin}
+ at end deftypefn
+strcat
+ at c ./strings/strcat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strcat (@var{s1}, @var{s2}, @dots{})
+Return a string containing all the arguments concatenated
+horizontally.  If the arguments are cells strings,  @code{strcat}
+returns a cell string with the individual cells concatenated.
+For numerical input, each element is converted to the
+corresponding ASCII character.  Trailing white space is eliminated.
+For example,
+
+ at example
+ at group
+s = [ "ab"; "cde" ];
+strcat (s, s, s)
+     @result{} ans =
+        "ab ab ab "
+        "cdecdecde"
+ at end group
+ at end example
+
+ at example
+ at group
+s = @{ "ab"; "cde" @};
+strcat (s, s, s)
+     @result{} ans =
+        @{
+          [1,1] = ababab
+          [2,1] = cdecdecde
+        @}
+ at end group
+ at end example
+
+ at seealso{cstrcat, char, strvcat}
+ at end deftypefn
+index
+ at c ./strings/index.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} index (@var{s}, @var{t})
+ at deftypefnx {Function File} {} index (@var{s}, @var{t}, @var{direction})
+Return the position of the first occurrence of the string @var{t} in the
+string @var{s}, or 0 if no occurrence is found.  For example,
+
+ at example
+ at group
+index ("Teststring", "t")
+     @result{} 4
+ at end group
+ at end example
+
+If @var{direction} is @samp{"first"}, return the first element found.
+If @var{direction} is @samp{"last"}, return the last element found.
+The @code{rindex} function is equivalent to @code{index} with
+ at var{direction} set to @samp{"last"}.
+
+ at strong{Caution:}  This function does not work for arrays of
+character strings.
+ at seealso{find, rindex}
+ at end deftypefn
+strjust
+ at c ./strings/strjust.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strjust (@var{s}, ["left"|"right"|"center"])
+Shift the non-blank text of @var{s} to the left, right or center of
+the string.  If @var{s} is a string array, justify each string in the
+array.  Null characters are replaced by blanks.  If no justification
+is specified, then all rows are right-justified.  For example:
+
+ at example
+ at group
+strjust (["a"; "ab"; "abc"; "abcd"])
+     @result{} ans =
+           a
+          ab
+         abc
+        abcd
+ at end group
+ at end example
+ at end deftypefn
+strchr
+ at c ./strings/strchr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{idx} =} strchr (@var{str}, @var{chars})
+ at deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n})
+ at deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n}, @var{direction})
+Search for the string @var{str} for occurrences of characters from the set @var{chars}.
+The return value, as well as the @var{n} and @var{direction} arguments behave
+identically as in @code{find}.
+
+This will be faster than using regexp in most cases.
+
+ at seealso{find}
+ at end deftypefn
+regexptranslate
+ at c ./strings/regexptranslate.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} regexptranslate (@var{op}, @var{s})
+Translate a string for use in a regular expression.  This might
+include either wildcard replacement or special character escaping.
+The behavior can be controlled by the @var{op} that can have the
+values
+
+ at table @asis
+ at item "wildcard"
+The wildcard characters @code{.}, @code{*} and @code{?} are replaced
+with wildcards that are appropriate for a regular expression. 
+For example:
+ at example
+ at group
+regexptranslate ("wildcard", "*.m")
+     @result{} ".*\.m"
+ at end group
+ at end example
+
+ at item "escape"
+The characters @code{$.?[]}, that have special meaning for regular
+expressions are escaped so that they are treated literally.  For example:
+ at example
+ at group
+regexptranslate ("escape", "12.5")
+     @result{} "12\.5"
+ at end group
+ at end example
+ at end table
+ at seealso{regexp, regexpi, regexprep}
+ at end deftypefn
+rindex
+ at c ./strings/rindex.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rindex (@var{s}, @var{t})
+Return the position of the last occurrence of the character string
+ at var{t} in the character string @var{s}, or 0 if no occurrence is
+found.  For example,
+
+ at example
+ at group
+rindex ("Teststring", "t")
+     @result{} 6
+ at end group
+ at end example
+
+ at strong{Caution:}  This function does not work for arrays of
+character strings.
+ at seealso{find, index}
+ at end deftypefn
+glpk
+ at c ./optimization/glpk.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{status}, @var{extra}] =} glpk (@var{c}, @var{a}, @var{b}, @var{lb}, @var{ub}, @var{ctype}, @var{vartype}, @var{sense}, @var{param})
+Solve a linear program using the GNU GLPK library.  Given three
+arguments, @code{glpk} solves the following standard LP:
+
+ at tex
+$$
+  \min_x C^T x
+$$
+ at end tex
+ at ifnottex
+ at example
+min C'*x
+ at end example
+ at end ifnottex
+
+subject to
+
+ at tex
+$$
+  Ax = b \qquad x \geq 0
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+A*x  = b
+  x >= 0
+ at end group
+ at end example
+ at end ifnottex
+
+but may also solve problems of the form
+
+ at tex
+$$
+  [ \min_x | \max_x ] C^T x
+$$
+ at end tex
+ at ifnottex
+ at example
+[ min | max ] C'*x
+ at end example
+ at end ifnottex
+
+subject to
+
+ at tex
+$$
+ Ax [ = | \leq | \geq ] b \qquad LB \leq x \leq UB
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+A*x [ "=" | "<=" | ">=" ] b
+  x >= LB
+  x <= UB
+ at end group
+ at end example
+ at end ifnottex
+
+Input arguments:
+
+ at table @var
+ at item c
+A column array containing the objective function coefficients.
+
+ at item a
+A matrix containing the constraints coefficients.
+
+ at item b
+A column array containing the right-hand side value for each constraint
+in the constraint matrix.
+
+ at item lb
+An array containing the lower bound on each of the variables.  If
+ at var{lb} is not supplied, the default lower bound for the variables is
+zero.
+
+ at item ub
+An array containing the upper bound on each of the variables.  If
+ at var{ub} is not supplied, the default upper bound is assumed to be
+infinite.
+
+ at item ctype
+An array of characters containing the sense of each constraint in the
+constraint matrix.  Each element of the array may be one of the
+following values
+ at table @code
+ at item "F"
+A free (unbounded) constraint (the constraint is ignored).
+ at item "U"
+An inequality constraint with an upper bound (@code{A(i,:)*x <= b(i)}).
+ at item "S"
+An equality constraint (@code{A(i,:)*x = b(i)}).
+ at item "L"
+An inequality with a lower bound (@code{A(i,:)*x >= b(i)}).
+ at item "D"
+An inequality constraint with both upper and lower bounds
+(@code{A(i,:)*x >= -b(i)} @emph{and} (@code{A(i,:)*x <= b(i)}).
+ at end table
+
+ at item vartype
+A column array containing the types of the variables.
+ at table @code
+ at item "C"
+A continuous variable.
+ at item "I"
+An integer variable.
+ at end table
+
+ at item sense
+If @var{sense} is 1, the problem is a minimization.  If @var{sense} is
+-1, the problem is a maximization.  The default value is 1.
+
+ at item param
+A structure containing the following parameters used to define the
+behavior of solver.  Missing elements in the structure take on default
+values, so you only need to set the elements that you wish to change
+from the default.
+
+Integer parameters:
+
+ at table @code
+ at item msglev (@code{LPX_K_MSGLEV}, default: 1)
+Level of messages output by solver routines:
+ at table @asis
+ at item 0
+No output.
+ at item 1
+Error messages only.
+ at item 2
+Normal output .
+ at item 3
+Full output (includes informational messages).
+ at end table
+
+ at item scale (@code{LPX_K_SCALE}, default: 1)
+Scaling option: 
+ at table @asis
+ at item 0
+No scaling.
+ at item 1
+Equilibration scaling.
+ at item 2
+Geometric mean scaling, then equilibration scaling.
+ at end table
+
+ at item dual	 (@code{LPX_K_DUAL}, default: 0)
+Dual simplex option:
+ at table @asis
+ at item 0
+Do not use the dual simplex.
+ at item 1
+If initial basic solution is dual feasible, use the dual simplex.
+ at end table
+
+ at item price	 (@code{LPX_K_PRICE}, default: 1)
+Pricing option (for both primal and dual simplex):
+ at table @asis
+ at item 0
+Textbook pricing.
+ at item 1
+Steepest edge pricing.
+ at end table
+  
+ at item round	 (@code{LPX_K_ROUND}, default: 0)
+Solution rounding option:
+ at table @asis
+ at item 0
+Report all primal and dual values "as is".
+ at item 1
+Replace tiny primal and dual values by exact zero.
+ at end table
+
+ at item itlim	 (@code{LPX_K_ITLIM}, default: -1)
+Simplex iterations limit.  If this value is positive, it is decreased by
+one each time when one simplex iteration has been performed, and
+reaching zero value signals the solver to stop the search.  Negative
+value means no iterations limit.
+
+ at item itcnt (@code{LPX_K_OUTFRQ}, default: 200)
+Output frequency, in iterations.  This parameter specifies how
+frequently the solver sends information about the solution to the
+standard output.
+
+ at item branch (@code{LPX_K_BRANCH}, default: 2)
+Branching heuristic option (for MIP only):
+ at table @asis
+ at item 0
+Branch on the first variable.
+ at item 1
+Branch on the last variable.
+ at item 2
+Branch using a heuristic by Driebeck and Tomlin.
+ at end table
+
+ at item btrack (@code{LPX_K_BTRACK}, default: 2)
+Backtracking heuristic option (for MIP only):
+ at table @asis
+ at item 0
+Depth first search.
+ at item 1
+Breadth first search.
+ at item 2
+Backtrack using the best projection heuristic.
+ at end table        
+
+ at item presol (@code{LPX_K_PRESOL}, default: 1)
+If this flag is set, the routine lpx_simplex solves the problem using
+the built-in LP presolver.  Otherwise the LP presolver is not used.
+
+ at item lpsolver (default: 1)
+Select which solver to use.  If the problem is a MIP problem this flag
+will be ignored.
+ at table @asis
+ at item 1
+Revised simplex method.
+ at item 2
+Interior point method.
+ at end table
+ at item save (default: 0)
+If this parameter is nonzero, save a copy of the problem in
+CPLEX LP format to the file @file{"outpb.lp"}.  There is currently no
+way to change the name of the output file.
+ at end table
+
+Real parameters:
+
+ at table @code
+ at item relax (@code{LPX_K_RELAX}, default: 0.07)
+Relaxation parameter used in the ratio test.  If it is zero, the textbook
+ratio test is used.  If it is non-zero (should be positive), Harris'
+two-pass ratio test is used.  In the latter case on the first pass of the
+ratio test basic variables (in the case of primal simplex) or reduced
+costs of non-basic variables (in the case of dual simplex) are allowed
+to slightly violate their bounds, but not more than
+ at code{relax*tolbnd} or @code{relax*toldj (thus, @code{relax} is a
+percentage of @code{tolbnd} or @code{toldj}}.
+
+ at item tolbnd (@code{LPX_K_TOLBND}, default: 10e-7)
+Relative tolerance used to check if the current basic solution is primal
+feasible.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+ at item toldj (@code{LPX_K_TOLDJ}, default: 10e-7)
+Absolute tolerance used to check if the current basic solution is dual
+feasible.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+ at item tolpiv (@code{LPX_K_TOLPIV}, default: 10e-9)
+Relative tolerance used to choose eligible pivotal elements of the
+simplex table.  It is not recommended that you change this parameter unless you
+have a detailed understanding of its purpose.
+
+ at item objll (@code{LPX_K_OBJLL}, default: -DBL_MAX)
+Lower limit of the objective function.  If on the phase II the objective
+function reaches this limit and continues decreasing, the solver stops
+the search.  This parameter is used in the dual simplex method only.
+
+ at item objul (@code{LPX_K_OBJUL}, default: +DBL_MAX)
+Upper limit of the objective function.  If on the phase II the objective
+function reaches this limit and continues increasing, the solver stops
+the search.  This parameter is used in the dual simplex only.
+
+ at item tmlim (@code{LPX_K_TMLIM}, default: -1.0)
+Searching time limit, in seconds.  If this value is positive, it is
+decreased each time when one simplex iteration has been performed by the
+amount of time spent for the iteration, and reaching zero value signals
+the solver to stop the search.  Negative value means no time limit.
+
+ at item outdly (@code{LPX_K_OUTDLY}, default: 0.0)
+Output delay, in seconds.  This parameter specifies how long the solver
+should delay sending information about the solution to the standard
+output.  Non-positive value means no delay.
+
+ at item tolint (@code{LPX_K_TOLINT}, default: 10e-5)
+Relative tolerance used to check if the current basic solution is integer
+feasible.  It is not recommended that you change this parameter unless
+you have a detailed understanding of its purpose.
+
+ at item tolobj (@code{LPX_K_TOLOBJ}, default: 10e-7)
+Relative tolerance used to check if the value of the objective function
+is not better than in the best known integer feasible solution.  It is
+not recommended that you change this parameter unless you have a
+detailed understanding of its purpose.
+ at end table
+ at end table
+
+Output values:
+
+ at table @var
+ at item xopt
+The optimizer (the value of the decision variables at the optimum).
+ at item fopt
+The optimum value of the objective function.
+ at item status
+Status of the optimization.
+
+Simplex Method:
+ at table @asis
+ at item 180 (@code{LPX_OPT})
+Solution is optimal.
+ at item 181 (@code{LPX_FEAS})
+Solution is feasible.
+ at item 182 (@code{LPX_INFEAS})
+Solution is infeasible.
+ at item 183 (@code{LPX_NOFEAS})
+Problem has no feasible solution.
+ at item 184 (@code{LPX_UNBND})
+Problem has no unbounded solution.
+ at item 185 (@code{LPX_UNDEF})
+Solution status is undefined.
+ at end table
+Interior Point Method:
+ at table @asis
+ at item 150 (@code{LPX_T_UNDEF})
+The interior point method is undefined.
+ at item 151 (@code{LPX_T_OPT})
+The interior point method is optimal.
+ at end table
+Mixed Integer Method:
+ at table @asis
+ at item 170 (@code{LPX_I_UNDEF})
+The status is undefined.
+ at item 171 (@code{LPX_I_OPT})
+The solution is integer optimal.
+ at item 172 (@code{LPX_I_FEAS})
+Solution integer feasible but its optimality has not been proven
+ at item 173 (@code{LPX_I_NOFEAS})
+No integer feasible solution.
+ at end table
+ at noindent
+If an error occurs, @var{status} will contain one of the following
+codes:
+
+ at table @asis
+ at item 204 (@code{LPX_E_FAULT})
+Unable to start the search.
+ at item 205 (@code{LPX_E_OBJLL})
+Objective function lower limit reached.
+ at item 206 (@code{LPX_E_OBJUL})
+Objective function upper limit reached.
+ at item 207 (@code{LPX_E_ITLIM})
+Iterations limit exhausted.
+ at item 208 (@code{LPX_E_TMLIM})
+Time limit exhausted.
+ at item 209 (@code{LPX_E_NOFEAS})
+No feasible solution.
+ at item 210 (@code{LPX_E_INSTAB})
+Numerical instability.
+ at item 211 (@code{LPX_E_SING})
+Problems with basis matrix.
+ at item 212 (@code{LPX_E_NOCONV})
+No convergence (interior).
+ at item 213 (@code{LPX_E_NOPFS})
+No primal feasible solution (LP presolver).
+ at item 214 (@code{LPX_E_NODFS})
+No dual feasible solution (LP presolver).
+ at end table
+ at item extra
+A data structure containing the following fields:
+ at table @code
+ at item lambda
+Dual variables.
+ at item redcosts
+Reduced Costs.
+ at item time
+Time (in seconds) used for solving LP/MIP problem.
+ at item mem
+Memory (in bytes) used for solving LP/MIP problem (this is not 
+available if the version of GLPK is 4.15 or later).
+ at end table
+ at end table
+
+Example:
+
+ at example
+ at group
+c = [10, 6, 4]';
+a = [ 1, 1, 1;
+     10, 4, 5;
+      2, 2, 6];
+b = [100, 600, 300]';
+lb = [0, 0, 0]';
+ub = [];
+ctype = "UUU";
+vartype = "CCC";
+s = -1;
+
+param.msglev = 1;
+param.itlim = 100;
+
+[xmin, fmin, status, extra] = @dots{}
+   glpk (c, a, b, lb, ub, ctype, vartype, s, param);
+ at end group
+ at end example
+ at end deftypefn
+lsqnonneg
+ at c ./optimization/lsqnonneg.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} lsqnonneg (@var{c}, @var{d})
+ at deftypefnx {Function File} {@var{x} =} lsqnonneg (@var{c}, @var{d}, @var{x0})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}, @var{output}] =} lsqnonneg (@dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}, @var{output}, @var{lambda}] =} lsqnonneg (@dots{})
+Minimize @code{norm (@var{c}*@var{x}-d)} subject to @code{@var{x} >=
+0}.  @var{c} and @var{d} must be real.  @var{x0} is an optional
+initial guess for @var{x}.
+
+Outputs:
+ at itemize @bullet
+ at item resnorm
+
+The squared 2-norm of the residual: norm(@var{c}*@var{x}- at var{d})^2
+ at item residual
+
+The residual: @var{d}- at var{c}*@var{x}
+ at item exitflag
+
+An indicator of convergence.  0 indicates that the iteration count
+was exceeded, and therefore convergence was not reached; >0 indicates
+that the algorithm converged.  (The algorithm is stable and will
+converge given enough iterations.)
+ at item output
+
+A structure with two fields:
+ at itemize @bullet
+ at item "algorithm": The algorithm used ("nnls")
+ at item "iterations": The number of iterations taken.
+ at end itemize
+ at item lambda
+
+Not implemented.
+ at end itemize
+ at seealso{optimset}
+ at end deftypefn
+__dogleg__
+ at c ./optimization/__dogleg__.m
+-*- texinfo -*-
+ at deftypefn{Function File} {@var{x}} = __dogleg__ (@var{r}, @var{b}, @var{x}, @var{d}, @var{delta}, @var{ismin})
+Solve the double dogleg trust-region problem:
+Minimize 
+ at example
+norm(@var{r}*@var{x}- at var{b}) 
+ at end example
+subject to the constraint 
+ at example
+norm(@var{d}.*@var{x}) <= @var{delta} ,
+ at end example
+x being a convex combination of the gauss-newton and scaled gradient.
+If @var{ismin} is true (default false), minimizes instead
+ at example
+norm(@var{r}*@var{x})^2-2*@var{b}'*@var{x} 
+ at end example
+ at end deftypefn
+fsolve
+ at c ./optimization/fsolve.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} fsolve (@var{fcn}, @var{x0}, @var{options})
+ at deftypefnx {Function File} {[@var{x}, @var{fvec}, @var{info}, @var{output}, @var{fjac}]} = fsolve (@var{fcn}, @dots{})
+Solve a system of nonlinear equations defined by the function @var{fcn}.
+ at var{fcn} should accepts a vector (array) defining the unknown variables,
+and return a vector of left-hand sides of the equations.  Right-hand sides
+are defined to be zeros.
+In other words, this function attempts to determine a vector @var{x} such 
+that @code{@var{fcn} (@var{x})} gives (approximately) all zeros.
+ at var{x0} determines a starting guess.  The shape of @var{x0} is preserved
+in all calls to @var{fcn}, but otherwise it is treated as a column vector.
+ at var{options} is a structure specifying additional options.
+Currently, @code{fsolve} recognizes these options:
+ at code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
+ at code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"}, 
+ at code{"Jacobian"}, @code{"Updating"} and @code{"ComplexEqn"}.
+
+If @code{"Jacobian"} is @code{"on"}, it specifies that @var{fcn},
+called with 2 output arguments, also returns the Jacobian matrix
+of right-hand sides at the requested point.  @code{"TolX"} specifies
+the termination tolerance in the unknown variables, while 
+ at code{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
+for both @code{"TolX"} and @code{"TolFun"}.
+If @code{"Updating"} is "on", the function will attempt to use Broyden
+updates to update the Jacobian, in order to reduce the amount of jacobian
+calculations.
+If your user function always calculates the Jacobian (regardless of number
+of output arguments), this option provides no advantage and should be set to
+false.
+
+ at code{"ComplexEqn"} is @code{"on"}, @code{fsolve} will attempt to solve
+complex equations in complex variables, assuming that the equations possess a
+complex derivative (i.e., are holomorphic).  If this is not what you want, 
+should unpack the real and imaginary parts of the system to get a real
+system.
+
+For description of the other options, see @code{optimset}.
+
+On return, @var{fval} contains the value of the function @var{fcn}
+evaluated at @var{x}, and @var{info} may be one of the following values:
+
+ at table @asis
+ at item 1
+Converged to a solution point.  Relative residual error is less than specified
+by TolFun.
+ at item 2
+Last relative step size was less that TolX.
+ at item 3
+Last relative decrease in residual was less than TolF. 
+ at item 0
+Iteration limit exceeded.
+ at item -3
+The trust region radius became excessively small. 
+ at end table
+
+Note: If you only have a single nonlinear equation of one variable, using 
+ at code{fzero} is usually a much better idea.
+ at seealso{fzero, optimset}
+
+Note about user-supplied jacobians:
+As an inherent property of the algorithm, jacobian is always requested for a
+solution vector whose residual vector is already known, and it is the last
+accepted successful step.  Often this will be one of the last two calls, but
+not always.  If the savings by reusing intermediate results from residual
+calculation in jacobian calculation are significant, the best strategy is to
+employ OutputFcn: After a vector is evaluated for residuals, if OutputFcn is
+called with that vector, then the intermediate results should be saved for
+future jacobian evaluation, and should be kept until a jacobian evaluation
+is requested or until outputfcn is called with a different vector, in which
+case they should be dropped in favor of this most recent vector.  A short
+example how this can be achieved follows:
+
+ at example
+function [fvec, fjac] = user_func (x, optimvalues, state)
+persistent sav = [], sav0 = [];
+if (nargin == 1)
+  ## evaluation call
+  if (nargout == 1)
+    sav0.x = x; # mark saved vector
+    ## calculate fvec, save results to sav0.
+  elseif (nargout == 2)
+    ## calculate fjac using sav.
+  endif
+else
+  ## outputfcn call.
+  if (all (x == sav0.x))
+    sav = sav0;
+  endif
+  ## maybe output iteration status, etc.
+endif
+endfunction
+
+ @dots{}.
+
+fsolve (@@user_func, x0, optimset ("OutputFcn", @@user_func, @dots{}))
+ at end example
+
+ at end deftypefn
+__all_opts__
+ at c ./optimization/__all_opts__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{names} =} __all_opts__ (@dots{})
+Undocumented internal function.
+ at end deftypefn
+optimget
+ at c ./optimization/optimget.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} optimget (@var{options}, @var{parname})
+ at deftypefnx {Function File} {} optimget (@var{options}, @var{parname}, @var{default})
+Return a specific option from a structure created by 
+ at code{optimset}.  If @var{parname} is not a field of the @var{options}
+structure, return @var{default} if supplied, otherwise return an 
+empty matrix.
+ at end deftypefn
+fzero
+ at c ./optimization/fzero.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{fval}, @var{info}, @var{output}] =} fzero (@var{fun}, @var{x0}, @var{options})
+Find a zero point of a univariate function.  @var{fun} should be a function
+handle or name.  @var{x0} specifies a starting point.  @var{options} is a
+structure specifying additional options.  Currently, @code{fzero}
+recognizes these options: @code{"FunValCheck"}, @code{"OutputFcn"},
+ at code{"TolX"}, @code{"MaxIter"}, @code{"MaxFunEvals"}. 
+For description of these options, see @ref{doc-optimset,,optimset}.
+
+On exit, the function returns @var{x}, the approximate zero point
+and @var{fval}, the function value thereof.
+ at var{info} is an exit flag that can have these values:
+ at itemize
+ at item 1
+The algorithm converged to a solution.
+ at item 0
+Maximum number of iterations or function evaluations has been exhausted.
+ at item -1
+The algorithm has been terminated from user output function.
+ at item -2 
+A general unexpected error.
+ at item -3
+A non-real value encountered.
+ at item -4
+A NaN value encountered.
+ at end itemize
+ at seealso{optimset, fsolve} 
+ at end deftypefn
+glpkmex
+ at c ./optimization/glpkmex.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{status}, @var{extra}] =} glpkmex (@var{sense}, @var{c}, @var{a}, @var{b}, @var{ctype}, @var{lb}, @var{ub}, @var{vartype}, @var{param}, @var{lpsolver}, @var{save_pb})
+This function is provided for compatibility with the old @sc{matlab}
+interface to the GNU GLPK library.  For Octave code, you should use
+the @code{glpk} function instead.
+ at end deftypefn
+__fdjac__
+ at c ./optimization/__fdjac__.m
+-*- texinfo -*-
+ at deftypefn{Function File} {} __fdjac__ (@var{fcn}, @var{x}, @var{fvec}, @var{err})
+Undocumented internal function.
+ at end deftypefn
+qp
+ at c ./optimization/qp.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb}, @var{A_in}, @var{A_ub})
+Solve the quadratic program
+ at tex
+$$
+ \min_x {1 \over 2} x^T H x + x^T q
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     min 0.5 x'*H*x + x'*q
+      x
+ at end group
+ at end example
+
+ at end ifnottex
+subject to
+ at tex
+$$
+ Ax = b \qquad lb \leq x \leq ub \qquad A_{lb} \leq A_{in} \leq A_{ub}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     A*x = b
+     lb <= x <= ub
+     A_lb <= A_in*x <= A_ub
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+using a null-space active-set method.
+
+Any bound (@var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb},
+ at var{A_ub}) may be set to the empty matrix (@code{[]}) if not
+present.  If the initial guess is feasible the algorithm is faster.
+
+The value @var{info} is a structure with the following fields:
+ at table @code
+ at item solveiter
+The number of iterations required to find the solution.
+ at item info
+An integer indicating the status of the solution, as follows:
+ at table @asis
+ at item 0
+The problem is feasible and convex.  Global solution found.
+ at item 1
+The problem is not convex.  Local solution found.
+ at item 2
+The problem is not convex and unbounded.
+ at item 3
+Maximum number of iterations reached.
+ at item 6
+The problem is infeasible.
+ at end table
+ at end table
+ at end deftypefn
+fminunc
+ at c ./optimization/fminunc.m
+-*- texinfo -*-
+ at deftypefn{Function File} {} fminunc (@var{fcn}, @var{x0}, @var{options})
+ at deftypefnx{Function File} {[@var{x}, @var{fvec}, @var{info}, @var{output}, @var{fjac}]} = fminunc (@var{fcn}, @dots{})
+Solve a unconstrained optimization problem defined by the function @var{fcn}.
+ at var{fcn} should accepts a vector (array) defining the unknown variables,
+and return the objective function value, optionally with gradient.
+In other words, this function attempts to determine a vector @var{x} such 
+that @code{@var{fcn} (@var{x})} is a local minimum.
+ at var{x0} determines a starting guess. The shape of @var{x0} is preserved
+in all calls to @var{fcn}, but otherwise it is treated as a column vector.
+ at var{options} is a structure specifying additional options.
+Currently, @code{fminunc} recognizes these options:
+ at code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
+ at code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"}, 
+ at code{"GradObj"}, @code{"FinDiffType"}.
+
+If @code{"GradObj"} is @code{"on"}, it specifies that @var{fcn},
+called with 2 output arguments, also returns the Jacobian matrix
+of right-hand sides at the requested point.  @code{"TolX"} specifies
+the termination tolerance in the unknown variables, while 
+ at code{"TolFun"} is a tolerance for equations. Default is @code{1e-7}
+for both @code{"TolX"} and @code{"TolFun"}.
+
+For description of the other options, see @code{optimset}.
+
+On return, @var{fval} contains the value of the function @var{fcn}
+evaluated at @var{x}, and @var{info} may be one of the following values:
+
+ at table @asis
+ at item 1
+Converged to a solution point. Relative gradient error is less than specified
+by TolFun.
+ at item 2
+Last relative step size was less that TolX.
+ at item 3
+Last relative decrease in func value was less than TolF. 
+ at item 0
+Iteration limit exceeded.
+ at item -3
+The trust region radius became excessively small. 
+ at end table
+
+Note: If you only have a single nonlinear equation of one variable, using 
+ at code{fminbnd} is usually a much better idea.
+ at seealso{fminbnd, optimset}
+ at end deftypefn
+sqp
+ at c ./optimization/sqp.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{iter}, @var{nf}, @var{lambda}] =} sqp (@var{x}, @var{phi}, @var{g}, @var{h}, @var{lb}, @var{ub}, @var{maxiter}, @var{tolerance})
+Solve the nonlinear program
+ at tex
+$$
+\min_x \phi (x)
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     min phi (x)
+      x
+ at end group
+ at end example
+
+ at end ifnottex
+subject to
+ at tex
+$$
+ g(x) = 0 \qquad h(x) \geq 0 \qquad lb \leq x \leq ub
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+     g(x)  = 0
+     h(x) >= 0
+     lb <= x <= ub
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+using a successive quadratic programming method.
+
+The first argument is the initial guess for the vector @var{x}.
+
+The second argument is a function handle pointing to the objective
+function.  The objective function must be of the form
+
+ at example
+     y = phi (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{y} is a scalar.
+
+The second argument may also be a 2- or 3-element cell array of
+function handles.  The first element should point to the objective
+function, the second should point to a function that computes the
+gradient of the objective function, and the third should point to a
+function to compute the hessian of the objective function.  If the
+gradient function is not supplied, the gradient is computed by finite
+differences.  If the hessian function is not supplied, a BFGS update
+formula is used to approximate the hessian.
+
+If supplied, the gradient function must be of the form
+
+ at example
+g = gradient (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{g} is a vector.
+
+If supplied, the hessian function must be of the form
+
+ at example
+h = hessian (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{h} is a matrix.
+
+The third and fourth arguments are function handles pointing to
+functions that compute the equality constraints and the inequality
+constraints, respectively.
+
+If your problem does not have equality (or inequality) constraints,
+you may pass an empty matrix for @var{cef} (or @var{cif}).
+
+If supplied, the equality and inequality constraint functions must be
+of the form
+
+ at example
+r = f (x)
+ at end example
+
+ at noindent
+in which @var{x} is a vector and @var{r} is a vector.
+
+The third and fourth arguments may also be 2-element cell arrays of
+function handles.  The first element should point to the constraint
+function and the second should point to a function that computes the
+gradient of the constraint function:
+
+ at tex
+$$
+ \Bigg( {\partial f(x) \over \partial x_1}, 
+        {\partial f(x) \over \partial x_2}, \ldots,
+        {\partial f(x) \over \partial x_N} \Bigg)^T
+$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+                [ d f(x)   d f(x)        d f(x) ]
+    transpose ( [ ------   -----   ...   ------ ] )
+                [  dx_1     dx_2          dx_N  ]
+ at end group
+ at end example
+ at end ifnottex
+
+The fifth and sixth arguments are vectors containing lower and upper bounds
+on @var{x}.  These must be consistent with equality and inequality
+constraints @var{g} and @var{h}.  If the bounds are not specified, or are
+empty, they are set to - at var{realmax} and @var{realmax} by default.
+
+The seventh argument is max. number of iterations.  If not specified,
+the default value is 100.
+
+The eighth argument is tolerance for stopping criteria.  If not specified,
+the default value is @var{eps}.
+
+Here is an example of calling @code{sqp}:
+
+ at example
+function r = g (x)
+  r = [ sumsq(x)-10;
+        x(2)*x(3)-5*x(4)*x(5); 
+        x(1)^3+x(2)^3+1 ];
+endfunction
+
+function obj = phi (x)
+  obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+endfunction
+
+x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+
+[x, obj, info, iter, nf, lambda] = sqp (x0, @@phi, @@g, [])
+
+x =
+    
+  -1.71714
+   1.59571
+   1.82725
+  -0.76364
+  -0.76364
+     
+obj = 0.053950
+info = 101
+iter = 8
+nf = 10
+lambda =
+    
+  -0.0401627
+   0.0379578
+  -0.0052227
+ at end example
+
+The value returned in @var{info} may be one of the following:
+ at table @asis
+ at item 101
+The algorithm terminated because the norm of the last step was less
+than @code{tol * norm (x))} (the value of tol is currently fixed at
+ at code{sqrt (eps)}---edit @file{sqp.m} to modify this value.
+ at item 102
+The BFGS update failed.
+ at item 103
+The maximum number of iterations was reached (the maximum number of
+allowed iterations is currently fixed at 100---edit @file{sqp.m} to
+increase this value).
+ at end table
+ at seealso{qp}
+ at end deftypefn
+optimset
+ at c ./optimization/optimset.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} optimset ()
+ at deftypefnx {Function File} {} optimset (@var{par}, @var{val}, @dots{})
+ at deftypefnx {Function File} {} optimset (@var{old}, @var{par}, @var{val}, @dots{})
+ at deftypefnx {Function File} {} optimset (@var{old}, @var{new})
+Create options struct for optimization functions.
+ at end deftypefn
+acoth
+ at c ./elfun/acoth.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} acoth (@var{x})
+Compute the inverse hyperbolic cotangent of each element of @var{x}.
+ at seealso{coth}
+ at end deftypefn
+acotd
+ at c ./elfun/acotd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} acotd (@var{x})
+Compute the inverse cotangent in degrees for each element of @var{x}.
+ at seealso{cotd, acot}
+ at end deftypefn
+tand
+ at c ./elfun/tand.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} tand (@var{x})
+Compute the tangent for each element of @var{x} in degrees.  Returns zero 
+for elements where @code{@var{x}/180} is an integer and @code{Inf} for
+elements where @code{(@var{x}-90)/180} is an integer.
+ at seealso{atand, tan}
+ at end deftypefn
+acot
+ at c ./elfun/acot.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} acot (@var{x})
+Compute the inverse cotangent in radians for each element of @var{x}.
+ at seealso{cot, acotd}
+ at end deftypefn
+coth
+ at c ./elfun/coth.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} coth (@var{x})
+Compute the hyperbolic cotangent of each element of @var{x}.
+ at seealso{acoth}
+ at end deftypefn
+sec
+ at c ./elfun/sec.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} sec (@var{x})
+Compute the secant for each element of @var{x} in radians.
+ at seealso{asec, secd, sech}
+ at end deftypefn
+atand
+ at c ./elfun/atand.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} atand (@var{x})
+Compute the inverse tangent in degrees for each element of @var{x}.
+ at seealso{tand, atan}
+ at end deftypefn
+lcm
+ at c ./elfun/lcm.m
+-*- texinfo -*-
+ at deftypefn  {Mapping Function} {} lcm (@var{x})
+ at deftypefnx {Mapping Function} {} lcm (@var{x}, @dots{})
+Compute the least common multiple of the elements of @var{x}, or
+of the list of all arguments.  For example,
+
+ at example
+lcm (a1, @dots{}, ak)
+ at end example
+
+ at noindent
+is the same as
+
+ at example
+lcm ([a1, @dots{}, ak]).
+ at end example
+
+All elements must be the same size or scalar.
+ at seealso{factor, gcd}
+ at end deftypefn
+secd
+ at c ./elfun/secd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} secd (@var{x})
+Compute the secant for each element of @var{x} in degrees.
+ at seealso{asecd, sec}
+ at end deftypefn
+cotd
+ at c ./elfun/cotd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cotd (@var{x})
+Compute the cotangent for each element of @var{x} in degrees.
+ at seealso{acotd, cot}
+ at end deftypefn
+csch
+ at c ./elfun/csch.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} csch (@var{x})
+Compute the hyperbolic cosecant of each element of @var{x}.
+ at seealso{acsch}
+ at end deftypefn
+asind
+ at c ./elfun/asind.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} asind (@var{x})
+Compute the inverse sine in degrees for each element of @var{x}.
+ at seealso{sind, asin}
+ at end deftypefn
+asec
+ at c ./elfun/asec.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} asec (@var{x})
+Compute the inverse secant in radians for each element of @var{x}.
+ at seealso{sec, asecd}
+ at end deftypefn
+acosd
+ at c ./elfun/acosd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} acosd (@var{x})
+Compute the inverse cosine in degrees for each element of @var{x}.
+ at seealso{cosd, acos}
+ at end deftypefn
+acsc
+ at c ./elfun/acsc.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} acsc (@var{x})
+Compute the inverse cosecant in radians for each element of @var{x}.
+ at seealso{csc, acscd}
+ at end deftypefn
+csc
+ at c ./elfun/csc.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} csc (@var{x})
+Compute the cosecant for each element of @var{x} in radians.
+ at seealso{acsc, cscd, csch}
+ at end deftypefn
+cot
+ at c ./elfun/cot.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} cot (@var{x})
+Compute the cotangent for each element of @var{x} in radians.
+ at seealso{acot, cotd, coth}
+ at end deftypefn
+sind
+ at c ./elfun/sind.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sind (@var{x})
+Compute the sine for each element of @var{x} in degrees.  Returns zero 
+for elements where @code{@var{x}/180} is an integer.
+ at seealso{asind, sin}
+ at end deftypefn
+sech
+ at c ./elfun/sech.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} sech (@var{x})
+Compute the hyperbolic secant of each element of @var{x}.
+ at seealso{asech}
+ at end deftypefn
+asech
+ at c ./elfun/asech.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} asech (@var{x})
+Compute the inverse hyperbolic secant of each element of @var{x}.
+ at seealso{sech}
+ at end deftypefn
+asecd
+ at c ./elfun/asecd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} asecd (@var{x})
+Compute the inverse secant in degrees for each element of @var{x}.
+ at seealso{secd, asec}
+ at end deftypefn
+cosd
+ at c ./elfun/cosd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cosd (@var{x})
+Compute the cosine for each element of @var{x} in degrees.  Returns zero 
+for elements where @code{(@var{x}-90)/180} is an integer.
+ at seealso{acosd, cos}
+ at end deftypefn
+cscd
+ at c ./elfun/cscd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cscd (@var{x})
+Compute the cosecant for each element of @var{x} in degrees.
+ at seealso{acscd, csc}
+ at end deftypefn
+acscd
+ at c ./elfun/acscd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} acscd (@var{x})
+Compute the inverse cosecant in degrees for each element of @var{x}.
+ at seealso{cscd, acsc}
+ at end deftypefn
+acsch
+ at c ./elfun/acsch.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} acsch (@var{x})
+Compute the inverse hyperbolic cosecant of each element of @var{x}.
+ at seealso{csch}
+ at end deftypefn
+etreeplot
+ at c ./sparse/etreeplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} etreeplot (@var{tree})
+ at deftypefnx {Function File} {} etreeplot (@var{tree}, @var{node_style}, @var{edge_style})
+Plot the elimination tree of the matrix @var{s} or
+ at code{@var{s}+ at var{s}'}  if @var{s} in non-symmetric.  The optional
+parameters @var{line_style} and @var{edge_style} define the output
+style.
+ at seealso{treeplot, gplot}
+ at end deftypefn
+gplot
+ at c ./sparse/gplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gplot (@var{a}, @var{xy})
+ at deftypefnx {Function File} {} gplot (@var{a}, @var{xy}, @var{line_style})
+ at deftypefnx {Function File} {[@var{x}, @var{y}] =} gplot (@var{a}, @var{xy})
+Plot a graph defined by @var{A} and @var{xy} in the graph theory
+sense.  @var{A} is the adjacency matrix of the array to be plotted
+and @var{xy} is an @var{n}-by-2 matrix containing the coordinates of
+the nodes of the graph.
+
+The optional parameter @var{line_style} defines the output style for
+the plot.  Called with no output arguments the graph is plotted
+directly.  Otherwise, return the coordinates of the plot in @var{x}
+and @var{y}.
+ at seealso{treeplot, etreeplot, spy}
+ at end deftypefn
+spstats
+ at c ./sparse/spstats.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{s})
+ at deftypefnx {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{s}, @var{j})
+Return the stats for the non-zero elements of the sparse matrix @var{s}.
+ at var{count} is the number of non-zeros in each column, @var{mean}
+is the mean of the non-zeros in each column, and @var{var} is the  
+variance of the non-zeros in each column.
+
+Called with two input arguments, if @var{s} is the data and @var{j}
+is the bin number for the data, compute the stats for each bin.  In 
+this case, bins can contain data values of zero, whereas with 
+ at code{spstats (@var{s})} the zeros may disappear.
+ at end deftypefn
+treeplot
+ at c ./sparse/treeplot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} treeplot (@var{tree})
+ at deftypefnx {Function File} {} treeplot (@var{tree}, @var{line_style}, @var{edge_style})
+Produces a graph of tree or forest.  The first argument is vector of
+predecessors, optional parameters @var{line_style} and @var{edge_style}
+define the output style.  The complexity of the algorithm is O(n) in
+terms of is time and memory requirements.
+ at seealso{etreeplot, gplot}
+ at end deftypefn
+spones
+ at c ./sparse/spones.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} spones (@var{x})
+Replace the non-zero entries of @var{x} with ones.  This creates a
+sparse matrix with the same structure as @var{x}.
+ at end deftypefn
+nonzeros
+ at c ./sparse/nonzeros.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nonzeros (@var{s})
+Returns a vector of the non-zero values of the sparse matrix @var{s}.
+ at end deftypefn
+bicgstab
+ at c ./sparse/bicgstab.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bicgstab (@var{A}, @var{b})
+ at deftypefnx {Function File} {} bicgstab (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+This procedure attempts to solve a system of linear equations A*x = b for x.
+The @var{A} must be square, symmetric and positive definite real matrix N*N.
+The @var{b} must be a one column vector with a length of N.
+The @var{tol} specifies the tolerance of the method, the default value is 1e-6.
+The @var{maxit} specifies the maximum number of iterations, the default value is min(20,N).
+The @var{M1} specifies a preconditioner, can also be a function handler which returns M\X.
+The @var{M2} combined with @var{M1} defines preconditioner as preconditioner=M1*M2.
+The @var{x0} is the initial guess, the default value is zeros(N,1).
+
+The value @var{x} is a computed result of this procedure.
+The value @var{flag} can be 0 when we reach tolerance in @var{maxit} iterations, 1 when
+we don't reach tolerance in @var{maxit} iterations and 3 when the procedure stagnates.
+The value @var{relres} is a relative residual - norm(b-A*x)/norm(b).
+The value @var{iter} is an iteration number in which x was computed.
+The value @var{resvec} is a vector of @var{relres} for each iteration.
+
+ at end deftypefn
+treelayout
+ at c ./sparse/treelayout.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} treelayout (@var{Tree})
+ at deftypefnx {Function File} {} treelayout (@var{Tree}, @var{permutation})
+treelayout lays out a tree or a forest.  The first argument @var{Tree} is a vector of
+predecessors, optional parameter @var{permutation} is an optional postorder permutation.
+The complexity of the algorithm is O(n) in
+terms of time and memory requirements.
+ at seealso{etreeplot, gplot,treeplot}
+ at end deftypefn
+sphcat
+ at c ./sparse/sphcat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} sphcat (@var{a1}, @var{a2}, @dots{}, @var{aN})
+Return the horizontal concatenation of sparse matrices.  This function
+is obselete and @code{horzcat} should be used.
+ at seealso {spvcat, vertcat, horzcat, cat}
+ at end deftypefn
+sprandsym
+ at c ./sparse/sprandsym.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sprandsym (@var{n}, @var{d})
+ at deftypefnx {Function File} {} sprandsym (@var{s})
+Generate a symmetric random sparse matrix.  The size of the matrix will be
+ at var{n} by @var{n}, with a density of values given by @var{d}.
+ at var{d} should be between 0 and 1. Values will be normally
+distributed with mean of zero and variance 1.
+
+Note: sometimes the actual density may be a bit smaller than @var{d}. 
+This is unlikely to happen for large really sparse matrices.
+
+If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix @var{S} is non-zero in its lower
+triangular part.
+ at seealso{sprand, sprandn}
+ at end deftypefn
+cgs
+ at c ./sparse/cgs.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cgs (@var{A}, @var{b})
+ at deftypefnx {Function File} {} cgs (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+This procedure attempts to solve a system of linear equations A*x = b for x.
+The @var{A} must be square, symmetric and positive definite real matrix N*N.
+The @var{b} must be a one column vector with a length of N.
+The @var{tol} specifies the tolerance of the method, default value is 1e-6.
+The @var{maxit} specifies the maximum number of iteration, default value is MIN(20,N).
+The @var{M1} specifies a preconditioner, can also be a function handler which returns M\X.
+The @var{M2} combined with @var{M1} defines preconditioner as preconditioner=M1*M2.
+The @var{x0} is initial guess, default value is zeros(N,1).
+
+ at end deftypefn
+pcg
+ at c ./sparse/pcg.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} pcg (@var{a}, @var{b}, @var{tol}, @var{maxit}, @var{m1}, @var{m2}, @var{x0}, @dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}, @var{eigest}] =} pcg (@dots{})
+
+Solves the linear system of equations @code{@var{a} * @var{x} =
+ at var{b}} by means of the Preconditioned Conjugate Gradient iterative
+method.  The input arguments are
+
+ at itemize
+ at item
+ at var{a} can be either a square (preferably sparse) matrix or a
+function handle, inline function or string containing the name
+of a function which computes @code{@var{a} * @var{x}}.  In principle
+ at var{a} should be symmetric and positive definite; if @code{pcg}
+finds @var{a} to not be positive definite, you will get a warning
+message and the @var{flag} output parameter will be set.
+
+ at item
+ at var{b} is the right hand side vector.
+
+ at item
+ at var{tol} is the required relative tolerance for the residual error,
+ at code{@var{b} - @var{a} * @var{x}}.  The iteration stops if @code{norm
+(@var{b} - @var{a} * @var{x}) <= @var{tol} * norm (@var{b} - @var{a} *
+ at var{x0})}.  If @var{tol} is empty or is omitted, the function sets
+ at code{@var{tol} = 1e-6} by default.
+
+ at item
+ at var{maxit} is the maximum allowable number of iterations; if
+ at code{[]} is supplied for @code{maxit}, or @code{pcg} has less
+arguments, a default value equal to 20 is used.
+
+ at item
+ at var{m} = @var{m1} * @var{m2} is the (left) preconditioning matrix, so that the iteration is
+(theoretically) equivalent to solving by @code{pcg} @code{@var{P} *
+ at var{x} = @var{m} \ @var{b}}, with @code{@var{P} = @var{m} \ @var{a}}.
+Note that a proper choice of the preconditioner may dramatically
+improve the overall performance of the method.  Instead of matrices
+ at var{m1} and @var{m2}, the user may pass two functions which return 
+the results of applying the inverse of @var{m1} and @var{m2} to 
+a vector (usually this is the preferred way of using the preconditioner). 
+If @code{[]} is supplied for @var{m1}, or @var{m1} is omitted, no 
+preconditioning is applied.  If @var{m2} is omitted, @var{m} = @var{m1}
+will be used as preconditioner.
+
+ at item
+ at var{x0} is the initial guess.  If @var{x0} is empty or omitted, the 
+function sets @var{x0} to a zero vector by default.
+ at end itemize
+
+The arguments which follow @var{x0} are treated as parameters, and
+passed in a proper way to any of the functions (@var{a} or @var{m})
+which are passed to @code{pcg}.  See the examples below for further
+details.  The output arguments are
+
+ at itemize
+ at item
+ at var{x} is the computed approximation to the solution of
+ at code{@var{a} * @var{x} = @var{b}}.
+
+ at item
+ at var{flag} reports on the convergence.  @code{@var{flag} = 0} means
+the solution converged and the tolerance criterion given by @var{tol}
+is satisfied.  @code{@var{flag} = 1} means that the @var{maxit} limit
+for the iteration count was reached.  @code{@var{flag} = 3} reports that
+the (preconditioned) matrix was found not positive definite.
+
+ at item
+ at var{relres} is the ratio of the final residual to its initial value,
+measured in the Euclidean norm.
+
+ at item
+ at var{iter} is the actual number of iterations performed.
+
+ at item 
+ at var{resvec} describes the convergence history of the method.
+ at code{@var{resvec} (i,1)} is the Euclidean norm of the residual, and
+ at code{@var{resvec} (i,2)} is the preconditioned residual norm,
+after the (@var{i}-1)-th iteration, @code{@var{i} =
+1, 2, @dots{}, @var{iter}+1}.  The preconditioned residual norm
+is defined as
+ at code{norm (@var{r}) ^ 2 = @var{r}' * (@var{m} \ @var{r})} where
+ at code{@var{r} = @var{b} - @var{a} * @var{x}}, see also the
+description of @var{m}.  If @var{eigest} is not required, only
+ at code{@var{resvec} (:,1)} is returned.
+
+ at item
+ at var{eigest} returns the estimate for the smallest @code{@var{eigest}
+(1)} and largest @code{@var{eigest} (2)} eigenvalues of the
+preconditioned matrix @code{@var{P} = @var{m} \ @var{a}}.  In 
+particular, if no preconditioning is used, the estimates for the
+extreme eigenvalues of @var{a} are returned.  @code{@var{eigest} (1)}
+is an overestimate and @code{@var{eigest} (2)} is an underestimate, 
+so that @code{@var{eigest} (2) / @var{eigest} (1)} is a lower bound
+for @code{cond (@var{P}, 2)}, which nevertheless in the limit should
+theoretically be equal to the actual value of the condition number. 
+The method which computes @var{eigest} works only for symmetric positive
+definite @var{a} and @var{m}, and the user is responsible for
+verifying this assumption. 
+ at end itemize
+
+Let us consider a trivial problem with a diagonal matrix (we exploit the
+sparsity of A) 
+
+ at example
+ at group
+	n = 10; 
+	a = diag (sparse (1:n));
+	b = rand (n, 1);
+     [l, u, p, q] = luinc (a, 1.e-3);
+ at end group
+ at end example
+
+ at sc{Example 1:} Simplest use of @code{pcg}
+
+ at example
+  x = pcg(A,b)
+ at end example
+
+ at sc{Example 2:} @code{pcg} with a function which computes
+ at code{@var{a} * @var{x}}
+
+ at example
+ at group
+  function y = apply_a (x)
+    y = [1:N]'.*x; 
+  endfunction
+
+  x = pcg ("apply_a", b)
+ at end group
+ at end example
+
+ at sc{Example 3:} @code{pcg} with a preconditioner: @var{l} * @var{u}
+
+ at example
+x = pcg (a, b, 1.e-6, 500, l*u);
+ at end example
+
+ at sc{Example 4:} @code{pcg} with a preconditioner: @var{l} * @var{u}.
+Faster than @sc{Example 3} since lower and upper triangular matrices 
+are easier to invert
+
+ at example
+x = pcg (a, b, 1.e-6, 500, l, u);
+ at end example
+
+ at sc{Example 5:} Preconditioned iteration, with full diagnostics.  The
+preconditioner (quite strange, because even the original matrix
+ at var{a} is trivial) is defined as a function
+
+ at example
+ at group
+  function y = apply_m (x)
+    k = floor (length (x) - 2);
+    y = x;
+    y(1:k) = x(1:k)./[1:k]';
+  endfunction
+
+  [x, flag, relres, iter, resvec, eigest] = ...
+                     pcg (a, b, [], [], "apply_m");
+  semilogy (1:iter+1, resvec);
+ at end group
+ at end example
+
+ at sc{Example 6:} Finally, a preconditioner which depends on a
+parameter @var{k}.
+
+ at example
+ at group
+  function y = apply_M (x, varargin)
+  K = varargin@{1@}; 
+  y = x;
+  y(1:K) = x(1:K)./[1:K]';
+  endfunction
+
+  [x, flag, relres, iter, resvec, eigest] = ...
+       pcg (A, b, [], [], "apply_m", [], [], 3)
+ at end group
+ at end example
+
+ at sc{References}
+
+	[1] C.T.Kelley, 'Iterative methods for linear and nonlinear equations',
+	SIAM, 1995 (the base PCG algorithm) 
+	
+	[2] Y.Saad, 'Iterative methods for sparse linear systems', PWS 1996
+	(condition number estimate from PCG) Revised version of this book is
+	available online at http://www-users.cs.umn.edu/~saad/books.html
+
+
+ at seealso{sparse, pcr}
+ at end deftypefn
+spvcat
+ at c ./sparse/spvcat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} spvcat (@var{a1}, @var{a2}, @dots{}, @var{aN})
+Return the vertical concatenation of sparse matrices.  This function
+is obselete and @code{vertcat} should be used
+ at seealso{sphcat, vertcat, horzcat, cat}
+ at end deftypefn
+normest
+ at c ./sparse/normest.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{n}, @var{c}] =} normest (@var{a}, @var{tol})
+Estimate the 2-norm of the matrix @var{a} using a power series
+analysis.  This is typically used for large matrices, where the cost
+of calculating the @code{norm (@var{a})} is prohibitive and an approximation
+to the 2-norm is acceptable.
+
+ at var{tol} is the tolerance to which the 2-norm is calculated.  By default
+ at var{tol} is 1e-6.  @var{c} returns the number of iterations needed for
+ at code{normest} to converge.
+ at end deftypefn
+pcr
+ at c ./sparse/pcr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} pcr (@var{a}, @var{b}, @var{tol}, @var{maxit}, @var{m}, @var{x0}, @dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} pcr (@dots{})
+
+Solves the linear system of equations @code{@var{a} * @var{x} =
+ at var{b}} by means of the Preconditioned Conjugate Residuals iterative
+method.  The input arguments are
+
+ at itemize
+ at item
+ at var{a} can be either a square (preferably sparse) matrix or a
+function handle, inline function or string containing the name
+of a function which computes @code{@var{a} * @var{x}}.  In principle
+ at var{a} should be symmetric and non-singular; if @code{pcr}
+finds @var{a} to be numerically singular, you will get a warning
+message and the @var{flag} output parameter will be set.
+
+ at item
+ at var{b} is the right hand side vector.
+
+ at item
+ at var{tol} is the required relative tolerance for the residual error,
+ at code{@var{b} - @var{a} * @var{x}}.  The iteration stops if @code{norm
+(@var{b} - @var{a} * @var{x}) <= @var{tol} * norm (@var{b} - @var{a} *
+ at var{x0})}.  If @var{tol} is empty or is omitted, the function sets
+ at code{@var{tol} = 1e-6} by default.
+
+ at item
+ at var{maxit} is the maximum allowable number of iterations; if
+ at code{[]} is supplied for @code{maxit}, or @code{pcr} has less
+arguments, a default value equal to 20 is used.
+
+ at item
+ at var{m} is the (left) preconditioning matrix, so that the iteration is
+(theoretically) equivalent to solving by @code{pcr} @code{@var{P} *
+ at var{x} = @var{m} \ @var{b}}, with @code{@var{P} = @var{m} \ @var{a}}.
+Note that a proper choice of the preconditioner may dramatically
+improve the overall performance of the method.  Instead of matrix
+ at var{m}, the user may pass a function which returns the results of 
+applying the inverse of @var{m} to a vector (usually this is the
+preferred way of using the preconditioner).  If @code{[]} is supplied
+for @var{m}, or @var{m} is omitted, no preconditioning is applied.
+
+ at item
+ at var{x0} is the initial guess.  If @var{x0} is empty or omitted, the 
+function sets @var{x0} to a zero vector by default.
+ at end itemize
+
+The arguments which follow @var{x0} are treated as parameters, and
+passed in a proper way to any of the functions (@var{a} or @var{m})
+which are passed to @code{pcr}.  See the examples below for further
+details.  The output arguments are
+
+ at itemize
+ at item
+ at var{x} is the computed approximation to the solution of
+ at code{@var{a} * @var{x} = @var{b}}.
+
+ at item
+ at var{flag} reports on the convergence.  @code{@var{flag} = 0} means
+the solution converged and the tolerance criterion given by @var{tol}
+is satisfied.  @code{@var{flag} = 1} means that the @var{maxit} limit
+for the iteration count was reached.  @code{@var{flag} = 3} reports t
+ at code{pcr} breakdown, see [1] for details.
+
+ at item
+ at var{relres} is the ratio of the final residual to its initial value,
+measured in the Euclidean norm.
+
+ at item
+ at var{iter} is the actual number of iterations performed.
+
+ at item 
+ at var{resvec} describes the convergence history of the method,
+so that @code{@var{resvec} (i)} contains the Euclidean norms of the 
+residual after the (@var{i}-1)-th iteration, @code{@var{i} =
+1,2, @dots{}, @var{iter}+1}.
+ at end itemize
+
+Let us consider a trivial problem with a diagonal matrix (we exploit the
+sparsity of A) 
+
+ at example
+ at group
+	n = 10; 
+	a = sparse (diag (1:n));
+	b = rand (N, 1);
+ at end group
+ at end example
+
+ at sc{Example 1:} Simplest use of @code{pcr}
+
+ at example
+  x = pcr(A, b)
+ at end example
+
+ at sc{Example 2:} @code{pcr} with a function which computes
+ at code{@var{a} * @var{x}}.
+
+ at example
+ at group
+  function y = apply_a (x) 
+    y = [1:10]'.*x; 
+  endfunction
+
+  x = pcr ("apply_a", b)
+ at end group
+ at end example
+
+ at sc{Example 3:}  Preconditioned iteration, with full diagnostics.  The
+preconditioner (quite strange, because even the original matrix
+ at var{a} is trivial) is defined as a function
+
+ at example
+ at group
+  function y = apply_m (x)		
+    k = floor (length(x)-2); 
+    y = x; 
+    y(1:k) = x(1:k)./[1:k]';	
+  endfunction
+
+  [x, flag, relres, iter, resvec] = ...
+                     pcr (a, b, [], [], "apply_m")
+  semilogy([1:iter+1], resvec);
+ at end group
+ at end example
+
+ at sc{Example 4:} Finally, a preconditioner which depends on a
+parameter @var{k}.
+
+ at example
+ at group
+  function y = apply_m (x, varargin)
+    k = varargin@{1@}; 
+    y = x; y(1:k) = x(1:k)./[1:k]';	 
+  endfunction
+
+  [x, flag, relres, iter, resvec] = ...
+                     pcr (a, b, [], [], "apply_m"', [], 3)
+ at end group
+ at end example
+
+ at sc{References}
+
+	[1] W. Hackbusch, "Iterative Solution of Large Sparse Systems of
+ 	Equations", section 9.5.4; Springer, 1994
+
+ at seealso{sparse, pcg}
+ at end deftypefn
+spy
+ at c ./sparse/spy.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spy (@var{x})
+ at deftypefnx {Function File} {} spy (@dots{}, @var{markersize})
+ at deftypefnx {Function File} {} spy (@dots{}, @var{line_spec})
+Plot the sparsity pattern of the sparse matrix @var{x}.  If the argument
+ at var{markersize} is given as an scalar value, it is used to determine the
+point size in the plot.  If the string @var{line_spec} is given it is
+passed to @code{plot} and determines the appearance of the plot.
+ at seealso{plot}
+ at end deftypefn
+spconvert
+ at c ./sparse/spconvert.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} spconvert (@var{m})
+This function converts for a simple sparse matrix format easily
+produced by other programs into Octave's internal sparse format.  The
+input @var{x} is either a 3 or 4 column real matrix, containing
+the row, column, real and imaginary parts of the elements of the
+sparse matrix.  An element with a zero real and imaginary part can
+be used to force a particular matrix size.
+ at end deftypefn
+spalloc
+ at c ./sparse/spalloc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{s} =} spalloc (@var{r}, @var{c}, @var{nz})
+Returns an empty sparse matrix of size @var{r}-by- at var{c}.  As Octave
+resizes sparse matrices at the first opportunity, so that no additional 
+space is needed, the argument @var{nz} is ignored.  This function is 
+provided only for compatibility reasons.
+
+It should be noted that this means that code like
+
+ at example
+ at group
+k = 5;
+nz = r * k;
+s = spalloc (r, c, nz)
+for j = 1:c
+  idx = randperm (r);
+  s (:, j) = [zeros(r - k, 1); rand(k, 1)] (idx);
+endfor
+ at end group
+ at end example
+
+will reallocate memory at each step.  It is therefore vitally important
+that code like this is vectorized as much as possible.
+ at seealso{sparse, nzmax}
+ at end deftypefn
+svds
+ at c ./sparse/svds.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{s} =} svds (@var{a})
+ at deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k})
+ at deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k}, @var{sigma})
+ at deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Function File} {[@var{u}, @var{s}, @var{v}, @var{flag}] =} svds (@dots{})
+
+Find a few singular values of the matrix @var{a}.  The singular values
+are calculated using 
+
+ at example
+ at group
+[@var{m}, @var{n}] = size(@var{a})
+ at var{s} = eigs([sparse(@var{m}, @var{m}), @var{a}; ...
+                @var{a}', sparse(@var{n}, @var{n})])
+ at end group
+ at end example
+
+The eigenvalues returned by @code{eigs} correspond to the singular
+values of @var{a}.  The number of singular values to calculate is given
+by @var{k}, whose default value is 6.
+
+The argument @var{sigma} can be used to specify which singular values
+to find.  @var{sigma} can be either the string 'L', the default, in 
+which case the largest singular values of @var{a} are found.  Otherwise
+ at var{sigma} should be a real scalar, in which case the singular values
+closest to @var{sigma} are found.  Note that for relatively small values
+of @var{sigma}, there is the chance that the requested number of singular
+values are not returned.  In that case @var{sigma} should be increased.
+
+If @var{opts} is given, then it is a structure that defines options
+that @code{svds} will pass to @var{eigs}.  The possible fields of this
+structure are therefore determined by @code{eigs}.  By default three
+fields of this structure are set by @code{svds}.
+
+ at table @code
+ at item tol
+The required convergence tolerance for the singular values.  @code{eigs}
+is passed @var{tol} divided by @code{sqrt(2)}.  The default value is 
+1e-10.
+
+ at item maxit
+The maximum number of iterations.  The default is 300.
+
+ at item disp
+The level of diagnostic printout.  If @code{disp} is 0 then there is no
+printout.  The default value is 0.
+ at end table
+
+If more than one output argument is given, then @code{svds} also
+calculates the left and right singular vectors of @var{a}.  @var{flag}
+is used to signal the convergence of @code{svds}.  If @code{svds} 
+converges to the desired tolerance, then @var{flag} given by
+
+ at example
+ at group
+norm (@var{a} * @var{v} - @var{u} * @var{s}, 1) <= ...
+        @var{tol} * norm (@var{a}, 1)
+ at end group
+ at end example
+
+will be zero.
+ at end deftypefn
+ at seealso{eigs}
+spdiags
+ at c ./sparse/spdiags.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{b}, @var{c}] =} spdiags (@var{a})
+ at deftypefnx {Function File} {@var{b} =} spdiags (@var{a}, @var{c})
+ at deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{a})
+ at deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{m}, @var{n})
+A generalization of the function @code{diag}.  Called with a single
+input argument, the non-zero diagonals @var{c} of @var{A} are extracted.
+With two arguments the diagonals to extract are given by the vector 
+ at var{c}.
+
+The other two forms of @code{spdiags} modify the input matrix by
+replacing the diagonals.  They use the columns of @var{v} to replace
+the columns represented by the vector @var{c}.  If the sparse matrix
+ at var{a} is defined then the diagonals of this matrix are replaced.
+Otherwise a matrix of @var{m} by @var{n} is created with the
+diagonals given by @var{v}.
+
+Negative values of @var{c} represent diagonals below the main
+diagonal, and positive values of @var{c} diagonals above the main
+diagonal.
+
+For example
+
+ at example
+ at group
+spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
+ at result{}    5 10  0  0
+      1  6 11  0
+      0  2  7 12
+      0  0  3  8
+      0  0  0  4
+ at end group
+ at end example
+
+ at end deftypefn
+spfun
+ at c ./sparse/spfun.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} spfun (@var{f}, at var{x})
+Compute @code{f(@var{x})} for the non-zero values of @var{x}.
+This results in a sparse matrix with the same structure as 
+ at var{x}.  The function @var{f} can be passed as a string, a
+function handle or an inline function.
+ at end deftypefn
+colperm
+ at c ./sparse/colperm.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{p} =} colperm (@var{s})
+Returns the column permutations such that the columns of
+ at code{@var{s} (:, @var{p})} are ordered in terms of increase number
+of non-zero elements.  If @var{s} is symmetric, then @var{p} is chosen
+such that @code{@var{s} (@var{p}, @var{p})} orders the rows and
+columns with increasing number of non zeros elements.
+ at end deftypefn
+sprand
+ at c ./sparse/sprand.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sprand (@var{m}, @var{n}, @var{d})
+ at deftypefnx {Function File} {} sprand (@var{s})
+Generate a random sparse matrix.  The size of the matrix will be
+ at var{m} by @var{n}, with a density of values given by @var{d}.
+ at var{d} should be between 0 and 1. Values will be uniformly
+distributed between 0 and 1.
+
+Note: sometimes the actual density may be a bit smaller than @var{d}. 
+This is unlikely to happen for large really sparse matrices.
+
+If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix @var{S} is non-zero.
+ at seealso{sprandn}
+ at end deftypefn
+spaugment
+ at c ./sparse/spaugment.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{s} =} spaugment (@var{a}, @var{c})
+Creates the augmented matrix of @var{a}.  This is given by
+
+ at example
+ at group
+[@var{c} * eye(@var{m}, @var{m}), at var{a}; @var{a}', zeros(@var{n},
+ at var{n})]
+ at end group
+ at end example
+
+ at noindent
+This is related to the least squares solution of 
+ at code{@var{a} \\ @var{b}}, by
+
+ at example
+ at group
+ at var{s} * [ @var{r} / @var{c}; x] = [@var{b}, zeros(@var{n},
+columns(@var{b})]
+ at end group
+ at end example
+
+ at noindent
+where @var{r} is the residual error
+
+ at example
+ at var{r} = @var{b} - @var{a} * @var{x}
+ at end example
+
+As the matrix @var{s} is symmetric indefinite it can be factorized
+with @code{lu}, and the minimum norm solution can therefore be found
+without the need for a @code{qr} factorization.  As the residual
+error will be @code{zeros (@var{m}, @var{m})} for under determined
+problems, and example can be 
+
+ at example
+ at group
+m = 11; n = 10; mn = max(m ,n);
+a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],
+             [-1, 0, 1], m, n);
+x0 = a \ ones (m,1);
+s = spaugment (a);
+[L, U, P, Q] = lu (s);
+x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+x1 = x1(end - n + 1 : end);
+ at end group
+ at end example
+
+To find the solution of an overdetermined problem needs an estimate
+of the residual error @var{r} and so it is more complex to formulate
+a minimum norm solution using the @code{spaugment} function.
+
+In general the left division operator is more stable and faster than
+using the @code{spaugment} function.
+ at end deftypefn
+speye
+ at c ./sparse/speye.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} speye (@var{m})
+ at deftypefnx {Function File} {@var{y} =} speye (@var{m}, @var{n})
+ at deftypefnx {Function File} {@var{y} =} speye (@var{sz})
+Returns a sparse identity matrix.  This is significantly more
+efficient than @code{sparse (eye (@var{m}))} as the full matrix
+is not constructed.
+
+Called with a single argument a square matrix of size @var{m} by
+ at var{m} is created.  Otherwise a matrix of @var{m} by @var{n} is
+created.  If called with a single vector argument, this argument 
+is taken to be the size of the matrix to create.
+ at end deftypefn
+sprandn
+ at c ./sparse/sprandn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sprandn (@var{m}, @var{n}, @var{d})
+ at deftypefnx {Function File} {} sprandn (@var{s})
+Generate a random sparse matrix.  The size of the matrix will be
+ at var{m} by @var{n}, with a density of values given by @var{d}.
+ at var{d} should be between 0 and 1. Values will be normally
+distributed with mean of zero and variance 1.
+
+Note: sometimes the actual density may be a bit smaller than @var{d}. 
+This is unlikely to happen for large really sparse matrices.
+
+If called with a single matrix argument, a random sparse matrix is
+generated wherever the matrix @var{S} is non-zero.
+ at seealso{sprand}
+ at end deftypefn
+assert
+ at c ./testfun/assert.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} assert (@var{cond})
+ at deftypefnx {Function File} {} assert (@var{cond}, @var{errmsg}, @dots{})
+ at deftypefnx {Function File} {} assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
+ at deftypefnx {Function File} {} assert (@var{observed}, at var{expected})
+ at deftypefnx {Function File} {} assert (@var{observed}, at var{expected}, at var{tol})
+
+Produces an error if the condition is not met.  @code{assert} can be
+called in three different ways.
+
+ at table @code
+ at item assert (@var{cond})
+ at itemx assert (@var{cond}, @var{errmsg}, @dots{})
+ at itemx assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
+Called with a single argument @var{cond}, @code{assert} produces an
+error if @var{cond} is zero.  If called with a single argument a
+generic error message.  With more than one argument, the additional
+arguments are passed to the @code{error} function.
+
+ at item assert (@var{observed}, @var{expected})
+Produce an error if observed is not the same as expected.  Note that 
+observed and expected can be strings, scalars, vectors, matrices, 
+lists or structures.
+
+ at item assert(@var{observed}, @var{expected}, @var{tol})
+Accept a tolerance when comparing numbers. 
+If @var{tol} is positive use it as an absolute tolerance, will produce an error if
+ at code{abs(@var{observed} - @var{expected}) > abs(@var{tol})}.
+If @var{tol} is negative use it as a relative tolerance, will produce an error if
+ at code{abs(@var{observed} - @var{expected}) > abs(@var{tol} * @var{expected})}.
+If @var{expected} is zero @var{tol} will always be used as an absolute tolerance.
+ at end table
+ at seealso{test}
+ at end deftypefn
+rundemos
+ at c ./testfun/rundemos.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rundemos (@var{directory})
+ at end deftypefn
+example
+ at c ./testfun/example.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} example ('@var{name}', at var{n})
+ at deftypefnx {Function File} {[@var{x}, @var{idx}] =} example ('@var{name}', at var{n})
+
+ Display the code for example @var{n} associated with the function 
+'@var{name}', but do not run it.  If @var{n} is not given, all examples 
+are displayed.
+
+Called with output arguments, the examples are returned in the form of
+a string @var{x}, with @var{idx} indicating the ending position of the 
+various examples.
+
+See @code{demo} for a complete explanation.
+ at seealso{demo, test}
+ at end deftypefn
+speed
+ at c ./testfun/speed.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} speed (@var{f}, @var{init}, @var{max_n}, @var{f2}, @var{tol})
+ at deftypefnx {Function File} {[@var{order}, @var{n}, @var{T_f}, @var{T_f2}] =} speed (@dots{})
+
+Determine the execution time of an expression for various @var{n}.
+The @var{n} are log-spaced from 1 to @var{max_n}.  For each @var{n},
+an initialization expression is computed to create whatever data
+are needed for the test.  If a second expression is given, the
+execution times of the two expressions will be compared.  Called 
+without output arguments the results are presented graphically.
+
+ at table @code
+ at item @var{f}
+The expression to evaluate.
+
+ at item @var{max_n}
+The maximum test length to run.  Default value is 100.  Alternatively,
+use @code{[min_n,max_n]} or for complete control, @code{[n1,n2, at dots{},nk]}.
+
+ at item @var{init}
+Initialization expression for function argument values.  Use @var{k} 
+for the test number and @var{n} for the size of the test.  This should
+compute values for all variables listed in args.  Note that init will
+be evaluated first for @math{k = 0}, so things which are constant throughout
+the test can be computed then.  The default value is @code{@var{x} =
+randn (@var{n}, 1);}.
+
+ at item @var{f2}
+An alternative expression to evaluate, so the speed of the two
+can be compared.  Default is @code{[]}.
+
+ at item @var{tol}
+If @var{tol} is @code{Inf}, then no comparison will be made between the
+results of expression @var{f} and expression @var{f2}.  Otherwise,
+expression @var{f} should produce a value @var{v} and expression @var{f2} 
+should produce a value @var{v2}, and these shall be compared using 
+ at code{assert(@var{v}, at var{v2}, at var{tol})}.  If @var{tol} is positive,
+the tolerance is assumed to be absolute.  If @var{tol} is negative,
+the tolerance is assumed to be relative.  The default is @code{eps}.
+
+ at item @var{order}
+The time complexity of the expression @code{O(a n^p)}.  This
+is a structure with fields @code{a} and @code{p}.
+
+ at item @var{n}
+The values @var{n} for which the expression was calculated and
+the execution time was greater than zero.
+
+ at item @var{T_f}
+The nonzero execution times recorded for the expression @var{f} in seconds.
+
+ at item @var{T_f2}
+The nonzero execution times recorded for the expression @var{f2} in seconds.
+If it is needed, the mean time ratio is just @code{mean(T_f./T_f2)}.
+
+ at end table
+
+The slope of the execution time graph shows the approximate
+power of the asymptotic running time @code{O(n^p)}.  This
+power is plotted for the region over which it is approximated
+(the latter half of the graph).  The estimated power is not
+very accurate, but should be sufficient to determine the
+general order of your algorithm.  It should indicate if for 
+example your implementation is unexpectedly @code{O(n^2)} 
+rather than @code{O(n)} because it extends a vector each 
+time through the loop rather than preallocating one which is 
+big enough.  For example, in the current version of Octave,
+the following is not the expected @code{O(n)}:
+
+ at example
+speed ("for i = 1:n, y@{i@} = x(i); end", "", [1000,10000])
+ at end example
+
+but it is if you preallocate the cell array @code{y}:
+
+ at example
+ at group
+speed ("for i = 1:n, y@{i@} = x(i); end", ...
+       "x = rand (n, 1); y = cell (size (x));", [1000, 10000])
+ at end group
+ at end example
+
+An attempt is made to approximate the cost of the individual 
+operations, but it is wildly inaccurate.  You can improve the
+stability somewhat by doing more work for each @code{n}.  For
+example:
+
+ at example
+speed ("airy(x)", "x = rand (n, 10)", [10000, 100000])
+ at end example
+
+When comparing a new and original expression, the line on the
+speedup ratio graph should be larger than 1 if the new expression
+is faster.  Better algorithms have a shallow slope.  Generally, 
+vectorizing an algorithm will not change the slope of the execution 
+time graph, but it will shift it relative to the original.  For
+example:
+
+ at example
+ at group
+speed ("v = sum (x)", "", [10000, 100000], ...
+       "v = 0; for i = 1:length (x), v += x(i); end")
+ at end group
+ at end example
+
+A more complex example, if you had an original version of @code{xcorr}
+using for loops and another version using an FFT, you could compare the
+run speed for various lags as follows, or for a fixed lag with varying
+vector lengths as follows:
+
+ at example
+ at group
+speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100,
+       "v2 = xcorr_orig (x, n)", -100*eps)
+speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100,
+       "v2 = xcorr_orig (x, n)", -100*eps)
+ at end group
+ at end example
+
+Assuming one of the two versions is in @var{xcorr_orig}, this
+would compare their speed and their output values.  Note that the
+FFT version is not exact, so we specify an acceptable tolerance on
+the comparison @code{100*eps}, and the errors should be computed
+relatively, as @code{abs((@var{x} - @var{y})./@var{y})} rather than 
+absolutely as @code{abs(@var{x} - @var{y})}.
+
+Type @code{example('speed')} to see some real examples.  Note for 
+obscure reasons, you can't run examples 1 and 2 directly using 
+ at code{demo('speed')}.  Instead use, @code{eval(example('speed',1))}
+and @code{eval(example('speed',2))}.
+ at end deftypefn
+test
+ at c ./testfun/test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} test @var{name}
+ at deftypefnx {Function File} {} test @var{name} quiet|normal|verbose
+ at deftypefnx {Function File} {} test ('@var{name}', 'quiet|normal|verbose', @var{fid})
+ at deftypefnx {Function File} {} test ([], 'explain', @var{fid})
+ at deftypefnx {Function File} {@var{success} =} test (@dots{})
+ at deftypefnx {Function File} {[@var{n}, @var{max}] =} test (@dots{})
+ at deftypefnx {Function File} {[@var{code}, @var{idx}] =} test ('@var{name}','grabdemo')
+
+Perform tests from the first file in the loadpath matching @var{name}.
+ at code{test} can be called as a command or as a function.  Called with 
+a single argument @var{name}, the tests are run interactively and stop
+after the first error is encountered.
+
+With a second argument the tests which are performed and the amount of
+output is selected.
+
+ at table @asis
+ at item 'quiet'
+ Don't report all the tests as they happen, just the errors.
+
+ at item 'normal'
+Report all tests as they happen, but don't do tests which require 
+user interaction.
+
+ at item 'verbose'
+Do tests which require user interaction.
+ at end table
+
+The argument @var{fid} can be used to allow batch processing.  Errors
+can be written to the already open file defined by @var{fid}, and 
+hopefully when Octave crashes this file will tell you what was happening
+when it did.  You can use @code{stdout} if you want to see the results as
+they happen.  You can also give a file name rather than an @var{fid}, in
+which case the contents of the file will be replaced with the log from 
+the current test.
+
+Called with a single output argument @var{success}, @code{test} returns
+true if all of the tests were successful.  Called with two output arguments
+ at var{n} and @var{max}, the number of successful tests and the total number
+of tests in the file @var{name} are returned.
+
+If the second argument is the string 'grabdemo', the contents of the demo
+blocks are extracted but not executed.  Code for all code blocks is
+concatenated and returned as @var{code} with @var{idx} being a vector of
+positions of the ends of the demo blocks.
+
+If the second argument is 'explain', then @var{name} is ignored and an
+explanation of the line markers used is written to the file @var{fid}.
+ at seealso{error, assert, fail, demo, example}
+ at end deftypefn
+fail
+ at c ./testfun/fail.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fail (@var{code}, at var{pattern})
+ at deftypefnx {Function File} {} fail (@var{code},'warning', at var{pattern})
+
+Return true if @var{code} fails with an error message matching
+ at var{pattern}, otherwise produce an error.  Note that @var{code}
+is a string and if @var{code} runs successfully, the error produced is:
+
+ at example
+          expected error but got none  
+ at end example
+
+If the code fails with a different error, the message produced is:
+
+ at example
+ at group
+          expected <pattern>
+          but got <text of actual error>
+ at end group
+ at end example
+
+The angle brackets are not part of the output.
+
+Called with three arguments, the behavior is similar to 
+ at code{fail(@var{code}, @var{pattern})}, but produces an error if no 
+warning is given during code execution or if the code fails.
+
+ at end deftypefn
+demo
+ at c ./testfun/demo.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} demo ('@var{name}', at var{n})
+
+Runs any examples associated with the function '@var{name}'.  
+Examples are stored in the script file, or in a file with the same 
+name but no extension somewhere on your path.  To keep them separate 
+from the usual script code, all lines are prefixed by @code{%!}.  Each
+example is introduced by the keyword 'demo' flush left to the prefix,
+with no intervening spaces.  The remainder of the example can contain 
+arbitrary Octave code.  For example:
+
+ at example
+ at group
+   %!demo
+   %! t=0:0.01:2*pi; x = sin(t);
+   %! plot(t,x)
+   %! %-------------------------------------------------
+   %! % the figure window shows one cycle of a sine wave
+ at end group
+ at end example
+
+Note that the code is displayed before it is executed, so a simple
+comment at the end suffices.  It is generally not necessary to use
+disp or printf within the demo.
+
+Demos are run in a function environment with no access to external
+variables.  This means that all demos in your function must use
+separate initialization code.  Alternatively, you can combine your
+demos into one huge demo, with the code:
+
+ at example
+   %! input("Press <enter> to continue: ","s");
+ at end example
+
+between the sections, but this is discouraged.  Other techniques
+include using multiple plots by saying figure between each, or
+using subplot to put multiple plots in the same window.
+
+Also, since demo evaluates inside a function context, you cannot
+define new functions inside a demo.  Instead you will have to
+use @code{eval(example('function',n))} to see them.  Because eval only
+evaluates one line, or one statement if the statement crosses
+multiple lines, you must wrap your demo in "if 1 <demo stuff> endif"
+with the 'if' on the same line as 'demo'.  For example,
+
+ at example
+ at group
+  %!demo if 1
+  %!  function y=f(x)
+  %!    y=x;
+  %!  endfunction
+  %!  f(3)
+  %! endif
+ at end group
+ at end example
+ at seealso{test, example}
+ at end deftypefn
+setdiff
+ at c ./set/setdiff.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} setdiff (@var{a}, @var{b})
+ at deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows")
+ at deftypefnx {Function File} {[@var{c}, @var{i}] =} setdiff (@var{a}, @var{b})
+Return the elements in @var{a} that are not in @var{b}, sorted in
+ascending order.  If @var{a} and @var{b} are both column vectors
+return a column vector, otherwise return a row vector.
+
+Given the optional third argument @samp{"rows"}, return the rows in
+ at var{a} that are not in @var{b}, sorted in ascending order by rows.
+
+If requested, return @var{i} such that @code{c = a(i)}.
+ at seealso{unique, union, intersect, setxor, ismember}
+ at end deftypefn
+intersect
+ at c ./set/intersect.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} intersect (@var{a}, @var{b})
+ at deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@var{a}, @var{b})
+
+Return the elements in both @var{a} and @var{b}, sorted in ascending
+order.  If @var{a} and @var{b} are both column vectors return a column
+vector, otherwise return a row vector.
+
+Return index vectors @var{ia} and @var{ib} such that @code{a(ia)==c} and
+ at code{b(ib)==c}.
+
+ at end deftypefn
+ at seealso{unique, union, setxor, setdiff, ismember}
+complement
+ at c ./set/complement.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} complement (@var{x}, @var{y})
+Return the elements of set @var{y} that are not in set @var{x}.  For
+example,
+
+ at example
+ at group
+complement ([ 1, 2, 3 ], [ 2, 3, 5 ])
+     @result{} 5
+ at end group
+ at end example
+ at seealso{union, intersect, unique}
+ at end deftypefn
+union
+ at c ./set/union.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} union (@var{a}, @var{b})
+ at deftypefnx{Function File} {} union (@var{a}, @var{b}, "rows")
+Return the set of elements that are in either of the sets @var{a} and
+ at var{b}.  For example,
+
+ at example
+ at group
+union ([1, 2, 4], [2, 3, 5])
+     @result{} [1, 2, 3, 4, 5]
+ at end group
+ at end example
+
+If the optional third input argument is the string "rows" each row of
+the matrices @var{a} and @var{b} will be considered an element of sets.
+For example,
+ at example
+ at group
+union([1, 2; 2, 3], [1, 2; 3, 4], "rows")
+     @result{}  1   2
+    2   3
+    3   4
+ at end group
+ at end example
+
+ at deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@var{a}, @var{b})
+
+Return index vectors @var{ia} and @var{ib} such that @code{a == c(ia)} and
+ at code{b == c(ib)}.
+
+ at seealso{intersect, complement, unique}
+ at end deftypefn
+unique
+ at c ./set/unique.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} unique (@var{x})
+ at deftypefnx {Function File} {} unique (@var{x}, "rows")
+ at deftypefnx {Function File} {} unique (@dots{}, "first")
+ at deftypefnx {Function File} {} unique (@dots{}, "last")
+ at deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{})
+Return the unique elements of @var{x}, sorted in ascending order.
+If @var{x} is a row vector, return a row vector, but if @var{x}
+is a column vector or a matrix return a column vector.
+
+If the optional argument @code{"rows"} is supplied, return the unique
+rows of @var{x}, sorted in ascending order.
+
+If requested, return index vectors @var{i} and @var{j} such that
+ at code{x(i)==y} and @code{y(j)==x}.
+
+Additionally, one of @code{"first"} or @code{"last"} may be given as
+an argument.  If @code{"last"} is specified, return the highest
+possible indices in @var{i}, otherwise, if @code{"first"} is
+specified, return the lowest.  The default is @code{"last"}.
+ at seealso{union, intersect, setdiff, setxor, ismember}
+ at end deftypefn
+ismember
+ at c ./set/ismember.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{tf} =} ismember (@var{A}, @var{S}) 
+ at deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{S}) 
+ at deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{S}, "rows")
+Return a matrix @var{tf} with the same shape as @var{A} which has a 1 if 
+ at code{A(i,j)} is in @var{S} and 0 if it is not.  If a second output argument 
+is requested, the index into @var{S} of each of the matching elements is
+also returned. 
+
+ at example
+ at group
+a = [3, 10, 1];
+s = [0:9];
+[tf, s_idx] = ismember (a, s);
+     @result{} tf = [1, 0, 1]
+     @result{} s_idx = [4, 0, 2]
+ at end group
+ at end example
+
+The inputs, @var{A} and @var{S}, may also be cell arrays.
+
+ at example
+ at group
+a = @{'abc'@};
+s = @{'abc', 'def'@};
+[tf, s_idx] = ismember (a, s);
+     @result{} tf = [1, 0]
+     @result{} s_idx = [1, 0]
+ at end group
+ at end example
+
+With the optional third argument @code{"rows"}, and matrices 
+ at var{A} and @var{S} with the same number of columns, compare rows in
+ at var{A} with the rows in @var{S}.
+
+ at example
+ at group
+a = [1:3; 5:7; 4:6];
+s = [0:2; 1:3; 2:4; 3:5; 4:6];
+[tf, s_idx] = ismember(a, s, 'rows');
+     @result{} tf = logical ([1; 0; 1])
+     @result{} s_idx = [2; 0; 5];
+ at end group
+ at end example
+
+ at seealso{unique, union, intersect, setxor, setdiff}
+ at end deftypefn
+setxor
+ at c ./set/setxor.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} setxor (@var{a}, @var{b})
+ at deftypefnx {Function File} {} setxor (@var{a}, @var{b}, 'rows')
+
+Return the elements exclusive to @var{a} or @var{b}, sorted in ascending
+order.  If @var{a} and @var{b} are both column vectors return a column
+vector, otherwise return a row vector.
+
+ at deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b})
+
+Return index vectors @var{ia} and @var{ib} such that @code{a == c(ia)} and
+ at code{b == c(ib)}.
+
+ at seealso{unique, union, intersect, setdiff, ismember}
+ at end deftypefn
+imfinfo
+ at c ./image/imfinfo.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {@var{info} =} imfinfo (@var{filename})
+ at deftypefnx {Function File} {@var{info} =} imfinfo (@var{url})
+Read image information from a file.
+
+ at code{imfinfo} returns a structure containing information about the image
+stored in the file @var{filename}.  The output structure contains the
+following fields.
+
+ at table @samp
+ at item Filename
+The full name of the image file.
+ at item FileSize
+Number of bytes of the image on disk
+ at item FileModDate
+Date of last modification to the file.
+ at item Height
+Image height in pixels.
+ at item Width
+Image Width in pixels.
+ at item BitDepth
+Number of bits per channel per pixel.
+ at item Format
+Image format (e.g., @code{"jpeg"}).
+ at item LongFormat
+Long form image format description.
+ at item XResolution
+X resolution of the image.
+ at item YResolution
+Y resolution of the image.
+ at item TotalColors
+Number of unique colors in the image.
+ at item TileName
+Tile name.
+ at item AnimationDelay
+Time in 1/100ths of a second (0 to 65535) which must expire before displaying
+the next image in an animated sequence.
+ at item AnimationIterations
+Number of iterations to loop an animation (e.g., Netscape loop extension) for.
+ at item ByteOrder
+Endian option for formats that support it.  Is either @code{"little-endian"},
+ at code{"big-endian"}, or @code{"undefined"}.
+ at item Gamma
+Gamma level of the image.  The same color image displayed on two different
+workstations may look different due to differences in the display monitor.
+ at item Matte
+ at code{true} if the image has transparency.
+ at item ModulusDepth
+Image modulus depth (minimum number of bits required to support red/green/blue
+components without loss of accuracy).
+ at item Quality
+JPEG/MIFF/PNG compression level.
+ at item QuantizeColors
+Preferred number of colors in the image.
+ at item ResolutionUnits
+Units of image resolution.  Is either @code{"pixels per inch"},
+ at code{"pixels per centimeter"}, or @code{"undefined"}.
+ at item ColorType
+Image type.  Is either @code{"grayscale"}, @code{"indexed"}, @code{"truecolor"},
+or @code{"undefined"}.
+ at item View
+FlashPix viewing parameters.
+ at end table
+
+ at seealso{imread, imwrite}
+ at end deftypefn
+imread
+ at c ./image/imread.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename})
+Read images from various file formats.
+
+The size and numeric class of the output depends on the
+format of the image.  A color image is returned as an
+MxNx3 matrix.  Grey-level and black-and-white images are
+of size MxN.
+The color depth of the image determines the numeric
+class of the output: "uint8" or "uint16" for grey
+and color, and "logical" for black and white.
+
+ at seealso{imwrite, imfinfo}
+ at end deftypefn
+brighten
+ at c ./image/brighten.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{map_out} =} brighten (@var{map}, @var{beta})
+ at deftypefnx {Function File} {@var{map_out} =} brighten (@var{h}, @var{beta})
+ at deftypefnx {Function File} {@var{map_out} =} brighten (@var{beta})
+Darkens or brightens the given colormap.  If the @var{map} argument 
+is omitted, the function is applied to the current colormap.  The first
+argument can also be a valid graphics handle @var{h}, in which case 
+ at code{brighten} is applied to the colormap associated with this handle.
+
+Should the resulting colormap @var{map_out} not be assigned, it will be
+written to the current colormap.
+
+The argument @var{beta} should be a scalar between -1 and 1,
+where a negative value darkens and a positive value brightens
+the colormap.
+ at seealso{colormap}
+ at end deftypefn
+gmap40
+ at c ./image/gmap40.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gmap40 (@var{n})
+Create a color colormap.  The colormap is red, green, blue, yellow,
+magenta and cyan.  These are the colors that are allowed with patch
+objects using gnuplot 4.0, and so this colormap function is specially
+designed for users of gnuplot 4.0.  The argument @var{n} should be 
+a scalar.  If it is omitted, a length of 6 is assumed.  Larger values
+of @var{n} result in a repetition of the above colors
+ at seealso{colormap}
+ at end deftypefn
+imshow
+ at c ./image/imshow.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} imshow (@var{im})
+ at deftypefnx {Function File} {} imshow (@var{im}, @var{limits})
+ at deftypefnx {Function File} {} imshow (@var{im}, @var{map})
+ at deftypefnx {Function File} {} imshow (@var{rgb}, @dots{})
+ at deftypefnx {Function File} {} imshow (@var{filename})
+ at deftypefnx {Function File} {} imshow (@dots{}, @var{string_param1}, @var{value1}, @dots{})
+Display the image @var{im}, where @var{im} can be a 2-dimensional
+(gray-scale image) or a 3-dimensional (RGB image) matrix.
+
+If @var{limits} is a 2-element vector @code{[@var{low}, @var{high}]},
+the image is shown using a display range between @var{low} and
+ at var{high}.  If an empty matrix is passed for @var{limits}, the
+display range is computed as the range between the minimal and the
+maximal value in the image.
+
+If @var{map} is a valid color map, the image will be shown as an indexed
+image using the supplied color map.
+
+If a file name is given instead of an image, the file will be read and
+shown.
+
+If given, the parameter @var{string_param1} has value
+ at var{value1}.  @var{string_param1} can be any of the following:
+ at table @samp
+ at item "displayrange"
+ at var{value1} is the display range as described above.
+ at end table
+ at seealso{image, imagesc, colormap, gray2ind, rgb2ind}
+ at end deftypefn
+gray2ind
+ at c ./image/gray2ind.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{img}, @var{map}] =} gray2ind (@var{I}, @var{n})
+Convert a gray scale intensity image to an Octave indexed image.
+The indexed image will consist of @var{n} different intensity values.  If not
+given @var{n} will default to 64.
+ at end deftypefn
+spring
+ at c ./image/spring.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spring (@var{n})
+Create color colormap.  This colormap is magenta to yellow.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+__img_via_file__
+ at c ./image/__img_via_file__.m
+Undocumented internal function.
+winter
+ at c ./image/winter.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} winter (@var{n})
+Create color colormap.  This colormap is blue to green.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+prism
+ at c ./image/prism.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} prism (@var{n})
+Create color colormap.  This colormap cycles trough red, orange, yellow,
+green, blue and violet.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+gray
+ at c ./image/gray.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gray (@var{n})
+Return a gray colormap with @var{n} entries corresponding to values from
+0 to @var{n}-1.  The argument @var{n} should be a scalar.  If it is
+omitted, the length of the current colormap or 64 is assumed.
+ at end deftypefn
+autumn
+ at c ./image/autumn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} autumn (@var{n})
+Create color colormap.  This colormap is red through orange to yellow.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+ind2gray
+ at c ./image/ind2gray.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ind2gray (@var{x}, @var{map})
+Convert an Octave indexed image to a gray scale intensity image.
+If @var{map} is omitted, the current colormap is used to determine the
+intensities.
+ at seealso{gray2ind, rgb2ntsc, image, colormap}
+ at end deftypefn
+flag
+ at c ./image/flag.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} flag (@var{n})
+Create color colormap.  This colormap cycles through red, white, blue 
+and black.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+saveimage
+ at c ./image/saveimage.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} saveimage (@var{file}, @var{x}, @var{fmt}, @var{map})
+Save the matrix @var{x} to @var{file} in image format @var{fmt}.  Valid
+values for @var{fmt} are
+
+ at table @code
+ at item "img"
+Octave's image format.  The current colormap is also saved in the file.
+
+ at item "ppm"
+Portable pixmap format.
+
+ at item "ps"
+PostScript format.  Note that images saved in PostScript format cannot
+be read back into Octave with loadimage.
+ at end table
+
+If the fourth argument is supplied, the specified colormap will also be
+saved along with the image.
+
+Note: if the colormap contains only two entries and these entries are
+black and white, the bitmap ppm and PostScript formats are used.  If the
+image is a gray scale image (the entries within each row of the colormap
+are equal) the gray scale ppm and PostScript image formats are used,
+otherwise the full color formats are used.
+ at seealso{loadimage, save, load, colormap}
+ at end deftypefn
+ntsc2rgb
+ at c ./image/ntsc2rgb.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ntsc2rgb (@var{yiq})
+Transform a colormap or image from NTSC to RGB.
+ at seealso{rgb2ntsc}
+ at end deftypefn
+ind2rgb
+ at c ./image/ind2rgb.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{rgb} =} ind2rgb (@var{x}, @var{map})
+ at deftypefnx {Function File} {[@var{r}, @var{g}, @var{b}] =} ind2rgb (@var{x}, @var{map})
+Convert an indexed image to red, green, and blue color components.
+If the colormap doesn't contain enough colors, pad it with the
+last color in the map.
+If @var{map} is omitted, the current colormap is used for the conversion.
+ at seealso{rgb2ind, image, imshow, ind2gray, gray2ind}
+ at end deftypefn
+rgb2ind
+ at c ./image/rgb2ind.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb})
+ at deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{r}, @var{g}, @var{b})
+Convert an RGB image to an Octave indexed image.
+ at seealso{ind2rgb, rgb2ntsc}
+ at end deftypefn
+jet
+ at c ./image/jet.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} jet (@var{n})
+Create color colormap.  This colormap is dark blue through blue, cyan, 
+green, yellow, red to dark red.  The argument @var{n} should be a scalar. 
+If it is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+hot
+ at c ./image/hot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hot (@var{n})
+Create color colormap.  This colormap is black through dark red, red, 
+orange, yellow to white.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+colormap
+ at c ./image/colormap.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} colormap (@var{map})
+ at deftypefnx {Function File} {} colormap ("default")
+Set the current colormap.
+
+ at code{colormap (@var{map})} sets the current colormap to @var{map}.  The
+color map should be an @var{n} row by 3 column matrix.  The columns
+contain red, green, and blue intensities respectively.  All entries
+should be between 0 and 1 inclusive.  The new colormap is returned.
+
+ at code{colormap ("default")} restores the default colormap (the
+ at code{jet} map with 64 entries).  The default colormap is returned.
+
+With no arguments, @code{colormap} returns the current color map.
+ at seealso{jet}
+ at end deftypefn
+ocean
+ at c ./image/ocean.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ocean (@var{n})
+Create color colormap.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at end deftypefn
+bone
+ at c ./image/bone.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bone (@var{n})
+Create color colormap.  This colormap is a gray colormap with a light 
+blue tone.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+rgb2hsv
+ at c ./image/rgb2hsv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{hsv_map} =} rgb2hsv (@var{rgb_map})
+Transform a colormap or image from the rgb space to the hsv space.
+
+A color n the RGB space consists of the red, green and blue intensities.
+
+In the HSV space each color is represented by their hue, saturation
+and value (brightness).  Value gives the amount of light in the color.
+Hue describes the dominant wavelength. 
+Saturation is the amount of Hue mixed into the color.
+ at seealso{hsv2rgb}
+ at end deftypefn
+__img__
+ at c ./image/__img__.m
+Undocumented internal function.
+cool
+ at c ./image/cool.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} cool (@var{n})
+Create color colormap.  The colormap is cyan to magenta.  The argument 
+ at var{n} should be a scalar.  If it is omitted, the length of the current
+colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+rainbow
+ at c ./image/rainbow.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rainbow (@var{n})
+Create color colormap.  This colormap is red through orange, yellow, green, 
+blue to violet.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+imagesc
+ at c ./image/imagesc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} imagesc (@var{a})
+ at deftypefnx {Function File} {} imagesc (@var{x}, @var{y}, @var{a})
+ at deftypefnx {Function File} {} imagesc (@dots{}, @var{limits})
+ at deftypefnx {Function File} {} imagesc (@var{h}, @dots{})
+ at deftypefnx {Function File} {@var{h} =} imagesc (@dots{})
+Display a scaled version of the matrix @var{a} as a color image.  The
+colormap is scaled so that the entries of the matrix occupy the entire
+colormap.  If @var{limits} = [@var{lo}, @var{hi}] are given, then that
+range is set to the 'clim' of the current axes.
+
+The axis values corresponding to the matrix elements are specified in
+ at var{x} and @var{y}, either as pairs giving the minimum and maximum
+values for the respective axes, or as values for each row and column
+of the matrix @var{a}.
+
+ at seealso{image, imshow, caxis}
+ at end deftypefn
+summer
+ at c ./image/summer.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} summer (@var{n})
+Create color colormap.  This colormap is green to yellow.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+hsv
+ at c ./image/hsv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hsv (@var{n})
+Create color colormap.  This colormap is red through yellow, green,
+cyan, blue, magenta to red.  It is obtained by linearly varying the
+hue through all possible values while keeping constant maximum
+saturation and value and is equivalent to
+ at code{hsv2rgb ([linspace(0,1,N)', ones(N,2)])}.
+
+The argument @var{n} should be a scalar.  If it is omitted, the
+length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+image
+ at c ./image/image.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} image (@var{img})
+ at deftypefnx {Function File} {} image (@var{x}, @var{y}, @var{img})
+Display a matrix as a color image.  The elements of @var{x} are indices
+into the current colormap, and the colormap will be scaled so that the
+extremes of @var{x} are mapped to the extremes of the colormap.
+
+It first tries to use @code{gnuplot}, then @code{display} from 
+ at code{ImageMagick}, then @code{xv}, and then @code{xloadimage}.
+The actual program used can be changed using the @code{image_viewer}
+function.
+
+The axis values corresponding to the matrix elements are specified in
+ at var{x} and @var{y}.  If you're not using gnuplot 4.2 or later, these
+variables are ignored.
+ at seealso{imshow, imagesc, colormap, image_viewer}
+ at end deftypefn
+white
+ at c ./image/white.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} white (@var{n})
+Create color colormap.  This colormap is completely white.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+image_viewer
+ at c ./image/image_viewer.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{fcn}, @var{default_zoom}] =} image_viewer (@var{fcn}, @var{default_zoom})
+Change the program or function used for viewing images and return the
+previous values.
+
+When the @code{image} or @code{imshow} function is called it will
+launch an external program to display the image.  The default behavior
+is to use gnuplot if the installed version supports image viewing,
+and otherwise try the programs @code{display}, @code{xv}, and
+ at code{xloadimage}.  Using this function it is possible to change that
+behavior.
+
+When called with one input argument images will be displayed by saving
+the image to a file and the system command @var{command} will be called
+to view the image.  The @var{command} must be a string containing
+ at code{%s} and possibly @code{%f}.  The @code{%s} will be replaced by
+the filename of the image, and the @code{%f} will (if present) be
+replaced by the zoom factor given to the @code{image} function.
+For example,
+ at example
+image_viewer ("eog %s");
+ at end example
+changes the image viewer to the @code{eog} program.
+
+With two input arguments, images will be displayed by calling
+the function @var{function_handle}.  For example,
+ at example
+image_viewer (data, @@my_image_viewer);
+ at end example
+sets the image viewer function to @code{my_image_viewer}.  The image
+viewer function is called with
+ at example
+my_image_viewer (@var{x}, @var{y}, @var{im}, @var{zoom}, @var{data})
+ at end example
+where @var{x} and @var{y} are the axis of the image, @var{im} is the image
+variable, and @var{data} is extra user-supplied data to be passed to
+the viewer function.
+
+With three input arguments it is possible to change the zooming.
+Some programs (like @code{xloadimage}) require the zoom factor to be
+between 0 and 100, and not 0 and 1 like Octave assumes.  This is
+solved by setting the third argument to 100.
+
+ at seealso{image, imshow}
+ at end deftypefn
+hsv2rgb
+ at c ./image/hsv2rgb.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{rgb_map} =} hsv2rgb (@var{hsv_map})
+Transform a colormap or image from the hsv space to the rgb space. 
+ at seealso{rgb2hsv}
+ at end deftypefn
+imwrite
+ at c ./image/imwrite.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
+ at deftypefnx {Function File} {} imwrite (@var{img}, @var{map}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
+Write images in various file formats.
+
+If @var{fmt} is missing, the file extension (if any) of
+ at var{filename} is used to determine the format.
+
+The parameter-value pairs (@var{p1}, @var{v1}, @dots{}) are optional.  Currently
+the following options are supported for @t{JPEG} images
+
+ at table @samp
+ at item Quality
+Sets the quality of the compression.  The corresponding value should be an
+integer between 0 and 100, with larger values meaning higher visual quality
+and less compression.
+ at end table
+
+ at seealso{imread, imfinfo}
+ at end deftypefn
+contrast
+ at c ./image/contrast.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} contrast (@var{x}, @var{n})
+Return a gray colormap that maximizes the contrast in an image.  The
+returned colormap will have @var{n} rows.  If @var{n} is not defined
+then the size of the current colormap is used instead.
+ at seealso{colormap}
+ at end deftypefn
+rgb2ntsc
+ at c ./image/rgb2ntsc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rgb2ntsc (@var{rgb})
+Transform a colormap or image from RGB to NTSC.
+ at seealso{ntsc2rgb}
+ at end deftypefn
+pink
+ at c ./image/pink.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} pink (@var{n})
+Create color colormap.  This colormap gives a sepia tone on black and
+white images.  The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+copper
+ at c ./image/copper.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} copper (@var{n})
+Create color colormap.  This colormap is black to a light copper tone.
+The argument @var{n} should be a scalar.  If it
+is omitted, the length of the current colormap or 64 is assumed.
+ at seealso{colormap}
+ at end deftypefn
+reallog
+ at c ./specfun/reallog.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} reallog (@var{x})
+Return the real-valued natural logarithm of each element of @var{x}.  Report 
+an error if any element results in a complex return value.
+ at seealso{log, realpow, realsqrt}
+ at end deftypefn
+factor
+ at c ./specfun/factor.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {@var{p} =} factor (@var{q})
+ at deftypefnx {Function File} {[@var{p}, @var{n}] =} factor (@var{q})
+
+Return prime factorization of @var{q}.  That is, @code{prod (@var{p})
+== @var{q}} and every element of @var{p} is a prime number.  If
+ at code{@var{q} == 1}, returns 1. 
+
+With two output arguments, return the unique primes @var{p} and
+their multiplicities.  That is, @code{prod (@var{p} .^ @var{n}) ==
+ at var{q}}.
+ at seealso{gcd, lcm}
+ at end deftypefn
+legendre
+ at c ./specfun/legendre.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{l} =} legendre (@var{n}, @var{x})
+ at deftypefnx {Function File} {@var{l} =} legendre (@var{n}, @var{x}, @var{normalization})
+Compute the Legendre function of degree @var{n} and order 
+ at var{m} = 0 @dots{} N.  The optional argument, @var{normalization}, 
+may be one of @code{"unnorm"}, @code{"sch"}, or @code{"norm"}.
+The default is @code{"unnorm"}.  The value of @var{n} must be a 
+non-negative scalar integer.  
+
+If the optional argument @var{normalization} is missing or is
+ at code{"unnorm"}, compute the Legendre function of degree @var{n} and
+order @var{m} and return all values for @var{m} = 0 @dots{} @var{n}.
+The return value has one dimension more than @var{x}.
+
+The Legendre Function of degree @var{n} and order @var{m}:
+
+ at example
+ at group
+ m        m       2  m/2   d^m
+P(x) = (-1) * (1-x  )    * ----  P (x)
+ n                         dx^m   n
+ at end group
+ at end example
+
+ at noindent
+with Legendre polynomial of degree @var{n}:
+
+ at example
+ at group
+          1     d^n   2    n
+P (x) = ------ [----(x - 1)  ]
+ n      2^n n!  dx^n
+ at end group
+ at end example
+
+ at noindent
+ at code{legendre (3, [-1.0, -0.9, -0.8])} returns the matrix:
+
+ at example
+ at group
+ x  |   -1.0   |   -0.9   |  -0.8
+------------------------------------
+m=0 | -1.00000 | -0.47250 | -0.08000
+m=1 |  0.00000 | -1.99420 | -1.98000
+m=2 |  0.00000 | -2.56500 | -4.32000
+m=3 |  0.00000 | -1.24229 | -3.24000 
+ at end group
+ at end example
+
+If the optional argument @code{normalization} is @code{"sch"}, 
+compute the Schmidt semi-normalized associated Legendre function.
+The Schmidt semi-normalized associated Legendre function is related
+to the unnormalized Legendre functions by the following:
+
+For Legendre functions of degree n and order 0:
+
+ at example
+ at group
+  0       0
+SP (x) = P (x)
+  n       n
+ at end group
+ at end example
+
+For Legendre functions of degree n and order m:
+
+ at example
+ at group
+  m       m          m    2(n-m)! 0.5
+SP (x) = P (x) * (-1)  * [-------]
+  n       n               (n+m)!
+ at end group
+ at end example
+
+If the optional argument @var{normalization} is @code{"norm"}, 
+compute the fully normalized associated Legendre function.
+The fully normalized associated Legendre function is related
+to the unnormalized Legendre functions by the following:
+
+For Legendre functions of degree @var{n} and order @var{m}
+
+ at example
+ at group
+  m       m          m    (n+0.5)(n-m)! 0.5
+NP (x) = P (x) * (-1)  * [-------------]
+  n       n                   (n+m)!    
+ at end group
+ at end example
+ at end deftypefn
+betai
+ at c ./specfun/betai.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} betai (@var{a}, @var{b}, @var{x})
+This function is provided for compatibility with older versions of
+Octave.  New programs should use betainc instead.
+
+ at code{betai (@var{a}, @var{b}, @var{x})} is the same as @code{betainc
+(@var{x}, @var{a}, @var{b})}. 
+ at end deftypefn
+perms
+ at c ./specfun/perms.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} perms (@var{v})
+
+Generate all permutations of @var{v}, one row per permutation.  The
+result has size @code{factorial (@var{n}) * @var{n}}, where @var{n}
+is the length of @var{v}.
+
+As an example, @code{perms([1, 2, 3])} returns the matrix
+ at example
+ at group
+  1   2   3
+  2   1   3
+  1   3   2
+  2   3   1
+  3   1   2
+  3   2   1
+ at end group
+ at end example
+ at end deftypefn
+realsqrt
+ at c ./specfun/realsqrt.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} realsqrt (@var{x})
+Return the real-valued square root of each element of @var{x}.  Report an
+error if any element results in a complex return value.
+ at seealso{sqrt, realpow, reallog}
+ at end deftypefn
+isprime
+ at c ./specfun/isprime.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isprime (@var{n})
+
+Return true if @var{n} is a prime number, false otherwise.
+
+Something like the following is much faster if you need to test a lot
+of small numbers:
+
+ at example
+   @var{t} = ismember (@var{n}, primes (max (@var{n} (:))));
+ at end example
+
+If max(n) is very large, then you should be using special purpose 
+factorization code.
+
+ at seealso{primes, factor, gcd, lcm}
+ at end deftypefn
+factorial
+ at c ./specfun/factorial.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} factorial (@var{n})
+Return the factorial of @var{n} where @var{n} is a positive integer.  If
+ at var{n} is a scalar, this is equivalent to @code{prod (1:@var{n})}.  For
+vector or matrix arguments, return the factorial of each element in the
+array.  For non-integers see the generalized factorial function
+ at code{gamma}.
+ at seealso{prod, gamma}
+ at end deftypefn
+erfinv
+ at c ./specfun/erfinv.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} erfinv (@var{z})
+Computes the inverse of the error function.
+ at seealso{erf, erfc}
+ at end deftypefn
+betaln
+ at c ./specfun/betaln.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} betaln (@var{a}, @var{b})
+Return the log of the Beta function,
+ at tex
+$$
+ B (a, b) = \log {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+betaln (a, b) = gammaln (a) + gammaln (b) - gammaln (a + b)
+ at end example
+ at end ifnottex
+ at seealso{beta, betainc, gammaln}
+ at end deftypefn
+realpow
+ at c ./specfun/realpow.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} realpow (@var{x}, @var{y})
+Compute the real-valued, element-by-element power operator.  This is 
+equivalent to @w{@code{@var{x} .^ @var{y}}}, except that @code{realpow}
+reports an error if any return value is complex.
+ at seealso{reallog, realsqrt}
+ at end deftypefn
+bessel
+ at c ./specfun/bessel.m
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{j}, @var{ierr}] =} besselj (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})
+Compute Bessel or Hankel functions of various kinds:
+
+ at table @code
+ at item besselj
+Bessel functions of the first kind.  If the argument @var{opt} is supplied, 
+the result is multiplied by @code{exp(-abs(imag(x)))}.
+ at item bessely
+Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(-abs(imag(x)))}.
+ at item besseli
+Modified Bessel functions of the first kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(-abs(real(x)))}.
+ at item besselk
+Modified Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(x)}.
+ at item besselh
+Compute Hankel functions of the first (@var{k} = 1) or second (@var{k}
+= 2) kind.  If the argument @var{opt} is supplied, the result is multiplied by
+ at code{exp (-I*@var{x})} for @var{k} = 1 or @code{exp (I*@var{x})} for
+ at var{k} = 2.
+ at end table
+
+If @var{alpha} is a scalar, the result is the same size as @var{x}.
+If @var{x} is a scalar, the result is the same size as @var{alpha}.
+If @var{alpha} is a row vector and @var{x} is a column vector, the
+result is a matrix with @code{length (@var{x})} rows and
+ at code{length (@var{alpha})} columns.  Otherwise, @var{alpha} and
+ at var{x} must conform and the result will be the same size.
+
+The value of @var{alpha} must be real.  The value of @var{x} may be
+complex.
+
+If requested, @var{ierr} contains the following status information
+and is the same size as the result.
+
+ at enumerate 0
+ at item
+Normal return.
+ at item
+Input error, return @code{NaN}.
+ at item
+Overflow, return @code{Inf}.
+ at item
+Loss of significance by argument reduction results in less than
+half of machine accuracy.
+ at item
+Complete loss of significance by argument reduction, return @code{NaN}.
+ at item
+Error---no computation, algorithm termination condition not met,
+return @code{NaN}.
+ at end enumerate
+ at end deftypefn
+gammai
+ at c ./specfun/gammai.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} gammai (@var{a}, @var{x})
+This function is provided for compatibility with older versions of
+Octave.  New programs should use @code{gammainc} instead.
+
+ at code{gammai (@var{a}, @var{x})} is the same as @code{gammainc
+(@var{x}, @var{a})}.
+ at end deftypefn
+primes
+ at c ./specfun/primes.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} primes (@var{n})
+
+Return all primes up to @var{n}.  
+
+The algorithm used is the Sieve of Erastothenes.
+
+Note that if you need a specific number of primes you can use the
+fact the distance from one prime to the next is, on average,
+proportional to the logarithm of the prime.  Integrating, one finds
+that there are about @math{k} primes less than
+ at tex
+$k \log (5 k)$.
+ at end tex
+ at ifnottex
+k*log(5*k).
+ at end ifnottex
+ at seealso{list_primes, isprime}
+ at end deftypefn
+pow2
+ at c ./specfun/pow2.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} pow2 (@var{x})
+ at deftypefnx {Mapping Function} {} pow2 (@var{f}, @var{e})
+With one argument, computes
+ at tex
+$2^x$
+ at end tex
+ at ifnottex
+2 .^ x
+ at end ifnottex
+for each element of @var{x}.
+
+With two arguments, returns
+ at tex
+$f \cdot 2^e$.
+ at end tex
+ at ifnottex
+f .* (2 .^ e).
+ at end ifnottex
+ at seealso{log2, nextpow2}
+ at end deftypefn
+beta
+ at c ./specfun/beta.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} beta (@var{a}, @var{b})
+For real inputs, return the Beta function,
+ at tex
+$$
+ B (a, b) = {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
+ at end example
+ at end ifnottex
+ at end deftypefn
+nchoosek
+ at c ./specfun/nchoosek.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
+
+Compute the binomial coefficient or all combinations of @var{n}.
+If @var{n} is a scalar then, calculate the binomial coefficient
+of @var{n} and @var{k}, defined as
+
+ at tex
+$$
+ {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+               = {n! \over k! (n-k)!}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+ /   \
+ | n |    n (n-1) (n-2) @dots{} (n-k+1)       n!
+ |   |  = ------------------------- =  ---------
+ | k |               k!                k! (n-k)!
+ \   /
+ at end group
+ at end example
+ at end ifnottex
+
+If @var{n} is a vector generate all combinations of the elements
+of @var{n}, taken @var{k} at a time, one row per combination.  The 
+resulting @var{c} has size @code{[nchoosek (length (@var{n}), 
+ at var{k}), @var{k}]}.
+
+ at code{nchoosek} works only for non-negative integer arguments; use
+ at code{bincoeff} for non-integer scalar arguments and for using vector
+arguments to compute many coefficients at once.
+
+ at seealso{bincoeff}
+ at end deftypefn
+wavread
+ at c ./audio/wavread.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} wavread (@var{filename})
+Load the RIFF/WAVE sound file @var{filename}, and return the samples
+in vector @var{y}.  If the file contains multichannel data, then
+ at var{y} is a matrix with the channels represented as columns.
+
+ at deftypefnx {Function File} {[@var{y}, @var{Fs}, @var{bits}] =} wavread (@var{filename})
+Additionally return the sample rate (@var{fs}) in Hz and the number of bits 
+per sample (@var{bits}).
+
+ at deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, @var{n})
+Read only the first @var{n} samples from each channel.
+
+ at deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename},[@var{n1} @var{n2}])
+Read only samples @var{n1} through @var{n2} from each channel.
+
+ at deftypefnx {Function File} {[@var{samples}, @var{channels}] =} wavread (@var{filename}, "size")
+Return the number of samples (@var{n}) and channels (@var{ch})
+instead of the audio data.
+ at seealso{wavwrite}
+ at end deftypefn
+lin2mu
+ at c ./audio/lin2mu.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} lin2mu (@var{x}, @var{n})
+Converts audio data from linear to mu-law.  Mu-law values use 8-bit
+unsigned integers.  Linear values use @var{n}-bit signed integers or 
+floating point values in the range -1<=@var{x}<=1 if @var{n} is 0.  
+If @var{n} is not specified it defaults to 0, 8 or 16 depending on 
+the range values in @var{x}.
+ at seealso{mu2lin, loadaudio, saveaudio, playaudio, setaudio, record}
+ at end deftypefn
+setaudio
+ at c ./audio/setaudio.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} setaudio ([@var{w_type} [, @var{value}]])
+Execute the shell command @samp{mixer [@var{w_type} [, @var{value}]]}
+ at end deftypefn
+record
+ at c ./audio/record.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} record (@var{sec}, @var{sampling_rate})
+Records @var{sec} seconds of audio input into the vector @var{x}.  The
+default value for @var{sampling_rate} is 8000 samples per second, or
+8kHz.  The program waits until the user types @key{RET} and then
+immediately starts to record.
+ at seealso{lin2mu, mu2lin, loadaudio, saveaudio, playaudio, setaudio}
+ at end deftypefn
+mu2lin
+ at c ./audio/mu2lin.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} mu2lin (@var{x}, @var{bps})
+Converts audio data from linear to mu-law.  Mu-law values are 8-bit
+unsigned integers.  Linear values use @var{n}-bit signed integers
+or floating point values in the range -1<=y<=1 if @var{n} is 0.  If
+ at var{n} is not specified it defaults to 8.
+ at seealso{lin2mu, loadaudio, saveaudio, playaudio, setaudio, record}
+ at end deftypefn
+saveaudio
+ at c ./audio/saveaudio.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} saveaudio (@var{name}, @var{x}, @var{ext}, @var{bps})
+Saves a vector @var{x} of audio data to the file
+ at file{@var{name}. at var{ext}}.  The optional parameters @var{ext} and
+ at var{bps} determine the encoding and the number of bits per sample used
+in the audio file (see @code{loadaudio});  defaults are @file{lin} and
+8, respectively.
+ at seealso{lin2mu, mu2lin, loadaudio, playaudio, setaudio, record}
+ at end deftypefn
+wavwrite
+ at c ./audio/wavwrite.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} wavwrite (@var{y}, @var{filename})
+ at deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{filename})
+ at deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{bits}, @var{filename})
+Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}
+with sample rate @var{fs} and bits per sample @var{bits}.  The
+default sample rate is 8000 Hz with 16-bits per sample.  Each column
+of the data represents a separate channel.
+ at seealso{wavread}
+ at end deftypefn
+playaudio
+ at c ./audio/playaudio.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} playaudio (@var{name}, @var{ext})
+ at deftypefnx {Function File} {} playaudio (@var{x})
+Plays the audio file @file{@var{name}. at var{ext}} or the audio data
+stored in the vector @var{x}.
+ at seealso{lin2mu, mu2lin, loadaudio, saveaudio, setaudio, record}
+ at end deftypefn
+loadaudio
+ at c ./audio/loadaudio.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} loadaudio (@var{name}, @var{ext}, @var{bps})
+Loads audio data from the file @file{@var{name}. at var{ext}} into the
+vector @var{x}.
+
+The extension @var{ext} determines how the data in the audio file is
+interpreted;  the extensions @file{lin} (default) and @file{raw}
+correspond to linear, the extensions @file{au}, @file{mu}, or @file{snd}
+to mu-law encoding.
+
+The argument @var{bps} can be either 8 (default) or 16, and specifies
+the number of bits per sample used in the audio file.
+ at seealso{lin2mu, mu2lin, saveaudio, playaudio, setaudio, record}
+ at end deftypefn
+__finish__
+ at c ./startup/__finish__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __finish__ ()
+Undocumented internal function.
+ at end deftypefn
+lookfor
+ at c ./help/lookfor.m
+-*- texinfo -*-
+ at deftypefn {Command} lookfor @var{str}
+ at deftypefnx {Command} lookfor -all @var{str}
+ at deftypefnx {Function} {[@var{func}, @var{helpstring}] =} lookfor (@var{str})
+ at deftypefnx {Function} {[@var{func}, @var{helpstring}] =} lookfor ('-all', @var{str})
+Search for the string @var{str} in all functions found in the current 
+function search path.  By default, @code{lookfor} searches for @var{str}
+in the first sentence of the help string of each function found.  The entire
+help text of each function can be searched if the '-all' argument is 
+supplied.  All searches are case insensitive.
+
+Called with no output arguments, @code{lookfor} prints the list of 
+matching functions to the terminal.  Otherwise, the output arguments 
+ at var{func} and @var{helpstring} define the matching functions and the 
+first sentence of each of their help strings.
+
+The ability of @code{lookfor} to correctly identify the first
+sentence of the help text is dependent on the format of the
+function's help.  All Octave core functions are correctly
+formatted, but the same can not be guaranteed for external packages and
+user-supplied functions.  Therefore, the use of the '-all' argument may 
+be necessary to find related functions that are not a part of Octave.
+ at seealso{help, doc, which}
+ at end deftypefn
+__strip_html_tags__
+ at c ./help/__strip_html_tags__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{text}, @var{status}] =} __strip_html_tags__ (@var{html_text})
+Undocumented internal function.
+ at end deftypefn
+gen_doc_cache
+ at c ./help/gen_doc_cache.m
+-*- texinfo -*-
+ at deftypefn {Function File} gen_doc_cache (@var{out_file}, @var{directory})
+Generate documentation caches for all functions in a given directory.
+
+A documentation cache is generated for all functions in @var{directory}.  The
+resulting cache is saved in the file @var{out_file}.
+The cache is used to speed up @code{lookfor}.
+
+If no directory is given (or it is the empty matrix), a cache for builtin
+operators, etc. is generated.
+
+ at seealso{lookfor, path}
+ at end deftypefn
+__makeinfo__
+ at c ./help/__makeinfo__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type})
+ at deftypefnx{Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type}, @var{see_also})
+Undocumented internal function.
+ at end deftypefn
+get_first_help_sentence
+ at c ./help/get_first_help_sentence.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{retval}, @var{status}] =} get_first_help_sentence (@var{name}, @var{max_len})
+Return the first sentence of a function help text.
+
+The function reads the first sentence of the help text of the function
+ at var{name}.  The first sentence is defined as the text after the function
+declaration until either the first period (".") or the first appearance of
+two consecutive end-lines ("\n\n").  The text is truncated to a maximum length
+of @var{max_len}, which defaults to 80.
+
+The optional output argument @var{status} returns the status reported by
+ at code{makeinfo}.  If only one output argument is requested, and @var{status}
+is non-zero, a warning is displayed.
+
+As an example, the first sentence of this help text is
+
+ at example
+ at group
+get_first_help_sentence ("get_first_help_sentence")
+ at print{} ans = Return the first sentence of a function help text.
+ at end group
+ at end example
+ at end deftypefn
+help
+ at c ./help/help.m
+-*- texinfo -*-
+ at deftypefn {Command} help @var{name}
+Display the help text for @var{name}.
+If invoked without any arguments, @code{help} prints a list
+of all the available operators and functions.
+
+For example, the command @kbd{help help} prints a short message
+describing the @code{help} command.
+
+The help command can give you information about operators, but not the
+comma and semicolons that are used as command separators.  To get help
+for those, you must type @kbd{help comma} or @kbd{help semicolon}.
+ at seealso{doc, lookfor, which}
+ at end deftypefn
+type
+ at c ./help/type.m
+-*- texinfo -*-
+ at deftypefn {Command} type options name @dots{}
+Display the definition of each @var{name} that refers to a function.
+
+Normally also displays whether each @var{name} is user-defined or built-in;
+the @code{-q} option suppresses this behavior.
+
+If an output argument is requested nothing is displayed.  Instead, a cell 
+array of strings is returned, where each element corresponds to the 
+definition of each requested function.
+ at end deftypefn
+__additional_help_message__
+ at c ./help/__additional_help_message__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} __additional_help_message__ ()
+Undocumented internal function.
+ at end deftypefn
+which
+ at c ./help/which.m
+-*- texinfo -*-
+ at deffn {Command} which name @dots{}
+Display the type of each @var{name}.  If @var{name} is defined from a
+function file, the full name of the file is also displayed.
+ at seealso{help, lookfor}
+ at end deffn
+print_usage
+ at c ./help/print_usage.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} print_usage ()
+ at deftypefnx{Function File} {} print_usage (@var{name})
+Print the usage message for a function.  When called with no input arguments
+the @code{print_usage} function displays the usage message of the currently
+executing function.
+ at seealso{help}
+ at end deftypefn
+doc
+ at c ./help/doc.m
+-*- texinfo -*-
+ at deftypefn {Command} doc @var{function_name}
+Display documentation for the function @var{function_name}
+directly from an on-line version of
+the printed manual, using the GNU Info browser.  If invoked without
+any arguments, the manual is shown from the beginning.
+
+For example, the command @kbd{doc rand} starts the GNU Info browser
+at the @code{rand} node in the on-line version of the manual.
+
+Once the GNU Info browser is running, help for using it is available
+using the command @kbd{C-h}.
+ at seealso{help}
+ at end deftypefn
+savepath
+ at c ./path/savepath.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} savepath (@var{file})
+Save the portion of the current function search path, that is
+not set during Octave's initialization process, to @var{file}.
+If @var{file} is omitted, @file{~/.octaverc} is used.  If successful,
+ at code{savepath} returns 0.
+ at seealso{path, addpath, rmpath, genpath, pathdef, pathsep}
+ at end deftypefn
+pathdef
+ at c ./path/pathdef.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{val} =} pathdef ()
+Return the default path for Octave.
+The path information is extracted from one of three sources.
+In order of preference, those are;
+
+ at enumerate
+ at item @file{~/.octaverc}
+ at item @file{<octave-home>/@dots{}/<version>/m/startup/octaverc}
+ at item Octave's path prior to changes by any octaverc.
+ at end enumerate
+ at seealso{path, addpath, rmpath, genpath, savepath, pathsep}
+ at end deftypefn
+__extractpath__
+ at c ./path/__extractpath__.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{val} =} __extractpath__ (@var{file})
+Undocumented internal function.
+ at end deftypefn
+matlabroot
+ at c ./path/matlabroot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{val} =} matlabroot ()
+Return the location of Octave's home.
+ at seealso{OCTAVE_HOME}
+ at end deftypefn
+ind2sub
+ at c ./general/ind2sub.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{s1}, @var{s2}, @dots{}, @var{sN}] =} ind2sub (@var{dims}, @var{ind})
+Convert a linear index into subscripts.
+
+The following example shows how to convert the linear index @code{8}
+in a 3-by-3 matrix into a subscript.  The matrix is linearly indexed
+moving from one column to next, filling up all rows in each column.
+ at example
+ at group
+[r, c] = ind2sub ([3, 3], 8)
+ at result{} r =  2
+c =  3
+ at end group
+ at end example
+ at seealso{sub2ind}
+ at end deftypefn
+celldisp
+ at c ./general/celldisp.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} celldisp (@var{c}, @var{name})
+Recursively display the contents of a cell array.  By default the values
+are displayed with the name of the variable @var{c}.  However, this name
+can be replaced with the variable @var{name}.
+ at seealso{disp}
+ at end deftypefn
+sub2ind
+ at c ./general/sub2ind.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{ind} =} sub2ind (@var{dims}, @var{i}, @var{j})
+ at deftypefnx {Function File} {@var{ind} =} sub2ind (@var{dims}, @var{s1}, @var{s2}, @dots{}, @var{sN})
+Convert subscripts into a linear index.
+
+The following example shows how to convert the two-dimensional
+index @code{(2,3)} of a 3-by-3 matrix to a linear index.  The matrix
+is linearly indexed moving from one column to next, filling up
+all rows in each column.
+
+ at example
+ at group
+linear_index = sub2ind ([3, 3], 2, 3)
+ at result{} 8
+ at end group
+ at end example
+ at seealso{ind2sub}
+ at end deftypefn
+pol2cart
+ at c ./general/pol2cart.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{y}] =} pol2cart (@var{theta}, @var{r})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{theta}, @var{r}, @var{z})
+Transform polar or cylindrical to Cartesian coordinates.
+ at var{theta}, @var{r} (and @var{z}) must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{r} is the distance to the z-axis (0, 0, z).
+ at seealso{cart2pol, cart2sph, sph2cart}
+ at end deftypefn
+issymmetric
+ at c ./general/issymmetric.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} issymmetric (@var{x}, @var{tol})
+If @var{x} is symmetric within the tolerance specified by @var{tol},
+then return the dimension of @var{x}.  Otherwise, return 0.  If
+ at var{tol} is omitted, use a tolerance equal to the machine precision.
+Matrix @var{x} is considered symmetric if
+ at code{norm (@var{x} - @var{x}.', inf) / norm (@var{x}, inf) < @var{tol}}.
+ at seealso{size, rows, columns, length, ismatrix, isscalar,
+issquare, isvector}
+ at end deftypefn
+runlength
+ at c ./general/runlength.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} runlength (@var{x})
+Find the lengths of all sequences of common values.  Return the
+vector of lengths and the value that was repeated.
+
+ at example
+ at group
+runlength ([2, 2, 0, 4, 4, 4, 0, 1, 1, 1, 1])
+ at result{}  [2, 1, 3, 1, 4]
+ at end group
+ at end example
+ at end deftypefn
+__splinen__
+ at c ./general/__splinen__.m
+Undocumented internal function.
+circshift
+ at c ./general/circshift.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} circshift (@var{x}, @var{n})
+Circularly shifts the values of the array @var{x}.  @var{n} must be
+a vector of integers no longer than the number of dimensions in 
+ at var{x}.  The values of @var{n} can be either positive or negative,
+which determines the direction in which the values or @var{x} are
+shifted.  If an element of @var{n} is zero, then the corresponding
+dimension of @var{x} will not be shifted.  For example
+
+ at example
+ at group
+x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+circshift (x, 1)
+ at result{}  7, 8, 9
+    1, 2, 3
+    4, 5, 6
+circshift (x, -2)
+ at result{}  7, 8, 9
+    1, 2, 3
+    4, 5, 6
+circshift (x, [0,1])
+ at result{}  3, 1, 2
+    6, 4, 5
+    9, 7, 8
+ at end group
+ at end example
+ at seealso {permute, ipermute, shiftdim}
+ at end deftypefn
+common_size
+ at c ./general/common_size.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{err}, @var{y1}, @dots{}] =} common_size (@var{x1}, @dots{})
+Determine if all input arguments are either scalar or of common
+size.  If so, @var{err} is zero, and @var{yi} is a matrix of the
+common size with all entries equal to @var{xi} if this is a scalar or
+ at var{xi} otherwise.  If the inputs cannot be brought to a common size,
+errorcode is 1, and @var{yi} is @var{xi}.  For example,
+
+ at example
+ at group
+[errorcode, a, b] = common_size ([1 2; 3 4], 5)
+     @result{} errorcode = 0
+     @result{} a = [ 1, 2; 3, 4 ]
+     @result{} b = [ 5, 5; 5, 5 ]
+ at end group
+ at end example
+
+ at noindent
+This is useful for implementing functions where arguments can either
+be scalars or of common size.
+ at end deftypefn
+shift
+ at c ./general/shift.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} shift (@var{x}, @var{b})
+ at deftypefnx {Function File} {} shift (@var{x}, @var{b}, @var{dim})
+If @var{x} is a vector, perform a circular shift of length @var{b} of
+the elements of @var{x}.
+
+If @var{x} is a matrix, do the same for each column of @var{x}.
+If the optional @var{dim} argument is given, operate along this 
+dimension
+ at end deftypefn
+cumtrapz
+ at c ./general/cumtrapz.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{z} =} cumtrapz (@var{y})
+ at deftypefnx {Function File} {@var{z} =} cumtrapz (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{z} =} cumtrapz (@dots{}, @var{dim})
+
+Cumulative numerical integration using trapezoidal method.
+ at code{cumtrapz (@var{y})} computes the cumulative integral of the 
+ at var{y} along the first non-singleton dimension.  If the argument 
+ at var{x} is omitted a equally spaced vector is assumed.  @code{cumtrapz 
+(@var{x}, @var{y})} evaluates the cumulative integral with respect 
+to @var{x}.
+ 
+ at seealso{trapz,cumsum}
+ at end deftypefn
+gradient
+ at c ./general/gradient.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{dx} =} gradient (@var{m})
+ at deftypefnx {Function File} {[@var{dx}, @var{dy}, @var{dz}, @dots{}] =} gradient (@var{m})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{m}, @var{s})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{m}, @var{x}, @var{y}, @var{z}, @dots{})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0}, @var{s})
+ at deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0}, @var{x}, @var{y}, @dots{})
+
+Calculate the gradient of sampled data or a function.  If @var{m}
+is a vector, calculate the one-dimensional gradient of @var{m}.  If
+ at var{m} is a matrix the gradient is calculated for each dimension.
+
+ at code{[@var{dx}, @var{dy}] = gradient (@var{m})} calculates the one
+dimensional gradient for @var{x} and @var{y} direction if @var{m} is a
+matrix.  Additional return arguments can be use for multi-dimensional
+matrices.
+
+A constant spacing between two points can be provided by the
+ at var{s} parameter.  If @var{s} is a scalar, it is assumed to be the spacing
+for all dimensions. 
+Otherwise, separate values of the spacing can be supplied by
+the @var{x}, @dots{} arguments.  Scalar values specify an equidistant spacing.
+Vector values for the @var{x}, @dots{} arguments specify the coordinate for that
+dimension.  The length must match their respective dimension of @var{m}.
+
+At boundary points a linear extrapolation is applied.  Interior points
+are calculated with the first approximation of the numerical gradient
+
+ at example
+y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).
+ at end example
+
+If the first argument @var{f} is a function handle, the gradient of the
+function at the points in @var{x0} is approximated using central
+difference.  For example, @code{gradient (@@cos, 0)} approximates the
+gradient of the cosine function in the point @math{x0 = 0}.  As with
+sampled data, the spacing values between the points from which the
+gradient is estimated can be set via the @var{s} or @var{dx},
+ at var{dy}, @dots{} arguments.  By default a spacing of 1 is used.
+ at seealso{diff, del2}
+ at end deftypefn
+triplequad
+ at c ./general/triplequad.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} triplequad (@var{f}, @var{xa}, @var{xb}, @var{ya}, @var{yb}, @var{za}, @var{zb}, @var{tol}, @var{quadf}, @dots{})
+Numerically evaluate a triple integral.  The function over which to
+integrate is defined by @code{@var{f}}, and the interval for the
+integration is defined by @code{[@var{xa}, @var{xb}, @var{ya},
+ at var{yb}, @var{za}, @var{zb}]}.  The function @var{f} must accept a
+vector @var{x} and a scalar @var{y}, and return a vector of the same
+length as @var{x}.
+
+If defined, @var{tol} defines the absolute tolerance to which to
+which to integrate each sub-integral.
+
+Additional arguments, are passed directly to @var{f}.  To use the default
+value for @var{tol} one may pass an empty matrix.
+ at seealso{dblquad, quad, quadv, quadl, quadgk, trapz}
+ at end deftypefn
+prepad
+ at c ./general/prepad.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} prepad (@var{x}, @var{l}, @var{c})
+ at deftypefnx {Function File} {} prepad (@var{x}, @var{l}, @var{c}, @var{dim})
+Prepend (append) the scalar value @var{c} to the vector @var{x}
+until it is of length @var{l}.  If the third argument is not
+supplied, a value of 0 is used.
+
+If @code{length (@var{x}) > @var{l}}, elements from the beginning (end) of
+ at var{x} are removed until a vector of length @var{l} is obtained.
+
+If @var{x} is a matrix, elements are prepended or removed from each row.
+
+If the optional @var{dim} argument is given, then operate along this
+dimension.
+ at seealso{postpad}
+ at end deftypefn
+cellidx
+ at c ./general/cellidx.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{idxvec}, @var{errmsg}] =} cellidx (@var{listvar}, @var{strlist})
+Return indices of string entries in @var{listvar} that match strings
+in @var{strlist}.
+
+Both @var{listvar} and @var{strlist} may be passed as strings or
+string matrices.  If they are passed as string matrices, each entry
+is processed by @code{deblank} prior to searching for the entries.
+
+The first output is the vector of indices in @var{listvar}.
+
+If @var{strlist} contains a string not in @var{listvar}, then
+an error message is returned in @var{errmsg}.  If only one output
+argument is requested, then @var{cellidx} prints @var{errmsg} to the
+screen and exits with an error.
+ at end deftypefn
+__isequal__
+ at c ./general/__isequal__.m
+Undocumented internal function.
+bitget
+ at c ./general/bitget.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{X} =} bitget (@var{a}, at var{n})
+Return the status of bit(s) @var{n} of unsigned integers in @var{a}
+the lowest significant bit is @var{n} = 1.
+
+ at example
+ at group
+bitget (100, 8:-1:1)
+ at result{} 0  1  1  0  0  1  0  0 
+ at end group
+ at end example
+ at seealso{bitand, bitor, bitxor, bitset, bitcmp, bitshift, bitmax}
+ at end deftypefn
+tril
+ at c ./general/tril.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} tril (@var{a}, @var{k})
+ at deftypefnx {Function File} {} triu (@var{a}, @var{k})
+Return a new matrix formed by extracting the lower (@code{tril})
+or upper (@code{triu}) triangular part of the matrix @var{a}, and
+setting all other elements to zero.  The second argument is optional,
+and specifies how many diagonals above or below the main diagonal should
+also be set to zero.
+
+The default value of @var{k} is zero, so that @code{triu} and
+ at code{tril} normally include the main diagonal as part of the result
+matrix.
+
+If the value of @var{k} is negative, additional elements above (for
+ at code{tril}) or below (for @code{triu}) the main diagonal are also
+selected.
+
+The absolute value of @var{k} must not be greater than the number of
+sub- or super-diagonals.
+
+For example,
+
+ at example
+ at group
+tril (ones (3), -1)
+     @result{}  0  0  0
+         1  0  0
+         1  1  0
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+tril (ones (3), 1)
+     @result{}  1  1  0
+         1  1  1
+         1  1  1
+ at end group
+ at end example
+ at seealso{triu, diag}
+ at end deftypefn
+num2str
+ at c ./general/num2str.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} num2str (@var{x})
+ at deftypefnx {Function File} {} num2str (@var{x}, @var{precision})
+ at deftypefnx {Function File} {} num2str (@var{x}, @var{format})
+Convert a number (or array) to a string (or a character array).  The
+optional second argument may either give the number of significant
+digits (@var{precision}) to be used in the output or a format
+template string (@var{format}) as in @code{sprintf} (@pxref{Formatted
+Output}).  @code{num2str} can also handle complex numbers.  For
+example: 
+
+ at example
+ at group
+num2str (123.456)
+     @result{} "123.46"
+
+num2str (123.456, 4)
+     @result{} "123.5"
+
+s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
+     @result{} s =
+        1.0  1.3
+        3.0  3.6
+whos s
+     @result{}
+      Attr Name        Size                     Bytes  Class
+      ==== ====        ====                     =====  ===== 
+           s           2x8                         16  char
+
+num2str (1.234 + 27.3i)
+     @result{} "1.234+27.3i"
+ at end group
+ at end example
+
+The @code{num2str} function is not very flexible.  For better control
+over the results, use @code{sprintf} (@pxref{Formatted Output}). 
+Note that for complex @var{x}, the format string may only contain one
+output conversion specification and nothing else.  Otherwise, you
+will get unpredictable results.  
+ at seealso{sprintf, int2str, mat2str}
+ at end deftypefn
+bitcmp
+ at c ./general/bitcmp.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bitcmp (@var{a}, @var{k})
+Return the @var{k}-bit complement of integers in @var{a}.  If
+ at var{k} is omitted @code{k = log2 (bitmax) + 1} is assumed.
+
+ at example
+ at group
+bitcmp(7,4)
+ at result{} 8
+dec2bin(11)
+ at result{} 1011
+dec2bin(bitcmp(11, 6))
+ at result{} 110100
+ at end group
+ at end example
+ at seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}
+ at end deftypefn
+rem
+ at c ./general/rem.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} rem (@var{x}, @var{y})
+Return the remainder of the division @code{@var{x} / @var{y}}, computed 
+using the expression
+
+ at example
+x - y .* fix (x ./ y)
+ at end example
+
+An error message is printed if the dimensions of the arguments do not
+agree, or if either of the arguments is complex.
+ at seealso{mod, fmod}
+ at end deftypefn
+interp1q
+ at c ./general/interp1q.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{yi} =} interp1q (@var{x}, @var{y}, @var{xi})
+One-dimensional linear interpolation without error checking.
+Interpolates @var{y}, defined at the points @var{x}, at the points
+ at var{xi}.  The sample points @var{x} must be a strictly monotonically
+increasing column vector.  If @var{y} is an array, treat the columns
+of @var{y} separately.  If @var{y} is a vector, it must be a column
+vector of the same length as @var{x}.
+
+Values of @var{xi} beyond the endpoints of the interpolation result
+in NA being returned.
+
+Note that the error checking is only a significant portion of the
+execution time of this @code{interp1} if the size of the input arguments
+is relatively small.  Therefore, the benefit of using @code{interp1q}
+is relatively small.
+ at seealso{interp1}
+ at end deftypefn
+is_duplicate_entry
+ at c ./general/is_duplicate_entry.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_duplicate_entry (@var{x})
+Return non-zero if any entries in @var{x} are duplicates of one
+another.
+ at end deftypefn
+polyarea
+ at c ./general/polyarea.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyarea (@var{x}, @var{y})
+ at deftypefnx {Function File} {} polyarea (@var{x}, @var{y}, @var{dim})
+
+Determines area of a polygon by triangle method.  The variables
+ at var{x} and @var{y} define the vertex pairs, and must therefore have
+the same shape.  They can be either vectors or arrays.  If they are
+arrays then the columns of @var{x} and @var{y} are treated separately
+and an area returned for each.
+
+If the optional @var{dim} argument is given, then @code{polyarea}
+works along this dimension of the arrays @var{x} and @var{y}.
+
+ at end deftypefn
+structfun
+ at c ./general/structfun.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} structfun (@var{func}, @var{s})
+ at deftypefnx {Function File} {[@var{a}, @var{b}] =} structfun (@dots{})
+ at deftypefnx {Function File} {} structfun (@dots{}, "ErrorHandler", @var{errfunc})
+ at deftypefnx {Function File} {} structfun (@dots{}, "UniformOutput", @var{val})
+
+Evaluate the function named @var{name} on the fields of the structure
+ at var{s}.  The fields of @var{s} are passed to the function @var{func}
+individually.
+
+ at code{structfun} accepts an arbitrary function @var{func} in the form of 
+an inline function, function handle, or the name of a function (in a 
+character string).  In the case of a character string argument, the 
+function must accept a single argument named @var{x}, and it must return 
+a string value.  If the function returns more than one argument, they are
+returned as separate output variables.
+
+If the parameter "UniformOutput" is set to true (the default), then the function
+must return a single element which will be concatenated into the
+return value.  If "UniformOutput" is false, the outputs placed in a structure
+with the same fieldnames as the input structure.
+
+ at example
+ at group
+s.name1 = "John Smith"; 
+s.name2 = "Jill Jones"; 
+structfun (@@(x) regexp (x, '(\w+)$', "matches")@{1@}, s, 
+           "UniformOutput", false)
+ at end group
+ at end example
+
+Given the parameter "ErrorHandler", then @var{errfunc} defines a function to
+call in case @var{func} generates an error.  The form of the function is
+
+ at example
+function [@dots{}] = errfunc (@var{se}, @dots{})
+ at end example
+
+where there is an additional input argument to @var{errfunc} relative to
+ at var{func}, given by @var{se}.  This is a structure with the elements
+"identifier", "message" and "index", giving respectively the error
+identifier, the error message, and the index into the input arguments
+of the element that caused the error.
+ at seealso{cellfun, arrayfun}
+ at end deftypefn
+isa
+ at c ./general/isa.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isa (@var{x}, @var{class})
+Return true if @var{x} is a value from the class @var{class}.
+ at end deftypefn
+del2
+ at c ./general/del2.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {@var{d} =} del2 (@var{m})
+ at deftypefnx {Function File} {@var{d} =} del2 (@var{m}, @var{h})
+ at deftypefnx {Function File} {@var{d} =} del2 (@var{m}, @var{dx}, @var{dy}, @dots{})
+
+Calculate the discrete Laplace
+ at tex
+operator $( \nabla^2 )$.
+ at end tex
+ at ifnottex
+operator.
+ at end ifnottex
+For a 2-dimensional matrix @var{m} this is defined as
+
+ at tex
+$$d = {1 \over 4} \left( {d^2 \over dx^2} M(x,y) + {d^2 \over dy^2} M(x,y) \right)$$
+ at end tex
+ at ifnottex
+ at example
+ at group
+      1    / d^2            d^2         \
+D  = --- * | ---  M(x,y) +  ---  M(x,y) | 
+      4    \ dx^2           dy^2        /
+ at end group
+ at end example
+ at end ifnottex
+
+For N-dimensional arrays the sum in parentheses is expanded to include second derivatives 
+over the additional higher dimensions.
+
+The spacing between evaluation points may be defined by @var{h}, which is a
+scalar defining the equidistant spacing in all dimensions.  Alternatively, 
+the spacing in each dimension may be defined separately by @var{dx}, @var{dy},
+etc.  A scalar spacing argument defines equidistant spacing, whereas a vector
+argument can be used to specify variable spacing.  The length of the spacing vectors
+must match the respective dimension of @var{m}.  The default spacing value
+is 1.
+
+At least 3 data points are needed for each dimension.  Boundary points are
+calculated from the linear extrapolation of interior points.
+
+ at seealso{gradient, diff}
+ at end deftypefn
+logspace
+ at c ./general/logspace.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logspace (@var{base}, @var{limit}, @var{n})
+Similar to @code{linspace} except that the values are logarithmically
+spaced from
+ at tex
+$10^{base}$ to $10^{limit}$.
+ at end tex
+ at ifnottex
+10^base to 10^limit.
+ at end ifnottex
+
+If @var{limit} is equal to
+ at tex
+$\pi$,
+ at end tex
+ at ifnottex
+pi,
+ at end ifnottex
+the points are between
+ at tex
+$10^{base}$ and $\pi$,
+ at end tex
+ at ifnottex
+10^base and pi,
+ at end ifnottex
+ at emph{not}
+ at tex
+$10^{base}$ and $10^{\pi}$,
+ at end tex
+ at ifnottex
+10^base and 10^pi,
+ at end ifnottex
+in order to be compatible with the corresponding @sc{matlab}
+function.
+
+Also for compatibility, return the second argument if fewer than two
+values are requested.
+ at seealso{linspace}
+ at end deftypefn
+bicubic
+ at c ./general/bicubic.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{zi} =} bicubic (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{extrapval})
+
+Return a matrix @var{zi} corresponding to the bicubic
+interpolations at @var{xi} and @var{yi} of the data supplied
+as @var{x}, @var{y} and @var{z}.  Points outside the grid are set
+to @var{extrapval}.
+
+See @url{http://wiki.woodpecker.org.cn/moin/Octave/Bicubic}
+for further information.
+ at seealso{interp2}
+ at end deftypefn
+sortrows
+ at c ./general/sortrows.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sortrows (@var{a}, @var{c})
+Sort the rows of the matrix @var{a} according to the order of the
+columns specified in @var{c}.  If @var{c} is omitted, a
+lexicographical sort is used.  By default ascending order is used 
+however if elements of @var{c} are negative then the corresponding  
+column is sorted in descending order.
+ at end deftypefn
+subsindex
+ at c ./general/subsindex.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{idx} =} subsindex (@var{a})
+Convert an object to an index vector.  When @var{a} is a class object 
+defined with a class constructor, then @code{subsindex} is the
+overloading method that allows the conversion of this class object to
+a valid indexing vector.  It is important to note that
+ at code{subsindex} must return a zero-based real integer vector of the
+class "double".  For example, if the class constructor
+
+ at example
+ at group
+function b = myclass (a)
+ b = myclass (struct ("a", a), "myclass");
+endfunction
+ at end group
+ at end example
+
+ at noindent
+then the @code{subsindex} function
+
+ at example
+ at group
+function idx = subsindex (a)
+ idx = double (a.a) - 1.0;
+endfunction
+ at end group
+ at end example
+
+ at noindent
+can then be used as follows
+
+ at example
+ at group
+a = myclass (1:4);
+b = 1:10;
+b(a)
+ at result{} 1  2  3  4
+ at end group
+ at end example
+
+ at seealso{class, subsref, subsasgn}
+ at end deftypefn
+interp2
+ at c ./general/interp2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{zi} =} interp2 (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{xi}, @var{yi})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{n})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method}, @var{extrapval})
+
+Two-dimensional interpolation.  @var{x}, @var{y} and @var{z} describe a
+surface function.  If @var{x} and @var{y} are vectors their length
+must correspondent to the size of @var{z}.  @var{x} and @var{y} must be
+monotonic.  If they are matrices they must have the @code{meshgrid} 
+format. 
+
+ at table @code
+ at item interp2 (@var{x}, @var{y}, @var{Z}, @var{xi}, @var{yi}, @dots{}) 
+Returns a matrix corresponding to the points described by the
+matrices @var{xi}, @var{yi}.  
+
+If the last argument is a string, the interpolation method can
+be specified.  The method can be 'linear', 'nearest' or 'cubic'.
+If it is omitted 'linear' interpolation is assumed.
+
+ at item interp2 (@var{z}, @var{xi}, @var{yi})
+Assumes @code{@var{x} = 1:rows (@var{z})} and @code{@var{y} = 
+1:columns (@var{z})}
+
+ at item interp2 (@var{z}, @var{n}) 
+Interleaves the matrix @var{z} n-times.  If @var{n} is omitted a value
+of @code{@var{n} = 1} is assumed.
+ at end table
+
+The variable @var{method} defines the method to use for the
+interpolation.  It can take one of the following values 
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors.
+ at item 'pchip'
+Piece-wise cubic hermite interpolating polynomial (not implemented yet).
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors.
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve.
+ at end table
+
+If a scalar value @var{extrapval} is defined as the final value, then
+values outside the mesh as set to this value.  Note that in this case 
+ at var{method} must be defined as well.  If @var{extrapval} is not
+defined then NA is assumed. 
+
+ at seealso{interp1}
+ at end deftypefn
+repmat
+ at c ./general/repmat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} repmat (@var{A}, @var{m}, @var{n})
+ at deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n}])
+ at deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n} @var{p} @dots{}])
+Form a block matrix of size @var{m} by @var{n}, with a copy of matrix
+ at var{A} as each element.  If @var{n} is not specified, form an 
+ at var{m} by @var{m} block matrix.
+ at end deftypefn
+isequal
+ at c ./general/isequal.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isequal (@var{x1}, @var{x2}, @dots{})
+Return true if all of @var{x1}, @var{x2}, @dots{} are equal.
+ at seealso{isequalwithequalnans}
+ at end deftypefn
+deal
+ at c ./general/deal.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} deal (@var{a})
+ at deftypefnx {Function File} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} deal (@var{a1}, @var{a2}, @dots{}, @var{an})
+
+Copy the input parameters into the corresponding output parameters.
+If only one input parameter is supplied, its value is copied to each
+of the outputs.
+
+For example,
+
+ at example
+[a, b, c] = deal (x, y, z);
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+ at group
+a = x;
+b = y;
+c = z;
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+[a, b, c] = deal (x);
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+a = b = c = x;
+ at end example
+ at end deftypefn
+quadv
+ at c ./general/quadv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{q} =} quadv (@var{f}, @var{a}, @var{b})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace}, @var{p1}, @var{p2}, @dots{})
+ at deftypefnx {Function File} {[@var{q}, @var{fcnt}] =} quadl (@dots{})
+
+Numerically evaluate integral using adaptive Simpson's rule.
+ at code{quadv (@var{f}, @var{a}, @var{b})} approximates the integral of
+ at code{@var{f}(@var{x})} to the default absolute tolerance of @code{1e-6}. 
+ at var{f} is either a function handle, inline function or string
+containing the name of the function to evaluate.  The function @var{f}
+must accept a string, and can return a vector representing the
+approximation to @var{n} different sub-functions.
+
+If defined, @var{tol} defines the absolute tolerance to which to
+which to integrate each sub-interval of @code{@var{f}(@var{x})}.
+While if @var{trace} is defined, displays the left end point of the
+current interval, the interval length, and the partial integral.
+
+Additional arguments @var{p1}, etc., are passed directly to @var{f}.
+To use default values for @var{tol} and @var{trace}, one may pass
+empty matrices.
+ at seealso{triplequad, dblquad, quad, quadl, quadgk, trapz}
+ at end deftypefn
+randperm
+ at c ./general/randperm.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} randperm (@var{n})
+Return a row vector containing a random permutation of the
+integers from 1 to @var{n}.
+ at end deftypefn
+interpn
+ at c ./general/interpn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{vi} =} interpn (@var{x1}, @var{x2}, @dots{}, @var{v}, @var{y1}, @var{y2}, @dots{})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@var{v}, @var{y1}, @var{y2}, @dots{})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@var{v}, @var{m})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@var{v})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{vi} =} interpn (@dots{}, @var{method}, @var{extrapval})
+
+Perform @var{n}-dimensional interpolation, where @var{n} is at least two. 
+Each element of the @var{n}-dimensional array @var{v} represents a value 
+at a location given by the parameters @var{x1}, @var{x2}, @dots{}, @var{xn}. 
+The parameters @var{x1}, @var{x2}, @dots{}, @var{xn} are either 
+ at var{n}-dimensional arrays of the same size as the array @var{v} in 
+the 'ndgrid' format or vectors.  The parameters @var{y1}, etc. respect a 
+similar format to @var{x1}, etc., and they represent the points at which
+the array @var{vi} is interpolated.
+
+If @var{x1}, @dots{}, @var{xn} are omitted, they are assumed to be 
+ at code{x1 = 1 : size (@var{v}, 1)}, etc.  If @var{m} is specified, then
+the interpolation adds a point half way between each of the interpolation 
+points.  This process is performed @var{m} times.  If only @var{v} is 
+specified, then @var{m} is assumed to be @code{1}.
+
+Method is one of:
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors.
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors (not implemented yet).
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve.
+ at end table
+
+The default method is 'linear'.
+
+If @var{extrapval} is the scalar value, use it to replace the values
+beyond the endpoints with that number.  If @var{extrapval} is missing,
+assume NA.
+ at seealso{interp1, interp2, spline, ndgrid}
+ at end deftypefn
+fliplr
+ at c ./general/fliplr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fliplr (@var{x})
+Return a copy of @var{x} with the order of the columns reversed.  For
+example,
+
+ at example
+ at group
+fliplr ([1, 2; 3, 4])
+     @result{}  2  1
+         4  3
+ at end group
+ at end example
+
+Note that @code{fliplr} only work with 2-D arrays.  To flip N-d arrays
+use @code{flipdim} instead.
+ at seealso{flipud, flipdim, rot90, rotdim}
+ at end deftypefn
+blkdiag
+ at c ./general/blkdiag.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} blkdiag (@var{a}, @var{b}, @var{c}, @dots{})
+Build a block diagonal matrix from @var{a}, @var{b}, @var{c}, @dots{}.
+All the arguments must be numeric and are two-dimensional matrices or
+scalars.
+ at seealso{diag, horzcat, vertcat}
+ at end deftypefn
+cell2mat
+ at c ./general/cell2mat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{m} =} cell2mat (@var{c})
+Convert the cell array @var{c} into a matrix by concatenating all
+elements of @var{c} into a hyperrectangle.  Elements of @var{c} must
+be numeric, logical or char, and @code{cat} must be able to
+concatenate them together.
+ at seealso{mat2cell, num2cell}
+ at end deftypefn
+interpft
+ at c ./general/interpft.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} interpft (@var{x}, @var{n})
+ at deftypefnx {Function File} {} interpft (@var{x}, @var{n}, @var{dim})
+
+Fourier interpolation.  If @var{x} is a vector, then @var{x} is
+resampled with @var{n} points.  The data in @var{x} is assumed to be
+equispaced.  If @var{x} is an array, then operate along each column of
+the array separately.  If @var{dim} is specified, then interpolate
+along the dimension @var{dim}.
+
+ at code{interpft} assumes that the interpolated function is periodic,
+and so assumptions are made about the end points of the interpolation.
+
+ at seealso{interp1}
+ at end deftypefn
+triu
+ at c ./general/triu.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} triu (@var{a}, @var{k})
+See tril.
+ at end deftypefn
+strerror
+ at c ./general/strerror.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} strerror (@var{name}, @var{num})
+Return the text of an error message for function @var{name}
+corresponding to the error number @var{num}.  This function is intended
+to be used to print useful error messages for those functions that
+return numeric error codes.
+ at end deftypefn
+nargoutchk
+ at c ./general/nargoutchk.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs})
+ at deftypefnx {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string")
+ at deftypefnx {Function File} {@var{msgstruct} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct")
+Return an appropriate error message string (or structure) if the
+number of outputs requested is invalid.
+
+This is useful for checking to see that the number of output
+arguments supplied to a function is within an acceptable range.
+ at seealso{nargchk, error, nargout, nargin}
+ at end deftypefn
+trapz
+ at c ./general/trapz.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{z} =} trapz (@var{y})
+ at deftypefnx {Function File} {@var{z} =} trapz (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{z} =} trapz (@dots{}, @var{dim})
+
+Numerical integration using trapezoidal method.  @code{trapz
+(@var{y})} computes the integral of the @var{y} along the first
+non-singleton dimension.  If the argument @var{x} is omitted a 
+equally spaced vector is assumed.  @code{trapz (@var{x}, @var{y})} 
+evaluates the integral with respect to @var{x}.
+ 
+ at seealso{cumtrapz}
+ at end deftypefn
+dblquad
+ at c ./general/dblquad.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} dblquad (@var{f}, @var{xa}, @var{xb}, @var{ya}, @var{yb}, @var{tol}, @var{quadf}, @dots{})
+Numerically evaluate a double integral.  The function over with to
+integrate is defined by @code{@var{f}}, and the interval for the
+integration is defined by @code{[@var{xa}, @var{xb}, @var{ya},
+ at var{yb}]}.  The function @var{f} must accept a vector @var{x} and a
+scalar @var{y}, and return a vector of the same length as @var{x}. 
+
+If defined, @var{tol} defines the absolute tolerance to which to
+which to integrate each sub-integral.
+
+Additional arguments, are passed directly to @var{f}.  To use the default
+value for @var{tol} one may pass an empty matrix.
+ at seealso{triplequad, quad, quadv, quadl, quadgk, trapz}
+ at end deftypefn
+isdir
+ at c ./general/isdir.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isdir (@var{f})
+Return true if @var{f} is a directory.
+ at end deftypefn
+isvector
+ at c ./general/isvector.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isvector (@var{a})
+Return 1 if @var{a} is a vector.  Otherwise, return 0.
+ at seealso{size, rows, columns, length, isscalar, ismatrix}
+ at end deftypefn
+cart2pol
+ at c ./general/cart2pol.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {[@var{theta}, @var{r}] =} cart2pol (@var{x}, @var{y})
+ at deftypefnx {Function File} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{x}, @var{y}, @var{z})
+Transform Cartesian to polar or cylindrical coordinates.
+ at var{x}, @var{y} (and @var{z}) must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{r} is the distance to the z-axis (0, 0, z).
+ at seealso{pol2cart, cart2sph, sph2cart}
+ at end deftypefn
+idivide
+ at c ./general/idivide.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} idivide (@var{x}, @var{y}, @var{op})
+Integer division with different round rules.  The standard behavior of
+the an integer division such as @code{@var{a} ./ @var{b}} is to round
+the result to the nearest integer.  This is not always the desired
+behavior and @code{idivide} permits integer element-by-element
+division to be performed with different treatment for the fractional
+part of the division as determined by the @var{op} flag.  @var{op} is
+a string with one of the values: 
+
+ at table @asis
+ at item "fix"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+towards zero.
+ at item "round"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+towards the nearest integer.
+ at item "floor"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+downwards.
+ at item "ceil"
+Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+upwards.
+ at end table
+
+ at noindent
+If @var{op} is not given it is assumed that it is @code{"fix"}.
+An example demonstrating these rounding rules is
+
+ at example
+ at group
+idivide (int8 ([-3, 3]), int8 (4), "fix")
+ at result{} int8 ([0, 0])
+idivide (int8 ([-3, 3]), int8 (4), "round")
+ at result{} int8 ([-1, 1])
+idivide (int8 ([-3, 3]), int8 (4), "ceil")
+ at result{} int8 ([0, 1])
+idivide (int8 ([-3, 3]), int8 (4), "floor")
+ at result{} int8 ([-1, 0])
+ at end group
+ at end example
+
+ at seealso{ldivide, rdivide}
+ at end deftypefn
+diff
+ at c ./general/diff.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} diff (@var{x}, @var{k}, @var{dim})
+If @var{x} is a vector of length @var{n}, @code{diff (@var{x})} is the
+vector of first differences
+ at tex
+ $x_2 - x_1, \ldots{}, x_n - x_{n-1}$.
+ at end tex
+ at ifnottex
+ at var{x}(2) - @var{x}(1), @dots{}, @var{x}(n) - @var{x}(n-1).
+ at end ifnottex
+
+If @var{x} is a matrix, @code{diff (@var{x})} is the matrix of column
+differences along the first non-singleton dimension.
+
+The second argument is optional.  If supplied, @code{diff (@var{x},
+ at var{k})}, where @var{k} is a non-negative integer, returns the
+ at var{k}-th differences.  It is possible that @var{k} is larger than
+then first non-singleton dimension of the matrix.  In this case,
+ at code{diff} continues to take the differences along the next
+non-singleton dimension.
+
+The dimension along which to take the difference can be explicitly
+stated with the optional variable @var{dim}.  In this case the 
+ at var{k}-th order differences are calculated along this dimension.
+In the case where @var{k} exceeds @code{size (@var{x}, @var{dim})}
+then an empty matrix is returned.
+ at end deftypefn
+loadobj
+ at c ./general/loadobj.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{b} =} loadobj (@var{a})
+Method of a class to manipulate an object after loading it from a file. 
+The function @code{loadobj} is called when the object @var{a} is loaded 
+using the @code{load} function.  An example of the use of @code{saveobj}
+might be to add fields to an object that don't make sense to be saved.
+For example
+
+ at example
+ at group
+function b = loadobj (a)
+  b = a;
+  b.addmissingfield = addfield (b);
+endfunction
+ at end group
+ at end example
+
+ at seealso{saveobj, class}
+ at end deftypefn
+sph2cart
+ at c ./general/sph2cart.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{theta}, @var{phi}, @var{r})
+Transform spherical to Cartesian coordinates.
+ at var{x}, @var{y} and @var{z} must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{phi} is the angle relative to the xy-plane.
+ at var{r} is the distance to the origin (0, 0, 0).
+ at seealso{pol2cart, cart2pol, cart2sph}
+ at end deftypefn
+cart2sph
+ at c ./general/cart2sph.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{theta}, @var{phi}, @var{r}] =} cart2sph (@var{x}, @var{y}, @var{z})
+Transform Cartesian to spherical coordinates.
+ at var{x}, @var{y} and @var{z} must be the same shape, or scalar.
+ at var{theta} describes the angle relative to the positive x-axis.
+ at var{phi} is the angle relative to the xy-plane.
+ at var{r} is the distance to the origin (0, 0, 0).
+ at seealso{pol2cart, cart2pol, sph2cart}
+ at end deftypefn
+flipdim
+ at c ./general/flipdim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} flipdim (@var{x}, @var{dim})
+Return a copy of @var{x} flipped about the dimension @var{dim}.
+For example
+
+ at example
+ at group
+flipdim ([1, 2; 3, 4], 2)
+     @result{}  2  1
+         4  3
+ at end group
+ at end example
+ at seealso{fliplr, flipud, rot90, rotdim}
+ at end deftypefn
+quadgk
+ at c ./general/quadgk.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} quadgk (@var{f}, @var{a}, @var{b}, @var{abstol}, @var{trace})
+ at deftypefnx {Function File} {} quadgk (@var{f}, @var{a}, @var{b}, @var{prop}, @var{val}, @dots{})
+ at deftypefnx {Function File} {[@var{q}, @var{err}] =} quadgk (@dots{})
+Numerically evaluate integral using adaptive Gauss-Konrod quadrature.
+The formulation is based on a proposal by L.F. Shampine,
+ at cite{"Vectorized adaptive quadrature in @sc{matlab}", Journal of
+Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2,
+Feb 2008} where all function evaluations at an iteration are
+calculated with a single call to @var{f}.  Therefore the function
+ at var{f} must be of the form @code{@var{f} (@var{x})} and accept
+vector values of @var{x} and return a vector of the same length
+representing the function evaluations at the given values of @var{x}.
+The function @var{f} can be defined in terms of a function handle,
+inline function or string.
+
+The bounds of the quadrature @code{[@var{a}, @var{b}]} can be finite
+or infinite and contain weak end singularities.  Variable
+transformation will be used to treat infinite intervals and weaken
+the singularities.  For example
+
+ at example
+quadgk(@@(x) 1 ./ (sqrt (x) .* (x + 1)), 0, Inf)
+ at end example
+
+ at noindent
+Note that the formulation of the integrand uses the
+element-by-element operator @code{./} and all user functions to
+ at code{quadgk} should do the same.
+
+The absolute tolerance can be passed as a fourth argument in a manner
+compatible with @code{quadv}.  Equally the user can request that
+information on the convergence can be printed is the fifth argument
+is logically true.
+
+Alternatively, certain properties of @code{quadgk} can be passed as
+pairs @code{@var{prop}, @var{val}}.  Valid properties are
+
+ at table @code
+ at item AbsTol
+Defines the absolute error tolerance for the quadrature.  The default
+absolute tolerance is 1e-10.
+
+ at item RelTol
+Defines the relative error tolerance for the quadrature.  The default
+relative tolerance is 1e-5.
+
+ at item MaxIntervalCount
+ at code{quadgk} initially subdivides the interval on which to perform
+the quadrature into 10 intervals.  Sub-intervals that have an
+unacceptable error are sub-divided and re-evaluated.  If the number of
+sub-intervals exceeds at any point 650 sub-intervals then a poor
+convergence is signaled and the current estimate of the integral is
+returned.  The property 'MaxIntervalCount' can be used to alter the
+number of sub-intervals that can exist before exiting.
+
+ at item WayPoints
+If there exists discontinuities in the first derivative of the
+function to integrate, then these can be flagged with the
+ at code{"WayPoints"} property.  This forces the ends of a sub-interval
+to fall on the breakpoints of the function and can result in
+significantly improved estimation of the error in the integral, faster
+computation or both.  For example,
+
+ at example
+quadgk (@@(x) abs (1 - x .^ 2), 0, 2, 'Waypoints', 1)
+ at end example
+
+ at noindent
+signals the breakpoint in the integrand at @code{@var{x} = 1}.
+
+ at item Trace
+If logically true, then @code{quadgk} prints information on the
+convergence of the quadrature at each iteration.
+ at end table
+
+If any of @var{a}, @var{b} or @var{waypoints} is complex, then the
+quadrature is treated as a contour integral along a piecewise
+continuous path defined by the above.  In this case the integral is
+assumed to have no edge singularities.  For example
+
+ at example
+ at group
+quadgk (@@(z) log (z), 1+1i, 1+1i, "WayPoints",
+        [1-1i, -1,-1i, -1+1i])
+ at end group
+ at end example
+
+ at noindent
+integrates @code{log (z)} along the square defined by @code{[1+1i,
+ 1-1i, -1-1i, -1+1i]}
+
+If two output arguments are requested, then @var{err} returns the
+approximate bounds on the error in the integral @code{abs (@var{q} -
+ at var{i})}, where @var{i} is the exact value of the integral.
+
+ at seealso{triplequad, dblquad, quad, quadl, quadv, trapz}
+ at end deftypefn
+perror
+ at c ./general/perror.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} perror (@var{name}, @var{num})
+Print the error message for function @var{name} corresponding to the
+error number @var{num}.  This function is intended to be used to print
+useful error messages for those functions that return numeric error
+codes.
+ at seealso{strerror}
+ at end deftypefn
+saveobj
+ at c ./general/saveobj.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{b} =} saveobj (@var{a})
+Method of a class to manipulate an object prior to saving it to a file. 
+The function @code{saveobj} is called when the object @var{a} is saved 
+using the @code{save} function.  An example of the use of @code{saveobj}
+might be to remove fields of the object that don't make sense to be saved
+or it might be used to ensure that certain fields of the object are
+initialized before the object is saved.  For example
+
+ at example
+ at group
+function b = saveobj (a)
+  b = a;
+  if (isempty (b.field))
+     b.field = initfield(b);
+  endif
+endfunction
+ at end group
+ at end example
+
+ at seealso{loadobj, class}
+ at end deftypefn
+interp3
+ at c ./general/interp3.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{vi} =} interp3 (@var{x}, @var{y}, at var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{xi}, @var{yi}, @var{zi})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{m})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@var{v})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method}, @var{extrapval})
+
+Perform 3-dimensional interpolation.  Each element of the 3-dimensional 
+array @var{v} represents a value at a location given by the parameters 
+ at var{x}, @var{y}, and @var{z}.  The parameters @var{x}, @var{x}, and 
+ at var{z} are either 3-dimensional arrays of the same size as the array 
+ at var{v} in the 'meshgrid' format or vectors.  The parameters @var{xi}, etc. 
+respect a similar format to @var{x}, etc., and they represent the points 
+at which the array @var{vi} is interpolated.
+
+If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be 
+ at code{x = 1 : size (@var{v}, 2)}, @code{y = 1 : size (@var{v}, 1)} and
+ at code{z = 1 : size (@var{v}, 3)}.  If @var{m} is specified, then
+the interpolation adds a point half way between each of the interpolation 
+points.  This process is performed @var{m} times.  If only @var{v} is 
+specified, then @var{m} is assumed to be @code{1}.
+
+Method is one of:
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors.
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors (not implemented yet).
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve.
+ at end table
+
+The default method is 'linear'.
+
+If @var{extrap} is the string 'extrap', then extrapolate values beyond
+the endpoints.  If @var{extrap} is a number, replace values beyond the
+endpoints with that number.  If @var{extrap} is missing, assume NA.
+ at seealso{interp1, interp2, spline, meshgrid}
+ at end deftypefn
+isscalar
+ at c ./general/isscalar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isscalar (@var{a})
+Return 1 if @var{a} is a scalar.  Otherwise, return 0.
+ at seealso{size, rows, columns, length, isscalar, ismatrix}
+ at end deftypefn
+shiftdim
+ at c ./general/shiftdim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} shiftdim (@var{x}, @var{n})
+ at deftypefnx {Function File} {[@var{y}, @var{ns}] =} shiftdim (@var{x})
+Shifts the dimension of @var{x} by @var{n}, where @var{n} must be
+an integer scalar.  When @var{n} is positive, the dimensions of
+ at var{x} are shifted to the left, with the leading dimensions
+circulated to the end.  If @var{n} is negative, then the dimensions
+of @var{x} are shifted to the right, with @var{n} leading singleton
+dimensions added.
+
+Called with a single argument, @code{shiftdim}, removes the leading
+singleton dimensions, returning the number of dimensions removed
+in the second output argument @var{ns}.
+
+For example 
+
+ at example
+ at group
+x = ones (1, 2, 3);
+size (shiftdim (x, -1))
+     @result{} [1, 1, 2, 3]
+size (shiftdim (x, 1))
+     @result{} [2, 3]
+[b, ns] = shiftdim (x);
+     @result{} b =  [1, 1, 1; 1, 1, 1]
+     @result{} ns = 1
+ at end group
+ at end example
+ at seealso {reshape, permute, ipermute, circshift, squeeze}
+ at end deftypefn
+rat
+ at c ./general/rat.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{s} =} rat (@var{x}, @var{tol})
+ at deftypefnx {Function File} {[@var{n}, @var{d}] =} rat (@var{x}, @var{tol})
+
+Find a rational approximation to @var{x} within the tolerance defined
+by @var{tol} using a continued fraction expansion.  For example,
+
+ at example
+ at group
+rat(pi) = 3 + 1/(7 + 1/16) = 355/113
+rat(e) = 3 + 1/(-4 + 1/(2 + 1/(5 + 1/(-2 + 1/(-7))))) 
+       = 1457/536
+ at end group
+ at end example
+
+Called with two arguments returns the numerator and denominator separately
+as two matrices.
+ at end deftypefn
+ at seealso{rats}
+isdefinite
+ at c ./general/isdefinite.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isdefinite (@var{x}, @var{tol})
+Return 1 if @var{x} is symmetric positive definite within the
+tolerance specified by @var{tol} or 0 if @var{x} is symmetric
+positive semidefinite.  Otherwise, return -1.  If @var{tol}
+is omitted, use a tolerance equal to 100 times the machine precision.
+ at seealso{issymmetric}
+ at end deftypefn
+nthroot
+ at c ./general/nthroot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nthroot (@var{x}, @var{n})
+
+Compute the n-th root of @var{x}, returning real results for real 
+components of @var{x}.  For example
+
+ at example
+ at group
+nthroot (-1, 3)
+ at result{} -1
+(-1) ^ (1 / 3)
+ at result{} 0.50000 - 0.86603i
+ at end group
+ at end example
+
+ at end deftypefn
+flipud
+ at c ./general/flipud.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} flipud (@var{x})
+Return a copy of @var{x} with the order of the rows reversed.  For
+example,
+
+ at example
+ at group
+flipud ([1, 2; 3, 4])
+     @result{}  3  4
+         1  2
+ at end group
+ at end example
+
+Due to the difficulty of defining which axis about which to flip the 
+matrix @code{flipud} only work with 2-d arrays.  To flip N-d arrays
+use @code{flipdim} instead.
+ at seealso{fliplr, flipdim, rot90, rotdim}
+ at end deftypefn
+postpad
+ at c ./general/postpad.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} postpad (@var{x}, @var{l}, @var{c})
+ at deftypefnx {Function File} {} postpad (@var{x}, @var{l}, @var{c}, @var{dim})
+ at seealso{prepad, resize}
+ at end deftypefn
+nextpow2
+ at c ./general/nextpow2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} nextpow2 (@var{x})
+If @var{x} is a scalar, return the first integer @var{n} such that
+ at tex
+$2^n \ge |x|$.
+ at end tex
+ at ifnottex
+2^n >= abs (x).
+ at end ifnottex
+
+If @var{x} is a vector, return @code{nextpow2 (length (@var{x}))}.
+ at seealso{pow2, log2}
+ at end deftypefn
+accumarray
+ at c ./general/accumarray.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} accumarray (@var{subs}, @var{vals}, @var{sz}, @var{func}, @var{fillval}, @var{issparse})
+ at deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, @dots{})
+
+Create an array by accumulating the elements of a vector into the
+positions defined by their subscripts.  The subscripts are defined by
+the rows of the matrix @var{subs} and the values by @var{vals}.  Each row
+of @var{subs} corresponds to one of the values in @var{vals}.
+
+The size of the matrix will be determined by the subscripts themselves.
+However, if @var{sz} is defined it determines the matrix size.  The length
+of @var{sz} must correspond to the number of columns in @var{subs}.
+
+The default action of @code{accumarray} is to sum the elements with the
+same subscripts.  This behavior can be modified by defining the @var{func}
+function.  This should be a function or function handle that accepts a 
+column vector and returns a scalar.  The result of the function should not
+depend on the order of the subscripts.
+
+The elements of the returned array that have no subscripts associated with
+them are set to zero.  Defining @var{fillval} to some other value allows
+these values to be defined.
+
+By default @code{accumarray} returns a full matrix.  If @var{issparse} is
+logically true, then a sparse matrix is returned instead.
+
+An example of the use of @code{accumarray} is:
+
+ at example
+ at group
+accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+ at result{} ans(:,:,1) = [101, 0, 0; 0, 0, 0]
+   ans(:,:,2) = [0, 0, 0; 206, 0, 208]
+ at end group
+ at end example
+ at end deftypefn
+colon
+ at c ./general/colon.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{r} =} colon (@var{a}, @var{b})
+ at deftypefnx {Function File} {@var{r} =} colon (@var{a}, @var{b}, @var{c})
+Method of a class to construct a range with the @code{:} operator.  For
+example.
+
+ at example
+ at group
+a = myclass (@dots{})
+b = myclass (@dots{})
+c = a : b
+ at end group
+ at end example
+
+ at seealso{class, subsref, subsasgn}
+ at end deftypefn
+display
+ at c ./general/display.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} display (@var{a})
+Display the contents of an object.  If @var{a} is an object of the
+class "myclass", then @code{display} is called in a case like
+
+ at example
+myclass (@dots{})
+ at end example
+
+ at noindent
+where Octave is required to display the contents of a variable of the
+type "myclass".
+
+ at seealso{class, subsref, subsasgn}
+ at end deftypefn
+rotdim
+ at c ./general/rotdim.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rotdim (@var{x}, @var{n}, @var{plane})
+Return a copy of @var{x} with the elements rotated counterclockwise in
+90-degree increments.  The second argument is optional, and specifies
+how many 90-degree rotations are to be applied (the default value is 1).
+The third argument is also optional and defines the plane of the
+rotation.  As such @var{plane} is a two element vector containing two
+different valid dimensions of the matrix.  If @var{plane} is not given
+Then the first two non-singleton dimensions are used.
+
+Negative values of @var{n} rotate the matrix in a clockwise direction.
+For example,
+
+ at example
+ at group
+rotdim ([1, 2; 3, 4], -1, [1, 2])
+     @result{}  3  1
+         4  2
+ at end group
+ at end example
+
+ at noindent
+rotates the given matrix clockwise by 90 degrees.  The following are all
+equivalent statements:
+
+ at example
+ at group
+rotdim ([1, 2; 3, 4], -1, [1, 2])
+rotdim ([1, 2; 3, 4], 3, [1, 2])
+rotdim ([1, 2; 3, 4], 7, [1, 2])
+ at end group
+ at end example
+ at seealso{rot90, flipud, fliplr, flipdim}
+ at end deftypefn
+issquare
+ at c ./general/issquare.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} issquare (@var{x})
+If @var{x} is a square matrix, then return the dimension of @var{x}.
+Otherwise, return 0.
+ at seealso{size, rows, columns, length, ismatrix, isscalar, isvector}
+ at end deftypefn
+logical
+ at c ./general/logical.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} logical (@var{arg})
+Convert @var{arg} to a logical value.  For example,
+
+ at example
+logical ([-1, 0, 1])
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+[-1, 0, 1] != 0
+ at end example
+ at end deftypefn
+bitset
+ at c ./general/bitset.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{x} =} bitset (@var{a}, @var{n})
+ at deftypefnx {Function File} {@var{x} =} bitset (@var{a}, @var{n}, @var{v})
+Set or reset bit(s) @var{n} of unsigned integers in @var{a}.
+ at var{v} = 0 resets and @var{v} = 1 sets the bits.
+The lowest significant bit is: @var{n} = 1
+
+ at example
+ at group
+dec2bin (bitset (10, 1))
+ at result{} 1011
+ at end group
+ at end example
+ at seealso{bitand, bitor, bitxor, bitget, bitcmp, bitshift, bitmax}
+ at end deftypefn
+arrayfun
+ at c ./general/arrayfun.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} arrayfun (@var{func}, @var{a})
+ at deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{a})
+ at deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{a}, @var{b}, @dots{})
+ at deftypefnx {Function File} {[@var{x}, @var{y}, @dots{}] =} arrayfun (@var{func}, @var{a}, @dots{})
+ at deftypefnx {Function File} {} arrayfun (@dots{}, "UniformOutput", @var{val})
+ at deftypefnx {Function File} {} arrayfun (@dots{}, "ErrorHandler", @var{errfunc})
+
+Execute a function on each element of an array.  This is useful for
+functions that do not accept array arguments.  If the function does
+accept array arguments it is better to call the function directly.
+
+The first input argument @var{func} can be a string, a function
+handle, an inline function or an anonymous function.  The input
+argument @var{a} can be a logic array, a numeric array, a string
+array, a structure array or a cell array.  By a call of the function
+ at command{arrayfun} all elements of @var{a} are passed on to the named
+function @var{func} individually.
+
+The named function can also take more than two input arguments, with
+the input arguments given as third input argument @var{b}, fourth
+input argument @var{c}, @dots{}  If given more than one array input
+argument then all input arguments must have the same sizes, for
+example
+
+ at example
+ at group
+arrayfun (@@atan2, [1, 0], [0, 1])
+ at result{} ans = [1.5708   0.0000]
+ at end group
+ at end example
+
+If the parameter @var{val} after a further string input argument
+"UniformOutput" is set @code{true} (the default), then the named
+function @var{func} must return a single element which then will be
+concatenated into the return value and is of type matrix.  Otherwise,
+if that parameter is set to @code{false}, then the outputs are
+concatenated in a cell array.  For example
+
+ at example
+ at group
+arrayfun (@@(x,y) x:y, "abc", "def", "UniformOutput", false)
+ at result{} ans =
+@{
+  [1,1] = abcd
+  [1,2] = bcde
+  [1,3] = cdef
+@}
+ at end group
+ at end example
+
+If more than one output arguments are given then the named function
+must return the number of return values that also are expected, for
+example
+
+ at example
+ at group
+[A, B, C] = arrayfun (@@find, [10; 0], "UniformOutput", false)
+ at result{}
+A =
+@{
+  [1,1] =  1
+  [2,1] = [](0x0)
+@}
+B =
+@{
+  [1,1] =  1
+  [2,1] = [](0x0)
+@}
+C =
+@{
+  [1,1] =  10
+  [2,1] = [](0x0)
+@}
+ at end group
+ at end example
+
+If the parameter @var{errfunc} after a further string input argument
+"ErrorHandler" is another string, a function handle, an inline
+function or an anonymous function, then @var{errfunc} defines a
+function to call in the case that @var{func} generates an error.
+The definition of the function must be of the form
+
+ at example
+function [@dots{}] = errfunc (@var{s}, @dots{})
+ at end example
+
+where there is an additional input argument to @var{errfunc}
+relative to @var{func}, given by @var{s}.  This is a structure with
+the elements "identifier", "message" and "index", giving
+respectively the error identifier, the error message and the index of
+the array elements that caused the error.  The size of the output
+argument of @var{errfunc} must have the same size as the output
+argument of @var{func}, otherwise a real error is thrown.  For
+example
+
+ at example
+ at group
+function y = ferr (s, x), y = "MyString"; endfunction
+arrayfun (@@str2num, [1234], \
+          "UniformOutput", false, "ErrorHandler", @@ferr)
+ at result{} ans =
+@{
+ [1,1] = MyString
+@}
+ at end group
+ at end example
+
+ at seealso{cellfun, spfun, structfun}
+ at end deftypefn
+nargchk
+ at c ./general/nargchk.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{msgstr} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs})
+ at deftypefnx {Function File} {@var{msgstr} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string")
+ at deftypefnx {Function File} {@var{msgstruct} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct")
+Return an appropriate error message string (or structure) if the
+number of inputs requested is invalid.
+
+This is useful for checking to see that the number of input arguments
+supplied to a function is within an acceptable range.
+ at seealso{nargoutchk, error, nargin, nargout}
+ at end deftypefn
+int2str
+ at c ./general/int2str.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} int2str (@var{n})
+Convert an integer (or array of integers) to a string (or a character
+array).
+
+ at example
+ at group
+
+int2str (123)
+     @result{} "123"
+
+s = int2str ([1, 2, 3; 4, 5, 6])
+     @result{} s = 
+        1  2  3
+        4  5  6
+
+whos s
+     @result{} s = 
+      Attr Name        Size                     Bytes  Class
+      ==== ====        ====                     =====  ===== 
+           s           2x7                         14  char
+ at end group
+ at end example
+
+This function is not very flexible.  For better control over the
+results, use @code{sprintf} (@pxref{Formatted Output}). 
+ at seealso{sprintf, num2str, mat2str}
+ at end deftypefn
+mod
+ at c ./general/mod.m
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} mod (@var{x}, @var{y})
+Compute the modulo of @var{x} and @var{y}.  Conceptually this is given by
+
+ at example
+x - y .* floor (x ./ y)
+ at end example
+
+and is written such that the correct modulus is returned for
+integer types.  This function handles negative values correctly.  That
+is, @code{mod (-1, 3)} is 2, not -1, as @code{rem (-1, 3)} returns.
+ at code{mod (@var{x}, 0)} returns @var{x}.
+
+An error results if the dimensions of the arguments do not agree, or if
+either of the arguments is complex.
+ at seealso{rem, fmod}
+ at end deftypefn
+rot90
+ at c ./general/rot90.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rot90 (@var{x}, @var{n})
+Return a copy of @var{x} with the elements rotated counterclockwise in
+90-degree increments.  The second argument is optional, and specifies
+how many 90-degree rotations are to be applied (the default value is 1).
+Negative values of @var{n} rotate the matrix in a clockwise direction.
+For example,
+
+ at example
+ at group
+rot90 ([1, 2; 3, 4], -1)
+     @result{}  3  1
+         4  2
+ at end group
+ at end example
+
+ at noindent
+rotates the given matrix clockwise by 90 degrees.  The following are all
+equivalent statements:
+
+ at example
+ at group
+rot90 ([1, 2; 3, 4], -1)
+rot90 ([1, 2; 3, 4], 3)
+rot90 ([1, 2; 3, 4], 7)
+ at end group
+ at end example
+
+Due to the difficulty of defining an axis about which to rotate the 
+matrix @code{rot90} only work with 2-D arrays.  To rotate N-d arrays
+use @code{rotdim} instead.
+ at seealso{rotdim, flipud, fliplr, flipdim}
+ at end deftypefn
+quadl
+ at c ./general/quadl.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace})
+ at deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace}, @var{p1}, @var{p2}, @dots{})
+
+Numerically evaluate integral using adaptive Lobatto rule.
+ at code{quadl (@var{f}, @var{a}, @var{b})} approximates the integral of
+ at code{@var{f}(@var{x})} to machine precision.  @var{f} is either a
+function handle, inline function or string containing the name of
+the function to evaluate.  The function @var{f} must return a vector
+of output values if given a vector of input values.
+
+If defined, @var{tol} defines the relative tolerance to which to
+which to integrate @code{@var{f}(@var{x})}.  While if @var{trace} is
+defined, displays the left end point of the current interval, the 
+interval length, and the partial integral.
+
+Additional arguments @var{p1}, etc., are passed directly to @var{f}.
+To use default values for @var{tol} and @var{trace}, one may pass
+empty matrices.
+
+Reference: W. Gander and W. Gautschi, 'Adaptive Quadrature - 
+Revisited', BIT Vol. 40, No. 1, March 2000, pp. 84--101.
+ at url{http://www.inf.ethz.ch/personal/gander/}
+
+ at end deftypefn
+isequalwithequalnans
+ at c ./general/isequalwithequalnans.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} isequalwithequalnans (@var{x1}, @var{x2}, @dots{})
+Assuming NaN == NaN, return true if all of @var{x1}, @var{x2}, @dots{}
+are equal.
+ at seealso{isequal}
+ at end deftypefn
+interp1
+ at c ./general/interp1.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{yi} =} interp1 (@var{x}, @var{y}, @var{xi})
+ at deftypefnx {Function File} {@var{yi} =} interp1 (@dots{}, @var{method})
+ at deftypefnx {Function File} {@var{yi} =} interp1 (@dots{}, @var{extrap})
+ at deftypefnx {Function File} {@var{pp} =} interp1 (@dots{}, 'pp')
+
+One-dimensional interpolation.  Interpolate @var{y}, defined at the
+points @var{x}, at the points @var{xi}.  The sample points @var{x} 
+must be strictly monotonic.  If @var{y} is an array, treat the columns
+of @var{y} separately.
+
+Method is one of:
+
+ at table @asis
+ at item 'nearest'
+Return the nearest neighbor.
+ at item 'linear'
+Linear interpolation from nearest neighbors
+ at item 'pchip'
+Piece-wise cubic hermite interpolating polynomial
+ at item 'cubic'
+Cubic interpolation from four nearest neighbors
+ at item 'spline'
+Cubic spline interpolation--smooth first and second derivatives
+throughout the curve
+ at end table
+
+Appending '*' to the start of the above method forces @code{interp1}
+to assume that @var{x} is uniformly spaced, and only @code{@var{x}
+(1)} and @code{@var{x} (2)} are referenced.  This is usually faster,
+and is never slower.  The default method is 'linear'.
+
+If @var{extrap} is the string 'extrap', then extrapolate values beyond
+the endpoints.  If @var{extrap} is a number, replace values beyond the
+endpoints with that number.  If @var{extrap} is missing, assume NA.
+
+If the string argument 'pp' is specified, then @var{xi} should not be
+supplied and @code{interp1} returns the piece-wise polynomial that
+can later be used with @code{ppval} to evaluate the interpolation.
+There is an equivalence, such that @code{ppval (interp1 (@var{x},
+ at var{y}, @var{method}, 'pp'), @var{xi}) == interp1 (@var{x}, @var{y},
+ at var{xi}, @var{method}, 'extrap')}.
+
+An example of the use of @code{interp1} is
+
+ at example
+ at group
+xf = [0:0.05:10];
+yf = sin (2*pi*xf/5);
+xp = [0:10];
+yp = sin (2*pi*xp/5);
+lin = interp1 (xp, yp, xf);
+spl = interp1 (xp, yp, xf, "spline");
+cub = interp1 (xp, yp, xf, "cubic");
+near = interp1 (xp, yp, xf, "nearest");
+plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
+      xf, cub, "c", xf, near, "m", xp, yp, "r*");
+legend ("original", "linear", "spline", "cubic", "nearest")
+ at end group
+ at end example
+
+ at seealso{interpft}
+ at end deftypefn
+cplxpair
+ at c ./general/cplxpair.m
+-*- texinfo -*-
+ at deftypefn  {Function File} {} cplxpair (@var{z})
+ at deftypefnx {Function File} {} cplxpair (@var{z}, @var{tol})
+ at deftypefnx {Function File} {} cplxpair (@var{z}, @var{tol}, @var{dim})
+Sort the numbers @var{z} into complex conjugate pairs ordered by 
+increasing real part.  Place the negative imaginary complex number
+first within each pair.  Place all the real numbers (those with
+ at code{abs (imag (@var{z}) / @var{z}) < @var{tol})}) after the
+complex pairs.
+
+If @var{tol} is unspecified the default value is 100*@code{eps}.
+
+By default the complex pairs are sorted along the first non-singleton
+dimension of @var{z}.  If @var{dim} is specified, then the complex
+pairs are sorted along this dimension.
+
+Signal an error if some complex numbers could not be paired.  Signal an
+error if all complex numbers are not exact conjugates (to within
+ at var{tol}).  Note that there is no defined order for pairs with identical
+real parts but differing imaginary parts.
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+cplxpair (exp(2i*pi*[0:4]'/5)) == exp(2i*pi*[3; 2; 4; 1; 0]/5)
+ at end smallexample
+ at end deftypefn
+genvarname
+ at c ./general/genvarname.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{varname} =} genvarname (@var{str})
+ at deftypefnx {Function File} {@var{varname} =} genvarname (@var{str}, @var{exclusions})
+Create unique variable(s) from @var{str}.  If @var{exclusions} is
+given, then the variable(s) will be unique to each other and to
+ at var{exclusions} (@var{exclusions} may be either a string or a cellstr).
+
+If @var{str} is a cellstr, then a unique variable is created for each
+cell in @var{str}.
+
+ at example
+ at group
+x = 3.141;
+genvarname ("x", who ())
+ at result{} x1
+ at end group
+ at end example
+
+If @var{wanted} is a cell array, genvarname will make sure the returned
+strings are distinct:
+
+ at example
+ at group
+genvarname (@{"foo", "foo"@})
+ at result{}
+@{
+  [1,1] = foo
+  [1,2] = foo1
+@}
+ at end group
+ at end example
+
+Note that the result is a char array/cell array of strings, not the
+variables themselves.  To define a variable, @code{eval()} can be
+used.  The following trivial example sets @code{x} to @code{42}.
+
+ at example
+ at group
+name = genvarname ("x");
+eval([name " = 42"]);
+ at result{} x =  42
+ at end group
+ at end example
+
+Also, this can be useful for creating unique struct field names.
+
+ at example
+ at group
+x = struct ();
+for i = 1:3
+  x.(genvarname ("a", fieldnames (x))) = i;
+endfor
+ at result{}
+x =
+@{
+  a =  1
+  a1 =  2
+  a2 =  3
+@}
+ at end group
+ at end example
+
+Since variable names may only contain letters, digits and underscores,
+genvarname replaces any sequence of disallowed characters with
+an underscore.  Also, variables may not begin with a digit; in this
+case an underscore is added before the variable name.
+
+Variable names beginning and ending with two underscores "__" are valid but
+they are used internally by octave and should generally be avoided, therefore
+genvarname will not generate such names.
+
+genvarname will also make sure that returned names do not clash with
+keywords such as "for" and "if".  A number will be appended if necessary.
+Note, however, that this does @strong{not} include function names,
+such as "sin".  Such names should be included in @var{avoid} if necessary.
+ at seealso{isvarname, exist, tmpnam, eval}
+ at end deftypefn
+fractdiff
+ at c ./signal/fractdiff.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fractdiff (@var{x}, @var{d})
+Compute the fractional differences @math{(1-L)^d x} where @math{L}
+denotes the lag-operator and @math{d} is greater than -1.
+ at end deftypefn
+hanning
+ at c ./signal/hanning.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hanning (@var{m})
+Return the filter coefficients of a Hanning window of length @var{m}.
+
+For a definition of this window type, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+fftshift
+ at c ./signal/fftshift.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fftshift (@var{v})
+ at deftypefnx {Function File} {} fftshift (@var{v}, @var{dim})
+Perform a shift of the vector @var{v}, for use with the @code{fft}
+and @code{ifft} functions, in order the move the frequency 0 to the
+center of the vector or matrix.
+
+If @var{v} is a vector of @math{N} elements corresponding to @math{N}
+time samples spaced of @math{Dt} each, then @code{fftshift (fft
+(@var{v}))} corresponds to frequencies
+
+ at example
+f = ((1:N) - ceil(N/2)) / N / Dt
+ at end example
+
+If @var{v} is a matrix, the same holds for rows and columns.  If 
+ at var{v} is an array, then the same holds along each dimension.
+
+The optional @var{dim} argument can be used to limit the dimension
+along which the permutation occurs.
+ at end deftypefn
+freqz_plot
+ at c ./signal/freqz_plot.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} freqz_plot (@var{w}, @var{h})
+Plot the pass band, stop band and phase response of @var{h}.
+ at end deftypefn
+sinewave
+ at c ./signal/sinewave.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sinewave (@var{m}, @var{n}, @var{d})
+Return an @var{m}-element vector with @var{i}-th element given by
+ at code{sin (2 * pi * (@var{i}+ at var{d}-1) / @var{n})}.
+
+The default value for @var{d} is 0 and the default value for @var{n}
+is @var{m}.
+ at end deftypefn
+autocov
+ at c ./signal/autocov.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} autocov (@var{x}, @var{h})
+Return the autocovariances from lag 0 to @var{h} of vector @var{x}.
+If @var{h} is omitted, all autocovariances are computed.
+If @var{x} is a matrix, the autocovariances of each column are
+computed.
+ at end deftypefn
+freqz
+ at c ./signal/freqz.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{h}, @var{w}] =} freqz (@var{b}, @var{a}, @var{n}, "whole")
+Return the complex frequency response @var{h} of the rational IIR filter
+whose numerator and denominator coefficients are @var{b} and @var{a},
+respectively.  The response is evaluated at @var{n} angular frequencies
+between 0 and
+ at ifnottex
+ 2*pi.
+ at end ifnottex
+ at tex
+ $2\pi$.
+ at end tex
+
+ at noindent
+The output value @var{w} is a vector of the frequencies.
+
+If the fourth argument is omitted, the response is evaluated at
+frequencies between 0 and
+ at ifnottex
+ pi.
+ at end ifnottex
+ at tex
+ $\pi$.
+ at end tex
+
+If @var{n} is omitted, a value of 512 is assumed.
+
+If @var{a} is omitted, the denominator is assumed to be 1 (this
+corresponds to a simple FIR filter).
+
+For fastest computation, @var{n} should factor into a small number of
+small primes.
+
+ at deftypefnx {Function File} {@var{h} =} freqz (@var{b}, @var{a}, @var{w})
+Evaluate the response at the specific frequencies in the vector @var{w}.
+The values for @var{w} are measured in radians.
+
+ at deftypefnx {Function File} {[@dots{}] =} freqz (@dots{}, @var{Fs})
+Return frequencies in Hz instead of radians assuming a sampling rate
+ at var{Fs}.  If you are evaluating the response at specific frequencies 
+ at var{w}, those frequencies should be requested in Hz rather than radians.
+
+ at deftypefnx {Function File} {} freqz (@dots{})
+Plot the pass band, stop band and phase response of @var{h} rather
+than returning them.
+ at end deftypefn
+periodogram
+ at c ./signal/periodogram.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} periodogram (@var{x})
+For a data matrix @var{x} from a sample of size @var{n}, return the
+periodogram.
+ at end deftypefn
+arch_rnd
+ at c ./signal/arch_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} arch_rnd (@var{a}, @var{b}, @var{t})
+Simulate an ARCH sequence of length @var{t} with AR
+coefficients @var{b} and CH coefficients @var{a}.  I.e., the result
+ at math{y(t)} follows the model
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+y(t) = b(1) + b(2) * y(t-1) + @dots{} + b(lb) * y(t-lb+1) + e(t),
+ at end smallexample
+
+ at noindent
+where @math{e(t)}, given @var{y} up to time @math{t-1}, is
+ at math{N(0, h(t))}, with
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+h(t) = a(1) + a(2) * e(t-1)^2 + @dots{} + a(la) * e(t-la+1)^2
+ at end smallexample
+ at end deftypefn
+sinetone
+ at c ./signal/sinetone.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sinetone (@var{freq}, @var{rate}, @var{sec}, @var{ampl})
+Return a sinetone of frequency @var{freq} with length of @var{sec}
+seconds at sampling rate @var{rate} and with amplitude @var{ampl}.
+The arguments @var{freq} and @var{ampl} may be vectors of common size.
+
+Defaults are @var{rate} = 8000, @var{sec} = 1 and @var{ampl} = 64.
+ at end deftypefn
+triangle_sw
+ at c ./signal/triangle_sw.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} triangle_sw (@var{n}, @var{b})
+Triangular spectral window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+hamming
+ at c ./signal/hamming.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hamming (@var{m})
+Return the filter coefficients of a Hamming window of length @var{m}.
+
+For a definition of the Hamming window, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+diffpara
+ at c ./signal/diffpara.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{d}, @var{dd}] =} diffpara (@var{x}, @var{a}, @var{b})
+Return the estimator @var{d} for the differencing parameter of an
+integrated time series.
+
+The frequencies from @math{[2*pi*a/t, 2*pi*b/T]} are used for the
+estimation.  If @var{b} is omitted, the interval
+ at math{[2*pi/T, 2*pi*a/T]} is used.  If both @var{b} and @var{a} are
+omitted then @math{a = 0.5 * sqrt (T)} and @math{b = 1.5 * sqrt (T)}
+is used, where @math{T} is the sample size.  If @var{x} is a matrix,
+the differencing parameter of each column is estimated.
+
+The estimators for all frequencies in the intervals
+described above is returned in @var{dd}.  The value of @var{d} is
+simply the mean of @var{dd}.
+
+Reference: Brockwell, Peter J. & Davis, Richard A. Time Series:
+Theory and Methods Springer 1987.
+ at end deftypefn
+rectangle_lw
+ at c ./signal/rectangle_lw.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rectangle_lw (@var{n}, @var{b})
+Rectangular lag window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+blackman
+ at c ./signal/blackman.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} blackman (@var{m})
+Return the filter coefficients of a Blackman window of length @var{m}.
+
+For a definition of the Blackman window, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+detrend
+ at c ./signal/detrend.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} detrend (@var{x}, @var{p})
+If @var{x} is a vector, @code{detrend (@var{x}, @var{p})} removes the
+best fit of a polynomial of order @var{p} from the data @var{x}.
+
+If @var{x} is a matrix, @code{detrend (@var{x}, @var{p})} does the same
+for each column in @var{x}.
+
+The second argument is optional.  If it is not specified, a value of 1
+is assumed.  This corresponds to removing a linear trend.
+ at end deftypefn
+stft
+ at c ./signal/stft.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{y}, @var{c}] =} stft (@var{x}, @var{win_size}, @var{inc}, @var{num_coef}, @var{w_type})
+Compute the short-time Fourier transform of the vector @var{x} with
+ at var{num_coef} coefficients by applying a window of @var{win_size} data
+points and an increment of @var{inc} points.
+
+Before computing the Fourier transform, one of the following windows
+is applied:
+
+ at table @asis
+ at item hanning
+w_type = 1
+ at item hamming
+w_type = 2
+ at item rectangle
+w_type = 3
+ at end table
+
+The window names can be passed as strings or by the @var{w_type} number.
+
+If not all arguments are specified, the following defaults are used:
+ at var{win_size} = 80, @var{inc} = 24, @var{num_coef} = 64, and
+ at var{w_type} = 1.
+
+ at code{@var{y} = stft (@var{x}, @dots{})} returns the absolute values
+of the Fourier coefficients according to the @var{num_coef} positive
+frequencies.
+
+ at code{[@var{y}, @var{c}] = stft (@code{x}, @dots{})} returns the
+entire STFT-matrix @var{y} and a 3-element vector @var{c} containing
+the window size, increment, and window type, which is needed by the
+synthesis function.
+ at end deftypefn
+spectral_adf
+ at c ./signal/spectral_adf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spectral_adf (@var{c}, @var{win}, @var{b})
+Return the spectral density estimator given a vector of
+autocovariances @var{c}, window name @var{win}, and bandwidth,
+ at var{b}.
+
+The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+used to search for a function called @code{@var{win}_sw}.
+
+If @var{win} is omitted, the triangle window is used.  If @var{b} is
+omitted, @code{1 / sqrt (length (@var{x}))} is used.
+ at end deftypefn
+filter2
+ at c ./signal/filter2.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} filter2 (@var{b}, @var{x})
+ at deftypefnx {Function File} {@var{y} =} filter2 (@var{b}, @var{x}, @var{shape})
+Apply the 2-D FIR filter @var{b} to @var{x}.  If the argument
+ at var{shape} is specified, return an array of the desired shape.
+Possible values are: 
+
+ at table @asis
+ at item 'full'
+pad @var{x} with zeros on all sides before filtering.
+ at item 'same'
+unpadded @var{x} (default)
+ at item 'valid'
+trim @var{x} after filtering so edge effects are no included.
+ at end table
+
+Note this is just a variation on convolution, with the parameters
+reversed and @var{b} rotated 180 degrees.
+ at seealso{conv2}
+ at end deftypefn
+fftfilt
+ at c ./signal/fftfilt.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fftfilt (@var{b}, @var{x}, @var{n})
+
+With two arguments, @code{fftfilt} filters @var{x} with the FIR filter
+ at var{b} using the FFT.
+
+Given the optional third argument, @var{n}, @code{fftfilt} uses the
+overlap-add method to filter @var{x} with @var{b} using an N-point FFT.
+
+If @var{x} is a matrix, filter each column of the matrix.
+ at end deftypefn
+fftconv
+ at c ./signal/fftconv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} fftconv (@var{a}, @var{b}, @var{n})
+Return the convolution of the vectors @var{a} and @var{b}, as a vector
+with length equal to the @code{length (a) + length (b) - 1}.  If @var{a}
+and @var{b} are the coefficient vectors of two polynomials, the returned
+value is the coefficient vector of the product polynomial.
+
+The computation uses the FFT by calling the function @code{fftfilt}.  If
+the optional argument @var{n} is specified, an N-point FFT is used.
+ at end deftypefn
+triangle_lw
+ at c ./signal/triangle_lw.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} triangle_lw (@var{n}, @var{b})
+Triangular lag window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+ifftshift
+ at c ./signal/ifftshift.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ifftshift (@var{v})
+ at deftypefnx {Function File} {} ifftshift (@var{v}, @var{dim})
+Undo the action of the @code{fftshift} function.  For even length 
+ at var{v}, @code{fftshift} is its own inverse, but odd lengths differ 
+slightly.
+ at end deftypefn
+durbinlevinson
+ at c ./signal/durbinlevinson.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} durbinlevinson (@var{c}, @var{oldphi}, @var{oldv})
+Perform one step of the Durbin-Levinson algorithm.
+
+The vector @var{c} specifies the autocovariances @code{[gamma_0, @dots{},
+gamma_t]} from lag 0 to @var{t}, @var{oldphi} specifies the
+coefficients based on @var{c}(@var{t}-1) and @var{oldv} specifies the
+corresponding error.
+
+If @var{oldphi} and @var{oldv} are omitted, all steps from 1 to
+ at var{t} of the algorithm are performed.
+ at end deftypefn
+unwrap
+ at c ./signal/unwrap.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{b} =} unwrap (@var{a}, @var{tol}, @var{dim})
+
+Unwrap radian phases by adding multiples of 2*pi as appropriate to
+remove jumps greater than @var{tol}.  @var{tol} defaults to pi.
+
+Unwrap will unwrap along the first non-singleton dimension of
+ at var{a}, unless the optional argument @var{dim} is given, in 
+which case the data will be unwrapped along this dimension
+ at end deftypefn
+arch_fit
+ at c ./signal/arch_fit.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{a}, @var{b}] =} arch_fit (@var{y}, @var{x}, @var{p}, @var{iter}, @var{gamma}, @var{a0}, @var{b0})
+Fit an ARCH regression model to the time series @var{y} using the
+scoring algorithm in Engle's original ARCH paper.  The model is
+
+ at example
+ at group
+y(t) = b(1) * x(t,1) + @dots{} + b(k) * x(t,k) + e(t),
+h(t) = a(1) + a(2) * e(t-1)^2 + @dots{} + a(p+1) * e(t-p)^2
+ at end group
+ at end example
+
+ at noindent
+in which @math{e(t)} is @math{N(0, h(t))}, given a time-series vector
+ at var{y} up to time @math{t-1} and a matrix of (ordinary) regressors
+ at var{x} up to @math{t}.  The order of the regression of the residual
+variance is specified by @var{p}.
+
+If invoked as @code{arch_fit (@var{y}, @var{k}, @var{p})} with a
+positive integer @var{k}, fit an ARCH(@var{k}, @var{p}) process,
+i.e., do the above with the @math{t}-th row of @var{x} given by
+
+ at example
+[1, y(t-1), @dots{}, y(t-k)]
+ at end example
+
+Optionally, one can specify the number of iterations @var{iter}, the
+updating factor @var{gamma}, and initial values @math{a0} and
+ at math{b0} for the scoring algorithm.
+ at end deftypefn
+spectral_xdf
+ at c ./signal/spectral_xdf.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spectral_xdf (@var{x}, @var{win}, @var{b})
+Return the spectral density estimator given a data vector @var{x},
+window name @var{win}, and bandwidth, @var{b}.
+
+The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+used to search for a function called @code{@var{win}_sw}.
+
+If @var{win} is omitted, the triangle window is used.  If @var{b} is
+omitted, @code{1 / sqrt (length (@var{x}))} is used.
+ at end deftypefn
+synthesis
+ at c ./signal/synthesis.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} synthesis (@var{y}, @var{c})
+Compute a signal from its short-time Fourier transform @var{y} and a
+3-element vector @var{c} specifying window size, increment, and
+window type.
+
+The values @var{y} and @var{c} can be derived by
+
+ at example
+[@var{y}, @var{c}] = stft (@var{x} , @dots{})
+ at end example
+ at end deftypefn
+rectangle_sw
+ at c ./signal/rectangle_sw.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} rectangle_sw (@var{n}, @var{b})
+Rectangular spectral window.  Subfunction used for spectral density
+estimation.
+ at end deftypefn
+yulewalker
+ at c ./signal/yulewalker.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{a}, @var{v}] =} yulewalker (@var{c})
+Fit an AR (p)-model with Yule-Walker estimates given a vector @var{c}
+of autocovariances @code{[gamma_0, @dots{}, gamma_p]}.
+
+Returns the AR coefficients, @var{a}, and the variance of white
+noise, @var{v}.
+ at end deftypefn
+arch_test
+ at c ./signal/arch_test.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{pval}, @var{lm}] =} arch_test (@var{y}, @var{x}, @var{p})
+For a linear regression model
+
+ at example
+y = x * b + e
+ at end example
+
+ at noindent
+perform a Lagrange Multiplier (LM) test of the null hypothesis of no
+conditional heteroscedascity against the alternative of CH(@var{p}).
+
+I.e., the model is
+
+ at example
+y(t) = b(1) * x(t,1) + @dots{} + b(k) * x(t,k) + e(t),
+ at end example
+
+ at noindent
+given @var{y} up to @math{t-1} and @var{x} up to @math{t},
+ at math{e}(t) is @math{N(0, h(t))} with
+
+ at example
+h(t) = v + a(1) * e(t-1)^2 + @dots{} + a(p) * e(t-p)^2,
+ at end example
+
+ at noindent
+and the null is @math{a(1)} == @dots{} == @math{a(p)} == 0.
+
+If the second argument is a scalar integer, @math{k}, perform the same
+test in a linear autoregression model of order @math{k}, i.e., with
+
+ at example
+[1, y(t-1), @dots{}, y(t- at var{k})]
+ at end example
+
+ at noindent
+as the @math{t}-th row of @var{x}.
+
+Under the null, LM approximately has a chisquare distribution with
+ at var{p} degrees of freedom and @var{pval} is the @math{p}-value (1
+minus the CDF of this distribution at LM) of the test.
+
+If no output argument is given, the @math{p}-value is displayed.
+ at end deftypefn
+arma_rnd
+ at c ./signal/arma_rnd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} arma_rnd (@var{a}, @var{b}, @var{v}, @var{t}, @var{n})
+Return a simulation of the ARMA model
+
+ at example
+ at group
+x(n) = a(1) * x(n-1) + @dots{} + a(k) * x(n-k)
+     + e(n) + b(1) * e(n-1) + @dots{} + b(l) * e(n-l)
+ at end group
+ at end example
+
+ at noindent
+in which @var{k} is the length of vector @var{a}, @var{l} is the
+length of vector @var{b} and @var{e} is Gaussian white noise with
+variance @var{v}.  The function returns a vector of length @var{t}.
+
+The optional parameter @var{n} gives the number of dummy
+ at var{x}(@var{i}) used for initialization, i.e., a sequence of length
+ at var{t}+ at var{n} is generated and @var{x}(@var{n}+1:@var{t}+ at var{n})
+is returned.  If @var{n} is omitted, @var{n} = 100 is used. 
+ at end deftypefn
+sinc
+ at c ./signal/sinc.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} sinc (@var{x})
+Return
+ at tex
+$ \sin (\pi x)/(\pi x)$.
+ at end tex
+ at ifnottex
+ sin(pi*x)/(pi*x).
+ at end ifnottex
+ at end deftypefn
+autoreg_matrix
+ at c ./signal/autoreg_matrix.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} autoreg_matrix (@var{y}, @var{k})
+Given a time series (vector) @var{y}, return a matrix with ones in the
+first column and the first @var{k} lagged values of @var{y} in the
+other columns.  I.e., for @var{t} > @var{k}, @code{[1,
+ at var{y}(@var{t}-1), @dots{}, @var{y}(@var{t}- at var{k})]} is the t-th row
+of the result.  The resulting matrix may be used as a regressor matrix
+in autoregressions.
+ at end deftypefn
+autocor
+ at c ./signal/autocor.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} autocor (@var{x}, @var{h})
+Return the autocorrelations from lag 0 to @var{h} of vector @var{x}.
+If @var{h} is omitted, all autocorrelations are computed.
+If @var{x} is a matrix, the autocorrelations of each column are
+computed.
+ at end deftypefn
+bartlett
+ at c ./signal/bartlett.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} bartlett (@var{m})
+Return the filter coefficients of a Bartlett (triangular) window of
+length @var{m}.
+
+For a definition of the Bartlett window, see e.g., A. V. Oppenheim &
+R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+ at end deftypefn
+hurst
+ at c ./signal/hurst.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} hurst (@var{x})
+Estimate the Hurst parameter of sample @var{x} via the rescaled range
+statistic.  If @var{x} is a matrix, the parameter is estimated for
+every single column.
+ at end deftypefn
+spencer
+ at c ./signal/spencer.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} spencer (@var{x})
+Return Spencer's 15 point moving average of every single column of
+ at var{x}.
+ at end deftypefn
+conv
+ at c ./polynomial/conv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} conv (@var{a}, @var{b})
+Convolve two vectors.
+
+ at code{y = conv (a, b)} returns a vector of length equal to
+ at 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.
+ at seealso{deconv, poly, roots, residue, polyval, polyderiv, polyinteg}
+ at end deftypefn
+roots
+ at c ./polynomial/roots.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} roots (@var{v})
+
+For a vector @var{v} with @math{N} components, return
+the roots of the polynomial
+ at tex
+$$
+v_1 z^{N-1} + \cdots + v_{N-1} z + v_N.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+v(1) * z^(N-1) + @dots{} + v(N-1) * z + v(N)
+ at end example
+ at end ifnottex
+
+As an example, the following code finds the roots of the quadratic
+polynomial
+ at tex
+$$ p(x) = x^2 - 5. $$
+ at end tex
+ at ifnottex
+ at example
+p(x) = x^2 - 5.
+ at end example
+ at end ifnottex
+ at example
+ at group
+c = [1, 0, -5];
+roots(c)
+ at result{}  2.2361
+ at result{} -2.2361
+ at end group
+ at end example
+Note that the true result is
+ at tex
+$\pm \sqrt{5}$
+ at end tex
+ at ifnottex
+ at math{+/- sqrt(5)}
+ at end ifnottex
+which is roughly
+ at tex
+$\pm 2.2361$.
+ at end tex
+ at ifnottex
+ at math{+/- 2.2361}.
+ at end ifnottex
+ at seealso{compan}
+ at end deftypefn
+pchip
+ at c ./polynomial/pchip.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{pp} =} pchip (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{yi} =} pchip (@var{x}, @var{y}, @var{xi})
+
+Piecewise Cubic Hermite interpolating polynomial.  Called with two
+arguments, the piece-wise polynomial @var{pp} is returned, that may
+later be used with @code{ppval} to evaluate the polynomial at
+specific points.
+
+The variable @var{x} must be a strictly monotonic vector (either
+increasing or decreasing).  While @var{y} can be either a vector or
+array.  In the case where @var{y} is a vector, it must have a length
+of @var{n}.  If @var{y} is an array, then the size of @var{y} must
+have the form
+ at tex
+$$[s_1, s_2, \cdots, s_k, n]$$
+ at end tex
+ at ifnottex
+ at code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]}
+ at end ifnottex
+The array is then reshaped internally to a matrix where the leading
+dimension is given by 
+ at tex
+$$s_1 s_2 \cdots s_k$$
+ at end tex
+ at ifnottex
+ at code{@var{s1} * @var{s2} * @dots{} * @var{sk}}
+ at end ifnottex
+and each row in this matrix is then treated separately.  Note that this
+is exactly the opposite treatment than @code{interp1} and is done
+for compatibility.
+
+Called with a third input argument, @code{pchip} evaluates the 
+piece-wise polynomial at the points @var{xi}.  There is an equivalence
+between @code{ppval (pchip (@var{x}, @var{y}), @var{xi})} and
+ at code{pchip (@var{x}, @var{y}, @var{xi})}.
+
+ at seealso{spline, ppval, mkpp, unmkpp}
+ at end deftypefn
+polyreduce
+ at c ./polynomial/polyreduce.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyreduce (@var{c})
+Reduces a polynomial coefficient vector to a minimum number of terms by
+stripping off any leading zeros.
+ at seealso{poly, roots, conv, deconv, residue, filter, polyval,
+polyvalm, polyderiv, polyinteg}
+ at end deftypefn
+compan
+ at c ./polynomial/compan.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} compan (@var{c})
+Compute the companion matrix corresponding to polynomial coefficient
+vector @var{c}.
+
+The companion matrix is
+ at tex
+$$
+A = \left[\matrix{
+ -c_2/c_1 & -c_3/c_1 & \cdots & -c_N/c_1 & -c_{N+1}/c_1\cr
+     1    &     0    & \cdots &     0    &         0   \cr
+     0    &     1    & \cdots &     0    &         0   \cr
+  \vdots  &   \vdots & \ddots &  \vdots  &      \vdots \cr
+     0    &     0    & \cdots &     1    &         0}\right].
+$$
+ at end tex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+     _                                                        _
+    |  -c(2)/c(1)   -c(3)/c(1)  @dots{}  -c(N)/c(1)  -c(N+1)/c(1)  |
+    |       1            0      @dots{}       0             0      |
+    |       0            1      @dots{}       0             0      |
+A = |       .            .   .            .             .      |
+    |       .            .       .        .             .      |
+    |       .            .           .    .             .      |
+    |_      0            0      @dots{}       1             0     _|
+ at end smallexample
+ at end ifnottex
+
+The eigenvalues of the companion matrix are equal to the roots of the
+polynomial.
+ at seealso{poly, roots, residue, conv, deconv, polyval, polyderiv,
+polyinteg}
+ at end deftypefn
+residue
+ at c ./polynomial/residue.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{r}, @var{p}, @var{k}, @var{e}] =} residue (@var{b}, @var{a})
+Compute the partial fraction expansion for the quotient of the
+polynomials, @var{b} and @var{a}.
+
+ at tex
+$$
+{B(s)\over A(s)} = \sum_{m=1}^M {r_m\over (s-p_m)^e_m}
+  + \sum_{i=1}^N k_i s^{N-i}.
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+ B(s)    M       r(m)         N
+ ---- = SUM -------------  + SUM k(i)*s^(N-i)
+ A(s)   m=1 (s-p(m))^e(m)    i=1
+ at end group
+ at end example
+ at end ifnottex
+
+ at noindent
+where @math{M} is the number of poles (the length of the @var{r},
+ at var{p}, and @var{e}), the @var{k} vector is a polynomial of order @math{N-1}
+representing the direct contribution, and the @var{e} vector specifies
+the multiplicity of the m-th residue's pole.
+
+For example,
+
+ at example
+ at group
+b = [1, 1, 1];
+a = [1, -5, 8, -4];
+[r, p, k, e] = residue (b, a);
+     @result{} r = [-2; 7; 3]
+     @result{} p = [2; 2; 1]
+     @result{} k = [](0x0)
+     @result{} e = [1; 2; 1]
+ at end group
+ at end example
+
+ at noindent
+which represents the following partial fraction expansion
+ at tex
+$$
+{s^2+s+1\over s^3-5s^2+8s-4} = {-2\over s-2} + {7\over (s-2)^2} + {3\over s-1}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+        s^2 + s + 1       -2        7        3
+   ------------------- = ----- + ------- + -----
+   s^3 - 5s^2 + 8s - 4   (s-2)   (s-2)^2   (s-1)
+ at end group
+ at end example
+
+ at end ifnottex
+
+ at deftypefnx {Function File} {[@var{b}, @var{a}] =} residue (@var{r}, @var{p}, @var{k})
+ at deftypefnx {Function File} {[@var{b}, @var{a}] =} residue (@var{r}, @var{p}, @var{k}, @var{e})
+Compute the reconstituted quotient of polynomials,
+ at var{b}(s)/@var{a}(s), from the partial fraction expansion;
+represented by the residues, poles, and a direct polynomial specified
+by @var{r}, @var{p} and @var{k}, and the pole multiplicity @var{e}.
+
+If the multiplicity, @var{e}, is not explicitly specified the multiplicity is
+determined by the script mpoles.m.
+
+For example,
+
+ at example
+ at group
+r = [-2; 7; 3];
+p = [2; 2; 1];
+k = [1, 0];
+[b, a] = residue (r, p, k);
+     @result{} b = [1, -5, 9, -3, 1]
+     @result{} a = [1, -5, 8, -4]
+
+where mpoles.m is used to determine e = [1; 2; 1]
+
+ at end group
+ at end example
+
+Alternatively the multiplicity may be defined explicitly, for example,
+
+ at example
+ at group
+r = [7; 3; -2];
+p = [2; 1; 2];
+k = [1, 0];
+e = [2; 1; 1];
+[b, a] = residue (r, p, k, e);
+     @result{} b = [1, -5, 9, -3, 1]
+     @result{} a = [1, -5, 8, -4]
+ at end group
+ at end example
+
+ at noindent
+which represents the following partial fraction expansion
+ at tex
+$$
+{-2\over s-2} + {7\over (s-2)^2} + {3\over s-1} + s = {s^4-5s^3+9s^2-3s+1\over s^3-5s^2+8s-4}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+    -2        7        3         s^4 - 5s^3 + 9s^2 - 3s + 1
+   ----- + ------- + ----- + s = --------------------------
+   (s-2)   (s-2)^2   (s-1)          s^3 - 5s^2 + 8s - 4
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{poly, roots, conv, deconv, mpoles, polyval, polyderiv, polyinteg}
+ at end deftypefn
+polyint
+ at c ./polynomial/polyint.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyint (@var{c}, @var{k})
+Return the coefficients of the integral of the polynomial whose
+coefficients are represented by the vector @var{c}.  The variable
+ at var{k} is the constant of integration, which by default is set to zero.
+ at seealso{poly, polyderiv, polyreduce, roots, conv, deconv, residue,
+filter, polyval, polyvalm}
+ at end deftypefn
+ppval
+ at c ./polynomial/ppval.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{yi} =} ppval (@var{pp}, @var{xi})
+Evaluate piece-wise polynomial @var{pp} at the points @var{xi}.  
+If @code{@var{pp}.d} is a scalar greater than 1, or an array,
+then the returned value @var{yi} will be an array that is 
+ at code{d1, d1, @dots{}, dk, length (@var{xi})]}.
+ at seealso{mkpp, unmkpp, spline}
+ at end deftypefn 
+spline
+ at c ./polynomial/spline.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{pp} =} spline (@var{x}, @var{y})
+ at deftypefnx {Function File} {@var{yi} =} spline (@var{x}, @var{y}, @var{xi})
+
+Return the cubic spline interpolant of @var{y} at points @var{x}. 
+If called with two arguments, @code{spline} returns the piece-wise
+polynomial @var{pp} that may later be used with @code{ppval} to
+evaluate the polynomial at specific points.
+If called with a third input argument, @code{spline} evaluates the 
+spline at the points @var{xi}.  There is an equivalence
+between @code{ppval (spline (@var{x}, @var{y}), @var{xi})} and
+ at code{spline (@var{x}, @var{y}, @var{xi})}.
+
+The variable @var{x} must be a vector of length @var{n}, and @var{y}
+can be either a vector or array.  In the case where @var{y} is a
+vector, it can have a length of either @var{n} or @code{@var{n} + 2}.
+If the length of @var{y} is @var{n}, then the 'not-a-knot' end
+condition is used.  If the length of @var{y} is @code{@var{n} + 2},
+then the first and last values of the vector @var{y} are the values
+of the first derivative of the cubic spline at the end-points.
+
+If @var{y} is an array, then the size of @var{y} must have the form
+ at tex
+$$[s_1, s_2, \cdots, s_k, n]$$
+ at end tex
+ at ifnottex
+ at code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]}
+ at end ifnottex
+or
+ at tex
+$$[s_1, s_2, \cdots, s_k, n + 2].$$
+ at end tex
+ at ifnottex
+ at code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n} + 2]}.
+ at end ifnottex
+The array is then reshaped internally to a matrix where the leading
+dimension is given by 
+ at tex
+$$s_1 s_2 \cdots s_k$$
+ at end tex
+ at ifnottex
+ at code{@var{s1} * @var{s2} * @dots{} * @var{sk}}
+ at end ifnottex
+and each row of this matrix is then treated separately.  Note that this
+is exactly the opposite treatment than @code{interp1} and is done
+for compatibility.
+ at seealso{ppval, mkpp, unmkpp}
+ at end deftypefn
+polyfit
+ at c ./polynomial/polyfit.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{p}, @var{s}, @var{mu}] =} polyfit (@var{x}, @var{y}, @var{n})
+Return the coefficients of a polynomial @var{p}(@var{x}) of degree
+ at var{n} that minimizes the least-squares-error of the fit.
+
+The polynomial coefficients are returned in a row vector.
+
+The second output is a structure containing the following fields:
+
+ at table @samp
+ at item R
+Triangular factor R from the QR decomposition.
+ at item X
+The Vandermonde matrix used to compute the polynomial coefficients.
+ at item df
+The degrees of freedom.
+ at item normr
+The norm of the residuals.
+ at item yf
+The values of the polynomial for each value of @var{x}.
+ at end table
+
+The second output may be used by @code{polyval} to calculate the 
+statistical error limits of the predicted values.
+
+When the third output, @var{mu}, is present the 
+coefficients, @var{p}, are associated with a polynomial in
+ at var{xhat} = (@var{x}- at var{mu}(1))/@var{mu}(2).
+Where @var{mu}(1) = mean (@var{x}), and @var{mu}(2) = std (@var{x}).
+This linear transformation of @var{x} improves the numerical
+stability of the fit.
+ at seealso{polyval, residue}
+ at end deftypefn
+polyder
+ at c ./polynomial/polyder.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyder (@var{c})
+ at deftypefnx {Function File} {[@var{q}] =} polyder (@var{b}, @var{a})
+ at deftypefnx {Function File} {[@var{q}, @var{r}] =} polyder (@var{b}, @var{a})
+See polyderiv.
+ at end deftypefn
+polygcd
+ at c ./polynomial/polygcd.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{q} =} polygcd (@var{b}, @var{a}, @var{tol})
+
+Find greatest common divisor of two polynomials.  This is equivalent
+to the polynomial found by multiplying together all the common roots.
+Together with deconv, you can reduce a ratio of two polynomials.
+Tolerance defaults to 
+ at example 
+sqrt(eps).
+ at end example
+ Note that this is an unstable
+algorithm, so don't try it on large polynomials.
+
+Example
+ at example
+ at group
+polygcd (poly(1:8), poly(3:12)) - poly(3:8)
+ at result{} [ 0, 0, 0, 0, 0, 0, 0 ]
+deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))) ...
+  - poly(1:2)
+ at result{} [ 0, 0, 0 ]
+ at end group
+ at end example
+ at seealso{poly, polyinteg, polyderiv, polyreduce, roots, conv, deconv,
+residue, filter, polyval, polyvalm}
+ at end deftypefn
+polyderiv
+ at c ./polynomial/polyderiv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyderiv (@var{c})
+ at deftypefnx {Function File} {[@var{q}] =} polyderiv (@var{b}, @var{a})
+ at deftypefnx {Function File} {[@var{q}, @var{r}] =} polyderiv (@var{b}, @var{a})
+Return the coefficients of the derivative of the polynomial whose
+coefficients are given by vector @var{c}.  If a pair of polynomials
+is given @var{b} and @var{a}, the derivative of the product is
+returned in @var{q}, or the quotient numerator in @var{q} and the
+quotient denominator in @var{r}.
+ at seealso{poly, polyinteg, polyreduce, roots, conv, deconv, residue,
+filter, polygcd, polyval, polyvalm}
+ at end deftypefn
+deconv
+ at c ./polynomial/deconv.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} deconv (@var{y}, @var{a})
+Deconvolve two vectors.
+
+ at code{[b, r] = deconv (y, a)} solves for @var{b} and @var{r} such that
+ at 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.
+ at seealso{conv, poly, roots, residue, polyval, polyderiv, polyinteg}
+ at end deftypefn
+mkpp
+ at c ./polynomial/mkpp.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{pp} =} mkpp (@var{x}, @var{p})
+ at deftypefnx {Function File} {@var{pp} =} mkpp (@var{x}, @var{p}, @var{d})
+
+Construct a piece-wise polynomial structure from sample points
+ at var{x} and coefficients @var{p}.  The i-th row of @var{p},
+ at code{@var{p} (@var{i},:)}, contains the coefficients for the polynomial
+over the @var{i}-th interval, ordered from highest to 
+lowest.  There must be one row for each interval in @var{x}, so 
+ at code{rows (@var{p}) == length (@var{x}) - 1}.  
+
+You can concatenate multiple polynomials of the same order over the 
+same set of intervals using @code{@var{p} = [ @var{p1}; @var{p2}; 
+ at dots{}; @var{pd} ]}.  In this case, @code{rows (@var{p}) == @var{d} 
+* (length (@var{x}) - 1)}.
+
+ at var{d} specifies the shape of the matrix @var{p} for all except the
+last dimension.  If @var{d} is not specified it will be computed as
+ at code{round (rows (@var{p}) / (length (@var{x}) - 1))} instead.
+
+ at seealso{unmkpp, ppval, spline}
+ at end deftypefn
+mpoles
+ at c ./polynomial/mpoles.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p})
+ at deftypefnx {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p}, @var{tol})
+ at deftypefnx {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p}, @var{tol}, @var{reorder})
+Identify unique poles in @var{p} and associates their multiplicity,
+ordering them from largest to smallest.
+
+If the relative difference of the poles is less than @var{tol}, then
+they are considered to be multiples.  The default value for @var{tol}
+is 0.001.
+
+If the optional parameter @var{reorder} is zero, poles are not sorted.
+
+The value @var{multp} is a vector specifying the multiplicity of the
+poles.  @var{multp}(:) refers to multiplicity of @var{p}(@var{indx}(:)).
+
+For example,
+
+ at example
+ at group
+p = [2 3 1 1 2];
+[m, n] = mpoles(p);
+  @result{} m = [1; 1; 2; 1; 2]
+  @result{} n = [2; 5; 1; 4; 3]
+  @result{} p(n) = [3, 2, 2, 1, 1]
+ at end group
+ at end example
+
+ at seealso{poly, roots, conv, deconv, polyval, polyderiv, polyinteg, residue}
+ at end deftypefn
+polyval
+ at c ./polynomial/polyval.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{y} =} polyval (@var{p}, @var{x})
+ at deftypefnx {Function File} {@var{y} =} polyval (@var{p}, @var{x}, [], @var{mu})
+Evaluate the polynomial at of the specified values for @var{x}.  When @var{mu}
+is present evaluate the polynomial for (@var{x}- at var{mu}(1))/@var{mu}(2).
+If @var{x} is a vector or matrix, the polynomial is evaluated for each of
+the elements of @var{x}.
+ at deftypefnx {Function File} {[@var{y}, @var{dy}] =} polyval (@var{p}, @var{x}, @var{s})
+ at deftypefnx {Function File} {[@var{y}, @var{dy}] =} polyval (@var{p}, @var{x}, @var{s}, @var{mu})
+In addition to evaluating the polynomial, the second output 
+represents the prediction interval, @var{y} +/- @var{dy}, which
+contains at least 50% of the future predictions.  To calculate the
+prediction interval, the structured variable @var{s}, originating
+form `polyfit', must be present.
+ at seealso{polyfit, polyvalm, poly, roots, conv, deconv, residue, filter,
+polyderiv, polyinteg}
+ at end deftypefn
+convn
+ at c ./polynomial/convn.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{c} =} convn (@var{a}, @var{b}, @var{shape})
+ at math{N}-dimensional convolution of matrices @var{a} and @var{b}.
+
+The size of the output is determined by the @var{shape} argument.
+This can be any of the following character strings:
+
+ at table @asis
+ at item "full"
+The full convolution result is returned.  The size out of the output is
+ at code{size (@var{a}) + size (@var{b})-1}.  This is the default behavior.
+ at item "same"
+The central part of the convolution result is returned.  The size out of the
+output is the same as @var{a}.
+ at item "valid"
+The valid part of the convolution is returned.  The size of the result is
+ at code{max (size (@var{a}) - size (@var{b})+1, 0)}.
+ at end table
+
+ at seealso{conv, conv2}
+ at end deftypefn
+polyvalm
+ at c ./polynomial/polyvalm.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyvalm (@var{c}, @var{x})
+Evaluate a polynomial in the matrix sense.
+
+ at code{polyvalm (@var{c}, @var{x})} will evaluate the polynomial in the
+matrix sense, i.e., matrix multiplication is used instead of element by
+element multiplication as is used in polyval.
+
+The argument @var{x} must be a square matrix.
+ at seealso{polyval, poly, roots, conv, deconv, residue, filter,
+polyderiv, polyinteg}
+ at end deftypefn
+polyout
+ at c ./polynomial/polyout.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyout (@var{c}, @var{x})
+Write formatted polynomial
+ at tex
+$$ c(x) = c_1 x^n + \ldots + c_n x + c_{n+1} $$
+ at end tex
+ at ifnottex
+ at example
+   c(x) = c(1) * x^n + @dots{} + c(n) x + c(n+1)
+ at end example
+ at end ifnottex
+ and return it as a string or write it to the screen (if
+ at var{nargout} is zero).
+ at var{x} defaults to the string @code{"s"}.
+ at seealso{polyval, polyvalm, poly, roots, conv, deconv, residue,
+filter, polyderiv, polyinteg}
+ at end deftypefn
+unmkpp
+ at c ./polynomial/unmkpp.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{x}, @var{p}, @var{n}, @var{k}, @var{d}] =} unmkpp (@var{pp})
+
+Extract the components of a piece-wise polynomial structure @var{pp}.
+These are as follows:
+
+ at table @asis
+ at item @var{x}
+Sample points.
+ at item @var{p}
+Polynomial coefficients for points in sample interval.  @code{@var{p}
+(@var{i}, :)} contains the coefficients for the polynomial over
+interval @var{i} ordered from highest to lowest.  If @code{@var{d} >
+1}, @code{@var{p} (@var{r}, @var{i}, :)} contains the coefficients for 
+the r-th polynomial defined on interval @var{i}.  However, this is 
+stored as a 2-D array such that @code{@var{c} = reshape (@var{p} (:,
+ at var{j}), @var{n}, @var{d})} gives @code{@var{c} (@var{i},  @var{r})}
+is the j-th coefficient of the r-th polynomial over the i-th interval.
+ at item @var{n}
+Number of polynomial pieces.
+ at item @var{k}
+Order of the polynomial plus 1.
+ at item @var{d}
+Number of polynomials defined for each interval.
+ at end table
+
+ at seealso{mkpp, ppval, spline}
+ at end deftypefn
+polyaffine
+ at c ./polynomial/polyaffine.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} polyaffine (@var{f}, @var{mu})
+Return the coefficients of the polynomial whose coefficients are given by
+vector @var{f} after an affine tranformation. If @var{f} is the vector
+representing the polynomial f(x), then @var{g} = polytrans (@var{f},
+ at var{mu}) is the vector representing 
+ at example
+g(x) = f((x- at var{mu}(1))/@var{mu}(2)).
+ at end example
+
+ at seealso{polyval}
+ at end deftypefn
+poly
+ at c ./polynomial/poly.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} poly (@var{a})
+If @var{a} is a square @math{N}-by- at math{N} matrix, @code{poly (@var{a})}
+is the row vector of the coefficients of @code{det (z * eye (N) - a)},
+the characteristic polynomial of @var{a}.  As an example we can use
+this to find the eigenvalues of @var{a} as the roots of @code{poly (@var{a})}.
+ at example
+ at group
+roots(poly(eye(3)))
+ at result{} 1.00000 + 0.00000i
+ at result{} 1.00000 - 0.00000i
+ at result{} 1.00000 + 0.00000i
+ at end group
+ at end example
+In real-life examples you should, however, use the @code{eig} function
+for computing eigenvalues.
+
+If @var{x} is a vector, @code{poly (@var{x})} is a vector of coefficients
+of the polynomial whose roots are the elements of @var{x}.  That is,
+of @var{c} is a polynomial, then the elements of 
+ at code{@var{d} = roots (poly (@var{c}))} are contained in @var{c}.
+The vectors @var{c} and @var{d} are, however, not equal due to sorting
+and numerical errors.
+ at seealso{eig, roots}
+ at end deftypefn
+datetick
+ at c ./time/datetick.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} datetick (@var{form})
+ at deftypefnx {Function File} {} datetick (@var{axis}, @var{form})
+ at deftypefnx {Function File} {} datetick (@dots{}, "keeplimits")
+ at deftypefnx {Function File} {} datetick (@dots{}, "keepticks")
+ at deftypefnx {Function File} {} datetick (@dots{ax}, @dots{})
+Adds date formatted tick labels to an axis.  The axis the apply the
+ticks to is determined by @var{axis} that can take the values "x",
+"y" or "z".  The default value is "x".  The formatting of the labels is
+determined by the variable @var{form}, that can either be a string in
+the format needed by @code{dateform}, or a positive integer that can
+be accepted by @code{datestr}.
+ at seealso{datenum, datestr}
+ at end deftypefn
+is_leap_year
+ at c ./time/is_leap_year.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} is_leap_year (@var{year})
+Return 1 if the given year is a leap year and 0 otherwise.  If no
+arguments are provided, @code{is_leap_year} will use the current year.
+For example,
+
+ at example
+ at group
+is_leap_year (2000)
+     @result{} 1
+ at end group
+ at end example
+ at end deftypefn
+datenum
+ at c ./time/datenum.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} datenum (@var{year}, @var{month}, @var{day})
+ at deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour})
+ at deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute})
+ at deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}, @var{second})
+ at deftypefnx {Function File} {} datenum (@code{"date"})
+ at deftypefnx {Function File} {} datenum (@code{"date"}, @var{p})
+Returns the specified local time as a day number, with Jan 1, 0000
+being day 1.  By this reckoning, Jan 1, 1970 is day number 719529.  
+The fractional portion, @var{p}, corresponds to the portion of the
+specified day.
+
+Notes:
+
+ at itemize
+ at item
+Years can be negative and/or fractional.
+ at item
+Months below 1 are considered to be January.
+ at item
+Days of the month start at 1.
+ at item
+Days beyond the end of the month go into subsequent months.
+ at item
+Days before the beginning of the month go to the previous month.
+ at item
+Days can be fractional.
+ at end itemize
+
+ at strong{Warning:} this function does not attempt to handle Julian
+calendars so dates before Octave 15, 1582 are wrong by as much
+as eleven days.  Also be aware that only Roman Catholic countries
+adopted the calendar in 1582.  It took until 1924 for it to be 
+adopted everywhere.  See the Wikipedia entry on the Gregorian 
+calendar for more details.
+
+ at strong{Warning:} leap seconds are ignored.  A table of leap seconds
+is available on the Wikipedia entry for leap seconds.
+ at seealso{date, clock, now, datestr, datevec, calendar, weekday}
+ at end deftypefn
+weekday
+ at c ./time/weekday.m
+-*- texinfo -*-
+ at deftypefn {Function File} {[@var{n}, @var{s}] =} weekday (@var{d}, [@var{form}])
+Return the day of week as a number in @var{n} and a string in @var{s},
+for example @code{[1, "Sun"]}, @code{[2, "Mon"]}, @dots{}, or
+ at code{[7, "Sat"]}.
+
+ at var{d} is a serial date number or a date string.
+
+If the string @var{form} is given and is @code{"long"}, @var{s} will
+contain the full name of the weekday; otherwise (or if @var{form} is
+ at code{"short"}), @var{s} will contain the abbreviated name of the weekday.
+ at seealso{datenum, datevec, eomday}
+ at end deftypefn
+calendar
+ at c ./time/calendar.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} calendar (@dots{})
+ at deftypefnx {Function File} {@var{c} =} calendar ()
+ at deftypefnx {Function File} {@var{c} =} calendar (@var{d})
+ at deftypefnx {Function File} {@var{c} =} calendar (@var{y}, @var{m})
+If called with no arguments, return the current monthly calendar in
+a 6x7 matrix.
+
+If @var{d} is specified, return the calendar for the month containing
+the day @var{d}, which must be a serial date number or a date string.
+
+If @var{y} and @var{m} are specified, return the calendar for year @var{y}
+and month @var{m}.
+
+If no output arguments are specified, print the calendar on the screen
+instead of returning a matrix.
+ at seealso{datenum}
+ at end deftypefn
+date
+ at c ./time/date.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} date ()
+Return the date as a character string in the form DD-MMM-YY.  For
+example,
+
+ at example
+ at group
+date ()
+     @result{} "20-Aug-93"
+ at end group
+ at end example
+ at end deftypefn
+asctime
+ at c ./time/asctime.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} asctime (@var{tm_struct})
+Convert a time structure to a string using the following five-field
+format: Thu Mar 28 08:40:14 1996.  For example,
+
+ at example
+ at group
+asctime (localtime (time ()))
+     @result{} "Mon Feb 17 01:15:06 1997\n"
+ at end group
+ at end example
+
+This is equivalent to @code{ctime (time ())}.
+ at end deftypefn
+addtodate
+ at c ./time/addtodate.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{d} =} addtodate (@var{d}, @var{q}, @var{f})
+Add @var{q} amount of time (with units @var{f}) to the datenum, @var{d}.
+
+ at var{f} must be one of "year", "month", "day", "hour", "minute", or
+"second".
+ at seealso{datenum, datevec}
+ at end deftypefn
+eomday
+ at c ./time/eomday.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{e} =} eomday (@var{y}, @var{m})
+Return the last day of the month @var{m} for the year @var{y}.
+ at seealso{datenum, datevec, weekday}
+ at end deftypefn
+datevec
+ at c ./time/datevec.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{v} =} datevec (@var{date})
+ at deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{f})
+ at deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{p})
+ at deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{f}, @var{p})
+ at deftypefnx {Function File} {[@var{y}, @var{m}, @var{d}, @var{h}, @var{mi}, @var{s}] =} datevec (@dots{})
+Convert a serial date number (see @code{datenum}) or date string (see
+ at code{datestr}) into a date vector.
+
+A date vector is a row vector with six members, representing the year,
+month, day, hour, minute, and seconds respectively.
+
+ at var{f} is the format string used to interpret date strings
+(see @code{datestr}).
+
+ at var{p} is the year at the start of the century in which two-digit years
+are to be interpreted in.  If not specified, it defaults to the current
+year minus 50.
+ at seealso{datenum, datestr, date, clock, now}
+ at end deftypefn
+clock
+ at c ./time/clock.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} clock ()
+Return a vector containing the current year, month (1-12), day (1-31),
+hour (0-23), minute (0-59) and second (0-61).  For example,
+
+ at example
+ at group
+clock ()
+     @result{} [ 1993, 8, 20, 4, 56, 1 ]
+ at end group
+ at end example
+
+The function clock is more accurate on systems that have the
+ at code{gettimeofday} function.
+ at end deftypefn
+etime
+ at c ./time/etime.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} etime (@var{t1}, @var{t2})
+Return the difference (in seconds) between two time values returned from
+ at code{clock}.  For example:
+
+ at example
+ at group
+t0 = clock ();
+ many computations later at dots{}
+elapsed_time = etime (clock (), t0);
+ at end group
+ at end example
+
+ at noindent
+will set the variable @code{elapsed_time} to the number of seconds since
+the variable @code{t0} was set.
+ at seealso{tic, toc, clock, cputime}
+ at end deftypefn
+ctime
+ at c ./time/ctime.m
+-*- texinfo -*-
+ at deftypefn {Function File} {} ctime (@var{t})
+Convert a value returned from @code{time} (or any other non-negative
+integer), to the local time and return a string of the same form as
+ at code{asctime}.  The function @code{ctime (time)} is equivalent to
+ at code{asctime (localtime (time))}.  For example,
+
+ at example
+ at group
+ctime (time ())
+     @result{} "Mon Feb 17 01:15:06 1997\n"
+ at end group
+ at end example
+ at end deftypefn
+datestr
+ at c ./time/datestr.m
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{str} =} datestr (@var{date}, [@var{f}, [@var{p}]])
+Format the given date/time according to the format @code{f} and return
+the result in @var{str}.  @var{date} is a serial date number (see
+ at code{datenum}) or a date vector (see @code{datevec}).  The value of
+ at var{date} may also be a string or cell array of strings.
+
+ at var{f} can be an integer which corresponds to one of the codes in
+the table below, or a date format string.
+
+ at var{p} is the year at the start of the century in which two-digit years
+are to be interpreted in.  If not specified, it defaults to the current
+year minus 50.
+
+For example, the date 730736.65149 (2000-09-07 15:38:09.0934) would be
+formatted as follows:
+
+ at multitable @columnfractions 0.1 0.45 0.35
+ at headitem Code @tab Format @tab Example
+ at item  0 @tab dd-mmm-yyyy HH:MM:SS   @tab 07-Sep-2000 15:38:09
+ at item  1 @tab dd-mmm-yyyy            @tab 07-Sep-2000
+ at item  2 @tab mm/dd/yy               @tab 09/07/00
+ at item  3 @tab mmm                    @tab Sep
+ at item  4 @tab m                      @tab S
+ at item  5 @tab mm                     @tab 09
+ at item  6 @tab mm/dd                  @tab 09/07
+ at item  7 @tab dd                     @tab 07
+ at item  8 @tab ddd                    @tab Thu
+ at item  9 @tab d                      @tab T
+ at item 10 @tab yyyy                   @tab 2000
+ at item 11 @tab yy                     @tab 00
+ at item 12 @tab mmmyy                  @tab Sep00
+ at item 13 @tab HH:MM:SS               @tab 15:38:09
+ at item 14 @tab HH:MM:SS PM            @tab 03:38:09 PM
+ at item 15 @tab HH:MM                  @tab 15:38
+ at item 16 @tab HH:MM PM               @tab 03:38 PM
+ at item 17 @tab QQ-YY                  @tab Q3-00
+ at item 18 @tab QQ                     @tab Q3
+ at item 19 @tab dd/mm                  @tab 13/03
+ at item 20 @tab dd/mm/yy               @tab 13/03/95
+ at item 21 @tab mmm.dd.yyyy HH:MM:SS   @tab Mar.03.1962 13:53:06
+ at item 22 @tab mmm.dd.yyyy            @tab Mar.03.1962
+ at item 23 @tab mm/dd/yyyy             @tab 03/13/1962
+ at item 24 @tab dd/mm/yyyy             @tab 12/03/1962
+ at item 25 @tab yy/mm/dd               @tab 95/03/13
+ at item 26 @tab yyyy/mm/dd             @tab 1995/03/13
+ at item 27 @tab QQ-YYYY                @tab Q4-2132
+ at item 28 @tab mmmyyyy                @tab Mar2047
+ at item 29 @tab yyyymmdd               @tab 20470313
+ at item 30 @tab yyyymmddTHHMMSS        @tab 20470313T132603
+ at item 31 @tab yyyy-mm-dd HH:MM:SS    @tab 1047-03-13 13:26:03
+ at end multitable
+
+If @var{f} is a format string, the following symbols are recognized:
+
+ at multitable @columnfractions 0.1 0.7 0.2
+ at headitem Symbol @tab Meaning @tab Example
+ at item yyyy @tab Full year                                    @tab 2005
+ at item yy   @tab Two-digit year                               @tab 2005
+ at item mmmm @tab Full month name                              @tab December
+ at item mmm  @tab Abbreviated month name                       @tab Dec
+ at item mm   @tab Numeric month number (padded with zeros)     @tab 01, 08, 12
+ at item m    @tab First letter of month name (capitalized)     @tab D
+ at item dddd @tab Full weekday name                            @tab Sunday
+ at item ddd  @tab Abbreviated weekday name                     @tab Sun
+ at item dd   @tab Numeric day of month (padded with zeros)     @tab 11
+ at item d    @tab First letter of weekday name (capitalized)   @tab S
+ at item HH   @tab Hour of day, padded with zeros if PM is set  @tab 09:00
+ at item      @tab and not padded with zeros otherwise          @tab 9:00 AM
+ at item MM   @tab Minute of hour (padded with zeros)           @tab 10:05
+ at item SS   @tab Second of minute (padded with zeros)         @tab 10:05:03
+ at item PM   @tab Use 12-hour time format                      @tab 11:30 PM
+ at end multitable
+
+If @var{f} is not specified or is @code{-1}, then use 0, 1 or 16,
+depending on whether the date portion or the time portion of
+ at var{date} is empty.
+
+If @var{p} is nor specified, it defaults to the current year minus 50.
+
+If a matrix or cell array of dates is given, a vector of date strings is
+returned.
+
+ at seealso{datenum, datevec, date, clock, now, datetick}
+ at end deftypefn
+now
+ at c ./time/now.m
+-*- texinfo -*-
+ at deftypefn {Function File} {t =} now ()
+Returns the current local time as the number of days since Jan 1, 0000.
+By this reckoning, Jan 1, 1970 is day number 719529.
+
+The integral part, @code{floor (now)} corresponds to 00:00:00 today.
+
+The fractional part, @code{rem (now, 1)} corresponds to the current
+time on Jan 1, 0000.
+
+The returned value is also called a "serial date number"
+(see @code{datenum}).
+ at seealso{clock, date, datenum}
+ at end deftypefn
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
new file mode 100644
index 0000000..aea2c0c
--- /dev/null
+++ b/scripts/Makefile.in
@@ -0,0 +1,115 @@
+# Makefile for octave's scripts directory
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+#               2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+script_sub_dir = .
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES =
+
+ALL_M_FILES1 := $(shell find $(srcdir) -name '*.m' -print)
+ALL_M_FILES := $(patsubst $(srcdir)/%, %, $(ALL_M_FILES1))
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in ChangeLog $(SOURCES) \
+	configure.in configure mkinstalldirs mkdoc mkpkgadd gethelp.cc \
+	skip-autoheader move-if-change) DOCSTRINGS
+
+SUBDIRS = audio deprecated elfun general geometry help image io \
+	linear-algebra miscellaneous optimization path pkg plot polynomial \
+	set signal sparse specfun special-matrix startup \
+	statistics strings testfun time
+
+DISTSUBDIRS = $(SUBDIRS)
+
+FCN_FILES = # $(wildcard $(srcdir)/*.m)
+FCN_FILES_NO_DIR = # $(notdir $(FCN_FILES))
+
+CONFIG_FILES = @ac_config_files@
+
+all: $(SUBDIRS) DOCSTRINGS
+.PHONY: all
+
+configfiles: $(CONFIG_FILES)
+.PHONY: configfiles
+
+$(CONFIG_FILES): %: %.in config.status
+	./config.status $@
+
+config.status: configure
+	./config.status --recheck
+
+configure: configure.in
+	if [ ! -f skip-autoconf ]; then autoconf --force; fi
+	if [ ! -f skip-autoheader ]; then autoheader --force; fi
+
+$(SUBDIRS):
+	$(MAKE) -C $@ all
+.PHONY: $(SUBDIRS)
+
+DOCSTRINGS: gethelp$(BUILD_EXEEXT) mkdoc $(ALL_M_FILES)
+	$(srcdir)/mkdoc $(srcdir) > $@.t
+	mv $@.t $@
+
+gethelp$(BUILD_EXEEXT): gethelp.cc
+	$(BUILD_CXX) $(BUILD_CXXFLAGS) -o $@ $^ $(BUILD_LDFLAGS)
+
+install install-strip uninstall clean mostlyclean distclean maintainer-clean::
+	@$(subdir-for-command)
+.PHONY: install install-strip uninstall
+.PHONY: clean mostlyclean distclean maintainer-clean
+
+tags TAGS:: $(SOURCES)
+	$(subdir-for-command)
+
+tags::
+	ctags $(SOURCES)
+
+TAGS:: $(SOURCES)
+	etags $(SOURCES)
+
+clean distclean maintainer-clean::
+	rm -f gethelp$(BUILD_EXEEXT)
+
+distclean maintainer-clean::
+	rm -f tags TAGS Makefile config.log config.status DOCSTRINGS
+	rm -rf autom4te.cache
+
+maintainer-clean::
+	rm -f configure
+
+dist:
+	ln $(DISTFILES) ../`cat ../.fname`/scripts
+	for dir in $(DISTSUBDIRS); do mkdir ../`cat ../.fname`/scripts/$$dir; $(MAKE) -C $$dir $@; done
+.PHONY: dist
+
+check-m-sources:
+	@$(subdir-for-command)
+.PHONY: check-m-sources
diff --git a/scripts/audio/Makefile.in b/scripts/audio/Makefile.in
new file mode 100644
index 0000000..d3a6e52
--- /dev/null
+++ b/scripts/audio/Makefile.in
@@ -0,0 +1,84 @@
+# Makefile for octave's scripts/audio directory
+#
+# Copyright (C) 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = audio
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = lin2mu.m loadaudio.m mu2lin.m playaudio.m record.m \
+  saveaudio.m setaudio.m wavread.m wavwrite.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/audio
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/audio/lin2mu.m b/scripts/audio/lin2mu.m
new file mode 100644
index 0000000..b47e55d
--- /dev/null
+++ b/scripts/audio/lin2mu.m
@@ -0,0 +1,75 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lin2mu (@var{x}, @var{n})
+## Converts audio data from linear to mu-law.  Mu-law values use 8-bit
+## unsigned integers.  Linear values use @var{n}-bit signed integers or 
+## floating point values in the range -1<=@var{x}<=1 if @var{n} is 0.  
+## If @var{n} is not specified it defaults to 0, 8 or 16 depending on 
+## the range values in @var{x}.
+## @seealso{mu2lin, loadaudio, saveaudio, playaudio, setaudio, record}
+## @end deftypefn
+
+
+## Author: Andreas Weingessel <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 17 October 1994
+## Adapted-By: jwe
+
+function y = lin2mu (x, bit)
+
+  if (nargin == 1)
+    range = max (abs (x (:)));
+    if (range <= 1)
+      bit = 0;
+    elseif (range <= 128)
+      bit = 8;
+      warning ("lin2mu: no precision specified, so using %d", bit);
+    else
+      bit = 16;
+    endif
+  elseif (nargin == 2)
+    if (bit != 0 && bit != 8 && bit != 16)
+      error ("lin2mu: bit must be either 0, 8 or 16");
+    endif
+  else
+    print_usage ();
+  endif
+
+  ## Transform real and n-bit format to 16-bit.
+  if (bit == 0)
+    ## [-1,1] -> [-32768, 32768]
+    x = 32768 * x;
+  elseif (bit != 16)
+    x = 2^(16-bit) .* x;
+  endif
+
+  ## Determine sign of x, set sign(0) = 1.
+  sig = sign(x) + (x == 0);
+
+  ## Take absolute value of x, but force it to be smaller than 32636;
+  ## add bias.
+  x = min (abs (x), 32635) + 132;
+
+  ## Find exponent and fraction of bineary representation.
+  [f, e] = log2 (x);
+
+  y = 64 * sig - 16 * e - fix (32 * f) + 335;
+
+endfunction
diff --git a/scripts/audio/loadaudio.m b/scripts/audio/loadaudio.m
new file mode 100644
index 0000000..63354b5
--- /dev/null
+++ b/scripts/audio/loadaudio.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} loadaudio (@var{name}, @var{ext}, @var{bps})
+## Loads audio data from the file @file{@var{name}. at var{ext}} into the
+## vector @var{x}.
+##
+## The extension @var{ext} determines how the data in the audio file is
+## interpreted;  the extensions @file{lin} (default) and @file{raw}
+## correspond to linear, the extensions @file{au}, @file{mu}, or @file{snd}
+## to mu-law encoding.
+##
+## The argument @var{bps} can be either 8 (default) or 16, and specifies
+## the number of bits per sample used in the audio file.
+## @seealso{lin2mu, mu2lin, saveaudio, playaudio, setaudio, record}
+## @end deftypefn
+
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 10 April 1994
+## Adapted-By: jwe
+
+function X = loadaudio (name, ext, bit)
+
+  if (nargin == 0 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    ext = "lin";
+  endif
+
+  if (nargin < 3)
+    bit = 8;
+  elseif (bit != 8 && bit != 16)
+    error ("loadaudio: bit must be either 8 or 16");
+  endif
+
+  name = [name, ".", ext];
+  num = fopen (name, "rb");
+
+  if (strcmp (ext, "lin") || strcmp (ext, "raw") || strcmp (ext, "pcm"))
+    if (bit == 8)
+      [Y, c] = fread (num, inf, "uchar");
+      X = Y - 127;
+    else
+      [X, c] = fread (num, inf, "short");
+    endif
+  elseif (strcmp (ext, "mu") || strcmp (ext, "au")
+	  || strcmp (ext, "snd") || strcmp(ext, "ul"))
+    [Y, c] = fread (num, inf, "uchar");
+    ## remove file header
+    m = find (Y(1:64) == 0, 1, "last");
+    if (! isempty (m))
+      Y(1:m) = [];
+    endif
+    X = mu2lin (Y, bit);
+  else
+    fclose (num);
+    error ("loadaudio does not support given extension");
+  endif
+
+  fclose (num);
+
+endfunction
diff --git a/scripts/audio/mu2lin.m b/scripts/audio/mu2lin.m
new file mode 100644
index 0000000..e661f03
--- /dev/null
+++ b/scripts/audio/mu2lin.m
@@ -0,0 +1,84 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mu2lin (@var{x}, @var{bps})
+## Converts audio data from linear to mu-law.  Mu-law values are 8-bit
+## unsigned integers.  Linear values use @var{n}-bit signed integers
+## or floating point values in the range -1<=y<=1 if @var{n} is 0.  If
+## @var{n} is not specified it defaults to 8.
+## @seealso{lin2mu, loadaudio, saveaudio, playaudio, setaudio, record}
+## @end deftypefn
+
+## Author:  Andreas Weingessel <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 18 October 1994
+## Adapted-By: jwe
+
+function y = mu2lin (x, bit)
+
+  if (nargin == 1)
+    ## COMPATIBILITY -- bps defaults to 8 for octave, 0 for Matlab
+    bit = 8;
+  elseif (nargin == 2)
+    if (bit != 0 && bit != 8 && bit != 16)
+      error ("mu2lin: bit must be either 0, 8 or 16");
+    endif
+  else
+    print_usage ();
+  endif
+
+  ulaw = [32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, \
+	  23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, \
+	  15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, \
+	  11900, 11388, 10876, 10364,  9852,  9340,  8828,  8316, \
+	   7932,  7676,  7420,  7164,  6908,  6652,  6396,  6140, \
+	   5884,  5628,  5372,  5116,  4860,  4604,  4348,  4092, \
+	   3900,  3772,  3644,  3516,  3388,  3260,  3132,  3004, \
+	   2876,  2748,  2620,  2492,  2364,  2236,  2108,  1980, \
+	   1884,  1820,  1756,  1692,  1628,  1564,  1500,  1436, \
+	   1372,  1308,  1244,  1180,  1116,  1052,   988,   924, \
+	    876,   844,   812,   780,   748,   716,   684,   652, \
+	    620,   588,   556,   524,   492,   460,   428,   396, \
+	    372,   356,   340,   324,   308,   292,   276,   260, \
+	    244,   228,   212,   196,   180,   164,   148,   132, \
+	    120,   112,   104,    96,    88,    80,    72,    64, \
+	     56,    48,    40,    32,    24,    16,     8,     0 ];
+
+  ulaw = [ -ulaw, ulaw ];
+
+  ## Set the shape of y to that of x overwrites the contents of y with
+  ## ulaw of x.
+  y = x;
+  y(:) = ulaw (x + 1);
+
+  ## Convert to real or 8-bit.
+  if (bit == 0)
+    ## [ -32768, 32767 ] -> [ -1, 1)
+    y = y/32768;
+  elseif (bit == 8)
+    ld = max (abs (y (:)));
+    if (ld < 16384 && ld > 0)
+      sc = 64 / ld;
+    else
+      sc = 1 / 256;
+    endif
+    y = fix (y * sc);
+  endif
+
+endfunction
diff --git a/scripts/audio/playaudio.m b/scripts/audio/playaudio.m
new file mode 100644
index 0000000..1eeefbf
--- /dev/null
+++ b/scripts/audio/playaudio.m
@@ -0,0 +1,76 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} playaudio (@var{name}, @var{ext})
+## @deftypefnx {Function File} {} playaudio (@var{x})
+## Plays the audio file @file{@var{name}. at var{ext}} or the audio data
+## stored in the vector @var{x}.
+## @seealso{lin2mu, mu2lin, loadaudio, saveaudio, setaudio, record}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 11 April 1994
+## Adapted-By: jwe
+
+function playaudio (name, ext)
+
+  if (nargin == 1 && isvector (name) && ! ischar (name))
+    ## play a vector
+    [nr, nc] = size (name);
+    if (nc != 1)
+      if (nr == 1)
+        name = name';
+        nr = nc;
+      else
+        error ("playaudio: X must be a vector");
+      endif
+    endif
+    X = name + 127;
+    unwind_protect
+      file = tmpnam ();
+      num = fopen (file, "wb");
+      c = fwrite (num, X, "uchar");
+      fclose (num);
+      system (sprintf ("cat \"%s\" > /dev/dsp", file));
+    unwind_protect_cleanup
+      unlink (file);
+    end_unwind_protect
+  elseif (nargin >= 1 && ischar (name))
+    ## play a file
+    if (nargin == 1)
+      name = [name, ".lin"];
+    elseif (nargin == 2)
+      name = [name, ".", ext];
+    else
+      print_usage ();
+    endif
+    if (strcmp (ext, "lin") || strcmp (ext, "raw"))
+      system (sprintf ("cat \"%s\" > /dev/dsp", name));
+    elseif (strcmp (ext, "mu") || strcmp (ext, "au")
+	    || strcmp (ext, "snd") || strcmp (ext, "ul"))
+      system (sprintf ("cat \"%s\" > /dev/audio", name));
+    else
+      error ("playaudio does not support given extension");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/audio/record.m b/scripts/audio/record.m
new file mode 100644
index 0000000..ddf8dba
--- /dev/null
+++ b/scripts/audio/record.m
@@ -0,0 +1,66 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2004, 2005,
+##               2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} record (@var{sec}, @var{sampling_rate})
+## Records @var{sec} seconds of audio input into the vector @var{x}.  The
+## default value for @var{sampling_rate} is 8000 samples per second, or
+## 8kHz.  The program waits until the user types @key{RET} and then
+## immediately starts to record.
+## @seealso{lin2mu, mu2lin, loadaudio, saveaudio, playaudio, setaudio}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 19 September 1994
+## Adapted-By: jwe
+
+function X = record (sec, sampling_rate)
+
+  if (nargin == 1)
+    sampling_rate = 8000;
+  elseif (nargin != 2)
+    print_usage ();
+  endif
+
+  unwind_protect
+
+    file = tmpnam ();
+
+    input ("Please hit ENTER and speak afterwards!\n", 1);
+
+    cmd = sprintf ("dd if=/dev/dsp of=\"%s\" bs=%d count=%d",
+                   file, sampling_rate, sec)
+
+    system (cmd);
+
+    num = fopen (file, "rb");
+
+    [Y, c] = fread (num, sampling_rate * sec, "uchar");
+
+    fclose (num);
+
+  unwind_protect_cleanup
+
+    unlink (file);
+
+  end_unwind_protect
+
+  X = Y - 127;
+
+endfunction
diff --git a/scripts/audio/saveaudio.m b/scripts/audio/saveaudio.m
new file mode 100644
index 0000000..ff9a6b4
--- /dev/null
+++ b/scripts/audio/saveaudio.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} saveaudio (@var{name}, @var{x}, @var{ext}, @var{bps})
+## Saves a vector @var{x} of audio data to the file
+## @file{@var{name}. at var{ext}}.  The optional parameters @var{ext} and
+## @var{bps} determine the encoding and the number of bits per sample used
+## in the audio file (see @code{loadaudio});  defaults are @file{lin} and
+## 8, respectively.
+## @seealso{lin2mu, mu2lin, loadaudio, playaudio, setaudio, record}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 5 September 1994
+## Adapted-By: jwe
+
+function saveaudio (name, X, ext, bit)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    ext = "lin";
+  endif
+
+  if (nargin < 4)
+    bit = 8;
+  elseif (bit != 8 && bit != 16)
+    error ("saveaudio: bit must be either 8 or 16");
+  endif
+
+  [nr, nc] = size (X);
+  if (nc != 1)
+    if (nr == 1)
+      X = X';
+      nr = nc;
+    else
+      error ("saveaudio: X must be a vector");
+    endif
+  endif
+
+  num = fopen ([name, ".", ext], "wb");
+
+  if (strcmp (ext, "lin") || strcmp (ext, "raw"))
+    if (bit == 8)
+      ld = max (abs (X));
+      if (ld > 127)   # convert 16 to 8 bit
+        if (ld < 16384)
+          sc = 64 / ld;
+        else
+          sc = 1 / 256;
+        endif
+        X = fix (X * sc);
+      endif
+      X = X + 127;
+      c = fwrite (num, X, "uchar");
+    else
+      c = fwrite (num, X, "short");
+    endif
+  elseif (strcmp (ext, "mu") || strcmp (ext, "au")
+	  || strcmp (ext, "snd") || strcmp (ext, "ul"))
+    Y = lin2mu (X);
+    c = fwrite (num, Y, "uchar");
+  else
+    fclose (num);
+    error ("saveaudio does not support given extension");
+  endif
+
+  fclose (num);
+
+endfunction
diff --git a/scripts/audio/setaudio.m b/scripts/audio/setaudio.m
new file mode 100644
index 0000000..36de5ca
--- /dev/null
+++ b/scripts/audio/setaudio.m
@@ -0,0 +1,40 @@
+## Copyright (C) 1995, 1996, 1997, 2000, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} setaudio ([@var{w_type} [, @var{value}]])
+## Execute the shell command @samp{mixer [@var{w_type} [, @var{value}]]}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 5 October 1994
+## Adapted-By: jwe
+
+function setaudio (w_type, value)
+
+  if (nargin == 0)
+    system ("mixer");
+  elseif (nargin == 1)
+    system (sprintf ("mixer %s", w_type));
+  elseif (nargin == 2)
+    system (sprintf ("mixer %s %d", w_type, value));
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/audio/wavread.m b/scripts/audio/wavread.m
new file mode 100644
index 0000000..ba71a75
--- /dev/null
+++ b/scripts/audio/wavread.m
@@ -0,0 +1,238 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Michael Zeising
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} wavread (@var{filename})
+## Load the RIFF/WAVE sound file @var{filename}, and return the samples
+## in vector @var{y}.  If the file contains multichannel data, then
+## @var{y} is a matrix with the channels represented as columns.
+##
+## @deftypefnx {Function File} {[@var{y}, @var{Fs}, @var{bits}] =} wavread (@var{filename})
+## Additionally return the sample rate (@var{fs}) in Hz and the number of bits 
+## per sample (@var{bits}).
+##
+## @deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, @var{n})
+## Read only the first @var{n} samples from each channel.
+##
+## @deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename},[@var{n1} @var{n2}])
+## Read only samples @var{n1} through @var{n2} from each channel.
+##
+## @deftypefnx {Function File} {[@var{samples}, @var{channels}] =} wavread (@var{filename}, "size")
+## Return the number of samples (@var{n}) and channels (@var{ch})
+## instead of the audio data.
+## @seealso{wavwrite}
+## @end deftypefn
+
+## Author: Michael Zeising <michael at michaels-website.de>
+## Created: 06 December 2005
+
+function [y, samples_per_sec, bits_per_sample] = wavread (filename, param)
+
+  FORMAT_PCM        = 0x0001;   # PCM (8/16/32 bit)
+  FORMAT_IEEE_FLOAT = 0x0003;   # IEEE float (32/64 bit)
+  BYTEORDER         = "ieee-le";
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (! ischar (filename))
+    error ("wavwrite: expecting filename to be a character string");
+  endif
+
+  # Open file for binary reading.
+  [fid, msg] = fopen (filename, "rb");
+  if (fid < 0)
+    error ("wavread: %s", msg);
+  endif
+
+  ## Get file size.
+  fseek (fid, 0, "eof");
+  file_size = ftell (fid);
+  fseek (fid, 0, "bof");
+
+  ## Find RIFF chunk.
+  riff_size = find_chunk (fid, "RIFF", file_size);
+  riff_pos = ftell (fid);
+  if (riff_size == -1)
+    fclose (fid);
+    error ("wavread: file contains no RIFF chunk");
+  endif
+
+  riff_type = char (fread (fid, 4))';
+  if(! strcmp (riff_type, "WAVE"))
+    fclose (fid);
+    error ("wavread: file contains no WAVE signature");
+  endif
+  riff_pos = riff_pos + 4;
+  riff_size = riff_size - 4; 
+
+  ## Find format chunk inside the RIFF chunk.
+  fseek (fid, riff_pos, "bof");
+  fmt_size = find_chunk (fid, "fmt ", riff_size);
+  fmt_pos = ftell(fid);
+  if (fmt_size == -1)
+    fclose (fid);
+    error ("wavread: file contains no format chunk");
+  endif
+ 
+  ## Find data chunk inside the RIFF chunk.
+  ## We don't assume that it comes after the format chunk.
+  fseek (fid, riff_pos, "bof");
+  data_size = find_chunk (fid, "data", riff_size);
+  data_pos = ftell (fid);
+  if (data_size == -1)
+    fclose (fid);
+    error ("wavread: file contains no data chunk");
+  endif
+  
+  ### Read format chunk.
+  fseek (fid, fmt_pos, "bof");
+ 
+  ## Sample format code.
+  format_tag = fread (fid, 1, "uint16", 0, BYTEORDER);
+  if (format_tag != FORMAT_PCM && format_tag != FORMAT_IEEE_FLOAT)
+    fclose (fid);
+    error ("wavread: sample format %#x is not supported", format_tag);
+  endif
+
+  ## Number of interleaved channels.
+  channels = fread (fid, 1, "uint16", 0, BYTEORDER);
+
+  ## Sample rate.
+  samples_per_sec = fread (fid, 1, "uint32", 0, BYTEORDER);
+
+  ## Bits per sample.
+  fseek (fid, 6, "cof");
+  bits_per_sample = fread (fid, 1, "uint16", 0, BYTEORDER);
+
+  ### Read data chunk.
+  fseek (fid, data_pos, "bof");
+  
+  ## Determine sample data type.
+  if (format_tag == FORMAT_PCM)
+    switch (bits_per_sample)
+      case 8
+        format = "uint8";
+      case 16 
+        format = "int16";
+      case 24
+	format = "uint8";
+      case 32 
+        format = "int32";
+      otherwise
+        fclose (fid);
+        error ("wavread: %d bits sample resolution is not supported with PCM",
+	       bits_per_sample);
+    endswitch
+  else
+    switch (bits_per_sample)
+      case 32 
+        format = "float32";
+      case 64 
+        format = "float64";
+      otherwise
+        fclose (fid);
+        error ("wavread: %d bits sample resolution is not supported with IEEE float",
+	       bits_per_sample);
+    endswitch
+  endif
+  
+  ## Parse arguments.
+  if (nargin == 1)
+    length = 8 * data_size / bits_per_sample;
+  else
+    if (size (param, 2) == 1)
+      ## Number of samples is given.
+      length = param * channels;
+    elseif (size (param, 2) == 2)
+      ## Sample range is given.
+      if (fseek (fid, (param(1)-1) * channels * (bits_per_sample/8), "cof") < 0)
+        warning ("wavread: seeking failed");
+      endif
+      length = (param(2)-param(1)+1) * channels;
+    elseif (size (param, 2) == 4 && char (param) == "size")
+      ## Size of the file is requested.
+      fclose (fid);
+      y = [data_size/channels/(bits_per_sample/8), channels];
+      return
+    else
+      fclose (fid);
+      error ("wavread: invalid argument 2");
+    endif
+  endif
+
+  ## Read samples and close file.
+  if (bits_per_sample == 24)
+    length *= 3;
+  endif
+  [yi, n] = fread (fid, length, format, 0, BYTEORDER);
+  fclose (fid);
+
+  ## Check data.
+  if (mod (numel (yi), channels) != 0)
+    error ("wavread: data in %s doesn't match the number of channels",
+	   filename);
+  endif
+
+  if (bits_per_sample == 24)
+    yi = reshape (yi, 3, rows(yi)/3)';
+    yi(yi(:,3) >= 128, 3) -= 256;
+    yi = yi * [1; 256; 65536];
+  endif
+
+  if (format_tag == FORMAT_PCM)
+    ## Normalize samples.
+    switch (bits_per_sample)
+      case 8
+        yi = (yi - 128)/127;
+      case 16
+        yi /= 32767;
+      case 24
+		yi /= 8388607;
+      case 32
+        yi /= 2147483647;
+    endswitch
+  endif
+  
+  ## Deinterleave.
+  nr = numel (yi) / channels;
+  y = reshape (yi, channels, nr)';
+  
+endfunction
+
+## Given a chunk_id, scan through chunks from the current file position
+## though at most size bytes.  Return the size of the found chunk, with
+## file position pointing to the start of the chunk data.  Return -1 for
+## size if chunk is not found.
+
+function chunk_size = find_chunk (fid, chunk_id, size)
+  id = "";
+  offset = 8;
+  chunk_size = 0;
+
+  while (! strcmp (id, chunk_id) && (offset < size))
+    fseek (fid, chunk_size, "cof");
+    id = char (fread (fid, 4))';
+    chunk_size = fread (fid, 1, "uint32", 0, "ieee-le");
+    offset = offset + 8 + chunk_size;
+  endwhile
+  if (! strcmp (id, chunk_id))
+    chunk_size = -1;
+  endif
+endfunction
diff --git a/scripts/audio/wavwrite.m b/scripts/audio/wavwrite.m
new file mode 100644
index 0000000..ae99b82
--- /dev/null
+++ b/scripts/audio/wavwrite.m
@@ -0,0 +1,186 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Michael Zeising
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wavwrite (@var{y}, @var{filename})
+## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{filename})
+## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{bits}, @var{filename})
+## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}
+## with sample rate @var{fs} and bits per sample @var{bits}.  The
+## default sample rate is 8000 Hz with 16-bits per sample.  Each column
+## of the data represents a separate channel.
+## @seealso{wavread}
+## @end deftypefn
+
+## Author: Michael Zeising <michael at michaels-website.de>
+## Created: 06 December 2005
+
+function wavwrite (y, varargin)
+
+  BYTEORDER = "ieee-le";
+
+  ## For backward compatibility with previous versions of Octave, also
+  ## accept the inputs
+  ##
+  ##   wavwrite (filename, y)
+  ##   wavwrite (filename, y, fs)
+  ##   wavwrite (filename, y, fs, bits)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  ## Defaults.
+  samples_per_sec = 8000;
+  bits_per_sample = 16;
+
+  if (ischar (y))
+    filename = y;
+    y = varargin{1};
+    if (nargin > 2)
+      samples_per_sec = varargin{2};
+      if (nargin > 3)
+	bits_per_sample = varargin{3};
+      endif
+    endif
+  else
+    filename = varargin{end};
+    if (nargin > 2)
+      samples_per_sec = varargin{1};
+      if (nargin > 3)
+	bits_per_sample = varargin{2};
+      endif
+    endif
+  endif
+
+  ## test arguments
+  if (columns (y) < 1)
+    error ("wavwrite: Y must have at least one column");
+  endif
+  if (columns (y) > 2^15-1)
+    error ("wavwrite: Y has more than 32767 columns (too many for a WAV-file)");
+  endif
+
+  ## determine sample format
+  switch (bits_per_sample)
+    case 8  
+      format = "uint8";
+    case 16 
+      format = "int16";
+    case 32 
+      format = "int32";
+    otherwise
+      error ("wavwrite: sample resolution not supported");
+  endswitch
+  
+  ## calculate filesize
+  [n, channels] = size(y);
+
+  ## size of data chunk
+  ck_size = n*channels*(bits_per_sample/8);
+  
+  ## open file for writing binary
+
+  if (! ischar (filename))
+    error ("wavwrite: expecting filename to be a character string");
+  endif
+    
+  [fid, msg] = fopen (filename, "wb");
+  if (fid < 0)
+    error ("wavwrite: %s", msg);
+  endif
+  
+  ## write RIFF/WAVE header
+  c = 0;
+  c += fwrite (fid, "RIFF", "uchar");
+
+  ## file size - 8
+  c += fwrite (fid, ck_size + 36, "uint32", 0, BYTEORDER);
+  c += fwrite (fid, "WAVEfmt ", "uchar");
+
+  ## size of fmt chunk
+  c += fwrite (fid, 16, "uint32", 0, BYTEORDER);
+
+  ## sample format code (PCM)
+  c += fwrite (fid, 1, "uint16", 0, BYTEORDER);
+
+  ## channels
+  c += fwrite (fid, channels, "uint16", 0, BYTEORDER);
+
+  ## sample rate
+  c += fwrite (fid, samples_per_sec, "uint32", 0, BYTEORDER);
+
+  ## bytes per second
+  bps = samples_per_sec*channels*bits_per_sample/8;
+  c += fwrite (fid, bps, "uint32", 0, BYTEORDER);
+
+  ## block align
+  c += fwrite (fid, channels*bits_per_sample/8, "uint16", 0, BYTEORDER);
+
+  c += fwrite (fid, bits_per_sample, "uint16", 0, BYTEORDER);   
+  c += fwrite (fid, "data", "uchar");
+  c += fwrite (fid, ck_size, "uint32", 0, BYTEORDER);
+  
+  if (c < 25)
+    fclose (fid);
+    error ("wavwrite: writing to file failed");
+  endif
+  
+  ## interleave samples
+  yi = reshape (y', n*channels, 1);
+  
+  ## scale samples
+  switch (bits_per_sample)
+    case 8
+      yi = round (yi*127 + 128);
+    case 16
+      yi = round (yi*32767);
+    case 32
+      yi = round (yi*2147483647);
+  endswitch
+  
+  ## write to file
+  c = fwrite (fid, yi, format, 0, BYTEORDER);
+  
+  fclose (fid);
+  
+endfunction
+
+%!test
+%! A = [1:10; 1:10]/10;
+%! wavwrite("a.wav", A);
+%! [B, samples_per_sec, bits_per_sample] = wavread("a.wav");
+%! assert(A,B, 10^(-4));
+%! assert(samples_per_sec, 8000);
+%! assert(bits_per_sample, 16);
+%
+%!test
+%! A=[1:10; 1:10] / 10;
+%! wavwrite("a.wav", A, 4000);
+%! [B, samples_per_sec, bits_per_sample] = wavread("a.wav");
+%! assert(A,B, 10^(-4));
+%! assert(samples_per_sec, 4000);
+%! assert(bits_per_sample, 16);
+%
+%!test
+%! A=[1:10; 1:10] / 10;
+%! wavwrite("a.wav", A, 4000, 8);
+%! [B, samples_per_sec, bits_per_sample] = wavread("a.wav");
+%! assert(A,B, 10^(-2));
+%! assert(samples_per_sec, 4000);
+%! assert(bits_per_sample, 8);
diff --git a/scripts/configure b/scripts/configure
new file mode 100755
index 0000000..3a4f737
--- /dev/null
+++ b/scripts/configure
@@ -0,0 +1,2928 @@
+#! /bin/sh
+# From configure.in .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="startup/inputrc"
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+ac_config_files
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+
+ac_config_files="$ac_config_files Makefile audio/Makefile deprecated/Makefile elfun/Makefile general/Makefile geometry/Makefile help/Makefile image/Makefile io/Makefile linear-algebra/Makefile miscellaneous/Makefile optimization/Makefile path/Makefile pkg/Makefile plot/Makefile polynomial/Makefile set/Makefile signal/Makefile sparse/Makefile specfun/Makefile special-matrix/Makefile startup/Makefile statistics/Makefile statistics/base/Makefile statistics/distributions/Makefile statistics/models/Makefile statistics/tests/Makefile strings/Makefile time/Makefile testfun/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.64,
+  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "audio/Makefile") CONFIG_FILES="$CONFIG_FILES audio/Makefile" ;;
+    "deprecated/Makefile") CONFIG_FILES="$CONFIG_FILES deprecated/Makefile" ;;
+    "elfun/Makefile") CONFIG_FILES="$CONFIG_FILES elfun/Makefile" ;;
+    "general/Makefile") CONFIG_FILES="$CONFIG_FILES general/Makefile" ;;
+    "geometry/Makefile") CONFIG_FILES="$CONFIG_FILES geometry/Makefile" ;;
+    "help/Makefile") CONFIG_FILES="$CONFIG_FILES help/Makefile" ;;
+    "image/Makefile") CONFIG_FILES="$CONFIG_FILES image/Makefile" ;;
+    "io/Makefile") CONFIG_FILES="$CONFIG_FILES io/Makefile" ;;
+    "linear-algebra/Makefile") CONFIG_FILES="$CONFIG_FILES linear-algebra/Makefile" ;;
+    "miscellaneous/Makefile") CONFIG_FILES="$CONFIG_FILES miscellaneous/Makefile" ;;
+    "optimization/Makefile") CONFIG_FILES="$CONFIG_FILES optimization/Makefile" ;;
+    "path/Makefile") CONFIG_FILES="$CONFIG_FILES path/Makefile" ;;
+    "pkg/Makefile") CONFIG_FILES="$CONFIG_FILES pkg/Makefile" ;;
+    "plot/Makefile") CONFIG_FILES="$CONFIG_FILES plot/Makefile" ;;
+    "polynomial/Makefile") CONFIG_FILES="$CONFIG_FILES polynomial/Makefile" ;;
+    "set/Makefile") CONFIG_FILES="$CONFIG_FILES set/Makefile" ;;
+    "signal/Makefile") CONFIG_FILES="$CONFIG_FILES signal/Makefile" ;;
+    "sparse/Makefile") CONFIG_FILES="$CONFIG_FILES sparse/Makefile" ;;
+    "specfun/Makefile") CONFIG_FILES="$CONFIG_FILES specfun/Makefile" ;;
+    "special-matrix/Makefile") CONFIG_FILES="$CONFIG_FILES special-matrix/Makefile" ;;
+    "startup/Makefile") CONFIG_FILES="$CONFIG_FILES startup/Makefile" ;;
+    "statistics/Makefile") CONFIG_FILES="$CONFIG_FILES statistics/Makefile" ;;
+    "statistics/base/Makefile") CONFIG_FILES="$CONFIG_FILES statistics/base/Makefile" ;;
+    "statistics/distributions/Makefile") CONFIG_FILES="$CONFIG_FILES statistics/distributions/Makefile" ;;
+    "statistics/models/Makefile") CONFIG_FILES="$CONFIG_FILES statistics/models/Makefile" ;;
+    "statistics/tests/Makefile") CONFIG_FILES="$CONFIG_FILES statistics/tests/Makefile" ;;
+    "strings/Makefile") CONFIG_FILES="$CONFIG_FILES strings/Makefile" ;;
+    "time/Makefile") CONFIG_FILES="$CONFIG_FILES time/Makefile" ;;
+    "testfun/Makefile") CONFIG_FILES="$CONFIG_FILES testfun/Makefile" ;;
+
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/scripts/configure.in b/scripts/configure.in
new file mode 100644
index 0000000..7a429f5
--- /dev/null
+++ b/scripts/configure.in
@@ -0,0 +1,42 @@
+dnl configure.in
+dnl
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007,
+dnl               2008, 2009 John W. Eaton
+### 
+### This file is part of Octave.
+### 
+### Octave is free software; you can redistribute it and/or modify it
+### under the terms of the GNU General Public License as published by the
+### Free Software Foundation; either version 3 of the License, or (at
+### your option) any later version.
+### 
+### Octave is distributed in the hope that it will be useful, but WITHOUT
+### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+### FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+### for more details.
+### 
+### You should have received a copy of the GNU General Public License
+### along with Octave; see the file COPYING.  If not, see
+### <http://www.gnu.org/licenses/>.
+
+AC_INIT
+AC_REVISION()
+AC_PREREQ(2.52)
+AC_CONFIG_SRCDIR([startup/inputrc])
+
+AC_PROG_INSTALL
+
+AC_SUBST(ac_config_files)
+AC_CONFIG_FILES([Makefile audio/Makefile deprecated/Makefile elfun/Makefile \
+	  general/Makefile geometry/Makefile help/Makefile image/Makefile \
+	  io/Makefile linear-algebra/Makefile miscellaneous/Makefile \
+	  optimization/Makefile path/Makefile pkg/Makefile plot/Makefile \
+	  polynomial/Makefile set/Makefile \
+	  signal/Makefile sparse/Makefile specfun/Makefile \
+	  special-matrix/Makefile startup/Makefile statistics/Makefile \
+	  statistics/base/Makefile statistics/distributions/Makefile \
+	  statistics/models/Makefile statistics/tests/Makefile \
+	  strings/Makefile time/Makefile testfun/Makefile])
+AC_OUTPUT
diff --git a/scripts/deprecated/Makefile.in b/scripts/deprecated/Makefile.in
new file mode 100644
index 0000000..1a1e61b
--- /dev/null
+++ b/scripts/deprecated/Makefile.in
@@ -0,0 +1,108 @@
+# Makefile for octave's scripts/deprecated directory
+#
+# Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = deprecated
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = beta_cdf.m beta_inv.m beta_pdf.m beta_rnd.m \
+  binomial_cdf.m binomial_inv.m binomial_pdf.m binomial_rnd.m \
+  chisquare_cdf.m chisquare_inv.m chisquare_pdf.m chisquare_rnd.m \
+  clearplot.m clg.m com2str.m create_set.m \
+  dmult.m exponential_cdf.m exponential_inv.m \
+  exponential_pdf.m exponential_rnd.m f_cdf.m f_inv.m f_pdf.m \
+  f_rnd.m gamma_cdf.m gamma_inv.m gamma_pdf.m gamma_rnd.m \
+  geometric_cdf.m geometric_inv.m geometric_pdf.m geometric_rnd.m \
+  hypergeometric_cdf.m hypergeometric_inv.m hypergeometric_pdf.m \
+  hypergeometric_rnd.m intersection.m is_bool.m is_complex.m \
+  is_list.m is_matrix.m is_scalar.m is_square.m is_stream.m \
+  is_struct.m is_symmetric.m is_vector.m iscommand.m israwcommand.m \
+  isstr.m lchol.m loadimage.m lognormal_cdf.m lognormal_inv.m \
+  lognormal_pdf.m lognormal_rnd.m mark_as_command.m \
+  mark_as_rawcommand.m meshdom.m normal_cdf.m normal_inv.m \
+  normal_pdf.m normal_rnd.m pascal_cdf.m pascal_inv.m pascal_pdf.m \
+  pascal_rnd.m poisson_cdf.m poisson_inv.m poisson_pdf.m \
+  poisson_rnd.m polyinteg.m setstr.m spatan2.m spchol2inv.m \
+  spcholinv.m spcumprod.m spcumsum.m spchol.m spdet.m spdiag.m \
+  spfind.m spinv.m spkron.m splchol.m split.m splu.m spmax.m spmin.m \
+  spprod.m spqr.m spsum.m spsumsq.m struct_contains.m \
+  struct_elements.m t_cdf.m t_inv.m t_pdf.m t_rnd.m uniform_cdf.m \
+  uniform_inv.m uniform_pdf.m uniform_rnd.m unmark_command.m \
+  unmark_rawcommand.m weibcdf.m weibinv.m weibpdf.m weibrnd.m \
+  weibull_cdf.m weibull_inv.m weibull_pdf.m weibull_rnd.m \
+  wiener_rnd.m str2mat.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/deprecated
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/deprecated/beta_cdf.m b/scripts/deprecated/beta_cdf.m
new file mode 100644
index 0000000..102b182
--- /dev/null
+++ b/scripts/deprecated/beta_cdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} beta_cdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, returns the CDF at @var{x} of the beta
+## distribution with parameters @var{a} and @var{b}, i.e.,
+## PROB (beta (@var{a}, @var{b}) <= @var{x}).
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Beta distribution
+
+## Deprecated in version 3.0
+
+function cdf = beta_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "beta_cdf is obsolete and will be removed from a future version of Octave; please use betacdf instead");
+  endif
+
+ cdf =  betacdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/beta_inv.m b/scripts/deprecated/beta_inv.m
new file mode 100644
index 0000000..930676a
--- /dev/null
+++ b/scripts/deprecated/beta_inv.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} beta_inv (@var{x}, @var{a}, @var{b})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the Beta distribution with parameters @var{a}
+## and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Beta distribution
+
+## Deprecated in version 3.0
+
+function inv = beta_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "beta_inv is obsolete and will be removed from a future version of Octave; please use betainv instead");
+  endif
+
+ inv =  betainv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/beta_pdf.m b/scripts/deprecated/beta_pdf.m
new file mode 100644
index 0000000..ca429c5
--- /dev/null
+++ b/scripts/deprecated/beta_pdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} beta_pdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, returns the PDF at @var{x} of the beta
+## distribution with parameters @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Beta distribution
+
+## Deprecated in version 3.0
+
+function pdf = beta_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "beta_pdf is obsolete and will be removed from a future version of Octave; please use betapdf instead");
+  endif
+
+ pdf =  betapdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/beta_rnd.m b/scripts/deprecated/beta_rnd.m
new file mode 100644
index 0000000..53cac6c
--- /dev/null
+++ b/scripts/deprecated/beta_rnd.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} beta_rnd (@var{a}, @var{b}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} beta_rnd (@var{a}, @var{b}, @var{sz})
+## Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+## random samples from the Beta distribution with parameters @var{a} and
+## @var{b}.  Both @var{a} and @var{b} must be scalar or of size @var{r}
+##  by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Beta distribution
+
+## Deprecated in version 3.0
+
+function rnd = beta_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "beta_rnd is obsolete and will be removed from a future version of Octave; please use betarnd instead");
+  endif
+
+ rnd =  betarnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/binomial_cdf.m b/scripts/deprecated/binomial_cdf.m
new file mode 100644
index 0000000..2f4e15f
--- /dev/null
+++ b/scripts/deprecated/binomial_cdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binomial_cdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the CDF at @var{x} of the
+## binomial distribution with parameters @var{n} and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the binomial distribution
+
+## Deprecated in version 3.0
+
+function cdf = binomial_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "binomial_cdf is obsolete and will be removed from a future version of Octave; please use binocdf instead");
+  endif
+
+ cdf =  binocdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/binomial_inv.m b/scripts/deprecated/binomial_inv.m
new file mode 100644
index 0000000..b85d81b
--- /dev/null
+++ b/scripts/deprecated/binomial_inv.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binomial_inv (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## binomial distribution with parameters @var{n} and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the binomial distribution
+
+## Deprecated in version 3.0
+
+function inv = binomial_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "binomial_inv is obsolete and will be removed from a future version of Octave; please use binoinv instead");
+  endif
+
+ inv =  binoinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/binomial_pdf.m b/scripts/deprecated/binomial_pdf.m
new file mode 100644
index 0000000..7c5abe6
--- /dev/null
+++ b/scripts/deprecated/binomial_pdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binomial_pdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the binomial distribution with parameters @var{n}
+## and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the binomial distribution
+
+## Deprecated in version 3.0
+
+function pdf = binomial_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "binomial_pdf is obsolete and will be removed from a future version of Octave; please use binopdf instead");
+  endif
+
+ pdf =  binopdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/binomial_rnd.m b/scripts/deprecated/binomial_rnd.m
new file mode 100644
index 0000000..fbd43b0
--- /dev/null
+++ b/scripts/deprecated/binomial_rnd.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binomial_rnd (@var{n}, @var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} binomial_rnd (@var{n}, @var{p}, @var{sz})
+## Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+## random samples from the binomial distribution with parameters @var{n}
+## and @var{p}.  Both @var{n} and @var{p} must be scalar or of size
+## @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{n} and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the binomial distribution
+
+## Deprecated in version 3.0
+
+function rnd = binomial_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "binomial_rnd is obsolete and will be removed from a future version of Octave; please use binornd instead");
+  endif
+
+ rnd =  binornd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/chisquare_cdf.m b/scripts/deprecated/chisquare_cdf.m
new file mode 100644
index 0000000..5ec4d77
--- /dev/null
+++ b/scripts/deprecated/chisquare_cdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chisquare_cdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the chisquare distribution with @var{n}
+## degrees of freedom.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: CDF of the chi-square distribution
+
+## Deprecated in version 3.0
+
+function cdf = chisquare_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "chisquare_cdf is obsolete and will be removed from a future version of Octave; please use chi2cdf instead");
+  endif
+
+ cdf =  chi2cdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/chisquare_inv.m b/scripts/deprecated/chisquare_inv.m
new file mode 100644
index 0000000..650eac3
--- /dev/null
+++ b/scripts/deprecated/chisquare_inv.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chisquare_inv (@var{x}, @var{n})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the chisquare distribution with @var{n} degrees of
+## freedom.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: Quantile function of the chi-square distribution
+
+## Deprecated in version 3.0
+
+function inv = chisquare_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "chisquare_inv is obsolete and will be removed from a future version of Octave; please use chi2inv instead");
+  endif
+
+ inv =  chi2inv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/chisquare_pdf.m b/scripts/deprecated/chisquare_pdf.m
new file mode 100644
index 0000000..0516be5
--- /dev/null
+++ b/scripts/deprecated/chisquare_pdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chisquare_pdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the chisquare distribution with @var{n} degrees
+## of freedom. 
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the chi-sqaure distribution
+
+## Deprecated in version 3.0
+
+function pdf = chisquare_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "chisquare_pdf is obsolete and will be removed from a future version of Octave; please use chi2pdf instead");
+  endif
+
+ pdf =  chi2pdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/chisquare_rnd.m b/scripts/deprecated/chisquare_rnd.m
new file mode 100644
index 0000000..7b3f85e
--- /dev/null
+++ b/scripts/deprecated/chisquare_rnd.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chisquare_rnd (@var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} chisquare_rnd (@var{n}, @var{sz})
+## Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+## random samples from the chisquare distribution with @var{n} degrees 
+## of freedom.  @var{n} must be a scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the chi-square distribution
+
+## Deprecated in version 3.0
+
+function rnd = chisquare_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "chisquare_rnd is obsolete and will be removed from a future version of Octave; please use chi2rnd instead");
+  endif
+
+ rnd =  chi2rnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/clearplot.m b/scripts/deprecated/clearplot.m
new file mode 100644
index 0000000..f765672
--- /dev/null
+++ b/scripts/deprecated/clearplot.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} clearplot ()
+## This function has been deprecated.  Use clf instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function clearplot ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "clearplot is obsolete and will be removed from a future version of Octave; please use clf instead");
+  endif
+
+  clf ();
+
+endfunction
diff --git a/scripts/deprecated/clg.m b/scripts/deprecated/clg.m
new file mode 100644
index 0000000..d768c54
--- /dev/null
+++ b/scripts/deprecated/clg.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} clg ()
+## This function has been deprecated.  Use clf instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function clg ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "clg is obsolete and will be removed from a future version of Octave, please use clf instead");
+  endif
+
+  clf ();
+
+endfunction
diff --git a/scripts/deprecated/com2str.m b/scripts/deprecated/com2str.m
new file mode 100644
index 0000000..5104923
--- /dev/null
+++ b/scripts/deprecated/com2str.m
@@ -0,0 +1,93 @@
+## Copyright (C) 1998, 2004, 2005, 2006, 2007, 2008
+##               Auburn University.  All rights reserved.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} com2str (@var{zz}, @var{flg})
+## This function has been deprecated.  Use num2str instead.
+##
+## Convert complex number to a string.
+## @strong{Inputs}
+## @table @var
+## @item zz
+## complex number
+## @item flg
+## format flag
+## 0 (default):            -1, 0, 1,   1i,   1 + 0.5i
+## 1 (for use with zpout): -1, 0, + 1, + 1i, + 1 + 0.5i
+## @end table
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function retval = com2str (zz, flg)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "com2str is obsolete and will be removed from a future version of Octave; please use num2str instead");
+  endif
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+  if (nargin == 1)
+    flg = 0;
+  endif
+
+  if (! (isscalar (zz) && isscalar (flg)))
+    error ("com2str: arguments must be a scalar");
+  endif
+
+  if (flg != 0 && flg != 1)
+    error ("invalid flg value: %d", flg);
+  endif
+
+  sgns = "+-";
+  rz = real (zz);
+  iz = imag (zz);
+  az = abs (zz);
+  if (iz == 0)
+    ## strictly a real number
+    switch (flg)
+      case(0)
+	retval = num2str (rz);
+      case(1)
+	retval = [sgns(1+(rz<0)), " ", num2str(abs(rz))];
+    endswitch
+  elseif (rz == 0)
+    ## strictly an imaginary number
+    switch (flg)
+      case(0)
+	retval = [num2str(iz), "i"];
+      case(1)
+	retval = [sgns(1+(iz<0)), " ", num2str(abs(iz)), "i"];
+    endswitch
+  else
+    ## complex number
+    ## strictly an imaginary number
+    switch (flg)
+      case(0)
+	retval = [num2str(rz), " ", com2str(i*iz,1)];
+      case(1)
+	retval = [sgns(1+(rz<0)), " ", num2str(abs(rz)), " ", com2str(i*iz,1)];
+    endswitch
+  endif
+
+endfunction
diff --git a/scripts/deprecated/create_set.m b/scripts/deprecated/create_set.m
new file mode 100644
index 0000000..ef8bbaa
--- /dev/null
+++ b/scripts/deprecated/create_set.m
@@ -0,0 +1,80 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} create_set (@var{x})
+## @deftypefnx{Function File} {} create_set (@var{x}, "rows")
+## This function has been deprecated.  Use unique instead.
+## @end deftypefn
+
+## Return a row vector containing the unique values in @var{x}, sorted in
+## ascending order.  For example,
+##
+## @example
+## @group
+## create_set ([ 1, 2; 3, 4; 4, 2; 1, 2 ])
+##      @result{} [ 1, 2, 3, 4 ]
+## @end group
+## @end example
+##
+## If the optional second input argument is the string "rows" each row of
+## the matrix @var{x} will be considered an element of set.  For example,
+## @example
+## @group
+## create_set ([ 1, 2; 3, 4; 4, 2; 1, 2 ], "rows")
+##      @result{}  1   2
+##     3   4
+##     4   2
+## @end group
+## @end example
+## @seealso{union, intersect, complement, unique}
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function y = create_set (x, rows_opt)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "create_set is obsolete and will be removed from a future version of Octave, please use unique instead");
+  endif
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+  
+  if (nargin == 1)
+    y = unique (x)(:)';
+  elseif (strcmpi (rows_opt, "rows"))
+    y = unique (x, "rows");
+  else
+    error ("create_set: expecting \"rows\" as second argument");
+  endif
+
+endfunction
+
+%!assert(all (all (create_set ([1, 2, 3, 4, 2, 4]) == [1, 2, 3, 4])));
+%!assert(all (all (create_set ([1, 2; 3, 4; 2, 4]) == [1, 2, 3, 4])));
+%!assert(all (all (create_set ([1; 2; 3; 4; 2; 4]) == [1, 2, 3, 4])));
+%!assert(isempty (create_set ([])));
+%!error create_set (1, 2);
+
diff --git a/scripts/deprecated/dmult.m b/scripts/deprecated/dmult.m
new file mode 100644
index 0000000..ceffb41
--- /dev/null
+++ b/scripts/deprecated/dmult.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dmult (@var{a}, @var{b})
+## This function has been deprecated.  Use the direct syntax @code{diag(A)*B}
+## which is more readable and now also more efficient.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Rescale the rows of a matrix
+
+## Deprecated in version 3.2
+
+function M = dmult (a, B)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "dmult is obsolete and will be removed from a future version of Octave; please use the straightforward (and now efficient) syntax ""diag(A)*B"".");
+  endif
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+ if (! isvector (a))
+    error ("dmult: a must be a vector of length rows (B)");
+  endif
+  a = a(:);
+  sb = size (B);
+  sb(1) = 1;
+  M = repmat (a(:), sb) .* B;
+endfunction
diff --git a/scripts/deprecated/exponential_cdf.m b/scripts/deprecated/exponential_cdf.m
new file mode 100644
index 0000000..cb24499
--- /dev/null
+++ b/scripts/deprecated/exponential_cdf.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} exponential_cdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the exponential distribution with
+## parameter @var{lambda}.
+##
+## The arguments can be of common size or scalar.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the exponential distribution
+
+## Deprecated in version 3.0
+
+function cdf = exponential_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "exponential_cdf is obsolete and will be removed from a future version of Octave; please use expcdf instead");
+  endif
+
+ if (nargin > 1)
+   varargin{2} = 1 ./ varargin{2};
+ endif
+
+ cdf =  expcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/exponential_inv.m b/scripts/deprecated/exponential_inv.m
new file mode 100644
index 0000000..9a91534
--- /dev/null
+++ b/scripts/deprecated/exponential_inv.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} exponential_inv (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the exponential distribution with parameter
+## @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the exponential distribution
+
+## Deprecated in version 3.0
+
+function inv = exponential_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "exponential_inv is obsolete and will be removed from a future version of Octave; please use expinv instead");
+  endif
+
+ if (nargin > 1)
+   varargin{2} = 1 ./ varargin{2};
+ endif
+
+ inv =  expinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/exponential_pdf.m b/scripts/deprecated/exponential_pdf.m
new file mode 100644
index 0000000..db64f12
--- /dev/null
+++ b/scripts/deprecated/exponential_pdf.m
@@ -0,0 +1,45 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} exponential_pdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the probability density function
+## (PDF) of the exponential distribution with parameter @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the exponential distribution
+
+## Deprecated in version 3.0
+
+function pdf = exponential_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "exponential_pdf is obsolete and will be removed from a future version of Octave; please use exppdf instead");
+  endif
+
+ if (nargin > 1)
+   varargin{2} = 1 ./ varargin{2};
+ endif
+
+ pdf =  exppdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/exponential_rnd.m b/scripts/deprecated/exponential_rnd.m
new file mode 100644
index 0000000..a21907b
--- /dev/null
+++ b/scripts/deprecated/exponential_rnd.m
@@ -0,0 +1,51 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} exponential_rnd (@var{lambda}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} exponential_rnd (@var{lambda}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## exponential distribution with parameter @var{lambda}, which must be a
+## scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a vector, 
+## create a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the exponential distribution
+
+## Deprecated in version 3.0
+
+function rnd = exponential_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "exponential_rnd is obsolete and will be removed from a future version of Octave; please use exprnd instead");
+  endif
+
+ if (nargin > 0)
+   varargin{1} = 1 ./ varargin{1};
+ endif
+
+ rnd =  exprnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/f_cdf.m b/scripts/deprecated/f_cdf.m
new file mode 100644
index 0000000..8b4d3d0
--- /dev/null
+++ b/scripts/deprecated/f_cdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} f_cdf (@var{x}, @var{m}, @var{n})
+## For each element of @var{x}, compute the CDF at @var{x} of the F
+## distribution with @var{m} and @var{n} degrees of freedom, i.e.,
+## PROB (F (@var{m}, @var{n}) <= @var{x}). 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the F distribution
+
+## Deprecated in version 3.0
+
+function cdf = f_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "f_cdf is obsolete and will be removed from a future version of Octave; please use fcdf instead");
+  endif
+
+ cdf =  fcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/f_inv.m b/scripts/deprecated/f_inv.m
new file mode 100644
index 0000000..3283b69
--- /dev/null
+++ b/scripts/deprecated/f_inv.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} f_inv (@var{x}, @var{m}, @var{n})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the F distribution with parameters @var{m} and
+## @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the F distribution
+
+## Deprecated in version 3.0
+
+function inv = f_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "f_inv is obsolete and will be removed from a future version of Octave; please use finv instead");
+  endif
+
+ inv =  finv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/f_pdf.m b/scripts/deprecated/f_pdf.m
new file mode 100644
index 0000000..0e3e058
--- /dev/null
+++ b/scripts/deprecated/f_pdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} f_pdf (@var{x}, @var{m}, @var{n})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the F distribution with @var{m} and @var{n}
+## degrees of freedom.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the F distribution
+
+## Deprecated in version 3.0
+
+function pdf = f_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "f_pdf is obsolete and will be removed from a future version of Octave; please use fpdf instead");
+  endif
+
+ pdf =  fpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/f_rnd.m b/scripts/deprecated/f_rnd.m
new file mode 100644
index 0000000..383ebca
--- /dev/null
+++ b/scripts/deprecated/f_rnd.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} f_rnd (@var{m}, @var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} f_rnd (@var{m}, @var{n}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the F
+## distribution with @var{m} and @var{n} degrees of freedom.  Both
+## @var{m} and @var{n} must be scalar or of size @var{r} by @var{c}.
+## If @var{sz} is a vector the random samples are in a matrix of 
+## size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{m} and @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the F distribution
+
+## Deprecated in version 3.0
+
+function rnd = f_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "f_rnd is obsolete and will be removed from a future version of Octave; please use frnd instead");
+  endif
+
+ rnd =  frnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/gamma_cdf.m b/scripts/deprecated/gamma_cdf.m
new file mode 100644
index 0000000..b20d9ee
--- /dev/null
+++ b/scripts/deprecated/gamma_cdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gamma_cdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the Gamma distribution with parameters
+## @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: CDF of the Gamma distribution
+
+## Deprecated in version 3.0
+
+function cdf = gamma_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "gamma_cdf is obsolete and will be removed from a future version of Octave; please use gamcdf instead");
+  endif
+
+ if (nargin > 2)
+   varargin{3} = 1 ./ varargin{3};
+ endif
+
+ cdf =  gamcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/gamma_inv.m b/scripts/deprecated/gamma_inv.m
new file mode 100644
index 0000000..2585c48
--- /dev/null
+++ b/scripts/deprecated/gamma_inv.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gamma_inv (@var{x}, @var{a}, @var{b})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the Gamma distribution with parameters @var{a}
+## and @var{b}. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Gamma distribution
+
+## Deprecated in version 3.0
+
+function inv = gamma_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "gamma_inv is obsolete and will be removed from a future version of Octave; please use gaminv instead");
+  endif
+
+ if (nargin > 2)
+   varargin{3} = 1 ./ varargin{3};
+ endif
+
+ inv =  gaminv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/gamma_pdf.m b/scripts/deprecated/gamma_pdf.m
new file mode 100644
index 0000000..9ad2419
--- /dev/null
+++ b/scripts/deprecated/gamma_pdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gamma_pdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, return the probability density function
+## (PDF) at @var{x} of the Gamma distribution with parameters @var{a}
+## and @var{b}.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the Gamma distribution
+
+## Deprecated in version 3.0
+
+function pdf = gamma_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "gamma_pdf is obsolete and will be removed from a future version of Octave; please use gampdf instead");
+  endif
+
+ if (nargin > 2)
+   varargin{3} = 1 ./ varargin{3};
+ endif
+
+ pdf =  gampdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/gamma_rnd.m b/scripts/deprecated/gamma_rnd.m
new file mode 100644
index 0000000..31aacfd
--- /dev/null
+++ b/scripts/deprecated/gamma_rnd.m
@@ -0,0 +1,51 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gamma_rnd (@var{a}, @var{b}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} gamma_rnd (@var{a}, @var{b}, @var{sz})
+## Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+## random samples from the Gamma distribution with parameters @var{a}
+## and @var{b}.  Both @var{a} and @var{b} must be scalar or of size 
+## @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Gamma distribution
+
+## Deprecated in version 3.0
+
+function rnd = gamma_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "gamma_rnd is obsolete and will be removed from a future version of Octave; please use gamrnd instead");
+  endif
+
+ if (nargin > 1)
+   varargin{2} = 1 ./ varargin{2};
+ endif
+
+ rnd =  gamrnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/geometric_cdf.m b/scripts/deprecated/geometric_cdf.m
new file mode 100644
index 0000000..723f25a
--- /dev/null
+++ b/scripts/deprecated/geometric_cdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geometric_cdf (@var{x}, @var{p})
+## For each element of @var{x}, compute the CDF at @var{x} of the
+## geometric distribution with parameter @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the geometric distribution
+
+## Deprecated in version 3.0
+
+function cdf = geometric_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "geometric_cdf is obsolete and will be removed from a future version of Octave; please use geocdf instead");
+  endif
+
+ cdf =  geocdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/geometric_inv.m b/scripts/deprecated/geometric_inv.m
new file mode 100644
index 0000000..a4735f7
--- /dev/null
+++ b/scripts/deprecated/geometric_inv.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geometric_inv (@var{x}, @var{p})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## geometric distribution with parameter @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the geometric distribution
+
+## Deprecated in version 3.0
+
+function inv = geometric_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "geometric_inv is obsolete and will be removed from a future version of Octave; please use geoinv instead");
+  endif
+
+ inv =  geoinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/geometric_pdf.m b/scripts/deprecated/geometric_pdf.m
new file mode 100644
index 0000000..99520bc
--- /dev/null
+++ b/scripts/deprecated/geometric_pdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geometric_pdf (@var{x}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the geometric distribution with parameter @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the geometric distribution
+
+## Deprecated in version 3.0
+
+function pdf = geometric_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "geometric_pdf is obsolete and will be removed from a future version of Octave; please use geopdf instead");
+  endif
+
+ pdf =  geopdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/geometric_rnd.m b/scripts/deprecated/geometric_rnd.m
new file mode 100644
index 0000000..c0a7cb8
--- /dev/null
+++ b/scripts/deprecated/geometric_rnd.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geometric_rnd (@var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} geometric_rnd (@var{p}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## geometric distribution with parameter @var{p}, which must be a scalar
+## or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+## @var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+## @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the geometric distribution
+
+## Deprecated in version 3.0
+
+function rnd = geometric_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "geometric_rnd is obsolete and will be removed from a future version of Octave; please use geornd instead");
+  endif
+
+ rnd =  geornd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/hypergeometric_cdf.m b/scripts/deprecated/hypergeometric_cdf.m
new file mode 100644
index 0000000..61b989a
--- /dev/null
+++ b/scripts/deprecated/hypergeometric_cdf.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hypergeometric_cdf (@var{x}, @var{m}, @var{t}, @var{n})
+## Compute the cumulative distribution function (CDF) at @var{x} of the
+## hypergeometric distribution with parameters @var{m}, @var{t}, and
+## @var{n}.  This is the probability of obtaining not more than @var{x}
+## marked items when randomly drawing a sample of size @var{n} without
+## replacement from a population of total size @var{t} containing
+## @var{m} marked items.
+##
+## The parameters @var{m}, @var{t}, and @var{n} must positive integers
+## with @var{m} and @var{n} not greater than @var{t}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the hypergeometric distribution
+
+## Deprecated in version 3.0
+
+function cdf = hypergeometric_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "hypergeometric_cdf is obsolete and will be removed from a future version of Octave; please use hygecdf instead");
+  endif
+
+ cdf =  hygecdf (varargin{:});
+
+endfunction
+
+
diff --git a/scripts/deprecated/hypergeometric_inv.m b/scripts/deprecated/hypergeometric_inv.m
new file mode 100644
index 0000000..1e4f3e3
--- /dev/null
+++ b/scripts/deprecated/hypergeometric_inv.m
@@ -0,0 +1,45 @@
+## Copyright (C) 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hypergeometric_inv (@var{x}, @var{m}, @var{t}, @var{n})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## hypergeometric distribution with parameters @var{m}, @var{t}, and
+## @var{n}.
+##
+## The parameters @var{m}, @var{t}, and @var{n} must positive integers
+## with @var{m} and @var{n} not greater than @var{t}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the hypergeometric distribution
+
+## Deprecated in version 3.0
+
+function inv = hypergeometric_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "hypergeometric_inv is obsolete and will be removed from a future version of Octave; please use hygeinv instead");
+  endif
+
+ inv =  hygeinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/hypergeometric_pdf.m b/scripts/deprecated/hypergeometric_pdf.m
new file mode 100644
index 0000000..6d5e12c
--- /dev/null
+++ b/scripts/deprecated/hypergeometric_pdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1996, 1997, 2005, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hypergeometric_pdf (@var{x}, @var{m}, @var{t}, @var{n})
+## Compute the probability density function (PDF) at @var{x} of the
+## hypergeometric distribution with parameters @var{m}, @var{t}, and
+## @var{n}.  This is the probability of obtaining @var{x} marked items
+## when randomly drawing a sample of size @var{n} without replacement
+## from a population of total size @var{t} containing @var{m} marked items.
+##
+## The arguments must be of common size or scalar.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the hypergeometric distribution
+
+## Deprecated in version 3.0
+
+function pdf = hypergeometric_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "hypergeometric_pdf is obsolete and will be removed from a future version of Octave; please use hygepdf instead");
+  endif
+
+ pdf =  hygepdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/hypergeometric_rnd.m b/scripts/deprecated/hypergeometric_rnd.m
new file mode 100644
index 0000000..a116d04
--- /dev/null
+++ b/scripts/deprecated/hypergeometric_rnd.m
@@ -0,0 +1,43 @@
+## Copyright (C) 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hypergeometric_rnd (@var{m}, @var{t}, @var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} hygernd (@var{m}, @var{t}, @var{n}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## hypergeometric distribution with parameters @var{m}, @var{t},
+## and @var{n}.
+##
+## The parameters @var{m}, @var{t}, and @var{n} must positive integers
+## with @var{m} and @var{n} not greater than @var{t}.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function rnd = hypergeometric_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "hypergeometric_rnd is obsolete and will be removed from a future version of Octave; please use hygernd instead");
+  endif
+
+  rnd = hygernd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/intersection.m b/scripts/deprecated/intersection.m
new file mode 100644
index 0000000..90657f0
--- /dev/null
+++ b/scripts/deprecated/intersection.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1996, 1997, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} intersection (@var{x}, @var{y})
+## This function has been deprecated.  Use intersect instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function y = intersection (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "intersection is obsolete and will be removed from a future version of Octave; please use intersect instead");
+  endif
+
+  y = intersect (varargin{:});
+
+endfunction
+
+%!assert(all (all (intersection ([1, 2, 3], [2, 3, 5]) == [2, 3])));
+
+%!assert(all (all (intersection ([1; 2; 3], [2, 3, 5]) == [2, 3])));
+
+%!assert(isempty (intersection ([1, 2, 3], [4; 5; 6])));
+
+%!error intersection (1);
+
+%!error intersection (1, 2, 5);
+
diff --git a/scripts/deprecated/is_bool.m b/scripts/deprecated/is_bool.m
new file mode 100644
index 0000000..7eefe09
--- /dev/null
+++ b/scripts/deprecated/is_bool.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_bool (@var{a})
+## This function has been deprecated.  Use isbool instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_bool (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_bool is obsolete and will be removed from a future version of Octave; please use isbool instead");
+  endif
+
+  retval = isbool (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_complex.m b/scripts/deprecated/is_complex.m
new file mode 100644
index 0000000..90cd584
--- /dev/null
+++ b/scripts/deprecated/is_complex.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_complex (@var{a})
+## This function has been deprecated.  Use iscomplex instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_complex (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_complex is obsolete and will be removed from a future version of Octave; please use iscomplex instead");
+  endif
+
+  retval = iscomplex (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_list.m b/scripts/deprecated/is_list.m
new file mode 100644
index 0000000..81086c2
--- /dev/null
+++ b/scripts/deprecated/is_list.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_list (@var{a})
+## This function has been deprecated.  Use islist instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_list (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_list is obsolete and will be removed from a future version of Octave; please use islist instead");
+  endif
+
+  retval = islist (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_matrix.m b/scripts/deprecated/is_matrix.m
new file mode 100644
index 0000000..7befbd8
--- /dev/null
+++ b/scripts/deprecated/is_matrix.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_matrix (@var{a})
+## This function has been deprecated.  Use ismatrix instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_matrix (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_matrix is obsolete and will be removed from a future version of Octave; please use ismatrix instead");
+  endif
+
+  retval = ismatrix (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_scalar.m b/scripts/deprecated/is_scalar.m
new file mode 100644
index 0000000..820afc0
--- /dev/null
+++ b/scripts/deprecated/is_scalar.m
@@ -0,0 +1,39 @@
+## Copyright (C) 1996, 1997, 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_scalar (@var{a})
+## This function has been deprecated.  Use isscalar instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_scalar (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_scalar is obsolete and will be removed from a future version of Octave; please use isscalar instead");
+  endif
+
+  retval = isscalar (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_square.m b/scripts/deprecated/is_square.m
new file mode 100644
index 0000000..aedc73f
--- /dev/null
+++ b/scripts/deprecated/is_square.m
@@ -0,0 +1,39 @@
+## Copyright (C) 1996, 1997, 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_square (@var{x})
+## This function has been deprecated.  Use issquare instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_square (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_square is obsolete and will be removed from a future version of Octave; please use issquare instead");
+  endif
+
+  retval = issquare (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_stream.m b/scripts/deprecated/is_stream.m
new file mode 100644
index 0000000..4f725b5
--- /dev/null
+++ b/scripts/deprecated/is_stream.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_stream (@var{a})
+## This function has been deprecated.  Use isstream instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_stream (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_stream is obsolete and will be removed from a future version of Octave; please use isstream instead");
+  endif
+
+  retval = isstream(varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_struct.m b/scripts/deprecated/is_struct.m
new file mode 100644
index 0000000..7ad578c
--- /dev/null
+++ b/scripts/deprecated/is_struct.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_struct (@var{a})
+## This function has been deprecated.  Use isstruct instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_struct (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_struct is obsolete and will be removed from a future version of Octave; please use isstruct instead");
+  endif
+
+  retval = isstruct (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_symmetric.m b/scripts/deprecated/is_symmetric.m
new file mode 100644
index 0000000..bb005fe
--- /dev/null
+++ b/scripts/deprecated/is_symmetric.m
@@ -0,0 +1,39 @@
+## Copyright (C) 1996, 1997, 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} issymmetric (@var{x}, @var{tol})
+## This function has been deprecated.  Use issymmetric instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_symmetric (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_symmetric is obsolete and will be removed from a future version of Octave; please use issymmetric instead");
+  endif
+
+  retval = issymmetric (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/is_vector.m b/scripts/deprecated/is_vector.m
new file mode 100644
index 0000000..5480c90
--- /dev/null
+++ b/scripts/deprecated/is_vector.m
@@ -0,0 +1,39 @@
+## Copyright (C) 1996, 1997, 2002, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_vector (@var{a})
+## This function has been deprecated.  Use isvector instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = is_vector (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "is_vector is obsolete and will be removed from a future version of Octave; please use isvector instead");
+  endif
+
+  retval = isvector (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/iscommand.m b/scripts/deprecated/iscommand.m
new file mode 100644
index 0000000..735cf16
--- /dev/null
+++ b/scripts/deprecated/iscommand.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} iscommand (@var{name})
+## This function is obsolete and will be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function retval = iscommand ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "iscommand is obsolete and will be removed from a future version of Octave");
+  endif
+
+  if (nargin == 0)
+    retval = {};
+  else
+    retval = true;
+  endif
+
+endfunction
diff --git a/scripts/deprecated/israwcommand.m b/scripts/deprecated/israwcommand.m
new file mode 100644
index 0000000..f070bfa
--- /dev/null
+++ b/scripts/deprecated/israwcommand.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} israwcommand (@var{name})
+## This function is obsolete and will be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function retval = israwcommand ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "israwcommand is obsolete and will be removed from a future version of Octave");
+  endif
+
+  if (nargin == 0)
+    retval = {};
+  else
+    retval = true;
+  endif
+
+endfunction
diff --git a/scripts/deprecated/isstr.m b/scripts/deprecated/isstr.m
new file mode 100644
index 0000000..744d757
--- /dev/null
+++ b/scripts/deprecated/isstr.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isstr (@var{a})
+## This function has been deprecated.  Use ischar instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = isstr (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "isstr is obsolete and will be removed from a future version of Octave, please use ischar instead");
+  endif
+
+  retval = ischar (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/lchol.m b/scripts/deprecated/lchol.m
new file mode 100644
index 0000000..e25ac56
--- /dev/null
+++ b/scripts/deprecated/lchol.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {@var{l} =} lchol (@var{a})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{p}] =} lchol (@var{a})
+## This function has been deprecated.  Use @code{chol (@dots{},'lower')}
+## instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = lchol (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spfind is obsolete and will be removed from a future version of Octave; please use find instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = chol (varargin{:}, "lower");
+
+endfunction
diff --git a/scripts/deprecated/loadimage.m b/scripts/deprecated/loadimage.m
new file mode 100644
index 0000000..52f0684
--- /dev/null
+++ b/scripts/deprecated/loadimage.m
@@ -0,0 +1,44 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{map}] =} loadimage (@var{file})
+## Load an image file and its associated color map from the specified
+## @var{file}.  The image must be stored in Octave's image format.
+## @seealso{saveimage, load, save}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+## Deprecated in version 3.2
+
+function [img_retval, map_retval] = loadimage (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "loadimage is obsolete and will be removed from a future version of Octave; please use imread instead");
+  endif
+
+  [img_retval, map_retval] = imread (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/lognormal_cdf.m b/scripts/deprecated/lognormal_cdf.m
new file mode 100644
index 0000000..31fd6f3
--- /dev/null
+++ b/scripts/deprecated/lognormal_cdf.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lognormal_cdf (@var{x}, @var{a}, @var{v})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the lognormal distribution with
+## parameters @var{a} and @var{v}.  If a random variable follows this
+## distribution, its logarithm is normally distributed with mean
+## @code{log (@var{a})} and variance @var{v}.
+##
+## Default values are @var{a} = 1, @var{v} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the log normal distribution
+
+## Deprecated in version 3.0
+
+function cdf = lognormal_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "lognormal_cdf is obsolete and will be removed from a future version of Octave; please use logncdf instead");
+  endif
+
+  if (nargin > 1)
+    a = varargin{2};
+    idx = a >= 0;
+    a(idx) = log (a(idx));
+    a(!idx) = NaN;
+    varargin{2} = a;
+  endif
+
+  if (nargin > 2)
+    v = varargin{3};
+    idx = v >= 0;
+    v(idx) = sqrt (v(idx));
+    v(!idx) = NaN;
+    varargin{3} = v;
+  endif
+
+  cdf = logncdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/lognormal_inv.m b/scripts/deprecated/lognormal_inv.m
new file mode 100644
index 0000000..68355c7
--- /dev/null
+++ b/scripts/deprecated/lognormal_inv.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lognormal_inv (@var{x}, @var{a}, @var{v})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the lognormal distribution with parameters @var{a}
+## and @var{v}.  If a random variable follows this distribution, its
+## logarithm is normally distributed with mean @code{log (@var{a})} and
+## variance @var{v}.
+##
+## Default values are @var{a} = 1, @var{v} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the log normal distribution
+
+## Deprecated in version 3.0
+
+function inv = lognormal_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "lognormal_inv is obsolete and will be removed from a future version of Octave; please use logninv instead");
+  endif
+
+  if (nargin > 1)
+    a = varargin{2};
+    idx = a >= 0;
+    a(idx) = log (a(idx));
+    a(!idx) = NaN;
+    varargin{2} = a;
+  endif
+
+  if (nargin > 2)
+    v = varargin{3};
+    idx = v >= 0;
+    v(idx) = sqrt (v(idx));
+    v(!idx) = NaN;
+    varargin{3} = v;
+  endif
+
+  inv = logninv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/lognormal_pdf.m b/scripts/deprecated/lognormal_pdf.m
new file mode 100644
index 0000000..d83585f
--- /dev/null
+++ b/scripts/deprecated/lognormal_pdf.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lognormal_pdf (@var{x}, @var{a}, @var{v})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the lognormal distribution with parameters
+## @var{a} and @var{v}.  If a random variable follows this distribution,
+## its logarithm is normally distributed with mean @code{log (@var{a})}
+## and variance @var{v}.
+##
+## Default values are @var{a} = 1, @var{v} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the log normal distribution
+
+## Deprecated in version 3.0
+
+function pdf = lognormal_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "lognormal_pdf is obsolete and will be removed from a future version of Octave; please use lognpdf instead");
+  endif
+
+  if (nargin > 1)
+    a = varargin{2};
+    idx = a >= 0;
+    a(idx) = log (a(idx));
+    a(!idx) = NaN;
+    varargin{2} = a;
+  endif
+
+  if (nargin > 2)
+    v = varargin{3};
+    idx = v >= 0;
+    v(idx) = sqrt (v(idx));
+    v(!idx) = NaN;
+    varargin{3} = v;
+  endif
+
+  pdf = lognpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/lognormal_rnd.m b/scripts/deprecated/lognormal_rnd.m
new file mode 100644
index 0000000..b5127a9
--- /dev/null
+++ b/scripts/deprecated/lognormal_rnd.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lognormal_rnd (@var{a}, @var{v}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} lognormal_rnd (@var{a}, @var{v}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## lognormal distribution with parameters @var{a} and @var{v}.  Both
+## @var{a} and @var{v} must be scalar or of size @var{r} by @var{c}.
+## Or if @var{sz} is a vector, create a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{v}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the log normal distribution
+
+## Deprecated in version 3.0
+
+function rnd = lognormal_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "lognormal_rnd is obsolete and will be removed from a future version of Octave; please use lognrnd instead");
+  endif
+
+  if (nargin > 1)
+    a = varargin{2};
+    idx = a >= 0;
+    a(idx) = log (a(idx));
+    a(!idx) = NaN;
+    varargin{2} = a;
+  endif
+
+  if (nargin > 2)
+    v = varargin{3};
+    idx = v >= 0;
+    v(idx) = sqrt (v(idx));
+    v(!idx) = NaN;
+    varargin{3} = v;
+  endif
+
+ rnd = lognrnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/mark_as_command.m b/scripts/deprecated/mark_as_command.m
new file mode 100644
index 0000000..6552216
--- /dev/null
+++ b/scripts/deprecated/mark_as_command.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} mark_as_command (@var{name})
+## This function is obsolete and will be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function mark_as_command ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "mark_as_command is obsolete and will be removed from a future version of Octave");
+  endif
+
+endfunction
diff --git a/scripts/deprecated/mark_as_rawcommand.m b/scripts/deprecated/mark_as_rawcommand.m
new file mode 100644
index 0000000..0dceaf4
--- /dev/null
+++ b/scripts/deprecated/mark_as_rawcommand.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} mark_as_rawcommand (@var{name})
+## This function is obsolete and will be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function mark_as_rawcommand ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "mark_as_rawcommand is obsolete and will be removed from a future version of Octave");
+  endif
+
+endfunction
diff --git a/scripts/deprecated/meshdom.m b/scripts/deprecated/meshdom.m
new file mode 100644
index 0000000..ac43ef5
--- /dev/null
+++ b/scripts/deprecated/meshdom.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1996, 1997, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} meshdom (@var{x}, @var{y})
+## This function has been deprecated.  Use @code{meshgrid} instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function [xx, yy] = meshdom (x, y)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "meshdom is obsolete and will be removed from a future version of Octave; please use meshgrid instead");
+  endif
+
+  if (nargin == 2)
+    if (isvector (x) && isvector (y))
+      xx = ones (length (y), 1) * x(:).';
+      yy = flipud (y(:)) * ones (1, length (x));
+    else
+      error ("meshdom: arguments must be vectors");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/deprecated/normal_cdf.m b/scripts/deprecated/normal_cdf.m
new file mode 100644
index 0000000..da312d8
--- /dev/null
+++ b/scripts/deprecated/normal_cdf.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normal_cdf (@var{x}, @var{m}, @var{v})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the normal distribution with mean
+## @var{m} and variance @var{v}.
+##
+## Default values are @var{m} = 0, @var{v} = 1.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: CDF of the normal distribution
+
+## Deprecated in version 3.0
+
+function cdf = normal_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "normal_cdf is obsolete and will be removed from a future version of Octave; please use normcdf instead");
+  endif
+
+ if (nargin > 2)
+   varargin{3} = sqrt (varargin{3});
+ endif
+
+ cdf =  normcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/normal_inv.m b/scripts/deprecated/normal_inv.m
new file mode 100644
index 0000000..3a44d2a
--- /dev/null
+++ b/scripts/deprecated/normal_inv.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normal_inv (@var{x}, @var{m}, @var{v})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the normal distribution with mean @var{m} and
+## variance @var{v}.
+##
+## Default values are @var{m} = 0, @var{v} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the normal distribution
+
+## Deprecated in version 3.0
+
+function inv = normal_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "normal_inv is obsolete and will be removed from a future version of Octave; please use norminv instead");
+  endif
+
+ if (nargin > 2)
+   varargin{3} = sqrt (varargin{3});
+ endif
+
+ inv =  norminv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/normal_pdf.m b/scripts/deprecated/normal_pdf.m
new file mode 100644
index 0000000..acee391
--- /dev/null
+++ b/scripts/deprecated/normal_pdf.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normal_pdf (@var{x}, @var{m}, @var{v})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the normal distribution with mean @var{m} and
+## variance @var{v}.
+##
+## Default values are @var{m} = 0, @var{v} = 1.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the normal distribution
+
+## Deprecated in version 3.0
+
+function pdf = normal_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "normal_pdf is obsolete and will be removed from a future version of Octave; please use normpdf instead");
+  endif
+
+ if (nargin > 2)
+   varargin{3} = sqrt (varargin{3});
+ endif
+
+ pdf = normpdf (varargin{:});
+   
+endfunction
diff --git a/scripts/deprecated/normal_rnd.m b/scripts/deprecated/normal_rnd.m
new file mode 100644
index 0000000..42cbd7b
--- /dev/null
+++ b/scripts/deprecated/normal_rnd.m
@@ -0,0 +1,51 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normal_rnd (@var{m}, @var{v}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} normal_rnd (@var{m}, @var{v}, @var{sz})
+## Return an @var{r} by @var{c}  or @code{size (@var{sz})} matrix of
+## random samples from the normal distribution with parameters @var{m} 
+## and @var{v}.  Both @var{m} and @var{v} must be scalar or of size 
+## @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{m} and @var{v}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the normal distribution
+
+## Deprecated in version 3.0
+
+function rnd = normal_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "normal_rnd is obsolete and will be removed from a future version of Octave; please use normrnd instead");
+  endif
+
+ if (nargin > 1)
+   varargin{2} = sqrt (varargin{2});
+ endif
+
+ rnd =  normrnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/pascal_cdf.m b/scripts/deprecated/pascal_cdf.m
new file mode 100644
index 0000000..a52f7b6
--- /dev/null
+++ b/scripts/deprecated/pascal_cdf.m
@@ -0,0 +1,45 @@
+## Copyright (C) 1995, 1996, 1997, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pascal_cdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the CDF at x of the Pascal
+## (negative binomial) distribution with parameters @var{n} and @var{p}.
+##
+## The number of failures in a Bernoulli experiment with success
+## probability @var{p} before the @var{n}-th success follows this
+## distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Pascal (negative binomial) distribution
+
+## Deprecated in version 3.0
+
+function cdf = pascal_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "pascal_cdf is obsolete and will be removed from a future version of Octave; please use nbincdf instead");
+  endif
+
+  cdf = nbincdf(varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/pascal_inv.m b/scripts/deprecated/pascal_inv.m
new file mode 100644
index 0000000..17377c0
--- /dev/null
+++ b/scripts/deprecated/pascal_inv.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pascal_inv (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## Pascal (negative binomial) distribution with parameters @var{n} and
+## @var{p}.
+##
+## The number of failures in a Bernoulli experiment with success
+## probability @var{p} before the @var{n}-th success follows this
+## distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Pascal distribution
+
+## Deprecated in version 3.0
+
+function inv = pascal_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "pascal_inv is obsolete and will be removed from a future version of Octave; please use nbininv instead");
+  endif
+
+  inv = nbininv(varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/pascal_pdf.m b/scripts/deprecated/pascal_pdf.m
new file mode 100644
index 0000000..3fe0554
--- /dev/null
+++ b/scripts/deprecated/pascal_pdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pascal_pdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the Pascal (negative binomial) distribution with
+## parameters @var{n} and @var{p}.
+##
+## The number of failures in a Bernoulli experiment with success
+## probability @var{p} before the @var{n}-th success follows this
+## distribution. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Pascal (negative binomial) distribution
+
+## Deprecated in version 3.0
+
+function pdf = pascal_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "pascal_pdf is obsolete and will be removed from a future version of Octave; please use nbinpdf instead");
+  endif
+
+  pdf = nbinpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/pascal_rnd.m b/scripts/deprecated/pascal_rnd.m
new file mode 100644
index 0000000..7115e61
--- /dev/null
+++ b/scripts/deprecated/pascal_rnd.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pascal_rnd (@var{n}, @var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} pascal_rnd (@var{n}, @var{p}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the Pascal
+## (negative binomial) distribution with parameters @var{n} and @var{p}.
+## Both @var{n} and @var{p} must be scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{n} and @var{p}.  Or if @var{sz} is a vector, 
+## create a matrix of size @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Pascal distribution
+
+## Deprecated in version 3.0
+
+function rnd = pascal_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "pascal_rnd is obsolete and will be removed from a future version of Octave; please use nbinrnd instead");
+  endif
+
+  rnd = nbinrnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/poisson_cdf.m b/scripts/deprecated/poisson_cdf.m
new file mode 100644
index 0000000..899c635
--- /dev/null
+++ b/scripts/deprecated/poisson_cdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poisson_cdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the Poisson distribution with parameter
+## lambda.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Poisson distribution
+
+## Deprecated in version 3.0
+
+function cdf = poisson_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "poisson_cdf is obsolete and will be removed from a future version of Octave; please use poisscdf instead");
+  endif
+
+ cdf =  poisscdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/poisson_inv.m b/scripts/deprecated/poisson_inv.m
new file mode 100644
index 0000000..96eb5b7
--- /dev/null
+++ b/scripts/deprecated/poisson_inv.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poisson_inv (@var{x}, @var{lambda})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the Poisson distribution with parameter
+## @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Poisson distribution
+
+## Deprecated in version 3.0
+
+function inv = poisson_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "poisson_inv is obsolete and will be removed from a future version of Octave; please use poissinv instead");
+  endif
+
+ inv =  poissinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/poisson_pdf.m b/scripts/deprecated/poisson_pdf.m
new file mode 100644
index 0000000..3e98b97
--- /dev/null
+++ b/scripts/deprecated/poisson_pdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poisson_pdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the poisson distribution with parameter @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Poisson distribution
+
+## Deprecated in version 3.0
+
+function pdf = poisson_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "poisson_pdf is obsolete and will be removed from a future version of Octave; please use poisspdf instead");
+  endif
+
+ pdf =  poisspdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/poisson_rnd.m b/scripts/deprecated/poisson_rnd.m
new file mode 100644
index 0000000..3df9198
--- /dev/null
+++ b/scripts/deprecated/poisson_rnd.m
@@ -0,0 +1,45 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poisson_rnd (@var{lambda}, @var{r}, @var{c})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## Poisson distribution with parameter @var{lambda}, which must be a 
+## scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Poisson distribution
+
+## Deprecated in version 3.0
+
+function rnd = poisson_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "poisson_rnd is obsolete and will be removed from a future version of Octave; please use poissrnd instead");
+  endif
+
+ rnd =  poissrnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/polyinteg.m b/scripts/deprecated/polyinteg.m
new file mode 100644
index 0000000..40488dd
--- /dev/null
+++ b/scripts/deprecated/polyinteg.m
@@ -0,0 +1,55 @@
+## Copyright (C) 1996, 1997, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyinteg (@var{c})
+## Return the coefficients of the integral of the polynomial whose
+## coefficients are represented by the vector @var{c}.
+##
+## The constant of integration is set to zero.
+## @seealso{polyint, poly, polyderiv, polyreduce, roots, conv, deconv, residue,
+## filter, polyval, polyvalm}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+## Deprecated in version 3.0
+
+function y = polyinteg (p)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "polyinteg is obsolete and will be removed from a future version of Octave; please use polyint instead");
+  endif
+
+  y = polyint (p);
+
+endfunction
+
+%!assert(all (all (polyinteg ([2, 2]) == [1, 2, 0])));
+
+%!assert(isempty (polyinteg ([])));
+
+%!assert(all (all (polyinteg (3) == [3, 0])));
+
+%!error polyinteg ([1, 2; 3, 4]);
+
diff --git a/scripts/deprecated/setstr.m b/scripts/deprecated/setstr.m
new file mode 100644
index 0000000..4dca2fc
--- /dev/null
+++ b/scripts/deprecated/setstr.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} setstr (@var{s})
+## This function has been deprecated.  Use char instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = setstr (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "setstr is obsolete and will be removed from a future version of Octave; please use char instead");
+  endif
+
+  retval = char (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spatan2.m b/scripts/deprecated/spatan2.m
new file mode 100644
index 0000000..3da19f7
--- /dev/null
+++ b/scripts/deprecated/spatan2.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spatan2 (@var{y}, @var{x})
+## This function has been deprecated.  Use @code{atan2} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spatan2 (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spatan2 is obsolete and will be removed from a future version of Octave; please use atan2 instead");
+  endif
+
+  retval = atan2 (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spchol.m b/scripts/deprecated/spchol.m
new file mode 100644
index 0000000..ccc51eb
--- /dev/null
+++ b/scripts/deprecated/spchol.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {@var{r} =} spchol (@var{a})
+## @deftypefnx {Loadable Function} {[@var{r}, @var{p}] =} spchol (@var{a})
+## @deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} spchol (@var{a})
+## This function has been deprecated.  Use @code{chol} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spchol (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spchol is obsolete and will be removed from a future version of Octave; please use chol instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = chol (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spchol2inv.m b/scripts/deprecated/spchol2inv.m
new file mode 100644
index 0000000..0515fa2
--- /dev/null
+++ b/scripts/deprecated/spchol2inv.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spchol2inv (@var{u})
+## This function has been deprecated.  Use @code{chol2inv} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spchol2inv (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spchol2inv is obsolete and will be removed from a future version of Octave; please use chol2inv instead");
+  endif
+
+  retval = chol2inv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spcholinv.m b/scripts/deprecated/spcholinv.m
new file mode 100644
index 0000000..4b7888e
--- /dev/null
+++ b/scripts/deprecated/spcholinv.m
@@ -0,0 +1,35 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spcholinv (@var{u})
+## This function has been deprecated.  Use @code{cholinv} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spcholinv (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spcholinv is obsolete and will be removed from a future version of Octave; please use cholinv instead");
+  endif
+  retval = cholinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spcumprod.m b/scripts/deprecated/spcumprod.m
new file mode 100644
index 0000000..111caf1
--- /dev/null
+++ b/scripts/deprecated/spcumprod.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spcumprod (@var{x}, @var{dim})
+## This function has been deprecated.  Use @code{cumprod} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spcumprod (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spcumprod is obsolete and will be removed from a future version of Octave; please use cumprod instead");
+  endif
+
+  retval = cumprod (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spcumsum.m b/scripts/deprecated/spcumsum.m
new file mode 100644
index 0000000..97ded1d
--- /dev/null
+++ b/scripts/deprecated/spcumsum.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spcumsum (@var{x}, @var{dim})
+## This function has been deprecated.  Use @code{cumsum} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spcumsum (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spcumsum is obsolete and will be removed from a future version of Octave; please use cumsum instead");
+  endif
+
+  retval = cumsum (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spdet.m b/scripts/deprecated/spdet.m
new file mode 100644
index 0000000..c07c0a7
--- /dev/null
+++ b/scripts/deprecated/spdet.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {[@var{d}, @var{rcond}] =} spdet (@var{a})
+## This function has been deprecated.  Use @code{det} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spdet (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spdet is obsolete and will be removed from a future version of Octave; please use det instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = det (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spdiag.m b/scripts/deprecated/spdiag.m
new file mode 100644
index 0000000..da34504
--- /dev/null
+++ b/scripts/deprecated/spdiag.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spdiag (@var{v}, @var{k})
+## This function has been deprecated.  Use @code{sparse (diag (@dots{}))} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spdiag (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spdiag is obsolete and will be removed from a future version of Octave; please use sparse (diag (...)) instead");
+  endif
+
+  retval = sparse (diag (varargin{:}));
+
+endfunction
diff --git a/scripts/deprecated/spfind.m b/scripts/deprecated/spfind.m
new file mode 100644
index 0000000..89cc099
--- /dev/null
+++ b/scripts/deprecated/spfind.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {} spfind (@var{x})
+## @deftypefnx {Loadable Function} {} spfind (@var{x}, @var{n})
+## @deftypefnx {Loadable Function} {} spfind (@var{x}, @var{n}, @var{direction})
+## @deftypefnx {Loadable Function} {[@var{i}, @var{j}, @var{v}} spfind (@dots{})
+## This function has been deprecated.  Use @code{find} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spfind (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spfind is obsolete and will be removed from a future version of Octave; please use find instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = find (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spinv.m b/scripts/deprecated/spinv.m
new file mode 100644
index 0000000..b896d7f
--- /dev/null
+++ b/scripts/deprecated/spinv.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{rcond}] =} spinv (@var{a})
+## This function has been deprecated.  Use @code{inv} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spinv (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spinv is obsolete and will be removed from a future version of Octave; please use inv instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = inv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spkron.m b/scripts/deprecated/spkron.m
new file mode 100644
index 0000000..d37ebf3
--- /dev/null
+++ b/scripts/deprecated/spkron.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spkron (@var{a}, @var{b})
+## This function has been deprecated.  Use @code{kron} instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function retval = spkron (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spkron is obsolete and will be removed from a future version of Octave; please use kron instead");
+  endif
+
+  retval = kron (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/splchol.m b/scripts/deprecated/splchol.m
new file mode 100644
index 0000000..5afd144
--- /dev/null
+++ b/scripts/deprecated/splchol.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {@var{l} =} splchol (@var{a})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{p}] =} splchol (@var{a})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{p}, @var{q}] =} splchol (@var{a})
+## This function has been deprecated.  Use @code{chol (@dots{},'lower')}
+## instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = splchol (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "splchol is obsolete and will be removed from a future version of Octave; please use chol instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = chol (varargin{:}, "lower");
+
+endfunction
diff --git a/scripts/deprecated/split.m b/scripts/deprecated/split.m
new file mode 100644
index 0000000..dfc1b56
--- /dev/null
+++ b/scripts/deprecated/split.m
@@ -0,0 +1,130 @@
+## Copyright (C) 1996, 1999, 2000, 2005, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} split (@var{s}, @var{t}, @var{n})
+## This function has been deprecated.  Use @code{char (strsplit (s, t))}
+## instead.
+## @end deftypefn
+
+## Divides the string @var{s} into pieces separated by @var{t}, returning
+## the result in a string array (padded with blanks to form a valid
+## matrix).  If the optional input @var{n} is supplied, split @var{s}
+## into at most @var{n} different pieces.
+##
+## For example,
+##
+## @example
+## split ("Test string", "t")
+##      @result{}
+##         "Tes "
+##         " s  "
+##         "ring"
+## @end example
+##
+## @example
+## split ("Test string", "t s", 2)
+##      @result{}
+##         "Tes  "
+##         "tring"
+## @end example
+## @seealso{strtok, index}
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+## Deprecated in version 3.2
+
+function m = split (s, t, n)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "split is obsolete and will be removed from a future version of Octave; please use strsplit instead");
+  endif
+
+  if (nargin == 2 || nargin == 3)
+    if (nargin == 2)
+      n = length (s);
+    endif
+
+    if (ischar (s) && ischar (t))
+
+      l_s = length (s);
+      l_t = length (t);
+
+      if (l_s == 0)
+	m = "";
+	return;
+      elseif (l_t == 0)
+	m = s';
+	return;
+      elseif (l_s < l_t)
+	error ("split: s must not be shorter than t");
+      endif
+
+      if (min (size (s)) != 1 || min (size (t)) != 1)
+	error("split: multi-line strings are not supported");
+      endif
+
+      ind = findstr (s, t, 0);
+      if (length (ind) == 0)
+	m = s;
+	return;
+      elseif (n - 1 < length(ind))
+	ind = ind(1:n-1);
+      endif
+      ind2 = [1, ind+l_t];
+      ind  = [ind, l_s+1];
+
+      ind_diff = ind-ind2;
+
+      ## Create a matrix of the correct size that's filled with spaces.
+      m_rows = length (ind);
+      m_cols = max (ind_diff);
+      m = repmat (" ", m_rows, m_cols);
+
+      ## Copy the strings to the matrix.
+      for i = 1:length (ind)
+	tmp = ind2(i):(ind(i)-1);
+	m(i,1:length(tmp)) = s(tmp);
+      endfor
+    else
+      error ("split: both s and t must be strings");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(all (all (split ("Test string", "t") == ["Tes "; " s  "; "ring"])));
+
+%!error split ();
+
+%!assert(all (strcmp (split ("foo bar baz", " ", 2), ["foo"; "bar baz"])));
+
+%!error split ("foo", "bar", 3, 4);
+
+%!assert (all (strcmp (split("road//to/hell","/"), ["road"; "    "; "to  "; "hell"])))
+
+%!assert (all (strcmp (split("/road/to/hell/","/"), ["    "; "road"; "to  "; "hell"; "    "])))
+
+
diff --git a/scripts/deprecated/splu.m b/scripts/deprecated/splu.m
new file mode 100644
index 0000000..c8c5af6
--- /dev/null
+++ b/scripts/deprecated/splu.m
@@ -0,0 +1,48 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {[@var{l}, @var{u}] =} splu (@var{a})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}] =} splu (@var{a})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}, @var{Q}] =} splu (@var{a})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}, @var{Q}] =} splu (@dots{}, @var{thres})
+## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}] =} splu (@dots{}, @var{Q})
+## This function has been deprecated.  Use @code{lu} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = splu (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "splu is obsolete and will be removed from a future version of Octave; please use lu instead");
+  endif
+
+  for i = 2 : nargin
+    arg = varargin {i};
+    if (! isscalar (arg))
+      error ("splu: Can no longer treat input column permutations");
+    endif
+  endfor
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = lu (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spmax.m b/scripts/deprecated/spmax.m
new file mode 100644
index 0000000..58c334c
--- /dev/null
+++ b/scripts/deprecated/spmax.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} spmax (@var{x}, @var{y}, @var{dim})
+## @deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmax (@var{x})
+## This function has been deprecated.  Use @code{max} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spmax (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spmax is obsolete and will be removed from a future version of Octave; please use max instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = max (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spmin.m b/scripts/deprecated/spmin.m
new file mode 100644
index 0000000..398bd6e
--- /dev/null
+++ b/scripts/deprecated/spmin.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} spmin (@var{x}, @var{y}, @var{dim})
+## @deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmin (@var{x})
+## This function has been deprecated.  Use @code{min} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spmin (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spmin is obsolete and will be removed from a future version of Octave; please use min instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = min (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spprod.m b/scripts/deprecated/spprod.m
new file mode 100644
index 0000000..b44a770
--- /dev/null
+++ b/scripts/deprecated/spprod.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spprod (@var{x}, @var{dim})
+## This function has been deprecated.  Use @code{prod} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spprod (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spprod is obsolete and will be removed from a future version of Octave; please use prod instead");
+  endif
+
+  retval = prod (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spqr.m b/scripts/deprecated/spqr.m
new file mode 100644
index 0000000..24b9b10
--- /dev/null
+++ b/scripts/deprecated/spqr.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {@var{r} =} spqr (@var{a})
+## @deftypefnx {Loadable Function} {@var{r} =} spqr (@var{a},0)
+## @deftypefnx {Loadable Function} {[@var{c}, @var{r}] =} spqr (@var{a}, at var{b})
+## @deftypefnx {Loadable Function} {[@var{c}, @var{r}] =} spqr (@var{a}, at var{b},0)
+## This function has been deprecated.  Use @code{qr} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function varargout = spqr (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spqr is obsolete and will be removed from a future version of Octave; please use qr instead");
+  endif
+
+  varargout = cell (nargout, 1);
+  [ varargout{:} ] = qr (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spsum.m b/scripts/deprecated/spsum.m
new file mode 100644
index 0000000..2d4e38b
--- /dev/null
+++ b/scripts/deprecated/spsum.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spsum (@var{x}, @var{dim})
+## This function has been deprecated.  Use @code{sum} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spsum (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spsum is obsolete and will be removed from a future version of Octave; please use sum instead");
+  endif
+
+  retval = sum (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/spsumsq.m b/scripts/deprecated/spsumsq.m
new file mode 100644
index 0000000..0c12f5d
--- /dev/null
+++ b/scripts/deprecated/spsumsq.m
@@ -0,0 +1,35 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spsumsq (@var{x}, @var{dim})
+## This function has been deprecated.  Use @code{sumsq} instead.
+## @end deftypefn
+
+## Deprecated in version 3.2
+
+function retval = spsumsq (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+	     "spsumsq is obsolete and will be removed from a future version of Octave; please use sumsq instead");
+  endif
+  retval = sumsq (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/str2mat.m b/scripts/deprecated/str2mat.m
new file mode 100644
index 0000000..d6be434
--- /dev/null
+++ b/scripts/deprecated/str2mat.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1996, 1998, 1999, 2000, 2002, 2004, 2005, 2006, 2007,
+##               2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} str2mat (@var{s_1}, @dots{}, @var{s_n})
+## Return a matrix containing the strings @var{s_1}, @dots{}, @var{s_n} as
+## its rows.  Each string is padded with blanks in order to form a valid
+## matrix.
+##
+## This function is modelled after @sc{matlab}.  In Octave, you can create
+## a matrix of strings by @code{[@var{s_1}; @dots{}; @var{s_n}]} even if
+## the strings are not all the same length.
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+## Deprecated in version 3.2
+
+function retval = str2mat (varargin)
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "str2mat is obsolete and will be removed from a future version of Octave; please use char instead.");
+  endif
+
+  retval = char (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/struct_contains.m b/scripts/deprecated/struct_contains.m
new file mode 100644
index 0000000..1372ce0
--- /dev/null
+++ b/scripts/deprecated/struct_contains.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} struct_contains (@var{expr}, @var{name})
+## This function has been deprecated.  Use isfield instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = struct_contains (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "struct_contains is obsolete and will be removed from a future version of Octave; please use isfield instead");
+  endif
+
+  retval = isfield (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/struct_elements.m b/scripts/deprecated/struct_elements.m
new file mode 100644
index 0000000..0062e01
--- /dev/null
+++ b/scripts/deprecated/struct_elements.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} struct_elements (@var{struct})
+## This function has been deprecated.  Use fieldnames instead.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.0
+
+function retval = struct_elements (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "struct_elements is obsolete and will be removed from a future version of Octave; please use fieldnames instead");
+  endif
+
+  retval = char (fieldnames (varargin{:}));
+
+endfunction
diff --git a/scripts/deprecated/t_cdf.m b/scripts/deprecated/t_cdf.m
new file mode 100644
index 0000000..73ad034
--- /dev/null
+++ b/scripts/deprecated/t_cdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} t_cdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the CDF at @var{x} of the
+## t (Student) distribution with @var{n} degrees of freedom, i.e.,
+## PROB (t(@var{n}) <= @var{x}).
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the t distribution
+
+## Deprecated in version 3.0
+
+function cdf = t_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "t_cdf is obsolete and will be removed from a future version of Octave; please use tcdf instead");
+  endif
+
+ cdf =  tcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/t_inv.m b/scripts/deprecated/t_inv.m
new file mode 100644
index 0000000..f5671ff
--- /dev/null
+++ b/scripts/deprecated/t_inv.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} t_inv (@var{x}, @var{n})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the t (Student) distribution with parameter
+## @var{n}.
+## @end deftypefn
+
+## For very large n, the "correct" formula does not really work well,
+## and the quantiles of the standard normal distribution are used
+## directly.
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the t distribution
+
+## Deprecated in version 3.0
+
+function inv = t_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "t_inv is obsolete and will be removed from a future version of Octave; please use tinv instead");
+  endif
+
+ inv =  tinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/t_pdf.m b/scripts/deprecated/t_pdf.m
new file mode 100644
index 0000000..d4cc683
--- /dev/null
+++ b/scripts/deprecated/t_pdf.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} t_pdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the @var{t} (Student) distribution with @var{n}
+## degrees of freedom. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the t distribution
+
+## Deprecated in version 3.0
+
+function pdf = t_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "t_pdf is obsolete and will be removed from a future version of Octave; please use tpdf instead");
+  endif
+
+ pdf =  tpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/t_rnd.m b/scripts/deprecated/t_rnd.m
new file mode 100644
index 0000000..94e2925
--- /dev/null
+++ b/scripts/deprecated/t_rnd.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} t_rnd (@var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} t_rnd (@var{n}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the t
+## (Student) distribution with @var{n} degrees of freedom.  @var{n} must
+## be a scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a
+## vector create a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the t distribution
+
+## Deprecated in version 3.0
+
+function rnd = t_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "t_rnd is obsolete and will be removed from a future version of Octave; please use trnd instead");
+  endif
+
+ rnd =  trnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/uniform_cdf.m b/scripts/deprecated/uniform_cdf.m
new file mode 100644
index 0000000..6f3bfdf
--- /dev/null
+++ b/scripts/deprecated/uniform_cdf.m
@@ -0,0 +1,43 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} uniform_cdf (@var{x}, @var{a}, @var{b})
+## Return the CDF at @var{x} of the uniform distribution on [@var{a},
+## @var{b}], i.e., PROB (uniform (@var{a}, @var{b}) <= x).
+##
+## Default values are @var{a} = 0, @var{b} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the uniform distribution
+
+## Deprecated in version 3.0
+
+function cdf = uniform_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "uniform_cdf is obsolete and will be removed from a future version of Octave; please use unifcdf instead");
+  endif
+
+ cdf =  unifcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/uniform_inv.m b/scripts/deprecated/uniform_inv.m
new file mode 100644
index 0000000..5e52dd4
--- /dev/null
+++ b/scripts/deprecated/uniform_inv.m
@@ -0,0 +1,43 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} uniform_inv (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the uniform distribution on [@var{a}, @var{b}].
+##
+## Default values are @var{a} = 0, @var{b} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the uniform distribution
+
+## Deprecated in version 3.0
+
+function inv = uniform_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "uniform_inv is obsolete and will be removed from a future version of Octave; please use unifinv instead");
+  endif
+
+ inv =  unifinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/uniform_pdf.m b/scripts/deprecated/uniform_pdf.m
new file mode 100644
index 0000000..c210783
--- /dev/null
+++ b/scripts/deprecated/uniform_pdf.m
@@ -0,0 +1,43 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} uniform_pdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, compute the PDF at @var{x} of the uniform
+## distribution on [@var{a}, @var{b}].
+##
+## Default values are @var{a} = 0, @var{b} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the uniform distribution
+
+## Deprecated in version 3.0
+
+function pdf = uniform_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "uniform_pdf is obsolete and will be removed from a future version of Octave; please use unifpdf instead");
+  endif
+
+ pdf =  unifpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/uniform_rnd.m b/scripts/deprecated/uniform_rnd.m
new file mode 100644
index 0000000..604dc53
--- /dev/null
+++ b/scripts/deprecated/uniform_rnd.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} uniform_rnd (@var{a}, @var{b}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} uniform_rnd (@var{a}, @var{b}, @var{sz})
+## Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+## random samples from the uniform distribution on [@var{a}, @var{b}]. 
+## Both @var{a} and @var{b} must be scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the uniform distribution
+
+## Deprecated in version 3.0
+
+function rnd = uniform_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "uniform_rnd is obsolete and will be removed from a future version of Octave; please use unifrnd instead");
+  endif
+
+ rnd =  unifrnd (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/unmark_command.m b/scripts/deprecated/unmark_command.m
new file mode 100644
index 0000000..6324781
--- /dev/null
+++ b/scripts/deprecated/unmark_command.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} unmark_command (@var{name})
+## This function is obsolete and will be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function unmark_command ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "unmark_command is obsolete and will be removed from a future version of Octave");
+  endif
+
+endfunction
diff --git a/scripts/deprecated/unmark_rawcommand.m b/scripts/deprecated/unmark_rawcommand.m
new file mode 100644
index 0000000..c41dc64
--- /dev/null
+++ b/scripts/deprecated/unmark_rawcommand.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} unmark_rawcommand (@var{name})
+## This function is obsolete and will be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in version 3.2
+
+function unmark_rawcommand ()
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "unmark_rawcommand is obsolete and will be removed from a future version of Octave");
+  endif
+
+endfunction
diff --git a/scripts/deprecated/weibcdf.m b/scripts/deprecated/weibcdf.m
new file mode 100644
index 0000000..ecdd1e7
--- /dev/null
+++ b/scripts/deprecated/weibcdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibcdf (@var{x}, @var{scale}, @var{shape})
+## Compute the cumulative distribution function (CDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape}, which is
+##
+## @example
+## 1 - exp(-(x/shape)^scale)
+## @end example
+##
+## @noindent
+## for @var{x} >= 0.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function cdf = weibcdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibcdf is obsolete and will be removed from a future version of Octave; please use wblcdf instead");
+  endif
+
+  cdf = wblcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/weibinv.m b/scripts/deprecated/weibinv.m
new file mode 100644
index 0000000..b678deb
--- /dev/null
+++ b/scripts/deprecated/weibinv.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibinv (@var{x}, @var{scale}, @var{shape})
+## Compute the quantile (the inverse of the CDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape}.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function inv = weibinv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibinv is obsolete and will be removed from a future version of Octave; please use wblinv instead");
+  endif
+
+  inv = wblinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/weibpdf.m b/scripts/deprecated/weibpdf.m
new file mode 100644
index 0000000..b7b6697
--- /dev/null
+++ b/scripts/deprecated/weibpdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibpdf (@var{x}, @var{scale}, @var{shape})
+## Compute the probability density function (PDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape} which is given by
+##
+## @example
+##    scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+## @end example
+##
+## @noindent
+## for @var{x} > 0.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function pdf = weibpdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibpdf is obsolete and will be removed from a future version of Octave; please use wblpdf instead");
+  endif
+
+  pdf = wblpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/weibrnd.m b/scripts/deprecated/weibrnd.m
new file mode 100644
index 0000000..ee4ac06
--- /dev/null
+++ b/scripts/deprecated/weibrnd.m
@@ -0,0 +1,45 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibrnd (@var{scale}, @var{shape}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} weibrnd (@var{scale}, @var{shape}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## Weibull distribution with parameters @var{scale} and @var{shape}
+## which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+## is a vector return a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{alpha} and @var{sigma}.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function rnd = weibrnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibrnd is obsolete and will be removed from a future version of Octave; please use wblrnd instead");
+  endif
+
+  rnd = wblrnd (varargin{:});
+
+endfunction
+
diff --git a/scripts/deprecated/weibull_cdf.m b/scripts/deprecated/weibull_cdf.m
new file mode 100644
index 0000000..8efbd3a
--- /dev/null
+++ b/scripts/deprecated/weibull_cdf.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibull_cdf (@var{x}, @var{shape}, @var{scale})
+## Compute the cumulative distribution function (CDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape}, which is
+##
+## @example
+## 1 - exp(-(x/shape)^scale)
+## @end example
+##
+## @noindent
+## for @var{x} >= 0.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function cdf = weibull_cdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibull_cdf is obsolete and will be removed from a future version of Octave; please use wblcdf instead");
+  endif
+
+  if (nargin == 2)
+    varargin{3} = varargin{2};
+    varargin{2} = 1;
+  elseif (nargin > 2)
+    tmp = varargin{3};
+    varargin{3} = varargin{2};
+    varargin{2} = tmp;
+  endif
+
+  cdf = wblcdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/weibull_inv.m b/scripts/deprecated/weibull_inv.m
new file mode 100644
index 0000000..5ecbfaf
--- /dev/null
+++ b/scripts/deprecated/weibull_inv.m
@@ -0,0 +1,48 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibull_inv (@var{x}, @var{shape}, @var{scale})
+## Compute the quantile (the inverse of the CDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape}.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function inv = weibull_inv (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibull_inv is obsolete and will be removed from a future version of Octave; please use wblinv instead");
+  endif
+
+  if (nargin == 2)
+    varargin{3} = varargin{2};
+    varargin{2} = 1;
+  elseif (nargin > 2)
+    tmp = varargin{3};
+    varargin{3} = varargin{2};
+    varargin{2} = tmp;
+  endif
+
+  inv = wblinv (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/weibull_pdf.m b/scripts/deprecated/weibull_pdf.m
new file mode 100644
index 0000000..116293e
--- /dev/null
+++ b/scripts/deprecated/weibull_pdf.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibull_pdf (@var{x}, @var{shape}, @var{scale})
+## Compute the probability density function (PDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape} which is given by
+##
+## @example
+##    scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+## @end example
+##
+## @noindent
+## for @var{x} > 0.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function pdf = weibull_pdf (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibull_pdf is obsolete and will be removed from a future version of Octave; please use wblpdf instead");
+  endif
+
+  if (nargin == 2)
+    varargin{3} = varargin{2};
+    varargin{2} = 1;
+  elseif (nargin > 2)
+    tmp = varargin{3};
+    varargin{3} = varargin{2};
+    varargin{2} = tmp;
+  endif
+
+  pdf = wblpdf (varargin{:});
+
+endfunction
diff --git a/scripts/deprecated/weibull_rnd.m b/scripts/deprecated/weibull_rnd.m
new file mode 100644
index 0000000..9c5d64d
--- /dev/null
+++ b/scripts/deprecated/weibull_rnd.m
@@ -0,0 +1,51 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} weibull_rnd (@var{shape}, @var{scale}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} weibull_rnd (@var{shape}, @var{scale}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## Weibull distribution with parameters @var{scale} and @var{shape}
+## which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+## is a vector return a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{alpha} and @var{sigma}.
+## @end deftypefn
+
+## Deprecated in version 3.0
+
+function rnd = weibull_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "weibull_rnd is obsolete and will be removed from a future version of Octave; please use wblrnd instead");
+  endif
+
+  if (nargin > 1)
+    tmp = varargin{2};
+    varargin{2} = varargin{1};
+    varargin{1} = tmp;
+  endif
+
+  rnd = wblrnd (varargin{:});
+
+endfunction
+
diff --git a/scripts/deprecated/wiener_rnd.m b/scripts/deprecated/wiener_rnd.m
new file mode 100644
index 0000000..346f356
--- /dev/null
+++ b/scripts/deprecated/wiener_rnd.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2007, 2008, 2009 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wiener_rnd (@var{t}, @var{d}, @var{n})
+## Return a simulated realization of the @var{d}-dimensional Wiener Process
+## on the interval [0, @var{t}].  If @var{d} is omitted, @var{d} = 1 is
+## used.  The first column of the return matrix contains time, the
+## remaining columns contain the Wiener process.
+##
+## The optional parameter @var{n} gives the number of summands used for
+## simulating the process over an interval of length 1.  If @var{n} is
+## omitted, @var{n} = 1000 is used.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Simulate a Wiener process
+
+## Deprecated in version 3.0
+
+function retval = wiener_rnd (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "wiener_rnd is obsolete and will be removed from a future version of Octave; please use wienrnd instead");
+  endif
+
+ retval =  wienrnd (varargin{:});
+
+endfunction
diff --git a/scripts/elfun/Makefile.in b/scripts/elfun/Makefile.in
new file mode 100644
index 0000000..673931c
--- /dev/null
+++ b/scripts/elfun/Makefile.in
@@ -0,0 +1,87 @@
+# Makefile for octave's scripts/elfun directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = elfun
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = acosd.m acot.m acotd.m acoth.m acsc.m acscd.m \
+  acsch.m asec.m asecd.m asech.m asind.m atand.m cosd.m \
+  cot.m cotd.m coth.m csc.m cscd.m csch.m lcm.m sec.m secd.m \
+  sech.m sind.m tand.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/elfun
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/elfun/acosd.m b/scripts/elfun/acosd.m
new file mode 100644
index 0000000..4a4fd1b
--- /dev/null
+++ b/scripts/elfun/acosd.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} acosd (@var{x})
+## Compute the inverse cosine in degrees for each element of @var{x}.
+## @seealso{cosd, acos}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = acosd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = acos(x) .* 180 ./ pi;
+endfunction
+
+%!error(acosd())
+%!error(acosd(1,2))
+%!assert(acosd(0:0.1:1),180/pi*acos(0:0.1:1),-10*eps)
diff --git a/scripts/elfun/acot.m b/scripts/elfun/acot.m
new file mode 100644
index 0000000..d9c9842
--- /dev/null
+++ b/scripts/elfun/acot.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} acot (@var{x})
+## Compute the inverse cotangent in radians for each element of @var{x}.
+## @seealso{cot, acotd}
+## @end deftypefn
+
+## Author: jwe
+
+function w = acot (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = atan (1./z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [rt3, 1, rt3/3, 0, -rt3/3, -1, -rt3];
+%! v = [pi/6, pi/4, pi/3, pi/2, -pi/3, -pi/4, -pi/6];
+%! assert(all (abs (acot (x) - v) < sqrt (eps)));
+
+%!error acot ();
+
+%!error acot (1, 2);
+
diff --git a/scripts/elfun/acotd.m b/scripts/elfun/acotd.m
new file mode 100644
index 0000000..9ad16f7
--- /dev/null
+++ b/scripts/elfun/acotd.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} acotd (@var{x})
+## Compute the inverse cotangent in degrees for each element of @var{x}.
+## @seealso{cotd, acot}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = acotd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = atand (1 ./ x);
+endfunction
+
+%!error(acotd())
+%!error(acotd(1,2))
+%!assert(acotd(0:10:90),180./pi.*acot(0:10:90),-10*eps)
diff --git a/scripts/elfun/acoth.m b/scripts/elfun/acoth.m
new file mode 100644
index 0000000..133662e
--- /dev/null
+++ b/scripts/elfun/acoth.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1996, 1997, 2000, 2004, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} acoth (@var{x})
+## Compute the inverse hyperbolic cotangent of each element of @var{x}.
+## @seealso{coth}
+## @end deftypefn
+
+## Author: jwe
+
+function w = acoth (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = atanh (1 ./ z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = -i*[pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6];
+%! x = i*[rt3, 1, rt3/3, -rt3/3, -1, -rt3];
+%! assert(all (abs (acoth (x) - v) < sqrt (eps)));
+
+%!error acoth ();
+
+%!error acoth (1, 2);
+
diff --git a/scripts/elfun/acsc.m b/scripts/elfun/acsc.m
new file mode 100644
index 0000000..b1153f2
--- /dev/null
+++ b/scripts/elfun/acsc.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} acsc (@var{x})
+## Compute the inverse cosecant in radians for each element of @var{x}.
+## @seealso{csc, acscd}
+## @end deftypefn
+
+## Author: jwe
+
+function w = acsc (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = asin (1 ./ z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = [pi/6, pi/4, pi/3, pi/2, pi/3, pi/4, pi/6];
+%! x = [2, rt2, 2*rt3/3, 1, 2*rt3/3, rt2, 2];
+%! assert(all (abs (acsc (x) - v) < sqrt (eps)));
+
+%!error acsc ();
+
+%!error acsc (1, 2);
+
diff --git a/scripts/elfun/acscd.m b/scripts/elfun/acscd.m
new file mode 100644
index 0000000..ea2102f
--- /dev/null
+++ b/scripts/elfun/acscd.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} acscd (@var{x})
+## Compute the inverse cosecant in degrees for each element of @var{x}.
+## @seealso{cscd, acsc}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = acscd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = acsc(x) .* 180 ./ pi;
+endfunction
+
+%!error(acscd())
+%!error(acscd(1,2))
+%!assert(acscd(0:10:90),180/pi*acsc(0:10:90),-10*eps)
diff --git a/scripts/elfun/acsch.m b/scripts/elfun/acsch.m
new file mode 100644
index 0000000..0885a23
--- /dev/null
+++ b/scripts/elfun/acsch.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} acsch (@var{x})
+## Compute the inverse hyperbolic cosecant of each element of @var{x}.
+## @seealso{csch}
+## @end deftypefn
+
+## Author: jwe
+
+function w = acsch (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = asinh (1 ./ z);
+
+endfunction
+
+%!test
+%! v = [pi/2*i, -pi/2*i];
+%! x = [-i, i];
+%! assert(all (abs (acsch (x) - v) < sqrt (eps)));
+
+%!error acsch ();
+
+%!error acsch (1, 2);
+
diff --git a/scripts/elfun/asec.m b/scripts/elfun/asec.m
new file mode 100644
index 0000000..76be35c
--- /dev/null
+++ b/scripts/elfun/asec.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} asec (@var{x})
+## Compute the inverse secant in radians for each element of @var{x}.
+## @seealso{sec, asecd}
+## @end deftypefn
+
+## Author: jwe
+
+function w = asec (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = acos (1 ./ z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = [0, pi/6, pi/4, pi/3, 2*pi/3, 3*pi/4, 5*pi/6, pi];
+%! x = [1, 2*rt3/3, rt2, 2, -2, -rt2, -2*rt3/3, -1];
+%! assert(all (abs (asec (x) - v) < sqrt (eps)));
+
+%!error asec ();
+
+%!error asec (1, 2);
diff --git a/scripts/elfun/asecd.m b/scripts/elfun/asecd.m
new file mode 100644
index 0000000..726ad3c
--- /dev/null
+++ b/scripts/elfun/asecd.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} asecd (@var{x})
+## Compute the inverse secant in degrees for each element of @var{x}.
+## @seealso{secd, asec}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = asecd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = asec (x) .* 180 ./ pi;
+endfunction;
+
+%!error(asecd())
+%!error(asecd(1,2))
+%!assert(asecd(0:10:90),180./pi.*asec(0:10:90),-10*eps)
diff --git a/scripts/elfun/asech.m b/scripts/elfun/asech.m
new file mode 100644
index 0000000..5a8695d
--- /dev/null
+++ b/scripts/elfun/asech.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} asech (@var{x})
+## Compute the inverse hyperbolic secant of each element of @var{x}.
+## @seealso{sech}
+## @end deftypefn
+
+## Author: jwe
+
+function w = asech (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = acosh (1 ./ z);
+
+endfunction
+
+%!test
+%! v = [0, pi*i];
+%! x = [1, -1];
+%! assert(all (abs (asech (x) - v) < sqrt (eps)));
+
+%!error asech ();
+
+%!error asech (1, 2);
+
diff --git a/scripts/elfun/asind.m b/scripts/elfun/asind.m
new file mode 100644
index 0000000..3ee11fb
--- /dev/null
+++ b/scripts/elfun/asind.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} asind (@var{x})
+## Compute the inverse sine in degrees for each element of @var{x}.
+## @seealso{sind, asin}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = asind (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = asin(x) .* 180 ./ pi;
+endfunction
+
+%!error(asind())
+%!error(asind(1,2))
+%!assert(asind(0:0.1:1),180/pi*asin(0:0.1:1),-10*eps)
diff --git a/scripts/elfun/atand.m b/scripts/elfun/atand.m
new file mode 100644
index 0000000..f577d2e
--- /dev/null
+++ b/scripts/elfun/atand.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} atand (@var{x})
+## Compute the inverse tangent in degrees for each element of @var{x}.
+## @seealso{tand, atan}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = atand (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = 180 ./ pi .* atan (x);
+endfunction
+
+%!error(atand())
+%!error(atand(1,2))
+%!assert(atand(0:10:90),180./pi.*atan(0:10:90),-10*eps)
diff --git a/scripts/elfun/cosd.m b/scripts/elfun/cosd.m
new file mode 100644
index 0000000..e1b5d23
--- /dev/null
+++ b/scripts/elfun/cosd.m
@@ -0,0 +1,42 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cosd (@var{x})
+## Compute the cosine for each element of @var{x} in degrees.  Returns zero 
+## for elements where @code{(@var{x}-90)/180} is an integer.
+## @seealso{acosd, cos}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = cosd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  I = x / 180;
+  y = cos (I .* pi);
+  I = I + 0.5;
+  y(I == round (I) & finite (I)) = 0;
+endfunction
+
+%!error(cosd())
+%!error(cosd(1,2))
+%!assert(cosd(0:10:80),cos(pi*[0:10:80]/180),-10*eps)
+%!assert(cosd([0,180,360]) != 0)
+%!assert(cosd([90,270]) == 0)
diff --git a/scripts/elfun/cot.m b/scripts/elfun/cot.m
new file mode 100644
index 0000000..ec08e77
--- /dev/null
+++ b/scripts/elfun/cot.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} cot (@var{x})
+## Compute the cotangent for each element of @var{x} in radians.
+## @seealso{acot, cotd, coth}
+## @end deftypefn
+
+## Author: jwe
+
+function w = cot (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = 1 ./ tan(z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6];
+%! v = [rt3, 1, rt3/3, 0, -rt3/3, -1, -rt3];
+%! assert(all (abs (cot (x) - v) < sqrt (eps)));
+
+%!error cot ();
+
+%!error cot (1, 2);
+
diff --git a/scripts/elfun/cotd.m b/scripts/elfun/cotd.m
new file mode 100644
index 0000000..42c8bcb
--- /dev/null
+++ b/scripts/elfun/cotd.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cotd (@var{x})
+## Compute the cotangent for each element of @var{x} in degrees.
+## @seealso{acotd, cot}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = cotd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = 1 ./ tand (x);
+endfunction
+
+%!error(cotd())
+%!error(cotd(1,2))
+%!assert(cotd(10:10:80),cot(pi*[10:10:80]/180),-10*eps)
+%!assert(cotd([0,180,360]) == Inf)
+%!assert(cotd([90,270]) == 0)
diff --git a/scripts/elfun/coth.m b/scripts/elfun/coth.m
new file mode 100644
index 0000000..0f17e5a
--- /dev/null
+++ b/scripts/elfun/coth.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2002, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} coth (@var{x})
+## Compute the hyperbolic cotangent of each element of @var{x}.
+## @seealso{acoth}
+## @end deftypefn
+
+## Author: jwe
+
+function w = coth (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = 1 ./ tanh (z);
+
+endfunction
+
+%!test
+%! x = [pi/2*i, 3*pi/2*i];
+%! v = [0, 0];
+%! assert(all (abs (coth (x) - v) < sqrt (eps)));
+
+%!error coth ();
+
+%!error coth (1, 2);
+
diff --git a/scripts/elfun/csc.m b/scripts/elfun/csc.m
new file mode 100644
index 0000000..8afef62
--- /dev/null
+++ b/scripts/elfun/csc.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} csc (@var{x})
+## Compute the cosecant for each element of @var{x} in radians.
+## @seealso{acsc, cscd, csch}
+## @end deftypefn
+
+## Author: jwe
+
+function w = csc (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = 1 ./ sin(z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6];
+%! v = [2, rt2, 2*rt3/3, 1, 2*rt3/3, rt2, 2];
+%! assert(all (abs (csc (x) - v) < sqrt (eps)));
+
+%!error csc ();
+
+%!error csc (1, 2);
+
diff --git a/scripts/elfun/cscd.m b/scripts/elfun/cscd.m
new file mode 100644
index 0000000..ba7841d
--- /dev/null
+++ b/scripts/elfun/cscd.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cscd (@var{x})
+## Compute the cosecant for each element of @var{x} in degrees.
+## @seealso{acscd, csc}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = cscd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = 1 ./ sind (x);
+endfunction
+
+%!error(cscd())
+%!error(cscd(1,2))
+%!assert(cscd(10:10:90),csc(pi*[10:10:90]/180),-10*eps)
+%!assert(cscd([0,180,360]) == Inf)
+%!assert(cscd([90,270]) != Inf)
+
diff --git a/scripts/elfun/csch.m b/scripts/elfun/csch.m
new file mode 100644
index 0000000..8d1c739
--- /dev/null
+++ b/scripts/elfun/csch.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} csch (@var{x})
+## Compute the hyperbolic cosecant of each element of @var{x}.
+## @seealso{acsch}
+## @end deftypefn
+
+## Author: jwe
+
+function w = csch (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = 1 ./ sinh(z);
+
+endfunction
+
+%!test
+%! x = [pi/2*i, 3*pi/2*i];
+%! v = [-i, i];
+%! assert(all (abs (csch (x) - v) < sqrt (eps)));
+
+%!error csch ();
+
+%!error csch (1, 2);
+
diff --git a/scripts/elfun/lcm.m b/scripts/elfun/lcm.m
new file mode 100644
index 0000000..010bee5
--- /dev/null
+++ b/scripts/elfun/lcm.m
@@ -0,0 +1,105 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Mapping Function} {} lcm (@var{x})
+## @deftypefnx {Mapping Function} {} lcm (@var{x}, @dots{})
+## Compute the least common multiple of the elements of @var{x}, or
+## of the list of all arguments.  For example,
+##
+## @example
+## lcm (a1, @dots{}, ak)
+## @end example
+##
+## @noindent
+## is the same as
+##
+## @example
+## lcm ([a1, @dots{}, ak]).
+## @end example
+##
+## All elements must be the same size or scalar.
+## @seealso{factor, gcd}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 16 September 1994
+## Adapted-By: jwe
+
+function l = lcm (varargin)
+
+  if (nargin == 0)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    a = varargin{1};
+
+    if (round (a) != a)
+      error ("lcm: all arguments must be integer");
+    endif
+
+    if (any (a) == 0)
+      l = 0;
+    else
+      a = abs (a);
+      l = a (1);
+      for k = 1:(length (a) - 1)
+	l = l * a(k+1) / gcd (l, a(k+1));
+      endfor
+    endif
+  else
+    
+    l = varargin{1};
+    sz = size (l);
+    nel = numel (l);
+
+    for i = 2:nargin
+      a = varargin{i};
+
+      if (size (a) != sz)
+	if (nel == 1)
+	  sz = size (a);
+	  nel = numel (a);
+	elseif (numel (a) != 1)
+	  error ("lcm: all arguments must be the same size or scalar");
+	endif
+      endif
+
+      if (round (a) != a)
+	error ("lcm: all arguments must be integer");
+      endif
+
+      idx = find (l == 0 || a == 0);
+      a = abs (a);
+      l = l .* a ./ gcd (l, a);
+      l(idx) = 0;
+    endfor
+  endif
+
+endfunction
+
+%!assert(lcm (3, 5, 7, 15) == lcm ([3, 5, 7, 15]) && lcm ([3, 5, 7,15]) == 105);
+
+%!error lcm ();
+
+%!test
+%! s.a = 1;
+%! fail("lcm (s)");
+
diff --git a/scripts/elfun/sec.m b/scripts/elfun/sec.m
new file mode 100644
index 0000000..f3beb32
--- /dev/null
+++ b/scripts/elfun/sec.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} sec (@var{x})
+## Compute the secant for each element of @var{x} in radians.
+## @seealso{asec, secd, sech}
+## @end deftypefn
+
+## Author: jwe
+
+function w = sec (z)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = 1 ./ cos(z);
+
+endfunction
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [0, pi/6, pi/4, pi/3, 2*pi/3, 3*pi/4, 5*pi/6, pi];
+%! v = [1, 2*rt3/3, rt2, 2, -2, -rt2, -2*rt3/3, -1];
+%! assert(all (abs (sec (x) - v) < sqrt (eps)));
+
+%!error sec ();
+
+%!error sec (1, 2);
+
diff --git a/scripts/elfun/secd.m b/scripts/elfun/secd.m
new file mode 100644
index 0000000..3fa3c2e
--- /dev/null
+++ b/scripts/elfun/secd.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} secd (@var{x})
+## Compute the secant for each element of @var{x} in degrees.
+## @seealso{asecd, sec}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = secd (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  y = 1 ./ cosd (x);
+endfunction
+
+%!error(secd())
+%!error(secd(1,2))
+%!assert(secd(0:10:80),sec(pi*[0:10:80]/180),-10*eps)
+%!assert(secd([0,180,360]) != Inf)
+%!assert(secd([90,270]) == Inf)
diff --git a/scripts/elfun/sech.m b/scripts/elfun/sech.m
new file mode 100644
index 0000000..1ff706a
--- /dev/null
+++ b/scripts/elfun/sech.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} sech (@var{x})
+## Compute the hyperbolic secant of each element of @var{x}.
+## @seealso{asech}
+## @end deftypefn
+
+## Author: jwe
+
+function w = sech (z)
+
+if (nargin != 1)
+    print_usage ();
+  endif
+
+  w = 1 ./ cosh(z);
+
+endfunction
+
+%!test
+%! x = [0, pi*i];
+%! v = [1, -1];
+%! assert(all (abs (sech (x) - v) < sqrt (eps)));
+
+%!error sech ();
+
+%!error sech (1, 2);
+
diff --git a/scripts/elfun/sind.m b/scripts/elfun/sind.m
new file mode 100644
index 0000000..4462427
--- /dev/null
+++ b/scripts/elfun/sind.m
@@ -0,0 +1,41 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sind (@var{x})
+## Compute the sine for each element of @var{x} in degrees.  Returns zero 
+## for elements where @code{@var{x}/180} is an integer.
+## @seealso{asind, sin}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = sind (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  I = x / 180;
+  y = sin (I .* pi);
+  y(I == round (I) & finite (I)) = 0;
+endfunction
+
+%!error(sind())
+%!error(sind(1,2))
+%!assert(sind(10:10:90),sin(pi*[10:10:90]/180),-10*eps)
+%!assert(sind([0,180,360]) == 0)
+%!assert(sind([90,270]) != 0)
diff --git a/scripts/elfun/tand.m b/scripts/elfun/tand.m
new file mode 100644
index 0000000..64d6b44
--- /dev/null
+++ b/scripts/elfun/tand.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} tand (@var{x})
+## Compute the tangent for each element of @var{x} in degrees.  Returns zero 
+## for elements where @code{@var{x}/180} is an integer and @code{Inf} for
+## elements where @code{(@var{x}-90)/180} is an integer.
+## @seealso{atand, tan}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function y = tand (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  I0 = x / 180;
+  I90 = (x-90) / 180;
+  y = tan (I0 .* pi);
+  y(I0 == round (I0) & finite (I0)) = 0;
+  y(I90 == round (I90) & finite (I90)) = Inf;
+endfunction;
+
+%!error(tand())
+%!error(tand(1,2))
+%!assert(tand(10:10:80),tan(pi*[10:10:80]/180),-10*eps)
+%!assert(tand([0,180,360]) == 0)
+%!assert(tand([90,270]) == Inf)
diff --git a/scripts/general/Makefile.in b/scripts/general/Makefile.in
new file mode 100644
index 0000000..3104f29
--- /dev/null
+++ b/scripts/general/Makefile.in
@@ -0,0 +1,97 @@
+# Makefile for octave's scripts/general directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = general
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = __isequal__.m __splinen__.m accumarray.m arrayfun.m \
+  bicubic.m bitcmp.m bitget.m bitset.m blkdiag.m cart2pol.m \
+  cart2sph.m cellidx.m cell2mat.m celldisp.m circshift.m colon.m common_size.m \
+  cplxpair.m cumtrapz.m dblquad.m deal.m del2.m diff.m display.m flipdim.m \
+  fliplr.m flipud.m genvarname.m gradient.m idivide.m ind2sub.m int2str.m \
+  interp1.m interp1q.m interp2.m interp3.m interpn.m interpft.m \
+  is_duplicate_entry.m isa.m isdefinite.m isdir.m isequal.m \
+  isequalwithequalnans.m isscalar.m issquare.m issymmetric.m \
+  isvector.m loadobj.m logical.m logspace.m mod.m nargchk.m \
+  nargoutchk.m nextpow2.m nthroot.m num2str.m perror.m pol2cart.m \
+  polyarea.m postpad.m prepad.m quadgk.m quadl.m quadv.m randperm.m rat.m \
+  rem.m repmat.m rot90.m rotdim.m runlength.m saveobj.m shift.m shiftdim.m \
+  sortrows.m sph2cart.m strerror.m structfun.m sub2ind.m subsindex.m \
+  triplequad.m trapz.m tril.m triu.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/general
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/general/__isequal__.m b/scripts/general/__isequal__.m
new file mode 100644
index 0000000..d47de7f
--- /dev/null
+++ b/scripts/general/__isequal__.m
@@ -0,0 +1,230 @@
+## Copyright (C) 2000, 2005, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## Undocumented internal function.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __isequal__ (@var{nans_compare_equal}, @var{x1}, @var{x2}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Return true if @var{x1}, @var{x2}, @dots{} are all equal and
+## @var{nans_compare_equal} evaluates to false.
+##
+## If @var{nans_compare_equal} evaluates to true, then assume NaN == NaN.
+
+## Modified by: William Poetra Yoga Hadisoeseno
+
+## Algorithm:
+##
+## 1. Determine the class of x
+## 2. If x is of the struct, cell, list or char class, for each
+##    argument after x, determine whether it has the same class
+##    and size as x.
+##    Otherwise, for each argument after x, verify that it is not
+##    of the struct, cell, list or char class, and that it has
+##    the same size as x.
+## 3. For each argument after x, compare it for equality with x:
+##    a. struct     compare each member by name, not by order (recursive)
+##    b. cell/list  compare each member by order (recursive)
+##    c. char       compare each member with strcmp
+##    d. <other>    compare each nonzero member, and assume NaN == NaN
+##                  if nans_compare_equal is nonzero.
+
+function t = __isequal__ (nans_compare_equal, x, varargin)
+
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  l_v = nargin - 2;
+
+  ## Generic tests.
+
+  ## Give an error for a list (that will make the code simpler and lists
+  ## are deprecated anyway.
+  if (islist (x))
+    error ("__isequal__: list objects are deprecated and cannot be tested for equality here; use cell arrays instead");
+  endif
+
+  ## All arguments must either be of the same class or they must be
+  ## numeric values.
+  t = (all (strcmp (class(x),
+		   cellfun (@class, varargin, "UniformOutput", false)))
+       || (isnumeric (x)
+	   && all (cellfun (@isnumeric, varargin, "UniformOutput", true))));
+
+  if (t)
+    ## Test that everything has the same number of dimensions.
+    s_x = size (x);
+    s_v = cellfun (@size, varargin, "UniformOutput", false);
+    t = all (length (s_x) == cellfun (@length, s_v));
+  endif
+
+  if (t)
+    ## Test that everything is the same size since it has the same
+    ## dimensionality.
+    l_x = length (s_x);
+    s_v = reshape ([s_v{:}], length (s_x), []);
+    idx = 0;
+    while (t && idx < l_x)
+      idx++;
+      t = all (s_x(idx) == s_v(idx, :));
+    endwhile
+  endif
+
+  if (t)
+    ## Check individual classes.
+    if (isstruct (x))
+      ## Test the number of fields.
+      fn_x = fieldnames (x);
+      l_fn_x = length (fn_x);
+      fn_v = cellfun (@fieldnames, varargin, "UniformOutput", false);
+      t = all (l_fn_x == cellfun (@length, fn_v));
+
+      ## Test that all the names are equal.
+      idx = 0;
+      s_fn_x = sort (fn_x);
+      while (t && idx < l_v)
+	idx++;
+	## We'll allow the fieldnames to be in a different order.
+	t = all (strcmp (s_fn_x, sort (fn_v{idx})));
+      endwhile
+
+      idx = 0;
+      while (t && idx < l_fn_x)
+	## Test that all field values are equal.
+	idx++;
+	args = {nans_compare_equal, {x.(fn_x{idx})}};
+	for argn = 1:l_v
+	  args{argn+2} = {varargin{argn}.(fn_x{idx})};
+	endfor
+	## Minimize function calls by calling for all the arguments at
+	## once.
+        t = __isequal__ (args{:});
+      endwhile
+
+    elseif (iscell (x))
+      ## Check that each element of a cell is equal.
+      l_x = numel (x);
+      idx = 0;
+      while (t && idx < l_x)
+	idx++;
+	args = {nans_compare_equal, x{idx}};
+	for p = 1:l_v
+	  args{p+2} = varargin{p}{idx};
+	endfor
+        t = __isequal__ (args{:});
+      endwhile
+
+    elseif (ischar (x))
+
+      ## Sizes are equal already, so we can just make everything into a
+      ## row and test the rows.
+      for i = 1:l_v
+	strings{i} = reshape (varargin{i}, 1, []);
+      endfor
+      t = all (strcmp (reshape (x, 1, []), strings));
+
+    else
+      ## Check the numeric types.
+
+      if (issparse (x))
+	f_x = spfind (x);
+      else
+	f_x = find (x);
+      endif
+      l_f_x = length (f_x);
+      x = x(f_x);
+      for argn = 1:l_v
+	y = varargin{argn};
+	if (issparse (y))
+          f_y = spfind (y);
+	else
+          f_y = find (y);
+	endif
+
+	t = (l_f_x == length (f_y)) && all (f_x == f_y);
+	if (!t)
+          return;
+	endif
+
+	y = y(f_y);
+	m = (x == y);
+	t = all (m);
+
+	if (!t)
+          if (nans_compare_equal)
+            t = isnan (x(!m)) && isnan (y(!m));
+          else
+            return;
+          endif
+	endif
+      endfor
+
+    endif
+  endif
+
+endfunction
+
+## test size and shape
+%!assert(__isequal__(0,[1,2,3,4],[1,2,3,4]), true)
+%!assert(__isequal__(0,[1;2;3;4],[1;2;3;4]), true)
+%!assert(__isequal__(0,[1,2,3,4],[1;2;3;4]), false)
+%!assert(__isequal__(0,[1,2,3,4],[1,2;3,4]), false)
+%!assert(__isequal__(0,[1,2,3,4],[1,3;2,4]), false)
+
+%!test
+%! A = 1:8;
+%! B = reshape (A, 2, 2, 2);
+%! assert (__isequal__ (0, A, B), false);
+
+%!test
+%! A = reshape (1:8, 2, 2, 2);
+%! B = A;
+%! assert (__isequal__ (0, A, B), true);
+
+%!test
+%! A = reshape (1:8, 2, 4);
+%! B = reshape (A, 2, 2, 2);
+%! assert (__isequal__ (0, A, B), false);
+
+## test for equality
+%!assert(__isequal__(0,[1,2,3,4],[1,2,3,4]), true)
+%!assert(__isequal__(1,{1,2,NaN,4},{1,2,NaN,4}), true)
+%!assert(__isequal__(1,[1,2,NaN,4],[1,2,NaN,4]), true)
+%!assert(__isequal__(0,['a','b','c','d'],['a','b','c','d']), true)
+## Test multi-line strings
+%!assert(__isequal__(0,["test";"strings"],["test";"strings"],["test";"strings"]), true)
+## test for inequality
+%!assert(__isequal__(0,[1,2,3,4],[1;2;3;4]),false)
+%!assert(__isequal__(0,{1,2,3,4},[1,2,3,4]),false)
+%!assert(__isequal__(0,[1,2,3,4],{1,2,3,4}),false)
+%!assert(__isequal__(0,[1,2,NaN,4],[1,2,NaN,4]),false)
+%!assert(__isequal__(1,[1,2,NaN,4],[1,NaN,3,4]),false)
+%!assert(__isequal__(1,[1,2,NaN,4],[1,2,3,4]),false)
+%!assert(__isequal__(0,['a','b','c','d'],['a';'b';'c';'d']),false)
+%!assert(__isequal__(0,{'a','b','c','d'},{'a';'b';'c';'d'}),false)
+## test for equality (struct)
+%!assert(__isequal__(0,struct('a',1,'b',2),struct('a',1,'b',2)),true)
+%!assert(__isequal__(0,struct('a',1,'b',2),struct('a',1,'b',2),struct('a',1,'b',2)),true)
+%!assert(__isequal__(0,struct('a','abc','b',2),struct('a','abc','b',2)),true)
+%!assert(__isequal__(1,struct('a',NaN,'b',2),struct('a',NaN,'b',2),struct('a',NaN,'b',2)),true)
+## test for inequality (struct)
+%!assert(__isequal__(0,struct('a',NaN,'b',2),struct('a',NaN,'b',2),struct('a',NaN,'b',2)),false)
+
diff --git a/scripts/general/__splinen__.m b/scripts/general/__splinen__.m
new file mode 100644
index 0000000..43c86f9
--- /dev/null
+++ b/scripts/general/__splinen__.m
@@ -0,0 +1,49 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## Undocumented internal function.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{yi} =} __splinen__ (@var{x}, @var{y}, @var{xi})
+## Undocumented internal function.
+## @end deftypefn
+
+## FIXME: Allow arbitrary grids..
+
+function yi = __splinen__ (x, y, xi, extrapval, f)
+  if (nargin != 5)
+    error ("Incorrect number of arguments");
+  endif
+  ## ND isvector function.
+  isvec = @(x) numel (x) == length (x);
+  if (!iscell (x) || length(x) < ndims(y) || any (! cellfun (isvec, x)) ||
+      !iscell (xi) || length(xi) < ndims(y) || any (! cellfun (isvec, xi)))
+    error ("%s: non gridded data or dimensions inconsistent", f);
+  endif
+  yi = y;
+  for i = length(x):-1:1
+    yi = permute (spline (x{i}, yi, xi{i}), [length(x),1:length(x)-1]);
+  endfor
+
+  [xi{:}] = ndgrid (cellfun (@(x) x(:), xi, "UniformOutput", false){:});
+  idx = zeros (size(xi{1}));
+  for i = 1 : length(x)
+    idx |= xi{i} < min (x{i}(:)) | xi{i} > max (x{i}(:));
+  endfor
+  yi(idx) = extrapval;
+endfunction
diff --git a/scripts/general/accumarray.m b/scripts/general/accumarray.m
new file mode 100644
index 0000000..d7739d2
--- /dev/null
+++ b/scripts/general/accumarray.m
@@ -0,0 +1,186 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} accumarray (@var{subs}, @var{vals}, @var{sz}, @var{func}, @var{fillval}, @var{issparse})
+## @deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, @dots{})
+##
+## Create an array by accumulating the elements of a vector into the
+## positions defined by their subscripts.  The subscripts are defined by
+## the rows of the matrix @var{subs} and the values by @var{vals}.  Each row
+## of @var{subs} corresponds to one of the values in @var{vals}.
+##
+## The size of the matrix will be determined by the subscripts themselves.
+## However, if @var{sz} is defined it determines the matrix size.  The length
+## of @var{sz} must correspond to the number of columns in @var{subs}.
+##
+## The default action of @code{accumarray} is to sum the elements with the
+## same subscripts.  This behavior can be modified by defining the @var{func}
+## function.  This should be a function or function handle that accepts a 
+## column vector and returns a scalar.  The result of the function should not
+## depend on the order of the subscripts.
+##
+## The elements of the returned array that have no subscripts associated with
+## them are set to zero.  Defining @var{fillval} to some other value allows
+## these values to be defined.
+##
+## By default @code{accumarray} returns a full matrix.  If @var{issparse} is
+## logically true, then a sparse matrix is returned instead.
+##
+## An example of the use of @code{accumarray} is:
+##
+## @example
+## @group
+## accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+## @result{} ans(:,:,1) = [101, 0, 0; 0, 0, 0]
+##    ans(:,:,2) = [0, 0, 0; 206, 0, 208]
+## @end group
+## @end example
+## @end deftypefn
+
+function A = accumarray (subs, val, sz, func, fillval, isspar)  
+
+  if (nargin < 2 || nargin > 6)
+    print_usage ();
+  endif
+
+  if (iscell (subs))
+    subs = cell2mat (cellfun (@(x) x(:), subs, "UniformOutput", false));
+  endif
+  ndims = size (subs, 2);
+
+  if (nargin < 5 || isempty (fillval))
+    fillval = 0;
+  endif
+
+  if (nargin < 6 || isempty (isspar))
+    isspar = false;
+  endif
+
+  if (isspar && ndims > 2)
+    error ("accumarray: sparse matrices limited to 2 dimensions");
+  endif
+
+  if (nargin < 4 || isempty (func))
+    func = @sum;
+    ## This is the fast summation case. Unlike the general case,
+    ## this case will be handled using an O(N) algorithm.
+
+    if (isspar && fillval == 0)
+      ## The "sparse" function can handle this case.
+
+      if ((nargin < 3 || isempty (sz)))
+        A = sparse (subs(:,1), subs(:,2), val);
+      elseif (length (sz) == 2)
+        A = sparse (subs(:,1), subs(:,2), val, sz(1), sz(2));
+      else
+        error ("accumarray: dimensions mismatch")
+      endif
+    else
+      ## This case is handled by an internal function.
+
+      if (ndims > 1)
+        if ((nargin < 3 || isempty (sz)))
+          sz = max (subs);
+        elseif (ndims != length (sz))
+          error ("accumarray: dimensions mismatch")
+        elseif (any (max (subs) > sz))
+          error ("accumarray: index out of range")
+        endif
+
+        ## Convert multidimensional subscripts.
+        subs = sub2ind (sz, mat2cell (subs, rows (subs), ones (1, ndims)){:});
+      elseif (nargin < 3)
+        ## In case of linear indexing, the fast built-in accumulator
+        ## will determine the extent for us.
+        sz = [];
+      endif
+
+      ## Call the built-in accumulator.
+      if (isempty (sz))
+        A = __accumarray_sum__ (subs, val);
+      else
+        A = __accumarray_sum__ (subs, val, prod (sz));
+        ## set proper shape.
+        A = reshape (A, sz);
+      endif
+
+      ## we fill in nonzero fill value.
+      if (fillval != 0)
+        mask = true (size (A));
+        mask(subs) = false;
+        A(mask) = fillval;
+      endif
+    endif
+
+    return
+  endif
+
+  if (nargin < 3 || isempty (sz))
+    sz = max (subs);
+    if (isscalar(sz))
+      sz = [sz, 1];
+    endif
+  elseif (length (sz) != ndims
+	  && (ndims != 1 || length (sz) != 2 || sz(2) != 1))
+    error ("accumarray: inconsistent dimensions");
+  endif
+  
+  [subs, idx] = sortrows (subs);
+
+  if (isscalar (val))
+    val = val * ones (size (idx));
+  else
+    val = val(idx);
+  endif
+  cidx = find ([true; (sum (abs (diff (subs)), 2) != 0)]);
+  idx = cell (1, ndims);
+  for i = 1:ndims
+    idx{i} = subs (cidx, i);
+  endfor
+  x = cellfun (func, mat2cell (val(:), diff ([cidx; length(val) + 1])));
+  if (isspar && fillval == 0)
+    A = sparse (idx{1}, idx{2}, x, sz(1), sz(2));
+  else
+    if (iscell (x))
+      ## Why did matlab choose to reverse the order of the elements
+      x = cellfun (@(x) flipud (x(:)), x, "UniformOutput", false);
+      A = cell (sz);
+    elseif (fillval == 0)
+      A = zeros (sz, class (x));
+    else 
+      A = fillval .* ones (sz);
+    endif
+    A(sub2ind (sz, idx{:})) = x;
+  endif
+endfunction
+
+%!error (accumarray (1:5))
+%!error (accumarray ([1,2,3],1:2))
+%!assert (accumarray ([1;2;4;2;4],101:105), [101;206;0;208])
+%!assert (accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2],101:105),cat(3, [101,0,0;0,0,0],[0,0,0;206,0,208]))
+%!assert (accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2],101:105,[],@(x)sin(sum(x))),sin(cat(3, [101,0,0;0,0,0],[0,0,0;206,0,208])))
+%!assert (accumarray ({[1 3 3 2 3 1 2 2 3 3 1 2],[3 4 2 1 4 3 4 2 2 4 3 4],[1 1 2 2 1 1 2 1 1 1 2 2]},101:112),cat(3,[0,0,207,0;0,108,0,0;0,109,0,317],[0,0,111,0;104,0,0,219;0,103,0,0]))
+%!assert (accumarray ([1,1;2,1;2,3;2,1;2,3],101:105,[2,4], at max,NaN),[101,NaN,NaN,NaN;104,NaN,105,NaN])
+%!assert (accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],101:105,[2 4], at prod,0,true),sparse([1,2,2],[1,1,3],[101,10608,10815],2,4))
+%!assert (accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],1,[2,4]), [1,0,0,0;2,0,2,0])
+%!assert (accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],101:105,[2,4],@(x)length(x)>1),[false,false,false,false;true,false,true,false])
+%!test
+%! A = accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],101:105,[2,4],@(x){x});
+%! assert (A{2},[104;102])
diff --git a/scripts/general/arrayfun.m b/scripts/general/arrayfun.m
new file mode 100644
index 0000000..ab85baa
--- /dev/null
+++ b/scripts/general/arrayfun.m
@@ -0,0 +1,353 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} arrayfun (@var{func}, @var{a})
+## @deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{a})
+## @deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{a}, @var{b}, @dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{y}, @dots{}] =} arrayfun (@var{func}, @var{a}, @dots{})
+## @deftypefnx {Function File} {} arrayfun (@dots{}, "UniformOutput", @var{val})
+## @deftypefnx {Function File} {} arrayfun (@dots{}, "ErrorHandler", @var{errfunc})
+##
+## Execute a function on each element of an array.  This is useful for
+## functions that do not accept array arguments.  If the function does
+## accept array arguments it is better to call the function directly.
+##
+## The first input argument @var{func} can be a string, a function
+## handle, an inline function or an anonymous function.  The input
+## argument @var{a} can be a logic array, a numeric array, a string
+## array, a structure array or a cell array.  By a call of the function
+## @command{arrayfun} all elements of @var{a} are passed on to the named
+## function @var{func} individually.
+## 
+## The named function can also take more than two input arguments, with
+## the input arguments given as third input argument @var{b}, fourth
+## input argument @var{c}, @dots{}  If given more than one array input
+## argument then all input arguments must have the same sizes, for
+## example
+##
+## @example
+## @group
+## arrayfun (@@atan2, [1, 0], [0, 1])
+## @result{} ans = [1.5708   0.0000]
+## @end group
+## @end example
+##
+## If the parameter @var{val} after a further string input argument
+## "UniformOutput" is set @code{true} (the default), then the named
+## function @var{func} must return a single element which then will be
+## concatenated into the return value and is of type matrix.  Otherwise,
+## if that parameter is set to @code{false}, then the outputs are
+## concatenated in a cell array.  For example
+##
+## @example
+## @group
+## arrayfun (@@(x,y) x:y, "abc", "def", "UniformOutput", false)
+## @result{} ans =
+## @{
+##   [1,1] = abcd
+##   [1,2] = bcde
+##   [1,3] = cdef
+## @}
+## @end group
+## @end example
+##
+## If more than one output arguments are given then the named function
+## must return the number of return values that also are expected, for
+## example
+##
+## @example
+## @group
+## [A, B, C] = arrayfun (@@find, [10; 0], "UniformOutput", false)
+## @result{}
+## A =
+## @{
+##   [1,1] =  1
+##   [2,1] = [](0x0)
+## @}
+## B =
+## @{
+##   [1,1] =  1
+##   [2,1] = [](0x0)
+## @}
+## C =
+## @{
+##   [1,1] =  10
+##   [2,1] = [](0x0)
+## @}
+## @end group
+## @end example
+##
+## If the parameter @var{errfunc} after a further string input argument
+## "ErrorHandler" is another string, a function handle, an inline
+## function or an anonymous function, then @var{errfunc} defines a
+## function to call in the case that @var{func} generates an error.
+## The definition of the function must be of the form
+##
+## @example
+## function [@dots{}] = errfunc (@var{s}, @dots{})
+## @end example
+##
+## where there is an additional input argument to @var{errfunc}
+## relative to @var{func}, given by @var{s}.  This is a structure with
+## the elements "identifier", "message" and "index", giving
+## respectively the error identifier, the error message and the index of
+## the array elements that caused the error.  The size of the output
+## argument of @var{errfunc} must have the same size as the output
+## argument of @var{func}, otherwise a real error is thrown.  For
+## example
+##
+## @example
+## @group
+## function y = ferr (s, x), y = "MyString"; endfunction
+## arrayfun (@@str2num, [1234], \
+##           "UniformOutput", false, "ErrorHandler", @@ferr)
+## @result{} ans =
+## @{
+##  [1,1] = MyString
+## @}
+## @end group
+## @end example
+##
+## @seealso{cellfun, spfun, structfun}
+## @end deftypefn
+
+## Author: Bill Denney <denney at seas.upenn.edu>
+
+function varargout = arrayfun (func, varargin)
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  ## Convert everything to cells and call cellfun (let cellfun error
+  ## check the options in case more options come available).
+  sizetomatch = size (varargin{1});
+  m2cargs{1} = ones (size (varargin{1}, 1), 1);
+  m2cargs{2} = ones (size (varargin{1}, 2), 1);
+  cfarg{1} = mat2cell (varargin{1}, m2cargs{:});
+  stillmatches = true;
+  idx = 1;
+  len = length (varargin);
+  while (stillmatches && idx < len)
+    idx++;
+    thissize = size (varargin{idx});
+    if (numel (thissize) == numel (sizetomatch)
+        && all (thissize == sizetomatch))
+      if (ischar (varargin{idx})
+          && (strcmpi (varargin{idx}, "UniformOutput")
+              || strcmpi (varargin{idx}, "ErrorHandler")))
+        ## Catch these strings just in case they happen to be the same
+        ## size as the other input.
+        stillmatches = false;
+      else
+        cfarg{idx} = mat2cell (varargin{idx}, m2cargs{:});
+      endif
+    else
+      stillmatches = false;
+    endif
+  endwhile
+
+  varargout = cell (max ([nargout, 1]), 1);
+  if (idx >= len)
+    [varargout{:}] = cellfun (func, cfarg{:});
+  else
+    [varargout{:}] = cellfun (func, cfarg{:}, varargin{idx:len});
+  endif
+endfunction
+
+%% Test function to check the "Errorhandler" option
+%!function [z] = arrayfunerror (S, varargin)
+%!      z = S;
+%!    endfunction
+%% First input argument can be a string, an inline function, a
+%% function_handle or an anonymous function
+%!test
+%!  arrayfun (@isequal, [false, true], [true, true]); %% No output argument
+%!error
+%!  arrayfun (@isequal); %% One or less input arguments
+%!test
+%!  A = arrayfun ("isequal", [false, true], [true, true]);
+%!  assert (A, [false, true]);
+%!test
+%!  A = arrayfun (inline ("(x == y)", "x", "y"), [false, true], [true, true]);
+%!  assert (A, [false, true]);
+%!test
+%!  A = arrayfun (@isequal, [false, true], [true, true]);
+%!  assert (A, [false, true]);
+%!test
+%!  A = arrayfun (@(x,y) isequal(x,y), [false, true], [true, true]);
+%!  assert (A, [false, true]);
+
+%% Number of input and output arguments may be greater than one
+%#!test
+%!  A = arrayfun (@(x) islogical (x), false);
+%!  assert (A, true);
+%!test
+%!  A = arrayfun (@(x,y,z) x + y + z, [1, 1, 1], [2, 2, 2], [3, 4, 5]);
+%!  assert (A, [6, 7, 8], 1e-16);
+%!test %% Two input arguments of different types
+%!  A = arrayfun (@(x,y) islogical (x) && ischar (y), false, "a");
+%!  assert (A, true);
+%!test %% Pass another variable to the anonymous function
+%!  y = true; A = arrayfun (@(x) islogical (x && y), false);
+%!  assert (A, true);
+%!test %% Three ouptut arguments of different type
+%!  [A, B, C] = arrayfun (@find, [10, 11; 0, 12], "UniformOutput", false);
+%!  assert (isequal (A, {true, true; [], true}));
+%!  assert (isequal (B, {true, true; [], true}));
+%!  assert (isequal (C, {10, 11; [], 12}));
+
+%% Input arguments can be of type logical
+%!test
+%!  A = arrayfun (@(x,y) x == y, [false, true], [true, true]);
+%!  assert (A, [false, true]);
+%!test
+%!  A = arrayfun (@(x,y) x == y, [false; true], [true; true], "UniformOutput", true);
+%!  assert (A, [false; true]);
+%!test
+%!  A = arrayfun (@(x) x, [false, true, false, true], "UniformOutput", false);
+%!  assert (A, {false, true, false, true});
+%!test %% Three ouptut arguments of same type
+%!  [A, B, C] = arrayfun (@find, [true, false; false, true], "UniformOutput", false);
+%!  assert (isequal (A, {true, []; [], true}));
+%!  assert (isequal (B, {true, []; [], true}));
+%!  assert (isequal (C, {true, []; [], true}));
+%!test
+%!  A = arrayfun (@(x,y) array2str (x,y), true, true, "ErrorHandler", @arrayfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = arrayfun (@(x,y) array2str (x,y), true, true, \
+%!                "UniformOutput", true, "ErrorHandler", @arrayfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+
+%% Input arguments can be of type numeric
+%!test
+%!  A = arrayfun (@(x,y) x>y, [1.1, 4.2], [3.1, 2+6*i]);
+%!  assert (A, [false, true]);
+%!test
+%!  A = arrayfun (@(x,y) x>y, [1.1, 4.2; 2, 4], [3.1, 2; 2, 4+2*i], "UniformOutput", true);
+%!  assert (A, [false, true; false, false]);
+%!test
+%!  A = arrayfun (@(x,y) x:y, [1.1, 4], [3.1, 6], "UniformOutput", false);
+%!  assert (isequal (A{1}, [1.1, 2.1, 3.1]));
+%!  assert (isequal (A{2}, [4, 5, 6]));
+%!test %% Three ouptut arguments of different type
+%!  [A, B, C] = arrayfun (@find, [10, 11; 0, 12], "UniformOutput", false);
+%!  assert (isequal (A, {true, true; [], true}));
+%!  assert (isequal (B, {true, true; [], true}));
+%!  assert (isequal (C, {10, 11; [], 12}));
+%!test
+%!  A = arrayfun (@(x,y) array2str(x,y), {1.1, 4}, {3.1, 6}, "ErrorHandler", @arrayfunerror);
+%!  B = isfield (A(1), "message") && isfield (A(1), "index");
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = arrayfun (@(x,y) array2str(x,y), {1.1, 4}, {3.1, 6}, \
+%!                "UniformOutput", true, "ErrorHandler", @arrayfunerror);
+%!  B = isfield (A(1), "message") && isfield (A(1), "index");
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+
+%% Input arguments can be of type character or strings
+%!test
+%!  A = arrayfun (@(x,y) x>y, ["ad", "c", "ghi"], ["cc", "d", "fgh"]);
+%!  assert (A, [false, true, false, true, true, true]);
+%!test
+%!  A = arrayfun (@(x,y) x>y, ["a"; "f"], ["c"; "d"], "UniformOutput", true);
+%!  assert (A, [false; true]);
+%!test
+%!  A = arrayfun (@(x,y) x:y, ["a", "d"], ["c", "f"], "UniformOutput", false);
+%!  assert (A, {"abc", "def"});
+%! %#!test
+%!   A = arrayfun (@(x,y) cell2str(x,y), ["a", "d"], ["c", "f"], "ErrorHandler", @arrayfunerror);
+%!   B = isfield (A(1), "identifier") && isfield (A(1), "message") && isfield (A(1), "index");
+%!   assert (B, true);
+
+%% Input arguments can be of type structure
+%!test
+%!  a = struct ("a", 1.1, "b", 4.2); b = struct ("a", 3.1, "b", 2);
+%!  A = arrayfun (@(x,y) (x.a < y.a) && (x.b > y.b), a, b);
+%!  assert (A, true);
+%!test
+%!  a = struct ("a", 1.1, "b", 4.2); b = struct ("a", 3.1, "b", 2);
+%!  A = arrayfun (@(x,y) (x.a < y.a) && (x.b > y.b), a, b, "UniformOutput", true);
+%!  assert (A, true);
+%!test
+%!  a = struct ("a", 1.1, "b", 4.2); b = struct ("a", 3.1, "b", 2);
+%!  A = arrayfun (@(x,y) x.a:y.a, a, b, "UniformOutput", false);
+%!  assert (isequal (A, {[1.1, 2.1, 3.1]}));
+%!test
+%!  A = arrayfun (@(x) mat2str(x), "a", "ErrorHandler", @arrayfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = arrayfun (@(x) mat2str(x), "a", "UniformOutput", true, \
+%!                "ErrorHandler", @arrayfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+
+%% Input arguments can be of type cell array
+%!test
+%!  A = arrayfun (@(x,y) x{1} < y{1}, {1.1, 4.2}, {3.1, 2});
+%!  assert (A, [true, false]);
+%!test
+%!  A = arrayfun (@(x,y) x{1} < y{1}, {1.1; 4.2}, {3.1; 2}, "UniformOutput", true);
+%!  assert (A, [true; false]);
+%!test
+%!  A = arrayfun (@(x,y) x{1} < y{1}, {1.1, 4.2}, {3.1, 2}, "UniformOutput", false);
+%!  assert (A, {true, false});
+%!test
+%!  A = arrayfun (@(x,y) num2str(x,y), {1.1, 4.2}, {3.1, 2}, "ErrorHandler", @arrayfunerror);
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+%!test
+%!  A = arrayfun (@(x,y) num2str(x,y), {1.1, 4.2}, {3.1, 2}, \
+%!                "UniformOutput", true, "ErrorHandler", @arrayfunerror);
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+
+## Local Variables: ***
+## mode: octave ***
+## End: ***
diff --git a/scripts/general/bicubic.m b/scripts/general/bicubic.m
new file mode 100644
index 0000000..ff1a1c0
--- /dev/null
+++ b/scripts/general/bicubic.m
@@ -0,0 +1,208 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Hoxide Ma
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{zi} =} bicubic (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{extrapval})
+##
+## Return a matrix @var{zi} corresponding to the bicubic
+## interpolations at @var{xi} and @var{yi} of the data supplied
+## as @var{x}, @var{y} and @var{z}.  Points outside the grid are set
+## to @var{extrapval}.
+##
+## See @url{http://wiki.woodpecker.org.cn/moin/Octave/Bicubic}
+## for further information.
+## @seealso{interp2}
+## @end deftypefn
+
+## Bicubic interpolation method.
+## Author: Hoxide Ma <hoxide_dirac at yahoo.com.cn>
+
+function F = bicubic (X, Y, Z, XI, YI, extrapval, spline_alpha)
+
+  if (nargin < 1 || nargin > 7)
+    print_usage ();
+  endif
+
+  if (nargin == 7 && isscalar(spline_alpha))
+    a = spline_alpha
+  else
+    a = 0.5;
+  endif
+
+  if (nargin < 6)
+    extrapval = NaN;
+  endif
+
+  if (isa (X, "single") || isa (Y, "single") || isa (Z, "single") || 
+      isa (XI, "single") || isa (YI, "single"))
+    myeps = eps("single");
+  else
+    myeps = eps;
+  endif
+
+  if (nargin <= 2)
+    ## bicubic (Z) or bicubic (Z, 2)
+    if (nargin == 1) 
+      n = 1;
+    else
+      n = Y;
+    endif
+    Z = X;
+    X = [];
+    [rz, cz] = size (Z);
+    s = linspace (1, cz, (cz-1)*pow2(n)+1);
+    t = linspace (1, rz, (rz-1)*pow2(n)+1);
+  elseif (nargin == 3)
+    if (! isvector (X) || ! isvector (Y))
+      error ("XI and YI must be vector");
+    endif
+    s = Y;
+    t = Z;
+    Z = X;
+    [rz, cz] = size (Z);
+  elseif (nargin == 5 || nargin == 6)
+    [rz, cz] = size (Z) ; 
+    if (isvector (X) && isvector (Y))
+      if (rz != length (Y) || cz != length (X))
+	error ("length of X and Y must match the size of Z");
+      endif
+    elseif (size_equal (X, Y) && size_equal (X, Z))
+      X = X(1,:);
+      Y = Y(:,1);
+    else
+      error ("X, Y and Z must be martrices of same size");
+    endif
+    
+    ## Mark values outside the lookup table.
+    xfirst_ind = find (XI < X(1));
+    xlast_ind  = find (XI > X(cz));    
+    yfirst_ind = find (YI < Y(1));
+    ylast_ind  = find (YI > Y(rz));
+    ## Set value outside the table preliminary to min max index.
+    XI(xfirst_ind) = X(1);
+    XI(xlast_ind) = X(cz);
+    YI(yfirst_ind) = Y(1);
+    YI(ylast_ind) = Y(rz);
+
+
+    X = reshape (X, 1, cz);
+    X(cz) *= 1 + sign (X(cz))*myeps;
+    if (X(cz) == 0) 
+      X(cz) = myeps;
+    endif; 
+    XI = reshape (XI, 1, length (XI));
+    [m, i] = sort ([X, XI]);
+    o = cumsum (i <= cz);
+    xidx = o(find (i > cz));
+    
+    Y = reshape (Y, rz, 1);
+    Y(rz) *= 1 + sign (Y(rz))*myeps;
+    if (Y(rz) == 0) 
+      Y(rz) = myeps;
+    endif; 
+    YI = reshape (YI, length (YI), 1);
+    [m, i] = sort ([Y; YI]);
+    o = cumsum (i <= rz);
+    yidx = o([find(i > rz)]);
+    
+    ## Set s and t used follow codes.
+    s = xidx + ((XI .- X(xidx))./(X(xidx+1) .- X(xidx)));
+    t = yidx + ((YI - Y(yidx))./(Y(yidx+1) - Y(yidx)));
+  else
+    print_usage ();
+  endif
+  
+  if (rz < 3 || cz < 3)
+    error ("Z at least a 3 by 3 matrices");
+  endif
+
+  inds = floor (s);
+  d = find (s == cz);
+  s = s - floor (s);
+  inds(d) = cz-1;
+  s(d) = 1.0;
+  
+  d = [];
+  indt = floor (t);
+  d = find (t == rz);
+  t = t - floor (t);
+  indt(d) = rz-1;
+  t(d) = 1.0;
+  d = [];
+
+  p = zeros (size (Z) + 2);
+  p(2:rz+1,2:cz+1) = Z;
+  p(1,:) =    (6*(1-a))*p(2,:)    - 3*p(3,:)  + (6*a-2)*p(4,:);
+  p(rz+2,:) = (6*(1-a))*p(rz+1,:) - 3*p(rz,:) + (6*a-2)*p(rz-1,:);
+  p(:,1) =    (6*(1-a))*p(:,2)    - 3*p(:,3)  + (6*a-2)*p(:,4);
+  p(:,cz+2) = (6*(1-a))*p(:,cz+1) - 3*p(:,cz) + (6*a-2)*p(:,cz-1);
+
+  ## Calculte the C1(t) C2(t) C3(t) C4(t) and C1(s) C2(s) C3(s) C4(s).
+  t2 = t.*t;
+  t3 = t2.*t;
+
+  ct0 =    -a .* t3 +     (2 * a) .* t2 - a .* t ;      # -a G0
+  ct1 = (2-a) .* t3 +      (-3+a) .* t2          + 1 ;  # F0 - a G1
+  ct2 = (a-2) .* t3 + (-2 *a + 3) .* t2 + a .* t ;      # F1 + a G0
+  ct3 =     a .* t3 -           a .* t2;                # a G1
+  t = []; t2 = []; t3 = [];
+
+  s2 = s.*s;
+  s3 = s2.*s;
+
+  cs0 =    -a .* s3 +     (2 * a) .* s2 - a .*s ;      # -a G0
+  cs1 = (2-a) .* s3 +    (-3 + a) .* s2         + 1 ;  # F0 - a G1
+  cs2 = (a-2) .* s3 + (-2 *a + 3) .* s2 + a .*s ;      # F1 + a G0
+  cs3 =     a .* s3 -           a .* s2;               # a G1
+  s = []; s2 = []; s3 = [];
+
+  cs0 = cs0([1,1,1,1],:);
+  cs1 = cs1([1,1,1,1],:);
+  cs2 = cs2([1,1,1,1],:);
+  cs3 = cs3([1,1,1,1],:);
+
+  lent = length (ct0);
+  lens = length (cs0);
+  F = zeros (lent, lens);
+  
+  for i = 1:lent
+    it = indt(i);
+    int = [it, it+1, it+2, it+3];
+    F(i,:) = ([ct0(i),ct1(i),ct2(i),ct3(i)]
+	      * (p(int,inds) .* cs0 + p(int,inds+1) .* cs1
+		 + p(int,inds+2) .* cs2 + p(int,inds+3) .* cs3));
+  endfor
+
+  ## Set points outside the table to extrapval.
+  if (! (isempty (xfirst_ind) && isempty (xlast_ind)))
+    F(:, [xfirst_ind, xlast_ind]) = extrapval;
+  endif
+  if (! (isempty (yfirst_ind) && isempty (ylast_ind)))
+    F([yfirst_ind; ylast_ind], :) = extrapval;
+  endif
+
+endfunction
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,4]+10; y=[-10,-9,-8];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,bicubic(x,y,A,xi,yi));
+%! [x,y] = meshgrid(x,y);
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
diff --git a/scripts/general/bitcmp.m b/scripts/general/bitcmp.m
new file mode 100644
index 0000000..9ad93bc
--- /dev/null
+++ b/scripts/general/bitcmp.m
@@ -0,0 +1,121 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bitcmp (@var{a}, @var{k})
+## Return the @var{k}-bit complement of integers in @var{a}.  If
+## @var{k} is omitted @code{k = log2 (bitmax) + 1} is assumed.
+##
+## @example
+## @group
+## bitcmp(7,4)
+## @result{} 8
+## dec2bin(11)
+## @result{} 1011
+## dec2bin(bitcmp(11, 6))
+## @result{} 110100
+## @end group
+## @end example
+## @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}
+## @end deftypefn
+
+## Liberally based of the version by Kai Habel from octave-forge
+
+function x = bitcmp (a, n)
+  
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2 && (! isscalar (n) || (floor (n) != n)))
+    error ("k must be a scalar integer");
+  endif
+
+  if (isa (a, "double"))
+    bmax = bitmax;
+    amax = ceil (log2 (bmax));
+  else
+    if (isa (a, "uint8"))
+      amax = 8;
+    elseif (isa (a, "uint16"))
+      amax = 16;
+    elseif (isa (a, "uint32"))
+      amax = 32;
+    elseif (isa (a, "uint64"))
+      amax = 64;
+    elseif (isa (a, "int8"))
+      amax = 8;
+    elseif (isa (a, "int16"))
+      amax = 16;
+    elseif (isa (a, "int32"))
+      amax = 32;
+    elseif (isa (a, "int64"))
+      amax = 64;
+    else
+      error ("invalid class %s", class (a));
+    endif
+    bmax = intmax (class (a));
+  endif
+
+  if (nargin == 1 || n == amax)
+    x = bitxor (a, bmax);
+  else
+    m = double (n);
+    if (any (m < 1) || any (m > amax))
+      error ("n must be in the range [1,%d]", amax);
+    endif
+    mask = bitshift (bmax, n - amax);
+    x = bitxor (bitand (a, mask), mask);
+  endif
+endfunction
+
+%!shared Amax,Bmax,A
+%! Amax=53;
+%! Bmax = bitmax;
+%! A = bitshift(Bmax,-2);
+%!assert(bitcmp(A,Amax),bitor(bitshift(1,Amax-1),bitshift(1,Amax-2)));
+%!assert(bitcmp(A,Amax-1),bitshift(1,Amax-2));
+%!assert(bitcmp(A,Amax-2),0);
+%!shared Amax,Bmax,A
+%! Amax=8;
+%! Bmax = intmax('uint8');
+%! A = bitshift(Bmax,-2);
+%!assert(bitcmp(A,Amax),bitor(bitshift(uint8(1),Amax-1),bitshift(uint8(1),Amax-2)));
+%!assert(bitcmp(A,Amax-1),bitshift(uint8(1),Amax-2));
+%!assert(bitcmp(A,Amax-2),uint8(0));
+%!shared Amax,Bmax,A
+%! Amax=16;
+%! Bmax = intmax('uint16');
+%! A = bitshift(Bmax,-2);
+%!assert(bitcmp(A,Amax),bitor(bitshift(uint16(1),Amax-1),bitshift(uint16(1),Amax-2)));
+%!assert(bitcmp(A,Amax-1),bitshift(uint16(1),Amax-2));
+%!assert(bitcmp(A,Amax-2),uint16(0));
+%!shared Amax,Bmax,A
+%! Amax=32;
+%! Bmax = intmax('uint32');
+%! A = bitshift(Bmax,-2);
+%!assert(bitcmp(A,Amax),bitor(bitshift(uint32(1),Amax-1),bitshift(uint32(1),Amax-2)));
+%!assert(bitcmp(A,Amax-1),bitshift(uint32(1),Amax-2));
+%!assert(bitcmp(A,Amax-2),uint32(0));
+%!shared Amax,Bmax,A
+%! Amax=64;
+%! Bmax = intmax('uint64');
+%! A = bitshift(Bmax,-2);
+%!assert(bitcmp(A,Amax),bitor(bitshift(uint64(1),Amax-1),bitshift(uint64(1),Amax-2)));
+%!assert(bitcmp(A,Amax-1),bitshift(uint64(1),Amax-2));
+%!assert(bitcmp(A,Amax-2),uint64(0));
diff --git a/scripts/general/bitget.m b/scripts/general/bitget.m
new file mode 100644
index 0000000..0433198
--- /dev/null
+++ b/scripts/general/bitget.m
@@ -0,0 +1,80 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{X} =} bitget (@var{a}, at var{n})
+## Return the status of bit(s) @var{n} of unsigned integers in @var{a}
+## the lowest significant bit is @var{n} = 1.
+##
+## @example
+## @group
+## bitget (100, 8:-1:1)
+## @result{} 0  1  1  0  0  1  0  0 
+## @end group
+## @end example
+## @seealso{bitand, bitor, bitxor, bitset, bitcmp, bitshift, bitmax}
+## @end deftypefn
+
+## Liberally based of the version by Kai Habel from octave-forge
+
+function X = bitget (A, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isa (A, "double"))
+    Amax = log2 (bitmax) + 1;
+    _conv = @double;
+  else
+    if (isa (A, "uint8"))
+      Amax = 8;
+      _conv = @uint8;
+    elseif (isa (A, "uint16"))
+      Amax = 16;
+      _conv = @uint16;
+    elseif (isa (A, "uint32"))
+      Amax = 32;
+      _conv = @uint32;
+    elseif (isa (A, "uint64"))
+      Amax = 64;
+      _conv = @uint64;
+    elseif (isa (A, "int8"))
+      Amax = 8;
+      _conv = @int8;
+    elseif (isa (A, "int16"))
+      Amax = 16;
+      _conv = @int16;
+    elseif (isa (A, "int32"))
+      Amax = 32;
+      _conv = @int32;
+    elseif (isa (A, "int64"))
+      Amax = 64;
+      _conv = @int64;
+    else
+      error ("invalid class %s", class (A));
+    endif
+  endif
+
+  m = double (n(:));
+  if (any (m < 1) || any (m > Amax))
+    error ("n must be in the range [1,%d]", Amax);
+  endif
+
+  X = bitand (A, bitshift (_conv (1), uint8 (n) - uint8 (1))) != _conv (0);
+endfunction
diff --git a/scripts/general/bitset.m b/scripts/general/bitset.m
new file mode 100644
index 0000000..a2b2f5f
--- /dev/null
+++ b/scripts/general/bitset.m
@@ -0,0 +1,94 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} bitset (@var{a}, @var{n})
+## @deftypefnx {Function File} {@var{x} =} bitset (@var{a}, @var{n}, @var{v})
+## Set or reset bit(s) @var{n} of unsigned integers in @var{a}.
+## @var{v} = 0 resets and @var{v} = 1 sets the bits.
+## The lowest significant bit is: @var{n} = 1
+##
+## @example
+## @group
+## dec2bin (bitset (10, 1))
+## @result{} 1011
+## @end group
+## @end example
+## @seealso{bitand, bitor, bitxor, bitget, bitcmp, bitshift, bitmax}
+## @end deftypefn
+
+## Liberally based of the version by Kai Habel from octave-forge
+
+function X = bitset (A, n, value)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    value = 1;
+  endif
+  
+  if (isa (A, "double"))
+    Bmax = bitmax;
+    Amax = log2 (Bmax) + 1;
+    _conv = @double;
+  else
+    if (isa (A, "uint8"))
+      Amax = 8;
+      _conv = @uint8;
+    elseif (isa (A, "uint16"))
+      Amax = 16;
+      _conv = @uint16;
+    elseif (isa (A, "uint32"))
+      Amax = 32;
+      _conv = @uint32;
+    elseif (isa (A, "uint64"))
+      Amax = 64;
+      _conv = @uint64;
+    elseif (isa (A, "int8"))
+      Amax = 8;
+      _conv = @int8;
+    elseif (isa (A, "int16"))
+      Amax = 16;
+      _conv = @int16;
+    elseif (isa (A, "int32"))
+      Amax = 32;
+      _conv = @int32;
+    elseif (isa (A, "int64"))
+      Amax = 64;
+      _conv = @int64;
+    else
+      error ("invalid class %s", class (A));
+    endif
+    Bmax = intmax (class (A));
+  endif
+
+  m = double (n(:));
+  if (any (m < 1) || any (m > Amax))
+    error ("n must be in the range [1,%d]", Amax);
+  endif
+
+  mask = bitshift (_conv (1), uint8 (n) - uint8 (1));
+  X = bitxor (A, bitand (A, mask));
+
+  if (value)
+    X = bitor (A, mask);
+  endif
+
+endfunction
diff --git a/scripts/general/blkdiag.m b/scripts/general/blkdiag.m
new file mode 100644
index 0000000..90c2a16
--- /dev/null
+++ b/scripts/general/blkdiag.m
@@ -0,0 +1,72 @@
+## Copyright (C) 2000, 2005, 2006, 2007, 2008 Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} blkdiag (@var{a}, @var{b}, @var{c}, @dots{})
+## Build a block diagonal matrix from @var{a}, @var{b}, @var{c}, @dots{}.
+## All the arguments must be numeric and are two-dimensional matrices or
+## scalars.
+## @seealso{diag, horzcat, vertcat}
+## @end deftypefn
+
+## Author: Daniel Calvelo
+## Modified by: William Poetra Yoga Hadisoeseno
+
+function retval = blkdiag (varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (! all (cellfun (@isnumeric, varargin)))
+    error ("blkdiag: all arguments must be numeric");
+  endif
+
+  ## Note: trailing singletons are automatically (correctly) ignored.
+  if (! all (cellfun ("ndims", varargin) == 2))
+    error ("blkdiag: all arguments must be two-dimensional matrices");
+  endif
+
+  ## size is an option for cellfun, but it's a bit different from
+  ## calling size directly.
+  tmp = cell2mat (cellfun (@size, varargin', "UniformOutput", false));
+  csz = cumsum ([0 0; tmp], 1);
+  retval = zeros (csz(end,:));
+
+  for p = 1:nargin
+    vp = varargin{p};
+    if (! isempty (vp))
+      retval((csz(p,1)+1):csz(p+1,1),(csz(p,2)+1):csz(p+1,2)) = vp;
+    endif
+  endfor
+
+endfunction
+
+# regular tests
+%!assert(blkdiag(1,ones(2),1),[1,0,0,0;0,1,1,0;0,1,1,0;0,0,0,1])
+%!assert(blkdiag([1,2],[3,4],[5,6]),[1,2,0,0,0,0;0,0,3,4,0,0;0,0,0,0,5,6])
+%!assert(blkdiag([1,2],[3;4],[5,6]),[1,2,0,0,0;0,0,3,0,0;0,0,4,0,0;0,0,0,5,6])
+%!assert(blkdiag([1,2;3,4],[5,6,7]),[1,2,0,0,0;3,4,0,0,0;0,0,5,6,7])
+# tests involving empty matrices
+%!assert(blkdiag([],[],[]),[])
+%!assert(blkdiag([],[1,2;3,4],[],5,[]),[1,2,0;3,4,0;0,0,5])
+%!assert(blkdiag(zeros(1,0,1),[1,2,3],1,0,5,zeros(0,1,1)),[0,0,0,0,0,0,0;1,2,3,0,0,0,0;0,0,0,1,0,0,0;0,0,0,0,0,0,0;0,0,0,0,0,5,0]);
+# sanity checks
+%!test
+%! A = rand (round (rand (1, 2) * 10));
+%! assert (blkdiag (A), A);
diff --git a/scripts/general/cart2pol.m b/scripts/general/cart2pol.m
new file mode 100644
index 0000000..48a59b9
--- /dev/null
+++ b/scripts/general/cart2pol.m
@@ -0,0 +1,105 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{theta}, @var{r}] =} cart2pol (@var{x}, @var{y})
+## @deftypefnx {Function File} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{x}, @var{y}, @var{z})
+## Transform Cartesian to polar or cylindrical coordinates.
+## @var{x}, @var{y} (and @var{z}) must be the same shape, or scalar.
+## @var{theta} describes the angle relative to the positive x-axis.
+## @var{r} is the distance to the z-axis (0, 0, z).
+## @seealso{pol2cart, cart2sph, sph2cart}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Adapted-by: jwe
+
+function [theta, r, z] = cart2pol (x, y, z)
+
+  if (nargin < 2 || nargin > 3)
+    error ("cart2pol: number of arguments must be 2 or 3");
+  endif
+
+  if (nargin == 2 && nargout > 2)
+    error ("cart2pol: number of output arguments must not be greater than number of input arguments");
+  endif
+
+  if ((ismatrix (x) && ismatrix (y) && (nargin == 2 || ismatrix (z)))
+      && (size_equal (x, y) || isscalar (x) || isscalar (y))
+      && (nargin == 2 || size_equal (x, z) || isscalar (x) || isscalar (z))
+      && (nargin == 2 || size_equal (y, z) || isscalar (y) || isscalar (z)))
+  
+    theta = atan2 (y, x);
+    r = sqrt (x .^ 2 + y .^ 2);
+
+  else
+    error ("cart2pol: arguments must be matrices of same size, or scalar");
+  endif
+
+endfunction
+
+%!test
+%! x = [0, 1, 2];
+%! y = 0;
+%! [t, r] = cart2pol (x, y);
+%! assert (t, [0, 0, 0]);
+%! assert (r, x);
+
+%!test
+%! x = [0, 1, 2];
+%! y = [0, 1, 2];
+%! [t, r] = cart2pol (x, y);
+%! assert (t, [0, pi/4, pi/4], sqrt(eps));
+%! assert (r, sqrt(2)*[0, 1, 2], sqrt(eps));
+
+%!test
+%! x = [0, 1, 2];
+%! y = [0, 1, 2];
+%! z = [0, 1, 2];
+%! [t, r, z2] = cart2pol (x, y, z);
+%! assert (t, [0, pi/4, pi/4], sqrt(eps));
+%! assert (r, sqrt(2)*[0, 1, 2], sqrt(eps));
+%! assert (z, z2);
+
+%!test
+%! x = [0, 1, 2];
+%! y = 0;
+%! z = 0;
+%! [t, r, z2] = cart2pol (x, y, z);
+%! assert (t, [0, 0, 0], eps);
+%! assert (r, x, eps);
+%! assert (z, z2);
+
+%!test
+%! x = 0;
+%! y = [0, 1, 2];
+%! z = 0;
+%! [t, r, z2] = cart2pol (x, y, z);
+%! assert (t, [0, 1, 1]*pi/2, eps);
+%! assert (r, y, eps);
+%! assert (z, z2);
+
+%!test
+%! x = 0;
+%! y = 0;
+%! z = [0, 1, 2];
+%! [t, r, z2] = cart2pol (x, y, z);
+%! assert (t, 0);
+%! assert (r, 0);
+%! assert (z, z2);
+
diff --git a/scripts/general/cart2sph.m b/scripts/general/cart2sph.m
new file mode 100644
index 0000000..1446ae4
--- /dev/null
+++ b/scripts/general/cart2sph.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{theta}, @var{phi}, @var{r}] =} cart2sph (@var{x}, @var{y}, @var{z})
+## Transform Cartesian to spherical coordinates.
+## @var{x}, @var{y} and @var{z} must be the same shape, or scalar.
+## @var{theta} describes the angle relative to the positive x-axis.
+## @var{phi} is the angle relative to the xy-plane.
+## @var{r} is the distance to the origin (0, 0, 0).
+## @seealso{pol2cart, cart2pol, sph2cart}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Adapted-by: jwe
+
+function [theta, phi, r] = cart2sph (x, y, z)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if ((ismatrix (x) && ismatrix (y) && ismatrix (z))
+      && (size_equal (x, y) || isscalar (x) || isscalar (y))
+      && (size_equal (x, z) || isscalar (x) || isscalar (z))
+      && (size_equal (y, z) || isscalar (y) || isscalar (z)))
+
+    theta = atan2 (y, x);
+    phi = atan2 (z, sqrt (x .^ 2 + y .^ 2));
+    r = sqrt (x .^ 2 + y .^ 2 + z .^ 2);
+
+  else
+    error ("cart2sph: arguments must be matrices of same size, or scalar");
+  endif
+
+endfunction
+
+%!test
+%! x = [0, 1, 2];
+%! y = [0, 1, 2];
+%! z = [0, 1, 2];
+%! [t, p, r] = cart2sph (x, y, z);
+%! assert (t, [0, pi/4, pi/4], eps);
+%! assert (p, [0, 1, 1]*atan(sqrt(0.5)), eps);
+%! assert (r, [0, 1, 2]*sqrt(3), eps);
+
+%!test
+%! x = 0;
+%! y = [0, 1, 2];
+%! z = [0, 1, 2];
+%! [t, p, r] = cart2sph (x, y, z);
+%! assert (t, [0, 1, 1] * pi/2, eps);
+%! assert (p, [0, 1, 1] * pi/4, eps);
+%! assert (r, [0, 1, 2] * sqrt(2), eps);
+
+%!test
+%! x = [0, 1, 2];
+%! y = 0;
+%! z = [0, 1, 2];
+%! [t, p, r] = cart2sph (x, y, z);
+%! assert (t, [0, 0, 0]);
+%! assert (p, [0, 1, 1] * pi/4);
+%! assert (r, [0, 1, 2] * sqrt(2));
+
+%!test
+%! x = [0, 1, 2];
+%! y = [0, 1, 2];
+%! z = 0;
+%! [t, p, r] = cart2sph (x, y, z);
+%! assert (t, [0, 1, 1] * pi/4);
+%! assert (p, [0, 0, 0]);
+%! assert (r, [0, 1, 2] * sqrt(2));
+
diff --git a/scripts/general/cell2mat.m b/scripts/general/cell2mat.m
new file mode 100644
index 0000000..46b2417
--- /dev/null
+++ b/scripts/general/cell2mat.m
@@ -0,0 +1,94 @@
+## Copyright (C) 2005, 2006, 2007, 2008 Laurent Mazet
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{m} =} cell2mat (@var{c})
+## Convert the cell array @var{c} into a matrix by concatenating all
+## elements of @var{c} into a hyperrectangle.  Elements of @var{c} must
+## be numeric, logical or char, and @code{cat} must be able to
+## concatenate them together.
+## @seealso{mat2cell, num2cell}
+## @end deftypefn
+
+function m = cell2mat (c)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! iscell (c))
+    error ("cell2mat: c is not a cell array");
+  endif
+  
+  nb = numel (c);
+
+  if (nb == 0)
+    m = [];
+  elseif (nb == 1)
+    elt = c{1};
+    if (isnumeric (elt) || ischar (elt) || islogical (elt))
+      m = elt;
+    elseif (iscell (elt))
+      m = cell2mat (elt);
+    else
+      error ("cell2mat: all elements of cell array must be numeric, logical or char");
+    endif
+  elseif (ndims (c) == 2)
+    nr = rows (c);
+    nc = columns (c);
+    if (nc > nr)
+      c1 = cell (nr, 1);
+      for i = 1 : nr
+	c1{i} = [c{i : nr : end}];
+      endfor
+      m = cat (1, c1 {:});
+    else
+      c1 = cell (nc, 1);
+      for i = 1 : nc
+	c1{i} = cat (1, c{(i - 1) * nr  + [1 : nr]});
+      endfor
+      m = [c1{:}];
+    endif
+  else
+    ## n dimensions case
+    for k = ndims (c):-1:2,
+      sz = size (c);
+      sz(end) = 1;
+      c1 = cell (sz);
+      for i = 1:(prod (sz))
+        c1{i} = cat (k, c{i:(prod (sz)):end});
+      endfor
+      c = c1;
+    endfor
+    m = cat (1, c1{:});
+  endif
+
+endfunction
+
+## Tests
+%!shared C, D, E, F
+%! C = {[1], [2 3 4]; [5; 9], [6 7 8; 10 11 12]};
+%! D = C; D(:,:,2) = C;
+%! E = [1 2 3 4; 5 6 7 8; 9 10 11 12];
+%! F = E; F(:,:,2) = E;
+%!assert (cell2mat (C), E);
+%!assert (cell2mat (D), F);
+## Demos
+%!demo
+%! C = {[1], [2 3 4]; [5; 9], [6 7 8; 10 11 12]};
+%! cell2mat (C)
diff --git a/scripts/general/celldisp.m b/scripts/general/celldisp.m
new file mode 100644
index 0000000..e5c159f
--- /dev/null
+++ b/scripts/general/celldisp.m
@@ -0,0 +1,62 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} celldisp (@var{c}, @var{name})
+## Recursively display the contents of a cell array.  By default the values
+## are displayed with the name of the variable @var{c}.  However, this name
+## can be replaced with the variable @var{name}.
+## @seealso{disp}
+## @end deftypefn
+
+## This is ugly, but seems to be what matlab does..
+
+function celldisp (c, name)
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (! iscell (c))
+    error ("celldisp: argument must be a cell array");
+  endif
+
+  if (nargin == 1)
+    name = inputname (1);
+  endif
+
+  for i = 1: numel (c)
+    if (iscell (c{i}))
+      celldisp (c{i}, sprintf ("%s{%s}", name, indices (size (c), i)));
+    else
+      disp (sprintf ("%s{%s} = \n", name, indices (size (c), i)));
+      disp (c{i});
+      disp ("");
+    endif
+  endfor
+endfunction
+
+function s = indices (dv, i)
+  if (sum (dv != 1) > 1)
+    c = cell (size (dv));
+    [c{:}] = ind2sub (dv, i);
+    s = sprintf("%i,", c{:});
+    s(end) = [];
+  else
+    s = sprintf("%i", i);
+  endif
+endfunction
diff --git a/scripts/general/cellidx.m b/scripts/general/cellidx.m
new file mode 100644
index 0000000..c9c15c9
--- /dev/null
+++ b/scripts/general/cellidx.m
@@ -0,0 +1,100 @@
+## Copyright (C) 2000, 2004, 2005, 2006, 2007, 2008, 2009
+##               Auburn University.  All rights reserved.
+##
+## This file is part of Octave.
+##
+## Octave program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{idxvec}, @var{errmsg}] =} cellidx (@var{listvar}, @var{strlist})
+## Return indices of string entries in @var{listvar} that match strings
+## in @var{strlist}.
+##
+## Both @var{listvar} and @var{strlist} may be passed as strings or
+## string matrices.  If they are passed as string matrices, each entry
+## is processed by @code{deblank} prior to searching for the entries.
+##
+## The first output is the vector of indices in @var{listvar}.
+##
+## If @var{strlist} contains a string not in @var{listvar}, then
+## an error message is returned in @var{errmsg}.  If only one output
+## argument is requested, then @var{cellidx} prints @var{errmsg} to the
+## screen and exits with an error.
+## @end deftypefn
+
+function [idxvec,errmsg]  = cellidx (listvar, strlist)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (ischar (strlist))
+    tmp = strlist;
+    strlist = {};
+    for kk = 1:rows(tmp)
+      strlist{kk} = deblank (tmp(kk,:));
+    endfor
+  endif
+
+  if (ischar (listvar))
+    tmp = listvar;
+    listvar = {};
+    for kk = 1:rows(tmp)
+      listvar{kk} = deblank (tmp(kk,:));
+    endfor
+  endif
+
+  ## initialize size of idxvec (for premature return)
+  idxvec = zeros (length(strlist), 1);
+
+  errmsg = "";
+  if (! iscellstr (listvar))
+    errmsg = "listvar must be a list of strings";
+  elseif (! iscellstr (strlist))
+    errmsg = "strlist must be a list of strings";
+  endif
+
+  if (length (errmsg))
+    if (nargout < 2)
+      error (errmsg);
+    else
+      return;
+    endif
+  endif
+
+  nsigs = length(listvar);
+  for idx = 1:length(strlist)
+    signame = strlist{idx};
+    for jdx = 1:nsigs
+      if (strcmp (signame, listvar{jdx}))
+	if (idxvec(idx) != 0)
+	  warning ("Duplicate signal name %s (%d,%d)\n",
+		   listvar{jdx}, jdx, idxvec(idx));
+	else
+	  idxvec(idx) = jdx;
+	endif
+      endif
+    endfor
+    if (idxvec(idx) == 0)
+      errmsg = sprintf ("Did not find %s", signame);
+      if (nargout == 1)
+	error (errmsg);
+      else
+	break;
+      endif
+    endif
+  endfor
+
+endfunction
diff --git a/scripts/general/circshift.m b/scripts/general/circshift.m
new file mode 100644
index 0000000..007186a
--- /dev/null
+++ b/scripts/general/circshift.m
@@ -0,0 +1,96 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} circshift (@var{x}, @var{n})
+## Circularly shifts the values of the array @var{x}.  @var{n} must be
+## a vector of integers no longer than the number of dimensions in 
+## @var{x}.  The values of @var{n} can be either positive or negative,
+## which determines the direction in which the values or @var{x} are
+## shifted.  If an element of @var{n} is zero, then the corresponding
+## dimension of @var{x} will not be shifted.  For example
+##
+## @example
+## @group
+## x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+## circshift (x, 1)
+## @result{}  7, 8, 9
+##     1, 2, 3
+##     4, 5, 6
+## circshift (x, -2)
+## @result{}  7, 8, 9
+##     1, 2, 3
+##     4, 5, 6
+## circshift (x, [0,1])
+## @result{}  3, 1, 2
+##     6, 4, 5
+##     9, 7, 8
+## @end group
+## @end example
+## @seealso {permute, ipermute, shiftdim}
+## @end deftypefn
+
+function y = circshift (x, n)
+
+  if (nargin == 2)
+    if (isempty (x))
+      y = x;
+    else
+      nd = ndims (x);
+      sz = size (x);
+
+      if (! isvector (n) && length (n) > nd)
+	error ("circshift: n must be a vector, no longer than the number of dimension in x");
+      endif
+    
+      if (any (n != floor (n)))
+	error ("circshift: all values of n must be integers");
+      endif
+
+      idx = cell ();
+      for i = 1:length (n);
+	nn = n(i);
+	if (nn < 0)
+	  while (sz(i) <= -nn)
+	    nn = nn + sz(i);
+	  endwhile
+	  idx{i} = [(1-nn):sz(i), 1:-nn];
+	else
+	  while (sz(i) <= nn)
+	    nn = nn - sz(i);
+	  endwhile
+	  idx{i} = [(sz(i)-nn+1):sz(i), 1:(sz(i)-nn)];
+	endif
+      endfor
+      for i = (length(n) + 1) : nd
+	idx{i} = 1:sz(i);
+      endfor
+      y = x(idx{:});
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
+
+%!shared x
+%! x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+
+%!assert (circshift (x, 1), [7, 8, 9; 1, 2, 3; 4, 5, 6])
+%!assert (circshift (x, -2), [7, 8, 9; 1, 2, 3; 4, 5, 6])
+%!assert (circshift (x, [0, 1]), [3, 1, 2; 6, 4, 5; 9, 7, 8]);
+%!assert (circshift ([],1), [])
diff --git a/scripts/general/colon.m b/scripts/general/colon.m
new file mode 100644
index 0000000..75eee11
--- /dev/null
+++ b/scripts/general/colon.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{r} =} colon (@var{a}, @var{b})
+## @deftypefnx {Function File} {@var{r} =} colon (@var{a}, @var{b}, @var{c})
+## Method of a class to construct a range with the @code{:} operator.  For
+## example.
+##
+## @example
+## @group
+## a = myclass (@dots{})
+## b = myclass (@dots{})
+## c = a : b
+## @end group
+## @end example
+##
+## @seealso{class, subsref, subsasgn}
+## @end deftypefn
+
+function r = colon (varargin)
+  error ("colon: not defined for class \"%s\"", class(varargin{1}));
+endfunction
diff --git a/scripts/general/common_size.m b/scripts/general/common_size.m
new file mode 100644
index 0000000..5dfb049
--- /dev/null
+++ b/scripts/general/common_size.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2005, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{err}, @var{y1}, @dots{}] =} common_size (@var{x1}, @dots{})
+## Determine if all input arguments are either scalar or of common
+## size.  If so, @var{err} is zero, and @var{yi} is a matrix of the
+## common size with all entries equal to @var{xi} if this is a scalar or
+## @var{xi} otherwise.  If the inputs cannot be brought to a common size,
+## errorcode is 1, and @var{yi} is @var{xi}.  For example,
+##
+## @example
+## @group
+## [errorcode, a, b] = common_size ([1 2; 3 4], 5)
+##      @result{} errorcode = 0
+##      @result{} a = [ 1, 2; 3, 4 ]
+##      @result{} b = [ 5, 5; 5, 5 ]
+## @end group
+## @end example
+##
+## @noindent
+## This is useful for implementing functions where arguments can either
+## be scalars or of common size.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 15 October 1994
+## Adapted-By: jwe
+
+function [errorcode, varargout] = common_size (varargin)
+
+  if (nargin < 2)
+    error ("common_size: only makes sense if nargin >= 2");
+  endif
+
+  len = 2;
+  for i = 1 : nargin
+    sz =  size (varargin{i});
+    if (length (sz) < len)
+      s(i,:) = [sz, ones(1,len - length(sz))];
+    else
+      if (length (sz) > len)
+	if (i > 1)
+	  s = [s, ones(size(s,1), length(sz) - len)];
+	endif
+	len = length (sz);
+      endif
+      s(i,:) = sz;
+    endif
+  endfor
+
+  m = max (s);
+  if (any (any ((s != 1)') & any ((s != ones (nargin, 1) * m)')))
+    errorcode = 1;
+    varargout = varargin;
+  else
+    errorcode = 0;
+    for i = 1 : nargin
+      varargout{i} = varargin{i};
+      if (prod (s(i,:)) == 1)
+	varargout{i} *= ones (m);
+      endif
+    endfor
+  endif
+
+endfunction
diff --git a/scripts/general/cplxpair.m b/scripts/general/cplxpair.m
new file mode 100644
index 0000000..b9366b6
--- /dev/null
+++ b/scripts/general/cplxpair.m
@@ -0,0 +1,164 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} cplxpair (@var{z})
+## @deftypefnx {Function File} {} cplxpair (@var{z}, @var{tol})
+## @deftypefnx {Function File} {} cplxpair (@var{z}, @var{tol}, @var{dim})
+## Sort the numbers @var{z} into complex conjugate pairs ordered by 
+## increasing real part.  Place the negative imaginary complex number
+## first within each pair.  Place all the real numbers (those with
+## @code{abs (imag (@var{z}) / @var{z}) < @var{tol})}) after the
+## complex pairs.
+##
+## If @var{tol} is unspecified the default value is 100*@code{eps}.
+##
+## By default the complex pairs are sorted along the first non-singleton
+## dimension of @var{z}.  If @var{dim} is specified, then the complex
+## pairs are sorted along this dimension.
+##
+## Signal an error if some complex numbers could not be paired.  Signal an
+## error if all complex numbers are not exact conjugates (to within
+## @var{tol}).  Note that there is no defined order for pairs with identical
+## real parts but differing imaginary parts.
+##
+## @c Set example in small font to prevent overfull line
+## @smallexample
+## cplxpair (exp(2i*pi*[0:4]'/5)) == exp(2i*pi*[3; 2; 4; 1; 0]/5)
+## @end smallexample
+## @end deftypefn
+
+## FIXME: subsort returned pairs by imaginary magnitude
+## FIXME: Why doesn't exp(2i*pi*[0:4]'/5) produce exact conjugates. Does
+## FIXME:    it in Matlab?  The reason is that complex pairs are supposed
+## FIXME:    to be exact conjugates, and not rely on a tolerance test.
+
+## 2006-05-12 David Bateman - Modified for NDArrays
+
+function y = cplxpair (z, tol, dim)
+
+  if nargin < 1 || nargin > 3
+    print_usage ();
+  endif
+
+  if (length (z) == 0)
+    y = zeros (size (z));
+    return; 
+  endif
+
+  if (nargin < 2 || isempty (tol))
+    if (isa (z, "single"))
+      tol = 100 * eps("single");
+    else
+      tol = 100*eps; 
+    endif
+  endif
+
+  nd = ndims (z);
+  orig_dims = size (z);
+  if (nargin < 3)
+    ## Find the first singleton dimension.
+    dim = 0;
+    while (dim < nd && orig_dims(dim+1) == 1)
+      dim++;
+    endwhile
+    dim++;
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    dim = floor(dim);
+    if (dim < 1 || dim > nd)
+      error ("cplxpair: invalid dimension along which to sort");
+    endif
+  endif
+
+  ## Move dimension to treat first, and convert to a 2-D matrix.
+  perm = [dim:nd, 1:dim-1];
+  z = permute (z, perm);
+  sz = size (z);
+  n = sz (1);
+  m = prod (sz) / n;
+  z = reshape (z, n, m);
+
+  ## Sort the sequence in terms of increasing real values.
+  [q, idx] = sort (real (z), 1);
+  z = z(idx + n * ones (n, 1) * [0:m-1]);
+
+  ## Put the purely real values at the end of the returned list.
+  cls = "double";
+  if (isa (z, "single"))
+    cls = "single";
+  endif
+  [idxi, idxj] = find (abs (imag (z)) ./ (abs (z) + realmin(cls)) < tol);
+  q = sparse (idxi, idxj, 1, n, m);
+  nr = sum (q, 1);
+  [q, idx] = sort (q, 1);
+  z = z(idx);
+  y = z;
+
+  ## For each remaining z, place the value and its conjugate at the
+  ## start of the returned list, and remove them from further
+  ## consideration.
+  for j = 1:m
+    p = n - nr(j);
+    for i = 1:2:p
+      if (i+1 > p)
+	error ("cplxpair could not pair all complex numbers");
+      endif
+      [v, idx] = min (abs (z(i+1:p) - conj (z(i))));
+      if (v > tol)
+	error ("cplxpair could not pair all complex numbers");
+      endif
+      if (imag (z(i)) < 0)
+	y([i, i+1]) = z([i, idx+i]);
+      else
+	y([i, i+1]) = z([idx+i, i]);
+      endif
+      z(idx+i) = z(i+1);
+    endfor
+  endfor
+
+  ## Reshape the output matrix.
+  y = ipermute (reshape (y, sz), perm);
+
+endfunction
+
+%!demo
+%! [ cplxpair(exp(2i*pi*[0:4]'/5)), exp(2i*pi*[3; 2; 4; 1; 0]/5) ]
+
+%!assert (isempty(cplxpair([])));
+%!assert (cplxpair(1), 1)
+%!assert (cplxpair([1+1i, 1-1i]), [1-1i, 1+1i])
+%!assert (cplxpair([1+1i, 1+1i, 1, 1-1i, 1-1i, 2]), \
+%!	  [1-1i, 1+1i, 1-1i, 1+1i, 1, 2])
+%!assert (cplxpair([1+1i; 1+1i; 1; 1-1i; 1-1i; 2]), \
+%!	  [1-1i; 1+1i; 1-1i; 1+1i; 1; 2]) 
+%!assert (cplxpair([0, 1, 2]), [0, 1, 2]);
+
+%!shared z
+%! z=exp(2i*pi*[4; 3; 5; 2; 6; 1; 0]/7);
+%!assert (cplxpair(z(randperm(7))), z);
+%!assert (cplxpair(z(randperm(7))), z);
+%!assert (cplxpair(z(randperm(7))), z);
+%!assert (cplxpair([z(randperm(7)),z(randperm(7))]),[z,z])
+%!assert (cplxpair([z(randperm(7)),z(randperm(7))],[],1),[z,z])
+%!assert (cplxpair([z(randperm(7)).';z(randperm(7)).'],[],2),[z.';z.'])
+
+%!## tolerance test
+%!assert (cplxpair([1i, -1i, 1+(1i*eps)],2*eps), [-1i, 1i, 1+(1i*eps)]);
diff --git a/scripts/general/cumtrapz.m b/scripts/general/cumtrapz.m
new file mode 100644
index 0000000..d880bbf
--- /dev/null
+++ b/scripts/general/cumtrapz.m
@@ -0,0 +1,113 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{z} =} cumtrapz (@var{y})
+## @deftypefnx {Function File} {@var{z} =} cumtrapz (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{z} =} cumtrapz (@dots{}, @var{dim})
+## 
+## Cumulative numerical integration using trapezoidal method.
+## @code{cumtrapz (@var{y})} computes the cumulative integral of the 
+## @var{y} along the first non-singleton dimension.  If the argument 
+## @var{x} is omitted a equally spaced vector is assumed.  @code{cumtrapz 
+## (@var{x}, @var{y})} evaluates the cumulative integral with respect 
+## to @var{x}.
+##  
+## @seealso{trapz,cumsum}
+## @end deftypefn
+
+## Author:	Kai Habel <kai.habel at gmx.de>
+##
+## also: June 2000 Paul Kienzle (fixes,suggestions) 
+## 2006-05-12 David Bateman - Modified for NDArrays
+
+function z = cumtrapz (x, y, dim)	
+
+  if (nargin < 1) || (nargin > 3)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+
+  have_x = false;
+  have_dim = false;
+  if (nargin == 3)
+    have_x = true;
+    have_dim = true;
+  endif
+  if (nargin == 2)
+    if (! size_equal (x, y) && isscalar (y))
+      dim = y;
+      have_dim = true;
+    else
+      have_x = true;
+    endif
+  endif
+
+  if (! have_dim)
+    ## Find the first singleton dimension.
+    dim = 0;
+    while (dim < nd && sz(dim+1) == 1)
+      dim++;
+    endwhile
+    dim++;
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    dim = floor (dim);
+    if (dim < 1 || dim > nd)
+      error ("cumtrapz: invalid dimension along which to sort");
+    endif
+  endif
+
+  n = sz(dim);
+  idx1 = cell ();
+  for i = 1:nd
+    idx1{i} = 1:sz(i);
+  endfor
+  idx2 = idx1;
+  idx1{dim} = 2 : n;	
+  idx2{dim} = 1 : (n - 1);
+
+  if (! have_x)
+    z = 0.5 * cumsum (x(idx1{:}) + x(idx2{:}), dim);
+  else
+    if (! size_equal (x, y))
+      error ("cumtrapz: x and y must have same shape");
+    endif
+    z = 0.5 * cumsum ((x(idx1{:}) - x(idx2{:})) .* 
+		      (y(idx1{:}) + y(idx2{:})), dim);
+  endif
+
+  sz(dim) = 1;
+  z = cat (dim, zeros (sz), z);
+
+endfunction
+
+%!shared x1,x2,y
+%! x1 = [0,0,0;2,2,2];
+%! x2 = [0,2,4;0,2,4];
+%! y = [1,2,3;4,5,6];
+%!assert (cumtrapz(y),[0,0,0;2.5,3.5,4.5])
+%!assert (cumtrapz(x1,y),[0,0,0;5,7,9])
+%!assert (cumtrapz(y,1),[0,0,0;2.5,3.5,4.5])
+%!assert (cumtrapz(x1,y,1),[0,0,0;5,7,9])
+%!assert (cumtrapz(y,2),[0,1.5,4;0,4.5,10])
+%!assert (cumtrapz(x2,y,2),[0,3,8;0,9,20])
diff --git a/scripts/general/dblquad.m b/scripts/general/dblquad.m
new file mode 100644
index 0000000..d3c5005
--- /dev/null
+++ b/scripts/general/dblquad.m
@@ -0,0 +1,68 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dblquad (@var{f}, @var{xa}, @var{xb}, @var{ya}, @var{yb}, @var{tol}, @var{quadf}, @dots{})
+## Numerically evaluate a double integral.  The function over with to
+## integrate is defined by @code{@var{f}}, and the interval for the
+## integration is defined by @code{[@var{xa}, @var{xb}, @var{ya},
+## @var{yb}]}.  The function @var{f} must accept a vector @var{x} and a
+## scalar @var{y}, and return a vector of the same length as @var{x}. 
+##
+## If defined, @var{tol} defines the absolute tolerance to which to
+## which to integrate each sub-integral.
+##
+## Additional arguments, are passed directly to @var{f}.  To use the default
+## value for @var{tol} one may pass an empty matrix.
+## @seealso{triplequad, quad, quadv, quadl, quadgk, trapz}
+## @end deftypefn
+
+function q = dblquad(f, xa, xb, ya, yb, tol, quadf, varargin) 
+  if (nargin < 5)
+    print_usage ();
+  endif
+  if (nargin < 6 || isempty (tol))
+    tol = 1e-6; 
+  endif
+  if (nargin < 7 || isempty (quadf))
+    quadf = @quadgk; 
+  endif
+
+  inner = @__dblquad_inner__;
+  if (ischar (f))
+    f = @(x,y) feval (f, x, y, varargin{:});
+    varargin = {};
+  endif
+
+  q = feval (quadf, @(y) inner (y, f, xa, xb, tol, quadf,
+				varargin{:}), ya, yb, tol);
+endfunction
+
+function q = __dblquad_inner__ (y, f, xa, xb, tol, quadf, varargin)
+  q = zeros (size(y));
+  for i = 1 : length (y)
+    q(i) = feval (quadf, @(x) f(x, y(i), varargin{:}), xa, xb, tol);
+  endfor
+endfunction
+
+%% Nasty integrand to show quadgk off
+%!assert (dblquad (@(x,y) 1 ./ (x+y), 0, 1, 0, 1), 2*log(2), 1e-6)
+
+%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, [],  @quadgk), pi * erf(1).^2, 1e-6)
+%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, [],  @quadl), pi * erf(1).^2, 1e-6)
+%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, [],  @quadv), pi * erf(1).^2, 1e-6)
diff --git a/scripts/general/deal.m b/scripts/general/deal.m
new file mode 100644
index 0000000..f875760
--- /dev/null
+++ b/scripts/general/deal.m
@@ -0,0 +1,83 @@
+## Copyright (C) 1998, 2004, 2005, 2006, 2007 Ariel Tankus
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} deal (@var{a})
+## @deftypefnx {Function File} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} deal (@var{a1}, @var{a2}, @dots{}, @var{an})
+##
+## Copy the input parameters into the corresponding output parameters.
+## If only one input parameter is supplied, its value is copied to each
+## of the outputs.
+##
+## For example,
+##
+## @example
+## [a, b, c] = deal (x, y, z);
+## @end example
+##
+## @noindent
+## is equivalent to
+##
+## @example
+## @group
+## a = x;
+## b = y;
+## c = z;
+## @end group
+## @end example
+##
+## @noindent
+## and
+##
+## @example
+## [a, b, c] = deal (x);
+## @end example
+##
+## @noindent
+## is equivalent to
+##
+## @example
+## a = b = c = x;
+## @end example
+## @end deftypefn
+
+## Author: Ariel Tankus
+## Author: Paul Kienzle and Etienne Grossman
+## Created: 13.11.98
+## Adapted-by: jwe
+
+function [varargout] = deal (varargin)
+
+  if (nargin == 0)
+    print_usage ();
+  elseif (nargin == 1 || nargin == nargout)
+    varargout(1:nargout) = varargin;
+  else
+    error ("deal: nargin > 1 and nargin != nargout");
+  endif
+
+endfunction
+
+%!test
+%! [a,b]=deal(1,2);
+%! assert(a,1);
+%! assert(b,2);
+%!test
+%! [a,b]=deal(1);
+%! assert(a,1);
+%! assert(b,1);
diff --git a/scripts/general/del2.m b/scripts/general/del2.m
new file mode 100644
index 0000000..7db87e1
--- /dev/null
+++ b/scripts/general/del2.m
@@ -0,0 +1,159 @@
+## Copyright (C) 2000, 2007, 2008, 2009 Kai Habel
+## Copyright (C) 2007  David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{d} =} del2 (@var{m})
+## @deftypefnx {Function File} {@var{d} =} del2 (@var{m}, @var{h})
+## @deftypefnx {Function File} {@var{d} =} del2 (@var{m}, @var{dx}, @var{dy}, @dots{})
+##
+## Calculate the discrete Laplace
+## @tex
+## operator $( \nabla^2 )$.
+## @end tex
+## @ifnottex
+## operator.
+## @end ifnottex
+## For a 2-dimensional matrix @var{m} this is defined as
+##
+## @tex
+## $$d = {1 \over 4} \left( {d^2 \over dx^2} M(x,y) + {d^2 \over dy^2} M(x,y) \right)$$
+## @end tex
+## @ifnottex
+## @example
+## @group
+##       1    / d^2            d^2         \
+## D  = --- * | ---  M(x,y) +  ---  M(x,y) | 
+##       4    \ dx^2           dy^2        /
+## @end group
+## @end example
+## @end ifnottex
+##
+## For N-dimensional arrays the sum in parentheses is expanded to include second derivatives 
+## over the additional higher dimensions.
+##
+## The spacing between evaluation points may be defined by @var{h}, which is a
+## scalar defining the equidistant spacing in all dimensions.  Alternatively, 
+## the spacing in each dimension may be defined separately by @var{dx}, @var{dy},
+## etc.  A scalar spacing argument defines equidistant spacing, whereas a vector
+## argument can be used to specify variable spacing.  The length of the spacing vectors
+## must match the respective dimension of @var{m}.  The default spacing value
+## is 1.
+##
+## At least 3 data points are needed for each dimension.  Boundary points are
+## calculated from the linear extrapolation of interior points.
+##
+## @seealso{gradient, diff}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function D = del2 (M, varargin)
+  
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  nd = ndims (M);
+  sz = size (M);
+  dx = cell (1, nd);
+  if (nargin == 2 || nargin == 1)
+    if (nargin == 1)
+      h = 1;
+    else
+      h = varargin{1};
+    endif
+    for i = 1 : nd
+      if (isscalar (h))
+	dx{i} = h * ones (sz (i), 1);
+      else
+	if (length (h) == sz (i))
+	  dx{i} = diff (h)(:);
+	else
+	  error ("dimensionality mismatch in %d-th spacing vector", i);
+	endif
+      endif
+    endfor
+  elseif (nargin - 1 == nd)
+    ## Reverse dx{1} and dx{2} as the X-dim is the 2nd dim of the ND array
+    tmp = varargin{1};
+    varargin{1} = varargin{2};
+    varargin{2} = tmp;
+
+    for i = 1 : nd
+      if (isscalar (varargin{i}))
+	dx{i} = varargin{i} * ones (sz (i), 1);
+      else
+	if (length (varargin{i}) == sz (i))
+	  dx{i} = diff (varargin{i})(:);
+	else
+	  error ("dimensionality mismatch in %d-th spacing vector", i);
+	endif
+      endif
+    endfor
+  else
+    print_usage ();
+  endif
+
+  idx = cell (1, nd);
+  for i = 1: nd
+    idx{i} = ":";
+  endfor
+
+  D = zeros (sz);
+  for i = 1: nd
+    if (sz(i) >= 3)
+      DD = zeros (sz);
+      idx1 = idx2 = idx3 = idx;
+
+      ## interior points
+      idx1{i} = 1 : sz(i) - 2;
+      idx2{i} = 2 : sz(i) - 1;
+      idx3{i} = 3 : sz(i);
+      szi = sz;
+      szi (i) = 1;
+
+      h1 = repmat (shiftdim (dx{i}(1 : sz(i) - 2), 1 - i), szi);
+      h2 = repmat (shiftdim (dx{i}(2 : sz(i) - 1), 1 - i), szi);
+      DD(idx2{:}) = ((M(idx1{:}) - M(idx2{:})) ./ h1 + ...
+		     (M(idx3{:}) - M(idx2{:})) ./ h2) ./ (h1 + h2);
+
+      ## left and right boundary
+      if (sz(i) == 3)
+	DD(idx1{:}) = DD(idx3{:}) = DD(idx2{:});
+      else
+	idx1{i} = 1;
+	idx2{i} = 2;
+	idx3{i} = 3;
+	DD(idx1{:}) = (dx{i}(1) + dx{i}(2)) / dx{i}(2) * DD (idx2{:}) - ...
+	    dx{i}(1) / dx{i}(2) * DD (idx3{:});
+
+	idx1{i} = sz(i);
+	idx2{i} = sz(i) - 1;
+	idx3{i} = sz(i) - 2;
+	DD(idx1{:}) =  (dx{i}(sz(i) - 1) + dx{i}(sz(i) - 2)) / ...
+	    dx{i}(sz(i) - 2) * DD (idx2{:}) - ...
+	    dx{i}(sz(i) - 1) / dx{i}(sz(i) - 2) * DD (idx3{:});
+      endif
+
+      D += DD;
+    endif
+  endfor
+
+  D = D ./ nd;
+endfunction
diff --git a/scripts/general/diff.m b/scripts/general/diff.m
new file mode 100644
index 0000000..0009730
--- /dev/null
+++ b/scripts/general/diff.m
@@ -0,0 +1,146 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007,
+##               2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} diff (@var{x}, @var{k}, @var{dim})
+## If @var{x} is a vector of length @var{n}, @code{diff (@var{x})} is the
+## vector of first differences
+## @tex
+##  $x_2 - x_1, \ldots{}, x_n - x_{n-1}$.
+## @end tex
+## @ifnottex
+##  @var{x}(2) - @var{x}(1), @dots{}, @var{x}(n) - @var{x}(n-1).
+## @end ifnottex
+##
+## If @var{x} is a matrix, @code{diff (@var{x})} is the matrix of column
+## differences along the first non-singleton dimension.
+##
+## The second argument is optional.  If supplied, @code{diff (@var{x},
+## @var{k})}, where @var{k} is a non-negative integer, returns the
+## @var{k}-th differences.  It is possible that @var{k} is larger than
+## then first non-singleton dimension of the matrix.  In this case,
+## @code{diff} continues to take the differences along the next
+## non-singleton dimension.
+##
+## The dimension along which to take the difference can be explicitly
+## stated with the optional variable @var{dim}.  In this case the 
+## @var{k}-th order differences are calculated along this dimension.
+## In the case where @var{k} exceeds @code{size (@var{x}, @var{dim})}
+## then an empty matrix is returned.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 2 February 1995
+## Adapted-By: jwe
+
+function x = diff (x, k, dim)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 2 || isempty(k))
+    k = 1;
+  else
+    if (! (isscalar (k) && k == round (k) && k >= 0))
+      error ("diff: k must be a nonnegative integer");
+    elseif (k == 0)
+      return;
+    endif
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin != 3)
+    %% Find the first non-singleton dimension
+    dim  = 1;
+    while (dim < nd + 1 && sz (dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim)) && dim > 0 && 
+	dim < (nd + 1))
+      error ("diff: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (ischar (x))
+    error ("diff: symbolic differentiation not (yet) supported");
+  endif
+
+
+  if (nargin == 3)
+    if (sz (dim) <= k)
+      sz(dim) = 0;
+      x = zeros (sz);
+    else
+      n = sz (dim);
+      idx1 = cell ();
+      for i = 1:nd
+	idx1{i} = 1:sz(i);
+      endfor
+      idx2 = idx1;
+      for i = 1 : k;
+	idx1{dim} = 2 : (n - i + 1);	
+	idx2{dim} = 1 : (n - i);	
+	x = x(idx1{:}) - x(idx2{:});
+      endfor
+    endif
+  else
+    if (sum (sz - 1) < k)
+      x = [];
+    else
+      idx1 = cell ();
+      for i = 1:nd
+	idx1{i} = 1:sz(i);
+      endfor
+      idx2 = idx1;
+      while (k)
+	n = sz (dim);
+	for i = 1 : min (k, n - 1)
+	  idx1{dim} = 2 : (n - i + 1);	
+	  idx2{dim} = 1 : (n - i);	
+	  x = x(idx1{:}) - x(idx2{:});
+	endfor
+	idx1{dim} = idx2{dim} = 1;
+	k = k - min (k, n - 1);
+	dim = dim + 1;
+      endwhile
+    endif
+  endif
+
+endfunction
+
+%!assert((diff ([1, 2, 3, 4]) == [1, 1, 1]
+%! && diff ([1, 3, 7, 19], 2) == [2, 8]
+%! && diff ([1, 2; 5, 4; 8, 7; 9, 6; 3, 1]) == [4, 2; 3, 3; 1, -1; -6, -5]
+%! && diff ([1, 2; 5, 4; 8, 7; 9, 6; 3, 1], 3) == [-1, -5; -5, 0]
+%! && isempty (diff (1))));
+
+%!error diff ([1, 2; 3, 4], -1);
+
+%!error diff ("foo");
+
+%!error diff ();
+
+%!error diff (1, 2, 3, 4);
+
diff --git a/scripts/general/display.m b/scripts/general/display.m
new file mode 100644
index 0000000..6bd5b6a
--- /dev/null
+++ b/scripts/general/display.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} display (@var{a})
+## Display the contents of an object.  If @var{a} is an object of the
+## class "myclass", then @code{display} is called in a case like
+##
+## @example
+## myclass (@dots{})
+## @end example
+##
+## @noindent
+## where Octave is required to display the contents of a variable of the
+## type "myclass".
+##
+## @seealso{class, subsref, subsasgn}
+## @end deftypefn
+
+function idx = display (a)
+  error ("display: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/scripts/general/flipdim.m b/scripts/general/flipdim.m
new file mode 100644
index 0000000..cf1d874
--- /dev/null
+++ b/scripts/general/flipdim.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} flipdim (@var{x}, @var{dim})
+## Return a copy of @var{x} flipped about the dimension @var{dim}.
+## For example
+##
+## @example
+## @group
+## flipdim ([1, 2; 3, 4], 2)
+##      @result{}  2  1
+##          4  3
+## @end group
+## @end example
+## @seealso{fliplr, flipud, rot90, rotdim}
+## @end deftypefn
+
+## Author: David Bateman
+
+function y = flipdim (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin == 1)
+    ## Find the first non-singleton dimension.
+    dim = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim)) && dim > 0 && dim < (nd + 1))
+      error ("flipdim: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  idx = cell ();
+  for i = 1:nd
+    idx{i} = 1:sz(i);
+  endfor
+  idx{dim} = sz(dim):-1:1;
+  y = x(idx{:});
+
+endfunction
diff --git a/scripts/general/fliplr.m b/scripts/general/fliplr.m
new file mode 100644
index 0000000..01ceac6
--- /dev/null
+++ b/scripts/general/fliplr.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fliplr (@var{x})
+## Return a copy of @var{x} with the order of the columns reversed.  For
+## example,
+##
+## @example
+## @group
+## fliplr ([1, 2; 3, 4])
+##      @result{}  2  1
+##          4  3
+## @end group
+## @end example
+##
+## Note that @code{fliplr} only work with 2-D arrays.  To flip N-d arrays
+## use @code{flipdim} instead.
+## @seealso{flipud, flipdim, rot90, rotdim}
+## @end deftypefn
+
+## Author: jwe
+
+function y = fliplr (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (ndims (x) > 2)
+    error ("fliplr: Only works with 2-D arrays");
+  endif
+
+  nc = columns (x);
+  y = x (:, nc:-1:1);
+
+endfunction
+
+%!assert((fliplr ([1, 2; 3, 4]) == [2, 1; 4, 3]
+%! && fliplr ([1, 2; 3, 4; 5, 6]) == [2, 1; 4, 3; 6, 5]
+%! && fliplr ([1, 2, 3; 4, 5, 6]) == [3, 2, 1; 6, 5, 4]));
+
+%!error fliplr();
+
+%!error fliplr (1, 2);
+
diff --git a/scripts/general/flipud.m b/scripts/general/flipud.m
new file mode 100644
index 0000000..f306ba8
--- /dev/null
+++ b/scripts/general/flipud.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} flipud (@var{x})
+## Return a copy of @var{x} with the order of the rows reversed.  For
+## example,
+##
+## @example
+## @group
+## flipud ([1, 2; 3, 4])
+##      @result{}  3  4
+##          1  2
+## @end group
+## @end example
+##
+## Due to the difficulty of defining which axis about which to flip the 
+## matrix @code{flipud} only work with 2-d arrays.  To flip N-d arrays
+## use @code{flipdim} instead.
+## @seealso{fliplr, flipdim, rot90, rotdim}
+## @end deftypefn
+
+## Author: jwe
+
+function y = flipud (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (ndims (x) > 2)
+    error ("flipud: Only works with 2-d arrays");
+  endif
+
+  nr = rows (x);
+  y = x (nr:-1:1, :);
+
+endfunction
+
+%!assert((flipud ([1, 2; 3, 4]) == [3, 4; 1, 2]
+%! && flipud ([1, 2; 3, 4; 5, 6]) == [5, 6; 3, 4; 1, 2]
+%! && flipud ([1, 2, 3; 4, 5, 6]) == [4, 5, 6; 1, 2, 3]));
+
+%!error flipud ();
+
+%!error flipud (1, 2);
+
diff --git a/scripts/general/genvarname.m b/scripts/general/genvarname.m
new file mode 100644
index 0000000..548270c
--- /dev/null
+++ b/scripts/general/genvarname.m
@@ -0,0 +1,209 @@
+## Copyright (C) 2008, 2009 Bill Denney, Robert Platt
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{varname} =} genvarname (@var{str})
+## @deftypefnx {Function File} {@var{varname} =} genvarname (@var{str}, @var{exclusions})
+## Create unique variable(s) from @var{str}.  If @var{exclusions} is
+## given, then the variable(s) will be unique to each other and to
+## @var{exclusions} (@var{exclusions} may be either a string or a cellstr).
+##
+## If @var{str} is a cellstr, then a unique variable is created for each
+## cell in @var{str}.
+##
+## @example
+## @group
+## x = 3.141;
+## genvarname ("x", who ())
+## @result{} x1
+## @end group
+## @end example
+##
+## If @var{wanted} is a cell array, genvarname will make sure the returned
+## strings are distinct:
+##
+## @example
+## @group
+## genvarname (@{"foo", "foo"@})
+## @result{}
+## @{
+##   [1,1] = foo
+##   [1,2] = foo1
+## @}
+## @end group
+## @end example
+##
+## Note that the result is a char array/cell array of strings, not the
+## variables themselves.  To define a variable, @code{eval()} can be
+## used.  The following trivial example sets @code{x} to @code{42}.
+##
+## @example
+## @group
+## name = genvarname ("x");
+## eval([name " = 42"]);
+## @result{} x =  42
+## @end group
+## @end example
+##
+## Also, this can be useful for creating unique struct field names.
+##
+## @example
+## @group
+## x = struct ();
+## for i = 1:3
+##   x.(genvarname ("a", fieldnames (x))) = i;
+## endfor
+## @result{}
+## x =
+## @{
+##   a =  1
+##   a1 =  2
+##   a2 =  3
+## @}
+## @end group
+## @end example
+##
+## Since variable names may only contain letters, digits and underscores,
+## genvarname replaces any sequence of disallowed characters with
+## an underscore.  Also, variables may not begin with a digit; in this
+## case an underscore is added before the variable name.
+##
+## Variable names beginning and ending with two underscores "__" are valid but
+## they are used internally by octave and should generally be avoided, therefore
+## genvarname will not generate such names.
+##
+## genvarname will also make sure that returned names do not clash with
+## keywords such as "for" and "if".  A number will be appended if necessary.
+## Note, however, that this does @strong{not} include function names,
+## such as "sin".  Such names should be included in @var{avoid} if necessary.
+## @seealso{isvarname, exist, tmpnam, eval}
+## @end deftypefn
+
+## Authors: Rob Platt <robert.platt at postgrad.manchester.ac.uk>
+##          Bill Denney <bill at denney.ws>
+
+function varname = genvarname (str, exclusions)
+
+  strinput = ischar (str);
+  ## Process the inputs
+  if (nargin < 2)
+    exclusions = {};
+  elseif (ischar (exclusions))
+    if (rows (exclusions) != 1)
+      error ("genvarname: if more than one exclusion is given, it must be a cellstr");
+    endif
+    exclusions = {exclusions};
+  elseif (! iscellstr (exclusions))
+    error ("genvarname: exclusions must be a string or a cellstr");
+  endif
+  if (ischar (str))
+    if (rows (str) != 1)
+      error ("genvarname: if more than one str is given, it must be a cellstr");
+    endif
+    str = {str};
+  elseif (! iscellstr (str))
+    error ("genvarname: str must be a string or a cellstr");
+  endif
+
+  validchars = cstrcat ("A":"Z", "a":"z", "0":"9", "_");
+
+  varname = cell (size (str));
+  for i = 1:numel (str)
+    ## Perform any modifications to the varname to make sure that it is
+    ## a valid variable name.
+
+    ## remove invalid characters
+    str{i}(! ismember (str{i}, validchars)) = "_";
+    ## do not use keywords
+    if (iskeyword (str{i}))
+      str{i} = cstrcat ("_", str{i});
+    endif
+    ## double underscores at the beginning and end are reserved variables
+    underscores = (str{i} == "_");
+    if (any (underscores))
+      firstnon = find (!underscores, 1);
+      lastnon = find (!underscores, 1, "last");
+      str{i}([1:firstnon-2, lastnon+2:end]) = [];
+    endif
+    ## The variable cannot be empty
+    if (isempty (str{i}))
+      str{i} = "x";
+    endif
+    ## it cannot start with a number
+    if (ismember (str{i}(1), "0":"9"))
+      str{i} = cstrcat ("_", str{i});
+    endif
+
+    ## make sure that the variable is unique relative to other variables
+    ## and the exclusions list
+    excluded = any (strcmp (str{i}, exclusions));
+    if (excluded && ismember (str{i}(end), "0":"9"))
+      ## if it is not unique and ends with a digit, add an underscore to
+      ## make the variable name more readable ("x1_1" instead of "x11")
+      str{i}(end+1) = "_";
+    endif
+    varname(i) = str(i);
+    idx = 0;
+    while excluded
+      idx++;
+      varname{i} = sprintf("%s%d", str{i}, idx);
+      excluded = any (strcmp (varname{i}, exclusions));
+    endwhile
+    exclusions(end+1) = varname(i);
+  endfor
+
+  if strinput
+    varname = varname{1};
+  endif
+
+endfunction
+
+## Tests
+## a single argument
+%!assert(genvarname("a"), "a")
+## a single argument with a non-conflicting exception
+%!assert(genvarname("a", "b"), "a")
+## a single argument with a conflicting exception
+%!assert(genvarname("a", "a"), "a1")
+## a single argument as a cell
+%!assert(genvarname({"a"}), {"a"})
+%!assert(genvarname({"a"}, "b"), {"a"})
+%!assert(genvarname({"a"}, {"b"}), {"a"})
+%!assert(genvarname({"a"}, "a"), {"a1"})
+%!assert(genvarname({"a"}, {"a"}), {"a1"})
+## Test different arguments
+## orientation
+%!assert(genvarname({"a" "b"}), {"a" "b"})
+%!assert(genvarname({"a";"b"}), {"a";"b"})
+%!assert(genvarname({"a" "a"}), {"a" "a1"})
+%!assert(genvarname({"a" "b";"c" "d"}), {"a" "b";"c" "d"})
+%!assert(genvarname({"a" "a" "a";"a" "a" "a"}), {"a" "a2" "a4";"a1" "a3" "a5"})
+## more than one repetition
+%!assert(genvarname({"a" "a" "a"}), {"a" "a1" "a2"})
+%!assert(genvarname({"a" "a" "a"}, {"a" "a1" "a2"}), {"a3" "a4" "a5"})
+## more than one repetition not in order
+%!assert(genvarname({"a" "b" "a" "b" "a"}), {"a" "b" "a1" "b1" "a2"})
+## Variable name munging
+%!assert (genvarname ("__x__"), "_x_")
+%!assert (genvarname ("123456789"), "_123456789")
+%!assert (genvarname ("_$1__"), "_1_")
+%!assert (genvarname ("__foo__", "_foo_"), "_foo_1")
+%!assert (genvarname ("1million_and1", "_1million_and1"), "_1million_and1_1")
+%!assert (genvarname ({"", "", ""}), {"x", "x1", "x2"})
+%!assert (genvarname ("if"), "_if")
+%!assert (genvarname ({"if", "if", "if"}), {"_if", "_if1", "_if2"})
diff --git a/scripts/general/gradient.m b/scripts/general/gradient.m
new file mode 100644
index 0000000..645d2f8
--- /dev/null
+++ b/scripts/general/gradient.m
@@ -0,0 +1,274 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{dx} =} gradient (@var{m})
+## @deftypefnx {Function File} {[@var{dx}, @var{dy}, @var{dz}, @dots{}] =} gradient (@var{m})
+## @deftypefnx {Function File} {[@dots{}] =} gradient (@var{m}, @var{s})
+## @deftypefnx {Function File} {[@dots{}] =} gradient (@var{m}, @var{x}, @var{y}, @var{z}, @dots{})
+## @deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0})
+## @deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0}, @var{s})
+## @deftypefnx {Function File} {[@dots{}] =} gradient (@var{f}, @var{x0}, @var{x}, @var{y}, @dots{})
+##
+## Calculate the gradient of sampled data or a function.  If @var{m}
+## is a vector, calculate the one-dimensional gradient of @var{m}.  If
+## @var{m} is a matrix the gradient is calculated for each dimension.
+##
+## @code{[@var{dx}, @var{dy}] = gradient (@var{m})} calculates the one
+## dimensional gradient for @var{x} and @var{y} direction if @var{m} is a
+## matrix.  Additional return arguments can be use for multi-dimensional
+## matrices.
+##
+## A constant spacing between two points can be provided by the
+## @var{s} parameter.  If @var{s} is a scalar, it is assumed to be the spacing
+## for all dimensions. 
+## Otherwise, separate values of the spacing can be supplied by
+## the @var{x}, @dots{} arguments.  Scalar values specify an equidistant spacing.
+## Vector values for the @var{x}, @dots{} arguments specify the coordinate for that
+## dimension.  The length must match their respective dimension of @var{m}.
+## 
+## At boundary points a linear extrapolation is applied.  Interior points
+## are calculated with the first approximation of the numerical gradient
+##
+## @example
+## y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).
+## @end example
+## 
+## If the first argument @var{f} is a function handle, the gradient of the
+## function at the points in @var{x0} is approximated using central
+## difference.  For example, @code{gradient (@@cos, 0)} approximates the
+## gradient of the cosine function in the point @math{x0 = 0}.  As with
+## sampled data, the spacing values between the points from which the
+## gradient is estimated can be set via the @var{s} or @var{dx},
+## @var{dy}, @dots{} arguments.  By default a spacing of 1 is used.
+## @seealso{diff, del2}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+## Modified: David Bateman <dbateman at free.fr> Added NDArray support
+
+function varargout = gradient (m, varargin)
+  
+  if (nargin < 1)
+    print_usage ()
+  endif
+
+  nargout_with_ans = max(1,nargout);
+  if (ismatrix (m))
+    [varargout{1:nargout_with_ans}] = matrix_gradient (m, varargin{:});
+  elseif (isa (m, "function_handle"))
+    [varargout{1:nargout_with_ans}] = handle_gradient (m, varargin{:});
+  elseif (ischar(m))
+    [varargout{1:nargout_with_ans}] = handle_gradient (str2func (m), varargin{:});
+  else
+    error ("gradient: first input must be an array or a function");
+  endif
+
+endfunction
+
+function varargout = matrix_gradient (m, varargin)
+  transposed = false;
+  if (isvector (m))
+    ## make a row vector.
+    transposed = (size (m, 2) == 1);
+    m = m(:)';
+  endif
+
+  nd = ndims (m);
+  sz = size (m);
+  if (length(sz) > 1)
+    tmp = sz(1); sz(1) = sz(2); sz(2) = tmp;
+  endif
+
+  if (nargin > 2 && nargin != nd + 1)
+    print_usage ()
+  endif
+  
+  ## cell d stores a spacing vector for each dimension
+  d = cell (1, nd);
+  if (nargin == 1)
+    ## no spacing given - assume 1.0 for all dimensions
+    for i = 1:nd
+      d{i} = ones (sz(i) - 1, 1);
+    endfor
+  elseif (nargin == 2)
+    if (isscalar (varargin{1}))
+      ## single scalar value for all dimensions
+      for i = 1:nd
+        d{i} = varargin{1} * ones (sz(i) - 1, 1);
+      endfor
+    else
+      ## vector for one-dimensional derivative
+      d{1} = diff (varargin{1}(:));
+    endif
+  else
+    ## have spacing value for each dimension
+    if (length(varargin) != nd)
+      error ("dimensions and number of spacing values do not match.");
+    end
+    for i = 1:nd
+      if (isscalar (varargin{i}))
+        d{i} = varargin{i} * ones (sz(i) - 1, 1);
+      else
+        d{i} = diff (varargin{i}(:));
+      endif
+    endfor
+  endif
+
+  m = shiftdim (m, 1);
+  for i = 1:min (nd, nargout)
+    mr = rows (m);
+    mc = numel (m) / mr;
+    Y = zeros (size (m), class (m));
+	
+    if (mr > 1)
+      ## Top and bottom boundary.
+      Y(1,:) = diff (m(1:2, :)) / d{i}(1);
+      Y(mr,:) = diff (m(mr-1:mr, :) / d{i}(mr - 1));
+    endif
+
+    if (mr > 2)
+      ## Interior points.
+      Y(2:mr-1,:) = ((m(3:mr,:) - m(1:mr-2,:))
+          ./ kron (d{i}(1:mr-2) + d{i}(2:mr-1), ones (1, mc)));
+    endif
+
+    ## turn multi-dimensional matrix in a way, that gradient
+    ## along x-direction is calculated first then y, z, ...
+
+    if (i == 1)
+      varargout{i} = shiftdim (Y, nd - 1);
+      m = shiftdim (m, nd - 1);
+    elseif (i == 2)
+      varargout{i} = Y;
+      m = shiftdim (m, 2);
+    else
+      varargout{i} = shiftdim (Y, nd - i + 1);
+      m = shiftdim (m, 1);
+    endif
+  endfor
+
+  if (transposed)
+    varargout{1} = varargout{1}.';
+  endif
+endfunction
+
+function varargout = handle_gradient (f, p0, varargin)
+  ## Input checking
+  p0_size = size (p0);
+
+  if (numel (p0_size) != 2)
+    error ("gradient: the second input argument should either be a vector or a matrix");
+  endif
+
+  if (any (p0_size == 1))
+    p0 = p0 (:);
+    dim = 1;
+    num_points = numel (p0);
+  else
+    num_points = p0_size (1);
+    dim = p0_size (2);
+  endif
+  
+  if (length (varargin) == 0)
+    delta = 1;
+  elseif (length (varargin) == 1 || length (varargin) == dim)
+    try
+      delta = [varargin{:}];
+    catch
+      error ("gradient: spacing parameters must be scalars or a vector");
+    end_try_catch
+  else
+    error ("gradient: incorrect number of spacing parameters");
+  endif
+  
+  if (isscalar (delta))
+    delta = repmat (delta, 1, dim);
+  elseif (!isvector (delta))
+    error ("gradient: spacing values must be scalars or a vector");
+  endif
+  
+  ## Calculate the gradient
+  p0 = mat2cell (p0, num_points, ones (1, dim));
+  varargout = cell (1, dim);
+  for d = 1:dim
+    s = delta (d);
+    df_dx = (f (p0{1:d-1}, p0{d}+s, p0{d+1:end})
+           - f (p0{1:d-1}, p0{d}-s, p0{d+1:end})) ./ (2*s);
+    if (dim == 1)
+      varargout{d} = reshape (df_dx, p0_size);
+    else
+      varargout{d} = df_dx;
+    endif
+  endfor
+endfunction
+
+%!test
+%! data = [1, 2, 4, 2];
+%! dx = gradient (data);
+%! dx2 = gradient (data, 0.25);
+%! dx3 = gradient (data, [0.25, 0.5, 1, 3]);
+%! assert (dx, [1, 3/2, 0, -2]);
+%! assert (dx2, [4, 6, 0, -8]);
+%! assert (dx3, [4, 4, 0, -1]);
+%! assert (size_equal(data, dx));
+
+%!test
+%! [Y,X,Z,U] = ndgrid (2:2:8,1:5,4:4:12,3:5:30);
+%! [dX,dY,dZ,dU] = gradient (X);
+%! assert (all(dX(:)==1));
+%! assert (all(dY(:)==0));
+%! assert (all(dZ(:)==0));
+%! assert (all(dU(:)==0));
+%! [dX,dY,dZ,dU] = gradient (Y);
+%! assert (all(dX(:)==0));
+%! assert (all(dY(:)==2));
+%! assert (all(dZ(:)==0));
+%! assert (all(dU(:)==0));
+%! [dX,dY,dZ,dU] = gradient (Z);
+%! assert (all(dX(:)==0));
+%! assert (all(dY(:)==0));
+%! assert (all(dZ(:)==4));
+%! assert (all(dU(:)==0));
+%! [dX,dY,dZ,dU] = gradient (U);
+%! assert (all(dX(:)==0));
+%! assert (all(dY(:)==0));
+%! assert (all(dZ(:)==0));
+%! assert (all(dU(:)==5));
+%! assert (size_equal(dX, dY, dZ, dU, X, Y, Z, U));
+%! [dX,dY,dZ,dU] = gradient (U, 5.0);
+%! assert (all(dU(:)==1));
+%! [dX,dY,dZ,dU] = gradient (U, 1.0, 2.0, 3.0, 2.5);
+%! assert (all(dU(:)==2));
+
+%!test
+%! x = 0:10;
+%! f = @cos;
+%! df_dx = @(x) -sin (x);
+%! assert (gradient (f, x), df_dx (x), 0.2);
+%! assert (gradient (f, x, 0.5), df_dx (x), 0.1);
+
+%!test
+%! xy = reshape (1:10, 5, 2);
+%! f = @(x,y) sin (x) .* cos (y);
+%! df_dx = @(x, y) cos (x) .* cos (y);
+%! df_dy = @(x, y) -sin (x) .* sin (y);
+%! [dx, dy] = gradient (f, xy);
+%! assert (dx, df_dx (xy (:, 1), xy (:, 2)), 0.1)
+%! assert (dy, df_dy (xy (:, 1), xy (:, 2)), 0.1)
+
diff --git a/scripts/general/idivide.m b/scripts/general/idivide.m
new file mode 100644
index 0000000..316fd70
--- /dev/null
+++ b/scripts/general/idivide.m
@@ -0,0 +1,120 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} idivide (@var{x}, @var{y}, @var{op})
+## Integer division with different round rules.  The standard behavior of
+## the an integer division such as @code{@var{a} ./ @var{b}} is to round
+## the result to the nearest integer.  This is not always the desired
+## behavior and @code{idivide} permits integer element-by-element
+## division to be performed with different treatment for the fractional
+## part of the division as determined by the @var{op} flag.  @var{op} is
+## a string with one of the values: 
+##
+## @table @asis
+## @item "fix"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## towards zero.
+## @item "round"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## towards the nearest integer.
+## @item "floor"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## downwards.
+## @item "ceil"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## upwards.
+## @end table
+## 
+## @noindent
+## If @var{op} is not given it is assumed that it is @code{"fix"}.
+## An example demonstrating these rounding rules is
+##
+## @example
+## @group
+## idivide (int8 ([-3, 3]), int8 (4), "fix")
+## @result{} int8 ([0, 0])
+## idivide (int8 ([-3, 3]), int8 (4), "round")
+## @result{} int8 ([-1, 1])
+## idivide (int8 ([-3, 3]), int8 (4), "ceil")
+## @result{} int8 ([0, 1])
+## idivide (int8 ([-3, 3]), int8 (4), "floor")
+## @result{} int8 ([-1, 0])
+## @end group
+## @end example
+##
+## @seealso{ldivide, rdivide}
+## @end deftypefn
+
+function z = idivide (x, y, op)
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  elseif (nargin == 2)
+    op = "fix";
+  else
+    op = tolower (op);
+  endif
+
+  if (strcmp (op, "round"))
+    z = x ./ y;
+  else
+    if (isfloat (x))
+      typ = class (y);
+    elseif (isfloat (y))
+      typ = class (x);
+    else
+      typ = class (x);
+      if (!strcmp (class (x), class (y)))
+	error ("idivide: incompatible types");
+      endif
+    endif
+
+    if (strcmp (op, "fix"))
+      z = cast (fix (double (x) ./ double (y)), typ);
+    elseif (strcmp (op, "floor"))
+      z = cast (floor (double (x) ./ double (y)), typ);
+    elseif (strcmp (op, "ceil"))
+      z = cast (ceil (double (x) ./ double (y)), typ);
+    else
+      error ("idivide: unrecognized rounding type");
+    endif
+  endif
+endfunction
+  
+%!shared a, af, b, bf
+%! a = int8(3);
+%! af = 3;
+%! b = int8([-4, 4]);
+%! bf = [-4, 4];
+
+%!assert (idivide (a, b), int8 ([0, 0]))
+%!assert (idivide (a, b, "floor"), int8([-1, 0]))
+%!assert (idivide (a, b, "ceil"), int8 ([0, 1]))
+%!assert (idivide (a, b, "round"), int8 ([-1, 1]))
+
+%!assert (idivide (af, b), int8 ([0, 0]))
+%!assert (idivide (af, b, "floor"), int8([-1, 0]))
+%!assert (idivide (af, b, "ceil"), int8 ([0, 1]))
+%!assert (idivide (af, b, "round"), int8 ([-1, 1]))
+
+%!assert (idivide (a, bf), int8 ([0, 0]))
+%!assert (idivide (a, bf, "floor"), int8([-1, 0]))
+%!assert (idivide (a, bf, "ceil"), int8 ([0, 1]))
+%!assert (idivide (a, bf, "round"), int8 ([-1, 1]))
+
+%!error (idivide (uint8(1), int8(1)))
diff --git a/scripts/general/ind2sub.m b/scripts/general/ind2sub.m
new file mode 100644
index 0000000..5f10411
--- /dev/null
+++ b/scripts/general/ind2sub.m
@@ -0,0 +1,86 @@
+## Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+##               Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{s1}, @var{s2}, @dots{}, @var{sN}] =} ind2sub (@var{dims}, @var{ind})
+## Convert a linear index into subscripts.
+##
+## The following example shows how to convert the linear index @code{8}
+## in a 3-by-3 matrix into a subscript.  The matrix is linearly indexed
+## moving from one column to next, filling up all rows in each column.
+## @example
+## @group
+## [r, c] = ind2sub ([3, 3], 8)
+## @result{} r =  2
+## c =  3
+## @end group
+## @end example
+## @seealso{sub2ind}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+## Adapted-by: jwe
+
+function varargout = ind2sub (dims, ind)
+
+  if (nargin == 2)
+    if (isvector (dims) && all (round (dims) == dims))
+      if (isnumeric (ind) && all (round (ind) == ind))
+	ntot = prod (dims);
+	if (all (ind > 0 & ind <= ntot))
+	  nd = length (dims);
+	  if (nargout > 0)
+	    vlen = nargout;
+	  else
+	    vlen = 1;
+	  endif
+	  if (nd > vlen);
+	    dims(vlen) = prod (dims(vlen:nd));
+	    dims(vlen+1:nd) = [];
+	  endif
+	  nd = length (dims);
+	  scale = [1; cumprod(dims(:))];
+	  for i = nd:-1:2
+	    k = (ind >= scale(i));
+	    r = ones (size (ind));
+	    t = zeros (size (ind));
+	    t(k) = floor ((ind(k) - 1) / scale(i));
+	    r(k) = t(k) + 1;
+	    varargout{i} = r;
+	    ind(k) -= t(k) * scale(i);
+	  endfor
+	  varargout{1} = ind;
+	  for i = nd+1:vlen
+	    varargout{i} = ones (size (ind));
+	  endfor
+	else
+	  error ("ind2sub: index out of range");
+	endif
+      else
+	error ("ind2sub: expecting integer-valued index argument");
+      endif
+    else
+      error ("ind2sub: expecting dims to be an integer vector");
+    endif
+  else
+    print_usage ();
+  endif
+
+
+endfunction
diff --git a/scripts/general/int2str.m b/scripts/general/int2str.m
new file mode 100644
index 0000000..736f4bd
--- /dev/null
+++ b/scripts/general/int2str.m
@@ -0,0 +1,120 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+##               2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} int2str (@var{n})
+## Convert an integer (or array of integers) to a string (or a character
+## array).
+##
+## @example
+## @group
+##
+## int2str (123)
+##      @result{} "123"
+##
+## s = int2str ([1, 2, 3; 4, 5, 6])
+##      @result{} s = 
+##         1  2  3
+##         4  5  6
+## 
+## whos s
+##      @result{} s = 
+##       Attr Name        Size                     Bytes  Class
+##       ==== ====        ====                     =====  ===== 
+##            s           2x7                         14  char
+## @end group
+## @end example
+##
+## This function is not very flexible.  For better control over the
+## results, use @code{sprintf} (@pxref{Formatted Output}). 
+## @seealso{sprintf, num2str, mat2str}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = int2str (x)
+
+  if (nargin == 1)
+    x = round (real(x));
+    sz = size(x);
+    nd = ndims (x);
+    nc = columns (x);
+    if (nc > 1)
+      idx = cell ();
+      for i = 1:nd
+	idx{i} = 1:sz(i);
+      endfor
+      idx(2) = 1;
+      ifmt = get_fmt (x(idx{:}), 0);
+      idx(2) = 2:sz(2);
+      rfmt = get_fmt (x(idx{:}), 2);
+      fmt = cstrcat (ifmt, repmat (rfmt, 1, nc-1), "\n");
+    else
+      fmt = cstrcat (get_fmt (x, 0), "\n");
+    endif
+    tmp = sprintf (fmt, permute (x, [2, 1, 3 : nd]));
+    tmp(end) = "";
+    retval = char (strsplit (tmp, "\n"));
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+function fmt = get_fmt (x, sep)
+
+  t = x(:);
+  t = t(t != 0);
+  if (isempty (t))
+    ## All zeros.
+    fmt = sprintf ("%%%dd", 1 + sep);
+  else
+    ## Maybe have some zeros.
+    nan_inf = isinf (t) | isnan (t);
+    if (any (nan_inf))
+      if (any (t(nan_inf) < 0))
+	min_fw = 4 + sep;
+      else
+	min_fw = 3 + sep;
+      endif
+    else
+      min_fw = 1 + sep;
+    endif
+    t = t(! nan_inf);
+    if (isempty (t))
+      ## Only zeros, Inf, and NaN.
+      fmt = sprintf ("%%%dd", min_fw);
+    else
+      ## Could have anything.
+      tfw = floor (log10 (double (abs (t)))) + 1 + sep;
+      fw = max (tfw);
+      if (any (t(tfw == fw) < 0))
+	fw++;
+      endif
+      fmt = sprintf ("%%%dd", max (fw, min_fw));
+    endif
+  endif
+
+endfunction
+
+%!assert(strcmp (int2str (-123), "-123") && strcmp (int2str (1.2), "1"));
+%!assert (all (int2str ([1, 2, 3; 4, 5, 6]) == ["1  2  3";"4  5  6"]));
+%!error int2str ();
+%!error int2str (1, 2);
+
diff --git a/scripts/general/interp1.m b/scripts/general/interp1.m
new file mode 100644
index 0000000..ae55e42
--- /dev/null
+++ b/scripts/general/interp1.m
@@ -0,0 +1,574 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{yi} =} interp1 (@var{x}, @var{y}, @var{xi})
+## @deftypefnx {Function File} {@var{yi} =} interp1 (@dots{}, @var{method})
+## @deftypefnx {Function File} {@var{yi} =} interp1 (@dots{}, @var{extrap})
+## @deftypefnx {Function File} {@var{pp} =} interp1 (@dots{}, 'pp')
+##
+## One-dimensional interpolation.  Interpolate @var{y}, defined at the
+## points @var{x}, at the points @var{xi}.  The sample points @var{x} 
+## must be strictly monotonic.  If @var{y} is an array, treat the columns
+## of @var{y} separately.
+##
+## Method is one of:
+##
+## @table @asis
+## @item 'nearest'
+## Return the nearest neighbor.
+## @item 'linear'
+## Linear interpolation from nearest neighbors
+## @item 'pchip'
+## Piece-wise cubic hermite interpolating polynomial
+## @item 'cubic'
+## Cubic interpolation from four nearest neighbors
+## @item 'spline'
+## Cubic spline interpolation--smooth first and second derivatives
+## throughout the curve
+## @end table
+##
+## Appending '*' to the start of the above method forces @code{interp1}
+## to assume that @var{x} is uniformly spaced, and only @code{@var{x}
+## (1)} and @code{@var{x} (2)} are referenced.  This is usually faster,
+## and is never slower.  The default method is 'linear'.
+##
+## If @var{extrap} is the string 'extrap', then extrapolate values beyond
+## the endpoints.  If @var{extrap} is a number, replace values beyond the
+## endpoints with that number.  If @var{extrap} is missing, assume NA.
+##
+## If the string argument 'pp' is specified, then @var{xi} should not be
+## supplied and @code{interp1} returns the piece-wise polynomial that
+## can later be used with @code{ppval} to evaluate the interpolation.
+## There is an equivalence, such that @code{ppval (interp1 (@var{x},
+## @var{y}, @var{method}, 'pp'), @var{xi}) == interp1 (@var{x}, @var{y},
+## @var{xi}, @var{method}, 'extrap')}.
+##
+## An example of the use of @code{interp1} is
+##
+## @example
+## @group
+## xf = [0:0.05:10];
+## yf = sin (2*pi*xf/5);
+## xp = [0:10];
+## yp = sin (2*pi*xp/5);
+## lin = interp1 (xp, yp, xf);
+## spl = interp1 (xp, yp, xf, "spline");
+## cub = interp1 (xp, yp, xf, "cubic");
+## near = interp1 (xp, yp, xf, "nearest");
+## plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
+##       xf, cub, "c", xf, near, "m", xp, yp, "r*");
+## legend ("original", "linear", "spline", "cubic", "nearest")
+## @end group
+## @end example
+##
+## @seealso{interpft}
+## @end deftypefn
+
+## Author: Paul Kienzle
+## Date: 2000-03-25
+##    added 'nearest' as suggested by Kai Habel
+## 2000-07-17 Paul Kienzle
+##    added '*' methods and matrix y
+##    check for proper table lengths
+## 2002-01-23 Paul Kienzle
+##    fixed extrapolation
+
+function yi = interp1 (x, y, varargin)
+
+  if (nargin < 3 || nargin > 6)
+    print_usage ();
+  endif
+
+  method = "linear";
+  extrap = NA;
+  xi = [];
+  pp = false;
+  firstnumeric = true;
+
+  if (nargin > 2)
+    for i = 1:length (varargin)
+      arg = varargin{i};
+      if (ischar (arg))
+	arg = tolower (arg);
+	if (strcmp ("extrap", arg))
+	  extrap = "extrap";
+	elseif (strcmp ("pp", arg))
+	  pp = true;
+	else
+	  method = arg;
+	endif
+      else
+	if (firstnumeric)
+	  xi = arg;
+	  firstnumeric = false;
+	else
+	  extrap = arg;
+	endif
+      endif
+    endfor
+  endif
+
+  ## reshape matrices for convenience
+  x = x(:);
+  nx = size (x, 1);
+  if (isvector(y) && size (y, 1) == 1)
+    y = y(:);
+  endif
+  ndy = ndims (y);
+  szy = size (y);
+  ny = szy(1);
+  nc = prod (szy(2:end));
+  y = reshape (y, ny, nc);
+  szx = size (xi);
+  xi = xi(:);
+
+  ## determine sizes
+  if (nx < 2 || ny < 2)
+    error ("interp1: table too short");
+  endif
+
+  ## determine which values are out of range and set them to extrap,
+  ## unless extrap == "extrap" in which case, extrapolate them like we
+  ## should be doing in the first place.
+  minx = x(1);
+  maxx = x(nx);
+  if (minx > maxx)
+    tmp = minx;
+    minx = maxx;
+    maxx = tmp;
+  endif
+  if (method(1) == "*")
+    dx = x(2) - x(1);
+  endif
+
+  if (! pp)
+    if (ischar (extrap) && strcmp (extrap, "extrap"))
+      range = 1:size (xi, 1);
+      yi = zeros (size (xi, 1), size (y, 2));
+    else
+      range = find (xi >= minx & xi <= maxx);
+      yi = extrap * ones (size (xi, 1), size (y, 2));
+      if (isempty (range))
+	if (! isvector (y) && length (szx) == 2
+	    && (szx(1) == 1 || szx(2) == 1))
+	  if (szx(1) == 1)
+	    yi = reshape (yi, [szx(2), szy(2:end)]);
+	  else
+	    yi = reshape (yi, [szx(1), szy(2:end)]);
+	  endif
+	else
+	  yi = reshape (yi, [szx, szy(2:end)]);
+        endif
+        return; 
+      endif
+      xi = xi(range);
+    endif
+  endif
+
+  if (strcmp (method, "nearest"))
+    if (pp)
+      yi = mkpp ([x(1); (x(1:end-1)+x(2:end))/2; x(end)], y, szy(2:end));
+    else
+      idx = lookup (0.5*(x(1:nx-1)+x(2:nx)), xi) + 1;
+      yi(range,:) = y(idx,:);
+    endif
+  elseif (strcmp (method, "*nearest"))
+    if (pp)
+      yi = mkpp ([x(1); x(1)+[0.5:(ny-1)]'*dx; x(nx)], y, szy(2:end));
+    else
+      idx = max (1, min (ny, floor((xi-x(1))/dx+1.5)));
+      yi(range,:) = y(idx,:);
+    endif
+  elseif (strcmp (method, "linear"))
+    dy = y(2:ny,:) - y(1:ny-1,:);
+    dx = x(2:nx) - x(1:nx-1);
+    if (pp)
+      yi = mkpp (x, [dy./dx, y(1:end-1)], szy(2:end));
+    else
+      ## find the interval containing the test point
+      idx = lookup (x, xi, "lr");
+      ## use the endpoints of the interval to define a line
+      s = (xi - x(idx))./dx(idx);
+      yi(range,:) = s(:,ones(1,nc)).*dy(idx,:) + y(idx,:);
+    endif
+  elseif (strcmp (method, "*linear"))
+    if (pp)
+      dy = [y(2:ny,:) - y(1:ny-1,:)];
+      yi = mkpp (x(1) + [0:ny-1]*dx, [dy./dx, y(1:end-1)], szy(2:end));
+    else
+      ## find the interval containing the test point
+      t = (xi - x(1))/dx + 1;
+      idx = max(1,min(ny,floor(t)));
+
+      ## use the endpoints of the interval to define a line
+      dy = [y(2:ny,:) - y(1:ny-1,:); y(ny,:) - y(ny-1,:)];
+      s = t - idx;
+      yi(range,:) = s(:,ones(1,nc)).*dy(idx,:) + y(idx,:); 
+    endif
+  elseif (strcmp (method, "pchip") || strcmp (method, "*pchip"))
+    if (nx == 2 || method(1) == "*") 
+      x = linspace (x(1), x(nx), ny);
+    endif
+    ## Note that pchip's arguments are transposed relative to interp1
+    if (pp)
+      yi = pchip (x.', y.');
+      yi.d = szy(2:end);
+    else
+      yi(range,:) = pchip (x.', y.', xi.').';
+    endif
+
+  elseif (strcmp (method, "cubic") || (strcmp (method, "*cubic") && pp))
+    ## FIXME Is there a better way to treat pp return return and *cubic
+    if (method(1) == "*")
+      x = linspace (x(1), x(nx), ny).'; 
+      nx = ny;
+    endif
+
+    if (nx < 4 || ny < 4)
+      error ("interp1: table too short");
+    endif
+    idx = lookup (x(2:nx-1), xi, "lr");
+
+    ## Construct cubic equations for each interval using divided
+    ## differences (computation of c and d don't use divided differences
+    ## but instead solve 2 equations for 2 unknowns). Perhaps
+    ## reformulating this as a lagrange polynomial would be more efficient.
+    i = 1:nx-3;
+    J = ones (1, nc);
+    dx = diff (x);
+    dx2 = x(i+1).^2 - x(i).^2;
+    dx3 = x(i+1).^3 - x(i).^3;
+    a = diff (y, 3)./dx(i,J).^3/6;
+    b = (diff (y(1:nx-1,:), 2)./dx(i,J).^2 - 6*a.*x(i+1,J))/2;
+    c = (diff (y(1:nx-2,:), 1) - a.*dx3(:,J) - b.*dx2(:,J))./dx(i,J);
+    d = y(i,:) - ((a.*x(i,J) + b).*x(i,J) + c).*x(i,J);
+
+    if (pp)
+      xs = [x(1);x(3:nx-2)];
+      yi = mkpp ([x(1);x(3:nx-2);x(nx)], 
+		 [a(:), (b(:) + 3.*xs(:,J).*a(:)), ... 
+		  (c(:) + 2.*xs(:,J).*b(:) + 3.*xs(:,J)(:).^2.*a(:)), ...
+		  (d(:) + xs(:,J).*c(:) + xs(:,J).^2.*b(:) + ...
+		   xs(:,J).^3.*a(:))], szy(2:end));
+    else
+      yi(range,:) = ((a(idx,:).*xi(:,J) + b(idx,:)).*xi(:,J) ...
+		     + c(idx,:)).*xi(:,J) + d(idx,:);
+    endif
+  elseif (strcmp (method, "*cubic"))
+    if (nx < 4 || ny < 4)
+      error ("interp1: table too short");
+    endif
+
+    ## From: Miloje Makivic 
+    ## http://www.npac.syr.edu/projects/nasa/MILOJE/final/node36.html
+    t = (xi - x(1))/dx + 1;
+    idx = max (min (floor (t), ny-2), 2);
+    t = t - idx;
+    t2 = t.*t;
+    tp = 1 - 0.5*t;
+    a = (1 - t2).*tp;
+    b = (t2 + t).*tp;
+    c = (t2 - t).*tp/3;
+    d = (t2 - 1).*t/6;
+    J = ones (1, nc);
+
+    yi(range,:) = a(:,J) .* y(idx,:) + b(:,J) .* y(idx+1,:) ...
+		  + c(:,J) .* y(idx-1,:) + d(:,J) .* y(idx+2,:);
+
+  elseif (strcmp (method, "spline") || strcmp (method, "*spline"))
+    if (nx == 2 || method(1) == "*") 
+      x = linspace(x(1), x(nx), ny); 
+    endif
+    ## Note that spline's arguments are transposed relative to interp1
+    if (pp)
+      yi = spline (x.', y.');
+      yi.d = szy(2:end);
+    else
+      yi(range,:) = spline (x.', y.', xi.').';
+    endif
+  else
+    error ("interp1: invalid method '%s'", method);
+  endif
+
+  if (! pp)
+    if (! isvector (y) && length (szx) == 2 && (szx(1) == 1 || szx(2) == 1))
+      if (szx(1) == 1)
+	yi = reshape (yi, [szx(2), szy(2:end)]);
+      else
+	yi = reshape (yi, [szx(1), szy(2:end)]);
+      endif
+    else
+      yi = reshape (yi, [szx, szy(2:end)]);
+    endif
+  endif
+
+endfunction
+
+%!demo
+%! xf=0:0.05:10; yf = sin(2*pi*xf/5);
+%! xp=0:10;      yp = sin(2*pi*xp/5);
+%! lin=interp1(xp,yp,xf,"linear");
+%! spl=interp1(xp,yp,xf,"spline");
+%! cub=interp1(xp,yp,xf,"pchip");
+%! near=interp1(xp,yp,xf,"nearest");
+%! plot(xf,yf,"r",xf,near,"g",xf,lin,"b",xf,cub,"c",xf,spl,"m",xp,yp,"r*");
+%! legend ("original","nearest","linear","pchip","spline")
+%! %--------------------------------------------------------
+%! % confirm that interpolated function matches the original
+
+%!demo
+%! xf=0:0.05:10; yf = sin(2*pi*xf/5);
+%! xp=0:10;      yp = sin(2*pi*xp/5);
+%! lin=interp1(xp,yp,xf,"*linear");
+%! spl=interp1(xp,yp,xf,"*spline");
+%! cub=interp1(xp,yp,xf,"*cubic");
+%! near=interp1(xp,yp,xf,"*nearest");
+%! plot(xf,yf,"r",xf,near,"g",xf,lin,"b",xf,cub,"c",xf,spl,"m",xp,yp,"r*");
+%! legend ("*original","*nearest","*linear","*cubic","*spline")
+%! %--------------------------------------------------------
+%! % confirm that interpolated function matches the original
+
+%!demo
+%! t = 0 : 0.3 : pi; dt = t(2)-t(1);
+%! n = length (t); k = 100; dti = dt*n/k;
+%! ti = t(1) + [0 : k-1]*dti;
+%! y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+%! ddyc = diff(diff(interp1(t,y,ti,'cubic'))./dti)./dti;
+%! ddys = diff(diff(interp1(t,y,ti,'spline'))./dti)./dti;
+%! ddyp = diff(diff(interp1(t,y,ti,'pchip'))./dti)./dti;
+%! plot (ti(2:end-1), ddyc,'g+',ti(2:end-1),ddys,'b*', ...
+%!       ti(2:end-1),ddyp,'c^');
+%! legend('cubic','spline','pchip');
+%! title("Second derivative of interpolated 'sin (4*t + 0.3) .* cos (3*t - 0.1)'");
+
+## For each type of interpolated test, confirm that the interpolated
+## value at the knots match the values at the knots.  Points away
+## from the knots are requested, but only 'nearest' and 'linear'
+## confirm they are the correct values.
+
+%!shared xp, yp, xi, style
+%! xp=0:2:10;      yp = sin(2*pi*xp/5);  
+%! xi = [-1, 0, 2.2, 4, 6.6, 10, 11];
+
+
+## The following BLOCK/ENDBLOCK section is repeated for each style
+##    nearest, linear, cubic, spline, pchip
+## The test for ppval of cubic has looser tolerance, but otherwise
+## the tests are identical.
+## Note that the block checks style and *style; if you add more tests
+## before to add them to both sections of each block.  One test, 
+## style vs. *style, occurs only in the first section.
+## There is an ENDBLOCKTEST after the final block
+%!test style = "nearest";
+## BLOCK
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+%!assert (interp1(xp,[yp',yp'],xi,style),
+%!	  interp1(xp,[yp',yp'],xi,["*",style]),100*eps);
+%!test style=['*',style];
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+## ENDBLOCK
+%!test style='linear';
+## BLOCK
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+%!assert (interp1(xp,[yp',yp'],xi,style),
+%!	  interp1(xp,[yp',yp'],xi,["*",style]),100*eps);
+%!test style=['*',style];
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+## ENDBLOCK
+%!test style='cubic';
+## BLOCK
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),100*eps);
+%!error interp1(1,1,1, style);
+%!assert (interp1(xp,[yp',yp'],xi,style),
+%!	  interp1(xp,[yp',yp'],xi,["*",style]),100*eps);
+%!test style=['*',style];
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),100*eps);
+%!error interp1(1,1,1, style);
+## ENDBLOCK
+%!test style='pchip';
+## BLOCK
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+%!assert (interp1(xp,[yp',yp'],xi,style),
+%!	  interp1(xp,[yp',yp'],xi,["*",style]),100*eps);
+%!test style=['*',style];
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+## ENDBLOCK
+%!test style='spline';
+## BLOCK
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+%!assert (interp1(xp,[yp',yp'],xi,style),
+%!	  interp1(xp,[yp',yp'],xi,["*",style]),100*eps);
+%!test style=['*',style];
+%!assert (interp1(xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA]);
+%!assert (interp1(xp,yp,xp,style), yp, 100*eps);
+%!assert (interp1(xp,yp,xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp',style), yp', 100*eps);
+%!assert (interp1(xp',yp',xp,style), yp, 100*eps);
+%!assert (isempty(interp1(xp',yp',[],style)));
+%!assert (isempty(interp1(xp,yp,[],style)));
+%!assert (interp1(xp,[yp',yp'],xi(:),style),...
+%!	  [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)]);
+%!assert (interp1(xp,yp,xi,style),...
+%!	  interp1(fliplr(xp),fliplr(yp),xi,style),100*eps);
+%!assert (ppval(interp1(xp,yp,style,"pp"),xi),
+%!	  interp1(xp,yp,xi,style,"extrap"),10*eps);
+%!error interp1(1,1,1, style);
+## ENDBLOCK
+## ENDBLOCKTEST
+
+%!# test linear extrapolation
+%!assert (interp1([1:5],[3:2:11],[0,6],"linear","extrap"), [1, 13], eps);
+%!assert (interp1(xp, yp, [-1, max(xp)+1],"linear",5), [5, 5]);
+
+%!error interp1
+%!error interp1(1:2,1:2,1,"bogus")
+
+%!assert (interp1(1:2,1:2,1.4,"nearest"),1);
+%!error interp1(1,1,1, "linear");
+%!assert (interp1(1:2,1:2,1.4,"linear"),1.4);
+%!error interp1(1:3,1:3,1, "cubic");
+%!assert (interp1(1:4,1:4,1.4,"cubic"),1.4);
+%!error interp1(1:2,1:2,1, "spline");
+%!assert (interp1(1:3,1:3,1.4,"spline"),1.4);
+
+%!error interp1(1,1,1, "*nearest");
+%!assert (interp1(1:2:4,1:2:4,1.4,"*nearest"),1);
+%!error interp1(1,1,1, "*linear");
+%!assert (interp1(1:2:4,1:2:4,[0,1,1.4,3,4],"*linear"),[NA,1,1.4,3,NA]);
+%!error interp1(1:3,1:3,1, "*cubic");
+%!assert (interp1(1:2:8,1:2:8,1.4,"*cubic"),1.4);
+%!error interp1(1:2,1:2,1, "*spline");
+%!assert (interp1(1:2:6,1:2:6,1.4,"*spline"),1.4);
+
+%!assert (interp1([3,2,1],[3,2,2],2.5),2.5)
diff --git a/scripts/general/interp1q.m b/scripts/general/interp1q.m
new file mode 100644
index 0000000..501ed14
--- /dev/null
+++ b/scripts/general/interp1q.m
@@ -0,0 +1,72 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{yi} =} interp1q (@var{x}, @var{y}, @var{xi})
+## One-dimensional linear interpolation without error checking.
+## Interpolates @var{y}, defined at the points @var{x}, at the points
+## @var{xi}.  The sample points @var{x} must be a strictly monotonically
+## increasing column vector.  If @var{y} is an array, treat the columns
+## of @var{y} separately.  If @var{y} is a vector, it must be a column
+## vector of the same length as @var{x}.
+##
+## Values of @var{xi} beyond the endpoints of the interpolation result
+## in NA being returned.
+##
+## Note that the error checking is only a significant portion of the
+## execution time of this @code{interp1} if the size of the input arguments
+## is relatively small.  Therefore, the benefit of using @code{interp1q}
+## is relatively small.
+## @seealso{interp1}
+## @end deftypefn
+
+function yi = interp1q (x, y, xi)
+  x = x(:);
+  nx = size (x, 1);
+  szy = size (y);
+  ny = szy (1);
+  nc = prod (szy (2 : end));
+  y = reshape (y, ny, nc);
+  szx = size (xi);
+  xi = xi (:);
+  range = find (xi >= x (1) & xi <= x (nx));
+  yi = NA (size(xi, 1), size (y, 2));
+  xi = xi (range);
+  dy = y (2 : ny, :) - y (1 : ny - 1, :);
+  dx = x (2 : nx) - x (1 : nx - 1);
+  idx = lookup (x, xi, "lr");
+  s = (xi - x (idx)) ./ dx (idx);
+  yi (range, :) = s (:, ones (1, nc)) .* dy (idx, :) + y (idx, :);
+  if (length (szx) == 2 && any (szx == 1))
+    yi = reshape (yi, [max(szx), szy(2:end)]);
+  else
+    yi = reshape (yi, [szx, szy(2:end)]);
+  endif
+endfunction
+
+%!shared xp, yp, xi, yi
+%! xp=[0:2:10].';      yp = sin(2*pi*xp/5);
+%! xi = [-1; 0; 2.2; 4; 6.6; 10; 11];
+%! yi = interp1 (xp,yp,xi);
+%!assert (interp1q(xp, yp, [min(xp)-1; max(xp)+1]), [NA; NA]);
+%!assert (interp1q(xp,yp,xp), yp, 100*eps);
+%!assert (isempty(interp1q(xp,yp,[])));
+%!assert (interp1q(xp,yp,xi), yi);
+%!assert (interp1q(xp,[yp,yp],xi), [yi, yi]);
+%!assert (interp1q(xp,yp,[xi,xi]), [yi, yi]);
+%!assert (interp1q(xp,[yp,yp],[xi,xi]), cat (3, [yi, yi], [yi, yi]));
diff --git a/scripts/general/interp2.m b/scripts/general/interp2.m
new file mode 100644
index 0000000..621fe1b
--- /dev/null
+++ b/scripts/general/interp2.m
@@ -0,0 +1,495 @@
+## Copyright (C) 2000, 2006, 2007, 2008 Kai Habel
+## Copyright (C) 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{zi} =} interp2 (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{xi}, @var{yi})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{n})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method}, @var{extrapval})
+##
+## Two-dimensional interpolation.  @var{x}, @var{y} and @var{z} describe a
+## surface function.  If @var{x} and @var{y} are vectors their length
+## must correspondent to the size of @var{z}.  @var{x} and @var{y} must be
+## monotonic.  If they are matrices they must have the @code{meshgrid} 
+## format. 
+##
+## @table @code
+## @item interp2 (@var{x}, @var{y}, @var{Z}, @var{xi}, @var{yi}, @dots{}) 
+## Returns a matrix corresponding to the points described by the
+## matrices @var{xi}, @var{yi}.  
+##
+## If the last argument is a string, the interpolation method can
+## be specified.  The method can be 'linear', 'nearest' or 'cubic'.
+## If it is omitted 'linear' interpolation is assumed.
+##
+## @item interp2 (@var{z}, @var{xi}, @var{yi})
+## Assumes @code{@var{x} = 1:rows (@var{z})} and @code{@var{y} = 
+## 1:columns (@var{z})}
+## 
+## @item interp2 (@var{z}, @var{n}) 
+## Interleaves the matrix @var{z} n-times.  If @var{n} is omitted a value
+## of @code{@var{n} = 1} is assumed.
+## @end table
+##
+## The variable @var{method} defines the method to use for the
+## interpolation.  It can take one of the following values 
+##
+## @table @asis
+## @item 'nearest'
+## Return the nearest neighbor.
+## @item 'linear'
+## Linear interpolation from nearest neighbors.
+## @item 'pchip'
+## Piece-wise cubic hermite interpolating polynomial (not implemented yet).
+## @item 'cubic'
+## Cubic interpolation from four nearest neighbors.
+## @item 'spline'
+## Cubic spline interpolation--smooth first and second derivatives
+## throughout the curve.
+## @end table
+##
+## If a scalar value @var{extrapval} is defined as the final value, then
+## values outside the mesh as set to this value.  Note that in this case 
+## @var{method} must be defined as well.  If @var{extrapval} is not
+## defined then NA is assumed. 
+##
+## @seealso{interp1}
+## @end deftypefn
+
+## Author:	Kai Habel <kai.habel at gmx.de>
+## 2005-03-02 Thomas Weber <weber at num.uni-sb.de> 
+##     * Add test cases
+## 2005-03-02 Paul Kienzle <pkienzle at users.sf.net>
+##     * Simplify
+## 2005-04-23 Dmitri A. Sergatskov <dasergatskov at gmail.com>
+##     * Modified demo and test for new gnuplot interface
+## 2005-09-07 Hoxide <hoxide_dirac at yahoo.com.cn>
+##     * Add bicubic interpolation method
+##     * Fix the eat line bug when the last element of XI or YI is
+##       negative or zero.
+## 2005-11-26 Pierre Baldensperger <balden at libertysurf.fr>
+##     * Rather big modification (XI,YI no longer need to be
+##       "meshgridded") to be consistent with the help message
+##       above and for compatibility.
+
+function ZI = interp2 (varargin)
+  Z = X = Y = XI = YI = n = [];
+  method = "linear";
+  extrapval = NA;
+
+  switch (nargin)
+    case 1
+      Z = varargin{1};
+    case 2
+      if (ischar (varargin{2}))
+	[Z, method] = deal (varargin{:});
+      else
+	[Z, n] = deal (varargin{:});
+      endif
+    case 3
+      if (ischar (varargin{3}))
+	[Z, n, method] = deal (varargin{:});
+      else
+	[Z, XI, YI] = deal (varargin{:});
+      endif
+    case 4
+      if (ischar (varargin{4}))
+	[Z, XI, YI, method] = deal (varargin{:});
+      else
+	[Z, n, method, extrapval] = deal (varargin{:});
+      endif
+    case 5
+      if (ischar (varargin{4}))
+	[Z, XI, YI, method, extrapval] = deal (varargin{:});
+      else
+	[X, Y, Z, XI, YI] = deal (varargin{:});
+      endif
+    case 6 
+	[X, Y, Z, XI, YI, method] = deal (varargin{:});
+    case 7
+	[X, Y, Z, XI, YI, method, extrapval] = deal (varargin{:});
+    otherwise
+      print_usage ();
+  endswitch
+
+  ## Type checking.
+  if (!ismatrix (Z))
+    error ("interp2 expected matrix Z"); 
+  endif
+  if (!isempty (n) && !isscalar (n))
+    error ("interp2 expected scalar n"); 
+  endif
+  if (!ischar (method))
+    error ("interp2 expected string 'method'"); 
+  endif
+  if (ischar (extrapval) || strcmp (extrapval, "extrap"))
+    extrapval = [];
+  elseif (!isscalar (extrapval))
+    error ("interp2 expected n extrapval");
+  endif
+
+  ## Define X, Y, XI, YI if needed
+  [zr, zc] = size (Z);
+  if (isempty (X))
+    X = 1:zc; 
+    Y = 1:zr;
+  endif
+  if (! isnumeric (X) || ! isnumeric (Y))
+    error ("interp2 expected numeric X, Y"); 
+  endif
+  if (! isempty (n))
+    p = 2^n; 
+    XI = (p:p*zc)/p; 
+    YI = (p:p*zr)'/p; 
+  endif
+  if (! isnumeric (XI) || ! isnumeric (YI))
+    error ("interp2 expected numeric XI, YI"); 
+  endif
+
+
+  if (strcmp (method, "linear") || strcmp (method, "nearest") ...
+      || strcmp (method, "pchip"))
+
+    ## If X and Y vectors produce a grid from them
+    if (isvector (X) && isvector (Y))
+      X = X(:); Y = Y(:);
+    elseif (size_equal (X, Y))
+      X = X(1,:)'; Y = Y(:,1);
+    else
+      error ("X and Y must be matrices of same size");
+    endif
+    if (columns (Z) != length (X) || rows (Z) != length (Y))
+      error ("X and Y size must match Z dimensions");
+    endif
+
+    ## If Xi and Yi are vectors of different orientation build a grid
+    if ((rows (XI) == 1 && columns (YI) == 1)
+	|| (columns (XI) == 1 && rows (YI) == 1))
+      [XI, YI] = meshgrid (XI, YI);
+    elseif (! size_equal (XI, YI))
+      error ("XI and YI must be matrices of same size");
+    endif
+
+    ## if XI, YI are vectors, X and Y should share their orientation.
+    if (rows (XI) == 1)
+      if (rows (X) != 1)
+        X = X.';
+      endif
+      if (rows (Y) != 1)
+        Y = Y.';
+      endif
+    elseif (columns (XI) == 1)
+      if (columns (X) != 1)
+        X = X.';
+      endif
+      if (columns (Y) != 1)
+        Y = Y.';
+      endif
+    endif
+
+    xidx = lookup (X, XI, "lr");
+    yidx = lookup (Y, YI, "lr");
+
+    if (strcmp (method, "linear"))
+      ## each quad satisfies the equation z(x,y)=a+b*x+c*y+d*xy
+      ##
+      ## a-b
+      ## | |
+      ## c-d
+      a = Z(1:(zr - 1), 1:(zc - 1));
+      b = Z(1:(zr - 1), 2:zc) - a;
+      c = Z(2:zr, 1:(zc - 1)) - a;
+      d = Z(2:zr, 2:zc) - a - b - c;
+
+      idx = sub2ind (size (a), yidx, xidx);
+
+      ## scale XI, YI values to a 1-spaced grid
+      Xsc = (XI - X(xidx)) ./ (X(xidx + 1) - X(xidx));
+      Ysc = (YI - Y(yidx)) ./ (Y(yidx + 1) - Y(yidx));
+
+      ## apply plane equation
+      ZI = a(idx) + b(idx).*Xsc + c(idx).*Ysc + d(idx).*Xsc.*Ysc;
+
+    elseif (strcmp (method, "nearest"))
+      ii = (XI - X(xidx) > X(xidx + 1) - XI);
+      jj = (YI - Y(yidx) > Y(yidx + 1) - YI);
+      idx = sub2ind (size (Z), yidx+jj, xidx+ii);
+      ZI = Z(idx);
+
+    elseif (strcmp (method, "pchip"))
+
+      if (length (X) < 2 || length (Y) < 2)
+	error ("interp2: pchip2 requires at least 2 points in each dimension")
+      endif
+
+      ## first order derivatives
+      DX = __pchip_deriv__ (X, Z, 2);
+      DY = __pchip_deriv__ (Y, Z, 1);
+      ## Compute mixed derivatives row-wise and column-wise, use the average.
+      DXY = (__pchip_deriv__ (X, DY, 2) + __pchip_deriv__ (Y, DX, 1))/2;
+      
+      ## do the bicubic interpolation
+      hx = diff (X); hx = hx(xidx);
+      hy = diff (Y); hy = hy(yidx);
+
+      tx = (XI - X(xidx)) ./ hx;
+      ty = (YI - Y(yidx)) ./ hy;
+
+      ## construct the cubic hermite base functions in x, y
+
+      ## formulas:
+      ## b{1,1} =    ( 2*t.^3 - 3*t.^2     + 1);
+      ## b{2,1} = h.*(   t.^3 - 2*t.^2 + t    );
+      ## b{1,2} =    (-2*t.^3 + 3*t.^2        );
+      ## b{2,2} = h.*(   t.^3 -   t.^2        );
+
+      ## optimized equivalents of the above:
+      t1 = tx.^2;
+      t2 = tx.*t1 - t1;
+      xb{2,2} = hx.*t2;
+      t1 = t2 - t1;
+      xb{2,1} = hx.*(t1 + tx);
+      t2 += t1;
+      xb{1,2} = -t2;
+      xb{1,1} = t2 + 1;
+
+      t1 = ty.^2;
+      t2 = ty.*t1 - t1;
+      yb{2,2} = hy.*t2;
+      t1 = t2 - t1;
+      yb{2,1} = hy.*(t1 + ty);
+      t2 += t1;
+      yb{1,2} = -t2;
+      yb{1,1} = t2 + 1;
+
+      ZI = zeros (size (XI));
+      for i = 1:2
+	for j = 1:2
+	  zidx = sub2ind (size (Z), yidx+(j-1), xidx+(i-1));
+	  ZI += xb{1,i} .* yb{1,j} .*   Z(zidx);
+	  ZI += xb{2,i} .* yb{1,j} .*  DX(zidx);
+	  ZI += xb{1,i} .* yb{2,j} .*  DY(zidx);
+	  ZI += xb{2,i} .* yb{2,j} .* DXY(zidx);
+	endfor
+      endfor
+
+    endif
+
+    if (! isempty (extrapval))
+      ## set points outside the table to 'extrapval'
+      if (X (1) < X (end))
+	if (Y (1) < Y (end))
+	  ZI (XI < X(1,1) | XI > X(end) | YI < Y(1,1) | YI > Y(end)) = ...
+		  extrapval;
+	else
+	  ZI (XI < X(1) | XI > X(end) | YI < Y(end) | YI > Y(1)) = ...
+		  extrapval;
+	endif
+      else
+	if (Y (1) < Y (end))
+	  ZI (XI < X(end) | XI > X(1) | YI < Y(1) | YI > Y(end)) = ...
+		  extrapval;
+	else
+	  ZI (XI < X(1,end) | XI > X(1) | YI < Y(end) | YI > Y(1)) = ...
+		  extrapval;
+	endif
+      endif
+    endif
+
+  else
+
+    ## If X and Y vectors produce a grid from them
+    if (isvector (X) && isvector (Y))
+      X = X(:).';
+      Y = Y(:);
+      if (!isequal ([length(X), length(Y)], size(Z)))
+	error ("X and Y size must match Z dimensions");
+      endif
+    elseif (!size_equal (X, Y))
+      error ("X and Y must be matrices of same size");
+      if (! size_equal (X, Z))
+	error ("X and Y size must match Z dimensions");
+      endif
+    endif
+
+    ## If Xi and Yi are vectors of different orientation build a grid
+    if ((rows (XI) == 1 && columns (YI) == 1)
+	|| (columns (XI) == 1 && rows (YI) == 1))
+      ## Do nothing
+    elseif (! size_equal (XI, YI))
+      error ("XI and YI must be matrices of same size");
+    endif
+
+    ## FIXME bicubic/__splinen__ don't handle arbitrary XI, YI
+    if (strcmp (method, "cubic"))
+      ZI = bicubic (X, Y, Z, XI(1,:), YI(:,1), extrapval);
+
+    elseif (strcmp (method, "spline"))
+      ZI = __splinen__ ({Y(:,1).', X(1,:)}, Z, {YI(:,1), XI(1,:)}, extrapval, 
+			"spline");
+    else
+      error ("interpolation method not recognized");
+    endif
+
+  endif
+endfunction
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,4]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'linear'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! [x,y,A] = peaks(10);
+%! x = x(1,:)'; y = y(:,1);
+%! xi=linspace(min(x),max(x),41);
+%! yi=linspace(min(y),max(y),41)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'linear'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,4]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'nearest'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! [x,y,A] = peaks(10);
+%! x = x(1,:)'; y = y(:,1);
+%! xi=linspace(min(x),max(x),41);
+%! yi=linspace(min(y),max(y),41)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'nearest'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,2]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'pchip'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! [x,y,A] = peaks(10);
+%! x = x(1,:)'; y = y(:,1);
+%! xi=linspace(min(x),max(x),41);
+%! yi=linspace(min(y),max(y),41)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'pchip'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,2]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'cubic'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! [x,y,A] = peaks(10);
+%! x = x(1,:)'; y = y(:,1);
+%! xi=linspace(min(x),max(x),41);
+%! yi=linspace(min(y),max(y),41)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'cubic'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,2]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'spline'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! [x,y,A] = peaks(10);
+%! x = x(1,:)'; y = y(:,1);
+%! xi=linspace(min(x),max(x),41);
+%! yi=linspace(min(y),max(y),41)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'spline'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!test % simple test
+%!  x = [1,2,3];
+%!  y = [4,5,6,7];
+%!  [X, Y] = meshgrid(x,y);
+%!  Orig = X.^2 + Y.^3;
+%!  xi = [1.2,2, 1.5];
+%!  yi = [6.2, 4.0, 5.0]';
+%!
+%!  Expected = ...
+%!    [243,   245.4,  243.9;
+%!      65.6,  68,     66.5;
+%!     126.6, 129,    127.5];
+%!  Result = interp2(x,y,Orig, xi, yi);
+%!
+%!  assert(Result, Expected, 1000*eps);
+
+%!test % 2^n form
+%!  x = [1,2,3];
+%!  y = [4,5,6,7];
+%!  [X, Y] = meshgrid(x,y);
+%!  Orig = X.^2 + Y.^3;
+%!  xi = [1:0.25:3]; yi = [4:0.25:7]';
+%!  Expected = interp2(x,y,Orig, xi, yi);
+%!  Result = interp2(Orig,2);
+%!  
+%!  assert(Result, Expected, 10*eps);
+
+%!test % matrix slice
+%!  A = eye(4);
+%!  assert(interp2(A,[1:4],[1:4]),[1,1,1,1]);
+
+%!test % non-gridded XI,YI
+%!  A = eye(4);
+%!  assert(interp2(A,[1,2;3,4],[1,3;2,4]),[1,0;0,1]);
+
+%!test % for values outside of boundaries
+%!  x = [1,2,3];
+%!  y = [4,5,6,7];
+%!  [X, Y] = meshgrid(x,y);
+%!  Orig = X.^2 + Y.^3;
+%!  xi = [0,4];
+%!  yi = [3,8]';
+%!  assert(interp2(x,y,Orig, xi, yi),[NA,NA;NA,NA]);
+%!  assert(interp2(x,y,Orig, xi, yi,'linear', 0),[0,0;0,0]);
+
+%!test % for values at boundaries
+%!  A=[1,2;3,4];
+%!  x=[0,1]; 
+%!  y=[2,3]';
+%!  assert(interp2(x,y,A,x,y,'linear'), A);
+%!  assert(interp2(x,y,A,x,y,'nearest'), A);
+
diff --git a/scripts/general/interp3.m b/scripts/general/interp3.m
new file mode 100644
index 0000000..f069d27
--- /dev/null
+++ b/scripts/general/interp3.m
@@ -0,0 +1,145 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{vi} =} interp3 (@var{x}, @var{y}, at var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
+## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{xi}, @var{yi}, @var{zi})
+## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{m})
+## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v})
+## @deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method})
+## @deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method}, @var{extrapval})
+##
+## Perform 3-dimensional interpolation.  Each element of the 3-dimensional 
+## array @var{v} represents a value at a location given by the parameters 
+## @var{x}, @var{y}, and @var{z}.  The parameters @var{x}, @var{x}, and 
+## @var{z} are either 3-dimensional arrays of the same size as the array 
+## @var{v} in the 'meshgrid' format or vectors.  The parameters @var{xi}, etc. 
+## respect a similar format to @var{x}, etc., and they represent the points 
+## at which the array @var{vi} is interpolated.
+##
+## If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be 
+## @code{x = 1 : size (@var{v}, 2)}, @code{y = 1 : size (@var{v}, 1)} and
+## @code{z = 1 : size (@var{v}, 3)}.  If @var{m} is specified, then
+## the interpolation adds a point half way between each of the interpolation 
+## points.  This process is performed @var{m} times.  If only @var{v} is 
+## specified, then @var{m} is assumed to be @code{1}.
+##
+## Method is one of:
+##
+## @table @asis
+## @item 'nearest'
+## Return the nearest neighbor.
+## @item 'linear'
+## Linear interpolation from nearest neighbors.
+## @item 'cubic'
+## Cubic interpolation from four nearest neighbors (not implemented yet).
+## @item 'spline'
+## Cubic spline interpolation--smooth first and second derivatives
+## throughout the curve.
+## @end table
+##
+## The default method is 'linear'.
+##
+## If @var{extrap} is the string 'extrap', then extrapolate values beyond
+## the endpoints.  If @var{extrap} is a number, replace values beyond the
+## endpoints with that number.  If @var{extrap} is missing, assume NA.
+## @seealso{interp1, interp2, spline, meshgrid}
+## @end deftypefn
+
+function vi = interp3 (varargin)
+  method = "linear";
+  extrapval = NA;
+  nargs = nargin;
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (ischar (varargin{end}))
+    method = varargin{end};
+    nargs = nargs - 1;
+  elseif (ischar (varargin{end-1}))
+    if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
+      error ("extrapal is expected to be a numeric scalar");
+    endif
+    extrapval = varargin{end};
+    method = varargin{end-1};
+    nargs = nargs - 2;
+  endif
+
+  if (nargs < 3 || (nargs == 4 && ! isvector (varargin{1})
+		    && nargs == (ndims (varargin{1}) + 1)))
+    v = varargin{1};
+    if (ndims (v) != 3)
+      error ("expect 3-dimensional array of values");
+    endif
+    x = varargin (2:4);
+    if (any (! cellfun (@isvector, x)))
+      for i = 2 : 3
+	if (! size_equal (x{1}, x{i}))
+	  error ("dimensional mismatch");
+	endif
+	x{i} = permute (x{i}, [2, 1, 3]);
+      endfor
+      x{1} = permute (x{1}, [2, 1, 3]);
+    endif
+    v = permute (v, [2, 1, 3]);
+    vi = ipermute (interpn (v, x{:}, method, extrapval), [2, 1, 3]);
+  elseif (nargs == 7 && nargs == (2 * ndims (varargin{ceil (nargs / 2)})) + 1)
+    v = varargin{4};
+    if (ndims (v) != 3)
+      error ("expect 3-dimensional array of values");
+    endif
+    x = varargin (1:3);
+    if (any (! cellfun (@isvector, x)))
+      for i = 2 : 3
+	if (! size_equal (x{1}, x{i}) || ! size_equal (x{i}, v))
+	  error ("dimensional mismatch");
+	endif
+	x{i} = permute (x{i}, [2, 1, 3]);
+      endfor
+      x{1} = permute (x{1}, [2, 1, 3]);
+    endif
+    y = varargin (5:7);
+    if (any (! cellfun (@isvector, y)))
+      for i = 2 : 3
+	if (! size_equal (y{1}, y{i}))
+	  error ("dimensional mismatch");
+	endif
+	y{i} = permute (y{i}, [2, 1, 3]);
+      endfor
+      y{1} = permute (y{1}, [2, 1, 3]);
+    endif
+    v = permute (v, [2, 1, 3]);
+    vi = ipermute (interpn (x{:}, v, y{:}, method, extrapval), [2, 1, 3]);
+  else
+    error ("wrong number or incorrectly formatted input arguments");
+  endif
+endfunction
+
+%!test
+%! x = y = z = -1:1;
+%! f = @(x,y,z) x.^2 - y - z.^2;
+%! [xx, yy, zz] = meshgrid (x, y, z);
+%! v = f (xx,yy,zz);
+%! xi = yi = zi = -1:0.5:1;
+%! [xxi, yyi, zzi] = meshgrid (xi, yi, zi);
+%! vi = interp3(x, y, z, v, xxi, yyi, zzi);
+%! [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+%! vi2 = interpn(x, y, z, v, xxi, yyi, zzi);
+%! assert (vi, vi2);
diff --git a/scripts/general/interpft.m b/scripts/general/interpft.m
new file mode 100644
index 0000000..3e4a0e2
--- /dev/null
+++ b/scripts/general/interpft.m
@@ -0,0 +1,114 @@
+## Copyright (C) 2001, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} interpft (@var{x}, @var{n})
+## @deftypefnx {Function File} {} interpft (@var{x}, @var{n}, @var{dim})
+##
+## Fourier interpolation.  If @var{x} is a vector, then @var{x} is
+## resampled with @var{n} points.  The data in @var{x} is assumed to be
+## equispaced.  If @var{x} is an array, then operate along each column of
+## the array separately.  If @var{dim} is specified, then interpolate
+## along the dimension @var{dim}.
+##
+## @code{interpft} assumes that the interpolated function is periodic,
+## and so assumptions are made about the end points of the interpolation.
+##
+## @seealso{interp1}
+## @end deftypefn
+
+## Author: Paul Kienzle
+## 2001-02-11
+##    * initial version
+## 2002-03-17 aadler
+##    * added code to work on matrices as well 
+## 2006-05-25 dbateman
+##    * Make it matlab compatiable, cutting out the 2-D interpolation
+
+function z = interpft (x, n, dim)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    if (isvector (x) && size (x, 1) == 1)
+      dim = 2;
+    else
+      dim = 1;
+    endif
+  endif
+
+  if (! isscalar (n))
+    error ("interpft: n must be an integer scalar");
+  endif
+
+  nd = ndims (x);
+
+  if (dim < 1 || dim > nd)
+    error ("interpft: integrating over invalid dimension");
+  endif
+
+  perm = [dim:nd, 1:(dim-1)];
+  x = permute (x, perm);
+  m = size (x, 1);
+
+  inc = 1;
+  while (inc*n < m)
+    inc++;
+  endwhile
+  y = fft (x) / m;
+  k = floor (m / 2);
+  sz = size (x);
+  sz(1) = n * inc - m;
+  idx = cell (nd, 1);
+  for i = 2:nd
+    idx{i} = 1:sz(i);
+  endfor
+  idx{1} = 1:k;
+  z = cat (1, y(idx{:}), zeros (sz));
+  idx{1} = k+1:m;
+  z = cat (1, z, y(idx{:}));
+  z = n * ifft (z);
+
+  if (inc != 1)
+    sz(1) = n;
+    z = inc * reshape (z(1:inc:end), sz);
+  endif
+
+  z = ipermute (z, perm);
+endfunction
+
+%!demo
+%! t = 0 : 0.3 : pi; dt = t(2)-t(1);
+%! n = length (t); k = 100;
+%! ti = t(1) + [0 : k-1]*dt*n/k;
+%! y = sin (4*t + 0.3) .* cos (3*t - 0.1);
+%! yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
+%! plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ...
+%!       ti, interpft (y, k), 'c', t, y, 'r+');
+%! legend ('sin(4t+0.3)cos(3t-0.1','spline','interpft','data');
+
+%!shared n,y
+%! x = [0:10]'; y = sin(x); n = length (x);
+%!assert (interpft(y, n), y, 20*eps);
+%!assert (interpft(y', n), y', 20*eps);
+%!assert (interpft([y,y],n), [y,y], 20*eps);
+
+%!error (interpft(y,n,0))
+%!error (interpft(y,[n,n]))
diff --git a/scripts/general/interpn.m b/scripts/general/interpn.m
new file mode 100644
index 0000000..3471fc6
--- /dev/null
+++ b/scripts/general/interpn.m
@@ -0,0 +1,258 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{vi} =} interpn (@var{x1}, @var{x2}, @dots{}, @var{v}, @var{y1}, @var{y2}, @dots{})
+## @deftypefnx {Function File} {@var{vi} =} interpn (@var{v}, @var{y1}, @var{y2}, @dots{})
+## @deftypefnx {Function File} {@var{vi} =} interpn (@var{v}, @var{m})
+## @deftypefnx {Function File} {@var{vi} =} interpn (@var{v})
+## @deftypefnx {Function File} {@var{vi} =} interpn (@dots{}, @var{method})
+## @deftypefnx {Function File} {@var{vi} =} interpn (@dots{}, @var{method}, @var{extrapval})
+##
+## Perform @var{n}-dimensional interpolation, where @var{n} is at least two. 
+## Each element of the @var{n}-dimensional array @var{v} represents a value 
+## at a location given by the parameters @var{x1}, @var{x2}, @dots{}, @var{xn}. 
+## The parameters @var{x1}, @var{x2}, @dots{}, @var{xn} are either 
+## @var{n}-dimensional arrays of the same size as the array @var{v} in 
+## the 'ndgrid' format or vectors.  The parameters @var{y1}, etc. respect a 
+## similar format to @var{x1}, etc., and they represent the points at which
+## the array @var{vi} is interpolated.
+##
+## If @var{x1}, @dots{}, @var{xn} are omitted, they are assumed to be 
+## @code{x1 = 1 : size (@var{v}, 1)}, etc.  If @var{m} is specified, then
+## the interpolation adds a point half way between each of the interpolation 
+## points.  This process is performed @var{m} times.  If only @var{v} is 
+## specified, then @var{m} is assumed to be @code{1}.
+##
+## Method is one of:
+##
+## @table @asis
+## @item 'nearest'
+## Return the nearest neighbor.
+## @item 'linear'
+## Linear interpolation from nearest neighbors.
+## @item 'cubic'
+## Cubic interpolation from four nearest neighbors (not implemented yet).
+## @item 'spline'
+## Cubic spline interpolation--smooth first and second derivatives
+## throughout the curve.
+## @end table
+##
+## The default method is 'linear'.
+##
+## If @var{extrapval} is the scalar value, use it to replace the values
+## beyond the endpoints with that number.  If @var{extrapval} is missing,
+## assume NA.
+## @seealso{interp1, interp2, spline, ndgrid}
+## @end deftypefn
+
+function vi = interpn (varargin)
+
+  method = "linear";
+  extrapval = NA;
+  nargs = nargin;
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (ischar (varargin{end}))
+    method = varargin{end};
+    nargs = nargs - 1;
+  elseif (ischar (varargin{end - 1}))
+    if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
+      error ("extrapal is expected to be a numeric scalar");
+    endif
+    method = varargin{end - 1};
+    extrapval = varargin{end};
+    nargs = nargs - 2;
+  endif
+
+  if (nargs < 3)
+    v = varargin{1};
+    m = 1;
+    if (nargs == 2)
+      m = varargin{2};
+      if (! isnumeric (m) || ! isscalar (m) || floor (m) != m)
+	error ("m is expected to be a integer scalar");
+      endif
+    endif
+    sz = size (v);
+    nd = ndims (v);
+    x = cell (1, nd);
+    y = cell (1, nd);
+    for i = 1 : nd;
+      x{i} = 1 : sz(i);
+      y{i} = 1 : (1 / (2 ^ m)) : sz(i);
+    endfor
+  elseif (! isvector (varargin{1}) && nargs == (ndims (varargin{1}) + 1))
+    v = varargin{1};
+    sz = size (v);
+    nd = ndims (v);
+    x = cell (1, nd);
+    y = varargin (2 : nargs);
+    for i = 1 : nd;
+      x{i} = 1 : sz(i);
+    endfor
+  elseif (rem (nargs, 2) == 1 && nargs ==  
+	  (2 * ndims (varargin{ceil (nargs / 2)})) + 1)
+    nv = ceil (nargs / 2);
+    v = varargin{nv};
+    sz = size (v);
+    nd = ndims (v);
+    x = varargin (1 : (nv - 1));
+    y = varargin ((nv + 1) : nargs);
+  else
+    error ("wrong number or incorrectly formatted input arguments");
+  endif
+
+  if (any (! cellfun (@isvector, x)))
+    for i = 2 : nd
+      if (! size_equal (x{1}, x{i}) || ! size_equal (x{i}, v))
+	error ("dimensional mismatch");
+      endif
+      idx (1 : nd) = {1};
+      idx (i) = ":";
+      x{i} = x{i}(idx{:})(:);
+    endfor
+    idx (1 : nd) = {1};
+    idx (1) = ":";
+    x{1} = x{1}(idx{:})(:);
+  endif
+
+  method = tolower (method);
+
+  if (strcmp (method, "linear"))
+    vi = __lin_interpn__ (x{:}, v, y{:});
+    vi (isna (vi)) = extrapval;
+  elseif (strcmp (method, "nearest"))
+    yshape = size (y{1});
+    yidx = cell (1, nd);
+    for i = 1 : nd
+      y{i} = y{i}(:);
+      yidx{i} = lookup (x{i}, y{i}, "lr");
+    endfor
+    idx = cell (1,nd);
+    for i = 1 : nd
+      idx{i} = yidx{i} + (y{i} - x{i}(yidx{i}) > x{i}(yidx{i} + 1) - y{i});
+    endfor
+    vi = v (sub2ind (sz, idx{:}));
+    idx = zeros (prod(yshape),1);
+    for i = 1 : nd
+      idx |= y{i} < min (x{i}(:)) | y{i} > max (x{i}(:));
+    endfor
+    vi(idx) = extrapval;
+    vi = reshape (vi, yshape); 
+  elseif (strcmp (method, "spline"))
+    if (any (! cellfun (@isvector, y)))
+      for i = 2 : nd
+	if (! size_equal (y{1}, y{i}))
+	  error ("dimensional mismatch");
+	endif
+	idx (1 : nd) = {1};
+	idx (i) = ":";
+	y{i} = y{i}(idx{:});
+      endfor
+      idx (1 : nd) = {1};
+      idx (1) = ":";
+      y{1} = y{1}(idx{:});
+    endif
+
+    vi = __splinen__ (x, v, y, extrapval, "interpn");
+
+    if (size_equal (y{:}))
+      ly = length (y{1});
+      idx = cell (1, ly);
+      q = cell (1, nd);
+      for i = 1 : ly
+ 	q(:) = i;
+ 	idx {i} = q;
+      endfor
+      vi = vi (cellfun (@(x) sub2ind (size(vi), x{:}), idx));
+      vi = reshape (vi, size(y{1}));
+    endif
+  elseif (strcmp (method, "cubic")) 
+    error ("cubic interpolation not yet implemented");
+  else
+    error ("unrecognized interpolation method");
+  endif
+
+endfunction
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,4]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! AI=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interpn(x,y,A.',xi,yi,"linear").');
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,4]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interpn(x,y,A.',xi,yi,"nearest").');
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!#demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,2]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interpn(x,y,A.',xi,yi,"cubic").');
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,2]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interpn(x,y,A.',xi,yi,"spline").');
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
+
+%!demo
+%! x = y = z = -1:1;
+%! f = @(x,y,z) x.^2 - y - z.^2;
+%! [xx, yy, zz] = meshgrid (x, y, z);
+%! v = f (xx,yy,zz);
+%! xi = yi = zi = -1:0.1:1;
+%! [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
+%! vi = interpn(x, y, z, v, xxi, yyi, zzi, 'spline');
+%! mesh (yi, zi, squeeze (vi(1,:,:)));
+
+
+%!test
+%! [x,y,z] = ndgrid(0:2);
+%! f = x+y+z;
+%! assert (interpn(x,y,z,f,[.5 1.5],[.5 1.5],[.5 1.5]), [1.5, 4.5])
+%! assert (interpn(x,y,z,f,[.51 1.51],[.51 1.51],[.51 1.51],'nearest'), [3, 6])
+%! assert (interpn(x,y,z,f,[.5 1.5],[.5 1.5],[.5 1.5],'spline'), [1.5, 4.5])
+%! assert (interpn(x,y,z,f,x,y,z), f)
+%! assert (interpn(x,y,z,f,x,y,z,'nearest'), f)
+%! assert (interpn(x,y,z,f,x,y,z,'spline'), f)
+
+%!test
+%! [x,y,z] = ndgrid(0:2);
+%! f = x.^2+y.^2+z.^2;
+%! assert (interpn(x,y,-z,f,1.5,1.5,-1.5), 7.5)
diff --git a/scripts/general/is_duplicate_entry.m b/scripts/general/is_duplicate_entry.m
new file mode 100644
index 0000000..a7b2afe
--- /dev/null
+++ b/scripts/general/is_duplicate_entry.m
@@ -0,0 +1,45 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007
+##               A. S. Hodel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_duplicate_entry (@var{x})
+## Return non-zero if any entries in @var{x} are duplicates of one
+## another.
+## @end deftypefn
+
+## Author: A. S. Hodel <scotte at eng.auburn.edu>
+
+function retval = is_duplicate_entry (x)
+
+  if (nargin == 1)
+    if (ismatrix (x))
+      lx = numel (x);
+      lx1 = lx-1;
+      x = sort (reshape (x, 1, lx));
+      dx = x(1:lx1) - x(2:lx);
+      retval = sum (dx == 0);
+    else
+      error ("is_duplicate_entry: expecting matrix argument");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
diff --git a/scripts/general/isa.m b/scripts/general/isa.m
new file mode 100644
index 0000000..f86b576
--- /dev/null
+++ b/scripts/general/isa.m
@@ -0,0 +1,74 @@
+## Copyright (C) 2004, 2005, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isa (@var{x}, @var{class})
+## Return true if @var{x} is a value from the class @var{class}.
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+## Adapted-by: jwe
+
+function retval = isa (x, cname)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  persistent float_classes = {"double", "single"};
+
+  persistent fnum_classes = {"double", "single", ...
+			     "uint8", "uint16", "uint32", "uint64", ...
+			     "int8", "int16", "int32", "int64"};
+
+  if (strcmp (cname, "float"))
+    retval = any (strcmp (class (x), float_classes));
+  elseif (strcmp (cname, "numeric"))
+    retval = any (strcmp (class (x), fnum_classes));
+  else
+    class_of_x = class (x);
+    retval = strcmp (class_of_x, cname);
+    if (! retval && isobject (x))
+      retval = __isa_parent__ (x, cname);
+    endif
+  endif
+
+endfunction
+
+%!assert (isa ("char", "float"), false)
+%!assert (isa (double (13), "float"), true)
+%!assert (isa (single (13), "float"), true)
+%!assert (isa (int8 (13), "float"), false)
+%!assert (isa (int16 (13), "float"), false)
+%!assert (isa (int32 (13), "float"), false)
+%!assert (isa (int64 (13), "float"), false)
+%!assert (isa (uint8 (13), "float"), false)
+%!assert (isa (uint16 (13), "float"), false)
+%!assert (isa (uint32 (13), "float"), false)
+%!assert (isa (uint64 (13), "float"), false)
+%!assert (isa ("char", "numeric"), false)
+%!assert (isa (double (13), "numeric"), true)
+%!assert (isa (single (13), "numeric"), true)
+%!assert (isa (int8 (13), "numeric"), true)
+%!assert (isa (int16 (13), "numeric"), true)
+%!assert (isa (int32 (13), "numeric"), true)
+%!assert (isa (int64 (13), "numeric"), true)
+%!assert (isa (uint8 (13), "numeric"), true)
+%!assert (isa (uint16 (13), "numeric"), true)
+%!assert (isa (uint32 (13), "numeric"), true)
+%!assert (isa (uint64 (13), "numeric"), true)
diff --git a/scripts/general/isdefinite.m b/scripts/general/isdefinite.m
new file mode 100644
index 0000000..83fa904
--- /dev/null
+++ b/scripts/general/isdefinite.m
@@ -0,0 +1,60 @@
+## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Gabriele Pannocchia
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isdefinite (@var{x}, @var{tol})
+## Return 1 if @var{x} is symmetric positive definite within the
+## tolerance specified by @var{tol} or 0 if @var{x} is symmetric
+## positive semidefinite.  Otherwise, return -1.  If @var{tol}
+## is omitted, use a tolerance equal to 100 times the machine precision.
+## @seealso{issymmetric}
+## @end deftypefn
+
+## Author: Gabriele Pannocchia <g.pannocchia at ing.unipi.it>
+## Created: November 2003
+## Adapted-By: jwe
+
+function retval = isdefinite (x, tol)
+
+  if (nargin == 1 || nargin == 2)
+    if (nargin == 1)
+      if (isa (x, "single"))
+	tol = 100 * eps("single");
+      else
+	tol = 100*eps; 
+      endif
+    endif
+    sym = issymmetric (x, tol);
+    if (sym > 0)
+      ## Matrix is symmetric, check eigenvalues.
+      mineig = min (eig (x));
+      if (mineig > tol)
+	retval = 1;
+      elseif (mineig > -tol)
+	retval = 0;
+      else
+	retval = -1;
+      endif
+    else
+      error ("isdefinite: matrix x must be symmetric");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/general/isdir.m b/scripts/general/isdir.m
new file mode 100644
index 0000000..fd13a53
--- /dev/null
+++ b/scripts/general/isdir.m
@@ -0,0 +1,31 @@
+## Copyright (C) 2004, 2006, 2007 Alois Schloegl 
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isdir (@var{f})
+## Return true if @var{f} is a directory.
+## @end deftypefn
+
+function t = isdir (x)
+  if (nargin == 1)
+    ## Exist returns an integer but isdir should return a logical.
+    t = exist (x, "dir") == 7;
+  else
+    print_usage ("isdir");
+  endif
+endfunction
diff --git a/scripts/general/isequal.m b/scripts/general/isequal.m
new file mode 100644
index 0000000..64077cf
--- /dev/null
+++ b/scripts/general/isequal.m
@@ -0,0 +1,34 @@
+## Copyright (C) 2005, 2006, 2007 William Poetra Yoga Hadisoeseno
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isequal (@var{x1}, @var{x2}, @dots{})
+## Return true if all of @var{x1}, @var{x2}, @dots{} are equal.
+## @seealso{isequalwithequalnans}
+## @end deftypefn
+
+function retval = isequal (x, varargin)
+
+  if (nargin > 1)
+    retval = __isequal__ (0, x, varargin{:});
+  else
+    print_usage ();
+  endif
+
+endfunction
+
diff --git a/scripts/general/isequalwithequalnans.m b/scripts/general/isequalwithequalnans.m
new file mode 100644
index 0000000..ec78f93
--- /dev/null
+++ b/scripts/general/isequalwithequalnans.m
@@ -0,0 +1,35 @@
+## Copyright (C) 2005, 2006, 2007 William Poetra Yoga Hadisoeseno
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isequalwithequalnans (@var{x1}, @var{x2}, @dots{})
+## Assuming NaN == NaN, return true if all of @var{x1}, @var{x2}, @dots{}
+## are equal.
+## @seealso{isequal}
+## @end deftypefn
+
+function retval = isequalwithequalnans (x, varargin)
+
+  if (nargin > 1)
+    retval = __isequal__ (1, x, varargin{:});
+  else
+    print_usage ();
+  endif
+
+endfunction
+
diff --git a/scripts/general/isscalar.m b/scripts/general/isscalar.m
new file mode 100644
index 0000000..6c953cf
--- /dev/null
+++ b/scripts/general/isscalar.m
@@ -0,0 +1,60 @@
+## Copyright (C) 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isscalar (@var{a})
+## Return 1 if @var{a} is a scalar.  Otherwise, return 0.
+## @seealso{size, rows, columns, length, isscalar, ismatrix}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = isscalar (x)
+
+  if (nargin == 1)
+    retval = numel (x) == 1;
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(isscalar (1));
+
+%!assert(!(isscalar ([1, 2])));
+
+%!assert(!(isscalar ([])));
+
+%!assert(!(isscalar ([1, 2; 3, 4])));
+
+%!test
+%! warn_str_to_num = 0;
+%! assert((isscalar ("t")));
+
+%!assert(!(isscalar ("test")));
+
+%!assert(!(isscalar (["test"; "ing"])));
+
+%!test
+%! s.a = 1;
+%! assert((isscalar (s)));
+
+%!error isscalar ();
+
+%!error isscalar (1, 2);
+
diff --git a/scripts/general/issquare.m b/scripts/general/issquare.m
new file mode 100644
index 0000000..d80f72c
--- /dev/null
+++ b/scripts/general/issquare.m
@@ -0,0 +1,74 @@
+## Copyright (C) 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} issquare (@var{x})
+## If @var{x} is a square matrix, then return the dimension of @var{x}.
+## Otherwise, return 0.
+## @seealso{size, rows, columns, length, ismatrix, isscalar, isvector}
+## @end deftypefn
+
+## Author: A. S. Hodel <scotte at eng.auburn.edu>
+## Created: August 1993
+## Adapted-By: jwe
+
+function retval = issquare (x)
+
+  retval = 0;
+
+  if (nargin == 1)
+    if (ismatrix (x) && ndims (x) < 3)
+      [nr, nc] = size (x);
+      if (nr == nc && nr > 0)
+        retval = nr;
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(issquare (1));
+
+%!assert(!(issquare ([1, 2])));
+
+%!assert(!(issquare ([])));
+
+%!assert(issquare ([1, 2; 3, 4]) == 2);
+
+%!test
+%! warn_str_to_num = 0;
+%! assert(!(issquare ("t")));
+
+%!assert(!(issquare ("test")));
+
+%!test
+%! warn_str_to_num = 0;
+%! assert(!(issquare (["test"; "ing"; "1"; "2"])));
+
+%!test
+%! s.a = 1;
+%! assert(!(issquare (s)));
+
+%!assert(!(issquare ([1, 2; 3, 4; 5, 6])));
+
+%!error issquare ();
+
+%!error issquare ([1, 2; 3, 4], 2);
+
diff --git a/scripts/general/issymmetric.m b/scripts/general/issymmetric.m
new file mode 100644
index 0000000..6b88bf3
--- /dev/null
+++ b/scripts/general/issymmetric.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} issymmetric (@var{x}, @var{tol})
+## If @var{x} is symmetric within the tolerance specified by @var{tol},
+## then return the dimension of @var{x}.  Otherwise, return 0.  If
+## @var{tol} is omitted, use a tolerance equal to the machine precision.
+## Matrix @var{x} is considered symmetric if
+## @code{norm (@var{x} - @var{x}.', inf) / norm (@var{x}, inf) < @var{tol}}.
+## @seealso{size, rows, columns, length, ismatrix, isscalar,
+## issquare, isvector}
+## @end deftypefn
+
+## Author: A. S. Hodel <scotte at eng.auburn.edu>
+## Created: August 1993
+## Adapted-By: jwe
+
+function retval = issymmetric (x, tol)
+
+  if (nargin == 1 || nargin == 2)
+    retval = issquare (x);
+    if (retval != 0)
+      if (nargin == 1)
+	if (isa (x, "single"))
+	  tol = eps("single");
+	else
+	  tol = eps; 
+	endif
+      endif
+      norm_x = norm (x, inf);
+      if (norm_x != 0 && norm (x - x', inf) / norm_x > tol)
+        retval = 0;
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(issymmetric (1));
+%!assert(!(issymmetric ([1, 2])));
+%!assert(!(issymmetric ([])));
+%!assert(issymmetric ([1, 2; 2, 1]) == 2);
+%!assert(!(issymmetric ("test")));
+%!assert(issymmetric ([1, 2.1; 2, 1.1], 0.2) == 2);
+%!assert(issymmetric ([1, 2i; -2i, 1]));
+%!assert(!(issymmetric ("t")));
+%!assert(!(issymmetric (["te"; "et"])));
+%!error issymmetric ([1, 2; 2, 1], 0, 0);
+%!error issymmetric ();
+
+%!test
+%! s.a = 1;
+%! assert(!(issymmetric (s)));
diff --git a/scripts/general/isvector.m b/scripts/general/isvector.m
new file mode 100644
index 0000000..334101b
--- /dev/null
+++ b/scripts/general/isvector.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isvector (@var{a})
+## Return 1 if @var{a} is a vector.  Otherwise, return 0.
+## @seealso{size, rows, columns, length, isscalar, ismatrix}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = isvector (x)
+
+  retval = 0;
+
+  if (nargin == 1)
+    sz = size (x);
+    retval = (ndims (x) == 2 && (sz(1) == 1 || sz(2) == 1));
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(isvector (1));
+
+%!assert(isvector ([1; 2; 3]));
+
+%!assert(!(isvector ([])));
+
+%!assert(!(isvector ([1, 2; 3, 4])));
+
+%!test
+%! warn_str_to_num = 0;
+%! assert((isvector ("t")));
+
+%!test
+%! warn_str_to_num = 0;
+%! assert((isvector ("test")));
+
+%!assert(!(isvector (["test"; "ing"])));
+
+%!test
+%! s.a = 1;
+%! assert((isvector (s)));
+
+%!error isvector ();
+
+%!error isvector ([1, 2], 2);
+
diff --git a/scripts/general/loadobj.m b/scripts/general/loadobj.m
new file mode 100644
index 0000000..70cbe58
--- /dev/null
+++ b/scripts/general/loadobj.m
@@ -0,0 +1,41 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{b} =} loadobj (@var{a})
+## Method of a class to manipulate an object after loading it from a file. 
+## The function @code{loadobj} is called when the object @var{a} is loaded 
+## using the @code{load} function.  An example of the use of @code{saveobj}
+## might be to add fields to an object that don't make sense to be saved.
+## For example
+##
+## @example
+## @group
+## function b = loadobj (a)
+##   b = a;
+##   b.addmissingfield = addfield (b);
+## endfunction
+## @end group
+## @end example
+##
+## @seealso{saveobj, class}
+## @end deftypefn
+
+function b = loadobj (a)
+  error ("loadobj: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/scripts/general/logical.m b/scripts/general/logical.m
new file mode 100644
index 0000000..8298bf4
--- /dev/null
+++ b/scripts/general/logical.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logical (@var{arg})
+## Convert @var{arg} to a logical value.  For example,
+##
+## @example
+## logical ([-1, 0, 1])
+## @end example
+##
+## @noindent
+## is equivalent to
+##
+## @example
+## [-1, 0, 1] != 0
+## @end example
+## @end deftypefn
+
+## Author: jwe
+
+function y = logical (x)
+
+  if (nargin == 1)
+    if (islogical (x))
+      y = x;
+    elseif (isempty (x))
+      y = zeros (size (x), "logical");
+    elseif (isnumeric (x))
+      if (any (isnan (x(:))))
+	error ("invalid conversion from NaN to logical");
+      else
+	y = x != 0;
+      endif
+    else
+      error ("logical not defined for type `%s'", typeinfo (x));
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert (logical ([]), zeros ([0, 0], "logical"));
+%!assert (logical (zeros (2, 0)), zeros ([2, 0], "logical"));
+%!assert (logical (0), false);
+%!assert (logical (13), true);
+%!assert (logical (-13), true);
+%!assert (logical (int8 (13)), true);
+%!assert (logical (int8 (-13)), true);
+%!assert (logical ([-1, 0, 1, Inf]), [-1, 0, 1, Inf] != 0);
+%!error (logical ([-1, 0, 1, NaN, Inf]))
+%!error (logical (NaN))
diff --git a/scripts/general/logspace.m b/scripts/general/logspace.m
new file mode 100644
index 0000000..e3a458e
--- /dev/null
+++ b/scripts/general/logspace.m
@@ -0,0 +1,103 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logspace (@var{base}, @var{limit}, @var{n})
+## Similar to @code{linspace} except that the values are logarithmically
+## spaced from
+## @tex
+## $10^{base}$ to $10^{limit}$.
+## @end tex
+## @ifnottex
+## 10^base to 10^limit.
+## @end ifnottex
+##
+## If @var{limit} is equal to
+## @tex
+## $\pi$,
+## @end tex
+## @ifnottex
+## pi,
+## @end ifnottex
+## the points are between
+## @tex
+## $10^{base}$ and $\pi$,
+## @end tex
+## @ifnottex
+## 10^base and pi,
+## @end ifnottex
+## @emph{not}
+## @tex
+## $10^{base}$ and $10^{\pi}$,
+## @end tex
+## @ifnottex
+## 10^base and 10^pi,
+## @end ifnottex
+## in order to be compatible with the corresponding @sc{matlab}
+## function.
+##
+## Also for compatibility, return the second argument if fewer than two
+## values are requested.
+## @seealso{linspace}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = logspace (x1, x2, n)
+
+  if (nargin == 2)
+    npoints = 50;
+  elseif (nargin == 3)
+    if (length (n) == 1)
+      npoints = fix (n);
+    else
+      error ("logspace: arguments must be scalars");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (length (x1) == 1 && length (x2) == 1)
+    x2_tmp = x2;
+    if (x2 == pi)
+      x2_tmp = log10 (pi);
+    endif
+    retval = 10 .^ (linspace (x1, x2_tmp, npoints));
+  else
+    error ("logspace: arguments must be scalars");
+  endif
+
+endfunction
+
+%!test
+%! x1 = logspace (1, 2);
+%! x2 = logspace (1, 2, 10);
+%! x3 = logspace (1, -2, 10);
+%! x4 = logspace (1, pi, 10);
+%! assert((size (x1) == [1, 50] && x1(1) == 10 && x1(50) == 100
+%! && size (x2) == [1, 10] && x2(1) == 10 && x2(10) == 100
+%! && size (x3) == [1, 10] && x3(1) == 10 && x3(10) == 0.01
+%! && size (x4) == [1, 10] && x4(1) == 10 && abs (x4(10) - pi) < sqrt (eps)));
+
+%!error logspace ([1, 2; 3, 4], 5, 6);
+
+%!error logspace ();
+
+%!error logspace (1, 2, 3, 4);
+
diff --git a/scripts/general/mod.m b/scripts/general/mod.m
new file mode 100644
index 0000000..152d478
--- /dev/null
+++ b/scripts/general/mod.m
@@ -0,0 +1,130 @@
+## Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008,
+##               2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} mod (@var{x}, @var{y})
+## Compute the modulo of @var{x} and @var{y}.  Conceptually this is given by
+##
+## @example
+## x - y .* floor (x ./ y)
+## @end example
+##
+## and is written such that the correct modulus is returned for
+## integer types.  This function handles negative values correctly.  That
+## is, @code{mod (-1, 3)} is 2, not -1, as @code{rem (-1, 3)} returns.
+## @code{mod (@var{x}, 0)} returns @var{x}.
+##
+## An error results if the dimensions of the arguments do not agree, or if
+## either of the arguments is complex.
+## @seealso{rem, fmod}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+## Modified by: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Adapted by: jwe
+
+function r = mod (x, y)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! size_equal (x, y) && ! (isscalar (x) || isscalar (y)))
+    error ("mod: argument sizes must agree");
+  endif
+
+  if (isreal (x) && isreal (y))
+    nz = y != 0.0;
+    if (all (nz(:)))
+      ## No elements of y are zero.
+      if (isinteger(x) || isinteger(y))
+	if (isinteger (x))
+	  typ = class (x);
+	else
+	  typ = class (y);
+	endif
+	r = x - y .* cast (floor (double(x) ./ double(y)), typ);
+      else
+	r = x - y .* floor (x ./ y);
+      endif
+    elseif (isscalar (y))
+      ## y must be zero.
+      r = x;
+    else
+      ## Some elements of y are zero.
+      if (isscalar (x))
+	r = x * ones (size(y), class(y));
+      else
+	r = x;
+	x = x(nz);
+      endif
+      y = y(nz);
+      if (isinteger(x) || isinteger(y))
+	if (isinteger (x))
+	  typ = class (x);
+	else
+	  typ = class (y);
+	endif
+	r(nz) = x - y .* floor (double(x) ./ double(y));
+      else
+	r(nz) = x - y .* floor (x ./ y);
+      endif
+    endif
+  else
+    error ("mod: complex arguments are not allowed");
+  endif
+
+endfunction
+  
+## empty input test
+%!assert (isempty(mod([], [])));
+
+## x mod y, y != 0 tests
+%!assert (mod(5, 3), 2);
+%!assert (mod(-5, 3), 1);
+%!assert (mod(0, 3), 0);
+%!assert (mod([-5, 5, 0], [3, 3, 3]), [1, 2, 0]);
+%!assert (mod([-5; 5; 0], [3; 3; 3]), [1; 2; 0]);
+%!assert (mod([-5, 5; 0, 3], [3, 3 ; 3, 1]), [1, 2 ; 0, 0]);
+
+## x mod 0 tests
+%!assert (mod(5, 0), 5);
+%!assert (mod(-5, 0), -5);
+%!assert (mod([-5, 5, 0], [3, 0, 3]), [1, 5, 0]);
+%!assert (mod([-5; 5; 0], [3; 0; 3]), [1; 5; 0]);
+%!assert (mod([-5, 5; 0, 3], [3, 0 ; 3, 1]), [1, 5 ; 0, 0]);
+%!assert (mod([-5, 5; 0, 3], [0, 0 ; 0, 0]), [-5, 5; 0, 3]);
+
+## mixed scalar/matrix tests
+%!assert (mod([-5, 5; 0, 3], 0), [-5, 5; 0, 3]); 
+%!assert (mod([-5, 5; 0, 3], 3), [1, 2; 0, 0]);
+%!assert (mod(-5,[0,0; 0,0]), [-5, -5; -5, -5]);
+%!assert (mod(-5,[3,0; 3,1]), [1, -5; 1, 0]);
+%!assert (mod(-5,[3,2; 3,1]), [1, 1; 1, 0]);
+
+## integer types
+%!assert (mod(uint8(5),uint8(4)),uint8(1))
+%!assert (mod(uint8([1:5]),uint8(4)),uint8([1,2,3,0,1]))
+%!assert (mod(uint8([1:5]),uint8(0)),uint8([1:5]))
+%!error (mod(uint8(5),int8(4)))
+
+## mixed integer/real types
+%!assert (mod(uint8(5),4),uint8(1))
+%!assert (mod(5,uint8(4)),uint8(1))
+%!assert (mod(uint8([1:5]),4),uint8([1,2,3,0,1]))
diff --git a/scripts/general/nargchk.m b/scripts/general/nargchk.m
new file mode 100644
index 0000000..05e4c09
--- /dev/null
+++ b/scripts/general/nargchk.m
@@ -0,0 +1,79 @@
+## Copyright (C) 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{msgstr} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs})
+## @deftypefnx {Function File} {@var{msgstr} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string")
+## @deftypefnx {Function File} {@var{msgstruct} =} nargchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct")
+## Return an appropriate error message string (or structure) if the
+## number of inputs requested is invalid.
+##
+## This is useful for checking to see that the number of input arguments
+## supplied to a function is within an acceptable range.
+## @seealso{nargoutchk, error, nargin, nargout}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function msg = nargchk (mina, maxa, narg, outtype)
+
+  if (nargin < 3 || nargin > 4)
+    print_usage ();
+  elseif (mina > maxa)
+    error ("nargchk: minargs must be <= maxargs");
+  elseif (nargin == 3)
+    outtype = "string";
+  elseif (! any (strcmpi (outtype, {"string", "struct"})))
+    error ("nargchk: output type must be either string or struct");
+  elseif (! (isscalar (mina) && isscalar (maxa) && isscalar (narg)))
+    error ("nargchk: mina, maxa, and narg must be scalars");
+  endif
+
+  msg = struct ("message", "", "identifier", "");
+  if (narg < mina)
+    msg.message = "not enough input arguments";
+    msg.identifier = "Octave:nargchk:not-enough-inputs";
+  elseif (narg > maxa)
+    msg.message = "too many input arguments";
+    msg.identifier = "Octave:nargchk:too-many-inputs";
+  endif
+
+  if (strcmpi (outtype, "string"))
+    msg = msg.message;
+  elseif (isempty (msg.message))
+    msg = struct ([]);
+  endif
+
+endfunction
+
+## Tests
+%!shared stmin, stmax
+%!  stmin = struct ("message", "not enough input arguments",
+%!                  "identifier", "Octave:nargchk:not-enough-inputs");
+%!  stmax = struct ("message", "too many input arguments",
+%!                  "identifier", "Octave:nargchk:too-many-inputs");
+%!assert (nargchk (0, 1, 0), "")
+%!assert (nargchk (0, 1, 1), "")
+%!assert (nargchk (1, 1, 0), "not enough input arguments")
+%!assert (nargchk (0, 1, 2), "too many input arguments")
+%!assert (nargchk (0, 1, 2, "string"), "too many input arguments")
+## Struct outputs
+%!assert (nargchk (0, 1, 0, "struct"), struct([]))
+%!assert (nargchk (0, 1, 1, "struct"), struct([]))
+%!assert (nargchk (1, 1, 0, "struct"), stmin)
+%!assert (nargchk (0, 1, 2, "struct"), stmax)
diff --git a/scripts/general/nargoutchk.m b/scripts/general/nargoutchk.m
new file mode 100644
index 0000000..017586c
--- /dev/null
+++ b/scripts/general/nargoutchk.m
@@ -0,0 +1,84 @@
+## Copyright (C) 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs})
+## @deftypefnx {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string")
+## @deftypefnx {Function File} {@var{msgstruct} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct")
+## Return an appropriate error message string (or structure) if the
+## number of outputs requested is invalid.
+##
+## This is useful for checking to see that the number of output
+## arguments supplied to a function is within an acceptable range.
+## @seealso{nargchk, error, nargout, nargin}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function msg = nargoutchk (mina, maxa, narg, outtype)
+
+  if (nargin < 3 || nargin > 4)
+    print_usage ();
+  elseif (mina > maxa)
+    error ("nargoutchk: minargs must be <= maxargs");
+  elseif (nargin == 3)
+    outtype = "string";
+  elseif (! any (strcmpi (outtype, {"string" "struct"})))
+    error ("nargoutchk: output type must be either string or struct");
+  elseif (! (isscalar (mina) && isscalar (maxa) && isscalar (narg)))
+    error ("nargoutchk: mina, maxa, and narg must be scalars");
+  endif
+
+  msg = struct ("message", "", "identifier", "");
+  if (narg < mina)
+    msg.message = "not enough output arguments";
+    msg.identifier = "Octave:nargoutchk:not-enough-outputs";
+  elseif (narg > maxa)
+    msg.message = "too many output arguments";
+    msg.identifier = "Octave:nargoutchk:too-many-outputs";
+  endif
+
+  if (strcmpi (outtype, "string"))
+    msg = msg.message;
+  else
+    if (isempty (msg.message))
+      msg = struct ([]);
+    endif
+    ## FIXME: remove the error below if error is modified to accept
+    ## struct inputs
+    error ("nargoutchk: error does not yet support struct inputs");
+  endif
+
+endfunction
+
+## Tests
+%!shared stmin, stmax
+%!  stmin = struct ("message", "not enough output arguments",
+%!                  "identifier", "Octave:nargoutchk:not-enough-outputs");
+%!  stmax = struct ("message", "too many output arguments",
+%!                  "identifier", "Octave:nargoutchk:too-many-outputs");
+%!assert (nargoutchk (0, 1, 0), "")
+%!assert (nargoutchk (0, 1, 1), "")
+%!assert (nargoutchk (1, 1, 0), "not enough output arguments")
+%!assert (nargoutchk (0, 1, 2), "too many output arguments")
+%!assert (nargoutchk (0, 1, 2, "string"), "too many output arguments")
+## Struct outputs
+#%!assert (nargoutchk (0, 1, 0, "struct"), struct([]))
+#%!assert (nargoutchk (0, 1, 1, "struct"), struct([]))
+#%!assert (nargoutchk (1, 1, 0, "struct"), stmin)
+#%!assert (nargoutchk (0, 1, 2, "struct"), stmax)
diff --git a/scripts/general/nextpow2.m b/scripts/general/nextpow2.m
new file mode 100644
index 0000000..0e82c78
--- /dev/null
+++ b/scripts/general/nextpow2.m
@@ -0,0 +1,58 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nextpow2 (@var{x})
+## If @var{x} is a scalar, return the first integer @var{n} such that
+## @tex
+## $2^n \ge |x|$.
+## @end tex
+## @ifnottex
+## 2^n >= abs (x).
+## @end ifnottex
+##
+## If @var{x} is a vector, return @code{nextpow2 (length (@var{x}))}.
+## @seealso{pow2, log2}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 7 October 1994
+## Adapted-By: jwe
+
+function n = nextpow2 (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isscalar (x) || isvector (x)))
+    error ("nextpow2: x must be a scalar or a vector");
+  endif
+
+  t = length (x);
+  if (t > 1)
+    x = t;
+  endif
+
+  [f, n] = log2 (abs (x));
+  if (f == 0.5)
+    n = n - 1;
+  endif
+
+endfunction
diff --git a/scripts/general/nthroot.m b/scripts/general/nthroot.m
new file mode 100644
index 0000000..38d3d44
--- /dev/null
+++ b/scripts/general/nthroot.m
@@ -0,0 +1,70 @@
+## Copyright (C) 2004, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nthroot (@var{x}, @var{n})
+## 
+## Compute the n-th root of @var{x}, returning real results for real 
+## components of @var{x}.  For example
+##
+## @example
+## @group
+## nthroot (-1, 3)
+## @result{} -1
+## (-1) ^ (1 / 3)
+## @result{} 0.50000 - 0.86603i
+## @end group
+## @end example
+##
+## @end deftypefn
+
+function y = nthroot (x, m)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+  
+  y = x.^(1./m);
+
+  if (isscalar (x))
+    x *= ones (size (m)); 
+  endif
+
+  if (isscalar (m))
+    m *= ones (size (x)); 
+  endif
+
+  idx = (mod (m, 2) == 1 & imag (x) == 0 & x < 0);
+
+  if (any (idx(:)))
+    y(idx) = -(-x(idx)).^(1./m(idx)); 
+  endif
+
+  ## If result is all real, make sure it looks real
+  if (all (imag (y) == 0))
+    y = real (y); 
+  endif
+
+endfunction
+
+%!assert(nthroot(-1,[3,-3]), [-1,-1],eps);
+%!assert(nthroot([-1,1],[3.1,-3]), [-1,1].^(1./[3.1,-3]));
+%!assert(nthroot([-1+1i,-1-1i],3), [-1+1i,-1-1i].^(1/3));
diff --git a/scripts/general/num2str.m b/scripts/general/num2str.m
new file mode 100644
index 0000000..62de181
--- /dev/null
+++ b/scripts/general/num2str.m
@@ -0,0 +1,190 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+##               2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} num2str (@var{x})
+## @deftypefnx {Function File} {} num2str (@var{x}, @var{precision})
+## @deftypefnx {Function File} {} num2str (@var{x}, @var{format})
+## Convert a number (or array) to a string (or a character array).  The
+## optional second argument may either give the number of significant
+## digits (@var{precision}) to be used in the output or a format
+## template string (@var{format}) as in @code{sprintf} (@pxref{Formatted
+## Output}).  @code{num2str} can also handle complex numbers.  For
+## example: 
+##
+## @example
+## @group
+## num2str (123.456)
+##      @result{} "123.46"
+##
+## num2str (123.456, 4)
+##      @result{} "123.5"
+##
+## s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
+##      @result{} s =
+##         1.0  1.3
+##         3.0  3.6
+## whos s
+##      @result{}
+##       Attr Name        Size                     Bytes  Class
+##       ==== ====        ====                     =====  ===== 
+##            s           2x8                         16  char
+##
+## num2str (1.234 + 27.3i)
+##      @result{} "1.234+27.3i"
+## @end group
+## @end example
+##
+## The @code{num2str} function is not very flexible.  For better control
+## over the results, use @code{sprintf} (@pxref{Formatted Output}). 
+## Note that for complex @var{x}, the format string may only contain one
+## output conversion specification and nothing else.  Otherwise, you
+## will get unpredictable results.  
+## @seealso{sprintf, int2str, mat2str}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = num2str (x, arg)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  if (ischar (x))
+    retval = x;
+  elseif (isempty (x))
+    retval = "";
+  elseif (iscomplex (x))
+    if (nargin == 2)
+      if (ischar (arg))
+	fmt = cstrcat (arg, "%-+", arg(2:end), "i");
+      else
+	if (isnumeric (x) && round (x) == x && abs (x) < (10 .^ arg))
+	  fmt = sprintf ("%%%dd%%-+%ddi  ", arg, arg);
+	else
+	  fmt = sprintf ("%%%d.%dg%%-+%d.%dgi", arg+7, arg, arg+7, arg);
+	endif
+      endif
+    else
+      ## Setup a suitable format string
+      if (isnumeric (x) && round (x) == x && abs (x) < 1e10)
+	if (max (abs (real (x(:)))) == 0)
+	  dgt1 = 2;
+	else
+	  dgt1 = ceil (log10 (max (max (abs (real (x(:)))),
+				   max (abs (imag (x(:))))))) + 2;
+	endif
+	dgt2 = dgt1 - (min (real (x(:))) >= 0);
+	
+	if (length (abs (x) == x) > 0)
+	  fmt = sprintf("%%%dg%%+-%dgi  ", dgt2, dgt1);
+	else
+	  fmt = sprintf("%%%dd%%+-%ddi  ", dgt2, dgt1);
+	endif
+      elseif (isscalar (x))
+	fmt = "%.6g%-+.6gi";
+      else
+	fmt = "%11.6g%-+11.6gi";
+      endif
+    endif
+
+    ## Manipulate the complex value to have real values in the odd
+    ## columns and imaginary values in the even columns.
+    sz = size (x);
+    nc = sz(2);
+    nd = ndims (x);
+    perm = fix ([1:0.5:nc+0.5]);
+    perm(2:2:2*nc) = perm(2:2:2*nc) + nc;
+    idx = cell ();
+    for i = 1:nd
+      idx{i} = 1:sz(i);
+    endfor
+    idx{2} = perm;
+    x = horzcat (real (x), imag (x));
+    x = x(idx{:});
+
+    fmt = cstrcat (deblank (repmat (fmt, 1, nc)), "\n");
+    tmp = sprintf (fmt, permute (x, [2, 1, 3:nd]));
+
+    ## Put the "i"'s where they are supposed to be.
+    while (true)
+      tmp2 = strrep (tmp, " i\n", "i\n");
+      if (length (tmp) == length (tmp2))
+	break;
+      else
+	tmp = tmp2;
+      endif
+    endwhile
+    while (true)
+      tmp2 = strrep (tmp, " i", "i ");
+      if (tmp == tmp2)
+	break;
+      else
+	tmp = tmp2;
+      endif
+    endwhile
+
+    tmp(length (tmp)) = "";
+    retval = char (strtrim (strsplit (tmp, "\n")));
+  else
+    if (nargin == 2)
+      if (ischar (arg))
+	fmt = arg;
+      else
+	if (isnumeric (x) && round (x) == x && abs (x) < (10 .^ arg))
+	  fmt = sprintf ("%%%dd  ", arg);
+	else
+	  fmt = sprintf ("%%%d.%dg", arg+7, arg);
+	endif
+      endif
+    else
+      if (isnumeric (x) && round (x) == x && abs (x) < 1e10)
+	if (max (abs (x(:))) == 0)
+	  dgt = 2;
+	else
+	  dgt = floor (log10 (max (abs(x(:))))) + (min (real (x(:))) < 0) + 2;
+	endif
+	if (length (abs (x) == x) > 0)
+	  fmt = sprintf ("%%%dg  ", dgt);
+	else
+	  fmt = sprintf ("%%%dd  ", dgt);
+	endif
+      elseif (isscalar (x))
+	fmt = "%11.5g";
+      else
+	fmt = "%11.5g";
+      endif
+    endif
+    fmt = cstrcat (deblank (repmat (fmt, 1, columns (x))), "\n");
+    nd = ndims (x);
+    tmp = sprintf (fmt, permute (x, [2, 1, 3:nd]));
+    tmp(length (tmp)) = "";
+    retval = strtrim (char (strsplit (tmp, "\n")));
+  endif
+
+endfunction
+
+%!assert ((strcmp (num2str (123), "123") && strcmp (num2str (1.23), "1.23")));
+%!assert (num2str (123.456, 4), "123.5");
+%!assert (all (num2str ([1, 1.34; 3, 3.56], "%5.1f") == ["1.0  1.3"; "3.0  3.6"]));
+%!assert (num2str (1.234 + 27.3i), "1.234+27.3i");
+%!error num2str ();
+%!error num2str (1, 2, 3);
+
diff --git a/scripts/general/perror.m b/scripts/general/perror.m
new file mode 100644
index 0000000..13f3a08
--- /dev/null
+++ b/scripts/general/perror.m
@@ -0,0 +1,39 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} perror (@var{name}, @var{num})
+## Print the error message for function @var{name} corresponding to the
+## error number @var{num}.  This function is intended to be used to print
+## useful error messages for those functions that return numeric error
+## codes.
+## @seealso{strerror}
+## @end deftypefn
+
+## Author: jwe
+
+function perror (name, err)
+
+  if (nargin != 2)
+    print_usage ();
+  else
+    printf (strerror (name, err));
+  endif
+
+endfunction
diff --git a/scripts/general/pol2cart.m b/scripts/general/pol2cart.m
new file mode 100644
index 0000000..7a0b2cb
--- /dev/null
+++ b/scripts/general/pol2cart.m
@@ -0,0 +1,105 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}] =} pol2cart (@var{theta}, @var{r})
+## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{theta}, @var{r}, @var{z})
+## Transform polar or cylindrical to Cartesian coordinates.
+## @var{theta}, @var{r} (and @var{z}) must be the same shape, or scalar.
+## @var{theta} describes the angle relative to the positive x-axis.
+## @var{r} is the distance to the z-axis (0, 0, z).
+## @seealso{cart2pol, cart2sph, sph2cart}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Adapted-by: jwe
+
+function [x, y, z] = pol2cart (theta, r, z)
+
+  if (nargin < 2 || nargin > 3)
+    error ("pol2cart: number of arguments must be 2 or 3");
+  endif
+
+  if (nargin == 2 && nargout > 2)
+    error ("pol2cart: number of output arguments must not be greater than number of input arguments");
+  endif
+
+   if ((ismatrix (theta) && ismatrix (r) && (nargin == 2 || ismatrix (z)))
+       && (size_equal (theta, r) || isscalar (theta) || isscalar (r))
+       && (nargin == 2 || size_equal (theta, z) || isscalar (theta) || isscalar (z))
+       && (nargin == 2 || size_equal (r, z) || isscalar (r) || isscalar (z)))
+
+    x = cos (theta) .* r;
+    y = sin (theta) .* r;
+
+  else
+    error ("pol2cart: arguments must be matrices of same size, or scalar");
+  endif
+
+endfunction
+
+%!test
+%! t = [0, 0.5, 1] * pi;
+%! r = 1;
+%! [x, y] = pol2cart (t, r);
+%! assert (x, [1, 0, -1], sqrt(eps));
+%! assert (y, [0, 1,  0], sqrt(eps));
+
+%!test
+%! t = [0, 1, 1] * pi/4;
+%! r = sqrt(2) * [0, 1, 2];
+%! [x, y] = pol2cart (t, r);
+%! assert (x, [0, 1, 2], sqrt(eps));
+%! assert (y, [0, 1, 2], sqrt(eps));
+
+%!test
+%! t = [0, 1, 1] * pi/4;
+%! r = sqrt(2) * [0, 1, 2];
+%! z = [0, 1, 2];
+%! [x, y, z2] = pol2cart (t, r, z);
+%! assert (x, [0, 1, 2], sqrt(eps));
+%! assert (y, [0, 1, 2], sqrt(eps));
+%! assert (z, z2);
+
+%!test
+%! t = 0;
+%! r = [0, 1, 2];
+%! z = [0, 1, 2];
+%! [x, y, z2] = pol2cart (t, r, z);
+%! assert (x, [0, 1, 2], sqrt(eps));
+%! assert (y, [0, 0, 0], sqrt(eps));
+%! assert (z, z2);
+
+%!test
+%! t = [1, 1, 1]*pi/4;
+%! r = 1;
+%! z = [0, 1, 2];
+%! [x, y, z2] = pol2cart (t, r, z);
+%! assert (x, [1, 1, 1] / sqrt(2), eps);
+%! assert (y, [1, 1, 1] / sqrt(2), eps);
+%! assert (z, z2);
+
+%!test
+%! t = 0;
+%! r = [1, 2, 3];
+%! z = 1;
+%! [x, y, z2] = pol2cart (t, r, z);
+%! assert (x, [1, 2, 3], eps);
+%! assert (y, [0, 0, 0] / sqrt(2), eps);
+%! assert (z, z2);
+
diff --git a/scripts/general/polyarea.m b/scripts/general/polyarea.m
new file mode 100644
index 0000000..d3bed82
--- /dev/null
+++ b/scripts/general/polyarea.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1999, 2006, 2007, 2009 David M. Doolin
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyarea (@var{x}, @var{y})
+## @deftypefnx {Function File} {} polyarea (@var{x}, @var{y}, @var{dim})
+##
+## Determines area of a polygon by triangle method.  The variables
+## @var{x} and @var{y} define the vertex pairs, and must therefore have
+## the same shape.  They can be either vectors or arrays.  If they are
+## arrays then the columns of @var{x} and @var{y} are treated separately
+## and an area returned for each.
+##
+## If the optional @var{dim} argument is given, then @code{polyarea}
+## works along this dimension of the arrays @var{x} and @var{y}.
+##
+## @end deftypefn
+
+## todo:  Add moments for centroid, etc.
+##
+## bugs and limitations:  
+##        Probably ought to be an optional check to make sure that
+##        traversing the vertices doesn't make any sides cross 
+##        (Is simple closed curve the technical definition of this?). 
+
+## Author: David M. Doolin <doolin at ce.berkeley.edu>
+## Date: 1999-04-14
+## Modified-by: 
+##    2000-01-15 Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+##    * use matlab compatible interface
+##    * return absolute value of area so traversal order doesn't matter
+##    2005-10-13 Torsten Finke
+##    * optimization saving half the sums and multiplies
+
+function a = polyarea (x, y, dim)
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  elseif (size_equal (x, y))
+    if (nargin == 2)
+      a = abs (sum (x .* (shift (y, -1) - shift (y, 1)))) / 2;
+    else
+      a = abs (sum (x .* (shift (y, -1, dim) - shift (y, 1, dim)), dim)) / 2;
+    endif
+  else
+    error ("polyarea: x and y must have the same shape");
+  endif
+endfunction
+
+%!shared x, y
+%! x = [1;1;3;3;1];
+%! y = [1;3;3;1;1];
+%!assert (polyarea(x,y), 4, eps)
+%!assert (polyarea([x,x],[y,y]), [4,4], eps)
+%!assert (polyarea([x,x],[y,y],1), [4,4], eps)
+%!assert (polyarea([x,x]',[y,y]',2), [4;4], eps)
diff --git a/scripts/general/postpad.m b/scripts/general/postpad.m
new file mode 100644
index 0000000..63a1fa2
--- /dev/null
+++ b/scripts/general/postpad.m
@@ -0,0 +1,83 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} postpad (@var{x}, @var{l}, @var{c})
+## @deftypefnx {Function File} {} postpad (@var{x}, @var{l}, @var{c}, @var{dim})
+## @seealso{prepad, resize}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+
+function y = postpad (x, l, c, dim)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 3 || isempty (c))
+    c = 0;
+  else
+    if (! isscalar (c))
+      error ("postpad: third argument must be empty or a scalar");
+    endif
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin < 4)
+    %% Find the first non-singleton dimension
+    dim  = 1;
+    while (dim < nd + 1 && sz (dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim)) && dim > 0 && 
+	dim < (nd + 1))
+      error ("postpad: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (! isscalar (l) || l < 0)
+    error ("second argument must be a positive scaler");
+  endif
+
+  if (dim > nd)
+    sz(nd+1:dim) = 1;
+  endif
+
+  d = sz (dim);
+
+  if (d >= l)
+    idx = cell ();
+    for i = 1:nd
+      idx{i} = 1:sz(i);
+    endfor
+    idx{dim} = 1:l;
+    y = x(idx{:});
+  else
+    sz (dim) = l - d;
+    y = cat (dim, x, c * ones (sz));
+  endif
+
+endfunction
diff --git a/scripts/general/prepad.m b/scripts/general/prepad.m
new file mode 100644
index 0000000..7c4f6dc
--- /dev/null
+++ b/scripts/general/prepad.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} prepad (@var{x}, @var{l}, @var{c})
+## @deftypefnx {Function File} {} prepad (@var{x}, @var{l}, @var{c}, @var{dim})
+## Prepend (append) the scalar value @var{c} to the vector @var{x}
+## until it is of length @var{l}.  If the third argument is not
+## supplied, a value of 0 is used.
+##
+## If @code{length (@var{x}) > @var{l}}, elements from the beginning (end) of
+## @var{x} are removed until a vector of length @var{l} is obtained.
+##
+## If @var{x} is a matrix, elements are prepended or removed from each row.
+##
+## If the optional @var{dim} argument is given, then operate along this
+## dimension.
+## @seealso{postpad}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+
+function y = prepad (x, l, c, dim)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 3 || isempty (c))
+    c = 0;
+  else
+    if (! isscalar (c))
+      error ("prepad: third argument must be empty or a scalar");
+    endif
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin < 4)
+    %% Find the first non-singleton dimension
+    dim  = 1;
+    while (dim < nd + 1 && sz (dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim)) && dim > 0 && 
+	dim < (nd + 1))
+      error ("prepad: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (! isscalar (l) || l < 0)
+    error ("second argument must be a positive scaler");
+  endif
+
+  if (dim > nd)
+    sz(nd+1:dim) = 1;
+  endif
+
+  d = sz (dim);
+
+  if (d >= l)
+    idx = cell ();
+    for i = 1:nd
+      idx{i} = 1:sz(i);
+    endfor
+    idx{dim} = d-l+1:d;
+    y = x(idx{:});
+  else
+    sz (dim) = l - d;
+    y = cat (dim, c * ones (sz), x);
+  endif
+
+endfunction
diff --git a/scripts/general/quadgk.m b/scripts/general/quadgk.m
new file mode 100644
index 0000000..4497f43
--- /dev/null
+++ b/scripts/general/quadgk.m
@@ -0,0 +1,446 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} quadgk (@var{f}, @var{a}, @var{b}, @var{abstol}, @var{trace})
+## @deftypefnx {Function File} {} quadgk (@var{f}, @var{a}, @var{b}, @var{prop}, @var{val}, @dots{})
+## @deftypefnx {Function File} {[@var{q}, @var{err}] =} quadgk (@dots{})
+## Numerically evaluate integral using adaptive Gauss-Konrod quadrature.
+## The formulation is based on a proposal by L.F. Shampine,
+## @cite{"Vectorized adaptive quadrature in @sc{matlab}", Journal of
+## Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2,
+## Feb 2008} where all function evaluations at an iteration are
+## calculated with a single call to @var{f}.  Therefore the function
+## @var{f} must be of the form @code{@var{f} (@var{x})} and accept
+## vector values of @var{x} and return a vector of the same length
+## representing the function evaluations at the given values of @var{x}.
+## The function @var{f} can be defined in terms of a function handle,
+## inline function or string.
+##
+## The bounds of the quadrature @code{[@var{a}, @var{b}]} can be finite
+## or infinite and contain weak end singularities.  Variable
+## transformation will be used to treat infinite intervals and weaken
+## the singularities.  For example
+##
+## @example
+## quadgk(@@(x) 1 ./ (sqrt (x) .* (x + 1)), 0, Inf)
+## @end example
+##
+## @noindent
+## Note that the formulation of the integrand uses the
+## element-by-element operator @code{./} and all user functions to
+## @code{quadgk} should do the same.
+##
+## The absolute tolerance can be passed as a fourth argument in a manner
+## compatible with @code{quadv}.  Equally the user can request that
+## information on the convergence can be printed is the fifth argument
+## is logically true.
+##
+## Alternatively, certain properties of @code{quadgk} can be passed as
+## pairs @code{@var{prop}, @var{val}}.  Valid properties are
+##
+## @table @code
+## @item AbsTol
+## Defines the absolute error tolerance for the quadrature.  The default
+## absolute tolerance is 1e-10.
+##
+## @item RelTol
+## Defines the relative error tolerance for the quadrature.  The default
+## relative tolerance is 1e-5.
+##
+## @item MaxIntervalCount
+## @code{quadgk} initially subdivides the interval on which to perform
+## the quadrature into 10 intervals.  Sub-intervals that have an
+## unacceptable error are sub-divided and re-evaluated.  If the number of
+## sub-intervals exceeds at any point 650 sub-intervals then a poor
+## convergence is signaled and the current estimate of the integral is
+## returned.  The property 'MaxIntervalCount' can be used to alter the
+## number of sub-intervals that can exist before exiting.
+##
+## @item WayPoints
+## If there exists discontinuities in the first derivative of the
+## function to integrate, then these can be flagged with the
+## @code{"WayPoints"} property.  This forces the ends of a sub-interval
+## to fall on the breakpoints of the function and can result in
+## significantly improved estimation of the error in the integral, faster
+## computation or both.  For example,
+##
+## @example
+## quadgk (@@(x) abs (1 - x .^ 2), 0, 2, 'Waypoints', 1)
+## @end example
+##
+## @noindent
+## signals the breakpoint in the integrand at @code{@var{x} = 1}.
+##
+## @item Trace
+## If logically true, then @code{quadgk} prints information on the
+## convergence of the quadrature at each iteration.
+##@end table
+##
+## If any of @var{a}, @var{b} or @var{waypoints} is complex, then the
+## quadrature is treated as a contour integral along a piecewise
+## continuous path defined by the above.  In this case the integral is
+## assumed to have no edge singularities.  For example
+##
+## @example
+## @group
+## quadgk (@@(z) log (z), 1+1i, 1+1i, "WayPoints",
+##         [1-1i, -1,-1i, -1+1i])
+## @end group
+## @end example
+##
+## @noindent
+## integrates @code{log (z)} along the square defined by @code{[1+1i,
+##  1-1i, -1-1i, -1+1i]}
+##
+## If two output arguments are requested, then @var{err} returns the
+## approximate bounds on the error in the integral @code{abs (@var{q} -
+## @var{i})}, where @var{i} is the exact value of the integral.
+##
+## @seealso{triplequad, dblquad, quad, quadl, quadv, trapz}
+## @end deftypefn
+
+function [q, err] = quadgk (f, a, b, varargin)
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  if (b < a)
+    [q, err] = quadgk (f, b, a, varargin{:});
+    q = -q;
+  else
+    abstol = 1e-10;
+    reltol = 1e-5;
+    waypoints = [];
+    maxint = 650;
+    trace = false;
+
+    if (nargin > 3)
+      if (! ischar (varargin{1}))
+	if (!isempty (varargin{1}))
+	  abstol = varargin{1};
+	  reltol = 0;
+	endif
+	if (nargin > 4)
+	  trace = varargin{2};
+	endif
+	if (nargin > 5)
+	  error ("quadgk: can not pass additional arguments to user function");
+        endif
+      else
+	idx = 1;
+	while (idx < nargin - 3)
+	  if (ischar (varargin{idx}))
+	    str = varargin{idx++};
+	    if (strcmpi (str, "reltol"))
+	      reltol = varargin{idx++};
+	    elseif (strcmpi (str, "abstol"))
+	      abstol = varargin{idx++};
+	    elseif (strcmpi (str, "waypoints"))
+	      waypoints = varargin{idx++} (:);
+	      if (isreal(waypoints))
+		waypoints (waypoints < a | waypoints > b) = [];
+	      endif
+	    elseif (strcmpi (str, "maxintervalcount"))
+	      maxint = varargin{idx++};
+	    elseif (strcmpi (str, "trace"))
+	      trace = varargin{idx++};
+	    else
+	      error ("quadgk: unknown property %s", str);
+	    endif
+	  else
+	    error ("quadgk: expecting property to be a string");
+	  endif
+	endwhile
+	if (idx != nargin - 2)
+	  error ("quadgk: expecting properties in pairs");
+	endif
+      endif
+    endif
+
+    ## Convert function given as a string to a function handle
+    if (ischar (f))
+      f = @(x) feval (f, x);
+    endif
+
+    ## Use variable subsitution to weaken endpoint singularities and to
+    ## perform integration with endpoints at infinity. No transform for
+    ## contour integrals
+    if (iscomplex (a) || iscomplex (b) || iscomplex(waypoints))
+      ## contour integral, no transform
+      subs = [a; waypoints; b];
+      h = b - a;
+      trans = @(t) t;
+    elseif (isinf (a) && isinf(b))
+      ## Standard Infinite to finite integral transformation.
+      ##   \int_{-\infinity_^\infinity f(x) dx = \int_-1^1 f (g(t)) g'(t) dt
+      ## where 
+      ##   g(t)  = t / (1 - t^2)
+      ##   g'(t) =  (1 + t^2) / (1 - t^2) ^ 2
+      ## waypoint transform is then
+      ##   t =  (2 * g(t)) ./ (1 + sqrt(1 + 4 * g(t) .^ 2))
+      if (!isempty (waypoints))
+	trans = @(x) (2 * x) ./ (1 + sqrt(1 + 4 * x .^ 2));
+	subs = [-1; trans(waypoints); 1];
+      else
+	subs = linspace (-1, 1, 11)'; 
+      endif
+      h = 2;
+      trans = @(t) t ./ (1 - t.^2);
+      f = @(t) f (t ./ (1 - t .^ 2)) .* (1 + t .^ 2) ./ ((1 - t .^ 2) .^ 2);
+    elseif (isinf(a))
+      ## Formula defined in Shampine paper as two separate steps. One to
+      ## weaken singularity at finite end, then a second to transform to
+      ## a finite interval. The singularity weakening transform is
+      ##   \int_{-\infinity}^b f(x) dx = 
+      ##               - \int_{-\infinity}^0 f (b - t^2) 2 t dt
+      ## (note minus sign) and the finite interval transform is
+      ##   \int_{-\infinity}^0 f(b - t^2)  2 t dt = 
+      ##                  \int_{-1}^0 f (b - g(s) ^ 2) 2 g(s) g'(s) ds
+      ## where 
+      ##   g(s)  = s / (1 + s)
+      ##   g'(s) = 1 / (1 + s) ^ 2
+      ## waypoint transform is then
+      ##   t = sqrt (b - x)
+      ##   s =  - t / (t + 1)
+      if (!isempty (waypoints))
+	tmp = sqrt (b - waypoints);
+	trans = @(x)  - x ./ (x + 1);
+	subs = [0; trans(tmp); 1];
+      else
+	subs = linspace (0, 1, 11)'; 
+      endif
+      h = 1;
+      trans = @(t) b - (t ./ (1 + t)).^2;
+      f = @(s) - 2 * s .* f (b -  (s ./ (1 + s)) .^ 2) ./ ((1 + s) .^ 3);
+    elseif (isinf(b))
+      ## Formula defined in Shampine paper as two separate steps. One to
+      ## weaken singularity at finite end, then a second to transform to
+      ## a finite interval. The singularity weakening transform is
+      ##   \int_a^\infinity f(x) dx = \int_0^\infinity f (a + t^2) 2 t dt
+      ## and the finite interval transform is
+      ##  \int_0^\infinity f(a + t^2)  2 t dt = 
+      ##           \int_0^1 f (a + g(s) ^ 2) 2 g(s) g'(s) ds
+      ## where 
+      ##   g(s)  = s / (1 - s)
+      ##   g'(s) = 1 / (1 - s) ^ 2
+      ## waypoint transform is then
+      ##   t = sqrt (x - a)
+      ##   s = t / (t + 1)
+      if (!isempty (waypoints))
+	tmp = sqrt (waypoints - a);
+	trans = @(x) x ./ (x + 1);
+	subs = [0; trans(tmp); 1];
+      else
+	subs = linspace (0, 1, 11)'; 
+      endif
+      h = 1;
+      trans = @(t) a + (t ./ (1 - t)).^2;
+      f = @(s) 2 * s .* f (a +  (s ./ (1 - s)) .^ 2) ./ ((1 - s) .^ 3);
+    else
+      ## Davis, Rabinowitz, "Methods of Numerical Integration" p441 2ed.
+      ## Presented in section 5 of the Shampine paper as
+      ##   g(t) = ((b - a) / 2) * (t / 2 * (3 - t^2)) + (b + a) / 2
+      ##   g'(t) = ((b-a)/4) * (3 - 3t^2);
+      ## waypoint transform can then be found by solving for t with
+      ## Maxima (solve (c + 3*t -  3^3, t);). This gives 3 roots, two of
+      ## which are complex for values between a and b and so can be
+      ## ignored. The third is
+      ##  c = (-4*x + 2*(b+a)) / (b-a);
+      ##  k = ((sqrt(c^2 - 4) + c)/2)^(1/3);
+      ##  t = (sqrt(3)* 1i * (1 - k^2) - (1 + k^2)) / 2 / k;
+      if (! isempty (waypoints))
+	trans = @__quadgk_finite_waypoint__;
+	subs = [-1; trans(waypoints, a, b); 1];
+      else
+	subs = linspace(-1, 1, 11)'; 
+      endif
+      h = 2;
+      trans = @(t) ((b - a) ./ 4) * t .* (3 - t.^2) + (b + a) ./ 2;
+      f = @(t) f((b - a) ./ 4 .* t .* (3 - t.^2) + (b + a) ./ 2) .* ...
+           3 .* (b - a) ./ 4 .* (1 - t.^2);
+    endif
+
+    ## Split interval into at least 10 sub-interval with a 15 point
+    ## Gauss-Kronrod rule giving a minimum of 150 function evaluations
+    while (length (subs) < 11)
+      subs = [subs' ; subs(1:end-1)' + diff(subs') ./ 2, NaN](:)(1 : end - 1);
+    endwhile
+    subs = [subs(1:end-1), subs(2:end)];
+
+    warn_state = warning ("query", "Octave:divide-by-zero");
+
+    unwind_protect
+      ## Singularity will cause divide by zero warnings
+      warning ("off", "Octave:divide-by-zero");
+
+      ## Initial evaluation of the integrand on the sub-intervals
+      [q_subs, q_errs] = __quadgk_eval__ (f, subs);
+      q0 = sum (q_subs);
+      err0 = sum (q_errs);
+    
+      if (isa (a, "single") || isa (b, "single") || isa (waypoints, "single"))
+	myeps = eps ("single");
+      else
+	myeps = eps;
+      endif
+
+      first = true;
+      while (true)
+	## Check for sub-intervals that are too small. Test must be
+	## performed in untransformed sub-intervals. What is a good
+	## value for this test. Shampine suggests 100*eps
+	if (any (diff (trans (subs), [], 2) / (b - a) < 100 * myeps))
+	  q = q0;
+	  err = err0;
+	  break;
+	endif
+
+	## Quit if any evaluations are not finite (Inf or NaN)
+	if (any (! isfinite (q_subs)))
+	  warning ("quadgk: non finite integrand encountered"); 
+	  q = q0;
+	  err = err0;
+	  break;
+	endif
+
+	tol = max (abstol, reltol .* abs (q0));
+
+	## If the global error estimate is meet exit
+	if (err0 < tol)
+	  q = q0;
+	  err = err0;
+	  break;
+	endif
+
+	## Accept the sub-intervals that meet the convergence criteria
+	idx = find (abs (q_errs) < tol .* diff (subs, [], 2) ./ h);
+	if (first)
+	  q = sum (q_subs (idx));
+	  err = sum (q_errs(idx));
+	  first = false;
+	else
+	  q0 = q + sum (q_subs);
+	  err0 = err + sum (q_errs);
+	  q += sum (q_subs (idx));
+	  err += sum (q_errs(idx));
+	endif
+	subs(idx,:) = [];
+
+	## If no remaining sub-intervals exit
+	if (rows (subs) == 0)
+	  break;
+	endif
+
+	if (trace)
+	  disp([rows(subs), err, q0]);
+	endif
+
+	## Split remaining sub-intervals in two
+	mid = (subs(:,2) + subs(:,1)) ./ 2;
+	subs = [subs(:,1), mid; mid, subs(:,2)];
+
+	## If the maximum sub-interval count is met accept remaining
+	## sub-interval and exit
+	if (rows (subs) > maxint)
+	  warning ("quadgk: maximum interval count (%d) met", maxint);
+	  q += sum (q_subs);
+	  err += sum (q_errs);
+	  break;
+	endif
+
+	## Evaluation of the integrand on the remaining sub-intervals
+	[q_subs, q_errs] = __quadgk_eval__ (f, subs);
+      endwhile
+
+      if (err > max (abstol, reltol * abs(q)))
+	warning ("quadgk: Error tolerance not met. Estimated error %g", err);
+      endif
+    unwind_protect_cleanup
+      if (strcmp (warn_state.state, "on")) 
+	warning ("on", "Octave:divide-by-zero");
+      endif
+    end_unwind_protect
+  endif
+endfunction
+
+function [q, err] = __quadgk_eval__ (f, subs)
+  ## A (15,7) point pair of Gauss-Konrod quadrature rules. The abscissa
+  ## and weights are copied directly from dqk15w.f from quadpack
+
+  persistent abscissa = [-0.9914553711208126e+00, -0.9491079123427585e+00, ...
+			 -0.8648644233597691e+00, -0.7415311855993944e+00, ...
+			 -0.5860872354676911e+00, -0.4058451513773972e+00, ...
+			 -0.2077849550078985e+00,  0.0000000000000000e+00, ...
+			  0.2077849550078985e+00,  0.4058451513773972e+00, ...
+			  0.5860872354676911e+00,  0.7415311855993944e+00, ...
+			  0.8648644233597691e+00,  0.9491079123427585e+00, ...
+			  0.9914553711208126e+00];
+
+  persistent weights15 = ...
+      diag ([0.2293532201052922e-01,  0.6309209262997855e-01, ...
+	     0.1047900103222502e+00,  0.1406532597155259e+00, ...
+	     0.1690047266392679e+00,  0.1903505780647854e+00, ...
+	     0.2044329400752989e+00,  0.2094821410847278e+00, ...
+	     0.2044329400752989e+00,  0.1903505780647854e+00, ...
+	     0.1690047266392679e+00,  0.1406532597155259e+00, ...
+	     0.1047900103222502e+00,  0.6309209262997855e-01, ...
+	     0.2293532201052922e-01]);
+
+  persistent weights7  = ...
+      diag ([0.1294849661688697e+00,  0.2797053914892767e+00, ...
+	     0.3818300505051889e+00,  0.4179591836734694e+00, ...
+	     0.3818300505051889e+00,  0.2797053914892767e+00, ...
+	     0.1294849661688697e+00]);
+
+  halfwidth = diff (subs, [], 2) ./ 2;
+  center = sum (subs, 2) ./ 2;;
+  x = bsxfun (@plus, halfwidth * abscissa, center);
+  y = reshape (f (x(:)), size(x));
+
+  ## This is faster than using bsxfun as the * operator can use a
+  ## single BLAS call, rather than rows(sub) calls to the @times
+  ## function.
+  q = sum (y * weights15, 2) .* halfwidth;
+  err = abs (sum (y(:,2:2:end) * weights7, 2) .* halfwidth - q);
+endfunction
+
+function t = __quadgk_finite_waypoint__ (x, a, b)
+  c = (-4 .* x + 2.* (b + a)) ./ (b - a);
+  k = ((sqrt(c .^ 2 - 4) + c) ./ 2) .^ (1/3);
+  t = real ((sqrt(3) .* 1i * (1 - k .^ 2) - (1 + k .^ 2)) ./ 2 ./ k);
+endfunction
+
+%error (quadgk (@sin))
+%error (quadgk (@sin, -pi))
+%error (quadgk (@sin, -pi, pi, 'DummyArg'))
+
+%!assert (quadgk(@sin,-pi,pi), 0, 1e-6)
+%!assert (quadgk(inline('sin'),-pi,pi), 0, 1e-6)
+%!assert (quadgk('sin',-pi,pi), 0, 1e-6)
+%!assert (quadgk(@sin,-pi,pi,'waypoints', 0, 'MaxIntervalCount', 100, 'reltol', 1e-3, 'abstol', 1e-6, 'trace', false), 0, 1e-6)
+%!assert (quadgk(@sin,-pi,pi,1e-6,false), 0, 1e-6)
+
+%!assert (quadgk(@sin,-pi,0), -2, 1e-6)
+%!assert (quadgk(@sin,0,pi), 2, 1e-6)
+%!assert (quadgk(@(x) 1./sqrt(x), 0, 1), 2, 1e-6)
+%!assert (quadgk (@(x) abs (1 - x.^2), 0, 2, 'Waypoints', 1), 2, 1e-6)
+%!assert (quadgk(@(x) 1./(sqrt(x).*(x+1)), 0, Inf), pi, 1e-6)
+%!assert (quadgk (@(z) log (z), 1+1i, 1+1i, 'WayPoints', [1-1i, -1,-1i, -1+1i]), -pi * 1i, 1e-6)
+
+%!assert (quadgk (@(x) exp(-x .^ 2), -Inf, Inf), sqrt(pi), 1e-6)
\ No newline at end of file
diff --git a/scripts/general/quadl.m b/scripts/general/quadl.m
new file mode 100644
index 0000000..b33d8f4
--- /dev/null
+++ b/scripts/general/quadl.m
@@ -0,0 +1,189 @@
+## Copyright (C) 1998, 2006, 2007, 2008, 2009 Walter Gautschi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b})
+## @deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol})
+## @deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace})
+## @deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace}, @var{p1}, @var{p2}, @dots{})
+##
+## Numerically evaluate integral using adaptive Lobatto rule.
+## @code{quadl (@var{f}, @var{a}, @var{b})} approximates the integral of
+## @code{@var{f}(@var{x})} to machine precision.  @var{f} is either a
+## function handle, inline function or string containing the name of
+## the function to evaluate.  The function @var{f} must return a vector
+## of output values if given a vector of input values.
+##
+## If defined, @var{tol} defines the relative tolerance to which to
+## which to integrate @code{@var{f}(@var{x})}.  While if @var{trace} is
+## defined, displays the left end point of the current interval, the 
+## interval length, and the partial integral.
+##
+## Additional arguments @var{p1}, etc., are passed directly to @var{f}.
+## To use default values for @var{tol} and @var{trace}, one may pass
+## empty matrices.
+##
+## Reference: W. Gander and W. Gautschi, 'Adaptive Quadrature - 
+## Revisited', BIT Vol. 40, No. 1, March 2000, pp. 84--101.
+## @url{http://www.inf.ethz.ch/personal/gander/}
+##
+## @end deftypefn
+
+##   Author: Walter Gautschi
+##   Date: 08/03/98
+##   Reference: Gander, Computermathematik, Birkhaeuser, 1992.
+
+## 2003-08-05 Shai Ayal
+##   * permission from author to release as GPL
+## 2004-02-10 Paul Kienzle
+##   * renamed to quadl for compatibility
+##   * replace global variable terminate2 with local function need_warning
+##   * add paper ref to docs
+
+function Q = quadl (f, a, b, tol, trace, varargin)
+  need_warning (1);
+  if (nargin < 4)
+    tol = []; 
+  endif
+  if (nargin < 5)
+    trace = []; 
+  endif
+  if (isa (a, "single") || isa (b, "single"))
+    myeps = eps ("single");
+  else
+    myeps = eps;
+  endif
+  if (isempty (tol))
+    tol = myeps; 
+  endif
+  if (isempty (trace))
+    trace = 0; 
+  endif
+  if (tol < myeps)
+    tol = myeps;
+  endif
+
+  m = (a+b)/2; 
+  h = (b-a)/2;
+  alpha = sqrt(2/3); 
+  beta = 1/sqrt(5);
+
+  x1 = .942882415695480; 
+  x2 = .641853342345781;
+  x3 = .236383199662150;
+
+  x = [a, m-x1*h, m-alpha*h, m-x2*h, m-beta*h, m-x3*h, m, m+x3*h, ...
+       m+beta*h, m+x2*h, m+alpha*h, m+x1*h, b];
+
+  y = feval (f, x, varargin{:});
+
+  fa = y(1); 
+  fb = y(13);
+
+  i2 = (h/6)*(y(1) + y(13) + 5*(y(5)+y(9)));
+
+  i1 = (h/1470)*(77*(y(1)+y(13))
+		 + 432*(y(3)+y(11))
+		 + 625*(y(5)+y(9))
+		 + 672*y(7));
+
+  is = h*(.0158271919734802*(y(1)+y(13))
+	  +.0942738402188500*(y(2)+y(12))
+	  + .155071987336585*(y(3)+y(11))
+	  + .188821573960182*(y(4)+y(10))
+	  + .199773405226859*(y(5)+y(9))
+	  + .224926465333340*(y(6)+y(8))
+	  + .242611071901408*y(7));
+
+  s = sign(is); 
+
+  if (s == 0)
+    s = 1;
+  endif
+  erri1 = abs(i1-is);
+  erri2 = abs(i2-is);
+  R = 1; 
+  if (erri2 != 0)
+    R = erri1/erri2; 
+  endif
+  if (R > 0 && R < 1)
+    tol = tol/R; 
+  endif
+  is = s*abs(is)*tol/myeps;
+  if (is == 0)
+    is = b-a;
+  endif
+  Q = adaptlobstp (f, a, b, fa, fb, is, trace, varargin{:});
+endfunction
+
+## ADAPTLOBSTP  Recursive function used by QUADL.
+##
+##   Q = ADAPTLOBSTP('F', A, B, FA, FB, IS, TRACE) tries to
+##   approximate the integral of F(X) from A to B to
+##   an appropriate relative error. The argument 'F' is
+##   a string containing the name of f.  The remaining
+##   arguments are generated by ADAPTLOB or by recursion.
+##
+##   Walter Gautschi, 08/03/98
+
+function Q = adaptlobstp (f, a, b, fa, fb, is, trace, varargin)
+  h = (b-a)/2; 
+  m = (a+b)/2;
+  alpha = sqrt(2/3); 
+  beta = 1/sqrt(5);
+  mll = m-alpha*h; 
+  ml = m-beta*h; 
+  mr = m+beta*h; 
+  mrr = m+alpha*h;
+  x = [mll, ml, m, mr, mrr];
+  y = feval(f, x, varargin{:});
+  fmll = y(1); 
+  fml = y(2); 
+  fm = y(3); 
+  fmr = y(4); 
+  fmrr = y(5);
+  i2 = (h/6)*(fa + fb + 5*(fml+fmr));
+  i1 = (h/1470)*(77*(fa+fb) + 432*(fmll+fmrr) + 625*(fml+fmr) + 672*fm);
+  if (is+(i1-i2) == is || mll <= a || b <= mrr)
+    if ((m <= a || b <= m) && need_warning ())
+      warning ("quadl: interval contains no more machine number");
+      warning ("quadl: required tolerance may not be met");
+      need_warning (0);
+    endif
+    Q = i1;
+    if (trace)
+      disp ([a, b-a, Q]);
+    endif
+  else
+    Q = (adaptlobstp (f, a, mll, fa, fmll, is, trace, varargin{:})
+	 + adaptlobstp (f, mll, ml, fmll, fml, is, trace, varargin{:})
+	 + adaptlobstp (f, ml, m, fml, fm, is, trace, varargin{:})
+	 + adaptlobstp (f, m, mr, fm, fmr, is, trace, varargin{:})
+	 + adaptlobstp (f, mr, mrr, fmr, fmrr, is, trace, varargin{:})
+	 + adaptlobstp (f, mrr, b, fmrr, fb, is, trace, varargin{:}));
+  endif
+endfunction
+
+function r = need_warning (v)
+  persistent w = [];
+  if (nargin == 0)
+    r = w;
+  else 
+    w = v; 
+  endif
+endfunction
diff --git a/scripts/general/quadv.m b/scripts/general/quadv.m
new file mode 100644
index 0000000..d7a6a46
--- /dev/null
+++ b/scripts/general/quadv.m
@@ -0,0 +1,136 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{q} =} quadv (@var{f}, @var{a}, @var{b})
+## @deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol})
+## @deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace})
+## @deftypefnx {Function File} {@var{q} =} quadl (@var{f}, @var{a}, @var{b}, @var{tol}, @var{trace}, @var{p1}, @var{p2}, @dots{})
+## @deftypefnx {Function File} {[@var{q}, @var{fcnt}] =} quadl (@dots{})
+##
+## Numerically evaluate integral using adaptive Simpson's rule.
+## @code{quadv (@var{f}, @var{a}, @var{b})} approximates the integral of
+## @code{@var{f}(@var{x})} to the default absolute tolerance of @code{1e-6}. 
+## @var{f} is either a function handle, inline function or string
+## containing the name of the function to evaluate.  The function @var{f}
+## must accept a string, and can return a vector representing the
+## approximation to @var{n} different sub-functions.
+##
+## If defined, @var{tol} defines the absolute tolerance to which to
+## which to integrate each sub-interval of @code{@var{f}(@var{x})}.
+## While if @var{trace} is defined, displays the left end point of the
+## current interval, the interval length, and the partial integral.
+##
+## Additional arguments @var{p1}, etc., are passed directly to @var{f}.
+## To use default values for @var{tol} and @var{trace}, one may pass
+## empty matrices.
+## @seealso{triplequad, dblquad, quad, quadl, quadgk, trapz}
+## @end deftypefn
+
+function [q, fcnt] = quadv (f, a, b, tol, trace, varargin)
+  if (nargin < 3)
+    print_usage ();
+  endif
+  if (nargin < 4)
+    tol = []; 
+  endif
+  if (nargin < 5)
+    trace = []; 
+  endif
+  if (isa (a, "single") || isa (b, "single"))
+    myeps = eps ("single");
+  else
+    myeps = eps;
+  endif
+  if (isempty (tol))
+    tol = 1e-6; 
+  endif
+  if (isempty (trace))
+    trace = 0; 
+  endif
+
+  ## Split the interval into 3 abscissa, and apply a 3 point Simpson's rule
+  c = (a + b) / 2;
+  fa = feval (f, a, varargin{:});
+  fc = feval (f, c, varargin{:});
+  fb = feval (f, b, varargin{:});
+  fcnt = 3;
+
+  ## If have edge singularities, move edge point by eps*(b-a) as
+  ## discussed in Shampine paper used to implement quadgk
+  if (isinf (fa))
+    fa = feval (f, a + myeps * (b-a), varargin{:});
+  endif
+  if (isinf (fb))
+    fb = feval (f, b - myeps * (b-a), varargin{:});
+  endif
+
+  h = (b - a) / 2;
+  q = (b - a) / 6 * (fa + 4 * fc + fb);
+ 
+  [q, fcnt, hmin] = simpsonstp (f, a, b, c, fa, fb, fc, q, fcnt, abs (b - a), 
+				tol, trace, varargin{:});
+
+  if (fcnt > 10000)
+    warning ("maximum iteration count reached");
+  elseif (isnan (q) || isinf (q))
+    warning ("infinite or NaN function evaluations were returned");
+  elseif (hmin < (b - a) * myeps)
+    warning ("minimum step size reached -- possibly singular integral");
+  endif
+endfunction
+
+function [q, fcnt, hmin] = simpsonstp (f, a, b, c, fa, fb, fc, q0, 
+				       fcnt, hmin, tol, trace, varargin)
+  if (fcnt > 10000)
+    q = q0;
+  else
+    d = (a + c) / 2;
+    e = (c + b) / 2;
+    fd = feval (f, d, varargin{:});
+    fe = feval (f, e, varargin{:});
+    fcnt += 2;
+    q1 = (c - a) / 6 * (fa + 4 * fd + fc);
+    q2 = (b - c) / 6 * (fc + 4 * fe + fb);
+    q = q1 + q2;
+
+    if (abs(a -  c) < hmin)
+      hmin = abs (a - c);
+    endif
+
+    if (trace)
+      disp ([fcnt, a, b-a, q]);
+    endif
+
+    ## Force at least one adpative step.
+    if (fcnt == 5 || abs (q - q0) > tol)
+      [q1, fcnt, hmin] = simpsonstp (f, a, c, d, fa, fc, fd, q1, fcnt, hmin,
+				    tol, trace, varargin{:});
+      [q2, fcnt, hmin] = simpsonstp (f, c, b, e, fc, fb, fe, q2, fcnt, hmin,
+				     tol, trace, varargin{:});
+      q = q1 + q2;
+    endif
+  endif
+endfunction
+
+%!assert (quadv (@sin, 0, 2 * pi), 0, 1e-5)
+%!assert (quadv (@sin, 0, pi), 2, 1e-5)
+
+%% Handles weak singularities at the edge
+%!assert (quadv (@(x) 1 ./ sqrt(x), 0, 1), 2, 1e-5)
+
diff --git a/scripts/general/randperm.m b/scripts/general/randperm.m
new file mode 100644
index 0000000..ecde8e5
--- /dev/null
+++ b/scripts/general/randperm.m
@@ -0,0 +1,40 @@
+## Copyright (C) 1998, 1999, 2000, 2002, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} randperm (@var{n})
+## Return a row vector containing a random permutation of the
+## integers from 1 to @var{n}.
+## @end deftypefn
+
+## Author: "James R. Van Zandt" <jrv at vanzandt.mv.com>
+## Adapted-By: jwe
+
+function retval = randperm (n)
+
+  if (nargin == 1 && isscalar (n) && floor (n) == n)
+    if (n >= 0)
+      [junk, retval] = sort (rand (1, n));
+    else
+      error ("randperm: argument must be non-negative");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/general/rat.m b/scripts/general/rat.m
new file mode 100644
index 0000000..eb80431
--- /dev/null
+++ b/scripts/general/rat.m
@@ -0,0 +1,152 @@
+## Copyright (C) 2001, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{s} =} rat (@var{x}, @var{tol})
+## @deftypefnx {Function File} {[@var{n}, @var{d}] =} rat (@var{x}, @var{tol})
+##
+## Find a rational approximation to @var{x} within the tolerance defined
+## by @var{tol} using a continued fraction expansion.  For example,
+##
+## @example
+## @group
+## rat(pi) = 3 + 1/(7 + 1/16) = 355/113
+## rat(e) = 3 + 1/(-4 + 1/(2 + 1/(5 + 1/(-2 + 1/(-7))))) 
+##        = 1457/536
+## @end group
+## @end example
+##
+## Called with two arguments returns the numerator and denominator separately
+## as two matrices.
+## @end deftypefn
+## @seealso{rats}
+
+function [n,d] = rat(x,tol)
+
+  if (nargin != [1,2] || nargout > 2)
+    print_usage ();
+  endif
+
+  y = x(:);
+
+  ## Replace Inf with 0 while calculating ratios.
+  y(isinf(y)) = 0;
+
+  ## default norm
+  if (nargin < 2)
+    tol = 1e-6 * norm(y,1);
+  endif
+
+  ## First step in the approximation is the integer portion
+
+  ## First element in the continued fraction.
+  n = round(y);
+  d = ones(size(y));
+  frac = y-n;
+  lastn = ones(size(y));
+  lastd = zeros(size(y));
+
+  nd = ndims(y);
+  nsz = numel (y);
+  steps = zeros([nsz, 0]);
+
+  ## Grab new factors until all continued fractions converge.
+  while (1)
+    ## Determine which fractions have not yet converged.
+    idx = find(abs (y-n./d) >= tol);
+    if (isempty(idx))
+      if (isempty (steps))
+	steps = NaN .* ones (nsz, 1);
+      endif
+      break;
+    endif
+
+    ## Grab the next step in the continued fraction.
+    flip = 1./frac(idx);
+    ## Next element in the continued fraction.
+    step = round(flip);
+
+    if (nargout < 2)
+      tsteps = NaN .* ones (nsz, 1);
+      tsteps (idx) = step;
+      steps = [steps, tsteps];
+    endif
+
+    frac(idx) = flip-step;
+
+    ## Update the numerator/denominator.
+    nextn = n;
+    nextd = d;
+    n(idx) = n(idx).*step + lastn(idx);
+    d(idx) = d(idx).*step + lastd(idx);
+    lastn = nextn;
+    lastd = nextd;
+  endwhile
+
+  if (nargout == 2)
+    ## Move the minus sign to the top.
+    n = n.*sign(d);
+    d = abs(d);
+
+    ## Return the same shape as you receive.
+    n = reshape(n, size(x));
+    d = reshape(d, size(x));
+
+    ## Use 1/0 for Inf.
+    n(isinf(x)) = sign(x(isinf(x)));
+    d(isinf(x)) = 0;
+
+    ## Reshape the output.
+    n = reshape (n, size (x));
+    d = reshape (d, size (x));
+  else
+    n = "";
+    nsteps = size(steps, 2);
+    for i = 1: nsz
+      s = [int2str(y(i))," "];
+      j = 1;
+
+      while (true)
+	step = steps(i, j++);
+	if (isnan (step))
+	  break;
+	endif
+	if (j > nsteps || isnan (steps(i, j)))
+	  if (step < 0)
+	    s = [s(1:end-1), " + 1/(", int2str(step), ")"];
+	  else
+	    s = [s(1:end-1), " + 1/", int2str(step)];
+	  endif
+	  break;
+	else
+	  s = [s(1:end-1), " + 1/(", int2str(step), ")"];
+        endif
+      endwhile
+      s = [s, repmat(")", 1, j-2)];
+      n_nc = columns (n);
+      s_nc = columns (s);
+      if (n_nc > s_nc)
+	s(:,s_nc+1:n_nc) = " "
+      elseif (s_nc > n_nc)
+	n(:,n_nc+1:s_nc) = " ";
+      endif
+      n = cat (1, n, s);
+    endfor
+  endif
+
+endfunction
diff --git a/scripts/general/rem.m b/scripts/general/rem.m
new file mode 100644
index 0000000..7ed0b91
--- /dev/null
+++ b/scripts/general/rem.m
@@ -0,0 +1,81 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} rem (@var{x}, @var{y})
+## Return the remainder of the division @code{@var{x} / @var{y}}, computed 
+## using the expression
+##
+## @example
+## x - y .* fix (x ./ y)
+## @end example
+##
+## An error message is printed if the dimensions of the arguments do not
+## agree, or if either of the arguments is complex.
+## @seealso{mod, fmod}
+## @end deftypefn
+
+## Author: jwe
+
+function r = rem (x, y)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! size_equal (x, y) && ! (isscalar (x) || isscalar (y)))
+    error ("rem: argument sizes must agree");
+  endif
+
+  if (isreal (x) && isreal (y))
+      if (isinteger(x) || isinteger(y))
+	if (isinteger (x))
+	  typ = class (x);
+	else
+	  typ = class (y);
+	endif
+	r = x - y .* cast (fix (double (x) ./ double (y)), typ);
+      else
+	r = x - y .* fix (x ./ y);
+      endif
+  else
+    error ("rem: complex arguments are not allowed");
+  endif
+
+endfunction
+
+%!assert(rem ([1, 2, 3; -1, -2, -3], 2), [1, 0, 1; -1, 0, -1]);
+
+%!assert(rem ([1, 2, 3; -1, -2, -3], 2 * ones (2, 3)),[1, 0, 1; -1, 0, -1]);
+
+%!error rem ();
+
+%!error rem (1, 2, 3);
+
+%!error rem ([1, 2], [3, 4, 5]);
+
+%!error rem (i, 1);
+
+%!assert(rem (uint8([1, 2, 3; -1, -2, -3]), uint8 (2)), uint8([1, 0, 1; -1, 0, -1]));
+
+%!assert(uint8(rem ([1, 2, 3; -1, -2, -3], 2 * ones (2, 3))),uint8([1, 0, 1; -1, 0, -1]));
+
+%!error rem (uint(8),int8(5));
+
+%!error rem (uint8([1, 2]), uint8([3, 4, 5]));
diff --git a/scripts/general/repmat.m b/scripts/general/repmat.m
new file mode 100644
index 0000000..9bb48b7
--- /dev/null
+++ b/scripts/general/repmat.m
@@ -0,0 +1,137 @@
+## Copyright (C) 2000, 2002, 2004, 2005, 2006, 2007, 2009 Paul Kienzle
+## Copyright (C) 2008 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} repmat (@var{A}, @var{m}, @var{n})
+## @deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n}])
+## @deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n} @var{p} @dots{}])
+## Form a block matrix of size @var{m} by @var{n}, with a copy of matrix
+## @var{A} as each element.  If @var{n} is not specified, form an 
+## @var{m} by @var{m} block matrix.
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+## Created: July 2000
+
+function x = repmat (a, m, n)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3)
+    if (! (isscalar (m) && isscalar (n)))
+      error ("repmat: with 3 arguments m and n must be scalar");
+    endif
+    idx = [m, n];
+  else 
+    if (isscalar (m))
+      idx = [m, m];
+      n = m;
+    elseif (isvector (m) && length (m) > 1)
+      ## Ensure that we have a row vector
+      idx = m(:).';
+    else
+      error ("repmat: invalid dimensional argument");
+    endif
+  endif
+  
+  if (all (idx < 0))
+    error ("repmat: invalid dimensions");
+  else
+    idx = max (idx, 0);
+  endif
+
+  if (numel (a) == 1)
+    ## optimize the scalar fill case.
+    x(1:prod (idx)) = a;
+    x = reshape (x, idx);
+  elseif (ndims (a) == 2 && length (idx) < 3)
+    if (issparse (a))
+      x = kron (ones (idx), a);
+    else
+      ## indexing is now faster, so we use it rather than kron.
+      m = rows (a); n = columns (a);
+      p = idx(1); q = idx(2);
+      x = reshape (a, m, 1, n, 1);
+      x = x(:, ones (1, p), :, ones (1, q));
+      x = reshape (x, m*p, n*q);
+    endif
+  else
+    aidx = size (a);
+    ## ensure matching size
+    idx(end+1:length (aidx)) = 1;
+    aidx(end+1:length (idx)) = 1;
+    ## create subscript array
+    cidx = cell (2, length (aidx));
+    for i = 1:length (aidx)
+      cidx{1,i} = ':';
+      cidx{2,i} = ones (1, idx (i));
+    endfor
+    aaidx = aidx;
+    # add singleton dims
+    aaidx(2,:) = 1;
+    a = reshape (a, aaidx(:));
+    x = reshape (a (cidx{:}), idx .* aidx);
+  endif
+
+endfunction
+
+# Test various methods of providing size parameters
+%!shared x
+%! x = [1 2;3 4];
+%!assert(repmat(x, [1 1]), repmat(x, 1));
+%!assert(repmat(x, [3 3]), repmat(x, 3));
+%!assert(repmat(x, [1 1]), repmat(x, 1, 1));
+%!assert(repmat(x, [1 3]), repmat(x, 1, 3));
+%!assert(repmat(x, [3 1]), repmat(x, 3, 1));
+%!assert(repmat(x, [3 3]), repmat(x, 3, 3));
+
+# Tests for numel==1 case:
+%!shared x, r
+%! x = [ 65 ];
+%! r = kron(ones(2,2), x);
+%!assert(r, repmat(x, [2 2]));
+%!assert(char(r), repmat(char(x), [2 2]));
+%!assert(int8(r), repmat(int8(x), [2 2]));
+
+# Tests for ndims==2 case:
+%!shared x, r
+%! x = [ 65 66 67 ];
+%! r = kron(ones(2,2), x);
+%!assert(r, repmat(x, [2 2]));
+%!assert(char(r), repmat(char(x), [2 2]));
+%!assert(int8(r), repmat(int8(x), [2 2]));
+
+# Tests for dim>2 case:
+%!shared x, r
+%! x = [ 65 66 67 ];
+%! r = kron(ones(2,2), x);
+%! r(:,:,2) = r(:,:,1);
+%!assert(r, repmat(x, [2 2 2]));
+%!assert(char(r), repmat(char(x), [2 2 2]));
+%!assert(int8(r), repmat(int8(x), [2 2 2]));
+
+# Test that sparsity is kept
+%!assert(sparse(4,4), repmat(sparse(2,2),[2 2]));
+
+
+%!assert (size (repmat (".", -1, 1)), [0, 1]);
+%!assert (size (repmat (".", 1, -1)), [1, 0]);
+%!error (size (repmat (".", -1, -1)));
diff --git a/scripts/general/rot90.m b/scripts/general/rot90.m
new file mode 100644
index 0000000..7aa6c3b
--- /dev/null
+++ b/scripts/general/rot90.m
@@ -0,0 +1,110 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rot90 (@var{x}, @var{n})
+## Return a copy of @var{x} with the elements rotated counterclockwise in
+## 90-degree increments.  The second argument is optional, and specifies
+## how many 90-degree rotations are to be applied (the default value is 1).
+## Negative values of @var{n} rotate the matrix in a clockwise direction.
+## For example,
+##
+## @example
+## @group
+## rot90 ([1, 2; 3, 4], -1)
+##      @result{}  3  1
+##          4  2
+## @end group
+## @end example
+##
+## @noindent
+## rotates the given matrix clockwise by 90 degrees.  The following are all
+## equivalent statements:
+##
+## @example
+## @group
+## rot90 ([1, 2; 3, 4], -1)
+## rot90 ([1, 2; 3, 4], 3)
+## rot90 ([1, 2; 3, 4], 7)
+## @end group
+## @end example
+##
+## Due to the difficulty of defining an axis about which to rotate the 
+## matrix @code{rot90} only work with 2-D arrays.  To rotate N-d arrays
+## use @code{rotdim} instead.
+## @seealso{rotdim, flipud, fliplr, flipdim}
+## @end deftypefn
+
+## Author: jwe
+
+function y = rot90 (x, k)
+
+  if (nargin == 1 || nargin == 2)
+    if (nargin < 2)
+      k = 1;
+    endif
+
+    if (ndims (x) > 2)
+      error ("rot90: Only works with 2-D arrays");
+    endif
+
+    if (imag (k) != 0 || fix (k) != k)
+      error ("rot90: k must be an integer");
+    endif
+
+    k = rem (k, 4);
+
+    if (k < 0)
+      k = k + 4;
+    endif
+
+    if (k == 0)
+      y = x;
+    elseif (k == 1)
+      y = flipud (x.');
+    elseif (k == 2)
+      y = flipud (fliplr (x));
+    elseif (k == 3)
+      y = (flipud (x)).';
+    else
+      error ("rot90: internal error!");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! x1 = [1, 2;
+%! 3, 4];
+%! x2 = [2, 4;
+%! 1, 3];
+%! x3 = [4, 3;
+%! 2, 1];
+%! x4 = [3, 1;
+%! 4, 2];
+%! 
+%! assert((rot90 (x1)== x2 && rot90 (x1, 2) == x3 && rot90 (x1, 3) == x4
+%! && rot90 (x1, 4) == x1 && rot90 (x1, 5) == x2 && rot90 (x1, -1) == x4));
+
+%!error rot90 ();
+
+%!error rot90 (1, 2, 3);
+
diff --git a/scripts/general/rotdim.m b/scripts/general/rotdim.m
new file mode 100644
index 0000000..e8de83c
--- /dev/null
+++ b/scripts/general/rotdim.m
@@ -0,0 +1,118 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rotdim (@var{x}, @var{n}, @var{plane})
+## Return a copy of @var{x} with the elements rotated counterclockwise in
+## 90-degree increments.  The second argument is optional, and specifies
+## how many 90-degree rotations are to be applied (the default value is 1).
+## The third argument is also optional and defines the plane of the
+## rotation.  As such @var{plane} is a two element vector containing two
+## different valid dimensions of the matrix.  If @var{plane} is not given
+## Then the first two non-singleton dimensions are used.
+##
+## Negative values of @var{n} rotate the matrix in a clockwise direction.
+## For example,
+##
+## @example
+## @group
+## rotdim ([1, 2; 3, 4], -1, [1, 2])
+##      @result{}  3  1
+##          4  2
+## @end group
+## @end example
+##
+## @noindent
+## rotates the given matrix clockwise by 90 degrees.  The following are all
+## equivalent statements:
+##
+## @example
+## @group
+## rotdim ([1, 2; 3, 4], -1, [1, 2])
+## rotdim ([1, 2; 3, 4], 3, [1, 2])
+## rotdim ([1, 2; 3, 4], 7, [1, 2])
+## @end group
+## @end example
+## @seealso{rot90, flipud, fliplr, flipdim}
+## @end deftypefn
+
+function y = rotdim (x, k, plane)
+  
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin > 1 && ! isempty(k))
+    if (!isscalar (k) || imag (k) != 0 || fix (k) != k)
+      error ("rotdim: k must be an scalar integer");
+    endif
+  else
+    k = 1;
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin < 3)
+    ## Find the first two non-singleton dimension.
+    plane = [];
+    dim = 0;
+    while (dim < nd)
+      dim = dim + 1;
+      if (sz (dim) != 1)
+	plane = [plane, dim];
+	if (length (plane) == 2)
+	  break;
+	endif
+      endif
+    endwhile
+    if (length (plane) < 1)
+      plane = [1, 2];
+    elseif (length (plane) < 2)
+      plane = [1, plane];
+    endif
+  else
+    if (! (isvector (plane) && length (plane) == 2
+	   && all (plane == round (plane)) && all (plane > 0)
+	   && all (plane < (nd + 1)) && plane(1) != plane(2)))
+      error ("rotdim: plane must be a 2 element integer vector defining a valid plane");
+    endif
+  endif
+
+  k = rem (k, 4);
+  if (k < 0)
+    k = k + 4;
+  endif
+  if (k == 0)
+    y = x;
+  elseif (k == 2)
+    y = flipdim (flipdim (x, plane(1)), plane(2));
+  elseif (k == 1 || k == 3)
+    perm = 1:nd;
+    perm(plane(1)) = plane(2);
+    perm(plane(2)) = plane(1);
+    y = permute (x, perm);
+    if (k == 1)
+      y = flipdim (y, min (plane));
+    else
+      y = flipdim (y, max (plane));
+    endif
+  else
+    error ("rotdim: internal error!");
+  endif
+
+endfunction
diff --git a/scripts/general/runlength.m b/scripts/general/runlength.m
new file mode 100644
index 0000000..401f61f
--- /dev/null
+++ b/scripts/general/runlength.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2005, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} runlength (@var{x})
+## Find the lengths of all sequences of common values.  Return the
+## vector of lengths and the value that was repeated.
+##
+## @example
+## @group
+## runlength ([2, 2, 0, 4, 4, 4, 0, 1, 1, 1, 1])
+## @result{}  [2, 1, 3, 1, 4]
+## @end group
+## @end example
+## @end deftypefn
+
+function [count, value] = runlength (x)
+  idx = [find(x(1:end-1) != x(2:end)), length(x)];
+  value = x(idx);
+  count = diff ([0 idx]);
+endfunction
+
+%!assert (runlength([2 2 0 4 4 4 0 1 1 1 1]), [2 1 3 1 4]);
diff --git a/scripts/general/saveobj.m b/scripts/general/saveobj.m
new file mode 100644
index 0000000..9cb51e1
--- /dev/null
+++ b/scripts/general/saveobj.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{b} =} saveobj (@var{a})
+## Method of a class to manipulate an object prior to saving it to a file. 
+## The function @code{saveobj} is called when the object @var{a} is saved 
+## using the @code{save} function.  An example of the use of @code{saveobj}
+## might be to remove fields of the object that don't make sense to be saved
+## or it might be used to ensure that certain fields of the object are
+## initialized before the object is saved.  For example
+##
+## @example
+## @group
+## function b = saveobj (a)
+##   b = a;
+##   if (isempty (b.field))
+##      b.field = initfield(b);
+##   endif
+## endfunction
+## @end group
+## @end example
+##
+## @seealso{loadobj, class}
+## @end deftypefn
+
+function b = saveobj (a)
+  error ("saveobj: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/scripts/general/shift.m b/scripts/general/shift.m
new file mode 100644
index 0000000..f8c727a
--- /dev/null
+++ b/scripts/general/shift.m
@@ -0,0 +1,102 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+##               2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} shift (@var{x}, @var{b})
+## @deftypefnx {Function File} {} shift (@var{x}, @var{b}, @var{dim})
+## If @var{x} is a vector, perform a circular shift of length @var{b} of
+## the elements of @var{x}.
+##
+## If @var{x} is a matrix, do the same for each column of @var{x}.
+## If the optional @var{dim} argument is given, operate along this 
+## dimension
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 14 September 1994
+## Adapted-By: jwe
+
+function y = shift (x, b, dim)
+
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (! (isscalar (b) && b == round (b)))
+    error ("shift: b must be an integer");
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+
+  if (nargin == 3)
+    if (! (isscalar (dim) && dim == round (dim)) && dim > 0 && 
+	dim < (nd + 1))
+      error ("shift: dim must be an integer and valid dimension");
+    endif
+  else
+    ## Find the first non-singleton dimension
+    dim  = 1;
+    while (dim < nd + 1 && sz (dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  endif
+
+  if (numel (x) < 1)
+    error ("shift: x must not be empty");
+  endif
+
+  d = sz (dim);
+
+  idx = cell ();
+  for i = 1:nd
+    idx{i} = 1:sz(i);
+  endfor
+  if (b >= 0)
+    b = rem (b, d);
+    idx{dim} = [d-b+1:d, 1:d-b];
+  elseif (b < 0)
+    b = rem (abs (b), d);
+    idx{dim} = [b+1:d, 1:b];
+  endif
+  y = x(idx{:});
+
+endfunction
+
+%!test
+%! a = [1, 2, 3];
+%! b = [4, 5, 6];
+%! c = [7, 8, 9];
+%! 
+%! r = [a, b, c];
+%! m = [a; b; c];
+%! 
+%! assert((shift (r, 3) == [c, a, b]
+%! && shift (r, -6) == [c, a, b]
+%! && shift (r, -3) == [b, c, a]
+%! && shift (m, 1) == [c; a; b]
+%! && shift (m, -2) == [c; a; b]));
+
+%!error shift ();
+
+%!error shift (1, 2, 3, 4);
+
diff --git a/scripts/general/shiftdim.m b/scripts/general/shiftdim.m
new file mode 100644
index 0000000..88a108e
--- /dev/null
+++ b/scripts/general/shiftdim.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 John Eaton and David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} shiftdim (@var{x}, @var{n})
+## @deftypefnx {Function File} {[@var{y}, @var{ns}] =} shiftdim (@var{x})
+## Shifts the dimension of @var{x} by @var{n}, where @var{n} must be
+## an integer scalar.  When @var{n} is positive, the dimensions of
+## @var{x} are shifted to the left, with the leading dimensions
+## circulated to the end.  If @var{n} is negative, then the dimensions
+## of @var{x} are shifted to the right, with @var{n} leading singleton
+## dimensions added.
+##
+## Called with a single argument, @code{shiftdim}, removes the leading
+## singleton dimensions, returning the number of dimensions removed
+## in the second output argument @var{ns}.
+##
+## For example 
+##
+## @example
+## @group
+## x = ones (1, 2, 3);
+## size (shiftdim (x, -1))
+##      @result{} [1, 1, 2, 3]
+## size (shiftdim (x, 1))
+##      @result{} [2, 3]
+## [b, ns] = shiftdim (x);
+##      @result{} b =  [1, 1, 1; 1, 1, 1]
+##      @result{} ns = 1
+## @end group
+## @end example
+## @seealso {reshape, permute, ipermute, circshift, squeeze}
+## @end deftypefn
+
+function [y, ns]  = shiftdim (x, n)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  orig_dims = size (x);
+
+  if (nargin == 1)
+    ## Find the first singleton dimension.
+    n = 0;
+    while (n < nd && orig_dims(n+1) == 1)
+      n++;
+    endwhile
+  endif
+
+  if (! isscalar (n) || floor (n) != n)
+    error ("shiftdim: n must be a scalar integer");
+  endif
+
+  if (n >= nd)
+    n = rem (n, nd);
+  endif
+
+  if (n < 0)
+    singleton_dims = ones (1, -n);
+    y = reshape (x, [singleton_dims, orig_dims]);
+  elseif (n > 0)
+    ## We need permute here instead of reshape to shift values in a
+    ## compatible way.
+    y = permute (x, [n+1:ndims(x) 1:n]);
+  else
+    y = x;
+  endif
+
+  ns = n;
+
+endfunction
diff --git a/scripts/general/sortrows.m b/scripts/general/sortrows.m
new file mode 100644
index 0000000..aeb9cf7
--- /dev/null
+++ b/scripts/general/sortrows.m
@@ -0,0 +1,79 @@
+## Copyright (C) 2000, 2005, 2007, 2008 Daniel Calvelo
+## Copyright (C) 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sortrows (@var{a}, @var{c})
+## Sort the rows of the matrix @var{a} according to the order of the
+## columns specified in @var{c}.  If @var{c} is omitted, a
+## lexicographical sort is used.  By default ascending order is used 
+## however if elements of @var{c} are negative then the corresponding  
+## column is sorted in descending order.
+## @end deftypefn
+
+## Author: Daniel Calvelo, Paul Kienzle
+## Adapted-by: jwe
+
+function [s, i] = sortrows (m, c)
+
+  default_mode = "ascend";
+  other_mode = "descend";
+
+  if (issparse (m))
+    error ("sortrows: sparse matrices not yet supported");
+  endif
+
+  ## If the sort is homogeneous, we use the built-in faster algorithm.
+  if (nargin == 1)
+    i = __sort_rows_idx__ (m, default_mode);
+  elseif (all (c > 0))
+    i = __sort_rows_idx__ (m(:,c), default_mode);
+  elseif (all (c < 0))
+    i = __sort_rows_idx__ (m(:,-c), other_mode);
+  else
+    ## Otherwise, fall back to the old algorithm
+    for ii = 1:length (c);
+      if (c(ii) < 0)
+        mode{ii} = other_mode;
+      else
+        mode{ii} = default_mode;
+      endif
+    endfor
+    indices = abs(c(:));
+
+    ## Since sort is 'stable' the order of identical elements will be
+    ## preserved, so by traversing the sort indices in reverse order we
+    ## will make sure that identical elements in index i are subsorted by
+    ## index j.
+    indices = flipud (indices);
+    mode = flipud (mode');
+    i = [1:size(m,1)]';
+    for ii = 1:length (indices);
+      [trash, idx] = sort (m(i, indices(ii)), mode{ii});
+      i = i(idx);
+    endfor
+  endif
+
+  s = m(i,:);
+
+endfunction
+
+%!shared x, idx
+%! [x, idx] = sortrows ([1, 1; 1, 2; 3, 6; 2, 7], [1, -2]);
+%!assert (x, [1, 2; 1, 1; 2, 7; 3, 6]);
+%!assert (idx, [2; 1; 4; 3]);
diff --git a/scripts/general/sph2cart.m b/scripts/general/sph2cart.m
new file mode 100644
index 0000000..9b5f19b
--- /dev/null
+++ b/scripts/general/sph2cart.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{theta}, @var{phi}, @var{r})
+## Transform spherical to Cartesian coordinates.
+## @var{x}, @var{y} and @var{z} must be the same shape, or scalar.
+## @var{theta} describes the angle relative to the positive x-axis.
+## @var{phi} is the angle relative to the xy-plane.
+## @var{r} is the distance to the origin (0, 0, 0).
+## @seealso{pol2cart, cart2pol, cart2sph}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Adapted-by: jwe
+
+function [x, y, z] = sph2cart (theta, phi, r)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if ((ismatrix (theta) && ismatrix (phi) && ismatrix (r))
+      && (size_equal (theta, phi) || isscalar (theta) || isscalar (phi))
+      && (size_equal (theta, r) || isscalar (theta) || isscalar (r))
+      && (size_equal (phi, r) || isscalar (phi) || isscalar (r)))
+
+    x = r .* cos (phi) .* cos (theta);
+    y = r .* cos (phi) .* sin (theta);
+    z = r .* sin (phi);
+
+  else
+    error ("sph2cart: arguments must be matrices of same size, or scalar");
+  endif
+
+endfunction
+
+%!test
+%! t = [0, 0, 0];
+%! p = [0, 0, 0];
+%! r = [0, 1, 2];
+%! [x, y, z] = sph2cart (t, p, r);
+%! assert (x, r);
+%! assert (y, [0, 0, 0]);
+%! assert (z, [0, 0, 0]);
+
+%!test
+%! t = 0;
+%! p = [0, 0, 0];
+%! r = [0, 1, 2];
+%! [x, y, z] = sph2cart (t, p, r);
+%! assert (x, r);
+%! assert (y, [0, 0, 0]);
+%! assert (z, [0, 0, 0]);
+
+%!test
+%! t = [0, 0, 0];
+%! p = 0;
+%! r = [0, 1, 2];
+%! [x, y, z] = sph2cart (t, p, r);
+%! assert (x, r);
+%! assert (y, [0, 0, 0]);
+%! assert (z, [0, 0, 0]);
+
+%!test
+%! t = [0, 0.5, 1]*pi;
+%! p = [0, 0, 0];
+%! r = 1;
+%! [x, y, z] = sph2cart (t, p, r);
+%! assert (x, [1, 0, -1], eps);
+%! assert (y, [0, 1, 0], eps);
+%! assert (z, [0, 0, 0], eps);
+
diff --git a/scripts/general/strerror.m b/scripts/general/strerror.m
new file mode 100644
index 0000000..1bb4fd1
--- /dev/null
+++ b/scripts/general/strerror.m
@@ -0,0 +1,66 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2002, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strerror (@var{name}, @var{num})
+## Return the text of an error message for function @var{name}
+## corresponding to the error number @var{num}.  This function is intended
+## to be used to print useful error messages for those functions that
+## return numeric error codes.
+## @end deftypefn
+
+## Author: jwe
+
+function msg = strerror (name, err)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! ischar (name))
+    error ("strerror: first argument must be a string");
+  endif
+
+  if (! isscalar (err))
+    error ("strerror: second argument must be a scalar");
+  endif
+
+  if (strcmp (name, "fsolve"))
+
+    if (err == -2)
+      msg = "input error\n";
+    elseif (err == -1)
+      msg = "error encountered in user-supplied function\n";
+    elseif (err == 1)
+      msg = "solution converged to requested tolerance\n";
+    elseif (err == 4)
+      msg = "iteration limit exceeded\n";
+    elseif (err == 3)
+      msg = "iteration is not making good progress\n";
+    else
+      error ("strerror: unrecognized error code for fsolve");
+    endif
+
+  else
+
+    error ("strerror: unrecognized function name");
+
+  endif
+
+endfunction
diff --git a/scripts/general/structfun.m b/scripts/general/structfun.m
new file mode 100644
index 0000000..c7a9b6b
--- /dev/null
+++ b/scripts/general/structfun.m
@@ -0,0 +1,86 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} structfun (@var{func}, @var{s})
+## @deftypefnx {Function File} {[@var{a}, @var{b}] =} structfun (@dots{})
+## @deftypefnx {Function File} {} structfun (@dots{}, "ErrorHandler", @var{errfunc})
+## @deftypefnx {Function File} {} structfun (@dots{}, "UniformOutput", @var{val})
+## 
+## Evaluate the function named @var{name} on the fields of the structure
+## @var{s}.  The fields of @var{s} are passed to the function @var{func}
+## individually.
+##
+## @code{structfun} accepts an arbitrary function @var{func} in the form of 
+## an inline function, function handle, or the name of a function (in a 
+## character string).  In the case of a character string argument, the 
+## function must accept a single argument named @var{x}, and it must return 
+## a string value.  If the function returns more than one argument, they are
+## returned as separate output variables.
+##
+## If the parameter "UniformOutput" is set to true (the default), then the function
+## must return a single element which will be concatenated into the
+## return value.  If "UniformOutput" is false, the outputs placed in a structure
+## with the same fieldnames as the input structure.
+## 
+## @example
+## @group
+## s.name1 = "John Smith"; 
+## s.name2 = "Jill Jones"; 
+## structfun (@@(x) regexp (x, '(\w+)$', "matches")@{1@}, s, 
+##            "UniformOutput", false)
+## @end group
+## @end example
+## 
+## Given the parameter "ErrorHandler", then @var{errfunc} defines a function to
+## call in case @var{func} generates an error.  The form of the function is
+## 
+## @example
+## function [@dots{}] = errfunc (@var{se}, @dots{})
+## @end example
+## 
+## where there is an additional input argument to @var{errfunc} relative to
+## @var{func}, given by @var{se}.  This is a structure with the elements
+## "identifier", "message" and "index", giving respectively the error
+## identifier, the error message, and the index into the input arguments
+## of the element that caused the error.
+## @seealso{cellfun, arrayfun}
+## @end deftypefn
+
+function varargout = structfun (fun, s, varargin);
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  varargout = cell (max ([nargout, 1]), 1);
+  [varargout{:}] = cellfun (fun, struct2cell (s), varargin{:});
+
+  if (iscell (varargout{1}))
+    [varargout{:}] = cell2struct (varargout{1}, fieldnames(s), 1);
+  endif
+endfunction
+
+
+%!test
+%! s.name1 = "John Smith"; 
+%! s.name2 = "Jill Jones"; 
+%! l.name1 = "Smith";
+%! l.name2 = "Jones";
+%! o = structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s, 
+%!		  "UniformOutput", false);
+%! assert (o, l);
diff --git a/scripts/general/sub2ind.m b/scripts/general/sub2ind.m
new file mode 100644
index 0000000..3be8891
--- /dev/null
+++ b/scripts/general/sub2ind.m
@@ -0,0 +1,128 @@
+## Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008,
+##               2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{ind} =} sub2ind (@var{dims}, @var{i}, @var{j})
+## @deftypefnx {Function File} {@var{ind} =} sub2ind (@var{dims}, @var{s1}, @var{s2}, @dots{}, @var{sN})
+## Convert subscripts into a linear index.
+##
+## The following example shows how to convert the two-dimensional
+## index @code{(2,3)} of a 3-by-3 matrix to a linear index.  The matrix
+## is linearly indexed moving from one column to next, filling up
+## all rows in each column.
+##
+## @example
+## @group
+## linear_index = sub2ind ([3, 3], 2, 3)
+## @result{} 8
+## @end group
+## @end example
+## @seealso{ind2sub}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+## Adapted-by: jwe
+
+function ind = sub2ind (dims, varargin)
+
+  if (nargin > 1)
+    if (isvector (dims) && all (round (dims) == dims))
+      nd = length (dims);
+      vlen = length (varargin);
+      dims(vlen) = prod (dims(vlen:nd));
+      dims(vlen+1:nd) = [];
+      scale = cumprod (dims(:));
+      for i = 1:vlen
+	arg = varargin{i};
+	if (isnumeric (arg) && isequal (round (arg), arg))
+	  if (i == 1)
+	    if (all (arg(:) > 0 & arg(:) <= dims(i)))
+	      ind = first_arg = arg;
+	    else
+	      error ("sub2ind: index out of range");
+	    endif
+	  else
+	    if (size_equal (first_arg, arg))
+	      if ((i > nd && arg == 1) || all (arg(:) > 0 & arg(:) <= dims(i)))
+		ind += scale(i-1) * (arg - 1);
+	      else
+		error ("sub2ind: index out of range");
+	      endif
+	    else
+	      error ("sub2ind: all index arguments must be the same size");
+	    endif
+	  endif
+	else
+	  error ("sub2ind: expecting integer-valued index arguments");
+	endif
+      endfor
+    else
+      error ("sub2ind: expecting dims to be an integer vector");
+    endif
+  else
+    print_usage ();
+  endif
+
+
+endfunction
+
+# Test input validation
+%!error <sub2ind: expecting dims to be an integer vector> sub2ind([10 10.5], 1, 1);
+%!error <sub2ind: expecting integer-valued index arguments> sub2ind([10 10], 1.5, 1);
+%!error <sub2ind: expecting integer-valued index arguments> sub2ind([10 10], 1, 1.5);
+
+# Test evaluation
+%!shared s1, s2, s3, in
+%! s1 = [   1   1   1   1 ;   2   2   2   2 ];
+%! s2 = [   1   1   2   2 ;   1   1   2   2 ];
+%! s3 = [   1   2   1   2 ;   1   2   1   2 ];
+%! in = [   1 101  11 111 ;   2 102  12 112 ];
+%!assert (sub2ind([10 10 10], s1, s2, s3), in);
+%!shared
+
+# Test low index
+%!assert (sub2ind([10 10 10], 1, 1, 1), 1);
+%!error <sub2ind: index out of range> sub2ind([10 10 10], 0, 1, 1);
+%!error <sub2ind: index out of range> sub2ind([10 10 10], 1, 0, 1);
+%!error <sub2ind: index out of range> sub2ind([10 10 10], 1, 1, 0);
+
+# Test high index
+%!assert (sub2ind([10 10 10], 10, 10, 10), 1000);
+%!error <sub2ind: index out of range> sub2ind([10 10 10], 11, 10, 10);
+%!error <sub2ind: index out of range> sub2ind([10 10 10], 10, 11, 10);
+%!error <sub2ind: index out of range> sub2ind([10 10 10], 10, 10, 11);
+
+# Test high index in the trailing dimensions
+%!assert (sub2ind([10], 2, 1, 1), 2);
+%!error <sub2ind: index out of range> sub2ind([10], 1, 2, 1);
+%!error <sub2ind: index out of range> sub2ind([10], 1, 1, 2);
+%!assert (sub2ind([10 10], 2, 2, 1), 12);
+%!error <sub2ind: index out of range> sub2ind([10 10], 2, 1, 2);
+%!error <sub2ind: index out of range> sub2ind([10 10], 1, 2, 2);
+
+# Test handling of empty arguments
+%!assert (sub2ind([10 10], zeros(0,0), zeros(0,0)), zeros(0,0));
+%!assert (sub2ind([10 10], zeros(2,0), zeros(2,0)), zeros(2,0));
+%!assert (sub2ind([10 10], zeros(0,2), zeros(0,2)), zeros(0,2));
+%!error <sub2ind: all index arguments must be the same size> sub2ind([10 10 10], zeros(0,2), zeros(2,0));
+
+# Test handling of arguments of different size
+%!error <sub2ind: all index arguments must be the same size> sub2ind([10 10], ones(1,2), ones(1,3));
+%!error <sub2ind: all index arguments must be the same size> sub2ind([10 10], ones(1,2), ones(2,1));
+
diff --git a/scripts/general/subsindex.m b/scripts/general/subsindex.m
new file mode 100644
index 0000000..ff22f8c
--- /dev/null
+++ b/scripts/general/subsindex.m
@@ -0,0 +1,64 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{idx} =} subsindex (@var{a})
+## Convert an object to an index vector.  When @var{a} is a class object 
+## defined with a class constructor, then @code{subsindex} is the
+## overloading method that allows the conversion of this class object to
+## a valid indexing vector.  It is important to note that
+## @code{subsindex} must return a zero-based real integer vector of the
+## class "double".  For example, if the class constructor
+##
+## @example
+## @group
+## function b = myclass (a)
+##  b = myclass (struct ("a", a), "myclass");
+## endfunction
+## @end group
+## @end example
+##
+## @noindent
+## then the @code{subsindex} function
+##
+## @example
+## @group
+## function idx = subsindex (a)
+##  idx = double (a.a) - 1.0;
+## endfunction
+## @end group
+## @end example
+##
+## @noindent
+## can then be used as follows
+##
+## @example
+## @group
+## a = myclass (1:4);
+## b = 1:10;
+## b(a)
+## @result{} 1  2  3  4
+## @end group
+## @end example
+##
+## @seealso{class, subsref, subsasgn}
+## @end deftypefn
+
+function idx = subsindex (a)
+  error ("subsindex: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/scripts/general/trapz.m b/scripts/general/trapz.m
new file mode 100644
index 0000000..7c9f584
--- /dev/null
+++ b/scripts/general/trapz.m
@@ -0,0 +1,105 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{z} =} trapz (@var{y})
+## @deftypefnx {Function File} {@var{z} =} trapz (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{z} =} trapz (@dots{}, @var{dim})
+## 
+## Numerical integration using trapezoidal method.  @code{trapz
+## (@var{y})} computes the integral of the @var{y} along the first
+## non-singleton dimension.  If the argument @var{x} is omitted a 
+## equally spaced vector is assumed.  @code{trapz (@var{x}, @var{y})} 
+## evaluates the integral with respect to @var{x}.
+##  
+## @seealso{cumtrapz}
+## @end deftypefn
+
+## Author:	Kai Habel <kai.habel at gmx.de>
+##
+## also: June 2000 - Paul Kienzle (fixes,suggestions) 
+## 2006-05-12 David Bateman - Modified for NDArrays
+
+function z = trapz (x, y, dim)
+	
+
+  if (nargin < 1) || (nargin > 3)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+
+  have_x = false;
+  have_dim = false;
+  if (nargin == 3)
+    have_x = true;
+    have_dim = true;
+  endif
+  if (nargin == 2)
+    if (! size_equal (x, y) && isscalar (y))
+      dim = y;
+      have_dim = true;
+    else
+      have_x = true;
+    endif
+  endif
+
+  if (! have_dim)
+    ## Find the first singleton dimension.
+    dim = 0;
+    while (dim < nd && sz(dim+1) == 1)
+      dim++;
+    endwhile
+    dim++;
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    dim = floor (dim);
+    if (dim < 1 || dim > nd)
+      error ("trapz: invalid dimension along which to sort");
+    endif
+  endif
+ 
+  n = sz(dim);
+  idx1 = cell ();
+  for i = 1:nd
+    idx1{i} = 1:sz(i);
+  endfor
+  idx2 = idx1;
+  idx1{dim} = 2 : n;	
+  idx2{dim} = 1 : (n - 1);
+
+  if (! have_x)
+    z = 0.5 * sum (x(idx1{:}) + x(idx2{:}), dim);
+  else
+    if (! size_equal (x, y))
+      error ("trapz: x and y must have same shape");
+    endif
+    z = 0.5 * sum ((x(idx1{:}) - x(idx2{:})) .* 
+		   (y(idx1{:}) + y(idx2{:})), dim);
+  endif
+endfunction
+
+%!assert (trapz(1:5), 12)
+%!assert (trapz(0:0.5:2,1:5), 6)
+%!assert (trapz([1:5;1:5],2),[12;12])
+%!assert (trapz([1:5;1:5].',1),[12,12])
+%!assert (trapz([0:0.5:2;0:0.5:2],[1:5;1:5],2),[6;6])
+%!assert (trapz([0:0.5:2;0:0.5:2].',[1:5;1:5].',1),[6,6])
diff --git a/scripts/general/tril.m b/scripts/general/tril.m
new file mode 100644
index 0000000..b4b3747
--- /dev/null
+++ b/scripts/general/tril.m
@@ -0,0 +1,112 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} tril (@var{a}, @var{k})
+## @deftypefnx {Function File} {} triu (@var{a}, @var{k})
+## Return a new matrix formed by extracting the lower (@code{tril})
+## or upper (@code{triu}) triangular part of the matrix @var{a}, and
+## setting all other elements to zero.  The second argument is optional,
+## and specifies how many diagonals above or below the main diagonal should
+## also be set to zero.
+##
+## The default value of @var{k} is zero, so that @code{triu} and
+## @code{tril} normally include the main diagonal as part of the result
+## matrix.
+##
+## If the value of @var{k} is negative, additional elements above (for
+## @code{tril}) or below (for @code{triu}) the main diagonal are also
+## selected.
+##
+## The absolute value of @var{k} must not be greater than the number of
+## sub- or super-diagonals.
+##
+## For example,
+##
+## @example
+## @group
+## tril (ones (3), -1)
+##      @result{}  0  0  0
+##          1  0  0
+##          1  1  0
+## @end group
+## @end example
+##
+## @noindent
+## and
+##
+## @example
+## @group
+## tril (ones (3), 1)
+##      @result{}  1  1  0
+##          1  1  1
+##          1  1  1
+## @end group
+## @end example
+## @seealso{triu, diag}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = tril (x, k)
+
+  if (nargin > 0)
+    if (isstruct (x))
+       error ("tril: structure arrays not supported");
+     endif 
+    [nr, nc] = size (x);
+  endif
+
+  if (nargin == 1)
+    k = 0;
+  elseif (nargin == 2)
+    if ((k > 0 && k > nc) || (k < 0 && k < -nr))
+      error ("tril: requested diagonal out of range");
+    endif
+  else
+    print_usage ();
+  endif
+
+  retval = resize (resize (x, 0), nr, nc);
+  for j = 1 : min (nc, nr+k)
+    nr_limit = max (1, j-k);
+    retval (nr_limit:nr, j) = x (nr_limit:nr, j);
+  endfor
+
+endfunction
+
+%!test
+%! a = [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12];
+%! 
+%! l0 = [1, 0, 0; 4, 5, 0; 7, 8, 9; 10, 11, 12];
+%! l1 = [1, 2, 0; 4, 5, 6; 7, 8, 9; 10, 11, 12];
+%! l2 = [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12];
+%! lm1 = [0, 0, 0; 4, 0, 0; 7, 8, 0; 10, 11, 12];
+%! lm2 = [0, 0, 0; 0, 0, 0; 7, 0, 0; 10, 11, 0];
+%! lm3 = [0, 0, 0; 0, 0, 0; 0, 0, 0; 10, 0, 0];
+%! lm4 = [0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0];
+%! 
+%! assert((tril (a, -4) == lm4 && tril (a, -3) == lm3
+%! && tril (a, -2) == lm2 && tril (a, -1) == lm1
+%! && tril (a) == l0 && tril (a, 1) == l1 && tril (a, 2) == l2));
+
+%!error tril ();
+
+%!error tril (1, 2, 3);
+
diff --git a/scripts/general/triplequad.m b/scripts/general/triplequad.m
new file mode 100644
index 0000000..528ef0e
--- /dev/null
+++ b/scripts/general/triplequad.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} triplequad (@var{f}, @var{xa}, @var{xb}, @var{ya}, @var{yb}, @var{za}, @var{zb}, @var{tol}, @var{quadf}, @dots{})
+## Numerically evaluate a triple integral.  The function over which to
+## integrate is defined by @code{@var{f}}, and the interval for the
+## integration is defined by @code{[@var{xa}, @var{xb}, @var{ya},
+## @var{yb}, @var{za}, @var{zb}]}.  The function @var{f} must accept a
+## vector @var{x} and a scalar @var{y}, and return a vector of the same
+## length as @var{x}.
+##
+## If defined, @var{tol} defines the absolute tolerance to which to
+## which to integrate each sub-integral.
+##
+## Additional arguments, are passed directly to @var{f}.  To use the default
+## value for @var{tol} one may pass an empty matrix.
+## @seealso{dblquad, quad, quadv, quadl, quadgk, trapz}
+## @end deftypefn
+
+function Q = triplequad(f, xa, xb, ya, yb, za, zb, tol, quadf, varargin)
+  if (nargin < 7)
+    print_usage ();
+  endif
+  if (nargin < 8 || isempty (tol))
+    tol = 1e-6; 
+  endif
+  if (nargin < 9 || isempty (quadf))
+    quadf = @quadgk; 
+  endif
+
+  inner = @__triplequad_inner__;
+  if (ischar (f))
+    f = @(x,y,z) feval (f, x, y, z, varargin{:});
+    varargin = {};
+  endif
+
+  Q = dblquad(@(y, z) inner (y, z, f, xa, xb, tol, quadf, varargin{:}),ya, yb, za, zb, tol);
+endfunction
+
+function Q = __triplequad_inner__ (y, z, f, xa, xb, tol, quadf, varargin)
+  Q = zeros (size(y));
+  for i = 1 : length (y)
+    Q(i) = feval (quadf, @(x) f (x, y(i), z, varargin{:}), xa, xb, tol);
+  endfor
+endfunction
+
+%% These tests are too expensive to run normally. Disable them
+% !#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [],  @quadgk), pi ^ (3/2) * erf(1).^3, 1e-6)
+% !#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [],  @quadl), pi ^ (3/2) * erf(1).^3, 1e-6)
+% !#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [],  @quadv), pi ^ (3/2) * erf(1).^3, 1e-6)
diff --git a/scripts/general/triu.m b/scripts/general/triu.m
new file mode 100644
index 0000000..8473015
--- /dev/null
+++ b/scripts/general/triu.m
@@ -0,0 +1,71 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2005, 2006,
+##               2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} triu (@var{a}, @var{k})
+## See tril.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = triu (x, k)
+
+  if (nargin > 0)
+    if (isstruct (x))
+       error ("tril: structure arrays not supported");
+     endif 
+    [nr, nc] = size (x);
+  endif
+  if (nargin == 1)
+    k = 0;
+  elseif (nargin == 2)
+    if ((k > 0 && k > nc) || (k < 0 && k < -nr))
+      error ("triu: requested diagonal out of range");
+    endif
+  else
+    print_usage ();
+  endif
+
+  retval = resize (resize (x, 0), nr, nc);
+  for j = max (1, k+1) : nc
+    nr_limit = min (nr, j-k);
+    retval (1:nr_limit, j) = x (1:nr_limit, j);
+  endfor
+
+endfunction
+
+%!test
+%! a = [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12];
+%! 
+%! u0 = [1, 2, 3; 0, 5, 6; 0, 0, 9; 0, 0, 0];
+%! u1 = [0, 2, 3; 0, 0, 6; 0, 0, 0; 0, 0, 0];
+%! u2 = [0, 0, 3; 0, 0, 0; 0, 0, 0; 0, 0, 0];
+%! u3 = [0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0];
+%! um1 = [1, 2, 3; 4, 5, 6; 0, 8, 9; 0, 0, 12];
+%! um2 = [1, 2, 3; 4, 5, 6; 7, 8, 9; 0, 11, 12];
+%! um3 = [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12];
+%! 
+%! assert((triu (a, -3) == um3 && triu (a, -2) == um2
+%! && triu (a, -1) == um1 && triu (a) == u0 && triu (a, 1) == u1
+%! && triu (a, 2) == u2 && triu (a, 3) == u3));
+
+%!error triu ();
+
+%!error triu (1, 2, 3);
+
diff --git a/scripts/geometry/Makefile.in b/scripts/geometry/Makefile.in
new file mode 100644
index 0000000..7d8d031
--- /dev/null
+++ b/scripts/geometry/Makefile.in
@@ -0,0 +1,100 @@
+# Makefile for octave's scripts/geometry directory
+#
+# Copyright (C) 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = geometry
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = \
+  convhull.m \
+  delaunay3.m \
+  delaunayn.m \
+  delaunay.m \
+  dsearch.m \
+  dsearchn.m \
+  griddata.m \
+  griddata3.m \
+  griddatan.m \
+  inpolygon.m \
+  rectint.m \
+  trimesh.m \
+  triplot.m \
+  trisurf.m \
+  tsearchn.m \
+  voronoi.m \
+  voronoin.m
+
+DISTFILES = $(addprefix $(srcdir)/,Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/geometry
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/geometry/convhull.m b/scripts/geometry/convhull.m
new file mode 100644
index 0000000..c0464af
--- /dev/null
+++ b/scripts/geometry/convhull.m
@@ -0,0 +1,86 @@
+## Copyright (C) 2000, 2007, 2008 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{H} =} convhull (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{H} =} convhull (@var{x}, @var{y}, @var{opt})
+## Returns the index vector to the points of the enclosing convex hull.  The
+## data points are defined by the x and y vectors.
+##
+## A third optional argument, which must be a string, contains extra options
+## passed to the underlying qhull command.  See the documentation for the 
+## Qhull library for details.
+##
+## @seealso{delaunay, convhulln}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function H = convhull (x, y, opt)
+
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (isvector (x) && isvector (y) && length (x) == length (y))
+    if (nargin == 2)
+      i = convhulln ([x(:), y(:)]);
+    elseif (ischar (opt) || iscell (opt))
+      i = convhulln ([x(:), y(:)], opt);
+    else
+      error ("convhull: third argument must be a string or cell array of strings");
+    endif
+  else
+    error ("convhull: first two input arguments must be vectors of same size");
+  endif
+
+  n = rows (i);
+  i = i'(:);
+  H = zeros (n + 1, 1);
+
+  H(1) = i(1);
+  next_i = i(2);
+  i(2) = 0;
+  for k = 2:n
+    next_idx = find (i == next_i);
+
+    if (rem (next_idx, 2) == 0)
+      H(k) = i(next_idx);
+      next_i = i(next_idx - 1);
+      i(next_idx - 1) = 0;
+    else
+      H(k) = i(next_idx);
+      next_i = i(next_idx + 1);
+      i(next_idx + 1) = 0;
+    endif
+  endfor
+
+  H(n + 1) = H(1);
+endfunction
+
+%!testif HAVE_QHULL
+%! x = -3:0.5:3;
+%! y = abs (sin (x));
+%! assert (convhull (x, y, {"s","Qci","Tcv","Pp"}), [1;7;13;12;11;10;4;3;2;1])
+
+%!demo
+%! x = -3:0.05:3;
+%! y = abs (sin (x));
+%! k = convhull (x, y);
+%! plot (x(k),y(k),'r-',x,y,'b+');
+%! axis ([-3.05, 3.05, -0.05, 1.05]);
diff --git a/scripts/geometry/delaunay.m b/scripts/geometry/delaunay.m
new file mode 100644
index 0000000..968f08f
--- /dev/null
+++ b/scripts/geometry/delaunay.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1999, 2000, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{tri} =} delaunay (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{tri} =} delaunay (@var{x}, @var{y}, @var{opt})
+## The return matrix of size [n, 3] contains a set triangles which are
+## described by the indices to the data point x and y vector.
+## The triangulation satisfies the Delaunay circum-circle criterion.
+## No other data point is in the circum-circle of the defining triangle.
+##
+## A third optional argument, which must be a string, contains extra options
+## passed to the underlying qhull command.  See the documentation for the 
+## Qhull library for details.
+##
+## @example
+## @group
+## x = rand (1, 10);
+## y = rand (size (x));
+## T = delaunay (x, y);
+## X = [x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1))];
+## Y = [y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1))];
+## axis ([0,1,0,1]);
+## plot (X, Y, "b", x, y, "r*");
+## @end group
+## @end example
+## @seealso{voronoi, delaunay3, delaunayn}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function ret = delaunay (x, y, opt)
+
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+  
+  if (isvector (x) && isvector (y) && length (x) == length (y))
+    if (nargin == 2)
+      tri = delaunayn ([x(:), y(:)]);
+    elseif (ischar (opt) || iscellstr (opt))
+      tri = delaunayn ([x(:), y(:)], opt);
+    else
+      error ("delaunay: third argument must be a string");
+    endif
+  else
+    error ("delaunay: first two input arguments must be vectors of same size");
+  endif
+
+  if (nargout == 0)
+    x = x(:).';
+    y = y(:).';
+    X = [x(tri(:,1)); x(tri(:,2)); x(tri(:,3)); x(tri(:,1))];
+    Y = [y(tri(:,1)); y(tri(:,2)); y(tri(:,3)); y(tri(:,1))];
+    plot(X, Y, 'b', x, y, 'r*');
+  else
+    ret = tri;
+  endif
+endfunction
+
+%!testif HAVE_QHULL
+%! x = [-1, 0, 1, 0, 0];
+%! y = [0, 1, 0, -1, 0];
+%! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,5;1,4,5;2,3,5;3,4,5])
+
+%!demo
+%! rand ('state', 1);
+%! x = rand(1,10);
+%! y = rand(size(x));
+%! T = delaunay(x,y);
+%! X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
+%! Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+%! axis([0,1,0,1]);
+%! plot(X,Y,'b',x,y,'r*');
diff --git a/scripts/geometry/delaunay3.m b/scripts/geometry/delaunay3.m
new file mode 100644
index 0000000..4aa6627
--- /dev/null
+++ b/scripts/geometry/delaunay3.m
@@ -0,0 +1,58 @@
+## Copyright (C) 1999, 2000, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{T} =} delaunay3 (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {@var{T} =} delaunay3 (@var{x}, @var{y}, @var{z}, @var{opt})
+## A matrix of size [n, 4] is returned.  Each row contains a 
+## set of tetrahedron which are
+## described by the indices to the data point vectors (x,y,z).
+##
+## A fourth optional argument, which must be a string or cell array of strings,
+## contains extra options passed to the underlying qhull command.  See the 
+## documentation for the Qhull library for details.
+## @seealso{delaunay,delaunayn}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function tetr = delaunay3 (x, y, z, opt)
+
+  if (nargin != 3 && nargin != 4)
+    print_usage ();
+  endif
+
+  if (isvector (x) && isvector (y) &&isvector (z)
+      && length (x) == length (y) && length(x) == length (z))
+    if (nargin == 3)
+      tetr = delaunayn ([x(:), y(:), z(:)]);
+    elseif (ischar (opt) || iscell (opt))
+      tetr = delaunayn ([x(:), y(:), z(:)], opt);
+    else
+      error ("delaunay3: fourth argument must be a string or cell array of strings");
+    endif
+  else
+    error ("delaunay3: first three input arguments must be vectors of same size");
+  endif
+
+endfunction
+
+%!testif HAVE_QHULL
+%! x = [-1, -1, 1, 0, -1]; y = [-1, 1, 1, 0, -1]; z = [0, 0, 0, 1, 1];
+%! assert (sortrows (sort (delaunay3 (x, y, z), 2)), [1,2,3,4;1,2,4,5])
+
diff --git a/scripts/geometry/delaunayn.m b/scripts/geometry/delaunayn.m
new file mode 100644
index 0000000..0feb9a9
--- /dev/null
+++ b/scripts/geometry/delaunayn.m
@@ -0,0 +1,81 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{T} =} delaunayn (@var{P})
+## @deftypefnx {Function File} {@var{T} =} delaunayn (@var{P}, @var{opt})
+## Form the Delaunay triangulation for a set of points.
+## The Delaunay triangulation is a tessellation of the convex hull of the
+## points such that no n-sphere defined by the n-triangles contains
+## any other points from the set.
+## The input matrix @var{P} of size @code{[n, dim]} contains @var{n}
+## points in a space of dimension dim.  The return matrix @var{T} has the
+## size @code{[m, dim+1]}.  It contains for each row a set of indices to
+## the points, which describes a simplex of dimension dim.  For example,
+## a 2d simplex is a triangle and 3d simplex is a tetrahedron.
+## 
+## Extra options for the underlying Qhull command can be specified by the
+## second argument.  This argument is a cell array of strings.  The default
+## options depend on the dimension of the input: 
+## 
+## @itemize 
+## @item 2D and 3D: @var{opt} = @code{@{"Qt", "Qbb", "Qc"@}}
+## @item 4D and higher: @var{opt} = @code{@{"Qt", "Qbb", "Qc", "Qz"@}} 
+## @end itemize
+## 
+## If @var{opt} is [], then the default arguments are used.  If @var{opt}
+## is @code{@{"@w{}"@}}, then none of the default arguments are used by Qhull. 
+## See the Qhull documentation for the available options. 
+## 
+## All options can also be specified as single string, for example
+## @code{"Qt Qbb Qc Qz"}.
+## 
+## @end deftypefn
+
+function t = delaunayn (x, varargin)
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  t = __delaunayn__ (x, varargin{:});
+
+  if (isa (x, "single"))
+    myeps = eps ("single");
+  else
+    myeps = eps;
+  endif
+
+  ## Try to remove the zero volume simplices. The volume of the i-th simplex is
+  ## given by abs(det(x(t(i,1:end-1),:)-x(t(i,2:end),:)))/prod(1:n) 
+  ## (reference http://en.wikipedia.org/wiki/Simplex). Any simplex with a 
+  ## relative volume less than some arbitrary criteria is rejected. The 
+  ## criteria we use is the volume of the simplex corresponding to an 
+  ## orthogonal simplex is equal edge length all equal to the edge length of 
+  ## the original simplex. If the relative volume is 1e3*eps then the simplex
+  ## is rejected. Note division of the two volumes means that the factor 
+  ## prod(1:n) is dropped.
+  idx = [];
+  [nt, n] = size (t);
+  for i = 1:nt
+    X = x(t(i,1:end-1),:) - x(t(i,2:end),:);
+    if (abs (det (X)) /  sqrt (sum (X .^ 2, 2)) < 1e3 * myeps)
+     idx = [idx, i];
+    endif
+  endfor
+  t(idx,:) = [];
+endfunction
diff --git a/scripts/geometry/dsearch.m b/scripts/geometry/dsearch.m
new file mode 100644
index 0000000..597f6fc
--- /dev/null
+++ b/scripts/geometry/dsearch.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{idx} =} dsearch (@var{x}, @var{y}, @var{tri}, @var{xi}, @var{yi})
+## @deftypefnx {Function File} {@var{idx} =} dsearch (@var{x}, @var{y}, @var{tri}, @var{xi}, @var{yi}, @var{s})
+## Returns the index @var{idx} or the closest point in @code{@var{x}, @var{y}}
+## to the elements @code{[@var{xi}(:), @var{yi}(:)]}.  The variable @var{s} is
+## accepted but ignored for compatibility.
+## @seealso{dsearchn, tsearch}
+## @end deftypefn
+
+function idx = dsearch (x, y, t, xi, yi, s)
+  if (nargin < 5 || nargin > 6)
+    print_usage ();
+  endif
+  idx = __dsearchn__ ([x(:), y(:)], [xi(:), yi(:)]);
+endfunction
+
+%!shared x, y, tri
+%! x = [-1;-1;1];
+%! y = [-1;1;-1];
+%! tri = [1,2,3]; 
+%!assert (dsearch(x,y,tri,1,1/3), 3);
+%!assert (dsearch(x,y,tri,1/3,1), 2);
diff --git a/scripts/geometry/dsearchn.m b/scripts/geometry/dsearchn.m
new file mode 100644
index 0000000..d89ba98
--- /dev/null
+++ b/scripts/geometry/dsearchn.m
@@ -0,0 +1,57 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{idx} =} dsearchn (@var{x}, @var{tri}, @var{xi})
+## @deftypefnx {Function File} {@var{idx} =} dsearchn (@var{x}, @var{tri}, @var{xi}, @var{outval})
+## @deftypefnx {Function File} {@var{idx} =} dsearchn (@var{x}, @var{xi})
+## @deftypefnx {Function File} {[@var{idx}, @var{d}] =} dsearchn (@dots{})
+## Returns the index @var{idx} or the closest point in @var{x} to the elements
+## @var{xi}.  If @var{outval} is supplied, then the values of @var{xi} that are
+## not contained within one of the simplicies @var{tri} are set to 
+## @var{outval}.  Generally, @var{tri} is returned from @code{delaunayn 
+## (@var{x})}.
+## @seealso{dsearch, tsearch}
+## @end deftypefn
+
+function [idx, d] = dsearchn (x, t, xi, outval)
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    [idx, d] = __dsearchn__ (x, t);
+  else
+    [idx, d] = __dsearchn__ (x, xi);
+    if (nargin == 4)
+      idx2 = isnan (tsearchn (x, t, xi));
+      idx(idx2) = outval;
+      d(idx2) = outval;
+    endif
+  endif
+endfunction
+
+%!shared x, tri
+%! x = [-1,-1;-1,1;1,-1]; 
+%! tri = [1,2,3]; 
+%!assert (dsearchn(x,tri,[1,1/3]), 3);
+%!assert (dsearchn(x,tri,[1,1/3],NaN), NaN);
+%!assert (dsearchn(x,tri,[1,1/3],NA), NA);
+%!assert (dsearchn(x,tri,[1/3,1]), 2);
+%!assert (dsearchn(x,tri,[1/3,1],NaN), NaN);
+%!assert (dsearchn(x,tri,[1/3,1],NA), NA);
diff --git a/scripts/geometry/griddata.m b/scripts/geometry/griddata.m
new file mode 100644
index 0000000..5090901
--- /dev/null
+++ b/scripts/geometry/griddata.m
@@ -0,0 +1,164 @@
+## Copyright (C) 1999, 2000, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{zi} =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
+## @deftypefnx {Function File} {[@var{xi}, @var{yi}, @var{zi}] =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
+## 
+## Generate a regular mesh from irregular data using interpolation.
+## The function is defined by @code{@var{z} = f (@var{x}, @var{y})}.
+## The interpolation points are all @code{(@var{xi}, @var{yi})}.  If
+## @var{xi}, @var{yi} are vectors then they are made into a 2D mesh.
+##
+## The interpolation method can be @code{"nearest"}, @code{"cubic"} or
+## @code{"linear"}.  If method is omitted it defaults to @code{"linear"}.
+## @seealso{delaunay}
+## @end deftypefn
+
+## Author:	Kai Habel <kai.habel at gmx.de>
+## Adapted-by:  Alexander Barth <barth.alexander at gmail.com>
+##              xi and yi are not "meshgridded" if both are vectors 
+##              of the same size (for compatibility)
+
+function [rx, ry, rz] = griddata (x, y, z, xi, yi, method)
+	
+  if (nargin == 5)
+    method = "linear";
+  endif
+  if (nargin < 5 || nargin > 7) 
+    print_usage ();
+  endif
+
+  if (ischar (method))
+    method = tolower (method);
+  endif
+  if (! all (size (x) == size (y) & size (x) == size (z)))
+    error ("griddata: x, y, and z must be vectors of same length");
+  endif
+  
+  ## Meshgrid xi and yi if they are vectors unless they
+  ## are vectors of the same length.
+  if (isvector (xi) && isvector (yi) && numel (xi) != numel (yi))
+    [xi, yi] = meshgrid (xi, yi);
+  endif
+
+  if (any (size (xi) != size (yi)))
+    error ("griddata: xi and yi must be vectors or matrices of same size");
+  endif
+
+  [nr, nc] = size (xi);
+  
+  x = x(:); y = y(:); z = z(:);
+
+  ## Triangulate data.
+  tri = delaunay (x, y);
+  zi = nan (size (xi));
+  
+  if (strcmp (method, "cubic"))
+    error ("griddata: cubic interpolation not yet implemented");
+
+  elseif (strcmp (method, "nearest"))
+    ## Search index of nearest point.
+    idx = dsearch (x, y, tri, xi, yi);
+    valid = !isnan (idx);
+    zi(valid) = z(idx(valid));
+
+  elseif (strcmp (method, "linear"))
+    ## Search for every point the enclosing triangle.
+    tri_list = tsearch (x, y, tri, xi(:), yi(:));
+
+    ## Only keep the points within triangles.
+    valid = !isnan (reshape (tri_list, size (xi)));
+    tri_list = tri_list(!isnan (tri_list));
+    nr_t = rows (tri_list);
+
+    ## Assign x,y,z for each point of triangle.
+    x1 = x(tri(tri_list,1));
+    x2 = x(tri(tri_list,2));
+    x3 = x(tri(tri_list,3));
+
+    y1 = y(tri(tri_list,1));
+    y2 = y(tri(tri_list,2));
+    y3 = y(tri(tri_list,3));
+
+    z1 = z(tri(tri_list,1));
+    z2 = z(tri(tri_list,2));
+    z3 = z(tri(tri_list,3));
+
+    ## Calculate norm vector.
+    N = cross ([x2-x1, y2-y1, z2-z1], [x3-x1, y3-y1, z3-z1]);
+    N_norm = sqrt (sumsq (N, 2));
+    N = N ./ N_norm(:,[1,1,1]);
+    
+    ## Calculate D of plane equation
+    ## Ax+By+Cz+D = 0;
+    D = -(N(:,1) .* x1 + N(:,2) .* y1 + N(:,3) .* z1);
+    
+    ## Calculate zi by solving plane equation for xi, yi.
+    zi(valid) = -(N(:,1).*xi(valid) + N(:,2).*yi(valid) + D) ./ N(:,3);
+    
+  else
+    error ("griddata: unknown interpolation method");
+  endif
+
+  if (nargout == 3)
+    rx = xi;
+    ry = yi;
+    rz = zi;
+  elseif (nargout == 1)
+    rx = zi;
+  elseif (nargout == 0)
+    mesh (xi, yi, zi);
+  endif
+endfunction
+
+%!testif HAVE_QHULL
+%! [xx,yy]=meshgrid(linspace(-1,1,32));
+%! x = xx(:);
+%! x = x + 10 * (2 * round(rand(size(x))) - 1) * eps;
+%! y = yy(:);
+%! y = y + 10 * (2 * round(rand(size(y))) - 1) * eps;
+%! z = sin(2*(x.^2+y.^2));
+%! zz = griddata(x,y,z,xx,yy,'linear');
+%! zz2 = sin(2*(xx.^2+yy.^2));
+%! zz2(isnan(zz)) = NaN;
+%! assert (zz, zz2, 100 * eps)
+
+%!demo
+%! x=2*rand(100,1)-1;
+%! y=2*rand(size(x))-1;
+%! z=sin(2*(x.^2+y.^2));
+%! [xx,yy]=meshgrid(linspace(-1,1,32));
+%! griddata(x,y,z,xx,yy);
+%! title('nonuniform grid sampled at 100 points');
+
+%!demo
+%! x=2*rand(1000,1)-1;
+%! y=2*rand(size(x))-1;
+%! z=sin(2*(x.^2+y.^2));
+%! [xx,yy]=meshgrid(linspace(-1,1,32));
+%! griddata(x,y,z,xx,yy);
+%! title('nonuniform grid sampled at 1000 points');
+
+%!demo
+%! x=2*rand(1000,1)-1;
+%! y=2*rand(size(x))-1;
+%! z=sin(2*(x.^2+y.^2));
+%! [xx,yy]=meshgrid(linspace(-1,1,32));
+%! griddata(x,y,z,xx,yy,'nearest');
+%! title('nonuniform grid sampled at 1000 points with nearest neighbor');
diff --git a/scripts/geometry/griddata3.m b/scripts/geometry/griddata3.m
new file mode 100644
index 0000000..6ee69e0
--- /dev/null
+++ b/scripts/geometry/griddata3.m
@@ -0,0 +1,80 @@
+## Copyright (C) 2007, 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{vi} =} griddata3 (@var{x}, @var{y}, @var{z}, @var{v} @var{xi}, @var{yi}, @var{zi}, @var{method}, @var{options})
+## 
+## Generate a regular mesh from irregular data using interpolation.
+## The function is defined by @code{@var{y} = f (@var{x}, at var{y}, at var{z})}.
+## The interpolation points are all @var{xi}.  
+##
+## The interpolation method can be @code{"nearest"} or @code{"linear"}.
+## If method is omitted it defaults to @code{"linear"}.
+## @seealso{griddata, delaunayn}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function vi = griddata3 (x, y, z, v, xi, yi, zi, method, varargin)
+	
+  if (nargin < 7)
+    print_usage ();
+  endif
+
+  if (!all (size (x) == size (y) & size (x) == size(z) & size(x) == size (v)))
+    error ("griddata3: x, y, z, and v must be vectors of same length");
+  endif
+
+  ## meshgrid xi, yi and zi if they are vectors unless they
+  ## are vectors of the same length 
+  if (isvector (xi) && isvector (yi) && isvector (zi)
+      && (numel (xi) != numel (yi) || numel (xi) != numel (zi)))
+    [xi, yi, zi] = meshgrid (xi, yi, zi);
+  endif
+
+  if (any (size(xi) != size(yi)) || any (size(xi) != size(zi)))
+    error ("griddata3: xi, yi and zi must be vectors or matrices of same size");
+  endif
+
+  vi = griddatan ([x(:), y(:), z(:)], v(:), [xi(:), yi(:), zi(:)], varargin{:});
+  vi = reshape (vi, size (xi));
+endfunction
+
+%!testif HAVE_QHULL
+%! rand('state', 0);
+%! x = 2 * rand(1000, 1) - 1;
+%! y = 2 * rand(1000, 1) - 1;
+%! z = 2 * rand(1000, 1) - 1;
+%! v = x.^2 + y.^2 + z.^2;
+%! [xi, yi, zi] = meshgrid (-0.8:0.2:0.8);
+%! ##vi = reshape (griddatan([x(:), y(:), z(:)], v, [xi(:), yi(:), zi(:)], 'linear'), size (xi));
+%! vi = griddata3 (x, y, z, v, xi, yi, zi, 'linear');
+%! vv = vi - xi.^2 - yi.^2 - zi.^2;
+%! assert (max(abs(vv(:))), 0, 0.1)
+
+%!testif HAVE_QHULL
+%! rand('state', 0);
+%! x = 2 * rand(1000, 1) - 1;
+%! y = 2 * rand(1000, 1) - 1;
+%! z = 2 * rand(1000, 1) - 1;
+%! v = x.^2 + y.^2 + z.^2;
+%! [xi, yi, zi] = meshgrid (-0.8:0.2:0.8);
+%! ##vi = reshape (griddatan([x(:), y(:), z(:)], v, [xi(:), yi(:), zi(:)], 'linear'), size (xi));
+%! vi = griddata3 (x, y, z, v, xi, yi, zi, 'nearest');
+%! vv = vi - xi.^2 - yi.^2 - zi.^2;
+%! assert (max(abs(vv(:))), 0, 0.1)
diff --git a/scripts/geometry/griddatan.m b/scripts/geometry/griddatan.m
new file mode 100644
index 0000000..9d253f8
--- /dev/null
+++ b/scripts/geometry/griddatan.m
@@ -0,0 +1,106 @@
+## Copyright (C) 2007, 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{yi} =} griddatan (@var{x}, @var{y}, @var{xi}, @var{method}, @var{options})
+## 
+## Generate a regular mesh from irregular data using interpolation.
+## The function is defined by @code{@var{y} = f (@var{x})}.
+## The interpolation points are all @var{xi}.  
+##
+## The interpolation method can be @code{"nearest"} or @code{"linear"}.
+## If method is omitted it defaults to @code{"linear"}.
+## @seealso{griddata, delaunayn}
+## @end deftypefn
+
+## Author: David Bateman <dbateman at free.fr>
+
+function yi = griddatan (x, y, xi, method, varargin)
+
+  if (nargin == 3)
+    method = "linear";
+  endif
+  if (nargin < 3) 
+    print_usage ();
+  endif
+
+  if (ischar (method))
+    method = tolower (method);
+  endif
+
+  [m, n] = size (x);
+  [mi, ni] = size (xi);
+  
+  if (n != ni || size (y, 1) != m || size (y, 2) != 1)
+    error ("griddatan: dimensional mismatch");
+  endif
+
+  ## triangulate data
+  ## tri = delaunayn(x, varargin{:});
+  tri = delaunayn (x);
+
+  yi = nan (mi, 1);
+  
+  if (strcmp (method, "nearest"))
+    ## search index of nearest point
+    idx = dsearchn (x, tri, xi);
+    valid = !isnan (idx);
+    yi(valid) = y(idx(valid));
+
+  elseif (strcmp (method, "linear"))
+    ## search for every point the enclosing triangle
+    [tri_list, bary_list] = tsearchn (x, tri, xi);
+
+    ## only keep the points within triangles.
+    valid = !isnan (tri_list);
+    tri_list = tri_list(!isnan (tri_list));
+    bary_list = bary_list(!isnan (tri_list), :);
+    nr_t = rows (tri_list);
+
+    ## assign x,y for each point of simplex
+    xt =  reshape (x(tri(tri_list,:),:), [nr_t, n+1, n]);
+    yt = y(tri(tri_list,:));
+
+    ## Use barycentric coordinate of point to calculate yi
+    yi(valid) = sum (y(tri(tri_list,:)) .* bary_list, 2);
+
+  else
+    error ("griddatan: unknown interpolation method");
+  endif
+
+endfunction
+
+%!testif HAVE_QHULL
+%! [xx,yy] = meshgrid(linspace(-1,1,32));
+%! xi = [xx(:), yy(:)];
+%! x = (2 * rand(100,2) - 1);
+%! x = [x;1,1;1,-1;-1,-1;-1,1];
+%! y = sin(2*(sum(x.^2,2)));
+%! zz = griddatan(x,y,xi,'linear');
+%! zz2 = griddata(x(:,1),x(:,2),y,xi(:,1),xi(:,2),'linear');
+%! assert (zz, zz2, 1e-10)
+
+%!testif HAVE_QHULL
+%! [xx,yy] = meshgrid(linspace(-1,1,32));
+%! xi = [xx(:), yy(:)];
+%! x = (2 * rand(100,2) - 1);
+%! x = [x;1,1;1,-1;-1,-1;-1,1];
+%! y = sin(2*(sum(x.^2,2)));
+%! zz = griddatan(x,y,xi,'nearest');
+%! zz2 = griddata(x(:,1),x(:,2),y,xi(:,1),xi(:,2),'nearest');
+%! assert (zz, zz2, 1e-10)
diff --git a/scripts/geometry/inpolygon.m b/scripts/geometry/inpolygon.m
new file mode 100644
index 0000000..aa1f4c5
--- /dev/null
+++ b/scripts/geometry/inpolygon.m
@@ -0,0 +1,132 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Frederick (Rick) A Niles
+##               and S�ren Hauberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{in}, @var{on}] =} inpolygon (@var{x}, @var{y}, @var{xv}, @var{xy})
+##
+## For a polygon defined by @code{(@var{xv}, @var{yv})} points, determine
+## if the points @code{(@var{x}, @var{y})} are inside or outside the polygon.
+## The variables @var{x}, @var{y}, must have the same dimension.  The optional
+## output @var{on} gives the points that are on the polygon.
+##
+## @end deftypefn
+
+## Author: Frederick (Rick) A Niles <niles at rickniles.com>
+## Created: 14 November 2006
+
+## Vectorized by S�ren Hauberg <soren at hauberg.org>
+
+## The method for determining if a point is in in a polygon is based on
+## the algorithm shown on
+## http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ and is
+## credited to Randolph Franklin.
+
+function [IN, ON] = inpolygon (X, Y, xv, yv)
+
+  if (nargin != 4)
+    print_usage ();
+  endif
+
+  if (! (isreal (X) && isreal (Y) && ismatrix (Y) && ismatrix (Y)
+	 && size_equal (X, Y)))
+    error ("inpolygon: first two arguments must be real matrices of same size");
+  elseif (! (isreal (xv) && isreal (yv) && isvector (xv) && isvector (yv)
+	     && size_equal (xv, yv)))
+    error ("inpolygon: last two arguments must be real vectors of same size");
+  endif
+
+  npol = length (xv);
+  do_boundary = (nargout >= 2);
+  
+  IN = zeros (size(X), "logical");
+  if (do_boundary) 
+    ON = zeros (size(X), "logical"); 
+  endif
+  
+  j = npol;
+  for i = 1 : npol
+    delta_xv = xv(j) - xv(i);
+    delta_yv = yv(j) - yv(i);
+    ## distance = [distance from (X,Y) to edge] * length(edge)
+    distance = delta_xv .* (Y - yv(i)) - (X - xv(i)) .* delta_yv;
+    ##
+    ## is Y between the y-values of edge i,j
+    ##        AND (X,Y) on the left of the edge ?
+    idx1 = (((yv(i) <= Y & Y < yv(j)) | (yv(j) <= Y & Y < yv(i)))
+	    & 0 < distance.*delta_yv);
+    IN (idx1) = !IN (idx1);
+
+    ## Check if (X,Y) are actually ON the boundary of the polygon.
+    if (do_boundary)
+       idx2 = (((yv(i) <= Y & Y <= yv(j)) | (yv(j) <= Y & Y <= yv(i)))
+	       & ((xv(i) <= X & X <= xv(j)) | (xv(j) <= X & X <= xv(i)))
+	       & (0 == distance | !delta_xv));
+       ON (idx2) = true;
+    endif
+    j = i;
+  endfor
+
+endfunction
+
+%!demo
+%!  xv=[ 0.05840, 0.48375, 0.69356, 1.47478, 1.32158, \
+%!       1.94545, 2.16477, 1.87639, 1.18218, 0.27615, \
+%!       0.05840 ];
+%!  yv=[ 0.60628, 0.04728, 0.50000, 0.50000, 0.02015, \
+%!       0.18161, 0.78850, 1.13589, 1.33781, 1.04650, \
+%!       0.60628 ];
+%! xa=[0:0.1:2.3];
+%! ya=[0:0.1:1.4];
+%! [x,y]=meshgrid(xa,ya);
+%! [IN,ON]=inpolygon(x,y,xv,yv);
+%! 
+%! inside=IN & !ON;
+%! plot(xv,yv)
+%! hold on
+%! plot(x(inside),y(inside),"@g")
+%! plot(x(~IN),y(~IN),"@m")
+%! plot(x(ON),y(ON),"@b")
+%! hold off
+%! disp("Green points are inside polygon, magenta are outside,");
+%! disp("and blue are on boundary.");
+
+%!demo
+%!  xv=[ 0.05840, 0.48375, 0.69356, 1.47478, 1.32158, \
+%!       1.94545, 2.16477, 1.87639, 1.18218, 0.27615, \
+%!       0.05840, 0.73295, 1.28913, 1.74221, 1.16023, \
+%!       0.73295, 0.05840 ];
+%!  yv=[ 0.60628, 0.04728, 0.50000, 0.50000, 0.02015, \
+%!       0.18161, 0.78850, 1.13589, 1.33781, 1.04650, \
+%!       0.60628, 0.82096, 0.67155, 0.96114, 1.14833, \
+%!       0.82096, 0.60628];
+%! xa=[0:0.1:2.3];
+%! ya=[0:0.1:1.4];
+%! [x,y]=meshgrid(xa,ya);
+%! [IN,ON]=inpolygon(x,y,xv,yv);
+%! 
+%! inside=IN & ~ ON;
+%! plot(xv,yv)
+%! hold on
+%! plot(x(inside),y(inside),"@g")
+%! plot(x(~IN),y(~IN),"@m")
+%! plot(x(ON),y(ON),"@b")
+%! hold off
+%! disp("Green points are inside polygon, magenta are outside,");
+%! disp("and blue are on boundary.");
+
diff --git a/scripts/geometry/rectint.m b/scripts/geometry/rectint.m
new file mode 100644
index 0000000..f2cb222
--- /dev/null
+++ b/scripts/geometry/rectint.m
@@ -0,0 +1,131 @@
+## Copyright (C) 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{area} =} rectint (@var{a}, @var{b})
+##
+## Compute the area of intersection of rectangles in @var{a} and
+## rectangles in @var{b}.  Rectangles are defined as [x y width height]
+## where x and y are the minimum values of the two orthogonal
+## dimensions.
+##
+## If @var{a} or @var{b} are matrices, then the output, @var{area}, is a
+## matrix where the i-th row corresponds to the i-th row of a and the j-th
+## column corresponds to the j-th row of b.
+##
+## @seealso{polyarea}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function area = rectint (a, b)
+	
+  if (nargin != 2)
+    print_usage ();
+  elseif (ndims (a) != 2 || ndims (b) != 2)
+    error ("rectint: expecting arguments to be 2-d arrays");
+  elseif (columns (a) != 4)
+    error ("rectint: a must have 4 columns");
+  elseif (columns (b) != 4)
+    error ("rectint: b must have 4 columns");
+  elseif any ([a(:,3:4);b(:,3:4)](:) < 0)
+    error ("rectint: all widths and heights must be > 0");
+  endif
+
+  ## This runs faster if the number of rows of a is greater than the
+  ## number of rows of b.  Swap them and transpose to make it run
+  ## faster.
+  swapinputs = false ();
+  if (rows (a) > rows (b))
+    tmp = a;
+    a = b;
+    b = tmp;
+    swapinputs = true ();
+  endif
+
+  area = zeros (rows (a), rows (b));
+  r1 = [a(:,1:2) a(:,1:2)+a(:,3:4)];
+  r2 = [b(:,1:2) b(:,1:2)+b(:,3:4)];
+  for i = 1:columns (area)
+    ## Find the location of each point relative to the other points.
+    r1x1small = r1(:,1) < r2(i,1);
+    r1x1large = r1(:,1) > r2(i,3);
+    r1x1mid = (r1(:,1) >= r2(i,1)) & (r1(:,1) <= r2(i,3));
+    r1x2small = r1(:,3) < r2(i,1);
+    r1x2large = r1(:,3) > r2(i,3);
+    r1x2mid = (r1(:,3) >= r2(i,1)) & (r1(:,3) <= r2(i,3));
+
+    r1y1small = r1(:,2) < r2(i,2);
+    r1y1large = r1(:,2) > r2(i,4);
+    r1y1mid = (r1(:,2) >= r2(i,2)) & (r1(:,2) <= r2(i,4));
+    r1y2small = r1(:,4) < r2(i,2);
+    r1y2large = r1(:,4) > r2(i,4);
+    r1y2mid = (r1(:,4) >= r2(i,2)) & (r1(:,4) <= r2(i,4));
+
+    ## determine the width of the rectangle
+    ## r1 completely encloses r2
+    area(r1x1small & r1x2large,i) = r2(i,3) - r2(i,1);
+    ## the range goes from r2x min to r1x max
+    mask = r1x1small & r1x2mid;
+    area(mask,i) = r1(mask,3) - r2(i,1);
+    ## the range goes from r1x min to r2x max
+    mask = r1x1mid & r1x2large;
+    area(mask,i) = r2(i,3) - r1(mask,1);
+    ## the range goes from r1x min to r1x max
+    mask = r1x1mid & r1x2mid;
+    area(mask,i) = r1(mask,3) - r1(mask,1);
+
+    ## determine the height of the rectangle
+    ## r1 completely encloses r2
+    area(r1y1small & r1y2large,i) .*= r2(i,4) - r2(i,2);
+    ## the range goes from r2y min to r1y max
+    mask = r1y1small & r1y2mid;
+    area(mask,i) .*= r1(mask,4) - r2(i,2);
+    ## the range goes from r1y min to r2y max
+    mask = r1y1mid & r1y2large;
+    area(mask,i) .*= r2(i,4) - r1(mask,2);
+    ## the range goes from r1x min to r1x max
+    mask = r1y1mid & r1y2mid;
+    area(mask,i) .*= r1(mask,4) - r1(mask,2);
+
+  endfor
+
+  if swapinputs
+    area = area';
+  endif
+
+endfunction
+
+## Tests
+## Exactly overlapping
+%!assert(rectint([0 0 1 1], [0 0 1 1]), 1)
+## rect2 completely enclosed by rect1
+%!assert(rectint([-1 -1 3 3], [0 0 1 1]), 1)
+## rect1 completely enclosed by rect2
+%!assert(rectint([0 0 1 1], [-1 -1 3 3]), 1)
+## rect1 right and top in rect2
+%!assert(rectint([-1 -1 1.5 1.5], [0 0 1 1]), 0.25)
+## rect2 right and top in rect1
+%!assert(rectint([0 0 1 1], [-1 -1 1.5 1.5]), 0.25)
+## no overlap - shared corner
+%!assert(rectint([0 0 1 1], [1 1 2 2]), 0)
+## no overlap - shared edge
+%!assert(rectint([0 0 1 1], [0 1 2 2]), 0)
+## Correct orientation of output
+%!assert(rectint([0 0 1 1;0.5 0.5 1 1;-1 -1 2 2], [1 1 2 2]), [0;0.25;0])
+%!assert(rectint([1 1 2 2], [0 0 1 1;0.5 0.5 1 1;-1 -1 2 2]), [0 0.25 0])
diff --git a/scripts/geometry/trimesh.m b/scripts/geometry/trimesh.m
new file mode 100644
index 0000000..e74851a
--- /dev/null
+++ b/scripts/geometry/trimesh.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} trimesh (@var{tri}, @var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {@var{h} =} trimesh (@dots{})
+## Plot a triangular mesh in 3D.  The variable @var{tri} is the triangular
+## meshing of the points @code{(@var{x}, @var{y})} which is returned 
+## from @code{delaunay}.  The variable @var{z} is value at the point 
+## @code{(@var{x}, @var{y})}.  The output argument @var{h} is the graphic 
+## handle to the plot.
+## @seealso{triplot, delaunay3}
+## @end deftypefn
+
+function h = trimesh (tri, x, y, z, varargin)
+
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3)
+    triplot (tri, x, y);
+  elseif (ischar (z))
+    triplot (tri, x, y, z, varargin{:});
+  else
+    newplot ();
+    if (nargout > 0)
+      h = patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri, 
+		 "FaceColor", "none", "EdgeColor", __next_line_color__(), 
+		 varargin{:});
+    else
+      patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri, 
+	     "FaceColor", "none", "EdgeColor", __next_line_color__(), 
+	     varargin{:});
+    endif
+
+    if (! ishold ())
+      set (gca(), "view", [-37.5, 30],
+	   "xgrid", "on", "ygrid", "on", "zgrid", "on");
+    endif
+  endif
+endfunction
+
+%!demo
+%! N = 10;
+%! rand ('state', 10)
+%! x = 3 - 6 * rand (N, N);
+%! y = 3 - 6 * rand (N, N);
+%! z = peaks (x, y);
+%! tri = delaunay (x(:), y(:));
+%! trimesh (tri, x(:), y(:), z(:));
diff --git a/scripts/geometry/triplot.m b/scripts/geometry/triplot.m
new file mode 100644
index 0000000..f5fe8c2
--- /dev/null
+++ b/scripts/geometry/triplot.m
@@ -0,0 +1,53 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} triplot (@var{tri}, @var{x}, @var{y})
+## @deftypefnx {Function File} {} triplot (@var{tri}, @var{x}, @var{y}, @var{linespec})
+## @deftypefnx {Function File} {@var{h} =} triplot (@dots{})
+## Plot a triangular mesh in 2D.  The variable @var{tri} is the triangular
+## meshing of the points @code{(@var{x}, @var{y})} which is returned from
+## @code{delaunay}.  If given, the @var{linespec} determines the properties
+## to use for the lines.  The output argument @var{h} is the graphic handle
+## to the plot.
+## @seealso{plot, trimesh, delaunay}
+## @end deftypefn
+
+function h = triplot (tri, x, y, varargin)
+
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  idx = tri(:, [1, 2, 3, 1]).';
+  nt = size (tri, 1);
+  if (nargout > 0)
+    h = plot ([x(idx); NaN*ones(1, nt)](:),
+	      [y(idx); NaN*ones(1, nt)](:), varargin{:});
+  else
+    plot ([x(idx); NaN*ones(1, nt)](:),
+	  [y(idx); NaN*ones(1, nt)](:), varargin{:});
+  endif
+endfunction
+
+%!demo
+%! rand ('state', 2)
+%! x = rand (20, 1);
+%! y = rand (20, 1);
+%! tri = delaunay (x, y);
+%! triplot (tri, x, y);
diff --git a/scripts/geometry/trisurf.m b/scripts/geometry/trisurf.m
new file mode 100644
index 0000000..c368d92
--- /dev/null
+++ b/scripts/geometry/trisurf.m
@@ -0,0 +1,75 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} trisurf (@var{tri}, @var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {@var{h} =} trisurf (@dots{})
+## Plot a triangular surface in 3D.  The variable @var{tri} is the triangular
+## meshing of the points @code{(@var{x}, @var{y})} which is returned 
+## from @code{delaunay}.  The variable @var{z} is value at the point 
+## @code{(@var{x}, @var{y})}.  The output argument @var{h} is the graphic 
+## handle to the plot.
+## @seealso{triplot, delaunay3}
+## @end deftypefn
+
+function h = trisurf (tri, x, y, z, varargin)
+
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3)
+    triplot (tri, x, y);
+  elseif (ischar (z))
+    triplot (tri, x, y, z, varargin{:});
+  else
+    if (nargin > 4 && isnumeric (varargin{1}))
+      c = varargin{1};
+      varargin(1) = [];
+    else
+      c = z;
+    endif
+
+    newplot ();
+    if (nargout > 0)
+      h = patch ("Faces", tri, "Vertices", [x(:), y(:), z(:)],  
+	     "FaceVertexCData", reshape (c, numel (c), 1), 
+	     "FaceColor", "flat", "EdgeColor", "none",
+	     varargin{:});
+    else
+      patch ("Faces", tri, "Vertices", [x(:), y(:), z(:)],  
+	     "FaceVertexCData", reshape (c, numel (c), 1), 
+	     "FaceColor", "flat", "EdgeColor", "none",
+	     varargin{:});
+    endif
+
+    if (! ishold ())
+      set (gca(), "view", [-37.5, 30],
+	   "xgrid", "on", "ygrid", "on", "zgrid", "on");
+    endif
+  endif
+endfunction
+
+%!demo
+%! N = 10;
+%! rand ('state', 10)
+%! x = 3 - 6 * rand (N, N);
+%! y = 3 - 6 * rand (N, N);
+%! z = peaks (x, y);
+%! tri = delaunay (x(:), y(:));
+%! trisurf (tri, x(:), y(:), z(:));
diff --git a/scripts/geometry/tsearchn.m b/scripts/geometry/tsearchn.m
new file mode 100644
index 0000000..f41c557
--- /dev/null
+++ b/scripts/geometry/tsearchn.m
@@ -0,0 +1,107 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{idx}, @var{p}] =} tsearchn (@var{x}, @var{t}, @var{xi})
+## Searches for the enclosing Delaunay convex hull.  For @code{@var{t} =
+## delaunayn (@var{x})}, finds the index in @var{t} containing the
+## points @var{xi}.  For points outside the convex hull, @var{idx} is NaN.
+## If requested @code{tsearchn} also returns the Barycentric coordinates @var{p}
+## of the enclosing triangles.
+## @seealso{delaunay, delaunayn}
+## @end deftypefn
+
+function [idx, p] = tsearchn (x, t, xi)
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  nt = size (t, 1);
+  [m, n] = size (x);
+  mi = size (xi, 1);
+  idx = nan (mi, 1);
+  p = nan (mi, n + 1);
+
+  ni = [1:mi].';
+  for i = 1 : nt
+    ## Only calculate the Barycentric coordinates for points that have not
+    ## already been found in a triangle.
+    b = cart2bary (x (t (i, :), :), xi(ni,:));
+
+    ## Our points xi are in the current triangle if
+    ## (all(b >= 0) && all (b <= 1)). However as we impose that 
+    ## sum(b,2) == 1 we only need to test all(b>=0). Note need to add
+    ## a small margin for rounding errors
+    intri = all (b >= -1e-12, 2);
+    idx(ni(intri)) = i;
+    p(ni(intri),:) = b(intri, :);
+    ni(intri) = [];
+  endfor
+endfunction
+
+function Beta = cart2bary (T, P)
+  ## Conversion of Cartesian to Barycentric coordinates.
+  ## Given a reference simplex in N dimensions represented by a
+  ## (N+1)-by-(N) matrix, and arbitrary point P in cartesion coordinates,
+  ## represented by a N-by-1 row vector can be written as
+  ##
+  ## P = Beta * T
+  ##
+  ## Where Beta is a N+1 vector of the barycentric coordinates. A criteria
+  ## on Beta is that
+  ##
+  ## sum (Beta) == 1
+  ##
+  ## and therefore we can write the above as
+  ##
+  ## P - T(end, :) = Beta(1:end-1) * (T(1:end-1,:) - ones(N,1) * T(end,:))
+  ##
+  ## and then we can solve for Beta as
+  ##
+  ## Beta(1:end-1) = (P - T(end,:)) / (T(1:end-1,:) - ones(N,1) * T(end,:))
+  ## Beta(end) = sum(Beta)
+  ##
+  ## Note below is generalize for multiple values of P, one per row.
+  [M, N] = size (P);
+  Beta = (P - ones (M,1) * T(end,:)) / (T(1:end-1,:) - ones(N,1) * T(end,:));
+  Beta (:,end+1) = 1 - sum(Beta, 2);
+endfunction
+
+%!shared x, tri
+%! x = [-1,-1;-1,1;1,-1];
+%! tri = [1, 2, 3];
+%!test
+%! [idx, p] = tsearchn (x,tri,[-1,-1]);
+%! assert (idx, 1)
+%! assert (p, [1,0,0], 1e-12)
+%!test
+%! [idx, p] = tsearchn (x,tri,[-1,1]);
+%! assert (idx, 1)
+%! assert (p, [0,1,0], 1e-12)
+%!test
+%! [idx, p] = tsearchn (x,tri,[1,-1]);
+%! assert (idx, 1)
+%! assert (p, [0,0,1], 1e-12)
+%!test
+%! [idx, p] = tsearchn (x,tri,[-1/3,-1/3]);
+%! assert (idx, 1)
+%! assert (p, [1/3,1/3,1/3], 1e-12)
+%!test
+%! [idx, p] = tsearchn (x,tri,[1,1]);
+%! assert (idx, NaN)
+%! assert (p, [NaN, NaN, NaN])
diff --git a/scripts/geometry/voronoi.m b/scripts/geometry/voronoi.m
new file mode 100644
index 0000000..77de61a
--- /dev/null
+++ b/scripts/geometry/voronoi.m
@@ -0,0 +1,167 @@
+## Copyright (C) 2000, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} voronoi (@var{x}, @var{y})
+## @deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle")
+## @deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle", @var{options})
+## @deftypefnx {Function File} {[@var{vx}, @var{vy}] =} voronoi (@dots{})
+## plots voronoi diagram of points @code{(@var{x}, @var{y})}.
+## The voronoi facets with points at infinity are not drawn.
+## [@var{vx}, @var{vy}] = voronoi(@dots{}) returns the vertices instead of plotting the
+## diagram. plot (@var{vx}, @var{vy}) shows the voronoi diagram.
+##
+## A fourth optional argument, which must be a string, contains extra options
+## passed to the underlying qhull command.  See the documentation for the
+## Qhull library for details.
+##
+## @example
+## @group
+##   x = rand (10, 1);
+##   y = rand (size (x));
+##   h = convhull (x, y);
+##   [vx, vy] = voronoi (x, y);
+##   plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g")
+##   legend ("", "points", "hull");
+## @end group
+## @end example
+##
+## @seealso{voronoin, delaunay, convhull}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## First Release: 20/08/2000
+
+## 2002-01-04 Paul Kienzle <pkienzle at users.sf.net>
+## * limit the default graph to the input points rather than the whole diagram
+## * provide example
+## * use unique(x,"rows") rather than __unique_rows__
+
+## 2003-12-14 Rafael Laboissiere <rafael at laboissiere.net>
+## Added optional fourth argument to pass options to the underlying
+## qhull command
+
+function [vvx, vvy] = voronoi (varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  narg = 1;
+  if (isscalar (varargin{1}) && ishandle (varargin{1}))
+    handl = varargin{1};
+    narg++;
+    if (! strcmp (get (handl, "type"), "axes"))
+      error ("voronoi: expecting first argument to be an axes object");
+    endif
+  else
+    if (nargout < 2)    
+      handl = gca ();
+    endif
+  endif
+
+  if (nargin < 1 + narg || nargin > 3 + narg)
+    print_usage ();
+  endif
+
+  x = varargin{narg++};
+  y = varargin{narg++};
+  
+  opts = {};
+  if (narg <= nargin) 
+    if (iscell (varargin{narg}))
+      opts = varargin(narg++);
+    elseif (ismatrix (varargin{narg}))
+      ## Accept but ignore the triangulation
+      narg++;
+    endif
+  endif
+
+  linespec = {"b"};
+  if (narg <= nargin) 
+    if (ischar (varargin{narg}))
+      linespec = varargin(narg);
+    endif
+  endif
+
+  lx = length (x);
+  ly = length (y);
+
+  if (lx != ly)
+    error ("voronoi: arguments must be vectors of same length");
+  endif
+
+  ## Add box to approximate rays to infinity. For Voronoi diagrams the
+  ## box can (and should) be close to the points themselves. To make the
+  ## job of finding the exterior edges it should be at least two times the
+  ## delta below however
+  xmax = max (x(:));
+  xmin = min (x(:));
+  ymax = max (y(:));
+  ymin = min (y(:));
+  xdelta = xmax - xmin;
+  ydelta = ymax - ymin;
+  scale = 2;
+
+  xbox = [xmin - scale * xdelta; xmin - scale * xdelta; ...
+	  xmax + scale * xdelta; xmax + scale * xdelta];
+  ybox = [xmin - scale * xdelta; xmax + scale * xdelta; ...
+	  xmax + scale * xdelta; xmin - scale * xdelta];
+
+  [p, c, infi] = __voronoi__ ([[x(:) ; xbox(:)], [y(:); ybox(:)]], opts{:});
+
+  idx = find (!infi);
+  ll = length (idx);
+  c = c(idx).';
+  k = sum (cellfun ('length', c));
+  edges = cell2mat(cellfun (@(x) [x ; [x(end), x(1:end-1)]], c, 
+			    "UniformOutput", false));
+
+  ## Identify the unique edges of the Voronoi diagram
+  edges = sortrows (sort (edges).').';
+  edges = edges (:, [(edges(1, 1: end - 1) != edges(1, 2 : end) | ...
+		      edges(2, 1 :end - 1) != edges(2, 2 : end)), true]);
+
+  ## Eliminate the edges of the diagram representing the box
+  poutside = (1 : rows(p)) ...
+      (p (:, 1) < xmin - xdelta | p (:, 1) > xmax + xdelta | ...
+       p (:, 2) < ymin - ydelta | p (:, 2) > ymax + ydelta);
+  edgeoutside = ismember (edges (1, :), poutside) & ...
+      ismember (edges (2, :), poutside);
+  edges (:, edgeoutside) = [];
+
+  ## Get points of the diagram
+  vx = reshape (p (edges, 1), size(edges));
+  vy = reshape (p (edges, 2), size(edges));
+
+  if (nargout < 2)    
+    lim = [xmin, xmax, ymin, ymax];
+    h = plot (handl, vx, vy, linespec{:}, x, y, '+');
+    axis (lim + 0.1 * [[-1, 1] * (lim (2) - lim (1)), ...
+		       [-1, 1] * (lim (4) - lim (3))]);
+    if (nargout == 1)
+      vxx = h;
+    endif
+  elseif (nargout == 2)
+    vvx = vx;
+    vvy = vy;
+  else
+    error ("voronoi: only two or zero output arguments supported");
+  endif
+
+endfunction
diff --git a/scripts/geometry/voronoin.m b/scripts/geometry/voronoin.m
new file mode 100644
index 0000000..e6233cd
--- /dev/null
+++ b/scripts/geometry/voronoin.m
@@ -0,0 +1,59 @@
+## Copyright (C) 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{C}, @var{F}] =} voronoin (@var{pts})
+## @deftypefnx {Function File} {[@var{C}, @var{F}] =} voronoin (@var{pts}, @var{options})
+## computes n- dimensional voronoi facets.  The input matrix @var{pts}
+## of size [n, dim] contains n points of dimension dim.
+## @var{C} contains the points of the voronoi facets.  The list @var{F}
+## contains for each facet the indices of the voronoi points.
+##
+## A second optional argument, which must be a string, contains extra options
+## passed to the underlying qhull command.  See the documentation for the
+## Qhull library for details.
+## @seealso{voronoin, delaunay, convhull}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## First Release: 20/08/2000
+
+## 2003-12-14 Rafael Laboissiere <rafael at laboissiere.net>
+## Added optional second argument to pass options to the underlying
+## qhull command
+
+function [C, F] = voronoin (pts, opt)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  [np, dims] = size (pts);
+  if (np > dims)
+    if (nargin == 1)
+      [C, F, infi] = __voronoi__ (pts);
+    elseif ischar(opt)
+      [C, F, infi] = __voronoi__ (pts, opt);
+    else
+      error ("voronoin: second argument must be a string");
+    endif
+
+  else
+    error ("voronoin: number of points must be greater than their dimension");
+  endif
+endfunction
diff --git a/scripts/gethelp.cc b/scripts/gethelp.cc
new file mode 100644
index 0000000..1c86c07
--- /dev/null
+++ b/scripts/gethelp.cc
@@ -0,0 +1,164 @@
+/*
+
+Copyright (C) 1999, 2000, 2003, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if defined (__DECCXX)
+#define __USE_STD_IOSTREAM
+#endif
+
+#include <cstdio>
+
+#include <iostream>
+#include <string>
+
+static bool
+looks_like_octave_copyright (const std::string& s)
+{
+  // Perhaps someday we will want to do more here, so leave this as a
+  // separate function.
+
+  return (s.substr (0, 9) == "Copyright");
+}
+
+// Eat whitespace and comments from FFILE, returning the text of the
+// first block of comments that doesn't look like a copyright notice,
+
+static std::string
+extract_help_text (void)
+{
+  std::string help_txt;
+
+  bool first_comments_seen = false;
+  bool begin_comment = false;
+  bool have_help_text = false;
+  bool in_comment = false;
+  bool discard_space = true;
+  int c;
+
+  while ((c = std::cin.get ()) != EOF)
+    {
+      if (begin_comment)
+	{
+	  if (c == '%' || c == '#')
+	    continue;
+	  else if (discard_space && c == ' ')
+	    {
+	      discard_space = false;
+	      continue;
+	    }
+	  else
+	    begin_comment = false;
+	}
+
+      if (in_comment)
+	{
+	  if (! have_help_text)
+	    {
+	      first_comments_seen = true;
+	      help_txt += (char) c;
+	    }
+
+	  if (c == '\n')
+	    {
+	      in_comment = false;
+	      discard_space = true;
+
+	      if ((c = std::cin.get ()) != EOF)
+		{
+		  if (c == '\n')
+		    break;
+		}
+	      else
+		break;
+	    }
+	}
+      else
+	{
+	  switch (c)
+	    {
+	    case ' ':
+	    case '\t':
+	      if (first_comments_seen)
+		have_help_text = true;
+	      break;
+
+	    case '\n':
+	      if (first_comments_seen)
+		have_help_text = true;
+	      continue;
+
+	    case '%':
+	    case '#':
+	      begin_comment = true;
+	      in_comment = true;
+	      break;
+
+	    default:
+	      goto done;
+	    }
+	}
+    }
+
+ done:
+
+  if (! help_txt.empty ())
+    {
+      if (looks_like_octave_copyright (help_txt)) 
+	help_txt.resize (0);
+
+      if (help_txt.empty ())
+	help_txt = extract_help_text ();
+    }
+
+  return help_txt;
+}
+
+int
+main (int argc, char **argv)
+{
+  std::string name;
+  std::string file_name;
+
+  if (argc != 3)
+    {
+      std::cerr << "usage: gethelp name file-name\n";
+      return 1;
+    }
+  else
+    {
+      name = argv[1];
+      file_name = argv[2];
+    }
+
+  std::string help_text = extract_help_text ();  
+
+  if (! help_text.empty ())
+    {
+      std::cout << "" << name << "\n"
+		<< "@c " << file_name << "\n"
+		<< help_text;
+
+      if (help_text[help_text.length () - 1] != '\n')
+	std::cout << "\n";
+    }
+
+  return 0;
+}
diff --git a/scripts/help/Makefile.in b/scripts/help/Makefile.in
new file mode 100644
index 0000000..b4d4628
--- /dev/null
+++ b/scripts/help/Makefile.in
@@ -0,0 +1,94 @@
+# Makefile for octave's scripts/help directory
+#
+# Copyright (C) 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = help
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = \
+  __additional_help_message__.m \
+  __makeinfo__.m \
+  __strip_html_tags__.m \
+  doc.m \
+  gen_doc_cache.m \
+  get_first_help_sentence.m \
+  help.m \
+  lookfor.m \
+  print_usage.m \
+  type.m \
+  which.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/help
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/help/__additional_help_message__.m b/scripts/help/__additional_help_message__.m
new file mode 100644
index 0000000..436c26c
--- /dev/null
+++ b/scripts/help/__additional_help_message__.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __additional_help_message__ ()
+## Undocumented internal function.
+## @end deftypefn
+
+function msg = __additional_help_message__ ()
+
+  if (suppress_verbose_help_message ())
+    msg = "";
+  else
+    msg = "\
+Additional help for built-in functions and operators is\n\
+available in the on-line version of the manual.  Use the command\n\
+`doc <topic>' to search the manual index.\n\
+\n\
+Help and information about Octave is also available on the WWW\n\
+at http://www.octave.org and via the help at octave.org\n\
+mailing list.\n";
+  endif
+
+endfunction
diff --git a/scripts/help/__makeinfo__.m b/scripts/help/__makeinfo__.m
new file mode 100644
index 0000000..deb0710
--- /dev/null
+++ b/scripts/help/__makeinfo__.m
@@ -0,0 +1,161 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type})
+## @deftypefnx{Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type}, @var{see_also})
+## Undocumented internal function.
+## @end deftypefn
+
+## Run @code{makeinfo} on a given text.
+##
+## The string @var{text} is run through the @code{__makeinfo__} program
+## to generate output in various formats. This string must contain valid
+## Texinfo formatted text.
+##
+## The @var{output_type} selects the format of the output. This can be either
+## @t{"html"}, @t{"texinfo"}, or @t{"plain text"}. By default this is
+## @t{"plain text"}. If @var{output_type} is @t{"texinfo"}, the @t{@@seealso}
+## macro is expanded, but otherwise the text is unaltered.
+##
+## If the optional argument @var{see_also} is present, it is used to expand the
+## Octave specific @t{@@seealso} macro. This argument must be a function handle,
+## that accepts a cell array of strings as input argument (each elements of the
+## array corresponds to the arguments to the @t{@@seealso} macro), and return
+## the expanded string. If this argument is not given, the @t{@@seealso} macro
+## will be expanded to the text
+##
+## @example
+## See also: arg1, arg2@, ...
+## @end example
+##
+## @noindent
+## for @t{"plain text"} output, and
+##
+## @example
+## See also: @@ref@{arg1@}, @@ref@{arg2@}, ...
+## @end example
+##
+## @noindent
+## otherwise.
+##
+## The optional output argument @var{status} contains the exit status of the
+## @code{makeinfo} program as returned by @code{system}.
+
+function [retval, status] = __makeinfo__ (text, output_type = "plain text", see_also = [])
+
+  ## Check input
+  if (nargin == 0)
+    print_usage ();
+  endif
+  
+  if (!ischar (text))
+    error ("__makeinfo__: first input argument must be a string");
+  endif
+  
+  if (!ischar (output_type))
+    error ("__makeinfo__: second input argument must be a string");
+  endif
+  
+  ## Define the @seealso macro
+  if (isempty (see_also))
+    if (strcmpi (output_type, "plain text"))
+      see_also = @simple_see_also;
+    else
+      see_also = @simple_see_also_with_refs;
+    endif
+  endif
+  
+  if (!isa (see_also, "function_handle"))
+    error ("__makeinfo__: third input argument must be the empty matrix, or a function handle");
+  endif
+  
+  ## It seems like makeinfo sometimes gets angry if the character on a line is
+  ## a space, so we remove these.
+  text = strrep (text, "\n ", "\n");
+  
+  ## Handle @seealso macro
+  SEE_ALSO = "@seealso";
+  starts = strfind (text, SEE_ALSO);
+  for start = starts
+    if (start == 1 || (text (start-1) != "@"))
+      bracket_start = find (text (start:end) == "{", 1);
+      stop = find (text (start:end) == "}", 1);
+      if (!isempty (stop) && !isempty (bracket_start))
+        stop += start - 1;
+        bracket_start += start - 1;
+      else
+        bracket_start = start + length (SEE_ALSO);
+        stop = find (text (start:end) == "\n", 1);
+        if (isempty (stop))
+          stop = length (text);
+        else
+          stop += start - 1;
+        endif
+      endif
+      see_also_args = text (bracket_start+1:(stop-1));
+      see_also_args = strtrim (strsplit (see_also_args, ","));
+      expanded = see_also (see_also_args);
+      text = strcat (text (1:start-1), expanded, text (stop+1:end));
+    endif
+  endfor
+  
+  if (strcmpi (output_type, "texinfo"))
+    status = 0;
+    retval = text;
+    return;
+  endif
+  
+  ## Create the final TeXinfo input string
+  text = sprintf ("\\input texinfo\n\n%s\n\n at bye\n", text);
+  
+  unwind_protect
+    ## Write Texinfo to tmp file
+    [fid, name, msg] = mkstemp ("octave_help_XXXXXX", true);
+    fwrite (fid, text);
+    fclose (fid);
+
+    ## Take action depending on output type
+    switch (lower (output_type))
+      case "plain text"
+         cmd = sprintf ("%s --no-headers --no-warn --force --no-validate %s",
+                        makeinfo_program (), name);
+      case "html"
+         cmd = sprintf ("%s --no-headers --html --no-warn --no-validate --force %s",
+                        makeinfo_program (), name);
+      otherwise
+        error ("__makeinfo__: unsupported output type: '%s'", output_type);
+    endswitch
+  
+    ## Call makeinfo
+    [status, retval] = system (cmd);
+   
+  unwind_protect_cleanup
+    if (exist (name, "file"))
+      delete (name);
+    endif
+  end_unwind_protect
+endfunction
+
+function expanded = simple_see_also (args)
+  expanded = strcat ("\nSee also:", sprintf (" %s,", args {:}));
+  expanded = strcat (expanded (1:end-1), "\n\n");
+endfunction
+
+function expanded = simple_see_also_with_refs (args)
+  expanded = strcat ("\nSee also:", sprintf (" @ref{%s},", args {:}));
+  expanded = strcat (expanded (1:end-1), "\n\n");
+endfunction
diff --git a/scripts/help/__strip_html_tags__.m b/scripts/help/__strip_html_tags__.m
new file mode 100644
index 0000000..61c36ba
--- /dev/null
+++ b/scripts/help/__strip_html_tags__.m
@@ -0,0 +1,79 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{text}, @var{status}] =} __strip_html_tags__ (@var{html_text})
+## Undocumented internal function.
+## @end deftypefn
+
+## Remove HTML tags from text.  This is used as a simple HTML-to-text
+## function. 
+
+function [text, status] = __strip_html_tags__ (html_text)
+  start = find (html_text == "<");
+  stop  = find (html_text == ">");
+  if (length (start) == length (stop))
+    text = html_text;
+    for n = length(start):-1:1
+      text (start (n):stop (n)) = [];
+    endfor
+    text = strip_superfluous_endlines (text);
+    status = 0;
+  else
+    warning ("help: invalid HTML data -- raw HTML source follows...");
+    disp (html_text);
+    text = "";
+    status = 1;
+  endif
+endfunction
+
+## This function removes end-lines (\n) that makes printing look bad
+function text = strip_superfluous_endlines (text)
+  ## Find groups of end-lines
+  els = find (text == "\n");
+  dels = diff (els);
+  groups = [els(1), 1]; # list containing [start, length] of each group
+  for k = 1:length (dels)
+    if (dels (k) == 1)
+      groups (end, 2) ++;
+    else
+      groups (end+1, 1:2) = [els(k+1), 1];
+    endif
+  endfor
+
+  keep = true (size (text));
+
+  ## Remove end-lines in the beginning
+  if (groups (1, 1) == 1)
+    keep (1:groups (1, 2)) = false;
+  endif
+  
+  ## Remove end-lines from the end
+  if (sum (groups (end, :)) - 1 == length (text))
+    keep (groups (end, 1):end) = false;
+  endif
+  
+  ## Remove groups of end-lines with more than 3 end-lines next to each other
+  idx = find (groups (:, 2) >= 3);
+  for k = 1:length (idx)
+    start = groups (idx (k), 1);
+    stop = start + groups (idx (k), 2) - 1;
+    keep (start+2:stop) = false;
+  endfor
+  
+  ## Actually remove the elements
+  text = text (keep);
+endfunction
diff --git a/scripts/help/doc.m b/scripts/help/doc.m
new file mode 100644
index 0000000..fa24532
--- /dev/null
+++ b/scripts/help/doc.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Søren Hauberg
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} doc @var{function_name}
+## Display documentation for the function @var{function_name}
+## directly from an on-line version of
+## the printed manual, using the GNU Info browser.  If invoked without
+## any arguments, the manual is shown from the beginning.
+##
+## For example, the command @kbd{doc rand} starts the GNU Info browser
+## at the @code{rand} node in the on-line version of the manual.
+##
+## Once the GNU Info browser is running, help for using it is available
+## using the command @kbd{C-h}.
+## @seealso{help}
+## @end deftypefn
+
+## Author: Soren Hauberg <soren at hauberg.org>
+## Adapted-by: jwe
+
+function retval = doc (fname)
+
+  if (nargin == 0 || nargin == 1)
+
+    ftype = 0;
+
+    if (nargin == 1)
+      ## Get the directory where the function lives.
+      ## FIXME -- maybe we should have a better way of doing this.
+
+      if (ischar (fname))
+	ftype = exist (fname);
+      else
+	error ("doc: expecting argument to be a character string");
+      endif
+    else
+      fname = "";
+    endif
+
+    if (ftype == 2 || ftype == 3)
+      ffile = which (fname);
+    else
+      ffile = "";
+    endif
+
+    if (isempty (ffile))
+      info_dir = octave_config_info ("infodir");
+    else
+      info_dir = fileparts (ffile);
+    endif
+
+    ## Determine if a file called doc.info exist in the same 
+    ## directory as the function.
+
+    info_file_name = fullfile (info_dir, "doc.info");
+
+    [stat_info, err] = stat (info_file_name);
+
+    if (err < 0)
+      info_file_name = info_file ();
+    endif
+
+    ## FIXME -- don't change the order of the arguments below because
+    ## the info-emacs-info script currently expects --directory DIR as
+    ## the third and fourth arguments.  Someone should fix that.
+
+    cmd = sprintf ("\"%s\" --file \"%s\" --directory \"%s\"",
+		   info_program (), info_file_name, info_dir);
+
+    have_fname = ! isempty (fname);
+
+    if (have_fname)
+      status = system (sprintf ("%s --index-search %s", cmd, fname));
+    endif
+
+    if (! (have_fname && status == 0))
+      status = system (cmd);
+      if (status == 127)
+	warning ("unable to find info program `%s'", info_program ());
+      endif
+    endif
+
+    if (nargout > 0)
+      retval = status;
+    endif
+
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test if exist( info_file ()) != 2 && exist (sprintf ("%s.gz", info_file ())) != 2
+%!       error ("Info file %s or %s.gz does not exist!", info_file (), info_file ());
+%!     endif
diff --git a/scripts/help/gen_doc_cache.m b/scripts/help/gen_doc_cache.m
new file mode 100644
index 0000000..d42a1e6
--- /dev/null
+++ b/scripts/help/gen_doc_cache.m
@@ -0,0 +1,142 @@
+## Copyright (C) 2009 S�ren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} gen_doc_cache (@var{out_file}, @var{directory})
+## Generate documentation caches for all functions in a given directory.
+##
+## A documentation cache is generated for all functions in @var{directory}.  The
+## resulting cache is saved in the file @var{out_file}.
+## The cache is used to speed up @code{lookfor}.
+##
+## If no directory is given (or it is the empty matrix), a cache for builtin
+## operators, etc. is generated.
+##
+## @seealso{lookfor, path}
+## @end deftypefn
+
+function gen_doc_cache (out_file = "doc-cache", directory = [])
+  ## Check input
+  if (!ischar (out_file))
+    print_usage ();
+  endif
+  
+  ## Generate cache
+  if (isempty (directory))
+    cache = gen_builtin_cache ();
+  elseif (ischar (directory))
+    cache = gen_doc_cache_in_dir (directory);
+  else
+    error ("gen_doc_cache: second input argument must be a string");
+  endif
+  
+  ## Save cache
+  if (! isempty (cache))
+    save ("-text", out_file, "cache");
+  endif
+endfunction
+
+function [text, first_sentence, status] = handle_function (f, text, format)
+  first_sentence = "";
+  ## Skip functions that start with __ as these shouldn't be searched by lookfor
+  if (length (f) > 2 && all (f (1:2) == "_"))
+    status = 1;
+    return;
+  endif
+
+  ## Take action depending on help text format
+  switch (lower (format))
+    case "plain text"
+      status = 0;
+    case "texinfo"
+      [text, status] = __makeinfo__ (text, "plain text");
+    case "html"
+      [text, status] = strip_html_tags (text);
+    otherwise
+      status = 1;
+  endswitch
+    
+  ## Did we get the help text?
+  if (status != 0 || isempty (text))
+    warning ("gen_doc_cache: unusable help text in '%s'. Ignoring function.", f);
+    return;
+  endif
+
+  ## Get first sentence of help text
+  first_sentence = get_first_help_sentence (f);
+endfunction
+
+function cache = create_cache (list)
+  cache = {};
+  
+  ## For each function:
+  for n = 1:length (list)
+    f = list {n};
+    
+    ## Get help text
+    [text, format] = get_help_text (f);
+    
+    [text, first_sentence, status] = handle_function (f, text, format);
+
+    ## Did we get the help text?
+    if (status != 0)
+      continue;
+    endif
+    
+    ## Store the help text
+    cache (1, end+1) = f;
+    cache (2, end) = text;
+    cache (3, end) = first_sentence;
+  endfor
+endfunction
+
+function cache = gen_doc_cache_in_dir (directory)
+  ## If 'directory' is not in the current path, add it so we search it
+  dir_in_path = false;
+  p = path ();
+  idx = find (p == pathsep ());
+  prev_idx = 1;
+  for n = 1:length (idx)
+    f = p (prev_idx:idx (n)-1);
+    if (strcmp (f, directory))
+      dir_in_path = true;
+      break;
+    endif
+    prev_idx = idx (n) + 1;
+  endfor
+  
+  if (!dir_in_path)
+    addpath (directory);
+  endif
+
+  ## Get list of functions in directory and create cache
+  list = __list_functions__ (directory);
+  cache = create_cache (list);
+  
+  if (!dir_in_path)
+    rmpath (directory);
+  endif
+endfunction
+
+function cache = gen_builtin_cache ()
+  operators = __operators__ ();
+  keywords = __keywords__ ();
+  builtins = __builtins__ ();
+  list = {operators{:}, keywords{:}, builtins{:}};
+
+  cache = create_cache (list);
+endfunction
+
diff --git a/scripts/help/get_first_help_sentence.m b/scripts/help/get_first_help_sentence.m
new file mode 100644
index 0000000..7f6d985
--- /dev/null
+++ b/scripts/help/get_first_help_sentence.m
@@ -0,0 +1,153 @@
+## Copyright (C) 2009 S�ren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{retval}, @var{status}] =} get_first_help_sentence (@var{name}, @var{max_len})
+## Return the first sentence of a function help text.
+##
+## The function reads the first sentence of the help text of the function
+## @var{name}.  The first sentence is defined as the text after the function
+## declaration until either the first period (".") or the first appearance of
+## two consecutive end-lines ("\n\n").  The text is truncated to a maximum length
+## of @var{max_len}, which defaults to 80.
+##
+## The optional output argument @var{status} returns the status reported by
+## @code{makeinfo}.  If only one output argument is requested, and @var{status}
+## is non-zero, a warning is displayed.
+##
+## As an example, the first sentence of this help text is
+##
+## @example
+## @group
+## get_first_help_sentence ("get_first_help_sentence")
+## @print{} ans = Return the first sentence of a function help text.
+## @end group
+## @end example
+## @end deftypefn
+
+function [retval, status] = get_first_help_sentence (name, max_len = 80)
+  ## Check input
+  if (nargin == 0)
+    error ("get_first_help_sentence: not enough input arguments");
+  endif
+  
+  if (!ischar (name))
+    error ("get_first_help_sentence: first input must be a string");
+  endif
+  
+  if (!isnumeric (max_len) || max_len <= 0 || max_len != round (max_len))
+    error ("get_first_help_sentence: second input must be positive integer");
+  endif
+
+  ## First, we get the raw help text
+  [help_text, format] = get_help_text (name);
+  
+  ## Then, we take action depending on the format
+  switch (lower (format))
+    case "plain text"
+      [retval, status] = first_sentence_plain_text (help_text, max_len);
+    case "texinfo"
+      [retval, status] = first_sentence_texinfo (help_text, max_len);
+    case "html"
+      [retval, status] = first_sentence_html (help_text, max_len);
+    case "not documented"
+      error ("get_first_help_sentence: `%s' is not documented\n", name);
+    case "not found"
+      error ("get_first_help_sentence: `%s' not found\n", name);
+    otherwise
+      error ("get_first_help_sentence: internal error: unsupported help text format: '%s'\n", format);
+  endswitch
+
+  if (nargout <= 1 && status != 0)
+    warning ("get_first_help_sentence: couldn't run makeinfo on '%s'", name);
+  endif
+endfunction
+
+## This function extracts the first sentence from a plain text help text
+function [retval, status] = first_sentence_plain_text (help_text, max_len)
+  ## Extract first line by searching for a period or a double line-end.
+  period_idx = find (help_text == ".", 1);
+  line_end_idx = strfind (help_text, "\n\n");
+  retval = help_text (1:min ([period_idx(:); line_end_idx(:); max_len; length(help_text)]));
+  status = 0;
+endfunction
+
+## This function extracts the first sentence from a Texinfo help text.
+## The function works by removing @def* from the texinfo text. After this, we
+## render the text to plain text using makeinfo, and then extract the first line.
+function [retval, status] = first_sentence_texinfo (help_text, max_len)
+  ## Lines ending with "@\n" are continuation lines, so they should be concatenated
+  ## with the following line.
+  help_text = strrep (help_text, "@\n", " ");
+  
+  ## Find, and remove, lines that start with @def. This should remove things
+  ## such as @deftypefn, @deftypefnx, @defvar, etc.
+  keep = true (size (help_text));
+  def_idx = strfind (help_text, "@def");
+  if (!isempty (def_idx))
+    endl_idx = find (help_text == "\n");
+    for k = 1:length (def_idx)
+      endl = endl_idx (find (endl_idx > def_idx (k), 1));
+      if (isempty (endl))
+        keep (def_idx (k):end) = false;
+      else
+        keep (def_idx (k):endl) = false;
+      endif
+    endfor
+  
+    ## Remove the @end ... that corresponds to the @def we removed above
+    def1 = def_idx (1);
+    space_idx = find (help_text == " ");
+    space_idx = space_idx (find (space_idx > def1, 1));
+    bracket_idx = find (help_text == "{" | help_text == "}");
+    bracket_idx = bracket_idx (find (bracket_idx > def1, 1));
+    if (isempty (space_idx) && isempty (bracket_idx))
+      error ("get_first_help_sentence: couldn't parse texinfo");
+    endif
+    sep_idx = min (space_idx, bracket_idx);
+    def_type = help_text (def1+1:sep_idx-1);
+
+    end_idx = strfind (help_text, sprintf ("@end %s", def_type));
+    if (isempty (end_idx))
+      error ("get_first_help_sentence: couldn't parse texinfo");
+    endif
+    endl = endl_idx (find (endl_idx > end_idx, 1));
+    if (isempty (endl))
+      keep (end_idx:end) = false;
+    else
+      keep (end_idx:endl) = false;
+    endif
+    
+    help_text = help_text (keep);
+  endif
+  
+  ## Run makeinfo to generate plain text
+  [help_text, status] = __makeinfo__ (help_text, "plain text");
+  
+  ## Extract first line with plain text method.
+  retval = first_sentence_plain_text (help_text, max_len);
+endfunction
+
+## This function extracts the first sentence from a html help text.
+## The function simply removes the tags and treats the text as plain text.
+function [retval, status] = first_sentence_html (help_text, max_len)
+  ## Strip tags
+  [help_text, status] = strip_html_tags (help_text);
+  
+  ## Extract first line with plain text method.
+  retval = first_sentence_plain_text (help_text, max_len);
+endfunction
+
diff --git a/scripts/help/help.m b/scripts/help/help.m
new file mode 100644
index 0000000..1d19d58
--- /dev/null
+++ b/scripts/help/help.m
@@ -0,0 +1,116 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} help @var{name}
+## Display the help text for @var{name}.
+## If invoked without any arguments, @code{help} prints a list
+## of all the available operators and functions.
+## 
+## For example, the command @kbd{help help} prints a short message
+## describing the @code{help} command.
+## 
+## The help command can give you information about operators, but not the
+## comma and semicolons that are used as command separators.  To get help
+## for those, you must type @kbd{help comma} or @kbd{help semicolon}.
+## @seealso{doc, lookfor, which}
+## @end deftypefn
+
+function help (name)
+
+  if (nargin == 0)
+
+    puts ("\n\
+  For help with individual commands and functions type\n\
+\n\
+    help NAME\n\
+\n\
+  (replace NAME with the name of the command or function you would\n\
+  like to learn more about).\n\
+\n\
+  For a more detailed introduction to GNU Octave, please consult the\n\
+  manual.  To read the manual from the prompt type\n\
+\n\
+    doc\n\
+\n\
+  GNU Octave is supported and developed by its user community.\n\
+  For more information visit http://www.octave.org.\n\n");
+
+  elseif (nargin == 1 && ischar (name))
+
+    ## Get help text
+    [text, format] = get_help_text (name);
+    
+    ## Take action depending on help text format
+    switch (lower (format))
+      case "plain text"
+        status = 0;
+      case "texinfo"
+        [text, status] = __makeinfo__ (text, "plain text");
+      case "html"
+        [text, status] = strip_html_tags (text);
+      case "not documented"
+        error ("help: `%s' is not documented\n", name);
+      case "not found"
+        [text, status] = do_contents (name);
+        if (status != 0)
+          error ("help: `%s' not found\n", name);
+        endif
+      otherwise
+        error ("help: internal error: unsupported help text format: '%s'\n", format);
+    endswitch
+    
+    ## Print text
+    if (status != 0)
+      warning ("help: Texinfo formatting filter exited abnormally; raw Texinfo source of help text follows...\n");
+    endif
+
+    which (name);
+    printf ("\n%s\n%s", text, __additional_help_message__ ());
+
+  else
+    error ("help: invalid input\n");
+  endif
+
+endfunction
+
+function [text, status] = do_contents (name)
+  text = "";
+  status = 1;
+
+  d = find_dir_in_path (name);
+  if (!isempty (d))
+    p = path ();
+    unwind_protect
+      ## Only include 'd' in the path, and then get the help text of 'Contents'
+      path (d);
+      [text, format] = get_help_text ("Contents");
+
+      ## Take action depending on help text format
+      switch (lower (format))
+        case "plain text"
+          status = 0;
+        case "texinfo"
+          [text, status] = __makeinfo__ (text, "plain text");
+        case "html"
+          [text, status] = strip_html_tags (text);
+      endswitch
+    unwind_protect_cleanup
+      ## Restore path
+      path (p);
+    end_unwind_protect
+  endif
+endfunction
diff --git a/scripts/help/lookfor.m b/scripts/help/lookfor.m
new file mode 100644
index 0000000..c38202d
--- /dev/null
+++ b/scripts/help/lookfor.m
@@ -0,0 +1,185 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} lookfor @var{str}
+## @deftypefnx {Command} lookfor -all @var{str}
+## @deftypefnx {Function} {[@var{func}, @var{helpstring}] =} lookfor (@var{str})
+## @deftypefnx {Function} {[@var{func}, @var{helpstring}] =} lookfor ('-all', @var{str})
+## Search for the string @var{str} in all functions found in the current 
+## function search path.  By default, @code{lookfor} searches for @var{str}
+## in the first sentence of the help string of each function found.  The entire
+## help text of each function can be searched if the '-all' argument is 
+## supplied.  All searches are case insensitive.
+## 
+## Called with no output arguments, @code{lookfor} prints the list of 
+## matching functions to the terminal.  Otherwise, the output arguments 
+## @var{func} and @var{helpstring} define the matching functions and the 
+## first sentence of each of their help strings.
+## 
+## The ability of @code{lookfor} to correctly identify the first
+## sentence of the help text is dependent on the format of the
+## function's help.  All Octave core functions are correctly
+## formatted, but the same can not be guaranteed for external packages and
+## user-supplied functions.  Therefore, the use of the '-all' argument may 
+## be necessary to find related functions that are not a part of Octave.
+## @seealso{help, doc, which}
+## @end deftypefn
+
+function [out_fun, out_help_text] = lookfor (str, extra)
+  if (strcmpi (str, "-all"))
+    ## The difference between using '-all' and not, is which part of the caches
+    ## we search. The cache is organised such that its first column contains
+    ## the function name, its second column contains the full help text, and its
+    ## third column contains the first sentence of the help text.
+    str = extra;
+    search_type = 2; # when using caches, search its second column
+  else
+    search_type = 3; # when using caches, search its third column
+  endif
+  str = lower (str);
+
+  ## Search functions, operators, and keywords that come with Octave
+  cache_file = doc_cache_file ();
+  if (exist (cache_file, "file"))
+    [fun, help_text] = search_cache (str, cache_file, search_type);
+    had_core_cache = true;
+  else
+    fun = help_text = {};
+    had_core_cache = false;
+  endif
+  
+  ## Search functions in new path dirs.
+  orig_path = strsplit (__pathorig__ (), pathsep ());
+
+  ## ditto for path.
+  new_path = strsplit (path (), pathsep ());
+
+  ## scratch out directories already covered by orig_path.
+  if (had_core_cache)
+    new_path = setdiff (new_path, orig_path);
+  endif
+
+  for n = 1:numel (new_path)
+    elt = new_path{n};
+    cache_file = fullfile (elt, "doc-cache");
+    if (exist (cache_file, "file"))
+      ## We have a cache in the directory, then read it and search it!
+      [funs, hts] = search_cache (str, cache_file, search_type);
+      fun (end+1:end+length (funs)) = funs;
+      help_text (end+1:end+length (hts)) = hts;
+    else
+    ## We don't have a cache. Search files
+      funs_in_f = __list_functions__ (elt);
+      for m = 1:length (funs_in_f)
+        fn = funs_in_f {m};
+      
+        ## Skip files that start with __
+        if (length (fn) > 2 && strcmp (fn (1:2), "__"))
+          continue;
+        endif
+      
+        ## Extract first sentence
+        try
+          warn_state = warning ();
+          unwind_protect
+            warning ("off");
+            first_sentence = get_first_help_sentence (fn);
+            status = 0;
+          unwind_protect_cleanup
+            warning (warn_state);
+          end_unwind_protect
+        catch
+          status = 1;
+        end_try_catch
+
+        if (search_type == 2) # search entire help text
+          try
+            warn_state = warning ();
+            unwind_protect
+              warning ("off");
+              [text, fmt] = get_help_text (fn);
+              status = 0;
+            unwind_protect_cleanup
+              warning (warn_state);
+            end_unwind_protect
+          catch
+            status = 1;
+          end_try_catch
+  
+          ## Take action depending on help text fmt
+          switch (lower (fmt))
+            case "plain text"
+              status = 0;
+            case "texinfo"
+              [text, status] = __makeinfo__ (text, "plain text");
+            case "html"
+              [text, status] = strip_html_tags (text);
+            otherwise
+              status = 1;
+          endswitch
+
+        elseif (status == 0) # only search the first sentence of the help text
+          text = first_sentence;
+        endif
+      
+        ## Search the help text, if we can
+        if (status == 0 && !isempty (strfind (text, str)))
+          fun (end+1) = fn;
+          help_text (end+1) = first_sentence;
+        endif
+      endfor
+    endif
+  endfor
+  
+  if (nargout == 0)
+    ## Print the results (FIXME: improve this to make it look better.
+    indent = 20;
+    term_width = terminal_size() (2);
+    desc_width = term_width - indent - 2;
+    indent_space = repmat (" ", 1, indent);
+    for k = 1:length (fun)
+      f = fun {k};
+      f (end+1:indent) = " ";
+      printf (f);
+      desc = strtrim (strrep (help_text {k}, "\n", " "));
+      ldesc = length (desc);
+      printf ("%s\n", desc (1:min (desc_width, ldesc)));
+      for start = desc_width+1:desc_width:ldesc
+        stop = min (start + desc_width, ldesc);
+        printf ("%s%s\n", indent_space, strtrim (desc (start:stop)));
+      endfor
+    endfor
+
+  else
+    ## Return the results instead of displaying them
+    out_fun = fun;
+    out_help_text = help_text;
+  endif
+endfunction
+
+function [funs, help_texts] = search_cache (str, cache_file, search_type)
+  load (cache_file);
+  if (! isempty (cache))
+    t1 = strfind (cache (1, :), str);
+    t2 = strfind (cache (search_type, :), str);
+    cache_idx = find (! (cellfun ("isempty", t1) & cellfun ("isempty", t2)));
+    funs = cache (1, cache_idx);
+    help_texts = cache (3, cache_idx);
+  else
+    funs = help_texts = {};
+  endif
+endfunction
diff --git a/scripts/help/print_usage.m b/scripts/help/print_usage.m
new file mode 100644
index 0000000..be470d6
--- /dev/null
+++ b/scripts/help/print_usage.m
@@ -0,0 +1,114 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} print_usage ()
+## @deftypefnx{Function File} {} print_usage (@var{name})
+## Print the usage message for a function.  When called with no input arguments
+## the @code{print_usage} function displays the usage message of the currently
+## executing function.
+## @seealso{help}
+## @end deftypefn
+
+function print_usage (name)
+  ## Handle input
+  if (nargin == 0)
+    ## Determine the name of the calling function
+    x = dbstack ();
+    if (numel (x) > 1)
+      name = x (2).name;
+    else
+      error ("print_usage: invalid function\n");
+    endif
+  elseif (!ischar (name))
+    error ("print_usage: input argument must be a string");
+  endif
+  
+  ## Do the actual work
+  [text, format] = get_help_text (name);
+  max_len = 80;
+  switch (lower (format))
+    case "plain text"
+      [usage_string, status] = get_usage_plain_text (text, max_len);
+    case "texinfo"
+      [usage_string, status] = get_usage_texinfo (text, max_len);
+    case "html"
+      [usage_string, status] = get_usage_html (text, max_len);
+    case "not documented"
+      error ("print_usage: `%s' is not documented\n", name);
+    case "not found"
+      error ("print_usage: `%s' not found\n", name);
+    otherwise
+      error ("print_usage: internal error: unsupported help text format: '%s'\n", format);
+  endswitch
+  
+  ## Raise the final error
+  if (status != 0)
+    warning ("print_usage: Texinfo formatting filter exited abnormally");
+    warning ("print_usage: raw Texinfo source of help text follows...\n");
+  endif
+
+  error ("Invalid call to %s.  Correct usage is:\n\n%s\n%s",
+	 name, usage_string, __additional_help_message__ ());
+endfunction
+
+function [retval, status] = get_usage_plain_text (help_text, max_len)
+  ## Extract first line by searching for a double line-end.
+  line_end_idx = strfind (help_text, "\n\n");
+  retval = help_text (1:min ([line_end_idx , max_len, length(help_text)]));
+  status = 0;
+endfunction
+
+function [retval, status] = get_usage_texinfo (help_text, max_len)
+  ## Lines ending with "@\n" are continuation lines, so they should be
+  ## concatenated with the following line.
+  help_text = strrep (help_text, "@\n", " ");
+  
+  ## Find, and keep, lines that start with @def or @end def. This should include things
+  ## such as @deftypefn, @deftypefnx, @defvar, etc. and their corresponding @end's
+  def_idx = strfind (help_text, "@def");
+  if (!isempty (def_idx))
+    buffer = "";
+    endl_idx = find (help_text == "\n");
+    for k = 1:length (def_idx)
+      endl = endl_idx (find (endl_idx > def_idx (k), 1));
+      if (isempty (endl))
+        buffer = strcat (buffer, help_text (def_idx (k):end), "\n");
+      else
+        buffer = strcat (buffer, help_text (def_idx (k):endl));
+      endif
+    endfor
+    
+    end_def_idx = strfind (help_text, "@end def");
+    if (!isempty (end_def_idx))
+      buffer = strcat (buffer, help_text (end_def_idx:end));
+    endif
+  else
+    [retval, status] = get_usage_plain_text (help_text, max_len);
+  endif
+
+  ## Run makeinfo to generate plain text
+  [retval, status] = __makeinfo__ (buffer, "plain text");
+endfunction
+
+function [retval, status] = get_usage_html (help_text, max_len)
+  ## Strip tags
+  [help_text, status] = strip_html_tags (help_text);
+  
+  ## Extract first line with plain text method.
+  retval = get_usage_plain_text (help_text, max_len);
+endfunction
+
diff --git a/scripts/help/type.m b/scripts/help/type.m
new file mode 100644
index 0000000..8a10160
--- /dev/null
+++ b/scripts/help/type.m
@@ -0,0 +1,110 @@
+## Copyright (C) 2009 Søren Hauberg
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} type options name @dots{}
+## Display the definition of each @var{name} that refers to a function.
+## 
+## Normally also displays whether each @var{name} is user-defined or built-in;
+## the @code{-q} option suppresses this behavior.
+##
+## If an output argument is requested nothing is displayed.  Instead, a cell 
+## array of strings is returned, where each element corresponds to the 
+## definition of each requested function.
+## @end deftypefn
+
+function retval = type (varargin)
+  ## Parse input
+  if (nargin == 0)
+    error ("type: not enough input arguments");
+  endif
+
+  if (!iscellstr (varargin))
+    error ("type: input arguments must be strings");
+  endif
+    
+  quiet = false;
+  idx = strcmpi (varargin, "-q") | strcmpi (varargin, "-quiet");
+  if (any (idx))
+    quiet = true;
+    varargin (idx) = [];
+  endif
+
+  if (nargout > 0)
+    retval = cell (size (varargin));
+  endif
+  
+  for n = 1:length (varargin)
+    name = varargin {n};
+    
+    ## Find function and get its code
+    text = "";
+    cmd = sprintf ("exist ('%s')", name);
+    e = evalin ("caller", cmd);
+    if (e == 1)
+      ## Variable
+      cmd = sprintf ("disp (%s);", name);
+      desc = evalin ("caller", cmd);
+      if (quiet)
+        text = desc;
+      else
+        text = sprintf ("%s is a variable\n%s", name, desc);
+      endif
+    elseif (e == 2)
+      ## m-file or ordinary file
+      file = which (name);
+      if (isempty (file))
+        ## 'name' is an ordinary file, and not a function name.
+        ## FIXME: Should we just print it anyway?
+        error ("type: `%s' undefined\n", name);
+      endif
+    
+      ## Read the file
+      fid = fopen (file, "r");
+      if (fid < 0)
+        error ("type: couldn't open `%s' for reading", file);
+      endif
+      contents = char (fread (fid).');
+      fclose (fid);
+    
+      if (quiet)
+        text = contents;
+      else
+        text = sprintf ("%s is the user-defined function defined from: %s\n\n%s",
+                        name, file, contents);
+      endif    
+    elseif (e == 3)
+      text = sprintf ("%s is a dynamically-linked function", name);
+    elseif (e == 5)
+      text = sprintf ("%s is a built-in function", name);
+    elseif (any (strcmp (__operators__ (), name)))
+      text = sprintf ("%s is an operator", name);
+    elseif (any (strcmp (__keywords__ (), name)))
+      text = sprintf ("%s is a keyword", name);
+    else
+      error ("type: `%s' undefined\n", name);
+    endif
+
+    ## Should we return the text or print if
+    if (nargout == 0)
+      disp (text);
+    else
+      retval {n} = text;
+    endif
+  endfor
+endfunction
+
+
diff --git a/scripts/help/which.m b/scripts/help/which.m
new file mode 100644
index 0000000..442a8dd
--- /dev/null
+++ b/scripts/help/which.m
@@ -0,0 +1,53 @@
+## Copyright (C) 2009 John W. Eaton
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deffn {Command} which name @dots{}
+## Display the type of each @var{name}.  If @var{name} is defined from a
+## function file, the full name of the file is also displayed.
+## @seealso{help, lookfor}
+## @end deffn
+
+function varargout = which (varargin)
+
+  if (nargin > 0 && iscellstr (varargin))
+    m = __which__ (varargin{:});
+
+    if (nargout == 0)
+      for i = 1:nargin
+	if (isempty (m(i).file))
+	  if (! isempty (m(i).type))
+	    printf ("`%s' is a %s\n",
+		    m(i).name, m(i).type);
+	  endif
+	else
+	  if (isempty (m(i).type))
+	    printf ("`%s' is the file %s\n",
+		    m(i).name, m(i).file);
+	  else
+	    printf ("`%s' is a %s from the file %s\n",
+		    m(i).name, m(i).type, m(i).file);
+	  endif
+	endif
+      endfor
+    else
+      varargout = {m.file};
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/image/Makefile.in b/scripts/image/Makefile.in
new file mode 100644
index 0000000..b8cdaab
--- /dev/null
+++ b/scripts/image/Makefile.in
@@ -0,0 +1,100 @@
+# Makefile for octave's scripts/image directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2003, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = image
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = __img__.m __img_via_file__.m autumn.m bone.m brighten.m colormap.m \
+  contrast.m cool.m copper.m flag.m gmap40.m gray.m gray2ind.m hot.m hsv.m \
+  hsv2rgb.m image.m image_viewer.m imagesc.m imfinfo.m imread.m imshow.m \
+  imwrite.m ind2gray.m ind2rgb.m jet.m ntsc2rgb.m ocean.m pink.m prism.m \
+  rainbow.m rgb2hsv.m rgb2ind.m rgb2ntsc.m saveimage.m spring.m summer.m \
+  white.m winter.m
+
+IMAGES = default.img
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES) $(IMAGES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(imagedir)
+	for f in $(IMAGES); do \
+	  rm -f $(DESTDIR)$(imagedir)/$$f; \
+	  $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(imagedir)/$$f; \
+	done
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(archlibdir)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+	for f in $(IMAGES); \
+	  do rm -f $(DESTDIR)$(imagedir)/$$f; \
+	done
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/image
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/image/__img__.m b/scripts/image/__img__.m
new file mode 100644
index 0000000..e4a53e6
--- /dev/null
+++ b/scripts/image/__img__.m
@@ -0,0 +1,80 @@
+## Copyright (C) 1996, 1997, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## Undocumented internal function.
+
+## -*- texinfo -*-
+## @deftypefnx {Function File} {} __img__ (@var{x}, @var{y}, @var{img}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Generic image creation.
+##
+## The axis values corresponding to the matrix elements are specified in
+## @var{x} and @var{y}. If you're not using gnuplot 4.2 or later, these
+## variables are ignored.
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function h = __img__ (x, y, img, varargin)
+
+  newplot ();
+
+  if (isempty (img))
+    error ("__img__: matrix is empty");
+  endif
+
+  if (isempty (x))
+    x = [1, columns(img)];
+  endif
+
+  if (isempty (y))
+    y = [1, rows(img)];
+  endif
+
+  xlim = [x(1), x(end)];
+  ylim = [y(1), y(end)];
+
+  ca = gca ();
+
+  tmp = __go_image__ (ca, "cdata", img, "xdata", xlim, "ydata", ylim, 
+		      "cdatamapping", "direct", varargin {:});
+
+  if (ndims (img) == 3)
+    if (isinteger (img))
+      c = class (img);
+      mn = intmin (c);
+      mx = intmax (c);
+      set (ca, "clim", double ([mn, mx]));
+    endif
+  endif
+
+  set (ca, "view", [0, 90], "xlimmode", "manual", "ylimmode", "manual",
+       "xlim", xlim, "ylim", ylim);
+
+  if (strcmp (get (ca, "nextplot"), "replace"))
+    set (ca, "ydir", "reverse");
+  endif
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/image/__img_via_file__.m b/scripts/image/__img_via_file__.m
new file mode 100644
index 0000000..3369ea5
--- /dev/null
+++ b/scripts/image/__img_via_file__.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2006, 2007, 2009 Søren Hauberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## Undocumented internal function.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __img_via_file__ (@var{x}, @var{y}, @var{im}, @var{zoom}, @var{command})
+## Undocumented internal function.
+## @end deftypefn
+
+## Display an image by saving it to a file in PPM format and launching
+## @var{command}.
+##
+## The @var{command} must be a format string containing @code{%s} and
+## possibly @code{%f}.  The @code{%s} will be replaced by the filename
+## of the image, and the @code{%f} will be replaced by @var{zoom}. The
+## @var{x} and @var{y} arguments are ignored.
+
+function __img_via_file__ (x, y, im, zoom, command)
+
+  ppm_name = tmpnam ();
+  saveimage (ppm_name, im, "ppm");
+
+  rm = sprintf ("rm -f \"%s\"", ppm_name);
+
+  if (isempty (command))
+    ## Different image viewer commands.
+    xv = sprintf ("xv -raw -expand %f \"%s\"", zoom, ppm_name);
+    xloadimage = sprintf ("xloadimage -zoom %f \"%s\"", zoom*100, ppm_name);
+    im_display = sprintf ("display -resize %f%% \"%s\"", zoom*100, ppm_name);
+  
+    ## Need to let the shell clean up the tmp file because we are putting
+    ## the viewer in the background.
+    status = system (sprintf ("( %s || %s || %s && %s ) > /dev/null 2>&1 &",
+                              im_display, xv, xloadimage, rm));
+  else
+    ## Does the command support zooming?
+    if (findstr (command, "%f"))
+      command = sprintf (command, zoom, ppm_name);
+    else
+      command = sprintf (command, ppm_name);
+    endif
+    status = system (sprintf ("( %s && %s) > /dev/null 2>&1 &", command, rm));
+  endif
+  
+  ## Did the system call fail?
+  if (status != 0)
+    error ("the image viewing command failed");
+  endif
+
+endfunction
diff --git a/scripts/image/autumn.m b/scripts/image/autumn.m
new file mode 100644
index 0000000..71e99d7
--- /dev/null
+++ b/scripts/image/autumn.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} autumn (@var{n})
+## Create color colormap.  This colormap is red through orange to yellow.
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = autumn (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("autumn: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [1, 0, 0];  
+  elseif (number > 1)
+    r = ones (number, 1);
+    g = (0:number - 1)' ./ (number - 1);
+    b = zeros (number, 1);
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/bone.m b/scripts/image/bone.m
new file mode 100644
index 0000000..4fddaf4
--- /dev/null
+++ b/scripts/image/bone.m
@@ -0,0 +1,55 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bone (@var{n})
+## Create color colormap.  This colormap is a gray colormap with a light 
+## blue tone.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = bone (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("bone: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0, 0];  
+  elseif (number > 1)
+    x = linspace (0, 1, number)';
+
+    r = (x < 3/4) .* (7/8 * x) + (x >= 3/4) .* (11/8 * x - 3/8);
+    g = (x < 3/8) .* (7/8 * x)\
+      + (x >= 3/8 & x < 3/4) .* (29/24 * x - 1/8)\
+      + (x >= 3/4) .* (7/8 * x + 1/8);
+    b = (x < 3/8) .* (29/24 * x) + (x >= 3/8) .* (7/8 * x + 1/8);
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+endfunction
diff --git a/scripts/image/brighten.m b/scripts/image/brighten.m
new file mode 100644
index 0000000..bf00b04
--- /dev/null
+++ b/scripts/image/brighten.m
@@ -0,0 +1,74 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{map_out} =} brighten (@var{map}, @var{beta})
+## @deftypefnx {Function File} {@var{map_out} =} brighten (@var{h}, @var{beta})
+## @deftypefnx {Function File} {@var{map_out} =} brighten (@var{beta})
+## Darkens or brightens the given colormap.  If the @var{map} argument 
+## is omitted, the function is applied to the current colormap.  The first
+## argument can also be a valid graphics handle @var{h}, in which case 
+## @code{brighten} is applied to the colormap associated with this handle.
+##
+## Should the resulting colormap @var{map_out} not be assigned, it will be
+## written to the current colormap.
+##
+## The argument @var{beta} should be a scalar between -1 and 1,
+## where a negative value darkens and a positive value brightens
+## the colormap.
+## @seealso{colormap}
+## @end deftypefn
+
+function Rmap = brighten (m, beta)
+  h = -1;
+  if (nargin == 1)
+    beta = m;
+    m = colormap;
+    h = gcf ();
+  elseif (nargin == 2)
+    if (ishandle (m))
+      h = m;
+      m = get (h, "colormap");
+    elseif (! is_matrix (m) || size (m, 2) != 3)
+      error ("brighten: first argument must be an Nx3 matrix or a handle");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (! isscalar (beta) || beta <= -1 || beta >= 1)
+    error ("brighten: beta must be a scalar in the range (-1,1)");
+  endif
+
+  if (beta > 0)
+    gamma = 1 - beta;
+  else
+    gamma = 1 / (1 + beta);
+  endif
+
+  if (nargout == 0)
+    if (ishandle (h))
+      set (h, "colormap", m .^ gamma);
+    else
+      colormap (m .^ gamma);
+    endif
+  else
+    Rmap = m .^ gamma;
+  endif
+
+endfunction
diff --git a/scripts/image/colormap.m b/scripts/image/colormap.m
new file mode 100644
index 0000000..766e11c
--- /dev/null
+++ b/scripts/image/colormap.m
@@ -0,0 +1,75 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2005,
+##               2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} colormap (@var{map})
+## @deftypefnx {Function File} {} colormap ("default")
+## Set the current colormap.
+##
+## @code{colormap (@var{map})} sets the current colormap to @var{map}.  The
+## color map should be an @var{n} row by 3 column matrix.  The columns
+## contain red, green, and blue intensities respectively.  All entries
+## should be between 0 and 1 inclusive.  The new colormap is returned.
+##
+## @code{colormap ("default")} restores the default colormap (the
+## @code{jet} map with 64 entries).  The default colormap is returned.
+##
+## With no arguments, @code{colormap} returns the current color map.
+## @seealso{jet}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function cmap = colormap (map)
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+
+    if (ischar (map))
+      if (strcmp (map, "default"))
+        map = jet (64);
+      else
+        map = feval (map);
+      endif
+    endif
+
+    if (! isempty (map))
+      if (columns (map) != 3)
+        error ("colormap: map must have 3 columns: [R,G,B]");
+      endif
+      if (min (min (map)) < 0 || max (max (map)) > 1)
+        error ("colormap: map must have values in [0,1]");
+      endif
+      ## Set the new color map
+      set (gcf (), "colormap", map);
+    endif
+
+  endif
+
+  ## Return current color map.
+  if (nargout > 0 || (nargout == 0 && nargin == 0))
+    cmap = get (gcf (), "colormap");
+  endif
+
+endfunction
diff --git a/scripts/image/contrast.m b/scripts/image/contrast.m
new file mode 100644
index 0000000..bebe7ae
--- /dev/null
+++ b/scripts/image/contrast.m
@@ -0,0 +1,50 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} contrast (@var{x}, @var{n})
+## Return a gray colormap that maximizes the contrast in an image.  The
+## returned colormap will have @var{n} rows.  If @var{n} is not defined
+## then the size of the current colormap is used instead.
+## @seealso{colormap}
+## @end deftypefn
+
+function map = contrast (x, n)
+
+  if (nargin == 1)
+    n = rows (colormap);
+  elseif (nargin == 2)
+    if (! isscalar (n))
+      error ("contrast: n must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  x = x(:);
+  minx = min (x);
+  map = find (diff (sort ([round(n * ((x - minx) ./ (max(x) - minx))); [0:n]'])));
+  minm = min (map);
+  map = (map - minm) ./ (max (map) - minm);
+  map = [map, map, map];
+endfunction
+
+%!assert (contrast(1:100,10),[([0:9]/9)',([0:9]/9)',([0:9]/9)'],1e-10)
+%!demo
+%! image (reshape (1:100, 10, 10))
+%! colormap (contrast (1:100,10))
diff --git a/scripts/image/cool.m b/scripts/image/cool.m
new file mode 100644
index 0000000..ec13f79
--- /dev/null
+++ b/scripts/image/cool.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cool (@var{n})
+## Create color colormap.  The colormap is cyan to magenta.  The argument 
+## @var{n} should be a scalar.  If it is omitted, the length of the current
+## colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = cool (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("cool: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 1, 1];  
+  elseif (number > 1)
+    r = (0:number - 1)' ./ (number - 1);
+    g = 1 - r;
+    b = ones (number, 1);
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/copper.m b/scripts/image/copper.m
new file mode 100644
index 0000000..632d912
--- /dev/null
+++ b/scripts/image/copper.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} copper (@var{n})
+## Create color colormap.  This colormap is black to a light copper tone.
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = copper (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("copper: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0, 0];  
+  elseif (number > 1)
+    x = linspace (0, 1, number)';
+    r = (x < 4/5) .* (5/4 * x) + (x >= 4/5);
+    g = 4/5 * x;
+    b = 1/2 * x;
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/default.img b/scripts/image/default.img
new file mode 100644
index 0000000..ec46f8e
--- /dev/null
+++ b/scripts/image/default.img
@@ -0,0 +1,178 @@
+# name: map
+# type: matrix
+# rows: 64
+# columns: 3
+0.00000 0.00000 0.00000
+0.01587 0.01587 0.01587
+0.03175 0.03175 0.03175
+0.04762 0.04762 0.04762
+0.06349 0.06349 0.06349
+0.07937 0.07937 0.07937
+0.09524 0.09524 0.09524
+0.11111 0.11111 0.11111
+0.12698 0.12698 0.12698
+0.14286 0.14286 0.14286
+0.15873 0.15873 0.15873
+0.17460 0.17460 0.17460
+0.19048 0.19048 0.19048
+0.20635 0.20635 0.20635
+0.22222 0.22222 0.22222
+0.23810 0.23810 0.23810
+0.25397 0.25397 0.25397
+0.26984 0.26984 0.26984
+0.28571 0.28571 0.28571
+0.30159 0.30159 0.30159
+0.31746 0.31746 0.31746
+0.33333 0.33333 0.33333
+0.34921 0.34921 0.34921
+0.36508 0.36508 0.36508
+0.38095 0.38095 0.38095
+0.39683 0.39683 0.39683
+0.41270 0.41270 0.41270
+0.42857 0.42857 0.42857
+0.44444 0.44444 0.44444
+0.46032 0.46032 0.46032
+0.47619 0.47619 0.47619
+0.49206 0.49206 0.49206
+0.50794 0.50794 0.50794
+0.52381 0.52381 0.52381
+0.53968 0.53968 0.53968
+0.55556 0.55556 0.55556
+0.57143 0.57143 0.57143
+0.58730 0.58730 0.58730
+0.60317 0.60317 0.60317
+0.61905 0.61905 0.61905
+0.63492 0.63492 0.63492
+0.65079 0.65079 0.65079
+0.66667 0.66667 0.66667
+0.68254 0.68254 0.68254
+0.69841 0.69841 0.69841
+0.71429 0.71429 0.71429
+0.73016 0.73016 0.73016
+0.74603 0.74603 0.74603
+0.76190 0.76190 0.76190
+0.77778 0.77778 0.77778
+0.79365 0.79365 0.79365
+0.80952 0.80952 0.80952
+0.82540 0.82540 0.82540
+0.84127 0.84127 0.84127
+0.85714 0.85714 0.85714
+0.87302 0.87302 0.87302
+0.88889 0.88889 0.88889
+0.90476 0.90476 0.90476
+0.92063 0.92063 0.92063
+0.93651 0.93651 0.93651
+0.95238 0.95238 0.95238
+0.96825 0.96825 0.96825
+0.98413 0.98413 0.98413
+1.00000 1.00000 1.00000
+# name: X
+# type: matrix
+# rows: 53
+# columns: 40
+35 35 36 37 35 36 36 35 34 35 36 36 37 38 37 37 39 38 38 40
+38 40 38 38 39 39 39 33 16 12 13 13 11 11 13 10 10 11 14 19
+35 35 35 36 35 36 36 35 35 35 36 35 36 37 37 37 38 37 38 38
+38 38 39 39 38 38 39 33 16 13 11 10 14 12 12 12 12  9 11 18
+35 36 36 35 37 36 35 37 36 35 36 36 36 37 37 39 37 38 38 38
+40 38 40 38 39 39 38 33 17 12 12 13 10 10 13 12 12 12 11 16
+36 35 37 36 37 34 36 36 35 35 36 36 36 37 37 37 38 38 38 38
+40 38 38 39 38 38 39 33 18 11 12 12 12  9 11 11 11  9 11 15
+36 36 35 36 35 36 37 36 36 36 36 36 37 37 38 38 37 38 38 37
+38 37 38 38 37 39 37 33 18 11 13 13 11 10 11 11 11 12 11 16
+35 36 36 37 37 37 36 36 36 36 37 36 38 38 36 34 32 29 27 25
+22 22 22 25 30 35 37 33 17 11 13 13 11 11 11 13 13 11 11 13
+36 37 36 36 37 36 36 36 37 37 37 36 35 33 28 27 20 15 13 12
+10 11 13 12 16 17 23 28 15 12 12 13 11 11 13 11 11 12 10 14
+35 36 35 37 37 38 37 37 37 37 36 35 34 28 19 14 13 13 12 10
+11 12 12 11 12 12 12 12 10 12 13 12 11 12 12 12 12 12  9 11
+35 35 37 37 37 36 38 37 35 37 35 27 18 14 13 11 10 11 11 13
+11 11 11 11 12 12 11 14 11 12 13 12 12 11 11 13  9 13  9 13
+30 35 36 37 36 37 35 36 38 33 23 16 11 12 11 12 11 12 13 13
+11 11 11 11 12 12 12 11 10 12 13 13 11 11 11 13 10 12 10 12
+27 33 34 37 38 36 37 36 32 22 14 11 11  8  9 12 10 12 13 13
+11 10  9 10 10 11 11  9  9 10 13 13 11 12 12 11 13 11 12 11
+21 28 36 36 37 37 36 33 16 12 12 11 10 11 11 11 11 13 15 11
+12 12 10 10 14 13 13 10 11 11 11 10 12 13 12 11 10 12 14 13
+18 25 33 36 37 37 33 19 13 12 11  9  9 11 11 11 10 13 11 11
+12 14 14 12 14 13 13 11 11  9 10 11 12 12 12 12 12 13 13 13
+16 21 31 36 36 33 19 15  9 10 12 11 11 10 12 10  8 11 13 13
+13 12 11 11 13 11 10 12 14 13 12 11 12 13 11 13 13 10  9 13
+14 19 26 34 33 21 13 13  9 11 12 11 12  9 11 10 11  9 13 13
+13 13 12 12 14 14 11 14 15 16 15 12 12 12 12 11 11 11 10 15
+11 18 25 32 24 14 11 10 12 14 13 13 12 13 14 11 10 12 14 17
+17 14 14 19 20 17 15 16 14 16 18 10 11 13 12 11 11 12  9 15
+13 15 22 26 17 13 13 13 13 12 15 16 17 19 18 18 20 22 22 25
+25 24 21 23 24 20 17 17 15 15 17 14 14 11 12 12 12  9 10 14
+12 14 22 22 12 13 15 17 15 15 20 23 26 26 24 27 29 29 31 33
+33 30 28 29 26 23 23 21 18 17 16 14 13 11 13 13 11 11  9 13
+11 14 21 19 12 12 17 20 17 18 24 30 34 33 33 34 35 36 40 39
+37 33 36 36 32 29 28 25 24 19 17 14 13 12 11 12 10 12 11 14
+10 15 21 17 13 13 18 22 22 25 32 37 38 39 39 41 38 43 46 44
+42 39 40 40 40 38 35 30 27 21 18 15 12 13 13 11 11 12 13 14
+11 16 21 18 12 11 19 23 26 32 35 39 40 41 41 43 43 45 45 44
+42 41 40 40 41 40 37 33 28 26 22 15 14 11 11 13 12 13 11 12
+12 16 22 19 11 10 16 22 27 33 38 40 42 43 43 44 43 44 44 44
+44 44 44 44 44 42 40 35 33 28 24 18 12 12 13 12 12 12 11 11
+14 18 24 19 13 10 16 21 26 33 39 41 44 43 44 45 44 46 46 47
+46 48 45 44 44 42 40 38 35 31 28 18  9 12 12 11 11 12 12 12
+13 19 22 15 11  9 14 21 26 34 40 43 45 43 45 46 47 49 50 49
+48 47 46 46 45 43 43 40 36 33 28 19 10 12 12 11 11 12 11 11
+17 20 19 11 13 10 15 21 28 35 40 43 44 45 46 46 48 48 49 49
+49 49 48 47 44 45 43 40 39 36 30 18 10 13 10 11 11 12 11 12
+19 27 15 14 13 10 14 22 32 37 41 44 44 46 46 46 48 49 49 49
+49 49 48 47 47 46 45 45 41 37 28 16 10 13 11 13 10 14 14 13
+31 31 16 13 13 10 16 24 30 36 39 41 44 45 47 47 48 49 49 49
+49 49 49 49 48 47 46 43 38 31 23 15 10  9 11 11 12 13 12 12
+42 40 24 15 13 14 20 24 29 34 38 42 43 45 46 48 49 50 49 50
+49 48 48 47 46 46 45 41 35 23 15 12 11 11 12 12  9 14 13 13
+53 55 38 18 16 19 20 25 28 36 42 44 43 44 45 47 48 50 51 50
+48 47 48 46 46 43 41 40 36 24 15 12 13 13 12 11 11 12 13 12
+61 61 49 22 21 23 25 27 35 40 44 46 44 40 39 45 47 50 51 47
+46 45 45 45 47 43 38 35 32 30 21 17 12 11 12 13 13 12 11 11
+62 61 54 32 29 32 29 30 34 35 36 38 36 36 37 43 49 53 49 43
+41 41 43 44 46 43 40 36 31 29 25 23 16 13 12 13 15 11  9  9
+62 62 60 42 36 38 35 32 32 30 19 17 19 31 33 40 48 53 47 40
+40 41 44 43 46 41 39 38 38 34 29 27 19 15 17 31 31 18 11 14
+62 61 61 46 38 37 34 38 42 37 32 37 38 37 35 39 43 46 44 39
+38 43 45 27 20 21 29 37 41 39 39 32 23 18 31 41 36 25 13 18
+60 61 61 45 39 34 33 40 45 44 44 42 41 40 36 38 41 41 39 40
+40 44 47 42 32 30 37 42 43 44 41 36 24 21 38 54 54 47 35 26
+59 61 61 45 39 35 35 39 43 43 45 44 45 45 38 41 44 43 41 35
+46 46 48 52 50 47 47 45 43 42 42 37 25 26 53 62 61 60 55 54
+45 52 56 44 37 37 36 41 41 44 44 47 49 44 43 46 49 48 42 40
+47 50 48 47 49 48 46 44 42 41 41 38 29 34 60 62 62 61 59 58
+39 38 42 38 36 35 38 41 38 45 46 50 51 47 46 46 44 46 45 41
+45 53 52 48 47 47 45 44 43 42 43 38 32 43 61 62 61 62 62 62
+43 40 35 33 34 37 37 42 43 43 46 50 51 48 45 44 46 47 44 43
+50 52 54 51 48 46 46 43 43 43 40 39 36 52 61 62 62 62 62 62
+38 40 40 31 32 35 38 39 41 44 45 50 49 47 44 44 43 43 43 48
+52 53 51 50 48 45 45 43 43 43 40 41 47 59 62 62 61 62 63 62
+38 40 40 37 32 36 34 34 43 43 45 48 49 47 42 44 43 43 43 46
+50 50 52 49 45 47 43 43 42 41 41 43 51 61 61 61 62 63 63 62
+41 38 39 37 35 30 35 38 38 42 44 45 45 44 38 38 40 41 43 44
+48 50 49 48 45 44 43 41 41 39 39 44 60 61 61 62 63 63 63 63
+44 40 36 38 34 30 31 33 37 39 42 45 45 37 30 29 31 33 40 43
+44 46 47 46 45 42 41 40 35 38 41 56 60 60 62 63 63 63 63 63
+48 46 41 36 32 29 31 32 38 41 44 44 39 27 25 28 29 31 30 35
+39 43 45 46 41 41 37 35 31 36 44 59 61 62 63 63 63 63 63 63
+48 47 45 42 37 30 26 29 35 40 44 44 34 28 27 29 29 29 29 35
+44 45 46 44 41 38 35 30 29 38 58 62 63 63 63 63 63 63 62 61
+49 48 48 46 41 37 31 35 32 33 41 40 32 29 29 29 29 31 33 36
+44 44 44 42 41 33 35 30 33 56 60 58 60 62 60 62 62 61 61 59
+47 49 48 48 45 42 38 46 41 34 32 34 35 33 33 33 37 37 38 39
+36 40 39 39 39 39 37 36 43 47 45 45 50 53 56 60 62 61 59 55
+45 47 50 46 45 44 40 44 47 43 39 39 39 38 38 38 40 39 39 34
+36 39 43 41 47 49 51 51 51 49 47 45 42 43 45 56 62 58 50 49
+43 44 47 44 45 45 39 39 46 45 43 50 50 45 38 41 43 38 31 36
+43 49 50 50 53 57 56 56 56 54 53 52 49 47 44 49 57 51 52 51
+39 48 46 42 42 46 36 33 36 40 44 49 49 51 44 47 53 50 46 37
+43 49 53 54 57 57 58 60 57 58 58 57 54 51 49 47 47 51 53 51
+46 52 47 41 47 45 38 45 52 48 43 44 47 48 46 47 54 54 49 43
+42 44 47 51 53 55 55 56 58 57 60 57 59 58 55 51 49 52 50 47
+50 50 44 43 51 45 41 57 62 61 57 51 48 47 48 48 54 52 52 52
+51 50 47 46 48 51 53 54 51 52 53 56 57 58 60 54 48 52 48 47
+44 41 41 49 52 43 42 60 62 62 62 63 61 61 61 60 52 53 54 55
+56 53 51 51 52 51 48 47 45 46 49 50 54 57 58 53 48 47 47 48
+30 35 46 50 47 37 45 60 61 62 63 63 63 63 63 63 61 54 52 54
+55 54 54 55 56 55 54 52 46 44 45 48 51 53 55 53 46 43 47 49
diff --git a/scripts/image/flag.m b/scripts/image/flag.m
new file mode 100644
index 0000000..65e8862
--- /dev/null
+++ b/scripts/image/flag.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} flag (@var{n})
+## Create color colormap.  This colormap cycles through red, white, blue 
+## and black.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+## flag(number) gives a colormap consists of red, white, blue and black
+## changing with each index
+
+function map = flag (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("flag: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  p = [1, 0, 0; 1, 1, 1; 0, 0, 1; 0, 0, 0];
+  if (rem(number,4) == 0)
+    map = kron (ones (number / 4, 1), p);
+  else
+    m1 = kron (ones (fix (number / 4), 1), p);
+    m2 = p(1:rem (number, 4), :);
+    map = [m1; m2];
+  endif
+
+endfunction
diff --git a/scripts/image/gmap40.m b/scripts/image/gmap40.m
new file mode 100644
index 0000000..36a130c
--- /dev/null
+++ b/scripts/image/gmap40.m
@@ -0,0 +1,49 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gmap40 (@var{n})
+## Create a color colormap.  The colormap is red, green, blue, yellow,
+## magenta and cyan.  These are the colors that are allowed with patch
+## objects using gnuplot 4.0, and so this colormap function is specially
+## designed for users of gnuplot 4.0.  The argument @var{n} should be 
+## a scalar.  If it is omitted, a length of 6 is assumed.  Larger values
+## of @var{n} result in a repetition of the above colors
+## @seealso{colormap}
+## @end deftypefn
+
+function map = gmap40 (number)
+
+  if (nargin == 0)
+    number = 6;
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("gmap40: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number >= 1)
+    map = repmat ([1, 0, 0; 0, 1, 0; 0, 0, 1; 1, 1, 0; 1, 0, 1; 0, 1, 1],
+		  ceil (number / 6), 1) (1:number, :);
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/gray.m b/scripts/image/gray.m
new file mode 100644
index 0000000..3083948
--- /dev/null
+++ b/scripts/image/gray.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gray (@var{n})
+## Return a gray colormap with @var{n} entries corresponding to values from
+## 0 to @var{n}-1.  The argument @var{n} should be a scalar.  If it is
+## omitted, the length of the current colormap or 64 is assumed.
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function map = gray (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("gray: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  gr = [0:(number-1)]';
+
+  map = [ gr, gr, gr ] / (number - 1);
+
+endfunction
diff --git a/scripts/image/gray2ind.m b/scripts/image/gray2ind.m
new file mode 100644
index 0000000..e44c35e
--- /dev/null
+++ b/scripts/image/gray2ind.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{img}, @var{map}] =} gray2ind (@var{I}, @var{n})
+## Convert a gray scale intensity image to an Octave indexed image.
+## The indexed image will consist of @var{n} different intensity values.  If not
+## given @var{n} will default to 64.
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function [X, map] = gray2ind (I, n = 64)
+  ## Check input
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+  C = class(I);
+  if (! ismatrix (I) || ndims (I) != 2)
+    error ("gray2ind: first input argument must be a gray scale image");
+  endif
+  if (! isscalar (n) || n < 0)
+    error ("gray2ind: second input argument must be a positive integer");
+  endif
+  ints = {"uint8", "uint16", "int8", "int16"};
+  floats = {"double", "single"};
+  if (! ismember (C, {ints{:}, floats{:}}))
+    error ("gray2ind: invalid data type '%s'", C);
+  endif
+  if (ismember (C, floats) && (min (I(:)) < 0 || max (I(:)) > 1))
+    error ("gray2ind: floating point images may only contain values between 0 and 1");
+  endif
+
+  ## Convert data
+  map = gray (n);
+  ## If @var{I} is an integer matrix convert it to a double matrix with values in [0, 1]
+  if (ismember (C, ints))
+    low = double (intmin (C));
+    high = double (intmax (C));
+    I = (double (I) - low) / (high - low);
+  endif
+  X = round (I*(n-1)) + 1;
+
+endfunction
diff --git a/scripts/image/hot.m b/scripts/image/hot.m
new file mode 100644
index 0000000..e6e4c02
--- /dev/null
+++ b/scripts/image/hot.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hot (@var{n})
+## Create color colormap.  This colormap is black through dark red, red, 
+## orange, yellow to white.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = hot (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1) 
+	if (! isscalar (number))
+      error ("hot: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0, 0];  
+  elseif (number > 1)
+    x = linspace (0, 1, number)';
+    r = (x < 2/5) .* (5/2 * x) + (x >= 2/5);
+    g = (x >= 2/5 & x < 4/5) .* (5/2 * x - 1) + (x >= 4/5);
+    b = (x >= 4/5) .* (5*x - 4);
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/hsv.m b/scripts/image/hsv.m
new file mode 100644
index 0000000..fe31e1c
--- /dev/null
+++ b/scripts/image/hsv.m
@@ -0,0 +1,55 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hsv (@var{n})
+## Create color colormap.  This colormap is red through yellow, green,
+## cyan, blue, magenta to red.  It is obtained by linearly varying the
+## hue through all possible values while keeping constant maximum
+## saturation and value and is equivalent to
+## @code{hsv2rgb ([linspace(0,1,N)', ones(N,2)])}.
+##
+## The argument @var{n} should be a scalar.  If it is omitted, the
+## length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = hsv (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("hsv: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [1, 0, 0];  
+  elseif (number > 1)
+    h = linspace (0, 1, number)';
+    map = hsv2rgb ([h, ones(number, 1), ones(number, 1)]);
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/hsv2rgb.m b/scripts/image/hsv2rgb.m
new file mode 100644
index 0000000..a24368e
--- /dev/null
+++ b/scripts/image/hsv2rgb.m
@@ -0,0 +1,88 @@
+## Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+##               Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{rgb_map} =} hsv2rgb (@var{hsv_map})
+## Transform a colormap or image from the hsv space to the rgb space. 
+## @seealso{rgb2hsv}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Adapted-by: jwe
+
+function rgb_map = hsv2rgb (hsv_map)
+
+## Each color value x = (r,g,b) is calculated with
+## x = (1-sat)*val+sat*val*f_x(hue)
+## where f_x(hue) is a piecewise defined function for
+## each color with f_r(hue-2/3) = f_g(hue) = f_b(hue-1/3).
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  ## If we have an image convert it into a color map.
+  if (ismatrix (hsv_map) && ndims (hsv_map) == 3)
+    is_image = true;
+    Sz = size (hsv_map);
+    hsv_map = [hsv_map(:,:,1)(:), hsv_map(:,:,2)(:), hsv_map(:,:,3)(:)];
+    ## Convert to a double image.
+    if (isinteger (hsv_map))
+      C = class (hsv_map);
+      low = double (intmin (C));
+      high = double (intmax (C));
+      hsv_map = (double (hsv_map) - low) / (high - low);
+    endif
+  else
+    is_image = false;
+  endif
+
+  if (! ismatrix (hsv_map) || columns (hsv_map) != 3)
+    error ("hsv2rgb: argument must be a matrix of size nx3");
+  endif
+
+  ## set values <0 to 0 and >1 to 1
+  hsv_map = (hsv_map >= 0 & hsv_map <= 1) .* hsv_map \
+      + (hsv_map < 0) .* 0 + (hsv_map > 1);
+
+  ## fill rgb map with v*(1-s)
+  rgb_map = kron ([1, 1, 1], hsv_map(:,3) .* (1 - hsv_map(:,2)));
+
+  ## red(hue-2/3)=green(hue)=blue(hue-1/3)
+  ## apply modulo 1 for red and blue 
+  t = hsv_map(:,1);
+  tp = t';
+  hue = [(tp - 2/3 - floor (t - 2/3)');
+         tp;
+         (tp - 1/3 - floor (t - 1/3)')]';
+
+  ## factor s*v -> f
+  f = kron ([1, 1, 1], hsv_map(:,2)) .* kron ([1, 1, 1], hsv_map(:,3));
+
+  ## add s*v* hue-function to rgb map
+  rgb_map = rgb_map +  f .* (6 * (hue < 1/6) .* hue
+			     + (hue >= 1/6 & hue < 1/2)
+			     + (hue >= 1/2 & hue < 2/3) .* (4 - 6 * hue));
+
+  ## If input was an image, convert it back into one.
+  if (is_image)
+    rgb_map = reshape (rgb_map, Sz);
+  endif
+
+endfunction
diff --git a/scripts/image/image.m b/scripts/image/image.m
new file mode 100644
index 0000000..b25f850
--- /dev/null
+++ b/scripts/image/image.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+##               2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} image (@var{img})
+## @deftypefnx {Function File} {} image (@var{x}, @var{y}, @var{img})
+## Display a matrix as a color image.  The elements of @var{x} are indices
+## into the current colormap, and the colormap will be scaled so that the
+## extremes of @var{x} are mapped to the extremes of the colormap.
+##
+## It first tries to use @code{gnuplot}, then @code{display} from 
+## @code{ImageMagick}, then @code{xv}, and then @code{xloadimage}.
+## The actual program used can be changed using the @code{image_viewer}
+## function.
+##
+## The axis values corresponding to the matrix elements are specified in
+## @var{x} and @var{y}.  If you're not using gnuplot 4.2 or later, these
+## variables are ignored.
+## @seealso{imshow, imagesc, colormap, image_viewer}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function retval = image (varargin)
+
+  [ax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:});
+
+  firstnonnumeric = Inf;
+  for i = 1 : nargin
+    if (! isnumeric (varargin{i}))
+      firstnonnumeric = i;
+      break;
+    endif
+  endfor
+
+  if (nargin == 0 || firstnonnumeric == 1)
+    img = loadimage ("default.img");
+    x = y = [];
+  elseif (nargin == 1 || firstnonnumeric == 2)
+    img = varargin{1};
+    x = y = [];
+  elseif (nargin == 2 || firstnonnumeric == 3)
+    print_usage ();
+  else
+    x = varargin{1};
+    y = varargin{2};
+    img = varargin{3};
+    firstnonnumeric = 4;
+  endif
+
+  oldax = gca ();
+  unwind_protect
+    axes (ax);
+    h = __img__ (x, y, img, varargin {firstnonnumeric:end});
+    set (ax, "layer", "top");
+  unwind_protect_cleanup
+    axes (oldax);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = h;
+  endif
+
+endfunction
diff --git a/scripts/image/image_viewer.m b/scripts/image/image_viewer.m
new file mode 100644
index 0000000..ffcec25
--- /dev/null
+++ b/scripts/image/image_viewer.m
@@ -0,0 +1,121 @@
+## Copyright (C) 2006, 2007, 2008, 2009 S�ren Hauberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{fcn}, @var{default_zoom}] =} image_viewer (@var{fcn}, @var{default_zoom})
+## Change the program or function used for viewing images and return the
+## previous values.
+##
+## When the @code{image} or @code{imshow} function is called it will
+## launch an external program to display the image.  The default behavior
+## is to use gnuplot if the installed version supports image viewing,
+## and otherwise try the programs @code{display}, @code{xv}, and
+## @code{xloadimage}.  Using this function it is possible to change that
+## behavior.
+##
+## When called with one input argument images will be displayed by saving
+## the image to a file and the system command @var{command} will be called
+## to view the image.  The @var{command} must be a string containing
+## @code{%s} and possibly @code{%f}.  The @code{%s} will be replaced by
+## the filename of the image, and the @code{%f} will (if present) be
+## replaced by the zoom factor given to the @code{image} function.
+## For example,
+## @example
+## image_viewer ("eog %s");
+## @end example
+## changes the image viewer to the @code{eog} program.
+##
+## With two input arguments, images will be displayed by calling
+## the function @var{function_handle}.  For example,
+## @example
+## image_viewer (data, @@my_image_viewer);
+## @end example
+## sets the image viewer function to @code{my_image_viewer}.  The image
+## viewer function is called with
+## @example
+## my_image_viewer (@var{x}, @var{y}, @var{im}, @var{zoom}, @var{data})
+## @end example
+## where @var{x} and @var{y} are the axis of the image, @var{im} is the image
+## variable, and @var{data} is extra user-supplied data to be passed to
+## the viewer function.
+##
+## With three input arguments it is possible to change the zooming.
+## Some programs (like @code{xloadimage}) require the zoom factor to be
+## between 0 and 100, and not 0 and 1 like Octave assumes.  This is
+## solved by setting the third argument to 100.
+##
+## @seealso{image, imshow}
+## @end deftypefn
+
+function [ocmd, ofcn, ozoom] = image_viewer (cmd, fcn, zoom)
+
+  persistent view_cmd;
+  persistent view_fcn;
+  persistent view_zoom = 1;
+
+  if (isempty (view_fcn))
+    if (isempty (view_cmd)
+	&& compare_versions (__gnuplot_version__ (), "4.0", ">"))
+      view_fcn = "gnuplot_internal";
+    else
+      view_fcn = @__img_via_file__;
+    endif
+  endif
+
+  if (nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    ocmd = view_cmd;
+    ofcn = view_fcn;
+    ozoom = view_zoom;
+  endif
+
+  if (nargin > 0)
+
+    if (nargin < 3)
+      zoom = 1;
+      if (nargin < 2)
+	fcn = [];
+      endif
+    endif
+
+    view_cmd = cmd;
+    view_fcn = fcn;
+    view_zoom = zoom;
+
+    if (nargin > 1)
+      if (isa (fcn, "function_handle"))
+	view_fcn = fcn;
+      else
+	error ("image_viewer: expecting second argument to be a function handle");
+      endif
+    endif
+
+    if (nargin > 2)
+      if (isnumeric (zoom) && isscalar (zoom) && isreal (zoom))
+	view_zoom = zoom;
+      else
+	error ("image_viewer: expecting third argument to be a real scalar");
+      endif
+    endif
+
+  endif
+
+endfunction
diff --git a/scripts/image/imagesc.m b/scripts/image/imagesc.m
new file mode 100644
index 0000000..a41e577
--- /dev/null
+++ b/scripts/image/imagesc.m
@@ -0,0 +1,121 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+##               2004, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} imagesc (@var{a})
+## @deftypefnx {Function File} {} imagesc (@var{x}, @var{y}, @var{a})
+## @deftypefnx {Function File} {} imagesc (@dots{}, @var{limits})
+## @deftypefnx {Function File} {} imagesc (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} imagesc (@dots{})
+## Display a scaled version of the matrix @var{a} as a color image.  The
+## colormap is scaled so that the entries of the matrix occupy the entire
+## colormap.  If @var{limits} = [@var{lo}, @var{hi}] are given, then that
+## range is set to the 'clim' of the current axes.
+##
+## The axis values corresponding to the matrix elements are specified in
+## @var{x} and @var{y}, either as pairs giving the minimum and maximum
+## values for the respective axes, or as values for each row and column
+## of the matrix @var{a}.
+##
+## @seealso{image, imshow, caxis}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function retval = imagesc (varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  elseif (isscalar (varargin{1}) && ishandle (varargin{1}))
+    h = varargin{1};
+    if (! strcmp (get (h, "type"), "axes"))
+      error ("imagesc: expecting first argument to be an axes object");
+    endif
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      tmp = __imagesc__ (h, varargin{2:end});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  else
+    tmp = __imagesc__ (gca (), varargin{:});
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+function ret = __imagesc__ (ax, x, y, A, limits, DEPRECATEDZOOM)
+
+  ## Deprecated zoom.  Remove this hunk of code if old zoom argument
+  ## is outmoded.
+  if ((nargin == 3 && isscalar (y))
+      || (nargin == 4 && (isscalar (y) || isscalar (A)))
+      || (nargin == 5 && isscalar (limits))
+      || nargin == 6)
+    warning ("image: zoom argument ignored -- use GUI features");
+  endif
+  if (nargin == 6)
+    if (isscalar (limits))
+      limits = DEPRECATEDZOOM;
+    endif
+    nargin = 5;
+  endif
+  if (nargin == 5 && isscalar (limits))
+    nargin = 4;
+  endif
+  if (nargin == 4 && (isscalar (y) || isscalar (A)))
+    if (isscalar (y))
+      y = A;
+    endif
+    nargin = 3;
+  endif
+  if (nargin == 3 && isscalar (y))
+    nargin = 2;
+  endif
+
+  if (nargin < 2 || nargin > 5)
+    print_usage ();
+  elseif (nargin == 2)
+    A = x;
+    x = y = limits = [];
+  elseif (nargin == 3)
+    A = x;
+    limits = y;
+    x = y = [];
+  elseif (nargin == 4 && ! isscalar (x) && ! isscalar (y) && ! isscalar (A))
+    limits = [];
+  endif
+
+  ret = image (ax, x, y, A);
+  set (ret, "cdatamapping", "scaled")
+
+  ## use given limits or guess them from the matrix
+  if (length (limits) == 2 && limits(2) >= limits(1))
+    set (ax, "clim", limits);
+  elseif (! isempty (limits))
+    error ("expected data limits to be [lo, hi]");
+  endif
+
+endfunction
diff --git a/scripts/image/imfinfo.m b/scripts/image/imfinfo.m
new file mode 100644
index 0000000..d832be9
--- /dev/null
+++ b/scripts/image/imfinfo.m
@@ -0,0 +1,140 @@
+## Copyright (C) 2008, 2009 Soren Hauberg <hauberg at gmail.com>
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{info} =} imfinfo (@var{filename})
+## @deftypefnx {Function File} {@var{info} =} imfinfo (@var{url})
+## Read image information from a file.
+##
+## @code{imfinfo} returns a structure containing information about the image
+## stored in the file @var{filename}.  The output structure contains the
+## following fields.
+##
+## @table @samp
+## @item Filename
+## The full name of the image file.
+## @item FileSize
+## Number of bytes of the image on disk
+## @item FileModDate
+## Date of last modification to the file.
+## @item Height
+## Image height in pixels.
+## @item Width
+## Image Width in pixels.
+## @item BitDepth
+## Number of bits per channel per pixel.
+## @item Format
+## Image format (e.g., @code{"jpeg"}).
+## @item LongFormat
+## Long form image format description.
+## @item XResolution
+## X resolution of the image.
+## @item YResolution
+## Y resolution of the image.
+## @item TotalColors
+## Number of unique colors in the image.
+## @item TileName
+## Tile name.
+## @item AnimationDelay
+## Time in 1/100ths of a second (0 to 65535) which must expire before displaying
+## the next image in an animated sequence.
+## @item AnimationIterations
+## Number of iterations to loop an animation (e.g., Netscape loop extension) for.
+## @item ByteOrder
+## Endian option for formats that support it.  Is either @code{"little-endian"},
+## @code{"big-endian"}, or @code{"undefined"}.
+## @item Gamma
+## Gamma level of the image.  The same color image displayed on two different
+## workstations may look different due to differences in the display monitor.
+## @item Matte
+## @code{true} if the image has transparency.
+## @item ModulusDepth
+## Image modulus depth (minimum number of bits required to support red/green/blue
+## components without loss of accuracy).
+## @item Quality
+## JPEG/MIFF/PNG compression level.
+## @item QuantizeColors
+## Preferred number of colors in the image.
+## @item ResolutionUnits
+## Units of image resolution.  Is either @code{"pixels per inch"},
+## @code{"pixels per centimeter"}, or @code{"undefined"}.
+## @item ColorType
+## Image type.  Is either @code{"grayscale"}, @code{"indexed"}, @code{"truecolor"},
+## or @code{"undefined"}.
+## @item View
+## FlashPix viewing parameters.
+## @end table
+##
+## @seealso{imread, imwrite}
+## @end deftypefn
+
+function info = imfinfo (filename)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (!ischar (filename))
+    error ("imfinfo: filename must be a string");
+  endif
+
+  filename = tilde_expand (filename);
+
+  delete_file = false;
+
+  unwind_protect
+
+    fn = file_in_path (IMAGE_PATH, filename);
+
+    if (isempty (fn))
+
+      ## Couldn't find file. See if it's an URL.
+
+      tmp = tmpnam ();
+
+      [fn, status, msg] = urlwrite (filename, tmp);
+
+      if (! status)
+	error ("imfinfo: cannot find %s", filename);
+      endif
+
+      if (! isempty (fn))
+	delete_file = true;
+      endif
+
+    endif
+
+    [statinfo, err, msg] = stat (fn);
+    if (err != 0)
+      error ("imfinfo: error reading '%s': %s", fn, msg);
+    endif
+
+    time_stamp = strftime ("%e-%b-%Y %H:%M:%S", localtime (statinfo.mtime));
+  
+    info = __magick_finfo__ (fn);
+    info.FileModDate = time_stamp;
+
+  unwind_protect_cleanup
+
+    if (delete_file)
+      unlink (fn);
+    endif
+
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/image/imread.m b/scripts/image/imread.m
new file mode 100644
index 0000000..4752ae2
--- /dev/null
+++ b/scripts/image/imread.m
@@ -0,0 +1,117 @@
+## Copyright (C) 2008, 2009 Thomas L. Scofield <scofield at calvin.edu>
+## Copyright (C) 2008 Kristian Rumberg <kristianrumberg at gmail.com>
+## Copyright (C) 2006 Thomas Weber <thomas.weber.mail at gmail.com>
+## Copyright (C) 2005 Stefan van der Walt <stefan at sun.ac.za>
+## Copyright (C) 2002 Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename})
+## Read images from various file formats.
+##
+## The size and numeric class of the output depends on the
+## format of the image.  A color image is returned as an
+## MxNx3 matrix.  Grey-level and black-and-white images are
+## of size MxN.
+## The color depth of the image determines the numeric
+## class of the output: "uint8" or "uint16" for grey
+## and color, and "logical" for black and white.
+##
+## @seealso{imwrite, imfinfo}
+## @end deftypefn
+
+function varargout = imread (filename, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (! ischar (filename))
+    error ("imread: filename must be a string");
+  endif
+
+  filename = tilde_expand (filename);
+
+  fn = file_in_path (IMAGE_PATH, filename);
+
+  if (isempty (fn))
+    error ("imread: cannot find %s", filename);
+  endif
+
+  try
+    [varargout{1:nargout}] = __magick_read__ (fn, varargin{:});
+  catch
+
+    magick_error = lasterr ();
+
+    img_field = false;
+    x_field = false;
+    map_field = false;
+
+    try
+      vars = load (fn);
+      if (isstruct (vars))
+	img_field = isfield (vars, "img");
+	x_field = isfield (vars, "X");
+	map_field = isfield (vars, "map");
+      endif
+    catch
+      error ("imread: invalid image file: %s", magick_error);
+    end_try_catch
+
+    if (map_field && (img_field || x_field))
+      varargout{2} = vars.map;
+      if (img_field)
+	varargout{1} = vars.img;
+      else
+	varargout{1} = vars.X;
+      endif
+    else
+      error ("imread: invalid Octave image file format");
+    endif
+
+  end_try_catch
+
+endfunction
+
+%!test 
+%! vpng = [ ...
+%!  137,  80,  78,  71,  13,  10,  26,  10,   0,   0, ...
+%!    0,  13,  73,  72,  68,  82,   0,   0,   0,   3, ...
+%!    0,   0,   0,   3,   8,   2,   0,   0,   0, 217, ...
+%!   74,  34, 232,   0,   0,   0,   1, 115,  82,  71, ...
+%!   66,   0, 174, 206,  28, 233,   0,   0,   0,   4, ...
+%!  103,  65,  77,  65,   0,   0, 177, 143,  11, 252, ...
+%!   97,   5,   0,   0,   0,  32,  99,  72,  82,  77, ...
+%!    0,   0, 122,  38,   0,   0, 128, 132,   0,   0, ...
+%!  250,   0,   0,   0, 128, 232,   0,   0, 117,  48, ...
+%!    0,   0, 234,  96,   0,   0,  58, 152,   0,   0, ...
+%!   23, 112, 156, 186,  81,  60,   0,   0,   0,  25, ...
+%!   73,  68,  65,  84,  24,  87,  99,  96,  96,  96, ...
+%!  248, 255, 255,  63, 144,   4,  81, 111, 101,  84, ...
+%!   16,  28, 160,  16,   0, 197, 214,  13,  34,  74, ...
+%!  117, 213,  17,   0,   0,   0,   0,  73,  69,  78, ...
+%!   68, 174,  66,  96, 130];
+%! fid = fopen('test.png', 'wb');
+%! fwrite(fid, vpng);
+%! fclose(fid);
+%! A = imread('test.png');
+%! delete('test.png');
+%! assert(A(:,:,1), uint8 ([0, 255, 0; 255, 237, 255; 0, 255, 0]));
+%! assert(A(:,:,2), uint8 ([0, 255, 0; 255,  28, 255; 0, 255, 0]));
+%! assert(A(:,:,3), uint8 ([0, 255, 0; 255,  36, 255; 0, 255, 0]));
diff --git a/scripts/image/imshow.m b/scripts/image/imshow.m
new file mode 100644
index 0000000..771c139
--- /dev/null
+++ b/scripts/image/imshow.m
@@ -0,0 +1,208 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} imshow (@var{im})
+## @deftypefnx {Function File} {} imshow (@var{im}, @var{limits})
+## @deftypefnx {Function File} {} imshow (@var{im}, @var{map})
+## @deftypefnx {Function File} {} imshow (@var{rgb}, @dots{})
+## @deftypefnx {Function File} {} imshow (@var{filename})
+## @deftypefnx {Function File} {} imshow (@dots{}, @var{string_param1}, @var{value1}, @dots{})
+## Display the image @var{im}, where @var{im} can be a 2-dimensional
+## (gray-scale image) or a 3-dimensional (RGB image) matrix.
+##
+## If @var{limits} is a 2-element vector @code{[@var{low}, @var{high}]},
+## the image is shown using a display range between @var{low} and
+## @var{high}.  If an empty matrix is passed for @var{limits}, the
+## display range is computed as the range between the minimal and the
+## maximal value in the image.
+##
+## If @var{map} is a valid color map, the image will be shown as an indexed
+## image using the supplied color map.
+##
+## If a file name is given instead of an image, the file will be read and
+## shown.
+##
+## If given, the parameter @var{string_param1} has value
+## @var{value1}.  @var{string_param1} can be any of the following:
+## @table @samp
+## @item "displayrange"
+## @var{value1} is the display range as described above.
+## @end table
+## @seealso{image, imagesc, colormap, gray2ind, rgb2ind}
+## @end deftypefn
+
+## Author: Stefan van der Walt  <stefan at sun.ac.za>
+## Author: Soren Hauberg <hauberg at gmail dot com>
+## Adapted-By: jwe
+
+function h = imshow (im, varargin)
+
+  if (nargin == 0)
+    print_usage ();
+  endif
+
+  display_range = NA;
+  true_color = false;
+  indexed = false;
+
+  ## Get the image.
+  if (ischar (im))
+    ## Eventually, this should be imread.
+    [im, map] = imread (im);
+    indexed = true;
+    colormap (map);
+  endif
+
+  if (! (isnumeric (im) && (ndims (im) == 2 || ndims (im) == 3)))
+    error ("imshow: first argument must be an image or the filename of an image");
+  endif
+
+  if (ndims (im) == 2)
+    if (! indexed)
+      colormap (gray ());
+    endif
+  elseif (size (im, 3) == 3)
+    if (ismember (class (im), {"uint8", "uint16", "double", "single"}))
+      true_color = true;
+    else
+      error ("imshow: color image must be uint8, uint16, double, or single");
+    endif
+  else
+    error ("imshow: expecting MxN or MxNx3 matrix for image");
+  endif
+
+  narg = 1;
+  while (narg <= numel (varargin))
+    arg = varargin{narg++};
+    if (isnumeric (arg))
+      if (numel (arg) == 2 || isempty (arg))
+	display_range = arg;
+      elseif (columns (arg) == 3)
+	indexed = true;
+	colormap (arg);
+      elseif (! isempty (arg))
+	error ("imshow: argument number %d is invalid", narg+1);
+      endif
+    elseif (ischar (arg))
+      switch (arg)
+	case "displayrange";
+	  display_range = varargin{narg++};
+	case {"truesize", "initialmagnification"}
+	  warning ("image: zoom argument ignored -- use GUI features");
+	otherwise
+	  warning ("imshow: unrecognized property %s", arg);
+	  narg++;
+      endswitch
+    else
+      error ("imshow: argument number %d is invalid", narg+1);
+    endif
+  endwhile
+
+  ## Set default display range if display_range not set yet.
+  if (isempty (display_range))
+    display_range = [min(im(:)), max(im(:))];
+  elseif (isna (display_range))
+    t = class (im);
+    switch (t)
+      case {"double", "single", "logical"}
+	display_range = [0, 1];
+      case {"int8", "int16", "int32", "uint8", "uint16", "uint32"}
+	## For compatibility, uint8 data should not be handled as
+	## double.  Doing so is a quick fix to allow the images to be
+	## displayed correctly.
+	display_range = double ([intmin(t), intmax(t)]);
+      otherwise
+	error ("imshow: invalid data type for image");
+    endswitch
+  endif
+
+  ## Check for complex images.
+  if (iscomplex (im))
+    warning ("imshow: only showing real part of complex image");
+    im = real (im);
+  endif
+  
+  nans = isnan (im(:));
+  if (any (nans))
+    warning ("Octave:imshow-NaN",
+	     "imshow: pixels with NaN or NA values are set to minimum pixel value");
+    im(nans) = display_range(1);
+  endif
+
+  ## This is for compatibility.
+  if (! (indexed || (true_color && isinteger (im))) || islogical (im))
+    im = double (im);
+  endif
+
+  ## Scale the image to the interval [0, 1] according to display_range.
+  if (! (true_color || indexed || islogical (im)))
+    low = display_range(1);
+    high = display_range(2);
+    im = (im-low)/(high-low);
+    im(im < 0) = 0;
+    im(im > 1) = 1;
+  endif
+
+  if (true_color || indexed)
+    tmp = image ([], [], im);
+  else
+    tmp = image (round ((rows (colormap ()) - 1) * im));
+  endif
+  set (gca (), "visible", "off");
+  axis ("image");
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
+
+%!error imshow ()                           # no arguments
+%!error imshow ({"cell"})                   # No image or filename given
+%!error imshow (ones(4,4,4))                # Too many dimensions in image
+
+%!demo
+%!  imshow ("default.img");
+
+%!demo
+%!  imshow ("default.img");
+%!  colormap ("autumn");
+
+%!demo
+%!  [I, M] = imread ("default.img");
+%!  imshow (I, M);
+
+%!demo
+%!  [I, M] = imread ("default.img");
+%!  [R, G, B] = ind2rgb (I, M);
+%!  imshow (cat(3, R, G*0.5, B*0.8));
+
+%!demo
+%!  imshow (rand (100, 100));
+
+%!demo
+%!  imshow (rand (100, 100, 3));
+
+%!demo
+%!  imshow (100*rand (100, 100, 3));
+
+%!demo
+%!  imshow (rand (100, 100));
+%!  colormap (jet);
diff --git a/scripts/image/imwrite.m b/scripts/image/imwrite.m
new file mode 100644
index 0000000..0844721
--- /dev/null
+++ b/scripts/image/imwrite.m
@@ -0,0 +1,161 @@
+## Copyright (C) 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
+## @deftypefnx {Function File} {} imwrite (@var{img}, @var{map}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
+## Write images in various file formats.
+##
+## If @var{fmt} is missing, the file extension (if any) of
+## @var{filename} is used to determine the format.
+##
+## The parameter-value pairs (@var{p1}, @var{v1}, @dots{}) are optional.  Currently
+## the following options are supported for @t{JPEG} images
+##
+## @table @samp
+## @item Quality
+## Sets the quality of the compression.  The corresponding value should be an
+## integer between 0 and 100, with larger values meaning higher visual quality
+## and less compression.
+## @end table
+##
+## @seealso{imread, imfinfo}
+## @end deftypefn
+
+function imwrite (varargin)
+
+  persistent accepted_formats = { "bmp", "gif", "jpg", "jpeg", ...
+    "ras", "pbm", "pgm", "png", "ppm", "svg", "tif", "tiff" };
+
+  img = [];
+  map = [];
+  fmt = "";
+
+  if (nargin > 1 && isnumeric (varargin{1}))
+    img = varargin{1};
+    offset = 2;
+    if (isnumeric (varargin{2}))
+      map = varargin{2};
+      if (isempty (map))
+        error ("imwrite: colormap must not be empty");
+      endif
+      offset = 3;
+    endif
+    if (offset <= nargin && ischar (varargin{offset}))
+      filename = varargin{offset};
+      offset++;
+      if (rem (nargin - offset, 2) == 0 && ischar (varargin{offset}))
+        fmt = varargin{offset};
+        offset++;
+      endif
+    else
+      print_usage ();
+    endif
+    if (offset < nargin)
+      has_param_list = 1;
+      for ii = offset:2:(nargin - 1)
+        options.(varargin{ii}) = varargin{ii + 1};
+      endfor
+    else
+      has_param_list = 0;
+    endif
+  else
+    print_usage ();
+  endif
+
+  filename = tilde_expand (filename);
+
+  if (isempty (fmt))
+    [d, n, fmt] = fileparts (filename);
+    if (! isempty (fmt))
+      fmt = fmt(2:end);
+    endif
+  endif
+
+  if (issparse (img) || issparse (map))
+    error ("imwrite: sparse images not supported");
+  endif
+
+  if (isempty (img))
+    error ("imwrite: invalid empty image");
+  endif
+
+  if (! strcmp (fmt, accepted_formats))
+    error ("imwrite: %s: unsupported or invalid image format", fmt);
+  endif
+
+  img_class = class (img);
+  map_class = class (map);
+  nd = ndims (img);
+
+  if (isempty (map))
+    if (any (strcmp (img_class, {"logical", "uint8", "uint16", "double"})))
+      if ((nd == 2 || nd == 3) && strcmp (img_class, "double"))
+        img = uint8 (img * 255);
+      endif
+      ## FIXME -- should we handle color images w/ alpha channel here?
+      if (nd == 3 && size (img, 3) < 3)
+        error ("imwrite: invalid dimensions for truecolor image");
+      endif
+      if (nd > 5)
+        error ("imwrite: invalid %d-dimensional image data", nd);
+      endif
+    else
+      error ("imwrite: %s: invalid class for truecolor image", img_class);
+    endif
+    if (has_param_list)
+      __magick_write__ (filename, fmt, img, options);
+    else
+      __magick_write__ (filename, fmt, img);
+    endif
+  else
+    if (any (strcmp (img_class, {"uint8", "uint16", "double"})))
+      if (strcmp (img_class, "double"))
+        img = uint8 (img - 1);
+      endif
+      if (nd != 2 && nd != 4)
+        error ("imwrite: invalid size for indexed image");
+      endif
+    else
+      error ("imwrite: %s: invalid class for indexed image data", img_class);
+    endif
+    if (isa (map, "double"))
+      if (ndims (map) != 2 || size (map, 2) != 3)
+        error ("imwrite: invalid size for colormap");
+      endif
+    else
+      error ("imwrite: %s invalid class for indexed image colormap",
+             class (map));
+    endif
+
+    ## FIXME -- we should really be writing indexed images here but
+    ## __magick_write__ needs to be fixed to handle them.
+
+    [r, g, b] = ind2rgb (img, map);
+    tmp = uint8 (cat (3, r, g, b) * 255);
+
+    if (has_param_list)
+      __magick_write__ (filename, fmt, tmp, options);
+      ## __magick_write__ (filename, fmt, img, map, options);
+    else
+      __magick_write__ (filename, fmt, tmp);
+      ## __magick_write__ (filename, fmt, img, map);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/image/ind2gray.m b/scripts/image/ind2gray.m
new file mode 100644
index 0000000..c36c686
--- /dev/null
+++ b/scripts/image/ind2gray.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005,
+##               2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ind2gray (@var{x}, @var{map})
+## Convert an Octave indexed image to a gray scale intensity image.
+## If @var{map} is omitted, the current colormap is used to determine the
+## intensities.
+## @seealso{gray2ind, rgb2ntsc, image, colormap}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function Y = ind2gray (X, map)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  elseif (nargin == 1)
+    map = colormap ();
+  endif
+
+  [rows, cols] = size (X);
+
+  ## Convert colormap to intensity values (the first column of the
+  ## result of the call to rgb2ntsc) and then replace indices in
+  ## the input matrix with indexed values in the output matrix (indexed
+  ## values are the result of indexing the intensity values by the
+  ## elements of X(:)).
+
+  Y = reshape (((rgb2ntsc (map))(:,1))(X(:)), rows, cols);
+
+endfunction
diff --git a/scripts/image/ind2rgb.m b/scripts/image/ind2rgb.m
new file mode 100644
index 0000000..1e9576a
--- /dev/null
+++ b/scripts/image/ind2rgb.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005,
+##               2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{rgb} =} ind2rgb (@var{x}, @var{map})
+## @deftypefnx {Function File} {[@var{r}, @var{g}, @var{b}] =} ind2rgb (@var{x}, @var{map})
+## Convert an indexed image to red, green, and blue color components.
+## If the colormap doesn't contain enough colors, pad it with the
+## last color in the map.
+## If @var{map} is omitted, the current colormap is used for the conversion.
+## @seealso{rgb2ind, image, imshow, ind2gray, gray2ind}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function [R, G, B] = ind2rgb (X, map)
+
+  ## Do we have the right number of inputs?
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  elseif (nargin == 1)
+    map = colormap ();
+  endif
+
+  ## Check if X is an indexed image.
+  if (ndims (X) != 2 || any (X(:) != round (X(:))) || min (X(:)) < 1)
+    error ("ind2rgb: first input argument must be an indexed image");
+  endif
+  
+  ## Check the color map.
+  if (ndims (map) != 2 || columns (map) != 3)
+    error ("ind2rgb: second input argument must be a color map");
+  endif
+
+  ## Do we have enough colors in the color map?
+  maxidx = max (X(:));
+  rm = rows (map);
+  if (rm < maxidx)
+    ## Pad with the last color in the map.
+    pad = repmat (map(end,:), maxidx-rm, 1);
+    map(end+1:maxidx, :) = pad;
+  endif
+  
+  ## Compute result
+  [hi, wi] = size (X);
+  R = reshape (map (X(:), 1), hi, wi);
+  G = reshape (map (X(:), 2), hi, wi);
+  B = reshape (map (X(:), 3), hi, wi);
+
+  ## Use 3D array if only one output is requested.
+  if (nargout <= 1)
+    R(:,:,3) = B;
+    R(:,:,2) = G;
+  endif
+endfunction
diff --git a/scripts/image/jet.m b/scripts/image/jet.m
new file mode 100644
index 0000000..f9afe5e
--- /dev/null
+++ b/scripts/image/jet.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} jet (@var{n})
+## Create color colormap.  This colormap is dark blue through blue, cyan, 
+## green, yellow, red to dark red.  The argument @var{n} should be a scalar. 
+## If it is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = jet (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("jet: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0, 0.5];  
+  elseif (number > 1)
+    x = linspace(0, 1, number)';
+    r = (x >= 3/8 & x < 5/8) .* (4 * x - 3/2)\
+      + (x >= 5/8 & x < 7/8) + (x >= 7/8) .* (-4 * x + 9/2);
+    g = (x >= 1/8 & x < 3/8) .* (4 * x - 1/2)\
+      + (x >= 3/8 & x < 5/8) + (x >= 5/8 & x < 7/8) .* (-4 * x + 7/2);
+    b = (x < 1/8) .* (4 * x + 1/2) + (x >= 1/8 & x < 3/8)\
+      + (x >= 3/8 & x < 5/8) .* (-4 * x + 5/2);
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/ntsc2rgb.m b/scripts/image/ntsc2rgb.m
new file mode 100644
index 0000000..e2ee700
--- /dev/null
+++ b/scripts/image/ntsc2rgb.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2005, 2006, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ntsc2rgb (@var{yiq})
+## Transform a colormap or image from NTSC to RGB.
+## @seealso{rgb2ntsc}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function rgb = ntsc2rgb (yiq)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  ## If we have an image convert it into a color map.
+  if (ismatrix (yiq) && ndims (yiq) == 3)
+    is_image = true;
+    Sz = size (yiq);
+    yiq = [yiq(:,:,1)(:), yiq(:,:,2)(:), yiq(:,:,3)(:)];
+    ## Convert to a double image.
+    if (isinteger (yiq))
+      C = class (yiq);
+      low = double (intmin (C));
+      high = double (intmax (C));
+      yiq = (double (yiq) - low) / (high - low);
+    endif
+  else
+    is_image = false;
+  endif
+
+  if (! ismatrix (yiq) || columns (yiq) != 3)
+    error ("ntsc2rgb: argument must be a matrix of size Nx3 or NxMx3");
+  endif
+  
+  ## Convert data
+  trans = [ 1.0,      1.0,      1.0;
+            0.95617, -0.27269, -1.10374;
+            0.62143, -0.64681, 1.70062 ];
+
+  rgb = yiq * trans;
+
+  ## If input was an image, convert it back into one.
+  if (is_image)
+    rgb = reshape (rgb, Sz);
+  endif
+
+endfunction
diff --git a/scripts/image/ocean.m b/scripts/image/ocean.m
new file mode 100644
index 0000000..b44219d
--- /dev/null
+++ b/scripts/image/ocean.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2002, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ocean (@var{n})
+## Create color colormap.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function map = ocean (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("ocean: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  cutin = fix (number/3);
+
+  dr = (number - 1) / cutin;
+
+  r = prepad ([0:dr:(number-1)], number)';
+
+  dg = (number - 1) / (2 * cutin);
+
+  g = prepad([0:dg:(number-1)], number)';
+
+  b = [0:(number-1)]';
+
+  map = [ r, g, b ] / (number - 1);
+
+endfunction
diff --git a/scripts/image/pink.m b/scripts/image/pink.m
new file mode 100644
index 0000000..628e568
--- /dev/null
+++ b/scripts/image/pink.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pink (@var{n})
+## Create color colormap.  This colormap gives a sepia tone on black and
+## white images.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = pink (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("pink: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0, 0];  
+  elseif (number > 1)
+    x = linspace (0, 1, number)';
+    r = (x < 3/8) .* (14/9 * x) + (x >= 3/8) .* (2/3 * x + 1/3);
+    g = (x < 3/8) .* (2/3 * x)\
+      + (x >= 3/8 & x < 3/4) .* (14/9 * x - 1/3)\
+      + (x >= 3/4) .* (2/3 * x + 1/3);
+    b = (x < 3/4) .* (2/3 * x) + (x >= 3/4) .* (2 * x - 1);
+
+    map = sqrt ([r, g, b]);
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/prism.m b/scripts/image/prism.m
new file mode 100644
index 0000000..0ff7875
--- /dev/null
+++ b/scripts/image/prism.m
@@ -0,0 +1,49 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} prism (@var{n})
+## Create color colormap.  This colormap cycles trough red, orange, yellow,
+## green, blue and violet.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = prism (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("prism: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  p = [1, 0, 0; 1, 1/2, 0; 1, 1, 0; 0, 1, 0; 0, 0, 1; 2/3, 0, 1];
+
+  if (rem (number, 6) == 0)
+    map = kron(ones (fix (number / 6), 1), p);
+  else
+    map = [kron(ones (fix (number / 6), 1), p); p(1:rem (number, 6), :)];
+  endif
+
+endfunction
diff --git a/scripts/image/rainbow.m b/scripts/image/rainbow.m
new file mode 100644
index 0000000..7ae22cc
--- /dev/null
+++ b/scripts/image/rainbow.m
@@ -0,0 +1,57 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rainbow (@var{n})
+## Create color colormap.  This colormap is red through orange, yellow, green, 
+## blue to violet.  The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = rainbow (number)
+## this colormap is not part of matlab, it is like the prism
+## colormap map but with a continuous map
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("rainbow: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [1, 0, 0];  
+  elseif (number > 1)
+    x = linspace (0, 1, number)';
+    r = (x < 2/5) + (x >= 2/5 & x < 3/5) .* (-5 * x + 3)\
+      + (x >= 4/5) .* (10/3 * x - 8/3);
+    g = (x < 2/5) .* (5/2 * x) + (x >= 2/5 & x < 3/5)\
+      + (x >= 3/5 & x < 4/5) .* (-5 * x + 4);
+    b = (x >= 3/5 & x < 4/5) .* (5 * x - 3) + (x >= 4/5);
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/rgb2hsv.m b/scripts/image/rgb2hsv.m
new file mode 100644
index 0000000..254c3e8
--- /dev/null
+++ b/scripts/image/rgb2hsv.m
@@ -0,0 +1,103 @@
+## Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
+##               Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{hsv_map} =} rgb2hsv (@var{rgb_map})
+## Transform a colormap or image from the rgb space to the hsv space.
+##
+## A color n the RGB space consists of the red, green and blue intensities.
+##
+## In the HSV space each color is represented by their hue, saturation
+## and value (brightness).  Value gives the amount of light in the color.
+## Hue describes the dominant wavelength. 
+## Saturation is the amount of Hue mixed into the color.
+## @seealso{hsv2rgb}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Adapted-by: jwe
+
+function hsval = rgb2hsv (rgb)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  ## If we have an image convert it into a color map.
+  if (ismatrix (rgb) && ndims (rgb) == 3)
+    is_image = true;
+    Sz = size (rgb);
+    rgb = [rgb(:,:,1)(:), rgb(:,:,2)(:), rgb(:,:,3)(:)];
+    ## Convert to a double image.
+    if (isinteger (rgb))
+      C = class (rgb);
+      low = double (intmin (C));
+      high = double (intmax (C));
+      rgb = (double (rgb) - low) / (high - low);
+    endif
+  else
+    is_image = false;
+  endif
+
+  if (! ismatrix (rgb) || columns (rgb) != 3)
+    error ("rgb2hsv: argument must be a matrix of size n x 3");
+  endif
+
+  ## get the max and min
+  s = min (rgb')';
+  v = max (rgb')';
+
+  ## set hue to zero for undefined values (gray has no hue)
+  h = zeros (size (v));
+  notgray = (s != v);
+    
+  ## blue hue
+  idx = (v == rgb(:,3) & notgray);
+  if (any (idx))
+    h(idx) = 2/3 + 1/6 * (rgb(idx,1) - rgb(idx,2)) ./ (v(idx) - s(idx));
+  endif
+
+  ## green hue
+  idx = (v == rgb(:,2) & notgray);
+  if (any (idx))
+    h(idx) = 1/3 + 1/6 * (rgb(idx,3) - rgb(idx,1)) ./ (v(idx) - s(idx));
+  endif
+
+  ## red hue
+  idx = (v == rgb(:,1) & notgray);
+  if (any (idx))
+    h(idx) =       1/6 * (rgb(idx,2) - rgb(idx,3)) ./ (v(idx) - s(idx));
+  endif
+
+  ## correct for negative red
+  idx = (h < 0);
+  h(idx) = 1+h(idx);
+
+  ## set the saturation
+  s(! notgray) = 0;
+  s(notgray) = 1 - s(notgray) ./ v(notgray);
+
+  hsval = [h, s, v];
+  
+  ## If input was an image, convert it back into one.
+  if (is_image)
+    hsval = reshape (hsval, Sz);
+  endif
+
+endfunction
diff --git a/scripts/image/rgb2ind.m b/scripts/image/rgb2ind.m
new file mode 100644
index 0000000..9eaf7af
--- /dev/null
+++ b/scripts/image/rgb2ind.m
@@ -0,0 +1,66 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb})
+## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{r}, @var{g}, @var{b})
+## Convert an RGB image to an Octave indexed image.
+## @seealso{ind2rgb, rgb2ntsc}
+## @end deftypefn
+
+## Bugs: The color map may have duplicate entries.
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function [X, map] = rgb2ind (R, G, B)
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+  
+  if (nargin == 1)
+    rgb = R;
+    if (length (size (rgb)) == 3 && size (rgb, 3) == 3)
+      R = rgb(:,:,1);
+      G = rgb(:,:,2);
+      B = rgb(:,:,3);
+    else
+      error ("rgb2ind: argument is not an RGB image");
+    endif
+  endif
+
+  if (! size_equal (R, G) || ! size_equal (R, B))
+    error ("rgb2ind: arguments must all have the same size");
+  endif
+
+  [hi, wi] = size (R);
+
+  X = zeros (hi, wi);
+
+  map = zeros (hi*wi, 3);
+
+  map(:,1) = R(:);
+  map(:,2) = G(:);
+  map(:,3) = B(:);
+
+  X(:) = 1:(hi*wi);
+
+endfunction
diff --git a/scripts/image/rgb2ntsc.m b/scripts/image/rgb2ntsc.m
new file mode 100644
index 0000000..f18fead
--- /dev/null
+++ b/scripts/image/rgb2ntsc.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2005, 2006, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rgb2ntsc (@var{rgb})
+## Transform a colormap or image from RGB to NTSC.
+## @seealso{ntsc2rgb}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+function yiq = rgb2ntsc (rgb)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  ## If we have an image convert it into a color map.
+  if (ismatrix (rgb) && ndims (rgb) == 3)
+    is_image = true;
+    Sz = size (rgb);
+    rgb = [rgb(:,:,1)(:), rgb(:,:,2)(:), rgb(:,:,3)(:)];
+    ## Convert to a double image.
+    if (isinteger (rgb))
+      C = class (rgb);
+      low = double (intmin (C));
+      high = double (intmax (C));
+      rgb = (double (rgb) - low) / (high - low);
+    endif
+  else
+    is_image = false;
+  endif
+
+  if (! ismatrix (rgb) || columns (rgb) != 3)
+    error ("rgb2ntsc: argument must be a matrix of size Nx3 or NxMx3");
+  endif
+  
+  ## Convert data
+  trans = [ 0.299,  0.596,  0.211;
+            0.587, -0.274, -0.523;
+            0.114, -0.322,  0.312 ];
+
+  yiq = rgb * trans;
+
+  ## If input was an image, convert it back into one.
+  if (is_image)
+    yiq = reshape (yiq, Sz);
+  endif
+
+endfunction
diff --git a/scripts/image/saveimage.m b/scripts/image/saveimage.m
new file mode 100644
index 0000000..42b7520
--- /dev/null
+++ b/scripts/image/saveimage.m
@@ -0,0 +1,308 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+##                2004, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} saveimage (@var{file}, @var{x}, @var{fmt}, @var{map})
+## Save the matrix @var{x} to @var{file} in image format @var{fmt}.  Valid
+## values for @var{fmt} are
+##
+## @table @code
+## @item "img"
+## Octave's image format.  The current colormap is also saved in the file.
+##
+## @item "ppm"
+## Portable pixmap format.
+##
+## @item "ps"
+## PostScript format.  Note that images saved in PostScript format cannot
+## be read back into Octave with loadimage.
+## @end table
+##
+## If the fourth argument is supplied, the specified colormap will also be
+## saved along with the image.
+##
+## Note: if the colormap contains only two entries and these entries are
+## black and white, the bitmap ppm and PostScript formats are used.  If the
+## image is a gray scale image (the entries within each row of the colormap
+## are equal) the gray scale ppm and PostScript image formats are used,
+## otherwise the full color formats are used.
+## @seealso{loadimage, save, load, colormap}
+## @end deftypefn
+
+## The conversion to PostScript is based on pbmtolps.c, which was
+## written by
+##
+##   George Phillips <phillips at cs.ubc.ca>
+##   Department of Computer Science
+##   University of British Columbia
+##
+## and is part of the portable bitmap utilities,
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: July 1994
+## Adapted-By: jwe
+
+## Rewritten by jwe to avoid using octoppm and pbm routines so that
+## people who don't have the pbm stuff installed can still use this
+## function.
+##
+## The conversion to PostScript is based on pnmtops.c, which is part of
+## the portable bitmap utilties and bears this copyright notice:
+##
+## Copyright (C) 1989 by Jef Poskanzer.
+##
+## Permission to use, copy, modify, and distribute this software and its
+## documentation for any purpose and without fee is hereby granted, provided
+## that the above copyright notice appear in all copies and that both that
+## copyright notice and this permission notice appear in supporting
+## documentation.  This software is provided "as is" without express or
+## implied warranty.
+
+function saveimage (filename, img, img_form, map)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 4)
+    if (size(img, 3) == 3)
+      [img, map] = rgb2ind(img);
+    else
+      map = colormap ();
+    endif
+  endif
+
+  [map_nr, map_nc] = size (map);
+
+  if (map_nc != 3)
+    error ("colormap should be an N x 3 matrix");
+  endif
+
+  if (nargin < 3)
+    img_form = "img";
+  elseif (! ischar (img_form))
+    error ("image format specification must be a string");
+  elseif (! (strcmp (img_form, "img")
+             || strcmp (img_form, "ppm")
+             || strcmp (img_form, "ps")))
+    error ("unsupported image format specification");
+  endif
+
+  if (! ismatrix (img))
+    warning ("image variable is not a matrix");
+  endif
+
+  if (! ischar (filename))
+    error ("file name must be a string");
+  endif
+
+  ## If we just want Octave image format, save and return.
+
+  if (strcmp (img_form, "img"))
+    save ("-text", filename, "map", "img");
+    return;
+  endif
+
+  ## Convert to another format if requested.
+
+  grey = all (map(:,1) == map(:,2) && map(:,1) == map (:,3));
+
+  pbm = pgm = ppm = 0;
+
+  map_sz = map_nr * map_nc;
+
+  map = reshape (map, map_sz, 1);
+
+  map (map > 1) = 1;
+  map (map < 0) = 0;
+
+  map = round (255 * map);
+
+  bw = (map_nr == 2
+        && ((map(1,1) == 0 && map(2,1) == 255)
+            || (map(1,1) == 255 && map(2,1) == 0)));
+
+  img = round (img');
+  [img_nr, img_nc] = size (img);
+
+  img_sz = img_nr * img_nc;
+  img = reshape (img, img_sz, 1);
+
+  img (img > map_nr) = map_nr;
+  img (img <= 0) = 1;
+
+  if (strcmp (img_form, "ppm"))
+
+    ## Would be nice to make this consistent with the line used by the
+    ## load/save functions, but we need a good way to get username and
+    ## hostname information.
+
+    time_string = ctime (time ());
+    time_string = time_string (1:length (time_string)-1);
+    tagline = sprintf ("# Created by Octave %s, %s",
+		       OCTAVE_VERSION, time_string);
+
+    if (grey && bw)
+
+      if (map(1) != 0)
+        map = [0; 1];
+      else
+        map = [1; 0];
+      endif
+
+      n_long = rem (img_nc, 8);
+      tmp = zeros (ceil (img_nc/8), img_nr);
+
+      k = ceil (img_nr/8);
+      tmp = zeros (k, img_nc);
+
+      ## Append columns with zeros to original image so that
+      ## mod (cols, 8) = 0.
+
+      bwimg = postpad (reshape (map(img), img_nr, img_nc), k * 8, 0);
+
+      b = kron (pow2 (7:-1:0)', ones (1, img_nc));
+
+      for i = 1:k
+        tmp(i,:) = sum (bwimg(8*(i-1)+1:8*i,:) .* b);
+      endfor
+
+      fid = fopen (filename, "wb");
+      fprintf (fid, "P4\n%s\n%d %d\n", tagline, img_nr, img_nc);
+      fwrite (fid, tmp, "uchar");
+      fprintf (fid, "\n");
+      fclose (fid);
+
+    elseif (grey)
+
+      fid = fopen (filename, "wb");
+      fprintf (fid, "P5\n%s\n%d %d\n255\n", tagline, img_nr, img_nc);
+      fwrite (fid, map(img), "uchar");
+      fprintf (fid, "\n");
+      fclose (fid);
+
+    else
+
+      img_idx = ((1:3:3*img_sz)+2)';
+      map_idx = ((2*map_nr+1):map_sz)';
+
+      tmap = map(map_idx);
+      tmp(img_idx--) = tmap(img);
+
+      map_idx = map_idx - map_nr;
+      tmap = map(map_idx);
+      tmp(img_idx--) = tmap(img);
+
+      map_idx = map_idx - map_nr;
+      tmap = map(map_idx);
+      tmp(img_idx--) = tmap(img);
+
+      fid = fopen (filename, "wb");
+      fprintf (fid, "P6\n%s\n%d %d\n255\n", tagline, img_nr, img_nc);
+      fwrite (fid, tmp, "uchar");
+      fprintf (fid, "\n");
+      fclose (fid);
+
+    endif
+
+  elseif (strcmp (img_form, "ps") == 1)
+
+    if (! grey)
+      error ("must have a greyscale color map for conversion to PostScript");
+    endif
+
+    bps = 8;
+    dpi = 300;
+    pagewid = 612;
+    pagehgt = 762;
+    MARGIN = 0.95;
+    devpix = dpi / 72.0 + 0.5;
+    pixfac = 72.0 / dpi * devpix;
+
+    ## Compute padding to round cols * bps up to the nearest multiple of 8
+    ## (nr and nc are switched because we transposed the image above).
+
+    padright = (((img_nr * bps + 7) / 8) * 8 - img_nr * bps) / bps;
+
+    scols = img_nr * pixfac;
+    srows = img_nc * pixfac;
+    scale = 1;
+
+    if (scols > pagewid * MARGIN || srows > pagehgt * MARGIN)
+      if (scols > pagewid * MARGIN)
+        scale = scale * (pagewid / scols * MARGIN);
+        scols = scale * img_nr * pixfac;
+        srows = scale * img_nc * pixfac;
+      endif
+      if (srows > pagehgt * MARGIN)
+        scale = scale * (pagehgt / srows * MARGIN);
+        scols = scale * img_nr * pixfac;
+        srows = scale * img_nc * pixfac;
+      endif
+      warning ("image too large for page, rescaling to %g", scale);
+    endif
+
+    llx = (pagewid - scols) / 2;
+    lly = (pagehgt - srows) / 2;
+    urx = llx + fix (scols + 0.5);
+    ury = lly + fix (srows + 0.5);
+
+    fid = fopen (filename, "wb");
+
+    fprintf (fid, "%%!PS-Adobe-2.0 EPSF-2.0\n");
+    fprintf (fid, "%%%%Creator: Octave %s (saveimage.m)\n", OCTAVE_VERSION);
+    fprintf (fid, "%%%%Title: %s\n", filename);
+    fprintf (fid, "%%%%Pages: 1\n");
+    fprintf (fid, "%%%%BoundingBox: %d %d %d %d\n",
+             fix (llx), fix (lly), fix (urx), fix (ury));
+    fprintf (fid, "%%%%EndComments\n");
+    fprintf (fid, "/readstring {\n");
+    fprintf (fid, "  currentfile exch readhexstring pop\n");
+    fprintf (fid, "} bind def\n");
+    fprintf (fid, "/picstr %d string def\n",
+             fix ((img_nr + padright) * bps / 8));
+    fprintf (fid, "%%%%EndProlog\n");
+    fprintf (fid, "%%%%Page: 1 1\n");
+    fprintf (fid, "gsave\n");
+    fprintf (fid, "%g %g translate\n", llx, lly);
+    fprintf (fid, "%g %g scale\n", scols, srows);
+    fprintf (fid, "%d %d %d\n", img_nr, img_nc, bps);
+    fprintf (fid, "[ %d 0 0 -%d 0 %d ]\n", img_nr, img_nc, img_nc);
+    fprintf (fid, "{ picstr readstring }\n");
+    fprintf (fid, "image\n");
+
+    img = map(img);
+
+    fmt = "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n";
+    fprintf (fid, fmt, img);
+
+    if (rem (img_sz, 30) != 0)
+      fprintf (fid, "\n");
+    endif
+
+    fprintf (fid, "grestore\n");
+    fprintf (fid, "showpage\n");
+    fprintf (fid, "%%%%Trailer\n");
+    fclose (fid);
+
+  else
+    error ("saveimage: what happened to the image type?");
+  endif
+
+endfunction
diff --git a/scripts/image/spring.m b/scripts/image/spring.m
new file mode 100644
index 0000000..1ebc725
--- /dev/null
+++ b/scripts/image/spring.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spring (@var{n})
+## Create color colormap.  This colormap is magenta to yellow.
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = spring (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("spring: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [1, 0, 1];  
+  elseif (number > 1)
+    r = ones (number, 1);
+    g = (0:number - 1)' ./ (number - 1);
+    b = 1 - g;
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/summer.m b/scripts/image/summer.m
new file mode 100644
index 0000000..cdf94db
--- /dev/null
+++ b/scripts/image/summer.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} summer (@var{n})
+## Create color colormap.  This colormap is green to yellow.
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+## Date:  06/03/2000
+function map = summer (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("summer: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0.5, 0.4];  
+  elseif (number > 1)
+    r = (0:number - 1)' ./ (number - 1);
+    g = 0.5 + r ./ 2;
+    b = 0.4 * ones (number, 1);
+
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/white.m b/scripts/image/white.m
new file mode 100644
index 0000000..cba1b38
--- /dev/null
+++ b/scripts/image/white.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1999, 2000, 2007 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} white (@var{n})
+## Create color colormap.  This colormap is completely white.
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = white (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("white: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number > 0)
+    map = ones (number, 3);
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/image/winter.m b/scripts/image/winter.m
new file mode 100644
index 0000000..ee24c87
--- /dev/null
+++ b/scripts/image/winter.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1999, 2000, 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} winter (@var{n})
+## Create color colormap.  This colormap is blue to green.
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @seealso{colormap}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+
+function map = winter (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! isscalar (number))
+      error ("winter: argument must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (number == 1)
+    map = [0, 0, 1];  
+  elseif (number > 1)
+    r = zeros (number, 1);
+    g = (0:number - 1)' ./ (number - 1);
+    b = 1 - g ./ 2;
+
+    map = [r, g, b];
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/scripts/io/Makefile.in b/scripts/io/Makefile.in
new file mode 100644
index 0000000..cc4cbfe
--- /dev/null
+++ b/scripts/io/Makefile.in
@@ -0,0 +1,83 @@
+# Makefile for octave's scripts/io directory
+#
+# Copyright (C) 1996, 1997, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = io
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = beep.m csvread.m csvwrite.m dlmwrite.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/io
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/io/beep.m b/scripts/io/beep.m
new file mode 100644
index 0000000..8572087
--- /dev/null
+++ b/scripts/io/beep.m
@@ -0,0 +1,35 @@
+## Copyright (C) 2003, 2004, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} beep ()
+## Produce a beep from the speaker (or visual bell).
+## @seealso{puts, fputs, printf, fprintf}
+## @end deftypefn
+
+## Author: jwe
+
+function beep ()
+
+  if (nargin == 0)
+    puts ("\a");
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/io/csvread.m b/scripts/io/csvread.m
new file mode 100644
index 0000000..78b531a
--- /dev/null
+++ b/scripts/io/csvread.m
@@ -0,0 +1,33 @@
+## Copyright (C) 2001, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} csvread (@var{filename})
+## Read the matrix @var{x} from a file.
+##
+## This function is equivalent to
+## @example
+## dlmread (@var{filename}, "," , @dots{})
+## @end example
+##
+## @seealso{dlmread, dlmwrite, csvwrite}
+## @end deftypefn
+
+function x = csvread (f, varargin)
+  x = dlmread (f, ",", varargin{:});
+endfunction
diff --git a/scripts/io/csvwrite.m b/scripts/io/csvwrite.m
new file mode 100644
index 0000000..53a4dfb
--- /dev/null
+++ b/scripts/io/csvwrite.m
@@ -0,0 +1,33 @@
+## Copyright (C) 2001, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} csvwrite (@var{filename}, @var{x})
+## Write the matrix @var{x} to a file.
+##
+## This function is equivalent to
+## @example
+## dlmwrite (@var{filename}, @var{x}, ",", @dots{})
+## @end example
+##
+## @seealso{dlmread, dlmwrite, csvread}
+## @end deftypefn
+
+function csvwrite (f, m, varargin)
+  dlmwrite (f, m, ",", varargin{:});
+endfunction
diff --git a/scripts/io/dlmwrite.m b/scripts/io/dlmwrite.m
new file mode 100644
index 0000000..8ba31d6
--- /dev/null
+++ b/scripts/io/dlmwrite.m
@@ -0,0 +1,202 @@
+## Copyright (C) 2002, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dlmwrite (@var{file}, @var{a})
+## @deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, @var{delim}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, @var{key}, @var{val} @dots{})
+## @deftypefnx {Function File} {} dlmwrite (@var{file}, @var{a}, "-append", @dots{})
+## Write the matrix @var{a} to the named file using delimiters.
+##
+## The parameter @var{delim} specifies the delimiter to use to separate
+## values on a row.
+##
+## The value of @var{r} specifies the number of delimiter-only lines to
+## add to the start of the file.
+##
+## The value of @var{c} specifies the number of delimiters to prepend to
+## each line of data.
+##
+## If the argument @code{"-append"} is given, append to the end of the
+## @var{file}.
+##
+## In addition, the following keyword value pairs may appear at the end
+## of the argument list:
+## @table @code
+## @item "append"
+## Either @samp{"on"} or @samp{"off"}.  See @samp{"-append"} above.
+##
+## @item "delimiter"
+## See @var{delim} above.
+##
+## @item "newline"
+## The character(s) to use to separate each row.  Three special cases
+## exist for this option.  @samp{"unix"} is changed into '\n',
+## @samp{"pc"} is changed into '\r\n', and @samp{"mac"} is changed
+## into '\r'.  Other values for this option are kept as is.
+##
+## @item "roffset"
+## See @var{r} above.
+##
+## @item "coffset"
+## See @var{c} above.
+##
+## @item "precision"
+## The precision to use when writing the file.  It can either be a
+## format string (as used by fprintf) or a number of significant digits.
+## @end table
+##
+## @example
+## dlmwrite ("file.csv", reshape (1:16, 4, 4));
+## @end example
+##
+## @example
+## dlmwrite ("file.tex", a, "delimiter", "&", "newline", "\\n")
+## @end example
+##
+## @seealso{dlmread, csvread, csvwrite}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+## 
+## This program was originally granted to the public domain
+## 
+## 2002-03-08 Paul Kienzle <pkienzle at users.sf.net>
+## * Initial revision
+## 2005-11-27 Bill Denney <bill at givebillmoney.com>
+## * Significant modifications of the input arguements for additional
+## functionality.
+
+function dlmwrite (file, a, varargin)
+
+  if (nargin < 2 || ! ischar (file))
+    print_usage ();
+  endif
+
+  ## set defaults
+  delim = ",";
+  r = 0;
+  c = 0;
+  newline = "\n";
+  if (ischar (a))
+    precision = "%c";
+  else
+    precision = "%.16g";
+  endif
+  opentype = "wt";
+
+  ## process the input arguements
+  i = 0;
+  while (i < length (varargin))
+    i = i + 1;
+    if (strcmpi (varargin{i}, "delimiter"))
+      i = i + 1;
+      delim = varargin{i};
+    elseif (strcmpi (varargin{i}, "newline"))
+      i = i + 1;
+      newline = varargin{i};
+      if (strcmpi (newline, "unix"))
+	newline = "\n";
+      elseif (strcmpi (newline, "pc"))
+	newline = "\r\n";
+      elseif (strcmpi (newline, "mac"))
+	newline = "\r";
+      endif
+    elseif (strcmpi (varargin{i}, "roffset"))
+      i = i + 1;
+      r = varargin{i};
+    elseif (strcmpi (varargin{i}, "coffset"))
+      i = i + 1;
+      c = varargin{i};
+    elseif (strcmpi (varargin{i}, "precision"))
+      i = i + 1;
+      precision = varargin{i};
+      if (! strcmpi (class (precision), "char"))
+	precision = sprintf ("%.%gg", precision);
+      endif
+    elseif (strcmpi (varargin{i}, "-append"))
+      opentype = "at";
+    elseif (strcmpi (varargin{i}, "append"))
+      i = i + 1;
+      if (strcmpi (varargin{i}, "on"))
+	opentype = "at";
+      elseif (strcmpi (varargin{i}, "off"))
+	opentype = "wt";
+      else
+	error ("dlmwrite: append must be \"on\" or \"off\".");
+      endif
+    else
+      if (i == 1)
+	delim = varargin{i};
+      elseif (i == 2)
+	r = varargin{i};
+      elseif (i == 3)
+	c = varargin{i};
+      else
+	print_usage();
+      endif
+    endif
+  endwhile
+
+  [fid, msg] = fopen (file, opentype);
+  if (fid < 0)
+    error (msg);
+  else
+    if (r > 0)
+      fprintf (fid, "%s",
+	       repmat ([repmat(delim, 1, c + columns(a)-1), newline], 1, r));
+    endif
+    if (iscomplex (a))
+      cprecision = regexprep (precision, '^%([-\d.])','%+$1');
+      template = [precision, cprecision, "i", ...
+		  repmat([delim, precision, cprecision, "i"], 1, ...
+		  columns(a) - 1), newline ];
+    else
+      template = [precision, repmat([delim, precision], 1, columns(a)-1),...
+		  newline];
+    endif
+    if (c > 0)
+      template = [repmat(delim, 1, c), template];
+    endif
+    if (iscomplex (a))
+      a = a.';
+      b = zeros (2*rows(a), columns (a));
+      b(1: 2 : end, :) = real (a);
+      b(2: 2 : end, :) = imag (a);
+      fprintf (fid, template, b);
+    else
+      fprintf (fid, template, a.');
+    endif
+    fclose (fid);
+  endif
+endfunction
+
+%!test
+%! f = tmpnam();
+%! dlmwrite(f,[1,2;3,4],'precision','%5.2f','newline','unix','roffset',1,'coffset',1);
+%! fid = fopen(f,"rt");
+%! f1 = char(fread(fid,Inf,'char')');
+%! fclose(fid);
+%! dlmwrite(f,[5,6],'precision','%5.2f','newline','unix','coffset',1,'delimiter',',','-append');
+%! fid = fopen(f,"rt");
+%! f2 = char(fread(fid,Inf,'char')');
+%! fclose(fid);
+%! unlink(f);
+%!
+%! assert(f1,",,\n, 1.00, 2.00\n, 3.00, 4.00\n");
+%! assert(f2,",,\n, 1.00, 2.00\n, 3.00, 4.00\n, 5.00, 6.00\n");
diff --git a/scripts/linear-algebra/Makefile.in b/scripts/linear-algebra/Makefile.in
new file mode 100644
index 0000000..a11d007
--- /dev/null
+++ b/scripts/linear-algebra/Makefile.in
@@ -0,0 +1,87 @@
+# Makefile for octave's scripts/linear-algebra directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008, 2009
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = linear-algebra
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = commutation_matrix.m cond.m condest.m cross.m \
+  dot.m duplication_matrix.m expm.m housh.m krylov.m krylovb.m logm.m \
+  null.m onenormest.m orth.m planerot.m qzhess.m rank.m rref.m subspace.m \
+  trace.m vec.m vech.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/linear-algebra
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/linear-algebra/commutation_matrix.m b/scripts/linear-algebra/commutation_matrix.m
new file mode 100644
index 0000000..c7dca29
--- /dev/null
+++ b/scripts/linear-algebra/commutation_matrix.m
@@ -0,0 +1,98 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} commutation_matrix (@var{m}, @var{n})
+## Return the commutation matrix
+## @tex
+##  $K_{m,n}$
+## @end tex
+## @ifnottex
+##  K(m,n)
+## @end ifnottex
+##  which is the unique
+## @tex
+##  $m n \times m n$
+## @end tex
+## @ifnottex
+##  @var{m}*@var{n} by @var{m}*@var{n}
+## @end ifnottex
+##  matrix such that
+## @tex
+##  $K_{m,n} \cdot {\rm vec} (A) = {\rm vec} (A^T)$
+## @end tex
+## @ifnottex
+##  @math{K(m,n) * vec(A) = vec(A')}
+## @end ifnottex
+##  for all
+## @tex
+##  $m\times n$
+## @end tex
+## @ifnottex
+##  @math{m} by @math{n}
+## @end ifnottex
+##  matrices
+## @tex
+##  $A$.
+## @end tex
+## @ifnottex
+##  @math{A}.
+## @end ifnottex
+##
+## If only one argument @var{m} is given,
+## @tex
+##  $K_{m,m}$
+## @end tex
+## @ifnottex
+##  @math{K(m,m)}
+## @end ifnottex
+##  is returned.
+##
+## See Magnus and Neudecker (1988), Matrix differential calculus with
+## applications in statistics and econometrics.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 8 May 1995
+## Adapted-By: jwe
+
+function k = commutation_matrix (m, n)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    if (! (isscalar (m) && m == round (m) && m > 0))
+      error ("commutation_matrix: m must be a positive integer");
+    endif
+    if (nargin == 1)
+      n = m;
+    elseif (! (isscalar (n) && n == round (n) && n > 0))
+      error ("commutation_matrix: n must be a positive integer");
+    endif
+  endif
+
+  ## It is clearly possible to make this a LOT faster!
+  k = zeros (m * n, m * n);
+  for i = 1 : m
+    for j = 1 : n
+      k ((i - 1) * n + j, (j - 1) * m + i) = 1;
+    endfor
+  endfor
+
+endfunction
diff --git a/scripts/linear-algebra/cond.m b/scripts/linear-algebra/cond.m
new file mode 100644
index 0000000..88857c2
--- /dev/null
+++ b/scripts/linear-algebra/cond.m
@@ -0,0 +1,84 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2003, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cond (@var{a}, at var{p})
+## Compute the @var{p}-norm condition number of a matrix.  @code{cond (@var{a})} is
+## defined as @code{norm (@var{a}, @var{p}) * norm (inv (@var{a}), @var{p})}.
+## By default @code{@var{p}=2} is used which implies a (relatively slow)
+## singular value decomposition.  Other possible selections are 
+## @code{@var{p}= 1, Inf, inf, 'Inf', 'fro'} which are generally faster.
+## @seealso{condest, rcond, norm, svd}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = cond (a, p)
+
+  if (nargin && nargin < 3)
+    if (ndims (a) > 2)
+      error ("cond: only valid on 2-D objects");
+    endif
+
+    if (nargin <2)
+      p = 2;
+    endif
+
+    if (! ischar (p) && p == 2)
+      [nr, nc] = size (a);
+      if (nr == 0 || nc == 0)
+        retval = 0.0;
+      elseif (any (any (isinf (a) | isnan (a))))
+        error ("cond: argument must not contain Inf or NaN values");
+      else
+        sigma   = svd (a);
+        sigma_1 = sigma(1);
+        sigma_n = sigma(end);
+        if (sigma_1 == 0 || sigma_n == 0)
+          retval = Inf;
+        else
+          retval = sigma_1 / sigma_n;
+        endif
+      endif
+    else
+      retval = norm (a, p) * norm (inv (a), p);  
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! y= [7, 2, 3; 1, 3, 4; 6, 4, 5];
+%! tol = 1e-6;
+%! type = {1, 2, 'fro', 'inf', inf};
+%! for n = 1:numel(type)
+%!   rcondition(n) = 1 / cond (y, type{n});
+%! endfor
+%! assert (rcondition, [0.017460, 0.019597, 0.018714, 0.012022, 0.012022], tol);
+
+%!assert (abs (cond ([1, 2; 2, 1]) - 3) < sqrt (eps));
+
+%!assert (cond ([1, 2, 3; 4, 5, 6; 7, 8, 9]) > 1.0e+16);
+
+%!error cond ();
+
+%!error cond (1, 2, 3);
+
diff --git a/scripts/linear-algebra/condest.m b/scripts/linear-algebra/condest.m
new file mode 100644
index 0000000..c8238d1
--- /dev/null
+++ b/scripts/linear-algebra/condest.m
@@ -0,0 +1,230 @@
+## Copyright (C) 2007, 2008, 2009 Regents of the University of California
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{est}, @var{v}] =} condest (@var{a}, @var{t}) 
+## @deftypefnx {Function File} {[@var{est}, @var{v}] =} condest (@var{a}, @var{solve}, @var{solve_t}, @var{t})
+## @deftypefnx {Function File} {[@var{est}, @var{v}] =} condest (@var{apply}, @var{apply_t}, @var{solve}, @var{solve_t}, @var{n}, @var{t})
+##
+## Estimate the 1-norm condition number of a matrix @var{A}
+## using @var{t} test vectors using a randomized 1-norm estimator.
+## If @var{t} exceeds 5, then only 5 test vectors are used.
+##
+## If the matrix is not explicit, e.g., when estimating the condition 
+## number of @var{a} given an LU factorization, @code{condest} uses the 
+## following functions:
+##
+## @table @var
+## @item apply
+## @code{A*x} for a matrix @code{x} of size @var{n} by @var{t}.
+## @item apply_t
+## @code{A'*x} for a matrix @code{x} of size @var{n} by @var{t}.
+## @item solve
+## @code{A \ b} for a matrix @code{b} of size @var{n} by @var{t}.
+## @item solve_t
+## @code{A' \ b} for a matrix @code{b} of size @var{n} by @var{t}.
+## @end table
+##
+## The implicit version requires an explicit dimension @var{n}.
+##
+## @code{condest} uses a randomized algorithm to approximate
+## the 1-norms.
+##
+## @code{condest} returns the 1-norm condition estimate @var{est} and
+## a vector @var{v} satisfying @code{norm (A*v, 1) == norm (A, 1) * norm
+## (@var{v}, 1) / @var{est}}.  When @var{est} is large, @var{v} is an
+## approximate null vector.
+##
+## References: 
+## @itemize
+## @item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+## for Matrix 1-Norm Estimation, with an Application to 1-Norm
+## Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+## @url{http://dx.doi.org/10.1137/S0895479899356080}
+## @item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+## for Matrix 1-Norm Estimation, with an Application to 1-Norm
+## Pseudospectra." @url{http://citeseer.ist.psu.edu/223007.html}
+## @end itemize
+##
+## @seealso{cond, norm, onenormest}
+## @end deftypefn
+
+## Code originally licensed under
+##
+##  Copyright (c) 2007, Regents of the University of California
+##  All rights reserved.
+##
+##  Redistribution and use in source and binary forms, with or without
+##  modification, are permitted provided that the following conditions
+##  are met:
+##
+##     * Redistributions of source code must retain the above copyright
+##       notice, this list of conditions and the following disclaimer.
+##
+##     * Redistributions in binary form must reproduce the above
+##       copyright notice, this list of conditions and the following
+##       disclaimer in the documentation and/or other materials provided
+##       with the distribution.
+##
+##     * Neither the name of the University of California, Berkeley nor
+##       the names of its contributors may be used to endorse or promote
+##       products derived from this software without specific prior
+##       written permission.
+##
+##  THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS AND
+##  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.
+
+## Author: Jason Riedy <ejr at cs.berkeley.edu>
+## Keywords: linear-algebra norm estimation
+## Version: 0.2
+
+function [est, v] = condest (varargin)
+
+  if (nargin < 1 || nargin > 6)
+    print_usage ();
+  endif
+
+  default_t = 5;
+
+  have_A = false;
+  have_t = false;
+  have_solve = false;
+
+  if (ismatrix (varargin{1}))
+    A = varargin{1};
+    n = issquare (A);
+    if (! n)
+      error ("condest: matrix must be square");
+    endif
+    have_A = true;
+
+    if (nargin > 1)
+      if (isscalar (varargin{2}))
+	t = varargin{2};
+	have_t = true;
+      elseif (nargin > 2)
+	solve = varargin{2};
+	solve_t = varargin{3};
+	have_solve = true;
+	if (nargin > 3)
+	  t = varargin{4};
+	  have_t = true;
+	endif
+      else
+	error ("condest: must supply both solve and solve_t");
+      endif
+    endif
+  elseif (nargin > 4)
+    apply = varargin{1};
+    apply_t = varargin{2};
+    solve = varargin{3};
+    solve_t = varargin{4};
+    have_solve = true;
+    n = varargin{5};
+    if (! isscalar (n))
+      error ("condest: dimension argument of implicit form must be scalar");
+    endif
+    if (nargin > 5)
+      t = varargin{6};
+      have_t = true;
+    endif
+  else
+    error ("condest: implicit form of condest requires at least 5 arguments");
+  endif
+
+  if (! have_t)
+    t = min (n, default_t);
+  endif
+
+  if (! have_solve)
+    if (issparse (A))
+      [L, U, P, Pc] = lu (A);
+      solve = @(x) Pc' * (U \ (L \ (P * x)));
+      solve_t = @(x) P' * (L' \ (U' \ (Pc * x)));
+    else
+      [L, U, P] = lu (A);
+      solve = @(x) U \ (L \ (P*x));
+      solve_t = @(x) P' * (L' \ (U' \ x));
+    endif
+  endif
+
+  if (have_A)
+    Anorm = norm (A, 1);
+  else
+    Anorm = onenormest (apply, apply_t, n, t);
+  endif
+
+  [Ainv_norm, v, w] = onenormest (solve, solve_t, n, t);
+
+  est = Anorm * Ainv_norm;
+  v = w / norm (w, 1);
+
+endfunction
+
+%!demo
+%!  N = 100;
+%!  A = randn (N) + eye (N);
+%!  condest (A)
+%!  [L,U,P] = lu (A);
+%!  condest (A, @(x) U\ (L\ (P*x)), @(x) P'*(L'\ (U'\x)))
+%!  condest (@(x) A*x, @(x) A'*x, @(x) U\ (L\ (P*x)), @(x) P'*(L'\ (U'\x)), N)
+%!  norm (inv (A), 1) * norm (A, 1)
+
+## Yes, these test bounds are really loose.  There's
+## enough randomization to trigger odd cases with hilb().
+
+%!test
+%!  N = 6;
+%!  A = hilb (N);
+%!  cA = condest (A);
+%!  cA_test = norm (inv (A), 1) * norm (A, 1);
+%!  assert (cA, cA_test, -2^-8);
+
+%!test
+%!  N = 6;
+%!  A = hilb (N);
+%!  solve = @(x) A\x; solve_t = @(x) A'\x;
+%!  cA = condest (A, solve, solve_t);
+%!  cA_test = norm (inv (A), 1) * norm (A, 1);
+%!  assert (cA, cA_test, -2^-8);
+
+%!test
+%!  N = 6;
+%!  A = hilb (N);
+%!  apply = @(x) A*x; apply_t = @(x) A'*x;
+%!  solve = @(x) A\x; solve_t = @(x) A'\x;
+%!  cA = condest (apply, apply_t, solve, solve_t, N);
+%!  cA_test = norm (inv (A), 1) * norm (A, 1);
+%!  assert (cA, cA_test, -2^-6);
+
+%!test
+%!  N = 12;
+%!  A = hilb (N);
+%!  [rcondA, v] = condest (A);
+%!  x = A*v;
+%!  assert (norm(x, inf), 0, eps);
diff --git a/scripts/linear-algebra/cross.m b/scripts/linear-algebra/cross.m
new file mode 100644
index 0000000..826a5a2
--- /dev/null
+++ b/scripts/linear-algebra/cross.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} cross (@var{x}, @var{y})
+## @deftypefnx {Function File} {} cross (@var{x}, @var{y}, @var{dim})
+## Compute the vector cross product of two 3-dimensional vectors
+## @var{x} and @var{y}.
+##
+## @example
+## @group
+## cross ([1,1,0], [0,1,1])
+##      @result{} [ 1; -1; 1 ]
+## @end group
+## @end example
+##
+## If @var{x} and @var{y} are matrices, the cross product is applied 
+## along the first dimension with 3 elements.  The optional argument 
+## @var{dim} forces the cross product to be calculated along
+## the specified dimension.
+## @seealso{dot}
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Created: 15 October 1994
+## Adapted-By: jwe
+
+function z = cross (x, y, dim)
+	
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (ndims (x) < 3 && ndims (y) < 3 && nargin < 3)
+    ## COMPATIBILITY -- opposite behaviour for cross(row,col)
+    ## Swap x and y in the assignments below to get the matlab behaviour.
+    ## Better yet, fix the calling code so that it uses conformant vectors.
+    if (columns (x) == 1 && rows (y) == 1)
+      warning ("cross: taking cross product of column by row");
+      y = y.';
+    elseif (rows (x) == 1 && columns (y) == 1)
+      warning ("cross: taking cross product of row by column");
+      x = x.';
+    endif
+  endif
+
+  if (nargin == 2)
+     dim = find (size (x) == 3, 1);
+     if (isempty (dim)) 
+       error ("cross: must have at least one dimension with 3 elements");
+     endif
+   else
+     if (size (x) != 3)
+       error ("cross: dimension dim must have 3 elements");
+     endif
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  idx1 = cell (1, nd);
+  for i = 1:nd
+    idx1{i} = 1:sz(i);
+  endfor
+  idx2 = idx3 = idx1;
+  idx1(dim) = 1;
+  idx2(dim) = 2;
+  idx3(dim) = 3;
+
+  if (size_equal (x, y))
+    z = cat (dim, 
+	     (x(idx2{:}) .* y(idx3{:}) - x(idx3{:}) .* y(idx2{:})),
+             (x(idx3{:}) .* y(idx1{:}) - x(idx1{:}) .* y(idx3{:})),
+             (x(idx1{:}) .* y(idx2{:}) - x(idx2{:}) .* y(idx1{:})));
+  else
+    error ("cross: x and y must have the same dimensions");
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/dot.m b/scripts/linear-algebra/dot.m
new file mode 100644
index 0000000..db6a931
--- /dev/null
+++ b/scripts/linear-algebra/dot.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dot (@var{x}, @var{y}, @var{dim})
+## Computes the dot product of two vectors.  If @var{x} and @var{y}
+## are matrices, calculate the dot-product along the first 
+## non-singleton dimension.  If the optional argument @var{dim} is
+## given, calculate the dot-product along this dimension.
+## @end deftypefn
+
+## Author: jwe
+
+function z = dot (x, y, dim)
+
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin < 3)
+    if isvector (x)
+      x = x(:);
+    endif
+    if isvector (y)
+      y = y(:);
+    endif
+    if (! size_equal (x, y))
+      error ("dot: sizes of arguments must match");
+    endif
+    z = sum(conj (x) .* y);
+  else
+    if (! size_equal (x, y))
+      error ("dot: sizes of arguments must match");
+    endif
+    z = sum(conj (x) .* y, dim);
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/duplication_matrix.m b/scripts/linear-algebra/duplication_matrix.m
new file mode 100644
index 0000000..7a780e0
--- /dev/null
+++ b/scripts/linear-algebra/duplication_matrix.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} duplication_matrix (@var{n})
+## Return the duplication matrix
+## @tex
+##  $D_n$
+## @end tex
+## @ifnottex
+##  @math{Dn}
+## @end ifnottex
+##  which is the unique
+## @tex
+##  $n^2 \times n(n+1)/2$
+## @end tex
+## @ifnottex
+##  @math{n^2} by @math{n*(n+1)/2}
+## @end ifnottex
+##  matrix such that
+## @tex
+##  $D_n * {\rm vech} (A) = {\rm vec} (A)$
+## @end tex
+## @ifnottex
+##  @math{Dn vech (A) = vec (A)}
+## @end ifnottex
+##  for all symmetric
+## @tex
+##  $n \times n$
+## @end tex
+## @ifnottex
+##  @math{n} by @math{n}
+## @end ifnottex
+##  matrices
+## @tex
+##  $A$.
+## @end tex
+## @ifnottex
+##  @math{A}.
+## @end ifnottex
+##
+## See Magnus and Neudecker (1988), Matrix differential calculus with
+## applications in statistics and econometrics.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 8 May 1995
+## Adapged-By: jwe
+
+function d = duplication_matrix (n)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isscalar (n) && n == round (n) && n > 0))
+    error ("duplication_matrix: n must be a positive integer");
+  endif
+
+  d = zeros (n * n, n * (n + 1) / 2);
+
+  ## It is clearly possible to make this a LOT faster!
+  count = 0;
+  for j = 1 : n
+    d ((j - 1) * n + j, count + j) = 1;
+    for i = (j + 1) : n
+      d ((j - 1) * n + i, count + i) = 1;
+      d ((i - 1) * n + j, count + i) = 1;
+    endfor
+    count = count + n - j;
+  endfor
+
+endfunction
diff --git a/scripts/linear-algebra/expm.m b/scripts/linear-algebra/expm.m
new file mode 100644
index 0000000..7f99bcb
--- /dev/null
+++ b/scripts/linear-algebra/expm.m
@@ -0,0 +1,148 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek, Marco Caliari
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} expm (@var{a})
+## Return the exponential of a matrix, defined as the infinite Taylor
+## series
+## @tex
+## $$
+##  \exp (A) = I + A + {A^2 \over 2!} + {A^3 \over 3!} + \cdots
+## $$
+## @end tex
+## @ifnottex
+## 
+## @example
+## expm(a) = I + a + a^2/2! + a^3/3! + @dots{}
+## @end example
+## 
+## @end ifnottex
+## The Taylor series is @emph{not} the way to compute the matrix
+## exponential; see Moler and Van Loan, @cite{Nineteen Dubious Ways to
+## Compute the Exponential of a Matrix}, SIAM Review, 1978.  This routine
+## uses Ward's diagonal
+## @tex
+## Pad\'e
+## @end tex
+## @ifnottex
+## Pade'
+## @end ifnottex
+## approximation method with three step preconditioning (SIAM Journal on
+## Numerical Analysis, 1977).  Diagonal
+## @tex
+## Pad\'e
+## @end tex
+## @ifnottex
+## Pade'
+## @end ifnottex
+##  approximations are rational polynomials of matrices
+## @tex
+## $D_q(a)^{-1}N_q(a)$
+## @end tex
+## @ifnottex
+## 
+## @example
+## @group
+##      -1
+## D (a)   N (a)
+## @end group
+## @end example
+## 
+## @end ifnottex
+##  whose Taylor series matches the first
+## @tex
+## $2 q + 1 $
+## @end tex
+## @ifnottex
+## @code{2q+1}
+## @end ifnottex
+## terms of the Taylor series above; direct evaluation of the Taylor series
+## (with the same preconditioning steps) may be desirable in lieu of the
+## @tex
+## Pad\'e
+## @end tex
+## @ifnottex
+## Pade'
+## @end ifnottex
+## approximation when
+## @tex
+## $D_q(a)$
+## @end tex
+## @ifnottex
+## @code{Dq(a)}
+## @end ifnottex
+## is ill-conditioned.
+## @end deftypefn
+
+function r = expm (a)
+
+  if (! ismatrix (a) || ! issquare (a))
+    error ("expm requires a square matrix");
+  endif
+
+  n = rows (a);
+  ## Trace reduction.
+  a(a == -Inf) = -realmax;
+  trshift = trace (a) / length (a);
+  if (trshift > 0)
+    a -= trshift*eye (n);
+  endif
+  ## Balancing.
+  [d, p, aa] = balance (a);
+  ## FIXME: can we both permute and scale at once? Or should we rather do
+  ## this:
+  ##
+  ##   [d, xx, aa] = balance (a, "noperm");
+  ##   [xx, p, aa] = balance (aa, "noscal");
+  [f, e] = log2 (norm (aa, "inf"));
+  s = max (0, e);
+  s = min (s, 1023);
+  aa *= 2^(-s);
+
+  ## Pade approximation for exp(A).
+  c = [5.0000000000000000e-1,...
+       1.1666666666666667e-1,...
+       1.6666666666666667e-2,...
+       1.6025641025641026e-3,...
+       1.0683760683760684e-4,...
+       4.8562548562548563e-6,...
+       1.3875013875013875e-7,...
+       1.9270852604185938e-9];
+
+  a2 = aa^2;
+  id = eye (n);
+  x = (((c(8) * a2 + c(6) * id) * a2 + c(4) * id) * a2 + c(2) * id) * a2 + id;
+  y = (((c(7) * a2 + c(5) * id) * a2 + c(3) * id) * a2 + c(1) * id) * aa;
+
+  r = (x - y) \ (x + y);
+
+  ## Undo scaling by repeated squaring.
+  for k = 1:s
+    r ^= 2;
+  endfor
+
+  ## inverse balancing.
+  d = diag (d);
+  r = d * r / d;
+  r(p, p) = r;
+  ## Inverse trace reduction.
+  if (trshift >0)
+    r *= exp (trshift);
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/housh.m b/scripts/linear-algebra/housh.m
new file mode 100644
index 0000000..f3f9db6
--- /dev/null
+++ b/scripts/linear-algebra/housh.m
@@ -0,0 +1,91 @@
+## Copyright (C) 1995, 1998, 1999, 2000, 2002, 2005, 2007, 2009
+##               A. Scottedward Hodel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{housv}, @var{beta}, @var{zer}] =} housh (@var{x}, @var{j}, @var{z})
+## Compute Householder reflection vector @var{housv} to reflect @var{x}
+## to be the j-th column of identity, i.e.,
+##
+## @example
+## @group
+## (I - beta*housv*housv')x =  norm(x)*e(j) if x(1) < 0,
+## (I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0
+## @end group
+## @end example
+##
+## @noindent
+## Inputs
+##
+## @table @var
+## @item x
+## vector
+## @item j
+## index into vector
+## @item z
+## threshold for zero  (usually should be the number 0)
+## @end table
+##
+## @noindent
+## Outputs (see Golub and Van Loan):
+##
+## @table @var
+## @item beta
+## If beta = 0, then no reflection need be applied (zer set to 0)
+## @item housv
+## householder vector
+## @end table
+## @end deftypefn
+
+## Author: A. S. Hodel
+## Created: August 1995
+
+function [housv, beta, zer] = housh (x, j, z)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  ## Check for valid inputs.
+  if (! isvector (x) && ! isscalar (x))
+    error ("housh: first input must be a vector");
+  elseif (! isscalar(j))
+    error ("housh: second argment must be an integer scalar");
+  else
+    housv = x;
+    m = max (abs (housv));
+    if (m != 0.0)
+      housv = housv / m;
+      alpha = norm (housv);
+      if (alpha > z)
+        beta = 1.0 / (alpha * (alpha + abs (housv(j))));
+        sg = sign (housv(j));
+        if (sg == 0)
+          sg = 1;
+        endif
+        housv(j) = housv(j) + alpha*sg;
+      else
+        beta = 0.0;
+      endif
+    else
+      beta = 0.0;
+    endif
+    zer = (beta == 0);
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/krylov.m b/scripts/linear-algebra/krylov.m
new file mode 100644
index 0000000..72e6bfb
--- /dev/null
+++ b/scripts/linear-algebra/krylov.m
@@ -0,0 +1,239 @@
+## Copyright (C) 1993, 1998, 1999, 2000, 2002, 2003, 2005, 2006, 2007,
+##               2008, 2009 Auburn University.  All rights reserved.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{u}, @var{h}, @var{nu}] =} krylov (@var{a}, @var{v}, @var{k}, @var{eps1}, @var{pflg})
+## Construct an orthogonal basis @var{u} of block Krylov subspace
+##
+## @example
+## [v a*v a^2*v @dots{} a^(k+1)*v]
+## @end example
+##
+## @noindent
+## Using Householder reflections to guard against loss of orthogonality.
+##
+## If @var{v} is a vector, then @var{h} contains the Hessenberg matrix
+## such that @code{a*u == u*h+rk*ek'}, in which @code{rk =
+## a*u(:,k)-u*h(:,k)}, and @code{ek'} is the vector
+## @code{[0, 0, @dots{}, 1]} of length @code{k}.  Otherwise, @var{h} is
+## meaningless.
+##
+## If @var{v} is a vector and @var{k} is greater than
+## @code{length(A)-1}, then @var{h} contains the Hessenberg matrix such
+## that @code{a*u == u*h}.
+##
+## The value of @var{nu} is the dimension of the span of the krylov
+## subspace (based on @var{eps1}).
+##
+## If @var{b} is a vector and @var{k} is greater than @var{m-1}, then
+## @var{h} contains the Hessenberg decomposition of @var{a}.
+##
+## The optional parameter @var{eps1} is the threshold for zero.  The
+## default value is 1e-12.
+##
+## If the optional parameter @var{pflg} is nonzero, row pivoting is used
+## to improve numerical behavior.  The default value is 0.
+##
+## Reference: Hodel and Misra, "Partial Pivoting in the Computation of
+## Krylov Subspaces", to be submitted to Linear Algebra and its
+## Applications
+## @end deftypefn
+
+## Author: A. Scottedward Hodel <a.s.hodel at eng.auburn.edu>
+
+function [Uret, H, nu] = krylov (A, V, k, eps1, pflg);
+
+  if (isa (A, "single") || isa (V, "single"))
+    defeps = 1e-6
+  else
+    defeps = 1e-12;
+  endif
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  elseif (nargin < 5)
+    ## Default permutation flag.
+    pflg = 0;
+  endif
+
+  if(nargin < 4)
+    ## Default tolerance parameter.
+    eps1 = defeps;
+  endif
+
+  if (isempty (eps1))
+    eps1 = defeps;
+  endif
+
+  na = issquare (A);
+  if (! na)
+    error ("A(%d x %d) must be square", rows (A), columns (A));
+  endif
+
+  [m, kb] = size (V);
+  if (m != na)
+    error("A(%d x %d), V(%d x %d): argument dimensions do not match",
+	  na, na, m, kb)
+  endif
+
+  if (! isscalar (k))
+    error ("krylov: third argument must be a scalar integer");
+  endif
+
+  Vnrm = norm (V, Inf);
+
+  ## check for trivial solution.
+  if (Vnrm == 0)
+    Uret = [];
+    H = [];
+    nu = 0;
+    return;
+  endif
+
+  ## Identify trivial null space.
+  abm = max (abs ([A, V]'));
+  zidx = find (abm == 0);
+
+  ## Set up vector of pivot points.
+  pivot_vec = 1:na;
+
+  iter = 0;
+  alpha = [];
+  nh = 0;
+  while (length(alpha) < na) && (columns(V) > 0) && (iter < k)
+    iter++;
+
+    ## Get orthogonal basis of V.
+    jj = 1;
+    while (jj <= columns (V) && length (alpha) < na)
+      ## Index of next Householder reflection.
+      nu = length(alpha)+1;
+
+      short_pv = pivot_vec(nu:na);
+      q = V(:,jj);
+      short_q = q(short_pv);
+
+      if (norm (short_q) < eps1)
+	## Insignificant column; delete.
+        nv = columns (V);
+        if (jj != nv)
+          [V(:,jj), V(:,nv)] = swap (V(:,jj), V(:,nv));
+	  ## FIXME -- H columns should be swapped too.  Not done
+	  ## since Block Hessenberg structure is lost anyway.
+        endif
+        V = V(:,1:(nv-1));
+	## One less reflection.
+        nu--;
+      else
+	## New householder reflection.
+        if (pflg)
+          ## Locate max magnitude element in short_q.
+          asq = abs (short_q);
+          maxv = max (asq);
+          maxidx = find (asq == maxv, 1);
+          pivot_idx = short_pv(maxidx);
+
+	  ## See if need to change the pivot list.
+          if (pivot_idx != pivot_vec(nu))
+            swapidx = maxidx + (nu-1);
+            [pivot_vec(nu), pivot_vec(swapidx)] = ...
+		swap (pivot_vec(nu), pivot_vec(swapidx));
+          endif
+        endif
+
+	## Isolate portion of vector for reflection.
+        idx = pivot_vec(nu:na);
+        jdx = pivot_vec(1:nu);
+
+        [hv, av, z] = housh (q(idx), 1, 0);
+        alpha(nu) = av;
+        U(idx,nu) = hv;
+
+        ## Reduce V per the reflection.
+        V(idx,:) = V(idx,:) - av*hv*(hv' * V(idx,:));
+        if(iter > 1)
+	  ## FIXME -- not done correctly for block case.
+          H(nu,nu-1) = V(pivot_vec(nu),jj);
+        endif
+
+        ## Advance to next column of V.
+        jj++;
+      endif
+    endwhile
+
+    ## Check for oversize V (due to full rank).
+    if ((columns (V) > na) && (length (alpha) == na))
+      ## Trim to size.
+      V = V(:,1:na);
+    elseif (columns(V) > na)
+      krylov_V = V
+      krylov_na = na
+      krylov_length_alpha = length (alpha)
+      error ("This case should never happen; submit a bug report");
+    endif
+
+    if (columns (V) > 0)
+      ## Construct next Q and multiply.
+      Q = zeros (size (V));
+      for kk = 1:columns (Q)
+        Q(pivot_vec(nu-columns(Q)+kk),kk) = 1;
+      endfor
+
+      ## Apply Householder reflections.
+      for ii = nu:-1:1
+        idx = pivot_vec(ii:na);
+        hv = U(idx,ii);
+        av = alpha(ii);
+        Q(idx,:) = Q(idx,:) - av*hv*(hv'*Q(idx,:));
+      endfor
+    endif
+
+    ## Multiply to get new vector.
+    V = A*Q;
+    ## Project off of previous vectors.
+    nu = length (alpha);
+    for i = 1:nu
+      hv = U(:,i);
+      av = alpha(i);
+      V = V - av*hv*(hv'*V);
+      H(i,nu-columns(V)+(1:columns(V))) = V(pivot_vec(i),:);
+    endfor
+
+  endwhile
+
+  ## Back out complete U matrix.
+  ## back out U matrix.
+  j1 = columns (U);
+  for i = j1:-1:1;
+    idx = pivot_vec(i:na);
+    hv = U(idx,i);
+    av = alpha(i);
+    U(:,i) = zeros (na, 1);
+    U(idx(1),i) = 1;
+    U(idx,i:j1) = U(idx,i:j1)-av*hv*(hv'*U(idx,i:j1));
+  endfor
+
+  nu = length (alpha);
+  Uret = U;
+  if (max (max (abs (Uret(zidx,:)))) > 0)
+    warning ("krylov: trivial null space corrupted; set pflg = 1 or eps1 > %e",
+	     eps1);
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/krylovb.m b/scripts/linear-algebra/krylovb.m
new file mode 100644
index 0000000..56d3b4c
--- /dev/null
+++ b/scripts/linear-algebra/krylovb.m
@@ -0,0 +1,38 @@
+## Copyright (C) 1993, 1998, 1999, 2000, 2003, 2005, 2006, 2007
+##               A. Scottedward Hodel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{u}, @var{ucols}] =} krylovb (@var{a}, @var{v}, @var{k}, @var{eps1}, @var{pflg})
+## See @code{krylov}.
+## @end deftypefn
+
+function [Uret, Ucols] = krylovb (A, V, k, eps1, pflg)
+
+  switch (nargin)
+    case (3)
+      [Uret, H, Ucols] = krylov (A, V, k);
+    case (4)
+      [Uret, H, Ucols] = krylov (A, V, k, eps1);
+    case (5)
+      [Uret, H, Ucols] = krylov (A, V, k, eps1, pflg);
+    otherwise
+      print_usage ();
+  endswitch
+
+endfunction
diff --git a/scripts/linear-algebra/logm.m b/scripts/linear-algebra/logm.m
new file mode 100644
index 0000000..4711259
--- /dev/null
+++ b/scripts/linear-algebra/logm.m
@@ -0,0 +1,35 @@
+## Copyright (C) 2003, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logm (@var{a})
+## Compute the matrix logarithm of the square matrix @var{a}.  Note that
+## this is currently implemented in terms of an eigenvalue expansion and
+## needs to be improved to be more robust.
+## @end deftypefn
+
+function B = logm (A)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [V, D] = eig (A);
+  B = V * diag (log (diag (D))) * inv (V);
+
+endfunction
diff --git a/scripts/linear-algebra/null.m b/scripts/linear-algebra/null.m
new file mode 100644
index 0000000..344ca9a
--- /dev/null
+++ b/scripts/linear-algebra/null.m
@@ -0,0 +1,78 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2003, 2005, 2006,
+##               2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} null (@var{a}, @var{tol})
+## Return an orthonormal basis of the null space of @var{a}.
+##
+## The dimension of the null space is taken as the number of singular
+## values of @var{a} not greater than @var{tol}.  If the argument @var{tol}
+## is missing, it is computed as
+##
+## @example
+## max (size (@var{a})) * max (svd (@var{a})) * eps
+## @end example
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 24 December 1993.
+## Adapted-By: jwe
+
+function retval = null (A, tol)
+
+  if (isempty (A))
+    retval = [];
+  else
+    [U, S, V] = svd (A);
+
+    [rows, cols] = size (A);
+
+    [S_nr, S_nc] = size (S);
+
+    if (S_nr == 1 || S_nc == 1)
+      s = S(1);
+    else
+      s = diag (S);
+    endif
+
+    if (nargin == 1)
+      if (isa (A, "single"))
+	tol = max (size (A)) * s (1) * eps ("single");
+      else
+	tol = max (size (A)) * s (1) * eps;
+      endif
+    elseif (nargin != 2)
+      print_usage ();
+    endif
+
+    rank = sum (s > tol);
+
+    if (rank < cols)
+      retval = V (:, rank+1:cols);
+      if (isa (A, "single"))
+	retval(abs (retval) < eps ("single")) = 0;
+      else
+	retval(abs (retval) < eps) = 0;
+      endif
+    else
+      retval = zeros (cols, 0);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/onenormest.m b/scripts/linear-algebra/onenormest.m
new file mode 100644
index 0000000..4edad26
--- /dev/null
+++ b/scripts/linear-algebra/onenormest.m
@@ -0,0 +1,284 @@
+## Copyright (C) 2007, 2008, 2009 Regents of the University of California
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{a}, @var{t}) 
+## @deftypefnx {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{apply}, @var{apply_t}, @var{n}, @var{t})
+##
+## Apply Higham and Tisseur's randomized block 1-norm estimator to
+## matrix @var{a} using @var{t} test vectors.  If @var{t} exceeds 5, then
+## only 5 test vectors are used.
+##
+## If the matrix is not explicit, e.g., when estimating the norm of 
+## @code{inv (@var{A})} given an LU factorization, @code{onenormest} applies 
+## @var{A} and its conjugate transpose through a pair of functions 
+## @var{apply} and @var{apply_t}, respectively, to a dense matrix of size 
+## @var{n} by @var{t}.  The implicit version requires an explicit dimension 
+## @var{n}.
+##
+## Returns the norm estimate @var{est}, two vectors @var{v} and
+## @var{w} related by norm
+## @code{(@var{w}, 1) = @var{est} * norm (@var{v}, 1)},
+## and the number of iterations @var{iter}.  The number of
+## iterations is limited to 10 and is at least 2.
+##
+## References: 
+## @itemize
+## @item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+## for Matrix 1-Norm Estimation, with an Application to 1-Norm
+## Pseudospectra." SIMAX vol 21, no 4, pp 1185-1201.
+## @url{http://dx.doi.org/10.1137/S0895479899356080}
+## @item Nicholas J. Higham and Françoise Tisseur, "A Block Algorithm
+## for Matrix 1-Norm Estimation, with an Application to 1-Norm
+## Pseudospectra." @url{http://citeseer.ist.psu.edu/223007.html}
+## @end itemize
+##
+## @seealso{condest, norm, cond}
+## @end deftypefn
+
+## Code originally licensed under
+##
+##  Copyright (c) 2007, Regents of the University of California
+##  All rights reserved.
+##
+##  Redistribution and use in source and binary forms, with or without
+##  modification, are permitted provided that the following conditions
+##  are met:
+##
+##     * Redistributions of source code must retain the above copyright
+##       notice, this list of conditions and the following disclaimer.
+##
+##     * Redistributions in binary form must reproduce the above
+##       copyright notice, this list of conditions and the following
+##       disclaimer in the documentation and/or other materials provided
+##       with the distribution.
+##
+##     * Neither the name of the University of California, Berkeley nor
+##       the names of its contributors may be used to endorse or promote
+##       products derived from this software without specific prior
+##       written permission.
+##
+##  THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS AND
+##  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.
+
+## Author: Jason Riedy <ejr at cs.berkeley.edu>
+## Keywords: linear-algebra norm estimation
+## Version: 0.2
+
+function [est, v, w, iter] = onenormest (varargin)
+
+  if (size (varargin, 2) < 1 || size (varargin, 2) > 4)
+    print_usage ();
+  endif
+
+  default_t = 5;
+  itmax = 10;
+
+  if (ismatrix (varargin{1}))
+    n = size (varargin{1}, 1);
+    if n != size (varargin{1}, 2),
+      error ("onenormest: matrix must be square");
+    endif
+    apply = @(x) varargin{1} * x;
+    apply_t = @(x) varargin{1}' * x;
+    if (size (varargin) > 1)
+      t = varargin{2};
+    else
+      t = min (n, default_t);
+    endif
+    issing = isa (varargin {1}, "single");
+  else
+    if (size (varargin, 2) < 3)
+      print_usage();
+    endif
+    n = varargin{3};
+    apply = varargin{1};
+    apply_t = varargin{2};
+    if (size (varargin) > 3)
+      t = varargin{4};
+    else
+      t = default_t;
+    endif
+    issing = isa (varargin {3}, "single");
+  endif
+
+  ## Initial test vectors X.
+  X = rand (n, t);
+  X = X ./ (ones (n,1) * sum (abs (X), 1));
+
+  ## Track if a vertex has been visited.
+  been_there = zeros (n, 1);
+
+  ## To check if the estimate has increased.
+  est_old = 0;
+
+  ## Normalized vector of signs.
+  S = zeros (n, t);
+
+  if (issing)
+    myeps = eps ("single");
+    X = single (X);
+  else
+    myeps = eps;
+  endif
+
+  for iter = 1 : itmax + 1
+    Y = feval (apply, X);
+
+    ## Find the initial estimate as the largest A*x.
+    [est, ind_best] = max (sum (abs (Y), 1));
+    if (est > est_old || iter == 2)
+      w = Y(:,ind_best);
+    endif
+    if (iter >= 2 && est < est_old)
+      ## No improvement, so stop.
+      est = est_old;
+      break;
+    endif
+
+    est_old = est;
+    S_old = S;
+    if (iter > itmax),
+      ## Gone too far.  Stop.
+      break;
+    endif
+
+    S = sign (Y);
+
+    ## Test if any of S are approximately parallel to previous S
+    ## vectors or current S vectors.  If everything is parallel,
+    ## stop. Otherwise, replace any parallel vectors with
+    ## rand{-1,+1}.
+    partest = any (abs (S_old' * S - n) < 4*eps*n);
+    if (all (partest))
+      ## All the current vectors are parallel to old vectors.
+      ## We've hit a cycle, so stop.
+      break;
+    endif
+    if (any (partest))
+      ## Some vectors are parallel to old ones and are cycling,
+      ## but not all of them.  Replace the parallel vectors with
+      ## rand{-1,+1}.
+      numpar = sum (partest);
+      replacements = 2*(rand (n,numpar) < 0.5) - 1;
+      S(:,partest) = replacements;
+    endif
+    ## Now test for parallel vectors within S.
+    partest = any ((S' * S - eye (t)) == n);
+    if (any (partest))
+      numpar = sum (partest);
+      replacements = 2*(rand (n,numpar) < 0.5) - 1;
+      S(:,partest) = replacements;
+    endif
+    
+    Z = feval (apply_t, S);
+
+    ## Now find the largest non-previously-visted index per
+    ## vector.
+    h = max (abs (Z),2);
+    [mh, mhi] = max (h);
+    if (iter >= 2 && mhi == ind_best)
+      ## Hit a cycle, stop.
+      break;
+    endif
+    [h, ind] = sort (h, 'descend');
+    if (t > 1)
+      firstind = ind(1:t);
+      if (all (been_there(firstind)))
+	## Visited all these before, so stop.
+	break;
+      endif
+      ind = ind (!been_there (ind));
+      if (length (ind) < t)
+	## There aren't enough new vectors, so we're practically
+	## in a cycle. Stop.
+	break;
+      endif
+    endif
+
+    ## Visit the new indices.
+    X = zeros (n, t);
+    for zz = 1 : t
+      X(ind(zz),zz) = 1;
+    endfor
+    been_there (ind (1 : t)) = 1;
+  endfor
+
+  ## The estimate est and vector w are set in the loop above. The
+  ## vector v selects the ind_best column of A.
+  v = zeros (n, 1);
+  v(ind_best) = 1;
+endfunction
+
+%!demo
+%!  N = 100;
+%!  A = randn(N) + eye(N);
+%!  [L,U,P] = lu(A);
+%!  nm1inv = onenormest(@(x) U\(L\(P*x)), @(x) P'*(L'\(U'\x)), N, 30)
+%!  norm(inv(A), 1)
+
+%!test
+%!  N = 10;
+%!  A = ones (N);
+%!  [nm1, v1, w1] = onenormest (A);
+%!  [nminf, vinf, winf] = onenormest (A', 6);
+%!  assert (nm1, N, -2*eps);
+%!  assert (nminf, N, -2*eps);
+%!  assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps)
+%!  assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps)
+
+%!test
+%!  N = 10;
+%!  A = ones (N);
+%!  [nm1, v1, w1] = onenormest (@(x) A*x, @(x) A'*x, N, 3);
+%!  [nminf, vinf, winf] = onenormest (@(x) A'*x, @(x) A*x, N, 3);
+%!  assert (nm1, N, -2*eps);
+%!  assert (nminf, N, -2*eps);
+%!  assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps)
+%!  assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps)
+
+%!test
+%!  N = 5;
+%!  A = hilb (N);
+%!  [nm1, v1, w1] = onenormest (A);
+%!  [nminf, vinf, winf] = onenormest (A', 6);
+%!  assert (nm1, norm (A, 1), -2*eps);
+%!  assert (nminf, norm (A, inf), -2*eps);
+%!  assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps)
+%!  assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps)
+
+## Only likely to be within a factor of 10.
+%!test
+%!  N = 100;
+%!  A = rand (N);
+%!  [nm1, v1, w1] = onenormest (A);
+%!  [nminf, vinf, winf] = onenormest (A', 6);
+%!  assert (nm1, norm (A, 1), -.1);
+%!  assert (nminf, norm (A, inf), -.1);
+%!  assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps)
+%!  assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps)
diff --git a/scripts/linear-algebra/orth.m b/scripts/linear-algebra/orth.m
new file mode 100644
index 0000000..957f01a
--- /dev/null
+++ b/scripts/linear-algebra/orth.m
@@ -0,0 +1,75 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2005, 2006,
+##               2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} orth (@var{a}, @var{tol})
+## Return an orthonormal basis of the range space of @var{a}.
+##
+## The dimension of the range space is taken as the number of singular
+## values of @var{a} greater than @var{tol}.  If the argument @var{tol} is
+## missing, it is computed as
+##
+## @example
+## max (size (@var{a})) * max (svd (@var{a})) * eps
+## @end example
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 24 December 1993.
+## Adapted-By: jwe
+
+function retval = orth (A, tol)
+
+  if (nargin == 1 || nargin == 2)
+
+    [U, S, V] = svd (A);
+
+    [rows, cols] = size (A);
+
+    [S_nr, S_nc] = size (S);
+
+    if (S_nr == 1 || S_nc == 1)
+      s = S(1);
+    else
+      s = diag (S);
+    endif
+
+    if (nargin == 1)
+      if (isa (A, "single"))
+	tol = max (size (A)) * s (1) * eps ("single");
+      else
+	tol = max (size (A)) * s (1) * eps;
+      endif
+    endif
+
+    rank = sum (s > tol);
+
+    if (rank > 0)
+      retval = -U (:, 1:rank);
+    else
+      retval = zeros (rows, 0);
+    endif
+
+  else
+
+    print_usage ();
+
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/planerot.m b/scripts/linear-algebra/planerot.m
new file mode 100644
index 0000000..92ae3ad
--- /dev/null
+++ b/scripts/linear-algebra/planerot.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{g}, @var{y}] =} planerot (@var{x})
+## Given a two-element column vector, returns the
+## @tex
+## $2 \times 2$ orthogonal matrix
+## @end tex
+## @ifnottex
+## 2 by 2 orthogonal matrix
+## @end ifnottex
+## @var{G} such that
+## @code{@var{y} = @var{g} * @var{x}} and @code{@var{y}(2) = 0}.
+## @seealso{givens}
+## @end deftypefn
+
+function [G, y] = planerot (x)
+  G = givens (x(1), x(2));
+  y = G * x(:);
+endfunction
diff --git a/scripts/linear-algebra/qzhess.m b/scripts/linear-algebra/qzhess.m
new file mode 100644
index 0000000..abcd700
--- /dev/null
+++ b/scripts/linear-algebra/qzhess.m
@@ -0,0 +1,93 @@
+## Copyright (C) 1993, 1995, 1996, 1997, 1999, 2000, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{aa}, @var{bb}, @var{q}, @var{z}] =} qzhess (@var{a}, @var{b})
+## Compute the Hessenberg-triangular decomposition of the matrix pencil
+## @code{(@var{a}, @var{b})}, returning
+## @code{@var{aa} = @var{q} * @var{a} * @var{z}},
+## @code{@var{bb} = @var{q} * @var{b} * @var{z}}, with @var{q} and @var{z}
+## orthogonal.  For example,
+##
+## @example
+## @group
+## [aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
+##      @result{} aa = [ -3.02244, -4.41741;  0.92998,  0.69749 ]
+##      @result{} bb = [ -8.60233, -9.99730;  0.00000, -0.23250 ]
+##      @result{}  q = [ -0.58124, -0.81373; -0.81373,  0.58124 ]
+##      @result{}  z = [ 1, 0; 0, 1 ]
+## @end group
+## @end example
+##
+## The Hessenberg-triangular decomposition is the first step in
+## Moler and Stewart's QZ decomposition algorithm.
+##
+## Algorithm taken from Golub and Van Loan, @cite{Matrix Computations, 2nd
+## edition}.
+## @end deftypefn
+
+## Author: A. S. Hodel <scotte at eng.auburn.edu>
+## Created: August 1993
+## Adapted-By: jwe
+
+function [aa, bb, q, z] = qzhess (a, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [na, ma] = size (a);
+  [nb, mb] = size (b);
+  if (na != ma || na != nb || nb != mb)
+    error ("qzhess: incompatible dimensions");
+  endif
+
+  ## Reduce to hessenberg-triangular form.
+
+  [q, bb] = qr (b);
+  aa = q' * a;
+  q = q';
+  z = eye (na);
+  for j = 1:(na-2)
+    for i = na:-1:(j+2)
+
+      ## disp (["zero out aa(", num2str(i), ",", num2str(j), ")"])
+
+      rot = givens (aa (i-1, j), aa (i, j));
+      aa ((i-1):i, :) = rot *aa ((i-1):i, :);
+      bb ((i-1):i, :) = rot *bb ((i-1):i, :);
+      q  ((i-1):i, :) = rot *q  ((i-1):i, :);
+
+      ## disp (["now zero out bb(", num2str(i), ",", num2str(i-1), ")"])
+
+      rot = givens (bb (i, i), bb (i, i-1))';
+      bb (:, (i-1):i) = bb (:, (i-1):i) * rot';
+      aa (:, (i-1):i) = aa (:, (i-1):i) * rot';
+      z  (:, (i-1):i) = z  (:, (i-1):i) * rot';
+
+    endfor
+  endfor
+
+  bb (2, 1) = 0.0;
+  for i = 3:na
+    bb (i, 1:(i-1)) = zeros (1, i-1);
+    aa (i, 1:(i-2)) = zeros (1, i-2);
+  endfor
+
+endfunction
diff --git a/scripts/linear-algebra/rank.m b/scripts/linear-algebra/rank.m
new file mode 100644
index 0000000..6415c3c
--- /dev/null
+++ b/scripts/linear-algebra/rank.m
@@ -0,0 +1,60 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rank (@var{a}, @var{tol})
+## Compute the rank of @var{a}, using the singular value decomposition.
+## The rank is taken to be the number of singular values of @var{a} that
+## are greater than the specified tolerance @var{tol}.  If the second
+## argument is omitted, it is taken to be
+##
+## @example
+## tol = max (size (@var{a})) * sigma(1) * eps;
+## @end example
+##
+## @noindent
+## where @code{eps} is machine precision and @code{sigma(1)} is the largest
+## singular value of @var{a}.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = rank (A, tol)
+
+  if (nargin == 1)
+    sigma = svd (A);
+    if (isempty (sigma))
+      tolerance = 0;
+    else
+      if (isa (A, "single"))
+	tolerance = max (size (A)) * sigma (1) * eps ("single");
+      else
+	tolerance = max (size (A)) * sigma (1) * eps;
+      endif
+    endif
+  elseif (nargin == 2)
+    sigma = svd (A);
+    tolerance = tol;
+  else
+    print_usage ();
+  endif
+
+  retval = sum (sigma > tolerance);
+
+endfunction
diff --git a/scripts/linear-algebra/rref.m b/scripts/linear-algebra/rref.m
new file mode 100644
index 0000000..16c8280
--- /dev/null
+++ b/scripts/linear-algebra/rref.m
@@ -0,0 +1,87 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{r}, @var{k}] =} rref (@var{a}, @var{tol})
+##
+## Returns the reduced row echelon form of @var{a}.  @var{tol} defaults
+## to @code{eps * max (size (@var{a})) * norm (@var{a}, inf)}.
+##
+## Called with two return arguments, @var{k} returns the vector of
+## "bound variables", which are those columns on which elimination 
+## has been performed.
+##
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+##         (based on a anonymous source from the public domain)
+
+function [A, k] = rref (A, tolerance)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (ndims (A) > 2)
+    error ("rref: expecting matrix argument");
+  endif
+
+  [rows, cols] = size (A);
+
+  if (nargin < 2)
+    if (isa (A, "single"))
+      tolerance = eps ("single") * max (rows, cols) * norm (A, inf ("single"));
+    else
+      tolerance = eps * max (rows, cols) * norm (A, inf);
+    endif
+  endif
+
+  used = zeros (1, cols);
+  r = 1;
+  for c = 1:cols
+    ## Find the pivot row
+    [m, pivot] = max (abs (A(r:rows,c)));
+    pivot = r + pivot - 1;
+
+    if (m <= tolerance)
+      ## Skip column c, making sure the approximately zero terms are
+      ## actually zero.
+      A (r:rows, c) = zeros (rows-r+1, 1);
+    else
+      ## keep track of bound variables
+      used (1, c) = 1;
+
+      ## Swap current row and pivot row
+      A ([pivot, r], c:cols) = A ([r, pivot], c:cols);
+
+      ## Normalize pivot row
+      A (r, c:cols) = A (r, c:cols) / A (r, c);
+
+      ## Eliminate the current column
+      ridx = [1:r-1, r+1:rows];
+      A (ridx, c:cols) = A (ridx, c:cols) - A (ridx, c) * A(r, c:cols);
+
+      ## Check if done
+      if (r++ == rows)
+	break;
+      endif
+    endif
+  endfor
+  k = find (used);
+
+endfunction
diff --git a/scripts/linear-algebra/subspace.m b/scripts/linear-algebra/subspace.m
new file mode 100644
index 0000000..e3299ee
--- /dev/null
+++ b/scripts/linear-algebra/subspace.m
@@ -0,0 +1,61 @@
+## Copyright (C) 2008, 2009 VZLU Prague, a.s., Czech Republic
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{angle} =} subspace (@var{a}, @var{B})
+## Determine the largest principal angle between two subspaces
+## spanned by columns of matrices @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: Jaroslav Hajek <highegg at gmail.com>
+
+## reference:
+## [1]  Andrew V. Knyazev, Merico E. Argentati:
+##   Principal Angles between Subspaces in an A-Based Scalar Product: 
+##  Algorithms and Perturbation Estimates.  
+##  SIAM Journal on Scientific Computing, Vol. 23 no. 6, pp. 2008-2040
+##
+## other texts are also around...
+
+function ang = subspace (a, b)
+
+  if (nargin != 2)
+    print_usage ();
+  elseif (ndims (a) != 2 || ndims (b) != 2)
+    error ("subspace: expecting A and B to be 2-dimensional arrays");
+  elseif (rows (a) != rows (b))
+    error ("subspace: column dimensions of a and b must match");
+  endif
+
+  a = orth (a);
+  b = orth (b);
+  c = a'*b;
+  scos = min (svd (c));
+  if (scos^2 > 1/2)
+    if (columns (a) >= columns (b))
+      c = b - a*c;
+    else
+      c = a - b*c';
+    endif
+    ssin = max (svd (c));
+    ang = asin (min (ssin, 1));
+  else
+    ang = acos (scos);
+  endif
+
+endfunction
diff --git a/scripts/linear-algebra/trace.m b/scripts/linear-algebra/trace.m
new file mode 100644
index 0000000..e837a39
--- /dev/null
+++ b/scripts/linear-algebra/trace.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2005, 2006, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} trace (@var{a})
+## Compute the trace of @var{a}, @code{sum (diag (@var{a}))}.
+## @end deftypefn
+
+## Author: jwe
+
+function y = trace (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (ndims (x) > 2)
+    error ("trace: only valid on 2-D objects");
+  elseif (isempty (x))
+    y = 0;
+  elseif (any (size (x) == 1))
+    y = x(1);
+  else
+    y = sum (diag (x));
+  endif
+
+endfunction
+
+%!assert(trace ([1, 2; 3, 4]) == 5);
+%!assert(trace ([1, 2; 3, 4; 5, 6]) == 5);
+%!assert(trace ([1, 3, 5; 2, 4, 6]) == 5);
+%!assert(trace ([]), 0);
+%!assert(trace (randn(1,0)), 0);
+%!
+%!error trace ();
+%!error trace (1, 2);
+%!error <only valid on 2-D objects> trace(reshape(1:9,[1,3,3]));
diff --git a/scripts/linear-algebra/vec.m b/scripts/linear-algebra/vec.m
new file mode 100644
index 0000000..ddb38e1
--- /dev/null
+++ b/scripts/linear-algebra/vec.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} vec (@var{x})
+## Return the vector obtained by stacking the columns of the matrix @var{x}
+## one above the other.
+## @end deftypefn
+
+## See Magnus and Neudecker (1988), Matrix differential calculus with
+## applications in statistics and econometrics.
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 8 May 1995
+## Adapted-By: jwe
+
+function v = vec (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  v = x(:);
+
+endfunction
+
+%!assert(vec ([1, 2; 3, 4]) == [1; 3; 2; 4] && vec ([1, 3, 2, 4]) == [1; 3; 2; 4]);
+
+%!error vec ();
+
+%!error vec (1, 2);
+
diff --git a/scripts/linear-algebra/vech.m b/scripts/linear-algebra/vech.m
new file mode 100644
index 0000000..d0f7827
--- /dev/null
+++ b/scripts/linear-algebra/vech.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006, 2007, 2008
+##               Kurt Hornik
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} vech (@var{x})
+## Return the vector obtained by eliminating all supradiagonal elements of
+## the square matrix @var{x} and stacking the result one column above the
+## other.
+## @end deftypefn
+
+## See Magnus and Neudecker (1988), Matrix differential calculus with
+## applications in statistics and econometrics.
+
+## Author KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 8 May 1995
+## Adapted-By: jwe
+
+function v = vech (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! issquare (x))
+    error ("vech: x must be square");
+  endif
+
+  n = rows (x);
+  slices = cellslices (x(:), (1:n) + n*(0:n-1), n*(1:n));
+  v = vertcat (slices{:});
+
+endfunction
+
+%!assert(all (vech ([1, 2, 3; 4, 5, 6; 7, 8, 9]) == [1; 4; 7; 5; 8; 9]));
+
+%!error vech ();
+
+%!error vech (1, 2);
+
diff --git a/scripts/miscellaneous/Makefile.in b/scripts/miscellaneous/Makefile.in
new file mode 100644
index 0000000..812db30
--- /dev/null
+++ b/scripts/miscellaneous/Makefile.in
@@ -0,0 +1,93 @@
+# Makefile for octave's scripts/miscellaneous directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008, 2009
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = miscellaneous
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = __xzip__.m ans.m bincoeff.m bug_report.m bunzip2.m bzip2.m \
+  cast.m comma.m compare_versions.m computer.m copyfile.m debug.m \
+  delete.m dir.m dos.m dump_prefs.m edit.m \
+  fileattrib.m fileparts.m flops.m fullfile.m getfield.m gunzip.m gzip.m \
+  info.m inputname.m intwarning.m ismac.m ispc.m isunix.m license.m \
+  list_primes.m ls.m ls_command.m menu.m mex.m mexext.m mkoctfile.m \
+  movefile.m namelengthmax.m news.m orderfields.m pack.m paren.m \
+  parseparams.m perl.m run.m semicolon.m setfield.m substruct.m swapbytes.m \
+  symvar.m tar.m tempdir.m tempname.m texas_lotto.m unix.m unpack.m untar.m \
+  unzip.m ver.m version.m warning_ids.m what.m xor.m zip.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/miscellaneous
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/miscellaneous/__xzip__.m b/scripts/miscellaneous/__xzip__.m
new file mode 100644
index 0000000..3a399b9
--- /dev/null
+++ b/scripts/miscellaneous/__xzip__.m
@@ -0,0 +1,140 @@
+## Copyright (C) 2008, 2009 Thorsten Meyer
+## based on the original gzip function by David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{entries} =} __xzip__ (@var{commandname}, @var{extension}, @var{commandtemplate}, @var{files}, @var{outdir})
+## Undocumented internal function.
+## @end deftypefn
+
+## Compress the list of files and/or directories specified in @var{files} 
+## with the external compression command @var{commandname}. The template 
+## @var{commandtemplate} is used to actually start the command. Each file
+## is compressed separately and a new file with the extension @var{extension} 
+## is created and placed into the directory @var{outdir}. The original files 
+## are not touched. Existing compressed files are silently overwritten. 
+## This is an internal function. Do not use directly.
+
+function entries = __xzip__ (commandname, extension, 
+                             commandtemplate, files, outdir)
+
+  if (nargin == 4 || nargin == 5)
+    if (! ischar (extension) || length (extension) == 0)
+      error ("__xzip__: extension has to be a string with finite length");
+    endif
+    
+    if (nargin == 5 && ! exist (outdir, "dir"))
+      error ("__xzip__: output directory does not exist");
+    endif
+
+    if (ischar (files))
+      files = cellstr (files);
+    else
+      error ("__xzip__: expecting FILES to be a character array");
+    endif
+
+    if (nargin == 4)
+      outdir = tmpnam ();
+      mkdir (outdir);
+    endif
+
+    cwd = pwd();
+    unwind_protect
+      files = glob (files);
+
+      ## Ignore any file with the compress extension
+      files (cellfun (@(x) length(x) > length(extension) 
+        && strcmp (x((end - length(extension) + 1):end), extension), 
+        files)) = [];
+
+      copyfile (files, outdir);
+
+      [d, f] = myfileparts(files);
+
+      cd (outdir);
+
+      cmd = sprintf (commandtemplate, sprintf (" %s", f{:}));
+
+      [status, output] = system (cmd);
+      if (status == 0)
+
+        if (nargin == 5)
+          compressed_files = cellfun(
+              @(x) fullfile (outdir, sprintf ("%s.%s", x, extension)), 
+              f, "UniformOutput", false);
+        else
+          movefile (cellfun(@(x) sprintf ("%s.%s", x, extension), f, 
+                            "UniformOutput", false), cwd);
+          ## FIXME this does not work when you try to compress directories
+
+          compressed_files  = cellfun(@(x) sprintf ("%s.%s", x, extension), 
+                                      files, "UniformOutput", false);
+        endif
+
+        if (nargout > 0)
+          entries = compressed_files;
+        endif
+      else
+        error ("%s command failed with exit status = %d",
+               commandname, status);
+      endif
+    unwind_protect_cleanup
+      cd(cwd);
+      if (nargin == 4)
+        crr = confirm_recursive_rmdir ();
+        unwind_protect
+          confirm_recursive_rmdir (false);
+          rmdir (outdir, "s");
+        unwind_protect_cleanup
+          confirm_recursive_rmdir (crr);
+        end_unwind_protect
+      endif
+    end_unwind_protect
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+function [d, f] = myfileparts (files)
+  [d, f, ext] = cellfun (@(x) fileparts (x), files, "UniformOutput", false);
+  f = cellfun (@(x, y) sprintf ("%s%s", x, y), f, ext,
+               "UniformOutput", false); 
+  idx = cellfun (@(x) isdir (x), files);
+  d(idx) = "";
+  f(idx) = files(idx);
+endfunction
+
+%!error <extension has to be a string with finite length> 
+%!  __xzip__("gzip", "", "gzip -r %s", "bla");
+%!error <no files to move>
+%!  __xzip__("gzip", ".gz", "gzip -r %s", tmpnam);
+%!error <command failed with exit status>
+%!  # test __xzip__ with invalid compression command
+%!  unwind_protect
+%!    filename = tmpnam;
+%!    dummy    = 1;
+%!    save(filename, "dummy");
+%!    dirname  = tmpnam;
+%!    mkdir(dirname);
+%!    entry = __xzip__("gzip", ".gz", "xxxzipxxx -r %s 2>/dev/null", 
+%!                     filename, dirname);
+%!  unwind_protect_cleanup
+%!    delete(filename);
+%!    rmdir(dirname);
+%!  end_unwind_protect
diff --git a/scripts/miscellaneous/ans.m b/scripts/miscellaneous/ans.m
new file mode 100644
index 0000000..f1270d4
--- /dev/null
+++ b/scripts/miscellaneous/ans.m
@@ -0,0 +1,30 @@
+## Copyright (C) 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @defvr {Automatic Variable} ans
+## The most recently computed result that was not
+## explicitly assigned to a variable.  For example, after the expression
+## 
+## @example
+## 3^2 + 4^2
+## @end example
+## 
+## @noindent
+## is evaluated, the value returned by @code{ans} is 25.
+## @end defvr
diff --git a/scripts/miscellaneous/bincoeff.m b/scripts/miscellaneous/bincoeff.m
new file mode 100644
index 0000000..b56f987
--- /dev/null
+++ b/scripts/miscellaneous/bincoeff.m
@@ -0,0 +1,114 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007,
+##               2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} bincoeff (@var{n}, @var{k})
+## Return the binomial coefficient of @var{n} and @var{k}, defined as
+## @tex
+## $$
+##  {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##  /   \
+##  | n |    n (n-1) (n-2) @dots{} (n-k+1)
+##  |   |  = -------------------------
+##  | k |               k!
+##  \   /
+## @end group
+## @end example
+## @end ifnottex
+##
+## For example,
+##
+## @example
+## @group
+## bincoeff (5, 2)
+##      @result{} 10
+## @end group
+## @end example
+##
+## In most cases, the @code{nchoosek} function is faster for small
+## scalar integer arguments.  It also warns about loss of precision for
+## big arguments.
+##
+## @seealso{nchoosek}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 8 October 1994
+## Adapted-By: jwe
+
+function b = bincoeff (n, k)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [retval, n, k] = common_size (n, k);
+  if (retval > 0)
+    error ("bincoeff: n and k must be of common size or scalars");
+  endif
+
+  sz = size (n);
+  b   = zeros (sz);
+
+  ind = (! (k >= 0) | (k != real (round (k))) | isnan (n));
+  b(ind) = NaN;
+  
+  ind = (k == 0);
+  b(ind) = 1;
+
+  ind = ((k > 0) & ((n == real (round (n))) & (n < 0)));
+  b(ind) = (-1) .^ k(ind) .* exp (gammaln (abs (n(ind)) + k(ind))
+				  - gammaln (k(ind) + 1)
+				  - gammaln (abs (n(ind))));
+
+  ind = ((k > 0) & (n >= k));
+  b(ind) = exp (gammaln (n(ind) + 1)
+		- gammaln (k(ind) + 1)
+		- gammaln (n(ind) - k(ind) + 1));
+
+  ind = ((k > 0) & ((n != real (round (n))) & (n < k)));
+  b(ind) = (1/pi) * exp (gammaln (n(ind) + 1)
+			 - gammaln (k(ind) + 1)
+			 + gammaln (k(ind) - n(ind))
+			 + log (sin (pi * (n(ind) - k(ind) + 1))));
+
+  ## Clean up rounding errors.
+  ind = (n == round (n));
+  b(ind) = round (b(ind));
+
+  ind = (n != round (n));
+  b(ind) = real (b(ind));
+
+endfunction
+
+%!assert(bincoeff(4,2), 6)
+%!assert(bincoeff(2,4), 0)
+%!assert(bincoeff(0.4,2), -.12, 8*eps)
+
+%!assert(bincoeff (5, 2) == 10 && bincoeff (50, 6) == 15890700);
+
+%!error bincoeff ();
+
+%!error bincoeff (1, 2, 3);
diff --git a/scripts/miscellaneous/bug_report.m b/scripts/miscellaneous/bug_report.m
new file mode 100644
index 0000000..18f8897
--- /dev/null
+++ b/scripts/miscellaneous/bug_report.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2005,
+##               2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bug_report ()
+## Have Octave create a bug report template file, invoke your favorite
+## editor, and submit the report to the bug-octave mailing list when
+## you are finished editing.
+## @end deftypefn
+
+## Author: jwe
+
+function bug_report ()
+
+  if (nargin != 0)
+    warning ("bug_report: ignoring extra arguments");
+  endif
+
+  printf ("Please enter a one-line description of your bug report.\n\n");
+  fflush (stdout);
+
+  subject = "";
+  subject = input ("Subject: ", "s");
+
+  unwind_protect
+
+    prefs = tmpnam ();
+
+    if (! isempty (prefs))
+      fid = fopen (prefs, "wt");
+      if (fid > 0)
+        dump_prefs (fid);
+        fclose (fid);
+      endif
+    endif
+
+    cmd = cstrcat ("octave-bug-", OCTAVE_VERSION);
+
+    if (length (subject) > 0)
+      cmd = sprintf ("%s -s \"%s\"", cmd, subject);
+    endif
+
+    if (! isempty (prefs))
+      cmd = sprintf ("%s \"%s\"", cmd, prefs);
+    endif
+
+    system (cmd);
+
+  unwind_protect_cleanup
+
+    if (! isempty (prefs))
+      unlink (prefs);
+    endif
+
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/miscellaneous/bunzip2.m b/scripts/miscellaneous/bunzip2.m
new file mode 100644
index 0000000..ba7a03b
--- /dev/null
+++ b/scripts/miscellaneous/bunzip2.m
@@ -0,0 +1,45 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Bill Denney
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bunzip2 (@var{bzfile}, @var{dir})
+## Unpack the bzip2 archive @var{bzfile} to the directory @var{dir}.  If
+## @var{dir} is not specified, it defaults to the current directory.
+## @seealso{unpack, bzip2, tar, untar, gzip, gunzip, zip, unzip}
+## @end deftypefn
+
+## Author: Bill Denney <denney at seas.upenn.edu>
+
+function varargout = bunzip2 (files, outputdir)
+
+  if (! (nargin == 1 || nargin == 2))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    outputdir = ".";
+  endif
+
+  if (nargout > 0)
+    varargout = cell (1, nargout);
+    [varargout{:}] = unpack (files, outputdir, mfilename ());
+  else
+    unpack (files, outputdir, mfilename ());
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/bzip2.m b/scripts/miscellaneous/bzip2.m
new file mode 100644
index 0000000..33e1eac
--- /dev/null
+++ b/scripts/miscellaneous/bzip2.m
@@ -0,0 +1,61 @@
+## Copyright (C) 2008, 2009 Thorsten Meyer
+## (based on gzip.m by David Bateman)
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{entries} =} bzip2 (@var{files})
+## @deftypefnx {Function File} {@var{entries} =} bzip2 (@var{files}, @var{outdir})
+## Compress the list of files specified in @var{files}.
+## Each file is compressed separately and a new file with a '.bz2' extension
+## is created.  The original files are not touched.  Existing compressed files 
+## are silently overwritten.If @var{outdir} is defined the compressed versions 
+## of the files are placed in this directory.
+## @seealso{bunzip2, gzip, zip, tar}
+## @end deftypefn
+
+function entries = bzip2 (varargin)
+
+  if (nargin == 1 || nargin == 2)
+    if nargout == 0
+      __xzip__ ("bzip2", "bz2", "bzip2 %s", varargin{:});
+    else
+      entries = __xzip__ ("bzip2", "bz2", "bzip2 %s", varargin{:});
+    endif      
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!xtest
+%!  # test for correct cleanup of temporary files
+%!  unwind_protect
+%!    filename = tmpnam;
+%!    dummy    = 1;
+%!    save(filename, "dummy");
+%!    n_tmpfiles_before = length(find(strncmp("oct-", cellstr(ls(P_tmpdir)), 4)));
+%!    entry = bzip2(filename);
+%!    n_tmpfiles_after = length(find(strncmp("oct-", cellstr(ls(P_tmpdir)), 4)));
+%!    if (n_tmpfiles_before != n_tmpfiles_after)
+%!      error("bzip2 has not cleaned up temporary files correctly!");
+%!    endif
+%!  unwind_protect_cleanup
+%!    delete(filename);
+%!    [path, basename, extension] = fileparts(filename);
+%!    delete([basename, extension, ".bz2"]);
+%!  end_unwind_protect
diff --git a/scripts/miscellaneous/cast.m b/scripts/miscellaneous/cast.m
new file mode 100644
index 0000000..abf75ea
--- /dev/null
+++ b/scripts/miscellaneous/cast.m
@@ -0,0 +1,45 @@
+## Copyright (C) 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cast (@var{val}, @var{type})
+## Convert @var{val} to data type @var{type}.
+## @seealso{int8, uint8, int16, uint16, int32, uint32, int64, uint64, double}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = cast (val, typ)
+
+  if (nargin == 2)
+    if (ischar (typ))
+      if (any (strcmp (typ, {"int8"; "uint8"; "int16"; "uint16";
+			     "int32"; "uint32"; "int64"; "uint64";
+			     "double"; "single"; "logical"; "char"})))
+	retval = feval (typ, val);
+      else
+	error ("cast: type name `%s' is not a built-in type", typ);
+      endif
+    else
+      error ("cast: expecting type name as second argument");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/comma.m b/scripts/miscellaneous/comma.m
new file mode 100644
index 0000000..5b91e52
--- /dev/null
+++ b/scripts/miscellaneous/comma.m
@@ -0,0 +1,24 @@
+## Copyright (C) 1995, 1996, 1997, 2000, 2004, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deffn {Operator} ,
+## Array index, function argument, or command separator.
+## @seealso{semicolon}
+## @end deffn
diff --git a/scripts/miscellaneous/compare_versions.m b/scripts/miscellaneous/compare_versions.m
new file mode 100644
index 0000000..0c623ba
--- /dev/null
+++ b/scripts/miscellaneous/compare_versions.m
@@ -0,0 +1,236 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} compare_versions (@var{v1}, @var{v2}, @var{operator})
+## Compares to version strings using the given @var{operator}.
+##
+## This function assumes that versions @var{v1} and @var{v2} are
+## arbitrarily long strings made of numeric and period characters
+## possibly followed by an arbitrary string (e.g., "1.2.3", "0.3",
+## "0.1.2+", or "1.2.3.4-test1").
+##
+## The version is first split into the numeric and the character parts
+## then the parts are padded to be the same length (i.e., "1.1" would be
+## padded to be like "1.1.0" when being compared with "1.1.1", and
+## separately, the character parts of the strings are padded with
+## nulls).
+##
+## The operator can be any logical operator from the set
+##
+## @itemize @bullet
+## @item
+## "=="
+## equal
+## @item
+## "<"
+## less than
+## @item
+## "<="
+## less than or equal to
+## @item
+## ">"
+## greater than
+## @item
+## ">="
+## greater than or equal to
+## @item
+## "!="
+## not equal
+## @item
+## "~="
+## not equal
+## @end itemize
+##
+## Note that version "1.1-test2" would compare as greater than
+## "1.1-test10".  Also, since the numeric part is compared first, "a"
+## compares less than "1a" because the second string starts with a
+## numeric part even though double("a") is greater than double("1").
+## @end deftypefn
+
+## Author: Bill Denney <denney at seas.upenn.edu>
+
+## FIXME?: This allows a single equal sign "=" to indicate equality, do
+## we want to require a double equal since that is the boolean operator?
+
+function out = compare_versions (v1, v2, operator)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  ## Make sure that the version numbers are valid.
+  if (! (ischar (v1) && ischar (v2)))
+    error ("compare_versions: both version numbers must be strings");
+  elseif (size (v1, 1) != 1 || size (v2, 1) != 1)
+    error ("compare_versions: version numbers must be a single row");
+  endif
+
+  ## check and make sure that the operator is valid
+  if (! ischar (operator))
+    error ("compare_versions: operator must be a character string");
+  elseif (numel (operator) > 2)
+    error("compare_versions: operator cannot be more than 2 characters long");
+  endif
+
+  ## trim off any character data that is not part of a normal version
+  ## number
+  numbers = "0123456789.";
+
+  v1firstchar = find (! ismember (v1, numbers), 1);
+  v2firstchar = find (! ismember (v2, numbers), 1);
+  if (! isempty (v1firstchar))
+    v1c = v1(v1firstchar:length(v1));
+    v1nochar = v1(1:v1firstchar-1);
+  else
+    v1c = "";
+    v1nochar = v1;
+  endif
+  if (! isempty (v2firstchar))
+    v2c = v2(v2firstchar:length(v2));
+    v2nochar = v2(1:v2firstchar-1);
+  else
+    v2c = "";
+    v2nochar = v2;
+  endif
+
+  v1n = str2num (char (strsplit (v1nochar, ".")));
+  v2n = str2num (char (strsplit (v2nochar, ".")));
+  if ((isempty (v1n) && isempty (v1c)) || (isempty (v2n) && isempty(v2c)))
+    error ("compare_versions: given version strings are not valid: %s %s",
+	   v1, v2);
+  endif
+
+  ## Assume that any additional elements would be 0 if one is longer
+  ## than the other.
+  maxnumlen = max ([length(v1n) length(v2n)]);
+  if (length (v1n) < maxnumlen)
+    v1n(length(v1n)+1:maxnumlen) = 0;
+  endif
+  if (length (v2n) < maxnumlen)
+    v2n(length(v2n)+1:maxnumlen) = 0;
+  endif
+
+  ## Assume that any additional character elements would be 0 if one is
+  ## longer than the other.
+  maxcharlen = max ([length(v1c), length(v2c)]);
+  if (length (v1c) < maxcharlen)
+    v1c(length(v1c)+1:maxcharlen) = "\0";
+  endif
+  if (length (v2c) < maxcharlen)
+    v2c(length(v2c)+1:maxcharlen) = "\0";
+  endif
+
+  ## Determine the operator.
+  if any (ismember (operator, "="))
+    equal_op = true;
+  else
+    equal_op = false;
+  endif
+  if any (ismember (operator, "~!"))
+    not_op = true;
+  else
+    not_op = false;
+  endif
+  if any (ismember (operator, "<"))
+    lt_op = true;
+  else
+    lt_op = false;
+  endif
+  if any (ismember (operator, ">"))
+    gt_op = true;
+  else
+    gt_op = false;
+  endif
+
+  ## Make sure that we don't have conflicting operators.
+  if (gt_op && lt_op)
+    error ("compare_versions: operator cannot contain both greater and less than symbols");
+  elseif ((gt_op || lt_op) && not_op)
+    error ("compare_versions: operator cannot contain not and greater than or less than symbols");
+  endif
+
+  ## Compare the versions (making sure that they're the same shape)
+  vcmp = v1n(:) - v2n(:);
+  vcmp = [vcmp; (v1c - v2c)(:)];
+  if (lt_op)
+    ## so that we only need to check for the output being greater than 1
+    vcmp = -vcmp;
+  endif
+  firstdiff = find (vcmp != 0, 1);
+
+  if (isempty (firstdiff))
+    ## They're equal.
+    out = equal_op;
+  elseif (lt_op || gt_op)
+    ## They're correctly less than or greater than.
+    out = (vcmp(firstdiff) > 0);
+  else
+    ## They're not correctly less than or greater than, and they're not
+    ## equal.
+    out = false;
+  endif
+
+  ## Reverse the output if not is given.
+  out = xor (not_op, out);
+
+endfunction
+
+## tests
+## test both equality symbols
+%!assert(compare_versions("1", "1", "="), true)
+## test arbitrarily long equality
+%!assert(compare_versions("1.1.0.0.0", "1.1", "=="), true)
+%!assert(compare_versions("1", "1.1", "<"), true)
+%!assert(compare_versions("1.1", "1.1", "<="), true)
+%!assert(compare_versions("1.1", "1.1.1", "<="), true)
+%!assert(compare_versions("1.23", "1.24", "=<"), true)
+## test different length numbers
+%!assert(compare_versions("23.2000", "23.1", ">"), true)
+%!assert(compare_versions("0.0.2", "0.0.1", ">="), true)
+%!assert(compare_versions("0.2", "0.0.100", "=>"), true)
+%!assert(compare_versions("0.1", "0.2", "!="), true)
+%!assert(compare_versions("0.1", "0.2", "~="), true)
+
+## test alphanumeric strings
+%!assert(compare_versions("1a", "1b", "<"), true)
+%!assert(compare_versions("a", "1", "<"), true)
+%!assert(compare_versions("1a", "1b", ">"), false)
+%!assert(compare_versions("a", "1", ">"), false)
+%!assert(compare_versions("1.1.0a", "1.1.0b", "=="), false)
+%!assert(compare_versions("1.1.0a", "1.1.0b", "!="), true)
+%!assert(compare_versions("1.1.0test", "1.1.0b", "=="), false)
+%!assert(compare_versions("1.1.0test", "1.1.0test", "=="), true)
+
+## make sure that it won't just give true output
+%!assert(compare_versions("1", "0", "="), false)
+## test arbitrarily long equality
+%!assert(compare_versions("1.1.1.0.0", "1.1", "=="), false)
+%!assert(compare_versions("1.1", "1", "<"), false)
+%!assert(compare_versions("2", "1.1", "<="), false)
+%!assert(compare_versions("1.1.1", "1.1", "<="), false)
+%!assert(compare_versions("1.25", "1.24", "=<"), false)
+## test different length numbers
+%!assert(compare_versions("23.2", "23.100", ">"), false)
+%!assert(compare_versions("0.0.0.2", "0.0.1", ">="), false)
+%!assert(compare_versions("0.0.20", "0.10.2", "=>"), false)
+%!assert(compare_versions("0.1", "0.1", "!="), false)
+%!assert(compare_versions("0.1", "0.1", "~="), false)
+
+## FIXME: how do we check to make sure that it gives errors when it
+## should
diff --git a/scripts/miscellaneous/computer.m b/scripts/miscellaneous/computer.m
new file mode 100644
index 0000000..08a6e4f
--- /dev/null
+++ b/scripts/miscellaneous/computer.m
@@ -0,0 +1,80 @@
+## Copyright (C) 2004, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{c}, @var{maxsize}, @var{endian}] =} computer ()
+## Print or return a string of the form @var{cpu}- at var{vendor}- at var{os}
+## that identifies the kind of computer Octave is running on.  If invoked
+## with an output argument, the value is returned instead of printed.  For
+## example,
+##
+## @example
+## @group
+## computer ()
+##      @print{} i586-pc-linux-gnu
+##
+## x = computer ()
+##      @result{} x = "i586-pc-linux-gnu"
+## @end group
+## @end example
+##
+## If two output arguments are requested, also return the maximum number
+## of elements for an array.
+##
+## If three output arguments are requested, also return the byte order
+## of the current system as a character (@code{"B"} for big-endian or
+## @code{"L"} for little-endian).
+## @end deftypefn
+
+function [c, maxsize, endian] = computer ()
+
+  if (nargin != 0)
+    warning ("computer: ignoring extra arguments");
+  endif
+
+  msg = octave_config_info ("canonical_host_type");
+
+  if (strcmp (msg, "unknown"))
+    msg = "Hi Dave, I'm a HAL-9000";
+  endif
+
+  if (nargout == 0)
+    printf ("%s\n", msg);
+  else
+    c = msg;
+    if (strcmp (octave_config_info ("USE_64_BIT_IDX_T"), "true"))
+      maxsize = 2^63-1;
+    else
+      maxsize = 2^31-1;
+    endif
+    if (octave_config_info ("words_big_endian"))
+      endian = "B";
+    elseif (octave_config_info ("words_little_endian"))
+      endian = "L";
+    else
+      endian = "?";
+    endif      
+  endif
+
+endfunction
+
+%!assert((ischar (computer ())
+%! && computer () == octave_config_info ("canonical_host_type")));
+
+%!warning a =computer(2);
+
diff --git a/scripts/miscellaneous/copyfile.m b/scripts/miscellaneous/copyfile.m
new file mode 100644
index 0000000..776c4ed
--- /dev/null
+++ b/scripts/miscellaneous/copyfile.m
@@ -0,0 +1,126 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2}, @var{force})
+## Copy the file @var{f1} to the new name @var{f2}.  The name @var{f1}
+## may contain globbing patterns.  If @var{f1} expands to multiple file
+## names, @var{f2} must be a directory.  If @var{force} is given and equals
+## the string "f" the copy operation will be forced.
+##
+## If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+## character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+## system-dependent error message, and @var{msgid} contains a unique\n\
+## message identifier.\n\
+## @seealso{glob, movefile}
+## @end deftypefn
+
+function [status, msg, msgid] = copyfile (f1, f2, force)
+
+  max_cmd_line = 1024;
+  status = true;
+  msg = "";
+  msgid = "";
+
+  ## FIXME -- maybe use the same method as in ls to allow users control
+  ## over the command that is executed.
+
+  if (ispc () && ! isunix () && isempty (file_in_path (EXEC_PATH, "cp.exe")))
+    ## Windows.
+    cmd = "cmd /C xcopy /E";
+    cmd_force_flag = "/Y";
+  else
+    cmd = "cp -r";
+    cmd_force_flag = "-f";
+  endif
+
+  if (nargin == 2 || nargin == 3)
+    ## Input type check.
+    if (! (ischar (f1) || iscellstr (f1)))
+      error ("copyfile: first argument must be a character string or a cell array of character strings");
+    endif
+
+    if (! ischar (f2))
+      error ("copyfile: second argument must be a character string");
+    endif
+
+    if (nargin == 3 && strcmp (force, "f"))
+      cmd = cstrcat (cmd, " ", cmd_force_flag);
+    endif
+
+    ## If f1 isn't a cellstr convert it to one.
+    if (ischar (f1))
+      f1 = cellstr (f1);
+    endif
+
+    ## If f1 has more than 1 element f2 must be a directory
+    isdir = (exist (f2, "dir") != 0);
+    if (length(f1) > 1 && ! isdir)
+      error ("copyfile: when copying multiple files, second argument must be a directory");
+    endif
+    
+    ## Protect the file name(s).
+    f1 = glob (f1);
+    if (isempty (f1))
+      error ("copyfile: no files to move");
+    endif
+    p1 = sprintf ("\"%s\" ", f1{:});
+    p2 = tilde_expand (f2);
+
+    if (isdir && length(p1) > max_cmd_line)
+      l2 = length(p2) + length (cmd) + 6;
+      while (! isempty(f1))
+	p1 = sprintf ("\"%s\" ", f1{1});
+	f1(1) = [];
+	while (!isempty (f1) && (length(p1) + length(f1{1}) + l2 < 
+				 max_cmd_line))
+	  p1 = sprintf ("%s\"%s\" ", p1, f1{1});
+	  f1(1) = [];
+	endwhile 
+
+	if (ispc () && ! isunix () && ! isempty (file_in_path (EXEC_PATH, "cp.exe")))
+	  p1 = strrep (p1, "\\", "/");
+	  p2 = strrep (p2, "\\", "/");
+	endif
+
+	## Copy the files.
+	[err, msg] = system (sprintf ("%s %s\"%s\"", cmd, p1, p2));
+	if (err < 0)
+	  status = false;
+	  msgid = "copyfile";
+	  break;
+	endif
+      endwhile
+    else
+      if (ispc () && ! isunix () && ! isempty (file_in_path (EXEC_PATH, "cp.exe")))
+	p1 = strrep (p1, "\\", "/");
+	p2 = strrep (p2, "\\", "/");
+      endif
+
+      ## Copy the files.
+      [err, msg] = system (sprintf ("%s %s\"%s\"", cmd, p1, p2));
+      if (err < 0)
+	status = false;
+	msgid = "copyfile";
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/debug.m b/scripts/miscellaneous/debug.m
new file mode 100644
index 0000000..d0d39f9
--- /dev/null
+++ b/scripts/miscellaneous/debug.m
@@ -0,0 +1,83 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} debug ()
+## Summary of the debugging commands.  The debugging commands that are
+## available in Octave are
+##
+## @table @code
+## @item keyboard
+## Force entry into debug mode.
+##
+## @item dbstop
+## Add a breakpoint.
+##
+## @item dbclear
+## Remove a breakpoint.
+##
+## @item dbstatus
+## List all breakpoints.
+##
+## @item dbcont
+## Continue execution from the debug prompt.
+##
+## @item dbstack
+## Print a backtrace of the execution stack.
+##
+## @item dbstep
+## Execute one or more lines and re-enter debug mode
+##
+## @item dbtype
+## List the function where execution is currently stopped, enumerating
+## the lines.
+##
+## @item dbup
+## The workspace up the execution stack.
+##
+## @item dbdown
+## The workspace down the execution stack.
+##
+## @item dbquit
+## Quit debugging mode and return to the main prompt.
+##
+## @item debug_on_error
+## Flag whether to enter debug mode in case Octave encounters an error.
+##
+## @item debug_on_warning
+## Flag whether to enter debug mode in case Octave encounters a warning.
+##
+## @item debug_on_interrupt
+## Flag whether to enter debug mode in case Octave encounters an interupt.
+## 
+## @end table
+##
+## @noindent
+## when Octave encounters a breakpoint or other reason to enter debug
+## mode, the prompt changes to @code{"debug>"}.  The workspace of the function
+## where the breakpoint was encountered becomes available and any Octave
+## command that works within that workspace may be executed.
+##
+## @seealso{dbstop, dbclear, dbstatus, dbcont, dbstack, dbstep, dbtype,
+## dbup, dbdown, dbquit, debug_on_error, debug_on_warning,
+## debug_on_interrupt}
+## @end deftypefn
+
+function debug ()
+  help ("debug");
+endfunction
diff --git a/scripts/miscellaneous/delete.m b/scripts/miscellaneous/delete.m
new file mode 100644
index 0000000..8813257
--- /dev/null
+++ b/scripts/miscellaneous/delete.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} delete (@var{file})
+## @deftypefnx {Function File} {} delete (@var{handle})
+## Delete the named file or graphics handle.
+##
+## Deleting graphics objects is the proper way to remove
+## features from a plot without clearing the entire figure.
+## @seealso{clf, cla}
+## @end deftypefn
+
+## Author: jwe
+
+function delete (arg)
+
+  if (nargin == 1)
+    if (ischar (arg))
+      files = glob (arg).';
+      if (isempty (files))
+        warning ("delete: no such file: %s", arg);
+      endif
+      for i = 1:length (files)
+        file = files{i};
+        [err, msg] = unlink (file);
+        if (err)
+          warning ("delete: %s: %s", file, msg);
+        endif
+      endfor
+    elseif (all (ishandle (arg(:))))
+      ## Delete a graphics object.
+      __go_delete__ (arg);
+    else
+      error ("delete: expecting argument to be a filename or graphics handle");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/dir.m b/scripts/miscellaneous/dir.m
new file mode 100644
index 0000000..b39d9e5
--- /dev/null
+++ b/scripts/miscellaneous/dir.m
@@ -0,0 +1,142 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dir (@var{directory})
+## @deftypefnx {Function File} {[@var{list}] =} dir (@var{directory})
+## Display file listing for directory @var{directory}.  If a return
+## value is requested, return a structure array with the fields
+##
+## @example
+## @group
+## name
+## bytes
+## date
+## isdir
+## statinfo
+## @end group
+## @end example
+##
+## @noindent
+## in which @code{statinfo} is the structure returned from @code{stat}.
+##
+## If @var{directory} is not a directory, return information about the
+## named @var{filename}.  @var{directory} may be a list of directories
+## specified either by name or with wildcard characters (like * and ?)
+## which will be expanded with glob.
+##
+## Note that for symbolic links, @code{dir} returns information about
+## the file that a symbolic link points to instead of the link itself.
+## However, if the link points to a nonexistent file, @code{dir} returns
+## information about the link.
+## @seealso{ls, stat, lstat, readdir, glob, filesep}
+## @end deftypefn
+
+## Author: jwe
+
+## FIXME -- this is quite slow for large directories, so perhaps
+## it should be converted to C++.
+
+function retval = dir (file)
+
+  if (nargin == 0)
+    file = ".";
+  elseif (nargin > 1)
+    print_usage ();
+  endif
+
+  ## Prep the retval.
+  info = struct (zeros (0, 1),
+		 {"name", "date", "bytes", "isdir", "datenum", "statinfo"});
+
+  if (ischar (file))
+    if (strcmp (file, "*"))
+      file = ".";
+    endif
+    if (strcmp (file, "."))
+      flst = {"."};
+      nf = 1;
+    else
+      flst = glob (file);
+      nf = length (flst);
+    endif
+
+    ## Determine the file list for the case where a single directory is
+    ## specified.
+    if (nf == 1)
+      fn = flst{1};
+      [st, err, msg] = stat (fn);
+      if (err < 0)
+	warning ("dir: `stat (%s)' failed: %s", fn, msg);
+	nf = 0;
+      elseif (S_ISDIR (st.mode))
+	flst = readdir (flst{1});
+	nf = length (flst);
+	for i = 1:nf
+	  flst{i} = fullfile (fn, flst{i});
+	endfor
+      endif
+    endif
+
+    if (length (flst) > 0)
+      ## Collect results.
+      for i = nf:-1:1
+	fn = flst{i};
+	[st, err, msg] = lstat (fn);
+	if (err < 0)
+	  warning ("dir: `lstat (%s)' failed: %s", fn, msg);
+	else
+	  ## If we are looking at a link that points to something,
+	  ## return info about the target of the link, otherwise, return
+	  ## info about the link itself.
+	  if (S_ISLNK (st.mode))
+	    [xst, err, msg] = stat (fn);
+	    if (! err)
+	      st = xst;
+	    endif
+	  endif
+	  [dummy, fn, ext] = fileparts (fn);
+	  fn = cstrcat (fn, ext);
+	  info(i,1).name = fn;
+	  lt = localtime (st.mtime);
+	  info(i,1).date = strftime ("%d-%b-%Y %T", lt);
+	  info(i,1).bytes = st.size;
+	  info(i,1).isdir = S_ISDIR (st.mode);
+	  info(i,1).datenum = datenum (lt.year + 1900, lt.mon, lt.mday,
+				       lt.hour, lt.min, lt.sec);
+	  info(i,1).statinfo = st;
+	endif
+      endfor
+    endif
+
+  else
+    error ("dir: expecting directory or filename to be a char array");
+  endif
+
+  ## Return the output arguments.
+  if (nargout > 0)
+    ## Return the requested structure.
+    retval = info;
+  elseif (length (info) > 0)
+    ## Print the structure to the screen.
+    printf ("%s", list_in_columns ({info.name}));
+  else
+    warning ("dir: nonexistent file `%s'", file);
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/dos.m b/scripts/miscellaneous/dos.m
new file mode 100644
index 0000000..2d61ad8
--- /dev/null
+++ b/scripts/miscellaneous/dos.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2004, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{status}, @var{text}] =} dos (@var{command})
+## @deftypefnx {Function File} {[@var{status}, @var{text}] =} dos (@var{command}, "-echo")
+## Execute a system command if running under a Windows-like operating
+## system, otherwise do nothing.  Return the exit status of the program
+## in @var{status} and any output sent to the standard output in
+## @var{text}.  If the optional second argument @code{"-echo"} is given,
+## then also send the output from the command to the standard output.
+## @seealso{unix, isunix, ispc, system}
+## @end deftypefn
+
+## Author: octave-forge ???
+## Adapted by: jwe
+
+function [status, text] = dos (cmd, echo_arg)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  elseif (! isunix ())
+    [status, text] = system (cmd);
+    if (nargin > 1 || nargout == 0)
+      printf ("%s\n", text);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/dump_prefs.m b/scripts/miscellaneous/dump_prefs.m
new file mode 100644
index 0000000..f80853c
--- /dev/null
+++ b/scripts/miscellaneous/dump_prefs.m
@@ -0,0 +1,98 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dump_prefs (@var{file})
+## Have Octave dump all the current user preference variables to
+## @var{file} in a format that can be parsed by Octave later.  If
+## @var{file} is omitted, the listing is printed to stdout.
+## @end deftypefn
+
+## Author: jwe
+
+function dump_prefs (file)
+
+  if (nargin == 0)
+    file = stdout;
+  endif
+
+  ## FIXME -- it would be nice to be able to get the list of
+  ## built-in variables directly from Octave so that we wouldn't have to
+  ## remember to update it each time the list of preference variables
+  ## changes
+
+  ## Note that these are no longer variables.
+
+  sym_list = ["EDITOR";
+              "EXEC_PATH";
+              "IMAGE_PATH";
+              "PAGER";
+              "PS1";
+              "PS2";
+              "PS4";
+              "beep_on_error";
+              "completion_append_char";
+              "crash_dumps_octave_core";
+              "echo_executing_commands";
+              "fixed_point_format";
+              "gnuplot_binary";
+              "gnuplot_command_end";
+              "gnuplot_command_plot";
+              "gnuplot_command_replot";
+              "gnuplot_command_splot";
+              "gnuplot_command_title";
+              "gnuplot_command_using";
+              "gnuplot_command_with";
+              "history_file";
+              "history_size";
+              "ignore_function_time_stamp";
+              "info_file";
+              "info_program";
+              "makeinfo_program";
+              "max_recursion_depth";
+              "output_max_field_width";
+              "output_precision";
+              "page_output_immediately";
+              "page_screen_output";
+              "print_answer_id_name";
+              "print_empty_dimensions";
+              "save_precision";
+              "saving_history";
+              "sighup_dumps_octave_core";
+              "sigterm_dumps_octave_core";
+              "silent_functions";
+              "split_long_rows";
+              "string_fill_char";
+              "struct_levels_to_print";
+              "suppress_verbose_help_message"];
+
+  for i = 1:rows(sym_list)
+    sym = deblank (sym_list(i,:));
+    try
+      val = feval (sym);
+      if (isnumeric (val))
+	val = sprintf ("%g", val);
+      endif
+      fprintf (file, "  %s = %s\n", sym, val);
+    catch
+      fprintf (file, "# %s = <no value or error in displaying it>\n", sym);
+    end_try_catch
+  endfor
+
+endfunction
diff --git a/scripts/miscellaneous/edit.m b/scripts/miscellaneous/edit.m
new file mode 100644
index 0000000..8aed01e
--- /dev/null
+++ b/scripts/miscellaneous/edit.m
@@ -0,0 +1,535 @@
+## Copyright (C) 2001, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} edit @var{name}
+## @deftypefnx {Command} edit @var{field} @var{value}
+## @deftypefnx {Command} {@var{value} =} edit get @var{field}
+## Edit the named function, or change editor settings.
+##
+## If @code{edit} is called with the name of a file or function as
+## its argument it will be opened in a text editor.
+## 
+## @itemize @bullet
+## @item
+## If the function @var{name} is available in a file on your path and
+## that file is modifiable, then it will be edited in place.  If it 
+## is a system function, then it will first be copied to the directory
+## @code{HOME} (see further down) and then edited.  
+## If no file is found, then the m-file 
+## variant, ending with ".m", will be considered.  If still no file
+## is found, then variants with a leading "@@" and then with both a
+## leading "@@" and trailing ".m" will be considered.
+##
+## @item
+## If @var{name} is the name of a function defined in the interpreter but 
+## not in an m-file, then an m-file will be created in @code{HOME}
+## to contain that function along with its current definition.  
+##
+## @item
+## If @code{name.cc} is specified, then it will search for @code{name.cc}
+## in the path and try to modify it, otherwise it will create a new
+## @file{.cc} file in @code{HOME}.  If @var{name} happens to be an
+## m-file or interpreter defined function, then the text of that
+## function will be inserted into the .cc file as a comment.
+##
+## @item
+## If @var{name.ext} is on your path then it will be edited, otherwise
+## the editor will be started with @file{HOME/name.ext} as the
+## filename.  If @file{name.ext} is not modifiable, it will be copied to
+## @code{HOME} before editing.
+##
+## @strong{WARNING!} You may need to clear name before the new definition
+## is available.  If you are editing a .cc file, you will need
+## to mkoctfile @file{name.cc} before the definition will be available.
+## @end itemize
+##
+## If @code{edit} is called with @var{field} and @var{value} variables,
+## the value of the control field @var{field} will be @var{value}.
+## If an output argument is requested and the first argument is @code{get}
+## then @code{edit} will return the value of the control field @var{field}.
+## If the control field does not exist, edit will return a structure 
+## containing all fields and values.  Thus, @code{edit get all} returns
+## a complete control structure.
+## The following control fields are used:
+##
+## @table @samp
+## @item editor
+## This is the editor to use to modify the functions.  By default it uses
+## Octave's @code{EDITOR} built-in function, which comes from 
+## @code{getenv("EDITOR")} and defaults to @code{emacs}.  Use @code{%s}
+## In place of the function name.  For example,
+## @table @samp
+## @item [EDITOR, " %s"]
+## Use the editor which Octave uses for @code{bug_report}.
+## @item "xedit %s &"           
+## pop up simple X11 editor in a separate window
+## @item "gnudoit -q \"(find-file \\\"%s\\\")\""   
+## Send it to current Emacs; must have @code{(gnuserv-start)} in @file{.emacs}.
+## @end table
+##
+## See also field 'mode', which controls how the editor is run by Octave.
+## 
+## On Cygwin, you will need to convert the Cygwin path to a Windows
+## path if you are using a native Windows editor.  For example
+## @c Set example in small font to prevent overfull line
+## @smallexample
+## '"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+## @end smallexample
+##
+## @item home
+## This is the location of user local m-files.  Be be sure it is in your
+## path.  The default is @file{~/octave}.
+##
+## @item author
+## This is the name to put after the "## Author:" field of new functions.
+## By default it guesses from the @code{gecos} field of password database.
+## 
+## @item email
+## This is the e-mail address to list after the name in the author field.
+## By default it guesses @code{<$LOGNAME@@$HOSTNAME>}, and if @code{$HOSTNAME}
+## is not defined it uses @code{uname -n}.  You probably want to override this.
+## Be sure to use @code{<user@@host>} as your format.
+##
+## @item license
+## @table @samp
+## @item gpl
+## GNU General Public License (default).
+## @item bsd
+## BSD-style license without advertising clause.
+## @item pd
+## Public domain.
+## @item "text"
+## Your own default copyright and license.
+## @end table
+## 
+## Unless you specify @samp{pd}, edit will prepend the copyright statement 
+## with "Copyright (C) yyyy Function Author".
+## 
+## @item mode
+## This value determines whether the editor should be started in async mode
+## (editor is started in the background and Octave continues) or sync mode
+## (Octave waits until the editor exits).  Set it to "async" to start the editor
+## in async mode.  The default is "sync" (see also "system").
+##
+## @item editinplace
+## Determines whether files should be edited in place, without regard to 
+## whether they are modifiable or not.  The default is @code{false}.
+## @end table
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+function ret = edit (file, state)
+
+  ## Pick up globals or default them.
+
+  persistent FUNCTION = struct ("EDITOR", cstrcat (EDITOR (), " %s"),
+  				"HOME", fullfile (default_home, "octave"),
+  				"AUTHOR", default_user(1),
+  				"EMAIL",  [],
+  				"LICENSE",  "GPL",
+  				"MODE", "sync",
+  				"EDITINPLACE", false);
+
+  ## Make sure the state variables survive "clear functions".
+  mlock;
+
+  if (nargin == 2)
+    switch (toupper (file))
+    case "EDITOR"
+      FUNCTION.EDITOR = state;
+    case "HOME"
+      if (! isempty (state) && state(1) == "~")
+	state = [ default_home, state(2:end) ];
+      endif
+      FUNCTION.HOME = state;
+    case "AUTHOR"
+      FUNCTION.AUTHOR = state;
+    case "EMAIL"
+      FUNCTION.EMAIL = state;
+    case "LICENSE"
+      FUNCTION.LICENSE = state;
+    case "MODE"
+      if (strcmp (state, "sync") || strcmp (state, "async"))
+        FUNCTION.MODE = state;
+      else
+    	error('expected "edit MODE sync|async"');
+      endif
+    case "EDITINPLACE"
+      if (ischar (state))
+        if (strcmpi (state, "true"))
+          state = true;
+        elseif (strcmpi (state, "false"))
+          state = false;
+        else
+          state = eval (state);
+        endif
+      endif
+      FUNCTION.EDITINPLACE = state;
+    case "GET"
+      if (isfield (FUNCTION, toupper(state)))
+        ret = FUNCTION.(toupper (state));
+      else
+        ret = FUNCTION;
+      endif
+    otherwise
+      error ("expected \"edit EDITOR|HOME|AUTHOR|EMAIL|LICENSE|MODE val\"");
+    endswitch
+    return
+  endif
+
+  ## Start the editor without a file if no file is given.
+  if (nargin < 1)
+    if (exist (FUNCTION.HOME, "dir") == 7 && (isunix () || ! ispc ()))
+      system (cstrcat ("cd \"", FUNCTION.HOME, "\" ; ",
+		      sprintf (FUNCTION.EDITOR, "")),
+	      [], FUNCTION.MODE);
+    else
+      system (sprintf (FUNCTION.EDITOR,""), [], FUNCTION.MODE);
+    endif
+    return;
+  endif
+
+  ## Check whether the user is trying to edit a builtin of compiled function.
+  switch (exist (file))
+    case {3, 5}
+      error ("unable to edit a built-in or compiled function");
+  endswitch
+
+  ## Checks for whether the file is
+  ## absolute or relative should be handled inside file_in_loadpath.
+  ## That way, it will be possible to look up files correctly given
+  ## partial path information.  For example, you should be able to
+  ## edit a particular overloaded function by doing any one of
+  ##
+  ##   edit classname/foo
+  ##   edit classname/foo.m
+  ##   edit @classname/foo
+  ##   edit @classname/foo.m
+  ##
+  ## This functionality is needed for other functions as well (at least
+  ## help and type; there may be more).  So the place to fix that is in
+  ## file_in_loadpath, possibly with some help from the load_path class.
+  
+  ## The code below includes a portion that serves as a place-holder for
+  ## the changes suggested above.
+
+  ## Create list of explicit and implicit file names.
+  filelist = {file};
+  ## If file has no extension, add file.m and file.cc to the list.
+  idx = rindex (file, ".");
+  if (idx == 0)
+    ## Create the list of files to look for
+    filelist = {file};
+    if (isempty (regexp (file, "\\.m$")))
+      ## No ".m" at the end of the file, add to the list.
+      filelist{end+1} = cat (2, file, ".m");
+    endif
+    if (isempty (regexp (file, "\\.cc$")))
+      ## No ".cc" at the end of the file, add to the list.
+      filelist{end+1} = cat (2, file, ".cc");
+    endif
+  endif
+
+  ## If the file includes a path, it may be an overloaded function.
+  if (! strcmp (file, "@") && index (file, filesep))
+    ## No "@" at the beginning of the file, add to the list.
+    numfiles = numel(filelist);
+    for n = 1:numfiles
+      filelist{n+numfiles} = cat (2, "@", filelist{n});
+    endfor
+  endif
+
+  ## Search the entire path for the 1st instance of a file in the list.
+  fileandpath = "";
+  for n = 1:numel(filelist)
+    filetoedit = file_in_path (path, filelist{n});
+    if (! isempty (filetoedit))
+      ## The path is explicitly included.
+      fileandpath = filetoedit;
+      break;
+    endif
+  endfor
+
+  if (! isempty (fileandpath))
+    ## If the file exists, then edit it.
+    if (FUNCTION.EDITINPLACE)
+      ## Edit in place even if it is protected.
+      system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
+              [], FUNCTION.MODE);
+      return;
+    else
+      ## If the file is modifiable in place then edit it, otherwise make
+      ## a copy in HOME and then edit it.
+      fid = fopen (fileandpath, "r+t");
+      if (fid < 0)
+        from = fileandpath;
+        fileandpath = cstrcat (FUNCTION.HOME, from (rindex (from, filesep):end));
+        [status, msg] = copyfile (from, fileandpath, 1);
+        if (status == 0)
+          error (msg);
+        endif
+      else
+        fclose (fid);
+      endif
+      system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
+              [], FUNCTION.MODE);
+      return;
+    endif
+  endif
+
+  ## If editing a new file that is neither a m-file or an oct-file,
+  ## just edit it.
+  fileandpath = file;
+  idx = rindex (file, ".");
+  name = file(1:idx-1);
+  ext = file(idx+1:end);
+  switch (ext)
+    case {"cc", "m"}
+      0;
+    otherwise
+      system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
+	      [], FUNCTION.MODE);
+      return;
+  endswitch
+
+  ## The file doesn't exist in path so create it, put in the function
+  ## template and edit it.
+
+  ## Guess the email name if it was not given.
+  if (isempty (FUNCTION.EMAIL))
+    host = getenv("HOSTNAME");
+    if (isempty (host) && ispc ())
+      host = getenv ("COMPUTERNAME");
+    endif
+    if (isempty (host))
+      [status, host] = system ("uname -n");
+      ## trim newline from end of hostname
+      if (! isempty (host))
+	host = host(1:end-1);
+      endif
+    endif
+    if (isempty (host))
+      FUNCTION.EMAIL = " ";
+    else
+      FUNCTION.EMAIL = cstrcat ("<", default_user(0), "@", host, ">");
+    endif
+  endif
+
+  ## Fill in the revision string.
+  now = localtime (time);
+  revs = cstrcat ("Created: ", strftime ("%Y-%m-%d", now));
+
+  ## Fill in the copyright string.
+  copyright = cstrcat (strftime ("Copyright (C) %Y ", now), FUNCTION.AUTHOR);
+
+  ## Fill in the author tag field.
+  author = cstrcat ("Author: ", FUNCTION.AUTHOR, " ", FUNCTION.EMAIL);
+
+  ## Fill in the header.
+  uclicense = toupper (FUNCTION.LICENSE);
+  switch (uclicense)
+    case "GPL"
+      head = cstrcat (copyright, "\n\n", "\
+This program is free software; you can redistribute it and/or modify\n\
+it under the terms of the GNU General Public License as published by\n\
+the Free Software Foundation; either version 2 of the License, or\n\
+(at your option) any later version.\n\
+\n\
+This program is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
+GNU General Public License for more details.\n\
+\n\
+You should have received a copy of the GNU General Public License\n\
+along with Octave; see the file COPYING.  If not, see\n\
+<http://www.gnu.org/licenses/>.\
+");
+      tail = cstrcat (author, "\n", revs);
+
+    case "BSD"
+      head = cstrcat (copyright, "\n\n", "\
+This program is free software; redistribution and use in source and\n\
+binary forms, with or without modification, are permitted provided that\n\
+the following conditions are met:\n\
+\n\
+   1.Redistributions of source code must retain the above copyright\n\
+     notice, this list of conditions and the following disclaimer.\n\
+   2.Redistributions in binary form must reproduce the above copyright\n\
+     notice, this list of conditions and the following disclaimer in the\n\
+     documentation and/or other materials provided with the distribution.\n\
+\n\
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n\
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n\
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n\
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\
+SUCH DAMAGE.\
+");
+      tail = cstrcat (author, "\n", revs);
+
+    case "PD"
+      head = "";
+      tail = cstrcat (author, "\n", revs, "\n\n",
+		     "This program is granted to the public domain.");
+
+    otherwise
+      head = "";
+      tail = cstrcat (copyright, "\n\n", FUNCTION.LICENSE, "\n",
+		     author, "\n", revs);
+  endswitch
+
+  ## Generate the function template.
+  exists = exist (name);
+  switch (ext)
+    case {"cc", "C", "cpp"}
+      if (isempty (head))
+	comment = cstrcat ("/*\n", tail, "\n\n*/\n\n");
+      else
+	comment = cstrcat ("/*\n", head, "\n\n", tail, "\n\n*/\n\n");
+      endif
+      ## If we are shadowing an m-file, paste the code for the m-file.
+      if (any (exists == [2, 103]))
+	code = cstrcat ("\\ ", strrep (type (name), "\n", "\n// "));
+      else
+	code = " ";
+      endif
+      body = cstrcat ("#include <octave/oct.h>\n\n",
+                     "DEFUN_DLD(", name, ",args,nargout,\"\\\n",
+		     name, "\\n\\\n\")\n{\n",
+		     "  octave_value_list retval;\n",
+		     "  int nargin = args.length();\n\n",
+		     code, "\n  return retval;\n}\n");
+
+      text = cstrcat (comment, body);
+    case "m"
+      ## If we are editing a function defined on the fly, paste the
+      ## code.
+      if (any (exists == [2, 103]))
+	body = type (name);
+      else
+	body = cstrcat ("function [ ret ] = ", name, " ()\n\nendfunction\n");
+      endif
+      if (isempty (head))
+	comment = cstrcat ("## ", name, "\n\n",
+			  "## ", strrep (tail, "\n", "\n## "), "\n\n");
+      else
+	comment = cstrcat ("## ", strrep(head,"\n","\n## "), "\n\n", ...
+			  "## ", name, "\n\n", ...
+			  "## ", strrep (tail, "\n", "\n## "), "\n\n");
+      endif
+      text = cstrcat (comment, body);
+  endswitch
+
+  ## Write the initial file (if there is anything to write)
+  fid = fopen (fileandpath, "wt");
+  if (fid < 0)
+    error ("edit: could not create %s", fileandpath);
+  endif
+  fputs (fid, text);
+  fclose (fid);
+
+  ## Finally we are ready to edit it!
+  system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
+	  [], FUNCTION.MODE);
+
+endfunction
+
+function ret = default_home ()
+
+  ret = getenv ("HOME");
+  if (isempty (ret))
+    ret = glob ("~");
+    if (! isempty (ret))
+      ret = ret{1};
+    else
+      ret = "";
+    endif
+  endif
+
+endfunction
+
+## Return the name associated with the current user ID.
+##
+## If LONG_FORM is 1, return the full name.  This will be the
+## default author.  Otherwise return the login name.
+## login at host will be the default email address.
+
+function ret = default_user (long_form)
+
+  ent = getpwuid (getuid);
+  if (! isstruct (ent))
+    ret = getenv ("USER");
+    if (isempty (ret))
+      ret = getenv ("USERNAME");
+    endif
+  elseif (long_form)
+    ret = ent.gecos;
+    pos = strfind (ret, ",");
+    if (! isempty (pos))
+      ret = ret(1:pos-1);
+    endif
+  else
+    ret = ent.name;
+  endif
+
+endfunction
+
+%!test
+%! s.editor = edit ("get", "editor");
+%! s.home = edit ("get", "home");
+%! s.author = edit ("get", "author");
+%! s.email = edit ("get", "email");
+%! s.license = edit ("get", "license");
+%! s.editinplace = edit ("get", "editinplace");
+%! s.mode = edit ("get", "mode");
+%! edit editor none
+%! edit home none
+%! edit author none
+%! edit email none
+%! edit license none
+%! edit ("editinplace", !s.editinplace)
+%! if (s.mode(1) == "a")
+%!   edit mode sync
+%! else
+%!   edit mode async
+%! endif
+%! edit ("editor", s.editor);
+%! edit ("home", s.home);
+%! edit ("author", s.author);
+%! edit ("email", s.email);
+%! edit ("license", s.license);
+%! edit ("editinplace", s.editinplace);
+%! edit ("mode", s.mode);
+%! assert (edit ("get", "editor"), s.editor);
+%! assert (edit ("get", "home"), s.home);
+%! assert (edit ("get", "author"), s.author);
+%! assert (edit ("get", "email"), s.email);
+%! assert (edit ("get", "license"), s.license);
+%! assert (edit ("get", "editinplace"), s.editinplace);
+%! assert (edit ("get", "mode"), s.mode);
+
diff --git a/scripts/miscellaneous/fileattrib.m b/scripts/miscellaneous/fileattrib.m
new file mode 100644
index 0000000..772c206
--- /dev/null
+++ b/scripts/miscellaneous/fileattrib.m
@@ -0,0 +1,137 @@
+## Copyright (C) 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} fileattrib (@var{file})
+## Return information about @var{file}.
+##
+## If successful, @var{status} is 1, with @var{result} containing a
+## structure with the following fields:
+##
+## @table @code
+## @item Name
+## Full name of @var{file}.
+## @item archive
+## True if @var{file} is an archive (Windows).
+## @item system
+## True if @var{file} is a system file (Windows).
+## @item hidden
+## True if @var{file} is a hidden file (Windows).
+## @item directory
+## True if @var{file} is a directory.
+## @item UserRead
+## @itemx GroupRead
+## @itemx OtherRead
+## True if the user (group; other users) has read permission for
+## @var{file}.
+## @item UserWrite
+## @itemx GroupWrite
+## @itemx OtherWrite
+## True if the user (group; other users) has write permission for
+## @var{file}.
+## @item UserExecute
+## @itemx GroupExecute
+## @itemx OtherExecute
+## True if the user (group; other users) has execute permission for
+## @var{file}.
+## @end table
+## If an attribute does not apply (i.e., archive on a Unix system) then
+## the field is set to NaN.
+##
+## With no input arguments, return information about the current
+## directory.
+##
+## If @var{file} contains globbing characters, return information about
+## all the matching files.
+## @seealso{glob}
+## @end deftypefn
+
+function [status, msg, msgid] = fileattrib (file)
+
+  status = true;
+  msg = "";
+  msgid = "";
+
+  if (nargin == 0)
+    file = ".";
+  endif
+
+  if (ischar (file))
+    files = glob (file);
+    if (isempty (files))
+      files = {file};
+      nfiles = 1;
+    else
+      nfiles = length (files);
+    endif
+  else
+    error ("fileattrib: expecting first argument to be a character string");
+  endif
+
+  if (nargin == 0 || nargin == 1)
+
+    r_n = r_a = r_s = r_h = r_d ...
+	= r_u_r = r_u_w = r_u_x ...
+	= r_g_r = r_g_w = r_g_x ...
+	= r_o_r = r_o_w = r_o_x = cell (nfiles, 1);
+
+    curr_dir = pwd ();
+
+    for i = 1:nfiles
+      [info, err, msg] = stat (files{i});
+      if (! err)
+	r_n{i} = canonicalize_file_name (files{i});
+	r_a{i} = NaN;
+	r_s{i} = NaN;
+	r_h{i} = NaN;
+	r_d{i} = S_ISDIR (info.mode);
+	## FIXME -- maybe we should have S_IRUSR etc. masks?
+	modestr = info.modestr;
+	r_u_r{i} = modestr(2) == "r";
+	r_u_w{i} = modestr(3) == "w";
+	r_u_x{i} = modestr(4) == "x";
+	r_g_r{i} = modestr(5) == "r";
+	r_g_w{i} = modestr(6) == "w";
+	r_g_x{i} = modestr(7) == "x";
+	r_o_r{i} = modestr(8) == "r";
+	r_o_w{i} = modestr(9) == "w";
+	r_o_x{i} = modestr(10) == "x";
+      else
+	status = false;
+	msgid = "fileattrib";
+	break;
+      endif
+    endfor
+    if (status)
+      r = struct ("Name", r_n, "archive", r_a, "system", r_s,
+		  "hidden", r_s, "directory", r_d, "UserRead", r_u_r,
+		  "UserWrite", r_u_w, "UserExecute", r_u_x,
+		  "GroupRead", r_g_r, "GroupWrite", r_g_w,
+		  "GroupExecute", r_g_x, "OtherRead", r_o_r,
+		  "OtherWrite", r_o_w, "OtherExecute", r_o_x);
+      if (nargout == 0)
+	status = r;
+      else
+	msg = r;
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/fileparts.m b/scripts/miscellaneous/fileparts.m
new file mode 100644
index 0000000..579b56f
--- /dev/null
+++ b/scripts/miscellaneous/fileparts.m
@@ -0,0 +1,96 @@
+## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{dir}, @var{name}, @var{ext}, @var{ver}] =} fileparts (@var{filename})
+## Return the directory, name, extension, and version components of
+## @var{filename}.
+## @seealso{fullfile}
+## @end deftypefn
+
+function [directory, name, extension, version] = fileparts (filename)
+
+  if (nargin == 1)
+    if (ischar (filename))
+      ds = strchr (filename, filesep ("all"), 1, "last");
+      if (isempty (ds))
+	ds = 0;
+      endif
+      es = rindex (filename, ".");
+      ## These can be the same if they are both 0 (no dir or ext).
+      if (es <= ds)
+	es = length(filename)+1;
+      endif
+      if (ds == 0)
+	directory = "";
+      elseif (ds == 1)
+	directory = filename(1);
+      else
+	directory = filename(1:ds-1);
+      endif
+      name = filename(ds+1:es-1);
+      if (es > 0 && es <= length (filename))
+	extension = filename(es:end);
+      else
+	extension = "";
+      endif
+      version = "";
+    else
+      error ("fileparts: expecting filename argument to be a string");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! [d, n, e] = fileparts ("file");
+%! assert (strcmp (d, "") && strcmp (n, "file") && strcmp (e, ""));
+
+%!test
+%! [d, n, e] = fileparts ("file.ext");
+%! assert (strcmp (d, "") && strcmp (n, "file") && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts ("/file.ext");
+%! assert (strcmp (d, "/") && strcmp (n, "file") && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts ("dir/file.ext");
+%! assert (strcmp (d, "dir") && strcmp (n, "file") && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts ("./file.ext");
+%! assert (strcmp (d, ".") && strcmp (n, "file") && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts ("d1/d2/file.ext");
+%! assert (strcmp (d, "d1/d2") && strcmp (n, "file") && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts ("/d1/d2/file.ext");
+%! assert (strcmp (d, "/d1/d2") && strcmp (n, "file") && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts ("/.ext");
+%! assert (strcmp (d, "/") && strcmp (n, char (zeros (1, 0))) && strcmp (e, ".ext"));
+
+%!test
+%! [d, n, e] = fileparts (".ext");
+%! assert (strcmp (d, "") && strcmp (n, char (zeros (1, 0))) && strcmp (e, ".ext"));
diff --git a/scripts/miscellaneous/flops.m b/scripts/miscellaneous/flops.m
new file mode 100644
index 0000000..79aa910
--- /dev/null
+++ b/scripts/miscellaneous/flops.m
@@ -0,0 +1,38 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} flops ()
+## This function is provided for @sc{matlab} compatibility, but it doesn't
+## actually do anything.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = flops ()
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  warning ("flops is a flop, always returning zero");
+
+  retval = 0;
+
+endfunction
diff --git a/scripts/miscellaneous/fullfile.m b/scripts/miscellaneous/fullfile.m
new file mode 100644
index 0000000..93211ee
--- /dev/null
+++ b/scripts/miscellaneous/fullfile.m
@@ -0,0 +1,80 @@
+## Copyright (C) 2003, 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{filename} =} fullfile (@var{dir1}, @var{dir2}, @dots{}, @var{file})
+## Return a complete filename constructed from the given components.
+## @seealso{fileparts}
+## @end deftypefn
+
+function filename = fullfile (varargin)
+
+  if (nargin > 0)
+    ## Discard all empty arguments
+    varargin(cellfun (@isempty, varargin)) = [];
+    nargs = numel (varargin);
+    if (nargs > 1)
+      filename = varargin{1};
+      if (strcmp (filename(end), filesep))
+	filename(end) = "";
+      endif
+      for i = 2:nargs
+	tmp = varargin{i};
+	if (i < nargs && strcmp (tmp(end), filesep))
+	  tmp(end) = "";
+	elseif (i == nargs && strcmp (tmp, filesep))
+	  tmp = "";
+	endif
+	filename = cstrcat (filename, filesep, tmp);
+      endfor
+    elseif (nargs == 1)
+      filename = varargin{1};
+    else
+      filename = "";
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!shared fs, fsx, xfs, fsxfs, xfsy
+%! fs = filesep ();
+%! fsx = cstrcat (fs, "x");
+%! xfs = cstrcat ("x", fs);
+%! fsxfs = cstrcat (fs, "x", fs);
+%! xfsy = cstrcat ("x", fs, "y");
+%!assert (fullfile (""), "")
+%!assert (fullfile (fs), fs)
+%!assert (fullfile ("", fs), fs)
+%!assert (fullfile (fs, ""), fs)
+%!assert (fullfile ("", fs), fs)
+%!assert (fullfile ("x"), "x")
+%!assert (fullfile ("", "x"), "x")
+%!assert (fullfile ("x", ""), "x")
+%!assert (fullfile ("", "x", ""), "x")
+%!assert (fullfile ("x", "y"), xfsy)
+%!assert (fullfile ("x", "", "y"), xfsy)
+%!assert (fullfile ("x", "", "y", ""), xfsy)
+%!assert (fullfile ("", "x", "", "y", ""), xfsy)
+%!assert (fullfile (fs), fs)
+%!assert (fullfile (fs, fs), fs)
+%!assert (fullfile (fs, "x"), fsx)
+%!assert (fullfile (fs, xfs), fsxfs)
+%!assert (fullfile (fsx, fs), fsxfs)
+%!assert (fullfile (fs, "x", fs), fsxfs)
diff --git a/scripts/miscellaneous/getfield.m b/scripts/miscellaneous/getfield.m
new file mode 100644
index 0000000..65e70d8
--- /dev/null
+++ b/scripts/miscellaneous/getfield.m
@@ -0,0 +1,63 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Etienne Grossmann
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{v1}, @dots{}] =} getfield (@var{s}, @var{key}, @dots{}) 
+## Extract fields from a structure.  For example
+##
+## @example
+## @group
+## ss(1,2).fd(3).b = 5;
+## getfield (ss, @{1,2@}, "fd", @{3@}, "b")
+## @result{} ans = 5
+## @end group
+## @end example
+##
+## Note that the function call in the previous example is equivalent to
+## the expression
+##
+## @example
+## @group
+## i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4= "b";
+## ss(i1@{:@}).(i2)(i3@{:@}).(i4)
+## @end group
+## @end example
+## @seealso{setfield, rmfield, isfield, isstruct, fieldnames, struct}
+## @end deftypefn
+
+## Author: Etienne Grossmann <etienne at cs.uky.edu>
+
+function s = getfield (s, varargin)
+
+  for idx = 1:nargin-1
+    i = varargin{idx};
+    if (iscell (i))
+      s = s(i{:});
+    else
+      s = s.(i);
+    endif
+  endfor
+
+endfunction
+
+%!test
+%! x.a = "hello";
+%! assert(getfield(x,"a"),"hello");
+%!test
+%! ss(1,2).fd(3).b = 5;
+%! assert(getfield(ss,{1,2},'fd',{3},'b'),5)
diff --git a/scripts/miscellaneous/gunzip.m b/scripts/miscellaneous/gunzip.m
new file mode 100644
index 0000000..a9fbffb
--- /dev/null
+++ b/scripts/miscellaneous/gunzip.m
@@ -0,0 +1,47 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Bill Denney
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gunzip (@var{gzfile}, @var{dir})
+## Unpack the gzip archive @var{gzfile} to the directory @var{dir}.  If
+## @var{dir} is not specified, it defaults to the current directory.  If
+## the @var{gzfile} is a directory, all files in the directory will be
+## recursively gunzipped.
+## @seealso{unpack, bunzip2, tar, untar, gzip, gunzip, zip, unzip}
+## @end deftypefn
+
+## Author: Bill Denney <denney at seas.upenn.edu>
+
+function varargout = gunzip (files, outputdir)
+
+  if (! (nargin == 1 || nargin == 2))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    outputdir = ".";
+  endif
+
+  if (nargout > 0)
+    varargout = cell (1, nargout);
+    [varargout{:}] = unpack (files, outputdir, mfilename ());
+  else
+    unpack (files, outputdir, mfilename ());
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/gzip.m b/scripts/miscellaneous/gzip.m
new file mode 100644
index 0000000..0fabb9b
--- /dev/null
+++ b/scripts/miscellaneous/gzip.m
@@ -0,0 +1,71 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{entries} =} gzip (@var{files})
+## @deftypefnx {Function File} {@var{entries} =} gzip (@var{files}, @var{outdir})
+## Compress the list of files and/or directories specified in @var{files}.
+## Each file is compressed separately and a new file with a '.gz' extension
+## is created.  The original files are not touched.  Existing compressed
+## files are silently overwritten.  If @var{outdir} is defined the compressed 
+## versions of the files are placed in this directory.
+## @seealso{gunzip, bzip2, zip, tar}
+## @end deftypefn
+
+function entries = gzip (varargin)
+  if (nargin == 1 || nargin == 2) && (nargout <= 1)
+    if nargout == 0
+      __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
+    else
+      entries = __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
+
+%!error <Invalid call to gzip.  Correct usage is> gzip("1", "2", "3");
+%!error <Invalid call to gzip.  Correct usage is> gzip();
+%!error <output directory does not exist> gzip("1", tmpnam);
+%!error <expecting FILES to be a character array> gzip(1);
+%!xtest
+%!  # test gzip together with gunzip
+%!  unwind_protect
+%!    filename = tmpnam;
+%!    dummy    = 1;
+%!    save(filename, "dummy");
+%!    dirname  = tmpnam;
+%!    mkdir(dirname);
+%!    entry = gzip(filename, dirname);
+%!    [path, basename, extension] = fileparts(filename);
+%!    if ! strcmp(entry, [dirname, filesep, basename, extension, ".gz"])
+%!      error("gzipped file does not match expected name!");
+%!    endif
+%!    if ! exist(entry, "file")
+%!      error("gzipped file cannot be found!");
+%!    endif 
+%!    gunzip(entry);
+%!    if (system(sprintf("diff %s %s%c%s%s", filename, dirname, filesep,
+%!                                          basename, extension)))
+%!      error("unzipped file not equal to original file!");
+%!    end
+%!  unwind_protect_cleanup
+%!    delete(filename);
+%!    delete([dirname, filesep, basename, extension]);
+%!    rmdir(dirname);
+%!  end_unwind_protect
diff --git a/scripts/miscellaneous/info.m b/scripts/miscellaneous/info.m
new file mode 100644
index 0000000..3dfb8f6
--- /dev/null
+++ b/scripts/miscellaneous/info.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2008 Julian Schnidder
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} info ()
+## Display contact information for the GNU Octave community.
+## @end deftypefn
+
+function info ()
+
+  printf ("\n\
+  Additional information about GNU Octave is available at\n\
+  http://www.octave.org\n\
+\n\
+  Descriptions of mailing lists devoted to Octave are available at\n\
+  http://www.octave.org/archive.html\n\
+\n\
+  You may also find some information in the Octave Wiki at\n\
+  http://wiki.octave.org\n\
+\n\
+  Additional functionality can be enabled by using packages from\n\
+  the Octave Forge project, which may be found at\n\
+  http://octave.sourceforge.net\n\
+\n\
+  Report bugs to <bug at octave.org> (but first, please read\n\
+  http://www.octave.org/bugs.html to learn how to write a helpful report)\n\
+\n");
+
+endfunction
diff --git a/scripts/miscellaneous/inputname.m b/scripts/miscellaneous/inputname.m
new file mode 100644
index 0000000..8a3aa9c
--- /dev/null
+++ b/scripts/miscellaneous/inputname.m
@@ -0,0 +1,50 @@
+## Copyright (C) 2004, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} inputname (@var{n})
+## Return the text defining @var{n}-th input to the function.
+## @end deftypefn
+
+function s = inputname (n)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  s = evalin ("caller", sprintf ("deblank (argn(%d,:));", n));
+
+endfunction
+
+## Warning: heap big magic in the following tests!!!
+## The test function builds a private context for each
+## test, with only the specified values shared between
+## them.  It does this using the following template:
+##
+##     function [<shared>] = testfn(<shared>)
+##        <test>
+##
+## To test inputname, I need a function context invoked
+## with known parameter names.  So define a couple of
+## shared parameters, et voila!, the test is trivial.
+%!shared hello,worldly
+%!assert(inputname(1),'hello');
+%!assert(inputname(2),'worldly');
diff --git a/scripts/miscellaneous/intwarning.m b/scripts/miscellaneous/intwarning.m
new file mode 100644
index 0000000..b033178
--- /dev/null
+++ b/scripts/miscellaneous/intwarning.m
@@ -0,0 +1,128 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} intwarning (@var{action})
+## @deftypefnx {Function File} {} intwarning (@var{s})
+## @deftypefnx {Function File} {@var{s} =} intwarning (@dots{})
+## Control the state of the warning for integer conversions and math
+## operations.
+##
+## @table @asis
+## @item "query"
+## The state of the Octave integer conversion and math warnings is
+## queried.  If there is no output argument, then the state is printed.
+## Otherwise it is returned in a structure with the fields "identifier"
+## and "state".
+##
+## @c Set example in small font to prevent overfull line
+## @smallexample
+## @group
+## intwarning ("query")
+## The state of warning "Octave:int-convert-nan" is "off"
+## The state of warning "Octave:int-convert-non-int-val" is "off"
+## The state of warning "Octave:int-convert-overflow" is "off"
+## The state of warning "Octave:int-math-overflow" is "off"
+## @end group
+## @end smallexample 
+##
+## @item "on"
+## Turn integer conversion and math warnings "on".  If there is no output
+## argument, then nothing is printed.  Otherwise the original state of
+## the state of the integer conversion and math warnings is returned in
+## a structure array.
+##
+## @item "off"
+## Turn integer conversion and math warnings "on".  If there is no output
+## argument, then nothing is printed.  Otherwise the original state of
+## the state of the integer conversion and math warnings is returned in
+## a structure array.
+## @end table
+##
+## The original state of the integer warnings can be restored by passing
+## the structure array returned by @code{intwarning} to a later call to
+## @code{intwarning}.  For example
+##
+## @example
+## @group
+## s = intwarning ("off");
+## @dots{}
+## intwarning (s);
+## @end group
+## @end example
+## @seealso{warning}
+## @end deftypefn
+
+function y = intwarning (x)
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    if (nargout > 0)
+      y = warning("query", "Octave:int-convert-nan");
+      y = [y; warning("query", "Octave:int-convert-non-int-val")];
+      y = [y; warning("query", "Octave:int-convert-overflow")];
+      y = [y; warning("query", "Octave:int-math-overflow")];
+    endif
+    if (ischar (x))
+      if (strcmpi (x, "query"))
+	if (nargout == 0)
+	  __print_int_warn_state__ ("Octave:int-convert-nan");
+	  __print_int_warn_state__ ("Octave:int-convert-non-int-val");
+	  __print_int_warn_state__ ("Octave:int-convert-overflow");
+	  __print_int_warn_state__ ("Octave:int-math-overflow");
+	  printf("\n");
+	endif
+      elseif (strcmpi (x, "on"))
+	warning ("on", "Octave:int-convert-nan");
+	warning ("on", "Octave:int-convert-non-int-val");
+	warning ("on", "Octave:int-convert-overflow");
+	warning ("on", "Octave:int-math-overflow");
+      elseif (strcmpi (x, "off"))
+	warning ("off", "Octave:int-convert-nan");
+	warning ("off", "Octave:int-convert-non-int-val");
+	warning ("off", "Octave:int-convert-overflow");    
+	warning ("off", "Octave:int-math-overflow");    
+      else
+	error ("intwarning: unrecognized argument");
+      endif
+    elseif (isstruct(x))
+      for fld = fieldnames (x)
+	if (strcmp ("Octave:int-convert-nan") || 
+	    strcmp ("Octave:int-convert-non-int-val") || 
+	    strcmp ("Octave:int-convert-overflow") ||
+	    strcmp ("Octave:int-cmath-overflow"))
+	  s = getfield (x, fld);
+	  if (! ischar (s) || !(strcmpi("s","on") || strcmpi("s","off")))
+	    error ("intwarning: unexpected warning state");
+	  endif
+	  warning (s, fld);
+	else
+	  error ("intwarning: unrecognized integer warning %s", fld);
+	endif
+      endfor
+    else
+      error ("intwarning: unexpected input");
+    endif
+  endif
+endfunction
+
+function __print_int_warn_state__ (s)
+  fprintf ("The state of warning \"%s\" is \"%s\"\n", 
+	   s, warning ("query", s).state);
+endfunction
diff --git a/scripts/miscellaneous/ismac.m b/scripts/miscellaneous/ismac.m
new file mode 100644
index 0000000..da404f9
--- /dev/null
+++ b/scripts/miscellaneous/ismac.m
@@ -0,0 +1,34 @@
+## Copyright (C) 2007 Thomas Treichl
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ismac ()
+## Return 1 if Octave is running on a Mac OS X system and 0 otherwise.
+## @seealso{ispc, isunix}
+## @end deftypefn
+
+function retval = ismac ()
+
+  if (nargin == 0)
+    retval = octave_config_info ("mac");
+  else
+    print_usage ();
+  endif
+
+endfunction
+
diff --git a/scripts/miscellaneous/ispc.m b/scripts/miscellaneous/ispc.m
new file mode 100644
index 0000000..0e8dddd
--- /dev/null
+++ b/scripts/miscellaneous/ispc.m
@@ -0,0 +1,33 @@
+## Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ispc ()
+## Return 1 if Octave is running on a Windows system and 0 otherwise.
+## @seealso{ismac, isunix}
+## @end deftypefn
+
+function retval = ispc ()
+
+  if (nargin == 0)
+    retval = octave_config_info ("windows");
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/isunix.m b/scripts/miscellaneous/isunix.m
new file mode 100644
index 0000000..9b7281c
--- /dev/null
+++ b/scripts/miscellaneous/isunix.m
@@ -0,0 +1,33 @@
+## Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isunix ()
+## Return 1 if Octave is running on a Unix-like system and 0 otherwise.
+## @seealso{ismac, ispc}
+## @end deftypefn
+
+function retval = isunix ()
+
+  if (nargin == 0)
+    retval = octave_config_info ("unix");
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/license.m b/scripts/miscellaneous/license.m
new file mode 100644
index 0000000..d9baa94
--- /dev/null
+++ b/scripts/miscellaneous/license.m
@@ -0,0 +1,189 @@
+## Copyright (C) 2005, 2006, 2007, 2009 William Poetra Yoga Hadisoeseno
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} license
+## Display the license of Octave.
+##
+## @deftypefnx {Function File} {} license ("inuse")
+## Display a list of packages currently being used.
+##
+## @deftypefnx {Function File} {@var{retval} =} license ("inuse")
+## Return a structure containing the fields @code{feature} and @code{user}.
+##
+## @deftypefnx {Function File} {@var{retval} =} license ("test", @var{feature})
+## Return 1 if a license exists for the product identified by the string
+## @var{feature} and 0 otherwise.  The argument @var{feature} is case
+## insensitive and only the first 27 characters are checked.
+##
+## @deftypefnx {Function File} {} license ("test", @var{feature}, @var{toggle})
+## Enable or disable license testing for @var{feature}, depending on
+## @var{toggle}, which may be one of:
+##
+## @table @samp
+## @item "enable"
+## Future tests for the specified license of @var{feature} are conducted
+## as usual.
+## @item "disable"
+## Future tests for the specified license of @var{feature} return 0.
+## @end table
+##
+## @deftypefnx {Function File} {@var{retval} =} license ("checkout", @var{feature})
+## Check out a license for @var{feature}, returning 1 on success and 0
+## on failure.
+##
+## This function is provided for compatibility with @sc{matlab}.
+## @seealso{ver, version}
+## @end deftypefn
+
+## Author: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function retval = license (varargin)
+
+  persistent __octave_licenses__;
+
+  if (isempty (__octave_licenses__))
+    __octave_licenses__ = cell ();
+    __octave_licenses__{1,1} = "Octave";
+    __octave_licenses__{1,2} = "GNU General Public License";
+    __octave_licenses__{1,3} = true;
+    if (exist ("OCTAVE_FORGE_VERSION"))
+      __octave_licenses__{2,1} = "octave-forge";
+      __octave_licenses__{2,2} = "<various licenses>";
+      __octave_licenses__{2,3} = true;
+    endif
+  endif
+
+  nout = nargout;
+  nin = nargin;
+  nr_licenses = rows (__octave_licenses__);
+
+  if (nout > 1 || nin > 3)
+    error ("type `help license' for usage info");
+  endif
+
+  if (nin == 0)
+
+    found = false;
+    for p = 1:nr_licenses
+      if (strcmp (__octave_licenses__{p,1}, "Octave"))
+        found = true;
+        break;
+      endif
+    endfor
+
+    if (found)
+      result = __octave_licenses__{p,2};
+    else
+      result = "unknown";
+    endif
+
+    if (nout == 0)
+      printf ("%s\n", result);
+    else
+      retval = result;
+    endif
+
+  elseif (nin == 1)
+
+    if (nout == 0)
+
+      if (! strcmp (varargin{1}, "inuse"))
+        usage ("license (\"inuse\")");
+      endif
+
+      for p = 1:nr_licenses
+        printf ("%s\n", __octave_licenses__{p,1});
+      endfor
+
+    else
+
+      if (! strcmp (varargin{1}, "inuse"))
+        usage ("retval = license (\"inuse\")");
+      endif
+
+      pw = getpwuid (getuid ());
+      if (isstruct (pw))
+	username = pw.name;
+      else
+	username = "octave_user";
+      endif
+
+      retval(1:nr_licenses) = struct ("feature", "", "user", "");
+      for p = 1:nr_licenses
+        retval(p).feature = __octave_licenses__{p,1};
+        retval(p).user = username;
+      endfor
+
+    endif
+
+  else
+
+    feature = varargin{2}(1:(min ([(length (varargin{2})), 27])));
+
+    if (strcmp (varargin{1}, "test"))
+
+      found = false;
+      for p = 1:nr_licenses
+        if (strcmpi (feature, __octave_licenses__{p,1}))
+          found = true;
+          break;
+        endif
+      endfor
+
+      if (nin == 2)
+        retval = found && __octave_licenses__{p,3};
+      else
+        if (found)
+          if (strcmp (varargin{3}, "enable"))
+            __octave_licenses__{p,3} = true;
+          elseif (strcmp (varargin{3}, "disable"))
+            __octave_licenses__{p,3} = false;
+          else
+            error ("toggle must be either `enable' of `disable'");
+          endif
+        else
+          error ("feature `%s' not found", feature);
+        endif
+      endif
+
+    elseif (strcmp (varargin{1}, "checkout"))
+
+      if (nin != 2)
+        usage ("retval = license (\"checkout\", feature)");
+      endif
+
+      found = false;
+      for p = 1:nr_licenses
+        if (strcmpi (feature, __octave_licenses__{p,1}))
+          found = true;
+          break;
+        endif
+      endfor
+
+      retval = found && __octave_licenses__{p,3};
+
+    else
+
+      error ("type `help license' for usage info");
+
+    endif
+
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/list_primes.m b/scripts/miscellaneous/list_primes.m
new file mode 100644
index 0000000..fbdb24d
--- /dev/null
+++ b/scripts/miscellaneous/list_primes.m
@@ -0,0 +1,85 @@
+## Copyright (C) 1993, 1995, 1996, 1997, 2000, 2002, 2005, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} list_primes (@var{n})
+## List the first @var{n} primes.  If @var{n} is unspecified, the first
+## 25 primes are listed.
+##
+## The algorithm used is from page 218 of the @TeX{}book.
+## @seealso{primes, isprime}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = list_primes (n)
+
+  if (nargin > 0)
+    if (! isscalar (n))
+      error ("list_primes: argument must be a scalar");
+    endif
+  endif
+
+  if (nargin == 0)
+    n = 25;
+  endif
+
+  if (n == 1)
+    retval = 2;
+    return;
+  endif
+
+  if (n == 2)
+    retval = [2; 3];
+    return;
+  endif
+
+  retval = zeros (1, n);
+  retval (1) = 2;
+  retval (2) = 3;
+
+  n = n - 2;
+  i = 3;
+  p = 5;
+  while (n > 0)
+
+    is_prime = 1;
+    is_unknown = 1;
+    d = 3;
+    while (is_unknown)
+      a = fix (p / d);
+      if (a <= d)
+        is_unknown = 0;
+      endif
+      if (a * d == p)
+        is_prime = 0;
+        is_unknown = 0;
+      endif
+      d = d + 2;
+    endwhile
+
+    if (is_prime)
+      retval (i++) = p;
+      n--;
+    endif
+    p = p + 2;
+
+  endwhile
+
+endfunction
diff --git a/scripts/miscellaneous/ls.m b/scripts/miscellaneous/ls.m
new file mode 100644
index 0000000..3cb6c90
--- /dev/null
+++ b/scripts/miscellaneous/ls.m
@@ -0,0 +1,83 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deffn {Command} ls options
+## List directory contents.  For example,
+## 
+## @example
+## @group
+## ls -l
+##      @print{} total 12
+##      @print{} -rw-r--r--   1 jwe  users  4488 Aug 19 04:02 foo.m
+##      @print{} -rw-r--r--   1 jwe  users  1315 Aug 17 23:14 bar.m
+## @end group
+## @end example
+## 
+## The @code{dir} and @code{ls} commands are implemented by calling your
+## system's directory listing command, so the available options may vary
+## from system to system.
+## @seealso{dir, stat, readdir, glob, filesep, ls_command}
+## @end deffn
+
+## Author: jwe
+
+function retval = ls (varargin)
+
+  global __ls_command__;
+
+  if (isempty (__ls_command__) || ! ischar (__ls_command__))
+    ## Initialize value for __ls_command__.
+    ls_command ();
+  endif
+
+  if (iscellstr (varargin))
+
+    args = tilde_expand (varargin);
+
+    cmd = sprintf ("%s ", __ls_command__, args{:});
+
+    if (page_screen_output () || nargout > 0)
+
+      [status, output] = system (cmd);
+
+      if (status == 0)
+	if (nargout == 0)
+	  puts (output);
+	else
+	  retval = strvcat (regexp (output, '[^\s]+', 'match'){:});
+	endif
+      else
+	error ("ls: command exited abnormally with status %d", status);
+      endif
+
+    else
+      ## Just let the output flow if the pager is off.  That way the
+      ## output from things like "ls -R /" will show up immediately and
+      ## we won't have to buffer all the output.
+      system (cmd);
+    endif
+    
+  else
+    error ("ls: expecting all arguments to be character strings");
+  endif
+
+endfunction
+
+%!error ls (1);
+
diff --git a/scripts/miscellaneous/ls_command.m b/scripts/miscellaneous/ls_command.m
new file mode 100644
index 0000000..33f5e7e
--- /dev/null
+++ b/scripts/miscellaneous/ls_command.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{old_cmd} =} ls_command (@var{cmd})
+## Set or return the shell command used by Octave's @code{ls} command.
+## The value of @var{cmd} must be a character string.
+## With no arguments, simply return the previous value.
+## @seealso{ls}
+## @end deftypefn
+
+## Author: jwe
+
+function old_cmd = ls_command (cmd)
+
+  global __ls_command__;
+
+  if (isempty (__ls_command__))
+    ## FIXME -- ispc and isunix both return true for Cygwin.  Should they?
+    if (ispc () && ! isunix () && isempty (file_in_path (EXEC_PATH, "ls")))
+      __ls_command__ = "cmd /C dir /D";
+    else
+      __ls_command__ = "ls -C";
+    endif
+  endif
+
+  if (nargin == 0 || nargin == 1)
+
+    old_cmd = __ls_command__;
+
+    if (nargin == 1)
+      if (ischar (cmd))
+	__ls_command__ = cmd;
+      else
+	error ("ls_command: expecting argument to be a character string");
+      endif
+    endif
+
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/menu.m b/scripts/miscellaneous/menu.m
new file mode 100644
index 0000000..a26d236
--- /dev/null
+++ b/scripts/miscellaneous/menu.m
@@ -0,0 +1,80 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+##               2004, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} menu (@var{title}, @var{opt1}, @dots{})
+## Print a title string followed by a series of options.  Each option will
+## be printed along with a number.  The return value is the number of the
+## option selected by the user.  This function is useful for interactive
+## programs.  There is no limit to the number of options that may be passed
+## in, but it may be confusing to present more than will fit easily on one
+## screen.
+## @seealso{disp, printf, input}
+## @end deftypefn
+
+## Author: jwe
+
+function num = menu (t, varargin)
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  ## Force pending output to appear before the menu.
+
+  fflush (stdout);
+
+  ## Don't send the menu through the pager since doing that can cause
+  ## major confusion.
+
+  save_page_screen_output = page_screen_output ();
+
+  unwind_protect
+
+    page_screen_output (0);
+
+    if (! isempty (t))
+      disp (t);
+      printf ("\n");
+    endif
+
+    nopt = nargin - 1;
+
+    while (1)
+      for i = 1:nopt
+        printf ("  [%2d] ", i);
+        disp (varargin{i});
+      endfor
+      printf ("\n");
+      s = input ("pick a number, any number: ", "s");
+      eval (sprintf ("num = %s;", s), "num = [];");
+      if (! isscalar (num) || num < 1 || num > nopt)
+        printf ("\nerror: input invalid or out of range\n\n");
+      else
+        break;
+      endif
+    endwhile
+
+  unwind_protect_cleanup
+
+    page_screen_output (save_page_screen_output);
+
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/miscellaneous/mex.m b/scripts/miscellaneous/mex.m
new file mode 100644
index 0000000..68d158d
--- /dev/null
+++ b/scripts/miscellaneous/mex.m
@@ -0,0 +1,29 @@
+## Copyright (C) 2006, 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mex [options] file @dots{}
+## Compile source code written in C, C++, or Fortran, to a MEX file.
+## This is equivalent to @code{mkoctfile --mex [options] file}.
+## @seealso{mkoctfile}
+## @end deftypefn
+
+function mex (varargin)
+  args = {"--mex", varargin{:}};
+  mkoctfile (args{:});
+endfunction
diff --git a/scripts/miscellaneous/mexext.m b/scripts/miscellaneous/mexext.m
new file mode 100644
index 0000000..4a94680
--- /dev/null
+++ b/scripts/miscellaneous/mexext.m
@@ -0,0 +1,26 @@
+## Copyright (C) 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mexext ()
+## Return the filename extension used for MEX files.
+## @end deftypefn
+
+function retval = mexext ()
+  retval = "mex";
+endfunction
diff --git a/scripts/miscellaneous/mkoctfile.m b/scripts/miscellaneous/mkoctfile.m
new file mode 100644
index 0000000..7683ffd
--- /dev/null
+++ b/scripts/miscellaneous/mkoctfile.m
@@ -0,0 +1,144 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Keith Goodman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mkoctfile [-options] file @dots{}
+## 
+## The @code{mkoctfile} function compiles source code written in C,
+## C++, or Fortran.  Depending on the options used with @code{mkoctfile}, the
+## compiled code can be called within Octave or can be used as a stand-alone
+## application.
+##
+## @code{mkoctfile} can be called from the shell prompt or from the Octave
+## prompt.
+##
+## @code{mkoctfile} accepts the following options, all of which are optional
+## except for the file name of the code you wish to compile:
+##
+## @table @samp
+## @item -I DIR
+## Add the include directory DIR to compile commands.
+##
+## @item -D DEF
+## Add the definition DEF to the compiler call.
+##
+## @item -l LIB
+## Add the library LIB to the link command.
+##          
+## @item -L DIR
+## Add the library directory DIR to the link command.
+##
+## @item -M
+## @itemx --depend 
+## Generate dependency files (.d) for C and C++ source files.
+##          
+## @item -c
+## Compile but do not link.
+##
+## @item -g
+## Enable debugging options for compilers.
+##
+## @item -o FILE
+## @itemx --output FILE  
+## Output file name.  Default extension is .oct
+## (or .mex if --mex is specified) unless linking
+## a stand-alone executable.
+##
+## @item -p VAR
+## @itemx --print VAR
+## Print the configuration variable VAR.  Recognized variables are: 
+##
+## @example             
+## @group
+##    ALL_CFLAGS                FFTW_LIBS     
+##    ALL_CXXFLAGS              FLIBS       
+##    ALL_FFLAGS                FPICFLAG      
+##    ALL_LDFLAGS               INCFLAGS      
+##    BLAS_LIBS                 LDFLAGS             
+##    CC                        LD_CXX              
+##    CFLAGS                    LD_STATIC_FLAG
+##    CPICFLAG                  LFLAGS              
+##    CPPFLAGS                  LIBCRUFT      
+##    CXX                       LIBOCTAVE     
+##    CXXFLAGS                  LIBOCTINTERP  
+##    CXXPICFLAG                LIBREADLINE   
+##    DEPEND_EXTRA_SED_PATTERN  LIBS        
+##    DEPEND_FLAGS              OCTAVE_LIBS   
+##    DL_LD                     RDYNAMIC_FLAG 
+##    DL_LDFLAGS                RLD_FLAG      
+##    F2C                       SED         
+##    F2CFLAGS                  XTRA_CFLAGS   
+##    F77                       XTRA_CXXFLAGS 
+##    FFLAGS
+## @end group
+## @end example
+##
+## @item --link-stand-alone
+## Link a stand-alone executable file.
+##
+## @item --mex
+## Assume we are creating a MEX file.  Set the default output extension 
+## to ".mex".
+##
+## @item -s
+## @itemx --strip
+## Strip the output file.
+##
+## @item -v
+## @itemx --verbose
+## Echo commands as they are executed.
+##
+## @item file
+## The file to compile or link.  Recognized file types are
+##
+## @example
+## @group
+##                   .c    C source
+##                   .cc   C++ source
+##                   .C    C++ source
+##                   .cpp  C++ source
+##                   .f    Fortran source
+##                   .F    Fortran source
+##                   .o    object file
+## @end group
+## @end example
+##
+## @end table
+## @end deftypefn
+
+function mkoctfile (varargin)
+
+  bindir = octave_config_info ("bindir");
+
+  shell_script = fullfile (bindir, sprintf ("mkoctfile-%s", OCTAVE_VERSION));
+
+  cmd = cstrcat ("\"", shell_script, "\"");
+  for i = 1:nargin
+    cmd = cstrcat (cmd, " \"", varargin{i}, "\"");
+  endfor
+  
+  status = system (cmd);
+
+  if (status == 127)
+    warning ("unable to find mkoctfile in expected location: `%s'",
+	     shell_script);
+
+    warning ("mkoctfile exited with failure status");
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/movefile.m b/scripts/miscellaneous/movefile.m
new file mode 100644
index 0000000..3e9d4c4
--- /dev/null
+++ b/scripts/miscellaneous/movefile.m
@@ -0,0 +1,123 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@var{f1}, @var{f2})
+## Move the file @var{f1} to the new name @var{f2}.  The name @var{f1}
+## may contain globbing patterns.  If @var{f1} expands to multiple file
+## names, @var{f2} must be a directory.
+##
+## If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+## character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+## system-dependent error message, and @var{msgid} contains a unique\n\
+## message identifier.\n\
+## @seealso{glob}
+## @end deftypefn
+
+function [status, msg, msgid] = movefile (f1, f2, force)
+
+  max_cmd_line = 1024;
+  status = true;
+  msg = "";
+  msgid = "";
+
+  ## FIXME -- maybe use the same method as in ls to allow users control
+  ## over the command that is executed.
+
+  if (ispc () && ! isunix () && isempty (file_in_path (EXEC_PATH, "mv.exe")))
+    ## Windows.
+    cmd = "cmd /C move";
+    cmd_force_flag = "/Y";
+  else
+    cmd = "mv";
+    cmd_force_flag = "-f";
+  endif
+
+  if (nargin == 2 || nargin == 3)
+    ## Input type check.
+    if (! (ischar (f1) || iscellstr (f1)))
+      error ("movefile: first argument must be a character string or a cell array of character strings");
+    endif
+
+    if (! ischar (f2))
+      error ("movefile: second argument must be a character string");
+    endif
+
+    if (nargin == 3 && strcmp (force, "f"))
+      cmd = cstrcat (cmd, " ", cmd_force_flag);
+    endif
+
+    ## If f1 isn't a cellstr convert it to one.
+    if (ischar (f1))
+      f1 = cellstr (f1);
+    endif
+    
+    ## If f1 has more than 1 element f2 must be a directory
+    isdir = (exist (f2, "dir") != 0);
+    if (length(f1) > 1 && ! isdir)
+      error ("movefile: when moving multiple files, second argument must be a directory");
+    endif
+    
+    ## Protect the file name(s).
+    f1 = glob (f1);
+    if (isempty (f1))
+      error ("movefile: no files to move");
+    endif
+    p1 = sprintf ("\"%s\" ", f1{:});
+    p2 = tilde_expand (f2);
+
+    if (isdir && length(p1) > max_cmd_line)
+      l2 = length(p2) + length (cmd) + 6;
+      while (! isempty(f1))
+	p1 = sprintf ("\"%s\" ", f1{1});
+	f1(1) = [];
+	while (!isempty (f1) && (length(p1) + length(f1{1}) + l2 < 
+				 max_cmd_line))
+	  p1 = sprintf ("%s\"%s\" ", p1, f1{1});
+	  f1(1) = [];
+	endwhile 
+
+	if (ispc () && ! isunix () && ! isempty (file_in_path (EXEC_PATH, "cp.exe")))
+	  p1 = strrep (p1, "\\", "/");
+	  p2 = strrep (p2, "\\", "/");
+	endif
+
+	## Move the file(s).
+	[err, msg] = system (sprintf ("%s %s \"%s\"", cmd, p1, p2));
+	if (err < 0)
+	  status = false;
+	  msgid = "movefile";
+	endif
+      endwhile
+    else
+      if (ispc () && ! isunix () && ! isempty (file_in_path (EXEC_PATH, "cp.exe")))
+	p1 = strrep (p1, "\\", "/");
+	p2 = strrep (p2, "\\", "/");
+      endif
+
+      ## Move the file(s).
+      [err, msg] = system (sprintf ("%s %s \"%s\"", cmd, p1, p2));
+      if (err < 0)
+	status = false;
+	msgid = "movefile";
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
diff --git a/scripts/miscellaneous/namelengthmax.m b/scripts/miscellaneous/namelengthmax.m
new file mode 100644
index 0000000..778df6f
--- /dev/null
+++ b/scripts/miscellaneous/namelengthmax.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} namelengthmax ()
+## Returns the @sc{matlab} compatible maximum variable name length.  Octave is
+## capable of storing strings up to 
+## @tex
+## $2^{31} - 1$
+## @end tex
+## @ifnottex
+## @code{2 ^ 31 - 1}
+## @end ifnottex
+## in length.  However for @sc{matlab} compatibility all variable, function
+## and structure field names should be shorter than the length supplied by
+## @code{namelengthmax}.  In particular variables stored to a @sc{matlab} file
+## format will have their names truncated to this length.
+## @end deftypefn
+
+function n = namelengthmax ()
+  n = 63;
+endfunction
diff --git a/scripts/miscellaneous/news.m b/scripts/miscellaneous/news.m
new file mode 100644
index 0000000..15937a5
--- /dev/null
+++ b/scripts/miscellaneous/news.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} news ()
+## Display the current NEWS file for Octave.
+## @end deftypefn
+
+function news ()
+
+  octetcdir = octave_config_info ("octetcdir");
+  newsfile = fullfile (octetcdir, "NEWS");
+
+  if (exist (newsfile, "file"))
+    f = fopen (newsfile, "r");
+    while (ischar (line = fgets (f)))
+      puts (line);
+    endwhile
+  else
+    error ("news: unable to locate NEWS file");
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/orderfields.m b/scripts/miscellaneous/orderfields.m
new file mode 100644
index 0000000..44c5306
--- /dev/null
+++ b/scripts/miscellaneous/orderfields.m
@@ -0,0 +1,136 @@
+## Copyright (C) 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2})
+## Return a struct with fields arranged alphabetically or as specified
+## by @var{s2} and a corresponding permutation vector.
+##
+## Given one struct, arrange field names in @var{s1} alphabetically.
+##
+## Given two structs, arrange field names in @var{s1} as they appear
+## in @var{s2}.  The second argument may also specify the order in
+## a permutation vector or a cell array of strings.
+##
+## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+## Adapted-By: jwe
+
+function [t, p] = orderfields (s1, s2)
+
+  if (nargin == 1 || nargin == 2)
+    if (! isstruct (s1))
+      error ("orderfields: expecting argument to be a struct");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    ## One structure: return the fields in alphabetical order.
+    if (isstruct (s1))
+      names = sort (fieldnames (s1));
+    endif
+  elseif (nargin == 2)
+    if (isstruct (s2))
+      ## Two structures: return the fields in the order of s2.
+      names = fieldnames (s2);
+      if (! isequal (sort (fieldnames (s1)), sort (names)))
+	error ("orderfields: structures do not have same fields");
+      endif
+    elseif (iscellstr (s2))
+      ## A structure and a list of fields: order by the list of fields.
+      t1 = sort (fieldnames (s1));
+      t2 = sort (s2(:));
+      if (! isequal (t1, t2))
+	error ("orderfields: name list does not match structure fields");
+      endif
+      names = s2;
+    elseif (isvector (s2))
+      ## A structure and a permutation vector: permute the order of s1.
+      names = fieldnames (s1);
+      t1 = sort (s2);
+      t1 = t1(:)';
+      t2 = 1:numel (names);
+      if (! isequal (t1, t2))
+	error ("orderfields: invalid permutation vector");
+      endif
+      names = names (s2);
+    endif
+  endif
+
+  ## Find permutation vector which converts the original name order
+  ## into the new name order.  Note: could save a couple of sorts
+  ## in some cases, but performance isn't critical.
+
+  if (nargout == 2)
+    [oldel, oldidx] = sort (fieldnames (s1));
+    [newel, newidx] = sort (names);
+    p = oldidx(newidx);
+  endif
+
+  ## Permute the names in the structure.
+  if (numel (s1) == 0)
+    args = cell (1, 2 * numel (names));
+    args(1:2:end) = names;
+    args(2:2:end) = {[]};
+    t = struct (args{:});
+  else
+    n = numel (s1);
+    for i = 1:numel (names)
+      el = names(i);
+      [t(1:n).(el)] = s1(:).(el);
+    endfor
+    ## inherit dimensions
+    t = reshape (t, size (s1));
+  endif
+
+endfunction
+
+%!shared a, b, c
+%! a = struct ("foo", {1, 2}, "bar", {3, 4});
+%! b = struct ("bar", 6, "foo", 5);
+%! c = struct ("bar", {7, 8}, "foo", 9);
+%!test
+%! a(2) = orderfields (b, a);
+%! assert (a(2).foo, 5)
+%! assert (a(2).bar, 6)
+%!test
+%! a(2) = orderfields (b, [2 1]);
+%! assert (a(2).foo, 5)
+%! assert (a(2).bar, 6)
+%!test
+%! a(2) = orderfields (b, fieldnames (a));
+%! assert (a(2).foo, 5)
+%! assert (a(2).bar, 6)
+%!test
+%! a(1:2) = orderfields (c, fieldnames (a));
+%! assert (a(2).foo, 9)
+%! assert (a(2).bar, 8)
+
+%!test
+%! aa.x = {1, 2};
+%! aa.y = 3;
+%! aa(2).x = {4, 5};
+%! bb.y = {6, 7};
+%! bb.x = 8;
+%! aa(2) = orderfields (bb, aa);
+%! assert (aa(2).x, 8);
+%! assert (aa(2).y{1}, 6);
diff --git a/scripts/miscellaneous/pack.m b/scripts/miscellaneous/pack.m
new file mode 100644
index 0000000..7ee3a52
--- /dev/null
+++ b/scripts/miscellaneous/pack.m
@@ -0,0 +1,29 @@
+## Copyright (C) 1999, 2000, 2005, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pack ()
+## This function is provided for compatibility with @sc{matlab}, but it
+## doesn't actually do anything.
+## @end deftypefn
+
+## Author: jwe
+
+function pack ()
+
+endfunction
diff --git a/scripts/miscellaneous/paren.m b/scripts/miscellaneous/paren.m
new file mode 100644
index 0000000..8c91678
--- /dev/null
+++ b/scripts/miscellaneous/paren.m
@@ -0,0 +1,23 @@
+## Copyright (C) 1996, 1997, 2000, 2005, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deffn {Operator} (
+## @deffnx {Operator} )
+## Array index or function argument delimeter.
+## @end deffn
diff --git a/scripts/miscellaneous/parseparams.m b/scripts/miscellaneous/parseparams.m
new file mode 100644
index 0000000..192ae38
--- /dev/null
+++ b/scripts/miscellaneous/parseparams.m
@@ -0,0 +1,64 @@
+## Copyright (C) 2006, 2007 Alexander Barth
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{reg}, @var{prop}] =} parseparams (@var{params})
+## Return in @var{reg} the cell elements of @var{param} up to the first
+## string element and in @var{prop} all remaining elements beginning
+## with the first string element.  For example 
+##
+## @example
+## @group
+## [reg, prop] = parseparams (@{1, 2, "linewidth", 10@})
+## reg =
+## @{
+##   [1,1] = 1
+##   [1,2] = 2
+## @}
+## prop =
+## @{
+##   [1,1] = linewidth
+##   [1,2] = 10
+## @}
+## @end group
+## @end example
+##
+## The parseparams function may be used to separate 'regular'
+## arguments and additional arguments given as property/value pairs of
+## the @var{varargin} cell array.
+## @seealso{varargin}
+## @end deftypefn
+
+## Author: Alexander Barth <abarth93 at users.sourceforge.net>
+## Author: Aida Alvera Azcarate <aida at netecho.info>
+
+function [reg, prop] = parseparams (params)
+
+  i = 1;
+
+  while (i <= numel (params))
+    if (ischar (params{i}))
+      break;
+    endif
+    i++;
+  endwhile
+
+  reg = params(1:i-1);
+  prop = params(i:end);
+
+endfunction
diff --git a/scripts/miscellaneous/perl.m b/scripts/miscellaneous/perl.m
new file mode 100644
index 0000000..64e5970
--- /dev/null
+++ b/scripts/miscellaneous/perl.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2008, 2009 Julian Schnidder
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{output}, @var{status}] =} perl (@var{scriptfile})
+## @deftypefnx {Function File} {[@var{output}, @var{status}] =} perl (@var{scriptfile}, @var{argument1}, @var{argument2}, @dots{})
+## Invoke perl script @var{scriptfile} with possibly a list of
+## command line arguments.
+## Returns output in @var{output} and status
+## in @var{status}.
+## @seealso{system}
+## @end deftypefn
+
+function [output, status] = perl (script = "-e ''", varargin)
+
+  ## VARARGIN is intialized to {}(1x0) if no additional arguments are
+  ## supplied, so there is no need to check for it, or provide an
+  ## initial value in the argument list of the function definition.
+
+  if (ischar (script)
+      && ((nargin != 1 && iscellstr (varargin))
+	  || (nargin == 1 && ! isempty (script))))
+    [status, output] = system (cstrcat ("perl ", script,
+					sprintf (" %s", varargin{:})));
+  else
+    error ("perl: invalid arguments");
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/run.m b/scripts/miscellaneous/run.m
new file mode 100644
index 0000000..d2a9c3e
--- /dev/null
+++ b/scripts/miscellaneous/run.m
@@ -0,0 +1,58 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} run (@var{f})
+## @deftypefnx {Command} {} run @var{f}
+## Run scripts in the current workspace that are not necessarily on the
+## path.  If @var{f} is the script to run, including its path, then @code{run}
+## change the directory to the directory where @var{f} is found.  @code{run}
+## then executes the script, and returns to the original directory.
+## @seealso{system}
+## @end deftypefn
+
+function run (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [d, f, ext] = fileparts (s);
+  if (! isempty (d))
+    if (exist (d, "dir"))
+      wd = pwd ();
+      unwind_protect
+	cd (d);
+	if (! exist (f, "file") || ! strcmp (ext, ".m"))
+	  error ("run: file must exist and be a valid Octave script file");
+	endif
+	evalin ("caller", [f, ";"], "rethrow (lasterror ())");
+      unwind_protect_cleanup
+	cd (wd);
+      end_unwind_protect
+    else
+      error ("run: the path %s doesn't exist", d);
+    endif
+  else
+    if (exist (f, "file"))
+      evalin ("caller", [f, ";"], "rethrow (lasterror ())");
+    else
+      error ("run: %s not found", s);
+    endif
+  endif
+endfunction
diff --git a/scripts/miscellaneous/semicolon.m b/scripts/miscellaneous/semicolon.m
new file mode 100644
index 0000000..ace1003
--- /dev/null
+++ b/scripts/miscellaneous/semicolon.m
@@ -0,0 +1,24 @@
+## Copyright (C) 1995, 1996, 1997, 2000, 2004, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deffn {Operator} ;
+## Array row or command separator.
+## @seealso{comma}
+## @end deffn
diff --git a/scripts/miscellaneous/setfield.m b/scripts/miscellaneous/setfield.m
new file mode 100644
index 0000000..8f50ef5
--- /dev/null
+++ b/scripts/miscellaneous/setfield.m
@@ -0,0 +1,72 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Etienne Grossmann
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{k1}, @dots{}, @var{v1}] =} setfield (@var{s}, @var{k1}, @var{v1}, @dots{})
+## Set field members in a structure.
+##
+## @example
+## @group
+## oo(1,1).f0 = 1;
+## oo = setfield (oo, @{1,2@}, "fd", @{3@}, "b", 6);
+## oo(1,2).fd(3).b == 6
+## @result{} ans = 1
+## @end group
+## @end example
+##
+## Note that this function could be written
+##
+## @example
+## @group
+## i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4 = "b";
+## oo(i1@{:@}).(i2)(i3@{:@}).(i4) == 6;
+## @end group
+## @end example
+## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
+## @end deftypefn
+
+## Author:  Etienne Grossmann <etienne at cs.uky.edu>
+
+function obj = setfield (obj, varargin)
+   field = "obj";
+   for i = 1:nargin-2
+     v = varargin{i};
+     if (iscell (v))
+       sep = "(";
+       for j = 1:length (v)
+	 field = sprintf ("%s%s%s", field, sep, num2str (v{j}));
+         sep = ",";
+       endfor
+       field = sprintf ("%s)", field);
+     else
+       field = sprintf ("%s.%s", field, v);
+     endif
+   endfor
+   val = varargin{nargin-1};
+   eval (sprintf ("%s=val;", field));
+endfunction
+
+%!test
+%! x.a = "hello";
+%! x = setfield(x,"b","world");
+%! y = struct("a","hello","b","world");
+%! assert(x,y);
+%!test
+%! oo(1,1).f0= 1;
+%! oo = setfield(oo,{1,2},"fd",{3},"b", 6);
+%! assert (oo(1,2).fd(3).b, 6)
diff --git a/scripts/miscellaneous/substruct.m b/scripts/miscellaneous/substruct.m
new file mode 100644
index 0000000..f2f48d5
--- /dev/null
+++ b/scripts/miscellaneous/substruct.m
@@ -0,0 +1,80 @@
+## Copyright (C) 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} substruct (@var{type}, @var{subs}, @dots{})
+## Create a subscript structure for use with @code{subsref} or
+## @code{subsasgn}.
+## @seealso{subsref, subsasgn}
+## @end deftypefn
+
+## Author:  jwe
+
+function retval = substruct (varargin)
+
+  nargs = nargin;
+
+  if (nargs > 1 && mod (nargs, 2) == 0)
+    narg_pairs = nargs / 2;
+    typ = cell (1, narg_pairs);
+    sub = cell (1, narg_pairs);
+    k = 1;
+    for i = 1:2:nargs
+      t = varargin{i};
+      dot = false;
+      switch (t)
+	case { "()", "{}" }
+	case "."
+	  dot = true;
+	otherwise
+	  error ("substruct: expecting type to be one of \"()\", \"{}\", or \".\"");
+      endswitch
+      s = varargin{i+1};
+      if (dot)
+	if (! ischar (s))
+	  error ("substruct: for type == %s, subs must be a character string", t);
+	endif
+      elseif (! (iscell (s) || (ischar (s) && strcmp (s, ":"))))
+	error ("substruct: for type == %s, subs must be a cell array or \":\"",
+	       t);
+      endif
+      typ{k} = t;
+      sub{k} = s;
+      k++;
+    endfor
+    retval = struct ("type", typ, "subs", sub);
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! x(1,1).type = "()";
+%! x(1,2).type = "{}";
+%! x(1,3).type = ".";
+%! x(1,1).subs = {1,2,3};
+%! x(1,2).subs = ":";
+%! x(1,3).subs = "foo";
+%! y = substruct ("()", {1,2,3}, "{}", ":", ".", "foo");
+%! assert(x,y);
+%!error assert(substruct);
+%!error assert(substruct (1, 2, 3));
+%!error assert(substruct ("x", 1));
+%!error assert(substruct ("()", [1,2,3]));
+%!error assert(substruct (".", {1,2,3}));
diff --git a/scripts/miscellaneous/swapbytes.m b/scripts/miscellaneous/swapbytes.m
new file mode 100644
index 0000000..8062b00
--- /dev/null
+++ b/scripts/miscellaneous/swapbytes.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} swapbytes (@var{x})
+## Swaps the byte order on values, converting from little endian to big 
+## endian and vice versa.  For example
+##
+## @example
+## @group
+## swapbytes (uint16 (1:4))
+## @result{} [   256   512   768  1024]
+## @end group
+## @end example
+##
+## @seealso{typecast, cast}
+## @end deftypefn
+
+function y = swapbytes (x)
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  clx = class (x);
+  if (strcmp (clx, "int8") || strcmp (clx, "uint8") || isempty (x))
+    y = x;
+  else
+    if (strcmp (clx, "int16") || strcmp (clx, "uint16"))
+      nb = 2;
+    elseif (strcmp (clx, "int32") || strcmp (clx, "uint32"))
+      nb = 4;
+    elseif (strcmp (clx, "int64") || strcmp (clx, "uint64") ||
+	    strcmp (clx, "double"))
+      nb = 8;
+    else
+      error ("swapbytes: invalid class of object");
+    endif
+    y = reshape (typecast (reshape (typecast (x(:), "uint8"), nb, numel (x))
+			   ([nb : -1 : 1], :) (:), clx), size(x));
+  endif
+endfunction
diff --git a/scripts/miscellaneous/symvar.m b/scripts/miscellaneous/symvar.m
new file mode 100644
index 0000000..5db9751
--- /dev/null
+++ b/scripts/miscellaneous/symvar.m
@@ -0,0 +1,30 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} symvar (@var{s})
+## Identifies the argument names in the function defined by a string.
+## Common constant names such as @code{pi}, @code{NaN}, @code{Inf},
+## @code{eps}, @code{i} or @code{j} are ignored.  The arguments that are
+## found are returned in a cell array of strings.  If no variables are
+## found then the returned cell array is empty.
+## @end deftypefn
+
+function args = symvar (s)
+  args = argnames (inline (s));
+endfunction
diff --git a/scripts/miscellaneous/tar.m b/scripts/miscellaneous/tar.m
new file mode 100644
index 0000000..c969bd7
--- /dev/null
+++ b/scripts/miscellaneous/tar.m
@@ -0,0 +1,74 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Søren Hauberg
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{entries} =} tar (@var{tarfile}, @var{files}, @var{root})
+## Pack @var{files} @var{files} into the TAR archive @var{tarfile}.  The
+## list of files must be a string or a cell array of strings.
+##
+## The optional argument @var{root} changes the relative path of @var{files}
+## from the current directory.
+##
+## If an output argument is requested the entries in the archive are
+## returned in a cell array.
+## @seealso{untar, gzip, gunzip, zip, unzip}
+## @end deftypefn
+
+## Author: Søren Hauberg <hauberg at gmail.com>
+
+function entries = tar (tarfile, files, root)
+
+  if (nargin == 2 || nargin == 3)
+
+    if (nargin == 2)
+      root = ".";
+    endif
+
+    ## Test type of input
+    if (ischar (files))
+      files = cellstr (files);
+    endif
+
+    if (ischar (tarfile) && iscellstr (files) && ischar (root))
+
+      cmd = sprintf ("tar cvf %s -C %s %s", tarfile, root,
+		     sprintf (" %s", files{:}));
+
+      [status, output] = system (cmd);
+
+      if (status == 0)
+	if (nargout > 0)
+	  if (output(end) == "\n")
+	    output(end) = [];
+	  endif
+          entries = strsplit (output, "\n");
+	  entries = entries';
+	endif
+      else
+	error ("tar: tar exited with status = %d", status);
+      endif
+    
+    else
+      error ("tar: expecting all arguments to be character strings");
+    endif
+
+  else
+    print_usage("tar");
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/tempdir.m b/scripts/miscellaneous/tempdir.m
new file mode 100644
index 0000000..faa8713
--- /dev/null
+++ b/scripts/miscellaneous/tempdir.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{dir} =} tempdir ()
+## Return the name of the system's directory for temporary files.
+## @end deftypefn
+
+function dirname = tempdir ()
+
+  dirname = getenv ("TMPDIR");
+  if (isempty (dirname))
+    dirname = P_tmpdir;
+  endif
+
+  if (! strcmp (dirname(end), filesep))
+    cstrcat (dirname, filesep);
+  endif
+
+  if (! isdir (dirname))
+    warning ("tempdir: `%s' does not exist or is not a directory", dirname);
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/tempname.m b/scripts/miscellaneous/tempname.m
new file mode 100644
index 0000000..33e1926
--- /dev/null
+++ b/scripts/miscellaneous/tempname.m
@@ -0,0 +1,28 @@
+## Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {filename =} tempname ()
+## This function is an alias for @code{tmpnam}.
+## @end deftypefn
+
+function filename = tempname (varargin)
+
+  filename = tmpnam (varargin{:});
+
+endfunction
diff --git a/scripts/miscellaneous/texas_lotto.m b/scripts/miscellaneous/texas_lotto.m
new file mode 100644
index 0000000..5771981
--- /dev/null
+++ b/scripts/miscellaneous/texas_lotto.m
@@ -0,0 +1,55 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2004, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} texas_lotto ()
+## Pick 6 unique numbers between 1 and 50 that are guaranteed to win
+## the Texas Lotto.
+## @seealso{rand}
+## @end deftypefn
+
+## Author: jwe
+
+function picks = texas_lotto ()
+
+  if (nargin != 0)
+    warning ("texas_lotto: ignoring extra arguments");
+  endif
+
+  picks = zeros (1,6);
+  picks (1) = round (50-49*(1-rand));
+  n = 2;
+  while (n < 7)
+    tmp = round (50-49*(1-rand));
+    equal = 0;
+    for i = 1:n
+      if (tmp == picks (i))
+        equal = 1;
+        break;
+      endif
+    endfor
+    if (! equal)
+      picks (n) = tmp;
+      n++;
+    endif
+  endwhile
+
+  picks = sort (picks);
+
+endfunction
diff --git a/scripts/miscellaneous/unix.m b/scripts/miscellaneous/unix.m
new file mode 100644
index 0000000..344bf2c
--- /dev/null
+++ b/scripts/miscellaneous/unix.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{status}, @var{text}]} unix (@var{command})
+## @deftypefnx {Function File} {[@var{status}, @var{text}]} unix (@var{command}, "-echo")
+## Execute a system command if running under a Unix-like operating
+## system, otherwise do nothing.  Return the exit status of the program
+## in @var{status} and any output sent to the standard output in
+## @var{text}.  If the optional second argument @code{"-echo"} is given,
+## then also send the output from the command to the standard output.
+## @seealso{isunix, ispc, system}
+## @end deftypefn
+
+## Author: octave-forge ???
+## Adapted by: jwe
+
+function [status, text] = unix (cmd, echo_arg)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  elseif (isunix ())
+    [status, text] = system (cmd);
+    if (nargin > 1 || nargout == 0)
+      printf ("%s\n", text);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/unpack.m b/scripts/miscellaneous/unpack.m
new file mode 100644
index 0000000..ca494f8
--- /dev/null
+++ b/scripts/miscellaneous/unpack.m
@@ -0,0 +1,273 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Bill Denney
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{files} =} unpack (@var{file}, @var{dir})
+## @deftypefnx {Function File} {@var{files} =} unpack (@var{file}, @var{dir}, @var{filetype})
+## Unpack the archive @var{file} based on its extension to the directory
+## @var{dir}.  If @var{file} is a cellstr, then all files will be
+## handled individually.  If @var{dir} is not specified, it defaults to
+## the current directory.  It returns a list of @var{files}
+## unpacked.  If a directory is in the file list, then the
+## @var{filetype} to unpack must also be specified.
+##
+## The @var{files} includes the entire path to the output files.
+## @seealso{bunzip2, tar, untar, gzip, gunzip, zip, unzip}
+## @end deftypefn
+
+## Author: Bill Denney <denney at seas.upenn.edu>
+
+function filelist = unpack (file, directory, filetype)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    directory = ".";
+  endif
+  if (nargin < 3)
+    filetype = "";
+  endif
+
+  if (ischar (file))
+    if (isdir (file))
+      if (isempty (filetype))
+	error ("unpack: filetype must be given for a directory");
+      elseif (! any (strcmpi (filetype, "gunzip")))
+	error ("unpack: filetype must be gunzip for a directory");
+      endif
+    else
+      [pathstr, name, ext] = fileparts (file);
+
+      ## Check to see if it's .tar.gz, .tar.Z, etc.
+      if (any (strcmpi ({".gz" ".Z" ".bz2" ".bz"}, ext)))
+	[tmppathstr, tmpname, tmpext] = fileparts (name);
+	if (strcmpi (tmpext, ".tar"))
+	  name = tmpname;
+	  ext = cstrcat (tmpext, ext);
+	endif
+      endif
+
+      ## If the file is a url, download it and then work with that
+      ## file.
+      if (! isempty (strfind (file, "://")))
+	## FIXME -- the above is not a perfect test for a url
+	urlfile = file;
+	## FIXME -- should we name the file that we download with the
+	## same file name as the url requests?
+	tmpfile = cstrcat (tmpnam (), ext);
+	[file, success, msg] = urlwrite (urlfile, tmpfile);
+	if (! success)
+	  error ("unpack: could not get \"%s\": %s", urlfile, msg);
+	endif
+      endif
+
+    endif
+
+    ## canonicalize_file_name returns empty if the file isn't found, so
+    ## use that to check for existence
+    cfile = canonicalize_file_name (file);
+
+    if (isempty (cfile))
+      error ("unpack: file \"%s\" not found.", file);
+    else
+      file = cfile;
+    endif
+
+  elseif (iscellstr (file))
+    files = {};
+    for i = 1:numel (file)
+      tmpfiles = unpack (file{i}, directory);
+      files = {files{:} tmpfiles{:}};
+    endfor
+
+    ## Return output if requested.
+    if (nargout > 0)
+      filelist = files;
+    endif
+
+    return
+  else
+    error ("unpack: invalid input file class, %s", class(file));
+  endif
+
+  ## Instructions on what to do for any extension.
+  ##
+  ## The field names are the file extension without periods.
+  ## The first cell is what is executed to unpack an archive verbosely.
+  ## The second cell is what is executed to unpack an archive quietly.
+  ## The third cell is the function to execute on output to get the
+  ##   files list.
+  ## The fourth cell indicates if the files may need to be manually moved
+  ##   (i.e. tar and unzip decompress into the current directory while
+  ##   bzip2 and gzip decompress the file at its location).
+  persistent commandlist;
+  if (isempty (commandlist))
+    commandlist.gz = {"gzip -d -v -r \"%s\"", ...
+		      "gzip -d -r \"%s\"", ...
+		      @__parse_gzip__, true};
+    commandlist.z = commandlist.gz;
+    commandlist.bz2 = {"bzip2 -d -v \"%s\"", ...
+		       "bzip2 -d \"%s\"", ...
+		       @__parse_bzip2__, true};
+    commandlist.bz = commandlist.bz2;
+    commandlist.tar = {"tar xvf \"%s\"", ...
+		       "tar xf \"%s\"", ...
+		       @__parse_tar__, false};
+    commandlist.targz = {"gzip -d -c \"%s\" | tar xvf -", ...
+			 "gzip -d -c \"%s\" | tar xf -", ...
+			 @__parse_tar__, false};
+    commandlist.tgz = commandlist.targz;
+    commandlist.tarbz2 = {"bzip2 -d -c \"%s\" | tar xvf -", ...
+			  "bzip2 -d -c \"%s\" | tar xf -", ...
+			  @__parse_tar__, false};
+    commandlist.tarbz = commandlist.tarbz2;
+    commandlist.tbz2 = commandlist.tarbz2;
+    commandlist.tbz = commandlist.tarbz2;
+    commandlist.zip = {"unzip \"%s\"", ...
+		       "unzip -q \"%s\"", ...
+		       @__parse_zip__, false};
+  endif
+
+  nodotext = ext(! ismember (ext, "."));
+  
+  origdir = pwd ();
+
+  if (isfield (commandlist, nodotext))
+    [commandv, commandq, parser, move] = deal (commandlist.(nodotext){:});
+    cstartdir = canonicalize_file_name (origdir);
+    cenddir = canonicalize_file_name (directory);
+    needmove = move && ! strcmp (cstartdir, cenddir);
+    if (nargout > 0 || needmove)
+      command = commandv;
+    else
+      command = commandq;
+    endif
+  else
+    warning ("unpack:filetype", "unrecognised file type, %s", ext);
+    files = file;
+    return;
+  endif
+
+  ## Create the directory if necessary.
+  s = stat (directory);
+  if (isempty (s))
+    [status, msg] = mkdir (directory);
+    if (! status)
+      error ("unpack: mkdir failed to create %s: %s", directory, msg);
+    endif
+  elseif (! S_ISDIR (s.mode))
+    error ("unpack: %s: not a directory", directory);
+  endif
+
+  unwind_protect
+    cd (directory);
+    [status, output] = system (sprintf (cstrcat (command, " 2>&1"), file));
+  unwind_protect_cleanup
+    cd (origdir);
+  end_unwind_protect
+
+  if (status)
+    error ("unpack: unarchiving program exited with status: %d\n%s",
+	   status, output);
+  endif
+
+  if (nargout > 0 || needmove)
+    ## Trim the last cr if needed.
+    ## FIXME -- will this need to change to a check for "\r\n" for windows?
+    if (output(length (output)) == "\n")
+      output(length (output)) = [];
+    endif
+    files = parser (strsplit (output, "\n"))';
+
+    ## Move files if necessary
+    if (needmove)
+      [st, msg, msgid] = movefile (files, directory);
+      if (! st)
+	error ("unpack: unable to move files to \"%s\": %s",
+	       directory, msg);
+      endif
+
+      ## Fix the names for the files since they were moved.
+      for i = 1:numel (files)
+	files{i} = strrep (files{i}, cstartdir, cenddir);
+      endfor
+    endif
+
+    ## Return output if requested.
+    if (nargout > 0)
+      filelist = files;
+    endif
+  endif
+
+endfunction
+
+function files = __parse_zip__ (output)
+  ## Parse the output from zip and unzip.
+
+  for i = 1:length (output)
+    files{i} = output{i}(14:length(output{i}));
+  endfor
+endfunction
+
+function output = __parse_tar__ (output)
+  ## This is a noop, but it makes things simpler for other cases.
+endfunction
+
+function files = __parse_gzip__ (output)
+  ## Parse the output from gzip and gunzip returning the files
+  ## commpressed (or decompressed).
+
+  files = {};
+  ## The middle ": " should indicate a good place to start looking for
+  ## the filename.
+  for i = 1:length (output)
+    colons = strfind (output{i}, ":");
+    if (isempty (colons))
+      warning ("unpack:parsing",
+	       "Unable to parse line (gzip missing colon):\n%s", output{i});
+    else
+      midcolon = colons(ceil (length (colons)/2));
+      thisstr = output{i}(midcolon+2:length(output{i}));
+      idx = index (thisstr, "with") + 5;
+      if (isempty (idx))
+	warning ("unpack:parsing",
+		 "Unable to parse line (gzip missing with):\n%s", output{i});
+      else
+	files{i} = thisstr(idx:length (thisstr));
+      endif
+    endif
+  endfor
+endfunction
+
+function files = __parse_bzip2__ (output)
+  ## Parse the output from bzip2 and bunzip2 returning the files
+  ## commpressed (or decompressed).
+
+  files = {};
+  for i = 1:length (output)
+    ## the -5 is to remove the ".bz2:"
+    endoffilename = rindex (output{i}, ": ") - 5;
+    if (isempty (endoffilename))
+      warning ("unpack:parsing", "Unable to parse line:\n%s", output{i});
+    else
+      files{i} = output{i}(3:endoffilename);
+    endif
+  endfor
+endfunction
diff --git a/scripts/miscellaneous/untar.m b/scripts/miscellaneous/untar.m
new file mode 100644
index 0000000..bc2d565
--- /dev/null
+++ b/scripts/miscellaneous/untar.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2005, 2006, 2007, 2008 Søren Hauberg
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} untar (@var{tarfile}, @var{dir})
+## Unpack the TAR archive @var{tarfile} to the directory @var{dir}.
+## If @var{dir} is not specified, it defaults to the current directory.
+## @seealso{unpack, bunzip2, tar, gzip, gunzip, zip, unzip}
+## @end deftypefn
+
+## Author: Søren Hauberg <hauberg at gmail.com>
+## Adapted-By: jwe, Bill Denney
+
+function varargout = untar (files, outputdir)
+
+  if (! (nargin == 1 || nargin == 2))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    outputdir = ".";
+  endif
+
+  if (nargout > 0)
+    varargout = cell (1, nargout);
+    [varargout{:}] = unpack (files, outputdir, mfilename ());
+  else
+    unpack (files, outputdir, mfilename ());
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/unzip.m b/scripts/miscellaneous/unzip.m
new file mode 100644
index 0000000..573096c
--- /dev/null
+++ b/scripts/miscellaneous/unzip.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2005, 2006, 2007, 2008 Søren Hauberg
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unzip (@var{zipfile}, @var{dir})
+## Unpack the ZIP archive @var{zipfile} to the directory @var{dir}.
+## If @var{dir} is not specified, it defaults to the current directory.
+## @seealso{unpack, bunzip2, tar, untar, gzip, gunzip, zip}
+## @end deftypefn
+
+## Author: Søren Hauberg <hauberg at gmail.com>
+## Adapted-By: jwe, Bill Denney
+
+function varargout = unzip (files, outputdir)
+
+  if (! (nargin == 1 || nargin == 2))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    outputdir = ".";
+  endif
+
+  if (nargout > 0)
+    varargout = cell (1, nargout);
+    [varargout{:}] = unpack (files, outputdir, mfilename ());
+  else
+    unpack (files, outputdir, mfilename ());
+  endif
+
+endfunction
diff --git a/scripts/miscellaneous/ver.m b/scripts/miscellaneous/ver.m
new file mode 100644
index 0000000..a5cce84
--- /dev/null
+++ b/scripts/miscellaneous/ver.m
@@ -0,0 +1,126 @@
+## Copyright (C) 2005, 2006, 2007, 2008 William Poetra Yoga Hadisoeseno
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ver ()
+## Display a header containing the current Octave version
+## number, license string and operating system, followed by 
+## the installed package names, versions, and installation
+## directories.
+## @deftypefnx {Function File} {v =} ver ()
+## Return a vector of structures, respecting Octave and each installed package.
+## The structure includes the following fields.
+##
+## @table @code
+##   @item Name
+##   Package name.
+##   @item Version
+##   Version of the package.
+##   @item Revision
+##   Revision of the package.
+##   @item Date
+##   Date respecting the version/revision.
+## @end table
+## @deftypefnx {Function File} {v =} ver (@code{"Octave"})
+## Return version information for Octave only..
+## @deftypefnx {Function File} {v =} ver (@var{pkg})
+## Return version information for the specified package @var{pkg}.
+## @seealso{license, version}
+## @end deftypefn
+
+## Author: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function varargout = ver (pack)
+
+  if (nargin == 0)
+    pack = "";
+  endif
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  ## Start with the version info for Octave
+  ret = struct ("Name", "Octave", "Version", version,
+                "Release", [], "Date", []);
+
+  ## Add the installed packages
+  lst = pkg ("list");
+  for i = 1:length (lst)
+    ret(end+1) = struct ("Name", lst{i}.name, "Version", lst{i}.version,
+                         "Release", [], "Date", lst{i}.date);
+  endfor
+
+  if (nargout == 0)
+    octave_license = license ();
+
+    [unm, status] = uname ();
+
+    if (status < 0)
+      os_string = "unknown";
+    else
+      os_string = sprintf ("%s %s %s %s", unm.sysname, unm.release,
+                           unm.version, unm.machine);
+    endif
+
+    hbar(1:70) = "-";
+    ver_line1 = "GNU Octave Version ";
+    ver_line2 = "GNU Octave License: ";
+    ver_line3 = "Operating System: ";
+
+    ver_desc = sprintf ("%s\n%s%s\n%s%s\n%s%s\n%s\n", hbar, ver_line1, version,
+                        ver_line2, octave_license, ver_line3, os_string, hbar);
+
+    puts (ver_desc);
+
+    pkg ("list");
+  else
+    if (! isempty (pack))
+      n = [];
+      for r = 1:numel(ret)
+        if (strcmpi (ret(r).Name, pack))
+          n = r;
+          break;
+        endif
+      endfor
+      ret = ret(n);
+    endif
+    varargout{1} = ret;
+  endif
+
+endfunction
+
+%!test
+%! result = ver;
+%! assert (result(1).Name, "Octave")
+%! assert (result(1).Version, version)
+%! result = ver ("octave");
+%! assert (result(1).Name, "Octave")
+%! assert (result(1).Version, version)
+
+%!test
+%! lst = pkg ("list");
+%! for n=1:numel(lst)
+%!   expected = lst{n}.name;
+%!   result = ver (expected);
+%!   assert (result.Name, expected);
+%!   assert (isfield (result, "Version"), true);
+%!   assert (isfield (result, "Release"), true);
+%!   assert (isfield (result, "Date"), true);
+%! endfor
+
diff --git a/scripts/miscellaneous/version.m b/scripts/miscellaneous/version.m
new file mode 100644
index 0000000..8e34705
--- /dev/null
+++ b/scripts/miscellaneous/version.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2005, 2007, 2008,
+##               2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} version ()
+## Return Octave's version number as a string.  This is also the value of
+## the built-in variable @w{@code{OCTAVE_VERSION}}.
+## @end deftypefn
+
+## Author: jwe
+
+function vs = version ()
+
+  if (nargin != 0)
+    warning ("version: ignoring extra arguments");
+  endif
+
+  vs = OCTAVE_VERSION;
+
+endfunction
+
+%!assert(ischar (version ()) && strcmp (version (), OCTAVE_VERSION));
+
+%!warning version (1);
+
diff --git a/scripts/miscellaneous/warning_ids.m b/scripts/miscellaneous/warning_ids.m
new file mode 100644
index 0000000..3eade27
--- /dev/null
+++ b/scripts/miscellaneous/warning_ids.m
@@ -0,0 +1,251 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @table @code
+## @item Octave:array-to-scalar
+## If the @code{Octave:array-to-scalar} warning is enabled, Octave will
+## warn when an implicit conversion from an array to a scalar value is
+## attempted.  By default, the @code{Octave:array-to-scalar} warning is
+## disabled.
+## 
+## @item Octave:array-to-vector
+## If the @code{Octave:array-to-vector} warning is enabled, Octave will
+## warn when an implicit conversion from an array to a vector value is
+## attempted.  By default, the @code{Octave:array-to-vector} warning is
+## disabled.
+## 
+## @item Octave:assign-as-truth-value
+## If the @code{Octave:assign-as-truth-value} warning is
+## enabled, a warning is issued for statements like
+## 
+## @example
+## @group
+## if (s = t)
+##   @dots{}
+## @end group
+## @end example
+## 
+## @noindent
+## since such statements are not common, and it is likely that the intent
+## was to write
+## 
+## @example
+## @group
+## if (s == t)
+##   @dots{}
+## @end group
+## @end example
+## 
+## @noindent
+## instead.
+## 
+## There are times when it is useful to write code that contains
+## assignments within the condition of a @code{while} or @code{if}
+## statement.  For example, statements like
+## 
+## @example
+## @group
+## while (c = getc())
+##   @dots{}
+## @end group
+## @end example
+## 
+## @noindent
+## are common in C programming.
+## 
+## It is possible to avoid all warnings about such statements by
+## disabling the @code{Octave:assign-as-truth-value} warning,
+## but that may also let real errors like
+## 
+## @example
+## @group
+## if (x = 1)  # intended to test (x == 1)!
+##   @dots{}
+## @end group
+## @end example
+## 
+## @noindent
+## slip by.
+## 
+## In such cases, it is possible suppress errors for specific statements by
+## writing them with an extra set of parentheses.  For example, writing the
+## previous example as
+## 
+## @example
+## @group
+## while ((c = getc()))
+##   @dots{}
+## @end group
+## @end example
+## 
+## @noindent
+## will prevent the warning from being printed for this statement, while
+## allowing Octave to warn about other assignments used in conditional
+## contexts.
+## 
+## By default, the @code{Octave:assign-as-truth-value} warning is enabled.
+## 
+## @item Octave:associativity-change
+## If the @code{Octave:associativity-change} warning is
+## enabled, Octave will warn about possible changes in the meaning of
+## some code due to changes in associativity for some operators.
+## Associativity changes have typically been made for @sc{matlab}
+## compatibility.  By default, the @code{Octave:associativity-change}
+## warning is enabled.
+## 
+## @item Octave:divide-by-zero
+## If the @code{Octave:divide-by-zero} warning is enabled, a
+## warning is issued when Octave encounters a division by zero.  By
+## default, the @code{Octave:divide-by-zero} warning is enabled.
+## 
+## @item Octave:empty-list-elements
+## If the @code{Octave:empty-list-elements} warning is enabled, a
+## warning is issued when an empty matrix is found in a matrix list.
+## For example,
+## 
+## @example
+## a = [1, [], 3, [], 5]
+## @end example
+## 
+## @noindent
+## By default, the @code{Octave:empty-list-elements} warning is enabled.
+## 
+## @item Octave:fortran-indexing
+## If the @code{Octave:fortran-indexing} warning is enabled, a warning is
+## printed for expressions which select elements of a two-dimensional matrix
+## using a single index.  By default, the @code{Octave:fortran-indexing}
+## warning is disabled.
+## 
+## @item Octave:function-name-clash
+## If the @code{Octave:function-name-clash} warning is enabled, a
+## warning is issued when Octave finds that the name of a function
+## defined in a function file differs from the name of the file.  (If
+## the names disagree, the name declared inside the file is ignored.)
+## By default, the @code{Octave:function-name-clash} warning is enabled.
+## 
+## @item Octave:future-time-stamp
+## If the @code{Octave:future-time-stamp} warning is enabled, Octave
+## will print a warning if it finds a function file with a time stamp
+## that is in the future.  By default, the
+## @code{Octave:future-time-stamp} warning is enabled.
+## 
+## @item Octave:imag-to-real
+## If the @code{Octave:imag-to-real} warning is enabled, a warning is
+## printed for implicit conversions of complex numbers to real numbers.
+## By default, the @code{Octave:imag-to-real} warning is disabled.
+## 
+## @item Octave:matlab-incompatible
+## Print warnings for Octave language features that may cause
+## compatibility problems with @sc{matlab}.
+## 
+## @item Octave:missing-semicolon
+## If the @code{Octave:missing-semicolon} warning is enabled, Octave
+## will warn when statements in function definitions don't end in
+## semicolons.  By default the @code{Octave:missing-semicolon} warning
+## is disabled.
+## 
+## @item Octave:neg-dim-as-zero
+## If the @code{Octave:neg-dim-as-zero} warning is enabled, print a warning
+## for expressions like
+## 
+## @example
+## eye (-1)
+## @end example
+## 
+## @noindent
+## By default, the @code{Octave:neg-dim-as-zero} warning is disabled.
+## 
+## @item Octave:num-to-str
+## If the @code{Octave:num-to-str} warning is enable, a warning is
+## printed for implicit conversions of numbers to their ASCII character
+## equivalents when strings are constructed using a mixture of strings and
+## numbers in matrix notation.  For example,
+## 
+## @example
+## @group
+## [ "f", 111, 111 ]
+##      @result{} "foo"
+## @end group
+## @end example
+## elicits a warning if the @code{Octave:num-to-str} warning is
+## enabled.  By default, the @code{Octave:num-to-str} warning is enabled.
+## 
+## @item Octave:precedence-change
+## If the @code{Octave:precedence-change} warning is enabled, Octave
+## will warn about possible changes in the meaning of some code due to
+## changes in precedence for some operators.  Precedence changes have
+## typically been made for @sc{matlab} compatibility.  By default, the
+## @code{Octave:precedence-change} warning is enabled.
+## 
+## @item Octave:reload-forces-clear
+## If several functions have been loaded from the same file, Octave must
+## clear all the functions before any one of them can be reloaded.  If
+## the @code{Octave:reload-forces-clear} warning is enabled, Octave will
+## warn you when this happens, and print a list of the additional
+## functions that it is forced to clear.  By default, the
+## @code{Octave:reload-forces-clear} warning is enabled.
+## 
+## @item Octave:resize-on-range-error
+## If the @code{Octave:resize-on-range-error} warning is enabled, print a
+## warning when a matrix is resized by an indexed assignment with
+## indices outside the current bounds.  By default, the
+## @code{Octave:resize-on-range-error} warning is disabled.
+## 
+## @item Octave:separator-insert
+## Print warning if commas or semicolons might be inserted
+## automatically in literal matrices.
+## 
+## @item Octave:single-quote-string
+## Print warning if a single quote character is used to introduce a
+## string constant.
+## 
+## @item Octave:str-to-num
+## If the @code{Octave:str-to-num} warning is enabled, a warning is printed
+## for implicit conversions of strings to their numeric ASCII equivalents.
+## For example,
+## @example
+## @group
+## "abc" + 0
+##      @result{} 97 98 99
+## @end group
+## @end example
+## elicits a warning if the @code{Octave:str-to-num} warning is enabled.
+## By default, the @code{Octave:str-to-num} warning is disabled.
+## 
+## @item Octave:string-concat
+## If the @code{Octave:string-concat} warning is enabled, print a
+## warning when concatenating a mixture of double and single quoted strings.
+## By default, the @code{Octave:string-concat} warning is disabled.
+## 
+## @item Octave:undefined-return-values
+## If the @code{Octave:undefined-return-values} warning is disabled,
+## print a warning if a function does not define all the values in
+## the return list which are expected.  By default, the
+## @code{Octave:undefined-return-values} warning is enabled.
+## 
+## @item Octave:variable-switch-label
+## If the @code{Octave:variable-switch-label} warning is enabled, Octave
+## will print a warning if a switch label is not a constant or constant
+## expression.  By default, the @code{Octave:variable-switch-label}
+## warning is disabled.
+## @end table
+
+function warning_ids ()
+  help ("warning_ids");
+endfunction
diff --git a/scripts/miscellaneous/what.m b/scripts/miscellaneous/what.m
new file mode 100644
index 0000000..5058f05
--- /dev/null
+++ b/scripts/miscellaneous/what.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} {} what 
+## @deftypefnx {Command} {} what @var{dir}
+## @deftypefnx {Function File} {w =} what (@var{dir})
+## List the Octave specific files in a directory.  If the variable @var{dir}
+## is given then check that directory rather than the current directory.  If
+## a return argument is requested, the files found are returned in the 
+## structure @var{w}.
+## @seealso{which}
+## @end deftypefn
+
+function ret = what (d)
+
+  if (nargin == 0)
+    d = pwd ();
+  elseif (isempty (strfind (d, filesep ())))
+    ## Find the appropriate directory on the path.
+    p = strtrim (strsplit (path (), pathsep()));
+    d = p{find (cellfun (@(x) ! isempty (strfind (x, d)), p))(end)};
+  else
+    [status, msg, msgid] = fileattrib (d);
+    if (status != 1)
+      error ("could not find the file or path %s", d);
+    else
+      d = msg.Name;
+    endif
+  endif
+
+  files = dir (d);
+  w.path = d;
+  w.m = cell (0, 1);
+  w.mex = cell (0, 1);
+  w.oct = cell (0, 1);
+  w.mat = cell (0, 1);
+  w.mdl = cell (0, 1);
+  w.p = cell (0, 1);
+  w.classes = cell (0, 1);
+
+  for i = 1 : length (files)
+    n = files(i).name;
+    ## Ignore . and ..
+    if (strcmp (n, ".") || strcmp (n, ".."))
+      continue;
+    else
+      ## Ignore mdl and p files
+      [dummy, f, e] = fileparts (n);
+      if (strcmp (e, ".m"))
+	w.m{end+1} = n; 
+      elseif (strcmp (e, mexext ()))
+	w.mex{end+1} = n; 
+      elseif (strcmp (e, ".oct"))
+	w.oct{end+1} = n;
+      elseif (strcmp (e, ".mat"))
+	w.mat{end+1} = n; 
+      elseif(strcmp (n(1), "@"))
+	w.classes{end+1} = n;
+      endif
+    endif
+  endfor
+
+  if (nargout == 0)
+    __display_filenames__ ("M-files in directory", w.path, w.m);
+    __display_filenames__ ("\nMEX-files in directory", w.path, w.mex);
+    __display_filenames__ ("\nOCT-files in directory", w.path, w.oct);
+    __display_filenames__ ("\nMAT-files in directory", w.path, w.mat);
+    __display_filenames__ ("\nClasses in directory", w.path, w.classes);
+  else
+    ret = w;
+  endif
+endfunction
+
+function __display_filenames__ (msg, p, f)
+  if (length (f) > 0)
+    printf ("%s %s:\n\n", msg, p)
+  
+    maxlen = max (cellfun (@(x) length (x), f));
+    ncols = max (1, floor (terminal_size()(2) / (maxlen + 3)));
+    fmt = "";
+    for i = 1: ncols
+      fmt = sprintf ("%s   %%-%ds", fmt, maxlen);
+    endfor
+    fmt = [fmt, "\n"];
+
+    nrows = ceil (length (f) / ncols); 
+    for i = 1 : nrows
+      args  = f(i:nrows:end);
+      if (length (args) < ncols)
+        args(end : ncols) = {""};
+      endif
+      printf (fmt, args{:});
+    endfor
+  endif
+endfunction
diff --git a/scripts/miscellaneous/xor.m b/scripts/miscellaneous/xor.m
new file mode 100644
index 0000000..ad4321c
--- /dev/null
+++ b/scripts/miscellaneous/xor.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006, 2007, 2008
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} xor (@var{x}, @var{y})
+## Return the `exclusive or' of the entries of @var{x} and @var{y}.
+## For boolean expressions @var{x} and @var{y},
+## @code{xor (@var{x}, @var{y})} is true if and only if @var{x} or @var{y}
+## is true, but not if both @var{x} and @var{y} are true.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 16 September 1994
+## Adapted-By: jwe
+
+function z = xor (x, y)
+
+  if (nargin == 2)
+    if (isscalar (x) || isscalar (y) || size_equal (x, y))
+      z = logical ((x | y) - (x & y));
+    else
+      error ("xor: x and y must be of common size or scalars");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert((xor ([1, 1, 0, 0], [0, 1, 0, 1]) == [1, 0, 0, 1]
+%! && xor ([i, i, 0, 0], [1, 0, 1, 0]) == [0, 1, 1, 0]));
+
+%!assert(all (all (xor (eye (2), fliplr (eye (2))) == ones (2))));
+
+%!error xor ();
+
+%!error xor (1, 2, 3);
+
diff --git a/scripts/miscellaneous/zip.m b/scripts/miscellaneous/zip.m
new file mode 100644
index 0000000..9293eb8
--- /dev/null
+++ b/scripts/miscellaneous/zip.m
@@ -0,0 +1,76 @@
+## Copyright (C) 2006, 2007, 2009 Sylvain Pelissier
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files})
+## @deftypefnx {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files}, @var{rootdir})
+## Compress the list of files and/or directories specified in @var{files} 
+## into the archive @var{zipfiles} in the same directory.  If @var{rootdir} 
+## is defined the @var{files} is located relative to @var{rootdir} rather 
+## than the current directory
+## @seealso{unzip,tar}
+## @end deftypefn
+
+## Author: Sylvain Pelissier <sylvain.pelissier at gmail.com>
+
+function entries = zip (zipfile, files, rootdir)
+
+  if (nargin != 3)
+    rootdir = "./";
+  endif
+
+  if (nargin == 2 || nargin == 3)
+    rootdir = tilde_expand (rootdir);
+
+    if (ischar (files))
+      files = cellstr (files);
+    endif
+
+    if (ischar (zipfile) && iscellstr (files))
+
+      cmd = sprintf ("cd %s; zip -r %s/%s %s", rootdir, pwd (), zipfile,
+		     sprintf (" %s", files{:}));
+
+      [status, output] = system (cmd);
+
+      if (status == 0)
+	if (nargout > 0)
+	  cmd = sprintf ("unzip -Z -1 %s", zipfile);
+	  [status, entries] = system (cmd);
+	  if (status == 0)
+	    if (entries(end) == "\n")
+	      entries(end) = [];
+	    endif
+            entries = strsplit (entries, "\n");
+	  else
+	    error ("zip: zipinfo failed with exit status = %d", status);
+	  endif
+	endif
+      else
+	error ("zip: zip failed with exit status = %d", status);
+      endif
+    
+    else
+      error ("zip: expecting all arguments to be character strings");
+    endif
+
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/mkdoc b/scripts/mkdoc
new file mode 100755
index 0000000..153a31b
--- /dev/null
+++ b/scripts/mkdoc
@@ -0,0 +1,59 @@
+#! /bin/sh
+#
+# Copyright (C) 1999, 2002, 2005, 2007, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+set -e
+
+FIND=${FIND:-'find'}
+
+PERL=${PERL:-'perl'}
+
+if test $# -eq 1; then
+  d=$1
+elif test $# -eq 0; then
+  d=.
+else
+  echo "usage: mkdoc [directory]" 1>&2
+  exit 1
+fi
+
+if test -f gethelp; then
+  cat << EOF
+### DO NOT EDIT!
+###
+### This file is generated automatically from the Octave sources.
+### Edit those files instead and run make to update this file.
+
+EOF
+  $FIND $d -name '*.m' | \
+    $PERL -n -e 'chop;
+               $f = "$_";
+               m{(.*)/(.*)\.m};
+               for (qx{./gethelp $2 "$f" < "$f"}) {
+                 s/^\s+\@/\@/ unless $i_am_in_example;
+                 s/^\s+\@group/\@group/;
+                 s/^\s+\@end\s+group/\@end\s+group/;
+                 $i_am_in_example = 1 if /\s*\@example/;
+                 $i_am_in_example = 0 if /\s*\@end\s+example/;
+                 print;
+               }'
+else
+  echo "gethelp program seems to be missing!" 1>&2
+  exit 1
+fi
\ No newline at end of file
diff --git a/scripts/mkinstalldirs b/scripts/mkinstalldirs
new file mode 100755
index 0000000..2a66feb
--- /dev/null
+++ b/scripts/mkinstalldirs
@@ -0,0 +1,36 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at gnu.org>
+# Created: 1993-05-16
+# Last modified: Wed Jan 25 09:35:21 1995
+# Public domain
+
+errstatus=0
+
+dirmode=0755
+
+for file in ${1+"$@"} ; do 
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" || errstatus=$?
+        echo "chmod $dirmode $pathcomp" 1>&2
+        chmod $dirmode "$pathcomp" || errstatus=$?
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/scripts/mkpkgadd b/scripts/mkpkgadd
new file mode 100755
index 0000000..deb6eab
--- /dev/null
+++ b/scripts/mkpkgadd
@@ -0,0 +1,40 @@
+#! /bin/sh
+#
+# Copyright (C) 2002, 2003, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+if [ $# -eq 1 ]; then
+  dir="$1"
+else
+  echo "usage: mkpkgadd directory" 1>&2
+  exit 1
+fi
+
+cd $dir
+
+m_files=`ls *.m`
+cxx_files=`ls *.cc`
+
+if [ -n "$m_files" ]; then
+  sed -n 's/^[#%][#%]* *PKG_ADD: *//p' $m_files
+fi
+
+if [ -n "$cxx_files" ]; then
+  sed -n -e 's,^//* *PKG_ADD: *,,p' \
+         -e 's,^/\** *PKG_ADD: *\(.*\) \*/$,\1,p' $cxx_files
+fi
diff --git a/scripts/move-if-change b/scripts/move-if-change
new file mode 100755
index 0000000..008440c
--- /dev/null
+++ b/scripts/move-if-change
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Like mv $1 $2, but if the files are the same, just delete $1.
+# Status is 0 if $2 is changed, 1 otherwise.
+
+if test -r $2; then
+  if cmp $1 $2 > /dev/null; then
+    echo $2 is unchanged
+    rm -f $1
+  else
+    mv -f $1 $2
+  fi
+else
+  mv -f $1 $2
+fi
diff --git a/scripts/optimization/Makefile.in b/scripts/optimization/Makefile.in
new file mode 100644
index 0000000..9905ca2
--- /dev/null
+++ b/scripts/optimization/Makefile.in
@@ -0,0 +1,98 @@
+# Makefile for octave's scripts/optimization directory
+#
+# Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = optimization
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = \
+  fzero.m \
+  __fdjac__.m \
+  __dogleg__.m \
+  fsolve.m \
+  fminunc.m \
+  glpk.m \
+  glpkmex.m \
+  lsqnonneg.m \
+  optimset.m \
+  optimget.m \
+  __all_opts__.m \
+  qp.m \
+  sqp.m
+
+EXTRAS = glpktest1 glpktest2
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/optimization
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/optimization/__all_opts__.m b/scripts/optimization/__all_opts__.m
new file mode 100644
index 0000000..314cfa1
--- /dev/null
+++ b/scripts/optimization/__all_opts__.m
@@ -0,0 +1,67 @@
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{names} =} __all_opts__ (@dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Query all options from all known optimization functions and return a
+## list of possible values.
+
+function names = __all_opts__ (varargin)
+  
+  persistent saved_names = {};
+
+  ## do not clear this function
+  mlock ();
+
+  ## guard against recursive calls.
+  persistent recursive = false;
+
+  if (recursive)
+    names = {};
+  elseif (nargin == 0)
+    names = saved_names;
+  else
+    ## query all options from all known functions. These will call optimset,
+    ## which will in turn call us, but we won't answer.
+    recursive = true;
+    names = saved_names;
+    for i = 1:nargin
+      try
+        opts = optimset (varargin{i});
+        fn = fieldnames (opts).';
+        names = [names, fn];
+      catch
+        # throw the error as a warning.
+        warning (lasterr ());
+      end_try_catch
+    endfor
+    names = unique (names);
+    lnames = unique (tolower (names));
+    if (length (lnames) < length (names))
+      ## This is bad.
+      error ("__all_opts__: duplicate options with inconsistent case");
+    endif
+    saved_names = names;
+    recursive = false;
+  endif
+
+endfunction
+
diff --git a/scripts/optimization/__dogleg__.m b/scripts/optimization/__dogleg__.m
new file mode 100644
index 0000000..4767767
--- /dev/null
+++ b/scripts/optimization/__dogleg__.m
@@ -0,0 +1,81 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn{Function File} {@var{x}} = __dogleg__ (@var{r}, @var{b}, @var{x}, @var{d}, @var{delta}, @var{ismin})
+## Solve the double dogleg trust-region problem:
+## Minimize 
+## @example
+## norm(@var{r}*@var{x}- at var{b}) 
+## @end example
+## subject to the constraint 
+## @example
+## norm(@var{d}.*@var{x}) <= @var{delta} ,
+## @end example
+## x being a convex combination of the gauss-newton and scaled gradient.
+## If @var{ismin} is true (default false), minimizes instead
+## @example
+## norm(@var{r}*@var{x})^2-2*@var{b}'*@var{x} 
+## @end example
+## @end deftypefn
+
+
+## TODO: error checks
+## TODO: handle singularity, or leave it up to mldivide?
+
+function x = __dogleg__ (r, b, d, delta, ismin = false)
+  ## Get Gauss-Newton direction.
+  if (ismin)
+    g = b;
+    b = r' \ g;
+  endif
+  x = r \ b;
+  xn = norm (d .* x);
+  if (xn > delta)
+    ## GN is too big, get scaled gradient.
+    if (ismin)
+      s = g ./ d;
+    else
+      s = (r' * b) ./ d;
+    endif
+    sn = norm (s);
+    if (sn > 0)
+      ## Normalize and rescale.
+      s = (s / sn) ./ d;
+      ## Get the line minimizer in s direction.
+      tn = norm (r*s);
+      snm = (sn / tn) / tn;
+      if (snm < delta)
+	## Get the dogleg path minimizer.
+        bn = norm (b);
+        dxn = delta/xn; snmd = snm/delta;
+        t = (bn/sn) * (bn/xn) * snmd;
+        t -= dxn * snmd^2 - sqrt ((t-dxn)^2 + (1-dxn^2)*(1-snmd^2));
+        alpha = dxn*(1-snmd^2) / t;
+      else
+        alpha = 0;
+      endif
+    else
+      alpha = delta / xn;
+      snm = 0;
+    endif
+    ## Form the appropriate convex combination.
+    x = alpha * x + ((1-alpha) * min (snm, delta)) * s;
+  endif
+endfunction
+
diff --git a/scripts/optimization/__fdjac__.m b/scripts/optimization/__fdjac__.m
new file mode 100644
index 0000000..1130589
--- /dev/null
+++ b/scripts/optimization/__fdjac__.m
@@ -0,0 +1,48 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn{Function File} {} __fdjac__ (@var{fcn}, @var{x}, @var{fvec}, @var{err})
+## Undocumented internal function.
+## @end deftypefn
+
+function fjac = __fdjac__ (fcn, x, fvec, cdif, err = 0)
+  if (cdif)
+    err = (max (eps, err)) ^ (1/3);
+    h = max (abs (x), 1)*err; # FIXME?
+    fjac = zeros (length (fvec), numel (x));
+    for i = 1:numel (x)
+      x1 = x2 = x;
+      x1(i) += h(i);
+      x2(i) -= h(i);
+      fjac(:,i) = (fcn (x1)(:) - fcn (x2)(:)) / (x1(i) - x2(i));
+    endfor
+  else
+    err = sqrt (max (eps, err));
+    h = max (abs (x), 1)*err; # FIXME?
+    fjac = zeros (length (fvec), numel (x));
+    for i = 1:numel (x)
+      x1 = x;
+      x1(i) += h(i);
+      fjac(:,i) = (fcn (x1)(:) - fvec) / (x1(i) - x(i));
+    endfor
+  endif
+endfunction
+
+
+
diff --git a/scripts/optimization/fminunc.m b/scripts/optimization/fminunc.m
new file mode 100644
index 0000000..d1abbea
--- /dev/null
+++ b/scripts/optimization/fminunc.m
@@ -0,0 +1,347 @@
+## Copyright (C) 2008, 2009 VZLU Prague, a.s.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Author: Jaroslav Hajek <highegg at gmail.com>
+
+## -*- texinfo -*-
+## @deftypefn{Function File} {} fminunc (@var{fcn}, @var{x0}, @var{options})
+## @deftypefnx{Function File} {[@var{x}, @var{fvec}, @var{info}, @var{output}, @var{fjac}]} = fminunc (@var{fcn}, @dots{})
+## Solve a unconstrained optimization problem defined by the function @var{fcn}.
+## @var{fcn} should accepts a vector (array) defining the unknown variables,
+## and return the objective function value, optionally with gradient.
+## In other words, this function attempts to determine a vector @var{x} such 
+## that @code{@var{fcn} (@var{x})} is a local minimum.
+## @var{x0} determines a starting guess. The shape of @var{x0} is preserved
+## in all calls to @var{fcn}, but otherwise it is treated as a column vector.
+## @var{options} is a structure specifying additional options.
+## Currently, @code{fminunc} recognizes these options:
+## @code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
+## @code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"}, 
+## @code{"GradObj"}, @code{"FinDiffType"}.
+##
+## If @code{"GradObj"} is @code{"on"}, it specifies that @var{fcn},
+## called with 2 output arguments, also returns the Jacobian matrix
+## of right-hand sides at the requested point.  @code{"TolX"} specifies
+## the termination tolerance in the unknown variables, while 
+## @code{"TolFun"} is a tolerance for equations. Default is @code{1e-7}
+## for both @code{"TolX"} and @code{"TolFun"}.
+## 
+## For description of the other options, see @code{optimset}.
+##
+## On return, @var{fval} contains the value of the function @var{fcn}
+## evaluated at @var{x}, and @var{info} may be one of the following values:
+## 
+## @table @asis
+## @item 1
+## Converged to a solution point. Relative gradient error is less than specified
+## by TolFun.
+## @item 2
+## Last relative step size was less that TolX.
+## @item 3
+## Last relative decrease in func value was less than TolF. 
+## @item 0
+## Iteration limit exceeded.
+## @item -3
+## The trust region radius became excessively small. 
+## @end table
+##
+## Note: If you only have a single nonlinear equation of one variable, using 
+## @code{fminbnd} is usually a much better idea.
+## @seealso{fminbnd, optimset}
+## @end deftypefn
+
+## PKG_ADD: __all_opts__ ("fminunc");
+
+function [x, fval, info, output, grad, hess] = fminunc (fcn, x0, options = struct ())
+
+  ## Get default options if requested.
+  if (nargin == 1 && ischar (fcn) && strcmp (fcn, 'defaults'))
+    x = optimset ("MaxIter", 400, "MaxFunEvals", Inf, \
+    "GradObj", "off", "TolX", 1.5e-8, "TolFun", 1.5e-8,
+    "OutputFcn", [], "FunValCheck", "off",
+    "FinDiffType", "central");
+    return;
+  endif
+
+  if (nargin < 2 || nargin > 3 || ! ismatrix (x0))
+    print_usage ();
+  endif    
+
+  if (ischar (fcn))
+    fcn = str2func (fcn);
+  endif
+
+  xsiz = size (x0);
+  n = numel (x0);
+
+  has_grad = strcmpi (optimget (options, "GradObj", "off"), "on");
+  cdif = strcmpi (optimget (options, "FinDiffType", "central"), "central");
+  maxiter = optimget (options, "MaxIter", 400);
+  maxfev = optimget (options, "MaxFunEvals", Inf);
+  outfcn = optimget (options, "OutputFcn");
+
+  funvalchk = strcmpi (optimget (options, "FunValCheck", "off"), "on");
+
+  if (funvalchk)
+    ## Replace fcn with a guarded version.
+    fcn = @(x) guarded_eval (fcn, x);
+  endif
+
+  ## These defaults are rather stringent. I think that normally, user
+  ## prefers accuracy to performance.
+
+  macheps = eps (class (x0));
+
+  tolx = optimget (options, "TolX", sqrt (macheps));
+  tolf = optimget (options, "TolFun", sqrt (macheps));
+
+  factor = 100;
+  ## FIXME: TypicalX corresponds to user scaling (???)
+  autodg = true;
+
+  niter = 1;
+  nfev = 0;
+
+  x = x0(:);
+  info = 0;
+
+  ## Initial evaluation.
+  fval = fcn (reshape (x, xsiz));
+  n = length (x);
+
+  if (! isempty (outfcn))
+    optimvalues.iter = niter;
+    optimvalues.funccount = nfev;
+    optimvalues.fval = fval;
+    optimvalues.searchdirection = zeros (n, 1);
+    state = 'init';
+    stop = outfcn (x, optimvalues, state);
+    if (stop)
+      info = -1;
+      break;
+    endif
+  endif
+
+  nsuciter = 0;
+  lastratio = 0;
+
+  grad = [];
+
+  ## Outer loop.
+  while (niter < maxiter && nfev < maxfev && ! info)
+
+    grad0 = grad;
+
+    ## Calculate function value and gradient (possibly via FD).
+    if (has_grad)
+      [fval, grad] = fcn (reshape (x, xsiz));
+      grad = grad(:);
+      nfev ++;
+    else
+      grad = __fdjac__ (fcn, reshape (x, xsiz), fval, cdif)(:);
+      nfev += (1 + cdif) * length (x);
+    endif
+
+    if (niter == 1)
+      ## Initialize by identity matrix. 
+      hesr = eye (n);
+    else
+      ## Use the damped BFGS formula.
+      y = grad - grad0;
+      sBs = sumsq (w);
+      Bs = hesr'*w;
+      sy = y'*s;
+      if (sy >= 0.2*sBs)
+        theta = 1;
+      else
+        theta = 0.8*sBs / (sBs - sy);
+      endif
+      r = theta * y + (1-theta) * Bs;
+      hesr = cholupdate (hesr, r / sqrt (s'*r), "+");
+      [hesr, info] = cholupdate (hesr, Bs / sqrt (sBs), "-");
+      if (info)
+        hesr = eye (n);
+      endif
+    endif
+
+    ## Second derivatives approximate the hessian.
+    d2f = norm (hesr, 'columns').';
+    if (niter == 1)
+      dg = d2f;
+      xn = norm (dg .* x);
+      ## FIXME: something better?
+      delta = max (factor * xn, 1);
+    endif
+
+    ## FIXME: maybe fixed lower and upper bounds?
+    dg = max (0.1*dg, d2f);
+
+    ## FIXME -- why tolf*n*xn? If abs (e) ~ abs(x) * eps is a vector
+    ## of perturbations of x, then norm (hesr*e) <= eps*xn, i.e. by
+    ## tolf ~ eps we demand as much accuracy as we can expect.
+    if (norm (grad) <= tolf*n*xn)
+      info = 1;
+      break;
+    endif
+
+    suc = false;
+    decfac = 0.5;
+
+    ## Inner loop.
+    while (! suc && niter <= maxiter && nfev < maxfev && ! info)
+
+      s = - __dogleg__ (hesr, grad, dg, delta, true);
+
+      sn = norm (dg .* s);
+      if (niter == 1)
+        delta = min (delta, sn);
+      endif
+
+      fval1 = fcn (reshape (x + s, xsiz)) (:);
+      nfev ++;
+
+      if (fval1 < fval)
+        ## Scaled actual reduction.
+        actred =  (fval - fval1) / (abs (fval1) + abs (fval));
+      else
+        actred = -1;
+      endif
+
+      w = hesr*s;
+      ## Scaled predicted reduction, and ratio.
+      t = 1/2 * sumsq (w) + grad'*s;
+      if (t < 0)
+        prered = -t/(abs (fval) + abs (fval + t));
+        ratio = actred / prered;
+      else
+        prered = 0;
+        ratio = 0;
+      endif
+
+      ## Update delta.
+      if (ratio < min(max(0.1, 0.8*lastratio), 0.9))
+        delta *= decfac;
+        decfac ^= 1.4142;
+        if (delta <= 1e1*macheps*xn)
+          ## Trust region became uselessly small.
+          info = -3;
+          break;
+        endif
+      else
+        lastratio = ratio;
+        decfac = 0.5;
+        if (abs (1-ratio) <= 0.1)
+          delta = 1.4142*sn;
+        elseif (ratio >= 0.5)
+          delta = max (delta, 1.4142*sn);
+        endif
+      endif
+
+      if (ratio >= 1e-4)
+        ## Successful iteration.
+        x += s;
+        xn = norm (dg .* x);
+        fval = fval1;
+        nsuciter ++;
+        suc = true;
+      endif
+
+      niter ++;
+
+      ## FIXME: should outputfcn be only called after a successful iteration?
+      if (! isempty (outfcn))
+        optimvalues.iter = niter;
+        optimvalues.funccount = nfev;
+        optimvalues.fval = fval;
+        optimvalues.searchdirection = s;
+        state = 'iter';
+        stop = outfcn (x, optimvalues, state);
+        if (stop)
+          info = -1;
+          break;
+        endif
+      endif
+
+      ## Tests for termination conditions. A mysterious place, anything
+      ## can happen if you change something here...
+      
+      ## The rule of thumb (which I'm not sure M*b is quite following)
+      ## is that for a tolerance that depends on scaling, only 0 makes
+      ## sense as a default value. But 0 usually means uselessly long
+      ## iterations, so we need scaling-independent tolerances wherever
+      ## possible.
+
+      ## The following tests done only after successful step.
+      if (ratio >= 1e-4)
+        ## This one is classic. Note that we use scaled variables again,
+        ## but compare to scaled step, so nothing bad.
+        if (sn <= tolx*xn)
+          info = 2;
+          ## Again a classic one.
+        elseif (actred < tolf)
+          info = 3;
+        endif
+      endif
+
+    endwhile
+  endwhile
+
+  ## Restore original shapes.
+  x = reshape (x, xsiz);
+
+  output.iterations = niter;
+  output.successful = nsuciter;
+  output.funcCount = nfev;
+
+endfunction
+
+## An assistant function that evaluates a function handle and checks for
+## bad results.
+function [fx, gx] = guarded_eval (fun, x)
+  if (nargout > 1)
+    [fx, gx] = fun (x);
+  else
+    fx = fun (x);
+    gx = [];
+  endif
+
+  if (! (isreal (fx) && isreal (jx)))
+    error ("fminunc:notreal", "fminunc: non-real value encountered"); 
+  elseif (complexeqn && ! (isnumeric (fx) && isnumeric(jx)))
+    error ("fminunc:notnum", "fminunc: non-numeric value encountered");
+  elseif (any (isnan (fx(:))))
+    error ("fminunc:isnan", "fminunc: NaN value encountered"); 
+  endif
+endfunction
+
+%!function f = rosenb (x)
+%!  n = length (x);
+%!  f = sumsq (1 - x(1:n-1)) + 100 * sumsq (x(2:n) - x(1:n-1).^2);
+%!test
+%! [x, fval, info, out] = fminunc (@rosenb, [5, -5]);
+%! tol = 2e-5;
+%! assert (info > 0);
+%! assert (x, ones (1, 2), tol);
+%! assert (fval, 0, tol);
+%!test
+%! [x, fval, info, out] = fminunc (@rosenb, zeros (1, 4));
+%! tol = 2e-5;
+%! assert (info > 0);
+%! assert (x, ones (1, 4), tol);
+%! assert (fval, 0, tol);
+
diff --git a/scripts/optimization/fsolve.m b/scripts/optimization/fsolve.m
new file mode 100644
index 0000000..53162e5
--- /dev/null
+++ b/scripts/optimization/fsolve.m
@@ -0,0 +1,528 @@
+## Copyright (C) 2008, 2009 VZLU Prague, a.s.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Author: Jaroslav Hajek <highegg at gmail.com>
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} fsolve (@var{fcn}, @var{x0}, @var{options})
+## @deftypefnx {Function File} {[@var{x}, @var{fvec}, @var{info}, @var{output}, @var{fjac}]} = fsolve (@var{fcn}, @dots{})
+## Solve a system of nonlinear equations defined by the function @var{fcn}.
+## @var{fcn} should accepts a vector (array) defining the unknown variables,
+## and return a vector of left-hand sides of the equations.  Right-hand sides
+## are defined to be zeros.
+## In other words, this function attempts to determine a vector @var{x} such 
+## that @code{@var{fcn} (@var{x})} gives (approximately) all zeros.
+## @var{x0} determines a starting guess.  The shape of @var{x0} is preserved
+## in all calls to @var{fcn}, but otherwise it is treated as a column vector.
+## @var{options} is a structure specifying additional options.
+## Currently, @code{fsolve} recognizes these options:
+## @code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
+## @code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"}, 
+## @code{"Jacobian"}, @code{"Updating"} and @code{"ComplexEqn"}.
+##
+## If @code{"Jacobian"} is @code{"on"}, it specifies that @var{fcn},
+## called with 2 output arguments, also returns the Jacobian matrix
+## of right-hand sides at the requested point.  @code{"TolX"} specifies
+## the termination tolerance in the unknown variables, while 
+## @code{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
+## for both @code{"TolX"} and @code{"TolFun"}.
+## If @code{"Updating"} is "on", the function will attempt to use Broyden
+## updates to update the Jacobian, in order to reduce the amount of jacobian
+## calculations.
+## If your user function always calculates the Jacobian (regardless of number
+## of output arguments), this option provides no advantage and should be set to
+## false.
+## 
+## @code{"ComplexEqn"} is @code{"on"}, @code{fsolve} will attempt to solve
+## complex equations in complex variables, assuming that the equations possess a
+## complex derivative (i.e., are holomorphic).  If this is not what you want, 
+## should unpack the real and imaginary parts of the system to get a real
+## system.
+##
+## For description of the other options, see @code{optimset}.
+##
+## On return, @var{fval} contains the value of the function @var{fcn}
+## evaluated at @var{x}, and @var{info} may be one of the following values:
+## 
+## @table @asis
+## @item 1
+## Converged to a solution point.  Relative residual error is less than specified
+## by TolFun.
+## @item 2
+## Last relative step size was less that TolX.
+## @item 3
+## Last relative decrease in residual was less than TolF. 
+## @item 0
+## Iteration limit exceeded.
+## @item -3
+## The trust region radius became excessively small. 
+## @end table
+## 
+## Note: If you only have a single nonlinear equation of one variable, using 
+## @code{fzero} is usually a much better idea.
+## @seealso{fzero, optimset}
+##
+## Note about user-supplied jacobians:
+## As an inherent property of the algorithm, jacobian is always requested for a
+## solution vector whose residual vector is already known, and it is the last
+## accepted successful step.  Often this will be one of the last two calls, but
+## not always.  If the savings by reusing intermediate results from residual
+## calculation in jacobian calculation are significant, the best strategy is to
+## employ OutputFcn: After a vector is evaluated for residuals, if OutputFcn is
+## called with that vector, then the intermediate results should be saved for
+## future jacobian evaluation, and should be kept until a jacobian evaluation
+## is requested or until outputfcn is called with a different vector, in which
+## case they should be dropped in favor of this most recent vector.  A short
+## example how this can be achieved follows:
+##
+## @example
+## function [fvec, fjac] = user_func (x, optimvalues, state)
+## persistent sav = [], sav0 = [];
+## if (nargin == 1)
+##   ## evaluation call
+##   if (nargout == 1)
+##     sav0.x = x; # mark saved vector
+##     ## calculate fvec, save results to sav0.
+##   elseif (nargout == 2)
+##     ## calculate fjac using sav.
+##   endif
+## else
+##   ## outputfcn call.
+##   if (all (x == sav0.x))
+##     sav = sav0;
+##   endif
+##   ## maybe output iteration status, etc.
+## endif
+## endfunction
+##
+## ## @dots{}.
+## 
+## fsolve (@@user_func, x0, optimset ("OutputFcn", @@user_func, @dots{}))
+## @end example
+###
+## @end deftypefn
+
+## PKG_ADD: __all_opts__ ("fsolve");
+
+function [x, fvec, info, output, fjac] = fsolve (fcn, x0, options = struct ())
+
+  ## Get default options if requested.
+  if (nargin == 1 && ischar (fcn) && strcmp (fcn, 'defaults'))
+    x = optimset ("MaxIter", 400, "MaxFunEvals", Inf, \
+    "Jacobian", "off", "TolX", 1.5e-8, "TolFun", 1.5e-8,
+    "OutputFcn", [], "Updating", "on", "FunValCheck", "off",
+    "ComplexEqn", "off", "FinDiffType", "central");
+    return;
+  endif
+
+  if (nargin < 2 || nargin > 3 || ! ismatrix (x0))
+    print_usage ();
+  endif    
+
+  if (ischar (fcn))
+    fcn = str2func (fcn);
+  endif
+
+  xsiz = size (x0);
+  n = numel (x0);
+
+  has_jac = strcmpi (optimget (options, "Jacobian", "off"), "on");
+  cdif = strcmpi (optimget (options, "FinDiffType", "central"), "central");
+  maxiter = optimget (options, "MaxIter", 400);
+  maxfev = optimget (options, "MaxFunEvals", Inf);
+  outfcn = optimget (options, "OutputFcn");
+  updating = strcmpi (optimget (options, "Updating", "on"), "on");
+  complexeqn = strcmpi (optimget (options, "ComplexEqn", "off"), "on");
+
+  funvalchk = strcmpi (optimget (options, "FunValCheck", "off"), "on");
+
+  if (funvalchk)
+    ## Replace fcn with a guarded version.
+    fcn = @(x) guarded_eval (fcn, x, complexeqn);
+  endif
+
+  ## These defaults are rather stringent. I think that normally, user
+  ## prefers accuracy to performance.
+
+  macheps = eps (class (x0));
+
+  tolx = optimget (options, "TolX", sqrt (macheps));
+  tolf = optimget (options, "TolFun", sqrt (macheps));
+
+  factor = 100;
+
+  niter = 1;
+  nfev = 1;
+
+  x = x0(:);
+  info = 0;
+
+  ## Initial evaluation.
+  ## Handle arbitrary shapes of x and f and remember them.
+  fvec = fcn (reshape (x, xsiz));
+  fsiz = size (fvec);
+  fvec = fvec(:);
+  fn = norm (fvec);
+  m = length (fvec);
+  n = length (x);
+
+  if (! isempty (outfcn))
+    optimvalues.iter = niter;
+    optimvalues.funccount = nfev;
+    optimvalues.fval = fn;
+    optimvalues.searchdirection = zeros (n, 1);
+    state = 'init';
+    stop = outfcn (x, optimvalues, state);
+    if (stop)
+      info = -1;
+      break;
+    endif
+  endif
+
+  nsuciter = 0;
+
+  ## Outer loop.
+  while (niter < maxiter && nfev < maxfev && ! info)
+
+    ## Calculate function value and Jacobian (possibly via FD).
+    if (has_jac)
+      [fvec, fjac] = fcn (reshape (x, xsiz));
+      ## If the jacobian is sparse, disable Broyden updating.
+      if (issparse (fjac))
+        updating = false;
+      endif
+      fvec = fvec(:);
+      nfev ++;
+    else
+      fjac = __fdjac__ (fcn, reshape (x, xsiz), fvec, cdif);
+      nfev += (1 + cdif) * length (x);
+    endif
+
+    ## For square and overdetermined systems, we update a QR
+    ## factorization of the jacobian to avoid solving a full system in each
+    ## step. In this case, we pass a triangular matrix to __dogleg__.
+    useqr = updating && m >= n && n > 10;
+
+    if (useqr)
+      ## FIXME: Currently, pivoting is mostly useless because the \ operator
+      ## cannot exploit the resulting props of the triangular factor.
+      ## Unpivoted QR is significantly faster so it doesn't seem right to pivot
+      ## just to get invariance. Original MINPACK didn't pivot either, at least
+      ## when qr updating was used.
+      [q, r] = qr (fjac, 0);
+    endif
+
+    ## Get column norms, use them as scaling factors.
+    jcn = norm (fjac, 'columns').';
+    if (niter == 1)
+      dg = jcn;
+      dg(dg == 0) = 1;
+      xn = norm (dg .* x);
+      ## FIXME: something better?
+      delta = max (factor * xn, 1);
+    endif
+
+    ## Rescale adaptively.
+    ## FIXME: the original minpack used the following rescaling strategy:
+    ##   dg = max (dg, jcn);
+    ## but it seems not good if we start with a bad guess yielding jacobian
+    ## columns with large norms that later decrease, because the corresponding
+    ## variable will still be overscaled. So instead, we only give the old
+    ## scaling a small momentum, but do not honor it.
+
+    dg = max (0.1*dg, jcn);
+
+    ## It also seems that in the case of fast (and inhomogeneously) changing
+    ## jacobian, the Broyden updates are of little use, so maybe we could
+    ## skip them if a big disproportional change is expected. The question is,
+    ## of course, how to define the above terms :)
+
+    lastratio = 0;
+    nfail = 0;
+    nsuc = 0;
+    decfac = 0.5;
+
+    ## Inner loop.
+    while (niter <= maxiter && nfev < maxfev && ! info)
+
+      ## Get trust-region model (dogleg) minimizer.
+      if (useqr)
+        qtf = q'*fvec;
+        s = - __dogleg__ (r, qtf, dg, delta);
+        w = qtf + r * s;
+      else
+        s = - __dogleg__ (fjac, fvec, dg, delta);
+        w = fvec + fjac * s;
+      endif
+
+      sn = norm (dg .* s);
+      if (niter == 1)
+        delta = min (delta, sn);
+      endif
+
+      fvec1 = fcn (reshape (x + s, xsiz)) (:);
+      fn1 = norm (fvec1);
+      nfev ++;
+
+      if (fn1 < fn)
+        ## Scaled actual reduction.
+        actred = 1 - (fn1/fn)^2;
+      else
+        actred = -1;
+      endif
+
+      ## Scaled predicted reduction, and ratio.
+      t = norm (w);
+      if (t < fn)
+        prered = 1 - (t/fn)^2;
+        ratio = actred / prered;
+      else
+        prered = 0;
+        ratio = 0;
+      endif
+
+      ## Update delta.
+      if (ratio < min(max(0.1, 0.8*lastratio), 0.9))
+        nsuc = 0;
+        nfail ++;
+        delta *= decfac;
+        decfac ^= 1.4142;
+        if (delta <= 1e1*macheps*xn)
+          ## Trust region became uselessly small.
+          info = -3;
+          break;
+        endif
+      else
+        lastratio = ratio;
+        decfac = 0.5;
+        nfail = 0;
+        nsuc ++;
+        if (abs (1-ratio) <= 0.1)
+          delta = 1.4142*sn;
+        elseif (ratio >= 0.5 || nsuc > 1)
+          delta = max (delta, 1.4142*sn);
+        endif
+      endif
+
+      if (ratio >= 1e-4)
+        ## Successful iteration.
+        x += s;
+        xn = norm (dg .* x);
+        fvec = fvec1;
+        fn = fn1;
+        nsuciter ++;
+      endif
+
+      niter ++;
+
+      ## FIXME: should outputfcn be only called after a successful iteration?
+      if (! isempty (outfcn))
+        optimvalues.iter = niter;
+        optimvalues.funccount = nfev;
+        optimvalues.fval = fn;
+        optimvalues.searchdirection = s;
+        state = 'iter';
+        stop = outfcn (x, optimvalues, state);
+        if (stop)
+          info = -1;
+          break;
+        endif
+      endif
+
+      ## Tests for termination conditions. A mysterious place, anything
+      ## can happen if you change something here...
+      
+      ## The rule of thumb (which I'm not sure M*b is quite following)
+      ## is that for a tolerance that depends on scaling, only 0 makes
+      ## sense as a default value. But 0 usually means uselessly long
+      ## iterations, so we need scaling-independent tolerances wherever
+      ## possible.
+
+      ## FIXME -- why tolf*n*xn? If abs (e) ~ abs(x) * eps is a vector
+      ## of perturbations of x, then norm (fjac*e) <= eps*n*xn, i.e. by
+      ## tolf ~ eps we demand as much accuracy as we can expect.
+      if (fn <= tolf*n*xn)
+        info = 1;
+	## The following tests done only after successful step.
+      elseif (ratio >= 1e-4)
+        ## This one is classic. Note that we use scaled variables again,
+	## but compare to scaled step, so nothing bad.
+        if (sn <= tolx*xn)
+          info = 2;
+          ## Again a classic one. It seems weird to use the same tolf
+	  ## for two different tests, but that's what M*b manual appears
+	  ## to say.
+        elseif (actred < tolf)
+          info = 3;
+        endif
+      endif
+
+      ## Criterion for recalculating jacobian.
+      if (! updating || nfail == 2 || nsuciter < 2)
+        break;
+      endif
+
+      ## Compute the scaled Broyden update.
+      if (useqr)
+        u = (fvec1 - q*w) / sn; 
+        v = dg .* ((dg .* s) / sn);
+
+        ## Update the QR factorization.
+        [q, r] = qrupdate (q, r, u, v);
+      else
+        u = (fvec1 - w);
+        v = dg .* ((dg .* s) / sn);
+
+        ## update the jacobian
+        fjac += u * v';
+      endif
+    endwhile
+  endwhile
+
+  ## Restore original shapes.
+  x = reshape (x, xsiz);
+  fvec = reshape (fvec, fsiz);
+
+  output.iterations = niter;
+  output.successful = nsuciter;
+  output.funcCount = nfev;
+
+endfunction
+
+## An assistant function that evaluates a function handle and checks for
+## bad results.
+function [fx, jx] = guarded_eval (fun, x, complexeqn)
+  if (nargout > 1)
+    [fx, jx] = fun (x);
+  else
+    fx = fun (x);
+    jx = [];
+  endif
+
+  if (! complexeqn && ! (isreal (fx) && isreal (jx)))
+    error ("fsolve:notreal", "fsolve: non-real value encountered"); 
+  elseif (complexeqn && ! (isnumeric (fx) && isnumeric(jx)))
+    error ("fsolve:notnum", "fsolve: non-numeric value encountered");
+  elseif (any (isnan (fx(:))))
+    error ("fsolve:isnan", "fsolve: NaN value encountered"); 
+  endif
+endfunction
+
+%!function retval = f (p) 
+%!  x = p(1);
+%!  y = p(2);
+%!  z = p(3);
+%!  retval = zeros (3, 1);
+%!  retval(1) = sin(x) + y**2 + log(z) - 7;
+%!  retval(2) = 3*x + 2**y -z**3 + 1;
+%!  retval(3) = x + y + z - 5;
+%!test
+%! x_opt = [ 0.599054;
+%! 2.395931;
+%! 2.005014 ];
+%! tol = 1.0e-5;
+%! [x, fval, info] = fsolve (@f, [ 0.5; 2.0; 2.5 ]);
+%! assert (info > 0);
+%! assert (norm (x - x_opt, Inf) < tol);
+%! assert (norm (fval) < tol);
+
+%!function retval = f (p)
+%!  x = p(1);
+%!  y = p(2);
+%!  z = p(3);
+%!  w = p(4);
+%!  retval = zeros (4, 1);
+%!  retval(1) = 3*x + 4*y + exp (z + w) - 1.007;
+%!  retval(2) = 6*x - 4*y + exp (3*z + w) - 11;
+%!  retval(3) = x^4 - 4*y^2 + 6*z - 8*w - 20;
+%!  retval(4) = x^2 + 2*y^3 + z - w - 4;
+%!test
+%! x_opt = [ -0.767297326653401, 0.590671081117440, 1.47190018629642, -1.52719341133957 ];
+%! tol = 1.0e-5;
+%! [x, fval, info] = fsolve (@f, [-1, 1, 2, -1]);
+%! assert (info > 0);
+%! assert (norm (x - x_opt, Inf) < tol);
+%! assert (norm (fval) < tol);
+
+%!function retval = f (p) 
+%!  x = p(1);
+%!  y = p(2);
+%!  z = p(3);
+%!  retval = zeros (3, 1);
+%!  retval(1) = sin(x) + y**2 + log(z) - 7;
+%!  retval(2) = 3*x + 2**y -z**3 + 1;
+%!  retval(3) = x + y + z - 5;
+%!  retval(4) = x*x + y - z*log(z) - 1.36;
+%!test
+%! x_opt = [ 0.599054;
+%! 2.395931;
+%! 2.005014 ];
+%! tol = 1.0e-5;
+%! [x, fval, info] = fsolve (@f, [ 0.5; 2.0; 2.5 ]);
+%! assert (info > 0);
+%! assert (norm (x - x_opt, Inf) < tol);
+%! assert (norm (fval) < tol);
+
+%!function retval = f (p) 
+%!  x = p(1);
+%!  y = p(2);
+%!  z = p(3);
+%!  retval = zeros (3, 1);
+%!  retval(1) = sin(x) + y**2 + log(z) - 7;
+%!  retval(2) = 3*x + 2**y -z**3 + 1;
+%!  retval(3) = x + y + z - 5;
+%!test
+%! x_opt = [ 0.599054;
+%! 2.395931;
+%! 2.005014 ];
+%! tol = 1.0e-5;
+%! opt = optimset ("Updating", "qrp");
+%! [x, fval, info] = fsolve (@f, [ 0.5; 2.0; 2.5 ], opt);
+%! assert (info > 0);
+%! assert (norm (x - x_opt, Inf) < tol);
+%! assert (norm (fval) < tol);
+
+%!test
+%! b0 = 3;
+%! a0 = 0.2;
+%! x = 0:.5:5;
+%! noise = 1e-5 * sin (100*x);
+%! y = exp (-a0*x) + b0 + noise;
+%! c_opt = [a0, b0];
+%! tol = 1e-5;
+%! 
+%! [c, fval, info, output] =  fsolve (@(c) (exp(-c(1)*x) + c(2) - y), [0, 0]);
+%! assert (info > 0);
+%! assert (norm (c - c_opt, Inf) < tol);
+%! assert (norm (fval) < norm (noise));
+
+
+%!function y = cfun (x)
+%!  y(1) = (1+i)*x(1)^2 - (1-i)*x(2) - 2;
+%!  y(2) = sqrt (x(1)*x(2)) - (1-2i)*x(3) + (3-4i);
+%!  y(3) = x(1) * x(2) - x(3)^2 + (3+2i);
+
+%!test
+%! x_opt = [-1+i, 1-i, 2+i];
+%! x = [i, 1, 1+i];
+%! 
+%! [x, f, info] = fsolve (@cfun, x, optimset ("ComplexEqn", "on"));
+%! tol = 1e-5;
+%! assert (norm (f) < tol);
+%! assert (norm (x - x_opt, Inf) < tol);
+
diff --git a/scripts/optimization/fzero.m b/scripts/optimization/fzero.m
new file mode 100644
index 0000000..b649c1f
--- /dev/null
+++ b/scripts/optimization/fzero.m
@@ -0,0 +1,308 @@
+## Copyright (C) 2008, 2009 VZLU Prague, a.s.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Author: Jaroslav Hajek <highegg at gmail.com>
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{fval}, @var{info}, @var{output}] =} fzero (@var{fun}, @var{x0}, @var{options})
+## Find a zero point of a univariate function.  @var{fun} should be a function
+## handle or name.  @var{x0} specifies a starting point.  @var{options} is a
+## structure specifying additional options.  Currently, @code{fzero}
+## recognizes these options: @code{"FunValCheck"}, @code{"OutputFcn"},
+## @code{"TolX"}, @code{"MaxIter"}, @code{"MaxFunEvals"}. 
+## For description of these options, see @ref{doc-optimset,,optimset}.
+## 
+## On exit, the function returns @var{x}, the approximate zero point
+## and @var{fval}, the function value thereof.
+## @var{info} is an exit flag that can have these values:
+## @itemize
+## @item 1
+## The algorithm converged to a solution.
+## @item 0
+## Maximum number of iterations or function evaluations has been exhausted.
+## @item -1
+## The algorithm has been terminated from user output function.
+## @item -2 
+## A general unexpected error.
+## @item -3
+## A non-real value encountered.
+## @item -4
+## A NaN value encountered.
+## @end itemize
+## @seealso{optimset, fsolve} 
+## @end deftypefn
+
+## This is essentially the ACM algorithm 748: Enclosing Zeros of
+## Continuous Functions due to Alefeld, Potra and Shi, ACM Transactions
+## on Mathematical Software, Vol. 21, No. 3, September 1995. Although
+## the workflow should be the same, the structure of the algorithm has
+## been transformed non-trivially; instead of the authors' approach of
+## sequentially calling building blocks subprograms we implement here a
+## FSM version using one interior point determination and one bracketing
+## per iteration, thus reducing the number of temporary variables and
+## simplifying the algorithm structure. Further, this approach reduces
+## the need for external functions and error handling. The algorithm has
+## also been slightly modified.
+
+## PKG_ADD: __all_opts__ ("fzero");
+
+function [x, fval, info, output] = fzero (fun, x0, options = struct ())
+
+  ## Get default options if requested.
+  if (nargin == 1 && ischar (fun) && strcmp (fun, 'defaults'))
+    x = optimset ("MaxIter", Inf, "MaxFunEvals", Inf, "TolX", 0, \
+    "OutputFcn", [], "FunValCheck", "off");
+    return;
+  endif
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (ischar (fun))
+    fun = str2func (fun);
+  endif
+
+  ## TODO
+  ## displev = optimget (options, "Display", "notify");
+  funvalchk = strcmpi (optimget (options, "FunValCheck", "off"), "on");
+  outfcn = optimget (options, "OutputFcn");
+  tolx = optimget (options, "TolX", 0);
+  maxiter = optimget (options, "MaxIter", Inf);
+  maxfev = optimget (options, "MaxFunEvals", Inf);
+
+  persistent mu = 0.5;
+
+  if (funvalchk)
+    ## Replace fun with a guarded version.
+    fun = @(x) guarded_eval (fun, x);
+  endif
+
+  ## The default exit flag if exceeded number of iterations.
+  info = 0;
+  niter = 0;
+  nfev = 0;
+
+  x = fval = a = fa = b = fb = NaN;
+
+  ## Prepare...
+  a = x0(1);
+  fa = fun (a); 
+  nfev = 1;
+  if (length (x0) > 1)
+    b = x0(2);
+    fb = fun (b);
+    nfev += 1;
+  else
+    ## Try to get b.
+    if (a == 0)
+      aa = 1;
+    else
+      aa = a;
+    endif
+    for b = [0.9*aa, 1.1*aa, aa-1, aa+1, 0.5*aa 1.5*aa, -aa, 2*aa, -10*aa, 10*aa]
+      fb = fun (b); nfev += 1;
+      if (sign (fa) * sign (fb) <= 0)
+        break;
+      endif
+    endfor
+  endif
+
+  if (b < a)
+    u = a;
+    a = b;
+    b = u;
+ 
+    fu = fa;
+    fa = fb;
+    fb = fu;
+  endif
+
+  if (! (sign (fa) * sign (fb) <= 0))
+    error ("fzero:bracket", "fzero: not a valid initial bracketing");
+  endif
+
+  itype = 1;
+
+  if (abs (fa) < abs (fb))
+    u = a; fu = fa;
+  else
+    u = b; fu = fb;
+  endif
+
+  d = e = u;
+  fd = fe = fu;
+  mba = mu*(b - a);
+  while (niter < maxiter && nfev < maxfev)
+    switch (itype)
+    case 1
+      ## The initial test.
+      if (b - a <= 2*(2 * abs (u) * eps + tolx))
+        x = u; fval = fu;
+        info = 1;
+        break;
+      endif
+      if (abs (fa) <= 1e3*abs (fb) && abs (fb) <= 1e3*abs (fa))
+        ## Secant step.
+        c = u - (a - b) / (fa - fb) * fu;
+      else
+        ## Bisection step.
+        c = 0.5*(a + b);
+      endif
+      d = u; fd = fu;
+      itype = 5;
+    case {2, 3}
+      l = length (unique ([fa, fb, fd, fe]));
+      if (l == 4)
+        ## Inverse cubic interpolation.
+        q11 = (d - e) * fd / (fe - fd);
+        q21 = (b - d) * fb / (fd - fb);
+        q31 = (a - b) * fa / (fb - fa);
+        d21 = (b - d) * fd / (fd - fb);
+        d31 = (a - b) * fb / (fb - fa);
+        q22 = (d21 - q11) * fb / (fe - fb);
+        q32 = (d31 - q21) * fa / (fd - fa);
+        d32 = (d31 - q21) * fd / (fd - fa);
+        q33 = (d32 - q22) * fa / (fe - fa);
+        c = a + q31 + q32 + q33;
+      endif
+      if (l < 4 || sign (c - a) * sign (c - b) > 0)
+        ## Quadratic interpolation + newton.
+        a0 = fa;
+        a1 = (fb - fa)/(b - a);
+        a2 = ((fd - fb)/(d - b) - a1) / (d - a);
+        ## Modification 1: this is simpler and does not seem to be worse.
+        c = a - a0/a1;
+        if (a2 != 0)
+          c = a - a0/a1;
+          for i = 1:itype
+            pc = a0 + (a1 + a2*(c - b))*(c - a);
+            pdc = a1 + a2*(2*c - a - b);
+            if (pdc == 0)
+              c = a - a0/a1;
+              break;
+            endif
+            c -= pc/pdc;
+          endfor
+        endif
+      endif
+      itype += 1; 
+    case 4
+      ## Double secant step.
+      c = u - 2*(b - a)/(fb - fa)*fu;
+      ## Bisect if too far.
+      if (abs (c - u) > 0.5*(b - a))
+        c = 0.5 * (b + a);
+      endif
+      itype = 5;
+    case 5
+      ## Bisection step.
+      c = 0.5 * (b + a);
+      itype = 2;
+    endswitch
+
+    ## Don't let c come too close to a or b.
+    delta = 2*0.7*(2 * abs (u) * eps + tolx);
+    if ((b - a) <= 2*delta)
+      c = (a + b)/2;
+    else
+      c = max (a + delta, min (b - delta, c));
+    endif
+
+    ## Calculate new point.
+    x = c;
+    fval = fc = fun (c); 
+    niter ++; nfev ++;
+
+    ## Modification 2: skip inverse cubic interpolation if
+    ## nonmonotonicity is detected.
+    if (sign (fc - fa) * sign (fc - fb) >= 0)
+      ## The new point broke monotonicity. 
+      ## Disable inverse cubic.
+      fe = fc;
+    else
+      e = d; fe = fd;
+    endif
+
+    ## Bracketing.
+    if (sign (fa) * sign (fc) < 0)
+      d = b; fd = fb;
+      b = c; fb = fc;
+    elseif (sign (fb) * sign (fc) < 0)
+      d = a; fd = fa;
+      a = c; fa = fc;
+    elseif (fc == 0)
+      a = b = c; fa = fb = fc;
+      info = 1;
+      break;
+    else
+      ## This should never happen.
+      error ("fzero:bracket", "fzero: zero point is not bracketed");
+    endif
+
+    ## If there's an output function, use it now.
+    if (outfcn)
+      optv.funccount = niter + 2;
+      optv.fval = fval;
+      optv.iteration = niter;
+      if (outfcn (x, optv, "iter"))
+        info = -1;
+        break;
+      endif
+    endif
+
+    if (abs (fa) < abs (fb))
+      u = a; fu = fa;
+    else
+      u = b; fu = fb;
+    endif
+    if (b - a <= 2*(2 * abs (u) * eps + tolx))
+      info = 1;
+      break;
+    endif
+
+    ## Skip bisection step if successful reduction.
+    if (itype == 5 && (b - a) <= mba)
+      itype = 2;
+    endif
+    if (itype == 2)
+      mba = mu * (b - a);
+    endif
+  endwhile
+
+  output.iterations = niter;
+  output.funcCount = niter + 2;
+  output.bracket = [a, b];
+  output.bracketf = [fa, fb];
+
+endfunction
+
+## An assistant function that evaluates a function handle and checks for
+## bad results.
+function fx = guarded_eval (fun, x)
+  fx = fun (x);
+  fx = fx(1);
+  if (! isreal (fx))
+    error ("fzero:notreal", "fzero: non-real value encountered"); 
+  elseif (isnan (fx))
+    error ("fzero:isnan", "fzero: NaN value encountered"); 
+  endif
+endfunction
+
+%!assert(fzero(@cos, [0, 3]), pi/2, 10*eps)
+%!assert(fzero(@(x) x^(1/3) - 1e-8, [0,1]), 1e-24, 1e-22*eps)
diff --git a/scripts/optimization/glpk.m b/scripts/optimization/glpk.m
new file mode 100644
index 0000000..3e011fb
--- /dev/null
+++ b/scripts/optimization/glpk.m
@@ -0,0 +1,552 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Nicolo' Giorgetti
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{status}, @var{extra}] =} glpk (@var{c}, @var{a}, @var{b}, @var{lb}, @var{ub}, @var{ctype}, @var{vartype}, @var{sense}, @var{param})
+## Solve a linear program using the GNU GLPK library.  Given three
+## arguments, @code{glpk} solves the following standard LP:
+## 
+## @tex
+## $$
+##   \min_x C^T x
+## $$
+## @end tex
+## @ifnottex
+## @example
+## min C'*x
+## @end example
+## @end ifnottex
+## 
+## subject to
+## 
+## @tex
+## $$
+##   Ax = b \qquad x \geq 0
+## $$
+## @end tex
+## @ifnottex
+## @example
+## @group
+## A*x  = b
+##   x >= 0
+## @end group
+## @end example
+## @end ifnottex
+## 
+## but may also solve problems of the form
+## 
+## @tex
+## $$
+##   [ \min_x | \max_x ] C^T x
+## $$
+## @end tex
+## @ifnottex
+## @example
+## [ min | max ] C'*x
+## @end example
+## @end ifnottex
+## 
+## subject to
+## 
+## @tex
+## $$
+##  Ax [ = | \leq | \geq ] b \qquad LB \leq x \leq UB
+## $$
+## @end tex
+## @ifnottex
+## @example
+## @group
+## A*x [ "=" | "<=" | ">=" ] b
+##   x >= LB
+##   x <= UB
+## @end group
+## @end example
+## @end ifnottex
+## 
+## Input arguments:
+## 
+## @table @var
+## @item c
+## A column array containing the objective function coefficients.
+## 
+## @item a
+## A matrix containing the constraints coefficients.
+## 
+## @item b
+## A column array containing the right-hand side value for each constraint
+## in the constraint matrix.
+## 
+## @item lb
+## An array containing the lower bound on each of the variables.  If
+## @var{lb} is not supplied, the default lower bound for the variables is
+## zero.
+## 
+## @item ub
+## An array containing the upper bound on each of the variables.  If
+## @var{ub} is not supplied, the default upper bound is assumed to be
+## infinite.
+## 
+## @item ctype
+## An array of characters containing the sense of each constraint in the
+## constraint matrix.  Each element of the array may be one of the
+## following values
+## @table @code
+## @item "F"
+## A free (unbounded) constraint (the constraint is ignored).
+## @item "U"
+## An inequality constraint with an upper bound (@code{A(i,:)*x <= b(i)}).
+## @item "S"
+## An equality constraint (@code{A(i,:)*x = b(i)}).
+## @item "L"
+## An inequality with a lower bound (@code{A(i,:)*x >= b(i)}).
+## @item "D"
+## An inequality constraint with both upper and lower bounds
+## (@code{A(i,:)*x >= -b(i)} @emph{and} (@code{A(i,:)*x <= b(i)}).
+## @end table
+## 
+## @item vartype
+## A column array containing the types of the variables.
+## @table @code
+## @item "C"
+## A continuous variable.
+## @item "I"
+## An integer variable.
+## @end table
+## 
+## @item sense
+## If @var{sense} is 1, the problem is a minimization.  If @var{sense} is
+## -1, the problem is a maximization.  The default value is 1.
+## 
+## @item param
+## A structure containing the following parameters used to define the
+## behavior of solver.  Missing elements in the structure take on default
+## values, so you only need to set the elements that you wish to change
+## from the default.
+## 
+## Integer parameters:
+## 
+## @table @code
+## @item msglev (@code{LPX_K_MSGLEV}, default: 1)
+## Level of messages output by solver routines:
+## @table @asis
+## @item 0
+## No output.
+## @item 1
+## Error messages only.
+## @item 2
+## Normal output .
+## @item 3
+## Full output (includes informational messages).
+## @end table
+## 
+## @item scale (@code{LPX_K_SCALE}, default: 1)
+## Scaling option: 
+## @table @asis
+## @item 0
+## No scaling.
+## @item 1
+## Equilibration scaling.
+## @item 2
+## Geometric mean scaling, then equilibration scaling.
+## @end table
+## 
+## @item dual	 (@code{LPX_K_DUAL}, default: 0)
+## Dual simplex option:
+## @table @asis
+## @item 0
+## Do not use the dual simplex.
+## @item 1
+## If initial basic solution is dual feasible, use the dual simplex.
+## @end table
+## 
+## @item price	 (@code{LPX_K_PRICE}, default: 1)
+## Pricing option (for both primal and dual simplex):
+## @table @asis
+## @item 0
+## Textbook pricing.
+## @item 1
+## Steepest edge pricing.
+## @end table
+##   
+## @item round	 (@code{LPX_K_ROUND}, default: 0)
+## Solution rounding option:
+## @table @asis
+## @item 0
+## Report all primal and dual values "as is".
+## @item 1
+## Replace tiny primal and dual values by exact zero.
+## @end table
+## 
+## @item itlim	 (@code{LPX_K_ITLIM}, default: -1)
+## Simplex iterations limit.  If this value is positive, it is decreased by
+## one each time when one simplex iteration has been performed, and
+## reaching zero value signals the solver to stop the search.  Negative
+## value means no iterations limit.
+## 
+## @item itcnt (@code{LPX_K_OUTFRQ}, default: 200)
+## Output frequency, in iterations.  This parameter specifies how
+## frequently the solver sends information about the solution to the
+## standard output.
+## 
+## @item branch (@code{LPX_K_BRANCH}, default: 2)
+## Branching heuristic option (for MIP only):
+## @table @asis
+## @item 0
+## Branch on the first variable.
+## @item 1
+## Branch on the last variable.
+## @item 2
+## Branch using a heuristic by Driebeck and Tomlin.
+## @end table
+## 
+## @item btrack (@code{LPX_K_BTRACK}, default: 2)
+## Backtracking heuristic option (for MIP only):
+## @table @asis
+## @item 0
+## Depth first search.
+## @item 1
+## Breadth first search.
+## @item 2
+## Backtrack using the best projection heuristic.
+## @end table        
+## 
+## @item presol (@code{LPX_K_PRESOL}, default: 1)
+## If this flag is set, the routine lpx_simplex solves the problem using
+## the built-in LP presolver.  Otherwise the LP presolver is not used.
+## 
+## @item lpsolver (default: 1)
+## Select which solver to use.  If the problem is a MIP problem this flag
+## will be ignored.
+## @table @asis
+## @item 1
+## Revised simplex method.
+## @item 2
+## Interior point method.
+## @end table
+## @item save (default: 0)
+## If this parameter is nonzero, save a copy of the problem in
+## CPLEX LP format to the file @file{"outpb.lp"}.  There is currently no
+## way to change the name of the output file.
+## @end table
+## 
+## Real parameters:
+## 
+## @table @code
+## @item relax (@code{LPX_K_RELAX}, default: 0.07)
+## Relaxation parameter used in the ratio test.  If it is zero, the textbook
+## ratio test is used.  If it is non-zero (should be positive), Harris'
+## two-pass ratio test is used.  In the latter case on the first pass of the
+## ratio test basic variables (in the case of primal simplex) or reduced
+## costs of non-basic variables (in the case of dual simplex) are allowed
+## to slightly violate their bounds, but not more than
+## @code{relax*tolbnd} or @code{relax*toldj (thus, @code{relax} is a
+## percentage of @code{tolbnd} or @code{toldj}}.
+## 
+## @item tolbnd (@code{LPX_K_TOLBND}, default: 10e-7)
+## Relative tolerance used to check if the current basic solution is primal
+## feasible.  It is not recommended that you change this parameter unless you
+## have a detailed understanding of its purpose.
+## 
+## @item toldj (@code{LPX_K_TOLDJ}, default: 10e-7)
+## Absolute tolerance used to check if the current basic solution is dual
+## feasible.  It is not recommended that you change this parameter unless you
+## have a detailed understanding of its purpose.
+## 
+## @item tolpiv (@code{LPX_K_TOLPIV}, default: 10e-9)
+## Relative tolerance used to choose eligible pivotal elements of the
+## simplex table.  It is not recommended that you change this parameter unless you
+## have a detailed understanding of its purpose.
+## 
+## @item objll (@code{LPX_K_OBJLL}, default: -DBL_MAX)
+## Lower limit of the objective function.  If on the phase II the objective
+## function reaches this limit and continues decreasing, the solver stops
+## the search.  This parameter is used in the dual simplex method only.
+## 
+## @item objul (@code{LPX_K_OBJUL}, default: +DBL_MAX)
+## Upper limit of the objective function.  If on the phase II the objective
+## function reaches this limit and continues increasing, the solver stops
+## the search.  This parameter is used in the dual simplex only.
+## 
+## @item tmlim (@code{LPX_K_TMLIM}, default: -1.0)
+## Searching time limit, in seconds.  If this value is positive, it is
+## decreased each time when one simplex iteration has been performed by the
+## amount of time spent for the iteration, and reaching zero value signals
+## the solver to stop the search.  Negative value means no time limit.
+## 
+## @item outdly (@code{LPX_K_OUTDLY}, default: 0.0)
+## Output delay, in seconds.  This parameter specifies how long the solver
+## should delay sending information about the solution to the standard
+## output.  Non-positive value means no delay.
+## 
+## @item tolint (@code{LPX_K_TOLINT}, default: 10e-5)
+## Relative tolerance used to check if the current basic solution is integer
+## feasible.  It is not recommended that you change this parameter unless
+## you have a detailed understanding of its purpose.
+## 
+## @item tolobj (@code{LPX_K_TOLOBJ}, default: 10e-7)
+## Relative tolerance used to check if the value of the objective function
+## is not better than in the best known integer feasible solution.  It is
+## not recommended that you change this parameter unless you have a
+## detailed understanding of its purpose.
+## @end table
+## @end table
+## 
+## Output values:
+## 
+## @table @var
+## @item xopt
+## The optimizer (the value of the decision variables at the optimum).
+## @item fopt
+## The optimum value of the objective function.
+## @item status
+## Status of the optimization.
+## 
+## Simplex Method:
+## @table @asis
+## @item 180 (@code{LPX_OPT})
+## Solution is optimal.
+## @item 181 (@code{LPX_FEAS})
+## Solution is feasible.
+## @item 182 (@code{LPX_INFEAS})
+## Solution is infeasible.
+## @item 183 (@code{LPX_NOFEAS})
+## Problem has no feasible solution.
+## @item 184 (@code{LPX_UNBND})
+## Problem has no unbounded solution.
+## @item 185 (@code{LPX_UNDEF})
+## Solution status is undefined.
+## @end table
+## Interior Point Method:
+## @table @asis
+## @item 150 (@code{LPX_T_UNDEF})
+## The interior point method is undefined.
+## @item 151 (@code{LPX_T_OPT})
+## The interior point method is optimal.
+## @end table
+## Mixed Integer Method:
+## @table @asis
+## @item 170 (@code{LPX_I_UNDEF})
+## The status is undefined.
+## @item 171 (@code{LPX_I_OPT})
+## The solution is integer optimal.
+## @item 172 (@code{LPX_I_FEAS})
+## Solution integer feasible but its optimality has not been proven
+## @item 173 (@code{LPX_I_NOFEAS})
+## No integer feasible solution.
+## @end table
+## @noindent
+## If an error occurs, @var{status} will contain one of the following
+## codes:
+##
+## @table @asis
+## @item 204 (@code{LPX_E_FAULT})
+## Unable to start the search.
+## @item 205 (@code{LPX_E_OBJLL})
+## Objective function lower limit reached.
+## @item 206 (@code{LPX_E_OBJUL})
+## Objective function upper limit reached.
+## @item 207 (@code{LPX_E_ITLIM})
+## Iterations limit exhausted.
+## @item 208 (@code{LPX_E_TMLIM})
+## Time limit exhausted.
+## @item 209 (@code{LPX_E_NOFEAS})
+## No feasible solution.
+## @item 210 (@code{LPX_E_INSTAB})
+## Numerical instability.
+## @item 211 (@code{LPX_E_SING})
+## Problems with basis matrix.
+## @item 212 (@code{LPX_E_NOCONV})
+## No convergence (interior).
+## @item 213 (@code{LPX_E_NOPFS})
+## No primal feasible solution (LP presolver).
+## @item 214 (@code{LPX_E_NODFS})
+## No dual feasible solution (LP presolver).
+## @end table
+## @item extra
+## A data structure containing the following fields:
+## @table @code
+## @item lambda
+## Dual variables.
+## @item redcosts
+## Reduced Costs.
+## @item time
+## Time (in seconds) used for solving LP/MIP problem.
+## @item mem
+## Memory (in bytes) used for solving LP/MIP problem (this is not 
+## available if the version of GLPK is 4.15 or later).
+## @end table
+## @end table
+## 
+## Example:
+## 
+## @example
+## @group
+## c = [10, 6, 4]';
+## a = [ 1, 1, 1;
+##      10, 4, 5;
+##       2, 2, 6];
+## b = [100, 600, 300]';
+## lb = [0, 0, 0]';
+## ub = [];
+## ctype = "UUU";
+## vartype = "CCC";
+## s = -1;
+## 
+## param.msglev = 1;
+## param.itlim = 100;
+## 
+## [xmin, fmin, status, extra] = @dots{}
+##    glpk (c, a, b, lb, ub, ctype, vartype, s, param);
+## @end group
+## @end example
+## @end deftypefn
+
+## Author: Nicolo' Giorgetti <giorgetti at dii.unisi.it>
+## Adapted-by: jwe
+
+function [xopt, fmin, status, extra] = glpk (c, a, b, lb, ub, ctype, vartype, sense, param)
+
+  ## If there is no input output the version and syntax
+  if (nargin < 3 || nargin > 9)
+    print_usage ();
+    return;
+  endif
+
+  if (all (size (c) > 1) || iscomplex (c) || ischar (c))
+    error ("C must be a real vector");
+    return;
+  endif
+  nx = length (c);
+  ## Force column vector.
+  c = c(:);
+
+  ## 2) Matrix constraint
+
+  if (isempty (a))
+    error ("A cannot be an empty matrix");
+    return;
+  endif
+  [nc, nxa] = size(a);
+  if (! isreal (a) || nxa != nx)
+    error ("A must be a real valued %d by %d matrix", nc, nx);
+    return;
+  endif
+
+  ## 3) RHS
+
+  if (isempty (b))
+    error ("B cannot be an empty vector");
+    return;
+  endif
+  if (! isreal (b) || length (b) != nc)
+    error ("B must be a real valued %d by 1 vector", nc);
+    return;
+  endif
+
+  ## 4) Vector with the lower bound of each variable
+
+  if (nargin > 3)
+    if (isempty (lb))
+      lb = zeros (nx, 1);
+    elseif (! isreal (lb) || all (size (lb) > 1) || length (lb) != nx)
+      error ("LB must be a real valued %d by 1 column vector", nx);
+      return;
+    endif
+  else
+    lb = zeros (nx, 1);
+  endif
+
+  ## 5) Vector with the upper bound of each variable
+
+  if (nargin > 4)
+    if (isempty (ub))
+      ub = repmat (Inf, nx, 1);
+    elseif (! isreal (ub) || all (size (ub) > 1) || length (ub) != nx)
+      error ("UB must be a real valued %d by 1 column vector", nx);
+      return;
+    endif
+  else
+    ub = repmat (Inf, nx, 1);
+  endif
+
+  ## 6) Sense of each constraint
+
+  if (nargin > 5)
+    if (isempty (ctype))
+      ctype = repmat ("S", nc, 1);
+    elseif (! ischar (ctype) || all (size (ctype) > 1) || length (ctype) != nc)
+      error ("CTYPE must be a char valued vector of length %d", nc);
+      return;
+    elseif (! all (ctype == "F" | ctype == "U" | ctype == "S"
+		   | ctype == "L" | ctype == "D"))
+      error ("CTYPE must contain only F, U, S, L, or D");
+      return;
+    endif
+  else
+    ctype = repmat ("S", nc, 1);
+  endif
+
+  ## 7) Vector with the type of variables
+
+  if (nargin > 6)
+    if (isempty (vartype))
+      vartype = repmat ("C", nx, 1);
+    elseif (! ischar (vartype) || all (size (vartype) > 1)
+	    || length (vartype) != nx)
+      error ("VARTYPE must be a char valued vector of length %d", nx);
+      return;
+    elseif (! all (vartype == "C" | vartype == "I"))
+      error ("VARTYPE must contain only C or I");
+      return;
+    endif
+  else
+    ## As default we consider continuous vars
+    vartype = repmat ("C", nx, 1);
+  endif
+
+  ## 8) Sense of optimization
+
+  if (nargin > 7)
+    if (isempty (sense))
+      sense = 1;
+    elseif (ischar (sense) || all (size (sense) > 1) || ! isreal (sense))
+      error ("SENSE must be an integer value");
+    elseif (sense >= 0)
+      sense = 1;
+    else
+      sense = -1;
+    endif
+  else
+    sense = 1;
+  endif
+
+  ## 9) Parameters vector
+
+  if (nargin > 8)
+    if (! isstruct (param))
+      error ("PARAM must be a structure");
+      return;
+    endif
+  else
+    param = struct ();
+  endif
+
+  [xopt, fmin, status, extra] = ...
+    __glpk__ (c, a, b, lb, ub, ctype, vartype, sense, param);
+
+endfunction
diff --git a/scripts/optimization/glpkmex.m b/scripts/optimization/glpkmex.m
new file mode 100644
index 0000000..3872b6d
--- /dev/null
+++ b/scripts/optimization/glpkmex.m
@@ -0,0 +1,109 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Nicolo' Giorgetti
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{status}, @var{extra}] =} glpkmex (@var{sense}, @var{c}, @var{a}, @var{b}, @var{ctype}, @var{lb}, @var{ub}, @var{vartype}, @var{param}, @var{lpsolver}, @var{save_pb})
+## This function is provided for compatibility with the old @sc{matlab}
+## interface to the GNU GLPK library.  For Octave code, you should use
+## the @code{glpk} function instead.
+## @end deftypefn
+
+function [xopt, fopt, status, extra] = glpkmex (varargin)
+
+  ## If there is no input output the version and syntax
+  if (nargin < 4 || nargin > 11)
+    print_usage ();
+    return;
+  endif
+
+  ## reorder args:
+  ##
+  ##     glpkmex    glpk
+  ##
+  ##  1   sense      c
+  ##  2   c          a
+  ##  3   a          b
+  ##  4   b          lb
+  ##  5   ctype      ub
+  ##  6   lb         ctype
+  ##  7   ub         vartype
+  ##  8   vartype    sense
+  ##  9   param      param
+  ## 10   lpsolver
+  ## 11   savepb
+
+  sense = varargin{1};
+  c = varargin{2};
+  a = varargin{3};
+  b = varargin{4};
+
+  nx = length  (c);
+
+  if (nargin > 4)
+    ctype = varargin{5};
+  else
+    ctype = repmat ("U", nx, 1);
+  endif
+
+  if (nargin > 5)
+    lb = varargin{6};
+  else
+    lb = repmat (-Inf, nx, 1);
+  endif
+
+  if (nargin > 6)
+    ub = varargin{7};
+  else
+    ub = repmat (Inf, nx, 1);
+  endif
+
+  if (nargin > 7)
+    vartype = varargin{8};
+  else
+    vartype = repmat ("C", nx, 1);
+  endif
+
+  if (nargin > 8)
+    param = varargin{9};
+  else
+    param = struct ();
+  endif
+
+  if (nargin > 9 && ! isfield (param, "lpsolver"))
+    param.lpsolver = varargin{10};
+  endif
+
+  if (nargin > 10 && ! isfield (param, "save"))
+    param.save = varargin{11};
+  endif
+
+  if (nargout == 0)
+    glpk (c, a, b, lb, ub, ctype, vartype, sense, param);
+  elseif (nargout == 1)
+    xopt = glpk (c, a, b, lb, ub, ctype, vartype, sense, param);
+  elseif (nargout == 2)
+    [xopt, fopt] = glpk (c, a, b, lb, ub, ctype, vartype, sense, param);
+  elseif (nargout == 3)
+    [xopt, fopt, status] = ...
+      glpk (c, a, b, lb, ub, ctype, vartype, sense, param);
+  else
+    [xopt, fopt, status, extra] = ...
+      glpk (c, a, b, lb, ub, ctype, vartype, sense, param);
+  endif
+
+endfunction
diff --git a/scripts/optimization/lsqnonneg.m b/scripts/optimization/lsqnonneg.m
new file mode 100644
index 0000000..2e1f74e
--- /dev/null
+++ b/scripts/optimization/lsqnonneg.m
@@ -0,0 +1,205 @@
+## Copyright (C) 2008 Bill Denney
+## Copyright (C) 2008 Jaroslav Hajek
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} lsqnonneg (@var{c}, @var{d})
+## @deftypefnx {Function File} {@var{x} =} lsqnonneg (@var{c}, @var{d}, @var{x0})
+## @deftypefnx {Function File} {[@var{x}, @var{resnorm}] =} lsqnonneg (@dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}] =} lsqnonneg (@dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}] =} lsqnonneg (@dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}, @var{output}] =} lsqnonneg (@dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{resnorm}, @var{residual}, @var{exitflag}, @var{output}, @var{lambda}] =} lsqnonneg (@dots{})
+## Minimize @code{norm (@var{c}*@var{x}-d)} subject to @code{@var{x} >=
+## 0}.  @var{c} and @var{d} must be real.  @var{x0} is an optional
+## initial guess for @var{x}.
+##
+## Outputs:
+## @itemize @bullet
+## @item resnorm
+##
+## The squared 2-norm of the residual: norm(@var{c}*@var{x}- at var{d})^2
+## @item residual
+##
+## The residual: @var{d}- at var{c}*@var{x}
+## @item exitflag
+##
+## An indicator of convergence.  0 indicates that the iteration count
+## was exceeded, and therefore convergence was not reached; >0 indicates
+## that the algorithm converged.  (The algorithm is stable and will
+## converge given enough iterations.)
+## @item output
+##
+## A structure with two fields:
+## @itemize @bullet
+## @item "algorithm": The algorithm used ("nnls")
+## @item "iterations": The number of iterations taken.
+## @end itemize
+## @item lambda
+##
+## Not implemented.
+## @end itemize
+## @seealso{optimset}
+## @end deftypefn
+
+## PKG_ADD: __all_opts__ ("lsqnonneg");
+
+## This is implemented from Lawson and Hanson's 1973 algorithm on page
+## 161 of Solving Least Squares Problems.
+
+function [x, resnorm, residual, exitflag, output, lambda] = lsqnonneg (c, d, x = [], options = struct ())
+
+  if (nargin == 1 && ischar (c) && strcmp (c, 'defaults'))
+    x = optimset ("MaxIter", 1e5);
+    return
+  endif
+
+  if (! (nargin >= 2 && nargin <= 4 && ismatrix (c) && ismatrix (d) && isstruct (options)))
+    print_usage ();
+  endif
+
+  ## Lawson-Hanson Step 1 (LH1): initialize the variables.
+  m = rows (c);
+  n = columns (c);
+  if (isempty (x))
+    ## Initial guess is 0s.
+    x = zeros (n, 1);
+  else
+    ## ensure nonnegative guess.
+    x = max (x, 0);
+  endif
+
+  useqr = m >= n;
+  max_iter = optimget (options, "MaxIter", 1e5);
+
+  ## Initialize P, according to zero pattern of x.
+  p = find (x > 0).';
+  if (useqr)
+    ## Initialize the QR factorization, economized form.
+    [q, r] = qr (c(:,p), 0);
+  endif
+
+  iter = 0;
+
+  ## LH3: test for completion.
+  while (iter < max_iter)
+    while (iter < max_iter)
+      iter++;
+
+      ## LH6: compute the positive matrix and find the min norm solution
+      ## of the positive problem.
+      if (useqr)
+        xtmp = r \ q'*d;
+      else
+        xtmp = c(:,p) \ d;
+      endif
+      idx = find (xtmp < 0);
+
+      if (isempty (idx)) 
+        ## LH7: tmp solution found, iterate.
+        x(:) = 0;
+        x(p) = xtmp;
+        break;
+      else
+        ## LH8, LH9: find the scaling factor.
+        pidx = p(idx);
+        sf = x(pidx)./(x(pidx) - xtmp(idx));
+        alpha = min (sf);
+        ## LH10: adjust X.
+        xx = zeros (n, 1);
+        xx(p) = xtmp;
+        x += alpha*(xx - x);
+        ## LH11: move from P to Z all X == 0.
+        ## This corresponds to those indices where minimum of sf is attained.
+        idx = idx (sf == alpha);
+        p(idx) = [];
+        if (useqr)
+          ## update the QR factorization.
+          [q, r] = qrdelete (q, r, idx);
+        endif
+      endif
+    endwhile
+      
+    ## compute the gradient.
+    w = c'*(d - c*x);
+    w(p) = [];
+    if (! any (w > 0))
+      if (useqr)
+        ## verify the solution achieved using qr updating.
+        ## in the best case, this should only take a single step.
+        useqr = false;
+        continue;
+      else
+        ## we're finished.
+        break;
+      endif
+    endif
+
+    ## find the maximum gradient.
+    idx = find (w == max (w));
+    if (numel (idx) > 1)
+      warning ("lsqnonneg:nonunique",
+               "A non-unique solution may be returned due to equal gradients.");
+      idx = idx(1);
+    endif
+    ## move the index from Z to P. Keep P sorted.
+    z = [1:n]; z(p) = [];
+    zidx = z(idx);
+    jdx = 1 + lookup (p, zidx);
+    p = [p(1:jdx-1), zidx, p(jdx:end)];
+    if (useqr)
+      ## insert the column into the QR factorization.
+      [q, r] = qrinsert (q, r, jdx, c(:,zidx));
+    endif
+
+  endwhile
+  ## LH12: complete.
+
+  ## Generate the additional output arguments.
+  if (nargout > 1)
+    resnorm = norm (c*x - d) ^ 2;
+  endif
+  if (nargout > 2)
+    residual = d - c*x;
+  endif
+  exitflag = iter;
+  if (nargout > 3 && iter >= max_iter)
+    exitflag = 0;
+  endif
+  if (nargout > 4)
+    output = struct ("algorithm", "nnls", "iterations", iter);
+  endif
+  if (nargout > 5)
+    lambda = zeros (size (x));
+    lambda(p) = w;
+  endif
+
+endfunction
+
+## Tests
+%!test
+%! C = [1 0;0 1;2 1];
+%! d = [1;3;-2];
+%! assert (lsqnonneg (C, d), [0;0.5], 100*eps)
+
+%!test
+%! C = [0.0372 0.2869;0.6861 0.7071;0.6233 0.6245;0.6344 0.6170];
+%! d = [0.8587;0.1781;0.0747;0.8405];
+%! xnew = [0;0.6929];
+%! assert (lsqnonneg (C, d), xnew, 0.0001)
diff --git a/scripts/optimization/optimget.m b/scripts/optimization/optimget.m
new file mode 100644
index 0000000..074114a
--- /dev/null
+++ b/scripts/optimization/optimget.m
@@ -0,0 +1,52 @@
+## Copyright (C) 2008 Jaroslav Hajek
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} optimget (@var{options}, @var{parname})
+## @deftypefnx {Function File} {} optimget (@var{options}, @var{parname}, @var{default})
+## Return a specific option from a structure created by 
+## @code{optimset}.  If @var{parname} is not a field of the @var{options}
+## structure, return @var{default} if supplied, otherwise return an 
+## empty matrix.
+## @end deftypefn
+
+function retval = optimget (options, parname, default)
+
+  if (nargin < 2 || nargin > 4 || ! isstruct (options) || ! ischar (parname))
+    print_usage ();
+  endif
+
+  opts = __all_opts__ ();
+  idx = lookup (opts, parname, "i");
+
+  if (idx > 0 && strcmpi (parname, opts{idx}))
+    parname = opts{idx};
+  else
+    warning ("unrecognized option: %s", parname);
+  endif
+  if (isfield (options, parname))
+    retval = options.(parname);
+  elseif (nargin > 2)
+    retval = default;
+  else
+    retval = [];
+  endif
+
+endfunction
+
diff --git a/scripts/optimization/optimset.m b/scripts/optimization/optimset.m
new file mode 100644
index 0000000..c49cf8b
--- /dev/null
+++ b/scripts/optimization/optimset.m
@@ -0,0 +1,91 @@
+## Copyright (C) 2007, 2008 John W. Eaton
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} optimset ()
+## @deftypefnx {Function File} {} optimset (@var{par}, @var{val}, @dots{})
+## @deftypefnx {Function File} {} optimset (@var{old}, @var{par}, @var{val}, @dots{})
+## @deftypefnx {Function File} {} optimset (@var{old}, @var{new})
+## Create options struct for optimization functions.
+## @end deftypefn
+
+function retval = optimset (varargin)
+
+  nargs = nargin ();
+
+  ## Add more as needed.
+  opts = __all_opts__ ();
+
+  if (nargs == 0)
+    if (nargout == 0)
+      ## Display possibilities.
+      puts ("\nAll possible optimization options:\n\n");
+      printf ("  %s\n", opts{:});
+      puts ("\n");
+    else
+      ## Return empty structure.
+      ## We're incompatible with Matlab at this point.
+      retval = struct ();
+    endif
+  elseif (nargs == 1 && ischar (varargin{1}))
+    ## Return defaults for named function.
+    fcn = varargin{1};
+    try
+      retval = feval (fcn, 'defaults');
+    catch
+      error ("no defaults for function `%s'", fcn);
+    end_try_catch
+  elseif (nargs == 2 && isstruct (varargin{1}) && isstruct (varargin{2}))
+    ## Set slots in old from nonempties in new.  Should we be checking
+    ## to ensure that the field names are expected?
+    old = varargin{1};
+    new = varargin{2};
+    fnames = fieldnames (old);
+    ## skip validation if we're in the internal query
+    validation = ! isempty (opts);
+    for [val, key] = new
+      if (validation)
+        ## Case insensitive lookup in all options.
+        i = lookup (opts, key, "i");
+        ## Validate option.
+        if (i > 0 && strcmpi (opts{i}, key))
+          ## Use correct case.
+          key = opts{i};
+        else
+          warning ("unrecognized option: %s", key);
+        endif
+      endif
+      old.(key) = val;
+    endfor
+    retval = old;
+  elseif (rem (nargs, 2) && isstruct (varargin{1}))
+    ## Set values in old from name/value pairs.
+    retval = optimset (varargin{1}, struct (varargin{2:end}));
+  elseif (rem (nargs, 2) == 0)
+    ## Create struct.  Default values are replaced by those specified by
+    ## name/value pairs.
+    retval = optimset (struct (), struct (varargin{:}));
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert (optimget (optimset ('tolx', 1e-2), 'tOLx'), 1e-2)
+%!assert (isfield (optimset ('tolFun', 1e-3), 'TolFun'))
diff --git a/scripts/optimization/qp.m b/scripts/optimization/qp.m
new file mode 100644
index 0000000..e82b383
--- /dev/null
+++ b/scripts/optimization/qp.m
@@ -0,0 +1,331 @@
+## Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008,
+##               2009 Gabriele Pannocchia.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb}, @var{A_in}, @var{A_ub})
+## Solve the quadratic program
+## @tex
+## $$
+##  \min_x {1 \over 2} x^T H x + x^T q
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      min 0.5 x'*H*x + x'*q
+##       x
+## @end group
+## @end example
+##
+## @end ifnottex
+## subject to
+## @tex
+## $$
+##  Ax = b \qquad lb \leq x \leq ub \qquad A_{lb} \leq A_{in} \leq A_{ub}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      A*x = b
+##      lb <= x <= ub
+##      A_lb <= A_in*x <= A_ub
+## @end group
+## @end example
+## @end ifnottex
+##
+## @noindent
+## using a null-space active-set method.
+##
+## Any bound (@var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb},
+## @var{A_ub}) may be set to the empty matrix (@code{[]}) if not
+## present.  If the initial guess is feasible the algorithm is faster.
+##
+## The value @var{info} is a structure with the following fields:
+## @table @code
+## @item solveiter
+## The number of iterations required to find the solution.
+## @item info
+## An integer indicating the status of the solution, as follows:
+## @table @asis
+## @item 0
+## The problem is feasible and convex.  Global solution found.
+## @item 1
+## The problem is not convex.  Local solution found.
+## @item 2
+## The problem is not convex and unbounded.
+## @item 3
+## Maximum number of iterations reached.
+## @item 6
+## The problem is infeasible.
+## @end table
+## @end table
+## @end deftypefn
+
+function [x, obj, INFO, lambda] = qp (x0, H, q, A, b, lb, ub, A_lb, A_in, A_ub)
+
+  if (nargin == 5 || nargin == 7 || nargin == 10)
+
+    ## Checking the quadratic penalty
+    n = issquare (H);
+    if (n == 0)
+      error ("qp: quadratic penalty matrix not square");
+    endif
+
+    n1 = issymmetric (H);
+    if (n1 == 0)
+      ## warning ("qp: quadratic penalty matrix not symmetric");
+      H = (H + H')/2;
+    endif
+
+    ## Checking the initial guess (if empty it is resized to the
+    ## right dimension and filled with 0)
+    if (isempty (x0))
+      x0 = zeros (n, 1);
+    elseif (length (x0) != n)
+      error ("qp: the initial guess has incorrect length");
+    endif
+
+    ## Linear penalty.
+    if (length (q) != n)
+      error ("qp: the linear term has incorrect length");
+    endif
+
+    ## Equality constraint matrices
+    if (isempty (A) || isempty(b))
+      n_eq = 0;
+      A = zeros (n_eq, n);
+      b = zeros (n_eq, 1);
+    else
+      [n_eq, n1] = size (A);
+      if (n1 != n)
+	error ("qp: equality constraint matrix has incorrect column dimension");
+      endif
+      if (length (b) != n_eq)
+	error ("qp: equality constraint matrix and vector have inconsistent dimension");
+      endif
+    endif
+
+    ## Bound constraints
+    Ain = zeros (0, n);
+    bin = zeros (0, 1);
+    n_in = 0;
+    if (nargin > 5)
+      if (! isempty (lb))
+	if (length(lb) != n)
+	  error ("qp: lower bound has incorrect length");
+	elseif (isempty (ub))
+	  Ain = [Ain; eye(n)];
+	  bin = [bin; lb];
+	endif
+      endif
+
+      if (! isempty (ub))
+	if (length (ub) != n)
+	  error ("qp: upper bound has incorrect length");
+	elseif (isempty (lb))
+	  Ain = [Ain; -eye(n)];
+	  bin = [bin; -ub];
+	endif
+      endif
+      
+      if (! isempty (lb) && ! isempty (ub))
+	rtol = sqrt (eps);
+	for i = 1:n
+	  if (abs(lb (i) - ub(i)) < rtol*(1 + max (abs (lb(i) + ub(i)))))
+            ## These are actually an equality constraint
+	    tmprow = zeros(1,n);
+	    tmprow(i) = 1;
+            A = [A;tmprow];
+            b = [b; 0.5*(lb(i) + ub(i))];
+	    n_eq = n_eq + 1;
+	  else
+	    tmprow = zeros(1,n);
+	    tmprow(i) = 1;
+	    Ain = [Ain; tmprow; -tmprow];
+	    bin = [bin; lb(i); -ub(i)];
+	    n_in = n_in + 2;
+	  endif
+	endfor
+      endif
+    endif
+
+    ## Inequality constraints
+    if (nargin > 7)
+      [dimA_in, n1] = size (A_in);
+      if (n1 != n)
+	error ("qp: inequality constraint matrix has incorrect column dimension");
+      else
+	if (! isempty (A_lb))
+	  if (length (A_lb) != dimA_in)
+	    error ("qp: inequality constraint matrix and lower bound vector inconsistent");
+	  elseif (isempty (A_ub))
+	    Ain = [Ain; A_in];
+	    bin = [bin; A_lb];
+	  endif
+	endif
+	if (! isempty (A_ub))
+	  if (length (A_ub) != dimA_in)
+	    error ("qp: inequality constraint matrix and upper bound vector inconsistent");
+	  elseif (isempty (A_lb))
+	    Ain = [Ain; -A_in];
+	    bin = [bin; -A_ub];
+	  endif
+	endif
+	
+	if (! isempty (A_lb) && ! isempty (A_ub))
+	  rtol = sqrt (eps);
+	  for i = 1:dimA_in
+	    if (abs (A_lb(i) - A_ub(i)) < rtol*(1 + max (abs (A_lb(i) + A_ub(i)))))
+              ## These are actually an equality constraint
+	      tmprow = A_in(i,:);
+              A = [A;tmprow];
+              b = [b; 0.5*(A_lb(i) + A_ub(i))];
+	      n_eq = n_eq + 1;
+	    else
+	      tmprow = A_in(i,:);
+	      Ain = [Ain; tmprow; -tmprow];
+	      bin = [bin; A_lb(i); -A_ub(i)];
+	      n_in = n_in + 2;
+	    endif
+	  endfor
+	endif
+      endif
+    endif
+
+    ## Now we should have the following QP:
+    ##
+    ##   min_x  0.5*x'*H*x + x'*q
+    ##   s.t.   A*x = b
+    ##          Ain*x >= bin
+
+    ## Discard inequality constraints that have -Inf bounds since those
+    ## will never be active.
+    idx = isinf (bin) & bin < 0;
+
+    bin(idx) = [];
+    Ain(idx,:) = [];
+
+    n_in = length (bin);
+
+    ## Check if the initial guess is feasible.
+    if (isa (x0, "single") || isa (H, "single") || isa (q, "single") || isa (A, "single")
+	|| isa (b, "single"))
+      rtol = sqrt (eps ("single"));
+    else
+      rtol = sqrt (eps);
+    endif
+
+    eq_infeasible = (n_eq > 0 && norm (A*x0-b) > rtol*(1+abs (b)));
+    in_infeasible = (n_in > 0 && any (Ain*x0-bin < -rtol*(1+abs (bin))));
+
+    info = 0;
+    if (eq_infeasible || in_infeasible)
+      ## The initial guess is not feasible.
+      ## First define xbar that is feasible with respect to the equality
+      ## constraints.
+      if (eq_infeasible)
+	if (rank (A) < n_eq)
+	  error ("qp: equality constraint matrix must be full row rank")
+	endif
+	xbar = pinv (A) * b;
+      else
+	xbar = x0;
+      endif
+
+      ## Check if xbar is feasible with respect to the inequality
+      ## constraints also.
+      if (n_in > 0)
+	res = Ain * xbar - bin;
+	if (any (res < -rtol * (1 + abs (bin))))
+	  ## xbar is not feasible with respect to the inequality
+	  ## constraints.  Compute a step in the null space of the
+	  ## equality constraints, by solving a QP.  If the slack is
+	  ## small, we have a feasible initial guess.  Otherwise, the
+	  ## problem is infeasible.
+	  if (n_eq > 0)
+	    Z = null (A);
+	    if (isempty (Z))
+	      ## The problem is infeasible because A is square and full
+	      ## rank, but xbar is not feasible.
+	      info = 6;
+	    endif
+	  endif
+
+	  if (info != 6)
+            ## Solve an LP with additional slack variables to find
+	    ## a feasible starting point.
+	    gamma = eye (n_in);
+	    if (n_eq > 0)
+	      Atmp = [Ain*Z, gamma];
+	      btmp = -res;
+	    else
+	      Atmp = [Ain, gamma];
+	      btmp = bin;
+	    endif
+	    ctmp = [zeros(n-n_eq, 1); ones(n_in, 1)];
+	    lb = [-Inf*ones(n-n_eq,1); zeros(n_in,1)];
+	    ub = [];
+	    ctype = repmat ("L", n_in, 1);
+	    [P, dummy, status] = glpk (ctmp, Atmp, btmp, lb, ub, ctype);
+	    if ((status == 180 || status == 181 || status == 151)
+		&& all (abs (P(n-n_eq+1:end)) < rtol * (1 + norm (btmp))))
+	      ## We found a feasible starting point
+	      if (n_eq > 0)
+		x0 = xbar + Z*P(1:n-n_eq);
+	      else
+		x0 = P(1:n);
+              endif
+	    else
+	      ## The problem is infeasible
+	      info = 6;
+	    endif
+	  endif
+	else
+	  ## xbar is feasible.  We use it a starting point.
+	  x0 = xbar;
+	endif
+      else
+	## xbar is feasible.  We use it a starting point.
+	x0 = xbar;
+      endif
+    endif
+
+    if (info == 0)
+      ## FIXME -- make maxit a user option.
+      ## The initial (or computed) guess is feasible.
+      ## We call the solver.
+      maxit = 200;
+      [x, lambda, info, iter] = __qp__ (x0, H, q, A, b, Ain, bin, maxit);
+    else
+      iter = 0;
+      x = x0;
+      lambda = [];
+    endif
+    obj = 0.5 * x' * H * x + q' * x;
+    INFO.solveiter = iter;
+    INFO.info = info;
+
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/optimization/sqp.m b/scripts/optimization/sqp.m
new file mode 100644
index 0000000..ee3be71
--- /dev/null
+++ b/scripts/optimization/sqp.m
@@ -0,0 +1,757 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{iter}, @var{nf}, @var{lambda}] =} sqp (@var{x}, @var{phi}, @var{g}, @var{h}, @var{lb}, @var{ub}, @var{maxiter}, @var{tolerance})
+## Solve the nonlinear program
+## @tex
+## $$
+## \min_x \phi (x)
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      min phi (x)
+##       x
+## @end group
+## @end example
+##
+## @end ifnottex
+## subject to
+## @tex
+## $$
+##  g(x) = 0 \qquad h(x) \geq 0 \qquad lb \leq x \leq ub
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      g(x)  = 0
+##      h(x) >= 0
+##      lb <= x <= ub
+## @end group
+## @end example
+## @end ifnottex
+##
+## @noindent
+## using a successive quadratic programming method.
+##
+## The first argument is the initial guess for the vector @var{x}.
+##
+## The second argument is a function handle pointing to the objective
+## function.  The objective function must be of the form
+##
+## @example
+##      y = phi (x)
+## @end example
+##
+## @noindent
+## in which @var{x} is a vector and @var{y} is a scalar.
+##
+## The second argument may also be a 2- or 3-element cell array of
+## function handles.  The first element should point to the objective
+## function, the second should point to a function that computes the
+## gradient of the objective function, and the third should point to a
+## function to compute the hessian of the objective function.  If the
+## gradient function is not supplied, the gradient is computed by finite
+## differences.  If the hessian function is not supplied, a BFGS update
+## formula is used to approximate the hessian.
+##
+## If supplied, the gradient function must be of the form
+##
+## @example
+## g = gradient (x)
+## @end example
+##
+## @noindent
+## in which @var{x} is a vector and @var{g} is a vector.
+##
+## If supplied, the hessian function must be of the form
+##
+## @example
+## h = hessian (x)
+## @end example
+##
+## @noindent
+## in which @var{x} is a vector and @var{h} is a matrix.
+##
+## The third and fourth arguments are function handles pointing to
+## functions that compute the equality constraints and the inequality
+## constraints, respectively.
+##
+## If your problem does not have equality (or inequality) constraints,
+## you may pass an empty matrix for @var{cef} (or @var{cif}).
+##
+## If supplied, the equality and inequality constraint functions must be
+## of the form
+##
+## @example
+## r = f (x)
+## @end example
+##
+## @noindent
+## in which @var{x} is a vector and @var{r} is a vector.
+## 
+## The third and fourth arguments may also be 2-element cell arrays of
+## function handles.  The first element should point to the constraint
+## function and the second should point to a function that computes the
+## gradient of the constraint function:
+##
+## @tex
+## $$
+##  \Bigg( {\partial f(x) \over \partial x_1}, 
+##         {\partial f(x) \over \partial x_2}, \ldots,
+##         {\partial f(x) \over \partial x_N} \Bigg)^T
+## $$
+## @end tex
+## @ifnottex
+## @example
+## @group
+##                 [ d f(x)   d f(x)        d f(x) ]
+##     transpose ( [ ------   -----   ...   ------ ] )
+##                 [  dx_1     dx_2          dx_N  ]
+## @end group
+## @end example
+## @end ifnottex
+##
+## The fifth and sixth arguments are vectors containing lower and upper bounds
+## on @var{x}.  These must be consistent with equality and inequality
+## constraints @var{g} and @var{h}.  If the bounds are not specified, or are
+## empty, they are set to - at var{realmax} and @var{realmax} by default.
+##
+## The seventh argument is max. number of iterations.  If not specified,
+## the default value is 100.
+##
+## The eighth argument is tolerance for stopping criteria.  If not specified,
+## the default value is @var{eps}.
+##
+## Here is an example of calling @code{sqp}:
+##
+## @example
+## function r = g (x)
+##   r = [ sumsq(x)-10;
+##         x(2)*x(3)-5*x(4)*x(5); 
+##         x(1)^3+x(2)^3+1 ];
+## endfunction
+##
+## function obj = phi (x)
+##   obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+## endfunction
+##
+## x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+##
+## [x, obj, info, iter, nf, lambda] = sqp (x0, @@phi, @@g, [])
+##
+## x =
+##     
+##   -1.71714
+##    1.59571
+##    1.82725
+##   -0.76364
+##   -0.76364
+##      
+## obj = 0.053950
+## info = 101
+## iter = 8
+## nf = 10
+## lambda =
+##     
+##   -0.0401627
+##    0.0379578
+##   -0.0052227
+## @end example
+##
+## The value returned in @var{info} may be one of the following:
+## @table @asis
+## @item 101
+## The algorithm terminated because the norm of the last step was less
+## than @code{tol * norm (x))} (the value of tol is currently fixed at
+## @code{sqrt (eps)}---edit @file{sqp.m} to modify this value.
+## @item 102
+## The BFGS update failed.
+## @item 103
+## The maximum number of iterations was reached (the maximum number of
+## allowed iterations is currently fixed at 100---edit @file{sqp.m} to
+## increase this value).
+## @end table
+## @seealso{qp}
+## @end deftypefn
+
+function [x, obj, info, iter, nf, lambda] = sqp (x, objf, cef, cif, lb, ub, maxiter, tolerance)
+
+  global __sqp_nfun__;
+  global __sqp_obj_fun__;
+  global __sqp_ce_fun__;
+  global __sqp_ci_fun__;
+  global __sqp_cif__;
+  global __sqp_cifcn__;
+
+  if (nargin >= 2 && nargin <= 8 && nargin != 5)
+
+    ## Choose an initial NxN symmetric positive definite Hessan
+    ## approximation B.
+
+    n = length (x);
+
+    ## Evaluate objective function, constraints, and gradients at initial
+    ## value of x.
+    ##
+    ## obj_fun
+    ## obj_grad
+    ## ce_fun  -- equality constraint functions
+    ## ci_fun  -- inequality constraint functions
+    ## A == [grad_{x_1} cx_fun, grad_{x_2} cx_fun, ..., grad_{x_n} cx_fun]^T
+
+    obj_grd = @fd_obj_grd;
+    have_hess = 0;
+    if (iscell (objf))
+      if (length (objf) > 0)
+	__sqp_obj_fun__ = obj_fun = objf{1};
+	if (length (objf) > 1)
+	  obj_grd = objf{2};
+	  if (length (objf) > 2)
+	    obj_hess = objf{3};
+	    have_hess = 1;
+	  endif
+	endif
+      else
+	error ("sqp: invalid objective function");
+      endif
+    else
+      __sqp_obj_fun__ = obj_fun = objf;
+    endif
+
+    ce_fun = @empty_cf;
+    ce_grd = @empty_jac;
+    if (nargin > 2)
+      ce_grd = @fd_ce_jac;
+      if (iscell (cef))
+	if (length (cef) > 0)
+	  __sqp_ce_fun__ = ce_fun = cef{1};
+	  if (length (cef) > 1)
+	    ce_grd = cef{2};
+	  endif
+	else
+	  error ("sqp: invalid equality constraint function");
+	endif
+      elseif (! isempty (cef))
+	ce_fun = cef;
+      endif
+    endif
+    __sqp_ce_fun__ = ce_fun;
+
+    ci_fun = @empty_cf;
+    ci_grd = @empty_jac;
+	
+    if (nargin > 3)
+      ## constraint function given by user with possibly gradient
+      __sqp_cif__ = cif;
+      ## constraint function given by user without gradient
+      __sqp_cifcn__ = @empty_cf;
+      if (iscell (__sqp_cif__))
+	if (length (__sqp_cif__) > 0)
+	  __sqp_cifcn__ = __sqp_cif__{1};
+	endif
+      elseif (! isempty (__sqp_cif__))
+	__sqp_cifcn__ = __sqp_cif__;
+      endif
+
+      if (nargin < 5)
+      	ci_grd = @fd_ci_jac;
+      	if (iscell (cif))
+	  if (length (cif) > 0)
+	    __sqp_ci_fun__ = ci_fun = cif{1};
+	    if (length (cif) > 1)
+	      ci_grd = cif{2};
+	    endif
+	  else
+	    error ("sqp: invalid equality constraint function");
+	  endif
+      	elseif (! isempty (cif))
+	  ci_fun = cif;
+      	endif
+      else
+	global __sqp_lb__;
+	if (isvector (lb))
+	  __sqp_lb__ = lb;
+	elseif (isempty (lb))
+	  if (isa (x, "single"))
+	    __sqp_lb__ = -realmax ("single");
+	  else
+	    __sqp_lb__ = -realmax;
+	  endif
+	else
+	  error ("sqp: invalid lower bound");
+	endif
+
+	global __sqp_ub__;
+	if (isvector (ub))
+	  __sqp_ub__ = ub;
+	elseif (isempty (lb))
+	  if (isa (x, "single"))
+	    __sqp_ub__ = realmax ("single");
+	  else
+	    __sqp_ub__ = realmax;
+	  endif
+	else
+	  error ("sqp: invalid upper bound");
+	endif
+
+	if (lb > ub)
+	  error ("sqp: upper bound smaller than lower bound");
+	endif
+       	__sqp_ci_fun__ = ci_fun = @cf_ub_lb;
+       	ci_grd = @cigrad_ub_lb;
+      endif
+      __sqp_ci_fun__ = ci_fun;
+    endif
+
+    iter_max = 100;
+    if (nargin > 6 && ! isempty (maxiter))
+      if (isscalar (maxiter) && maxiter > 0 && round (maxiter) == maxiter)
+	iter_max = maxiter;
+      else
+	error ("sqp: invalid number of maximum iterations");
+      endif
+    endif
+
+    tol = sqrt (eps);
+    if (nargin > 7 && ! isempty (tolerance))
+      if (isscalar (tolerance) && tolerance > 0)
+	tol = tolerance;
+      else
+	error ("sqp: invalid value for tolerance");
+      endif
+    endif
+
+    iter = 0;
+
+    obj = feval (obj_fun, x);
+    __sqp_nfun__ = 1;
+
+    c = feval (obj_grd, x);
+
+    if (have_hess)
+      B = feval (obj_hess, x);
+    else
+      B = eye (n, n);
+    endif
+
+    ce = feval (ce_fun, x);
+    F = feval (ce_grd, x);
+
+    ci = feval (ci_fun, x);
+    C = feval (ci_grd, x);
+
+    A = [F; C];
+
+    ## Choose an initial lambda (x is provided by the caller).
+
+    lambda = 100 * ones (rows (A), 1);
+
+    qp_iter = 1;
+    alpha = 1;
+
+    ## report ();
+
+    ## report (iter, qp_iter, alpha, __sqp_nfun__, obj);
+
+    info = 0;
+
+    while (++iter < iter_max)
+
+      ## Check convergence.  This is just a simple check on the first
+      ## order necessary conditions.
+
+      ## IDX is the indices of the active inequality constraints.
+
+      nr_f = rows (F);
+
+      lambda_e = lambda((1:nr_f)');
+      lambda_i = lambda((nr_f+1:end)');
+
+      con = [ce; ci];
+
+      t0 = norm (c - A' * lambda);
+      t1 = norm (ce);
+      t2 = all (ci >= 0);
+      t3 = all (lambda_i >= 0);
+      t4 = norm (lambda .* con);
+
+      if (t2 && t3 && max ([t0; t1; t4]) < tol)
+	break;
+      endif
+
+      ## Compute search direction p by solving QP.
+
+      g = -ce;
+      d = -ci;
+
+      ## Discard inequality constraints that have -Inf bounds since those
+      ## will never be active.
+      idx = isinf (d) & d < 0;
+      d(idx) = [];
+      C(idx,:) = [];
+
+      [p, obj_qp, INFO, lambda] = qp (x, B, c, F, g, [], [], d, C,
+				      Inf * ones (size (d)));
+
+      info = INFO.info;
+
+      ## Check QP solution and attempt to recover if it has failed.
+
+      ## Choose mu such that p is a descent direction for the chosen
+      ## merit function phi.
+
+      [x_new, alpha, obj_new] = linesearch_L1 (x, p, obj_fun, obj_grd,
+					       ce_fun, ci_fun, lambda, obj);
+
+      ## Evaluate objective function, constraints, and gradients at
+      ## x_new.
+
+      c_new = feval (obj_grd, x_new);
+
+      ce_new = feval (ce_fun, x_new);
+      F_new = feval (ce_grd, x_new);
+
+      ci_new = feval (ci_fun, x_new);
+      C_new = feval (ci_grd, x_new);
+
+      A_new = [F_new; C_new];
+
+      ## Set
+      ##
+      ## s = alpha * p
+      ## y = grad_x L (x_new, lambda) - grad_x L (x, lambda})
+
+      y = c_new - c;
+
+      if (! isempty (A))
+	t = ((A_new - A)'*lambda);
+	y -= t;
+      endif
+
+      delx = x_new - x;
+
+      if (norm (delx) < tol * norm (x))
+	info = 101;
+	break;
+      endif
+
+      if (have_hess)
+
+	B = feval (obj_hess, x);
+
+      else
+
+	## Update B using a quasi-Newton formula.
+
+	delxt = delx';
+
+	## Damped BFGS.  Or maybe we would actually want to use the Hessian
+	## of the Lagrangian, computed directly.
+
+	d1 = delxt*B*delx;
+
+	t1 = 0.2 * d1;
+	t2 = delxt*y;
+
+	if (t2 < t1)
+	  theta = 0.8*d1/(d1 - t2);
+	else
+	  theta = 1;
+	endif
+
+	r = theta*y + (1-theta)*B*delx;
+
+	d2 = delxt*r;
+
+	if (d1 == 0 || d2 == 0)
+	  info = 102;
+	  break;
+	endif
+
+	B = B - B*delx*delxt*B/d1 + r*r'/d2;
+
+      endif
+
+      x = x_new;
+
+      obj = obj_new;
+
+      c = c_new;
+
+      ce = ce_new;
+      F = F_new;
+
+      ci = ci_new;
+      C = C_new;
+
+      A = A_new;
+
+      ## report (iter, qp_iter, alpha, __sqp_nfun__, obj);
+
+    endwhile
+
+    if (iter >= iter_max)
+      info = 103;
+    endif
+
+    nf = __sqp_nfun__;
+
+  else
+
+    print_usage ();
+
+  endif
+
+endfunction
+
+
+function [merit, obj] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, mu)
+
+  global __sqp_nfun__;
+
+  ce = feval (ce_fun, x);
+  ci = feval (ci_fun, x);
+
+  idx = ci < 0;
+
+  con = [ce; ci(idx)];
+
+  if (isempty (obj))
+    obj = feval (obj_fun, x);
+    __sqp_nfun__++;
+  endif
+
+  merit = obj;
+  t = norm (con, 1) / mu;
+
+  if (! isempty (t))
+    merit += t;
+  endif
+
+endfunction
+
+
+function [x_new, alpha, obj] = linesearch_L1 (x, p, obj_fun, obj_grd,
+					      ce_fun, ci_fun, lambda, obj)
+
+  ## Choose parameters
+  ##
+  ## eta in the range (0, 0.5)
+  ## tau in the range (0, 1)
+
+  eta = 0.25;
+  tau = 0.5;
+
+  delta_bar = sqrt (eps);
+
+  if (isempty (lambda))
+    mu = 1 / delta_bar;
+  else
+    mu = 1 / (norm (lambda, Inf) + delta_bar);
+  endif
+
+  alpha = 1;
+
+  c = feval (obj_grd, x);
+  ce = feval (ce_fun, x);
+
+  [phi_x_mu, obj] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, mu);
+
+  D_phi_x_mu = c' * p;
+  d = feval (ci_fun, x);
+  ## only those elements of d corresponding
+  ## to violated constraints should be included.
+  idx = d < 0;
+  t = - norm ([ce; d(idx)], 1) / mu;
+  if (! isempty (t))
+    D_phi_x_mu += t;
+  endif
+
+  while (1)
+    [p1, obj] = phi_L1 ([], obj_fun, ce_fun, ci_fun, x+alpha*p, mu);
+    p2 = phi_x_mu+eta*alpha*D_phi_x_mu;
+    if (p1 > p2)
+      ## Reset alpha = tau_alpha * alpha for some tau_alpha in the
+      ## range (0, tau).
+      tau_alpha = 0.9 * tau;  ## ??
+      alpha = tau_alpha * alpha;
+    else
+      break;
+    endif
+  endwhile
+
+  ## Set x_new = x + alpha * p;
+
+  x_new = x + alpha * p;
+
+endfunction
+
+
+function report (iter, qp_iter, alpha, nfun, obj)
+
+  if (nargin == 0)
+    printf ("  Itn ItQP     Step  Nfun     Objective\n");
+  else
+    printf ("%5d %4d %8.1g %5d %13.6e\n", iter, qp_iter, alpha, nfun, obj);
+  endif
+
+endfunction
+
+
+function grd = fdgrd (f, x)
+
+  if (! isempty (f))
+    y0 = feval (f, x);
+    nx = length (x);
+    grd = zeros (nx, 1);
+    deltax = sqrt (eps);
+    for i = 1:nx
+      t = x(i);
+      x(i) += deltax;
+      grd(i) = (feval (f, x) - y0) / deltax;
+      x(i) = t;
+    endfor
+  else
+    grd = zeros (0, 1);
+  endif
+
+endfunction
+
+
+function jac = fdjac (f, x)
+  nx = length (x);
+  if (! isempty (f))
+    y0 = feval (f, x);
+    nf = length (y0);
+    nx = length (x);
+    jac = zeros (nf, nx);
+    deltax = sqrt (eps);
+    for i = 1:nx
+      t = x(i);
+      x(i) += deltax;
+      jac(:,i) = (feval (f, x) - y0) / deltax;
+      x(i) = t;
+    endfor
+  else
+    jac = zeros  (0, nx);
+  endif
+
+endfunction
+
+
+function grd = fd_obj_grd (x)
+
+  global __sqp_obj_fun__;
+
+  grd = fdgrd (__sqp_obj_fun__, x);
+
+endfunction
+
+
+function res = empty_cf (x)
+
+  res = zeros (0, 1);
+
+endfunction
+
+
+function res = empty_jac (x)
+
+  res = zeros (0, length (x));
+
+endfunction
+
+
+function jac = fd_ce_jac (x)
+
+  global __sqp_ce_fun__;
+
+  jac = fdjac (__sqp_ce_fun__, x);
+
+endfunction
+
+
+function jac = fd_ci_jac (x)
+
+  global __sqp_cifcn__;
+  ## __sqp_cifcn__ = constraint function without gradients and lb or ub
+  jac = fdjac (__sqp_cifcn__, x);
+
+endfunction
+
+
+function res = cf_ub_lb (x)
+
+  ## combine constraint function with ub and lb
+  global __sqp_cifcn__ __sqp_lb__ __sqp_ub__
+
+  res = [x-__sqp_lb__; __sqp_ub__-x];
+
+  if (! isempty (__sqp_cifcn__))
+    res = [feval(__sqp_cifcn__,x); x-__sqp_lb__; __sqp_ub__-x];
+  endif
+
+endfunction
+
+
+function res = cigrad_ub_lb (x)
+
+  global __sqp_cif__
+
+  res = [eye(numel(x)); -eye(numel(x))];
+
+  cigradfcn = @fd_ci_jac;
+
+  if (iscell (__sqp_cif__) && length (__sqp_cif__) > 1)
+    cigradfcn = __sqp_cif__{2};
+  endif
+	
+  if (! isempty (cigradfcn))
+    res = [feval(cigradfcn,x); eye(numel(x)); -eye(numel(x))];
+  endif
+
+endfunction
+
+%!function r = g (x)
+%!  r = [sumsq(x)-10;
+%!       x(2)*x(3)-5*x(4)*x(5);
+%!       x(1)^3+x(2)^3+1 ];
+%!
+%!function obj = phi (x)
+%!  obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
+%!
+%!test
+%! x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
+%!
+%! [x, obj, info, iter, nf, lambda] = sqp (x0, @phi, @g, []);
+%!
+%! x_opt = [-1.717143501952599;
+%!           1.595709610928535;
+%!           1.827245880097156;
+%!          -0.763643103133572;
+%!          -0.763643068453300];
+%!
+%! obj_opt = 0.0539498477702739;
+%!
+%! assert (all (abs (x-x_opt) < 5*sqrt (eps)) && abs (obj-obj_opt) < sqrt (eps));
diff --git a/scripts/path/Makefile.in b/scripts/path/Makefile.in
new file mode 100644
index 0000000..903dfff
--- /dev/null
+++ b/scripts/path/Makefile.in
@@ -0,0 +1,83 @@
+# Makefile for octave's scripts/path directory
+#
+# Copyright (C) 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = path
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = __extractpath__.m matlabroot.m pathdef.m savepath.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/path
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/path/__extractpath__.m b/scripts/path/__extractpath__.m
new file mode 100644
index 0000000..6ad6ff2
--- /dev/null
+++ b/scripts/path/__extractpath__.m
@@ -0,0 +1,95 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Bill Denney
+## Copyright (C) 2007 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{val} =} __extractpath__ (@var{file})
+## Undocumented internal function.
+## @end deftypefn
+
+## Extact the path information from the script/function @var{file},
+## created by @file{savepath.m}. If @var{file} is omitted, 
+## @file{~/.octaverc} is used.  If successful, @code{__extractpath__}
+## returns the path specified in @var{file}.
+
+## Author: Ben Abbott <bpabbott at mac.com>
+
+function specifiedpath = __extractpath__ (savefile)
+
+  ## The majority of this code was borrowed from savepath.m.
+  ## FIXME -- is there some way to share the common parts instead of
+  ## duplicating?
+
+  beginstring = "## Begin savepath auto-created section, do not edit";
+  endstring   = "## End savepath auto-created section";
+
+  if (nargin == 0)
+    savefile = tilde_expand ("~/.octaverc");
+  endif
+
+  ## Parse the file if it exists to see if we should replace a section
+  ## or create a section.
+  startline = 0;
+  endline = 0;
+  filelines = {};
+  if (exist (savefile) == 2)
+    ## read in all lines of the file
+    [fid, msg] = fopen (savefile, "rt");
+    if (fid < 0)
+      error ("__extractpath__: could not open savefile, %s: %s", savefile, msg);
+    endif
+    unwind_protect
+      linenum = 0;
+      while (linenum >= 0)
+	result = fgetl (fid);
+	if (isnumeric (result))
+	  ## End at the end of file.
+	  linenum = -1;
+	else
+	  linenum++;
+	  filelines{linenum} = result;
+	  ## Find the first and last lines if they exist in the file.
+	  if (strcmp (result, beginstring))
+	    startline = linenum + 1;
+	  elseif (strcmp (result, endstring))
+	    endline = linenum - 1;
+	  endif
+	endif
+      endwhile
+    unwind_protect_cleanup
+      closeread = fclose (fid);
+      if (closeread < 0)
+	error ("savepath: could not close savefile after reading, %s",
+	       savefile);
+      endif
+    end_unwind_protect
+  endif
+
+  ## Extract the path specifiation.
+  if (startline > endline || (startline > 0 && endline == 0))
+    error ("savepath: unable to parse file, %s", savefile);
+  elseif (startline > 0)
+    ## Undo doubling of single quote characters performed by savepath.
+    specifiedpath = strrep (regexprep (cstrcat (filelines(startline:endline){:}),
+				       " *path *\\('(.*)'\\); *", "$1"),
+			    "''", "'");
+  else
+    specifiedpath = "";
+  endif
+
+endfunction  
diff --git a/scripts/path/matlabroot.m b/scripts/path/matlabroot.m
new file mode 100644
index 0000000..6bcaf65
--- /dev/null
+++ b/scripts/path/matlabroot.m
@@ -0,0 +1,32 @@
+## Copyright (C) 2008 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{val} =} matlabroot ()
+## Return the location of Octave's home.
+## @seealso{OCTAVE_HOME}
+## @end deftypefn
+
+function val = matlabroot ()
+
+  val = OCTAVE_HOME;
+
+endfunction
+
+
+
diff --git a/scripts/path/pathdef.m b/scripts/path/pathdef.m
new file mode 100644
index 0000000..eb7cdba
--- /dev/null
+++ b/scripts/path/pathdef.m
@@ -0,0 +1,61 @@
+## Copyright (C) 2008, 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{val} =} pathdef ()
+## Return the default path for Octave.
+## The path information is extracted from one of three sources.
+## In order of preference, those are;
+##
+## @enumerate
+## @item @file{~/.octaverc}
+## @item @file{<octave-home>/@dots{}/<version>/m/startup/octaverc}
+## @item Octave's path prior to changes by any octaverc.
+## @end enumerate
+## @seealso{path, addpath, rmpath, genpath, savepath, pathsep}
+## @end deftypefn
+
+function val = pathdef ()
+
+  ## Locate the site octaverc file.
+  pathdir = octave_config_info ("localstartupfiledir");
+  site_octaverc = fullfile (pathdir, "octaverc");
+
+  ## Locate the user ~\.octaverc file.
+  user_octaverc = fullfile ("~", ".octaverc");
+
+  ## Extract the specified paths from the site and user octaverc"s.
+  site_path = __extractpath__ (site_octaverc);
+  if (exist (user_octaverc, "file"))
+    user_path = __extractpath__ (user_octaverc);
+  else
+    user_path = "";
+  endif
+
+  ## A path definition in the user octaverc has precedence over the
+  ## site.
+
+  if (! isempty (user_path))
+    val = user_path;
+  elseif (! isempty (site_path))
+    val = site_path;
+  else
+    val = __pathorig__ ();
+  endif
+
+endfunction
diff --git a/scripts/path/savepath.m b/scripts/path/savepath.m
new file mode 100644
index 0000000..dcb174b
--- /dev/null
+++ b/scripts/path/savepath.m
@@ -0,0 +1,214 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} savepath (@var{file})
+## Save the portion of the current function search path, that is
+## not set during Octave's initialization process, to @var{file}.
+## If @var{file} is omitted, @file{~/.octaverc} is used.  If successful,
+## @code{savepath} returns 0.
+## @seealso{path, addpath, rmpath, genpath, pathdef, pathsep}
+## @end deftypefn
+
+## Author: Bill Denney <bill at givebillmoney.com>
+
+function varargout = savepath (savefile)
+
+  retval = 1;
+
+  beginstring = "## Begin savepath auto-created section, do not edit";
+  endstring   = "## End savepath auto-created section";
+
+  if (nargin == 0)
+    savefile = fullfile ("~", ".octaverc");
+  endif
+
+  ## parse the file if it exists to see if we should replace a section
+  ## or create a section
+  startline = 0;
+  endline = 0;
+  filelines = {};
+  if (exist (savefile) == 2)
+    ## read in all lines of the file
+    [fid, msg] = fopen (savefile, "rt");
+    if (fid < 0)
+      error ("savepath: could not open savefile, %s: %s", savefile, msg);
+    endif
+    unwind_protect
+      linenum = 0;
+      while (linenum >= 0)
+	result = fgetl (fid);
+	if (isnumeric (result))
+	  ## end at the end of file
+	  linenum = -1;
+	else
+	  linenum = linenum + 1;
+	  filelines{linenum} = result;
+	  ## find the first and last lines if they exist in the file
+	  if (strcmp (result, beginstring))
+	    startline = linenum;
+	  elseif (strcmp (result, endstring))
+	    endline = linenum;
+	  endif
+	endif
+      endwhile
+    unwind_protect_cleanup
+      closeread = fclose (fid);
+      if (closeread < 0)
+	error ("savepath: could not close savefile after reading, %s",
+	       savefile);
+      endif
+    end_unwind_protect
+  endif
+
+  if (startline > endline || (startline > 0 && endline == 0))
+    error ("savepath: unable to parse file, %s", savefile);
+  endif
+
+  ## put the current savepath lines into the file
+  if (isempty (filelines)
+      || (startline == 1 && endline == length (filelines)))
+    ## savepath is the entire file
+    pre = post = {};
+  elseif (endline == 0)
+    ## drop the savepath statements at the end of the file
+    pre = filelines;
+    post = {};
+  elseif (startline == 1)
+    pre = {};
+    post = filelines(endline+1:end);
+  elseif (endline == length (filelines))
+    pre = filelines(1:startline-1);
+    post = {};
+  else
+    ## insert in the middle
+    pre = filelines(1:startline-1);
+    post = filelines(endline+1:end);
+  endif
+
+  ## write the results
+  [fid, msg] = fopen (savefile, "wt");
+  if (fid < 0)
+    error ("savepath: unable to open file for writing, %s, %s", savefile, msg);
+  endif
+  unwind_protect
+    for i = 1:length (pre)
+      fprintf (fid, "%s\n", pre{i})
+    endfor
+
+    ## Remove the portion of the path defined via the command line
+    ## and/or the environment.
+    workingpath = parsepath (path);
+    command_line_path = parsepath (command_line_path ());
+    octave_path = parsepath (getenv ("OCTAVE_PATH"));
+    if (isempty (pathdef ()))
+      ## This occurs when running octave via run-octave. In this instance
+      ## the entire path is specified via the command line and pathdef()
+      ## is empty.
+      [tmp, n] = setdiff (workingpath, octave_path);
+      default_path = command_line_path;
+    else
+      [tmp, n] = setdiff (workingpath, union (command_line_path, octave_path));
+      default_path = parsepath (pathdef ());
+    endif
+    ## This is the path we'd like to preserve when octave is run.
+    path_to_preserve = workingpath (sort (n));
+
+    ## Determine the path to Octave's user and sytem wide pkgs.
+    [pkg_user, pkg_system] = pkg ("list");
+    pkg_user_path = cell (1, numel (pkg_user));
+    pkg_system_path = cell (1, numel (pkg_system));
+    for n = 1:numel(pkg_user)
+      pkg_user_path{n} = pkg_user{n}.archprefix;
+    endfor
+    for n = 1:numel(pkg_system)
+      pkg_system_path{n} = pkg_system{n}.archprefix;
+    endfor
+    pkg_path = union (pkg_user_path, pkg_system_path);
+
+    ## Rely on Octave's initialization to include the pkg path elements.
+    if (! isempty (pkg_path))
+      [tmp, n] = setdiff (path_to_preserve, strcat (pkg_path, ":"));
+      path_to_preserve = path_to_preserve (sort (n));
+    endif
+
+    ## Split the path to be saved into two groups. Those path elements that
+    ## belong at the beginning and those at the end.
+    if (! isempty (default_path))
+      n1 = strmatch (default_path{1}, path_to_preserve, "exact");
+      n2 = strmatch (default_path{end}, path_to_preserve, "exact");
+      n_middle = round (0.5*(n1+n2));
+      [tmp, n] = setdiff (path_to_preserve, default_path);
+      path_to_save = path_to_preserve (sort (n));
+      ## Remove pwd
+      path_to_save = path_to_save (! strcmpi (path_to_save,
+					      strcat (".", pathsep)));
+      n = ones (size (path_to_save));
+      for m = 1:numel(path_to_save)
+        n(m) = strmatch (path_to_save{m}, path_to_preserve);
+      endfor
+      path_to_save_begin = path_to_save(n <= n_middle);
+      path_to_save_end   = path_to_save(n > n_middle);
+    else
+      path_to_save_begin = path_to_preserve;
+      path_to_save_end   = {};
+    endif
+    path_to_save_begin = cell2mat (path_to_save_begin);
+    path_to_save_end   = cell2mat (path_to_save_end);
+
+    ## Use single quotes for PATH argument to avoid string escape
+    ## processing.  Since we are using single quotes around the arg,
+    ## double any single quote characters found in the string.
+    fprintf (fid, "%s\n", beginstring)
+    if (! isempty (path_to_save_begin))
+      n = find (path_to_save_begin != pathsep, 1, "last");
+      fprintf (fid, "  addpath ('%s', '-begin');\n",
+               strrep (path_to_save_begin(1:n), "'", "''"))
+    endif
+    if (! isempty (path_to_save_end))
+      n = find (path_to_save_end != pathsep, 1, "last");
+      fprintf (fid, "  addpath ('%s', '-end');\n",
+               strrep (path_to_save_end(1:n), "'", "''"))
+    endif
+    fprintf (fid, "%s\n", endstring)
+
+    for i = 1:length (post)
+      fprintf (fid, "%s\n", post{i});
+    endfor
+  unwind_protect_cleanup
+    closeread = fclose (fid);
+    if (closeread < 0)
+      error ("savepath: could not close savefile after writing, %s", savefile);
+    elseif (nargin == 0)
+      warning ("savepath: current path saved to %s", savefile);
+    endif
+  end_unwind_protect
+
+  retval = 0;
+
+  if (nargout == 1)
+    varargout{1} = retval;
+  endif
+  
+endfunction  
+
+function path_elements = parsepath (p)
+  pat = sprintf ("([^%s]+[%s$])", pathsep, pathsep);
+  [jnk1, jnk2, jnk3, path_elements] = regexpi (strcat (p, pathsep), pat);
+endfunction
+
diff --git a/scripts/pkg/Makefile.in b/scripts/pkg/Makefile.in
new file mode 100644
index 0000000..6ea5aee
--- /dev/null
+++ b/scripts/pkg/Makefile.in
@@ -0,0 +1,83 @@
+# Makefile for octave's scripts/pkg directory
+#
+# Copyright (C) 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = pkg
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = pkg.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/pkg
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/pkg/pkg.m b/scripts/pkg/pkg.m
new file mode 100644
index 0000000..66802b0
--- /dev/null
+++ b/scripts/pkg/pkg.m
@@ -0,0 +1,2287 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 S�ren Hauberg
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Command} pkg @var{command} @var{pkg_name}
+## @deftypefnx {Command} pkg @var{command} @var{option} @var{pkg_name}
+## This command interacts with the package manager.  Different actions will
+## be taken depending on the value of @var{command}.
+##
+## @table @samp
+## @item install
+## Install named packages.  For example,
+## @example
+## pkg install image-1.0.0.tar.gz
+## @end example
+## @noindent
+## installs the package found in the file @file{image-1.0.0.tar.gz}.
+##
+## The @var{option} variable can contain options that affect the manner
+## in which a package is installed.  These options can be one or more of
+##
+## @table @code
+## @item -nodeps
+## The package manager will disable the dependency checking.  That way it 
+## is possible to install a package even if it depends on another package 
+## that's not installed on the system.  @strong{Use this option with care.}
+##
+## @item -noauto
+## The package manager will not automatically load the installed package 
+## when starting Octave, even if the package requests that it is.
+##
+## @item -auto
+## The package manager will automatically load the installed package when 
+## starting Octave, even if the package requests that it isn't.
+##
+## @item -local
+## A local installation is forced, even if the user has system privileges.
+##
+## @item -global
+## A global installation is forced, even if the user doesn't normally have
+## system privileges
+##
+## @item -verbose
+## The package manager will print the output of all of the commands that are 
+## performed.
+## @end table
+##
+## @item uninstall
+## Uninstall named packages.  For example,
+## @example
+## pkg uninstall image
+## @end example
+## @noindent
+## removes the @code{image} package from the system.  If another installed
+## package depends on the @code{image} package an error will be issued.
+## The package can be uninstalled anyway by using the @code{-nodeps} option.
+## @item load
+## Add named packages to the path.  After loading a package it is
+## possible to use the functions provided by the package.  For example,
+## @example
+## pkg load image
+## @end example
+## @noindent
+## adds the @code{image} package to the path.  It is possible to load all
+## installed packages at once with the command
+## @example
+## pkg load all
+## @end example
+## @item unload
+## Removes named packages from the path.  After unloading a package it is
+## no longer possible to use the functions provided by the package.
+## This command behaves like the @code{load} command.
+## @item list
+## Show a list of the currently installed packages.  By requesting one or two
+## output argument it is possible to get a list of the currently installed
+## packages.  For example,
+## @example
+## installed_packages = pkg list;
+## @end example
+## @noindent
+## returns a cell array containing a structure for each installed package.
+## The command
+## @example
+## [@var{user_packages}, @var{system_packages}] = pkg list
+## @end example
+## @noindent
+## splits the list of installed packages into those who are installed by
+## the current user, and those installed by the system administrator.
+## @item describe
+## Show a short description of the named installed packages, with the option
+## '-verbose' also list functions provided by the package, e.g.:
+## @example
+##  pkg describe -verbose all
+## @end example
+## @noindent
+## will describe all installed packages and the functions they provide.
+## If one output is requested a cell of structure containing the
+## description and list of functions of each package is returned as
+## output rather than printed on screen:
+## @example
+##  desc = pkg ("describe", "secs1d", "image")
+## @end example
+## @noindent
+## If any of the requested packages is not installed, pkg returns an
+## error, unless a second output is requested:
+## @example
+##  [ desc, flag] = pkg ("describe", "secs1d", "image")
+## @end example
+## @noindent
+## @var{flag} will take one of the values "Not installed", "Loaded" or
+## "Not loaded" for each of the named packages.
+## @item prefix
+## Set the installation prefix directory.  For example,
+## @example
+## pkg prefix ~/my_octave_packages
+## @end example
+## @noindent
+## sets the installation prefix to @file{~/my_octave_packages}.
+## Packages will be installed in this directory.
+##
+## It is possible to get the current installation prefix by requesting an
+## output argument.  For example,
+## @example
+## p = pkg prefix
+## @end example
+##
+## The location in which to install the architecture dependent files can be
+## independent specified with an addition argument.  For example
+##
+## @example
+## pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
+## @end example
+## @item local_list
+## Set the file in which to look for information on the locally
+## installed packages.  Locally installed packages are those that are
+## typically available only to the current user.  For example
+## @example
+## pkg local_list ~/.octave_packages
+## @end example
+## It is possible to get the current value of local_list with the following
+## @example
+## pkg local_list
+## @end example
+## @item global_list
+## Set the file in which to look for, for information on the globally
+## installed packages.  Globally installed packages are those that are
+## typically available to all users.  For example
+## @example
+## pkg global_list /usr/share/octave/octave_packages
+## @end example
+## It is possible to get the current value of global_list with the following
+## @example
+## pkg global_list
+## @end example
+## @item rebuild
+## Rebuilds the package database from the installed directories.  This can 
+## be used in cases where for some reason the package database is corrupted.
+## It can also take the @code{-auto} and @code{-noauto} options to allow the
+## autoloading state of a package to be changed.  For example
+##
+## @example
+## pkg rebuild -noauto image
+## @end example
+##
+## will remove the autoloading status of the image package.
+## @item build
+## Builds a binary form of a package or packages.  The binary file produced
+## will itself be an Octave package that can be installed normally with
+## @code{pkg}.  The form of the command to build a binary package is
+##
+## @example
+## pkg build builddir image-1.0.0.tar.gz @dots{}
+## @end example
+##
+## @noindent
+## where @code{builddir} is the name of a directory where the temporary
+## installation will be produced and the binary packages will be found.
+## The options @code{-verbose} and @code{-nodeps} are respected, while 
+## the other options are ignored.
+## @end table
+## @end deftypefn
+
+function [local_packages, global_packages] = pkg (varargin)
+  ## Installation prefix (FIXME: what should these be on windows?)
+  persistent user_prefix = false;
+  persistent prefix = -1;
+  persistent archprefix = -1;
+  persistent local_list = tilde_expand (fullfile ("~", ".octave_packages"));
+  persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave",
+				     "octave_packages");
+  mlock ();
+
+  global_install = issuperuser ();
+
+  if (prefix == -1)
+    if (global_install)
+      prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
+      archprefix = fullfile (octave_config_info ("libexecdir"),
+			     "octave", "packages");
+    else
+      prefix = fullfile ("~", "octave");
+      archprefix = prefix;
+    endif
+    prefix = tilde_expand (prefix);
+    archprefix = tilde_expand (archprefix);
+  endif
+
+  available_actions = {"list", "install", "uninstall", "load", ...
+		       "unload", "prefix", "local_list", ...
+		       "global_list", "rebuild", "build","describe"}; 
+  ## Handle input
+  if (length (varargin) == 0 || ! iscellstr (varargin))
+    print_usage ();
+  endif
+  files = {};
+  deps = true;
+  auto = 0;
+  action = "none";
+  verbose = false;
+  for i = 1:length (varargin)
+    switch (varargin{i})
+      case "-nodeps"
+	deps = false;
+      case "-noauto"
+	auto = -1;
+      case "-auto"
+	auto = 1;
+      case "-verbose"
+	verbose = true;
+      case "-local"
+	global_install = false;
+	if (! user_prefix)
+	  prefix = tilde_expand (fullfile ("~", "octave"));
+	  archprefix = prefix;
+	endif
+      case "-global"
+	global_install = true;
+	if (! user_prefix)
+	  prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
+	  archprefix = fullfile (octave_config_info ("libexecdir"),
+				 "octave", "packages");
+	endif
+      case available_actions
+	if (strcmp (action, "none"))
+	  action = varargin{i};
+	else
+	  error ("more than one action specified");
+	endif
+      otherwise
+	files{end+1} = varargin{i};
+    endswitch
+  endfor
+
+  ## Take action
+  switch (action)
+    case "list"
+      if (nargout == 0)
+	installed_packages (local_list, global_list);
+      elseif (nargout == 1)
+	local_packages = installed_packages (local_list, global_list);
+      elseif (nargout == 2)
+	[local_packages, global_packages] = installed_packages (local_list,
+								global_list);
+      else
+	error ("too many output arguments requested");
+      endif
+
+    case "install"
+      if (length (files) == 0)
+	error ("you must specify at least one filename when calling 'pkg install'");
+      endif
+      install (files, deps, auto, prefix, archprefix, verbose, local_list, 
+	       global_list, global_install);
+
+    case "uninstall"
+      if (length (files) == 0)
+	error ("you must specify at least one package when calling 'pkg uninstall'");
+      endif
+      uninstall (files, deps, verbose, local_list, 
+		 global_list, global_install);
+
+    case "load"
+      if (length (files) == 0)
+	error ("you must specify at least one package, 'all' or 'auto' when calling 'pkg load'");
+      endif
+      load_packages (files, deps, local_list, global_list);
+
+    case "unload"
+      if (length (files) == 0)
+	error ("you must specify at least one package or 'all' when calling 'pkg unload'");
+      endif
+      unload_packages (files, deps, local_list, global_list);
+
+    case "prefix"
+      if (length (files) == 0 && nargout == 0)
+	printf ("Installation prefix:             %s\n", prefix);
+	printf ("Architecture dependent prefix:   %s\n", archprefix);
+      elseif (length (files) == 0 && nargout >= 1)
+	local_packages = prefix;
+	global_packages = archprefix;
+      elseif (length (files) >= 1 && nargout <= 2 && ischar (files{1}))
+	prefix = files{1};
+	prefix = absolute_pathname (prefix);
+	local_packages = prefix;
+	user_prefix = true;
+	if (length (files) >= 2 && ischar (files{2}))
+	  archprefix = files{2};
+	  try
+	    archprefix = absolute_pathname (archprefix);
+          catch
+	    mkdir (archprefix);
+	    warning ("creating the directory %s\n", archprefix);
+	    archprefix = absolute_pathname (archprefix);
+	  end_try_catch
+	  global_packages = archprefix;
+	endif
+      else
+	error ("you must specify a prefix directory, or request an output argument");
+      endif
+
+    case "local_list"
+      if (length (files) == 0 && nargout == 0)
+	disp (local_list);
+      elseif (length (files) == 0 && nargout == 1)
+	local_packages = local_list;
+      elseif (length (files) == 1 && nargout == 0 && ischar (files{1}))
+	try
+	  local_list = absolute_pathname (files{1});
+	catch
+	  ## Force file to be created
+	  fclose (fopen (files{1}, "wt"));
+	  local_list = absolute_pathname (files{1});
+	end_try_catch
+      else
+	error ("you must specify a local_list file, or request an output argument");
+      endif
+
+    case "global_list"
+      if (length (files) == 0 && nargout == 0)
+	disp(global_list);
+      elseif (length (files) == 0 && nargout == 1)
+	local_packages = global_list;
+      elseif (length (files) == 1 && nargout == 0 && ischar (files{1}))
+	try
+	  global_list = absolute_pathname (files{1});
+	catch
+	  ## Force file to be created
+	  fclose (fopen (files{1}, "wt"));
+	  global_list = absolute_pathname (files{1});
+	end_try_catch
+      else
+	error ("you must specify a global_list file, or request an output argument");
+      endif
+
+    case "rebuild"
+      if (global_install)
+	global_packages = rebuild (prefix, archprefix, global_list, files, 
+				   auto, verbose);
+	global_packages = save_order (global_packages);
+	save (global_list, "global_packages");
+	if (nargout > 0)
+	  local_packages = global_packages;
+	endif
+      else
+	local_packages = rebuild (prefix, archprefix, local_list, files, auto, 
+				  verbose);
+	local_packages = save_order (local_packages);
+	save (local_list, "local_packages");
+	if (nargout == 0)
+	  clear ("local_packages");
+	endif
+      endif
+
+    case "build"
+      if (length (files) < 2)
+	error ("you must specify at least the build directory and one filename\nwhen calling 'pkg build'");
+      endif
+      build (files, deps, auto, verbose);
+
+    case "describe"
+      if (length (files) == 0)
+	error ("you must specify at least one package or 'all' when calling 'pkg describe'");
+      endif
+      ## FIXME: the name of the output variables is inconsistent
+      ##            with their content
+      switch (nargout)
+	case 0
+	  describe (files, verbose, local_list, global_list);
+	case 1
+	  pkg_desc_list = describe (files, verbose, local_list, ...
+				    global_list);
+	  local_packages = pkg_desc_list;
+	case 2
+	  [pkg_desc_list, flag] = describe (files, verbose, local_list, ...
+					    global_list);
+	  local_packages  = pkg_desc_list;
+	  global_packages = flag;
+	otherwise
+	  error ("you can request at most two outputs when calling 'pkg describe'");
+      endswitch
+		
+    otherwise
+      error ("you must specify a valid action for 'pkg'. See 'help pkg' for details");
+  endswitch
+endfunction
+
+function descriptions = rebuild (prefix, archprefix, list, files, auto, verbose)
+  if (isempty (files))
+    [dirlist, err, msg] = readdir (prefix);
+    if (err)
+      error ("couldn't read directory %s: %s", prefix, msg);
+    endif
+    ## the two first entries of dirlist are "." and ".."
+    dirlist([1,2]) = [];
+  else
+    old_descriptions = installed_packages (list, list);
+    wd = pwd ();
+    unwind_protect
+      cd (prefix);
+      dirlist = glob (cellfun(@(x) cstrcat(x, '-*'), files, 'UniformOutput', 0));
+    unwind_protect_cleanup
+      cd (wd);
+    end_unwind_protect
+  endif
+  descriptions = {};
+  for k = 1:length (dirlist)
+    descfile = fullfile (prefix, dirlist{k}, "packinfo", "DESCRIPTION");
+    if (verbose)
+      printf ("recreating package description from %s\n", dirlist{k});
+    endif
+    if (exist (descfile, "file"))
+      desc = get_description (descfile);
+      desc.dir = fullfile (prefix, dirlist{k});
+      desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-",
+				  desc.version));
+      if (auto != 0)
+	if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
+	  unlink (fullfile (desc.dir, "packinfo", ".autoload"));
+	endif
+        if (auto < 0)
+	  desc.autoload = 0;
+	elseif (auto > 0)
+	  desc.autoload = 1;
+	  fclose (fopen (fullfile (desc.dir, "packinfo", ".autoload"), "wt"));
+	endif
+      else
+	if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
+	  desc.autoload = 1;
+	else
+	  desc.autoload = 0;
+	endif
+      endif
+      descriptions{end + 1} = desc;
+    elseif (verbose)
+      warning ("directory %s is not a valid package", dirlist{k});
+    endif
+  endfor
+
+  if (! isempty (files))
+    ## We are rebuilding for a particular package(s) so we should take
+    ## care to keep the other untouched packages in the descriptions
+    descriptions = {descriptions{:}, old_descriptions{:}};
+
+    dup = [];
+    for i = 1:length (descriptions)
+      if (find (dup, i))
+	continue;
+      endif
+      for j = (i+1):length (descriptions)
+	if (find (dup, j))
+	  continue;
+	endif
+	if (strcmp (descriptions{i}.name, descriptions{j}.name))
+	  dup = [dup, j];
+	endif
+      endfor
+    endfor
+    if (! isempty (dup))
+      descriptions (dup) = [];
+    endif  
+  endif
+endfunction
+
+function build (files, handle_deps, autoload, verbose)
+  if (length (files) < 1)
+    error ("insufficient number of files");
+  endif
+  builddir = files{1};
+  if (! exist (builddir, "dir"))
+    warning ("creating build directory %s", builddir);
+    [status, msg] = mkdir (builddir);
+    if (status != 1)
+      error ("could not create installation directory: %s", msg);
+    endif
+  endif
+  builddir = absolute_pathname (builddir);
+  installdir = fullfile (builddir, "install");
+  if (! exist (installdir, "dir"))
+    [status, msg] = mkdir (installdir);
+    if (status != 1)
+      error ("could not create installation directory: %s", msg);
+    endif
+  endif
+  files(1) = [];
+  buildlist = fullfile (builddir, "octave_packages");
+  install (files, handle_deps, autoload, installdir, installdir, verbose, 
+	   buildlist, "", false);
+  unwind_protect
+    repackage (builddir, buildlist);
+  unwind_protect_cleanup
+    unload_packages ({"all"}, handle_deps, buildlist, "");
+    if (exist (installdir, "dir"))
+      rm_rf (installdir);
+    endif
+    if (exist (buildlist, "file"))
+      unlink (buildlist);
+    endif
+  end_unwind_protect
+endfunction
+
+function install (files, handle_deps, autoload, prefix, archprefix, verbose, 
+		  local_list, global_list, global_install)
+
+  ## Check that the directory in prefix exist. If it doesn't: create it!
+  if (! exist (prefix, "dir"))
+    warning ("creating installation directory %s", prefix);
+    [status, msg] = mkdir (prefix);
+    if (status != 1)
+      error ("could not create installation directory: %s", msg);
+    endif
+  endif
+
+  ## Get the list of installed packages.
+  [local_packages, global_packages] = installed_packages (local_list, 
+							  global_list);
+
+  installed_pkgs_lst = {local_packages{:}, global_packages{:}};        
+
+  if (global_install)
+    packages = global_packages;
+  else
+    packages = local_packages;
+  endif
+
+  ## Uncompress the packages and read the DESCRIPTION files.
+  tmpdirs = packdirs = descriptions = {};
+  try
+    ## Warn about non existent files.
+    for i = 1:length (files)
+      if (isempty (glob(files{i}))) 
+	warning ("file %s does not exist", files{i});
+      endif
+    endfor
+
+    ## Unpack the package files and read the DESCRIPTION files.
+    files = glob (files);
+    packages_to_uninstall = [];
+    for i = 1:length (files)
+      tgz = files{i};
+
+      if (exist (tgz, "file"))
+	## Create a temporary directory.
+	tmpdir = tmpnam ();
+	tmpdirs{end+1} = tmpdir;
+        if (verbose)
+	  printf ("mkdir (%s)\n", tmpdir);
+	endif
+	[status, msg] = mkdir (tmpdir);
+	if (status != 1)
+	  error ("couldn't create temporary directory: %s", msg);
+	endif
+
+	## Uncompress the package.
+	if (verbose)
+	  printf ("untar (%s, %s)\n", tgz, tmpdir);
+	endif
+	untar (tgz, tmpdir);
+
+	## Get the name of the directories produced by tar.
+	[dirlist, err, msg] = readdir (tmpdir);
+	if (err)
+	  error ("couldn't read directory produced by tar: %s", msg);
+	endif
+
+	if (length (dirlist) > 3)
+	  error ("bundles of packages are not allowed")
+	endif
+      endif
+
+      ## The filename pointed to an uncompressed package to begin with.
+      if (exist (tgz, "dir"))
+	dirlist = {".", "..", tgz};
+      endif
+
+      if (exist (tgz, "file") || exist (tgz, "dir"))
+	## The two first entries of dirlist are "." and "..".
+	if (exist (tgz, "file"))
+	  packdir = fullfile (tmpdir, dirlist{3});
+	else
+	  packdir = fullfile (pwd(), dirlist{3});
+	endif
+	packdirs{end+1} = packdir;
+	
+	## Make sure the package contains necessary files.
+	verify_directory (packdir);
+	
+	## Read the DESCRIPTION file.
+	filename = fullfile (packdir, "DESCRIPTION");
+	desc = get_description (filename);
+	
+	## Verify that package name corresponds with filename.
+	[dummy, nm] = fileparts (tgz); 
+	if ((length (nm) >= length (desc.name))
+	    && ! strcmp (desc.name, nm(1:length(desc.name))))
+	  error ("package name '%s' doesn't correspond to its filename '%s'", 
+		 desc.name, nm);
+	endif
+	
+	## Set default installation directory.
+	desc.dir = fullfile (prefix, cstrcat (desc.name, "-", desc.version));
+	
+	## Set default architectire dependent installation directory.
+	desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-",
+							 desc.version));
+	
+	## Save desc.
+	descriptions{end+1} = desc;
+	
+	## Are any of the new packages already installed?
+	## If so we'll remove the old version.
+	for j = 1:length (packages)
+	  if (strcmp (packages{j}.name, desc.name))
+	    packages_to_uninstall(end+1) = j;
+	  endif
+	endfor
+      endif
+    endfor
+  catch
+    ## Something went wrong, delete tmpdirs.
+    for i = 1:length (tmpdirs)
+      rm_rf (tmpdirs{i});
+    endfor
+    rethrow (lasterror ());
+  end_try_catch
+
+  ## Check dependencies.
+  if (handle_deps)
+    ok = true;
+    error_text = "";
+    for i = 1:length (descriptions)
+      desc = descriptions{i};
+      idx2 = complement (i, 1:length(descriptions));
+      if (global_install)
+	## Global installation is not allowed to have dependencies on locally
+	## installed packages.
+	idx1 = complement (packages_to_uninstall, 
+			   1:length(global_packages));
+	pseudo_installed_packages = {global_packages{idx1}, ...
+				     descriptions{idx2}};
+      else
+	idx1 = complement (packages_to_uninstall, 
+			   1:length(local_packages));
+	pseudo_installed_packages = {local_packages{idx1}, ... 
+				     global_packages{:}, ...
+				     descriptions{idx2}};
+      endif
+      bad_deps = get_unsatisfied_deps (desc, pseudo_installed_packages);
+      ## Are there any unsatisfied dependencies?
+      if (! isempty (bad_deps))
+	ok = false;
+	for i = 1:length (bad_deps)
+	  dep = bad_deps{i};
+	  error_text = cstrcat (error_text, " ", desc.name, " needs ",
+			       dep.package, " ", dep.operator, " ",
+			       dep.version, "\n");
+	endfor
+      endif
+    endfor
+
+    ## Did we find any unsatisfied dependencies?
+    if (! ok)
+      error ("the following dependencies where unsatisfied:\n  %s", error_text);
+    endif
+  endif
+
+  ## Prepare each package for installation.
+  try
+    for i = 1:length (descriptions)
+      desc = descriptions{i};
+      pdir = packdirs{i};
+      prepare_installation (desc, pdir);
+      configure_make (desc, pdir, verbose);
+    endfor
+  catch
+    ## Something went wrong, delete tmpdirs.
+    for i = 1:length (tmpdirs)
+      rm_rf (tmpdirs{i});
+    endfor
+    rethrow (lasterror ());
+  end_try_catch
+
+  ## Uninstall the packages that will be replaced.
+  try
+    for i = packages_to_uninstall
+      if (global_install)
+	uninstall ({global_packages{i}.name}, false, verbose, local_list, 
+		   global_list, global_install);
+      else
+	uninstall ({local_packages{i}.name}, false, verbose, local_list, 
+		   global_list, global_install);
+      endif
+    endfor
+  catch
+    ## Something went wrong, delete tmpdirs.
+    for i = 1:length (tmpdirs)
+      rm_rf (tmpdirs{i});
+    endfor
+    rethrow (lasterror ());
+  end_try_catch
+
+  ## Install each package.
+  try
+    for i = 1:length (descriptions)
+      desc = descriptions{i};
+      pdir = packdirs{i};
+      copy_files (desc, pdir, global_install);
+      create_pkgadddel (desc, pdir, "PKG_ADD", global_install);
+      create_pkgadddel (desc, pdir, "PKG_DEL", global_install);
+      finish_installation (desc, pdir, global_install);
+      generate_lookfor_cache (desc);
+    endfor
+  catch
+    ## Something went wrong, delete tmpdirs.
+    for i = 1:length (tmpdirs)
+      rm_rf (tmpdirs{i});
+    endfor
+    for i = 1:length (descriptions)
+      rm_rf (descriptions{i}.dir);
+      rm_rf (getarchdir (descriptions{i}));
+    endfor
+    rethrow (lasterror ());
+  end_try_catch
+
+  ## Check if the installed directory is empty. If it is remove it
+  ## from the list.
+  for i = length (descriptions):-1:1
+    if (dirempty (descriptions{i}.dir, {"packinfo", "doc"}) &&
+	dirempty (getarchdir (descriptions{i})))
+      warning ("package %s is empty\n", descriptions{i}.name);
+      rm_rf (descriptions{i}.dir);
+      rm_rf (getarchdir (descriptions{i}));
+      descriptions(i) = [];
+    endif
+  endfor
+
+  ## If the package requested that it is autoloaded, or the installer
+  ## requested that it is, then mark the package as autoloaded.
+  for i = length (descriptions):-1:1
+    if (autoload > 0 || (autoload == 0 && isautoload (descriptions(i))))
+      fclose (fopen (fullfile (descriptions{i}.dir, "packinfo", 
+			       ".autoload"), "wt"));
+      descriptions{i}.autoload = 1;
+    endif
+  endfor
+
+  ## Add the packages to the package list.
+  try
+    if (global_install)
+      idx = complement (packages_to_uninstall, 1:length(global_packages));
+      global_packages = save_order ({global_packages{idx}, descriptions{:}});
+      save (global_list, "global_packages");
+      installed_pkgs_lst = {local_packages{:}, global_packages{:}};
+    else
+      idx = complement (packages_to_uninstall, 1:length(local_packages));
+      local_packages = save_order ({local_packages{idx}, descriptions{:}});
+      save (local_list, "local_packages");
+      installed_pkgs_lst = {local_packages{:}, global_packages{:}};
+    endif
+  catch
+    ## Something went wrong, delete tmpdirs.
+    for i = 1:length (tmpdirs)
+      rm_rf (tmpdirs{i});
+    endfor
+    for i = 1:length (descriptions)
+      rm_rf (descriptions{i}.dir);
+    endfor
+    if (global_install)
+      printf ("error: couldn't append to %s\n", global_list);
+    else
+      printf ("error: couldn't append to %s\n", local_list);
+    endif
+    rethrow (lasterror ());
+  end_try_catch
+
+  ## All is well, let's clean up.
+  for i = 1:length (tmpdirs)
+    [status, msg] = rm_rf (tmpdirs{i});
+    if (status != 1)
+      warning ("couldn't clean up after my self: %s\n", msg);
+    endif
+  endfor
+
+  ## Add the newly installed packages to the path, so the user
+  ## can begin using them. Only load them if they are marked autoload.
+  if (length (descriptions) > 0)
+    idx = [];
+    for i = 1:length (descriptions)
+      if (isautoload (descriptions(i)))
+	nm = descriptions{i}.name;
+	for j = 1:length (installed_pkgs_lst)
+	  if (strcmp (nm, installed_pkgs_lst{j}.name))
+	    idx (end + 1) = j;
+	    break;
+	  endif
+	endfor
+      endif
+    endfor
+    load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst,
+				    global_install);
+  endif
+endfunction
+
+function uninstall (pkgnames, handle_deps, verbose, local_list, 
+		    global_list, global_install)
+  ## Get the list of installed packages.
+  [local_packages, global_packages] = installed_packages(local_list, 
+							 global_list);
+  if (global_install)
+    installed_pkgs_lst = {local_packages{:}, global_packages{:}};
+  else
+    installed_pkgs_lst = local_packages;
+  endif
+
+  num_packages = length (installed_pkgs_lst);
+  delete_idx = [];
+  for i = 1:num_packages
+    cur_name = installed_pkgs_lst{i}.name;
+    if (any (strcmp (cur_name, pkgnames)))
+      delete_idx(end+1) = i;
+    endif
+  endfor
+
+  ## Are all the packages that should be uninstalled already installed?
+  if (length (delete_idx) != length (pkgnames))
+    if (global_install)
+      ## Try again for a locally installed package.
+      installed_pkgs_lst = local_packages;
+
+      num_packages = length (installed_pkgs_lst);
+      delete_idx = [];
+      for i = 1:num_packages
+	cur_name = installed_pkgs_lst{i}.name;
+	if (any (strcmp (cur_name, pkgnames)))
+	  delete_idx(end+1) = i;
+	endif
+      endfor
+      if (length (delete_idx) != length (pkgnames))
+	## FIXME: We should have a better error message.
+	warning ("some of the packages you want to uninstall are not installed");
+      endif
+    else
+      ## FIXME: We should have a better error message.
+      warning ("some of the packages you want to uninstall are not installed");
+    endif
+  endif
+
+  ## Compute the packages that will remain installed.
+  idx = complement (delete_idx, 1:num_packages);
+  remaining_packages = {installed_pkgs_lst{idx}};
+
+  ## Check dependencies.
+  if (handle_deps)
+    error_text = "";
+    for i = 1:length (remaining_packages)
+      desc = remaining_packages{i};
+      bad_deps = get_unsatisfied_deps (desc, remaining_packages);
+
+      ## Will the uninstallation break any dependencies?
+      if (! isempty (bad_deps))
+	for i = 1:length (bad_deps)
+	  dep = bad_deps{i};
+	  error_text = cstrcat (error_text, " ", desc.name, " needs ",
+			       dep.package, " ", dep.operator, " ",
+			       dep.version, "\n");
+	endfor
+      endif
+    endfor
+
+    if (! isempty (error_text))
+      error ("the following dependencies where unsatisfied:\n  %s", error_text);
+    endif
+  endif
+
+  ## Delete the directories containing the packages.
+  for i = delete_idx
+    desc = installed_pkgs_lst{i};
+    ## If an 'on_uninstall.m' exist, call it!
+    if (exist (fullfile (desc.dir, "packinfo", "on_uninstall.m"), "file"))
+      wd = pwd ();
+      cd (fullfile (desc.dir, "packinfo"));
+      on_uninstall (desc);
+      cd (wd);
+    endif
+    ## Do the actual deletion.
+    if (desc.loaded)
+      rmpath (desc.dir);
+      if (exist (getarchdir (desc)))
+	rmpath (getarchdir (desc));
+      endif
+    endif
+    if (exist (desc.dir, "dir"))
+      [status, msg] = rm_rf (desc.dir);
+      if (status != 1)
+	error ("couldn't delete directory %s: %s", desc.dir, msg);
+      endif
+      [status, msg] = rm_rf (getarchdir (desc));
+      if (status != 1)
+	error ("couldn't delete directory %s: %s", getarchdir (desc), msg);
+      endif
+      if (dirempty (desc.archprefix))
+	rm_rf (desc.archprefix);
+      endif
+    else
+      warning ("directory %s previously lost", desc.dir);
+    endif
+  endfor
+
+  ## Write a new ~/.octave_packages.
+  if (global_install)
+    if (length (remaining_packages) == 0)
+      unlink (global_list);
+    else
+      global_packages = save_order (remaining_packages);
+      save (global_list, "global_packages");
+    endif
+  else
+    if (length (remaining_packages) == 0)
+      unlink (local_list);
+    else
+      local_packages = save_order (remaining_packages);
+      save (local_list, "local_packages");
+    endif
+  endif
+
+endfunction
+
+function [pkg_desc_list, flag] = describe (pkgnames, verbose, 
+					   local_list, global_list)
+
+  ## Get the list of installed packages.
+  installed_pkgs_lst = installed_packages(local_list, global_list);
+  num_packages = length (installed_pkgs_lst);
+  
+
+  describe_all = false;
+  if (any (strcmp ("all", pkgnames)))
+    describe_all = true;
+    flag(1:num_packages) = {"Not Loaded"};
+    num_pkgnames = num_packages;
+  else
+    num_pkgnames = length (pkgnames);
+    flag(1:num_pkgnames) = {"Not installed"};
+  endif
+
+  for i = 1:num_packages
+    curr_name = installed_pkgs_lst{i}.name;
+    if (describe_all)
+      name_pos = i;
+    else
+      name_pos = find(strcmp (curr_name, pkgnames));
+    endif
+
+    if (! isempty (name_pos))
+      if (installed_pkgs_lst{i}.loaded)
+	flag{name_pos} = "Loaded";
+      else
+	flag{name_pos} = "Not loaded";
+      endif
+
+      pkg_desc_list{name_pos}.name = installed_pkgs_lst{i}.name;
+      pkg_desc_list{name_pos}.version = installed_pkgs_lst{i}.version;
+      pkg_desc_list{name_pos}.description = installed_pkgs_lst{i}.description;
+      pkg_desc_list{name_pos}.provides = parse_pkg_idx (installed_pkgs_lst{i}.dir);
+
+    endif
+  endfor
+
+  non_inst = find (strcmp (flag, "Not installed"));
+  if (! isempty (non_inst))
+    if (nargout < 2)
+      non_inst_str = sprintf (" %s ", pkgnames{non_inst});
+      error ("some packages are not installed: %s", non_inst_str);
+    else
+      pkg_desc_list{non_inst} = struct ("name", {}, "description",  
+					{}, "provides", {});
+    endif
+  endif
+
+  if (nargout == 0)
+    for i = 1:num_pkgnames
+      print_package_description (pkg_desc_list{i}.name,
+				 pkg_desc_list{i}.version,
+				 pkg_desc_list{i}.provides,  
+				 pkg_desc_list{i}.description,
+				 flag{i}, verbose);
+    endfor
+  endif
+
+endfunction
+
+## AUXILIARY FUNCTIONS
+
+## Read an INDEX file.
+function [pkg_idx_struct] = parse_pkg_idx (packdir)
+
+  index_file = fullfile (packdir, "packinfo", "INDEX");
+
+  if (! exist (index_file, "file"))
+    error ("could not find any INDEX file in directory %s, try 'pkg rebuild all' to generate missing INDEX files", packdir);
+  endif    
+
+    
+  [fid, msg] = fopen (index_file, "r");
+  if (fid == -1)
+    error ("the INDEX file %s could not be read: %s", 
+	   index_file, msg);
+  endif
+
+  cat_num = 1;
+  pkg_idx_struct{1}.category = "Uncategorized";
+  pkg_idx_struct{1}.functions = {};
+
+  line = fgetl (fid);
+  while (isempty (strfind (line, ">>")) && ! feof (fid))
+    line = fgetl (fid);
+  endwhile
+
+  while (! feof (fid) || line != -1)
+    if (! any (! isspace (line)) || line(1) == "#" || any (line == "="))
+      ## Comments,  blank lines or comments about unimplemented 
+      ## functions: do nothing
+      ## FIXME: probably comments and pointers to external functions
+      ## could be treated better when printing to screen?
+    elseif (! isempty (strfind (line, ">>")))
+      ## Skip package name and description as they are in DESCRIPTION
+      ## already.
+    elseif (! isspace (line(1)))
+      ## Category.
+      if (! isempty (pkg_idx_struct{cat_num}.functions))
+	pkg_idx_struct{++cat_num}.functions = {};
+      endif
+      pkg_idx_struct{cat_num}.category = deblank (line);
+    else
+      ## Function names.
+      while (any (! isspace (line)))
+	[fun_name, line] = strtok (line);
+	pkg_idx_struct{cat_num}.functions{end+1} = deblank (fun_name);
+      endwhile
+    endif
+    line = fgetl (fid);
+  endwhile
+  fclose (fid);
+endfunction
+
+function print_package_description (pkg_name, pkg_ver, pkg_idx_struct, 
+				    pkg_desc, status, verbose)
+
+  printf ("---\nPackage name:\n\t%s\n", pkg_name);
+  printf ("Version:\n\t%s\n", pkg_ver);
+  printf ("Short description:\n\t%s\n", pkg_desc);
+  printf ("Status:\n\t%s\n", status);
+  if (verbose)
+    printf ("---\nProvides:\n");    
+    for i = 1:length(pkg_idx_struct)
+      if (! isempty (pkg_idx_struct{i}.functions))
+	printf ("%s\n", pkg_idx_struct{i}.category);
+	for j = 1:length(pkg_idx_struct{i}.functions)
+	  printf ("\t%s\n", pkg_idx_struct{i}.functions{j});
+	endfor
+      endif
+    endfor
+  endif
+
+endfunction
+
+
+function pth = absolute_pathname (pth)
+  [status, msg, msgid] = fileattrib (pth);
+  if (status != 1)
+    error ("could not find the file or path %s", pth);
+  else
+    pth = msg.Name;
+  endif
+endfunction
+
+function repackage (builddir, buildlist)
+  packages = installed_packages (buildlist, buildlist);
+
+  wd = pwd();
+  for i = 1 : length(packages)
+    pack = packages{i};
+    unwind_protect
+      cd (builddir);
+      mkdir (pack.name);
+      mkdir (fullfile (pack.name, "inst"));
+      copyfile (fullfile (pack.dir, "*"), fullfile (pack.name, "inst"));
+      movefile (fullfile (pack.name, "inst","packinfo", "*"), pack.name);
+      if (exist (fullfile (pack.name, "inst","packinfo", ".autoload"), "file"))
+	unlink (fullfile (pack.name, "inst","packinfo", ".autoload"));
+      endif
+      rmdir (fullfile (pack.name, "inst", "packinfo"));
+      if (exist (fullfile (pack.name, "inst", "doc"), "dir"))
+	movefile (fullfile (pack.name, "inst", "doc"), pack.name);
+      endif
+      if (exist (fullfile (pack.name, "inst", "bin"), "dir"))
+	movefile (fullfile (pack.name, "inst", "bin"), pack.name);
+      endif
+      archdir = fullfile (pack.archprefix, cstrcat (pack.name, "-",
+			  pack.version), getarch ());
+      if (exist (archdir, "dir"))
+	if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file"))
+	  unlink (fullfile (pack.name, "inst", "PKG_ADD"));
+	endif
+	if (exist (fullfile (pack.name, "inst", "PKG_DEL"), "file"))
+	  unlink (fullfile (pack.name, "inst", "PKG_DEL"));
+	endif
+	if (exist (fullfile (archdir, "PKG_ADD"), "file"))
+	  movefile (fullfile (archdir, "PKG_ADD"), 
+		    fullfile (pack.name, "PKG_ADD"));
+	endif
+	if (exist (fullfile (archdir, "PKG_DEL"), "file"))
+	  movefile (fullfile (archdir, "PKG_DEL"), 
+		    fullfile (pack.name, "PKG_DEL")); 
+	endif
+      else
+	if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file"))
+	  movefile (fullfile (pack.name, "inst", "PKG_ADD"), 
+		    fullfile (pack.name, "PKG_ADD"));
+	endif 
+	if (exist (fullfile (pack.name, "inst", "PKG_DEL"), "file"))
+	  movefile (fullfile (pack.name, "inst", "PKG_DEL"), 
+		    fullfile (pack.name, "PKG_DEL")); 
+	endif	
+      endif	
+      tfile = cstrcat (pack.name, "-", pack.version, ".tar");
+      tar (tfile, pack.name);
+      try 
+	gzip (tfile);
+	unlink (tfile);
+      catch
+	warning ("failed to compress %s", tfile);
+      end_try_catch
+    unwind_protect_cleanup
+      if (exist (pack.name, "dir"))
+	rm_rf (pack.name);
+      endif
+      cd (wd);
+    end_unwind_protect
+  endfor
+endfunction
+
+function auto = isautoload (desc)
+  auto = false;
+  if (isfield (desc{1}, "autoload"))
+    a = desc{1}.autoload;
+    if ((isnumeric (a) && a > 0)
+        || (ischar (a) && (strcmpi (a, "true")
+			 || strcmpi (a, "on")
+			 || strcmpi (a, "yes")
+			 || strcmpi (a, "1"))))
+      auto = true;
+    endif
+  endif
+endfunction
+
+function prepare_installation (desc, packdir)
+  ## Is there a pre_install to call?
+  if (exist (fullfile (packdir, "pre_install.m"), "file"))
+    wd = pwd ();
+    try
+      cd (packdir);
+      pre_install (desc); 
+      cd (wd);
+    catch
+      cd (wd);
+      rethrow (lasterror ());
+    end_try_catch
+  endif
+
+  ## If the directory "inst" doesn't exist, we create it.
+  inst_dir = fullfile (packdir, "inst");
+  if (! exist (inst_dir, "dir"))
+    [status, msg] = mkdir (inst_dir);
+    if (status != 1)
+      rm_rf (desc.dir);
+      error ("the 'inst' directory did not exist and could not be created: %s", 
+	     msg);
+    endif
+  endif
+endfunction
+
+function configure_make (desc, packdir, verbose)   
+  ## Perform ./configure, make, make install in "src".
+  if (exist (fullfile (packdir, "src"), "dir"))
+    src = fullfile (packdir, "src");
+    ## Configure.
+    if (exist (fullfile (src, "configure"), "file"))
+      flags = "";
+      if (isempty (getenv ("CC")))
+        flags = cstrcat (flags, " CC=\"", octave_config_info ("CC"), "\"");
+      endif
+      if (isempty (getenv ("CXX")))
+        flags = cstrcat (flags, " CXX=\"", octave_config_info ("CXX"), "\"");
+      endif
+      if (isempty (getenv ("AR")))
+        flags = cstrcat (flags, " AR=\"", octave_config_info ("AR"), "\"");
+      endif
+      if (isempty (getenv ("RANLIB")))
+        flags = cstrcat (flags, " RANLIB=\"", octave_config_info ("RANLIB"), "\"");
+      endif
+      [status, output] = shell (strcat ("cd '", src, "'; ./configure --prefix=\"",
+                                        desc.dir, "\"", flags));
+      if (status != 0)
+	rm_rf (desc.dir);
+	error ("the configure script returned the following error: %s", output);
+      elseif (verbose)
+	printf("%s", output);
+      endif
+
+    endif
+
+    ## Make.
+    if (exist (fullfile (src, "Makefile"), "file"))
+      [status, output] = shell (cstrcat ("export INSTALLDIR=\"", desc.dir,
+					 "\"; make -C '", src, "'"));
+      if (status != 0)
+	rm_rf (desc.dir);
+	error ("'make' returned the following error: %s", output);
+      elseif (verbose)
+	printf("%s", output);
+      endif
+    endif
+
+    ## Copy files to "inst" and "inst/arch" (this is instead of 'make
+    ## install').
+    files = fullfile (src, "FILES");
+    instdir = fullfile (packdir, "inst");
+    archdir = fullfile (packdir, "inst", getarch ());
+
+    ## Get file names.
+    if (exist (files, "file"))
+      [fid, msg] = fopen (files, "r");
+      if (fid < 0)
+	error ("couldn't open %s: %s", files, msg);
+      endif
+      filenames = char (fread (fid))';
+      fclose (fid);
+      if (filenames(end) == "\n")
+	filenames(end) = [];
+      endif
+      filenames = split_by (filenames, "\n");
+      delete_idx =  [];
+      for i = 1:length (filenames)
+	if (! all (isspace (filenames{i})))
+	  filenames{i} = fullfile (src, filenames{i});
+	else
+	  delete_idx(end+1) = i;
+	endif
+      endfor
+      filenames(delete_idx) = [];
+    else
+      m = dir (fullfile (src, "*.m"));
+      oct = dir (fullfile (src, "*.oct"));
+      mex = dir (fullfile (src, "*.mex"));
+
+      filenames = cellfun (@(x) fullfile (src, x),
+			   {m.name, oct.name, mex.name},
+			   "UniformOutput", false);
+    endif
+
+    ## Split into architecture dependent and independent files.
+    if (isempty (filenames))
+      idx = [];
+    else
+      idx = cellfun (@is_architecture_dependent, filenames);
+    endif
+    archdependent = filenames (idx);
+    archindependent = filenames (!idx);
+
+    ## Copy the files.
+    if (! all (isspace ([filenames{:}])))
+	if (! exist (instdir, "dir")) 
+	  mkdir (instdir);
+	endif
+	if (! all (isspace ([archindependent{:}])))
+	  if (verbose)
+	    printf ("copyfile");
+	    printf (" %s", archindependent{:});
+	    printf ("%s\n", instdir);
+	  endif
+	  [status, output] = copyfile (archindependent, instdir);
+	  if (status != 1)
+	    rm_rf (desc.dir);
+	    error ("Couldn't copy files from 'src' to 'inst': %s", output);
+	  endif
+        endif
+	if (! all (isspace ([archdependent{:}])))
+	  if (verbose)
+	    printf ("copyfile");
+	    printf (" %s", archdependent{:});
+	    printf (" %s\n", archdir);
+	  endif
+	  if (! exist (archdir, "dir")) 
+	    mkdir (archdir);
+	  endif
+	  [status, output] = copyfile (archdependent, archdir);
+	  if (status != 1)
+	    rm_rf (desc.dir);
+	    error ("Couldn't copy files from 'src' to 'inst': %s", output);
+	  endif
+        endif
+    endif
+  endif
+endfunction
+
+function pkg = extract_pkg (nm, pat)
+  fid = fopen (nm, "rt");
+  pkg = "";
+  if (fid >= 0)
+    while (! feof (fid))
+      ln = fgetl (fid);
+      if (ln > 0)
+	t = regexp (ln, pat, "tokens");
+	if (! isempty (t))
+          pkg = cstrcat (pkg, "\n", t{1}{1});
+	endif
+      endif
+    endwhile
+    if (! isempty (pkg))
+      pkg = cstrcat (pkg, "\n");
+    endif
+    fclose (fid);
+  endif
+endfunction
+
+function create_pkgadddel (desc, packdir, nm, global_install)
+  instpkg = fullfile (desc.dir, nm);
+  instfid = fopen (instpkg, "wt");
+  ## If it is exists, most of the  PKG_* file should go into the 
+  ## architecture dependent directory so that the autoload/mfilename 
+  ## commands work as expected. The only part that doesn't is the
+  ## part in the main directory.
+  archdir = fullfile (getarchprefix (desc), cstrcat (desc.name, "-",
+		      desc.version), getarch ());
+  if (exist (getarchdir (desc, global_install), "dir"))
+    archpkg = fullfile (getarchdir (desc, global_install), nm);
+    archfid = fopen (archpkg, "at");
+  else
+    archpkg = instpkg;
+    archfid = instfid;
+  endif
+
+  if (archfid >= 0 && instfid >= 0)
+    ## Search all dot-m files for PKG commands.
+    lst = dir (fullfile (packdir, "inst", "*.m"));
+    for i = 1:length (lst)
+      nam = fullfile (packdir, "inst", lst(i).name);
+      fwrite (instfid, extract_pkg (nam, ['^[#%][#%]* *' nm ': *(.*)$']));
+    endfor
+
+    ## Search all C++ source files for PKG commands.
+    lst = dir (fullfile (packdir, "src", "*.cc"));
+    for i = 1:length (lst)
+      nam = fullfile (packdir, "src", lst(i).name);
+      fwrite (archfid, extract_pkg (nam, ['^//* *' nm ': *(.*)$']));
+      fwrite (archfid, extract_pkg (nam, ['^/\** *' nm ': *(.*) *\*/$']));
+    endfor
+
+    ## Add developer included PKG commands.
+    packdirnm = fullfile (packdir, nm);
+    if (exist (packdirnm, "file"))
+      fid = fopen (packdirnm, "rt");
+      if (fid >= 0)
+        while (! feof (fid))
+          ln = fgets (fid);
+          if (ln > 0)
+            fwrite (archfid, ln);
+          endif
+        endwhile
+        fclose (fid);
+      endif
+    endif
+
+    ## If the files is empty remove it.
+    fclose (instfid);
+    t = dir (instpkg);
+    if (t.bytes <= 0)
+      unlink (instpkg);
+    endif
+
+    if (instfid != archfid)
+      fclose (archfid);
+      t = dir (archpkg);
+      if (t.bytes <= 0)
+        unlink (archpkg);
+      endif
+    endif
+  endif
+endfunction
+
+function copy_files (desc, packdir, global_install)
+  ## Create the installation directory.
+  if (! exist (desc.dir, "dir"))
+    [status, output] = mkdir (desc.dir);
+    if (status != 1)
+      error ("couldn't create installation directory %s : %s", 
+      desc.dir, output);
+    endif
+  endif
+
+  octfiledir = getarchdir (desc);
+
+  ## Copy the files from "inst" to installdir.
+  instdir = fullfile (packdir, "inst");
+  if (! dirempty (instdir))
+    [status, output] = copyfile (fullfile (instdir, "*"), desc.dir);
+    if (status != 1)
+      rm_rf (desc.dir);
+      error ("couldn't copy files to the installation directory");
+    endif
+    if (exist (fullfile (desc.dir, getarch ()), "dir") &&
+	! strcmp (fullfile (desc.dir, getarch ()), octfiledir))
+      if (! exist (octfiledir, "dir"))
+        ## Can be required to create upto three levels of dirs.
+        octm1 = fileparts (octfiledir);
+        if (! exist (octm1, "dir"))
+          octm2 = fileparts (octm1);
+          if (! exist (octm2, "dir"))
+            octm3 = fileparts (octm2);
+            if (! exist (octm3, "dir"))
+              [status, output] = mkdir (octm3);
+              if (status != 1)
+                rm_rf (desc.dir);
+                error ("couldn't create installation directory %s : %s", 
+                       octm3, output);
+              endif
+            endif
+            [status, output] = mkdir (octm2);
+            if (status != 1)
+              rm_rf (desc.dir);
+              error ("couldn't create installation directory %s : %s", 
+                     octm2, output);
+            endif
+          endif
+          [status, output] = mkdir (octm1);
+          if (status != 1)
+            rm_rf (desc.dir);
+            error ("couldn't create installation directory %s : %s", 
+                   octm1, output);
+          endif
+        endif
+        [status, output] = mkdir (octfiledir);
+        if (status != 1)
+          rm_rf (desc.dir);
+          error ("couldn't create installation directory %s : %s", 
+          octfiledir, output);
+        endif
+      endif
+      [status, output] = movefile (fullfile (desc.dir, getarch (), "*"), 
+				   octfiledir);
+      rm_rf (fullfile (desc.dir, getarch ()));
+
+      if (status != 1)
+        rm_rf (desc.dir);
+        rm_rf (octfiledir);
+        error ("couldn't copy files to the installation directory");
+      endif
+    endif
+
+  endif
+
+  ## Create the "packinfo" directory.
+  packinfo = fullfile (desc.dir, "packinfo");
+  [status, msg] = mkdir (packinfo);
+  if (status != 1)
+    rm_rf (desc.dir);
+    rm_rf (octfiledir);
+    error ("couldn't create packinfo directory: %s", msg);
+  endif
+
+  ## Copy DESCRIPTION.
+  [status, output] = copyfile (fullfile (packdir, "DESCRIPTION"), packinfo);
+  if (status != 1)
+    rm_rf (desc.dir);
+    rm_rf (octfiledir);
+    error ("couldn't copy DESCRIPTION: %s", output);
+  endif
+
+  ## Copy COPYING.
+  [status, output] = copyfile (fullfile (packdir, "COPYING"), packinfo);
+  if (status != 1)
+    rm_rf (desc.dir);
+    rm_rf (octfiledir);
+    error ("couldn't copy COPYING: %s", output);
+  endif
+
+  ## If the file ChangeLog exists, copy it.
+  changelog_file = fullfile (packdir, "ChangeLog");
+  if (exist (changelog_file, "file"))
+    [status, output] = copyfile (changelog_file, packinfo);
+    if (status != 1)
+      rm_rf (desc.dir);
+      rm_rf (octfiledir);
+      error ("couldn't copy ChangeLog file: %s", output);
+    endif
+  endif
+
+  ## Is there an INDEX file to copy or should we generate one?
+  index_file = fullfile (packdir, "INDEX");
+  if (exist(index_file, "file"))
+    [status, output] = copyfile (index_file, packinfo);
+    if (status != 1)
+      rm_rf (desc.dir);
+      rm_rf (octfiledir);
+      error ("couldn't copy INDEX file: %s", output);
+    endif
+  else
+    try
+      write_index (desc, fullfile (packdir, "inst"),
+		   fullfile (packinfo, "INDEX"), global_install);
+    catch
+      rm_rf (desc.dir);
+      rm_rf (octfiledir);
+      rethrow (lasterror ());
+    end_try_catch
+  endif
+
+  ## Is there an 'on_uninstall.m' to install?
+  fon_uninstall = fullfile (packdir, "on_uninstall.m");
+  if (exist (fon_uninstall, "file"))
+    [status, output] = copyfile (fon_uninstall, packinfo);
+    if (status != 1)
+      rm_rf (desc.dir);
+      rm_rf (octfiledir);
+      error ("couldn't copy on_uninstall.m: %s", output);
+    endif
+  endif
+
+  ## Is there a doc/ directory that needs to be installed?
+  docdir = fullfile (packdir, "doc");
+  if (exist (docdir, "dir") && ! dirempty (docdir))
+    [status, output] = copyfile (docdir, desc.dir);
+  endif
+
+  ## Is there a bin/ directory that needs to be installed?
+  ## FIXME: Need to treat architecture dependent files in bin/
+  bindir = fullfile (packdir, "bin");
+  if (exist (bindir, "dir") && ! dirempty (bindir))
+    [status, output] = copyfile (bindir, desc.dir);
+  endif
+endfunction
+
+function finish_installation (desc, packdir, global_install)
+  ## Is there a post-install to call?
+  if (exist (fullfile (packdir, "post_install.m"), "file"))
+    wd = pwd ();
+    try
+      cd (packdir);
+      post_install (desc);
+      cd (wd);
+    catch
+      cd (wd);
+      rm_rf (desc.dir);
+      rm_rf (getarchdir (desc), global_install);
+      rethrow (lasterror ());
+    end_try_catch
+  endif
+endfunction
+
+function generate_lookfor_cache (desc)
+  dirs = split_by (genpath (desc.dir), pathsep ());
+  for i = 1 : length (dirs)
+    gen_doc_cache (fullfile (dirs{i}, "doc-cache"), dirs{i});
+  endfor
+endfunction
+
+## Make sure the package contains the essential files.
+function verify_directory (dir)
+  needed_files = {"COPYING", "DESCRIPTION"};
+  for f = needed_files
+    if (! exist (fullfile (dir, f{1}), "file"))
+      error ("package is missing file: %s", f{1});
+    endif
+  endfor
+endfunction
+
+## Parse the DESCRIPTION file.
+function desc = get_description (filename)
+  [fid, msg] = fopen (filename, "r");
+  if (fid == -1)
+    error ("the DESCRIPTION file %s could not be read: %s", filename, msg);
+  endif
+
+  desc = struct ();
+
+  line = fgetl (fid);
+  while (line != -1)
+    if (line(1) == "#")
+      ## Comments, do nothing.
+    elseif (isspace(line(1)))
+      ## Continuation lines
+      if (exist ("keyword", "var") && isfield (desc, keyword))
+	desc.(keyword) = cstrcat (desc.(keyword), " ", rstrip(line));
+      endif
+    else
+      ## Keyword/value pair
+      colon = find (line == ":");
+      if (length (colon) == 0)
+	disp ("skipping line");
+      else
+	colon = colon(1);
+	keyword = tolower (strip (line(1:colon-1)));
+	value = strip (line (colon+1:end));
+	if (length (value) == 0)
+	    fclose (fid);
+	    error ("the keyword %s has an empty value", desc.keywords{end});
+	endif
+	desc.(keyword) = value;
+      endif
+    endif
+    line = fgetl (fid);
+  endwhile
+  fclose (fid);
+
+  ## Make sure all is okay.
+  needed_fields = {"name", "version", "date", "title", ...
+		   "author", "maintainer", "description"};
+  for f = needed_fields
+    if (! isfield (desc, f{1}))
+      error ("description is missing needed field %s", f{1});
+    endif
+  endfor
+  desc.version = fix_version (desc.version);
+  if (isfield (desc, "depends"))
+    desc.depends = fix_depends (desc.depends);
+  else
+    desc.depends = "";
+  endif
+  desc.name = tolower (desc.name);
+endfunction
+
+## Make sure the version string v is a valid x.y.z version string
+## Examples: "0.1" => "0.1.0", "monkey" => error(...).
+function out = fix_version (v)
+  dots = find (v == ".");
+  if (length (dots) == 1)
+    major = str2num (v(1:dots-1));
+    minor = str2num (v(dots+1:end));
+    if (length (major) != 0 && length (minor) != 0)
+      out = sprintf ("%d.%d.0", major, minor);
+      return;
+    endif
+  elseif (length (dots) == 2)
+    major = str2num (v(1:dots(1)-1));
+    minor = str2num (v(dots(1)+1:dots(2)-1));
+    rev = str2num (v(dots(2)+1:end));
+    if (length (major) != 0 && length (minor) != 0 && length (rev) != 0)
+      out = sprintf ("%d.%d.%d", major, minor, rev);
+      return;
+    endif
+  endif
+  error ("bad version string: %s", v);
+endfunction
+
+## Make sure the depends field is of the right format.
+## This function returns a cell of structures with the following fields:
+##   package, version, operator
+function deps_cell = fix_depends (depends)
+  deps = split_by (tolower (depends), ",");
+  deps_cell = cell (1, length (deps));
+
+  ## For each dependency.
+  for i = 1:length (deps)
+    dep = deps{i};
+    lpar = find (dep == "(");
+    rpar = find (dep == ")");
+    ## Does the dependency specify a version
+    ## Example: package(>= version).
+    if (length (lpar) == 1 && length (rpar) == 1)
+      package = tolower (strip (dep(1:lpar-1)));
+      sub = dep(lpar(1)+1:rpar(1)-1);
+      parts = strsplit (sub, " ", true);
+      if (length (parts) != 2)
+	error ("incorrect syntax for dependency `%s' in the DESCRIPTION file\n",
+	       dep);
+      endif
+      operator = parts{1};
+      if (! any (strcmp (operator, {">", ">=", "<=", "<", "=="})))
+	error ("unsupported operator: %s", operator);
+      endif
+      version  = fix_version (parts{2});
+
+  ## If no version is specified for the dependency
+  ## we say that the version should be greater than 
+  ## or equal to "0.0.0".
+  else
+    package = tolower (strip (dep));
+    operator = ">=";
+    version  = "0.0.0";
+  endif
+  deps_cell{i} = struct ("package", package, "operator", operator,
+			 "version", version);
+  endfor
+endfunction
+
+## Strip the text of spaces from the right
+## Example: "  hello world  " => "  hello world"
+## FIXME -- is this the same as deblank?
+function text = rstrip (text)
+  chars = find (! isspace (text));
+  if (length (chars) > 0)
+    ## FIXME: shouldn't it be text = text(1:chars(end));
+    text = text (chars(1):end);
+  else
+    text = "";
+  endif
+endfunction
+
+## Strip the text of spaces from the left and the right.
+## Example: "  hello world  " => "hello world"
+function text = strip (text)
+  chars = find (! isspace (text));
+  if (length (chars) > 0)
+    text = text(chars(1):chars(end));
+  else
+    text = "";
+  endif
+endfunction
+
+## Split the text into a cell array of strings by sep.
+## Example: "A, B" => {"A", "B"} (with sep = ",")
+function out = split_by (text, sep)
+  out = strtrim (strsplit (text, sep));
+endfunction
+
+## Create an INDEX file for a package that doesn't provide one.
+##   'desc'  describes the package.
+##   'dir'   is the 'inst' directory in temporary directory.
+##   'index_file' is the name (including path) of resulting INDEX file.
+function write_index (desc, dir, index_file, global_install)
+  ## Get names of functions in dir
+  [files, err, msg] = readdir (dir);
+  if (err)
+    error ("couldn't read directory %s: %s", dir, msg);
+  endif
+
+  ## Check for architecture dependent files.
+  tmpdir = getarchdir (desc);
+  if (exist (tmpdir, "dir"))
+    [files2, err, msg] = readdir (tmpdir);
+    if (err)
+      error ("couldn't read directory %s: %s", tmpdir, msg);
+    endif
+    files = [files; files2];    
+  endif
+
+  functions = {};
+  for i = 1:length (files)
+    file = files{i};
+    lf = length (file);
+    if (lf > 2 && strcmp (file(end-1:end), ".m"))
+      functions{end+1} = file(1:end-2);
+    elseif (lf > 4 && strcmp (file(end-3:end), ".oct"))
+      functions{end+1} = file(1:end-4);
+    endif
+  endfor
+
+  ## Does desc have a categories field?
+  if (! isfield (desc, "categories"))
+    error ("the DESCRIPTION file must have a Categories field, when no INDEX file is given");
+  endif
+  categories = split_by (desc.categories, ",");
+  if (length (categories) < 1)
+      error ("the Category field is empty");
+  endif
+
+  ## Write INDEX.
+  fid = fopen (index_file, "w");
+  if (fid == -1)
+    error ("couldn't open %s for writing.", index_file);
+  endif
+  fprintf (fid, "%s >> %s\n", desc.name, desc.title);
+  fprintf (fid, "%s\n", categories{1});
+  fprintf (fid, "  %s\n", functions{:});
+  fclose (fid);
+endfunction
+
+function bad_deps = get_unsatisfied_deps (desc, installed_pkgs_lst)
+  bad_deps = {};
+
+  ## For each dependency.
+  for i = 1:length (desc.depends)
+    dep = desc.depends{i};
+
+    ## Is the current dependency Octave?
+    if (strcmp (dep.package, "octave"))
+      if (! compare_versions (OCTAVE_VERSION, dep.version, dep.operator))
+        bad_deps{end+1} = dep;
+      endif
+      ## Is the current dependency not Octave?
+    else
+      ok = false;
+      for i = 1:length (installed_pkgs_lst)
+	cur_name = installed_pkgs_lst{i}.name;
+	cur_version = installed_pkgs_lst{i}.version;
+	if (strcmp (dep.package, cur_name)
+	    && compare_versions (cur_version, dep.version, dep.operator))
+	  ok = true;
+	  break;
+	endif
+      endfor
+      if (! ok)
+        bad_deps{end+1} = dep;
+      endif
+    endif
+  endfor
+endfunction
+
+function [out1, out2] = installed_packages (local_list, global_list)
+  ## Get the list of installed packages.
+  try
+    local_packages = load (local_list).local_packages;
+  catch
+    local_packages = {};
+  end_try_catch
+  try
+    global_packages = load (global_list).global_packages;
+  catch
+    global_packages = {};
+  end_try_catch
+  installed_pkgs_lst = {local_packages{:}, global_packages{:}};
+
+  ## Eliminate duplicates in the installed package list.
+  ## Locally installed packages take precedence.
+  dup = [];
+  for i = 1:length (installed_pkgs_lst)
+    if (find (dup, i))
+      continue;
+    endif
+    for j = (i+1):length (installed_pkgs_lst)
+      if (find (dup, j))
+	continue;
+      endif
+      if (strcmp (installed_pkgs_lst{i}.name, installed_pkgs_lst{j}.name))
+	dup = [dup, j];
+      endif
+    endfor
+  endfor
+  if (! isempty(dup))
+    installed_pkgs_lst(dup) = [];
+  endif  
+
+  ## Now check if the package is loaded.
+  tmppath = strrep (path(), "\\", "/");
+  for i = 1:length (installed_pkgs_lst)
+    if (findstr (tmppath, strrep (installed_pkgs_lst{i}.dir, "\\", "/")))
+      installed_pkgs_lst{i}.loaded = true;
+    else
+      installed_pkgs_lst{i}.loaded = false;
+    endif
+  endfor
+  for i = 1:length (local_packages)
+    if (findstr (tmppath, strrep (local_packages{i}.dir, "\\", "/")))
+      local_packages{i}.loaded = true;
+    else
+      local_packages{i}.loaded = false;
+    endif
+  endfor
+  for i = 1:length (global_packages)
+    if (findstr (tmppath, strrep (global_packages{i}.dir, "\\", "/")))
+      global_packages{i}.loaded = true;
+    else
+      global_packages{i}.loaded = false;
+    endif
+  endfor
+
+  ## Should we return something?
+  if (nargout == 2)
+    out1 = local_packages;
+    out2 = global_packages;
+    return;
+  elseif (nargout == 1)
+    out1 = installed_pkgs_lst;
+    return;
+  endif
+
+  ## We shouldn't return something, so we'll print something.
+  num_packages = length (installed_pkgs_lst);
+  if (num_packages == 0)
+    printf ("no packages installed.\n");
+    return;
+  endif
+
+  ## Compute the maximal lengths of name, version, and dir.
+  h1 = "Package Name";
+  h2 = "Version";
+  h3 = "Installation directory";
+  max_name_length = length (h1); 
+  max_version_length = length (h2);
+  names = cell (num_packages, 1); 
+  for i = 1:num_packages
+    max_name_length = max (max_name_length,
+			   length (installed_pkgs_lst{i}.name));
+    max_version_length = max (max_version_length,
+			      length (installed_pkgs_lst{i}.version));
+    names{i} = installed_pkgs_lst{i}.name;
+  endfor
+  max_dir_length = terminal_size()(2) - max_name_length - ...
+					     max_version_length - 7;
+  if (max_dir_length < 20)
+     max_dir_length = Inf;
+  endif
+
+  h1 = postpad (h1, max_name_length + 1, " ");
+  h2 = postpad (h2, max_version_length, " ");;
+
+  ## Print a header.
+  header = sprintf("%s | %s | %s\n", h1, h2, h3);
+  printf (header);
+  tmp = sprintf (repmat ("-", 1, length(header)-1));
+  tmp(length(h1)+2) = "+";
+  tmp(length(h1)+length(h2)+5) = "+";
+  printf ("%s\n", tmp);
+
+  ## Print the packages.
+  format = sprintf ("%%%ds %%1s| %%%ds | %%s\n", max_name_length,
+		    max_version_length);
+  [dummy, idx] = sort (names);
+  for i = 1:num_packages
+    cur_name = installed_pkgs_lst{idx(i)}.name;
+    cur_version = installed_pkgs_lst{idx(i)}.version;
+    cur_dir = installed_pkgs_lst{idx(i)}.dir;
+    if (length (cur_dir) > max_dir_length)
+      first_char = length (cur_dir) - max_dir_length + 4;
+      first_filesep = strfind (cur_dir(first_char:end), filesep());
+      if (! isempty (first_filesep))
+        cur_dir = cstrcat ("...", 
+			  cur_dir((first_char + first_filesep(1) - 1):end));
+      else
+        cur_dir = cstrcat ("...", cur_dir(first_char:end));
+      endif
+    endif
+    if (installed_pkgs_lst{idx(i)}.loaded)
+      cur_loaded = "*";
+    else
+      cur_loaded = " ";
+    endif
+    printf (format, cur_name, cur_loaded, cur_version, cur_dir);
+  endfor
+endfunction
+
+function load_packages (files, handle_deps, local_list, global_list)
+  installed_pkgs_lst = installed_packages (local_list, global_list);
+  num_packages = length (installed_pkgs_lst);
+
+  ## Read package names and installdirs into a more convenient format.
+  pnames = pdirs = cell (1, num_packages);
+  for i = 1:num_packages
+    pnames{i} = installed_pkgs_lst{i}.name;
+    pdirs{i} = installed_pkgs_lst{i}.dir;
+  endfor
+
+  ## Load all.
+  if (length (files) == 1 && strcmp (files{1}, "all"))
+    idx = [1:length(installed_pkgs_lst)];
+  ## Load auto.
+  elseif (length (files) == 1 && strcmp (files{1}, "auto")) 
+    idx = [];
+    for i = 1:length (installed_pkgs_lst)
+      if (exist (fullfile (pdirs{i}, "packinfo", ".autoload"), "file"))
+	idx (end + 1) = i;
+      endif
+    endfor
+  ## Load package_name1 ...
+  else
+    idx = [];
+    for i = 1:length (files)
+      idx2 = find (strcmp (pnames, files{i}));
+      if (! any (idx2))
+	  error ("package %s is not installed", files{i});
+      endif
+      idx (end + 1) = idx2;
+    endfor
+  endif
+
+  ## Load the packages, but take care of the ordering of dependencies.
+  load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, true);
+endfunction
+
+function unload_packages (files, handle_deps, local_list, global_list)
+  installed_pkgs_lst = installed_packages (local_list, global_list);
+  num_packages = length (installed_pkgs_lst);
+
+  ## Read package names and installdirs into a more convenient format.
+  pnames = pdirs = cell (1, num_packages);
+  for i = 1:num_packages
+    pnames{i} = installed_pkgs_lst{i}.name;
+    pdirs{i} = installed_pkgs_lst{i}.dir;
+    pdeps{i} = installed_pkgs_lst{i}.depends;
+  endfor
+
+  ## Get the current octave path.
+  p = split_by (path(), pathsep ());
+
+  if (length (files) == 1 && strcmp (files{1}, "all"))
+    ## Unload all.
+    dirs = pdirs;
+    desc = installed_pkgs_lst;
+  else
+    ## Unload package_name1 ...
+    dirs = {};
+    desc = {};
+    for i = 1:length (files)
+      idx = strcmp (pnames, files{i});
+      if (! any (idx))
+	error ("package %s is not installed", files{i});
+      endif
+	dirs{end+1} = pdirs{idx};
+        desc{end+1} = installed_pkgs_lst{idx};
+      endfor
+  endif
+
+  ## Check for architecture dependent directories.
+  archdirs = {};
+  for i = 1:length (dirs)
+    tmpdir = getarchdir (desc{i});
+    if (exist (tmpdir, "dir"))
+      archdirs{end+1} = dirs{i};
+      archdirs{end+1} = tmpdir;
+    else
+      archdirs{end+1} = dirs{i};
+    endif
+  endfor
+
+  ## Unload the packages.
+  for i = 1:length (archdirs)
+    d = archdirs{i};
+    idx = strcmp (p, d);
+    if (any (idx))
+      rmpath (d);
+      ## FIXME: We should also check if we need to remove items from
+      ## EXEC_PATH.
+    endif
+  endfor
+endfunction
+
+function [status_out, msg_out] = rm_rf (dir)
+  if (exist (dir))
+    crr = confirm_recursive_rmdir ();
+    unwind_protect
+      confirm_recursive_rmdir (false);
+      [status, msg] = rmdir (dir, "s");
+    unwind_protect_cleanup
+      confirm_recursive_rmdir (crr);
+    end_unwind_protect
+  else
+    status = 1;
+    msg = "";
+  endif
+  if (nargout > 0)
+    status_out = status;
+  endif
+  if (nargout > 1)
+    msg_out = msg;
+  endif
+endfunction
+
+function emp = dirempty (nm, ign)
+  if (exist (nm, "dir"))
+    if (nargin < 2)
+      ign = {".", ".."};
+    else
+      ign = [{".", ".."}, ign];
+    endif
+    l = dir (nm);
+    for i = 1:length (l)
+      found = false;
+      for j = 1:length (ign)
+        if (strcmp (l(i).name, ign{j}))
+          found = true;
+          break;
+        endif
+      endfor
+      if (! found)
+        emp = false;
+        return
+      endif
+    endfor
+    emp = true;
+  else
+    emp = true;
+  endif
+endfunction
+
+function arch = getarch ()
+  persistent _arch = cstrcat (octave_config_info("canonical_host_type"), ...
+			     "-", octave_config_info("api_version"));
+  arch = _arch;
+endfunction
+
+function archprefix = getarchprefix (desc, global_install)
+  if ((nargin == 2 && global_install) || (nargin < 2 && issuperuser ()))
+    archprefix = fullfile (octave_config_info ("libexecdir"), "octave", 
+			   "packages", cstrcat(desc.name, "-", desc.version));
+  else
+    archprefix = desc.dir;
+  endif
+endfunction
+
+function archdir = getarchdir (desc)
+  archdir = fullfile (desc.archprefix, getarch());
+endfunction
+
+function s = issuperuser ()
+  if ((ispc () && ! isunix ()) || (geteuid() == 0))
+    s = true;
+  else
+    s = false;
+  endif
+endfunction
+
+function [status, output] = shell (cmd)
+  persistent have_sh;
+
+  cmd = strrep (cmd, "\\", "/");
+  if (ispc () && ! isunix ())
+    if (isempty(have_sh))
+      if (system("sh.exe -c \"exit\""))
+        have_sh = false;
+      else
+        have_sh = true;
+      endif
+    endif
+    if (have_sh)
+      [status, output] = system (cstrcat ("sh.exe -c \"", cmd, "\""));
+    else
+      error ("Can not find the command shell")
+    endif
+  else
+    [status, output] = system (cmd);
+  endif
+endfunction
+
+function newdesc = save_order (desc)
+  newdesc = {};
+  for i = 1 : length(desc)
+    deps = desc{i}.depends;
+    if (isempty (deps) || (length (deps) == 1 && 
+			  strcmp(deps{1}.package, "octave")))
+      newdesc {end + 1} = desc{i};
+    else
+      tmpdesc = {};
+      for k = 1 : length (deps)
+        for j = 1 : length (desc)
+          if (strcmp (desc{j}.name, deps{k}.package))
+            tmpdesc{end+1} = desc{j};
+	    break;
+          endif
+        endfor
+      endfor
+      if (! isempty (tmpdesc))					     
+        newdesc = {newdesc{:}, save_order(tmpdesc){:}, desc{i}};
+      else
+        newdesc{end+1} = desc{i};
+      endif
+    endif
+  endfor
+  ## Eliminate the duplicates.
+  idx = [];
+  for i = 1 : length (newdesc)
+    for j = (i + 1) : length (newdesc)
+      if (strcmp (newdesc{i}.name, newdesc{j}.name))
+        idx (end + 1) = j;
+      endif
+    endfor
+  endfor
+  newdesc(idx) = [];
+endfunction
+
+function load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst,
+					 global_install)
+  idx = load_package_dirs (idx, [], handle_deps, installed_pkgs_lst);
+  dirs = {};
+  execpath = EXEC_PATH ();
+  for i = idx;
+    ndir = installed_pkgs_lst{i}.dir;
+    dirs{end+1} = ndir;
+    if (exist (fullfile (dirs{end}, "bin"), "dir"))
+      execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath);
+    endif
+    tmpdir = getarchdir (installed_pkgs_lst{i});
+    if (exist (tmpdir, "dir"))
+      dirs{end + 1} = tmpdir;
+      if (exist (fullfile (dirs{end}, "bin"), "dir"))
+        execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath);
+      endif
+    endif
+  endfor
+
+  ## Load the packages.
+  if (length (dirs) > 0)
+    addpath (dirs{:});
+  endif
+
+  ## Add the binaries to exec_path.
+  if (! strcmp (EXEC_PATH, execpath))
+    EXEC_PATH (execpath);
+  endif
+endfunction
+
+function idx = load_package_dirs (lidx, idx, handle_deps, installed_pkgs_lst)
+  for i = lidx
+    if (isfield (installed_pkgs_lst{i}, "loaded") &&
+	installed_pkgs_lst{i}.loaded)
+      continue;
+    else
+      if (handle_deps)
+        deps = installed_pkgs_lst{i}.depends;
+        if ((length (deps) > 1) || (length (deps) == 1 && 
+	  		  ! strcmp(deps{1}.package, "octave")))
+          tmplidx = [];
+          for k = 1 : length (deps)
+            for j = 1 : length (installed_pkgs_lst)
+              if (strcmp (installed_pkgs_lst{j}.name, deps{k}.package))
+                tmplidx (end + 1) = j;
+	        break;
+              endif
+            endfor
+          endfor
+          idx = load_package_dirs (tmplidx, idx, handle_deps, 
+				 installed_pkgs_lst);
+        endif
+      endif
+      if (isempty (find(idx == i)))
+        idx (end + 1) = i;
+      endif
+    endif
+  endfor
+endfunction
+
+function dep = is_architecture_dependent (nm)
+  persistent archdepsuffix = {".oct",".mex",".a",".lib",".so",".so.*",".dll","dylib"};
+
+  dep = false;
+  for i = 1 : length (archdepsuffix)
+    ext = archdepsuffix{i};
+    if (ext(end) == "*")
+      isglob = true;
+      ext(end) = [];
+    else
+      isglob = false;
+    endif
+    pos = findstr (nm, ext);
+    if (pos)
+      if (! isglob && (length(nm) - pos(end) != length(ext) - 1))
+	continue;
+      endif
+      dep = true;
+      break;
+    endif
+  endfor
+endfunction
diff --git a/scripts/plot/Makefile.in b/scripts/plot/Makefile.in
new file mode 100644
index 0000000..5e9ce85
--- /dev/null
+++ b/scripts/plot/Makefile.in
@@ -0,0 +1,257 @@
+# Makefile for octave's scripts/plot directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008, 2009
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = plot
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = \
+  __actual_axis_position__.m \
+  __add_datasource__.m \
+  __area__.m \
+  __axes_limits__.m \
+  __axis_label__.m \
+  __bar__.m \
+  __bars__.m \
+  __clabel__.m \
+  __contour__.m \
+  __default_plot_options__.m \
+  __errcomm__.m \
+  __errplot__.m \
+  __ezplot__.m \
+  __gnuplot_get_var__.m \
+  __gnuplot_has_feature__.m \
+  __gnuplot_open_stream__.m \
+  __go_close_all__.m \
+  __go_draw_axes__.m \
+  __go_draw_figure__.m \
+  __gnuplot_ginput__.m \
+  __gnuplot_version__.m \
+  __interp_cube__.m \
+  __line__.m \
+  __marching_cube__.m \
+  __next_line_color__.m \
+  __patch__.m \
+  __plr1__.m \
+  __plr2__.m \
+  __plt1__.m \
+  __plt2__.m \
+  __plt2mm__.m \
+  __plt2mv__.m \
+  __plt2ss__.m \
+  __plt2sv__.m \
+  __plt2vm__.m \
+  __plt2vs__.m \
+  __plt2vv__.m \
+  __plt__.m \
+  __plt_get_axis_arg__.m \
+  __pltopt1__.m \
+  __pltopt__.m \
+  __quiver__.m \
+  __scatter__.m \
+  __stem__.m \
+  allchild.m \
+  ancestor.m \
+  area.m \
+  axes.m \
+  axis.m \
+  backend.m \
+  bar.m \
+  barh.m \
+  box.m \
+  caxis.m \
+  cla.m \
+  clabel.m \
+  clf.m \
+  close.m \
+  closereq.m \
+  colorbar.m \
+  comet.m \
+  compass.m \
+  contour3.m \
+  contour.m \
+  contourc.m \
+  contourf.m \
+  cylinder.m \
+  diffuse.m \
+  gnuplot_drawnow.m \
+  ellipsoid.m \
+  errorbar.m \
+  ezcontourf.m \
+  ezcontour.m \
+  ezmeshc.m \
+  ezmesh.m \
+  ezplot.m \
+  ezplot3.m \
+  ezpolar.m \
+  ezsurfc.m \
+  ezsurf.m \
+  feather.m \
+  figure.m \
+  fill.m \
+  findall.m \
+  findobj.m \
+  fplot.m \
+  gca.m \
+  gcbf.m \
+  gcbo.m \
+  gcf.m \
+  ginput.m \
+  grid.m \
+  gtext.m \
+  hggroup.m \
+  hidden.m \
+  hist.m \
+  hold.m \
+  isfigure.m \
+  ishghandle.m \
+  ishold.m \
+  isocolors.m \
+  isonormals.m \
+  isosurface.m \
+  legend.m \
+  line.m \
+  linkprop.m \
+  loglog.m \
+  loglogerr.m \
+  mesh.m \
+  meshc.m \
+  meshgrid.m \
+  meshz.m \
+  ndgrid.m \
+  newplot.m \
+  orient.m \
+  pareto.m \
+  patch.m \
+  pcolor.m \
+  peaks.m \
+  pie.m \
+  plot.m \
+  plotmatrix.m \
+  plotyy.m \
+  plot3.m \
+  plotyy.m \
+  polar.m \
+  print.m \
+  quiver.m \
+  quiver3.m \
+  refresh.m \
+  refreshdata.m \
+  replot.m \
+  ribbon.m \
+  rose.m \
+  scatter.m \
+  scatter3.m \
+  semilogx.m \
+  semilogxerr.m \
+  semilogy.m \
+  semilogyerr.m \
+  shading.m \
+  shg.m \
+  slice.m \
+  sombrero.m \
+  specular.m \
+  sphere.m \
+  spinmap.m \
+  stairs.m \
+  stem.m \
+  stem3.m \
+  subplot.m \
+  surf.m \
+  surface.m \
+  surfc.m \
+  surfl.m \
+  surfnorm.m \
+  text.m \
+  title.m \
+  view.m \
+  waitforbuttonpress.m \
+  xlabel.m \
+  xlim.m \
+  ylabel.m \
+  ylim.m \
+  zlabel.m \
+  zlim.m
+
+SOURCES_IN = gnuplot_binary.in
+
+GEN_M = $(SOURCES_IN:.in=.m)
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES) $(SOURCES_IN))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES)) $(GEN_M)
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: $(GEN_M) PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD $(GEN_M)
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/plot
+.PHONY: dist
+
+$(GEN_M): %.m : %.in $(TOPDIR)/Makeconf
+	@$(do-subst-config-vals)
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/plot/__actual_axis_position__.m b/scripts/plot/__actual_axis_position__.m
new file mode 100644
index 0000000..015beb0
--- /dev/null
+++ b/scripts/plot/__actual_axis_position__.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __actual_axis_position__ (@var{h})
+## @deftypefnx {Function File} {} __actual_axis_position__ (@var{axis_struct})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: Ben Abbott
+
+function pos = __actual_axis_position__ (axis_obj)
+  if (ishandle (axis_obj))
+    axis_obj = get (axis_obj);
+  endif
+
+  ## When using {rltb}margin, Gnuplot does not handle the specified
+  ## aspect ratio properly, so handle it here.
+  if (__calc_dimensions__ (axis_obj) == 3)
+    ## FIXME -- this works for "axis square", but has not been
+    ##          thoroughly tested for other aspect ratios.
+    aspect_ratio_2d = [max(axis_obj.dataaspectratio(1:2)), ...
+			   axis_obj.dataaspectratio(3)/sqrt(2)];
+  else
+    aspect_ratio_2d = axis_obj.dataaspectratio(1:2);
+  endif
+  orig_fig_units = get (axis_obj.parent, "units");
+  orig_fig_position = get (axis_obj.parent, "units");
+  unwind_protect
+    set (axis_obj.parent, "units", "pixels")
+    fig_position = get (axis_obj.parent, "position");
+    pos_in_pixels = axis_obj.position .* fig_position([3, 4, 3, 4]);
+    orig_aspect_ratio_2d = pos_in_pixels(3:4);
+    rel_aspect_ratio_2d =  aspect_ratio_2d ./ orig_aspect_ratio_2d;
+    rel_aspect_ratio_2d = rel_aspect_ratio_2d ./ max (rel_aspect_ratio_2d);
+    if (rel_aspect_ratio_2d(1) < rel_aspect_ratio_2d(2));
+      dx = (1.0 - rel_aspect_ratio_2d(1)) * pos_in_pixels(3);
+      pos_in_pixels = pos_in_pixels + dx*[0.5, 0.0, -1.0, 0.0];
+    elseif (rel_aspect_ratio_2d(1) > rel_aspect_ratio_2d(2))
+      dy = (1.0 - rel_aspect_ratio_2d(2)) * pos_in_pixels(4);
+      pos_in_pixels = pos_in_pixels + dy*[0.0, 0.5, 0.0, -1.0];
+    endif
+    pos = pos_in_pixels ./ fig_position([3, 4, 3, 4]);
+  unwind_protect_cleanup
+    set (axis_obj.parent, "units", orig_fig_units)
+    set (axis_obj.parent, "units", orig_fig_position)
+  end_unwind_protect
+
+endfunction
+
+function nd = __calc_dimensions__ (obj)
+  kids = obj.children;
+  nd = 2;
+  for i = 1:length (kids)
+    obj = get (kids(i));
+    switch (obj.type)
+      case {"image", "text"}
+        ## ignore as they 
+      case {"line", "patch"}
+        if (! isempty (obj.zdata))
+          nd = 3;
+        endif
+      case "surface"
+        nd = 3;
+      case "hggroup"
+        obj_nd = __calc_dimensions__ (obj);
+        if (obj_nd == 3)
+          nd = 3;
+        endif
+    endswitch
+  endfor
+endfunction
+
diff --git a/scripts/plot/__add_datasource__.m b/scripts/plot/__add_datasource__.m
new file mode 100644
index 0000000..2412b02
--- /dev/null
+++ b/scripts/plot/__add_datasource__.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{newargs} =} __add_datasource__ (@var{fcn}, @var{h}, @var{data}, @var{varargin})
+## Undocumented internal function.
+## @end deftypefn
+
+function newargs = __add_datasource__ (fcn, h, data, varargin)
+
+  if (nargin < 3)
+    error ("internal error");
+  endif
+
+  if (ischar (data))
+    data = {data};
+  endif
+
+  for i = 1 : numel (data)
+    addproperty (strcat (data{i}, "datasource"), h, "string", "");
+  endfor
+
+  i = 0;
+  newargs = {};
+  while (i < numel (varargin))
+    arg = varargin{++i};
+    if (i != numel(varargin) && ischar (arg)
+	&& length (arg) > 9 && strcmpi (arg(end-9:end), "datasource"))
+      arg = tolower (arg);
+      val = varargin{++i};
+      if (ischar (val))
+	set (h, arg, val);
+      else
+	error ("%s: expecting data source to be a string", fcn);
+      endif
+    else
+      newargs{end + 1} = arg;
+    endif
+  endwhile
+endfunction
diff --git a/scripts/plot/__area__.m b/scripts/plot/__area__.m
new file mode 100644
index 0000000..6af78fd
--- /dev/null
+++ b/scripts/plot/__area__.m
@@ -0,0 +1,127 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __area__ (@var{ax}, @var{x}, @var{y}, @var{bv}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+function retval = __area__ (ax, x, y, bv, varargin)
+
+  y0 = bv * ones (1, rows (y));
+  y0 = zeros (1, rows (y));
+  retval = [];
+  for i = 1: size (y, 2);
+    hg = hggroup ();
+    retval = [retval; hg];
+    args = __add_datasource__ ("area", hg, {"x", "y"}, varargin{:});
+
+    x1 = x(:, 1).';
+    y1 = y (:, i).';
+    addproperty ("xdata", hg, "data", x1);
+    addproperty ("ydata", hg, "data", y1);
+
+    addlistener (hg, "xdata", @update_data);
+    addlistener (hg, "ydata", @update_data);
+
+    if (i == 1)
+      h = patch (ax, [x1(1), x1, fliplr(x1)], [bv, y1, bv*ones(1, length(y1))],
+		 __next_line_color__ (), "parent", hg);
+    else
+      y1 = y0 + y1;
+      h = patch (ax, [x1(1), x1, fliplr(x1)], [y0(1), y1, fliplr(y0)],
+		 __next_line_color__ (), "parent", hg);
+    endif
+
+    y0 = y1;
+
+    addproperty ("basevalue", hg, "data", bv);
+    addlistener (hg, "basevalue", @move_baseline); 
+
+    addproperty ("edgecolor", hg, "patchedgecolor", get (h, "edgecolor"));
+    addproperty ("linewidth", hg, "patchlinewidth", get (h, "linewidth"));
+    addproperty ("linestyle", hg, "patchlinestyle", get (h, "linestyle"));
+    addproperty ("facecolor", hg, "patchfacecolor", get (h, "facecolor"));
+
+    addlistener (hg, "edgecolor", @update_props);
+    addlistener (hg, "linewidth", @update_props); 
+    addlistener (hg, "linestyle", @update_props); 
+    addlistener (hg, "facecolor", @update_props); 
+
+    addproperty ("areagroup", hg, "data");
+    set (retval, "areagroup", retval);
+
+    if (! isempty (args))
+      set (hg, args{:});
+    endif
+  endfor
+
+endfunction
+
+function update_props (h, d)
+  kids = get (h, "children");
+  set (kids, "edgecolor", get (h, "edgecolor"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"),
+       "facecolor", get (h, "facecolor"));
+endfunction
+
+function move_baseline (h, d)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      hlist = get (h, "areagroup");
+      b0 = get (h, "basevalue");
+
+      for hh = hlist(:)'
+	if (hh != h)
+	  b1 = get (hh, "basevalue");
+	  if (b1 != b0)
+	    set (hh, "basevalue", b0);
+	  endif
+	endif
+      endfor
+      update_data (h, d);
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
+
+function update_data (h, d)
+  hlist = get (h, "areagroup");
+  bv = get (h, "basevalue");
+  for i = 1 : length (hlist)
+    hh = hlist(i);
+    x1 = get (hh, "xdata")(:);
+    y1 = get (hh, "ydata")(:);
+
+    set (get (hh, "children"), "xdata", [x1(1); x1; flipud(x1)]);
+    if (i == 1)
+      set (get (hh, "children"), "ydata", [bv; y1; bv*ones(length(y1), 1)]);
+    else
+      y1 = y0 + y1;
+      set (get (hh, "children"), "ydata", [y0(1); y1; flipud(y0)]);
+    endif      
+
+    y0 = y1;
+  endfor
+endfunction
diff --git a/scripts/plot/__axes_limits__.m b/scripts/plot/__axes_limits__.m
new file mode 100644
index 0000000..a403bd9
--- /dev/null
+++ b/scripts/plot/__axes_limits__.m
@@ -0,0 +1,52 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __axes_limits__ (@var{fcn}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+function retval = __axes_limits__ (fcn, varargin)
+
+  retval = [];
+
+  fcnmode = sprintf ("%smode", fcn);
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ (fcn, varargin{:});
+
+  if (nargin == 0)
+    retval = get (h, fcn);
+  else
+    arg = varargin{1};
+
+    if (ischar (arg))
+      if (strcmpi (arg, "mode"))
+	retval = get (h, fcnmode);
+      elseif (strcmpi (arg, "auto") ||  strcmpi (arg, "manual"))
+	set (h, fcnmode, arg);
+      endif
+    else
+      if (!isnumeric (arg) && any (size(arg(:)) != [2, 1]))
+	error ("%s: argument must be a 2 element vector", fcn);
+      else
+	set (h, fcn, arg(:));
+      endif
+    endif
+  endif
+
+endfunction
diff --git a/scripts/plot/__axis_label__.m b/scripts/plot/__axis_label__.m
new file mode 100644
index 0000000..57da7f9
--- /dev/null
+++ b/scripts/plot/__axis_label__.m
@@ -0,0 +1,49 @@
+## Copyright (C) 1996, 1997, 2000, 2003, 2005, 2006, 2007, 2008,
+##               2009 John W. Eaton 
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __axis_label__ (@var{caller}, @var{txt}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __axis_label__ (caller, txt, varargin)
+
+  if (ischar (txt))
+    ca = gca ();
+
+    h = get (gca (), caller);
+
+    set (h, "fontangle", get (ca, "fontangle"),
+         "fontname", get (ca, "fontname"),
+         "fontsize", get (ca, "fontsize"),
+         "fontunits", get (ca, "fontunits"),
+         "fontweight", get (ca, "fontweight"),
+         "string", txt,
+	 varargin{:});
+
+    if (nargout > 0)
+      retval = h;
+    endif
+  else
+    error ("%s: expecting first argument to be character string", caller);
+  endif
+
+endfunction
diff --git a/scripts/plot/__bar__.m b/scripts/plot/__bar__.m
new file mode 100644
index 0000000..b3dcecf
--- /dev/null
+++ b/scripts/plot/__bar__.m
@@ -0,0 +1,173 @@
+## Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __bar__ (@var{vertical}, @var{func}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function varargout = __bar__ (vertical, func, varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ((nargout > 1), func, varargin{:});
+
+  ## Slightly smaller than 0.8 to avoid clipping issue in gnuplot 4.0
+  width = 0.8 - 10 * eps; 
+  group = true;
+  bv = 0;
+
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  if (nargin > 3 && isnumeric (varargin{2}))
+    x = varargin{1};
+    if (isvector (x))
+      x = x(:);
+    endif
+    y = varargin{2};
+    if (isvector (y))
+      y = y(:);
+    endif
+    if (size (x, 1) != size (y, 1))
+      y = varargin{1};
+      if (isvector (y))
+	y = y(:);
+      endif
+      x = [1:size(y,1)]';
+      idx = 2;
+    else
+      if (! isvector (x))
+	error ("%s: x must be a vector", func);
+      endif
+      idx = 3;
+    endif
+  else
+    y = varargin{1};
+    if (isvector (y))
+      y = y(:);
+    endif
+    x = [1:size(y,1)]';
+    idx = 2;
+  endif
+      
+  newargs = {};
+  have_line_spec = false;
+  while (idx <= nargin - 2)
+    if (ischar (varargin{idx}) && strcmpi (varargin{idx}, "grouped"))
+      group = true;
+      idx++;
+    elseif (ischar (varargin{idx}) && strcmpi (varargin{idx}, "stacked"))
+      group = false;
+      idx++;
+    else
+      if ((ischar (varargin{idx}) || iscell (varargin{idx}))
+	  && ! have_line_spec)
+	[linespec, valid] = __pltopt__ (func, varargin{idx}, false);
+	if (valid)
+	  have_line_spec = true;
+	  newargs = [{linespec.color}, newargs];
+	  idx++;
+	  continue;
+	endif
+      endif
+      if (isscalar(varargin{idx}))
+	width = varargin{idx++};
+      elseif (idx == nargin - 2)
+	newargs = [newargs,varargin(idx++)];
+      elseif (ischar (varargin{idx})
+	      && strcmpi (varargin{idx}, "basevalue")
+	      && isscalar (varargin{idx+1}))
+        bv = varargin{idx+1};
+        idx += 2;
+      else
+	newargs = [newargs,varargin(idx:idx+1)];
+	idx += 2;
+      endif
+    endif
+  endwhile
+
+  xlen = size (x, 1);
+  ylen = size (y, 1);
+
+  if (xlen != ylen)
+    error ("%s: length of x and y must be equal", func);
+  endif
+  if (any (x(2:end) < x(1:end-1)))
+    error ("%s: x vector values must be in ascending order", func);
+  endif
+
+  ycols = size (y, 2);
+  cutoff = min (diff (double(x))) / 2;
+  if (group)
+    delta_p = delta_m = repmat (cutoff * width / ycols, size (x));
+  else
+    delta_p = delta_m = repmat (cutoff * width, size (x));
+  endif
+  x1 = (x - delta_m)(:)';
+  x2 = (x + delta_p)(:)';
+  xb = repmat ([x1; x1; x2; x2](:), 1, ycols);
+
+  if (group)
+    offset = ((delta_p + delta_m) * [-(ycols - 1) / 2 : (ycols - 1) / 2]);
+    xb(1:4:4*ylen,:) += offset;
+    xb(2:4:4*ylen,:) += offset;
+    xb(3:4:4*ylen,:) += offset;
+    xb(4:4:4*ylen,:) += offset;
+    y0 = zeros (size (y)) + bv;
+    y1 = y;
+  else
+    y1 = cumsum(y,2);
+    y0 = [zeros(ylen,1)+bv, y1(:,1:end-1)];
+  endif
+
+  yb = zeros (4*ylen, ycols);
+  yb(1:4:4*ylen,:) = y0;
+  yb(2:4:4*ylen,:) = y1;
+  yb(3:4:4*ylen,:) = y1;
+  yb(4:4:4*ylen,:) = y0;
+
+  xb = reshape (xb, [4, numel(xb) / 4 / ycols, ycols]);
+  yb = reshape (yb, [4, numel(yb) / 4 / ycols, ycols]);
+
+  if (nargout < 2)
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+
+      tmp = __bars__ (h, vertical, x, y, xb, yb, width, group,
+		      have_line_spec, bv, newargs{:});
+      if (nargout == 1)
+	varargout{1} = tmp;
+      endif
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  else
+    if (vertical)
+      varargout{1} = xb;
+      varargout{2} = yb;
+    else
+      varargout{1} = yb;
+      varargout{2} = xb;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/plot/__bars__.m b/scripts/plot/__bars__.m
new file mode 100644
index 0000000..4ab0a33
--- /dev/null
+++ b/scripts/plot/__bars__.m
@@ -0,0 +1,274 @@
+## Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __bars__ (@var{ax}, @var{vertical}, @var{x}, @var{y}, @var{xb}, @var{yb}, @var{width}, @var{group}, @var{have_color_spec}, @var{base_value}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function tmp = __bars__ (ax, vertical, x, y, xb, yb, width, group, have_color_spec, base_value, varargin)
+
+  ycols = columns (y);
+  clim = get (ax, "clim");
+  tmp = [];
+
+  for i = 1:ycols
+    hg = hggroup ();
+    tmp = [tmp; hg];
+    args = __add_datasource__ ("bar", hg, {"x", "y"}, varargin{:});
+    
+    if (vertical)
+      if (! have_color_spec)
+	if (ycols == 1)
+	  lev = clim(1);
+	else
+	  lev = (i - 1) * (clim(2) - clim(1)) / (ycols - 1) - clim(1);
+	endif
+	h = patch(xb(:,:,i), yb(:,:,i), "FaceColor", "flat", 
+		  "cdata", lev, "parent", hg);
+      else
+	h = patch(xb(:,:,i), yb(:,:,i), "parent", hg);
+      endif
+    else
+      if (! have_color_spec)
+	if (ycols == 1)
+	  lev = clim(1)
+	else
+	  lev = (i - 1) * (clim(2) - clim(1)) / (ycols - 1) - clim(1);
+	endif
+	h = patch(yb(:,:,i), xb(:,:,i), "FaceColor", "flat", 
+		  "cdata", lev, "parent", hg);
+      else
+	h = patch(yb(:,:,i), xb(:,:,i), "parent", hg);
+      endif
+    endif
+
+    if (i == 1)
+      x_axis_range = get (ax, "xlim");
+      h_baseline = line (x_axis_range, [0, 0], "color", [0, 0, 0]);
+      set (h_baseline, "handlevisibility", "off");
+      set (h_baseline, "xliminclude", "off");
+      addlistener (ax, "xlim", @update_xlim);
+      addlistener (h_baseline, "ydata", @update_baseline);
+      addlistener (h_baseline, "visible", @update_baseline);
+    endif
+
+    ## Setup the hggroup and listeners
+    addproperty ("showbaseline", hg, "radio", "{on}|off");
+    addproperty ("basevalue", hg, "data", base_value);
+    addproperty ("baseline", hg, "data", h_baseline);
+
+    addlistener (hg, "showbaseline", @show_baseline);
+    addlistener (hg, "basevalue", @move_baseline); 
+
+    addproperty ("barwidth", hg, "data", width);
+    if (group)
+      addproperty ("barlayout", hg, "radio", "stacked|{grouped}", "grouped");
+    else
+      addproperty ("barlayout", hg, "radio", "{stacked}|grouped", "stacked");
+    endif
+    if (vertical)
+      addproperty ("horizontal", hg, "radio", "on|{off}", "off")
+    else
+      addproperty ("horizontal", hg, "radio", "{on}|off", "on")
+    endif
+
+    addlistener (hg, "barwidth", @update_group);
+    addlistener (hg, "barlayout", @update_group);
+    addlistener (hg, "horizontal", @update_group);
+
+    addproperty ("edgecolor", hg, "patchedgecolor", get (h, "edgecolor"));
+    addproperty ("linewidth", hg, "patchlinewidth", get (h, "linewidth"));
+    addproperty ("linestyle", hg, "patchlinestyle", get (h, "linestyle"));
+    addproperty ("facecolor", hg, "patchfacecolor", get (h, "facecolor"));
+
+    addlistener (hg, "edgecolor", @update_props);
+    addlistener (hg, "linewidth", @update_props); 
+    addlistener (hg, "linestyle", @update_props); 
+    addlistener (hg, "facecolor", @update_props); 
+
+    if (isvector (x))
+      addproperty ("xdata", hg, "data", x);
+    else
+      addproperty ("xdata", hg, "data", x(:, i));
+    endif
+    addproperty ("ydata", hg, "data", y(:, i));
+ 
+    addlistener (hg, "xdata", @update_data);
+    addlistener (hg, "ydata", @update_data);
+
+    addproperty ("bargroup", hg, "data");
+    set (tmp, "bargroup", tmp);
+    if (! isempty (args))
+      set (hg, args{:});
+    endif
+    if (i == 1)
+      set (h_baseline, "parent", get (hg, "parent"));
+    endif
+  endfor
+
+  update_xlim (ax, []);
+endfunction
+
+function update_xlim (h, d)
+  kids = get (h, "children");
+  xlim = get (h, "xlim");
+
+  for i = 1 : length (kids)
+    obj = get (kids (i));
+    if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline"))
+      if (any (get (obj.baseline, "xdata") != xlim))
+	set (obj.baseline, "xdata", xlim);
+      endif
+    endif
+  endfor
+endfunction
+
+function update_baseline (h, d)
+  visible = get (h, "visible");
+  ydata = get (h, "ydata")(1);
+
+  kids = get (get (h, "parent"), "children");
+  for i = 1 : length (kids)
+    obj = get (kids (i));
+    if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline") 
+	&& obj.baseline == h)
+      ## Only alter if changed to avoid recursion of the listener functions
+      if (! strcmpi (get (kids(i), "showbaseline"), visible))
+	set (kids (i), "showbaseline", visible);
+      endif
+      if (! strcmpi (get (kids(i), "basevalue"), visible))
+	set (kids (i), "basevalue", ydata);
+      endif
+    endif
+  endfor
+endfunction
+
+function show_baseline (h, d)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      hlist = get (h, "bargroup");
+      showbaseline = get (h, "showbaseline");
+      for hh = hlist(:)'
+	if (hh != h)
+	  set (hh, "showbaseline", showbaseline);
+	endif
+      endfor
+      set (get (h, "baseline"), "visible", showbaseline);
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
+
+function move_baseline (h, d)
+  b0 = get (h, "basevalue");
+  bl = get (h, "baseline");
+
+  if (get (bl, "ydata") != [b0, b0])
+    set (bl, "ydata", [b0, b0]);
+  endif
+
+  if (strcmpi (get (h, "barlayout"), "grouped"))
+    update_data (h, d);
+  endif
+endfunction
+
+function update_props (h, d)
+  kids = get (h, "children");
+  set (kids, "edgecolor", get (h, "edgecolor"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"),
+       "facecolor", get (h, "facecolor"));
+endfunction
+
+function update_data (h, d)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      hlist = get (h, "bargroup");
+      x = get (h, "xdata");
+      if (!isvector (x))
+	x = x(:);
+      endif
+      y = [];
+      for hh = hlist(:)'
+	ytmp = get (hh, "ydata");
+	y = [y ytmp(:)];
+      endfor
+
+      [xb, yb] = bar (x, y, get (h, "barwidth"), get (h, "barlayout"),
+		      "basevalue", get (h, "basevalue"));
+      ny = columns (y);
+      vert = strcmpi (get (h, "horizontal"), "off");
+
+      for i = 1:ny
+	hp = get (hlist(i), "children");
+	if (vert)
+	  set (hp, "xdata", xb(:,:,i), "ydata", yb(:,:,i));
+	else
+	  set (hp, "xdata", yb(:,:,i), "ydata", xb(:,:,i));
+	endif
+      endfor
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
+
+function update_group (h, d)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      hlist = get (h, "bargroup");
+      barwidth = get(h, "barwidth");
+      barlayout = get (h, "barlayout");
+      horizontal = get (h, "horizontal");
+
+      ## To prevent recursion, only change if modified
+      for hh = hlist(:)'
+	if (hh != h)
+	  if (get (hh, "barwidth") != barwidth)
+	    set (hh, "barwidth", barwidth);
+	  endif
+	  if (! strcmpi (get (hh, "barlayout"), barlayout))
+	    set (hh, "barlayout", barlayout);
+	  endif
+	  if (! strcmpi (get (hh, "horizontal"), horizontal))
+	    set (hh, "horizontal", horizontal);
+	  endif
+	endif
+      endfor
+      update_data (h, d);
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
diff --git a/scripts/plot/__clabel__.m b/scripts/plot/__clabel__.m
new file mode 100644
index 0000000..02bc271
--- /dev/null
+++ b/scripts/plot/__clabel__.m
@@ -0,0 +1,115 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} __clabel__ (@var{c}, @var{v}, @var{hparent}, @var{label_spacing}, @var{z}, @var{varargin})
+## Undocumented internal function.
+## @end deftypefn
+
+function h = __clabel__ (c, v, hparent, label_spacing, z, varargin)
+  ## FIXME
+  ## Assume that the plot size is 4 by 3 inches.
+  lims = axis ();
+  xspacing = 72 * 4 / abs(lims(1) - lims(2));
+  yspacing = 72 * 3 / abs(lims(3) - lims(4));
+
+  if (isscalar (hparent) && ishandle(hparent) && 
+	strcmp (get (hparent, "type"), "hggroup"))
+    x = get (hparent, "xdata");
+    xmin = min (x(:));
+    xmax = max (x(:));
+    y = get (hparent, "ydata");
+    ymin = min (y(:));
+    ymax = max (y(:));
+  else
+    i1 = 1;
+    while (i1 < length (c))
+      clev = c(1,i1);
+      clen = c(2,i1);
+      p = c(:, i1+1:i1+clen)      
+
+      xmin = min (c(1,:));
+      xmax = max (c(1,:));
+      ymin = min (c(2,:));
+      ymax = max (c(2,:));
+
+      i1 += clen+1;
+    endwhile
+  endif
+
+  ## Decode contourc output format and place labels.
+  i1 = 1;
+  h = [];
+  while (i1 < length (c))
+    clev = c(1,i1);
+    clen = c(2,i1);
+
+    if (!isempty (v) && ! any (find (clev == v)))
+      i1 += clen+1;
+      continue;
+    endif
+
+    p = c(:, i1+1:i1+clen) .* repmat ([xspacing; yspacing], 1, clen);
+    d = sqrt (sumsq (diff (p, 1, 2)));
+    cumd = cumsum (d);
+    td = sum(d);
+    ntag = ceil (td / label_spacing);
+
+    if (all (c(:,i1+1) == c(:,i1+clen)))
+      Spacing = td / ntag;
+      pos = Spacing / 2 + [0:ntag-1] * Spacing;
+    else
+      pos = zeros(1, ntag);
+      pos(1) = (td - label_spacing * (ntag - 1)) ./ 2;
+      pos(2:ntag) = pos(1) + [1:ntag-1] * label_spacing;
+    endif
+
+    j1 = 2;
+    tlabel = sprintf ("%g", clev);
+    for i = 1 : ntag
+      tagpos = pos(i);
+      
+      while (j1 < clen && cumd(j1) < tagpos)
+	j1++;
+      endwhile
+      tpos = sum(c(:,i1+j1-1:i1+j1), 2) ./ 2;
+
+      if (tpos(1) != xmin &&  tpos(1) != xmax && 
+	  tpos(2) != ymin &&  tpos(2) != ymax)
+	trot = 180 / pi * atan2 (diff (c(2,i1+j1-1:i1+j1)),
+				 diff (c(1,i1+j1-1:i1+j1)));
+
+	if (ischar (z))
+	  ht = text (tpos(1), tpos(2), clev, tlabel, "rotation", trot, 
+		     "parent", hparent, "horizontalalignment", "center",
+		     "userdata", clev, varargin{:});
+	elseif (!isempty (z))
+	  ht = text (tpos(1), tpos(2), z, tlabel, "rotation", trot, 
+		     "parent", hparent, "horizontalalignment", "center",
+		     "userdata", clev, varargin{:});
+	else
+	  ht = text (tpos(1), tpos(2), tlabel, "rotation", trot,
+		     "parent", hparent, "horizontalalignment", "center",
+		     "userdata", clev, varargin{:});
+	endif
+	h = [h; ht];
+      endif
+    endfor
+    i1 += clen+1;
+  endwhile
+endfunction 
\ No newline at end of file
diff --git a/scripts/plot/__contour__.m b/scripts/plot/__contour__.m
new file mode 100644
index 0000000..4615eb9
--- /dev/null
+++ b/scripts/plot/__contour__.m
@@ -0,0 +1,514 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{c}, @var{hg}] =} __contour__ (@dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+function [c, hg] = __contour__ (varargin)
+  ax = varargin{1};
+  zlevel = varargin{2};
+  filled = "off";
+
+  linespec.linestyle = "-";
+  linespec.color = "auto";
+  edgecolor = "flat";
+  for i = 3 : nargin
+    arg = varargin {i};
+    if ((ischar (arg) || iscell (arg)))
+      [linespec, valid] = __pltopt__ ("__contour__", arg, false);
+      if (isempty (linespec.color))
+	linespec.color = "auto";
+      endif
+      if (valid)
+	have_line_spec = true;
+	varargin(i) = [];
+	break;
+      endif
+    endif
+  endfor
+
+  opts = {};
+  i = 3;
+  while (i < length (varargin))
+    if (ischar (varargin {i}))
+      if (strcmpi (varargin{i}, "fill"))
+	filled = varargin {i + 1};
+	varargin(i:i+1) = [];
+      elseif (strcmpi (varargin{i}, "linecolor"))
+	linespec.color = varargin {i + 1};
+	edgecolor = linespec.color;
+	if (ischar (edgecolor) && strcmpi (edgecolor, "auto"))
+	  edgecolor = "flat";
+	endif
+	varargin(i:i+1) = [];
+      elseif (strcmpi (varargin{i}, "edgecolor"))
+	linespec.color = varargin {i + 1};
+	edgecolor = linespec.color;
+	if (ischar (edgecolor) && strcmpi (edgecolor, "flat"))
+	  linespec.color = "auto";
+	endif
+	varargin(i:i+1) = [];
+      else
+	opts{end+1} = varargin{i};
+        varargin(i) = [];
+        opts{end+1} = varargin{i};
+        varargin(i) = [];
+      endif
+    else
+      i++;
+    endif
+  endwhile
+
+  if (length(varargin) < 5)
+    z1 = varargin{3};
+    x1 = 1 : rows(z1);
+    y1 = 1 : columns(z1);
+  else
+    x1 = varargin{3};
+    y1 = varargin{4};
+    z1 = varargin{5};
+  endif
+  if (length (varargin) == 4 || length (varargin) == 6)
+    vn = varargin {end};
+    vnauto = false;
+  else
+    vnauto = true;
+    vn = 10; 
+  endif
+
+  if (isscalar (vn))
+    lvl = linspace (min (z1(!isinf(z1))), max (z1(!isinf(z1))), 
+		    vn + 2)(1:end-1);
+  else
+    lvl = vn;
+  endif
+
+  if (strcmpi (filled, "on"))
+    if (isvector (x1) || isvector (y1))
+      [x1, y1] = meshgrid (x1, y1);
+    endif
+    [nr, nc] = size (z1);
+    x0 = prepad(x1, nc+1, 2 * x1(1, 1) - x1(1, 2), 2);
+    x0 = postpad(x0, nc+2, 2 * x1(1, nc) - x1(1, nc - 1), 2);
+    x0 = [x0(1, :); x0; x0(1, :)];
+    y0 = prepad(y1, nr+1, 2 * y1(1, 1) - y1(2, 1), 1);
+    y0 = postpad(y0, nr+2, 2 * y1(nr, 1) - y1(nr - 1, 1));
+    y0 = [y0(:, 1), y0, y0(:, 1)];
+    z0 = -Inf(nr+2, nc+2);
+    z0(2:nr+1, 2:nc+1) = z1;
+    [c, lev] = contourc (x0, y0, z0, lvl);
+  else
+    [c, lev] = contourc (x1, y1, z1, lvl);
+  endif
+
+  hg = hggroup ();
+  opts = __add_datasource__ ("__countour__", hg, {"x", "y", "z"}, opts{:});
+
+  addproperty ("xdata", hg, "data", x1);
+  addproperty ("ydata", hg, "data", y1);
+  addproperty ("zdata", hg, "data", z1);
+  addproperty ("contourmatrix", hg, "data", c);
+
+  addlistener (hg, "xdata", @update_data);
+  addlistener (hg, "ydata", @update_data);
+  addlistener (hg, "zdata", @update_data);
+  addlistener (hg, "contourmatrix", @update_data);
+
+  addproperty ("fill", hg, "radio", "on|{off}", filled);
+
+  ## The properties zlevel and zlevelmode don't exist in matlab, but
+  ## allow the use of contourgroups with the contour3, meshc and surfc 
+  ## functions. 
+  if (isnumeric (zlevel))
+    addproperty ("zlevelmode", hg, "radio", "{none}|auto|manual", "manual")
+    addproperty ("zlevel", hg, "data", zlevel);
+  else
+    addproperty ("zlevelmode", hg, "radio", "{none}|auto|manual", zlevel)
+    if (ischar (zlevel) && strcmpi (zlevel, "manual"))
+      z = varargin{3};
+      z = 2 * (min (z(:)) - max (z(:)));
+      addproperty ("zlevel", hg, "data", z);
+    else
+      addproperty ("zlevel", hg, "data", 0.);
+    endif
+  endif
+
+  lvlstep = sum (abs (diff (lvl))) / (length (lvl) - 1);
+
+  addproperty ("levellist", hg, "data", lev);
+  addproperty ("levelstep", hg, "double", lvlstep);
+  if (vnauto)
+    addproperty ("levellistmode", hg, "radio", "{auto}|manual", "auto");
+    addproperty ("levelstepmode", hg, "radio", "{auto}|manual", "auto");
+  elseif (isscalar (vn))
+    addproperty ("levellistmode", hg, "radio", "{auto}|manual", "auto");
+    addproperty ("levelstepmode", hg, "radio", "{auto}|manual", "manual");
+  else
+    addproperty ("levellistmode", hg, "radio", "{auto}|manual", "manual");
+    addproperty ("levelstepmode", hg, "radio", "{auto}|manual", "auto");
+  endif
+
+  addproperty ("labelspacing", hg, "double", 144);
+  addproperty ("textlist", hg, "data", lev);
+  addproperty ("textlistmode", hg, "radio", "{auto}|manual", "auto");
+  addproperty ("textstep", hg, "double", lvlstep);
+  addproperty ("textstepmode", hg, "radio", "{auto}|manual", "auto");
+  addproperty ("showtext", hg, "radio", "on|{off}", "off");
+
+  addproperty ("linecolor", hg, "color", linespec.color, "{auto}|none");
+  addproperty ("linestyle", hg, "linelinestyle", linespec.linestyle);
+  addproperty ("linewidth", hg, "linelinewidth", 0.5);
+
+  ## FIXME It would be good to hide this property which is just an undocumented
+  ## alias for linecolor
+  addproperty ("edgecolor", hg, "color", edgecolor, "{flat}|none");
+
+  addlistener (hg, "fill", @update_data);
+
+  addlistener (hg, "zlevelmode", @update_zlevel);
+  addlistener (hg, "zlevel", @update_zlevel);
+
+  addlistener (hg, "levellist", @update_data);
+  addlistener (hg, "levelstep", @update_data);
+  addlistener (hg, "levellistmode", @update_data);
+  addlistener (hg, "levelstepmode", @update_data);
+
+  addlistener (hg, "labelspacing", @update_text);
+  addlistener (hg, "textlist", @update_text);
+  addlistener (hg, "textlistmode", @update_text);
+  addlistener (hg, "textstep", @update_text);
+  addlistener (hg, "textstepmode", @update_text);
+  addlistener (hg, "showtext", @update_text);
+
+  addlistener (hg, "linecolor", @update_line);
+  addlistener (hg, "linestyle", @update_line);
+  addlistener (hg, "linewidth", @update_line);
+
+  addlistener (hg, "edgecolor", @update_edgecolor);
+
+  add_patch_children (hg);
+
+  if (!isempty (opts))
+    set (hg, opts{:});
+  endif
+endfunction
+
+function add_patch_children (hg)
+  c = get (hg, "contourmatrix");
+  lev = get (hg, "levellist");
+  fill = get (hg, "fill");
+  z = get (hg, "zlevel");
+  zmode = get (hg, "zlevelmode");
+  lc = get (hg, "linecolor");
+  lw = get (hg, "linewidth");
+  ls = get (hg, "linestyle");
+  filled = get (hg, "fill");
+
+  if (strcmpi (lc, "auto"))
+    lc = "flat";
+  endif
+
+  if (strcmpi (filled, "on"))
+    if (diff (lev) < 10*eps) 
+      lvl_eps = 1e-6;
+    else
+      lvl_eps = min (diff (lev)) / 1000.0;
+    endif
+
+    ## Decode contourc output format.
+    i1 = 1;
+    ncont = 0;
+    while (i1 < columns (c))
+      ncont++;
+      cont_lev(ncont) = c(1, i1);
+      cont_len(ncont) = c(2, i1);
+      cont_idx(ncont) = i1+1;
+
+      ii = i1+1:i1+cont_len(ncont);
+      cur_cont = c(:, ii);
+      startidx = ii(1);
+      stopidx = ii(end);
+      cont_area(ncont) = polyarea (c(1, ii), c(2, ii));
+      i1 += c(2, i1) + 1;
+    endwhile
+
+    ## Handle for each level the case where we have (a) hole(s) in a patch.
+    ## Those are to be filled with the color of level below or with the
+    ## background colour.
+    for k = 1:numel (lev)
+      lvl_idx = find (abs (cont_lev - lev(k)) < lvl_eps);
+      len = numel (lvl_idx);
+      if (len > 1)
+	## mark = logical(zeros(size(lvl_idx)));
+	mark = false (size (lvl_idx));
+	a = 1;
+	while (a < len)
+	  ## take 1st patch
+          b = a + 1;
+          pa_idx = lvl_idx(a);
+          ## get pointer to contour start, and contour length
+          curr_ct_idx = cont_idx(pa_idx);
+          curr_ct_len = cont_len(pa_idx);
+	  ## get contour
+          curr_ct = c(:, curr_ct_idx:curr_ct_idx+curr_ct_len-1);
+          b_vec = (a+1):len;
+          next_ct_pt_vec = c(:, cont_idx(lvl_idx(b_vec)));
+          in = inpolygon (next_ct_pt_vec(1,:), next_ct_pt_vec(2,:),
+			  curr_ct(1, :), curr_ct(2, :));
+          mark(b_vec(in)) = !mark(b_vec(in));
+          a++;
+	endwhile
+	if (numel (mark) > 0)
+	  ## All marked contours describe a hole in a larger contour of
+	  ## the same level and must be filled with colour of level below.
+          ma_idx = lvl_idx(mark);
+          if (k > 1)
+	    ## Find color of level below.
+            tmp = find(abs(cont_lev - lev(k - 1)) < lvl_eps);
+            lvl_bel_idx = tmp(1);
+	    ## Set color of patches found.
+	    cont_lev(ma_idx) = cont_lev(lvl_bel_idx);
+          else
+	    ## Set lowest level contour to NaN.
+	    cont_lev(ma_idx) = NaN;
+          endif
+	endif
+      endif
+    endfor
+
+    ## The algorithm can create patches with the size of the plotting
+    ## area, we would like to draw only the patch with the highest level.
+    del_idx = [];
+    max_idx = find (cont_area == max (cont_area));
+    if (numel (max_idx) > 1)
+      ## delete double entries
+      del_idx = max_idx(1:end-1);
+      cont_area(del_idx) = cont_lev(del_idx) = [];
+      cont_len(del_idx) = cont_idx(del_idx) = [];
+    endif
+
+    ## Now we have everything together and can start plotting the patches
+    ## beginning with largest area.
+    [tmp, svec] = sort (cont_area);
+    len = ncont - numel (del_idx);
+    h = [];
+    for n = len:(-1):1
+      idx = svec(n);
+      ctmp = c(:, cont_idx(idx):cont_idx(idx) + cont_len(idx) - 1);
+      if (all (ctmp(:,1) == ctmp(:,end)))
+        ctmp(:, end) = [];
+      else
+	## Special case unclosed contours
+      endif
+      h = [h; patch(ctmp(1, :), ctmp(2, :), cont_lev(idx), "edgecolor", lc, 
+		    "linestyle", ls, "linewidth", lw, "parent", hg)];
+    endfor
+
+    if (min (lev) == max (lev))
+      set (gca (), "clim", [min(lev)-1, max(lev)+1]);
+    else
+      set (gca(), "clim", [min(lev), max(lev)]);
+    endif
+
+    set (gca (), "layer", "top");
+  else
+    ## Decode contourc output format.
+    i1 = 1;
+    h = [];
+    while (i1 < length (c))
+      clev = c(1,i1);
+      clen = c(2,i1);
+
+      if (all (c(:,i1+1) == c(:,i1+clen)))
+	p = c(:, i1+1:i1+clen-1);
+      else
+	p = [c(:, i1+1:i1+clen), NaN(2, 1)];
+      endif
+
+      switch (zmode)
+	case "none"
+	  h = [h; patch(p(1,:), p(2,:), "facecolor", "none", 
+			"edgecolor", lc, "linestyle", ls, "linewidth", lw,
+			"cdata", clev, "parent", hg)]; 
+	case "auto"
+	  h = [h; patch(p(1,:), p(2,:), clev * ones (1, columns (p)),
+			"facecolor", "none", "edgecolor", lc, 
+			"linestyle", ls, "linewidth", lw, "cdata", clev, 
+			"parent", hg)];
+	otherwise
+	  h = [h; patch(p(1,:), p(2,:), z * ones (1, columns (p)),
+			"facecolor", "none", "edgecolor", lc,
+			"linestyle", ls, "linewidth", lw, "cdata", clev,
+			"parent", hg)];
+      endswitch
+      i1 += clen+1;
+    endwhile
+  endif
+
+endfunction
+
+function update_zlevel (h, d)
+  z = get (h, "zlevel");
+  zmode = get (h, "zlevelmode");
+  kids = get (h, "children");
+
+  switch (zmode)
+    case "none"
+      set (kids, "zdata", []);
+    case "auto"
+      for i = 1 : length (kids)
+	set (kids(i), "zdata", get (kids (i), "cdata") .* 
+	     ones (size (get (kids (i), "xdata"))));
+      endfor
+    otherwise
+      for i = 1 : length (kids)
+	set (kids(i), "zdata", z .* ones (size (get (kids (i), "xdata"))));
+      endfor
+  endswitch
+endfunction
+
+function update_edgecolor (h, d)
+  ec = get (h, "edgecolor");
+  lc = get (h, "linecolor");
+  if (ischar (ec) && strcmpi (ec, "flat"))
+    if (! strcmpi (lc, "auto"))
+      set (h, "linecolor", "auto");
+    endif
+  elseif (! isequal (ec, lc))
+    set (h, "linecolor", ec);
+  endif
+endfunction
+
+function update_line (h, d)
+  lc = get (h, "linecolor");
+  ec = get (h, "edgecolor");
+  if (strcmpi (lc, "auto"))
+    lc = "flat";
+  endif
+  if (! isequal (ec, lc))
+    set (h, "edgecolor", lc);
+  endif
+  set (findobj (h, "type", "patch"), "edgecolor", lc,
+       "linewidth", get (h, "linewidth"), "linestyle", get (h, "linestyle"));
+endfunction
+
+function update_data (h, d)
+  persistent recursive = false;
+
+  if (!recursive)
+    recursive = true;
+
+    delete (get (h, "children"));
+
+    if (strcmpi (get (h, "levellistmode"), "manual"))
+      lvl = get (h, "levellist");
+    elseif (strcmpi (get (h, "levelstepmode"), "manual"))
+      z = get (h, "zdata");
+      lvl = ceil ((max(z(:)) - min (z(:)) ./ get (h, "levelstep")));
+    else
+      lvl = 10;
+    endif
+
+    if (strcmpi (get (h, "fill"), "on"))
+      X = get (h, "xdata");
+      Y = get (h, "ydata");
+      Z = get (h, "zdata");
+      if (isvector (X) || isvector (Y))
+	[X, Y] = meshgrid (X, Y);
+      endif
+      [nr, nc] = size (Z);
+      X0 = prepad(X, nc+1, 2 * X(1, 1) - X(1, 2), 2);
+      X0 = postpad(X0, nc+2, 2 * X(1, nc) - X(1, nc - 1), 2);
+      X0 = [X0(1, :); X0; X0(1, :)];
+      Y0 = prepad(Y, nr+1, 2 * Y(1, 1) - Y(2, 1), 1);
+      Y0 = postpad(Y0, nr+2, 2 * Y(nr, 1) - Y(nr - 1, 1));
+      Y0 = [Y0(:, 1), Y0, Y0(:, 1)];
+      Z0 = -Inf(nr+2, nc+2);
+      Z0(2:nr+1, 2:nc+1) = Z;
+      [c, lev] = contourc (X0, Y0, Z0, lvl);
+    else
+      [c, lev] = contourc (get (h, "xdata"), get (h, "ydata"), 
+			   get (h, "zdata"), lvl); 
+    endif
+    set (h, "contourmatrix", c);
+
+    if (strcmpi (get (h, "levellistmode"), "manual"))
+      ## Do nothing
+    elseif (strcmpi (get (h, "levelstepmode"), "manual"))
+      set (h, "levellist", lev);
+    else
+      set (h, "levellist", lev);
+      z = get (h, "zdata");
+      lvlstep = (max(z(:)) - min(z(:))) / 10;
+      set (h, "levelstep", lvlstep);
+    endif
+
+    add_patch_children (h);
+    update_text (h, d);
+  endif
+
+  recursive = false;
+endfunction
+
+function update_text (h, d)
+  persistent recursive = false;
+
+  if (!recursive)
+    recursive = true;
+
+    delete (findobj (h, "type", "text"));
+
+    if (strcmpi (get (h, "textlistmode"), "manual"))
+      lvl = get (h, "textlist");
+    elseif (strcmpi (get (h, "textstepmode"), "manual"))
+      lev = get (h, "levellist");
+
+      if (diff (lev) < 10*eps) 
+	lvl_eps = 1e-6;
+      else
+	lvl_eps = min (abs (diff (lev))) / 1000.0;
+      endif
+
+      stp = get (h, "textstep");
+      t = [0, floor(cumsum(diff (lev)) / (abs(stp) - lvl_eps))];
+      lvl = lev([true, t(1:end-1) != t(2:end)]);
+      set (h, "textlist", lvl);
+    else
+      lvl = get (h, "levellist");
+      set (h, "textlist", lvl, "textstep", get (h, "levelstep"));
+    endif
+
+    if (strcmpi (get (h, "showtext"), "on"))
+      switch (get (h, "zlevelmode"))
+	case "manual"
+	  __clabel__ (get (h, "contourmatrix"), lvl, h, 
+		      get (h, "labelspacing"), get (h, "zlevel"));
+	case "auto"
+	  __clabel__ (get (h, "contourmatrix"), lvl, h,
+		      get (h, "labelspacing"), "auto");
+	otherwise
+	  __clabel__ (get (h, "contourmatrix"), lvl, h,
+		      get (h, "labelspacing"), []);
+      endswitch
+    endif
+  endif
+
+  recursive = false;
+endfunction
diff --git a/scripts/plot/__default_plot_options__.m b/scripts/plot/__default_plot_options__.m
new file mode 100644
index 0000000..9e458c8
--- /dev/null
+++ b/scripts/plot/__default_plot_options__.m
@@ -0,0 +1,33 @@
+## Copyright (C) 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{options} =} __default_plot_options__ ()
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function options = __default_plot_options__ ()
+
+  options.key = "";
+  options.color = [];
+  options.linestyle = "-";
+  options.marker = "none";
+
+endfunction
diff --git a/scripts/plot/__errcomm__.m b/scripts/plot/__errcomm__.m
new file mode 100644
index 0000000..c013c75
--- /dev/null
+++ b/scripts/plot/__errcomm__.m
@@ -0,0 +1,79 @@
+## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __errcomm__ (@var{caller}, @var{p}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Created: 20.02.2001
+## Author: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function retval = __errcomm__ (caller, p, varargin)
+
+  if (nargin < 4)
+    print_usage ();
+  endif
+
+  nargs = length (varargin);
+
+  k = 1;
+  idx = 1;
+  data = cell(6,1);
+  while (k <= nargs)
+    a = varargin{k++};
+    if (isvector (a))
+      a = a(:);
+    elseif (ismatrix (a))
+      ;
+    else
+      usage ("%s (...)", caller);
+    endif
+    sz = size (a);
+    ndata = 1;
+    data{ndata} = a;
+    while (k <= nargs)
+      a = varargin{k++};
+      if (ischar (a) || iscellstr (a))
+	retval(idx++) = __errplot__ (a, p, data{1:ndata});
+	break;
+      elseif (isvector (a))
+	a = a(:);
+      elseif (ismatrix (a))
+	;
+      else
+	error ("wrong argument types");
+      endif
+      if (size (a) != sz)
+	error ("argument sizes do not match");
+      endif
+      data{++ndata} = a;
+      if (ndata > 6)
+	error ("too many arguments to a plot");
+      endif
+    endwhile
+  endwhile
+
+  if (! (ischar (a) || iscellstr (a)))
+    retval(idx++) = __errplot__ ("~", p, data{1:ndata});
+  endif
+
+  drawnow ();
+
+endfunction
diff --git a/scripts/plot/__errplot__.m b/scripts/plot/__errplot__.m
new file mode 100644
index 0000000..88304a7
--- /dev/null
+++ b/scripts/plot/__errplot__.m
@@ -0,0 +1,180 @@
+## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+##               Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{p}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Created: 18.7.2000
+## Author: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function h = __errplot__ (fstr, p, a1, a2, a3, a4, a5, a6)
+
+  if (nargin < 4 || nargin > 8) # at least two data arguments needed
+    print_usage ();
+  endif
+
+  [fmt, key] = __pltopt__ ("__errplot__", fstr);
+
+  [len, nplots] = size (a1);
+  h = [];
+
+  for i = 1:nplots
+    ## Set the plot type based on linestyle.
+
+    if (strcmp (fmt.linestyle, "~"))
+      ifmt = "yerr";
+    elseif (strcmp (fmt.linestyle, ">"))
+      ifmt = "xerr";
+    elseif (strcmp (fmt.linestyle, "~>"))
+      ifmt = "xyerr";
+    elseif (strcmp (fmt.linestyle, "#"))
+      ifmt = "box";
+    elseif (strcmp (fmt.linestyle, "#~"))
+      ifmt = "boxy";
+    elseif (strcmp (fmt.linestyle, "#~>"))
+      ifmt = "boxxy";
+    else
+      print_usage ();
+    endif
+
+    hg = hggroup ("parent", p);
+    h = [h; hg];
+    args = __add_datasource__ ("__errplot__", hg, 
+			       {"x", "y", "l", "u", "xl", "xu"});
+
+    if (isempty (fmt.color))
+      hl = __line__ (hg, "color", __next_line_color__ ());
+    else
+      hl = __line__ (hg, "color", fmt.color);
+    endif
+
+    ## FIXME -- note the code below adds the errorbar data directly as
+    ## ldata, etc properties of the line objects, as gnuplot can handle
+    ## this.  Matlab has the errorbar part of the plot as a special line
+    ## object with embedded NaNs that draws the three segments of the
+    ## bar separately.  Should we duplicate Matlab's behavior and stop
+    ## using the ldata, etc. properties of the line objects that are
+    ## Octace specific?
+
+    switch (nargin - 2)
+      case 1
+	error ("error plot requires 2, 3, 4 or 6 columns");
+      case 2
+	set (hl, "xdata", (1:len)');
+	set (hl, "ydata", a1(:,i));
+	set (hl, "ldata", a2(:,i));
+	set (hl, "udata", a2(:,i));
+      case 3
+	set (hl, "xdata", a1(:,i));
+	set (hl, "ydata", a2(:,i));
+	set (hl, "ldata", a3(:,i));
+	set (hl, "udata", a3(:,i));
+      case 4
+	set (hl, "xdata", a1(:,i));
+	set (hl, "ydata", a2(:,i));
+
+	if (index (ifmt, "boxxy") || index (ifmt, "xyerr"))
+	  set (hl, "xldata", a3(:,i));
+	  set (hl, "xudata", a3(:,i));
+	  set (hl, "ldata", a4(:,i));
+	  set (hl, "udata", a4(:,i));
+	elseif (index (ifmt, "xerr"))
+	  set (hl, "xldata", a3(:,i));
+	  set (hl, "xudata", a4(:,i));
+	else
+	  set (hl, "ldata", a3(:,i));
+	  set (hl, "udata", a4(:,i));
+	endif
+      case 5
+	error ("error plot requires 2, 3, 4 or 6 columns");
+      case 6
+	set (hl, "xdata", a1(:,i));
+	set (hl, "ydata", a2(:,i));
+	set (hl, "xldata", a3(:,i));
+	set (hl, "xudata", a4(:,i));
+	set (hl, "ldata", a5(:,i));
+	set (hl, "udata", a6(:,i));
+    endswitch
+
+    addproperty ("color", hg, "linecolor", get (hl, "color"));
+    addproperty ("linewidth", hg, "linelinewidth", get (hl, "linewidth"));
+    addproperty ("linestyle", hg, "linelinestyle", get (hl, "linestyle"));
+    addproperty ("marker", hg, "linemarker", get (hl, "marker"));
+    addproperty ("markerfacecolor", hg, "linemarkerfacecolor", 
+		 get (hl, "markerfacecolor"));
+    addproperty ("markeredgecolor", hg, "linemarkerfacecolor", 
+		 get (hl, "markeredgecolor"));
+    addproperty ("markersize", hg, "linemarkersize", 
+		 get (hl, "markersize"));
+
+    addlistener (hg, "color", @update_props);
+    addlistener (hg, "linewidth", @update_props); 
+    addlistener (hg, "linestyle", @update_props); 
+    addlistener (hg, "marker", @update_props); 
+    addlistener (hg, "markerfacecolor", @update_props); 
+    addlistener (hg, "markersize", @update_props);
+
+    addproperty ("xdata", hg, "data", get (hl, "xdata"));
+    addproperty ("ydata", hg, "data", get (hl, "ydata"));
+    addproperty ("ldata", hg, "data", get (hl, "ldata"));
+    addproperty ("udata", hg, "data", get (hl, "udata"));
+    addproperty ("xldata", hg, "data", get (hl, "xldata"));
+    addproperty ("xudata", hg, "data", get (hl, "xudata"));
+
+    addlistener (hg, "xdata", @update_data);
+    addlistener (hg, "ydata", @update_data);
+    addlistener (hg, "ldata", @update_data);
+    addlistener (hg, "udata", @update_data);
+    addlistener (hg, "xldata", @update_data);
+    addlistener (hg, "xudata", @update_data);
+
+    __line__ (hg, "xdata", get (hl, "xdata"), 
+	      "ydata", get (hl, "ydata"), 
+	      "color", get (hl, "color"),
+	      "linewidth", get (hl, "linewidth"),
+	      "linestyle", get (hl, "linestyle"), 
+	      "marker", "none", "parent", hg);
+  endfor
+
+endfunction
+
+function update_props (h, d)
+  set (get (h, "children"), "color", get (h, "color"), 
+       "linewidth", get (h, "linewidth"), "linestyle", get (h, "linestyle"), 
+       "marker", get (h, "marker"), "markersize", get (h, "markersize"),
+       "markerfacecolor", get (h, "markerfacecolor"),
+       "markeredgecolor", get (h, "markeredgecolor"));
+endfunction
+
+function update_data (h, d)
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+  l = get (h, "ldata");
+  u = get (h, "udata");
+  xl = get (h, "xldata");
+  xu = get (h, "xudata");
+
+  kids = get (h, "children");
+  set (kids(1), "xdata", x, "ydata", y);
+  set (kids(2), "xdata", x, "ydata", y, "ldata", l, "udata", u, 
+       "xldata", xl, "xudata", xu);
+endfunction
diff --git a/scripts/plot/__ezplot__.m b/scripts/plot/__ezplot__.m
new file mode 100644
index 0000000..c1684d4
--- /dev/null
+++ b/scripts/plot/__ezplot__.m
@@ -0,0 +1,445 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{h}, @var{needusage}] =} __ezplot__ (@var{pfunc}, @var{varargin})
+## Undocumented internal function.
+## @end deftypefn
+
+function [h, needusage] = __ezplot__ (pfunc, varargin)
+
+  func = cstrcat ("ez", pfunc);
+  if (strncmp (pfunc, "contour", 7))
+    iscontour = true;
+  else
+    iscontour = false;
+  endif
+  if (strcmp (pfunc, "plot"))
+    isplot = true;
+    isplot3 = false;
+    ispolar = false;
+    nargs = 1;
+  elseif (strcmp (pfunc, "plot3"))
+    isplot = false;
+    isplot3 = true;
+    ispolar = false;
+    nargs = 1;
+  elseif (strcmp (pfunc, "polar"))
+    isplot = false;
+    isplot3 = false;
+    ispolar = true;
+    nargs = 1;
+  else
+    isplot = false;
+    isplot3 = false;
+    ispolar = false;
+    nargs = 2;
+  endif
+
+  [ax, varargin, nargin] = __plt_get_axis_arg__ (func, varargin{:});
+
+  needusage = false;
+  if (nargin < 1)
+    needusage = true;
+    return;
+  endif
+
+  parametric = false;
+  fun = varargin {1};
+  if (ischar (fun))
+    if (exist (fun, "file") || exist (fun, "builtin"))
+      fun = vectorize (inline (cstrcat (fun, "(t)")));
+    else
+      fun = vectorize (inline (fun));
+    endif
+    if (isplot && length (argnames (fun)) == 2)
+      nargs = 2;
+    elseif (length (argnames (fun)) != nargs)
+      error ("%s: excepting a function of %d arguments", func, nargs);
+    endif
+    fstr = formula (fun);
+    if (isplot)
+      xarg = argnames(fun){1};
+      if (nargs == 2)
+	yarg = argnames(fun){2};
+      else
+	yarg = "";
+      endif
+    elseif (isplot3)
+      xarg = "x";
+      yarg = "y";
+    elseif (ispolar)
+      xarg = "";
+      yarg = "";
+    else
+      xarg = argnames(fun){1};
+      yarg = argnames(fun){2};
+    endif
+  elseif (strcmp (typeinfo (fun), "inline function"))
+    if (isplot && length (argnames (fun)) == 2)
+      nargs = 2;
+    elseif (length (argnames (fun)) != nargs)
+      error ("%s: excepting a function of %d arguments", func, nargs);
+    endif
+    fun = vectorize (fun);
+    fstr = formula (fun);
+    if (isplot)
+      xarg = argnames(fun){1};
+      if (nargs == 2)
+	yarg = argnames(fun){2};
+      else
+	yarg = "";
+      endif
+    elseif (isplot3)
+      xarg = "x";
+      yarg = "y";
+    elseif (isplot || ispolar)
+      xarg = "";
+      yarg = "";
+    else
+      xarg = argnames(fun)(1);
+      yarg = argnames(fun)(2);
+    endif
+  elseif (isa (fun, "function_handle"))
+    fstr = func2str (fun);
+    if (length (findstr (fstr, ")")) != 0)
+      args = regexp (substr (fstr, 3, findstr (fstr, ")")(1) - 3), 
+		     '(\w[\w\d]*)', 'tokens');
+    fstr = substr (fstr, findstr (fstr, ")")(1) + 1);
+    else
+      args = {{"x"}};
+    endif
+    if (isplot && length (args) == 2)
+      nargs = 2;
+    elseif (length (args) != nargs)
+      error ("%s: excepting a function of %d arguments", func, nargs);
+    endif
+    if (isplot)
+      xarg = args{1}{1};
+      if (nargs == 2)
+	yarg = args{2}{1};
+      else
+	yarg = "";
+      endif
+    elseif (isplot3)
+      xarg = "x";
+      yarg = "y";
+    elseif (ispolar)
+      xarg = "";
+      yarg = "";
+    else
+      xarg = args{1}{1};
+      yarg = args{2}{1};
+    endif
+  else
+    error ("%s: expecting string, inline function or function handle", func);
+  endif
+
+  if (nargin > 2 || (nargin == 2 && isplot))
+    funx = fun;
+    fstrx = fstr;
+    funy = varargin {2};
+    if (ischar (funy) && ! strcmp (funy, "circ") && ! strcmp (funy, "animate"))
+      parametric = true;
+      if (exist (funy, "file") || exist (funy, "builtin"))
+	funy = vectorize (inline (cstrcat (funy, "(t)")));
+      else
+	funy = vectorize (inline (funy));
+      endif
+      if (length (argnames (funy)) != nargs)
+	error ("%s: excepting a function of %d arguments", func, nargs);
+      endif
+      fstry = formula (funy);
+    elseif (strcmp (typeinfo (funy), "inline function"))
+      parametric = true;
+      if (length (argnames (funy)) != nargs)
+	error ("%s: excepting a function of %d arguments", func, nargs);
+      endif
+      funy = vectorize (funy);
+      fstry = formula (funy);
+    elseif (isa (funy, "function_handle"))
+      parametric = true;
+      fstry = func2str (funy);
+      if (length (findstr (fstry, ")")) != 0)
+	args = regexp (substr (fstry, 3, findstr (fstry, ")")(1) - 3), 
+		       '(\w[\w\d]*)', 'tokens');
+	fstry = substr (fstry, findstr (fstry, ")")(1) + 1);
+      else
+	args = {{"y"}};
+      endif
+      if (length (args) != nargs)
+	error ("%s: excepting a function of %d arguments", func, nargs);
+      endif
+    endif
+
+    if (parametric && isplot)
+      xarg = "x";
+      yarg = "y";
+      if (nargs == 2)
+	error ("%s: can not define a parametric function in this manner");
+      endif
+    endif
+
+    if (!isplot && parametric)
+      funz = varargin {3};
+      if (ischar (funz) && ! strcmp (funz, "circ") && 
+	  ! strcmp (funz, "animate"))
+	if (exist (funz, "file") || exist (funz, "builtin"))
+	  funz = vectorize (inline (cstrcat (funz, "(t)")));
+	else
+	  funz = vectorize (inline (funz));
+	endif
+	if (length (argnames (funz)) != nargs)
+	  error ("%s: excepting a function of %d arguments", func, nargs);
+	endif
+	fstrz = formula (funz);
+      elseif (strcmp (typeinfo (funz), "inline function"))
+	if (length (argnames (funz)) != nargs)
+	  error ("%s: excepting a function of %d arguments", func, nargs);
+	endif
+	funz = vectorize (funz);
+	fstrz = formula (funz);
+      elseif (isa (funz, "function_handle"))
+	fstrz = func2str (funz);
+	args = regexp (substr (fstrz, 3, findstr (fstrz, ")")(1) - 3), 
+		       '(\w[\w\d]*)', 'tokens');
+	if (length (args) != nargs)
+	  error ("%s: excepting a function of %d arguments", func, nargs);
+	endif
+	fstrz = substr (fstrz, findstr (fstrz, ")")(1) + 1);
+      else
+	error ("%s: parametric plots expect 3 functions", func);
+      endif
+    endif
+  endif
+
+  if (isplot && nargs != 2)
+    n = 500; 
+  else
+    n = 60;
+  endif
+  domain = [];
+  circ = false;
+  animate = false;
+  if (parametric)
+    if (isplot)
+      iarg = 3;
+    else
+      iarg = 4;
+    endif
+  else
+    iarg = 2;
+  endif
+  while (iarg <= nargin)
+    arg = varargin{iarg++};
+    if (ischar (arg) && strcmp (arg, "circ"))
+      circ = true;
+    elseif (ischar (arg) && strcmp (arg, "animate"))
+      animate = true;
+    elseif (isscalar (arg))
+      n = arg;
+    elseif (numel (arg) == 2)
+      domain = [arg(:).' arg(:).'];
+    elseif (numel (arg) == 4)
+      domain = arg(:).';
+    else
+      error ("%s: expecting scalar, 2 or 4 element vector", func);
+    endif
+  endwhile
+
+  if (isempty (domain))
+    if (isplot3 || ispolar)
+      domain = [0, 2*pi, 0, 2*pi];
+    else
+      domain = [-2*pi, 2*pi, -2*pi, 2*pi];
+    endif
+  endif
+
+  if (circ)
+    if (iscontour || isplot3 || isplot)
+      needusage = true;
+      return;
+    endif
+    if (parametric)
+      error ("%s: can not have both circular domain and parametric function", 
+	     func);
+    endif
+    cent = [domain(1) + domain(2), domain(3) + domain(4)] / 2;
+    funx = @(r,t) r .* cos (t) + cent (1);
+    funy = @(r,t) r .* sin (t) + cent (2);
+    domain = [0, sqrt((domain(2) - cent(1))^2 + (domain(4) - cent(2))^2), ...
+	      -pi, pi];
+    funz = fun;
+    parametric = true;
+  endif
+
+  if (animate)
+    if (!isplot3)
+      error ("%s: animated graphs only valid with plot3", func);
+    endif
+    error ("%s: animated graphs not implemented", func);
+  endif
+
+  if (isplot3 || ispolar || (isplot && nargs == 1))
+    X = linspace (domain (1), domain (2), n);
+  elseif (isplot && numel (domain) == 2)
+    x = linspace (domain (1), domain (2), n);
+    [X, Y] = meshgrid (x, x);
+  else
+    x = linspace (domain (1), domain (2), n);
+    y = linspace (domain (3), domain (4), n);
+    [X, Y] = meshgrid (x, y);
+  endif
+
+  if (parametric)
+    if (isplot)
+      XX = feval (funx, X);
+      Z = feval (funy, X);
+      X = XX;
+    elseif (isplot3)
+      Z = feval (funz, X);
+      XX = feval (funx, X);
+      YY = feval (funy, X);
+      X = XX;
+      Y = YY;
+    else
+      Z = feval (funz, X, Y);
+      XX = feval (funx, X, Y);
+      YY = feval (funy, X, Y);
+      X = XX;
+      Y = YY;
+
+      ## Eliminate the singularities
+      X = __eliminate_sing__ (X);
+      Y = __eliminate_sing__ (Y);
+      Z = __eliminate_sing__ (Z);
+    endif
+
+    fstrx = regexprep (regexprep (regexprep (fstrx,'\.\^\s*','^'), 
+		      '\./', '/'), '[\.]*\*', '');
+    fstry = regexprep (regexprep (regexprep (fstry,'\.\^\s*','^'), 
+		      '\./', '/'), '[\.]*\*', '');
+    if (isplot)
+      fstr = cstrcat ("x = ",fstrx,", y = ",fstry);
+    else
+      fstrz = regexprep (regexprep (regexprep (fstrz,'\.\^\s*','^'), 
+				    '\./', '/'), '[\.]*\*', '');
+      fstr = cstrcat ("x = ",fstrx,",y = ",fstry,", z = ",fstrz);
+    endif
+  else
+    if (isplot3)
+      needusage = true;
+      return;
+    endif
+
+    fstr = regexprep (regexprep (regexprep (fstr,'\.\^\s*','^'), '\./', '/'), 
+		      '[\.]*\*', '');
+    if (isplot && nargs == 2)
+      if (strcmp (typeinfo (fun), "inline function") && 
+	  !isempty (strfind (formula (fun) , "=")))
+	fun = inline (cstrcat (strrep (formula (fun), "=", "- ("), ")"));
+      else
+	fstr = cstrcat (fstr, " = 0");
+      endif
+
+      Z = feval (fun, X, Y);
+
+      ## Matlab returns line objects for this case and so can't call 
+      ## contour directly as it returns patch objects to allow colormaps
+      ## to work with contours. Therefore recreate the lines from the
+      ## output for contourc, and store in cell arrays.
+      [c, lev] = contourc (X, Y, Z, [0, 0]);
+
+      i1 = 1;
+      XX = {};
+      YY = {};
+      while (i1 < length (c))
+	clev = c(1,i1);
+	clen = c(2,i1);
+	XX = [XX, {c(1, i1+1:i1+clen)}];
+	YY = [YY, {c(2, i1+1:i1+clen)}];
+	i1 += clen+1;
+      endwhile
+    else  
+      if (ispolar)
+	Z = feval (fun, X);
+      elseif (isplot)
+	Z = real (feval (fun, X));
+
+	## Eliminate the singularities. This seems to be what matlab
+	## does, but can't be sure.
+	XX = sort (Z (isfinite (Z)));
+	if (length (X) > 4)
+	  d = XX(fix (7 * length (XX) / 8)) - XX(fix (length (XX) / 8));
+	  yrange = [max(XX(1) - d/8, XX(fix (length (XX) / 8)) - d), ...
+		    min(XX(end) + d/8, XX(fix (7 * length (XX) / 8)) + d)];
+	else
+	  yrange = [XX(1), XX(end)];
+        endif
+
+	idx = 2 : length(Z);
+	idx = find (((Z(idx) > yrange(2) / 2) & (Z(idx-1) < yrange(1) / 2)) |
+		 ((Z(idx) < yrange(1) / 2) & (Z(idx-1) > yrange (2) / 2)));
+	if (any(idx))
+	  Z(idx) = NaN; 
+	endif
+      else
+	Z = feval (fun, X, Y);
+
+	## Eliminate the singularities
+	Z = __eliminate_sing__ (Z);
+      endif
+    endif
+  endif
+
+  oldax = gca (); 
+  unwind_protect
+    axes (ax);
+    if (iscontour)
+      [clev, h] = feval (pfunc, X, Y, Z);
+    elseif (isplot && nargs == 2)
+      h = [];
+      hold_state = get (ax, "nextplot");
+      for i = 1 : length (XX)
+	h = [h; plot(XX{i}, YY{i})];
+	if (i == 1)
+	  set (ax, "nextplot", "add")
+	endif
+      endfor
+      set (ax, "nextplot", hold_state)
+    elseif (ispolar || isplot)
+      h = feval (pfunc, X, Z);
+      if (isplot && !parametric)
+	axis ([X(1), X(end), yrange]);
+      endif
+    else
+      h = feval (pfunc, X, Y, Z);
+    endif
+    xlabel (xarg);
+    ylabel (yarg);
+    title (fstr);
+  unwind_protect_cleanup
+    axes (oldax);
+  end_unwind_protect
+
+endfunction
+
+function x = __eliminate_sing__ (x)
+  x (isinf (x)) = NaN;
+  x (abs (del2 (x)) > 0.2 * (max(x(:)) - min(x(:)))) = NaN;
+endfunction
diff --git a/scripts/plot/__gnuplot_get_var__.m b/scripts/plot/__gnuplot_get_var__.m
new file mode 100644
index 0000000..f7f87ec
--- /dev/null
+++ b/scripts/plot/__gnuplot_get_var__.m
@@ -0,0 +1,161 @@
+## Copyright (C) 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{value} =} __gnuplot_get_var__ (@var{h}, @var{name}, @var{fmt})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Created: 2009-02-07
+
+function gp_var_value = __gnuplot_get_var__ (h, gp_var_name, fmt)
+
+  if (nargin == 0)
+    h = gcf ();
+  endif
+  if (nargin < 2)
+    print_usage ();
+  endif
+  if (nargin < 3)
+    fmt = '';
+  endif
+
+  if (numel (h) == 1 && isfigure (h))
+    if (isempty (get (gcf, "__plot_stream__")))
+      ostream = __gnuplot_open_stream__ (2, h);
+    else
+      ostream = get (h, "__plot_stream__");
+    endif
+  else
+    ostream = h;
+  endif
+  if (numel (ostream) < 1)
+    error ("__gnuplot_get_var__: stream to gnuplot not open");
+  elseif (ispc ())
+    if (numel (ostream) == 1)
+      error ("__gnuplot_get_var__: Need mkfifo that is not implemented under Windows");
+    endif
+    use_mkfifo = false;
+    istream = ostream(2);
+    ostream = ostream(1);
+  else
+    use_mkfifo = true;
+    ostream = ostream(1);
+  endif
+
+  if (use_mkfifo)
+    gpin_name = tmpnam ();
+
+    ## Mode: 6*8*8 ==  0600
+    [err, msg] = mkfifo (gpin_name, 6*8*8);
+
+    if (err != 0)
+      error ("__gnuplot_get_var__: Can not make fifo (%s)", msg);
+    endif
+  endif
+
+  gp_var_name = strtrim (gp_var_name);
+  n = min (strfind (gp_var_name, " "), strfind (gp_var_name, ",")) - 1;
+  if (isempty (n))
+    n = numel (gp_var_name);
+  endif
+
+  unwind_protect
+
+    ## Notes: Variables may be undefined if user closes gnuplot by "q"
+    ## or Alt-F4. Further, this abrupt close also requires the leading
+    ## "\n" on the next line.
+    if (use_mkfifo)
+      fprintf (ostream, "\nset print \"%s\";\n", gpin_name);
+      fflush (ostream);
+      [gpin, err] = fopen (gpin_name, "r");
+      if (err != 0)
+        ## Try a second time, and then give an error.
+        [gpin, err] = fopen (gpin_name, "r");
+      endif
+      if (err != 0)
+        error ("__gnuplot_get_var__: Can not open fifo.");
+      endif
+      gp_cmd = sprintf ("\nif (exists(\"%s\")) print %s; else print NaN\n",
+                        gp_var_name(1:n), gp_var_name);
+      fputs (ostream, gp_cmd);
+
+      ## Close output file, to force it to be flushed
+      fputs (ostream, "set print;\n");
+      fflush (ostream);
+
+      ## Now read from fifo.
+      reading = true;
+      str = {};
+      while (reading)
+        str{end+1} = fgets (gpin);
+        if (isnumeric (str{end}) && (str{end} == -1))
+          reading = false;
+          str = str(1:(end-1));
+        endif
+      endwhile
+      str = strcat (str{:});
+      fclose (gpin);
+    else
+      ## Direct gnuplot to print to <STDOUT>
+      fprintf (ostream, "set print \"-\";\n");
+      fflush (ostream);
+      gp_cmd = sprintf ("\nif (exists(\"%s\")) print \"OCTAVE: \", %s; else print NaN\n",
+                        gp_var_name(1:n), gp_var_name);
+      fputs (ostream, gp_cmd);
+      fflush (ostream);
+      ## Direct gnuplot to print to <STDERR>
+      fputs (ostream, "set print;\n");
+      fflush (ostream);
+
+      str = {};
+      while (isempty (str))
+        str = char (fread (istream)');
+        if (isempty (str))
+	  sleep (0.05);
+	else
+          str = regexp (str, "OCTAVE:.*", "match");
+          str = str{end}(8:end);
+        endif
+        fclear (istream);
+      endwhile
+    endif
+
+    ## Strip out EOLs and the continuation character "|"
+    str(str=="\n") = "";
+    str(str=="\r") = "";
+    n_continue = strfind (str, " \\ ");
+    if (! isempty (n_continue))
+      str(n_continue+1) = "";
+    endif
+
+    if (isempty (fmt))
+      gp_var_value = strtrim (str);
+    else
+      gp_var_value = sscanf (str, fmt);
+    endif
+
+  unwind_protect_cleanup
+    if (use_mkfifo)
+      unlink (gpin_name);
+    endif
+  end_unwind_protect
+
+endfunction
+
diff --git a/scripts/plot/__gnuplot_ginput__.m b/scripts/plot/__gnuplot_ginput__.m
new file mode 100644
index 0000000..4c55377
--- /dev/null
+++ b/scripts/plot/__gnuplot_ginput__.m
@@ -0,0 +1,152 @@
+## Copyright (C) 2004, 2006, 2008 Petr Mikulik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __gnuplot_ginput__ (@var{f}, @var{n})
+## Undocumented internal function.
+## @end deftypefn
+
+## This is ginput.m implementation for gnuplot and X11.
+## It requires gnuplot 4.1 and later.
+
+## This file initially bore the copyright statement
+## Petr Mikulik
+## History: June 2006; August 2005; June 2004; April 2004
+## License: public domain
+
+function [x, y, button] = __gnuplot_ginput__ (f, n)
+
+  ostream = get (f, "__plot_stream__");
+  if (numel (ostream) < 1)
+    error ("ginput: stream to gnuplot not open");
+  elseif (ispc ())
+    if (numel (ostream) == 1)
+      error ("ginput: Need mkfifo that is not implemented under Windows");
+    endif
+    use_mkfifo = false;
+    istream = ostream(2);
+    ostream = ostream(1);
+  else
+    use_mkfifo = true;
+    ostream = ostream(1);
+  endif
+
+  if (compare_versions (__gnuplot_version__ (), "4.0", "<="))
+    error ("ginput: version %s of gnuplot not supported", gnuplot_version ());
+  endif
+
+  if (nargin == 1)
+    x = zeros (100, 1);
+    y = zeros (100, 1);
+    button = zeros (100, 1);
+  else
+    x = zeros (n, 1);
+    y = zeros (n, 1);
+    button = zeros (n, 1);
+  endif
+
+  if (use_mkfifo)
+    gpin_name = tmpnam ();
+
+    ##Mode: 6*8*8 ==  0600
+    [err, msg] = mkfifo (gpin_name, 6*8*8);
+
+    if (err != 0)
+      error ("ginput: Can not open fifo (%s)", msg);
+    endif
+  endif
+
+  unwind_protect
+
+    k = 0;
+    while (true)
+      k++;
+
+      ## Notes: MOUSE_* can be undefined if user closes gnuplot by "q"
+      ## or Alt-F4. Further, this abrupt close also requires the leading
+      ## "\n" on the next line.
+      if (use_mkfifo)
+	fprintf (ostream, "set print \"%s\";\n", gpin_name);
+	fflush (ostream);
+	[gpin, err] = fopen (gpin_name, "r");
+	if (err != 0)
+	  error ("ginput: Can not open fifo (%s)", msg);
+	endif
+	fputs (ostream, "pause mouse any;\n\n");
+	fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n");
+
+	## Close output file, to force it to be flushed
+	fputs (ostream, "set print;\n");
+	fflush (ostream);
+
+	## Now read from fifo.
+	[x(k), y(k), button(k), count] = fscanf (gpin, "%f %f %d", "C");
+	fclose (gpin);
+      else
+	fprintf (ostream, "set print \"-\";\n");
+	fflush (ostream);
+	fputs (ostream, "pause mouse any;\n\n");
+	fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print \"OCTAVE: \", MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n");
+
+	## Close output file, to force it to be flushed
+	fputs (ostream, "set print;\n");
+	fflush (ostream);
+
+	str = {};
+	while (isempty (str))
+	  str = char (fread (istream)');
+	  if (! isempty (str))
+	    str = regexp (str, 'OCTAVE:\s+[\d.\+-]+\s+[\d.\+-]+\s+\d*', 'match');
+	  endif
+	  fclear (istream);
+	endwhile
+        [x(k), y(k), button(k), count] = sscanf (str{end}(8:end), "%f %f %d", "C");
+      endif
+
+      if ([x(k), y(k), button(k)] == [0, 0, -1])
+	## Mousing not active (no plot yet).
+	break;
+      endif
+
+      if (nargin > 1)
+	## Input argument n was given => stop when k == n.
+	if (k == n) 
+	  break; 
+	endif
+      else
+	## Input argument n not given => stop when hitting a return key.
+	## if (button(k) == 0x0D || button(k) == 0x0A) 
+	##   ## hit Return or Enter
+	if (button(k) == 0x0D)
+	  ## hit Return
+	  x(k:end) = [];
+	  y(k:end) = [];
+	  button(k:end) = [];
+	  break;
+	endif
+      endif
+    endwhile
+
+  unwind_protect_cleanup
+    if (use_mkfifo)
+      unlink (gpin_name);
+    endif
+  end_unwind_protect
+
+endfunction
+
diff --git a/scripts/plot/__gnuplot_has_feature__.m b/scripts/plot/__gnuplot_has_feature__.m
new file mode 100644
index 0000000..1da890e
--- /dev/null
+++ b/scripts/plot/__gnuplot_has_feature__.m
@@ -0,0 +1,54 @@
+## Copyright (C) 2009 Ben Abbott
+## 
+## This program is free software; you can 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{has_feature} =} __gnuplot_has_feature__ (@var{feature})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Created: 2009-01-27
+
+function res = __gnuplot_has_feature__ (feature)
+  persistent features has_features
+  features = {"x11_figure_position",
+              "wxt_figure_size",
+              "transparent_patches",
+              "transparent_surface",
+              "epslatex_implies_eps_filesuffix",
+              "epslatexstandalone_terminal",
+              "screen_coordinates_for_{lrtb}margin",
+              "variable_GPVAL_TERMINALS",
+              "key_has_font_properties"};
+
+  if (isempty (has_features))
+    gnuplot_version = __gnuplot_version__ ();
+    versions = {"4.2.5", "4.3.0", "4.3", "4.3", "4.2", "4.2", "4.3", "4.3", "4.3"};
+    operators = {">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">="};
+    have_features = logical (zeros (size (features)));
+    for n = 1 : numel (have_features)
+      has_features(n) = compare_versions (gnuplot_version, versions{n}, operators{n});
+    endfor
+  endif
+
+  n = find (strcmpi (feature, features));
+  if (isempty (n))
+    res = NaN;
+  else
+    res = has_features(n);
+  endif
+endfunction
+
diff --git a/scripts/plot/__gnuplot_open_stream__.m b/scripts/plot/__gnuplot_open_stream__.m
new file mode 100644
index 0000000..fbf6c7f
--- /dev/null
+++ b/scripts/plot/__gnuplot_open_stream__.m
@@ -0,0 +1,43 @@
+## Copyright (C) 2009 Ben Abbott
+## 
+## This program is free software; you can 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{stream}} __gnuplot_open_stream__ (@var{npipes}, @var{h})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Created: 2009-04-11
+
+function plot_stream = __gnuplot_open_stream__ (npipes, h)
+  cmd = gnuplot_binary ();
+  if (npipes > 1)
+    [plot_stream(1), plot_stream(2), pid] = popen2 (cmd);
+    if (pid < 0)
+      error ("__gnuplot_open_stream__: failed to open connection to gnuplot.");
+    else
+      plot_stream(3) = pid;
+    endif
+  else
+    plot_stream = popen (cmd, "w");
+    if (plot_stream < 0)
+      error ("__gnuplot_open_stream__: failed to open connection to gnuplot.");
+    endif
+  endif
+  if (nargin > 1)
+    set (h, "__plot_stream__", plot_stream);
+  endif
+endfunction
diff --git a/scripts/plot/__gnuplot_version__.m b/scripts/plot/__gnuplot_version__.m
new file mode 100644
index 0000000..65d889a
--- /dev/null
+++ b/scripts/plot/__gnuplot_version__.m
@@ -0,0 +1,51 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Daniel Sebald
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{version} =} __gnuplot_version__ ()
+## Undocumented internal function.
+## @end deftypefn
+
+## Return the version of gnuplot we are using.  Note that we do not
+## attempt to handle the case of the user switching to different
+## versions of gnuplot during the same session.
+
+function version = __gnuplot_version__ ()
+
+  persistent __version__ = "";
+
+  if (isempty (__version__))
+    [status, output] = system (sprintf ("\"%s\" --version", gnuplot_binary ()));
+    if (status != 0)
+      ## This message ends in a newline so that the traceback messages
+      ## are skipped and people might actually see the message, read it,
+      ## comprehend it, actually take the advice it gives, and stop
+      ## asking us why plotting fails when gnuplot is not found.
+      error ("you must have gnuplot installed to display graphics; if you have gnuplot installed in a non-standard location, see the 'gnuplot_binary' function\n");
+    endif
+    output = strrep (output, "gnuplot", "");
+    output = strrep (output, "patchlevel", ".");
+    output = strrep (output, "\n", "");
+    output = strrep (output, "\r", "");
+    __version__ = strrep (output, " ", "");
+  endif
+
+  version = __version__;
+
+endfunction
+
diff --git a/scripts/plot/__go_close_all__.m b/scripts/plot/__go_close_all__.m
new file mode 100644
index 0000000..30563fb
--- /dev/null
+++ b/scripts/plot/__go_close_all__.m
@@ -0,0 +1,28 @@
+## Copyright (C) 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __go_close_all__ ()
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function __go_close_all__ ()
+  close ("all", "hidden");
+endfunction
diff --git a/scripts/plot/__go_draw_axes__.m b/scripts/plot/__go_draw_axes__.m
new file mode 100644
index 0000000..7b79810
--- /dev/null
+++ b/scripts/plot/__go_draw_axes__.m
@@ -0,0 +1,2151 @@
+## Copyright (C) 2005, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __go_draw_axes__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function __go_draw_axes__ (h, plot_stream, enhanced, mono, implicit_margin)
+
+  if (nargin >= 4 && nargin <= 5)
+
+    showhiddenhandles = get (0, "showhiddenhandles");
+    unwind_protect
+      set (0, "showhiddenhandles", "on");
+      axis_obj = __get__ (h);
+    unwind_protect_cleanup
+      set (0, "showhiddenhandles", showhiddenhandles);
+    end_unwind_protect
+
+    parent_figure_obj = get (axis_obj.parent);
+    gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM");
+
+    ## Set to false for plotyy axes.
+    if (strcmp (axis_obj.tag, "plotyy"))
+      ymirror = false;
+    else
+      ymirror = true;
+    endif
+
+    nd = __calc_dimensions__ (axis_obj);
+    pos = axis_obj.position;
+    pos = pos - implicit_margin([1, 2, 1, 2]).*[1, 1, -0.5, -0.5];
+    if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
+      if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
+	pos = __actual_axis_position__ (axis_obj);
+      endif
+      if (nd == 2)
+	x = [1, 1];
+      else
+	## 3D plots need to be sized down to fit in the window.
+	x = 1.0 ./ sqrt([2, 2.5]);
+      endif
+      fprintf (plot_stream, "set tmargin screen %.15g;\n", pos(2)+pos(4)/2+x(2)*pos(4)/2);
+      fprintf (plot_stream, "set bmargin screen %.15g;\n", pos(2)+pos(4)/2-x(2)*pos(4)/2);
+      fprintf (plot_stream, "set lmargin screen %.15g;\n", pos(1)+pos(3)/2-x(1)*pos(3)/2);
+      fprintf (plot_stream, "set rmargin screen %.15g;\n", pos(1)+pos(3)/2+x(1)*pos(3)/2);
+    else
+      ## FIXME -- nothing should change for gnuplot 4.2.x.
+      fprintf (plot_stream, "set tmargin 0;\n");
+      fprintf (plot_stream, "set bmargin 0;\n");
+      fprintf (plot_stream, "set lmargin 0;\n");
+      fprintf (plot_stream, "set rmargin 0;\n");
+
+      fprintf (plot_stream, "set origin %.15g, %.15g;\n", pos(1), pos(2));
+      fprintf (plot_stream, "set size %.15g, %.15g;\n", pos(3), pos(4));
+
+      if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
+        r = axis_obj.dataaspectratio;
+        fprintf (plot_stream, "set size ratio %.15g;\n", -r(2)/r(1));
+      else
+        fputs (plot_stream, "set size noratio;\n");
+      endif
+    endif
+
+    ## Reset all labels, axis-labels, tick-labels, and title
+    ## FIXME - We should have an function to initialize the axis.
+    ##         Presently, this is dispersed in this function.
+    fputs (plot_stream, "unset label;\n");
+    fputs (plot_stream, "unset xtics;\n");
+    fputs (plot_stream, "unset ytics;\n");
+    fputs (plot_stream, "unset ztics;\n");
+    fputs (plot_stream, "unset x2tics;\n");
+    fputs (plot_stream, "unset x2tics;\n");
+
+    if (! isempty (axis_obj.title))
+      t = get (axis_obj.title);
+      if (isempty (t.string))
+	fputs (plot_stream, "unset title;\n");
+      else
+	[tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+	fontspec = create_fontspec (f, s, gnuplot_term);
+	fprintf (plot_stream, "set title \"%s\" %s %s",
+		 undo_string_escapes (tt), fontspec,
+		 __do_enhanced_option__ (enhanced, t));
+	if (nd == 3 && __gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
+	  fprintf (plot_stream, " offset screen 0, screen %.3f;\n", pos(4)/5);
+	else
+	  fprintf (plot_stream, ";\n");
+	endif
+      endif
+    endif
+
+    if (! isempty (axis_obj.xlabel))
+      t = get (axis_obj.xlabel);
+      angle = t.rotation;
+      colorspec = get_text_colorspec (axis_obj.xcolor, mono);
+      if (isempty (t.string))
+	fprintf (plot_stream, "unset xlabel;\n");
+	fprintf (plot_stream, "unset x2label;\n");
+      else
+	[tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+	fontspec = create_fontspec (f, s, gnuplot_term);
+	if (strcmpi (axis_obj.xaxislocation, "top"))
+	  fprintf (plot_stream, "set x2label \"%s\" %s %s %s",
+		   undo_string_escapes (tt), colorspec, fontspec,
+		   __do_enhanced_option__ (enhanced, t));
+	else
+	  fprintf (plot_stream, "set xlabel \"%s\" %s %s %s",
+		   undo_string_escapes (tt), colorspec, fontspec,
+		   __do_enhanced_option__ (enhanced, t));
+	endif
+	fprintf (plot_stream, " rotate by %f;\n", angle);
+	if (strcmpi (axis_obj.xaxislocation, "top"))
+	  fprintf (plot_stream, "unset xlabel;\n");
+	else
+	  fprintf (plot_stream, "unset x2label;\n");
+	endif
+      endif
+    endif
+
+    if (! isempty (axis_obj.ylabel))
+      t = get (axis_obj.ylabel);
+      angle = t.rotation;
+      colorspec = get_text_colorspec (axis_obj.ycolor, mono);
+      if (isempty (t.string))
+	fprintf (plot_stream, "unset ylabel;\n");
+	fprintf (plot_stream, "unset y2label;\n");
+      else
+	[tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+	fontspec = create_fontspec (f, s, gnuplot_term);
+	if (strcmpi (axis_obj.yaxislocation, "right"))
+	  fprintf (plot_stream, "set y2label \"%s\" %s %s %s",
+		   undo_string_escapes (tt), colorspec, fontspec,
+		   __do_enhanced_option__ (enhanced, t));
+	else
+	  fprintf (plot_stream, "set ylabel \"%s\" %s %s %s",
+		   undo_string_escapes (tt), colorspec, fontspec,
+		   __do_enhanced_option__ (enhanced, t));
+	endif
+	fprintf (plot_stream, " rotate by %f;\n", angle);
+	if (strcmpi (axis_obj.yaxislocation, "right"))
+	  fprintf (plot_stream, "unset ylabel;\n");
+	else
+	  fprintf (plot_stream, "unset y2label;\n");
+	endif
+      endif
+    endif
+
+    if (! isempty (axis_obj.zlabel))
+      t = get (axis_obj.zlabel);
+      angle = t.rotation;
+      colorspec = get_text_colorspec (axis_obj.zcolor, mono);
+      if (isempty (t.string))
+	fputs (plot_stream, "unset zlabel;\n");
+      else
+	[tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+	fontspec = create_fontspec (f, s, gnuplot_term);
+	fprintf (plot_stream, "set zlabel \"%s\" %s %s %s",
+		 undo_string_escapes (tt), colorspec, fontspec,
+		 __do_enhanced_option__ (enhanced, t));
+	fprintf (plot_stream, " rotate by %f;\n", angle);
+      endif
+    endif
+
+    if (strcmpi (axis_obj.xaxislocation, "top"))
+      xaxisloc = "x2";
+      xaxisloc_using = "x2";
+    else
+      xaxisloc = "x";
+      xaxisloc_using = "x1";
+      if (strcmpi (axis_obj.xaxislocation, "zero"))
+	fputs (plot_stream, "set xzeroaxis;\n");
+      endif
+    endif
+    if (strcmpi (axis_obj.yaxislocation, "right"))
+      yaxisloc = "y2";
+      yaxisloc_using = "y2";
+    else
+      yaxisloc = "y";
+      yaxisloc_using = "y1";
+      if (strcmpi (axis_obj.yaxislocation, "zero"))
+	fputs (plot_stream, "set yzeroaxis;\n");
+      endif
+    endif
+
+    have_grid = false;
+
+    if (strcmpi (axis_obj.xgrid, "on"))
+      have_grid = true;
+      fprintf (plot_stream, "set grid %stics;\n", xaxisloc);
+    else
+      fprintf (plot_stream, "set grid no%stics;\n", xaxisloc);
+    endif
+
+    if (strcmpi (axis_obj.ygrid, "on"))
+      have_grid = true;
+      fprintf (plot_stream, "set grid %stics;\n", yaxisloc);
+    else
+      fprintf (plot_stream, "set grid no%stics;\n", yaxisloc);
+    endif
+
+    if (strcmpi (axis_obj.zgrid, "on"))
+      have_grid = true;
+      fputs (plot_stream, "set grid ztics;\n");
+    else
+      fputs (plot_stream, "set grid noztics;\n");
+    endif
+
+    if (strcmpi (axis_obj.xminorgrid, "on"))
+      have_grid = true;
+      if (strcmp (axis_obj.xscale, "log"))
+	m = 10;
+      else
+	m = 5;
+      endif
+      fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m);
+      fprintf (plot_stream, "set grid m%stics;\n", xaxisloc);
+    else
+      fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc);
+    endif
+
+    if (strcmpi (axis_obj.yminorgrid, "on"))
+      have_grid = true;
+      if (strcmp (axis_obj.yscale, "log"))
+	m = 10;
+      else
+	m = 5;
+      endif
+      fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m);
+      fprintf (plot_stream, "set grid m%stics;\n", yaxisloc);
+    else
+      fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc);
+    endif
+
+    if (strcmpi (axis_obj.zminorgrid, "on"))
+      have_grid = true;
+      if (strcmp (axis_obj.zscale, "log"))
+	m = 10;
+      else
+	m = 5;
+      endif
+      fprintf (plot_stream, "set mztics %d;\n", m);
+      fputs (plot_stream, "set grid mztics;\n");
+    else
+      fputs (plot_stream, "set grid nomztics;\n");
+    endif
+
+    ## The grid front/back/layerdefault option also controls the
+    ## appearance of tics, so it is used even if the grid is absent.
+    if (strcmpi (axis_obj.layer, "top"))
+      fputs (plot_stream, "set grid front;\n");
+      fputs (plot_stream, "set border front;\n");
+    else
+      fputs (plot_stream, "set grid layerdefault;\n");
+      ## FIXME -- the gnuplot help says that "layerdefault" should work
+      ## for set border too, but it fails for me with gnuplot 4.2.5.  So
+      ## use "back" instead.
+      fputs (plot_stream, "set border back;\n");
+    endif
+    if (! have_grid)
+      fputs (plot_stream, "unset grid;\n");
+    endif
+
+    do_tics (axis_obj, plot_stream, ymirror, mono, gnuplot_term);
+
+    xlogscale = strcmpi (axis_obj.xscale, "log");
+    if (xlogscale)
+      fprintf (plot_stream, "set logscale %s;\n", xaxisloc);
+    else
+      fprintf (plot_stream, "unset logscale %s;\n", xaxisloc);
+    endif
+
+    ylogscale = strcmpi (axis_obj.yscale, "log");
+    if (ylogscale)
+      fprintf (plot_stream, "set logscale %s;\n", yaxisloc);
+    else
+      fprintf (plot_stream, "unset logscale %s;\n", yaxisloc);
+    endif
+
+    zlogscale = strcmpi (axis_obj.zscale, "log");
+    if (zlogscale)
+      fputs (plot_stream, "set logscale z;\n");
+    else
+      fputs (plot_stream, "unset logscale z;\n");
+    endif
+
+    xautoscale = strcmpi (axis_obj.xlimmode, "auto");
+    yautoscale = strcmpi (axis_obj.ylimmode, "auto");
+    zautoscale = strcmpi (axis_obj.zlimmode, "auto");
+    cautoscale = strcmpi (axis_obj.climmode, "auto");
+    cdatadirect = false;
+    truecolor = false;
+
+    fputs (plot_stream, "set clip two;\n");
+
+    kids = axis_obj.children;
+    ## Remove the axis labels and title from the children, and
+    ## preserved the original order.
+    [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ...
+                               axis_obj.zlabel; axis_obj.title]);
+    kids = kids (sort (k));
+
+    if (nd == 3)
+      fputs (plot_stream, "set parametric;\n");
+      fputs (plot_stream, "set style data lines;\n");
+      fputs (plot_stream, "set surface;\n");
+      fputs (plot_stream, "unset contour;\n");
+    endif
+
+    data_idx = 0;
+    data = cell ();
+    is_image_data = [];
+    hidden_removal = NaN;
+    view_map = false;
+
+    xlim = axis_obj.xlim;
+    ylim = axis_obj.ylim;
+    zlim = axis_obj.zlim;
+    clim = axis_obj.clim;
+
+    if (! cautoscale && clim(1) == clim(2))
+      clim(2)++;
+    endif
+    addedcmap = [];
+
+    [view_cmd, view_fcn, view_zoom] = image_viewer ();
+    use_gnuplot_for_images = (ischar (view_fcn)
+			      && strcmpi (view_fcn, "gnuplot_internal"));
+
+    ximg_data = {};
+    ximg_data_idx = 0;
+
+    while (! isempty (kids))
+
+      obj = get (kids(end));
+      kids = kids(1:(end-1));
+
+      if (strcmpi (obj.visible, "off"))
+	continue;
+      endif
+
+      ## Check for facecolor interpolation for surfaces.
+      doing_interp_color = ...
+         isfield (obj, "facecolor") && strncmp (obj.facecolor, "interp", 6);
+
+      switch (obj.type)
+	case "image"
+	  img_data = obj.cdata;
+	  img_xdata = obj.xdata;
+	  img_ydata = obj.ydata;
+
+	  if (use_gnuplot_for_images)
+
+	    if (ndims (img_data) == 3)
+	      truecolor = true;
+	    elseif (strcmpi (obj.cdatamapping, "direct"))
+	      cdatadirect = true;
+	    endif
+	    data_idx++;
+	    is_image_data(data_idx) = true;
+	    parametric(data_idx) = false;
+	    have_cdata(data_idx) = false;
+	    have_3d_patch(data_idx) = false;
+
+	    [y_dim, x_dim] = size (img_data(:,:,1));
+	    if (x_dim > 1)
+	      dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1);
+	    else
+	      x_dim = 2;
+	      img_data = [img_data, img_data];
+	      dx = abs (img_xdata(2)-img_xdata(1));
+	    endif
+	    if (y_dim > 1)
+	      dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1);
+	    else
+	      y_dim = 2;
+	      img_data = [img_data; img_data];
+	      dy = abs (img_ydata(2)-img_ydata(1));
+	    endif
+	    x_origin = min (img_xdata);
+	    y_origin = min (img_ydata);
+
+	    if (ndims (img_data) == 3)
+	      data{data_idx} = permute (img_data, [3, 1, 2])(:);
+	      format = "1:2:3";
+	      imagetype = "rgbimage";
+	    else
+	      data{data_idx} = img_data(:);
+	      format = "1";
+	      imagetype = "image";
+	    endif
+
+	    titlespec{data_idx} = "title \"\"";
+	    usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s",
+		x_dim, y_dim, x_origin, y_origin, dx, dy, format);
+	    withclause{data_idx} = sprintf ("with %s;", imagetype);
+
+	  else
+	    ximg_data{++ximg_data_idx} = img_data;
+	  endif
+
+	case "line"
+	  if (strncmp (obj.linestyle, "none", 4)
+	      && (! isfield (obj, "marker")
+		  || (isfield (obj, "marker")
+		      && strncmp (obj.marker, "none", 4))))
+	    continue;
+	  endif
+	  data_idx++;
+	  is_image_data(data_idx) = false;
+	  parametric(data_idx) = true;
+	  have_cdata(data_idx) = false;
+	  have_3d_patch(data_idx) = false;
+
+	  if (isempty (obj.keylabel))
+	    titlespec{data_idx} = "title \"\"";
+	  else
+	    tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel"));
+	    titlespec{data_idx} = cstrcat ("title \"", tmp, "\"");
+	  endif
+	  usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
+	  errbars = "";
+	  if (nd == 3)
+	    xdat = obj.xdata(:);
+	    ydat = obj.ydata(:);
+	    if (! isempty (obj.zdata))
+	      zdat = obj.zdata(:);
+	    else
+	      zdat = zeros (size (xdat));
+	    endif
+	    data{data_idx} = [xdat, ydat, zdat]';
+	    usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat));
+	    ## fputs (plot_stream, "set parametric;\n");
+	  else
+	    xdat = obj.xdata(:);
+	    ydat = obj.ydata(:);
+	    ldat = obj.ldata;
+	    yerr = xerr = false;
+	    if (! isempty (ldat))
+	      yerr = true;
+	      ldat = ldat(:);
+	    endif
+	    udat = obj.udata;
+	    if (! isempty (udat))
+	      udat = udat(:);
+	    endif
+	    xldat = obj.xldata;
+	    if (! isempty (xldat))
+	      xerr = true;
+	      xldat = xldat(:);
+	    endif
+	    xudat = obj.xudata;
+	    if (! isempty (xudat))
+	      xudat = xudat(:);
+	    endif
+	    if (yerr)
+	      if (isempty (ldat))
+		ylo = ydat;
+	      else
+		ylo = ydat-ldat;
+	      endif
+	      if (isempty (udat))
+		yhi = ydat;
+	      else
+		yhi = ydat+udat;
+	      endif
+	      if (xerr)
+		if (isempty (xldat))
+		  xlo = xdat;
+		else
+		  xlo = xdat-xldat;
+		endif
+		if (isempty (xudat))
+		  xhi = xdat;
+		else
+		  xhi = xdat+xudat;
+		endif
+		data{data_idx} = [xdat, ydat, xlo, xhi, ylo, yhi]';
+		usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4):($5):($6)", numel (xdat));
+		errbars = "xyerrorbars";
+	      else
+		data{data_idx} = [xdat, ydat, ylo, yhi]';
+		usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", numel (xdat));
+		errbars = "yerrorbars";
+	      endif
+	    elseif (xerr)
+	      if (isempty (xldat))
+		xlo = xdat;
+	      else
+		xlo = xdat-xldat;
+	      endif
+	      if (isempty (xudat))
+		xhi = xdat;
+	      else
+		xhi = xdat+xudat;
+	      endif
+	      data{data_idx} = [xdat, ydat, xlo, xhi]';
+	      usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", numel (xdat));
+	      errbars = "xerrorbars";
+	    else
+	      data{data_idx} = [xdat, ydat]';
+	      usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s",
+					      rows(xdat), xaxisloc_using, yaxisloc_using);
+	    endif
+	  endif
+
+	  [style, typ, with] = do_linestyle_command (obj, data_idx, mono,
+						     plot_stream, errbars);
+
+	  withclause{data_idx} = sprintf ("with %s linestyle %d",
+					  style, data_idx);
+
+       case "patch"
+         cmap = parent_figure_obj.colormap;
+	 [nr, nc] = size (obj.xdata);
+
+	 if (! isempty (obj.cdata))
+	   cdat = obj.cdata;
+	   if (strcmpi (obj.cdatamapping, "direct"))
+	     cdatadirect = true;
+	   endif
+	 else
+	   cdat = [];
+	 endif
+
+	 data_3d_idx = NaN;
+	 for i = 1:nc
+	   xcol = obj.xdata(:,i);
+	   ycol = obj.ydata(:,i);
+	   if (nd == 3)
+	     if (! isempty (obj.zdata))
+	       zcol = obj.zdata(:,i);
+	     else
+	       zcol = zeros (size (xcol));
+	     endif
+	   endif
+
+	   if (! isnan (xcol) && ! isnan (ycol))
+	     ## Is the patch closed or not
+	     if (strncmp (obj.facecolor, "none", 4)) 
+	       hidden_removal = false;
+	     else
+
+	       if (isnan (hidden_removal))
+		 hidden_removal = true;
+	       endif
+	       if (nd == 3)
+		 if (numel (xcol) > 3)
+		   error ("gnuplot (as of v4.2) only supports 3D filled triangular patches");
+		 else
+		   if (isnan (data_3d_idx))
+		     data_idx++;
+		     data_3d_idx = data_idx; 
+		     is_image_data(data_idx) = false;
+		     parametric(data_idx) = false;
+		     have_cdata(data_idx) = true;
+		     have_3d_patch(data_idx) = true;
+		     withclause{data_3d_idx} = sprintf ("with pm3d");
+		     usingclause{data_3d_idx} =  "using 1:2:3:4";
+		     data{data_3d_idx} = [];
+		   endif
+		   local_idx = data_3d_idx;
+		   ccdat = NaN;
+		 endif
+	       else
+		 data_idx++;
+		 local_idx = data_idx;
+		 is_image_data(data_idx) = false;
+		 parametric(data_idx) = false;
+		 have_cdata(data_idx) = false;
+		 have_3d_patch(data_idx) = false;
+	       endif
+
+	       if (i > 1 || isempty (obj.keylabel))
+		 titlespec{local_idx} = "title \"\"";
+	       else
+		 tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel"));
+		 titlespec{local_idx} = cstrcat ("title \"", tmp, "\"");
+	       endif
+               if (isfield (obj, "facecolor"))
+		 if ((strncmp (obj.facecolor, "flat", 4)
+		     || strncmp (obj.facecolor, "interp", 6))
+		     && isfield (obj, "cdata"))
+		   if (ndims (obj.cdata) == 2
+		       && (size (obj.cdata, 2) == nc
+			   && (size (obj.cdata, 1) == 1
+			       || size (obj.cdata, 1) == 3)))
+		     ccol = cdat (:, i);
+		   elseif (ndims (obj.cdata) == 2
+		       && (size (obj.cdata, 1) == nc
+			   && (size (obj.cdata, 2) == 1
+			       || size (obj.cdata, 2) == 3)))
+		     ccol = cdat (i, :);
+		   elseif (ndims (obj.cdata) == 3)
+		     ccol = permute (cdat (:, i, :), [1, 3, 2]);
+		   else
+		     ccol = cdat;
+		   endif
+		   if (strncmp (obj.facecolor, "flat", 4))
+		     if (numel(ccol) == 3)
+		       color = ccol;
+		     elseif (nd == 3 && numel (xcol) == 3)
+		       ccdat = ccol * ones (3,1);
+		     else
+		       r = 1 + round ((size (cmap, 1) - 1)
+				      * (ccol - clim(1))/(clim(2) - clim(1)));
+		       r = max (1, min (r, size (cmap, 1)));
+		       color = cmap(r, :);
+		     endif
+		   elseif (strncmp (obj.facecolor, "interp", 6))
+		     if (nd == 3 && numel (xcol) == 3)
+		       ccdat = ccol;
+		       if (! isvector (ccdat))
+			 tmp = rows(cmap) + rows(addedcmap) + ... 
+			      [1 : rows(ccdat)];
+			 addedcmap = [addedcmap; ccdat];
+			 ccdat = tmp(:);
+		       else
+			 ccdat = ccdat(:);
+		       endif
+		     else
+		       warning ("\"interp\" not supported, using 1st entry of cdata");
+		       r = 1 + round ((size (cmap, 1) - 1) * ccol(1));
+		       r = max (1, min (r, size (cmap, 1)));
+		       color = cmap(r,:);
+		     endif
+		   endif
+		 elseif (isnumeric (obj.facecolor))
+		   color = obj.facecolor;
+		 else
+		   color = [0, 1, 0];
+		 endif
+               else
+		 color = [0, 1, 0];
+               endif
+
+	       if (nd == 3 && numel (xcol) == 3)
+		 if (isnan (ccdat))
+		   ccdat = (rows (cmap) + rows(addedcmap) + 1) * ones(3, 1);
+		   addedcmap = [addedcmap; reshape(color, 1, 3)];
+		 endif
+		 data{data_3d_idx} = [data{data_3d_idx}, ...
+				      [[xcol; xcol(end)], [ycol; ycol(end)], ...
+				      [zcol; zcol(end)], [ccdat; ccdat(end)]]'];
+	       else
+		 if (mono)
+		   colorspec = "";
+		 elseif (__gnuplot_has_feature__ ("transparent_patches")
+			 && isscalar (obj.facealpha))
+                   colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f",
+				      round (255*color), obj.facealpha);
+		 else
+		   colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+					round (255*color));
+		 endif
+
+		 withclause{data_idx} = sprintf ("with filledcurve %s",
+					       colorspec);
+		 data{data_idx} = [xcol, ycol]';
+		 usingclause{data_idx} = sprintf ("record=%d using ($1):($2)",
+						  numel (xcol));
+	       endif
+	     endif
+	   endif
+
+           ## patch outline
+	   if (! strncmp (obj.edgecolor, "none", 4))
+
+	     data_idx++;
+             is_image_data(data_idx) = false;
+             parametric(data_idx) = false;
+	     have_cdata(data_idx) = false;
+	     have_3d_patch(data_idx) = false;
+             titlespec{data_idx} = "title \"\"";
+	     usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
+
+	     if (isfield (obj, "markersize"))
+	       mdat = obj.markersize / 3;
+	     endif
+
+             if (isfield (obj, "edgecolor"))
+	       if ((strncmp (obj.edgecolor, "flat", 4)
+		    || strncmp (obj.edgecolor, "interp", 6))
+		   && isfield (obj, "cdata"))
+		 if (ndims (obj.cdata) == 2
+		     && (size (obj.cdata, 2) == nc
+			 && (size (obj.cdata, 1) == 1
+			     || size (obj.cdata, 1) == 3)))
+		   ccol = cdat (:, i);
+		 elseif (ndims (obj.cdata) == 2
+			 && (size (obj.cdata, 1) == nc
+			     && (size (obj.cdata, 2) == 1
+				 || size (obj.cdata, 2) == 3)))
+		   ccol = cdat (i, :);
+		 elseif (ndims (obj.cdata) == 3)
+		   ccol = permute (cdat (:, i, :), [1, 3, 2]);
+		 else
+		   ccol = cdat;
+		 endif
+		 if (strncmp (obj.edgecolor, "flat", 4))
+		   if (numel(ccol) == 3)
+		     color = ccol;
+		   else
+		     r = 1 + round ((size (cmap, 1) - 1)
+				    * (ccol - clim(1))/(clim(2) - clim(1)));
+		     r = max (1, min (r, size (cmap, 1)));
+		     color = cmap(r, :);
+		   endif
+		 elseif (strncmp (obj.edgecolor, "interp", 6))
+		   warning ("\"interp\" not supported, using 1st entry of cdata");
+		   r = 1 + round ((size (cmap, 1) - 1) * ccol(1));
+		   r = max (1, min (r, size (cmap, 1)));
+		   color = cmap(r,:);
+		 endif
+	       elseif (isnumeric (obj.edgecolor))
+		 color = obj.edgecolor;
+	       else
+		 color = [0, 0, 0];
+	       endif
+             else
+	       color = [0, 0, 0];
+             endif
+
+	     if (isfield (obj, "linestyle"))
+	       switch (obj.linestyle)
+		 case "-"
+		   lt = "lt 1";
+		 case "--"
+		   lt = "lt 2";
+		 case ":"
+		   lt = "lt 3";
+		 case "-."
+		   lt = "lt 6";
+		 case "none"
+		   lt = "";
+		 otherwise
+		   lt = "";
+	       endswitch
+	     else
+	       lt = "";
+	     endif
+
+	     if (isfield (obj, "linewidth"))
+	       lw = sprintf("linewidth %f", obj.linewidth);
+	     else
+	       lw  = "";
+	     endif
+
+	     if (isfield (obj, "marker"))
+	       if (isfield (obj, "marker"))
+		 switch (obj.marker)
+		   case "+"
+		     pt = "pt 1";
+		   case "o"
+		     pt = "pt 6";
+		   case "*"
+		     pt = "pt 3";
+		   case "."
+		     pt = "pt 0";
+		   case "x"
+		     pt = "pt 2";
+		   case {"square", "s"}
+		     pt = "pt 5";
+		   case {"diamond", "d"}
+		     pt = "pt 13";
+		   case "^"
+		     pt = "pt 9";
+		   case "v"
+		     pt = "pt 11";
+		   case ">"
+		     pt = "pt 8";
+		   case "<"
+		     pt = "pt 10";
+		   case {"pentagram", "p"}
+		     pt = "pt 4";
+		   case {"hexagram", "h"}
+		     pt = "pt 12";
+		   case "none"
+		     pt = "";
+		   otherwise
+		     pt = "";
+		 endswitch
+	       endif
+	     else
+	       pt = "";
+	     endif
+
+	     style = "lines";
+	     if (isempty (lt))
+	       if (! isempty (pt))
+		 style = "points";
+	       endif
+	     elseif (! isempty (pt))
+	       style = "linespoints";
+	     endif
+
+	     if (isfield (obj, "markersize"))
+	       if (length (mdat) == nc)
+		 m = mdat(i);
+	       else
+		 m = mdat;
+	       endif
+	       if (! strcmpi (style, "lines"))
+		 ps = sprintf("pointsize %f", m);
+	       else
+		 ps = "";
+	       endif
+	     else
+	       ps = "";
+	     endif
+
+	     if (mono)
+	       colorspec = "";
+	     else
+	       colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+				    round (255*color));
+	     endif
+	     withclause{data_idx} = sprintf ("with %s %s %s %s %s %s",
+					     style, lw, pt, lt, ps, 
+					     colorspec);
+
+	     if (nd == 3)
+	       if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
+		 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
+				   [zcol; zcol(1)]]';
+	       else
+		 data{data_idx} = [xcol, ycol, zcol]';
+	       endif
+	       usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
+	     else
+	       if (! isnan (xcol) && ! isnan (ycol))
+		 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]';
+	       else
+		 data{data_idx} = [xcol, ycol]';
+	       endif
+	       usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx}));
+	     endif
+	   endif
+	 endfor
+
+	case "surface"
+	  view_map = true;
+          if (! (strncmp (obj.edgecolor, "none", 4)
+		 && strncmp (obj.facecolor, "none", 4)))
+	    data_idx++;
+	    is_image_data(data_idx) = false;
+	    parametric(data_idx) = false;
+	    have_cdata(data_idx) = true;
+	    have_3d_patch(data_idx) = false;
+	    [style, typ, with] = do_linestyle_command (obj, data_idx,
+						       mono, plot_stream);
+	    if (isempty (obj.keylabel))
+	      titlespec{data_idx} = "title \"\"";
+	    else
+	      tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel"));
+	      titlespec{data_idx} = cstrcat ("title \"", tmp, "\"");
+	    endif
+	    withclause{data_idx} = sprintf ("with pm3d linestyle %d",
+		           		    data_idx);
+
+	    xdat = obj.xdata;
+	    ydat = obj.ydata;
+	    zdat = obj.zdata;
+	    cdat = obj.cdata;
+
+  	    err = false;
+            if (! size_equal(zdat, cdat))
+              err = true;
+            endif
+	    if (isvector (xdat) && isvector (ydat) && ismatrix (zdat))
+	      if (rows (zdat) == length (ydat)
+		  && columns (zdat) == length (xdat))
+                [xdat, ydat] = meshgrid (xdat, ydat);
+	      else
+                err = true;
+	      endif
+	    elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat))
+	      if (! size_equal (xdat, ydat, zdat))
+                err = true;
+	      endif
+	    else
+	      err = true;
+	    endif
+	    if (err)
+	      error ("__go_draw_axes__: invalid grid data");
+	    endif
+	    xlen = columns (zdat);
+	    ylen = rows (zdat);
+	    if (xlen == columns (xdat) && xlen == columns (ydat)
+	        && ylen == rows (xdat) && ylen == rows (ydat))
+	      len = 4 * xlen;
+	      zz = zeros (ylen, len);
+	      k = 1;
+	      for kk = 1:4:len
+	        zz(:,kk)   = xdat(:,k);
+	        zz(:,kk+1) = ydat(:,k);
+	        zz(:,kk+2) = zdat(:,k);
+	        zz(:,kk+3) = cdat(:,k);
+	        k++;
+	      endfor
+	      data{data_idx} = zz.';
+	    endif
+
+	    if (doing_interp_color)
+	      interp_str = "interpolate 0, 0";
+	    else
+	      ## No interpolation of facecolors.
+	      interp_str = "";
+	    endif
+	    usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen);
+
+            flat_interp_face = (strncmp (obj.facecolor, "flat", 4)
+				|| strncmp (obj.facecolor, "interp", 6));
+            flat_interp_edge = (strncmp (obj.edgecolor, "flat", 4)
+				|| strncmp (obj.edgecolor, "interp", 6));
+
+	    facecolor_none_or_white = (strncmp (obj.facecolor, "none", 4)
+				       || (isnumeric (obj.facecolor)
+					   && all (obj.facecolor == 1)));
+	    hidden_removal = false;
+            fputs (plot_stream, "set style increment default;\n");
+            if (flat_interp_edge && facecolor_none_or_white)
+	      withclause{data_idx} = "with line palette";
+	      fputs (plot_stream, "unset pm3d\n");
+	      if (all (obj.facecolor == 1))
+                hidden_removal = true;
+              endif
+	    elseif (facecolor_none_or_white)
+	      edgecol = obj.edgecolor;
+	      if (mono)
+		colorspec = "";
+	      else
+		colorspec = sprintf ("linecolor rgb \"#%02x%02x%02x\"",
+				     round (255*edgecol));
+	      endif
+	      if (all (obj.facecolor == 1))
+                hidden_removal = true;
+              endif
+	      fputs(plot_stream,"unset pm3d;\n");
+              fprintf (plot_stream,
+                       "set style line %d %s lw %f;\n",
+                       data_idx, colorspec, obj.linewidth);
+	      fputs(plot_stream,"set style increment user;\n");
+	      withclause{data_idx} = sprintf("with line linestyle %d", data_idx);
+	      fputs (plot_stream, "unset pm3d\n");
+            endif
+
+	    if (doing_interp_color)
+	      ## "depthorder" interferes with interpolation of colors.
+	      dord = "scansautomatic";
+	    else
+	      dord = "depthorder";
+	    endif
+
+	    if (flat_interp_face && strncmp (obj.edgecolor, "flat", 4))
+              fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n", 
+		       interp_str, dord);
+            elseif (!facecolor_none_or_white)
+              if (strncmp (obj.edgecolor, "none", 4))
+                if (__gnuplot_has_feature__ ("transparent_surface") 
+                    && isscalar (obj.facealpha))
+                  fprintf (plot_stream,
+                           "set style fill transparent solid %f;\n",
+                           obj.facealpha);
+                endif
+                fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n", 
+			 interp_str, dord);
+              else
+                edgecol = obj.edgecolor;
+                if (ischar (obj.edgecolor))
+                  edgecol = [0, 0, 0];
+                endif
+                fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n", 
+			 data_idx, interp_str, dord);
+
+		if (mono)
+		  colorspec = "";
+		else
+		  colorspec = sprintf ("linecolor rgb \"#%02x%02x%02x\"",
+				       round (255*edgecol));
+		endif
+                fprintf (plot_stream,
+                         "set style line %d %s lw %f;\n",
+                         data_idx, colorspec, obj.linewidth);
+                if (__gnuplot_has_feature__ ("transparent_surface") 
+                    && isscalar (obj.facealpha))
+                  fprintf (plot_stream,
+                           "set style fill transparent solid %f;\n",
+                           obj.facealpha);
+                endif
+              endif
+            endif
+	  endif
+
+	case "text"
+	  [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string");
+	  fontspec = create_fontspec (f, s, gnuplot_term);
+	  lpos = obj.position;
+	  halign = obj.horizontalalignment;
+	  angle = obj.rotation;
+          units = obj.units;
+	  color = obj.color;
+          if (strcmpi (units, "normalized"))
+            units = "graph";
+          else
+            units = "";
+          endif
+	  
+	  if (isnumeric (color))
+	    colorspec = get_text_colorspec (color, mono);
+	  endif
+
+	  if (nd == 3)
+	    fprintf (plot_stream,
+		     "set label \"%s\" at %s %.15g,%.15g,%.15g %s rotate by %f %s %s front %s;\n",
+		     undo_string_escapes (label), units, lpos(1),
+		     lpos(2), lpos(3), halign, angle, fontspec,
+		     __do_enhanced_option__ (enhanced, obj), colorspec);
+	  else
+ 	    fprintf (plot_stream,
+ 		     "set label \"%s\" at %s %.15g,%.15g %s rotate by %f %s %s front %s;\n",
+ 		     undo_string_escapes (label), units,
+ 		     lpos(1), lpos(2), halign, angle, fontspec,
+		     __do_enhanced_option__ (enhanced, obj), colorspec);
+	  endif
+
+        case "hggroup"
+	  ## Push group children into the kid list.
+	  if (isempty (kids))
+	    kids = obj.children;
+	  elseif (! isempty (obj.children))
+	    kids = [kids; obj.children];
+	  endif
+
+	otherwise
+	  error ("__go_draw_axes__: unknown object class, %s",
+		 obj.type);
+      endswitch
+
+    endwhile
+
+    ## This is need to prevent warnings for rotations in 3D plots, while
+    ## allowing colorbars with contours.
+    if (nd == 2 || (data_idx > 1 && !view_map))
+      fputs (plot_stream, "set pm3d implicit;\n");
+    else
+      fputs (plot_stream, "set pm3d explicit;\n");
+    endif
+
+    if (isnan(hidden_removal) || hidden_removal)
+      fputs (plot_stream, "set hidden3d;\n");
+    else
+      fputs (plot_stream, "unset hidden3d;\n");
+    endif
+
+    have_data = (! (isempty (data) || all (cellfun (@isempty, data))));
+
+    ## Note we don't use the [xy]2range of gnuplot as we don't use the
+    ## dual axis plotting features of gnuplot.
+    if (isempty (xlim))
+      return;
+    endif
+    if (strcmpi (axis_obj.xdir, "reverse"))
+      xdir = "reverse";
+    else
+      xdir = "noreverse";
+    endif
+    fprintf (plot_stream, "set xrange [%.15e:%.15e] %s;\n", xlim, xdir);
+    if (strcmpi (axis_obj.xaxislocation, "top"))
+      fprintf (plot_stream, "set x2range [%.15e:%.15e] %s;\n", xlim, xdir);
+    endif
+
+    if (isempty (ylim))
+      return;
+    endif
+    if (strcmpi (axis_obj.ydir, "reverse"))
+      ydir = "reverse";
+    else
+      ydir = "noreverse";
+    endif
+    fprintf (plot_stream, "set yrange [%.15e:%.15e] %s;\n", ylim, ydir);
+    if (strcmpi (axis_obj.yaxislocation, "right"))
+      fprintf (plot_stream, "set y2range [%.15e:%.15e] %s;\n", ylim, ydir);
+    endif
+
+    if (nd == 3)
+      if (isempty (zlim))
+	return;
+      endif
+      if (strcmpi (axis_obj.zdir, "reverse"))
+	zdir = "reverse";
+      else
+	zdir = "noreverse";
+      endif
+      fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir);
+    endif
+
+    cmap = parent_figure_obj.colormap;    
+    cmap_sz = rows(cmap);
+    if (! any (isinf (clim)))
+      if (truecolor || ! cdatadirect)
+	if (rows(addedcmap) > 0)
+	  for i = 1:data_idx
+	    if (have_3d_patch(i))
+	      data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz;
+	     endif
+	  endfor
+	  fprintf (plot_stream, "set cbrange [%g:%g];\n", clim(1), clim(2) * 
+		   (cmap_sz + rows(addedcmap)) / cmap_sz);
+	else
+	  fprintf (plot_stream, "set cbrange [%g:%g];\n", clim);
+	endif
+      else
+	fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz + 
+		 rows (addedcmap));
+      endif
+    endif
+
+    if (strcmpi (axis_obj.box, "on"))
+      if (nd == 3)
+	fputs (plot_stream, "set border 4095;\n");
+      else
+	fputs (plot_stream, "set border 431;\n");
+      endif
+    else
+      if (nd == 3)
+	fputs (plot_stream, "set border 895;\n");
+      else
+	if (strcmpi (axis_obj.yaxislocation, "right"))
+	  fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n",
+		   axis_obj.tickdir);
+	  if (strcmpi (axis_obj.xaxislocation, "top"))
+	    fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
+		     axis_obj.tickdir);
+	    fputs (plot_stream, "set border 12;\n");
+	  else
+	    fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+		     axis_obj.tickdir);
+	    fputs (plot_stream, "set border 9;\n");
+	  endif
+	else
+	  fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
+		   axis_obj.tickdir);
+	  if (strcmpi (axis_obj.xaxislocation, "top"))
+	    fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
+		     axis_obj.tickdir);
+	    fputs (plot_stream, "set border 6;\n");
+	  else
+	    fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+		     axis_obj.tickdir);
+	    fputs (plot_stream, "set border 3;\n");
+	  endif
+	endif
+      endif
+    endif
+
+    if (strcmpi (axis_obj.visible, "off"))
+      fputs (plot_stream, "unset border; unset tics\n");
+    else
+      fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth);
+    endif
+
+    if (strcmpi (axis_obj.key, "on"))
+      if (strcmpi (axis_obj.keybox, "on"))
+	box = "box";
+      else
+	box = "nobox";
+      endif
+      if (strcmpi (axis_obj.keyreverse, "on"))
+	reverse = "reverse";
+      else
+	reverse = "noreverse";
+      endif
+      inout = "inside";
+      keypos = axis_obj.keypos;
+      if (ischar (keypos))
+	keypos = lower (keypos);
+	keyout = findstr (keypos, "outside");
+	if (! isempty (keyout))
+	  inout = "outside";
+	  keypos = keypos(1:keyout-1);
+	endif
+      endif
+      switch (keypos)
+	case -1
+	  pos = "right top";
+	  inout = "outside";
+	case 1
+	  pos = "right top";
+	case 2
+	  pos = "left top";
+	case 3
+	  pos = "left bottom";
+	case {4, 0}
+	  pos = "right bottom";
+	case "north"
+	  pos = "center top";
+	case "south"
+	  pos = "center bottom";
+	case "east"
+	  pos = "right center";
+	case "west"
+	  pos = "left center";
+	case "northeast"
+	  pos = "right top";
+	case "northwest"
+	  pos = "left top";
+	case "southeast"
+	  pos = "right bottom";
+	case "southwest"
+	  pos = "left bottom";
+	case "best" 
+	  pos = "";
+	  warning ("legend: 'Best' not yet implemented for location specifier.\n");
+	  ## Least conflict with data in plot.
+	  ## Least unused space outside plot.
+	otherwise
+	  pos = "";
+      endswitch
+      if (__gnuplot_has_feature__ ("key_has_font_properties"))
+        fontspec = create_fontspec (axis_obj.fontname, axis_obj.fontsize, gnuplot_term);
+      else
+	fontspec = "";
+      endif
+      fprintf (plot_stream, "set key %s %s %s %s %s;\n", inout, pos, box,
+               reverse, fontspec);
+    else
+      fputs (plot_stream, "unset key;\n");
+    endif
+
+    fputs (plot_stream, "set style data lines;\n");
+
+    if (! use_gnuplot_for_images)
+      for i = 1:ximg_data_idx
+	view_fcn (xlim, ylim, ximg_data{i}, view_zoom, view_cmd);
+      endfor
+    endif
+
+    cmap = [cmap; addedcmap];
+    cmap_sz = cmap_sz + rows(addedcmap);
+    if (length(cmap) > 0)
+      fprintf (plot_stream,
+	       "set palette positive color model RGB maxcolors %i;\n",
+	       cmap_sz);
+      fprintf (plot_stream,
+	       "set palette file \"-\" binary record=%d using 1:2:3:4;\n",
+	       cmap_sz);
+      fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32");
+      fwrite (plot_stream, "\n");
+    endif
+
+    fputs (plot_stream, "unset colorbox;\n");
+
+    if (have_data)
+      if (nd == 2)
+	plot_cmd = "plot";
+      else
+	plot_cmd = "splot";
+	rot_x = 90 - axis_obj.view(2);
+	rot_z = axis_obj.view(1);
+	while (rot_z < 0)
+	  rot_z += 360;
+	endwhile
+ 	fputs (plot_stream, "set ticslevel 0;\n");
+	if (view_map && rot_x == 0 && rot_z == 0)
+	  fputs (plot_stream, "set view map;\n");
+	else
+	  fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z);
+	endif
+      endif
+      if (have_3d_patch (1))
+	fputs (plot_stream, "set pm3d depthorder\n");
+	fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
+		 usingclause{1}, titlespec{1}, withclause{1});
+      elseif (is_image_data (1))
+	fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
+		 usingclause{1}, titlespec{1}, withclause{1});
+      else
+	fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
+		 usingclause{1}, titlespec{1}, withclause{1});
+      endif
+      for i = 2:data_idx
+	if (have_3d_patch (i))
+	  fprintf (plot_stream, ", \"-\" %s %s %s \\\n",
+		   usingclause{i}, titlespec{i}, withclause{i});
+	elseif (is_image_data (i))
+	  if (! is_image_data (i-1))
+	    fputs (plot_stream, "; ");
+	  endif
+          fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
+		   usingclause{i}, titlespec{i}, withclause{i});
+	elseif (is_image_data (i-1))
+	  fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
+		   usingclause{i}, titlespec{i}, withclause{i});
+	else
+	  fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n",
+		   usingclause{i}, titlespec{i}, withclause{i});
+	endif
+      endfor
+      fputs (plot_stream, ";\n");
+      for i = 1:data_idx
+	if (have_3d_patch (i))
+	  ## Can't write 3d patch data as binary as can't plot more than 
+	  ## a single patch at a time and have to plot all patches together
+	  ## so that the gnuplot depth ordering is done correctly
+	  for j = 1 : 4 : columns(data{i})
+	    if (j != 1)
+	      fputs (plot_stream, "\n\n");
+	    endif
+	    fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).');
+	    fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).');
+	    fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).');
+	    fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).');
+	  endfor
+	  fputs (plot_stream, "e\n");
+	elseif (is_image_data(i))
+	  fwrite (plot_stream, data{i}, "float32");
+	else
+	  __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i), 
+				  have_cdata(i));
+	endif
+      endfor
+    else
+      fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n");
+    endif
+
+    ## Needed to allow mouse rotation with pcolor.
+    if (view_map)
+      fputs (plot_stream, "unset view;\n");
+    endif
+
+    fflush (plot_stream);
+
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+function fontspec = create_fontspec (f, s, gp_term)
+  if (strcmp (f, "*"))
+    fontspec = sprintf ("font \",%d\"", s);
+  else
+    fontspec = sprintf ("font \"%s,%d\"", f, s);
+  endif
+endfunction
+
+function [style, typ, with] = do_linestyle_command (obj, idx, mono,
+						    plot_stream, errbars = "")
+
+  fprintf (plot_stream, "set style line %d default;\n", idx);
+  fprintf (plot_stream, "set style line %d", idx);
+
+  found_style = false;
+  typ = NaN;
+  with = "";
+
+  if (isfield (obj, "color"))
+    color = obj.color;
+    if (isnumeric (color))
+      if (! mono)
+	fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
+		 round (255*color));
+      endif
+    endif
+    found_style = true;
+  endif
+
+  if (isfield (obj, "linestyle"))
+    switch (obj.linestyle)
+      case "-"
+	lt = "1";
+      case "--"
+	lt = "2";
+      case ":"
+	lt = "3";
+      case "-."
+	lt = "6";
+      case "none"
+	lt = "";
+      otherwise
+	lt = "";
+    endswitch
+
+    ## FIXME -- linetype is currently broken, since it disables the
+    ## gnuplot default dashed and solid linestyles with the only
+    ## benefit of being able to specify '--' and get a single sized
+    ## dashed line of identical dash pattern for all called this way.
+    ## All dash patterns are a subset of "with lines" and none of the
+    ## lt specifications will correctly propagate into the x11 terminal
+    ## or the print command.   Therefore, it is currently disabled in
+    ## order to allow print (..., "-dashed") etc. to work correctly.
+
+    ##    if (! isempty (lt))
+    ##      fprintf (plot_stream, " linetype %s", lt);
+    ##      found_style = true;
+    ##    endif
+
+  else
+    lt = "";
+  endif
+
+  if (isfield (obj, "linewidth"))
+    fprintf (plot_stream, " linewidth %f", obj.linewidth);
+    found_style = true;
+  endif
+
+  if (isfield (obj, "marker"))
+    switch (obj.marker)
+      case "+"
+	pt = "1";
+      case "o"
+	pt = "6";
+      case "*"
+	pt = "3";
+      case "."
+	pt = "0";
+      case "x"
+	pt = "2";
+      case {"square", "s"}
+	pt = "5";
+      case {"diamond", "d"}
+	pt = "13";
+      case "^"
+	pt = "9";
+      case "v"
+	pt = "11";
+      case ">"
+	pt = "8";
+      case "<"
+	pt = "10";
+      case {"pentagram", "p"}
+	pt = "4";
+      case {"hexagram", "h"}
+	pt = "12";
+      case "none"
+	pt = "";
+      otherwise
+	pt = "";
+    endswitch
+    if (! isempty (pt))
+      fprintf (plot_stream, " pointtype %s", pt);
+      found_style = true;
+    endif
+  else
+    pt = "";
+  endif
+
+  if (isempty (errbars))
+    style = "lines";
+    if (isempty (lt))
+      if (! isempty (pt))
+	style = "points";
+      endif
+    elseif (! isempty (pt))
+      style = "linespoints";
+    endif
+
+    if (isfield (obj, "markersize"))
+      fprintf (plot_stream, " pointsize %f", obj.markersize / 3);
+      found_style = true;
+    endif
+  else
+    style = errbars;
+    found_style = true;
+  endif
+
+  if (! found_style)
+    fputs (plot_stream, " default");
+  endif
+
+  fputs (plot_stream, ";\n");
+
+endfunction
+
+function nd = __calc_dimensions__ (obj)
+  kids = obj.children;
+  nd = 2;
+  for i = 1:length (kids)
+    obj = get (kids(i));
+    switch (obj.type)
+      case {"image", "text"}
+	## ignore as they 
+      case {"line", "patch"}
+	if (! isempty (obj.zdata))
+	  nd = 3;
+	endif
+      case "surface"
+	nd = 3;
+      case "hggroup"
+        obj_nd = __calc_dimensions__ (obj);
+        if (obj_nd == 3)
+          nd = 3;
+        endif
+    endswitch
+  endfor
+endfunction
+
+function __gnuplot_write_data__ (plot_stream, data, nd, parametric, cdata)
+  
+  ## DATA is already transposed.
+
+  ## FIXME -- this may need to be converted to C++ for speed.
+
+  ## Convert NA elements to normal NaN values because fprintf writes
+  ## "NA" and that confuses gnuplot.
+  idx = find (isna (data));
+  if (any (idx))
+    data(idx) = NaN;
+  endif
+
+  if (nd == 2)
+    fwrite (plot_stream, data, "float64");
+  elseif (nd == 3)
+    if (parametric)
+      fwrite (plot_stream, data, "float64");
+    else
+      nr = rows (data);
+      if (cdata)
+	for j = 1:4:nr
+	  fwrite (plot_stream, data(j:j+3,:), "float64");
+	endfor
+      else
+	for j = 1:3:nr
+	  fwrite (plot_stream, data(j:j+2,:), "float64");
+	endfor
+      endif
+    endif
+  endif
+
+endfunction
+
+function do_tics (obj, plot_stream, ymirror, mono, gnuplot_term)
+
+  obj.xticklabel = ticklabel_to_cell (obj.xticklabel);
+  obj.yticklabel = ticklabel_to_cell (obj.yticklabel);
+  obj.zticklabel = ticklabel_to_cell (obj.zticklabel);
+
+  if (strcmp (obj.xminorgrid, "on"))
+    obj.xminortick = "on";
+  endif
+  if (strcmp (obj.yminorgrid, "on"))
+    obj.yminortick = "on";
+  endif
+  if (strcmp (obj.zminorgrid, "on"))
+    obj.zminortick = "on";
+  endif
+
+  [fontname, fontsize] = get_fontname_and_size (obj);
+  fontspec = create_fontspec (fontname, fontsize, gnuplot_term);
+
+  ## A Gnuplot tic scale of 69 is equivalent to Octave's 0.5.
+  ticklength = sprintf ("scale %4.1f", (69/0.5)*obj.ticklength(1));
+
+  if (strcmpi (obj.xaxislocation, "top"))
+    do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode,
+	       obj.xticklabel, obj.xcolor, "x2", plot_stream, true, mono,
+	       "border", obj.tickdir, ticklength, fontname, fontspec,
+	       obj.interpreter, obj.xscale);
+    do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel,
+	       obj.xcolor, "x", plot_stream, true, mono, "border",
+	       "", "", fontname, fontspec, obj.interpreter, obj.xscale);
+  elseif (strcmpi (obj.xaxislocation, "zero"))
+    do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode,
+	       obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono,
+	       "axis", obj.tickdir, ticklength, fontname, fontspec,
+	       obj.interpreter, obj.xscale);
+    do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel,
+	       obj.xcolor, "x2", plot_stream, true, mono, "axis",
+	       "", "", fontname, fontspec, obj.interpreter, obj.xscale);
+  else
+    do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode,
+	       obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono,
+	       "border", obj.tickdir, ticklength, fontname, fontspec,
+	       obj.interpreter, obj.xscale);
+    do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel,
+	       obj.xcolor, "x2", plot_stream, true, mono, "border",
+	       "", "", fontname, fontspec, obj.interpreter, obj.xscale);
+  endif
+  if (strcmpi (obj.yaxislocation, "right"))
+    do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode,
+	       obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, mono,
+	       "border", obj.tickdir, ticklength, fontname, fontspec,
+	       obj.interpreter, obj.yscale);
+    do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel,
+	       obj.ycolor, "y", plot_stream, ymirror, mono, "border",
+	       "", "", fontname, fontspec, obj.interpreter, obj.yscale);
+  elseif (strcmpi (obj.yaxislocation, "zero"))
+    do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode,
+	       obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono,
+	       "axis", obj.tickdir, ticklength, fontname, fontspec,
+	       obj.interpreter, obj.yscale);
+    do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel,
+	       obj.ycolor, "y2", plot_stream, ymirror, mono, "axis",
+	       "", "", fontname, fontspec, obj.interpreter, obj.yscale);
+  else
+    do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode,
+	       obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono,
+	       "border", obj.tickdir, ticklength, fontname, fontspec,
+	       obj.interpreter, obj.yscale);
+    do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel,
+	       obj.ycolor, "y2", plot_stream, ymirror, mono, "border",
+	       "", "", fontname, fontspec, obj.interpreter, obj.yscale);
+  endif
+  do_tics_1 (obj.ztickmode, obj.ztick, obj.zminortick, obj.zticklabelmode,
+	     obj.zticklabel, obj.zcolor, "z", plot_stream, true, mono,
+	     "border", obj.tickdir, ticklength, fontname, fontspec,
+	     obj.interpreter, obj.yscale);
+endfunction
+
+function do_tics_1 (ticmode, tics, mtics, labelmode, labels, color, ax,
+		    plot_stream, mirror, mono, axispos, tickdir, ticklength,
+		    fontname, fontspec, interpreter, scale)
+  persistent warned_latex = false;
+  if (strcmpi (interpreter, "tex"))
+    for n = 1 : numel(labels)
+      labels{n} = __tex2enhanced__ (labels{n}, fontname, false, false);
+    endfor
+  elseif (strcmpi (interpreter, "latex"))
+    if (! warned_latex)
+      warning ("latex markup not supported for tick marks");
+      warned_latex = true;
+    endif
+  endif
+  if (strcmp (scale, "log"))
+    fmt = "10^{%T}";
+    num_mtics = 10;
+  else
+    fmt = "%g";
+    num_mtics = 5;
+  endif
+  colorspec = get_text_colorspec (color, mono);
+  if (strcmpi (ticmode, "manual") || strcmpi (labelmode, "manual"))
+    if (isempty (tics))
+      fprintf (plot_stream, "unset %stics;\nunset m%stics;\n", ax, ax);
+    elseif (strcmpi (labelmode, "manual"))
+      if (ischar (labels))
+	labels = cellstr (labels);
+      endif
+      if (isnumeric (labels))
+	labels = num2str (real (labels(:)));
+      endif
+      if (ischar (labels))
+	labels = permute (cellstr (labels), [2, 1]);
+      endif
+      if (iscellstr (labels))
+	k = 1;
+	ntics = numel (tics);
+	nlabels = numel (labels);
+	fprintf (plot_stream, "set format %s \"%%s\";\n", ax);
+	if (mirror)
+	  fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, 
+		   tickdir, ticklength, axispos);
+	else
+	  fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax,
+		   tickdir, ticklength, axispos);
+	endif
+ 
+	labels = regexprep(labels, "%", "%%");
+	for i = 1:ntics
+	  fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i));
+	  if (i < ntics)
+	    fputs (plot_stream, ", ");
+	  endif
+	  if (k > nlabels)
+	    k = 1;
+	  endif
+	endfor
+	fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec);
+ 	if (strcmp (mtics, "on"))
+	  fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
+	else
+	  fprintf (plot_stream, "unset m%stics;\n", ax);
+	endif
+     else
+	error ("unsupported type of ticklabel");
+      endif
+    else
+      fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
+      if (mirror)
+	fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, tickdir,
+		 ticklength, axispos);
+      else
+	fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax, tickdir,
+		 ticklength, axispos);
+      endif
+      fprintf (plot_stream, " %.15g,", tics(1:end-1));
+      fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec);
+      if (strcmp (mtics, "on"))
+        fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
+      else
+	fprintf (plot_stream, "unset m%stics;\n", ax);
+      endif
+    endif
+  else
+    fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
+    if (mirror)
+      fprintf (plot_stream, "set %stics %s %s %s mirror %s %s;\n", ax, 
+	       axispos, tickdir, ticklength, colorspec, fontspec);
+    else
+      fprintf (plot_stream, "set %stics %s %s %s nomirror %s %s;\n", ax, 
+	       tickdir, ticklength, axispos, colorspec, fontspec);
+    endif
+    if (strcmp (mtics, "on"))
+      fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
+    else
+      fprintf (plot_stream, "unset m%stics;\n", ax);
+    endif
+  endif
+endfunction
+
+function ticklabel = ticklabel_to_cell (ticklabel)
+  if (isnumeric (ticklabel))
+    ## Use upto 5 significant digits
+    ticklabel = num2str (ticklabel(:), 5);
+  endif
+  if (ischar (ticklabel))
+    if (size (ticklabel, 1) == 1 && any (ticklabel == "|"))
+      n = setdiff (findstr (ticklabel, "|"), findstr (ticklabel, '\|'));
+      ticklabel = strsplit (ticklabel, "|");
+    else
+      ticklabel = cellstr (ticklabel);
+    endif
+  elseif (isempty (ticklabel))
+    ticklabel = {""};
+  else
+    ticklabel = ticklabel;
+  endif
+endfunction
+
+function colorspec = get_text_colorspec (color, mono)
+  if (mono)
+    colorspec = "";
+  else
+    colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"",
+			 round (255*color));
+  endif
+endfunction
+
+function [f, s, fnt, it, bld] = get_fontname_and_size (t)
+  if (isempty (t.fontname))
+    fnt = "Helvetica";
+  else
+    fnt = t.fontname;
+  endif
+  f = fnt;
+  it = false;
+  bld = false;
+  if (! isempty (t.fontweight) && strcmpi (t.fontweight, "bold"))
+    if (! isempty(t.fontangle)
+	&& (strcmpi (t.fontangle, "italic")
+	    || strcmpi (t.fontangle, "oblique")))
+      f = cstrcat (f, "-bolditalic");
+      it = true;
+      bld = true;
+    else
+      f = cstrcat (f, "-bold");
+      bld = true;
+    endif
+  elseif (! isempty(t.fontangle)
+	  && (strcmpi (t.fontangle, "italic")
+	      || strcmpi (t.fontangle, "oblique")))
+    f = cstrcat (f, "-italic");
+    it = true;
+  endif
+  if (isempty (t.fontsize))
+    s = 10;
+  else
+    s = t.fontsize;
+  endif
+endfunction
+
+function [str, f, s] = __maybe_munge_text__ (enhanced, obj, fld)
+
+  persistent warned_latex = false;
+
+  if (strcmp (fld, "string"))
+    [f, s, fnt, it, bld] = get_fontname_and_size (obj);
+  else
+    f = "Helvetica";
+    s = 10;
+    fnt = f;
+    it = false;
+    bld = false;
+  endif
+
+  str = getfield (obj, fld);
+  if (enhanced)
+    if (strcmpi (obj.interpreter, "tex"))
+      str = __tex2enhanced__ (str, fnt, it, bld);
+    elseif (strcmpi (obj.interpreter, "latex"))
+      if (! warned_latex)
+	warning ("latex markup not supported for text objects");
+	warned_latex = true;
+      endif
+    endif
+  endif
+endfunction
+
+function str = __tex2enhanced__ (str, fnt, it, bld)
+  persistent sym = __setup_sym_table__ ();
+  persistent flds = fieldnames (sym);
+
+  [s, e, m] = regexp(str,'\\([a-zA-Z]+|0)','start','end','matches');
+
+  for i = length (s) : -1 : 1
+    ## special case for "\0"  and replace with "{/Symbol \306}'
+    if (strncmp (m{i}, '\0', 2))
+      str = cstrcat (str(1:s(i) - 1), '{/Symbol \306}', str(s(i) + 2:end));
+    else
+      f = m{i}(2:end);
+      if (isfield (sym, f))
+	g = getfield(sym, f);
+	## FIXME The symbol font doesn't seem to support bold or italic
+	##if (bld)
+	##  if (it)
+	##    g = regexprep (g, '/Symbol', '/Symbol-bolditalic');
+	##  else
+	##    g = regexprep (g, '/Symbol', '/Symbol-bold');
+	##  endif
+	##elseif (it)
+	##  g = regexprep (g, '/Symbol', '/Symbol-italic');
+	##endif
+        str = cstrcat (str(1:s(i) - 1), g, str(e(i) + 1:end));
+      elseif (strncmp (f, "rm", 2))
+	bld = false;
+	it = false;
+        str = cstrcat (str(1:s(i) - 1), '/', fnt, ' ', str(s(i) + 3:end));
+      elseif (strncmp (f, "it", 2) || strncmp (f, "sl", 2))
+	it = true;
+	if (bld)
+          str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ', 
+			str(s(i) + 3:end));
+        else
+          str = cstrcat (str(1:s(i) - 1), '/', fnt, '-italic ', 
+			str(s(i) + 3:end));
+        endif
+      elseif (strncmp (f, "bf", 2))
+	bld = true;
+	if (it)
+          str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ', 
+			str(2(i) + 3:end));
+        else
+          str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bold ', 
+			str(s(i) + 3:end));
+        endif
+      elseif (strcmpi (f, "color"))
+	## FIXME Ignore \color but remove trailing {} block as well
+	d = strfind(str(e(i) + 1:end),'}');
+        if (isempty (d))
+	  warning ('syntax error in \color argument');
+	else
+	  str = cstrcat (str(1:s(i) - 1), str(e(i) + d + 1:end));
+        endif
+      elseif(strcmpi (f, "fontname"))
+	b1 = strfind(str(e(i) + 1:end),'{');
+	b2 = strfind(str(e(i) + 1:end),'}');
+        if (isempty(b1) || isempty(b2))
+	  warning ('syntax error in \fontname argument');
+	else
+          str = cstrcat (str(1:s(i) - 1), '/', 
+			str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}',
+			str(e(i) + b2(1) + 1:end));
+        endif
+      elseif(strcmpi (f, "fontsize"))
+	b1 = strfind(str(e(i) + 1:end),'{');
+	b2 = strfind(str(e(i) + 1:end),'}');
+        if (isempty(b1) || isempty(b2))
+	  warning ('syntax error in \fontname argument');
+	else
+          str = cstrcat (str(1:s(i) - 1), '/=', 
+			str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}',
+			str(e(i) + b2(1) + 1:end));
+        endif
+      else
+	## Last desperate attempt to treat the symbol. Look for things
+	## like \pix, that should be translated to the symbol Pi and x
+	for j = 1 : length (flds)
+	  if (strncmp (flds{j}, f, length (flds{j})))
+	    g = getfield(sym, flds{j});
+	    ## FIXME The symbol font doesn't seem to support bold or italic
+	    ##if (bld)
+	    ##  if (it)
+	    ##    g = regexprep (g, '/Symbol', '/Symbol-bolditalic');
+	    ##  else
+	    ##    g = regexprep (g, '/Symbol', '/Symbol-bold');
+	    ##  endif
+	    ##elseif (it)
+	    ##  g = regexprep (g, '/Symbol', '/Symbol-italic');
+	    ##endif
+            str = cstrcat (str(1:s(i) - 1), g, 
+	    		  str(s(i) + length (flds{j}) + 1:end));
+	    break;
+	  endif
+	endfor
+      endif
+    endif
+  endfor
+
+  ## Prepend @ to things  things like _0^x or _{-100}^{100} for
+  ## alignment But need to put the shorter of the two arguments first.
+  ## Carful of nested {} and unprinted characters when defining
+  ## shortest.. Don't have to worry about things like ^\theta as they
+  ## are already converted to ^{/Symbol q}.
+
+  ## FIXME -- This is a mess... Is it worth it just for a "@" character?
+
+  [s, m] = regexp(str,'[_\^]','start','matches');
+  i = 1;
+  p = 0;
+  while (i < length (s))
+    if (i < length(s))
+      if (str(s(i) + p + 1) == "{")
+	s1 = strfind(str(s(i) + p + 2:end),'{');
+	si = 1;
+	l1 = strfind(str(s(i) + p + 1:end),'}');
+        li = 1;
+	while (li <= length (l1) && si <= length (s1))
+          if (l1(li) < s1(si))
+	    if (li == si)
+	      break;
+	    endif
+	    li++;
+	  else
+	    si++;
+	  endif
+	endwhile
+	l1 = l1 (min (length(l1), si));
+        if (s(i) + l1 + 1 == s(i+1))
+	  if (str(s(i + 1) + p + 1) == "{")
+	    s2 = strfind(str(s(i + 1) + p + 2:end),'{');
+	    si = 1;
+	    l2 = strfind(str(s(i + 1) + p + 1:end),'}');
+            li = 1;
+	    while (li <= length (l2) && si <= length (s2))
+              if (l2(li) < s2(si))
+		if (li == si)
+		  break;
+		endif
+		li++;
+	      else
+		si++;
+	      endif
+	    endwhile
+	    l2 = l2 (min (length(l2), si));
+	    if (length_string (str(s(i)+p+2:s(i)+p+l1-1)) <=
+		length_string(str(s(i+1)+p+2:s(i+1)+p+l2-1)))
+	      ## Shortest already first!
+	      str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end));
+	    else
+	      ## Have to swap sub/super-script to get shortest first.
+	      str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+l2),
+			    str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+l2+1:end));
+	    endif
+	  else
+	    ## Have to swap sub/super-script to get shortest first.
+	    str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+1),
+			  str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+2:end));
+	  endif
+          i += 2;
+	  p ++;
+	else
+	  i++;
+	endif
+      else
+	if (s(i+1) == s(i) + 2)
+	  ## Shortest already first!
+	  str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end));
+	  p ++;
+          i += 2;
+	else
+	  i ++;
+	endif
+      endif
+    else
+      i ++;
+    endif
+  endwhile
+
+endfunction
+
+function l = length_string (s)
+  l = length (s) - length (strfind(s,'{')) - length (strfind(s,'}'));
+  m = regexp (s, '/([\w\-]+|[\w\-]+=\d+)', 'matches');
+  if (!isempty (m))
+    l = l - sum (cellfun (@length, m));
+  endif
+endfunction
+
+function sym = __setup_sym_table__ ()
+  ## Setup the translation table for TeX to gnuplot enhanced mode.
+  sym.forall = '{/Symbol \042}';
+  sym.exists = '{/Symbol \044}';
+  sym.ni = '{/Symbol \047}';
+  sym.cong = '{/Symbol \100}';
+  sym.Delta = '{/Symbol D}';
+  sym.Phi = '{/Symbol F}';
+  sym.Gamma = '{/Symbol G}';
+  sym.vartheta = '{/Symbol J}';
+  sym.Lambda = '{/Symbol L}';
+  sym.Pi = '{/Symbol P}';
+  sym.Theta = '{/Symbol Q}';
+  sym.Sigma = '{/Symbol S}';
+  sym.varsigma = '{/Symbol V}';
+  sym.Omega = '{/Symbol W}';
+  sym.Xi = '{/Symbol X}';
+  sym.Psi = '{/Symbol Y}';
+  sym.perp = '{/Symbol \136}';
+  sym.alpha = '{/Symbol a}';
+  sym.beta = '{/Symbol b}';
+  sym.chi = '{/Symbol c}';
+  sym.delta = '{/Symbol d}';
+  sym.epsilon = '{/Symbol e}';
+  sym.phi = '{/Symbol f}';
+  sym.gamma = '{/Symbol g}';
+  sym.eta = '{/Symbol h}';
+  sym.iota = '{/Symbol i}';
+  sym.varphi = '{/Symbol j}';
+  sym.kappa = '{/Symbol k}';
+  sym.lambda = '{/Symbol l}';
+  sym.mu = '{/Symbol m}';
+  sym.nu = '{/Symbol n}';
+  sym.o =  '{/Symbol o}';
+  sym.pi = '{/Symbol p}';
+  sym.theta = '{/Symbol q}';
+  sym.rho = '{/Symbol r}';
+  sym.sigma = '{/Symbol s}';
+  sym.tau = '{/Symbol t}';
+  sym.upsilon = '{/Symbol u}';
+  sym.varpi = '{/Symbol v}';
+  sym.omega = '{/Symbol w}';
+  sym.xi = '{/Symbol x}';
+  sym.psi = '{/Symbol y}';
+  sym.zeta = '{/Symbol z}';
+  sym.sim = '{/Symbol \176}';
+  sym.Upsilon = '{/Symbol \241}';
+  sym.prime = '{/Symbol \242}';
+  sym.leq = '{/Symbol \243}';
+  sym.infty = '{/Symbol \245}';
+  sym.clubsuit = '{/Symbol \247}';
+  sym.diamondsuit = '{/Symbol \250}';
+  sym.heartsuit = '{/Symbol \251}';
+  sym.spadesuit = '{/Symbol \252}';
+  sym.leftrightarrow = '{/Symbol \253}';
+  sym.leftarrow = '{/Symbol \254}';
+  sym.uparrow = '{/Symbol \255}';
+  sym.rightarrow = '{/Symbol \256}';
+  sym.downarrow = '{/Symbol \257}';
+  sym.circ = '{/Symbol \260}';
+  sym.pm = '{/Symbol \261}';
+  sym.geq = '{/Symbol \263}';
+  sym.times = '{/Symbol \264}';
+  sym.propto = '{/Symbol \265}';
+  sym.partial = '{/Symbol \266}';
+  sym.bullet = '{/Symbol \267}';
+  sym.div = '{/Symbol \270}';
+  sym.neq = '{/Symbol \271}';
+  sym.equiv = '{/Symbol \272}';
+  sym.approx = '{/Symbol \273}';
+  sym.ldots = '{/Symbol \274}';
+  sym.mid = '{/Symbol \275}';
+  sym.aleph = '{/Symbol \300}';
+  sym.Im = '{/Symbol \301}';
+  sym.Re = '{/Symbol \302}';
+  sym.wp = '{/Symbol \303}';
+  sym.otimes = '{/Symbol \304}';
+  sym.oplus = '{/Symbol \305}';
+  sym.oslash = '{/Symbol \306}';
+  sym.cap = '{/Symbol \307}';
+  sym.cup = '{/Symbol \310}';
+  sym.supset = '{/Symbol \311}';
+  sym.supseteq = '{/Symbol \312}';
+  sym.subset = '{/Symbol \314}';
+  sym.subseteq = '{/Symbol \315}';
+  sym.in = '{/Symbol \316}';
+  sym.notin = '{/Symbol \317}';
+  sym.angle = '{/Symbol \320}';
+  sym.bigtriangledown = '{/Symbol \321}';
+  sym.langle = '{/Symbol \341}';
+  sym.rangle = '{/Symbol \361}';
+  sym.nabla = '{/Symbol \321}';
+  sym.prod = '{/Symbol \325}';
+  sym.surd = '{/Symbol \326}';
+  sym.cdot = '{/Symbol \327}';
+  sym.neg = '{/Symbol \330}';
+  sym.wedge = '{/Symbol \331}';
+  sym.vee = '{/Symbol \332}';
+  sym.Leftrightarrow = '{/Symbol \333}';
+  sym.Leftarrow = '{/Symbol \334}';
+  sym.Uparrow = '{/Symbol \335}';
+  sym.Rightarrow = '{/Symbol \336}';
+  sym.Downarrow = '{/Symbol \337}';
+  sym.diamond = '{/Symbol \340}';
+  sym.copyright = '{/Symbol \343}';
+  sym.lfloor = '{/Symbol \353}';
+  sym.lceil  = '{/Symbol \351}';
+  sym.rfloor = '{/Symbol \373}';
+  sym.rceil  = '{/Symbol \371}';
+  sym.int = '{/Symbol \362}';
+endfunction
+
+function retval = __do_enhanced_option__ (enhanced, obj)
+  retval = "";
+  if (enhanced)
+    if (strcmpi (obj.interpreter, "none"))
+      retval = "noenhanced";
+    else
+      retval = "enhanced";
+    endif
+  endif
+endfunction
+
+function typ = get_old_gnuplot_color (color)
+  if (isequal (color, [0, 0, 0]))
+    typ = -1;
+  elseif (isequal (color, [1, 0, 0]))
+    typ = 1;
+  elseif (isequal (color, [0, 1, 0]))
+    typ = 2;
+  elseif (isequal (color, [0, 0, 1]))
+    typ = 3;
+  elseif (isequal (color, [1, 0, 1]))
+    typ = 4;
+  elseif (isequal (color, [0, 1, 1]))
+    typ = 5;
+  elseif (isequal (color, [1, 1, 1]))
+    typ = -1;
+  elseif (isequal (color, [1, 1, 0]))
+    typ = 7;
+  else
+    typ = -1;
+  endif
+endfunction
diff --git a/scripts/plot/__go_draw_figure__.m b/scripts/plot/__go_draw_figure__.m
new file mode 100644
index 0000000..3a44add
--- /dev/null
+++ b/scripts/plot/__go_draw_figure__.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2005, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __go_draw_figure__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function __go_draw_figure__ (h, plot_stream, enhanced, mono, output_to_paper, implicit_margin)
+
+  if (nargin < 5)
+    output_to_paper = false;
+  elseif (nargin < 6)
+    ## Gnuplot has implicit margins for some output. For example, for postscript
+    ## the margin is 50pts. If not specified asssume 0.
+    implicit_margin = 0;
+  endif
+
+  if (nargin >= 4 && nargin <= 6)
+    htype = get (h, "type");
+    if (strcmp (htype, "figure"))
+      ## When printing, set paperunits to inches and rely on a listener to convert
+      ## the values for papersize and paperposition.
+      if (output_to_paper)
+	orig_paper_units = get (h, "paperunits");
+	gpval_term = __gnuplot_get_var__ (h, "GPVAL_TERM");
+	gpval_termoptions = __gnuplot_get_var__ (h, "GPVAL_TERMOPTIONS");
+	unwind_protect
+	  set (h, "paperunits", "inches");
+          paper_size = get (h, "papersize");
+          paper_position = get (h, "paperposition");
+          paper_position = paper_position ./ paper_size([1, 2, 1, 2]);
+	  implicit_margin = implicit_margin ./ paper_size;
+	unwind_protect_cleanup
+	  set (h, "paperunits", orig_paper_units);
+	end_unwind_protect
+	if (strcmp (gpval_term, "postscript")
+	    && ! isempty (strfind (gpval_termoptions, "landscape")))
+	  ## This needed to obtain the expected result.
+	  implicit_margin(2) = -implicit_margin(2);
+	endif
+      else
+	implicit_margin = implicit_margin * [1 1];
+      endif
+
+      ## Get complete list of children.
+      kids = allchild (h);
+      nkids = length (kids);
+
+      if (nkids > 0)
+	fputs (plot_stream, "\nreset;\n");
+	fputs (plot_stream, "set autoscale keepfix;\n");
+	fputs (plot_stream, "set origin 0, 0\n");
+	fputs (plot_stream, "set size 1, 1\n");
+	for i = 1:nkids
+	  type = get (kids(i), "type");
+	  switch (type)
+	    case "axes"
+	      ## Rely upon listener to convert axes position to "normalized" units.
+	      orig_axes_units = get (kids(i), "units");
+	      orig_axes_position = get (kids(i), "position");
+	      unwind_protect
+		set (kids(i), "units", "normalized");
+		if (output_to_paper)
+		  axes_position_on_page = orig_axes_position .* paper_position([3, 4, 3 ,4]);
+		  axes_position_on_page(1:2) = axes_position_on_page(1:2) +  paper_position(1:2);
+		  set (kids(i), "position", axes_position_on_page);
+		  __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, implicit_margin);
+		else
+		  ## Return axes "units" and "position" back to their original values.
+		  __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, implicit_margin);
+		endif
+		unwind_protect_cleanup
+		set (kids(i), "units", orig_axes_units);
+		set (kids(i), "position", orig_axes_position);
+	      end_unwind_protect
+	    otherwise
+	      error ("__go_draw_figure__: unknown object class, %s", type);
+	  endswitch
+	endfor
+      else
+	fputs (plot_stream, "\nreset; clear;\n");
+	fflush (plot_stream);
+      endif
+    else
+      error ("__go_draw_figure__: expecting figure object, found `%s'",
+	     htype);
+    endif
+  else
+    print_usage ();
+  endif    
+
+endfunction
+
diff --git a/scripts/plot/__interp_cube__.m b/scripts/plot/__interp_cube__.m
new file mode 100644
index 0000000..9d73cf8
--- /dev/null
+++ b/scripts/plot/__interp_cube__.m
@@ -0,0 +1,181 @@
+## Copyright (C) 2009 Martin Helm
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
+##
+## Author: Martin Helm <martin at mhelm.de>
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{vxyz}, @var{idx}, @var{frac}] =} __interp_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{v})
+## Undocumented internal function.
+## @end deftypefn
+
+function [Vxyz, idx, frac] = __interp_cube__(x, y, z, val, v, req = "values" )
+  if (ismatrix (x) && ndims (x) == 3 && ismatrix (y) && ndims (y) == 3 ...
+       && ismatrix (z) && ndims (z) == 3 && size_equal (x, y, z, val))
+    x = squeeze (x(1,:,1))(:);
+    y = squeeze (y(:,1,1))(:);
+    z = squeeze (z(1,1,:))(:);
+  elseif (isvector (x) && isvector (y) && isvector (z) )
+    x = x(:);
+    y = y(:);
+    z = z(:);
+  else
+    error("x, y, z have wrong dimensions");
+  endif
+  if (size (val) != [length(x), length(y), length(z)])
+    error ("val has wrong dimensions");
+  endif
+  if (size (v, 2) != 3)
+    error ( "v has to be N*3 matrix");
+  endif
+  if (!ischar (req))
+   error ("Invalid request parameter use 'values', 'normals' or 'normals8'");
+  endif
+  if (isempty (v))
+    Vxyz = idx = frac = [];
+    return
+  endif
+
+  switch req
+    case "values"
+      [Vxyz, idx, frac] = interp_cube_trilin (x, y, z, val, v);
+    case "normals"
+      [idx, frac] = cube_idx (x, y, z, v);
+
+      dx = x(2:end) - x(1:end-1);
+      dy = y(2:end) - y(1:end-1);
+      dz = z(2:end) - z(1:end-1);
+      dx = 0.5 .* [dx;dx(end)](idx(:,2));
+      dy = 0.5 .* [dy;dy(end)](idx(:,1));
+      dz = 0.5 .* [dz;dz(end)](idx(:,3));
+
+      p000 = [v(:, 1) - dx, v(:, 2) - dy, v(:, 3) - dz];
+      p100 = [v(:, 1) + dx, v(:, 2) - dy, v(:, 3) - dz];
+      p010 = [v(:, 1) - dx, v(:, 2) + dy, v(:, 3) - dz];
+      p001 = [v(:, 1) - dx, v(:, 2) - dy, v(:, 3) + dz];
+      p011 = [v(:, 1) - dx, v(:, 2) + dy, v(:, 3) + dz];
+      p101 = [v(:, 1) + dx, v(:, 2) - dy, v(:, 3) + dz];
+      p110 = [v(:, 1) + dx, v(:, 2) + dy, v(:, 3) - dz];
+      p111 = [v(:, 1) + dx, v(:, 2) + dy, v(:, 3) + dz];
+
+      v000 = interp_cube_trilin (x, y, z, val, p000);
+      v100 = interp_cube_trilin (x, y, z, val, p100);
+      v010 = interp_cube_trilin (x, y, z, val, p010);
+      v001 = interp_cube_trilin (x, y, z, val, p001);
+      v011 = interp_cube_trilin (x, y, z, val, p011);
+      v101 = interp_cube_trilin (x, y, z, val, p101);
+      v110 = interp_cube_trilin (x, y, z, val, p110);
+      v111 = interp_cube_trilin (x, y, z, val, p111);
+
+      Dx = -v000 .+ v100 .- v010 .- v001 .- v011 .+ v101 .+ v110 .+ v111;
+      Dy = -v000 .- v100 .+ v010 .- v001 .+ v011 .- v101 .+ v110 .+ v111;
+      Dz = -v000 .- v100 .- v010 .+ v001 .+ v011 .+ v101 .- v110 .+ v111;
+      Vxyz = 0.5 .* [Dx./dx, Dy./dy, Dz./dz];
+    case "normals8"
+      [idx, frac] = cube_idx (x, y, z, v);
+
+      dx = x(2:end) - x(1:end-1);
+      dy = y(2:end) - y(1:end-1);
+      dz = z(2:end) - z(1:end-1);
+      dx = [dx;dx(end)](idx(:,2));
+      dy = [dy;dy(end)](idx(:,1));
+      dz = [dz;dz(end)](idx(:,3));
+      [Dx, Dy, Dz, idx, frac] = interp_cube_trilin_grad (x, y, z, val, v);
+      Vxyz = [Dx./dx, Dy./dy, Dz./dz];
+   otherwise
+     error ("Invalid request type '%s', use 'values', 'normals' or 'normals8'", req);
+  endswitch
+endfunction
+
+function [Vxyz, idx, frac] = interp_cube_trilin(x, y, z, val, v)
+  [idx, frac] = cube_idx (x(:), y(:), z(:), v);
+  sval = size (val);
+  i000 = sub2ind (sval, idx(:, 1), idx(:, 2), idx(:, 3));
+  i100 = sub2ind (sval, idx(:, 1)+1, idx(:, 2), idx(:, 3));
+  i010 = sub2ind (sval, idx(:, 1), idx(:, 2)+1, idx(:, 3));
+  i001 = sub2ind (sval, idx(:, 1), idx(:, 2), idx(:, 3)+1);
+  i101 = sub2ind (sval, idx(:, 1)+1, idx(:, 2), idx(:, 3)+1);
+  i011 = sub2ind (sval, idx(:, 1), idx(:, 2)+1, idx(:, 3)+1);
+  i110 = sub2ind (sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3));
+  i111 = sub2ind (sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3)+1 );
+  Bx = frac(:, 1);
+  By = frac(:, 2);
+  Bz = frac(:, 3);
+  Vxyz = ...
+    val( i000 ) .* (1 .- Bx) .* (1 .- By) .* (1 .- Bz) .+ ...
+    val( i100 ) .* Bx .* (1 .- By) .* (1 .- Bz) .+ ...
+    val( i010 ) .* (1 .- Bx) .* By .* (1 .- Bz) .+ ...
+    val( i001 ) .* (1 .- Bx) .* (1 .- By) .* Bz .+ ...
+    val( i011 ) .* (1 .- Bx) .* By .* Bz .+ ...
+    val( i101 ) .* Bx .* (1 .- By) .* Bz .+ ...
+    val( i110 ) .* Bx .* By .* (1 .- Bz) .+ ...
+    val( i111 ) .* Bx .* By .* Bz;
+endfunction
+
+function [Dx, Dy, Dz, idx, frac] = interp_cube_trilin_grad(x, y, z, val, v)
+  [idx, frac] = cube_idx (x(:), y(:), z(:), v);
+  sval = size (val);
+  i000 = sub2ind (sval, idx(:, 1), idx(:, 2), idx(:, 3));
+  i100 = sub2ind (sval, idx(:, 1)+1, idx(:, 2), idx(:, 3));
+  i010 = sub2ind (sval, idx(:, 1), idx(:, 2)+1, idx(:, 3));
+  i001 = sub2ind (sval, idx(:, 1), idx(:, 2), idx(:, 3)+1);
+  i101 = sub2ind (sval, idx(:, 1)+1, idx(:, 2), idx(:, 3)+1);
+  i011 = sub2ind (sval, idx(:, 1), idx(:, 2)+1, idx(:, 3)+1);
+  i110 = sub2ind (sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3));
+  i111 = sub2ind (sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3)+1 );
+  Bx = frac(:, 1);
+  By = frac(:, 2);
+  Bz = frac(:, 3);
+  Dx = ...
+    val( i000 ) .* -1 .* (1 .- By) .* (1 .- Bz) .+ ...
+    val( i100 ) .* (1 .- By) .* (1 .- Bz) .+ ...
+    val( i010 ) .* -1 .* By .* (1 .- Bz) .+ ...
+    val( i001 ) .* -1 .* (1 .- By) .* Bz .+ ...
+    val( i011 ) .* -1 .* By .* Bz .+ ...
+    val( i101 ) .* (1 .- By) .* Bz .+ ...
+    val( i110 ) .* By .* (1 .- Bz) .+ ...
+    val( i111 ) .* By .* Bz;
+  Dy = ...
+    val( i000 ) .* (1 .- Bx) .* -1 .* (1 .- Bz) .+ ...
+    val( i100 ) .* Bx .* -1 .* (1 .- Bz) .+ ...
+    val( i010 ) .* (1 .- Bx) .* (1 .- Bz) .+ ...
+    val( i001 ) .* (1 .- Bx) .* -1 .* Bz .+ ...
+    val( i011 ) .* (1 .- Bx) .* Bz .+ ...
+    val( i101 ) .* Bx .* -1 .* Bz .+ ...
+    val( i110 ) .* Bx .* (1 .- Bz) .+ ...
+    val( i111 ) .* Bx .* Bz;
+  Dz = ...
+    val( i000 ) .* (1 .- Bx) .* (1 .- By) .* -1 .+ ...
+    val( i100 ) .* Bx .* (1 .- By) .* -1 .+ ...
+    val( i010 ) .* (1 .- Bx) .* By .* -1 .+ ...
+    val( i001 ) .* (1 .- Bx) .* (1 .- By) .+ ...
+    val( i011 ) .* (1 .- Bx) .* By + ...
+    val( i101 ) .* Bx .* (1 .- By) .+ ...
+    val( i110 ) .* Bx .* By .* -1 .+ ...
+    val( i111 ) .* Bx .* By;
+endfunction
+
+function [idx, frac] = cube_idx(x, y, z, v)
+  idx = zeros (size (v));
+  frac = zeros (size (v));
+  idx(:, 2) = lookup (x(2:end-1), v(:, 1)) + 1;
+  frac(:, 2) = (v(:, 1) - x(idx(:, 2)) )...
+      ./ (x(idx(:, 2)+1) - x(idx(:, 2)));
+  idx(:, 1) = lookup (y(2:end-1), v(:, 2)) + 1;
+  frac(:, 1) = (v(:, 2) - y(idx(:, 1))) ...
+      ./ (y(idx(:, 1)+1) - y(idx(:, 1)));
+  idx(:, 3) = lookup (z(2:end-1), v(:, 3)) + 1;
+  frac(:, 3) = (v(:, 3) - z(idx(:, 3))) ...
+      ./ (z(idx(:, 3)+1) - z(idx(:, 3)));
+endfunction
\ No newline at end of file
diff --git a/scripts/plot/__line__.m b/scripts/plot/__line__.m
new file mode 100644
index 0000000..a23ae28
--- /dev/null
+++ b/scripts/plot/__line__.m
@@ -0,0 +1,67 @@
+## Copyright (C) 2005, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} __line__ (@var{p}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## __line__ (p, x, y, z)
+## Create line object from x, y, and z with parent p.
+## Return handle to line object.
+
+## Author: jwe
+
+function h = __line__ (p, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  nvargs = numel (varargin);
+
+  if (nvargs > 1 && isnumeric (varargin{1}) && isnumeric (varargin{2}))
+    if (nvargs > 2 && isnumeric (varargin{3}))
+      num_data_args = 3;
+    else
+      num_data_args = 2;
+    endif
+  else
+    num_data_args = 0;
+  endif
+
+  if (rem (nvargs - num_data_args, 2) != 0)
+    print_usage ("line");
+  endif
+
+  data_args = {};
+  if (num_data_args > 1)
+    data_args(1:4) = { "xdata", varargin{1}, "ydata", varargin{2} };
+    if (num_data_args == 3)
+      data_args(5:6) = { "zdata", varargin{3} };
+    endif
+  endif
+
+  other_args = {};
+  if (nvargs > num_data_args)
+    other_args = varargin(num_data_args+1:end);
+  endif
+
+  h = __go_line__ (p, data_args{:}, other_args{:});
+
+endfunction
diff --git a/scripts/plot/__marching_cube__.m b/scripts/plot/__marching_cube__.m
new file mode 100644
index 0000000..ee4ec3b
--- /dev/null
+++ b/scripts/plot/__marching_cube__.m
@@ -0,0 +1,522 @@
+## Copyright (C) 2009 Martin Helm
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+## @deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col})
+## Undocumented internal function.
+## @end deftypefn
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+## @deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col})
+##
+## Return the triangulation information @var{t} at points @var{p} for
+## the isosurface values resp. the volume data @var{val} and the iso
+## level @var{iso}.  It is considered that the volume data @var{val} is
+## given at the points @var{x}, @var{y} and @var{z} which are of type
+## three--dimensional numeric arrays.  The orientation of the triangles
+## is choosen such that the normals point from the higher values to the
+## lower values.
+##
+## Optionally the color data @var{col} can be passed to this function
+## whereas computed vertices color data @var{c} is returned as third
+## argument.
+##
+## The marching cube algorithm is well known and described eg. at
+## Wikipedia. The triangulation lookup table and the edge table used
+## here are based on Cory Gene Bloyd's implementation and can be found
+## beyond other surface and geometry stuff at Paul Bourke's website
+## @uref{http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise}.
+##
+## For example,
+## @example
+## N = 20;
+## lin = linspace(0, 2, N);
+## [x, y, z] = meshgrid (lin, lin, lin);
+##
+## c = (x-.5).^2 + (y-.5).^2 + (z-.5).^2;
+## [t, p] = __marching_cube__ (x, y, z, c, .5);
+##
+## figure ();
+## trimesh (t, p(:,1), p(:,2), p(:,3));
+## @end example
+##
+## Instead of the @command{trimesh} function the @command{patch}
+## function can be used to visualize the geometry. For example,
+##
+## @example
+## figure (); view (-38, 20);
+## pa = patch ("Faces", t, "Vertices", p, "FaceVertexCData", p, \
+##             "FaceColor", "interp", "EdgeColor", "none");
+##
+## ## Revert normals
+## set (pa, "VertexNormals", -get(pa, "VertexNormals"));
+##
+## ## Set lightning (available with the JHandles package)
+## # set (pa, "FaceLighting", "gouraud");
+## # light( "Position", [1 1 5]);
+## @end example
+##
+## @end deftypefn
+
+## Author: Martin Helm <martin at mhelm.de>
+
+function [T, p, col] = __marching_cube__ (xx, yy, zz, c, iso, colors)
+  
+  persistent edge_table=[];
+  persistent tri_table=[];
+
+  calc_cols = false;
+  lindex = 4;
+
+  if (isempty (tri_table) || isempty (edge_table))
+    [edge_table, tri_table] = init_mc ();
+  endif
+   
+  if ((nargin != 5 && nargin != 6) || (nargout != 2 && nargout != 3))
+    print_usage ();
+  endif
+  
+  if (!ismatrix (xx) || !ismatrix (yy) || !ismatrix (zz) || !ismatrix (c) || ...
+    ndims (xx) != 3 || ndims (yy) != 3 || ndims (zz) != 3 || ndims (c) != 3)
+    error ("xx, yy, zz, c have to be matrizes of dim 3");
+  endif
+  
+  if (!size_equal (xx, yy, zz, c))
+    error ("xx, yy, zz, c are not the same size");
+  endif
+  
+  if (any (size (xx) < [2 2 2]))
+    error ("grid size has to be at least 2x2x2");
+  endif
+  
+  if (!isscalar (iso))
+    error ("iso needs to be scalar value");
+  endif
+
+  if (nargin == 6)
+    if ( !ismatrix (colors) || ndims (colors) != 3 || size (colors) != size (c) )
+      error ( "color has to be matrix of dim 3 and of same size as c" );
+    endif
+    calc_cols = true;
+    lindex = 5;
+  endif
+  
+  n = size (c) - 1;
+  
+  ## phase I: assign information to each voxel which edges are intersected by
+  ## the isosurface
+  cc = zeros (n(1), n(2), n(3), "uint16");
+  cedge = zeros (size (cc), "uint16");
+  
+  vertex_idx = {1:n(1), 1:n(2), 1:n(3); ...
+    2:n(1)+1, 1:n(2), 1:n(3); ...
+    2:n(1)+1, 2:n(2)+1, 1:n(3); ...
+    1:n(1), 2:n(2)+1, 1:n(3); ...
+    1:n(1), 1:n(2), 2:n(3)+1; ...
+    2:n(1)+1, 1:n(2), 2:n(3)+1; ...
+    2:n(1)+1, 2:n(2)+1, 2:n(3)+1; ...
+    1:n(1), 2:n(2)+1, 2:n(3)+1 };
+  
+  ## calculate which vertices have values higher than iso
+  for ii=1:8
+    idx = c(vertex_idx{ii, :}) > iso;
+    cc(idx) = bitset (cc(idx), ii);
+  endfor 
+  
+  cedge = edge_table(cc+1); # assign the info about intersected edges
+  id =  find (cedge); # select only voxels which are intersected
+  if (isempty (id))
+    T = p = col = [];
+    return
+  endif
+  
+  ## phase II: calculate the list of intersection points
+  xyz_off = [1, 1, 1; 2, 1, 1; 2, 2, 1; 1, 2, 1; 1, 1, 2;  2, 1, 2; 2, 2, 2; 1, 2, 2];
+  edges = [1 2; 2 3; 3 4; 4 1; 5 6; 6 7; 7 8; 8 5; 1 5; 2 6; 3 7; 4 8];
+  offset = sub2ind (size (c), xyz_off(:, 1), xyz_off(:, 2), xyz_off(:, 3)) -1;
+  pp = zeros (length (id), lindex, 12);
+  ccedge = [vec(cedge(id)), id];
+  ix_offset=0;
+  for jj=1:12
+    id__ = bitget (ccedge(:, 1), jj);
+    id_ = ccedge(id__, 2);
+    [ix iy iz] = ind2sub (size (cc), id_);
+    id_c = sub2ind (size (c), ix, iy, iz);
+    id1 = id_c + offset(edges(jj, 1));
+    id2 = id_c + offset(edges(jj, 2));
+    if (calc_cols)
+      pp(id__, 1:5, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ...
+        xx(id2), yy(id2), zz(id2), c(id1), c(id2), colors(id1), colors(id2)), ...
+        (1:size (id_, 1))' + ix_offset ];
+    else
+      pp(id__, 1:4, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ...
+        xx(id2), yy(id2), zz(id2), c(id1), c(id2)), ...
+        (1:size (id_, 1))' + ix_offset ];
+    endif
+    ix_offset += size (id_, 1);
+  endfor
+  
+  ## phase III: calculate the triangulation from the point list 
+  T = [];
+  tri = tri_table(cc(id)+1, :);
+  for jj=1:3:15
+    id_ = find (tri(:, jj)>0);
+    p = [id_, lindex*ones(size (id_, 1), 1),tri(id_, jj:jj+2)];
+    if (!isempty (p))
+      p1 = sub2ind (size (pp), p(:,1), p(:,2), p(:,3));
+      p2 = sub2ind (size (pp), p(:,1), p(:,2), p(:,4));
+      p3 = sub2ind (size (pp), p(:,1), p(:,2), p(:,5));
+      T = [T; pp(p1), pp(p2), pp(p3)];
+    endif
+  endfor
+  
+  p = [];
+  col = [];
+  for jj = 1:12
+    idp = pp(:, lindex, jj) > 0;
+    if (any (idp))
+      p(pp(idp, lindex, jj), 1:3) = pp(idp, 1:3, jj);
+      if (calc_cols)
+        col(pp(idp, lindex, jj),1) = pp(idp, 4, jj);
+      endif
+    endif
+  endfor
+endfunction
+
+function p = vertex_interp(isolevel,p1x, p1y, p1z,...
+  p2x, p2y, p2z,valp1,valp2, col1, col2)
+  
+  if (nargin == 9)
+    p = zeros (length (p1x), 3);
+  elseif (nargin == 11)
+    p = zeros (length (p1x), 4);
+  else 
+    error ("Wrong number of arguments");
+  endif
+  mu = zeros (length (p1x), 1);
+  id = abs (valp1-valp2) < (10*eps) .* (abs (valp1) .+ abs (valp2));
+  if (any (id))
+    p(id, 1:3) = [ p1x(id), p1y(id), p1z(id) ];
+    if (nargin == 11)
+      p(id, 4) = col1(id);
+    endif
+  endif
+  nid = !id;
+  if (any (nid))
+    mu(nid) = (isolevel - valp1(nid)) ./ (valp2(nid) - valp1(nid));
+    p(nid, 1:3) = [p1x(nid) + mu(nid) .* (p2x(nid) - p1x(nid)), ...
+      p1y(nid) + mu(nid) .* (p2y(nid) - p1y(nid)), ...
+      p1z(nid) + mu(nid) .* (p2z(nid) - p1z(nid))];
+    if (nargin == 11)
+      p(nid, 4) = col1(nid) + mu(nid) .* (col2(nid) - col1(nid));
+    endif
+  endif
+endfunction
+
+function [edge_table, tri_table] = init_mc()
+  edge_table = [
+  0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, ...
+  0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, ...
+  0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, ...
+  0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, ...
+  0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, ...
+  0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, ...
+  0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, ...
+  0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, ...
+  0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, ...
+  0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, ...
+  0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, ...
+  0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, ...
+  0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, ...
+  0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, ...
+  0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , ...
+  0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, ...
+  0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, ...
+  0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, ...
+  0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, ...
+  0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, ...
+  0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, ...
+  0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, ...
+  0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, ...
+  0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, ...
+  0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, ...
+  0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, ...
+  0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, ...
+  0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, ...
+  0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, ...
+  0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, ...
+  0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, ...
+  0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0   ];
+  
+  tri_table =[ 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1;
+  3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1;
+  3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1;
+  3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1;
+  9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1;
+  9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1;
+  2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1;
+  8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1;
+  9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1;
+  4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1;
+  3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1;
+  1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1;
+  4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1;
+  4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1;
+  9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1;
+  5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1;
+  2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1;
+  9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1;
+  0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1;
+  2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1;
+  10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1;
+  4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1;
+  5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1;
+  5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1;
+  9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1;
+  0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1;
+  1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1;
+  10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1;
+  8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1;
+  2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1;
+  7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1;
+  9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1;
+  2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1;
+  11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1;
+  9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1;
+  5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1;
+  11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1;
+  11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1;
+  1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1;
+  9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1;
+  5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1;
+  2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1;
+  0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1;
+  5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1;
+  6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1;
+  3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1;
+  6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1;
+  5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1;
+  1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1;
+  10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1;
+  6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1;
+  8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1;
+  7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1;
+  3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1;
+  5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1;
+  0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1;
+  9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1;
+  8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1;
+  5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1;
+  0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1;
+  6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1;
+  10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1;
+  10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1;
+  8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1;
+  1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1;
+  3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1;
+  0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1;
+  10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1;
+  3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1;
+  6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1;
+  9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1;
+  8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1;
+  3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1;
+  6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1;
+  0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1;
+  10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1;
+  10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1;
+  2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1;
+  7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1;
+  7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1;
+  2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1;
+  1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1;
+  11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1;
+  8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1;
+  0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1;
+  7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1;
+  10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1;
+  2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1;
+  6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1;
+  7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1;
+  2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1;
+  1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1;
+  10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1;
+  10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1;
+  0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1;
+  7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1;
+  6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1;
+  8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1;
+  9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1;
+  6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1;
+  4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1;
+  10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1;
+  8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1;
+  0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1;
+  1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1;
+  8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1;
+  10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1;
+  4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1;
+  10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1;
+  5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1;
+  11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1;
+  9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1;
+  6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1;
+  7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1;
+  3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1;
+  7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1;
+  9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1;
+  3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1;
+  6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1;
+  9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1;
+  1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1;
+  4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1;
+  7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1;
+  6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1;
+  3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1;
+  0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1;
+  6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1;
+  0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1;
+  11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1;
+  6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1;
+  5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1;
+  9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1;
+  1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1;
+  1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1;
+  10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1;
+  0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1;
+  5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1;
+  10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1;
+  11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1;
+  9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1;
+  7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1;
+  2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1;
+  8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1;
+  9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1;
+  9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1;
+  1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1;
+  9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1;
+  9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1;
+  5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1;
+  0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1;
+  10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1;
+  2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1;
+  0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1;
+  0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1;
+  9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1;
+  5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1;
+  3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1;
+  5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1;
+  8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1;
+  0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1;
+  9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1;
+  0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1;
+  1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1;
+  3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1;
+  4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1;
+  9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1;
+  11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1;
+  11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1;
+  2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1;
+  9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1;
+  3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1;
+  1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1;
+  4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1;
+  4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1;
+  0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1;
+  3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1;
+  3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1;
+  0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1;
+  9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1;
+  1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + 1;
+endfunction
diff --git a/scripts/plot/__next_line_color__.m b/scripts/plot/__next_line_color__.m
new file mode 100644
index 0000000..0d9e3dd
--- /dev/null
+++ b/scripts/plot/__next_line_color__.m
@@ -0,0 +1,51 @@
+## Copyright (C) 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{rgb} =} __next_line_color__ (@var{reset})
+## Undocumented internal function.
+## @end deftypefn
+
+## Return the next line color in the rotation.
+
+## Author: jwe
+
+function rgb = __next_line_color__ (reset)
+
+  persistent color_rotation;
+  persistent num_colors;
+  persistent color_index;
+
+  if (nargin < 2)
+    if (nargin == 1 && reset)
+      color_rotation = get (gca (), "colororder");
+      num_colors = rows (color_rotation);
+      color_index = 1;
+    elseif (! isempty (color_rotation))
+      rgb = color_rotation(color_index,:);
+      if (++color_index > num_colors)
+	color_index = 1;
+      endif
+    else
+      error ("__next_line_color__: color_rotation not initialized");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/__patch__.m b/scripts/plot/__patch__.m
new file mode 100644
index 0000000..d9812c5
--- /dev/null
+++ b/scripts/plot/__patch__.m
@@ -0,0 +1,316 @@
+## Copyright (C) 2007, 2008, 2009 John W. Eaton, Shai Ayal, Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{h}, @var{fail}] =} __patch__ (@var{p}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## __patch__ (p, x, y, c)
+## Create patch object from x and y with color c and parent p.
+## Return handle to patch object.
+
+## Author: Kai Habel
+
+function [h, failed] = __patch__ (p, varargin)
+
+  failed = false;
+
+  if (isstruct (varargin{1}))
+    if (isfield (varargin{1}, "vertices") && isfield (varargin{1}, "faces"))
+      args{1} = "faces";
+      args{2} = getfield(varargin{1}, "faces");
+      args{3} = "vertices";
+      args{4} = getfield(varargin{1}, "vertices");
+      args{5} = "facevertexcdata";
+      if (isfield (varargin{1}, "facevertexcdata"))
+	args{6} = getfield(varargin{1}, "facevertexcdata");
+      else
+	args{6} = [];
+      endif
+      args = [args; varargin(2:end)];
+      args = setdata (args);
+    else
+      failed = true;
+    endif
+  elseif (isnumeric (varargin{1}))
+    if (nargin < 3 || ! isnumeric (varargin{2}))
+      failed = true;
+    else
+      x = varargin{1};
+      y = varargin{2};
+      iarg = 3;
+
+      if (nargin > 3 && ndims (varargin{3}) == 2 && ndims (x) == 2
+	  && size_equal(x, varargin{3}) && !ischar(varargin{3}))
+	z = varargin{3};
+	iarg++;
+      else
+	z = [];
+      endif
+
+      if (isvector (x))
+	x = x(:);
+	y = y(:);
+	z = z(:);
+      endif
+      args{1} = "xdata";
+      args{2} = x;
+      args{3} = "ydata";
+      args{4} = y;
+      args{5} = "zdata";
+      args{6} = z;
+
+      if (isnumeric (varargin{iarg}))
+	c = varargin{iarg};
+	iarg++;
+
+	if (ndims (c) == 3 && size (c, 2) == 1)
+	  c = permute (c, [1, 3, 2]);
+	endif
+
+	if (isvector (c) && numel (c) == columns (x))
+	  if (isnan (c))
+	    args{7} = "facecolor";
+	    args{8} = [1, 1, 1];
+	    args{9} = "cdata";
+	    args{10} = c;
+	  elseif (isnumeric (c))
+	    args{7} = "facecolor";
+	    args{8} = "flat";
+	    args{9} = "cdata";
+	    args{10} = c;
+	  else
+	    error ("patch: color value not valid");
+	  endif
+	elseif (size (c, ndims (c)) == 3)
+	  args{7} = "facecolor";
+	  args{8} = "flat";
+	  args{9} = "cdata";
+	  args{10} = c;
+	else
+	  ## Color Vectors
+	  if (rows (c) != rows (x) || rows (c) != length (y))
+	    error ("patch: size of x, y, and c must be equal")
+	  else
+	    args{7} = "facecolor";
+	    args{8} = "interp";
+	    args{9} = "cdata";
+	    args{10} = [];
+	  endif
+	endif
+      elseif (ischar (varargin{iarg}) && rem (nargin - iarg, 2) != 0)
+	## Assume that any additional argument over an even number is
+	## color string.
+	args{7} = "facecolor";
+	args{8} =  tolower (varargin{iarg});
+	args{9} = "cdata";
+	args{10} = [];
+	iarg++;
+      else
+	args{7} = "facecolor";
+	args{8} = [0, 1, 0];
+	args{9} = "cdata";
+	args{10} = [];
+      endif
+
+      args = [args, varargin(iarg:end)];
+      args = setvertexdata (args);
+    endif
+  else
+    args = varargin;
+    if (any(cellfun (@(x) strcmpi(x,"faces") || strcmpi(x, "vertices"), args)))
+      args = setdata (args);
+    else
+      args = setvertexdata (args);
+    endif
+  endif
+
+  if (!failed)
+    h = __go_patch__ (p, args {:});
+
+    ## Setup listener functions
+    addlistener (h, "xdata", @update_data);
+    addlistener (h, "ydata", @update_data);
+    addlistener (h, "zdata", @update_data);
+    addlistener (h, "cdata", @update_data);
+
+    addlistener (h, "faces", @update_fvc);
+    addlistener (h, "vertices", @update_fvc);
+    addlistener (h, "facevertexcdata", @update_fvc);
+  endif
+endfunction
+
+function args = delfields(args, flds)
+  idx = cellfun (@(x) any (strcmpi (x, flds)), args);
+  idx = idx | [false, idx(1:end-1)];
+  args (idx) = [];
+endfunction
+
+function args = setdata (args)
+  args = delfields (args, {"xdata", "ydata", "zdata", "cdata"});
+  nargs = length (args);
+  idx = find (cellfun (@(x) strcmpi (x, "faces"), args)) + 1;
+  if (idx > nargs)
+    faces = [];
+  else
+    faces = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "vertices"), args)) + 1;
+  if (idx > nargs)
+    vert = [];
+  else
+    vert = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "facevertexcdata"), args)) + 1;
+  if (isempty(idx) || idx > nargs)
+    fvc = [];
+  else
+    fvc = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "facecolor"), args)) + 1;
+  if (isempty(idx) || idx > nargs)
+    if (!isempty (fvc))
+      fc = "flat";
+    else
+      fc = [0, 1, 0];
+    endif
+    args = {"facecolor", fc, args{:}};
+  else
+    fc = args {idx};
+  endif
+
+  nr = size (faces, 2);
+  nc = size (faces, 1);
+  idx = faces .';
+  t1 = isnan (idx);
+  if (any (t1(:)))
+    t2 = find (t1 != t1([2:end,end],:));
+    idx (t1) = idx (t2 (cell2mat (cellfun (@(x) x(1)*ones(1,x(2)),
+		mat2cell ([1 : nc; sum(t1)], 2, ones(1,nc)), 
+					   "UniformOutput", false))));
+  endif
+  x = reshape (vert(:,1)(idx), size (idx));
+  y = reshape (vert(:,2)(idx), size (idx));
+  if (size(vert,2) > 2)
+    z = reshape (vert(:,3)(idx), size (idx));
+  else
+    z = [];
+  endif
+
+  if (ischar (fc) && (strcmpi (fc, "flat") || strcmpi (fc, "interp")))
+    if (size(fvc, 1) == nc || size (fvc, 1) == 1)
+      c = reshape (fvc, [1, size(fvc)]);
+    else
+      if (size(fvc, 2) == 3)
+	c = cat(3, reshape (fvc(idx, 1), size(idx)),
+		reshape (fvc(idx, 2), size(idx)),
+		reshape (fvc(idx, 3), size(idx)));
+      else
+	c = reshape (fvc(idx), size(idx));
+      endif
+    endif
+  else
+    c = [];
+  endif
+  args = {"xdata", x, "ydata", y, "zdata", z, "cdata", c, args{:}};
+endfunction
+
+function args = setvertexdata (args)
+  args = delfields (args, {"vertices", "faces", "facevertexcdata"});
+  nargs = length (args);
+  idx = find (cellfun (@(x) strcmpi (x, "xdata"), args)) + 1;
+  if (idx > nargs)
+    x = [];
+  else
+    x = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "ydata"), args)) + 1;
+  if (idx > nargs)
+    y = [];
+  else
+    y = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "zdata"), args)) + 1;
+  if (isempty(idx) || idx > nargs)
+    z = [];
+  else
+    z = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "cdata"), args)) + 1;
+  if (isempty(idx) || idx > nargs)
+    c = [];
+  else
+    c = args {idx};
+  endif
+  idx = find (cellfun (@(x) strcmpi (x, "facecolor"), args)) + 1;
+  if (isempty(idx) || idx > nargs)
+    if (!isempty (c))
+      fc = "flat";
+    else
+      fc = [0, 1, 0];
+    endif
+    args = {"facecolor", fc, args{:}};
+  else
+    fc = args {idx};
+  endif
+
+  [nr, nc] = size (x);
+  if (!isempty (z))
+    vert = [x(:), y(:), z(:)];
+  else
+    vert = [x(:), y(:)];
+  endif
+  faces = reshape (1:numel(x), rows (x), columns (x));
+  faces = faces';
+
+  if (ischar (fc) && (strcmpi (fc, "flat") || strcmpi (fc, "interp")))
+    if (ndims (c) == 3)
+      fvc = reshape (c, size (c, 1) * size (c, 2), size(c, 3));
+    else
+      fvc = c(:);
+    endif
+  else
+    fvc = [];
+  endif
+
+  args = {"faces", faces, "vertices", vert, "facevertexcdata", fvc, args{:}};
+endfunction
+
+function update_data (h, d)
+  update_handle (h, false);
+endfunction
+
+function update_fvc (h, d)
+  update_handle (h, true);
+endfunction
+
+function update_handle (h, isfv)
+  persistent recursive = false;
+
+  if (! recursive)
+    recursive = true;
+    f = get (h);
+    if (isfvc)
+      set (h, setvertexdata ([fieldnames(f), struct2cell(f)].'(:)){:});
+    else
+      set (h, setdata ([fieldnames(f), struct2cell(f)].'(:)){:});
+    endif
+    recursive = false;
+  endif
+endfunction
diff --git a/scripts/plot/__plr1__.m b/scripts/plot/__plr1__.m
new file mode 100644
index 0000000..b927c5b
--- /dev/null
+++ b/scripts/plot/__plr1__.m
@@ -0,0 +1,51 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 2000, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plr1__ (@var{h}, @var{theta}, @var{fmt})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plr1__ (h, theta, fmt)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  [nr, nc] = size (theta);
+  if (nr == 1)
+    theta = theta';
+    tmp = nr;
+    nr = nc;
+    nc = tmp;
+  endif
+  theta_i = imag (theta);
+  if (any (theta_i))
+    rho = theta_i;
+    theta = real (theta);
+  else
+    rho = theta;
+    theta = (1:nr)';
+  endif
+
+  retval = __plr2__ (h, theta, rho, fmt);
+
+endfunction
diff --git a/scripts/plot/__plr2__.m b/scripts/plot/__plr2__.m
new file mode 100644
index 0000000..ec09d1c
--- /dev/null
+++ b/scripts/plot/__plr2__.m
@@ -0,0 +1,124 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plr2__ (@var{h}, @var{theta}, @var{rho}, @var{fmt})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plr2__ (h, theta, rho, fmt)
+
+  if (nargin != 4)
+    print_usage ();
+  endif
+
+  if (any (imag (theta)))
+    theta = real (theta);
+  endif
+
+  if (any (imag (rho)))
+    rho = real (rho);
+  endif
+
+  if (isscalar (theta))
+    if (isscalar (rho))
+      x = rho * cos (theta);
+      y = rho * sin (theta);
+      retval = __plt__ ("polar", h, x, y, fmt);
+    else
+      error ("__plr2__: invalid data for plotting");
+    endif
+  elseif (isvector (theta))
+    if (isvector (rho))
+      if (length (theta) != length (rho))
+        error ("__plr2__: vector lengths must match");
+      endif
+      if (rows (rho) == 1)
+        rho = rho';
+      endif
+      if (rows (theta) == 1)
+        theta = theta';
+      endif
+      x = rho .* cos (theta);
+      y = rho .* sin (theta);
+      retval = __plt__ ("polar", h, x, y, fmt);
+    elseif (ismatrix (rho))
+      [t_nr, t_nc] = size (theta);
+      if (t_nr == 1)
+        theta = theta';
+        tmp = t_nr;
+        t_nr = t_nc;
+        t_nc = tmp;
+      endif
+      [r_nr, r_nc] = size (rho);
+      if (t_nr != r_nr)
+        rho = rho';
+        tmp = r_nr;
+        r_nr = r_nc;
+        r_nc = tmp;
+      endif
+      if (t_nr != r_nr)
+        error ("__plr2__: vector and matrix sizes must match");
+      endif
+      x = diag (cos (theta)) * rho;
+      y = diag (sin (theta)) * rho;
+      retval = __plt__ ("polar", h, x, y, fmt);
+    else
+      error ("__plr2__: invalid data for plotting");
+    endif
+  elseif (ismatrix (theta))
+    if (isvector (rho))
+      [r_nr, r_nc] = size (rho);
+      if (r_nr == 1)
+        rho = rho';
+        tmp = r_nr;
+        r_nr = r_nc;
+        r_nc = tmp;
+      endif
+      [t_nr, t_nc] = size (theta);
+      if (r_nr != t_nr)
+        theta = theta';
+        tmp = t_nr;
+        t_nr = t_nc;
+        t_nc = tmp;
+      endif
+      if (r_nr != t_nr)
+        error ("__plr2__: vector and matrix sizes must match");
+      endif
+      diag_r = diag (rho);
+      x = diag_r * cos (theta);
+      y = diag_r * sin (theta);
+      retval = __plt__ ("polar", h, x, y, fmt);
+    elseif (ismatrix (rho))
+      if (! size_equal (rho, theta))
+        error ("__plr2__: matrix dimensions must match");
+      endif
+      x = rho .* cos (theta);
+      y = rho .* sin (theta);
+      retval = __plt__ ("polar", h, x, y, fmt);
+    else
+      error ("__plr2__: invalid data for plotting");
+    endif
+  else
+    error ("__plr2__: invalid data for plotting");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt1__.m b/scripts/plot/__plt1__.m
new file mode 100644
index 0000000..acff996
--- /dev/null
+++ b/scripts/plot/__plt1__.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 2000, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt1__ (@var{h}, @var{x1}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt1__ (h, x1, options, properties)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 3 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 4)
+    properties = {};
+  endif
+
+  if (! isstruct (options))
+    error ("__plt1__: options must be a struct array");
+  endif
+
+  [nr, nc] = size (x1);
+  if (nr == 1)
+    x1 = x1.';
+    tmp = nr;
+    nr = nc;
+    nc = tmp;
+  endif
+  x1_i = imag (x1);
+  if (any (any (x1_i)))
+    x2 = x1_i;
+    x1 = real (x1);
+  else
+    x2 = x1;
+    x1 = (1:nr)';
+  endif
+
+  retval = __plt2__ (h, x1, x2, options, properties);
+
+endfunction
diff --git a/scripts/plot/__plt2__.m b/scripts/plot/__plt2__.m
new file mode 100644
index 0000000..a4d06a7
--- /dev/null
+++ b/scripts/plot/__plt2__.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2__ (@var{h}, @var{x1}, @var{x2}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2__ (h, x1, x2, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  if (! isstruct (options))
+    error ("__plt1__: options must be a struct array");
+  endif
+
+  if (any (any (imag (x1))))
+    x1 = real (x1);
+  endif
+
+  if (any (any (imag (x2))))
+    x2 = real (x2);
+  endif
+
+  h_set = false;
+  if (isempty (x1) && isempty (x2))
+    retval = zeros (0, 1);
+  elseif (isscalar (x1))
+    if (isscalar (x2))
+      retval = __plt2ss__ (h, x1, x2, options, properties);
+    elseif (isvector (x2))
+      retval = __plt2sv__ (h, x1, x2, options, properties);
+    else
+      error ("__plt2__: invalid data for plotting");
+    endif
+  elseif (isvector (x1))
+    if (isscalar (x2))
+      retval = __plt2vs__ (h, x1, x2, options, properties);
+    elseif (isvector (x2))
+      retval = __plt2vv__ (h, x1, x2, options, properties);
+    elseif (ismatrix (x2))
+      retval = __plt2vm__ (h, x1, x2, options, properties);
+    else
+      error ("__plt2__: invalid data for plotting");
+    endif
+  elseif (ismatrix (x1))
+    if (isvector (x2))
+      retval = __plt2mv__ (h, x1, x2, options, properties);
+    elseif (ismatrix (x2))
+      retval = __plt2mm__ (h, x1, x2, options, properties);
+    else
+      error ("__plt2__: invalid data for plotting");
+    endif
+  else
+    error ("__plt2__: invalid data for plotting");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2mm__.m b/scripts/plot/__plt2mm__.m
new file mode 100644
index 0000000..710ec55
--- /dev/null
+++ b/scripts/plot/__plt2mm__.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2mm__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2mm__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  [x_nr, x_nc] = size (x);
+  [y_nr, y_nc] = size (y);
+
+  k = 1;
+  if (x_nr == y_nr && x_nc == y_nc)
+    if (x_nc > 0)
+      if (numel (options) == 1)
+	options = repmat (options(:), x_nc, 1);
+      endif
+      retval = zeros (x_nc, 1);
+      for i = 1:x_nc
+	tkey = options(i).key;
+	if (! isempty (tkey))
+	  set (h, "key", "on");
+	endif
+	color = options(i).color;
+	if (isempty (color))
+	  color = __next_line_color__ ();
+	endif
+
+	retval(i) = line (x(:,i), y(:,i), "keylabel", tkey, "color", color,
+			  "linestyle", options(i).linestyle,
+			  "marker", options(i).marker, properties{:});
+      endfor
+    else
+      error ("__plt2mm__: arguments must be a matrices");
+    endif
+  else
+    error ("__plt2mm__: matrix dimensions must match");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2mv__.m b/scripts/plot/__plt2mv__.m
new file mode 100644
index 0000000..db73e00
--- /dev/null
+++ b/scripts/plot/__plt2mv__.m
@@ -0,0 +1,85 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2mv__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2mv__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  [x_nr, x_nc] = size (x);
+  [y_nr, y_nc] = size (y);
+
+  if (y_nr == 1)
+    y = y';
+    tmp = y_nr;
+    y_nr = y_nc;
+    y_nc = tmp;
+  endif
+
+  if (x_nr == y_nr)
+    1;
+  elseif (x_nc == y_nr)
+    x = x';
+    tmp = x_nr;
+    x_nr = x_nc;
+    x_nc = tmp;
+  else
+    error ("__plt2mv__: matrix dimensions must match");
+  endif
+
+  if (x_nc > 0)
+    if (numel (options) == 1)
+      options = repmat (options(:), x_nc, 1);
+    endif
+    retval = zeros (x_nc, 1);
+    for i = 1:x_nc
+      tkey = options(i).key;
+      if (! isempty (tkey))
+	set (h, "key", "on");
+      endif
+      color = options(i).color;
+      if (isempty (color))
+	color = __next_line_color__ ();
+      endif
+
+      retval(i) = line (x(:,i), y, "keylabel", tkey, "color", color,
+			"linestyle", options(i).linestyle,
+			"marker", options(i).marker, properties{:});
+    endfor
+  else
+    error ("__plt2mv__: arguments must be a matrices");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2ss__.m b/scripts/plot/__plt2ss__.m
new file mode 100644
index 0000000..e8804f0
--- /dev/null
+++ b/scripts/plot/__plt2ss__.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2ss__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2ss__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  if (numel (options) > 1)
+    options = options(1);
+  endif
+
+  [x_nr, x_nc] = size (x);
+  [y_nr, y_nc] = size (y);
+
+  if (x_nr == 1 && x_nr == y_nr && x_nc == 1 && x_nc == y_nc)
+    key = options.key;
+    if (! isempty (key))
+      set (h, "key", "on");
+    endif
+    color = options.color;
+    if (isempty (color))
+      color = __next_line_color__ ();
+    endif
+
+    retval = line (x, y, "keylabel", key, "color", color,
+		   "linestyle", options.linestyle,
+		   "marker", options.marker, properties{:});
+  else
+    error ("__plt2ss__: arguments must be scalars");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2sv__.m b/scripts/plot/__plt2sv__.m
new file mode 100644
index 0000000..c6a2d0b
--- /dev/null
+++ b/scripts/plot/__plt2sv__.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2sv__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2sv__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  if (isscalar (x) && isvector (y))
+    len = numel (y);
+    if (numel (options) == 1)
+      options = repmat (options(:), len, 1);
+    endif
+    retval = zeros (len, 1);
+    for i = 1:len
+      tkey = options(i).key;
+      if (! isempty (tkey))
+	set (h, "key", "on");
+      endif
+      color = options(i).color;
+      if (isempty (color))
+	color = __next_line_color__ ();
+      endif
+
+      retval(i) = line (x, y(i), "keylabel", tkey, "color", color,
+			"linestyle", options(i).linestyle,
+			"marker", options(i).marker, properties{:});
+    endfor
+  else
+    error ("__plt2sv__: first arg must be scalar, second arg must be vector");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2vm__.m b/scripts/plot/__plt2vm__.m
new file mode 100644
index 0000000..77ac62a
--- /dev/null
+++ b/scripts/plot/__plt2vm__.m
@@ -0,0 +1,85 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2vm__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2vm__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  [x_nr, x_nc] = size (x);
+  [y_nr, y_nc] = size (y);
+
+  if (x_nr == 1)
+    x = x';
+    tmp = x_nr;
+    x_nr = x_nc;
+    x_nc = tmp;
+  endif
+
+  if (x_nr == y_nr)
+    1;
+  elseif (x_nr == y_nc)
+    y = y';
+    tmp = y_nr;
+    y_nr = y_nc;
+    y_nc = tmp;
+  else
+    error ("__plt2vm__: matrix dimensions must match");
+  endif
+
+  if (y_nc > 0)
+    if (numel (options) == 1)
+      options = repmat (options(:), y_nc, 1);
+    endif
+    retval = zeros (y_nc, 1);
+    for i = 1:y_nc
+      tkey = options(i).key;
+      if (! isempty (tkey))
+	set (h, "key", "on");
+      endif
+      color = options(i).color;
+      if (isempty (color))
+	color = __next_line_color__ ();
+      endif
+
+      retval(i) = line (x, y(:,i), "keylabel", tkey, "color", color,
+			"linestyle", options(i).linestyle,
+			"marker", options(i).marker, properties{:});
+    endfor
+  else
+    error ("__plt2vm__: arguments must be a matrices");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2vs__.m b/scripts/plot/__plt2vs__.m
new file mode 100644
index 0000000..9e9a98a
--- /dev/null
+++ b/scripts/plot/__plt2vs__.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2vs__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2vs__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  if (isvector (x) && isscalar (y))
+    len = numel (x);
+    if (numel (options) == 1)
+      options = repmat (options(:), len, 1);
+    endif
+    retval = zeros (len, 1);
+    for i = 1:len
+      tkey = options(i).key;
+      if (! isempty (tkey))
+	set (h, "key", "on");
+      endif
+      color = options(i).color;
+      if (isempty (color))
+	color = __next_line_color__ ();
+      endif
+
+      retval(i) = line (x(i), y, "keylabel", tkey, "color", color,
+			"linestyle", options(i).linestyle,
+			"marker", options(i).marker, properties{:});
+    endfor
+  else
+    error ("__plt2vs__: first arg must be vector, second arg must be scalar");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt2vv__.m b/scripts/plot/__plt2vv__.m
new file mode 100644
index 0000000..5620285
--- /dev/null
+++ b/scripts/plot/__plt2vv__.m
@@ -0,0 +1,79 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt2vv__ (@var{h}, @var{x}, @var{y}, @var{options}, @var{properties})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt2vv__ (h, x, y, options, properties)
+
+  if (nargin < 3 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 4 || isempty (options))
+    options = __default_plot_options__ ();
+  endif
+
+  if (nargin < 5)
+    properties = {};
+  endif
+
+  if (numel (options) > 1)
+    options = options(1);
+  endif
+
+  [x_nr, x_nc] = size (x);
+  [y_nr, y_nc] = size (y);
+
+  if (x_nr == 1)
+    x = x';
+    tmp = x_nr;
+    x_nr = x_nc;
+    x_nc = tmp;
+  endif
+
+  if (y_nr == 1)
+    y = y';
+    tmp = y_nr;
+    y_nr = y_nc;
+    y_nc = tmp;
+  endif
+
+  if (x_nr == y_nr)
+    key = options.key;
+    if (! isempty (key))
+      set (h, "key", "on");
+    endif
+    color = options.color;
+    if (isempty (color))
+      color = __next_line_color__ ();
+    endif
+
+    retval = line (x, y, "keylabel", key, "color", color,
+	      "linestyle", options.linestyle,
+	      "marker", options.marker, properties{:});
+  else
+    error ("__plt2vv__: vector lengths must match");
+  endif
+
+endfunction
diff --git a/scripts/plot/__plt__.m b/scripts/plot/__plt__.m
new file mode 100644
index 0000000..48c25ba
--- /dev/null
+++ b/scripts/plot/__plt__.m
@@ -0,0 +1,120 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __plt__ (@var{caller}, @var{h}, @var{varargin})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = __plt__ (caller, h, varargin)
+
+  nargs = nargin - 2;
+
+  if (nargs > 0)
+
+    k = 1;
+
+    x_set = false;
+    y_set = false;
+    property_set = false;
+    properties = {};
+
+    ## Gather arguments, decode format, gather plot strings, and plot lines.
+
+    retval = [];
+
+    while (nargs > 0 || x_set)
+
+      if (nargs == 0)
+	## Force the last plot when input variables run out.
+	next_cell = {};
+	next_arg = {""};
+      else
+	next_cell = varargin(k);
+	next_arg = varargin{k++};
+      endif
+
+      nargs--;
+
+      if (ischar (next_arg) || iscellstr (next_arg))
+	if (x_set)
+	  [options, valid] = __pltopt__ (caller, next_arg, false);
+	  if (! valid)
+	    if (nargs == 0)
+	      error ("%s: properties must appear followed by a value", caller);
+	    endif
+	    properties = [properties, [next_cell, varargin(k++)]];
+	    nargs--;
+	    continue;
+	  else
+	    while (nargs > 0 && ischar (varargin{k}))
+	      if (nargs < 2)
+		error ("%s: properties must appear followed by a value",
+		       caller);
+	      endif
+	      properties = [properties, varargin(k:k+1)];
+	      k += 2;
+	      nargs -= 2;
+	    endwhile
+	  endif
+	  if (y_set)
+	    tmp = __plt2__ (h, x, y, options, properties);
+	    properties = {};
+	    retval = [retval; tmp];
+	  else
+	    tmp = __plt1__ (h, x, options, properties);
+	    properties = {};
+	    retval = [retval; tmp];
+	  endif
+	  x_set = false;
+	  y_set = false;
+	else
+	  error ("plot: no data to plot");
+	endif
+      elseif (x_set)
+	if (y_set)
+	  options = __pltopt__ (caller, {""});
+	  tmp = __plt2__ (h, x, y, options, properties);
+	  retval = [retval; tmp];
+	  x = next_arg;
+	  y_set = false;
+	  properties = {};
+	else
+	  y = next_arg;
+	  y_set = true;
+	endif
+      else
+	x = next_arg;
+	x_set = true;
+      endif
+
+    endwhile
+
+  else
+    msg = sprintf ("%s (y)\n", caller);
+    msg = sprintf ("%s       %s (x, y, ...)\n", msg, caller);
+    msg = sprintf ("%s       %s (x, y, fmt, ...)", msg, caller);
+    msg = sprintf ("%s       %s (x, y, property, value, ...)", msg, caller);
+    usage (msg);
+  endif
+
+endfunction
+  
diff --git a/scripts/plot/__plt_get_axis_arg__.m b/scripts/plot/__plt_get_axis_arg__.m
new file mode 100644
index 0000000..19a6e35
--- /dev/null
+++ b/scripts/plot/__plt_get_axis_arg__.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1996, 1997, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{h}, @var{varargin}, @var{narg}] =} __plt_get_axis_arg__ (@var{caller}, @var{varargin})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: jwe
+
+function [h, varargin, narg] = __plt_get_axis_arg__ (caller, varargin)
+
+  if (islogical (caller))
+    nogca = caller;
+    caller = varargin{1};
+    varargin(1) = [];
+  else
+    nogca = false;
+  endif
+
+  ## Figure handles are integers, but object handles are non integer,
+  ## therefore ignore integer scalars.
+  if (nargin > 1 && length (varargin) > 0 && isnumeric (varargin{1}) 
+      && numel (varargin{1}) == 1 && ishandle (varargin{1}(1)) 
+      && varargin{1}(1) != 0 && ! isfigure (varargin{1}(1)))
+    tmp = varargin{1};
+    obj = get (tmp);
+    if (strcmp (obj.type, "axes") || strcmp (obj.type, "hggroup"))
+      h = ancestor (tmp, "axes");
+      varargin(1) = [];
+      if (isempty (varargin))
+	varargin = {};
+      endif
+    else
+      error ("%s: expecting first argument to be axes handle", caller);
+    endif
+  else
+    f = get (0, "currentfigure");
+    if (isempty (f))
+      h = [];
+    else
+      h = get (f, "currentaxes");
+    endif
+    if (isempty (h))
+      if (nogca)
+	h = NaN;
+      else
+	h = gca ();
+      endif
+    endif
+    if (nargin < 2)
+      varargin = {};
+    endif
+  endif
+
+  narg = length (varargin);
+
+endfunction
diff --git a/scripts/plot/__pltopt1__.m b/scripts/plot/__pltopt1__.m
new file mode 100644
index 0000000..abc2253
--- /dev/null
+++ b/scripts/plot/__pltopt1__.m
@@ -0,0 +1,136 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+##               2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{options}, @var{valid}] =} __pltopt1__ (@var{caller}, @var{opt}, @var{err_on_invalid})
+## Undocumented internal function.
+## @end deftypefn
+
+## Really decode plot option strings.
+
+## Author: Rick Niles <niles at axp745.gsfc.nasa.gov>
+## Adapted-By: jwe
+## Maintainer: jwe
+
+function [options, valid] = __pltopt1__ (caller, opt, err_on_invalid)
+
+  options = __default_plot_options__ ();
+  valid = true;
+
+  more_opts = 1;
+
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (! ischar (opt))
+    return;
+  endif
+
+  have_linestyle = false;
+  have_marker = false;
+
+  ## If called by __errplot__, extract the linestyle before proceeding.
+  if (strcmp (caller,"__errplot__"))
+    if (strncmp (opt, "#~>", 3))
+      n = 3;
+    elseif (strncmp (opt, "#~", 2) || strncmp (opt, "~>", 2))
+      n = 2;
+    elseif (strncmp (opt, "~", 1) || strncmp (opt, ">", 1) 
+	    || strncmp (opt, "#", 1))
+      n = 1;
+    endif
+      options.linestyle = opt(1:n);
+      opt(1:n) = [];
+      have_linestyle = true;
+  endif
+
+  while (! isempty (opt))
+    if (strncmp (opt, "--", 2) || strncmp (opt, "-.", 2))
+      options.linestyle = opt(1:2);
+      have_linestyle = true;
+      n = 2;
+    else
+      topt = opt(1);
+      n = 1;
+      if (topt == "-" || topt == ":")
+	have_linestyle = true;
+	options.linestyle = topt;
+      elseif (topt == "+" || topt == "o" || topt == "*"
+	      || topt == "." || topt == "x" || topt == "s"
+	      || topt == "d" || topt == "^" || topt == "v"
+	      || topt == ">" || topt == "<" || topt == "p"
+	      || topt == "h" || topt == "@")
+	have_marker = true;
+	## Backward compatibility.  Leave undocumented.
+	if (topt == "@")
+	  topt = "+";
+	endif
+	options.marker = topt;
+### Numeric color specs for backward compatibility.  Leave undocumented.
+      elseif (topt == "k" || topt == "0")
+	options.color = [0, 0, 0];
+      elseif (topt == "r" || topt == "1")
+	options.color = [1, 0, 0];
+      elseif (topt == "g" || topt == "2")
+	options.color = [0, 1, 0];
+      elseif (topt == "b" || topt == "3")
+	options.color = [0, 0, 1];
+      elseif (topt == "y")
+	options.color = [1, 1, 0];
+      elseif (topt == "m" || topt == "4")
+	options.color = [1, 0, 1];
+      elseif (topt == "c" || topt == "5")
+	options.color = [0, 1, 1];
+      elseif (topt == "w" || topt == "6")
+	options.color = [1, 1, 1];
+      elseif (isspace (topt))
+	## Do nothing.
+      elseif (topt == ";")
+	t = index (opt(2:end), ";");
+	if (t)
+	  options.key = undo_string_escapes (opt(2:t));
+	  n = t+1;
+	else
+	  if (err_on_invalid)
+            error ("%s: unfinished key label", caller);
+	  else
+	    valid = false;
+	    options = __default_plot_options__ ();
+	    return;
+	  endif
+        endif
+      else
+	if (err_on_invalid)
+	  error ("%s: unrecognized format character: `%s'", caller, topt);
+	else
+	  valid = false;
+	  options = __default_plot_options__ ();
+	  return;
+	endif
+      endif
+    endif
+    opt(1:n) = [];
+  endwhile
+
+  if (have_marker && ! have_linestyle)
+    options.linestyle = "none";
+  endif
+
+endfunction
diff --git a/scripts/plot/__pltopt__.m b/scripts/plot/__pltopt__.m
new file mode 100644
index 0000000..71b9413
--- /dev/null
+++ b/scripts/plot/__pltopt__.m
@@ -0,0 +1,122 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __pltopt__ (@var{caller}, @var{opt})
+## Undocumented internal function.
+## @end deftypefn
+
+## @deftypefn {Function File} {} __pltopt__ (@var{caller}, @var{opt})
+##
+## Decode plot option strings.
+##
+## @var{opt} can currently be some combination of the following:
+##
+## @table @code
+## @item "-"
+## For solid linestyle (default).
+##
+## @item "--"
+## For dashed line style.
+##
+## @item "-."
+## For linespoints plot style.
+##
+## @item ":"
+## For dots plot style.
+##
+## @item "r"
+## Red line color.
+##
+## @item "g"
+## Green line color.
+##
+## @item "b"
+## Blue line color.
+##
+## @item "c"
+## Cyan line color.
+##
+## @item "m"
+## Magenta line color.
+##
+## @item "y"
+## Yellow line color.
+##
+## @item "k"
+## Black line color.
+##
+## @item "w"
+## White line color.
+##
+## @item ";title;"
+## Here @code{"title"} is the label for the key.
+##
+## @item "+"
+## @itemx "o"
+## @itemx "*"
+## @itemx "."
+## @itemx "x"
+## @itemx "s"
+## @itemx "d"
+## @itemx "^"
+## @itemx "v"
+## @itemx ">"
+## @itemx "<"
+## @itemx "p"
+## @itemx "h"
+## Used in combination with the points or linespoints styles, set the point
+## style.
+## @end table
+##
+## The legend may be fixed to include the name of the variable
+## plotted in some future version of Octave.
+
+## Author: jwe
+
+function [options, valid] = __pltopt__ (caller, opt, err_on_invalid)
+
+  valid = true;
+  options =  __default_plot_options__ ();
+
+  if ((nargin == 2 || nargin == 3) && (nargout == 1 || nargout == 2))
+    if (nargin == 2)
+      err_on_invalid = true;
+    endif
+    if (ischar (opt))
+      nel = rows (opt);
+    elseif (iscellstr (opt))
+      nel = numel (opt);
+    else
+      error ("__pltopt__: expecting argument to be character string or cell array of character strings");
+    endif
+    if (ischar (opt))
+      opt = cellstr (opt);
+    endif
+    for i = nel:-1:1
+      [options(i), valid] = __pltopt1__ (caller, opt{i}, err_on_invalid);
+      if (! err_on_invalid && ! valid)
+	return;
+      endif
+    endfor
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/__quiver__.m b/scripts/plot/__quiver__.m
new file mode 100644
index 0000000..b58e8f5
--- /dev/null
+++ b/scripts/plot/__quiver__.m
@@ -0,0 +1,421 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{hg} =} __quiver__ (@dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+function hg = __quiver__ (varargin)
+
+  h = varargin{1};
+  is3d = varargin{2};
+
+  autoscale = 0.9;
+  arrowsize = 0.2;
+
+  firstnonnumeric = Inf;
+  for i = 3:nargin
+    if (! isnumeric (varargin{i}))
+      firstnonnumeric = i;
+      break;
+    endif
+  endfor
+
+  ioff = 3;
+  if (nargin < (6 + is3d) || firstnonnumeric < (6 + is3d))
+    u = varargin{ioff++};
+    v = varargin{ioff++};
+    if (is3d)
+      w = varargin{ioff++}
+      [x, y, z] = meshgrid (1:size(u,2), 1:size(u,1), 1:max(size(w)));
+    else
+      [x, y] = meshgrid (1:size(u,2), 1:size(u,1));
+    endif
+    if (nargin >= ioff && isnumeric (varargin{ioff})
+	&& isscalar (varargin{ioff}))
+      autoscale = varargin{ioff++};
+    endif
+  else
+    x = varargin{ioff++};
+    y = varargin{ioff++};
+    if (is3d)
+      z = varargin{ioff++};
+    endif
+    u = varargin{ioff++};
+    v = varargin{ioff++}; 
+    if (is3d)
+      w = varargin{ioff++};
+      if (isvector (x) && isvector (y) && isvector (z)
+	  && (! isvector (u) || ! isvector (v) || ! isvector(w)))
+	[x, y, z] = meshgrid (x, y, z);
+      endif
+    else
+      if (isvector (x) && isvector (y) && (! isvector (u) || ! isvector (v)))
+	[x, y] = meshgrid (x, y);
+      endif
+    endif
+    if (nargin >= ioff && isnumeric (varargin{ioff})
+	&& isscalar (varargin{ioff}))
+      autoscale = varargin{ioff++};
+    endif
+  endif
+
+  have_filled = false;
+  have_line_spec = false;
+  args = {};
+  while (ioff <= nargin)
+    arg = varargin{ioff++};
+    if (ischar (arg) && strncmpi (arg, "filled", 6))
+      have_filled = true;
+    elseif ((ischar (arg) || iscell (arg))
+	    && ! have_line_spec)
+      [linespec, valid] = __pltopt__ ("quiver", arg, false);
+      if (valid)
+	have_line_spec = true;
+	if (strncmp (linespec.linestyle, "none", 4))
+	  linespec.linestyle = "-";
+	endif
+      else
+	args {end + 1} = arg;
+        if (ioff <= nargin)
+          args {end + 1} = varargin{ioff++};
+        endif
+      endif
+    else
+      args {end + 1} = arg;
+      if (ioff <= nargin)
+        args {end + 1} = varargin{ioff++};
+      endif
+    endif
+  endwhile
+
+  if (autoscale && numel (u) > 1)
+    ## Scale the arrows to fit in the grid
+    dx = (max(x(:)) - min(x(:))) ./ size (x, 2);
+    dy = (max(y(:)) - min(y(:))) ./ size (y, 1);
+    if (is3d)
+      ## What should this be divided by? The below seems right
+      dz = (max(z(:)) - min(z(:))) ./ max (size (z));
+      len = max (sqrt (u(:).^2 + dy(:).^2) + dz(:).^2);
+    else
+      len = max (sqrt (u(:).^2 + dy(:).^2));
+      dz = 0;
+    endif
+    if (len > 0)
+      s = 2 * autoscale / sqrt (2) * sqrt (dx.^2 + dy.^2 + dz.^2) / len; 
+      uu = s * u;
+      vv = s * v;
+      if (is3d)
+	ww = s*w;
+      endif
+    endif
+  else
+    uu = u;
+    vv = v;
+    if (is3d)
+      ww = w;
+    endif
+  endif
+
+  hstate = get (h, "nextplot");
+  unwind_protect
+    hg = hggroup ();
+    if (is3d)
+      args = __add_datasource__ ("quiver3", hg, 
+				 {"x", "y", "z", "u", "v", "w"}, args{:});
+    else
+      args = __add_datasource__ ("quiver", hg, 
+				 {"x", "y", "z", "u", "v", "w"}, args{:});
+    endif
+    hold on;
+
+    addproperty ("xdata", hg, "data", x);
+    addproperty ("ydata", hg, "data", y);
+
+    addproperty ("udata", hg, "data", u);
+    addproperty ("vdata", hg, "data", v);
+    if (is3d)
+      addproperty ("zdata", hg, "data", z);
+      addproperty ("wdata", hg, "data", w);
+    else
+      addproperty ("zdata", hg, "data", []);
+      addproperty ("wdata", hg, "data", []);
+    endif
+
+    addlistener (hg, "xdata", @update_data);
+    addlistener (hg, "ydata", @update_data);
+    addlistener (hg, "zdata", @update_data);
+    addlistener (hg, "udata", @update_data);
+    addlistener (hg, "vdata", @update_data);
+    addlistener (hg, "wdata", @update_data);
+
+    x = x(:);
+    y = y(:);
+    xend = x + uu(:);
+    yend = y + vv(:);
+    if (is3d)
+      z = z(:);
+      zend = z + ww(:);
+    endif
+
+    if (have_line_spec)
+      if (is3d)
+	h1 = plot3 ([x.'; xend.'; NaN(1, length (x))](:),
+		    [y.'; yend.'; NaN(1, length (y))](:),
+		    [z.'; zend.'; NaN(1, length (z))](:),
+		    "linestyle", linespec.linestyle, 
+		    "color", linespec.color, "parent", hg);
+      else
+	h1 = plot ([x.'; xend.'; NaN(1, length (x))](:),
+		   [y.'; yend.'; NaN(1, length (y))](:),
+		   "linestyle", linespec.linestyle, 
+		    "color", linespec.color, "parent", hg);
+      endif
+    else
+      if (is3d)
+	h1 = plot3 ([x.'; xend.'; NaN(1, length (x))](:),
+		    [y.'; yend.'; NaN(1, length (y))](:),
+		    [z.'; zend.'; NaN(1, length (z))](:),
+		    "parent", hg);
+      else
+	h1 = plot ([x.'; xend.'; NaN(1, length (x))](:),
+		   [y.'; yend.'; NaN(1, length (y))](:),
+		   "parent", hg);
+      endif
+    endif
+
+    xtmp = x + uu(:) .* (1 - arrowsize);
+    ytmp = y + vv(:) .* (1 - arrowsize);
+    xarrw1 = xtmp + (y - yend) * arrowsize / 3;
+    xarrw2 = xtmp - (y - yend) * arrowsize / 3;
+    yarrw1 = ytmp - (x - xend) * arrowsize / 3;
+    yarrw2 = ytmp + (x - xend) * arrowsize / 3;
+    if (is3d)
+      zarrw1 = zarrw2 = zend - ww(:) * arrowsize;
+    endif
+
+    if (have_line_spec)
+      if (isfield (linespec, "marker") && 
+	! strncmp (linespec.marker, "none", 4))
+	if (is3d)
+	  h2 = plot3 ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
+		      [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
+		      [zarrw1.'; zend.'; zarrw2.'; NaN(1, length (z))](:),
+		      "linestyle", "none", "parent", hg);
+	else
+	  h2 = plot ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
+		     [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
+		     "linestyle", "none", "parent", hg);
+	endif
+      else
+	if (is3d)
+	  h2 = plot3 ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
+		      [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
+		      [zarrw1.'; zend.'; zarrw2.'; NaN(1, length (z))](:),
+		      "linestyle", linespec.linestyle,
+		      "color", linespec.color, "parent", hg);
+	else
+	  h2 = plot ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
+		     [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
+		     "linestyle", linespec.linestyle,
+		      "color", linespec.color, "parent", hg);
+	endif
+      endif
+    elseif (is3d)
+      h2 = plot3 ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
+		  [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
+		  [zarrw1.'; zend.'; zarrw2.'; NaN(1, length (z))](:),
+		  "parent", hg);
+    else
+      h2 = plot ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
+		 [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
+		 "parent", hg);
+    endif
+
+    if (! have_line_spec
+	|| (isfield (linespec, "marker")
+	    && strncmp (linespec.marker, "none", 4)))
+      if (is3d)
+	h3 = plot3 (x, y, z, "linestyle", "none", "marker", "none", 
+		    "parent", hg);
+      else
+	h3 = plot (x, y, "linestyle", "none", "marker", "none", "parent", hg);
+      endif
+    else
+      if (is3d)
+	h3 = plot3 (x, y, z, "linestyle", "none", "marker", linespec.marker,
+		    "parent", hg);
+      else
+
+	h3 = plot (x, y, "linestyle", "none", "marker", linespec.marker,
+		   "parent", hg);
+      endif
+    endif
+    if (have_filled)
+      ## FIXME gnuplot doesn't respect the markerfacecolor field
+      set (h3, "markerfacecolor", get (h1, "color")); 
+    endif
+
+    ## Set up the hggroup properties and listeners
+    if (autoscale)
+      addproperty ("autoscale", hg, "radio", "{on}|off", "on");
+      addproperty ("autoscalefactor", hg, "data", autoscale)
+    else
+      addproperty ("autoscale", hg, "radio", "{on}|off", "off");
+      addproperty ("autoscalefactor", hg, "data", 1.0)
+    endif
+    addlistener (hg, "autoscale", @update_data)
+    addlistener (hg, "autoscalefactor", @update_data)
+
+    addproperty ("maxheadsize", hg, "data", arrowsize)
+    addlistener (hg, "maxheadsize", @update_data);
+
+    addproperty ("showarrowhead", hg, "radio", "{on}|off", "on");
+    addlistener (hg, "showarrowhead", @update_props);
+
+    addproperty ("color", hg, "linecolor", get (h1, "color"));
+    addproperty ("linewidth", hg, "linelinewidth", get (h1, "linewidth"));
+    addproperty ("linestyle", hg, "linelinestyle", get (h1, "linestyle"));
+    addproperty ("marker", hg, "linemarker", get (h3, "marker"));
+    addproperty ("markerfacecolor", hg, "linemarkerfacecolor",
+		 get (h3, "markerfacecolor"));
+    addproperty ("markersize", hg, "linemarkersize", get (h3, "markersize"));
+
+    addlistener (hg, "color", @update_props);
+    addlistener (hg, "linewidth", @update_props); 
+    addlistener (hg, "linestyle", @update_props); 
+    addlistener (hg, "marker", @update_props); 
+    addlistener (hg, "markerfacecolor", @update_props); 
+    addlistener (hg, "markersize", @update_props);
+
+    if (! isempty (args))
+      set (hg, args{:});
+    endif
+  unwind_protect_cleanup
+    set (h, "nextplot", hstate);
+  end_unwind_protect
+
+endfunction
+
+function update_data (h, d)
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+  z = get (h, "zdata");
+
+  u = get (h, "udata");
+  v = get (h, "vdata");
+  w = get (h, "wdata");
+
+  s = get (h, "autoscalefactor");
+  arrowsize = get (h, "maxheadsize");
+
+  kids = get (h, "children");
+
+  if (isempty (z) || isempty (w))
+    is3d = false;
+  else
+    is3d = true;
+  endif
+
+  if (strcmpi (get (h, "autoscale"), "on") && s != 0)
+    ## Scale the arrows to fit in the grid
+    dx = (max(x(:)) - min(x(:))) ./ size (x, 2);
+    dy = (max(y(:)) - min(y(:))) ./ size (y, 1);
+    if (is3d)
+      ## What should this be divided by? The below seems right
+      dz = (max(z(:)) - min(z(:))) ./ max (size (z));
+      len = max (sqrt (u(:).^2 + dy(:).^2) + dz(:).^2);
+    else
+      len = max (sqrt (u(:).^2 + dy(:).^2));
+      dz = 0;
+    endif
+    if (len > 0)
+      s = 2 * s / sqrt (2) * sqrt (dx.^2 + dy.^2 + dz.^2) / len; 
+      u = s * u;
+      v = s * v;
+      if (is3d)
+	w = s*w;
+      endif
+    endif
+  endif
+
+  x = x(:);
+  y = y(:);
+  xend = x + u(:);
+  yend = y + v(:);
+  if (is3d)
+    z = z(:);
+    zend = z + w(:);
+  endif
+
+  set (kids (3), "xdata", [x.'; xend.'; NaN(1, length (x))](:));
+  set (kids (3), "ydata", [y.'; yend.'; NaN(1, length (y))](:));
+  if (is3d)
+    set (kids (3), "zdata", [z.'; zend.'; NaN(1, length (z))](:));
+  endif
+
+  xtmp = x + u(:) .* (1 - arrowsize);
+  ytmp = y + v(:) .* (1 - arrowsize);
+  xarrw1 = xtmp + (y - yend) * arrowsize / 3;
+  xarrw2 = xtmp - (y - yend) * arrowsize / 3;
+  yarrw1 = ytmp - (x - xend) * arrowsize / 3;
+  yarrw2 = ytmp + (x - xend) * arrowsize / 3;
+  if (is3d)
+    zarrw1 = zarrw2 = zend - w(:) * arrowsize;
+  endif
+
+  set (kids (2), "xdata", [x.'; xend.'; NaN(1, length (x))](:));
+  set (kids (2), "ydata", [y.'; yend.'; NaN(1, length (y))](:));
+  if (is3d)
+    set (kids (2), "zdata", [z.'; zend.'; NaN(1, length (z))](:));
+  endif
+
+  set (kids (2), "xdata", [xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:));
+  set (kids (2), "ydata", [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:));
+  if (is3d)
+    set (kids (2), "zdata", [zarrw1.'; zend.'; zarrw2.'; NaN(1, length (z))](:));
+  endif
+
+  set (kids (1), "xdata", x);
+  set (kids (1), "ydata", y);
+  if (is3d)
+    set (kids (1), "zdata", z);
+  endif
+
+endfunction
+
+function update_props (h, d)
+  kids = get (h, "children");
+
+  set (kids(3), "color", get (h, "color"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"));
+  set (kids(2), "color", get (h, "color"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"));
+  if (strcmpi (get (h, "showarrowhead"), "on"))
+    set (kids (2), "visible", "on");
+  else
+    set (kids (2), "visible", "off");
+  endif
+  set (kids(1), "color", get (h, "color"), 
+       "marker", get (h, "marker"),
+       "markerfacecolor", get (h, "markerfacecolor"),
+       "markersize", get (h, "markersize"));
+endfunction
diff --git a/scripts/plot/__scatter__.m b/scripts/plot/__scatter__.m
new file mode 100644
index 0000000..e44a005
--- /dev/null
+++ b/scripts/plot/__scatter__.m
@@ -0,0 +1,246 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{hg} =} __scatter__ (@dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+function hg = __scatter__ (varargin)
+
+  h = varargin{1};
+  nd = varargin{2};
+  fcn = varargin{3};
+  x = varargin{4}(:);
+  y = varargin{5}(:);
+  istart = 6;
+
+  if (nd == 3)
+    z = varargin{6}(:);
+    idx = isnan(x) | isnan (y) | isnan (z);
+    x (idx) = [];
+    y (idx) = [];
+    z (idx) = [];
+    istart = 7;
+  else
+    idx = isnan(x) | isnan (y);
+    x (idx) = [];
+    y (idx) = [];
+    z = zeros (length (x), 0);
+  endif
+
+  firstnonnumeric = Inf;
+  for i = istart:nargin
+    if (! isnumeric (varargin{i}))
+      firstnonnumeric = i;
+      break;
+    endif
+  endfor
+
+  if (istart < nargin && firstnonnumeric > istart)
+    s = varargin{istart};
+    if (isempty (s))
+      s = 6;
+    endif
+  else
+    s = 6;
+  endif
+  if (numel (s) == 1)
+    ss = s;
+    s = repmat (s, numel(x), 1);
+  endif
+
+  if (istart < nargin && firstnonnumeric > istart + 1)
+    c = varargin{istart + 1};
+    if (isvector (c))
+      if (columns (c) == 3)
+	cc = c;
+	c = repmat (c, numel(x), 1);
+      else
+	c = c(:);
+      endif
+    elseif (isempty (c))
+      cc = __next_line_color__();
+      c = repmat (cc, numel(x), 1);
+    endif
+  elseif (firstnonnumeric == istart + 1 && ischar (varargin{istart + 1}))
+    c = varargin{istart + 1};
+    firstnonnumeric++;
+  else
+    cc = __next_line_color__();
+    c = repmat (cc, numel(x), 1);
+  endif
+
+  newargs = {};
+  filled = false;
+  have_marker = false;
+  marker = "o";
+  iarg = firstnonnumeric;
+  while (iarg <= nargin)
+    arg = varargin{iarg++};
+    if (ischar (arg) && strncmpi (arg, "filled", 6))
+      filled = true;
+    elseif ((ischar (arg) || iscell (arg)) && ! have_marker)
+      [linespec, valid] = __pltopt__ (fcn, arg, false);
+      if (valid)
+	have_marker = true;
+	marker = linespec.marker;
+	if (strncmp (marker, "none", 4))
+	  marker = "o";
+	endif
+      else
+	error ("%s: invalid linespec", fcn);
+      endif
+    else
+      newargs{end+1} = arg;
+      if (iarg <= nargin)
+	newargs{end+1} = varagin{iarg++};
+      endif
+    endif
+  endwhile
+
+  hg = hggroup ();
+  newargs = __add_datasource__ (fcn, hg, {"x", "y", "z", "c", "size"}, 
+			     newargs{:});
+
+  addproperty ("xdata", hg, "data", x);
+  addproperty ("ydata", hg, "data", y);
+  addproperty ("zdata", hg, "data", z);
+  if (exist ("cc", "var"))
+    addproperty ("cdata", hg, "data", cc);
+  else
+    addproperty ("cdata", hg, "data", c);
+  endif
+  if (exist ("ss", "var"))
+    addproperty ("sizedata", hg, "data", ss);
+  else
+    addproperty ("sizedata", hg, "data", s);
+  endif
+  addlistener (hg, "xdata", @update_data);
+  addlistener (hg, "ydata", @update_data);
+  addlistener (hg, "zdata", @update_data);
+  addlistener (hg, "cdata", @update_data);
+  addlistener (hg, "sizedata", @update_data);
+
+  if (ischar (c))
+    for i = 1 : numel (x)
+      h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+			"faces", 1, "vertices", [x(i), y(i), z(i,:)], 
+			"facecolor", "none", "edgecolor", c, "marker", marker, 
+			"markersize", s(i), "linestyle", "none");
+      if (filled)
+	set(h, "markerfacecolor", c); 
+      endif
+    endfor
+  else
+    for i = 1 : numel (x)
+      h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+			"faces", 1, "vertices", [x(i), y(i), z(i,:)], 
+			"facecolor", "none", "edgecolor", "flat", 
+			"cdata", reshape(c(i,:),[1,size(c)(2:end)]), 
+			"marker", marker, "markersize", s(i), 
+			"linestyle", "none");
+      if (filled)
+	set(h, "markerfacecolor", "flat"); 
+      endif
+    endfor
+    ax = get (hg, "parent");
+    clim = get (ax, "clim");
+    if (min(c(:)) < clim(1))
+      clim(1) = min(c(:));
+      set (ax, "clim", clim);
+    endif
+    if (max(c(:)) > clim(2))
+      set (ax, "clim", [clim(1), max(c(:))]);
+    endif
+  endif
+
+  addproperty ("linewidth", hg, "patchlinewidth", 0.5);
+  addproperty ("marker", hg, "patchmarker", marker);
+  if (numel (x) > 0)
+    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", "none");
+    addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", "none");
+  else
+    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", 
+		 get (h, "markerfacecolor"));
+    addproperty ("markeredgecolor", hg, "patchmarkeredgecolor",
+		 get (h, "edgecolor"));
+  endif
+  addlistener (hg, "linewidth", @update_props); 
+  addlistener (hg, "marker", @update_props); 
+  addlistener (hg, "markerfacecolor", @update_props); 
+  addlistener (hg, "markeredgecolor", @update_props);
+
+  if (! isempty (newargs))
+    set (hg, newargs{:})
+  endif
+
+endfunction
+
+function update_props (h, d)
+  lw = get (h, "linewidth");
+  m = get (h, "marker");
+  fc = get (h, "markerfacecolor");
+  ec = get (h, "markeredgecolor");
+  kids = get (h, "children");
+
+  for i = 1 : numel (kids)
+    set (kids (i), "linewidth", lw, "marker", m, "markerfacecolor", fc, 
+	 "edgecolor", ec)
+  endfor
+endfunction
+
+function update_data (h, d)
+  x1 = get (h, "xdata");
+  y1 = get (h, "ydata");
+  z1 = get (h, "zdata");
+  c1 = get (h, "cdata");
+  if (!ischar (c1) && rows (c1) == 1)
+    c1 = repmat (c1, numel (x1), 1);
+  endif
+  size1 = get (h, "sizedata");
+  if (numel (size1) == 1)
+    size1 = repmat (size1, numel (x1), 1);
+  endif
+  hlist = get (h, "children");
+  if (ischar (c1))
+    if (isempty (z1))
+      for i = 1 : length (hlist)
+	set (hlist(i), "vertices", [x1(i), y1(i)], "cdata", c1,
+	     "markersize", size1(i));
+      endfor
+    else
+      for i = 1 : length (hlist)
+	set (hlist(i), "vertices", [x1(i), y1(i), z1(i)], "cdata", c1,
+	     "markersize", size1(i));
+      endfor
+    endif
+  else
+    if (isempty (z1))
+      for i = 1 : length (hlist)
+	set (hlist(i), "vertices", [x1(i), y1(i)], "cdata", 
+	     reshape(c1(i,:),[1, size(c1)(2:end)]), "markersize", size1(i));
+      endfor
+    else
+      for i = 1 : length (hlist)
+	set (hlist(i), "vertices", [x1(i), y1(i), z1(i)], "cdata", 
+	     reshape(c1(i,:),[1, size(c1)(2:end)]), "markersize", size1(i));
+      endfor
+    endif
+  endif
+endfunction
diff --git a/scripts/plot/__stem__.m b/scripts/plot/__stem__.m
new file mode 100644
index 0000000..df2eed4
--- /dev/null
+++ b/scripts/plot/__stem__.m
@@ -0,0 +1,553 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Michel D. Schmid
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} __stem__ (@var{have_z}, @var{varargin})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: Michel D. Schmid <michaelschmid at users.sourceforge.net>
+## Adapted-by: jwe
+
+function h = __stem__ (have_z, varargin)
+
+  if (have_z)
+    caller = "stem3";
+  else
+    caller = "stem";
+  endif
+
+  [ax, varargin, nargin] = __plt_get_axis_arg__ (caller, varargin{:});
+
+  [x, y, z, dofill, llc, ls, mmc, ms, varargin] = ...
+      check_stem_arg (have_z, varargin{:});
+
+  oldax = gca ();
+  unwind_protect
+    axes (ax);
+    hold_state = get (ax, "nextplot");
+    newplot ();
+    h = [];
+
+    nx = rows (x);
+    for i = 1: columns (x)
+      if (have_z)
+	xt = x(:)';
+	xt = [xt; xt; NaN(1, nx)](:);
+	yt = y(:)';
+	yt = [yt; yt; NaN(1, nx)](:);
+	zt = z(:)';
+	zt = [zeros(1, nx); zt; NaN(1, nx)](:);
+      else
+	xt = x(:, i)';
+	xt = [xt; xt; NaN(1, nx)](:);
+	yt = y(:, i)';
+	yt = [zeros(1, nx); yt; NaN(1, nx)](:);
+      endif
+
+      hg  = hggroup ();
+      h = [h; hg];
+      args = __add_datasource__ (caller, hg, {"x", "y", "z"}, varargin{:});
+      
+      if (i == 1)
+	set (ax, "nextplot", "add");
+      endif
+
+      if (isempty (llc))
+	lc = __next_line_color__ ();
+      else
+	lc = llc;
+      endif
+
+      if (isempty (mmc))
+	mc = lc;
+      else
+	mc = mmc;
+      endif
+
+      if (dofill)
+	fc = mc;
+      else
+	fc = "none";
+      endif
+
+      if (have_z)
+	h_stems = plot3 (xt, yt, zt, "color", lc, "linestyle", ls, 
+			 "parent", hg, x, y, z, "color", mc,
+			 "marker",  ms, "linestyle", "none",
+			 "markerfacecolor", fc, "parent", hg);
+
+	h_baseline = [];
+      else
+	h_stems = plot (xt, yt, "color", lc, "linestyle", ls,
+			"parent", hg, x(:,i), y(:, i), "color", mc, "marker",
+			ms, "linestyle", "none", "markerfacecolor",
+			fc, "parent", hg); 
+
+	if (i == 1)
+	  x_axis_range = get (ax, "xlim");
+	  h_baseline = line (x_axis_range, [0, 0], "color", [0, 0, 0]);
+	  set (h_baseline, "handlevisibility", "off");
+	  set (h_baseline, "xliminclude", "off");
+	  addlistener (ax, "xlim", @update_xlim);
+	  addlistener (h_baseline, "ydata", @update_baseline);
+	  addlistener (h_baseline, "visible", @update_baseline);
+	endif
+      endif
+
+      ## Setup the hggroup and listeners.
+      addproperty ("showbaseline", hg, "radio", "{on}|off");
+      addproperty ("basevalue", hg, "data", 0);
+      addproperty ("baseline", hg, "data", h_baseline);
+
+      if (!have_z)
+	addlistener (hg, "showbaseline", @show_baseline);
+	addlistener (hg, "basevalue", @move_baseline); 
+      endif
+
+      addproperty ("color", hg, "linecolor", lc);
+      addproperty ("linewidth", hg, "linelinewidth", 0.5);
+      addproperty ("linestyle", hg, "linelinestyle", ls);
+      addproperty ("marker", hg, "linemarker", ms);
+      addproperty ("markerfacecolor", hg, "linemarkerfacecolor", fc);
+      addproperty ("markersize", hg, "linemarkersize", 6);
+
+      addlistener (hg, "color", @update_props);
+      addlistener (hg, "linewidth", @update_props); 
+      addlistener (hg, "linestyle", @update_props); 
+      addlistener (hg, "marker", @update_props); 
+      addlistener (hg, "markerfacecolor", @update_props); 
+      addlistener (hg, "markersize", @update_props);
+
+      addproperty ("xdata", hg, "data", x(:, i));
+      addproperty ("ydata", hg, "data", y(:, i));
+      if (have_z)
+	addproperty ("zdata", hg, "data", z(:, i));
+      else
+	addproperty ("zdata", hg, "data", []);
+      endif
+
+      addlistener (hg, "xdata", @update_data);
+      addlistener (hg, "ydata", @update_data);
+      addlistener (hg, "zdata", @update_data);
+
+      if (! isempty (args))
+	set (hg, args{:});
+      endif
+      if (i == 1 && !isempty(h_baseline))
+	set (h_baseline, "parent", get (hg, "parent"));
+      endif
+    endfor
+
+  unwind_protect_cleanup
+    set (ax, "nextplot", hold_state);
+    axes (oldax);
+  end_unwind_protect
+endfunction
+
+function [x, y, z, dofill, lc, ls, mc, ms, newargs] = check_stem_arg (have_z, varargin)
+
+  ## FIXME -- there seems to be a lot of duplicated code in this
+  ## function.  It seems like it should be possible to simplify things
+  ## by combining some of the nearly identical code sections into
+  ## additional subfunctions.
+
+  if (have_z)
+    caller = "stem3";
+  else
+    caller = "stem";
+  endif
+
+  ## Remove prop/val pairs from data to consider.
+  i = 2;
+  newargs = {};
+  while (i < length (varargin))
+    if (ischar (varargin{i}) && !(strcmpi ("fill", varargin{i})
+				  || strcmpi ("filled", varargin{i})))
+      newargs{end + 1} = varargin{i};
+      newargs{end + 1} = varargin{i + 1};
+      nargin = nargin - 2;
+      varargin(i:i+1) = [];
+    else
+      i++;
+    endif
+  endwhile
+
+  ## set specifiers to default values.
+  [lc, ls, mc, ms] = set_default_values ();
+  dofill = 0;
+  fill_2 = 0;
+  linespec_2 = 0;
+  z = [];
+
+  ## Check input arguments.
+  if (nargin == 2)
+    if (have_z)
+      z = varargin{1};
+      x = 1:rows (z);
+      y = 1:columns (z);
+    else
+      y = varargin{1};
+      if (isvector (y))
+	x = 1:length (y);
+      elseif (ismatrix (y))
+	x = 1:rows (y);
+      else 
+	error ("stem: Y must be a matrix");
+      endif # in each case, x & y will be defined
+    endif
+  elseif (nargin == 3)
+    ## Several possibilities
+    ##
+    ## 1. the real y data
+    ## 2. 'filled'
+    ## 3. line spec
+    if (ischar (varargin{2}))
+      ## Only 2. or 3. possible.
+      if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2}))
+	dofill = 1;
+      else
+	## Parse the linespec.
+	[lc, ls, mc, ms] = stem_line_spec (caller, varargin{2});
+      endif
+      if (have_z)
+	z = varargin{1};
+	x = 1:rows (z);
+	y = 1:columns (z);
+      else
+	y = varargin{1};
+	if (isvector (y))
+	  x = 1:length (y);
+	elseif (ismatrix (y))
+	  x = 1:rows (y);
+	else
+	  error ("stem: Y must be a matrix");
+	endif # in each case, x & y will be defined
+      endif
+    else
+      if (have_z)
+	error ("stem3: must define X, Y and Z");
+      else
+	## Must be the real y data.
+	x = varargin{1};
+	y = varargin{2};
+	if (! (ismatrix (x) && ismatrix (y)))
+	  error ("stem: X and Y must be matrices");
+	endif
+      endif
+    endif
+  elseif (nargin == 4)
+    ## Again, several possibilities:
+    ##
+    ## arg2 1. real y
+    ## arg2 2. 'filled' or linespec
+    ## arg3 1. real z
+    ## arg3 2. 'filled' or linespec
+    if (ischar (varargin{2}))
+      ## Only arg2 2. / arg3 1. & arg3 3. are possible.
+      if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2}))
+	dofill = 1;
+	fill_2 = 1; # Be sure, no second "fill" is in the arguments.
+      else
+	## Must be a linespec.
+	[lc, ls, mc, ms] = stem_line_spec (caller, varargin{2});
+	linespec_2 = 1;
+      endif
+      if (have_z)
+	z = varargin{1};
+	x = 1:rows (z);
+	y = 1:columns (z);
+      else
+	y = varargin{1};
+	if (isvector (y))
+	  x = 1:length (y);
+	elseif (ismatrix (y))
+	  x = 1:rows (y);
+	else
+	  error ("stem: Y must be a matrix");
+	endif # in each case, x & y will be defined
+      endif
+    else
+      if (have_z)
+	x = varargin{1};
+	y = varargin{2};
+	z = varargin{3};
+	if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
+	  error ("stem3: X, Y and Z must be matrices");
+	endif
+      else
+	## must be the real y data.
+	x = varargin{1};
+	y = varargin{2};
+	if (! (ismatrix (x) && ismatrix (y)))
+	  error ("stem: X and Y must be matrices");
+	endif
+      endif
+    endif # if ischar(varargin{2})
+    if (! have_z)
+      ## varargin{3} must be char.
+      ## Check for "fill.
+      if ((strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled"))
+	  && fill_2)
+	error ("stem: duplicate fill argument");
+      elseif (strcmpi ("fill", varargin{3}) && linespec_2)
+	## Must be "fill".
+	dofill = 1;
+	fill_2 = 1;
+      elseif ((strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled"))
+	  && !linespec_2)
+	## Must be "fill".
+	dofill = 1;
+	fill_2 = 1;
+      elseif (! linespec_2)
+	## Must be linespec.
+	[lc, ls, mc, ms] = stem_line_spec (caller, varargin{3});
+	linespec_2 = 1;
+      endif
+    endif
+  elseif (nargin == 5)
+    if (have_z)
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+      if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
+	error ("stem3: X, Y and Z must be matrices");
+      endif
+    else
+      x = varargin{1};
+      y = varargin{2};
+      if (! (ismatrix (x) && ismatrix (y)))
+	error ("stem: X and Y must be matrices");
+      endif
+    endif
+
+    if (! have_z)
+      if (strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled"))
+	dofill = 1;
+	fill_2 = 1; # Be sure, no second "fill" is in the arguments.
+      else
+	## Must be a linespec.
+	[lc, ls, mc, ms] = stem_line_spec (caller, varargin{3});
+	linespec_2 = 1;
+      endif
+    endif
+
+    ## Check for "fill".
+    if ((strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled"))
+	&& fill_2)
+      error ("%s: duplicate fill argument", caller);
+    elseif ((strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled"))
+	&& linespec_2)
+      ## Must be "fill".
+      dofill = 1;
+      fill_2 = 1;
+    elseif (!strcmpi (varargin{4}, "fill") && !strcmpi (varargin{4}, "filled")
+	&& !linespec_2)
+      ## Must be linespec.
+      [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4});
+      linespec_2 = 1;
+    endif
+  elseif (nargin == 6 && have_z)
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
+      error ("stem3: X, Y and Z must be matrices");
+    endif
+
+    if (strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled"))
+      dofill = 1;
+      fill_2 = 1; # be sure, no second "fill" is in the arguments
+    else
+      ## Must be a linespec.
+      [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4});
+      linespec_2 = 1;
+    endif
+
+    ## check for "fill" ..
+    if ((strcmpi (varargin{5}, "fill") || strcmpi (varargin{5}, "filled"))
+	&& fill_2)
+      error ("stem3: duplicate fill argument");
+    elseif ((strcmpi (varargin{5}, "fill") || strcmpi (varargin{5}, "filled"))
+	&& linespec_2)
+      ## Must be "fill".
+      dofill = 1;
+      fill_2 = 1;
+    elseif (!strcmpi (varargin{5}, "fill") && !strcmpi (varargin{5}, "filled")
+	    && !linespec_2)
+      ## Must be linespec.
+      [lc, ls, mc, ms] = stem_line_spec (caller, varargin{5});
+      linespec_2 = 1;
+    endif
+  else
+    error ("%s: incorrect number of arguments", caller);
+  endif
+
+  ## Check sizes of x, y and z.
+  if (have_z)
+    if (!size_equal (x, y, z))
+      error ("stem3: inconsistent size of x, y and z");
+    else
+      x = x(:);
+      y = y(:);
+      z = z(:);
+    endif
+  else
+    if (isvector (x))
+      x = x(:);
+      if (isvector (y))
+	if (length (x) != length (y))
+	  error ("stem: inconsistent size of x and y");
+	else
+	  y = y(:);
+	endif
+      else
+	if (length (x) == rows (y))
+	  x = repmat (x(:), 1, columns (y));
+	else
+	  error ("stem: inconsistent size of x and y");
+	endif
+      endif
+    elseif (!size_equal (x, y))
+      error ("stem: inconsistent size of x and y");
+    endif
+  endif
+
+endfunction
+
+function [lc, ls, mc, ms] = stem_line_spec (caller, str)
+  if (! ischar (str))
+    error ("%s: expecting argument to be \"fill\" or a string of specifiers",
+	   caller);
+  endif
+  [lc, ls, mc, ms] = set_default_values ();
+  ## Parse the line specifier string.
+  cur_props = __pltopt__ ("stem", str, false);
+  for i = 1:length(cur_props)
+    if (isfield (cur_props(i), "color") && ! isempty (cur_props(i).color)); # means line color
+      mc = lc = cur_props(i).color;
+    elseif (isfield (cur_props(i), "linestyle"))
+      ls = cur_props(i).linestyle;
+    elseif (isfield (cur_props(i), "marker") && ! strcmpi (cur_props(i).marker, "none"))
+      ms = cur_props(i).marker;
+    endif
+  endfor
+endfunction
+
+function [lc, ls, mc, ms] = set_default_values ()
+  ## set default values
+  mc = [];
+  lc = [];
+  ls = "-";
+  ms = "o";
+endfunction
+
+function update_xlim (h, d)
+  kids = get (h, "children");
+  xlim = get (h, "xlim");
+
+  for i = 1 : length (kids)
+    obj = get (kids (i));
+    if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline"))
+      if (any (get (obj.baseline, "xdata") != xlim))
+	set (obj.baseline, "xdata", xlim);
+      endif
+    endif
+  endfor
+endfunction
+
+function update_baseline (h, d)
+  visible = get (h, "visible");
+  ydata = get (h, "ydata")(1);
+
+  kids = get (get (h, "parent"), "children");
+  for i = 1 : length (kids)
+    obj = get (kids (i));
+    if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline") 
+	&& obj.baseline == h)
+      ## Only alter if changed to avoid recursion of the listener functions
+      if (! strcmpi (get (kids(i), "showbaseline"), visible))
+	set (kids (i), "showbaseline", visible);
+      endif
+      if (! strcmpi (get (kids(i), "basevalue"), visible))
+	set (kids (i), "basevalue", ydata);
+      endif
+    endif
+  endfor
+endfunction
+
+function show_baseline (h, d)
+  set (get (h, "baseline"), "visible", get (h, "showbaseline"));
+endfunction
+
+function move_baseline (h, d)
+  b0 = get (h, "basevalue");
+  bl = get (h, "baseline");
+
+  if (get (bl, "ydata") != [b0, b0])
+    set (bl, "ydata", [b0, b0]);
+  endif
+
+  kids = get (h, "children");
+  yt = get(h, "ydata")(:)';
+  ny = length (yt);
+  yt = [b0 * ones(1, ny); yt; NaN(1, ny)](:);
+  set (kids(2), "ydata", yt);
+endfunction
+
+function update_props (h, d)
+  kids = get (h, "children");
+  set (kids(2), "color", get (h, "color"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"));
+  set (kids(1), "color", get (h, "color"), 
+       "marker", get (h, "marker"),
+       "markerfacecolor", get (h, "markerfacecolor"),
+       "markersize", get (h, "markersize"));
+endfunction
+
+function update_data (h, d)
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+  z = get (h, "zdata");
+
+  if (!isempty (z) && size_equal (x, y, z))
+    error ("stem3: inconsistent size of x, y and z");
+  elseif (numel(x) != numel (y))
+    error ("stem: inconsistent size of x and y");
+  else
+    bl = get (h, "basevalue");
+    nx = numel (x);
+    x = x(:)';
+    xt = [x; x; NaN(1, nx)](:);
+    if (! isempty (z))
+      y = y(:)';
+      yt = [y; y; NaN(1, nx)](:);
+      z = z(:)';
+      zt = [bl * ones(1, nx); z; NaN(1, nx)](:);
+    else
+      y = y(:)';
+      yt = [bl * ones(1, nx); y; NaN(1, nx)](:);
+      zt = [];
+    endif
+
+    kids = get (h, "children");
+    set (kids(2), "xdata", xt, "ydata", yt, "zdata", zt)
+    set (kids(1), "xdata", x, "ydata", y, "zdata", z)
+  endif
+endfunction
diff --git a/scripts/plot/allchild.m b/scripts/plot/allchild.m
new file mode 100644
index 0000000..df3f323
--- /dev/null
+++ b/scripts/plot/allchild.m
@@ -0,0 +1,50 @@
+## Copyright (C) 2008 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} allchild (@var{handles})
+## Find all children, including hidden children, of a graphics object.
+##
+## This function is similar to @code{get (h, "children")}, but also
+## returns includes hidden objects.  If @var{handles} is a scalar,
+## @var{h} will be a vector.  Otherwise, @var{h} will be a cell matrix
+## of the same size as @var{handles} and each cell will contain a
+## vector of handles.
+## @seealso{get, set, findall, findobj}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function h = allchild (ha)
+
+  shh = get (0, "showhiddenhandles");
+  unwind_protect
+    set (0, "showhiddenhandles", "on");
+    if (isscalar (ha))
+      h = get (ha, "children");
+    else
+      h = cell (size (ha));
+      for i = 1:numel (ha)
+        h{i} = get (ha, "children");
+      endfor
+    endif
+  unwind_protect_cleanup
+    set (0, "showhiddenhandles", shh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/ancestor.m b/scripts/plot/ancestor.m
new file mode 100644
index 0000000..960b1c3
--- /dev/null
+++ b/scripts/plot/ancestor.m
@@ -0,0 +1,70 @@
+## Copyright (C) 2007, 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{parent} =} ancestor (@var{h}, @var{type})
+## @deftypefnx {Function File} {@var{parent} =} ancestor (@var{h}, @var{type}, 'toplevel')
+## Return the first ancestor of handle object @var{h} whose type matches
+## @var{type}, where @var{type} is a character string.  If @var{type} is a
+## cell array of strings, return the first parent whose type matches
+## any of the given type strings.
+##
+## If the handle object @var{h} is of type @var{type}, return @var{h}.
+##
+## If @code{"toplevel"} is given as a 3rd argument, return the highest
+## parent in the object hierarchy that matches the condition, instead
+## of the first (nearest) one.
+## @seealso{get, set}
+## @end deftypefn
+
+function p = ancestor (h, type, toplevel)
+
+  if (nargin == 2 || nargin == 3)
+    p = [];
+    if (ischar (type))
+      type = { type };
+    endif
+    if (iscellstr (type))
+      look_first = true;
+      if (nargin == 3)
+        if (ischar (toplevel) && strcmpi (toplevel, "toplevel"))
+          look_first = false;
+        else
+          error ("ancestor: third argument must be \"toplevel\"");
+        endif
+      endif
+      while (true)
+        if (isempty (h) || ! ishandle (h))
+          break;
+        endif
+        if (any (strcmpi (get (h, "type"), type)))
+          p = h;
+          if (look_first)
+            break;
+          endif
+        endif
+		h = get (h, "Parent");
+      endwhile
+    else
+      error ("ancestor: second argument must be a string or cell array of strings");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/area.m b/scripts/plot/area.m
new file mode 100644
index 0000000..fdede19
--- /dev/null
+++ b/scripts/plot/area.m
@@ -0,0 +1,100 @@
+## Copyright (C) 2007, 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} area (@var{x}, @var{y})
+## @deftypefnx {Function File} {} area (@var{x}, @var{y}, @var{lvl})
+## @deftypefnx {Function File} {} area (@dots{}, @var{prop}, @var{val}, @dots{})
+## @deftypefnx {Function File} {} area (@var{y}, @dots{})
+## @deftypefnx {Function File} {} area (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} area (@dots{})
+## Area plot of cumulative sum of the columns of @var{y}.  This shows the
+## contributions of a value to a sum, and is functionally similar to 
+## @code{plot (@var{x}, cumsum (@var{y}, 2))}, except that the area under 
+## the curve is shaded.
+##
+## If the @var{x} argument is omitted it is assumed to be given by
+## @code{1 : rows (@var{y})}.  A value @var{lvl} can be defined that determines
+## where the base level of the shading under the curve should be defined.
+##
+## Additional arguments to the @code{area} function are passed to the 
+## @code{patch}.  The optional return value @var{h} provides a handle to 
+## area series object representing the patches of the areas.
+## @seealso{plot, patch}
+## @end deftypefn
+
+function h = area (varargin)
+
+  [ax, varargin, nargin] = __plt_get_axis_arg__ ("area", varargin{:});
+
+  if (nargin > 0)
+    idx = 1;
+    x = y = [];
+    bv = 0;
+    args = {};
+    ## Check for (X) or (X,Y) arguments and possible base value.
+    if (nargin >= idx && ismatrix (varargin{idx}))
+      y = varargin{idx};
+      idx++;
+      if (nargin >= idx)
+        if (isscalar (varargin{idx}))
+          bv = varargin{idx};
+          idx++;
+        elseif (ismatrix (varargin{idx}))
+          x = y;
+          y = varargin{idx};
+          idx++;
+          if (nargin >= idx && isscalar (varargin{idx}))
+            bv = varargin{idx};
+            idx++;
+          endif
+        endif
+      endif
+    else
+      print_usage ();
+    endif
+    ## Check for additional args.
+    if (nargin >= idx)
+      args = {varargin{idx:end}};
+    endif
+    newplot ();
+    if (isvector (y))
+      y = y(:);
+    endif
+    if (isempty (x))
+      x = repmat ([1:size(y, 1)]', 1, size (y, 2));
+    elseif (isvector (x))
+      x = repmat (x(:),  1, size (y, 2));
+    endif
+
+    oldax = gca ();
+    unwind_protect
+      axes (ax);
+      tmp = __area__ (ax, x, y, bv, args{:});
+    unwind_protect_cleanup
+      axes (oldax);
+    end_unwind_protect
+
+    if (nargout > 0)
+      h = tmp;
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/axes.m b/scripts/plot/axes.m
new file mode 100644
index 0000000..1447093
--- /dev/null
+++ b/scripts/plot/axes.m
@@ -0,0 +1,60 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} axes ()
+## @deftypefnx {Function File} {} axes (@var{property}, @var{value}, @dots{})
+## @deftypefnx {Function File} {} axes (@var{h})
+## Create an axes object and return a handle to it.
+## @end deftypefn
+
+## Author: jwe
+
+function h = axes (varargin)
+
+  if (nargin == 0 || nargin > 1)
+    ## make default axes object, and make it the current axes for the
+    ## current figure.
+    idx = find (strcmpi (varargin(1:2:end), "parent"), 1, "first");
+    if (! isempty (idx) && length (varargin) >= 2*idx)
+      cf = varargin{2*idx};
+      varargin([2*idx-1, 2*idx]) = [];
+    else
+      cf = gcf ();
+    endif
+    tmp = __go_axes__ (cf, varargin{:});
+    set (ancestor (cf, "figure"), "currentaxes", tmp);
+  else
+    ## arg is axes handle, make it the current axes for the current
+    ## figure.
+    tmp = varargin{1};
+    if (length(tmp) == 1 && ishandle (tmp)
+	&& strcmp (get (tmp, "type"), "axes"))
+      parent = ancestor (tmp, "figure");
+      set (0, "currentfigure", parent);
+      set (parent, "currentaxes", tmp);
+    else
+      error ("axes: expecting argument to be a scalar axes handle");
+    endif
+  endif
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/axis.m b/scripts/plot/axis.m
new file mode 100644
index 0000000..623ed42
--- /dev/null
+++ b/scripts/plot/axis.m
@@ -0,0 +1,461 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} axis (@var{limits})
+## Set axis limits for plots.
+##
+## The argument @var{limits} should be a 2, 4, or 6 element vector.  The
+## first and second elements specify the lower and upper limits for the x
+## axis.  The third and fourth specify the limits for the y-axis, and the
+## fifth and sixth specify the limits for the z-axis.
+##
+## Without any arguments, @code{axis} turns autoscaling on.  
+##
+## With one output argument, @code{x = axis} returns the current axes 
+##
+## The vector argument specifying limits is optional, and additional
+## string arguments may be used to specify various axis properties.  For
+## example,
+##
+## @example
+## axis ([1, 2, 3, 4], "square");
+## @end example
+##
+## @noindent
+## forces a square aspect ratio, and
+##
+## @example
+## axis ("labely", "tic");
+## @end example
+##
+## @noindent
+## turns tic marks on for all axes and tic mark labels on for the y-axis
+## only.
+##
+## @noindent
+## The following options control the aspect ratio of the axes.
+##
+## @table @code
+## @item "square"
+## Force a square aspect ratio.
+## @item "equal"
+## Force x distance to equal y-distance.
+## @item "normal"
+## Restore the balance.
+## @end table
+##
+## @noindent
+## The following options control the way axis limits are interpreted.
+##
+## @table @code
+## @item "auto" 
+## Set the specified axes to have nice limits around the data
+## or all if no axes are specified.
+## @item "manual" 
+## Fix the current axes limits.
+## @item "tight"
+## Fix axes to the limits of the data.
+## @end table
+##
+## @noindent
+## The option @code{"image"} is equivalent to @code{"tight"} and
+## @code{"equal"}.
+##
+## @noindent
+## The following options affect the appearance of tic marks.
+##
+## @table @code
+## @item "on" 
+## Turn tic marks and labels on for all axes.
+## @item "off"
+## Turn tic marks off for all axes.
+## @item "tic[xyz]"
+## Turn tic marks on for all axes, or turn them on for the
+## specified axes and off for the remainder.
+## @item "label[xyz]"
+## Turn tic labels on for all axes, or turn them on for the 
+## specified axes and off for the remainder.
+## @item "nolabel"
+## Turn tic labels off for all axes.
+## @end table
+## Note, if there are no tic marks for an axis, there can be no labels.
+##
+## @noindent
+## The following options affect the direction of increasing values on
+## the axes.
+##
+## @table @code
+## @item "ij"
+## Reverse y-axis, so lower values are nearer the top.
+## @item "xy" 
+## Restore y-axis, so higher values are nearer the top. 
+## @end table
+## 
+## If an axes handle is passed as the first argument, then operate on
+## this axes rather than the current axes.
+## @end deftypefn
+
+## Author: jwe
+
+function varargout = axis (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    varargout = cell (max (nargin == 0, nargout), 1);
+    if (isempty (varargout))
+      __axis__ (h, varargin{:});
+    else
+      [varargout{:}] = __axis__ (h, varargin{:});
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
+
+function curr_axis = __axis__ (ca, ax, varargin)
+
+  if (nargin == 1)
+    if (nargout == 0)
+      set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
+    else
+      xlim = get (ca, "xlim");
+      ylim = get (ca, "ylim");
+      zlim = get (ca, "zlim");
+      curr_axis = [xlim, ylim, zlim];
+    endif
+
+  elseif (ischar (ax))
+    len = length (ax);
+
+    ## 'matrix mode' to reverse the y-axis
+    if (strcmpi (ax, "ij"))
+      set (ca, "ydir", "reverse");
+    elseif (strcmpi (ax, "xy"))
+      set (ca, "ydir", "normal");
+
+      ## aspect ratio
+    elseif (strcmpi (ax, "image"))
+      __axis__ (ca, "equal")
+      __do_tight_option__ (ca);
+    elseif (strcmpi (ax, "square"))
+      if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
+        set (ca, "dataaspectratio", [1, 1, 1]);
+      else
+        x = xlim;
+        y = ylim;
+        set (ca, "dataaspectratio", [(y(2)-y(1)), (x(2)-x(1)), 1]);
+      endif
+    elseif  (strcmp (ax, "equal"))
+      if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
+        x = xlim;
+        y = ylim;
+        set (ca, "dataaspectratio", [(x(2)-x(1)), (y(2)-y(1)), 1]);
+      else
+        set (ca, "dataaspectratio", [1, 1, 1]);
+      endif
+    elseif (strcmpi (ax, "normal"))
+      set (ca, "dataaspectratiomode", "auto");
+
+      ## axis limits
+    elseif (len >= 4 && strcmpi (ax(1:4), "auto"))
+      if (len > 4)
+	if (any (ax == "x"))
+	  set (ca, "xlimmode", "auto");
+	endif
+	if (any (ax == "y"))
+	  set (ca, "ylimmode", "auto");
+	endif
+	if (any (ax == "z"))
+	  set (ca, "zlimmode", "auto");
+	endif
+      else
+	set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
+      endif
+    elseif (strcmpi (ax, "manual"))
+      ## fixes the axis limits, like axis(axis) should;
+      set (ca, "xlimmode", "manual", "ylimmode", "manual", "zlimmode", "manual");
+    elseif (strcmpi (ax, "tight"))
+      ## sets the axis limits to the min and max of all data.
+      __do_tight_option__ (ca);
+      ## tic marks
+    elseif (strcmpi (ax, "on") || strcmpi (ax, "tic"))
+      set (ca, "xtickmode", "auto", "ytickmode", "auto", "ztickmode", "auto");
+      if (strcmpi (ax, "on"))
+        set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto",
+	   "zticklabelmode", "auto");
+      endif
+      set (ca, "visible", "on");
+    elseif (strcmpi (ax, "off"))
+      set (ca, "xtick", [], "ytick", [], "ztick", []);
+      set (ca, "visible", "off");
+    elseif (len > 3 && strcmpi (ax(1:3), "tic"))
+      if (any (ax == "x"))
+	set (ca, "xtickmode", "auto");
+      else
+	set (ca, "xtick", []);
+      endif
+      if (any (ax == "y"))
+	set (ca, "ytickmode", "auto");
+      else
+	set (ca, "ytick", []);
+      endif
+      if (any (ax == "z"))
+	set (ca, "ztickmode", "auto");
+      else
+	set (ca, "ztick", []);
+      endif
+    elseif (strcmpi (ax, "label"))
+      set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto",
+	   "zticklabelmode", "auto");
+    elseif (strcmpi (ax, "nolabel"))
+      set (ca, "xticklabel", "", "yticklabel", "", "zticklabel", "");
+    elseif (len > 5 && strcmpi (ax(1:5), "label"))
+      if (any (ax == "x"))
+	set (ca, "xticklabelmode", "auto");
+      else
+	set (ca, "xticklabel", "");
+      endif
+      if (any (ax == "y"))
+	set (ca, "yticklabelmode", "auto");
+      else
+	set (ca, "yticklabel", "");
+      endif
+      if (any (ax == "z"))
+	set (ca, "zticklabelmode", "auto");
+      else
+	set (ca, "zticklabel", "");
+      endif
+
+    else
+      warning ("unknown axis option '%s'", ax);
+    endif
+
+  elseif (isvector (ax))
+
+    len = length (ax);
+
+    if (len != 2 && len != 4 && len != 6)
+      error ("axis: expecting vector with 2, 4, or 6 elements");
+    endif
+
+    for i = 1:2:len
+      if (ax(i) == ax(i+1))
+	error ("axis: limits(%d) cannot equal limits(%d)", i, i+1);
+      endif
+    endfor
+
+    if (len > 1)
+      set (ca, "xlim", [ax(1), ax(2)]);
+    endif
+
+    if (len > 3)
+      set (ca, "ylim", [ax(3), ax(4)]);
+    endif
+
+    if (len > 5)
+      set (ca, "zlim", [ax(5), ax(6)]);
+    endif
+
+  else
+    error ("axis: expecting no args, or a vector with 2, 4, or 6 elements");
+  endif
+
+  if (! isempty (varargin))
+    __axis__ (ca, varargin{:});
+  endif
+
+endfunction
+
+function lims = __get_tight_lims__ (ca, ax)
+
+  ## Get the limits for axis ("tight").
+  ## AX should be one of "x", "y", or "z".
+  kids = findobj (ca, "-property", strcat (ax, "data"));
+  if (isempty (kids))
+    ## Return the current limits.
+    lims = get (ca, strcat (ax, "lim"));
+  else
+    data = get (kids, strcat (ax, "data"));
+    if (iscell (data))
+      data = data (find (! cellfun (@isempty, data)));
+      if (! isempty (data))
+        lims_min = min (cellfun (@min, cellfun (@min, data, 'UniformOutput', false)(:))); 
+        lims_max = max (cellfun (@max, cellfun (@max, data, 'UniformOutput', false)(:))); 
+        lims = [lims_min, lims_max]; 
+      else
+        lims = [0, 1];
+      endif
+    else
+      lims = [min(data(:)), max(data(:))];
+    endif
+  endif
+
+
+endfunction
+
+function __do_tight_option__ (ca)
+
+  set (ca,
+       "xlim", __get_tight_lims__ (ca, "x"),
+       "ylim", __get_tight_lims__ (ca, "y"),
+       "zlim", __get_tight_lims__ (ca, "z"));
+
+endfunction
+
+%!demo
+%! t=0:0.01:2*pi; x=sin(t);
+%!
+%! subplot(221);
+%! plot(t, x);
+%! title("normal plot");
+%!
+%! subplot(222);
+%! plot(t, x);
+%! title("square plot");
+%! axis("square");
+%!
+%! subplot(223);
+%! plot(t, x);
+%! title("equal plot");
+%! axis("equal");
+%! 
+%! subplot(224);
+%! plot(t, x);
+%! title("normal plot again");
+%! axis("normal");
+
+%!demo
+%! t=0:0.01:2*pi; x=sin(t);
+%!
+%! subplot(121);
+%! plot(t, x);
+%! title("ij plot");
+%! axis("ij");
+%!
+%! subplot(122);
+%! plot(t, x);
+%! title("xy plot");
+%! axis("xy");
+
+%!demo
+%! t=0:0.01:2*pi; x=sin(t);
+%!
+%! subplot(331);
+%! plot(t, x);
+%! title("x tics and labels");
+%! axis("ticx");
+%!
+%! subplot(332);
+%! plot(t, x);
+%! title("y tics and labels");
+%! axis("ticy");
+%!
+%! subplot(333);
+%! plot(t, x);
+%! title("axis off");
+%! axis("off");
+%!
+%! subplot(334);
+%! plot(t, x);
+%! title("x and y tics, x labels");
+%! axis("labelx","tic");
+%!
+%! subplot(335);
+%! plot(t, x);
+%! title("x and y tics, y labels");
+%! axis("labely","tic");
+%!
+%! subplot(336);
+%! plot(t, x);
+%! title("all tics but no labels");
+%! axis("nolabel","tic");
+%!
+%! subplot(337);
+%! plot(t, x);
+%! title("x tics, no labels");
+%! axis("nolabel","ticx");
+%!
+%! subplot(338);
+%! plot(t, x);
+%! title("y tics, no labels");
+%! axis("nolabel","ticy");
+%!
+%! subplot(339);
+%! plot(t, x);
+%! title("all tics and labels");
+%! axis("on");
+
+%!demo
+%! t=0:0.01:2*pi; x=sin(t);
+%!
+%! subplot(321);
+%! plot(t, x);
+%! title("axes at [0 3 0 1]")
+%! axis([0,3,0,1]);
+%!
+%! subplot(322);
+%! plot(t, x);
+%! title("auto");
+%! axis("auto");
+%!
+%! subplot(323);
+%! plot(t, x, ";sine [0:2pi];"); hold on;
+%! plot(-3:3,-3:3, ";line (-3,-3)->(3,3);"); hold off;
+%! title("manual");
+%! axis("manual");
+%!
+%! subplot(324);
+%! plot(t, x, ";sine [0:2pi];");
+%! title("axes at [0 3 0 1], then autox");
+%! axis([0,3,0,1]); axis("autox");
+%!
+%! subplot(325);
+%! plot(t, x, ";sine [0:2p];");
+%! axis([3,6,0,1]); axis("autoy");
+%! title("axes at [3 6 0 1], then autoy");
+%!
+%! subplot(326);
+%! plot(t, sin(t), t, -2*sin(t/2))
+%! axis("tight");
+%! title("tight");
+
+%!demo
+%! clf
+%! axis image
+%! x=0:0.1:10;
+%! plot(x,sin(x))
+%! axis image
+%! title("image")
+
+%!demo
+%! clf
+%! [x,y,z] = peaks(50);
+%! x1 = max(x(:));
+%! pcolor(x-x1,y-x1/2,z)
+%! hold on
+%! [x,y,z] = sombrero;
+%! s = x1/max(x(:));
+%! pcolor(s*x+x1,s*y+x1/2,5*z)
+%! axis tight
+
diff --git a/scripts/plot/backend.m b/scripts/plot/backend.m
new file mode 100644
index 0000000..853cc19
--- /dev/null
+++ b/scripts/plot/backend.m
@@ -0,0 +1,70 @@
+## Copyright (C) 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} backend (@var{name})
+## @deftypefnx {Function File} {} backend (@var{hlist}, @var{name})
+## Change the default graphics backend to @var{name}.  If the backend is
+## not already loaded, it is first initialized (initialization is done
+## through the execution of @code{__init_ at var{name}__}).
+##
+## When called with a list of figure handles, @var{hlist}, the backend is
+## changed only for the listed figures.
+## @seealso{available_backends}
+## @end deftypefn
+
+function backend (varargin)
+
+  name = "";
+  hlist = [];
+
+  if (nargin == 1)
+    if (ischar (varargin{1}))
+      name = varargin{1};
+    else
+      error ("backend: invalid backend name");
+    endif
+  elseif (nargin == 2)
+    if (isnumeric (varargin{1}) && ischar (varargin{2}))
+      hlist = varargin{1};
+      name = varargin{2};
+    elseif (ischar (varargin{2}))
+      error ("backend: invalid handle list");
+    else
+      error ("backend: invalid backend name");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (! any (strcmp (available_backends (), name)))
+    feval (["__init_", name, "__"]);
+    if (! any (strcmp (available_backends (), name)))
+      error ("backend: backend was not correctly registered");
+    endif
+  endif
+
+  if (isempty (hlist))
+    set (0, "defaultfigure__backend__", name);
+  else
+    for h = hlist(:)'
+      set (h, "__backend__", name);
+    endfor
+  endif
+
+endfunction
diff --git a/scripts/plot/bar.m b/scripts/plot/bar.m
new file mode 100644
index 0000000..9099679
--- /dev/null
+++ b/scripts/plot/bar.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bar (@var{x}, @var{y})
+## @deftypefnx {Function File} {} bar (@var{y})
+## @deftypefnx {Function File} {} bar (@var{x}, @var{y}, @var{w})
+## @deftypefnx {Function File} {} bar (@var{x}, @var{y}, @var{w}, @var{style})
+## @deftypefnx {Function File} {@var{h} =} bar (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} bar (@var{h}, @dots{})
+## Produce a bar graph from two vectors of x-y data.
+##
+## If only one argument is given, it is taken as a vector of y-values
+## and the x coordinates are taken to be the indices of the elements.
+##
+## The default width of 0.8 for the bars can be changed using @var{w}. 
+##
+## If @var{y} is a matrix, then each column of @var{y} is taken to be a
+## separate bar graph plotted on the same graph.  By default the columns
+## are plotted side-by-side.  This behavior can be changed by the @var{style}
+## argument, which can take the values @code{"grouped"} (the default),
+## or @code{"stacked"}.
+##
+## The optional return value @var{h} provides a handle to the "bar series"
+## object with one handle per column of the variable @var{y}.  This
+## series allows common elements of the group of bar series objects to
+## be changed in a single bar series and the same properties are changed
+## in the other "bar series".  For example
+##
+## @example
+## @group
+## h = bar (rand (5, 10));
+## set (h(1), "basevalue", 0.5);
+## @end group
+## @end example
+##
+## @noindent
+## changes the position on the base of all of the bar series.
+##
+## The optional input handle @var{h} allows an axis handle to be passed.
+## Properties of the patch graphics object can be changed using
+## @var{prop}, @var{val} pairs.
+##
+## @seealso{barh, plot} 
+## @end deftypefn
+
+## Author: jwe
+
+function varargout = bar (varargin)
+  varargout = cell (nargout, 1);
+  [varargout{:}] = __bar__ (true, "bar", varargin{:});
+endfunction
diff --git a/scripts/plot/barh.m b/scripts/plot/barh.m
new file mode 100644
index 0000000..19a12f9
--- /dev/null
+++ b/scripts/plot/barh.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} barh (@var{x}, @var{y})
+## @deftypefnx {Function File} {} barh (@var{y})
+## @deftypefnx {Function File} {} barh (@var{x}, @var{y}, @var{w})
+## @deftypefnx {Function File} {} barh (@var{x}, @var{y}, @var{w}, @var{style})
+## @deftypefnx {Function File} {@var{h} =} barh (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} barh (@var{h}, @dots{})
+## Produce a horizontal bar graph from two vectors of x-y data.
+##
+## If only one argument is given, it is taken as a vector of y-values
+## and the x coordinates are taken to be the indices of the elements.
+##
+## The default width of 0.8 for the bars can be changed using @var{w}. 
+##
+## If @var{y} is a matrix, then each column of @var{y} is taken to be a
+## separate bar graph plotted on the same graph.  By default the columns
+## are plotted side-by-side.  This behavior can be changed by the @var{style}
+## argument, which can take the values @code{"grouped"} (the default),
+## or @code{"stacked"}.
+##
+## The optional return value @var{h} provides a handle to the bar series
+## object.  See @code{bar} for a description of the use of the bar series.
+##
+## The optional input handle @var{h} allows an axis handle to be passed.
+## Properties of the patch graphics object can be changed using
+## @var{prop}, @var{val} pairs.
+##
+## @seealso{bar, plot}
+## @end deftypefn
+
+## Author: jwe
+
+function varargout = barh (varargin)
+  varargout = cell (nargout, 1);
+  [varargout{:}] = __bar__ (false, "barh", varargin{:});
+endfunction
diff --git a/scripts/plot/box.m b/scripts/plot/box.m
new file mode 100644
index 0000000..2963ad4
--- /dev/null
+++ b/scripts/plot/box.m
@@ -0,0 +1,61 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} box (@var{arg})
+## @deftypefnx {Function File} {} box (@var{h}, @dots{})
+## Control the display of a border around the plot.
+## The argument may be either @code{"on"} or @code{"off"}.  If it is
+## omitted, the current box state is toggled.
+## @seealso{grid}
+## @end deftypefn
+
+## Author: jwe
+
+function box (varargin)
+
+  h = gca ();
+
+  box_state = get (h, "box");
+
+  nargs = numel (varargin);
+
+  if (nargs == 0)
+    if (strcmpi (box_state, "on"))
+      box_state = "off";
+    else
+      box_state = "on";
+    endif
+  elseif (nargs == 1)
+    state = varargin{1};
+    if (ischar (state))
+      if (strcmpi (state, "off"))
+	box_state = "off";
+      elseif (strcmpi (state, "on"))
+	box_state = "on";
+      else
+	print_usage ();
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+  set (h, "box", box_state);
+
+endfunction
diff --git a/scripts/plot/caxis.m b/scripts/plot/caxis.m
new file mode 100644
index 0000000..b68f210
--- /dev/null
+++ b/scripts/plot/caxis.m
@@ -0,0 +1,88 @@
+## Copyright (C)  2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} caxis (@var{limits})
+## @deftypefnx {Function File} {} caxis (@var{h}, @dots{})
+## Set color axis limits for plots.
+##
+## The argument @var{limits} should be a 2 element vector specifying the 
+## lower and upper limits to assign to the first and last value in the
+## colormap.  Values outside this range are clamped to the first and last
+## colormap entries. 
+##
+## If @var{limits} is 'auto', then automatic colormap scaling is applied,
+## whereas if @var{limits} is 'manual' the colormap scaling is set to manual.
+##
+## Called without any arguments to current color axis limits are returned.
+##
+## If an axes handle is passed as the first argument, then operate on
+## this axes rather than the current axes.
+## @end deftypefn
+
+function varargout = caxis (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("caxis", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    varargout = cell (max (nargin == 0, nargout), 1);
+    if (isempty (varargout))
+      __caxis__ (h, varargin{:});
+    else
+      [varargout{:}] = __caxis__ (h, varargin{:});
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
+
+function [cmin, cmax] = __caxis__ (ca, ax, varargin)
+
+  if (nargin == 1)
+    cmin = get (ca, "clim");
+    if (nargout > 1)
+      cmax = cmin(2);
+      cmin = cmin(1);
+    endif
+  elseif (ischar (ax))
+    if (strcmpi (ax, "auto"))
+      set (ca, "climmode", "auto");
+    elseif (strcmpi (ax, "manual"))
+      set (ca, "climmode", "manual");
+    endif
+  elseif (isvector (ax))
+    len = length (ax);
+
+    if (len != 2)
+      error ("caxis: expecting vector with 2 elements");
+    endif
+
+    set (ca, "clim", [ax(1), ax(2)]);
+  else
+    error ("caxis: expecting no args, a string or a 2 element vector");
+  endif
+
+  if (nargin > 2)
+    __caxis__ (ca, varargin{:})'
+  endif
+
+endfunction
+      
diff --git a/scripts/plot/cla.m b/scripts/plot/cla.m
new file mode 100644
index 0000000..7f5ce8b
--- /dev/null
+++ b/scripts/plot/cla.m
@@ -0,0 +1,101 @@
+## Copyright (C) 2008, 2009 Ben Abbott
+## 
+## This program is free software; you can 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cla ()
+## @deftypefnx {Function File} {} cla ("reset")
+## @deftypefnx {Function File} {} cla (@var{hax})
+## @deftypefnx {Function File} {} cla (@var{hax}, "reset")
+## Delete the children of the current axes with visible handles.
+## If @var{hax} is specified and is an axes object handle, operate on it
+## instead of the current axes.  If the optional argument @code{"reset"}
+## is specified, also delete the children with hidden handles.
+## @seealso{clf}
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Created: 2008-10-03
+
+function cla (varargin)
+
+  if (nargin > 2)
+    print_usage ();
+  elseif (nargin > 1)
+    if (ishandle (varargin{1})
+	&& strcmp (get (varargin{1}, "type"), "axes")
+	&& ischar (varargin{2}) && strcmpi (varargin{2}, "reset"))
+      oldhax = gca;
+      hax = varargin{1};
+      do_reset = true;
+    else
+      print_usage ();
+    endif
+  elseif (nargin == 1)
+    if (ishandle (varargin{1})
+	&& strcmp (get (varargin{1}, "type"), "axes"))
+      oldhax = gca;
+      hax = varargin{1};
+      do_reset = false;
+    elseif (ischar (varargin{1}) && strcmpi (varargin{1}, "reset"))
+      hax = gca;
+      oldhax = hax;
+      do_reset = true;
+    else
+      print_usage ();
+    endif
+  else
+    hax = gca;
+    oldhax = hax;
+    do_reset = false;
+  endif
+
+  hc = get (hax, "children");
+
+  if (! do_reset && ! isempty (hc))
+    hc = findobj (hc, "flat", "visible", "on");
+    hc = setdiff (hc, hax);
+  endif
+
+  if (! isempty (hc))
+    ## Delete the children of the axis.
+    delete (hc);
+  endif
+
+  ## FIXME: The defaults should be "reset()" below, but so far there is
+  ## no method to determine the defaults, much less return an object's
+  ## properties to their default values.  Instead make a close
+  ## approximation.
+
+  axes (hax);
+  axis auto
+
+  ## Set the current axis back to where it was upon entry.
+  axes (oldhax);
+
+endfunction
+
+%!test
+%! hf = figure (1, "visible", "off");
+%! unwind_protect
+%!   clf
+%!   plot (1:10)
+%!   cla ()
+%!   kids = get (gca, "children");
+%!   cla ()
+%! unwind_protect_cleanup
+%!   close (hf)
+%! end_unwind_protect
+%! assert (numel (kids), 0)
diff --git a/scripts/plot/clabel.m b/scripts/plot/clabel.m
new file mode 100644
index 0000000..b85fd52
--- /dev/null
+++ b/scripts/plot/clabel.m
@@ -0,0 +1,139 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} clabel (@var{c}, @var{h})
+## @deftypefnx {Function File} {} clabel (@var{c}, @var{h}, @var{v})
+## @deftypefnx {Function File} {} clabel (@var{c}, @var{h}, "manual")
+## @deftypefnx {Function File} {} clabel (@var{c})
+## @deftypefnx {Function File} {} clabel (@var{c}, @var{h})
+## @deftypefnx {Function File} {} clabel (@dots{}, @var{prop}, @var{val}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} clabel (@dots{})
+## Adds labels to the contours of a contour plot.  The contour plot is specified
+## by the contour matrix @var{c} and optionally the contourgroup object @var{h}
+## that are returned by @code{contour}, @code{contourf} and @code{contour3}.
+## The contour labels are rotated and placed in the contour itself.
+##
+## By default, all contours are labelled.  However, the contours to label can be
+## specified by the vector @var{v}.  If the "manual" argument is given then
+## the contours to label can be selected with the mouse.
+##
+## Additional property/value pairs that are valid properties of text objects
+## can be given and are passed to the underlying text objects.  Additionally,
+## the property "LabelSpacing" is available allowing the spacing between labels
+## on a contour (in points) to be specified.  The default is 144 points, or 2
+## inches.
+##
+## The returned value @var{h} is the set of text object that represent the
+## contour labels.  The "userdata" property of the text objects contains the
+## numerical value of the contour label.
+##
+## An example of the use of @code{clabel} is
+##
+## @example
+## @group
+## [c, h] = contour (peaks(), -4 : 6);
+## clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+## @end group
+## @end example
+##
+## @seealso{contour, contourf, contour3, meshc, surfc, text}
+## @end deftypefn
+
+function retval = clabel (c, varargin)
+  label_spacing = 2 * 72;
+  have_hg = false;
+  have_labelspacing = false;
+
+  if (nargin < 1)
+    print_usage()
+  elseif (nargin == 1)
+    hparent = gca ();
+  else
+    arg = varargin{1};
+    if (isscalar (arg) && ishandle(arg) && 
+	strcmp (get (arg, "type"), "hggroup"))
+      obj = get (arg);
+      if (! isfield (obj, "contourmatrix"))
+	error ("clabel: expecting the handle to be a contour group");
+      endif
+      hg = arg;
+      have_hg = true;
+      varargin(1) = [];
+    else
+      hparent = gca ();
+    endif
+  endif
+
+  if (length(varargin) > 0 && isnumeric (varargin{1}))
+    v = varargin{1}(:);
+    varargin(1) = [];
+  else
+    v = [];
+  endif
+
+  for i = 1 : length (varargin) - 1
+    arg = varargin{i};
+    if (strcmpi (arg, "labelspacing"))
+      label_spacing = varargin{i+1};
+      have_labelspacing = true;
+      varargin(i:i+1) = [];
+      break;
+    endif
+  endfor
+
+  for i = 1 : length (varargin)
+    arg = varargin{i};
+    if (strcmpi (arg, "manual"))
+      error ("clabel: manual contouring mode not supported");
+    endif
+  endfor
+
+  if (have_hg)
+    if (! isempty (v))
+      if (have_labelspacing)
+	set (hg, "textlistmode", "manual", "textlist", v, 
+	     "labelspacing", label_spacing, "showtext", "on");
+      else
+	set (hg, "textlistmode", "manual", "textlist", v, "showtext", "on");
+      endif
+    else
+      if (have_labelspacing)
+	set (hg,"showtext", "on", "labelspacing", label_spacing);
+      else
+	set (hg,"showtext", "on");
+      endif
+    endif
+    retval = findobj (hg, "type", "text");
+    if (! isempty (varargin))
+      set (retval, varargin {:});
+    endif
+  else
+    retval =  __clabel__ (c, v, hparent, label_spacing, [], varargin{:});
+  endif
+endfunction
+
+%!demo
+%! clf
+%! [c, h] = contour (peaks(), -4 : 6);
+%! clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
+
+%!demo
+%! clf
+%! [c, h] = contourf (peaks(), -7 : 6);
+%! clabel (c, h, -6 : 2 : 6, 'fontsize', 12);
diff --git a/scripts/plot/clf.m b/scripts/plot/clf.m
new file mode 100644
index 0000000..7af2284
--- /dev/null
+++ b/scripts/plot/clf.m
@@ -0,0 +1,77 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} clf ()
+## @deftypefnx {Function File} {} clf ("reset")
+## @deftypefnx {Function File} {} clf (@var{hfig})
+## @deftypefnx {Function File} {} clf (@var{hfig}, "reset")
+## Clear the current figure window.  @code{clf} operates by deleting child
+## graphics objects with visible handles (@code{HandleVisibility} = on).
+## If @var{hfig} is specified operate on it instead of the current figure.
+## If the optional argument @code{"reset"} is specified, all objects including
+## those with hidden handles are deleted.
+## @seealso{cla, close, delete}
+## @end deftypefn
+
+## Author: jwe
+
+function clf (varargin)
+
+  if (nargin > 2)
+    print_usage ();
+  elseif (nargin > 1)
+    if (isfigure (varargin{1}) && ischar (varargin{2})
+	&& strcmpi (varargin{2}, "reset"))
+      oldfig = gcf;
+      hfig = varargin{1};
+      do_reset = true;
+    else
+      print_usage ();
+    endif
+  elseif (nargin == 1)
+    if (isfigure (varargin{1}))
+      oldfig = gcf;
+      hfig = varargin{1};
+      do_reset = false;
+    elseif (ischar (varargin{1}) && strcmpi (varargin{1}, "reset"))
+      hfig = gcf;
+      oldfig = hfig;
+      do_reset = true;
+    else
+      print_usage ();
+    endif
+  else
+    hfig = gcf;
+    oldfig = hfig;
+    do_reset = false;
+  endif
+
+  if (do_reset)
+    ## Select all the children, including the one with hidden handles.
+    hc = allchild (hfig);
+    reset (hfig)
+  else
+    ## Select only the chilren with visible handles.
+    hc = get (hfig, "children");
+  endif
+
+  ## Delete the children.
+  delete (hc);
+
+endfunction
diff --git a/scripts/plot/close.m b/scripts/plot/close.m
new file mode 100644
index 0000000..2c9bff7
--- /dev/null
+++ b/scripts/plot/close.m
@@ -0,0 +1,78 @@
+## Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} {} close
+## @deftypefnx {Command} {} close (@var{n})
+## @deftypefnx {Command} {} close all
+## @deftypefnx {Command} {} close all hidden
+## Close figure window(s) by calling the function specified by the
+## @code{"closerequestfcn"} property for each figure.  By default, the
+## function @code{closereq} is used.
+## @seealso{closereq}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = close (arg1, arg2)
+
+  figs = [];
+
+  if (nargin == 0)
+    ## Close current figure.  Don't use gcf because that will open a new
+    ## plot window if one doesn't exist.
+    figs = get (0, "currentfigure");
+    if (! isempty (figs) && figs == 0)
+      figs = [];
+    endif
+  elseif (nargin == 1)
+    if (ischar (arg1) && strcmpi (arg1, "all"))
+      close_all_figures (false);
+    elseif (isfigure (arg1))
+      figs = arg1;
+    else
+      error ("close: expecting argument to be \"all\" or a figure handle");
+    endif
+  elseif (nargin == 2
+	  && ischar (arg1) && strcmpi (arg1, "all")
+	  && ischar (arg2) && strcmpi (arg2, "hidden"))
+    close_all_figures (true);
+  else
+    print_usage ();
+  endif
+
+  for h = figs
+    __go_execute_callback__ (h, "closerequestfcn");
+  endfor
+
+  if (nargout > 0)
+    retval = 1;
+  endif
+
+endfunction
+
+function close_all_figures (close_hidden_figs)
+
+  while (! isempty (fig = get (0, "currentfigure")))
+    ## handlevisibility = get (fig, "handlevisibility")
+    ## if (close_hidden_figs || ! strcmpi (handlevisibility, "off"))
+    close (fig);
+    ## endif
+  endwhile
+
+endfunction
diff --git a/scripts/plot/closereq.m b/scripts/plot/closereq.m
new file mode 100644
index 0000000..410ec75
--- /dev/null
+++ b/scripts/plot/closereq.m
@@ -0,0 +1,43 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} closereq ()
+## Close the current figure and delete all graphics objects associated
+## with it.
+## @seealso{close, delete}
+## @end deftypefn
+
+## Author: jwe
+
+function closereq ()
+
+  if (nargin == 0)
+    cf = gcbf ();
+    if (isempty (cf))
+      warning ("closereq: calling closereq from octave prompt is not supported, use `close' instead");
+      cf = get (0, "currentfigure");
+    endif
+    if (! isempty (cf) && isfigure (cf))
+      delete (cf);
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/colorbar.m b/scripts/plot/colorbar.m
new file mode 100644
index 0000000..1a7c440
--- /dev/null
+++ b/scripts/plot/colorbar.m
@@ -0,0 +1,599 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} colorbar (@var{s})
+## @deftypefnx {Function File} {} colorbar ("peer", @var{h}, @dots{})
+## Adds a colorbar to the current axes.  Valid values for @var{s} are
+##
+## @table @asis
+## @item "EastOutside"
+## Place the colorbar outside the plot to the right.  This is the default.
+## @item "East"
+## Place the colorbar inside the plot to the right.
+## @item "WestOutside"
+## Place the colorbar outside the plot to the left.
+## @item "West"
+## Place the colorbar inside the plot to the left.
+## @item "NorthOutside"
+## Place the colorbar above the plot.
+## @item "North"
+## Place the colorbar at the top of the plot.
+## @item "SouthOutside"
+## Place the colorbar under the plot.
+## @item "South"
+## Place the colorbar at the bottom of the plot.
+## @item "Off", "None"
+## Remove any existing colorbar from the plot.
+## @end table
+##
+## If the argument "peer" is given, then the following argument is treated
+## as the axes handle on which to add the colorbar.
+## @end deftypefn
+
+function h = colorbar (varargin)
+  ax = [];
+  loc = "eastoutside";
+  args = {};
+  deleting = false;
+
+  i = 1;
+  while (i <= nargin)
+    arg = varargin {i++};
+
+    if (ischar(arg))
+      if (strcmpi (arg, "peer"))
+	if (i > nargin)
+	  error ("colorbar: missing axes handle after \"peer\"");
+	else
+	  ax = vargin{i++}
+	  if (!isscalar (ax) || ! ishandle (ax)
+	      || strcmp (get (ax, "type"), "axes"))
+	    error ("colorbar: expecting an axes handle following \"peer\"");
+	  endif
+	endif
+      elseif (strcmpi (arg, "north") || strcmpi (arg, "south")
+	      || strcmpi (arg, "east") || strcmpi (arg, "west")
+	      || strcmpi (arg, "northoutside") || strcmpi (arg, "southoutside")
+	      || strcmpi (arg, "eastoutside") || strcmpi (arg, "westoutside"))
+	loc = tolower (arg);
+      elseif (strcmpi (arg, "off") || strcmpi (arg, "none"))
+	deleting = true;
+      else
+	args{end+1} = arg;
+      endif
+    else
+      args{end+1} = arg;
+    endif
+  endwhile
+
+  if (isempty (ax))
+    ax = gca ();
+  endif
+
+  showhiddenhandles = get (0, "showhiddenhandles");
+  unwind_protect
+    set (0, "showhiddenhandles", "on")
+    cax = findobj (get (ax, "parent"), "tag", "colorbar", "type", "axes", "axes", ax);
+    if (! isempty (cax))
+      delete (cax);
+    endif
+  unwind_protect_cleanup
+    set (0, "showhiddenhandles", showhiddenhandles)
+  end_unwind_protect
+
+  if (! deleting)
+    obj = get (ax);
+    position = obj.position;
+    clen = rows (get (get (ax, "parent"), "colormap"));
+    cext = get (ax, "clim");
+    cdiff = (cext(2) - cext(1)) / clen / 2;
+    cmin = cext(1) + cdiff;
+    cmax = cext(2) - cdiff;
+
+    orig_pos = obj.position;
+    orig_opos = obj.outerposition;
+    [pos, cpos, vertical, mirror, aspect] =  ...
+	__position_colorbox__ (loc, obj, ancestor (ax, "figure"));
+    set (ax, "activepositionproperty", "position", "position", pos);
+
+    cax = __go_axes__ (get (ax, "parent"), "tag", "colorbar", 
+    		       "handlevisibility", "on", 
+		       "activepositionproperty", "position", 
+		       "position", cpos);
+    addproperty ("location", cax, "radio",
+		 "eastoutside|east|westoutside|west|northoutside|north|southoutside|south",
+		 loc);
+    addproperty ("axes", cax, "handle", ax);
+
+    if (vertical)
+      hi = image (cax, [0,1], [cmin, cmax], [1 : clen]');
+      if (mirror)
+	set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
+	     "ylim", cext, "ylimmode", "manual",
+	     "yaxislocation", "right", args{:});
+      else
+	set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
+	     "ylim", cext, "ylimmode", "manual",
+	     "yaxislocation", "left", args{:});
+      endif
+    else
+      hi = image (cax, [cmin, cmax], [0,1], [1 : clen]);
+      if (mirror)
+	set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
+	     "xlim", cext, "xlimmode", "manual",
+	     "xaxislocation", "top", args{:});
+      else
+	set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
+	     "xlim", cext, "xlimmode", "manual",
+	     "xaxislocation", "bottom", args{:});
+      endif
+    endif
+
+    if (! isnan (aspect))
+      set (cax, "dataaspectratio", aspect);
+    endif
+
+    ctext = text (0, 0, "", "tag", "colorbar","visible", "off", 
+		  "handlevisibility", "off", "xliminclude", "off",  
+		  "yliminclude", "off", "zliminclude", "off",
+		  "deletefcn", {@deletecolorbar, cax, orig_pos, orig_opos});
+
+    set (cax, "deletefcn", {@resetaxis, orig_pos, orig_opos});
+
+    addlistener (ax, "clim", {@update_colorbar_clim, hi, vertical})
+    addlistener (ax, "dataaspectratio", {@update_colorbar_axis, cax})
+    addlistener (ax, "position", {@update_colorbar_axis, cax})
+
+  endif
+
+  if (nargout > 0)
+    h = cax;
+  endif
+endfunction
+
+function deletecolorbar (h, d, hc, pos, opos)
+  ## Don't delete the colorbar and reset the axis size if the
+  ## parent figure is being deleted.
+  if (ishandle (hc) && strcmp (get (hc, "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
+    if (strcmp (get (hc, "beingdeleted"), "off"))
+      delete (hc);
+    endif
+    if (!isempty (ancestor (h, "axes")) &&
+	strcmp (get (ancestor (h, "axes"), "beingdeleted"), "off"))
+      set (ancestor (h, "axes"), "position", pos, "outerposition", opos);
+    endif
+  endif
+endfunction
+
+function resetaxis (h, d, pos, opos)
+  if (ishandle (h) && strcmp (get (h, "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) &&
+      ishandle (get (h, "axes")))
+     set (get (h, "axes"), "position", pos, "outerposition", opos);
+  endif
+endfunction
+
+function update_colorbar_clim (h, d, hi, vert)
+  if (ishandle (h) && strcmp (get (h, "type"), "image") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
+    clen = rows (get (get (h, "parent"), "colormap"));
+    cext = get (h, "clim");
+    cdiff = (cext(2) - cext(1)) / clen / 2;
+    cmin = cext(1) + cdiff;
+    cmax = cext(2) - cdiff;
+
+    if (vert)
+      set (hi, "ydata", [cmin, cmax]);
+      set (get (hi, "parent"), "ylim", cext);
+    else
+      set (hi, "xdata", [cmin, cmax]);
+      set (get (hi, "parent"), "xlim", cext);
+    endif
+  endif
+endfunction
+
+function update_colorbar_axis (h, d, cax)
+  if (ishandle (cax) && strcmp (get (cax, "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
+    loc = get (cax, "location");
+    obj = get (h);
+    [pos, cpos, vertical, mirror, aspect] =  ...
+	__position_colorbox__ (loc, obj, ancestor (h, "figure"));
+
+    if (vertical)
+      if (mirror)
+	set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
+	     "yaxislocation", "right", "position", cpos);
+      else
+	set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
+	     "yaxislocation", "left", "position", cpos);
+      endif
+    else
+      if (mirror)
+	set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
+	     "xaxislocation", "top", "position", cpos);
+      else
+	set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
+	     "xaxislocation", "bottom", "position", cpos);
+      endif
+    endif
+
+    if (! isnan (aspect))
+      set (cax, "dataaspectratio", aspect);
+    endif
+  endif
+endfunction
+
+function [pos, cpos, vertical, mirr, aspect] = __position_colorbox__ (cbox, obj, cf)
+
+  pos = obj.position;
+  sz = pos(3:4);
+
+  off = 0;
+  if (strcmpi (obj.dataaspectratiomode, "manual"))
+    r = obj.dataaspectratio;
+    if (pos(3) > pos(4))
+      switch (cbox)
+	case {"east", "eastoutside", "west", "westoutside"}
+	  off = [(pos(3) - pos(4)) ./ (r(2) / r(1)), 0];	  
+      endswitch
+    else
+      switch (cbox)
+	case {"north", "northoutside", "south", "southoutside"}
+	  off = [0, (pos(4) - pos(3)) ./ (r(1) / r(2))];
+	  ## This shouldn't be here except that gnuplot doesn't have a
+	  ## square window and so a square aspect ratio is not square.
+	  ## The corrections are empirical.
+	  if (strcmp (get (cf, "__backend__"), "gnuplot"))
+	    if (length (cbox) > 7 && strcmp (cbox(end-6:end),"outside"))
+	      off = off / 2;
+	    else
+	      off = off / 1.7;
+	    endif
+	  endif
+      endswitch
+    endif
+    off = off / 2;
+  endif
+
+  switch (cbox)
+    case "northoutside"
+      origin = pos(1:2) + [0., 0.9] .* sz + [1, -1] .* off;
+      sz = sz .* [1.0, 0.06];
+      pos(4) = 0.8 * pos(4);
+      mirr = true;
+      vertical = false;
+    case "north"
+      origin = pos(1:2) + [0.05, 0.9] .* sz + [1, -1] .* off;
+      sz = sz .* [1.0, 0.06] * 0.9;
+      mirr = false;
+      vertical = false;
+    case "southoutside"
+      origin = pos(1:2) + off;
+      sz = sz .* [1.0, 0.06];
+      pos(2) = pos(2) + pos(4) * 0.2;
+      pos(4) = 0.8 * pos(4);
+      mirr = false;
+      vertical = false;
+    case "south"
+      origin = pos(1:2) + [0.05, 0.05] .* sz + off;
+      sz = sz .* [1.0, 0.06] * 0.9;
+      mirr = true;
+      vertical = false;
+    case "eastoutside"
+      origin = pos(1:2) + [0.9, 0] .* sz + [-1, 1] .* off;
+      sz = sz .* [0.06, 1.0];
+      pos(3) = 0.8 * pos(3);
+      mirr = true;
+      vertical = true;
+    case "east"
+      origin = pos(1:2) + [0.9, 0.05] .* sz + [-1, 1] .* off;
+      sz = sz .* [0.06, 1.0] * 0.9;
+      mirr = false;
+      vertical = true;
+    case "westoutside"
+      origin = pos(1:2) + off;
+      sz = sz .* [0.06, 1.0];
+      pos(1) = pos(1) + pos(3) * 0.2;
+      pos(3) = 0.8 * pos(3);
+      mirr = false;
+      vertical = true;
+    case "west"
+      origin = pos(1:2) + [0.05, 0.05] .* sz + off;
+      sz = sz .* [0.06, 1.0] .* 0.9;
+      mirr = true;
+      vertical = true;
+  endswitch
+
+  cpos = [origin, sz];
+
+  if (strcmpi (obj.dataaspectratiomode, "manual"))
+    if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
+      obj.position = pos;
+      actual_pos = __actual_axis_position__ (obj);
+      if (strfind (cbox, "outside"))
+	scale = 1.0;
+      else
+	scale = 0.9;
+      endif
+      if (sz(1) > sz(2))
+	dx = (1-scale)*actual_pos(3);
+	cpos(1) = actual_pos(1) + dx/2;
+	cpos(3) = actual_pos(3) - dx;
+      else
+	dy = (1-scale)*actual_pos(4);
+	cpos(2) = actual_pos(2) + dy/2;
+	cpos(4) = actual_pos(4) - dy;
+      endif
+      aspect = NaN;
+    else
+      if (vertical)
+	aspect = [1, 0.21, 1];
+      else
+	aspect = [0.21, 1, 1];
+      endif
+    endif
+  else
+    aspect = NaN;
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! imagesc(x)
+%! colorbar();
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! imagesc(x)
+%! colorbar("westoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! imagesc(x)
+%! colorbar("northoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! imagesc(x)
+%! colorbar("southoutside");
+
+%!demo
+%! clf
+%! contour(peaks())
+%! colorbar("west");
+
+%!demo
+%! clf
+%! subplot(2,2,1)
+%! contour(peaks())
+%! colorbar("east");
+%! subplot(2,2,2)
+%! contour(peaks())
+%! colorbar("west");
+%! subplot(2,2,3)
+%! contour(peaks())
+%! colorbar("north");
+%! subplot(2,2,4)
+%! contour(peaks())
+%! colorbar("south");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(2,2,1)
+%! imagesc(x)
+%! colorbar();
+%! subplot(2,2,2)
+%! imagesc(x)
+%! colorbar("westoutside");
+%! subplot(2,2,3)
+%! imagesc(x)
+%! colorbar("northoutside");
+%! subplot(2,2,4)
+%! imagesc(x)
+%! colorbar("southoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(1,2,1)
+%! imagesc(x)
+%! axis square;
+%! colorbar();
+%! subplot(1,2,2)
+%! imagesc(x)
+%! axis square;
+%! colorbar("westoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(1,2,1)
+%! imagesc(x)
+%! axis square;
+%! colorbar("northoutside");
+%! subplot(1,2,2)
+%! imagesc(x)
+%! axis square;
+%! colorbar("southoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(2,1,1)
+%! imagesc(x)
+%! axis square;
+%! colorbar();
+%! subplot(2,1,2)
+%! imagesc(x)
+%! axis square;
+%! colorbar("westoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(2,1,1)
+%! imagesc(x)
+%! axis square;
+%! colorbar("northoutside");
+%! subplot(2,1,2)
+%! imagesc(x)
+%! axis square;
+%! colorbar("southoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(1,2,1)
+%! imagesc(x)
+%! colorbar();
+%! subplot(1,2,2)
+%! imagesc(x)
+%! colorbar("westoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(1,2,1)
+%! imagesc(x)
+%! colorbar("northoutside");
+%! subplot(1,2,2)
+%! imagesc(x)
+%! colorbar("southoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(2,1,1)
+%! imagesc(x)
+%! colorbar();
+%! subplot(2,1,2)
+%! imagesc(x)
+%! colorbar("westoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(2,1,1)
+%! imagesc(x)
+%! colorbar("northoutside");
+%! subplot(2,1,2)
+%! imagesc(x)
+%! colorbar("southoutside");
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! subplot(1,2,1)
+%! contour(x)
+%! axis square;
+%! colorbar("east");
+%! xlim ([1, 64])
+%! ylim ([1, 64])
+%! subplot(1,2,2)
+%! contour(x)
+%! colorbar("west");
+%! xlim ([1, 64])
+%! ylim ([1, 64])
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! contour (x)
+%! xlim ([1, 64])
+%! ylim ([1, 64])
+%! colorbar ();
+%! colorbar off
+
+%!demo
+%! clf
+%! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 
+%! contour (x)
+%! xlim ([1, 64])
+%! ylim ([1, 64])
+%! colorbar ();
+%! colorbar ();
+
+%!demo
+%! clf
+%! imagesc (1./hilb(99));
+%! h = colorbar;
+%! set (h, 'yscale', 'log');
+
+%!demo
+%! clf
+%! imagesc (log10 (1 ./ hilb (99)));
+%! h = colorbar;
+%! ytick = get(h, "ytick");
+%! set (h, "yticklabel", sprintf ('10^{%g}|', ytick));
+
+%!demo
+%! clf
+%! n=5;x=linspace(0,5,n);y=linspace(0,1,n); 
+%! imagesc(1./hilb(n)); axis equal; colorbar 
+
+%!demo
+%! clf
+%! n=5;x=linspace(0,5,n);y=linspace(0,1,n); 
+%! imagesc(x,y,1./hilb(n)); axis equal; colorbar 
+
+%!demo
+%! clf
+%! n=5;x=linspace(0,5,n);y=linspace(0,1,n); 
+%! imagesc(y,x,1./hilb(n)); axis equal; colorbar
+## This requires that the axes position be properly determined for "axes equal"
+
+%!demo
+%! clf
+%! axes
+%! colorbar
+%! hold on
+%! contour(peaks)
+%! hold off
+
+%!demo
+%! clf
+%! plot([0, 2])
+%! colorbar ("east")
+%! axis square
+
+%!demo
+%! clf
+%! plot([0, 2])
+%! colorbar ("eastoutside")
+%! axis square
+
+%!demo
+%! clf
+%! plot([0, 2])
+%! colorbar ("east")
+%! axis equal
+
+%!demo
+%! clf
+%! plot([0, 2])
+%! colorbar ("eastoutside")
+%! axis equal
diff --git a/scripts/plot/comet.m b/scripts/plot/comet.m
new file mode 100644
index 0000000..aad2ef4
--- /dev/null
+++ b/scripts/plot/comet.m
@@ -0,0 +1,87 @@
+## Copyright (C) 2008, 2009 Ben Abbott
+## 
+## This program is free software; you can 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} comet (@var{y})
+## @deftypefnx {Function File} {} comet (@var{x}, @var{y})
+## @deftypefnx {Function File} {} comet (@var{x}, @var{y}, @var{p})
+## @deftypefnx {Function File} {} comet (@var{ax}, @dots{})
+## Produce a simple comet style animation along the trajectory provided by 
+## the input coordinate vectors (@var{x}, @var{y}), where @var{x} will default
+## to the indices of @var{y}.
+##
+## The speed of the comet may be controlled by @var{p}, which represents the
+## time which passes as the animation passes from one point to the next.  The
+## default for @var{p} is 0.1 seconds.
+##
+## If @var{ax} is specified the animation is produced in that axis rather than
+## the @code{gca}.
+## @end deftypefn
+
+## Author: Ben Abbott bpabbott at mac.com
+## Created: 2008-09-21
+
+function comet (varargin)
+
+  if (nargin == 0)
+    print_usage ();
+  elseif (numel (varargin{1}) == 1 && ishandle (varargin{1})
+	  && strcmpi (get (varargin{1}, "type"), "axes"))
+    axes (varargin{1});
+    varargin = varargin(2:end);
+    numargin = nargin - 1;
+  else
+    numargin = nargin;
+  endif
+
+  p = 0.1;
+  if (numargin == 1)
+    y = varargin{1};
+    x = 1:numel(y);
+  elseif (numargin == 2)
+    x = varargin{1};
+    y = varargin{2};
+  elseif (numargin == 3)
+    x = varargin{1};
+    y = varargin{2};
+    p = varargin{3};
+  else
+    print_usage ();
+  endif
+  
+  theaxis = [min(x), max(x), min(y), max(y)];
+  num = numel (y);
+  dn = round (num/10);
+  for n = 1:(num+dn);
+    m = n - dn;
+    m = max ([m, 1]);
+    k = min ([n, num]);
+    h = plot (x(1:m), y(1:m), "r", x(m:k), y(m:k), "g", x(k), y(k), "ob");
+    axis (theaxis);
+    drawnow ();
+    pause (p);
+  endfor
+
+endfunction
+
+%!demo
+%! clf
+%! t = 0:.1:2*pi;
+%! x = cos(2*t).*(cos(t).^2);
+%! y = sin(2*t).*(sin(t).^2);
+%! comet(x,y)
+
+
diff --git a/scripts/plot/compass.m b/scripts/plot/compass.m
new file mode 100644
index 0000000..551a48c
--- /dev/null
+++ b/scripts/plot/compass.m
@@ -0,0 +1,118 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} compass (@var{u}, @var{v})
+## @deftypefnx {Function File} {} compass (@var{z})
+## @deftypefnx {Function File} {} compass (@dots{}, @var{style})
+## @deftypefnx {Function File} {} compass (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} compass (@dots{})
+##
+## Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
+## from the origin of a polar plot.  If a single complex argument @var{z} is 
+## given, then @code{@var{u} = real (@var{z})} and @code{@var{v} = imag 
+## (@var{z})}.
+##
+## The style to use for the plot can be defined with a line style @var{style}
+## in a similar manner to the line styles used with the @code{plot} command.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+## compass (eig (a))
+## @end group
+## @end example
+##
+## @seealso{plot, polar, quiver, feather}
+## @end deftypefn
+
+function retval = compass (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("compass", varargin{:});
+
+  arrowsize = 0.25;
+  firstnonnumeric = Inf;
+  for i = 1:nargin
+    if (! isnumeric (varargin{i}))
+      firstnonnumeric = i;
+      break;
+    endif
+  endfor
+
+  if (nargin < 2 || firstnonnumeric < 2)
+    ioff = 2;
+    z = varargin {1} (:) .';
+    u = real (z);
+    v = imag (z);
+  else
+    ioff = 3;
+    u = varargin {1} (:) .';
+    v = varargin {2} (:) .';
+  endif
+
+  line_spec = "b-";
+  while (ioff <= nargin)
+    arg = varargin{ioff++};
+    if ((ischar (arg) || iscell (arg)) && ! have_line_spec)
+      [linespec, valid] = __pltopt__ ("compass", arg, false);
+      if (valid)
+	line_spec = arg;
+	break;
+      else
+	error ("compass: invalid linespec");
+      endif
+    else
+      error ("compass: unrecognized argument");
+    endif
+  endwhile
+
+  ## Matlab draws compass plots, with the arrow head as one continous 
+  ## line, and each arrow separately. This is completely different than 
+  ## quiver and quite ugly.
+  n = length (u);
+  xend = u;
+  xtmp = u .* (1 - arrowsize);
+  yend = v;
+  ytmp = v .* (1 - arrowsize);
+  x = [zeros(1, n); xend; xtmp  - v * arrowsize / 3; xend; ...
+       xtmp + v * arrowsize / 3];
+  y = [zeros(1, n); yend; ytmp  + u * arrowsize / 3; yend; ...
+       ytmp - u * arrowsize / 3];
+  [r, p] = cart2pol (x, y);
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+    hlist = polar (h, r, p, line_spec);
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = hlist;
+  endif
+
+endfunction
+
+%!demo
+%! a = toeplitz([1;randn(9,1)],[1,randn(1,9)]);
+%! compass (eig (a))
diff --git a/scripts/plot/contour.m b/scripts/plot/contour.m
new file mode 100644
index 0000000..816d653
--- /dev/null
+++ b/scripts/plot/contour.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+##               2003, 2004, 2005, 2006, 2007, 2008 Shai Ayal
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} contour (@var{z})
+## @deftypefnx {Function File} {} contour (@var{z}, @var{vn})
+## @deftypefnx {Function File} {} contour (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {} contour (@var{x}, @var{y}, @var{z}, @var{vn})
+## @deftypefnx {Function File} {} contour (@dots{}, @var{style})
+## @deftypefnx {Function File} {} contour (@var{h}, @dots{})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contour (@dots{})
+## Plot level curves (contour lines) of the matrix @var{z}, using the
+## contour matrix @var{c} computed by @code{contourc} from the same
+## arguments; see the latter for their interpretation.  The set of
+## contour levels, @var{c}, is only returned if requested.  For example:
+##
+## @example
+## @group
+## x = 0:2;
+## y = x;
+## z = x' * y;
+## contour (x, y, z, 2:3)
+## @end group
+## @end example
+##
+## The style to use for the plot can be defined with a line style @var{style}
+## in a similar manner to the line styles used with the @code{plot} command.
+## Any markers defined by @var{style} are ignored.
+##
+## The optional input and output argument @var{h} allows an axis handle to 
+## be passed to @code{contour} and the handles to the contour objects to be
+## returned.
+## @seealso{contourc, patch, plot}
+## @end deftypefn
+
+## Author: Shai Ayal <shaiay at users.sourceforge.net>
+
+function [c, h] = contour (varargin)
+
+  [xh, varargin] = __plt_get_axis_arg__ ("contour", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (xh);
+    newplot ();
+    [ctmp, htmp] = __contour__ (xh, "none", varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    c = ctmp;
+    h = htmp;
+  endif
+
+endfunction
+
+%!demo
+%! [x, y, z] = peaks ();
+%! contour (x, y, z);
+
+%!demo
+%! [theta, r] = meshgrid (linspace (0, 2*pi, 64), linspace(0,1,64));
+%! [X, Y] = pol2cart (theta, r);
+%! Z = sin(2*theta).*(1-r);
+%! contour(X, Y, abs(Z), 10)
diff --git a/scripts/plot/contour3.m b/scripts/plot/contour3.m
new file mode 100644
index 0000000..8492ebc
--- /dev/null
+++ b/scripts/plot/contour3.m
@@ -0,0 +1,81 @@
+## Copyright (C) 2007, 2008, 2009 David BAteman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} contour3 (@var{z})
+## @deftypefnx {Function File} {} contour3 (@var{z}, @var{vn})
+## @deftypefnx {Function File} {} contour3 (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {} contour3 (@var{x}, @var{y}, @var{z}, @var{vn})
+## @deftypefnx {Function File} {} contour3 (@dots{}, @var{style})
+## @deftypefnx {Function File} {} contour3 (@var{h}, @dots{})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contour3 (@dots{})
+## Plot level curves (contour lines) of the matrix @var{z}, using the
+## contour matrix @var{c} computed by @code{contourc} from the same
+## arguments; see the latter for their interpretation.  The contours are
+## plotted at the Z level corresponding to their contour.  The set of
+## contour levels, @var{c}, is only returned if requested.  For example:
+##
+## @example
+## @group
+## contour3 (peaks (19));
+## hold on
+## surface (peaks (19), "facecolor", "none", "EdgeColor", "black")
+## colormap hot
+## @end group
+## @end example
+##
+## The style to use for the plot can be defined with a line style @var{style}
+## in a similar manner to the line styles used with the @code{plot} command.
+## Any markers defined by @var{style} are ignored.
+##
+## The optional input and output argument @var{h} allows an axis handle to 
+## be passed to @code{contour} and the handles to the contour objects to be
+## returned.
+## @seealso{contourc, patch, plot}
+## @end deftypefn
+
+function [c, h] = contour3 (varargin)
+
+  [xh, varargin, nargin] = __plt_get_axis_arg__ ("contour3", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (xh);
+    newplot ();
+    [ctmp, htmp] = __contour__ (xh, "auto", varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (! ishold ())
+    set (xh, "view", [-37.5, 30]);
+  endif
+
+  if (nargout > 0)
+    c = ctmp;
+    h = htmp;
+  endif
+
+endfunction
+
+%!demo
+%! contour3 (peaks (19));
+%! hold on
+%! surface (peaks (19), "facecolor", "none", "edgecolor", "black")
+%! colormap hot
+%! hold off
diff --git a/scripts/plot/contourc.m b/scripts/plot/contourc.m
new file mode 100644
index 0000000..dfdf238
--- /dev/null
+++ b/scripts/plot/contourc.m
@@ -0,0 +1,149 @@
+## Copyright (C) 2003, 2007, 2008, 2009 Shai Ayal
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{c}, @var{lev}] =}  contourc (@var{x}, @var{y}, @var{z}, @var{vn})
+## Compute isolines (contour lines) of the matrix @var{z}. 
+## Parameters @var{x}, @var{y} and @var{vn} are optional.
+##
+## The return value @var{lev} is a vector of the contour levels.
+## The return value @var{c} is a 2 by @var{n} matrix containing the
+## contour lines in the following format
+##
+## @example
+## @group
+## @var{c} = [lev1, x1, x2, @dots{}, levn, x1, x2, @dots{} 
+##      len1, y1, y2, @dots{}, lenn, y1, y2, @dots{}]
+## @end group
+## @end example
+##
+## @noindent
+## in which contour line @var{n} has a level (height) of @var{levn} and
+## length of @var{lenn}.
+## 
+## If @var{x} and @var{y} are omitted they are taken as the row/column 
+## index of @var{z}.  @var{vn} is either a scalar denoting the number of lines 
+## to compute or a vector containing the values of the lines.  If only one 
+## value is wanted, set @code{@var{vn} = [val, val]};
+## If @var{vn} is omitted it defaults to 10.
+##
+## For example,
+## @example
+## @group
+## x = 0:2;
+## y = x;
+## z = x' * y;
+## contourc (x, y, z, 2:3)
+##      @result{}   2.0000   2.0000   1.0000   3.0000   1.5000   2.0000
+##      2.0000   1.0000   2.0000   2.0000   2.0000   1.5000
+##
+## @end group
+## @end example
+## @seealso{contour}
+## @end deftypefn
+
+## Author: Shai Ayal <shaiay at users.sourceforge.net>
+
+function [cout, lev] = contourc (varargin)
+
+  if (nargin == 1)
+    vn = 10;
+    z = varargin{1};
+    [nr, nc] = size (z);
+    x = 1:nc;
+    y = 1:nr;
+  elseif (nargin == 2)
+    vn = varargin{2};
+    z = varargin{1};
+    [nr, nc] = size (z);
+    x = 1:nc;
+    y = 1:nr;
+  elseif (nargin == 3)
+    vn = 10;
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+  elseif (nargin == 4)
+    vn = varargin{4};
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (vn))
+    vv = linspace (min (z(:)), max (z(:)), vn+2)(2:end-1);
+  else
+    vv = unique (sort (vn));
+  endif
+
+  if (isvector (x) && isvector (y))
+    c = __contourc__ (x(:)', y(:)', z, vv);
+  else
+    ## Indexes x,y for the purpose of __contourc__.    
+    ii = 1:size (z,2);
+    jj = 1:size (z,1);
+  
+    ## Now call __contourc__ for the real work...
+    c = __contourc__ (ii, jj, z, vv);
+  
+    ## Map the contour lines from index space (i,j) back 
+    ## to the original grid (x,y)
+    i = 1;
+
+    while (i < size (c,2))
+      clen = c(2, i);      
+      ind = i + [1 : clen];
+
+      ci = c(1, ind);
+      cj = c(2,ind);
+
+      ## due to rounding errors some elements of ci and cj
+      ## can fall out of the range of ii and jj and interp2 would
+      ## return NA for those values. 
+      ## The permitted range is enforced here: 
+        
+      ci = max (ci, 1); ci = min (ci, size (z, 2));
+      cj = max (cj, 1); cj = min (cj, size (z, 1));
+        
+      c(1, ind) = interp2 (ii, jj, x, ci, cj);
+      c(2, ind) = interp2 (ii, jj, y, ci, cj);
+      
+      i = i + clen + 1;
+    endwhile
+  endif
+    
+  if (nargout > 0)
+    cout = c;
+    lev = vv;
+  endif
+
+endfunction
+
+%!test
+%! x = 0:2;
+%! y = x;
+%! z = x' * y;
+%! [c_actual, lev_actual]= contourc (x, y, z, 2:3);
+%! c_expected = [2, 1, 1, 2, 2, 3, 1.5, 2; 4, 2, 2, 1, 1, 2, 2, 1.5];
+%! lev_expected = [2 3];
+%! assert (c_actual, c_expected, eps)
+%! assert (lev_actual, lev_expected, eps)
+
+
diff --git a/scripts/plot/contourf.m b/scripts/plot/contourf.m
new file mode 100644
index 0000000..0ab605e
--- /dev/null
+++ b/scripts/plot/contourf.m
@@ -0,0 +1,90 @@
+## Copyright (C) 2007, 2008, 2009 Kai Habel
+## Copyright (C) 2003 Shai Ayal
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z}, @var{lvl})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z}, @var{n})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z}, @var{n})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z}, @var{lvl})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{z})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@var{ax}, @dots{})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contourf (@dots{}, @var{"property"}, @var{val})
+## Compute and plot filled contours of the matrix @var{z}.
+## Parameters @var{x}, @var{y} and @var{n} or @var{lvl} are optional.
+##
+## The return value @var{c} is a 2xn matrix containing the contour lines
+## as described in the help to the contourc function.
+##
+## The return value @var{h} is handle-vector to the patch objects creating
+## the filled contours.
+##
+## If @var{x} and @var{y} are omitted they are taken as the row/column
+## index of @var{z}.  @var{n} is a scalar denoting the number of lines
+## to compute.  Alternatively @var{lvl} is a vector containing the
+## contour levels.  If only one value (e.g., lvl0) is wanted, set
+## @var{lvl} to [lvl0, lvl0].  If both @var{n} or @var{lvl} are omitted
+## a default value of 10 contour level is assumed.
+##
+## If provided, the filled contours are added to the axes object
+## @var{ax} instead of the current axis.
+##
+## The following example plots filled contours of the @code{peaks}
+## function.
+## @example
+## @group
+## [x, y, z] = peaks (50);
+## contourf (x, y, z, -7:9)
+## @end group
+## @end example
+## @seealso{contour, contourc, patch}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+## Author: Shai Ayal <shaiay at users.sourceforge.net>
+
+function [c, h] = contourf (varargin)
+
+  [xh, varargin] = __plt_get_axis_arg__ ("contour", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (xh);
+    newplot ();
+    [ctmp, htmp] = __contour__ (xh, "none", "fill", "on",
+				"linecolor", "black", varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    c = ctmp;
+    h = htmp;
+  endif
+endfunction
+
+%!demo
+%! [x, y, z] = peaks (50);
+%! contourf (x, y, z, -7:9)
+
+%!demo
+%! [theta, r] = meshgrid (linspace (0, 2*pi, 64), linspace(0,1,64));
+%! [X, Y] = pol2cart (theta, r);
+%! Z = sin(2*theta).*(1-r);
+%! contourf(X, Y, abs(Z), 10)
diff --git a/scripts/plot/cylinder.m b/scripts/plot/cylinder.m
new file mode 100644
index 0000000..d83f6bd
--- /dev/null
+++ b/scripts/plot/cylinder.m
@@ -0,0 +1,90 @@
+## Copyright (C) 2007, 2009 Michael Goffioul and Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cylinder
+## @deftypefnx {Function File} {} cylinder (@var{r})
+## @deftypefnx {Function File} {} cylinder (@var{r}, @var{n})
+## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} cylinder (@dots{})
+## @deftypefnx {Function File} {} cylinder (@var{ax}, @dots{})
+## Generates three matrices in @code{meshgrid} format, such that
+## @code{surf (@var{x}, @var{y}, @var{z})} generates a unit cylinder.
+## The matrices are of size @code{@var{n}+1}-by- at code{@var{n}+1}. 
+## @var{r} is a vector containing the radius along the z-axis.
+## If @var{n} or @var{r} are omitted then default values of 20 or [1 1]
+## are assumed.
+##
+## Called with no return arguments, @code{cylinder} calls directly
+## @code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle @var{ax}
+## is passed as the first argument, the surface is plotted to this set
+## of axes.
+##
+## Examples:
+## @example
+## @group
+## disp ("plotting a cone")
+## [x, y, z] = cylinder (10:-1:0,50);
+## surf (x, y, z);
+## @end group
+## @end example
+## @seealso{sphere}
+## @end deftypefn
+
+function [xx, yy, zz] = cylinder (varargin)
+
+  [ax, args, nargs] = __plt_get_axis_arg__ ((nargout > 0), "cylinder", 
+					    varargin{:});
+
+  if (nargs == 0)
+    n = 20;
+    r = [1, 1];
+  elseif (nargs == 1)
+    n = 20;
+    r = args{1};
+  elseif (nargs == 2)
+    r = args{1};
+    n = args{2};
+  else
+    print_usage ();
+  endif
+
+  if (length (r) < 2)
+    error ("cylinder: length(r) must be larger than 2")
+  endif
+
+  phi = linspace (0, 2*pi, n+1);
+  idx = 1:length(r);
+  [phi, idx] = meshgrid(phi, idx);
+  z = (idx - 1) / (length(r) - 1);
+  r = r(idx);
+  [x, y] = pol2cart (phi, r);
+
+  if (nargout > 0)
+    xx = x;
+    yy = y;
+    zz = z;
+  else
+    surf (ax, x, y, z);
+  endif
+
+endfunction
+
+%!demo
+%! disp ("plotting a cone")
+%! [x, y, z] = cylinder (10:-1:0,50);
+%! surf (x, y, z);
diff --git a/scripts/plot/diffuse.m b/scripts/plot/diffuse.m
new file mode 100644
index 0000000..2434e28
--- /dev/null
+++ b/scripts/plot/diffuse.m
@@ -0,0 +1,58 @@
+## Copyright (C) 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} diffuse (@var{sx}, @var{sy}, @var{sz}, @var{l})
+## Calculate diffuse reflection strength of a surface defined by the normal
+## vector elements @var{sx}, @var{sy}, @var{sz}. 
+## The light vector can be specified using parameter @var{L}.  It can be
+## given as 2-element vector [azimuth, elevation] in degrees or as 3-element
+## vector [lx, ly, lz]. 
+## @seealso{specular, surfl}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function retval = diffuse (sx, sy, sz, lv)
+
+  if (nargin != 4)
+    print_usage ();
+  endif
+
+  ## check for normal vector
+  if (!size_equal (sx, sy, sz))
+    error ("diffuse: SX, SY, and SZ must have same size");
+  endif
+  
+  ## check for light vector (lv) argument
+  if (length (lv) < 2 || length (lv) > 3)
+    error ("diffuse: light vector LV must be a 2- or 3-element vector");
+  elseif (length (lv) == 2)
+    [lv(1), lv(2), lv(3)] = sph2cart (lv(1) * pi/180, lv(2) * pi/180, 1.0);
+  endif
+
+  ## Normalize view and light vector.
+  if (sum (abs (lv)) > 0)
+    lv  /= norm (lv);
+  endif
+
+  ns = sqrt (sx.^2 + sy.^2 + sz.^2);
+  retval = (sx * lv(1) + sy * lv(2) + sz * lv(3)) ./ ns;
+  retval(retval < 0) = 0;
+  
+endfunction
diff --git a/scripts/plot/ellipsoid.m b/scripts/plot/ellipsoid.m
new file mode 100644
index 0000000..2643b3a
--- /dev/null
+++ b/scripts/plot/ellipsoid.m
@@ -0,0 +1,73 @@
+## Copyright (C) 2007, 2008, 2009 Sylvain Pelissier
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} ellipsoid (@var{xc}, at var{yc}, @var{zc}, @var{xr}, @var{yr}, @var{zr}, @var{n})
+## @deftypefnx {Function File} {} ellipsoid (@var{h}, @dots{})
+## Generate three matrices in @code{meshgrid} format that define an
+## ellipsoid.  Called with no return arguments, @code{ellipsoid} calls
+## directly @code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle
+## is passed as the first argument, the surface is plotted to this
+## set of axes.
+## @seealso{sphere}
+## @end deftypefn
+
+## Author: Sylvain Pelissier <sylvain.pelissier at gmail.com>
+
+function [xx, yy, zz] = ellipsoid (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ((nargout > 0), "ellipsoid", 
+						varargin{:});
+
+  if (nargin != 6 && nargin != 7)
+    print_usage ();
+  endif
+
+  xc = varargin{1};
+  yc = varargin{2};
+  zc = varargin{3};
+  xr = varargin{4};
+  yr = varargin{5};
+  zr = varargin{6};
+
+  if (nargin == 6)
+    n = 20;
+  else
+    n = varargin{7};
+  endif
+
+  theta = linspace (0, 2 * pi, n + 1);
+  phi = linspace (-pi / 2, pi / 2, n + 1);
+  [theta, phi] = meshgrid (theta, phi);
+
+  x = xr .* cos (phi) .* cos (theta) + xc;
+  y = yr .* cos (phi) .* sin (theta) + yc;
+  z = zr .* sin (phi) + zc;
+
+  if (nargout > 0)
+    xx = x;
+    yy = y;
+    zz = z;
+  else
+    surf (h, x, y, z);
+  endif
+
+endfunction
+
+%!demo
+%! ellipsoid (0, 0, 1, 2, 3, 4, 20);
diff --git a/scripts/plot/errorbar.m b/scripts/plot/errorbar.m
new file mode 100644
index 0000000..7491578
--- /dev/null
+++ b/scripts/plot/errorbar.m
@@ -0,0 +1,140 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
+##               2009 Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} errorbar (@var{args})
+## This function produces two-dimensional plots with errorbars.  Many
+## different combinations of arguments are possible.  The simplest form is
+##
+## @example
+## errorbar (@var{y}, @var{ey})
+## @end example
+##
+## @noindent
+## where the first argument is taken as the set of @var{y} coordinates
+## and the second argument @var{ey} is taken as the errors of the
+## @var{y} values.  @var{x} coordinates are taken to be the indices
+## of the elements, starting with 1.
+##
+## If more than two arguments are given, they are interpreted as
+##
+## @example
+## errorbar (@var{x}, @var{y}, @dots{}, @var{fmt}, @dots{})
+## @end example
+##
+## @noindent
+## where after @var{x} and @var{y} there can be up to four error
+## parameters such as @var{ey}, @var{ex}, @var{ly}, @var{uy}, etc.,
+## depending on the plot type.  Any number of argument sets may appear,
+## as long as they are separated with a format string @var{fmt}.
+##
+## If @var{y} is a matrix, @var{x} and error parameters must also be matrices
+## having same dimensions.  The columns of @var{y} are plotted versus the
+## corresponding columns of @var{x} and errorbars are drawn from
+## the corresponding columns of error parameters.
+##
+## If @var{fmt} is missing, yerrorbars ("~") plot style is assumed.
+##
+## If the @var{fmt} argument is supplied, it is interpreted as in
+## normal plots.  In addition the following plot styles are supported by
+## errorbar:
+##
+## @table @samp
+## @item ~
+## Set yerrorbars plot style (default).
+##
+## @item >
+## Set xerrorbars plot style.
+##
+## @item ~>
+## Set xyerrorbars plot style.
+##
+## @item #
+## Set boxes plot style.
+##
+## @item #~
+## Set boxerrorbars plot style.
+##
+## @item #~>
+## Set boxxyerrorbars plot style.
+## @end table
+##
+## Examples:
+##
+## @example
+## errorbar (@var{x}, @var{y}, @var{ex}, ">")
+## @end example
+##
+## produces an xerrorbar plot of @var{y} versus @var{x} with @var{x}
+## errorbars drawn from @var{x}- at var{ex} to @var{x}+ at var{ex}.
+##
+## @example
+## @group
+## errorbar (@var{x}, @var{y1}, @var{ey}, "~",
+##           @var{x}, @var{y2}, @var{ly}, @var{uy})
+## @end group
+## @end example
+##
+## produces yerrorbar plots with @var{y1} and @var{y2} versus @var{x}.
+## Errorbars for @var{y1} are drawn from @var{y1}- at var{ey} to
+## @var{y1}+ at var{ey}, errorbars for @var{y2} from @var{y2}- at var{ly} to
+## @var{y2}+ at var{uy}.
+##
+## @example
+## @group
+## errorbar (@var{x}, @var{y}, @var{lx}, @var{ux},
+##           @var{ly}, @var{uy}, "~>")
+## @end group
+## @end example
+##
+## produces an xyerrorbar plot of @var{y} versus @var{x} in which
+## @var{x} errorbars are drawn from @var{x}- at var{lx} to @var{x}+ at var{ux}
+## and @var{y} errorbars from @var{y}- at var{ly} to @var{y}+ at var{uy}.
+## @seealso{semilogxerr, semilogyerr, loglogerr}
+## @end deftypefn
+
+## Created: 18.7.2000
+## Author: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function retval = errorbar (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("errorbar", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    tmp = __errcomm__ ("errorbar", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
+
+%!demo
+%! errorbar(0:10,rand(1,11),0.25*rand(1,11))
+
+%!demo
+%! errorbar(0:10,rand(1,11),rand(1,11), ">")
diff --git a/scripts/plot/ezcontour.m b/scripts/plot/ezcontour.m
new file mode 100644
index 0000000..1244251
--- /dev/null
+++ b/scripts/plot/ezcontour.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezcontour (@var{f})
+## @deftypefnx {Function File} {} ezcontour (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezcontour (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezcontour (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezcontour (@dots{})
+##
+## Plots the contour lines of a function.  @var{f} is a string, inline function
+## or function handle with two arguments defining the function.  By default the
+## plot is over the domain @code{-2*pi < @var{x} < 2*pi} and @code{-2*pi < 
+## @var{y} < 2*pi} with 60 points in each dimension. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+## then the minimum and maximum value of @var{x} and @var{y} are specify
+## separately.
+##
+## @var{n} is a scalar defining the number of points to use in each dimension.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+## ezcontour (f, [-3, 3]);
+## @end group
+## @end example
+##
+## @seealso{ezplot, ezcontourf, ezsurfc, ezmeshc}
+## @end deftypefn
+
+function retval = ezcontour (varargin)
+
+  [h, needusage] = __ezplot__ ("contour", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+%! ezcontour (f, [-3, 3]);
diff --git a/scripts/plot/ezcontourf.m b/scripts/plot/ezcontourf.m
new file mode 100644
index 0000000..9f13a1a
--- /dev/null
+++ b/scripts/plot/ezcontourf.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezcontourf (@var{f})
+## @deftypefnx {Function File} {} ezcontourf (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezcontourf (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezcontourf (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezcontourf (@dots{})
+##
+## Plots the filled contour lines of a function.  @var{f} is a string, inline 
+## function or function handle with two arguments defining the function.  By 
+## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and 
+## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+## then the minimum and maximum value of @var{x} and @var{y} are specify
+## separately.
+##
+## @var{n} is a scalar defining the number of points to use in each dimension.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+## ezcontourf (f, [-3, 3]);
+## @end group
+## @end example
+##
+## @seealso{ezplot, ezcontour, ezsurfc, ezmeshc}
+## @end deftypefn
+
+function retval = ezcontourf (varargin)
+
+  [h, needusage] = __ezplot__ ("contourf", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+%! ezcontourf (f, [-3, 3]);
diff --git a/scripts/plot/ezmesh.m b/scripts/plot/ezmesh.m
new file mode 100644
index 0000000..6d506c0
--- /dev/null
+++ b/scripts/plot/ezmesh.m
@@ -0,0 +1,92 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezmesh (@var{f})
+## @deftypefnx {Function File} {} ezmesh (@var{fx}, @var{fy}, @var{fz})
+## @deftypefnx {Function File} {} ezmesh (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezmesh (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezmesh (@dots{}, 'circ')
+## @deftypefnx {Function File} {} ezmesh (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezmesh (@dots{})
+##
+## Plots the mesh defined by a function.  @var{f} is a string, inline
+## function or function handle with two arguments defining the function.  By 
+## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+## then the minimum and maximum value of @var{x} and @var{y} are specify
+## separately.
+##
+## @var{n} is a scalar defining the number of points to use in each dimension.
+##
+## If three functions are passed, then plot the parametrically defined 
+## function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+## @var{fz} (@var{s}, @var{t})]}. 
+##
+## If the argument 'circ' is given, then the function is plotted over a disk
+## centered on the middle of the domain @var{dom}.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+## ezmesh (f, [-3, 3]);
+## @end group
+## @end example
+##
+## An example of a parametrically defined function is
+##
+## @example
+## @group
+## fx = @@(s,t) cos (s) .* cos(t);
+## fy = @@(s,t) sin (s) .* cos(t);
+## fz = @@(s,t) sin(t);
+## ezmesh (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+## @end group
+## @end example
+##
+## @seealso{ezplot, ezsurf, ezsurfc, ezmeshc}
+## @end deftypefn
+
+function retval = ezmesh (varargin)
+
+  [h, needusage] = __ezplot__ ("mesh", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+%! ezmesh (f, [-3, 3]);
+
+%!demo
+%! fx = @(s,t) cos (s) .* cos(t);
+%! fy = @(s,t) sin (s) .* cos(t);
+%! fz = @(s,t) sin (t);
+%! ezmesh (fx, fy, fz, [-pi,pi,-pi/2,pi/2], 20);
diff --git a/scripts/plot/ezmeshc.m b/scripts/plot/ezmeshc.m
new file mode 100644
index 0000000..9bc6fb9
--- /dev/null
+++ b/scripts/plot/ezmeshc.m
@@ -0,0 +1,75 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezmeshc (@var{f})
+## @deftypefnx {Function File} {} ezmeshc (@var{fx}, @var{fy}, @var{fz})
+## @deftypefnx {Function File} {} ezmeshc (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezmeshc (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezmeshc (@dots{}, 'circ')
+## @deftypefnx {Function File} {} ezmeshc (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezmeshc (@dots{})
+##
+## Plots the mesh and contour lines defined by a function.  @var{f} is a string,
+## inline function or function handle with two arguments defining the function.
+## By default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+## then the minimum and maximum value of @var{x} and @var{y} are specify
+## separately.
+##
+## @var{n} is a scalar defining the number of points to use in each dimension.
+##
+## If three functions are passed, then plot the parametrically defined 
+## function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+## @var{fz} (@var{s}, @var{t})]}. 
+##
+## If the argument 'circ' is given, then the function is plotted over a disk
+## centered on the middle of the domain @var{dom}.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+## ezmeshc (f, [-3, 3]);
+## @end group
+## @end example
+##
+## @seealso{ezplot, ezsurfc, ezsurf, ezmesh}
+## @end deftypefn
+
+function retval = ezmeshc (varargin)
+
+  [h, needusage] = __ezplot__ ("meshc", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+%! ezmeshc (f, [-3, 3]);
diff --git a/scripts/plot/ezplot.m b/scripts/plot/ezplot.m
new file mode 100644
index 0000000..89b8b1f
--- /dev/null
+++ b/scripts/plot/ezplot.m
@@ -0,0 +1,89 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezplot (@var{f})
+## @deftypefnx {Function File} {} ezplot (@var{fx}, @var{fy})
+## @deftypefnx {Function File} {} ezplot (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezplot (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezplot (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezplot (@dots{})
+##
+## Plots in two-dimensions the curve defined by @var{f}.  The function
+## @var{f} may be a string, inline function or function handle and can
+## have either one or two variables.  If @var{f} has one variable, then 
+## the function is plotted over the domain @code{-2*pi < @var{x} < 2*pi}  
+## with 500 points. 
+##
+## If @var{f} has two variables then @code{@var{f}(@var{x}, at var{y}) = 0}
+## is calculated over the meshed domain @code{-2*pi < @var{x} | @var{y}
+## < 2*pi} with 60 by 60 in the mesh.  For example
+##
+## @example
+## ezplot (@@(@var{x}, @var{y}) @var{x} .^ 2 - @var{y} .^ 2 - 1)
+## @end example
+##
+## If two functions are passed as strings, inline functions or function
+## handles, then the parametric function
+##
+## @example
+## @group
+## @var{x} = @var{fx} (@var{t})
+## @var{y} = @var{fy} (@var{t})
+## @end group
+## @end example
+##
+## is plotted over the domain @code{-2*pi < @var{t} < 2*pi} with 500
+## points. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of @var{x}, @var{y} and @var{t}.  If it is a four element
+## vector, then the minimum and maximum values of @var{x} and @var{t}
+## are determined by the first two elements and the minimum and maximum
+## of @var{y} by the second pair of elements.
+##
+## @var{n} is a scalar defining the number of points to use in plotting
+## the function.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the line objects plotted.
+##
+## @seealso{plot, ezplot3}
+## @end deftypefn
+
+function retval = ezplot (varargin)
+
+  [h, needusage] = __ezplot__ ("plot", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! ezplot (@cos, @sin)
+
+%!demo
+%! ezplot ("1/x")
+
+%!demo
+%! ezplot (inline("x^2 - y^2 = 1"))
diff --git a/scripts/plot/ezplot3.m b/scripts/plot/ezplot3.m
new file mode 100644
index 0000000..9773187
--- /dev/null
+++ b/scripts/plot/ezplot3.m
@@ -0,0 +1,67 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezplot3 (@var{fx}, @var{fy}, @var{fz})
+## @deftypefnx {Function File} {} ezplot3 (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezplot3 (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezplot3 (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezplot3 (@dots{})
+##
+## Plots in three-dimensions the curve defined parametrically. 
+## @var{fx}, @var{fy}, and @var{fz} are strings, inline functions
+## or function handles with one arguments defining the function.  By 
+## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi}  
+## with 60 points. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of @var{t}.  @var{n} is a scalar defining the number of points to use.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## fx = @@(t) cos (t);
+## fy = @@(t) sin (t);
+## fz = @@(t) t;
+## ezplot3 (fx, fy, fz, [0, 10*pi], 100);
+## @end group
+## @end example
+##
+## @seealso{plot3, ezplot, ezsurf, ezmesh}
+## @end deftypefn
+
+function retval = ezplot3 (varargin)
+
+  [h, needusage] = __ezplot__ ("plot3", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! fx = @(t) cos (t);
+%! fy = @(t) sin (t);
+%! fz = @(t) t;
+%! ezplot3 (fx, fy, fz, [0, 10*pi], 100);
diff --git a/scripts/plot/ezpolar.m b/scripts/plot/ezpolar.m
new file mode 100644
index 0000000..db3a9c9
--- /dev/null
+++ b/scripts/plot/ezpolar.m
@@ -0,0 +1,59 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezpolar (@var{f})
+## @deftypefnx {Function File} {} ezpolar (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezpolar (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezpolar (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezpolar (@dots{})
+##
+## Plots in polar plot defined by a function.  The function @var{f} is either
+## a string, inline function or function handle with one arguments defining 
+## the function.  By default the plot is over the domain @code{0 < @var{x} < 
+## 2*pi} with 60 points. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{t}.  @var{n} is a scalar defining the number of points to 
+## use.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## ezpolar (@@(t) 1 + sin (t));
+## @end example
+##
+## @seealso{polar, ezplot, ezsurf, ezmesh}
+## @end deftypefn
+
+function retval = ezpolar (varargin)
+
+  [h, needusage] = __ezplot__ ("polar", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! ezpolar (@(t) 1 + sin (t));
diff --git a/scripts/plot/ezsurf.m b/scripts/plot/ezsurf.m
new file mode 100644
index 0000000..645fd3d
--- /dev/null
+++ b/scripts/plot/ezsurf.m
@@ -0,0 +1,92 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezsurf (@var{f})
+## @deftypefnx {Function File} {} ezsurf (@var{fx}, @var{fy}, @var{fz})
+## @deftypefnx {Function File} {} ezsurf (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezsurf (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezsurf (@dots{}, 'circ')
+## @deftypefnx {Function File} {} ezsurf (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezsurf (@dots{})
+##
+## Plots the surface defined by a function.  @var{f} is a string, inline
+## function or function handle with two arguments defining the function.  By 
+## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and
+## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+## then the minimum and maximum value of @var{x} and @var{y} are specify
+## separately.
+##
+## @var{n} is a scalar defining the number of points to use in each dimension.
+##
+## If three functions are passed, then plot the parametrically defined 
+## function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+## @var{fz} (@var{s}, @var{t})]}. 
+##
+## If the argument 'circ' is given, then the function is plotted over a disk
+## centered on the middle of the domain @var{dom}.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+## ezsurf (f, [-3, 3]);
+## @end group
+## @end example
+##
+## An example of a parametrically defined function is
+##
+## @example
+## @group
+## fx = @@(s,t) cos (s) .* cos(t);
+## fy = @@(s,t) sin (s) .* cos(t);
+## fz = @@(s,t) sin(t);
+## ezsurf (fx, fy, fz, [-pi, pi, -pi/2, pi/2], 20);
+## @end group
+## @end example
+##
+## @seealso{ezplot, ezmesh, ezsurfc, ezmeshc}
+## @end deftypefn
+
+function retval = ezsurf (varargin)
+
+  [h, needusage] = __ezplot__ ("surf", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+%! ezsurf (f, [-3, 3]);
+
+%!demo
+%! fx = @(s,t) cos (s) .* cos(t);
+%! fy = @(s,t) sin (s) .* cos(t);
+%! fz = @(s,t) sin (t);
+%! ezsurf (fx, fy, fz, [-pi,pi,-pi/2,pi/2], 20);
diff --git a/scripts/plot/ezsurfc.m b/scripts/plot/ezsurfc.m
new file mode 100644
index 0000000..6722a42
--- /dev/null
+++ b/scripts/plot/ezsurfc.m
@@ -0,0 +1,75 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezsurfc (@var{f})
+## @deftypefnx {Function File} {} ezsurfc (@var{fx}, @var{fy}, @var{fz})
+## @deftypefnx {Function File} {} ezsurfc (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezsurfc (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezsurfc (@dots{}, 'circ')
+## @deftypefnx {Function File} {} ezsurfc (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} ezsurfc (@dots{})
+##
+## Plots the surface and contour lines defined by a function.  @var{f} is a
+## string, inline function or function handle with two arguments defining the
+## function.  By default the plot is over the domain @code{-2*pi < @var{x} <
+## 2*pi} and @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension. 
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of both @var{x} and @var{y}.  If @var{dom} is a four element vector,
+## then the minimum and maximum value of @var{x} and @var{y} are specify
+## separately.
+##
+## @var{n} is a scalar defining the number of points to use in each dimension.
+##
+## If three functions are passed, then plot the parametrically defined 
+## function @code{[@var{fx} (@var{s}, @var{t}), @var{fy} (@var{s}, @var{t}), 
+## @var{fz} (@var{s}, @var{t})]}. 
+##
+## If the argument 'circ' is given, then the function is plotted over a disk
+## centered on the middle of the domain @var{dom}.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## f = @@(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+## ezsurfc (f, [-3, 3]);
+## @end group
+## @end example
+##
+## @seealso{ezplot, ezmeshc, ezsurf, ezmesh}
+## @end deftypefn
+
+function retval = ezsurfc (varargin)
+
+  [h, needusage] = __ezplot__ ("surfc", varargin{:});
+
+  if (needusage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = h;
+  endif
+endfunction
+
+%!demo
+%! f = @(x,y) sqrt(abs(x .* y)) ./ (1 + x.^2 + y.^2);
+%! ezsurfc (f, [-3, 3]);
diff --git a/scripts/plot/feather.m b/scripts/plot/feather.m
new file mode 100644
index 0000000..21a26d9
--- /dev/null
+++ b/scripts/plot/feather.m
@@ -0,0 +1,117 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} feather (@var{u}, @var{v})
+## @deftypefnx {Function File} {} feather (@var{z})
+## @deftypefnx {Function File} {} feather (@dots{}, @var{style})
+## @deftypefnx {Function File} {} feather (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} feather (@dots{})
+##
+## Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
+## from equidistant points on the x-axis.  If a single complex argument
+## @var{z} is given, then @code{@var{u} = real (@var{z})} and
+## @code{@var{v} = imag (@var{z})}.
+##
+## The style to use for the plot can be defined with a line style @var{style}
+## in a similar manner to the line styles used with the @code{plot} command.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## @example
+## @group
+## phi = [0 : 15 : 360] * pi / 180;
+## feather (sin (phi), cos (phi))
+## @end group
+## @end example
+##
+## @seealso{plot, quiver, compass}
+## @end deftypefn
+
+function retval = feather (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("feather", varargin{:});
+
+  arrowsize = 0.25;
+  firstnonnumeric = Inf;
+  for i = 1:nargin
+    if (! isnumeric (varargin{i}))
+      firstnonnumeric = i;
+      break;
+    endif
+  endfor
+
+  if (nargin < 2 || firstnonnumeric < 2)
+    ioff = 2;
+    z = varargin {1} (:) .';
+    u = real (z);
+    v = imag (z);
+  else
+    ioff = 3;
+    u = varargin {1} (:) .';
+    v = varargin {2} (:) .';
+  endif
+
+  line_spec = "b-";
+  while (ioff <= nargin)
+    arg = varargin{ioff++};
+    if ((ischar (arg) || iscell (arg)) && ! have_line_spec)
+      [linespec, valid] = __pltopt__ ("feather", arg, false);
+      if (valid)
+	line_spec = arg;
+	break;
+      else
+	error ("feather: invalid linespec");
+      endif
+    else
+      error ("feather: unrecognized argument");
+    endif
+  endwhile
+
+  ## Matlab draws feather plots, with the arrow head as one continous 
+  ## line, and each arrow separately. This is completely different than 
+  ## quiver and quite ugly.
+  n = length (u);
+  xend = [1 : n] + u;
+  xtmp = [1 : n] + u .* (1 - arrowsize);
+  yend = v;
+  ytmp = v .* (1 - arrowsize);
+  x = [[1 : n]; xend; xtmp  - v * arrowsize; xend; ...
+       xtmp + v * arrowsize];
+  y = [zeros(1, n); yend; ytmp  + u * arrowsize / 3; yend; ...
+       ytmp - u * arrowsize / 3];
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+    hlist = plot (h, x, y, line_spec, [1, n], [0, 0], line_spec);
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = hlist;
+  endif
+
+endfunction
+
+%!demo
+%! phi = [0 : 15 : 360] * pi / 180;
+%! feather (sin (phi), cos (phi))
diff --git a/scripts/plot/figure.m b/scripts/plot/figure.m
new file mode 100644
index 0000000..be45ebc
--- /dev/null
+++ b/scripts/plot/figure.m
@@ -0,0 +1,80 @@
+## Copyright (C) 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} figure (@var{n})
+## @deftypefnx {Function File} {} figure (@var{n}, @var{property}, @var{value}, @dots{})
+## Set the current plot window to plot window @var{n}.  If no arguments are
+## specified, the next available window number is chosen.
+##
+## Multiple property-value pairs may be specified for the figure, but they
+## must appear in pairs.
+## @end deftypefn
+
+## Author: jwe, Bill Denney
+
+function h = figure (varargin)
+
+  nargs = nargin;
+
+  f = NaN;
+
+  init_new_figure = false;
+  if (mod (nargs, 2) == 1)
+    tmp = varargin{1};
+    if (ishandle (tmp) && strcmp (get (tmp, "type"), "figure"))
+      f = tmp;
+      varargin(1) = [];
+      nargs--;
+    elseif (isnumeric (tmp) && tmp > 0 && round (tmp) == tmp)
+      f = tmp;
+      init_new_figure = true;
+      varargin(1) = [];
+      nargs--;
+    else
+      error ("figure: expecting figure handle or figure number");
+    endif
+  endif
+
+  ## Check to see if we already have a figure on the screen.  If we do,
+  ## then update it if it is different from the figure we are creating
+  ## or switching to.
+  cf = get (0, "currentfigure");
+  if (! isempty (cf) && cf != 0)
+    if (isnan (f) || cf != f)
+      drawnow ();
+    endif
+  endif
+
+  if (rem (nargs, 2) == 0)
+    if (isnan (f) || init_new_figure)
+      f = __go_figure__ (f, varargin{:});
+    elseif (nargs > 0)
+      set (f, varargin{:});
+    endif
+    set (0, "currentfigure", f);
+  else
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    h = f;
+  endif
+
+endfunction
diff --git a/scripts/plot/fill.m b/scripts/plot/fill.m
new file mode 100644
index 0000000..49e5672
--- /dev/null
+++ b/scripts/plot/fill.m
@@ -0,0 +1,118 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fill (@var{x}, @var{y}, @var{c})
+## @deftypefnx {Function File} {} fill (@var{x1}, @var{y1}, @var{c1}, @var{x2}, @var{y2}, @var{c2})
+## @deftypefnx {Function File} {} fill (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} fill (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} fill (@dots{})
+## Create one or more filled patch objects, returning a patch object for each.
+## @end deftypefn
+
+function retval = fill (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("fill", varargin{:});
+
+  htmp = [];
+  iargs = __find_patches__ (varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+
+    for i = 1 : length (iargs)
+      if (i == length (iargs))
+	args = varargin (iargs(i):end);
+      else
+        args = varargin (iargs(i):iargs(i+1)-1);
+      endif
+      newplot ();
+      [tmp, fail] = __patch__ (h, args{:});
+      if (fail)
+	print_usage();
+      endif
+      htmp (end + 1) = tmp;
+    endfor
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = htmp;
+  endif
+
+endfunction
+
+function iargs = __find_patches__ (varargin)
+  iargs = [];
+  i = 1;
+  while (i < nargin)
+    iargs (end + 1) = i;
+    if (ischar (varargin{i})
+	&& (strcmpi (varargin{i}, "faces")
+	    || strcmpi (varargin{i}, "vertices")))
+      i += 4;
+    elseif (isnumeric (varargin{i}))
+      i += 2;
+    endif
+
+    if (i <= nargin)
+      while (true);
+	if (ischar (varargin{i}) && 
+	    (strcmpi (varargin{i}, "faces")
+	     || strcmpi (varargin{i}, "vertices")))
+	  break;
+	elseif (isnumeric (varargin{i}))
+	  ## Assume its the colorspec
+	  i++;
+	  break;
+	elseif (ischar (varargin{i}))
+	  colspec = tolower (varargin{i});
+	  collen = length (colspec);
+
+	  if (strncmp (colspec, "blue", collen)
+	      || strncmp (colspec, "black", collen)
+	      || strncmp (colspec, "k", collen)
+	      || strncmp (colspec, "black", collen)
+	      || strncmp (colspec, "red", collen)
+	      || strncmp (colspec, "green", collen)
+	      || strncmp (colspec, "yellow", collen)
+	      || strncmp (colspec, "magenta", collen)
+	      || strncmp (colspec, "cyan", collen)
+	      || strncmp (colspec, "white", collen))
+	    i++;
+	    break;
+	  endif
+	else
+	  i += 2;
+	endif
+      endwhile
+    endif
+  endwhile
+endfunction
+
+%!demo
+%! clf
+%! t1 = (1/16:1/8:1)'*2*pi;
+%! t2 = ((1/16:1/8:1)' + 1/32)*2*pi;
+%! x1 = sin(t1) - 0.8;
+%! y1 = cos(t1);
+%! x2 = sin(t2) + 0.8;
+%! y2 = cos(t2);
+%! h = fill(x1,y1,'r',x2,y2,'g');
diff --git a/scripts/plot/findall.m b/scripts/plot/findall.m
new file mode 100644
index 0000000..89c02f6
--- /dev/null
+++ b/scripts/plot/findall.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} findall ()
+## @deftypefnx {Function File} {@var{h} =} findall (@var{prop_name}, @var{prop_value})
+## @deftypefnx {Function File} {@var{h} =} findall (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} findall (@var{h}, "-depth", @var{d}, @dots{})
+## Find object with specified property values including hidden handles.
+##
+## This function performs the same function as @code{findobj}, but it
+## includes hidden objects in its search.  For full documentation, see
+## @code{findobj}.
+## @seealso{get, set, findobj, allchild}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function h = findall (varargin)
+
+  unwind_protect
+    shh = get (0, "showhiddenhandles");
+    set (0, "showhiddenhandles", "on");
+    h = findobj (varargin{:});
+  unwind_protect_cleanup
+    set (0, "showhiddenhandles", shh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/findobj.m b/scripts/plot/findobj.m
new file mode 100644
index 0000000..cb2b90d
--- /dev/null
+++ b/scripts/plot/findobj.m
@@ -0,0 +1,244 @@
+## Copyright (C) 2007, 2008, 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} findobj ()
+## @deftypefnx {Function File} {@var{h} =} findobj (@var{prop_name}, @var{prop_value})
+## @deftypefnx {Function File} {@var{h} =} findobj ('-property', @var{prop_name})
+## @deftypefnx {Function File} {@var{h} =} findobj ('-regexp', @var{prop_name}, @var{pattern})
+## @deftypefnx {Function File} {@var{h} =} findobj ('flat', @dots{})
+## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, '-depth', @var{d}, @dots{})
+## Find object with specified property values.  The simplest form is
+##
+## @example
+## findobj (@var{prop_name}, @var{prop_Value})
+## @end example
+##
+## @noindent
+## which returns all of the handles to the objects with the name 
+## @var{prop_name} and the name @var{prop_Value}.  The search can be limited
+## to a particular object or set of objects and their descendants by 
+## passing a handle or set of handles @var{h} as the first argument to 
+## @code{findobj}.
+##
+## The depth of hierarchy of objects to which to search to can be limited
+## with the '-depth' argument.  To limit the number depth of the hierarchy
+## to search to @var{d} generations of children, and example is
+##
+## @example
+## findobj (@var{h}, '-depth', @var{d}, @var{prop_Name}, @var{prop_Value})
+## @end example
+##
+## Specifying a depth @var{d} of 0, limits the search to the set of object
+## passed in @var{h}.  A depth @var{d} of 0 is equivalent to the '-flat'
+## argument. 
+##
+## A specified logical operator may be applied to the pairs of @var{prop_Name}
+## and @var{prop_Value}.  The supported logical operators are '-and', '-or', 
+## '-xor', '-not'.
+##
+## The objects may also be matched by comparing a regular expression to the 
+## property values, where property values that match @code{regexp 
+## (@var{prop_Value}, @var{pattern})} are returned.  Finally, objects may be 
+## matched by property name only, using the '-property' option.
+## @seealso{get, set}
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+
+function h = findobj (varargin)
+
+  depth = NaN;
+  if (nargin == 0)
+    handles = 0;
+    n1 = 0;
+  else
+    if (! isempty (varargin{1}))
+      if (ishandle (varargin{1}(1)))
+        handles = varargin{1};
+        n1 = 2;
+      else
+        handles = 0;
+        n1 = 1;
+      endif
+    else
+      ## Return [](0x1) for compatibility.
+      h = zeros (0, 1);
+      return;
+    endif
+    if (n1 <= nargin)
+      if (ischar (varargin{n1}))
+	if (strcmpi (varargin{n1}, "flat"))
+	  depth = 0;
+	  n1 = n1 + 1;
+	elseif (strcmpi (varargin{n1}, "-depth"))
+	  depth = varargin{n1+1};
+	  n1 = n1 + 2;
+	endif
+      else
+	error ("findobj: properties and options must be strings");
+      endif
+    endif
+  endif
+
+  if (n1 <= nargin && nargin > 0)
+    args = varargin(n1 : nargin);
+  else
+    args = {};
+  endif
+
+  regularexpression = [];
+  property          = [];
+  logicaloperator   = {};
+  pname             = {};
+  pvalue            = {};
+  np = 1;
+  na = 1;
+
+  while (na <= numel (args))
+    regularexpression(np) = 0;
+    property(np) = 0;
+    logicaloperator{np} = "and";
+    if (ischar (args{na}))
+      if (strcmpi (args{na}, "-regexp"))
+	if (na + 2 <= numel (args))
+	  regularexpression(np) = 1;
+	  na = na + 1;
+	  pname{np} = args{na};
+	  na = na + 1;
+	  pvalue{np} = args{na};
+	  na = na + 1;
+	  np = np + 1;
+	else
+	  error ("findobj: inconsistent number of arguments");
+	endif
+      elseif (strcmpi (args{na}, "-property"))
+	if (na + 1 <= numel (args))
+	  na = na + 1;
+	  property(np) = 1;
+	  pname{np} = args{na};
+	  na = na + 1;
+	  pvalue{np} = [];
+	  np = np + 1;
+	else
+	  error ("findobj: inconsistent number of arguments");
+	endif
+      elseif (! strcmp (args{na}(1), "-"))
+	## Parameter/value pairs.
+	if (na + 1 <= numel (args))
+	  pname{np} = args{na};
+	  na = na + 1;
+	  pvalue{np} = args{na};
+	  na = na + 1;
+	  if (na <= numel(args))
+	    if (ischar (args{na}))
+	      if strcmpi(args{na}, "-and")
+		logicaloperator{np} = "and";
+		na = na+1;
+	      elseif strcmpi(args{na}, "-or")
+		logicaloperator{np} = "or";
+		na = na+1;
+	      elseif strcmpi(args{na}, "-xor")
+		logicaloperator{np} = "xor";
+		na = na+1;
+	      elseif strcmpi(args{na}, "-not")
+		logicaloperator{np} = "not";
+		na = na+1;
+	      endif
+	    else
+	      error ("findobj: properties and options must be strings");
+	    endif
+	  else
+	    logicaloperator{np} = "and";
+	  endif
+	  np = np + 1;
+	else
+	  error ("findobj: inconsistent number of arguments");
+	endif
+      else
+	## This is sloppy ... but works like Matlab.
+	if strcmpi(args{na}, "-not")
+	  h = [];
+	  return
+	endif
+	na = na + 1;
+      endif
+    else
+      error ("findobj: properties and options must be strings");
+    endif
+  endwhile
+
+  numpairs = np - 1;
+  
+  ## Load all objects which qualify for being searched.
+  idepth = 0;
+  h = handles;
+  while (numel (handles) && ! (idepth >= depth))
+    children = [];
+    for n = 1 : numel (handles)
+      children = union (children, get(handles(n), "children"));
+    endfor 
+    handles = children;
+    h = union (h, children);
+    idepth = idepth + 1;
+  endwhile
+
+  keepers = ones (size (h));
+  if (numpairs > 0)
+    for nh = 1 : numel(h)
+      p = get (h (nh));
+      for np = 1 : numpairs
+	fields = fieldnames (p);
+	fieldindex = find (strcmpi (fields, pname{np}), 1);
+	if (numel (fieldindex))
+          pname{np} = fields{fieldindex};
+          if (property(np))
+            match = 1;
+          else
+            if (regularexpression(np))
+	      match = regexp (p.(pname{np}), pvalue{np});
+              if isempty (match)
+                match = 0;
+              endif
+            elseif (numel (p.(pname{np})) == numel (pvalue{np}))
+	      if (ischar (pvalue{np}))
+		match = strcmpi (pvalue{np}, p.(pname{np}));
+	      else
+		match = (pvalue{np} == p.(pname{np}));
+	      endif
+            else
+	      match = 0;
+            endif
+            match = all (match);
+          endif
+          if (strcmpi (logicaloperator{np}, "not"))
+            keepers(nh) = ! keepers(nh) & ! match;
+          else
+            keepers(nh) = feval (logicaloperator{np}, keepers(nh), match);
+          endif
+	else
+	  keepers(nh) = 0;
+	endif
+      endfor
+    endfor
+  endif
+
+  h = h (keepers != 0);
+  h = reshape (h, [numel(h), 1]);
+endfunction
diff --git a/scripts/plot/fplot.m b/scripts/plot/fplot.m
new file mode 100644
index 0000000..1fa5be3
--- /dev/null
+++ b/scripts/plot/fplot.m
@@ -0,0 +1,127 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fplot (@var{fn}, @var{limits})
+## @deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{tol})
+## @deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{n})
+## @deftypefnx {Function File} {} fplot (@dots{}, @var{fmt})
+## Plot a function @var{fn}, within the defined limits.  @var{fn}
+## an be either a string, a function handle or an inline function.
+## The limits of the plot are given by @var{limits} of the form
+## @code{[@var{xlo}, @var{xhi}]} or @code{[@var{xlo}, @var{xhi},
+## @var{ylo}, @var{yhi}]}.  @var{tol} is the default tolerance to use for the
+## plot, and if @var{tol} is an integer it is assumed that it defines the 
+## number points to use in the plot.  The @var{fmt} argument is passed
+## to the plot command.
+##
+## @example
+## @group
+##    fplot ("cos", [0, 2*pi])
+##    fplot ("[cos(x), sin(x)]", [0, 2*pi])
+## @end group
+## @end example
+## @seealso{plot}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+
+function fplot (fn, limits, n, linespec)
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 3) 
+    n = 0.002; 
+  endif
+
+  have_linespec = true;
+  if (nargin < 4) 
+    have_linespec = false;
+  endif
+
+  if (ischar (n))
+    have_linespec = true;
+    linespec = n;
+    n = 0.002;
+  endif
+
+  if (strcmp (typeinfo (fn), "inline function"))
+    fn = vectorize (fn);
+    nam = formula (fn);
+  elseif (isa (fn, "function_handle"))
+    nam = func2str (fn);
+  elseif (all (isalnum (fn)))
+    nam = fn;
+  else
+    fn = vectorize (inline (fn));
+    nam = formula (fn);
+  endif
+
+  if (floor(n) != n)
+    tol = n;
+    x0 = linspace (limits(1), limits(2), 5)';
+    y0 = feval (fn, x0);
+    err0 = Inf;
+    n = 8;
+    x = linspace (limits(1), limits(2), n)';
+    y = feval (fn, x);
+
+    while (n < 2 .^ 20)
+      y00 = interp1 (x0, y0, x, "linear");
+      err = 0.5 * max (abs ((y00 - y) ./ (y00 + y))(:));
+      if (err == err0 || 0.5 * max (abs ((y00 - y) ./ (y00 + y))(:)) < tol)
+	break;
+      endif
+      x0 = x;
+      y0 = y;
+      err0 = err;
+      n = 2 * (n - 1) + 1;
+      x = linspace (limits(1), limits(2), n)';
+      y = feval (fn, x);
+    endwhile 
+  else
+    x = linspace (limits(1), limits(2), n)';
+    y = feval (fn, x);
+  endif
+
+  if (have_linespec)
+    plot (x, y, linespec);
+  else
+    plot (x, y);
+  endif
+
+  if (length (limits) > 2) 
+    axis (limits);
+  endif
+
+  if (isvector (y))
+    legend (nam);
+  else
+    for i = 1:columns (y)
+      nams{i} = sprintf ("%s(:,%i)", nam, i);
+    endfor
+    legend (nams{:});
+  endif
+endfunction
+
+%!demo
+%! fplot ("cos", [0, 2*pi])
+
+%!demo
+%! fplot ("[cos(x), sin(x)]", [0, 2*pi])
diff --git a/scripts/plot/gca.m b/scripts/plot/gca.m
new file mode 100644
index 0000000..1196dca
--- /dev/null
+++ b/scripts/plot/gca.m
@@ -0,0 +1,51 @@
+## Copyright (C) 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gca ()
+## Return a handle to the current axis object.  If no axis object
+## exists, create one and return its handle.  The handle may then be
+## used to examine or set properties of the axes.  For example,
+##
+## @example
+## @group
+## ax = gca ();
+## set (ax, "position", [0.5, 0.5, 0.5, 0.5]);
+## @end group
+## @end example
+##
+## @noindent
+## creates an empty axes object, then changes its location and size in
+## the figure window.
+## @seealso{get, set}
+## @end deftypefn
+
+## Author: jwe
+
+function h = gca ()
+
+  if (nargin == 0)
+    h = get (gcf (), "currentaxes");
+    if (isempty (h))
+      h = axes ();
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/gcbf.m b/scripts/plot/gcbf.m
new file mode 100644
index 0000000..1e599f4
--- /dev/null
+++ b/scripts/plot/gcbf.m
@@ -0,0 +1,33 @@
+## Copyright (C) 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{fig} =} gcbf ()
+## Return a handle to the figure containing the object whose callback
+## is currently executing.  If no callback is executing, this function
+## returns the empty matrix.  The handle returned by this function is
+## the same as the second output argument of gcbo.
+##
+##@seealso{gcf, gca, gcbo}
+##@end deftypefn
+
+function fig = gcbf ()
+
+  [dummy, fig] = gcbo ();
+
+endfunction
diff --git a/scripts/plot/gcbo.m b/scripts/plot/gcbo.m
new file mode 100644
index 0000000..4a93d3b
--- /dev/null
+++ b/scripts/plot/gcbo.m
@@ -0,0 +1,43 @@
+## Copyright (C) 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} gcbo ()
+## @deftypefnx {Function File} {[@var{h}, @var{fig}] =} gcbo ()
+## Return a handle to the object whose callback is currently
+## executing.  If no callback is executing, this function returns the
+## empty matrix.  This handle is obtained from the root object property
+## "CallbackObject".
+##
+## Additionally return the handle of the figure containing the
+## object whose callback is currently executing.  If no callback is
+## executing, the second output is also set to the empty matrix.
+##
+##@seealso{gcf, gca, gcbf}
+##@end deftypefn
+
+function [h, fig] = gcbo ()
+
+  h = get (0, "callbackobject");
+  fig = [];
+
+  if (! isempty (h) && nargout > 1)
+    fig = ancestor (h, "figure");
+  endif
+
+endfunction
diff --git a/scripts/plot/gcf.m b/scripts/plot/gcf.m
new file mode 100644
index 0000000..8620e03
--- /dev/null
+++ b/scripts/plot/gcf.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gcf ()
+## Return the current figure handle.  If a figure does not exist, create
+## one and return its handle.  The handle may then be used to examine or
+## set properties of the figure.  For example,
+##
+## @example
+## @group
+## fplot (@@sin, [-10, 10]);
+## fig = gcf ();
+## set (fig, "visible", "off");
+## @end group
+## @end example
+##
+## @noindent
+## plots a sine wave, finds the handle of the current figure, and then
+## makes that figure invisible.  Setting the visible property of the
+## figure to @code{"on"} will cause it to be displayed again.
+## @seealso{get, set}
+## @end deftypefn
+
+## Author: jwe, Bill Denney
+
+function h = gcf ()
+
+  if (nargin == 0)
+    h = get (0, "currentfigure");
+    if (isempty (h) || h == 0)
+      ## We only have a root figure object, so create a new figure
+      ## object and make it the current figure.
+      h = figure (1);
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/ginput.m b/scripts/plot/ginput.m
new file mode 100644
index 0000000..e9c19c5
--- /dev/null
+++ b/scripts/plot/ginput.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} ginput (@var{n})
+## Return which mouse buttons were pressed and keys were hit on the current
+## figure.  If @var{n} is defined, then wait for @var{n} mouse clicks
+## before returning.  If @var{n} is not defined, then @code{ginput} will
+## loop until the return key is pressed.
+## @end deftypefn
+
+function varargout = ginput (n)
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  f = gcf ();
+  drawnow ();
+  backend = (get (f, "__backend__"));
+
+  varargout = cell (1, nargout);
+  if (nargin == 0)
+    [varargout{:}] = feval (strcat ("__", backend, "_ginput__"), f);
+  else
+    [varargout{:}] = feval (strcat ("__", backend, "_ginput__"), f, n);
+  endif
+
+endfunction
diff --git a/scripts/plot/gnuplot_binary.in b/scripts/plot/gnuplot_binary.in
new file mode 100644
index 0000000..0e58c81
--- /dev/null
+++ b/scripts/plot/gnuplot_binary.in
@@ -0,0 +1,50 @@
+## Copyright (C) 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {@var{val} =} gnuplot_binary ()
+## @deftypefnx {Loadable Function} {@var{old_val} =} gnuplot_binary (@var{new_val})
+## Query or set the name of the program invoked by the plot command.
+## The default value @code{\"gnuplot\"}.  @xref{Installation}.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = gnuplot_binary (new_val)
+
+  persistent gp_binary = %OCTAVE_CONF_GNUPLOT%;
+
+  if (nargout > 0 || nargin == 0)
+    retval = gp_binary;
+  endif
+
+  if (nargin == 1)
+    if (ischar (new_val))
+      if (! isempty (new_val))
+	gp_binary = new_val;
+      else
+	error ("gnuplot_binary: value must not be empty");
+      endif
+    else
+      error ("gnuplot_binary: expecting arg to be a character string");
+    endif
+  elseif (nargin > 1)
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/gnuplot_drawnow.m b/scripts/plot/gnuplot_drawnow.m
new file mode 100644
index 0000000..90381e0
--- /dev/null
+++ b/scripts/plot/gnuplot_drawnow.m
@@ -0,0 +1,400 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} drawnow ()
+## Update and display the current graphics.
+##
+## Octave automatically calls drawnow just before printing a prompt,
+## when @code{sleep} or @code{pause} is called, or while waiting for
+## command-line input.
+## @end deftypefn
+
+## Author: jwe
+
+function gnuplot_drawnow (h, term, file, mono, debug_file)
+
+  if (nargin < 4)
+    mono = false;
+  endif
+
+  if (nargin >= 3 && nargin <= 5)
+    ## Produce various output formats, or redirect gnuplot stream to a
+    ## debug file.
+    plot_stream = [];
+    fid = [];
+    printing = ! output_to_screen (gnuplot_trim_term (term));
+    default_plot_stream = get (h, "__plot_stream__");
+    unwind_protect
+      plot_stream = __gnuplot_open_stream__ (2, h);
+      if (__gnuplot_has_feature__ ("variable_GPVAL_TERMINALS"))
+        available_terminals = __gnuplot_get_var__ (plot_stream, "GPVAL_TERMINALS");
+        available_terminals = regexp (available_terminals, "\\b\\w+\\b", "match");
+        gnuplot_supports_term = any (strcmpi (available_terminals,
+                                              gnuplot_trim_term (term)));
+      else
+        gnuplot_supports_term = true;
+      endif
+      if (gnuplot_supports_term)
+        [enhanced, implicit_margin] = gnuplot_set_term (plot_stream (1), true,
+                                                        h, term, file);
+        __go_draw_figure__ (h, plot_stream(1), enhanced, mono, printing, implicit_margin);
+        if (nargin == 5)
+          fid = fopen (debug_file, "wb");
+          [enhanced, implicit_margin] = gnuplot_set_term (fid, true, h, term, file);
+          __go_draw_figure__ (h, fid, enhanced, mono, printing, implicit_margin);
+        endif
+      else
+        error ("gnuplot_drawnow: the gnuplot terminal, \"%s\", is not available.",
+               gnuplot_trim_term (term))
+      endif
+    unwind_protect_cleanup
+      set (h, "__plot_stream__", default_plot_stream);
+      if (! isempty (plot_stream))
+        pclose (plot_stream(1));
+        if (numel (plot_stream) > 1)
+          pclose (plot_stream(2));
+        endif
+	if (numel (plot_stream) > 2)
+	  waitpid (plot_stream(3));
+	endif
+      endif
+      if (! isempty (fid))
+        fclose (fid);
+      endif
+    end_unwind_protect
+  elseif (nargin == 1)
+    ##  Graphics terminal for display.
+    plot_stream = get (h, "__plot_stream__");
+    if (isempty (plot_stream))
+      plot_stream = __gnuplot_open_stream__ (2, h);
+      new_stream = true;
+    else
+      new_stream = false;
+    endif
+    term = gnuplot_default_term ();
+    if (strcmp (term, "dumb"))
+      ## popen2 eats stdout of gnuplot, use temporary file instead
+      dumb_tmp_file = tmpnam ();
+      enhanced = gnuplot_set_term (plot_stream (1), new_stream, h, ...
+                                   term, dumb_tmp_file);
+    else
+      enhanced = gnuplot_set_term (plot_stream (1), new_stream, h, term);
+    end
+    __go_draw_figure__ (h, plot_stream (1), enhanced, mono, 0);
+    fflush (plot_stream (1));
+    if (strcmp (term, "dumb"))
+      fid = -1;
+      while (fid < 0)
+        pause (0.1);
+        fid = fopen (dumb_tmp_file, 'r');
+      endwhile
+      ## reprint the plot on screen
+      [a, count] = fscanf (fid, '%c', Inf);
+      puts (a);
+      fclose (fid);
+      unlink (dumb_tmp_file);
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+function implicit_margin = gnuplot_implicit_margin (term, opts_str)
+  ## gnuplot has an implicit margin of 50pts for PS output.
+  if (strcmpi (term, "postscript"))
+    if (isempty (strfind (opts_str, " eps"))
+        && isempty (strfind (opts_str, "eps ")))
+      implicit_margin = 50/72;
+    else
+      ## When zero, the behavior of gnuplot changes.
+      implicit_margin = 1/72;
+    endif
+  else
+    implicit_margin = 0.0;
+  endif
+endfunction
+
+function [enhanced, implicit_margin] = gnuplot_set_term (plot_stream, new_stream, h, term, file)
+  ## Generate the gnuplot "set terminal <term> ..." command.
+  ## When "term" originates from print.m, it may include other options.
+  if (nargin < 4)
+    ## This supports the gnuplot backend.
+    term = gnuplot_default_term ();
+    opts_str = "";
+  else
+    ## Get the one word terminal id and save the remaining as options to
+    ## be passed on to gnuplot.  The terminal may respect the backend.
+    [term, opts_str] = gnuplot_trim_term (term);
+    if (strcmpi (term, "pdf") && strcmpi (opts_str, "color"))
+      ## FIXME -- "color" for the pdf terminal produces a gnuplot error.
+      opts_str = "";
+    endif
+  endif
+
+  implicit_margin = gnuplot_implicit_margin (term, opts_str);
+
+  enhanced = gnuplot_is_enhanced_term (term);
+
+  ## Set the terminal.
+  if (! isempty (term))
+
+    if (enhanced)
+      enh_str = "enhanced";
+    else
+      enh_str = "";
+    endif
+
+    if (! isempty (h) && isfigure (h))
+
+      ## Generate gnuplot title string for backend plot windows.
+      if (output_to_screen (term) && ~strcmp (term, "dumb"))
+        fig.numbertitle = get (h, "numbertitle");
+        fig.name = get (h, "name");
+        if (strcmpi (get (h, "numbertitle"), "on"))
+          title_str = sprintf ("Figure %d", h);
+        else
+          title_str = "";
+        endif
+        if (! isempty (fig.name) && ! isempty (title_str))
+          title_str = sprintf ("%s: %s", title_str, fig.name);
+        elseif (! isempty (fig.name) && isempty (title_str))
+          title_str = fig.name;
+        endif
+        if (! isempty (title_str))
+          title_str = sprintf ("title \"%s\"", title_str);
+        endif
+      else
+        title_str = "";
+      endif
+      if (! (any (strfind (opts_str, " size ") > 0) 
+	  || any (strfind (opts_str, "size ") == 1)))
+        ## Convert position to units used by gnuplot.
+        if (output_to_screen (term))
+          ## Get figure size in pixels.  Rely on listener
+	  ## to handle coversion of position property.
+	  units = get (h, "units");
+	  unwind_protect
+	    set (h, "units", "pixels");
+	    position_in_pixesl = get (h, "position");
+	  unwind_protect_cleanup
+	    set (h, "units", units);
+	  end_unwind_protect
+	  gnuplot_pos = position_in_pixesl(1:2);
+	  gnuplot_size = position_in_pixesl(3:4);
+        else
+          ## Get size of the printed plot in inches. Rely on listener
+	  ## to handle coversion of papersize property.
+	  paperunits = get (h, "paperunits");
+	  unwind_protect
+	    set (h, "paperunits", "inches");
+            gnuplot_size = get (h, "papersize");
+	  unwind_protect_cleanup
+	    set (h, "paperunits", paperunits);
+	  end_unwind_protect
+          if (term_units_are_pixels (term))
+	    ## Convert to inches using the property set by print().
+	    gnuplot_size = gnuplot_size * get (h, "__pixels_per_inch__");
+	  else
+	    ## Implicit margins are in units of "inches"
+	    gnuplot_size = gnuplot_size - implicit_margin;
+          endif
+        endif
+	[begin_match, end_match, te, match] = regexp (opts_str, "(\\s-r\\d+)|(^-r\\d+)");
+	if (! isempty (begin_match))
+	  error ("gnuplot_drawnow.m: specifying resultion, '%s', not supported for terminal '%s'",
+	         strtrim (match{1}), term)
+	endif
+        if (all (gnuplot_size > 0))
+          ## Set terminal size.
+          terminals_with_size = {"emf", "gif", "jpeg", "latex", "pbm", ...
+                                 "pdf", "png", "postscript", "svg", ...
+                                 "epslatex", "pstex", "pslatex"};
+          if (__gnuplot_has_feature__ ("x11_figure_position"))
+            terminals_with_size{end+1} = "x11";
+          endif
+          if (__gnuplot_has_feature__ ("wxt_figure_size"))
+            terminals_with_size{end+1} = "wxt";
+          endif
+          if (any (strncmpi (term, terminals_with_size, 3)))
+	    if (term_units_are_pixels (term))
+              size_str = sprintf ("size %d,%d", gnuplot_size);
+	    else
+              size_str = sprintf ("size %.15g,%.15g", gnuplot_size);
+	    endif
+            if (strncmpi (term, "X11", 3) && __gnuplot_has_feature__ ("x11_figure_position"))
+	      ## X11 allows the window to be positioned as well.
+	      units = get (0, "units");
+	      unwind_protect
+	        set (0, "units", "pixels");
+	        screen_size = get (0, "screensize")(3:4);
+	      unwind_protect_cleanup
+	        set (0, "units", units);
+	      end_unwind_protect
+              if (all (screen_size > 0))
+                ## For X11, set the figure positon as well as the size
+                ## gnuplot position is UL, Octave's is LL (same for screen/window)
+                gnuplot_pos(2) = screen_size(2) - gnuplot_pos(2) - gnuplot_size(2);
+                gnuplot_pos = max (gnuplot_pos, 1);
+                size_str = sprintf ("%s position %d,%d", size_str, 
+                                    gnuplot_pos(1), gnuplot_pos(2));
+              endif
+            endif
+          elseif (strncmpi (term, "aqua", 3))
+            ## Aqua has size, but the format is different.
+            size_str = sprintf ("size %d %d", gnuplot_size);
+          elseif (strncmpi (term, "dumb", 3))
+            new_stream = 1;
+            if (~isempty (getenv ("COLUMNS")) && ~isempty (getenv ("LINES")))
+              ## Let dumb use full text screen size.
+              size_str = ["size ", getenv("COLUMNS"), " ", getenv("LINES")];
+            else
+	      ## Use the gnuplot default.
+              size_str = "";
+            end
+          elseif (strncmpi (term, "fig", 3))
+            ## Fig also has size, but the format is different.
+            size_str = sprintf ("size %.15g %.15g", gnuplot_size);
+          elseif (any (strncmpi (term, {"corel", "hpgl"}, 3)))
+            ## The size for corel and hpgl are goes at the end (implicit).
+            size_str = sprintf ("%.15g %.15g", gnuplot_size);
+          elseif (any (strncmpi (term, {"dxf"}, 3)))
+            ## DXF uses autocad units.
+            size_str = "";
+          else
+            size_str = "";
+          endif
+        else
+          size_str = "";
+	  warning ("gnuplot_set_term: size is zero")
+        endif
+      else
+        ## A specified size take priority over the figure properies.
+        size_str = "";
+      endif
+    else
+      if isempty (h)
+        disp ("gnuplot_set_term: figure handle is empty")
+      elseif !isfigure(h)
+        disp ("gnuplot_set_term: not a figure handle")
+      endif
+      title_str = "";
+      size_str = "";
+    endif
+
+    ## Set the gnuplot terminal (type, enhanced, title, options & size).
+    term_str = sprintf ("set terminal %s", term);
+    if (! isempty (enh_str))
+      term_str = sprintf ("%s %s", term_str, enh_str);
+    endif
+    if (! isempty (title_str))
+      term_str = sprintf ("%s %s", term_str, title_str);
+    endif
+    if (nargin > 3 && ischar (opts_str))
+      ## Options must go last.
+      term_str = sprintf ("%s %s", term_str, opts_str);
+    endif
+    if (! isempty (size_str) && new_stream)
+      ## size_str comes after other options to permit specification of
+      ## the canvas size for terminals cdr/corel.
+      term_str = sprintf ("%s %s", term_str, size_str);
+    endif
+    ## Work around the gnuplot feature of growing the x11 window and
+    ## flickering window (x11, windows, & wxt) when the mouse and
+    ## multiplot are set in gnuplot.
+    fputs (plot_stream, "unset multiplot;\n");
+    flickering_terms = {"x11", "windows", "wxt", "dumb"};
+    if (! any (strcmp (term, flickering_terms))
+        || numel (findall (h, "type", "axes")) > 1
+        || numel (findall (h, "type", "image")) > 0)
+      fprintf (plot_stream, "%s\n", term_str);
+      if (nargin == 5)
+        if (! isempty (file))
+          fprintf (plot_stream, "set output '%s';\n", file);
+        endif
+      endif
+      fputs (plot_stream, "set multiplot;\n");
+    elseif (any (strcmp (term, flickering_terms)))
+      fprintf (plot_stream, "%s\n", term_str);
+      if (nargin == 5)
+        if (! isempty (file))
+          fprintf (plot_stream, "set output '%s';\n", file);
+        endif
+      endif
+    endif
+  else
+    ## gnuplot will pick up the GNUTERM environment variable itself
+    ## so no need to set the terminal type if not also setting the
+    ## figure title, enhanced mode, or position.
+  endif
+
+endfunction
+
+function term = gnuplot_default_term ()
+  term = getenv ("GNUTERM");
+  ## If not specified, guess the terminal type.
+  if (isempty (term))
+    if (ismac ())
+      term = "aqua";
+    elseif (! isunix ())
+      term = "windows";
+    elseif (! isempty (getenv ("DISPLAY")))
+      term = "x11";
+    else
+      term = "dumb";
+    endif
+  endif
+endfunction
+
+function [term, opts] = gnuplot_trim_term (string)
+  ## Extract the terminal type and terminal options (from print.m)
+  string = deblank (string);
+  n = strfind (string, ' ');
+  if (isempty (n))
+    term = string;
+    opts = "";
+  else
+    term = string(1:(n-1));
+    opts = string((n+1):end);
+  endif
+endfunction
+
+function have_enhanced = gnuplot_is_enhanced_term (term)
+  persistent enhanced_terminals;
+  if (isempty (enhanced_terminals))
+    ## Don't include pstex, pslatex or epslatex here as the TeX commands
+    ## should not be interpreted in that case.
+    enhanced_terminals = {"aqua", "dumb", "png", "jpeg", "gif", "pm", ...
+                          "windows", "wxt", "svg", "postscript", "x11", "pdf"};
+  endif
+  if (nargin < 1)
+    ## Determine the default gnuplot terminal.
+    term = gnuplot_default_term ();
+  endif
+  have_enhanced = any (strncmp (enhanced_terminals, term, min (numel (term), 3)));
+endfunction
+
+function ret = output_to_screen (term)
+  ret = any (strcmpi ({"aqua", "dumb", "wxt", "x11", "windows", "pm"}, term));
+endfunction
+
+function ret = term_units_are_pixels (term)
+  ret = any (strncmpi ({"emf", "gif", "jpeg", "pbm", "png", "svg"}, term, 3));
+endfunction
+
diff --git a/scripts/plot/grid.m b/scripts/plot/grid.m
new file mode 100644
index 0000000..5f6d086
--- /dev/null
+++ b/scripts/plot/grid.m
@@ -0,0 +1,122 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2003, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} grid (@var{arg})
+## @deftypefnx {Function File} {} grid ("minor", @var{arg2})
+## @deftypefnx {Function File} {} grid (@var{hax}, @dots{})
+## Force the display of a grid on the plot.
+## The argument may be either @code{"on"}, or @code{"off"}.
+## If it is omitted, the current grid state is toggled.
+##
+## If @var{arg} is @code{"minor"} then the minor grid is toggled.  When
+## using a minor grid a second argument @var{arg2} is allowed, which can
+## be either @code{"on"} or @code{"off"} to explicitly set the state of
+## the minor grid.
+##
+## If the first argument is an axis handle, @var{hax}, operate on the
+## specified axis object.
+## @seealso{plot}
+## @end deftypefn
+
+## Author: jwe
+
+function grid (varargin)
+
+  [ax, varargin, nargs] = __plt_get_axis_arg__ ("grid", varargin{:});
+
+  grid_on = (strcmp (get (ax, "xgrid"), "on")
+             && strcmp (get (ax, "ygrid"), "on")
+             && strcmp (get (ax, "zgrid"), "on"));
+
+  minor_on = (strcmp (get (ax, "xminorgrid"), "on")
+              && strcmp (get (ax, "yminorgrid"), "on")
+              && strcmp (get (ax, "zminorgrid"), "on"));
+
+  if (nargs > 2)
+    print_usage ();
+  elseif (nargs == 0)
+    grid_on = ! grid_on;
+  else
+    x = varargin{1};
+    if (ischar (x))
+      if (strcmpi (x, "off"))
+	grid_on = false;
+      elseif (strcmpi (x, "on"))
+	grid_on = true;
+      elseif (strcmpi (x, "minor"))
+        if (nargs == 2)
+	  x2 = varargin{2};
+	  if (strcmpi (x2, "on"))
+	    minor_on = true;
+	    grid_on = true;
+	  elseif (strcmpi (x2, "off"))
+	    minor_on = false;
+	  else
+	    print_usage ();
+	  endif
+	else
+	   minor_on = ! minor_on;
+	   if (minor_on)
+	     grid_on = true;
+	   endif
+	endif
+      else
+	print_usage ();
+      endif
+    else
+      error ("grid: argument must be a string");
+    endif
+  endif
+
+  if (grid_on)
+    set (ax, "xgrid", "on", "ygrid", "on", "zgrid", "on");
+    if (minor_on)
+      set (ax, "xminorgrid", "on", "yminorgrid", "on", "zminorgrid", "on");
+    else
+      set (ax, "xminorgrid", "off", "yminorgrid", "off", "zminorgrid", "off");
+    endif
+  else
+    set (ax, "xgrid", "off", "ygrid", "off", "zgrid", "off");
+    set (ax, "xminorgrid", "off", "yminorgrid", "off", "zminorgrid", "off");
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! subplot (2,2,1)
+%! plot (1:100)
+%! grid minor
+%! grid minor
+%! grid
+%! title ("no grid")
+%! subplot (2,2,2)
+%! plot (1:100)
+%! grid
+%! title ("grid on")
+%! subplot (2,2,3)
+%! plot (1:100)
+%! grid minor
+%! title ("grid minor")
+%! subplot (2,2,4)
+%! semilogy (1:100)
+%! grid minor
+%! title ("grid minor")
+
diff --git a/scripts/plot/gtext.m b/scripts/plot/gtext.m
new file mode 100644
index 0000000..387b996
--- /dev/null
+++ b/scripts/plot/gtext.m
@@ -0,0 +1,53 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} gtext (@var{s})
+## @deftypefnx {Function File} {} gtext (@{@var{s1}; @var{s2}; @dots{}@})
+## @deftypefnx {Function File} {} gtext (@dots{}, @var{prop}, @var{val})
+## Place text on the current figure using the mouse.  The text is defined
+## by the string @var{s}.  If @var{s} is a cell array, each element of the cell
+## array is written to a separate line.  Additional arguments are passed to
+## the underlying text object as properties.
+## @seealso{ginput, text}
+## @end deftypefn
+
+function gtext (s, varargin)
+
+  if (nargin > 0)
+    if (iscellstr (s))
+      if (isempty (s))
+	s = "";
+      else
+	s = sprintf ("%s\n", s{:});
+      endif
+    endif
+    if (ischar (s))
+      if (! isempty (s))
+	[x, y] = ginput (1);
+	text (x, y, s, varargin{:});
+      endif
+    else
+      error ("gtext: expecting a string or cell array of strings");
+    endif 
+  else
+    print_usage ();
+  endif
+
+endfunction
+
diff --git a/scripts/plot/hggroup.m b/scripts/plot/hggroup.m
new file mode 100644
index 0000000..a1e81ed
--- /dev/null
+++ b/scripts/plot/hggroup.m
@@ -0,0 +1,43 @@
+## Copyright (C) 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hggroup ()
+## @deftypefnx {Function File} {} hggroup (@var{h})
+## @deftypefnx {Function File} {} hggroup (@dots{}, @var{property}, @var{value}, @dots{})
+## Create group object with parent @var{h}.  If no parent is specified,
+## the group is created in the current axes.  Return the handle of the
+## group object created.
+##
+## Multiple property-value pairs may be specified for the group, but they
+## must appear in pairs.
+## @end deftypefn
+
+## Author: goffioul
+
+function h = hggroup (varargin)
+
+  [ax, varargin] = __plt_get_axis_arg__ ("hggroup", varargin{:});
+
+  tmp = __go_hggroup__ (ax, varargin{:});
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/hidden.m b/scripts/plot/hidden.m
new file mode 100644
index 0000000..62aa7c4
--- /dev/null
+++ b/scripts/plot/hidden.m
@@ -0,0 +1,77 @@
+## Copyright (C) 2007, 2008, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hidden (@var{mode})
+## @deftypefnx {Function File} {} hidden ()
+## Manipulation the mesh hidden line removal.  Called with no argument
+## the hidden line removal is toggled.  The argument @var{mode} can be either
+## 'on' or 'off' and the set of the hidden line removal is set accordingly.
+## @seealso{mesh, meshc, surf}
+## @end deftypefn
+
+function retval = hidden (mode)
+
+  if (nargin == 0)
+    mode = "swap";
+  elseif (nargin == 1);
+    if (ischar (mode))
+      mode = tolower (mode);
+      if (! strcmp (mode, "on") && ! strcmp (mode, "off"))
+	error ("hidden: mode expected to be 'on' or 'off'");
+      endif
+    else
+      error ("hidden: expecting mode to be a string");
+    endif
+  else
+    print_usage ();
+  endif
+
+  for h = get (gca (), "children");
+    htype = lower (get (h, "type"));
+    if (strcmp (htype, "surface"))
+      fc = get (h, "facecolor");
+      if ((! ischar (fc) && is_white (fc))
+	  || (ischar (fc) && strcmpi (fc, "none")))
+        switch (mode)
+        case "on"
+          set (h, "facecolor", "w");
+        case "off"
+          set (h, "facecolor", "none");
+        case "swap"
+          if (ischar (fc))
+            set (h, "facecolor", "w");
+	    mode = "on";
+          else
+            set (h, "facecolor", "none");
+	    mode = "off";
+          endif
+        endswitch
+      endif
+    endif
+  endfor
+
+  if (nargout > 0)
+    retval = mode;
+  endif
+
+endfunction
+
+function retval = is_white (color)
+  retval = all (color == 1);
+endfunction
diff --git a/scripts/plot/hist.m b/scripts/plot/hist.m
new file mode 100644
index 0000000..d666541
--- /dev/null
+++ b/scripts/plot/hist.m
@@ -0,0 +1,171 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+##               2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hist (@var{y}, @var{x}, @var{norm})
+## Produce histogram counts or plots.
+##
+## With one vector input argument, plot a histogram of the values with
+## 10 bins.  The range of the histogram bins is determined by the range
+## of the data.  With one matrix input argument, plot a histogram where
+## each bin contains a bar per input column.
+##
+## Given a second scalar argument, use that as the number of bins.
+##
+## Given a second vector argument, use that as the centers of the bins,
+## with the width of the bins determined from the adjacent values in
+## the vector.
+##
+## If third argument is provided, the histogram is normalized such that
+## the sum of the bars is equal to @var{norm}.
+##
+## Extreme values are lumped in the first and last bins.
+##
+## With two output arguments, produce the values @var{nn} and @var{xx} such
+## that @code{bar (@var{xx}, @var{nn})} will plot the histogram.
+## @seealso{bar}
+## @end deftypefn
+
+## Author: jwe
+
+function [nn, xx] = hist (y, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  arg_is_vector = isvector (y);
+
+  if (rows (y) == 1)
+    y = y(:);
+  endif
+
+  if (isreal (y))
+    max_val = max (y(:));
+    min_val = min (y(:));
+  else
+    error ("hist: first argument must be real valued");
+  endif
+
+  iarg = 1;
+  if (nargin == 1 || ischar (varargin{iarg}))
+    n = 10;
+    x = [0.5:n]'/n;
+    x = x * (max_val - min_val) + ones(size(x)) * min_val;
+  else
+    ## nargin is either 2 or 3
+    x = varargin{iarg++};
+    if (isscalar (x))
+      n = x;
+      if (n <= 0)
+        error ("hist: number of bins must be positive");
+      endif
+      x = [0.5:n]'/n;
+      x = x * (max_val - min_val) + ones (size (x)) * min_val;
+    elseif (isreal (x))
+      if (isvector (x))
+	x = x(:);
+      endif
+      tmp = sort (x);
+      if (any (tmp != x))
+        warning ("hist: bin values not sorted on input");
+        x = tmp;
+      endif
+    else
+      error ("hist: second argument must be a scalar or a vector");
+    endif
+  endif
+
+  ## Avoid issues with integer types for x and y
+  x = double (x);
+  y = double (y);
+
+  cutoff = (x(1:end-1,:) + x(2:end,:)) / 2;
+  n = rows (x);
+  y_nc = columns (y);
+  if (n < 30 && columns (x) == 1)
+    ## The following algorithm works fastest for n less than about 30.
+    chist = zeros (n+1, y_nc);
+    for i = 1:n-1
+      chist(i+1,:) = sum (y <= cutoff(i));
+    endfor
+    chist(n+1,:) = sum (! isnan (y));
+  else
+    ## The following algorithm works fastest for n greater than about 30.
+    ## Put cutoff elements between boundaries, integrate over all
+    ## elements, keep totals at boundaries.
+    [s, idx] = sort ([y; repmat(cutoff, 1, y_nc)]);
+    len = rows (y);
+    chist = cumsum (idx <= len);
+    chist = [(zeros (1, y_nc));
+	     (reshape (chist(idx > len), rows (cutoff), y_nc));
+	     (chist(end,:) - sum (isnan (y)))];
+  endif
+
+  freq = diff (chist);
+
+  if (nargin > 2 && ! ischar (varargin{iarg}))
+    ## Normalise the histogram.
+    norm = varargin{iarg++};
+    freq = freq / rows (y) * norm;
+  endif
+
+  if (nargout > 0)
+    if (arg_is_vector)
+      nn = freq';
+      xx = x';
+    else
+      nn = freq;
+      xx = x;
+    endif
+  elseif (size (freq, 2) != 1)
+    bar (x, freq, 0.8, varargin{iarg:end});
+  else
+    bar (x, freq, 1.0, varargin{iarg:end});
+  endif
+
+endfunction
+
+%!test
+%!  [nn,xx]=hist([1:4],3);
+%!  assert(xx, [1.5,2.5,3.5]);
+%!  assert(nn, [2,1,1]);
+%!test
+%!  [nn,xx]=hist([1:4]',3);
+%!  assert(xx, [1.5,2.5,3.5]);
+%!  assert(nn, [2,1,1]);
+%!test
+%!  [nn,xx]=hist([1 1 1 NaN NaN NaN 2 2 3],[1 2 3]);
+%!  assert(xx, [1,2,3]);
+%!  assert(nn, [3,2,1]);
+%!test
+%!  [nn,xx]=hist([[1:4]',[1:4]'],3);
+%!  assert(xx, [1.5;2.5;3.5]);
+%!  assert(nn, [[2,1,1]',[2,1,1]']);
+%!assert(hist(1,1),1);
+%!test
+%!  for n = [10, 30, 100, 1000]
+%!    assert(sum(hist([1:n], n)), n);
+%!    assert(sum(hist([1:n], [2:n-1])), n);
+%!    assert(sum(hist([1:n], [1:n])), n);
+%!    assert(sum(hist([1:n], 29)), n);
+%!    assert(sum(hist([1:n], 30)), n);
+%!  endfor
+%!test
+%!  assert (size (hist(randn(750,240), 200)), [200,240]);
diff --git a/scripts/plot/hold.m b/scripts/plot/hold.m
new file mode 100644
index 0000000..95b8598
--- /dev/null
+++ b/scripts/plot/hold.m
@@ -0,0 +1,130 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} hold
+## @deftypefnx {Function File} {} hold @var{state}
+## @deftypefnx {Function File} {} hold (@var{hax}, @dots{})
+## Toggle or set the 'hold' state of the plotting engine which determines
+## whether new graphic objects are added to the plot or replace the existing
+## objects.  
+## 
+## @table @code
+## @item hold on
+## Retain plot data and settings so that subsequent plot commands are displayed
+## on a single graph.
+##
+## @item hold off
+## Clear plot and restore default graphics settings before each new plot
+## command.  (default).
+##
+## @item hold
+## Toggle the current 'hold' state.
+## @end table
+## 
+## When given the additional argument @var{hax}, the hold state is modified
+## only for the given axis handle.
+##
+## To query the current 'hold' state use the @code{ishold} function.
+## @seealso{ishold, cla, newplot, clf}
+## @end deftypefn
+
+function hold (varargin)
+
+  if (nargin > 0 && numel (varargin{1}) == 1 && ishandle (varargin{1})
+      && strcmp (get (varargin{1}, "type"), "axes"))
+    [ax, varargin, nargs] = __plt_get_axis_arg__ ("hold", varargin{:});
+  elseif (nargin > 0 && numel (varargin{1}) > 1 && ishandle (varargin{1}))
+    print_usage ();
+  else
+    ax = gca ();
+    fig = gcf ();
+    nargs = numel (varargin);
+  endif
+
+  if (nargs == 0)
+    turn_hold_off = ishold (ax);
+  elseif (nargs == 1)
+    state = varargin{1};
+    if (ischar (state))
+      if (strcmpi (state, "off"))
+	turn_hold_off = true;
+      elseif (strcmpi (state, "on"))
+	turn_hold_off = false;
+      else
+	error ("hold: invalid hold state");
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (turn_hold_off)
+    set (ax, "nextplot", "replace");
+  else
+    set (ax, "nextplot", "add");
+    set (fig, "nextplot", "add");
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! A = rand (100);
+%! [X, Y] = find (A > 0.9);
+%! imshow (A)
+%! hold on
+%! plot (X, Y, 'o')
+%! hold off
+
+%!demo
+%! clf
+%! hold on
+%! imagesc(1./hilb(4));
+%! plot (1:4, "-s")
+%! hold off
+
+%!demo
+%! clf
+%! hold on
+%! imagesc(1./hilb(2));
+%! imagesc(1./hilb(4));
+%! hold off
+
+%!demo
+%! clf
+%! hold on
+%! plot (1:4, "-s")
+%! imagesc(1./hilb(4));
+%! hold off
+
+%!demo
+%! clf
+%! colormap (jet)
+%! t = linspace (-3, 3, 50);
+%! [x, y] = meshgrid (t, t);
+%! z = peaks (x, y);
+%! contourf (x, y, z, 10);
+%! hold ("on");
+%! plot (vec (x), vec (y), "^");
+%! patch ([-1.0 1.0 1.0 -1.0 -1.0], [-1.0 -1.0 1.0 1.0 -1.0], "red");
+%! xlim ([-2.0 2.0]);
+%! ylim ([-2.0 2.0]);
+%! colorbar ("SouthOutside");
+%! title ("Test script for some plot functions");
+
diff --git a/scripts/plot/isfigure.m b/scripts/plot/isfigure.m
new file mode 100644
index 0000000..7d6a585
--- /dev/null
+++ b/scripts/plot/isfigure.m
@@ -0,0 +1,35 @@
+## Copyright (C) 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isfigure (@var{h})
+## Return true if @var{h} is a graphics handle that contains a figure
+## object and false otherwise.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = isfigure (h)
+
+  if (nargin == 1)
+    retval = (ishandle (h) && strcmp (get (h, "type"), "figure"));
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/ishghandle.m b/scripts/plot/ishghandle.m
new file mode 100644
index 0000000..fa4bdb7
--- /dev/null
+++ b/scripts/plot/ishghandle.m
@@ -0,0 +1,28 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ishghandle (@var{h})
+## Return true if @var{h} is a graphics handle and false otherwise.
+## @end deftypefn
+
+function retval = ishghandle (h)
+  ## This function is just included for compatibility as Octave has 
+  ## no simulink equivalent.
+  retval = ishandle (h);
+endfunction
diff --git a/scripts/plot/ishold.m b/scripts/plot/ishold.m
new file mode 100644
index 0000000..d34f130
--- /dev/null
+++ b/scripts/plot/ishold.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2005, 2006, 2007, 2008 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ishold
+## Return true if the next line will be added to the current plot, or
+## false if the plot device will be cleared before drawing the next line.
+## @end deftypefn
+
+function retval = ishold (h)
+
+  if (nargin == 0)
+    ax = gca ();
+    fig = gcf ();
+  elseif (nargin == 1)
+    if (ishandle (h))
+      if (isfigure (h))
+	ax = get (h, "currentaxes");
+	if (isempty (ax))
+	  ax = __go_axes__ (h);
+	  set (h, "currentaxes", ax);
+	endif
+	fig = h;
+      elseif (strcmpi (get (h, "type"), "axes"))
+	ax = h;
+	fig = get (h, "parent");
+      else
+	error ("hold: expecting argument to be axes or figure graphics handle");
+      endif
+    else
+      error ("hold: expecting argument to be axes or figure graphics handle");
+    endif
+  else
+    print_usage ();
+  endif
+
+  retval = (strcmpi (get (fig, "nextplot"), "add")
+	    && strcmpi (get (ax, "nextplot"), "add"));
+
+endfunction
diff --git a/scripts/plot/isocolors.m b/scripts/plot/isocolors.m
new file mode 100644
index 0000000..2d2b792
--- /dev/null
+++ b/scripts/plot/isocolors.m
@@ -0,0 +1,168 @@
+## Copyright (C) 2009 Martin Helm
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{cd}] =} isocolors (@var{c}, @var{v})
+## @deftypefnx {Function File} {[@var{cd}] =} isocolors (@var{x}, @var{y}, @var{z}, @var{c}, @var{v})
+## @deftypefnx {Function File} {[@var{cd}] =} isocolors (@var{x}, @var{y}, @var{z}, @var{r}, @var{g}, @var{b}, @var{v})
+## @deftypefnx {Function File} {[@var{cd}] =} isocolors (@var{r}, @var{g}, @var{b}, @var{v})
+## @deftypefnx {Function File} {[@var{cd}] =} isocolors (@dots{}, @var{p})
+## @deftypefnx {Function File} isocolors (@dots{})
+##
+## If called with one output argument and the first input argument
+## @var{c} is a three--dimensional array that contains color values and
+## the second input argument @var{v} keeps the vertices of a geometry
+## then return a matrix @var{cd} with color data information for the
+## geometry at computed points 
+## @command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}.  The output argument
+## @var{cd} can be taken to manually set FaceVertexCData of a patch.
+##
+## If called with further input arguments @var{x}, @var{y} and @var{z}
+## which are three--dimensional arrays of the same size than @var{c}
+## then the color data is taken at those given points.  Instead of the
+## color data @var{c} this function can also be called with RGB values
+## @var{r}, @var{g}, @var{b}.  If input argumnets @var{x}, @var{y},
+## @var{z} are not given then again @command{meshgrid} computed values
+## are taken.
+##
+## Optionally, the patch handle @var{p} can be given as the last input
+## argument to all variations of function calls instead of the vertices
+## data @var{v}.  Finally, if no output argument is given then directly
+## change the colors of a patch that is given by the patch handle
+## @var{p}.
+##
+## For example,
+## @example
+## function [] = isofinish (p)
+##   set (gca, "DataAspectRatioMode", "manual", \
+##        "DataAspectRatio", [1 1 1]);
+##   set (p, "FaceColor", "interp");
+##   ## set (p, "FaceLighting", "flat");
+##   ## light ("Position", [1 1 5]); ## Available with JHandles
+## endfunction
+## 
+## N = 15;    ## Increase number of vertices in each direction
+## iso = .4;  ## Change isovalue to .1 to display a sphere
+## lin = linspace (0, 2, N);
+## [x, y, z] = meshgrid (lin, lin, lin);
+## c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); 
+## figure (); ## Open another figure window
+##
+## subplot (2, 2, 1); view (-38, 20); 
+## [f, v] = isosurface (x, y, z, c, iso);
+## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+## cdat = rand (size (c));       ## Compute random patch color data
+## isocolors (x, y, z, cdat, p); ## Directly set colors of patch
+## isofinish (p);                ## Call user function isofinish
+##
+## subplot (2, 2, 2); view (-38, 20); 
+## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+## [r, g, b] = meshgrid (lin, 2-lin, 2-lin);
+## cdat = isocolors (x, y, z, c, v); ## Compute color data vertices
+## set (p, "FaceVertexCData", cdat); ## Set color data manually
+## isofinish (p);
+##
+## subplot (2, 2, 3); view (-38, 20); 
+## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+## cdat = isocolors (r, g, b, c, p); ## Compute color data patch
+## set (p, "FaceVertexCData", cdat); ## Set color data manually
+## isofinish (p);
+##
+## subplot (2, 2, 4); view (-38, 20); 
+## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+## r = g = b = repmat ([1:N] / N, [N, 1, N]); ## Black to white
+## cdat = isocolors (x, y, z, r, g, b, v);
+## set (p, "FaceVertexCData", cdat);
+## isofinish (p);
+## @end example
+##
+## @seealso{isosurface, isonormals, isocaps}
+##
+## @end deftypefn
+
+## Author: Martin Helm <martin at mhelm.de>
+
+function varargout = isocolors(varargin)
+  calc_rgb = false;
+  switch nargin
+    case 2
+      c = varargin{1};
+      vp = varargin{2};
+      x = 1:size (c, 2);
+      y = 1:size (c, 1);
+      z = 1:size (c, 3);
+    case 4
+      calc_rgb = true;
+      R = varargin{1};
+      G = varargin{2};
+      B = varargin{3};
+      vp = varargin{4};
+      x = 1:size (R, 1);
+      y = 1:size (R, 2);
+      z = 1:size (R, 3);
+    case 5
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+      c = varargin{4};
+      vp = varargin{5};
+    case 7
+      calc_rgb = true;
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+      R = varargin{4};
+      G = varargin{5};
+      B = varargin{6};
+      vp = varargin{7};
+    otherwise 
+      print_usage ();
+  endswitch
+  if (ismatrix (vp) && size (vp,2) == 3)
+    pa = [];
+    v = vp;
+  elseif ( ishandle (vp) )
+    pa = vp;
+    v = get (pa, "Vertices");
+  else
+    error("Last argument is no vertex list and no patch handle");
+  endif
+  if ( calc_rgb )
+    new_col = zeros (size (v, 1), 3);
+    new_col(:, 1) = __interp_cube__ (x, y, z, R, v, "values" );
+    new_col(:, 2) = __interp_cube__ (x, y, z, G, v, "values" );
+    new_col(:, 3) = __interp_cube__ (x, y, z, B, v, "values" );
+  else
+    new_col = __interp_cube__ (x, y, z, c, v, "values" );
+  endif
+  switch nargout
+    case 0
+      if (!isempty (pa))
+        set (pa, "FaceVertexCData", new_col);
+      endif
+    case 1
+      varargout = {new_col};
+    otherwise
+      print_usage ();
+  endswitch
+endfunction
+
+%!test
+%!  [x, y, z] = meshgrid (0:.5:2, 0:.5:2, 0:.5:2);
+%!  c = (x-.5).^2 + (y-.5).^2 + (z-.5).^2; 
+%!  [f, v] = isosurface (x, y, z, c, .4);
+%!  cdat = isocolors (x, y, z, c, v);
+%!  assert (size (cdat, 1) == size (v, 1));
+## Can't create a patch handle for tests without a figure
diff --git a/scripts/plot/isonormals.m b/scripts/plot/isonormals.m
new file mode 100644
index 0000000..4d5b6e2
--- /dev/null
+++ b/scripts/plot/isonormals.m
@@ -0,0 +1,158 @@
+## Copyright (C) 2009 Martin Helm
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{n}] =} isonormals (@var{val}, @var{v})
+## @deftypefnx {Function File} {[@var{n}] =} isonormals (@var{val}, @var{p})
+## @deftypefnx {Function File} {[@var{n}] =} isonormals (@var{x}, @var{y}, @var{z}, @var{val}, @var{v})
+## @deftypefnx {Function File} {[@var{n}] =} isonormals (@var{x}, @var{y}, @var{z}, @var{val}, @var{p})
+## @deftypefnx {Function File} {[@var{n}] =} isonormals (@dots{}, "negate")
+## @deftypefnx {Function File} isonormals (@dots{}, @var{p})
+##
+## If called with one output argument and the first input argument
+## @var{val} is a three--dimensional array that contains the data for an
+## isosurface geometry and the second input argument @var{v} keeps the
+## vertices of an isosurface then return the normals @var{n} in form of
+## a matrix with the same size than @var{v} at computed points
+## @command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}.  The output argument
+## @var{n} can be taken to manually set @var{VertexNormals} of a patch.
+##
+## If called with further input arguments @var{x}, @var{y} and @var{z}
+## which are three--dimensional arrays with the same size than @var{val}
+## then the volume data is taken at those given points.  Instead of the
+## vertices data @var{v} a patch handle @var{p} can be passed to this
+## function.
+##
+## If given the string input argument "negate" as last input argument
+## then compute the reverse vector normals of an isosurface geometry.
+##
+## If no output argument is given then directly redraw the patch that is
+## given by the patch handle @var{p}.
+##
+## For example,
+## @example
+## function [] = isofinish (p)
+##   set (gca, "DataAspectRatioMode","manual","DataAspectRatio",[1 1 1]);
+##   set (p, "VertexNormals", -get(p,"VertexNormals")); ## Revert normals
+##   set (p, "FaceColor", "interp");
+##   ## set (p, "FaceLighting", "phong");
+##   ## light ("Position", [1 1 5]); ## Available with JHandles
+## endfunction
+##
+## N = 15;    ## Increase number of vertices in each direction
+## iso = .4;  ## Change isovalue to .1 to display a sphere
+## lin = linspace (0, 2, N);
+## [x, y, z] = meshgrid (lin, lin, lin);
+## c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
+## figure (); ## Open another figure window
+##
+## subplot (2, 2, 1); view (-38, 20);
+## [f, v, cdat] = isosurface (x, y, z, c, iso, y);
+## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+## 	   "FaceColor", "interp", "EdgeColor", "none");
+## isofinish (p); ## Call user function isofinish
+##
+## subplot (2, 2, 2); view (-38, 20);
+## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+## 	   "FaceColor", "interp", "EdgeColor", "none");
+## isonormals (x, y, z, c, p); ## Directly modify patch
+## isofinish (p);
+##
+## subplot (2, 2, 3); view (-38, 20);
+## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+## 	   "FaceColor", "interp", "EdgeColor", "none");
+## n = isonormals (x, y, z, c, v); ## Compute normals of isosurface
+## set (p, "VertexNormals", n);    ## Manually set vertex normals
+## isofinish (p);
+##
+## subplot (2, 2, 4); view (-38, 20);
+## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, \
+## 	   "FaceColor", "interp", "EdgeColor", "none");
+## isonormals (x, y, z, c, v, "negate"); ## Use reverse directly
+## isofinish (p);
+## @end example
+##
+## @seealso {isosurface, isocolors, isocaps, marching_cube}
+##
+## @end deftypefn
+
+## Author: Martin Helm <martin at mhelm.de>
+
+function varargout = isonormals(varargin)
+  na = nargin;
+  negate = false;
+  if (ischar (varargin{nargin}))
+    na = nargin-1;
+    if (strcmp (lower (varargin{nargin}), "negate"))
+      negate = true;
+    else
+      error ("Unknown option '%s'", varargin{nargin});
+    endif
+  endif
+  switch na
+    case 2
+      c = varargin{1};
+      vp = varargin{2};
+      x = 1:size (c, 2);
+      y = 1:size (c, 1);
+      z = 1:size (c, 3);
+    case 5
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+      c = varargin{4};
+      vp = varargin{5};
+    otherwise 
+      print_usage ();
+  endswitch
+  if (ismatrix (vp) && size (vp,2) == 3)
+    pa = [];
+    v = vp;
+  elseif (ishandle (vp))
+    pa = vp;
+    v = get (pa, "Vertices");
+  else
+    error ("Last argument is no vertex list and no patch handle");
+  endif
+  if (negate)
+    normals = -__interp_cube__ (x, y, z, c, v, "normals");
+  else
+    normals = __interp_cube__ (x, y, z, c, v, "normals");
+  endif
+  switch nargout
+    case 0
+      if (!isempty (pa))
+        set (pa, "VertexNormals", normals);
+      endif
+    case 1
+      varargout = {normals};
+    otherwise
+      print_usage ();
+  endswitch
+endfunction
+
+%!test
+%!  [x, y, z] = meshgrid (0:.5:2, 0:.5:2, 0:.5:2);
+%!  c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); 
+%!  [f, v, cdat] = isosurface (x, y, z, c, .4, y);
+%!  n = isonormals (x, y, z, c, v);
+%!  assert (size (v), size (n));
+%!test
+%!  [x, y, z] = meshgrid (0:.5:2, 0:.5:2, 0:.5:2);
+%!  c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); 
+%!  [f, v, cdat] = isosurface (x, y, z, c, .4, y);
+%!  np = isonormals (x, y, z, c, v);
+%!  nn = isonormals (x, y, z, c, v, "negate");
+%!  assert (all (np == -nn));
diff --git a/scripts/plot/isosurface.m b/scripts/plot/isosurface.m
new file mode 100644
index 0000000..3bf60e5
--- /dev/null
+++ b/scripts/plot/isosurface.m
@@ -0,0 +1,215 @@
+## Copyright (C) 2009 Martin Helm
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{fv}] =} isosurface (@var{val}, @var{iso})
+## @deftypefnx {Function File} {[@var{fv}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+## @deftypefnx {Function File} {[@var{fv}] =} isosurface (@dots{}, "noshare", "verbose")
+## @deftypefnx {Function File} {[@var{fvc}] =} isosurface (@dots{}, @var{col})
+## @deftypefnx {Function File} {[@var{f}, @var{v}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso})
+## @deftypefnx {Function File} {[@var{f}, @var{v}, @var{c}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col})
+## @deftypefnx {Function File} {} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}, @var{opt})
+##
+## If called with one output argument and the first input argument
+## @var{val} is a three--dimensional array that contains the data of an
+## isosurface geometry and the second input argument @var{iso} keeps the
+## isovalue as a scalar value then return a structure array @var{fv}
+## that contains the fields @var{Faces} and @var{Vertices} at computed
+## points @command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}.  The output
+## argument @var{fv} can directly be taken as an input argument for the 
+## @command{patch} function.
+##
+## If called with further input arguments @var{x}, @var{y} and @var{z}
+## which are three--dimensional arrays with the same size than @var{val}
+## then the volume data is taken at those given points.
+##
+## The string input argument "noshare" is only for compatibility and
+## has no effect. If given the string input argument
+## "verbose" then print messages to the command line interface about the
+## current progress.
+##
+## If called with the input argument @var{col} which is a
+## three-dimensional array of the same size than @var{val} then take
+## those values for the interpolation of coloring the isosurface
+## geometry.  Add the field @var{FaceVertexCData} to the structure
+## array @var{fv}.
+##
+## If called with two or three output arguments then return the
+## information about the faces @var{f}, vertices @var{v} and color data
+## @var{c} as seperate arrays instead of a single structure array.
+##
+## If called with no output argument then directly process the
+## isosurface geometry with the @command{patch} command.
+##
+## For example
+##
+## @example
+## [x, y, z] = meshgrid (1:5, 1:5, 1:5);
+## val = rand (5, 5, 5);
+## isosurface (x, y, z, val, .5);
+## @end example
+##
+## will directly draw a random isosurface geometry in a graphics window.
+## Another example for an isosurface geometry with different additional
+## coloring
+##
+## @example
+## N = 15;    ## Increase number of vertices in each direction
+## iso = .4;  ## Change isovalue to .1 to display a sphere
+## lin = linspace (0, 2, N);
+## [x, y, z] = meshgrid (lin, lin, lin);
+## c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); 
+## figure (); ## Open another figure window
+##
+## subplot (2, 2, 1); view (-38, 20); 
+## [f, v] = isosurface (x, y, z, c, iso);
+## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none");
+## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+## # set (p, "FaceColor", "green", "FaceLighting", "phong");
+## # light ("Position", [1 1 5]); ## Available with the JHandles package
+##
+## subplot (2, 2, 2); view (-38, 20);
+## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "blue");
+## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+## # set (p, "FaceColor", "none", "FaceLighting", "phong");
+## # light ("Position", [1 1 5]);
+##
+## subplot (2, 2, 3); view (-38, 20);
+## [f, v, c] = isosurface (x, y, z, c, iso, y);
+## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \
+##            "FaceColor", "interp", "EdgeColor", "none");
+## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+## # set (p, "FaceLighting", "phong");
+## # light ("Position", [1 1 5]);
+##
+## subplot (2, 2, 4); view (-38, 20);
+## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \
+##            "FaceColor", "interp", "EdgeColor", "blue");
+## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]);
+## # set (p, "FaceLighting", "phong");
+## # light ("Position", [1 1 5]);
+## @end example
+##
+## @seealso{isocolors, isonormals, isocaps}
+##
+## @end deftypefn
+
+## Author: Martin Helm <martin at mhelm.de>
+
+function varargout = isosurface(varargin)
+
+  if (nargin < 2 || nargin > 8 || nargout > 3)
+    print_usage ();
+  endif
+
+  calc_colors = false;
+  f = v = c = [];
+  verbose = false;
+  noshare = false;
+  if (nargin >= 5)
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    val = varargin{4};
+    iso = varargin{5};
+    if (nargin >= 6 && ismatrix (varargin{6}))
+      colors = varargin{6};
+      calc_colors = true;
+    endif
+  else
+    val = varargin{1};
+    [n1, n2, n3] = size (val);
+    [x, y, z] = meshgrid (1:n1, 1:n2, 1:n3);
+    iso = varargin{2};
+    if (nargin >= 3 && ismatrix (varargin{3}))
+        colors = varargin{3};
+        calc_colors = true;
+    endif
+  endif
+  if (calc_colors)
+    if (nargout == 2)
+      warning ( "Colors will be calculated, but you did not specify an output argument for it!" );
+    endif
+    [fvc.faces, fvc.vertices, fvc.facevertexcdata] = __marching_cube__ (x, y, z, val, iso, colors);
+  else
+    [fvc.faces, fvc.vertices] = __marching_cube__ (x, y, z, val, iso);
+  endif
+  
+  if (isempty (fvc.vertices) || isempty (fvc.faces))
+    warning ( "The resulting triangulation is empty" );
+  endif
+
+  switch (nargout)
+    case 0
+      ## plot the calculated surface
+      newplot ();
+      if (calc_colors)
+        pa = patch ("Faces", fvc.faces, "Vertices", fvc.vertices,
+		    "FaceVertexCData", fvc.facevertexcdata, 
+		    "FaceColor", "flat", "EdgeColor", "none");
+      else
+        pa = patch ("Faces", fvc.faces, "Vertices", fvc.vertices, 
+		    "FaceColor", "g", "EdgeColor", "k");
+      endif
+      if (! ishold ())
+	set (gca(), "view", [-37.5, 30],
+	     "xgrid", "on", "ygrid", "on", "zgrid", "on");
+      endif
+    case 1
+      varargout = {fvc};
+    case 2
+      varargout = {fvc.faces, fvc.vertices};
+    case 3
+      varargout = {fvc.faces, fvc.vertices, fvc.facevertexcdata};
+    otherwise
+      print_usage ();
+  endswitch
+
+endfunction
+
+
+%!shared x, y, z, val
+%!  [x, y, z]  = meshgrid (0:1, 0:1, 0:1); ## Points for single
+%!  val        = [0, 0; 0, 0];             ## cube and a 3--dim
+%!  val(:,:,2) = [0, 0; 1, 0];             ## array of values
+%!test
+%!  fv = isosurface (x, y, z, val, 0.3);
+%!  assert (isfield (fv, "vertices"), true);
+%!  assert (isfield (fv, "faces"), true);
+%!  assert (size (fv.vertices), [3 3]);
+%!  assert (size (fv.faces), [1 3]);
+%!test
+%!  fvc = isosurface (x, y, z, val, .3, y);
+%!  assert (isfield (fvc, "vertices"), true);
+%!  assert (isfield (fvc, "faces"), true);
+%!  assert (isfield (fvc, "facevertexcdata"), true);
+%!  assert (size (fvc.vertices), [3 3]);
+%!  assert (size (fvc.faces), [1 3]);
+%!  assert (size (fvc.facevertexcdata), [3 1]);
+%!test
+%!  [f, v] = isosurface (x, y, z, val, .3);
+%!  assert (size (f), [1 3]);
+%!  assert (size (v), [3 3]);
+%!test
+%!  [f, v, c] = isosurface (x, y, z, val, .3, y);
+%!  assert (size (f), [1 3]);
+%!  assert (size (v), [3 3]);
+%!  assert (size (c), [3 1]);
+
+%!demo
+%! clf
+%! [x,y,z] = meshgrid(-2:0.5:2, -2:0.5:2, -2:0.5:2);
+%! v = x.^2 + y.^2 + z.^2;
+%! isosurface (x, y, z, v, 1) 
\ No newline at end of file
diff --git a/scripts/plot/legend.m b/scripts/plot/legend.m
new file mode 100644
index 0000000..16bacbb
--- /dev/null
+++ b/scripts/plot/legend.m
@@ -0,0 +1,281 @@
+## Copyright (C) 2001, 2006, 2007, 2008, 2009 Laurent Mazet
+## Copyright (C) 2006 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} legend (@var{st1}, @var{st2}, @dots{})
+## @deftypefnx {Function File} {} legend (@var{st1}, @var{st2}, @dots{}, "location", @var{pos})
+## @deftypefnx {Function File} {} legend (@var{matstr})
+## @deftypefnx {Function File} {} legend (@var{matstr}, "location", @var{pos})
+## @deftypefnx {Function File} {} legend (@var{cell})
+## @deftypefnx {Function File} {} legend (@var{cell}, "location", @var{pos})
+## @deftypefnx {Function File} {} legend ('@var{func}')
+##
+## Display a legend for the current axes using the specified strings
+## as labels.  Legend entries may be specified as individual character
+## string arguments, a character array, or a cell array of character
+## strings.  Legend works on line graphs, bar graphs, etc.  A plot must
+## exist before legend is called.
+##
+## The optional parameter @var{pos} specifies the location of the legend
+## as follows:
+##
+## @multitable @columnfractions 0.06 0.14 0.80
+## @item @tab north @tab
+##   center top
+## @item @tab south @tab
+##   center bottom
+## @item @tab east @tab
+##   right center
+## @item @tab west @tab
+##   left center
+## @item @tab northeast @tab
+##   right top (default)
+## @item @tab northwest @tab
+##   left top
+## @item @tab southeast @tab
+##   right bottom
+## @item @tab southwest @tab
+##   left bottom
+## @item 
+## @item @tab outside @tab
+##   can be appended to any location string
+## @end multitable
+##
+## Some specific functions are directly available using @var{func}:
+##
+## @table @asis
+## @item "show"
+##   Show legends from the plot
+## @item "hide"
+## @itemx "off"
+##   Hide legends from the plot
+## @item "boxon"
+##   Draw a box around legends
+## @item "boxoff"
+##   Withdraw the box around legends
+## @item "left"
+##   Text is to the left of the keys
+## @item "right"
+##   Text is to the right of the keys
+## @end table
+## @end deftypefn
+
+function legend (varargin)
+
+  [ca, varargin, nargin] = __plt_get_axis_arg__ ("legend", varargin{:});
+  nargs = nargin;
+
+  if (nargs > 0)
+    pos = varargin{nargs};
+    if (isnumeric (pos) && isscalar (pos) && round (pos) == pos)
+      if (pos >= -1 && pos <= 4)
+	set (ca, "keypos", pos);
+	nargs--;
+      else
+	error ("legend: invalid position specified");
+      endif
+    endif
+  endif
+  
+  if (nargs > 1)
+    pos = varargin{nargs-1};
+    str = varargin{nargs};
+    if (strcmpi (pos, "location")  && ischar (str))
+      set (ca, "keypos", str);
+      nargs -= 2;
+    endif
+  endif
+
+  kids = get (ca, "children");
+  nkids = numel (kids);
+  k = 1;
+  turn_on_legend = false;
+
+  if (nargs == 1)
+    arg = varargin{1};
+    if (ischar (arg))
+      if (rows (arg) == 1)
+	str = tolower (deblank (arg));
+	switch (str)
+	  case {"off", "hide"}
+	    set (ca, "key", "off");
+	    nargs--;
+	  case "show"
+	    set (ca, "key", "on");
+	    nargs--;
+	  case "toggle"
+	    val = get (ca, "key");
+	    if (strcmpi (val, "on"))
+	      set (ca, "key", "off");
+	    else
+	      set (ca, "key", "on");
+	    endif
+	    nargs--;
+	  case "boxon"
+	    set (ca, "key", "on", "keybox", "on");
+	    nargs--;
+	  case "boxoff"
+	    set (ca, "keybox", "off");
+	    nargs--;
+	  case "left"
+	    set (ca, "keyreverse", "off")
+	    nargs--;
+	  case "right"
+	    set (ca, "keyreverse", "on")
+	    nargs--;
+	  otherwise
+	endswitch
+      else
+	varargin = cellstr (arg);
+	nargs = numel (varargin);
+      endif
+    elseif (iscellstr (arg))
+      varargin = arg;
+      nargs = numel (varargin);
+    else
+      error ("legend: expecting argument to be a character string");
+    endif
+  endif
+
+  if (nargs > 0)
+    have_data = false;
+    for k = 1:nkids
+      typ = get (kids(k), "type");
+      if (strcmp (typ, "line") || strcmp (typ, "surface")
+	  || strcmp (typ, "patch") || strcmp (typ, "hggroup"))
+	have_data = true;
+	break;
+      endif
+    endfor
+    if (! have_data)
+      warning ("legend: plot data is empty; setting key labels has no effect");
+    endif
+  endif
+
+  warned = false;
+  k = nkids;
+  for i = 1:nargs
+    arg = varargin{i};
+    if (ischar (arg))
+      typ = get (kids(k), "type");
+      while (k > 1
+	     && ! (strcmp (typ, "line") || strcmp (typ, "surface")
+		   || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
+	typ = get (kids(--k), "type");
+      endwhile
+      if (k > 0)
+	if (strcmp (get (kids(k), "type"), "hggroup"))
+	  hgkids = get (kids(k), "children");
+	  for j = 1 : length (hgkids)
+	    hgobj = get (hgkids (j));
+	    if (isfield (hgobj, "keylabel"))
+	      set (hgkids(j), "keylabel", arg);
+	      break;
+	    endif
+	  endfor
+	else
+	  set (kids(k), "keylabel", arg);
+	endif
+	turn_on_legend = true;
+	if (--k == 0)
+	  break;
+	endif
+      elseif (! warned)
+	warned = true;
+	warning ("legend: ignoring extra labels");
+      endif
+    else
+      error ("legend: expecting argument to be a character string");
+    endif
+  endfor
+
+  if (turn_on_legend)
+    set (ca, "key", "on");
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! plot(1:10, 1:10, 1:10, fliplr(1:10));
+%! title("incline is blue and decline is green");
+%! legend({"I'm blue", "I'm green"}, "location", "east")
+
+%!demo
+%! clf
+%! plot(1:10, 1:10, 1:10, fliplr(1:10));
+%! title("incline is blue and decline is green");
+%! legend("I'm blue", "I'm green", "location", "east")
+
+%!demo
+%! clf
+%! plot(1:10, 1:10);
+%! title("a very long label can sometimes cause problems");
+%! legend({"hello world"}, "location", "northeastoutside")
+
+%!demo
+%! clf
+%! plot(1:10, 1:10);
+%! title("a very long label can sometimes cause problems");
+%! legend("hello world", "location", "northeastoutside")
+
+%!demo
+%! clf
+%! labels = {};
+%! for i = 1:5
+%!     h = plot(1:100, i + rand(100,1)); hold on;
+%!     set (h, "color", get (gca, "colororder")(i,:))
+%!     labels = {labels{:}, cstrcat("Signal ", num2str(i))};
+%! endfor; hold off;
+%! title("Signals with random offset and uniform noise")
+%! xlabel("Sample Nr [k]"); ylabel("Amplitude [V]");
+%! legend(labels, "location", "southoutside")
+%! legend("boxon")
+
+%!demo
+%! clf
+%! labels = {};
+%! for i = 1:5
+%!     h = plot(1:100, i + rand(100,1)); hold on;
+%!     set (h, "color", get (gca, "colororder")(i,:))
+%!     labels = {labels{:}, cstrcat("Signal ", num2str(i))};
+%! endfor; hold off;
+%! title("Signals with random offset and uniform noise")
+%! xlabel("Sample Nr [k]"); ylabel("Amplitude [V]");
+%! legend(labels{:}, "location", "southoutside")
+%! legend("boxon")
+
+%!demo
+%! hold ("off");
+%! x = linspace (0, 10);
+%! plot (x, x);
+%! hold ("on");
+%! stem (x, x.^2, 'g')
+%! legend ("linear");
+%! hold ("off");
+
+%!demo
+%! x = linspace (0, 10);
+%! plot (x, x, x, x.^2);
+%! legend ("linear");
+
+%!demo
+%! x = linspace (0, 10);
+%! plot (x, x, x, x.^2);
+%! legend ("linear", "quadratic");
diff --git a/scripts/plot/line.m b/scripts/plot/line.m
new file mode 100644
index 0000000..f59a3ed
--- /dev/null
+++ b/scripts/plot/line.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} line ()
+## @deftypefnx {Function File} {} line (@var{x}, @var{y})
+## @deftypefnx {Function File} {} line (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {} line (@var{x}, @var{y}, @var{z}, @var{property}, @var{value}, @dots{})
+## Create line object from @var{x} and @var{y} and insert in current
+## axes object.  Return a handle (or vector of handles) to the line
+## objects created.
+##
+## Multiple property-value pairs may be specified for the line, but they
+## must appear in pairs.
+## @end deftypefn
+
+## Author: jwe
+
+function h = line (varargin)
+
+  ## make a default line object, and make it the current axes for
+  ## the current figure.
+  tmp = __line__ (gca (), varargin{:});
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/linkprop.m b/scripts/plot/linkprop.m
new file mode 100644
index 0000000..2b1e896
--- /dev/null
+++ b/scripts/plot/linkprop.m
@@ -0,0 +1,98 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{hlink} =} linkprop (@var{h}, @var{prop})
+## Links graphics object properties, such that a change in one is
+## propagated to the others.  The properties to link are given as a
+## string of cell string array by @var{prop} and the objects containing
+## these properties by the handle array @var{h}.
+##
+## An example of the use of linkprops is
+##
+## @example
+## @group
+## x = 0:0.1:10;
+## subplot (1, 2, 1);
+## h1 = plot (x, sin (x));
+## subplot (1, 2, 2);
+## h2 = plot (x, cos (x));
+## hlink = linkprop ([h1, h2], @{"color","linestyle"@});
+## set (h1, "color", "green");
+## set (h2, "linestyle", "--");
+## @end group
+## @end example
+##
+## @end deftypefn
+
+function hlink = linkprop (h, prop)
+  if (ischar (prop))
+    prop = {prop};
+  elseif (!iscellstr (prop))
+    error ("linkprop: properties must be a string or cell string array");
+  endif
+
+  for i = 1 : numel (h)
+    for j = 1 : numel (prop)
+      addlistener (h(i), prop{j}, {@update_prop, h, prop{j}});
+    endfor
+  endfor
+
+  ## This should be an object that when destroyed removes the links
+  ## The below is not quite right. As when you call "clear hlink" the
+  ## hggroup continues to exist.
+  hlink = hggroup ();
+  set (hlink, "deletefcn", {@delete_prop, h, prop});
+endfunction
+
+function update_prop (h, d, hlist, prop)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      val = get (h, prop);
+      for hh = hlist(:)'
+	if (hh != h)
+	  oldval = get (hh, prop);
+	  if (! isequal (val, oldval))
+	    set (hh, prop, val);
+	  endif
+	endif
+      endfor
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
+
+function delete_prop (h, d, hlist, prop)
+  ## FIXME. Actually need to delete the linked properties.
+  ## However, only warn if the graphics objects aren't being deleted.
+  warn = false;
+  for h = hlist(:)'
+    if (ishandle (h) && !strcmpi (get (h, "beingdeleted"), "on"))
+      warn = true;
+      break;
+    endif
+  endfor
+  if (warn)
+    warning ("linkprop: can not remove linked properties");
+  endif
+endfunction
diff --git a/scripts/plot/loglog.m b/scripts/plot/loglog.m
new file mode 100644
index 0000000..57711e4
--- /dev/null
+++ b/scripts/plot/loglog.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} loglog (@var{args})
+## Produce a two-dimensional plot using log scales for both axes.  See
+## the description of @code{plot} for a description of the arguments
+## that @code{loglog} will accept.
+## @seealso{plot, semilogx, semilogy}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = loglog (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("loglog", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    set (h, "xscale", "log", "yscale", "log");
+
+    tmp = __plt__ ("loglog", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/loglogerr.m b/scripts/plot/loglogerr.m
new file mode 100644
index 0000000..57eb3fa
--- /dev/null
+++ b/scripts/plot/loglogerr.m
@@ -0,0 +1,62 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009
+##               Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} loglogerr (@var{args})
+## Produce two-dimensional plots on double logarithm axis with
+## errorbars.  Many different combinations of arguments are possible.
+## The most used form is
+##
+## @example
+## loglogerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+## @end example
+##
+## @noindent
+## which produces a double logarithm plot of @var{y} versus @var{x} 
+## with errors in the @var{y}-scale defined by @var{ey} and the plot
+## format defined by @var{fmt}.  See errorbar for available formats and 
+## additional information.
+## @seealso{errorbar, semilogxerr, semilogyerr}
+## @end deftypefn
+
+## Created: 20.2.2001
+## Author: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function retval = loglogerr (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("loglogerr", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    set (h, "xscale", "log", "yscale", "log");
+
+    tmp = __errcomm__ ("loglogerr", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/mesh.m b/scripts/plot/mesh.m
new file mode 100644
index 0000000..6724c98
--- /dev/null
+++ b/scripts/plot/mesh.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mesh (@var{x}, @var{y}, @var{z})
+## Plot a mesh given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+## the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+## correspond to different @var{x} values and rows of @var{z} correspond
+## to different @var{y} values.
+## @seealso{meshgrid, contour}
+## @end deftypefn
+
+## Author: jwe
+
+function h = mesh (varargin)
+
+  newplot ();
+
+  tmp = surface (varargin{:});
+
+  ax = get (tmp, "parent");
+
+  set (tmp, "facecolor", "w");
+  set (tmp, "edgecolor", "flat");
+
+  if (! ishold ())
+    set (ax, "view", [-37.5, 30]);
+  endif
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/meshc.m b/scripts/plot/meshc.m
new file mode 100644
index 0000000..8450a55
--- /dev/null
+++ b/scripts/plot/meshc.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1996, 1997, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} meshc (@var{x}, @var{y}, @var{z})
+## Plot a mesh and contour given matrices @var{x}, and @var{y} from 
+## @code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+## @var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+## then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+## columns of @var{z} correspond to different @var{x} values and rows of 
+## @var{z} correspond to different @var{y} values.
+## @seealso{meshgrid, mesh, contour}
+## @end deftypefn
+
+function h = meshc (varargin)
+
+  newplot ();
+
+  tmp = surface (varargin{:});
+
+  ax = get (tmp, "parent");
+
+  set (tmp, "facecolor", "w");
+  set (tmp, "edgecolor", "flat");
+
+  if (! ishold ())
+    set (ax, "view", [-37.5, 30]);
+  endif
+
+  z = get (tmp, "zdata");
+  zmin = 2 * (min(z(:)) - max(z(:)));
+
+  [c, tmp2] = __contour__ (ax, zmin, varargin{:});
+
+  tmp = [tmp; tmp2];
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/meshgrid.m b/scripts/plot/meshgrid.m
new file mode 100644
index 0000000..a2fc7bf
--- /dev/null
+++ b/scripts/plot/meshgrid.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{xx}, @var{yy}, @var{zz}] =} meshgrid (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {[@var{xx}, @var{yy}] =} meshgrid (@var{x}, @var{y})
+## @deftypefnx {Function File} {[@var{xx}, @var{yy}] =} meshgrid (@var{x})
+## Given vectors of @var{x} and @var{y} and @var{z} coordinates, and
+## returning 3 arguments, return three-dimensional arrays corresponding
+## to the @var{x}, @var{y}, and @var{z} coordinates of a mesh.  When
+## returning only 2 arguments, return matrices corresponding to the
+## @var{x} and @var{y} coordinates of a mesh.  The rows of @var{xx} are
+## copies of @var{x}, and the columns of @var{yy} are copies of @var{y}.
+## If @var{y} is omitted, then it is assumed to be the same as @var{x},
+## and @var{z} is assumed the same as @var{y}.
+## @seealso{mesh, contour}
+## @end deftypefn
+
+## Author: jwe
+
+function [xx, yy, zz] = meshgrid (x, y, z)
+
+  if (nargin == 0 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    y = x;
+  endif
+
+  ## Use repmat to ensure that the result values have the same type as
+  ## the arguments.
+
+  if (nargout < 3)
+    if (isvector (x) && isvector (y))
+      xx = repmat (x(:).', length (y), 1);
+      yy = repmat (y(:), 1, length (x));
+    else
+      error ("meshgrid: arguments must be vectors");
+    endif
+  else
+    if (nargin < 3)
+      z = y;
+    endif
+    if (isvector (x) && isvector (y) && isvector (z))
+       lenx = length (x);
+       leny = length (y);
+       lenz = length (z);
+       xx = repmat (repmat (x(:).', leny, 1), [1, 1, lenz]);
+       yy = repmat (repmat (y(:), 1, lenx), [1, 1, lenz]);
+       zz = reshape (repmat (z(:).', lenx*leny, 1)(:), leny, lenx, lenz);
+    else
+      error ("meshgrid: arguments must be vectors");
+    endif
+  endif
+
+endfunction
diff --git a/scripts/plot/meshz.m b/scripts/plot/meshz.m
new file mode 100644
index 0000000..ddea0ab
--- /dev/null
+++ b/scripts/plot/meshz.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2007 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} meshz (@var{x}, @var{y}, @var{z})
+## Plot a curtain mesh given matrices @var{x}, and @var{y} from 
+## @code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+## @var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+## then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+## columns of @var{z} correspond to different @var{x} values and rows of 
+## @var{z} correspond to different @var{y} values.
+## @seealso{meshgrid, mesh, contour}
+## @end deftypefn
+ 
+function retval = meshz (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("meshz", varargin{:});
+
+  ioff = nargin + 1;
+  for i = 1:nargin
+    if (ischar (varargin{i}))
+      ioff = i;
+      break;
+    endif
+  endfor
+
+  ## Bundle C matrix back into varargin
+  if (ioff == 3 || ioff == 5)
+    ioff --;
+  endif
+
+  if (ioff == 2)
+    z = varargin{1};
+    [m, n] = size (z);
+    x = 1:n;
+    y = (1:m).';
+  else
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+  endif
+
+
+  if (isvector (x) && isvector (y))
+    x = [x(1), x(:).', x(end)];
+    y = [y(1); y(:); y(end)];
+  else
+    x = [x(1, 1), x(1, :), x(1, end);
+	 x(:, 1), x, x(:, end);
+	 x(end, 1), x(end, :), x(end, end)]; 
+    y = [y(1, 1), y(1, :), y(1, end);
+	 y(:, 1), y, y(:, end);
+	 y(end, 1), y(end, :), y(end, end)]; 
+  endif
+
+  zref = min(z(isfinite(z)));
+  z = [zref .* ones(1, size(z, 2) + 2);
+       zref .* ones(size(z, 1), 1), z, zref .* ones(size(z, 1), 1); 
+       zref.* ones(1, size(z, 2) + 2)];
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    tmp = mesh (x, y, z, varargin{ioff:end});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/ndgrid.m b/scripts/plot/ndgrid.m
new file mode 100644
index 0000000..73d0f46
--- /dev/null
+++ b/scripts/plot/ndgrid.m
@@ -0,0 +1,71 @@
+## Copyright (C) 2006, 2007, 2009 Alexander Barth
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{y1}, @var{y2}, @dots{},  @var{y}n] =} ndgrid (@var{x1}, @var{x2}, @dots{}, @var{x}n)
+## @deftypefnx {Function File} {[@var{y1}, @var{y2}, @dots{},  @var{y}n] =} ndgrid (@var{x})
+## Given n vectors @var{x1}, @dots{} @var{x}n, @code{ndgrid} returns
+## n arrays of dimension n. The elements of the i-th output argument
+## contains the elements of the vector @var{x}i repeated over all
+## dimensions different from the i-th dimension.  Calling ndgrid with
+## only one input argument @var{x} is equivalent of calling ndgrid with
+## all n input arguments equal to @var{x}:
+##
+## [@var{y1}, @var{y2}, @dots{},  @var{y}n] = ndgrid (@var{x}, @dots{}, @var{x})
+## @seealso{meshgrid}
+## @end deftypefn
+
+## Author: Alexander Barth <abarth at marine.usf.edu>
+
+function varargout = ndgrid (varargin)
+
+  if (nargin == 1)
+    n = max ([nargout, 2]);  
+    ## If only one input argument is given, repeat it n-times
+    varargin(1:n) = varargin(1);
+  elseif (nargin >= nargout)
+    n = max ([nargin, 2]);  
+  else
+    error ("ndgrid: wrong number of input arguments");
+  endif
+
+  ## Determine the size of the output arguments
+  
+  shape = zeros (1, n);
+
+  for i = 1:n
+    if (! isvector (varargin{i}))
+      error ("ndgrid: arguments must be vectors");
+    endif
+
+    shape(i) = length (varargin{i});
+  endfor
+
+  for i = 1:n
+    ## size for reshape
+    r = ones (1, n);
+    r(i) = shape(i);
+
+    ## size for repmat
+    s = shape;
+    s(i) = 1;
+
+    varargout{i} = repmat (reshape (varargin{i}, r), s);
+  endfor
+
+endfunction
diff --git a/scripts/plot/newplot.m b/scripts/plot/newplot.m
new file mode 100644
index 0000000..cfafda3
--- /dev/null
+++ b/scripts/plot/newplot.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} newplot ()
+## Prepare graphics engine to produce a new plot.  This function should
+## be called at the beginning of all high-level plotting functions.
+## @end deftypefn
+
+function newplot ()
+
+  if (nargin == 0)
+    __next_line_color__ (true);
+    cf = gcf ();
+    fnp = get (cf, "nextplot");
+    switch (fnp)
+      ## FIXME -- probably we should do more than validate the nextplot
+      ## property value...
+      case "new"
+      case "add"
+      case "replacechildren"
+      case "replace"
+      otherwise
+	error ("newplot: unrecognized nextplot property for current figure");
+    endswitch
+    ca = gca ();
+    anp = get (ca, "nextplot");
+    switch (anp)
+      case "add"
+      case "replacechildren"
+      case "replace"
+	__go_axes_init__ (ca, "replace");
+	__request_drawnow__ ();
+      otherwise
+	error ("newplot: unrecognized nextplot property for current axes");
+    endswitch
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/orient.m b/scripts/plot/orient.m
new file mode 100644
index 0000000..271d746
--- /dev/null
+++ b/scripts/plot/orient.m
@@ -0,0 +1,109 @@
+## Copyright (C) 2001, 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} orient (@var{orientation})
+## Set the default print orientation.  Valid values for
+## @var{orientation} include @code{"landscape"}, @code{"portrait"}, 
+## and @code{"tall"}.
+##
+## The @code{"tall"} option sets the orientation to portait and fills
+## the page with the plot, while leaving a 0.25in border.
+##
+## If called with no arguments, return the default print orientation.
+## @end deftypefn
+
+## Author: Paul Kienzle
+## Adapted-By: jwe
+
+function retval = orient (varargin)
+
+  nargs = nargin;
+
+  if (nargs > 0 && numel (varargin{1}) == 1 && isfigure (varargin{1}))
+    cf = varargin{1};
+    varargin(1) = [];
+    nargs--;
+  else
+    cf = gcf ();
+  endif
+
+  if (nargs == 0)
+    retval = get (cf, "paperorientation");
+  elseif (nargin == 1)
+    orientation = varargin{1};
+    if (strcmpi (orientation, "landscape") || strcmpi (orientation, "portrait"))
+      if (! strcmpi (get (cf, "paperorientation"), orientation))
+        ## FIXME - with the proper listeners in place there won't be a need to set
+        ##         the papersize and paperpostion here.
+        papersize = get (cf, "papersize");
+        paperposition = get (cf, "paperposition");
+        set (cf, "paperorientation", orientation)
+        set (cf, "papersize", papersize([2, 1]));
+        set (cf, "paperposition", paperposition([2, 1, 4, 3]));
+      endif
+    elseif (strcmpi (varargin{1}, 'tall'))
+      orient ("portrait")
+      papersize = get (cf, "papersize");
+      set (cf, "paperposition", [0.25, 0.25, (papersize - 0.5)]);
+    else
+      error ("orient: unknown orientation");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!shared papersize, paperposition, tallpaperposition, hfig
+%!  papersize = [8.5, 11];
+%!  paperposition = [0.25, 2.5, 8, 6];
+%!  tallpaperposition = [0.25, 0.25, (papersize-0.5)];
+%!  hfig = figure ();
+%!  set (hfig, "visible", "off")
+%!  set (hfig, "paperorientation", "portrait")
+%!  set (hfig, "papersize", papersize)
+%!  set (hfig, "paperposition", paperposition)
+%!test
+%!  orient portrait
+%!  assert (orient, "portrait") # default
+%!  assert (get (hfig, "papersize"), papersize)
+%!  assert (get (hfig, "paperposition"), paperposition)
+%!test
+%!  orient landscape
+%!  assert (orient,"landscape") # change to landscape
+%!  assert (get (hfig, "papersize"), papersize([2, 1]))
+%!  assert (get (hfig, "paperposition"), paperposition([2, 1, 4, 3]))
+%!test
+%!  orient portrait # change back to portrait
+%!  assert (orient, "portrait")
+%!  assert (get (hfig, "papersize"), papersize)
+%!  assert (get (hfig, "paperposition"), paperposition)
+%!test
+%!  orient landscape
+%!  orient tall
+%!  assert (orient, "portrait")
+%!  assert (get (hfig, "papersize"), papersize)
+%!  assert (get (hfig, "paperposition"), tallpaperposition)
+%!fail ("orient ('nobody')", "unknown orientation")
+%!test
+%!  orient portrait # errors don't change the state
+%!  assert (orient, "portrait")
+%!  assert (get (hfig, "papersize"), papersize)
+%!  assert (get (hfig, "paperposition"), tallpaperposition)
+%!  close (hfig)
diff --git a/scripts/plot/pareto.m b/scripts/plot/pareto.m
new file mode 100644
index 0000000..1b72ac8
--- /dev/null
+++ b/scripts/plot/pareto.m
@@ -0,0 +1,116 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+## Copyright (C) 2003 Alberto Terruzzi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pareto (@var{x})
+## @deftypefnx {Function File} {} pareto (@var{x}, @var{y})
+## @deftypefnx {Function File} {} pareto (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} pareto (@dots{})
+## Draw a Pareto chart, also called ABC chart.  A Pareto chart is a bar graph 
+## used to arrange information in such a way that priorities for process 
+## improvement can be established.  It organizes and displays information 
+## to show the relative importance of data.  The chart is similar to the 
+## histogram or bar chart, except that the bars are arranged in decreasing 
+## order from left to right along the abscissa.
+## 
+## The fundamental idea (Pareto principle) behind the use of Pareto 
+## diagrams is that the majority of an effect is due to a small subset of the
+## causes, so for quality improvement the first few (as presented on the 
+## diagram) contributing causes to a problem usually account for the majority 
+## of the result.  Thus, targeting these "major causes" for elimination 
+## results in the most cost-effective improvement scheme.
+##
+## The data are passed as @var{x} and the abscissa as @var{y}.  If @var{y} is
+## absent, then the abscissa are assumed to be @code{1 : length (@var{x})}.
+## @var{y} can be a string array, a cell array of strings or a numerical
+## vector.
+##
+## An example of the use of @code{pareto} is
+##
+## @example
+## @group
+## Cheese = @{"Cheddar", "Swiss", "Camembert", ...
+##           "Munster", "Stilton", "Blue"@};
+## Sold = [105, 30, 70, 10, 15, 20];
+## pareto(Sold, Cheese);
+## @end group
+## @end example
+## @end deftypefn
+
+function h = pareto (varargin)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  x = varargin {1}(:).';
+  if (nargin == 2)
+    y = varargin {2}(:).';
+    if (! iscell (y))
+      if (ischar (y))
+	y = cellstr (y);
+      else
+	y = cellfun (@(x) num2str (x), num2cell (y), "UniformOutput", false);
+      endif
+    endif
+  else
+    y = cellfun (@(x) int2str (x), num2cell (1 : numel(x)), 
+		 "UniformOutput", false);
+  endif
+
+  [x, idx] = sort (x, "descend");
+  y = y (idx);
+  cdf = cumsum (x);
+  maxcdf = max(cdf);
+  cdf = cdf ./ maxcdf;
+  cdf95 = cdf - 0.95;
+  idx95 = find(sign(cdf95(1:end-1)) != sign(cdf95(2:end)))(1);
+
+  [ax, hbar, hline] = plotyy (1 : idx95, x (1 : idx95), 
+			      1 : length(cdf), 100 .* cdf, 
+			      @bar, @plot);
+
+  axis (ax(1), [1 - 0.6, idx95 + 0.6, 0, maxcdf]);
+  axis (ax(2), [1 - 0.6, idx95 + 0.6, 0, 100]);
+  set (ax(2), "ytick", [0, 20, 40, 60, 80, 100], 
+       "yticklabel", {"0%", "20%", "40%", "60%", "80%", "100%"});
+  set (ax(1), "xtick", 1 : idx95, "xticklabel", y (1: idx95));
+  set (ax(2), "xtick", 1 : idx95, "xticklabel", y (1: idx95));
+
+  if (nargout > 0)
+    h = [hbar; hline];
+  endif
+  
+endfunction
+
+%!demo
+%! clf
+%! colormap (jet (64))
+%! Cheese = {"Cheddar", "Swiss", "Camembert", "Munster", "Stilton", "Blue"};
+%! Sold = [105, 30, 70, 10, 15, 20];
+%! pareto(Sold, Cheese);
+
+%!demo
+%! clf
+%! % Suppose that we want establish which products makes 80 % of turnover.
+%! Codes = {"AB4","BD7","CF8","CC5","AD11","BB5","BB3","AD8","DF3","DE7"};
+%! Value = [2.35 7.9 2.45 1.1 0.15 13.45 5.4 2.05 0.85  1.65]';
+%! SoldUnits = [54723 41114 16939 1576091 168000 687197 120222 168195, ...
+%!              1084118 55576]';
+%! pareto (Value.*SoldUnits, Codes);
diff --git a/scripts/plot/patch.m b/scripts/plot/patch.m
new file mode 100644
index 0000000..9350013
--- /dev/null
+++ b/scripts/plot/patch.m
@@ -0,0 +1,138 @@
+## Copyright (C) 2005, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} patch ()
+## @deftypefnx {Function File} {} patch (@var{x}, @var{y}, @var{c})
+## @deftypefnx {Function File} {} patch (@var{x}, @var{y}, @var{z}, @var{c})
+## @deftypefnx {Function File} {} patch (@var{fv})
+## @deftypefnx {Function File} {} patch ('Faces', @var{f}, 'Vertices', @var{v}, @dots{})
+## @deftypefnx {Function File} {} patch (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} patch (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} patch (@dots{})
+## Create patch object from @var{x} and @var{y} with color @var{c} and
+## insert in the current axes object.  Return handle to patch object.
+##
+## For a uniform colored patch, @var{c} can be given as an RGB vector,
+## scalar value referring to the current colormap, or string value (for
+## example, "r" or "red").
+##
+## If passed a structure @var{fv} contain the fields "vertices", "faces"
+## and optionally "facevertexcdata", create the patch based on these 
+## properties.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = patch (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("patch", varargin{:});
+
+  oldh = gca ();
+
+  unwind_protect
+    axes (h);
+    [tmp, failed] = __patch__ (h, varargin{:});
+    if (failed)
+      print_usage ();
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! ## Patches with same number of vertices
+%! clf
+%! t1 = (1/16:1/8:1)'*2*pi;
+%! t2 = ((1/16:1/8:1)' + 1/32)*2*pi;
+%! x1 = sin(t1) - 0.8;
+%! y1 = cos(t1);
+%! x2 = sin(t2) + 0.8;
+%! y2 = cos(t2);
+%! patch([x1,x2],[y1,y2],'r');
+
+%!demo
+%! ## Unclosed patch
+%! clf
+%! t1 = (1/16:1/8:1)'*2*pi;
+%! t2 = ((1/16:1/16:1)' + 1/32)*2*pi;
+%! x1 = sin(t1) - 0.8;
+%! y1 = cos(t1);
+%! x2 = sin(t2) + 0.8;
+%! y2 = cos(t2);
+%! patch([[x1;NaN(8,1)],x2],[[y1;NaN(8,1)],y2],'r');
+
+%!demo
+%! ## Specify vertices and faces separately
+%! clf
+%! t1 = (1/16:1/8:1)'*2*pi;
+%! t2 = ((1/16:1/16:1)' + 1/32)*2*pi;
+%! x1 = sin(t1) - 0.8;
+%! y1 = cos(t1);
+%! x2 = sin(t2) + 0.8;
+%! y2 = cos(t2);
+%! vert = [x1, y1; x2, y2];
+%! fac = [1:8,NaN(1,8);9:24];
+%! patch('Faces',fac,'Vertices',vert,'FaceColor','r');
+
+%!demo
+%! ## Specify vertices and faces separately
+%! clf
+%! t1 = (1/16:1/8:1)'*2*pi;
+%! t2 = ((1/16:1/16:1)' + 1/32)*2*pi;
+%! x1 = sin(t1) - 0.8;
+%! y1 = cos(t1);
+%! x2 = sin(t2) + 0.8;
+%! y2 = cos(t2);
+%! vert = [x1, y1; x2, y2];
+%! fac = [1:8,NaN(1,8);9:24];
+%! patch('Faces',fac,'Vertices',vert,'FaceVertexCData', [0, 1, 0; 0, 0, 1]);
+
+%!demo
+%! ## Property change on multiple patches
+%! clf
+%! t1 = (1/16:1/8:1)'*2*pi;
+%! t2 = ((1/16:1/8:1)' + 1/32)*2*pi;
+%! x1 = sin(t1) - 0.8;
+%! y1 = cos(t1);
+%! x2 = sin(t2) + 0.8;
+%! y2 = cos(t2);
+%! h = patch([x1,x2],[y1,y2],cat (3,[0,0],[1,0],[0,1]));
+%! pause (1);
+%! set (h, 'FaceColor', 'r');
+
+%!demo
+%! clf
+%! vertices = [0, 0, 0;
+%!             1, 0, 0;
+%!             1, 1, 0;
+%!             0, 1, 0;
+%!             0.5, 0.5, 1];
+%! faces = [1, 2, 5;
+%!          2, 3, 5;
+%!          3, 4, 5;
+%!          4, 1, 5];
+%! patch('Vertices', vertices, 'Faces', faces, ...
+%!       'FaceVertexCData', jet(4), 'FaceColor', 'flat')
+%! view (-37.5, 30)
diff --git a/scripts/plot/pcolor.m b/scripts/plot/pcolor.m
new file mode 100644
index 0000000..1448199
--- /dev/null
+++ b/scripts/plot/pcolor.m
@@ -0,0 +1,81 @@
+## Copyright (C) 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pcolor (@var{x}, @var{y}, @var{c})
+## @deftypefnx {Function File} {} pcolor (@var{c})
+## Density plot for given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{c} corresponding to the @var{x} and @var{y} coordinates of
+## the mesh's vertices.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{c}(i,j)).  Thus, columns of @var{c}
+## correspond to different @var{x} values and rows of @var{c} correspond
+## to different @var{y} values.
+##
+## The @code{colormap} is scaled to the extents of @var{c}.
+## Limits may be placed on the color axis by the
+## command @code{caxis}, or by setting the @code{clim} property of the
+## parent axis.
+##
+## The face color of each cell of the mesh is determined by interpolating
+## the values of @var{c} for the cell's vertices.  Contrast this with 
+## @code{imagesc} which renders one cell for each element of @var{c}.
+##
+## @code{shading} modifies an attribute determining the manner by which the
+## face color of each cell is interpolated from the values of @var{c},
+## and the visibility of the cells' edges.  By default the attribute is
+## "faceted", which renders a single color for each cell's face with the edge
+## visible.
+##
+## @var{h} is the handle to the surface object.
+##
+## @seealso{caxis, contour, meshgrid, imagesc, shading}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function h = pcolor (x, y, c)
+
+  newplot ();
+
+  if (nargin == 1)
+    c = x;
+    [nr, nc] = size(c);
+    z = zeros (nr, nc);
+    [x, y] = meshgrid (1:nc, 1:nr);
+  elseif (nargin == 3)
+    z = zeros (size (c));
+  else
+    print_usage ();
+  endif
+
+  tmp = surface (x, y, z, c);
+
+  ax = get (tmp, "parent");
+
+  set (tmp, "facecolor", "flat");
+  set (ax, "box", "on");
+  
+  if (! ishold ())
+    set (ax, "view", [0, 90]);
+  endif
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/peaks.m b/scripts/plot/peaks.m
new file mode 100644
index 0000000..9bad40b
--- /dev/null
+++ b/scripts/plot/peaks.m
@@ -0,0 +1,86 @@
+## Copyright (C) 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} peaks ()
+## @deftypefnx {Function File} {} peaks (@var{n})
+## @deftypefnx {Function File} {} peaks (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{z} =} peaks (@dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} peaks (@dots{})
+## Generate a function with lots of local maxima and minima.  The function
+## has the form
+##
+## @tex
+## $f(x,y) = 3 (1 - x) ^ 2 e ^ {\left(-x^2 - (y+1)^2\right)} - 10 \left({x \over 5} - x^3 - y^5)\right) - {1 \over 3} e^{\left(-(x+1)^2 - y^2\right)}$
+## @end tex
+## @ifnottex
+## @verbatim
+## f(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) ...
+##          - 10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) ...
+##          - 1/3*exp(-(x+1)^2 - y^2)
+## @end verbatim
+## @end ifnottex
+##
+## Called without a return argument, @code{peaks} plots the surface of the 
+## above function using @code{mesh}.  If @var{n} is a scalar, the @code{peaks}
+## returns the values of the above function on a @var{n}-by- at var{n} mesh over
+## the range @code{[-3,3]}.  The default value for @var{n} is 49.
+##
+## If @var{n} is a vector, then it represents the @var{x} and @var{y} values
+## of the grid on which to calculate the above function.  The @var{x} and 
+## @var{y} values can be specified separately.
+## @seealso{surf, mesh, meshgrid}
+## @end deftypefn
+
+## Expression for the peaks function was taken from the following paper:
+## http://www.control.hut.fi/Kurssit/AS-74.115/Material/GENALGgoga.pdf
+
+function [X_out, Y_out, Z_out] = peaks (x, y)
+
+  if (nargin == 0)
+    x = y = linspace (-3, 3, 49);
+  elseif (nargin == 1)
+    if length(x) > 1
+      y = x;
+    else
+      x = y = linspace (-3, 3, x);
+    endif
+  endif
+
+  if (isvector (x) && isvector (y))
+    [X, Y] = meshgrid (x, y);
+  else
+    X = x;
+    Y = y;
+  endif
+
+  Z = 3 * (1 - X) .^ 2 .* exp(- X .^ 2 - (Y + 1) .^ 2) \
+      - 10 * (X / 5 - X .^ 3 - Y .^ 5) .* exp(- X .^ 2 - Y .^ 2) \
+      - 1 / 3 * exp(- (X + 1) .^ 2 - Y .^ 2);
+
+  if (nargout == 0)
+    surf (x, y, Z);
+  elseif (nargout == 1)
+    X_out = Z;
+  else
+    X_out = X;
+    Y_out = Y;
+    Z_out = Z;
+  endif
+
+endfunction
diff --git a/scripts/plot/pie.m b/scripts/plot/pie.m
new file mode 100644
index 0000000..35d3694
--- /dev/null
+++ b/scripts/plot/pie.m
@@ -0,0 +1,163 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pie (@var{y})
+## @deftypefnx {Function File} {} pie (@var{y}, @var{explode})
+## @deftypefnx {Function File} {} pie (@dots{}, @var{labels})
+## @deftypefnx {Function File} {} pie (@var{h}, @dots{});
+## @deftypefnx {Function File} {@var{h} =} pie (@dots{});
+## Produce a pie chart. 
+##
+## Called with a single vector argument, produces a pie chart of the
+## elements in @var{x}, with the size of the slice determined by percentage
+## size of the values of @var{x}.
+##
+## The variable @var{explode} is a vector of the same length as @var{x} that
+## if non zero 'explodes' the slice from the pie chart.
+##
+## If given @var{labels} is a cell array of strings of the same length as
+## @var{x}, giving the labels of each of the slices of the pie chart. 
+##
+## The optional return value @var{h} provides a handle to the patch object.
+##
+## @seealso{bar, stem}
+## @end deftypefn
+
+## Very roughly based on pie.m from octave-forge whose author was
+## Daniel Heiserer <Daniel.heiserer at physik.tu-muenchen.de>
+
+function retval = pie (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("pie", varargin{:});
+
+  if (nargin < 1)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      tmp = __pie__ (h, varargin{:});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+function hlist = __pie__ (varargin)
+
+  h = varargin{1};
+  x = abs (varargin{2});
+  iarg = 3;
+
+  if (! isvector (x))
+    error ("pie: expecting vector argument");
+  endif
+
+  len = length (x);
+
+  have_explode = false;
+  have_labels = false;
+
+  while (iarg <= nargin)
+    arg = varargin{iarg++};
+    if (iscell (arg))
+      labels = arg;
+      have_labels = true;
+      if (numel (x) != numel (labels))
+	error ("pie: mismatch in number of labels and data");
+      endif
+    elseif (isnumeric (arg))
+      explode = arg;
+      have_explode = true;
+      if (! size_equal (x, explode))
+	error ("pie: mismatch in number of elements in explode and data");
+      endif
+    endif
+  endwhile
+
+  if (! have_explode)
+    explode = zeros (size (x));
+  endif
+
+  if (! have_labels)
+    xp = round (100 * x ./ sum (x)); 
+    for i = 1:len
+      labels{i} = sprintf ("%d%%", xp(i));
+    endfor
+  endif
+
+  hlist = [];
+  refinement = 90;
+  phi = 0:refinement:360;
+  xphi = cumsum (x / sum (x) * 360);
+  for i = 1:len 
+    if (i == 1)
+      xn = 0 : 360 / refinement : xphi(i);
+    else
+      xn = xphi(i-1) : 360 / refinement : xphi(i);
+    endif
+
+    if (xn(end) != xphi(i))
+      xn = [xn, xphi(i)];
+    endif
+
+    xn2 = (xn(1) + xn(end)) / 2;
+    if (explode (i))
+      xoff = - 0.1 * sind (xn2);
+      yoff = 0.1 * cosd (xn2);
+    else
+      xoff = 0;
+      yoff = 0;
+    endif
+    xt = - 1.2 * sind (xn2);
+    yt = 1.2 * cosd (xn2);
+    if (xt > 0)
+      align = "left";
+    else
+      align = "right";
+    endif
+
+    hlist = [hlist; patch(xoff + [0, - sind(xn)], yoff + [0, cosd(xn)], i);
+    	     text(xt, yt, labels{i}, "horizontalalignment", align)];
+  endfor
+
+  if (len == 1)
+    set (h, "clim", [1, 2]);
+  else
+    set (h, "clim", [1, len]);
+  endif
+
+  axis ([-1.5, 1.5, -1.5, 1.5], "square");
+
+endfunction
+
+%!demo
+%! pie ([3, 2, 1], [0, 0, 1]);
+%! colormap([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
+
+%!demo
+%! pie ([3, 2, 1], [0, 0, 1], {"Cheddar", "Swiss", "Camembert"});
+%! colormap([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
+%! axis ([-2,2,-2,2]);
diff --git a/scripts/plot/plot.m b/scripts/plot/plot.m
new file mode 100644
index 0000000..9dd752d
--- /dev/null
+++ b/scripts/plot/plot.m
@@ -0,0 +1,193 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} plot (@var{y})
+## @deftypefnx {Function File} {} plot (@var{x}, @var{y})
+## @deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
+## @deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{fmt})
+## @deftypefnx {Function File} {} plot (@var{h}, @dots{})
+## Produces two-dimensional plots.  Many different combinations of
+## arguments are possible.  The simplest form is
+##
+## @example
+## plot (@var{y})
+## @end example
+##
+## @noindent
+## where the argument is taken as the set of @var{y} coordinates and the
+## @var{x} coordinates are taken to be the indices of the elements,
+## starting with 1.
+##
+## To save a plot, in one of several image formats such as PostScript
+## or PNG, use the @code{print} command.
+##
+## If more than one argument is given, they are interpreted as
+##
+## @example
+## plot (@var{y}, @var{property}, @var{value}, @dots{})
+## @end example
+##
+## @noindent
+## or
+##
+## @example
+## plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
+## @end example
+##
+## @noindent
+## or
+##
+## @example
+## plot (@var{x}, @var{y}, @var{fmt}, @dots{})
+## @end example
+##
+## @noindent
+## and so on.  Any number of argument sets may appear.  The @var{x} and
+## @var{y} values are interpreted as follows:
+##
+## @itemize @bullet
+## @item
+## If a single data argument is supplied, it is taken as the set of @var{y}
+## coordinates and the @var{x} coordinates are taken to be the indices of
+## the elements, starting with 1.
+##
+## @item
+## If the @var{x} is a vector and @var{y} is a matrix, then
+## the columns (or rows) of @var{y} are plotted versus @var{x}.
+## (using whichever combination matches, with columns tried first.)
+##
+## @item
+## If the @var{x} is a matrix and @var{y} is a vector,
+## @var{y} is plotted versus the columns (or rows) of @var{x}.
+## (using whichever combination matches, with columns tried first.)
+##
+## @item
+## If both arguments are vectors, the elements of @var{y} are plotted versus
+## the elements of @var{x}.
+##
+## @item
+## If both arguments are matrices, the columns of @var{y} are plotted
+## versus the columns of @var{x}.  In this case, both matrices must have
+## the same number of rows and columns and no attempt is made to transpose
+## the arguments to make the number of rows match.
+##
+## If both arguments are scalars, a single point is plotted.
+## @end itemize
+##
+## Multiple property-value pairs may be specified, but they must appear
+## in pairs.  These arguments are applied to the lines drawn by
+## @code{plot}.
+##
+## If the @var{fmt} argument is supplied, it is interpreted as
+## follows.  If @var{fmt} is missing, the default gnuplot line style
+## is assumed.
+##
+## @table @samp
+## @item -
+## Set lines plot style (default).
+##
+## @item .
+## Set dots plot style.
+##
+## @item @var{n}
+## Interpreted as the plot color if @var{n} is an integer in the range 1 to
+## 6.
+##
+## @item @var{nm}
+## If @var{nm} is a two digit integer and @var{m} is an integer in the
+## range 1 to 6, @var{m} is interpreted as the point style.  This is only
+## valid in combination with the @code{@@} or @code{-@@} specifiers.
+##
+## @item @var{c}
+## If @var{c} is one of @code{"k"} (black), @code{"r"} (red), @code{"g"}
+## (green), @code{"b"} (blue), @code{"m"} (magenta), @code{"c"} (cyan),
+## or @code{"w"} (white), it is interpreted as the line plot color.
+##
+## @item ";title;"
+## Here @code{"title"} is the label for the key.
+##
+## @item +
+## @itemx *
+## @itemx o
+## @itemx x
+## @itemx ^
+## Used in combination with the points or linespoints styles, set the point
+## style.
+## @end table
+##
+## The @var{fmt} argument may also be used to assign key titles.
+## To do so, include the desired title between semi-colons after the
+## formatting sequence described above, e.g., "+3;Key Title;"
+## Note that the last semi-colon is required and will generate an error if
+## it is left out.
+##
+## Here are some plot examples:
+##
+## @example
+## plot (x, y, "@@12", x, y2, x, y3, "4", x, y4, "+")
+## @end example
+##
+## This command will plot @code{y} with points of type 2 (displayed as
+## @samp{+}) and color 1 (red), @code{y2} with lines, @code{y3} with lines of
+## color 4 (magenta) and @code{y4} with points displayed as @samp{+}.
+##
+## @example
+## plot (b, "*", "markersize", 3)
+## @end example
+##
+## This command will plot the data in the variable @code{b},
+## with points displayed as @samp{*} with a marker size of 3.
+##
+## @example
+## @group
+## t = 0:0.1:6.3;
+## plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+## @end group
+## @end example
+##
+## This will plot the cosine and sine functions and label them accordingly
+## in the key.
+##
+## If the first argument is an axis handle, then plot into these axes, 
+## rather than the current axis handle returned by @code{gca}. 
+## @seealso{semilogx, semilogy, loglog, polar, mesh, contour, bar,
+## stairs, errorbar, xlabel, ylabel, title, print}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = plot (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("plot", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+    tmp = __plt__ ("plot", h, varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/plot3.m b/scripts/plot/plot3.m
new file mode 100644
index 0000000..0715bf4
--- /dev/null
+++ b/scripts/plot/plot3.m
@@ -0,0 +1,320 @@
+## Copyright (C) 1996, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} plot3 (@var{args})
+## Produce three-dimensional plots.  Many different combinations of
+## arguments are possible.  The simplest form is
+##
+## @example
+## plot3 (@var{x}, @var{y}, @var{z})
+## @end example
+##
+## @noindent
+## in which the arguments are taken to be the vertices of the points to
+## be plotted in three dimensions.  If all arguments are vectors of the
+## same length, then a single continuous line is drawn.  If all arguments
+## are matrices, then each column of the matrices is treated as a
+## separate line.  No attempt is made to transpose the arguments to make
+## the number of rows match.
+##
+## If only two arguments are given, as
+##
+## @example
+## plot3 (@var{x}, @var{c})
+## @end example
+##
+## @noindent
+## the real and imaginary parts of the second argument are used
+## as the @var{y} and @var{z} coordinates, respectively.
+##
+## If only one argument is given, as
+##
+## @example
+## plot3 (@var{c})
+## @end example
+##
+## @noindent
+## the real and imaginary parts of the argument are used as the @var{y}
+## and @var{z} values, and they are plotted versus their index.
+##
+## Arguments may also be given in groups of three as
+##
+## @example
+## plot3 (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2}, @dots{})
+## @end example
+## 
+## @noindent
+## in which each set of three arguments is treated as a separate line or
+## set of lines in three dimensions.
+##
+## To plot multiple one- or two-argument groups, separate each group
+## with an empty format string, as
+##
+## @example
+## plot3 (@var{x1}, @var{c1}, "", @var{c2}, "", @dots{})
+## @end example
+##
+## An example of the use of @code{plot3} is
+##
+## @example
+## @group
+##    z = [0:0.05:5];
+##    plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+##    plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
+## @end group
+## @end example
+## @seealso{plot, xlabel, ylabel, zlabel, title, print}
+## @end deftypefn
+
+## Author: Paul Kienzle
+##         (modified from __plt__.m)
+
+function retval = plot3 (varargin)
+
+  newplot ();
+
+  x_set = 0;
+  y_set = 0;
+  z_set = 0;
+  property_set = 0;
+  fmt_set = 0;
+  properties = {};
+
+  idx = 0;
+
+  ## Gather arguments, decode format, and plot lines.
+  arg = 0;
+  while (arg++ < nargin)
+    new = varargin{arg};
+    new_cell = varargin(arg);
+
+    if (property_set)
+      properties = [properties, new_cell];
+      property_set = 0;
+      continue;
+    endif
+
+    if (ischar (new))
+      if (! z_set)
+	if (! y_set)
+	  if (! x_set)
+	    error ("plot3: needs x, [ y, [ z ] ]");
+	  else
+	    z = imag (x);
+	    y = real (x);
+	    y_set = 1;
+	    z_set = 1;
+	    if (rows(x) > 1)
+	      x = repmat ((1:rows(x))', 1, columns(x));
+	    else
+	      x = 1:columns(x);
+	    endif
+	  endif
+	else
+	  z = imag (y);
+	  y = real (y);
+	  z_set = 1;
+	endif
+      endif
+
+      if (! fmt_set)
+	[options, valid] = __pltopt__ ("plot3", new, false);
+	if (! valid)
+	  properties = [properties, new_cell];
+	  property_set = 1;
+	  continue;
+	else
+	  fmt_set = 1;
+	  while (arg < nargin && ischar (varargin{arg+1}))
+	    if (nargin - arg < 2)
+	      error ("plot3: properties must appear followed by a value");
+	    endif
+	    properties = [properties, varargin(arg+1:arg+2)];
+	    arg += 2;
+	  endwhile
+	endif
+      else
+	properties = [properties, new_cell];
+	property_set = 1;
+	continue;
+      endif
+
+      if (isvector (x) && isvector (y))
+	if (isvector (z))
+	  x = x(:);
+	  y = y(:);
+	  z = z(:);
+	elseif (length (x) == rows (z) && length (y) == columns (z))
+	  [x, y] = meshgrid (x, y);
+	else
+	  error ("plot3: [length(x), length(y)] must match size(z)");
+	endif
+      endif
+
+      if (! size_equal (x, y, z))
+	error ("plot3: x, y, and z must have the same shape");
+      endif
+
+      key = options.key;
+      if (! isempty (key))
+	set (gca (), "key", "on");
+      endif
+
+      for i = 1 : columns (x)
+	color = options.color;
+	if (isempty (options.color))
+	  color = __next_line_color__ ();
+	endif
+
+	tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key,
+			   "color", color,
+			   "linestyle", options.linestyle,
+			   "marker", options.marker, properties{:});
+      endfor
+
+      x_set = 0;
+      y_set = 0;
+      z_set = 0;
+      fmt_set = 0;
+      properties = {};
+    elseif (! x_set)
+      x = new;
+      x_set = 1;
+    elseif (! y_set)
+      y = new;
+      y_set = 1;
+    elseif (! z_set)
+      z = new;
+      z_set = 1;
+    else
+      if (isvector (x) && isvector (y))
+	if (isvector (z))
+	  x = x(:);
+	  y = y(:);
+	  z = z(:);
+	elseif (length (x) == rows (z) && length (y) == columns (z))
+	  [x, y] = meshgrid (x, y);
+	else
+	  error ("plot3: [length(x), length(y)] must match size(z)");
+	endif
+      endif
+
+      if (! size_equal (x, y, z))
+	error ("plot3: x, y, and z must have the same shape");
+      endif
+
+      options =  __default_plot_options__ ();
+      key = options.key;
+      if (! isempty (key))
+	set (gca (), "key", "on");
+      endif
+
+      for i = 1 : columns (x)
+	color = options.color;
+	if (isempty (color))
+	  color = __next_line_color__ ();
+	endif
+
+	tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key,
+			   "color", color,
+			   "linestyle", options.linestyle,
+			   "marker", options.marker, properties{:});
+      endfor
+
+      x = new;
+      y_set = 0;
+      z_set = 0;
+      fmt_set = 0;
+      properties = {};
+    endif
+
+  endwhile
+
+  if (property_set)
+    error ("plot3: properties must appear followed by a value");
+  endif
+
+  ## Handle last plot.
+
+  if (x_set)
+    if (y_set)
+      if (! z_set)
+	z = imag (y);
+	y = real (y);
+	z_set = 1;
+      endif
+    else
+      z = imag (x);
+      y = real (x);
+      y_set = 1;
+      z_set = 1;
+      if (rows (x) > 1)
+	x = repmat ((1:rows (x))', 1, columns(x));
+      else
+	x = 1:columns(x);
+      endif
+    endif
+
+    if (isvector (x) && isvector (y))
+      if (isvector (z))
+	x = x(:);
+	y = y(:);
+	z = z(:);
+      elseif (length (x) == rows (z) && length (y) == columns (z))
+	[x, y] = meshgrid (x, y);
+      else
+	error ("plot3: [length(x), length(y)] must match size(z)");
+      endif
+    endif
+
+    if (! size_equal (x, y, z))
+      error ("plot3: x, y, and z must have the same shape");
+    endif
+
+    options =  __default_plot_options__ ();
+    key = options.key;
+    if (! isempty (key))
+      set (gca (), "key", "on");
+    endif
+
+    for i = 1 : columns (x)
+      color = options.color;
+      if (isempty (color))
+	color = __next_line_color__ ();
+      endif
+
+      tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key, 
+			 "color", color,
+			 "linestyle", options.linestyle,
+			 "marker", options.marker, properties{:});
+    endfor
+  endif
+
+  set (gca (), "view", [-37.5, 30]);
+
+  if (nargout > 0 && idx > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! z = [0:0.05:5];
+%! plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
+%! plot3 (z, exp(2i*pi*z), ";complex sinusoid;");
diff --git a/scripts/plot/plotmatrix.m b/scripts/plot/plotmatrix.m
new file mode 100644
index 0000000..2fdee2b
--- /dev/null
+++ b/scripts/plot/plotmatrix.m
@@ -0,0 +1,189 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} plotmatrix (@var{x}, @var{y})
+## @deftypefnx {Function File} {} plotmatrix (@var{x})
+## @deftypefnx {Function File} {} plotmatrix (@dots{}, @var{style})
+## @deftypefnx {Function File} {} plotmatrix (@var{h}, @dots{})
+## @deftypefnx {Function File} {[@var{h}, @var{ax}, @var{bigax}, @var{p}, @var{pax}] =} plotmatrix (@dots{})
+## Scatter plot of the columns of one matrix against another.  Given the
+## arguments @var{x} and @var{y}, that have a matching number of rows,
+## @code{plotmatrix} plots a set of axes corresponding to
+##
+## @example
+## plot (@var{x} (:, i), @var{y} (:, j)
+## @end example
+##
+## Given a single argument @var{x}, then this is equivalent to 
+##
+## @example
+## plotmatrix (@var{x}, @var{x})
+## @end example
+##
+## @noindent
+## except that the diagonal of the set of axes will be replaced with the
+## histogram @code{hist (@var{x} (:, i))}.
+##
+## The marker to use can be changed with the @var{style} argument, that is a 
+## string defining a marker in the same manner as the @code{plot}
+## command.  If a leading axes handle @var{h} is passed to
+## @code{plotmatrix}, then this axis will be used for the plot.
+##
+## The optional return value @var{h} provides handles to the individual
+## graphics objects in the scatter plots, whereas @var{ax} returns the
+## handles to the scatter plot axis objects.  @var{bigax} is a hidden
+## axis object that surrounds the other axes, such that the commands 
+## @code{xlabel}, @code{title}, etc., will be associated with this hidden
+## axis.  Finally @var{p} returns the graphics objects associated with
+## the histogram and @var{pax} the corresponding axes objects.
+##
+## @example
+## @group
+## plotmatrix (randn (100, 3), 'g+')
+## @end group
+## @end example
+##
+## @end deftypefn
+
+function [h, ax, bigax, p, pax] = plotmatrix (varargin)
+
+  [bigax2, varargin, nargin] = __plt_get_axis_arg__ ("plotmatrix", varargin{:});
+
+  if (nargin > 3 || nargin < 1)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (bigax2);
+      newplot ();
+      [h2, ax2, p2, pax2, need_usage] = __plotmatrix__ (bigax2, varargin{:});
+      if (need_usage)
+	print_usage ();
+      endif
+      if (nargout > 0)
+	h = h2;
+	ax = ax2;
+	bigax = bigax2;
+	p = p2;
+	pax = pax2;
+      endif
+      axes (bigax2);
+      ctext = text (0, 0, "", "visible", "off", 
+		    "handlevisibility", "off", "xliminclude", "off",  
+		    "yliminclude", "off", "zliminclude", "off",
+		    "deletefcn", {@plotmatrixdelete, [ax2; pax2]});
+      set (bigax2, "visible", "off");
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+endfunction
+
+%!demo
+%! plotmatrix (randn (100, 3), 'g+')
+
+function plotmatrixdelete (h, d, ax)
+  for i = 1 : numel (ax)
+    hc = ax(i);
+    if (ishandle (hc) && strcmp (get (hc, "type"), "axes") && 
+	strcmpi (get (hc, "beingdeleted"), "off"))
+      parent = get (hc, "parent");
+      ## If the parent is invalid or being deleted, then do nothing
+      if (ishandle (parent) && strcmpi (get (parent, "beingdeleted"), "off"))
+	delete (hc);
+      endif
+    endif
+  endfor
+endfunction
+
+function [h, ax, p, pax, need_usage] = __plotmatrix__ (bigax, varargin)
+  need_usage = false;
+  have_line_spec = false;
+  have_hist = false;
+  parent = get (bigax, "parent");
+  for i = 1 : nargin - 1
+    arg = varargin{i};
+    if (ischar (arg) || iscell (arg))
+      [linespec, valid] = __pltopt__ ("plotmatrix", varargin{i}, false);
+      if (valid)
+	have_line_spec = true;      
+	linespec = varargin(i);
+	varargin(i) = [];
+	nargin = nargin - 1;
+	break;
+      else
+	need_usage = true;
+	returm;
+      endif
+    endif
+  endfor
+
+  if (nargin == 2)
+    X = varargin{1};
+    Y = X;
+    have_hist = true;
+  elseif (nargin == 3)
+    X = varargin{1};
+    Y = varargin{2};
+  else
+    need_usage = true;
+    returm;
+  endif
+
+  if (rows(X) != rows(Y))
+    error ("plotmatrix: dimension mismatch in the arguments");
+  endif
+
+  [dummy, m] = size (X);
+  [dummy, n] = size (Y);
+
+  h = [];
+  ax = [];
+  p = [];
+  pax = [];
+
+  xsize = 0.9 / m;
+  ysize = 0.9 / n;
+  xoff = 0.05;
+  yoff = 0.05;
+  border = [0.130, 0.110, 0.225, 0.185] .* [xsize, ysize, xsize, ysize];
+  border(3:4) = - border(3:4) - border(1:2);
+
+  for i = 1 : n
+    for j = 1 : m
+      pos = [xsize * (j - 1) + xoff, ysize * (n - i) + yoff, xsize, ysize];
+      tmp = axes ("outerposition", pos, "position", pos + border,
+		  "parent", parent);
+      if (i == j && have_hist)
+	pax = [pax ; tmp];
+	[nn, xx] = hist (X(:, i));
+	tmp = bar (xx, nn, 1.0);
+	p = [p; tmp];
+      else
+	ax = [ax ; tmp];
+	if (have_line_spec)
+	  tmp = plot (X (:, i), Y (:, j), linespec);
+	else
+	  tmp = plot (X (:, i), Y (:, j), ".");
+	endif
+	h = [h ; tmp];
+      endif
+    endfor
+  endfor
+endfunction
diff --git a/scripts/plot/plotyy.m b/scripts/plot/plotyy.m
new file mode 100644
index 0000000..12b9845
--- /dev/null
+++ b/scripts/plot/plotyy.m
@@ -0,0 +1,268 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} plotyy (@var{x1}, @var{y1}, @var{x2}, @var{y2})
+## @deftypefnx {Function File} {} plotyy (@dots{}, @var{fun})
+## @deftypefnx {Function File} {} plotyy (@dots{}, @var{fun1}, @var{fun2})
+## @deftypefnx {Function File} {} plotyy (@var{h}, @dots{})
+## @deftypefnx {Function File} {[@var{ax}, @var{h1}, @var{h2}] =} plotyy (@dots{})
+## Plots two sets of data with independent y-axes.  The arguments @var{x1} and
+## @var{y1} define the arguments for the first plot and @var{x1} and @var{y2}
+## for the second. 
+##
+## By default the arguments are evaluated with 
+## @code{feval (@@plot, @var{x}, @var{y})}.  However the type of plot can be
+## modified with the @var{fun} argument, in which case the plots are
+## generated by @code{feval (@var{fun}, @var{x}, @var{y})}.  @var{fun} can be 
+## a function handle, an inline function or a string of a function name.
+##
+## The function to use for each of the plots can be independently defined 
+## with @var{fun1} and @var{fun2}.
+##
+## If given, @var{h} defines the principal axis in which to plot the @var{x1}
+## and @var{y1} data.  The return value @var{ax} is a two element vector with
+## the axis handles of the two plots.  @var{h1} and @var{h2} are handles to
+## the objects generated by the plot commands.
+##
+## @example
+## @group
+## x = 0:0.1:2*pi; 
+## y1 = sin (x);
+## y2 = exp (x - 1);
+## ax = plotyy (x, y1, x - 1, y2, @@plot, @@semilogy);
+## xlabel ("X");
+## ylabel (ax(1), "Axis 1");
+## ylabel (ax(2), "Axis 2");
+## @end group
+## @end example
+## @end deftypefn
+
+function [Ax, H1, H2] = plotyy (varargin)
+
+  ## Don't use __plt_get_axis_arg__ here as ax is a two vector for plotyy
+  if (nargin > 1 && length (varargin{1}) == 2 && ishandle(varargin{1}(1)) 
+      &&  ishandle(varargin{1}(2)) && 
+      all (floor (varargin{1}) != varargin{1}))
+    obj1 = get (varargin{1}(1));
+    obj2 = get (varargin{1}(2));
+    if (strcmp (obj1.type, "axes") || strcmp (obj2.type, "axes"))
+      ax = [obj1, obj2];
+      varargin(1) = [];
+      if (isempty (varargin))
+	varargin = {};
+      endif
+    else
+      error ("plotyy: expecting first argument to be axes handle");
+    endif
+  else
+    f = get (0, "currentfigure");
+    if (isempty (f))
+      f = figure ();
+    endif
+    ca = get (f, "currentaxes");
+    if (isempty (ca))
+      ax = [];
+    elseif (strcmp (get (ca, "tag"), "plotyy"));
+      ax = get (ca, "__plotyy_axes__");
+    else
+      ax = ca;
+    endif
+    if (length (ax) > 2)
+      for i = 3 : length (ax)
+        delete (ax (i));
+      endfor
+      ax = ax(1:2);
+    elseif (length (ax) == 1)
+      ax(2) = axes ();
+    elseif (isempty (ax))
+      ax(1) = axes ();
+      ax(2) = axes ();
+    endif
+    if (nargin < 2)
+      varargin = {};
+    endif
+  endif 
+
+  if (nargin < 4)
+    print_usage ();
+  endif
+
+  oldh = gca ();
+  unwind_protect
+    [ax, h1, h2] = __plotyy__ (ax, varargin{:});
+  unwind_protect_cleanup
+    ## Only change back to the old axis if we didn't delete it
+    if (ishandle(oldh) && strcmp (get (oldh, "type"), "axes"))
+      axes (oldh);
+    endif
+  end_unwind_protect
+
+  if (nargout > 0)
+    Ax = ax;
+    H1 = h1;
+    H2 = h2;
+  endif
+
+endfunction
+
+function [ax, h1, h2] = __plotyy__ (ax, x1, y1, x2, y2, varargin)
+  if (nargin > 5)
+    fun1 = varargin{1};
+  else
+    fun1 = @plot;
+  endif
+  if (nargin > 6)
+    fun2 = varargin{2};
+  else
+    fun2 = fun1;
+  endif
+
+  xlim = [min([x1(:); x2(:)]), max([x1(:); x2(:)])];
+
+  if (ishandle(ax(1)) && strcmp (get (ax(1), "type"), "axes"))
+    axes (ax(1));
+  else
+    ax(1) = axes ();
+  endif
+  newplot ();
+  h1 = feval (fun1, x1, y1);
+
+  set (ax(1), "ycolor", getcolor (h1(1)));
+  set (ax(1), "xlim", xlim);
+
+  cf = gcf ();
+  set (cf, "nextplot", "add");
+
+  if (ishandle(ax(2)) && strcmp (get (ax(2), "type"), "axes"))
+    axes (ax(2));
+  else
+    ax(2) = axes ();
+  endif
+  newplot ();
+
+  colors = get (ax(1), "colororder");
+  set (ax(2), "colororder", [colors(2:end,:); colors(1,:)]);
+
+  h2 = feval (fun2, x2, y2);
+  set (ax(2), "yaxislocation", "right");
+  set (ax(2), "ycolor", getcolor (h2(1)));
+  set (ax(2), "position", get (ax(1), "position"));
+  set (ax(2), "xlim", xlim);
+  set (ax(2), "color", "none");
+
+  ## Add invisible text objects that when destroyed, 
+  ## also remove the other axis
+  t1 = text (0, 0, "", "parent", ax(1), "tag", "plotyy", 
+	     "handlevisibility", "off", "visible", "off",
+	     "xliminclude", "off", "yliminclude", "off");
+  t2 = text (0, 0, "", "parent", ax(2), "tag", "plotyy", 
+	     "handlevisibility", "off", "visible", "off",
+	     "xliminclude", "off", "yliminclude", "off");
+
+  set (t1, "deletefcn", {@deleteplotyy, ax(2), t2});
+  set (t2, "deletefcn", {@deleteplotyy, ax(1), t1});
+
+  addlistener (ax(1), "position", {@update_position, ax(2)});
+  addlistener (ax(2), "position", {@update_position, ax(1)});
+  addlistener (ax(1), "view", {@update_position, ax(2)});
+  addlistener (ax(2), "view", {@update_position, ax(1)});
+  addlistener (ax(1), "dataaspectratio", {@update_position, ax(2)});
+  addlistener (ax(2), "dataaspectratio", {@update_position, ax(1)});
+
+  ## Tag the plotyy axes, so we can use that information
+  ## not to mirror the y axis tick marks
+  set (ax, "tag", "plotyy")
+
+  ## Store the axes handles for the sister axes.
+  addproperty ("__plotyy_axes__", ax(1), "data", ax);
+  addproperty ("__plotyy_axes__", ax(2), "data", ax);
+
+endfunction
+
+%!demo
+%! clf
+%! x = 0:0.1:2*pi; 
+%! y1 = sin (x);
+%! y2 = exp (x - 1);
+%! ax = plotyy (x, y1, x - 1, y2, @plot, @semilogy);
+%! xlabel ("X");
+%! ylabel (ax(1), "Axis 1");
+%! ylabel (ax(2), "Axis 2");
+
+%!demo
+%! clf
+%! x = linspace (-1, 1, 201);
+%! subplot (2, 2, 1)
+%! plotyy (x, sin(pi*x), x, 10*cos(pi*x))
+%! subplot (2, 2, 2)
+%! surf (peaks (25))
+%! subplot (2, 2, 3)
+%! contour (peaks (25))
+%! subplot (2, 2, 4)
+%! plotyy (x, 10*sin(2*pi*x), x, cos(2*pi*x))
+%! axis square
+
+function deleteplotyy (h, d, ax2, t2)
+  if (ishandle (ax2) && strcmp (get (ax2, "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) &&
+      strcmp (get (ax2, "beingdeleted"), "off"))
+    set (t2, "deletefcn", []);
+    delete (ax2);
+  endif
+endfunction
+
+function update_position (h, d, ax2)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      position = get (h, "position");
+      view = get (h, "view");
+      dataaspectratio = get (h, "dataaspectratio");
+      oldposition = get (ax2, "position");
+      oldview = get (ax2, "view");
+      olddataaspectratio = get (ax2, "dataaspectratio");
+      if (! (isequal (position, oldposition)
+             && isequal (view, oldview)
+             && isequal (dataaspectratio, olddataaspectratio)))
+	set (ax2, "position", position,
+                  "view", view,
+		  "dataaspectratio", dataaspectratio);
+      endif
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif  
+endfunction
+
+function color = getcolor (ax)
+  obj = get (ax);
+  if (isfield (obj, "color"))
+    color = obj.color;
+  elseif (isfield (obj, "facecolor") && ! ischar (obj.facecolor))
+    color = obj.facecolor;
+  elseif (isfield (obj, "edgecolor") && !  ischar (obj.edgecolor))
+    color = obj.edgecolor;
+  else
+    color = [0, 0, 0];
+  endif
+endfunction
+
diff --git a/scripts/plot/polar.m b/scripts/plot/polar.m
new file mode 100644
index 0000000..f2b2c80
--- /dev/null
+++ b/scripts/plot/polar.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005,
+##               2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polar (@var{theta}, @var{rho}, @var{fmt})
+## Make a two-dimensional plot given the polar coordinates @var{theta} and
+## @var{rho}.
+##
+## The optional third argument specifies the line type.
+## @seealso{plot}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = polar (varargin)
+
+  [h, varargin, nargs] = __plt_get_axis_arg__ ("polar", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    if (nargs == 3)
+      if (! ischar (varargin{3}))
+	error ("polar: third argument must be a string");
+      endif
+      tmp = __plr2__ (h, varargin{:});
+      maxr = max (varargin {2} (:));
+    elseif (nargs == 2)
+      if (ischar (varargin{2}))
+	tmp = __plr1__ (h, varargin{:});
+	if (iscomplex(varargin{1}))
+	  maxr = max (imag(varargin{1})(:));
+	else
+	  maxr = max (varargin{1}(:));
+	endif
+      else
+	fmt = "";
+	tmp = __plr2__ (h, varargin{:}, fmt);
+	maxr = max (varargin {2} (:));
+      endif
+    elseif (nargs == 1)
+      fmt = "";
+      tmp = __plr1__ (h, varargin{:}, fmt);
+      if (iscomplex(varargin{1}))
+	maxr = max (imag(varargin{1})(:));
+      else
+	maxr = max (varargin{1}(:));
+      endif
+    else
+      print_usage ();
+    endif
+
+    set (h, "xlim", [-maxr, maxr], "ylim", [-maxr, maxr],
+	 "xaxislocation", "zero", "yaxislocation", "zero",
+	 "dataaspectratio", [1, 1, 1]); 
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/print.m b/scripts/plot/print.m
new file mode 100644
index 0000000..8868a13
--- /dev/null
+++ b/scripts/plot/print.m
@@ -0,0 +1,811 @@
+## Copyright (C) 1999, 2005, 2006, 2007, 2008, 2009 Daniel Heiserer
+## Copyright (C) 2001 Laurent Mazet
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} print ()
+## @deftypefnx {Function File} {} print (@var{options})
+## @deftypefnx {Function File} {} print (@var{filename}, @var{options})
+## @deftypefnx {Function File} {} print (@var{h}, @var{filename}, @var{options})
+## Print a graph, or save it to a file
+##
+## @var{filename} defines the file name of the output file.  If no
+## filename is specified, the output is sent to the printer.
+##
+## @var{h} specifies the figure handle.  If no handle is specified
+## the handle for the current figure is used.
+##
+## @var{options}:
+## @table @code
+## @item -P at var{printer}
+##   Set the @var{printer} name to which the graph is sent if no
+##   @var{filename} is specified.
+## @item -G at var{ghostscript_command}
+##   Specify the command for calling Ghostscript.  For Unix and Windows,
+## the defaults are 'gs' and 'gswin32c', respectively.
+## @item -color
+## @itemx -mono
+##   Monochrome or color lines.
+## @item -solid
+## @itemx -dashed
+##   Solid or dashed lines.
+## @item -portrait
+## @itemx -landscape
+##   Specify the orientation of the plot for printed output.
+## @item -d at var{device}
+##   Output device, where @var{device} is one of:
+##   @table @code
+##   @item ps
+##   @itemx ps2
+##   @itemx psc
+##   @itemx psc2
+##     Postscript (level 1 and 2, mono and color)
+##   @item eps
+##   @itemx eps2
+##   @itemx epsc
+##   @itemx epsc2
+##     Encapsulated postscript (level 1 and 2, mono and color)
+##   @item tex
+##   @itemx epslatex
+##   @itemx epslatexstandalone
+##   @itemx pstex
+##   @itemx pslatex
+##     Generate a @LaTeX{} (or @TeX{}) file for labels, and eps/ps for
+## graphics.  The file produced by @code{epslatexstandalone} can be
+## processed directly by @LaTeX{}.  The other formats are intended to
+## be included in a @LaTeX{} (or @TeX{}) document.  The @code{tex} device
+## is the same as the @code{epslatex} device.
+##   @item ill
+##   @itemx aifm
+##     Adobe Illustrator
+##   @item cdr
+##   @itemx corel
+##     CorelDraw
+##   @item dxf
+##     AutoCAD
+##   @item emf
+##   @itemx meta
+##     Microsoft Enhanced Metafile
+##   @item fig
+##     XFig.  If this format is selected the additional options
+##     @code{-textspecial} or @code{-textnormal} can be used to control
+##     whether the special flag should be set for the text in
+##     the figure (default is @code{-textnormal}). 
+##   @item hpgl
+##     HP plotter language
+##   @item mf
+##     Metafont
+##   @item png
+##     Portable network graphics
+##   @item jpg
+##   @itemx jpeg
+##     JPEG image
+##   @item gif
+##     GIF image
+##   @item pbm
+##     PBMplus
+##   @item svg
+##     Scalable vector graphics
+##   @item pdf
+##     Portable document format
+##   @end table
+##
+##   If the device is omitted, it is inferred from the file extension,
+## or if there is no filename it is sent to the printer as postscript.
+##
+## @item -d at var{gs_device}
+##   Additional devices are supported by Ghostscript.
+## Some examples are;
+##
+##   @table @code
+##   @item ljet2p 
+##     HP LaserJet IIP
+##   @item ljet3 
+##     HP LaserJet III
+##   @item deskjet
+##     HP DeskJet and DeskJet Plus
+##   @item cdj550
+##     HP DeskJet 550C
+##   @item paintjet
+##     HP PointJet
+##   @item pcx24b
+##     24-bit color PCX file format
+##   @item ppm
+##     Portable Pixel Map file format
+##   @end table
+##
+##   For a complete list, type `system ("gs -h")' to see what formats
+## and devices are available.
+##
+##   When the ghostscript is sent to a printer the size is determined
+## by the figure's "papersize" property.  When the ghostscript output 
+## is sent to a file the size is determined by the figure's
+## "paperposition" property.
+##
+## @itemx -r at var{NUM}
+##   Resolution of bitmaps in pixels per inch.  For both metafiles and 
+## SVG the default is the screen resolution, for other it is 150 dpi.
+## To specify screen resolution, use "-r0".
+##
+## @item -tight
+##   Forces a tight bounding box for eps-files.  Since the ghostscript
+## devices are conversion of an eps-file, this option works the those
+## devices as well.
+##
+## @itemx -S at var{xsize}, at var{ysize}
+##   Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG.  If
+## using the command form of the print function, you must quote the
+## @var{xsize}, at var{ysize} option.  For example, by writing
+## @w{@code{"-S640,480"}}.  The size defaults to that specified by the
+## figure's paperposition property.
+##
+## @item -F at var{fontname}
+## @itemx -F at var{fontname}:@var{size}
+## @itemx -F:@var{size}
+##   @var{fontname} set the postscript font (for use with postscript,
+## aifm, corel and fig).  By default, 'Helvetica' is set for PS/Aifm,
+## and 'SwitzerlandLight' for Corel.  It can also be 'Times-Roman'.
+## @var{size} is given in points.  @var{fontname} is ignored for the
+## fig device.
+## @end table
+##
+## The filename and options can be given in any order.
+## @end deftypefn
+
+## Author: Daniel Heiserer <Daniel.heiserer at physik.tu-muenchen.de>
+## Adapted-By: jwe
+
+function print (varargin)
+
+  persistent warn_on_inconsistent_orientation = true
+  orientation = "";
+  use_color = 0; # 0=default, -1=mono, +1=color
+  force_solid = 0; # 0=default, -1=dashed, +1=solid
+  fontsize = "";
+  font = "";
+  canvas_size = "";
+  name = "";
+  devopt = "";
+  printer = "";
+  debug = false;
+  debug_file = "octave-print-commands.log";
+  special_flag = "textnormal";
+  tight_flag = false;
+  resolution = "";
+
+  persistent ghostscript_binary = "";
+  if (isempty (ghostscript_binary))
+    ghostscript_binary = getenv ("GSC");
+    ng = 0;
+    if (isunix ())
+      ## Unix - Includes Mac OSX and Cygwin.
+      gs_binaries = {"gs", "gs.exe"};
+    else
+      ## pc - Includes Win32 and mingw.
+      gs_binaries = {"gs.exe", "gswin32c.exe"};
+    endif
+    while (ng < numel (gs_binaries) && isempty (ghostscript_binary))
+      ng = ng + 1;
+      ghostscript_binary = file_in_path (EXEC_PATH, gs_binaries{ng});
+    endwhile
+  endif
+
+  old_fig = get (0, "currentfigure");
+  unwind_protect
+    ## Ensure the last figure is on the screen for single line commands like
+    ##   plot(...); print(...);
+    drawnow ();
+
+    for i = 1:nargin
+      arg = varargin{i};
+      if (ischar (arg))
+        if (strcmp (arg, "-color"))
+	  use_color = 1;
+        elseif (strcmp (arg, "-mono"))
+	  use_color = -1;
+        elseif (strcmp (arg, "-solid"))
+          force_solid = 1;
+        elseif (strcmp (arg, "-dashed"))
+          force_solid = -1;
+        elseif (strcmp (arg, "-portrait"))
+	  orientation = "portrait";
+        elseif (strcmp (arg, "-landscape"))
+	  orientation = "landscape";
+        elseif (strcmp (arg, "-tight"))
+	  tight_flag = true;
+        elseif (strcmp (arg, "-textspecial"))
+	  special_flag = "textspecial";
+        elseif (strncmp (arg, "-debug", 6))
+	  debug = true;
+	  if (length (arg) > 7)
+	    debug_file = arg(8:end);
+	  endif
+        elseif (length (arg) > 2 && arg(1:2) == "-d")
+	  devopt = tolower(arg(3:end));
+        elseif (length (arg) > 2 && arg(1:2) == "-P")
+	  printer = arg;
+	elseif ((length (arg) > 2) && arg(1:2) == "-G")
+	  ghostscript_binary = arg(3:end);
+	  if (exist (ghostscript_binary, "file") != 2)
+	    ghostscript_binary = file_in_path (EXEC_PATH, ghostscript_binary);
+	  endif
+	  if (isempty (ghostscript_binary))
+	    error ("print.m: Ghostscript binary ""%s"" could not be located", arg(3:end))
+	  endif
+        elseif (length (arg) > 2 && arg(1:2) == "-F")
+	  idx = rindex (arg, ":");
+	  if (idx)
+	    font = arg(3:idx-1);
+	    fontsize = arg(idx+1:length(arg));
+	  else
+	    font = arg(3:length(arg));
+	  endif
+        elseif (length (arg) > 2 && arg(1:2) == "-S")
+	  canvas_size = arg(3:length(arg));
+        elseif (length (arg) > 2 && arg(1:2) == "-r")
+	  resolution = arg(3:length(arg));
+        elseif (length (arg) >= 1 && arg(1) == "-")
+	  error ("print: unknown option `%s'", arg);
+	elseif (length (arg) > 0)
+	  name = arg;
+        endif
+      elseif (isfigure (arg))
+        figure (arg);
+      else
+        error ("print: expecting inputs to be character string options or a figure handle");
+      endif
+    endfor
+
+    have_ghostscript = (exist (ghostscript_binary, "file") == 2);
+
+    doprint = isempty (name);
+    if (doprint)
+      if (isempty (devopt))
+	if (use_color < 0)
+	  devopt = "ps";
+          printname = cstrcat (tmpnam, ".ps");
+	else
+	  devopt = "psc";
+          printname = cstrcat (tmpnam, ".psc");
+	endif
+      else
+        printname = cstrcat (tmpnam, ".", devopt);
+      endif
+      name = printname;
+    endif
+
+    if (isempty (devopt))
+      dot = rindex (name, ".");
+      if (dot == 0)
+        error ("print: no format specified");
+      else
+        dev = tolower (name(dot+1:end));
+      endif
+    else
+      dev = devopt;
+    endif
+
+    if (strcmp (dev, "tex"))
+      dev = "epslatex";
+      ## gnuplot 4.0 wants ".eps" in the output name    
+      if (! __gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix"))
+        name = cstrcat (name(1:dot), "eps");
+      endif
+    elseif (strcmp (dev, "ill"))
+      dev = "aifm";
+    elseif (strcmp (dev, "cdr"))
+      dev = "corel";
+    elseif (strcmp (dev, "meta"))
+      dev = "emf";
+    elseif (strcmp (dev, "jpg"))
+      dev = "jpeg";
+    endif
+
+    ## Check if the specified device is one that is supported by gnuplot.
+    ## If not, assume it is a device/format supported by Ghostscript.
+    dev_list = {"aifm", "corel", "fig", "png", "jpeg", ...
+		"gif", "pbm", "dxf", "mf", "svg", "hpgl", ...
+		"ps", "ps2", "psc", "psc2", "eps", "eps2", ...
+		"epsc", "epsc2", "emf", "pdf", "pslatex", ...
+		"epslatex", "epslatexstandalone", "pstex"};
+    if (! any (strcmp (dev, dev_list)) && have_ghostscript)
+      ghostscript_output = name;
+      ghostscript_device = dev;
+      if (doprint)
+	## If printing, use color postscript.
+        dev = "psc";
+        name = cstrcat (tmpnam, ".ps");
+      else
+	## If saving to a file, use color encapsulated postscript.
+        dev = "epsc";
+        name = cstrcat (tmpnam, ".eps");
+      endif
+    else
+      ghostscript_output = "";
+    endif
+
+    termn = dev;
+
+    ## SVG isn't actually a bitmap, but gnuplot treats its size option as it
+    ## does the bitmap terminals.
+    bitmap_devices = {"emf", "gif", "jpeg", "pbm", "png", "svg"};
+
+    if (any (strcmp (dev, {"ps", "ps2", "psc", "psc2", "epsc", "epsc2", ...
+                           "eps", "eps2", "pstex", "pslatex", "epslatex", ...
+                           "epslatexstandalone"})))
+
+      ## Various postscript options
+      if (any (strcmp (dev, {"pstex", "pslatex", "epslatex"})))
+        options = "";
+      elseif (strcmp (dev, "epslatexstandalone"))
+        if (__gnuplot_has_feature__ ("epslatexstandalone_terminal"))
+	  termn = "epslatex";
+	  options = "standalone ";
+        else
+	  error ("print: epslatexstandalone needs gnuplot 4.2 or higher");
+        endif
+      else
+        if (dev(1) == "e")
+	  options = "eps ";
+        else
+	  options = "";
+        endif
+        termn = "postscript";
+      endif
+
+      if (any (dev == "c") || use_color > 0
+          || (! isempty (strfind (dev, "tex")) && use_color == 0))
+	use_color = 1;
+      else
+	use_color = -1;
+      endif
+      
+      if (use_color > 0)
+        if (force_solid < 0)
+	  options = cstrcat (options, "color dashed ");
+        else
+	  options = cstrcat (options, "color solid ");
+        endif
+      else
+        if (force_solid > 0)
+	  options = cstrcat (options, "mono solid ");
+        else
+	  options = cstrcat (options, "mono dashed ");
+        endif
+      endif
+
+      if (! isempty (font))
+        options = cstrcat (options, "\"", font, "\" ");
+      endif
+      if (! isempty (fontsize))
+        options = cstrcat (options, " ", fontsize);
+      endif
+      
+    elseif (strcmp (dev, "aifm") || strcmp (dev, "corel"))
+      ## Adobe Illustrator, CorelDraw
+      if (use_color >= 0)
+        options = " color";
+      else
+        options = " mono";
+      endif
+      if (! isempty (font))
+        options = cstrcat (options, " \"", font, "\"");
+      endif
+      if (! isempty (fontsize))
+        options = cstrcat (options, " ", fontsize);
+      endif
+
+    elseif (strcmp (dev, "fig"))
+      ## XFig
+      options = orientation;
+      if (use_color >= 0)
+        options = " color";
+      else
+        options = " mono";
+      endif
+      options = cstrcat (options, " ", special_flag);
+      if (! isempty (fontsize))
+        options = cstrcat (options, " fontsize ", fontsize);
+      endif
+
+    elseif (strcmp (dev, "emf"))
+      ## Enhanced Metafile format
+      options = " ";
+      if (use_color >= 0)
+        options = " color";
+      else
+        options = " mono";
+      endif
+      if (force_solid >= 0)
+        options = cstrcat (options, " solid");
+      endif
+      if (! isempty (font))
+        options = cstrcat (options, " \"", font, "\"");
+      endif
+      if (! isempty (fontsize))
+        options = cstrcat (options, " ", fontsize);
+      endif
+
+    elseif (any (strcmp (dev, bitmap_devices)))
+
+      if (isempty (canvas_size) && isempty (resolution) 
+	  && any (strcmp (dev, {"pbm", "gif", "jpeg", "png"})))
+	options = "";
+      elseif (strcmp (dev, "svg"))
+	## Referring to size, either "dynamic" or "fixed"
+	options = "fixed";
+      else
+	options = "";
+      end
+      if (! isempty (canvas_size))
+        options = cstrcat (options, " size ", canvas_size);
+      endif
+
+    elseif (any (strcmp (dev, {"dxf", "mf", "hpgl"})))
+      ## AutoCad DXF, METAFONT, HPGL
+      options = "";
+
+    elseif (strcmp (dev, "pdf"))
+      ## Portable Document format
+      options = " ";
+      if (use_color >= 0)
+        options = "color";
+      else
+        options = "mono";
+      endif
+      if (force_solid >= 0)
+        options = cstrcat (options, " solid");
+      elseif (force_solid < 0)
+        options = cstrcat (options, " dashed");
+      endif
+      if (! isempty (font))
+        options = cstrcat (options, "\"", font, "\" ");
+      endif
+      if (! isempty (fontsize))
+        options = cstrcat (options, " ", fontsize);
+      endif
+
+    endif
+ 
+    if (__gnuplot_has_feature__ ("variable_GPVAL_TERMINALS"))
+      available_terminals = __gnuplot_get_var__ (gcf, "GPVAL_TERMINALS");
+      available_terminals = regexp (available_terminals, "\\b\\w+\\b", "match");
+      ## Favor the cairo terminals.
+      if (strcmp (termn, "pdf") 
+          && any (strcmp (available_terminals, "pdfcairo")))
+        termn = "pdfcairo";
+	gnuplot_supports_term = true;
+      elseif (strcmp (termn, "png")
+              && any (strcmp (available_terminals, "pngcairo")))
+        termn = "pngcairo";
+	gnuplot_supports_term = true;
+      else
+        gnuplot_supports_term = any (strcmp (available_terminals, termn));
+      endif
+    elseif (strcmp (termn, "pdf"))
+      ## Some Linux variants do not include a "pdf" capable gnuplot.
+      ## To be safe, use Ghostscript.
+      if (have_ghostscript)
+        gnuplot_supports_term = false;
+        ghostscript_device = "pdfwrite";
+      else
+        gnuplot_supports_term = true;
+      endif
+    else
+      gnuplot_supports_term = true;
+    endif
+
+    if (! gnuplot_supports_term)
+      if (strcmp (termn, "pdf"))
+	## If there the installed gnuplot does not support pdf, use Ghostscript.
+        ghostscript_device = "pdfwrite";
+	if (strfind (name, ".pdf") == numel (name) - 3)
+          ghostscript_output = name;
+	else
+	  ghostscript_output = strcat (name, ".pdf");
+	endif
+        name = cstrcat (tmpnam, ".ps");
+        termn = "postscript";
+	## All "options" for pdf work for postscript as well.
+      else
+        error ("print: the device, \"%s\", is not available.", dev)
+      endif
+    endif
+
+    is_eps_file = strncmp (dev, "eps", 3);
+    p.units = get (gcf, "units");
+    p.paperunits = get (gcf, "paperunits");
+    p.papersize = get (gcf, "papersize");
+    p.paperposition = get (gcf, "paperposition");
+    p.paperpositionmode = get (gcf, "paperpositionmode");
+    p.paperorientation = get (gcf, "paperorientation");
+    if (p.papersize(1) > p.papersize(2))
+      paperorientation = "landscape";
+    else
+      paperorientation = "portrait";
+    endif
+    if (! strcmp (paperorientation, get (gcf, "paperorientation"))
+        && warn_on_inconsistent_orientation)
+       msg = {"print.m - inconsistent papersize and paperorientation properties.\n",
+	       sprintf("         papersize = %.2f, %.2f\n", p.papersize),
+	       sprintf("         paperorientation = \"%s\"\n", p.paperorientation),
+	               "         the paperorientation property has been ignored"};
+      warning ("%s",msg{:})
+      warn_on_inconsistent_orientation = false;
+    endif
+
+    if (strcmp (termn, "postscript") && ! strncmp (dev, "eps", 3))
+      if (isempty (orientation))
+	orientation = paperorientation;
+      endif
+      ## This is done here to accommodate ghostscript conversion.
+      options = cstrcat (orientation, " ", options);
+    end
+
+    new_terminal = cstrcat (termn, " ", options);
+
+    mono = (use_color < 0);
+
+    terminals_for_prn = {"postscript", "pdf", "pdfcairo"};
+    output_for_printer = any (strncmp (termn, terminals_for_prn, numel(termn)));
+
+    if (isempty (resolution))
+      if (any (strcmp (dev, {"emf", "svg"})) || output_for_printer)
+        resolution = get (0, "screenpixelsperinch");
+      else
+        resolution = 150;
+      endif
+    else
+      resolution = str2num (resolution);
+      if (resolution == 0)
+        resolution = get (0, "screenpixelsperinch");
+      endif
+    endif
+    figure_properties = get (gcf);
+    if (! isfield (figure_properties, "__pixels_per_inch__"))
+      addproperty ("__pixels_per_inch__", gcf, "double", resolution);
+    endif
+    set (gcf, "__pixels_per_inch__", resolution)
+
+    unwind_protect
+      set (gcf, "paperunits", "inches");
+      set (gcf, "units", "pixels");
+      restore_properties = true;
+      if ((! output_for_printer || is_eps_file) && ! doprint)
+	## If not PDF or PostScript, and the result is not being sent to a printer,
+        ## render an image the size of the paperposition box.
+	## Trigger the listener to convert all paper props to inches.
+	if (! isempty (canvas_size))
+          size_in_pixels = sscanf (canvas_size ,"%d, %d");
+          size_in_pixels = reshape (size_in_pixels, [1, numel(size_in_pixels)]);
+          papersize_in_inches = size_in_pixels ./ resolution;
+          paperposition_in_inches = [0, 0, papersize_in_inches];
+	else
+          paperposition_in_inches = get (gcf, "paperposition");
+          paperposition_in_inches(1:2) = 0;
+          papersize_in_inches = paperposition_in_inches(3:4);
+        endif
+        set (gcf, "papersize", papersize_in_inches);
+        set (gcf, "paperposition", paperposition_in_inches);
+        set (gcf, "paperpositionmode", "manual");
+      else
+	if (strcmp (p.paperpositionmode, "auto"))
+	  size_in_pixels = get (gcf, "position")(3:4);
+	  paperposition_in_inches(3:4) = size_in_pixels ./ resolution;
+	  paperposition_in_inches(1:2) = (p.papersize - paperposition_in_inches(3:4))/2;
+	else
+	  paperposition_in_inches = p.paperposition;
+	endif
+	if (! isempty (orientation) && ! strcmp (orientation, paperorientation))
+	  ## When -landscape/portrait changes the orientation, flip both the
+	  ## papersize and paperposition.
+	  restore_properties = true;
+	  set (gcf, "papersize", p.papersize([2, 1]));
+	  set (gcf, "paperposition", paperposition_in_inches([2, 1, 4, 3]));
+	else
+	  set (gcf, "paperposition", paperposition_in_inches);
+	endif
+      endif
+      if (use_color < 0)
+	[objs_with_color, color_of_objs] = convert_color2mono (gcf);
+      endif
+      if (debug)
+        drawnow (new_terminal, name, mono, debug_file);
+      else
+        drawnow (new_terminal, name, mono);
+      endif
+    unwind_protect_cleanup
+      ## FIXME - it would be nice to delete "__pixels_per_inch__" property here.
+      if (restore_properties)
+        props = fieldnames (p);
+        for n = 1:numel(props)
+          set (gcf, props{n}, p.(props{n}))
+        endfor
+      endif
+      if (use_color < 0)
+	convert_mono_to_or_from_color (objs_with_color, color_of_objs, false);
+      endif
+    end_unwind_protect
+
+    if (! isempty (ghostscript_output))
+      if (is_eps_file && tight_flag)
+	## If gnuplot's output is an eps-file then crop at the bounding box.
+        fix_eps_bbox (name, ghostscript_binary);
+      endif
+      ghostscript_options = "-q -dBATCH -dSAFER -dNOPAUSE -dTextAlphaBits=4";
+      if (is_eps_file)
+	ghostscript_options = sprintf ("%s -dEPSCrop", ghostscript_options);
+      endif
+      if (isempty (strfind (lower (ghostscript_device), "write")))
+	## If output is a bitmap then include the resolution
+	ghostscript_options = sprintf ("%s -r%d", ghostscript_options, resolution);
+      endif
+      ghostscript_options = sprintf ("%s -sDEVICE=%s", ghostscript_options,
+                                     ghostscript_device);
+      command = sprintf ("\"%s\" %s -sOutputFile=\"%s\" \"%s\" 2>&1", ghostscript_binary,
+                          ghostscript_options, ghostscript_output, name);
+      [errcode, output] = system (command);
+      unlink (name);
+      if (errcode)
+        error ("print: Conversion failed, %s -> %s.\nError was:\n%s\n",
+               name, ghostscript_output, output);
+      endif
+    elseif (is_eps_file && tight_flag && ! doprint)
+      ## If the saved output file is an eps file, use ghostscript to set a tight bbox.
+      ## This may result in a smaller or larger bbox geometry.
+      if (have_ghostscript)
+        fix_eps_bbox (name, ghostscript_binary);
+      endif
+    endif
+
+    if (doprint)
+      if (isunix ())
+	prn_opt = "-l";
+      elseif (ispc ())
+	prn_opt = "-o l";
+      else
+	## FIXME - besides Unix and Windows, what other OS's might be considered.
+	prn_opt = "";
+      endif
+      if (isempty (printer))
+        prn_cmd = sprintf ("lpr %s '%s' 2>&1", prn_opt, printname);
+      else
+        prn_cmd = sprintf ("lpr %s -P %s '%s' 2>&1", prn_opt, printer, printname);
+      endif
+      [status, output] = system (prn_cmd);
+      if (status != 0)
+	disp (output)
+	warning ("print.m: printing failed.")
+      endif
+      [status, output] = unlink (printname);
+      if (status != 0)
+	disp (output)
+	warning ("print.m: failed to delete temporay file, '%s'.", printname)
+      endif
+    endif
+
+  unwind_protect_cleanup
+    if (isfigure (old_fig))
+      figure (old_fig)
+    endif
+  end_unwind_protect
+
+endfunction
+
+function bb = fix_eps_bbox (eps_file_name, ghostscript_binary)
+
+  persistent warn_on_no_ghostscript = true
+
+  box_string = "%%BoundingBox:";
+
+  ghostscript_options = "-q -dBATCH -dSAFER -dNOPAUSE -dTextAlphaBits=4 -sDEVICE=bbox";
+  cmd = sprintf ("\"%s\" %s \"%s\" 2>&1", ghostscript_binary,
+                 ghostscript_options, eps_file_name);
+  [status, output] = system (cmd);
+
+  if (status == 0)
+
+    pattern = strcat (box_string, "[^%]*");
+    pattern = pattern(1:find(double(pattern)>32, 1, "last"));
+    bbox_line = regexp (output, pattern, "match");
+    if (iscell (bbox_line))
+      bbox_line = bbox_line{1};
+    endif
+    ## Remore the EOL characters.
+    bbox_line(double(bbox_line)<32) = "";
+
+    fid = fopen (eps_file_name, "r+");
+    unwind_protect
+      bbox_replaced = false;
+      while (! bbox_replaced)
+        current_line = fgetl (fid);
+        if (strncmpi (current_line, box_string, numel(box_string)))
+          line_length = numel (current_line);
+          num_spaces = line_length - numel (bbox_line);
+          if (numel (current_line) < numel (bbox_line))
+	    ## If there new line is longer, continue with the current line.
+            new_line = current_line;
+          else
+	    new_line = bbox_line;
+	    new_line(end+1:numel(current_line)) = " ";
+          endif
+          ## Back up to the beginning of the line (include EOL characters).
+          if (ispc ())
+            fseek (fid, -line_length-2, "cof");
+          else
+            fseek (fid, -line_length-1, "cof");
+          endif
+          count = fprintf (fid, "%s", new_line);
+          bbox_replaced = true;
+        elseif (! ischar (current_line))
+          bbox_replaced = true;
+          warning ("print.m: no bounding box found in '%s'.", eps_file_name)
+        endif
+      endwhile
+    unwind_protect_cleanup
+      fclose (fid);
+    end_unwind_protect
+  elseif (warn_on_no_ghostscript)
+    warn_on_no_ghostscript = false;
+    warning ("print.m: Ghostscript failed to determine the bounding box.\nError was:\n%s\n", output)
+  endif
+
+endfunction
+
+function [h, c] = convert_color2mono (hfig)
+  unwind_protect
+    showhiddenhandles = get (0, "showhiddenhandles");
+    set (0, "showhiddenhandles", "on");
+    h.color = findobj (hfig, "-property", "color");
+    h.facecolor = findobj (hfig, "-property", "facecolor");
+    h.edgecolor = findobj (hfig, "-property", "edgecolor");
+    h.backgroundcolor = findobj (hfig, "-property", "backgroundcolor");
+    h.colormap = findobj (hfig, "-property", "colormap");
+  unwind_protect_cleanup
+    set (0, "showhiddenhandles", showhiddenhandles);
+  end_unwind_protect
+  f = fieldnames (h);
+  for nf = 1:numel(f)
+    if (! isempty (h.(f{nf})))
+      v = get (h.(f{nf}), f{nf});
+      if (! iscell (v))
+        v = {v};
+      endif
+      c.(f{nf}) = v;
+    endif
+  endfor
+  convert_mono_to_or_from_color (h, c, true)
+endfunction
+
+function convert_mono_to_or_from_color (h, c, mono)
+  f = fieldnames (h);
+  for nf = 1:numel(f)
+    for nh = 1:numel (h.(f{nf}))
+      color = c.(f{nf}){nh};
+      ## Ignore color == {"none", "flat", ...}
+      if (isfloat (color))
+	if (mono)
+	  ## Same method as used by rgb2gray in the image pkg.
+	  color = rgb2ntsc (color)(:,1) * ones (1, 3);
+	endif
+        set (h.(f{nf})(nh), f{nf}, color);
+      endif
+    endfor
+  endfor
+endfunction
+
diff --git a/scripts/plot/quiver.m b/scripts/plot/quiver.m
new file mode 100644
index 0000000..d139920
--- /dev/null
+++ b/scripts/plot/quiver.m
@@ -0,0 +1,94 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} quiver (@var{u}, @var{v})
+## @deftypefnx {Function File} {} quiver (@var{x}, @var{y}, @var{u}, @var{v})
+## @deftypefnx {Function File} {} quiver (@dots{}, @var{s})
+## @deftypefnx {Function File} {} quiver (@dots{}, @var{style})
+## @deftypefnx {Function File} {} quiver (@dots{}, 'filled')
+## @deftypefnx {Function File} {} quiver (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} quiver (@dots{})
+##
+## Plot the @code{(@var{u}, @var{v})} components of a vector field in 
+## an @code{(@var{x}, @var{y})} meshgrid.  If the grid is uniform, you can 
+## specify @var{x} and @var{y} as vectors.
+##
+## If @var{x} and @var{y} are undefined they are assumed to be
+## @code{(1:@var{m}, 1:@var{n})} where @code{[@var{m}, @var{n}] = 
+## size(@var{u})}.
+##
+## The variable @var{s} is a scalar defining a scaling factor to use for
+##  the arrows of the field relative to the mesh spacing.  A value of 0 
+## disables all scaling.  The default value is 1.
+##
+## The style to use for the plot can be defined with a line style @var{style}
+## in a similar manner to the line styles used with the @code{plot} command.
+## If a marker is specified then markers at the grid points of the vectors are
+## printed rather than arrows.  If the argument 'filled' is given then the
+## markers as filled.
+##
+## The optional return value @var{h} provides a quiver group that
+## regroups the components of the quiver plot (body, arrow and marker),
+## and allows them to be changed together
+##
+## @example
+## @group
+## [x, y] = meshgrid (1:2:20);
+## h = quiver (x, y, sin (2*pi*x/10), sin (2*pi*y/10));
+## set (h, "maxheadsize", 0.33);
+## @end group
+## @end example
+##
+## @seealso{plot}
+## @end deftypefn
+
+function retval = quiver (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("quiver", varargin{:});
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      tmp = __quiver__ (h, 0, varargin{:});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! [x,y] = meshgrid(1:2:20);
+%! h = quiver(x,y,sin(2*pi*x/10),sin(2*pi*y/10));
+%! set (h, "maxheadsize", 0.33);
+
+%!demo
+%! axis("equal");
+%! x=linspace(0,3,80); y=sin(2*pi*x); theta=2*pi*x+pi/2;
+%! quiver(x,y,sin(theta)/10,cos(theta)/10);
+%! hold on; plot(x,y,"r"); hold off;
diff --git a/scripts/plot/quiver3.m b/scripts/plot/quiver3.m
new file mode 100644
index 0000000..e26f08c
--- /dev/null
+++ b/scripts/plot/quiver3.m
@@ -0,0 +1,110 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} quiver3 (@var{u}, @var{v}, @var{w})
+## @deftypefnx {Function File} {} quiver3 (@var{x}, @var{y}, @var{z}, @var{u}, @var{v}, @var{w})
+## @deftypefnx {Function File} {} quiver3 (@dots{}, @var{s})
+## @deftypefnx {Function File} {} quiver3 (@dots{}, @var{style})
+## @deftypefnx {Function File} {} quiver3 (@dots{}, 'filled')
+## @deftypefnx {Function File} {} quiver3 (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} quiver3 (@dots{})
+##
+## Plot the @code{(@var{u}, @var{v}, @var{w})} components of a vector field in 
+## an @code{(@var{x}, @var{y}), @var{z}} meshgrid.  If the grid is uniform, you 
+## can specify @var{x}, @var{y} @var{z} as vectors.
+##
+## If @var{x}, @var{y} and @var{z} are undefined they are assumed to be
+## @code{(1:@var{m}, 1:@var{n}, 1:@var{p})} where @code{[@var{m}, @var{n}] = 
+## size(@var{u})} and @code{@var{p} = max (size (@var{w}))}.
+##
+## The variable @var{s} is a scalar defining a scaling factor to use for
+##  the arrows of the field relative to the mesh spacing.  A value of 0 
+## disables all scaling.  The default value is 1.
+##
+## The style to use for the plot can be defined with a line style @var{style}
+## in a similar manner to the line styles used with the @code{plot} command.
+## If a marker is specified then markers at the grid points of the vectors are
+## printed rather than arrows.  If the argument 'filled' is given then the
+## markers as filled.
+##
+## The optional return value @var{h} provides a quiver group that
+## regroups the components of the quiver plot (body, arrow and marker),
+## and allows them to be changed together
+##
+## @example
+## @group
+## [x, y, z] = peaks (25);
+## surf (x, y, z);
+## hold on;
+## [u, v, w] = surfnorm (x, y, z / 10);
+## h = quiver3 (x, y, z, u, v, w);
+## set (h, "maxheadsize", 0.33);
+## @end group
+## @end example
+##
+## @seealso{plot}
+## @end deftypefn
+
+function retval = quiver3 (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("quiver3", varargin{:});
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      tmp = __quiver__ (h, 1, varargin{:});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! colormap (jet (64))
+%! [x,y]=meshgrid (-1:0.1:1); 
+%! z=sin(2*pi*sqrt(x.^2+y.^2)); 
+%! theta=2*pi*sqrt(x.^2+y.^2)+pi/2;
+%! quiver3(x,y,z,sin(theta),cos(theta),ones(size(z)));
+%! hold on; 
+%! mesh(x,y,z); 
+%! hold off;
+
+%!demo
+%! clf
+%! [x, y, z] = peaks (25);
+%! surf (x, y, z);
+%! hold on;
+%! [u, v, w] = surfnorm (x, y, z / 10);
+%! h = quiver3 (x, y, z, u, v, w);
+%! set (h, "maxheadsize", 0.33);
+%! hold off;
+
+%!demo
+%! shading interp
+
diff --git a/scripts/plot/refresh.m b/scripts/plot/refresh.m
new file mode 100644
index 0000000..4207d06
--- /dev/null
+++ b/scripts/plot/refresh.m
@@ -0,0 +1,42 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} refresh ()
+## @deftypefnx {Function File} {} refresh (@var{h})
+## Refresh a figure, forcing it to be redrawn.  Called without an
+## argument the current figure is redrawn, otherwise the figure pointed
+## to by @var{h} is redrawn.
+## @seealso{drawnow}
+## @end deftypefn
+
+function refresh (h)
+
+  if (nargin == 1)
+    if (!ishandle (h) || !strcmp (get (h, "type"), "figure"))
+      error ("refresh: expecting argument to be a valid figure handle");
+    endif
+  elseif (nargin > 1)
+    print_usage ();
+  else
+    h = gcf ();
+  endif
+
+  set(h,"__modified__", "on")
+  drawnow ();
+endfunction
diff --git a/scripts/plot/refreshdata.m b/scripts/plot/refreshdata.m
new file mode 100644
index 0000000..61df668
--- /dev/null
+++ b/scripts/plot/refreshdata.m
@@ -0,0 +1,112 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} refreshdata ()
+## @deftypefnx {Function File} {} refreshdata (@var{h})
+## @deftypefnx {Function File} {} refreshdata (@var{h}, @var{workspace})
+## Evaluate any @samp{datasource} properties of the current figure and update
+## the plot if the corresponding data has changed.  If called with one or more
+## arguments @var{h} is a scalar or array of figure handles to refresh.  The
+## optional second argument @var{workspace} can take the following values.
+##
+## @table @code
+## @item "base"
+## Evaluate the datasource properties in the base workspace.  (default).
+## @item "caller"
+## Evaluate the datasource properties in the workspace of the function
+## that called @code{refreshdata}.
+## @end table
+##
+## An example of the use of @code{refreshdata} is:
+##
+## @example
+## @group
+## x = 0:0.1:10;
+## y = sin (x);
+## plot (x, y, "ydatasource", "y");
+## for i = 1 : 100
+##   pause(0.1)
+##   y = sin (x + 0.1 * i);
+##   refreshdata();
+## endfor
+## @end group
+## @end example
+## @end deftypefn
+
+function refreshdata (h, ws)
+
+  if (nargin == 0)
+    h = gcf ();
+    ws = "base";
+  else
+    if (iscell (h))
+      h = [h{:}];
+    endif
+    if (!all (ishandle (h)) || !all (strcmp (get (h, "type"), "figure")))
+      error ("refreshdata: expecting a list of figure handles");
+    endif
+    if (nargin < 2)
+      ws = "base";
+    else
+      if (!ischar (ws) || !(strcmpi (ws, "base") || strcmpi (ws, "caller")))
+	error ("refreshdata: expecting workspace to be \"base\" or ""caller\"");
+      else
+	ws = tolower (ws);
+      endif
+    endif
+  endif
+
+  h = findall (h);
+  objs = [];
+  props = {};
+
+  for i = 1 : numel (h)
+    obj = get (h (i));
+    fldnames = fieldnames (obj);
+    m = regexpi (fieldnames(obj), "^.+datasource$", "match");
+    idx = cellfun (@(x) !isempty(x), m);
+    if (any (idx))
+      props = [props; {cell2mat(m(idx))}];
+      objs  = [objs ; h(i)];
+    endif
+  endfor
+
+  for i = 1 : length (objs)
+    for j = 1 : length (props {i})
+      expr = get (objs(i), props{i}{j});
+      if (!isempty (expr))
+	val = evalin (ws, expr);
+	prop =  props{i}{j}(1:end-6);
+        if (! isequal (get (objs(i), prop), val))
+	  set (objs(i), props{i}{j}(1:end-6), val);
+        endif
+      endif
+    endfor
+  endfor
+endfunction
+
+%!demo
+%! x = 0:0.1:10;
+%! y = sin (x);
+%! plot (x, y, "ydatasource", "y");
+%! for i = 1 : 100
+%!   pause(0.1)
+%!   y = sin (x + 0.1 * i);
+%!   refreshdata(gcf(), "caller");
+%! endfor
diff --git a/scripts/plot/replot.m b/scripts/plot/replot.m
new file mode 100644
index 0000000..d6d66f3
--- /dev/null
+++ b/scripts/plot/replot.m
@@ -0,0 +1,34 @@
+## Copyright (C) 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} replot ()
+## Refresh the plot window.
+## @end deftypefn
+
+## Author: jwe
+
+function replot ()
+  
+  if (nargin == 0)
+    drawnow ();
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/ribbon.m b/scripts/plot/ribbon.m
new file mode 100644
index 0000000..1ea2d25
--- /dev/null
+++ b/scripts/plot/ribbon.m
@@ -0,0 +1,91 @@
+## Copyright (C) 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} ribbon (@var{x}, @var{y}, @var{width})
+## @deftypefnx {Function File} {} ribbon (@var{y})
+## @deftypefnx {Function File} {@var{h} =} ribbon (@dots{})
+## Plot a ribbon plot for the columns of @var{y} vs.  @var{x}.  The
+## optional parameter @var{width} specifies the width of a single ribbon
+## (default is 0.75).  If @var{x} is omitted, a vector containing the
+## row numbers is assumed (1:rows(Y)).  If requested, return a vector
+## @var{h} of the handles to the surface objects.
+## @seealso{gca, colorbar}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function h = ribbon (x, y, width)
+
+  newplot ();
+
+  if (nargin == 1)
+    y = x;
+    if (isvector (y))
+      y = y(:);
+    endif
+    [nr, nc] = size (y);
+    x = repmat ((1:nr)', 1, nc);
+    width = 0.75;
+  elseif (nargin == 2)
+    width = 0.75;
+  elseif (nargin != 3)
+    print_usage ();
+  endif
+
+  if (isvector (x) && isvector (y))
+    if (length (x) != length (y))
+      error ("ribbon: in case of vectors, X and Y must have same length");
+    else
+      [x, y] = meshgrid (x, y);
+    endif
+  else
+    if (! size_equal(x, y))
+      error ("ribbon: in case of matrices, X and Y must have same size");
+    endif
+  endif
+
+  [nr, nc] = size (y);
+  tmp = zeros (1, nc);
+
+  for c = nc:-1:1
+    zz = [y(:,c), y(:,c)];
+    yy = x(:,c);
+    xx = [c - width / 2, c + width / 2];
+    [xx, yy] = meshgrid (xx, yy);
+    cc = ones (size (zz)) * c;
+    tmp(c) = surface (xx, yy, zz, cc);
+  endfor
+
+  ax = get (tmp(c), "parent");
+
+  if (! ishold ())
+    set (ax, "view", [-37.5, 30], "box", "off", "xgrid", "on",
+	 "ygrid", "on", "zgrid", "on");
+  endif
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! [x, y, z] = sombrero ();
+%! [x, y] = meshgrid (x, y);
+%! ribbon (y, z);
diff --git a/scripts/plot/rose.m b/scripts/plot/rose.m
new file mode 100644
index 0000000..8c9ac7a
--- /dev/null
+++ b/scripts/plot/rose.m
@@ -0,0 +1,109 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rose (@var{th}, @var{r})
+## @deftypefnx {Function File} {} rose (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} rose (@dots{})
+## @deftypefnx {Function File} {[@var{r}, @var{th}] =} rose (@dots{})
+##
+## Plot an angular histogram.  With one vector argument @var{th}, plots the
+## histogram with 20 angular bins.  If @var{th} is a matrix, then each column
+## of @var{th} produces a separate histogram.
+##
+## If @var{r} is given and is a scalar, then the histogram is produced with
+## @var{r} bins.  If @var{r} is a vector, then the center of each bin are 
+## defined by the values of @var{r}.
+##
+## The optional return value @var{h} provides a list of handles to the 
+## the parts of the vector field (body, arrow and marker).
+##
+## If two output arguments are requested, then rather than plotting the 
+## histogram, the polar vectors necessary to plot the histogram are 
+## returned.
+##
+## @example
+## @group
+## [r, t] = rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)]);
+## polar (r, t);
+## @end group
+## @end example
+##
+##
+## @seealso{plot, compass, polar, hist}
+## @end deftypefn
+
+function [thout, rout] = rose (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ((nargout > 1), "rose", 
+						varargin{:});
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  ## Force theta to [0,2*pi] range
+  th = varargin {1};
+  th = atan2  (sin (th), cos (th)) + pi;
+
+  if (nargin > 1)
+    x = varargin {2};
+    if (isscalar (x))
+      x = [0.5/x : 1/x : 1] * 2 * pi; 
+    else
+      ## Force theta to [0,2*pi] range
+      x = atan2  (sin (x), cos (x)) + pi;
+    endif
+  else
+    x = [1/40 : 1/20 : 1] * 2 * pi;
+  endif
+
+  [nn, xx] = hist (th, x);
+  xx = xx(:).';
+  if (isvector (nn))
+    nn = nn (:);
+  endif
+  x1 = xx(1:end-1) + diff (xx, 1) / 2;
+  x1 = [x1 ; x1; x1; x1](:);
+  th = [0; 0; x1; 2*pi ; 2*pi];
+  r = zeros (4 * size (nn, 1), size (nn, 2));
+  r(2:4:end, :) = nn;
+  r(3:4:end, :) = nn;
+
+  if (nargout < 2)
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      hlist = polar (h, th, r);
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+
+    if (nargout > 0)
+      thout = hlist;
+    endif
+  else
+    thout = th;
+    rout = r;
+  endif
+
+endfunction
+
+%!demo
+%! rose ([2*randn(1e5,1), pi + 2 * randn(1e5,1)])
diff --git a/scripts/plot/scatter.m b/scripts/plot/scatter.m
new file mode 100644
index 0000000..a405045
--- /dev/null
+++ b/scripts/plot/scatter.m
@@ -0,0 +1,83 @@
+## Copyright (C) 2007, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} scatter (@var{x}, @var{y}, @var{s}, @var{c})
+## @deftypefnx {Function File} {} scatter (@dots{}, 'filled')
+## @deftypefnx {Function File} {} scatter (@dots{}, @var{style})
+## @deftypefnx {Function File} {} scatter (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} scatter (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} scatter (@dots{})
+##
+## Plot a scatter plot of the data.  A marker is plotted at each point 
+## defined by the points in the vectors @var{x} and @var{y}.  The size of
+## the markers used is determined by the @var{s}, which can be a scalar, 
+## a vector of the same length of @var{x} and @var{y}.  If @var{s} is not 
+## given or is an empty matrix, then the default value of 8 points is used.
+##
+## The color of the markers is determined by @var{c}, which can be a string
+## defining a fixed color, a 3 element vector giving the red, green and blue 
+## components of the color, a vector of the same length as @var{x} that gives
+## a scaled index into the current colormap, or a @var{n}-by-3 matrix defining
+## the colors of each of the markers individually.
+##
+## The marker to use can be changed with the @var{style} argument, that is a 
+## string defining a marker in the same manner as the @code{plot} command. 
+## If the argument 'filled' is given then the markers as filled.  All 
+## additional arguments are passed to the underlying patch command.
+##
+## The optional return value @var{h} provides a handle to the patch object
+##
+## @example
+## @group
+## x = randn (100, 1);
+## y = randn (100, 1);
+## scatter (x, y, [], sqrt(x.^2 + y.^2));
+## @end group
+## @end example
+##
+## @seealso{plot, patch, scatter3}
+## @end deftypefn
+
+function retval = scatter (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("scatter", varargin{:});
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      tmp = __scatter__ (h, 2, "scatter", varargin{:});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! x = randn (100, 1);
+%! y = randn (100, 1);
+%! scatter (x, y, [], sqrt(x.^2 + y.^2));
diff --git a/scripts/plot/scatter3.m b/scripts/plot/scatter3.m
new file mode 100644
index 0000000..4225b2f
--- /dev/null
+++ b/scripts/plot/scatter3.m
@@ -0,0 +1,106 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} scatter3 (@var{x}, @var{y}, @var{z}, @var{s}, @var{c})
+## @deftypefnx {Function File} {} scatter3 (@dots{}, 'filled')
+## @deftypefnx {Function File} {} scatter3 (@dots{}, @var{style})
+## @deftypefnx {Function File} {} scatter3 (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} scatter3 (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} scatter3 (@dots{})
+##
+## Plot a scatter plot of the data in 3D.  A marker is plotted at each point 
+## defined by the points in the vectors @var{x}, @var{y} and @var{z}.  The size
+## of the markers used is determined by @var{s}, which can be a scalar or
+## a vector of the same length of @var{x}, @var{y} and @var{z}.  If @var{s} is
+## not given or is an empty matrix, then the default value of 8 points is used.
+##
+## The color of the markers is determined by @var{c}, which can be a string
+## defining a fixed color, a 3 element vector giving the red, green and blue 
+## components of the color, a vector of the same length as @var{x} that gives
+## a scaled index into the current colormap, or a @var{n}-by-3 matrix defining
+## the colors of each of the markers individually.
+##
+## The marker to use can be changed with the @var{style} argument, that is a 
+## string defining a marker in the same manner as the @code{plot} command. 
+## If the argument 'filled' is given then the markers as filled.  All 
+## additional arguments are passed to the underlying patch command.
+##
+## The optional return value @var{h} provides a handle to the patch object
+##
+## @example
+## @group
+## [x, y, z] = peaks (20);
+## scatter3 (x(:), y(:), z(:), [], z(:));
+## @end group
+## @end example
+##
+## @seealso{plot, patch, scatter}
+## @end deftypefn
+
+function retval = scatter3 (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("scatter3", varargin{:});
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      tmp = __scatter__ (h, 3, "scatter3", varargin{:});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+
+  if (! ishold ())
+    set (get (tmp, "parent"), "view", [-37.5, 30]);
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! [x, y, z] = peaks (20);
+%! scatter3 (x(:), y(:), z(:), [], z(:));
+
+%!demo
+%! x = rand (20,1);
+%! y = rand (20,1);
+%! z = rand (20,1);
+%! scatter3 (x(:), y(:), z(:), 10, z(:), "s");
+
+%!demo
+%! x = rand (20,1);
+%! y = rand (20,1);
+%! z = rand (20,1);
+%! scatter3 (x(:), y(:), z(:), 20*z(:), z(:), "s");
+
+%!demo
+%! x = rand (20,1);
+%! y = rand (20,1);
+%! z = rand (20,1);
+%! scatter3 (x(:), y(:), z(:), 20*z(:), [], "s");
+
+
+
diff --git a/scripts/plot/semilogx.m b/scripts/plot/semilogx.m
new file mode 100644
index 0000000..47f68c9
--- /dev/null
+++ b/scripts/plot/semilogx.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} semilogx (@var{args})
+## Produce a two-dimensional plot using a log scale for the @var{x}
+## axis.  See the description of @code{plot} for a description of the
+## arguments that @code{semilogx} will accept.
+## @seealso{plot, semilogy, loglog}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = semilogx (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("semilogx", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    set (h, "xscale", "log");
+
+    tmp = __plt__ ("semilogx", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/semilogxerr.m b/scripts/plot/semilogxerr.m
new file mode 100644
index 0000000..3b71fff
--- /dev/null
+++ b/scripts/plot/semilogxerr.m
@@ -0,0 +1,62 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009
+##               Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} semilogxerr (@var{args})
+## Produce two-dimensional plots on a semilogarithm axis with errorbars.
+## Many different combinations of arguments are possible.  The most used
+## form is
+##
+## @example
+## semilogxerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+## @end example
+##
+## @noindent
+## which produces a semi-logarithm plot of @var{y} versus @var{x}
+## with errors in the @var{y}-scale defined by @var{ey} and the plot
+## format defined by @var{fmt}.  See errorbar for available formats and 
+## additional information.
+## @seealso{errorbar, loglogerr semilogyerr}
+## @end deftypefn
+
+## Created: 20.2.2001
+## Author: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function retval = semilogxerr (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("semilogxerr", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    set (h, "xscale", "log");
+
+    tmp = __errcomm__ ("semilogxerr", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/semilogy.m b/scripts/plot/semilogy.m
new file mode 100644
index 0000000..4a08d43
--- /dev/null
+++ b/scripts/plot/semilogy.m
@@ -0,0 +1,51 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} semilogy (@var{args})
+## Produce a two-dimensional plot using a log scale for the @var{y}
+## axis.  See the description of @code{plot} for a description of the
+## arguments that @code{semilogy} will accept.
+## @seealso{plot, semilogx, loglog}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = semilogy (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("semilogy", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    set (h, "yscale", "log");
+
+    tmp = __plt__ ("semilogy", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/semilogyerr.m b/scripts/plot/semilogyerr.m
new file mode 100644
index 0000000..33d87cc
--- /dev/null
+++ b/scripts/plot/semilogyerr.m
@@ -0,0 +1,61 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007 Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} semilogyerr (@var{args})
+## Produce two-dimensional plots on a semilogarithm axis with errorbars.
+## Many different combinations of arguments are possible.  The most used
+## form is
+##
+## @example
+## semilogyerr (@var{x}, @var{y}, @var{ey}, @var{fmt})
+## @end example
+##
+## @noindent
+## which produces a semi-logarithm plot of @var{y} versus @var{x}
+## with errors in the @var{y}-scale defined by @var{ey} and the plot
+## format defined by @var{fmt}.  See errorbar for available formats and 
+## additional information.
+## @seealso{errorbar, loglogerr semilogxerr}
+## @end deftypefn
+
+## Created: 20.2.2001
+## Author: Teemu Ikonen <tpikonen at pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function retval = semilogyerr (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("semilogyerr", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    set (h, "yscale", "log");
+
+    tmp = __errcomm__ ("semilogyerr", h, varargin{:});
+
+    if (nargout > 0)
+      retval = tmp;
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+endfunction
diff --git a/scripts/plot/shading.m b/scripts/plot/shading.m
new file mode 100644
index 0000000..6eb318b
--- /dev/null
+++ b/scripts/plot/shading.m
@@ -0,0 +1,96 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} shading (@var{type})
+## @deftypefnx {Function File} {} shading (@var{ax}, @dots{})
+## Set the shading of surface or patch graphic objects.  Valid arguments
+## for @var{type} are
+##
+## @table @code
+## @item "flat"
+## Single colored patches with invisible edges.
+##
+## @item "faceted"
+## Single colored patches with visible edges.
+##
+## @item "interp"
+## Color between patch vertices are interpolated and the patch edges are
+## invisible.
+## @end table
+##
+## If @var{ax} is given the shading is applied to axis @var{ax} instead
+## of the current axis.
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function shading (varargin)
+
+  [ax, varargin] = __plt_get_axis_arg__ ("shading", varargin{:});
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  mode = varargin{1};
+
+  h1 = findobj (ax, "type", "patch");
+  h2 = findobj (ax, "type", "surface");
+
+  obj = [h1(:); h2(:)];
+
+  for n = 1:numel(obj)
+    h = obj(n); 
+    if (strcmpi (mode, "flat"))
+      set (h, "facecolor", "flat");
+      set (h, "edgecolor", "none");
+    elseif (strcmpi (mode, "interp"))
+      set (h, "facecolor", "interp");
+      set (h, "edgecolor", "none");
+    elseif (strcmpi (mode, "faceted"))
+      set (h, "facecolor", "flat");
+      set (h, "edgecolor", [0 0 0]);
+    else
+      error ("unknown argument");
+    endif
+  endfor
+
+endfunction
+
+%!demo
+%! clf
+%! colormap (jet)
+%! sombrero
+%! shading faceted
+%! title('shading "faceted"')
+
+%!demo
+%! sombrero
+%! shading interp
+%! title('shading "interp"')
+
+%!demo
+%! pcolor (peaks ())
+%! shading faceted
+%! title('shading "faceted"')
+
+%!demo
+%! pcolor (peaks ())
+%! shading interp
+%! title('shading "interp"')
diff --git a/scripts/plot/shg.m b/scripts/plot/shg.m
new file mode 100644
index 0000000..7e86622
--- /dev/null
+++ b/scripts/plot/shg.m
@@ -0,0 +1,37 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 2000, 2004, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} shg
+## Show the graph window.  Currently, this is the same as executing
+## @code{drawnow}.
+## @seealso{drawnow, figure}
+## @end deftypefn
+
+## Author: jwe
+
+function shg ()
+
+  if (nargin != 0)
+    warning ("shg: ignoring extra arguments");
+  endif
+
+  drawnow ();
+
+endfunction
diff --git a/scripts/plot/slice.m b/scripts/plot/slice.m
new file mode 100644
index 0000000..a1d3aea
--- /dev/null
+++ b/scripts/plot/slice.m
@@ -0,0 +1,184 @@
+## Copyright (C) 2007, 2009 Kai Habel, David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} slice (@var{x}, @var{y}, @var{z}, @var{v}, @var{sx}, @var{sy}, @var{sz})
+## @deftypefnx {Function File} {} slice (@var{x}, @var{y}, @var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
+## @deftypefnx {Function File} {} slice (@var{v}, @var{sx}, @var{sy}, @var{sz})
+## @deftypefnx {Function File} {} slice (@var{v}, @var{xi}, @var{yi}, @var{zi})
+## @deftypefnx {Function File} {@var{h} =} slice (@dots{})
+## @deftypefnx {Function File} {@var{h} =} slice (@dots{}, @var{method})
+## Plot slices of 3D data/scalar fields.  Each element of the 3-dimensional 
+## array @var{v} represents a scalar value at a location given by the
+## parameters @var{x}, @var{y}, and @var{z}.  The parameters @var{x},
+## @var{x}, and @var{z} are either 3-dimensional arrays of the same size
+## as the array @var{v} in the "meshgrid" format or vectors.  The
+## parameters @var{xi}, etc. respect a similar format to @var{x}, etc.,
+## and they represent the points at which the array @var{vi} is
+## interpolated using interp3.  The vectors @var{sx}, @var{sy}, and
+## @var{sz} contain points of orthogonal slices of the respective axes.
+##
+## If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be 
+## @code{x = 1:size (@var{v}, 2)}, @code{y = 1:size (@var{v}, 1)} and
+## @code{z = 1:size (@var{v}, 3)}. 
+##
+## @var{Method} is one of:
+##
+## @table @code
+## @item "nearest"
+## Return the nearest neighbor.
+## @item "linear"
+## Linear interpolation from nearest neighbors.
+## @item "cubic"
+## Cubic interpolation from four nearest neighbors (not implemented yet).
+## @item "spline"
+## Cubic spline interpolation---smooth first and second derivatives
+## throughout the curve.
+## @end table
+##
+## The default method is @code{"linear"}.
+## The optional return value @var{h} is a vector of handles to the
+## surface graphic objects.
+##
+## Examples:
+## @example
+## @group
+## [x, y, z] = meshgrid (linspace (-8, 8, 32));
+## v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+## slice (x, y, z, v, [], 0, []);
+## [xi, yi] = meshgrid (linspace (-7, 7));
+## zi = xi + yi;
+## slice (x, y, z, v, xi, yi, zi);
+## @end group
+## @end example
+## @seealso{interp3, surface, pcolor}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function h = slice (varargin)
+
+  method = "linear";
+  nargs = nargin;
+
+  if (ischar (varargin{end}))
+    method = varargin{end};
+    nargs -= 1;
+  endif
+
+  if (nargs == 4)
+    v = varargin{1};
+    if (ndims (v) != 3)
+      error ("slice: expect 3-dimensional array of values");
+    endif
+    [nx, ny, nz] = size (v);
+    [x, y, z] = meshgrid (1:nx, 1:ny, 1:nz);
+    sx = varargin{2};
+    sy = varargin{3};
+    sz = varargin{4};
+  elseif (nargs == 7)
+    v = varargin{4};
+    if (ndims (v) != 3)
+      error ("slice: expect 3-dimensional array of values");
+    endif
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    if (all ([isvector(x), isvector(y), isvector(z)]))
+      [x, y, z] = meshgrid (x, y, z);
+    elseif (ndims (x) == 3 && size_equal (x, y, z))
+      ## Do nothing.
+    else
+      error ("slice: X, Y, Z size mismatch");
+    endif
+    sx = varargin{5};
+    sy = varargin{6};
+    sz = varargin{7};
+  else
+    print_usage ();
+  endif
+
+  if (any ([isvector(sx), isvector(sy), isvector(sz)]))
+    have_sval = true;
+  elseif (ndims(sx) == 2 && size_equal (sx, sy, sz))
+    have_sval = false;
+  else
+    error ("slice: dimensional mismatch for (XI, YI, ZI) or (SX, SY, SZ)");
+  endif
+
+  newplot ();
+  ax = gca ();
+  sidx = 1;
+  maxv = max (v(:));
+  minv = min (v(:));
+  set (ax, "clim", [minv, maxv]);
+
+  if (have_sval)
+    ns = length (sx) + length (sy) + length (sz);
+    hs = zeros(ns,1);
+    [ny, nx, nz] = size (v);
+    if (length(sz) > 0)
+      for i = 1:length(sz)
+        [xi, yi, zi] = meshgrid (squeeze (x(1,:,1)),
+				 squeeze (y(:,1,1)), sz(i));
+        vz = squeeze (interp3 (x, y, z, v, xi, yi, zi, method));
+        tmp(sidx++) = surface (xi, yi, sz(i) * ones (size (yi)), vz);
+      endfor
+    endif
+
+    if (length (sy) > 0)
+      for i = length(sy):-1:1
+	[xi, yi, zi] = meshgrid (squeeze (x(1,:,1)), sy(i), squeeze (z(1,1,:)));
+        vy = squeeze (interp3 (x, y, z, v, xi, yi, zi, method));
+        tmp(sidx++) = surface (squeeze (xi),
+			       squeeze (sy(i) * ones (size (zi))),
+			       squeeze (zi), vy);
+      endfor
+    endif
+
+    if (length (sx) > 0)
+      for i = length(sx):-1:1
+        [xi, yi, zi] = meshgrid (sx(i), squeeze (y(:,1,1)), squeeze (z(1,1,:)));
+        vx = squeeze (interp3 (x, y, z, v, xi, yi, zi, method));
+        tmp(sidx++) = surface (squeeze (sx(i) * ones (size (zi))),
+			       squeeze (yi), squeeze(zi), vx);
+      endfor
+    endif
+  else
+    vi = interp3 (x, y, z, v, sx, sy, sz);
+    tmp = surface (sx, sy, sz, vi);
+  endif
+
+  if (! ishold ())
+    set (ax, "view", [-37.5, 30.0], "box", "off", "xgrid", "on",
+	 "ygrid", "on", "zgrid", "on");
+  endif
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! [x, y, z] = meshgrid (linspace (-8, 8, 32));
+%! v = sin (sqrt (x.^2 + y.^2 + z.^2)) ./ (sqrt (x.^2 + y.^2 + z.^2));
+%! slice (x, y, z, v, [], 0, []);
+%! [xi, yi] = meshgrid (linspace (-7, 7));
+%! zi = xi + yi;
+%! slice (x, y, z, v, xi, yi, zi);
diff --git a/scripts/plot/sombrero.m b/scripts/plot/sombrero.m
new file mode 100644
index 0000000..b7e7755
--- /dev/null
+++ b/scripts/plot/sombrero.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2005, 2006, 2007
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sombrero (@var{n})
+## Produce the familiar three-dimensional sombrero plot using @var{n}
+## grid lines.  If @var{n} is omitted, a value of 41 is assumed.
+##
+## The function plotted is
+##
+## @example
+## z = sin (sqrt (x^2 + y^2)) / (sqrt (x^2 + y^2))
+## @end example
+## @seealso{surf, meshgrid, mesh}
+## @end deftypefn
+
+## Author: jwe
+
+function [x, y, z] = sombrero (n)
+
+  if (nargin == 0)
+    n = 41;
+  endif
+
+  if (nargin < 2)
+    if (n > 1)
+      tx = ty = linspace (-8, 8, n)';
+      [xx, yy] = meshgrid (tx, ty);
+      r = sqrt (xx .^ 2 + yy .^ 2) + eps;
+      tz = sin (r) ./ r;
+      if (nargout == 0)
+        surf (tx, ty, tz);
+	box ("off");
+      else
+	x = tx;
+	y = ty;
+	z = tz;
+      endif
+    else
+      error ("sombrero: number of grid lines must be greater than 1");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!demo
+%! sombrero ();
diff --git a/scripts/plot/specular.m b/scripts/plot/specular.m
new file mode 100644
index 0000000..e383f88
--- /dev/null
+++ b/scripts/plot/specular.m
@@ -0,0 +1,89 @@
+## Copyright (C) 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{l}, @var{v})
+## @deftypefnx {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{l}, @var{v}, @var{se})
+## Calculate specular reflection strength of a surface defined by the normal
+## vector elements @var{sx}, @var{sy}, @var{sz} using Phong's approximation. 
+## The light and view vectors can be specified using parameter @var{L} and @var{V} respectively.
+## Both can be given as 2-element vectors [azimuth, elevation] in degrees or as 3-element
+## vector [x, y, z].  An optional 6th argument describes the specular exponent (spread) @var{se}.
+## @seealso{surfl, diffuse}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function retval = specular (sx, sy, sz, lv, vv, se)
+
+  if (nargin < 5 || nargin > 6)
+    print_usage ();
+  endif
+
+  ## Checks for specular exponent (se).
+  if (nargin < 6)
+    se = 10;
+  else
+    if (!isnumeric (se) || numel (se) != 1 || se <= 0)
+      error ("specular: exponent must be positive scalar");
+    endif
+  endif
+
+  ## Checks for normal vector.
+  if (!size_equal (sx, sy, sz))
+    error ("specular: SX, SY, and SZ must have same size");
+  endif
+  
+  ## Check for light vector (lv) argument.
+  if (length (lv) < 2 || length (lv) > 3)
+    error ("specular: light vector LV must be a 2- or 3-element vector");
+  elseif (length (lv) == 2)
+    [lv(1), lv(2), lv(3)] = sph2cart (lv(1) * pi/180, lv(2) * pi/180, 1.0);
+  endif
+
+  ## Check for view vector (vv) argument.
+  if (length (vv) < 2 || length (lv) > 3)
+    error ("view vector VV must be a 2- or 3-element vector");
+  elseif (length (vv) == 2)
+    [vv(1), vv(2), vv(3)] = sph2cart (vv(1) * pi / 180, vv(2) * pi / 180, 1.0);
+  endif
+
+  ## Normalize view and light vector.
+  if (sum (abs (lv)) > 0)
+    lv  /= norm (lv);
+  endif
+  if (sum (abs (vv)) > 0)
+    vv  /= norm (vv);
+  endif
+
+  ## Calculate normal vector lengths and dot-products.
+  ns = sqrt (sx.^2 + sy.^2 + sz.^2);
+  l_dot_n = (sx * lv(1) + sy * lv(2) + sz * lv(3)) ./ ns;
+  v_dot_n = (sx * vv(1) + sy * vv(2) + sz * vv(3)) ./ ns;
+
+  ## Calculate specular reflection using Phong's approximation.
+  retval = 2 * l_dot_n .* v_dot_n - dot (lv, vv);
+  
+  ## Set zero if light is on the other side.
+  retval(l_dot_n < 0) = 0;
+
+  ## Allow postive values only.
+  retval(retval < 0) = 0;
+  retval = retval .^ se;
+  
+endfunction
diff --git a/scripts/plot/sphere.m b/scripts/plot/sphere.m
new file mode 100644
index 0000000..1001370
--- /dev/null
+++ b/scripts/plot/sphere.m
@@ -0,0 +1,61 @@
+## Copyright (C) 2007, 2009 Michael Goffioul
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sphere (@var{n})
+## @deftypefnx {Function File} {} sphere (@var{h}, @dots{})
+## Generates three matrices in @code{meshgrid} format, such that 
+## @code{surf (@var{x}, @var{y}, @var{z})} generates a unit sphere. 
+## The matrices of @code{@var{n}+1}-by- at code{@var{n}+1}.  If @var{n} is 
+## omitted then a default value of 20 is assumed.
+##
+## Called with no return arguments, @code{sphere} call directly 
+## @code{surf (@var{x}, @var{y}, @var{z})}.  If an axes handle is passed
+## as the first argument, the surface is plotted to this set of axes.
+## @seealso{peaks}
+## @end deftypefn
+
+function [xx, yy, zz] = sphere (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ((nargout > 0), "sphere", 
+						varargin{:});
+  if (nargin > 1)
+    print_usage ();
+  elseif (nargin == 1)
+    n = varargin{1};
+  else
+    n = 20;
+  endif
+
+  theta = linspace (0, 2*pi, n+1);
+  phi = linspace (-pi/2, pi/2, n+1);
+  [theta,phi] = meshgrid (theta, phi);
+
+  x = cos (phi) .* cos (theta);
+  y = cos (phi) .* sin (theta);
+  z = sin (phi);
+
+  if (nargout > 0)
+    xx = x;
+    yy = y;
+    zz = z;
+  else
+    surf (h, x, y, z);
+  endif
+
+endfunction
diff --git a/scripts/plot/spinmap.m b/scripts/plot/spinmap.m
new file mode 100644
index 0000000..b0146f0
--- /dev/null
+++ b/scripts/plot/spinmap.m
@@ -0,0 +1,57 @@
+## Copyright (C) 2007, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spinmap (@var{t}, @var{inc})
+## Cycle the colormap for @var{t} seconds with an increment
+## of @var{inc}.  Both parameters are optional.  The default cycle time
+## is 5 seconds and the default increment is 2.
+##
+## A higher value of @var{inc} causes a faster cycle through the
+## colormap.
+## @seealso{gca, colorbar}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function spinmap (t, inc)
+
+  if (nargin == 0)
+    inc = 2;
+    t = 5;
+  elseif (nargin == 1)
+    inc = 2;
+  endif
+
+  cmap = get (gcf (), "colormap");
+  clen = rows (cmap);
+
+  t0 = clock;
+
+  while (etime (clock, t0) < t)
+    for n = 1:inc:clen
+      newmap = shift (cmap, n, 1);
+      set (gcf (), "colormap", newmap)
+      drawnow ();
+    endfor
+  endwhile
+
+  set (gcf (), "colormap", cmap)
+
+endfunction
+
diff --git a/scripts/plot/stairs.m b/scripts/plot/stairs.m
new file mode 100644
index 0000000..211550f
--- /dev/null
+++ b/scripts/plot/stairs.m
@@ -0,0 +1,258 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} stairs (@var{x}, @var{y})
+## @deftypefnx {Function File} {} stairs (@dots{}, @var{style})
+## @deftypefnx {Function File} {} stairs (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} stairs (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} stairs (@dots{})
+## Produce a stairstep plot.  The arguments may be vectors or matrices.
+##
+## If only one argument is given, it is taken as a vector of y-values
+## and the x coordinates are taken to be the indices of the elements.
+##
+## If two output arguments are specified, the data are generated but
+## not plotted.  For example,
+##
+## @example
+## stairs (x, y);
+## @end example
+##
+## @noindent
+## and
+##
+## @example
+## @group
+## [xs, ys] = stairs (x, y);
+## plot (xs, ys);
+## @end group
+## @end example
+##
+## @noindent
+## are equivalent.
+## @seealso{plot, semilogx, semilogy, loglog, polar, mesh, contour,
+## bar, xlabel, ylabel, title}
+## @end deftypefn
+
+## Author: jwe
+
+function [xs, ys] = stairs (varargin)
+
+  [ax, varargin, nargin] = __plt_get_axis_arg__ ("stairs", varargin{:});
+
+  if (nargin < 1)
+    print_usage ();
+  else
+    if (nargout > 1)
+      [h, xs, ys] = __stairs__ (false, varargin{:});
+    else
+      oldax = gca ();
+      unwind_protect
+	axes (ax);
+	newplot ();
+	[h, xxs, yys] = __stairs__ (true, varargin{:});
+      unwind_protect_cleanup
+	axes (oldax);
+      end_unwind_protect
+    endif
+    if (nargout == 1)
+      xs = h;
+    endif
+  endif
+endfunction
+
+function [h, xs, ys] = __stairs__ (doplot, varargin)
+
+  if (nargin == 2 || ischar (varargin{2}))
+    y = varargin {1};
+    varargin(1) = [];
+    if (ismatrix (y))
+      if (isvector (y))
+	y = y(:);
+      endif
+      x = 1:rows (y);
+    endif
+  else
+    x = varargin{1};
+    y = varargin{2};
+    varargin(1:2) = [];
+  endif
+
+  if (ndims (x) > 2 || ndims (y) > 2)
+    error ("stairs: expecting 2-d arguments");
+  endif
+
+  vec_x = isvector (x);
+
+  if (vec_x)
+    x = x(:);
+  endif
+
+  if (isvector (y))
+    y = y(:);
+  endif
+
+  if (ismatrix (y))
+    [nr, nc] = size (y);
+    if (vec_x)
+      x = repmat (x, [1, nc]);
+    else
+      [x_nr, x_nc] = size (x);
+      if (x_nr != nr || x_nc != nc)
+	error ("stairs: argument size mismatch");
+      endif
+    endif
+  endif
+
+  len = 2*nr - 1;
+
+  xs = ys = zeros (len, nc);
+
+  xs(1,:) = x(1,:);
+  ys(1,:) = y(1,:);
+
+  xtmp = x(2:nr,:);
+  ridx = 2:2:len-1;
+  xs(ridx,:) = xtmp;
+  ys(ridx,:) = y(1:nr-1,:);
+
+  ridx = 3:2:len;
+  xs(ridx,:) = xtmp;
+  ys(ridx,:) = y(2:nr,:);
+
+  have_line_spec = false;
+  for i = 1 : length (varargin)
+    arg = varargin {i};
+    if ((ischar (arg) || iscell (arg)) && ! have_line_spec)
+      [linespec, valid] = __pltopt__ ("stairs", arg, false);
+      if (valid)
+	have_line_spec = true;
+	varargin(i) = [];
+	break;
+      endif
+    endif
+  endfor 
+
+  if (doplot)
+    h = [];
+    unwind_protect
+      hold_state = get (gca (), "nextplot");
+      for i = 1 : size(y, 2)
+	hg = hggroup ();
+	h = [h; hg];
+	args = __add_datasource__ ("stairs", hg, {"x", "y"}, varargin{:});
+
+	addproperty ("xdata", hg, "data", x(:,i).');
+	addproperty ("ydata", hg, "data", y(:,i).');
+
+	addlistener (hg, "xdata", @update_data);
+	addlistener (hg, "ydata", @update_data);
+
+	if (have_line_spec)
+	  tmp = line (xs(:,i).', ys(:,i).', "color", linespec.color,
+		      "parent", hg);
+	else
+	  tmp = line (xs(:,i).', ys(:,i).', "color", __next_line_color__ (),
+		      "parent", hg);
+	endif
+
+        addproperty ("color", hg, "linecolor", get (tmp, "color"));
+	addproperty ("linewidth", hg, "linelinewidth", get (tmp, "linewidth"));
+	addproperty ("linestyle", hg, "linelinestyle", get (tmp, "linestyle"));
+
+	addproperty ("marker", hg, "linemarker", get (tmp, "marker"));
+	addproperty ("markerfacecolor", hg, "linemarkerfacecolor",
+		     get (tmp, "markerfacecolor"));
+	addproperty ("markeredgecolor", hg, "linemarkeredgecolor",
+		     get (tmp, "markeredgecolor"));
+	addproperty ("markersize", hg, "linemarkersize",
+		     get (tmp, "markersize"));
+
+	addlistener (hg, "color", @update_props);
+	addlistener (hg, "linewidth", @update_props); 
+	addlistener (hg, "linestyle", @update_props); 
+	addlistener (hg, "marker", @update_props); 
+	addlistener (hg, "markerfacecolor", @update_props); 
+	addlistener (hg, "markeredgecolor", @update_props); 
+	addlistener (hg, "markersize", @update_props); 
+
+	if (! isempty (args))
+	  set (hg, args{:});
+	endif
+      endfor
+    unwind_protect_cleanup
+      set (gca (), "nextplot", hold_state);
+    end_unwind_protect
+  else
+    h = 0;
+  endif
+
+endfunction
+
+%!demo
+%! x = 1:10;
+%! y = rand (1, 10);
+%! stairs (x, y);
+
+%!demo
+%! x = 1:10;
+%! y = rand (1, 10);
+%! [xs, ys] = stairs (x, y);
+%! plot (xs, ys);
+
+%!demo
+%! stairs (1:9);
+
+%!demo
+%! [xs, ys] = stairs (9:-1:1);
+%! plot (xs, ys);
+
+function update_props (h, d)
+  set (get (h, "children"), "color", get (h, "color"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"),
+       "marker", get (h, "marker"),
+       "markerfacecolor", get (h, "markerfacecolor"),
+       "markeredgecolor", get (h, "markeredgecolor"),
+       "markersize", get (h, "markersize"));
+endfunction
+
+function update_data (h, d)
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+
+  nr = length (x);
+  len = 2 * nr - 1;
+  xs = ys = zeros (1, len);
+
+  xs(1) = x(1);
+  ys(1) = y(1);
+
+  xtmp = x(2:nr);
+  ridx = 2:2:len-1;
+  xs(ridx) = xtmp;
+  ys(ridx) = y(1:nr-1);
+
+  ridx = 3:2:len;
+  xs(ridx) = xtmp;
+  ys(ridx) = y(2:nr);
+
+  set (get (h, "children"), "xdata", xs, "ydata", ys);
+endfunction
diff --git a/scripts/plot/stem.m b/scripts/plot/stem.m
new file mode 100644
index 0000000..d37f5b3
--- /dev/null
+++ b/scripts/plot/stem.m
@@ -0,0 +1,120 @@
+## Copyright (C) 2006, 2007, 2008, 2009 Michel D. Schmid
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} stem (@var{x}, @var{y}, @var{linespec})
+## @deftypefnx {Function File} {@var{h} =} stem (@dots{}, "filled")
+## Plot a stem graph from two vectors of x-y data.  If only one argument
+## is given, it is taken as the y-values and the x coordinates are taken
+## from the indices of the elements.
+##
+## If @var{y} is a matrix, then each column of the matrix is plotted as
+## a separate stem graph.  In this case @var{x} can either be a vector,
+## the same length as the number of rows in @var{y}, or it can be a
+## matrix of the same size as @var{y}.
+##
+## The default color is @code{"r"} (red).  The default line style is
+## @code{"-"} and the default marker is @code{"o"}.  The line style can
+## be altered by the @code{linespec} argument in the same manner as the
+## @code{plot} command.  For example
+##
+## @example
+## @group
+## x = 1:10;
+## y = ones (1, length (x))*2.*x;
+## stem (x, y, "b");
+## @end group
+## @end example
+##
+## @noindent
+## plots 10 stems with heights from 2 to 20 in blue;
+## 
+## The return value of @code{stem} is a vector if "stem series" graphics
+## handles, with one handle per column of the variable @var{y}.  This
+## handle regroups the elements of the stem graph together as the
+## children of the "stem series" handle, allowing them to be altered
+## together.  For example
+##
+## @example
+## @group
+## x = [0 : 10].';
+## y = [sin(x), cos(x)]
+## h = stem (x, y);
+## set (h(2), "color", "g");
+## set (h(1), "basevalue", -1)
+## @end group
+## @end example
+##
+## @noindent
+## changes the color of the second "stem series"  and moves the base line
+## of the first.
+## @seealso{bar, barh, plot}
+## @end deftypefn
+
+## Author: Michel D. Schmid <michaelschmid at users.sourceforge.net>
+## Adapted-by: jwe
+
+function h = stem (varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  tmp = __stem__ (false, varargin{:});
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! x = 1:10;
+%! stem (x);
+
+%!demo
+%! x = 1:10;
+%! y = ones (1, length (x))*2.*x;
+%! stem (x, y);
+
+%!demo
+%! x = 1:10;
+%! y = ones (size (x))*2.*x;
+%! h = stem (x, y, "b");
+
+%!demo
+%! x = 1:10;
+%! y = ones (size (x))*2.*x;
+%! h = stem (x, y, "-.k");
+
+%!demo
+%! x = 1:10;
+%! y = ones (size (x))*2.*x;
+%! h = stem (x, y, "-.k.");
+
+%!demo
+%! x = 1:10;
+%! y = ones (size (x))*2.*x;
+%! h = stem (x, y, "fill");
+
+%!demo
+%! x = [0 : 10].';
+%! y = [sin(x), cos(x)];
+%! h = stem (x, y);
+%! set (h(2), "color", "g");
+%! set (h(1), "basevalue", -1)
diff --git a/scripts/plot/stem3.m b/scripts/plot/stem3.m
new file mode 100644
index 0000000..5b9e4ea
--- /dev/null
+++ b/scripts/plot/stem3.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} stem3 (@var{x}, @var{y}, @var{z}, @var{linespec})
+## Plot a three-dimensional stem graph and return the handles of the line
+## and marker objects used to draw the stems as "stem series" object.
+## The default color is @code{"r"} (red).  The default line style is
+## @code{"-"} and the default marker is @code{"o"}.
+##
+## For example,
+## @example
+## @group
+## theta = 0:0.2:6; 
+## stem3 (cos (theta), sin (theta), theta) 
+## @end group
+## @end example
+##
+## @noindent
+## plots 31 stems with heights from 0 to 6 lying on a circle.  Color 
+## definitions with rgb-triples are not valid!
+## @seealso{bar, barh, stem, plot}
+## @end deftypefn
+
+function h = stem3 (varargin)
+
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
+
+  tmp = __stem__ (true, varargin{:});
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! theta = 0:0.2:6; 
+%! stem3 (cos (theta), sin (theta), theta) 
diff --git a/scripts/plot/subplot.m b/scripts/plot/subplot.m
new file mode 100644
index 0000000..513406c
--- /dev/null
+++ b/scripts/plot/subplot.m
@@ -0,0 +1,266 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005,
+##               2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} subplot (@var{rows}, @var{cols}, @var{index})
+## @deftypefnx {Function File} {} subplot (@var{rcn})
+## Set up a plot grid with @var{cols} by @var{rows} subwindows and plot
+## in location given by @var{index}.
+##
+## If only one argument is supplied, then it must be a three digit value
+## specifying the location in digits 1 (rows) and 2 (columns) and the plot
+## index in digit 3.
+##
+## The plot index runs row-wise.  First all the columns in a row are filled
+## and then the next row is filled.
+##
+## For example, a plot with 2 by 3 grid will have plot indices running as
+## follows:
+## @tex
+## \vskip 10pt
+## \hfil\vbox{\offinterlineskip\hrule
+## \halign{\vrule#&&\qquad\hfil#\hfil\qquad\vrule\cr
+## height13pt&1&2&3\cr height12pt&&&\cr\noalign{\hrule}
+## height13pt&4&5&6\cr height12pt&&&\cr\noalign{\hrule}}}
+## \hfil
+## \vskip 10pt
+## @end tex
+## @ifnottex
+## @display
+## @example
+## @group
+##
+## +-----+-----+-----+
+## |  1  |  2  |  3  |
+## +-----+-----+-----+
+## |  4  |  5  |  6  |
+## +-----+-----+-----+
+## @end group
+## @end example
+## @end display
+## @end ifnottex
+## @seealso{plot}
+## @end deftypefn
+
+## Author: Vinayak Dutt <Dutt.Vinayak at mayo.EDU>
+## Adapted-By: jwe
+
+function h = subplot (rows, columns, index)
+
+  if (nargin != 3 && nargin != 1)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+
+    if (! (isscalar (rows) && rows >= 0))
+      error ("subplot: input rcn has to be a positive scalar");
+    endif
+
+    tmp = rows;
+    index = rem (tmp, 10);
+    tmp = (tmp - index) / 10;
+    columns = rem (tmp, 10);
+    tmp = (tmp - columns) / 10;
+    rows = rem (tmp, 10);
+
+  elseif (! (isscalar (columns) && isscalar (rows)))
+    error ("subplot: columns, and rows must be scalars");
+  elseif (any (index < 1) || any (index > rows*columns))
+    error ("subplot: index value must be greater than 1 and less than rows*columns")
+  endif
+
+  columns = round (columns);
+  rows = round (rows);
+  index = round (index);
+
+  if (index > columns*rows)
+    error ("subplot: index must be less than columns*rows");
+  endif
+
+  if (columns < 1 || rows < 1 || index < 1)
+    error ("subplot: columns,rows,index must be be positive");
+  endif
+
+  units = get (0, "defaultaxesunits");
+  unwind_protect
+    set (0, "defaultaxesunits", "normalized")
+    pos = subplot_position (rows, columns, index, "position", units);
+
+    cf = gcf ();
+
+    set (cf, "nextplot", "add");
+
+    found = false;
+    kids = get (cf, "children");
+    for child = reshape (kids, 1, numel (kids))
+      ## Check whether this child is still valid; this might not be the
+      ## case anymore due to the deletion of previous children (due to
+      ## "deletefcn" callback or for legends/colorbars that are deleted
+      ## with their corresponding axes).
+      if (! ishandle (child))
+        continue;
+      endif
+      if (strcmp (get (child, "type"), "axes"))
+        ## Skip legend and colorbar objects.
+        if (strcmp (get (child, "tag"), "legend") || 
+	    strcmp (get (child, "tag"), "colorbar"))
+          continue;
+        endif
+        objpos = get (child, "position");
+        if (all (objpos == pos))
+	  ## If the new axes are in exactly the same position as an
+	  ## existing axes object, use the existing axes.
+	  found = true;
+	  tmp = child;
+        else
+	  ## If the new axes overlap an old axes object, delete the old
+	  ## axes.
+	  x0 = pos(1);
+	  x1 = x0 + pos(3);
+	  y0 = pos(2);
+	  y1 = y0 + pos(4);	
+	  objx0 = objpos(1);
+	  objx1 = objx0 + objpos(3);
+	  objy0 = objpos(2);
+	  objy1 = objy0 + objpos(4);
+	  if (! (x0 >= objx1 || x1 <= objx0 || y0 >= objy1 || y1 <= objy0))
+	    delete (child);
+	  endif
+        endif
+      endif
+    endfor
+
+    if (found)
+      set (cf, "currentaxes", tmp);
+    else
+      pos = subplot_position (rows, columns, index, "outerposition", units);
+      pos2 = subplot_position (rows, columns, index, "position", units);
+      tmp = axes ("outerposition", pos, "position", pos2);
+    endif
+
+  unwind_protect_cleanup
+    set (0, "defaultaxesunits", units);
+  end_unwind_protect
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
+
+function pos = subplot_position (rows, columns, index, position_property, units)
+
+  ## For 1 row and 1 column return the usual default.
+  if (rows == 1 && columns == 1)
+    if (strcmpi (position_property, "position"))
+      pos = get (0, "defaultaxesposition");
+    else
+      pos = get (0, "defaultaxesouterposition");
+    endif
+    return
+  endif
+
+  ## This produces compatible behavior for the "position" property.
+  margins.left   = 0.130;
+  margins.right  = 0.095;
+  margins.top    = 0.075;
+  margins.bottom = 0.110;
+  pc = 1 ./ [0.1860, (margins.left + margins.right - 1)];
+  margins.column = 1 ./ polyval (pc , columns);
+  pr = 1 ./ [0.2282, (margins.top + margins.bottom - 1)];
+  margins.row    = 1 ./ polyval (pr , rows);
+
+  ## Calculate the width/height of the subplot axes.
+  width = 1 - margins.left - margins.right - (columns-1)*margins.column;
+  width = width / columns;
+  height = 1 - margins.top - margins.bottom - (rows-1)*margins.row;
+  height = height / rows;
+
+  if (strcmp (position_property, "outerposition") )
+    ## Calculate the outerposition/position inset
+    if (rows > 1)
+      inset.top    = 8/420;
+      inset.bottom = max (polyval ([0.1382,-0.0026], height), 16/420);
+    else
+      inset.bottom = margins.bottom;
+      inset.top = margins.top;
+    endif
+    if (columns > 1)
+      if (strcmpi (units, "normalized"))
+        inset.right = max (polyval ([0.1200,-0.0014], width), 5/560);
+      else
+        inset.right = max (polyval ([0.1252,-0.0023], width), 5/560);
+      endif
+      inset.left   = 22/560;
+    else
+      inset.left  = margins.left;
+      inset.right = margins.right;
+    endif
+    ## Apply the inset to the geometries for the "position" property.
+    margins.column = margins.column - inset.right - inset.left;
+    margins.row = margins.row - inset.top - inset.bottom;
+    width = width + inset.right + inset.left;
+    height = height + inset.top + inset.bottom;
+  endif
+
+  yp = fix ((index(:)-1)/columns);
+  xp = index(:) - yp*columns - 1;
+  yp = (rows - 1) - yp;
+
+  x0 = xp .* (width + margins.column) + margins.left;
+  y0 = yp .* (height + margins.row) + margins.bottom;
+
+  if (strcmp (position_property, "outerposition") )
+    x0 = x0 - inset.left;
+    y0 = y0 - inset.bottom;
+  endif
+
+  if (numel(x0) > 1)
+    x1 = max (x0) + width;
+    y1 = max (y0) + height;
+    x0 = min (x0);
+    y0 = min (y0);
+    pos = [x0, y0, x1-x0, y1-y0];
+  else
+    pos = [x0, y0, width, height];
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! r = 3;
+%! c = 3;
+%! fmt = {'horizontalalignment', 'center', 'verticalalignment', 'middle'};
+%! for n = 1:(r*c)
+%!   subplot (r, c, n)
+%!   xlabel (sprintf ("xlabel #%d", n))
+%!   ylabel (sprintf ("ylabel #%d", n))
+%!   title (sprintf ("title #%d", n))
+%!   text (0.5, 0.5, sprintf('subplot(%d,%d,%d)', r, c, n), fmt{:})
+%!   axis ([0 1 0 1])
+%! endfor
+%! subplot (r, c, 1:3)
+%! xlabel (sprintf ("xlabel #%d:%d", 1, 3))
+%! ylabel (sprintf ("ylabel #%d:%d", 1, 3))
+%! title (sprintf ("title #%d:%d", 1, 3))
+%! text (0.5, 0.5, sprintf('subplot(%d,%d,%d:%d)', r, c, 1, 3), fmt{:})
+%! axis ([0 1 0 1])
+
diff --git a/scripts/plot/surf.m b/scripts/plot/surf.m
new file mode 100644
index 0000000..987236e
--- /dev/null
+++ b/scripts/plot/surf.m
@@ -0,0 +1,54 @@
+## Copyright (C) 2007 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} surf (@var{x}, @var{y}, @var{z})
+## Plot a surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+## the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+## correspond to different @var{x} values and rows of @var{z} correspond
+## to different @var{y} values.
+## @seealso{mesh, surface}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function retval = surf (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("surf", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+    tmp = surface (varargin{:});
+
+    if (! ishold ())
+      set (h, "view", [-37.5, 30],
+	   "xgrid", "on", "ygrid", "on", "zgrid", "on");
+    endif
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/surface.m b/scripts/plot/surface.m
new file mode 100644
index 0000000..da852e9
--- /dev/null
+++ b/scripts/plot/surface.m
@@ -0,0 +1,158 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} surface (@var{x}, @var{y}, @var{z}, @var{c})
+## @deftypefnx {Function File} {} surface (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {} surface (@var{z}, @var{c})
+## @deftypefnx {Function File} {} surface (@var{z})
+## @deftypefnx {Function File} {} surface (@dots{}, @var{prop}, @var{val})
+## @deftypefnx {Function File} {} surface (@var{h}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} surface (@dots{})
+## Plot a surface graphic object given matrices @var{x}, and @var{y} from 
+## @code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+## @var{y} coordinates of the surface.  If @var{x} and @var{y} are vectors,
+## then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+## columns of @var{z} correspond to different @var{x} values and rows of 
+## @var{z} correspond to different @var{y} values.  If @var{x} and @var{y}
+## are missing, they are constructed from size of the matrix @var{z}.
+##
+## Any additional properties passed are assigned to the surface.
+## @seealso{surf, mesh, patch, line}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = surface (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("surface", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    [tmp, bad_usage] = __surface__ (h, varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (bad_usage)
+    print_usage ();
+  endif
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+function [h, bad_usage] = __surface__ (ax, varargin)
+
+  bad_usage = false;
+  h = 0;
+  firststring = nargin;
+  for i = 2 : nargin
+    if (ischar (varargin{i - 1}))
+      firststring = i - 1;
+      break;
+    endif
+  endfor
+
+  if (firststring > 5)
+    bad_usage = true;
+  elseif (firststring == 5)
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    c = varargin{4};
+
+    if (! size_equal (z, c))
+      error ("surface: z and c must have same size");
+    endif
+    if (isvector (x) && isvector (y) && ismatrix (z))
+      if (rows (z) == length (y) && columns (z) == length (x))
+        x = x(:)';
+        y = y(:);
+      else
+        error ("surface: rows (z) must be the same as length (y) and columns (z) must be the same as length (x)");
+      endif
+    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
+      if (! size_equal (x, y, z))
+        error ("surface: x, y, and z must have same dimensions");
+      endif
+    else
+      error ("surface: x and y must be vectors and z must be a matrix");
+    endif
+  elseif (firststring == 4)
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    c = z;
+    if (isvector (x) && isvector (y) && ismatrix (z))
+      if (rows (z) == length (y) && columns (z) == length (x))
+        x = x(:)';
+        y = y(:);
+      else
+        error ("surface: rows (z) must be the same as length (y) and columns (z) must be the same as length (x)");
+      endif
+    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
+      if (! size_equal (x, y, z))
+        error ("surface: x, y, and z must have same dimensions");
+      endif
+    else
+      error ("surface: x and y must be vectors and z must be a matrix");
+    endif
+  elseif (firststring == 3)    
+    z = varargin{1};
+    c = varargin{2};
+    if (ismatrix (z))
+      [nr, nc] = size (z);
+      x = 1:nc;
+      y = (1:nr)';
+    else
+      error ("surface: argument must be a matrix");
+    endif
+  elseif (firststring == 2)    
+    z = varargin{1};
+    c = z;
+    if (ismatrix (z))
+      [nr, nc] = size (z);
+      x = 1:nc;
+      y = (1:nr)';
+    else
+      error ("surface: argument must be a matrix");
+    endif
+  else
+    bad_usage = true;
+  endif
+
+  if (! bad_usage)
+    ## Make a default surface object.
+    other_args = {};
+    if (firststring < nargin)
+      other_args = varargin(firststring:end);
+    endif
+    h = __go_surface__ (ax, "xdata", x, "ydata", y, "zdata", z, "cdata", c,
+			other_args{:});
+
+    if (! ishold ())
+      set (ax, "view", [0, 90], "box", "off");
+    endif
+  endif
+
+endfunction
diff --git a/scripts/plot/surfc.m b/scripts/plot/surfc.m
new file mode 100644
index 0000000..df3d870
--- /dev/null
+++ b/scripts/plot/surfc.m
@@ -0,0 +1,59 @@
+## Copyright (C) 1996, 1997, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} surfc (@var{x}, @var{y}, @var{z})
+## Plot a surface and contour given matrices @var{x}, and @var{y} from 
+## @code{meshgrid} and a matrix @var{z} corresponding to the @var{x} and 
+## @var{y} coordinates of the mesh.  If @var{x} and @var{y} are vectors, 
+## then a typical vertex is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, 
+## columns of @var{z} correspond to different @var{x} values and rows of 
+## @var{z} correspond to different @var{y} values.
+## @seealso{meshgrid, surf, contour}
+## @end deftypefn
+
+function h = surfc (varargin)
+
+  newplot ();
+
+  tmp = surface (varargin{:});
+
+  ax = get (tmp, "parent");
+
+  set (tmp, "facecolor", "flat");
+
+  if (! ishold ())
+    set (ax, "view", [-37.5, 30]);
+  endif
+
+  if (nargin == 1)
+    z = varargin{1};
+  else
+    z = varargin{3};
+  endif
+  zmin = 2 * (min(z(:)) - max(z(:)));
+
+  [c, tmp2] = __contour__ (ax, zmin, varargin{:});
+
+  tmp = [tmp; tmp2];
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/surfl.m b/scripts/plot/surfl.m
new file mode 100644
index 0000000..19ec7d8
--- /dev/null
+++ b/scripts/plot/surfl.m
@@ -0,0 +1,180 @@
+## Copyright (C) 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} surfl (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {} surfl (@var{z})
+## @deftypefnx {Function File} {} surfl (@var{x}, @var{y}, @var{z}, @var{L})
+## @deftypefnx {Function File} {} surfl (@var{x}, @var{y}, @var{z}, @var{L}, @var{P})
+## @deftypefnx {Function File} {} surfl (@dots{},"light")
+## Plot a lighted surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+## the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+## correspond to different @var{x} values and rows of @var{z} correspond
+## to different @var{y} values.
+##
+## The light direction can be specified using @var{L}.  It can be
+## given as 2-element vector [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz].
+## The default value is rotated 45° counter-clockwise from the current view.
+##
+## The material properties of the surface can specified using a 4-element vector
+## @var{P} = [@var{AM} @var{D} @var{SP} @var{exp}] which defaults to
+## @var{p} = [0.55 0.6 0.4 10]. 
+## @table @code
+## @item "AM" strength of ambient light
+## @item "D" strength of diffuse reflection
+## @item "SP" strength of specular reflection
+## @item "EXP" specular exponent
+## @end table
+## 
+## The default lighting mode "cdata", changes the cdata property to give the impression
+## of a lighted surface.  Please note: the alternative "light" mode, which creates a light
+## object to illuminate the surface is not implemented (yet).
+##
+## Example:
+##
+## @example
+## @group
+## colormap(bone);
+## surfl(peaks);
+## shading interp;
+## @end group
+## @end example
+## @seealso{surf, diffuse, specular, surface}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel at gmx.de>
+
+function retval = surfl (varargin)
+
+  [h, varargin] = __plt_get_axis_arg__ ("surfl", varargin{:});
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    newplot ();
+
+    ## Check for lighting type.
+    use_cdata = true;
+    if (ischar (varargin{end}))
+      lstr = varargin{end};
+      if (strncmp (tolower (lstr), "light", 5))
+        warning ("light method not supported (yet), using cdata method instead");
+	## This can be implemented when light objects are supported.
+        use_cdata = false;
+      elseif (strncmp (tolower (lstr), "cdata", 5))
+        use_cdata = true;
+      else
+        error ("surfl: unknown lighting method");
+      endif
+      varargin(end) = [];
+    endif
+
+    ## Check for reflection properties argument.
+    ##
+    ## r = [ambient light strength,
+    ##      diffuse reflection strength,
+    ##      specular reflection strength,
+    ##      specular shine] 
+    if (length (varargin{end}) == 4 && isnumeric (varargin{end}))
+      r = varargin{end};
+      varargin(end) = [];
+    else
+      ## Default values.
+      r = [0.55, 0.6, 0.4, 10];
+    endif
+
+    ## Check for light vector (lv) argument.
+    have_lv = false;
+    if (isnumeric (varargin{end}))
+      len = numel (varargin{end});
+      lastarg = varargin{end};
+      if (len == 3)
+        lv = lastarg;
+        varargin(end) = [];
+        have_lv = true;
+      elseif (len == 2)
+        [lv(1), lv(2), lv(3)] = sph2cart ((lastarg(1) - 90) * pi/180, lastarg(2) * pi/180, 1.0);
+        varargin(end) = [];
+        have_lv = true;
+      endif
+    endif
+    
+    tmp = surface (varargin{:});
+    if (! ishold ())
+      set (h, "view", [-37.5, 30],
+	   "xgrid", "on", "ygrid", "on", "zgrid", "on", "clim", [0 1]);
+    endif
+
+    ## Get view vector (vv).
+    a = axis;
+    [az, el] = view;
+    [vv(1), vv(2), vv(3)] = sph2cart ((az - 90) * pi/180.0, el * pi/180.0, 1.0);
+    vv /= norm (vv);
+
+    if (!have_lv)
+      ## Calculate light vector (lv) from view vector.
+      Phi = 45.0 / 180.0 * pi;
+      R = [cos(Phi), -sin(Phi), 0;
+           sin(Phi),  cos(Phi), 0;
+           0,          0,         1];
+      lv = (R * vv.').';
+    endif
+
+    vn = get (tmp, "vertexnormals");
+    dar = get (h, "dataaspectratio");
+    vn(:,:,1) *= dar(1);
+    vn(:,:,2) *= dar(2);
+    vn(:,:,3) *= dar(3);
+
+    ## Normalize vn.
+    vn = vn ./ repmat (sqrt (sumsq (vn, 3)), [1, 1, 3]);
+    [nr, nc] = size(get(tmp, "zdata"));
+
+    ## Ambient, diffuse, and specular term.
+    cdata = (r(1) * ones (nr, nc)
+             + r(2) * diffuse  (vn(:,:,1), vn(:,:,2), vn(:,:,3), lv)
+             + r(3) * specular (vn(:,:,1), vn(:,:,2), vn(:,:,3), lv, vv, r(4)));
+
+    set (tmp, "cdata", cdata ./ sum (r(1:3)));
+    
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
+
+%!demo
+%! clf
+%! [X,Y,Z]=sombrero;
+%! colormap(copper);
+%! surfl(X,Y,Z);
+%! shading interp;
+
+%!demo
+%! [X,Y,Z]=sombrero;
+%! colormap(copper);
+%! [az, el] = view;
+%! surfl(X,Y,Z,[az+225,el],[0.2 0.6 0.4 25]);
+%! shading interp;
+
diff --git a/scripts/plot/surfnorm.m b/scripts/plot/surfnorm.m
new file mode 100644
index 0000000..3cb0676
--- /dev/null
+++ b/scripts/plot/surfnorm.m
@@ -0,0 +1,150 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} surfnorm (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {} surfnorm (@var{z})
+## @deftypefnx {Function File} {[@var{nx}, @var{ny}, @var{nz}] =} surfnorm (@dots{})
+## @deftypefnx {Function File} {} surfnorm (@var{h}, @dots{})
+## Find the vectors normal to a meshgridded surface.  The meshed gridded 
+## surface is defined by @var{x}, @var{y}, and @var{z}.  If @var{x} and 
+## @var{y} are not defined, then it is assumed that they are given by
+##
+## @example
+## @group
+## [@var{x}, @var{y}] = meshgrid (1:size(@var{z}, 1), 
+##                      1:size(@var{z}, 2));
+## @end group
+## @end example
+##
+## If no return arguments are requested, a surface plot with the normal 
+## vectors to the surface is plotted.  Otherwise the components of the normal
+## vectors at the mesh gridded points are returned in @var{nx}, @var{ny},
+## and @var{nz}.
+##
+## The normal vectors are calculated by taking the cross product of the 
+## diagonals of each of the quadrilaterals in the meshgrid to find the 
+## normal vectors of the centers of these quadrilaterals.  The four nearest
+## normal vectors to the meshgrid points are then averaged to obtain the 
+## normal to the surface at the meshgridded points.
+##
+## An example of the use of @code{surfnorm} is
+##
+## @example
+## surfnorm (peaks (25));
+## @end example
+## @seealso{surf, quiver3}
+## @end deftypefn
+
+function [Nx, Ny, Nz] = surfnorm (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ((nargout != 0), "surfnorm", 
+						varargin{:});
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    z = varargin{1};
+    [x, y] = meshgrid (1:size(z,1), 1:size(z,2));
+    ioff = 2;
+  else
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    ioff = 4;
+  endif
+
+  if (nargout == 0)
+  endif
+
+  ## Make life easier, and avoid having to do the extrapolation later, do
+  ## a simpler linear extrapolation here. This is approximative, and works
+  ## badly for closed surfaces like spheres.
+  xx = [2 .* x(:,1) - x(:,2), x, 2 .* x(:,end) - x(:,end-1)];
+  xx = [2 .* xx(1,:) - xx(2,:); xx; 2 .* xx(end,:) - xx(end-1,:)];
+  yy = [2 .* y(:,1) - y(:,2), y, 2 .* y(:,end) - y(:,end-1)];
+  yy = [2 .* yy(1,:) - yy(2,:); yy; 2 .* yy(end,:) - yy(end-1,:)];
+  zz = [2 .* z(:,1) - z(:,2), z, 2 .* z(:,end) - z(:,end-1)];
+  zz = [2 .* zz(1,:) - zz(2,:); zz; 2 .* zz(end,:) - zz(end-1,:)];
+
+  u.x = xx(1:end-1,1:end-1) - xx(2:end,2:end);
+  u.y = yy(1:end-1,1:end-1) - yy(2:end,2:end);
+  u.z = zz(1:end-1,1:end-1) - zz(2:end,2:end);
+  v.x = xx(1:end-1,2:end) - xx(2:end,1:end-1);
+  v.y = yy(1:end-1,2:end) - yy(2:end,1:end-1);
+  v.z = zz(1:end-1,2:end) - zz(2:end,1:end-1);
+
+  c = cross ([u.x(:), u.y(:), u.z(:)], [v.x(:), v.y(:), v.z(:)]);
+  w.x = reshape (c(:,1), size(u.x));
+  w.y = reshape (c(:,2), size(u.y));
+  w.z = reshape (c(:,3), size(u.z));
+
+  ## Create normal vectors as mesh vectices from normals at mesh centers
+  nx = (w.x(1:end-1,1:end-1) + w.x(1:end-1,2:end) +
+	w.x(2:end,1:end-1) + w.x(2:end,2:end)) ./ 4; 
+  ny = (w.y(1:end-1,1:end-1) + w.y(1:end-1,2:end) +
+	w.y(2:end,1:end-1) + w.y(2:end,2:end)) ./ 4; 
+  nz = (w.z(1:end-1,1:end-1) + w.z(1:end-1,2:end) +
+	w.z(2:end,1:end-1) + w.z(2:end,2:end)) ./ 4; 
+
+  ## Normalize the normal vectors
+  len = sqrt (nx.^2 + ny.^2 + nz.^2);
+  nx = nx ./ len;
+  ny = ny ./ len;
+  nz = nz ./ len;
+
+  if (nargout == 0)
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      surf (x, y, z, varargin{ioff:end});
+      old_hold_state = get (h, "nextplot");
+      unwind_protect
+	set (h, "nextplot", "add");
+	plot3 ([x(:)'; x(:).' + nx(:).' ; NaN(size(x(:).'))](:),
+	       [y(:)'; y(:).' + ny(:).' ; NaN(size(y(:).'))](:),
+	       [z(:)'; z(:).' + nz(:).' ; NaN(size(z(:).'))](:), 
+	       varargin{ioff:end});
+      unwind_protect_cleanup
+	set (h, "nextplot", old_hold_state);
+      end_unwind_protect
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  else
+    Nx = nx;
+    Ny = ny;
+    Nz = nz;
+  endif
+
+endfunction
+
+%!demo
+%! colormap (jet (64))
+%! [x, y, z] = peaks(10);
+%! surfnorm (x, y, z);
+
+%!demo
+%! surfnorm (peaks(10));
+
+%!demo
+%! surfnorm (peaks(32));
+%! shading interp
diff --git a/scripts/plot/text.m b/scripts/plot/text.m
new file mode 100644
index 0000000..49d75e9
--- /dev/null
+++ b/scripts/plot/text.m
@@ -0,0 +1,105 @@
+## Copyright (C) 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{label})
+## @deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{z}, @var{label})
+## @deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{label}, @var{p1}, @var{v1}, @dots{})
+## @deftypefnx {Function File} {@var{h} =} text (@var{x}, @var{y}, @var{z}, @var{label}, @var{p1}, @var{v1}, @dots{})
+## Create a text object with text @var{label} at position @var{x},
+## @var{y}, @var{z} on the current axes.  Property-value pairs following
+## @var{label} may be used to specify the appearance of the text.
+## @end deftypefn
+
+## Author: jwe
+
+function h = text (varargin)
+
+  nargs = nargin;
+  offset = 0;
+
+  if (nargs > 2 && isnumeric (varargin{1}) && isnumeric (varargin{2}))
+    x = varargin{1};
+    y = varargin{2};
+    offset = 3;
+
+    if (nargin > 3 && isnumeric (varargin{3}))
+      z = varargin{3};
+      offset = 4;
+    else
+      z = zeros (size (x));
+      offset = 3;
+    endif
+
+    label = varargin{offset};
+    if (ischar (label) || iscellstr (label))
+      varargin(1:offset) = [];
+      if (ischar (label))
+	label = cellstr (label);
+      endif
+      n = numel (label);
+      nx = numel (x);
+      ny = numel (y);
+      nz = numel (z);
+    else
+      error ("text: expecting label to be a character string or cell array of character strings");
+    endif
+  else
+    x = y = z = 0;
+    nx = ny = nz = 1;
+    label = {""};
+    n = 1;
+  endif
+
+  if (rem (numel (varargin), 2) == 0)
+
+    if (nx == ny && nx == nz)
+      pos = [x(:), y(:), z(:)];
+      ca = gca ();
+      tmp = zeros (n, 1);
+      if (n == 1)
+	label = label{1};
+	for i = 1:nx
+	  tmp(i) = __go_text__ (ca, "string", label,
+				"position", pos(i,:),
+				varargin{:});
+	endfor
+	__request_drawnow__ ();
+      elseif (n == nx)
+	for i = 1:nx
+	  tmp(i) = __go_text__ (ca, "string", label{i},
+				"position", pos(i,:),
+				varargin{:});
+	endfor
+	__request_drawnow__ ();
+      else
+	error ("text: dimension mismatch for coordinates and label");
+      endif
+    else
+      error ("text: dimension mismatch for coordinates");
+    endif
+
+    if (nargout > 0)
+      h = tmp;
+    endif
+
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/title.m b/scripts/plot/title.m
new file mode 100644
index 0000000..c4eb09d
--- /dev/null
+++ b/scripts/plot/title.m
@@ -0,0 +1,40 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2003, 2004,
+##               2005, 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} title (@var{title})
+## @deftypefnx {Function File} {} title (@var{title}, @var{p1}, @var{v1}, @dots{})
+## Create a title object and return a handle to it.
+## @end deftypefn
+
+## Author: jwe
+
+function h = title (s, varargin)
+
+  if (rem (nargin, 2) == 1)
+    if (nargout > 0)
+      h = __axis_label__ ("title", s, varargin{:});
+    else
+      __axis_label__ ("title", s, varargin{:});
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/view.m b/scripts/plot/view.m
new file mode 100644
index 0000000..ad78595
--- /dev/null
+++ b/scripts/plot/view.m
@@ -0,0 +1,68 @@
+## Copyright (C) 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} view (@var{azimuth}, @var{elevation})
+## @deftypefnx {Function File} {} view (@var{dims})
+## @deftypefnx {Function File} {[@var{azimuth}, @var{elevation}] =} view ()
+## Set or get the viewpoint for the current axes.
+## @end deftypefn
+
+## Author: jwe
+
+function [azimuth, elevation] = view (x, y, z)
+
+  if (nargin < 4)
+    if (nargin == 0)
+      tmp = get (gca (), "view");
+      az = tmp(1);
+      el = tmp(2);
+    elseif (nargin == 1)
+      if (x == 2)
+	az = 0;
+	el = 90;
+      elseif (x == 3)
+	az = -37.5;
+	el = 30;
+      else
+	error ("view: expecting single argument to be 2 or 3");
+      endif
+    elseif (nargin == 2)
+      az = x;
+      el = y;
+    elseif (nargin == 3)
+      error ("view: view (x, y, z) not implemented");
+    endif
+
+    if (nargin > 0)
+      set (gca (), "view", [az, el]);
+    endif
+
+    if (nargout == 1)
+      error ("view: T = view () not implemented");
+    endif
+
+    if (nargout == 2)
+      azimuth = az;
+      elevation = el;
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/plot/waitforbuttonpress.m b/scripts/plot/waitforbuttonpress.m
new file mode 100644
index 0000000..e30e633
--- /dev/null
+++ b/scripts/plot/waitforbuttonpress.m
@@ -0,0 +1,47 @@
+## Copyright (C) 2004, 2006, 2008, 2009 Petr Mikulik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{b} =} waitforbuttonpress ()
+## Wait for button or mouse press.over a figure window.  The value of
+## @var{b} returns 0 if a mouse button was pressed or 1 is a key was
+## pressed.
+## @seealso{ginput}
+## @end deftypefn
+
+## The original version of this code bore the copyright
+## Author: Petr Mikulik
+## License: public domain
+
+function a = waitforbuttonpress ()
+
+  if (nargin != 0 || nargout > 1)
+    print_usage ();
+  endif
+
+  [x, y, k] = ginput (1);
+
+  if (nargout == 1)
+    if (k <= 5) 
+      a = 0;
+    else 
+      a = 1;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/plot/xlabel.m b/scripts/plot/xlabel.m
new file mode 100644
index 0000000..178f48f
--- /dev/null
+++ b/scripts/plot/xlabel.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+##               2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} xlabel (@var{string})
+## @deftypefnx {Function File} {} ylabel (@var{string})
+## @deftypefnx {Function File} {} zlabel (@var{string})
+## @deftypefnx {Function File} {} xlabel (@var{h}, @var{string})
+## Specify x, y, and z axis labels for the current figure.  If @var{h} is
+## specified then label the axis defined by @var{h}.
+## @seealso{plot, semilogx, semilogy, loglog, polar, mesh, contour,
+## bar, stairs, title}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = xlabel (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("xlabel", varargin{:});
+
+  if (rem (nargin, 2) != 1)
+    print_usage ();
+  endif
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    tmp = __axis_label__ ("xlabel", varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/xlim.m b/scripts/plot/xlim.m
new file mode 100644
index 0000000..c17d405
--- /dev/null
+++ b/scripts/plot/xlim.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{xl} =} xlim ()
+## @deftypefnx {Function File} {} xlim (@var{xl})
+## @deftypefnx {Function File} {@var{m} =} xlim ('mode')
+## @deftypefnx {Function File} {} xlim (@var{m})
+## @deftypefnx {Function File} {} xlim (@var{h}, @dots{})
+## Get or set the limits of the x-axis of the current plot.  Called without
+## arguments @code{xlim} returns the x-axis limits of the current plot.
+## If passed a two element vector @var{xl}, the limits of the x-axis are set
+## to this value.
+##
+## The current mode for calculation of the x-axis can be returned with a
+## call @code{xlim ('mode')}, and can be either 'auto' or 'manual'.  The 
+## current plotting mode can be set by passing either 'auto' or 'manual' 
+## as the argument.
+##
+## If passed an handle as the first argument, then operate on this handle
+## rather than the current axes handle.
+## @seealso{ylim, zlim, set, get, gca}
+## @end deftypefn
+
+function retval = xlim (varargin)
+  ret = __axes_limits__ ("xlim", varargin{:});
+
+  if (! isempty (ret))
+    retval = ret;
+  endif
+endfunction
diff --git a/scripts/plot/ylabel.m b/scripts/plot/ylabel.m
new file mode 100644
index 0000000..d8cca61
--- /dev/null
+++ b/scripts/plot/ylabel.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ylabel (@var{string})
+## @deftypefnx {Function File} {} ylabel (@var{h}, @var{string})
+## @seealso{xlabel}.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = ylabel (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("ylabel", varargin{:});
+
+  if (rem (nargin, 2) != 1)
+    print_usage ();
+  endif
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    tmp = __axis_label__ ("ylabel", varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/ylim.m b/scripts/plot/ylim.m
new file mode 100644
index 0000000..a65190f
--- /dev/null
+++ b/scripts/plot/ylim.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{xl} =} ylim ()
+## @deftypefnx {Function File} {} ylim (@var{xl})
+## @deftypefnx {Function File} {@var{m} =} ylim ('mode')
+## @deftypefnx {Function File} {} ylim (@var{m})
+## @deftypefnx {Function File} {} ylim (@var{h}, @dots{})
+## Get or set the limits of the y-axis of the current plot.  Called without
+## arguments @code{ylim} returns the y-axis limits of the current plot.
+## If passed a two element vector @var{xl}, the limits of the y-axis are set
+## to this value.
+##
+## The current mode for calculation of the y-axis can be returned with a
+## call @code{ylim ('mode')}, and can be either 'auto' or 'manual'.  The 
+## current plotting mode can be set by passing either 'auto' or 'manual' 
+## as the argument.
+##
+## If passed an handle as the first argument, then operate on this handle
+## rather than the current axes handle.
+## @seealso{xlim, zlim, set, get, gca}
+## @end deftypefn
+
+function retval = ylim (varargin)
+  ret = __axes_limits__ ("ylim", varargin{:});
+
+  if (! isempty (ret))
+    retval = ret;
+  endif
+endfunction
diff --git a/scripts/plot/zlabel.m b/scripts/plot/zlabel.m
new file mode 100644
index 0000000..b681fb8
--- /dev/null
+++ b/scripts/plot/zlabel.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} zlabel (@var{string})
+## @deftypefnx {Function File} {} zlabel (@var{h}, @var{string})
+## @seealso{xlabel}.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = zlabel (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("zlabel", varargin{:});
+
+  if (rem (nargin, 2) != 1)
+    print_usage ();
+  endif
+
+  oldh = gca ();
+  unwind_protect
+    axes (h);
+    tmp = __axis_label__ ("zlabel", varargin{:});
+  unwind_protect_cleanup
+    axes (oldh);
+  end_unwind_protect
+
+  if (nargout > 0)
+    retval = tmp;
+  endif
+
+endfunction
diff --git a/scripts/plot/zlim.m b/scripts/plot/zlim.m
new file mode 100644
index 0000000..83f1d3e
--- /dev/null
+++ b/scripts/plot/zlim.m
@@ -0,0 +1,46 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{xl} =} zlim ()
+## @deftypefnx {Function File} {} zlim (@var{xl})
+## @deftypefnx {Function File} {@var{m} =} zlim ('mode')
+## @deftypefnx {Function File} {} zlim (@var{m})
+## @deftypefnx {Function File} {} zlim (@var{h}, @dots{})
+## Get or set the limits of the z-axis of the current plot.  Called without
+## arguments @code{zlim} returns the z-axis limits of the current plot.
+## If passed a two element vector @var{xl}, the limits of the z-axis are set
+## to this value.
+##
+## The current mode for calculation of the z-axis can be returned with a
+## call @code{zlim ('mode')}, and can be either 'auto' or 'manual'.  The 
+## current plotting mode can be set by passing either 'auto' or 'manual' 
+## as the argument.
+##
+## If passed an handle as the first argument, then operate on this handle
+## rather than the current axes handle.
+## @seealso{xlim, ylim, set, get, gca}
+## @end deftypefn
+
+function retval = zlim (varargin)
+  ret = __axes_limits__ ("zlim", varargin{:});
+
+  if (! isempty (ret))
+    retval = ret;
+  endif
+endfunction
diff --git a/scripts/polynomial/Makefile.in b/scripts/polynomial/Makefile.in
new file mode 100644
index 0000000..d4de8d9
--- /dev/null
+++ b/scripts/polynomial/Makefile.in
@@ -0,0 +1,87 @@
+# Makefile for octave's scripts/polynomial directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008, 2009
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = polynomial
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = compan.m conv.m convn.m deconv.m mkpp.m mpoles.m \
+  pchip.m poly.m polyaffine.m polyder.m polyderiv.m polyfit.m \
+  polygcd.m polyint.m polyout.m polyreduce.m polyval.m \
+  polyvalm.m ppval.m residue.m roots.m spline.m unmkpp.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/polynomial
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/polynomial/compan.m b/scripts/polynomial/compan.m
new file mode 100644
index 0000000..ca65146
--- /dev/null
+++ b/scripts/polynomial/compan.m
@@ -0,0 +1,93 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} compan (@var{c})
+## Compute the companion matrix corresponding to polynomial coefficient
+## vector @var{c}.
+##
+## The companion matrix is
+## @tex
+## $$
+## A = \left[\matrix{
+##  -c_2/c_1 & -c_3/c_1 & \cdots & -c_N/c_1 & -c_{N+1}/c_1\cr
+##      1    &     0    & \cdots &     0    &         0   \cr
+##      0    &     1    & \cdots &     0    &         0   \cr
+##   \vdots  &   \vdots & \ddots &  \vdots  &      \vdots \cr
+##      0    &     0    & \cdots &     1    &         0}\right].
+## $$
+## @end tex
+## @ifnottex
+##
+## @c Set example in small font to prevent overfull line
+## @smallexample
+##      _                                                        _
+##     |  -c(2)/c(1)   -c(3)/c(1)  @dots{}  -c(N)/c(1)  -c(N+1)/c(1)  |
+##     |       1            0      @dots{}       0             0      |
+##     |       0            1      @dots{}       0             0      |
+## A = |       .            .   .            .             .      |
+##     |       .            .       .        .             .      |
+##     |       .            .           .    .             .      |
+##     |_      0            0      @dots{}       1             0     _|
+## @end smallexample
+## @end ifnottex
+##
+## The eigenvalues of the companion matrix are equal to the roots of the
+## polynomial.
+## @seealso{poly, roots, residue, conv, deconv, polyval, polyderiv,
+## polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function A = compan (c)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! isvector (c))
+    error ("compan: expecting a vector argument");
+  endif
+
+  n = length (c);
+
+  if (n == 1)
+    A = [];
+  else
+    A = diag (ones (n-2, 1), -1);
+    A(1,:) = -c(2:n) / c(1);
+  endif
+
+endfunction
+
+%!assert(all (all (compan ([1, 2, 3]) == [-2, -3; 1, 0])));
+
+%!assert(all (all (compan ([1; 2; 3]) == [-2, -3; 1, 0])));
+
+%!assert(isempty (compan (4)));
+
+%!assert(all (all (compan ([3, 2, 1]) == [-2/3, -1/3; 1, 0])));
+
+%!error compan ([1,2;3,4]);
+
+%!error compan ([]);
+
diff --git a/scripts/polynomial/conv.m b/scripts/polynomial/conv.m
new file mode 100644
index 0000000..85fcde7
--- /dev/null
+++ b/scripts/polynomial/conv.m
@@ -0,0 +1,121 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} conv (@var{a}, @var{b})
+## Convolve two vectors.
+##
+## @code{y = conv (a, b)} returns a vector of length equal to
+## @code{length (a) + length (b) - 1}.
+## If @var{a} and @var{b} are polynomial coefficient vectors, @code{conv}
+## returns the coefficients of the product polynomial.
+## @seealso{deconv, poly, roots, residue, polyval, polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function y = conv (a, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! (isvector (a) && isvector (b)))
+    error("conv: both arguments must be vectors");
+  endif
+
+  la = length (a);
+  lb = length (b);
+
+  ly = la + lb - 1;
+
+  ## Use the shortest vector as the coefficent vector to filter.
+  ## Preserve the row/column orientation of the longer input.
+  if (la < lb)
+    if (ly > lb)
+      if (size (b, 1) <= size (b, 2))
+        x = [b, (zeros (1, ly - lb))];
+      else
+        x = [b; (zeros (ly - lb, 1))];
+      endif
+    else
+      x = b;
+    endif
+    y = filter (a, 1, x);
+  else
+    if(ly > la)
+      if (size (a, 1) <= size (a, 2))
+        x = [a, (zeros (1, ly - la))];
+      else
+        x = [a; (zeros (ly - la, 1))];
+      endif
+    else
+      x = a;
+    endif
+    y = filter (b, 1, x);
+  endif
+
+endfunction
+
+%!assert(all (all (conv (ones (3, 1), ones (3, 1)) == [1; 2; 3; 2; 1])));
+
+%!assert(all (all (conv (ones (1, 3), ones (3, 1)) == [1, 2, 3, 2, 1])));
+
+%!assert(all (all (conv (3, [1, 2, 3]) == [3, 6, 9])));
+
+%!error conv ([1, 2; 3, 4], 3);
+
+%!assert(conv (2, 3),6);
+
+%!error conv (2, []);
+
+%!test
+%! a = 1:10;
+%! b = 1:3;
+%! c = conv (a, b);
+%! assert (size(c), [1, numel(a)+numel(b)-1])
+%!test
+%! a = (1:10).';
+%! b = 1:3;
+%! c = conv (a, b);
+%! assert (size(c), [numel(a)+numel(b)-1, 1])
+%!test
+%! a = 1:10;
+%! b = (1:3).';
+%! c = conv (a, b);
+%! assert (size(c), [1, numel(a)+numel(b)-1])
+
+%!test
+%! b = 1:10;
+%! a = 1:3;
+%! c = conv (a, b);
+%! assert (size(c), [1, numel(a)+numel(b)-1])
+%!test
+%! b = (1:10).';
+%! a = 1:3;
+%! c = conv (a, b);
+%! assert (size(c), [numel(a)+numel(b)-1, 1])
+%!test
+%! b = 1:10;
+%! a = (1:3).';
+%! c = conv (a, b);
+%! assert (size(c), [1, numel(a)+numel(b)-1])
+
diff --git a/scripts/polynomial/convn.m b/scripts/polynomial/convn.m
new file mode 100644
index 0000000..58e6633
--- /dev/null
+++ b/scripts/polynomial/convn.m
@@ -0,0 +1,128 @@
+## Copyright (C) 2008, 2009 Soren Hauberg
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{c} =} convn (@var{a}, @var{b}, @var{shape})
+## @math{N}-dimensional convolution of matrices @var{a} and @var{b}.
+##
+## The size of the output is determined by the @var{shape} argument.
+## This can be any of the following character strings:
+##
+## @table @asis
+## @item "full"
+## The full convolution result is returned.  The size out of the output is
+## @code{size (@var{a}) + size (@var{b})-1}.  This is the default behavior.
+## @item "same"
+## The central part of the convolution result is returned.  The size out of the
+## output is the same as @var{a}.
+## @item "valid"
+## The valid part of the convolution is returned.  The size of the result is
+## @code{max (size (@var{a}) - size (@var{b})+1, 0)}.
+## @end table
+##
+## @seealso{conv, conv2}
+## @end deftypefn
+
+function c = convn (a, b, shape = "full")
+
+  if (nargin < 2)
+    error ("convn: not enough input arguments");
+  endif
+
+  if (!ismatrix (a) || !ismatrix (b) || ndims (a) != ndims (b))
+    error ("convn: first and second arguments must be matrices of the same dimensionality");
+  endif
+
+  if (!ischar (shape))
+    error ("convn: third input argument must be a string");
+  endif
+
+  if (!any (strcmpi (shape, {"full", "same", "valid"})))
+    error ("convn: invalid shape argument: '%s'", shape);
+  endif
+  
+  ## Should we swap 'a' and 'b'?
+  ## FIXME -- should we also swap in any of the non-full cases?
+  if (numel (b) > numel (a) && strcmpi (shape, "full"))
+    tmp = a;
+    a = b;
+    b = tmp;
+  endif
+  
+  ## Pad A.
+  switch (lower (shape))
+    case "full"
+      a = pad (a, size (b)-1, size (b)-1);
+    case "same"
+      a = pad (a, floor ((size (b)-1)/2), ceil ((size (b)-1)/2));
+  endswitch
+  
+  ## Perform convolution.
+  c = __convn__ (a, b);
+
+endfunction
+
+## Helper function that performs the padding.
+function a = pad (a, left, right)
+  cl = class (a);
+  for dim = 1:ndims (a)
+    l = r = size (a);
+    l(dim) = left(dim);
+    r(dim) = right(dim);
+    a = cat (dim, zeros (l, cl), a, zeros (r, cl));
+  endfor
+endfunction
+
+%!test
+%! ## Compare to conv2
+%! a = rand (100); 
+%! b = ones (3);
+%! c2 = conv2 (a, b, "full");
+%! cn = convn (a, b, "full");
+%! assert (max (abs (cn(:)-c2(:))), 0, 100*eps);
+
+%!test
+%! ## Compare to conv2
+%! a = rand (100); 
+%! b = ones (3);
+%! c2 = conv2 (a, b, "same");
+%! cn = convn (a, b, "same");
+%! assert (max (abs (cn(:)-c2(:))), 0, 100*eps);
+
+%!test
+%! ## Compare to conv2
+%! a = rand (100); 
+%! b = ones (3);
+%! c2 = conv2 (a, b, "valid");
+%! cn = convn (a, b, "valid");
+%! assert (max (abs (cn(:)-c2(:))), 0, 100*eps);
+
+%!test
+%! ## Real data
+%! a = ones (10,10,10); 
+%! b = ones (3,3,3);
+%! c = convn (a, b, "valid");
+%! assert (all (c == numel (b)));
+
+%!test
+%! ## Complex data
+%! a = complex(ones (10,10,10), ones(10,10,10));
+%! b = complex(ones (3,3,3), ones(3,3,3));
+%! c = convn (a, b, "valid");
+%! assert (all (c == 2*i*numel (b)));
+
diff --git a/scripts/polynomial/deconv.m b/scripts/polynomial/deconv.m
new file mode 100644
index 0000000..fc8292c
--- /dev/null
+++ b/scripts/polynomial/deconv.m
@@ -0,0 +1,106 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} deconv (@var{y}, @var{a})
+## Deconvolve two vectors.
+##
+## @code{[b, r] = deconv (y, a)} solves for @var{b} and @var{r} such that
+## @code{y = conv (a, b) + r}.
+##
+## If @var{y} and @var{a} are polynomial coefficient vectors, @var{b} will
+## contain the coefficients of the polynomial quotient and @var{r} will be
+## a remainder polynomial of lowest order.
+## @seealso{conv, poly, roots, residue, polyval, polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function [b, r] = deconv (y, a)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! (isvector (y) && isvector (a)))
+    error("conv: both arguments must be vectors");
+  endif
+
+  la = length (a);
+  ly = length (y);
+
+  lb = ly - la + 1;
+
+  ## Ensure A is oriented as Y.
+  if (diff (size (y)(1:2)) * diff (size (a)(1:2)) < 0)
+    a = permute (a, [2, 1]);
+  endif
+
+  if (ly > la)
+    b = filter (y, a, [1, (zeros (1, ly - la))]);
+  elseif (ly == la)
+    b = filter (y, a, 1);
+  else
+    b = 0;
+  endif
+
+  lc = la + length (b) - 1;
+  if (ly == lc)
+    r = y - conv (a, b);
+  else
+    ## Respect the orientation of Y"
+    if (size (y, 1) <= size (y, 2))
+      r = [(zeros (1, lc - ly)), y] - conv (a, b);
+    else
+      r = [(zeros (lc - ly, 1)); y] - conv (a, b);
+    endif
+    if (ly < la)
+      ## Trim the remainder is equal to the length of Y.
+      r = r(end-(length(y)-1):end);
+    endif
+  endif
+
+endfunction
+
+%!test
+%! [b, r] = deconv ([3, 6, 9, 9], [1, 2, 3]);
+%! assert(all (all (b == [3, 0])) && all (all (r == [0, 0, 0, 9])));
+
+%!test
+%! [b, r] = deconv ([3, 6], [1, 2, 3]);
+%! assert(b == 0 && all (all (r == [3, 6])));
+
+%!test
+%! [b, r] = deconv ([3, 6], [1; 2; 3]);
+%! assert(b == 0 && all (all (r == [3, 6])));
+
+%!test
+%! [b,r] = deconv ([3; 6], [1; 2; 3]);
+%! assert (b == 0 && all (all (r == [3; 6])))
+
+%!test
+%! [b, r] = deconv ([3; 6], [1, 2, 3]);
+%! assert (b == 0 && all (all (r == [3; 6])))
+
+%!error [b, r] = deconv ([3, 6], [1, 2; 3, 4]);
+
+%!error [b, r] = deconv ([3, 6; 1, 2], [1, 2, 3]);
+
diff --git a/scripts/polynomial/mkpp.m b/scripts/polynomial/mkpp.m
new file mode 100644
index 0000000..e831918
--- /dev/null
+++ b/scripts/polynomial/mkpp.m
@@ -0,0 +1,67 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{pp} =} mkpp (@var{x}, @var{p})
+## @deftypefnx {Function File} {@var{pp} =} mkpp (@var{x}, @var{p}, @var{d})
+## 
+## Construct a piece-wise polynomial structure from sample points
+## @var{x} and coefficients @var{p}.  The i-th row of @var{p},
+## @code{@var{p} (@var{i},:)}, contains the coefficients for the polynomial
+## over the @var{i}-th interval, ordered from highest to 
+## lowest.  There must be one row for each interval in @var{x}, so 
+## @code{rows (@var{p}) == length (@var{x}) - 1}.  
+##
+## You can concatenate multiple polynomials of the same order over the 
+## same set of intervals using @code{@var{p} = [ @var{p1}; @var{p2}; 
+## @dots{}; @var{pd} ]}.  In this case, @code{rows (@var{p}) == @var{d} 
+## * (length (@var{x}) - 1)}.
+##
+## @var{d} specifies the shape of the matrix @var{p} for all except the
+## last dimension.  If @var{d} is not specified it will be computed as
+## @code{round (rows (@var{p}) / (length (@var{x}) - 1))} instead.
+##
+## @seealso{unmkpp, ppval, spline}
+## @end deftypefn
+
+function pp = mkpp (x, P, d)
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+  pp.x = x(:);
+  pp.P = P;
+  pp.n = length (x) - 1;
+  pp.k = columns (P);
+  if (nargin < 3)
+    d = round (rows (P) / pp.n); 
+  endif
+  pp.d = d;
+  if (pp.n * prod (d) != rows (P))
+    error ("mkpp: num intervals in x doesn't match num polynomials in P");
+  endif
+endfunction
+
+%!demo # linear interpolation
+%! x=linspace(0,pi,5)'; 
+%! t=[sin(x),cos(x)];
+%! m=diff(t)./(x(2)-x(1)); 
+%! b=t(1:4,:);
+%! pp = mkpp(x, [m(:),b(:)]);
+%! xi=linspace(0,pi,50);
+%! plot(x,t,"x",xi,ppval(pp,xi));
+%! legend("control","interp");
diff --git a/scripts/polynomial/mpoles.m b/scripts/polynomial/mpoles.m
new file mode 100644
index 0000000..67d2793
--- /dev/null
+++ b/scripts/polynomial/mpoles.m
@@ -0,0 +1,121 @@
+## Copyright (C) 2007, 2008, 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p})
+## @deftypefnx {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p}, @var{tol})
+## @deftypefnx {Function File} {[@var{multp}, @var{indx}] =} mpoles (@var{p}, @var{tol}, @var{reorder})
+## Identify unique poles in @var{p} and associates their multiplicity,
+## ordering them from largest to smallest.
+## 
+## If the relative difference of the poles is less than @var{tol}, then
+## they are considered to be multiples.  The default value for @var{tol}
+## is 0.001.
+##
+## If the optional parameter @var{reorder} is zero, poles are not sorted.
+##
+## The value @var{multp} is a vector specifying the multiplicity of the
+## poles.  @var{multp}(:) refers to multiplicity of @var{p}(@var{indx}(:)).
+##
+## For example,
+##
+## @example
+## @group
+## p = [2 3 1 1 2];
+## [m, n] = mpoles(p);
+##   @result{} m = [1; 1; 2; 1; 2]
+##   @result{} n = [2; 5; 1; 4; 3]
+##   @result{} p(n) = [3, 2, 2, 1, 1]
+## @end group
+## @end example
+##
+## @seealso{poly, roots, conv, deconv, polyval, polyderiv, polyinteg, residue}
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Created: Sept 30, 2007
+
+function [multp, indx] = mpoles (p, tol, reorder)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+   if (nargin < 2 || isempty (tol))
+     tol = 0.001;
+   endif
+
+   if (nargin < 3 || isempty (reorder))
+     reorder = true;
+   endif
+
+  Np = numel (p);
+
+  ## Force the poles to be a column vector.
+
+  p = p(:);
+
+  ## Sort the poles according to their magnitidues, largest first.
+
+  if (reorder)
+    ## Sort with smallest magnitude first.
+    [p, ordr] = sort (p);
+    ## Reverse order, largest maginitude first.
+    n = Np:-1:1;
+    p = p(n);
+    ordr = ordr(n);
+  else
+    ordr = 1:Np;
+  endif
+
+  ## Find pole multiplicty by comparing the relative differnce in the
+  ## poles.
+
+  multp = zeros (Np, 1);
+  indx = [];
+  n = find (multp == 0, 1);
+  while (n)
+    dp = abs (p-p(n));
+    if (p(n) == 0.0)
+      if (any (abs (p) > 0 & isfinite (p)))
+        p0 = mean (abs (p(abs (p) > 0 & isfinite (p))));
+      else
+        p0 = 1;
+      endif
+    else
+      p0 = abs (p(n));
+    endif
+    k = find (dp < tol * p0);
+    ## Poles can only be members of one multiplicity group.
+    if (numel (indx))
+      k = k(! ismember (k, indx));
+    endif
+    m = 1:numel (k);
+    multp(k) = m;
+    indx = [indx; k];
+    n = find (multp == 0, 1);
+  endwhile
+  multp = multp(indx);
+  indx = ordr(indx);
+
+endfunction
+
+%!test
+%! [mp, n] = mpoles ([0 0], 0.01);
+%! assert (mp, [1; 2])
+
diff --git a/scripts/polynomial/pchip.m b/scripts/polynomial/pchip.m
new file mode 100644
index 0000000..757e0cf
--- /dev/null
+++ b/scripts/polynomial/pchip.m
@@ -0,0 +1,151 @@
+## Copyright (C) 2001, 2002, 2006, 2007, 2008, 2009 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{pp} =} pchip (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{yi} =} pchip (@var{x}, @var{y}, @var{xi})
+##
+## Piecewise Cubic Hermite interpolating polynomial.  Called with two
+## arguments, the piece-wise polynomial @var{pp} is returned, that may
+## later be used with @code{ppval} to evaluate the polynomial at
+## specific points.
+##
+## The variable @var{x} must be a strictly monotonic vector (either
+## increasing or decreasing).  While @var{y} can be either a vector or
+## array.  In the case where @var{y} is a vector, it must have a length
+## of @var{n}.  If @var{y} is an array, then the size of @var{y} must
+## have the form
+## @tex
+## $$[s_1, s_2, \cdots, s_k, n]$$
+## @end tex
+## @ifnottex
+## @code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]}
+## @end ifnottex
+## The array is then reshaped internally to a matrix where the leading
+## dimension is given by 
+## @tex
+## $$s_1 s_2 \cdots s_k$$
+## @end tex
+## @ifnottex
+## @code{@var{s1} * @var{s2} * @dots{} * @var{sk}}
+## @end ifnottex
+## and each row in this matrix is then treated separately.  Note that this
+## is exactly the opposite treatment than @code{interp1} and is done
+## for compatibility.
+##
+## Called with a third input argument, @code{pchip} evaluates the 
+## piece-wise polynomial at the points @var{xi}.  There is an equivalence
+## between @code{ppval (pchip (@var{x}, @var{y}), @var{xi})} and
+## @code{pchip (@var{x}, @var{y}, @var{xi})}.
+##
+## @seealso{spline, ppval, mkpp, unmkpp}
+## @end deftypefn
+
+## Author:  Kai Habel <kai.habel at gmx.de>
+## Date: 9. mar 2001
+##
+## S_k = a_k + b_k*x + c_k*x^2 + d_k*x^3; (spline polynom)
+##
+## 4 conditions:
+## S_k(x_k) = y_k;
+## S_k(x_k+1) = y_k+1;
+## S_k'(x_k) = y_k';
+## S_k'(x_k+1) = y_k+1';
+
+function ret = pchip (x, y, xi)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  x = x(:);
+  n = length (x);
+
+  ## Check the size and shape of y
+  ndy = ndims (y);
+  szy = size (y);
+  if (ndy == 2 && (szy(1) == 1 || szy(2) == 1))
+    if (szy(1) == 1)
+      y = y';
+    else
+      szy = fliplr (szy);
+    endif
+  else
+    y = reshape (y, [prod(szy(1:end-1)), szy(end)])';
+  endif
+
+  h = diff (x);
+  if (all (h < 0))
+    x = flipud (x);
+    h = diff (x);
+    y = flipud (y);
+  elseif (any (h <= 0))
+    error("pchip: x must be strictly monotonic");
+  endif
+
+  if (rows (y) != n)
+    error("pchip: size of x and y must match");
+  endif
+
+  [ry, cy] = size (y);
+  if (cy > 1)
+    h = kron (diff (x), ones (1, cy));
+  endif
+  
+  dy = diff (y) ./ h;
+
+  a = y;
+  b = __pchip_deriv__ (x, y);
+  c = - (b(2:n, :) + 2 * b(1:n - 1, :)) ./ h + 3 * diff (a) ./ h .^ 2;
+  d = (b(1:n - 1, :) + b(2:n, :)) ./ h.^2 - 2 * diff (a) ./ h.^3;
+
+  d = d(1:n - 1, :); c = c(1:n - 1, :);
+  b = b(1:n - 1, :); a = a(1:n - 1, :);
+  coeffs = [d(:), c(:), b(:), a(:)];
+  pp = mkpp (x, coeffs, szy(1:end-1));
+
+  if (nargin == 2)
+    ret = pp;
+  else
+    ret = ppval (pp, xi);
+  endif
+
+endfunction
+
+%!demo
+%! x = 0:8; 
+%! y = [1, 1, 1, 1, 0.5, 0, 0, 0, 0];
+%! xi = 0:0.01:8; 
+%! yspline = spline(x,y,xi);
+%! ypchip = pchip(x,y,xi);
+%! title("pchip and spline fit to discontinuous function");
+%! plot(xi,yspline,xi,ypchip,"-",x,y,"+");
+%! legend ("spline","pchip","data");
+%! %-------------------------------------------------------------------
+%! % confirm that pchip agreed better to discontinuous data than spline
+
+%!shared x,y
+%! x = 0:8; 
+%! y = [1, 1, 1, 1, 0.5, 0, 0, 0, 0];
+%!assert (pchip(x,y,x), y);
+%!assert (pchip(x,y,x'), y');
+%!assert (pchip(x',y',x'), y');
+%!assert (pchip(x',y',x), y);
+%!assert (isempty(pchip(x',y',[])));
+%!assert (isempty(pchip(x,y,[])));
+%!assert (pchip(x,[y;y],x), [pchip(x,y,x);pchip(x,y,x)])
diff --git a/scripts/polynomial/poly.m b/scripts/polynomial/poly.m
new file mode 100644
index 0000000..dcff0a5
--- /dev/null
+++ b/scripts/polynomial/poly.m
@@ -0,0 +1,88 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poly (@var{a})
+## If @var{a} is a square @math{N}-by- at math{N} matrix, @code{poly (@var{a})}
+## is the row vector of the coefficients of @code{det (z * eye (N) - a)},
+## the characteristic polynomial of @var{a}.  As an example we can use
+## this to find the eigenvalues of @var{a} as the roots of @code{poly (@var{a})}.
+## @example
+## @group
+## roots(poly(eye(3)))
+## @result{} 1.00000 + 0.00000i
+## @result{} 1.00000 - 0.00000i
+## @result{} 1.00000 + 0.00000i
+## @end group
+## @end example
+## In real-life examples you should, however, use the @code{eig} function
+## for computing eigenvalues.
+##
+## If @var{x} is a vector, @code{poly (@var{x})} is a vector of coefficients
+## of the polynomial whose roots are the elements of @var{x}.  That is,
+## of @var{c} is a polynomial, then the elements of 
+## @code{@var{d} = roots (poly (@var{c}))} are contained in @var{c}.
+## The vectors @var{c} and @var{d} are, however, not equal due to sorting
+## and numerical errors.
+## @seealso{eig, roots}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 24 December 1993
+## Adapted-By: jwe
+
+function y = poly (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  m = min (size (x));
+  n = max (size (x));
+  if (m == 0)
+    y = 1;
+    return;
+  elseif (m == 1)
+    v = x;
+  elseif (m == n)
+    v = eig (x);
+  else
+    print_usage ();
+  endif
+
+  y = zeros (1, n+1);
+  y(1) = 1;
+  for j = 1:n;
+    y(2:(j+1)) = y(2:(j+1)) - v(j) .* y(1:j);
+  endfor
+
+  if (all (all (imag (x) == 0)))
+    y = real (y);
+  endif
+
+endfunction
+
+%!assert(all (all (poly ([1, 2, 3]) == [1, -6, 11, -6])));
+
+%!assert(all (all (abs (poly ([1, 2; 3, 4]) - [1, -5, -2]) < sqrt (eps))));
+
+%!error poly ([1, 2, 3; 4, 5, 6]);
+
+%!assert(poly ([]),1);
+
diff --git a/scripts/polynomial/polyaffine.m b/scripts/polynomial/polyaffine.m
new file mode 100644
index 0000000..414544e
--- /dev/null
+++ b/scripts/polynomial/polyaffine.m
@@ -0,0 +1,89 @@
+## Copyright (C) 2009  Tony Richardson, Jaroslav Hajek
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyaffine (@var{f}, @var{mu})
+## Return the coefficients of the polynomial whose coefficients are given by
+## vector @var{f} after an affine tranformation. If @var{f} is the vector
+## representing the polynomial f(x), then @var{g} = polytrans (@var{f},
+## @var{mu}) is the vector representing 
+## @example
+## g(x) = f((x- at var{mu}(1))/@var{mu}(2)).
+## @end example
+## 
+## @seealso{polyval}
+## @end deftypefn
+
+
+function g = polyaffine (f, mu)
+
+   if (nargin != 2)
+      print_usage ();
+   endif
+
+   if (! isvector (f))
+      error ("polyaffine: first argument must be a vector.");
+   endif
+
+   if (! isvector (mu) || length (mu) != 2)
+      error ("polyaffine: second argument must be a two-element vector.");
+   endif
+
+   lf = length (f);
+
+   ## Ensure that f is a row vector
+   if (rows (f) > 1)
+      f = f.';
+   endif
+
+   g = f;
+
+   ## Scale.
+   if (mu(2) != 1)
+     g = g ./ (mu(2) .^ (lf-1:-1:0));
+   endif
+
+   ## Translate.
+   if (mu(1) != 0)
+     w = (-mu(1)) .^ (0:lf-1);
+     ii = lf:-1:1;
+     g = g(ii) * (toeplitz (w) .* pascal (lf, -1));
+     g = g(ii);
+   endif
+
+endfunction
+
+%!test
+%! f = [1/5 4/5 -7/5 -2];
+%!
+%! mu = [1, 1.2];
+%!
+%! g = polyaffine (f, mu);
+%!
+%! x = linspace (-4, 4, 100);
+%!
+%! assert (polyval(f, x, [], mu), polyval (g, x), 1e-10);
+%!
+%!demo
+%! f = [1/5 4/5 -7/5 -2];
+%!
+%! g = polyaffine (f, [1, 1.2]);
+%!
+%! x = linspace (-4, 4, 100);
+%!
+%! plot(x, polyval (f, x), x, polyval (g, x));
+%!
+%! axis ([-4 4 -3 5]);
+%! grid ("on");
diff --git a/scripts/polynomial/polyder.m b/scripts/polynomial/polyder.m
new file mode 100644
index 0000000..bb92d4a
--- /dev/null
+++ b/scripts/polynomial/polyder.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 2000, 2005, 2006, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyder (@var{c})
+## @deftypefnx {Function File} {[@var{q}] =} polyder (@var{b}, @var{a})
+## @deftypefnx {Function File} {[@var{q}, @var{r}] =} polyder (@var{b}, @var{a})
+## See polyderiv.
+## @end deftypefn
+
+## Author: John W. Eaton
+
+function [q, r] = polyder (p, a)
+
+  if (nargin == 1)
+    q = polyderiv (p);
+  elseif (nargin == 2)
+    if (nargout == 2)
+      [q, r] = polyderiv (p, a);
+    else
+      q = polyderiv (p, a);
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/polynomial/polyderiv.m b/scripts/polynomial/polyderiv.m
new file mode 100644
index 0000000..91b6f52
--- /dev/null
+++ b/scripts/polynomial/polyderiv.m
@@ -0,0 +1,101 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyderiv (@var{c})
+## @deftypefnx {Function File} {[@var{q}] =} polyderiv (@var{b}, @var{a})
+## @deftypefnx {Function File} {[@var{q}, @var{r}] =} polyderiv (@var{b}, @var{a})
+## Return the coefficients of the derivative of the polynomial whose
+## coefficients are given by vector @var{c}.  If a pair of polynomials
+## is given @var{b} and @var{a}, the derivative of the product is
+## returned in @var{q}, or the quotient numerator in @var{q} and the
+## quotient denominator in @var{r}.
+## @seealso{poly, polyinteg, polyreduce, roots, conv, deconv, residue,
+## filter, polygcd, polyval, polyvalm}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function [q, r] = polyderiv (p, a)
+
+  if (nargin == 1 || nargin == 2)
+    if (! isvector (p))
+      error ("polyderiv: argument must be a vector");
+    endif
+    if (nargin == 2)
+      if (! isvector (a))
+	error ("polyderiv: argument must be a vector");
+      endif
+      if (nargout == 1) 
+	## derivative of p*a returns a single polynomial
+	q = polyderiv (conv (p, a));
+      else
+	## derivative of p/a returns numerator and denominator
+	r = conv (a, a);
+	if (numel (p) == 1)
+	  q = -p * polyderiv (a);
+	elseif (numel (a) == 1)
+	  q = a * polyderiv (p);
+	else
+	  q = conv (polyderiv (p), a) - conv (p, polyderiv (a));
+	  q = polyreduce (q);
+	endif
+
+	## remove common factors from numerator and denominator
+	x = polygcd (q, r);
+	if (length(x) != 1)
+	  q = deconv (q, x);
+	  r = deconv (r, x);
+	endif
+
+	## move all the gain into the numerator
+	q = q/r(1);
+	r = r/r(1);
+      endif
+    else
+      lp = numel (p);
+      if (lp == 1)
+	q = 0;
+	return;
+      elseif (lp == 0)
+	q = [];
+	return;
+      endif
+
+      ## Force P to be a row vector.
+      p = p(:).';
+
+      q = p(1:(lp-1)) .* [(lp-1):-1:1];
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(all (all (polyderiv ([1, 2, 3]) == [2, 2])));
+
+%!assert(polyderiv (13) == 0);
+
+%!error polyderiv ([]);
+
+%!error polyderiv ([1, 2; 3, 4]);
+
diff --git a/scripts/polynomial/polyfit.m b/scripts/polynomial/polyfit.m
new file mode 100644
index 0000000..51e2f85
--- /dev/null
+++ b/scripts/polynomial/polyfit.m
@@ -0,0 +1,171 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{p}, @var{s}, @var{mu}] =} polyfit (@var{x}, @var{y}, @var{n})
+## Return the coefficients of a polynomial @var{p}(@var{x}) of degree
+## @var{n} that minimizes the least-squares-error of the fit.
+##
+## The polynomial coefficients are returned in a row vector.
+##
+## The second output is a structure containing the following fields:
+##
+## @table @samp
+## @item R
+## Triangular factor R from the QR decomposition.
+## @item X
+## The Vandermonde matrix used to compute the polynomial coefficients.
+## @item df
+## The degrees of freedom.
+## @item normr
+## The norm of the residuals.
+## @item yf
+## The values of the polynomial for each value of @var{x}.
+## @end table
+##
+## The second output may be used by @code{polyval} to calculate the 
+## statistical error limits of the predicted values.
+##
+## When the third output, @var{mu}, is present the 
+## coefficients, @var{p}, are associated with a polynomial in
+## @var{xhat} = (@var{x}- at var{mu}(1))/@var{mu}(2).
+## Where @var{mu}(1) = mean (@var{x}), and @var{mu}(2) = std (@var{x}).
+## This linear transformation of @var{x} improves the numerical
+## stability of the fit.
+## @seealso{polyval, residue}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 13 December 1994
+## Adapted-By: jwe
+
+function [p, s, mu] = polyfit (x, y, n)
+
+  if (nargin < 3 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargout > 2)
+    ## Normalized the x values.
+    mu = [mean(x), std(x)];
+    x = (x - mu(1)) / mu(2);
+  endif
+
+  if (! size_equal (x, y))
+    error ("polyfit: x and y must be vectors of the same size");
+  endif
+
+  if (! (isscalar (n) && n >= 0 && ! isinf (n) && n == round (n)))
+    error ("polyfit: n must be a nonnegative integer");
+  endif
+
+  y_is_row_vector = (rows (y) == 1);
+
+  ## Reshape x & y into column vectors.
+  l = numel (x);
+  x = x(:);
+  y = y(:);
+
+  ## Construct the Vandermonde matrix.
+  v = vander (x, n+1);
+
+  ## Solve by QR decomposition.
+  [q, r, k] = qr (v, 0);
+  p = r \ (q' * y);
+  p(k) = p;
+
+  if (nargout > 1)
+    yf = v*p;
+
+    if (y_is_row_vector)
+      s.yf = yf.';
+    else
+      s.yf = yf;
+    endif
+
+    s.R = r;
+    s.X = v;
+    s.df = l - n - 1;
+    s.normr = norm (yf - y);
+  endif
+
+  ## Return a row vector.
+  p = p.';
+
+endfunction
+
+%!test
+%! x = [-2, -1, 0, 1, 2];
+%! assert(all (all (abs (polyfit (x, x.^2+x+1, 2) - [1, 1, 1]) < sqrt (eps))));
+
+%!error(polyfit ([1, 2; 3, 4], [1, 2, 3, 4], 2))
+
+%!test
+%! x = [-2, -1, 0, 1, 2];
+%! assert(all (all (abs (polyfit (x, x.^2+x+1, 3) - [0, 1, 1, 1]) < sqrt (eps))));
+
+%!test
+%! x = [-2, -1, 0, 1, 2];
+%! fail("polyfit (x, x.^2+x+1)");
+
+%!test
+%! x = [-2, -1, 0, 1, 2];
+%! fail("polyfit (x, x.^2+x+1, [])");
+
+## Test difficult case where scaling is really needed. This example
+## demonstrates the rather poor result which occurs when the dependent
+## variable is not normalized properly.
+## Also check the usage of 2nd & 3rd output arguments.
+%!test
+%! x = [ -1196.4, -1195.2, -1194, -1192.8, -1191.6, -1190.4, -1189.2, -1188, \
+%!       -1186.8, -1185.6, -1184.4, -1183.2, -1182];
+%! y = [ 315571.7086, 315575.9618, 315579.4195, 315582.6206, 315585.4966,    \
+%!       315588.3172, 315590.9326, 315593.5934, 315596.0455, 315598.4201,    \
+%!       315600.7143, 315602.9508, 315605.1765 ];
+%! [p1, s1] = polyfit (x, y, 10);
+%! [p2, s2, mu] = polyfit (x, y, 10);
+%! assert (s2.normr < s1.normr)
+
+%!test
+%! x = 1:4;
+%! p0 = [1i, 0, 2i, 4];
+%! y0 = polyval (p0, x);
+%! p = polyfit (x, y0, numel(p0)-1);
+%! assert (p, p0, 1000*eps)
+
+%!test
+%! x = 1000 + (-5:5);
+%! xn = (x - mean (x)) / std (x);
+%! pn = ones (1,5);
+%! y = polyval (pn, xn);
+%! [p, s, mu] = polyfit (x, y, numel(pn)-1);
+%! [p2, s2] = polyfit (x, y, numel(pn)-1);
+%! assert (p, pn, s.normr)
+%! assert (s.yf, y, s.normr)
+%! assert (mu, [mean(x), std(x)])
+%! assert (s.normr/s2.normr < sqrt(eps))
+
+%!test
+%! x = [1, 2, 3; 4, 5, 6];
+%! y = [0, 0, 1; 1, 0, 0];
+%! p = polyfit (x, y, 5);
+%! expected = [0, 1, -14, 65, -112, 60]/12;
+%! assert (p, expected, sqrt(eps))
+
+
diff --git a/scripts/polynomial/polygcd.m b/scripts/polynomial/polygcd.m
new file mode 100644
index 0000000..f917b0e
--- /dev/null
+++ b/scripts/polynomial/polygcd.m
@@ -0,0 +1,83 @@
+## Copyright (C) 2000, 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{q} =} polygcd (@var{b}, @var{a}, @var{tol})
+##
+## Find greatest common divisor of two polynomials.  This is equivalent
+## to the polynomial found by multiplying together all the common roots.
+## Together with deconv, you can reduce a ratio of two polynomials.
+## Tolerance defaults to 
+## @example 
+## sqrt(eps).
+## @end example
+##  Note that this is an unstable
+## algorithm, so don't try it on large polynomials.
+##
+## Example
+## @example
+## @group
+## polygcd (poly(1:8), poly(3:12)) - poly(3:8)
+## @result{} [ 0, 0, 0, 0, 0, 0, 0 ]
+## deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))) ...
+##   - poly(1:2)
+## @result{} [ 0, 0, 0 ]
+## @end group
+## @end example
+## @seealso{poly, polyinteg, polyderiv, polyreduce, roots, conv, deconv,
+## residue, filter, polyval, polyvalm}
+## @end deftypefn
+
+function x = polygcd (b, a, tol)
+
+  if (nargin == 2 || nargin == 3)
+    if (nargin == 2)
+      if (isa (a, "single") || isa (b, "single"))
+	tol = sqrt (eps ("single"));
+      else
+	tol = sqrt (eps);
+      endif
+    endif
+    if (length (a) == 1 || length (b) == 1)
+      if (a == 0)
+	x = b;
+      elseif (b == 0)
+	x = a;
+      else
+	x = 1;
+      endif
+    else
+      a /= a(1);
+      while (1)
+	[d, r] = deconv (b, a);
+	nz = find (abs (r) > tol);
+	if (isempty (nz))
+	  x = a;
+	  break;
+	else
+	  r = r(nz(1):length(r));
+	endif
+	b = a;
+	a = r / r(1);
+      endwhile
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/polynomial/polyint.m b/scripts/polynomial/polyint.m
new file mode 100644
index 0000000..9bec7e2
--- /dev/null
+++ b/scripts/polynomial/polyint.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1996, 1997, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyint (@var{c}, @var{k})
+## Return the coefficients of the integral of the polynomial whose
+## coefficients are represented by the vector @var{c}.  The variable
+## @var{k} is the constant of integration, which by default is set to zero.
+## @seealso{poly, polyderiv, polyreduce, roots, conv, deconv, residue,
+## filter, polyval, polyvalm}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function p = polyint (p, k)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    k = 0;
+  elseif (! isscalar (k))
+    error ("polyint: the constant of integration must be a scalar");
+  endif
+
+  if (! (isvector (p) || isempty (p)))
+    error ("argument must be a vector");
+  endif
+
+  lp = length (p);
+
+  if (lp == 0)
+    p = [];
+    return;
+  endif
+
+  if (rows (p) > 1)
+    ## Convert to column vector
+    p = p.';
+  endif
+
+  p = [(p ./ [lp:-1:1]), k];
+
+endfunction
diff --git a/scripts/polynomial/polyout.m b/scripts/polynomial/polyout.m
new file mode 100644
index 0000000..6b58bd1
--- /dev/null
+++ b/scripts/polynomial/polyout.m
@@ -0,0 +1,96 @@
+## Copyright (C) 1995, 1998, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+##               Auburn University.  All rights reserved.
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyout (@var{c}, @var{x})
+## Write formatted polynomial
+## @tex
+## $$ c(x) = c_1 x^n + \ldots + c_n x + c_{n+1} $$
+## @end tex
+## @ifnottex
+## @example
+##    c(x) = c(1) * x^n + @dots{} + c(n) x + c(n+1)
+## @end example
+## @end ifnottex
+##  and return it as a string or write it to the screen (if
+##  @var{nargout} is zero).
+##  @var{x} defaults to the string @code{"s"}.
+## @seealso{polyval, polyvalm, poly, roots, conv, deconv, residue,
+## filter, polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: A. S. Hodel <a.s.hodel at eng.auburn.edu>
+## Created: May 1995
+## Nov 1998: Correctly handles complex coefficients
+
+function y = polyout (c, x)
+
+  if (nargin < 1) || (nargin > 2) || (nargout < 0) || (nargout > 1)
+    print_usage ();
+  endif
+
+  if (! isvector (c))
+    error ("polyout: first argument must be a vector");
+  endif
+
+  if (nargin == 1)
+    x = "s";
+  elseif (! ischar (x))
+    error ("polyout: second argument must be a string");
+  endif
+
+  n = length (c);
+  if(n > 0)
+    n1 = n+1;
+
+    tmp = coeff (c(1));
+    for ii = 2:n
+      if (real (c(ii)) < 0)
+	ns = " - ";
+	c(ii) = -c(ii);
+      else
+        ns = " + ";
+      endif
+
+      tmp = sprintf ("%s*%s^%d%s%s", tmp, x, n1-ii, ns, coeff (c(ii)));
+
+    endfor
+  else
+    tmp = " ";
+  endif
+
+  if(nargout == 0)
+    disp (tmp)
+  else
+    y = tmp;
+  endif
+
+endfunction
+
+function str = coeff (c)
+  if (imag (c))
+    if (real (c))
+      str = sprintf ("(%s)", num2str (c, 5));
+    else
+      str = num2str (c, 5);
+    endif
+  else
+    str = num2str (c, 5);
+  endif
+endfunction
diff --git a/scripts/polynomial/polyreduce.m b/scripts/polynomial/polyreduce.m
new file mode 100644
index 0000000..7fceb9e
--- /dev/null
+++ b/scripts/polynomial/polyreduce.m
@@ -0,0 +1,69 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyreduce (@var{c})
+## Reduces a polynomial coefficient vector to a minimum number of terms by
+## stripping off any leading zeros.
+## @seealso{poly, roots, conv, deconv, residue, filter, polyval,
+## polyvalm, polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function p = polyreduce (p)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isvector (p) || isempty (p)))
+    error ("polyreduce: argument must be a vector");
+  endif
+
+  if (! isempty (p))
+
+    index = find (p != 0);
+
+    if (isempty (index))
+      
+      p = 0;
+    
+    else
+
+      p = p (index (1):length (p));
+
+    endif
+
+  endif
+
+endfunction
+
+%!assert(all (all (polyreduce ([0, 0, 1, 2, 3]) == [1, 2, 3])));
+
+%!assert(all (all (polyreduce ([1, 2, 3, 0, 0]) == [1, 2, 3, 0, 0])));
+
+%!assert(all (all (polyreduce ([1, 0, 3]) == [1, 0, 3])));
+
+%!assert(isempty (polyreduce ([])));
+
+%!error polyreduce ([1, 2; 3, 4]);
+
diff --git a/scripts/polynomial/polyval.m b/scripts/polynomial/polyval.m
new file mode 100644
index 0000000..168e342
--- /dev/null
+++ b/scripts/polynomial/polyval.m
@@ -0,0 +1,127 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} polyval (@var{p}, @var{x})
+## @deftypefnx {Function File} {@var{y} =} polyval (@var{p}, @var{x}, [], @var{mu})
+## Evaluate the polynomial at of the specified values for @var{x}.  When @var{mu}
+## is present evaluate the polynomial for (@var{x}- at var{mu}(1))/@var{mu}(2).
+## If @var{x} is a vector or matrix, the polynomial is evaluated for each of
+## the elements of @var{x}.
+## @deftypefnx {Function File} {[@var{y}, @var{dy}] =} polyval (@var{p}, @var{x}, @var{s})
+## @deftypefnx {Function File} {[@var{y}, @var{dy}] =} polyval (@var{p}, @var{x}, @var{s}, @var{mu})
+## In addition to evaluating the polynomial, the second output 
+## represents the prediction interval, @var{y} +/- @var{dy}, which
+## contains at least 50% of the future predictions.  To calculate the
+## prediction interval, the structured variable @var{s}, originating
+## form `polyfit', must be present.
+## @seealso{polyfit, polyvalm, poly, roots, conv, deconv, residue, filter,
+## polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function [y, dy] = polyval (p, x, s, mu)
+
+  if (nargin < 2 || nargin > 4 || (nargout == 2 && nargin < 3))
+    print_usage ();
+  endif
+
+  if (nargin < 3)
+    s = [];
+  endif
+
+  if (! (isvector (p) || isempty (p)))
+    error ("polyval: first argument must be a vector");
+  endif
+
+  if (nargin < 4)
+    mu = [0, 1];
+  endif
+
+  if (isempty (x))
+    y = [];
+    return;
+  endif
+
+  if (length (p) == 0)
+    y = p;
+    return;
+  endif
+
+  n = length (p) - 1;
+  k = numel (x);
+  x = (x - mu(1)) / mu(2);
+  A = (x(:) * ones (1, n+1)) .^ (ones (k, 1) * (n:-1:0));
+  y = A * p(:);
+  y = reshape (y, size (x));
+
+  if (nargout == 2)
+    ## Note: the F-Distribution is generally considered to be single-sided.
+    ## http://www.itl.nist.gov/div898/handbook/eda/section3/eda3673.htm
+    ##   t = finv (1-alpha, s.df, s.df);
+    ##   dy = t * sqrt (1 + sumsq (A/s.R, 2)) * s.normr / sqrt (s.df)
+    ## If my inference is correct, then t must equal 1 for polyval.
+    ## This is because finv (0.5, n, n) = 1.0 for any n.
+    dy = sqrt (1 + sumsq (A/s.R, 2)) * s.normr / sqrt (s.df);
+    dy = reshape (dy, size (x));
+  endif
+
+endfunction
+
+%!test
+%! fail("polyval([1,0;0,1],0:10)");
+
+%!test
+%! r = 0:10:50;
+%! p = poly (r);
+%! p = p / max(abs(p));
+%! x = linspace(0,50,11);
+%! y = polyval(p,x) + 0.25*sin(100*x);
+%! [pf, s] = polyfit (x, y, numel(r));
+%! [y1, delta] = polyval (pf, x, s);
+%! expected = [0.37235, 0.35854, 0.32231, 0.32448, 0.31328, ...
+%!    0.32036, 0.31328, 0.32448, 0.32231, 0.35854, 0.37235];
+%! assert (delta, expected, 0.00001)
+
+%!test
+%! x = 10 + (-2:2);
+%! y = [0, 0, 1, 0, 2];
+%! p = polyfit (x, y, numel (x) - 1);
+%! [pn, s, mu] = polyfit (x, y, numel (x) - 1);
+%! y1 = polyval (p, x);
+%! yn = polyval (pn, x, [], mu);
+%! assert (y1, y, sqrt(eps))
+%! assert (yn, y, sqrt(eps))
+
+%!test
+%! p = [0, 1, 0];
+%! x = 1:10;
+%! assert (x, polyval(p,x), eps)
+%! x = x(:);
+%! assert (x, polyval(p,x), eps)
+%! x = reshape(x, [2, 5]);
+%! assert (x, polyval(p,x), eps)
+%! x = reshape(x, [5, 2]);
+%! assert (x, polyval(p,x), eps)
+%! x = reshape(x, [1, 1, 5, 2]);
+%! assert (x, polyval(p,x), eps)
+
diff --git a/scripts/polynomial/polyvalm.m b/scripts/polynomial/polyvalm.m
new file mode 100644
index 0000000..2b17821
--- /dev/null
+++ b/scripts/polynomial/polyvalm.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007, 2008 John W. Eaton
+## Copyright (C) 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} polyvalm (@var{c}, @var{x})
+## Evaluate a polynomial in the matrix sense.
+##
+## @code{polyvalm (@var{c}, @var{x})} will evaluate the polynomial in the
+## matrix sense, i.e., matrix multiplication is used instead of element by
+## element multiplication as is used in polyval.
+##
+## The argument @var{x} must be a square matrix.
+## @seealso{polyval, poly, roots, conv, deconv, residue, filter,
+## polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Created: June 1994
+## Adapted-By: jwe
+
+function y = polyvalm (c, x)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! (isvector (c) || isempty (c)))
+    error ("polyvalm: first argument must be a vector");
+  endif
+
+  if (! issquare (x))
+    error ("polyvalm: second argument must be a square matrix");
+  endif
+
+  n = length (c);
+  if (n == 0)
+    y = zeros (rows (x), class (x));
+  else
+    id = eye (rows (x), class (x));
+    y = c(1) * id;
+    for i = 2:n
+      y = y * x + c(i) * id;
+    endfor
+  endif
+
+endfunction
+
+
+%!assert(! any (polyvalm ([], [1, 2; 3, 4]))(:));
+%!assert(polyvalm ([1, 2, 3, 4], [3, -4, 1; -2, 0, 2; -1, 4, -3]), [117, -124, 11; -70, 36, 38; -43, 92, -45])
+
+%!error polyvalm ([1, 1, 1], [1, 2; 3, 4; 5, 6]);
+
diff --git a/scripts/polynomial/ppval.m b/scripts/polynomial/ppval.m
new file mode 100644
index 0000000..82aee90
--- /dev/null
+++ b/scripts/polynomial/ppval.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2000, 2006, 2007, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{yi} =} ppval (@var{pp}, @var{xi})
+## Evaluate piece-wise polynomial @var{pp} at the points @var{xi}.  
+## If @code{@var{pp}.d} is a scalar greater than 1, or an array,
+## then the returned value @var{yi} will be an array that is 
+## @code{d1, d1, @dots{}, dk, length (@var{xi})]}.
+## @seealso{mkpp, unmkpp, spline}
+## @end deftypefn 
+
+function yi = ppval (pp, xi)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+  if (! isstruct (pp))
+    error ("ppval: expects a pp structure");
+  endif
+  if (isempty (xi))
+    yi = [];
+  else
+    transposed = (columns (xi) == 1);
+    xi = xi(:);
+    xn = length (xi);
+    idx = lookup (pp.x, xi, "lr");
+    dx = (xi - pp.x(idx)).';
+    dx = reshape (dx(ones(1,prod(pp.d)),:),[pp.d,xn]);
+    c = reshape (pp.P(:,1), pp.n, prod (pp.d));
+    yi = reshape (c(idx,:).', [pp.d, xn]);
+    for i  = 2 : pp.k;
+      c = reshape (pp.P(:,i), pp.n, prod (pp.d));
+      yi = yi .* dx + reshape (c(idx,:).', [pp.d, xn]);
+    endfor
+    if (transposed && isscalar (pp.d) && pp.d == 1)
+      yi = yi.';
+    endif
+  endif
+endfunction
diff --git a/scripts/polynomial/residue.m b/scripts/polynomial/residue.m
new file mode 100644
index 0000000..ee59075
--- /dev/null
+++ b/scripts/polynomial/residue.m
@@ -0,0 +1,412 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2005
+##                2006, 2007, 2008, 2009 John W. Eaton
+## Copyright (C) 2007 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{r}, @var{p}, @var{k}, @var{e}] =} residue (@var{b}, @var{a})
+## Compute the partial fraction expansion for the quotient of the
+## polynomials, @var{b} and @var{a}.
+##
+## @tex
+## $$
+## {B(s)\over A(s)} = \sum_{m=1}^M {r_m\over (s-p_m)^e_m}
+##   + \sum_{i=1}^N k_i s^{N-i}.
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##  B(s)    M       r(m)         N
+##  ---- = SUM -------------  + SUM k(i)*s^(N-i)
+##  A(s)   m=1 (s-p(m))^e(m)    i=1
+## @end group
+## @end example
+## @end ifnottex
+##
+## @noindent
+## where @math{M} is the number of poles (the length of the @var{r},
+## @var{p}, and @var{e}), the @var{k} vector is a polynomial of order @math{N-1}
+## representing the direct contribution, and the @var{e} vector specifies
+## the multiplicity of the m-th residue's pole.
+##
+## For example,
+##
+## @example
+## @group
+## b = [1, 1, 1];
+## a = [1, -5, 8, -4];
+## [r, p, k, e] = residue (b, a);
+##      @result{} r = [-2; 7; 3]
+##      @result{} p = [2; 2; 1]
+##      @result{} k = [](0x0)
+##      @result{} e = [1; 2; 1]
+## @end group
+## @end example
+##
+## @noindent
+## which represents the following partial fraction expansion
+## @tex
+## $$
+## {s^2+s+1\over s^3-5s^2+8s-4} = {-2\over s-2} + {7\over (s-2)^2} + {3\over s-1}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##         s^2 + s + 1       -2        7        3
+##    ------------------- = ----- + ------- + -----
+##    s^3 - 5s^2 + 8s - 4   (s-2)   (s-2)^2   (s-1)
+## @end group
+## @end example
+##
+## @end ifnottex
+##
+## @deftypefnx {Function File} {[@var{b}, @var{a}] =} residue (@var{r}, @var{p}, @var{k})
+## @deftypefnx {Function File} {[@var{b}, @var{a}] =} residue (@var{r}, @var{p}, @var{k}, @var{e})
+## Compute the reconstituted quotient of polynomials,
+## @var{b}(s)/@var{a}(s), from the partial fraction expansion;
+## represented by the residues, poles, and a direct polynomial specified
+## by @var{r}, @var{p} and @var{k}, and the pole multiplicity @var{e}.
+##
+## If the multiplicity, @var{e}, is not explicitly specified the multiplicity is
+## determined by the script mpoles.m.
+##
+## For example,
+##
+## @example
+## @group
+## r = [-2; 7; 3];
+## p = [2; 2; 1];
+## k = [1, 0];
+## [b, a] = residue (r, p, k);
+##      @result{} b = [1, -5, 9, -3, 1]
+##      @result{} a = [1, -5, 8, -4]
+##
+## where mpoles.m is used to determine e = [1; 2; 1]
+##
+## @end group
+## @end example
+##
+## Alternatively the multiplicity may be defined explicitly, for example,
+##
+## @example
+## @group
+## r = [7; 3; -2];
+## p = [2; 1; 2];
+## k = [1, 0];
+## e = [2; 1; 1];
+## [b, a] = residue (r, p, k, e);
+##      @result{} b = [1, -5, 9, -3, 1]
+##      @result{} a = [1, -5, 8, -4]
+## @end group
+## @end example
+##
+## @noindent
+## which represents the following partial fraction expansion
+## @tex
+## $$
+## {-2\over s-2} + {7\over (s-2)^2} + {3\over s-1} + s = {s^4-5s^3+9s^2-3s+1\over s^3-5s^2+8s-4}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##     -2        7        3         s^4 - 5s^3 + 9s^2 - 3s + 1
+##    ----- + ------- + ----- + s = --------------------------
+##    (s-2)   (s-2)^2   (s-1)          s^3 - 5s^2 + 8s - 4
+## @end group
+## @end example
+## @end ifnottex
+## @seealso{poly, roots, conv, deconv, mpoles, polyval, polyderiv, polyinteg}
+## @end deftypefn
+
+## Author: Tony Richardson <arichard at stark.cc.oh.us>
+## Author: Ben Abbott <bpabbott at mac.com>
+## Created: June 1994
+## Adapted-By: jwe
+
+function [r, p, k, e] = residue (b, a, varargin)
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  toler = .001;
+
+  if (nargin >= 3)
+    if (nargin >= 4)
+      e = varargin{2};
+    else
+      e = [];
+    endif
+    ## The inputs are the residue, pole, and direct part. Solve for the
+    ## corresponding numerator and denominator polynomials
+    [r, p] = rresidue (b, a, varargin{1}, toler, e);
+    return
+  endif
+
+  ## Make sure both polynomials are in reduced form.
+
+  a = polyreduce (a);
+  b = polyreduce (b);
+
+  b = b / a(1);
+  a = a / a(1);
+
+  la = length (a);
+  lb = length (b);
+
+  ## Handle special cases here.
+
+  if (la == 0 || lb == 0)
+    k = r = p = e = [];
+    return;
+  elseif (la == 1)
+    k = b / a;
+    r = p = e = [];
+    return;
+  endif
+
+  ## Find the poles.
+
+  p = roots (a);
+  lp = length (p);
+
+  ## Sort poles so that multiplicity loop will work.
+
+  [e, indx] = mpoles (p, toler, 1);
+  p = p (indx);
+
+  ## For each group of pole multiplicity, set the value of each
+  ## pole to the average of the group. This reduces the error in 
+  ## the resulting poles.
+
+  p_group = cumsum (e == 1);
+  for ng = 1:p_group(end)
+    m = find (p_group == ng);
+    p(m) = mean (p(m));
+  endfor
+
+  ## Find the direct term if there is one.
+
+  if (lb >= la)
+    ## Also return the reduced numerator.
+    [k, b] = deconv (b, a);
+    lb = length (b);
+  else
+    k = [];
+  endif
+
+  ## Determine if the poles are (effectively) zero.
+
+  small = max (abs (p));
+  if (isa (a, "single") || isa (b, "single"))
+    small = max ([small, 1]) * eps ("single") * 1e4 * (1 + numel (p))^2;
+  else
+    small = max ([small, 1]) * eps * 1e4 * (1 + numel (p))^2;
+  endif
+  p(abs (p) < small) = 0;
+
+  ## Determine if the poles are (effectively) real, or imaginary.
+
+  index = (abs (imag (p)) < small);
+  p(index) = real (p(index));
+  index = (abs (real (p)) < small);
+  p(index) = 1i * imag (p(index));
+
+  ## The remainder determines the residues.  The case of one pole
+  ## is trivial.
+
+  if (lp == 1)
+    r = polyval (b, p);
+    return;
+  endif
+
+  ## Determine the order of the denominator and remaining numerator.
+  ## With the direct term removed the potential order of the numerator
+  ## is one less than the order of the denominator.
+
+  aorder = numel (a) - 1;
+  border = aorder - 1;
+
+  ## Construct a system of equations relating the individual
+  ## contributions from each residue to the complete numerator.
+
+  A = zeros (border+1, border+1);
+  B = prepad (reshape (b, [numel(b), 1]), border+1, 0);
+  for ip = 1:numel(p)
+    ri = zeros (size (p));
+    ri(ip) = 1;
+    A(:,ip) = prepad (rresidue (ri, p, [], toler), border+1, 0).';
+  endfor
+
+  ## Solve for the residues.
+
+  r = A \ B;
+
+endfunction
+
+function [pnum, pden, e] = rresidue (r, p, k, toler, e)
+
+  ## Reconstitute the numerator and denominator polynomials from the
+  ## residues, poles, and direct term.
+
+  if (nargin < 2 || nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin < 5)
+    e = [];
+  endif
+
+  if (nargin < 4)
+    toler = [];
+  endif
+
+  if (nargin < 3)
+    k = [];
+  endif
+ 
+  if numel (e)
+    indx = 1:numel(p);
+  else
+    [e, indx] = mpoles (p, toler, 0);
+    p = p (indx);
+    r = r (indx);
+  endif
+
+  indx = 1:numel(p);
+
+  for n = indx
+    pn = [1, -p(n)];
+    if n == 1
+      pden = pn;
+    else
+      pden = conv (pden, pn);
+    endif
+  endfor
+
+  ## D is the order of the denominator
+  ## K is the order of the direct polynomial
+  ## N is the order of the resulting numerator
+  ## pnum(1:(N+1)) is the numerator's polynomial
+  ## pden(1:(D+1)) is the denominator's polynomial
+  ## pm is the multible pole for the nth residue
+  ## pn is the numerator contribution for the nth residue
+
+  D = numel (pden) - 1;
+  K = numel (k) - 1;
+  N = K + D;
+  pnum = zeros (1, N+1);
+  for n = indx(abs (r) > 0)
+    p1 = [1, -p(n)];
+    for m = 1:e(n)
+      if (m == 1)
+        pm = p1;
+      else
+        pm = conv (pm, p1);
+      endif
+    endfor
+    pn = deconv (pden, pm);
+    pn = r(n) * pn;
+    pnum = pnum + prepad (pn, N+1, 0, 2);
+  endfor
+
+  ## Add the direct term.
+
+  if (numel (k))
+    pnum = pnum + conv (pden, k);
+  endif
+
+  ## Check for leading zeros and trim the polynomial coefficients.
+  if (isa (r, "single") || isa (p, "single") || isa (k, "single"))
+    small = max ([max(abs(pden)), max(abs(pnum)), 1]) * eps ("single");
+  else
+    small = max ([max(abs(pden)), max(abs(pnum)), 1]) * eps;
+  endif
+
+  pnum(abs (pnum) < small) = 0;
+  pden(abs (pden) < small) = 0;
+
+  pnum = polyreduce (pnum);
+  pden = polyreduce (pden);
+
+endfunction
+
+%!test
+%! b = [1, 1, 1];
+%! a = [1, -5, 8, -4];
+%! [r, p, k, e] = residue (b, a);
+%! assert (abs (r - [-2; 7; 3]) < 1e-12
+%!   && abs (p - [2; 2; 1]) < 1e-12
+%!   && isempty (k)
+%!   && e == [1; 2; 1]);
+%! k = [1 0];
+%! b = conv (k, a) + prepad (b, numel (k) + numel (a) - 1, 0);
+%! a = a;
+%! [br, ar] = residue (r, p, k);
+%! assert ((abs (br - b) < 1e-12
+%!   && abs (ar - a) < 1e-12));
+%! [br, ar] = residue (r, p, k, e);
+%! assert ((abs (br - b) < 1e-12
+%!   && abs (ar - a) < 1e-12));
+
+%!test
+%! b = [1, 0, 1];
+%! a = [1, 0, 18, 0, 81];
+%! [r, p, k, e] = residue (b, a);
+%! r1 = [-5i; 12; +5i; 12]/54;
+%! p1 = [+3i; +3i; -3i; -3i];
+%! assert (abs (r - r1) < 1e-12 && abs (p - p1) < 1e-12
+%!   && isempty (k)
+%!   && e == [1; 2; 1; 2]);
+%! [br, ar] = residue (r, p, k);
+%! assert ((abs (br - b) < 1e-12
+%!   && abs (ar - a) < 1e-12));
+
+%!test
+%! r = [7; 3; -2];
+%! p = [2; 1; 2];
+%! k = [1 0];
+%! e = [2; 1; 1];
+%! [b, a] = residue (r, p, k, e);
+%! assert ((abs (b - [1, -5, 9, -3, 1]) < 1e-12
+%!   && abs (a - [1, -5, 8, -4]) < 1e-12));
+%! [rr, pr, kr, er] = residue (b, a);
+%! [jnk, n] = mpoles(p);
+%! assert ((abs (rr - r(n)) < 1e-12
+%!   && abs (pr - p(n)) < 1e-12
+%!   && abs (kr - k) < 1e-12
+%!   && abs (er - e(n)) < 1e-12));
+
+%!test
+%! b = [1];
+%! a = [1, 10, 25];
+%! [r, p, k, e] = residue (b, a);
+%! r1 = [0; 1];
+%! p1 = [-5; -5];
+%! assert (abs (r - r1) < 1e-12 && abs (p - p1) < 1e-12
+%!   && isempty (k)
+%!   && e == [1; 2]);
+%! [br, ar] = residue (r, p, k);
+%! assert ((abs (br - b) < 1e-12
+%!   && abs (ar - a) < 1e-12));
diff --git a/scripts/polynomial/roots.m b/scripts/polynomial/roots.m
new file mode 100644
index 0000000..a2bcca7
--- /dev/null
+++ b/scripts/polynomial/roots.m
@@ -0,0 +1,137 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2004, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} roots (@var{v})
+##
+## For a vector @var{v} with @math{N} components, return
+## the roots of the polynomial
+## @tex
+## $$
+## v_1 z^{N-1} + \cdots + v_{N-1} z + v_N.
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## v(1) * z^(N-1) + @dots{} + v(N-1) * z + v(N)
+## @end example
+## @end ifnottex
+##
+## As an example, the following code finds the roots of the quadratic
+## polynomial
+## @tex
+## $$ p(x) = x^2 - 5. $$
+## @end tex
+## @ifnottex
+## @example
+## p(x) = x^2 - 5.
+## @end example
+## @end ifnottex
+## @example
+## @group
+## c = [1, 0, -5];
+## roots(c)
+## @result{}  2.2361
+## @result{} -2.2361
+## @end group
+## @end example
+## Note that the true result is
+## @tex
+## $\pm \sqrt{5}$
+## @end tex
+## @ifnottex
+## @math{+/- sqrt(5)}
+## @end ifnottex
+## which is roughly
+## @tex
+## $\pm 2.2361$.
+## @end tex
+## @ifnottex
+## @math{+/- 2.2361}.
+## @end ifnottex
+## @seealso{compan}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 24 December 1993
+## Adapted-By: jwe
+
+function r = roots (v)
+
+  if (nargin != 1 || min (size (v)) > 1)
+    print_usage ();
+  elseif (any (isnan(v) | isinf(v)))
+    error ("roots: inputs must not contain Inf or NaN");
+  endif
+
+  n = numel (v);
+  v = v(:);
+
+  ## If v = [ 0 ... 0 v(k+1) ... v(k+l) 0 ... 0 ], we can remove the
+  ## leading k zeros and n - k - l roots of the polynomial are zero.
+
+  if (isempty (v))
+    f = v;
+  else
+    f = find (v ./ max (abs (v)));
+  endif
+  m = numel (f);
+
+  if (m > 0 && n > 1)
+    v = v(f(1):f(m));
+    l = max (size (v));
+    if (l > 1)
+      A = diag (ones (1, l-2), -1);
+      A(1,:) = -v(2:l) ./ v(1);
+      r = eig (A);
+      if (f(m) < n)
+        tmp = zeros (n - f(m), 1);
+        r = [r; tmp];
+      endif
+    else
+      r = zeros (n - f(m), 1);
+    endif
+  else
+    r = [];
+  endif
+
+endfunction
+
+%!test
+%! p = [poly([3 3 3 3]), 0 0 0 0];
+%! r = sort (roots (p));
+%! assert (r, [0; 0; 0; 0; 3; 3; 3; 3], 0.001)
+
+%!assert(all (all (abs (roots ([1, -6, 11, -6]) - [3; 2; 1]) < sqrt (eps))));
+
+%!assert(isempty (roots ([])));
+
+%!error roots ([1, 2; 3, 4]);
+ 
+%!assert(isempty (roots (1)));
+
+ %!error roots ([1, 2; 3, 4]);
+ 
+%!error roots ([1 Inf 1]);
+
+%!error roots ([1 NaN 1]);
+
+%!assert(roots ([1e-200, -1e200, 1]), 1e-200)
+%!assert(roots ([1e-200, -1e200 * 1i, 1]), -1e-200 * 1i)
diff --git a/scripts/polynomial/spline.m b/scripts/polynomial/spline.m
new file mode 100644
index 0000000..556a7d2
--- /dev/null
+++ b/scripts/polynomial/spline.m
@@ -0,0 +1,225 @@
+## Copyright (C) 2000, 2001, 2006, 2007, 2008, 2009 Kai Habel
+## Copyright (C) 2006 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{pp} =} spline (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{yi} =} spline (@var{x}, @var{y}, @var{xi})
+##
+## Return the cubic spline interpolant of @var{y} at points @var{x}. 
+## If called with two arguments, @code{spline} returns the piece-wise
+## polynomial @var{pp} that may later be used with @code{ppval} to
+## evaluate the polynomial at specific points.
+## If called with a third input argument, @code{spline} evaluates the 
+## spline at the points @var{xi}.  There is an equivalence
+## between @code{ppval (spline (@var{x}, @var{y}), @var{xi})} and
+## @code{spline (@var{x}, @var{y}, @var{xi})}.
+##
+## The variable @var{x} must be a vector of length @var{n}, and @var{y}
+## can be either a vector or array.  In the case where @var{y} is a
+## vector, it can have a length of either @var{n} or @code{@var{n} + 2}.
+## If the length of @var{y} is @var{n}, then the 'not-a-knot' end
+## condition is used.  If the length of @var{y} is @code{@var{n} + 2},
+## then the first and last values of the vector @var{y} are the values
+## of the first derivative of the cubic spline at the end-points.
+##
+## If @var{y} is an array, then the size of @var{y} must have the form
+## @tex
+## $$[s_1, s_2, \cdots, s_k, n]$$
+## @end tex
+## @ifnottex
+## @code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]}
+## @end ifnottex
+## or
+## @tex
+## $$[s_1, s_2, \cdots, s_k, n + 2].$$
+## @end tex
+## @ifnottex
+## @code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n} + 2]}.
+## @end ifnottex
+## The array is then reshaped internally to a matrix where the leading
+## dimension is given by 
+## @tex
+## $$s_1 s_2 \cdots s_k$$
+## @end tex
+## @ifnottex
+## @code{@var{s1} * @var{s2} * @dots{} * @var{sk}}
+## @end ifnottex
+## and each row of this matrix is then treated separately.  Note that this
+## is exactly the opposite treatment than @code{interp1} and is done
+## for compatibility.
+## @seealso{ppval, mkpp, unmkpp}
+## @end deftypefn
+
+## This code is based on csape.m from octave-forge, but has been
+## modified to use the sparse solver code in octave that itself allows
+## special casing of tri-diagonal matrices, modified for NDArrays and
+## for the treatment of vectors y 2 elements longer than x as complete
+## splines.
+
+function ret = spline (x, y, xi)
+
+  x = x(:);
+  n = length (x);
+  if (n < 3)
+    error ("spline: requires at least 3 points"); 
+  endif
+
+  ## Check the size and shape of y
+  ndy = ndims (y);
+  szy = size (y);
+  if (ndy == 2 && (szy(1) == 1 || szy(2) == 1))
+    if (szy(1) == 1)
+      a = y.';
+    else
+      a = y;
+      szy = fliplr (szy);
+    endif
+  else
+    a = reshape (y, [prod(szy(1:end-1)), szy(end)]).';
+  endif
+  complete = false;
+  if (size (a, 1) == n + 2)
+    complete = true;
+    dfs = a(1,:);
+    dfe = a(end,:);
+    a = a(2:end-1,:);
+  endif
+
+  b = c = zeros (size (a));
+  h = diff (x);
+  idx = ones (columns (a), 1);
+
+  if (complete)
+
+    if (n == 3)
+      dg = 1.5 * h(1) - 0.5 * h(2);
+      c(2:n-1,:) = 1/dg(1);
+    else
+      dg = 2 * (h(1:n-2) .+ h(2:n-1));
+      dg(1) = dg(1) - 0.5 * h(1);
+      dg(n-2) = dg(n-2) - 0.5 * h(n-1);
+
+      e = h(2:n-2);
+
+      g = 3 * diff (a(2:n,:)) ./ h(2:n-1,idx) ...
+          - 3 * diff (a(1:n-1,:)) ./ h(1:n-2,idx);
+      g(1,:) = 3 * (a(3,:) - a(2,:)) / h(2) ...
+          - 3 / 2 * (3 * (a(2,:) - a(1,:)) / h(1) - dfs);
+      g(n-2,:) = 3 / 2 * (3 * (a(n,:) - a(n-1,:)) / h(n-1) - dfe) ...
+          - 3 * (a(n-1,:) - a(n-2,:)) / h(n-2);
+
+      c(2:n-1,:) = spdiags ([[e(:); 0], dg, [0; e(:)]],
+			      [-1, 0, 1], n-2, n-2) \ g;
+    endif
+
+    c(1,:) = (3 / h(1) * (a(2,:) - a(1,:)) - 3 * dfs
+	      - c(2,:) * h(1)) / (2 * h(1));
+    c(n,:) = - (3 / h(n-1) * (a(n,:) - a(n-1,:)) - 3 * dfe
+		+ c(n-1,:) * h(n-1)) / (2 * h(n-1));
+    b(1:n-1,:) = diff (a) ./ h(1:n-1, idx) ...
+	- h(1:n-1,idx) / 3 .* (c(2:n,:) + 2 * c(1:n-1,:));
+    d = diff (c) ./ (3 * h(1:n-1, idx));
+
+  else
+
+    g = zeros (n-2, columns (a));
+    g(1,:) = 3 / (h(1) + h(2)) ...
+	* (a(3,:) - a(2,:) - h(2) / h(1) * (a(2,:) - a(1,:)));
+    g(n-2,:) = 3 / (h(n-1) + h(n-2)) ...
+	* (h(n-2) / h(n-1) * (a(n,:) - a(n-1,:)) - (a(n-1,:) - a(n-2,:)));
+
+    if (n > 4)
+
+      g(2:n - 3,:) = 3 * diff (a(3:n-1,:)) ./ h(3:n-2,idx) ...
+          - 3 * diff (a(2:n-2,:)) ./ h(2:n - 3,idx);
+
+      dg = 2 * (h(1:n-2) .+ h(2:n-1));
+      dg(1) = dg(1) - h(1);
+      dg(n-2) = dg(n-2) - h(n-1);
+
+      ldg = udg = h(2:n-2);
+      udg(1) = udg(1) - h(1);
+      ldg(n - 3) = ldg(n-3) - h(n-1);
+      c(2:n-1,:) = spdiags ([[ldg(:); 0], dg, [0; udg(:)]],
+			      [-1, 0, 1], n-2, n-2) \ g;
+
+    elseif (n == 4)
+
+      dg = [h(1) + 2 * h(2); 2 * h(2) + h(3)];
+      ldg = h(2) - h(3);
+      udg = h(2) - h(1);
+      c(2:n-1,:) = spdiags ([[ldg(:);0], dg, [0; udg(:)]],
+			      [-1, 0, 1], n-2, n-2) \ g;
+      
+    else # n == 3
+	    
+      dg = h(1) + 2 * h(2);
+      c(2:n-1,:) = g/dg(1);
+
+    endif
+
+    c(1,:) = c(2,:) + h(1) / h(2) * (c(2,:) - c(3,:));
+    c(n,:) = c(n-1,:) + h(n-1) / h(n-2) * (c(n-1,:) - c(n-2,:));
+    b = diff (a) ./ h(1:n-1, idx) ...
+	- h(1:n-1, idx) / 3 .* (c(2:n,:) + 2 * c(1:n-1,:));
+    d = diff (c) ./ (3 * h(1:n-1, idx));
+
+  endif
+
+  d = d(1:n-1,:);
+  c = c(1:n-1,:);
+  b = b(1:n-1,:);
+  a = a(1:n-1,:);
+  coeffs = [d(:), c(:), b(:), a(:)];
+  ret = mkpp (x, coeffs, szy(1:end-1));
+
+  if (nargin == 3)
+    ret = ppval (ret, xi);
+  endif
+
+endfunction
+
+%!demo
+%! x = 0:10; y = sin(x);
+%! xspline = 0:0.1:10; yspline = spline(x,y,xspline);
+%! title("spline fit to points from sin(x)");
+%! plot(xspline,sin(xspline),"r",xspline,yspline,"g-",x,y,"b+");
+%! legend("original","interpolation","interpolation points");
+%! %--------------------------------------------------------
+%! % confirm that interpolated function matches the original
+
+%!shared x,y,abserr
+%! x = [0:10]; y = sin(x); abserr = 1e-14;
+%!assert (spline(x,y,x), y, abserr);
+%!assert (spline(x,y,x'), y', abserr);
+%!assert (spline(x',y',x'), y', abserr);
+%!assert (spline(x',y',x), y, abserr);
+%!assert (isempty(spline(x',y',[])));
+%!assert (isempty(spline(x,y,[])));
+%!assert (spline(x,[y;y],x), [spline(x,y,x);spline(x,y,x)],abserr)
+%! y = cos(x) + i*sin(x);
+%!assert (spline(x,y,x), y, abserr)
+%!assert (real(spline(x,y,x)), real(y), abserr);
+%!assert (real(spline(x,y,x.')), real(y).', abserr);
+%!assert (real(spline(x.',y.',x.')), real(y).', abserr);
+%!assert (real(spline(x.',y,x)), real(y), abserr);
+%!assert (imag(spline(x,y,x)), imag(y), abserr);
+%!assert (imag(spline(x,y,x.')), imag(y).', abserr);
+%!assert (imag(spline(x.',y.',x.')), imag(y).', abserr);
+%!assert (imag(spline(x.',y,x)), imag(y), abserr);
diff --git a/scripts/polynomial/unmkpp.m b/scripts/polynomial/unmkpp.m
new file mode 100644
index 0000000..cd5f513
--- /dev/null
+++ b/scripts/polynomial/unmkpp.m
@@ -0,0 +1,60 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{p}, @var{n}, @var{k}, @var{d}] =} unmkpp (@var{pp})
+##
+## Extract the components of a piece-wise polynomial structure @var{pp}.
+## These are as follows:
+##
+## @table @asis
+## @item @var{x}
+## Sample points.
+## @item @var{p}
+## Polynomial coefficients for points in sample interval.  @code{@var{p}
+## (@var{i}, :)} contains the coefficients for the polynomial over
+## interval @var{i} ordered from highest to lowest.  If @code{@var{d} >
+## 1}, @code{@var{p} (@var{r}, @var{i}, :)} contains the coefficients for 
+## the r-th polynomial defined on interval @var{i}.  However, this is 
+## stored as a 2-D array such that @code{@var{c} = reshape (@var{p} (:,
+## @var{j}), @var{n}, @var{d})} gives @code{@var{c} (@var{i},  @var{r})}
+## is the j-th coefficient of the r-th polynomial over the i-th interval.
+## @item @var{n}
+## Number of polynomial pieces.
+## @item @var{k}
+## Order of the polynomial plus 1.
+## @item @var{d}
+## Number of polynomials defined for each interval.
+## @end table
+##
+## @seealso{mkpp, ppval, spline}
+## @end deftypefn
+
+function [x, P, n, k, d] = unmkpp (pp)
+  if (nargin == 0)
+    print_usage ();
+  endif
+  if (! isstruct (pp))
+    error ("unmkpp: expecting piecewise polynomial structure");
+  endif
+  x = pp.x;
+  P = pp.P;
+  n = pp.n;
+  k = pp.k;
+  d = pp.d;
+endfunction
diff --git a/scripts/set/Makefile.in b/scripts/set/Makefile.in
new file mode 100644
index 0000000..e85ff6b
--- /dev/null
+++ b/scripts/set/Makefile.in
@@ -0,0 +1,85 @@
+# Makefile for octave's scripts/set directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008, 2009
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = set
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = complement.m intersect.m ismember.m \
+  setdiff.m setxor.m union.m unique.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/set
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/set/complement.m b/scripts/set/complement.m
new file mode 100644
index 0000000..eb0d7ee
--- /dev/null
+++ b/scripts/set/complement.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} complement (@var{x}, @var{y})
+## Return the elements of set @var{y} that are not in set @var{x}.  For
+## example,
+##
+## @example
+## @group
+## complement ([ 1, 2, 3 ], [ 2, 3, 5 ])
+##      @result{} 5
+## @end group
+## @end example
+## @seealso{union, intersect, unique}
+## @end deftypefn
+
+## Author: jwe
+
+function y = complement (a, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isempty (a))
+    y = unique (b);
+  elseif (isempty (b))
+    y = [];
+  else
+    a = unique (a);
+    b = unique (b);
+    yindex = 1;
+    y = zeros (1, length (b));
+    for index = 1:length (b)
+      if (all (a != b (index)))
+        y(yindex++) = b(index);
+      endif
+    endfor
+    y = y(1:(yindex-1));
+  endif
+
+endfunction
+
+%!assert(all (all (complement ([1, 2, 3], [3; 4; 5; 6]) == [4, 5, 6])));
+
+%!assert(all (all (complement ([1, 2, 3], [3, 4, 5, 6]) == [4, 5, 6])));
+
+%!assert(isempty (complement ([1, 2, 3], [3, 2, 1])));
+
+%!error complement (1);
+
+%!error complement (1, 2, 3);
+
diff --git a/scripts/set/intersect.m b/scripts/set/intersect.m
new file mode 100644
index 0000000..88bff5a
--- /dev/null
+++ b/scripts/set/intersect.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+## Copyright (C) 2000, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} intersect (@var{a}, @var{b})
+## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@var{a}, @var{b})
+##
+## Return the elements in both @var{a} and @var{b}, sorted in ascending
+## order.  If @var{a} and @var{b} are both column vectors return a column
+## vector, otherwise return a row vector.
+##
+## Return index vectors @var{ia} and @var{ib} such that @code{a(ia)==c} and
+## @code{b(ib)==c}.
+##
+## @end deftypefn
+## @seealso{unique, union, setxor, setdiff, ismember}
+
+function [c, ia, ib] = intersect (a, b, varargin)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3 && ! strcmpi (varargin{1}, "rows"))
+    error ("intersect: if a third input argument is present, it must be the string 'rows'");
+  endif
+
+
+  if (isempty (a) || isempty (b))
+    c = ia = ib = [];
+  else
+    ## form a and b into sets
+    if (nargout > 1)
+      [a, ja] = unique (a, varargin{:});
+      [b, jb] = unique (b, varargin{:});
+    else
+      a = unique (a, varargin{:});
+      b = unique (b, varargin{:});
+    endif
+
+    if (nargin > 2)
+      c = [a; b];
+      [c, ic] = sortrows (c);
+      ii = find (all (c(1:end-1,:) == c(2:end,:), 2));
+      c = c(ii,:);
+    else
+      c = [a(:); b(:)];
+      [c, ic] = sort (c);               ## [a(:);b(:)](ic) == c
+      if (iscellstr (c))
+	ii = find (strcmp (c(1:end-1), c(2:end)));
+      else
+	ii = find (c(1:end-1) == c(2:end));
+      endif
+      c = c(ii);
+    endif
+
+
+    if (nargout > 1)
+      ia = ja(ic(ii));                  ## a(ia) == c
+      ib = jb(ic(ii+1) - length (a));   ## b(ib) == c
+    endif
+
+
+    if (nargin == 2 && (size (b, 1) == 1 || size (a, 1) == 1))
+      c = c.';
+    endif
+  endif
+
+endfunction
+
+
+%!# Test the routine for index vectors ia and ib
+%!test
+%! a = [3 2 4 5 7 6 5 1 0 13 13];
+%! b = [3 5 12 1 1 7];
+%! [c,ia,ib] = intersect(a,b);
+%! assert(c,[1 3 5 7]);
+%! assert(ia,[8 1 7 5]);
+%! assert(ib,[5 1 2 6]);
+%! assert(a(ia),c);
+%! assert(b(ib),c);
+%!test
+%! a = [1,1,2;1,4,5;2,1,7];
+%! b = [1,4,5;2,3,4;1,1,2;9,8,7];
+%! [c,ia,ib] = intersect(a,b,'rows');
+%! assert(c,[1,1,2;1,4,5]);
+%! assert(ia,[1;2]);
+%! assert(ib,[3;1]);
+%! assert(a(ia,:),c);
+%! assert(b(ib,:),c);
+%!test
+%! a = [1 1 1 2 2 2];
+%! b = [1 2 3 4 5 6];
+%! c = intersect(a,b);
+%! assert(c, [1,2]);
diff --git a/scripts/set/ismember.m b/scripts/set/ismember.m
new file mode 100644
index 0000000..595e5d4
--- /dev/null
+++ b/scripts/set/ismember.m
@@ -0,0 +1,315 @@
+## Copyright (C) 2000, 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{tf} =} ismember (@var{A}, @var{S}) 
+## @deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{S}) 
+## @deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{S}, "rows")
+## Return a matrix @var{tf} with the same shape as @var{A} which has a 1 if 
+## @code{A(i,j)} is in @var{S} and 0 if it is not.  If a second output argument 
+## is requested, the index into @var{S} of each of the matching elements is
+## also returned. 
+##
+## @example
+## @group
+## a = [3, 10, 1];
+## s = [0:9];
+## [tf, s_idx] = ismember (a, s);
+##      @result{} tf = [1, 0, 1]
+##      @result{} s_idx = [4, 0, 2]
+## @end group
+## @end example
+##
+## The inputs, @var{A} and @var{S}, may also be cell arrays.
+##
+## @example
+## @group
+## a = @{'abc'@};
+## s = @{'abc', 'def'@};
+## [tf, s_idx] = ismember (a, s);
+##      @result{} tf = [1, 0]
+##      @result{} s_idx = [1, 0]
+## @end group
+## @end example
+##
+## With the optional third argument @code{"rows"}, and matrices 
+## @var{A} and @var{S} with the same number of columns, compare rows in
+## @var{A} with the rows in @var{S}.
+##
+## @example
+## @group
+## a = [1:3; 5:7; 4:6];
+## s = [0:2; 1:3; 2:4; 3:5; 4:6];
+## [tf, s_idx] = ismember(a, s, 'rows');
+##      @result{} tf = logical ([1; 0; 1])
+##      @result{} s_idx = [2; 0; 5];
+## @end group
+## @end example
+##
+## @seealso{unique, union, intersect, setxor, setdiff}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+## Author: Søren Hauberg <hauberg at gmail.com>
+## Author: Ben Abbott <bpabbott at mac.com>
+## Adapted-by: jwe
+
+function [tf, a_idx] = ismember (a, s, rows_opt) 
+
+  if (nargin == 2 || nargin == 3) 
+    if (iscell (a) || iscell (s))
+      if (nargin == 3)
+        error ("ismember: with 'rows' both sets must be matrices"); 
+      else
+        [tf, a_idx] = cell_ismember (a, s);
+      endif
+    else
+      if (nargin == 3) 
+        ## The 'rows' argument is handled in a fairly ugly way. A better
+        ## solution would be to vectorize this loop over 'r' below.
+        if (strcmpi (rows_opt, "rows") && ismatrix (a) && ismatrix (s)
+	    && columns (a) == columns (s)) 
+          rs = rows (s);
+          ra = rows (a);
+          a_idx = zeros (ra, 1);
+          for r = 1:ra
+           tmp = ones (rs, 1) * a(r,:);
+            f = find (all (tmp' == s'), 1);
+            if (! isempty (f))
+              a_idx(r) = f;
+            endif
+          endfor
+          tf = logical (a_idx);
+        elseif (strcmpi (rows_opt, "rows"))
+          error ("ismember: with 'rows' both sets must be matrices with an equal number of columns"); 
+        else
+          error ("ismember: invalid input"); 
+        endif
+      else
+        ## Input checking 
+        if (! isa (a, class (s))) 
+          error ("ismember: both input arguments must be the same type");
+        elseif (! ischar (a) && ! isnumeric (a))
+          error ("ismember: input arguments must be arrays, cell arrays, or strings"); 
+        elseif (ischar (a) && ischar (s))
+          a = uint8 (a);
+          s = uint8 (s);
+        endif
+        ## Convert matrices to vectors.
+        if (all (size (a) > 1))
+          a = a(:);
+        endif 
+        if (all (size (s) > 1))
+          s = s(:);
+        endif 
+        ## Do the actual work.
+        if (isempty (a) || isempty (s))
+          tf = zeros (size (a), "logical");
+          a_idx = zeros (size (a)); 
+        elseif (numel (s) == 1) 
+          tf = (a == s);
+          a_idx = double (tf);
+        elseif (numel (a) == 1) 
+          f = find (a == s, 1); 
+          tf = !isempty (f);
+          a_idx = f; 
+          if (isempty (a_idx))
+            a_idx = 0;
+          endif 
+        else
+          ## Magic:  the following code determines for each a, the index i 
+          ## such that s(i)<= a < s(i+1).  It does this by sorting the a 
+          ## into s and remembering the source index where each element came 
+          ## from.  Since all the a's originally came after all the s's, if 
+          ## the source index is less than the length of s, then the element 
+          ## came from s.  We can then do a cumulative sum on the indices to 
+          ## figure out which element of s each a comes after. 
+          ## E.g., s=[2 4 6], a=[1 2 3 4 5 6 7] 
+          ##    unsorted [s a]  = [ 2 4 6 1 2 3 4 5 6 7 ] 
+          ##    sorted [s a]    = [ 1 2 2 3 4 4 5 6 6 7 ] 
+          ##    source index p  = [ 4 1 5 6 2 7 8 3 9 10 ] 
+          ##    boolean p<=l(s) = [ 0 1 0 0 1 0 0 1 0 0 ] 
+          ##    cumsum(p<=l(s)) = [ 0 1 1 1 2 2 2 3 3 3 ] 
+          ## Note that this leaves a(1) coming after s(0) which doesn't 
+          ## exist.  So arbitrarily, we will dump all elements less than 
+          ## s(1) into the interval after s(1).  We do this by dropping s(1) 
+          ## from the sort!  E.g., s=[2 4 6], a=[1 2 3 4 5 6 7] 
+          ##    unsorted [s(2:3) a] =[4 6 1 2 3 4 5 6 7 ] 
+          ##    sorted [s(2:3) a] = [ 1 2 3 4 4 5 6 6 7 ] 
+          ##    source index p    = [ 3 4 5 1 6 7 2 8 9 ] 
+          ##    boolean p<=l(s)-1 = [ 0 0 0 1 0 0 1 0 0 ] 
+          ##    cumsum(p<=l(s)-1) = [ 0 0 0 1 1 1 2 2 2 ] 
+          ## Now we can use Octave's lvalue indexing to "invert" the sort, 
+          ## and assign all these indices back to the appropriate a and s, 
+          ## giving s_idx = [ -- 1 2], a_idx = [ 0 0 0 1 1 2 2 ].  Add 1 to 
+          ## a_idx, and we know which interval s(i) contains a.  It is 
+          ## easy to now check membership by comparing s(a_idx) == a.  This 
+          ## magic works because s starts out sorted, and because sort 
+          ## preserves the relative order of identical elements. 
+          lt = numel(s); 
+          [s, sidx] = sort (s); 
+          [v, p] = sort ([s(2:lt)(:); a(:)]); 
+          idx(p) = cumsum (p <= lt-1) + 1; 
+          idx = idx(lt:end); 
+          tf = (a == reshape (s(idx), size (a))); 
+          a_idx = zeros (size (tf)); 
+          a_idx(tf) = sidx(idx(tf));
+        endif
+        ## Resize result to the original size of 'a' 
+        size_a = size (a);
+        tf = reshape (tf, size_a); 
+        a_idx = reshape (a_idx, size_a);
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+function [tf, a_idx] = cell_ismember (a, s)
+  if (nargin == 2)
+    if (ischar (a) && iscellstr (s)) 
+      if (isempty (a))
+	## Work around bug in cellstr.
+        a = {''};
+      else
+        a = cellstr (a);
+      endif
+    elseif (iscellstr (a) && ischar (s))
+      if (isempty (s))
+	## Work around bug in cellstr.
+        s = {''};
+      else
+        s = cellstr (s);
+      endif
+    endif 
+    if (iscellstr (a) && iscellstr (s))
+      ## Do the actual work.
+      if (isempty (a) || isempty (s))
+        tf = zeros (size (a), "logical");
+        a_idx = zeros (size (a)); 
+      elseif (numel (s) == 1) 
+        tf = strcmp (a, s);
+        a_idx = double (tf);
+      elseif (numel (a) == 1) 
+        f = find (strcmp (a, s), 1); 
+        tf = !isempty (f);
+        a_idx = f; 
+        if (isempty (a_idx))
+          a_idx = 0;
+        endif 
+      else 
+        lt = numel (s);
+        [s, sidx] = sort (s);
+        [v, p] = sort ([s(2:lt)(:); a(:)]);
+        idx(p) = cumsum (p <= lt-1) + 1;
+        idx = idx(lt:end);
+        tf = (cellfun ("length", a) 
+              == reshape (cellfun ("length", s(idx)), size (a)));
+        idx2 = find (tf);
+        tf(idx2) = (all (char (a(idx2)) == char (s(idx)(idx2)), 2));
+        a_idx = zeros (size (tf));
+        a_idx(tf) = sidx(idx(tf));
+      endif
+    else
+      error ("cell_ismember: arguments must be cell arrays of character strings");
+    endif
+  else
+    print_usage ();
+  endif
+  ## Resize result to the original size of A.
+  size_a = size (a);
+  tf = reshape (tf, size_a); 
+  a_idx = reshape (a_idx, size_a); 
+endfunction
+
+%!assert (ismember ({''}, {'abc', 'def'}), false);
+%!assert (ismember ('abc', {'abc', 'def'}), true);
+%!assert (isempty (ismember ([], [1, 2])), true);
+%!assert (isempty (ismember ({}, {'a', 'b'})), true);
+%!assert (ismember ('', {'abc', 'def'}), false);
+%!fail ('ismember ([], {1, 2})');
+%!fail ('ismember ({[]}, {1, 2})');
+%!fail ('ismember ({}, {1, 2})');
+%!fail ('ismember ({1}, {''1'', ''2''})');
+%!fail ('ismember (1, ''abc'')');
+%!fail ('ismember ({''1''}, {''1'', ''2''},''rows'')');
+%!fail ('ismember ([1 2 3], [5 4 3 1], ''rows'')');
+%!assert (ismember ({'foo', 'bar'}, {'foobar'}), logical ([0, 0]));
+%!assert (ismember ({'foo'}, {'foobar'}), false);
+%!assert (ismember ({'bar'}, {'foobar'}), false);
+%!assert (ismember ({'bar'}, {'foobar', 'bar'}), true);
+%!assert (ismember ({'foo', 'bar'}, {'foobar', 'bar'}), logical ([0, 1]));
+%!assert (ismember ({'xfb', 'f', 'b'}, {'fb', 'b'}), logical ([0, 0, 1]));
+%!assert (ismember ("1", "0123456789."), true);
+
+%!test
+%! [result, a_idx] = ismember ([1, 2], []);
+%! assert (result, logical ([0, 0]))
+%! assert (a_idx, [0, 0]);
+
+%!test
+%! [result, a_idx] = ismember ([], [1, 2]);
+%! assert (result, logical ([]))
+%! assert (a_idx, []);
+
+%!test
+%! [result, a_idx] = ismember ({'a', 'b'}, '');
+%! assert (result, logical ([0, 0]))
+%! assert (a_idx, [0, 0]);
+
+%!test
+%! [result, a_idx] = ismember ({'a', 'b'}, {});
+%! assert (result, logical ([0, 0]))
+%! assert (a_idx, [0, 0]);
+
+%!test
+%! [result, a_idx] = ismember ('', {'a', 'b'});
+%! assert (result, false)
+%! assert (a_idx, 0);
+
+%!test
+%! [result, a_idx] = ismember ({}, {'a', 'b'});
+%! assert (result, logical ([]))
+%! assert (a_idx, []);
+
+%!test
+%! [result, a_idx] = ismember([1 2 3 4 5], [3]);
+%! assert (all (result == logical ([0 0 1 0 0])) && all (a_idx == [0 0 1 0 0]));
+
+%!test
+%! [result, a_idx] = ismember([1 6], [1 2 3 4 5 1 6 1]);
+%! assert (all (result == logical ([1 1])) && all (a_idx == [8 7]));
+
+%!test
+%! [result, a_idx] = ismember ([3,10,1], [0,1,2,3,4,5,6,7,8,9]);
+%! assert (all (result == logical ([1, 0, 1])) && all (a_idx == [4, 0, 2]));
+
+%!test
+%! [result, a_idx] = ismember ("1.1", "0123456789.1");
+%! assert (all (result == logical ([1, 1, 1])) && all (a_idx == [12, 11, 12]));
+
+%!test
+%! [result, a_idx] = ismember([1:3; 5:7; 4:6], [0:2; 1:3; 2:4; 3:5; 4:6], 'rows');
+%! assert (all (result == logical ([1; 0; 1])) && all (a_idx == [2; 0; 5]));
+
+%!test
+%! [result, a_idx] = ismember([1.1,1.2,1.3; 2.1,2.2,2.3; 10,11,12], [1.1,1.2,1.3; 10,11,12; 2.12,2.22,2.32], 'rows');
+%! assert (all (result == logical ([1; 0; 1])) && all (a_idx == [1; 0; 2]));
+
diff --git a/scripts/set/setdiff.m b/scripts/set/setdiff.m
new file mode 100644
index 0000000..8cd5083
--- /dev/null
+++ b/scripts/set/setdiff.m
@@ -0,0 +1,114 @@
+## Copyright (C) 2000, 2005, 2006, 2007 Paul Kienzle
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} setdiff (@var{a}, @var{b})
+## @deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows")
+## @deftypefnx {Function File} {[@var{c}, @var{i}] =} setdiff (@var{a}, @var{b})
+## Return the elements in @var{a} that are not in @var{b}, sorted in
+## ascending order.  If @var{a} and @var{b} are both column vectors
+## return a column vector, otherwise return a row vector.
+##
+## Given the optional third argument @samp{"rows"}, return the rows in
+## @var{a} that are not in @var{b}, sorted in ascending order by rows.
+##
+## If requested, return @var{i} such that @code{c = a(i)}.
+## @seealso{unique, union, intersect, setxor, ismember}
+## @end deftypefn
+
+## Author: Paul Kienzle
+## Adapted-by: jwe
+
+function [c, i] = setdiff (a, b, byrows_arg)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  byrows = false;
+
+  if (nargin == 3)
+    if (! strcmpi (byrows_arg, "rows"))
+      error ("expecting third argument to be \"rows\"");
+    elseif (iscell (a) || iscell (b))
+      warning ("setdiff: \"rows\" not valid for cell arrays");
+    else
+      byrows = true;
+    endif
+  endif
+
+  if (byrows)
+    if (nargout > 1)
+      [c, i] = unique (a, "rows");
+    else
+      c = unique (a, "rows");
+    endif
+    if (! isempty (c) && ! isempty (b))
+      ## Form a and b into combined set.
+      b = unique (b, "rows");
+      [dummy, idx] = sortrows ([c; b]);
+      ## Eliminate those elements of a that are the same as in b.
+      dups = find (all (dummy(1:end-1,:) == dummy(2:end,:), 2));
+      c(idx(dups),:) = [];
+      if (nargout > 1)
+	i(idx(dups),:) = [];
+      endif
+    endif
+  else
+    if (nargout > 1)
+      [c, i] = unique (a);
+    else
+      c = unique (a);
+    endif
+    if (! isempty (c) && ! isempty (b))
+      ## Form a and b into combined set.
+      b = unique (b);
+      [dummy, idx] = sort ([c(:); b(:)]);
+      ## Eliminate those elements of a that are the same as in b.
+      if (iscellstr (dummy))
+        dups = find (strcmp (dummy(1:end-1), dummy(2:end)));
+      else
+	dups = find (dummy(1:end-1) == dummy(2:end));
+      endif
+      c(idx(dups)) = [];
+      if (nargout > 1)
+	i(idx(dups)) = [];
+      endif
+      ## Reshape if necessary.
+      if (size (c, 1) != 1 && size (b, 1) == 1)
+	c = c.';
+      endif
+    endif
+  endif
+  
+endfunction
+  
+%!assert(setdiff(["bb";"zz";"bb";"zz"],["bb";"cc";"bb"],"rows"), "zz")
+%!assert(setdiff(["b";"z";"b";"z"],["b";"c";"b"],"rows"), "z")
+%!assert(setdiff(["b";"z";"b";"z"],["b";"c";"b"]), "z")
+%!assert(setdiff([1, 1; 2, 2; 3, 3; 4, 4], [1, 1; 2, 2; 4, 4], "rows"), [3 3])
+%!assert(setdiff([1; 2; 3; 4], [1; 2; 4], "rows"), 3)
+%!assert(setdiff([1, 2; 3, 4], [1, 2; 3, 6], "rows"), [3, 4])
+%!assert(setdiff({"one","two";"three","four"},{"one","two";"three","six"}), {"four"})
+
+%!test
+%! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4];
+%! [y, i] = setdiff (a, b.');
+%! assert(y, [5]);
+%! assert(y, a(i));
diff --git a/scripts/set/setxor.m b/scripts/set/setxor.m
new file mode 100644
index 0000000..6a070e6
--- /dev/null
+++ b/scripts/set/setxor.m
@@ -0,0 +1,100 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+## Copyright (C) 2000, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} setxor (@var{a}, @var{b})
+## @deftypefnx {Function File} {} setxor (@var{a}, @var{b}, 'rows')
+##
+## Return the elements exclusive to @var{a} or @var{b}, sorted in ascending
+## order.  If @var{a} and @var{b} are both column vectors return a column
+## vector, otherwise return a row vector.
+##
+## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b})
+##
+## Return index vectors @var{ia} and @var{ib} such that @code{a == c(ia)} and
+## @code{b == c(ib)}.
+## 
+## @seealso{unique, union, intersect, setdiff, ismember}
+## @end deftypefn
+
+function [c, ia, ib] = setxor (a, b, varargin)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3 && ! strcmpi (varargin{1}, "rows"))
+    error ("setxor: if a third input argument is present, it must be the string 'rows'");
+  endif
+
+  ## Form A and B into sets.
+  if (nargout > 1)
+    [a, ia] = unique (a, varargin{:});
+    [b, ib] = unique (b, varargin{:});
+  else
+    a = unique (a, varargin{:});
+    b = unique (b, varargin{:});
+  endif
+
+  if (isempty (a))
+    c = b;
+  elseif (isempty (b))
+    c = a;
+  else
+    ## Reject duplicates.
+    if (nargin > 2)
+      na = rows (a); nb = rows (b);
+      [c, i] = sortrows ([a; b]);
+      n = rows (c);
+      idx = find (all (c(1:n-1) == c(2:n), 2));
+      if (! isempty (idx))
+	c([idx, idx+1],:) = [];
+	i([idx, idx+1],:) = [];
+      endif
+    else
+      na = numel (a); nb = numel (b);
+      [c, i] = sort ([a(:); b(:)]);
+      n = length (c);
+      if (iscell (c))
+        idx = find (strcmp (c(1:n-1), c(2:n)));	  
+      else
+        idx = find (c(1:n-1) == c(2:n));
+      endif
+      if (! isempty (idx))
+	c([idx, idx+1]) = [];
+	i([idx, idx+1]) = [];
+      endif
+      if (size (a, 1) == 1 || size (b, 1) == 1)
+	c = c.';
+      endif
+    endif
+  endif
+  if (nargout > 1)
+    ia = ia(i(i <= na));
+    ib = ib(i(i > na) - na);
+  endif
+
+endfunction
+
+%!assert(setxor([1,2,3],[2,3,4]),[1,4])
+%!test
+%! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4];
+%! [y, ia, ib] = setxor (a, b.');
+%! assert(y, [2, 5]);
+%! assert(y, sort([a(ia), b(ib)]));
diff --git a/scripts/set/union.m b/scripts/set/union.m
new file mode 100644
index 0000000..aec52cb
--- /dev/null
+++ b/scripts/set/union.m
@@ -0,0 +1,103 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2003, 2004, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} union (@var{a}, @var{b})
+## @deftypefnx{Function File} {} union (@var{a}, @var{b}, "rows")
+## Return the set of elements that are in either of the sets @var{a} and
+## @var{b}.  For example,
+##
+## @example
+## @group
+## union ([1, 2, 4], [2, 3, 5])
+##      @result{} [1, 2, 3, 4, 5]
+## @end group
+## @end example
+##
+## If the optional third input argument is the string "rows" each row of
+## the matrices @var{a} and @var{b} will be considered an element of sets.
+## For example,
+## @example
+## @group
+## union([1, 2; 2, 3], [1, 2; 3, 4], "rows")
+##      @result{}  1   2
+##     2   3
+##     3   4
+## @end group
+## @end example
+##
+## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@var{a}, @var{b})
+##
+## Return index vectors @var{ia} and @var{ib} such that @code{a == c(ia)} and
+## @code{b == c(ib)}.
+## 
+## @seealso{intersect, complement, unique}
+## @end deftypefn
+
+## Author: jwe
+
+function [y, ia, ib] = union (a, b, varargin)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3 && ! strcmpi (varargin{1}, "rows"))
+    error ("union: if a third input argument is present, it must be the string 'rows'");
+  endif
+
+  if (nargin == 2)
+    y = [a(:); b(:)];
+    na = numel (a); nb = numel (b);
+    if (size (a, 1) == 1 || size (b, 1) == 1)
+      y = y.';
+    endif
+  elseif (ndims (a) == 2 && ndims (b) == 2 && columns (a) == columns (b))
+    y = [a; b];
+    na = rows (a); nb = rows (b);
+  else
+    error ("union: input arguments must contain the same number of columns when \"rows\" is specified");
+  endif
+
+  if (nargout == 1)
+    y = unique (y, varargin{:});
+  else
+    [y, i] = unique (y, varargin{:});
+    ia = i(i <= na);
+    ib = i(i > na) - na;
+  endif
+
+endfunction
+
+%!assert(all (all (union ([1, 2, 4], [2, 3, 5]) == [1, 2, 3, 4, 5])));
+
+%!assert(all (all (union ([1; 2; 4], [2, 3, 5]) == [1, 2, 3, 4, 5])));
+
+%!assert(all (all (union ([1, 2, 3], [5; 7; 9]) == [1, 2, 3, 5, 7, 9])));
+
+%!error union (1);
+
+%!error union (1, 2, 3);
+
+%!test
+%! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4];
+%! [y, ia, ib] = union (a, b.');
+%! assert(y, [1, 2, 3, 4, 5]);
+%! assert(y, sort([a(ia), b(ib)]));
diff --git a/scripts/set/unique.m b/scripts/set/unique.m
new file mode 100644
index 0000000..e15af31
--- /dev/null
+++ b/scripts/set/unique.m
@@ -0,0 +1,163 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+## Copyright (C) 2000, 2001, 2005, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unique (@var{x})
+## @deftypefnx {Function File} {} unique (@var{x}, "rows")
+## @deftypefnx {Function File} {} unique (@dots{}, "first")
+## @deftypefnx {Function File} {} unique (@dots{}, "last")
+## @deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{})
+## Return the unique elements of @var{x}, sorted in ascending order.
+## If @var{x} is a row vector, return a row vector, but if @var{x}
+## is a column vector or a matrix return a column vector.
+##
+## If the optional argument @code{"rows"} is supplied, return the unique
+## rows of @var{x}, sorted in ascending order.
+##
+## If requested, return index vectors @var{i} and @var{j} such that
+## @code{x(i)==y} and @code{y(j)==x}.
+##
+## Additionally, one of @code{"first"} or @code{"last"} may be given as
+## an argument.  If @code{"last"} is specified, return the highest
+## possible indices in @var{i}, otherwise, if @code{"first"} is
+## specified, return the lowest.  The default is @code{"last"}.
+## @seealso{union, intersect, setdiff, setxor, ismember}
+## @end deftypefn
+
+function [y, i, j] = unique (x, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (nargin > 1)
+
+    ## parse options
+    if (iscellstr (varargin))
+      varargin = unique (varargin);
+      optfirst = strmatch ("first", varargin) > 0;
+      optlast = strmatch ("last", varargin) > 0;
+      optrows = strmatch ("rows", varargin) > 0 && size (x, 2) > 1;
+      if (optfirst && optlast)
+        error ("unique: cannot specify both \"last\" and \"first\"");
+      elseif (optfirst + optlast + optrows != nargin-1)
+        error ("unique: invalid option");
+      endif
+    else
+      error ("unique: options must be strings");
+    endif
+
+    if (optrows && iscell (x))
+      warning ("unique: 'rows' is ignored for cell arrays");
+      optrows = false;
+    endif
+
+  else
+    optfirst = 0;
+    optrows = 0;
+  endif
+
+  if (optrows)
+    n = size (x, 1);
+    dim = 1;
+  else
+    n = numel (x);
+    dim = (size (x, 1) == 1) + 1;
+  endif
+
+  y = x;
+  if (n < 1)
+    i = j = [];
+    return;
+  elseif (n < 2)
+    i = j = 1;
+    return;
+  endif
+
+  if (optrows)
+    [y, i] = sortrows (y);
+    match = all (y(1:n-1,:) == y(2:n,:), 2);
+    idx = find (match);
+    y(idx,:) = [];
+  else
+    if (size (y, 1) != 1)
+      y = y(:);
+    endif
+    [y, i] = sort (y);
+    if (iscell (y))
+      match = strcmp (y(1:n-1), y(2:n));
+    else
+      match = (y(1:n-1) == y(2:n));
+    endif
+    idx = find (match);
+    y(idx) = [];
+  endif
+
+  if (nargout >= 3)
+    j = i;
+    if (dim == 1)
+      j(i) = cumsum ([1; !match]);
+    else
+      j(i) = cumsum ([1, !match]);
+    endif
+  endif
+
+  if (optfirst)
+    i(idx+1) = [];
+  else
+    i(idx) = [];
+  endif
+
+
+endfunction
+
+%!assert(unique([1 1 2; 1 2 1; 1 1 2]),[1;2])
+%!assert(unique([1 1 2; 1 0 1; 1 1 2],'rows'),[1 0 1; 1 1 2])
+%!assert(unique([]),[])
+%!assert(unique([1]),[1])
+%!assert(unique([1 2]),[1 2])
+%!assert(unique([1;2]),[1;2])
+%!assert(unique([1,NaN,Inf,NaN,Inf]),[1,Inf,NaN,NaN])
+%!assert(unique({'Foo','Bar','Foo'}),{'Bar','Foo'})
+%!assert(unique({'Foo','Bar','FooBar'}'),{'Bar','Foo','FooBar'}')
+
+%!test
+%! [a,i,j] = unique([1,1,2,3,3,3,4]);
+%! assert(a,[1,2,3,4])
+%! assert(i,[2,3,6,7])
+%! assert(j,[1,1,2,3,3,3,4])
+%!
+%!test
+%! [a,i,j] = unique([1,1,2,3,3,3,4]','first');
+%! assert(a,[1,2,3,4]')
+%! assert(i,[1,3,4,7]')
+%! assert(j,[1,1,2,3,3,3,4]')
+%!
+%!test
+%! [a,i,j] = unique({'z'; 'z'; 'z'});
+%! assert(a,{'z'})
+%! assert(i,[3]')
+%! assert(j,[1,1,1]')
+%!
+%!test
+%! A=[1,2,3;1,2,3];
+%! [a,i,j] = unique(A,'rows');
+%! assert(a,[1,2,3])
+%! assert(A(i,:),a)
+%! assert(a(j,:),A)
diff --git a/scripts/signal/Makefile.in b/scripts/signal/Makefile.in
new file mode 100644
index 0000000..8ff7fea
--- /dev/null
+++ b/scripts/signal/Makefile.in
@@ -0,0 +1,91 @@
+# Makefile for octave's scripts/signal directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = signal
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = arch_fit.m arch_rnd.m arch_test.m arma_rnd.m autocor.m \
+  autocov.m autoreg_matrix.m bartlett.m blackman.m detrend.m \
+  diffpara.m durbinlevinson.m fftconv.m fftfilt.m fftshift.m \
+  filter2.m fractdiff.m freqz.m freqz_plot.m hamming.m hanning.m \
+  hurst.m ifftshift.m periodogram.m rectangle_lw.m rectangle_sw.m \
+  sinc.m sinetone.m sinewave.m spectral_adf.m spectral_xdf.m \
+  spencer.m stft.m synthesis.m triangle_lw.m triangle_sw.m \
+  unwrap.m yulewalker.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/signal
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/signal/arch_fit.m b/scripts/signal/arch_fit.m
new file mode 100644
index 0000000..f08f731
--- /dev/null
+++ b/scripts/signal/arch_fit.m
@@ -0,0 +1,119 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{a}, @var{b}] =} arch_fit (@var{y}, @var{x}, @var{p}, @var{iter}, @var{gamma}, @var{a0}, @var{b0})
+## Fit an ARCH regression model to the time series @var{y} using the
+## scoring algorithm in Engle's original ARCH paper.  The model is
+##
+## @example
+## @group
+## y(t) = b(1) * x(t,1) + @dots{} + b(k) * x(t,k) + e(t),
+## h(t) = a(1) + a(2) * e(t-1)^2 + @dots{} + a(p+1) * e(t-p)^2
+## @end group
+## @end example
+##
+## @noindent
+## in which @math{e(t)} is @math{N(0, h(t))}, given a time-series vector
+## @var{y} up to time @math{t-1} and a matrix of (ordinary) regressors
+## @var{x} up to @math{t}.  The order of the regression of the residual
+## variance is specified by @var{p}.
+##
+## If invoked as @code{arch_fit (@var{y}, @var{k}, @var{p})} with a
+## positive integer @var{k}, fit an ARCH(@var{k}, @var{p}) process,
+## i.e., do the above with the @math{t}-th row of @var{x} given by
+##
+## @example
+## [1, y(t-1), @dots{}, y(t-k)]
+## @end example
+##
+## Optionally, one can specify the number of iterations @var{iter}, the
+## updating factor @var{gamma}, and initial values @math{a0} and
+## @math{b0} for the scoring algorithm.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Fit an ARCH regression model
+
+function [a, b] = arch_fit (y, X, p, ITER, gamma, a0, b0)
+
+  if ((nargin < 3) || (nargin == 6) || (nargin > 7))
+    print_usage ();
+  endif
+
+  if (! (isvector (y)))
+    error ("arch_test: y must be a vector");
+  endif
+
+  T   = length (y);
+  y   = reshape (y, T, 1);
+  [rx, cx] = size (X);
+  if ((rx == 1) && (cx == 1))
+    X = autoreg_matrix (y, X);
+  elseif (! (rx == T))
+    error ("arch_test: either rows (X) == length (y), or X is a scalar");
+  endif
+
+  [T, k] = size (X);
+
+  if (nargin == 7)
+    a   = a0;
+    b   = b0;
+    e   = y - X * b;
+  else
+    [b, v_b, e] = ols (y, X);
+    a   = [v_b, (zeros (1, p))]';
+    if (nargin < 5)
+      gamma = 0.1;
+      if (nargin < 4)
+        ITER = 50;
+      endif
+    endif
+  endif
+
+  esq = e.^2;
+  Z   = autoreg_matrix (esq, p);
+
+  for i = 1 : ITER;
+    h    = Z * a;
+    tmp  = esq ./ h.^2 - 1 ./ h;
+    s    = 1 ./ h(1:T-p);
+    for j = 1 : p;
+      s = s - a(j+1) * tmp(j+1:T-p+j);
+    endfor
+    r    = 1 ./ h(1:T-p);
+    for j = 1:p;
+      r = r + 2 * h(j+1:T-p+j).^2 .* esq(1:T-p);
+    endfor
+    r   = sqrt (r);
+    X_tilde = X(1:T-p, :) .* (r * ones (1,k));
+    e_tilde = e(1:T-p) .*s ./ r;
+    delta_b = inv (X_tilde' * X_tilde) * X_tilde' * e_tilde;
+    b   = b + gamma * delta_b;
+    e   = y - X * b;
+    esq = e .^ 2;
+    Z   = autoreg_matrix (esq, p);
+    h   = Z * a;
+    f   = esq ./ h - ones(T,1);
+    Z_tilde = Z ./ (h * ones (1, p+1));
+    delta_a = inv (Z_tilde' * Z_tilde) * Z_tilde' * f;
+    a   = a + gamma * delta_a;
+  endfor
+
+endfunction
diff --git a/scripts/signal/arch_rnd.m b/scripts/signal/arch_rnd.m
new file mode 100644
index 0000000..ce132f2
--- /dev/null
+++ b/scripts/signal/arch_rnd.m
@@ -0,0 +1,103 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} arch_rnd (@var{a}, @var{b}, @var{t})
+## Simulate an ARCH sequence of length @var{t} with AR
+## coefficients @var{b} and CH coefficients @var{a}.  I.e., the result
+## @math{y(t)} follows the model
+##
+## @c Set example in small font to prevent overfull line
+## @smallexample
+## y(t) = b(1) + b(2) * y(t-1) + @dots{} + b(lb) * y(t-lb+1) + e(t),
+## @end smallexample
+##
+## @noindent
+## where @math{e(t)}, given @var{y} up to time @math{t-1}, is
+## @math{N(0, h(t))}, with
+##
+## @c Set example in small font to prevent overfull line
+## @smallexample
+## h(t) = a(1) + a(2) * e(t-1)^2 + @dots{} + a(la) * e(t-la+1)^2
+## @end smallexample
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Simulate an ARCH process
+
+function y = arch_rnd (a, b, T)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! ((min (size (a)) == 1) && (min (size (b)) == 1)))
+    error ("arch_rnd: a and b must both be scalars or vectors");
+  endif
+  if (! (isscalar (T) && (T > 0) && (rem (T, 1) == 0)))
+    error ("arch_rnd: T must be a positive integer");
+  endif
+
+  if (! (a(1) > 0))
+    error ("arch_rnd: a(1) must be positive");
+  endif
+  ## perhaps add a test for the roots of a(z) here ...
+
+  la = length (a);
+  a  = reshape (a, 1, la);
+  if (la == 1)
+    a  = [a, 0];
+    la = la + 1;
+  endif
+
+  lb = length (b);
+  b  = reshape (b, 1, lb);
+  if (lb == 1)
+    b  = [b, 0];
+    lb = lb + 1;
+  endif
+  M  = max([la, lb]);
+
+  e  = zeros (T, 1);
+  h  = zeros (T, 1);
+  y  = zeros (T, 1);
+
+  h(1) = a(1);
+  e(1) = sqrt (h(1)) * randn;
+  y(1) = b(1) + e(1);
+
+  for t = 2:M
+    ta   = min ([t, la]);
+    h(t) = a(1) + a(2:ta) * e(t-ta+1:t-1).^2;
+    e(t) = sqrt (h(t)) * randn;
+    tb   = min ([t, lb]);
+    y(t) = b(1) + b(2:tb) * y(t-tb+1:t-1) + e(t);
+  endfor
+
+  if (T > M)
+    for t = M+1:T
+      h(t) = a(1) + a(2:la) * e(t-la+1:t-1).^2;
+      e(t) = sqrt (h(t)) * randn;
+      y(t) = b(1) + b(2:lb) * y(t-tb+1:t-1) + e(t);
+    endfor
+  endif
+
+  y = y(1:T);
+
+endfunction
diff --git a/scripts/signal/arch_test.m b/scripts/signal/arch_test.m
new file mode 100644
index 0000000..45621fb
--- /dev/null
+++ b/scripts/signal/arch_test.m
@@ -0,0 +1,97 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{lm}] =} arch_test (@var{y}, @var{x}, @var{p})
+## For a linear regression model
+##
+## @example
+## y = x * b + e
+## @end example
+##
+## @noindent
+## perform a Lagrange Multiplier (LM) test of the null hypothesis of no
+## conditional heteroscedascity against the alternative of CH(@var{p}).
+##
+## I.e., the model is
+##
+## @example
+## y(t) = b(1) * x(t,1) + @dots{} + b(k) * x(t,k) + e(t),
+## @end example
+##
+## @noindent
+## given @var{y} up to @math{t-1} and @var{x} up to @math{t},
+## @math{e}(t) is @math{N(0, h(t))} with
+##
+## @example
+## h(t) = v + a(1) * e(t-1)^2 + @dots{} + a(p) * e(t-p)^2,
+## @end example
+##
+## @noindent
+## and the null is @math{a(1)} == @dots{} == @math{a(p)} == 0.
+##
+## If the second argument is a scalar integer, @math{k}, perform the same
+## test in a linear autoregression model of order @math{k}, i.e., with
+##
+## @example
+## [1, y(t-1), @dots{}, y(t- at var{k})]
+## @end example
+##
+## @noindent
+## as the @math{t}-th row of @var{x}.
+##
+## Under the null, LM approximately has a chisquare distribution with
+## @var{p} degrees of freedom and @var{pval} is the @math{p}-value (1
+## minus the CDF of this distribution at LM) of the test.
+##
+## If no output argument is given, the @math{p}-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Test for conditional heteroscedascity
+
+function [pval, lm] = arch_test (y, X, p)
+
+  if (nargin != 3)
+    error ("arch_test needs 3 input arguments");
+  endif
+
+  if (! (isvector (y)))
+    error ("arch_test: y must be a vector");
+  endif
+  T   = length (y);
+  y   = reshape (y, T, 1);
+  [rx, cx] = size (X);
+  if ((rx == 1) && (cx == 1))
+    X = autoreg_matrix (y, X);
+  elseif (! (rx == T))
+    error ("arch_test: either rows(X) == length(y), or X is a scalar");
+  endif
+  if (! (isscalar(p) && (rem(p, 1) == 0) && (p > 0)))
+    error ("arch_test: p must be a positive integer");
+  endif
+
+  [b, v_b, e] = ols (y, X);
+  Z    = autoreg_matrix (e.^2, p);
+  f    = e.^2 / v_b - ones (T, 1);
+  f    = Z' * f;
+  lm   = f' * inv (Z'*Z) * f / 2;
+  pval = 1 - chisquare_cdf (lm, p);
+
+endfunction
\ No newline at end of file
diff --git a/scripts/signal/arma_rnd.m b/scripts/signal/arma_rnd.m
new file mode 100644
index 0000000..e4fbf14
--- /dev/null
+++ b/scripts/signal/arma_rnd.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2005, 2006,
+##               2007, 2009 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} arma_rnd (@var{a}, @var{b}, @var{v}, @var{t}, @var{n})
+## Return a simulation of the ARMA model
+##
+## @example
+## @group
+## x(n) = a(1) * x(n-1) + @dots{} + a(k) * x(n-k)
+##      + e(n) + b(1) * e(n-1) + @dots{} + b(l) * e(n-l)
+## @end group
+## @end example
+##
+## @noindent
+## in which @var{k} is the length of vector @var{a}, @var{l} is the
+## length of vector @var{b} and @var{e} is Gaussian white noise with
+## variance @var{v}.  The function returns a vector of length @var{t}.
+##
+## The optional parameter @var{n} gives the number of dummy
+## @var{x}(@var{i}) used for initialization, i.e., a sequence of length
+## @var{t}+ at var{n} is generated and @var{x}(@var{n}+1:@var{t}+ at var{n})
+## is returned.  If @var{n} is omitted, @var{n} = 100 is used. 
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Simulate an ARMA process
+
+function x = arma_rnd (a, b, v, t, n)
+
+  if (nargin == 4)
+    n = 100;
+  elseif (nargin == 5)
+    if (!isscalar (t))
+      error ("arma_rnd: n must be a scalar");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if ((min (size (a)) > 1) || (min (size (b)) > 1))
+    error ("arma_rnd: a and b must not be matrices");
+  endif
+
+  if (!isscalar (t))
+    error ("arma_rnd: t must be a scalar");
+  endif
+
+  ar = length (a);
+  br = length (b);
+
+  a = reshape (a, ar, 1);
+  b = reshape (b, br, 1);
+
+  ## Apply our notational convention.
+  a = [1; -a];
+  b = [1; b];
+
+  n = min (n, ar + br);
+
+  e = sqrt (v) * randn (t + n, 1);
+
+  x = filter (b, a, e);
+  x = x(n + 1 : t + n);
+
+endfunction
diff --git a/scripts/signal/autocor.m b/scripts/signal/autocor.m
new file mode 100644
index 0000000..a76e608
--- /dev/null
+++ b/scripts/signal/autocor.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} autocor (@var{x}, @var{h})
+## Return the autocorrelations from lag 0 to @var{h} of vector @var{x}.
+## If @var{h} is omitted, all autocorrelations are computed.
+## If @var{x} is a matrix, the autocorrelations of each column are
+## computed.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Compute autocorrelations
+
+function retval = autocor (X, h)
+
+  if (nargin == 1)
+    retval = autocov (X);
+  elseif (nargin == 2)
+    retval = autocov (X, h);
+  else
+    print_usage ();
+  endif
+
+  if (min (retval (1,:)) != 0)
+    retval = retval ./ (ones (rows (retval), 1) * retval(1,:));
+  endif
+
+endfunction
+
+
+
diff --git a/scripts/signal/autocov.m b/scripts/signal/autocov.m
new file mode 100644
index 0000000..d07b511
--- /dev/null
+++ b/scripts/signal/autocov.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005,
+##               2007 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} autocov (@var{x}, @var{h})
+## Return the autocovariances from lag 0 to @var{h} of vector @var{x}.
+## If @var{h} is omitted, all autocovariances are computed.
+## If @var{x} is a matrix, the autocovariances of each column are
+## computed.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Compute autocovariances
+
+function retval = autocov (X, h)
+
+  [n, c] = size (X);
+
+  if (isvector (X))
+    n = length (X);
+    c = 1;
+    X = reshape (X, n, 1);
+  endif
+
+  X = center (X);
+
+  if (nargin == 1)
+    h = n - 1;
+  endif
+
+  retval = zeros (h + 1, c);
+
+  for i = 0 : h
+    retval(i+1, :) = diag (X(i+1:n, :).' * conj (X(1:n-i, :))).' / n;
+  endfor
+
+endfunction
diff --git a/scripts/signal/autoreg_matrix.m b/scripts/signal/autoreg_matrix.m
new file mode 100644
index 0000000..17b3c58
--- /dev/null
+++ b/scripts/signal/autoreg_matrix.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} autoreg_matrix (@var{y}, @var{k})
+## Given a time series (vector) @var{y}, return a matrix with ones in the
+## first column and the first @var{k} lagged values of @var{y} in the
+## other columns.  I.e., for @var{t} > @var{k}, @code{[1,
+## @var{y}(@var{t}-1), @dots{}, @var{y}(@var{t}- at var{k})]} is the t-th row
+## of the result.  The resulting matrix may be used as a regressor matrix
+## in autoregressions.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Design matrix for autoregressions
+
+function X = autoreg_matrix (y, k)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! (isvector (y)))
+    error ("autoreg_matrix: y must be a vector");
+  endif
+
+  T = length (y);
+  y = reshape (y, T, 1);
+  X = ones (T, k+1);
+  for j = 1 : k;
+    X(:, j+1) = [(zeros (j, 1)); y(1:T-j)];
+  endfor
+
+endfunction
diff --git a/scripts/signal/bartlett.m b/scripts/signal/bartlett.m
new file mode 100644
index 0000000..eb36647
--- /dev/null
+++ b/scripts/signal/bartlett.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bartlett (@var{m})
+## Return the filter coefficients of a Bartlett (triangular) window of
+## length @var{m}.
+##
+## For a definition of the Bartlett window, see e.g., A. V. Oppenheim &
+## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Coefficients of the Bartlett (triangular) window
+
+function c = bartlett (m)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isscalar (m) && (m == round (m)) && (m > 0)))
+    error ("bartlett: m has to be an integer > 0");
+  endif
+
+  if (m == 1)
+    c = 1;
+  else
+    m = m - 1;
+    n = fix (m / 2);
+    c = [2*(0:n)/m, 2-2*(n+1:m)/m]';
+  endif
+
+endfunction
diff --git a/scripts/signal/blackman.m b/scripts/signal/blackman.m
new file mode 100644
index 0000000..c0bc3dc
--- /dev/null
+++ b/scripts/signal/blackman.m
@@ -0,0 +1,49 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} blackman (@var{m})
+## Return the filter coefficients of a Blackman window of length @var{m}.
+##
+## For a definition of the Blackman window, see e.g., A. V. Oppenheim &
+## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Coefficients of the Blackman window
+
+function c = blackman (m)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isscalar (m) && (m == round (m)) && (m > 0)))
+    error ("blackman: m has to be an integer > 0");
+  endif
+
+  if (m == 1)
+    c = 1;
+  else
+    m = m - 1;
+    k = (0 : m)' / m;
+    c = 0.42 - 0.5 * cos (2 * pi * k) + 0.08 * cos (4 * pi * k);
+  endif
+
+endfunction
diff --git a/scripts/signal/detrend.m b/scripts/signal/detrend.m
new file mode 100644
index 0000000..f509ee6
--- /dev/null
+++ b/scripts/signal/detrend.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} detrend (@var{x}, @var{p})
+## If @var{x} is a vector, @code{detrend (@var{x}, @var{p})} removes the
+## best fit of a polynomial of order @var{p} from the data @var{x}.
+##
+## If @var{x} is a matrix, @code{detrend (@var{x}, @var{p})} does the same
+## for each column in @var{x}.
+##
+## The second argument is optional.  If it is not specified, a value of 1
+## is assumed.  This corresponds to removing a linear trend.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 11 October 1994
+## Adapted-By: jwe
+
+function y = detrend (x, p)
+
+  if (nargin == 1)
+    p = 1;
+  elseif (nargin == 2)
+    if (! (isscalar (p) && p == round (p) && p >= 0))
+      error ("detrend: p must be a nonnegative integer");
+    endif
+  else
+    print_usage ();
+  endif
+
+  [m, n] = size (x);
+  if (m == 1)
+    x = x';
+  endif
+
+  r = rows (x);
+  b = ((1 : r)' * ones (1, p + 1)) .^ (ones (r, 1) * (0 : p));
+  y = x - b * (b \ x);
+
+  if (m == 1)
+    y = y';
+  endif
+
+endfunction
+
+%!test
+%! N=32;
+%! x = (0:1:N-1)/N + 2;
+%! y = detrend(x);
+%! assert(all (all (abs (y) < 20*eps)));
+
+%!test
+%! N=32;
+%! t = (0:1:N-1)/N;
+%! x = t .* t + 2;
+%! y = detrend(x,2);
+%! assert(all (all (abs (y) < 30*eps)));
+
+%!test
+%! N=32;
+%! t = (0:1:N-1)/N;
+%! x = [t;4*t-3]';
+%! y = detrend(x);
+%! assert(all (all (abs (y) < 20*eps)));
+
diff --git a/scripts/signal/diffpara.m b/scripts/signal/diffpara.m
new file mode 100644
index 0000000..7528626
--- /dev/null
+++ b/scripts/signal/diffpara.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{d}, @var{dd}] =} diffpara (@var{x}, @var{a}, @var{b})
+## Return the estimator @var{d} for the differencing parameter of an
+## integrated time series.
+##
+## The frequencies from @math{[2*pi*a/t, 2*pi*b/T]} are used for the
+## estimation.  If @var{b} is omitted, the interval
+## @math{[2*pi/T, 2*pi*a/T]} is used.  If both @var{b} and @var{a} are
+## omitted then @math{a = 0.5 * sqrt (T)} and @math{b = 1.5 * sqrt (T)}
+## is used, where @math{T} is the sample size.  If @var{x} is a matrix,
+## the differencing parameter of each column is estimated.
+##
+## The estimators for all frequencies in the intervals
+## described above is returned in @var{dd}.  The value of @var{d} is
+## simply the mean of @var{dd}.
+##
+## Reference: Brockwell, Peter J. & Davis, Richard A. Time Series:
+## Theory and Methods Springer 1987.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Estimate the fractional differencing parameter
+
+function [d, D] = diffpara (X, a, b)
+
+  if ((nargin < 1) || (nargin > 3))
+    print_usage ();
+  else
+    if (isvector (X))
+      n = length (X);
+      k = 1;
+      X = reshape (X, n, 1);
+    else
+      [n, k] = size(X);
+    endif
+    if (nargin == 1)
+      a = 0.5 * sqrt (n);
+      b = 1.5 * sqrt (n);
+    elseif (nargin == 2)
+      b = a;
+      a = 1;
+    endif
+  endif
+
+  if (! (isscalar (a) && isscalar (b)))
+    error ("diffpara: a and b must be scalars");
+  endif
+
+  D = zeros (b - a + 1, k);
+
+  for l = 1:k
+
+    w = 2 * pi * (1 : n-1) / n;
+
+    x = 2 * log (abs (1 - exp (-i*w)));
+    y = log (periodogram (X(2:n,l)));
+
+    x = center (x);
+    y = center (y);
+
+    for m = a:b
+      D(m-a+1) = - x(1:m) * y(1:m) / sumsq (x(1:m));
+    endfor
+
+  endfor
+
+  d = mean (D);
+
+endfunction
+
diff --git a/scripts/signal/durbinlevinson.m b/scripts/signal/durbinlevinson.m
new file mode 100644
index 0000000..cfb294c
--- /dev/null
+++ b/scripts/signal/durbinlevinson.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1995, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} durbinlevinson (@var{c}, @var{oldphi}, @var{oldv})
+## Perform one step of the Durbin-Levinson algorithm.
+##
+## The vector @var{c} specifies the autocovariances @code{[gamma_0, @dots{},
+## gamma_t]} from lag 0 to @var{t}, @var{oldphi} specifies the
+## coefficients based on @var{c}(@var{t}-1) and @var{oldv} specifies the
+## corresponding error.
+##
+## If @var{oldphi} and @var{oldv} are omitted, all steps from 1 to
+## @var{t} of the algorithm are performed.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Perform one step of the Durbin-Levinson algorithm
+
+function [newphi, newv] = durbinlevinson (c, oldphi, oldv)
+
+  if (! ((nargin == 1) || (nargin == 3)))
+    print_usage ();
+  endif
+
+  if (columns (c) > 1)
+    c = c';
+  endif
+
+  newphi = 0;
+  newv = 0;
+
+  if (nargin == 3)
+
+    t = length (oldphi) + 1;
+
+    if (length (c) < t+1)
+      error ("durbilevinson: c too small");
+    endif
+
+    if (oldv == 0)
+      error ("durbinlevinson: oldv = 0");
+    endif
+
+    if (rows (oldphi) > 1)
+      oldphi = oldphi';
+    endif
+
+    newphi = zeros (1, t);
+    newphi(1) = (c(t+1) - oldphi * c(2:t)) / oldv;
+    for i = 2 : t
+      newphi(i) = oldphi(i-1) - newphi(1) * oldphi(t-i+1);
+    endfor
+    newv = (1 - newphi(1)^2) * oldv;
+
+  elseif(nargin == 1)
+
+    tt = length (c)-1;
+    oldphi = c(2) / c(1);
+    oldv = (1 - oldphi^2) * c(1);
+
+    for t = 2 : tt
+
+      newphi = zeros (1, t);
+      newphi(1) = (c(t+1) - oldphi * c(2:t)) / oldv;
+      for i = 2 : t
+        newphi(i) = oldphi(i-1) - newphi(1) * oldphi(t-i+1);
+      endfor
+      newv = (1 - newphi(1)^2) * oldv;
+
+      oldv = newv;
+      oldphi = newphi;
+
+    endfor
+
+  endif
+
+endfunction
diff --git a/scripts/signal/fftconv.m b/scripts/signal/fftconv.m
new file mode 100644
index 0000000..0e687a9
--- /dev/null
+++ b/scripts/signal/fftconv.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fftconv (@var{a}, @var{b}, @var{n})
+## Return the convolution of the vectors @var{a} and @var{b}, as a vector
+## with length equal to the @code{length (a) + length (b) - 1}.  If @var{a}
+## and @var{b} are the coefficient vectors of two polynomials, the returned
+## value is the coefficient vector of the product polynomial.
+##
+## The computation uses the FFT by calling the function @code{fftfilt}.  If
+## the optional argument @var{n} is specified, an N-point FFT is used.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 3 September 1994
+## Adapted-By: jwe
+
+function c = fftconv (a, b, N)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (! (isvector (a) && isvector (b)))
+    error ("fftconv: both a and b should be vectors");
+  endif
+  la = length (a);
+  lb = length (b);
+  if ((la == 1) || (lb == 1))
+    c = a * b;
+  else
+    lc = la + lb - 1;
+    a(lc) = 0;
+    b(lc) = 0;
+    if (nargin == 2)
+      c = fftfilt (a, b);
+    else
+      if (! (isscalar (N)))
+        error ("fftconv: N has to be a scalar");
+      endif
+      c = fftfilt (a, b, N);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/signal/fftfilt.m b/scripts/signal/fftfilt.m
new file mode 100644
index 0000000..1dbd6e3
--- /dev/null
+++ b/scripts/signal/fftfilt.m
@@ -0,0 +1,108 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fftfilt (@var{b}, @var{x}, @var{n})
+##
+## With two arguments, @code{fftfilt} filters @var{x} with the FIR filter
+## @var{b} using the FFT.
+##
+## Given the optional third argument, @var{n}, @code{fftfilt} uses the
+## overlap-add method to filter @var{x} with @var{b} using an N-point FFT.
+##
+## If @var{x} is a matrix, filter each column of the matrix.
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Created: 3 September 1994
+## Adapted-By: jwe
+
+function y = fftfilt (b, x, N)
+
+  ## If N is not specified explicitly, we do not use the overlap-add
+  ## method at all because loops are really slow.  Otherwise, we only
+  ## ensure that the number of points in the FFT is the smallest power
+  ## of two larger than N and length(b).  This could result in length
+  ## one blocks, but if the user knows better ...
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  transpose = (rows (x) == 1);
+
+  if (transpose)
+    x = x.';
+  endif
+
+  [r_x, c_x] = size (x);
+  [r_b, c_b] = size (b);
+
+  if min ([r_b, c_b]) != 1
+    error ("fftfilt: b should be a vector");
+  endif
+
+  l_b = r_b * c_b;
+  b = reshape (b, l_b, 1);
+
+  if (nargin == 2)
+    ## Use FFT with the smallest power of 2 which is >= length (x) +
+    ## length (b) - 1 as number of points ...
+    N = 2 ^ (ceil (log (r_x + l_b - 1) / log (2)));
+    B = fft (b, N);
+    y = ifft (fft (x, N) .* B(:,ones (1, c_x)));
+  else
+    ## Use overlap-add method ...
+    if (! (isscalar (N)))
+      error ("fftfilt: N has to be a scalar");
+    endif
+    N = 2 ^ (ceil (log (max ([N, l_b])) / log (2)));
+    L = N - l_b + 1;
+    B = fft (b, N);
+    B = B(:,ones (c_x,1));
+    R = ceil (r_x / L);
+    y = zeros (r_x, c_x);
+    for r = 1:R;
+      lo = (r - 1) * L + 1;
+      hi = min (r * L, r_x);
+      tmp = zeros (N, c_x);
+      tmp(1:(hi-lo+1),:) = x(lo:hi,:);
+      tmp = ifft (fft (tmp) .* B);
+      hi  = min (lo+N-1, r_x);
+      y(lo:hi,:) = y(lo:hi,:) + tmp(1:(hi-lo+1),:);
+    endfor
+  endif
+
+  y = y(1:r_x,:);
+  if (transpose)
+    y = y.';
+  endif
+
+  ## Final cleanups: if both x and b are real respectively integer, y
+  ## should also be
+
+  if (isreal (b) && isreal (x))
+    y = real (y);
+  endif
+  if (! any (b - round (b)))
+    idx = !any (x - round (x));
+    y(:,idx) = round (y(:,idx));
+  endif
+
+endfunction
diff --git a/scripts/signal/fftshift.m b/scripts/signal/fftshift.m
new file mode 100644
index 0000000..ce001f2
--- /dev/null
+++ b/scripts/signal/fftshift.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007, 2009
+##               Vincent Cautaerts
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fftshift (@var{v})
+## @deftypefnx {Function File} {} fftshift (@var{v}, @var{dim})
+## Perform a shift of the vector @var{v}, for use with the @code{fft}
+## and @code{ifft} functions, in order the move the frequency 0 to the
+## center of the vector or matrix.
+##
+## If @var{v} is a vector of @math{N} elements corresponding to @math{N}
+## time samples spaced of @math{Dt} each, then @code{fftshift (fft
+## (@var{v}))} corresponds to frequencies
+##
+## @example
+## f = ((1:N) - ceil(N/2)) / N / Dt
+## @end example
+##
+## If @var{v} is a matrix, the same holds for rows and columns.  If 
+## @var{v} is an array, then the same holds along each dimension.
+##
+## The optional @var{dim} argument can be used to limit the dimension
+## along which the permutation occurs.
+## @end deftypefn
+
+## Author: Vincent Cautaerts <vincent at comf5.comm.eng.osaka-u.ac.jp>
+## Created: July 1997
+## Adapted-By: jwe
+
+function retval = fftshift (V, dim)
+
+  retval = 0;
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    if (!isscalar (dim))
+      error ("fftshift: dimension must be an integer scalar");
+    endif
+    nd = ndims (V);
+    sz = size (V);
+    sz2 = ceil (sz(dim) / 2);
+    idx = cell ();
+    for i = 1:nd
+      idx{i} = 1:sz(i);
+    endfor
+    idx{dim} = [sz2+1:sz(dim), 1:sz2];
+    retval = V (idx{:});
+  else
+    if (isvector (V))
+      x = length (V);
+      xx = ceil (x/2);
+      retval = V([xx+1:x, 1:xx]);
+    elseif (ismatrix (V))
+      nd = ndims (V);
+      sz = size (V);
+      sz2 = ceil (sz ./ 2);
+      idx = cell ();
+      for i = 1:nd
+        idx{i} = [sz2(i)+1:sz(i), 1:sz2(i)];
+      endfor
+      retval = V (idx{:});
+    else
+      error ("fftshift: expecting vector or matrix argument");
+    endif
+  endif
+
+endfunction
diff --git a/scripts/signal/filter2.m b/scripts/signal/filter2.m
new file mode 100644
index 0000000..2c26420
--- /dev/null
+++ b/scripts/signal/filter2.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2001, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} filter2 (@var{b}, @var{x})
+## @deftypefnx {Function File} {@var{y} =} filter2 (@var{b}, @var{x}, @var{shape})
+## Apply the 2-D FIR filter @var{b} to @var{x}.  If the argument
+## @var{shape} is specified, return an array of the desired shape.
+## Possible values are: 
+##
+## @table @asis
+## @item 'full'
+## pad @var{x} with zeros on all sides before filtering.
+## @item 'same'
+## unpadded @var{x} (default)
+## @item 'valid'
+## trim @var{x} after filtering so edge effects are no included.
+## @end table
+##
+## Note this is just a variation on convolution, with the parameters
+## reversed and @var{b} rotated 180 degrees.
+## @seealso{conv2}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+## 2001-02-08 
+##    * initial release
+
+function Y = filter2 (B, X, shape)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+  if (nargin < 3)
+    shape = "same";
+  endif
+
+  [nr, nc] = size(B);
+  Y = conv2 (X, B(nr:-1:1, nc:-1:1), shape);
+endfunction
diff --git a/scripts/signal/fractdiff.m b/scripts/signal/fractdiff.m
new file mode 100644
index 0000000..ad7d758
--- /dev/null
+++ b/scripts/signal/fractdiff.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2007, 2009
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fractdiff (@var{x}, @var{d})
+## Compute the fractional differences @math{(1-L)^d x} where @math{L}
+## denotes the lag-operator and @math{d} is greater than -1.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Compute fractional differences
+
+function retval = fractdiff (x, d)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  N = 100;
+
+  if (! isvector (x))
+    error ("fractdiff: x must be a vector");
+  endif
+
+  if (! isscalar (d))
+    error ("fractdiff: d must be a scalar");
+  endif
+
+
+  if (d >= 1)
+    for k = 1 : d
+      x = x(2 : length (x)) - x(1 : length (x) - 1);
+    endfor
+  endif
+
+  if (d > -1)
+
+    d = rem (d, 1);
+
+    if (d != 0)
+      n = (0 : N)';
+      w = real (gamma (-d+n) ./ gamma (-d) ./ gamma (n+1));
+      retval = fftfilt (w, x);
+      retval = retval(1 : length (x));
+    else
+      retval = x;
+    endif
+
+  else
+    error ("fractdiff: d must be > -1");
+
+  endif
+
+endfunction
diff --git a/scripts/signal/freqz.m b/scripts/signal/freqz.m
new file mode 100644
index 0000000..8e357cd
--- /dev/null
+++ b/scripts/signal/freqz.m
@@ -0,0 +1,198 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{h}, @var{w}] =} freqz (@var{b}, @var{a}, @var{n}, "whole")
+## Return the complex frequency response @var{h} of the rational IIR filter
+## whose numerator and denominator coefficients are @var{b} and @var{a},
+## respectively.  The response is evaluated at @var{n} angular frequencies
+## between 0 and
+## @ifnottex
+##  2*pi.
+## @end ifnottex
+## @tex
+##  $2\pi$.
+## @end tex
+##
+## @noindent
+## The output value @var{w} is a vector of the frequencies.
+##
+## If the fourth argument is omitted, the response is evaluated at
+## frequencies between 0 and
+## @ifnottex
+##  pi.
+## @end ifnottex
+## @tex
+##  $\pi$.
+## @end tex
+##
+## If @var{n} is omitted, a value of 512 is assumed.
+##
+## If @var{a} is omitted, the denominator is assumed to be 1 (this
+## corresponds to a simple FIR filter).
+##
+## For fastest computation, @var{n} should factor into a small number of
+## small primes.
+##
+## @deftypefnx {Function File} {@var{h} =} freqz (@var{b}, @var{a}, @var{w})
+## Evaluate the response at the specific frequencies in the vector @var{w}.
+## The values for @var{w} are measured in radians.
+##
+## @deftypefnx {Function File} {[@dots{}] =} freqz (@dots{}, @var{Fs})
+## Return frequencies in Hz instead of radians assuming a sampling rate
+## @var{Fs}.  If you are evaluating the response at specific frequencies 
+## @var{w}, those frequencies should be requested in Hz rather than radians.
+##
+## @deftypefnx {Function File} {} freqz (@dots{})
+## Plot the pass band, stop band and phase response of @var{h} rather
+## than returning them.
+## @end deftypefn
+
+## Author: jwe ???
+
+function [h_r, f_r] = freqz (b, a, n, region, Fs)
+
+  if (nargin < 1 || nargin > 5)
+    print_usage ();
+  elseif (nargin == 1)
+    ## Response of an FIR filter.
+    a = n = region = Fs = [];
+  elseif (nargin == 2)
+    ## Response of an IIR filter
+    n = region = Fs = [];
+  elseif (nargin == 3)
+    region = Fs = [];
+  elseif (nargin == 4)
+    Fs = [];
+    if (! ischar (region) && ! isempty (region))
+      Fs = region; 
+      region = [];
+    endif
+  endif
+
+  if (isempty (b))
+    b = 1;
+  endif
+  if (isempty (a)) 
+    a = 1; 
+  endif
+  if (isempty (n))
+    n = 512; 
+  endif
+  if (isempty (region))
+    if (isreal (b) && isreal (a))
+      region = "half";
+    else
+      region = "whole";
+    endif
+  endif
+  if (isempty (Fs)) 
+    if (nargout == 0) 
+      Fs = 2; 
+    else 
+      Fs = 2*pi; 
+    endif
+  endif
+
+  a = a(:);
+  b = b(:);
+
+  if (! isscalar (n))
+    ## Explicit frequency vector given
+    w = f = n;
+    if (nargin == 4)
+      ## Sampling rate Fs was specified
+      w = 2*pi*f/Fs;
+    endif
+    k = max (length (b), length (a));
+    hb = polyval (postpad (b, k), exp (j*w));
+    ha = polyval (postpad (a, k), exp (j*w));
+  else
+    ## polyval(fliplr(P),exp(jw)) is O(p n) and fft(x) is O(n log(n)),
+    ## where p is the order of the polynomial P.  For small p it
+    ## would be faster to use polyval but in practice the overhead for
+    ## polyval is much higher and the little bit of time saved isn't
+    ## worth the extra code.
+    k = max (length (b), length (a));
+    if (k > n/2 && nargout == 0)
+      ## Ensure a causal phase response.
+      n = n * 2 .^ ceil (log2 (2*k/n));
+    endif
+
+    if (strcmp (region, "whole"))
+      N = n;
+    else
+      N = 2*n;
+    endif
+
+    f = Fs * (0:n-1).' / N;
+
+    pad_sz = N*ceil (k/N);
+    b = postpad (b, pad_sz);
+    a = postpad (a, pad_sz);
+
+    hb = zeros (n, 1);
+    ha = zeros (n, 1);
+
+    for i = 1:N:pad_sz
+      hb = hb + fft (postpad (b(i:i+N-1), N))(1:n);
+      ha = ha + fft (postpad (a(i:i+N-1), N))(1:n);
+    endfor
+
+  endif
+
+  h = hb ./ ha;
+
+  if (nargout != 0)
+    ## Return values and don't plot.
+    h_r = h;
+    f_r = f;
+  else
+    ## Plot and don't return values.
+    freqz_plot (f, h);
+  endif
+
+endfunction
+
+%!test # correct values and fft-polyval consistency
+%! # butterworth filter, order 2, cutoff pi/2 radians
+%! b = [0.292893218813452  0.585786437626905  0.292893218813452];
+%! a = [1  0  0.171572875253810];
+%! [h,w] = freqz(b,a,32);
+%! assert(h(1),1,10*eps);
+%! assert(abs(h(17)).^2,0.5,10*eps);
+%! assert(h,freqz(b,a,w),10*eps); # fft should be consistent with polyval
+
+%!test # whole-half consistency
+%! b = [1 1 1]/3; # 3-sample average
+%! [h,w] = freqz(b,1,32,'whole');
+%! assert(h(2:16),conj(h(32:-1:18)),20*eps);
+%! [h2,w2] = freqz(b,1,16,'half');
+%! assert(h(1:16),h2,20*eps);
+%! assert(w(1:16),w2,20*eps);
+
+%!test # Sampling frequency properly interpreted
+%! b = [1 1 1]/3; a = [1 0.2];
+%! [h,f] = freqz(b,a,16,320);
+%! assert(f,[0:15]'*10,10*eps);
+%! [h2,f2] = freqz(b,a,[0:15]*10,320);
+%! assert(f2,[0:15]*10,10*eps);
+%! assert(h,h2.',20*eps);
+%! [h3,f3] = freqz(b,a,32,'whole',320);
+%! assert(f3,[0:31]'*10,10*eps);
diff --git a/scripts/signal/freqz_plot.m b/scripts/signal/freqz_plot.m
new file mode 100644
index 0000000..48f3922
--- /dev/null
+++ b/scripts/signal/freqz_plot.m
@@ -0,0 +1,66 @@
+## Copyright (C) 2002, 2003, 2005, 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} freqz_plot (@var{w}, @var{h})
+## Plot the pass band, stop band and phase response of @var{h}.
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+
+function freqz_plot (w, h)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  n = length (w);
+
+  ## ## exclude zero-frequency
+  ## h = h (2 : length (h));
+  ## w = w (2 : length (w));
+  ## n = n-1;
+
+  mag = 20 * log10 (abs (h));
+  phase = unwrap (arg (h));
+  maxmag = max (mag);
+
+  subplot (3, 1, 1);
+  plot (w, mag);
+  grid ("on");
+  legend ("Pass band (dB)");
+  axis ([w(1), w(n), maxmag-3, maxmag], "labely");
+
+  subplot (3, 1, 2);
+  plot (w, mag);
+  grid ("on");
+  legend ("Stop band (dB)");
+  if (maxmag - min (mag) > 100)
+    axis ([w(1), w(n), maxmag-100, maxmag], "labely");
+  else
+    axis ("autoy", "labely");
+  endif
+
+  subplot (3, 1, 3);
+  plot (w, phase*360/(2*pi));
+  grid ("on");
+  legend ("Phase (degrees)");
+  xlabel ("Frequency");
+  axis ([w(1), w(n)], "autoy", "label");
+
+endfunction
diff --git a/scripts/signal/hamming.m b/scripts/signal/hamming.m
new file mode 100644
index 0000000..b411059
--- /dev/null
+++ b/scripts/signal/hamming.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hamming (@var{m})
+## Return the filter coefficients of a Hamming window of length @var{m}.
+##
+## For a definition of the Hamming window, see e.g., A. V. Oppenheim &
+## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Coefficients of the Hamming window
+
+function c = hamming (m)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isscalar (m) && (m == round (m)) && (m > 0)))
+    error ("hamming: m has to be an integer > 0");
+  endif
+
+  if (m == 1)
+    c = 1;
+  else
+    m = m - 1;
+    c = 0.54 - 0.46 * cos (2 * pi * (0:m)' / m);
+  endif
+
+endfunction
diff --git a/scripts/signal/hanning.m b/scripts/signal/hanning.m
new file mode 100644
index 0000000..a95da9c
--- /dev/null
+++ b/scripts/signal/hanning.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hanning (@var{m})
+## Return the filter coefficients of a Hanning window of length @var{m}.
+##
+## For a definition of this window type, see e.g., A. V. Oppenheim &
+## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Coefficients of the Hanning window
+
+function c = hanning (m)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isscalar (m) && (m == round (m)) && (m > 0)))
+    error ("hanning: m has to be an integer > 0");
+  endif
+
+  if (m == 1)
+    c = 1;
+  else
+    m = m - 1;
+    c = 0.5 - 0.5 * cos (2 * pi * (0 : m)' / m);
+  endif
+
+endfunction
diff --git a/scripts/signal/hurst.m b/scripts/signal/hurst.m
new file mode 100644
index 0000000..3186708
--- /dev/null
+++ b/scripts/signal/hurst.m
@@ -0,0 +1,49 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2009 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hurst (@var{x})
+## Estimate the Hurst parameter of sample @var{x} via the rescaled range
+## statistic.  If @var{x} is a matrix, the parameter is estimated for
+## every single column.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Estimate the Hurst parameter
+
+function H = hurst (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (isscalar (x))
+    error ("hurst: x must not be a scalar");
+  elseif (isvector (x))
+    x = reshape (x, length (x), 1);
+  endif
+
+  [xr, xc] = size (x);
+
+  s = std (x);
+  w = cumsum (x - mean (x));
+  RS = (max(w) - min(w)) ./ s;
+  H = log (RS) / log (xr);
+
+endfunction
diff --git a/scripts/signal/ifftshift.m b/scripts/signal/ifftshift.m
new file mode 100644
index 0000000..a21d4bc
--- /dev/null
+++ b/scripts/signal/ifftshift.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1997, 2006, 2007, 2009 by Vincent Cautaerts
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ifftshift (@var{v})
+## @deftypefnx {Function File} {} ifftshift (@var{v}, @var{dim})
+## Undo the action of the @code{fftshift} function.  For even length 
+## @var{v}, @code{fftshift} is its own inverse, but odd lengths differ 
+## slightly.
+## @end deftypefn
+
+## Author: Vincent Cautaerts <vincent at comf5.comm.eng.osaka-u.ac.jp>
+## Created: July 1997
+## Adapted-By: jwe
+## Modified-By: Paul Kienzle, converted from fftshift
+## Modified-By: David Bateman, add NDArray capability and option dim arg
+
+function retval = ifftshift (V, dim)
+
+  retval = 0;
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    if (! isscalar (dim))
+      error ("ifftshift: dimension must be an integer scalar");
+    endif
+    nd = ndims (V);
+    sz = size (V);
+    sz2 = floor (sz(dim) / 2);
+    idx = cell ();
+    for i = 1:nd
+      idx{i} = 1:sz(i);
+    endfor
+    idx{dim} = [sz2+1:sz(dim), 1:sz2];
+    retval = V (idx{:});
+  else
+    if (isvector (V))
+      x = length (V);
+      xx = floor (x/2);
+      retval = V([xx+1:x, 1:xx]);
+    elseif (ismatrix (V))
+      nd = ndims (V);
+      sz = size (V);
+      sz2 = floor (sz ./ 2);
+      idx = cell ();
+      for i = 1:nd
+        idx{i} = [sz2(i)+1:sz(i), 1:sz2(i)];
+      endfor
+      retval = V (idx{:});
+    else
+      error ("ifftshift: expecting vector or matrix argument");
+    endif
+  endif
+
+endfunction
diff --git a/scripts/signal/periodogram.m b/scripts/signal/periodogram.m
new file mode 100644
index 0000000..263b22e
--- /dev/null
+++ b/scripts/signal/periodogram.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2007
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} periodogram (@var{x})
+## For a data matrix @var{x} from a sample of size @var{n}, return the
+## periodogram.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Compute the periodogram
+
+function retval = periodogram (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [r, c] = size(x);
+
+  if (r == 1)
+    r = c;
+  endif
+
+  retval = (abs (fft (x - mean (x)))) .^ 2 / r;
+
+endfunction
+
+
+
+
+
+
+
diff --git a/scripts/signal/rectangle_lw.m b/scripts/signal/rectangle_lw.m
new file mode 100644
index 0000000..cad5c98
--- /dev/null
+++ b/scripts/signal/rectangle_lw.m
@@ -0,0 +1,40 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2007, 2009
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rectangle_lw (@var{n}, @var{b})
+## Rectangular lag window.  Subfunction used for spectral density
+## estimation.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Rectangular lag window
+
+function retval = rectangle_lw (n, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  retval = zeros (n, 1);
+  t = floor (1 / b);
+
+  retval (1:t, 1) = ones (t, 1);
+
+endfunction
diff --git a/scripts/signal/rectangle_sw.m b/scripts/signal/rectangle_sw.m
new file mode 100644
index 0000000..de894a0
--- /dev/null
+++ b/scripts/signal/rectangle_sw.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2007
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rectangle_sw (@var{n}, @var{b})
+## Rectangular spectral window.  Subfunction used for spectral density
+## estimation.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Rectangular spectral window
+
+function retval = rectangle_sw (n, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  retval = zeros (n, 1);
+  retval(1) = 2 / b + 1;
+
+  l = (2:n)' - 1;
+  l = 2 * pi * l / n;
+
+  retval(2:n) = sin ((2/b + 1) * l / 2) ./ sin (l / 2);
+
+endfunction
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/signal/sinc.m b/scripts/signal/sinc.m
new file mode 100644
index 0000000..f06d0b0
--- /dev/null
+++ b/scripts/signal/sinc.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1994, 1996, 1997, 1999, 2000, 2004, 2005, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sinc (@var{x})
+## Return
+## @tex
+## $ \sin (\pi x)/(\pi x)$.
+## @end tex
+## @ifnottex
+##  sin(pi*x)/(pi*x).
+## @end ifnottex
+## @end deftypefn
+
+## Author: jwe ???
+
+function result = sinc (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  result = ones (size (x));
+
+  i = (x != 0);
+
+  if (any (i(:)))
+    t = pi * x(i);
+    result(i) = sin (t) ./ t;
+  endif
+
+endfunction
diff --git a/scripts/signal/sinetone.m b/scripts/signal/sinetone.m
new file mode 100644
index 0000000..c6aa2bb
--- /dev/null
+++ b/scripts/signal/sinetone.m
@@ -0,0 +1,67 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2008
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sinetone (@var{freq}, @var{rate}, @var{sec}, @var{ampl})
+## Return a sinetone of frequency @var{freq} with length of @var{sec}
+## seconds at sampling rate @var{rate} and with amplitude @var{ampl}.
+## The arguments @var{freq} and @var{ampl} may be vectors of common size.
+##
+## Defaults are @var{rate} = 8000, @var{sec} = 1 and @var{ampl} = 64.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Compute a sine tone
+
+function retval = sinetone (f, r, s, a)
+
+  if (nargin == 1)
+    r = 8000;
+    s = 1;
+    a = 64;
+  elseif (nargin == 2)
+    s = 1;
+    a = 64;
+  elseif (nargin == 3)
+    a = 64;
+  elseif ((nargin < 1) || (nargin > 4))
+    print_usage ();
+  endif
+
+  [err, f, a] = common_size (f, a);
+  if (err || ! isvector (f))
+    error ("sinetone: freq and ampl must be vectors of common size");
+  endif
+
+  if (! (isscalar (r) && isscalar (s)))
+    error ("sinetone: rate and sec must be scalars");
+  endif
+
+  n = length (f);
+  ns = round (r * s);
+
+  retval = zeros (ns, n);
+
+  for k = 1:n
+    retval (:, k) = a(k) * sin (2 * pi * (1:ns) / r * f(k))';
+  endfor
+
+endfunction
+
+%!assert (size (sinetone (18e6, 150e6, 19550/150e6, 1)), [19550, 1]);
diff --git a/scripts/signal/sinewave.m b/scripts/signal/sinewave.m
new file mode 100644
index 0000000..f8a9920
--- /dev/null
+++ b/scripts/signal/sinewave.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sinewave (@var{m}, @var{n}, @var{d})
+## Return an @var{m}-element vector with @var{i}-th element given by
+## @code{sin (2 * pi * (@var{i}+ at var{d}-1) / @var{n})}.
+##
+## The default value for @var{d} is 0 and the default value for @var{n}
+## is @var{m}.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Compute a sine wave
+
+function x = sinewave (m, n, d)
+
+  if (nargin > 0 && nargin < 4)
+    if (nargin < 3)
+      d = 0;
+    endif
+    if (nargin < 2)
+      n = m;
+    endif
+    x = sin (((1 : m) + d - 1) * 2 * pi / n);
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/signal/spectral_adf.m b/scripts/signal/spectral_adf.m
new file mode 100644
index 0000000..d5cefb6
--- /dev/null
+++ b/scripts/signal/spectral_adf.m
@@ -0,0 +1,66 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005,
+##               2007, 2008, 2009 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spectral_adf (@var{c}, @var{win}, @var{b})
+## Return the spectral density estimator given a vector of
+## autocovariances @var{c}, window name @var{win}, and bandwidth,
+## @var{b}.
+##
+## The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+## used to search for a function called @code{@var{win}_sw}.
+##
+## If @var{win} is omitted, the triangle window is used.  If @var{b} is
+## omitted, @code{1 / sqrt (length (@var{x}))} is used.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Spectral density estimation
+
+function retval = spectral_adf (c, win, b)
+
+  cr = length (c);
+
+  if (columns (c) > 1)
+    c = c';
+  endif
+
+  if (nargin < 3)
+    b = 1 / ceil (sqrt (cr));
+  endif
+
+  if (nargin == 1)
+    w = triangle_lw (cr, b);
+  else
+    win = str2func (cstrcat (win, "_lw"));
+    w = feval (win, cr, b);
+  endif
+
+  c = c .* w;
+
+  retval = 2 * real (fft (c)) - c(1);
+  retval = [(zeros (cr, 1)), retval];
+  retval(:, 1) = (0 : cr-1)' / cr;
+
+endfunction
+
+
+
+
+
diff --git a/scripts/signal/spectral_xdf.m b/scripts/signal/spectral_xdf.m
new file mode 100644
index 0000000..e67d835
--- /dev/null
+++ b/scripts/signal/spectral_xdf.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005,
+##               2007, 2008 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spectral_xdf (@var{x}, @var{win}, @var{b})
+## Return the spectral density estimator given a data vector @var{x},
+## window name @var{win}, and bandwidth, @var{b}.
+##
+## The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+## used to search for a function called @code{@var{win}_sw}.
+##
+## If @var{win} is omitted, the triangle window is used.  If @var{b} is
+## omitted, @code{1 / sqrt (length (@var{x}))} is used.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Spectral density estimation
+
+function retval = spectral_xdf (X, win, b)
+
+  xr = length (X);
+
+  if (columns (X) > 1)
+    X = X';
+  endif
+
+  if (nargin < 3)
+    b = 1 / ceil (sqrt (xr));
+  endif
+
+  if (nargin == 1)
+    w = triangle_sw (xr, b);
+  else
+    win = str2func (cstrcat (win, "_sw"));
+    w = feval (win, xr, b);
+  endif
+
+  X = X - sum (X) / xr;
+
+  retval = (abs (fft (X)) / xr).^2;
+  retval = real (ifft (fft(retval) .* fft(w)));
+
+  retval = [(zeros (xr, 1)), retval];
+  retval(:, 1) = (0 : xr-1)' / xr;
+
+endfunction
+
+
+
+
+
+
+
+
diff --git a/scripts/signal/spencer.m b/scripts/signal/spencer.m
new file mode 100644
index 0000000..605f921
--- /dev/null
+++ b/scripts/signal/spencer.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spencer (@var{x})
+## Return Spencer's 15 point moving average of every single column of
+## @var{x}.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Apply Spencer's 15-point MA filter
+
+function retval = spencer (X)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [xr, xc] = size(X);
+
+  n = xr;
+  c = xc;
+
+  if (isvector(X))
+   n = length(X);
+   c = 1;
+   X = reshape(X, n, 1);
+  endif
+
+  W = [-3, -6, -5, 3, 21, 46, 67, 74, 67, 46, 21, 3, -5, -6, -3] / 320;
+
+  retval = fftfilt (W, X);
+  retval = [zeros(7,c); retval(15:n,:); zeros(7,c);];
+
+  retval = reshape(retval, xr, xc);
+
+endfunction
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/signal/stft.m b/scripts/signal/stft.m
new file mode 100644
index 0000000..4874538
--- /dev/null
+++ b/scripts/signal/stft.m
@@ -0,0 +1,133 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{y}, @var{c}] =} stft (@var{x}, @var{win_size}, @var{inc}, @var{num_coef}, @var{w_type})
+## Compute the short-time Fourier transform of the vector @var{x} with
+## @var{num_coef} coefficients by applying a window of @var{win_size} data
+## points and an increment of @var{inc} points.
+##
+## Before computing the Fourier transform, one of the following windows
+## is applied:
+##
+## @table @asis
+## @item hanning
+## w_type = 1
+## @item hamming
+## w_type = 2
+## @item rectangle
+## w_type = 3
+## @end table
+##
+## The window names can be passed as strings or by the @var{w_type} number.
+##
+## If not all arguments are specified, the following defaults are used:
+## @var{win_size} = 80, @var{inc} = 24, @var{num_coef} = 64, and
+## @var{w_type} = 1.
+##
+## @code{@var{y} = stft (@var{x}, @dots{})} returns the absolute values
+## of the Fourier coefficients according to the @var{num_coef} positive
+## frequencies.
+##
+## @code{[@var{y}, @var{c}] = stft (@code{x}, @dots{})} returns the
+## entire STFT-matrix @var{y} and a 3-element vector @var{c} containing
+## the window size, increment, and window type, which is needed by the
+## synthesis function.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Short-Time Fourier Transform
+
+function [Y, c] = stft(X, win, inc, coef, w_type)
+
+  ## Default values of unspecified arguments.
+  if (nargin < 5)
+    w_type = 1;
+    if (nargin < 4)
+      coef = 64;
+      if (nargin < 3)
+        inc = 24;
+        if (nargin < 2)
+          win = 80;
+        endif
+      endif
+    endif
+  elseif (nargin == 5)
+    if (ischar (w_type))
+      if (strcmp (w_type, "hanning"))
+        w_type = 1;
+      elseif (strcmp (w_type, "hamming"))
+        w_type = 2;
+      elseif (strcmp (w_type, "rectangle"))
+        w_type = 3;
+      else
+        error ("stft: unknown window type `%s'", w_type);
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+  ## Check whether X is a vector.
+  [nr, nc] = size (X);
+  if (nc != 1)
+    if (nr == 1)
+      X = X';
+      nr = nc;
+    else
+      error ("stft: X must be a vector");
+    endif
+  endif
+
+  num_coef = 2 * coef;
+  if (win > num_coef)
+    win = num_coef;
+    printf ("stft: window size adjusted to %f\n", win);
+  endif
+  num_win = fix ((nr - win) / inc);
+
+  ## compute the window coefficients
+  if (w_type == 3)
+    ## Rectangular window.
+    WIN_COEF = ones (win, 1);
+  elseif (w_type == 2)
+    ## Hamming window.
+    WIN_COEF = hamming (win);
+  else
+    ## Hanning window.
+    WIN_COEF = hanning (win);
+  endif
+
+  ## Create a matrix Z whose columns contain the windowed time-slices.
+  Z = zeros (num_coef, num_win + 1);
+  start = 1;
+  for i = 0:num_win
+    Z(1:win, i+1) = X(start:start+win-1) .* WIN_COEF;
+    start = start + inc;
+  endfor
+
+  Y = fft (Z);
+
+  if (nargout == 1)
+    Y = abs (Y(1:coef, :));
+  else
+    c = [win, inc, w_type];
+  endif
+
+endfunction
diff --git a/scripts/signal/synthesis.m b/scripts/signal/synthesis.m
new file mode 100644
index 0000000..6c750de
--- /dev/null
+++ b/scripts/signal/synthesis.m
@@ -0,0 +1,74 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Andreas Weingessel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} synthesis (@var{y}, @var{c})
+## Compute a signal from its short-time Fourier transform @var{y} and a
+## 3-element vector @var{c} specifying window size, increment, and
+## window type.
+##
+## The values @var{y} and @var{c} can be derived by
+##
+## @example
+## [@var{y}, @var{c}] = stft (@var{x} , @dots{})
+## @end example
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Description: Recover a signal from its short-term Fourier transform
+
+function X = synthesis (Y, c)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [nr, nc] = size (c);
+  if (nr * nc != 3)
+    error ("synthesis: c must contain exactly 3 elements");
+  endif
+
+  ## not necessary, enables better reading
+  win = c(1);
+  inc = c(2);
+  w_type = c(3);
+
+  if (w_type == 1)
+    H = hanning (win);
+  elseif (w_type == 2)
+    H = hamming (win);
+  elseif (w_type == 3)
+    H = ones (win, 1);
+  else
+    error ("synthesis: window_type must be 1, 2, or 3");
+  endif
+
+  Z = real (ifft (Y));
+  st = fix ((win-inc) / 2);
+  Z = Z(st:st+inc-1, :);
+  H = H(st:st+inc-1);
+
+  nc = columns(Z);
+  for i = 1:nc
+    Z(:, i) = Z(:, i) ./ H;
+  endfor
+
+  X = reshape(Z, inc * nc, 1);
+
+endfunction
diff --git a/scripts/signal/triangle_lw.m b/scripts/signal/triangle_lw.m
new file mode 100644
index 0000000..95484df
--- /dev/null
+++ b/scripts/signal/triangle_lw.m
@@ -0,0 +1,39 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2007, 2009
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} triangle_lw (@var{n}, @var{b})
+## Triangular lag window.  Subfunction used for spectral density
+## estimation.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Triangular lag window
+
+function retval = triangle_lw (n, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  retval = 1 - (0 : n-1)' * b;
+  retval = max ([retval'; (zeros (1, n))])';
+
+endfunction
+
diff --git a/scripts/signal/triangle_sw.m b/scripts/signal/triangle_sw.m
new file mode 100644
index 0000000..f2ebbab
--- /dev/null
+++ b/scripts/signal/triangle_sw.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2007
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} triangle_sw (@var{n}, @var{b})
+## Triangular spectral window.  Subfunction used for spectral density
+## estimation.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Triangular spectral window
+
+function retval = triangle_sw (n, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  retval = zeros(n,1);
+  retval(1) = 1 / b;
+
+  l = (2:n)' - 1;
+  l = 2 * pi * l / n;
+
+  retval(2:n) = b * (sin (l / (2*b)) ./ sin (l / 2)).^2;
+
+endfunction
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/signal/unwrap.m b/scripts/signal/unwrap.m
new file mode 100644
index 0000000..61903e8
--- /dev/null
+++ b/scripts/signal/unwrap.m
@@ -0,0 +1,136 @@
+## Copyright (C) 2000, 2002, 2004, 2005, 2006, 2007, 2008 Bill Lash
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{b} =} unwrap (@var{a}, @var{tol}, @var{dim})
+## 
+## Unwrap radian phases by adding multiples of 2*pi as appropriate to
+## remove jumps greater than @var{tol}.  @var{tol} defaults to pi.
+##
+## Unwrap will unwrap along the first non-singleton dimension of
+## @var{a}, unless the optional argument @var{dim} is given, in 
+## which case the data will be unwrapped along this dimension
+## @end deftypefn
+
+## Author: Bill Lash <lash at tellabs.com>
+
+function retval = unwrap (a, tol, dim)
+        
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  nd = ndims (a);
+  sz = size (a);
+
+  if (nargin == 3)
+    if (! (isscalar (dim) && dim == round (dim)) && dim > 0 && 
+	dim < (nd + 1))
+      error ("unwrap: dim must be an integer and valid dimension");
+    endif
+  else
+    ## Find the first non-singleton dimension
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  endif
+
+  if (nargin < 2 || isempty (tol))
+    tol = pi;
+  endif
+
+  ## Don't let anyone use a negative value for TOL.
+  tol = abs (tol);
+  
+  rng = 2*pi;
+  m = sz(dim);
+
+  ## Handle case where we are trying to unwrap a scalar, or only have
+  ## one sample in the specified dimension.
+  if (m == 1)       
+    retval = a;     
+    return;         
+  endif
+
+  ## Take first order difference to see so that wraps will show up
+  ## as large values, and the sign will show direction.
+  idx = cell ();
+  for i = 1:nd
+    idx{i} = 1:sz(i);
+  endfor
+  idx{dim} = [1,1:m-1];
+  d = a(idx{:}) - a;
+
+  ## Find only the peaks, and multiply them by the range so that there
+  ## are kronecker deltas at each wrap point multiplied by the range
+  ## value.
+  p =  rng * (((d > tol) > 0) - ((d < -tol) > 0));
+
+  ## Now need to "integrate" this so that the deltas become steps.
+  r = cumsum (p, dim);
+
+  ## Now add the "steps" to the original data and put output in the
+  ## same shape as originally.
+  retval = a + r;
+
+endfunction
+
+%!function t = xassert(a,b,tol)
+%!  if (nargin == 1)
+%!    t = all(a(:));
+%!  else
+%!    if (nargin == 2)
+%!      tol = 0;
+%!    endif
+%!    if (any (size(a) != size(b)))
+%!      t = 0;
+%!    elseif (any (abs(a(:) - b(:)) > tol))
+%!      t = 0;
+%!    else
+%!      t = 1;
+%!    endif
+%!  endif
+%!
+%!test
+%! 
+%! i = 0;
+%! t = [];
+%! 
+%! r = [0:100];                        # original vector
+%! w = r - 2*pi*floor((r+pi)/(2*pi));  # wrapped into [-pi,pi]
+%! tol = 1e3*eps;                      # maximum expected deviation
+%! 
+%! t(++i) = xassert(r, unwrap(w), tol);               #unwrap single row
+%! t(++i) = xassert(r', unwrap(w'), tol);             #unwrap single column
+%! t(++i) = xassert([r',r'], unwrap([w',w']), tol);   #unwrap 2 columns
+%! t(++i) = xassert([r;r], unwrap([w;w],[],2), tol);  #verify that dim works
+%! t(++i) = xassert(r+10, unwrap(10+w), tol);         #verify that r(1)>pi works
+%! 
+%! t(++i) = xassert(w', unwrap(w',[],2));  #unwrap col by rows should not change it
+%! t(++i) = xassert(w, unwrap(w,[],1));    #unwrap row by cols should not change it
+%! t(++i) = xassert([w;w], unwrap([w;w])); #unwrap 2 rows by cols should not change them
+%! 
+%! ## verify that setting tolerance too low will cause bad results.
+%! t(++i) = xassert(any(abs(r - unwrap(w,0.8)) > 100));
+%! 
+%! assert(all(t));
+
diff --git a/scripts/signal/yulewalker.m b/scripts/signal/yulewalker.m
new file mode 100644
index 0000000..5868d91
--- /dev/null
+++ b/scripts/signal/yulewalker.m
@@ -0,0 +1,61 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2007, 2009
+##               Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{a}, @var{v}] =} yulewalker (@var{c})
+## Fit an AR (p)-model with Yule-Walker estimates given a vector @var{c}
+## of autocovariances @code{[gamma_0, @dots{}, gamma_p]}.
+##
+## Returns the AR coefficients, @var{a}, and the variance of white
+## noise, @var{v}.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Fit AR model by Yule-Walker method
+
+function [a, v] = yulewalker (c)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  p = length (c) - 1;
+
+  if (columns (c) > 1)
+    c = c';
+  endif
+
+  cp = c(2 : p+1);
+  CP = zeros(p, p);
+
+  for i = 1:p
+    for j = 1:p
+      CP (i, j) = c (abs (i-j) + 1);
+    endfor
+  endfor
+
+  a = inv (CP) * cp;
+  v = c(1) - a' * cp;
+
+endfunction
+
+
+
+
+
diff --git a/scripts/skip-autoheader b/scripts/skip-autoheader
new file mode 100644
index 0000000..e69de29
diff --git a/scripts/sparse/Makefile.in b/scripts/sparse/Makefile.in
new file mode 100644
index 0000000..40c0390
--- /dev/null
+++ b/scripts/sparse/Makefile.in
@@ -0,0 +1,86 @@
+# Makefile for octave's scripts/sparse directory
+#
+# Copyright (C) 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = sparse
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = bicgstab.m cgs.m colperm.m etreeplot.m gplot.m nonzeros.m normest.m \
+  pcg.m pcr.m spalloc.m spaugment.m spconvert.m spdiags.m speye.m \
+  spfun.m sphcat.m spones.m sprand.m sprandn.m sprandsym.m spstats.m \
+  spvcat.m spy.m svds.m treelayout.m treeplot.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/sparse
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/sparse/bicgstab.m b/scripts/sparse/bicgstab.m
new file mode 100644
index 0000000..07083a1
--- /dev/null
+++ b/scripts/sparse/bicgstab.m
@@ -0,0 +1,172 @@
+## Copyright (C) 2008 Radek Salac
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bicgstab (@var{A}, @var{b})
+## @deftypefnx {Function File} {} bicgstab (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+## This procedure attempts to solve a system of linear equations A*x = b for x.
+## The @var{A} must be square, symmetric and positive definite real matrix N*N.
+## The @var{b} must be a one column vector with a length of N.
+## The @var{tol} specifies the tolerance of the method, the default value is 1e-6.
+## The @var{maxit} specifies the maximum number of iterations, the default value is min(20,N).
+## The @var{M1} specifies a preconditioner, can also be a function handler which returns M\X.
+## The @var{M2} combined with @var{M1} defines preconditioner as preconditioner=M1*M2.
+## The @var{x0} is the initial guess, the default value is zeros(N,1).
+##
+## The value @var{x} is a computed result of this procedure.
+## The value @var{flag} can be 0 when we reach tolerance in @var{maxit} iterations, 1 when
+## we don't reach tolerance in @var{maxit} iterations and 3 when the procedure stagnates.
+## The value @var{relres} is a relative residual - norm(b-A*x)/norm(b).
+## The value @var{iter} is an iteration number in which x was computed.
+## The value @var{resvec} is a vector of @var{relres} for each iteration.
+##
+## @end deftypefn
+
+function [x, flag, relres, iter, resvec] = bicgstab (A, b, tol, maxit, M1, M2, x0)
+
+  if (nargin < 2 || nargin > 7 || nargout > 5)
+    print_usage ();
+  elseif (!isnumeric (A) || rows (A) != columns (A))
+    error ("bicgstab: the first argument must be a n-by-n matrix");
+  elseif (!isvector (b))
+    error ("bicgstab: b must be a vector");
+  elseif (!any (b))
+    error ("bicgstab: b shuldn't be a vector of zeros");
+  elseif (rows (A) != rows (b))
+    error ("bicgstab: the first and second argument must have the same number of rows");
+  elseif (nargin > 2 && !isscalar (tol))
+    error ("bicgstab: tol must be a scalar");
+  elseif (nargin > 3 && !isscalar (maxit))
+    error ("bicgstab: maxit must be a scalar");
+  elseif (nargin > 4 && ismatrix (M1) && (rows (M1) != rows (A) || columns (M1) != columns (A)))
+    error ("bicgstab: M1 must have the same number of rows and columns as A");
+  elseif (nargin > 5 && (!ismatrix (M2) || rows (M2) != rows (A) || columns (M2) != columns (A)))
+    error ("bicgstab: M2 must have the same number of rows and columns as A");
+  elseif (nargin > 6 && !isvector (x0))
+    error ("bicgstab: x0 must be a vector");
+  elseif (nargin > 6 && rows (x0) != rows (b))
+    error ("bicgstab: x0 must have the same number of rows as b");
+  endif
+
+  ## Default tolerance.
+  if (nargin < 3)
+    tol = 1e-6;
+  endif
+
+  ## Default maximum number of iteration.
+  if (nargin < 4)
+    maxit = min (rows (b), 20);
+  endif
+
+  ## Left preconditioner.
+  if (nargin == 5)
+    if (isnumeric (M1))
+      precon = @(x) M1 \ x;
+    endif
+  elseif (nargin > 5)
+    if (issparse (M1) && issparse (M2))
+      precon = @(x) M2 \ (M1 \ x);
+    else
+      M = M1*M2;
+      precon = @(x) M \ x;
+    endif
+  else
+    precon = @(x) x;
+  endif
+
+  ## specifies initial estimate x0
+  if (nargin < 7)
+    x = zeros (rows (b), 1);
+  else
+    x = x0;
+  endif
+
+  norm_b = norm (b);
+
+  res = b - A*x;
+  rr = res;
+
+  ## Vector of the residual norms for each iteration.
+  resvec = [norm(res)/norm_b];
+
+  ## Default behaviour we don't reach tolerance tol within maxit iterations.
+  flag = 1;
+
+  for iter = 1:maxit
+    rho_1 = res' * rr;
+
+    if (iter == 1)
+      p = res;
+    else
+      beta = (rho_1 / rho_2) * (alpha / omega);
+      p = res + beta * (p - omega * v);
+    endif
+
+    phat = precon (p);
+
+    v = A * phat;
+    alpha = rho_1 / (rr' * v);
+    s = res - alpha * v;
+
+    shat = precon (s);
+
+    t = A * shat; 
+    omega = (t' * s) / (t' * t);
+    x = x + alpha * phat + omega * shat;
+    res = s - omega * t;
+    rho_2 = rho_1;
+
+    relres = norm (res) / norm_b;
+    resvec = [resvec; relres];
+
+    if (relres <= tol)
+      ## We reach tolerance tol within maxit iterations.
+      flag = 0;
+      break;
+    elseif (resvec (end) == resvec (end - 1)) 
+      ## The method stagnates.
+      flag = 3;
+      break;
+    endif
+  endfor
+
+  if (nargout < 2)
+    if (flag == 0) 
+      printf (["bicgstab converged at iteration %i ",
+      "to a solution with relative residual %e\n"],iter,relres);
+    elseif (flag == 3)
+      printf (["bicgstab stopped at iteration %i ",
+      "without converging to the desired tolerance %e\n",
+      "because the method stagnated.\n",
+      "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres);
+    else
+      printf (["bicgstab stopped at iteration %i ",
+      "without converging to the desired toleranc %e\n",
+      "because the maximum number of iterations was reached.\n",
+      "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres);
+    endif
+  endif
+
+endfunction
+
+%!demo
+%! % Solve system of A*x=b
+%! A = [5 -1 3;-1 2 -2;3 -2 3]
+%! b = [7;-1;4]
+%! [x, flag, relres, iter, resvec] = bicgstab(A, b)
+
diff --git a/scripts/sparse/cgs.m b/scripts/sparse/cgs.m
new file mode 100644
index 0000000..42e5ed7
--- /dev/null
+++ b/scripts/sparse/cgs.m
@@ -0,0 +1,155 @@
+## Copyright (C) 2008 Radek Salac
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cgs (@var{A}, @var{b})
+## @deftypefnx {Function File} {} cgs (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+## This procedure attempts to solve a system of linear equations A*x = b for x.
+## The @var{A} must be square, symmetric and positive definite real matrix N*N.
+## The @var{b} must be a one column vector with a length of N.
+## The @var{tol} specifies the tolerance of the method, default value is 1e-6.
+## The @var{maxit} specifies the maximum number of iteration, default value is MIN(20,N).
+## The @var{M1} specifies a preconditioner, can also be a function handler which returns M\X.
+## The @var{M2} combined with @var{M1} defines preconditioner as preconditioner=M1*M2.
+## The @var{x0} is initial guess, default value is zeros(N,1).
+##
+## @end deftypefn
+
+function [x, flag, relres, iter, resvec] = cgs (A, b, tol, maxit, M1, M2, x0)
+
+  if (nargin < 2 || nargin > 7 || nargout > 5)
+    print_usage ();
+  elseif (!isnumeric (A) || rows (A) != columns (A))
+    error ("cgs: first argument must be a n-by-n matrix");
+  elseif (!isvector (b))
+    error ("cgs: b must be a vector");
+  elseif (rows (A) != rows (b))
+    error ("cgs: first and second argument must have the same number of rows");
+  elseif (nargin > 2 && !isscalar (tol))
+    error ("cgs: tol must be a scalar");
+  elseif (nargin > 3 && !isscalar (maxit))
+    error ("cgs: maxit must be a scalar");
+  elseif (nargin > 4 && ismatrix (M1) && (rows (M1) != rows (A) || columns (M1) != columns (A)))
+    error ("cgs: M1 must have the same number of rows and columns as A");
+  elseif (nargin > 5 && (!ismatrix (M2) || rows (M2) != rows (A) || columns (M2) != columns (A)))
+    error ("cgs: M2 must have the same number of rows and columns as A");
+  elseif (nargin > 6 && !isvector (x0))
+    error ("cgs: x0 must be a vector");
+  elseif (nargin > 6 && rows (x0) != rows (b))
+    error ("cgs: x0 must have the same number of rows as b");
+  endif
+
+  ## Default tolerance.
+  if (nargin < 3)
+    tol = 1e-6;
+  endif
+
+  ## Default maximum number of iteration.
+  if (nargin < 4)
+    maxit = min (rows (b),20);
+  endif
+
+  ## Left preconditioner.
+  if (nargin == 5)
+    if (isnumeric (M1))
+      precon = @(x) M1 \ x;
+    endif
+  elseif (nargin > 5)
+    if (issparse (M1) && issparse (M2))
+      precon = @(x) M2 \ (M1 \ x);
+    else
+      M = M1*M2;
+      precon = @(x) M \ x;
+    endif
+  else
+    precon = @(x) x;
+  endif
+
+  ## Specifies initial estimate x0.
+  if (nargin < 7)
+    x = zeros (rows (b), 1);
+  else
+    x = x0;
+  endif
+
+  res = b - A * x;
+  norm_b = norm (b);
+  ## Vector of the residual norms for each iteration.
+  resvec = [ norm(res)/norm_b ];
+  ro = 0;
+  ## Default behavior we don't reach tolerance tol within maxit iterations.
+  flag = 1;
+  for iter = 1 : maxit
+
+    z = precon (res);
+
+    ## Cache.
+    ro_old = ro;
+    ro = res' * z;
+    if (iter == 1)
+      p = z;
+    else
+      beta = ro / ro_old;
+      p = z + beta * p;
+    endif
+    ## Cache.
+    q = A * p;
+    alpha = ro / (p' * q);
+    x = x + alpha * p;
+
+    res = res - alpha * q;
+    relres = norm(res) / norm_b;
+    resvec = [resvec;relres];
+
+    if (relres <= tol)
+      ## We reach tolerance tol within maxit iterations.
+      flag = 0;
+      break;
+    elseif (resvec (end) == resvec (end - 1))
+      ## The method stagnates.
+      flag = 3;
+      break;
+    endif
+  endfor;
+
+  if (nargout < 1)
+    if ( flag == 0 ) 
+      printf (["cgs converged at iteration %i ",
+      "to a solution with relative residual %e\n"],iter,relres);
+    elseif (flag == 3)
+      printf (["cgs stopped at iteration %i ",
+      "without converging to the desired tolerance %e\n",
+      "because the method stagnated.\n",
+      "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres);
+    else
+      printf (["cgs stopped at iteration %i ",
+      "without converging to the desired tolerance %e\n",
+      "because the maximum number of iterations was reached.\n",
+      "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres);
+    endif
+  endif
+
+endfunction
+
+
+
+%!demo
+%! % Solve system of A*x=b
+%! A=[5 -1 3;-1 2 -2;3 -2 3]
+%! b=[7;-1;4]
+%! [a,b,c,d,e]=cgs(A,b)
diff --git a/scripts/sparse/colperm.m b/scripts/sparse/colperm.m
new file mode 100644
index 0000000..d79b999
--- /dev/null
+++ b/scripts/sparse/colperm.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2004, 2005, 2007, 2008, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{p} =} colperm (@var{s})
+## Returns the column permutations such that the columns of
+## @code{@var{s} (:, @var{p})} are ordered in terms of increase number
+## of non-zero elements.  If @var{s} is symmetric, then @var{p} is chosen
+## such that @code{@var{s} (@var{p}, @var{p})} orders the rows and
+## columns with increasing number of non zeros elements.
+## @end deftypefn
+
+function p = colperm (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [i, j] = find (s);
+  idx = find (diff ([j; Inf]) != 0);
+  [dummy, p] = sort (idx - [0; idx(1:(end-1))]);
+endfunction
diff --git a/scripts/sparse/etreeplot.m b/scripts/sparse/etreeplot.m
new file mode 100644
index 0000000..7f6b5ec
--- /dev/null
+++ b/scripts/sparse/etreeplot.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2005, 2006, 2007 Ivana Varekova
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} etreeplot (@var{tree})
+## @deftypefnx {Function File} {} etreeplot (@var{tree}, @var{node_style}, @var{edge_style})
+## Plot the elimination tree of the matrix @var{s} or
+## @code{@var{s}+ at var{s}'}  if @var{s} in non-symmetric.  The optional
+## parameters @var{line_style} and @var{edge_style} define the output
+## style.
+## @seealso{treeplot, gplot}
+## @end deftypefn
+
+function etreeplot (s, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  treeplot (etree (s+s'), varargin{:});
+endfunction
diff --git a/scripts/sparse/gplot.m b/scripts/sparse/gplot.m
new file mode 100644
index 0000000..f55fc46
--- /dev/null
+++ b/scripts/sparse/gplot.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Ivana Varekova
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gplot (@var{a}, @var{xy})
+## @deftypefnx {Function File} {} gplot (@var{a}, @var{xy}, @var{line_style})
+## @deftypefnx {Function File} {[@var{x}, @var{y}] =} gplot (@var{a}, @var{xy})
+## Plot a graph defined by @var{A} and @var{xy} in the graph theory
+## sense.  @var{A} is the adjacency matrix of the array to be plotted
+## and @var{xy} is an @var{n}-by-2 matrix containing the coordinates of
+## the nodes of the graph.
+##
+## The optional parameter @var{line_style} defines the output style for
+## the plot.  Called with no output arguments the graph is plotted
+## directly.  Otherwise, return the coordinates of the plot in @var{x}
+## and @var{y}.
+## @seealso{treeplot, etreeplot, spy}
+## @end deftypefn
+
+function [x, y] = gplot (a, xy, line_style)
+
+  if (nargin < 2 || nargin > 3 || nargout > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    line_style = "-";
+  endif
+
+  [i, j] = find (a);
+  xcoord = [xy(i,1), xy(j,1), NaN * ones(length(i),1)]'(:);
+  ycoord = [xy(i,2), xy(j,2), NaN * ones(length(i),1)]'(:);
+
+  if (nargout == 0)
+    plot (xcoord, ycoord, line_style); 
+  else
+    x = xcoord;
+    y = ycoord;
+  endif
+
+endfunction
diff --git a/scripts/sparse/nonzeros.m b/scripts/sparse/nonzeros.m
new file mode 100644
index 0000000..9af8af8
--- /dev/null
+++ b/scripts/sparse/nonzeros.m
@@ -0,0 +1,34 @@
+## Copyright (C) 2004, 2005, 2007, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nonzeros (@var{s})
+## Returns a vector of the non-zero values of the sparse matrix @var{s}.
+## @end deftypefn
+
+function t = nonzeros (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [i, j, t] = find (s);
+endfunction
+
+%!assert(nonzeros([1,2;3,0]),[1;3;2])
+%!assert(nonzeros(sparse([1,2;3,0])),[1;3;2])
diff --git a/scripts/sparse/normest.m b/scripts/sparse/normest.m
new file mode 100644
index 0000000..adaae6a
--- /dev/null
+++ b/scripts/sparse/normest.m
@@ -0,0 +1,87 @@
+## Copyright (C) 2006, 2007, 2008, 2009 David Bateman and Marco Caliari
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{n}, @var{c}] =} normest (@var{a}, @var{tol})
+## Estimate the 2-norm of the matrix @var{a} using a power series
+## analysis.  This is typically used for large matrices, where the cost
+## of calculating the @code{norm (@var{a})} is prohibitive and an approximation
+## to the 2-norm is acceptable.
+##
+## @var{tol} is the tolerance to which the 2-norm is calculated.  By default
+## @var{tol} is 1e-6.  @var{c} returns the number of iterations needed for
+## @code{normest} to converge.
+## @end deftypefn
+
+function [e1, c] = normest (A, tol)
+  if (nargin < 2)
+    tol = 1e-6;
+  endif
+  if (isa (A, "single"))
+    if (tol < eps ("single"))
+      tol = eps ("single");
+    endif
+  else
+    if (tol < eps)
+      tol = eps
+    endif
+  endif
+  if (ndims (A) != 2)
+    error ("normest: A must be a matrix");
+  endif 
+  maxA = max (max (abs (A)));
+  c = 0;
+  if (maxA == 0)
+    e1 = 0
+  else
+    [m, n] = size (A);
+    B = A / maxA;
+    Bt = B';
+    if (m > n)
+      tmp = B;
+      B = Bt;
+      Bt = tmp;
+    endif
+    e0 = 0;
+    x = randn (min (m, n), 1);
+    e1 = norm (x);
+    x = x / e1;
+    e1 = sqrt (e1);
+    if (issparse (A))
+      while (abs (e1 - e0) > tol * e1)
+	e0 = e1;
+	x = B * (Bt * x);
+	e1 = norm (x);
+	x = x / e1;
+	e1 = sqrt (e1);
+	c = c + 1;
+      endwhile
+    else
+      B = B * Bt;
+      while (abs (e1 - e0) > tol * e1)
+	e0 = e1;
+	x = B * x;
+	e1 = norm (x);
+	x = x / e1;
+	e1 = sqrt (e1);
+	c = c + 1;
+      endwhile
+    endif
+    e1 = e1 * maxA;
+  endif
+endfunction
diff --git a/scripts/sparse/pcg.m b/scripts/sparse/pcg.m
new file mode 100644
index 0000000..b339f92
--- /dev/null
+++ b/scripts/sparse/pcg.m
@@ -0,0 +1,528 @@
+## Copyright (C) 2004, 2006, 2007, 2008, 2009 Piotr Krzyzanowski
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} pcg (@var{a}, @var{b}, @var{tol}, @var{maxit}, @var{m1}, @var{m2}, @var{x0}, @dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}, @var{eigest}] =} pcg (@dots{})
+##
+## Solves the linear system of equations @code{@var{a} * @var{x} =
+## @var{b}} by means of the Preconditioned Conjugate Gradient iterative
+## method.  The input arguments are
+##
+## @itemize
+## @item
+## @var{a} can be either a square (preferably sparse) matrix or a
+## function handle, inline function or string containing the name
+## of a function which computes @code{@var{a} * @var{x}}.  In principle
+## @var{a} should be symmetric and positive definite; if @code{pcg}
+## finds @var{a} to not be positive definite, you will get a warning
+## message and the @var{flag} output parameter will be set.
+## 
+## @item
+## @var{b} is the right hand side vector.
+## 
+## @item
+## @var{tol} is the required relative tolerance for the residual error,
+## @code{@var{b} - @var{a} * @var{x}}.  The iteration stops if @code{norm
+## (@var{b} - @var{a} * @var{x}) <= @var{tol} * norm (@var{b} - @var{a} *
+## @var{x0})}.  If @var{tol} is empty or is omitted, the function sets
+## @code{@var{tol} = 1e-6} by default.
+## 
+## @item
+## @var{maxit} is the maximum allowable number of iterations; if
+## @code{[]} is supplied for @code{maxit}, or @code{pcg} has less
+## arguments, a default value equal to 20 is used.
+## 
+## @item
+## @var{m} = @var{m1} * @var{m2} is the (left) preconditioning matrix, so that the iteration is
+## (theoretically) equivalent to solving by @code{pcg} @code{@var{P} *
+## @var{x} = @var{m} \ @var{b}}, with @code{@var{P} = @var{m} \ @var{a}}.
+## Note that a proper choice of the preconditioner may dramatically
+## improve the overall performance of the method.  Instead of matrices
+## @var{m1} and @var{m2}, the user may pass two functions which return 
+## the results of applying the inverse of @var{m1} and @var{m2} to 
+## a vector (usually this is the preferred way of using the preconditioner). 
+## If @code{[]} is supplied for @var{m1}, or @var{m1} is omitted, no 
+## preconditioning is applied.  If @var{m2} is omitted, @var{m} = @var{m1}
+## will be used as preconditioner.
+## 
+## @item
+## @var{x0} is the initial guess.  If @var{x0} is empty or omitted, the 
+## function sets @var{x0} to a zero vector by default.
+## @end itemize
+## 
+## The arguments which follow @var{x0} are treated as parameters, and
+## passed in a proper way to any of the functions (@var{a} or @var{m})
+## which are passed to @code{pcg}.  See the examples below for further
+## details.  The output arguments are
+##
+## @itemize
+## @item
+## @var{x} is the computed approximation to the solution of
+## @code{@var{a} * @var{x} = @var{b}}.
+## 
+## @item
+## @var{flag} reports on the convergence.  @code{@var{flag} = 0} means
+## the solution converged and the tolerance criterion given by @var{tol}
+## is satisfied.  @code{@var{flag} = 1} means that the @var{maxit} limit
+## for the iteration count was reached.  @code{@var{flag} = 3} reports that
+## the (preconditioned) matrix was found not positive definite.
+## 
+## @item
+## @var{relres} is the ratio of the final residual to its initial value,
+## measured in the Euclidean norm.
+## 
+## @item
+## @var{iter} is the actual number of iterations performed.
+##
+## @item 
+## @var{resvec} describes the convergence history of the method.
+## @code{@var{resvec} (i,1)} is the Euclidean norm of the residual, and
+## @code{@var{resvec} (i,2)} is the preconditioned residual norm,
+## after the (@var{i}-1)-th iteration, @code{@var{i} =
+## 1, 2, @dots{}, @var{iter}+1}.  The preconditioned residual norm
+## is defined as
+## @code{norm (@var{r}) ^ 2 = @var{r}' * (@var{m} \ @var{r})} where
+## @code{@var{r} = @var{b} - @var{a} * @var{x}}, see also the
+## description of @var{m}.  If @var{eigest} is not required, only
+## @code{@var{resvec} (:,1)} is returned.
+## 
+## @item
+## @var{eigest} returns the estimate for the smallest @code{@var{eigest}
+## (1)} and largest @code{@var{eigest} (2)} eigenvalues of the
+## preconditioned matrix @code{@var{P} = @var{m} \ @var{a}}.  In 
+## particular, if no preconditioning is used, the estimates for the
+## extreme eigenvalues of @var{a} are returned.  @code{@var{eigest} (1)}
+## is an overestimate and @code{@var{eigest} (2)} is an underestimate, 
+## so that @code{@var{eigest} (2) / @var{eigest} (1)} is a lower bound
+## for @code{cond (@var{P}, 2)}, which nevertheless in the limit should
+## theoretically be equal to the actual value of the condition number. 
+## The method which computes @var{eigest} works only for symmetric positive
+## definite @var{a} and @var{m}, and the user is responsible for
+## verifying this assumption. 
+## @end itemize
+## 
+## Let us consider a trivial problem with a diagonal matrix (we exploit the
+## sparsity of A) 
+## 
+## @example
+## @group
+## 	n = 10; 
+## 	a = diag (sparse (1:n));
+## 	b = rand (n, 1);
+##      [l, u, p, q] = luinc (a, 1.e-3);
+## @end group
+## @end example
+## 
+## @sc{Example 1:} Simplest use of @code{pcg}
+## 
+## @example
+##   x = pcg(A,b)
+## @end example
+## 
+## @sc{Example 2:} @code{pcg} with a function which computes
+## @code{@var{a} * @var{x}}
+## 
+## @example
+## @group
+##   function y = apply_a (x)
+##     y = [1:N]'.*x; 
+##   endfunction
+##
+##   x = pcg ("apply_a", b)
+## @end group
+## @end example
+##
+## @sc{Example 3:} @code{pcg} with a preconditioner: @var{l} * @var{u}
+##
+## @example
+## x = pcg (a, b, 1.e-6, 500, l*u);
+## @end example
+##
+## @sc{Example 4:} @code{pcg} with a preconditioner: @var{l} * @var{u}.
+## Faster than @sc{Example 3} since lower and upper triangular matrices 
+## are easier to invert
+##
+## @example
+## x = pcg (a, b, 1.e-6, 500, l, u);
+## @end example
+##
+## @sc{Example 5:} Preconditioned iteration, with full diagnostics.  The
+## preconditioner (quite strange, because even the original matrix
+## @var{a} is trivial) is defined as a function
+## 
+## @example
+## @group
+##   function y = apply_m (x)
+##     k = floor (length (x) - 2);
+##     y = x;
+##     y(1:k) = x(1:k)./[1:k]';
+##   endfunction
+## 
+##   [x, flag, relres, iter, resvec, eigest] = ...
+##                      pcg (a, b, [], [], "apply_m");
+##   semilogy (1:iter+1, resvec);
+## @end group
+## @end example
+## 
+## @sc{Example 6:} Finally, a preconditioner which depends on a
+## parameter @var{k}.
+## 
+## @example
+## @group
+##   function y = apply_M (x, varargin)
+##   K = varargin@{1@}; 
+##   y = x;
+##   y(1:K) = x(1:K)./[1:K]';
+##   endfunction
+## 
+##   [x, flag, relres, iter, resvec, eigest] = ...
+##        pcg (A, b, [], [], "apply_m", [], [], 3)
+## @end group
+## @end example
+## 
+## @sc{References}
+## 
+## 	[1] C.T.Kelley, 'Iterative methods for linear and nonlinear equations',
+## 	SIAM, 1995 (the base PCG algorithm) 
+## 	
+## 	[2] Y.Saad, 'Iterative methods for sparse linear systems', PWS 1996
+## 	(condition number estimate from PCG) Revised version of this book is
+## 	available online at http://www-users.cs.umn.edu/~saad/books.html
+## 
+##
+## @seealso{sparse, pcr}
+## @end deftypefn
+
+## Author: Piotr Krzyzanowski <piotr.krzyzanowski at mimuw.edu.pl>
+## Modified by: Vittoria Rezzonico <vittoria.rezzonico at epfl.ch>
+##    - Add the ability to provide the pre-conditioner as two separate
+## matrices
+
+function [x, flag, relres, iter, resvec, eigest] = pcg (a, b, tol, maxit, m1, m2, x0, varargin)
+
+  ## M = M1*M2
+
+  if (nargin < 7 || isempty (x0))
+    x = zeros (size (b));
+  else
+    x = x0;
+  endif
+
+  if (nargin < 5 || isempty (m1))
+     exist_m1 = 0;
+  else
+     exist_m1 = 1;
+  endif
+
+  if (nargin < 6 || isempty (m2))
+     exist_m2 = 0;
+  else
+     exist_m2 = 1;
+  endif
+
+  if (nargin < 4 || isempty (maxit))
+    maxit = min (size (b, 1), 20);
+  endif
+
+  maxit += 2;
+
+  if (nargin < 3 || isempty (tol))
+    tol = 1e-6;
+  endif
+
+  preconditioned_residual_out = false;
+  if (nargout > 5)
+    T = zeros (maxit, maxit);
+    preconditioned_residual_out = true;
+  endif
+
+  ## Assume A is positive definite.
+  matrix_positive_definite = true;
+
+  p = zeros (size (b));
+  oldtau = 1; 
+  if (isnumeric (a))
+    ## A is a matrix.
+    r = b - a*x; 
+  else
+    ## A should be a function.
+    r = b - feval (a, x, varargin{:});
+  endif
+
+  resvec(1,1) = norm (r);
+  alpha = 1;
+  iter = 2;
+
+  while (resvec (iter-1,1) > tol * resvec (1,1) && iter < maxit)
+    if (exist_m1)
+      if(isnumeric (m1))
+	y = m1 \ r;
+      else
+	y = feval (m1, r, varargin{:});
+      endif
+    else
+      y = r;
+    endif
+    if (exist_m2)
+      if (isnumeric (m2))
+	z = m2 \ y;
+      else
+	z = feval (m2, y, varargin{:});
+      endif
+    else
+      z = y;
+    endif
+    tau = z' * r; 
+    resvec (iter-1,2) = sqrt (tau);
+    beta = tau / oldtau;
+    oldtau = tau;
+    p = z + beta * p;
+    if (isnumeric (a))
+      ## A is a matrix.
+      w = a * p;
+    else
+      ## A should be a function.
+      w = feval (a, p, varargin{:});
+    endif
+    ## Needed only for eigest.
+    oldalpha = alpha;
+    alpha = tau / (p'*w);
+    if (alpha <= 0.0)
+      ## Negative matrix.
+      matrix_positive_definite = false;
+    endif
+    x += alpha * p;
+    r -= alpha * w;
+    if (nargout > 5 && iter > 2)
+      T(iter-1:iter, iter-1:iter) = T(iter-1:iter, iter-1:iter) + ...
+	  [1 sqrt(beta); sqrt(beta) beta]./oldalpha;
+      ## EVS = eig(T(2:iter-1,2:iter-1));
+      ## fprintf(stderr,"PCG condest: %g (iteration: %d)\n", max(EVS)/min(EVS),iter);
+    endif
+    resvec (iter,1) = norm (r);
+    iter++;
+  endwhile
+
+  if (nargout > 5)
+    if (matrix_positive_definite)
+      if (iter > 3)
+	T = T(2:iter-2,2:iter-2);
+	l = eig (T);
+	eigest = [min(l), max(l)];
+	## fprintf (stderr, "pcg condest: %g\n", eigest(2)/eigest(1));
+      else
+	eigest = [NaN, NaN];
+	warning ("pcg: eigenvalue estimate failed: iteration converged too fast.");
+      endif
+    else
+      eigest = [NaN, NaN];
+    endif
+
+    ## Apply the preconditioner once more and finish with the precond
+    ## residual.
+    if (exist_m1)
+      if (isnumeric (m1))
+	y = m1 \ r;
+      else
+	y = feval (m1, r, varargin{:});
+      endif
+    else
+      y = r;
+    endif
+    if (exist_m2)
+      if (isnumeric (m2))
+	z = m2 \ y;
+      else
+	z = feval (m2, y, varargin{:});
+      endif
+    else
+      z = y;
+    endif
+
+    resvec (iter-1,2) = sqrt (r' * z);
+  else
+    resvec = resvec(:,1);
+  endif
+
+  flag = 0;
+  relres = resvec (iter-1,1) ./ resvec(1,1);
+  iter -= 2;
+  if (iter >= maxit - 2)
+    flag = 1;
+    if (nargout < 2)
+      warning ("pcg: maximum number of iterations (%d) reached\n", iter);
+      warning ("the initial residual norm was reduced %g times.\n", ...
+	       1.0 / relres);
+    endif
+  elseif (nargout < 2)
+    fprintf (stderr, "pcg: converged in %d iterations. ", iter);
+    fprintf (stderr, "the initial residual norm was reduced %g times.\n",...
+	     1.0/relres);
+  endif
+
+  if (! matrix_positive_definite)
+    flag = 3;
+    if (nargout < 2)
+      warning ("pcg: matrix not positive definite?\n");
+    endif
+  endif
+endfunction
+
+%!demo
+%!
+%!	# Simplest usage of pcg (see also 'help pcg')
+%!
+%!	N = 10; 
+%!	A = diag ([1:N]); b = rand (N, 1); y =  A \ b; #y is the true solution
+%!  	x = pcg (A, b);
+%!	printf('The solution relative error is %g\n', norm (x - y) / norm (y));
+%!
+%!	# You shouldn't be afraid if pcg issues some warning messages in this
+%!	# example: watch out in the second example, why it takes N iterations 
+%!	# of pcg to converge to (a very accurate, by the way) solution
+%!demo
+%!
+%!	# Full output from pcg, except for the eigenvalue estimates
+%!	# We use this output to plot the convergence history  
+%!
+%!	N = 10; 
+%!	A = diag ([1:N]); b = rand (N, 1); X =  A \ b; #X is the true solution
+%!  	[x, flag, relres, iter, resvec] = pcg (A, b);
+%!	printf('The solution relative error is %g\n', norm (x - X) / norm (X));
+%!	title('Convergence history'); xlabel('Iteration'); ylabel('log(||b-Ax||/||b||)');
+%!	semilogy([0:iter], resvec / resvec(1),'o-g');
+%!      legend('relative residual');
+%!demo
+%!
+%!	# Full output from pcg, including the eigenvalue estimates
+%!	# Hilbert matrix is extremely ill conditioned, so pcg WILL have problems
+%!
+%!	N = 10; 
+%!	A = hilb (N); b = rand (N, 1); X = A \ b; #X is the true solution
+%!  	[x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], 200);
+%!	printf('The solution relative error is %g\n', norm (x - X) / norm (X));
+%!	printf('Condition number estimate is %g\n', eigest(2) / eigest (1));
+%!	printf('Actual condition number is   %g\n', cond (A));
+%!	title('Convergence history'); xlabel('Iteration'); ylabel('log(||b-Ax||)');
+%!	semilogy([0:iter], resvec,['o-g';'+-r']);
+%!      legend('absolute residual','absolute preconditioned residual');
+%!demo
+%!
+%!	# Full output from pcg, including the eigenvalue estimates
+%!	# We use the 1-D Laplacian matrix for A, and cond(A) = O(N^2)
+%!	# and that's the reasone we need some preconditioner; here we take
+%!	# a very simple and not powerful Jacobi preconditioner, 
+%!	# which is the diagonal of A
+%!
+%!	N = 100; 
+%!	A = zeros (N, N);
+%!	for i=1 : N - 1 # form 1-D Laplacian matrix
+%!		A (i:i+1, i:i+1) = [2 -1; -1 2];
+%!	endfor
+%!	b = rand (N, 1); X = A \ b; #X is the true solution
+%!	maxit = 80;
+%!	printf('System condition number is %g\n', cond (A));
+%!	# No preconditioner: the convergence is very slow!
+%!
+%!  	[x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit);
+%!	printf('System condition number estimate is %g\n', eigest(2) / eigest(1));
+%!	title('Convergence history'); xlabel('Iteration'); ylabel('log(||b-Ax||)');
+%!	semilogy([0:iter], resvec(:,1), 'o-g');
+%!      legend('NO preconditioning: absolute residual');
+%!
+%!	pause(1);
+%!	# Test Jacobi preconditioner: it will not help much!!!
+%!
+%!	M = diag (diag (A)); # Jacobi preconditioner
+%!  	[x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit, M);
+%!	printf('JACOBI preconditioned system condition number estimate is %g\n', eigest(2) / eigest(1));
+%!	hold on;
+%!	semilogy([0:iter], resvec(:,1), 'o-r');
+%!      legend('NO preconditioning: absolute residual', ...
+%!             'JACOBI preconditioner: absolute residual');
+%!
+%!	pause(1);
+%!	# Test nonoverlapping block Jacobi preconditioner: it will help much!
+%!
+%!	M = zeros (N, N); k = 4;
+%!	for i = 1 : k : N # form 1-D Laplacian matrix
+%!		M (i:i+k-1, i:i+k-1) = A (i:i+k-1, i:i+k-1);
+%!	endfor
+%!  	[x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit, M);
+%!	printf('BLOCK JACOBI preconditioned system condition number estimate is %g\n', eigest(2) / eigest(1));
+%!	semilogy ([0:iter], resvec(:,1),'o-b');
+%!      legend('NO preconditioning: absolute residual', ...
+%!             'JACOBI preconditioner: absolute residual', ...
+%!             'BLOCK JACOBI preconditioner: absolute residual');
+%!	hold off;
+%!test
+%!
+%!	#solve small diagonal system
+%!
+%!	N = 10; 
+%!	A = diag ([1:N]); b = rand (N, 1); X = A \ b; #X is the true solution
+%!  	[x, flag] = pcg (A, b, [], N+1);
+%!	assert(norm (x - X) / norm (X), 0, 1e-10);
+%!	assert(flag, 0);
+%!
+%!test
+%!
+%!	#solve small indefinite diagonal system
+%!	#despite A is indefinite, the iteration continues and converges
+%!	#indefiniteness of A is detected
+%!
+%!	N = 10; 
+%!	A = diag([1:N] .* (-ones(1, N) .^ 2)); b = rand (N, 1); X = A \ b; #X is the true solution
+%!  	[x, flag] = pcg (A, b, [], N+1);
+%!	assert(norm (x - X) / norm (X), 0, 1e-10);
+%!	assert(flag, 3);
+%!
+%!test
+%!
+%!	#solve tridiagonal system, do not converge in default 20 iterations
+%!
+%!	N = 100; 
+%!	A = zeros (N, N);
+%!	for i = 1 : N - 1 # form 1-D Laplacian matrix
+%!		A (i:i+1, i:i+1) = [2 -1; -1 2];
+%!	endfor
+%!	b = ones (N, 1); X = A \ b; #X is the true solution
+%!  	[x, flag, relres, iter, resvec, eigest] = pcg (A, b, 1e-12);
+%!	assert(flag);
+%!	assert(relres > 1.0);
+%!	assert(iter, 20); #should perform max allowable default number of iterations
+%!
+%!test
+%!
+%!	#solve tridiagonal system with 'prefect' preconditioner
+%!	#converges in one iteration, so the eigest does not work
+%!	#and issues a warning
+%!
+%!	N = 100; 
+%!	A = zeros (N, N);
+%!	for i = 1 : N - 1 # form 1-D Laplacian matrix
+%!		A (i:i+1, i:i+1) = [2 -1; -1 2];
+%!	endfor
+%!	b = ones (N, 1); X = A \ b; #X is the true solution
+%!  	[x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], [], A, [], b);
+%!	assert(norm (x - X) / norm (X), 0, 1e-6);
+%!	assert(flag, 0);
+%!	assert(iter, 1); #should converge in one iteration
+%!	assert(isnan (eigest), isnan ([NaN, NaN]));
+%!
diff --git a/scripts/sparse/pcr.m b/scripts/sparse/pcr.m
new file mode 100644
index 0000000..61081d9
--- /dev/null
+++ b/scripts/sparse/pcr.m
@@ -0,0 +1,430 @@
+## Copyright (C) 2004, 2006, 2007, 2009 Piotr Krzyzanowski
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} pcr (@var{a}, @var{b}, @var{tol}, @var{maxit}, @var{m}, @var{x0}, @dots{})
+## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} pcr (@dots{})
+## 
+## Solves the linear system of equations @code{@var{a} * @var{x} =
+## @var{b}} by means of the Preconditioned Conjugate Residuals iterative
+## method.  The input arguments are
+##
+## @itemize
+## @item
+## @var{a} can be either a square (preferably sparse) matrix or a
+## function handle, inline function or string containing the name
+## of a function which computes @code{@var{a} * @var{x}}.  In principle
+## @var{a} should be symmetric and non-singular; if @code{pcr}
+## finds @var{a} to be numerically singular, you will get a warning
+## message and the @var{flag} output parameter will be set.
+## 
+## @item
+## @var{b} is the right hand side vector.
+## 
+## @item
+## @var{tol} is the required relative tolerance for the residual error,
+## @code{@var{b} - @var{a} * @var{x}}.  The iteration stops if @code{norm
+## (@var{b} - @var{a} * @var{x}) <= @var{tol} * norm (@var{b} - @var{a} *
+## @var{x0})}.  If @var{tol} is empty or is omitted, the function sets
+## @code{@var{tol} = 1e-6} by default.
+## 
+## @item
+## @var{maxit} is the maximum allowable number of iterations; if
+## @code{[]} is supplied for @code{maxit}, or @code{pcr} has less
+## arguments, a default value equal to 20 is used.
+##
+## @item
+## @var{m} is the (left) preconditioning matrix, so that the iteration is
+## (theoretically) equivalent to solving by @code{pcr} @code{@var{P} *
+## @var{x} = @var{m} \ @var{b}}, with @code{@var{P} = @var{m} \ @var{a}}.
+## Note that a proper choice of the preconditioner may dramatically
+## improve the overall performance of the method.  Instead of matrix
+## @var{m}, the user may pass a function which returns the results of 
+## applying the inverse of @var{m} to a vector (usually this is the
+## preferred way of using the preconditioner).  If @code{[]} is supplied
+## for @var{m}, or @var{m} is omitted, no preconditioning is applied.
+## 
+## @item
+## @var{x0} is the initial guess.  If @var{x0} is empty or omitted, the 
+## function sets @var{x0} to a zero vector by default.
+## @end itemize
+## 
+## The arguments which follow @var{x0} are treated as parameters, and
+## passed in a proper way to any of the functions (@var{a} or @var{m})
+## which are passed to @code{pcr}.  See the examples below for further
+## details.  The output arguments are
+##
+## @itemize
+## @item
+## @var{x} is the computed approximation to the solution of
+## @code{@var{a} * @var{x} = @var{b}}.
+## 
+## @item
+## @var{flag} reports on the convergence.  @code{@var{flag} = 0} means
+## the solution converged and the tolerance criterion given by @var{tol}
+## is satisfied.  @code{@var{flag} = 1} means that the @var{maxit} limit
+## for the iteration count was reached.  @code{@var{flag} = 3} reports t
+## @code{pcr} breakdown, see [1] for details.
+## 
+## @item
+## @var{relres} is the ratio of the final residual to its initial value,
+## measured in the Euclidean norm.
+## 
+## @item
+## @var{iter} is the actual number of iterations performed.
+##
+## @item 
+## @var{resvec} describes the convergence history of the method,
+## so that @code{@var{resvec} (i)} contains the Euclidean norms of the 
+## residual after the (@var{i}-1)-th iteration, @code{@var{i} =
+## 1,2, @dots{}, @var{iter}+1}.
+## @end itemize
+## 
+## Let us consider a trivial problem with a diagonal matrix (we exploit the
+## sparsity of A) 
+## 
+## @example
+## @group
+## 	n = 10; 
+## 	a = sparse (diag (1:n));
+## 	b = rand (N, 1);
+## @end group
+## @end example
+## 
+## @sc{Example 1:} Simplest use of @code{pcr}
+## 
+## @example
+##   x = pcr(A, b)
+## @end example
+## 
+## @sc{Example 2:} @code{pcr} with a function which computes
+## @code{@var{a} * @var{x}}.
+##
+## @example
+## @group
+##   function y = apply_a (x) 
+##     y = [1:10]'.*x; 
+##   endfunction
+## 
+##   x = pcr ("apply_a", b)
+## @end group
+## @end example
+## 
+## @sc{Example 3:}  Preconditioned iteration, with full diagnostics.  The
+## preconditioner (quite strange, because even the original matrix
+## @var{a} is trivial) is defined as a function
+## 
+## @example
+## @group
+##   function y = apply_m (x)		
+##     k = floor (length(x)-2); 
+##     y = x; 
+##     y(1:k) = x(1:k)./[1:k]';	
+##   endfunction
+## 
+##   [x, flag, relres, iter, resvec] = ...
+##                      pcr (a, b, [], [], "apply_m")
+##   semilogy([1:iter+1], resvec);
+## @end group
+## @end example
+##
+## @sc{Example 4:} Finally, a preconditioner which depends on a
+## parameter @var{k}.
+## 
+## @example
+## @group
+##   function y = apply_m (x, varargin)
+##     k = varargin@{1@}; 
+##     y = x; y(1:k) = x(1:k)./[1:k]';	 
+##   endfunction
+## 
+##   [x, flag, relres, iter, resvec] = ...
+##                      pcr (a, b, [], [], "apply_m"', [], 3)
+## @end group
+## @end example
+## 
+## @sc{References}
+## 
+## 	[1] W. Hackbusch, "Iterative Solution of Large Sparse Systems of
+##  	Equations", section 9.5.4; Springer, 1994
+##
+## @seealso{sparse, pcg}
+## @end deftypefn
+
+## Author: Piotr Krzyzanowski <piotr.krzyzanowski at mimuw.edu.pl>
+
+function [x, flag, relres, iter, resvec] = pcr (a, b, tol, maxit, m, x0, varargin)
+
+  breakdown = false;
+
+  if (nargin < 6 || isempty (x0))
+    x = zeros (size (b));
+  else
+    x = x0;
+  endif
+
+  if (nargin < 5)
+    m = [];
+  endif
+
+  if (nargin < 4 || isempty (maxit))
+    maxit = 20;
+  endif
+
+  maxit += 2;
+
+  if (nargin < 3 || isempty (tol))
+    tol = 1e-6;
+  endif
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  ##  init
+  if (isnumeric (a))		# is A a matrix?
+    r = b - a*x;
+  else				# then A should be a function!
+    r = b - feval (a, x, varargin{:});
+  endif
+
+  if (isnumeric (m))		# is M a matrix?
+    if (isempty (m))		# if M is empty, use no precond
+      p = r;
+    else			# otherwise, apply the precond
+      p = m \ r;
+    endif
+  else				# then M should be a function!
+    p = feval (m, r, varargin{:});
+  endif
+
+  iter = 2;
+
+  b_bot_old = 1;
+  q_old = p_old = s_old = zeros (size (x));
+
+  if (isnumeric (a))		# is A a matrix?
+    q = a * p;
+  else				# then A should be a function!
+    q = feval (a, p, varargin{:});
+  endif
+	
+  resvec(1) = abs (norm (r)); 
+
+  ## iteration
+  while (resvec(iter-1) > tol*resvec(1) && iter < maxit)
+
+    if (isnumeric (m))		# is M a matrix?
+      if (isempty (m))		# if M is empty, use no precond
+	s = q;
+      else			# otherwise, apply the precond
+	s = m \ q;
+      endif
+    else			# then M should be a function!
+      s = feval (m, q, varargin{:});
+    endif
+    b_top = r' * s;
+    b_bot = q' * s;
+	
+    if (b_bot == 0.0)
+      breakdown = true;
+      break;
+    endif
+    lambda = b_top / b_bot;
+	
+    x += lambda*p;
+    r -= lambda*q;
+	
+    if (isnumeric(a))		# is A a matrix?
+      t = a*s;
+    else			# then A should be a function!
+      t = feval (a, s, varargin{:});
+    endif
+	
+    alpha0 = (t'*s) / b_bot;
+    alpha1 = (t'*s_old) / b_bot_old;
+	
+    p_temp = p;
+    q_temp = q;
+
+    p = s - alpha0*p - alpha1*p_old;
+    q = t - alpha0*q - alpha1*q_old;
+	
+    s_old = s;
+    p_old = p_temp;
+    q_old = q_temp;
+    b_bot_old = b_bot;
+	
+    resvec(iter) = abs (norm (r));
+    iter++;
+  endwhile
+
+  flag = 0;
+  relres = resvec(iter-1) ./ resvec(1);
+  iter -= 2;
+  if (iter >= maxit-2)
+    flag = 1;
+    if (nargout < 2)
+      warning ("pcr: maximum number of iterations (%d) reached\n", iter);
+      warning ("the initial residual norm was reduced %g times.\n", 1.0/relres);
+    endif
+  elseif (nargout < 2 && ! breakdown)
+    fprintf (stderr, "pcr: converged in %d iterations. \n", iter);
+    fprintf (stderr, "the initial residual norm was reduced %g times.\n",
+	     1.0 / relres);
+  endif
+
+  if (breakdown)
+    flag = 3;
+    if (nargout < 2)
+      warning ("pcr: breakdown occurred:\n");
+      warning ("system matrix singular or preconditioner indefinite?\n");
+    endif
+  endif
+
+endfunction
+
+%!demo
+%!
+%!	# Simplest usage of PCR (see also 'help pcr')
+%!
+%!	N = 20; 
+%!	A = diag(linspace(-3.1,3,N)); b = rand(N,1); y = A\b; #y is the true solution
+%!  	x = pcr(A,b);
+%!	printf('The solution relative error is %g\n', norm(x-y)/norm(y));
+%!
+%!	# You shouldn't be afraid if PCR issues some warning messages in this
+%!	# example: watch out in the second example, why it takes N iterations 
+%!	# of PCR to converge to (a very accurate, by the way) solution
+%!demo
+%!
+%!	# Full output from PCR
+%!	# We use this output to plot the convergence history  
+%!
+%!	N = 20; 
+%!	A = diag(linspace(-3.1,30,N)); b = rand(N,1); X = A\b; #X is the true solution
+%!  	[x, flag, relres, iter, resvec] = pcr(A,b);
+%!	printf('The solution relative error is %g\n', norm(x-X)/norm(X));
+%!	title('Convergence history'); xlabel('Iteration'); ylabel('log(||b-Ax||/||b||)');
+%!	semilogy([0:iter],resvec/resvec(1),'o-g;relative residual;');
+%!demo
+%!
+%!	# Full output from PCR
+%!	# We use indefinite matrix based on the Hilbert matrix, with one
+%!	# strongly negative eigenvalue
+%!	# Hilbert matrix is extremely ill conditioned, so is ours, 
+%!	# and that's why PCR WILL have problems
+%!
+%!	N = 10; 
+%!	A = hilb(N); A(1,1)=-A(1,1); b = rand(N,1); X = A\b; #X is the true solution
+%!	printf('Condition number of A is   %g\n', cond(A));
+%!  	[x, flag, relres, iter, resvec] = pcr(A,b,[],200);
+%!	if (flag == 3)
+%!	  printf('PCR breakdown. System matrix is [close to] singular\n');
+%!	end
+%!	title('Convergence history'); xlabel('Iteration'); ylabel('log(||b-Ax||)');
+%!	semilogy([0:iter],resvec,'o-g;absolute residual;');
+%!demo
+%!
+%!	# Full output from PCR
+%!	# We use an indefinite matrix based on the 1-D Laplacian matrix for A, 
+%!	# and here we have cond(A) = O(N^2)
+%!	# That's the reason we need some preconditioner; here we take
+%!	# a very simple and not powerful Jacobi preconditioner, 
+%!	# which is the diagonal of A
+%!
+%!	# Note that we use here indefinite preconditioners!
+%!
+%!	N = 100; 
+%!	A = zeros(N,N);
+%!	for i=1:N-1 # form 1-D Laplacian matrix
+%!		A(i:i+1,i:i+1) = [2 -1; -1 2];
+%!	endfor
+%!	A = [A, zeros(size(A)); zeros(size(A)), -A];
+%!	b = rand(2*N,1); X = A\b; #X is the true solution
+%!	maxit = 80;
+%!	printf('System condition number is %g\n',cond(A));
+%!	# No preconditioner: the convergence is very slow!
+%!
+%!  	[x, flag, relres, iter, resvec] = pcr(A,b,[],maxit);
+%!	title('Convergence history'); xlabel('Iteration'); ylabel('log(||b-Ax||)');
+%!	semilogy([0:iter],resvec,'o-g;NO preconditioning: absolute residual;');
+%!
+%!	pause(1);
+%!	# Test Jacobi preconditioner: it will not help much!!!
+%!
+%!	M = diag(diag(A)); # Jacobi preconditioner
+%!  	[x, flag, relres, iter, resvec] = pcr(A,b,[],maxit,M);
+%!	hold on;
+%!	semilogy([0:iter],resvec,'o-r;JACOBI preconditioner: absolute residual;');
+%!
+%!	pause(1);
+%!	# Test nonoverlapping block Jacobi preconditioner: this one should give
+%!	# some convergence speedup!
+%!
+%!	M = zeros(N,N);k=4;
+%!	for i=1:k:N # get k x k diagonal blocks of A
+%!		M(i:i+k-1,i:i+k-1) = A(i:i+k-1,i:i+k-1);
+%!	endfor
+%!	M = [M, zeros(size(M)); zeros(size(M)), -M];
+%!  	[x, flag, relres, iter, resvec] = pcr(A,b,[],maxit,M);
+%!	semilogy([0:iter],resvec,'o-b;BLOCK JACOBI preconditioner: absolute residual;');
+%!	hold off;
+%!test
+%!
+%!	#solve small indefinite diagonal system
+%!
+%!	N = 10; 
+%!	A = diag(linspace(-10.1,10,N)); b = ones(N,1); X = A\b; #X is the true solution
+%!  	[x, flag] = pcr(A,b,[],N+1);
+%!	assert(norm(x-X)/norm(X)<1e-10);
+%!	assert(flag,0);
+%!
+%!test
+%!
+%!	#solve tridiagonal system, do not converge in default 20 iterations
+%!	#should perform max allowable default number of iterations
+%!
+%!	N = 100; 
+%!	A = zeros(N,N);
+%!	for i=1:N-1 # form 1-D Laplacian matrix
+%!		A(i:i+1,i:i+1) = [2 -1; -1 2];
+%!	endfor
+%!	b = ones(N,1); X = A\b; #X is the true solution
+%!  	[x, flag, relres, iter, resvec] = pcr(A,b,1e-12);
+%!	assert(flag,1);
+%!	assert(relres>0.6);
+%!	assert(iter,20);
+%!
+%!test
+%!
+%!	#solve tridiagonal system with 'prefect' preconditioner
+%!	#converges in one iteration
+%!
+%!	N = 100; 
+%!	A = zeros(N,N);
+%!	for i=1:N-1 # form 1-D Laplacian matrix
+%!		A(i:i+1,i:i+1) = [2 -1; -1 2];
+%!	endfor
+%!	b = ones(N,1); X = A\b; #X is the true solution
+%!  	[x, flag, relres, iter] = pcr(A,b,[],[],A,b);
+%!	assert(norm(x-X)/norm(X)<1e-6);
+%!	assert(relres<1e-6);
+%!	assert(flag,0);
+%!	assert(iter,1); #should converge in one iteration
+%!
diff --git a/scripts/sparse/spalloc.m b/scripts/sparse/spalloc.m
new file mode 100644
index 0000000..9332578
--- /dev/null
+++ b/scripts/sparse/spalloc.m
@@ -0,0 +1,52 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{s} =} spalloc (@var{r}, @var{c}, @var{nz})
+## Returns an empty sparse matrix of size @var{r}-by- at var{c}.  As Octave
+## resizes sparse matrices at the first opportunity, so that no additional 
+## space is needed, the argument @var{nz} is ignored.  This function is 
+## provided only for compatibility reasons.
+##
+## It should be noted that this means that code like
+##
+## @example
+## @group
+## k = 5;
+## nz = r * k;
+## s = spalloc (r, c, nz)
+## for j = 1:c
+##   idx = randperm (r);
+##   s (:, j) = [zeros(r - k, 1); rand(k, 1)] (idx);
+## endfor
+## @end group
+## @end example
+##
+## will reallocate memory at each step.  It is therefore vitally important
+## that code like this is vectorized as much as possible.
+## @seealso{sparse, nzmax}
+## @end deftypefn
+
+function s = spalloc (r, c, nz)
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  s = sparse (r, c);
+endfunction
diff --git a/scripts/sparse/spaugment.m b/scripts/sparse/spaugment.m
new file mode 100644
index 0000000..f66d5ec
--- /dev/null
+++ b/scripts/sparse/spaugment.m
@@ -0,0 +1,102 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{s} =} spaugment (@var{a}, @var{c})
+## Creates the augmented matrix of @var{a}.  This is given by
+##
+## @example
+## @group
+## [@var{c} * eye(@var{m}, @var{m}), at var{a}; @var{a}', zeros(@var{n},
+## @var{n})]
+## @end group
+## @end example
+##
+## @noindent
+## This is related to the least squares solution of 
+## @code{@var{a} \\ @var{b}}, by
+## 
+## @example
+## @group
+## @var{s} * [ @var{r} / @var{c}; x] = [@var{b}, zeros(@var{n},
+## columns(@var{b})]
+## @end group
+## @end example
+##
+## @noindent
+## where @var{r} is the residual error
+##
+## @example
+## @var{r} = @var{b} - @var{a} * @var{x}
+## @end example
+##
+## As the matrix @var{s} is symmetric indefinite it can be factorized
+## with @code{lu}, and the minimum norm solution can therefore be found
+## without the need for a @code{qr} factorization.  As the residual
+## error will be @code{zeros (@var{m}, @var{m})} for under determined
+## problems, and example can be 
+##
+## @example
+## @group
+## m = 11; n = 10; mn = max(m ,n);
+## a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],
+##              [-1, 0, 1], m, n);
+## x0 = a \ ones (m,1);
+## s = spaugment (a);
+## [L, U, P, Q] = lu (s);
+## x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+## x1 = x1(end - n + 1 : end);
+## @end group
+## @end example
+##
+## To find the solution of an overdetermined problem needs an estimate
+## of the residual error @var{r} and so it is more complex to formulate
+## a minimum norm solution using the @code{spaugment} function.
+##
+## In general the left division operator is more stable and faster than
+## using the @code{spaugment} function.
+## @end deftypefn
+
+function s = spaugment (a, c)
+  if (nargin < 2)
+    if (issparse (a))
+      c = max (max (abs (a))) / 1000;
+    else
+      if (ndims (a) != 2)
+	error ("spaugment: expecting 2-dimenisional matrix")
+      else
+	c = max (abs (a(:))) / 1000;
+      endif
+    endif
+  elseif (!isscalar (c))
+    error ("spaugment: c must be a scalar");
+  endif
+
+  [m, n] = size (a);
+  s = [ c * speye(m, m), a; a', sparse(n, n)];
+endfunction
+
+%!testif HAVE_UMFPACK
+%! m = 11; n = 10; mn = max(m ,n);
+%! a = spdiags ([ones(mn,1), 10*ones(mn,1), -ones(mn,1)],[-1,0,1], m, n);
+%! x0 = a \ ones (m,1);
+%! s = spaugment (a);
+%! [L, U, P, Q] = lu (s);
+%! x1 = Q * (U \ (L \ (P  * [ones(m,1); zeros(n,1)])));
+%! x1 = x1(end - n + 1 : end);
+%! assert (x1, x0, 1e-6)
diff --git a/scripts/sparse/spconvert.m b/scripts/sparse/spconvert.m
new file mode 100644
index 0000000..072647a
--- /dev/null
+++ b/scripts/sparse/spconvert.m
@@ -0,0 +1,45 @@
+## Copyright (C) 2004, 2005, 2007, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{x} =} spconvert (@var{m})
+## This function converts for a simple sparse matrix format easily
+## produced by other programs into Octave's internal sparse format.  The
+## input @var{x} is either a 3 or 4 column real matrix, containing
+## the row, column, real and imaginary parts of the elements of the
+## sparse matrix.  An element with a zero real and imaginary part can
+## be used to force a particular matrix size.
+## @end deftypefn
+
+function s = spconvert (m)
+
+  if (issparse (m))
+    s = m;
+  else
+    sz = size (m);
+    if (nargin != 1 || ! ismatrix (m) || ! isreal (m)
+	|| length (sz) != 2 || (sz(2) != 3 && sz(2) != 4))
+      error ("spconvert: argument must be sparse or real matrix with 3 or 4 columns");
+    elseif (sz(2) == 3)
+      s = sparse (m(:,1), m(:,2), m(:,3));
+    else
+      s = sparse (m(:,1), m(:,2), m(:,3) + 1i*m(:,4));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/sparse/spdiags.m b/scripts/sparse/spdiags.m
new file mode 100644
index 0000000..f628554
--- /dev/null
+++ b/scripts/sparse/spdiags.m
@@ -0,0 +1,88 @@
+## Copyright (C) 2000, 2001, 2004, 2005, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{b}, @var{c}] =} spdiags (@var{a})
+## @deftypefnx {Function File} {@var{b} =} spdiags (@var{a}, @var{c})
+## @deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{a})
+## @deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{m}, @var{n})
+## A generalization of the function @code{diag}.  Called with a single
+## input argument, the non-zero diagonals @var{c} of @var{A} are extracted.
+## With two arguments the diagonals to extract are given by the vector 
+## @var{c}.
+##
+## The other two forms of @code{spdiags} modify the input matrix by
+## replacing the diagonals.  They use the columns of @var{v} to replace
+## the columns represented by the vector @var{c}.  If the sparse matrix
+## @var{a} is defined then the diagonals of this matrix are replaced.
+## Otherwise a matrix of @var{m} by @var{n} is created with the
+## diagonals given by @var{v}.
+##
+## Negative values of @var{c} represent diagonals below the main
+## diagonal, and positive values of @var{c} diagonals above the main
+## diagonal.
+##
+## For example
+##
+## @example
+## @group
+## spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
+## @result{}    5 10  0  0
+##       1  6 11  0
+##       0  2  7 12
+##       0  0  3  8
+##       0  0  0  4
+## @end group
+## @end example
+##
+## @end deftypefn
+
+function [A, c] = spdiags (v, c, m, n)
+
+  if (nargin == 1 || nargin == 2)
+    ## extract nonzero diagonals of v into A,c
+    [nr, nc] = size (v);
+    [i, j, v] = find (v);
+
+    if (nargin == 1)
+      ## c contains the active diagonals
+      c = unique (j-i);
+    endif
+    ## FIXME: we can do this without a loop if we are clever
+    offset = max (min (c, nc-nr), 0);
+    A = zeros (min (nr, nc), length (c));
+    for k = 1:length (c)
+      idx = find (j-i == c(k));
+      A(j(idx)-offset(k),k) = v(idx);
+    endfor
+  elseif (nargin == 3)
+    ## Replace specific diagonals c of m with v,c
+    [nr, nc] = size (m);
+    B = spdiags (m, c);
+    A = m - spdiags (B, c, nr, nc) + spdiags (v, c, nr, nc);
+  else
+    ## Create new matrix of size mxn using v,c
+    [j, i, v] = find (v);
+    offset = max (min (c(:), n-m), 0);
+    j = j(:) + offset(i);
+    i = j-c(:)(i);
+    idx = i > 0 & i <= m & j > 0 & j <= n;
+    A = sparse (i(idx), j(idx), v(idx), m, n);
+  endif
+
+endfunction
diff --git a/scripts/sparse/speye.m b/scripts/sparse/speye.m
new file mode 100644
index 0000000..5913757
--- /dev/null
+++ b/scripts/sparse/speye.m
@@ -0,0 +1,57 @@
+## Copyright (C) 2004, 2005, 2007, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} speye (@var{m})
+## @deftypefnx {Function File} {@var{y} =} speye (@var{m}, @var{n})
+## @deftypefnx {Function File} {@var{y} =} speye (@var{sz})
+## Returns a sparse identity matrix.  This is significantly more
+## efficient than @code{sparse (eye (@var{m}))} as the full matrix
+## is not constructed.
+##
+## Called with a single argument a square matrix of size @var{m} by
+## @var{m} is created.  Otherwise a matrix of @var{m} by @var{n} is
+## created.  If called with a single vector argument, this argument 
+## is taken to be the size of the matrix to create.
+## @end deftypefn
+
+function s = speye (m, n)
+  if (nargin == 1)
+    if (isvector (m) && length(m) == 2)
+      n = m(2);
+      m = m(1);
+    elseif (isscalar (m))
+      n = m;
+    else
+      error ("speye: invalid matrix dimension");
+    endif
+  else
+    if (! isscalar (m) || ! isscalar (n))
+      error ("speye: invalid matrix dimension");
+    endif
+  endif
+
+  lo = min ([m, n]);
+  s = sparse (1:lo, 1:lo, 1, m, n);
+endfunction
+
+%!assert(issparse(speye(4)))
+%!assert(speye(4),sparse(1:4,1:4,1))
+%!assert(speye(2,4),sparse(1:2,1:2,1,2,4))
+%!assert(speye(4,2),sparse(1:2,1:2,1,4,2))
+%!assert(speye([4,2]),sparse(1:2,1:2,1,4,2))
diff --git a/scripts/sparse/spfun.m b/scripts/sparse/spfun.m
new file mode 100644
index 0000000..620089d
--- /dev/null
+++ b/scripts/sparse/spfun.m
@@ -0,0 +1,49 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+##               David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} spfun (@var{f}, at var{x})
+## Compute @code{f(@var{x})} for the non-zero values of @var{x}.
+## This results in a sparse matrix with the same structure as 
+## @var{x}.  The function @var{f} can be passed as a string, a
+## function handle or an inline function.
+## @end deftypefn
+
+function t = spfun (f, s)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [i, j, v] = find (s);
+  [m, n] = size (s);
+
+  if (isa (f, "function_handle") || isa (f, "inline function"))
+    t = sparse (i, j, f(v), m, n);
+  else
+    t = sparse(i, j, feval (f, v), m, n);
+  endif
+
+endfunction
+
+%!assert(spfun('exp',[1,2;3,0]),sparse([exp(1),exp(2);exp(3),0]))
+%!assert(spfun('exp',sparse([1,2;3,0])),sparse([exp(1),exp(2);exp(3),0]))
+%!assert(spfun(@exp,[1,2;3,0]),sparse([exp(1),exp(2);exp(3),0]))
+%!assert(spfun(@exp,sparse([1,2;3,0])),sparse([exp(1),exp(2);exp(3),0]))
+
diff --git a/scripts/sparse/sphcat.m b/scripts/sparse/sphcat.m
new file mode 100644
index 0000000..b098a5c
--- /dev/null
+++ b/scripts/sparse/sphcat.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} sphcat (@var{a1}, @var{a2}, @dots{}, @var{aN})
+## Return the horizontal concatenation of sparse matrices.  This function
+## is obselete and @code{horzcat} should be used.
+## @seealso {spvcat, vertcat, horzcat, cat}
+## @end deftypefn
+
+function y = sphcat (varargin)
+
+  persistent sphcat_warned = false;
+
+  if (! sphcat_warned)
+    sphcat_warned = true;
+    warning ("sphcat: This function is depreciated.  Use horzcat instead");
+  endif
+
+  y = horzcat (varargin{:});
+endfunction
diff --git a/scripts/sparse/spones.m b/scripts/sparse/spones.m
new file mode 100644
index 0000000..952db00
--- /dev/null
+++ b/scripts/sparse/spones.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2004, 2005, 2007, 2008, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} spones (@var{x})
+## Replace the non-zero entries of @var{x} with ones.  This creates a
+## sparse matrix with the same structure as @var{x}.
+## @end deftypefn
+
+function s = spones (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [i, j, v] = find (s);
+  [m, n] = size (s);
+
+  s = sparse (i, j, 1, m, n);
+
+endfunction
+
+%!assert(issparse(spones([1,2;3,0])))
+%!assert(spones([1,2;3,0]),sparse([1,1;1,0]))
+%!assert(spones(sparse([1,2;3,0])),sparse([1,1;1,0]))
diff --git a/scripts/sparse/sprand.m b/scripts/sparse/sprand.m
new file mode 100644
index 0000000..9f4b52e
--- /dev/null
+++ b/scripts/sparse/sprand.m
@@ -0,0 +1,76 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sprand (@var{m}, @var{n}, @var{d})
+## @deftypefnx {Function File} {} sprand (@var{s})
+## Generate a random sparse matrix.  The size of the matrix will be
+## @var{m} by @var{n}, with a density of values given by @var{d}.
+## @var{d} should be between 0 and 1. Values will be uniformly
+## distributed between 0 and 1.
+##
+## Note: sometimes the actual density may be a bit smaller than @var{d}. 
+## This is unlikely to happen for large really sparse matrices.
+##
+## If called with a single matrix argument, a random sparse matrix is
+## generated wherever the matrix @var{S} is non-zero.
+## @seealso{sprandn}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+##
+## Changelog:
+##
+## Piotr Krzyzanowski <przykry2004 at users.sf.net>
+## 	2004-09-27	use Paul's hint to allow larger random matrices
+##			at the price of sometimes lower density than desired
+## David Bateman 
+##      2004-10-20      Texinfo help and copyright message 
+
+function S = sprand (m, n, d)
+  if (nargin == 1)
+    [i, j, v] = find (m);
+    [nr, nc] = size (m);
+    S = sparse (i, j, rand (size (v)), nr, nc);
+  elseif (nargin == 3)
+    mn = n*m;
+    ## how many entries in S would be satisfactory?
+    k = round (d*mn);
+    idx = unique (fix (rand (min (k*1.01, k+10), 1) * mn)) + 1; 
+    ## idx contains random numbers in [1,mn]
+    ## generate 1% or 10 more random values than necessary in order to
+    ## reduce the probability that there are less than k distinct
+    ## values; maybe a better strategy could be used but I don't think
+    ## it's worth the price
+
+    ## actual number of entries in S
+    k = min (length (idx), k);
+    j = floor ((idx(1:k)-1)/m);
+    i = idx(1:k) - j*m;
+    if (isempty (i))
+      S = sparse (m, n);
+    else
+      S = sparse (i, j+1, rand (k, 1), m, n);
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
diff --git a/scripts/sparse/sprandn.m b/scripts/sparse/sprandn.m
new file mode 100644
index 0000000..b316948
--- /dev/null
+++ b/scripts/sparse/sprandn.m
@@ -0,0 +1,67 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sprandn (@var{m}, @var{n}, @var{d})
+## @deftypefnx {Function File} {} sprandn (@var{s})
+## Generate a random sparse matrix.  The size of the matrix will be
+## @var{m} by @var{n}, with a density of values given by @var{d}.
+## @var{d} should be between 0 and 1. Values will be normally
+## distributed with mean of zero and variance 1.
+##
+## Note: sometimes the actual density may be a bit smaller than @var{d}. 
+## This is unlikely to happen for large really sparse matrices.
+##
+## If called with a single matrix argument, a random sparse matrix is
+## generated wherever the matrix @var{S} is non-zero.
+## @seealso{sprand}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+
+function S = sprandn (m, n, d)
+  if (nargin == 1)
+    [i, j, v] = find (m);
+    [nr, nc] = size (m);
+    S = sparse (i, j, randn (size (v)), nr, nc);
+  elseif (nargin == 3)
+    mn = m*n;
+    k = round (d*mn);
+    idx = unique (fix (rand (min (k*1.01, k+10), 1) * mn)) + 1; 
+    ## idx contains random numbers in [1,mn]
+    ## generate 1% or 10 more random values than necessary in order to
+    ## reduce the probability that there are less than k distinct
+    ## values; maybe a better strategy could be used but I don't think
+    ## it's worth the price.
+
+    ## actual number of entries in S
+    k = min (length (idx), k);
+    j = floor ((idx(1:k)-1)/m);
+    i = idx(1:k) - j*m;
+    if (isempty (i))
+      S = sparse (m, n);
+    else
+      S = sparse (i, j+1, randn (k, 1), m, n);
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
diff --git a/scripts/sparse/sprandsym.m b/scripts/sparse/sprandsym.m
new file mode 100644
index 0000000..d8c6e43
--- /dev/null
+++ b/scripts/sparse/sprandsym.m
@@ -0,0 +1,77 @@
+## Copyright (C) 2004, 2006, 2007, 2008, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sprandsym (@var{n}, @var{d})
+## @deftypefnx {Function File} {} sprandsym (@var{s})
+## Generate a symmetric random sparse matrix.  The size of the matrix will be
+## @var{n} by @var{n}, with a density of values given by @var{d}.
+## @var{d} should be between 0 and 1. Values will be normally
+## distributed with mean of zero and variance 1.
+##
+## Note: sometimes the actual density may be a bit smaller than @var{d}. 
+## This is unlikely to happen for large really sparse matrices.
+##
+## If called with a single matrix argument, a random sparse matrix is
+## generated wherever the matrix @var{S} is non-zero in its lower
+## triangular part.
+## @seealso{sprand, sprandn}
+## @end deftypefn
+
+function S = sprandsym (n, d)
+  if (nargin == 1)
+    [i, j, v] = find (tril (n));
+    [nr, nc] = size (n);
+    S = sparse (i, j, randn (size (v)), nr, nc);
+    S = S + tril (S, -1)';
+  elseif (nargin == 2)
+    m1 = floor (n/2);
+    n1 = m1 + rem (n, 2);
+    mn1 = m1*n1;
+    k1 = round (d*mn1);
+    idx1 = unique (fix (rand (min (k1*1.01, k1+10), 1) * mn1)) + 1; 
+    ## idx contains random numbers in [1,mn] generate 1% or 10 more
+    ## random values than necessary in order to reduce the probability
+    ## that there are less than k distinct values; maybe a better
+    ## strategy could be used but I don't think it's worth the price.
+
+    ## Actual number of entries in S.
+    k1 = min (length (idx1), k1);
+    j1 = floor ((idx1(1:k1)-1)/m1);
+    i1 = idx1(1:k1) - j1*m1;
+
+    n2 = ceil (n/2);
+    nn2 = n2*n2;
+    k2 = round (d*nn2);
+    idx2 = unique (fix (rand (min (k2*1.01, k1+10), 1) * nn2)) + 1; 
+    k2 = min (length (idx2), k2);
+    j2 = floor ((idx2(1:k2)-1)/n2);
+    i2 = idx2(1:k2) - j2*n2;
+
+    if (isempty (i1) && isempty (i2))
+      S = sparse (n, n);
+    else
+      S1 = sparse (i1, j1+1, randn (k1, 1), m1, n1);
+      S = [tril(S1), sparse(m1,m1); ...
+	   sparse(i2,j2+1,randn(k2,1),n2,n2), triu(S1,1)'];
+      S = S + tril (S, -1)';
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
diff --git a/scripts/sparse/spstats.m b/scripts/sparse/spstats.m
new file mode 100644
index 0000000..6f9bb93
--- /dev/null
+++ b/scripts/sparse/spstats.m
@@ -0,0 +1,64 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{s})
+## @deftypefnx {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{s}, @var{j})
+## Return the stats for the non-zero elements of the sparse matrix @var{s}.
+## @var{count} is the number of non-zeros in each column, @var{mean}
+## is the mean of the non-zeros in each column, and @var{var} is the  
+## variance of the non-zeros in each column.
+##
+## Called with two input arguments, if @var{s} is the data and @var{j}
+## is the bin number for the data, compute the stats for each bin.  In 
+## this case, bins can contain data values of zero, whereas with 
+## @code{spstats (@var{s})} the zeros may disappear.
+## @end deftypefn
+
+function [count, mean, var] = spstats (S, j)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    [i, j, v] = find (S);
+  else
+    v = S;    
+    i = 1:length (v);
+    S = sparse (i, j, v);
+  endif 
+  [n, m] = size (S);
+
+  count = sum (sparse (i, j, 1, n, m));
+  if (nargout > 1) 
+    mean = sum (S) ./ count; 
+  endif
+  if (nargout > 2) 
+    ## FIXME Variance with count = 0 or 1?
+    diff = S - sparse (i, j, mean(j), n, m); 
+    var = sum (diff .* diff) ./ (count - 1);
+  endif
+
+endfunction
+
+%!test
+%! [n,m,v] = spstats([1 2 1 2 3 4],[2 2 1 1 1 1]);
+%! assert(n,sparse([4,2]));
+%! assert(m,sparse([10/4,3/2]),10*eps);
+%! assert(v,sparse([5/3,1/2]),10*eps);
diff --git a/scripts/sparse/spvcat.m b/scripts/sparse/spvcat.m
new file mode 100644
index 0000000..c104fc7
--- /dev/null
+++ b/scripts/sparse/spvcat.m
@@ -0,0 +1,36 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman and Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} spvcat (@var{a1}, @var{a2}, @dots{}, @var{aN})
+## Return the vertical concatenation of sparse matrices.  This function
+## is obselete and @code{vertcat} should be used
+## @seealso{sphcat, vertcat, horzcat, cat}
+## @end deftypefn
+
+function y = spvcat (varargin)
+
+  persistent spvcat_warned = false;
+
+  if (! spvcat_warned)
+    spvcat_warned = true;
+    warning ("spvcat: This function is depreciated. Use vertcat instead");
+  endif
+
+  y = vertcat (varargin{:});
+endfunction
diff --git a/scripts/sparse/spy.m b/scripts/sparse/spy.m
new file mode 100644
index 0000000..b831c64
--- /dev/null
+++ b/scripts/sparse/spy.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+##               2007, 2008, 2009 Andy Adler
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spy (@var{x})
+## @deftypefnx {Function File} {} spy (@dots{}, @var{markersize})
+## @deftypefnx {Function File} {} spy (@dots{}, @var{line_spec})
+## Plot the sparsity pattern of the sparse matrix @var{x}.  If the argument
+## @var{markersize} is given as an scalar value, it is used to determine the
+## point size in the plot.  If the string @var{line_spec} is given it is
+## passed to @code{plot} and determines the appearance of the plot.
+## @seealso{plot}
+## @end deftypefn
+
+function spy (x, varargin) 
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  markersize = NaN;
+  if (numel (i) < 1000)
+    line_spec = "*";
+  else
+    line_spec = ".";
+  endif
+  for i = 1:length (varargin)
+    if (ischar (varargin{i}))
+      line_spec = varargin{i};
+    elseif (isscalar (varargin{i}))
+      markersize = varargin{i};
+    else
+      error ("spy: expected markersize or linespec");
+    endif
+  endfor
+
+  [i, j, s] = find (x);
+  [m, n] = size (x);
+
+  if (isnan (markersize))
+    plot (j, i, line_spec);
+  else
+    plot (j, i, line_spec, "markersize", markersize);
+  endif
+
+  axis ([0, n+1, 0, m+1], "ij");
+
+endfunction
diff --git a/scripts/sparse/svds.m b/scripts/sparse/svds.m
new file mode 100644
index 0000000..b6869b1
--- /dev/null
+++ b/scripts/sparse/svds.m
@@ -0,0 +1,233 @@
+## Copyright (C) 2006, 2008, 2009 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 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 <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{s} =} svds (@var{a})
+## @deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k})
+## @deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k}, @var{sigma})
+## @deftypefnx {Function File} {@var{s} =} svds (@var{a}, @var{k}, @var{sigma}, @var{opts})
+## @deftypefnx {Function File} {[@var{u}, @var{s}, @var{v}, @var{flag}] =} svds (@dots{})
+##
+## Find a few singular values of the matrix @var{a}.  The singular values
+## are calculated using 
+##
+## @example
+## @group
+## [@var{m}, @var{n}] = size(@var{a})
+## @var{s} = eigs([sparse(@var{m}, @var{m}), @var{a}; ...
+##                 @var{a}', sparse(@var{n}, @var{n})])
+## @end group
+## @end example
+##
+## The eigenvalues returned by @code{eigs} correspond to the singular
+## values of @var{a}.  The number of singular values to calculate is given
+## by @var{k}, whose default value is 6.
+## 
+## The argument @var{sigma} can be used to specify which singular values
+## to find.  @var{sigma} can be either the string 'L', the default, in 
+## which case the largest singular values of @var{a} are found.  Otherwise
+## @var{sigma} should be a real scalar, in which case the singular values
+## closest to @var{sigma} are found.  Note that for relatively small values
+## of @var{sigma}, there is the chance that the requested number of singular
+## values are not returned.  In that case @var{sigma} should be increased.
+##
+## If @var{opts} is given, then it is a structure that defines options
+## that @code{svds} will pass to @var{eigs}.  The possible fields of this
+## structure are therefore determined by @code{eigs}.  By default three
+## fields of this structure are set by @code{svds}.
+##
+## @table @code
+## @item tol
+## The required convergence tolerance for the singular values.  @code{eigs}
+## is passed @var{tol} divided by @code{sqrt(2)}.  The default value is 
+## 1e-10.
+##
+## @item maxit
+## The maximum number of iterations.  The default is 300.
+##
+## @item disp
+## The level of diagnostic printout.  If @code{disp} is 0 then there is no
+## printout.  The default value is 0.
+## @end table
+##
+## If more than one output argument is given, then @code{svds} also
+## calculates the left and right singular vectors of @var{a}.  @var{flag}
+## is used to signal the convergence of @code{svds}.  If @code{svds} 
+## converges to the desired tolerance, then @var{flag} given by
+##
+## @example
+## @group
+## norm (@var{a} * @var{v} - @var{u} * @var{s}, 1) <= ...
+##         @var{tol} * norm (@var{a}, 1)
+## @end group
+## @end example
+##
+## will be zero.
+## @end deftypefn
+## @seealso{eigs}
+
+function [u, s, v, flag] = svds (a, k, sigma, opts)
+
+  persistent root2 = sqrt (2);
+
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 4)
+    opts.tol = 1e-10 / root2;
+    opts.disp = 0;
+    opts.maxit = 300;
+  else
+    if (!isstruct (opts))
+      error ("svds: opts must be a structure");
+    endif
+    if (!isfield (opts, "tol"))
+      opts.tol = 1e-10 / root2;
+    endif
+  endif
+
+  if (nargin < 3 || strcmp (sigma, "L"))
+    if (isreal (a))
+      sigma = "LA";
+    else
+      sigma = "LR";
+    endif
+  elseif (isscalar (sigma) && isreal (sigma))
+    if (sigma < 0)
+      error ("svds: sigma must be a positive real value");
+    endif
+  else
+    error ("svds: sigma must be a positive real value or the string 'L'");
+  endif
+
+  max_a = max (abs (a(:)));
+  if (max_a == 0)
+    u = eye (m, k);
+    s = zeros (k, k);
+    v = eye (n, k);
+  else
+    [m, n] = size (a);
+    if (nargin < 2)
+      k = min ([6, m, n]);
+    else
+      k = min ([k, m, n]);
+    endif
+
+    ## Scale everything by the 1-norm to make things more stable.
+    b = a / max_a;
+    b_opts = opts;
+    b_opts.tol = opts.tol / max_a;
+    b_sigma = sigma;
+    if (!ischar (b_sigma))
+      b_sigma = b_sigma / max_a;
+    endif
+
+    if (!ischar (b_sigma) && b_sigma == 0)
+      ## The eigenvalues returns by eigs are symmetric about 0. As we 
+      ## are only interested in the positive eigenvalues, we have to
+      ## double k. If sigma is smaller than the smallest singular value
+      ## this can also be an issue. However, we'd like to avoid double
+      ## k for all scalar value of sigma...
+      [V, s, flag] = eigs ([sparse(m,m), b; b', sparse(n,n)], 
+			   2 * k, b_sigma, b_opts);
+    else
+      [V, s, flag] = eigs ([sparse(m,m), b; b', sparse(n,n)],
+			   k, b_sigma, b_opts);
+    endif
+    s = diag (s);
+
+    if (ischar (sigma))
+      norma = max (s);
+    else
+      norma = normest (a);
+    endif
+    V = root2 * V;
+    u = V(1:m,:);
+    v = V(m+1:end,:);
+
+    ## We wish to exclude all eigenvalues that are less than zero as these
+    ## are artifacts of the way the matrix passed to eigs is formed. There 
+    ## is also the possibility that the value of sigma chosen is exactly 
+    ## a singular value, and in that case we're dead!! So have to rely on 
+    ## the warning from eigs. We exclude the singular values which are
+    ## less than or equal to zero to within some tolerance scaled by the
+    ## norm since if we don't we might end up with too many singular
+    ## values. What is appropriate for the tolerance?
+    tol = norma * opts.tol;
+    ind = find(s > tol);
+    if (length (ind) < k)
+      ## Find the zero eigenvalues of B, Ignore the eigenvalues that are 
+      ## nominally negative.
+      zind = find (abs (s) <= tol);
+      p = min (length (zind), k - length (ind));
+      ind = [ind; zind(1:p)];
+    elseif (length (ind) > k)
+      ind = ind(1:k);
+    endif
+    u = u(:,ind);
+    s = s(ind);
+    v = v(:,ind);
+
+    if (length (s) < k)
+      warning ("returning fewer singular values than requested");
+      if (!ischar (sigma))
+	warning ("try increasing the value of sigma");
+      endif
+    endif
+
+    s = s * max_a;
+  endif
+
+  if (nargout < 2)
+    u = s;
+  else
+    s = diag(s);
+    if (nargout > 3)
+      flag = norm (a*v - u*s, 1) > root2 * opts.tol * norm (a, 1);
+    endif
+  endif
+endfunction
+
+%!shared n, k, a, u, s, v, opts
+%! n = 100;
+%! k = 7;
+%! a = sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),0.4*n*ones(1,n),ones(1,n-2)]);
+%! %%a = sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]);
+%! [u,s,v] = svd(full(a));
+%! s = diag(s);
+%! [dum, idx] = sort(abs(s));
+%! s = s(idx);
+%! u = u(:,idx);
+%! v = v(:,idx);
+%! randn('state',42)
+%!testif HAVE_ARPACK
+%! [u2,s2,v2,flag] = svds(a,k);
+%! s2 = diag(s2);
+%! assert(flag,!1);
+%! assert(s(end:-1:end-k+1), s2, 1e-10); 
+%!testif HAVE_ARPACK
+%! [u2,s2,v2,flag] = svds(a,k,0);
+%! s2 = diag(s2);
+%! assert(flag,!1);
+%! assert(s(k:-1:1), s2, 1e-10); 
+%!testif HAVE_ARPACK
+%! idx = floor(n/2);
+%! % Don't put sigma right on a singular value or there are convergence 
+%! sigma = 0.99*s(idx) + 0.01*s(idx+1); 
+%! [u2,s2,v2,flag] = svds(a,k,sigma);
+%! s2 = diag(s2);
+%! assert(flag,!1);
+%! assert(s((idx+floor(k/2)):-1:(idx-floor(k/2))), s2, 1e-10); 
diff --git a/scripts/sparse/treelayout.m b/scripts/sparse/treelayout.m
new file mode 100644
index 0000000..e95e1bb
--- /dev/null
+++ b/scripts/sparse/treelayout.m
@@ -0,0 +1,209 @@
+## Copyright (C) 2008, 2009 Ivana Varekova & Radek Salac
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} treelayout (@var{Tree})
+## @deftypefnx {Function File} {} treelayout (@var{Tree}, @var{permutation})
+## treelayout lays out a tree or a forest.  The first argument @var{Tree} is a vector of
+## predecessors, optional parameter @var{permutation} is an optional postorder permutation.
+## The complexity of the algorithm is O(n) in
+## terms of time and memory requirements.
+## @seealso{etreeplot, gplot,treeplot}
+## @end deftypefn
+
+function [x_coordinate, y_coordinate, height, s] = treelayout (tree, permutation)
+  if (nargin < 1 || nargin > 2 || nargout > 4)
+    print_usage ();
+  elseif (! isvector (tree) || rows (tree) != 1 || ! isnumeric (tree) 
+          ||  any (tree > length (tree)) || any (tree < 0))
+    error ("treelayout: the first input argument must be a vector of predecessors");
+  else
+    ## Make it a row vector.
+    tree = tree(:)';
+
+    ## The count of nodes of the graph.
+    num_nodes = length (tree);
+    ## The number of children.
+    num_children = zeros (1, num_nodes + 1);
+
+    ## Checking vector of predecessors.
+    for i = 1 : num_nodes
+      if (tree(i) < i)
+	## This part of graph was checked before.
+        continue;
+      endif
+
+      ## Try to find cicle in this part of graph using modified Floyd's
+      ## cycle-finding algorithm.
+      tortoise = tree(i);
+      hare = tree(tortoise);
+
+      while (tortoise != hare)
+	## End after finding a cicle or reaching a checked part of graph.
+
+        if (hare < i)
+          ## This part of graph was checked before.
+          break
+        endif
+
+        tortoise = tree(tortoise);
+	## Hare will move faster than tortoise so in cicle hare must
+	## reach tortoise.
+        hare = tree(tree(hare));
+
+      endwhile
+
+      if (tortoise == hare)
+	## If hare reach tortoise we found circle.
+        error ("treelayout: vector of predecessors has bad format");
+      endif
+
+    endfor
+    ## Vector of predecessors has right format.
+
+    for i = 1:num_nodes
+      ## vec_of_child is helping vector which is used to speed up the
+      ## choice of descendant nodes.
+
+      num_children(tree(i)+1) = num_children(tree(i)+1) + 1;
+    endfor
+
+    pos = 1;
+    start = zeros (1, num_nodes+1);
+    xhelp = zeros (1, num_nodes+1);
+    stop = zeros (1, num_nodes+1);
+    for i = 1 : num_nodes + 1
+      start(i) = pos;
+      xhelp(i) = pos;
+      pos += num_children(i);
+      stop(i) = pos;
+    endfor
+
+    if (nargin == 1)
+      for i = 1:num_nodes
+        vec_of_child(xhelp(tree(i)+1)) = i;  
+        xhelp(tree(i)+1) = xhelp(tree(i)+1) + 1;
+      endfor
+    else
+      vec_of_child = permutation;
+    endif
+
+    ## The number of "parent" (actual) node (it's descendants will be
+    ## browse in the next iteration).
+    par_number = 0;
+
+    ## The x-coordinate of the left most descendant of "parent node"
+    ## this value is increased in each leaf.
+    left_most = 0;
+
+    ## The level of "parent" node (root level is num_nodes).
+    level = num_nodes;
+
+    ## num_nodes - max_ht is the height of this graph.
+    max_ht = num_nodes;
+
+    ## Main stack - each item consists of two numbers - the number of
+    ## node and the number it's of parent node on the top of stack
+    ## there is "parent node".
+    stk = [-1, 0];
+
+    ## Number of vertices s in the top-level separator.
+    s = 0;
+    ## Flag which says if we are in top level separator.
+    top_level = 1;
+    ## The top of the stack.
+    while (par_number != -1)
+      if (start(par_number+1) < stop(par_number+1))
+        idx = vec_of_child(start(par_number+1) : stop(par_number+1) - 1);
+      else
+        idx = zeros (1, 0);
+      endif
+
+      ## Add to idx the vector of parent descendants.
+      stk = [stk; [idx', ones(fliplr(size(idx))) * par_number]];
+
+      ## We are in top level separator when we have one child and the
+      ## flag is 1
+      if (columns(idx) == 1 && top_level == 1)
+        s++;
+      else
+        # We aren't in top level separator now.
+        top_level = 0;
+      endif
+      ## If there is not any descendant of "parent node":
+      if (stk(end,2) != par_number)
+       left_most++;
+       x_coordinate_r(par_number) = left_most;           
+       max_ht = min (max_ht, level);
+       if (length(stk) > 1 && find ((shift(stk,1)-stk) == 0) > 1
+	   && stk(end,2) != stk(end-1,2))
+	  ## Return to the nearest branching the position to return
+	  ## position is the position on the stack, where should be
+          ## started further search (there are two nodes which has the
+          ## same parent node).
+
+          position = (find ((shift (stk(:,2), 1) - stk(:,2)) == 0))(end) + 1;
+          par_number_vec = stk(position:end,2);
+
+          ## The vector of removed nodes (the content of stack form
+          ## position to end).
+
+          level += length (par_number_vec);
+
+	  ## The level have to be decreased.
+
+          x_coordinate_r(par_number_vec) = left_most;
+          stk(position:end,:) = [];
+        endif	
+
+        ## Remove the next node from "searched branch".
+
+        stk(end,:) = [];
+	## Choose new "parent node".
+        par_number = stk(end,1);
+	## If there is another branch start to search it.
+	if (par_number != -1)
+          y_coordinate(par_number) = level;	
+          x_coordinate_l(par_number) = left_most + 1;
+	endif
+      else
+
+        ## There were descendants of "parent nod" choose the last of
+        ## them and go on through it.
+        level--;
+        par_number = stk(end,1);
+        y_coordinate(par_number) = level;     
+        x_coordinate_l(par_number) = left_most + 1;
+      endif
+    endwhile
+
+    ## Calculate the x coordinates (the known values are the position
+    ## of most left and most right descendants).
+    x_coordinate = (x_coordinate_l + x_coordinate_r) / 2;
+
+    height = num_nodes - max_ht - 1;
+  endif
+endfunction
+
+%!demo
+%! % Compute a simple tree layout 
+%! [x,y,h,s]=treelayout([0 1 2 2])
+
+%!demo
+%! % Compute a simple tree layout with defined postorder permutation
+%! [x,y,h,s]=treelayout([0 1 2 2],[1 2 3 4]) 
diff --git a/scripts/sparse/treeplot.m b/scripts/sparse/treeplot.m
new file mode 100644
index 0000000..0eafa3d
--- /dev/null
+++ b/scripts/sparse/treeplot.m
@@ -0,0 +1,215 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Ivana Varekova
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} treeplot (@var{tree})
+## @deftypefnx {Function File} {} treeplot (@var{tree}, @var{line_style}, @var{edge_style})
+## Produces a graph of tree or forest.  The first argument is vector of
+## predecessors, optional parameters @var{line_style} and @var{edge_style}
+## define the output style.  The complexity of the algorithm is O(n) in
+## terms of is time and memory requirements.
+## @seealso{etreeplot, gplot}
+## @end deftypefn
+
+function treeplot (tree, node_s, edge_s)
+
+  if (nargin < 1 || nargin > 3 || nargout > 0)
+    print_usage ();
+  else
+    if (! ismatrix (tree) || rows (tree) != 1 || ! isnumeric (tree) 
+        || ! isvector (tree) || any (tree > length (tree)))
+      error ("treeplot: the first input argument must be a vector of predecessors");
+    else
+      ## The initialization of node end edge style.
+      node_style = "k*";
+      edge_style = "r";      
+      if (nargin > 2)
+        edge_style = edge_s;
+        if (nargin > 1) 
+	  if (length (findstr (node_s, "*")) == 0
+	      && length (findstr (node_s, "+")) == 0
+	      && length (findstr (node_s, "x")) == 0)
+	    node_style = [node_s, "o"];
+	  else
+	    node_style = node_s;
+	  endif
+        endif
+      endif
+
+      ## Make it a row vector.
+      tree = tree(:)';
+
+      ## The count of nodes of the graph.
+      num_nodes = length (tree);
+
+      ## The number of children.
+      num_children = zeros (1, num_nodes+1);
+      
+      for i = 1:num_nodes
+        ## VEC_OF_CHILD is helping vector which is used to speed up the
+        ## choose of descendant nodes.
+
+        num_children(tree(i)+1) = num_children(tree(i)+1) + 1;
+      endfor
+      pos = 1;
+      start = zeros (1, num_nodes+1);
+      xhelp = zeros (1, num_nodes+1);
+      stop = zeros (1, num_nodes+1);
+      for i = 1:num_nodes+1
+        start(i) = pos;
+	xhelp(i) = pos;
+	pos += num_children(i);
+	stop(i) = pos;
+      endfor
+      for i = 1:num_nodes        
+        vec_of_child(xhelp(tree(i)+1)) = i;  
+	xhelp(tree(i)+1) = xhelp(tree(i)+1)+1;
+      endfor
+
+      ## The number of "parent" (actual) node (it's descendants will be
+      ## browse in the next iteration).
+      par_number = 0;
+
+      ## The x-coordinate of the left most descendant of "parent node"
+      ## this value is increased in each leaf.
+      left_most = 0;
+
+      ## The level of "parent" node (root level is num_nodes).
+      level = num_nodes;
+
+      ## Num_nodes - max_ht is the height of this graph.
+      max_ht = num_nodes;
+
+      ## Main stack - each item consists of two numbers - the number of
+      ## node and the number it's of parent node on the top of stack
+      ## there is "parent node".
+      stk = [-1, 0];
+
+      ## Stack which is use to draw the graph edge (it have to be
+      ## uninterupted line).
+      skelet = 0;
+
+      ## The top of the stack.
+      while (par_number != -1)
+	if (start(par_number+1) < stop(par_number+1))
+	  idx = vec_of_child(start(par_number+1):stop(par_number+1)-1);
+	else
+	  idx = zeros (1, 0);
+	endif
+        ## Add to idx the vector of parent descendants.
+	stk = [stk; [idx', ones(fliplr(size(idx)))*par_number]];
+	## Add to stack the records relevant to parent descandant s.
+	if (par_number != 0)
+	  skelet = [skelet; ([ones(size(idx))*par_number; idx])(:)];
+	endif
+
+	## If there is not any descendant of "parent node":
+	if (stk(end,2) != par_number)
+	  left_most++;
+          x_coordinate_r(par_number) = left_most;           
+	  max_ht = min (max_ht, level);
+          if (length(stk) > 1 && find ((shift(stk,1)-stk) == 0) > 1
+	      && stk(end,2) != stk(end-1,2))
+	    ## Return to the nearest branching the position to return
+	    ## position is the position on the stack, where should be
+	    ## started further search (there are two nodes which has the
+	    ## same parent node).
+            position = (find ((shift(stk(:,2),1)-stk(:,2)) == 0))(end) + 1;
+            par_number_vec = stk(position:end,2);
+            ## The vector of removed nodes (the content of stack form
+	    ## position to end).
+            skelet = [skelet; flipud(par_number_vec)];
+            level += length (par_number_vec);
+	    ## The level have to be decreased.
+            x_coordinate_r(par_number_vec) = left_most;
+            stk(position:end,:) = [];
+          endif	
+       	  ## Remove the next node from "searched branch".
+	  stk(end,:) = [];
+	  ## Choose new "parent node".
+          par_number = stk(end,1);
+	  ## If there is another branch start to search it.
+	  if (par_number != -1)
+	    skelet = [skelet; stk(end,2); par_number];
+            y_coordinate(par_number) = level;	
+	    x_coordinate_l(par_number) = left_most + 1;
+	  endif
+	else
+          ## There were descendants of "parent nod" choose the last of
+	  ## them and go on through it.
+          level--;
+	  par_number = stk(end,1);
+	  y_coordinate(par_number) = level;     
+	  x_coordinate_l(par_number) = left_most + 1;
+	endif
+      endwhile
+
+      ## Calculate the x coordinates (the known values are the position
+      ## of most left and most right descendants).
+      x_coordinate = (x_coordinate_l + x_coordinate_r) / 2;
+
+      ## FIXME -- we should probably stuff all the arguments into a cell
+      ## array and make a single call to plot here so we can avoid
+      ## setting the hold state...
+
+      hold_is_on = ishold ();
+      unwind_protect
+	hold ("on");
+
+	## Plot grah nodes.
+	plot (x_coordinate, y_coordinate, node_style);
+
+	## Helping command - usable for plotting edges
+	skelet = [skelet; 0];
+
+	## Draw graph edges.
+	idx = find (skelet == 0);
+
+	## Plot each tree component in one loop.
+	for i = 2:length(idx)
+	  ## Tree component start.
+	  istart = idx(i-1) + 1;
+	  ## Tree component end.
+	  istop = idx(i) - 1;
+	  if (istop - istart < 1)                          
+	    continue;
+	  endif
+	  plot (x_coordinate(skelet(istart:istop)),
+		y_coordinate(skelet(istart:istop)), edge_style)
+	endfor
+
+	## Set axis and graph size.
+	axis ([0.5, left_most+0.5, max_ht-0.5, num_nodes-0.5], "nolabel");
+
+      unwind_protect_cleanup
+	if (! hold_is_on)
+	  hold ("off");
+	endif
+      end_unwind_protect
+      
+    endif
+  endif
+endfunction
+
+%!demo
+%! % Plot a simple tree plot 
+%! treeplot([2 4 2 0 6 4 6])
+
+%!demo
+%! % Plot a simple tree plot defining the edge and node styles
+%! treeplot([2 4 2 0 6 4 6], "b+", "g") 
diff --git a/scripts/specfun/Makefile.in b/scripts/specfun/Makefile.in
new file mode 100644
index 0000000..7a1d478
--- /dev/null
+++ b/scripts/specfun/Makefile.in
@@ -0,0 +1,86 @@
+# Makefile for octave's scripts/specfun directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = specfun
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = bessel.m beta.m betai.m betaln.m erfinv.m factor.m \
+  factorial.m gammai.m isprime.m legendre.m nchoosek.m \
+  perms.m pow2.m primes.m reallog.m realpow.m realsqrt.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/specfun
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/specfun/bessel.m b/scripts/specfun/bessel.m
new file mode 100644
index 0000000..d1367dd
--- /dev/null
+++ b/scripts/specfun/bessel.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1996, 1997, 1999, 2000, 2005, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Loadable Function} {[@var{j}, @var{ierr}] =} besselj (@var{alpha}, @var{x}, @var{opt})
+## @deftypefnx {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})
+## @deftypefnx {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})
+## @deftypefnx {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})
+## @deftypefnx {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})
+## Compute Bessel or Hankel functions of various kinds:
+## 
+## @table @code
+## @item besselj
+## Bessel functions of the first kind.  If the argument @var{opt} is supplied, 
+## the result is multiplied by @code{exp(-abs(imag(x)))}.
+## @item bessely
+## Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+## the result is multiplied by @code{exp(-abs(imag(x)))}.
+## @item besseli
+## Modified Bessel functions of the first kind.  If the argument @var{opt} is supplied,
+## the result is multiplied by @code{exp(-abs(real(x)))}.
+## @item besselk
+## Modified Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+## the result is multiplied by @code{exp(x)}.
+## @item besselh
+## Compute Hankel functions of the first (@var{k} = 1) or second (@var{k}
+## = 2) kind.  If the argument @var{opt} is supplied, the result is multiplied by
+## @code{exp (-I*@var{x})} for @var{k} = 1 or @code{exp (I*@var{x})} for
+## @var{k} = 2.
+## @end table
+## 
+## If @var{alpha} is a scalar, the result is the same size as @var{x}.
+## If @var{x} is a scalar, the result is the same size as @var{alpha}.
+## If @var{alpha} is a row vector and @var{x} is a column vector, the
+## result is a matrix with @code{length (@var{x})} rows and
+## @code{length (@var{alpha})} columns.  Otherwise, @var{alpha} and
+## @var{x} must conform and the result will be the same size.
+## 
+## The value of @var{alpha} must be real.  The value of @var{x} may be
+## complex.
+## 
+## If requested, @var{ierr} contains the following status information
+## and is the same size as the result.
+## 
+## @enumerate 0
+## @item
+## Normal return.
+## @item
+## Input error, return @code{NaN}.
+## @item
+## Overflow, return @code{Inf}.
+## @item
+## Loss of significance by argument reduction results in less than
+## half of machine accuracy.
+## @item
+## Complete loss of significance by argument reduction, return @code{NaN}.
+## @item
+## Error---no computation, algorithm termination condition not met,
+## return @code{NaN}.
+## @end enumerate
+## @end deftypefn
+
+function bessel ()
+  error ("bessel: you must use besselj, bessely, besseli, or besselk");
+endfunction
+
diff --git a/scripts/specfun/beta.m b/scripts/specfun/beta.m
new file mode 100644
index 0000000..9bd88eb
--- /dev/null
+++ b/scripts/specfun/beta.m
@@ -0,0 +1,82 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} beta (@var{a}, @var{b})
+## For real inputs, return the Beta function,
+## @tex
+## $$
+##  B (a, b) = {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
+## @end example
+## @end ifnottex
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 13 June 1993
+## Adapted-By: jwe
+
+function retval = beta (a, b)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (any (size (a) != size (b)) && numel (a) != 1 && numel (b) != 1)
+    error ("beta: inputs have inconsistent sizes");
+  endif
+
+  if (! isreal (a) || ! isreal (b))
+    error ("beta: inputs must be real");
+  endif
+
+  retval = real (exp (gammaln (a) + gammaln (b) - gammaln (a+b)));
+
+endfunction
+
+%!test
+%! a=[1, 1.5, 2, 3];
+%! b=[4, 3, 2, 1];
+%! v1=beta(a,b);
+%! v2=beta(b,a);
+%! v3=gamma(a).*gamma(b)./gamma(a+b);
+%! assert(all(abs(v1-v2)<sqrt(eps)) && all(abs(v2-v3)<sqrt(eps)));
+
+%!error beta();
+
+%!error beta(1);
+
+%!assert (1, beta (1, 1))
+
+%!test
+%! a = 2:10;
+%! tol = 10 * max (a) * eps;
+%! assert (-a, beta (-1./a, 1), tol)
+%! assert (-a, beta (1, -1./a), tol)
+
+%!test
+%! a = 0.25 + (0:5) * 0.5;
+%! tol = 10 * max (a) * eps;
+%! assert (zeros (size (a)), beta (a, -a), tol)
+%! assert (zeros (size (a)), beta (-a, a), tol)
diff --git a/scripts/specfun/betai.m b/scripts/specfun/betai.m
new file mode 100644
index 0000000..501bd17
--- /dev/null
+++ b/scripts/specfun/betai.m
@@ -0,0 +1,40 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} betai (@var{a}, @var{b}, @var{x})
+## This function is provided for compatibility with older versions of
+## Octave.  New programs should use betainc instead.
+##
+## @code{betai (@var{a}, @var{b}, @var{x})} is the same as @code{betainc
+## (@var{x}, @var{a}, @var{b})}. 
+## @end deftypefn
+
+## Author: jwe
+## Created: 30 Jan 1998
+
+function retval = betai (a, b, x)
+
+  if (nargin == 3)
+    retval = betainc (x, a, b);
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/specfun/betaln.m b/scripts/specfun/betaln.m
new file mode 100644
index 0000000..b187fce
--- /dev/null
+++ b/scripts/specfun/betaln.m
@@ -0,0 +1,51 @@
+## Copyright (C) 1998, 2006, 2007, 2008, 2009 by Nicol N. Schraudolph
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} betaln (@var{a}, @var{b})
+## Return the log of the Beta function,
+## @tex
+## $$
+##  B (a, b) = \log {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## betaln (a, b) = gammaln (a) + gammaln (b) - gammaln (a + b)
+## @end example
+## @end ifnottex
+## @seealso{beta, betainc, gammaln}
+## @end deftypefn
+
+## Author:   Nicol N. Schraudolph <nic at idsia.ch>
+## Created:  06 Aug 1998
+## Keywords: log beta special function
+
+function retval = betaln (a, b)
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  retval = gammaln (a) + gammaln (b) - gammaln (a + b);
+endfunction
+
+%!assert (betaln(3,4),log(beta(3,4)),eps)
+
+%!error (betaln(1.))
+%!error (betaln(1.,1.,1.))
diff --git a/scripts/specfun/erfinv.m b/scripts/specfun/erfinv.m
new file mode 100644
index 0000000..31e12b6
--- /dev/null
+++ b/scripts/specfun/erfinv.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+## Copyright (C) 2008 Alois Schloegl
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} erfinv (@var{z})
+## Computes the inverse of the error function.
+## @seealso{erf, erfc}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 27 September 1994
+## Adapted-By: jwe
+
+function [y, iterations] = erfinv (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  maxit = 100;
+  if (isa (x, "single"))
+    tol = eps ("single");
+  else
+    tol = eps;
+  endif
+
+  iterations = 0;
+
+  sz = size (x);
+  nel = numel (x);
+
+  x = reshape (x, nel, 1);
+  y = zeros (nel, 1);
+
+  ## x < -1 or x > 1 ==> NaN
+  y(abs (x) >= 1) = NaN;
+  y(x == -1) = -Inf;
+  y(x == +1) = +Inf;
+
+  i = find ((x > -1) & (x < 1));
+  if (any (i))
+    s = sqrt (pi) / 2;
+    z = sqrt (-log (1 - abs (x(i)))) .* sign (x(i));
+    while (any (abs (erf (z) - x(i)) > tol * abs (x(i))))
+      z = z - (erf (z) - x(i)) .* exp (z.^2) * s;
+      if (++iterations > maxit)
+        warning ("erfinv: iteration limit exceeded");
+        break;
+      endif
+    endwhile
+    y(i) = z;
+  endif
+
+  y = reshape (y, sz);
+
+endfunction
diff --git a/scripts/specfun/factor.m b/scripts/specfun/factor.m
new file mode 100644
index 0000000..213cc2e
--- /dev/null
+++ b/scripts/specfun/factor.m
@@ -0,0 +1,95 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{p} =} factor (@var{q})
+## @deftypefnx {Function File} {[@var{p}, @var{n}] =} factor (@var{q})
+##
+## Return prime factorization of @var{q}.  That is, @code{prod (@var{p})
+## == @var{q}} and every element of @var{p} is a prime number.  If
+## @code{@var{q} == 1}, returns 1. 
+##
+## With two output arguments, return the unique primes @var{p} and
+## their multiplicities.  That is, @code{prod (@var{p} .^ @var{n}) ==
+## @var{q}}.
+## @seealso{gcd, lcm}
+## @end deftypefn
+
+## Author: Paul Kienzle
+
+## 2002-01-28 Paul Kienzle
+## * remove recursion; only check existing primes for multiplicity > 1
+## * return multiplicity as suggested by Dirk Laurie
+## * add error handling
+
+function [x, m] = factor (n)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (! isscalar (n) || n != fix (n))
+    error ("factor: n must be a scalar integer");
+  endif
+
+  ## Special case of no primes less than sqrt(n).
+  if (n < 4)
+    x = n;
+    m = 1;
+    return;
+  endif 
+
+  x = [];
+  ## There is at most one prime greater than sqrt(n), and if it exists,
+  ## it has multiplicity 1, so no need to consider any factors greater
+  ## than sqrt(n) directly. [If there were two factors p1, p2 > sqrt(n),
+  ## then n >= p1*p2 > sqrt(n)*sqrt(n) == n. Contradiction.]
+  p = primes (sqrt (n));
+  while (n > 1)
+    ## Find prime factors in remaining n.
+    q = n ./ p;
+    p = p (q == fix (q));
+    if (isempty (p))
+      ## Can't be reduced further, so n must itself be a prime.
+      p = n;
+    endif
+    x = [x, p];
+    ## Reduce n.
+    n = n / prod (p);
+  endwhile
+  x = sort (x);
+
+  ## Determine muliplicity.
+  if (nargout > 1)
+    idx = find ([0, x] != [x, 0]);
+    x = x(idx(1:length(idx)-1));
+    m = diff (idx);
+  endif
+
+endfunction
+
+## test:
+##   assert(factor(1),1);
+##   for i=2:20
+##      p = factor(i);
+##      assert(prod(p),i);
+##      assert(all(isprime(p)));
+##      [p,n] = factor(i);
+##      assert(prod(p.^n),i);
+##      assert(all([0,p]!=[p,0]));
+##   end
diff --git a/scripts/specfun/factorial.m b/scripts/specfun/factorial.m
new file mode 100644
index 0000000..5714e37
--- /dev/null
+++ b/scripts/specfun/factorial.m
@@ -0,0 +1,42 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} factorial (@var{n})
+## Return the factorial of @var{n} where @var{n} is a positive integer.  If
+## @var{n} is a scalar, this is equivalent to @code{prod (1:@var{n})}.  For
+## vector or matrix arguments, return the factorial of each element in the
+## array.  For non-integers see the generalized factorial function
+## @code{gamma}.
+## @seealso{prod, gamma}
+## @end deftypefn
+
+function x = factorial (n)
+  if (nargin != 1)
+    print_usage ();
+  elseif (any (n(:) < 0 | n(:) != round (n(:))))
+    error ("factorial: n must all be nonnegative integers");
+  endif
+  x = round (gamma (n+1));
+endfunction
+
+%!assert (factorial(5), prod(1:5))
+%!assert (factorial([1,2;3,4]), [1,2;6,24])
+%!assert (factorial(70), exp(sum(log(1:70))), -128*eps)
+%!fail ('factorial(5.5)', "must all be nonnegative integers")
+%!fail ('factorial(-3)', "must all be nonnegative integers")
diff --git a/scripts/specfun/gammai.m b/scripts/specfun/gammai.m
new file mode 100644
index 0000000..629f034
--- /dev/null
+++ b/scripts/specfun/gammai.m
@@ -0,0 +1,40 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2005, 2006,
+##               2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gammai (@var{a}, @var{x})
+## This function is provided for compatibility with older versions of
+## Octave.  New programs should use @code{gammainc} instead.
+##
+## @code{gammai (@var{a}, @var{x})} is the same as @code{gammainc
+## (@var{x}, @var{a})}.
+## @end deftypefn
+
+## Author: jwe
+## Created: 30 Jan 1998
+
+function retval = gammai (a, x)
+
+  if (nargin == 2)
+    retval = gammainc (x, a);
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/specfun/isprime.m b/scripts/specfun/isprime.m
new file mode 100644
index 0000000..e4e3989
--- /dev/null
+++ b/scripts/specfun/isprime.m
@@ -0,0 +1,57 @@
+## Copyright (C) 2000, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isprime (@var{n})
+##
+## Return true if @var{n} is a prime number, false otherwise.
+##
+## Something like the following is much faster if you need to test a lot
+## of small numbers:
+##
+## @example
+##    @var{t} = ismember (@var{n}, primes (max (@var{n} (:))));
+## @end example
+##
+## If max(n) is very large, then you should be using special purpose 
+## factorization code.
+##
+## @seealso{primes, factor, gcd, lcm}
+## @end deftypefn
+
+function t = isprime (n)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (! isscalar (n))
+    nel = numel (n);
+    t = n;
+    for i = 1:nel
+      t(i) = isprime (t(i));
+    endfor
+  elseif (n != fix (n) || n < 2)
+    t = 0;
+  elseif (n < 9)
+    t = all (n != [4, 6, 8]);
+  else
+    q = n./[2, 3:2:sqrt(n)];
+    t = all (q != fix (q));
+  endif
+endfunction
diff --git a/scripts/specfun/legendre.m b/scripts/specfun/legendre.m
new file mode 100644
index 0000000..418fa73
--- /dev/null
+++ b/scripts/specfun/legendre.m
@@ -0,0 +1,237 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Kai Habel
+## Copyright (C) 2008 Marco Caliari
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{l} =} legendre (@var{n}, @var{x})
+## @deftypefnx {Function File} {@var{l} =} legendre (@var{n}, @var{x}, @var{normalization})
+## Compute the Legendre function of degree @var{n} and order 
+## @var{m} = 0 @dots{} N.  The optional argument, @var{normalization}, 
+## may be one of @code{"unnorm"}, @code{"sch"}, or @code{"norm"}.
+## The default is @code{"unnorm"}.  The value of @var{n} must be a 
+## non-negative scalar integer.  
+##
+## If the optional argument @var{normalization} is missing or is
+## @code{"unnorm"}, compute the Legendre function of degree @var{n} and
+## order @var{m} and return all values for @var{m} = 0 @dots{} @var{n}.
+## The return value has one dimension more than @var{x}.
+##
+## The Legendre Function of degree @var{n} and order @var{m}:
+##
+## @example
+## @group
+##  m        m       2  m/2   d^m
+## P(x) = (-1) * (1-x  )    * ----  P (x)
+##  n                         dx^m   n
+## @end group
+## @end example
+##
+## @noindent
+## with Legendre polynomial of degree @var{n}:
+##
+## @example
+## @group
+##           1     d^n   2    n
+## P (x) = ------ [----(x - 1)  ]
+##  n      2^n n!  dx^n
+## @end group
+## @end example
+##
+## @noindent
+## @code{legendre (3, [-1.0, -0.9, -0.8])} returns the matrix:
+##
+## @example
+## @group
+##  x  |   -1.0   |   -0.9   |  -0.8
+## ------------------------------------
+## m=0 | -1.00000 | -0.47250 | -0.08000
+## m=1 |  0.00000 | -1.99420 | -1.98000
+## m=2 |  0.00000 | -2.56500 | -4.32000
+## m=3 |  0.00000 | -1.24229 | -3.24000 
+## @end group
+## @end example
+##
+## If the optional argument @code{normalization} is @code{"sch"}, 
+## compute the Schmidt semi-normalized associated Legendre function.
+## The Schmidt semi-normalized associated Legendre function is related
+## to the unnormalized Legendre functions by the following:
+##
+## For Legendre functions of degree n and order 0:
+##
+## @example
+## @group
+##   0       0
+## SP (x) = P (x)
+##   n       n
+## @end group
+## @end example
+##
+## For Legendre functions of degree n and order m:
+##
+## @example
+## @group
+##   m       m          m    2(n-m)! 0.5
+## SP (x) = P (x) * (-1)  * [-------]
+##   n       n               (n+m)!
+## @end group
+## @end example
+##
+## If the optional argument @var{normalization} is @code{"norm"}, 
+## compute the fully normalized associated Legendre function.
+## The fully normalized associated Legendre function is related
+## to the unnormalized Legendre functions by the following:
+##
+## For Legendre functions of degree @var{n} and order @var{m}
+##
+## @example
+## @group
+##   m       m          m    (n+0.5)(n-m)! 0.5
+## NP (x) = P (x) * (-1)  * [-------------]
+##   n       n                   (n+m)!    
+## @end group
+## @end example
+## @end deftypefn
+
+## Author: Marco Caliari <marco.caliari at univr.it>
+
+function retval = legendre (n, x, normalization)
+
+  persistent warned_overflow = false;
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 3)
+    normalization = lower (normalization);
+  else
+    normalization = "unnorm";
+  endif
+
+  if (! isscalar (n) || n < 0 || n != fix (n))
+    error ("legendre: n must be a non-negative scalar integer");
+  endif
+
+  if (! isvector (x) || any (x < -1 || x > 1))
+    error ("legendre: x must be vector in range -1 <= x <= 1");
+  endif
+
+  switch (normalization)
+    case "norm"
+      scale = sqrt (n+0.5);
+    case "sch"
+      scale = sqrt (2);
+    case "unnorm"
+      scale = 1;
+    otherwise
+      error ("legendre: expecting normalization option to be \"norm\", \"sch\", or \"unnorm\"");
+  endswitch
+
+  scale = scale * ones (1, numel (x));
+
+  ## Based on the recurrence relation below
+  ##            m                 m              m
+  ## (n-m+1) * P (x) = (2*n+1)*x*P (x)  - (n+1)*P (x)
+  ##            n+1               n              n-1
+  ## http://en.wikipedia.org/wiki/Associated_Legendre_function
+
+  overflow = false;
+  for m = 1:n
+    lpm1 = scale;
+    lpm2 = (2*m-1) .* x .* scale;      
+    lpm3 = lpm2;
+    for k = m+1:n
+      lpm3a = (2*k-1) .* x .* lpm2;
+      lpm3b = (k+m-2) .* lpm1;
+      lpm3 = (lpm3a - lpm3b)/(k-m+1);
+      lpm1 = lpm2;
+      lpm2 = lpm3;
+      if (! warned_overflow)
+        if (any (abs (lpm3a) > realmax)
+            || any (abs (lpm3b) > realmax)
+            || any (abs (lpm3)  > realmax))
+          overflow = true;
+        endif
+      endif
+    endfor
+    retval(m,:) = lpm3;
+    if (strcmp (normalization, "unnorm"))
+      scale = -scale * (2*m-1);
+    else
+      ## normalization == "sch" or normalization == "norm"
+      scale = scale / sqrt ((n-m+1)*(n+m))*(2*m-1);
+    endif
+    scale = scale .* sqrt(1-x.^2);
+  endfor
+
+  retval(n+1,:) = scale;
+
+  if (strcmp (normalization, "sch"))
+    retval(1,:) = retval(1,:) / sqrt (2);
+  endif
+
+  if (overflow && ! warned_overflow)
+    warning ("legendre: overflow - results may be unstable for high orders");
+    warned_overflow = true;
+  endif
+
+endfunction
+
+%!test
+%! result = legendre (3, [-1.0 -0.9 -0.8]);
+%! expected = [
+%!    -1.00000  -0.47250  -0.08000
+%!     0.00000  -1.99420  -1.98000
+%!     0.00000  -2.56500  -4.32000
+%!     0.00000  -1.24229  -3.24000
+%! ];
+%! assert (result, expected, 1e-5);
+
+%!test
+%! result = legendre (3, [-1.0 -0.9 -0.8], "sch");
+%! expected = [
+%!    -1.00000  -0.47250  -0.08000
+%!     0.00000   0.81413   0.80833
+%!    -0.00000  -0.33114  -0.55771
+%!     0.00000   0.06547   0.17076
+%! ];
+%! assert (result, expected, 1e-5);
+
+%!test
+%! result = legendre (3, [-1.0 -0.9 -0.8], "norm");
+%! expected = [
+%!    -1.87083  -0.88397  -0.14967
+%!     0.00000   1.07699   1.06932
+%!    -0.00000  -0.43806  -0.73778
+%!     0.00000   0.08661   0.22590
+%! ];
+%! assert (result, expected, 1e-5);
+
+%!test
+%! result = legendre (151, 0);
+%! ## Don't compare to "-Inf" since it would fail on 64 bit systems.
+%! assert (result(end) < -1.7976e308 && all (isfinite (result(1:end-1))));
+
+%!test
+%! result = legendre (150, 0);
+%! ## This agrees with Matlab's result.
+%! assert (result(end), 3.7532741115719e+306, 0.0000000000001e+306)
+
+%!test
+%! result = legendre (0, 0:0.1:1);
+%! assert (result, full(ones(1,11)))
diff --git a/scripts/specfun/nchoosek.m b/scripts/specfun/nchoosek.m
new file mode 100644
index 0000000..9e2abae
--- /dev/null
+++ b/scripts/specfun/nchoosek.m
@@ -0,0 +1,129 @@
+## Copyright (C) 2001, 2006, 2007, 2009 Rolf Fabian and Paul Kienzle
+## Copyright (C) 2008 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
+##
+## Compute the binomial coefficient or all combinations of @var{n}.
+## If @var{n} is a scalar then, calculate the binomial coefficient
+## of @var{n} and @var{k}, defined as
+##
+## @tex
+## $$
+##  {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
+##                = {n! \over k! (n-k)!}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##  /   \
+##  | n |    n (n-1) (n-2) @dots{} (n-k+1)       n!
+##  |   |  = ------------------------- =  ---------
+##  | k |               k!                k! (n-k)!
+##  \   /
+## @end group
+## @end example
+## @end ifnottex
+##
+## If @var{n} is a vector generate all combinations of the elements
+## of @var{n}, taken @var{k} at a time, one row per combination.  The 
+## resulting @var{c} has size @code{[nchoosek (length (@var{n}), 
+## @var{k}), @var{k}]}.
+##
+## @code{nchoosek} works only for non-negative integer arguments; use
+## @code{bincoeff} for non-integer scalar arguments and for using vector
+## arguments to compute many coefficients at once.
+##
+## @seealso{bincoeff}
+## @end deftypefn
+
+## Author: Rolf Fabian  <fabian at tu-cottbus.de>
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+## Author: Jaroslav Hajek
+
+function A = nchoosek (v, k)
+
+  if (nargin != 2
+      || !isnumeric(k) || !isnumeric(v)
+      || !isscalar(k) || (!isscalar(v) && !isvector(v)))
+    print_usage ();
+  endif
+  if ((isscalar(v) && v < k) || k < 0
+      || k != round(k) || any (v < 0 || v != round(v)))
+    error ("nchoosek: args are nonnegative integers with V not less than K");
+  endif
+
+  n = length (v);
+
+  if (n == 1)
+    ## Improve precision at next step.
+    k = min (k, v-k);
+    A = round (prod ((v-k+1:v)./(1:k)));
+    if (A*2*k*eps >= 0.5)
+      warning ("nchoosek", "nchoosek: possible loss of precision");
+    endif
+  elseif (k == 0)
+    A = [];
+  elseif (k == 1)
+    A = v(:);
+  elseif (k == n)
+    A = v(:).';
+  elseif (k > n)
+    A = zeros (0, k, class (v));
+  else
+    p = cell (1, k);
+    ## Hack: do the op in the smallest integer class possible to avoid
+    ## moving too much data.
+    if (n < intmax ("uint8"))
+      cl = "uint8";
+    elseif (n < intmax ("uint16"))
+      cl = "uint16";
+    elseif (n < intmax ("uint32"))
+      cl = "uint32";
+    else
+      ## This would exhaust memory anyway.
+      cl = "double";
+    endif
+     
+    ## Use a generalized Pascal triangle. Traverse backwards to keep
+    ## alphabetical order.
+    for i = 1:k
+      p{i} = zeros (0, i, cl);
+    endfor
+    s = ones (1, 1, cl);
+    p{1} = n*s;
+    for j = n-1:-1:1
+      for i = k:-1:2
+	q = p{i-1};
+	p{i} = [[repmat(s*j, rows (p{i-1}), 1), p{i-1}]; p{i}];
+      endfor
+      p{1} = [j;p{1}];
+    endfor
+    v = v(:);
+    A = v(p{k});
+  endif
+endfunction
+
+%!warning (nchoosek(100,45));
+%!error (nchoosek(100,45.5));
+%!error (nchoosek(100,145));
+%!assert (nchoosek(80,10), bincoeff(80,10))
+%!assert (nchoosek(1:5,3),[1:3;1,2,4;1,2,5;1,3,4;1,3,5;1,4,5;2:4;2,3,5;2,4,5;3:5])
diff --git a/scripts/specfun/perms.m b/scripts/specfun/perms.m
new file mode 100644
index 0000000..6acd328
--- /dev/null
+++ b/scripts/specfun/perms.m
@@ -0,0 +1,60 @@
+## Copyright (C) 2001, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} perms (@var{v})
+##
+## Generate all permutations of @var{v}, one row per permutation.  The
+## result has size @code{factorial (@var{n}) * @var{n}}, where @var{n}
+## is the length of @var{v}.
+##
+## As an example, @code{perms([1, 2, 3])} returns the matrix
+## @example
+## @group
+##   1   2   3
+##   2   1   3
+##   1   3   2
+##   2   3   1
+##   3   1   2
+##   3   2   1
+## @end group
+## @end example
+## @end deftypefn
+
+function A = perms (v)
+  if (nargin != 1)
+    print_usage ();
+  endif
+  v = v(:);
+  n = length (v);
+  if (n == 1)
+    A = v;
+  else
+    B = perms (v(1:n-1));
+    Bidx = 1:size (B, 1);
+    A = v(n) * ones (prod (2:n), n);
+    A(Bidx,1:n-1) = B;
+    k = size (B, 1);
+    for i = n-1:-1:2
+      A(k+Bidx,1:i-1) = B(Bidx,1:i-1);
+      A(k+Bidx,i+1:n) = B(Bidx,i:n-1);
+      k = k + size (B, 1);
+    endfor
+    A(k+Bidx,2:n) = B;
+  endif
+endfunction
diff --git a/scripts/specfun/pow2.m b/scripts/specfun/pow2.m
new file mode 100644
index 0000000..5eb5bdb
--- /dev/null
+++ b/scripts/specfun/pow2.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007,
+##               2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} pow2 (@var{x})
+## @deftypefnx {Mapping Function} {} pow2 (@var{f}, @var{e})
+## With one argument, computes
+## @tex
+## $2^x$
+## @end tex
+## @ifnottex
+## 2 .^ x
+## @end ifnottex
+## for each element of @var{x}.
+##
+## With two arguments, returns
+## @tex
+## $f \cdot 2^e$.
+## @end tex
+## @ifnottex
+## f .* (2 .^ e).
+## @end ifnottex
+## @seealso{log2, nextpow2}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel at ci.tuwien.ac.at>
+## Created: 17 October 1994
+## Adapted-By: jwe
+
+function y = pow2 (f, e)
+
+  if (nargin == 1)
+    y = 2 .^ f;
+  elseif (nargin == 2)
+    y = f .* (2 .^ e);
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! x = [3, 0, -3];
+%! v = [8, 1, .125];
+%! assert(all (abs (pow2 (x) - v) < sqrt (eps)));
+
+%!test
+%! x = [3, 0, -3, 4, 0, -4, 5, 0, -5];
+%! y = [-2, -2, -2, 1, 1, 1, 3, 3, 3];
+%! z = x .* (2 .^ y);
+%! assert(all (abs (pow2 (x,y) - z) < sqrt (eps)));
+
+%!error pow2();
+
diff --git a/scripts/specfun/primes.m b/scripts/specfun/primes.m
new file mode 100644
index 0000000..2066bc3
--- /dev/null
+++ b/scripts/specfun/primes.m
@@ -0,0 +1,94 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} primes (@var{n})
+##
+## Return all primes up to @var{n}.  
+##
+## The algorithm used is the Sieve of Erastothenes.
+##
+## Note that if you need a specific number of primes you can use the
+## fact the distance from one prime to the next is, on average,
+## proportional to the logarithm of the prime.  Integrating, one finds
+## that there are about @math{k} primes less than
+## @tex
+## $k \log (5 k)$.
+## @end tex
+## @ifnottex
+## k*log(5*k).
+## @end ifnottex
+## @seealso{list_primes, isprime}
+## @end deftypefn
+
+## Author: Paul Kienzle
+## Author: Francesco Potortì
+## Author: Dirk Laurie
+
+function x = primes (p)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! isscalar (p))
+    error ("primes: n must be a scalar");
+  endif
+
+  if (p > 100000)
+    ## Optimization: 1/6 less memory, and much faster (asymptotically)
+    ## 100000 happens to be the cross-over point for Paul's machine;
+    ## below this the more direct code below is faster.  At the limit
+    ## of memory in Paul's machine, this saves .7 seconds out of 7 for
+    ## p = 3e6.  Hardly worthwhile, but Dirk reports better numbers.
+    lenm = floor ((p+1)/6);       # length of the 6n-1 sieve
+    lenp = floor ((p-1)/6);       # length of the 6n+1 sieve
+    sievem = ones (1, lenm);      # assume every number of form 6n-1 is prime
+    sievep = ones (1, lenp);      # assume every number of form 6n+1 is prime
+
+    for i = 1:(sqrt(p)+1)/6       # check up to sqrt(p)
+      if (sievem(i))              # if i is prime, eliminate multiples of i
+        sievem(7*i-1:6*i-1:lenm) = 0;
+        sievep(5*i-1:6*i-1:lenp) = 0;
+      endif                       # if i is prime, eliminate multiples of i
+      if (sievep(i))
+        sievep(7*i+1:6*i+1:lenp) = 0;
+        sievem(5*i+1:6*i+1:lenm) = 0;
+      endif
+    endfor
+    x = sort([2, 3, 6*find(sievem)-1, 6*find(sievep)+1]);
+  elseif (p > 352)                # nothing magical about 352; must be >2
+    len = floor ((p-1)/2);        # length of the sieve
+    sieve = ones (1, len);        # assume every odd number is prime
+    for i = 1:(sqrt(p)-1)/2       # check up to sqrt(p)
+      if (sieve(i))               # if i is prime, eliminate multiples of i
+        sieve(3*i+1:2*i+1:len) = 0; # do it
+      endif
+    endfor
+    x = [2, 1+2*find(sieve)];     # primes remaining after sieve
+  else
+    a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, ...
+	 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, ...
+	 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, ...
+	 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, ...
+	 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, ...
+	 293, 307, 311, 313, 317, 331, 337, 347, 349];
+    x = a(a <= p);
+  endif
+
+endfunction
diff --git a/scripts/specfun/reallog.m b/scripts/specfun/reallog.m
new file mode 100644
index 0000000..0844e07
--- /dev/null
+++ b/scripts/specfun/reallog.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} reallog (@var{x})
+## Return the real-valued natural logarithm of each element of @var{x}.  Report 
+## an error if any element results in a complex return value.
+## @seealso{log, realpow, realsqrt}
+## @end deftypefn
+
+function y = reallog (x)
+  if (nargin != 1)
+    print_usage ();
+  elseif (iscomplex (x) || any (x(:) < 0))
+    error ("reallog: produced complex result");
+  else    
+    y = log (x);
+  endif
+endfunction
+
+%!assert (log(1:5),reallog(1:5))
+%!test
+%! x = rand (10,10);
+%! assert (log(x),reallog(x))
+%!error (reallog(-1))
diff --git a/scripts/specfun/realpow.m b/scripts/specfun/realpow.m
new file mode 100644
index 0000000..34686cf
--- /dev/null
+++ b/scripts/specfun/realpow.m
@@ -0,0 +1,45 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} realpow (@var{x}, @var{y})
+## Compute the real-valued, element-by-element power operator.  This is 
+## equivalent to @w{@code{@var{x} .^ @var{y}}}, except that @code{realpow}
+## reports an error if any return value is complex.
+## @seealso{reallog, realsqrt}
+## @end deftypefn
+
+function z = realpow (x, y)
+  if (nargin != 2)
+    print_usage ();
+  else
+    z = x .^ y;
+    if (iscomplex (z))
+      error ("realpow: produced complex result");
+    endif
+  endif
+endfunction
+
+%!assert (power (1:10, 0.5:0.5:5), realpow (1:10, 0.5:0.5:5))
+%!assert ([1:10] .^ [0.5:0.5:5], realpow (1:10, 0.5:0.5:5))
+%!test
+%! x = rand (10,10);
+%! y = randn (10,10);
+%! assert (x.^y,realpow(x,y))
+%!assert (realpow(1i,2),-1)
+%!error (realpow(-1, 1/2))
diff --git a/scripts/specfun/realsqrt.m b/scripts/specfun/realsqrt.m
new file mode 100644
index 0000000..c9ab1c2
--- /dev/null
+++ b/scripts/specfun/realsqrt.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} realsqrt (@var{x})
+## Return the real-valued square root of each element of @var{x}.  Report an
+## error if any element results in a complex return value.
+## @seealso{sqrt, realpow, reallog}
+## @end deftypefn
+
+function y = realsqrt (x)
+  if (nargin != 1)
+    print_usage ();
+  elseif (iscomplex (x) || any (x(:) < 0))
+    error ("realsqrt: produced complex result");
+  else    
+    y = sqrt (x);
+  endif
+endfunction
+
+%!assert (sqrt(1:5),realsqrt(1:5))
+%!test
+%! x = rand (10,10);
+%! assert (sqrt(x),realsqrt(x))
+%!error (realsqrt(-1))
diff --git a/scripts/special-matrix/Makefile.in b/scripts/special-matrix/Makefile.in
new file mode 100644
index 0000000..3ea4942
--- /dev/null
+++ b/scripts/special-matrix/Makefile.in
@@ -0,0 +1,85 @@
+# Makefile for octave's scripts/special-matrix directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = special-matrix
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = hadamard.m hankel.m hilb.m invhilb.m magic.m pascal.m \
+  rosser.m sylvester_matrix.m toeplitz.m vander.m wilkinson.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/special-matrix
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/special-matrix/hadamard.m b/scripts/special-matrix/hadamard.m
new file mode 100644
index 0000000..6ba59a7
--- /dev/null
+++ b/scripts/special-matrix/hadamard.m
@@ -0,0 +1,175 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2004, 2006, 2007, 2009
+##               Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hadamard (@var{n})
+## Construct a Hadamard matrix @var{Hn} of size @var{n}-by- at var{n}.  The 
+## size @var{n} must be of the form @code{2 ^ @var{k} * @var{p}} in which
+## @var{p} is one of 1, 12, 20 or 28.  The returned matrix is normalized,
+## meaning @code{Hn(:,1) == 1} and @code{H(1,:) == 1}.
+##
+## Some of the properties of Hadamard matrices are:
+##
+## @itemize @bullet
+## @item
+## @code{kron (@var{Hm}, @var{Hn})} is a Hadamard matrix of size 
+## @var{m}-by- at var{n}.
+## @item
+## @code{Hn * Hn' == @var{n} * eye (@var{n})}.
+## @item
+## The rows of @var{Hn} are orthogonal.
+## @item
+## @code{det (@var{A}) <= abs(det (@var{Hn}))} for all @var{A} with
+## @code{abs (@var{A} (@var{i}, @var{j})) <= 1}.
+## @item
+## Multiply any row or column by -1 and still have a Hadamard matrix.
+## @end itemize
+##
+## @end deftypefn
+
+   
+## Reference [1] contains a list of Hadamard matrices up to n=256.
+## See code for h28 in hadamard.m for an example of how to extend
+## this function for additional p.
+##
+## References:
+## [1] A Library of Hadamard Matrices, N. J. A. Sloane 
+##     http://www.research.att.com/~njas/hadamard/
+
+function h = hadamard (n)
+  
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  ## Find k if n = 2^k*p.
+  k = 0;
+  while (n > 1 && floor (n/2) == n/2)
+    k++; 
+    n = n/2; 
+  endwhile
+  
+  ## Find base hadamard.
+  ## Except for n=2^k, need a multiple of 4.
+  if (n != 1)
+    k -= 2; 
+  endif
+
+  ## Trigger error if not a multiple of 4.
+  if (k < 0)
+    n =- 1;
+  endif
+
+  switch (n)
+    case 1
+      h = 1;
+    case 3
+      h = h12 ();
+    case 5
+      h = h20 ();
+    case 7
+      h = hnormalize (h28 ());
+    otherwise
+      error ("n must be 2^k*p, for p = 1, 12, 20 or 28");
+  endswitch
+
+  ## Build H(2^k*n) from kron(H(2^k),H(n)).
+  h2 = [1,1;1,-1];
+  while (true)
+    if (floor (k/2) != k/2)
+      h = kron (h2, h); 
+    endif
+    k = floor (k/2);
+    if (k == 0) 
+      break; 
+    endif
+    h2 = kron (h2, h2);
+  endwhile
+endfunction
+
+function h = h12 ()
+  tu = [-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1];
+  tl = [-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,+1];
+  ## Note: assert (tu(2:end), tl(end:-1:2)).
+  h = ones (12);
+  h(2:end,2:end) = toeplitz (tu, tl);
+endfunction
+
+
+function h = h20 ()
+  tu = [+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1];
+  tl = [+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1];
+  ## Note: assert (tu(2:end), tl(end:-1:2)).
+  h = ones (20);
+  h(2:end,2:end) = fliplr (toeplitz (tu, tl));
+endfunction
+
+function h = hnormalize (h)
+  ## Make sure each row and column starts with +1.
+  h(h(:,1)==-1,:) *= -1;
+  h(:,h(1,:)==-1) *= -1;
+endfunction
+
+function h = h28 ()
+  ## Williamson matrix construction from
+  ## http://www.research.att.com/~njas/hadamard/had.28.will.txt
+  s = ["+------++----++-+--+-+--++--";
+       "-+-----+++-----+-+--+-+--++-";
+       "--+-----+++---+-+-+----+--++";
+       "---+-----+++---+-+-+-+--+--+";
+       "----+-----+++---+-+-+++--+--";
+       "-----+-----++++--+-+--++--+-";
+       "------++----++-+--+-+--++--+";
+       "--++++-+-------++--+++-+--+-";
+       "---++++-+-----+-++--+-+-+--+";
+       "+---+++--+----++-++--+-+-+--";
+       "++---++---+----++-++--+-+-+-";
+       "+++---+----+----++-++--+-+-+";
+       "++++--------+-+--++-++--+-+-";
+       "-++++--------+++--++--+--+-+";
+       "-+-++-++--++--+--------++++-";
+       "+-+-++--+--++--+--------++++";
+       "-+-+-++--+--++--+----+---+++";
+       "+-+-+-++--+--+---+---++---++";
+       "++-+-+-++--+------+--+++---+";
+       "-++-+-+-++--+------+-++++---";
+       "+-++-+---++--+------+-++++--";
+       "-++--++-+-++-+++----++------";
+       "+-++--++-+-++-+++-----+-----";
+       "++-++---+-+-++-+++-----+----";
+       "-++-++-+-+-+-+--+++-----+---";
+       "--++-++++-+-+----+++-----+--";
+       "+--++-+-++-+-+----+++-----+-";
+       "++--++-+-++-+-+----++------+"];
+  ## Without this, the assignment of -1 will not work properly
+  ## (compatibility forces LHS(idx) = ANY_VAL to keep the LHS logical
+  ## instead of widening to a type that can represent ANY_VAL).
+  h = double (s == "+");
+  h(!h) = -1;
+endfunction
+
+%!assert(hadamard(1),1)
+%!assert(hadamard(2),[1,1;1,-1])
+%!test
+%!  for n=[1,2,4,8,12,24,48,20,28,2^9]
+%!    h=hadamard(n); assert(norm(h*h'-n*eye(n)),0);
+%!  end
diff --git a/scripts/special-matrix/hankel.m b/scripts/special-matrix/hankel.m
new file mode 100644
index 0000000..ccb0aff
--- /dev/null
+++ b/scripts/special-matrix/hankel.m
@@ -0,0 +1,116 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hankel (@var{c}, @var{r})
+## Return the Hankel matrix constructed given the first column @var{c}, and
+## (optionally) the last row @var{r}.  If the last element of @var{c} is
+## not the same as the first element of @var{r}, the last element of
+## @var{c} is used.  If the second argument is omitted, it is assumed to
+## be a vector of zeros with the same size as @var{c}.
+##
+## A Hankel matrix formed from an m-vector @var{c}, and an n-vector
+## @var{r}, has the elements
+## @tex
+## $$
+## H (i, j) = \cases{c_{i+j-1},&$i+j-1\le m$;\cr r_{i+j-m},&otherwise.\cr}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+## H(i,j) = c(i+j-1),  i+j-1 <= m;
+## H(i,j) = r(i+j-m),  otherwise
+## @end group
+## @end example
+## @end ifnottex
+## @seealso{vander, sylvester_matrix, hilb, invhilb, toeplitz}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = hankel (c, r)
+
+  if (nargin == 1)
+    r = resize (resize (c, 0), size(c));
+  elseif (nargin != 2)
+    print_usage ();
+  endif
+
+  [c_nr, c_nc] = size (c);
+  [r_nr, r_nc] = size (r);
+
+  if ((c_nr != 1 && c_nc != 1) || (r_nr != 1 && r_nc != 1))
+    error ("hankel: expecting vector arguments");
+  endif
+
+  if (nargin == 1)
+    r (1) = c (length (c));
+  endif
+
+  if (c_nc != 1)
+    c = c.';
+  endif
+
+  if (r_nr != 1)
+    r = r.';
+  endif
+
+  nc = length (r);
+  nr = length (c);
+
+  if (r (1) != c (nr))
+    warning ("hankel: column wins anti-diagonal conflict");
+  endif
+
+  ## This should probably be done with the colon operator...
+
+  retval = resize (resize (c, 0), nr, nc);
+
+  for i = 1:min (nr, nc)
+    retval (1:nr-i+1, i) = c (i:nr);
+  endfor
+
+  tmp = 1;
+  if (nc <= nr)
+    tmp = nr - nc + 2;
+  endif
+
+  for i = nr:-1:tmp
+    retval (i, 2+nr-i:nc) = r (2:nc-nr+i);
+  endfor
+
+endfunction
+
+%!assert(hankel(1:3),[1,2,3;2,3,0;3,0,0])
+%!assert(hankel(1),[1]);
+%!assert(hankel(1:3,3:6),[1,2,3,4;2,3,4,5;3,4,5,6]);
+%!assert(hankel(1:3,3:4),[1,2;2,3;3,4]);
+%!assert(hankel(1:3,4:6),[1,2,3;2,3,5;3,5,6]);
+
+%!assert((hankel (1) == 1 && hankel ([1, 2]) == [1, 2; 2, 0]
+%! && hankel ([1, 2], [2; -1; -3]) == [1, 2, -1; 2, -1, -3]));
+
+%!error hankel ([1, 2; 3, 4], [1, 2; 3, 4]);
+
+%!error hankel ();
+
+%!error hankel (1, 2, 3);
+
diff --git a/scripts/special-matrix/hilb.m b/scripts/special-matrix/hilb.m
new file mode 100644
index 0000000..148bd0e
--- /dev/null
+++ b/scripts/special-matrix/hilb.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hilb (@var{n})
+## Return the Hilbert matrix of order @var{n}.  The
+## @tex
+## $i,\,j$
+## @end tex
+## @ifnottex
+## i, j
+## @end ifnottex
+## element of a Hilbert matrix is defined as
+## @tex
+## $$
+## H (i, j) = {1 \over (i + j - 1)}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## H (i, j) = 1 / (i + j - 1)
+## @end example
+## @end ifnottex
+## @seealso{hankel, vander, sylvester_matrix, invhilb, toeplitz}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = hilb (n)
+
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  nmax = length (n);
+  if (nmax == 1)
+    retval = zeros (n);
+    tmp = 1:n;
+    for i = 1:n
+      retval (i, :) = 1.0 ./ (tmp + (i - 1));
+    endfor
+  else
+    error ("hilb: expecting scalar argument, found something else");
+  endif
+
+endfunction
+
+%!assert((hilb (2) == [1, 1/2; 1/2, 1/3]
+%! && hilb (3) == [1, 1/2, 1/3; 1/2, 1/3, 1/4; 1/3, 1/4, 1/5]));
+
+%!error hilb ();
+
+%!error hilb (1, 2);
+
diff --git a/scripts/special-matrix/invhilb.m b/scripts/special-matrix/invhilb.m
new file mode 100644
index 0000000..a3f47b2
--- /dev/null
+++ b/scripts/special-matrix/invhilb.m
@@ -0,0 +1,130 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+##               2004, 2005, 2006, 2007, 2008, 2009 Dirk Laurie
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} invhilb (@var{n})
+## Return the inverse of a Hilbert matrix of order @var{n}.  This can be 
+## computed exactly using
+## @tex
+## $$\eqalign{
+##   A_{ij} &= -1^{i+j} (i+j-1)
+##              \left( \matrix{n+i-1 \cr n-j } \right)
+##              \left( \matrix{n+j-1 \cr n-i } \right)
+##              \left( \matrix{i+j-2 \cr i-2 } \right)^2 \cr
+##          &= { p(i)p(j) \over (i+j-1) }
+## }$$
+## where
+## $$
+##   p(k) = -1^k \left( \matrix{ k+n-1 \cr k-1 } \right)
+##               \left( \matrix{ n \cr k } \right)
+##$$
+## @end tex
+## @ifnottex
+## @example
+## @group
+##
+##             (i+j)         /n+i-1\  /n+j-1\   /i+j-2\ 2
+##  A(i,j) = -1      (i+j-1)(       )(       ) (       )
+##                           \ n-j /  \ n-i /   \ i-2 /
+##
+##         = p(i) p(j) / (i+j-1)
+##
+## @end group
+## @end example
+## where
+## @example
+## @group
+##              k  /k+n-1\   /n\
+##     p(k) = -1  (       ) (   )
+##                 \ k-1 /   \k/
+## @end group
+## @end example
+## @end ifnottex
+##
+## The validity of this formula can easily be checked by expanding 
+## the binomial coefficients in both formulas as factorials.  It can 
+## be derived more directly via the theory of Cauchy matrices: 
+## see J. W. Demmel, Applied Numerical Linear Algebra, page 92.
+##
+## Compare this with the numerical calculation of @code{inverse (hilb (n))},
+## which suffers from the ill-conditioning of the Hilbert matrix, and the
+## finite precision of your computer's floating point arithmetic.
+## @seealso{hankel, vander, sylvester_matrix, hilb, toeplitz}
+## @end deftypefn
+
+## Author: Dirk Laurie <dlaurie at na-net.ornl.gov>
+
+function retval = invhilb (n)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  nmax = length (n);
+  if (nmax == 1)
+
+    ## The point about the second formula above is that when vectorized,
+    ## p(k) is evaluated for k=1:n which involves O(n) calls to bincoeff 
+    ## instead of O(n^2).
+    ##
+    ## We evaluate the expression as (-1)^(i+j)*(p(i)*p(j))/(i+j-1) except
+    ## when p(i)*p(j) would overflow.  In cases where p(i)*p(j) is an exact
+    ## machine number, the result is also exact.  Otherwise we calculate
+    ## (-1)^(i+j)*p(i)*(p(j)/(i+j-1)).
+    ##
+    ## The Octave bincoeff routine uses transcendental functions (gammaln
+    ## and exp) rather than multiplications, for the sake of speed.  
+    ## However, it rounds the answer to the nearest integer, which 
+    ## justifies the claim about exactness made above.
+
+    retval = zeros (n); 
+    k = [1:n]; 
+    p = k .* bincoeff (k+n-1, k-1) .* bincoeff (n, k);
+    p(2:2:n) = -p(2:2:n);
+    if (n < 203)
+      for l = 1:n
+        retval(l,:) = (p(l) * p) ./ [l:l+n-1];
+      endfor
+    else
+      for l = 1:n
+        retval(l,:) = p(l) * (p ./ [l:l+n-1]);
+      endfor
+    endif
+  else
+    error ("invhilb: expecting scalar argument, found something else");
+  endif
+
+endfunction
+
+%!test
+%! result4 = [16, -120, 240, -140;
+%! -120, 1200, -2700, 1680;
+%! 240, -2700, 6480, -4200;
+%! -140, 1680, -4200, 2800];
+%! 
+%! assert((invhilb (1) == 1 && invhilb (2) == [4, -6; -6, 12]
+%! && invhilb (4) == result4
+%! && abs (invhilb (7) * hilb (7) - eye (7)) < sqrt (eps)));
+
+%!error invhilb ([1, 2]);
+
+%!error invhilb ();
+
+%!error invhilb (1, 2);
+
diff --git a/scripts/special-matrix/magic.m b/scripts/special-matrix/magic.m
new file mode 100644
index 0000000..ad464bb
--- /dev/null
+++ b/scripts/special-matrix/magic.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1999, 2000, 2001, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} magic (@var{n})
+##
+## Create an @var{n}-by- at var{n} magic square.  Note that @code{magic
+## (@var{2})} is undefined since there is no 2-by-2 magic square.
+##
+## @end deftypefn
+
+function A = magic(n)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (n != floor (n) || n < 0 || n == 2)
+    error ("magic: n must be an positive integer not equal to 2");
+  endif
+
+  if (n == 0)
+
+    A = [];
+
+  elseif (mod (n, 2) == 1)
+
+    shift = floor ((0:n*n-1)/n);
+    c = mod ([1:n*n] - shift + (n-3)/2, n);
+    r = mod ([n*n:-1:1] + 2*shift, n);
+    A (c*n+r+1) = 1:n*n;
+    A = reshape (A, n, n);
+
+  elseif (mod (n, 4) == 0)
+
+    A = reshape (1:n*n, n, n)';
+    I = [1:4:n, 4:4:n];
+    J = fliplr (I);
+    A(I,I) = A(J,J);
+    I = [2:4:n, 3:4:n];
+    J = fliplr (I);
+    A(I,I) = A(J,J);
+
+  elseif (mod (n, 4) == 2)
+
+    m = n/2;
+    A = magic (m);
+    A = [A, A+2*m*m; A+3*m*m, A+m*m];
+    k = (m-1)/2;
+    if (k>1)
+      I = 1:m;
+      J = [2:k, n-k+2:n];
+      A([I,I+m],J) = A([I+m,I],J);
+    endif
+    I = [1:k, k+2:m];
+    A([I,I+m],1) = A([I+m,I],1);
+    I = k + 1;
+    A([I,I+m],I) = A([I+m,I],I);
+  
+  endif
+
+endfunction
+
+%!test
+%! for i=3:30
+%!   A=magic(i);
+%!   assert(norm(diff([sum(diag(A)),sum(diag(flipud(A))),sum(A),sum(A')])),0)
+%! endfor
+%!assert(isempty(magic(0)));
+%!assert(magic(1),1);
+%!error magic(2)
diff --git a/scripts/special-matrix/pascal.m b/scripts/special-matrix/pascal.m
new file mode 100644
index 0000000..be9d9b2
--- /dev/null
+++ b/scripts/special-matrix/pascal.m
@@ -0,0 +1,79 @@
+## Copyright (C) 1999, 2006, 2007 Peter Ekberg
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} pascal (@var{n}, @var{t})
+##
+## Return the Pascal matrix of order @var{n} if @code{@var{t} = 0}.
+## @var{t} defaults to 0. Return lower triangular Cholesky factor of 
+## the Pascal matrix if @code{@var{t} = 1}.  This matrix is its own
+## inverse, that is @code{pascal (@var{n}, 1) ^ 2 == eye (@var{n})}.
+## If @code{@var{t} = -1}, return its absolute value.  This is the
+## standard pascal triangle as a lower-triangular matrix.
+## If @code{@var{t} = 2}, return a transposed and permuted version of
+## @code{pascal (@var{n}, 1)}, which is the cube-root of the identity
+## matrix.  That is @code{pascal (@var{n}, 2) ^ 3 == eye (@var{n})}.
+##
+## @seealso{hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz
+##           hadamard, wilkinson, compan, rosser}
+## @end deftypefn
+
+## Author: Peter Ekberg
+##         (peda)
+
+function retval = pascal (n, t)
+
+  if (nargin > 2) || (nargin == 0)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    t = 0;
+  endif
+
+  if (! isscalar (n) || ! isscalar (t))
+    error ("pascal: expecting scalar arguments, found something else");
+  endif
+
+  retval = zeros (n);
+  retval(:,1) = 1;
+
+  if (t == -1)
+    for j = 2:n
+      retval(j:n,j) = cumsum (retval (j-1:n-1,j-1));
+    endfor
+  else
+    for j = 2:n
+      retval(j:n,j) = -cumsum (retval (j-1:n-1,j-1));
+    endfor
+  endif
+
+  if (t == 0)
+    retval = retval*retval';
+  elseif (t == 2)
+    retval = retval';
+    retval = retval(n:-1:1,:);
+    retval(:,n) = -retval(:,n);
+    retval(n,:) = -retval(n,:);
+    if (rem(n,2) != 1)
+      retval = -retval;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/special-matrix/rosser.m b/scripts/special-matrix/rosser.m
new file mode 100644
index 0000000..28a3ec1
--- /dev/null
+++ b/scripts/special-matrix/rosser.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1999, 2006, 2007, 2009 Peter Ekberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rosser ()
+##
+## Returns the Rosser matrix.  This is a difficult test case used to test
+## eigenvalue algorithms.
+##
+## @seealso{hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz
+##           hadamard, wilkinson, compan, pascal}
+## @end deftypefn
+
+## Author: Peter Ekberg
+##         (peda)
+
+function retval = rosser ()
+
+  if (nargin != 0)
+    print_usage ();
+  endif
+
+  retval = [611,   196,  -192,   407,    -8,   -52,   -49,    29;
+            196,   899,   113,  -192,   -71,   -43,    -8,   -44;
+           -192,   113,   899,   196,    61,    49,     8,    52;
+            407,  -192,   196,   611,     8,    44,    59,   -23;
+             -8,   -71,    61,     8,   411,  -599,   208,   208;
+            -52,   -43,    49,    44,  -599,   411,   208,   208;
+            -49,    -8,     8,    59,   208,   208,    99,  -911;
+             29,   -44,    52,   -23,   208,   208,  -911,    99];
+endfunction
diff --git a/scripts/special-matrix/sylvester_matrix.m b/scripts/special-matrix/sylvester_matrix.m
new file mode 100644
index 0000000..ea3c8b5
--- /dev/null
+++ b/scripts/special-matrix/sylvester_matrix.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} sylvester_matrix (@var{k})
+## Return the Sylvester matrix of order
+## @tex
+## $n = 2^k$.
+## @end tex
+## @ifnottex
+## n = 2^k.
+## @end ifnottex
+## @seealso{hankel, vander, hilb, invhilb, toeplitz}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = sylvester_matrix (k)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (isscalar (k))
+    if (k < 1)
+      retval = 1;
+    else
+      tmp = sylvester_matrix (k-1);
+      retval = [tmp, tmp; tmp, -tmp];
+    endif
+  else
+    error ("sylvester_matrix: expecting scalar argument");
+  endif
+
+endfunction
+
+%!assert((sylvester_matrix (1) == [1, 1; 1, -1]
+%! && (sylvester_matrix (2)
+%! == [1, 1, 1, 1; 1, -1, 1, -1; 1, 1, -1, -1; 1, -1, -1, 1])));
+
+%!error sylvester_matrix ([1, 2; 3, 4]);
+
+%!error sylvester_matrix ();
+
+%!error sylvester_matrix (1, 2);
+
diff --git a/scripts/special-matrix/toeplitz.m b/scripts/special-matrix/toeplitz.m
new file mode 100644
index 0000000..4b5961e
--- /dev/null
+++ b/scripts/special-matrix/toeplitz.m
@@ -0,0 +1,125 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} toeplitz (@var{c}, @var{r})
+## Return the Toeplitz matrix constructed given the first column @var{c},
+## and (optionally) the first row @var{r}.  If the first element of @var{c}
+## is not the same as the first element of @var{r}, the first element of
+## @var{c} is used.  If the second argument is omitted, the first row is
+## taken to be the same as the first column.
+##
+## A square Toeplitz matrix has the form:
+## @tex
+## $$
+## \left[\matrix{c_0    & r_1     & r_2      & \cdots & r_n\cr
+##               c_1    & c_0     & r_1      & \cdots & r_{n-1}\cr
+##               c_2    & c_1     & c_0      & \cdots & r_{n-2}\cr
+##               \vdots & \vdots  & \vdots   & \ddots & \vdots\cr
+##               c_n    & c_{n-1} & c_{n-2} & \ldots & c_0}\right]
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+## c(0)  r(1)   r(2)  @dots{}  r(n)
+## c(1)  c(0)   r(1)  @dots{} r(n-1)
+## c(2)  c(1)   c(0)  @dots{} r(n-2)
+##  .     ,      ,   .      .
+##  .     ,      ,     .    .
+##  .     ,      ,       .  .
+## c(n) c(n-1) c(n-2) @dots{}  c(0)
+## @end group
+## @end example
+## @end ifnottex
+## @seealso{hankel, vander, sylvester_matrix, hilb, invhilb}
+## @end deftypefn
+
+## Author: jwe && jh
+
+function retval = toeplitz (c, r)
+
+  if (nargin == 1)
+    r = c;
+  elseif (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! (isvector (c) && isvector (r)))
+    error ("toeplitz: expecting vector arguments");
+  endif
+
+  nc = length (r);
+  nr = length (c);
+
+  if (nr == 0 || nc == 0)
+    ## Empty matrix.
+    retval = zeros (nr, nc, class (c));
+    return;
+  endif
+
+  if (r (1) != c (1))
+    warning ("toeplitz: column wins diagonal conflict");
+  endif
+
+  ## If we have a single complex argument, we want to return a
+  ## Hermitian-symmetric matrix (actually, this will really only be
+  ## Hermitian-symmetric if the first element of the vector is real).
+
+  if (nargin == 1 && iscomplex (c))
+    c = conj (c);
+    c(1) = conj (c(1));
+  endif
+
+  if (issparse(c) && issparse(r))
+    c = c(:).';
+    r = r(:).';
+    cidx = find(c);
+    ridx = find(r);
+
+    ## Ignore the first element in r.
+    ridx = ridx(ridx > 1);
+
+    ## Form matrix.
+    retval = spdiags(repmat(c(cidx),nr,1),1-cidx,nr,nc)+...
+	spdiags(repmat(r(ridx),nr,1),ridx-1,nr,nc);
+  else  
+    ## Concatenate data into a single column vector.
+    data = [r(end:-1:2)(:); c(:)];
+
+    ## Get slices.
+    slices = cellslices (data, nc:-1:1, nc+nr-1:-1:nr);
+
+    ## Form matrix.
+    retval = horzcat (slices{:});
+  endif
+endfunction
+
+%!assert((toeplitz (1) == 1
+%! && toeplitz ([1, 2, 3], [1; -3; -5]) == [1, -3, -5; 2, 1, -3; 3, 2, 1]
+%! && toeplitz ([1, 2, 3], [1; -3i; -5i]) == [1, -3i, -5i; 2, 1, -3i; 3, 2, 1]));
+
+%!error toeplitz ([1, 2; 3, 4], 1);
+
+%!error toeplitz ();
+
+%!error toeplitz (1, 2, 3);
+
diff --git a/scripts/special-matrix/vander.m b/scripts/special-matrix/vander.m
new file mode 100644
index 0000000..be96522
--- /dev/null
+++ b/scripts/special-matrix/vander.m
@@ -0,0 +1,95 @@
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+##               2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} vander (@var{c}, @var{n})
+## Return the Vandermonde matrix whose next to last column is @var{c}.
+## If @var{n} is specified, it determines the number of columns;
+## otherwise, @var{n} is taken to be equal to the length of @var{c}.
+##
+## A Vandermonde matrix has the form:
+## @tex
+## $$
+## \left[\matrix{c_1^{n-1}  & \cdots & c_1^2  & c_1    & 1      \cr
+##               c_2^{n-1}  & \cdots & c_2^2  & c_2    & 1      \cr
+##               \vdots     & \ddots & \vdots & \vdots & \vdots \cr
+##               c_n^{n-1}  & \cdots & c_n^2  & c_n    & 1      }\right]
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+## c(1)^(n-1) @dots{} c(1)^2  c(1)  1
+## c(2)^(n-1) @dots{} c(2)^2  c(2)  1
+##     .     .      .      .    .
+##     .       .    .      .    .
+##     .         .  .      .    .
+## c(n)^(n-1) @dots{} c(n)^2  c(n)  1
+## @end group
+## @end example
+## @end ifnottex
+## @seealso{hankel, sylvester_matrix, hilb, invhilb, toeplitz}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = vander (c, n)
+
+  if (nargin == 1)
+    n = length (c);
+  elseif (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isvector (c))
+    retval = zeros (length (c), n, class (c));
+    ## avoiding many ^s appears to be faster for n >= 100.
+    d = 1;
+    c = c(:);
+    for i = n:-1:1
+      retval(:,i) = d;
+      d = c .* d;
+    endfor
+  else
+    error ("vander: argument must be a vector");
+  endif
+
+endfunction
+
+%!test
+%! c = [0,1,2,3];
+%! expect = [0,0,0,1; 1,1,1,1; 8,4,2,1; 27,9,3,1];
+%! result = vander(c);
+%! assert(expect, result);
+
+%!assert((vander (1) == 1 && vander ([1, 2, 3]) == vander ([1; 2; 3])
+%! && vander ([1, 2, 3]) == [1, 1, 1; 4, 2, 1; 9, 3, 1]
+%! && vander ([1, 2, 3]*i) == [-1, i, 1; -4, 2i, 1; -9, 3i, 1]));
+
+%!assert(vander (2, 3), [4, 2, 1])
+%!assert(vander ([2, 3], 3), [4, 2, 1; 9, 3, 1])
+
+%!error vander ([1, 2; 3, 4]);
+
+%!error vander ();
+
+%!error vander (1, 2, 3);
+
diff --git a/scripts/special-matrix/wilkinson.m b/scripts/special-matrix/wilkinson.m
new file mode 100644
index 0000000..46748aa
--- /dev/null
+++ b/scripts/special-matrix/wilkinson.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1999, 2006, 2007 Peter Ekberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wilkinson (@var{n})
+##
+## Return the Wilkinson matrix of order @var{n}.
+##
+## @seealso{hankel, vander, sylvester_matrix, hilb, invhilb, toeplitz
+##           hadamard, rosser, compan, pascal}
+## @end deftypefn
+
+## Author: Peter Ekberg
+##         (peda)
+
+function retval = wilkinson (n)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  nmax = length (n);
+  if (! (nmax == 1))
+    error ("wilkinson: expecting scalar argument, found something else");
+  endif
+
+  side = ones (n-1, 1);
+  center = abs (-(n-1)/2:(n-1)/2);
+  retval = diag (side, -1) + diag (center) + diag (side, 1);
+
+endfunction
diff --git a/scripts/startup/Makefile.in b/scripts/startup/Makefile.in
new file mode 100644
index 0000000..639f0a4
--- /dev/null
+++ b/scripts/startup/Makefile.in
@@ -0,0 +1,107 @@
+# Makefile for octave's scripts/startup directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2003, 2005, 2006, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = startup
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = __finish__.m main-rcfile local-rcfile inputrc
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)
+	if test -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/octaverc; then true; \
+	else \
+	  $(INSTALL_DATA) $(srcdir)/main-rcfile \
+	    $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/octaverc; \
+	fi
+	if test -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/inputrc; then true; \
+	else \
+	  $(INSTALL_DATA) $(srcdir)/inputrc \
+	    $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/inputrc; \
+	fi
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(localfcnfiledir)/$(script_sub_dir)
+	if test -f $(DESTDIR)$(localfcnfiledir)/$(script_sub_dir)/octaverc; \
+	then true; \
+	else \
+	  $(INSTALL_DATA) $(srcdir)/local-rcfile \
+	    $(DESTDIR)$(localfcnfiledir)/$(script_sub_dir)/octaverc; \
+	fi
+	for f in $(FCN_FILES_NO_DIR); do \
+	  rm -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/$$f; \
+	  $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/$$f; \
+	done
+.PHONY: install install-strip
+
+uninstall:
+	for f in $(FCN_FILES_NO_DIR); \
+	  do rm -f $(DESTDIR)$(fcnfiledir)/$(script_sub_dir)/$$f; \
+	done
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/startup
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/startup/__finish__.m b/scripts/startup/__finish__.m
new file mode 100644
index 0000000..5bef807
--- /dev/null
+++ b/scripts/startup/__finish__.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2008, 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __finish__ ()
+## Undocumented internal function.
+## @end deftypefn
+
+## Check for the existence of the function/script, @file{finish}, in the 
+## path or current working directory and execute it.  This function is
+## intended to be excecuted upon a clean exit form Octave.  This is
+## accomplished in the system script @file{startup/octaverc} by use of
+## the built-in function @code{onexit}.
+
+function __finish__ ()
+
+  if (exist ("finish", "file"))
+    ## No arg list here since finish might be a script.
+    finish;
+  endif
+
+endfunction
+
diff --git a/scripts/startup/inputrc b/scripts/startup/inputrc
new file mode 100644
index 0000000..2adb532
--- /dev/null
+++ b/scripts/startup/inputrc
@@ -0,0 +1,21 @@
+## This file configures the behavior of line-input editing for all
+## Octave users when Octave is configured to use GNU Readline library
+## for input-line editing.
+
+## history-search-backward:
+## 
+##   Search backward through the history for the string of characters
+##   between the start of the current line and the point.  This is a
+##   non-incremental search.  Bound to "\e[A", the ANSI escape
+##   sequence for the UP arrow.
+
+"\e[A": history-search-backward
+
+## history-search-forward:
+## 
+##   Search forward through the history for the string of characters
+##   between the start of the current line and the point.  This is a
+##   non-incremental search.  Bound to "\e[B", the ANSI escape
+##   sequence for the DOWN arrow.
+
+"\e[B": history-search-forward
diff --git a/scripts/startup/local-rcfile b/scripts/startup/local-rcfile
new file mode 100644
index 0000000..6159d06
--- /dev/null
+++ b/scripts/startup/local-rcfile
@@ -0,0 +1,4 @@
+## System-wide startup file for Octave.
+##
+## This file should contain any commands that should be executed each
+## time Octave starts for every user at this site.
diff --git a/scripts/startup/main-rcfile b/scripts/startup/main-rcfile
new file mode 100644
index 0000000..8547e41
--- /dev/null
+++ b/scripts/startup/main-rcfile
@@ -0,0 +1,22 @@
+## System-wide startup file for Octave.
+##
+## This file should contain any commands that should be executed each
+## time Octave starts for every user at this site.
+
+## Configure readline using the file inputrc in the Octave startup
+## directory.
+
+read_readline_init_file (sprintf ("%s%s%s",
+				  octave_config_info ("startupfiledir"),
+				  filesep, "inputrc"));
+
+if (strcmp (PAGER (), "less") && isempty (getenv ("LESS")))
+  PAGER_FLAGS ('-e -X -P"-- less ?pB(%pB\\%):--. (f)orward, (b)ack, (q)uit$"');
+endif
+
+## This appears here instead of in the pkg/PKG_ADD file so that --norc
+## will also skip automatic loading of packages.
+
+pkg ("load", "auto");
+
+atexit ("__finish__");
diff --git a/scripts/statistics/Makefile.in b/scripts/statistics/Makefile.in
new file mode 100644
index 0000000..ec2b64c
--- /dev/null
+++ b/scripts/statistics/Makefile.in
@@ -0,0 +1,71 @@
+# Makefile for octave's scripts/statistics directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2005, 2007, 2008
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = statistics
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+DISTFILES = $(srcdir)/Makefile.in
+
+SUBDIRS = base distributions models tests
+
+DISTSUBDIRS = $(SUBDIRS)
+
+all: $(SUBDIRS)
+.PHONY: all
+
+$(SUBDIRS):
+	$(MAKE) -C $@ all
+.PHONY: $(SUBDIRS)
+
+install install-strip uninstall clean mostlyclean distclean maintainer-clean::
+	@$(subdir-for-command)
+.PHONY: install install-strip uninstall
+.PHONY: clean mostlyclean distclean maintainer-clean
+
+tags TAGS:
+	$(subdir-for-command)
+
+distclean::
+	rm -f Makefile
+
+maintainer-clean::
+	rm -f tags TAGS Makefile
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/statistics
+	for dir in $(DISTSUBDIRS); do mkdir ../../`cat ../../.fname`/scripts/statistics/$$dir; $(MAKE) -C $$dir $@; done
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+	@$(subdir-for-command)
+.PHONY: check-m-sources
diff --git a/scripts/statistics/base/Makefile.in b/scripts/statistics/base/Makefile.in
new file mode 100644
index 0000000..41aef41
--- /dev/null
+++ b/scripts/statistics/base/Makefile.in
@@ -0,0 +1,87 @@
+# Makefile for octave's scripts/statistics/base directory
+#
+# Copyright (C) 1998, 2002, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../../..
+
+script_sub_dir = statistics/base
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = __quantile__.m center.m cloglog.m cor.m corrcoef.m cov.m \
+  cut.m gls.m histc.m iqr.m kendall.m kurtosis.m logit.m mahalanobis.m \
+  mean.m meansq.m median.m mode.m moment.m ols.m ppplot.m prctile.m probit.m \
+  qqplot.m quantile.m range.m ranks.m run_count.m skewness.m spearman.m \
+  statistics.m std.m studentize.m table.m values.m var.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../../`cat ../../../.fname`/scripts/$(script_sub_dir)
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/statistics/base/__quantile__.m b/scripts/statistics/base/__quantile__.m
new file mode 100644
index 0000000..9a9bdcf
--- /dev/null
+++ b/scripts/statistics/base/__quantile__.m
@@ -0,0 +1,262 @@
+## Copyright (C) 2008, 2009 Ben Abbott and Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{q} =} __quantile__ (@var{x}, @var{p})
+## @deftypefnx {Function File} {@var{q} =} __quantile__ (@var{x}, @var{p}, @var{method})
+## Undocumented internal function.
+## @end deftypefn
+
+## For the cumulative probability values in @var{p}, compute the 
+## quantiles, @var{q} (the inverse of the cdf), for the sample, @var{x}.
+##
+## The optional input, @var{method}, refers to nine methods available in R
+## (http://www.r-project.org/). The default is @var{method} = 7. For more 
+## detail, see `help quantile'.
+## @seealso{prctile, quantile, statistics}
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Vectorized version: Jaroslav Hajek <highegg at gmail.com>
+## Description: Quantile function of a empirical samples
+
+function inv = __quantile__ (x, p, method = 5)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (! ismatrix (x))
+    error ("quantile: x must be a matrix");
+  endif
+
+  ## Save length and set shape of quantiles.
+  n = numel (p);
+  p = p(:);
+
+  ## Save length and set shape of samples.
+  ## FIXME: does sort guarantee that NaN's come at the end?
+  x = sort (x);
+  m = sum (! isnan (x));
+  mx = size (x, 1);
+  nx = size (x, 2);
+
+  ## Initialize output values.
+  inv = Inf*(-(p < 0) + (p > 1));
+  inv = repmat (inv, 1, nx);
+
+  ## Do the work.
+  if (any(k = find((p >= 0) & (p <= 1))))
+    n = length (k);
+    p = p (k);
+    ## Special case.
+    if (mx == 1)
+      inv(k,:) = repmat (x, n, 1);
+      return
+    endif
+
+    ## The column-distribution indices.
+    pcd = kron (ones (n, 1), mx*(0:nx-1));
+    mm = kron (ones (n, 1), m);
+    switch method
+      case {1, 2, 3}
+        switch method
+          case 1
+	    p = max (ceil (kron (p, m)), 1);
+	    inv(k,:) = x(p + pcd);
+
+          case 2
+	    p = kron (p, m);
+	    p_lr = max (ceil (p), 1);
+	    p_rl = min (floor (p + 1), mm);
+	    inv(k,:) = (x(p_lr + pcd) + x(p_rl + pcd))/2;
+
+          case 3
+           ## Used by SAS, method PCTLDEF=2.
+           ## http://support.sas.com/onlinedoc/913/getDoc/en/statug.hlp/stdize_sect14.htm
+	    t = max (kron (p, m), 1);
+	    t = roundb (t);
+	    inv(k,:) = x(t + pcd);
+        endswitch
+
+      otherwise
+        switch method
+          case 4
+	    p = kron (p, m);
+
+          case 5
+            ## Used by Matlab.
+	    p = kron (p, m) + 0.5;
+
+          case 6
+            ## Used by Minitab and SPSS.
+	    p = kron (p, m+1);
+
+          case 7
+            ## Used by S and R.
+	    p = kron (p, m-1) + 1;
+
+          case 8
+            ## Median unbiased .
+	    p = kron (p, m+1/3) + 1/3;
+
+          case 9
+            ## Approximately unbiased respecting order statistics.
+	    p = kron (p, m+0.25) + 0.375;
+
+          otherwise
+            error ("quantile: Unknown method, '%d'", method);
+        endswitch
+
+	## Duplicate single values.
+	imm1 = mm == 1;
+	x(2,imm1) = x(1,imm1);
+
+	## Interval indices.
+	pi = max (min (floor (p), mm-1), 1);
+	pr = max (min (p - pi, 1), 0);
+	pi += pcd;
+	inv(k,:) = (1-pr) .* x(pi) + pr .* x(pi+1);
+    endswitch
+  endif
+
+endfunction
+
+%!test
+%! p = 0.5;
+%! x = sort (rand (11));
+%! q = __quantile__ (x, p);
+%! assert (q, x(6,:))
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 3; 4];
+%! a = [1.0000   1.0000   2.0000   3.0000   4.0000
+%!      1.0000   1.5000   2.5000   3.5000   4.0000
+%!      1.0000   1.0000   2.0000   3.0000   4.0000
+%!      1.0000   1.0000   2.0000   3.0000   4.0000
+%!      1.0000   1.5000   2.5000   3.5000   4.0000
+%!      1.0000   1.2500   2.5000   3.7500   4.0000
+%!      1.0000   1.7500   2.5000   3.2500   4.0000
+%!      1.0000   1.4167   2.5000   3.5833   4.0000
+%!      1.0000   1.4375   2.5000   3.5625   4.0000];
+%! for m = (1:9)
+%!   q = __quantile__ (x, p, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 3; 4; 5];
+%! a = [1.0000   2.0000   3.0000   4.0000   5.0000
+%!      1.0000   2.0000   3.0000   4.0000   5.0000
+%!      1.0000   1.0000   2.0000   4.0000   5.0000
+%!      1.0000   1.2500   2.5000   3.7500   5.0000
+%!      1.0000   1.7500   3.0000   4.2500   5.0000
+%!      1.0000   1.5000   3.0000   4.5000   5.0000
+%!      1.0000   2.0000   3.0000   4.0000   5.0000
+%!      1.0000   1.6667   3.0000   4.3333   5.0000
+%!      1.0000   1.6875   3.0000   4.3125   5.0000];
+%! for m = (1:9)
+%!   q = __quantile__ (x, p, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 5; 9];
+%! a = [1.0000   1.0000   2.0000   5.0000   9.0000
+%!      1.0000   1.5000   3.5000   7.0000   9.0000
+%!      1.0000   1.0000   2.0000   5.0000   9.0000
+%!      1.0000   1.0000   2.0000   5.0000   9.0000
+%!      1.0000   1.5000   3.5000   7.0000   9.0000
+%!      1.0000   1.2500   3.5000   8.0000   9.0000
+%!      1.0000   1.7500   3.5000   6.0000   9.0000
+%!      1.0000   1.4167   3.5000   7.3333   9.0000
+%!      1.0000   1.4375   3.5000   7.2500   9.0000];
+%! for m = (1:9)
+%!   q = __quantile__ (x, p, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 5; 9; 11];
+%! a = [1.0000    2.0000    5.0000    9.0000   11.0000
+%!      1.0000    2.0000    5.0000    9.0000   11.0000
+%!      1.0000    1.0000    2.0000    9.0000   11.0000
+%!      1.0000    1.2500    3.5000    8.0000   11.0000
+%!      1.0000    1.7500    5.0000    9.5000   11.0000
+%!      1.0000    1.5000    5.0000   10.0000   11.0000
+%!      1.0000    2.0000    5.0000    9.0000   11.0000
+%!      1.0000    1.6667    5.0000    9.6667   11.0000
+%!      1.0000    1.6875    5.0000    9.6250   11.0000];
+%! for m = (1:9)
+%!   q = __quantile__ (x, p, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [16; 11; 15; 12; 15;  8; 11; 12;  6; 10];
+%! a = [6.0000   10.0000   11.0000   15.0000   16.0000
+%!      6.0000   10.0000   11.5000   15.0000   16.0000
+%!      6.0000    8.0000   11.0000   15.0000   16.0000
+%!      6.0000    9.0000   11.0000   13.5000   16.0000
+%!      6.0000   10.0000   11.5000   15.0000   16.0000
+%!      6.0000    9.5000   11.5000   15.0000   16.0000
+%!      6.0000   10.2500   11.5000   14.2500   16.0000
+%!      6.0000    9.8333   11.5000   15.0000   16.0000
+%!      6.0000    9.8750   11.5000   15.0000   16.0000];
+%! for m = (1:9)
+%!   q = __quantile__ (x, p, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [-0.58851;  0.40048;  0.49527; -2.551500; -0.52057; ...
+%!      -0.17841; 0.057322; -0.62523;  0.042906;  0.12337];
+%! a = [-2.551474  -0.588505  -0.178409   0.123366   0.495271
+%!      -2.551474  -0.588505  -0.067751   0.123366   0.495271
+%!      -2.551474  -0.625231  -0.178409   0.123366   0.495271
+%!      -2.551474  -0.606868  -0.178409   0.090344   0.495271
+%!      -2.551474  -0.588505  -0.067751   0.123366   0.495271
+%!      -2.551474  -0.597687  -0.067751   0.192645   0.495271
+%!      -2.551474  -0.571522  -0.067751   0.106855   0.495271
+%!      -2.551474  -0.591566  -0.067751   0.146459   0.495271
+%!      -2.551474  -0.590801  -0.067751   0.140686   0.495271];
+%! for m = (1:9)
+%!   q = __quantile__ (x, p, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = 0.5;
+%! x = [0.112600, 0.114800, 0.052100, 0.236400, 0.139300
+%!      0.171800, 0.727300, 0.204100, 0.453100, 0.158500
+%!      0.279500, 0.797800, 0.329600, 0.556700, 0.730700
+%!      0.428800, 0.875300, 0.647700, 0.628700, 0.816500
+%!      0.933100, 0.931200, 0.963500, 0.779600, 0.846100];
+%! tol = 0.00001;
+%! x(5,5) = NaN;
+%! assert (__quantile__ (x, p), [0.27950, 0.79780, 0.32960, 0.55670, 0.44460], tol);
+%! x(1,1) = NaN;
+%! assert (__quantile__ (x, p), [0.35415, 0.79780, 0.32960, 0.55670, 0.44460], tol);
+%! x(3,3) = NaN;
+%! assert (__quantile__ (x, p), [0.35415, 0.79780, 0.42590, 0.55670, 0.44460], tol);
+
diff --git a/scripts/statistics/base/center.m b/scripts/statistics/base/center.m
new file mode 100644
index 0000000..d91515e
--- /dev/null
+++ b/scripts/statistics/base/center.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} center (@var{x})
+## @deftypefnx {Function File} {} center (@var{x}, @var{dim})
+## If @var{x} is a vector, subtract its mean.
+## If @var{x} is a matrix, do the above for each column.
+## If the optional argument @var{dim} is given, perform the above
+## operation along this dimension
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Center by subtracting means
+
+function retval = center (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    t = find (size (x) != 1);
+    if (isempty (t))
+      dim = 1;
+    else
+      dim = t(1);
+    endif
+  endif
+  n = size (x, dim);
+
+  if (n == 1)
+    retval = zeros (size (x));
+  elseif (n > 0)
+    if (isvector (x))
+      retval = x - sum (x) / n;
+    else
+      mx = sum (x, dim) / n;
+      idx(1:ndims (x)) = {':'}; 
+      idx{dim} = ones (1, n);
+      retval = x - mx(idx{:});
+    endif
+  else
+    retval = x;
+  endif
+endfunction
diff --git a/scripts/statistics/base/cloglog.m b/scripts/statistics/base/cloglog.m
new file mode 100644
index 0000000..5b296ba
--- /dev/null
+++ b/scripts/statistics/base/cloglog.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cloglog (@var{x})
+## Return the complementary log-log function of @var{x}, defined as
+##
+## @tex
+## $$
+## {\rm cloglog}(x) = - \log (- \log (x))
+## $$
+## @end tex
+## @ifnottex
+## @example
+## cloglog(x) = - log (- log (@var{x}))
+## @end example
+## @end ifnottex
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Complementary log-log function
+
+function y = cloglog (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  y = - log (- log (x));
+
+endfunction
diff --git a/scripts/statistics/base/cor.m b/scripts/statistics/base/cor.m
new file mode 100644
index 0000000..9f3f683
--- /dev/null
+++ b/scripts/statistics/base/cor.m
@@ -0,0 +1,66 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cor (@var{x}, @var{y})
+## Compute correlation.
+##
+## The (@var{i}, @var{j})-th entry of @code{cor (@var{x}, @var{y})} is
+## the correlation between the @var{i}-th variable in @var{x} and the
+## @var{j}-th variable in @var{y}.
+##
+## @tex
+## $$
+## {\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
+## $$
+## @end tex
+## @ifnottex
+## @example
+## corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+## @end example
+## @end ifnottex
+##
+## For matrices, each row is an observation and each column a variable;
+## vectors are always observations and may be row or column vectors.
+##
+## @code{cor (@var{x})} is equivalent to @code{cor (@var{x}, @var{x})}.
+##
+## Note that the @code{corrcoef} function does the same as @code{cor}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute correlations
+
+function retval = cor (x, y)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    c = cov (x, y);
+    s = std (x)' * std (y);
+    retval = c ./ s;
+  elseif (nargin == 1)
+    c = cov (x);
+    s = reshape (sqrt (diag (c)), 1, columns (c));
+    retval = c ./ (s' * s);
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/corrcoef.m b/scripts/statistics/base/corrcoef.m
new file mode 100644
index 0000000..07a62a8
--- /dev/null
+++ b/scripts/statistics/base/corrcoef.m
@@ -0,0 +1,75 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2004, 2005, 2006, 2007, 2008, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} corrcoef (@var{x}, @var{y})
+## Compute correlation.
+##
+## If each row of @var{x} and @var{y} is an observation and each column is
+## a variable, the (@var{i}, @var{j})-th entry of
+## @code{corrcoef (@var{x}, @var{y})} is the correlation between the
+## @var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}.
+##
+## @tex
+## $$
+## {\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
+## $$
+## @end tex
+## @ifnottex
+## @example
+## corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
+## @end example
+## @end ifnottex
+##
+## If called with one argument, compute @code{corrcoef (@var{x}, @var{x})}.
+## @end deftypefn
+
+## Author: Kurt Hornik <hornik at wu-wien.ac.at>
+## Created: March 1993
+## Adapted-By: jwe
+
+function retval = corrcoef (x, y)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    c = cov (x, y);
+    s = std (x)' * std (y);
+    retval = c ./ s;
+  elseif (nargin == 1)
+    c = cov (x);
+    s = reshape (sqrt (diag (c)), 1, columns (c));
+    retval = c ./ (s' * s);
+  endif
+
+endfunction
+
+%!test
+%! x = rand (10);
+%! cc1 = corrcoef (x);
+%! cc2 = corrcoef (x, x);
+%! assert((size (cc1) == [10, 10] && size (cc2) == [10, 10]
+%! && abs (cc1 - cc2) < sqrt (eps)));
+
+%!error corrcoef ();
+
+%!error corrcoef (1, 2, 3);
+
diff --git a/scripts/statistics/base/cov.m b/scripts/statistics/base/cov.m
new file mode 100644
index 0000000..02a2988
--- /dev/null
+++ b/scripts/statistics/base/cov.m
@@ -0,0 +1,77 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cov (@var{x}, @var{y})
+## Compute covariance.
+##
+## If each row of @var{x} and @var{y} is an observation and each column is
+## a variable, the (@var{i}, @var{j})-th entry of
+## @code{cov (@var{x}, @var{y})} is the covariance between the @var{i}-th
+## variable in @var{x} and the @var{j}-th variable in @var{y}.
+## @tex
+## $$
+## \sigma_{ij} = {1 \over N-1} \sum_{i=1}^N (x_i - \bar{x})(y_i - \bar{y})
+## $$
+## where $\bar{x}$ and $\bar{y}$ are the mean values of $x$ and $y$.
+## @end tex
+## If called with one argument, compute @code{cov (@var{x}, @var{x})}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute covariances
+
+function c = cov (x, y)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (rows (x) == 1)
+    x = x';
+  endif
+  n = rows (x);
+
+  if (nargin == 2)
+    if (rows (y) == 1)
+      y = y';
+    endif
+    if (rows (y) != n)
+      error ("cov: x and y must have the same number of observations");
+    endif
+    x = center (x, 1);
+    y = center (y, 1);
+    c = conj (x' * y / (n - 1));
+  elseif (nargin == 1)
+    x = center (x, 1);
+    c = conj (x' * x / (n - 1));
+  endif
+
+endfunction
+
+%!test
+%! x = rand (10);
+%! cx1 = cov (x);
+%! cx2 = cov (x, x);
+%! assert(size (cx1) == [10, 10] && size (cx2) == [10, 10] && norm(cx1-cx2) < 1e1*eps);
+
+%!error cov ();
+
+%!error cov (1, 2, 3);
+
diff --git a/scripts/statistics/base/cut.m b/scripts/statistics/base/cut.m
new file mode 100644
index 0000000..4bfb210
--- /dev/null
+++ b/scripts/statistics/base/cut.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cut (@var{x}, @var{breaks})
+## Create categorical data out of numerical or continuous data by
+## cutting into intervals.
+##
+## If @var{breaks} is a scalar, the data is cut into that many
+## equal-width intervals.  If @var{breaks} is a vector of break points,
+## the category has @code{length (@var{breaks}) - 1} groups.
+##
+## The returned value is a vector of the same size as @var{x} telling
+## which group each point in @var{x} belongs to.  Groups are labelled
+## from 1 to the number of groups; points outside the range of
+## @var{breaks} are labelled by @code{NaN}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Cut data into intervals
+
+function group = cut (X, BREAKS)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! isvector (X))
+    error ("cut: X must be a vector");
+  endif
+  if isscalar (BREAKS)
+    BREAKS = linspace (min (X), max (X), BREAKS + 1);
+    BREAKS(1) = BREAKS(1) - 1;
+  elseif isvector (BREAKS)
+    BREAKS = sort (BREAKS);
+  else
+    error ("cut: BREAKS must be a scalar or vector");
+  endif
+
+  group = NaN * ones (size (X));
+  m = length (BREAKS);
+  if any (k = find ((X >= min (BREAKS)) & (X <= max (BREAKS))))
+    n = length (k);
+    group(k) = sum ((ones (m, 1) * reshape (X(k), 1, n))
+                    > (reshape (BREAKS, m, 1) * ones (1, n)));
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/gls.m b/scripts/statistics/base/gls.m
new file mode 100644
index 0000000..6978bd8
--- /dev/null
+++ b/scripts/statistics/base/gls.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{beta}, @var{v}, @var{r}] =} gls (@var{y}, @var{x}, @var{o})
+## Generalized least squares estimation for the multivariate model
+## @tex
+## $y = x b + e$
+## with $\bar{e} = 0$ and cov(vec($e$)) = $(s^2)o$,
+## @end tex
+## @ifnottex
+## @math{y = x b + e} with @math{mean (e) = 0} and
+## @math{cov (vec (e)) = (s^2) o},
+## @end ifnottex
+##  where
+## @tex
+## $y$ is a $t \times p$ matrix, $x$ is a $t \times k$ matrix, $b$ is a $k
+## \times p$ matrix, $e$ is a $t \times p$ matrix, and $o$ is a $tp \times
+## tp$ matrix.
+## @end tex
+## @ifnottex
+## @math{y} is a @math{t} by @math{p} matrix, @math{x} is a @math{t} by
+## @math{k} matrix, @math{b} is a @math{k} by @math{p} matrix, @math{e}
+## is a @math{t} by @math{p} matrix, and @math{o} is a @math{t p} by
+## @math{t p} matrix.
+## @end ifnottex
+##
+## @noindent
+## Each row of @var{y} and @var{x} is an observation and each column a
+## variable.  The return values @var{beta}, @var{v}, and @var{r} are
+## defined as follows.
+##
+## @table @var
+## @item beta
+## The GLS estimator for @math{b}.
+##
+## @item v
+## The GLS estimator for @math{s^2}.
+##
+## @item r
+## The matrix of GLS residuals, @math{r = y - x beta}.
+## @end table
+## @end deftypefn
+
+## Author: Teresa Twaroch <twaroch at ci.tuwien.ac.at>
+## Created: May 1993
+## Adapted-By: jwe
+
+function [BETA, v, R] = gls (Y, X, O)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  [rx, cx] = size (X);
+  [ry, cy] = size (Y);
+  if (rx != ry)
+    error ("gls: incorrect matrix dimensions");
+  endif
+
+  O = O^(-1/2);
+  Z = kron (eye (cy), X);
+  Z = O * Z;
+  Y1 = O * reshape (Y, ry*cy, 1);
+  U = Z' * Z;
+  r = rank (U);
+
+  if (r == cx*cy)
+    B = inv (U) * Z' * Y1;
+  else
+    B = pinv (Z) * Y1;
+  endif
+
+  BETA = reshape (B, cx, cy);
+  R = Y - X * BETA;
+  v = (reshape (R, ry*cy, 1))' * (O^2) * reshape (R, ry*cy, 1) / (rx*cy - r);
+
+endfunction
diff --git a/scripts/statistics/base/histc.m b/scripts/statistics/base/histc.m
new file mode 100644
index 0000000..0a11a51
--- /dev/null
+++ b/scripts/statistics/base/histc.m
@@ -0,0 +1,166 @@
+## Copyright (C) 2009, Søren Hauberg
+## Copyright (C) 2009 VZLU Prague
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{n} =} histc (@var{y}, @var{edges})
+## @deftypefnx {Function File} {@var{n} =} histc (@var{y}, @var{edges}, @var{dim})
+## @deftypefnx {Function File} {[@var{n}, @var{idx}] =} histc (@dots{})
+## Produce histogram counts.
+##
+## When @var{y} is a vector, the function counts the number of elements of
+## @var{y} that fall in the histogram bins defined by @var{edges}.  This must be
+## a vector of monotonically non-decreasing values that define the edges of the
+## histogram bins.  So, @code{@var{n} (k)} contains the number of elements in
+## @var{y} for which @code{@var{edges} (k) <= @var{y} < @var{edges} (k+1)}.
+## The final element of @var{n} contains the number of elements of @var{y}
+## that was equal to the last element of @var{edges}.
+##
+## When @var{y} is a @math{N}-dimensional array, the same operation as above is
+## repeated along dimension @var{dim}.  If this argument is given, the operation
+## is performed along the first non-singleton dimension.
+##
+## If a second output argument is requested an index matrix is also returned.
+## The @var{idx} matrix has same size as @var{y}.  Each element of @var{idx}
+## contains the index of the histogram bin in which the corresponding element
+## of @var{y} was counted.
+##
+## @seealso{hist}
+## @end deftypefn
+
+function [n, idx] = histc (data, edges, dim)
+  ## Check input
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  sz = size (data);
+  if (nargin < 3)
+    dim = find (sz > 1, 1);
+    if (isempty (dim))
+      dim = 1;
+    endif
+  endif
+
+  if (!isreal (data))
+    error ("histc: first argument must be real a vector");
+  endif
+  
+  ## Make sure 'edges' is sorted
+  num_edges = numel (edges);
+  if (num_edges == 0)
+    error ("histc: edges must not be empty")
+  endif
+
+  if (isreal (edges))
+    edges = edges (:);
+    if (! issorted (edges) || edges(1) > edges(end))
+      warning ("histc: edge values not sorted on input");
+      edges = sort (edges);
+    endif
+  else
+    error ("histc: second argument must be a vector");
+  endif
+
+  nsz = sz;
+  nsz (dim) = num_edges;
+  
+  ## the splitting point is 3 bins
+
+  if (num_edges <= 3)
+
+    ## This is the O(M*N) algorithm.
+
+    ## Allocate the histogram
+    n = zeros (nsz);
+
+    ## Allocate 'idx'
+    if (nargout > 1)
+      idx = zeros (sz);
+    endif
+    
+    ## Prepare indices
+    idx1 = cell (1, dim-1);
+    for k = 1:length (idx1)
+      idx1 {k} = 1:sz (k);
+    endfor
+    idx2 = cell (length (sz) - dim);
+    for k = 1:length (idx2)
+      idx2 {k} = 1:sz (k+dim);
+    endfor
+    
+    ## Compute the histograms
+    for k = 1:num_edges-1
+      b = (edges (k) <= data & data < edges (k+1));
+      n (idx1 {:}, k, idx2 {:}) = sum (b, dim);
+      if (nargout > 1)
+        idx (b) = k;
+      endif
+    endfor
+    b = (data == edges (end));
+    n (idx1 {:}, num_edges, idx2 {:}) = sum (b, dim);
+    if (nargout > 1)
+      idx (b) = num_edges;
+    endif
+
+  else
+
+    ## This is the O(M*log(N) + N) algorithm.
+
+    ## Look-up indices.
+    idx = lookup (edges, data);
+    ## Zero invalid ones (including NaNs). data < edges(1) are already zero. 
+    idx(! (data <= edges(end))) = 0;
+
+    iidx = idx;
+
+    ## In case of matrix input, we adjust the indices.
+    if (! isvector (data))
+      nl = prod (sz(1:dim-1));
+      nn = sz(dim);
+      nu = prod (sz(dim+1:end));
+      if (nl != 1)
+        iidx = (iidx-1) * nl;
+        iidx += reshape (kron (ones (1, nn*nu), 1:nl), sz);
+      endif
+      if (nu != 1)
+        ne =length (edges);
+        iidx += reshape (kron (nl*ne*(0:nu-1), ones (1, nl*nn)), sz);
+      endif
+    endif
+
+    ## Select valid elements.
+    iidx = iidx(idx != 0);
+
+    ## Call accumarray to sum the indexed elements.
+    n = accumarray (iidx(:), 1, nsz);
+
+  endif
+
+endfunction
+
+%!test
+%! data = linspace (0, 10, 1001);
+%! n = histc (data, 0:10);
+%! assert (n, [repmat(100, 1, 10), 1]);
+
+%!test
+%! data = repmat (linspace (0, 10, 1001), [2, 1, 3]);
+%! n = histc (data, 0:10, 2);
+%! assert (n, repmat ([repmat(100, 1, 10), 1], [2, 1, 3]));
+
diff --git a/scripts/statistics/base/iqr.m b/scripts/statistics/base/iqr.m
new file mode 100644
index 0000000..bb06f6c
--- /dev/null
+++ b/scripts/statistics/base/iqr.m
@@ -0,0 +1,78 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005,
+##               2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} iqr (@var{x}, @var{dim})
+## If @var{x} is a vector, return the interquartile range, i.e., the
+## difference between the upper and lower quartile, of the input data.
+##
+## If @var{x} is a matrix, do the above for first non-singleton
+## dimension of @var{x}.  If the option @var{dim} argument is given,
+## then operate along this dimension.
+## @end deftypefn
+
+## Author KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Interquartile range
+
+function y = iqr (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  nel = numel (x);
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("iqr: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  ## This code is a bit heavy, but is needed until empirical_inv 
+  ## takes other than vector arguments.
+  c = sz(dim);
+  sz(dim) = 1;
+  y = zeros (sz);
+  stride = prod (sz(1:dim-1));
+  for i = 1 : nel / c;
+    offset = i;
+    offset2 = 0;
+    while (offset > stride)
+      offset -= stride;
+      offset2++;
+    endwhile
+    offset += offset2 * stride * c;
+    rng = [0 : c-1] * stride + offset;
+
+    y (i) = empirical_inv (3/4, x(rng)) - empirical_inv (1/4, x(rng));
+  endfor
+
+endfunction
diff --git a/scripts/statistics/base/kendall.m b/scripts/statistics/base/kendall.m
new file mode 100644
index 0000000..ff47391
--- /dev/null
+++ b/scripts/statistics/base/kendall.m
@@ -0,0 +1,103 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} kendall (@var{x}, @var{y})
+## Compute Kendall's @var{tau} for each of the variables specified by
+## the input arguments.
+##
+## For matrices, each row is an observation and each column a variable;
+## vectors are always observations and may be row or column vectors.
+##
+## @code{kendall (@var{x})} is equivalent to @code{kendall (@var{x},
+## @var{x})}.
+##
+## For two data vectors @var{x}, @var{y} of common length @var{n},
+## Kendall's @var{tau} is the correlation of the signs of all rank
+## differences of @var{x} and @var{y};  i.e., if both @var{x} and
+## @var{y} have distinct entries, then
+##
+## @tex
+## $$ \tau = {1 \over n(n-1)} \sum_{i,j} {\rm sign}(q_i-q_j) {\rm sign}(r_i-r_j) $$
+## @end tex
+## @ifnottex
+## @example
+## @group
+##          1    
+## tau = -------   SUM sign (q(i) - q(j)) * sign (r(i) - r(j))
+##       n (n-1)   i,j
+## @end group
+## @end example
+## @end ifnottex
+##
+## @noindent
+## in which the
+## @tex
+## $q_i$ and $r_i$
+## @end tex
+## @ifnottex
+## @var{q}(@var{i}) and @var{r}(@var{i})
+## @end ifnottex
+##  are the ranks of
+## @var{x} and @var{y}, respectively.
+##
+## If @var{x} and @var{y} are drawn from independent distributions,
+## Kendall's @var{tau} is asymptotically normal with mean 0 and variance
+## @tex
+## ${2 (2n+5) \over 9n(n-1)}$.
+## @end tex
+## @ifnottex
+## @code{(2 * (2 at var{n}+5)) / (9 * @var{n} * (@var{n}-1))}.
+## @end ifnottex
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Kendall's rank correlation tau
+
+function tau = kendall (x, y)
+
+  if ((nargin < 1) || (nargin > 2))
+    print_usage ();
+  endif
+
+  if (rows (x) == 1)
+    x = x';
+  endif
+  [n, c] = size (x);
+
+  if (nargin == 2)
+    if (rows (y) == 1)
+      y = y';
+    endif
+    if (rows (y) != n)
+      error ("kendall: x and y must have the same number of observations");
+    else
+      x = [x, y];
+    endif
+  endif
+
+  r   = ranks (x);
+  m   = sign (kron (r, ones (n, 1)) - kron (ones (n, 1), r));
+  tau = cor (m);
+
+  if (nargin == 2)
+    tau = tau (1 : c, (c + 1) : columns (x));
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/kurtosis.m b/scripts/statistics/base/kurtosis.m
new file mode 100644
index 0000000..d275653
--- /dev/null
+++ b/scripts/statistics/base/kurtosis.m
@@ -0,0 +1,97 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} kurtosis (@var{x}, @var{dim})
+## If @var{x} is a vector of length @math{N}, return the kurtosis
+## @tex
+## $$
+##  {\rm kurtosis} (x) = {1\over N \sigma(x)^4} \sum_{i=1}^N (x_i-\bar{x})^4 - 3
+## $$
+## where $\bar{x}$ is the mean value of $x$.
+## @end tex
+## @ifnottex
+##
+## @example
+## kurtosis (x) = N^(-1) std(x)^(-4) sum ((x - mean(x)).^4) - 3
+## @end example
+## @end ifnottex
+##
+## @noindent
+## of @var{x}.  If @var{x} is a matrix, return the kurtosis over the
+## first non-singleton dimension.  The optional argument @var{dim}
+## can be given to force the kurtosis to be given over that 
+## dimension.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 29 July 1994
+## Adapted-By: jwe
+
+function retval = kurtosis (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("kurtosis: dim must be an integer and valid dimension");
+    endif
+  endif
+  
+  if (! ismatrix (x))
+    error ("kurtosis: x has to be a matrix or a vector");
+  endif
+
+  c = sz(dim);
+  sz(dim) = 1;
+  idx = ones (1, nd);
+  idx(dim) = c;
+  x = x - repmat (mean (x, dim), idx);
+  retval = zeros (sz);
+  s = std (x, [], dim);
+  x = sum(x.^4, dim);
+  ind = find (s > 0);
+  retval(ind) = x(ind) ./ (c * s(ind) .^ 4) - 3;
+
+endfunction
+
+%!test
+%! x = [-1; 0; 0; 0; 1];
+%! y = [x, 2*x];
+%! assert(all (abs (kurtosis (y) - [-1.4, -1.4]) < sqrt (eps)));
+
+%!error kurtosis ();
+
+%!error kurtosis (1, 2, 3);
+
diff --git a/scripts/statistics/base/logit.m b/scripts/statistics/base/logit.m
new file mode 100644
index 0000000..8efcb0c
--- /dev/null
+++ b/scripts/statistics/base/logit.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logit (@var{p})
+## For each component of @var{p}, return the logit of @var{p} defined as
+## @tex
+## $$
+## {\rm logit}(p) = \log\Big({p \over 1-p}\Big)
+## $$
+## @end tex
+## @ifnottex
+## @example
+## logit(@var{p}) = log (@var{p} / (1- at var{p}))
+## @end example
+## @end ifnottex
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Logit transformation
+
+function y = logit (p)
+
+  if (nargin == 1)
+    y = logistic_inv (p);
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/mahalanobis.m b/scripts/statistics/base/mahalanobis.m
new file mode 100644
index 0000000..9a12a9b
--- /dev/null
+++ b/scripts/statistics/base/mahalanobis.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2005, 2006, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mahalanobis (@var{x}, @var{y})
+## Return the Mahalanobis' D-square distance between the multivariate
+## samples @var{x} and @var{y}, which must have the same number of
+## components (columns), but may have a different number of observations
+## (rows).
+## @end deftypefn
+
+## Author: Friedrich Leisch <leisch at ci.tuwien.ac.at>
+## Created: July 1993
+## Adapted-By: jwe
+
+function retval = mahalanobis (X, Y)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [xr, xc] = size (X);
+  [yr, yc] = size (Y);
+
+  if (xc != yc)
+    error ("mahalanobis: X and Y must have the same number of columns");
+  endif
+
+  Xm = sum (X) / xr;
+  Ym = sum (Y) / yr;
+
+  X = X - ones (xr, 1) * Xm;
+  Y = Y - ones (yr, 1) * Ym;
+
+  W = (X' * X + Y' * Y) / (xr + yr - 2);
+
+  Winv = inv (W);
+
+  retval = (Xm - Ym) * Winv * (Xm - Ym)';
+
+endfunction
+
+%!error mahalanobis ();
+
+%!error mahalanobis (1, 2, 3);
+
+
diff --git a/scripts/statistics/base/mean.m b/scripts/statistics/base/mean.m
new file mode 100644
index 0000000..4e77794
--- /dev/null
+++ b/scripts/statistics/base/mean.m
@@ -0,0 +1,125 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005,
+##               2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} mean (@var{x}, @var{dim}, @var{opt})
+## If @var{x} is a vector, compute the mean of the elements of @var{x}
+## @tex
+## $$ {\rm mean}(x) = \bar{x} = {1\over N} \sum_{i=1}^N x_i $$
+## @end tex
+## @ifnottex
+##
+## @example
+## mean (x) = SUM_i x(i) / N
+## @end example
+## @end ifnottex
+## If @var{x} is a matrix, compute the mean for each column and return them
+## in a row vector.
+##
+## With the optional argument @var{opt}, the kind of mean computed can be
+## selected.  The following options are recognized:
+##
+## @table @code
+## @item "a"
+## Compute the (ordinary) arithmetic mean.  This is the default.
+##
+## @item "g"
+## Compute the geometric mean.
+##
+## @item "h"
+## Compute the harmonic mean.
+## @end table
+##
+## If the optional argument @var{dim} is supplied, work along dimension
+## @var{dim}.
+##
+## Both @var{dim} and @var{opt} are optional.  If both are supplied,
+## either may appear first.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute arithmetic, geometric, and harmonic mean
+
+function y = mean (x, opt1, opt2)
+
+  need_dim = 0;
+
+  if (nargin == 1)
+    opt = "a";
+    need_dim = 1;
+  elseif (nargin == 2)
+    if (ischar (opt1))
+      opt = opt1;
+      need_dim = 1;
+    else
+      dim = opt1;
+      opt = "a";
+    endif
+  elseif (nargin == 3)
+    if (ischar (opt1))
+      opt = opt1;
+      dim = opt2;
+    elseif (ischar (opt2))
+      opt = opt2;
+      dim = opt1;
+    else
+      error ("mean: expecting opt to be a string");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (need_dim)
+    t = find (size (x) != 1);
+    if (isempty (t))
+      dim = 1;
+    else
+      dim = t(1);
+    endif
+  endif
+
+  if (dim > ndims (x))
+    n = 1;
+  else
+    sz = size (x);
+    n = sz (dim);
+  endif
+
+  if (strcmp (opt, "a"))
+    y = sum (x, dim) / n;
+  elseif (strcmp (opt, "g"))
+    y = prod (x, dim) .^ (1/n);
+  elseif (strcmp (opt, "h"))
+    y = n ./ sum (1 ./ x, dim);
+  else
+    error ("mean: option `%s' not recognized", opt);
+  endif
+
+endfunction
+
+%!test
+%! x = -10:10;
+%! y = x';
+%! z = [y, y+10];
+%! assert(mean (x) == 0 && mean (y) == 0 && mean (z) == [0, 10]);
+
+%!error mean ();
+
+%!error mean (1, 2, 3);
+
diff --git a/scripts/statistics/base/meansq.m b/scripts/statistics/base/meansq.m
new file mode 100644
index 0000000..fe56920
--- /dev/null
+++ b/scripts/statistics/base/meansq.m
@@ -0,0 +1,50 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+## Copyright (C) 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} meansq (@var{x})
+## @deftypefnx {Function File} {} meansq (@var{x}, @var{dim})
+## For vector arguments, return the mean square of the values.
+## For matrix arguments, return a row vector containing the mean square
+## of each column.  With the optional @var{dim} argument, returns the
+## mean squared of the values along this dimension.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute mean square
+
+function y = meansq (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    t = find (size (x) != 1);
+    if (isempty (t))
+      dim = 1;
+    else
+      dim = t(1);
+    endif
+  endif
+
+  y = sumsq (x, dim) / size (x, dim);
+
+endfunction
diff --git a/scripts/statistics/base/median.m b/scripts/statistics/base/median.m
new file mode 100644
index 0000000..0f1ab91
--- /dev/null
+++ b/scripts/statistics/base/median.m
@@ -0,0 +1,110 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} median (@var{x}, @var{dim})
+## If @var{x} is a vector, compute the median value of the elements of
+## @var{x}.  If the elements of @var{x} are sorted, the median is defined
+## as
+## @tex
+## $$
+## {\rm median} (x) =
+##   \cases{x(\lceil N/2\rceil), & $N$ odd;\cr
+##           (x(N/2)+x(N/2+1))/2, & $N$ even.}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##             x(ceil(N/2)),             N odd
+## median(x) =
+##             (x(N/2) + x((N/2)+1))/2,  N even
+## @end group
+## @end example
+## @end ifnottex
+## If @var{x} is a matrix, compute the median value for each
+## column and return them in a row vector.  If the optional @var{dim}
+## argument is given, operate along this dimension.
+## @seealso{std, mean}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = median (a, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+  if (nargin < 2)
+    dim = find (size (a) > 1, 1);
+    if (isempty (dim))
+      dim = 1;
+    endif
+  endif
+
+  sz = size (a);
+  s = sort (a, dim);
+  if (numel (a) > 0)
+    if (numel (a) == sz(dim))
+      if (rem (sz(dim), 2) == 0)
+	i = sz(dim) / 2;
+	retval = (s(i) + s(i+1)) / 2;
+      else
+	i = ceil (sz(dim) /2);
+	retval = s(i);
+      endif
+    else
+      idx = cell ();
+      nd = length (sz);
+      for i = 1:nd
+	idx{i} = 1:sz(i);
+      endfor
+      if (rem (sz(dim), 2) == 0)
+	i = sz(dim) / 2;
+	idx{dim} = i;
+	retval = s(idx{:});
+	idx{dim} = i+1;
+	retval = (retval + s(idx{:})) / 2;
+      else
+	idx{dim} = ceil (sz(dim) / 2);
+	retval = s(idx{:});
+      endif
+    endif
+  else
+    error ("median: invalid matrix argument");
+  endif
+
+endfunction
+
+%!test
+%! x = [1, 2, 3, 4, 5, 6];
+%! x2 = x';
+%! y = [1, 2, 3, 4, 5, 6, 7];
+%! y2 = y';
+%! 
+%! assert((median (x) == median (x2) && median (x) == 3.5
+%! && median (y) == median (y2) && median (y) == 4
+%! && median ([x2, 2*x2]) == [3.5, 7]
+%! && median ([y2, 3*y2]) == [4, 12]));
+
+%!error median ();
+
+%!error median (1, 2, 3);
+
diff --git a/scripts/statistics/base/mode.m b/scripts/statistics/base/mode.m
new file mode 100644
index 0000000..8fc0f7e
--- /dev/null
+++ b/scripts/statistics/base/mode.m
@@ -0,0 +1,151 @@
+## Copyright (C) 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{m}, @var{f}, @var{c}] =} mode (@var{x}, @var{dim})
+## Count the most frequently appearing value.  @code{mode} counts the 
+## frequency along the first non-singleton dimension and if two or more
+## values have the same frequency returns the smallest of the two in
+## @var{m}.  The dimension along which to count can be specified by the
+## @var{dim} parameter.
+##
+## The variable @var{f} counts the frequency of each of the most frequently 
+## occurring elements.  The cell array @var{c} contains all of the elements
+## with the maximum frequency .
+## @end deftypefn
+
+function [m, f, c] = mode (x, dim)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+        && dim > 0
+        && dim < (nd + 1))
+      error ("mode: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  sz2 = sz;
+  sz2 (dim) = 1;
+  sz3 = ones (1, nd);
+  sz3 (dim) = sz (dim);
+
+  if (issparse (x))
+    t2 = sparse (sz(1), sz(2));
+  else
+    t2 = zeros (sz);
+  endif
+
+  if (dim != 1)
+    perm = [dim, 1:dim-1, dim+1:nd];
+    t2 = permute (t2, perm);
+  endif
+
+  xs = sort (x, dim);
+  t = cat (dim, true (sz2), diff (xs, 1, dim) != 0);
+
+  if (dim != 1)
+    t2 (permute (t != 0, perm)) = diff ([find(permute (t, perm))(:); prod(sz)+1]);
+    f = max (ipermute (t2, perm), [], dim);
+    xs = permute (xs, perm);
+  else
+    t2 (t) = diff ([find(t)(:); prod(sz)+1]);
+    f = max (t2, [], dim);
+  endif
+
+  c = cell (sz2);
+  if (issparse (x))
+    m = sparse (sz2(1), sz2(2));
+  else
+    m = zeros (sz2);
+  endif
+  for i = 1 : prod (sz2)
+    c{i} = xs (t2 (:, i) == f(i), i);
+    m (i) = c{i}(1);
+  endfor
+endfunction
+
+%!test
+%! [m, f, c] = mode (toeplitz (1:5));
+%! assert (m, [1,2,2,2,1]);
+%! assert (f, [1,2,2,2,1]);
+%! assert (c, {[1;2;3;4;5],[2],[2;3],[2],[1;2;3;4;5]});
+%!test
+%! [m, f, c] = mode (toeplitz (1:5), 2);
+%! assert (m, [1;2;2;2;1]);
+%! assert (f, [1;2;2;2;1]);
+%! assert (c, {[1;2;3;4;5];[2];[2;3];[2];[1;2;3;4;5]});
+%!test
+%! a = sprandn (32, 32, 0.05);
+%! [m, f, c] = mode (a);
+%! [m2, f2, c2] = mode (full (a));
+%! assert (m, sparse (m2));
+%! assert (f, sparse (f2));
+%! assert (c, cellfun (@(x) sparse (0), c2, 'UniformOutput', false));
+
+%!assert(mode([2,3,1,2,3,4],1),[2,3,1,2,3,4])
+%!assert(mode([2,3,1,2,3,4],2),2)
+%!assert(mode([2,3,1,2,3,4]),2)
+
+%!assert(mode([2;3;1;2;3;4],1),2)
+%!assert(mode([2;3;1;2;3;4],2),[2;3;1;2;3;4])
+%!assert(mode([2;3;1;2;3;4]),2)
+
+%!shared x
+%! x(:,:,1) = toeplitz (1:3);
+%! x(:,:,2) = circshift (toeplitz (1:3), 1);
+%! x(:,:,3) = circshift (toeplitz (1:3), 2);
+%!test
+%! [m, f, c] = mode (x, 1);
+%! assert (reshape (m, [3, 3]), [1 1 1; 2 2 2; 1 1 1])
+%! assert (reshape (f, [3, 3]), [1 1 1; 2 2 2; 1 1 1])
+%! c = reshape (c, [3, 3]);
+%! assert (c{1}, [1; 2; 3])
+%! assert (c{2}, 2)
+%! assert (c{3}, [1; 2; 3])
+%!test
+%! [m, f, c] = mode (x, 2);
+%! assert (reshape (m, [3, 3]), [1 1 2; 2 1 1; 1 2 1])
+%! assert (reshape (f, [3, 3]), [1 1 2; 2 1 1; 1 2 1])
+%! c = reshape (c, [3, 3]);
+%! assert (c{1}, [1; 2; 3])
+%! assert (c{2}, 2)
+%! assert (c{3}, [1; 2; 3])
+%!test
+%! [m, f, c] = mode (x, 3);
+%! assert (reshape (m, [3, 3]), [1 2 1; 1 2 1; 1 2 1])
+%! assert (reshape (f, [3, 3]), [1 2 1; 1 2 1; 1 2 1])
+%! c = reshape (c, [3, 3]);
+%! assert (c{1}, [1; 2; 3])
+%! assert (c{2}, [1; 2; 3])
+%! assert (c{3}, [1; 2; 3])
diff --git a/scripts/statistics/base/moment.m b/scripts/statistics/base/moment.m
new file mode 100644
index 0000000..1485496
--- /dev/null
+++ b/scripts/statistics/base/moment.m
@@ -0,0 +1,108 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005,
+##               2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} moment (@var{x}, @var{p}, @var{opt}, @var{dim})
+## If @var{x} is a vector, compute the @var{p}-th moment of @var{x}.
+##
+## If @var{x} is a matrix, return the row vector containing the
+## @var{p}-th moment of each column.
+##
+## With the optional string opt, the kind of moment to be computed can
+## be specified.  If opt contains @code{"c"} or @code{"a"}, central
+## and/or absolute moments are returned.  For example,
+##
+## @example
+## moment (x, 3, "ac")
+## @end example
+##
+## @noindent
+## computes the third central absolute moment of @var{x}.
+##
+## If the optional argument @var{dim} is supplied, work along dimension
+## @var{dim}.
+## @end deftypefn
+
+## Can easily be made to work for continuous distributions (using quad)
+## as well, but how does the general case work?
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute moments
+
+function m = moment (x, p, opt1, opt2)
+
+  if ((nargin < 2) || (nargin > 4))
+    print_usage ();
+  endif
+
+  need_dim = 0;
+
+  if (nargin == 2)
+    opt = "";
+    need_dim = 1;
+  elseif (nargin == 3)
+    if (ischar (opt1))
+      opt = opt1;
+      need_dim = 1;
+    else
+      dim = opt1;
+      opt = "";
+    endif
+  elseif (nargin == 4)
+    if (ischar (opt1))
+      opt = opt1;
+      dim = opt2;
+    elseif (ischar (opt2))
+      opt = opt2;
+      dim = opt1;
+    else
+      error ("moment: expecting opt to be a string");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (need_dim)
+    t = find (size (x) != 1);
+    if (isempty (t))
+      dim = 1;
+    else
+      dim = t(1);
+    endif
+  endif
+
+  sz = size (x);
+  n = sz (dim);
+
+  if (numel (x) < 1)
+    error ("moment: x must not be empty");
+  endif
+
+  if any (opt == "c")
+    rng = ones (1, length (sz));
+    rng(dim) = sz(dim);
+    x = x - repmat (sum (x, dim), rng) / n;
+  endif
+  if any (opt == "a")
+    x = abs (x);
+  endif
+
+  m = sum (x .^ p, dim) / n;
+
+endfunction
diff --git a/scripts/statistics/base/ols.m b/scripts/statistics/base/ols.m
new file mode 100644
index 0000000..3cd796d
--- /dev/null
+++ b/scripts/statistics/base/ols.m
@@ -0,0 +1,100 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2005, 2006, 2007, 2009
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{beta}, @var{sigma}, @var{r}] =} ols (@var{y}, @var{x})
+## Ordinary least squares estimation for the multivariate model
+## @tex
+## $y = x b + e$
+## with
+## $\bar{e} = 0$, and cov(vec($e$)) = kron ($s, I$)
+## @end tex
+## @ifnottex
+## @math{y = x b + e} with
+## @math{mean (e) = 0} and @math{cov (vec (e)) = kron (s, I)}.
+## @end ifnottex
+##  where
+## @tex
+## $y$ is a $t \times p$ matrix, $x$ is a $t \times k$ matrix,
+## $b$ is a $k \times p$ matrix, and $e$ is a $t \times p$ matrix.
+## @end tex
+## @ifnottex
+## @math{y} is a @math{t} by @math{p} matrix, @math{x} is a @math{t} by
+## @math{k} matrix, @math{b} is a @math{k} by @math{p} matrix, and
+## @math{e} is a @math{t} by @math{p} matrix.
+## @end ifnottex
+##
+## Each row of @var{y} and @var{x} is an observation and each column a
+## variable.
+##
+## The return values @var{beta}, @var{sigma}, and @var{r} are defined as
+## follows.
+##
+## @table @var
+## @item beta
+## The OLS estimator for @var{b}, @code{@var{beta} = pinv (@var{x}) *
+## @var{y}}, where @code{pinv (@var{x})} denotes the pseudoinverse of
+## @var{x}.
+##
+## @item sigma
+## The OLS estimator for the matrix @var{s},
+##
+## @example
+## @group
+## @var{sigma} = (@var{y}- at var{x}*@var{beta})'
+##   * (@var{y}- at var{x}*@var{beta})
+##   / (@var{t}-rank(@var{x}))
+## @end group
+## @end example
+##
+## @item r
+## The matrix of OLS residuals, @code{@var{r} = @var{y} - @var{x} *
+## @var{beta}}.
+## @end table
+## @end deftypefn
+
+## Author: Teresa Twaroch <twaroch at ci.tuwien.ac.at>
+## Created: May 1993
+## Adapted-By: jwe
+
+function [BETA, SIGMA, R] = ols (Y, X)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [nr, nc] = size (X);
+  [ry, cy] = size (Y);
+  if (nr != ry)
+    error ("ols: incorrect matrix dimensions");
+  endif
+
+  Z = X' * X;
+  r = rank (Z);
+
+  if (r == nc)
+    BETA = inv (Z) * X' * Y;
+  else
+    BETA = pinv (X) * Y;
+  endif
+
+  R = Y - X * BETA;
+  SIGMA = R' * R / (nr - r);
+
+endfunction
diff --git a/scripts/statistics/base/ppplot.m b/scripts/statistics/base/ppplot.m
new file mode 100644
index 0000000..fd45fc9
--- /dev/null
+++ b/scripts/statistics/base/ppplot.m
@@ -0,0 +1,79 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005,
+##               2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{p}, @var{y}] =} ppplot (@var{x}, @var{dist}, @var{params})
+## Perform a PP-plot (probability plot).
+##
+## If F is the CDF of the distribution @var{dist} with parameters
+## @var{params} and @var{x} a sample vector of length @var{n}, the
+## PP-plot graphs ordinate @var{y}(@var{i}) = F (@var{i}-th largest
+## element of @var{x}) versus abscissa @var{p}(@var{i}) = (@var{i} -
+## 0.5)/@var{n}.  If the sample comes from F, the pairs will
+## approximately follow a straight line.
+##
+## The default for @var{dist} is the standard normal distribution.  The
+## optional argument @var{params} contains a list of parameters of
+## @var{dist}.  For example, for a probability plot of the uniform
+## distribution on [2,4] and @var{x}, use
+##
+## @example
+## ppplot (x, "uniform", 2, 4)
+## @end example
+##
+## @noindent
+## @var{dist} can be any string for which a function @var{dist_cdf}
+## that calculates the CDF of distribution @var{dist} exists.
+##
+## If no output arguments are given, the data are plotted directly.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Perform a PP-plot (probability plot)
+
+function [p, y] = ppplot (x, dist, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (! isvector (x))
+    error ("ppplot: x must be a vector");
+  endif
+
+  s = sort (x);
+  n = length (x);
+  p = ((1 : n)' - 0.5) / n;
+  if (nargin == 1)
+    F = @stdnormal_cdf;
+  else
+    F = str2func (sprintf ("%s_cdf", dist));
+  endif;
+  if (nargin <= 2)
+    y = feval (F, s);
+  else
+    y = feval (F, s, varargin{:});
+  endif
+
+  if (nargout == 0)
+    plot (p, y);
+    axis ([0, 1, 0, 1]);
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/prctile.m b/scripts/statistics/base/prctile.m
new file mode 100644
index 0000000..cc4a21b
--- /dev/null
+++ b/scripts/statistics/base/prctile.m
@@ -0,0 +1,156 @@
+## Copyright (C) 2008, 2009 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{y} =} prctile (@var{x}, @var{p})
+## @deftypefnx {Function File} {@var{q} =} prctile (@var{x}, @var{p}, @var{dim})
+## For a sample @var{x}, compute the quantiles, @var{y}, corresponding
+## to the cumulative probability values, P, in percent.  All non-numeric
+## values (NaNs) of X are ignored.
+## 
+## If @var{x} is a matrix, compute the percentiles for each column and
+## return them in a matrix, such that the i-th row of @var{y} contains the 
+## @var{p}(i)th percentiles of each column of @var{x}.
+## 
+## The optional argument @var{dim} determines the dimension along which
+## the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
+## a vector or matrix, it defaults to 1 (column wise quantiles).  In the 
+## instance that @var{x} is a N-d array, @var{dim} defaults to the first 
+## dimension whose size greater than unity.
+## 
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Description: Matlab style prctile function.
+
+function q = prctile (x, p, dim)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    p = 100*[0.00 0.25, 0.50, 0.75, 1.00];
+  endif
+
+  if (nargin < 3)
+    if (ndims (x) == 2)
+      ## If a matrix or vector, use the 1st dimension.
+      dim = 1;
+    else 
+      ## If an N-d array, use the firt dimension with a length > 1.
+      dim = find (size(v) != 1);
+      if (isempty (dim))
+        dim = 1;
+      endif
+    endif
+  endif
+
+  ## Convert from percent.
+  p = 0.01 * p;
+
+  ## The 5th method is compatible with Matlab.
+  method = 5;
+
+  ## Call the quantile function
+  q = quantile (x, p, dim, method);
+
+endfunction
+
+%!test
+%! pct = 50;
+%! q = prctile (1:4, pct, 1);
+%! qa = [1, 2, 3, 4];
+%! assert (q, qa);
+%! q = prctile (1:4, pct, 2);
+%! qa = 2.5000;
+%! assert (q, qa);
+
+%!test
+%! pct = 50;
+%! x = [0.1126, 0.1148, 0.0521, 0.2364, 0.1393
+%!      0.1718, 0.7273, 0.2041, 0.4531, 0.1585
+%!      0.2795, 0.7978, 0.3296, 0.5567, 0.7307
+%!      0.4288, 0.8753, 0.6477, 0.6287, 0.8165
+%!      0.9331, 0.9312, 0.9635, 0.7796, 0.8461];
+%! tol = 0.0001;
+%! q = prctile (x, pct, 1);
+%! qa = [0.2795, 0.7978, 0.3296, 0.5567, 0.7307];
+%! assert (q, qa, tol);
+%! q = prctile (x, pct, 2);
+%! qa = [0.1148; 0.2041; 0.5567; 0.6477; 0.9312];
+%! assert (q, qa, tol);
+
+%!test
+%! pct = 50;
+%! tol = 0.0001;
+%! x = [0.1126, 0.1148, 0.0521, 0.2364, 0.1393
+%!      0.1718, 0.7273, 0.2041, 0.4531, 0.1585
+%!      0.2795, 0.7978, 0.3296, 0.5567, 0.7307
+%!      0.4288, 0.8753, 0.6477, 0.6287, 0.8165
+%!      0.9331, 0.9312, 0.9635, 0.7796, 0.8461];
+%! x(5,5) = Inf;
+%! q = prctile (x, pct, 1);
+%! qa = [0.2795, 0.7978, 0.3296, 0.5567, 0.7307];
+%! assert (q, qa, tol);
+%! x(5,5) = -Inf;
+%! q = prctile (x, pct, 1);
+%! qa = [0.2795, 0.7978, 0.3296, 0.5567, 0.1585];
+%! assert (q, qa, tol);
+%! x(1,1) = Inf;
+%! q = prctile (x, pct, 1);
+%! qa = [0.4288, 0.7978, 0.3296, 0.5567, 0.1585];
+%! assert (q, qa, tol);
+
+%!test
+%! pct = 50;
+%! tol = 0.0001;
+%! x = [0.1126, 0.1148, 0.0521, 0.2364, 0.1393
+%!      0.1718, 0.7273, 0.2041, 0.4531, 0.1585
+%!      0.2795, 0.7978, 0.3296, 0.5567, 0.7307
+%!      0.4288, 0.8753, 0.6477, 0.6287, 0.8165
+%!      0.9331, 0.9312, 0.9635, 0.7796, 0.8461];
+%! x(3,3) = Inf;
+%! q = prctile (x, pct, 1);
+%! qa = [0.2795, 0.7978, 0.6477, 0.5567, 0.7307];
+%! assert (q, qa, tol);
+%! q = prctile (x, pct, 2);
+%! qa = [0.1148; 0.2041; 0.7307; 0.6477; 0.9312];
+%! assert (q, qa, tol);
+
+%!test
+%! pct = 50;
+%! tol = 0.0001;
+%! x = [0.1126, 0.1148, 0.0521, 0.2364, 0.1393
+%!      0.1718, 0.7273, 0.2041, 0.4531, 0.1585
+%!      0.2795, 0.7978, 0.3296, 0.5567, 0.7307
+%!      0.4288, 0.8753, 0.6477, 0.6287, 0.8165
+%!      0.9331, 0.9312, 0.9635, 0.7796, 0.8461];
+%! x(5,5) = NaN;
+%! q = prctile (x, pct, 2);
+%! qa = [0.1148; 0.2041; 0.5567; 0.6477; 0.9322];
+%! assert (q, qa, tol);
+%! x(1,1) = NaN;
+%! q = prctile (x, pct, 2);
+%! qa = [0.1270; 0.2041; 0.5567; 0.6477; 0.9322];
+%! assert (q, qa, tol);
+%! x(3,3) = NaN;
+%! q = prctile (x, pct, 2);
+%! qa = [0.1270; 0.2041; 0.6437; 0.6477; 0.9322];
+%! assert (q, qa, tol);
+
diff --git a/scripts/statistics/base/probit.m b/scripts/statistics/base/probit.m
new file mode 100644
index 0000000..ecf134e
--- /dev/null
+++ b/scripts/statistics/base/probit.m
@@ -0,0 +1,37 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} probit (@var{p})
+## For each component of @var{p}, return the probit (the quantile of the
+## standard normal distribution) of @var{p}.
+## @end deftypefn
+
+## Written by KH <Kurt.Hornik at wu-wien.ac.at> on 1995/02/04
+## Description: Probit transformation
+
+function y = probit (p)
+
+  if (nargin == 1)
+    y = stdnormal_inv (p);
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/qqplot.m b/scripts/statistics/base/qqplot.m
new file mode 100644
index 0000000..483308e
--- /dev/null
+++ b/scripts/statistics/base/qqplot.m
@@ -0,0 +1,90 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005,
+##               2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{q}, @var{s}] =} qqplot (@var{x}, @var{dist}, @var{params})
+## Perform a QQ-plot (quantile plot).
+##
+## If F is the CDF of the distribution @var{dist} with parameters
+## @var{params} and G its inverse, and @var{x} a sample vector of length
+## @var{n}, the QQ-plot graphs ordinate @var{s}(@var{i}) = @var{i}-th
+## largest element of x versus abscissa @var{q}(@var{i}f) = G((@var{i} -
+## 0.5)/@var{n}).
+##
+## If the sample comes from F except for a transformation of location
+## and scale, the pairs will approximately follow a straight line.
+##
+## The default for @var{dist} is the standard normal distribution.  The
+## optional argument @var{params} contains a list of parameters of
+## @var{dist}.  For example, for a quantile plot of the uniform
+## distribution on [2,4] and @var{x}, use
+##
+## @example
+## qqplot (x, "uniform", 2, 4)
+## @end example
+##
+## @noindent
+## @var{dist} can be any string for which a function @var{dist_inv}
+## that calculates the inverse CDF of distribution @var{dist} exists.
+##
+## If no output arguments are given, the data are plotted directly.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Perform a QQ-plot (quantile plot)
+
+function [q, s] = qqplot (x, dist, varargin)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (! (isvector(x)))
+    error ("qqplot: x must be a vector");
+  endif
+
+  s = sort (x);
+  n = length (x);
+  t = ((1 : n)' - .5) / n;
+  if (nargin == 1)
+    f = @stdnormal_inv;
+  else
+    f = str2func (sprintf ("%s_inv", dist));
+  endif;
+  if (nargin <= 2)
+    q = feval (f, t);
+    q_label = func2str (f);
+  else
+    q = feval (f, t, varargin{:});
+    if (nargin > 3)
+      tmp = sprintf (", %g", varargin{2:end});
+    else 
+      tmp = "";
+    endif
+    q_label = sprintf ("%s with parameter(s) %g%s", func2str (f),
+		       varargin{1}, tmp);
+  endif
+
+  if (nargout == 0)
+    plot (q, s);
+    xlabel (q_label);
+    ylabel ("sample points");
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/quantile.m b/scripts/statistics/base/quantile.m
new file mode 100644
index 0000000..c3cacfc
--- /dev/null
+++ b/scripts/statistics/base/quantile.m
@@ -0,0 +1,267 @@
+## Copyright (C) 2008, 2009 Ben Abbott
+## 
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{q} =} quantile (@var{x}, @var{p})
+## @deftypefnx {Function File} {@var{q} =} quantile (@var{x}, @var{p}, @var{dim})
+## @deftypefnx {Function File} {@var{q} =} quantile (@var{x}, @var{p}, @var{dim}, @var{method})
+## For a sample, @var{x}, calculate the quantiles, @var{q}, corresponding to
+## the cumulative probability values in @var{p}.  All non-numeric values (NaNs) of
+## @var{x} are ignored.
+##
+## If @var{x} is a matrix, compute the quantiles for each column and
+## return them in a matrix, such that the i-th row of @var{q} contains
+## the @var{p}(i)th quantiles of each column of @var{x}.
+## 
+## The optional argument @var{dim} determines the dimension along which 
+## the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
+## a vector or matrix, it defaults to 1 (column wise quantiles).  In the 
+## instance that @var{x} is a N-d array, @var{dim} defaults to the first 
+## dimension whose size greater than unity.
+## 
+## The methods available to calculate sample quantiles are the nine methods
+## used by R (http://www.r-project.org/).  The default value is METHOD = 5.
+## 
+## Discontinuous sample quantile methods 1, 2, and 3
+## 
+## @enumerate 1
+## @item Method 1: Inverse of empirical distribution function.
+## @item Method 2: Similar to method 1 but with averaging at discontinuities.
+## @item Method 3: SAS definition: nearest even order statistic.
+## @end enumerate
+## 
+## Continuous sample quantile methods 4 through 9, where p(k) is the linear
+## interpolation function respecting each methods' representative cdf.
+## 
+## @enumerate 4
+## @item Method 4: p(k) = k / n. That is, linear interpolation of the empirical cdf.
+## @item Method 5: p(k) = (k - 0.5) / n. That is a piecewise linear function where 
+## the knots are the values midway through the steps of the empirical cdf. 
+## @item Method 6: p(k) = k / (n + 1).
+## @item Method 7: p(k) = (k - 1) / (n - 1).
+## @item Method 8: p(k) = (k - 1/3) / (n + 1/3).  The resulting quantile estimates 
+## are approximately median-unbiased regardless of the distribution of @var{x}.
+## @item Method 9: p(k) = (k - 3/8) / (n + 1/4).  The resulting quantile estimates 
+## are approximately unbiased for the expected order statistics if @var{x} is 
+## normally distributed.
+## @end enumerate
+## 
+## Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R
+## (versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS
+## use method 6.  @sc{matlab} uses method 5.
+## 
+## References:
+## 
+## @itemize @bullet
+## @item Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New
+## S Language.  Wadsworth & Brooks/Cole.
+##
+## @item Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in
+## statistical packages, American Statistician, 50, 361--365.
+##
+## @item R: A Language and Environment for Statistical Computing;
+## @url{http://cran.r-project.org/doc/manuals/fullrefman.pdf}.
+## @end itemize
+## @end deftypefn
+
+## Author: Ben Abbott <bpabbott at mac.com>
+## Description: Matlab style quantile function of a discrete/continuous distribution
+
+function q = quantile (x, p, dim, method)
+
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    p = [0.00 0.25, 0.50, 0.75, 1.00];
+  endif
+
+  if (nargin < 3)
+    dim = 1;
+  endif
+
+  if (nargin < 4)
+    method = 5;
+  endif
+
+  if (dim > ndims(x))
+    error ("quantile: invalid dimension");
+  endif
+
+  ## Set the permutation vector.
+  perm = 1:ndims(x);
+  perm(1) = dim;
+  perm(dim) = 1;
+
+  ## Permute dim to the 1st index.
+  x = permute (x, perm);
+
+  ## Save the size of the permuted x N-d array.
+  sx = size (x);
+
+  ## Reshape to a 2-d array.
+  x = reshape (x, [sx(1), prod(sx(2:end))]);
+
+  ## Calculate the quantiles.
+  q = __quantile__ (x, p, method);
+
+  ## Return the shape to the original N-d array.
+  q = reshape (q, [numel(p), sx(2:end)]);
+
+  ## Permute the 1st index back to dim.
+  q = ipermute (q, perm);
+
+endfunction
+
+%!test
+%! p = 0.5;
+%! x = sort (rand (11));
+%! q = quantile (x, p);
+%! assert (q, x(6,:))
+%! x = x.';
+%! q = quantile (x, p, 2);
+%! assert (q, x(:,6));
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 3; 4];
+%! a = [1.0000   1.0000   2.0000   3.0000   4.0000
+%!      1.0000   1.5000   2.5000   3.5000   4.0000
+%!      1.0000   1.0000   2.0000   3.0000   4.0000
+%!      1.0000   1.0000   2.0000   3.0000   4.0000
+%!      1.0000   1.5000   2.5000   3.5000   4.0000
+%!      1.0000   1.2500   2.5000   3.7500   4.0000
+%!      1.0000   1.7500   2.5000   3.2500   4.0000
+%!      1.0000   1.4167   2.5000   3.5833   4.0000
+%!      1.0000   1.4375   2.5000   3.5625   4.0000];
+%! for m = (1:9)
+%!   q = quantile (x, p, 1, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 3; 4; 5];
+%! a = [1.0000   2.0000   3.0000   4.0000   5.0000
+%!      1.0000   2.0000   3.0000   4.0000   5.0000
+%!      1.0000   1.0000   2.0000   4.0000   5.0000
+%!      1.0000   1.2500   2.5000   3.7500   5.0000
+%!      1.0000   1.7500   3.0000   4.2500   5.0000
+%!      1.0000   1.5000   3.0000   4.5000   5.0000
+%!      1.0000   2.0000   3.0000   4.0000   5.0000
+%!      1.0000   1.6667   3.0000   4.3333   5.0000
+%!      1.0000   1.6875   3.0000   4.3125   5.0000];
+%! for m = (1:9)
+%!   q = quantile (x, p, 1, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 5; 9];
+%! a = [1.0000   1.0000   2.0000   5.0000   9.0000
+%!      1.0000   1.5000   3.5000   7.0000   9.0000
+%!      1.0000   1.0000   2.0000   5.0000   9.0000
+%!      1.0000   1.0000   2.0000   5.0000   9.0000
+%!      1.0000   1.5000   3.5000   7.0000   9.0000
+%!      1.0000   1.2500   3.5000   8.0000   9.0000
+%!      1.0000   1.7500   3.5000   6.0000   9.0000
+%!      1.0000   1.4167   3.5000   7.3333   9.0000
+%!      1.0000   1.4375   3.5000   7.2500   9.0000];
+%! for m = (1:9)
+%!   q = quantile (x, p, 1, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [1; 2; 5; 9; 11];
+%! a = [1.0000    2.0000    5.0000    9.0000   11.0000
+%!      1.0000    2.0000    5.0000    9.0000   11.0000
+%!      1.0000    1.0000    2.0000    9.0000   11.0000
+%!      1.0000    1.2500    3.5000    8.0000   11.0000
+%!      1.0000    1.7500    5.0000    9.5000   11.0000
+%!      1.0000    1.5000    5.0000   10.0000   11.0000
+%!      1.0000    2.0000    5.0000    9.0000   11.0000
+%!      1.0000    1.6667    5.0000    9.6667   11.0000
+%!      1.0000    1.6875    5.0000    9.6250   11.0000];
+%! for m = (1:9)
+%!   q = quantile (x, p, 1, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [16; 11; 15; 12; 15;  8; 11; 12;  6; 10];
+%! a = [6.0000   10.0000   11.0000   15.0000   16.0000
+%!      6.0000   10.0000   11.5000   15.0000   16.0000
+%!      6.0000    8.0000   11.0000   15.0000   16.0000
+%!      6.0000    9.0000   11.0000   13.5000   16.0000
+%!      6.0000   10.0000   11.5000   15.0000   16.0000
+%!      6.0000    9.5000   11.5000   15.0000   16.0000
+%!      6.0000   10.2500   11.5000   14.2500   16.0000
+%!      6.0000    9.8333   11.5000   15.0000   16.0000
+%!      6.0000    9.8750   11.5000   15.0000   16.0000];
+%! for m = (1:9)
+%!   q = quantile (x, p, 1, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = [0.00, 0.25, 0.50, 0.75, 1.00];
+%! x = [-0.58851;  0.40048;  0.49527; -2.551500; -0.52057; ...
+%!      -0.17841; 0.057322; -0.62523;  0.042906;  0.12337];
+%! a = [-2.551474  -0.588505  -0.178409   0.123366   0.495271
+%!      -2.551474  -0.588505  -0.067751   0.123366   0.495271
+%!      -2.551474  -0.625231  -0.178409   0.123366   0.495271
+%!      -2.551474  -0.606868  -0.178409   0.090344   0.495271
+%!      -2.551474  -0.588505  -0.067751   0.123366   0.495271
+%!      -2.551474  -0.597687  -0.067751   0.192645   0.495271
+%!      -2.551474  -0.571522  -0.067751   0.106855   0.495271
+%!      -2.551474  -0.591566  -0.067751   0.146459   0.495271
+%!      -2.551474  -0.590801  -0.067751   0.140686   0.495271];
+%! for m = (1:9)
+%!   q = quantile (x, p, 1, m).';
+%!   assert (q, a(m,:), 0.0001)
+%! endfor
+
+%!test
+%! p = 0.5;
+%! x = [0.112600, 0.114800, 0.052100, 0.236400, 0.139300
+%!      0.171800, 0.727300, 0.204100, 0.453100, 0.158500
+%!      0.279500, 0.797800, 0.329600, 0.556700, 0.730700
+%!      0.428800, 0.875300, 0.647700, 0.628700, 0.816500
+%!      0.933100, 0.931200, 0.963500, 0.779600, 0.846100];
+%! tol = 0.00001;
+%! x(5,5) = NaN;
+%! assert (quantile(x, p, 1), [0.27950, 0.79780, 0.32960, 0.55670, 0.44460], tol);
+%! x(1,1) = NaN;
+%! assert (quantile(x, p, 1), [0.35415, 0.79780, 0.32960, 0.55670, 0.44460], tol);
+%! x(3,3) = NaN;
+%! assert (quantile(x, p, 1), [0.35415, 0.79780, 0.42590, 0.55670, 0.44460], tol);
+
+%!test
+%! sx = [2, 3, 4];
+%! x = rand (sx);
+%! dim = 2;
+%! p = 0.5;
+%! yobs = quantile (x, p, dim);
+%! yexp = median (x, dim);
+%! assert (yobs, yexp);
+
diff --git a/scripts/statistics/base/range.m b/scripts/statistics/base/range.m
new file mode 100644
index 0000000..125ea75
--- /dev/null
+++ b/scripts/statistics/base/range.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+## Copyright (C) 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} range (@var{x})
+## @deftypefnx {Function File} {} range (@var{x}, @var{dim})
+## If @var{x} is a vector, return the range, i.e., the difference
+## between the maximum and the minimum, of the input data.
+##
+## If @var{x} is a matrix, do the above for each column of @var{x}.
+##
+## If the optional argument @var{dim} is supplied, work along dimension
+## @var{dim}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute range
+
+function y = range (x, dim)
+
+  if (nargin == 1)
+    y = max (x) - min (x);
+  elseif (nargin == 2)
+    y = max (x, [], dim) - min (x, [], dim);
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/ranks.m b/scripts/statistics/base/ranks.m
new file mode 100644
index 0000000..2f4d717
--- /dev/null
+++ b/scripts/statistics/base/ranks.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ranks (@var{x}, @var{dim})
+## Return the ranks of @var{x} along the first non-singleton dimension
+## adjust for ties.  If the optional argument @var{dim} is
+## given, operate along this dimension.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute ranks
+
+## This code was rather ugly, since it didn't use sort due to the
+## fact of how to deal with ties. Now it does use sort and its
+## even uglier!!! At least it handles NDArrays..
+
+function y = ranks (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("ranks: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (sz(dim) == 1)
+    y = ones(sz);
+  else
+    ## The algorithm works only on dim = 1, so permute if necesary.
+    if (dim != 1)
+      perm = [1 : nd];
+      perm(1) = dim;
+      perm(dim) = 1;
+      x = permute (x, perm);
+    endif
+    sz = size (x);
+    infvec = -Inf * ones ([1, sz(2 : end)]);
+    [xs, xi] = sort (x);
+    eq_el = find (diff ([xs; infvec]) == 0);
+    if (isempty (eq_el))
+      [eq_el, y] = sort (xi);
+    else
+      runs = complement (eq_el+1, eq_el);
+      len = diff (find (diff ([Inf; eq_el; -Inf]) != 1)) + 1;
+      [eq_el, y] = sort (xi);
+      for i = 1 : length(runs)
+	y (xi (runs (i) + [0:(len(i)-1)]) + floor (runs (i) ./ sz(1)) 
+	   * sz(1)) = eq_el(runs(i)) + (len(i) - 1) / 2;
+      endfor
+    endif  
+    if (dim != 1)
+      y = permute (y, perm);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/run_count.m b/scripts/statistics/base/run_count.m
new file mode 100644
index 0000000..6234202
--- /dev/null
+++ b/scripts/statistics/base/run_count.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} run_count (@var{x}, @var{n})
+## Count the upward runs along the first non-singleton dimension of
+## @var{x} of length 1, 2, @dots{}, @var{n}-1 and greater than or equal 
+## to @var{n}.  If the optional argument @var{dim} is given operate
+## along this dimension
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Count upward runs
+
+function retval = run_count (x, n, dim)
+
+  if (nargin != 2 && nargin != 3)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin != 3)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("run_count: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (! (isscalar (n) && n == round (n)) && n > 0)
+    error ("run_count: n must be a positive integer");
+  endif
+  
+  nd = ndims (x);
+  if (dim != 1)
+    perm = [1 : nd];
+    perm(1) = dim;
+    perm(dim) = 1;
+    x = permute (x, perm);
+  endif
+
+  sz = size (x);
+  idx = cell ();
+  for i = 1 : nd
+    idx{i} = 1 : sz(i);
+  endfor
+  c = sz(1); 
+  tmp = zeros ([c + 1, sz(2 : end)]);
+  infvec = Inf * ones ([1, sz(2 : end)]);
+
+  ind = find (diff ([infvec; x; -infvec]) < 0);
+  tmp(ind(2:end) - 1) = diff(ind);
+  tmp = tmp(idx{:});
+
+  sz(1) = n;
+  retval = zeros (sz);
+  for k = 1 : (n-1)
+    idx{1} = k;
+    retval(idx{:}) = sum (tmp == k);
+  endfor
+  idx{1} = n;
+  retval (idx{:}) = sum (tmp >= n);
+
+  if (dim != 1)
+    retval = ipermute (retval, perm);
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/skewness.m b/scripts/statistics/base/skewness.m
new file mode 100644
index 0000000..7239de6
--- /dev/null
+++ b/scripts/statistics/base/skewness.m
@@ -0,0 +1,91 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} skewness (@var{x}, @var{dim})
+## If @var{x} is a vector of length @math{n}, return the skewness
+## @tex
+## $$
+## {\rm skewness} (x) = {1\over N \sigma(x)^3} \sum_{i=1}^N (x_i-\bar{x})^3
+## $$
+## where $\bar{x}$ is the mean value of $x$.
+## @end tex
+## @ifnottex
+##
+## @example
+## skewness (x) = N^(-1) std(x)^(-3) sum ((x - mean(x)).^3)
+## @end example
+## @end ifnottex
+##
+## @noindent
+## of @var{x}.  If @var{x} is a matrix, return the skewness along the
+## first non-singleton dimension of the matrix.  If the optional
+## @var{dim} argument is given, operate along this dimension.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Created: 29 July 1994
+## Adapted-By: jwe
+
+function retval = skewness (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("skewness: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (! ismatrix (x))
+    error ("skewness: x has to be a matrix or a vector");
+  endif
+
+  c = sz(dim);
+  idx = ones (1, nd);
+  idx (dim) = c;
+  x = x - repmat (mean (x, dim), idx);
+  sz(dim) = 1;
+  retval = zeros (sz);
+  s = std (x, [], dim);
+  ind = find (s > 0);
+  x = sum (x .^ 3, dim);
+  retval(ind) = x(ind) ./ (c * s(ind) .^ 3);
+  
+endfunction
+
+%!error skewness ();
+
+%!error skewness (1, 2, 3);
+
diff --git a/scripts/statistics/base/spearman.m b/scripts/statistics/base/spearman.m
new file mode 100644
index 0000000..1843d96
--- /dev/null
+++ b/scripts/statistics/base/spearman.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} spearman (@var{x}, @var{y})
+## Compute Spearman's rank correlation coefficient @var{rho} for each of
+## the variables specified by the input arguments.
+##
+## For matrices, each row is an observation and each column a variable;
+## vectors are always observations and may be row or column vectors.
+##
+## @code{spearman (@var{x})} is equivalent to @code{spearman (@var{x},
+## @var{x})}.
+##
+## For two data vectors @var{x} and @var{y}, Spearman's @var{rho} is the
+## correlation of the ranks of @var{x} and @var{y}.
+##
+## If @var{x} and @var{y} are drawn from independent distributions,
+## @var{rho} has zero mean and variance @code{1 / (n - 1)}, and is
+## asymptotically normally distributed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Spearman's rank correlation rho
+
+function rho = spearman (x, y)
+
+  if ((nargin < 1) || (nargin > 2))
+    print_usage ();
+  endif
+
+  if (rows (x) == 1)
+    x = x';
+  endif
+  n = rows (x);
+
+  if (nargin == 1)
+    rho = cor (ranks (x));
+  else
+    if (rows (y) == 1)
+      y = y';
+    endif
+    if (rows (y) != n)
+      error ("spearman: x and y must have the same number of observations");
+    endif
+    rho = cor (ranks (x), ranks (y));
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/statistics.m b/scripts/statistics/base/statistics.m
new file mode 100644
index 0000000..2f68138
--- /dev/null
+++ b/scripts/statistics/base/statistics.m
@@ -0,0 +1,74 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} statistics (@var{x})
+## If @var{x} is a matrix, return a matrix with the minimum, first
+## quartile, median, third quartile, maximum, mean, standard deviation,
+## skewness and kurtosis of the columns of @var{x} as its columns.
+##
+## If @var{x} is a vector, calculate the statistics along the 
+## non-singleton dimension.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute basic statistics
+
+function S = statistics (X, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (X);
+  sz = size (X);
+  nel = numel (X);
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("statistics: dim must be an integer and valid dimension");
+    endif
+  endif
+  
+  if (! ismatrix (X) || sz(dim) < 2)
+    error ("statistics: invalid argument");
+  endif    
+
+  emp_inv = quantile (X, [0.25; 0.5; 0.75], dim, 7);
+
+  S = cat (dim, min (X, [], dim), emp_inv, max (X, [], dim), mean (X, dim),
+	   std (X, [], dim), skewness (X, dim), kurtosis (X, dim));
+
+endfunction
+
+%!test
+%! x = rand(7,5);
+%! s = statistics (x);
+%! m = median (x);
+%! assert (m, s(3,:), eps);
diff --git a/scripts/statistics/base/std.m b/scripts/statistics/base/std.m
new file mode 100644
index 0000000..360e6e2
--- /dev/null
+++ b/scripts/statistics/base/std.m
@@ -0,0 +1,97 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2006, 2007, 2008,
+##               2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} std (@var{x})
+## @deftypefnx {Function File} {} std (@var{x}, @var{opt})
+## @deftypefnx {Function File} {} std (@var{x}, @var{opt}, @var{dim})
+## If @var{x} is a vector, compute the standard deviation of the elements
+## of @var{x}.
+## @tex
+## $$
+## {\rm std} (x) = \sigma (x) = \sqrt{{\sum_{i=1}^N (x_i - \bar{x})^2 \over N - 1}}
+## $$
+## where $\bar{x}$ is the mean value of $x$.
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+## std (x) = sqrt (sumsq (x - mean (x)) / (n - 1))
+## @end group
+## @end example
+## @end ifnottex
+## If @var{x} is a matrix, compute the standard deviation for
+## each column and return them in a row vector.
+##
+## The argument @var{opt} determines the type of normalization to use.  Valid values
+## are
+##
+## @table @asis 
+## @item 0:
+##   normalizes with @math{N-1}, provides the square root of best unbiased estimator of 
+##   the variance [default]
+## @item 1:
+##   normalizes with @math{N}, this provides the square root of the second moment around 
+##   the mean
+## @end table
+##
+## The third argument @var{dim} determines the dimension along which the standard
+## deviation is calculated.
+## @seealso{mean, median}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = std (a, opt, dim)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+  if (nargin < 3)
+    dim = find (size (a) > 1, 1);
+    if (isempty (dim))
+      dim = 1;
+    endif
+  endif
+  if (nargin < 2 || isempty (opt))
+    opt = 0;
+  endif
+
+  n = size (a, dim);
+  if (n == 1)
+    retval = zeros (size (a));
+  elseif (numel (a) > 0)
+    retval = sqrt (sumsq (center (a, dim), dim) / (n + opt - 1));
+  else
+    error ("std: x must not be empty");
+  endif
+
+endfunction
+
+%!test
+%! x = ones (10, 2);
+%! y = [1, 3];
+%! assert(std (x) == [0, 0] && abs (std (y) - sqrt (2)) < sqrt (eps));
+%! assert (std (x, 0, 3), zeros (10, 2))
+%! assert (std (ones (3, 1, 2), 0, 2), zeros (3, 1, 2))
+
+%!error std ();
+
+%!error std (1, 2, 3, 4);
diff --git a/scripts/statistics/base/studentize.m b/scripts/statistics/base/studentize.m
new file mode 100644
index 0000000..ad05638
--- /dev/null
+++ b/scripts/statistics/base/studentize.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005,
+##               2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} studentize (@var{x}, @var{dim})
+## If @var{x} is a vector, subtract its mean and divide by its standard
+## deviation.
+##
+## If @var{x} is a matrix, do the above along the first non-singleton
+## dimension.  If the optional argument @var{dim} is given then operate
+## along this dimension.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Subtract mean and divide by standard deviation
+
+function t = studentize (x, dim)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin != 2)
+    ## Find the first non-singleton dimension.
+    dim  = 1;
+    while (dim < nd + 1 && sz(dim) == 1)
+      dim = dim + 1;
+    endwhile
+    if (dim > nd)
+      dim = 1;
+    endif
+  else
+    if (! (isscalar (dim) && dim == round (dim))
+	&& dim > 0
+	&& dim < (nd + 1))
+      error ("studentize: dim must be an integer and valid dimension");
+    endif
+  endif
+
+  if (! ismatrix (x))
+    error ("studentize: x must be a vector or a matrix");
+  endif
+
+  c = sz(dim);
+  idx = ones (1, nd);
+  idx(dim) = c;
+  t = x - repmat (mean (x, dim), idx);
+  t = t ./ repmat (max (cat (dim, std(t, [], dim), ! any (t, dim)), [], dim), idx);
+
+endfunction
diff --git a/scripts/statistics/base/table.m b/scripts/statistics/base/table.m
new file mode 100644
index 0000000..848fa9c
--- /dev/null
+++ b/scripts/statistics/base/table.m
@@ -0,0 +1,58 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{t}, @var{l_x}] =} table (@var{x})
+## @deftypefnx {Function File} {[@var{t}, @var{l_x}, @var{l_y}] =} table (@var{x}, @var{y})
+## Create a contingency table @var{t} from data vectors.  The @var{l}
+## vectors are the corresponding levels.
+##
+## Currently, only 1- and 2-dimensional tables are supported.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Cross tabulation
+
+function [t, v, w] = table (x, y)
+
+  if (nargin == 1)
+    if (! (isvector (x)))
+      error ("table: x must be a vector");
+    endif
+    v = values (x);
+    for i = 1 : length (v)
+      t(i) = sum (x == v(i) | isnan (v(i)) * isnan (x));
+    endfor
+  elseif (nargin == 2)
+    if (! (isvector (x) && isvector (y) && (length (x) == length (y))))
+      error ("table: x and y must be vectors of the same length");
+    endif
+    v = values (x);
+    w = values (y);
+    for i = 1 : length (v)
+      for j = 1 : length (w)
+        t(i,j) = sum ((x == v(i) | isnan (v(i)) * isnan (x)) &
+                      (y == w(j) | isnan (w(j)) * isnan (y)));
+      endfor
+    endfor
+  else
+    print_usage ();
+  endif
+
+endfunction
\ No newline at end of file
diff --git a/scripts/statistics/base/values.m b/scripts/statistics/base/values.m
new file mode 100644
index 0000000..eb241aa
--- /dev/null
+++ b/scripts/statistics/base/values.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} values (@var{x})
+## Return the different values in a column vector, arranged in ascending
+## order.
+##
+## As an example, @code{values([1, 2, 3, 1])} returns the vector
+## @code{[1, 2, 3]}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Extract unique elements
+
+function v = values (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (isvector (x)))
+    error ("values: x must be a vector");
+  endif
+
+  i = any (isnan (x));
+  ## HACK!
+  x = x(find(!isnan (x)));
+  n = length (x);
+  x = reshape (x, n, 1);
+  s = sort (x);
+  v = s([1; (find (s(2:n) > s(1:n-1)) + 1)]);
+  if (i)
+    v = [v; NaN];
+  endif
+
+endfunction
diff --git a/scripts/statistics/base/var.m b/scripts/statistics/base/var.m
new file mode 100644
index 0000000..fea263d
--- /dev/null
+++ b/scripts/statistics/base/var.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} var (@var{x})
+## For vector arguments, return the (real) variance of the values.
+## For matrix arguments, return a row vector containing the variance for
+## each column.
+##
+## The argument @var{opt} determines the type of normalization to use.
+## Valid values are
+##
+## @table @asis 
+## @item 0:
+## Normalizes with @math{N-1}, provides the best unbiased estimator of the
+## variance [default].
+## @item 1:
+## Normalizes with @math{N}, this provides the second moment around the mean.
+## @end table
+##
+## The third argument @var{dim} determines the dimension along which the 
+## variance is calculated.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compute variance
+
+function retval = var (x, opt, dim)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+  if (nargin < 3)
+    dim = find (size (x) > 1, 1);
+    if (isempty (dim))
+      dim = 1;
+    endif
+  endif
+  if (nargin < 2 || isempty (opt))
+    opt = 0;
+  endif
+
+  sz = size (x);
+  n = sz(dim);
+  if (isempty (x))
+    ## FIXME -- is there a way to obtain these results without all the
+    ## special cases?
+    if (ndims (x) == 2 && sz(1) == 0 && sz(2) == 0)
+      retval = NaN;
+    else
+      sz(dim) = 1;
+      if (n == 0)
+	if (prod (sz) == 0)
+	  retval = zeros (sz);
+	else
+	  retval = NaN (sz);
+	endif
+      else
+	retval = zeros (sz);
+      endif
+    endif
+  elseif (n == 1)
+    retval = zeros (sz);
+  else
+    retval = sumsq (center (x, dim), dim) / (n + opt - 1);
+  endif
+
+endfunction
+
+%!assert (var (13), 0)
+%!assert (var ([]), NaN)
+%!assert (var (ones (0, 0, 0), 0, 1), zeros (1, 0, 0))
+%!assert (var (ones (0, 0, 0), 0, 2), zeros (0, 1, 0))
+%!assert (var (ones (0, 0, 0), 0, 3), zeros (0, 0))
+%!assert (var (ones (1, 2, 0)), zeros (1, 1, 0))
+%!assert (var (ones (1, 2, 0, 0), 0, 1), zeros (1, 2, 0, 0))
+%!assert (var (ones (1, 2, 0, 0), 0, 2), zeros (1, 1, 0, 0))
+%!assert (var (ones (1, 2, 0, 0), 0, 3), zeros (1, 2, 1, 0))
diff --git a/scripts/statistics/distributions/Makefile.in b/scripts/statistics/distributions/Makefile.in
new file mode 100644
index 0000000..8bee865
--- /dev/null
+++ b/scripts/statistics/distributions/Makefile.in
@@ -0,0 +1,100 @@
+# Makefile for octave's scripts/statistics/distributions directory
+#
+# Copyright (C) 1998, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../../..
+
+script_sub_dir = statistics/distributions
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = betacdf.m betainv.m betapdf.m betarnd.m binocdf.m \
+  binoinv.m binopdf.m binornd.m cauchy_cdf.m cauchy_inv.m \
+  cauchy_pdf.m cauchy_rnd.m chi2cdf.m chi2inv.m chi2pdf.m \
+  chi2rnd.m discrete_cdf.m discrete_inv.m discrete_pdf.m \
+  discrete_rnd.m empirical_cdf.m empirical_inv.m empirical_pdf.m \
+  empirical_rnd.m expcdf.m expinv.m exppdf.m exprnd.m fcdf.m \
+  finv.m fpdf.m frnd.m gamcdf.m gaminv.m gampdf.m gamrnd.m \
+  geocdf.m geoinv.m geopdf.m geornd.m hygecdf.m hygeinv.m \
+  hygepdf.m hygernd.m kolmogorov_smirnov_cdf.m laplace_cdf.m \
+  laplace_inv.m laplace_pdf.m laplace_rnd.m logistic_cdf.m \
+  logistic_inv.m logistic_pdf.m logistic_rnd.m logncdf.m \
+  logninv.m lognpdf.m lognrnd.m nbincdf.m nbininv.m nbinpdf.m \
+  nbinrnd.m normcdf.m norminv.m normpdf.m normrnd.m \
+  poisscdf.m poissinv.m poisspdf.m poissrnd.m stdnormal_cdf.m \
+  stdnormal_inv.m stdnormal_pdf.m stdnormal_rnd.m tcdf.m tinv.m \
+  tpdf.m trnd.m unidrnd.m unidcdf.m unidinv.m unidpdf.m unifrnd.m \
+  unifcdf.m unifinv.m unifpdf.m wblcdf.m wblinv.m wblpdf.m wblrnd.m \
+  wienrnd.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../../`cat ../../../.fname`/scripts/$(script_sub_dir)
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/statistics/distributions/betacdf.m b/scripts/statistics/distributions/betacdf.m
new file mode 100644
index 0000000..c0a8df3
--- /dev/null
+++ b/scripts/statistics/distributions/betacdf.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} betacdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, returns the CDF at @var{x} of the beta
+## distribution with parameters @var{a} and @var{b}, i.e.,
+## PROB (beta (@var{a}, @var{b}) <= @var{x}).
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Beta distribution
+
+function cdf = betacdf (x, a, b)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("betacdf: x, a and b must be of common size or scalar");
+    endif
+  endif
+
+  sz = size(x);
+  cdf = zeros (sz);
+
+  k = find (!(a > 0) | !(b > 0) | isnan (x));
+  if (any (k))
+    cdf (k) = NaN;
+  endif
+
+  k = find ((x >= 1) & (a > 0) & (b > 0));
+  if (any (k))
+    cdf (k) = 1;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (a > 0) & (b > 0));
+  if (any (k))
+    if (isscalar (a) && isscalar(b))
+      cdf (k) = betainc (x(k), a, b);
+    else
+      cdf (k) = betainc (x(k), a(k), b(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/betainv.m b/scripts/statistics/distributions/betainv.m
new file mode 100644
index 0000000..14ceabc
--- /dev/null
+++ b/scripts/statistics/distributions/betainv.m
@@ -0,0 +1,103 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} betainv (@var{x}, @var{a}, @var{b})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the Beta distribution with parameters @var{a}
+## and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Beta distribution
+
+function inv = betainv (x, a, b)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("betainv: x, a and b must be of common size or scalars");
+    endif
+  endif
+  
+  sz = size (x);
+  inv = zeros (sz);
+
+  k = find ((x < 0) | (x > 1) | !(a > 0) | !(b > 0) | isnan (x));
+  if (any (k))
+    inv (k) = NaN;
+  endif
+
+  k = find ((x == 1) & (a > 0) & (b > 0));
+  if (any (k))
+    inv (k) = 1;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (a > 0) & (b > 0));
+  if (any (k))
+    if (!isscalar(a) || !isscalar(b))
+      a = a (k);
+      b = b (k);
+      y = a ./ (a + b);
+    else
+      y = a / (a + b) * ones (size (k));
+    endif
+    x = x (k);
+
+    if (isa (y, "single"))
+      myeps = eps ("single");
+    else
+      myeps = eps;
+    endif
+
+    l = find (y < myeps);
+    if (any (l))
+      y(l) = sqrt (myeps) * ones (length (l), 1);
+    endif
+    l = find (y > 1 - myeps);
+    if (any (l))
+      y(l) = 1 - sqrt (myeps) * ones (length (l), 1);
+    endif
+
+    y_old = y;
+    for i = 1 : 10000
+      h     = (betacdf (y_old, a, b) - x) ./ betapdf (y_old, a, b);
+      y_new = y_old - h;
+      ind   = find (y_new <= myeps);
+      if (any (ind))
+        y_new (ind) = y_old (ind) / 10;
+      endif
+      ind = find (y_new >= 1 - myeps);
+      if (any (ind))
+        y_new (ind) = 1 - (1 - y_old (ind)) / 10;
+      endif
+      h = y_old - y_new;
+      if (max (abs (h)) < sqrt (myeps))
+        break;
+      endif
+      y_old = y_new;
+    endfor
+
+    inv (k) = y_new;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/betapdf.m b/scripts/statistics/distributions/betapdf.m
new file mode 100644
index 0000000..c928e5b
--- /dev/null
+++ b/scripts/statistics/distributions/betapdf.m
@@ -0,0 +1,60 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} betapdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, returns the PDF at @var{x} of the beta
+## distribution with parameters @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Beta distribution
+
+function pdf = betapdf (x, a, b)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+  
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("betapdf: x, a and b must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  pdf = zeros (sz);
+
+  k = find (!(a > 0) | !(b > 0) | isnan (x));
+  if (any (k))
+    pdf (k) = NaN;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (a > 0) & (b > 0));
+  if (any (k))
+    if (isscalar(a) && isscalar(b))
+      pdf(k) = exp ((a - 1) .* log (x(k))
+		    + (b - 1) .* log (1 - x(k))) ./ beta (a, b);
+    else
+      pdf(k) = exp ((a(k) - 1) .* log (x(k))
+		    + (b(k) - 1) .* log (1 - x(k))) ./ beta (a(k), b(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/betarnd.m b/scripts/statistics/distributions/betarnd.m
new file mode 100644
index 0000000..be9adc1
--- /dev/null
+++ b/scripts/statistics/distributions/betarnd.m
@@ -0,0 +1,99 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} betarnd (@var{a}, @var{b}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} betarnd (@var{a}, @var{b}, @var{sz})
+## Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+## random samples from the Beta distribution with parameters @var{a} and
+## @var{b}.  Both @var{a} and @var{b} must be scalar or of size @var{r}
+##  by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Beta distribution
+
+function rnd = betarnd (a, b, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(a) || !isscalar(b)) 
+      [retval, a, b] = common_size (a, b);
+      if (retval > 0)
+	error ("betarnd: a and b must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("betarnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("betarnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (a) != 1)
+	&& (length (size (a)) != length (sz) || any (size (a) != sz)))
+      error ("betarnd: a and b must be scalar or of size [r,c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("betarnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (a) != 1)
+	&& (length (size (a)) != length (sz) || any (size (a) != sz)))
+      error ("betarnd: a and b must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(a);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar(a) && isscalar(b))
+    if (find (!(a > 0) | !(a < Inf) | !(b > 0) | !(b < Inf)))
+      rnd = NaN * ones (sz);
+    else
+      r1 = randg(a,sz); 
+      rnd = r1 ./ (r1 + randg(b,sz));
+    endif
+  else
+    rnd = zeros (sz);
+
+    k = find (!(a > 0) | !(a < Inf) | !(b > 0) | !(b < Inf));
+    if (any (k))
+      rnd(k) = NaN * ones (size (k));
+    endif
+
+    k = find ((a > 0) & (a < Inf) & (b > 0) & (b < Inf));
+    if (any (k))
+      r1 = randg(a(k),size(k)); 
+      rnd(k) = r1 ./ (r1 + randg(b(k),size(k)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/binocdf.m b/scripts/statistics/distributions/binocdf.m
new file mode 100644
index 0000000..6d4919c
--- /dev/null
+++ b/scripts/statistics/distributions/binocdf.m
@@ -0,0 +1,67 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binocdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the CDF at @var{x} of the
+## binomial distribution with parameters @var{n} and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the binomial distribution
+
+function cdf = binocdf (x, n, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (n) || !isscalar (p))
+    [retval, x, n, p] = common_size (x, n, p);
+    if (retval > 0)
+      error ("binocdf: x, n and p must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  cdf = zeros (sz);
+
+  k = find (isnan (x) | !(n >= 0) | (n != round (n))
+	    | !(p >= 0) | !(p <= 1));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x >= n) & (n >= 0) & (n == round (n))
+	    & (p >= 0) & (p <= 1));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x >= 0) & (x < n) & (n == round (n))
+	    & (p >= 0) & (p <= 1));
+  if (any (k))
+    tmp = floor (x(k));
+    if (isscalar (n) && isscalar (p))
+      cdf(k) = 1 - betainc (p, tmp + 1, n - tmp);
+    else
+      cdf(k) = 1 - betainc (p(k), tmp + 1, n(k) - tmp);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/binoinv.m b/scripts/statistics/distributions/binoinv.m
new file mode 100644
index 0000000..e249a50
--- /dev/null
+++ b/scripts/statistics/distributions/binoinv.m
@@ -0,0 +1,78 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binoinv (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## binomial distribution with parameters @var{n} and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the binomial distribution
+
+function inv = binoinv (x, n, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (n) || !isscalar (p))
+    [retval, x, n, p] = common_size (x, n, p);
+    if (retval > 0)
+      error ("binoinv: x, n and p must be of common size or scalars");
+    endif
+  endif
+  
+  sz = size (x);
+  inv = zeros (sz);
+
+  k = find (!(x >= 0) | !(x <= 1) | !(n >= 0) | (n != round (n))
+	    | !(p >= 0) | !(p <= 1));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x >= 0) & (x <= 1) & (n >= 0) & (n == round (n))
+	    & (p >= 0) & (p <= 1));
+  if (any (k))
+    if (isscalar (n) && isscalar (p))
+      cdf = binopdf (0, n, p) * ones (size(k));
+      while (any (inv(k) < n))
+	m = find (cdf < x(k));
+	if (any (m))
+          inv(k(m)) = inv(k(m)) + 1;
+          cdf(m) = cdf(m) + binopdf (inv(k(m)), n, p);
+	else
+          break;
+	endif
+      endwhile
+    else 
+      cdf = binopdf (0, n(k), p(k));
+      while (any (inv(k) < n(k)))
+	m = find (cdf < x(k));
+	if (any (m))
+          inv(k(m)) = inv(k(m)) + 1;
+          cdf(m) = cdf(m) + binopdf (inv(k(m)), n(k(m)), p(k(m)));
+	else
+          break;
+	endif
+      endwhile
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/binopdf.m b/scripts/statistics/distributions/binopdf.m
new file mode 100644
index 0000000..a1b540c
--- /dev/null
+++ b/scripts/statistics/distributions/binopdf.m
@@ -0,0 +1,60 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binopdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the binomial distribution with parameters @var{n}
+## and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the binomial distribution
+
+function pdf = binopdf (x, n, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! isscalar (n) || ! isscalar (p))
+    [retval, x, n, p] = common_size (x, n, p);
+    if (retval > 0)
+      error ("binopdf: x, n and p must be of common size or scalar");
+    endif
+  endif
+
+  k = ((x >= 0) & (x <= n)
+       & (x == round (x)) & (n == round (n))
+       & (p >= 0) & (p <= 1));
+
+  pdf = zeros (size (x));
+  pdf(! k) = NaN;
+  if (any (k(:)))
+    x = x(k);
+    if (! isscalar (n))
+      n = n(k);
+    endif
+    if (! isscalar (p))
+      p = p(k);
+    endif
+    z = gammaln(n+1) - gammaln(x+1) - gammaln(n-x+1) + x.*log(p) + (n-x).*log(1-p);
+    pdf(k) = exp (z);
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/binornd.m b/scripts/statistics/distributions/binornd.m
new file mode 100644
index 0000000..04f22ea
--- /dev/null
+++ b/scripts/statistics/distributions/binornd.m
@@ -0,0 +1,112 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} binornd (@var{n}, @var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} binornd (@var{n}, @var{p}, @var{sz})
+## Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+## random samples from the binomial distribution with parameters @var{n}
+## and @var{p}.  Both @var{n} and @var{p} must be scalar or of size
+## @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{n} and @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the binomial distribution
+
+function rnd = binornd (n, p, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(n) || !isscalar(p)) 
+      [retval, n, p] = common_size (n, p);
+      if (retval > 0)
+	error ("binornd: n and p must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("binornd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("binornd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (n) != 1)
+	&& (length (size (n)) != length (sz) ||	any (size (n) != sz)))
+      error ("binornd: n and must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("binornd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (n) != 1)
+	&& (length (size (n)) != length (sz) || any (size (n) != sz)))
+      error ("binornd: n and must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(n);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (n) && isscalar (p))
+    if (find (!(n >= 0) | !(n < Inf) | !(n == round (n)) |
+              !(p >= 0) | !(p <= 1)))
+      rnd = NaN * ones (sz);
+    elseif (n == 0)
+      rnd = zeros (sz);
+    else
+      nel = prod (sz);
+      tmp = rand (n, nel);
+      rnd = sum(tmp < ones (n, nel) * p, 1);
+      rnd = reshape(rnd, sz);
+    endif
+  else
+    rnd = zeros (sz);
+
+    k = find (!(n >= 0) | !(n < Inf) | !(n == round (n)) |
+              !(p >= 0) | !(p <= 1));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+
+    k = find ((n > 0) & (n < Inf) & (n == round (n)) & (p >= 0) & (p <= 1));
+    if (any (k))
+      N = max (n(k));
+      L = length (k);
+      tmp = rand (N, L);
+      ind = (1 : N)' * ones (1, L);
+      rnd(k) = sum ((tmp < ones (N, 1) * p(k)(:)') &
+                    (ind <= ones (N, 1) * n(k)(:)'),1);
+    endif
+  endif
+
+endfunction
+
+%!assert (binornd(0, 0, 1), 0)
+%!assert (binornd([0, 0], [0, 0], 1, 2), [0, 0])
diff --git a/scripts/statistics/distributions/cauchy_cdf.m b/scripts/statistics/distributions/cauchy_cdf.m
new file mode 100644
index 0000000..7eb23c7
--- /dev/null
+++ b/scripts/statistics/distributions/cauchy_cdf.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cauchy_cdf (@var{x}, @var{lambda}, @var{sigma})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the Cauchy distribution with location
+## parameter @var{lambda} and scale parameter @var{sigma}.  Default
+## values are @var{lambda} = 0, @var{sigma} = 1. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Cauchy distribution
+
+function cdf = cauchy_cdf (x, location, scale)
+
+  if (! (nargin == 1 || nargin == 3))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    location = 0;
+    scale = 1;
+  endif
+
+  if (!isscalar (location) || !isscalar (scale)) 
+    [retval, x, location, scale] = common_size (x, location, scale);
+    if (retval > 0)
+      error ("cauchy_cdf: x, lambda and sigma must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  cdf = NaN * ones (sz);
+
+  k = find ((x > -Inf) & (x < Inf) & (location > -Inf) &
+            (location < Inf) & (scale > 0) & (scale < Inf));
+  if (any (k))
+    if (isscalar (location) && isscalar (scale)) 
+      cdf(k) = 0.5 + atan ((x(k) - location) ./ scale) / pi;
+    else
+      cdf(k) = 0.5 + atan ((x(k) - location(k)) ./ scale(k)) / pi;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/cauchy_inv.m b/scripts/statistics/distributions/cauchy_inv.m
new file mode 100644
index 0000000..33c1b1a
--- /dev/null
+++ b/scripts/statistics/distributions/cauchy_inv.m
@@ -0,0 +1,74 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cauchy_inv (@var{x}, @var{lambda}, @var{sigma})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the Cauchy distribution with location parameter
+## @var{lambda} and scale parameter @var{sigma}.  Default values are
+## @var{lambda} = 0, @var{sigma} = 1. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Cauchy distribution
+
+function inv = cauchy_inv (x, location, scale)
+
+  if (! (nargin == 1 || nargin == 3))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    location = 0;
+    scale = 1;
+  endif
+
+  if (!isscalar (location) || !isscalar (scale)) 
+    [retval, x, location, scale] = common_size (x, location, scale);
+    if (retval > 0)
+      error ("cauchy_inv: x, lambda and sigma must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  inv = NaN * ones (sz);
+
+  ok = ((location > -Inf) & (location < Inf) &
+       (scale > 0) & (scale < Inf));
+
+  k = find ((x == 0) & ok);
+  if (any (k))
+    inv(k) = -Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & ok);
+  if (any (k))
+    if (isscalar (location) && isscalar (scale)) 
+      inv(k) = location - scale .* cot (pi * x(k));
+    else
+      inv(k) = location(k) - scale(k) .* cot (pi * x(k));
+    endif
+  endif
+
+  k = find ((x == 1) & ok);
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/cauchy_pdf.m b/scripts/statistics/distributions/cauchy_pdf.m
new file mode 100644
index 0000000..775850b
--- /dev/null
+++ b/scripts/statistics/distributions/cauchy_pdf.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cauchy_pdf (@var{x}, @var{lambda}, @var{sigma})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the Cauchy distribution with location parameter
+## @var{lambda} and scale parameter @var{sigma} > 0.  Default values are
+## @var{lambda} = 0, @var{sigma} = 1. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Cauchy distribution
+
+function pdf = cauchy_pdf (x, location, scale)
+
+  if (! (nargin == 1 || nargin == 3))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    location = 0;
+    scale = 1;
+  endif
+
+  if (!isscalar (location) || !isscalar (scale)) 
+    [retval, x, location, scale] = common_size (x, location, scale);
+    if (retval > 0)
+      error ("cauchy_pdf: x, lambda and sigma must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  pdf = NaN * ones (sz);
+
+  k = find ((x > -Inf) & (x < Inf) & (location > -Inf) &
+            (location < Inf) & (scale > 0) & (scale < Inf));
+  if (any (k))
+    if (isscalar (location) && isscalar (scale)) 
+      pdf(k) = ((1 ./ (1 + ((x(k) - location) ./ scale) .^ 2))
+		/ pi ./ scale);
+    else
+      pdf(k) = ((1 ./ (1 + ((x(k) - location(k)) ./ scale(k)) .^ 2))
+		/ pi ./ scale(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/cauchy_rnd.m b/scripts/statistics/distributions/cauchy_rnd.m
new file mode 100644
index 0000000..afa7f12
--- /dev/null
+++ b/scripts/statistics/distributions/cauchy_rnd.m
@@ -0,0 +1,91 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cauchy_rnd (@var{lambda}, @var{sigma}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} cauchy_rnd (@var{lambda}, @var{sigma}, @var{sz})
+## Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+## random samples from the Cauchy distribution with parameters @var{lambda} 
+## and @var{sigma} which must both be scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{lambda} and @var{sigma}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Cauchy distribution
+
+function rnd = cauchy_rnd (l, scale, r, c)
+
+  if (nargin > 1)
+    if (!isscalar (l) || !isscalar (scale)) 
+      [retval, l, scale] = common_size (l, scale);
+      if (retval > 0)
+	error ("cauchy_rnd: lambda and sigma must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("cauchy_rnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("cauchy_rnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (l) != 1)
+	&& (length (size (l)) != length (sz) || any (size (l) != sz)))
+      error ("cauchy_rnd: lambda and sigma must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("cauchy_rnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (l) != 1)
+	&& (length (size (l)) != length (sz) ||	any (size (l) != sz)))
+      error ("cauchy_rnd: lambda and sigma must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(l);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (l) && isscalar (scale)) 
+    if (find (!(l > -Inf) | !(l < Inf) | !(scale > 0) | !(scale < Inf)))
+      rnd = NaN * ones (sz);
+    else
+      rnd = l - cot (pi * rand (sz)) .* scale;
+    endif
+  else
+    rnd = NaN * ones (sz);
+    k = find ((l > -Inf) & (l < Inf) & (scale > 0) & (scale < Inf));
+    if (any (k))
+      rnd(k) = l(k)(:) - cot (pi * rand (size (k))) .* scale(k)(:);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/chi2cdf.m b/scripts/statistics/distributions/chi2cdf.m
new file mode 100644
index 0000000..cd76b9d
--- /dev/null
+++ b/scripts/statistics/distributions/chi2cdf.m
@@ -0,0 +1,44 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chi2cdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the chisquare distribution with @var{n}
+## degrees of freedom.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: CDF of the chi-square distribution
+
+function cdf = chi2cdf (x, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (n))
+    [retval, x, n] = common_size (x, n);
+    if (retval > 0)
+      error ("chi2cdf: x and n must be of common size or scalar");
+    endif
+  endif
+
+  cdf = gamcdf (x, n / 2, 2);
+
+endfunction
diff --git a/scripts/statistics/distributions/chi2inv.m b/scripts/statistics/distributions/chi2inv.m
new file mode 100644
index 0000000..3a863af
--- /dev/null
+++ b/scripts/statistics/distributions/chi2inv.m
@@ -0,0 +1,44 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chi2inv (@var{x}, @var{n})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the chisquare distribution with @var{n} degrees of
+## freedom.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: Quantile function of the chi-square distribution
+
+function inv = chi2inv (x, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (n))
+    [retval, x, n] = common_size (x, n);
+    if (retval > 0)
+      error ("chi2inv: x and n must be of common size or scalar");
+    endif
+  endif
+
+  inv = gaminv (x, n / 2, 2);
+
+endfunction
diff --git a/scripts/statistics/distributions/chi2pdf.m b/scripts/statistics/distributions/chi2pdf.m
new file mode 100644
index 0000000..0477b8c
--- /dev/null
+++ b/scripts/statistics/distributions/chi2pdf.m
@@ -0,0 +1,44 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chisquare_pdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the chisquare distribution with @var{n} degrees
+## of freedom.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the chi-square distribution
+
+function pdf = chi2pdf (x, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (n))
+    [retval, x, n] = common_size (x, n);
+    if (retval > 0)
+      error ("chi2pdf: x and n must be of common size or scalar");
+    endif
+  endif
+
+  pdf = gampdf (x, n / 2, 2);
+
+endfunction
diff --git a/scripts/statistics/distributions/chi2rnd.m b/scripts/statistics/distributions/chi2rnd.m
new file mode 100644
index 0000000..e66df3e
--- /dev/null
+++ b/scripts/statistics/distributions/chi2rnd.m
@@ -0,0 +1,91 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} chi2rnd (@var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} chi2rnd (@var{n}, @var{sz})
+## Return an @var{r} by @var{c}  or a @code{size (@var{sz})} matrix of 
+## random samples from the chisquare distribution with @var{n} degrees 
+## of freedom.  @var{n} must be a scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the chi-square distribution
+
+function rnd = chi2rnd (n, r, c)
+
+  if (nargin == 3)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("chi2rnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("chi2rnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (n) != 1)
+	&& (length (size (n)) != length (sz) ||	any (size (n) != sz)))
+      error ("chi2rnd: n must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 2)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("chi2rnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (n) != 1)
+	&& (length (size (n)) != length (sz) || any (size (n) != sz)))
+      error ("chi2rnd: n must be scalar or of size sz");
+    endif
+  elseif (nargin == 1)
+    sz = size(n);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (n))
+     if (find (!(n > 0) | !(n < Inf)))
+       rnd = NaN * ones (sz);
+     else
+       rnd = 2 * randg(n/2, sz);
+     endif
+  else
+    [retval, n, dummy] = common_size (n, ones (sz));
+    if (retval > 0)
+      error ("chi2rnd: a and b must be of common size or scalar");
+    endif
+
+    rnd = zeros (sz);
+    k = find (!(n > 0) | !(n < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+
+    k = find ((n > 0) & (n < Inf));
+    if (any (k))
+      rnd(k) = 2 * randg(n(k)/2, size(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/discrete_cdf.m b/scripts/statistics/distributions/discrete_cdf.m
new file mode 100644
index 0000000..11ac954
--- /dev/null
+++ b/scripts/statistics/distributions/discrete_cdf.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} discrete_cdf (@var{x}, @var{v}, @var{p})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of a univariate discrete distribution which
+## assumes the values in @var{v} with probabilities @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of a discrete distribution
+
+function cdf = discrete_cdf (x, v, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  sz = size (x);
+
+  if (! isvector (v))
+    error ("discrete_cdf: v must be a vector");
+  elseif (! isvector (p) || (length (p) != length (v)))
+    error ("discrete_cdf: p must be a vector with length (v) elements");
+  elseif (! (all (p >= 0) && any (p)))
+    error ("discrete_cdf: p must be a nonzero, nonnegative vector");
+  endif
+
+  n = numel (x);
+  m = length (v);
+  x = reshape (x, n, 1);
+  v = reshape (v, 1, m);
+  p = reshape (p / sum (p), m, 1);
+
+  cdf = zeros (sz);
+  k = find (isnan (x));
+  if (any (k))
+    cdf (k) = NaN;
+  endif
+  k = find (!isnan (x));
+  if (any (k))
+    n = length (k);
+    cdf (k) = ((x(k) * ones (1, m)) >= (ones (n, 1) * v)) * p;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/discrete_inv.m b/scripts/statistics/distributions/discrete_inv.m
new file mode 100644
index 0000000..a95f2d9
--- /dev/null
+++ b/scripts/statistics/distributions/discrete_inv.m
@@ -0,0 +1,80 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} discrete_inv (@var{x}, @var{v}, @var{p})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the univariate distribution which assumes the
+## values in @var{v} with probabilities @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of a discrete distribution
+
+function inv = discrete_inv (x, v, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  sz = size (x);
+
+  if (! isvector (v))
+    error ("discrete_inv: v must be a vector");
+  elseif (! isvector (p) || (length (p) != length (v)))
+    error ("discrete_inv: p must be a vector with length (v) elements");
+  elseif (! (all (p >= 0) && any (p)))
+    error ("discrete_inv: p must be a nonzero, nonnegative vector");
+  endif
+
+  n = numel (x);
+  x = reshape (x, 1, n);
+  m = length (v);
+  v = sort (v);
+  s = reshape (cumsum (p / sum (p)), m, 1);
+
+  ## Allow storage allocated for P to be reclaimed.
+  p = [];
+
+  inv = NaN * ones (sz);
+  if (any (k = find (x == 0)))
+    inv(k) = -Inf;
+  endif
+  if (any (k = find (x == 1)))
+    inv(k) = v(m) * ones (size (k));
+  endif
+
+  if (any (k = find ((x > 0) & (x < 1))))
+    n = length (k);
+
+    ## The following loop is a space/time tradeoff in favor of space,
+    ## since the dataset may be large.
+    ##
+    ## Vectorized code is:
+    ##
+    ##     inv(k) = v(sum ((ones (m, 1) * x(k)) > (s * ones (1, n))) + 1);
+
+    for q = 1:n
+      inv(k(q)) = v(sum (x(k(q)) > s) + 1);
+    endfor
+  endif
+
+endfunction
+
+
diff --git a/scripts/statistics/distributions/discrete_pdf.m b/scripts/statistics/distributions/discrete_pdf.m
new file mode 100644
index 0000000..f1e7654
--- /dev/null
+++ b/scripts/statistics/distributions/discrete_pdf.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} discrete_pdf (@var{x}, @var{v}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of a univariate discrete distribution which assumes
+## the values in @var{v} with probabilities @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: pDF of a discrete distribution
+
+function pdf = discrete_pdf (x, v, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  sz = size (x);
+
+  if (! isvector (v))
+    error ("discrete_pdf: v must be a vector");
+  elseif (! isvector (p) || (length (p) != length (v)))
+    error ("discrete_pdf: p must be a vector with length (v) elements");
+  elseif (! (all (p >= 0) && any (p)))
+    error ("discrete_pdf: p must be a nonzero, nonnegative vector");
+  endif
+
+  n = numel (x);
+  m = length (v);
+  x = reshape (x, n, 1);
+  v = reshape (v, 1, m);
+  p = reshape (p / sum (p), m, 1);
+
+  pdf = zeros (sz);
+  k = find (isnan (x));
+  if (any (k))
+    pdf (k) = NaN;
+  endif
+  k = find (!isnan (x));
+  if (any (k))
+    n = length (k);
+    pdf (k) = ((x(k) * ones (1, m)) == (ones (n, 1) * v)) * p;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/discrete_rnd.m b/scripts/statistics/distributions/discrete_rnd.m
new file mode 100644
index 0000000..e552288
--- /dev/null
+++ b/scripts/statistics/distributions/discrete_rnd.m
@@ -0,0 +1,78 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} discrete_rnd (@var{n}, @var{v}, @var{p})
+## @deftypefnx {Function File} {} discrete_rnd (@var{v}, @var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} discrete_rnd (@var{v}, @var{p}, @var{sz})
+## Generate a row vector containing a random sample of size @var{n} from
+## the univariate distribution which assumes the values in @var{v} with
+## probabilities @var{p}.  @var{n} must be a scalar.
+##
+## If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+## @var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+## @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from a discrete distribution
+
+function rnd = discrete_rnd (v, p, r, c)
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("discrete_rnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("discrete_rnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+  elseif (nargin == 3)
+    ## A potential problem happens here if all args are scalar, as
+    ## we can't distiguish between the command syntax. Thankfully this
+    ## case doesn't make much sense. So we assume the first syntax
+    ## if the first arg is scalar
+
+    if (isscalar (v))
+      sz = [1, floor(v)];
+      v = p;
+      p = r;
+    else
+      if (isscalar (r) && (r > 0))
+	sz = [r, r];
+      elseif (isvector(r) && all (r > 0))
+	sz = r(:)';
+      else
+	error ("discrete_rnd: r must be a positive integer or vector");
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (! isvector (v))
+    error ("discrete_rnd: v must be a vector");
+  elseif (! isvector (p) || (length (p) != length (v)))
+    error ("discrete_rnd: p must be a vector with length (v) elements");
+  elseif (! (all (p >= 0) && any (p)))
+    error ("discrete_rnd: p must be a nonzero, nonnegative vector");
+  endif
+
+  rnd = v (lookup (cumsum (p (1 : end-1)) / sum(p), rand (sz)) + 1); 
+endfunction
diff --git a/scripts/statistics/distributions/empirical_cdf.m b/scripts/statistics/distributions/empirical_cdf.m
new file mode 100644
index 0000000..956d69d
--- /dev/null
+++ b/scripts/statistics/distributions/empirical_cdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} empirical_cdf (@var{x}, @var{data})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the empirical distribution obtained from
+## the univariate sample @var{data}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the empirical distribution
+
+function cdf = empirical_cdf (x, data)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! isvector (data))
+    error ("empirical_cdf: data must be a vector");
+  endif
+
+  cdf = discrete_cdf (x, data, ones (size (data)) / length (data));
+
+endfunction
diff --git a/scripts/statistics/distributions/empirical_inv.m b/scripts/statistics/distributions/empirical_inv.m
new file mode 100644
index 0000000..0a0500c
--- /dev/null
+++ b/scripts/statistics/distributions/empirical_inv.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} empirical_inv (@var{x}, @var{data})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the empirical distribution obtained from the
+## univariate sample @var{data}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the empirical distribution
+
+function inv = empirical_inv (x, data)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! isvector (data))
+    error ("empirical_inv: data must be a vector");
+  endif
+
+  inv = discrete_inv (x, data, ones (size (data)) / length (data));
+
+endfunction
diff --git a/scripts/statistics/distributions/empirical_pdf.m b/scripts/statistics/distributions/empirical_pdf.m
new file mode 100644
index 0000000..d1db3c6
--- /dev/null
+++ b/scripts/statistics/distributions/empirical_pdf.m
@@ -0,0 +1,41 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} empirical_pdf (@var{x}, @var{data})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the empirical distribution obtained from the
+## univariate sample @var{data}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the empirical distribution
+
+function pdf = empirical_pdf (x, data)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (! isvector (data))
+    error ("empirical_pdf: data must be a vector");
+  endif
+
+  pdf = discrete_pdf (x, data, ones (size (data)) / length (data));
+
+endfunction
diff --git a/scripts/statistics/distributions/empirical_rnd.m b/scripts/statistics/distributions/empirical_rnd.m
new file mode 100644
index 0000000..57615b2
--- /dev/null
+++ b/scripts/statistics/distributions/empirical_rnd.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} empirical_rnd (@var{n}, @var{data})
+## @deftypefnx {Function File} {} empirical_rnd (@var{data}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} empirical_rnd (@var{data}, @var{sz})
+## Generate a bootstrap sample of size @var{n} from the empirical
+## distribution obtained from the univariate sample @var{data}.
+##
+## If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+## @var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+## @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Bootstrap samples from the empirical distribution
+
+function rnd = empirical_rnd (data, r, c)
+
+  if (nargin == 2)
+    if (isscalar(data))
+      c = data;
+      data = r;
+      r = 1;
+    endif
+  elseif (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! isvector (data))
+    error ("empirical_rnd: data must be a vector");
+  endif
+
+  rnd = discrete_rnd (data, ones (size (data)) / length (data), r, c);
+
+endfunction
diff --git a/scripts/statistics/distributions/expcdf.m b/scripts/statistics/distributions/expcdf.m
new file mode 100644
index 0000000..f731bf4
--- /dev/null
+++ b/scripts/statistics/distributions/expcdf.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} expcdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the exponential distribution with
+## mean @var{lambda}.
+##
+## The arguments can be of common size or scalar.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the exponential distribution
+
+function cdf = expcdf (x, l)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (x) && !isscalar(l))
+    [retval, x, l] = common_size (x, l);
+    if (retval > 0)
+      error ("expcdf: x and lambda must be of common size or scalar");
+    endif
+  endif
+
+  if (isscalar (x))
+    sz = size (l);
+  else
+    sz = size (x);
+  endif
+
+  cdf = zeros (sz);
+
+  k = find (isnan (x) | !(l > 0));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (l > 0));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & (l > 0));
+  if (any (k))
+    if isscalar (l)
+      cdf (k) = 1 - exp (- x(k) ./ l);
+    elseif isscalar (x)
+      cdf (k) = 1 - exp (- x ./ l(k));
+    else
+      cdf (k) = 1 - exp (- x(k) ./ l(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/expinv.m b/scripts/statistics/distributions/expinv.m
new file mode 100644
index 0000000..cff584f
--- /dev/null
+++ b/scripts/statistics/distributions/expinv.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} expinv (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the exponential distribution with mean
+## @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the exponential distribution
+
+function inv = expinv (x, l)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (x) && !isscalar(l))
+    [retval, x, l] = common_size (x, l);
+    if (retval > 0)
+      error ("expinv: x and lambda must be of common size or scalar");
+    endif
+  endif
+
+  if (isscalar (x))
+    sz = size (l);
+  else
+    sz = size (x);
+  endif
+
+  inv = zeros (sz);
+
+  k = find (!(l > 0) | (x < 0) | (x > 1) | isnan (x));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 1) & (l > 0));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (l > 0));
+  if (any (k))
+    if isscalar (l)
+      inv(k) = - l .* log (1 - x(k));
+    elseif isscalar (x)
+      inv(k) = - l(k) .* log (1 - x);
+    else
+      inv(k) = - l(k) .* log (1 - x(k));
+    endif
+  endif
+
+endfunction
+
diff --git a/scripts/statistics/distributions/exppdf.m b/scripts/statistics/distributions/exppdf.m
new file mode 100644
index 0000000..cb72562
--- /dev/null
+++ b/scripts/statistics/distributions/exppdf.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} exppdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the probability density function
+## (PDF) of the exponential distribution with mean @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the exponential distribution
+
+function pdf = exppdf (x, l)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (x) && !isscalar(l))
+    [retval, x, l] = common_size (x, l);
+    if (retval > 0)
+      error ("exppdf: x and lambda must be of common size or scalar");
+    endif
+  endif
+
+  if (isscalar (x))
+    sz = size (l);
+  else
+    sz = size (x);
+  endif
+  pdf = zeros (sz);
+
+  k = find (!(l > 0) | isnan (x));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & (l > 0));
+  if (any (k))
+    if isscalar (l)
+      pdf(k) = exp (- x(k) ./ l) ./ l;
+    elseif isscalar (x)
+      pdf(k) = exp (- x ./ l(k)) ./ l(k);
+    else
+      pdf(k) = exp (- x(k) ./ l(k)) ./ l(k);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/exprnd.m b/scripts/statistics/distributions/exprnd.m
new file mode 100644
index 0000000..1840480
--- /dev/null
+++ b/scripts/statistics/distributions/exprnd.m
@@ -0,0 +1,87 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} exprnd (@var{lambda}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} exprnd (@var{lambda}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## exponential distribution with mean @var{lambda}, which must be a
+## scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a vector, 
+## create a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the exponential distribution
+
+function rnd = exprnd (l, r, c)
+
+  if (nargin == 3)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("exprnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("exprnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (l) != 1) && 
+	(length (size (l)) != length (sz) || any (size (l) != sz)))
+      error ("exprnd: lambda must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 2)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("exprnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (l) != 1) && 
+	((length (size (l)) != length (sz)) || any (size (l) != sz)))
+      error ("exprnd: lambda must be scalar or of size sz");
+    endif
+  elseif (nargin == 1)
+    sz = size (l);
+  else
+    print_usage ();
+  endif
+
+
+  if (isscalar (l))
+    if ((l > 0) && (l < Inf))
+      rnd = rande(sz) * l;
+    else
+      rnd = NaN * ones (sz);
+    endif
+  else
+    rnd = zeros (sz);
+    k = find (!(l > 0) | !(l < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+    k = find ((l > 0) & (l < Inf));
+    if (any (k))
+      rnd(k) = rande(size(k)) .* l(k);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/fcdf.m b/scripts/statistics/distributions/fcdf.m
new file mode 100644
index 0000000..0ddaa10
--- /dev/null
+++ b/scripts/statistics/distributions/fcdf.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fcdf (@var{x}, @var{m}, @var{n})
+## For each element of @var{x}, compute the CDF at @var{x} of the F
+## distribution with @var{m} and @var{n} degrees of freedom, i.e.,
+## PROB (F (@var{m}, @var{n}) <= @var{x}). 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the F distribution
+
+function cdf = fcdf (x, m, n)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (m) || !isscalar (n))
+    [retval, x, m, n] = common_size (x, m, n);
+    if (retval > 0)
+      error ("fcdf: x, m and n must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  cdf = zeros (sz);
+
+  k = find (!(m > 0) | !(n > 0) | isnan (x));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (m > 0) & (n > 0));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & (m > 0) & (n > 0));
+  if (any (k))
+    if (isscalar (m) && isscalar (n))
+      cdf(k) = 1 - betainc (1 ./ (1 + m .* x(k) ./ n), n / 2, m / 2);
+    else
+      cdf(k) = 1 - betainc (1 ./ (1 + m(k) .* x(k) ./ n(k)), n(k) / 2, 
+			    m(k) / 2);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/finv.m b/scripts/statistics/distributions/finv.m
new file mode 100644
index 0000000..5455bd5
--- /dev/null
+++ b/scripts/statistics/distributions/finv.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} finv (@var{x}, @var{m}, @var{n})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the F distribution with parameters @var{m} and
+## @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the F distribution
+
+function inv = finv (x, m, n)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (m) || !isscalar (n))
+    [retval, x, m, n] = common_size (x, m, n);
+    if (retval > 0)
+      error ("finv: x, m and n must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  inv = zeros (sz);
+
+  k = find ((x < 0) | (x > 1) | isnan (x) | !(m > 0) | !(n > 0));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 1) & (m > 0) & (n > 0));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (m > 0) & (n > 0));
+  if (any (k))
+    if (isscalar (m) && isscalar (n))
+      inv(k) = ((1 ./ betainv (1 - x(k), n / 2, m / 2) - 1) .* n ./ m);
+    else
+      inv(k) = ((1 ./ betainv (1 - x(k), n(k) / 2, m(k) / 2) - 1)
+		.* n(k) ./ m(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/fpdf.m b/scripts/statistics/distributions/fpdf.m
new file mode 100644
index 0000000..744b298
--- /dev/null
+++ b/scripts/statistics/distributions/fpdf.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fpdf (@var{x}, @var{m}, @var{n})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the F distribution with @var{m} and @var{n}
+## degrees of freedom.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the F distribution
+
+function pdf = fpdf (x, m, n)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (m) || !isscalar (n))
+    [retval, x, m, n] = common_size (x, m, n);
+    if (retval > 0)
+      error ("fpdf: x, m and n must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  pdf = zeros (sz);
+
+  k = find (isnan (x) | !(m > 0) | !(n > 0));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & (m > 0) & (n > 0));
+  if (any (k))
+    if (isscalar (m) && isscalar (n))
+      tmp = m / n * x(k);
+      pdf(k) = (exp ((m / 2 - 1) .* log (tmp)
+		     - ((m + n) / 2) .* log (1 + tmp))
+		.* (m / n) ./ beta (m / 2, n / 2));
+    else
+      tmp = m(k) .* x(k) ./ n(k);
+      pdf(k) = (exp ((m(k) / 2 - 1) .* log (tmp)
+		     - ((m(k) + n(k)) / 2) .* log (1 + tmp))
+		.* (m(k) ./ n(k)) ./ beta (m(k) / 2, n(k) / 2));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/frnd.m b/scripts/statistics/distributions/frnd.m
new file mode 100644
index 0000000..b2d1f8d
--- /dev/null
+++ b/scripts/statistics/distributions/frnd.m
@@ -0,0 +1,119 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} frnd (@var{m}, @var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} frnd (@var{m}, @var{n}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the F
+## distribution with @var{m} and @var{n} degrees of freedom.  Both
+## @var{m} and @var{n} must be scalar or of size @var{r} by @var{c}.
+## If @var{sz} is a vector the random samples are in a matrix of 
+## size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{m} and @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the F distribution
+
+function rnd = frnd (m, n, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(m) || !isscalar(n)) 
+      [retval, m, n] = common_size (m, n);
+      if (retval > 0)
+	error ("frnd: m and n must be of common size or scalar");
+      endif
+    endif
+  endif
+
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("frnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("frnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (m) != 1) && 
+	((length (size (m)) != length (sz)) || any (size (m) != sz)))
+      error ("frnd: m and n must be scalar or of size [r,c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("frnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (m) != 1) && 
+	((length (size (m)) != length (sz)) || any (size (m) != sz)))
+      error ("frnd: m and n must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(a);
+  else
+    print_usage ();
+  endif
+
+
+  if (isscalar (m) && isscalar (n))
+    if (isinf (m) || isinf (n))
+      if (isinf (m))
+	rnd = ones (sz);
+      else
+	rnd = 2 ./ m .* randg(m / 2, sz);
+      endif
+      if (! isinf (n))
+	rnd = 0.5 .* n .* rnd ./ randg (n / 2, sz); 
+      endif
+    elseif ((m > 0) && (m < Inf) && (n > 0) && (n < Inf))
+      rnd = n ./ m .* randg (m / 2, sz) ./ randg (n / 2, sz);
+    else
+      rnd = NaN * ones (sz);
+    endif
+  else
+    rnd = zeros (sz);
+
+    k = find (isinf(m) | isinf(n));
+    if (any (k))
+      rnd (k) = 1;
+      k2 = find (!isinf(m) & isinf(n));
+      rnd (k2) = 2 ./ m(k2) .* randg (m(k2) ./ 2, size(k2));
+      k2 = find (isinf(m) & !isinf(n));
+      rnd (k2) = 0.5 .* n(k2) .* rnd(k2) ./ randg (n(k2) ./ 2, size(k2));
+    endif
+
+    k = find (!(m > 0) | !(n > 0));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+
+    k = find ((m > 0) & (m < Inf) &
+              (n > 0) & (n < Inf));
+    if (any (k))
+      rnd(k) = n(k) ./ m(k) .* randg(m(k)./2,size(k)) ./ randg(n(k)./2,size(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/gamcdf.m b/scripts/statistics/distributions/gamcdf.m
new file mode 100644
index 0000000..a6924be
--- /dev/null
+++ b/scripts/statistics/distributions/gamcdf.m
@@ -0,0 +1,60 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gamcdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the Gamma distribution with parameters
+## @var{a} and @var{b}.
+## @seealso{gamma, gammaln, gammainc, gampdf, gaminv, gamrnd}
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: CDF of the Gamma distribution
+
+function cdf = gamcdf (x, a, b)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("gamcdf: x, a and b must be of common size or scalars");
+    endif
+  endif
+
+  sz = size (x);
+  cdf = zeros (sz);
+
+  k = find (!(a > 0) | !(b > 0) | isnan (x));
+  if (any (k))
+    cdf (k) = NaN;
+  endif
+
+  k = find ((x > 0) & (a > 0) & (b > 0));
+  if (any (k))
+    if (isscalar (a) && isscalar(b))
+      cdf (k) = gammainc (x(k) ./ b, a);
+    else
+      cdf (k) = gammainc (x(k) ./ b(k), a(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/gaminv.m b/scripts/statistics/distributions/gaminv.m
new file mode 100644
index 0000000..5e41e58
--- /dev/null
+++ b/scripts/statistics/distributions/gaminv.m
@@ -0,0 +1,96 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gaminv (@var{x}, @var{a}, @var{b})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the Gamma distribution with parameters @var{a}
+## and @var{b}.
+## @seealso{gamma, gammaln, gammainc, gampdf, gamcdf, gamrnd}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Gamma distribution
+
+function inv = gaminv (x, a, b)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("gaminv: x, a and b must be of common size or scalars");
+    endif
+  endif
+
+  sz = size (x);
+  inv = zeros (sz);
+
+  k = find ((x < 0) | (x > 1) | isnan (x) | !(a > 0) | !(b > 0));
+  if (any (k))
+    inv (k) = NaN;
+  endif
+
+  k = find ((x == 1) & (a > 0) & (b > 0));
+  if (any (k))
+    inv (k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (a > 0) & (b > 0));
+  if (any (k))
+    if (!isscalar(a) || !isscalar(b))
+      a = a (k);
+      b = b (k);
+      y = a .* b;
+    else
+      y = a * b * ones (size (k));
+    endif
+    x = x (k);
+
+    if (isa (x, "single"))
+      myeps = eps ("single");
+    else
+      myeps = eps;
+    endif
+
+    l = find (x < myeps);
+    if (any (l))
+      y(l) = sqrt (myeps) * ones (length (l), 1);
+    endif
+
+    y_old = y;
+    for i = 1 : 100
+      h     = (gamcdf (y_old, a, b) - x) ./ gampdf (y_old, a, b);
+      y_new = y_old - h;
+      ind   = find (y_new <= myeps);
+      if (any (ind))
+        y_new (ind) = y_old (ind) / 10;
+        h = y_old - y_new;
+      endif
+      if (max (abs (h)) < sqrt (myeps))
+        break;
+      endif
+      y_old = y_new;
+    endfor
+
+    inv (k) = y_new;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/gampdf.m b/scripts/statistics/distributions/gampdf.m
new file mode 100644
index 0000000..39fc6b7
--- /dev/null
+++ b/scripts/statistics/distributions/gampdf.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gampdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, return the probability density function
+## (PDF) at @var{x} of the Gamma distribution with parameters @var{a}
+## and @var{b}.
+## @seealso{gamma, gammaln, gammainc, gamcdf, gaminv, gamrnd}
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the Gamma distribution
+
+function pdf = gampdf (x, a, b)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("gampdf: x, a and b must be of common size or scalars");
+    endif
+  endif
+
+  sz = size(x);
+  pdf = zeros (sz);
+
+  k = find (!(a > 0) | !(b > 0) | isnan (x));
+  if (any (k))
+    pdf (k) = NaN;
+  endif
+
+  k = find ((x > 0) & (a > 0) & (a <= 1) & (b > 0));
+  if (any (k))
+    if (isscalar(a) && isscalar(b))
+      pdf(k) = (x(k) .^ (a - 1)) ...
+		.* exp(- x(k) ./ b) ./ gamma (a) ./ (b .^ a);
+    else
+      pdf(k) = (x(k) .^ (a(k) - 1)) ...
+		.* exp(- x(k) ./ b(k)) ./ gamma (a(k)) ./ (b(k) .^ a(k));
+    endif
+  endif
+
+  k = find ((x > 0) & (a > 1) & (b > 0));
+  if (any (k))
+    if (isscalar(a) && isscalar(b))
+      pdf(k) = exp (- a .* log (b) + (a-1) .* log (x(k))
+		    - x(k) ./ b - gammaln (a));
+    else
+      pdf(k) = exp (- a(k) .* log (b(k)) + (a(k)-1) .* log (x(k))
+		    - x(k) ./ b(k) - gammaln (a(k)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/gamrnd.m b/scripts/statistics/distributions/gamrnd.m
new file mode 100644
index 0000000..6f603dd
--- /dev/null
+++ b/scripts/statistics/distributions/gamrnd.m
@@ -0,0 +1,97 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gamrnd (@var{a}, @var{b}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} gamrnd (@var{a}, @var{b}, @var{sz})
+## Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+## random samples from the Gamma distribution with parameters @var{a}
+## and @var{b}.  Both @var{a} and @var{b} must be scalar or of size 
+## @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{b}.
+## @seealso{gamma, gammaln, gammainc, gampdf, gamcdf, gaminv}
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Gamma distribution
+
+function rnd = gamrnd (a, b, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(a) || !isscalar(b)) 
+      [retval, a, b] = common_size (a, b);
+      if (retval > 0)
+	error ("gamrnd: a and b must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("gamrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("gamrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (a) != 1)
+	&& (length (size (a)) != length (sz) || any (size (a) != sz)))
+      error ("gamrnd: a and b must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("gamrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (a) != 1)
+	&& (length (size (a)) != length (sz) || any (size (a) != sz)))
+      error ("gamrnd: a and b must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(a);
+  else
+    print_usage ();
+  endif
+
+  rnd = zeros (sz);
+
+  if (isscalar (a) && isscalar(b))
+    if (find (!(a > 0) | !(a < Inf) | !(b > 0) | !(b < Inf)))
+      rnd = NaN * ones (sz);
+    else
+      rnd = b .* randg(a, sz);
+    endif
+  else 
+    k = find (!(a > 0) | !(a < Inf) | !(b > 0) | !(b < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+    k = find ((a > 0) & (a < Inf) & (b > 0) & (b < Inf));
+    if (any (k))
+      rnd(k) = b(k) .* randg(a(k), size(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/geocdf.m b/scripts/statistics/distributions/geocdf.m
new file mode 100644
index 0000000..09f903b
--- /dev/null
+++ b/scripts/statistics/distributions/geocdf.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geocdf (@var{x}, @var{p})
+## For each element of @var{x}, compute the CDF at @var{x} of the
+## geometric distribution with parameter @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the geometric distribution
+
+function cdf = geocdf (x, p)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (x) && !isscalar (p))
+    [retval, x, p] = common_size (x, p);
+    if (retval > 0)
+      error ("geocdf: x and p must be of common size or scalar");
+    endif
+  endif
+
+  cdf = zeros (size (x));
+
+  k = find (isnan (x) | !(p >= 0) | !(p <= 1));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (p >= 0) & (p <= 1));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x >= 0) & (x < Inf) & (x == round (x)) & (p > 0) & (p <= 1));
+  if (any (k))
+    if (isscalar (x))
+      cdf(k) = 1 - ((1 - p(k)) .^ (x + 1));
+    elseif (isscalar (p))
+      cdf(k) = 1 - ((1 - p) .^ (x(k) + 1));
+    else
+      cdf(k) = 1 - ((1 - p(k)) .^ (x(k) + 1));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/geoinv.m b/scripts/statistics/distributions/geoinv.m
new file mode 100644
index 0000000..1a0f8e3
--- /dev/null
+++ b/scripts/statistics/distributions/geoinv.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geoinv (@var{x}, @var{p})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## geometric distribution with parameter @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the geometric distribution
+
+function inv = geoinv (x, p)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (x) && !isscalar (p))
+    [retval, x, p] = common_size (x, p);
+    if (retval > 0)
+      error ("geoinv: x and p must be of common size or scalar");
+    endif
+  endif
+
+  inv = zeros (size (x));
+
+  k = find (!(x >= 0) | !(x <= 1) | !(p >= 0) | !(p <= 1));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 1) & (p >= 0) & (p <= 1));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (p > 0) & (p <= 1));
+  if (any (k))
+    if (isscalar (x))
+      inv(k) = max (ceil (log (1 - x) ./ log (1 - p(k))) - 1, 0);
+    elseif (isscalar (p))
+      inv(k) = max (ceil (log (1 - x(k)) / log (1 - p)) - 1, 0);
+    else
+      inv(k) = max (ceil (log (1 - x(k)) ./ log (1 - p(k))) - 1, 0);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/geopdf.m b/scripts/statistics/distributions/geopdf.m
new file mode 100644
index 0000000..ab5f6b0
--- /dev/null
+++ b/scripts/statistics/distributions/geopdf.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geopdf (@var{x}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the geometric distribution with parameter @var{p}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the geometric distribution
+
+function pdf = geopdf (x, p)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (x) && !isscalar (p))
+    [retval, x, p] = common_size (x, p);
+    if (retval > 0)
+      error ("geopdf: x and p must be of common size or scalar");
+    endif
+  endif
+
+  pdf = zeros (size (x));
+
+  k = find (isnan (x) | !(p >= 0) | !(p <= 1));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  ## Just for the fun of it ...
+  k = find ((x == Inf) & (p == 0));
+  if (any (k))
+    pdf(k) = 1;
+  endif
+
+  k = find ((x >= 0) & (x < Inf) & (x == round (x)) & (p > 0) & (p <= 1));
+  if (any (k))
+    if (isscalar (x))
+      pdf(k) = p(k) .* ((1 - p(k)) .^ x);
+    elseif (isscalar (p))
+      pdf(k) = p .* ((1 - p) .^ x(k));
+    else
+      pdf(k) = p(k) .* ((1 - p(k)) .^ x(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/geornd.m b/scripts/statistics/distributions/geornd.m
new file mode 100644
index 0000000..52f80c1
--- /dev/null
+++ b/scripts/statistics/distributions/geornd.m
@@ -0,0 +1,93 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} geornd (@var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} geornd (@var{p}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## geometric distribution with parameter @var{p}, which must be a scalar
+## or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are given create a matrix with @var{r} rows and
+## @var{c} columns.  Or if @var{sz} is a vector, create a matrix of size
+## @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the geometric distribution
+
+function rnd = geornd (p, r, c)
+
+  if (nargin == 3)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("geornd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("geornd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (p) != 1) && ((length (size (p)) != length (sz)) ||
+				any (size (p) != sz)))
+      error ("geornd: p must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 2)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("geornd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (p) != 1) && ((length (size (p)) != length (sz)) ||
+				any (size (p) != sz)))
+      error ("geornd: n must be scalar or of size sz");
+    endif
+  elseif (nargin == 1)
+    sz = size(n);
+  elseif (nargin != 1)
+    print_usage ();
+  endif
+
+
+  if (isscalar (p))
+    if (!(p >= 0) || !(p <= 1))
+      rnd = NaN * ones (sz);
+    elseif (p == 0)
+      rnd = Inf * ones (sz);
+    elseif ((p > 0) & (p < 1));
+      rnd = floor (- rande(sz) ./ log (1 - p));
+    else
+      rnd = zeros (sz);
+    endif
+  else
+    rnd = floor (- rande(sz) ./ log (1 - p));
+
+    k = find (!(p >= 0) | !(p <= 1));
+    if (any (k))
+      rnd(k) = NaN * ones (1, length (k));
+    endif
+
+    k = find (p == 0);
+    if (any (k))
+      rnd(k) = Inf * ones (1, length (k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/hygecdf.m b/scripts/statistics/distributions/hygecdf.m
new file mode 100644
index 0000000..ae821e5
--- /dev/null
+++ b/scripts/statistics/distributions/hygecdf.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hygecdf (@var{x}, @var{t}, @var{m}, @var{n})
+## Compute the cumulative distribution function (CDF) at @var{x} of the
+## hypergeometric distribution with parameters @var{t}, @var{m}, and
+## @var{n}.  This is the probability of obtaining not more than @var{x}
+## marked items when randomly drawing a sample of size @var{n} without
+## replacement from a population of total size @var{t} containing
+## @var{m} marked items.
+##
+## The parameters @var{t}, @var{m}, and @var{n} must positive integers
+## with @var{m} and @var{n} not greater than @var{t}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the hypergeometric distribution
+
+function cdf = hygecdf (x, t, m, n)
+
+  if (nargin != 4)
+    print_usage ();
+  endif
+
+  if (!isscalar (t) || !isscalar (m) || !isscalar (n))
+    error ("hygecdf: t, m and n must all be positive integers");
+  endif
+
+  if ((t < 0) | (m < 0) | (n <= 0) | (t != round (t)) |
+      (m != round (m)) | (n != round (n)) | (m > t) | (n > t))
+    cdf = NaN * ones (size (x))
+  else
+    cdf = discrete_cdf (x, 0 : n, hygepdf (0 : n, t, m, n));
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/hygeinv.m b/scripts/statistics/distributions/hygeinv.m
new file mode 100644
index 0000000..1eec933
--- /dev/null
+++ b/scripts/statistics/distributions/hygeinv.m
@@ -0,0 +1,49 @@
+## Copyright (C) 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hygeinv (@var{x}, @var{t}, @var{m}, @var{n})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## hypergeometric distribution with parameters @var{t}, @var{m}, and
+## @var{n}.
+##
+## The parameters @var{t}, @var{m}, and @var{n} must positive integers
+## with @var{m} and @var{n} not greater than @var{t}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the hypergeometric distribution
+
+function inv = hygeinv (x, t, m, n)
+
+  if (nargin != 4)
+    print_usage ();
+  endif
+
+  if (!isscalar (t) || !isscalar (m) || !isscalar (n))
+    error ("hygeinv: t, m and n must all be positive integers");
+  endif
+
+  if ((t < 0) | (m < 0) | (n <= 0) | (t != round (t)) |
+      (m != round (m)) | (n != round (n)) | (m > t) | (n > t))
+    inv = NaN * ones (size (x))
+  else
+    inv = discrete_inv (x, 0 : n, hygepdf (0 : n, t, m, n));
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/hygepdf.m b/scripts/statistics/distributions/hygepdf.m
new file mode 100644
index 0000000..dc74838
--- /dev/null
+++ b/scripts/statistics/distributions/hygepdf.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1996, 1997, 2005, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hygepdf (@var{x}, @var{t}, @var{m}, @var{n})
+## Compute the probability density function (PDF) at @var{x} of the
+## hypergeometric distribution with parameters @var{t}, @var{m}, and
+## @var{n}.  This is the probability of obtaining @var{x} marked items
+## when randomly drawing a sample of size @var{n} without replacement
+## from a population of total size @var{t} containing @var{m} marked items.
+##
+## The arguments must be of common size or scalar.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the hypergeometric distribution
+
+function pdf = hygepdf (x, t, m, n)
+
+  if (nargin != 4)
+    print_usage ();
+  endif
+
+  if (!isscalar (t) || !isscalar (m) || !isscalar (n))
+    [retval, x, t, m, n] = common_size (x, t, m, n);
+    if (retval > 0)
+      error ("hygepdf: x, t, m, and n must be of common size or scalar");
+    endif
+  endif
+
+  pdf = zeros (size (x));
+
+  ## everything in i1 gives NaN
+  i1 = ((t < 0) | (m < 0) | (n <= 0) | (t != round (t)) |
+        (m != round (m)) | (n != round (n)) | (m > t) | (n > t));
+  ## everything in i2 gives 0 unless in i1
+  i2 = ((x != round (x)) | (x < 0) | (x > m) | (n < x) | (n-x > t-m));
+  k = find (i1);
+  if (any (k))
+    if (isscalar (t) && isscalar (m) && isscalar (n))
+      pdf = NaN * ones (size (x));
+    else
+      pdf (k) = NaN;
+    endif
+  endif
+  k = find (!i1 & !i2);
+  if (any (k))
+    if (isscalar (t) && isscalar (m) && isscalar (n))
+      pdf (k) = (bincoeff (m, x(k)) .* bincoeff (t-m, n-x(k))
+		 / bincoeff (t, n));
+    else
+      pdf (k) = (bincoeff (m(k), x(k)) .* bincoeff (t(k)-m(k), n(k)-x(k))
+		 ./ bincoeff (t(k), n(k)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/hygernd.m b/scripts/statistics/distributions/hygernd.m
new file mode 100644
index 0000000..0b87898
--- /dev/null
+++ b/scripts/statistics/distributions/hygernd.m
@@ -0,0 +1,97 @@
+## Copyright (C) 1997, 2005, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hygernd (@var{t}, @var{m}, @var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} hygernd (@var{t}, @var{m}, @var{n}, @var{sz})
+## @deftypefnx {Function File} {} hygernd (@var{t}, @var{m}, @var{n})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## hypergeometric distribution with parameters @var{t}, @var{m},
+## and @var{n}.
+##
+## The parameters @var{t}, @var{m}, and @var{n} must positive integers
+## with @var{m} and @var{n} not greater than @var{t}.
+##
+## The parameter @var{sz} must be scalar or a vector of matrix
+## dimensions.  If @var{sz} is scalar, then a @var{sz} by @var{sz}
+## matrix of random samples is generated.
+## @end deftypefn
+
+function rnd = hygernd (t, m, n, r, c)
+
+  if (nargin == 5)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("hygernd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("hygernd: c must be a positive integer");
+    endif
+    sz = [r, c];
+  elseif (nargin == 4)
+    if (isvector (r) && all (r > 0) && all (r == round (r)))
+      if (isscalar (r))
+        sz = [r, r];
+      else
+        sz = r(:)';
+      endif
+    else
+      error ("hygernd: r must be a vector of positive integers");
+    endif
+  elseif (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! isscalar (t) || ! isscalar (m) || ! isscalar (n))
+    [retval, t, m, n] = common_size (t, m, n);
+    if (retval > 0)
+      error ("hygernd: t, m and n must be of common size or scalar");
+    endif
+    if (nargin > 3)
+      if (any (sz != size (t)))
+        error ("hygernd: t, m and n must have the same size as implied by r and c or must be scalar");
+      endif
+    else
+      sz = size (t);
+    endif
+  elseif (nargin == 3)
+    sz = 1;
+  endif
+
+  ## NaN elements
+  ne = (! (t >= 0) | ! (m >= 0) | ! (n > 0) | ! (t == round (t)) | ! (m == round (m)) | ! (n == round (n)) | ! (m <= t) | ! (n <= t));
+
+  if (! isscalar (t))
+    rnd = zeros (sz);
+    rnd(ne) = NaN;
+    rn = rand (sz);
+    for i = find (! ne)
+      v = 0 : n(i);
+      p = hygepdf (v, t(i), m(i), n(i));
+      rnd(i) = v(lookup (cumsum (p(1 : end-1)) / sum (p), rn(i)) + 1);
+    endfor
+  else
+    if (ne)
+      rnd = NaN * ones (sz);
+    else
+      v = 0:n;
+      p = hygepdf (v, t, m, n);
+      rnd = v(lookup (cumsum (p(1:end-1)) / sum (p), rand (sz)) + 1);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/kolmogorov_smirnov_cdf.m b/scripts/statistics/distributions/kolmogorov_smirnov_cdf.m
new file mode 100644
index 0000000..676cc2b
--- /dev/null
+++ b/scripts/statistics/distributions/kolmogorov_smirnov_cdf.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} kolmogorov_smirnov_cdf (@var{x}, @var{tol})
+## Return the CDF at @var{x} of the Kolmogorov-Smirnov distribution,
+## @tex
+## $$ Q(x) = \sum_{k=-\infty}^\infty (-1)^k \exp(-2 k^2 x^2) $$
+## @end tex
+## @ifnottex
+## @example
+## @group
+##          Inf
+## Q(x) =   SUM    (-1)^k exp(-2 k^2 x^2)
+##        k = -Inf
+## @end group
+## @end example
+## @end ifnottex
+##
+## @noindent
+## for @var{x} > 0.
+##
+## The optional parameter @var{tol} specifies the precision up to which
+## the series should be evaluated;  the default is @var{tol} = @code{eps}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Kolmogorov-Smirnov distribution
+
+function cdf = kolmogorov_smirnov_cdf (x, tol)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    if (isa (x, "single"))
+      tol = eps ("single");
+    else
+      tol = eps;
+    endif
+  else
+    if (! isscalar (tol) || ! (tol > 0))
+      error ("kolmogorov_smirnov_cdf: tol has to be a positive scalar");
+    endif
+  endif
+
+  n = numel (x);
+  if (n == 0)
+    error ("kolmogorov_smirnov_cdf: x must not be empty");
+  endif
+
+  cdf = zeros (size (x));
+
+  ind = find (x > 0);
+  if (length (ind) > 0)
+    if (size(ind,2) < size(ind,1))
+      y = x(ind.');
+    else
+      y   = x(ind);
+    endif
+    K   = ceil (sqrt (- log (tol) / 2) / min (y));
+    k   = (1:K)';
+    A   = exp (- 2 * k.^2 * y.^2);
+    odd = find (rem (k, 2) == 1);
+    A(odd,:) = -A(odd,:);
+    cdf(ind) = 1 + 2 * sum (A);
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/laplace_cdf.m b/scripts/statistics/distributions/laplace_cdf.m
new file mode 100644
index 0000000..19fb919
--- /dev/null
+++ b/scripts/statistics/distributions/laplace_cdf.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} laplace_cdf (@var{x})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the Laplace distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Laplace distribution
+
+function cdf = laplace_cdf (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  cdf = zeros (size (x));
+
+  k = find (isnan (x));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find (x == Inf);
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x > -Inf) & (x < Inf));
+  if (any (k))
+    cdf(k) = (1 + sign (x(k)) .* (1 - exp (- abs (x(k))))) / 2;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/laplace_inv.m b/scripts/statistics/distributions/laplace_inv.m
new file mode 100644
index 0000000..ba717a9
--- /dev/null
+++ b/scripts/statistics/distributions/laplace_inv.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} laplace_inv (@var{x})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the Laplace distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Laplace distribution
+
+function inv = laplace_inv (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  inv = (-Inf) * ones (size (x));
+
+  k = find (isnan (x) | (x < 0) | (x > 1));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find (x == 1);
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1));
+  if (any (k))
+    inv(k) = ((x(k) < 1/2) .* log (2 * x(k))
+	      - (x(k) > 1/2) .* log (2 * (1 - x(k))));
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/laplace_pdf.m b/scripts/statistics/distributions/laplace_pdf.m
new file mode 100644
index 0000000..084f0fe
--- /dev/null
+++ b/scripts/statistics/distributions/laplace_pdf.m
@@ -0,0 +1,47 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} laplace_pdf (@var{x})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the Laplace distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Laplace distribution
+
+function pdf = laplace_pdf (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  pdf = zeros (size (x));
+
+  k = find (isnan (x));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find ((x > -Inf) & (x < Inf));
+  if (any (k))
+    pdf(k) = exp (- abs (x(k))) / 2;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/laplace_rnd.m b/scripts/statistics/distributions/laplace_rnd.m
new file mode 100644
index 0000000..d429197
--- /dev/null
+++ b/scripts/statistics/distributions/laplace_rnd.m
@@ -0,0 +1,57 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} laplace_rnd (@var{r}, @var{c})
+## @deftypefnx {Function File} {} laplace_rnd (@var{sz});
+## Return an @var{r} by @var{c} matrix of random numbers from the
+## Laplace distribution.  Or if @var{sz} is a vector, create a matrix of
+## @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Laplace distribution
+
+function rnd = laplace_rnd (r, c)
+
+  if (nargin == 2)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("laplace_rnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("laplace_rnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+  elseif (nargin == 1)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("laplace_rnd: r must be a positive integer or vector");
+    endif
+  else
+    print_usage ();
+  endif
+
+  tmp = rand (sz);
+  rnd = ((tmp < 1/2) .* log (2 * tmp)
+         - (tmp > 1/2) .* log (2 * (1 - tmp)));
+
+endfunction
diff --git a/scripts/statistics/distributions/logistic_cdf.m b/scripts/statistics/distributions/logistic_cdf.m
new file mode 100644
index 0000000..0d9b662
--- /dev/null
+++ b/scripts/statistics/distributions/logistic_cdf.m
@@ -0,0 +1,37 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logistic_cdf (@var{x})
+## For each component of @var{x}, compute the CDF at @var{x} of the
+## logistic distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the logistic distribution
+
+function cdf = logistic_cdf (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  cdf = 1 ./ (1 + exp (- x));
+
+endfunction
diff --git a/scripts/statistics/distributions/logistic_inv.m b/scripts/statistics/distributions/logistic_inv.m
new file mode 100644
index 0000000..c17575c
--- /dev/null
+++ b/scripts/statistics/distributions/logistic_inv.m
@@ -0,0 +1,57 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logistic_inv (@var{x})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the logistic distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the logistic distribution
+
+function inv = logistic_inv (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  inv = zeros (size (x));
+
+  k = find ((x < 0) | (x > 1) | isnan (x));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find (x == 0);
+  if (any (k))
+    inv(k) = -Inf;
+  endif
+
+  k = find (x == 1);
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1));
+  if (any (k))
+    inv (k) = - log (1 ./ x(k) - 1);
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/logistic_pdf.m b/scripts/statistics/distributions/logistic_pdf.m
new file mode 100644
index 0000000..6bdfad9
--- /dev/null
+++ b/scripts/statistics/distributions/logistic_pdf.m
@@ -0,0 +1,38 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logistic_pdf (@var{x})
+## For each component of @var{x}, compute the PDF at @var{x} of the
+## logistic distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the logistic distribution
+
+function pdf = logistic_pdf (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  cdf = logistic_cdf (x);
+  pdf = cdf .* (1 - cdf);
+
+endfunction
diff --git a/scripts/statistics/distributions/logistic_rnd.m b/scripts/statistics/distributions/logistic_rnd.m
new file mode 100644
index 0000000..e4209e3
--- /dev/null
+++ b/scripts/statistics/distributions/logistic_rnd.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logistic_rnd (@var{r}, @var{c})
+## @deftypefnx {Function File} {} logistic_rnd (@var{sz})
+## Return an @var{r} by @var{c} matrix of random numbers from the
+## logistic distribution.  Or if @var{sz} is a vector, create a matrix of
+## @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the logistic distribution
+
+function rnd = logistic_rnd (r, c)
+
+
+  if (nargin == 2)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("logistic_rnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("logistic_rnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+  elseif (nargin == 1)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("logistic_rnd: r must be a positive integer or vector");
+    endif
+  else
+    print_usage ();
+  endif
+
+  rnd = - log (1 ./ rand (sz) - 1);
+
+endfunction
diff --git a/scripts/statistics/distributions/logncdf.m b/scripts/statistics/distributions/logncdf.m
new file mode 100644
index 0000000..77472cb
--- /dev/null
+++ b/scripts/statistics/distributions/logncdf.m
@@ -0,0 +1,77 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logncdf (@var{x}, @var{mu}, @var{sigma})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the lognormal distribution with
+## parameters @var{mu} and @var{sigma}.  If a random variable follows this
+## distribution, its logarithm is normally distributed with mean
+## @var{mu} and standard deviation @var{sigma}.
+##
+## Default values are @var{mu} = 1, @var{sigma} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the log normal distribution
+
+function cdf = logncdf (x, mu, sigma)
+
+  if (! ((nargin == 1) || (nargin == 3)))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    mu = 0;
+    sigma = 1;
+  endif
+
+  ## The following "straightforward" implementation unfortunately does
+  ## not work (because exp (Inf) -> NaN etc):
+  ## cdf = normal_cdf (log (x), log (mu), sigma);
+  ## Hence ...
+
+  if (!isscalar (mu) || !isscalar (sigma))
+    [retval, x, mu, sigma] = common_size (x, mu, sigma);
+    if (retval > 0)
+      error ("logncdf: x, mu and sigma must be of common size or scalars");
+    endif
+  endif
+
+  cdf = zeros (size (x));
+
+  k = find (isnan (x) | !(sigma > 0) | !(sigma < Inf));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (sigma > 0) & (sigma < Inf));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & (sigma > 0) & (sigma < Inf));
+  if (any (k))
+    if (isscalar (mu) && isscalar (sigma))
+      cdf(k) = stdnormal_cdf ((log (x(k)) - mu) / sigma);
+    else
+      cdf(k) = stdnormal_cdf ((log (x(k)) - mu(k)) ./ sigma(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/logninv.m b/scripts/statistics/distributions/logninv.m
new file mode 100644
index 0000000..8fdb62a
--- /dev/null
+++ b/scripts/statistics/distributions/logninv.m
@@ -0,0 +1,77 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} logninv (@var{x}, @var{mu}, @var{sigma})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the lognormal distribution with parameters @var{mu}
+## and @var{sigma}.  If a random variable follows this distribution, its
+## logarithm is normally distributed with mean @code{log (@var{mu})} and
+## variance @var{sigma}.
+##
+## Default values are @var{mu} = 1, @var{sigma} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the log normal distribution
+
+function inv = logninv (x, mu, sigma)
+
+  if (! ((nargin == 1) || (nargin == 3)))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    mu = 0;
+    sigma = 1;
+  endif
+
+  ## The following "straightforward" implementation unfortunately does
+  ## not work (because exp (Inf) -> NaN):
+  ## inv = exp (norminv (x, mu, sigma));
+  ## Hence ...
+
+  if (!isscalar (mu) || !isscalar (sigma))
+    [retval, x, mu, sigma] = common_size (x, mu, sigma);
+    if (retval > 0)
+      error ("logninv: x, mu and sigma must be of common size or scalars");
+    endif
+  endif
+
+  inv = zeros (size (x));
+
+  k = find (!(x >= 0) | !(x <= 1) | !(sigma > 0) | !(sigma < Inf));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 1) & (sigma > 0) & (sigma < Inf));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (sigma > 0) & (sigma < Inf));
+  if (any (k))
+    if (isscalar (mu) && isscalar (sigma))
+      inv(k) = exp (mu) .* exp (sigma .* stdnormal_inv (x(k)));
+    else
+      inv(k) = exp (mu(k)) .* exp (sigma(k) .* stdnormal_inv (x(k)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/lognpdf.m b/scripts/statistics/distributions/lognpdf.m
new file mode 100644
index 0000000..a1762f9
--- /dev/null
+++ b/scripts/statistics/distributions/lognpdf.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lognpdf (@var{x}, @var{mu}, @var{sigma})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the lognormal distribution with parameters
+## @var{mu} and @var{sigma}.  If a random variable follows this distribution,
+## its logarithm is normally distributed with mean @var{mu}
+## and standard deviation @var{sigma}.
+##
+## Default values are @var{mu} = 1, @var{sigma} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the log normal distribution
+
+function pdf = lognpdf (x, mu, sigma)
+
+  if (! ((nargin == 1) || (nargin == 3)))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    mu = 0;
+    sigma = 1;
+  endif
+
+  ## The following "straightforward" implementation unfortunately does
+  ## not work for the special cases (Inf, ...)
+  ## pdf = (x > 0) ./ x .* normpdf (log (x), mu, sigma);
+  ## Hence ...
+
+  if (!isscalar (mu) || !isscalar (sigma))
+    [retval, x, mu, sigma] = common_size (x, mu, sigma);
+    if (retval > 0)
+      error ("lognpdf: x, mu and sigma must be of common size or scalars");
+    endif
+  endif
+
+  pdf = zeros (size (x));
+
+  k = find (isnan (x) | !(sigma > 0) | !(sigma < Inf));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & (sigma > 0) & (sigma < Inf));
+  if (any (k))
+    if (isscalar (mu) && isscalar (sigma))
+      pdf(k) = normpdf (log (x(k)), mu, sigma) ./ x(k);
+    else
+      pdf(k) = normpdf (log (x(k)), mu(k), sigma(k)) ./ x(k);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/lognrnd.m b/scripts/statistics/distributions/lognrnd.m
new file mode 100644
index 0000000..7305fe2
--- /dev/null
+++ b/scripts/statistics/distributions/lognrnd.m
@@ -0,0 +1,92 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} lognrnd (@var{mu}, @var{sigma}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} lognrnd (@var{mu}, @var{sigma}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## lognormal distribution with parameters @var{mu} and @var{sigma}.  Both
+## @var{mu} and @var{sigma} must be scalar or of size @var{r} by @var{c}.
+## Or if @var{sz} is a vector, create a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{mu} and @var{sigma}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the log normal distribution
+
+function rnd = lognrnd (mu, sigma, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(mu) || !isscalar(sigma)) 
+      [retval, mu, sigma] = common_size (mu, sigma);
+      if (retval > 0)
+	error ("lognrnd: mu and sigma must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("lognrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("lognrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (mu) != 1) && 
+	((length (size (mu)) != length (sz)) || any (size (mu) != sz)))
+      error ("lognrnd: mu and sigma must be scalar or of size [r, c]");
+    endif
+
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("lognrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (mu) != 1) && 
+	((length (size (mu)) != length (sz)) || any (size (mu) != sz)))
+      error ("lognrnd: mu and sigma must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(mu);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (mu) && isscalar (sigma))
+    if  (!(sigma > 0) || !(sigma < Inf))
+      rnd = NaN * ones (sz);
+    else
+      rnd = exp(mu + sigma .* randn (sz)); 
+    endif
+  else
+    rnd = exp (mu + sigma .* randn (sz));
+    k = find ((sigma < 0) | (sigma == Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/nbincdf.m b/scripts/statistics/distributions/nbincdf.m
new file mode 100644
index 0000000..f005fd2
--- /dev/null
+++ b/scripts/statistics/distributions/nbincdf.m
@@ -0,0 +1,92 @@
+## Copyright (C) 1995, 1996, 1997, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nbincdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the CDF at x of the Pascal
+## (negative binomial) distribution with parameters @var{n} and @var{p}.
+##
+## The number of failures in a Bernoulli experiment with success
+## probability @var{p} before the @var{n}-th success follows this
+## distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Pascal (negative binomial) distribution
+
+function cdf = nbincdf (x, n, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar(n) || !isscalar(p)) 
+    [retval, x, n, p] = common_size (x, n, p);
+    if (retval > 0)
+      error ("nbincdf: x, n and p must be of common size or scalar");
+    endif
+  endif
+  
+  cdf = zeros (size (x));
+
+  k = find (isnan (x) | (n < 1) | (n == Inf) | (n != round (n))
+	    | (p < 0) | (p > 1));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (n > 0) & (n < Inf) & (n == round (n))
+	    & (p >= 0) & (p <= 1));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x >= 0) & (x < Inf) & (x == round (x)) & (n > 0)
+	    & (n < Inf) & (n == round (n)) & (p > 0) & (p <= 1));
+  if (any (k))
+    ## Does anyone know a better way to do the summation?
+    m = zeros (size (k));
+    x = floor (x(k));
+    y = cdf(k);
+    if (isscalar (n) && isscalar (p))
+      while (1)
+	l = find (m <= x);
+	if (any (l))
+          y(l) = y(l) + nbinpdf (m(l), n, p);
+          m(l) = m(l) + 1;
+	else
+          break;
+	endif
+      endwhile
+    else
+      n = n(k);
+      p = p(k);
+      while (1)
+	l = find (m <= x);
+	if (any (l))
+          y(l) = y(l) + nbinpdf (m(l), n(l), p(l));
+          m(l) = m(l) + 1;
+	else
+          break;
+	endif
+      endwhile
+    endif
+    cdf(k) = y;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/nbininv.m b/scripts/statistics/distributions/nbininv.m
new file mode 100644
index 0000000..077df77
--- /dev/null
+++ b/scripts/statistics/distributions/nbininv.m
@@ -0,0 +1,93 @@
+## Copyright (C) 1995, 1996, 1997, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nbininv (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the quantile at @var{x} of the
+## Pascal (negative binomial) distribution with parameters @var{n} and
+## @var{p}.
+##
+## The number of failures in a Bernoulli experiment with success
+## probability @var{p} before the @var{n}-th success follows this
+## distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Pascal distribution
+
+function inv = nbininv (x, n, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar(n) || !isscalar(p)) 
+    [retval, x, n, p] = common_size (x, n, p);
+    if (retval > 0)
+      error ("nbininv: x, n and p must be of common size or scalar");
+    endif
+  endif
+
+  inv = zeros (size (x));
+
+  k = find (isnan (x) | (x < 0) | (x > 1) | (n < 1) | (n == Inf)
+	    | (n != round (n)) | (p < 0) | (p > 1));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 1) & (n > 0) & (n < Inf) & (n == round (n))
+	    & (p >= 0) & (p <= 1));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x >= 0) & (x < 1) & (n > 0) & (n < Inf)
+	    & (n == round (n)) & (p > 0) & (p <= 1));
+  if (any (k))
+    m = zeros (size (k));
+    x = x(k);
+    if (isscalar (n) && isscalar (p))
+      s = p ^ n * ones (size(k));
+      while (1)
+	l = find (s < x);
+	if (any (l))
+          m(l) = m(l) + 1;
+          s(l) = s(l) + nbinpdf (m(l), n, p);
+	else
+          break;
+	endif
+      endwhile
+    else
+      n = n(k);
+      p = p(k);
+      s = p .^ n;
+      while (1)
+	l = find (s < x);
+	if (any (l))
+          m(l) = m(l) + 1;
+          s(l) = s(l) + nbinpdf (m(l), n(l), p(l));
+	else
+          break;
+	endif
+      endwhile
+    endif
+    inv(k) = m;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/nbinpdf.m b/scripts/statistics/distributions/nbinpdf.m
new file mode 100644
index 0000000..4c5e234
--- /dev/null
+++ b/scripts/statistics/distributions/nbinpdf.m
@@ -0,0 +1,71 @@
+## Copyright (C) 1995, 1996, 1997, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nbinpdf (@var{x}, @var{n}, @var{p})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the Pascal (negative binomial) distribution with
+## parameters @var{n} and @var{p}.
+##
+## The number of failures in a Bernoulli experiment with success
+## probability @var{p} before the @var{n}-th success follows this
+## distribution. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Pascal (negative binomial) distribution
+
+function pdf = nbinpdf (x, n, p)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (!isscalar(n) || !isscalar(p)) 
+    [retval, x, n, p] = common_size (x, n, p);
+    if (retval > 0)
+      error ("nbinpdf: x, n and p must be of common size or scalar");
+    endif
+  endif
+
+  pdf = zeros (size (x));
+
+  k = find (isnan (x) | (n < 1) | (n == Inf) | (n != round (n))
+	    | (p < 0) | (p > 1));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  ## Just for the fun of it ...
+  k = find ((x == Inf) & (n > 0) & (n < Inf) & (n == round (n))
+	    & (p == 0));
+  if (any (k))
+    pdf(k) = 1;
+  endif
+
+  k = find ((x >= 0) & (x < Inf) & (x == round (x)) & (n > 0)
+	    & (n < Inf) & (n == round (n)) & (p > 0) & (p <= 1));
+  if (any (k))
+    if (isscalar (n) && isscalar (p))
+      pdf(k) = bincoeff (-n, x(k)) .* (p ^ n) .* ((p - 1) .^ x(k));
+    else
+      pdf(k) = bincoeff (-n(k), x(k)) .* (p(k) .^ n(k)) .* ((p(k) - 1) .^ x(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/nbinrnd.m b/scripts/statistics/distributions/nbinrnd.m
new file mode 100644
index 0000000..aa8f3b3
--- /dev/null
+++ b/scripts/statistics/distributions/nbinrnd.m
@@ -0,0 +1,102 @@
+## Copyright (C) 1995, 1996, 1997, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nbinrnd (@var{n}, @var{p}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} nbinrnd (@var{n}, @var{p}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the Pascal
+## (negative binomial) distribution with parameters @var{n} and @var{p}.
+## Both @var{n} and @var{p} must be scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{n} and @var{p}.  Or if @var{sz} is a vector, 
+## create a matrix of size @var{sz}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Pascal distribution
+
+function rnd = nbinrnd (n, p, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(n) || !isscalar(p)) 
+      [retval, n, p] = common_size (n, p);
+      if (retval > 0)
+	error ("nbinrnd: n and p must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("nbinrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("nbinrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (n) != 1) && 
+	((length (size (n)) != length (sz)) || any (size (n) != sz)))
+      error ("nbinrnd: n and p must be scalar or of size [r, c]");
+    endif
+
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("nbinrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (n) != 1) && 
+	((length (size (n)) != length (sz)) || any (size (n) != sz)))
+      error ("nbinrnd: n and p must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(n);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (n) && isscalar (p))
+    if ((n < 1) || (n == Inf) || (n != round (n)) || (p <= 0) || (p > 1));
+      rnd = NaN * ones (sz);
+    elseif ((n > 0) && (n < Inf) && (n == round (n)) && 
+	    (p > 0) && (p <= 1))
+      rnd = randp ((1 - p) ./ p .* randg (n, sz));
+    else
+      rnd = zeros (sz);
+    endif
+  else
+    rnd = zeros (sz);
+
+    k = find ((n < 1) || (n == Inf) || (n != round (n)) || 
+	      (p <= 0) || (p > 1));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+
+    k = find ((n > 0) & (n < Inf) & (n == round (n)) & (p > 0) & (p <= 1));
+    if (any (k))
+      rnd(k) = randp ((1 - p(k)) ./ p(k) .* randg (n(k), size(k)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/normcdf.m b/scripts/statistics/distributions/normcdf.m
new file mode 100644
index 0000000..c2aafc4
--- /dev/null
+++ b/scripts/statistics/distributions/normcdf.m
@@ -0,0 +1,72 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normcdf (@var{x}, @var{m}, @var{s})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the normal distribution with mean
+## @var{m} and standard deviation @var{s}.
+##
+## Default values are @var{m} = 0, @var{s} = 1.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: CDF of the normal distribution
+
+function cdf = normcdf (x, m, s)
+
+  if (! ((nargin == 1) || (nargin == 3)))
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    m = 0;
+    s = 1;
+  endif
+
+  if (!isscalar (m) || !isscalar (s))
+    [retval, x, m, s] = common_size (x, m, s);
+    if (retval > 0)
+      error ("normcdf: x, m and s must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  cdf = zeros (sz);
+
+  if (isscalar (m) && isscalar(s))
+    if (find (isinf (m) | isnan (m) | !(s >= 0) | !(s < Inf)))
+      cdf = NaN * ones (sz);
+    else
+      cdf =  stdnormal_cdf ((x - m) ./ s);
+    endif
+  else
+    k = find (isinf (m) | isnan (m) | !(s >= 0) | !(s < Inf));
+    if (any (k))
+      cdf(k) = NaN;
+    endif
+
+    k = find (!isinf (m) & !isnan (m) & (s >= 0) & (s < Inf));
+    if (any (k))
+      cdf(k) = stdnormal_cdf ((x(k) - m(k)) ./ s(k));
+    endif
+  endif
+
+  cdf((s == 0) & (x == m)) = 0.5;
+
+endfunction
diff --git a/scripts/statistics/distributions/norminv.m b/scripts/statistics/distributions/norminv.m
new file mode 100644
index 0000000..3cd3516
--- /dev/null
+++ b/scripts/statistics/distributions/norminv.m
@@ -0,0 +1,78 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} norminv (@var{x}, @var{m}, @var{s})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the normal distribution with mean @var{m} and
+## standard deviation @var{s}.
+##
+## Default values are @var{m} = 0, @var{s} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the normal distribution
+
+function inv = norminv (x, m, s)
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    m = 0;
+    s = 1;
+  endif
+
+  if (!isscalar (m) || !isscalar (s))
+    [retval, x, m, s] = common_size (x, m, s);
+    if (retval > 0)
+      error ("norminv: x, m and s must be of common size or scalars");
+    endif
+  endif
+
+  sz = size (x);
+  inv = zeros (sz);
+
+  if (isscalar (m) && isscalar (s))
+    if (find (isinf (m) | isnan (m) | !(s > 0) | !(s < Inf)))
+      inv = NaN * ones (sz);
+    else
+      inv =  m + s .* stdnormal_inv (x);
+    endif
+  else
+    k = find (isinf (m) | isnan (m) | !(s > 0) | !(s < Inf));
+    if (any (k))
+      inv(k) = NaN;
+    endif
+
+    k = find (!isinf (m) & !isnan (m) & (s > 0) & (s < Inf));
+    if (any (k))
+      inv(k) = m(k) + s(k) .* stdnormal_inv (x(k));
+    endif
+  endif
+
+  k = find ((s == 0) & (x > 0) & (x < 1));
+  if (any (k))
+    inv(k) = m(k);
+  endif
+
+  inv((s == 0) & (x == 0)) = -Inf;
+  inv((s == 0) & (x == 1)) = Inf;
+
+endfunction
diff --git a/scripts/statistics/distributions/normpdf.m b/scripts/statistics/distributions/normpdf.m
new file mode 100644
index 0000000..ca91a06
--- /dev/null
+++ b/scripts/statistics/distributions/normpdf.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normpdf (@var{x}, @var{m}, @var{s})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the normal distribution with mean @var{m} and
+## standard deviation @var{s}.
+##
+## Default values are @var{m} = 0, @var{s} = 1.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the normal distribution
+
+function pdf = normpdf (x, m, s)
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    m = 0;
+    s = 1;
+  endif
+
+  if (!isscalar (m) || !isscalar (s))
+    [retval, x, m, s] = common_size (x, m, s);
+    if (retval > 0)
+      error ("normpdf: x, m and s must be of common size or scalars");
+    endif
+  endif
+
+  sz = size (x);
+  pdf = zeros (sz);
+
+  if (isscalar (m) && isscalar (s))
+    if (find (isinf (m) | isnan (m) | !(s >= 0) | !(s < Inf)))
+      pdf = NaN * ones (sz);
+    else
+      pdf = stdnormal_pdf ((x - m) ./ s) ./ s;
+    endif
+  else
+    k = find (isinf (m) | isnan (m) | !(s >= 0) | !(s < Inf));
+    if (any (k))
+      pdf(k) = NaN;
+    endif
+
+    k = find (!isinf (m) & !isnan (m) & (s >= 0) & (s < Inf));
+    if (any (k))
+      pdf(k) = stdnormal_pdf ((x(k) - m(k)) ./ s(k)) ./ s(k);
+    endif
+  endif
+
+  pdf((s == 0) & (x == m)) = Inf;
+  pdf((s == 0) & ((x < m) | (x > m))) = 0;
+
+endfunction
diff --git a/scripts/statistics/distributions/normrnd.m b/scripts/statistics/distributions/normrnd.m
new file mode 100644
index 0000000..a3505b1
--- /dev/null
+++ b/scripts/statistics/distributions/normrnd.m
@@ -0,0 +1,91 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} normrnd (@var{m}, @var{s}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} normrnd (@var{m}, @var{s}, @var{sz})
+## Return an @var{r} by @var{c}  or @code{size (@var{sz})} matrix of
+## random samples from the normal distribution with parameters mean @var{m} 
+## and standard deviation @var{s}.  Both @var{m} and @var{s} must be scalar 
+## or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{m} and @var{s}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the normal distribution
+
+function rnd = normrnd (m, s, r, c)
+
+  if (nargin > 1)
+    if (!isscalar (m) || !isscalar (s)) 
+      [retval, m, s] = common_size (m, s);
+      if (retval > 0)
+	error ("normrnd: m and s must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("normrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("normrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (m) != 1)
+	&& (length (size (m)) != length (sz) || any (size (m) != sz)))
+      error ("normrnd: m and s must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("normrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (m) != 1)
+	&& (length (size (m)) != length (sz) || any (size (m) != sz)))
+      error ("normrnd: m and s must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(m);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (m) && isscalar (s))
+    if (find (isnan (m) | isinf (m) | !(s > 0) | !(s < Inf)))
+      rnd = NaN * ones (sz);
+    else
+      rnd =  m + s .* randn (sz);
+    endif
+  else
+    rnd = m + s .* randn (sz);
+    k = find (isnan (m) | isinf (m) | !(s > 0) | !(s < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/poisscdf.m b/scripts/statistics/distributions/poisscdf.m
new file mode 100644
index 0000000..14b4edd
--- /dev/null
+++ b/scripts/statistics/distributions/poisscdf.m
@@ -0,0 +1,63 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poisscdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the Poisson distribution with parameter
+## lambda.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Poisson distribution
+
+function cdf = poisscdf (x, l)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (l))
+    [retval, x, l] = common_size (x, l);
+    if (retval > 0)
+      error ("poisscdf: x and lambda must be of common size or scalar");
+    endif
+  endif
+
+  cdf = zeros (size (x));
+
+  k = find (isnan (x) | !(l > 0));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (l > 0));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x >= 0) & (x < Inf) & (l > 0));
+  if (any (k))
+    if (isscalar (l))
+      cdf(k) = 1 - gammainc (l, floor (x(k)) + 1);
+    else
+      cdf(k) = 1 - gammainc (l(k), floor (x(k)) + 1);
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/poissinv.m b/scripts/statistics/distributions/poissinv.m
new file mode 100644
index 0000000..0b826cf
--- /dev/null
+++ b/scripts/statistics/distributions/poissinv.m
@@ -0,0 +1,76 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poissinv (@var{x}, @var{lambda})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the Poisson distribution with parameter
+## @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Poisson distribution
+
+function inv = poissinv (x, l)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (l))
+    [retval, x, l] = common_size (x, l);
+    if (retval > 0)
+      error ("poissinv: x and lambda must be of common size or scalar");
+    endif
+  endif
+
+  inv = zeros (size (x));
+
+  k = find ((x < 0) | (x > 1) | isnan (x) | !(l > 0));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 1) & (l > 0));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (l > 0));
+  if (any (k))
+    if (isscalar (l))
+      cdf = exp (-l) * ones (size (k));
+    else
+      cdf = exp (-l(k));
+    endif
+    while (1)
+      m = find (cdf < x(k));
+      if (any (m))
+        inv(k(m)) = inv(k(m)) + 1;
+	if (isscalar (l))
+          cdf(m) = cdf(m) + poisspdf (inv(k(m)), l);
+	else
+          cdf(m) = cdf(m) + poisspdf (inv(k(m)), l(k(m)));
+	endif
+      else
+        break;
+      endif
+    endwhile
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/poisspdf.m b/scripts/statistics/distributions/poisspdf.m
new file mode 100644
index 0000000..2afadc7
--- /dev/null
+++ b/scripts/statistics/distributions/poisspdf.m
@@ -0,0 +1,57 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poisspdf (@var{x}, @var{lambda})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the poisson distribution with parameter @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Poisson distribution
+
+function pdf = poisspdf (x, l)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (l))
+    [retval, x, l] = common_size (x, l);
+    if (retval > 0)
+      error ("poisspdf: x and lambda must be of common size or scalar");
+    endif
+  endif
+
+  pdf = zeros (size (x));
+
+  k = find (!(l > 0) | isnan (x));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find ((x >= 0) & (x < Inf) & (x == round (x)) & (l > 0));
+  if (any (k))
+    if (isscalar (l))
+      pdf(k) = exp (x(k) .* log (l) - l - gammaln (x(k) + 1));
+    else
+      pdf(k) = exp (x(k) .* log (l(k)) - l(k) - gammaln (x(k) + 1));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/poissrnd.m b/scripts/statistics/distributions/poissrnd.m
new file mode 100644
index 0000000..39bc15e
--- /dev/null
+++ b/scripts/statistics/distributions/poissrnd.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} poissrnd (@var{lambda}, @var{r}, @var{c})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## Poisson distribution with parameter @var{lambda}, which must be a 
+## scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{lambda}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Poisson distribution
+
+function rnd = poissrnd (l, r, c)
+
+  if (nargin == 3)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("poissrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("poissrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (l) != 1) && 
+	((length (size (l)) != length (sz)) || any (size (l) != sz)))
+      error ("poissrnd: lambda must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 2)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("poissrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (l) != 1) && 
+	((length (size (l)) != length (sz)) || any (size (l) != sz)))
+      error ("poissrnd: lambda must be scalar or of size sz");
+    endif
+  elseif (nargin == 1)
+    sz = size (l);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (l))
+
+    if (!(l >= 0) | !(l < Inf))
+      rnd = NaN * ones (sz);
+    elseif ((l > 0) & (l < Inf))
+      rnd = randp(l, sz);
+    else
+      rnd = zeros (sz);
+    endif
+  else
+    rnd = zeros (sz);
+
+    k = find (!(l >= 0) | !(l < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+
+    k = find ((l > 0) & (l < Inf));
+    if (any (k))
+      rnd(k) = randp(l(k), size(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/stdnormal_cdf.m b/scripts/statistics/distributions/stdnormal_cdf.m
new file mode 100644
index 0000000..4722288
--- /dev/null
+++ b/scripts/statistics/distributions/stdnormal_cdf.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} stdnormal_cdf (@var{x})
+## For each component of @var{x}, compute the CDF of the standard normal
+## distribution at @var{x}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the standard normal distribution
+
+function cdf = stdnormal_cdf (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  sz = size (x);
+  if (numel(x) == 0)
+    error ("stdnormal_cdf: x must not be empty");
+  endif
+
+  cdf = (ones (sz) + erf (x / sqrt (2))) / 2;
+
+endfunction
+
+
+
+
diff --git a/scripts/statistics/distributions/stdnormal_inv.m b/scripts/statistics/distributions/stdnormal_inv.m
new file mode 100644
index 0000000..fa6721c
--- /dev/null
+++ b/scripts/statistics/distributions/stdnormal_inv.m
@@ -0,0 +1,37 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} stdnormal_inv (@var{x})
+## For each component of @var{x}, compute the quantile (the
+## inverse of the CDF) at @var{x} of the standard normal distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the standard normal distribution
+
+function inv = stdnormal_inv (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  inv = sqrt (2) * erfinv (2 * x - 1);
+
+endfunction
diff --git a/scripts/statistics/distributions/stdnormal_pdf.m b/scripts/statistics/distributions/stdnormal_pdf.m
new file mode 100644
index 0000000..8610997
--- /dev/null
+++ b/scripts/statistics/distributions/stdnormal_pdf.m
@@ -0,0 +1,48 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} stdnormal_pdf (@var{x})
+## For each element of @var{x}, compute the probability density function
+## (PDF) of the standard normal distribution at @var{x}.
+## @end deftypefn
+
+## Author: TT <Teresa.Twaroch at ci.tuwien.ac.at>
+## Description: PDF of the standard normal distribution
+
+function pdf = stdnormal_pdf (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  sz = size(x);
+  pdf = zeros (sz);
+
+  k = find (isnan (x));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find (!isinf (x));
+  if (any (k))
+    pdf (k) = (2 * pi)^(- 1/2) * exp (- x(k) .^ 2 / 2);
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/stdnormal_rnd.m b/scripts/statistics/distributions/stdnormal_rnd.m
new file mode 100644
index 0000000..8762fef
--- /dev/null
+++ b/scripts/statistics/distributions/stdnormal_rnd.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} stdnormal_rnd (@var{r}, @var{c})
+## @deftypefnx {Function File} {} stdnormal_rnd (@var{sz})
+## Return an @var{r} by @var{c} or @code{size (@var{sz})} matrix of 
+## random numbers from the standard normal distribution.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the standard normal distribution
+
+function rnd = stdnormal_rnd (r, c)
+
+  if (nargin != 1 && nargin != 2)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("stdnormal_rnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("stdnormal_rnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+  else
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("stdnormal_rnd: r must be a positive integer or vector");
+    endif
+  endif
+
+  rnd = randn (sz);
+
+endfunction
diff --git a/scripts/statistics/distributions/tcdf.m b/scripts/statistics/distributions/tcdf.m
new file mode 100644
index 0000000..41f5001
--- /dev/null
+++ b/scripts/statistics/distributions/tcdf.m
@@ -0,0 +1,67 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} tcdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of the t (Student) distribution with
+## @var{n} degrees of freedom, i.e., PROB (t(@var{n}) <= @var{x}).
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the t distribution
+
+function cdf = tcdf (x, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (n))
+    [retval, x, n] = common_size (x, n);
+    if (retval > 0)
+      error ("tcdf: x and n must be of common size or scalar");
+    endif
+  endif
+
+  cdf = zeros (size (x));
+
+  k = find (isnan (x) | !(n > 0));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x == Inf) & (n > 0));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+  k = find ((x > -Inf) & (x < Inf) & (n > 0));
+  if (any (k))
+    if (isscalar (n))
+      cdf(k) = betainc (1 ./ (1 + x(k) .^ 2 ./ n), n / 2, 1 / 2) / 2;
+    else
+      cdf(k) = betainc (1 ./ (1 + x(k) .^ 2 ./ n(k)), n(k) / 2, 1 / 2) / 2;
+    endif
+    ind = find (x(k) > 0);
+    if (any (ind))
+      cdf(k(ind)) = 1 - cdf(k(ind));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/tinv.m b/scripts/statistics/distributions/tinv.m
new file mode 100644
index 0000000..972d04f
--- /dev/null
+++ b/scripts/statistics/distributions/tinv.m
@@ -0,0 +1,84 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} tinv (@var{x}, @var{n})
+## For each probability value @var{x}, compute the inverse of the
+## cumulative distribution function (CDF) of the t (Student)
+## distribution with degrees of freedom @var{n}.  This function is
+## analogous to looking in a table for the t-value of a single-tailed
+## distribution.
+## @end deftypefn
+
+## For very large n, the "correct" formula does not really work well,
+## and the quantiles of the standard normal distribution are used
+## directly.
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the t distribution
+
+function inv = tinv (x, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (n))
+    [retval, x, n] = common_size (x, n);
+    if (retval > 0)
+      error ("tinv: x and n must be of common size or scalar");
+    endif
+  endif
+
+  inv = zeros (size (x));
+
+  k = find ((x < 0) | (x > 1) | isnan (x) | !(n > 0));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x == 0) & (n > 0));
+  if (any (k))
+    inv(k) = -Inf;
+  endif
+
+  k = find ((x == 1) & (n > 0));
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & (n > 0) & (n < 10000));
+  if (any (k))
+    if (isscalar (n))
+      inv(k) = (sign (x(k) - 1/2)
+		.* sqrt (n .* (1 ./ betainv (2*min (x(k), 1 - x(k)),
+						 n/2, 1/2) - 1)));
+    else
+      inv(k) = (sign (x(k) - 1/2)
+		.* sqrt (n(k) .* (1 ./ betainv (2*min (x(k), 1 - x(k)),
+						 n(k)/2, 1/2) - 1)));
+    endif
+  endif
+
+  ## For large n, use the quantiles of the standard normal
+  k = find ((x > 0) & (x < 1) & (n >= 10000));
+  if (any (k))
+    inv(k) = stdnormal_inv (x(k));
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/tpdf.m b/scripts/statistics/distributions/tpdf.m
new file mode 100644
index 0000000..933c155
--- /dev/null
+++ b/scripts/statistics/distributions/tpdf.m
@@ -0,0 +1,60 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} tpdf (@var{x}, @var{n})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of the @var{t} (Student) distribution with @var{n}
+## degrees of freedom. 
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the t distribution
+
+function pdf = tpdf (x, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (!isscalar (n))
+    [retval, x, n] = common_size (x, n);
+    if (retval > 0)
+      error ("tpdf: x and n must be of common size or scalar");
+    endif
+  endif
+
+  pdf = zeros (size (x));
+
+  k = find (isnan (x) | !(n > 0) | !(n < Inf));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find (!isinf (x) & !isnan (x) & (n > 0) & (n < Inf));
+  if (any (k))
+    if (isscalar (n))
+      pdf(k) = (exp (- (n + 1) .* log (1 + x(k) .^ 2 ./ n)/2)
+		/ (sqrt (n) * beta (n/2, 1/2)));
+    else
+      pdf(k) = (exp (- (n(k) + 1) .* log (1 + x(k) .^ 2 ./ n(k))/2)
+		./ (sqrt (n(k)) .* beta (n(k)/2, 1/2)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/trnd.m b/scripts/statistics/distributions/trnd.m
new file mode 100644
index 0000000..09250ce
--- /dev/null
+++ b/scripts/statistics/distributions/trnd.m
@@ -0,0 +1,90 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} trnd (@var{n}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} trnd (@var{n}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the t
+## (Student) distribution with @var{n} degrees of freedom.  @var{n} must
+## be a scalar or of size @var{r} by @var{c}.  Or if @var{sz} is a
+## vector create a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the size of @var{n}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the t distribution
+
+function rnd = trnd (n, r, c)
+
+  if (nargin == 3)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("trnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("trnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (n) != 1) && 
+	((length (size (n)) != length (sz)) || any (size (n) != sz)))
+      error ("trnd: n must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("trnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (n) != 1) && 
+	((length (size (n)) != length (sz)) || any (size (n) != sz)))
+      error ("trnd: n must be scalar or of size sz");
+    endif
+  elseif (nargin == 1)
+    sz = size (n);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (n))
+    if (!(n > 0) || !(n < Inf))
+      rnd = NaN * ones (sz);
+    elseif ((n > 0) && (n < Inf))
+      rnd = randn(sz) ./ sqrt(2*randg(n/2,sz)./n); 
+    else
+      rnd = zeros (size (n));
+    endif
+  else
+    rnd = zeros (size (n));
+
+    k = find (!(n > 0) | !(n < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+
+    k = find ((n > 0) & (n < Inf));
+    if (any (k))
+      rnd(k) = randn(size(k)) ./ sqrt(2*randg(n(k)/2,size(k))./n(k)); 
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/unidcdf.m b/scripts/statistics/distributions/unidcdf.m
new file mode 100644
index 0000000..d345ae3
--- /dev/null
+++ b/scripts/statistics/distributions/unidcdf.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2007 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unidcdf (@var{x}, @var{v})
+## For each element of @var{x}, compute the cumulative distribution
+## function (CDF) at @var{x} of a univariate discrete distribution which
+## assumes the values in @var{v} with equal probability.
+## @end deftypefn
+
+function cdf = unidcdf (x, v)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isscalar(v))
+    v = [1:v].';
+  else
+    v = v(:);
+  endif
+
+  cdf = discrete_cdf (x, v, ones(size(v)));
+endfunction
diff --git a/scripts/statistics/distributions/unidinv.m b/scripts/statistics/distributions/unidinv.m
new file mode 100644
index 0000000..36e5be5
--- /dev/null
+++ b/scripts/statistics/distributions/unidinv.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2007 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unidinv (@var{x}, @var{v})
+## For each component of @var{x}, compute the quantile (the inverse of
+## the CDF) at @var{x} of the univariate discrete distribution which assumes the
+## values in @var{v} with equal probability
+## @end deftypefn
+
+function inv = unidinv (x, v)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isscalar(v))
+    v = [1:v].';
+  else
+    v = v(:);
+  endif
+
+  inv = discrete_inv (x, v, ones(size(v)));
+endfunction
diff --git a/scripts/statistics/distributions/unidpdf.m b/scripts/statistics/distributions/unidpdf.m
new file mode 100644
index 0000000..6f0bd8d
--- /dev/null
+++ b/scripts/statistics/distributions/unidpdf.m
@@ -0,0 +1,39 @@
+## Copyright (C) 2007 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unidpdf (@var{x}, @var{v})
+## For each element of @var{x}, compute the probability density function
+## (PDF) at @var{x} of a univariate discrete distribution which assumes
+## the values in @var{v} with equal probability.
+## @end deftypefn
+
+function pdf = unidpdf (x, v)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isscalar(v))
+    v = [1:v].';
+  else
+    v = v(:);
+  endif
+
+  pdf = discrete_pdf (x, v, ones(size(v)));
+endfunction
diff --git a/scripts/statistics/distributions/unidrnd.m b/scripts/statistics/distributions/unidrnd.m
new file mode 100644
index 0000000..e9f2e4f
--- /dev/null
+++ b/scripts/statistics/distributions/unidrnd.m
@@ -0,0 +1,60 @@
+## Copyright (C) 2005, 2007 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unidrnd (@var{mx});
+## @deftypefnx {Function File} {} unidrnd (@var{mx}, @var{v});
+## @deftypefnx {Function File} {} unidrnd (@var{mx}, @var{m}, @var{n}, @dots{});
+## Return random values from discrete uniform distribution, with maximum
+## value(s) given by the integer @var{mx}, which may be a scalar or
+## multidimensional array.
+##
+## If @var{mx} is a scalar, the size of the result is specified by
+## the vector @var{v}, or by the optional arguments @var{m}, @var{n},
+## @dots{}.  Otherwise, the size of the result is the same as the size
+## of @var{mx}.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = unidrnd (n, varargin)
+  if (nargin == 1)
+    dims = size (n);
+  elseif (nargin == 2)
+    if (rows (varargin{1}) == 1 && columns (varargin{1}) > 1)
+      dims = varargin{1};
+    else
+      error ("unidrnd: invalid dimension vector");
+    endif
+  elseif (nargin > 2)
+    for i = 1:nargin-1
+      if (! isscalar (varargin{i}))
+	error ("unidrnd: expecting scalar dimensions");
+      endif
+    endfor
+    dims = [varargin{:}];
+  else
+    error ("unidrnd (n, ...)");
+  endif
+  if (isscalar (n)
+      || (length (size (n)) == length (dims) && all (size (n) == dims)))
+    retval = ceil (rand (dims) .* n);
+  else
+    error ("unidrnd: dimension mismatch");
+  endif
+endfunction
diff --git a/scripts/statistics/distributions/unifcdf.m b/scripts/statistics/distributions/unifcdf.m
new file mode 100644
index 0000000..60a64b7
--- /dev/null
+++ b/scripts/statistics/distributions/unifcdf.m
@@ -0,0 +1,70 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unifcdf (@var{x}, @var{a}, @var{b})
+## Return the CDF at @var{x} of the uniform distribution on [@var{a},
+## @var{b}], i.e., PROB (uniform (@var{a}, @var{b}) <= x).
+##
+## Default values are @var{a} = 0, @var{b} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the uniform distribution
+
+function cdf = unifcdf (x, a, b)
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    a = 0;
+    b = 1;
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("unifcdf: x, a and b must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  cdf = zeros (sz);
+
+  k = find (isnan (x) | !(a < b));
+  if (any (k))
+    cdf(k) = NaN;
+  endif
+
+  k = find ((x >= b) & (a < b));
+  if (any (k))
+    cdf(k) = 1;
+  endif
+  
+  k = find ((x > a) & (x < b));
+  if (any (k))
+    if (isscalar (a) && isscalar(b))
+      cdf(k) = (x(k) < b) .* (x(k) - a) ./ (b - a);
+    else
+      cdf(k) = (x(k) < b(k)) .* (x(k) - a(k)) ./ (b(k) - a(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/unifinv.m b/scripts/statistics/distributions/unifinv.m
new file mode 100644
index 0000000..2e6083d
--- /dev/null
+++ b/scripts/statistics/distributions/unifinv.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unifinv (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, compute the quantile (the inverse of the
+## CDF) at @var{x} of the uniform distribution on [@var{a}, @var{b}].
+##
+## Default values are @var{a} = 0, @var{b} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the uniform distribution
+
+function inv = unifinv (x, a, b)
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    a = 0;
+    b = 1;
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("uniform_cdf: x, a and b must be of common size or scalar");
+    endif
+  endif
+
+  sz = size (x);
+  inv = zeros (sz);
+
+  k = find ((x < 0) | (x > 1) | isnan (x) | !(a < b));
+  if (any (k))
+    inv(k) = NaN;
+  endif
+
+  k = find ((x >= 0) & (x <= 1) & (a < b));
+  if (any (k))
+    if (isscalar (a) && isscalar(b))
+      inv(k) = a + x(k) .* (b - a);
+    else
+      inv(k) = a(k) + x(k) .* (b(k) - a(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/unifpdf.m b/scripts/statistics/distributions/unifpdf.m
new file mode 100644
index 0000000..7f6c93d
--- /dev/null
+++ b/scripts/statistics/distributions/unifpdf.m
@@ -0,0 +1,65 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unifpdf (@var{x}, @var{a}, @var{b})
+## For each element of @var{x}, compute the PDF at @var{x} of the uniform
+## distribution on [@var{a}, @var{b}].
+##
+## Default values are @var{a} = 0, @var{b} = 1.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the uniform distribution
+
+function pdf = unifpdf (x, a, b)
+
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    a = 0;
+    b = 1;
+  endif
+
+  if (!isscalar (a) || !isscalar(b))
+    [retval, x, a, b] = common_size (x, a, b);
+    if (retval > 0)
+      error ("unifpdf: x, a and b must be of common size or scalars");
+    endif
+  endif
+
+  sz = size (x);
+  pdf = zeros (sz);
+
+  k = find (isnan (x) | !(a < b));
+  if (any (k))
+    pdf(k) = NaN;
+  endif
+
+  k = find ((x > a) & (x < b));
+  if (any (k))
+    if (isscalar (a) && isscalar(b))
+      pdf(k) = 1 ./ (b - a);
+    else
+      pdf(k) = 1 ./ (b(k) - a(k));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/unifrnd.m b/scripts/statistics/distributions/unifrnd.m
new file mode 100644
index 0000000..6c88484
--- /dev/null
+++ b/scripts/statistics/distributions/unifrnd.m
@@ -0,0 +1,91 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} unifrnd (@var{a}, @var{b}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} unifrnd (@var{a}, @var{b}, @var{sz})
+## Return an @var{r} by @var{c} or a @code{size (@var{sz})} matrix of 
+## random samples from the uniform distribution on [@var{a}, @var{b}]. 
+## Both @var{a} and @var{b} must be scalar or of size @var{r} by @var{c}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{a} and @var{b}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the uniform distribution
+
+function rnd = unifrnd (a, b, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(a) || !isscalar(b)) 
+      [retval, a, b] = common_size (a, b);
+      if (retval > 0)
+	error ("unifrnd: a and b must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("unifrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("unifrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (a) != 1)
+	&& (length (size (a)) != length (sz) || any (size (a) != sz)))
+      error ("unifrnd: a and b must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("unifrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (a) != 1)
+	&& (length (size (a)) != length (sz) || any (size (a) != sz)))
+      error ("unifrnd: a and b must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(a);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar(a) && isscalar(b))
+    if (find (!(-Inf < a) | !(a < b) | !(b < Inf)))
+      rnd = NaN * ones(sz);
+    else
+      rnd =  a + (b - a) .* rand (sz);
+    endif
+  else
+    rnd =  a + (b - a) .* rand (sz);
+
+    k = find (!(-Inf < a) | !(a < b) | !(b < Inf));
+    if (any (k))
+      rnd(k) = NaN;
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/wblcdf.m b/scripts/statistics/distributions/wblcdf.m
new file mode 100644
index 0000000..b9401d3
--- /dev/null
+++ b/scripts/statistics/distributions/wblcdf.m
@@ -0,0 +1,84 @@
+## Copyright (C) 1995, 1996, 1997, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wblcdf (@var{x}, @var{scale}, @var{shape})
+## Compute the cumulative distribution function (CDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape}, which is
+##
+## @tex
+## $$ 1 - \exp(-(x/shape)^{scale}) $$
+## for $x\geq 0$.
+## @end tex
+## @ifnottex
+## @example
+## 1 - exp(-(x/shape)^scale)
+## @end example
+## for @var{x} >= 0.
+## @end ifnottex
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: CDF of the Weibull distribution
+
+function cdf = wblcdf (x, scale, shape)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 3)
+    shape = 1;
+  endif
+
+  if (nargin < 2)
+    scale = 1;
+  endif
+
+  if (!isscalar (shape) || !isscalar (scale))
+    [retval, x, shape, scale] = common_size (x, shape, scale);
+    if (retval > 0)
+      error ("wblcdf: x, scale and shape must be of common size or scalar");
+    endif
+  endif
+
+  cdf = NaN * ones (size (x));
+
+  ok = ((shape > 0) & (shape < Inf) & (scale > 0) & (scale < Inf));
+
+  k = find ((x <= 0) & ok);
+  if (any (k))
+    cdf(k) = 0;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & ok);
+  if (any (k))
+    if (isscalar (shape) && isscalar (scale))
+      cdf(k) = 1 - exp (- (x(k) / scale) .^ shape);
+    else
+      cdf(k) = 1 - exp (- (x(k) ./ scale(k)) .^ shape(k));
+    endif
+  endif
+
+  k = find ((x == Inf) & ok);
+  if (any (k))
+    cdf(k) = 1;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/wblinv.m b/scripts/statistics/distributions/wblinv.m
new file mode 100644
index 0000000..5f3ac08
--- /dev/null
+++ b/scripts/statistics/distributions/wblinv.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1995, 1996, 1997, 2006, 2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wblinv (@var{x}, @var{scale}, @var{shape})
+## Compute the quantile (the inverse of the CDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Quantile function of the Weibull distribution
+
+function inv = wblinv (x, scale, shape)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 3)
+    shape = 1;
+  endif
+
+  if (nargin < 2)
+    scale = 1;
+  endif
+
+  if (!isscalar (shape) || !isscalar (scale))
+    [retval, x, shape, scale] = common_size (x, shape, scale);
+    if (retval > 0)
+      error ("wblinv: x, scale and shape must be of common size or scalar");
+    endif
+  endif
+
+  inv = NaN * ones (size (x));
+
+  ok = ((shape > 0) & (shape < Inf) & (scale > 0) & (scale < Inf));
+
+  k = find ((x == 0) & ok);
+  if (any (k))
+    inv(k) = -Inf;
+  endif
+
+  k = find ((x > 0) & (x < 1) & ok);
+  if (any (k))
+    if (isscalar (shape) && isscalar (scale))
+      inv(k) = scale * (- log (1 - x(k))) .^ (1 / shape);
+    else
+      inv(k) = scale(k) .* (- log (1 - x(k))) .^ (1 ./ shape(k));
+    endif
+  endif
+
+  k = find ((x == 1) & ok);
+  if (any (k))
+    inv(k) = Inf;
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/wblpdf.m b/scripts/statistics/distributions/wblpdf.m
new file mode 100644
index 0000000..d1985e1
--- /dev/null
+++ b/scripts/statistics/distributions/wblpdf.m
@@ -0,0 +1,83 @@
+## Copyright (C) 1995, 1996, 1997, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wblpdf (@var{x}, @var{scale}, @var{shape})
+## Compute the probability density function (PDF) at @var{x} of the
+## Weibull distribution with shape parameter @var{scale} and scale
+## parameter @var{shape} which is given by
+##
+## @tex
+## $$  scale \cdot shape^{-scale} x^{scale-1} \exp(-(x/shape)^{scale}) $$
+## @end tex
+## @ifnottex
+## @example
+##    scale * shape^(-scale) * x^(scale-1) * exp(-(x/shape)^scale)
+## @end example
+## @end ifnottex
+##
+## @noindent
+## for @var{x} > 0.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: PDF of the Weibull distribution
+
+function pdf = wblpdf (x, scale, shape)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 3)
+    shape = 1;
+  endif
+
+  if (nargin < 2)
+    scale = 1;
+  endif
+
+  if (!isscalar (shape) || !isscalar (scale))
+    [retval, x, shape, scale] = common_size (x, shape, scale);
+    if (retval > 0)
+      error ("wblpdf: x, scale and shape must be of common size or scalar");
+    endif
+  endif
+
+  pdf = NaN * ones (size (x));
+  ok = ((shape > 0) & (shape < Inf) & (scale > 0) & (scale < Inf));
+
+  k = find ((x > -Inf) & (x <= 0) & ok);
+  if (any (k))
+    pdf(k) = 0;
+  endif
+
+  k = find ((x > 0) & (x < Inf) & ok);
+  if (any (k))
+    if (isscalar (shape) && isscalar (scale))
+      pdf(k) = (shape .* (scale .^ -shape)
+		.* (x(k) .^ (shape - 1))
+		.* exp(- (x(k) / scale) .^ shape));
+    else
+      pdf(k) = (shape(k) .* (scale(k) .^ -shape(k))
+		.* (x(k) .^ (shape(k) - 1))
+		.* exp(- (x(k) ./ scale(k)) .^ shape(k)));
+    endif
+  endif
+
+endfunction
diff --git a/scripts/statistics/distributions/wblrnd.m b/scripts/statistics/distributions/wblrnd.m
new file mode 100644
index 0000000..41fc7ab
--- /dev/null
+++ b/scripts/statistics/distributions/wblrnd.m
@@ -0,0 +1,94 @@
+## Copyright (C) 1995, 1996, 1997, 2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wblrnd (@var{scale}, @var{shape}, @var{r}, @var{c})
+## @deftypefnx {Function File} {} wblrnd (@var{scale}, @var{shape}, @var{sz})
+## Return an @var{r} by @var{c} matrix of random samples from the
+## Weibull distribution with parameters @var{scale} and @var{shape}
+## which must be scalar or of size @var{r} by @var{c}.  Or if @var{sz}
+## is a vector return a matrix of size @var{sz}.
+##
+## If @var{r} and @var{c} are omitted, the size of the result matrix is
+## the common size of @var{alpha} and @var{sigma}.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Random deviates from the Weibull distribution
+
+function rnd = wblrnd (scale, shape, r, c)
+
+  if (nargin > 1)
+    if (!isscalar(shape) || !isscalar(scale)) 
+      [retval, shape, scale] = common_size (shape, scale);
+      if (retval > 0)
+	error ("wblrnd: shape and scale must be of common size or scalar");
+      endif
+    endif
+  endif
+
+  if (nargin == 4)
+    if (! (isscalar (r) && (r > 0) && (r == round (r))))
+      error ("wblrnd: r must be a positive integer");
+    endif
+    if (! (isscalar (c) && (c > 0) && (c == round (c))))
+      error ("wblrnd: c must be a positive integer");
+    endif
+    sz = [r, c];
+
+    if (any (size (scale) != 1) && 
+	((length (size (scale)) != length (sz))
+	 || any (size (scale) != sz)))
+      error ("wblrnd: shape and scale must be scalar or of size [r, c]");
+    endif
+  elseif (nargin == 3)
+    if (isscalar (r) && (r > 0))
+      sz = [r, r];
+    elseif (isvector(r) && all (r > 0))
+      sz = r(:)';
+    else
+      error ("wblrnd: r must be a positive integer or vector");
+    endif
+
+    if (any (size (scale) != 1) && 
+	((length (size (scale)) != length (sz))
+	 || any (size (scale) != sz)))
+      error ("wblrnd: shape and scale must be scalar or of size sz");
+    endif
+  elseif (nargin == 2)
+    sz = size(shape);
+  else
+    print_usage ();
+  endif
+
+  if (isscalar (shape) && isscalar (scale))
+    if ((shape > 0) & (shape < Inf) & (scale > 0) & (scale < Inf))
+      rnd = scale .* rande(sz) .^ (1./shape);
+    else
+      rnd = NaN * ones (sz);
+    endif
+  else
+    rnd = scale .* rande(sz) .^ (1./shape);
+    k = find ((shape <= 0) | (shape == Inf) | ((scale <= 0) & (scale == Inf)));
+    if (any(k))
+      rnd(k) = NaN;
+    endif
+  endif
+
+endfunction
+
diff --git a/scripts/statistics/distributions/wienrnd.m b/scripts/statistics/distributions/wienrnd.m
new file mode 100644
index 0000000..b4678c2
--- /dev/null
+++ b/scripts/statistics/distributions/wienrnd.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007, 2009 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} wienrnd (@var{t}, @var{d}, @var{n})
+## Return a simulated realization of the @var{d}-dimensional Wiener Process
+## on the interval [0, @var{t}].  If @var{d} is omitted, @var{d} = 1 is
+## used.  The first column of the return matrix contains time, the
+## remaining columns contain the Wiener process.
+##
+## The optional parameter @var{n} gives the number of summands used for
+## simulating the process over an interval of length 1.  If @var{n} is
+## omitted, @var{n} = 1000 is used.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Simulate a Wiener process
+
+function retval = wienrnd (t, d, n)
+
+  if (nargin == 1)
+    d = 1;
+    n = 1000;
+  elseif (nargin == 2)
+    n = 1000;
+  elseif (nargin > 3)
+    print_usage ();
+  endif
+
+  if (!isscalar (t) || !isscalar (d) || !isscalar (n))
+    error ("wienrnd: t, d and n must all be positive integers");
+  endif
+
+  retval = randn (n * t, d);
+  retval = cumsum (retval) / sqrt (n);
+
+  retval = [((1: n*t)' / n), retval];
+
+endfunction
diff --git a/scripts/statistics/models/Makefile.in b/scripts/statistics/models/Makefile.in
new file mode 100644
index 0000000..3ec5160
--- /dev/null
+++ b/scripts/statistics/models/Makefile.in
@@ -0,0 +1,84 @@
+# Makefile for octave's scripts/statistics/models directory
+#
+# Copyright (C) 1998, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../../..
+
+script_sub_dir = statistics/models
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = logistic_regression.m logistic_regression_derivatives.m \
+  logistic_regression_likelihood.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../../`cat ../../../.fname`/scripts/$(script_sub_dir)
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/statistics/models/logistic_regression.m b/scripts/statistics/models/logistic_regression.m
new file mode 100644
index 0000000..3d36ff9
--- /dev/null
+++ b/scripts/statistics/models/logistic_regression.m
@@ -0,0 +1,194 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2007,
+##               2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{theta}, @var{beta}, @var{dev}, @var{dl}, @var{d2l}, @var{p}] =} logistic_regression (@var{y}, @var{x}, @var{print}, @var{theta}, @var{beta})
+## Perform ordinal logistic regression.
+##
+## Suppose @var{y} takes values in @var{k} ordered categories, and let
+## @code{gamma_i (@var{x})} be the cumulative probability that @var{y}
+## falls in one of the first @var{i} categories given the covariate
+## @var{x}.  Then
+##
+## @example
+## [theta, beta] = logistic_regression (y, x)
+## @end example
+##
+## @noindent
+## fits the model
+##
+## @example
+## logit (gamma_i (x)) = theta_i - beta' * x,   i = 1 @dots{} k-1
+## @end example
+##
+## The number of ordinal categories, @var{k}, is taken to be the number
+## of distinct values of @code{round (@var{y})}.  If @var{k} equals 2,
+## @var{y} is binary and the model is ordinary logistic regression.  The
+## matrix @var{x} is assumed to have full column rank.
+##
+## Given @var{y} only, @code{theta = logistic_regression (y)}
+## fits the model with baseline logit odds only.
+##
+## The full form is
+##
+## @example
+## @group
+## [theta, beta, dev, dl, d2l, gamma]
+##    = logistic_regression (y, x, print, theta, beta)
+## @end group
+## @end example
+##
+## @noindent
+## in which all output arguments and all input arguments except @var{y}
+## are optional.
+##
+## Setting @var{print} to 1 requests summary information about the fitted
+## model to be displayed.  Setting @var{print} to 2 requests information
+## about convergence at each iteration.  Other values request no
+## information to be displayed.  The input arguments @var{theta} and
+## @var{beta} give initial estimates for @var{theta} and @var{beta}.
+##
+## The returned value @var{dev} holds minus twice the log-likelihood.
+##
+## The returned values @var{dl} and @var{d2l} are the vector of first
+## and the matrix of second derivatives of the log-likelihood with
+## respect to @var{theta} and @var{beta}.
+##
+## @var{p} holds estimates for the conditional distribution of @var{y}
+## given @var{x}.
+## @end deftypefn
+
+## Original for MATLAB written by Gordon K Smyth <gks at maths.uq.oz.au>,
+## U of Queensland, Australia, on Nov 19, 1990.  Last revision Aug 3,
+## 1992.
+
+## Author: Gordon K Smyth <gks at maths.uq.oz.au>,
+## Adapted-By: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Ordinal logistic regression
+
+## Uses the auxiliary functions logistic_regression_derivatives and
+## logistic_regression_likelihood.
+
+function [theta, beta, dev, dl, d2l, p] ...
+  = logistic_regression (y, x, print, theta, beta)
+
+  ## check input
+  y = round (vec (y));
+  [my, ny] = size (y);
+  if (nargin < 2)
+    x = zeros (my, 0);
+  endif;
+  [mx, nx] = size (x);
+  if (mx != my)
+    error ("x and y must have the same number of observations");
+  endif
+
+  ## initial calculations
+  x = -x;
+  tol = 1e-6; incr = 10; decr = 2;
+  ymin = min (y); ymax = max (y); yrange = ymax - ymin;
+  z  = (y * ones (1, yrange)) == ((y * 0 + 1) * (ymin : (ymax - 1)));
+  z1 = (y * ones (1, yrange)) == ((y * 0 + 1) * ((ymin + 1) : ymax));
+  z  = z(:, any (z));
+  z1 = z1 (:, any(z1));
+  [mz, nz] = size (z);
+
+  ## starting values
+  if (nargin < 3)
+    print = 0;
+  endif;
+  if (nargin < 4)
+    beta = zeros (nx, 1);
+  endif;
+  if (nargin < 5)
+    g = cumsum (sum (z))' ./ my;
+    theta = log (g ./ (1 - g));
+  endif;
+  tb = [theta; beta];
+
+  ## likelihood and derivatives at starting values
+  [g, g1, p, dev] = logistic_regression_likelihood (y, x, tb, z, z1);
+  [dl, d2l] = logistic_regression_derivatives (x, z, z1, g, g1, p);
+  epsilon = std (vec (d2l)) / 1000;
+
+  ## maximize likelihood using Levenberg modified Newton's method
+  iter = 0;
+  while (abs (dl' * (d2l \ dl) / length (dl)) > tol)
+    iter = iter + 1;
+    tbold = tb;
+    devold = dev;
+    tb = tbold - d2l \ dl;
+    [g, g1, p, dev] = logistic_regression_likelihood (y, x, tb, z, z1);
+    if ((dev - devold) / (dl' * (tb - tbold)) < 0)
+      epsilon = epsilon / decr;
+    else
+      while ((dev - devold) / (dl' * (tb - tbold)) > 0)
+        epsilon = epsilon * incr;
+         if (epsilon > 1e+15)
+           error ("epsilon too large");
+         endif
+         tb = tbold - (d2l - epsilon * eye (size (d2l))) \ dl;
+         [g, g1, p, dev] = logistic_regression_likelihood (y, x, tb, z, z1);
+         disp ("epsilon"); disp (epsilon);
+      endwhile
+    endif
+    [dl, d2l] = logistic_regression_derivatives (x, z, z1, g, g1, p);
+    if (print == 2)
+      disp ("Iteration"); disp (iter);
+      disp ("Deviance"); disp (dev);
+      disp ("First derivative"); disp (dl');
+      disp ("Eigenvalues of second derivative"); disp (eig (d2l)');
+    endif
+  endwhile
+
+  ## tidy up output
+
+  theta = tb (1 : nz, 1);
+  beta  = tb ((nz + 1) : (nz + nx), 1);
+
+  if (print >= 1)
+    printf ("\n");
+    printf ("Logistic Regression Results:\n");
+    printf ("\n");
+    printf ("Number of Iterations: %d\n", iter);
+    printf ("Deviance:             %f\n", dev);
+    printf ("Parameter Estimates:\n");
+    printf ("     Theta         S.E.\n");
+    se = sqrt (diag (inv (-d2l)));
+    for i = 1 : nz
+      printf ("   %8.4f     %8.4f\n", tb (i), se (i));
+    endfor
+    if (nx > 0)
+      printf ("      Beta         S.E.\n");
+      for i = (nz + 1) : (nz + nx)
+        printf ("   %8.4f     %8.4f\n", tb (i), se (i));
+      endfor
+    endif
+  endif
+
+  if (nargout == 6)
+    if (nx > 0)
+      e = ((x * beta) * ones (1, nz)) + ((y * 0 + 1) * theta');
+    else
+      e = (y * 0 + 1) * theta';
+    endif
+    gamma = diff ([(y * 0), (exp (e) ./ (1 + exp (e))), (y * 0 + 1)]')';
+  endif
+
+endfunction
diff --git a/scripts/statistics/models/logistic_regression_derivatives.m b/scripts/statistics/models/logistic_regression_derivatives.m
new file mode 100644
index 0000000..84b89fd
--- /dev/null
+++ b/scripts/statistics/models/logistic_regression_derivatives.m
@@ -0,0 +1,46 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{dl}, @var{d2l}] =} logistic_regression_derivatives (@var{x}, @var{z}, @var{z1}, @var{g}, @var{g1}, @var{p})
+## Called by logistic_regression.  Calculates derivates of the
+## log-likelihood for ordinal logistic regression model.
+## @end deftypefn
+
+## Author: Gordon K. Smyth <gks at maths.uq.oz.au>
+## Adapted-By: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Derivates of log-likelihood in logistic regression
+
+function [dl, d2l] = logistic_regression_derivatives (x, z, z1, g, g1, p)
+
+  if (nargin != 6)
+    print_usage ();
+  endif
+
+  ## first derivative
+  v = g .* (1 - g) ./ p; v1 = g1 .* (1 - g1) ./ p;
+  dlogp = [(diag (v) * z - diag (v1) * z1), (diag (v - v1) * x)];
+  dl = sum (dlogp)';
+
+  ## second derivative
+  w = v .* (1 - 2 * g); w1 = v1 .* (1 - 2 * g1);
+  d2l = [z, x]' * diag (w) * [z, x] - [z1, x]' * diag (w1) * [z1, x] ...
+      - dlogp' * dlogp;
+
+endfunction
diff --git a/scripts/statistics/models/logistic_regression_likelihood.m b/scripts/statistics/models/logistic_regression_likelihood.m
new file mode 100644
index 0000000..8cc12b0
--- /dev/null
+++ b/scripts/statistics/models/logistic_regression_likelihood.m
@@ -0,0 +1,43 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{g}, @var{g1}, @var{p}, @var{dev}] =} logistic_regression_likelihood (@var{y}, @var{x}, @var{beta}, @var{z}, @var{z1})
+## Calculates likelihood for the ordinal logistic regression model.
+## Called by logistic_regression.
+## @end deftypefn
+
+## Author: Gordon K. Smyth <gks at maths.uq.oz.au>
+## Adapted-By: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Likelihood in logistic regression
+
+function [g, g1, p, dev] = logistic_regression_likelihood (y, x, beta, z, z1)
+
+  if (nargin != 5)
+    print_usage ();
+  endif
+
+  e = exp ([z, x] * beta); e1 = exp ([z1, x] * beta);
+  g = e ./ (1 + e); g1 = e1 ./ (1 + e1);
+  g = max (y == max (y), g); g1 = min (y > min(y), g1);
+
+  p = g - g1;
+  dev = -2 * sum (log (p));
+
+endfunction
diff --git a/scripts/statistics/tests/Makefile.in b/scripts/statistics/tests/Makefile.in
new file mode 100644
index 0000000..0c07cd3
--- /dev/null
+++ b/scripts/statistics/tests/Makefile.in
@@ -0,0 +1,89 @@
+# Makefile for octave's scripts/statistics/tests directory
+#
+# Copyright (C) 1998, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../../..
+
+script_sub_dir = statistics/tests
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = anova.m bartlett_test.m chisquare_test_homogeneity.m \
+  chisquare_test_independence.m cor_test.m f_test_regression.m \
+  hotelling_test.m hotelling_test_2.m kolmogorov_smirnov_test.m \
+  kolmogorov_smirnov_test_2.m kruskal_wallis_test.m manova.m \
+  mcnemar_test.m prop_test_2.m run_test.m sign_test.m t_test.m \
+  t_test_2.m t_test_regression.m u_test.m var_test.m welch_test.m \
+  wilcoxon_test.m z_test.m z_test_2.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../../`cat ../../../.fname`/scripts/$(script_sub_dir)
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/statistics/tests/anova.m b/scripts/statistics/tests/anova.m
new file mode 100644
index 0000000..23f792c
--- /dev/null
+++ b/scripts/statistics/tests/anova.m
@@ -0,0 +1,111 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_b}, @var{df_w}] =} anova (@var{y}, @var{g})
+## Perform a one-way analysis of variance (ANOVA).  The goal is to test
+## whether the population means of data taken from @var{k} different
+## groups are all equal.
+##
+## Data may be given in a single vector @var{y} with groups specified by
+## a corresponding vector of group labels @var{g} (e.g., numbers from 1
+## to @var{k}).  This is the general form which does not impose any
+## restriction on the number of data in each group or the group labels.
+##
+## If @var{y} is a matrix and @var{g} is omitted, each column of @var{y}
+## is treated as a group.  This form is only appropriate for balanced
+## ANOVA in which the numbers of samples from each group are all equal.
+##
+## Under the null of constant means, the statistic @var{f} follows an F
+## distribution with @var{df_b} and @var{df_w} degrees of freedom.
+##
+## The p-value (1 minus the CDF of this distribution at @var{f}) is
+## returned in @var{pval}.
+##
+## If no output argument is given, the standard one-way ANOVA table is
+## printed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: One-way analysis of variance (ANOVA)
+
+function [pval, f, df_b, df_w] = anova (y, g)
+
+  if ((nargin < 1) || (nargin > 2))
+    print_usage ();
+  elseif (nargin == 1)
+    if (isvector (y))
+      error ("anova: for `anova (y)', y must not be a vector");
+    endif
+    [group_count, k] = size (y);
+    n = group_count * k;
+    group_mean = mean (y);
+  else
+    if (! isvector (y))
+      error ("anova: for `anova (y, g)', y must be a vector");
+    endif
+    n = length (y);
+    if (! isvector (g) || (length (g) != n))
+      error ("anova: g must be a vector of the same length as y");
+    endif
+    s = sort (g);
+    i = find (s (2 : n) > s(1 : (n-1)));
+    k = length (i) + 1;
+    if (k == 1)
+      error ("anova: there should be at least 2 groups");
+    else
+      group_label = s ([1, (reshape (i, 1, k-1) + 1)]);
+    endif
+    for i = 1 : k;
+      v = y (find (g == group_label (i)));
+      group_count (i) = length (v);
+      group_mean (i) = mean (v);
+    endfor
+
+  endif
+
+  total_mean = mean (y(:));
+  SSB = sum (group_count .* (group_mean - total_mean) .^ 2);
+  SST = sumsq (reshape (y, n, 1) - total_mean);
+  SSW = SST - SSB;
+  df_b = k - 1;
+  df_w = n - k;
+  v_b = SSB / df_b;
+  v_w = SSW / df_w;
+  f = v_b / v_w;
+  pval = 1 - f_cdf (f, df_b, df_w);
+
+  if (nargout == 0)
+    ## This eventually needs to be done more cleanly ...
+    printf ("\n");
+    printf ("One-way ANOVA Table:\n");
+    printf ("\n");
+    printf ("Source of Variation   Sum of Squares    df  Empirical Var\n");
+    printf ("*********************************************************\n");
+    printf ("Between Groups       %15.4f  %4d  %13.4f\n", SSB, df_b, v_b);
+    printf ("Within Groups        %15.4f  %4d  %13.4f\n", SSW, df_w, v_w);
+    printf ("---------------------------------------------------------\n");
+    printf ("Total                %15.4f  %4d\n", SST, n - 1);
+    printf ("\n");
+    printf ("Test Statistic f     %15.4f\n", f);
+    printf ("p-value              %15.4f\n", pval);
+    printf ("\n");
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/bartlett_test.m b/scripts/statistics/tests/bartlett_test.m
new file mode 100644
index 0000000..3525dad
--- /dev/null
+++ b/scripts/statistics/tests/bartlett_test.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} bartlett_test (@var{x1}, @dots{}) 
+## Perform a Bartlett test for the homogeneity of variances in the data
+## vectors @var{x1}, @var{x2}, @dots{}, @var{xk}, where @var{k} > 1.
+##
+## Under the null of equal variances, the test statistic @var{chisq}
+## approximately follows a chi-square distribution with @var{df} degrees of
+## freedom.
+##
+## The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+## returned in @var{pval}.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Bartlett test for homogeneity of variances
+
+function [pval, chisq, df] = bartlett_test (varargin)
+
+  k = nargin;
+  if (k < 2)
+    print_usage ();
+  endif
+
+  f = zeros (k, 1);
+  v = zeros (k, 1);
+
+  for i = 1 : k;
+    x = varargin{i};
+    if (! isvector (x))
+      error ("bartlett_test: all arguments must be vectors");
+    endif
+    f(i) = length (x) - 1;
+    v(i) = var (x);
+  endfor
+
+  f_tot = sum (f);
+  v_tot = sum (f .* v) / f_tot;
+  c     = 1 + (sum (1 ./ f) - 1 / f_tot) / (3 * (k - 1));
+  chisq = (f_tot * log (v_tot) - sum (f .* log (v))) / c;
+  df    = k;
+  pval  = 1 - chisquare_cdf (chisq, df);
+
+  if (nargout == 0)
+    printf("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/chisquare_test_homogeneity.m b/scripts/statistics/tests/chisquare_test_homogeneity.m
new file mode 100644
index 0000000..db1bd50
--- /dev/null
+++ b/scripts/statistics/tests/chisquare_test_homogeneity.m
@@ -0,0 +1,69 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} chisquare_test_homogeneity (@var{x}, @var{y}, @var{c})
+## Given two samples @var{x} and @var{y}, perform a chisquare test for
+## homogeneity of the null hypothesis that @var{x} and @var{y} come from
+## the same distribution, based on the partition induced by the
+## (strictly increasing) entries of @var{c}.
+##
+## For large samples, the test statistic @var{chisq} approximately follows a
+## chisquare distribution with @var{df} = @code{length (@var{c})}
+## degrees of freedom.
+##
+## The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+## returned in @var{pval}.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Chi-square test for homogeneity
+
+function [pval, chisq, df] = chisquare_test_homogeneity (x, y, c)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! (isvector(x) && isvector(y) && isvector(c)))
+    error ("chisquare_test_homogeneity: x, y and c must be vectors");
+  endif
+  ## Now test c for strictly increasing entries
+  df = length (c);
+  if (any ((c(2 : df) - c(1 : (df - 1))) <= 0))
+    error ("chisquare_test_homogeneity: c must be increasing");
+  endif
+
+  c     = [(reshape (c, 1, df)), Inf];
+  l_x   = length (x);
+  x     = reshape (x, l_x, 1);
+  n_x   = sum (x * ones (1, df+1) < ones (l_x, 1) * c);
+  l_y   = length (y);
+  y     = reshape (y, l_y, 1);
+  n_y   = sum(y * ones (1, df+1) < ones (l_y, 1) * c);
+  chisq = l_x * l_y * sum ((n_x/l_x - n_y/l_y).^2 ./ (n_x + n_y));
+  pval  = 1 - chisquare_cdf (chisq, df);
+
+  if (nargout == 0)
+    printf("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/chisquare_test_independence.m b/scripts/statistics/tests/chisquare_test_independence.m
new file mode 100644
index 0000000..e19c608
--- /dev/null
+++ b/scripts/statistics/tests/chisquare_test_independence.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} chisquare_test_independence (@var{x})
+## Perform a chi-square test for independence based on the contingency
+## table @var{x}.  Under the null hypothesis of independence,
+## @var{chisq} approximately has a chi-square distribution with
+## @var{df} degrees of freedom.
+##
+## The p-value (1 minus the CDF of this distribution at chisq) of the
+## test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Chi-square test for independence
+
+function [pval, chisq, df] = chisquare_test_independence (X)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  [r, s] = size (X);
+  df = (r - 1) * (s - 1);
+  n = sum (sum (X));
+  Y = sum (X')' * sum (X) / n;
+  X = (X - Y) .^2 ./ Y;
+  chisq = sum (sum (X));
+  pval  = 1 - chisquare_cdf (chisq, df);
+
+  if (nargout == 0)
+    printf("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/cor_test.m b/scripts/statistics/tests/cor_test.m
new file mode 100644
index 0000000..8afe696
--- /dev/null
+++ b/scripts/statistics/tests/cor_test.m
@@ -0,0 +1,131 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cor_test (@var{x}, @var{y}, @var{alt}, @var{method})
+## Test whether two samples @var{x} and @var{y} come from uncorrelated
+## populations.
+##
+## The optional argument string @var{alt} describes the alternative
+## hypothesis, and can be @code{"!="} or @code{"<>"} (non-zero),
+## @code{">"} (greater than 0), or @code{"<"} (less than 0).  The
+## default is the two-sided case.
+##
+## The optional argument string @var{method} specifies on which
+## correlation coefficient the test should be based.  If @var{method} is
+## @code{"pearson"} (default), the (usual) Pearson's product moment
+## correlation coefficient is used.  In this case, the data should come
+## from a bivariate normal distribution.  Otherwise, the other two
+## methods offer nonparametric alternatives.  If @var{method} is
+## @code{"kendall"}, then Kendall's rank correlation tau is used.  If
+## @var{method} is @code{"spearman"}, then Spearman's rank correlation
+## rho is used.  Only the first character is necessary.
+##
+## The output is a structure with the following elements:
+##
+## @table @var
+## @item pval
+## The p-value of the test.
+## @item stat
+## The value of the test statistic.
+## @item dist
+## The distribution of the test statistic.
+## @item params
+## The parameters of the null distribution of the test statistic.
+## @item alternative
+## The alternative hypothesis.
+## @item method
+## The method used for testing.
+## @end table
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Adapted-by: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Test for zero correlation
+
+function t = cor_test (X, Y, ALTERNATIVE, METHOD)
+
+  if ((nargin < 2) || (nargin > 4))
+    print_usage ();
+  endif
+
+  if (!isvector (X) || !isvector (Y) || length (X) != length (Y))
+    error ("cor_test: X and Y must be vectors of the same length");
+  endif
+
+  if (nargin < 3)
+    ALTERNATIVE = "!=";
+  elseif (! ischar (ALTERNATIVE))
+    error ("cor_test: ALTERNATIVE must be a string");
+  endif
+
+  if (nargin < 4)
+    METHOD = "pearson";
+  elseif (! ischar (METHOD))
+    error ("cor_test: METHOD must be a string");
+  endif
+
+  n = length (X);
+  m = METHOD (1);
+
+  if (m == "p")
+    r = cor (X, Y);
+    df = n - 2;
+    t.method = "Pearson's product moment correlation";
+    t.params = df;
+    t.stat = sqrt (df) .* r / sqrt (1 - r.^2);
+    t.dist = "t";
+    cdf  = t_cdf (t.stat, df);
+  elseif (m == "k")
+    tau = kendall (X, Y);
+    t.method = "Kendall's rank correlation tau";
+    t.params = [];
+    t.stat = tau / sqrt ((2 * (2*n+5)) / (9*n*(n-1)));
+    t.dist = "stdnormal";
+    cdf = stdnormal_cdf (t.stat);
+  elseif (m == "s")
+    rho = spearman (X, Y);
+    t.method = "Spearman's rank correlation rho";
+    t.params = [];
+    t.stat = sqrt (n-1) * (rho - 6/(n^3-n));
+    t.dist = "stdnormal";
+    cdf = stdnormal_cdf (t.stat);
+  else
+    error ("cor_test: method `%s' not recognized", METHOD);
+  endif
+
+  if (strcmp (ALTERNATIVE, "!=") || strcmp (ALTERNATIVE, "<>"))
+    t.pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (ALTERNATIVE, ">"))
+    t.pval = 1 - cdf;
+  elseif (strcmp (ALTERNATIVE, "<"))
+    t.pval = cdf;
+  else
+    error ("cor_test: alternative `%s' not recognized", ALTERNATIVE);
+  endif
+
+  t.alternative = ALTERNATIVE;
+
+  if (nargout == 0)
+    printf ("pval: %g\n", t.pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/f_test_regression.m b/scripts/statistics/tests/f_test_regression.m
new file mode 100644
index 0000000..4e2c713
--- /dev/null
+++ b/scripts/statistics/tests/f_test_regression.m
@@ -0,0 +1,78 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_num}, @var{df_den}] =} f_test_regression (@var{y}, @var{x}, @var{rr}, @var{r})
+## Perform an F test for the null hypothesis rr * b = r in a classical
+## normal regression model y = X * b + e.
+##
+## Under the null, the test statistic @var{f} follows an F distribution
+## with @var{df_num} and @var{df_den} degrees of freedom.
+##
+## The p-value (1 minus the CDF of this distribution at @var{f}) is
+## returned in @var{pval}.
+##
+## If not given explicitly, @var{r} = 0.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Test linear hypotheses in linear regression model
+
+function [pval, f, df_num, df_den] = f_test_regression (y, X, R, r)
+
+  if (nargin < 3 || nargin > 4)
+    print_usage ();
+  endif
+
+  [T, k] = size (X);
+  if (! (isvector (y) && (length (y) == T)))
+    error ("f_test_regression: y must be a vector of length rows (X)");
+  endif
+  y = reshape (y, T, 1);
+
+  [q, c_R ] = size (R);
+  if (c_R != k)
+    error ("f_test_regression: R must have as many columns as X");
+  endif
+
+  if (nargin == 4)
+    s_r = size (r);
+    if ((min (s_r) != 1) || (max (s_r) != q))
+      error ("f_test_regression: r must be a vector of length rows (R)");
+    endif
+    r = reshape (r, q, 1);
+  else
+    r = zeros (q, 1);
+  endif
+
+  df_num = q;
+  df_den = T - k;
+
+  [b, v] = ols (y, X);
+  diff   = R * b - r;
+  f      = diff' * inv (R * inv (X' * X) * R') * diff / (q * v);
+  pval  = 1 - f_cdf (f, df_num, df_den);
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/hotelling_test.m b/scripts/statistics/tests/hotelling_test.m
new file mode 100644
index 0000000..64d82a1
--- /dev/null
+++ b/scripts/statistics/tests/hotelling_test.m
@@ -0,0 +1,73 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{tsq}] =} hotelling_test (@var{x}, @var{m})
+## For a sample @var{x} from a multivariate normal distribution with unknown
+## mean and covariance matrix, test the null hypothesis that @code{mean
+## (@var{x}) == @var{m}}.
+##
+## Hotelling's @math{T^2} is returned in @var{tsq}.  Under the null,
+## @math{(n-p) T^2 / (p(n-1))} has an F distribution with @math{p} and
+## @math{n-p} degrees of freedom, where @math{n} and @math{p} are the
+## numbers of samples and variables, respectively.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Test for mean of a multivariate normal
+
+function [pval, Tsq] = hotelling_test (x, m)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isvector (x))
+    if (! isscalar (m))
+      error ("hotelling_test: if x is a vector, m must be a scalar");
+    endif
+    n = length (x);
+    p = 1;
+  elseif (ismatrix (x))
+    [n, p] = size (x);
+    if (n <= p)
+      error ("hotelling_test: x must have more rows than columns");
+    endif
+    if (isvector (m) && length (m) == p)
+      m = reshape (m, 1, p);
+    else
+      error ("hotelling_test: if x is a matrix, m must be a vector of length columns (x)");
+    endif
+  else
+    error ("hotelling_test: x must be a matrix or vector");
+  endif
+
+  d    = mean (x) - m;
+  Tsq  = n * d * (cov (x) \ d');
+  pval = 1 - f_cdf ((n-p) * Tsq / (p * (n-1)), p, n-p);
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/hotelling_test_2.m b/scripts/statistics/tests/hotelling_test_2.m
new file mode 100644
index 0000000..d98e576
--- /dev/null
+++ b/scripts/statistics/tests/hotelling_test_2.m
@@ -0,0 +1,87 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{tsq}] =} hotelling_test_2 (@var{x}, @var{y})
+## For two samples @var{x} from multivariate normal distributions with
+## the same number of variables (columns), unknown means and unknown
+## equal covariance matrices, test the null hypothesis @code{mean
+## (@var{x}) == mean (@var{y})}.
+##
+## Hotelling's two-sample @math{T^2} is returned in @var{tsq}.  Under the null,
+##
+## @tex
+## $$
+## {n_x+n_y-p-1) T^2 \over p(n_x+n_y-2)}
+## $$
+## @end tex
+## @ifnottex
+## @example
+## (n_x+n_y-p-1) T^2 / (p(n_x+n_y-2))
+## @end example
+## @end ifnottex
+##
+## @noindent
+## has an F distribution with @math{p} and @math{n_x+n_y-p-1} degrees of
+## freedom, where @math{n_x} and @math{n_y} are the sample sizes and
+## @math{p} is the number of variables.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compare means of two multivariate normals
+
+function [pval, Tsq] = hotelling_test_2 (x, y)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isvector (x))
+    n_x = length (x);
+    if (! isvector (y))
+      error ("hotelling_test_2: if x is a vector, y must also be a vector");
+    else
+      n_y = length (y);
+      p   = 1;
+    endif
+  elseif (ismatrix (x))
+    [n_x, p] = size (x);
+    [n_y, q] = size (y);
+    if (p != q)
+      error ("hotelling_test_2: x and y must have the same number of columns");
+    endif
+  else
+    error ("hotelling_test_2: x and y must be matrices (or vectors)");
+  endif
+
+  d    = mean (x) - mean (y);
+  S    = ((n_x - 1) * cov (x) + (n_y - 1) * cov (y)) / (n_x + n_y - 2);
+  Tsq  = (n_x * n_y / (n_x + n_y)) * d * (S \ d');
+  pval = 1 - f_cdf ((n_x + n_y - p - 1) * Tsq / (p * (n_x + n_y - 2)),
+                    p, n_x + n_y - p - 1);
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/kolmogorov_smirnov_test.m b/scripts/statistics/tests/kolmogorov_smirnov_test.m
new file mode 100644
index 0000000..1132f79
--- /dev/null
+++ b/scripts/statistics/tests/kolmogorov_smirnov_test.m
@@ -0,0 +1,105 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005,
+##               2006, 2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{ks}] =} kolmogorov_smirnov_test (@var{x}, @var{dist}, @var{params}, @var{alt})
+## Perform a Kolmogorov-Smirnov test of the null hypothesis that the
+## sample @var{x} comes from the (continuous) distribution dist.  I.e.,
+## if F and G are the CDFs corresponding to the sample and dist,
+## respectively, then the null is that F == G.
+##
+## The optional argument @var{params} contains a list of parameters of
+## @var{dist}.  For example, to test whether a sample @var{x} comes from
+## a uniform distribution on [2,4], use
+##
+## @example
+## kolmogorov_smirnov_test(x, "uniform", 2, 4)
+## @end example
+##
+## @noindent
+## @var{dist} can be any string for which a function @var{dist_cdf}
+## that calculates the CDF of distribution @var{dist} exists.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative F
+## != G.  In this case, the test statistic @var{ks} follows a two-sided
+## Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
+## one-sided alternative F > G is considered.  Similarly for @code{"<"},
+## the one-sided alternative F > G is considered.  In this case, the
+## test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
+## distribution.  The default is the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: One-sample Kolmogorov-Smirnov test
+
+function [pval, ks] = kolmogorov_smirnov_test (x, dist, varargin)
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  if (! isvector (x))
+    error ("kolmogorov_smirnov_test: x must be a vector");
+  endif
+
+  n = length (x);
+  s = sort (x);
+  f = str2func (sprintf ("%s_cdf", dist));
+
+  alt  = "!=";
+
+  if (nargin == 2)
+    z = reshape (feval (f, s), 1, n);
+  else
+    args = "";
+    for k = 1 : (nargin-2);
+      tmp  = varargin{k};
+      if ischar (tmp)
+        alt = tmp;
+      else
+        args = sprintf ("%s, %g", args, tmp);
+      endif
+    endfor
+    z = reshape (eval (sprintf ("%s(s%s);", func2str (f), args)), 1, n);
+  endif
+
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    ks   = sqrt (n) * max (max ([abs(z - (0:(n-1))/n); abs(z - (1:n)/n)]));
+    pval = 1 - kolmogorov_smirnov_cdf (ks);
+  elseif (strcmp (alt, ">"))
+    ks   = sqrt (n) * max (max ([z - (0:(n-1))/n; z - (1:n)/n]));
+    pval = exp (- 2 * ks^2);
+  elseif (strcmp (alt, "<"))
+    ks   = - sqrt (n) * min (min ([z - (0:(n-1))/n; z - (1:n)/n]));
+    pval = exp (- 2 * ks^2);
+  else
+    error ("kolmogorov_smirnov_test: alternative %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/kolmogorov_smirnov_test_2.m b/scripts/statistics/tests/kolmogorov_smirnov_test_2.m
new file mode 100644
index 0000000..f8f9707
--- /dev/null
+++ b/scripts/statistics/tests/kolmogorov_smirnov_test_2.m
@@ -0,0 +1,105 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+##               2007, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{ks}, @var{d}] =} kolmogorov_smirnov_test_2 (@var{x}, @var{y}, @var{alt})
+## Perform a 2-sample Kolmogorov-Smirnov test of the null hypothesis
+## that the samples @var{x} and @var{y} come from the same (continuous)
+## distribution.  I.e., if F and G are the CDFs corresponding to the
+## @var{x} and @var{y} samples, respectively, then the null is that F ==
+## G.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative F
+## != G.  In this case, the test statistic @var{ks} follows a two-sided
+## Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
+## one-sided alternative F > G is considered.  Similarly for @code{"<"},
+## the one-sided alternative F < G is considered.  In this case, the
+## test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
+## distribution.  The default is the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## The third returned value, @var{d}, is the test statistic, the maximum
+## vertical distance between the two cumulative distribution functions.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Two-sample Kolmogorov-Smirnov test
+
+function [pval, ks, d] = kolmogorov_smirnov_test_2 (x, y, alt)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y)))
+    error ("kolmogorov_smirnov_test_2: both x and y must be vectors");
+  endif
+
+  if (nargin == 2)
+    alt = "!=";
+  else
+    if (! ischar (alt))
+      error ("kolmogorov_smirnov_test_2: alt must be a string");
+    endif
+  endif
+
+  n_x = length (x);
+  n_y = length (y);
+  n   = n_x * n_y / (n_x + n_y);
+  x   = reshape (x, n_x, 1);
+  y   = reshape (y, n_y, 1);
+  [s, i] = sort ([x; y]);
+  count (find (i <= n_x)) = 1 / n_x;
+  count (find (i > n_x)) = - 1 / n_y;
+
+  z = cumsum (count);
+  ds = diff (s);
+  if (any (ds == 0))
+    ## There are some ties, so keep only those changes.
+    warning ("cannot compute correct p-values with ties");
+    elems = [find(ds); n_x+n_y];
+    z = z(elems);
+  endif
+  
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    d    = max (abs (z));
+    ks   = sqrt (n) * d;
+    pval = 1 - kolmogorov_smirnov_cdf (ks);
+  elseif (strcmp (alt, ">"))
+    d    = max (z);
+    ks   = sqrt (n) * d;
+    pval = exp (-2 * ks^2);
+  elseif (strcmp (alt, "<"))
+    d    = min (z);
+    ks   = -sqrt (n) * d;
+    pval = exp (-2 * ks^2);
+  else
+    error ("kolmogorov_smirnov_test_2: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/kruskal_wallis_test.m b/scripts/statistics/tests/kruskal_wallis_test.m
new file mode 100644
index 0000000..8e758f6
--- /dev/null
+++ b/scripts/statistics/tests/kruskal_wallis_test.m
@@ -0,0 +1,99 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{k}, @var{df}] =} kruskal_wallis_test (@var{x1}, @dots{})
+## Perform a Kruskal-Wallis one-factor "analysis of variance".
+##
+## Suppose a variable is observed for @var{k} > 1 different groups, and
+## let @var{x1}, @dots{}, @var{xk} be the corresponding data vectors.
+##
+## Under the null hypothesis that the ranks in the pooled sample are not
+## affected by the group memberships, the test statistic @var{k} is
+## approximately chi-square with @var{df} = @var{k} - 1 degrees of
+## freedom.
+##
+## If the data contains ties (some value appears more than once)
+## @var{k} is divided by
+## 
+## 1 - @var{sum_ties} / (@var{n}^3 - @var{n})
+##
+## where @var{sum_ties} is the sum of @var{t}^2 - @var{t} over each group
+## of ties where @var{t} is the number of ties in the group and @var{n}
+## is the total number of values in the input data.  For more info on
+## this adjustment see "Use of Ranks in One-Criterion Variance Analysis"
+## in Journal of the American Statistical Association, Vol. 47,
+## No. 260 (Dec 1952) by William H. Kruskal and W. Allen Wallis.
+##
+## The p-value (1 minus the CDF of this distribution at @var{k}) is
+## returned in @var{pval}.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Kruskal-Wallis test
+
+function [pval, k, df] = kruskal_wallis_test (varargin)
+
+  m = nargin;
+  if (m < 2)
+    print_usage ();
+  endif
+
+  n = [];
+  p = [];
+
+  for i = 1 : m;
+    x = varargin{i};
+    if (! isvector (x))
+      error ("kruskal_wallis_test: all arguments must be vectors");
+    endif
+    l = length (x);
+    n = [n, l];
+    p = [p, (reshape (x, 1, l))];
+  endfor
+
+  r = ranks (p);
+
+  k = 0;
+  j = 0;
+  for i = 1 : m;
+    k = k + (sum (r ((j + 1) : (j + n(i))))) ^ 2 / n(i);
+    j = j + n(i);
+  endfor
+
+  n = length (p);
+  k = 12 * k / (n * (n + 1)) - 3 * (n + 1);
+
+  ## Adjust the result to takes ties into account.
+  sum_ties = sum (polyval ([1, 0, -1, 0], runlength (sort (p))));
+  k = k / (1 - sum_ties / (n^3 - n));
+
+  df = m - 1;
+  pval = 1 - chisquare_cdf (k, df);
+
+  if (nargout == 0)
+    printf ("pval: %g\n", pval);
+  endif
+
+endfunction
+
+## Test with ties
+%!assert (abs(kruskal_wallis_test([86 86], [74]) - 0.157299207050285) < 0.0000000000001)
diff --git a/scripts/statistics/tests/manova.m b/scripts/statistics/tests/manova.m
new file mode 100644
index 0000000..bf41469
--- /dev/null
+++ b/scripts/statistics/tests/manova.m
@@ -0,0 +1,162 @@
+## Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006, 2007,
+##               2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} manova (@var{y}, @var{g})
+## Perform a one-way multivariate analysis of variance (MANOVA).  The
+## goal is to test whether the p-dimensional population means of data
+## taken from @var{k} different groups are all equal.  All data are
+## assumed drawn independently from p-dimensional normal distributions
+## with the same covariance matrix.
+##
+## The data matrix is given by @var{y}.  As usual, rows are observations
+## and columns are variables.  The vector @var{g} specifies the
+## corresponding group labels (e.g., numbers from 1 to @var{k}).
+##
+## The LR test statistic (Wilks' Lambda) and approximate p-values are
+## computed and displayed.
+## @end deftypefn
+
+## Three test statistics (Wilks, Hotelling-Lawley, and Pillai-Bartlett)
+## and corresponding approximate p-values are calculated and displayed.
+## (Currently NOT because the f_cdf respectively betai code is too bad.)
+
+## Author: TF <Thomas.Fuereder at ci.tuwien.ac.at>
+## Adapted-By: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: One-way multivariate analysis of variance (MANOVA)
+
+function manova (Y, g)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isvector (Y))
+    error ("manova: Y must not be a vector");
+  endif
+
+  [n, p] = size (Y);
+
+  if (!isvector (g) || (length (g) != n))
+    error ("manova: g must be a vector of length rows (Y)");
+  endif
+
+  s = sort (g);
+  i = find (s (2:n) > s(1:(n-1)));
+  k = length (i) + 1;
+
+  if (k == 1)
+    error ("manova: there should be at least 2 groups");
+  else
+    group_label = s ([1, (reshape (i, 1, k - 1) + 1)]);
+  endif
+
+  Y = Y - ones (n, 1) * mean (Y);
+  SST = Y' * Y;
+
+  s = zeros (1, p);
+  SSB = zeros (p, p);
+  for i = 1 : k;
+    v = Y (find (g == group_label (i)), :);
+    s = sum (v);
+    SSB = SSB + s' * s / rows (v);
+  endfor
+  n_b = k - 1;
+
+  SSW = SST - SSB;
+  n_w = n - k;
+
+  l = real (eig (SSB / SSW));
+
+  if (isa (l, "single"))
+    l (l < eps ("single")) = 0;
+  else
+    l (l < eps) = 0;
+  endif
+
+  ## Wilks' Lambda
+  ## =============
+
+  Lambda = prod (1 ./ (1 + l));
+
+  delta = n_w + n_b - (p + n_b + 1) / 2
+  df_num = p * n_b
+  W_pval_1 = 1 - chisquare_cdf (- delta * log (Lambda), df_num);
+
+  if (p < 3)
+    eta = p;
+  else
+    eta = sqrt ((p^2 * n_b^2 - 4) / (p^2 + n_b^2 - 5))
+  endif
+
+  df_den = delta * eta - df_num / 2 + 1
+
+  WT = exp (- log (Lambda) / eta) - 1
+  W_pval_2 = 1 - f_cdf (WT * df_den / df_num, df_num, df_den);
+
+  if (0)
+
+    ## Hotelling-Lawley Test
+    ## =====================
+
+    HL = sum (l);
+
+    theta = min (p, n_b);
+    u = (abs (p - n_b) - 1) / 2;
+    v = (n_w - p - 1) / 2;
+
+    df_num = theta * (2 * u + theta + 1);
+    df_den = 2 * (theta * v + 1);
+
+    HL_pval = 1 - f_cdf (HL * df_den / df_num, df_num, df_den);
+
+    ## Pillai-Bartlett
+    ## ===============
+
+    PB = sum (l ./ (1 + l));
+
+    df_den = theta * (2 * v + theta + 1);
+    PB_pval = 1 - f_cdf (PB * df_den / df_num, df_num, df_den);
+
+    printf ("\n");
+    printf ("One-way MANOVA Table:\n");
+    printf ("\n");
+    printf ("Test             Test Statistic      Approximate p\n");
+    printf ("**************************************************\n");
+    printf ("Wilks            %10.4f           %10.9f \n", Lambda, W_pval_1);
+    printf ("                                      %10.9f \n", W_pval_2);
+    printf ("Hotelling-Lawley %10.4f           %10.9f \n", HL, HL_pval);
+    printf ("Pillai-Bartlett  %10.4f           %10.9f \n", PB, PB_pval);
+    printf ("\n");
+
+  endif
+
+  printf ("\n");
+  printf ("MANOVA Results:\n");
+  printf ("\n");
+  printf ("# of groups:    %d\n", k);
+  printf ("# of samples:   %d\n", n);
+  printf ("# of variables: %d\n", p);
+  printf ("\n");
+  printf ("Wilks' Lambda:  %5.4f\n", Lambda);
+  printf ("Approximate p:  %10.9f (chisquare approximation)\n", W_pval_1);
+  printf ("                 %10.9f (F approximation)\n", W_pval_2);
+  printf ("\n");
+
+endfunction
diff --git a/scripts/statistics/tests/mcnemar_test.m b/scripts/statistics/tests/mcnemar_test.m
new file mode 100644
index 0000000..322fd20
--- /dev/null
+++ b/scripts/statistics/tests/mcnemar_test.m
@@ -0,0 +1,68 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} mcnemar_test (@var{x})
+## For a square contingency table @var{x} of data cross-classified on
+## the row and column variables, McNemar's test can be used for testing
+## the null hypothesis of symmetry of the classification probabilities.
+##
+## Under the null, @var{chisq} is approximately distributed as chisquare
+## with @var{df} degrees of freedom.
+##
+## The p-value (1 minus the CDF of this distribution at @var{chisq}) is
+## returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: McNemar's test for symmetry
+
+function [pval, chisq, df] = mcnemar_test (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! (min (size (x)) > 1) && issquare (x))
+    error ("mcnemar_test: x must be a square matrix of size > 1");
+  elseif (! (all (all (x >= 0)) && all (all (x == round (x)))))
+    error ("mcnemar_test: all entries of x must be nonnegative integers");
+  endif
+
+  r = rows (x);
+  df = r * (r - 1) / 2;
+  if (r == 2)
+    num = max (abs (x - x') - 1, 0) .^ 2;
+  else
+    num = abs (x - x') .^ 2;
+  endif
+
+  chisq = sum (sum (triu (num ./ (x + x'), 1)));
+  pval = 1 - chisquare_cdf (chisq, df);
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
+
+
+
diff --git a/scripts/statistics/tests/prop_test_2.m b/scripts/statistics/tests/prop_test_2.m
new file mode 100644
index 0000000..3b0513c
--- /dev/null
+++ b/scripts/statistics/tests/prop_test_2.m
@@ -0,0 +1,81 @@
+## Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{z}] =} prop_test_2 (@var{x1}, @var{n1}, @var{x2}, @var{n2}, @var{alt})
+## If @var{x1} and @var{n1} are the counts of successes and trials in
+## one sample, and @var{x2} and @var{n2} those in a second one, test the
+## null hypothesis that the success probabilities @var{p1} and @var{p2}
+## are the same.  Under the null, the test statistic @var{z}
+## approximately follows a standard normal distribution.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @var{p1} != @var{p2}.  If @var{alt} is @code{">"}, the one-sided
+## alternative @var{p1} > @var{p2} is used.  Similarly for @code{"<"},
+## the one-sided alternative @var{p1} < @var{p2} is used.
+## The default is the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compare two proportions
+
+function [pval, z] = prop_test_2 (x1, n1, x2, n2, alt)
+
+  if ((nargin < 4) || (nargin > 5))
+        print_usage ();
+  endif
+
+  ## Could do sanity checking on x1, n1, x2, n2 here
+
+  p1  = x1 / n1;
+  p2  = x2 / n2;
+  pc  = (x1 + x2) / (n1 + n2);
+
+  z   = (p1 - p2) / sqrt (pc * (1 - pc) * (1/n1 + 1/n2));
+
+  cdf = stdnormal_cdf (z);
+
+  if (nargin == 4)
+    alt  = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("prop_test_2: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif strcmp (alt, ">")
+    pval = 1 - cdf;
+  elseif strcmp (alt, "<")
+    pval = cdf;
+  else
+    error ("prop_test_2: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/run_test.m b/scripts/statistics/tests/run_test.m
new file mode 100644
index 0000000..c74ffa1
--- /dev/null
+++ b/scripts/statistics/tests/run_test.m
@@ -0,0 +1,59 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Friedrich Leisch
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{chisq}] =} run_test (@var{x})
+## Perform a chi-square test with 6 degrees of freedom based on the
+## upward runs in the columns of @var{x}.  Can be used to test whether
+## @var{x} contains independent data.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value is displayed.
+## @end deftypefn
+
+## Author: FL <Friedrich.Leisch at ci.tuwien.ac.at>
+## Description: Run test for independence
+
+function [pval, chisq] = run_test (x)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  A = [4529.4,  9044.9, 13568,  18091,  22615,  27892;
+       9044.4, 18097,   27139,  36187,  45234,  55789;
+      13568,   27139,   40721,  54281,  67852,  83685;
+      18091,   36187,   54281,  72414,  90470, 111580;
+      22615,   45234,   67852,  90470, 113262, 139476;
+      27892,   55789,   83685, 111580, 139476, 172860];
+
+  b = [1/6; 5/24; 11/120; 19/720; 29/5040; 1/840];
+
+  n = rows (x);
+  r = run_count (x, 6) - n * b * ones (1, columns(x));
+
+  chisq = diag (r' * A * r)' / n;
+  pval  = chisquare_cdf (chisq, 6);
+
+  if (nargout == 0)
+    printf("pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/sign_test.m b/scripts/statistics/tests/sign_test.m
new file mode 100644
index 0000000..eb3755e
--- /dev/null
+++ b/scripts/statistics/tests/sign_test.m
@@ -0,0 +1,84 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{b}, @var{n}] =} sign_test (@var{x}, @var{y}, @var{alt})
+## For two matched-pair samples @var{x} and @var{y}, perform a sign test
+## of the null hypothesis PROB (@var{x} > @var{y}) == PROB (@var{x} <
+## @var{y}) == 1/2.  Under the null, the test statistic @var{b} roughly
+## follows a binomial distribution with parameters @code{@var{n} = sum
+## (@var{x} != @var{y})} and @var{p} = 1/2.
+##
+## With the optional argument @code{alt}, the alternative of interest
+## can be selected.  If @var{alt} is @code{"!="} or @code{"<>"}, the
+## null hypothesis is tested against the two-sided alternative PROB
+## (@var{x} < @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+## one-sided alternative PROB (@var{x} > @var{y}) > 1/2 ("x is
+## stochastically greater than y") is considered.  Similarly for
+## @code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) < 1/2
+## ("x is stochastically less than y") is considered.  The default is
+## the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Sign test
+
+function [pval, b, n] = sign_test (x, y, alt)
+
+  if ((nargin < 2) || (nargin > 3))
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y) && (length (x) == length (y))))
+    error ("sign_test: x and y must be vectors of the same length");
+  endif
+
+  n   = length (x);
+  x   = reshape (x, 1, n);
+  y   = reshape (y, 1, n);
+  n   = sum (x != y);
+  b   = sum (x > y);
+  cdf = binomial_cdf (b, n, 1/2);
+
+  if (nargin == 2)
+    alt  = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("sign_test: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif strcmp (alt, ">")
+    pval = 1 - cdf;
+  elseif strcmp (alt, "<")
+    pval = cdf;
+  else
+    error ("sign_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/t_test.m b/scripts/statistics/tests/t_test.m
new file mode 100644
index 0000000..7e570f2
--- /dev/null
+++ b/scripts/statistics/tests/t_test.m
@@ -0,0 +1,84 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test (@var{x}, @var{m}, @var{alt})
+## For a sample @var{x} from a normal distribution with unknown mean and
+## variance, perform a t-test of the null hypothesis @code{mean
+## (@var{x}) == @var{m}}.  Under the null, the test statistic @var{t}
+## follows a Student distribution with @code{@var{df} = length (@var{x})
+## - 1} degrees of freedom.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+## one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
+## Similarly for @var{"<"}, the one-sided alternative @code{mean
+## (@var{x}) < @var{m}} is considered.  The default is the two-sided
+## case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Student's one-sample t test
+
+function [pval, t, df] = t_test (x, m, alt)
+
+  if ((nargin < 2) || (nargin > 3))
+    print_usage ();
+  endif
+
+  if (! isvector (x))
+    error ("t_test: x must be a vector");
+  endif
+  if (! isscalar (m))
+    error ("t_test: m must be a scalar");
+  endif
+
+  n   = length (x);
+  df  = n - 1;
+  t   = sqrt (n) * (sum (x) / n - m) / std (x);
+  cdf = t_cdf (t, df);
+
+  if (nargin == 2)
+    alt  = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("t_test: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif strcmp (alt, ">")
+    pval = 1 - cdf;
+  elseif strcmp (alt, "<")
+    pval = cdf;
+  else
+    error ("t_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/t_test_2.m b/scripts/statistics/tests/t_test_2.m
new file mode 100644
index 0000000..e751aa6
--- /dev/null
+++ b/scripts/statistics/tests/t_test_2.m
@@ -0,0 +1,85 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test_2 (@var{x}, @var{y}, @var{alt})
+## For two samples x and y from normal distributions with unknown means
+## and unknown equal variances, perform a two-sample t-test of the null
+## hypothesis of equal means.  Under the null, the test statistic
+## @var{t} follows a Student distribution with @var{df} degrees of
+## freedom.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != mean (@var{y})}.  If @var{alt} is @code{">"},
+## the one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is
+## used.  Similarly for @code{"<"}, the one-sided alternative @code{mean
+## (@var{x}) < mean (@var{y})} is used.  The default is the two-sided
+## case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Student's two-sample t test
+
+function [pval, t, df] = t_test_2 (x, y, alt)
+
+  if ((nargin < 2) || (nargin > 3))
+        print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y)))
+    error ("t_test_2: both x and y must be vectors");
+  endif
+
+  n_x  = length (x);
+  n_y  = length (y);
+  df   = n_x + n_y - 2;
+  mu_x = sum (x) / n_x;
+  mu_y = sum (y) / n_y;
+  v    = sumsq (x - mu_x) + sumsq (y - mu_y);
+  t    = (mu_x - mu_y) * sqrt ((n_x * n_y * df) / (v * (n_x + n_y)));
+  cdf  = t_cdf (t, df);
+
+  if (nargin == 2)
+    alt = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("t_test_2: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif strcmp (alt, ">")
+    pval = 1 - cdf;
+  elseif strcmp (alt, "<")
+    pval = cdf;
+  else
+    error ("t_test_2: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/t_test_regression.m b/scripts/statistics/tests/t_test_regression.m
new file mode 100644
index 0000000..eb052fa
--- /dev/null
+++ b/scripts/statistics/tests/t_test_regression.m
@@ -0,0 +1,97 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} t_test_regression (@var{y}, @var{x}, @var{rr}, @var{r}, @var{alt})
+## Perform an t test for the null hypothesis @code{@var{rr} * @var{b} =
+## @var{r}} in a classical normal regression model @code{@var{y} =
+## @var{x} * @var{b} + @var{e}}.  Under the null, the test statistic @var{t}
+## follows a @var{t} distribution with @var{df} degrees of freedom.
+##
+## If @var{r} is omitted, a value of 0 is assumed.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{@var{rr} * @var{b} != @var{r}}.  If @var{alt} is @code{">"}, the
+## one-sided alternative @code{@var{rr} * @var{b} > @var{r}} is used.
+## Similarly for @var{"<"}, the one-sided alternative @code{@var{rr} *
+## @var{b} < @var{r}} is used.  The default is the two-sided case. 
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Test one linear hypothesis in linear regression model
+
+function [pval, t, df] = t_test_regression (y, X, R, r, alt)
+
+  if (nargin == 3)
+    r   = 0;
+    alt = "!=";
+  elseif (nargin == 4)
+    if (ischar (r))
+      alt = r;
+      r   = 0;
+    else
+      alt = "!=";
+    endif
+  elseif (! (nargin == 5))
+    print_usage ();
+  endif
+
+  if (! isscalar (r))
+    error ("t_test_regression: r must be a scalar");
+  elseif (! ischar (alt))
+    error ("t_test_regression: alt must be a string");
+  endif
+
+  [T, k] = size (X);
+  if (! (isvector (y) && (length (y) == T)))
+    error ("t_test_regression: y must be a vector of length rows (X)");
+  endif
+  s      = size (R);
+  if (! ((max (s) == k) && (min (s) == 1)))
+    error ("t_test_regression: R must be a vector of length columns (X)");
+  endif
+
+  R      = reshape (R, 1, k);
+  y      = reshape (y, T, 1);
+  [b, v] = ols (y, X);
+  df     = T - k;
+  t      = (R * b - r) / sqrt (v * R * inv (X' * X) * R');
+  cdf    = t_cdf (t, df);
+
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif strcmp (alt, ">")
+    pval = 1 - cdf;
+  elseif strcmp (alt, "<")
+    pval = cdf;
+  else
+    error ("t_test_regression: the value `%s' for alt is not possible", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/u_test.m b/scripts/statistics/tests/u_test.m
new file mode 100644
index 0000000..8b1317c
--- /dev/null
+++ b/scripts/statistics/tests/u_test.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{z}] =} u_test (@var{x}, @var{y}, @var{alt})
+## For two samples @var{x} and @var{y}, perform a Mann-Whitney U-test of
+## the null hypothesis PROB (@var{x} > @var{y}) == 1/2 == PROB (@var{x}
+## < @var{y}).  Under the null, the test statistic @var{z} approximately
+## follows a standard normal distribution.  Note that this test is
+## equivalent to the Wilcoxon rank-sum test.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## PROB (@var{x} > @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+## one-sided alternative PROB (@var{x} > @var{y}) > 1/2 is considered.
+## Similarly for @code{"<"}, the one-sided alternative PROB (@var{x} >
+## @var{y}) < 1/2 is considered.  The default is the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## This implementation is still incomplete---for small sample sizes,
+## the normal approximation is rather bad ...
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Mann-Whitney U-test
+
+function [pval, z] = u_test (x, y, alt)
+
+  if ((nargin < 2) || (nargin > 3))
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y)))
+    error ("u_test: both x and y must be vectors");
+  endif
+
+  n_x  = length (x);
+  n_y  = length (y);
+  r    = ranks ([(reshape (x, 1, n_x)), (reshape (y, 1, n_y))]);
+  z    = (sum (r(1 : n_x)) - n_x * (n_x + n_y + 1) / 2) ...
+           / sqrt (n_x * n_y * (n_x + n_y + 1) / 12);
+
+  cdf  = stdnormal_cdf (z);
+
+  if (nargin == 2)
+    alt  = "!=";
+  endif
+
+  if (! ischar (alt))
+    error("u_test: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (alt, ">"))
+    pval = cdf;
+  elseif (strcmp (alt, "<"))
+    pval = 1 - cdf;
+  else
+    error ("u_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/var_test.m b/scripts/statistics/tests/var_test.m
new file mode 100644
index 0000000..153a85d
--- /dev/null
+++ b/scripts/statistics/tests/var_test.m
@@ -0,0 +1,81 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{f}, @var{df_num}, @var{df_den}] =} var_test (@var{x}, @var{y}, @var{alt})
+## For two samples @var{x} and @var{y} from normal distributions with
+## unknown means and unknown variances, perform an F-test of the null
+## hypothesis of equal variances.  Under the null, the test statistic
+## @var{f} follows an F-distribution with @var{df_num} and @var{df_den}
+## degrees of freedom.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{var (@var{x}) != var (@var{y})}.  If @var{alt} is @code{">"},
+## the one-sided alternative @code{var (@var{x}) > var (@var{y})} is
+## used.  Similarly for "<", the one-sided alternative @code{var
+## (@var{x}) > var (@var{y})} is used.  The default is the two-sided
+## case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: F test to compare two variances
+
+function [pval, f, df_num, df_den] = var_test (x, y, alt)
+
+  if ((nargin < 2) || (nargin > 3))
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y)))
+    error ("var_test: both x and y must be vectors");
+  endif
+
+  df_num = length (x) - 1;
+  df_den = length (y) - 1;
+  f      = var (x) / var (y);
+  cdf    = f_cdf (f, df_num, df_den);
+
+  if (nargin == 2)
+    alt  = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("var_test: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (alt, ">"))
+    pval = 1 - cdf;
+  elseif (strcmp (alt, "<"))
+    pval = cdf;
+  else
+    error ("var_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/welch_test.m b/scripts/statistics/tests/welch_test.m
new file mode 100644
index 0000000..332948f
--- /dev/null
+++ b/scripts/statistics/tests/welch_test.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2005, 2006,
+##               2007 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{t}, @var{df}] =} welch_test (@var{x}, @var{y}, @var{alt})
+## For two samples @var{x} and @var{y} from normal distributions with
+## unknown means and unknown and not necessarily equal variances,
+## perform a Welch test of the null hypothesis of equal means.
+## Under the null, the test statistic @var{t} approximately follows a
+## Student distribution with @var{df} degrees of freedom.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+## one-sided alternative mean(x) > @var{m} is considered.  Similarly for
+## @code{"<"}, the one-sided alternative mean(x) < @var{m} is
+## considered.  The default is the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Welch two-sample t test
+
+function [pval, t, df] = welch_test (x, y, alt)
+
+  if ((nargin < 2) || (nargin > 3))
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y)))
+    error ("welch_test: both x and y must be vectors");
+  endif
+
+  n_x  = length (x);
+  n_y  = length (y);
+  mu_x = sum (x) / n_x;
+  mu_y = sum (y) / n_y;
+  v_x  = sumsq (x - mu_x) / (n_x * (n_x - 1));
+  v_y  = sumsq (y - mu_y) / (n_y * (n_y - 1));
+  c    = v_x / (v_x + v_y);
+  df   = 1 / (c^2 / (n_x - 1) + (1 - c)^2 / (n_y - 1));
+  t    = (mu_x - mu_y) / sqrt (v_x + v_y);
+  cdf  = t_cdf (t, df);
+
+  if (nargin == 2)
+    alt  = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("welch_test: alt must be a string");
+  endif
+  if (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (alt, ">"))
+    pval = 1 - cdf;
+  elseif (strcmp (alt, "<"))
+    pval = cdf;
+  else
+    error ("welch_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/wilcoxon_test.m b/scripts/statistics/tests/wilcoxon_test.m
new file mode 100644
index 0000000..512e50f
--- /dev/null
+++ b/scripts/statistics/tests/wilcoxon_test.m
@@ -0,0 +1,92 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{z}] =} wilcoxon_test (@var{x}, @var{y}, @var{alt})
+## For two matched-pair sample vectors @var{x} and @var{y}, perform a
+## Wilcoxon signed-rank test of the null hypothesis PROB (@var{x} >
+## @var{y}) == 1/2.  Under the null, the test statistic @var{z}
+## approximately follows a standard normal distribution when @var{n} > 25.
+##
+## @strong{Warning}: This function assumes a normal distribution for @var{z}
+## and thus is invalid for @var{n} <= 25.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## PROB (@var{x} > @var{y}) != 1/2.  If alt is @code{">"}, the one-sided
+## alternative PROB (@var{x} > @var{y}) > 1/2 is considered.  Similarly
+## for @code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) <
+## 1/2 is considered.  The default is the two-sided case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Wilcoxon signed-rank test
+
+function [pval, z] = wilcoxon_test (x, y, alt)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y) && (length (x) == length (y))))
+    error ("wilcoxon_test: x and y must be vectors of the same length");
+  endif
+
+  n = length (x);
+  x = reshape (x, 1, n);
+  y = reshape (y, 1, n);
+  d = x - y;
+  d = d (find (d != 0));
+  n = length (d);
+  if (n > 25)
+    r = ranks (abs (d));
+    z = sum (r (find (d > 0)));
+    z = ((z - n * (n + 1) / 4) / sqrt (n * (n + 1) * (2 * n + 1) / 24));
+  else
+    error ("wilcoxon_test: implementation requires more than 25 different pairs");
+  endif
+
+  cdf = stdnormal_cdf (z);
+
+  if (nargin == 2)
+    alt = "!=";
+  endif
+
+  if (! ischar (alt))
+    error("wilcoxon_test: alt must be a string");
+  elseif (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (alt, ">"))
+    pval = 1 - cdf;
+  elseif (strcmp (alt, "<"))
+    pval = cdf;
+  else
+    error ("wilcoxon_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    printf ("  pval: %g\n", pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/z_test.m b/scripts/statistics/tests/z_test.m
new file mode 100644
index 0000000..8032032
--- /dev/null
+++ b/scripts/statistics/tests/z_test.m
@@ -0,0 +1,88 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2008
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{z}] =} z_test (@var{x}, @var{m}, @var{v}, @var{alt})
+## Perform a Z-test of the null hypothesis @code{mean (@var{x}) ==
+## @var{m}} for a sample @var{x} from a normal distribution with unknown
+## mean and known variance @var{v}.  Under the null, the test statistic
+## @var{z} follows a standard normal distribution.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+## one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
+## Similarly for @code{"<"}, the one-sided alternative @code{mean
+## (@var{x}) < @var{m}} is considered.  The default is the two-sided
+## case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed
+## along with some information.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Test for mean of a normal sample with known variance
+
+function [pval, z] = z_test (x, m, v, alt)
+
+  if ((nargin < 3) || (nargin > 4))
+    print_usage ();
+  endif
+
+  if (! isvector (x))
+    error ("z_test: x must be a vector");
+  endif
+  if (! isscalar (m))
+    error ("z_test: m must be a scalar");
+  endif
+  if (! (isscalar (v) && (v > 0)))
+    error ("z_test: v must be a positive scalar");
+  endif
+
+  n = length (x);
+  z = sqrt (n/v) * (sum (x) / n - m);
+  cdf = stdnormal_cdf (z);
+
+  if (nargin == 3)
+    alt = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("z_test: alt must be a string");
+  elseif (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (alt, ">"))
+    pval = 1 - cdf;
+  elseif (strcmp (alt, "<"))
+    pval = cdf;
+  else
+    error ("z_test: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    s = cstrcat ("Z-test of mean(x) == %g against mean(x) %s %g,\n",
+                "with known var(x) == %g:\n",
+                "  pval = %g\n");
+    printf (s, m, alt, m, v, pval);
+  endif
+
+endfunction
diff --git a/scripts/statistics/tests/z_test_2.m b/scripts/statistics/tests/z_test_2.m
new file mode 100644
index 0000000..b24ace2
--- /dev/null
+++ b/scripts/statistics/tests/z_test_2.m
@@ -0,0 +1,89 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2008
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{pval}, @var{z}] =} z_test_2 (@var{x}, @var{y}, @var{v_x}, @var{v_y}, @var{alt})
+## For two samples @var{x} and @var{y} from normal distributions with
+## unknown means and known variances @var{v_x} and @var{v_y}, perform a
+## Z-test of the hypothesis of equal means.  Under the null, the test
+## statistic @var{z} follows a standard normal distribution.
+##
+## With the optional argument string @var{alt}, the alternative of
+## interest can be selected.  If @var{alt} is @code{"!="} or
+## @code{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != mean (@var{y})}.  If alt is @code{">"}, the
+## one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is used.
+## Similarly for @code{"<"}, the one-sided alternative @code{mean
+## (@var{x}) < mean (@var{y})} is used.  The default is the two-sided
+## case.
+##
+## The p-value of the test is returned in @var{pval}.
+##
+## If no output argument is given, the p-value of the test is displayed
+## along with some information.
+## @end deftypefn
+
+## Author: KH <Kurt.Hornik at wu-wien.ac.at>
+## Description: Compare means of two normal samples with known variances
+
+function [pval, z] = z_test_2 (x, y, v_x, v_y, alt)
+
+  if ((nargin < 4) || (nargin > 5))
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y)))
+    error("z_test_2: both x and y must be vectors");
+  elseif (! (isscalar (v_x) && (v_x > 0)
+             && isscalar (v_y) && (v_y > 0)))
+    error ("z_test_2: both v_x and v_y must be positive scalars");
+  endif
+
+  n_x  = length (x);
+  n_y  = length (y);
+  mu_x = sum (x) / n_x;
+  mu_y = sum (y) / n_y;
+  z    = (mu_x - mu_y) / sqrt (v_x / n_x + v_y / n_y);
+  cdf  = stdnormal_cdf (z);
+
+  if (nargin == 4)
+    alt = "!=";
+  endif
+
+  if (! ischar (alt))
+    error ("z_test_2: alt must be a string");
+  elseif (strcmp (alt, "!=") || strcmp (alt, "<>"))
+    pval = 2 * min (cdf, 1 - cdf);
+  elseif (strcmp (alt, ">"))
+    pval = 1 - cdf;
+  elseif (strcmp (alt, "<"))
+    pval = cdf;
+  else
+    error ("z_test_2: option %s not recognized", alt);
+  endif
+
+  if (nargout == 0)
+    s = cstrcat ("Two-sample Z-test of mean(x) == mean(y) against ",
+                "mean(x) %s mean(y),\n",
+                "with known var(x) == %g and var(y) == %g:\n",
+                "  pval = %g\n");
+    printf (s, alt, v_x, v_y, pval);
+  endif
+
+endfunction
diff --git a/scripts/strings/Makefile.in b/scripts/strings/Makefile.in
new file mode 100644
index 0000000..6151e5a
--- /dev/null
+++ b/scripts/strings/Makefile.in
@@ -0,0 +1,89 @@
+# Makefile for octave's scripts/strings directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008, 2009
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = strings
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = base2dec.m bin2dec.m blanks.m deblank.m dec2base.m \
+  dec2bin.m dec2hex.m findstr.m hex2dec.m index.m isletter.m isstrprop.m \
+  mat2str.m regexptranslate.m rindex.m strsplit.m str2double.m \
+  str2num.m strcat.m cstrcat.m strcmpi.m strchr.m strfind.m strjust.m strmatch.m \
+  strncmpi.m strrep.m strtok.m strtrim.m strtrunc.m \
+  substr.m validatestring.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/strings
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/strings/base2dec.m b/scripts/strings/base2dec.m
new file mode 100644
index 0000000..6ce07bd
--- /dev/null
+++ b/scripts/strings/base2dec.m
@@ -0,0 +1,93 @@
+## Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009 Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} base2dec (@var{s}, @var{b})
+## Convert @var{s} from a string of digits of base @var{b} into an
+## integer.
+##
+## @example
+## @group
+## base2dec ("11120", 3)
+##      @result{} 123
+## @end group
+## @end example
+##
+## If @var{s} is a matrix, returns a column vector with one value per
+## row of @var{s}.  If a row contains invalid symbols then the
+## corresponding value will be NaN.  Rows are right-justified before
+## converting so that trailing spaces are ignored.
+##
+## If @var{b} is a string, the characters of @var{b} are used as the
+## symbols for the digits of @var{s}.  Space (' ') may not be used as a
+## symbol.
+##
+## @example
+## @group
+## base2dec ("yyyzx", "xyz")
+##      @result{} 123
+## @end group
+## @end example
+## @seealso{dec2base, dec2bin, bin2dec, hex2dec, dec2hex}
+## @end deftypefn
+
+## Author: Daniel Calvelo <dcalvelo at yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+
+function out = base2dec (d, base)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  if (ischar (base))
+    symbols = base;
+    base = length (symbols);
+    if (any (diff (sort (toascii (symbols))) == 0))
+      error ("base2dec: symbols representing digits must be unique");
+    endif
+  elseif (! isscalar (base))
+    error ("base2dec: cannot convert from several bases at once");
+  elseif (base < 2 || base > length (symbols))
+    error ("base2dec: base must be between 2 and 36 or a string of symbols");
+  else
+    d = toupper (d);
+  endif
+
+  ## Right justify the values before anything else.
+  d = strjust (d, "right");
+
+  ## Lookup value of symbols in symbol table, with invalid symbols
+  ## evaluating to NaN and space evaluating to 0.
+  table = NaN * ones (256, 1);
+  table (toascii (symbols (1 : base))) = 0 : base-1;
+  table (toascii (" ")) = 0;
+  d = reshape (table (toascii (d)), size (d));
+
+  ## Multiply the resulting digits by the appropriate power and
+  ## sum the rows.
+  out = d * (base .^ (columns(d)-1 : -1 : 0)');
+
+endfunction
+
+%!error <Invalid call to base2dec.*> base2dec();
+%!error <Invalid call to base2dec.*> base2dec("11120");
+%!error <Invalid call to base2dec.*> base2dec("11120", 3, 4);
+%!assert(base2dec ("11120", 3), 123);
+%!assert(base2dec ("yyyzx", "xyz"), 123);
diff --git a/scripts/strings/bin2dec.m b/scripts/strings/bin2dec.m
new file mode 100644
index 0000000..e8960bf
--- /dev/null
+++ b/scripts/strings/bin2dec.m
@@ -0,0 +1,61 @@
+## Copyright (C) 1996, 2000, 2001, 2005, 2006, 2007, 2008, 2009
+##               Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} bin2dec (@var{s})
+## Return the decimal number corresponding to the binary number stored
+## in the string @var{s}.  For example,
+##
+## @example
+## @group
+## bin2dec ("1110")
+##      @result{} 14
+## @end group
+## @end example
+##
+## If @var{s} is a string matrix, returns a column vector of converted
+## numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
+## @seealso{dec2hex, base2dec, dec2base, hex2dec, dec2bin}
+## @end deftypefn
+
+## Author: Daniel Calvelo <dcalvelo at yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+
+function d = bin2dec (h)
+
+  if (nargin == 1 && ischar (h))
+    n = rows (h);
+    d = zeros (n, 1);
+    for i = 1:n
+      s = h(i,:);
+      s = s(! isspace (s));
+      d(i) = base2dec (s, 2);
+    endfor
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(bin2dec ("1110") == 14);
+
+%!error bin2dec ();
+
+%!error bin2dec ("str", 1);
+
diff --git a/scripts/strings/blanks.m b/scripts/strings/blanks.m
new file mode 100644
index 0000000..4a62c07
--- /dev/null
+++ b/scripts/strings/blanks.m
@@ -0,0 +1,64 @@
+## Copyright (C) 1996, 1997, 1999, 2002, 2003, 2005, 2006, 2007, 2008, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} blanks (@var{n})
+## Return a string of @var{n} blanks, for example:
+##
+## @example
+## @group
+## blanks(10);
+## whos ans;
+##      @result{}
+##       Attr Name        Size                     Bytes  Class
+##       ==== ====        ====                     =====  ===== 
+##            ans         1x10                        10  char
+## @end group
+## @end example
+## @seealso{repmat}
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+function s = blanks (n)
+
+  if (nargin != 1)
+    print_usage ();
+  elseif (! (isscalar (n) && n == round (n)))
+    error ("blanks: n must be a non-negative integer");
+  endif
+
+  ## If 1:n is empty, the following expression will create an empty
+  ## character string.  Otherwise, it will create a row vector.
+  s(1:n) = " ";
+
+endfunction
+
+## There really isn't that much to test here
+%!assert(blanks (0), "")
+%!assert(blanks (5), "     ")
+%!assert(blanks (10), "          ")
+
+%!assert(strcmp (blanks (3), "   "));
+
+%!error blanks ();
+
+%!error blanks (1, 2);
+
diff --git a/scripts/strings/cstrcat.m b/scripts/strings/cstrcat.m
new file mode 100644
index 0000000..e492631
--- /dev/null
+++ b/scripts/strings/cstrcat.m
@@ -0,0 +1,80 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} cstrcat (@var{s1}, @var{s2}, @dots{})
+## Return a string containing all the arguments concatenated
+## horizontally.  Trailing white space is preserved.  For example,
+##
+## @example
+## @group
+## cstrcat ("ab   ", "cd")
+##      @result{} "ab   cd"
+## @end group
+## @end example
+##
+## @example
+## @group
+## s = [ "ab"; "cde" ];
+## cstrcat (s, s, s)
+##      @result{} ans =
+##         "ab ab ab "
+##         "cdecdecde"
+## @end group
+## @end example
+## @seealso{strcat, char, strvcat}
+## @end deftypefn
+
+## Author: jwe
+
+function st = cstrcat (varargin)
+
+  if (nargin > 0)
+
+    if (iscellstr (varargin))
+      ## All arguments are character strings.
+      unwind_protect
+	tmp = warning ("query", "Octave:empty-list-elements");
+	warning ("off", "Octave:empty-list-elements");
+	st = [varargin{:}];
+      unwind_protect_cleanup
+	warning (tmp.state, "Octave:empty-list-elements");
+      end_unwind_protect
+    else
+      error ("cstrcat: expecting arguments to character strings");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+## test the dimensionality
+## 1d
+%!assert(cstrcat("ab ", "ab "), "ab ab ")
+## 2d
+%!assert(cstrcat(["ab ";"cde"], ["ab ";"cde"]), ["ab ab ";"cdecde"])
+
+%!assert((strcmp (cstrcat ("foo", "bar"), "foobar")
+%! && strcmp (cstrcat (["a"; "bb"], ["foo"; "bar"]), ["a foo"; "bbbar"])));
+
+%!error cstrcat ();
+
+%!error cstrcat (1, 2);
+
diff --git a/scripts/strings/deblank.m b/scripts/strings/deblank.m
new file mode 100644
index 0000000..bb398e1
--- /dev/null
+++ b/scripts/strings/deblank.m
@@ -0,0 +1,86 @@
+## Copyright (C) 1996, 1998, 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} deblank (@var{s})
+## Remove trailing blanks and nulls from @var{s}.  If @var{s}
+## is a matrix, @var{deblank} trims each row to the length of longest
+## string.  If @var{s} is a cell array, operate recursively on each
+## element of the cell array.
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+function s = deblank (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  char_arg = ischar (s);
+
+  if (char_arg || isnumeric (s))
+
+    if (! isempty (s))
+      if (char_arg)
+	k = find (! isspace (s) & s != "\0");
+      else
+	warning ("deblank: expecting character string argument")
+	k = find (s != 0);
+      endif
+
+      if (isempty (k))
+	s = resize (s, 0, 0);
+      else
+	s = s(:,1:ceil (max (k) / rows (s)));
+      endif
+    endif
+
+  elseif (iscell(s))
+
+    s = cellfun (@deblank, s, "UniformOutput", false);
+
+  else
+    error ("deblank: expecting character string argument");
+  endif
+
+endfunction
+
+%!assert (strcmp (deblank (" f o o  "), " f o o"));
+
+%!assert (deblank ([]), [])
+%!assert (deblank ({}), {})
+%!assert (deblank (""), "")
+
+%!assert (deblank ([0,0,0]), [])
+%!assert (deblank ('   '), '')
+%!assert (deblank ("   "), "")
+
+%!assert (typeinfo (deblank ("   ")), "string")
+%!assert (typeinfo (deblank ('   ')), "sq_string")
+
+%!assert (deblank ([1,2,0]), [1,2])
+%!assert (deblank ([1,2,0,32]), [1,2,0,32])
+
+%!assert (deblank (int8 ([1,2,0])), int8 ([1,2]))
+
+%!error deblank ();
+
+%!error deblank ("foo", "bar");
diff --git a/scripts/strings/dec2base.m b/scripts/strings/dec2base.m
new file mode 100644
index 0000000..f0a5d86
--- /dev/null
+++ b/scripts/strings/dec2base.m
@@ -0,0 +1,134 @@
+## Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009 Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dec2base (@var{n}, @var{b}, @var{len})
+## Return a string of symbols in base @var{b} corresponding to
+## the non-negative integer @var{n}.
+##
+## @example
+## @group
+## dec2base (123, 3)
+##      @result{} "11120"
+## @end group
+## @end example
+##
+## If @var{n} is a vector, return a string matrix with one row per value,
+## padded with leading zeros to the width of the largest value.
+##
+## If @var{b} is a string then the characters of @var{b} are used as
+## the symbols for the digits of @var{n}.  Space (' ') may not be used
+## as a symbol.
+##
+## @example
+## @group
+## dec2base (123, "aei")
+##      @result{} "eeeia"
+## @end group
+## @end example
+##
+## The optional third argument, @var{len}, specifies the minimum
+## number of digits in the result.
+## @seealso{base2dec, dec2bin, bin2dec, hex2dec, dec2hex}
+## @end deftypefn
+
+## Author: Daniel Calvelo <dcalvelo at yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+
+function retval = dec2base (n, base, len)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (numel (n) != length (n))
+    n = n(:);
+  elseif (any (n < 0 | n != fix (n)))
+    error ("dec2base: can only convert non-negative integers");
+  endif
+
+  symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  if (ischar (base))
+    symbols = base;
+    base = length (symbols);
+    if any (diff (sort (toascii (symbols))) == 0)
+      error ("dec2base: symbols representing digits must be unique");
+    endif
+  elseif (! isscalar (base))
+    error ("dec2base: cannot convert from several bases at once");
+  elseif (base < 2 || base > length (symbols))
+    error ("dec2base: base must be between 2 and 36 or a string of symbols");
+  endif
+  
+  ## determine number of digits required to handle all numbers, can overflow
+  ## by 1 digit
+  max_len = round (log (max (max (n), 1)) ./ log (base)) + 1;
+
+  if (nargin == 3)
+    max_len = max (max_len, len);
+  endif
+  
+  ## determine digits for each number
+  power = ones (length (n), 1) * (base .^ (max_len-1 : -1 : 0));
+  n = n(:) * ones (1, max_len);
+  digits = floor (rem (n, base*power) ./ power);
+
+  ## convert digits to symbols
+  retval = reshape (symbols (digits+1), size (digits));
+
+  ## Check if the first element is the zero symbol. It seems possible
+  ## that LEN is provided, and is less than the computed MAX_LEN and
+  ## MAX_LEN is computed to be one larger than necessary, so we would
+  ## have a leading zero to remove.  But if LEN >= MAX_LEN, we should
+  ## not remove any leading zeros.
+  if ((nargin == 2 || (nargin == 3 && max_len > len))
+      && all (retval(:,1) == symbols(1)) && length (retval) != 1)
+    retval = retval(:,2:end);
+  endif
+
+endfunction
+
+%!test
+%! s0='';
+%! for n=1:13
+%!   for b=2:16
+%!     pp=dec2base(b^n+1,b);
+%!     assert(dec2base(b^n,b),['1',s0,'0']);
+%!     assert(dec2base(b^n+1,b),['1',s0,'1']);
+%!   end
+%!   s0=[s0,'0'];
+%! end
+
+%!test
+%! digits='0123456789ABCDEF';
+%! for n=1:13
+%!   for b=2:16
+%!     pm=dec2base(b^n-1,b);
+%!     assert(length(pm),n);
+%!     assert(all(pm==digits(b)));
+%!   end
+%! end
+
+%!test
+%! for b=2:16
+%!   assert(dec2base(0,b),'0');
+%! end
+
+%!test
+%!   assert(dec2base(2^51-1,2),
+%!          '111111111111111111111111111111111111111111111111111');
diff --git a/scripts/strings/dec2bin.m b/scripts/strings/dec2bin.m
new file mode 100644
index 0000000..faecdf2
--- /dev/null
+++ b/scripts/strings/dec2bin.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1996, 1999, 2000, 2001, 2003, 2005, 2006, 2007, 2008, 2009
+##               Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dec2bin (@var{n}, @var{len})
+## Return a binary number corresponding to the non-negative decimal number
+## @var{n}, as a string of ones and zeros.  For example,
+##
+## @example
+## @group
+## dec2bin (14)
+##      @result{} "1110"
+## @end group
+## @end example
+##
+## If @var{n} is a vector, returns a string matrix, one row per value,
+## padded with leading zeros to the width of the largest value.
+##
+## The optional second argument, @var{len}, specifies the minimum
+## number of digits in the result.
+## @seealso{bin2dec, dec2base, base2dec, hex2dec, dec2hex}
+## @end deftypefn
+
+## Author: Daniel Calvelo <dcalvelo at yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+
+function retval = dec2bin (n, len)
+
+  if (nargin == 1)
+    retval = dec2base (n, 2);
+  elseif (nargin == 2)
+    retval = dec2base (n, 2, len);
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(strcmp (dec2bin (14), "1110"));
+
+%!error dec2bin ();
+
+%!assert(strcmp (dec2bin (14, 6), "001110"));
+
+%!error dec2bin (1, 2, 3);
+
diff --git a/scripts/strings/dec2hex.m b/scripts/strings/dec2hex.m
new file mode 100644
index 0000000..1550c07
--- /dev/null
+++ b/scripts/strings/dec2hex.m
@@ -0,0 +1,62 @@
+## Copyright (C) 1996, 1999, 2000, 2001, 2003, 2005, 2006, 2007, 2008, 2009
+##               Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dec2hex (@var{n}, @var{len})
+## Return the hexadecimal string corresponding to the non-negative 
+## integer @var{n}.  For example,
+##
+## @example
+## @group
+## dec2hex (2748)
+##      @result{} "ABC"
+## @end group
+## @end example
+##
+## If @var{n} is a vector, returns a string matrix, one row per value,
+## padded with leading zeros to the width of the largest value.
+##
+## The optional second argument, @var{len}, specifies the minimum
+## number of digits in the result.
+## @seealso{hex2dec, dec2base, base2dec, bin2dec, dec2bin}
+## @end deftypefn
+
+## Author: Daniel Calvelo <dcalvelo at yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+
+function retval = dec2hex (n, len)
+
+  if (nargin == 1)
+    retval = dec2base (n, 16);
+  elseif (nargin == 2)
+    retval = dec2base (n, 16, len);
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(strcmp (tolower (dec2hex (2748)), "abc"));
+
+%!error dec2hex ();
+
+%!assert(strcmp (tolower (dec2hex (2748, 5)), "00abc"));
+
+%!error dec2hex (1, 2, 3);
+
diff --git a/scripts/strings/findstr.m b/scripts/strings/findstr.m
new file mode 100644
index 0000000..649b8ea
--- /dev/null
+++ b/scripts/strings/findstr.m
@@ -0,0 +1,144 @@
+## Copyright (C) 1996, 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2008, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} findstr (@var{s}, @var{t}, @var{overlap})
+## Return the vector of all positions in the longer of the two strings
+## @var{s} and @var{t} where an occurrence of the shorter of the two starts.
+## If the optional argument @var{overlap} is nonzero, the returned vector
+## can include overlapping positions (this is the default).  For example,
+##
+## @example
+## @group
+## findstr ("ababab", "a")
+##      @result{} [1, 3, 5]
+## findstr ("abababa", "aba", 0)
+##      @result{} [1, 5]
+## @end group
+## @end example
+## @seealso{strfind, strmatch, strcmp, strncmp, strcmpi, strncmpi, find}
+## @end deftypefn
+
+## Note that this implementation swaps the strings if second one is longer
+## than the first, so try to put the longer one first.
+##
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+function v = findstr (s, t, overlap)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (all (size (s) > 1) || all (size (t) > 1))
+    error ("findstr: arguments must have only one non-singleton dimension");
+  endif
+
+  if (nargin == 2)
+    overlap = 1;
+  endif
+
+  ## Make S be the longer string.
+  if (length (s) < length (t))
+    tmp = s;
+    s = t;
+    t = tmp;
+  endif
+  
+  l_s = length (s);
+  l_t = length (t);
+  
+  if (l_t == 0)
+    ## zero length target: return empty set
+    v = [];
+    
+  elseif (l_t == 1)
+    ## length one target: simple find
+    v = find (s == t);
+    
+  elseif (l_t == 2)
+    ## length two target: find first at i and second at i+1
+    v = find (s(1:l_s-1) == t(1) & s(2:l_s) == t(2));
+    
+  else
+    ## length three or more: match the first three by find then go through
+    ## the much smaller list to determine which of them are real matches
+    limit = l_s - l_t + 1;
+    v = find (s(1:limit) == t(1)
+	      & s(2:limit+1) == t(2)
+	      & s (3:limit+2) == t(3));
+  endif
+
+  ## Need to search the index vector if our find was too short
+  ## (target length > 3), or if we don't allow overlaps.  Note though
+  ## that there cannot be any overlaps if the first character in the
+  ## target is different from the remaining characters in the target,
+  ## so a single character, two different characters, or first character
+  ## different from the second two don't need to be searched.
+  if (l_t >= 3 || (! overlap && l_t > 1 && any (t(1) == t(2:l_t))))
+    ## force strings to be both row vectors or both column vectors
+    if (all (size (s) != size (t)))
+      t = t.';
+    endif
+    
+    ## determine which ones to keep
+    keep = zeros (size (v));
+    ind = 0:l_t-1;
+    if (overlap)
+      for idx = 1:length (v)
+	keep(idx) = all (s(v(idx) + ind) == t);
+      endfor
+    else
+      ## First possible position for next non-overlapping match.
+      next = 1;
+      for idx = 1:length (v)
+	if (v(idx) >= next && s(v(idx) + ind) == t)
+	  keep(idx) = 1;
+	  ## Skip to the next possible match position.
+	  next = v(idx) + l_t;
+	else
+	  keep(idx) = 0;
+	endif
+      endfor
+    endif
+    if (! isempty (v))
+      v = v(find (keep));
+    endif
+  endif
+
+  if (isempty (v))
+    v = [];
+  endif
+
+  ## Always return a column vector, because that's what the old one did.
+  if (rows (v) > 1) 
+    v = v.';
+  endif
+
+endfunction
+
+%!assert ((findstr ("abababa", "a") == [1, 3, 5, 7]
+%! && findstr ("abababa", "aba") == [1, 3, 5]
+%! && findstr ("abababa", "aba", 0) == [1, 5]));
+
+%!error findstr ();
+
+%!error findstr ("foo", "bar", 3, 4);
+
diff --git a/scripts/strings/hex2dec.m b/scripts/strings/hex2dec.m
new file mode 100644
index 0000000..3e78e17
--- /dev/null
+++ b/scripts/strings/hex2dec.m
@@ -0,0 +1,57 @@
+## Copyright (C) 1996, 1999, 2000, 2001, 2005, 2006, 2007, 2008, 2009
+##               Daniel Calvelo
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} hex2dec (@var{s})
+## Return the integer corresponding to the hexadecimal number stored
+## in the string @var{s}.  For example,
+##
+## @example
+## @group
+## hex2dec ("12B")
+##      @result{} 299
+## hex2dec ("12b")
+##      @result{} 299
+## @end group
+## @end example
+##
+## If @var{s} is a string matrix, returns a column vector of converted
+## numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
+## @seealso{dec2hex, base2dec, dec2base, bin2dec, dec2bin}
+## @end deftypefn
+
+## Author: Daniel Calvelo <dcalvelo at yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle at kienzle.powernet.co.uk>
+
+function d = hex2dec (h)
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    d = base2dec (h, 16);
+  endif
+
+endfunction
+
+%!assert(hex2dec ("12b") == 299 && hex2dec ("12B") == 299);
+
+%!error hex2dec ();
+
+%!error hex2dec ("str", 1);
+
diff --git a/scripts/strings/index.m b/scripts/strings/index.m
new file mode 100644
index 0000000..c182f0d
--- /dev/null
+++ b/scripts/strings/index.m
@@ -0,0 +1,143 @@
+## Copyright (C) 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} index (@var{s}, @var{t})
+## @deftypefnx {Function File} {} index (@var{s}, @var{t}, @var{direction})
+## Return the position of the first occurrence of the string @var{t} in the
+## string @var{s}, or 0 if no occurrence is found.  For example,
+##
+## @example
+## @group
+## index ("Teststring", "t")
+##      @result{} 4
+## @end group
+## @end example
+##
+## If @var{direction} is @samp{"first"}, return the first element found.
+## If @var{direction} is @samp{"last"}, return the last element found.
+## The @code{rindex} function is equivalent to @code{index} with
+## @var{direction} set to @samp{"last"}.
+##
+## @strong{Caution:}  This function does not work for arrays of
+## character strings.
+## @seealso{find, rindex}
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+function n = index (s, t, direction)
+
+  ## This is patterned after the AWK function of the same name.
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  elseif (nargin < 3)
+    direction = "first";
+  endif
+  direction = lower (direction);
+
+  if (! (ischar (s) && ischar (t)))
+    error ("index: expecting character string arguments");
+  elseif (! strcmp (direction, {"first", "last"}))
+    error ("index: direction must be either \"first\" or \"last\"");
+  endif
+
+  l_s = length (s);
+  l_t = length (t);
+
+  n = 0;
+  if (l_s == 0 || l_s < l_t)
+    ## zero length source, or target longer than source
+    ## return 0
+    v = [];
+
+  elseif (l_t == 0)
+    ## zero length target: return first
+    v = 1;
+
+  elseif (l_t == 1)
+    ## length one target: simple find
+    v = find (s == t, 1, direction);
+
+  elseif (l_t == 2)
+    ## length two target: find first at i and second at i+1
+    v = find (s (1:l_s-1) == t(1) & s(2:l_s) == t(2), 1, direction);
+
+  else
+    ## length three or more: match the first three by find then go through
+    ## the much smaller list to determine which of them are real matches
+    limit = l_s - l_t + 1;
+    v = find (s (1:limit) == t(1)
+	      & s (2:limit+1) == t(2)
+	      & s (3:limit+2) == t(3));
+    if (strcmp (direction, "last"))
+      v = v(length(v):-1:1);
+    endif
+
+    if (l_t > 3)
+
+      ## force strings to be both row vectors or both column vectors
+      if (all (size (s) != size (t)))
+	t = t.';
+      endif
+
+      ## search index vector for a match
+      ind = 0:l_t-1;
+      ## return 0 if loop terminates without finding any match
+      for idx = 1:length(v)
+	if (s (v(idx) + ind) == t)
+	  n = v(idx);
+	  break;
+	endif
+      endfor
+      v = [];
+    endif
+
+  endif
+
+  if (n == 0 && ! isempty (v))
+    ## return the first found if n is not already set and v is not empty
+    n = v(1);
+  endif
+
+endfunction
+
+## Test the function out
+%!assert(index("astringbstringcstring", "s"), 2)
+%!assert(index("astringbstringcstring", "st"), 2)
+%!assert(index("astringbstringcstring", "str"), 2)
+%!assert(index("astringbstringcstring", "string"), 2)
+%!assert(index("abc---", "abc+++"), 0) 
+
+## test everything out in reverse
+%!assert(index("astringbstringcstring", "s", "last"), 16)
+%!assert(index("astringbstringcstring", "st", "last"), 16)
+%!assert(index("astringbstringcstring", "str", "last"), 16)
+%!assert(index("astringbstringcstring", "string", "last"), 16)
+%!assert(index("abc---", "abc+++", "last"), 0)
+
+
+%!assert(index ("foobarbaz", "b") == 4 && index ("foobarbaz", "z") == 9);
+
+%!error index ();
+
+%!error index ("foo", "bar", 3);
+
diff --git a/scripts/strings/isletter.m b/scripts/strings/isletter.m
new file mode 100644
index 0000000..87807f5
--- /dev/null
+++ b/scripts/strings/isletter.m
@@ -0,0 +1,38 @@
+## Copyright (C) 1998, 2000, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isletter (@var{s})
+## Returns true if @var{s} is a letter, false otherwise.
+## @seealso{isalpha}
+## @end deftypefn
+
+## Author: jwe
+
+function retval = isletter (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  retval = isalpha (s);
+
+endfunction
+
+%!error isletter();
+%!error isletter("a", "b");
diff --git a/scripts/strings/isstrprop.m b/scripts/strings/isstrprop.m
new file mode 100644
index 0000000..78150d5
--- /dev/null
+++ b/scripts/strings/isstrprop.m
@@ -0,0 +1,121 @@
+## Copyright (C) 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isstrprop (@var{str}, @var{pred})
+## Test character string properties.  For example,
+##
+## @example
+## @group
+## isstrprop ("abc123", "alpha")
+## @result{} [1, 1, 1, 0, 0, 0]
+## @end group
+## @end example
+## 
+## If @var{str} is a cell array, @code{isstrpop} is applied recursively
+## to each element of the cell array.
+##
+## Numeric arrays are converted to character strings.
+##
+## The second argument @var{pred} may be one of
+##
+## @table @code
+## @item "alpha"
+## True for characters that are alphabetic
+##
+## @item "alnum"
+## @itemx "alphanum"
+## True for characters that are alphabetic or digits.
+## 
+## @item "ascii"
+## True for characters that are in the range of ASCII encoding.
+## 
+## @item "cntrl"
+## True for control characters.
+## 
+## @item "digit"
+## True for decimal digits.
+## 
+## @item "graph"
+## @itemx "graphic"
+## True for printing characters except space.
+## 
+## @item "lower"
+## True for lower-case letters.
+## 
+## @item "print"
+## True for printing characters including space.
+## 
+## @item "punct"
+## True for printing characters except space or letter or digit.
+## 
+## @item "space"
+## @itemx "wspace"
+## True for whitespace characters (space, formfeed, newline, carriage
+## return, tab, vertical tab).
+## 
+## @item "upper"
+## True for upper-case letters.
+## 
+## @item "xdigit"
+## True for hexadecimal digits.
+## @end table
+##
+## @seealso{isalnum, isalpha, isascii, iscntrl, isdigit, isgraph,
+## islower, isprint, ispunct, isspace, isupper, isxdigit}
+## @end deftypefn
+
+function retval = isstrprop (str, pred)
+
+  if (nargin == 2)
+    switch (pred)
+      case "alpha"
+	retval = isalpha (str);
+      case {"alnum", "alphanum"}
+	retval = isalnum (str);
+      case "ascii"
+	retval = isascii (str);
+      case "cntrl"
+	retval = iscntrl (str);
+      case "digit"
+	retval = isdigit (str);
+      case {"graph", "graphic"}
+	retval = isgraph (str);
+      case "lower"
+	retval = islower (str);
+      case "print"
+	retval = isprint (str);
+      case "punct"
+	retval = ispunct (str);
+      case {"space", "wspace"}
+	retval = isspace (str);
+      case "upper"
+	retval = isupper (str);
+      case "xdigit"
+	retval = isxdigit (str);
+      otherwise
+	error ("isstrprop: invalid predicate");
+    endswitch
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!error <invalid predicate> isstrprop ("abc123", "foo");
+%!assert (isstrprop ("abc123", "alpha"), logical ([1, 1, 1, 0, 0, 0]));
\ No newline at end of file
diff --git a/scripts/strings/mat2str.m b/scripts/strings/mat2str.m
new file mode 100644
index 0000000..9bcad32
--- /dev/null
+++ b/scripts/strings/mat2str.m
@@ -0,0 +1,127 @@
+## Copyright (C) 2002, 2006, 2007, 2008, 2009 Rolf Fabian
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{s} =} mat2str (@var{x}, @var{n})
+## @deftypefnx {Function File} {@var{s} =} mat2str (@dots{}, 'class')
+##
+## Format real/complex numerical matrices as strings.  This function
+## returns values that are suitable for the use of the @code{eval}
+## function.
+##
+## The precision of the values is given by @var{n}.  If @var{n} is a
+## scalar then both real and imaginary parts of the matrix are printed
+## to the same precision.  Otherwise @code{@var{n} (1)} defines the
+## precision of the real part and @code{@var{n} (2)} defines the
+## precision of the imaginary part.  The default for @var{n} is 17.
+##
+## If the argument 'class' is given, then the class of @var{x} is
+## included in the string in such a way that the eval will result in the
+## construction of a matrix of the same class.
+##
+## @example
+## @group
+## mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
+##      @result{} "[-0.3333+0.14i;0.3333-0.14i]"
+##
+## mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
+##      @result{} "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]"
+##
+## mat2str (int16([1 -1]), 'class')
+##      @result{} "int16([1,-1])"
+## @end group
+## @end example
+##
+## @seealso{sprintf, num2str, int2str}
+## @end deftypefn
+
+## Author: Rolf Fabian <fabian at tu-cottbus.de>
+
+function s = mat2str (x, n, cls)
+
+  if (nargin < 2 || isempty (n))
+    ## Default precision
+    n = 17;
+  endif
+
+  if (nargin < 3)
+    if (ischar (n))
+      cls = n;
+      n = 17;
+    else
+      cls = "";
+    endif
+  endif
+
+  if (nargin < 1 || nargin > 3 || ! isnumeric (x))
+    print_usage ();
+  endif
+  
+  if (ndims (x) > 2)
+    error ("mat2str: X must be two dimensional");
+  endif
+
+  x_iscomplex = iscomplex (x);
+
+  if (! x_iscomplex)
+    fmt = sprintf ("%%.%dg", n(1));
+  else
+    if (length (n) == 1)
+      n = [n, n];
+    endif
+    fmt = sprintf ("%%.%dg%%+.%dgi", n(1), n(2));
+  endif
+
+  nel = numel (x);
+
+  if (nel == 0)
+    ## Empty, only print brackets
+    s = "[]";
+  elseif (nel == 1)
+    ## Scalar X, don't print brackets
+    if (! x_iscomplex)
+      s = sprintf (fmt, x);
+    else
+      s = sprintf (fmt, real (x), imag (x));
+    endif
+  else
+    ## Non-scalar X, print brackets
+    fmt = [fmt, ","];
+    if (! x_iscomplex)
+      s = sprintf (fmt, x.');
+    else
+      t = x.';
+      s = sprintf (fmt, [real(t(:))'; imag(t(:))']);
+    endif
+
+    s = ["[", s];
+    s(end) = "]";
+    ind = find (s == ",");
+    nc = columns (x);
+    s(ind(nc:nc:end)) = ";";
+  endif
+
+  if (strcmp ("class", cls))
+    s = [class(x), "(", s, ")"];
+  endif
+endfunction
+
+%!assert (mat2str ([-1/3 + i/7; 1/3 - i/7], [4 2]), "[-0.3333+0.14i;0.3333-0.14i]")
+%!assert (mat2str ([-1/3 +i/7; 1/3 -i/7], [4 2]), "[-0.3333+0i,0+0.14i;0.3333+0i,-0-0.14i]")
+%!assert (mat2str (int16 ([1 -1]), 'class'), "int16([1,-1])")
+
diff --git a/scripts/strings/regexptranslate.m b/scripts/strings/regexptranslate.m
new file mode 100644
index 0000000..6cdde09
--- /dev/null
+++ b/scripts/strings/regexptranslate.m
@@ -0,0 +1,82 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} regexptranslate (@var{op}, @var{s})
+## Translate a string for use in a regular expression.  This might
+## include either wildcard replacement or special character escaping.
+## The behavior can be controlled by the @var{op} that can have the
+## values
+##
+## @table @asis
+## @item "wildcard"
+## The wildcard characters @code{.}, @code{*} and @code{?} are replaced
+## with wildcards that are appropriate for a regular expression. 
+## For example:
+## @example
+## @group
+## regexptranslate ("wildcard", "*.m")
+##      @result{} ".*\.m"
+## @end group
+## @end example
+## 
+## @item "escape"
+## The characters @code{$.?[]}, that have special meaning for regular
+## expressions are escaped so that they are treated literally.  For example:
+## @example
+## @group
+## regexptranslate ("escape", "12.5")
+##      @result{} "12\.5"
+## @end group
+## @end example
+## @end table
+## @seealso{regexp, regexpi, regexprep}
+## @end deftypefn
+
+function y = regexptranslate (op, x)
+  
+  if nargin != 2
+    print_usage ();
+  endif 
+  
+  if (ischar (op))
+    op = tolower (op);
+    if (strcmp ("wildcard", op))
+      y = regexprep (regexprep (regexprep (x, "\\.", "\\."), "\\*",
+				".*"), "\\?", ".");
+    elseif (strcmp ("escape", op))
+      ch = {'\$', '\.', '\?', '\[', '\]'};
+      y = x;
+      for i = 1 : length (ch)
+	y = regexprep (y, ch{i}, ch{i});
+      endfor
+    else
+      error ("regexptranslate: unexpected operation");
+    endif
+  else
+    error ("regexptranslate: expecting operation to be a string");
+  endif
+endfunction
+
+%!error <Invalid call to regexptranslate> regexptranslate ();
+%!error <Invalid call to regexptranslate> regexptranslate ("wildcard");
+%!error <Invalid call to regexptranslate> regexptranslate ("a", "b", "c");
+%!error <unexpected operation> regexptranslate ("foo", "abc");
+%!error <expecting operation to be a string> regexptranslate (10, "abc");
+%!assert (regexptranslate ("wildcard", "/a*b?c."), "/a.*b.c\\.")
+%!assert (regexptranslate ("escape", '$.?[]'), '\$\.\?\[\]')
diff --git a/scripts/strings/rindex.m b/scripts/strings/rindex.m
new file mode 100644
index 0000000..278723d
--- /dev/null
+++ b/scripts/strings/rindex.m
@@ -0,0 +1,58 @@
+## Copyright (C) 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+##               Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rindex (@var{s}, @var{t})
+## Return the position of the last occurrence of the character string
+## @var{t} in the character string @var{s}, or 0 if no occurrence is
+## found.  For example,
+##
+## @example
+## @group
+## rindex ("Teststring", "t")
+##      @result{} 6
+## @end group
+## @end example
+##
+## @strong{Caution:}  This function does not work for arrays of
+## character strings.
+## @seealso{find, index}
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+function n = rindex (s, t)
+
+  ## This is patterned after the AWK function of the same name.
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  n = index (s, t, "last");
+
+endfunction
+
+%!assert(rindex ("foobarbaz", "b") == 7 && rindex ("foobarbaz", "o") == 3);
+
+%!error rindex ();
+
+%!error rindex ("foo", "bar", 3);
+
diff --git a/scripts/strings/str2double.m b/scripts/strings/str2double.m
new file mode 100644
index 0000000..9ffce02
--- /dev/null
+++ b/scripts/strings/str2double.m
@@ -0,0 +1,293 @@
+## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by Alois Schloegl
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{num}, @var{status}, @var{strarray}] =} str2double (@var{str}, @var{cdelim}, @var{rdelim}, @var{ddelim})
+## Convert strings into numeric values.
+##
+## @code{str2double} can replace @code{str2num}, but avoids the use of
+## @code{eval} on unknown data.
+##
+## @var{str} can be the form @samp{[+-]d[.]dd[[eE][+-]ddd]} in which
+## @samp{d} can be any of digit from 0 to 9, and @samp{[]} indicate
+## optional elements.
+##
+## @var{num} is the corresponding numeric value.  If the conversion
+## fails, status is -1 and @var{num} is NaN.
+##
+## @var{status} is 0 if the conversion was successful and -1 otherwise.
+##
+## @var{strarray} is a cell array of strings.
+##
+## Elements which are not defined or not valid return NaN and the
+## @var{status} becomes -1.
+##
+## If @var{str} is a character array or a cell array of strings, then
+## @var{num} and @var{status} return matrices of appropriate size. 
+##
+## @var{str} can also contain multiple elements separated by row and
+## column delimiters (@var{cdelim} and @var{rdelim}).
+## 
+## The parameters @var{cdelim}, @var{rdelim}, and @var{ddelim} are
+## optional column, row, and decimal delimiters.
+##
+## The default row-delimiters are newline, carriage return and semicolon
+## (ASCII 10, 13 and 59).  The default column-delimiters are tab, space
+## and comma (ASCII 9, 32, and 44).  The default decimal delimiter is
+## @samp{.} (ASCII 46).
+##
+## @var{cdelim}, @var{rdelim}, and @var{ddelim} must contain only nul,
+## newline, carriage return, semicolon, colon, slash, tab, space, comma,
+## or @samp{()[]@{@}} (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40,
+## 41, 44, 47, 58, 59, 91, 93, 123, 124, 125).
+##
+## Examples:
+##
+## @example
+## @group
+## str2double ("-.1e-5")
+## @result{} -1.0000e-006
+##
+## str2double (".314e1, 44.44e-1, .7; -1e+1")
+## @result{}
+##    3.1400    4.4440    0.7000
+##  -10.0000       NaN       NaN
+##
+## line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+## [x, status] = str2double (line)
+## @result{} x =
+##     200   300   NaN  -Inf   NaN   NaN   999   NaN   NaN
+## @result{} status =
+##       0     0     0     0    -1    -1     0    -1     0
+## @end group
+## @end example
+## @seealso{str2num}
+## @end deftypefn
+
+## Author: Alois Schloegl <a.schloegl at ieee.org>
+## Adapted-by: jwe
+
+function [num, status, strarray] = str2double (s, cdelim, rdelim, ddelim)
+
+  ## digits, sign, exponent,NaN,Inf
+  ## valid_char = '0123456789eE+-.nNaAiIfF';
+
+  ## Valid delimiters.
+  valid_delim = char (sort ([0, 9:14, 32:34, abs("()[]{},;:\"|/")]));
+
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    ## Column delimiter.
+    cdelim = char ([9, 32, abs(",")]);
+  else
+    ## Make unique cdelim.
+    cdelim = char (sort (cdelim(:)));
+    tmp = [1; 1+find(diff(abs(cdelim))>0)];
+    cdelim = cdelim(tmp)';
+  endif
+
+  if (nargin < 3)
+    ## Row delimiter.
+    rdelim = char ([0, 10, 13, abs(";")]);
+  else
+    ## Make unique rdelim.
+    rdelim = char (sort (rdelim(:)));
+    tmp = [1; 1+find(diff(abs(rdelim))>0)];
+    rdelim = rdelim(tmp)';
+  endif
+
+  if (nargin < 4)
+    ddelim = ".";
+  elseif (length (ddelim) != 1)
+    error ("decimal delimiter must be exactly one character");
+  endif
+
+  ## Check if RDELIM and CDELIM are distinct.
+
+  delim = sort (abs ([cdelim, rdelim, ddelim]));
+  tmp   = [1, 1+find(diff(delim)>0)];
+  delim = delim(tmp);
+  ## [length(delim),length(cdelim),length(rdelim)]
+  if (length (delim) < (length(cdelim) + length(rdelim))+1)
+    ## length (ddelim) must be one.
+    error ("row, column and decimal delimiter are not distinct");
+  endif
+
+  ## Check if delimiters are valid.
+  tmp  = sort (abs ([cdelim, rdelim]));
+  flag = zeros (size (tmp));
+  curr_row = 1;
+  curr_col = 1;
+  while (curr_row <= length (tmp) && curr_col <= length (valid_delim)),
+    if (tmp(curr_row) == valid_delim(curr_col))
+      flag(curr_row) = 1;
+      curr_row++;
+    elseif (tmp(curr_row) < valid_delim(curr_col))
+      curr_row++;
+    elseif (tmp(curr_row) > valid_delim(curr_col))
+      curr_col++;
+    endif
+  endwhile
+  if (! all (flag))
+    error ("invalid delimiters!");
+  endif
+
+  ## Various input parameters.
+
+  if (isnumeric (s))
+    if (all (s < 256) && all (s >= 0))
+      s = char (s);
+    else
+      error ("str2double: input variable must be a string");
+    endif
+  endif
+
+  if (isempty (s))
+    num = [];
+    status = 0;
+    return;
+  elseif (iscell (s))
+    strarray = s;
+  elseif (ischar (s) && all (size (s) > 1))
+    ## Char array transformed into a string.
+    for k = 1:size (s, 1)
+      tmp = find (! isspace (s(k,:)));
+      strarray{k,1} = s(k,min(tmp):max(tmp));
+    endfor
+  elseif (ischar (s)),
+    num = [];
+    status = 0;
+    strarray = {};
+    ## Add stop sign; makes sure last digit is not skipped.
+    s(end+1) = rdelim(1);
+    RD = zeros (size (s));
+    for k = 1:length (rdelim),
+      RD = RD | (s == rdelim(k));
+    endfor
+    CD = RD;
+    for k = 1:length (cdelim),
+      CD = CD | (s == cdelim(k));
+    endfor
+
+    curr_row = 1;
+    curr_col = 0;
+    curr_elt = 0;
+
+    sl = length (s);
+    ix = 1;
+    ## while (ix < sl) & any(abs(s(ix))==[rdelim,cdelim]),
+    while (ix < sl && CD(ix))
+      ix++;
+    endwhile
+    ta = ix;
+    te = [];
+    while (ix <= sl)
+      if (ix == sl)
+        te = sl;
+      endif
+      ## if any(abs(s(ix))==[cdelim(1),rdelim(1)]),
+      if (CD(ix))
+        te = ix - 1;
+      endif
+      if (! isempty (te))
+        curr_col++;
+        curr_elt++;
+        strarray{curr_row,curr_col} = s(ta:te);
+        ## strarray{curr_row,curr_col} = [ta,te];
+
+        flag = 0;
+        ## while any(abs(s(ix))==[cdelim(1),rdelim(1)]) & (ix < sl),
+        while (CD(ix) && ix < sl)
+          flag = flag | RD(ix);
+          ix++;
+        endwhile
+
+        if (flag)
+          curr_col = 0;
+          curr_row++;
+        endif
+        ta = ix;
+        te = [];
+      endif
+      ix++;
+    endwhile
+  else
+    error ("str2double: invalid input argument");
+  endif
+
+  [nr, nc]= size (strarray);
+  status = zeros (nr, nc);
+  num = repmat (NaN, nr, nc);
+
+  for curr_row = 1:nr
+    for curr_col = 1:nc
+      t = strarray{curr_row,curr_col};
+      if (length (t) == 0)
+	## Return error code.
+	status(curr_row,curr_col) = -1;
+	num(curr_row,curr_col) = NaN;
+      else
+	## Get mantisse.
+	g = 0;
+	v = 1;
+	if (t(1) == "-")
+	  v = -1;
+	  l = min (2, length(t));
+	elseif (t(1) == "+")
+	  l = min (2, length (t));
+	else
+	  l = 1;
+	endif
+
+	if (strcmpi (t(l:end), "inf"))
+	  num(curr_row,curr_col) = v*Inf;
+	elseif (strcmpi (t(l:end), "NaN"));
+	  num(curr_row,curr_col) = NaN;
+	else
+	  if (ddelim == ".")
+	    t(t == ddelim) = ".";
+	  endif
+	  [v, tmp2, c] = sscanf(char(t), "%f %s", "C");
+	  ## [v,c,em,ni] = sscanf(char(t),"%f %s");
+	  ## c = c * (ni>length(t));
+	  if (c == 1),
+	    num(curr_row,curr_col) = v;
+	  else
+	    num(curr_row,curr_col) = NaN;
+	    status(curr_row,curr_col) = -1;
+	  endif
+	endif
+      endif
+    endfor
+  endfor
+
+endfunction
+
+%!error <Invalid call to str2double> str2double();
+%!error <Invalid call to str2double> str2double("1e10", " ", "\n", ".", "x");
+%!assert (str2double ("-.1e-5"), -1.0000e-006);
+%!assert (str2double (".314e1, 44.44e-1, .7; -1e+1"),
+%!  [3.1400, 4.4440, 0.7000; -10.0000, NaN, NaN]);
+%!test
+%!  line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN";
+%!  [x, status] = str2double (line);
+%!  assert (x, [200, 300, NaN, -Inf, NaN, NaN, 999, NaN, NaN]);
+%!  assert (status, [0, 0, 0, 0, -1, -1, 0, -1, 0]);
diff --git a/scripts/strings/str2num.m b/scripts/strings/str2num.m
new file mode 100644
index 0000000..6a2cb50
--- /dev/null
+++ b/scripts/strings/str2num.m
@@ -0,0 +1,67 @@
+## Copyright (C) 1996, 1998, 1999, 2005, 2006, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} str2num (@var{s})
+## Convert the string (or character array) @var{s} to a number (or an
+## array).  Examples:  
+##
+## @example
+## @group
+## str2num("3.141596")
+##      @result{} 3.141596
+## 
+## str2num(["1, 2, 3"; "4, 5, 6"]);
+##      @result{} ans =
+##         1  2  3
+##         4  5  6
+## @end group
+## @end example
+## 
+## @strong{Caution:} As @code{str2num} uses the @code{eval} function
+## to do the conversion, @code{str2num} will execute any code contained
+## in the string @var{s}.  Use @code{str2double} instead if you want to
+## avoid the use of @code{eval}. 
+## @seealso{str2double, eval}
+## @end deftypefn
+
+## Author: jwe
+
+function m = str2num (s)
+
+  if (nargin == 1 && ischar (s))
+    [nr, nc] = size (s);
+    sep = ";";
+    sep = sep (ones (nr, 1), 1);
+    s = sprintf ("m = [%s];", reshape ([s, sep]', 1, nr * (nc + 1)));
+    eval (s, "m = [];");
+    if (ischar (m))
+      m = [];
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert(str2num ("-1.3e2") == -130 && str2num ("[1, 2; 3, 4]") == [1, 2; 3, 4]);
+
+%!error str2num ();
+
+%!error str2num ("string", 1);
+
diff --git a/scripts/strings/strcat.m b/scripts/strings/strcat.m
new file mode 100644
index 0000000..a777d7d
--- /dev/null
+++ b/scripts/strings/strcat.m
@@ -0,0 +1,145 @@
+## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+##               2005, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strcat (@var{s1}, @var{s2}, @dots{})
+## Return a string containing all the arguments concatenated
+## horizontally.  If the arguments are cells strings,  @code{strcat}
+## returns a cell string with the individual cells concatenated.
+## For numerical input, each element is converted to the
+## corresponding ASCII character.  Trailing white space is eliminated.
+## For example,
+##
+## @example
+## @group
+## s = [ "ab"; "cde" ];
+## strcat (s, s, s)
+##      @result{} ans =
+##         "ab ab ab "
+##         "cdecdecde"
+## @end group
+## @end example
+##
+## @example
+## @group
+## s = @{ "ab"; "cde" @};
+## strcat (s, s, s)
+##      @result{} ans =
+##         @{
+##           [1,1] = ababab
+##           [2,1] = cdecdecde
+##         @}
+## @end group
+## @end example
+##
+## @seealso{cstrcat, char, strvcat}
+## @end deftypefn
+
+## Author: jwe
+
+function st = strcat (varargin)
+
+  if (nargin > 0)
+    if (nargin == 1)
+      st = varargin{1};
+    elseif (nargin > 1)
+      ## Convert to cells of strings
+      numstrs(nargin) = 0;
+      dims{nargin} = [];
+      allchar = true;
+      for nv = 1:nargin
+        if (ischar (varargin{nv}))
+          varargin{nv} = cellstr (varargin{nv});
+        elseif (isreal (varargin{nv}))
+          varargin{nv} = cellstr (char (varargin{nv}));
+        elseif (isempty (varargin{nv}))
+          varargin{nv} = cellstr ('');
+        elseif (iscell (varargin{nv}))
+          allchar = false;
+        else
+          error ("strcat: inputs must be strings or cells of strings");
+        endif
+        dims{nv} = size (varargin{nv});
+        numstrs(nv) = numel (varargin{nv});
+      endfor
+
+      ## Set all cells to a common size
+      n = find (numstrs == max (numstrs), 1);
+      maxstrs = numstrs (n);
+      dim = dims{n};
+      for nv = find (numstrs == 1)
+        str = varargin{nv}{1};
+        varargin{nv} = cell (dim);
+        varargin{nv}(:) = {str};
+      endfor
+
+      ## Concatenate the strings
+      st = varargin{1};
+      for ns = 1:maxstrs
+        for nv = 2:nargin
+          if (size_equal (st, varargin{nv}))
+            st{ns} = [st{ns}, varargin{nv}{ns}];
+          else
+            error ("strcat: arguments must be the same size, or be scalars");
+          endif
+        endfor
+      endfor
+
+      if (allchar)
+        ## If all inputs were strings, return strings.
+        st = char (st);
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+## test the dimensionality
+## 1d
+%!assert(strcat("ab ", "ab "), "abab")
+%!assert(strcat({"ab "}, "ab "), {"ab ab"})
+%!assert(strcat("ab ", {"ab "}), {"abab "})
+%!assert(strcat({"ab "}, {"ab "}), {"ab ab "})
+%!assert(strcat("", "ab"), "ab")
+%!assert(strcat("", {"ab"}, {""}), {"ab"})
+## 2d
+%!assert(strcat(["ab ";"cde"], ["ab ";"cde"]), ["abab  ";"cdecde"])
+
+## test for deblanking implied trailing spaces of character input
+%!assert((strcmp (strcat ("foo", "bar"), "foobar") &&
+%!        strcmp (strcat (["a"; "bb"], ["foo"; "bar"]), ["afoo "; "bbbar"])));
+
+## test for mixing character and cell inputs
+%!assert(all (strcmp (strcat ("a", {"bc", "de"}, "f"), {"abcf", "adef"})))
+
+## test for scalar strings with vector strings
+%!assert(all (strcmp (strcat (["a"; "b"], "c"), ["ac"; "bc"])))
+
+## test with cells with strings of differing lengths
+%!assert(all (strcmp (strcat ({"a", "bb"}, "ccc"), {"accc", "bbccc"})))
+%!assert(all (strcmp (strcat ("a", {"bb", "ccc"}), {"abb", "accc"})))
+
+%!error strcat ();
+
+%!assert (strcat (1, 2), strcat (char(1), char(2)))
+
+%!assert (strcat ('', 2), strcat ([], char(2)))
+
diff --git a/scripts/strings/strchr.m b/scripts/strings/strchr.m
new file mode 100644
index 0000000..a15aafc
--- /dev/null
+++ b/scripts/strings/strchr.m
@@ -0,0 +1,43 @@
+## Copyright (C) 2008, 2009 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{idx} =} strchr (@var{str}, @var{chars})
+## @deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n})
+## @deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n}, @var{direction})
+## Search for the string @var{str} for occurrences of characters from the set @var{chars}.
+## The return value, as well as the @var{n} and @var{direction} arguments behave
+## identically as in @code{find}.
+##
+## This will be faster than using regexp in most cases.
+##
+## @seealso{find}
+## @end deftypefn
+
+function varargout = strchr (str, chars, varargin)
+  if (nargin < 2 || ! ischar (str) || ! ischar (chars))
+    print_usage ();
+  endif
+  f = false (1, 256);
+  f(chars + 1) = true;
+  varargout = cell (1, nargout);
+  varargout{1} = [];
+  [varargout{:}] = find (reshape (f(str + 1), size (str)), varargin{:});
+endfunction 
+
+%!assert(strchr("Octave is the best software","best"),[3, 6, 9, 11, 13, 15, 16, 17, 18, 20, 23, 27])
diff --git a/scripts/strings/strcmpi.m b/scripts/strings/strcmpi.m
new file mode 100644
index 0000000..8fc95d5
--- /dev/null
+++ b/scripts/strings/strcmpi.m
@@ -0,0 +1,55 @@
+## Copyright (C) 2000, 2005, 2006, 2007, 2009 Bill Lash
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strcmpi (@var{s1}, @var{s2})
+## Ignoring case, return 1 if the character strings (or character
+## arrays) @var{s1} and @var{s2} are the same, and 0 otherwise.
+##
+## If either @var{s1} or @var{s2} is a cell array of strings, then an array
+## of the same size is returned, containing the values described above for
+## every member of the cell array.  The other argument may also be a cell
+## array of strings (of the same size or with only one element), char matrix
+## or character string.
+##
+## @strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmpi
+## function returns 1 if the character strings are equal, and 0 otherwise.
+## This is just the opposite of the corresponding C library function.
+## @seealso{strcmp, strncmp, strncmpi}
+## @end deftypefn
+
+## Author: Bill Lash <lash at tellabs.com>
+## Adapted-by: jwe
+
+function retval = strcmpi (s1, s2)
+
+  if (nargin == 2)
+    if ((ischar(s1) || iscellstr(s1)) && (ischar(s2) || iscellstr(s2)))
+      ## Note that we don't use tolower here because we need to be able
+      ## to handle cell arrays of strings.
+      retval = strcmp (lower (s1), lower (s2));
+    else
+      retval = false;
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert (strcmpi("abc123", "ABC123"), logical(1));
diff --git a/scripts/strings/strfind.m b/scripts/strings/strfind.m
new file mode 100644
index 0000000..b6fa59c
--- /dev/null
+++ b/scripts/strings/strfind.m
@@ -0,0 +1,94 @@
+## Copyright (C) 2004, 2006, 2007, 2009 by Alois Schloegl
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{idx} =} strfind (@var{str}, @var{pattern})
+## @deftypefnx {Function File} {@var{idx} =} strfind (@var{cellstr}, @var{pattern})
+## Search for @var{pattern} in the string @var{str} and return the
+## starting index of every such occurrence in the vector @var{idx}.
+## If there is no such occurrence, or if @var{pattern} is longer
+## than @var{str}, then @var{idx} is the empty array @code{[]}.
+##
+## If the cell array of strings @var{cellstr} is specified instead of the
+## string @var{str}, then @var{idx} is a cell array of vectors, as specified
+## above.  Examples:
+##
+## @example
+## @group
+## strfind ("abababa", "aba")
+##      @result{} [1, 3, 5]
+##
+## strfind (@{"abababa", "bebebe", "ab"@}, "aba")
+##      @result{} ans =
+##         @{
+##           [1,1] =
+##
+##              1   3   5
+##
+##           [1,2] = [](1x0)
+##           [1,3] = [](1x0)
+##         @}
+## @end group
+## @end example
+## @seealso{findstr, strmatch, strcmp, strncmp, strcmpi, strncmpi, find}
+## @end deftypefn
+
+## Author: alois schloegl <a.schloegl at ieee.org>
+## Created: 1 November 2004
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function idx = strfind (text, pattern)
+
+  if (nargin != 2)
+    print_usage ();
+  elseif (! ischar (pattern))
+    error ("strfind: pattern must be a string value");
+  endif
+
+  lp = length (pattern);
+
+  if (ischar (text))
+    idx = __strfind_string__ (text, pattern, lp);
+  elseif (iscellstr (text))
+    idx = cell (size (text));
+    for i = 1:(numel (text))
+      idx{i} = __strfind_string__ (text{i}, pattern, lp);
+    endfor
+  else
+    error ("strfind: text must be a string or cell array of strings");
+  endif
+
+### endfunction
+
+function idx = __strfind_string__ (text, pattern, lp)
+
+  idx = 1:(length (text) - lp + 1);
+  k = 0;
+  while (k < lp && ! isempty (idx))
+    idx = idx(text(idx + k) == pattern(++k));
+  endwhile
+
+### endfunction
+
+%!error <Invalid call to strfind> strfind ();
+%!error <Invalid call to strfind> strfind ("foo", "bar", 1);
+%!error <pattern must be a string value> strfind ("foo", 100);
+%!error <text must be a string or cell array of string> strfind (100, "foo");
+
+%!assert (strfind ("abababa", "aba"), [1, 3, 5]);
+%!assert (strfind ({"abababa", "bla", "bla"}, "a"), {[1, 3, 5, 7], 3, 3});
diff --git a/scripts/strings/strjust.m b/scripts/strings/strjust.m
new file mode 100644
index 0000000..ef56406
--- /dev/null
+++ b/scripts/strings/strjust.m
@@ -0,0 +1,83 @@
+## Copyright (C) 2000, 2001, 2003, 2005, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strjust (@var{s}, ["left"|"right"|"center"])
+## Shift the non-blank text of @var{s} to the left, right or center of
+## the string.  If @var{s} is a string array, justify each string in the
+## array.  Null characters are replaced by blanks.  If no justification
+## is specified, then all rows are right-justified.  For example:
+##
+## @example
+## @group
+## strjust (["a"; "ab"; "abc"; "abcd"])
+##      @result{} ans =
+##            a
+##           ab
+##          abc
+##         abcd
+## @end group
+## @end example
+## @end deftypefn
+
+function x = strjust (x, just)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    just = "right";
+  endif
+
+  just = tolower (just);
+
+  ## convert nulls to blanks
+  idx = find (toascii (x) == 0);
+  if (! isempty (idx))
+    x(idx) = " ";
+  endif
+
+  ## For all cases, left, right and center, the algorithm is the same.
+  ## Find the number of blanks at the left/right end to determine the
+  ## shift, rotate the row index by using mod with that shift, then
+  ## translate the shifted row index into an array index.
+  [nr, nc] = size (x);
+  idx = (x' != " ");
+  if (strcmp (just, "right"))
+    [N, hi] = max (cumsum (idx));
+    shift = hi;
+  elseif (strcmp (just, "left"))
+    [N, lo] = max (cumsum (flipud (idx)));
+    shift = (nc - lo);
+  else
+    [N, hi] = max (cumsum (idx));
+    [N, lo] = max (cumsum (flipud (idx)));
+    shift = ceil (nc - (lo-hi)/2);
+  endif
+  idx = rem (ones(nr,1)*[0:nc-1] + shift'*ones(1,nc), nc);
+  x = x (idx*nr + [1:nr]'*ones(1,nc));
+
+endfunction
+
+%!error <Invalid call to strjust> strjust();
+%!error <Invalid call to strjust> strjust(["a";"ab"], "center", 1);
+%!assert (strjust (["a"; "ab"; "abc"; "abcd"]),
+%!        ["   a";"  ab"; " abc"; "abcd"]);
+%!assert (strjust (["a"; "ab"; "abc"; "abcd"], "center"),
+%!        [" a  "; " ab"; "abc "; "abcd"]);
diff --git a/scripts/strings/strmatch.m b/scripts/strings/strmatch.m
new file mode 100644
index 0000000..ede3eb1
--- /dev/null
+++ b/scripts/strings/strmatch.m
@@ -0,0 +1,93 @@
+## Copyright (C) 2000, 2005, 2006, 2007, 2009 Paul Kienzle
+## Copyright (C) 2003 Alois Schloegl
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strmatch (@var{s}, @var{a}, "exact")
+## Return indices of entries of @var{a} that match the string @var{s}.
+## The second argument @var{a} may be a string matrix or a cell array of
+## strings.  If the third argument @code{"exact"} is not given, then
+## @var{s} only needs to match @var{a} up to the length of @var{s}.  Nul
+## characters match blanks.  Results are returned as a column vector. 
+## For example:
+##
+## @example
+## @group
+## strmatch ("apple", "apple juice")
+##      @result{} 1
+##
+## strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
+##      @result{} [1; 2]
+##
+## strmatch ("apple", @{"apple pie"; "apple juice"; "tomato"@})
+##      @result{} [1; 2]
+## @end group
+## @end example
+## @seealso{strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find}
+## @end deftypefn
+
+## Author: Paul Kienzle, Alois Schloegl
+## Adapted-by: jwe
+
+function idx = strmatch (s, A, exact)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  [nr, nc] = size (A);
+  nel = numel (A);
+  if (iscell (A))
+    match = zeros (nel, 1);
+    if (nargin > 2)
+      for k = 1:nel
+	match(k) = strcmp (s, A{k}); 
+      endfor
+    else
+      for k = 1:nel
+	match(k) = strncmp (s, A{k}, length (s));
+      endfor
+    endif
+    idx = find (match);
+  elseif (length (s) > nc)
+    idx = [];
+  else
+    if (nargin == 3 && length(s) < nc)
+      s(1,nc) = " ";
+    endif
+    s(s == 0) = " ";
+    A(A == 0) = " ";
+    match = s(ones(size(A,1),1),:) == A(:,1:length(s));
+    if (length (s) == 1)
+      idx = find (match);
+    else
+      idx = find (all (match')');
+    endif
+  endif
+    
+endfunction 
+
+%!error <Invalid call to strmatch> strmatch();
+%!error <Invalid call to strmatch> strmatch("a", "aaa", "exact", 1);
+%!assert (strmatch("a", {"aaa", "bab", "bbb"}), 1);
+%!assert (strmatch ("apple", "apple juice"), 1);
+%!assert (strmatch ("apple", ["apple pie"; "apple juice"; "an apple"]),
+%!        [1; 2]);
+%!assert (strmatch ("apple", {"apple pie"; "apple juice"; "tomato"}),
+%!        [1; 2]);
+%!assert (strmatch ("apple pie", "apple"), []);
diff --git a/scripts/strings/strncmpi.m b/scripts/strings/strncmpi.m
new file mode 100644
index 0000000..80a39fd
--- /dev/null
+++ b/scripts/strings/strncmpi.m
@@ -0,0 +1,49 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Bill Lash
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strncmpi (@var{s1}, @var{s2}, @var{n})
+## Ignoring case, return 1 if the first @var{n} characters of character
+## strings (or character arrays) @var{s1} and @var{s2} are the same, and
+## 0 otherwise.
+##
+## If either @var{s1} or @var{s2} is a cell array of strings, then an array
+## of the same size is returned, containing the values described above for
+## every member of the cell array.  The other argument may also be a cell
+## array of strings (of the same size or with only one element), char matrix
+## or character string.
+##
+## @strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmpi
+## function returns 1 if the character strings are equal, and 0 otherwise.
+## This is just the opposite of the corresponding C library function.
+## @seealso{strcmp, strcmpi, strncmp}
+## @end deftypefn
+
+function retval = strncmpi (s1, s2, n)
+
+  if (nargin == 3)
+    ## Note that we don't use tolower here because we need to be able to
+    ## handle cell arrays of strings.
+    retval = strncmp (lower (s1), lower (s2), n);
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!assert (strncmpi("abc123", "ABC456", 3), logical(1));
diff --git a/scripts/strings/strrep.m b/scripts/strings/strrep.m
new file mode 100644
index 0000000..7591693
--- /dev/null
+++ b/scripts/strings/strrep.m
@@ -0,0 +1,107 @@
+## Copyright (C) 1995, 1996, 1998, 1999, 2000, 2005, 2006, 2007, 2008,
+##               2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strrep (@var{s}, @var{x}, @var{y})
+## Replace all occurrences of the substring @var{x} of the string @var{s}
+## with the string @var{y} and return the result.  For example,
+##
+## @example
+## @group
+## strrep ("This is a test string", "is", "&%$")
+##      @result{} "Th&%$ &%$ a test string"
+## @end group
+## @end example
+## @seealso{regexprep, strfind, findstr}
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Created: 11 November 1994
+## Adapted-By: jwe
+
+function t = strrep (s, x, y)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! (ischar (s) && ischar (x) && ischar (y)))
+    error ("strrep: all arguments must be strings");
+  endif
+
+  if (length (x) > length (s) || isempty (x))
+    t = s;
+    return;
+  endif
+
+  ind = findstr (s, x, 0);
+
+  if (length(ind) == 0)
+    t = s;
+  elseif (length(y) > 0)
+    ## Replacement.
+    ##
+    ## Copy the parts of s that aren't being replaced.  This is done
+    ## with an index vector, with jumps where each search string
+    ## is found.  For a jump of 0 (target length == replacement length)
+    ## the index is just cumsum (ones (length (s))).  For non-zero
+    ## jumps, add the jump size to the ones vector at each found position.
+    jump = length(y) - length(x);
+    if (jump > 0)
+      ## S expands.
+      di = ones (size (s));
+      di(ind) = 1 + jump * ones (length (ind), 1);
+      t(cumsum (di)) = s;
+    elseif (jump < 0)
+      ## S contracts.
+      di = ones (jump * length (ind) + length (s), 1);
+      di (ind + jump * [0:length(ind)-1]) = 1 - jump * ones (length (ind), 1);
+      t = s (cumsum (di));
+    else
+      ## S stays the same length.
+      t = s;
+    endif
+    ## Now, substitute a copy of the replacement string whereever the
+    ## search string was found.  Note that we must first update the
+    ## target positions to account for any expansion or contraction
+    ## of s that may have occurred.
+    ind = ind + jump * [0:length(ind)-1];
+    repeat = [1:length(y)]' * ones (1, length (ind));
+    dest = ones (length (y), 1) * ind + repeat - 1;
+    t(dest) = y(repeat);
+  else
+    ## Deletion.
+    ##
+    ## Build an index vector of all locations where the target was found
+    ## in the search string, and zap them. 
+    t = toascii (s);
+    repeat = [1:length(x)]' * ones (1, length (ind));
+    delete = ones (length (x), 1) * ind + repeat - 1;
+    t(delete) = [];
+    t = char (t);
+  endif
+
+endfunction
+
+%!assert(strcmp (strrep ("This is a test string", "is", "&%$"),
+%! "Th&%$ &%$ a test string"));
+
+%!error strrep ();
+
+%!error strrep ("foo", "bar", 3, 4);
diff --git a/scripts/strings/strsplit.m b/scripts/strings/strsplit.m
new file mode 100644
index 0000000..c30cd12
--- /dev/null
+++ b/scripts/strings/strsplit.m
@@ -0,0 +1,67 @@
+## Copyright (C) 2009 Jaroslav Hajek
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{s}] =} strsplit (@var{p}, @var{sep}, @var{strip_empty})
+## Split a single string using one or more delimiters and return a cell
+## array of strings.  Consecutive delimiters and delimiters at
+## boundaries result in empty strings, unless @var{strip_empty} is true.
+## The default value of @var{strip_empty} is false.
+## @seealso{strtok}
+## @end deftypefn
+
+function s = strsplit (p, sep, strip_empty = false)
+
+  if (nargin < 2 || nargin > 3 || ! ischar (p) || rows (p) > 1
+      || ! ischar (sep) || ! islogical (strip_empty))
+    print_usage ();
+  endif
+
+  if (isempty (p))
+    s = cell (size (p));
+  else
+    ## Split p according to delimiter.
+    if (isscalar (sep))
+      ## Single separator.
+      idx = find (p == sep);
+    else
+      ## Multiple separators.
+      idx = strchr (p, sep);
+    endif
+
+    ## Get substring sizes.
+    if (isempty (idx))
+      sizes = numel (p);
+    else
+      sizes = [idx(1)-1, diff(idx)-1, numel(p)-idx(end)];
+    endif
+    ## Remove separators.
+    p(idx) = []; 
+    if (strip_empty)
+      ## Omit zero lengths.
+      sizes = sizes (sizes != 0); 
+    endif
+    ## Convert!
+    s = mat2cell (p, 1, sizes);
+  endif
+
+endfunction
+
+%!assert (all (strcmp (strsplit ("road to hell", " "), {"road", "to", "hell"})))
+
+%!assert (all (strcmp (strsplit ("road to^hell", " ^"), {"road", "to", "hell"})))
+
+%!assert (all (strcmp (strsplit ("road   to--hell", " -", true), {"road", "to", "hell"})))
diff --git a/scripts/strings/strtok.m b/scripts/strings/strtok.m
new file mode 100644
index 0000000..f8bc942
--- /dev/null
+++ b/scripts/strings/strtok.m
@@ -0,0 +1,161 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{tok}, @var{rem}] =} strtok (@var{str}, @var{delim})
+## 
+## Find all characters up to but not including the first character which
+## is in the string delim.  If @var{rem} is requested, it contains the
+## remainder of the string, starting at the first delimiter.  Leading
+## delimiters are ignored.  If @var{delim} is not specified, space is
+## assumed.  For example: 
+##
+## @example
+## @group
+## strtok ("this is the life")
+##      @result{} "this"
+##
+## [tok, rem] = strtok ("14*27+31", "+-*/")
+##      @result{}
+##         tok = 14
+##         rem = *27+31
+## @end group
+## @end example
+## @seealso{index, strsplit}
+## @end deftypefn
+
+## FIXME: check what to do for a null delimiter
+
+function [tok, rem] = strtok (str, delim)
+
+  if (nargin<1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin < 2 || isempty (delim))
+    delim = "\t\n\v\f\r "; 
+  endif
+
+  if (isempty (str))
+    tok = rem = "";
+  elseif (length (delim) > 3)
+    start = 1;
+    len = length (str);
+    while (start <= len)
+      if (all (str(start) != delim))
+	break; 
+      endif
+      start++;
+    endwhile
+    stop = start;
+    while (stop <= len)
+      if (any (str(stop) == delim))
+	break; 
+      endif
+      stop++;
+    endwhile
+    tok = str(start:stop-1);
+    rem = str(stop:len);
+  else
+    if (length (delim) == 1)
+      idx = find (str == delim);
+    elseif (length (delim) == 2)
+      idx = find (str == delim(1) | str == delim(2));
+    else
+      idx = find (str == delim(1) | str == delim(2) | str == delim(3));
+    endif
+    if (isempty (idx))
+      tok = str;
+      rem = "";
+    else
+      ## Find first non-leading delimiter.
+      skip = find (idx(:)' != 1:length(idx));
+      if (isempty (skip))
+      	tok = str(idx(length(idx))+1:length(str));
+      	rem = "";
+      else
+      	tok = str(skip(1):idx(skip(1))-1);
+      	rem = str(idx(skip(1)):length(str));
+      endif
+    endif
+  endif
+
+endfunction
+
+%!demo
+%! strtok("this is the life")
+%! % split at the first space, returning "this"
+
+%!demo
+%! s = "14*27+31"
+%! while 1
+%!   [t,s] = strtok(s, "+-*/");
+%!   printf("<%s>", t);
+%!   if isempty(s), break; endif
+%!   printf("<%s>", s(1));
+%! endwhile
+%! printf("\n");
+%! % ----------------------------------------------------
+%! % Demonstrates processing of an entire string split on
+%! % a variety of delimiters. Tokens and delimiters are 
+%! % printed one after another in angle brackets.  The
+%! % string is:
+
+%!# test the tokens for all cases
+%!assert(strtok(""), "");             # no string
+%!assert(strtok("this"), "this");     # no delimiter in string
+%!assert(strtok("this "), "this");    # delimiter at end
+%!assert(strtok("this is"), "this");  # delimiter in middle
+%!assert(strtok(" this"), "this");    # delimiter at start
+%!assert(strtok(" this "), "this");   # delimiter at start and end
+%!assert(strtok(" "), ""(1:0));            # delimiter only
+
+%!# test the remainder for all cases
+%!test [t,r] = strtok(""); assert(r, "");
+%!test [t,r] = strtok("this"); assert(r, char (zeros (1, 0)));
+%!test [t,r] = strtok("this "); assert(r, " ");
+%!test [t,r] = strtok("this is"); assert(r, " is");
+%!test [t,r] = strtok(" this"); assert(r, char (zeros (1, 0)));
+%!test [t,r] = strtok(" this "); assert(r, " ");
+%!test [t,r] = strtok(" "); assert(r, char (zeros (1, 0)));
+
+%!# simple check with 2 and 3 delimeters
+%!assert(strtok("this is", "i "), "th");
+%!assert(strtok("this is", "ij "), "th");
+
+%!# test all cases for 4 delimiters since a different 
+%!# algorithm is used when more than 3 delimiters
+%!assert(strtok("","jkl "), "");
+%!assert(strtok("this","jkl "), "this");
+%!assert(strtok("this ","jkl "), "this");
+%!assert(strtok("this is","jkl "), "this");
+%!assert(strtok(" this","jkl "), "this");
+%!assert(strtok(" this ","jkl "), "this");
+%!assert(strtok(" ","jkl "), ""(1:0));
+
+%!# test 'bad' string orientations
+%!assert(strtok(" this "'), "this"');   # delimiter at start and end
+%!assert(strtok(" this "',"jkl "), "this"');
+
+%!# test with TAB, LF, VT, FF, and CR
+%!test
+%! for ch = "\t\n\v\f\r"
+%!   [t, r] = strtok (cstrcat ("beg", ch, "end"));
+%!   assert (t, "beg");
+%!   assert (r, cstrcat (ch, "end"))
+%! endfor
diff --git a/scripts/strings/strtrim.m b/scripts/strings/strtrim.m
new file mode 100644
index 0000000..a22f3cc
--- /dev/null
+++ b/scripts/strings/strtrim.m
@@ -0,0 +1,69 @@
+## Copyright (C) 1996, 2007, 2008, 2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strtrim (@var{s})
+## Remove leading and trailing blanks and nulls from @var{s}.  If
+## @var{s} is a matrix, @var{strtrim} trims each row to the length of
+## longest string.  If @var{s} is a cell array, operate recursively on
+## each element of the cell array.  For example:
+##
+## @example
+## @group
+## strtrim ("    abc  ")
+##      @result{} "abc"
+##
+## strtrim ([" abc   "; "   def   "])
+##      @result{} ["abc  "; "  def"]
+## @end group
+## @end example
+## @end deftypefn
+
+## Author: John Swensen <jpswensen at jhu.edu>
+
+## This function was derived from deblank.
+
+function s = strtrim (s)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (ischar (s))
+
+    k = find (! isspace (s) & s != "\0");
+    if (isempty (s) || isempty (k))
+      s = "";
+    else
+      s = s(:,ceil (min (k) / rows (s)):ceil (max (k) / rows (s)));
+    endif
+
+  elseif (iscell(s))
+
+    s = cellfun (@strtrim, s, "UniformOutput", false);
+
+  else
+    error ("strtrim: expecting string argument");
+  endif
+
+endfunction
+
+%!error <Invalid call to strtrim> strtrim();
+%!error <Invalid call to strtrim> strtrim("abc", "def");
+%!assert (strtrim ("    abc  "), "abc");
+%!assert (strtrim ([" abc   "; "   def   "]), ["abc  "; "  def"]);
diff --git a/scripts/strings/strtrunc.m b/scripts/strings/strtrunc.m
new file mode 100644
index 0000000..7db21c8
--- /dev/null
+++ b/scripts/strings/strtrunc.m
@@ -0,0 +1,59 @@
+## Copyright (C) 2006, 2007, 2009 William Poetra Yoga Hadisoeseno
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strtrunc (@var{s}, @var{n})
+## Truncate the character string @var{s} to length @var{n}.  If @var{s}
+## is a char matrix, then the number of columns is adjusted.
+##
+## If @var{s} is a cell array of strings, then the operation is performed
+## on its members and the new cell array is returned.
+## @end deftypefn
+
+function s = strtrunc (s, n)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (ischar (s))
+    s_was_char = true;
+    s = {s};
+  else
+    s_was_char = false;
+  endif
+
+  if (iscellstr (s))
+    for i = 1:(numel (s))
+      s{i} = s{i}(:,1:(min (n, columns (s{i}))));
+    endfor
+  else
+    error ("strtrunc: s must be a character string or a cell array of strings");
+  endif
+
+  if (s_was_char)
+    s = s{:};
+  endif
+
+endfunction
+
+%!error <Invalid call to strtrunc> strtrunc ();
+%!error <s must be a character string or a cell array of strings> strtrunc (1, 1)
+%!assert (strtrunc("abcdefg", 4), "abcd");
+%!assert (strtrunc("abcdefg", 10), "abcdefg");
+%!assert (strtrunc({"abcdef", "fedcba"}, 3), {"abc", "fed"});
diff --git a/scripts/strings/substr.m b/scripts/strings/substr.m
new file mode 100644
index 0000000..6abdc02
--- /dev/null
+++ b/scripts/strings/substr.m
@@ -0,0 +1,81 @@
+## Copyright (C) 1996, 1999, 2000, 2004, 2005, 2006, 2007, 2008,
+##               2009 Kurt Hornik
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} substr (@var{s}, @var{offset}, @var{len})
+## Return the substring of @var{s} which starts at character number
+## @var{offset} and is @var{len} characters long.
+##
+## If @var{offset} is negative, extraction starts that far from the end of
+## the string.  If @var{len} is omitted, the substring extends to the end
+## of S.
+##
+## For example,
+##
+## @example
+## @group
+## substr ("This is a test string", 6, 9)
+##      @result{} "is a test"
+## @end group
+## @end example
+##
+## This function is patterned after AWK.  You can get the same result by
+## @code{@var{s}(@var{offset} : (@var{offset} + @var{len} - 1))}.
+## @end deftypefn
+
+## Author: Kurt Hornik <Kurt.Hornik at wu-wien.ac.at>
+## Adapted-By: jwe
+
+function t = substr (s, offset, len)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (ischar (s))
+    nc = columns (s);
+    if (abs (offset) > 0 && abs (offset) <= nc)
+      if (offset <= 0)
+        offset += nc + 1;
+      endif
+      if (nargin == 2)
+        eos = nc;
+      else
+        eos = offset + len - 1;
+      endif
+      if (eos <= nc)
+        t = s (:, offset:eos);
+      else
+        error ("substr: length = %d out of range", len);
+      endif
+    else
+      error ("substr: offset = %d out of range", offset);
+    endif
+  else
+    error ("substr: expecting string argument");
+  endif
+
+endfunction
+
+%!assert(strcmp (substr ("This is a test string", 6, 9), "is a test"));
+
+%!error substr ();
+
+%!error substr ("foo", 2, 3, 4);
+
diff --git a/scripts/strings/validatestring.m b/scripts/strings/validatestring.m
new file mode 100644
index 0000000..d7edd45
--- /dev/null
+++ b/scripts/strings/validatestring.m
@@ -0,0 +1,143 @@
+## Copyright (C) 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray})
+## @deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname})
+## @deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname}, @var{varname})
+## @deftypefnx {Function File} {@var{validstr} =} validatestring (@dots{}, @var{position})
+## Verify that @var{str} is a string or substring of an element of
+## @var{strarray}.
+##
+## @var{str} is a character string to be tested, and @var{strarray} is a
+## cellstr of valid values.  @var{validstr} will be the validated form
+## of @var{str} where validation is defined as @var{str} being a member
+## or substring of @var{validstr}.  If @var{str} is a substring of
+## @var{validstr} and there are multiple matches, the shortest match
+## will be returned if all matches are substrings of each other, and an
+## error will be raised if the matches are not substrings of each other.
+##
+## All comparisons are case insensitive.
+## @seealso{strcmp, strcmpi}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function str = validatestring (str, strarray, varargin)
+
+  if (nargin < 2 || nargin > 5)
+    print_usage ();
+  endif
+
+  ## set the defaults
+  funcname = "";
+  varname = "";
+  position = 0;
+  ## set the actual values
+  if (! isempty (varargin))
+    if (isnumeric (varargin{end}))
+      position = varargin{end};
+      varargin(end) = [];
+    endif
+  endif
+  funcnameset = false;
+  varnameset = false;
+  for i = 1:numel (varargin)
+    if (ischar (varargin{i}))
+      if (varnameset)
+        error ("validatestring: invalid number of character inputs: %d",
+               numel (varargin));
+      elseif (funcnameset)
+        varname = varargin{i};
+        varnameset = true;
+      else
+        funcname = varargin{i};
+        funcnameset = true;
+      endif
+    endif
+  endfor
+
+  ## Check the inputs
+  if (! ischar (str))
+    error ("validatestring: str must be a character string");
+  elseif (rows (str) != 1)
+    error ("validatestring: str must have only one row");
+  elseif (! iscellstr (strarray))
+    error ("validatestring: strarray must be a cellstr");
+  elseif (! ischar (funcname))
+    error ("validatestring: funcname must be a character string");
+  elseif (! isempty (funcname) && (rows (funcname) != 1))
+    error ("validatestring: funcname must be exactly one row");
+  elseif (! ischar (varname))
+    error ("validatestring: varname must be a character string");
+  elseif (! isempty (varname) && (rows (varname) != 1))
+    error ("validatestring: varname must be exactly one row");
+  elseif (position < 0)
+    error ("validatestring: position must be >= 0");
+  endif
+
+  ## make the part of the error that will use funcname, varname, and
+  ## position
+  errstr = "";
+  if (! isempty (funcname))
+    errstr = sprintf ("Function: %s ", funcname);
+  endif
+  if (! isempty (varname))
+    errstr = sprintf ("%sVariable: %s ", errstr, varname);
+  endif
+  if (position > 0)
+    errstr = sprintf ("%sArgument position %d ", errstr, position);
+  endif
+  if (! isempty (errstr))
+    errstr(end:end+1) = ":\n";
+  endif
+
+  matches = strncmpi (str, strarray(:), numel (str));
+  nmatches = sum (matches);
+  if (nmatches == 1)
+    str = strarray{matches};
+  elseif (nmatches == 0)
+    error ("validatestring: %s%s does not match any of\n%s", errstr, str,
+           sprintf ("%s, ", strarray{:})(1:end-1));
+  else
+    ## are the matches a substring of each other, if so, choose the
+    ## shortest.  If not, raise an error.
+    match_idx = find (matches);
+    match_l = cellfun (@length, strarray(match_idx));
+    longest_idx = find (match_l == max (match_l), 1);
+    shortest_idx = find (match_l == min (match_l), 1);
+    longest = strarray(match_idx)(longest_idx);
+    for i = 1:numel(match_idx)
+      currentmatch = strarray(match_idx(i));
+      if (! strncmpi (longest, currentmatch, length(currentmatch)))
+        error ("validatestring: %smultiple unique matches were found for %s:\n%s",
+               errstr, sprintf ("%s, ", strarray(match_idx))(1:end-2));
+      endif
+    endfor
+    str = strarray{shortest_idx};
+  endif
+
+endfunction
+
+## Tests
+%!shared strarray
+%!  strarray = {"octave" "Oct" "octopus" "octaves"};
+%!assert (validatestring ("octave", strarray), "octave")
+%!assert (validatestring ("oct", strarray), "Oct")
+%!assert (validatestring ("octave", strarray), "octave")
+%!assert (validatestring ("octav", strarray), "octave")
diff --git a/scripts/testfun/Makefile.in b/scripts/testfun/Makefile.in
new file mode 100644
index 0000000..777f059
--- /dev/null
+++ b/scripts/testfun/Makefile.in
@@ -0,0 +1,83 @@
+# Makefile for octave's scripts/testfun directory
+#
+# Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = testfun
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = assert.m demo.m example.m fail.m rundemos.m speed.m test.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/testfun
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/testfun/assert.m b/scripts/testfun/assert.m
new file mode 100644
index 0000000..75296e2
--- /dev/null
+++ b/scripts/testfun/assert.m
@@ -0,0 +1,291 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} assert (@var{cond})
+## @deftypefnx {Function File} {} assert (@var{cond}, @var{errmsg}, @dots{})
+## @deftypefnx {Function File} {} assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
+## @deftypefnx {Function File} {} assert (@var{observed}, at var{expected})
+## @deftypefnx {Function File} {} assert (@var{observed}, at var{expected}, at var{tol})
+##
+## Produces an error if the condition is not met.  @code{assert} can be
+## called in three different ways.
+##
+## @table @code
+## @item assert (@var{cond})
+## @itemx assert (@var{cond}, @var{errmsg}, @dots{})
+## @itemx assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
+## Called with a single argument @var{cond}, @code{assert} produces an
+## error if @var{cond} is zero.  If called with a single argument a
+## generic error message.  With more than one argument, the additional
+## arguments are passed to the @code{error} function.
+##
+## @item assert (@var{observed}, @var{expected})
+## Produce an error if observed is not the same as expected.  Note that 
+## observed and expected can be strings, scalars, vectors, matrices, 
+## lists or structures.
+##
+## @item assert(@var{observed}, @var{expected}, @var{tol})
+## Accept a tolerance when comparing numbers. 
+## If @var{tol} is positive use it as an absolute tolerance, will produce an error if
+## @code{abs(@var{observed} - @var{expected}) > abs(@var{tol})}.
+## If @var{tol} is negative use it as a relative tolerance, will produce an error if
+## @code{abs(@var{observed} - @var{expected}) > abs(@var{tol} * @var{expected})}.
+## If @var{expected} is zero @var{tol} will always be used as an absolute tolerance.
+## @end table
+## @seealso{test}
+## @end deftypefn
+
+## FIXME: Output throttling: don't print out the entire 100x100 matrix,
+## but instead give a summary; don't print out the whole list, just
+## say what the first different element is, etc.  To do this, make
+## the message generation type specific.
+
+function assert (cond, varargin)
+
+  in = deblank (argn(1,:));
+  for i = 2:rows (argn)
+    in = cstrcat (in, ",", deblank (argn(i,:)));
+  endfor
+  in = cstrcat ("(", in, ")");
+
+  if (nargin == 1 || (nargin > 1 && islogical (cond) && ischar (varargin{1})))
+    if (! isnumeric (cond) || ! all (cond(:)))
+      if (nargin == 1)
+	## Say which elements failed?
+	error ("assert %s failed", in);
+      else
+	error (varargin{:});
+      endif
+    endif  
+  else
+    if (nargin < 2 || nargin > 3)
+      print_usage ();
+    endif
+
+    expected = varargin {1};
+    if (nargin < 3)
+      tol = 0;
+    else
+      tol = varargin {2};
+    endif
+
+    if (exist ("argn") == 0)
+      argn = " ";
+    endif
+
+    coda = "";
+    iserror = 0;
+
+
+    if (ischar (expected))
+      iserror = (! ischar (cond) || ! strcmp (cond, expected));
+
+    elseif (iscell (expected))
+      if (! iscell (cond) || any (size (cond) != size (expected)))
+	iserror = 1;
+      else
+	try
+	  for i = 1:length (expected(:))
+	    assert (cond{i}, expected{i}, tol);
+	  endfor
+	catch
+	  iserror = 1;
+	end_try_catch
+      endif
+
+    elseif (isstruct (expected))
+      if (! isstruct (cond) || any (size (cond) != size (expected))
+	  || rows (fieldnames (cond)) != rows (fieldnames (expected)))
+	iserror = 1;
+      else
+	try
+	  empty = numel (cond) == 0;
+	  normal = numel (cond) == 1;
+	  for [v, k] = cond
+	    if (! isfield (expected, k))
+	      error ();
+	    endif
+	    if (empty)
+	      v = cell (1, 0);
+	    endif
+	    if (normal)
+	      v = {v};
+	    else
+	      v = v(:)';
+	    endif
+	    assert (v, {expected.(k)}, tol);
+	  endfor
+	catch
+	  iserror = 1;
+	end_try_catch
+      endif
+
+    elseif (ndims (cond) != ndims (expected)
+	    || any (size (cond) != size (expected)))
+      iserror = 1;
+      coda = "Dimensions don't match";
+
+    elseif (nargin < 3 && ! strcmp (typeinfo (cond), typeinfo (expected)))
+      iserror = 1;
+      coda = cstrcat ("Type ", typeinfo (cond), " != ", typeinfo (expected));
+
+    else
+      ## Numeric.
+      A = cond(:);
+      B = expected(:);
+      ## Check exceptional values.
+      if (any (isna (A) != isna (B)))
+	iserror = 1;
+	coda = "NAs don't match";
+      elseif (any (isnan (A) != isnan (B)))
+	iserror = 1;
+	coda = "NaNs don't match";
+### Try to avoid problems comparing strange values like Inf+NaNi.
+      elseif (any (isinf (A) != isinf (B))
+	      || any (A(isinf (A) & ! isnan (A)) != B(isinf (B) & ! isnan (B))))
+	iserror = 1;
+	coda = "Infs don't match";
+      else
+	## Check normal values.
+	A = A(finite (A));
+	B = B(finite (B));
+	if (tol == 0)
+          err = any (A != B);
+	  errtype = "values do not match";
+	elseif (tol >= 0)
+	  err = max (abs (A - B));
+	  errtype = "maximum absolute error %g exceeds tolerance %g";
+	else 
+	  abserr = max (abs (A(B == 0)));
+	  A = A(B != 0);
+	  B = B(B != 0);
+	  relerr = max (abs (A - B) ./ abs (B));
+	  err = max ([abserr; relerr]);
+	  errtype = "maximum relative error %g exceeds tolerance %g";
+	endif
+	if (err > abs (tol))
+	  iserror = 1;
+	  coda = sprintf (errtype, err, abs (tol));
+	endif
+      endif
+    endif
+
+    if (! iserror)
+      return;
+    endif
+
+    ## Pretty print the "expected but got" info, trimming leading and
+    ## trailing "\n".
+    str = disp (expected);
+    idx = find (str != "\n");
+    if (! isempty (idx))
+      str = str(idx(1):idx(end));
+    endif
+    str2 = disp (cond);
+    idx = find (str2 != "\n");
+    if (! isempty (idx))
+      str2 = str2 (idx(1):idx(end));
+    endif
+    msg = cstrcat ("assert ", in, " expected\n", str, "\nbut got\n", str2);
+    if (! isempty (coda))
+      msg = cstrcat (msg, "\n", coda);
+    endif
+    error ("%s", msg);
+    ## disp (msg);
+    ## error ("assertion failed");
+  endif
+endfunction
+
+## empty
+%!assert([])
+%!assert(zeros(3,0),zeros(3,0))
+%!error assert(zeros(3,0),zeros(0,2))
+%!error assert(zeros(3,0),[])
+%!fail("assert(zeros(2,0,2),zeros(2,0))", "Dimensions don't match")
+
+## conditions
+%!assert(isempty([]))
+%!assert(1)
+%!error assert(0)
+%!assert(ones(3,1))
+%!assert(ones(1,3))
+%!assert(ones(3,4))
+%!error assert([1,0,1])
+%!error assert([1;1;0])
+%!error assert([1,0;1,1])
+
+## vectors
+%!assert([1,2,3],[1,2,3]);
+%!assert([1;2;3],[1;2;3]);
+%!error assert([2;2;3],[1;2;3]);
+%!error assert([1,2,3],[1;2;3]);
+%!error assert([1,2],[1,2,3]);
+%!error assert([1;2;3],[1;2]);
+%!assert([1,2;3,4],[1,2;3,4]);
+%!error assert([1,4;3,4],[1,2;3,4])
+%!error assert([1,3;2,4;3,5],[1,2;3,4])
+
+## exceptional values
+%!assert([NaN, NA, Inf, -Inf, 1+eps, eps],[NaN, NA, Inf, -Inf, 1, 0],eps)
+%!error assert(NaN, 1)
+%!error assert(NA, 1)
+%!error assert(-Inf, Inf)
+
+## scalars
+%!error assert(3, [3,3; 3,3])
+%!error assert([3,3; 3,3], 3)
+%!assert(3, 3);
+%!assert(3+eps, 3, eps);
+%!assert(3, 3+eps, eps);
+%!error assert(3+2*eps, 3, eps);
+%!error assert(3, 3+2*eps, eps);
+
+## must give a little space for floating point errors on relative
+%!assert(100+100*eps, 100, -2*eps); 
+%!assert(100, 100+100*eps, -2*eps);
+%!error assert(100+300*eps, 100, -2*eps); 
+%!error assert(100, 100+300*eps, -2*eps);
+%!error assert(3, [3,3]);
+%!error assert(3,4);
+
+## test relative vs. absolute tolerances
+%!test  assert (0.1+eps, 0.1,  2*eps);  # accept absolute
+%!error assert (0.1+eps, 0.1, -2*eps);  # fail relative
+%!test  assert (100+100*eps, 100, -2*eps);  # accept relative
+%!error assert (100+100*eps, 100,  2*eps);  # fail absolute
+
+## structures
+%!shared x,y
+%! x.a = 1; x.b=[2, 2];
+%! y.a = 1; y.b=[2, 2];
+%!assert (x,y)
+%!test y.b=3;
+%!error assert (x,y)
+%!error assert (3, x);
+%!error assert (x, 3);
+
+## check usage statements
+%!error assert
+%!error assert(1,2,3,4,5)
+
+## strings
+%!assert("dog","dog")
+%!error assert("dog","cat")
+%!error assert("dog",3);
+%!error assert(3,"dog");
diff --git a/scripts/testfun/demo.m b/scripts/testfun/demo.m
new file mode 100644
index 0000000..0f0fe92
--- /dev/null
+++ b/scripts/testfun/demo.m
@@ -0,0 +1,133 @@
+## Copyright (C) 2000, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} demo ('@var{name}', at var{n})
+##
+## Runs any examples associated with the function '@var{name}'.  
+## Examples are stored in the script file, or in a file with the same 
+## name but no extension somewhere on your path.  To keep them separate 
+## from the usual script code, all lines are prefixed by @code{%!}.  Each
+## example is introduced by the keyword 'demo' flush left to the prefix,
+## with no intervening spaces.  The remainder of the example can contain 
+## arbitrary Octave code.  For example:
+##
+## @example
+## @group
+##    %!demo
+##    %! t=0:0.01:2*pi; x = sin(t);
+##    %! plot(t,x)
+##    %! %-------------------------------------------------
+##    %! % the figure window shows one cycle of a sine wave
+## @end group
+## @end example
+##
+## Note that the code is displayed before it is executed, so a simple
+## comment at the end suffices.  It is generally not necessary to use
+## disp or printf within the demo.
+##
+## Demos are run in a function environment with no access to external
+## variables.  This means that all demos in your function must use
+## separate initialization code.  Alternatively, you can combine your
+## demos into one huge demo, with the code:
+##
+## @example
+##    %! input("Press <enter> to continue: ","s");
+## @end example
+##
+## between the sections, but this is discouraged.  Other techniques
+## include using multiple plots by saying figure between each, or
+## using subplot to put multiple plots in the same window.
+##
+## Also, since demo evaluates inside a function context, you cannot
+## define new functions inside a demo.  Instead you will have to
+## use @code{eval(example('function',n))} to see them.  Because eval only
+## evaluates one line, or one statement if the statement crosses
+## multiple lines, you must wrap your demo in "if 1 <demo stuff> endif"
+## with the 'if' on the same line as 'demo'.  For example,
+##
+## @example
+## @group
+##   %!demo if 1
+##   %!  function y=f(x)
+##   %!    y=x;
+##   %!  endfunction
+##   %!  f(3)
+##   %! endif
+## @end group
+## @end example
+## @seealso{test, example}
+## @end deftypefn
+
+## FIXME: modify subplot so that gnuplot_has_multiplot == 0 causes it to
+## use the current figure window but pause if not plotting in the
+## first subplot.
+
+function demo (name, n)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    n = 0;
+  endif
+
+  [code, idx] = test (name, "grabdemo");
+  if (length (idx) == 0)
+    warning ("demo not available for %s", name);
+    return;
+  elseif (n >= length (idx))
+    warning ("only %d demos available for %s", length (idx) - 1, name);
+    return;
+  endif
+
+
+  if (n > 0)
+    doidx = n;
+  else
+    doidx = 1:length(idx)-1;
+  endif
+  for i = 1:length (doidx)
+    ## Pause between demos
+    if (i > 1)
+      input ("Press <enter> to continue: ", "s");
+    endif
+
+    ## Process each demo without failing
+    try
+      block = code(idx(doidx(i)):idx(doidx(i)+1)-1);
+      ## Use an environment without variables
+      eval (cstrcat ("function __demo__()\n", block, "\nendfunction"));
+      ## Display the code that will be executed before executing it
+      printf ("%s example %d:%s\n\n", name, doidx(i), block);
+      __demo__;
+    catch
+      ## Let the programmer know which demo failed.
+      printf ("%s example %d: failed\n%s", name, doidx(i), __error_text__);
+    end_try_catch
+    clear __demo__;
+  endfor
+
+endfunction
+
+%!demo
+%! t=0:0.01:2*pi; x = sin(t);
+%! plot(t,x)
+%! %-------------------------------------------------
+%! % the figure window shows one cycle of a sine wave
diff --git a/scripts/testfun/example.m b/scripts/testfun/example.m
new file mode 100644
index 0000000..d381d85
--- /dev/null
+++ b/scripts/testfun/example.m
@@ -0,0 +1,94 @@
+## Copyright (C) 2000, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} example ('@var{name}', at var{n})
+## @deftypefnx {Function File} {[@var{x}, @var{idx}] =} example ('@var{name}', at var{n})
+##
+##  Display the code for example @var{n} associated with the function 
+## '@var{name}', but do not run it.  If @var{n} is not given, all examples 
+## are displayed.
+##
+## Called with output arguments, the examples are returned in the form of
+## a string @var{x}, with @var{idx} indicating the ending position of the 
+## various examples.
+##
+## See @code{demo} for a complete explanation.
+## @seealso{demo, test}
+## @end deftypefn
+
+function [code_r, idx_r] = example (name, n)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+  if (nargin < 2)
+    n = 0;
+  endif
+
+  [code, idx] = test (name, "grabdemo");
+  if (nargout > 0)
+    if (n > 0)
+      if (n <= length (idx))
+      	code_r = code(idx(n):idx(n+1)-1);
+      	idx_r = [1, length(code_r)+1];
+      else
+	code_r = "";
+	idx_r = [];
+      endif
+    else
+      code_r = code;
+      idx_r = idx;
+    endif
+  else
+    if (n > 0)
+      doidx = n;
+    else
+      doidx = 1:length(idx)-1;
+    endif
+    if (length (idx) == 0)
+      warning ("example not available for %s", name);
+    elseif (n >= length(idx))
+      warning ("only %d examples available for %s", length(idx)-1, name);
+      doidx = [];
+    endif
+
+    for i = 1:length (doidx)
+      block = code (idx(doidx(i)):idx(doidx(i)+1)-1);
+      printf ("%s example %d:%s\n\n", name, doidx(i), block);
+    endfor
+  endif
+
+endfunction
+
+%!## warning: don't modify the demos without modifying the tests!
+%!demo
+%! example('example');
+%!demo
+%! t=0:0.01:2*pi; x=sin(t);
+%! plot(t,x)
+
+%!assert (example('example',1), "\n example('example');");
+%!test
+%! [code, idx] = example('example');
+%! assert (code, ... 
+%!	   "\n example('example');\n t=0:0.01:2*pi; x=sin(t);\n plot(t,x)")
+%! assert (idx, [1, 22, 59]);
+
+%!error example;
+%!error example('example',3,5)
diff --git a/scripts/testfun/fail.m b/scripts/testfun/fail.m
new file mode 100644
index 0000000..9efc384
--- /dev/null
+++ b/scripts/testfun/fail.m
@@ -0,0 +1,142 @@
+## Copyright (C) 2005, 2006, 2007, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} fail (@var{code}, at var{pattern})
+## @deftypefnx {Function File} {} fail (@var{code},'warning', at var{pattern})
+##
+## Return true if @var{code} fails with an error message matching
+## @var{pattern}, otherwise produce an error.  Note that @var{code}
+## is a string and if @var{code} runs successfully, the error produced is:
+##
+## @example
+##           expected error but got none  
+## @end example
+##
+## If the code fails with a different error, the message produced is:
+##
+## @example
+## @group
+##           expected <pattern>
+##           but got <text of actual error>
+## @end group
+## @end example
+##
+## The angle brackets are not part of the output.
+##
+## Called with three arguments, the behavior is similar to 
+## @code{fail(@var{code}, @var{pattern})}, but produces an error if no 
+## warning is given during code execution or if the code fails.
+##
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle at users.sf.net>
+
+function ret = fail (code, pattern, warning_pattern)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  ## sort out arguments
+  test_warning = (nargin > 1 && strcmp (pattern, "warning"));
+  if (nargin == 3)
+    pattern = warning_pattern;
+  elseif (nargin == 1 || (nargin == 2 && test_warning))
+    pattern = "";
+  endif
+
+  ## match any nonempty message
+  if (isempty (pattern))
+    pattern = ".";
+  endif
+
+  ## allow assert(fail())
+  if (nargout)
+    ret = 1;
+  endif  
+
+  if (test_warning)
+    ## Perform the warning test.
+    ## Clear old warnings.
+    lastwarn ();
+    ## Make sure warnings are turned on.
+    state = warning ("query", "quiet");
+    warning ("on", "quiet");
+    try
+      ## printf("lastwarn before %s: %s\n",code,lastwarn);
+      evalin ("caller", sprintf ("%s;", code));
+      ## printf("lastwarn after %s: %s\n",code,lastwarn);
+      ## Retrieve new warnings.
+      err = lastwarn ();
+      warning (state.state, "quiet");
+      if (isempty (err))
+        msg = sprintf ("expected warning <%s> but got none", pattern); 
+      else
+	## Transform "warning: ...\n" to "...".
+        err([1:9, end]) = [];
+        if (! isempty (regexp (err, pattern, "once")))
+	  return;
+	endif
+        msg = sprintf ("expected warning <%s>\nbut got <%s>", pattern, err);
+      endif
+    catch
+      warning (state.state, "quiet");
+      err = lasterr;
+      ## Transform "error: ...\n", to "...".
+      err([1:7, end]) = [];
+      msg = sprintf ("expected warning <%s> but got error <%s>", pattern, err);
+    end_try_catch
+      
+  else
+    ## Perform the error test.
+    try
+      evalin ("caller", sprintf ("%s;", code));
+      msg = sprintf ("expected error <%s> but got none", pattern);
+    catch
+      err = lasterr ();
+      if (strcmp (err(1:7), "error:"))
+         err([1:6, end]) = []; # transform "error: ...\n", to "..."
+      endif
+      if (! isempty (regexp (err, pattern, "once")))
+	return;
+      endif
+      msg = sprintf ("expected error <%s>\nbut got <%s>", pattern, err);
+    end_try_catch
+  endif
+
+  ## If we get here, then code didn't fail or error didn't match.
+  error (msg);
+
+endfunction
+
+%!fail ('[1,2]*[2,3]','nonconformant')
+%!fail ("fail('[1,2]*[2;3]','nonconformant')","expected error <nonconformant> but got none")
+%!fail ("fail('[1,2]*[2,3]','usage:')","expected error <usage:>\nbut got.*nonconformant")
+%!fail ("warning('test warning')",'warning','test warning');
+
+%!# fail ("warning('next test')",'warning','next test');  ## only allowed one warning test?!?
+
+## Comment out the following tests if you don't want to see what
+## errors look like
+% !fail ('a*[2;3]', 'nonconformant')
+% !fail ('a*[2,3]', 'usage:')
+% !fail ("warning('warning failure')", 'warning', 'success')
diff --git a/scripts/testfun/rundemos.m b/scripts/testfun/rundemos.m
new file mode 100644
index 0000000..d3bb3df
--- /dev/null
+++ b/scripts/testfun/rundemos.m
@@ -0,0 +1,77 @@
+## Copyright (C) 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rundemos (@var{directory})
+## @end deftypefn
+
+## Author: jwe
+
+function rundemos (directory)
+
+  if (nargin == 0)
+    dirs = strsplit (path (), pathsep ());
+  elseif (nargin == 1)
+    if (is_absolute_filename (directory))
+      dirs = {directory};
+    else
+      fullname = find_dir_in_path (directory);
+      if (! isempty (fullname))
+	dirs = {fullname};
+      else
+	error ("rundemos: expecting argument to be a directory name");
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+  for i = 1:numel (dirs)
+    d = dirs{i};
+    run_all_demos (d);
+  endfor
+
+endfunction
+
+function run_all_demos (directory)
+  dirinfo = dir (directory);
+  flist = {dirinfo.name};
+  for i = 1:numel (flist)
+    f = flist{i};
+    if (length (f) > 2 && strcmp (f((end-1):end), ".m"))
+      f = fullfile (directory, f);
+      if (has_demos (f))
+	demo (f);
+	if (i != numel (flist))
+	  input ("Press <enter> to continue: ", "s");
+	endif
+      endif
+    endif
+  endfor
+endfunction
+
+function retval = has_demos (f)
+  fid = fopen (f);
+  if (f < 0)
+    error ("fopen failed: %s", f);
+  else
+    str = fscanf (fid, "%s");
+    fclose (fid);
+    retval = findstr (str, "%!demo");
+  endif
+endfunction
diff --git a/scripts/testfun/speed.m b/scripts/testfun/speed.m
new file mode 100644
index 0000000..04794ff
--- /dev/null
+++ b/scripts/testfun/speed.m
@@ -0,0 +1,383 @@
+## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+##               2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} speed (@var{f}, @var{init}, @var{max_n}, @var{f2}, @var{tol})
+## @deftypefnx {Function File} {[@var{order}, @var{n}, @var{T_f}, @var{T_f2}] =} speed (@dots{})
+##
+## Determine the execution time of an expression for various @var{n}.
+## The @var{n} are log-spaced from 1 to @var{max_n}.  For each @var{n},
+## an initialization expression is computed to create whatever data
+## are needed for the test.  If a second expression is given, the
+## execution times of the two expressions will be compared.  Called 
+## without output arguments the results are presented graphically.
+##
+## @table @code
+## @item @var{f}
+## The expression to evaluate.
+##
+## @item @var{max_n}
+## The maximum test length to run.  Default value is 100.  Alternatively,
+## use @code{[min_n,max_n]} or for complete control, @code{[n1,n2, at dots{},nk]}.
+##
+## @item @var{init}
+## Initialization expression for function argument values.  Use @var{k} 
+## for the test number and @var{n} for the size of the test.  This should
+## compute values for all variables listed in args.  Note that init will
+## be evaluated first for @math{k = 0}, so things which are constant throughout
+## the test can be computed then.  The default value is @code{@var{x} =
+## randn (@var{n}, 1);}.
+##
+## @item @var{f2}
+## An alternative expression to evaluate, so the speed of the two
+## can be compared.  Default is @code{[]}.
+##
+## @item @var{tol}
+## If @var{tol} is @code{Inf}, then no comparison will be made between the
+## results of expression @var{f} and expression @var{f2}.  Otherwise,
+## expression @var{f} should produce a value @var{v} and expression @var{f2} 
+## should produce a value @var{v2}, and these shall be compared using 
+## @code{assert(@var{v}, at var{v2}, at var{tol})}.  If @var{tol} is positive,
+## the tolerance is assumed to be absolute.  If @var{tol} is negative,
+## the tolerance is assumed to be relative.  The default is @code{eps}.
+##
+## @item @var{order}
+## The time complexity of the expression @code{O(a n^p)}.  This
+## is a structure with fields @code{a} and @code{p}.
+##
+## @item @var{n}
+## The values @var{n} for which the expression was calculated and
+## the execution time was greater than zero.
+##
+## @item @var{T_f}
+## The nonzero execution times recorded for the expression @var{f} in seconds.
+##
+## @item @var{T_f2}
+## The nonzero execution times recorded for the expression @var{f2} in seconds.
+## If it is needed, the mean time ratio is just @code{mean(T_f./T_f2)}.
+##
+## @end table
+##
+## The slope of the execution time graph shows the approximate
+## power of the asymptotic running time @code{O(n^p)}.  This
+## power is plotted for the region over which it is approximated
+## (the latter half of the graph).  The estimated power is not
+## very accurate, but should be sufficient to determine the
+## general order of your algorithm.  It should indicate if for 
+## example your implementation is unexpectedly @code{O(n^2)} 
+## rather than @code{O(n)} because it extends a vector each 
+## time through the loop rather than preallocating one which is 
+## big enough.  For example, in the current version of Octave,
+## the following is not the expected @code{O(n)}:
+##
+## @example
+## speed ("for i = 1:n, y@{i@} = x(i); end", "", [1000,10000])
+## @end example
+##
+## but it is if you preallocate the cell array @code{y}:
+##
+## @example
+## @group
+## speed ("for i = 1:n, y@{i@} = x(i); end", ...
+##        "x = rand (n, 1); y = cell (size (x));", [1000, 10000])
+## @end group
+## @end example
+##
+## An attempt is made to approximate the cost of the individual 
+## operations, but it is wildly inaccurate.  You can improve the
+## stability somewhat by doing more work for each @code{n}.  For
+## example:
+##
+## @example
+## speed ("airy(x)", "x = rand (n, 10)", [10000, 100000])
+## @end example
+##
+## When comparing a new and original expression, the line on the
+## speedup ratio graph should be larger than 1 if the new expression
+## is faster.  Better algorithms have a shallow slope.  Generally, 
+## vectorizing an algorithm will not change the slope of the execution 
+## time graph, but it will shift it relative to the original.  For
+## example:
+##
+## @example
+## @group
+## speed ("v = sum (x)", "", [10000, 100000], ...
+##        "v = 0; for i = 1:length (x), v += x(i); end")
+## @end group
+## @end example
+## 
+## A more complex example, if you had an original version of @code{xcorr}
+## using for loops and another version using an FFT, you could compare the
+## run speed for various lags as follows, or for a fixed lag with varying
+## vector lengths as follows:
+##
+## @example
+## @group
+## speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100,
+##        "v2 = xcorr_orig (x, n)", -100*eps)
+## speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100,
+##        "v2 = xcorr_orig (x, n)", -100*eps)
+## @end group
+## @end example
+##
+## Assuming one of the two versions is in @var{xcorr_orig}, this
+## would compare their speed and their output values.  Note that the
+## FFT version is not exact, so we specify an acceptable tolerance on
+## the comparison @code{100*eps}, and the errors should be computed
+## relatively, as @code{abs((@var{x} - @var{y})./@var{y})} rather than 
+## absolutely as @code{abs(@var{x} - @var{y})}.
+##
+## Type @code{example('speed')} to see some real examples.  Note for 
+## obscure reasons, you can't run examples 1 and 2 directly using 
+## @code{demo('speed')}.  Instead use, @code{eval(example('speed',1))}
+## and @code{eval(example('speed',2))}.
+## @end deftypefn
+
+## FIXME: consider two dimensional speedup surfaces for functions like kron.
+function [__order, __test_n, __tnew, __torig] ...
+      = speed (__f1, __init, __max_n, __f2, __tol)
+
+  if (nargin < 1 || nargin > 6)
+    print_usage ();
+  endif
+
+  if (nargin < 2 || isempty (__init))
+    __init = "x = randn(n, 1);";
+  endif
+
+  if (nargin < 3 || isempty (__max_n))
+    __max_n = 100;
+  endif
+
+  if (nargin < 4)
+    __f2 = [];
+  endif
+
+  if (nargin < 5 || isempty (__tol))
+    __tol = eps;
+  endif
+
+  __numtests = 15;
+
+  ## Let user specify range of n.
+  if (isscalar (__max_n))
+    __min_n = 1;
+    assert (__max_n > __min_n);
+    __test_n = logspace (0, log10 (__max_n), __numtests);
+  elseif (length (__max_n) == 2)
+    __min_n = __max_n(1);
+    __max_n = __max_n(2);
+    assert (__min_n >= 1);
+    __test_n = logspace (log10 (__min_n), log10 (__max_n), __numtests);
+  else
+    __test_n = __max_n;
+  endif
+  ## Force n to be an integer.
+  __test_n = unique (round (__test_n));
+  assert (__test_n >= 1);
+
+  __torig = __tnew = zeros (size (__test_n));
+
+  disp (cstrcat ("testing ", __f1, "\ninit: ", __init));
+
+  ## Make sure the functions are freshly loaded by evaluating them at
+  ## test_n(1); first have to initialize the args though.
+  n = 1;
+  k = 0;
+  eval (cstrcat (__init, ";"));
+  if (! isempty (__f2))
+    eval (cstrcat (__f2, ";"));
+  endif
+  eval (cstrcat (__f1, ";"));
+
+  ## Run the tests.
+  for k = 1:length (__test_n)
+    n = __test_n(k);
+    eval (cstrcat (__init, ";"));
+    
+    printf ("n%i = %i  ",k, n);
+    fflush (stdout);
+    eval (cstrcat ("__t = time();", __f1, "; __v1=ans; __t = time()-__t;"));
+    if (__t < 0.25)
+      eval (cstrcat ("__t2 = time();", __f1, "; __t2 = time()-__t2;"));
+      eval (cstrcat ("__t3 = time();", __f1, "; __t3 = time()-__t3;"));
+      __t = min ([__t, __t2, __t3]);
+    endif
+    __tnew(k) = __t;
+
+    if (! isempty (__f2))
+      eval (cstrcat ("__t = time();", __f2, "; __v2=ans; __t = time()-__t;"));
+      if (__t < 0.25)
+      	eval (cstrcat ("__t2 = time();", __f2, "; __t2 = time()-__t2;"));
+      	eval (cstrcat ("__t3 = time();", __f2, "; __t3 = time()-__t3;"));
+      endif
+      __torig(k) = __t;
+      if (! isinf(__tol))
+      	assert (__v1, __v2, __tol);
+      endif
+    endif
+  endfor
+  
+  ## Drop times of zero.
+  if (! isempty (__f2))
+    zidx = (__tnew < 100*eps |  __torig < 100*eps);
+    __test_n(zidx) = [];
+    __tnew(zidx) = [];
+    __torig(zidx) = [];
+  else
+    zidx = (__tnew < 100*eps);
+    __test_n(zidx) = [];
+    __tnew(zidx) = [];
+  endif
+
+  ## Approximate time complexity and return it if requested.
+  tailidx = ceil(length(__test_n)/2):length(__test_n);
+  p = polyfit (log (__test_n(tailidx)), log (__tnew(tailidx)), 1);
+  if (nargout > 0) 
+    __order.p = p(1);
+    __order.a = exp (p(2));
+  endif
+
+  ## Plot the data if no output is requested.
+  doplot = (nargout == 0);
+  
+  if (doplot)
+    figure;
+  endif
+
+  if (doplot && ! isempty (__f2))
+    subplot (1, 2, 1);
+    semilogx (__test_n, __torig./__tnew, 
+	      cstrcat ("-*r;", strrep (__f1, ";", "."), "/",
+		      strrep (__f2, ";", "."), ";"),
+	       __test_n, __tnew./__torig,
+	      cstrcat ("-*g;", strrep (__f2, ";", "."), "/",
+		      strrep (__f1, ";", "."), ";"));
+    xlabel ("test length");
+    title (__f1);
+    ylabel ("speedup ratio");
+
+    subplot (1, 2, 2);
+    loglog (__test_n, __tnew*1000,
+	    cstrcat ("*-g;", strrep (__f1, ";", "."), ";"), 
+	    __test_n, __torig*1000,
+	    cstrcat ("*-r;", strrep (__f2,";","."), ";"));
+  
+    xlabel ("test length");
+    ylabel ("best execution time (ms)");
+    title (cstrcat ("init: ", __init));
+
+    ratio = mean (__torig ./ __tnew);
+    printf ("\n\nMean runtime ratio = %.3g for '%s' vs '%s'\n",
+            ratio, __f2, __f1);
+
+  elseif (doplot)
+
+    loglog (__test_n, __tnew*1000, "*-g;execution time;");
+    xlabel ("test length");
+    ylabel ("best execution time (ms)");
+    title (cstrcat (__f1, "  init: ", __init));
+
+  endif
+
+  if (doplot)
+
+    ## Plot time complexity approximation (using milliseconds).
+    order = sprintf ("O(n^%g)", round (10*p(1))/10);
+    v = polyval (p, log (__test_n(tailidx)));
+
+    loglog (__test_n(tailidx), exp(v)*1000, sprintf ("b;%s;", order)); 
+
+    ## Get base time to 1 digit of accuracy.
+    dt = exp (p(2));
+    dt = floor (dt/10^floor(log10(dt)))*10^floor(log10(dt));
+    if (log10 (dt) >= -0.5)
+      time = sprintf ("%g s", dt);
+    elseif (log10 (dt) >= -3.5)
+      time = sprintf ("%g ms", dt*1e3);
+    elseif (log10 (dt) >= -6.5)
+      time = sprintf ("%g us", dt*1e6);
+    else
+      time = sprintf ("%g ns", dt*1e9);
+    endif
+
+    ## Display nicely formatted complexity.
+    printf ("\nFor %s:\n", __f1);
+    printf ("  asymptotic power: %s\n", order);
+    printf ("  approximate time per operation: %s\n", time); 
+
+  endif
+
+endfunction
+
+%!demo if 1
+%!  function x = build_orig(n)
+%!    ## extend the target vector on the fly
+%!    for i=0:n-1, x([1:10]+i*10) = 1:10; endfor
+%!  endfunction
+%!  function x = build(n)
+%!    ## preallocate the target vector
+%!    x = zeros(1, n*10);
+%!    try
+%!      if (prefer_column_vectors), x = x.'; endif
+%!    catch
+%!    end
+%!    for i=0:n-1, x([1:10]+i*10) = 1:10; endfor
+%!  endfunction
+%!
+%!  disp("-----------------------");
+%!  type build_orig;
+%!  disp("-----------------------");
+%!  type build;
+%!  disp("-----------------------");
+%!
+%!  disp("Preallocated vector test.\nThis takes a little while...");
+%!  speed('build(n)', '', 1000, 'build_orig(n)');
+%!  clear build build_orig
+%!  disp("Note how much faster it is to pre-allocate a vector.");
+%!  disp("Notice the peak speedup ratio.");
+%! endif
+
+%!demo if 1
+%!  function x = build_orig(n)
+%!    for i=0:n-1, x([1:10]+i*10) = 1:10; endfor
+%!  endfunction
+%!  function x = build(n)
+%!    idx = [1:10]';
+%!    x = idx(:,ones(1,n));
+%!    x = reshape(x, 1, n*10);
+%!    try
+%!      if (prefer_column_vectors), x = x.'; endif
+%!    catch
+%!    end
+%!  endfunction
+%!
+%!  disp("-----------------------");
+%!  type build_orig;
+%!  disp("-----------------------");
+%!  type build;
+%!  disp("-----------------------");
+%!
+%!  disp("Vectorized test. This takes a little while...");
+%!  speed('build(n)', '', 1000, 'build_orig(n)');
+%!  clear build build_orig
+%!  disp("-----------------------");
+%!  disp("This time, the for loop is done away with entirely.");
+%!  disp("Notice how much bigger the speedup is then in example 1.");
+%! endif
diff --git a/scripts/testfun/test.m b/scripts/testfun/test.m
new file mode 100644
index 0000000..7ebb1c6
--- /dev/null
+++ b/scripts/testfun/test.m
@@ -0,0 +1,792 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} test @var{name}
+## @deftypefnx {Function File} {} test @var{name} quiet|normal|verbose
+## @deftypefnx {Function File} {} test ('@var{name}', 'quiet|normal|verbose', @var{fid})
+## @deftypefnx {Function File} {} test ([], 'explain', @var{fid})
+## @deftypefnx {Function File} {@var{success} =} test (@dots{})
+## @deftypefnx {Function File} {[@var{n}, @var{max}] =} test (@dots{})
+## @deftypefnx {Function File} {[@var{code}, @var{idx}] =} test ('@var{name}','grabdemo')
+##
+## Perform tests from the first file in the loadpath matching @var{name}.
+## @code{test} can be called as a command or as a function.  Called with 
+## a single argument @var{name}, the tests are run interactively and stop
+## after the first error is encountered.
+##
+## With a second argument the tests which are performed and the amount of
+## output is selected.
+##
+## @table @asis
+## @item 'quiet'
+##  Don't report all the tests as they happen, just the errors.
+##
+## @item 'normal'
+## Report all tests as they happen, but don't do tests which require 
+## user interaction.
+##
+## @item 'verbose'
+## Do tests which require user interaction.
+## @end table
+##
+## The argument @var{fid} can be used to allow batch processing.  Errors
+## can be written to the already open file defined by @var{fid}, and 
+## hopefully when Octave crashes this file will tell you what was happening
+## when it did.  You can use @code{stdout} if you want to see the results as
+## they happen.  You can also give a file name rather than an @var{fid}, in
+## which case the contents of the file will be replaced with the log from 
+## the current test.
+##
+## Called with a single output argument @var{success}, @code{test} returns
+## true if all of the tests were successful.  Called with two output arguments
+## @var{n} and @var{max}, the number of successful tests and the total number
+## of tests in the file @var{name} are returned.
+##
+## If the second argument is the string 'grabdemo', the contents of the demo
+## blocks are extracted but not executed.  Code for all code blocks is
+## concatenated and returned as @var{code} with @var{idx} being a vector of
+## positions of the ends of the demo blocks.
+##
+## If the second argument is 'explain', then @var{name} is ignored and an
+## explanation of the line markers used is written to the file @var{fid}.
+## @seealso{error, assert, fail, demo, example}
+## @end deftypefn
+
+## FIXME: * Consider using keyword fail rather then error?  This allows us
+## to make a functional form of error blocks, which means we
+## can include them in test sections which means that we can use
+## octave flow control for both kinds of tests.
+
+function [__ret1, __ret2, __ret3, __ret4] = test (__name, __flag, __fid)
+  ## Information from test will be introduced by "key".
+  persistent __signal_fail =  "!!!!! ";
+  persistent __signal_empty = "????? ";
+  persistent __signal_block = "  ***** ";
+  persistent __signal_file =  ">>>>> ";
+  persistent __signal_skip = "----- ";
+
+  __xfail = 0;
+  __xskip = 0;
+
+  if (nargin < 2 || isempty (__flag))
+    __flag = "quiet";
+  endif
+  if (nargin < 3)
+    __fid = []; 
+  endif
+  if (nargin < 1 || nargin > 3
+      || (! ischar (__name) && ! isempty (__name)) || ! ischar (__flag))
+    print_usage ();
+  endif
+  if (isempty (__name) && (nargin != 3 || ! strcmp (__flag, "explain")))
+    print_usage ();
+  endif
+  __batch = (! isempty (__fid));
+
+  ## Decide if error messages should be collected.
+  __close_fid = 0;
+  if (__batch)
+    if (ischar (__fid))
+      __fid = fopen (__fid, "wt");
+      if (__fid < 0)
+	error ("could not open log file");
+      endif
+      __close_fid = 1;
+    endif
+    fprintf (__fid, "%sprocessing %s\n", __signal_file, __name);
+    fflush (__fid);
+  else
+    __fid = stdout;
+  endif
+
+  if (strcmp (__flag, "normal"))
+    __grabdemo = 0;
+    __rundemo = 0;
+    __verbose = __batch;
+  elseif (strcmp (__flag, "quiet"))
+    __grabdemo = 0;
+    __rundemo = 0;
+    __verbose = 0;
+  elseif (strcmp (__flag, "verbose"))
+    __grabdemo = 0;
+    __rundemo = 1;
+    __verbose = 1;
+  elseif (strcmp (__flag, "grabdemo"))
+    __grabdemo = 1;
+    __rundemo = 0;
+    __verbose = 0;
+    __demo_code = "";
+    __demo_idx = 1;
+  elseif (strcmp (__flag, "explain"))
+    fprintf (__fid, "# %s new test file\n", __signal_file);
+    fprintf (__fid, "# %s no tests in file\n", __signal_empty);
+    fprintf (__fid, "# %s test had an unexpected result\n", __signal_fail);
+    fprintf (__fid, "# %s code for the test\n", __signal_block);
+    fprintf (__fid, "# Search for the unexpected results in the file\n");
+    fprintf (__fid, "# then page back to find the file name which caused it.\n");
+    fprintf (__fid, "# The result may be an unexpected failure (in which\n");
+    fprintf (__fid, "# case an error will be reported) or an unexpected\n");
+    fprintf (__fid, "# success (in which case no error will be reported).\n");
+    fflush (__fid);
+    if (__close_fid)
+      fclose(__fid);
+    endif
+    return;
+  else
+    error ("test unknown flag '%s'", __flag);
+  endif
+
+  ## Locate the file to test.
+  __file = file_in_loadpath (__name, "all");
+  if (isempty (__file))
+    __file = file_in_loadpath (cstrcat (__name, ".m"), "all");
+  endif
+  if (isempty (__file))
+    __file = file_in_loadpath (cstrcat (__name, ".cc"), "all");
+  endif
+  if (iscell (__file))
+      ## If repeats, return first in path.
+    if (isempty (__file))
+      __file = "";
+    else
+      __file = __file{1};
+    endif
+  endif
+  if (isempty (__file))
+    if (__grabdemo)
+      __ret1 = "";
+      __ret2 = [];
+    else
+      fprintf (__fid, "%s%s does not exist in path\n", __signal_empty, __name);
+      fflush (__fid);
+      if (nargout > 0)
+	__ret1 = __ret2 = 0;
+      endif
+    endif
+    if (__close_fid)
+      fclose(__fid);
+    endif
+    return;
+  endif
+
+  ## Grab the test code from the file.
+  __body = __extract_test_code (__file);
+
+  if (isempty (__body))
+    if (__grabdemo)
+      __ret1 = "";
+      __ret2 = [];
+    else
+      fprintf (__fid, "%s%s has no tests available\n", __signal_empty, __file);
+      fflush (__fid);
+      if (nargout > 0)
+	__ret1 = __ret2 = 0;
+      endif
+    endif
+    if (__close_fid)
+      fclose(__fid);
+    endif
+    return;
+  else
+    ## Add a dummy comment block to the end for ease of indexing.
+    if (__body (length(__body)) == "\n")
+      __body = sprintf ("\n%s#", __body); 
+    else
+      __body = sprintf ("\n%s\n#", __body); 
+    endif
+  endif
+
+  ## Chop it up into blocks for evaluation.
+  __lineidx = find (__body == "\n");
+  __blockidx = __lineidx(find (! isspace (__body(__lineidx+1))))+1;
+
+  ## Ready to start tests ... if in batch mode, tell us what is happening.
+  if (__verbose)
+    disp (cstrcat (__signal_file, __file));
+  endif
+
+  ## Assume all tests will pass.
+  __all_success = 1;
+
+  ## Process each block separately, initially with no shared variables.
+  __tests = __successes = 0;
+  __shared = " ";
+  __shared_r = " ";
+  __clear = "";
+  for __i = 1:length(__blockidx)-1
+
+    ## Extract the block.
+    __block = __body(__blockidx(__i):__blockidx(__i+1)-2);
+
+    ## Let the user/logfile know what is happening.
+    if (__verbose)
+      fprintf (__fid, "%s%s\n", __signal_block, __block);
+      fflush (__fid);
+    endif
+
+    ## Split __block into __type and __code.
+    __idx = find (! isletter (__block));
+    if (isempty (__idx))
+      __type = __block;
+      __code = "";
+    else
+      __type = __block(1:__idx(1)-1);
+      __code = __block(__idx(1):length(__block));
+    endif
+
+    ## Assume the block will succeed.
+    __success = 1;
+    __msg = [];
+
+### DEMO
+
+    ## If in __grabdemo mode, then don't process any other block type.
+    ## So that the other block types don't have to worry about
+    ## this __grabdemo mode, the demo block processor grabs all block
+    ## types and skips those which aren't demo blocks.
+
+    __isdemo = strcmp (__type, "demo");
+    if (__grabdemo || __isdemo)
+      __istest = 0;
+
+      if (__grabdemo && __isdemo)
+	if (isempty(__demo_code))
+	  __demo_code = __code;
+	  __demo_idx = [1, length(__demo_code)+1];
+	else
+	  __demo_code = cstrcat(__demo_code, __code);
+	  __demo_idx = [__demo_idx, length(__demo_code)+1];
+	endif
+
+      elseif (__rundemo && __isdemo)
+      	try
+	  ## process the code in an environment without variables
+      	  eval (sprintf ("function __test__()\n%s\nendfunction", __code));
+	  __test__;
+	  input ("Press <enter> to continue: ", "s");
+      	catch
+	  __success = 0;
+	  __msg = sprintf ("%sdemo failed\n%s",  __signal_fail, __error_text__);
+      	end_try_catch
+      	clear __test__;
+
+      endif
+      ## Code already processed.
+      __code = "";
+      
+### SHARED
+
+    elseif (strcmp (__type, "shared"))
+      __istest = 0;
+
+      ## Separate initialization code from variables.
+      __idx = find (__code == "\n");
+      if (isempty (__idx))
+	__vars = __code;
+	__code = "";
+      else
+      	__vars = __code (1:__idx(1)-1);
+      	__code = __code (__idx(1):length(__code));
+      endif
+      
+      ## Strip comments off the variables.
+      __idx = find (__vars == "%" | __vars == "#");
+      if (! isempty (__idx))
+	__vars = __vars(1:__idx(1)-1);
+      endif
+      
+      ## Assign default values to variables.
+      try
+	__vars = deblank (__vars);
+	if (! isempty (__vars))
+	  eval (cstrcat (strrep (__vars, ",", "=[];"), "=[];"));
+	  __shared = __vars;
+	  __shared_r = cstrcat ("[ ", __vars, "] = ");
+      	else
+	  __shared = " ";
+	  __shared_r = " ";
+      	endif
+      catch
+	## Couldn't declare, so don't initialize.
+	__code = "";
+	__success = 0;
+	__msg = sprintf ("%sshared variable initialization failed\n",
+		         __signal_fail);
+      end_try_catch
+
+      ## Clear shared function definitions.
+      eval (__clear, "");
+      __clear = "";
+      
+      ## Initialization code will be evaluated below.
+    
+### FUNCTION
+
+    elseif (strcmp (__type, "function"))
+      __istest = 0;
+      persistent __fn = 0;
+      __name_position = function_name (__block);
+      if (isempty (__name_position))
+        __success = 0;
+        __msg = sprintf ("%stest failed: missing function name\n",
+			 __signal_fail);
+      else
+        __name = __block(__name_position(1):__name_position(2));
+        __code = __block;
+        try
+          eval(__code); ## Define the function
+          __clear = sprintf ("%sclear %s;\n", __clear, __name);
+        catch
+          __success = 0;
+          __msg = sprintf ("%stest failed: syntax error\n%s",
+			   __signal_fail, __error_text__);
+        end_try_catch
+      endif
+      __code = "";
+      
+### ASSERT/FAIL
+
+    elseif (strcmp (__type, "assert") || strcmp (__type, "fail"))
+      __istest = 1;
+      ## Put the keyword back on the code.
+      __code = __block;
+      ## The code will be evaluated below as a test block.
+      
+### ERROR/WARNING
+
+    elseif (strcmp (__type, "error") || strcmp(__type, "warning"))
+      __istest = 1;
+      __warning = strcmp (__type, "warning");
+      [__pattern, __code] = getpattern (__code);
+      try
+      	eval (sprintf ("function __test__(%s)\n%s\nendfunction",
+		       __shared, __code));
+      catch
+      	__success = 0;
+      	__msg = sprintf ("%stest failed: syntax error\n%s",
+			 __signal_fail, __error_text__);
+      end_try_catch
+      
+      if (__success)
+        __success = 0;
+	__warnstate = warning ("query", "quiet");
+	warning ("on", "quiet");
+      	try
+ 	  eval (sprintf ("__test__(%s);", __shared));
+          if (! __warning)
+       	    __msg = sprintf ("%sexpected <%s> but got no error\n",
+ 			     __signal_fail, __pattern);
+	  else
+	    __err = trimerr (lastwarn, "warning");
+            warning (__warnstate.state, "quiet");
+            if (isempty (__err))
+              __msg = sprintf ("%sexpected <%s> but got no warning\n",
+			     __signal_fail, __pattern);
+            elseif (isempty (regexp (__err, __pattern, "once")))
+              __msg = sprintf ("%sexpected <%s> but got %s\n",
+ 			       __signal_fail, __pattern, __err);
+            else
+              __success = 1;
+            endif
+	  endif
+
+      	catch
+	  __err = trimerr (lasterr, "error");
+          warning (__warnstate.state, "quiet");
+          if (__warning)
+            __msg = sprintf ("%sexpected warning <%s> but got error %s\n",
+			     __signal_fail, __pattern, __err);
+	  elseif (isempty (regexp (__err, __pattern, "once")))
+            __msg = sprintf ("%sexpected <%s> but got %s\n",
+			     __signal_fail, __pattern, __err);
+          else
+	    __success = 1;
+          endif
+      	end_try_catch
+      	clear __test__;
+      endif
+      ## Code already processed.
+      __code = "";
+      
+### TESTIF
+
+    elseif (strcmp (__type, "testif"))
+      [__e, __feat] = regexp (__code, '^\s*([^\s]+)', 'end', 'tokens');
+      if (isempty (findstr (octave_config_info ("DEFS"), __feat{1}{1})))
+        __xskip++;
+	__success = 0;
+	__istest = 0;
+	## Skip the code.
+	__code = "";
+	__msg = sprintf ("%sskipped test\n", __signal_skip);
+      else
+        __istest = 1;
+	__code = __code(__e + 1 : end);
+      endif
+
+### TEST
+
+    elseif (strcmp (__type, "test") || strcmp (__type, "xtest"))
+      __istest = 1;
+      ## Code will be evaluated below.
+
+### Comment block.
+
+    elseif (strcmp (__block(1:1), "#"))
+      __istest = 0;
+      __code = ""; # skip the code
+
+### Unknown block.
+
+    else
+      __istest = 1;
+      __success = 0;
+      __msg = sprintf ("%sunknown test type!\n", __signal_fail);
+      __code = ""; # skip the code
+    endif
+
+    ## evaluate code for test, shared, and assert.
+    if (! isempty(__code))
+      try
+      	eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
+		       __shared_r,__shared, __code));
+	eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
+      catch
+        if (strcmp (__type, "xtest"))
+           __msg = sprintf ("%sknown failure\n%s", __signal_fail, __error_text__);
+	   __xfail++;
+        else
+           __msg = sprintf ("%stest failed\n%s", __signal_fail, __error_text__);
+	   __success = 0;
+        endif
+	if (isempty (__error_text__))
+	  error ("empty error text, probably Ctrl-C --- aborting"); 
+	endif
+      end_try_catch
+      clear __test__;
+    endif
+    
+    ## All done.  Remember if we were successful and print any messages.
+    if (! isempty (__msg))
+      ## Make sure the user knows what caused the error.
+      if (! __verbose)
+      	fprintf (__fid, "%s%s\n", __signal_block, __block);
+	fflush (__fid);
+      endif
+      fputs (__fid, __msg);
+      fflush (__fid);
+      ## Show the variable context.
+      if (! strcmp (__type, "error") && ! strcmp (__type, "testif")
+	  && ! all (__shared == " "))
+	fputs (__fid, "shared variables ");
+	eval (sprintf ("fdisp(__fid,bundle(%s));", __shared)); 
+	fflush (__fid);
+      endif
+    endif
+    if (__success == 0)
+      __all_success = 0;
+      ## Stop after one error if not in batch mode.
+      if (! __batch)
+    	if (nargout > 0)
+	  __ret1 = __ret2 = 0;
+	endif
+	if (__close_fid)
+	  fclose(__fid);
+	endif
+      	return;
+      endif
+    endif
+    __tests += __istest;
+    __successes += __success * __istest;
+  endfor
+  eval (__clear, "");
+
+  if (nargout == 0)
+    if (__tests || __xfail || __xskip)
+      if (__xfail)
+	printf ("PASSES %d out of %d tests (%d expected failures)\n",
+		__successes, __tests, __xfail);
+      else
+	printf ("PASSES %d out of %d tests\n", __successes, __tests);
+      endif
+      if (__xskip)
+	printf ("Skipped %d tests due to missing features\n", __xskip);
+      endif
+    else
+      printf ("%s%s has no tests available\n", __signal_empty, __file);
+    endif
+  elseif (__grabdemo)
+    __ret1 = __demo_code;
+    __ret2 = __demo_idx;
+  elseif (nargout == 1)
+    __ret1 = __all_success; 
+  else
+    __ret1 = __successes;
+    __ret2 = __tests;
+    __ret3 = __xfail;
+    __ret4 = __xskip;
+  endif
+endfunction
+
+## Create structure with fieldnames the name of the input variables.
+function s = varstruct (varargin)
+  for i = 1:nargin
+    s.(deblank (argn(i,:))) = varargin{i};
+  endfor
+endfunction
+
+## Find [start,end] of fn in 'function [a,b] = fn'.
+function pos = function_name (def)
+  pos = [];
+
+  ## Find the end of the name.
+  right = find (def == "(", 1);
+  if (isempty (right))
+    return;
+  endif
+  right = find (def(1:right-1) != " ", 1, "last");
+
+  ## Find the beginning of the name.
+  left = max ([find(def(1:right)==" ", 1, "last"), ...
+	       find(def(1:right)=="=", 1, "last")]);
+  if (isempty (left))
+    return;
+  endif
+  left++;
+
+  ## Return the end points of the name.
+  pos = [left, right];
+endfunction
+
+## Strip <pattern> from '<pattern> code'.
+function [pattern, rest] = getpattern (str)
+  pattern = ".";
+  rest = str; 
+  str = trimleft (str);
+  if (! isempty (str) && str(1) == "<")
+    close = index (str, ">");
+    if (close)
+      pattern = str(2:close-1);
+      rest = str(close+1:end);
+    endif
+  endif
+endfunction
+
+## Strip '.*prefix:' from '.*prefix: msg\n' and strip trailing blanks.
+function msg = trimerr (msg, prefix)
+  idx = index (msg, cstrcat (prefix, ":"));
+  if (idx > 0)
+    msg(1:idx+length(prefix)) = [];
+  endif
+  msg = trimleft (deblank (msg));
+endfunction
+
+## Strip leading blanks from string.
+function str = trimleft (str)
+  idx = find (isspace (str));
+  leading = find (idx == 1:length(idx));
+  if (! isempty (leading))
+    str = str(leading(end)+1:end);
+  endif
+endfunction
+
+## Make a structure out of the named variables
+## (based on Etienne Grossmann's tar function).
+function s = bundle (varargin)
+  for i = 1:nargin
+    s.(deblank (argn(i,:))) = varargin{i};
+  endfor
+endfunction
+
+function body = __extract_test_code (nm)
+  fid = fopen (nm, "rt");
+  body = [];
+  if (fid >= 0)
+    while (! feof (fid))
+      ln = fgetl (fid);
+      if (length (ln) >= 2 && strcmp (ln(1:2), "%!"))
+        body = [body, "\n"];
+        if (length(ln) > 2)
+          body = cstrcat (body, ln(3:end));
+        endif
+      endif
+    endwhile
+    fclose (fid);
+  endif
+endfunction
+
+### Test for test for missing features
+%!testif OCTAVE_SOURCE
+%! ## This test should be run
+%! assert (true);
+
+### Disable this test to avoid spurious skipped test for "make check"
+% !testif HAVE_FOOBAR
+% ! ## missing feature. Fail if this test is run
+% ! error("Failed missing feature test");
+
+### Test for a known failure
+%!xtest error("This test is known to fail")
+
+### example from toeplitz
+%!shared msg
+%! msg="expecting vector arguments";
+%!fail ('toeplitz([])', msg);
+%!fail ('toeplitz([1,2],[])', msg);
+%!fail ('toeplitz([1,2;3,4])', msg);
+%!fail ('toeplitz([1,2],[1,2;3,4])', msg);
+%!fail ('toeplitz ([1,2;3,4],[1,2])', msg);
+% !fail ('toeplitz','usage: toeplitz'); # usage doesn't generate an error
+% !fail ('toeplitz(1, 2, 3)', 'usage: toeplitz');
+%!test  assert (toeplitz ([1,2,3], [1,4]), [1,4; 2,1; 3,2]);
+%!demo  toeplitz ([1,2,3,4],[1,5,6])
+
+### example from kron
+%!#error kron  # FIXME suppress these until we can handle output
+%!#error kron(1,2,3)
+%!test assert (isempty (kron ([], rand(3, 4))))
+%!test assert (isempty (kron (rand (3, 4), [])))
+%!test assert (isempty (kron ([], [])))
+%!shared A, B
+%!test
+%! A = [1, 2, 3; 4, 5, 6]; 
+%! B = [1, -1; 2, -2];
+%!assert (size (kron (zeros (3, 0), A)), [ 3*rows(A), 0 ])
+%!assert (size (kron (zeros (0, 3), A)), [ 0, 3*columns(A) ])
+%!assert (size (kron (A, zeros (3, 0))), [ 3*rows(A), 0 ])
+%!assert (size (kron (A, zeros (0, 3))), [ 0, 3*columns(A) ])
+%!assert (kron (pi, e), pi*e)
+%!assert (kron (pi, A), pi*A) 
+%!assert (kron (A, e), e*A)
+%!assert (kron ([1, 2, 3], A), [ A, 2*A, 3*A ])
+%!assert (kron ([1; 2; 3], A), [ A; 2*A; 3*A ])
+%!assert (kron ([1, 2; 3, 4], A), [ A, 2*A; 3*A, 4*A ])
+%!test
+%! res = [1,-1,2,-2,3,-3; 2,-2,4,-4,6,-6; 4,-4,5,-5,6,-6; 8,-8,10,-10,12,-12];
+%! assert (kron (A, B), res)
+
+### an extended demo from specgram
+%!#demo 
+%! ## Speech spectrogram
+%! [x, Fs] = auload(file_in_loadpath("sample.wav")); # audio file
+%! step = fix(5*Fs/1000);     # one spectral slice every 5 ms
+%! window = fix(40*Fs/1000);  # 40 ms data window
+%! fftn = 2^nextpow2(window); # next highest power of 2
+%! [S, f, t] = specgram(x, fftn, Fs, window, window-step);
+%! S = abs(S(2:fftn*4000/Fs,:)); # magnitude in range 0<f<=4000 Hz.
+%! S = S/max(max(S));         # normalize magnitude so that max is 0 dB.
+%! S = max(S, 10^(-40/10));   # clip below -40 dB.
+%! S = min(S, 10^(-3/10));    # clip above -3 dB.
+%! imagesc(flipud(20*log10(S)), 1);
+%! % you should now see a spectrogram in the image window
+
+
+### now test test itself
+
+%!## usage and error testing
+% !fail ('test','usage.*test')           # no args, generates usage()
+% !fail ('test(1,2,3,4)','usage.*test')  # too many args, generates usage()
+%!fail ('test("test", "bogus")','unknown flag')      # incorrect args
+%!fail ('garbage','garbage.*undefined')  # usage on nonexistent function should be
+
+%!error test                     # no args, generates usage()
+%!error test(1,2,3,4)            # too many args, generates usage()
+%!error <unknown flag> test("test", 'bogus');  # incorrect args, generates error()
+%!error <garbage' undefined> garbage           # usage on nonexistent function should be
+
+%!error test("test", 'bogus');           # test without pattern
+
+%!test
+%! lastwarn();            # clear last warning just in case
+
+%!warning <warning message> warning('warning message');
+
+%!## test of shared variables
+%!shared a                # create a shared variable
+%!test   a=3;             # assign to a shared variable
+%!test   assert(a,3)      # variable should equal 3    
+%!shared b,c              # replace shared variables
+%!test assert (!exist("a"));   # a no longer exists
+%!test assert (isempty(b));    # variables start off empty
+%!shared a,b,c            # recreate a shared variable
+%!test assert (isempty(a));    # value is empty even if it had a previous value
+%!test a=1; b=2; c=3;   # give values to all variables
+%!test assert ([a,b,c],[1,2,3]); # test all of them together
+%!test c=6;             # update a value
+%!test assert([a, b, c],[1, 2, 6]); # show that the update sticks
+%!shared                    # clear all shared variables
+%!test assert(!exist("a"))  # show that they are cleared
+%!shared a,b,c              # support for initializer shorthand
+%! a=1; b=2; c=4;
+
+%!function x = __test_a(y)
+%! x = 2*y;
+%!assert(__test_a(2),4);       # Test a test function
+
+%!function __test_a (y)
+%! x = 2*y;
+%!test
+%! __test_a(2);                # Test a test function with no return value
+
+%!function [x,z] = __test_a (y)
+%! x = 2*y;
+%! z = 3*y;
+%!test                   # Test a test function with multiple returns
+%! [x,z] = __test_a(3);
+%! assert(x,6); 
+%! assert(z,9);
+
+%!## test of assert block
+%!assert (isempty([]))      # support for test assert shorthand
+
+%!## demo blocks
+%!demo                   # multiline demo block
+%! t=[0:0.01:2*pi]; x=sin(t);
+%! plot(t,x);
+%! % you should now see a sine wave in your figure window
+%!demo a=3               # single line demo blocks work too
+
+%!## this is a comment block. it can contain anything.
+%!##
+%! it is the "#" as the block type that makes it a comment
+%! and it  stays as a comment even through continuation lines
+%! which means that it works well with commenting out whole tests
+
+% !# failure tests.  All the following should fail. These tests should
+% !# be disabled unless you are developing test() since users don't
+% !# like to be presented with expected failures.  I use % ! to disable.
+% !test   error("---------Failure tests.  Use test('test','verbose',1)");
+% !test   assert([a,b,c],[1,3,6]);   # variables have wrong values
+% !bogus                     # unknown block type
+% !error  toeplitz([1,2,3]); # correct usage
+% !test   syntax errors)     # syntax errors fail properly
+% !shared garbage in         # variables must be comma separated
+% !error  syntax++error      # error test fails on syntax errors
+% !error  "succeeds.";       # error test fails if code succeeds
+% !error <wrong pattern> error("message")  # error pattern must match
+% !demo   with syntax error  # syntax errors in demo fail properly
+% !shared a,b,c              
+% !demo                      # shared variables not available in demo
+% ! assert(exist("a"))
+% !error  
+% ! test('/etc/passwd');
+% ! test("nonexistent file");
+% ! ## These don't signal an error, so the test for an error fails. Note 
+% ! ## that the call doesn't reference the current fid (it is unavailable),
+% ! ## so of course the informational message is not printed in the log.
diff --git a/scripts/time/Makefile.in b/scripts/time/Makefile.in
new file mode 100644
index 0000000..a3b3e8c
--- /dev/null
+++ b/scripts/time/Makefile.in
@@ -0,0 +1,85 @@
+# Makefile for octave's scripts/time directory
+#
+# Copyright (C) 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../..
+
+script_sub_dir = time
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SOURCES = addtodate.m asctime.m calendar.m clock.m ctime.m date.m \
+  datenum.m datestr.m datetick.m datevec.m eomday.m etime.m is_leap_year.m \
+  now.m weekday.m
+
+DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
+
+FCN_FILES = $(addprefix $(srcdir)/, $(SOURCES))
+FCN_FILES_NO_DIR = $(notdir $(FCN_FILES))
+
+all: PKG_ADD
+.PHONY: all
+
+install install-strip:
+	$(do-script-install)
+.PHONY: install install-strip
+
+uninstall:
+	$(do-script-uninstall)
+.PHONY: uninstall
+
+clean:
+.PHONY: clean
+
+PKG_ADD: $(FCN_FILES)
+	@echo "making PKG_ADD"
+	@$(do-mkpkgadd)
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile PKG_ADD
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../../`cat ../../.fname`/scripts/time
+.PHONY: dist
+
+check-m-sources:
+	@$(do-check-m-sources)
+.PHONY: check-m-sources
diff --git a/scripts/time/addtodate.m b/scripts/time/addtodate.m
new file mode 100644
index 0000000..4d2469c
--- /dev/null
+++ b/scripts/time/addtodate.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2008, 2009 Bill Denney
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{d} =} addtodate (@var{d}, @var{q}, @var{f})
+## Add @var{q} amount of time (with units @var{f}) to the datenum, @var{d}.
+##
+## @var{f} must be one of "year", "month", "day", "hour", "minute", or
+## "second".
+## @seealso{datenum, datevec}
+## @end deftypefn
+
+## Author: Bill Denney <bill at denney.ws>
+
+function d = addtodate (d, q, f)
+
+  if (nargin != 3)
+    print_usage ();
+  elseif (! (ischar (f) && rows (f) == 1))
+    ## FIXME: enhance the function so that it works with cellstrs of the
+    ## same size as the output.
+    error ("addtodate: f must be a single row character string");
+  endif
+
+  if (numel (d) == 1 && numel (q) > 1)
+    ## expand d to the size of q if d only has one element to make
+    ## addition later eaiser.
+    d = d.*ones (size (q));
+  endif
+
+  ## in case the user gives f as a plural, remove the s
+  if ("s" == f(end))
+    f(end) = [];
+  endif
+
+  if (any (strcmpi ({"year" "month"}, f)))
+    dtmp = datevec (d);
+    if (strcmpi ("year", f))
+      dtmp(:,1) += q(:);
+    elseif (strcmpi ("month", f))
+      dtmp(:,2) += q(:);
+      ## adjust the years and months if the date rolls over a year
+      dtmp(:,1) += floor ((dtmp(:,2)-1)/12);
+      dtmp(:,2) = mod (dtmp(:,2)-1, 12) + 1;
+    endif
+    dnew = datenum (dtmp);
+    ## make the output the right shape
+    if (numel (d) == numel (dnew))
+      d = reshape (dnew, size (d));
+    else
+      d = reshape (dnew, size (q));
+    endif
+  elseif (any (strcmpi ({"day" "hour" "minute" "second"}, f)))
+    mult = struct ("day", 1, "hour", 1/24, "minute", 1/1440, "second", 1/86400);
+    d += q.*mult.(f);
+  else
+    error ("addtodate: Invalid time unit: %s", f);
+  endif
+
+endfunction
+
+## tests
+%!shared d
+%!  d = datenum (2008, 1, 1);
+## Identity
+%!assert (addtodate (d, 0, "year"), d)
+%!assert (addtodate (d, 0, "month"), d)
+%!assert (addtodate (d, 0, "day"), d)
+%!assert (addtodate (d, 0, "hour"), d)
+%!assert (addtodate (d, 0, "minute"), d)
+%!assert (addtodate (d, 0, "second"), d)
+## Add one of each
+## leap year
+%!assert (addtodate (d, 1, "year"), d+366)
+%!assert (addtodate (d, 1, "month"), d+31)
+%!assert (addtodate (d, 1, "day"), d+1)
+%!assert (addtodate (d, 1, "hour"), d+1/24)
+%!assert (addtodate (d, 1, "minute"), d+1/1440)
+%!assert (addtodate (d, 1, "second"), d+1/86400)
+## substract one of each
+%!assert (addtodate (d, -1, "year"), d-365)
+%!assert (addtodate (d, -1, "month"), d-31)
+%!assert (addtodate (d, -1, "day"), d-1)
+%!assert (addtodate (d, -1, "hour"), d-1/24)
+%!assert (addtodate (d, -1, "minute"), d-1/1440)
+%!assert (addtodate (d, -1, "second"), d-1/86400)
+## rollover
+%!assert (addtodate (d, 12, "month"), d+366)
+%!assert (addtodate (d, 13, "month"), d+366+31)
+## multiple inputs and output orientation
+%!assert (addtodate ([d d], [1 13], "month"), [d+31 d+366+31])
+%!assert (addtodate ([d;d], [1;13], "month"), [d+31;d+366+31])
+%!assert (addtodate (d, [1;13], "month"), [d+31;d+366+31])
+%!assert (addtodate (d, [1 13], "month"), [d+31 d+366+31])
+%!assert (addtodate ([d;d+1], 1, "month"), [d+31;d+1+31])
+%!assert (addtodate ([d d+1], 1, "month"), [d+31 d+1+31])
diff --git a/scripts/time/asctime.m b/scripts/time/asctime.m
new file mode 100644
index 0000000..75d60d6
--- /dev/null
+++ b/scripts/time/asctime.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} asctime (@var{tm_struct})
+## Convert a time structure to a string using the following five-field
+## format: Thu Mar 28 08:40:14 1996.  For example,
+##
+## @example
+## @group
+## asctime (localtime (time ()))
+##      @result{} "Mon Feb 17 01:15:06 1997\n"
+## @end group
+## @end example
+##
+## This is equivalent to @code{ctime (time ())}.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = asctime (t)
+
+  if (nargin == 1)
+    retval = strftime ("%a %b %d %H:%M:%S %Y\n", t);
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! t = time ();
+%! assert(strcmp (asctime (localtime (t)), ctime (t)));
+
+%!error asctime ();
+
+%!error asctime (1, 2);
+
diff --git a/scripts/time/calendar.m b/scripts/time/calendar.m
new file mode 100644
index 0000000..04fd791
--- /dev/null
+++ b/scripts/time/calendar.m
@@ -0,0 +1,101 @@
+## Copyright (C) 2004, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} calendar (@dots{})
+## @deftypefnx {Function File} {@var{c} =} calendar ()
+## @deftypefnx {Function File} {@var{c} =} calendar (@var{d})
+## @deftypefnx {Function File} {@var{c} =} calendar (@var{y}, @var{m})
+## If called with no arguments, return the current monthly calendar in
+## a 6x7 matrix.
+##
+## If @var{d} is specified, return the calendar for the month containing
+## the day @var{d}, which must be a serial date number or a date string.
+##
+## If @var{y} and @var{m} are specified, return the calendar for year @var{y}
+## and month @var{m}.
+##
+## If no output arguments are specified, print the calendar on the screen
+## instead of returning a matrix.
+## @seealso{datenum}
+## @end deftypefn
+
+## Author: pkienzle <pkienzle at users.sf.net>
+## Created: 25 July 2004
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function varargout = calendar (varargin)
+
+  switch (nargin)
+    case 0
+      v = clock ();
+      y = v(1);
+      m = v(2);
+      d = v(3);
+    case 1
+      v = datevec (varargin{1});
+      y = v(1);
+      m = v(2);
+      d = v(3);
+    case 2
+      y = varargin{1};
+      m = varargin{2};
+      d = [];
+    otherwise
+      print_usage ();
+  endswitch
+
+  c = zeros (7, 6);
+  dayone = datenum (y, m, 1);
+  ndays = eomday (y, m);
+  c(weekday (dayone) - 1 + [1:ndays]) = 1:ndays;
+
+  if (nargout > 0)
+    varargout{1} = c';
+  else
+    ## Layout the calendar days, 6 columns per day, 7 days per row.
+    str = sprintf ("    %2d    %2d    %2d    %2d    %2d    %2d    %2d\n", c);
+
+    ## Print an asterisk before the specified date
+    if (! isempty (d) && d >= 1 && d <= ndays)
+      pos = weekday (dayone) + d - 1;
+      idx = 6 * (pos - 1) + floor (pos / 7) + 1;
+      while (str(idx) == " ")
+        ++idx;
+      endwhile
+      str(--idx) = "*";
+    endif
+
+    ## Display the calendar.
+    s.year = y - 1900;
+    s.mon = m - 1;
+    puts (strftime ("                    %b %Y\n", s));
+    puts ("     S     M    Tu     W    Th     F     S\n");
+    puts (str);
+  endif
+
+endfunction
+
+# tests
+%!assert((calendar(2000,2))'(2:31),[0:29]);
+%!assert((calendar(1957,10))'(2:33),[0:31]);
+# demos
+%!demo
+%! calendar ()
+%!demo
+%! calendar (1957, 10)
diff --git a/scripts/time/clock.m b/scripts/time/clock.m
new file mode 100644
index 0000000..5485844
--- /dev/null
+++ b/scripts/time/clock.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2005, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} clock ()
+## Return a vector containing the current year, month (1-12), day (1-31),
+## hour (0-23), minute (0-59) and second (0-61).  For example,
+##
+## @example
+## @group
+## clock ()
+##      @result{} [ 1993, 8, 20, 4, 56, 1 ]
+## @end group
+## @end example
+##
+## The function clock is more accurate on systems that have the
+## @code{gettimeofday} function.
+## @end deftypefn
+
+## Author: jwe
+
+function retval = clock ()
+
+  tm = localtime (time ());
+
+  retval = zeros (1, 6);
+
+  retval(1) = tm.year + 1900;
+  retval(2) = tm.mon + 1;
+  retval(3) = tm.mday;
+  retval(4) = tm.hour;
+  retval(5) = tm.min;
+  retval(6) = tm.sec + tm.usec / 1e6;
+
+endfunction
+
+%!test
+%! t1 = clock;
+%! t2 = str2num (strftime ("[%Y, %m, %d, %H, %M, %S]", localtime (time ())));
+%! assert(etime (t1, t2) < 1);
+
diff --git a/scripts/time/ctime.m b/scripts/time/ctime.m
new file mode 100644
index 0000000..f9e7e5c
--- /dev/null
+++ b/scripts/time/ctime.m
@@ -0,0 +1,54 @@
+## Copyright (C) 1995, 1996, 1997, 1999, 2000, 2002, 2005, 2006, 2007,
+##               2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ctime (@var{t})
+## Convert a value returned from @code{time} (or any other non-negative
+## integer), to the local time and return a string of the same form as
+## @code{asctime}.  The function @code{ctime (time)} is equivalent to
+## @code{asctime (localtime (time))}.  For example,
+##
+## @example
+## @group
+## ctime (time ())
+##      @result{} "Mon Feb 17 01:15:06 1997\n"
+## @end group
+## @end example
+## @end deftypefn
+
+## Author: jwe
+
+function retval = ctime (t)
+
+  if (nargin == 1)
+    retval = asctime (localtime (t));
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+%!test
+%! t = time ();
+%! assert(strcmp (asctime (localtime (t)), ctime (t)));
+
+%!error ctime ();
+
+%!error ctime (1, 2);
+
diff --git a/scripts/time/date.m b/scripts/time/date.m
new file mode 100644
index 0000000..7315141
--- /dev/null
+++ b/scripts/time/date.m
@@ -0,0 +1,42 @@
+## Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2005, 2007, 2008
+##               John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} date ()
+## Return the date as a character string in the form DD-MMM-YY.  For
+## example,
+##
+## @example
+## @group
+## date ()
+##      @result{} "20-Aug-93"
+## @end group
+## @end example
+## @end deftypefn
+
+## Author: jwe
+
+function retval = date ()
+
+  retval = strftime ("%d-%b-%Y", localtime (time ()));
+
+endfunction
+
+%!assert(strcmp (date (), strftime ("%d-%b-%Y", localtime (time ()))));
+
diff --git a/scripts/time/datenum.m b/scripts/time/datenum.m
new file mode 100644
index 0000000..ff14eeb
--- /dev/null
+++ b/scripts/time/datenum.m
@@ -0,0 +1,156 @@
+## Copyright (C) 2006, 2007, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} datenum (@var{year}, @var{month}, @var{day})
+## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour})
+## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute})
+## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}, @var{second})
+## @deftypefnx {Function File} {} datenum (@code{"date"})
+## @deftypefnx {Function File} {} datenum (@code{"date"}, @var{p})
+## Returns the specified local time as a day number, with Jan 1, 0000
+## being day 1.  By this reckoning, Jan 1, 1970 is day number 719529.  
+## The fractional portion, @var{p}, corresponds to the portion of the
+## specified day.
+##
+## Notes:
+##
+## @itemize
+## @item
+## Years can be negative and/or fractional.
+## @item
+## Months below 1 are considered to be January.
+## @item
+## Days of the month start at 1.
+## @item
+## Days beyond the end of the month go into subsequent months.
+## @item
+## Days before the beginning of the month go to the previous month.
+## @item
+## Days can be fractional.
+## @end itemize
+##
+## @strong{Warning:} this function does not attempt to handle Julian
+## calendars so dates before Octave 15, 1582 are wrong by as much
+## as eleven days.  Also be aware that only Roman Catholic countries
+## adopted the calendar in 1582.  It took until 1924 for it to be 
+## adopted everywhere.  See the Wikipedia entry on the Gregorian 
+## calendar for more details.
+##
+## @strong{Warning:} leap seconds are ignored.  A table of leap seconds
+## is available on the Wikipedia entry for leap seconds.
+## @seealso{date, clock, now, datestr, datevec, calendar, weekday}
+## @end deftypefn
+
+## Algorithm: Peter Baum (http://vsg.cape.com/~pbaum/date/date0.htm)
+## Author: pkienzle <pkienzle at users.sf.net>
+
+function [days, secs] = datenum (Y, M, D, h, m, s)
+
+  ## Days until start of month assuming year starts March 1.
+  persistent monthstart = [306; 337; 0; 31; 61; 92; 122; 153; 184; 214; 245; 275];
+
+  if (nargin == 0 || (nargin > 2  && ischar (Y)) || nargin > 6)
+    print_usage ();
+  endif
+  if (ischar (Y))
+    if (nargin < 2)
+      M = [];
+    endif
+    [Y, M, D, h, m, s] = datevec (Y, M);
+  else
+    if (nargin < 6) s = 0; endif
+    if (nargin < 5) m = 0; endif
+    if (nargin < 4) h = 0; endif
+    if (nargin == 1)
+      nc = columns (Y);
+      if (nc > 6 || nc < 3)
+        error ("expected date vector containing [Y, M, D, h, m, s]");
+      endif
+      s = m = h = 0;
+      if (nc >= 6) s = Y(:,6); endif
+      if (nc >= 5) m = Y(:,5); endif
+      if (nc >= 4) h = Y(:,4); endif
+      D = Y(:,3);
+      M = Y(:,2);
+      Y = Y(:,1);
+    endif 
+  endif
+
+  M(M<1) = 1; ## For compatibility.  Otherwise allow negative months.
+
+  ## Set start of year to March by moving Jan. and Feb. to previous year.
+  ## Correct for months > 12 by moving to subsequent years.
+  Y += fix ((M-14)/12);
+
+  ## Lookup number of days since start of the current year.
+  if (numel (M) == 1 || numel (D) == 1)
+    ## Allow M or D to be scalar while other values may be vectors or
+    ## matrices.
+    D += monthstart (mod (M-1,12) + 1) + 60;
+    if (numel (M) > 1)
+      D = reshape (D, size (M));
+    endif
+  else
+    D += reshape (monthstart (mod (M-1,12) + 1), size (D)) + 60;
+  endif
+
+  ## Add number of days to the start of the current year. Correct
+  ## for leap year every 4 years except centuries not divisible by 400.
+  D += 365*Y + floor (Y/4) - floor (Y/100) + floor (Y/400);
+
+  ## Add fraction representing current second of the day.
+  days = D + (h+(m+s/60)/60)/24;
+
+  ## Output seconds if asked so that etime can be more accurate
+  secs = 86400*D + h*3600 + m*60 + s;
+
+endfunction
+
+%!shared part
+%! part = 0.514623842592593;
+%!assert(datenum(2001,5,19), 730990)
+%!assert(datenum([1417,6,12]), 517712)
+%!assert(datenum([2001,5,19;1417,6,12]), [730990;517712])
+%!assert(datenum(2001,5,19,12,21,3.5), 730990+part, eps)
+%!assert(datenum([1417,6,12,12,21,3.5]), 517712+part, eps)
+## Test vector inputs
+%!test
+%! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5];
+%! n = [730990; 517712] + part;
+%! assert(datenum(t), n, 2*eps);
+## Make sure that the vectors can have either orientation
+%!test
+%! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5]';
+%! n = [730990 517712] + part;
+%! assert(datenum(t(1,:), t(2,:), t(3,:), t(4,:), t(5,:), t(6,:)), n, 2*eps);
+
+## Test mixed vectors and scalars
+%!assert (datenum([2008;2009], 1, 1), [datenum(2008, 1, 1);datenum(2009, 1, 1)]);
+%!assert (datenum(2008, [1;2], 1), [datenum(2008, 1, 1);datenum(2008, 2, 1)]);
+%!assert (datenum(2008, 1, [1;2]), [datenum(2008, 1, 1);datenum(2008, 1, 2)]);
+%!assert (datenum([2008;2009], [1;2], 1), [datenum(2008, 1, 1);datenum(2009, 2, 1)]);
+%!assert (datenum([2008;2009], 1, [1;2]), [datenum(2008, 1, 1);datenum(2009, 1, 2)]);
+%!assert (datenum(2008, [1;2], [1;2]), [datenum(2008, 1, 1);datenum(2008, 2, 2)]);
+## And the other orientation
+%!assert (datenum([2008 2009], 1, 1), [datenum(2008, 1, 1) datenum(2009, 1, 1)]);
+%!assert (datenum(2008, [1 2], 1), [datenum(2008, 1, 1) datenum(2008, 2, 1)]);
+%!assert (datenum(2008, 1, [1 2]), [datenum(2008, 1, 1) datenum(2008, 1, 2)]);
+%!assert (datenum([2008 2009], [1 2], 1), [datenum(2008, 1, 1) datenum(2009, 2, 1)]);
+%!assert (datenum([2008 2009], 1, [1 2]), [datenum(2008, 1, 1) datenum(2009, 1, 2)]);
+%!assert (datenum(2008, [1 2], [1 2]), [datenum(2008, 1, 1) datenum(2008, 2, 2)]);
diff --git a/scripts/time/datestr.m b/scripts/time/datestr.m
new file mode 100644
index 0000000..f46b87a
--- /dev/null
+++ b/scripts/time/datestr.m
@@ -0,0 +1,340 @@
+## Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008,
+##               2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{str} =} datestr (@var{date}, [@var{f}, [@var{p}]])
+## Format the given date/time according to the format @code{f} and return
+## the result in @var{str}.  @var{date} is a serial date number (see
+## @code{datenum}) or a date vector (see @code{datevec}).  The value of
+## @var{date} may also be a string or cell array of strings.
+##
+## @var{f} can be an integer which corresponds to one of the codes in
+## the table below, or a date format string.
+##
+## @var{p} is the year at the start of the century in which two-digit years
+## are to be interpreted in.  If not specified, it defaults to the current
+## year minus 50.
+##
+## For example, the date 730736.65149 (2000-09-07 15:38:09.0934) would be
+## formatted as follows:
+##
+## @multitable @columnfractions 0.1 0.45 0.35
+## @headitem Code @tab Format @tab Example
+## @item  0 @tab dd-mmm-yyyy HH:MM:SS   @tab 07-Sep-2000 15:38:09
+## @item  1 @tab dd-mmm-yyyy            @tab 07-Sep-2000
+## @item  2 @tab mm/dd/yy               @tab 09/07/00
+## @item  3 @tab mmm                    @tab Sep
+## @item  4 @tab m                      @tab S
+## @item  5 @tab mm                     @tab 09
+## @item  6 @tab mm/dd                  @tab 09/07
+## @item  7 @tab dd                     @tab 07
+## @item  8 @tab ddd                    @tab Thu
+## @item  9 @tab d                      @tab T
+## @item 10 @tab yyyy                   @tab 2000
+## @item 11 @tab yy                     @tab 00
+## @item 12 @tab mmmyy                  @tab Sep00
+## @item 13 @tab HH:MM:SS               @tab 15:38:09
+## @item 14 @tab HH:MM:SS PM            @tab 03:38:09 PM
+## @item 15 @tab HH:MM                  @tab 15:38
+## @item 16 @tab HH:MM PM               @tab 03:38 PM
+## @item 17 @tab QQ-YY                  @tab Q3-00
+## @item 18 @tab QQ                     @tab Q3
+## @item 19 @tab dd/mm                  @tab 13/03
+## @item 20 @tab dd/mm/yy               @tab 13/03/95
+## @item 21 @tab mmm.dd.yyyy HH:MM:SS   @tab Mar.03.1962 13:53:06
+## @item 22 @tab mmm.dd.yyyy            @tab Mar.03.1962
+## @item 23 @tab mm/dd/yyyy             @tab 03/13/1962
+## @item 24 @tab dd/mm/yyyy             @tab 12/03/1962
+## @item 25 @tab yy/mm/dd               @tab 95/03/13
+## @item 26 @tab yyyy/mm/dd             @tab 1995/03/13
+## @item 27 @tab QQ-YYYY                @tab Q4-2132
+## @item 28 @tab mmmyyyy                @tab Mar2047
+## @item 29 @tab yyyymmdd               @tab 20470313
+## @item 30 @tab yyyymmddTHHMMSS        @tab 20470313T132603
+## @item 31 @tab yyyy-mm-dd HH:MM:SS    @tab 1047-03-13 13:26:03
+## @end multitable
+##
+## If @var{f} is a format string, the following symbols are recognized:
+##
+## @multitable @columnfractions 0.1 0.7 0.2
+## @headitem Symbol @tab Meaning @tab Example
+## @item yyyy @tab Full year                                    @tab 2005
+## @item yy   @tab Two-digit year                               @tab 2005
+## @item mmmm @tab Full month name                              @tab December
+## @item mmm  @tab Abbreviated month name                       @tab Dec
+## @item mm   @tab Numeric month number (padded with zeros)     @tab 01, 08, 12
+## @item m    @tab First letter of month name (capitalized)     @tab D
+## @item dddd @tab Full weekday name                            @tab Sunday
+## @item ddd  @tab Abbreviated weekday name                     @tab Sun
+## @item dd   @tab Numeric day of month (padded with zeros)     @tab 11
+## @item d    @tab First letter of weekday name (capitalized)   @tab S
+## @item HH   @tab Hour of day, padded with zeros if PM is set  @tab 09:00
+## @item      @tab and not padded with zeros otherwise          @tab 9:00 AM
+## @item MM   @tab Minute of hour (padded with zeros)           @tab 10:05
+## @item SS   @tab Second of minute (padded with zeros)         @tab 10:05:03
+## @item PM   @tab Use 12-hour time format                      @tab 11:30 PM
+## @end multitable
+##
+## If @var{f} is not specified or is @code{-1}, then use 0, 1 or 16,
+## depending on whether the date portion or the time portion of
+## @var{date} is empty.
+##
+## If @var{p} is nor specified, it defaults to the current year minus 50.
+##
+## If a matrix or cell array of dates is given, a vector of date strings is
+## returned.
+##
+## @seealso{datenum, datevec, date, clock, now, datetick}
+## @end deftypefn
+
+## FIXME: parse arbitrary code strings.
+## e.g., for  Wednesday 2001-03-05 09:04:06 AM, use
+##     yy    01
+##     yyyy  2001
+##     m     M
+##     mm    03
+##     mmm   Mar
+##     d     W
+##     dd    05
+##     ddd   Wed
+##     HH    09
+##     MM    04
+##     SS    06
+##     PM    AM
+## FIXME: Vectorize.  It is particularly easy since all the codes are
+##    fixed width.  Just generate the parts in separate arrays and
+##    concatenate.
+
+## Author: pkienzle <pkienzle at users.sf.net>
+## Created: 10 October 2001 (CVS)
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function retval = datestr (date, f, p)
+
+  persistent dateform names_mmmm names_mmm names_m names_dddd names_ddd names_d;
+
+  if (isempty (dateform))
+
+    dateform = cell (32, 1);
+    dateform{1} = "dd-mmm-yyyy HH:MM:SS";
+    dateform{2} = "dd-mmm-yyyy";
+    dateform{3} = "mm/dd/yy";
+    dateform{4} = "mmm";
+    dateform{5} = "m";
+    dateform{6} = "mm";
+    dateform{7} = "mm/dd";
+    dateform{8} = "dd";
+    dateform{9} = "ddd";
+    dateform{10} = "d";
+    dateform{11} = "yyyy";
+    dateform{12} = "yy";
+    dateform{13} = "mmmyy";
+    dateform{14} = "HH:MM:SS";
+    dateform{15} = "HH:MM:SS PM";
+    dateform{16} = "HH:MM";
+    dateform{17} = "HH:MM PM";
+    dateform{18} = "QQ-YY";
+    dateform{19} = "QQ";
+    dateform{20} = "dd/mm";
+    dateform{21} = "dd/mm/yy";
+    dateform{22} = "mmm.dd.yyyy HH:MM:SS";
+    dateform{23} = "mmm.dd.yyyy";
+    dateform{24} = "mm/dd/yyyy";
+    dateform{25} = "dd/mm/yyyy";
+    dateform{26} = "yy/mm/dd";
+    dateform{27} = "yyyy/mm/dd";
+    dateform{28} = "QQ-YYYY";
+    dateform{29} = "mmmyyyy";
+    dateform{30} = "yyyymmdd";
+    dateform{31} = "yyyymmddTHHMMSS";
+    dateform{32} = "yyyy-mm-dd HH:MM:SS";
+
+    names_m = {"J"; "F"; "M"; "A"; "M"; "J"; "J"; "A"; "S"; "O"; "N"; "D"};
+
+    names_d = {"S"; "M"; "T"; "W"; "T"; "F"; "S"};
+
+  endif
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    f = [];
+  endif
+  if (nargin < 3)
+    p = [];
+  endif
+
+  if (ischar (date))
+    t = date;
+    date = cell (1);
+    date{1} = t;
+  endif
+
+  ## Guess, so we might be wrong.
+  if (iscell (date) || columns (date) != 6)
+    v = datevec (date, p);
+  else
+    v = [];
+    if (columns (date) == 6)
+      ## Make sure that the input really is a datevec.
+      maxdatevec = [Inf, 12, 31, 23, 59, 60];
+      for i = 1:numel (maxdatevec)
+        if (any (date(:,i) > maxdatevec(i)) || 
+	    (i != 6 && any (floor (date(:, i)) != date (:, i))))
+          v = datevec (date, p);
+          break;
+        endif
+      endfor
+    endif
+    if (isempty (v))
+      v = date;
+    endif
+  endif
+
+  for i = 1:(rows (v))
+
+    if (isempty (f) || f == -1)
+      if (v(i,4:6) == 0)
+        f = 1;
+	## elseif (v(i,1:3) == [0, 1, 1])
+      elseif (v(i,1:3) == [-1, 12, 31])
+        f = 16;
+      else
+        f = 0;
+      endif
+    endif
+
+    if (isnumeric (f))
+      df = dateform{f + 1};
+    else
+      df = f;
+    endif
+
+    df_orig = df;
+    df = regexprep (df, "[AP]M", "%p");
+    if (strcmp (df, df_orig))
+      ## PM not set.
+      df = strrep (df, "HH", "%H");
+    else
+      df = strrep (df, "HH", sprintf ("%2d", v(i,4)));
+    endif  
+
+    df = regexprep (df, "[Yy][Yy][Yy][Yy]", "%Y");
+
+    df = regexprep (df, "[Yy][Yy]", "%y");
+
+    df = regexprep (df, "[Dd][Dd][Dd][Dd]", "%A");
+
+    df = regexprep (df, "[Dd][Dd][Dd]", "%a");
+
+    df = regexprep (df, "[Dd][Dd]", "%d");
+
+    tmp = names_d{weekday (datenum (v(i,1), v(i,2), v(i,3)))};
+    df = regexprep (df, "([^%])[Dd]", sprintf ("$1%s", tmp));
+    df = regexprep (df, "^[Dd]", sprintf ("%s", tmp));
+
+    df = strrep (df, "mmmm", "%B");
+
+    df = strrep (df, "mmm", "%b");
+
+    df = strrep (df, "mm", "%m");
+
+    tmp = names_m{v(i,2)};
+    pos = regexp (df, "[^%]m") + 1;
+    df(pos) = tmp;
+    df = regexprep (df, "^m", tmp);
+
+    df = strrep (df, "MM", "%M");
+
+    df = strrep (df, "SS", "%S");
+
+    df = regexprep (df, "[Qq][Qq]", sprintf ("Q%d", fix ((v(i,2) + 2) / 3)));
+
+    vi = v(i,:);
+    tm.year = vi(1) - 1900;
+    tm.mon = vi(2) - 1;
+    tm.mday = vi(3);
+    tm.hour = vi(4);
+    tm.min = vi(5);
+    sec = vi(6);
+    tm.sec = fix (sec);
+    tm.usec = fix (rem (sec, 1) * 1e6);
+    ## Force mktime to check for DST.
+    tm.isdst = -1;
+ 
+    str = strftime (df, localtime (mktime (tm)));
+
+    if (i == 1)
+      retval = str;
+    else
+      retval = [retval; str];
+    endif
+
+  endfor
+
+endfunction
+
+# simple tests
+%!shared testtime
+%! testtime = [2005.0000, 12.0000, 18.0000, 2.0000, 33.0000, 17.3822];
+%!assert(datestr(testtime,0),"18-Dec-2005 02:33:17");
+%!assert(datestr(testtime,1),"18-Dec-2005");
+%!assert(datestr(testtime,2),"12/18/05");
+%!assert(datestr(testtime,3),"Dec");
+%!assert(datestr(testtime,4),"D");
+%!assert(datestr(testtime,5),"12");
+%!assert(datestr(testtime,6),"12/18");
+%!assert(datestr(testtime,7),"18");
+%!assert(datestr(testtime,8),"Sun");
+%!assert(datestr(testtime,9),"S");
+%!assert(datestr(testtime,10),"2005");
+%!assert(datestr(testtime,11),"05");
+%!assert(datestr(testtime,12),"Dec05");
+%!assert(datestr(testtime,13),"02:33:17");
+%!assert(datestr(testtime,14)," 2:33:17 AM");
+%!assert(datestr(testtime,15),"02:33");
+%!assert(datestr(testtime,16)," 2:33 AM");
+%!assert(datestr(testtime,17),"Q4-05");
+%!assert(datestr(testtime,18),"Q4");
+%!assert(datestr(testtime,19),"18/12");
+%!assert(datestr(testtime,20),"18/12/05");
+%!assert(datestr(testtime,21),"Dec.18.2005 02:33:17");
+%!assert(datestr(testtime,22),"Dec.18.2005");
+%!assert(datestr(testtime,23),"12/18/2005");
+%!assert(datestr(testtime,24),"18/12/2005");
+%!assert(datestr(testtime,25),"05/12/18");
+%!assert(datestr(testtime,26),"2005/12/18");
+%!assert(datestr(testtime,27),"Q4-2005");
+%!assert(datestr(testtime,28),"Dec2005");
+%!assert(datestr(testtime,29),"20051218");
+%!assert(datestr(testtime,30),"20051218T023317");
+%!assert(datestr(testtime,31),"2005-12-18 02:33:17");
+%!assert(datestr(testtime+[0 0 3 0 0 0],"dddd"),"Wednesday")
+## avoid the bug where someone happens to give a vector of datenums that
+## happens to be 6 wide
+%!assert(datestr(733452.933:733457.933), ["14-Feb-2008 22:23:31";"15-Feb-2008 22:23:31";"16-Feb-2008 22:23:31";"17-Feb-2008 22:23:31";"18-Feb-2008 22:23:31";"19-Feb-2008 22:23:31"])
+# demos
+%!demo
+%! datestr (now ())
+%!demo
+%! datestr (rem (now (), 1))
+%!demo
+%! datestr (floor (now ()))
diff --git a/scripts/time/datetick.m b/scripts/time/datetick.m
new file mode 100644
index 0000000..bc08541
--- /dev/null
+++ b/scripts/time/datetick.m
@@ -0,0 +1,288 @@
+## Copyright (C) 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} datetick (@var{form})
+## @deftypefnx {Function File} {} datetick (@var{axis}, @var{form})
+## @deftypefnx {Function File} {} datetick (@dots{}, "keeplimits")
+## @deftypefnx {Function File} {} datetick (@dots{}, "keepticks")
+## @deftypefnx {Function File} {} datetick (@dots{ax}, @dots{})
+## Adds date formatted tick labels to an axis.  The axis the apply the
+## ticks to is determined by @var{axis} that can take the values "x",
+## "y" or "z".  The default value is "x".  The formatting of the labels is
+## determined by the variable @var{form}, that can either be a string in
+## the format needed by @code{dateform}, or a positive integer that can
+## be accepted by @code{datestr}.
+## @seealso{datenum, datestr}
+## @end deftypefn
+
+function datetick (varargin)
+
+  [h, varargin, nargin] = __plt_get_axis_arg__ ("datetick", varargin{:});
+
+  if (nargin < 1)
+    print_usage ();
+  else
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      __datetick__ (varargin{:});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  endif
+endfunction
+
+%!demo
+%! yr = 1900:10:2000;
+%! pop = [76.094, 92.407, 106.461, 123.077 131.954, 151.868, 179.979, ...
+%!        203.984, 227.225, 249.623, 282.224];
+%! plot (datenum (yr, 1, 1), pop);
+%! title ("US population (millions)");
+%! xlabel ("Year");
+%! datetick ("x", "YYYY");
+
+function __datetick__ (varargin)
+
+  keeplimits = false;
+  keeptick = false;
+  idx = [];
+  for i = 1 : nargin
+    arg = varargin {i};
+    if (ischar (arg))
+      if (strcmpi (arg, "keeplimits"))
+	keeplimits = true;
+	idx = [idx, i];
+      elseif (strcmpi (arg, "keeptick"))
+	keeptick = true;
+	idx = [idx, i];
+      endif
+    endif
+  endfor
+
+  varargin(idx) = [];
+  nargin = length (varargin);
+  form = [];
+  ax = "x";
+
+  if (nargin != 0)
+    arg = varargin{1};
+    if (ischar(arg) && (strcmp (arg, "x") || strcmp (arg, "y") || 
+			strcmp (arg, "z")))
+      ax = arg;
+      if (nargin > 1)
+	form = varargin{2};
+	varargin(1:2) = [];
+      else
+	varargin(1) = [];
+      endif
+    else
+      form = arg;
+      varargin(1) = [];
+    endif
+  endif
+
+  ## Don't publish the existence of this variable for use with dateaxis
+  if (length (varargin) > 0)
+    startdate = varargin{1};
+  else
+    startdate = [];
+  endif
+
+  if (isnumeric (form))
+    if (! isscalar (form) || floor (form) != form || form < 0)
+      error ("datetick: expecting form argument to be a positive integer");
+    endif
+  elseif (! ischar (form) && !isempty (form))
+    error ("datetick: expecting valid date format string");
+  endif
+
+  if (keeptick)
+    ticks = get (gca (), strcat (ax, "tick"))
+  else
+    ## Need to do our own axis tick position calculation as
+    ## year, etc, don't fallback on nice datenum values.
+    objs = findall (gca());
+    xmax = NaN;
+    xmin = NaN;
+    for i = 1 : length (objs)
+      fld = get (objs (i));
+      if (isfield (fld, strcat (ax, "data")))
+	xdata = getfield (fld, strcat (ax, "data"))(:);
+	xmin = min (xmin, min (xdata));
+	xmax = max (xmax, max (xdata));
+      endif
+    endfor
+
+    if (isnan (xmin) || isnan (xmax))
+      xmin = 0;
+      xmax = 1;
+    elseif (xmin == xmax)
+      xmax = xmin + 1;
+    endif
+
+    N = 3;
+    if (xmax - xmin < N)
+      ## Day scale or less
+      if (xmax - xmin < N / 24 / 60 / 60) 
+	scl = 1 / 24 / 60 / 60;
+      elseif (xmax - xmin < N / 24 / 6)
+	scl = 1 / 24 / 60;
+      else
+	scl = 1 / 24;
+      endif
+      sep = __calc_tick_sep__ (xmin / scl , xmax / scl);
+      xmin = sep * floor (xmin / scl / sep);
+      xmax = sep * ceil (xmax / scl / sep);
+      nticks = (xmax - xmin) / sep + 1;
+      xmin *= scl;
+      xmax *= scl;
+    else
+      [ymin, mmin, dmin] = datevec (xmin);
+      [ymax, mmax, dmax] = datevec (xmax);
+      minyear = ymin + (mmin - 1) / 12 + (dmin - 1) / 12 / 30;    
+      maxyear = ymax + (mmax - 1) / 12 + (dmax - 1) / 12 / 30;    
+      minmonth = mmin + (dmin - 1) / 30;    
+      maxmonth = (ymax  - ymin) * 12 + mmax + (dmax - 1) / 30;    
+
+      if (maxmonth - minmonth < N)
+	sep = __calc_tick_sep__ (xmin, xmax);
+	xmin = sep * floor (xmin / sep);
+	xmax = sep * ceil (xmax / sep);
+	nticks = (xmax - xmin) / sep + 1;
+      elseif (maxyear - minyear < N)
+	sep = __calc_tick_sep__ (minmonth , maxmonth);
+	xmin = datenum (ymin, sep * floor (minmonth / sep), 1);
+	xmax = datenum (ymin, sep * ceil (maxmonth / sep), 1);
+	nticks = ceil (maxmonth / sep) - floor (minmonth / sep) + 1;
+      else
+	sep = __calc_tick_sep__ (minyear , maxyear);
+	xmin = datenum (sep * floor (minyear / sep), 1, 1);
+	xmax = datenum (sep * ceil (maxyear / sep), 1, 1);
+	nticks = ceil (maxyear / sep) - floor (minyear / sep) + 1;
+      endif
+    endif
+    ticks = xmin + [0 : nticks - 1] / (nticks - 1) * (xmax - xmin);
+  endif
+
+  if (isempty (form))
+    r = max(ticks) - min(ticks);
+    if r < 10/60/24
+      ## minutes and seconds
+      form = 13;
+    elseif r < 2
+      ## hours
+      form = 15;
+    elseif r < 15
+      ## days
+      form = 8;
+    elseif r < 365
+      ## months
+      form = 6;
+    elseif r < 90*12
+      ## quarters
+      form = 27;
+    else
+      ## years
+      form = 10;
+    endif
+  endif
+
+  if (length (ticks) == 6)
+    ## Careful that its not treated as a datevec
+    if (! isempty (startdate))
+      sticks = strvcat (datestr (ticks(1:end-1) - ticks(1) + startdate, form),
+			datestr (ticks(end) - ticks(1) + startdate, form));
+    else
+      sticks = strvcat (datestr (ticks(1:end-1), form), 
+			datestr (ticks(end), form));
+    endif
+  else
+    if (! isempty (startdate))
+      sticks = datestr (ticks - ticks(1) + startdate, form);
+    else
+      sticks = datestr (ticks, form);
+    endif
+  endif
+
+  sticks = mat2cell (sticks, ones (rows (sticks), 1), columns (sticks));
+
+  if (keeptick)
+    if (keeplimits)
+      set (gca(), strcat (ax, "ticklabel"), sticks);
+    else
+      set (gca(), strcat (ax, "ticklabel"), sticks, strcat (ax, "lim"), 
+	   [min(ticks), max(ticks)]);
+    endif
+  else
+    if (keeplimits)
+      set (gca(), strcat (ax, "tick"), ticks, strcat (ax, "ticklabel"), sticks);
+    else
+      set (gca(), strcat (ax, "tick"), ticks, strcat (ax, "ticklabel"), sticks,
+	   strcat (ax, "lim"), [min(ticks), max(ticks)]);
+    endif
+  endif
+endfunction
+
+function [a, b] = __magform__ (x)
+  if (x == 0)
+    a = 0;
+    b = 0;
+  else
+    l = log10 (abs (x));
+    r = fmod (l, 1);
+    a = 10 .^ r;
+    b = fix (l - r);
+    if (a < 1)
+      a *= 10;
+      b -= 1;
+    endif
+    if (x < 0)
+      a = -a;
+    endif
+  endif
+endfunction
+
+## A translation from Tom Holoryd's python code at
+## http://kurage.nimh.nih.gov/tomh/tics.py
+function sep = __calc_tick_sep__ (lo, hi)
+  persistent sqrt_2  = sqrt (2.0);
+  persistent sqrt_10 = sqrt (10.0);
+  persistent sqrt_50 = sqrt (50.0);
+
+  ticint = 5;
+
+  ## Reference: Lewart, C. R., "Algorithms SCALE1, SCALE2, and
+  ## SCALE3 for Determination of Scales on Computer Generated
+  ## Plots", Communications of the ACM, 10 (1973), 639-640.
+  ## Also cited as ACM Algorithm 463.
+
+  [a, b] = __magform__ ((hi - lo) / ticint);
+
+  if (a < sqrt_2)
+    x = 1;
+  elseif (a < sqrt_10)
+    x = 2;
+  elseif (a < sqrt_50)
+    x = 5;
+  else
+    x = 10;
+  endif
+  sep = x * 10 .^ b;
+endfunction
+
diff --git a/scripts/time/datevec.m b/scripts/time/datevec.m
new file mode 100644
index 0000000..92a9c5e
--- /dev/null
+++ b/scripts/time/datevec.m
@@ -0,0 +1,326 @@
+## Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008, 2009 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{v} =} datevec (@var{date})
+## @deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{f})
+## @deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{p})
+## @deftypefnx {Function File} {@var{v} =} datevec (@var{date}, @var{f}, @var{p})
+## @deftypefnx {Function File} {[@var{y}, @var{m}, @var{d}, @var{h}, @var{mi}, @var{s}] =} datevec (@dots{})
+## Convert a serial date number (see @code{datenum}) or date string (see
+## @code{datestr}) into a date vector.
+##
+## A date vector is a row vector with six members, representing the year,
+## month, day, hour, minute, and seconds respectively.
+##
+## @var{f} is the format string used to interpret date strings
+## (see @code{datestr}).
+##
+## @var{p} is the year at the start of the century in which two-digit years
+## are to be interpreted in.  If not specified, it defaults to the current
+## year minus 50.
+## @seealso{datenum, datestr, date, clock, now}
+## @end deftypefn
+
+## Algorithm: Peter Baum (http://vsg.cape.com/~pbaum/date/date0.htm)
+
+## Author: pkienzle <pkienzle at users.sf.net>
+## Modified: bdenney <bill at givebillmoney.com>
+## Created: 10 October 2001 (CVS)
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+## The function __date_str2vec__ is based on datesplit by Bill Denney.
+
+function [y, m, d, h, mi, s] = datevec (date, varargin)
+
+  persistent std_formats nfmt;
+
+  if (isempty (std_formats))
+    std_formats = cell ();
+    nfmt = 0;
+    std_formats{++nfmt} = "dd-mmm-yyyy HH:MM:SS";   # 0
+    std_formats{++nfmt} = "dd-mmm-yyyy";            # 1
+    std_formats{++nfmt} = "mm/dd/yy";               # 2
+    std_formats{++nfmt} = "mm/dd";                  # 6
+    std_formats{++nfmt} = "HH:MM:SS";               # 13
+    std_formats{++nfmt} = "HH:MM:SS PM";            # 14
+    std_formats{++nfmt} = "HH:MM";                  # 15
+    std_formats{++nfmt} = "HH:MM PM";               # 16
+    std_formats{++nfmt} = "mm/dd/yyyy";             # 23
+    std_formats{++nfmt} = "mmm-dd-yyyy HH:MM:SS"; 
+    std_formats{++nfmt} = "mmm-dd-yyyy";
+    std_formats{++nfmt} = "dd mmm yyyy HH:MM:SS";
+    std_formats{++nfmt} = "dd mmm yyyy";
+    std_formats{++nfmt} = "mmm dd yyyy HH:MM:SS";
+    std_formats{++nfmt} = "mmm dd yyyy";
+    std_formats{++nfmt} = "dd.mmm.yyyy HH:MM:SS";
+    std_formats{++nfmt} = "dd.mmm.yyyy";
+    std_formats{++nfmt} = "mmm.dd.yyyy HH:MM:SS";
+    std_formats{++nfmt} = "mmm.dd.yyyy";
+
+    ## Custom formats.
+    std_formats{++nfmt} = "mmmyy";                  # 12
+    std_formats{++nfmt} = "mm/dd/yyyy HH:MM";
+  endif
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  switch (nargin)
+  case 1
+    f = [];
+    p = [];
+  case 2
+    if (ischar (varargin{1}))
+      f = varargin{1};
+      p = [];
+    else
+      f = [];
+      p = varargin{1};
+    endif
+  case 3
+      f = varargin{1};
+      p = varargin{2};
+  endswitch
+
+  if (isempty (f))
+    f = -1;
+  endif
+
+  if (isempty (p))
+    p = (localtime (time)).year + 1900 - 50;
+  endif
+
+  if (ischar (date))
+    date = cellstr (date);
+  endif
+
+  if (iscell (date))
+
+    nd = numel (date);
+
+    y = m = d = h = mi = s = zeros (nd, 1);
+
+    if (f == -1)
+      for k = 1:nd
+        found = false;
+        for l = 1:nfmt
+          [f, rY, ry, fy, fm, fd, fh, fmi, fs] = __date_vfmt2sfmt__ (std_formats{l});
+          [found y(k) m(k) d(k) h(k) mi(k) s(k)] = __date_str2vec__ (date{k}, p, f, rY, ry, fy, fm, fd, fh, fmi, fs);
+          if (found)
+            break;
+          endif
+        endfor
+        if (! found)
+          error ("datevec: none of the standard formats match the date string");
+        endif
+      endfor
+    else
+      % Decipher the format string just once for sake of speed.
+      [f, rY, ry, fy, fm, fd, fh, fmi, fs] = __date_vfmt2sfmt__ (f);
+      for k = 1:nd
+        [found y(k) m(k) d(k) h(k) mi(k) s(k)] = __date_str2vec__ (date{k}, p, f, rY, ry, fy, fm, fd, fh, fmi, fs);
+        if (! found)
+          error ("datevec: date not parsed correctly with given format");
+        endif
+      endfor
+    endif
+
+  else
+
+    date = date(:);
+
+    ## Move day 0 from midnight -0001-12-31 to midnight 0000-3-1
+    z = floor (date) - 60;
+    ## Calculate number of centuries; K1 = 0.25 is to avoid rounding problems.
+    a = floor ((z - 0.25) / 36524.25);
+    ## Days within century; K2 = 0.25 is to avoid rounding problems.
+    b = z - 0.25 + a - floor (a / 4);
+    ## Calculate the year (year starts on March 1).
+    y = floor (b / 365.25);
+    ## Calculate day in year.
+    c = fix (b - floor (365.25 * y)) + 1;
+    ## Calculate month in year.
+    m = fix ((5 * c + 456) / 153);
+    d = c - fix ((153 * m - 457) / 5);
+    ## Move to Jan 1 as start of year.
+    ++y(m > 12);
+    m(m > 12) -= 12;
+
+    ## Convert hour-minute-seconds.  Attempt to account for precision of
+    ## datenum format.
+
+    fracd = date - floor (date);
+    tmps = abs (eps*86400*date);
+    tmps(tmps == 0) = 1;
+    srnd = 2 .^ floor (- log2 (tmps));
+    s = round (86400 * fracd .* srnd) ./ srnd;
+    h = floor (s / 3600);
+    s = s - 3600 * h;
+    mi = floor (s / 60);
+    s = s - 60 * mi;
+
+  endif
+
+  if (nargout <= 1)
+    y = [y, m, d, h, mi, s];
+  endif
+
+### endfunction
+
+function [f, rY, ry, fy, fm, fd, fh, fmi, fs] = __date_vfmt2sfmt__ (f)
+
+  ## Play safe with percent signs.
+  f = strrep(f, "%", "%%");
+
+  ## Dates to lowercase (note: we cannot convert MM to mm).
+  f = strrep (f, "YYYY", "yyyy");
+  f = strrep (f, "YY", "yy");
+  f = strrep (f, "QQ", "qq");
+  f = strrep (f, "MMMM", "mmmm");
+  f = strrep (f, "MMM", "mmm");
+  f = strrep (f, "DDDD", "dddd");
+  f = strrep (f, "DDD", "ddd");
+  f = strrep (f, "DD", "dd");
+  ## Times to uppercase (also cannot convert mm to MM).
+  f = strrep (f, "hh", "HH");
+  f = strrep (f, "ss", "SS");
+  f = strrep (f, "pm", "PM");
+  f = strrep (f, "am", "AM");
+
+  ## Right now, the format string may only contain these tokens:
+  ##
+  ## yyyy   4 digit year
+  ## yy     2 digit year
+  ## mmmm   month name, full
+  ## mmm    month name, abbreviated
+  ## mm     month number
+  ## dddd   weekday name, full
+  ## ddd    weekday name, abbreviated
+  ## dd     date
+  ## HH     hour
+  ## MM     minutes
+  ## SS     seconds
+  ## PM     AM/PM
+  ## AM     AM/PM
+
+  if (! isempty (strfind (f, "PM")) || ! isempty (strfind (f, "AM")))
+    ampm = true;
+  else
+    ampm = false;
+  endif
+
+  ## Date part.
+  f = strrep (f, "yyyy", "%Y");
+  f = strrep (f, "yy", "%y");
+  f = strrep (f, "mmmm", "%B");
+  f = strrep (f, "mmm", "%b");
+  f = strrep (f, "mm", "%m");
+  f = strrep (f, "dddd", "%A");
+  f = strrep (f, "ddd", "%a");
+  f = strrep (f, "dd", "%d");
+
+  ## Time part.
+  if (ampm)
+    f = strrep (f, "HH", "%I");
+    f = strrep (f, "PM", "%p");
+    f = strrep (f, "AM", "%p");
+  else
+    f = strrep (f, "HH", "%H");
+  endif
+  f = strrep (f, "MM", "%M");
+  f = strrep (f, "SS", "%S");
+
+  rY = rindex (f, "%Y");
+  ry = rindex (f, "%y");
+
+  ## Check whether we need to give default values.
+  ## Possible error when string contains "%%".
+  fy = rY || ry;
+  fm = index (f, "%m") || index (f, "%b") || index (f, "%B");
+  fd = index (f, "%d") || index (f, "%a") || index (f, "%A");
+  fh = index (f, "%H") || index (f, "%I");
+  fmi = index (f, "%M");
+  fs = index (f, "%S");
+
+### endfunction
+
+function [found, y, m, d, h, mi, s] = __date_str2vec__ (ds, p, f, rY, ry, fy, fm, fd, fh, fmi, fs)
+
+  [tm, nc] = strptime (ds, f);
+
+  if (nc == size (ds, 2) + 1)
+    y = tm.year + 1900; m = tm.mon + 1; d = tm.mday;
+    h = tm.hour; mi = tm.min; s = tm.sec + tm.usec / 1e6;
+    found = true;
+    if (rY < ry)
+      if (y > 1999)
+        y -= 2000;
+      else
+        y -= 1900;
+      endif
+      y += p - mod (p, 100);
+      if (y < p)
+        y += 100;
+      endif
+    endif
+    if (! fy && ! fm && ! fd)
+      tmp = localtime (time ());
+      y = tmp.year + 1900;
+      m = tmp.mon + 1;
+      d = tmp.mday;
+    elseif (! fy && fm && fd)
+      tmp = localtime (time ());
+      y = tmp.year + 1900;
+    elseif (fy && fm && ! fd)
+      tmp = localtime (time ());
+      d = 1;
+    endif
+    if (! fh && ! fmi && ! fs)
+      h = mi = s = 0;
+    elseif (fh && fmi && ! fs)
+      s = 0;
+    endif
+  else
+    y = m = d = h = mi = s = 0;
+    found = false;
+  endif
+
+### endfunction
+
+%!shared nowvec
+%! nowvec = datevec (now); # Some tests could fail around midnight!
+# tests for standard formats: 0, 1, 2, 6, 13, 14, 15, 16, 23
+%!assert(datevec("07-Sep-2000 15:38:09"),[2000,9,7,15,38,9]);
+%!assert(datevec("07-Sep-2000"),[2000,9,7,0,0,0]);
+%!assert(datevec("09/07/00"),[2000,9,7,0,0,0]);
+%!assert(datevec("09/13"),[nowvec(1),9,13,0,0,0]);
+%!assert(datevec("15:38:09"),[nowvec(1:3),15,38,9]);
+%!assert(datevec("3:38:09 PM"),[nowvec(1:3),15,38,9]);
+%!assert(datevec("15:38"),[nowvec(1:3),15,38,0]);
+%!assert(datevec("03:38 PM"),[nowvec(1:3),15,38,0]);
+%!assert(datevec("03/13/1962"),[1962,3,13,0,0,0]);
+# other tests
+%!assert(all(datenum(datevec([-1e4:1e4]))==[-1e4:1e4]'))
+%!test
+%! t = linspace (-2e5, 2e5, 10993);
+%! assert (all (abs (datenum (datevec (t)) - t') < 1e-5));
+# demos
+%!demo
+%! datevec (now ())
diff --git a/scripts/time/eomday.m b/scripts/time/eomday.m
new file mode 100644
index 0000000..a7a879c
--- /dev/null
+++ b/scripts/time/eomday.m
@@ -0,0 +1,57 @@
+## Copyright (C) 2004, 2006, 2007, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{e} =} eomday (@var{y}, @var{m})
+## Return the last day of the month @var{m} for the year @var{y}.
+## @seealso{datenum, datevec, weekday}
+## @end deftypefn
+
+## Author: pkienzle <pkienzle at users.sf.net>
+## Created: 25 July 2004
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function e = eomday (y, m)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  eom = [31, 28, 31, 30 ,31, 30, 31, 31, 30, 31, 30, 31];
+  e = reshape (eom(m), size (m));
+  e += (m == 2) & (mod (y, 4) == 0 & (mod (y, 100) != 0 | mod (y, 400) == 0));
+
+endfunction
+
+# tests
+%!assert(eomday([-4:4],2),[29,28,28,28,29,28,28,28,29])
+%!assert(eomday([-901,901],2),[28,28])
+%!assert(eomday([-100,100],2),[28,28])
+%!assert(eomday([-900,900],2),[28,28])
+%!assert(eomday([-400,400],2),[29,29])
+%!assert(eomday([-800,800],2),[29,29])
+%!assert(eomday(2001,1:12),[31,28,31,30,31,30,31,31,30,31,30,31])
+%!assert(eomday(1:3,1:3),[31,28,31])
+%!assert(eomday(1:2000,2)',datevec(datenum(1:2000,3,0))(:,3))
+%!assert([1900:1999](find(eomday(1900:1999,2*ones(1,100))==29)),[1904,1908,1912,1916,1920,1924,1928,1932,1936,1940,1944,1948,1952,1956,1960,1964,1968,1972,1976,1980,1984,1988,1992,1996])
+%!assert(eomday([2004;2005], [2;2]), [29;28])
+# demos
+%!demo
+%! y = 1900:1999;
+%! e = eomday (y, 2 * ones (1, 100));
+%! y (find (e == 29))
diff --git a/scripts/time/etime.m b/scripts/time/etime.m
new file mode 100644
index 0000000..f867e7a
--- /dev/null
+++ b/scripts/time/etime.m
@@ -0,0 +1,75 @@
+## Copyright (C) 1996, 1997, 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} etime (@var{t1}, @var{t2})
+## Return the difference (in seconds) between two time values returned from
+## @code{clock}.  For example:
+##
+## @example
+## @group
+## t0 = clock ();
+## # many computations later at dots{}
+## elapsed_time = etime (clock (), t0);
+## @end group
+## @end example
+##
+## @noindent
+## will set the variable @code{elapsed_time} to the number of seconds since
+## the variable @code{t0} was set.
+## @seealso{tic, toc, clock, cputime}
+## @end deftypefn
+
+## Author: jwe
+
+function secs = etime (t1, t0)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  [d1, s1] = datenum (t1);
+  [d0, s0] = datenum (t0);
+
+  secs = s1 - s0;
+
+endfunction
+
+%!assert(etime([1900,12,31,23,59,59],[1901,1,1,0,0,0]),-1)
+%!assert(etime([1900,2,28,23,59,59],[1900,3,1,0,0,0]),-1)
+%!assert(etime([2000,2,28,23,59,59],[2000,3,1,0,0,0]),-86401)
+%!assert(etime([1996,2,28,23,59,59],[1996,3,1,0,0,0]),-86401)
+%!test
+%!  t1 = [1900,12,31,23,59,59; 1900,2,28,23,59,59];
+%!  t2 = [1901,1,1,0,0,0; 1900,3,1,0,0,0];
+%!  assert(etime(t2, t1), [1;1]);
+
+%!test
+%! t1 = [1993, 8, 20, 4, 56, 1];
+%! t2 = [1993, 8, 21, 4, 56, 1];
+%! t3 = [1993, 8, 20, 5, 56, 1];
+%! t4 = [1993, 8, 20, 4, 57, 1];
+%! t5 = [1993, 8, 20, 4, 56, 14];
+%! 
+%! assert((etime (t2, t1) == 86400 && etime (t3, t1) == 3600
+%! && etime (t4, t1) == 60 && etime (t5, t1) == 13));
+
+%!error etime ();
+
+%!error etime (1, 2, 3);
+
diff --git a/scripts/time/is_leap_year.m b/scripts/time/is_leap_year.m
new file mode 100644
index 0000000..46ee6c4
--- /dev/null
+++ b/scripts/time/is_leap_year.m
@@ -0,0 +1,56 @@
+## Copyright (C) 1996, 1997, 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} is_leap_year (@var{year})
+## Return 1 if the given year is a leap year and 0 otherwise.  If no
+## arguments are provided, @code{is_leap_year} will use the current year.
+## For example,
+##
+## @example
+## @group
+## is_leap_year (2000)
+##      @result{} 1
+## @end group
+## @end example
+## @end deftypefn
+
+## Author: jwe
+
+function retval = is_leap_year (year)
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  if (nargin == 0)
+    t = clock ();
+    year = t (1);
+  endif
+
+  retval = ((rem (year, 4) == 0 & rem (year, 100) != 0) ...
+            | rem (year, 400) == 0);
+
+endfunction
+
+%!assert((is_leap_year (2000) == 1 && is_leap_year (1976) == 1
+%! && is_leap_year (1000) == 0 && is_leap_year (1800) == 0
+%! && is_leap_year (1600) == 1));
+
+%!error is_leap_year (1, 2);
+
diff --git a/scripts/time/now.m b/scripts/time/now.m
new file mode 100644
index 0000000..afec653
--- /dev/null
+++ b/scripts/time/now.m
@@ -0,0 +1,52 @@
+## Copyright (C) 2000, 2001, 2003, 2005, 2006, 2007 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {t =} now ()
+## Returns the current local time as the number of days since Jan 1, 0000.
+## By this reckoning, Jan 1, 1970 is day number 719529.
+##
+## The integral part, @code{floor (now)} corresponds to 00:00:00 today.
+##
+## The fractional part, @code{rem (now, 1)} corresponds to the current
+## time on Jan 1, 0000.
+##
+## The returned value is also called a "serial date number"
+## (see @code{datenum}).
+## @seealso{clock, date, datenum}
+## @end deftypefn
+
+## Author: pkienzle <pkienzle at users.sf.net>
+## Created: 10 October 2001 (CVS)
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function t = now ()
+
+  t = datenum (clock ());
+
+  ## The following doesn't work (e.g., one hour off on 2005-10-04):
+  ##
+  ##   seconds since 1970-1-1 corrected by seconds from GMT to local time
+  ##   divided by 86400 sec/day plus day num for 1970-1-1
+  ##   t = (time - mktime(gmtime(0)))/86400 + 719529;
+  ##
+  ## mktime(gmtime(0)) does indeed return the offset from Greenwich to the
+  ## local time zone, but we need to account for daylight savings time
+  ## changing by an hour the offset from CUT for part of the year.
+
+endfunction
diff --git a/scripts/time/weekday.m b/scripts/time/weekday.m
new file mode 100644
index 0000000..7994e2f
--- /dev/null
+++ b/scripts/time/weekday.m
@@ -0,0 +1,104 @@
+## Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008 Paul Kienzle
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{n}, @var{s}] =} weekday (@var{d}, [@var{form}])
+## Return the day of week as a number in @var{n} and a string in @var{s},
+## for example @code{[1, "Sun"]}, @code{[2, "Mon"]}, @dots{}, or
+## @code{[7, "Sat"]}.
+##
+## @var{d} is a serial date number or a date string.
+##
+## If the string @var{form} is given and is @code{"long"}, @var{s} will
+## contain the full name of the weekday; otherwise (or if @var{form} is
+## @code{"short"}), @var{s} will contain the abbreviated name of the weekday.
+## @seealso{datenum, datevec, eomday}
+## @end deftypefn
+
+## Author: pkienzle <pkienzle at users.sf.net>
+## Created: 10 October 2001 (CVS)
+## Adapted-By: William Poetra Yoga Hadisoeseno <williampoetra at gmail.com>
+
+function [d, s] = weekday (d, form)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin < 2)
+    form = "short";
+  endif
+
+  if (iscell (d) || isnumeric (d))
+    endsize = size (d);
+  elseif (ischar (d))
+    endsize = [size(d, 1), 1];
+  endif
+  if (ischar (d) || iscell (d))
+    ## Make sure the date is numeric
+    d = datenum (d);
+  endif
+  ## Find the offset from a known Sunday (2008-Jan-6), mod 7.
+  d = floor (reshape (mod(d - 733048, 7), endsize));
+  ## Make Saturdays a 7 and not a 0.
+  d(!d) = 7;
+
+  if (nargout > 1)
+    if (strcmpi (form, "long"))
+      names = {"Sunday" "Monday" "Tuesday" "Wednesday" "Thursday"
+	       "Friday" "Saturday"};
+    else
+      names = {"Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"};
+    endif
+    s = strvcat (names(d));
+  endif
+
+endfunction
+
+# tests
+%!assert(weekday(728647),2)
+## Test vector inputs for both directions
+%!assert(weekday([728647 728648]), [2 3])
+%!assert(weekday([728647;728648]), [2;3])
+## Test a full week before our reference day
+%!assert(weekday('19-Dec-1994'),2)
+%!assert(weekday('20-Dec-1994'),3)
+%!assert(weekday('21-Dec-1994'),4)
+%!assert(weekday('22-Dec-1994'),5)
+%!assert(weekday('23-Dec-1994'),6)
+%!assert(weekday('24-Dec-1994'),7)
+%!assert(weekday('25-Dec-1994'),1)
+## Test our reference day
+%!assert(weekday('6-Jan-2008'),1)
+## Test a full week after our reference day
+%!assert(weekday('1-Feb-2008'),6)
+%!assert(weekday('2-Feb-2008'),7)
+%!assert(weekday('3-Feb-2008'),1)
+%!assert(weekday('4-Feb-2008'),2)
+%!assert(weekday('5-Feb-2008'),3)
+%!assert(weekday('6-Feb-2008'),4)
+%!assert(weekday('7-Feb-2008'),5)
+## Test fractional dates
+%!assert(weekday(728647.1),2)
+# demos
+%!demo
+%! [n, s] = weekday (now ())
+%!demo
+%! [n, s] = weekday (728647)
+%!demo
+%! [n, s] = weekday ('19-Dec-1994')
diff --git a/src/Cell.cc b/src/Cell.cc
new file mode 100644
index 0000000..f7bac71
--- /dev/null
+++ b/src/Cell.cc
@@ -0,0 +1,292 @@
+/*
+
+Copyright (C) 1999, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "idx-vector.h"
+
+#include "Cell.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+
+Cell::Cell (const octave_value_list& ovl)
+  : ArrayN<octave_value> (ovl.cell_value ())
+{
+}
+
+Cell::Cell (const string_vector& sv, bool trim)
+  : ArrayN<octave_value> ()
+{
+  octave_idx_type n = sv.length ();
+
+  if (n > 0)
+    {
+      resize (dim_vector (n, 1));
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  std::string s = sv[i];
+
+	  if (trim)
+	    {
+	      size_t pos = s.find_last_not_of (' ');
+
+	      s = (pos == std::string::npos) ? "" : s.substr (0, pos+1);
+	    }
+
+	  elem(i,0) = s;
+	}
+    }
+}
+
+Cell::Cell (const Array<std::string>& sa)
+  : ArrayN<octave_value> (sa.dims ())
+{
+  octave_idx_type n = sa.numel ();
+
+  octave_value *dst = fortran_vec ();
+  const std::string *src = sa.data ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    dst[i] = src[i];
+}
+
+// Set size to DV, filling with [].  Then fill with as many elements of
+// SV as possible.
+
+Cell::Cell (const dim_vector& dv, const string_vector& sv, bool trim)
+  : ArrayN<octave_value> (dv, resize_fill_value ())
+{
+  octave_idx_type n = sv.length ();
+
+  if (n > 0)
+    {
+      octave_idx_type m = numel ();
+
+      octave_idx_type len = n > m ? m : n;
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  std::string s = sv[i];
+
+	  if (trim)
+	    {
+	      size_t pos = s.find_last_not_of (' ');
+
+	      s = (pos == std::string::npos) ? "" : s.substr (0, pos+1);
+	    }
+
+	  elem(i) = s;
+	}
+    }
+}
+
+bool
+Cell::is_cellstr (void) const
+{
+  bool retval = true;
+
+  for (int i = 0; i < numel (); i++)
+    {
+      if (! elem(i).is_string ())
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+Cell
+Cell::index (const octave_value_list& idx_arg, bool resize_ok) const
+{
+  Cell retval;
+
+  octave_idx_type n = idx_arg.length ();
+
+  switch (n)
+    {
+    case 0:
+      retval = *this;
+      break;
+
+    case 1:
+      {
+	idx_vector i = idx_arg(0).index_vector ();
+
+	if (! error_state)
+	  retval = ArrayN<octave_value>::index (i, resize_ok, resize_fill_value ());
+      }
+      break;
+
+    case 2:
+      {
+	idx_vector i = idx_arg(0).index_vector ();
+
+	if (! error_state)
+	  {
+	    idx_vector j = idx_arg(1).index_vector ();
+
+	    if (! error_state)
+	      retval = ArrayN<octave_value>::index (i, j, resize_ok,
+                                                    resize_fill_value ());
+	  }
+      }
+      break;
+
+    default:
+      {
+	Array<idx_vector> iv (n);
+
+	for (octave_idx_type i = 0; i < n; i++)
+	  {
+	    iv(i) = idx_arg(i).index_vector ();
+
+	    if (error_state)
+	      break;
+	  }
+
+	if (!error_state)
+	  retval = ArrayN<octave_value>::index (iv, resize_ok,
+                                                resize_fill_value ());
+      }
+      break;
+    }
+
+  return retval;
+}
+
+Cell&
+Cell::assign (const octave_value_list& idx_arg, const Cell& rhs,
+	      const octave_value& fill_val)
+
+{
+  octave_idx_type len = idx_arg.length ();
+
+  Array<idx_vector> ra_idx (len);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    ra_idx(i) = idx_arg(i).index_vector ();
+
+  Array<octave_value>::assign (ra_idx, rhs, fill_val);
+
+  return *this;
+}
+
+Cell&
+Cell::delete_elements (const octave_value_list& idx_arg)
+
+{
+  octave_idx_type len = idx_arg.length ();
+
+  Array<idx_vector> ra_idx (len);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    ra_idx.xelem (i) = idx_arg(i).index_vector ();
+
+  Array<octave_value>::delete_elements (ra_idx);
+
+  return *this;
+}
+
+octave_idx_type
+Cell::nnz (void) const
+{
+  gripe_wrong_type_arg ("nnz", "cell array");
+  return -1;
+}
+
+Cell
+Cell::column (octave_idx_type i) const
+{
+  Cell retval;
+
+  if (ndims () < 3)
+    {
+      if (i < 0 || i >= cols ())
+	error ("invalid column selection");
+      else
+	{
+	  octave_idx_type nr = rows ();
+
+	  retval.resize (dim_vector (nr, 1));
+
+	  for (octave_idx_type j = 0; j < nr; j++)
+	    retval.xelem (j) = elem (j, i);
+	}
+    }
+  else
+    error ("Cell::column: requires 2-d cell array");
+
+  return retval;
+}
+
+Cell
+Cell::concat (const Cell& rb, const Array<octave_idx_type>& ra_idx)
+{
+  return insert (rb, ra_idx);
+}
+
+Cell&
+Cell::insert (const Cell& a, octave_idx_type r, octave_idx_type c)
+{
+  Array<octave_value>::insert (a, r, c);
+  return *this;
+}
+
+Cell&
+Cell::insert (const Cell& a, const Array<octave_idx_type>& ra_idx)
+{
+  Array<octave_value>::insert (a, ra_idx);
+  return *this;
+}
+
+Cell
+Cell::map (ctype_mapper fcn) const
+{
+  Cell retval (dims ());
+  octave_value *r = retval.fortran_vec ();
+
+  const octave_value *p = data ();
+
+  for (octave_idx_type i = 0; i < numel (); i++)
+    r[i] = ((p++)->*fcn) ();
+
+  return retval;
+}
+
+Cell
+Cell::diag (octave_idx_type k) const
+{
+  return ArrayN<octave_value>::diag (k);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/Cell.h b/src/Cell.h
new file mode 100644
index 0000000..aa376f3
--- /dev/null
+++ b/src/Cell.h
@@ -0,0 +1,139 @@
+/*
+
+Copyright (C) 1999, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (Cell_h)
+#define Cell_h 1
+
+#include <string>
+
+#include "ArrayN.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+#include "ov.h"
+
+class octave_value_list;
+
+class
+OCTINTERP_API
+Cell : public ArrayN<octave_value>
+{
+public:
+
+  Cell (void)
+    : ArrayN<octave_value> (dim_vector (0, 0)) { }
+
+  Cell (const octave_value& val)
+    : ArrayN<octave_value> (dim_vector (1, 1), val) { }
+
+  Cell (const octave_value_list& ovl);
+
+  Cell (octave_idx_type n, octave_idx_type m,
+	const octave_value& val = resize_fill_value ())
+    : ArrayN<octave_value> (dim_vector (n, m), val) { }
+
+  Cell (const dim_vector& dv, const octave_value& val = resize_fill_value ())
+    : ArrayN<octave_value> (dv, val) { }
+
+  Cell (const ArrayN<octave_value>& c)
+    : ArrayN<octave_value> (c) { }
+
+  Cell (const Array<octave_value>& c)
+    : ArrayN<octave_value> (c) { }
+
+  Cell (const Array<octave_value>& c, octave_idx_type nr, octave_idx_type nc)
+    : ArrayN<octave_value> (c, dim_vector (nr, nc)) { }
+
+  Cell (const string_vector& sv, bool trim = false);
+
+  Cell (const Array<std::string>& sa);
+
+  Cell (const dim_vector& dv, const string_vector& sv, bool trim = false);
+
+  Cell (const Cell& c)
+    : ArrayN<octave_value> (c) { }
+
+  bool is_cellstr (void) const;
+
+  Cell index (const octave_value_list& idx, bool resize_ok = false) const;
+
+  Cell& delete_elements (const octave_value_list& idx);
+
+  Cell& assign (const octave_value_list& idx, const Cell& rhs,
+		const octave_value& fill_val = resize_fill_value ());
+
+  Cell reshape (const dim_vector& new_dims) const
+    { return ArrayN<octave_value>::reshape (new_dims); }
+
+  octave_idx_type nnz (void) const;
+
+  Cell column (octave_idx_type i) const;
+
+  // FIXME
+  boolMatrix all (int /* dim */ = 0) const { return boolMatrix (); }
+
+  // FIXME
+  boolMatrix any (int /* dim */ = 0) const { return boolMatrix (); }
+
+  Cell concat (const Cell& rb, const Array<octave_idx_type>& ra_idx);
+
+  Cell& insert (const Cell& a, octave_idx_type r, octave_idx_type c);
+  Cell& insert (const Cell& a, const Array<octave_idx_type>& ra_idx);
+
+  // FIXME
+  bool any_element_is_nan (void) const { return false; }
+  bool is_true (void) const { return false; }
+
+  static octave_value resize_fill_value (void) { return Matrix (); }
+
+  Cell diag (octave_idx_type k = 0) const;
+
+  Cell xisalnum (void) const { return map (&octave_value::xisalnum); }
+  Cell xisalpha (void) const { return map (&octave_value::xisalpha); }
+  Cell xisascii (void) const { return map (&octave_value::xisascii); }
+  Cell xiscntrl (void) const { return map (&octave_value::xiscntrl); }
+  Cell xisdigit (void) const { return map (&octave_value::xisdigit); }
+  Cell xisgraph (void) const { return map (&octave_value::xisgraph); }
+  Cell xislower (void) const { return map (&octave_value::xislower); }
+  Cell xisprint (void) const { return map (&octave_value::xisprint); }
+  Cell xispunct (void) const { return map (&octave_value::xispunct); }
+  Cell xisspace (void) const { return map (&octave_value::xisspace); }
+  Cell xisupper (void) const { return map (&octave_value::xisupper); }
+  Cell xisxdigit (void) const { return map (&octave_value::xisxdigit); }
+  Cell xtoascii (void) const { return map (&octave_value::xtoascii); }
+  Cell xtolower (void) const { return map (&octave_value::xtolower); }
+  Cell xtoupper (void) const { return map (&octave_value::xtoupper); }
+
+private:
+
+  typedef octave_value (octave_value::*ctype_mapper) (void) const;
+
+  Cell map (ctype_mapper) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ChangeLog b/src/ChangeLog
new file mode 100644
index 0000000..da199c5
--- /dev/null
+++ b/src/ChangeLog
@@ -0,0 +1,30980 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+2009-10-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* variables.cc (extract_function): Pass 0 to eval_string to avoid
+	error.
+
+2009-07-23  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (IGNORE_EXCEPTION, SAFE_CALL): New macros.
+	(clean_up_and_exit, do_octave_atexit): Use SAFE_CALL to handle
+	exceptions while preparing to exit.
+
+2009-08-04  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_call_stack::do_goto_frame_relative): Allow
+	NSKIP to be 0.  Set current scope and context.
+	* input.cc (Fkeyboard): Use octave_call_stack::goto_frame_relative
+	to set scope in user code that called the keyboard function.
+
+2009-08-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* input.cc (Fkeyboard): Only call do_keyboard, don't fiddle with
+	stack.
+
+2009-11-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/balance.cc: Fix docs.
+
+2009-11-03  David Grundberg  <davidg at cs.umu.se>
+
+	* ov-class.cc (make_idx_args): Call user-defined subsref/subsasgn
+	with 1xN structs instead of Nx1.
+
+2009-09-30  John W. Eaton  <jwe at octave.org>
+
+	* error.cc (error_1, pr_where_2, handle_message):
+	Don't do anything if fmt is empty.
+	(Ferror): Call print_usage if nargin == 0.
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+2009-09-08  Rafael Laboissiere  <rafael at debian.org>
+
+	* pr-output.cc: New test.
+
+2009-09-03  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (set_format (const Complex&, int&, int&)):
+	Avoid passing NaN or Inf to log10.
+
+2008-09-01  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/eig.cc (Feigs): Correct nesting error in option
+	parsing that prevented the use of a function for generalized
+	eigenvalue problems.
+
+2009-09-01  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-class.cc (get_current_method_class): Check before slicing.
+
+2009-08-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (Ffmod): Reverse order of args.
+
+2009-08-26  Rob Mahurin  <rob at utk.edu>
+
+	* syscalls.cc: Recommend waitpid() in popen2() documentation.
+	
+2009-08-25  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (gnuplot_backend::send_quit): Wait for gnuplot process.
+
+2009-08-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (Fissorted, F__sort_rows_idx__, Fnorm): Mark as Built-in
+	Functions in the inline help.
+
+2009-08-10  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/dlmread.cc (Fdlmread): Perform tilde expansion on
+	filename argument.
+
+2009-06-11  John W. Eaton  <jwe at octave.org>
+
+	* display.h (display_info::no_window_system): New static function.
+	(display_info::display_info, display_info::init,
+	display_info::instance_ok): New argument, QUERY.
+	(display_info::init): Skip query if QUERY is false.
+
+	* octave.cc (long_opts, octave_main): Handle --no-window-system option.
+	(NO_WINDOW_SYSTEM_OPTION): New defined value.
+	(usage_string, verbose_usage): Mention --no-window-system option.
+
+2009-08-09  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (Fevalin): Also return output from CATCH expression.
+
+2009-08-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* OPERATORS/op-dm-template.cc, OPERATORS/op-pm-template.cc:
+	Also define conversions for null string and null sq_string.
+
+2009-08-06  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-cdm-m.cc, OPERATORS/op-dm-m.cc, OPERATORS/op-pm-m.cc:
+	Define LDMATRIX and DEFINENULLASSIGNCONV.
+	* OPERATORS/op-dm-template.cc, OPERATORS/op-pm-template.cc:
+	Include ov-null-mat.h and define assignment conversion for null
+	matrices if DEFINENULLASSIGNCONV is defined.  Define OCTAVE_LDMATRIX.
+
+2009-08-05  John W. Eaton  <jwe at octave.org>
+
+	* pt-eval.cc (tree_evaluator::visit_complex_for_command):
+	Use key_list order for iterating through map.
+
+2009-08-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-idx.cc (tree_index_expression::lvalue): Implant code from
+	development version.
+	(get_numel): New assistant function.
+
+2009-07-29  John W. Eaton  <jwe at octave.org>
+
+	* ov-float.cc, ov-flt-re-mat.cc, ov-re-mat.cc, ov-re-sparse.cc,
+	ov-scalar.cc: Use complex function for acos mapper if arg is out
+	of range [-1, 1].
+
+2009-07-29  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (param_list_end): Also set
+	lexer_flags.looking_for_object_index to false.
+
+2009-07-24  John W. Eaton  <jwe at octave.org>
+
+	* pt-mat.cc (DO_SINGLE_TYPE_CONCAT_NO_MUTATE): New macro.
+	(tree_matrix::rvalue1): Use it to avoid complex -> real conversion.
+
+2009-07-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/chol.cc (Fcholupdate,
+	Fcholinsert, Fcholdelete, Fcholshift): Replace is_matrix_type ->
+	is_numeric_type.
+
+2009-07-20  Aleksej Saushev  <asau at inbox.ru>
+
+	* sysdep.cc: Also define BSD_init if __NetBSD__ is defined.
+	(sysdep_init): Also call BSD_init if __NetBSD__ is defined.
+
+2009-07-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* bitfcns.cc (DO_UBITSHIFT): Avoid overflow.
+	(DO_SBITSHIFT): Fix mask calculation. 
+
+2009-07-17  Benjamin Lindner <lindnerb at users.sourceforge.net>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (F__magick_read__):
+	Determine correct number of bits required when reading images.
+
+2009-07-16  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (get_array_limits): Require min_pos value to be
+	greater than zero.
+
+2009-07-08  John W. Eaton  <jwe at octave.org>
+
+	* pt-assign.cc (maybe_warn_former_built_in_variable): Improve message.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-07-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-eval.cc (do_unwind_protect_cleanup_code): Add missing
+	unwind_protect::run.
+
+2009-07-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* help.cc (do_which): Also look for files.
+
+2009-07-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Cell.cc (Cell::index): Use proper resize_fill_value.
+
+2008-07-01  David Bateman  <dbateman at free.fr>
+	
+	* pr-output.cc (static inline std::string rational_approx (double, 
+	int)): Test for underflow of fractional part of rational approximation
+	earlier in the loop.
+
+2009-07-01  Joe Rothweiler <octaveuser at sensicomm.com>
+
+	* input.cc (raw_mode): Use TCSADRAIN if no wait.
+
+2009-06-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* symtab.h (force_variable): Remove assertion.
+
+2009-06-26  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (Faddpath): Preserve order of prepended elements.
+
+2009-06-24  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* oct-map.cc (Octave_map::squeeze, Octave_map::permute,
+	Octave_map::transpose, Octave_map::reshape, Octave_map::concat,
+	Octave_map::index): Add tests for preservation of key order in
+	struct arrays.
+
+2009-06-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-mat.cc (get_concat_class): Use empty string as zero value.
+	(tm_row_const_rep::tm_row_const_rep): Initialize class_nm to empty
+	string.
+	(tm_const::tm_const): Ditto.
+
+2009-06-24  John W. Eaton  <jwe at octave.org>
+
+	* pt-assign.cc (former_built_in_variables): Remove "ans" from the list.
+
+2009-06-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-eval.cc (do_unwind_protect_cleanup_code):
+	Workaround sig_atomic_t != int.
+
+2009-06-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* quit.h (octave_quit_exception): Delete.
+	(exit_status, quitting_gracefully): New globals.
+	* quit.cc: Initialize them.
+	(Fquit): Set the globals, simulate interrupt.
+	(main_loop): Handle exit properly.
+	* octave.cc (execute_eval_option_code): Ditto.
+	(execute_command_line_file): Ditto.
+	* pt-eval.cc (do_unwind_protect_cleanup_code):
+	Fix order of unwind_protect calls.
+
+2009-06-23  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.cc (Octave_map::squeeze, Octave_map::permute,
+	Octave_map::transpose, Octave_map::reshape, Octave_map::concat):
+	Preserve key order.
+
+2009-06-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.cc (octave_cell::all_strings): Avoid duplicate conversions.
+
+2009-06-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.cc (Fsubsasgn): Uniquify shared value before assigning to it.
+
+2009-06-17  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_octave_value::get_data):
+	If octave_value::mex_get_data returns a valid pointer, mark it as
+	foreign and return it instead of enumerating the types that can be
+	handled directly.
+
+	* ov-re-mat.h (octave_matrix::mex_get_data): New function.
+	* ov-bool-mat.h (octave_bool_matrix::mex_get_data): Ditto.
+	* ov-flt-re-mat.h (octave_float_matrix::mex_get_data): Ditto.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::mex_get_data): Ditto.
+	* ov-base-mat.h (octave_base_matrix::mex_get_data): Delete.
+
+2009-06-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* symtab.h (symbol_table::set_scope_and_context): Avoid checking
+	error_state for setting context.
+
+2009-06-12  Kai NODA  <nodakai at gmail.com>
+
+	* ls-mat4.h: Fix include guard
+	* ov-type-conv.h: Add missing include guard.
+
+2009-06-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.cc (octave_cell::sort (Array<octave_idx_type>&)): Simplify.
+
+2009-06-10  John W. Eaton  <jwe at octave.org>
+
+	* pt-fcn-handle.cc (tree_anon_fcn_handle::dup): Don't convert to
+	tree_constant object here.  Do inherit from current symbol table
+	scope and context.  New test.
+
+	* lex.l	(handle_identifier): Set lexer_flags.looking_for_object_index
+	false if identifier is a keyword.
+	({IDENT}{S}*): Don't set lexer_flags.looking_for_object_index here.
+
+2009-06-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* octave.cc (octave_main): Call initialize_command_input
+	conditionally. Move line_editing update in front of it.
+	Call command_editor::force_default_editor if not line_editing.
+
+2009-06-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (Flog2): Fix tests.
+
+2009-06-08  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_exist): Returnn 1 for function handles and
+	inline function objects.
+
+2009-06-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* symtab.h (symbol_table::do_clear_global,
+	symbol_table::do_clear_global_pattern): Properly erase from both local
+	and global table.
+
+2009-06-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* variables.cc (Fclear): Clear also globals when called without
+	arguments.
+
+2009-06-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* graphics.cc (color_property::do_set): Allow a wider range of types.
+
+2009-06-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/find.cc (Ffind): Fix docs. Improve second argument
+	handling. Add regression tests.
+
+2009-06-06  Rik  <rdrider0-list at yahoo.com>
+
+	* data.cc: Update documentation for 'complex' function
+
+2009-06-06  Rik  <rdrider0-list at yahoo.com>
+
+	* load-save.cc: Update documentation for NA and isna functions
+
+2009-06-06  Rik  <rdrider0-list at yahoo.com>
+
+	* load-save.cc: Update documentation for load and save
+
+2009-06-06  Rik  <rdrider0-list at yahoo.com>
+
+	* pr-output.cc: Update documentation for 'format'
+
+2009-06-05  Rik  <rdrider0-list at yahoo.com>
+
+	* variables.cc: Update documentation for 'who' family of functions
+
+2009-06-03  Rik  <rdrider0-list at yahoo.com>
+
+	* input.cc: Correct documentation for keyboard function
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-06-02  Rob Mahurin  <rob at utk.edu>
+
+	* Makefile.in: Add CARBON_LIBS to OCTINTERP_LINK_DEPS.
+	From Bernard Desgraups <bdesgraupes at orange.fr>.
+	
+2009-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base.cc (octave_base_value::numeric_assign): Gripe when no index
+	given.
+	* ov-cell.cc (octave_cell::subsasgn): Ditto.
+	* ov-struct.cc (octave_struct::subsasgn): Ditto.
+	* ov-list.cc (octave_list::subsasgn): Ditto.
+
+2009-05-28  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_files): Avoid shadow warning from GCC.
+
+2009-05-27  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (write_image):
+	Bail out if given indexed image.
+
+2009-05-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (encode_map): Fix RGB color
+	construction.
+
+2009-05-26  John W. Eaton  <jwe at octave.org>
+
+	* load-path.h, load-path.cc (load_path::files, load_path::do_files): 
+	New arg, OMIT_EXTS.
+	* help.cc (F__list_functions__): Call load_path::files with
+	omit_exts set to true.
+
+	* symtab.h
+	(symbol_table::symbol_record::symbol_record_rep::is_variable):
+	Use "! is_local ()" instead of storage_class != local.
+	(symbol_table::do_variable_names): Only add variables to the list.
+	(symbol_table::unmark_forced_variables): New static function
+	* variables.cc (do_who): Use is_variable instead of is_defined.
+	Also limit output to variables when using regexp pattern.
+	* octave.cc (unmark_forced_vars): Delete.
+	(execute_eval_option_code): Don't add unmark_forced_vars to 
+	unwind_protect stack here.
+	* toplev.cc (main_loop): Add symbol_table::unmark_forced_variables
+	to the unwind_protect stack here.
+	* input.cc (get_debug_input): Likewise.
+	* parse.y (parse_fcn_file, eval_string): Likewise.
+
+2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* toplev.h (quit_allowed): New global variable.
+	* toplev.cc (quit_allowed): Declare it.
+	(Fquit): Raise error if quitting is not allowed.
+	* octave.cc (octave_main): if running as embedded, disable quit by
+	default.
+
+2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* variables.cc (do_who): Only output symbols with a defined value.
+
+2009-05-22  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* toplev.h (main_loop): Tag with OCTINTERP_API.
+	* input.h (octave_read, get_input_from_file, get_input_from_stdin):
+	Ditto.
+	* lex.h (create_buffer, current_buffer, switch_to_buffer,
+	delete_buffer, restore_input_buffer, delete_input_buffer): Ditto.
+
+2009-05-22  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* ov-class.h, ov-class.cc (octave_class::clear_exemplar_map):
+	New function.
+	* symtab.h (symbol_record::clear_objects,
+	symbol_record::do_clear_objects): New functions.
+	* variables.cc (do_matlab_compatible_clear, clear):
+	Handle -classes option.
+
+2009-05-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* src/ov-base-mat.cc (octave_base_matrix<MT>::assign (const
+	octave_value_list, typename MT::element_type)): Avoid out of bounds
+	assignments.
+
+2009-05-21  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.cc (figure::properties::get_boundingbox,
+	figure::properties::set_boundingbox): Get screen size from root
+	object.
+	(convert_position): Get screen resolution from root object and remove
+	unneeded "backend" argument.
+	(axes::properties::get_boundingbox,
+	figure::properties::get_boundingbox,
+	figure::properties::set_boundingbox): Remove unneeded backend argument
+	to convert_position call.
+
+	* debug.h (class bp_table): Tag with OCTINTERP_API.
+	* input.h (Vdebugging): Ditto.
+	* pt-eval.h (class tree_evaluator): Ditto.
+	* toplev.h (class octave_call_stack): Ditto.
+
+	* file-io.cc (mkstemp): Add mktemp-based implementation of mkstemp on
+	platforms that do not have it (mkstemp is required by the new help
+	system).
+
+	* TEMPLATE-INST/Array-os.cc: Add "extern template" declaration for
+	Array<octave_idx_type> to avoid implicit instantiation (and duplicate
+	symbols at link-time) [Win32]
+
+2009-05-20  John W. Eaton  <jwe at octave.org>
+
+	* pt-assign.cc (maybe_warn_former_built_in_variable):
+	Set initialized to true when done initializing vars set.
+	From Michael Goffioul  <michael.goffioul at gmail.com>.
+
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-typeinfo.h
+	(octave_value_typeinfo::unary_class_ops,
+	octave_value_typeinfo::unary_ops,
+	octave_value_typeinfo::non_const_unary_ops,
+	octave_value_typeinfo::binary_class_ops,
+	octave_value_typeinfo::binary_ops,
+	octave_value_typeinfo::compound_binary_class_ops,
+	octave_value_typeinfo::compound_binary_ops,
+	octave_value_typeinfo::cat_ops,
+	octave_value_typeinfo::assign_ops,
+	octave_value_typeinfo::assignany_ops,
+	octave_value_typeinfo::pref_assign_conv,
+	octave_value_typeinfo::type_conv_ops,
+	octave_value_typeinfo::widening_ops): Declare as Array<void *>.
+	* ov-typeinfo.cc: Reflect changes.
+
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* toplev.h (octave_exit_func): New typedef.
+	(octave_exit): Change to octave_exit_func.
+	
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* ov-typeinfo.cc: Don't include oct-obj.h.
+
+2009-05-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* toplev.h (octave_quit_exception): New class.
+	(octave_exit): New global variable.
+	* toplev.cc (octave_exit): Initialize to ::exit.
+	(clean_up_and_exit): Call octave_exit if set.
+	(Fquit): Raise octave_quit_exception to quit.
+	(main_loop): Catch octave_quit_exception.
+	* octave.cc (execute_command_line_file): Ditto.
+	(execute_eval_option_code): Ditto.
+
+2009-05-19  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fltk_backend.cc (F__fltk_redraw__): New function.
+	(F__init_fltk__): Call add_input_event_hook with feval to add
+	__fltk_redraw__ to the list of even hook functions to call.
+	Call mlock when initializing.
+	(F__remove_fltk__): Call remove_input_event_hook with feval to
+	remove __fltk_redraw__ from the list of event hook functions.
+	Unlock __init_fltk__ when shutting down.
+
+	* input.cc (Finput_event_hook): Delete.
+	(input_event_hook): Handle set of functions instead of just one.
+	(Fadd_input_event_hook, Fremove_input_event_hook): New functions.
+
+2009-05-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Makefile.in: Add X11_LIBS to OCTINTERP_LINK_DEPS.
+
+2009-05-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* TEMPLATE-INST/Array-tc.cc: Change #include.
+
+2009-05-15  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* ov-class.cc (octave_class::exemplar_info): Fix typo in error message.
+	* ov-class.cc (Fmethods): Methods returns cell array.
+	* ls-mat5.cc (read_mat5_binary_element):
+	Construct exemplar array and ensure inheritance is correct.
+
+2009-05-15  John W. Eaton  <jwe at octave.org>
+
+	* error.cc (Ferror): Handle error struct argument.
+
+	* ls-mat5.cc (save_mat5_binary_element): Avoid multiple calls to
+	contents method.  From David Bateman <dbateman at free.fr>.
+	(save_mat5_element_length): Use const Cell to avoid making copies
+	when indexing.
+
+2009-05-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-stream.cc: Don't instantiate Array2<read_fptr>.
+	(octave_stream::read): Make read_fptr_table a static 2d array.
+	(FILL_TABLE_ROW): Update.
+
+2009-05-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (F__accumarray_sum__): Optimize the constant range case.
+
+2009-05-11  John W. Eaton  <jwe at octave.org>
+
+	* sparse-xdiv.cc (do_rightdiv_sm_dm, do_leftdiv_dm_sm):
+	Avoid apparent MSVC bug with typedef.
+
+	* Makefile.in (install-lib): Remove
+	$(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB_VER), not
+	$(DESTDIR)$(octlibdir)/$(SHLPRE)octinterp.$(SHLEXT_VER).
+
+2009-05-08  Carsten Clark <tantumquantum+gnuoctave at gmail.com>
+
+	* data.cc (Fissorted): Fix typo in documentation entry.
+
+2009-05-07  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* ov-class.h, ov-class.cc (octave_class::reconstruct_exemplar):
+	New function.
+	* ov-class.cc (octave_class::load_binary, octave_class::load_hdf5,
+	octave_class::load_ascii): Construct exemplar table and ensure
+	inheritance is correct.
+        * ov-struct.cc (struct): Return struct from object.
+
+2009-05-07  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (base_graphics_object::set): Undo previous change.
+	(base_properties::set (const caseless_str&, const octave_value&):
+	New virtual function.
+	(base_properties::set (const caseless_str&, const std::string&,
+	const octave_value&)): No longer virtual.
+
+	* toplev.cc (octave_config_info): Remove F2C and F2CFLAGS from the
+	config infor struct.
+	* oct-conf.h.in (OCTAVE_CONF_F2CFLAGS, OCTAVE_CONF_F2C):
+	Delete definitions.
+
+2009-05-07  Marco Atzeri  <marco_atzeri at yahoo.it>
+
+        * Makefile.in: (SHLPRE): Rename from SHLLIBPRE.
+
+2009-05-07  John W. Eaton  <jwe at octave.org>
+
+	* genprops.awk (emit_declarations): Emit decls for static
+	has_property functions.
+	(emit_source): Add class name argument to base_properties::set
+	function.  Pass class name to set_dynamic and
+	base_properties::set.  Emit definitions for has_property
+	functions.
+	* graphics.h.in, graphics.cc
+	(base_properties::set, base_properties::set_dynamic):
+	New argument CNAME.
+	(base_properties::all_dynamic_properties): New static data member.
+	(base_properties::has_dynamic_property): New static function.
+	(base_graphics_object::set): Pass class name to
+	base_properties::set function.
+	(property_list::set): Check for invalid property names.
+
+2009-05-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-re-mat.cc (Fdouble): Fix order of branches.
+
+2009-05-05  John Swensen  <jpswensen at comcast.net>
+
+	* debug.h, debug.cc (breakpoints): Rename from bp_map, use a
+	std::set instead of a std::map object.  Change all uses.
+	(bp_table::do_get_breakpoint_list): Simplify.
+
+2009-05-05  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* ov-class.h, ov-class.cc (octave_class::reconstruct_parents):
+	New function.
+	* ov-class.cc (octave_class::load_binary, octave_class::load_hdf5):
+	Contstruct parent list.
+	(get_current_method_class): Clean up method class extraction.
+
+2009-05-05  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (array_property::validate): Require object to be any
+	numeric type, not necessarily a double precision value.
+
+	* variables.cc (set_internal_variable): Pass NM in call to error.
+
+2009-05-04  Peter O'Gorman  <pogma at thewrittenword.com>
+
+	* utils.cc: Don't define HAVE_C99_VSNPRINTF here.
+
+2009-05-01  John W. Eaton  <jwe at octave.org>
+
+	* error.cc (Vlast_error_file, Vlast_error_name, Vlast_error_line,
+	Vlast_error_column): Delete.
+	(Vlast_error_stack): New static variable.
+	(initialize_last_error_stack): New static function.
+	(verror, Frethrow, Flasterror): Set or use Vlast_error_stack, not
+	Vlast_error_file, etc.
+
+2009-04-27  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (octave_class::dotref): Handle empty parent class.
+	(octave_class::get_current_method_class): Allow result to be empty.
+	(called_from_builtin): New static function.
+	(octave_class::subsref, octave_class::subsasgn): Use it.
+
+2009-04-23  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (Fclass): Check newly constructed classes against
+	the first constructed object of the class.
+
+	* ov-class.h, ov-class.cc (octave_class::exmplar_info): New class.
+	(exemplar_map): New static data member.
+	(exemplar_iterator, exemplar_const_iterator): New typedefs.
+
+	* ov-class.h (octave_class::nparents,
+	octave_class::parent_class_name_list): New functions.
+	* ov.h (octave_base_value::nparents,
+	octave_base_value::parent_class_name_list): New functions.
+	* ov-base.h, ov-base.cc (octave_base_value::nparents,
+	octave_base_value::parent_class_name_list): New functions.
+	(parent_class_names): Error if called for wrong type argument.
+
+	* symtab.cc (load_out_of_date_fcn): New arg, dispatch_type.
+	(out_of_date_check_internal): Pass dispatch type to
+	load_out_of_date_fcn.
+
+2009-04-22  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-int.cc (octave_base_int_helper<T, false,
+	false>::char_value_out_of_range): Correct result for specialization.
+
+	* ov-class.cc (octave_class::dotref, octave_class::subsasgn):
+	Protect against possibly invalid octave_value -> string conversions.
+
+2009-04-22  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* variables.cc (symbol_exist): Also return 1 for objects.
+	* ov-base.h (octave_base_value::assign): New virtual function.
+	* ov-class.h (octave_class::assign): New function.
+	* ov-class.cc (octave_class::find_parent_class): Simplify.
+	(octave_class::octave_class): Don't allow duplicate parent classes.
+	(octave_class::subsasgn): Allow cls = method (cls, value) to work
+	properly when method is a parent-class method.
+	(get_method_class): New static function.
+	(octave_class:subsasgn, octave_class::dotref): Use it.
+	(F__isa_parent__): New function.
+
+2009-04-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-range.cc (octave_range::char_array_value): New virtual function
+	override.
+	* ov-range.h: Declare it.
+
+2009-04-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::do_init_element):
+	Update class name even for all-zeros elements.
+	(get_concat_class): Update the default value if possible.
+
+2009-04-21  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (Fassignin): Add missing unwind_protect frame.
+
+	* toplev.h (push (symbol_table::scope_id, symbol_table::context_id)):
+	New function.
+
+	* toplev.cc (main_loop): Don't call symbol_table::reset_scope.
+
+	* mex.cc (mexGetVariable, mexPutVariable): Use unwind_protect to
+	restore call stack and scope.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Don't use symbol_table::push_scope.
+	* variablees.cc (do_who): Likewise.  Use octave_call_stack and
+	unwind_protect to manage change in scope.
+	* ov-fcn-handle.cc (octave_fcn_handle::load_ascii,
+	octave_fcn_handle::load_binary, octave_fcn_handle::load_hdf5):
+	Likewise.
+	* ls-mat5.cc (read_mat5_binary_element): Likewise.
+
+	* symtab.h (erase_scope (void*)): New function, for unwind_protect.
+	(symbol_table::push_scope, symbol_table::pop_scope,
+	symbol_table::reset_scope): Delete.
+	(symbol_table::scope_stack): Delete static member.
+	* symtab.cc (symbol_table::scope_stack): Delete definition.
+
+2009-04-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-map.h (Octave_map::contents (const_iterator) const,
+	Octave_map::contents (iterator)): Simplify.
+
+2009-04-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-map.cc (Octave_map::assign (const octave_value_list&, const
+	std::string&, const Cell&)): Fix & simplify.
+	(common_size): Remove.
+
+2009-04-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-idx.cc (make_value_list): Gripe on magic end query for undefined
+	variables.
+
+2009-04-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* xpow.cc (same_sign): New helper function.
+	(elem_xpow (double, const Range&), elem_xpow (const Complex&, const Range&)): 
+	Only optimize monotonic-magnitude integer ranges, start always from
+	the smaller end.
+
+2008-04-11  David Bateman  <dbateman at free.fr>
+
+	* ov-cell.cc (Fstruct2cell): Treat possible trailing singleton for
+	creation of cell array from column structure vector.
+
+2009-04-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.cc (octave_cell::subsasgn): Fix reference counting
+	optimization.
+
+2009-04-08  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (rehash_internal): New function.
+	(Frehash): Use it.
+	(Fpath, Faddpath, Frmpath): Call rehash_internal if path is modified.
+
+2009-04-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* xpow.cc (elem_xpow (double, const Range&),
+	elem_xpow (const Complex&, const Range&)): New functions.
+	* xpow.h: Declare them.
+	* OPERATORS/op-range.cc: Define scalar .^ range and complex .^ range &
+	install them.
+
+2009-04-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-struct.cc (octave_struct::subsasgn): Fix reference counting
+	optimization.
+
+2008-04-03  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/max.cc (MINMAX_SPARSE_BODY): Allow sparse boolean 
+	values.
+
+2009-04-01  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-str-mat.cc (default_numeric_conversion_function):
+	Create an octave_scalar if possible.
+
+2009-03-29  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fltk_backend.cc (plot_window::button_press):
+	Don't pass arbitrary input to fl_message as a format string.
+
+2009-03-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-eval.cc (do_unwind_protect_cleanup_code): Protect also
+	octave_interrupt_state.
+
+2009-03-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellslices): Index n-d arrays along the
+	last dimension.
+
+2009-03-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/balance.cc (Fbalance): Fix order of output args.
+
+2009-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/find.cc 
+	(find_nonzero_elem_idx (const Array<T>&, ...)): Move dimensions
+	fixup to liboctave.
+
+2009-03-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/find.cc 
+	(find_nonzero_elem_idx (const Array<T>&, ...)): Simplify.
+	Instantiate for bool and octave_int types.
+	(find_nonzero_elem_idx (const Sparse<T>&, ...)): 
+	Instantiate for bool.
+	(Ffind): Handle bool and octave_int cases.
+
+2009-03-25  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.55+.
+	(OCTAVE_API_VERSION): Now api-v37+.
+
+	* version.h (OCTAVE_VERSION): Now 3.1.55.
+	(OCTAVE_API_VERSION): Now api-v37.
+	(OCTAVE_RELEASE_DATE): Now 2009-03-25.
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx): Also return
+	[](0x0) if the array has 0 rows and it is not a column vector.
+
+	* oct-stream.cc (octave_stream::write (const Array<T>&,
+	octave_idx_type, oct_data_conv::data_type, octave_idx_type,
+	oct_mach_info::float_format)): Seek to skip if still inside bounds
+	of existing file.  Otherwise, write NUL to skip.
+
+	* Makefile.in (%.df : %.cc): Write source file name to output,
+	wrapped in XDEFUN_FILE_NAME macro.
+	* mkbuiltins: Provide definition for XDEFUN_FILE_NAME.
+	* mkgendoc: Likeiwse.
+	(XDEFUN_DLD_INTERNAL, XDEFUNX_DLD_INTERNAL, XDEFUN_INTERNAL,
+	XDEFCONSTFUN_INTERNAL, XDEFUNX_INTERNAL, XDEFVAR_INTERNAL,
+	XDEFCONST_INTERNAL): Pass file_name to print_doc_string.
+	(print_doc_string): New arg, FILE_NAME.  Print file name as
+	comment.
+
+2009-03-24  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (F__parent_classes__): New function.
+
+2009-03-24  Robert T. Short  <octave at phaselockedsystems.com>
+
+	* ov-class.h, ov-class.cc (octave_class::octave_class (const
+	Octave_map&, const std::string&, const octave_value_list&)):
+	New constructor.
+	(octave_class::find_parent_class, octave_class::parent_classes):
+	New functions.
+	(octave_class::dotref): Also look in parent class.
+	(Fclass): Handle parent class arguments.
+
+	* ov-base.h (octave_base_value::get_parent_list,
+	octave_base_value::parent_classes): New virtual functions.
+
+	* load-path.h, load-path.cc (load_path::parent_map): New data member. 
+	(load_path::add_to_parent_map): New static function.
+	(load_path::do_add_to_parent_map): New member function.
+	(load_path::do_find_method): Also look in parent classes for methods.
+	(load_path::parent_map_type, load_path::const_parent_map_iterator,
+	load_path::parent_map_iterator): New typedefs.
+
+2009-03-23  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h
+	(symbol_table::symbol_record::symobl_recoord_rep::is_variable):
+	Also return true if symbol is tagged as a variable.
+	(symbol_table::symbol_record::symobl_recoord_rep::force_variable):
+	Don't set variable value.
+	(symbol_table::symbol_record::symobl_recoord_rep::clear_forced,
+	symbol_table::symbol_record::clear_forced): Delete.
+	(symbol_table::unmark_forced_variables): Rename from
+	symbol_table::clear_forced_variables.
+	(symbol_table::do_unmark_forced_variables): Rename from
+	symbol_table::do_clear_forced_variables.
+	* parse.y (make_script, finish_function): Call
+	symbol_table::unmark_forced_variables instead of
+	symbol_table::clear_forced_variables.
+	* octave.cc (unmark_forced_vars): New function.
+	(execute_eval_option_code): Add it to the unwind-protect stack.
+
+2009-03-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-eval.cc (tree_evaluator::visit_simple_for_command):
+	Remove struct branch, handle structs by the generic code.
+	(tree_evaluator::visit_complex_for_command):
+	Add missing const qualifiers.
+
+2009-03-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-diag.cc: Add missing include.
+	* sparse-xdiv.cc: Ditto.
+	* DLD-FUNCTIONS/__glpk__.cc: Ditto.
+	* DLD-FUNCTIONS/__lin_interpn__.cc: Ditto.
+	* DLD-FUNCTIONS/__voronoi__.cc: Ditto.
+
+2009-03-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-re-mat.cc (octave_matrix::load_ascii): Simplify.
+	* ov-flt-re-mat.cc (octave_float_matrix::load_ascii): Simplify.
+	* ov-cx-mat.cc (octave_complex_matrix::load_ascii): Simplify.
+	* ov-flt-cx-mat.cc (octave_float_complex_matrix::load_ascii): Simplify.
+
+2009-03-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-re-mat.cc (octave_matrix::isnan, octave_matrix::isinf,
+	octave_matrix::finite): Simplify.
+	* ov-flt-re-mat.cc (octave_float_matrix::isnan,
+	octave_float_matrix::isinf, octave_float_matrix::finite): Simplify.
+	* ov-cx-mat.cc (octave_complex_matrix::isnan,
+	octave_complex_matrix::isinf, octave_complex_matrix::finite):
+	Simplify.
+	* ov-flt-cx-mat.cc (octave_float_complex_matrix::isnan,
+	octave_float_complex_matrix::isinf,
+	octave_float_complex_matrix::finite): Simplify.
+
+2009-03-19  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* ls-oct-ascii.cc (extract_keyword): Replace loop with call to
+	read_until_newline to avoid leaving stray '\r' in stream when
+	reading files with CRLF line endings.
+
+2009-03-18  Jaroslav Hajek <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/cellfun.cc
+	(scalar_col_helper, scalar_col_helper_def, scalar_col_helper_nda,
+	scalar_query_helper): New classes.
+	(make_col_helper): New function.
+	(Fcellfun): Use col_helper classes for UniformOutput. Avoid copying by
+	using const variables.
+
+2009-03-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* OPERATORS/op-b-bm.cc: Add missing INSTALL_BINOPs.
+	* OPERATORS/op-bm-b.cc: Ditto.
+	* OPERATORS/op-fm-fm.cc: Ditto.
+	* OPERATORS/op-m-m.cc: Ditto.
+
+2009-03-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.cc (octave_value::octave_value): Move to ov.h
+	* ov.h (octave_value::octave_value): Implement fast inline constructor
+	using a static rep.
+
+2009-03-15  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellslices): New DLD function.
+
+2009-03-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h (octave_value::compound_binary_op): Support bool compound ops.
+	* ov.cc (do_binary_op, decompose_binary_op, binary_op_fcn_name):
+	Ditto.
+	* pt-cbinop.cc (strip_not, simplify_and_or_op): New funcs.
+	(maybe_compound_binary_expression): Support bool compound ops.
+	* OPERATORS/op-int.h: Support bool compound ops.
+	* OPERATORS/op-b-bm.cc: Ditto.
+	* OPERATORS/op-bm-b.cc: Ditto.
+	* OPERATORS/op-bm-bm.cc: Ditto.
+	* OPERATORS/op-fm-fm.cc: Ditto.
+	* OPERATORS/op-m-m.cc: Ditto.
+
+2009-03-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* xpow.cc (xpow (const NDArray&, double), xpow (const ComplexNDArray&, double),
+	xpow (const FloatNDArray&, float), xpow (const FloatComplexNDArray&,
+	float)): Use xisint for testing ints. Optimize w.r.t int exponents.
+
+2009-03-13  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (maybe_warn_assign_as_truth_value, make_binary_op,
+	maybe_warn_variable_switch_label, maybe_warn_associativity_change): 
+	Print file and line number info if available.
+	* lex.l (gripe_matlab_incompatible): Likewise.
+
+	* error.cc (pr_where): Use octave_call_stack::backtrace to print
+	complete stack trace at once.  Don't attempt to print code.
+	(error_2): Set error_state to 0 before calling pr_where.
+	(warning_1): Switch sense of test on symbol_table::at_top_level.
+	Call pr_where after printing primary warning message.
+
+2009-03-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-range.h (octave_range::octave_range (const Range&)): Allow
+	constructing from invalid range op result.
+	* ov-range.cc (octave_range::try_narrowing_conversion): Validate
+	invalid range op results.
+	* data.cc (fill_matrix): Return packed form (zero-step range) if
+	possible.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* DLD-FUNCTIONS/lu.cc (lu): Call fact.Pr_mat () and fact.Pc_mat ()
+	to return permutation matrices in the sparse case.
+
+2009-03-12  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat-ascii.cc (get_mat_data_input_line): If we are looking at
+	'\r' or '\n', skip current line ending instead of skipping until
+	the next.
+
+2009-03-12  Ben Abbott <bpabbott at mac.com>
+
+	* graphics.cc: Fix default "papersize" property value.
+
+2009-03-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-flt-perm.h, ov-flt-perm.cc: Remove sources.
+	* ov.h, ov.cc (octave_value::octave_value (const PermMatrix&)): Remove
+	use "single" argument.
+	* ov.cc (install_types): Update.
+	* xpow.cc, xpow.h (xpow (PermMatrix, float)): Remove.
+	* ov-base-diag.cc (octave_base_diag::do_index_op): Remove permutation
+	creating block.
+	* ov-re-diag.cc (octave_diag_matrix::do_index_op): Move it here.
+	* ov-re-diag.h (octave_diag_matrix::do_index_op): New decl.
+
+	* DLD-FUNCTIONS/det.cc (Fdet): Update.
+	* DLD-FUNCTIONS/inv.cc (Finv): Update.
+	* DLD-FUNCTIONS/pinv.cc (Fpinv): Update.
+
+	* OPERATORS/op-fcm-pm.cc <-- OPERATORS/op-fcm-fpm.cc
+	* OPERATORS/op-fcm-pm.cc: Update.
+	* OPERATORS/op-fm-pm.cc <-- OPERATORS/op-fm-fpm.cc
+	* OPERATORS/op-fm-pm.cc: Update.
+	* OPERATORS/op-pm-fcm.cc <-- OPERATORS/op-fpm-fcm.cc
+	* OPERATORS/op-pm-fcm.cc: Update.
+	* OPERATORS/op-pm-fm.cc <-- OPERATORS/op-fpm-fm.cc
+	* OPERATORS/op-pm-fm.cc: Update.
+	* OPERATORS/op-pm-pm.cc: Update.
+	* OPERATORS/op-pm-template.cc: Update.
+
+2009-03-11  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* xpow.cc (xpow (const PermMatrix&, double), xpow (const PermMatrix&,
+	float)): New functions.
+	* xpow.h: Declare them.
+	* DLD-FUNCTIONS/op-pm-pm.cc: Support permutation matrix ^ scalar.
+	* DLD-FUNCTIONS/op-fpm-fpm.cc: Ditto.
+
+2009-03-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-ch-mat.cc (octave_char_matrix::double_value, 
+	octave_char_matrix::float_value, octave_char_matrix::complex_value,
+	octave_char_matrix::float_complex_value): Cast to unsigned char.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* OPERATORS/op-pm-sm.cc (mul_pm_sm): New Octave binding for
+	perm * sparse.
+	(ldiv_pm_sm): New Octave binding for perm \ sparse.
+	(mul_sm_pm): New Octave binding for sparse * perm.
+	(div_sm_pm): New Octave binding for sparse / perm.
+	(install_pm_sm_ops): Install the above bindings.
+
+	* OPERATORS/op-pm-scm.cc (mul_pm_scm): New Octave binding for
+	perm * sparse complex.
+	(ldiv_pm_scm): New Octave binding for perm \ sparse complex.
+	(mul_scm_pm): New Octave binding for sparse complex * perm.
+	(div_scm_pm): New Octave binding for sparse complex / perm.
+	(install_pm_scm_ops): Install the above bindings.
+
+	* Makefile.in (PERM_OP_XSRC): Add op-pm-sm.cc and op-pm-scm.cc for
+	operations between permutations and sparse matrices.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx): New override
+	for find on PermMatrix.
+	(find): Add a branch testing arg.is_perm_matrix () and calling the
+	above override.
+
+2009-03-10  John W. Eaton  <jwe at octave.org>
+
+	* c-file-ptr-stream.cc, dynamic-ld.cc, error.cc, lex.l, pager.cc,
+	zfstream.cc: Include <iostream>.
+	* zfstream.h: Include <iosfwd> instead of <istream> and <ostream>.
+	* c-file-ptr-stream.h, help.h, load-path.h, load-save.h,
+	ls-ascii-helper.h, oct-iostrm.h, oct-stream.h, ov-base-diag.h,
+	ov-base-int.h, ov-base-mat.h, ov-base-scalar.h, ov-base-sparse.h,
+	ov-base.h, ov-bool-mat.h, ov-bool-sparse.h, ov-bool.h, ov-cell.h,
+	ov-ch-mat.h, ov-class.h, ov-colon.h, ov-complex.h, ov-cs-list.h,
+	ov-cx-mat.h, ov-cx-sparse.h, ov-fcn-handle.h, ov-fcn-inline.h,
+	ov-float.h, ov-flt-complex.h, ov-flt-cx-mat.h, ov-flt-re-mat.h,
+	ov-intx.h, ov-list.h, ov-range.h, ov-re-mat.h, ov-re-sparse.h,
+	ov-scalar.h, ov-str-mat.h, ov-struct.h, ov.h, pager.h,
+	pr-output.h, procstream.h, pt-assign.h, pt-cell.h, pt-const.h,
+	pt-fcn-handle.h, pt-id.h, pt-mat.h, pt.h, utils.h:
+	Include <iosfwd> instead of <iosstream>.
+
+2009-03-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (Fsize_equal): Allow single argument call.
+	* DLD-FUNCTIONS/max.cc (Fcummin, Fcummax): Update docs.
+
+2009-03-09  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* ls-ascii-helper.h, ls-ascii-helper.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	* load-save.cc (Fload): Open all files in binary mode.
+	* ov-range.cc (load_ascii): Explicitly handle CR and CRLF line endings.
+	* ov-fcn-handle.cc (load_ascii): Likewise.
+	* ov-fcn-inline.cc (load_ascii): Likewise.
+	* ov-str-mat.cc (load_ascii): Likewise.
+	* ls-mat-ascii.cc (get_mat_data_input_line): Likewise.
+	* ls-oct-ascii.cc (extract_keyword, read_ascii_data): Likewise.
+	* ls-oct-ascii.h (extract_keyword): Likewise.
+	
+2009-03-09  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (OCTAVE_DEFAULT_FONTNAME): New macro, defaults to "*".
+	(axes::properties, text::properties): Use it to set default fontname.
+	* graphics.cc (axes::properties::set_defaults): Likewise.
+
+2009-03-09  Rafael Laboissiere  <rafael at debian.org>
+
+	* Makefile.in (maintainer-clean): Remove y.tab.h here.
+	(distclean): Not here.
+
+2009-03-09  Jason Riedy  <jason at acm.org>
+
+	* OPERATORS/op-dm-sm.cc (add_dm_sm): Octave binding for diag + sparse.
+	(sub_dm_sm): Octave binding for diag - sparse.
+	(add_sm_dm): Octave binding for diag + sparse.
+	(sub_sm_dm): Octave binding for diag - sparse.
+	(install_dm_sm_ops): Install above bindings.
+
+	* OPERATORS/op-dm-scm.cc (add_cdm_sm): Octave binding for diag + sparse.
+	(add_dm_scm): Octave binding for diag + sparse.
+	(add_cdm_scm): Octave binding for diag + sparse.
+	(sub_cdm_sm): Octave binding for diag - sparse.
+	(sub_dm_scm): Octave binding for diag - sparse.
+	(sub_cdm_csm): Octave binding for diag - sparse.
+	(add_sm_cdm): Octave binding for diag + sparse.
+	(add_scm_dm): Octave binding for diag + sparse.
+	(add_scm_cdm): Octave binding for diag + sparse.
+	(sub_sm_cdm): Octave binding for diag - sparse.
+	(sub_scm_dm): Octave binding for diag - sparse.
+	(sub_scm_cdm): Octave binding for diag - sparse.
+	(install_dm_scm_ops): Install above bindings.
+
+2009-03-08  Jason Riedy  <jason at acm.org>
+
+	* sparse-xdiv.h (xleftdiv): Declare overrides for
+	xleftdiv (diagonal, sparse), both real and complex.
+	(xdiv): Declare overrides for xdiv (sparse, diagonal), both real
+	and complex.
+
+	* sparse-xdiv.cc (do_rightdiv_sm_dm): New template function.
+	Implementation for xdiv (sparse, diagonal).
+	(xdiv): Call do_rightdiv_sm_dm to implement overrides, real and
+	complex.
+	(do_leftdiv_dm_sm): New template function.  Implementation for
+	xleftdiv (diagonal, sparse).
+	(xleftdiv): Call do_leftdiv_dm_sm to implement overrides, real and
+	complex.
+
+	* OPERATORS/op-dm-sm.cc (ldiv_dm_sm): Octave binding for real left
+	division, diagonal into sparse.
+	(div_sm_dm): Octave binding for real right division, sparse by
+	diagonal.
+	(install_dm_sm_ops): Install above bindings.
+
+	* OPERATORS/op-dm-scm.cc (ldiv_dm_scm): Octave binding for real
+	diagonal \ complex sparse.
+	(ldiv_cdm_sm): Octave binding for complex diagonal \ real sparse.
+	(ldiv_cdm_scm): Octave binding for complex diagonal \ complex sparse.
+	(div_scm_dm): Octave binding for complex sparse / real diagonal.
+	(div_sm_cdm): Octave binding for real sparse / complex diagonal.
+	(div_scm_cdm): Octave binding for complex sparse / complex diagonal.
+	(install_dm_scm_ops): Install above bindings.
+
+2009-03-08  Jason Riedy  <jason at acm.org>
+
+	* OPERATORS/op-dm-scm.cc: New file.  Implement multiplication
+	between diagonal matrices (both real and complex) and complex
+	sparse matrices.
+	* OPERATORS/op-dm-sm.cc: New file.  Implement multiplication
+	between diagonal matrices and sparse matrices, all real.
+	* Makefile.in (DIAG_OP_XSRC): Add op-dm-sm.cc and op-dm-scm.cc.
+
+2009-03-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (F__accumarray_sum__): New function.
+	(do_accumarray_sum): New helper template function.
+
+2009-03-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* xdiv.cc (mdm_div_impl, dmm_lelftdiv_impl, dmdm_div_impl,
+	dmdm_leftdiv_impl): Optimize.
+
+2009-03-07  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (octave_print_internal (std::ostream&,
+	const PermMatrix&, bool, int)): Delete unused variable SCALE.
+
+	* utils.cc (octave_vsnprintf): Avoid uninitialized variable
+	warning from GCC.
+
+	* DLD-FUNCTIONS/qz.cc (Fqz): Avoid "maybe clobbered by vfork"
+	warning from GCC.
+
+	* version.h (OCTAVE_VERSION): Now 3.1.54.
+	(OCTAVE_API_VERSION): Now api-v36.
+	(OCTAVE_RELEASE_DATE): Now 2009-03-07.
+
+	* octave.cc (verbose_usage): Include --doc-cache-file in option list.
+
+2009-03-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h (octave_value::diag_matrix_value,
+	octave_value::complex_diag_matrix_value,
+	octave_value::float_diag_matrix_value,
+	octave_value::float_complex_diag_matrix_value,
+	octave_value::perm_matrix_value): New methods.
+
+	* ov-base.cc (octave_base_value::diag_matrix_value,
+	octave_base_value::complex_diag_matrix_value,
+	octave_base_value::float_diag_matrix_value,
+	octave_base_value::float_complex_diag_matrix_value,
+	octave_base_value::perm_matrix_value): New virtual methods.
+	
+	* ov-base.h: Declare them.
+
+	* ov-base-diag.h (octave_base_diag::diag_matrix_value,
+	octave_base_diag::complex_diag_matrix_value,
+	octave_base_diag::float_diag_matrix_value,
+	octave_base_diag::float_complex_diag_matrix_value,
+	octave_base_diag::perm_matrix_value): Remove declarations.
+
+	* DLD-FUNCTIONS/inv.cc (Finv): Simplify handling diag & perm matrices.
+	* DLD-FUNCTIONS/pinv.cc (Fpinv): Ditto.
+	* DLD-FUNCTIONS/det.cc (Fdet): Ditto.
+
+2009-03-05  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* ls-hdf5.cc (add_hdf5_data): Handle diag & perm matrices.
+
+2009-03-05  John W. Eaton  <jwe at octave.org>
+
+	* pt-cell.cc, pt-cell.h (tree_cell::dup): Now const.
+	* comment-list.cc, comment-list.h (octave_comment_list::dup): Ditto.
+	* pt-arg-list.cc, pt-arg-list.h (tree_argument_list::dup): Ditto.
+	* pt-assign.cc, pt-assign.h (tree_simple_assignment::dup,
+	tree_multi_assignment::dup): Ditto.
+	* pt-binop.cc, pt-binop.h (tree_binary_expression::dup,
+	tree_boolean_expression::dup): Ditto.
+	* pt-cmd.cc, pt-cmd.h (tree_no_op_command::dup,
+	tree_function_def::dup): Ditto.
+	* pt-colon.cc, pt-colon.h (tree_colon_expression::dup): Ditto.
+	* pt-const.cc, pt-const.h (tree_constant::dup): Ditto.
+	* pt-decl.cc, pt-decl.h (tree_decl_elt::dup, tree_decl_init_list::dup,
+	tree_global_command::dup, tree_static_command::dup): Ditto.
+	* pt-except.cc, pt-except.h (tree_try_catch_command::dup,
+	tree_unwind_protect_command::dup): Ditto.
+	* pt-fcn-handle.cc, pt-fcn-handle.h (tree_fcn_handle::dup,
+	tree_anon_fcn_handle::dup): Ditto.
+	* pt-id.cc, pt-id.h (tree_identifier::dup): Ditto.
+	* pt-idx.cc, pt-idx.h (tree_index_expression::dup): Ditto.
+	* pt-jump.cc, pt-jump.h (tree_break_command::dup,
+	tree_continue_command::dup, tree_return_command::dup): Ditto.
+	* pt-loop.cc, pt-loop.h (tree_while_command::dup,
+	tree_do_until_command::dup, tree_simple_for_command::dup,
+	tree_complex_for_command::dup): Ditto.
+	* pt-mat.cc, pt-mat.h (tree_matrix::dup): Ditto.
+	* pt-misc.cc, pt-misc.h (tree_parameter_list::dup,
+	tree_return_list::dup): Ditto.
+	* pt-select.cc, pt-select.h (tree_if_clause::dup,
+	tree_if_command_list::dup, tree_if_command::dup,
+	tree_switch_case::dup, tree_switch_case_list::dup,
+	tree_switch_command::dup): Ditto.
+	* pt-stmt.cc, pt-stmt.h (tree_statement::dup,
+	tree_statement_list::dup): Ditto.
+	* pt-unop.cc, pt-unop.h (tree_prefix_expression::dup,
+	tree_postfix_expression::dup): Ditto.
+	* pt-fcn-handle.h (tree_anon_fcn_handle::parameter_list,
+	tree_anon_fcn_handle::return_list, tree_anon_fcn_handle::body,
+	tree_anon_fcn_handle::scope): Ditto.
+
+2009-03-05  Jason Riedy  <jason at acm.org>
+
+	* ov-base-int.cc (convert_to_str_internal): Replace elt_type with
+	element_type throughout.
+
+2009-03-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/sparse.cc (Fsparse): Handle diagonal and permutation
+	matrices.
+
+2009-03-03  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::save_ascii,
+	octave_struct::save_binary, octave_struct::save_hdf5):
+	Preserve order of structure fields.
+	* ls-mat5.cc (save_mat5_binary_element): Likewise.
+
+	* symtab.h (symbol_table::do_inherit): Only inherit values for
+	symbols from the donor_scope that already exist in the table.
+	(symbol_table::symbol_record::symbol_record_rep::dup): Now const.
+	(symbol_table::symbol_record::operator=): Decrement rep->count and
+	maybe delete rep.
+	(symbol_table::fcn_info::operator=): Likewise.
+
+	* pt-fcn-handle.cc: (tree_anon_fcn_handle::dup): Transform
+	tree_anon_fcn_handle objects to tree_constant objects containing
+	octave_fcn_handle objects.  New tests.
+
+	* pt-assign.cc (tree_simple_assignment::rvalue1): Assign result of
+	call to rhs->rvalue1() to an octave_value object, not an
+	octave_value_list object.
+
+2009-03-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-stream.h (octave_stream_list::lookup_cache): New member field.
+	(octave_stream_list::octave_stream_list): Initialize it.
+	(octave_stream_list::do_lookup): Use it.
+	(octave_stream_list::clear): Make flush optional. Do physically erase
+	entries from the map. Close files.
+	(octave_stream_list::do_remove): Call clear on "all". Do erase deleted
+	entry from the map.
+
+2009-03-02  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (Fget, F__get__): Return a column vector of property
+	values, not a row vector.
+
+2009-03-01  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-fcm-fcm.cc (DEFNDASSIGNOP_FN (dbl_assign)):
+	LHS type is float_complex_matrix, not complex_matrix.  RHS value
+	function is float_complex_array, not complex_array.
+
+2009-03-01  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-perm.cc (octave_perm_matrix::print_raw): Call
+	octave_print_internal.
+	(octave_perm_matrix::print_raw): Call print_raw.
+	* pr-output.cc (octave_print_internal (...,const DiagMatrix&,...)):
+	Indicate diagonal matrix.
+	(octave_print_internal (...,const ComplexDiagMatrix&,...)): Ditto.
+	(octave_print_internal (...,const PermMatrix&,...)): New function.
+	* pr-output.h: Declare it.
+
+2009-02-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* OPERATORS/op-dms-template.cc (gripe_if_zero): New template static
+	function.
+	(dmsdiv, sdmldiv): Call it.
+
+2009-02-26  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_table::symbol_record::symbol_record_rep::forced):
+	New static constant.
+	(symbol_table::symbol_record::symbol_record_rep::force_variable,
+	symbol_table::symbol_record::force_variable): New functions.
+	(symbol_table::symbol_record::symbol_record_rep::is_forced,
+	symbol_table::symbol_record::symbol_record_rep::mark_forced,
+	symbol_table::symbol_record::symbol_record_rep::unmark_forced,
+	symbol_table::symbol_record::symbol_record_rep::clear_forced,
+	symbol_table::symbol_record::is_forced,
+	symbol_table::symbol_record::mark_forced,
+	symbol_table::symbol_record::clear_forced,
+	symbol_table::symbol_record::unmark_forced): New fucntions.
+	* lex.h, lex.l (force_local_variable): Delete.
+	(handle_identifier): Call symbol_table::force_variable instead of
+	force_local_variable.
+	* parse.y (make_script): Call symbol_table:clear_forced_variables
+	after defining script.
+	(finish_function): Call symbol_table::clear_forced_variables
+	instead of symbol_table::clear_variables.
+	
+	* DLD-FUNCTIONS/chol.cc: Correct spelling of CHOLMOD in tests.
+
+	* version.h (OCTAVE_VERSION): Now 3.1.53+.
+	(OCTAVE_API_VERSION): Now api-v35+.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.53.
+	(OCTAVE_API_VERSION): Now api-v35.
+	(OCTAVE_RELEASE_DATE): Now 2009-02-25.
+	(OCTAVE_COPYRIGHT): Update year.
+
+	* Makefile.in (distclean): Remove tags TAGS y.tab.h y.output
+	yy.lex.c here, not in maintainer-clean target.  Also remove
+	parse.output.
+
+	* DLD-FUNCTIONS/rand.cc: Note that the tests for the old random
+	number generator will fail if using 64-bit indexing.
+
+2009-02-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/lu.cc (maybe_set_triangular): New function.
+	(Flu): Use it.
+	* DLD-FUNCTIONS/qr.cc (maybe_set_triangular): New function.
+	(Fqr): Use it.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/chol.cc: Fix tests for missing cholmod.
+
+	* input.cc (get_debug_input): Write debugging location info
+	directly to std::cerr instead of calling message.
+	* pt-eval.cc (tree_evaluator::do_breakpoint): Write debugging
+	location info directly to std::cerr, not octave_stdout.
+
+	* defaults.h.in (OCTAVE_DOC_CACHE_FILE): New macro.
+	* defaults.cc (set_default_doc_cache_file): New function.
+	(install_defaults): Call it.
+
+	* help.cc (__list_functions__): Simplify
+
+	* input.cc (get_debug_input): Don't pass arbitrary input to
+	message as a format string.
+
+2009-02-24  John W. Eaton  <jwe at octave.org>
+
+	* help.cc, help.h (Vdoc_cache_file): New global variable.
+	(Fdoc_cache_file): New function.
+	* octave.cc (DOC_CACHE_FILE_OPTION): New option tag.
+	(long_opts): Include doc-cache-file in the list.
+	(octave_main): Handle DOC_CACHE_FILE_OPTION.
+
+2009-02-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-scalar.h 
+	(octave_scalar::int8_scalar_value): New method.
+	(octave_scalar::int16_scalar_value): New method.
+	(octave_scalar::int32_scalar_value): New method.
+	(octave_scalar::int64_scalar_value): New method.
+	(octave_scalar::uint8_scalar_value): New method.
+	(octave_scalar::uint16_scalar_value): New method.
+	(octave_scalar::uint32_scalar_value): New method.
+	(octave_scalar::uint64_scalar_value): New method.
+
+	* ov-float.h 
+	(octave_float_scalar::int8_scalar_value): New method.
+	(octave_float_scalar::int16_scalar_value): New method.
+	(octave_float_scalar::int32_scalar_value): New method.
+	(octave_float_scalar::int64_scalar_value): New method.
+	(octave_float_scalar::uint8_scalar_value): New method.
+	(octave_float_scalar::uint16_scalar_value): New method.
+	(octave_float_scalar::uint32_scalar_value): New method.
+	(octave_float_scalar::uint64_scalar_value): New method.
+
+	* OPERATORS/op-s-s.cc (scalar_to_float): Remove duplicate conversion.
+	* OPERATORS/op-range.cc (range_to_float_matrix): Ditto.
+
+2009-02-24  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-float-conv.cc: New file.
+	* Makefile.in (FLOAT_OP_XSRC): Add it to the list.
+	(DOUBLE_OP_XSRC): Move op-double-conv.cc here from INTTYPE_OP_XSRC.
+	* ops.h (DEFFLTCONVFN, DEFSTRFLTCONVFN): New macros.
+
+2009-02-23  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-sparse.cc (octave_base_sparse<T>::print_raw):
+	Remove extra ")" from output.
+
+	* DLD-FUNCTIONS/eigs.cc (Feigs): If sigma argument is not a
+	string, try extraction as complex value and check for error
+	instead of inquiring about type first.
+
+	* pt-eval.cc (tree_evaluator::visit_break_command,
+	tree_evaluator::visit_return_command,
+	tree_evaluator::visit_global_command,
+	tree_evaluator::visit_static_command): Handle breakpoint.
+	(tree_evaluator::visit_simple_for_command,
+	tree_evaluator::visit_complex_for_command): Handle breakpoint once
+	at beginning of loop.
+	(tree_evaluator::visit_if_command_list): Don't call do_breakpoint
+	for else clauses.
+	(tree_evaluator::visit_no_op_command): Handle breakpoint if no-op
+	command is end of function or script.
+	(tree_evaluator::visit_statement): Handle breakpoint for
+	expressions but not commands.
+	(tree_evaluator::visit_while_command,
+	tree_evaluator::visit_do_until_command):
+	Check for breakpoint set on cmd, not expr.
+	(tree_evaluator::visit_do_until_command): Handle breakpoint
+	between check for breaking out of loop and loop control
+	expression.
+
+	* pt-cmd.h (tree_no_op_command::eof): New data member
+	(tree_no_op_command::tree_no_op_command): Initialize it.
+	(tree_no_op_command::is_end_of_fcn_or_script): New function.
+	* pt-stmt.cc (tree_statement::is_end_of_fcn_or_script):
+	Call is_end_of_fcn_or_script instead of looking at original text
+	of no-op command.
+
+	* pt-select.h, pt-select.cc (tree_if_command::set_breakpoint,
+	tree_if_command::delete_breakpoint): New functions.
+	(tree_switch_command::set_breakpoint,
+	tree_switch_command::delete_breakpoint): New functions.
+	* pt-stmt.h, pt-stmt.cc (tree_statement::set_breakpoint,
+	tree_statement::delete_breakpoint, tree_statement::is_breakpoint):
+	Delegate real work to cmd or expr.
+	(tree_statement::bp): Delete data member.
+	(tree_statement::tree_statement): Don't initialize bp.
+	(tree_statement::dup): Don't copy bp.
+
+	* pt.h (tree::line (int), tree:column (int)): New functions.
+	(tree:set_breakpoint, tree::delete_breakpoint): Now virtual.
+
+	* parse.y (finish_if_command): Also store line and column info for
+	if statement in first element of list.
+	(finish_switch_command): Likewise, for switch.
+
+	* input.cc (last_debugging_command): New static variable.
+	(octave_gets): Set it here.  Don't insert repeated debugging
+	commands in the history list.
+
+2009-02-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/pinv.cc: Support diagonal and permutation matrices.
+
+2008-02-21  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc, OPERATORS/op-s-scm.cc,
+	OPERATORS/op-s-sm.cc, OPERATORS/op-scm-cs.cc, OPERATORS/op-scm-s.cc,
+	OPERATORS/op-sm-cs.cc, OPERATORS/op-sm-s.cc: Don't perform any 
+	narrowing to full matrices.
+
+2009-02-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-diag.h (octave_base_diag::sqrt): Remove.
+	* ov-re-diag.cc (octave_diag_matrix::sqrt): New method.
+	* ov-re-diag.h: Declare it.
+	* ov-flt-re-diag.cc (octave_float_diag_matrix::sqrt): New method.
+	* ov-flt-re-diag.h: Declare it.
+	* ov-cx-diag.cc (octave_complex_diag_matrix::sqrt): New method.
+	* ov-cx-diag.h: Declare it.
+	* ov-flt-cx-diag.cc (octave_float_complex_diag_matrix::sqrt): New method.
+	* ov-flt-cx-diag.h: Declare it.
+
+2009-02-20  John W. Eaton  <jwe at octave.org>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_mex): Clear and
+	reload mex file if it is out of date.  Don't check path for file.
+
+	* pt-bp.cc (tree_breakpoint::visit_octave_user_script,
+	tree_breakpoint::visit_octave_user_function):
+	Don't panic.  Call accept on command list if it exists.
+
+2009-02-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::do_index_op):
+	Correctly compute all-scalar index.
+	* ov-cell.cc (octave_cell::is_sorted, octave_cell::is_sorted_rows):
+	New methods.
+	(octave_cell::octave_cell (const Array<std::string>&)): New
+	constructor.
+	* ov-cell.h: Declare them.
+	* ov-cell.cc (octave_cell::sort): Create result already with
+	cellstr_cache.
+	* strfns.cc (Fstrcmp): Use special code when dealing with
+	cellstr arrays.
+
+2009-02-20  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::assign):
+	Correctly compute all-scalar index.
+
+	* symbtab.cc (symbol_table::stash_dir_name_for_subfunctions):
+	New function.
+	* symtab.h: Provide decl.
+	* parse.y (load_fcn_from_file): Call it after parsing a function.
+
+2009-02-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.h (octave_cell::cellstr_cache): New field.
+	(octave_cell::clear_cellstr_cache, octave_cell::make_cellstr_cache,
+	octave_cell::assign, octave_cell::delete_elements,
+	octave_cell::mex_get_data): New methods.
+	(octave_cell::is_cellstr): Reuse cellstr cache if possible, create if
+	successful.
+	(octave_cell::cellstr_value): Reuse cellstr cache if possible.
+	(octave_cell::subsasgn): Clear cellstr cache.
+
+2009-02-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/lookup.cc (Flookup): Use Array<T>::lookup if possible.
+	Do not compare octave_values directly. Properly check for iscellstr.
+
+2009-02-19  John W. Eaton  <jwe at octave.org>
+
+	* data.cc, graphics.cc, help.cc, lex.l, load-path.cc, parse.y:
+	Consistent doc strings for internal functions.
+
+2009-02-18  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (convert_to_octave_idx_type_array): New static function.
+	(octave_value::octave_idx_type_vector_value): New function.
+	* ov.h (octave_value::octave_idx_type_vector_value): Provide decl.
+	* DLD-FUNCTIONS/qr.cc (Fqrdelete, Fqrinsert): Use it to convert
+	octave_value object to array of octave_idx_type values.
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx): Likewise.
+	* DLD-FUNCTIONS/time.cc (strptime): Likewise.
+	* DLD-FUNCTIONS/quad.cc (Fquad): Eliminate unnecessary cast.
+	* toplev.cc (run_command_and_return_output): Likewise.
+
+	* strfns.cc (Fstrvcat): Use octave_idx_type and size_t instead of
+	int as needed.
+	(Fstrcmp, Fstrncmp): Use octave_idx_type instead of int as needed.
+
+	* DLD-FUNCTIONS/hex2num.cc (Fhex2num, Fnum2hex):
+	Use union to avoid reinterpret_cast and GCC warning.
+
+	* mex.cc (call_mex): Declare local nargout variable volatile to
+	avoid "maybe clobbered by vfork" warning from GCC.
+
+	* ov-cx-mat.cc (xabs): Comment out unused static function.
+	* ov-flt-cx-mat.cc (xabs): Ditto.
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::seekoff,
+	c_file_ptr_buf::seepos, c_zfile_ptr_buf::seekoff,
+	c_zfile_ptr_buf::seepos): Avoid unused paramter warnings.
+
+2009-02-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (Fresize): Allow arbitrary number of parameters. Improve
+	documentation.
+
+2009-02-17  Benjamin Lindner  <lindnerb at users.sourceforge.net>
+
+	* file-io.cc: (Fmkstemp): Use mkstemps if it is available and
+	mkstemp is missing.
+
+2009-02-17  Olaf Till  <olaf.till at uni-jena.de>
+
+	* DLD-FUNCTIONS/lsode.cc, DLD-FUNCTIONS/daspk.cc, 
+	DLD-FUNCTIONS/dassl.cc, DLD-FUNCTIONS/dasrt.cc: Documentation fixes.
+
+2009-02-17  Kai Habel  <kai.habel at gmx.de>
+
+	* DLD-FUNCTIONS/convhulln.cc (Fconvhulln): Compute convex hull
+	volume and return it as second output.  New tests.
+
+2009-02-17  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn.h (octave_function::octave_function): Initialize data members.
+	(octave_function::dispatch_class): No longer virtual.
+	Replace with version from ov-usr-fcn.h.
+	(octave_function::xdispatch_class,
+	octave_function::stash_dispatch_class): Move here from ov-usr-fcn.h.
+	(octave_function::mark_as_private_function,
+	octave_function::is_private_function,
+	octave_function::is_private_function_of_class): New functions.
+	(octave_function::private_function): New data member.
+	* ov-usr-fcn.h (octave_user_function::xdispatch_class,
+	octave_user_function::stash_dispatch_class,
+	octave_user_function::dispatch_class): Delete.
+	* ov-usr-fcn.cc (octave_user_function::octave_user_function):
+	Don't initialize xdispatch_type.
+
+	* symtab.cc
+	(symbol_table::fcn_info::fcn_info_rep::load_private_function):
+	If private directory is subdirectory of class directory, qmark
+	function as a private directory of the class.
+
+	* ov-class.cc (octave_class::in_class_method): Also return true
+	for functions that are private to a class.
+	(octave_class::subsasgn): If not in class method, look for
+	subsasgn method.  If not found, or if not in a class method,
+	perform default struct-style subscripted indexing.
+
+	* ov-class.h (octave_class::empty_clone):
+	Preserve fields and class name.
+	* oct-map.h (Octave_map::Octave_map (const string_vector&):
+	New constructor.
+
+	* ov-class.cc (octave_class::subsref): If indexing directly and
+	result is map, return class object, not simple struct.
+
+	* symtab.cc
+	(symbol_table::fcn_info::fcn_info_rep::load_private_function):
+	Pass dir_name to load_fcn_from_file.
+	
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/data.cc (NATIVE_REDUCTION): Add BOOL_FCN argument.
+	(NATIVE_REDUCTION_1): Check integer overflow flags and possibly gripe.
+	(Fsum): Reflect change.
+	(Fcumsum): USE NATIVE_REDUCTION.
+	* gripes.cc (gripe_native_integer_math_truncated): New function.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/max.cc (Fcummin, Fcummax): Improve inline docs.
+
+2009-02-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/max.cc (MINMAX_DOUBLE_SBODY): New macro.
+	(MINMAX_DOUBLE_BODY): Move part of code to MINMAX_DOUBLE_SBODY.
+	(MINMAX_SINGLE_SBODY): New macro.
+	(MINMAX_SINGLE_BODY): Move part of code to MINMAX_DOUBLE_SBODY.
+	(MINMAX_INT_SBODY): New macro.
+	(MINMAX_INT_BODY): Move part of code to MINMAX_DOUBLE_SBODY.
+	(CUMMINMAX_BODY): New macro.
+	(Fcummin, Fcummax): New DLD functions.
+
+2009-02-17  John W. Eaton  <jwe at octave.org>
+
+	* octave.gperf: Eliminate whitespace to allow gperf 2.7.2 to work.
+
+	* file-io.cc (Ffscanf, Fsscanf): Check error_state after call to
+	octave_stream::scanf.
+	(Ffgetl): Check error state after call to octave_stream::getl.
+	(Ffgets): Check error state after call to octave_stream::gets.
+
+	* oct-stream.cc (octave_base_stream::do_gets,
+	octave_base_stream::do_scanf):
+	Disallow reading from stdin when running interactively.
+
+	* toplev.cc (octave_config_info): Add CARBON_LIBS, X11_INCFLAGS,
+	and X11_LIBS to the struct.
+	* oct-conf.h.in (OCTAVE_CONF_CARBON_LIBS,
+	OCTAVE_CONF_X11_INCFLAGS, OCTAVE_CONF_X11_LIBS): New macros.
+
+2009-02-17  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* Makefile.in (octave$(EXEEXT)): Link with CARBON_LIBS.
+
+2009-02-16  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (next_token_can_follow_bin_op):
+	Push all characters read on to buffer stack.
+
+	* genprops.awk (emit_source): Don't use + to concatenate strings.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* data.cc (NATIVE_REDUCTION): Use boolNDArray::any for native bool
+	summation, boolNDArray::sum for double-valued.
+
+2009-02-16  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::assign (const octave_value_list&,
+	typename MT::element_type): Fix invalid index.
+	* ov-re-mat.cc (default_numeric_demotion_function): Use
+	float_array_value instead of float_matrix_value.
+
+2009-02-16  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (gnu_readline): Use fputs instead of fprintf.
+
+2009-02-15  John W. Eaton  <jwe at octave.org>
+
+	* defun.cc, defun-int.h, defun-dld.h (DEFUN_INTERNAL,
+	DEFCONSTFUN_INTERNAL, DEFUNX_INTERNAL, DEFUN_DLD_INTERNAL,
+	DEFUNX_DLD_INTERNAL, install_builtin_function,
+	install_dld_function, install_mex_function):
+	Delete IS_TEXT_FCN arg.  Fix all uses.
+	(DEFMD, DEFUN_TEXT): Delete.
+	* mkbuiltins, mkgendoc: Adapt to DEFUN macro changes.
+
+	* lex.h, lex.l (lexer_flags::at_beginning_of_statement):
+	New data member.  Set it as needed in rules.
+	(is_keyword_token):
+	Handle lexer_flags::at_beginning_of_statement.
+	(next_token_can_follow_bin_op, looks_like_command_arg): New functions.
+	(handle_identifier): Use them to determine 
+	Don't check is_command_name or is_rawcommand_name.
+	* parse.y (statement): Recognize word_list_cmd here.
+	(expression): Not here.
+
+	* lex.l (handle_string): Delete arg TEXT_STYLE.
+	(BIN_OP_RETURN, XBIN_OP_RETURN): New arg, BOS. Change all uses.
+
+	* lex.h, lex.l (lexer_flags::doing_raw_command): Delete data
+	member and all uses.
+
+	* debug.cc, dirfns.cc, error.cc, input.cc, lex.l, load-path.cc,
+	load-save.cc, oct-hist.cc, ov-class.cc, pager.cc, parse.y,
+	pr-output.cc, sysdep.cc, utils.cc, variables.cc:
+	Replace all uses of DEFCMD with DEFUN.
+
+	* variables.cc (command_set, rawcommand_set): Delete static variables.
+	(mark_as_command, unmark_command, is_command_name,
+	mark_as_rawcommand, unmark_raw_command, is_rawcommand_name): Delete.
+	(Fmark_as_command, Funmark_command, Fiscommand,
+	Fmark_as_rawcommand, Funmark_rawcommand, Fisrawcommand):
+	Convert to .m files and move to scripts/deprecated.
+	* variables.h (mark_as_command, is_command_name,
+	is_marked_as_rawcommand, mark_as_rawcommand, unmark_rawcommand,
+	is_rawcommand_name): Delete decls.
+
+	* lex.h, lex.l (lexer_flags.looking_at_object_index): Now a
+	std::list<bool> object instead of an int.
+	Push TRUE to list at start of object index.  Push FALSE at
+	beginning of matrix list.  Pop value at end of object index or
+	matrix list.
+	(lexer_flags.looking_for_object_index): New data member.
+	Set it as needed in rules.
+	(inside_any_object_index): New function.
+	* parse.y (begin_obj_idx, cancel_obj_idx): Delete non-terminals
+	and all uses.
+
+2009-02-13 Ben Abbott <bpabott at mac.com>
+
+	* graphics.h.in (class axes::properties): Initialize ticklength.
+	* graphics.cc (default_axes_ticklength): New function.
+
+2009-02-13  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_base_stream::do_gets): Handle CRLF and CR.
+
+	* toplev.cc (do_octave_atexit): Only save history if
+	Vsaving_history is true.
+
+2009-02-12  John W. Eaton  <jwe at octave.org>
+
+	* data.cc, ov-base-diag.h, ov-base-mat.h, ov-base-scalar.h,
+	ov-base-sparse.h, ov-base.cc, ov-base.h, ov-perm.h, ov-range.h,
+	ov.h: Rename internal issorted and issorted_rows functions to
+	is_sorted and is_sorted_rows.
+
+	* ov-base-diag.h, ov-base-mat.h, ov-base-scalar.h, ov-base.h,
+	ov-cell.h, ov-perm.h, ov-range.h, ov.h, data.cc, ov-base.cc,
+	ov-cell.cc: Rename all uses of sortrows_idx to sort_rows_idx.
+
+	* TEMPLATE-INST/Array-tc.cc: Don't instantiate sort functions for
+	Arrays of octave_value objects.
+	(octave_sort<octave_value>::ascending_compare,
+	octave_sort<octave_value>::descending_compare): Delete.
+
+	* ov.h (octave_value::cellstr_value): New function.
+	* ov-base.cc, ov-base.h (octave_base_value::cellstr_value):
+	New function.
+	* ov-cell.h (octave_cell::cellstr_value, octave_cell::sort,
+	octave_cell::sortrows_idx): New functions
+	* Cell.h, Cell.cc (Cell::Cell (Array<std::string>)): New constructor.
+
+	* TEMPLATE-INST/Array-tc.cc: Undo previous change.
+	(octave_sort<octave_value>::ascending_compare,
+	octave_sort<octave_value>::descending_compare):
+	Pass args by const reference instead of value.
+
+	* version.h (OCTAVE_VERSION): Now 3.1.52+.
+	(OCTAVE_API_VERSION): Now api-v34+.
+
+	* TEMPLATE-INST/Array-tc.cc
+	(octave_sort<octave_value>::ascending_compare,
+	octave_sort<octave_value>::descending_compare):
+	Delete unused template specializations.
+	Use NO_INSTANTIATE_ARRAY_SORT instead of INSTANTIATE_ARRAY_SORT
+	for octave_values.
+
+2009-02-11  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* gl-render.h: Use HAVE_FRAMEWORK_OPENGL.
+	* gl-render.cc (opengl_tesselator, opengl_renderer::draw, 
+	opengl_renderer::init_marker): Use HAVE_FRAMEWORK_OPENGL.
+	
+2009-02-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h (octave_value::issorted, octave_value::sortrows_idx,
+	octave_value::issorted_rows): New methods.
+	* ov.cc (octave_base_value::issorted, octave_base_value::sortrows_idx,
+	octave_base_value::issorted_rows): New methods.
+	* ov.cc: Declare them.
+
+	* ov-base-mat.h (octave_base_matrix::issorted, octave_base_matrix::sortrows_idx,
+	octave_base_matrix::issorted_rows): New methods.
+
+	* ov-base-diag.h (octave_base_diag::issorted, octave_base_diag::sortrows_idx,
+	octave_base_diag::issorted_rows): New methods.
+
+	* ov-perm.h (octave_perm_matrix::issorted, octave_perm_matrix::sortrows_idx,
+	octave_perm_matrix::issorted_rows): New methods.
+
+	* ov-range.h (octave_range::issorted, octave_range::sortrows_idx,
+	octave_range::issorted_rows): New methods.
+
+	* data.cc (F__sortrows_idx__, Fissorted): New defuns.
+
+2009-02-11  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_config_info): Add octetcdir to the struct.
+	* defaults.h.in (OCTAVE_OCTETCDIR): New macro.
+
+2009-02-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/__pchip_deriv__.cc (F__pchip_deriv__):
+	Add support for computing pchip derivatives along rows of matrix.
+	Eliminate redundant copying by using const args where appropriate.
+
+2009-02-09  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.52.
+	(OCTAVE_RELEASE_DATE): Now 2009-02-09.
+	(OCTAVE_COPYRIGHT): Update year.
+
+	* load-path.cc (dir_info::update, dir_info::initialize):
+	Likewise, to allow some functionality if getcwd fails.
+
+	* toplev.cc (main_loop): Also catch octave_execution_exception.
+
+	* DLD-FUNCTIONS/dispatch.cc: Comment out troublesome tests.
+
+	* DLD-FUNCTIONS/eigs.cc: Increase tolerance to 1e-11 on all tests.
+
+	* lex.l (lexical_feedback::looking_at_decl_list): New data member.
+	* lex.l (lexical_feedback::init): Initialize it.
+	(handle_identifier): Also force local variable if looking_at_decl_list.
+	* parse.y (parsing_decl_list): New non-terminal.
+	(declaration): Use it.  Set lexer_flags.looking_at_decl_list to
+	false after parsing the declaration.
+
+2009-02-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* TEMPLATE-INST/Array-tc.cc: Reflect changes in octave_sort.
+
+2009-02-08  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (initialize_pathsearch): Delete.
+	(octave_main): Don't call initialize_pathsearch.
+
+2009-02-07  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (eval_string): Use the one true evaluator.
+
+2009-02-06  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (INCLUDES): Include oct-hdf5.h in the list.
+
+	* Makefile.in (oct-gperf.h): Don't use pipeline to process gperf
+	output.
+
+2009-02-05  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_table::fcn_info::cn_info_rep::xfind):
+	New function.
+	(symbol_table::fcn_info::cn_info_rep::find):
+	Use it to avoid recursive call.
+
+	* graphics.cc (Fdrawnow): Return after errors.  Don't strip
+	trailing directory separator from name used in call to file_stat.
+
+	* DLD-FUNCTIONS/eigs.cc (Feigs): Avoid warnings about ambiguous
+	else.  Style fixes.  Return after errors.
+
+2009-02-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-map.cc (Octave_map::index): Optimize.
+
+2009-02-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* OPERATORS/op-cm-cs.cc: Use scalar_value in scalar-to-matrix
+	indexed assignments.
+	* OPERATORS/op-fcm-fcs.cc: Ditto.
+	* OPERATORS/op-fm-fs.cc: Ditto.
+	* OPERATORS/op-m-s.cc: Ditto.
+	* OPERATORS/op-int.h (OCTAVE_MS_INT_ASSIGN_OPS): Use homogeneous
+	integer scalar-to-matrix assignment.
+	(OCTAVE_MM_INT_ASSIGN_OPS): Use homogeneous integer matrix-to-matrix
+	assignment.
+
+	* Cell.h (Cell::index): Remove direct idx_vector overloads.
+	(Cell::assign): Remove direct idx_vector overloads.
+	(Cell::delete_elements): Remove direct idx_vector overloads.
+	* Cell.cc (Cell::index (const octave_value_list&)): Call
+	ArrayN<octave_value>::index.
+
+	* oct-map.h (Octave_map::index): Remove direct idx_vector overloads.
+	* oct-map.cc (Octave_map::index): Ditto.
+	* ov-base-mat.cc (octave_base_mat::do_index_op): Optimize scalar
+	indexing case.
+	(octave_base_mat::assign (const octave_value_list&, const MT&)):
+	Specialize variable argument number.
+	(octave_base_mat::assign (const octave_value_list&, const 
+	typename MT::element_type&)):
+	New method overload with optimized scalar indexing case.
+
+	* ov-cell.cc (octave_base_matrix<Cell>::do_index_op,
+	octave_base_matrix<Cell>::assign,
+	octave_base_matrix<Cell>::delete_elements): Specialize.
+	(octave_cell::assign (const_octave_value_list, const octave_value&):
+	Delete method.
+	* ov-cell.h: Reflect change.
+
+	* ov-cx-mat.cc (octave_complex_matrix::assign): Delete overloads.
+	* ov-cx-mat.h: Reflect changes.
+	* ov-flt-cx-mat.cc (octave_float_complex_matrix::assign): Delete overloads.
+	* ov-flt-cx-mat.h: Reflect changes.
+	* ov-list.cc (octave_list::do_index_op): Simplify.
+	* ov-struct.cc (octave_struct::do_index_op): Simplify.
+	* pt-eval.cc (tree_evaluator::visit_simple_for_command): Optimize
+	traversing a row vector.
+
+2009-02-05  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (Vignore_function_time_stamp):
+	Eliminate unused static variable.
+
+	* debug.cc (get_file_line): Override default precedence in logical
+	expression.
+
+	* ov-null-mat.cc (default_null_str_numeric_conversion_function,
+	default_null_sq_str_numeric_conversion_function,
+	default_null_matrix_numeric_conversion_function):
+	Avoid unused variable warning.
+
+	* ov-flt-re-diag.cc (octave_float_diag_matrix::save_binary):
+	Avoid unused parameter warning.
+	* pt-eval.cc (tree_evaluator::visit_if_clause): Likewise.
+	* ov-typeinfo.cc (octave_value_typeinfo::do_register_type): Likewise.
+	* ov-base.cc (octave_base_value::subsref (const std::string&,
+	const std::list<octave_value_list>&, bool): Likewise.
+	* ov-flt-cx-diag.cc (octave_float_complex_diag_matrix::save_binary): 
+	Likewise.
+
+	* oct-hdf5.h: New file.
+	* ls-hdf5.cc, ov-base.h, ov.h: Include oct-hdf5.h instead of hdf5.h.
+	* ls-hdf5.h: Include oct-hdf5.h.
+	* load-save.cc: Include ls-hdf5.h instead of hdf5.h.
+	* ov-base-sparse.cc, load-save.cc:
+	Don't protect #include "ls-hdf5.h" with #ifdef.
+
+2009-02-04  Kai Habel  <kai.habel at gmx.de>
+
+	* gl-render.cc (opengl_renderer::draw (surface::properties)):
+	Normalize surface normals. Correct calculation of diffuse lighting.
+	* gl-render.cc (opengl_renderer::draw (patch::properties)):
+	Correct calculation of diffuse lighting.
+
+2009-02-04  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (do_which): If NAME is not in the symbol table, look for
+	a function file in the load path.
+	(raw_help_from_file): Unwind-protect and set reading_script_file.
+
+	* pt-loop.h, pt-loop.cc (evaluating_looping_command):
+	Delete global variable and all uses.
+	* parse.y, parse.h (evaluating_function_body): Delete global
+	variable and all uses.
+	(make_break_command, make_continue_command, make_return_command):
+	Use tree_evaluator::in_fcn_or_script_body and
+	tree_evaluator::in_loop_command instead of
+	evaluating_function_body and evaluating_looping_command.
+
+	* pt-eval.h (tree_evaluator::in_function_or_script_body):
+	Delete 	member variable and all uses.
+	(tree_evaluator::reset): Delete function and all uses.
+	
+	* pt-eval.cc, pt-eval.h (tree_evaluator::in_fcn_or_script_body,
+	tree_evaluator::in_loop_command): New static variables.
+	(tree_evaluator::visit_simple_for_command,
+	tree_evaluator::visit_complex_for_command,
+	tree_evaluator::visit_while_command,
+	tree_evaluator::visit_do_until_command): Unwind-protect and set
+	tree_evaluator::in_loop_command instead of
+	evaluating_looping_command.
+	(tree_evaluator::visit_statement): Only call echo_code if
+	evaluating function or script and (Vecho_executing_commands &
+	ECHO_FUNCTIONS).  Use tree_evaluator::in_fcn_or_script_body
+	instead of evaluating_function_body.  
+
+	* ov-usr-fcn.cc (octave_user_script::do_multi_index_op):
+	octave_user_function::do_multi_index_op): Unwind-protect and set
+	tree_evaluator::in_fcn_or_script_body.
+
+	* pt-stmt.cc, pt-stmt.h (tree_statement::echo_code):
+	Rename from maybe_echo_code.  Simplify.
+
+2009-02-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-loop.h (tree_simple_for_command::do_for_loop_once,
+	tree_complex_for_command::do_for_loop_once): Remove obsolete decls.
+	* pt-loop.cc (quit_loop_now): Remove obsolete method.
+	* pt-eval.cc (DO_ND_LOOP): Delete macro.
+	(tree_evaluator::visit_simple_for_command): Use the generic
+	do_index_op for iterating matrices.
+
+2009-02-04  John W. Eaton  <jwe at octave.org>
+
+	New evaluator and debugger derived from tree-walker class.
+
+	* pt-eval.h, pt-eval.cc: New files.  Parse tree evaluator code
+	adapted from eval member functions in classes derived from
+	tree_command.
+	* Makefile.in (PT_INCLUDES, PT_SRC): Add them to the lists
+
+	* pt-cmd.cc (tree_function_def::eval): Delete.
+	* pt-cmd.h: Delete decl.
+	(tree_command::eval): Delete pure virtual function.
+	(tree_no_op_command::eval): Delete.
+	(tree_function_def::function): Return octave_value, instead of
+	pointer to octave_function.  Change all uses.
+
+	* pt-except.cc (do_catch_code, tree_try_catch_command::eval,
+	do_unwind_protect_cleanup_code,
+	tree_unwind_protect_command::eval): Delete.
+	* pt-except.h: Delete decls.
+
+	* pt-jump.cc (tree_break_command::eval, tree_return_command::eval,
+	tree_continue_command::eval): Delete.
+	* pt-jump.h: Delete decls.
+
+	* pt-loop.cc (DO_ND_LOOP): Delete macro.
+	(tree_while_command::eval, tree_do_until_command::eval,
+	tree_simple_for_command::do_for_loop_once,
+	tree_simple_for_command::eval,
+	tree_complex_for_command::do_for_loop_once,
+	tree_complex_for_command::eval):
+	* pt-loop.h: Delete decls.
+
+	* pt-select.cc (tree_if_clause::eval, tree_if_command_list::eval,
+	tree_if_command::eval, tree_switch_case::eval,
+	tree_switch_case_list::eval, tree_switch_command::eval): Delete.
+	* pt-select.h: Delete decls.
+	(class tree_if_clause, class tree_switch_case): Derive from tree.
+	Handle line and column in constructors.
+
+	* pt-stmt.cc (tree_statement::eval): Delete
+	* pt-stmt.h: Delete decl.
+
+	* pt-stmt.cc, pt-stmt.h (tree_statement::is_command,
+	tree_statement::is_expression, tree_statement::line,
+	tree_statement::column): Now const.
+	
+	* pt-stmt.cc (tree_statement::set_print_flag,
+	tree_statement::is_end_of_fcn_or_script): New functions.
+	* pt-stmt.h: Provide decl.
+	(set_breakpoint, delete_breakpoint, is_breakpoint): New function.
+	(bp): New member variable.
+	(print_result): Delete member variable.
+	(tree_statement_list::anon_function_body): New member variable.
+	(tree_statement_list::mark_as_anon_function_body,
+	tree_statement_list::is_anon_function_body,
+	tree_statement_list::is_script_body): New functions.
+
+	* pt-decl.cc (tree_decl_init_list::eval,
+	tree_decl_command::accept, tree_global_command::do_init,
+	tree_global_command::eval, tree_static_command::do_init,
+	tree_static_command::eval): Delete.
+	* pt-decl.h: Delete decls.
+	(tree_decl_elt::eval_fcn): Delete typedef.
+
+	* pt-decl.cc (tree_global_command::accept,
+	tree_static_command::accept): New functions.
+	
+	* pt-stmt.cc (tree_statement::print_result): Move here from
+	pt-stmt.h.  Return true if expr is printable.
+
+	* ov-base.cc (Vsilent_functions): Delete.
+	(octave_base_value::print_with_name): Don't check
+	evaluating_function_body && Vsilent_functions here.
+	* ov-class.cc (octave_class::print_with_name): Likewise.
+	* ov-base.h (Vsilent_functions): Delete decl.
+	* pt-eval.cc (Fsilent_functions): Move here from ov-base.cc.
+	(Vsilent_functions): New static variable.
+
+	* sighandlers.cc (user_abort): Set tree_evaluator::debug_mode here.
+
+	* pt.h (tree::bp): Rename from tree::break_point.
+	(tree::set_breakpoint, tree::delete_breakpoint, tree::is_breakpoint):
+	No longer virtual.
+
+	* input.cc (get_debug_input): Use current_evaluator and
+	tree-walker to evaluate command.
+	* ov-usr-fcn.cc (octave_user_script::do_multi_index_op): Likewise.
+	* toplev.cc (main_loop): Likewise.
+	* parse.y (eval_string):
+
+	* input.h, input.cc (Vdebugging_current_line): Delete.
+	(get_debug_input): Use tree_evaluator::debug_line instead of
+	Vdebugging_current_line.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Handle inline functions and anonymous functions as single
+	expressions.
+	* parse.y (eval_string): Likewise.
+
+	* parse.y (make_do_until_command): Rename first argument from
+	do_tok to until_tok.
+	(loop_command): Pass UNTIL token instead of DO token to
+	make_do_until_command.
+	(make_elseif_clause): New arg, elseif_tok.  Pass line and column
+	info to tree_if_clause constructor.
+	(elseif_clause): Pass ELSEIF token to make_elseif_clause.
+	(make_switch_case): New arg, case_tok.  Pass line and column info
+	to tree_switch_case constructor.
+	(switch_case): Pass CASE token to make_switch_case.
+	(make_script): New arg end_script.  Append it to cmds.
+	(script): Create no-op command for end of script and pass it to
+	make_script.
+	(start_function): New arg, end_function. Append it to body.
+	(function2): Pass end_function to start_function.
+	(make_end): New function.
+	(function_end): Declare as tree_statement_type.
+	Create no-op command for end of script.
+	(make_anon_fcn_handle): Mark body as anonymous function.
+	(set_stmt_print_flag): Set print flag for all separator types
+
+	* parse.y (fold (tree_binary_expression*),
+	fold (tree_unary_expression *),	finish_colon_expression,
+	finish_matrix): Call rvalue1 instead of rvalue.
+	Stash line number in new tree_constant object.
+
+	* debug.h (bp_table::have_breakpoints): New static function.
+	(bp_table::do_have_breakpoints): New member function.
+	* debug.cc (bp_table::do_add_breakpoint,
+	bp_table::do_remove_breakpoint,
+	bp_table::do_remove_all_breakpoints_in_file,
+	bp_table::do_remove_all_breakpoints): Call
+	bp_table::have_breakpoints to set tree_evaluator::debug_mode.
+	(Fdbnext): Delete function.  Alias to dbstep.
+	(Fdbquit, Fdbcont): Set tree_evaluator::dbstep_flag to zero.
+	(Fdbstep): Rewrite to use tree_evaluator::dbstep_flag instead of
+	tree::break_next, tree::last_line, tree::break_function, and
+	tree::last_break_function.
+	(Fdbwhere): Use tree_evaluator::debug_line and
+	tree_evaluator::debug_column to get current line and column info.
+	Don't print column if it is less than zero.
+	* pt.cc, pt.h (tree::break_next, tree::last_line,
+	tree::last_break_function, tree::break_function,
+	tree::break_statement): Delete.
+
+	* pt-bp.cc (tree_breakpoint::visit_global_command,
+	tree_breakpoint::visit_static_command,
+	tree_breakpoint::take_action (tree_statement&)): New functions.
+	* pt-bp.h: Provide decls.
+
+	* pt-bp.h (tree_walker::visit_global_command,
+	tree_walker::visit_static_command): New pure virtual functions.
+	(tree_walker::visit_decl_command): Delete.
+
+	* pt-bp.cc (tree_breakpoint::visit_decl_command): Delete.
+	* pt-bp.h: Delete decl.
+	(MAYBE_DO_BREAKPOINT): Delete macro and all uses.
+
+	* pt-bp.cc (tree_breakpoint::visit_no_op_command): Do nothing.
+	(tree_breakpoint::visit_argument_list,
+	tree_breakpoint::visit_binary_expression,
+	tree_breakpoint::visit_colon_expression,
+	tree_breakpoint::visit_decl_elt,
+	tree_breakpoint::visit_decl_init_list,
+	tree_breakpoint::visit_octave_user_script,
+	tree_breakpoint::visit_octave_user_function,
+	tree_breakpoint::visit_octave_user_function_header,
+	tree_breakpoint::visit_octave_user_function_trailer,
+	tree_breakpoint::visit_identifier,
+	tree_breakpoint::visit_index_expression,
+	tree_breakpoint::visit_matrix, tree_breakpoint::visit_cell,
+	tree_breakpoint::visit_multi_assignment,
+	tree_breakpoint::visit_anon_fcn_handle,
+	tree_breakpoint::visit_constant,
+	tree_breakpoint::visit_fcn_handle,
+	tree_breakpoint::visit_parameter_list,
+	tree_breakpoint::visit_postfix_expression,
+	tree_breakpoint::visit_prefix_expression,
+	tree_breakpoint::visit_return_list,
+	tree_breakpoint::visit_simple_assignment): Call panic_impossible
+	since breakpoints aren't set on expressions.
+	(tree_breakpoint::visit_if_clause): Fold into visit_if_command_list.
+	(tree_breakpoint::visit_switch_case): Fold into visit_switch_case_list.
+	(tree_breakpoint::visit_try_catch_command,
+	tree_breakpoint::visit_unwind_protect_command):
+	Don't set breakpoint on command itself, the the statements it
+	contains.
+	(tree_breakpoint::visit_global_command,
+	tree_breakpoint::visit_static_command): Call do_decl_command to do
+	actual work.
+	(tree_breakpoint::visit_while_command,
+	tree_breakpoint::visit_do_until_command,
+	tree_breakpoint::visit_simple_for_command,
+	tree_breakpoint::visit_complex_for_command,
+	tree_breakpoint::visit_statement,
+	tree_breakpoint::visit_statement_list,
+	tree_breakpoint::visit_switch_case_list): Set breakpoints at
+	appropriate places.
+
+	* pt-pr-code.h, pt-pr-code.cc (tree_print_code::visit_global_command,
+	tree_print_code::visit_static_command,
+	tree_print_code::do_decl_command): New functions.
+	(tree_print_code::visit_decl_command): Delete.
+
+	* pt-check.h, pt-check.cc (tree_checker::visit_global_command,
+	tree_checker::visit_static_command, tree_checker::do_decl_command):
+	New functions. 
+	(tree_checker::visit_decl_command): Delete.
+
+	* pt-select.cc (tree_switch_case::label_matches): Call rvalue1
+	instead of rvalue.
+
+	* pt-exp.h, pt-exp.cc (tree_expression::rvalue1): New function.
+	(tree_expression::rvalue (void)): Delete.
+	(tree_expression::is_logically_true): Call rvalue1 instead of rvalue.
+
+	* pt-fcn-handle.h, pt-fcn-handle.cc (tree_fcn_handle::rvalue1,
+	tree_anon_fcn_handle::rvalue1): New functions.
+	(tree_fcn_handle:rvalue (void),
+	tree_anon_fcn_handle::rvalue1 (void)): Delete.
+	(tree_fcn_handle::rvalue (int), tree_anon_fcn_handle_rvalue (int)):
+	Call rvalue1 instead of rvalue.
+
+	* pt-idx.h, pt-idx.cc (tree_index_expression::rvalue1): New function.
+	(tree_index_expression::rvalue (void)): Delete.
+	(tree_index_expression::get_struct_index,
+	tree_index_expression::rvalue (int)): Call rvalue1 instead of rvalue.
+
+	* pt-mat.h, pt-mat.cc (tree_matrix::rvalue1): New function.
+	(tree_matrix::rvalue (void)): Delete.
+	(tm_row_const::tm_row_const_rep::init,
+	tree_matrix::rvalue (int)): Call rvalue1 instead of rvalue.
+
+	* pt-misc.cc (tree_parameter_list::convert_to_const_vector):
+	Call rvalue1 instead of rvalue.
+	* pt-arg-list.cc (tree_argument_list::convert_to_const_vector):
+	Likewise.
+
+	* pt-unop.h, pt-unop.cc (tree_prefix_expression::rvalue1,
+	tree_postfix_expression::rvalue1): New functions.
+	(tree_prefix_expression::rvalue (void),
+	tree_postfix_expression::rvalue (void)): Delete.
+	(tree_prefix_expression::rvalue (int),
+	tree_postfix_expression::rvalue (int)):
+	Call rvalue1 instead of rvalue.
+
+	* pt-id.h, pt-id.cc (tree_identifier::rvalue1): New function.
+	(tree_identifier::rvalue (void)): Delete.
+
+	* pt-assign.h, pt-assign.cc (tree_simple_assignment::rvalue1,
+	tree_multi_assignment::rvalue1): New functions.
+	(tree_simple_assignment::rvalue (void),
+	tree_multi_assignment::rvalue (void): Delete.
+	(tree_simple_assignment::rvalue (int)):
+	Call rvalue1 instead of rvalue.
+
+	* pt-binop.h, pt-binop.cc (tree_binary_expression::rvalue1,
+	tree_boolean_expression::rvalue1): New functions.
+	(tree_binary_expression::rvalue (void),
+	tree_boolean_expression::rvalue (void)): Delete.
+	(tree_binary_expression::rvalue (int),
+	tree_boolean_expression::rvalue (int)):
+	Call rvalue1 instead of rvalue.
+
+	* pt-cbinop.h, pt-cbinop.cc
+	(tree_compound_binary_expression::rvalue1): New function.
+	(tree_compound_binary_expression::rvalue (void)): Delete.
+
+	* pt-cell.h, pt-cell.cc (tree_cell::rvalue1): New function.
+	(tree_cell::rvalue (void)): Delete.
+	(tree_cell::rvalue (int)): Call rvalue1 instead of rvalue.
+
+	* pt-colon.h, pt-colon.cc (tree_colon_expression::rvalue1):
+	New function.
+	(tree_colon_expression::rvalue (void)): Delete.
+	(tree_colon_expression::rvalue (int)):
+	Call rvalue1 instead of rvalue.
+
+	* pt-const.h, pt-const.cc (tree_constant::rvalue1): New function.
+	(tree_constant::rvalue (void)): Delete.
+	(tree_constant::rvalue (int)): Call rvalue1 instead of rvalue.
+
+	* pt-decl.h, pt-decl.cc (tree_decl_elt::ravlue1): New function.
+	(tree_decl_elt::ravlue (void)): Delete.
+	(tree_decl_elt::eval): Call rvalue1 instead of rvalue.
+
+2009-02-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* TEMPLATE-INST/Array-tc.cc: Replace vec_index by pointers.
+
+2009-02-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-re-mat.cc (octave_matrix::abs, octave_matrix::real,
+	octave_matrix::imag, octave_matrix::conj): Use special code.
+	* ov-flt-re-mat.cc (octave_float_matrix::abs, octave_float_matrix::real,
+	octave_float_matrix::imag, octave_float_matrix::conj): Use special code.
+	* ov-cx-mat.cc (octave_complex_matrix::abs, octave_complex_matrix::real,
+	octave_complex_matrix::imag, octave_complex_matrix::conj): Use special code.
+	* ov-flt-cx-mat.cc (octave_float_complex_matrix::abs, octave_float_complex_matrix::real,
+	octave_float_complex_matrix::imag, octave_float_complex_matrix::conj): Use special code.
+
+2009-01-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/lookup.cc (Flookup): Add missing check.
+
+2009-01-29  John W. Eaton  <jwe at octave.org>
+
+	* pt-stmt.cc (tree_statement::eval): Check
+	in_function_or_script_body instead of symbol_table::at_top_level ()
+	to decide whether to call octave_call_stack::set_statement.
+
+	* graphics.cc (properties::set_defaults): Also set
+	horizontalalignment, verticalalignmnt, and rotation properties for
+	new label objects here.
+
+	* ov-base-scalar.cc (octave_base_scalar<ST>::is_true (void) const):
+	Error if scalar is NaN.
+	* ov-base-mat.cc (octave_base_matrix<MT>::is_true (void) const):
+	Likewise, if any element of matrix is NaN.
+	* ov-cell.cc (octave_cell::is_true): New function.
+	* Cell.h (Cell::any_element_is_nan): New function.
+
+2009-01-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pr-output.cc:
+	(void octave_print_internal (..., const DiagMatrix& m,...),
+	(void octave_print_internal (..., const ComplexDiagMatrix& m,...),
+	(void octave_print_internal (..., const FloatDiagMatrix& m,...),
+	(void octave_print_internal (..., const FloatComplexDiagMatrix& m,...)):
+	New functions.
+	* pr-output.h: Declare them.
+	* ov-base-diag.cc (octave_base_diag::print_raw): Call
+	octave_print_internal.
+
+2009-01-28  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (install, uninstall): Handle SHLLIBPRE and SHLBINPRE
+	library prefixes.  From Marco Atzeri <marco_atzeri at yahoo.it>.
+
+2008-01-28  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp_list): Don't break for zero
+	length match, but rather advance the index by one character and
+	try again.
+
+2009-01-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/lookup.cc (Flookup): Fix doc string.
+
+2009-01-27  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (Fcommand_line_path): Rename from Fcommandlinepath.
+
+2009-01-27 Ben Abbott <bpabbott at mac.com>
+
+	* graphics.cc (convert_position): Handle character units.
+	(default_axes_tick, default_figure_papersize,
+	default_figure_paperposition): New functions.
+	* graphics.h.in (class figure::properties): Use them to
+	initialize papersize, paperposition, xtick, ytick, and ztick
+	properties.
+
+2009-01-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/qr.cc (Fqr): Treat empty matrices correctly.
+
+2009-01-26  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* display.cc (display_info::init): Use double instead of CGFloat.
+	Use HAVE_FRAMEWORK_CARBON instead of OCTAVE_USE_OS_X_API.
+
+2009-01-26  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_find_fcn): Handle @foo/bar.
+
+2009-01-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-cell.cc (tree_cell::rvalue): Optimize the single row case.
+
+2009-01-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-struct.cc (octave_struct::subsasgn): Reshape cs-list on rhs 
+	according to the index expression.
+	* ov-cell.cc (octave_cell::subsasgn): Ditto.
+
+2008-12-25 Ben Abbott <bpabbott at mac.com>
+
+	* load-path.cc (Fcommandlinepath): New function.
+	* load-path.h (load_path::get_command_line_path,
+	load_path::do_get_command_line_path): New functions.
+
+2009-01-24 Ben Abbott <bpabbott at mac.com>
+
+	* DLD-FUNCTIONS/eigs.cc: eigs.cc: skip tests if ARPACK is missing.
+
+2009-01-25  Søren Hauberg  <hauberg at gmail.com>
+
+	* help.cc (do_get_help_text, raw_help_from_symbol_table): new output to
+	flag the a function is found but not documented.
+	
+2009-01-25  Søren Hauberg  <hauberg at gmail.com>
+
+	* help.cc (raw_help_from_file): No longer search for files called
+	'Contents.m', as this is moved to 'script/help.m'.
+	
+
+2009-01-23  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_call_stack::do_goto_caller_frame):
+	Also allow caller frame to be base frame, not just user code.
+
+2009-01-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* gripes.cc (gripe_indexed_cs_list, gripe_invalid_inquiry_subscript):
+	New functions.
+	* gripes.h: Declare them.
+	* pt-idx.cc: Remove definitions of the above funcs.
+	* ov-cell.cc (octave_cell::subsref): Declare constants as const.
+	(octave_cell::subsasgn): Remove dead branch, declare constants as const.
+	(octave_cell::list_value): Optimize.
+	* ov-struct.cc 
+	(octave_struct::subsref): Declare constants as const.
+	(octave_struct::subsasgn): Remove dead branch, declare constants as const.
+	* ov-cs-list.cc (octave_cs_list::octave_cs_list (const Cell&)):
+	Optimize.
+	* oct-obj.cc (octave_value_list::octave_value_list (const
+	std::list<octave_value_list>&)): New constructor.
+	* oct-obj.h: Declare it.
+	* pt-arg-list.cc (convert_to_const_vector): Optimize.
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::find): Use const
+	reference to avoid redundant copy.
+	* ov-usr-fcn.cc (octave_user_function::bind_automatic_vars): Optimize.
+	(octave_user_function::octave_all_va_args): Optimize.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Cell.h (Cell::Cell (octave_value_list)): Only declare.
+	(Cell::index (*)): Change resize_ok type to bool.
+	* Cell.cc (Cell::Cell (octave_value_list)): Redefine.
+	* oct-obj.h, oct-obj.cc: Change octave_value_list::data to
+	Cell variable, reflect changes.
+
+2009-01-22  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (do_which (std::ostream&, const std::string&), Fwhich):
+	Delete.
+	(do_which (const std::string&, std::string&), F__which__):
+	New functions.
+	* do_which (const std::string&):
+	Call do_which (const std::string&, std::string&) to do the work.
+
+2009-01-22  Søren Hauberg  <hauberg at gmail.com>
+
+	* defun-int.h (print_usage): No longer mark as deprecated.
+	* defun.cc (print_usage): Simply call feval to execute print_usage.m.
+	* help.cc (additional_help_message, display_names_from_help_list,
+	display_symtab_names, simple_help, try_info, help_from_info,
+	display_help_text, display_usage_text, raw_help_from_list,
+	help_from_list, help_from_symbol_table, help_from_file,
+	builtin_help, Fhelp, display_file, do_type, Ftype,
+	first_help_sentence, print_lookfor, Flookfor): Delete.
+	(looks_like_html, raw_help_from_map, raw_help, do_get_help_text,
+	F__operators__, F__keywords__, F__builtins__,
+	file_is_in_dir, F__list_functions__): New functions.
+	(pair_type, map_iter): New typedefs.
+	(operators, keywords): Use pair_type for elements of list.
+	(names): Use map for (keyword, doc) lists.
+	(make_name_list): Sprinkle with const.
+	* help.h (display_help_text, display_usage_text,
+	additional_help_message): Delete decls.
+
+2009-01-22  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_config_info): Check OCTAVEUSE_OS_X_API instead
+	of __APPLE__ && __MACH__.
+
+	* display.cc (display_info::init): Get info for Windows and OS X
+	systems.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-idx.cc (tree_index_expression::lvalue): Correct tmpi when seeing
+	a plain struct component.
+	* ov-struct.cc (octave_struct::subsasgn): Use proper type substr in
+	empty_conv.
+
+2009-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/qr.cc: Remove HAVE_QRUPDATE check.
+	* DLD-FUNCTIONS/chol.cc: Ditto.
+
+2009-01-21  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (display.o): Add X11_INCFLAGS to CPPFLAGS.
+	(octave$(EXEEXT)): Link with X11_LIBS.
+
+	* display.h, display.cc: New files.
+	* graphics.cc (default_screendepth, default_screensize,
+	default_screenpixelsperinch): New functions.
+	* graphics.h.in (class root_figure::properties): New property,
+	screendepth.  Use default_screensize to initialize screensize
+	property.  Use default_screenpixelsperinch to initialize
+	screenpixelsperinch property.
+
+	* graphics.cc (properties::init): Set default xlabel, ylabel,
+	zlabel, and title properties that differ from default text
+	properties.
+
+2009-01-21  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* OPERATORS/op-range.cc: Define & register range-scalar ops.
+
+2009-01-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h (octave_value::subsref (..., bool auto_add)): New method.
+	(octave_value::next_subsref (bool auto_add, ...)): New method.
+	* ov.cc (octave_value::next_subsref (bool auto_add, ...)): New method.
+	* ov-base.h (octave_base_value::subsref (..., bool auto_add)): New
+	virtual method.
+	* ov-base.cc (octave_base_value::subsref (..., bool auto_add)): New
+	virtual method.
+	* ov-cell.cc (octave_cell::subsref (..., bool auto_add)): New virtual
+	method.
+	* ov-cell.h (octave_cell::subsref (..., bool auto_add)): Declare it.
+	* ov-struct.cc (octave_struct::subsref (..., bool auto_add)): New
+	virtual method.
+	(octave_struct::subsref (const std::string& type, const
+	std::list<octave_value_list>& idx)): Do not allow resizing.
+	* ov-struct.h (octave_struct::subsref (..., bool auto_add)): Declare
+	it.
+	* ov-struct.cc (octave_struct::dotref (..., bool auto_add)): New
+	virtual method.
+	* ov-struct.h (octave_struct::dotref (..., bool auto_add)): Declare it.
+	* pt-idx.cc (tree_index_expression::rvalue): Do not reevaluate already
+	evaluated part of the index chain.
+	(tree_index_expression::rvalue): Do not reevaluate already evaluated
+	part of the index chain. Do not actually perform trailing indexing. 
+	Do not allow indexing cs-lists.
+
+2009-01-20  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (Ffstat): New function.
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/qr.cc (Fqrupdate, Fqrinsert, Fqrdelete, Fqrshift):
+	Reflect changes in liboctave.
+	* DLD-FUNCTIONS/chol.cc (Fcholupdate, Fcholinsert):
+	Reflect changes in liboctave.
+
+2009-01-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h (octave_value::make_unique (int)): New method.
+	* oct-obj.h (octave_value_list::octave_value_list (const Cell&)): New
+	constructor.
+	* ov-cell.cc (octave_cell::subsasgn): Allow composed {} indexing
+	in multi-assignments. Optimize.
+	* ov-struct.cc (octave_struct::subsasgn): Correct composed {} indexing
+	in multi-assignments. Optimize & fix bugs.
+	* pt-idx.cc (tree_index_expression::lvalue): Rewrite to allow
+	specifying cs-list anywhere in index chain, be more robust.
+
+2009-01-19  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (grab_comment_block): If not reading input from a file,
+	bail out at first newline inside a comment.
+
+	* lex.l (lexer_debug_flag): New static variable.
+	(F__lexer_debug_flag__): New function.
+	(LEXER_DEBUG): New macro.  Use it in all patterns.
+	(DISPLAY_TOK_AND_RETURN): Also display token if lexer_debug_flag
+	is set.
+	(process_comment): Display comment if lexer_debug_flag is set.
+	(display_character, display_state, lexer_debug): New static functions.
+	(xunput): Display character if lexer_debug_flag is set.
+
+2009-01-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h: Describe usage of storable_value and make_storable_value.
+	* ov.cc: Remove FIXME comment.
+
+2009-01-15  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Freshape): Include mismatched dimensions in error message.
+	From Robert Millan <rmh at aybabtu.com>.
+
+2009-01-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.cc (octave_value::maybe_economize): New method.
+	(octave_value::non_null_value): rename to storable_value.
+	(octave_value::make_non_null_value): rename to make_storable_value.
+	* ov-base.h (octave_base_value::maybe_economize): New method.
+	* ov-base-mat.h (octave_base_mat::maybe_economize): New override.
+	* oct-obj.cc (octave_value_list::normalize_null_values):
+	Rename to make_storable_values, use make_storable_value.
+	* oct-obj.h: Ditto.
+	* ov-builtin.cc: non_null_value -> storable_value.
+	* ov-cell.cc: Ditto.
+	* ov-struct.cc: Ditto.
+	* pt-decl.h: Ditto.
+
+2009-01-15  Søren Hauberg  <hauberg at gmail.com>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (encode_uint_image):
+	Initialize bitdepth.
+
+2009-01-14  Søren Hauberg  <hauberg at gmail.com>
+
+	* DLD-FUNCTIONS/betainc.cc, DLD-FUNCTIONS/chol.cc,
+	DLD-FUNCTIONS/daspk.cc, DLD-FUNCTIONS/dasrt.cc,
+	DLD-FUNCTIONS/dassl.cc, DLD-FUNCTIONS/filter.cc,
+	DLD-FUNCTIONS/gammainc.cc, DLD-FUNCTIONS/gcd.cc,
+	DLD-FUNCTIONS/givens.cc, DLD-FUNCTIONS/hess.cc,
+	DLD-FUNCTIONS/lsode.cc, DLD-FUNCTIONS/qr.cc, DLD-FUNCTIONS/qz.cc,
+	DLD-FUNCTIONS/schur.cc, DLD-FUNCTIONS/svd.cc,
+	DLD-FUNCTIONS/syl.cc, data.cc, mappers.cc:
+	Use ifnottex instead of ifinfo.
+
+2009-01-14  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_set): Call do_clear after disabling
+	add_hook.
+
+2009-01-13  Jaroslav Hajek  <highegg at gmail.com>
+
+	* dirfns.cc (Freadddir): qsort -> sort.
+	* graphics.cc (maybe_set_children): Ditto.
+	* help.cc (simple_help): Ditto.
+	* input.cc (generate_possible_completions): Ditto.
+	* oct_map.cc (keys_ok): Ditto.
+	* ov-fcn-inline.cc (Finline): Ditto.
+	* variables.cc (Fisrawcommand): Ditto.
+
+2009-01-12  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (maximum_braindamage): Set confirm_recursive_rmdir to
+	false.
+
+	* strfns.cc (Fstrcmp, Fstrncmp): Simplify by initializing all
+	elements of output to false with constructor argument.
+
+2009-01-12  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* strfns.cc (Fstrncmp): New test.
+	
+2009-01-12  John W. Eaton  <jwe at octave.org>
+
+	* pt-stmt.h (tree_statement::is_null_statement): New function.
+	* parse.y (set_stmt_print_flag): Return list.  Remove trailing
+	null statements from list.
+	(list, simple_list): Simplify action.
+	(make_statement, make_statement_list, append_statement_list):
+	Always create statements and them to the list.
+
+	* base-list.h (octave_base_list::push_front,
+	octave_base_list::push_back, octave_base_list::pop_front,
+	octave_base_list::pop_back): New functions.
+
+	* DLD-FUNCTIONS/qr.cc (Fqrupdate, Fqrinsert, Fqrdelete, Fqrshift):
+	Require args to be numeric, not necessarily matrix objects.
+
+2009-01-12  Ben Abbott  <bpabbott at mac.com>
+
+	* graphics.h.in (text::properties::fontunits): Fix typo in list of
+	possible values.
+
+2009-01-12  John W. Eaton  <jwe at octave.org>
+
+	* strfns.cc (Fstrvcat, Fchar): Use queue to avoid duplicate calls
+	to all_strings.
+
+2009-01-12  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* strfns.cc (Fstrvcap): New function.
+	
+2008-11-29  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * strfns.cc (Fchar, Fischar, Fstrncmp, Flist_in_columns):
+	Improve documentation strings.  Add examples and tests.
+        
+2009-01-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-perm.cc (octave_perm_matrix::do_index_op): Return shallow copy
+	when indexed by (:,:).
+	* ov-base-mat.cc (octave_base_diag::do_index_op): Return shallow copy
+	when indexed by (:,:). Optimize indexing equivalent to resizing.
+	* data.cc: Fix tests.
+	* mappers.cc: Fix tests.
+
+2009-01-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-diag.h, ov-base-mat.h, ov-base-scalar.h, ov-base-sparse.h,
+	ov-base.cc, ov-base.h, ov-perm.h, ov-range.h, ov.h: Add full_value
+	methods to octave_value, octave_base_value and its relevant
+	subclasses.
+	* data.cc (Ffull): New DEFUN.
+	* DLD-FUNCTIONS/sparse.cc (Ffull): move to data.cc.
+2009-01-11  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* ov.h (octave_value::is_copy_of): New method.
+	* ov-struct.cc (numeric_conv): Add output parameter orig.
+	(octave_struct::subsasgn): Temporarily erase duplicate lhs value prior
+	to assignment.
+
+2009-01-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-obj.cc (octave_value_list::all_scalars): New method.
+	* oct-obj.h: Declare it.
+	* ov-cell.cc (octave_cell::subsasgn): Disable assigning
+	to non-scalar {}-indexed cell, unless in a multi-assignment.
+
+2009-01-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/sparse.cc (Ffull): Convert diagonal & permutation
+	matrices, leave other classes untouched.
+
+2009-01-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* OPERATORS/op-cdm-cdm.cc: Install missing widening op.
+	* OPERATORS/op-dm-dm.cc: Ditto.
+	* OPERATORS/op-fcdm-fcdm.cc: Ditto.
+	* OPERATORS/op-fdm-fdm.cc: Ditto.
+	* OPERATORS/op-pm-pm.cc: Ditto.
+	* OPERATORS/op-fpm-fpm.cc: Ditto.
+
+2009-01-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.cc (octave_cell::subsasgn): Put erased copy back after
+	make_unique has been called.
+
+2009-01-09  Kai Habel <kai.habel at gmx.de>
+
+        * graphics.cc: Calculate normals for surface boundaries, use
+        more neighboring points to calculate interior normals
+
+2009-01-09  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (get_user_input (void)): Don't increment input_line_number.
+	* lex.l (xunput): New function.  Use it in place of yyunput
+	anywhere a newline character may be put back on the input stream.
+	Increment input_line_number in all rules that consume newlines
+	characters.
+	(text_yyinput): Increment input_line_number
+	(fixup_column_count): Increment input_line_number.
+	(prep_for_function): Set input_line_number to 1, not 0.
+	(reset_parser): Set input_line_number to current_command_number,
+	not current_command_number-1.
+	(flex_stream_reader::ungetc): Call xunput, not yyunput.
+	* parse.y (input_line_number): Initialize to 1, not 0.
+	(text_getc): Increment input_line_number correctly.
+	(stdio_stream_reader::ungetc): Decrement input_line_number if
+	putting back a newline character.
+	(parse_fcn_file): Set input_line_number to 1, not 0.
+	(eval_string): Unwind-protect input_line_number and
+	current_input_column.
+
+	* parse.y (make_statement): New function.
+	(statement): Use it.
+	(make_statement_list, append_statement_list): New functions.
+	(simple_list1, list1): Use them.
+
+2009-01-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.cc (octave_cell::subsasgn): Erase duplicate lhs value 
+	prior to assignment to avoid a redundant copy.
+
+2008-12-26  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* mappers.cc (Ftoascii), mappers.cc (Ftolower), mappers.cc
+	(Ftoupper), DLD-FUNCTIONS/regexp.cc (Fregexp),
+	DLD-FUNCTIONS/regexp.cc	(Fregexpi), DLD-FUNCTIONS/regexp.cc
+	(Fregexprep): Add references.
+	
+2008-12-27  Jaroslav Hajek <highegg at gmail.com>
+
+	* oct-obj.h, oct-obj.cc (octave_value_list::valid_scalar_indices): Remove.
+	* ov-base-diag.cc, ov-base-diag.h, ov-base-scalar.cc, ov-base.h,
+	ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc, ov-bool-sparse.h,
+	ov-bool.cc, ov-bool.h, ov-ch-mat.cc, ov-ch-mat.h, ov-colon.h,
+	ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h,
+	ov-cx-sparse.cc, ov-cx-sparse.h, ov-float.cc, ov-float.h,
+	ov-flt-complex.cc, ov-flt-complex.h, ov-flt-cx-mat.cc,
+	ov-flt-cx-mat.h, ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h,
+	ov-perm.cc, ov-perm.h, ov-range.h, ov-re-mat.cc, ov-re-mat.h,
+	ov-re-sparse.cc, ov-re-sparse.h, ov-scalar.cc, ov-scalar.h,
+	ov-str-mat.cc, ov-str-mat.h, ov.h:
+	Remove valid_as_scalar_index and valid_as_zero_index methods
+	from octave_value, octave_base_value and all of its subclasses.
+
+2008-12-26  Francesco Potortì  <pot at gnu.org>
+
+	* data.cc (resize): Add cross reference to postpad.
+
+2008-12-25  Jaroslav Hajek <highegg at gmail.com>
+
+	* load-save.h (load_save_format_type, load_save_format_options): New
+	enums.
+	(load_save_format): Convert to a class.
+	* load-save.cc (do_save(..., const octave_value&,...)): Use fmt.type
+	in switch. Use options of LS_MAT_ASCII.
+	(do_load, write_header): Use format.type in switch.
+	* ls-mat-ascii.h (save_mat_ascii_data): Add tabs option.
+	* ls-mat-ascii.cc (save_mat_ascii_data): Implement it.
+
+2008-12-24  Ben Abbott  <bpabbott at mac.com>
+
+	* DLD-FUNCTIONS/chol.cc: Compare results to 0 in tests.
+	Delete spurious function calls in test block.
+
+2008-12-24  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/eigs.cc: Use "testif HAVE_ARPACK" to skip tests if
+	ARPACK is not available.
+
+	* Makefile.in (DLD_XSRC): Add eigs.cc to the list.
+
+	* load-save.cc (parse_save_options): Handle -double.
+
+2008-12-23  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/eigs.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it here.
+
+2008-12-22  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/__voronoi__.cc (F__voronoi__): Resize AtInf array
+	before returning it.
+
+2008-12-12  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/chol.cc (Fcholinv): Add test.
+
+2008-12-12  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ls-hdf5.cc (add_hdf5_data): Check for diagonal & permutation
+	matrices and convert them to full prior to saving.
+
+2008-12-11  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* ov-re-mat.cc (Fdouble): Handle diagonal & perm matrices. 
+	* ov-flt-re-mat.cc (Fsingle): Handle diagonal & perm matrices. 
+
+2008-12-11  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-diag.cc (octave_base_diag<DMT,MT>::subsasgn): New method.
+	* ov-base-diag.h (octave_base_diag<DMT,MT>::subsasgn): Declare it.
+	(octave_base_diag<DMT,MT>::chk_valid_scalar): New method decl.
+
+	* ov-re-diag.cc (octave_diag_matrix::chk_valid_scalar): New method
+	override.
+	* ov-re-diag.h: Declare it.
+	* ov-flt-re-diag.cc (octave_float_diag_matrix::chk_valid_scalar): New
+	method override.
+	* ov-flt-re-diag.h: Declare it.
+	* ov-cx-diag.cc (octave_complex_diag_matrix::chk_valid_scalar): New 
+	method override.
+	* ov-cx-diag.h: Declare it.
+	* ov-flt-cx-diag.cc (octave_float_complex_diag_matrix::chk_valid_scalar): 
+	New method override.
+	* ov-flt-cx-diag.h: Declare it.
+
+2008-12-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/expm.cc: Remove.
+	* Makefile.in: Update.
+
+2008-12-10  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_SCALAR_T::empty_clone): Construct an
+	empty matrix instead of zero.
+
+2008-12-07  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * mappers.cc (Ftolower): Make lower alias of tolower, add tests
+        * mappers.cc (Ftoupper): Make upper alias of toupper, add tests
+
+2008-12-09  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/balance.cc (Fbalance): Exploit the new AEPBAL functionality.
+
+2008-12-08  Jaroslav Hajek  <highegg at gmail.com>
+	
+	* xpow.cc ( xpow (const DiagMatrix& a, double b), 
+	xpow (const DiagMatrix& a, const Complex& b), 
+	xpow (const ComplexDiagMatrix& a, double b), 
+	xpow (const ComplexDiagMatrix& a, const Complex& b), 
+	xpow (const FloatDiagMatrix& a, float b), 
+	xpow (const FloatDiagMatrix& a, const FloatComplex& b), 
+	xpow (const FloatComplexDiagMatrix& a, float b), 
+	xpow (const FloatComplexDiagMatrix& a, const FloatComplex& b)):
+	New methods.
+	* xpow.h: Declare them.
+	* OPERATORS/op-dms-template.cc: Support diagonal matrix ^ scalar.
+
+2008-12-08  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-re-diag.cc (octave_diag_matrix::save_binary,
+	octave_diag_matrix::load_binary): New methods.
+	* ov-re-diag.h: Declare them.
+	* ov-flt-re-diag.cc (octave_float_diag_matrix::save_binary,
+	octave_float_diag_matrix::load_binary): New methods.
+	* ov-flt-re-diag.h: Declare them.
+	* ov-cx-diag.cc (octave_complex_diag_matrix::save_binary,
+	octave_complex_diag_matrix::load_binary): New methods.
+	* ov-cx-diag.h: Declare them.
+	* ov-flt-cx-diag.cc (octave_float_complex_diag_matrix::save_binary,
+	octave_float_complex_diag_matrix::load_binary): New methods.
+	* ov-flt-cx-diag.h: Declare them.
+	* ov-perm.cc (octave_perm_matrix::save_binary,
+	octave_perm_matrix::load_binary): New methods.
+	* ov-perm.h: Declare them.
+
+2008-12-06  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::load_binary): Call istream::get
+	rather than istream::read to supply null terminating character.
+
+2008-10-29  Jaroslav Hajek  <highegg at gmail.com>
+	* file-io.cc, gl-render.cc, load-save.cc, ls-hdf5.cc, ls-mat4.cc,
+	ls-mat5.cc, ls-oct-binary.cc, mex.cc, oct.h, ov-base-int.cc,
+	ov-bool-mat.cc, ov-bool-sparse.cc, ov-cell.cc, ov-class.cc,
+	ov-cx-mat.cc, ov-cx-sparse.cc, ov-fcn-handle.cc, ov-fcn-inline.cc,
+	ov-flt-cx-mat.cc, ov-flt-re-mat.cc, ov-re-mat.cc, ov-re-sparse.cc,
+	ov-str-mat.cc, ov-struct.cc, toplev.cc,
+	DLD-FUNCTIONS/__lin_interpn__.cc, DLD-FUNCTIONS/amd.cc,
+	DLD-FUNCTIONS/ccolamd.cc, DLD-FUNCTIONS/cellfun.cc,
+	DLD-FUNCTIONS/colamd.cc, DLD-FUNCTIONS/gcd.cc,
+	DLD-FUNCTIONS/matrix_type.cc, DLD-FUNCTIONS/regexp.cc,
+	DLD-FUNCTIONS/symbfact.cc, DLD-FUNCTIONS/symrcm.cc: 
+	Include oct-locbuf.h.
+
+2008-12-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base-diag.cc (save_ascii, load_ascii): Save natively.
+	* ov-base-diag.h (load_ascii): Declare.
+	* ov-perm.cc (save_ascii, load_ascii): Save natively.
+	* ov-perm.h (load_ascii): Declare.
+
+
+2008-12-04  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * strfns.cc (Fchar): Add test from str2mat.m
+        
+2008-12-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov.h (octave_value::is_perm_matrix): New method.
+	* ov-base.h (octave_base_value::is_perm_matrix): New method.
+	* ov-perm.h (octave_perm_matrix::is_perm_matrix): New method.
+	* DLD-FUNCTIONS/inv.cc (Finv): Handle permutation matrices specially,
+	compute rcond for diagonal matrices.
+	* DLD-FUNCTIONS/det.cc (Fdet): Handle permutation & diagonal matrices
+	specially.
+
+2008-12-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-perm.h: New source.
+	* ov-perm.cc: New source.
+	* ov-flt-perm.h: New source.
+	* ov-flt-perm.cc: New source.
+	* ov-base-diag.cc (octave_base_diag<DMT, MT>::do_index_op):
+	If subscripting an identity matrix by permutation(s), return a
+	permutation matrix object.
+	* ov.cc (octave_value::octave_value (const PermMatrix&)): New
+	constructor.
+	* ov.cc (octave_value::octave_value (const PermMatrix&)): Declare it.
+	* op-cm-pm.cc: New source.
+	* op-fcm-fpm.cc: New source.
+	* op-fm-fpm.cc: New source.
+	* op-fpm-fcm.cc: New source.
+	* op-fpm-fm.cc: New source.
+	* op-fpm-fpm.cc: New source.
+	* op-m-pm.cc: New source.
+	* op-pm-cm.cc: New source.
+	* op-pm-m.cc: New source.
+	* op-pm-pm.cc: New source.
+	* op-pm-template.cc: New source.
+	* Makefile.in: Include new sources.
+	* DLD-FUNCTIONS/qr.cc (Fqr): Reflect interface changes of QR classes.
+
+2008-12-03  John W. Eaton  <jwe at octave.org>
+
+	* debug.cc (bp_table::do_get_breakpoint_list): Style fixes.
+
+2008-12-01  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base.h (octave_base_value::is_diag_matrix): New virtual method.
+	* ops.h (CONCAT2, CONCAT3): New macros. Use CONCAT macros instead of 
+	direct token pasting to avoid disabling argument prescan.
+	* xdiv.cc, xdiv.h: Implement xdiv and xleftdiv overloads for diagonal
+	and mixed dense-diagonal operands.
+
+	* ov-re-diag.h: New source.
+	* ov-re-diag.cc: New source.
+	* ov-flt-re-diag.h: New source.
+	* ov-flt-re-diag.cc: New source.
+	* ov-base-diag.h: New source.
+	* ov-base-diag.cc: New source.
+	* OPERATORS/op-m-dm.cc: New source.
+	* OPERATORS/op-m-cdm.cc: New source.
+	* OPERATORS/op-fm-fdm.cc: New source.
+	* OPERATORS/op-fm-fcdm.cc: New source.
+	* OPERATORS/op-fdm-fs.cc: New source.
+	* OPERATORS/op-fdm-fm.cc: New source.
+	* OPERATORS/op-fdm-fdm.cc: New source.
+	* OPERATORS/op-fdm-fcs.cc: New source.
+	* OPERATORS/op-fdm-fcm.cc: New source.
+	* OPERATORS/op-fdm-fcdm.cc: New source.
+	* OPERATORS/op-fcm-fdm.cc: New source.
+	* OPERATORS/op-fcm-fcdm.cc: New source.
+	* OPERATORS/op-fcdm-fs.cc: New source.
+	* OPERATORS/op-fcdm-fm.cc: New source.
+	* OPERATORS/op-fcdm-fdm.cc: New source.
+	* OPERATORS/op-fcdm-fcs.cc: New source.
+	* OPERATORS/op-fcdm-fcm.cc: New source.
+	* OPERATORS/op-fcdm-fcdm.cc: New source.
+	* OPERATORS/op-dms-template.cc: New source.
+	* OPERATORS/op-dm-template.cc: New source.
+	* OPERATORS/op-dm-s.cc: New source.
+	* OPERATORS/op-dm-m.cc: New source.
+	* OPERATORS/op-dm-dm.cc: New source.
+	* OPERATORS/op-dm-cs.cc: New source.
+	* OPERATORS/op-dm-cm.cc: New source.
+	* OPERATORS/op-dm-cdm.cc: New source.
+	* OPERATORS/op-cm-dm.cc: New source.
+	* OPERATORS/op-cm-cdm.cc: New source.
+	* OPERATORS/op-cdm-s.cc: New source.
+	* OPERATORS/op-cdm-m.cc: New source.
+	* OPERATORS/op-cdm-dm.cc: New source.
+	* OPERATORS/op-cdm-cs.cc: New source.
+	* OPERATORS/op-cdm-cm.cc: New source.
+	* OPERATORS/op-cdm-cdm.cc: New source.
+	* Makefile.in: Include them.
+
+	* ov-re-mat.cc (octave_matrix::diag): New method override.
+	* ov-re-mat.h: Declare it.
+	* ov-cx-mat.cc: Likewise with octave_complex_matrix.
+	* ov-cx-mat.h: Likewise with octave_complex_matrix.
+	* ov-flt-re-mat.cc: Likewise with octave_float_matrix.
+	* ov-flt-re-mat.h: Likewise with octave_float_matrix.
+	* ov-flt-cx-mat.cc: Likewise with octave_float_complex_matrix.
+	* ov-flt-cx-mat.h: Likewise with octave_float_complex_matrix.
+	* ov.cc (octave_value::octave_value (const DiagMatrix&))
+	(octave_value::octave_value (const FloatDiagMatrix&))
+	(octave_value::octave_value (const ComplexDiagMatrix&))
+	(octave_value::octave_value (const FloatComplexDiagMatrix&)):
+	Construct a diagonal matrix object.
+	* data.cc (Fdiag): Support explicit dimensions. Fix tests.
+	(Feye): Return diagonal matrix objects if possible. Fix tests.
+	* mappers.cc (Freal, Fimag): Fix tests.
+	* DLD-FUNCTIONS/inv.cc (Finv): Handle diagonal matrix objects.
+	* ov-range.h (octave_range::diag): Declare only.
+	* ov-range.cc (octave_range::diag): Return DiagMatrix if possible.
+
+2008-11-25  Jaroslav Hajek  <highegg at gmail.com>
+	* ov.cc (octave_value::is_equal): New member function.
+	* ov.h: Declare it.
+	* pt-select.cc (tree_switch_case::label_matches): Call
+	octave_value::is_equal.
+
+2008-12-04  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* DLD-FUNCTIONS/cellfun.cc: Added more tests for cellfun.
+
+2008-11-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base.h (octave_base_value::type_conv_info): New class.
+	* ov-base.h, ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc,
+	ov-bool-sparse.h, ov-bool.cc, ov-bool.h, ov-complex.cc, ov-complex.h,
+	ov-cx-mat.cc, ov-cx-mat.h, ov-null-mat.cc, ov-null-mat.h,
+	ov-range.cc, ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-scalar.cc,
+	ov-scalar.h, ov-str-mat.cc, ov-str-mat.h, ov.h:
+	Return type_conv_info instead of type_conv_fcn from
+	numeric_conversion_function and numeric_demotion_function
+	methods.
+	* ov-base.cc (octave_base_value::numeric_assign): Try biased conversion
+	first if possible.
+	* ov.cc (do_binary_op): Likewise. Also, search recursively.
+	* ov.cc (do_cat_op): Likewise.
+
+2008-11-24  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (F__go_delete__): Check validity of handles before
+	deleting them to avoid issues with callback function also deleting
+	the handles.
+	
+2008-11-21  John Swensen  <jpswensen at comcast.net> 
+
+	* debug.cc (bp_table::do_get_breakpoint_list): Avoid modifying
+	bp_map while iterating over it.
+
+2008-11-21  Jarkko Kaleva  <d3roga at gmail.com>
+
+	* DLD-FUNCTIONS/eig.cc (Feig): Handle generalized eigenvalues and 
+	eigenvectors.
+
+2008-11-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD_FUNCTIONS/det.cc: Include only DET.h. Retrieve & matrix type &
+	store it after calculation if possible.
+
+2008-11-17  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::dir_info::update): Simplify previous
+	change.
+
+	* load-path.h (load_path::dir_info::abs_dir_name): New data member.
+	(load_path::dir_info::dir_info, load_path::dir_info::operator =):
+	Copy abs_dir_name.
+	(load_path::abs_dir_cache_type, load_path::dir_cache_iterator,
+	load_path::const_dir_cache_iterator): New typedefs.
+	(load_path::abs_dir_cache): New static data member.
+	(load_path::dir_info:dir_info): New constructor.
+	* load-path.cc (load_path::abs_dir_cache): Define new static data
+	member.
+	(load_path::dir_info::update): Look in abs_dir_cache for relative
+	directory names.
+	(load_path::dir_info::initialize): Update abs_dir_cache here.
+
+2008-11-13  John W. Eaton  <jwe at octave.org>
+
+	* ov-int8.h, ov-int16.h, ov-int32.h, ov-int64.h, ov-uint8.h,
+	ov-uint16.h, ov-uint32.h, ov-uint64.h: Don't define
+	OCTAVE_INT_NDARRAY_T.
+	* ov-intx.h (class OCTAVE_VALUE_INT_MATRIX_T,
+	class OCTAVE_VALUE_INT_SCALAR_T): Use intNDArray<OCTAVE_INT_T>
+	instead of OCTAVE_INT_NDARRAY_T.
+	(OCTAVE_VALUE_INT_MATRIX_T::increment,
+	OCTAVE_VALUE_INT_MATRIX_T::decrement,
+	OCTAVE_VALUE_INT_SCALAR_T::increment,
+	OCTAVE_VALUE_INT_SCALAR_T::decrement): Convert 1 to OCTAVE_INT_T.
+
+2008-11-15  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+        * strfns.cc (Fchar): adapt to conserve empty strings, add tests
+        
+2008-11-12  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* dirfcn.cc (Ffilesep): Make it return all file separators when 'all'
+	is given as argument.
+
+	* DLD-FUNCTIONS/getrusage.cc: Undefine min/max.
+	* TEMPLATE-INST/Array-os.cc: Declare Array<bool> as extern template.
+
+2008-11-12  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-cell.cc (op_catop_matrix_cell): Cast args in the correct
+	order.
+	* OPERATORS/op-struct.cc (op_catop_matrix_struct): Ditto.
+
+2008-11-11  Jaroslav Hajek <highegg at gmail.com>
+
+	* pt-assign.cc: Fix handling of empty cs-lists in assignment LHS.
+
+2008-11-11  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (<MATRIX_START>{S}+): Don't insert separator if next token
+	is a separator.
+
+	* parse.y (F__parser_debug_flag__): New function.
+
+2008-10-31  Jaroslav Hajek <highegg at gmail.com>
+
+	* xnorm.cc: New source.
+	* xnorm.h: New header file.
+	* Makefile.in: Include xnorm.cc in the build process.
+	* data.cc (Fnorm): Call xnorm, xcolnorms, xrownorms or xfrobnorm
+	to do the actual work.
+
+
+2008-10-31  David Bateman  <dbateman at free.fr>
+
+	* ov-base-scalar.h (octave_value octave_base_scalar::reshape 
+	(const dim_vector&) const): New method.
+
+2008-10-30  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.cc (Octave_map::index): Copy key_list.
+
+2008-10-31  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (void image::init (void)): Add a constraint for
+	logical cdata.
+	
+	* graphics.h.in (base_property::delete_listener): New method.
+	(property::delete_listener): New method.
+	(base_graphics_object::delete_listener): New method.
+	(base_graphics_object::delete_property_listener): New method.
+	(base_graphics_object::remove_all_listeners): New method.
+	(graphics_object::delete_property_listener): New method.
+	(axes::set_defaults): Call remove_all_listeners.
+	* graphics.cc (void base_properties::delete_listener): New method
+	(void base_graphics_object::remove_all_listeners (void)): New method
+	(Fdellistener): New command to remove listener functions associated
+	with a property.
+	
+2008-10-30  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (axes::properties): Add keyreverse property.
+	* graphics.cc (axes::properties::set_defaults): Initialize
+	keyreverse property.
+
+2008-10-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* Cell.h (Cell::assign (const Array<idx_vector>&, ...),
+	Cell::delete_elements (const Array<idx_vector>&, ...)):
+	New member functions.
+	* Cell.cc (Cell::assign (const octave_value_list&, ...),
+	Cell::delete_elements (const octave_value_list&, ...)):
+	Call Array<T>::assign.
+	* DLD-FUNCTIONS/dlmread.cc: Call Array<T>::resize_fill.
+	* ov-base-mat.cc (octave_base_matrix::assign): Call Array<T>::assign.
+	(octave_base_matrix::delete_elements):: Call Array<T>::delete_elements.
+	* ov-cell.cc (Fcell): Call Array<T>::chop_trailing_singletons,
+	simplify.
+	* ov-cx-mat.cc (octave_complex_matrix::assign): Call Array<T>::assign.
+	* ov-flt-cx-mat.cc (octave_float_complex_matrix::assign): Call
+	Array<T>::assign.
+	* ov-list.cc (octave_list::subsasgn): Call Array<T>::assign.
+	* pr-output.cc (PRINT_ND_ARRAY): Use zero-based indices.
+
+
+2008-10-29  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* data.cc (Fcolumns): Remove "and" from @seealso string.
+	* mappers.cc (Fgamma, Flgamma): Replace @seealso reference to
+	deprecated gammai by gammainc.
+	* DLD-FUNCTIONS/sqrtm.cc (Fsqrtm): Remove reference to Octave
+	Forge function funm.
+	* DLD-FUNCTIONS/qz.cc (Fqz): removed @seealso reference to Octave
+	Forge function dare.
+	* DLD-FUNCTIONS/rcond.cc (Frcond): removed @seealso reference to
+	mldivide.
+	* debug.cc (Fdbstop): Fix @seealso references and function name in
+	docstring of dbnext.
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun): Remove @seealso reference
+	to isclass.
+	* syscalls.cc (Fwaitpid): Replace WCONTINUED by WCONTINUE.
+	* oct-hist.cc (Fhistory_size, Fsaving_history): Fix @seealso
+	references to history_timestamp_format_string.
+	* DLD-FUNCTIONS/luinc.cc (Fluinc): Remove reference to missing
+	function cholinc.
+        
+2008-10-29  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/qr.cc (Fcholinsert, Fcholdelete, Fcholshift): Fix
+	inline docs.
+
+2008-10-28  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (finish_function): Clear local variables in function scope.
+	* symtab.h (symbol_table::clear_variables): New argument, scope.
+
+2008-10-28  Brian Gough  <bjg at gnu.org>
+
+	* DLD-FUNCTIONS/besselj.cc: Added tests.
+
+2008-10-23  John W. Eaton  <jwe at octave.org>
+
+	* oct-hist.c (initialize_history): New arg, read_history_file)
+	* oct-hist.h: Fix decl.
+	* octave.cc (octave_main): Set read_history_file to false if
+	--no-history option is specified.  Pass read_history_file to
+	initialize_history.
+
+	* DLD-FUNCTIONS/fltk_backend.cc: Update initialization comment.
+
+2008-10-22  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fltk_backend.cc (figure_manager::do_close_all):
+	Rename from close_all.  Now private.
+	(figure_manager::do_new_window): Rename from new_window.
+	Now private.
+	(figure_manager::do_delete_window): Rename from delete_window.
+	Now private.
+	(figure_manager::do_mark_modified): Rename from mark_modified.
+	Now private.
+	(figure_manager::do_get_size): Rename from get_size.  Now private.
+	(figure_manager::close_all, figure_manager::do_new_window, 
+	figure_manager::do_delete_window,
+	figure_manager::do_mark_modified, figure_manager::do_get_size):
+	New static functions.
+	(figure_manager::instance_ok): New function.
+	(figure_manager::Instance): Delete.  Eliminate all uses in favor
+	of static methods that call instance_ok and forward to private
+	member functions.
+	(figure_manager::instance): New static data member.
+	(figure_manager::hnd2idx, figure_manager::figprops2idx,
+	figure_manager::figprops2idx, figure_manager::str2idx): Now static.
+
+	* DLD-FUNCTIONS/fltk_backend.cc (figure_manager::default_size):
+	Increase default window size.
+
+	* graphics.cc (figure::properties::remove_child): New function.
+	* graphics.h.in: Provide decl.
+
+	* gl-render.cc (opengl_renderer::draw): Get all children.
+
+	* DLD-FUNCTIONS/fltk_backend.cc (__fltk_redraw__):
+	Check for "root" object, not "root_figure".
+
+	* graphics.h.in (base_properties::get_all_children): New function.
+
+2008-10-22  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (line::properties, surface::properties): Add data
+	source properties.
+
+2008-10-21  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (axes::properties::delete_children): Delete decl.
+
+	* graphics.h.in (gh_manager::is_handle_visible): New function.
+	(axes::properites): Move title property after label properties.
+	(graphics_object::is_handle_visible): New function.
+	(base_properties::is_handle_visible): New function.
+	(base_properties): Mark children property with G.
+	* graphics.cc (axes::properties::set_text_child): New function.
+	(axes::properties::set_title, axes::properties::set_xlabel,
+	axes::properties::set_ylabel, axes::properties::set_zlabel): Use it.
+	(base_property::get_children): New function.  Only
+	return handles that are visible.
+	(axes::properties::delete_text_child): Set handlevisibility to
+	"off" for newly created object and add it to the list of children.
+	Call base_properties::remove_child on previous handle value.
+	(axes::properties::set_defaults): Don't explicitly delete xlabel,
+	ylabel, zlabel, and title handles.  Reinitialize them after
+	deleting children.
+	(axes::properties::remove_child): Don't explicitly delete xlabel,
+	ylabel, zlabel, and title handles.
+	(axes::properties::init): Move here from graphics.h.in.  Set
+	handlevisibility to "off" for xlabel, ylabel, zlabel, and title
+	and add them to the list of children.
+	(axes::properties::delete_children): Delete.
+
+	* genprops.awk: Allow whitespace between BEGIN_PROPERTIES and
+	opening paren.  Accept optional second argument for graphics
+	object name.
+	* graphics.h.in (root_figure properties): Pass "root" as second
+	arg to BEGIN_PROPERTIES.
+
+2008-10-16  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (make_handle_fraction): New static function.
+	(gh_manager::get_handle): Use it.
+	(gh_manager::do_free): Call make_handle_fraction to replace
+	fractional part of non-figure handles.
+
+	* graphics.cc (base_properties::remove_child): Handle children as
+	a column vector instead of a row vector.
+
+	* utils.cc (Fis_absolute_filename, Fis_rooted_relative_filename,
+	Fmake_absolute_filename, Ffind_dir_in_path): New functions.
+
+2008-10-16  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (void axes::properties::set_defaults 
+	(base_graphics_object&,	const std::string&)): Preserve font
+	and position properties if the axis is "replaced".
+
+2008-10-16  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (class axes::properties): New property: interpreter.
+
+2008-10-15  David Bateman  <dbateman at free.fr>
+
+	* ov-class.c (Fsuperiorto, Finferiorto): Allow more than one class
+	to be defined at a time.
+
+2008-10-12  David Bateman  <dbateman at free.fr>
+
+	* pt-colon.cc (octave_value tree_colon_expression::make_range 
+	(const octave_value&, const octave_value&, const octave_value&)):
+	Treating class overloading of colon operator.
+	(octave_value tree_colon_expression::rvalue (void)): Ditto.
+
+2008-10-10  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (base_properties::adopt): Place new child at front
+	of list, not end.  Make list of children a column vector instead
+	of a row vector.
+
+	* graphics.cc (gh_manager::do_free): Set the beingdeleted
+	property, then delete the children, then execute the deletefcn.
+	(axes::properties::set_defaults, axes::properties::remove_child,
+	axes::properites::delete_children): Call delete_text_child to
+	manage the title, xlabel, ylabel, and zlabel properties.
+	(axes::properties::get_title, axes::properties::get_xlabel,
+	axes::properties::get_ylabel, axes::properties::get_zlabel): Delete.
+
+	* graphics.h.in (axes::properites::title,
+	axes::properites::xlabel, axes::properites::ylabel,
+	axes::properites::zlabel): No longer mutable.  Don't generate
+	factory default values or custom get functions for these
+	properties.
+
+	* graphics.cc (axes::properties::delete_text_child): New function.
+	* graphics.h.in: Provide decl.
+
+	* graphics.h.in (graphics_object::type): New function.
+
+2008-10-10  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (radio_property axes::properties::__colorbar__):
+	Delete.
+	* graphics.cc (void axes::properties::sync_positions (void)):
+	Disable code synchronizing outerposiiton and position.
+	(void axes::properties::set_defaults (base_graphics_object&,
+	const std::string&): Remove __colorbar__.
+	(F__go_delete__): Don't delete if already being deleting to avoid
+	recursion in callback functions.
+	(F__go_axes_init__): Flag error if handle is deleted during
+	initialization due.
+	
+2008-10-09  David Bateman  <dbateman at free.fr>
+
+	* ov-class.cc (Octave_map octave_class::map_value (void) const): 
+	Remove.
+	(bool octave_class::save_ascii (std::ostream&), 
+	bool octave_class::load_ascii (std::istream&),
+	bool octave_class::save_binary (std::ostream&, bool&),
+	bool octave_class::save_binary (std::ostream&, bool&),
+	bool octave_class::save_hdf5 (hid_t, const char *, bool),
+	bool octave_class::load_hdf5 (hid_t, const char *, bool)):
+	Allow saving and reloading of classes.
+	* ov-class. (Octave_map octave_class::map_value (void) const): 
+	Remove.
+	* ls-mat.cc (std::string read_mat5_binary_element (std::istream&, 
+	const std::string&, bool, bool&, octave_value&), 
+	int save_mat5_element_length (const octave_value&, const std::string&,
+	bool, bool)): Allow saving and loading of classes. 
+	* ls-oct-ascii.h (template <class T> bool extract_keyword 
+	(std::istream&, const char *, T&, const bool)): Initialize value with
+	null constructor rather than 0.
+	
+2008-10-07  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (F__go_delete__): Allow arrays of graphic handles.
+
+2008-10-01  Jaroslav Hajek <highegg at gmail.com>
+
+	* OPERATORS/op-i64-i64.cc: Instantiate all 64-bit operations.
+	* OPERATORS/op-ui64-ui64.cc: Instantiate all unsigned 64-bit operations.
+
+2008-10-06  John W. Eaton  <jwe at octave.org>
+
+	* ov-type-conv.h (octave_type_conv_body): Avoid shadow warning
+	from GCC.
+
+2008-10-06  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (static bool is_handle (const octave_value&)): Delete.
+	(static octave_value is_handle (const octave_value&)): New function.
+
+2008-10-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Cell.cc (Cell::delete_elements): Don't pass second arg to
+	Array<T>::maybe_delete_elements.
+	* ov-base-mat.cc (octave_base_matrix<MT>::delete_elements): Ditto.
+
+2008-10-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Cell.h (Cell::delete_elements): Declare new member function.
+	* Cell.h (Cell::delete_elements): Define it.
+	* oct-map.cc (Octave_map::maybe_delete_elements): Call delete_elements
+	instead of assign with empty Cell.
+
+2008-10-02  John W. Eaton  <jwe at octave.org>
+
+	* pt-arg-list.cc (tree_argument_list::convert_to_const_vector):
+	Don't insert undefined elements in return list.
+
+2008-09-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-str-mat.h (octave-char-matrix-str::assign): Remove declaration.
+	* ov-str-mat.cc (octave-char-matrix-str::assign): Remove definition.
+
+2008-09-30  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__magick_read__.cc: Only define
+	magick_to_octave_value if HAVE_MAGICK is defined.
+
+2008-09-29  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::load_class_method):
+	Call load_class_constructor if name and dispatch_type are the same.
+
+2008-09-29  David Bateman  <dbateman at free.fr>
+
+	* symtab.cc (octave_value symbol_table::find_function 
+	(const std::string&, tree_argument_list *, const string_vector&,
+	octave_value_list&, bool&)): If first character of function name
+	is "@" then look for class specific method.
+
+2008-09-26  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (out_of_date_check_internal):
+	Fix order of arguments in call to load_path::find_method.
+
+2008-09-26  David Bateman  <dbateman at free.fr>
+
+	* ov-class.h (idx_vector index_vector (void) const): Declare new
+	maethod.
+	* ov-class.cc (idx_vector index_vector (void) const): Define new
+	method.
+	* (Fismethod): New function.
+
+2008-09-26  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/urlwrite.cc (urlwrite_cleanup_file) New function.
+	(urlwrite_delete_file, urlwrite_filename): New static variables.
+	(Furlwrite): Only return filename if urlget succeeds.  Use
+	unwind_protect to delete files we create if download fails.
+
+2008-09-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-null-mat.h: New header file.
+	* ov-null-mat.cc: New source.
+	* ov.h (octave_value::is_null_value, octave_value::non_null_value,
+	octave_value::make_non_null_value):
+	Declare new member functions.
+	* ov.cc (octave_value:non_null_value, octave_value::make_non_null_value): 
+	Define them.
+	(octave_value::assign (assign_op op, const octave_value& rhs)): 
+	(register_types): Register null types.
+	Call non_null_value ().
+	* oct-obj.cc (octave_value_list::normalize_null_values): New member
+	function. 
+	* oct-obj.h (octave_value_list::normalize_null_values): Declare it.
+	* ov-base.h (is_null_value): New virtual member function.
+	* ops.h (NULLASSIGNOPDECL, DEFNULLASSIGNOP_FN): New macros.
+	* ov-base-mat.cc (octave_base_mat<MT>::delete_elements): New member func.
+	* ov-base-mat.h: Declare it.
+	* ov-base-sparse.cc (octave_base_sparse<MT>::delete_elements): New member func.
+	* ov-base-sparse.h: Declare it.
+	* ov-cell.cc (octave_cell:subsasgn): Handle null values.	
+	* ov-struct.cc (octave_cell:subsasgn): Handle null values.
+	* ov-builtin.cc (octave_builtin::do_multi_index_op): Normalize return
+	values.
+	* pt-misc.cc (tree_parameter_list::define_from_arg_vector): Call
+	octave_lvalue::define instead of octave_lvalue::assign.
+	* pt-decl.h (tree_decl_elt::rvalue): Call non_null_value ().
+	* OPERATORS/op-int.h (OCTAVE_INT_NULL_ASSIGN_OPS,
+	OCTAVE_INSTALL_INT_NULL_ASSIGN_OPS): New macros.
+	* OPERATORS/op-m-m.cc: Install & define assignment & conversion operators.
+	* OPERATORS/op-bm-bm.cc: Ditto.
+	* OPERATORS/op-cell.cc: Ditto.
+	* OPERATORS/op-cm-cm.cc: Ditto.
+	* OPERATORS/op-cs-cs.cc: Ditto.
+	* OPERATORS/op-fcm-fcm.cc: Ditto.
+	* OPERATORS/op-fcs-fcs.cc: Ditto.
+	* OPERATORS/op-fm-fm.cc: Ditto.
+	* OPERATORS/op-fs-fs.cc: Ditto.
+	* OPERATORS/op-int.h: Ditto.
+	* OPERATORS/op-m-m.cc: Ditto.
+	* OPERATORS/op-range.cc: Ditto.
+	* OPERATORS/op-s-s.cc: Ditto.
+	* OPERATORS/op-scm-scm.cc: Ditto.
+	* OPERATORS/op-sm-sm.cc: Ditto.
+	* OPERATORS/op-str-str.cc: Ditto.
+	* OPERATORS/op-i16-i16.cc: Ditto.
+	* OPERATORS/op-i32-i32.cc: Ditto.
+	* OPERATORS/op-i64-i64.cc: Ditto.
+	* OPERATORS/op-i8-i8.cc: Ditto.
+	* OPERATORS/op-ui16-ui16.cc: Ditto.
+	* OPERATORS/op-ui32-ui32.cc: Ditto.
+	* OPERATORS/op-ui64-ui64.cc: Ditto.
+	* OPERATORS/op-ui8-ui8.cc: Ditto.
+
+2008-09-25  David Bateman  <dbateman at free.fr>
+
+	* pt-mat.cc (class tm_row_const): Add any_class test
+	(class tm_const): Ditto.
+	(octave_value tree_matrix::rvalue (void)): If any object to
+	concatenate is a class object, dispatch to the appropriate
+	vertcat/horzcat function.
+
+2008-09-25  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_table::do_find): Don't set evaluated_args and
+	args_evaluated here, prior to call to symbol_table::fcn_info::find.
+
+2008-09-24  Søren Hauberg  <hauberg at gmail.com>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (magick_to_octave_value): New
+	template function with specializations for various
+	GraphicsMagick++ types.
+	(F__magick_finfo__): New function.
+
+2008-09-24  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Add symbol_table::clear_variables cleanup function to the
+	unwind_protect stack after the parameter list cleanup functions.
+
+	* load-path.cc (load_path::do_initialize): Check for OCTAVE_PATH
+	in the environment, not OCTAVE_LOADPATH.
+
+2008-09-24  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp_list): Retry if match limit
+	is exceeded.
+
+2008-09-24  John W. Eaton  <jwe at octave.org>
+
+	* genprops.awk (emit_declarations): Emit call to set_mode before
+	updaters.
+
+2008-09-23  John W. Eaton  <jwe at octave.org>
+
+	* pt-arg-list.cc (F__end__): Dispatch to user-defined end
+	function for classes if one is defined.
+	* lex.l (is_keyword_token): Allow "end" as a functon name.
+
+2008-09-23  David Bateman  <dbateman at free.fr>
+
+	* variables.cc (static octave_value do_who (int, const string_vector&,
+	bool, bool, std::string): Add final message argument and simple
+	treatment of the "-file" option.
+
+2008-09-22  David Bateman  <dbateman at free.fr>
+
+	* debug.cc (static octave_user_code * get_user_code 
+	(const std::string&)): Only check user code as break points can't
+	be set in builtins or oct-files.
+	(bp_table::intmap bp_table::do_remove_all_breakpoints_in_file 
+	(const std::string&, bool)): Add flag to silence the error message 
+	from this function if a user code with breakpoints is not found.
+	(bp_table::fname_line_map bp_table::do_get_breakpoint_list (const 
+	octave_value_list&)): Do an ourt of date check on the function
+	before checking the breakpoints.
+	* debug.h (do_remove_all_breakpoints_in_file, 
+	remove_all_breakpoints_in_file): Add flag to silence error
+	message.
+	* symtab.cc (out_of_date_check_internal): Clear breakpoints in
+	function if out_of_date. split into two versions taking the 
+	octave_function pointer seperately or not.
+	* symtab.h (bool out_of_date_check (octave_function*)): New function.
+	
+2008-09-18  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/fftw.cc (Ffftw): Clarify the documentation.
+
+2008-09-17  Krzesimir Nowak  <qdlacz at gmail.com>
+
+	* debug.cc (Fisdebugmode): New function.
+
+2008-09-17  David Bateman  <dbateman at free.fr>
+
+	* data.cc (do_cat): Chopping trailing singleton dimensions.
+
+	* data.cc (SINGLE_TYPE_CONCAT, DO_SINGLE_TYPE_CONCAT): New macros
+	(do_cat): Special case single type concatenations for speed.
+	* pt.mat.cc (std::string get_concat_class (const std::string&,
+	const std::string&), void maybe_warn_string_concat (bool, bool)):
+	Remove static declaration.
+	* pt-mat.h (std::string get_concat_class (const std::string&,
+	const std::string&), void maybe_warn_string_concat (bool, bool)):
+	Define extern here.
+	
+	* DLD-FUNCTIONS/sparse.cc (Fsparse): Clarify the help string.
+
+2008-09-10  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (octave_main): Make all command-line arguments
+	available to startup scripts and PKG_ADD files.
+
+2008-09-09  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp_list): Distinguish between
+	matlab named tokens and perl lookbehind expressions. For
+	lookbehind expression replace "*" and "+" with a limited number of
+	fixed length expressions to simulate arbitrary length look behind.
+
+2008-09-08  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (encode_uint_image): Resolve "pow"
+	ambiguity.
+
+	* graphics.cc (base_properties::get_dynamic,
+	base_properties::set_dynamic, base_propertyes::get_property_dynamic):
+	Add the 3rd template parameter to std::map, corresponding to all_props
+	field.
+
+2008-09-08  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.cc (std::string extract_keyword (std::istream&,
+	const char *, const bool)): Also accept \r as line ending character.
+	* ls-oct-ascii.h (template <class T> bool extract_keyword
+	(std::istream&, const char *, T&, const bool)): Likewise.
+	(template <class T> bool extract_keyword (std::istream&, const
+	string_vector&, std::string&, T&, const bool)): Likewise.
+
+2008-09-03  Ben Abbott  <bpabott at mac.com>
+
+	* mappers.cc: Use eps(single) as tolerance for single precesion test.
+
+2008-09-03  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (mlock): Lock current function on the call stack.
+	(Fmlock): Lock caller.
+
+	* symtab.cc (out_of_date_check_internal): If dispatch type is set,
+	check for method.  If that fails, check for regular function. 
+
+2008-09-02  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.cc (hggroup::update_axis_limits): Also reacts on
+	[xyzac]liminclude changes.
+
+2008-08-31  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* DLD-FUNCTIONS/fltk_backend.cc (fltk_backend::redraw_figure,
+	fltk_backend::print_figure): Change graphics_handle argument to
+	graphics_object.
+
+2008-08-29  David Bateman  <dbateman at free.fr>
+
+	* src/graphics.cc: Replace int by octave_idx_type in multiple
+	places.
+	(array_property::is_equal): In macro CHECK_ARRAY_EQUAL, special
+	case scalar case and keep copy of array value to avoid early
+	destruction of converted array values.
+	
+2008-08-28  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (root_figure::properties::showhiddenhandles):
+	New property.
+
+2008-08-27  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Initialize output vectors 
+	by NA value.
+
+2008-08-26 Ben Abbott  <bpabott at mac.com>
+
+	* mappers.cc: Adjust tolerance for single precesion tests.
+
+	* DLD-FUNCTIONS/chol.cc: Double tolerance.
+
+2008-08-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* parse.y (Fassignin): Use default  scope when calling varref.
+
+2008-08-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* genprops.awk (emit_declarations): Call updaters/listeners only when
+	'set' method returned true.
+	* graphics.h.in (base_property::set, base_property::do_set):
+	Return bool value.
+	(property::set): Likewise.
+	(string_property::do_set): Check value change and return bool value.
+	(radio_property::do_set, double_property::do_set,
+	array_property::do_set): Likewise.
+	(color_property::do_set, double_radio_property::do_set,
+	row_vector_property::do_set, bool_property::do_set,
+	handle_property::do_set): Return bool value.
+	(any_property::do_set, callback_property::do_set): Return always true.
+	(color_values::operator==, color_values::operator!=): Add.
+	(array_property::is_equal): Add.
+	* graphics.cc (base_property::set): Executes listeners/notifiers only
+	when do_set returns true. Return bool value.
+	(color_property::do_set, double_radio_property::do_set): Check value
+	change and return bool value.
+	(array_property::is_equal): Add.
+
+	* genprops.awk (emit_declarations, emit_source): Change code emission
+	when emitting base_properties code (base is 1).
+	(BEGIN): Initialize pcount to 0.
+	(BEGIN_PROPERTIES): Initialize base to 0.
+	(BEGIN_BASE_PROPERTIES): New statement.
+	(main): Add support for 'f' modifier. Add support for non xxx_property
+	typed properties.
+	* graphics.h.in (base_properties::base_properties): Remove
+	implementation.
+	(base_properties::get_tag, base_properties::get_parent,
+	base_properties::get_type, base_properties::get___myhandle__,
+	base_properties::get_busyaction, base_properties::get_buttondownfcn,
+	base_properties::is_clipping, base_properties::get_clipping,
+	base_properties::execute_createfcn, base_properties::get_createfcn,
+	base_properties::execute_deletefcn, base_properties::get_deletefcn,
+	base_properties::get_handlevisibility, base_properties::is_hittest,
+	base_properties::get_hittest, base_properties::is_interruptible,
+	base_properties::get_interruptible, base_properties::is_selected,
+	base_properties::get_selected, base_properties::is_selectionhighlight,
+	base_properties::get_selectionhighlight,
+	base_properties::get_uicontextmenu, base_properties::get_userdata,
+	base_properties::is_visible, base_properties::get_visible,
+	base_properties::is_beingdeleted, base_properties::get_beingdeleted,
+	base_properties::set_busyaction, base_properties::set_buttondownfcn,
+	base_properties::set_clipping, base_properties::set_createfcn,
+	base_properties::set_deletefcn, base_properties::set_handlevisibility,
+	base_properties::set_hittest, base_properties::set_interruptible,
+	base_properties::set_selected,
+	base_properties::set_selectionhighlight,
+	base_properties::set_uicontextmenu, base_properties::set_userdata,
+	base_properties::set_visible, base_properties::set_beingdeleted,
+	base_properties::get_children): Remove (now auto-generated).
+	(base_properties::enum): Likewise.
+	(base_properties::is_modified): Call is___modified__.
+	(base_properties::set_modified): Call set___modified__.
+	(base_properties::set_children): Add.
+	(base_properties::set_dynamic, base_properties::get_dynamic,
+	base_properties::get_property_dynamic): New methods.
+	(class base_properties): Surround properties declaration with
+	BEGIN_BASE_PROPERTIES/END_PROPERTIES pair.
+	* graphics.cc (base_properties::get, base_properties::set,
+	base_properties::get_property): Remove (now auto-generated).
+	(base_properties::set_dynamic, base_properties::get_dynamic,
+	base_properties::get_property_dynamic): New methods.
+	(base_properties::set_children): Likewise.
+
+	* DLD_FUNCTIONS/fltk_backend.cc (F__fltk_redraw__): Make static.
+	(F__init_fltk__): Protect from mutliple invocations.
+	(F__remove_fltk__): Likewise.
+	(F__init_fltk__): Register input event hook.
+	(F__remove_fltk__): Unregister input event hook.
+
+	* DLD_FUNCTIONS/fltk_backend.cc (fltk_backend::close_figure): Remove.
+	(fltk_backend::object_destroyed, fltk_backend::property_changed): New
+	methods.
+	* genprops.awk (emit_declarations): Generate "enum" property fields.
+	(emit_sources): Emit set_id calls.
+	* graphics.h.in (base_property::id): New field.
+	(base_property::base_property): Initialize it.
+	(base_property::get_id, base_property::set_id): Add accessors.
+	(property::get_id, property::set_id): Likewise.
+	(base_graphics_backend::close_figure, graphics_backend::close_figure):
+	Remove methods.
+	(base_graphics_backend::redraw_figure,
+	base_graphics_backend::print_figure, graphics_backend::redraw_figure,
+	graphics_backend::print_figure): Change graphics_handle argument into
+	graphics_object.
+	(base_graphics_backend::property_changed,
+	base_graphics_backend::object_created,
+	base_graphics_backend::object_destroyed,
+	graphics_backend::property_changed, graphics_backend::object_created,
+	graphics_backend::object_destroyed): New signature with
+	graphics_object argument.
+	(base_properties::base_properties): Add set_id calls.
+	(class base_properties): Add "enum" property fields.
+	(root_figure::properties::remove_child): Add overloaded method.
+	(figure::properties::close): Remove.
+	(figure::properties::set_backend): Call object_destroyed instead of
+	close.
+	(figure::~figure): Remove close call.
+	(figure::properties::get_title): New method.
+	* graphics.cc (base_property::set): Call property_changed only for
+	valid id (>=0); Use graphics_object argument.
+	(gh_manager::do_free): Call object_destroyed with graphics_object
+	argument.
+	(base_graphics_backend::property_changed,
+	base_graphics_backend::object_created,
+	base_graphics_object::object_destroyed): Implement wrappers for
+	graphics_handle argument case.
+	(gnuplot_backend::close_figure): Remove.
+	(gnuplot_backend::object_destroyed,
+	gnuplot_backend::property_changed): New methods.
+	(gnuplot_backend::redraw_figure, gnuplot_backend::print_figure):
+	Change graphics_handle argument to graphics_object.
+	(root_figure::properties::remove_child): Add.
+	(figure::properties::close): Remove.
+	(figure::properties::set_position): Do not call set_figure_position.
+	(figure::properties::get_title): New method.
+	(gh_manager::do_make_graphics_handle): Call object_created with
+	a graphics_object argument.
+	(gh_manager::do_make_figure_handle): Likewise.
+	(Fdrawnow): Call redraw_figure and print_figure with a graphics_object
+	argument.
+
+2008-08-26  Maciek Gajewski <maciej.gajewski0 at gmail.com>
+
+	* graphics.h.in (base_property::set): Remove inline implementation.
+	(base_graphics_backend::property_changed,
+	base_graphics_backend::object_created,
+	base_graphics_backend::object_destroyed): New method.
+	(graphics_backend::property_changed, graphics_backend::object_created,
+	graphics_backend::object_destroyed): Likewise.
+	* graphics.cc (base_property::set): Moved from header file.
+	(gh_manager::do_free): Add backend notification.
+	(gh_manager::do_make_graphics_handle): Likewise.
+	(gh_manager::do_make_figure_handle): Likewise.
+
+2008-08-25  Thomas L. Scofield  <scofield at calvin.edu>
+
+	* DLD-FUNCTIONS/__magick_read__.cc: Untabify.
+	(jpg_settings, encode_bool_image, encode_uint_image, encode_map):
+	New functions.
+	(write_image): Use them to handle various image types.
+
+2008-08-25  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (void gh_manager::do_execute_callback 
+	(const graphics_handle&, const octave_value&, const
+	octave_value&)): Don't pass the function handle as first arg of
+	property listener functions
+
+	* graphics.h.in (class base_properties): Add functor for caseless
+	string comparison. Use it in the property map, so that user added
+	properties are found in a case insensitive fashion.
+
+2008-08-22  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_table::inherit): Pass reference to symbol table
+	to do_inherit instead of scope.
+	(symbol_table::do_inherit): First arg is now reference to
+	symbol_table, not scope id.  Insert all variables from donor scope.
+
+2008-08-21  Thomas Treichl  <Thomas.Treichl at gmx.net>
+	
+	* mappers.cc: Increase test script tolerance.
+
+2008-08-20  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (builtin_help): Go to next symbol name on error.
+	(do_type, do_which): Omit separate path search for files.
+	(help_from_symbol_table): Only insert Texinfo markup if it looks
+	like the help message is already in Texinfo.
+
+2008-08-19  David Bateman  <dbateman at free.fr>
+
+	* load-path.cc (load-path::do_find_dir (const std:string&) const)):
+	Method to find a directory on the load-path corresponding to the
+	argument.
+	* load-path.h (load-path::do_find_dir (const std:string&) const),
+	load-path::find_dir (const std::string&) const): New methods.
+	* utils.cc (std::string contents_file_in_path (const std::string&)):
+	New function.
+	* utils.h  (std::string contents_file_in_path (const std::string&)): 
+	Declare it.
+	* help.cc (static bool raw_help_from_file (const std::string&,
+	std::string&, std::string&, bool&)): Also check is requested
+	argument is a directory and contains the file Contents.m.
+
+	* OPERATORS/op-int-conv.cc (DEFINTCONVFN): New macro that warn
+	for integer conversion issues. Use it to replace DEFCONVFN.
+	* OPERATORS/op-int.h (DEFINTBINOP_OP, DEFINTNDBINOP_OP,
+	DEFINTBINOP_FN, DEFINTNDBINOP_FN): New macros that warn for
+	integer truncation issues. Use them to replace the corresponding
+	macros in the integer arithmetic macros. Update other integer
+	arithmetic functions that don't use these macros individually.
+	* error.cc (initialize_default_warning_state (void)): Initialize
+	the default warning state for the integer warnings to be off.
+	* gripes.cc (void gripe_binop_integer_math_truncated (const char *,
+	const char *, const char *), void gripe_unop_integer_math_truncated
+	(const char *, const char *), void gripe_non_integer_conversion
+	(const char *, const char *), void gripe_nan_conversion (const char *,
+	const char *)): Warning functions for integer conversion and math
+	issues.
+	* gripes.h (void gripe_binop_integer_math_truncated (const char *,
+	const char *, const char *), void gripe_unop_integer_math_truncated
+	(const char *, const char *), void gripe_non_integer_conversion
+	(const char *, const char *), void gripe_nan_conversion (const char *,
+	const char *)): Declare them.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::convert_gripe,
+	OCTAVE_VALUE_INT_SCALAR_T::convert_gripe): Adapt for new means of
+	flagging integer truncation.
+	(OCTAVE_VALUE_INT_MATRIX_T::decrement,
+	OCTAVE_VALUE_INT_MATRIX_T::increment,
+	OCTAVE_VALUE_INT_SCALAR_T::decrement,
+	OCTAVE_VALUE_INT_SCALAR_T::increment): Check for integer
+	truncation.
+	* ov.cc (convert_to_int_array): Adapt for new means of
+	flagging integer truncation.
+
+2008-08-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* pt-assign.h (tree_simple_assignment::first_execution): New
+	member field.
+	(tree_simple_assignment::first_execution): Ditto.
+	* pt-assign.cc (tree_simple_assignment::tree_simple_assignment):
+	Initialize first_execution.
+	(tree_multi_assignment::tree_multi_assignment): Ditto.
+	(tree_simple_assignment::rvalue): Check for obsolete built-in
+	variables only at first execution.
+	(tree_multi_assignment::rvalue): Ditto.
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Checks whether LB and UB are
+	of proper size.
+
+	* oct-obj.cc, oct-obj.h (octave_value_list::make_argv): 
+	Allow calling without fcn_name.
+	* load-save.cc (parse_save_options (const string_vector&, ...)): 
+	Return string_vector with parsed arguments removed instead.
+	(parse_save_options (const std::string&, ...)):	Ditto.
+	(Fsave): Fix calls to parse_save_options.
+
+2008-08-19  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (Feval): Return value produced by evaluating CATCH string.
+
+2008-08-12  John W. Eaton  <jwe at octave.org>
+
+	* pt-fcn-handle.cc (tree_anon_fcn_handle::rvalue):
+	Call stash_parent_function_scope for user function.
+	* ov-fcn-inline.cc (octave_fcn_inline::octave_fcn_inline): 
+	Likewise.
+
+	* ov-struct.cc (octave_struct::subsref): Don't allow resizing for
+	simple x(idx) case.
+
+2008-08-07  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (octave_value::idx_type_value): Don't include default
+	argument values in definition.
+
+	* src/glrender.h, src/zfstream.h: Don't include config.h.
+
+	* oct-errno.h: Include <cerrno>.
+
+	* Cell.cc, DLD-FUNCTIONS/regexp.cc, DLD-FUNCTIONS/dlmread.cc,
+	debug.cc, error.cc, file-io.cc, graphics.cc, help.cc, input.cc,
+	lex.l, load-path.cc, load-save.cc, ls-mat-ascii.cc,
+	ls-oct-ascii.cc, oct-stream.cc, octave.cc, variables.cc,
+	ov-fcn-handle.cc, parse.y, pr-output.cc, symtab.cc, sysdep.cc,
+	utils.cc, graphics.h.in: Replace all uses of NPOS with
+	std::string::npos.
+
+	* ov.cc (octave_value::idx_type_value): Move definition here.
+	* ov.h: From here.
+
+	* DLD-FUNCTIONS/fsolve.cc (override_options): Don't fail if
+	options_map does not contain an expected keyword.
+	Fix typo in warning identifier.
+	(make_unimplemented_options): Use CamelCase names here.
+
+2008-08-06  Søren Hauberg  <hauberg at gmail.com>
+
+	* error.cc (Ferror): Update format of error messages in exmple.
+	* parse.y: (Feval): Likewise.
+
+2008-08-06  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fsolve.cc (hybrd_info_to_fsolve_info):
+	Update INFO values to be compatible with Matlab's current fsolve.
+	(make_unimplemented_options, override_options): New functions.
+	(Ffsolve): Handle optimset options.  Update doc string.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op,
+	octave_user_script::do_multi_index_op):
+	Call octave_call_stack::backtrace_error_message.
+	* toplev.h (octave_call_stack::do_pop): Don't call
+	backtrace_error_message here.
+	* toplev.cc, toplev.h (octave_call_stack::do_backtrace_error_message):
+	Rename from octave_call_stack::backtrace_error_message.
+	* toplev.h (octave_call_stack::backtrace_error_message):
+	New public static function. 
+
+2008-08-05  John W. Eaton  <jwe at octave.org>
+
+	* gripes.cc (gripe_truncated_conversion,
+	gripe_logical_conversion): Don't declare as extern here.
+	* utils.cc (octave_format, octave_vformat): Likewise.
+	* pr-output.cc (octave_print_internal (std::ostream&, const Cell&,
+	bool, int, bool)): Likewise.
+
+	* toplev.cc (octave_call_stack::backtrace_error_message): New
+	function.
+	* toplev.h: Provide decl.
+	(octave_call_stack::do_pop): Call backtrace_error_message if
+	error_state is nonzero.
+
+	* pt-unop.cc (tree_prefix_expression::eval_error, 
+	tree_postfix_expression::eval_error): Delete.  Eliminate all uses.
+	* pt-unop.h: Delete decls.
+
+	* pt-select.cc (tree_switch_case::eval_error,
+	tree_switch_command::eval_error): Delete.  Eliminate all uses.
+	(tree_if_command::eval): Omit "evaluating if command" message.
+	* pt-select.h: Delete decls.
+
+	* pt-loop.cc (tree_while_command::eval_error,
+	tree_complex_for_command::eval_error,
+	tree_simple_for_command::eval_error,
+	tree_do_until_command::eval_error): Delete.  Eliminate all uses.
+	* pt-loop.h: Delete decls.
+
+	* pt-exp.cc (tree_expression::is_logically_true): Omit "evaluating
+	conditional expression" error message.
+
+	* pt-decl.cc (tree_global_command::eval): Omit "evaluating global
+	command" error message.
+	(tree_static_command::eval): Omit "evaluating static command"
+	error message.
+
+	* pt-colon.cc (tree_colon_expression::eval_error): Omit
+	"evaluating colon expression" error message.
+	* pt-colon.h (tree_colon_expression::eval_error): Eliminate
+	default argument value.
+
+	* pt-idx.cc (tree_index_expression::eval_error): Delete.
+	Eliminate all uses.
+	* pt-idx.h: Delete decl.
+
+	* pt-binop.cc (tree_binary_expression::eval_error): Delete.
+	* pt-binop.cc, pt-cbinop.cc: Eliminate all uses of eval_error.
+	* pt-binop.h: Delete decl.
+
+	* pt-assign.cc (tree_simple_assignment::eval_error,
+	tree_multi_assignment::eval_error): Delete.  Eliminate all uses.
+	* pt-assign.h: Delete decls.
+
+	* ov-usr-fcn.cc (octave_user_script::traceback_error,
+	octave_user_function::traceback_error): Delete.  Eliminate all uses.
+	* ov-usr-fcn.h: Delete decls.
+
+	* ov-builtin.cc (octave_builtin::do_multi_index_op): Call
+	gripe_library_exectuion_error on octave_execution_exception.
+	* ov-mex-fcn.cc (octave_mex_function::do_multi_index_op): Likewise.
+	* ov.cc (do_binary_op, do_cat_op, do_unary_op,
+	do_non_const_unary_op): Likewise.
+	* pt-stmt.cc (tree_statement::eval): Likewise.
+
+	* gripes.cc (gripe_library_execution_error): New function.
+	* gripes.h: Provide decl.
+
+	* dirfns.cc (Fpathsep): Fix usage of dir_path::path_sep_str.
+	* defaults.cc (set_exec_path, set_image_path): Likewise.
+	* load-path.h (load_path::set_command_line_path): Likewise.
+	* load-path.cc (maybe_add_path_elts, load_path::do_initialize,
+	load_path::do_path, genpath, Fpath): Likewise.
+	(split_path): Fix usage of dir_path::path_sep_char.
+
+2008-08-04  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::find_autoload):
+	Fix usage of file_ops::dir_sep_chars.
+	* variables.cc (looks_like_struct):
+	Likewise.
+	* ov-fcn-handle.cc (octave_fcn_handle::set_fcn): Likewise.
+	* octave.cc (execute_command_line_file): Likewise.
+	* ls-mat5.cc (read_mat5_binary_element): Likewise.
+	* load-save.cc (find_file_to_load): Likewise.
+	* load-path.cc (load_path::do_find_file): Likewise.
+	* graphics.cc (drawnow): Likewise.
+	* parse.y (frob_function): Likewise.
+
+	* octave.cc (initialize_pathsearch): Fix usage of
+	file_ops::dir_sep_str.
+	* help.cc (Flookfor): Likewise.
+	* dirfns.cc (Ffilesep): Likewise.
+	(Fautoload): Likewise.
+
+	* defaults.cc (subst_octave_home): Fix usage of
+	file_ops::dir_sep_char.
+	(Fmfilename): Likewise.
+
+2008-07-31  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (assign_lhs): Call force_local_variable on all elements
+	of lexer_flags.pending_local_variables here, then clear the set.
+	(matrix): Clear lexer_flags.pending_local_variable here.
+	* lex.l (lexical_feedback::init): Clear it.
+	(force_local_variable): No longer static.
+	(is_variable): Also return true for names in the
+	lexer_flags.pending_local_variables.
+	(handle_identifier): If we are parsing a matrix list, mark
+	identifiers as pending local variables rather than forcing them to
+	be local variables immediately.
+	* lex.h (lexical_feedback::pending_local_variables): New data member.
+	(force_local_variable): Provide decl.
+
+2008-07-30  John W. Eaton  <jwe at octave.org>
+
+	* ov-intx.h, ov.cc: Style fixes.
+
+	* gripes.cc (gripe_truncated_conversion): Use the warning ID
+	Octave:int-convert-overflow.
+
+2008-07-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* gripes.cc (gripe_truncated_conversion): New function.
+	* gripes.h (gripe_truncated_conversion): Declare it.
+	* ops.h (DEFCONVFNX2): New macro.
+	(DEFCONVFN, DEFCONVFN2): Call DEFCONVFNX2 instead of DEFCONVFNX.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::convert_gripe): New member
+	function.
+	(OCTAVE_VALUE_INT_MATRIX_T::int*_array_value): Call convert_gripe.
+	(OCTAVE_VALUE_INT_SCALAR_T::convert_gripe): New member function.
+	(OCTAVE_VALUE_INT_SCALAR_T::int*_scalar_value): Call convert_gripe.
+	(OCTAVE_VALUE_INT_SCALAR_T::int*_array_value): Call int*_scalar_value.
+	* ov.cc (convert_to_int_array): New function.
+	(int_vector_value): Call convert_to_int_array.
+
+2008-07-30  John W. Eaton  <jwe at octave.org>
+
+	* defun-dld.h (DEFUNX_DLD): Eliminate fsname arg.
+	* defun-int.h (DEFINE_FUN_INSTALLER_FUN2,
+	DEFINE_FUN_INSTALLER_FUN3, DEFINE_FUNX_INSTALLER_FUN2): Delete.
+	(DEFINE_FUNX_INSTALLER_FUN): Rename from DEFINE_FUNX_INSTALLER_FUN3.
+	Don't emit fsname function.  Don't append cxx_abi to gname.
+	(DEFINE_FUN_INSTALLER_FUN): Define in terms of
+	DEFINE_FUNX_INSTALLER_FUN, not DEFINE_FUN_INSTALLER_FUN2.
+	* dynamic-ld.cc (octave_dynamic_loader::name_mangler,
+	octave_dynamic_loader::name_uscore_mangler): New functions.
+	(octave_dynamic_loader::mangle_name,
+	octave_dynamic_loader::xmangle_name): Delete.
+	(octave_dynamic_loader::do_load_oct): Search for function with
+	name_mangler then name_uscore_mangler.
+
+	* oct-stream.cc (do_read): New arg, do_NA_conv.
+	Perform NA translation if do_NA_conv is true.
+	(DO_READ_VAL_TEMPLATE, read_fptr): Include the new arg for do_read
+	in decl.
+	(octave_stream::read): Pass do_NA_conv to do_read.
+
+2008-07-29  David Bateman  <dbateman at free.fr>
+
+	* data.cc (FNA): Add tests for conversion of single to double NA
+	values.
+
+	* ov-flt-re-mat.cc (Fsingle): Documentation fix.
+
+2008-07-28  David Bateman  <dbateman at free.fr>
+
+	* error.cc (last_error_id, last_error_message, last_warning_id,
+	last_warning_message): New functions to return the error/warning
+	message and id without exposing the internal values.
+	* error.h  (last_error_id, last_error_message, last_warning_id,
+	last_warning_message): Declare them.
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun): Use them to pass the error
+	to the ErrorHandler function.
+	
+2008-07-28  John W. Eaton  <jwe at octave.org>
+
+	* error.cc (Flasterror, Flasterr): Unwind-protect error_state.
+
+	* DLD-FUNCTIONS/__magick_read__.cc (F__magick_write__, write_image):
+	New functions.
+
+2008-07-25  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/det.cc (Fdet): Return calculated determinant for
+	numerically singular matrices, not 0.
+
+	* symtab.cc (get_dispatch_type): New function.
+	(symbol_table::fcn_info::fcn_info_rep::find): Use it.
+
+	* ov-class.cc (set_class_relationship): Delete static function.
+	(Fsuperiorto, Finferiorto): Warn about precedence conflicts.
+	Call symbol_table::set_class_relationship instead of local static
+	function.
+	* symtab.h (symbol_table::class_precedence_table): New data member.
+	(symbol_table::set_class_relationship, symbol_table::is_superiorto):
+	New static functions.
+
+2008-07-24  John W. Eaton  <jwe at octave.org>
+
+	* load-path.h (load_path::dir_info::class_info): New struct.
+	(load_path::dir_info::method_file_map_type): Now a map from
+	class name to a to a class_info object.  Change all uses.
+	* load-path.cc (load_path::dir_info::get_method_file_map):
+	Also look for private functions in the class directory.
+	(load_path::add_to_method_map): Also add private functions from
+	class directories to private_fcn_map.
+
+	* dirfns.cc (Fmkdir): If directory already exists, return status =
+	true, but also set error message.
+
+2008-07-23  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr_fcn.cc (octave_user_function::do_multi_index_op):
+	Don't unwind_protect and set curr_parent_function here.
+	* toplev.cc (curr_parent_function): Delete definition.
+	* toplev.h: (curr_parent_function): Delete declaration.
+
+	* ov-usr-fcn.h (octave_user_function::parent_scope): New data member.
+	(octave_user_function::parent_fcn_scope,
+	octave_user_function::stash_parent_fcn_scope): New functions.
+	* ov-usr_fcn.cc (octave_user_function::octave_user_function):
+	Initialize parent_scope.
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::find):
+	Check parent of current function by looking at call stack, not
+	global curr_parent_function variable.
+	* parse.y (frob_function): If parsing nested function, stash
+	current parent function scope.
+	* ov-fcn.h (octave_function::parent_fcn_scope): New virtual function.
+
+2008-07-22  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.cc (F__go_execute_callback__): New function.
+
+	* DLD-FUNCTIONS/fltk_backend.cc: Undefine min/max after FLTK headers
+	inclusion.
+
+	* graphics.h.in (class base_graphics_event, class graphics_event): New
+	classes (replace gh_manager::event_data).
+	(class gh_manager::event_data): Remove.
+	(gh_manager::post_function, gh_manager::do_post_function): Use
+	graphics_event::event_fcn type.
+	(gh_manager::event_queue, gh_manager::do_post_event): Use
+	graphics_event type.
+	* graphics.cc (class callback_event, class function_event, class
+	set_event): Renamed from xxx_data classes.
+	(graphics_event::create_callback_event,
+	graphics_event::create_function_event,
+	graphics_event::create_set_event): Renamed from gh_manager::xxx
+	equivalent methods, removed reference count increment.
+	(gh_manager::do_post_event): Likewise.
+	(gh_manager::do_post_event): Use graphics_event type.
+	(gh_manager::do_post_function): Use graphics_event::event_fcn type.
+
+2008-07-22  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.51+.
+
+2008-07-21  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.51.
+	(OCTAVE_RELEASE_DATE): Now 2008-07-21.
+
+	* ov-class.cc (octave_class::subsasgn): Only do internal magic if
+	rhs is not an octave_class object.
+
+	* OPERATORS/op-struct.cc: Define concatenation operators for
+	struct/matrix concatenation (valid if matrix is empty).
+	* OPERATORS/op-cell.cc (install_cell_ops): Likewise, for cells.
+
+	* DLD-FUNCTIONS/fltk_backend.cc: Don't include oct.h.
+	Make compilation of entire file conditional on HAVE_FLTK.
+
+	* gl-render.cc: Make compilation of entire file conditional on
+	HAVE_OPENGL.
+
+	* Makefile.in (GL_RENDER_SRC, FLTK_BACKEND_SRC): Delete variables.
+	(DLD_XSRC): Always include fltk_backend.cc in the list.
+	(DIST_SRC): Always include gl-render.cc in the list.
+
+2008-07-19  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.50+.
+	(OCTAVE_API_VERSION): Now api-v33+.
+
+2008-07-18  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 3.1.50.
+	(OCTAVE_API_VERSION): Now api-v33.
+	(OCTAVE_RELEASE_DATE): Now 2008-07-18.
+	(OCTAVE_COPYRIGHT): Update date to 2008.
+
+2008-07-18  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (__magick_read__.df): New rule.
+	Append MAGICK_INCFLAGS to CPPFLAGS.
+
+	* Makefile.in (EXTRAS): Add graphics-props.cc to the list.
+	List graphics-props.cc as a target generated by genprops.awk.
+
+2008-07-18 Carlo de Falco  <carlo.defalco at gmail.com>
+
+	* gl-render.h: Conditionally include GL/gl.h or OpenGL/gl.h
+	and GL/glu.h or OpenGL/glu.h
+
+2008-07-17  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (out_of_date_check_internal): New arg, dispatch_type.
+	Use it to handle class methods.
+
+	* toplev.h (octave_call_stack::do_caller): New function.
+	(octave_call_stack::caller): Use it.
+
+2008-07-17  Jaroslav Hajek  <highegg at gmail.com>
+
+	* Makefile.in (convhulln.oct, __delaunayn__.oct, __voronoi__.oct, 
+	regexp.oct, urlwrite.oct, __glpk__.oct, fltk_backend.oct):
+	Use OCT_LINK_DEPS instead of DL_LDFLAGS for target-specific
+	dependencies.
+
+2008-07-17  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTION/__magick_read__.cc (F__magick_read__): Allow build
+	without GraphicsMagick++ installed.
+
+2008-07-16  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (gh_manager::autolock): Delete copy constructor
+	and assignment definitions.
+
+2008-07-16  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (callback_property::execute): Remove static version.
+	(base_properties::is_hittest, base_properties::is_interruptible,
+	base_properties::is_selected, base_properties::is_selectionhighlight):
+	New convenience property accessors.
+	(base_graphics_object::get_handle, graphics_object::get_handle): Idem.
+	(gh_manager::graphics_lock): New global mutex
+	(gh_manager::lock, gh_manager::unlock, gh_manager::do_lock,
+	gh_manager::do_unlock): Add accessors for it.
+	(gh_manager::autolock): New class for easy locking of the graphics
+	system.
+	(gh_manager::event_data): New class for event management.
+	(gh_manager::event_queue): New object to hold pending events.
+	(gh_manager::callback_objects): New stack of callback objects.
+	(gh_manager::execute_callback, gh_manager:post_callback,
+	gh_manager::post_function, gh_manager::post_set,
+	gh_manager::process_events, gh_manager::flush_events,
+	gh_manager::restore_gcbo): New static methods for event management.
+	(gh_manager::do_execute_callback, gh_manager::do_post_callback,
+	gh_manager::do_post_function, gh_manager::do_post_set,
+	gh_manager::do_process_events, gh_manager::do_post_event,
+	gh_manager::do_restore_gcbo): New non-static versions.
+	* graphics.cc (xreset_gcbo): Remove.
+	(execute_callback): Likewise.
+	(base_property::run_listeners, callback_property::execute): Use
+	gh_manager::execute_callback.
+	(class callback_event_data, class function_event_data, class
+	set_event_data): New classes to implement various types of events.
+	(gh_manager::event_data::create_callback_event,
+	gh_manager::event_data::create_function_event,
+	gh_manager::event_data::create_set_event): Implement event factory
+	methods.
+	(gh_manager::do_restore_gcbo, gh_manager::do_execute_callback,
+	gh_manager::do_post_event, gh_manager::do_post_callback,
+	gh_manager::do_post_function, gh_manager::do_post_set,
+	gh_manager::do_process_events): New methods for event management.
+	(Fishandle, Fset, Fget, F__get__, F__go_figure__, F__go_delete__,
+	F__go_axes_init__, F__go_handles__, F__go_figure_handles__,
+	Favailable_backends, Fdrawnow, Faddlistener, Faddproperty,
+	get_property_from_handle, set_property_in_handle): Lock graphics
+	system.
+	(GO_BODY): Likewise.
+	(Fdrawnow): Support single "expose" argument.
+
+2008-07-15  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__convn__.cc (convn): Cast second arg to
+	octave_idx_type in call to std::max.
+
+2008-07-14  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (convhulln.oct, __delaunayn__.oct, __voronoi__.oct, 
+	regexp.oct, urlwrite.oct, __glpk__.oct, fltk_backend.oct):
+	Simplify with target-specific settings for DL_LDFLAGS.
+
+	* DLD-FUNCTIONS/__magick_read__.cc: Delete "using namespace std"
+	and "using namespace Magick" directives.  Style fixes.
+
+	* oct-conf.h.in (OCTAVE_CONF_MAGICK_INCFLAGS,
+	OCTAVE_CONF_MAGICK_LIBS): Substitute here.
+	* toplev.cc (octave_config_info): Include MAGICK_INCFLAGS and
+	MAGICK_LIBS in the struct.
+	* Makefile.in (DLD_XSRC): Add __magick_read__.cc to the list.
+	(OCTAVE_LIBS): Add $(MAGICK_LIBS) to the list for static linking case.
+	(__magick_read__.d, __magick_read__.o, pic/__magick_read__.o):
+	Append MAGICK_INCFLAGS to CPPFLAGS.
+	(__magick_read__.oct): Append MAGICK_LIBS to LDFLAGS.
+
+2008-07-14  Thomas L. Scofield  <scofield at calvin.edu>
+
+	* DLD-FUNCTIONS/__magick_read__.cc: New file from Octave Forge.
+
+2008-07-11  John W. Eaton  <jwe at octave.org>
+
+	* syscalls.cc (const_value): Delete arg NM.  Change all uses.
+
+	* DLD-FUNCTIONS/fft.cc (do_fft): Avoid GCC warning.
+	* DLD-FUNCTIONS/fft2.cc (do_fft2): Likewise.
+	* DLD-FUNCTIONS/fftn.cc (do_fftn): Likewise.
+	* DLD-FUNCTIONS/qr.cc (Fqrshift): Likewise.
+	* DLD-FUNCTIONS/lookup.cc (Flookup): Likewise.
+	* gl-render.cc (opengl_renderer::draw): Likewise.
+	* graphics.cc (axes::update_axis_limits,
+	hggroup::update_axis_limits, Favailable_backends):
+	Likewise.
+	* pt-cmd.cc (tree_no_op_command::dup, tree_function_def::dup):
+	Likewise.
+	* pt-const.cc (tree_constant::dup): Likewise.
+	* pt-id.cc (tree_identifier::dup): Likewise.
+	* pt-jump.cc (tree_break_command::dup, tree_continue_command::dup,
+	tree_return_command::dup): Likewise.
+
+	* DLD-FUNCTIONS/colamd.cc: Style fixes.
+	(tree_postorder): Rename from TreePostorder.
+	(tree_postorder, coletree): Avoid GCC warnings.
+
+	* DLD-FUNCTIONS/chol.cc (Fchol): Avoid GCC warnings.
+	(Fcholdelete, Fcholshift): Delete unused arg nargout.
+
+	* toplev.cc, toplev.h (octave_call_stack::caller_user_function,
+	octave_call_stack::caller_user_script,
+	octave_call_stack::do_caller_user_function,
+	octave_call_stack::do_caller_user_script):
+	Delete functions and decls. 
+
+	* defun.cc (print_usage): Call octave_call_stack::caller_user_code,
+	not octave_call_stack::caller_user_function.
+	* debug.cc (get_user_code): Likewise.
+
+	* toplev.h (octave_call_stack::difference_type): Delete typedef.
+	* toplev.cc, toplev.h (octave_call_stack::caller_user_code_line,
+	octave_call_stack::do_caller_user_code_line, 
+	octave_call_stack::caller_user_code_column,
+	octave_call_stack::do_caller_user_code_column,
+	octave_call_stack::caller_script,
+	octave_call_stack::do_caller_script,
+	octave_call_stack::caller_user_function,
+	octave_call_stack::do_caller_user_function,
+	octave_call_stack::caller_user_code,
+	octave_call_stack::do_caller_user_code):
+	Delete unused difference_type arg.
+
+	* ov-float.h, ov-flt-re-mat.cc, ov-range.h, ov-re-mat.h,
+	ov-re-sparse.cc, ov-scalar.h: Check for NaN in bool_value and
+	bool_array_value member functions to bool.
+
+	* ops.h (DEFSCALARBOOLOP_OP): New macro.
+	* OPERATORS/op-s-s.cc, OPERATORS/op-fs-fs.cc: Use it to define
+	el_and and el_or ops.
+
+2008-07-10  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/lookup.cc (assign): Delete.
+	(Flookup): Use new NDArray constructors rather than assign.
+	* data.cc (Fsort): Use new NDArray constructors rather than 
+	directly assigning.
+	* besselj.cc (int_array2_to_matrix, int_arrayn_to_array,
+	int_array2_to_float_matrix, int_arrayn_to_float_array): Delete.
+	(do-bessel): Use new NDArray constructors.
+	* max.cc (MINMAX_SPARSE_BODY, MINMAX_INT_BODY, MINMAX_SINGLE_BODY,
+	MINMAX_DOUBLE_BODY): Use new NDArray constructors. 
+	* ov-bool.h (array_value, float_array_value): Explictly cast
+	boolean scalar to double before the assignment to avoid ambiguity.
+
+2008-07-10  David Bateman  <dbateman at free.fr>
+
+	* ls-mat4.cc (read_mat_binary_data, save_mat_binary_data): Add
+	loading and saving of sparse matrices.
+	
+2008-07-10  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Makefile.in: Add OPENGL_LIBS to liboctinterp link command. Add
+	GRAPHICS_CFLAGS to fltk_backend.cc compilation command.
+	* data.cc: Define hypotf to _hypotf when not present.
+	* gl-render.h: Replace OCTGRAPHICS_API with OCTINTERP_API.
+	* gl-render.cc: Get rid of Array2<vertex_data>.
+	* OPERATORS/op-int.h: Use powf instead of pow when invoked
+	with float arguments.
+
+2008-07-09  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (get_debug_input): Don't delete global_command here.
+	* toplev.cc (main_loop): Undo previous change.
+
+	* toplev.h (octave_call_stack::instance_ok): Push top scope when
+	creating instance.
+
+	* DLD-FUNCTIONS/inv.cc (Finv): Avoid GCC warning.
+
+	* DLD-FUNCTIONS/expm.cc (Fexpm): Avoid GCC warning.
+
+	* ov-fcn-inline.cc (octave_fcn_inline::load_ascii): Avoid GCC warning.
+
+2008-07-09  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* gl-render.cc (opengl_renderer::draw(figure)): Enable line smoothing
+	according to __enhanced__ property.
+	(opengl_renderer::draw_marker): Only draw markers with valid call
+	lists ID.
+	(opengl_renderer::make_marker_list): Do not produce filled marker call
+	list for non-fillable markers.
+	(opengl_renderer::draw(axes)): Do not antialias axes system.
+
+	* gl-render.cc (opengl_renderer::set_polygon_offset): Also enable
+	polygon offseting in GL_LINE mode.
+	(opengl_renderer::draw_marker): Offset markers foward instead of
+	backward (to draw them above lines).
+
+	* Makefile.in: new substituted variables GL_RENDER_SRC and
+	FLTK_BACKEND_SRC.
+
+	* gl-render.cc (vertex_data::vertex_data_rep::vertex_data(void),
+	vertex_data::vertex_data(void), vertex_data::vertex_data(...)):
+	initialize reference counting correctly.
+
+2008-07-09  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (main_loop): Unwind-protect global_command.
+	* input.cc (get_debug_input): Likewise.
+
+2008-07-09  David Bateman  <dbateman at free.fr>
+
+	* pt-id.cc (octave_value_list tree_identifier::rvalue (int), 
+	octave_lvalue tree_identifier::lvalue (void)): Remove 
+	MAYBE_DO_BREAKPOINT.
+
+2008-07-08  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (axes::properties::keypos): Declare as
+	any_property instead of double_property.
+
+2008-06-28  John W. Eaton  <jwe at octave.org>
+
+	* debug.cc (push_dummy_call_stack_elt): Delete.
+	(Fdbstack): Don't push dummy stack elt.  Use nskip instead of
+	nframes, and curr_frame instead of idx.  Pass curr_frame to
+	octave_call_stack::backtrace.
+
+	* ls-mat5.cc (read_mat5_binary_element): Explicitly pass 0 for
+	current_context in call to symbol_table::varref.
+	* ov-fcn-handle.cc (octave_fcn_handle::load_ascii): Likewise.
+	Fix test.
+
+	* mex.cc (mexGetVariable, mexPutVariable): Use octave_call_stack
+	methods to manipulate scope and context.
+	* parse.y (source_file, Fassignin, Fevalin): Likewise.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Call octave_call_stack::push after call to symbol_table::push_scope.
+	Call unwind_protect::add with octave_call_stack::unwind_pop
+	immediately after call to octave_call_stack::push.
+
+	* symtab.cc (symbol_table::xcurrent_caller_scope): Delete definition.
+	* symtab.h (symbol_table::xcurrent_caller_scope): Delete decl.
+	Delete all uses.
+	(xcurrent_context_this_table): Delete.  Delete all uses.
+	(symbol_table::current_caller_scope): Delete.
+
+	* toplev.cc (octave_call_stack::do_num_user_code_frames):
+	New function.
+	(octave_call_stack::do_backtrace): New arg, curr_user_frame.	
+	Rename nframes arg to nskip.  Correctly handle curr_frame not at
+	end of stack.
+	(octave_call_stack::do_goto_frame_relative): Rename n arg to nskip.
+	Correctly handle curr_frame not at end of stack.
+	(octave_call_stack::do_goto_caller_frame): New function.
+	(octave_call_stack::do_goto_base_frame): New function.
+	* toplev.h: Provide decls for new functions.
+	(octave_call_stack::call_stack_elt::prev): New data member.
+	Initialize it in constructor.
+	(octave_call_stack::const_reverse_iterator,
+	octave_call_stack::reverse_iterator): New typedefs.
+	(octave_call_stack::symbol_table::scope_id current_scope,
+	octave_call_stack::symbol_table::context_id current_context,
+	octave_call_stack::num_user_code_frames,
+	octave_call_stack::goto_caller_frame,
+	octave_call_stack::goto_base_frame,
+	octave_call_stack::do_num_user_code_frames,
+	octave_call_stack::do_current_scope,
+	octave_call_stack::do_current_context): New functions.
+
+	(octave_call_stack::push): Default value for context arg is
+	symbol_table::current_context, not 0.
+	(octave_call_stack::do_push): Save previous frame.  Always push
+	new frame on back of stack.  Call symbol_table::set_scope_and_context.
+	(octave_call_stack::do_pop): Restore previous frame.  Always pop
+	frame from back of stack.  Call symbol_table::set_scope_and_context.
+
+2008-06-26  John W. Eaton  <jwe at octave.org>
+
+	* token.h: Omit "class symbol_table::symbol_record" decl;
+
+	* lex.l (grab_block_comment): Use parens around || expression
+	within && expression.
+
+2008-06-23  John W. Eaton  <jwe at octave.org>
+
+	* debug.cc (Fdbstack): Avoid shadowed variable warning.
+
+2008-06-23  Jaroslav Hajek  <highegg at gmail.com>
+
+	* genprops.awk (emit_source): Avoid gensub for portability.
+	(BEGIN): Ditto.
+
+2008-06-20  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp_list): Make "once" an output
+	argument.
+	(octregexp): Do not use cell arrays when "once" is requested.
+
+	* ov.cc (make_vector_dims): New function.
+	(vector_value, complex_vector_value, float_vector_value,
+	float_complex_vector_value): Query N-d array values and simplify,
+	avoid copying.
+	(column_vector_value, complex_column_vector_value,
+	float_column_vector_value, float_complex_column_vector_value,
+	row_vector_value, complex_row_vector_value,
+	float_row_vector_value, float_complex_row_vector_value): 
+	Simplify to trivial wrappers.
+	(int_vector_value): Avoid conversions if integer type, query N-d array
+	value, simplify.
+
+2008-06-17  John W. Eaton  <jwe at octave.org>
+
+	* toplev.h, toplev.cc (class octave_call_stack):
+	Push elements on and pop from back of queue.
+	(octave_call_stack::do_push, octave_call_stack::do_pop):
+	Always adjust curr_frame.
+	(octave_call_stack::size, octave_call_stack::do_size): New functions.
+	* pt-stmt.cc (tree_statement::eval):
+	Also call octave_call_stack::set_statement when debugging.
+	* debug.cc (push_dummy_call_stack_elt): New function.
+	(Fdbstack): Omit dbstack from call stack by popping element rather
+	than adjusting frame number.  Correctly handle arg.
+
+2008-06-12  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/qr.cc (Fqrupdate, Fqrinsert, Fqrshift, Fqrdelete):
+	Allow single precision arguments, add tests for single precision.
+
+2008-06-11  John W. Eaton  <jwe at octave.org>
+
+	* ov-base.cc (octave_base_value::streamoff_value,
+	octave_base_value::streamoff_array_value): Delete.
+	* ov-base.h: Delete decls.
+	(octave_base_value::is_streamoff): Delete.
+	* ov-float.cc (octave_float_scalar::streamoff_value,
+	octave_float_scalar::streamoff_array_value): Delete.
+	* ov-float.h: Delete decls.
+	* ov-flt-re-mat.cc (octave_float_matrix::streamoff_array_value): Delete.
+	* ov-flt-re-mat.h: Delete decl.
+	* ov-re-mat.cc (octave_matrix::streamoff_array_value): Delete.
+	* ov-re-mat.h: Delete decl.
+	* ov-re-sparse.cc (octave_sparse_matrix::streamoff_array_value): Delete.
+	* ov-re-sparse.h: Delete decl.
+	* ov-scalar.cc (octave_scalar::streamoff_value,
+	octave_scalar::streamoff_array_value): Delete.
+	* ov-scalar.h: Delete decls.
+	* ov.cc (octave_value::octave_value (const streamoff_array&),
+	octave_value::octave_value (const ArrayN<std::streamoff>&),
+	octave_value::streamoff_value (void) const,
+	octave_value::streamoff_array_value (void) const): Delete.
+	* ov.h: Delete decls.
+	(octave_value::is_streamoff): Delete.
+	* ov.cc (install_types): Don't register streamoff type.
+	* ov-streamoff.h, ov-streamoff.cc, OPERATORS/op-streamoff.cc: Delete.
+	* Makefile.in: Delete them from the lists.
+
+	* error.cc (verror): Restore newline in msg_string.  Stripping
+	"error: " prefix when buffering error messages is no longer neeed.
+
+2008-06-25  David Bateman  <dbateman at free.fr>
+
+	* pr-output.cc (Frats): Print usage if nargin == 0.
+	
+2008-06-10  John W. Eaton  <jwe at octave.org>
+
+	* mexproto.h (mxCreateLogicalScalar): Declar arg as mxLogical, not int.
+
+2008-06-09  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (execute_callback): Pass CB by const reference and
+	explicitly make a copy.
+	(xget_ancestor): Pass GO by const reference and explicitly make a copy.
+
+	* error.cc (verror): Omit "name: " and "\a" from Vlast_error_msg.
+	Save line and column information from user code.
+	* toplev.cc (octave_call_stack::do_caller_user_code_line,
+	octave_call_stack::do_caller_user_code_column): New functions.
+	* toplev.h: Provide decls.
+	(octave_call_stack::caller_user_code_line,
+	octave_call_stack::caller_user_code_column): New functions.
+	(octave_call_stack::current_line, octave_call_stack::current_column): 
+	Default return value is -1, not 0.
+
+2008-06-06  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (octave_value::erase_subfunctions):
+	New function.
+	* ov-base.h (octave_base_value::erase_subfunctions):
+	New virtual function.
+	* ov-usr-fcn.h (octave_user_function::erase_subfunctions):
+	New function.
+	* symtab.h (symbol_table::fcn_info::::erase_subfunction,
+	symbol_table::fcn_info::fcn_info_rep::erase_subfunction,
+	symbol_table::erase_subfunctions_in_scope):
+	New functions.
+	(symbol_table::fcn_info::fcn_info_rep::clear_user_function):
+	Erase subfunctions here.
+
+	* variables.cc (Fmlock): Doc fix.
+
+2008-06-05  John W. Eaton  <jwe at octave.org>
+
+	* gl-render.cc (opengl_renderer::draw): Correctly avoid shadow
+	warnings from gcc for xmin, xmax, ymin, ymax, zmin, and zmax.
+
+	* graphics/ChangeLog, graphics/Makefile.in, graphics/Makerules.in,
+	graphics/fltk_backend/Makefile.in, graphics/opengl/Makefile.in:
+	Delete.
+
+	* gl-render.cc, gl-render.h: Move here from src/graphics/opengl.
+	* Makefile.in: Add them to the appropriate lists.
+	(octave$(EXEEXT)): Also link with $(OPENGL_LIBS)
+
+	* fltk_backend.cc: Move here from src/graphics/fltk_backend.
+	* Makefile.in (DLD_XSRC): Add it to the list
+	(fltk_backend.oct): Include special rules for linking with
+	$(GRAPHICS_LIBS) and $(FT2_LIBS).
+
+	* dynamic-ld.cc (octave_dynamic_loader::mex_mangler,
+	octave_dynamic_loader::mex_uscore_mangler,
+	octave_dynamic_loader::mex_f77_mangler): New functions.
+	(octave_dynamic_loader::do_load_mex): Use them.
+	(octave_dynamic_loader::do_remove_oct): Rename from
+	octave_dynamic_loader::do_remove.
+	(octave_dynamic_loader::do_remove_mex): New function.
+	* dynamic-ld.h: Provide/fix decls.
+
+	* graphics.cc (properties::update_normals): Style fixes.
+	* graphics.h.in: Style fixes.
+
+	ChangeLog entries for gl-render.h, gl-render.cc, and
+	fltk_backend.cc before the move:
+
+	2008-06-05  John W. Eaton  <jwe at octave.org>
+
+	* opengl/gl-render.cc (xmin): New static function.
+
+	* opengl/gl-render.h (opengl_renderer): Style fixes.
+	* fltk_backend/fltk_backend.cc: Style fixes.
+
+	2008-04-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.h (opengl_renderer::draw(hggroup)): New method.
+	* opengl/gl-render.cc (opengl_renderer::draw(hggroup)): Likewise.
+	(opengl_renderer::draw(graphics_object)): Call it.
+
+	2008-03-17  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (plot_window::resize,
+	plot_window::draw): make canvas the size of figure.position
+
+	2008-03-09  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (plot_window::handle): add zoom
+	stack
+
+	2008-03-06  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (plot_window::handle): Add handling
+	of the 'a' and 'g' keys
+	(plot_window: toggle_grid): New helper function
+	(plot_window): Add new togglegrid button
+
+	2008-03-01  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (OpenGL_fltk::draw_overlay,
+	OpenGL_fltk::zoom, OpenGL_fltk::set_zoom_box): Added to support
+	zoom box
+	(plot_window::handle): Added zoom box code, B-3 now does autoscale
+	(plot_window::axis_auto): New utility function to call axis("auto")
+	(plot_window::button_press): "A" button now does autoscale
+
+	* opengl/gl-render.cc (make_marker_list): Add the "+x*.^v><"
+	markers
+
+	2008-02-27  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.cc (opengl_renderer::draw(patch),
+	opengl_renderer::draw(surface)): Adapt to type change of facealpha and
+	edgealpha, using double_radio_property class.
+
+	2008-02-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.h: Make sure windows.h is included before OpenGL
+	headers.
+	* fltk_backend/Makefile.in (FLTK_EXTRA_CXXFLAGS): Use $(srcdir) for
+	includesion of OpenGL renderer headers.
+	(Makeconf): Move inclusion of Makeconf later on, to avoid freezing
+	MinGW make.
+
+	* fltk_backend/Makefile.in (GRAPHICS_CFLAGS): New substituted
+	variable.
+
+	2008-02-25  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (class plot_window): Many changes
+	to use figure::properties instead of figure handle to reference
+	the figure
+	(class figure_manager): ditto
+	(__fltk_redraw__): moved most of functionality into the
+	figure_manager class
+	(plot_window::pixel2pos): Modified to use axes::pixel2coord
+	(plot_window::pixel2staus): Modified to use pixel2pos
+	(plot_window::handle): Added zoom with mouse 
+
+	2008-02-24  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (OpenGL_fltk::Draw): removed double
+	buffer switch
+	(OpenGL_fltk::setup_viewport): removed call to glOrtho --
+	gl-render takes care of all the transformations
+
+	2008-02-23  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/fltk_backend.cc (plot_window::mark_modifed): mark
+	the whole window as damaged (otherwise changing figure.postion
+	does not have immediate effect)
+	(plot_window::draw): New function, checks for window size 
+	(__fltk_maxtime__): New DEFUN to allow tweaking of fltk timeout
+	(__fltk_redraw__): Use fltk_maxtime as timeout
+
+	2008-02-21  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.cc (opengl_renderer::patch_tesselator::combine):
+	Protect against NULL vertex data.
+
+	* opengl/gl-render.cc (opengl_renderer::draw(patch)): Add marker
+	rendering of patch objects.
+
+	2008-02-21  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* opengl/gl-render.cc: remove OpenGL includes
+	* opengl/gl-render.h: add OpenGL includes
+	* fltk_backend/fltk_backend.cc: remove OpenGL includes
+	(__fltk_redraw__): put figure handle into the figure's
+	__plot_stream__ property for later
+	(fltk_backend::close_figure): use argument as figure handle to
+	close
+
+	2008-02-20  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* fltk_backend/Makefile.in: initial import
+
+	* fltk_backend/fltk_backend.cc: initial import
+	
+
+	2008-02-20  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.h (opengl_renderer::draw(patch)): New method to
+	render patch objects.
+	(class opengl_renderer::patch_tesselator): Forward declaration.
+	* opengl/gl-render.cc (opengl_texture::create): Use RGB data format
+	instead of RGBA.
+	(class opengl_tesselator): New classes to abstract GLU tessellation
+	process.
+	(class opengl_renderer::patch_tesselator): New class to render opaque
+	patch objects.
+	(class vertex_data): New class to hold vertex data during tessellation
+	of patch objects.
+	(opengl_renderer::draw(patch)): New method to render patch objects (no
+	transparency, no border, no marker yet).
+	(opengl_renderer::draw(graphics_object)): Dispatch to it.
+
+	* opengl/gl-render.cc (opengl_renderer::draw(patch)): Use patch color
+	data and support face/vertex single color specification.
+
+	* opengl/gl-render.cc (opengl_tesselator::begin_polygon): Set
+	tessellation property also for non-filled polygons.
+	(opengl_renderer::patch_tesselator::vertex): Protect against empty
+	color matrices.
+	(opengl_renderer::draw(patch)): Render patch border (no transparency
+	yet).
+
+	2008-02-19  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.cc (opengl_texture::texture_rep::tex_coord,
+	opengl_texture::tex_coord): New wrapper around glTexCoord2d.
+	(opengl_renderer::draw(surface)): Use it for texturemap
+	implementation.
+	(opengl_renderer::draw(surface)): Fix indexing bug when creating clip
+	matrix.
+	(opengl_texture::operator=): Add assignment operator.
+	(opengl_texture::create): New static opengl_texture creator.
+	(opengl_texture::is_valid): New accessor.
+
+	2008-02-18  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.cc (class opengl_texture): New class to wrap
+	texture operations in OpenGL.
+
+	2008-02-17  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.cc (opengl_renderer::draw(surface)): Set material
+	color when rendering surface facets.
+
+	* opengl/gl-render.cc (opengl_renderer::draw(surface)): Add rendering
+	of mesh and markers.
+
+	2008-02-16  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.cc (opengl_renderer::draw(figure)): Initialize the
+	OpenGL context correctly.
+	(opengl_renderer::draw(surface)): Add missing glEnd call.
+
+	2008-02-14  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* opengl/gl-render.h opengl/gl-render.cc: Add rendering
+	interface for surface objects (actual implement still
+	missing).
+
+	2008-02-14  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Makefile.in Makerules.in: Initial import
+	* opengl/Makefile.in: Likewise.
+	* opengl/gl-render.h opengl/gl-render.cc: Likewise.
+
+2008-06-04  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.cc (axes::properties::set_defaults): Preserve position
+	if mode is replace.
+	(axes::properties::sync_positions): Use default_axes_postion for
+	consistency.
+
+	* graphics.h.in (axes::properties::sync_positions,
+	axes::properties::update_position,
+	axes::properties::update_outerposition): New functions to sync
+	outerposition and position.
+
+	* graphics.h.in (axes::properties::update_xlim,
+	axes::properties::update_ylim, axes::properties::update_zlim):
+	pass is_logscale flag to axes::properties::calc_ticks_and_lims
+	* graphics.cc (axes::properties::calc_ticks_and_lims): Added
+	support for log scale
+
+	* graphics.h.in (axes::properities::fix_limits) : New method.
+	(axes::properties::update_xlim, axes::properties::update_ylim,
+	axes::properties::update_zlim): Use fix_limits.
+
+	* graphics.cc (axes::properties::calc_ticks_and_lims): Make sure
+	that lo <= hi.
+
+	* graphics.h.in (axes::pixel2coord, axes::coord2pixel): New functions.
+
+	* graphics.cc (convert_position): No longer static.
+	* graphics.h.in: Provide decl.
+
+ 	* graphics.cc (Favailable_backends): New function.
+  	* graphics.h.in (base_graphics_backend::available_backends_list):
+	New function.
+
+	* graphics.cc (axes::properties::calc_ticks_and_lims): Refactor.
+	Adjust axes limits & tics together so that the result is consistent.
+	(axes::properties::calc_tick_sep): Ditto.
+	(axes::properties::get_axis_limits): Ditto.  Now a member of
+	axes::properties
+	(magform): Now file-scope static function instead of
+	axes::properties member function.
+
+	* graphics.h.in (axes::properties::update_xlim): call the new
+	axes::properties::calc_ticks_and_lims method
+	(axes::properties::update_ylim): ditto
+	(axes::properties::update_zlim): ditto
+
+2008-06-04  Michael Goffioul <michael.goffioul at gmail.com>
+
+	* ov-fcn-inline.h (class octave_fcn_inline): Mark with OCTINTERP_API.
+	* ov-fcn-handle.h (class Octave_fcn_handle): Likewise.
+	* ls-oct-binary.h (save_binary_data, read_binary_data): Likewise.
+
+	* genprops.awk (emit_source): Fix if-then-else statement generation
+	when the first property is hidden.
+	* graphics.h.in (base_properties::adopt): Call mark_modified.
+	(class hggroup): New graphics object class.
+	* graphics.cc (lookup_object_name, make_graphics_object_from_type,
+	property_list::lookup, property_list::set,
+	root_figure::init_factory_properties): Support hggroup as possible
+	object type.
+	(hggroup::update_axis_limits): New graphics object class.
+	(make_graphics_object): Look for "parent" property in the arguments
+	and use it as actual parent for the created object.
+	(F__go_hggroup__): New function.
+	(F__go_delete__): Set Vdrawnow_requested to true.
+
+	* graphics.h.in (base_property::clone, string_property::clone,
+	radio_property::clone, color_property::clone, double_property::clone,
+	double_radio_property::clone, array_property::clone,
+	row_vector_property::clone, bool_property::clone,
+	handle_property::clone, callback_property::clone, any_property::clone,
+	property::clone): New virtual method.
+	(property::create): New static method to create dynamic properties.
+	(base_properties::has_property): New method to check the existence of
+	a property.
+	(any_property::any_property, row_vector_property::row_vector_property,
+	double_radio_property::double_radio_property): New copy constructors.
+	* graphics.cc (lookup_object_name): New static utility function.
+	(make_graphics_object_from_type): Likewise.
+	(gh_manager::do_make_graphics_handle): Use it.
+	(dprop_obj_map): New static map used for chaching purpose in dynamic
+	property creation.
+	(property::create): New static method to create dynamic properties.
+	(base_properties::has_property): New method to check the existence of
+	a property.
+	(base_properties::override_defaults): Check parent validity.
+	(Faddlistener): Documentation fix.
+	(Faddproperty): New function to create dynamic properties.
+
+	* genprops.awk (emit_get_array): Don't produce get_xxx_property
+	accessors.
+	* graphics.h.in (array_property::get_limits): New method to return the
+	array limits.
+	(base_properties::get_xdata_property,
+	base_properties::get_ydata_property,
+	base_properties::get_zdata_property,
+	base_properties::get_ldata_property,
+	base_properties::get_udata_property,
+	base_properties::get_xldata_property,
+	base_properties::get_xudata_property,
+	base_properties::get_cdata_property): Remove methods, replaced with
+	limit-based equivalent.
+	(base_graphics_object::get_xdata_property,
+	base_graphics_object::get_ydata_property,
+	base_graphics_object::get_zdata_property,
+	base_graphics_object::get_ldata_property,
+	base_graphics_object::get_udata_property,
+	base_graphics_object::get_xldata_property,
+	base_graphics_object::get_xudata_property,
+	base_graphics_object::get_cdata_property): Likewise.
+	(graphics_object::get_xdata_property,
+	graphics_object::get_ydata_property,
+	graphics_object::get_zdata_property,
+	graphics_object::get_ldata_property,
+	graphics_object::get_udata_property,
+	graphics_object::get_xldata_property,
+	graphics_object::get_xudata_property,
+	graphics_object::get_cdata_property): Likewise.
+	(base_properties::get_xlim, base_properties::get_ylim,
+	base_properties::get_zlim, base_properties::get_clim,
+	base_properties::get_alim, base_properties::is_xliminclude,
+	base_properties::is_yliminclude, base_properties::is_zliminclude,
+	base_properties::is_climinclude, base_properties::is_aliminclude):
+	New methods.
+	(base_graphics_object::get_xlim, base_graphics_object::get_ylim,
+	base_graphics_object::get_zlim, base_graphics_object::get_clim,
+	base_graphics_object::get_alim, base_graphics_object::is_xliminclude,
+	base_graphics_object::is_yliminclude,
+	base_graphics_object::is_zliminclude,
+	base_graphics_object::is_climinclude,
+	base_graphics_object::is_aliminclude): Likewise.
+	(graphics_object::get_xlim, graphics_object::get_ylim,
+	graphics_object::get_zlim, graphics_object::get_clim,
+	graphics_object::get_alim, graphics_object::is_xliminclude,
+	graphics_object::is_yliminclude, graphics_object::is_zliminclude,
+	graphics_object::is_climinclude, graphics_object::is_aliminclude):
+	Likewise.
+	(base_graphics_object::update_axis_limits): Provide default behavior
+	by passing the call to the parent object.
+	(line::properties::xdata, line::properties::ydata,
+	line::properties::zdata, line::properties::ldata,
+	line::properties::udata, line::properties::xldata,
+	line::properties::xudata): Replace 'l' modifier with 'u'.
+	(line::properties::xlim, line::properties::ylim,
+	line::properties::zlim, line::properties::xliminclude,
+	line::properties::yliminclude, line::properties::zliminclude): New
+	hidden properties.
+	(line::properties::update_xdata, line::properties::update_ydata,
+	line::properties::update_zdata, line::properties::update_xldata,
+	line::properties::update_xudata, line::properties::update_ldata,
+	line::properties::update_udata): New updaters that update limit
+	properties.
+	(line::properties::compute_xlim, line::properties::compute_ylim): New
+	method to compute actual limits taking into account x/y data and
+	upper/lower bounds.
+	(text::properties::position): Add 'u' modifier.
+	(text::properties::xlim, text::properties::ylim,
+	text::properties::zlim, text::properties::xliminclude,
+	text::properties::yliminclude, text::properties::zliminclude): New
+	hidden properties.
+	(text::properties::update_position): New updater that updates limit
+	properties.
+	(image::properties::xdata, image::properties::ydata,
+	image::properties::cdata): Replace 'l' modifier with 'u'.
+	(image::properties::cdatamapping): Add 'l' modifier.
+	(image::properties::xlim, image::properties::ylim,
+	image::properties::clim, image::properties::xliminclude,
+	image::properties::yliminclude, image::properties::climinclude): New
+	hidden properties.
+	(image::properties::get_climinclude,
+	image::properties::is_climinclude): Provide specialized inline
+	accessors.
+	(image::properties::update_xdata, image::properties::update_ydata,
+	image::properties::update_cdata): New updaters that update limit
+	properties.
+	(patch::properties::xdata, patch::properties::ydata,
+	patch::properties::zdata, patch::properties::cdata): Replace 'l'
+	modifier with 'u'.
+	(patch::properties::cdatamapping): Add 'l' modifier.
+	(patch::properties::alphadatamapping): New property.
+	(patch::properties::xlim, patch::properties::ylim,
+	patch::properties::zlim, patch::properties::clim,
+	patch::properties::alim, patch::properties::xliminclude,
+	patch::properties::yliminclude, patch::properties::zliminclude,
+	patch::properties::climinclude, patch::properties::aliminclude: New
+	hidden properties.
+	(patch::properties::get_climinclude,
+	patch::properties::is_climinclude, patch::properties::get_aliminclude,
+	patch::properties::is_aliminclude): Provide specialized inline
+	accessors.
+	(patch::properties::update_xdata, patch::properties::update_ydata,
+	patch::properties::update_zdata, patch::properties::update_cdata): New
+	updaters that update limit properties.
+	(surface::properties::xdata, surface::properties::ydata,
+	surface::properties::zdata, surface::properties::cdata,
+	surface::properties::alphadata): Replace 'l' modifier with 'u'.
+	(surface::properties::cdatamapping,
+	surface::properties::alphadatamapping): Add 'l' modifier.
+	(surface::properties::xlim, surface::properties::ylim,
+	surface::properties::zlim, surface::properties::clim,
+	surface::properties::alim, surface::properties::xliminclude,
+	surface::properties::yliminclude, surface::properties::zliminclude,
+	surface::properties::climinclude, surface::properties::aliminclude: New
+	hidden properties.
+	(surface::properties::get_climinclude,
+	surface::properties::is_climinclude,
+	surface::properties::get_aliminclude,
+	surface::properties::is_aliminclude): Provide specialized inline
+	accessors.
+	(surface::properties::update_xdata, surface::properties::update_ydata,
+	surface::properties::update_zdata): Update limit properties.
+	(surface::properties::update_cdata,
+	surface::properties::update_alphadata): New updaters that update limit
+	properties.
+	* graphics.cc (base_properties::update_axis_limits): Simply call
+	update_axis_limits in owning graphics_object.
+	(base_graphics_object::update_axis_limits): Provide default behavior
+	by passing the call to the parent object.
+	(check_limits_vals(double&,double&,double&,const octave_value&)): New
+	static method to work with new limit properties in graphics objects.
+	(get_children_limits): New static method to compute the raw limits of
+	a set of children, based on the new limit properties.
+	(axes::update_axis_limits): Simplify and call get_children_limits. Add
+	handling of alpha limits.
+	(line::properties::compute_xlim, line::properties::compute_ylim): New
+	methods to compute line limits taking into account upper/lower bounds.
+
+	* graphics.cc (axes::properties::sync_positions): Update
+	transformation data.
+
+	* graphics.cc (Faddlistener): Rename from Fadd_listener.
+
+	* graphics.h.in (axes::properties::pixel2coord): Center Z coordinate
+	on x_zlim instead of 0.
+	(axes::properties::zoom, axes::properties::unzoom,
+	axes::properties::clear_zoom_stack): New methods to handle zoom stack.
+	(axes::properties::zoom_stack): New field to hold zoom stack.
+	(axes::properties::update_xlim, axes::properites::update_ylim):
+	Additional do_clr_zoom argument to control whether the zoom stack will
+	be cleared.
+	(axes::properties::update_zlim): Clear zoom stack.
+	* graphics.cc (axes::properties::zoom, axes::properties::unzoom,
+	axes::properties::clear_zoom_stack): New methods to handle zoom stack.
+
+	* genprops.awk (emit_source): Use all properties in factory defaults.
+
+	* graphics.h.in (base_property::base_property): Set internal counter
+	to 1 by default.
+	(property::property): Adapt constructors to default counter value in
+	base_property.
+
+	* graphics.h.in (base_properties::get_property): Make virtual and
+	remove const modifier.
+	* graphics.cc (base_properties::get_property): Can return built-in
+	properties. Generate an error if the property does not exist.
+	(base_properties::add_listener): Use get_property.
+	(Fadd_listener): Add documentation.
+	* genprops.awk (emit_common_declarations, emit_source): Emit code for
+	overloaded get_property method.
+
+	* genprops.awk (emit_declarations): Run listeners in the property
+	setter methods.
+	* graphics.h.in (enum listener_mode): New enum type for listeners.
+	(base_property::set): Make non-virtual and handle listeners execution.
+	(base_property::listeners): New field holding a map of listeners.
+	(base_property::add_listener, base_property::run_listeners,
+	base_property::do_set): New methods to handle listeners.
+	(property::add_listener, property::run_listeners): Likewise.
+	(base_properties::add_listener): Likewise.
+	(base_graphics_object::add_property_listener,
+	graphics_object::add_property_listener): Likewise.
+	(all property classes): Rename set to do_set and make it protected.
+	* graphics.cc (base_property::run_listeners): New method to execute
+	listeners.
+	(color_property::set, double_radio_property::set,
+	handle_property::set): Rename to do_set.
+	(base_properties::add_listener): New method to handle listener
+	additio. Only handle dynamic properties.
+	(Fadd_listener): New octave interface to add property listeners to
+	graphics object.
+
+	* genprops.awk (emit_get_data): Remove.
+	(emit_declarations): Treat row_vector_property as array_property and
+	remove data_property references.
+	* graphics.h.in (array_property::array_property(array_property)): Add
+	copy constructor.
+	(class data_property): Remove (replaced by array_property).
+	(class base_graphics_backend, class graphics_backend): Replace
+	data_property references with array_property.
+	(line::properties::xdata, line::properties::ydata,
+	line::properties::zdata, line::properties::ldata,
+	line::properties::udata, line::properties::xldata,
+	line::properties::xudata): Turn into row_vector_property.
+	(image::properties::xdata, image::properties::ydata): Likewise.
+	(image::properties::init): Add length constraints for xdata and ydata.
+	(patch::properties::xdata, patch::properties::ydata,
+	patch::properties::zdata, patch::properties::facevertexalphadata):
+	Turn into array_property.
+	(surface::properties::xdata, surface::properties::ydata,
+	surface::properties::zdata): Likewise.
+	(patch::properties::init): Add size constraints for xdata, ydata,
+	zdata and facevertexalphadata.
+	(surface::properties::init): Add size constraints for xdata, ydata and
+	zdata.
+	* graphics.cc (check_limit_vals): Remove override with data_property.
+	(axes::update_axis_limits): Replace data_property references with
+	array_property.
+
+	* graphics.h.in (root_figure::get_default): Use factory defaults when
+	no explicit default value exists.
+	(figure::properties::set___backend__): Reset __plot_stream__ to empty
+	value.
+	* graphics.cc (gh_manager::gh_manager): Call
+	graphics_backend::default_backend to make sure the default backend is
+	initialized.
+
+	* graphics.h.in (patch::properties::edgealpha,
+	surface::properties::facealpha, surface::properties::edgealpha): Fix
+	typos in property names.
+
+	* graphics.h.in (class double_radio_property): New property class for
+	holding face/edge alpha values.
+	(patch::properties::facealpha, patch::properties::edgealpha,
+	surface::properties::facealpha, surface::properties::edgealpha): Use
+	double_radio_property class.
+	* graphics.cc (double_radio_property::set): Implement new property
+	class.
+	* genprops.awk (emit_get_double_radio): New function to emit code for
+	double_radio_property.
+	(emit_declarations): Use it.
+
+	* graphics.h.in (array_property::array_property(void)): New default
+	constructor.
+	(array_property::xmin, array_property:xmax, array_property::xminp,
+	array_property::min_val, array_property::max_val,
+	array_property::min_pos): New fields and accessors to hold min/max
+	values of the array data.
+	(array_property::get_data_limits): New method to compute min/max
+	values of the array data.
+	(base_properties::get_cdata_property,
+	graphics_object::get_cdata_property): Return array_property.
+	(image::properties::cdata, surface::properties::cdata,
+	patch::properties::cdata, patch::properties::facevertexcdata): Turn
+	into array_property type.
+	(image::properties::init, surface::properties::init,
+	patch::properties::init): Add constraint initialization for cdata and
+	facevertexcdata (patch only).
+	* genprops.awk (emit_get_array): New function to emit accessor for
+	array_property.
+	(emit_declarations): Use it.
+	* graphics.cc (get_array_limits): New template function to compute
+	min/max values of an Array<T> object.
+	(array_property::get_data_limits): New method to compute min/max
+	values of the array data, using get_array_limits.
+	(check_limit_vals): Overridden function with array_property.
+	(axes::update_axis_limits): Turn cdata property into array_property.
+
+	* graphics.h.in (patch::properties::get_color_data): New utility
+	function to retrieve actual color data.
+	* graphics.cc (patch::properties::get_color_data): Likewise.
+
+	* graphics.h.in (base_scaler::is_linear, lin_scaler::is_linear,
+	scaler::is_linear): New method to detect linear scales.
+	(graphics_xform::scale(Matrix)): New method to scale 2D/3D coordinates
+	directly.
+	(patch::properties::facelighting): Set default value to "none".
+
+	* graphics.h.in (axes::axes): Be sure to initialize transformation
+	data correctly.
+
+	* graphics.cc (xget_ancestor): Pass graphics_object argument by value
+	instead of by reference.
+
+	* graphics.h.in (surface::properties::xdata,
+	surface::properties::ydata, surface::properties::zdata,
+	surface::properties::normalmode, surface::properties::vertexnormals):
+	Add 'u' modifier.
+	(surface::properties::update_normals): New method to compute normals
+	automatically.
+	(surface::properties::update_xdata, surface::properties::update_ydata,
+	surface::properties::update_zdata,
+	surface::properties::update_normalmode,
+	surface::properties::update_vertexnormals): New updaters to update
+	normals automatically.
+	* graphics.cc (surface::properties::update_normals): Likewise.
+	(cross_product): New inlined utility function for cross product
+	computation adn accumulation.
+
+	* graphics.h.in (class base_scaler, class lin_scaler, class
+	log_scaler, class scaler): Add scale method for NDArray.
+	(log_scaler::do_scale): Factorize scaling code.
+
+	* graphics.h.in (figure::properties::update_position): Re-remove.
+	(figure::properties::facecolor): Re-add 'texturemap' value.
+	(surface::properties::get_color_data): New method to compute actual
+	surface color data from cdata.
+	* graphics.cc (surface::properties::get_color_data): Likewise.
+	(xget_ancestor): New utility function to retrieve an ancestor of a
+	given type.
+	(convert_cdata): New utility function to convert cdata property into
+	actual color data.
+
+	* graphics.h.in (surface::properties::facecolor): Add "texturemap"
+	as possible value.
+	(class surface::properties): New properties alphadata,
+	alphadatmapping, ambientstrength, backfacelighting, diffusestrength,
+	edgealpha, edgelighting, erasemode, facelighting, meshstyle,
+	normalmode, specularcolorreflectance, specularexponent,
+	specularstrength, vertexnormals.
+	(surface::properties::init): Add constraints for alphadata,
+	vertexnormals and cdata (the latter are commented until cdata
+	has changed type).
+
+	* graphics.h.in (base_properties::update_boundingbox): New method
+	to handle object resize.
+	(figure::properties::set_boundingbox): New method to set figure
+	position from backend.
+	(figure::properties::update_position): Remove method.
+	(figure::properties::position): Remove 'u' modifier and add 'S'
+	modifier.
+	(axes::properties::update_boundingbox): Overload to recompute
+	transformation when axes size changed.
+	* graphics.cc (base_properties::update_boundingbox): New method.
+	(figure::properties::set_boundingbox,
+	figure::properties::set_position): Likewise.
+
+	* genprops.awk: Add 'U' modifier to support extern updaters.
+	* graphics.h.in (base_graphics_backend::gripe_invalid): New method
+	to simplify error reporting.
+	(class base_graphics_backend): Use it.
+	(base_graphics_backend::set_figure_position): New backend method.
+	(graphics_backend::set_figure_position): Likewise.
+	(figure::properties::position): Mark property with updater.
+	(figure::properties::update_position): New updater.
+
+	* graphics.h.in (root_figure::properties::callbackobject):
+	New root property.
+	(root_figure::properties::cbo_stack): New field.
+	* graphics.cc (xset_gcbo, xreset_gcbo): New utility functions.
+	(execute_callback): Set callbackobject property in root object
+	before executing a callback.
+	(root_figure::properties::set_callbackobject): Implement accessor.
+
+	* graphics.h.in (root_figure::properties::callbackobject):
+	New root property.
+	(root_figure::properties::cbo_stack): New field.
+	* graphics.cc (xset_gcbo, xreset_gcbo): New utility functions.
+	(execute_callback): Set callbackobject property in root object
+	before executing a callback.
+	(root_figure::properties::set_callbackobject): Implement accessor.
+
+	* graphics.h.in (class root_figure::properties,
+	class line::properties, class text::properties,
+	class image::properties, class patch::properties,
+	class surface::properties): Export classes with
+	OCTINTERP_API.
+
+	* graphics.cc (axes::properties::set_defaults): Use correct
+	default values for gridlinestyle and minorgridlinestyle.
+
+2008-06-03  Jaroslav Hajek  <highegg at gmail.com>
+
+	* load-save.cc (Fload): Fix "-7" option.
+
+2008-06-02  David Bateman  <dbateman at free.fr>
+
+	* pt.cc (tree:last_break_function): Next pointer to last function
+	with a breakpoint.
+	* pt.h (tree:last_break_function): ditto.
+	* debug.cc (Fdbstep): Use tree::break_function value of zero to
+	signal to step into the next function. Set tree::last_break_function
+	to indicate position of last breakpoint.
+	(Fdbnext):  Set tree::last_break_function to indicate position of
+	last breakpoint.
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Check tree::break_function value
+	of zero as well. Only check tree::last_line if we are in teh same
+	function as the last breakpoint.
+	* input.cc (char Vfilemarker): New global variable.
+	(Ffilemarker): New function to query and set Vfilemarker.
+	* input.h (extern char Vfilemarker): Make Vfilemarker available.
+	* util.cc (fcn_file_in_path): If the input argument contains
+	Vfilemarker, strip the trailing part of string from this point
+	when looking for function file.
+	* toplev.cc (octave_call_stack::fo_backtrace): Mark subfunctions
+	with the name of the parent function and Vfilemarker.
+	* symtab.cc (symbol_table::find_function (const std::string&,
+	tree_argument_list *, const string_vector&, octave_value_list*,
+	bool&): If function name contains Vfilemarker, check in scope of
+	specified parent function.
+
+	* DLD-FUNCTIONS/betainc.cc: Move test code here. Add test code for
+	single precision type.
+	* DLD-FUNCTIONS/gammainc.cc: Ditto.
+	* DLD-FUNCTIONS/gcd.cc (Fgcd): Support single precision. Move test
+	code here. Add test code for single precision type.
+	* data.cc: Move test code here and add tests for single precision
+	type. Add tests for Fislogical.
+	(NATIVE_REDUCTION): Support the 'double' argument.
+	* mapper.cc: Move test code here and add tests for single precision
+	type.
+	* ov-float.cc (CD_SCALAR_MAPPER): Replace Complex with
+	FloatComplex.
+	(erf, erfc, abs, acos, asin, asinh, atan, atanh, ceil, cos, cosh,
+	exp, expm1, floor, log10, log1p, sin, sinh, sqrt, tan, tanh): Use
+	float version of base functions (ie. ::sinf and not ::sin)
+	(lgamma, acosh, log, log2, log10, log1p): Use single precision
+	infinity value.
+	* ov-flt-complex.cc (erf, erfc, expm1, log1p): Use the float
+	version of base functions.
+	* ov-flt-cx-mat.cc (DARRY_MAPPER): Replace NDArray with FloatNDArray.
+	(erf, erdc, gamma): Use FloatNDArray::dmapper and not
+	NDArray::dmapper.
+	* ov-flt-cx-mat.h (is_double_type): Delete.
+	(is_single_type): New method.
+	* ov-flt-re-mat.cc (lgamma,  acosh, log, log2, log10, log1p,
+	sqrt): Use single precision infinity value.
+	
+	* chol.cc (Fcholinv, Fchol2inv, Fcholupdate, Fcholinsert,
+	Fcholdelete, Fcholshift): Allow single precision arguments.
+	(Fchol): Move test code here. Add test code for single precision.
+	(Fcholupdate, Fcholinsert, Fcholdelete, Fcholshift): Add test code
+	for single precision.
+	* conv2.cc (Fconv2): Add single precision test code.
+	* det.cc (Fdet): For single values or empty matrices, return
+	single precision arg for single precion input. Move test code
+	here. Add single precision test code.
+	* fft.cc (do_fft): For empty single precision arguments return a
+	single precision value. Add single precision test code. Remove
+	fft2 test code.
+	* fft2.cc (do_fft2): For empty single precision arguments return a
+	single precision value. Add single precision test code. Move fft2
+	test code here.
+	* fftn.cc (do_fftn): For empty single precision arguments return a
+	single precision value.
+	* eig.cc (Feig):  Move test code here. Add single precision test
+	code.
+	* expm.cc (Fexpm): Ditto.
+	* find.cc (Ffind): Ditto.
+	* hess.cc (Fhess): Ditto.
+	* inv.cc (Finc): Ditto.
+	* lu.cc (Flu): Ditto.
+	* qr.cc (Fqr): Ditto.
+	* schur.cc (Fschur): Ditto.
+	* svd.cc (Fsvd): Ditto.
+	* syl.cc (Fsyl): Ditto.
+	
+	* op-fcm-fcm.cc, op-fcm-fcs.cc, op-fcm-fm.cc, op-fcm-fs.cc, 
+	op-fcs-fcm.cc, op-fcs-fcs.cc, op-fcs-fm.cc, op-fcs-fs.cc, 
+	op-fm-fcm.cc, op-fm-fcs.cc, op-fm-fm.cc, op-fm-fs.cc, 
+	op-fs-fcm.cc, op-fs-fcs.cc, op-fs-fm.cc, op-fs-fs.cc: Add mixed
+	double, single precision concatenation operators.
+
+	* data.cc (Fall, Fany, Fdiag, Fcat, Fismatrix, Fones, Fzeros,
+	Finf, FNaN, FNA, Feye, Flinspace, Freshape, Ftranspose,
+	Fctranspose, Fsort). Move tests here. Add single precision tests.
+	* mappers.cc (Ffinite, Fisinf, Fisna, Fisnan): Ditto.
+	* ov-float.cc (octave_float_scalar:resize): single precision
+	return value.
+	* ov.cc (octave_value::octave_value (const
+	FloatComplexDiagMatrix&)): Ditto.
+	* data.cc (Fnorm): Add single precision.
+	(do_cat): Disable fast return and skipping empty matrices, as they
+	play a part in determining the return type.
+	* ov.cc (octave_value do_cat_op (const octave_value&, const
+	octave_value&, const Array<octave_idx_type>&)): ditto.
+
+2008-06-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-cell.cc (Fcellstr): For compatibility with Matlab, return {''}
+	when given ''.
+
+2008-05-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/fsolve.cc (fsolve_user_function,
+	fsolve_user_jacobian): Reshape argument to original dims before
+	passing. 
+	(Ffsolve): Save original dimensions of the starting guess and reshape
+	on return. Fix tests.
+
+2008-05-21  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/quad.cc (quad_float_user_function): New function.
+	(Fquad): Handle float type.
+	New tests.
+
+2008-05-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	* OPERATORS/op-fcm-fcm.cc (trans_mul, mul_trans, herm_mul, mul_herm):
+	New functions.
+	(install_fcm_fcm_ops): Install them.
+	* OPERATORS/op-fm-fm.cc (trans_mul, mul_trans): New functions.
+	(install_fm_fm_ops): Install them.
+
+	* OPERATORS/op-sm-m.cc (trans_mul): New function.
+	(install_sm_m_ops): Register it.
+	* OPERATORS/op-m-sm.cc (mul_trans): New function.
+	(install_m_sm_ops): Register it.
+	* OPERATORS/op-scm-cm.cc (trans_mul, herm_mul): New function.
+	(install_scm_cm_ops): Register it.
+	* OPERATORS/op-cm-scm.cc (mul_trans, mul_herm): New function.
+	(install_cm_scm_ops): Register it.
+
+	* dMatrix.cc: Declare DSYRK.
+	(xgemm): Call DSYRK if symmetric case detected.
+	* CMatrix.cc: Declare ZSYRK, ZHERK.
+	(xgemm): Call ZSYRK/ZHERK if symmetric/hermitian case detected.
+
+	* ov.h (octave_value::compound_binary_op): New enum.
+	(do_binary_op (octave_value::compound_binary_op, ...), 
+	octave_value::binary_op_fcn_name (compound_binary_op),
+	octave_value::do_binary_op (compound_binary_op, ...)):
+	New declarations.
+	(OV_COMP_BINOP_FN): New macro (+ several expansions).
+	* ov.cc (octave_value::binary_op_fcn_name (compound_binary_op),
+	decompose_binary_op, do_binary_op (compound_binary_op, ...)): 
+	New functions.
+	* ov-typeinfo.h (octave_value_typeinfo::register_binary_class_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::register_binary_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::do_register_binary_class_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::do_register_binary_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::do_lookup_binary_class_op 
+	(octave_value::compound_binary_op),
+	octave_value_typeinfo::do_lookup_binary_op 
+	(octave_value::compound_binary_op, ...)):
+	New declarations.
+	(octave_value_typeinfo::lookup_binary_class_op
+	(octave_value::compound_binary_op),
+	(octave_value_typeinfo::lookup_binary_op
+	(octave_value::compound_binary_op, ...)):
+	New functions.
+	(octave_value_typeinfo::compound_binary_class_ops,
+	octave_value_typeinfo::compound_binary_ops): 
+	New fields.
+	* ov-typeinfo.cc (octave_value_typeinfo::register_binary_class_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::register_binary_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::do_register_binary_class_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::do_register_binary_op 
+	(octave_value::compound_binary_op, ...),
+	octave_value_typeinfo::do_lookup_binary_class_op 
+	(octave_value::compound_binary_op),
+	octave_value_typeinfo::do_lookup_binary_op 
+	(octave_value::compound_binary_op, ...)):
+	New functions.
+	(octave_value::do_register_type): Resize also compound_binary_ops
+	field.
+	* pt-exp.h (tree_expression::is_unary_expression): New virtual
+	function.
+	* pt-unop.h (tree_unary_expression::is_unary_expression): New virtual
+	override.
+	* pt-cbinop.h, pt-cbinop.cc: New files (implement
+	tree_compound_binary_expression class).
+	* pt-all.h: Include pt-cbinop.h.
+	* Makefile.in (PT_INCLUDES, PT_SRC): Include them in the lists.
+	* parse.y (make_binary_op): Call maybe_compound_binary_expression.
+	* OPERATORS/op-m-m.cc (trans_mul, mul_trans): New operator handlers.
+	(install_m_m_ops): Register them.
+	* OPERATORS/op-cm-cm.cc (trans_mul, mul_trans, herm_mul, mul_herm): 
+	New operator handlers.
+	(install_cm_cm_ops): Register them.
+
+	* DLD-FUNCTIONS/matrix_type.cc: Fix tests relying on the
+	older more optimistic hermitian check.
+
+2008-05-21  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/rcond.cc (Frcond): Add support for single precision.
+
+	* DLD-FUNCTIONS/sqrt.m: Replace DBL_* with FLT_* for single
+	precision types.
+	* data.cc (static octave_value fill_matrix (const
+	octave_value_list&, double, float, const char *)): Add function
+	with additional argument to allow for different valid for double
+	and single precision.
+	(Finf, FNaN, FNA, Frealmax, Frealmin): Use it here.
+	(Feps): Modify behavior for a single numerical argument to give
+	difference to next largest value in the class of the type passed.
+
+2008-05-21  John W. Eaton  <jwe at octave.org>
+
+	* pt-idx.h (tree_index_expression::tree_index_expression (int, int)): 
+	Delete default argument values.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Flog2): Handle single precision.
+	* ov-float.h, ov.float.cc, ov-flt-complex.h, ov-flt-complex.cc,
+	ov-flt-re-mat.h, ov-flt-re-mat.cc, ov-flt-cx-mat.h,
+	ov-flt-cx-mat.cc: Provide single precision version of log2 mapper
+	function.
+
+	* DLD-FUNCTIONS/__convn__.cc, DLD-FUNCTIONS/__pchip_deriv__.cc,
+	DLD-FUNCTIONS/besselj.cc, DLD-FUNCTIONS/betainc.cc,
+	DLD-FUNCTIONS/conv2.cc, DLD-FUNCTIONS/gammainc.cc,
+	DLD-FUNCTIONS/givens.cc, DLD-FUNCTIONS/kron.cc,
+	DLD-FUNCTIONS/lookup.cc, DLD-FUNCTIONS/syl.cc, data.cc:
+	Prefer demotion to single precision rather than promotion to double.
+
+	* ov-float.cc, ov-float.h, ov-flt-complex.cc, ov-flt-complex.h,
+	ov-flt-cx-mat.cc, ov-flt-cx-mat.h, ov-flt-re-mat.cc,
+	ov-flt-re-mat.h (numeric_conversion_function (void) const): 
+	Remove method.
+
+	* ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h,
+	ov-re-mat.cc, ov-re-mat.h, ov-scalar.cc, ov-scalar.h 
+	(numeric_conversion_function (void) const): Add method for
+	conversion to single precision.
+
+	* DLD-FUNCTIONS/conv2.cc (Fconv2): Don't access third arg if we
+	don't have one.
+	
+	* DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/expm.cc,
+	DLD-FUNCTIONS/find.cc, DLD-FUNCTIONS/hess.cc,
+	DLD-FUNCTIONS/qr.cc: COnvert for use with single precision.
+
+	* OPERATORS/op-int.h, OPERATORS/op-int-conv.cc,
+	OPERATORS/op-int-concat.cc: Adapt for single precision.
+
+	* OPERATORS/op-i8-i8.cc, OPERATORS/op-i16-i16.cc, 
+	OPERATORS/op-i32-i32.cc, OPERATORS/op-i64-i64.cc, 
+	OPERATORS/op-ui8-ui8.cc, OPERATORS/op-ui16-ui16.cc, 
+	OPERATORS/op-ui32-ui32.cc, OPERATORS/op-ui64-ui64.cc:
+	Add includes for single precision types.
+	
+	* OPERATORS/op-b-b.cc, OPERATORS/op-b-bm.cc, OPERATORS/op-bm-b.cc,
+	OPERATORS/op-fcm-fs.cc, OPERATORS/op-fcs-fs.cc,
+	OPERATORS/op-fm-fs.cc, OPERATORS/op-fs-fcm.cc,
+	OPERATORS/op-fs-fcs.cc, OPERATORS/op-fs-fm.cc,
+	OPERATORS/op-fs-fs.cc, OPERATORS/op-int.h, ov.cc, ov-scalar.cc,
+	ov-float.h, ov-flt-complex.cc, ov-float.cc, ov-flt-re-mat.cc,
+	ov-flt-cx-mat.cc: Replace octave_float with octave_scalar_float
+
+	* OPERATORS/op-fm-fm.cc, OPERATORS/op-fm-fs.cc, 
+	OPERATORS/op-fm-fcm.cc, OPERATORS/op-fm-fcs.cc, 
+	OPERATORS/op-fs-fm.cc, OPERATORS/op-fs-fs.cc, 
+	OPERATORS/op-fs-fcm.cc, OPERATORS/op-fs-fcs.cc, 
+	OPERATORS/op-fcm-fm.cc, OPERATORS/op-fcm-fs.cc, 
+	OPERATORS/op-fcm-fcm.cc, OPERATORS/op-fcm-fcs.cc, 
+	OPERATORS/op-fcs-fm.cc, OPERATORS/op-fcs-fs.cc, 
+	OPERATORS/op-fcs-fcm.cc, OPERATORS/op-fcs-fcs.cc, 
+	OPERATORS/op-m-m.cc, OPERATORS/op-m-s.cc, 
+	OPERATORS/op-m-cm.cc, OPERATORS/op-m-cs.cc, 
+	OPERATORS/op-s-m.cc, OPERATORS/op-s-s.cc, 
+	OPERATORS/op-s-cm.cc, OPERATORS/op-s-cs.cc, 
+	OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc, 
+	OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc, 
+	OPERATORS/op-cs-m.cc, OPERATORS/op-cs-s.cc, 
+	OPERATORS/op-cs-cm.cc, OPERATORS/op-cs-cs.cc:
+	Add mixed single/double assign operators.
+
+	* ov.h (numeric_demotion_function): New method for double to
+	single demotion.
+	* ov-base.h (numeric_demotion_function): Declare virtual version.
+
+	* ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h,
+	ov-re-mat.cc, ov-re-mat.h, ov-scalar.cc, ov-scalar.h 
+	(numeric_cdemote_function (void) const): Add method for
+	conversion to single precision renamed from the method
+	numeric_conversion_function
+
+	* ov.cc (do_binary_op): Use demotion function seperately than the
+	numeric conversion function so as to avoid isses like
+	a=zeros(2,2);a(1,:)=1:2.
+
+	* OPERATORS/op-fcm-fcm.cc, OPERATORS/op-fcm-fcs.cc,
+	OPERATORS/op-fcm-fm.cc, OPERATORS/op-fcm-fs.cc,
+	OPERATORS/op-fcs-fcm.cc, OPERATORS/op-fcs-fcs.cc,
+	OPERATORS/op-fcs-fm.cc, OPERATORS/op-fcs-fs.cc,
+	OPERATORS/op-fm-fcm.cc, OPERATORS/op-fm-fcs.cc,
+	OPERATORS/op-fm-fm.cc, OPERATORS/op-fm-fs.cc,
+	OPERATORS/op-fs-fcm.cc, OPERATORS/op-fs-fcs.cc,
+	OPERATORS/op-fs-fm.cc, OPERATORS/op-fs-fs.cc, ov-float.cc,
+	ov-float.h, ov-flt-complex.cc, ov-flt-complex.h, ov-flt-cx-mat.cc,
+	ov-flt-cx-mat.h, ov-flt-re-mat.cc, ov-flt-re-mat.h: New files.
+	* Makefile.in (OV_INCLUDES, OV_SRC, OP_XSRC. FLOAT_OP_XSRC,
+	DOUBLE_OP_XSRC): Add them here.
+
+	* DLD-FUNCTIONS/__convn__.cc, DLD-FUNCTIONS/__lin_interpn__.cc,
+	DLD-FUNCTIONS/__pchip_deriv__.cc, DLD-FUNCTIONS/besselj.cc,
+	DLD-FUNCTIONS/betainc.cc, DLD-FUNCTIONS/bsxfun.cc,
+	DLD-FUNCTIONS/chol.cc, DLD-FUNCTIONS/conv2.cc,
+	DLD-FUNCTIONS/det.cc, DLD-FUNCTIONS/eig.cc, DLD-FUNCTIONS/fft.cc,
+	DLD-FUNCTIONS/fft2.cc, DLD-FUNCTIONS/fftn.cc,
+	DLD-FUNCTIONS/fftw.cc, DLD-FUNCTIONS/filter.cc,
+	DLD-FUNCTIONS/gammainc.cc, DLD-FUNCTIONS/givens.cc,
+	DLD-FUNCTIONS/inv.cc, DLD-FUNCTIONS/kron.cc,
+	DLD-FUNCTIONS/lookup.cc, DLD-FUNCTIONS/lu.cc,
+	DLD-FUNCTIONS/matrix_type.cc, DLD-FUNCTIONS/max.cc,
+	DLD-FUNCTIONS/pinv.cc, DLD-FUNCTIONS/schur.cc,
+	DLD-FUNCTIONS/sqrtm.cc, DLD-FUNCTIONS/svd.cc,
+	DLD-FUNCTIONS/syl.cc, DLD-FUNCTIONS/symbfact.cc,
+	DLD-FUNCTIONS/typecast.cc, OPERATORS/op-b-b.cc,
+	OPERATORS/op-b-bm.cc, OPERATORS/op-bm-b.cc, OPERATORS/op-bm-bm.cc,
+	OPERATORS/op-cm-cm.cc, OPERATORS/op-cs-cs.cc, OPERATORS/op-m-m.cc,
+	OPERATORS/op-range.cc, OPERATORS/op-s-s.cc, bitfcns.cc, data.cc,
+	oct-stream.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc,
+	ov-bool-mat.h, ov-bool.h, ov-ch-mat.cc, ov-ch-mat.h,
+	ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h, ov-intx.h,
+	ov-range.cc, ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-scalar.h,
+	ov.cc, ov.h, pr-output.cc, pr-output.h, pt-mat.cc, utils.cc,
+	utils.h, xdiv.cc, xdiv.h, xpow.cc, xpow.h:
+	Allow single precision types.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/rcond.cc: New function.
+	* Makefile.in (DLD_XSRC): Add it here.
+
+	* debug.cc (Fdbstop): If no line specified assume line 1.
+	(Fdbstep, Fdbcont, Fdbnext): Move debugging functions 
+	to normal commands.
+	(Fdbquit): New command to quit debugging mode and return to the 
+	prompt.
+	(Fdbstep): Modify the dbstep command for compatibility.
+	* input.cc (Vdebugging_current_line): Store current line being
+	debugged for use in DEFCMD versions of debug commands.
+	(match_sans_spaces_semi): Delete.
+	(static void get_debug_input (const std;string&)): New function to
+	parse input in debug mode using standard Octave parser.
+	(static octave_value_list get_user_input (const
+	octave_value_list&, int)): Remove debugging specialization.
+	* input.h (Vdebugging_current_line): Store current line being
+	debugged for use in DEFCMD versions of debug commands.
+	* parse.y (make_return_command): Special handling in debug mode.
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Support break in n lines needed
+	to support "dbstep N". 
+	* pt.cc (tree::break_next): Convert to a down counter to support
+	break in N lines. Breakpoint occure when tree::break_next is zero.
+	* toplev.cc (octave_user_script *
+	octave_call_stack::do_caller_user_script (difference_type) const):
+	Support skipping the first N functions to support "dbstep out".
+	(octave_user_function * octave_call_stack::do_caller_user_function
+	(difference_type) const): Ditto.
+	(octave_user_code * octave_call_stack::do_caller_user_code
+	(difference_type) const): Ditto.
+	* toplev.h (octave_user_script *
+	octave_call_stack::do_caller_user_script (difference_type) const):
+	Add difference_type argument.
+	(octave_user_function * octave_call_stack::do_caller_user_function
+	(difference_type) const): Ditto.
+	(octave_user_code * octave_call_stack::do_caller_user_code
+	(difference_type) const): Ditto.
+	(static octave_user_script *caller_script (difference_type)):
+	Ditto.
+	(static octave_user_function *caller_user_function
+	(difference_type q)): Ditto.
+	(static octave_user_code *caller_user_code (difference_type q)):
+	Ditto.
+
+2008-05-20  Kim Hansen  <kimhanse at gmail.com>
+
+	* load-path.cc (load_path::do_initialize):
+	Include separator when appending sys_path.
+
+2008-05-20  Bill Denney  <bill at denney.ws>
+
+	* file-io.cc (Ffgets, Fgets, Ffputs, Ffscanf): Doc fix (seealso).
+
+2008-05-20  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* DLD-FUNCTIONS/rand.cc (Frandn): Doc fix.
+
+2008-05-20  David Bateman  <dbateman at free.fr>
+
+	* load-save.cc (do_load): Treat non verbose list_only output in
+	the same manner as Fwho.
+	* symtab.h (static void clear_variable_regexp (const
+	std::string&): New method.
+	(static std::list<symbol_record> regexp (const std::string&)): Ditto.
+	(static std::list<symbol_record> regexp_variables (const
+	std::string&)): Ditto.
+	(static std::list<symbol_record> regexp_global_variables (const
+	std::string&)): Ditto,
+	(static std::list<symbol_record> regexp_variables (const
+	string_vector&)): Ditto.
+	(void do_clear_variable_regexp (const std::string&)): Ditto.
+	(std::list<symbol_record> do_regexp (const std::string&, bool)
+	const): Ditto.
+	(do_who): Accept the "-regexp" option. Use regexp versions of
+	symbol table functions.
+	(static inline bool name_match_any_pattern (const string_vector&,
+	int, int, bool): Add regexp argument, and use regexp matching if
+	true.
+	(do_clear_variables): Add regexp option and pass to
+	name_match_any_pattern.
+	(Fclear): Accept the -regexp option.
+
+2008-05-07  John W. Eaton  <jwe at octave.org>
+
+	* pt-arg-list.cc, pt-arg-list.h (tree_argument_list::dup):
+	New arg, context.
+	* pt-assign.cc, pt-assign.h (tree_simple_assignment::dup,
+	tree_multi_assignment::dup): Likewise.
+	* pt-binop.cc, pt-binop.h (tree_binary_expression::dup,
+	tree_boolean_expression::dup): Likewise.
+	* pt-cell.cc, pt-cell.h (tree_cell::dup): Likewise.
+	* pt-cmd.cc, pt-cmd.h (tree_no_op_command::dup,
+	tree_function_def::dup): Likewise.
+	* pt-colon.cc, pt-colon.h (tree_colon_expression::dup): Likewise.
+	* pt-const.cc, pt-const.h (tree_constant::dup): Likewise.
+	* pt-decl.cc, pt-decl.h (tree_decl_elt::dup, tree_decl_init_list::dup,
+	tree_global_command::dup, tree_static_command::dup): Likewise.
+	* pt-except.cc, pt-except.h (tree_try_catch_command::dup,
+	tree_unwind_protect_command::dup): Likewise.
+	* pt-exp.h (tree_expression:dup): Likewise.
+	* pt-fcn-handle.cc, pt-exp.h (tree_expression:dup): Likewise.
+	* pt-fcn-handle.h (tree_fcn_handle::dup,
+	tree_anon_fcn_handle::dup): Likewise.
+	* pt-id.cc, pt-id.h (tree_identifier::dup): Likewise.
+	* pt-idx.cc, pt-idx.h (tree_index_expression::dup): Likewise.
+	* pt-jump.cc, pt-jump.h (tree_break_command::dup,
+	tree_continue_command::dup, tree_return_command::dup): Likewise.
+	* pt-loop.cc, pt-loop.h (tree_while_command::dup,
+	tree_do_until_command::dup, tree_simple_for_command::dup,
+	tree_complex_for_command::dup): Likewise.
+	* pt-mat.cc, pt-mat.h (tree_matrix::dup): Likewise.
+	* pt-misc.cc, pt-misc.h (tree_parameter_list::dup,
+	tree_return_list::dup): Likewise.
+	* pt-select.cc, pt-select.h (tree_if_clause::dup,
+	tree_if_command_list::dup, tree_if_command::dup,
+	tree_switch_case::dup, tree_switch_case_list::dup,
+	tree_switch_command::dup, tree_statement::dup,
+	tree_statement_list::dup, tree_prefix_expression::dup,
+	tree_postfix_expression::dup): Likewise.
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii,
+	octave_fcn_handle::save_binary, octave_fcn_handle::save_hdf5):
+ 	Pass context to symbol_table::all_variables.
+	* load-save.cc (dump_octave_core): Likewise.
+	* ov-fcn-handle.cc (Ffunctions): Don't skip anonymous functions
+	with the name set to the text of the function body.
+ 	Pass context to symbol_table::all_variables and
+	symbol_table::symbol_record::varval.
+
+	* symtab.h (symbol_table::varref, symbol_table::do_varref,
+	symbol_table::varval, symbol_table::do_varval,
+	symbol_table::all_variables, symbol_table::do_all_variables, 
+	symbol_table::symbol_record::varref,
+	symbol_table::symbol_record::varval,
+	symbol_table::symbol_record::is_defined,
+	symbol_table::symbol_record::is_variable,
+	symbol_table::symbol_record::symbol_record_rep::varref,
+	symbol_table::symbol_record::symbol_record_rep::varval,
+	symbol_table::symbol_record::symbol_record_rep::is_defined,
+	symbol_table::symbol_record::symbol_record_rep::is_variable,
+	):
+	* symtab.h (symbol_table::do_inherit): New arg, donor_context.
+	Look for value in donor_contxt.  Set value in base context.
+	* symtab.cc (symbol_table::symbol_record::symbol_record_rep::dump):
+	Pass xcurrent_context to varval.
+
+2008-05-06  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-inline.cc (Finline): Also ignore NaN, Inf, pi, NA and eps.
+
+	* bitfcns.cc (BITOP): Treat octave_bool types and octave_scalar.
+
+2008-05-06  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_table::scope_id_cache): New class.  Use it to
+	replace scope_ids_in_use and scope_ids_free_list.
+	(symbol_table::erase_scope): Call free_scope.
+	(symbol_table::free_scope): Call scope_id_cache::free.
+
+	* ov-fcn.h (octave_function::lock_subfunctions,
+	octave_function::unlock_subfunctions): New virtual functions.
+	(octave_function::lock_subfunctions): Call lock_subfunctions here.
+	(octave_function::unlock_subfunctions): Call unlock_subfunctions here.
+	* ov-usr-fcn.h (octave_user_function::lock_subfunctions,
+	octave_user_function::unlock_subfunctions): New functions.
+
+	* symtab.h (symbol_table::lock_subfunctions,
+	symbol_table::lock_subfunctions,
+	symbol_table::fcn_info::lock_subfunction,
+	symbol_table::fcn_info::unlock_subfunction,
+	symbol_table::fcn_info::fcn_info_rep::lock_subfunction, 
+	symbol_table::fcn_info::fcn_info_rep::unlock_subfunction):	
+	New functions.
+
+	* symtab.h (symbol_table::set_scope, symbol_table::get_instance):
+	Don't set instance unless allocation succeeds.
+	(symbol_table::print_scope, symbol_table::do_print_scope): Delete.
+	(symbol_table::free_scope): Avoid using invalid iterator.
+	(symbol_table::erase_scope): Call free_scope here.
+
+	* ov-fcn-handle.cc (octave_fcn_handle::load_ascii,
+	octave_fcn_handle::load_binary, octave_fcn_handle::load_hdf5):
+	Cache anonymous name here.
+	(octave_fcn_handle::octave_fcn_handle): Move here from
+	ov-fcn-handle.h.  Cache name if function is user-defined.
+
+	* pt-id.cc (tree_identifier::dup): Avoid shadow warning.
+
+	* symtab.h (symbol_table::cache_name, symbol_table::do_cache_name):
+	New functions.
+	(symbol_table::get_instance): Cache top-level name here.
+	* parse.y (finish_function): Call symbol_table::cache_name here.
+
+	* symtab.cc (F__dump_symtab_info__): New function.
+	
+	* symtab.cc (symbol_table::dump, symbol_table::dump_global,
+	symbol_table::dump_functions, symbol_table::do_dump,
+	symbol_table::symbol_record::symbol_record_rep::dump,
+	symobl_table::fcn_info::fcn_info_rep::dump): New functions.
+	* symtab.h: Provide decls.
+	(symtab::scopes, symbol_table::symbol_record::dump,
+	symbol_table::fcn_info::dump): New functions.
+	(symtab::get_instance): New arg, create; if false throw error if
+	instance for given scope is not found.
+
+	* ov-base.cc (octave_base_value::dump): New virtual function.
+	* ov-base.h: Proivde decl.
+	* ov.h (octave_value::dump): New function.
+
+	* ov.h, ov.c (octave_value::function_value): New const version.
+	* ov-base.h, ov-base.cc (octave_base_value::function_value): Likewise.
+	* ov-builtin.h (octave_builtin::function_value): Likewise.
+	* ov-fcn-handle.h (octave_fcn_handle::function_value): Likewise.
+	* ov-mex-fcn.h (octave_mex_function::function_value): Likewise.
+	* ov-usr-fcn.h (octave_user_script::function_value,
+	octave_user_function): Likewise.
+	
+	* symtab.h, symtab.cc: Use consistent naming scheme for iterator
+	typedefs.  Change all uses.
+
+	* variables.cc (F__print_symtab_info__, F__print_symbol_info__):
+	Delete.
+
+	* ov-cell.cc (Fstruct2cell): Handle structure arrays properly.
+
+2008-05-05  David Bateman  <dbateman at free.fr>
+
+	* sysdep.cc (Fputenv): Allow single arg. Alias to setenv.
+
+2008-05-05  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (Fre_read_readline_init_file): New function.
+
+2008-05-04  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-handle.cc (Ffunctions): Pass octave_value object instead
+	of Cell in structure field assignment.
+
+	* parse.y (frob_function): Don't install subfunctions here.
+	(finish_function): Handle subfunctions here.
+	Conditionally define tree_function_def object here.
+
+	* symtab.h (symbol_table::fcn_info::fcn_info_rep::find_function):
+	Initialize args_evaluated.
+	* pt-id.cc (tree_identifier::rvalue): Likewise.
+	* variables.cc (symbol_exist): Likewise.
+
+	* pt-id.h (tree_identifier::tree_identifer): Delete useless statement.
+
+	* variables.cc (get_global_value): Use symbol_table::global_varval
+	instead of passing scope to symbol_table::varval.
+	(set_global_value): Use symbol_table::global_varref
+	instead of passing scope to symbol_table::varref.
+	(do_who): Use symbol_table::glob_global_variables
+	instead of passing scope to symbol_table::glob_variables.
+	(do_clear_globals):
+	Use symbol_table::global_variable_names and
+	symbol_table::clear_global instead of passing scope to
+	symbol_table::clear_variables.
+	Use symbol_table::global_variable_names instead of passing scope
+	to symbol_table::variable_names.
+
+	* unwind-prot.cc (unwind_protect::save_size_t): New function.
+	(saved_variable::restore_value): Handle size_t values.
+	(saved_variable::saved_variable): New size_t constructor.
+	(saved_variable::size_type): New var_type enum value.
+	(saved_variable::ptr_to_size_t, saved_variable::size_t_value):
+	New union elements.
+	* unwind-prot.h (unwind_protect::save_size_t): Provide decl
+	(unwind_protect_size_t): New macro.
+
+	* toplev.cc (octave_call_stack::do_goto_frame,
+	octave_call_stack::do_goto_frame_relative): New functions.
+	(octave_call_stack::do_backtrace): Also return scope and context ids.
+	* toplev.h 	(octave_call_stack::do_goto_frame,
+	octave_call_stack::do_goto_frame_relative): Provide decls.
+	(octave_call_stack::curr_frame): New data member.
+	(octave_call_stack::octave_call_stack): Initialize it.
+	(octave_call_stack::call_stack_elt::scope,
+	(octave_call_stack::call_stack_elt::context): New data members.,
+	(octave_call_stack::current_frame,
+	(octave_call_stack::do_current_frame
+	octave_call_stack::do_goto_frame,
+	octave_call_stack::do_goto_frame_relative): New functions.
+	(octave_call_stack::push, octave_call_stack::do_push):
+	New args, scope and context.
+	(octave_call_stack::do_push, octave_call_stack::do_pop): Update
+	curr_frame if debugging.
+
+	* symtab.cc (symbol_table::global_table): New map for global values.
+	(symbol_table::xcurrent_context): New variable for context info.
+	* symtab.h: Provide decls.
+	(symbol_table::global_varref, symbol_table::global_varval,
+	symbol_table::current_context,
+	symbol_table::set_scope_and_context,
+	symbol_table::glob_global_variables,
+	symbol_table::global_variable_names,
+	symbol_table::top_leve_variable_names):
+	New functions.
+	(symbol_table::context_id, const_global_table_iterator,
+	global_table_iterator): New typedefs.
+	(symbol_table::xcurrent_context_this_table): New variable.
+	(symbol_table::symbol_table): Initialize it.
+	(symbol_table::set_scope): Use it.
+	(symbol_table::symbol_record::find, symbol_table::do_find):
+	Use symbol_table::global_varref instead of passing scope to
+	symbol_table::varref.
+	(symbol_table::symbol_record::symbol_record_rep::value_stack):
+	Now a std::deque instead of a std::stack.
+	(symbol_table::symbol_record::symbol_record_rep::push_context,
+	symbol_table::symbol_record::symbol_record_rep::pop_context):
+	Don't push or pop persistent of global variables.
+	(symbol_table::symbol_record::symbol_record_rep::varval,
+	Handle context here.  Call symbol_table::global_varval instead of
+	passing scope to symbol_table::varval.
+	(symbol_table::symbol_record::symbol_record_rep::varref):
+	Handle context here.  Call symbol_table::global_varref instead of
+	passing scope to symbol_table::varref.
+	(symbol_table::symbol_record::varref,
+	symbol_table::symbol_record::varval): No need to handle global
+	values specially here.
+	(symbol_table::symbol_record::push_context
+	symbol_table::symbol_record::pop_context: No need to handle global
+	or persistent values specially here.
+	(symbol_table::get_instance): Don't return global scope.
+	(symbol_table::do_push_context, symbol_table::do_pop_context):
+	Increment/decrement xcurrent_context.
+	(symbol_table::do_clear_global, symbol_table::do_clear_global_pattern):
+	Use global_table instead of separate scope.	
+
+	* symtab.h, symtab.cc (symbol_table::fcn_info::fcn_info_rep::find,
+	symbol_table::fcn_info::fcn_info_rep::find_function,
+	symbol_table::fcn_info::find, symbol_table::fcn_info::find_function,
+	symbol_table::find, symbol_table::find_function,
+	symbol_table::do_find, symbol_table::insert, symbol_table::varref,
+	symbol_table::varval, symbol_table::persistent_varref,
+	symbol_table::persistent_varval, symbol_table::erase_persistent,
+	symbol_table::is_variable, symbol_table::clear,
+	symbol_table::clear_variables, symbol_table::clear_global,
+	symbol_table::clear_variable, symbol_table::clear_global_pattern,
+	symbol_table::clear_variable_pattern, symbol_table::push_context,
+	symbol_table::pop_context, symbol_table::mark_hidden,
+	symbol_table::mark_global, symbol_table::glob,
+	symbol_table::glob_variables, symbol_table::variable_names,
+	symbol_table::is_local_variable, symbol_table::is_global):
+	Eliminate scope arg.  Change all uses.
+	(symbol_table::erase_scope, symbol_table::dup_scope):
+	Require scope arg.
+
+	* pt-stmt.cc (tree_statement::eval): Don't update statement info
+	in octave_call_stack if debugging.
+
+	* pt-id.h (tree_identifier::xsym): New function.
+	(tree_identifier::rvalue, tree_identifier::lvalue,
+	tree_identifier::dup, tree_identifier::is_defined,
+	tree_identifier::is_variable, tree_identifier::mark_global,
+	tree_identifier::mark_as_static, tree_identifier::do_lookup,
+	tree_identifier::mark_as_formal_parameter):
+	Use xsym to access symbol.
+	(tree_identifier::scope): New data member.
+	(tree_identifier::tree_identifier): Initialize it.
+
+	* ov-usr-fcn.cc (octave_user_script::octave_user_script,
+	octave_user_function::octave_user_function):
+	Initialize call_depth to -1.
+	(octave_user_script::do_multi_index_op): Fix comparison of
+	call_depth with Vmax_recursion_depth.
+	(octave_user_function::do_multi_index_op):
+	Compare call depth > 0, instead of > 1.
+	* ov-usr-fcn.h (octave_user_function::save_args_passed):
+	Compare call depth > 0, instead of > 1.
+
+	* input.cc (Vdebugging): New variable.
+	(get_user_input): Eliminate DEBUG argument.  Use global Vdebugging
+	variable instead.  Change all callers.
+	(saved_frame): New static variable.
+	(restore_frame): New function.
+	(do_keyboard): Unwind-protect Vdebugging here and set it to TRUE.
+	Save current frame.  Use unwind_protect to restore it.
+	(Fkeyboard): Save current frame.  Use unwind_protect to restore it.
+	Move up the call stack one frame before calling do_keyboard.  
+	* input.h (Vdebugging): Provide decl.
+
+	* mex.cc (mexGetVariable): Handle global vars with get_global_value.
+	(mexPutVariable): Likewise, with set_global_value.
+
+	* octave.cc (intern_argv): Assert that we are at the top level.
+	Don't pass scope to symbol_table::varref or symbol_table::mark_hidden.
+
+	* load-save.cc (install_loaded_variable): Use
+	symbol_table::global_varref instead of passing global scope to
+	symbol_table::varref.
+
+	* help.cc (make_name_list): Call symbol_table::global_variable_names
+	and symbol_table::top_level_variable_names instead of passing
+	scope to symbol_table::variable_names.
+
+	* debug.cc (do_dbupdown, Fdbup, Fdbdown): New functions.
+	(current_stack_frame): Delete static variable.
+	(Fdbstack): Rename from F__dbstack__.  Implement all of dbstack
+	here instead of partially in dbstack.m.
+
+2008-05-03  John W. Eaton  <jwe at octave.org>
+
+	* pt-arg-list.cc (F__end__): If there are more dimensions than
+	indices, smash extra dimensions first.
+	(num_indices): New static variable.
+	(tree_argument_list::convert_to_const_vector): Save and set it.
+
+	* parse.y (parse_fcn_file): Also temporarily set parser_end_of_input
+	and get_input_from_eval_string to false while reading script files.
+
+2008-05-01  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (load_fcn_from_file): Expect
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_oct):
+	Search currently loaded .oct files by file name.  Don't search
+	currently loaded files for functions.
+	(octave_shlib_list::find_file, octave_shlib_list::do_find_file):
+	New functions.
+	(octave_shlib_list::search, octave_shlib_list::do_search): Delete.
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_oct): No need to
+	do load_path lookups here.
+	(octave_shlib_list::iterator, octave_shlib_list::const_iterator):
+	New typedefs.
+	(octave_shlib_list::do_remove, octave_shlib_list::do_search,
+	octave_shlib_list::do_display): Use them.
+	(octave_mex_file_list::iterator, octave_mex_file_list::const_iterator):
+	New typedefs.
+	(octave_mex_file_list::do_remove): Use them.
+
+2008-05-03  Rafael Laboissiere <rafael at debian.org>
+
+	* DLD-FUNCTIONS/time.cc, file_io.cc: Use ischar instead of
+	deprecated isstr.
+
+2008-04-30  John W. Eaton  <jwe at octave.org>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_oct):
+	If function already exists, reload it anyway.  Clear existing
+	oct_file only if reloading a function from the same file.
+	(octave_shlib_list::display): New static function.
+	(octave_shlib_list::do_display): New function.
+
+	* symtab.cc (out_of_date_check_internal): Better handling for
+	functions found in files by relative file names.
+	(load_out_of_date_fcn): New function.
+
+	* ls-oct-ascii.cc (extract_keyword): Return early if first char is
+	not a comment character.
+	(read_ascii_data): Accept .nargin. and .nargout. as valid identifiers.
+
+	* ov-fcn-handle.cc: Combine tests.  Test saving and loading
+	handles for built-in, .oct, and .m functions.
+	(octave_fcn_handle::save_ascii, octave_fcn_handle::save_binary,
+	octave_fcn_handle::save_hdf5, octave_fcn_handle::print):
+	Avoid dereferencing invalid pointer.
+
+	* data.cc: Fix tests.  Use "%!assert", not "%! assert" for
+	individual assert tests.
+
+2008-04-30  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-base.cc, ov-base.h, ov-bool-mat.h, ov-bool-sparse.h,
+	ov-bool.h, ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h,
+	ov-cx-sparse.cc, ov-cx-sparse.h, ov-intx.h, ov-range.h,
+	ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc, ov-re-sparse.h,
+	ov-scalar.cc, ov-scalar.h, ov.h:
+ 	Provide log2 mapper function.
+	* data.cc (Flog2): New function.
+
+2008-04-25  John W. Eaton  <jwe at octave.org>
+
+	* pt-stmt.h (tree_statement_list::function_body): New data member.
+	(tree_statement_list::tree_statement_list): Initialize it.
+	(tree_statement_list::mark_as_script_body): New function.
+	(tree_statement::maybe_echo_code, tree_statement::eval):
+	Rename in_function_body argument to in_function_or_script_body.
+	* pt-stmt.cc (tree_statement::eval): Only set statement in call
+	stack if in_function_or_script_body is true.
+
+	* pt-stmt.cc (tree_statement_list::eval): Call elt->eval with
+	function_body || script_body.
+	* ov-usr-fcn.cc (octave_user_script::octave_user_script):
+	command list as script body here.
+	(octave_user_function::octave_user_function):
+	Mark command list as function body here.
+	* parse.y (start_function, make_anon_fcn_handle): Not here.
+
+	* toplev.h, toplev.cc (octave_call_stack::backtrace,
+	octave_call_stack::do_backtrace): New arg, N.  Skip innermost N
+	stack frames.
+
+	* debug.cc (F__dbstack__): New function.
+	(current_stack_frame): New static variable.
+
+	* error.cc (verror, pr_where): Use octave_call_stack instead of
+	tree_statement stack to get line and column information.
+	(pr_where): Use octave_call_stack instead of tree_statement stack
+	to get current statement.
+	* input.cc (get_user_input): Extract current line number from
+	octave_call_stack instead of tree_statement_stack.
+	* pt-stmt.cc (tree_statement::eval): Put current statement on
+	octave_call_stack instead of tree_statement_stack.
+	* pt-stmt.h, pt-stmt.cc (class tree_statement_stack): Delete.
+
+	* toplev.h, toplev.cc (octave_call_stack::call_stack_elt):
+	New nested struct.
+	(octave_call_stack::cs): Now a deque of call_stack_elts.
+	Change all uses.
+	(octave_call_stack::current_statement,
+	octave_call_stack::current_line,
+	octave_call_stack::current_column,
+	octave_call_stack::top_statement,
+	octave_call_stack::set_statement, octave_call_stack::backtrace):
+	New static functions.
+	(octave_call_stack::do_current_line,
+	octave_call_stack::do_current_column,
+	octave_call_stack::do_top_statement,
+	octave_call_stack::do_set_statement,
+	octave_call_stack::do_backtrace): New member functions.
+
+2008-04-24  John W. Eaton  <jwe at octave.org>
+
+	* toplev.h, toplev.cc (octave_call_stack::unwind_pop_script):
+	Delete unused function.
+
+	* ov-usr-fcn.cc: Move constructor definitions here, from ov-usr-fcn.h.
+	* ov-usr-fcn.h (octave_user_script::octave_user_script): 
+	Also Initialize t_parsed and t_checked.
+
+2008-04-24  Jaroslav Hajek  <highegg at gmail.com>
+
+	* ov-usr-fcn.h (octave_user_script::octave_user_script): 
+	Initialize call_depth.
+
+2008-04-24  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (do_stream_open): Return -1 for directories.
+
+2008-04-23  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Avoid bounds error when removing
+	constraint from active set.
+
+	* lex.l (text_yyinput): New function.  Use it in place of yyinput.
+	(next_token_is_sep_op, scan_for_comments, eat_whitespace,
+	have_continuation): No need to check for CR or CRLF.
+	* parse.y (text_getc): Also return NL for single CR.
+
+2008-04-32  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* input.cc (get_input_from_file): Open file in binary mode.
+
+2008-04-20  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream::read): Allow single data type
+	specification but return double.
+
+2008-04-18  John W. Eaton  <jwe at octave.org>
+
+	* lex.l, lex.h (process_comment): New arg, start_in_block.  Call
+	grab_block_comment if start_in_block is true.  Change all uses.
+	* lex.l (grab_block_comment): New function.
+	(grab_comment_block): New arg, at_bol.  Change all uses.
+	Call grab_block_comment if we find the start of a block comment.
+	(block_comment_nesting_level): New static variable.
+	(^{S}*{CCHAR}\{{S}*{NL}): New rule.
+	(<<EOF>>): Warn about open block comments.
+	(reset_parser): Set block_comment_nesting_level to zero.
+	* parse.y (parse_fcn_file): Stash help text from
+	gobble_leading_white_space after calling reset_parser.
+	(text_getc): Keep track of input_line_number here.
+	(skip_white_sapce): Don't increment input_line_number here.
+	* lex.l (grab_comment_block): Or here.
+
+	* lex.l (Vdisplay_tokens): New static variable.
+	(F__display_tokens__): New function.
+	(display_token): New function.
+	(DISPLAY_TOK_AND_RETURN): New macro.
+	(COUNT_TOK_AND_RETURN): Use DISPLAY_TOK_AND_RETURN.
+	(<COMMAND_START>[\"\'], "'", \"): Move handle_string outside of
+	COUNT_TOK_AND_RETURN macro parameter list.
+	(handle_identifier): Don't use macros to return token values here.
+	(<MATRIX_START>{S}*{COMMENT}{SNLCMT}*|<MATRIX_START>{S}*{NL}{SNLCMT}*):
+	Recognize block comments here.
+	
+	* pr-output.cc (Fdisp): If nargout > 0, produce an sq-string
+	unless arg is a dq-string.
+
+2008-04-17  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (looks_like_copyright): Handle leading whitespace.
+	(class stdio_stream_reader): New class.
+	(skip_white_space): New function.
+	(gobble_leading_white_space): New arg, EOF.  Change all uses.
+	Use skip_white_space and grab_comment_block to process comments.
+	(process_leading_comments): Delete.
+	(parse_fcn_file): Call gobble_leading_white_space instead of
+	process_leading_comments.
+	Skip parsing if gobble_leading_white_space detects EOF.
+	* lex.l (process_comment): Delete CCHAR arg.  Change all uses.
+	({CCHAR}): Unput comment character before calling process_comment.
+	(grab_comment_block): Rename from grab_help_text.  Don't discard
+	spaces from comment text.  Update input_line_number and
+	current_input_column as characters are read.  Warn only once about
+	incompatible comment characters in a given block of comments.
+	Use stream_reader class instead of accessing yyinput and yyunput
+	directly.
+	(class flex_stream_reader): New class.
+	(process_comment): Use grab_comment_block to handle all comments.
+	Don't call maybe_gripe_matlab_incompatible_comment.
+	Always store comment text returned by grab_comment_block.
+	* lex.h (grab_comment_block): Provide decl.
+	(class stream_reader): New class.
+
+2008-04-16  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (Fautoload, Fmfilename): Call
+	octave_call_stack::caller_user_code, not
+	octave_call_stack::caller_user_script_or_function.
+	* toplev.cc, toplev.h (octave_call_stack::caller_user_code):
+	Rename from octave_call_stack::caller_user_script_or_function.
+	(octave_call_stack::do_caller_user_code): Rename from
+	octave_call_stack::do_caller_user_script_or_function.
+	* ov-usr-fcn.h (class octave_user_code): New class, derived from
+	octave_fucntion.
+	(class octave_user_function, class octave_user_script): Derive
+	from octave_user_code, not octave_function.
+	(octave_user_script::user_code_value,
+	octave_user_function::user_code_value): New functions.
+	* ov.cc (octave_value::user_script_value,
+	octave_value::user_code_value): New functions.
+	* ov.h: Provide decls.
+	(octave_value::is_user_code, octave_value::is_user_script):
+	New functions.
+	* ov-base.cc (octave_base_value::user_script_value,
+	octave_base_value::user_code_value): New virutal functions.
+	* ov-base.h: Provide decls.
+	(octave_base_value::is_user_script, octave_base_value::is_user_code):
+	New virtual functions.
+	* error.cc (verror, pr_where, error_2, warning_1):
+	Call octave_call_stack::caller_user_code instead of
+	octave_call_stack::caller_user_script_or_function
+	* input.cc (get_user_input): Likewise.
+	* debug.h (bp_table::breakpoint_map): Use pointer to
+	octave_user_code instead of octave_user_function.
+	* debug.cc (get_user_code): Rename from get_user_function.
+	Return pointer to octave_user_code instead of octave_user_function.
+	Change all uses.
+	(bp_table::do_add_breakpoint, bp_table::do_remove_breakpoint,
+	bp_table::do_remove_all_breakpoints_in_file,
+	bp_table::do_get_breakpoint_list):
+	Avoid dereferencing invalid pointers.
+	(parse_dbfunction_params): Call
+	octave_call_stack::caller_user_code, not
+	octave_call_stack::caller_user_script_or_function. 
+
+	* load-save.cc (Fsave): Fix continuation character in doc string.
+
+	* pt-walk.h (tree_walker::visit_function_def): New function.
+	* pt-pr-code.cc (tree_print_code::visit_function_def): New function.
+	* pt-pr-code.h: Provide decl.
+	* pt-bp.cc (tree_breakpoint::visit_function_def): New function.
+	* pt-bp.h: Provide decl.
+	* pt-check.cc (tree_checker::visit_function_def): New function.
+	* pt-check.h: Provide decl.
+
+	* parse.y (finish_function): Return ptr to tree_function_def object
+	if curr_fcn_ptr is not defined.  Avoid dereferencing invalid pointers.
+	(frob_function): Set curr_fcn_ptr only when reading a function file.
+	(function): Call finish function in both cases to generate value
+	of production.
+
+	* pt-cmd.h, pt-cmd.cc (tree_function_def): New class.
+
+	* parse.y (parse_and_execute): Delete.
+	* parse.h: Delete decl.
+
+	* pt-pb.cc (tree_breakpoint::visit_octave_user_script): New function.
+	* pt-pb.h: Provide decl.
+	* pt-check.cc (tree_checker::visit_octave_user_script): New function.
+	* pt-check.h: Provide decl.
+	* pt-pr-code.cc (tree_print_code::visit_octave_user_script):
+	New function.
+	* pt-pr-code.h: Provide decl.
+	* pt-walk.h (visit_octave_user_script): New pure virtual function.
+
+	* parse.y (make_script, process_leading_comments,
+	looking_at_function_keyword): New static functions.
+	(SCRIPT): New token.
+	(script): New non-terminal.
+	(command): Handle script here.
+	(parse_fcn_file): Eliminate EXEC_SCRIPT argument.  Change all
+	callers.  Parse scripts and return an octave_user_script rather
+	than executing them here.
+	(load_fcn_from_file): Handle script and function files the same.
+	(source_file): Call d_multi_index_op on object returned by
+	parse_fcn_file.
+	(is_function_file): Delete.
+	(gobble_leading_white_space): Don't recurse.  Simplify.  Eliminate
+	SKIP_CODE, IN_PARTS, and SAVE_COPYRIGHT arguments.  Change all
+	callers.
+	(octave_function_ptr): Delete unused typedef.
+	(get_help_from_file): If help text isn't found by
+	gobble_leading_whitespace, parse file to find it.
+
+	* lex.l (SCRIPT_FILE_BEGIN): New exclusive start state.
+	(prep_lexer_for_script): New function.
+	(grab_help_text): New arg, EOF.
+	(process_comment): New function.
+	({CCHAR}): Use it.
+	* lex.h (prep_lexer_for_script): Provide decl.
+
+	* lex.h, lex.cc, parse.y (lexical_feedback::beginning_of_function):
+	Delete data member and all uses.
+
+	* ov-usr-fcn.cc (octave_user_script::~octave_user_script):
+	Move destructor here from ov-usr-fcn.h.  Delete cmd_list.
+	(octave_user_script::subsref, octave_user_script::accept,
+	octave_user_script::traceback_error): New functions.
+	(octave_user_script::do_multi_index_op):
+	Execute cmd_list instead of calling source_file.
+	* ov-usr-fcn.h (octave_usr_script::cmd_list,
+	octave_usr_script::t_parsed, octave_usr_script::t_checked,
+	octave_usr_script::call_depth): New data members.
+	(octave_usr_script::octave_usr_script): Initialize all data members.
+	(octave_usr_script::octave_usr_script (const std::string&, const
+	std::string&, tree_statement_list *, const std::string&)):
+	New constructor.
+	(octave_usr_script::function_value,
+	octave_usr_script::user_script_value, mark_fcn_file_up_to_date,
+	octave_usr_script::stash_fcn_file_time,
+	octave_usr_script::time_parsed, octave_usr_script::time_checked,
+	octave_usr_script::subsref, octave_usr_script::body): New functions.
+	(octave_user_script::subsref, octave_user_script::accept,
+	octave_user_script::traceback_error): Provide decls.
+
+2008-04-14  Jaroslav Hajek  <highegg at gmail.com>
+
+	* oct-stream.cc (octave_scan_1): Ensure digit following X is hex
+	digit before reading number as hex.
+
+2008-04-14  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (Ffread): Allow SKIP arg to be omitted.
+	(Ffwrite): Likewise.  Handle args in a way consistent with Ffread.
+
+2008-04-09  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* DLD-FUNCTIONS/dispatch.cc: Replace system("echo '...'>...") calls
+	with real file writing.
+
+2008-04-07  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/qr.cc (Fqrshift): New function.
+	* DLD-FUNCTIONS/chol.cc (Fcholinsert, Fcholdelete, Fcholshift):
+	New functions.
+
+2008-04-04  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (make_constant): Handle escape sequences in dq-strings.
+
+2008-04-03  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (make_constant): Also stash original text for strings.
+
+	* ov-fcn-handle.cc (octave_fcn_handle::subsref):
+	Don't call next_subsref here.
+
+2008-04-01  John W. Eaton  <jwe at octave.org>
+
+	* pt-id.h (do_lookup (bool&, bool)): Delete.
+	(do_lookup (tree_argument_list *, const string_vector&,
+	octave_value_list&, bool&)): Call MAYBE_DO_BREAKPOINT here.
+
+2008-04-02  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (void gnuplot_backend::close_figure (const
+	octave_value&) const): Allow for an input and output stream.
+
+2008-03-28  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/lookup.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2008-03-28  David Bateman  <dbateman at free.fr>
+
+	* ov-complex.cc (SCALAR_MAPPER, CD_SCALAR_MAPPER): New macro for
+	complex values with zero imaginary part.
+	(erf, erfc, gamma, lgamma): Use the new mappers to define these
+	mapper functions.
+	* ov-complex.h (erf, erfc, gamma, lgamma): Declare them.
+	* ov-cx-mat.cc (any_element_less_than, any_element_greater_than):
+	New static functions
+	(DARRAY_MAPPER, CD_ARRAY_MAPPER): New macro for complex values
+	with zero imaginary part.
+	(erf, erfc, gamma, lgamma): Use the new mappers to define these
+	mapper functions.
+	* ov-cx-mat.h (erf, erfc, gamma, lgamma): Declare them.
+	* ov-cx-sparse.cc (any_element_less_than, any_element_greater_than):
+	New static functions
+	(DSPARSE_MAPPER, CD_SPARSE_MAPPER): New macro for complex values
+	with zero imaginary part.
+	(erf, erfc, gamma, lgamma): Use the new mappers to define these
+	mapper functions.
+	* ov-cx-sparse.h (erf, erfc, gamma, lgamma): Declare them.
+	* ov-re-sparse.cc (CD_SPARSE_MAPPER): Use correct mapper functors.
+	* mapper.cc: Add tests for the above cases.
+
+2008-03-27  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/max.cc: Rename from minmax.cc.
+	* Makefile.in (DLD_XSRC): Rename minmax.cc to max.cc.
+
+	* DLD-FUNCTIONS/__convn__.cc (convn): Use traits class and
+	typedefs to allow all types to be deduced from argument types.
+
+2008-03-27  Søren Hauberg  <hauberg at gmail.com>
+
+	* DLD-FUNCTIONS/__convn__.cc (Fconvn): Allow convolving real data with
+	complex data.
+
+2008-03-26  John W. Eaton  <jwe at octave.org>
+
+	* ov-range.h (octave_range::subsref (const std::string&,
+	const std::list<octave_value_list>&, int)):
+	Forward to simple subsref.
+	* ov-base-sparse.h (octave_base_sparse<T>::subsref (const std::string&,
+	const std::list<octave_value_list>&, int)): Likewise.
+	* ov-base-scalar.h (octave_base_sparse<T>::subsref (const std::string&,
+	const std::list<octave_value_list>&, int)): Likewise.
+	* ov-base-matrix.h (octave_base_matrix<T>::subsref (const std::string&,
+	const std::list<octave_value_list>&, int)): Likewise.
+
+	* ov-struct.cc, ov-cell.h (octave_cell::subsref (const
+	std::string&, const std::list<octave_value_list>&, int)):
+	Define nargout version of subsref instead of simple version.
+	* ov-struct.cc, ov-struct.h (octave_struct::subsref (const
+	std::string&, const std::list<octave_value_list>&, int)):
+	Define nargout version of subsref instead of simple version.
+
+	* ov-builtin.h (octave_builtin::subsref (const std::string&,
+	const std::list<octave_value_list>&): Forward to nargout subsref.
+	* ov-cell.h (octave_cell::subsref (const std::string&,
+	const std::list<octave_value_list>&)):
+	* ov-class.h (octave_class::subsref (const std::string&,
+	const std::list<octave_value_list>&): Likewise.
+	* ov-fcn-handle.h (octave_fcn_handle::subsref (const std::string&,
+	const std::list<octave_value_list>&): Likewise.
+	* ov-list.h (octave_list::subsref (const std::string&,
+	const std::list<octave_value_list>&): Likewise.
+	* ov-mex-fcn.h (octave_mex_function::subsref (const std::string&,
+	const std::list<octave_value_list>&): Likewise.
+	* ov-struct.h (octave_struct::subsref (const std::string&,
+	const std::list<octave_value_list>&)):
+	* ov-usr-fcn.h (octave_user_function::subsref (const std::string&,
+	const std::list<octave_value_list>&): Likewise.
+
+	* ov.cc (octave_value::subsref): Use value of nargout instead of
+	is_constant method to decide which type of subsref method to call.
+	(octave_value::assign): Always call simple subref method here.
+
+	* DLD-FUNCTIONS/chol.cc, DLD-FUNCTIONS/det.cc,
+	DLD-FUNCTIONS/getpwent.cc, DLD-FUNCTIONS/inv.cc,
+	DLD-FUNCTIONS/qr.cc, DLD-FUNCTIONS/symrcm.cc, file-io.cc):
+	Texinfo fixes.
+
+2008-03-26  Søren Hauberg  <hauberg at gmail.com>
+
+	* DLD-FUNCTIONS/__convn__.cc (Fconvn):
+	Call complex_array_value to extract N-d array.
+
+2008-03-26  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-sparse.cc (octave_base_sparse<T>::print_raw):
+	Also display percentage of elements that are nonzero.
+
+2008-03-25  Søren Hauberg  <hauberg at gmail.com>
+
+	* DLD-FUNCTIONS/__convn__.cc: New file.
+	* Makefile.in: Add __convn__.cc
+
+2008-03-25  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/hex2num.cc: New function
+	* Makefile.in (DLD_XSRC): Add hex2num.cc.
+
+2008-03-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* mappers.cc (Fexpm1, Flog1p): New functions.
+	* ov-base.cc, ov-base.h, ov-bool-mat.h, ov-bool-sparse.h,
+	ov-bool.h, ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h,
+	ov-cx-sparse.cc, ov-cx-sparse.h, ov-range.h, ov-re-mat.cc,
+	ov-re-mat.h, ov-re-sparse.cc, ov-re-sparse.h, ov-scalar.cc,
+	ov-scalar.h, ov.h:
+	Provide expm1 and log1p functions.
+
+	* mappers.cc (Froundb): New functions
+	* ov-base.cc, ov-base.h, ov-bool-mat.h, ov-bool-sparse.h,
+	ov-bool.h, ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h,
+	ov-cx-sparse.cc, ov-cx-sparse.h, ov-intx.h, ov-range.h,
+	ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc, ov-re-sparse.h,
+	ov-scalar.cc, ov-scalar.h, ov.h:
+ 	Provide roundb mapper function.
+
+2008-03-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* load-save.cc (save_vars): Handle -struct modifier.
+	(save_fields): New function.
+	(Fsave): Document new feature.
+
+2008-03-25  John W. Eaton  <jwe at octave.org>
+
+	* lex.h (lexical_feedback::looking_at_initializer_expression):
+	New data member.
+	* lex.l (lexical_feedback::init): Initialize it.
+	(handle_identifier): Don't unconditionally force identifiers to be
+	variables in the current scope.  Don't call force_local_variable
+	for symbols that appear in parameter initializer expressions.
+	* parse.y (decl_param_init): New parser "subroutine".
+	(decl2): Use it.  Set lexer_flags.looking_at_initializer_expression
+	to false after parsing initializer.
+
+2008-03-24  David Bateman  <dbateman at free.fr>
+
+	* data.cc (map_s_s): Fix for sparse/sparse mappers that resulted
+	in an empty sparse matrix being returned.
+	(Fhypot): New function based on the libm hypot function.
+
+2008-03-24  Primozz Peterlin  <primozz.peterlin at gmail.com>
+
+	* variables.cc (Fexist): Doc fix.
+
+2008-03-23  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-int.h: Add el_div and el_ldiv operators to the
+	binops that were missing them. Added elem_pow functions for mixed
+	integer floating point cases. Initialize the mixed integer
+	floating point cases.
+
+2008-03-21  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.h (octave_cell::is_constant): Return true.
+	* ov-cell.h, ov-cell.cc (octave_cell::subsref (const std::string&,
+	const std::list<octave_value_list>&)): Define.
+	(octave_cell::subsref (const std::string&,
+	const std::list<octave_value_list>&, int)): Call panic_impossible.
+
+	* ov-struct.h (octave_struct::is_constant): New function.
+	* ov-struct.h, ov-struct.cc (octave_struct::subsref (const std::string&,
+	const std::list<octave_value_list>&)): Define.
+	(octave_struct::subsref (const std::string&,
+	const std::list<octave_value_list>&, int)): Call panic_impossible.
+
+2008-03-21  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/amd.cc: New file.
+	* Makefile.in (DLD_XSRC): Add amd.cc.
+
+2008-03-20  David Bateman  <dbateman at free.fr>
+
+	* Cell.cc (Cell Cell::diag (void) const): delete.
+	(Cell Cell::diag (octave__idx_type) const):Rewrite in terms of
+	template classes function.
+	* Cell.h (Cell diag (void) const): delete.
+
+	* ov.h (octave_value diag (octave_idx_type) const): New method.
+	* ov-base.h (virtual octave_value diag (octave_idx_type) const):
+	New virtual method.
+	* ov-base.cc (octave_value octave_base_value::diag
+	(octave_idx_type) const): New default method.
+	
+	* ov-base-mat.h (octave_value diag (octave_idx_type) const): New
+	method. 
+	* ov-base-sparse.h (octave_value diag (octave_idx_type) const): New
+	method. 
+	* ov-base-scalar.h (octave_value diag (octave_idx_type) const): New
+	method. 
+	* ov-range.h (octave_value diag (octave_idx_type) const): New
+	method. 
+
+	* data.cc (make_diag, make_spdiag): Delete.
+	(Fdiag): Rewrite in terms of octave_value diag function.
+		
+	* data.cc (static octave_value make_diag (const Cell&,
+	octave_idx_type)): New instantiation of template function.
+	(static octave_value make_diag (const octave_value&,
+	octave_idx_type)): Allow cell arrays.
+
+	* Cell.cc (Cell Cell::diag (void) const, Cell Cell::diag
+	(octave__idx_type)): New methods for diagonal matrices.
+	* Cell.h (Cell Cell::diag (void) const, Cell Cell::diag
+	(octave__idx_type)): Declare them.
+
+2008-03-18  David Bateman  <dbateman at free.fr>
+
+	* ov-re-mat.cc (lgamma): Convert to a allow negative arguments.
+	* ov-re-sparse.cc (lgamma): ditto.
+	* ov-scalar.cc (lgamma): ditto.
+
+	* DLD-FUNCTIONS/minmax.cc: 64-bit indexing fix.
+
+2008-03-13  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr-fcn.cc (octave_user_function::octave_user_function):
+	Handle num_named_args in initialization list instead of functinon body.
+
+	* octave.gperf: Eliminate varargin and varargout keywords.
+	* lex.l (is_keyword_token): Eliminate varargin_kw and varargout_kw
+	from switch statement.
+	* parse.y (return_list): Eliminate special cases for VARARGOUT.
+	Call validate on tree_parameter_list object.
+	(param_list1): Likewise, for VARARGIN.
+	* pt-misc.cc (tree_parameter_list::validate): New function.
+	(tree_parameter_list::mark_varargs_only): Now private.
+	(tree_parameter_list::mark_varargs): Now private.
+	* pt-misc.h (tree_parameter_list::validate): Provide decl.
+
+2008-03-12  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (Vwhos_line_format): Omit print_dims parameter.
+	Fix doc string in Vwhos_line_format DEVAR.
+	(symbol_record_name_compare): Delete unused function.
+	(whos_parameter::dimensions): Delete struct field.
+	(symbol_info_list): New class.
+	(dimensions_string_req_first_space, make_dimensions_string,
+	dimensions_string_req_total_space): Delete.
+	(parse_whos_line_format): Move functionality to new
+	symbol_info_list class.
+	(print_symbol_info_line): Move functionality to new
+	symbol_info_list::struct symbol_info::displaly_line method.
+	(do_who): Simplify with new symbol_info_list class.
+	Handle index expressions in addition to symbol names.
+
+	* DLD-FUNCTIONS/dlmread.cc (Fdlmread): Fix separator detection.
+
+2008-03-11  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/eig.cc (Feig): Handle possible error from EIG.
+	* DLD-FUNCTIONS/qp.cc (qp, Fqp): Likewise.
+	* xpow.cc (xpow): Likewise.
+
+2008-03-11  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/dlmread.cc: Style fixes.
+
+2008-03-11  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/dlmread.cc: Function ported from octave forge. Add
+	spreadsheet style ranges.
+	* Makefile.in (DLD_XSRC): Add dlmread.cc.
+
+2008-03-10  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxCreateLogicalScalar): Argument is now mxLogical.
+
+	* data.cc (Fisfloat): New function.
+	* ov.h (octave_value::is_float_type): Ditto.
+	* ov-base.h (octave_base_value::is_float_type): Ditto.
+	* ov-complex.h (octave_complex): Ditto.
+	* ov-cx-mat.h (octave_complex_matrix): Ditto.
+	* ov-cx-sparse.h (octave_sparse_complex_matrix): Ditto.
+	* ov-range.h (octave_range): Ditto.
+	* ov-re-mat.h (octave_matrix): Ditto.
+	* ov-re-sparse.h (octave_sparse_matrix): Ditto.
+	* ov-scalar.h (octave_scalar): Ditto.
+
+	* mxarray.h.in (mxLogical): Use unsigned char instead of int.
+	From Antwerpen, G. (Gert) van <gert.vanantwerpen at tno.nl>.
+
+2008-03-07  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::print_raw): Don't print contents fo
+	struct arrays that have more than one element.
+
+2008-03-06  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Document that
+	the initial interpretation of a positive definite return from
+	matrix_type is that the matrix is "probably" positive definite and
+	not certainly so.
+
+2008-03-06  John W. Eaton  <jwe at octave.org>
+
+	* parse.y: Move tests here from test/test_eval.m.
+	* DLD-FUNCTIONS/fft.cc: Move tests here from test/test_signal.m.
+	* DLD-FUNCTIONS/dassl.cc: Move tests here from test/test_diffeq.m.
+	* DLD-FUNCTIONS/lsode.cc: Move tests here from test/test_diffeq.m.
+	* DLD-FUNCTIONS/quad.cc: Move tests here from test/test_quad.m.
+	* DLD-FUNCTIONS/time.cc: Move tests here from test/test_system.m.
+
+2008-03-06  Alexander Barth  <barth.alexander at gmail.com>
+
+	* DLD-FUNCTIONS/__lin_interpn__.cc (lookup):
+	Handle decreasing coordinate values.
+
+2008-03-05  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/chol.cc (Fcholupdate): Adjust code to meet 
+	Octave's coding guidelines.
+
+	* DLD-FUNCTIONS/qr.cc (Fqrupdate, Fqrinsert, Fqrdelete): Adjust 
+	code to meet Octave's coding guidelines.
+	* DLD-FUNCTIONS/qr.cc (Fqrdelete): Fix incorrect test. 
+
+	* DLD-FUNCTIONS/qr.cc (Fqrinsert, Fqrdelete): Modify to use
+	0-based indexing in liboctave's QR classes.
+
+2008-03-04  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/chol.cc (Fcholupdate): New function.
+
+	* DLD-FUNCTIONS/qr.cc (Fqrupdate, Fqrinsert, Fqrdelete):
+	New functions.
+
+2008-03-04  Ryan Rusaw  <rrusaw at gmail.com>
+
+	* toplev.h (octave_call_stack::element): New static function.
+	(octave_call_stack::cs): Now std::deque instead of std::list.
+
+	* pt-stmt.cc (curr_statement, curr_caller_statement): Delete.
+	* pt-stmt.h: Delete decls.
+
+	* pt-stmt.h, pt-stmt.cc (tree_statement_stack): New class.
+
+	* pt-stmt.cc (tree_statement::eval): Use tree_statement_stack
+	instead of curr_statement variable.
+
+	* ov-usr-func.cc (octave_user_function::do_multi_index_op):
+	Don't set curr_caller_statement.
+
+	* error.cc (verror, pr_where): Call tree_statement_stack::current_line
+	and tree_statement_stack::current_column instead of 
+	instead of curr_statement->line and curr_statement->column.
+	* input.cc (get_user_input): Likewise.
+
+2008-02-27  John P. Swensen  <jpswensen at gmail.com>
+
+	* debug.cc (get_user_function): Call symtab::find_function instead
+	of symtab::find_user_function.
+
+2008-02-27  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (do_read): Stop reading if seek fails.
+
+2008-02-26  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-int.cc (octave_base_int_helper,
+	octave_base_int_helper_traits): New templates and specializations.
+	(octave_base_int_matrix<T>::convert_to_str_internal,
+	octave_base_int_matrix<T>::convert_to_str_internal): Use them.
+
+	* DLD-FUNCTIONS/rand.cc (do_rand): Pass name of calling function
+	to octave_rand::state.
+
+	* variables.cc (bind_ans): Handle cs-lists recursively.
+
+	* ov-cs-list.h, ov-cs-list.cc (octave_cs_list::print,
+	octave_cs_list::print_raw): Delete.
+
+2008-02-25  John W. Eaton  <jwe at octave.org>
+
+	* Cell.cc (Cell::map): New function.
+	* Cell.h (Cell::map): Declare.
+	(xisalnum, xisalpha, xisascii, xiscntrl, xisdigit,
+	xisgraph, xislower, xisprint, xispunct, xisspace, xisupper,
+	xisxdigit, xtoascii, xtolower, xtoupper): New mapper functions.
+	(ctype_mapper): New private typedef.
+
+	* ov-cell.h (xisalnum, xisalpha, xisascii, xiscntrl, xisdigit,
+	xisgraph, xislower, xisprint, xispunct, xisspace, xisupper,
+	xisxdigit, xtoascii, xtolower, xtoupper): New mapper functions.
+
+2008-02-25  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* ov-scalar.cc (octave_scalar::round): Use xround instead of ::round
+	in mapper implementation.
+
+2008-02-25  John W. Eaton  <jwe at octave.org>
+
+	* ov-base.cc (UNDEFINED_MAPPER, STRING_MAPPER): New macros.  Use
+	them to define mapper functions.
+
+	* mappers.cc (Fisalnum, Fisalpha, Fisascii, Fiscntrl, Fisdigit,
+	Fisgraph, Fislower, Fisprint, Fispunct, Fisspace, Fisupper,
+	Fisxdigit, Ftoascii, Ftolower, Ftoupper):
+	Use DEFUNX to define ctype mapper functions.
+	Use new function names.
+
+	* ov-base.h, ov-base.cc, ov-str-mat.h, ov-str-mat.cc:
+	Prepend x to ctype mapper function names.
+
+	* graphics.h.in (row_vector_property::row_vector_property):
+	Set default constraints here.
+	(row_vector_property::add_constraint): New function.
+	(row_vector_property::validate): Delete decl.
+	(axes::properties::init): Use single-arg add_constraint function
+	for xlim, ylim, zlim, clim, and alim properties.
+
+	* graphics.cc (row_vector_property::validate): Delete.
+
+	* graphics.cc (axes::properties::update_camera,
+	axes::properties::update_aspectratios):
+	Avoid shadow warnings from GCC.
+
+	* graphics.h.in (base_properties::get_bounding_box):
+	Avoid unused argument warning from GCC.
+
+	* graphics.h.in (array_property::add_constraint): Arg is now const
+	reference, not value.
+
+	* graphics.h.in, graphics.cc (class row_vector_property): New class.	
+	(axes::properties): xlim, ylim, zlim, clim, alim, xtick, ytick,
+	ztick properties are now row_vector_property objects instead of
+	array_property objects.
+
+	* genprops.awk: Special case row_vector_property in the same way
+	as array_property.
+
+2008-02-22  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/ccolamd.cc, DLD-FUNCTIONS/colamd.cc,
+	DLD-FUNCTIONS/convhulln.cc, DLD-FUNCTIONS/dmperm.cc,
+	DLD-FUNCTIONS/qz.cc, DLD-FUNCTIONS/regexp.cc,
+	DLD-FUNCTIONS/symbfact.cc, zfstream.h, zfstream.cc:
+	Use 0 instead of NULL.
+
+2008-02-22  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/chol.c (Fchol, Fcholinv, Fchol2iinv): Treat 
+	sparse matrices. Add the "lower" and "vector" flags.
+	* DLD-FUNCTIONS/inv.c (Finv): Treat sparse matrices.
+	* DLD-FUNCTION/sparse.cc (static bool is_sparse (const
+	octave_value&)): Remove and use arg.is_sparse_type () instead.
+	(Fspcumprod, Fspcumsum, Fspprod, spsum, spsumsq, spdiag): Remove.
+	* DLD-FUNCTIONS/splu.cc: Remove.
+	* DLD-FUNCTIONS/lu.cc: Treat sparse matrices, Add "vector" flag.
+	* DLD-FUNCTIONS/spchol.cc: Move to symbfact.cc
+	* DLD-FUNCTIONS/symbfact.cc: Remove cholesky functions Fspchol,
+	Fspcholinv, Fspchol2inv.
+	* DLD-FUNCTIONS/luinc.cc: Modify for new sparse LU
+	constructors. Ass the 'vector' flag.
+	* DLD-FUNCTIONS/spparms.cc: Add the sum_tol flag.
+
+	* Makifile.in (DLD_XSRC): Remove spchol.cc, splu.cc and add 
+	symbfact.cc
+	* data.cc (NATIVE_REDUCTION): Treat sparse matrices
+	(DATA_REDUCTION): Ditto.
+	(template <class T> static octave_value make_spdiag (const T&, 
+	octave_idx_type)): New template function for sparse diag
+	function. Instantiate it.
+	(static octave_value make_diag (const octave_value&, 
+	octave_idx_type): Use make_spdiag for sparse matrice.
+	(Fatan2): Compatibility fixes for mixed full/sparse matrices.
+	
+2008-02-21  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fsolve.cc (fsolve_user_jacobian):
+	Check dimensions of user-supplied Jacobian matrix.
+	(fsolve_user_function): Check for non-square systems.
+
+2008-02-20  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (map_d_m, map_m_d, map_m_m, Fatan2, Ffmod):
+	Handle N-d arrays.
+
+	* ov-bool-mat.h (octave_bool_matrix (const Array2<bool>&)): Delete.
+
+2008-02-20  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/det.cc, DLD-FUNCTIONS/find.cc,
+	* DLD-FUNCTIONS/minmax.cc, DLD-FUNCTIONS/qr.cc:
+	Treat sparse matrices.
+	
+	* DLD-FUNCTIONS/sparse.cc (Fspmin, Fspmax, Fatan2): Remove functions.
+
+	* DLD-FUNCTIONS/dmperm.cc: Rename from spqr.cc.
+	(Fspqr): Delete function.
+
+	* DLD-FUNCTIONS/spqr.cc, DLD-FUNCTIONS/spdet.cc,
+	DLD-FUNCTIONS/spfind.cc: Remove.
+
+	* Makefile.in (DLD_XSRC): Add dmperm.cc to the list.
+	Delete det.cc, find.cc, minmax.cc, and qr.cc from the list.
+
+	* Makefile.in (OV_SRC): Remove ov-mapper.cc.
+	(OV_INCLUDES): Remove ov-mapper.h.
+	(DEFUN_PATTERN): No longer accept DEFUN_MAPPER as valid.
+	* ov-mapper.cc, ov-mapepr.h: Delete, remove all includes of
+	ov-mapper.h from all files.
+
+	* op-b-sbm.cc, op-bm-sbm.cc, op-smb-b.cc, op-sbm-bm.cc: Include 
+	ov-bool-sparse.h.
+
+	* defun-int.h (DEFUN_MAPPER_INTERNAL, install_builtin_mapper):
+	Remove.
+	* defun.cc (install_builtin_mapper): Ditto.
+	* defun.h (DEFUN_MAPPER): Remove.
+
+	* mappers.cc: Rewrite all mapper function using DEFUN and newly
+	introduced octave_value mapper functions.
+	(dummyp, xabs, xisalnum, xisascii, xiscntrl, xisdigit,
+	xisgraph, xislower, xisprint, xispunct, xisspace, xisupper,
+	xtoascii, xtolower, xtoupper, xconj, ximag, xreal): Remove
+	static wrapper functions.
+
+	* mkbuiltins (XDEFUN_MAPPER_INTERNAL, install_builtin_functions): 
+	Remove.
+	* mkgendoc (XDEFUN_MAPPER_INTERNAL): Remove.
+
+	* ov.cc (octave_mapper::register_type): Remove.
+	
+	* ov.h (abs, acos, acosh, angle, arg, asin, asinh, atan, atanh,
+	ceil, conj, cos, cosh, erf, erfc, exp, finite, fix, floor, gamma,
+	imag, isinf, isna, isnan, lgamma, log, log10, real, round, signum,
+	sin, sinh, sqrt, tan, tanh, isalnum, isalpha, isascii, iscntrl,
+	isdigit, isgraph, islower, isprint, ispunct, isspace, isupper,
+	isxdigit, toascii, tolower, toupper):
+	New octave_value mapper	functions.
+
+	* ov-base.h (abs, acos, acosh, angle, arg, asin, asinh, atan,
+	atanh, ceil, conj, cos, cosh, erf, erfc, exp, finite, fix, floor,
+	gamma, imag, isinf, isna, isnan, lgamma, log, log10, real, round,
+	signum, sin, sinh, sqrt, tan, tanh, isalnum, isalpha, isascii,
+	iscntrl, isdigit, isgraph, slower, isprint, ispunct, isspace,
+	isupper, isxdigit, toascii, tolower, toupper):
+	New virtual mapper functions.
+	* ov-base.cc (abs, acos, acosh, angle, arg, asin, asinh, atan,
+	atanh, ceil, conj, cos, cosh, erf, erfc, exp, finite, fix, floor,
+	gamma, imag, isinf, isna, isnan, lgamma, log, log10, real, round,
+	signum, sin, sinh, sqrt, tan, tanh, isalnum, isalpha, isascii,
+	iscntrl, isdigit, isgraph, slower, isprint, ispunct, isspace,
+	isupper, isxdigit, toascii, tolower, toupper):
+	Base versions of mapper functions.
+
+	* ov-bool-mat.h (abs, acos, acosh, angle, arg, asin, asinh, atan,
+	atanh, ceil, conj, cos, cosh, erf, erfc, exp, finite, fix, floor,
+	gamma, imag, isinf, isna, isnan, lgamma, log, log10, real, round,
+	signum, sin, sinh, sqrt, tan, tanh):
+	Mapper function recast boolen matrix as double.
+	* ov-bool.h (abs, acos, acosh, angle, arg, asin, asinh, atan,
+	atanh, ceil, conj, cos, cosh, erf, erfc, exp, finite, fix, floor,
+	gamma, imag, isinf, isna, isnan, lgamma, log, log10, real, round,
+	signum, sin, sinh, sqrt, tan, tanh): Ditto.
+	* ov-bool-sparse.h (abs, acos, acosh, angle, arg, asin, asinh,
+	atan, atanh, ceil, conj, cos, cosh, erf, erfc, exp, finite, fix,
+	floor, gamma, imag, isinf, isna, isnan, lgamma, log, log10, real,
+	round, signum, sin, sinh, sqrt, tan, tanh): Ditto.
+	(char_array_value): New method to convert to charNDArray.
+	* ov-bool-sparse.cc (char_array_value): New method to convert to
+	charNDArray.
+	* ov-complex.cc (char_array_value): ditto.
+	(xabs, ximag, xreal): Static wrapper functions.
+	(abs, acos, acosh, angle, arg, asin, asinh, atan, atanh, ceil,
+	conj, cos, cosh, exp, finite, fix, floor, imag, isinf, isna,
+	isnan, log, log10, real, round, signum, sin, sinh, sqrt, tan,
+	tanh): New mapper methods.
+	* ov-complex.h: Provide decls.
+
+	* ov-cx-mat.cc (char_array_value): New method to convert to
+	charNDArray.
+	(xabs, ximag, xreal): Static wrapper functions.
+	(abs, acos, acosh, angle, arg, asin, asinh, atan, atanh, ceil,
+	conj, cos, cosh, exp, finite, fix, floor, imag, isinf, isna,
+	isnan, log, log10, real, round, signum, sin, sinh, sqrt, tan,
+	tanh): New mapper methods.
+	* ov-cx-mat.h: Provide decls.
+	
+	* ov-cx-sparse.cc (char_array_value): New method to convert to
+	charNDArray.
+	(xabs, ximag, xreal): Static wrapper functions.
+	(abs, acos, acosh, angle, arg, asin, asinh, atan, atanh, ceil,
+	conj, cos, cosh, exp, finite, fix, floor, imag, isinf, isna,
+	isnan, log, log10, real, round, signum, sin, sinh, sqrt, tan,
+	tanh): New mapper methods.
+	* ov-cx-sparse.h: Provide decls.
+
+	* ov-intx.h (abs, signum, imag, ceil, conj, fix, floor, real,
+	round, finite, isinf, isna, isnan): Define for both matrix and
+	scalar classes.
+	
+	* ov-range.h (abs, acos, acosh, angle, arg, asin, asinh, atan,
+	atanh, ceil, conj, cos, cosh, erf, erfc, exp, finite, fix, floor,
+	gamma, imag, isinf, isna, isnan, lgamma, log, log10, real, round,
+	signum, sin, sinh, sqrt, tan, tanh): New mapper functions.
+
+	* ov-re-mat.cc (any_element_less_than): Static function to check if
+	any elemet was less than a value,
+	(any_element_greater_than): Ditto with greater than.
+	(abs, acos, acosh, angle, arg, asin, asinh, atan, atanh, ceil,
+	conj, cos, cosh, erf, erfc, exp, finite, fix, floor, gamma, imag,
+	isinf, isna, isnan, lgamma, log, log10, real, round, signum, sin,
+	sinh, sqrt, tan, tanh): New mapper functions.
+	* ov-re-mat.h: Provide decls.
+	
+	* ov-scalar.cc (any_element_less_than): Static function to check if
+	any elemet was less than a value,
+	(any_element_greater_than): ditto with greater than.
+	(abs acos acosh angle arg asin asinh atan atanh 
+	ceil conj cos cosh erf erfc exp finite fix floor gamma imag 
+	isinf isna isnan lgamma log log10 real round signum sin sinh 
+	sqrt tan tanh): New mapper functions.
+	* ov-scalar.h: Provide decls.
+
+	* ov-str-mat.cc (xisalnum, xisascii, xiscntrl, xisdigit,
+	xisgraph, xislower, xisprint, xispunct, xisspace, xisupper,
+	xtoascii, xtolower, xtoupper): New static wrapper functions.
+	(isalnum, isalpha, isascii, iscntrl, isdigit, isgraph, islower,
+	isprint, ispunct, isspace, isupper, isxdigit, toascii, tolower,
+	toupper): New mapper methods.
+	* ov-str-mat.h: Provide decls.
+
+2008-02-18  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Fatan2): Reject arguments that are integer types.
+
+2008-02-19  Jaroslav Hajek  <highegg at gmail.com>
+
+	* DLD-FUNCTIONS/qr.cc: Doc fix.
+
+2008-02-18  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h
+	(symbol_table::fcn_info::fcn_info_rep::clear_unlocked_functions):
+	symbol_table::fcn_info::fcn_info_rep::clear_cmdline_function,
+	symbol_table::fcn_info::fcn_info_rep::clear_autoload_function):
+	New functions.
+	(symbol_table::fcn_info::fcn_info_rep::clear_user_function):
+	Don't clear locked functions.
+	(symbol_table::fcn_info::fcn_info_rep::clear_mex_function):
+	Call clear_user_function instead of setting function_on_path directly.
+	(symbol_table::fcn_info::fcn_info_rep::clear):
+	Use new functions to do the real work.
+
+	* ov.h (octave_value::lock, octave_value::unlock,
+	octave_value::islocked): New functions.
+	* ov-base.cc (octave_base_value::lock, octave_base_value::unlock):
+	New functions.
+	* ov-base.h Provide decls.
+	(octave_base_value::islocked): New function.
+	* ov-fcn.h (octave_function::islocked): Now const.
+
+2008-02-15  John W. Eaton  <jwe at octave.org>
+
+	* ov-builtin.cc (octave_builtin::do_multi_index_op):
+	Catch possible octave_execution_exception.
+	* ov-mex-fcn.cc (octave_mex_function::do_multi_index_op): Likewise.
+	* ov.cc (do_binary_op, do_cat_op, do_unary_op,
+	octave_value::do_non_const_unary_op): Likewise.
+
+2008-02-14  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/qz.cc:
+	Don't check f77_exception_encountered.
+
+	* sighandlers.cc (user_abort): If interrupting immediately, set
+	octave_interrupt_state if it is not already set.
+
+	* pt-stmt.cc (tree_statement::eval): Catch execution exceptions.
+
+	* octave.cc (lo_error_handler): New static function.
+	(initialize_error_handlers): Set liboctave_error_handler to
+	lo_error_handler, not error.
+
+	* DLD-FUNCTIONS/urlwrite.cc (urlget): Call octave_rethrow_exception
+	instead of octave_throw_interrupt_exception.
+	* utils.cc (BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF): 
+	Likewise.
+
+2008-02-12  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in: Implement the cdatamapping property in patch and
+	image objects.
+
+2008-02-12  John W. Eaton  <jwe at octave.org>
+
+	* pt-loop.cc (tree_simple_for_command::eval): Compute range
+	element with multiplication.
+
+2008-02-11  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in ($(MAKEDEPS)): Skip dependencies if omit_deps is defined.
+
+2008-02-09  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (set_range_format): Eliminate sign arg.
+	Change all callers.
+
+2008-02-08  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::subsref): Allow Cell::index to resize.
+
+	* input.cc (interactive_input): Eliminate debug arg.  Change All uses.
+	(get_user_input): Don't process input_buf if there is an error.
+	Call reset_error_handler instead of setting error_state to 0.
+
+2008-02-08  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (callback_property::execute): New static
+	helper method (useful to execute callbacks by name).
+	* graphics.cc (callback_property::execute): Likewise.
+	(execute_callback): Avoid undefined argument when executing
+	callback. Do not use arguments when the callback is a string.
+
+2008-02-07  John W. Eaton  <jwe at octave.org>
+
+	* ov-range.h (octave_range::sort): New functions.
+
+2008-02-07  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (DLD_XSRC): Delete spkron.cc.
+	* DLD-FUNCTIONS/spkron.cc: Delete.
+	* DLD-FUNCTIONS/kron.cc: Include here and dispatch to the sparse
+	version if either argument is sparse.
+
+2008-02-06  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (parse.cc): Also use --defines option for bison.
+
+2008-02-06  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.cc (axes::properties::set_defaults): Set default axes
+	color to white.
+
+2008-02-06  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (parse.cc): Use "-o $@" instead of renaming y.tab.c.
+	(maintainer-clean): Don't remove y.tab.c.
+
+	* Makefile.in (parse.cc : parse.y): Use mv instead of move-if-change.
+	(stamp-prereq, stamp-liboctave-prereq): Eliminate.
+	(clean): Don't remove stamp-prereq and stamp-liboctave-prereq.
+	(OPT_BASE, OPT_IN, OPT_INC): New macros.
+	(OPT_HANDLERS): Define in terms of OPT_BASE.
+	($(OPT_INC) : %.h : %.in): New pattern rule.
+	(PREREQ): New macro.
+	($(MAKEDEPS)): Simplify with $(PREREQ).
+
+2008-02-05  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in: Unconditionally include $(MAKEDEPS).
+	Mark $(MAKEDEPS) as .PHONY targets if omit_deps is true.
+
+2008-02-05  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (base_properties::get_boundingbox): New method.
+	(figure::properties::get_boundingbox): Overload method.
+	(axes::properties::get_boundingbox): Likewise.
+	* graphics.cc (figure::properties::get_boundingbox): Return a
+	left-to-right/top-to-bottom bounding box rectangle.
+	(axes::properties::get_boundingbox): Likewise.
+	(axes::properties::update_camera): Remove backend access and
+	use the new axes bounding box.
+
+2008-02-04  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h.in (axes::properties::update_xlim,
+	axes::properties::update_ylim, axes::properties::update_zlim):
+	New update methods.
+
+	* graphics.cc (axes::properties::calc_ticks): New function.
+	(axes::properties::magform): New function.
+	(axes::update_axis_limits): Call update_{x,y,z}lims if
+	appropriate.
+
+2008-02-04  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (base_graphics_backend::get_screen_size,
+	graphics_backend::get_screen_size): New methods.
+	(graphics_backend::available_backends): Export symbol.
+	(class figure::properties, class axes::properties): Export classes.
+	(figure::properties::get_boundingbox): New utility method.
+	(figure::properties::position): Use valid default position.
+	(axes::properties::gridlinestyle,
+	axes::properties::minorgridlinestyle):
+	Use dotted line style as default. 
+	* graphics.cc (default_figure_position): New static function.
+	(gnuplot_backend::get_screen_size): New method.
+	(figure::properties::get_boundingbox): New utility method.
+
+2008-02-02  Shai Ayal  <shaiay at users.sourceforge.org>
+
+        * graphics.h.in (base_scaler::~base_scalar): New virtual destructor.
+        * graphics.cc (axes::properties::update_camera): Tag abs with std.
+
+	* graphics.h.in (graphics_backend::find_backend): New function.
+	(class figure): Add __backend__ property and set method.
+	
+2008-02-02  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (do_type): Don't print dyamically loaded function files.
+
+	* ov-fcn.h (octave_function::is_dynamically_loaded_function): Delete.
+
+2008-02-01  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (Fset_variable, Fvariable_value):
+	New functions, but commented out for now.
+
+2008-01-30  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (axes::properties::get_transform_matrix,
+	axes::properties::get_inverse_transform_matrix,
+	axes::properties::get_opengl_matrix_1,
+	axes::properties::get_opengl_matrix_2,
+	axes::properties::get_transform_zlim): New accessors.
+	(base_properties::is_clipping): New accessor.
+	(class graphics_xform): New class encapsulating axes transformation.
+	(axes::properties::get_transform): New method returning a
+	graphics_xform object.
+	* graphics.cc (class graphics_xform): New class.
+
+2008-01-31  David Bateman  <dbateman at free.fr>
+
+	* ov.cc (octave_value::octave_value (const ArrayN<bool>&),
+	octave_value::octave_value (const Sparse<bool>&, const MatrixType &),
+	octave_value::octave_value (const ArrayN<std::streamoff>&)): New 
+	constructors.
+	* ov.h: (octave_value (const ArrayN<bool>&),
+	octave_value (const Sparse<bool>&, const MatrixType &),
+	octave_value (const ArrayN<std::streamoff>&)): Declare them.
+	(octave_value sort (octave_idx_type, sortmode) const, octave_value
+	sort (Array<octave_idx_type> &, octave_idx_type, sortmode) const):
+	octave_value sort method.
+	
+	
+	* ov-base.cc (sort): Base versions of teh octave_value sort methods.
+	* ov-base.h (sort): Declare the octave_value sort methods
+	* ov-base-scalar.h (sort): Simple sort methods for scalars.
+	* ov-base-mat.h, ov-base-sparse.h (sort): Sort methods calling
+	underlying array or sparse sort methods.
+	* ov-str-mat.h (sort): String specific sort methods.
+	
+	* TEMPLATE-INST/Array-tc.cc: Instantiate the array sort methods.
+	* ov-streamoff.h (sort): Sort versions returning and error.
+	* oct-stream.cc, ov-typeinfo.cc, Array-os.cc: Null instantiation
+	of array sort methods.
+	
+	* Makefile.in (DLD_XSRC): Remove sort.cc
+	* DLD-FUNCTIONS/sort.cc: Remove
+	* data.cc (Fsort): New function using octave_value sort methods
+	for the sorting. Add tests.
+
+2008-01-30  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* pager.cc (Fmore): Doc fix.
+
+2008-01-28  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* genprops.awk: Add update ('u') modifier and document the
+	readonly ('r') modifier.
+	* graphics.h.in (class base_scaler, class lin_scaler, class
+	log_scaler, class scaler): New classes to make abstraction of the
+	axis scale.
+	(base_graphics_backend::get_screen_resolution,
+	graphics_backend::get_screen_resolution): New methods.
+	(axes::properties::sx, axes::properties::sy,
+	axes::properties::sz): New scaler fields.
+	(axes::properties::get_x_scaler, axes::properties::get_y_scaler,
+	axes::properties::get_z_scaler): New accessors.
+	(axes::properties::x_render, axes::properties::x_render_inv,
+	axes::properties::x_gl_mat1, axes::properties::x_gl_mat2,
+	axes::properties::x_zlim): New utility Matrix fields.
+	(axes::properties::get_boundingbox,
+	axes::properties::update_camera,
+	axes::properites::update_aspectratios,
+	axes::properties::update_transform,
+	axes::properties::update_xscale, axes::properties::update_yscale,
+	axes::properties::update_zscale, axes::properties::update_view,
+	axes::properties::update_xdir, axes::properties::update_ydir,
+	axes::properties::update_zdir): New updater methods.
+	(axes::properties::init): Initialize sx, sy, sz and x_zlim correctly.
+	(axes::properties::position): Use valid default position value.
+	(axes::properties::xscale, axes::properties::yscale,
+	axes::properties::zscale, axes::properties::xdir,
+	axes::properties::ydir, axes::properties::zdir,
+	axes::properties::view): Add updater ('u') property modifier.
+	* graphics.cc (default_axes_position, default_axes_outerposition):
+	New initializers.
+	(convert_position): New utility function to convert position
+	according to specified units.
+	(gnuplot_backend::get_screen_resolution): New method.
+	(axes::properties::set_defaults): Initilize recently added properties.
+	(xform_matrix, xform_vector, transform, xform_scale,
+	xform_translate, scale, translate, xform, normalize, dot, cross,
+	unit_cube, cam2xform, xform2cam): New inline transformation
+	utility functions.
+	(axes::properties::update_camera,
+	axes::properties::update_aspectratios,
+	axes::properties::get_boundingbox): New updater methods for
+	computing transformation matrices.
+	(axes::update_axis_limits): Update transformation data.
+
+2008-01-28  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (BEGIN_CHAR_CLASS_CONVERSION): Handle width properly.
+	(OCTAVE_SCAN) [__GNUG__ && ! CXX_ISO_COMPLIANT_LIBRARY]:
+	Delete special case.
+
+2008-01-25  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/rand.cc (Frandp): Relax relative error on randp
+	tests.
+
+2008-01-25  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (base_properties::get_backend,
+	base_graphics_object::get_backend, graphics_backend::get_backend):
+	New methods for convenient access to the backend.
+	(figure::get_backend, figure::set_backend): Remove.
+	* graphics.cc (base_properties::get_backend): New method.
+	(Fdrawnow): Use graphics_object::get_backend to simplify code.
+
+2008-01-24  Pascal Dupuis  <Pascal.Dupuis at worldonline.be>
+
+	* mxarray.h.in: Include <cstring>.
+
+2008-01-22  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (clear_drawnow_request): New function.
+	(Fdrawnow): Add it to the unwind_protect stack.
+
+	* input.cc (Vdrawnow_requested): No longer static.
+	* input.h: Provide decl.
+	* graphics.cc (Fdrawnow, Fset, make_graphics_object):
+	Use Vdrawnow_requested directly.
+
+	* toplev.cc (octave_add_atexit_function,
+	octave_remove_atexit_function): New functions.
+	(Fatexit): Use them.
+	* graphics.cc (Fdrawnow): Call octave_add_atexit_function instead
+	of using eval.
+	* toplev.h (octave_add_atexit_function,
+	octave_remove_atexit_function): Provide decls.
+
+2008-01-22  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (base_properties::is_visible,
+	base_properties::set_modified): New accessors.
+	(class base_graphics_backend, class graphics_backend): New classes
+	for handling octave/backend interaction.
+	(figure::properties::close): Add "pop" argument controlling
+	whether the figure should be popped from the list of existing figures.
+	(class figure::properties): New backend field and accessors, holding
+	the graphics backend associated with the figure.
+	* graphics.cc (class gnuplot_backend): New class for the default
+	gnuplot backend.
+	(figure::properties::close): Add "pop" argument and transfer the
+	figure closing to the associated backend.
+	(Fdrawnow): New builtin function, converted from drawnow.m.
+
+2008-01-19  John W. Eaton  <jwe at octave.org>
+
+	* genprops.awk (emit_source): Use "pname" for property name argument.
+
+2008-01-19  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h.in (class figure::properties): New properties:
+	alphamap, currentcharacter, currentobject, current_point,
+	dockcontrols, doublebuffer, filename, integerhandle,
+	inverthardcopy, keypressfcn, keyreleasefcn, menubar, mincolormap,
+	name, numbertitle, paperunits, paperposition, paperpositionmode,
+	papersize, papertype, pointer, pointershapecdata,
+	pointershapehotspot, position, renderer, renderermode, resize,
+	resizefcn, selectiontype, toolbar, units, windowbuttondownfcn,
+	windowbuttonmotionfcn, windowbuttonupfcn, windowbuttonwheelfcn,
+	windowstyle, wvisual, wvisualmode, xdisplay, xvisual, xvisualmode,
+	buttondownfcn.
+
+2008-01-19  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (base_properties::beingdeleted,
+	base_properties::is_beingdeleted,
+	base_properties::get_beingdeleted,
+	base_properties::set_beingdeleted):
+	Add beingdeleted property and accessors.
+	* graphics.cc (base_properties::get): Likewise.
+	(gh_manager::free): Set beingdeleted to "on" when freeing an object.
+	* genprops.awk: Skip C++-style comments in property declaration.
+
+	* graphics.h.in (class axes::properties): New properties: alim,
+	alimmode, xminortick, yminortick, zminortick, ambientlightcolor,
+	cameraposition, cameratarget, cameraupvector, cameraviewangle,
+	camerapositionmode, cameratargetmode, cameraupvectormode,
+	cameraviewanglemode, currentpoint, drawmode, fontangle, fontname,
+	fontsize, fontweight, fontunits, gridlinestyle,
+	minorgridlinestyle, linestyleorder, linewidth, plotboxaspectratio,
+	plotboxaspectratiomode, projection, tickdir, tickdirmode,
+	ticklength, tightinset, units, x_viewtransform,
+	x_projectiontransform, x_viewporttransform, x_normrendertransform,
+	x_rendertransform.
+	* genprops.awk: Handle new readonly modifier 'r'.
+
+2008-01-18  Juhani Saastamoinen  <juhani at cs.joensuu.fi>
+
+	* genprops.awk: Avoid using "default" as a variable name.
+
+2008-01-17  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (data_property::get_data_limits): Reset min/max values.
+
+2008-01-17  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-inline.cc: Add tests for Finline.
+
+2008-01-17  Ben Abbott  <bpabbott at mac.com>
+
+	* load-path.cc (F__pathorig__): Rename from Fpathdef.
+	(Frestoredefaultpath): New function.
+
+2008-01-16  John W. Eaton  <jwe at octave.org>
+
+	* pt-assign.cc (tree_simple_assignment::rvalue,
+	tree_multi_assignment::rvalue): Handle assignment of
+	comma-separated lists.
+
+2008-01-15  John W. Eaton  <jwe at octave.org>
+
+	* mappers.cc (install_mapper_functions): Move test for asin here
+	from test/test_arith.m.
+
+	* graphics.h.in (class line::properties, class text::properties):
+	Rename erase_mode property to erasemode.
+
+2008-01-15  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (base_properties::remove_child,
+	base_properties::adopt, base_properties::update_axis_limits):
+	Make virtual.
+	(base_graphics_object::mark_modified,
+	base_graphics_object::override-defaults,
+	base_graphics_object::set_from_list, base_graphics_object::set,
+	base_graphics_object::get, base_graphics_object::get_parent,
+	base_graphics_object::remove_child, base_graphics_object::adopt,
+	base_graphics_object::reparent, base_graphics_object::defaults,
+	base_graphics_object::type): Add default implementation.
+	(class root_figure, class figure, class axes, class line,
+	class text, class image, class patch, class surface):
+	Remove overloaded virtual methods whose implementation is
+	identical to the default one.
+
+	* genprops.awk: Handle 'h' modifier for hidden properties.
+	Replace "get(void)" method with "get(bool all = false)" to allow
+	access to hidden properties.
+
+	* graphics.h.in (base_properties::get, base_graphics_object::get,
+	graphics_object::get, root_figure::get, figure::get, axes::get,
+	line::get, text::get, patch::get, surface::get, image::get):
+	New arg, ALL, to access hidden properties.
+	(gh_manager::do_get_object): Do not look for invalid handles.
+	(figure::properties::__plot_stream__,
+	figure::properties::__enhanced__, axes::properties::__colorbar__):
+	Make properties hidden.
+	(axes::properties, line::properties, text::properties,
+	patch::properties, surface::properties): Remove obsolete 'a'
+	property modifier.
+	* graphics.cc (base_properties::get): New arg ALL, to access
+	hidden properties.
+	(base_properties::mark_modified): Call mark_modified only on valid
+	parent object.
+	(__get__): New internal function returning all properties,
+	including the hidden ones.
+
+2008-01-15  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (properties::set_currentfigure,
+	properties::set_currentaxes): Don't convert arg to double
+	before passing to graphics_handle constructor.
+	(base_properties::remove_child): Call mark_modified if list of
+	children changes.
+
+2008-01-15  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h.in (class line::properties): New properties:
+	displayname, erasemode.
+	(class text::properties) New properties: backgroundcolor,
+	displayname, edgecolor, erase_mode, editing, fontunits, linestyle,
+	linewidth, margin, verticalalignment.
+
+2008-01-14  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_initialize): Start with sys_path empty.
+	(maybe_add_path_elts): Omit path_sep_str if path is empty.
+
+	* symtab.h (symbol_table::do_pop_context): Remove symbol_records
+	which have no more context.
+	(symbol_table::symbol_record::pop_context,
+	(symbol_table::symbol_record::symbol_record_rep::pop_context):
+	Return size of value_stack, or 1 if variable is persistent or global.
+
+2008-01-14  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.h.in (class patch::properties): New properties:
+	cdatamapping, facevertexalphadata, facevertexcdata, vertexnormals,
+	normalmode, facelighting, edgealpha, edgelighting,
+	backfacelighting, ambientstrength, diffusestrength,
+	specularstrength, specularexponent, specularcolorreflectance,
+	erasemode.
+
+2008-01-14  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* graphics.h.in (gh_manager::do_make_graphics_handle,
+	gh_manager::make_graphics_handle): New boolean parameter
+	do_createfcn.
+	* graphics.cc (xcreatefcn): New static function.
+	(gh_manager::do_make_graphics_handle): New boolean parameter
+	do_createfcn.  Execute createfcn callback accordingly.
+	(make_graphics_object, F__go_figure__): Use do_createfcn
+	parameter and call xcreatefcn
+
+	* genprops.awk (emit_get_callback): Pass user data to execute method.
+	* graphics.cc (execute_callback): New static function.
+	(callback_property::validate): Make it work.
+	(callback_property::execute): Make it work.
+	(gh_manager::do_free): Execute delete function here.
+	* graphics.h.in (callback_property::execute): Fix decl.
+	(base_properties::buttondownfcn, base_properties::createfcn,
+	base_properties::deletefcn, base_properties::userdata): Default
+	value is empty Matrix, not undefined octave_value object.
+	(base_properties::execute_createfcn): New function.
+	(base_properties::execute_deletefcn): New function.
+
+2007-12-13  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h.in, graphics.cc (class base_properties): New
+	properties: busyaction, buttondownfcn, clipping, createfcn,
+	deletefcn, handlevisibility, hittest, interruptible, selected,
+	selectionhighlight, uicontextmenu, userdata, visible.
+	(class figure): Delete visible property.
+
+2008-01-13  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* grahpics.h.in: Sprinkle with OCTINTERP_API as needed.
+	(axes::properties::xaxislocation): Allow value of zero.
+	(axes::properties::yaxislocation): Likewise.
+
+2008-01-12  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* Makefile.in (distclean): Delete graphics-props.cc.
+
+	* genprops.awk: Handle new graphics property classes.
+
+	* graphics.h.in, graphics.cc: Adapt for new specific property types.
+
+2008-01-12  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_config_info): Add GNUPLOT to the struct.
+	* oct-conf.h.in (OCTAVE_CONF_GNUPLOT): New macro.
+
+2008-01-11  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Undo part of change from
+	2007-09-04 (compute Y at each iteration).
+
+2008-01-10  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Doc fix.
+	(hybrd_info_to_fsolve_info): Swap return values for -1 and -2 inputs.
+
+	* DLD_FUNCTIONS/__gnuplot_raw__.l: Delete.
+	* Makefile.in (DLD_XSRC): Remove it from the list.
+	(BUILT_DISTFILES): Remove __gnuplot_raw__.cc from the list.
+	(stamp-prereq): Don't depend on __gnuplot_raw__.cc.
+	(maintainer-clean): Don't remove __gnuplot_raw__.cc.
+	(__gnuplot_raw__.cc): Delete target.
+	(__gnuplot_raw__.o, pic/__gnuplot_raw__.o): Delete targets.
+
+	* mex.cc (calc_single_subscript_internal): New static function.
+	(mxArray_octave_value::calc_single_subscript): Use it.
+	(mxArray_matlab::calc_single_subscript): Use it.
+
+2008-01-07  John W. Eaton  <jwe at octave.org>
+
+	* src/pt-except.cc (tree_try_catch_command::eval):
+	Set Vdebug_on_error and Vdebug_on_warning to false while executing
+	try block.
+
+	* error.cc (Vdebug_on_error, Vdebug_on_warning): No longer static.
+	* error.h: Provide decls.
+
+	* gripes.cc (gripe_wrong_type_arg (const std::string&, const
+	octave_value&, bool)): New function.
+	* gripes.h: Provide decl.
+
+	* oct-stream.cc (printf_value_cache::printf_value_cache):
+	Reject structs, cells, objects, and lists.
+	(octave_base_stream::do_printf): Quit early if printf_value_cache
+	constructor fails.
+
+	* parse.y (make_anon_fcn_handle): Don't attempt to convert
+	expression to assignment to __retval__.
+
+2008-01-07  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* ov-builtin.h (octave_builtin): Tag with OCTINTERP_API.
+	* ov-dld-fcn.h (octave_dld_function): Likewise.
+
+	* ov-dld-fcn.cc (octave_dld_function::create): New function.
+	* ov-dld-fcn.h: Provide decl.
+	* defun.h (DEFINE_FUNX_INSTALLER_FUN3): Call it instead of
+	creating a new octave_dld_function object directly.
+
+2008-01-04  John Swensen  <jpswensen at comcast.net>
+
+	* debug.cc (bp_table::do_remove_all_breakpoints_in_file):
+	Avoid calling erase on invalid bp_map iterators.
+	(bp_table::do_remove_breakpoint): Only try to delete breakpoints
+	if some exist.  Avoid calling erase on invalid bp_map iterators.
+	(parse_dbfunction_params): Return early if ARGS is empty.
+	New arg, WHO.  Change all uses.
+	Accept but do nothing with struct args.
+
+2008-01-04  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* variables.cc (Fclear): Doc fix.
+
+2008-01-04  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_table:pop_scope): Avoid accessing beyond end of
+	scope_stack.
+
+2008-01-04  David Bateman  <dbateman at free.fr>
+
+	* ov-mapper.cc (SPARSE_MAPPER_LOOP_2): Use data method instead of
+	elem in the case where F(0) is non-zero.
+
+2007-12-28  John W. Eaton  <jwe at octave.org>
+
+	Merge changes from object branch:
+
+	2007-12-12  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::dir_info::get_file_list,
+	load_path::move_method_map, load_path::remove_method_map,
+	load_path::do_find_fcn, load_path::do_find_private_fcn,
+	load_path::do_find_method, load_path::do_find_file,
+	load_path::do_find_first_of, load_path::do_find_all_first_of,
+	load_path::do_display, load_path::add_to_method_map, genpath,
+	execute_pkg_add_or_del): Use file_ops::concat.
+
+	2007-08-24  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (Fmislocked): return value for nargin == 0 case.
+
+	2007-07-27  John W. Eaton  <jwe at octave.org>
+
+	* pt-idx.cc (tree_index_expression::rvalue):
+	Pass substring of type to subsref when doing partial evaluation.
+	(tree_index_expression::lvalue): Likewise.
+
+	2007-06-29  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (is_built_in_class, set_class_relationship,
+	Fsuperiorto, Finferiorto): New functions.
+	(octave_class::in_class_method): New function.
+	(octave_class::subsref, octave_class:subsasgn): Use it.
+
+	2007-06-28  John W. Eaton  <jwe at octave.org>
+
+	* src/ov-class.cc (sanitize): New function.
+	(make_idx_args): Use it.
+
+	2007-06-28  John W. Eaton  <jwe at octave.org>
+
+	* src/ov-class.cc (octave_class::subsasgn): Expect and use only
+	one return value from feval of subsasgn method.
+
+	* ov.cc (octave_value::assign): Don't convert to struct if
+	indexing a class object with ".".
+
+	* pt-idx.cc (tree_index_expression::make_arg_struct):
+	Use Cell instead of octave_value_list for subscripts.
+
+	* ov-class.cc (make_idx_args): For "." index, subs field is
+	string, not cell.
+
+	2007-06-27  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii,
+	octave_fcn_handle::load_ascii, octave_fcn_handle::save_binary,
+	octave_fcn_handle::load_binary, octave_fcn_handle::save_hdf5,
+	octave_fcn_handle::load_hdf5): Adapt to new symbol table objects.
+
+	* symtab.h (symbol_table::all_variables,
+	symbol_table::do_all_variables): New arg, defined_only.
+
+	2007-06-26  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (read_mat5_binary_element): Adapt to new symbol table
+	objects.
+
+	* variables.cc (Vwhos_line_format): New static variable.
+	(Fwhos_line_format): New function.
+	(symbol_record_name_compare): Delete function.
+	(symbol_record_name_compare, whos_parameter): New structs.
+	(print_descriptor, dimensions_string_req_first_space,
+	dimensions_string_req_total_space, make_dimensions_string,
+	parse_whos_line_format, print_symbol_info_line): New static
+	functions, adapted from old symbol table class.
+	(do_who): Adapt to new symbol table objects.
+
+	* symtab.h (symbol_table::glob_variables): New functions.
+	(symbol_table::do_glob): New argument, vars_only.  Change all uses.
+
+	2007-06-22  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::help_for_dispatch):
+	New function.
+	* symtab.h: Provide decl.
+	(symbol_table::fcn_info::help_for_dispatch,
+	symbol_table::help_for_dispatch): New functions.
+
+	* help.cc (help_from_symbol_table): Call
+	symbol_table::help_for_dispatch instead of
+	extract_help_from_dispatch.
+
+	* help.cc (extract_help_from_dispatch): Delete.
+	* help.h: Delete decl.
+
+	2007-06-21  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/dispatch.cc (class octave_dispatch): Delete class.
+	(builtin, any_arg_is_magic_colon, dispatch_record): Delete functions.
+	(Fbuiltin, Fdispatch): Adapt to new symbol table objects.
+
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::print_dispatch):
+	New function.
+	* symtab.h: Provide decl.
+	(symbol_table::fcn_info::print_dispatch, symbol_table::print_dispatch):
+	New functions.
+
+	* symtab.h (symbol_table::fcn_info::fcn_info_rep::clear_dispatch,
+	symbol_table::fcn_info::clear_dispatch, symbol_table::clear_dispatch):
+	New functions.
+
+	* symtab.h (symbol_table::fcn_info::fcn_info_rep::get_dispatch,
+	symbol_table::fcn_info::get_dispatch, symbol_table::get_dispatch):
+	New functions.
+
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::find):
+	Use leftmost class argument as dispatch type, or first argument if
+	there are no class arguments.
+
+	2007-06-20  John W. Eaton  <jwe at octave.org>
+
+	* ov-base.cc (Vprint_answer_id_name, Fprint_answer_id_name): Delete.
+	(octave_base_value::print_with_name): Always print name.
+
+	* ov-base.cc (Vsilent_functions): No longer static.
+	* ov-base.h: Provide decl.
+
+	* ov-class.cc (Fmethods): Define as command.
+
+	* ov-class.cc (octave_class::print): Simply call print_raw.
+
+	* ov-class.cc (octave_class::print_with_name): New function.
+	* ov-class.h: Provide decl.
+
+	2007-06-19  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (octave_value::do_unary_op, octave_value::do_binary_op):
+	Handle class methods.
+
+	* ov.cc (octave_value::unary_op_fcn_name,
+	octave_value::binary_op_fcn_name): New functions.
+	* ov.h: Provide decls.
+
+	* ov-typeinfo.cc (octave_value_typeinfo::register_unary_class_op,
+	octave_value_typeinfo::register_binary_class_op,
+	octave_value_typeinfo::do_register_unary_class_op,
+	octave_value_typeinfo::do_register_binary_class_op,
+	octave_value_typeinfo::do_lookup_unary_class_op,
+	octave_value_typeinfo::do_lookup_binary_class_op): New functions.
+	* ov-typeinfo.h: Provide decls.
+	
+	* ov-typeinfo.h (octave_value_typeinfo::unary_class_op_fcn,
+	octave_value_typeinfo::binary_class_op_fcn): New typedefs.
+	(octave_value_typeinfo::unary_class_ops,
+	octave_value_typeinfo::binary_class_ops): New data members.
+	(octave_value_typeinfo::octave_value_typeinfo): Initialize them.
+	(octave_value_typeinfo::lookup_unary_class_op,
+	octave_value_typeinfo::lookup_binary_class_op): New functions.
+
+	* OPERATORS/op-class.cc: New file.
+	* Makefile.in (OP_XSRC): Add it to the list.
+
+	* ov.cc (install_types): Call octave_class::register_type here.
+
+	* ov-class.h (octave_class): Implement by containing a map object
+	instead of deriving from octave_struct.
+	* ov-class.cc (octave_class::subsref, octave_class::subsasgn):
+	Don't use octave_class implementation as default action.
+
+	* ov.h, ov.cc (octave_value::octave_value (const Octave_map&, const
+	std::string&)): New constructor.
+
+	2007-06-18  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (octave_class::subsref, octave_class::subsasgn):
+	Handle dispatch to user-defined methods.
+
+	* parse.y (load_fcn_from_file): New arg, dispatch_type.
+	Change all uses.
+
+	* ov-fcn.h (octave_function::is_class_constructor,
+	octave_function::is_class_method, octave_function::dispatch_class):
+	New virtual functions.
+
+	* ov-usr-fcn.h (octave_user_function::dispatch_class,
+	octave_usr_function::stash_dispatch_class): New functions.
+	(octave_usr_fucntion::xdispatch_class): New data member.
+	* parse.y (frob_function): Call stash_dispatch_class here.
+
+	* ov-struct.cc (Ffieldnames): Also handle objects.
+
+	* ov-class.cc (Fmethods): New function.
+	* load-path.cc (load_path::do_methods): New function.
+	* load-path.h (load_path::methods): New function.
+
+	* ov.h (octave_value::is_object): New function.
+	* ov-base.h (octave_base_value::is_object): New virtual function.
+	* ov-class.h (octave_class::is_object): New function.
+	* ov-class.cc (Fisobject): New function.
+
+	2007-06-15  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (octave_class::print): Call display method if found.
+
+	* symtab.h (symbol_table::fcn_info::find_method): New function.
+	(symbol_table::find_method): New function.
+	(symbol_table::fcn_info::fcn_info_rep::find_method): Provide decl.
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::find_method):
+	New function.
+	(symbol_table::fcn_info::fcn_info_rep::find): Use it.
+
+	2007-06-14  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_table::clear_mex_functions): Make it work.
+	(symbol_table::fcn_info::fcn_info_rep::clear_mex_function,
+	symbol_table::fcn_info::clear_mex_function): New functions.
+
+	2007-06-08  John W. Eaton  <jwe at octave.org>
+
+	* defun.cc (Falias): Delete.
+
+	* variables.cc (load_fcn_try_ctor): New function.
+	(lookup): call load_fcn_try_ctor instead of load_fcn_from_file.
+
+	* variables.cc, variables.h (at_top_level, lookup_by_name, lookup,
+	initialize_symbol_tables, fcn_out_of_date, symbol_out_of_date,
+	lookup_function, lookup_user_function, link_to_global_variable,
+	link_to_builtin_or_function, force_link_to_function, Fdocument,
+	is_local_variable, do_clear_all, do_clear_functions,
+	do_clear_globals, do_clear_variables, do_clear_function,
+	do_clear_global, do_clear_variable, do_clear_symbol,
+	do_clear_function_pattern, do_clear_global_pattern,
+	do_clear_variable_pattern, do_clear_symbol_pattern,
+	clear_function, clear_variable, clear_symbol):
+	Delete (some functionality moved to the new symtab.cc and some is
+	no longer needed).
+	(Fignore_function_time_stamp): Move to symtab.cc.
+
+	* lex.l (lookup_identifier): Delete.
+
+	* parse.y (is_function_file): New function.
+	(load_fcn_from_file): Return pointer to octave_function, not bool.
+
+	* ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_function::argn_sr,
+	octave_user_function::nargin_sr, octave_user_function::nargout_sr,
+	octave_user_function::varargin_sr): Delete data members.
+	(octave_user_function::install_automatic_vars): Delete.
+	(octave_user_script::do_multi_index_op): New function.
+
+	* ov-fcn.h (octave_function::locked, octave_function::my_dir_name):
+	New data members.
+	(octave_function::dir_name, octave_function::stash_dir_name,
+	octave_function::lock, octave_function::unlock,
+	octave_function::islocked): New functions.
+
+	* of-fcn-handle.h, ov-fcn-handle.cc (octave_fcn_handle::subsref):
+	Call out_of_date_check here to simplify time stamp checking.
+	(octave_fcn_handle::reload_warning): Delete.
+
+	* ov.h (octave_value::is_user_script, octave_value::is_user_function):
+	New functions.
+	* ov-base.h (octave_base_value::is_user_script,
+	octave_base_value::is_user_function): New pure virtual functions.
+	* ov-fcn.h (octave_function::is_user_script,
+	octave_function::is_user_function): Delete.
+
+	* load-save.cc (install_loaded_variable): Greatly simplify.
+
+	* load-path.h, load-path.cc: Change private_fcn_file to private_file.
+	(load_path::private_fcn_map): New data member.
+	(load_path::do_add, load_path::do_remove, load_path::do_update):
+	Also manage private_file_map here.
+	(load_path::add_to_private_fcn_map): New function.
+	(load_path::remove_private_fcn_map): New function.
+	(load_path::do_find_private_fcn): Make it work.
+	(get_file_list): New function.
+	(load_path::do_display): Use it.  Display private map.
+	(load_path::find_method, load_path::find_fcn): Handle directory name.
+
+	* token.cc, token.h, toplev.cc, debug.cc, defun.cc, defun-dld.h,
+	defun-int.h, error.cc, help.cc, load-save.h, load-save.cc, mex.cc,
+	octave.cc, ov-fcn-handle.cc, ov-usr-fcn.cc, parse.h, parse.y,
+	lex.l, variables.cc: Adapt to new symbol table objects (my
+	apologies for the lack of detail).
+
+	* unwind-prot.h (unwind_protect::add): Set default value for ptr arg.
+
+	* pt-stmt.cc (tree_statement::eval): Rework method for deciding
+	whether to assign value to ans.
+
+	* pt-idx.cc (tree_index_expression::rvalue):
+	Looking up symbol may evaluaate first args now.
+
+	* pt-id.h, pt-id.cc (tree_identifier::document,
+	tree_identifier::is_defined, tree_identifier::define,
+	tree_identifier::is_function, tree_identifier::lookup,
+	tree_identifier::link_to_global): Delete.
+	(tree_identifier::do_lookup): Simplify.
+	(tree_identifier::rvalue): Looking up symbol can't execute script now.
+
+	* pt-misc.cc (tree_parameter_list::initialize_undefined,
+	tree_parameter_list::is_defined): Call is_variable for elt, not
+	is_defined.
+
+	* pt-fcn-handle.h (tree_anon_fcn_handle::fcn): Now pointer to
+	octave_user_function, not value.  Change all uses.
+
+	* pt-decl.h (tree_decl_command::initialized): Delete data member.
+	(tree_decl_elt::is_variable): New function.
+	* pt-decl.cc: Fix all uses of tree_decl_command::initialized.
+
+	* ls-hdf5.cc, ls-mat-ascii.cc, ls-mat4.cc, ls-mat5.cc,
+	ls-oct-ascii.cc, ls-oct-binary.cc, input.cc: Don't include symtab.h.
+
+	* dynamic-ld.h, dynamic-ld.cc (octave_dynamic_loader::load_oct,
+	octave_dynamic_loader::load_mex, octave_dynamic_loader::do_load_oct,
+	octave_dynamic_loader::do_load_mex): Adapt to new symbol table
+	objects.  Return pointer octave_function instead of bool.
+
+	* DLD-FUNCTIONS/dispatch.cc (Fbuiltin): Disable for now.
+	Disable code that works with old symbol tables.
+	(Fbuiltin): Simply call symbol_table::add_dispatch.
+
+	* pt-arg-list.cc, pt-arg-list.h, pt-assign.cc, pt-assign.h,
+	pt-binop.cc, pt-binop.h, pt-bp.h, pt-cell.cc, pt-cell.h,
+	pt-cmd.cc, pt-cmd.h, pt-colon.cc, pt-colon.h, pt-const.cc,
+	pt-const.h, pt-decl.cc, pt-decl.h, pt-except.cc, pt-except.h,
+	pt-exp.h, pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h,
+	pt-idx.cc, pt-idx.h, pt-jump.cc, pt-jump.h, pt-loop.cc, pt-loop.h,
+	pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h, pt-select.cc,
+	pt-select.h, pt-stmt.cc, pt-stmt.h, pt-unop.cc, pt-unop.h:
+	Adapt dup functions to use scope instead of symbol_table objects.
+
+	* TEMPLATE-INST/Array-sym.cc: Delete.
+	* Makefile.in (TI_XSRC): Remove it from the list.
+
+	* symtab.h, symtab.cc: Replace with new versions.
+
+	2007-05-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-lvalue.cc, oct-lvalue.h (octave_lvalue::chg_fcn): Delete.
+	Fix all uses.
+
+	2007-05-15  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_find_private_function): New function.
+	* load-path.h (load_path::do_find_private_function): Provide decl.
+        (load_path::find_private_function): New function.
+
+	2007-05-08  John W. Eaton  <jwe at octave.org>
+
+	* pt-idx.cc (tree_index_expression::rvalue): Handle dispatch here.
+
+	* pt-id.cc (tree_identifier::is_variable, tree_identifier::lookup):
+	New functions.
+	* pt-id.cc: Provide decls.
+
+	* parse.y (current_class_name): New global variable.
+	* parse.h: Provide decl.
+
+	* parse.y (load_fcn_from_file, parse_fcn_file):
+	New arg, dispatch_type.
+	(parse_fcn_file): Protect current_class_name and set it to
+	dispatch_type before parsing function.
+	(load_fcn_from_file): If dispatch_type is not empty, call
+	load_path::find_method instead of load_path::find_fcn.
+	* parse.h: Fix decls for extern functions.
+
+	* lex.h (lexical_feedback::parsing_class_method): New data member.
+	* lex.l (lexical_feedback::init): Initialize it.
+	(lookup_identifier): Check it and set sym_name accordingly.
+
+	* ov-usr-fcn.h (octave_user_function::mark_as_class_constructor,
+	octave_user_function::is_class_constructor,
+	octave_user_function::mark_as_class_method,
+	octave_user_function::is_class_method): New functions.
+	(octave_user_function::class_constructor,
+	octave_user_function::class_method): New data members.
+	* ov-usr-fcn.cc (octave_user_function::octave_user_function):
+	Initialize them.
+
+	* load-path.h, load-path.cc: Use typedefs to simplify template decls.
+	Use fcn consistently instead of function.
+	
+	2007-05-03  John W. Eaton  <jwe at octave.org>
+
+	* ov-class.cc (Fclass): Move here.
+	* ov-typeinfo.cc: From here.
+
+	* input.cc (octave_gets): Call load_path::update if user input
+	contains something other than one of the characters " \t\n\r".
+
+	* ov-class.cc, ov-class.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* load-path.cc (genpath): Skip directories beginning with "@".
+	(load_path::dir_info::get_file_list):  Don't return anything.
+	Call get_private_function_map here.
+	(load_path::dir_info::initialize): Not here.
+	(load_path::dir_info_::get_method_file_map): New function.
+	(load_path::method_map): New data member.
+	(load_path::do_clear): Also clear method_map.
+	(load_path::do_add): Also call add_to_method_map.
+	(load_path::do_update): Also clear method_map and call
+	(load_path::do_find_method): New function.
+	(load_path::do_add_to_method_map): New function.
+	(load_path::move_fcn_map, load_path::move_method_map): New functions.
+	(load_path::move): Use them.
+	(load_path::remove_fcn_map, load_path::remove_method_map):
+	New functions.
+	(load_path::remove): Use them.
+	* load-path.h: Provide/fix decls.
+	(load_path::find_method): New static function.
+
+	* Makefile.in (%.df : %.cc): Use mv instead of
+	$(simple-move-if-change-rule).
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+	* version.h (OCTAVE_VERSION): Now 3.0.0.
+	(OCTAVE_API_VERSION): Now api-v32.
+	(OCTAVE_RELEASE_DATE): Now 2007-12-21.
+
+2007-12-19  Thomas Kasper  <ThomasKasper at gmx.net>
+
+	* OPERATORS/op-scm-cs.cc (DEFBINOP (pow)): Extract complex value
+	from second arg.
+
+2007-12-12  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sparse.cc (Fsparse): Check for scalar arguments
+	for 2 argument version.
+
+2007-12-12  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (class axes) Add the layer property.
+	* graphics.cc (class axes) Ditto.
+
+	* graphics.cc (gh_manager::get_handle): Use ceil instead of trunc.
+
+2007-12-11  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.19+.
+
+2007-12-11  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.19.
+	(OCTAVE_API_VERSION): Now api-v31.
+	(OCTAVE_RELEASE_DATE): Now 2007-12-11.
+
+	* graphics.cc (make_graphics_object):
+	If successful, call __request_drawnow__.
+
+	* input.cc (Vgud_mode): New static variable.
+	(F__gud_mode__): New function.
+	(get_user_input): If debug and Vgud_mode, print location info in
+	format for Emacs GUD mode.
+
+2007-12-11  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-bm-sbm.cc, OPERATORS/op-b-sbm.cc, 
+	OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc, 
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc, 
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc, 
+	OPERATORS/op-s-scm.cc, OPERATORS/op-s-sm.cc: Privilege 
+	conversion to dense matrices for compatibility.
+
+	* DLD-FUNCTIONS/sparse.cc (FSparse): Remove the mutate flag, as
+	default bahavior is now to keep matrix sparse always.
+	
+	* graphics.cc (axes::properties::properties):
+	Initialize xcolor, ycolor, and zcolor to (0, 0, 0).
+
+	* graphics.h.in (gh_manager::next_handle): Now double.
+	* graphics.cc (gh_manager::get_handle, gh_manager::gh_manager):
+	Set fractional part of next_handle to a random value.
+
+2007-12-10  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.cc (octave_cell::all_strings): Handle empty elements.
+	Handle N-d cell arrays.
+
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve):
+	For compatibility, return [x, fval, info] instead of [x, info, msg].
+ 	Move tests here from test/test_nonlin.m.
+
+	* OPERATORS/op-cm-s.cc: Define function for el_mul with
+	DEFNDBINOP_OP, not DEFBINOP_OP.
+
+	* OPERATORS/op-s-cm.cc: Define functions for el_and and el_or
+	operators with DEFNDBINOP_FN.
+
+	* oct-hist.cc (default_history_file): Use file_ops::concat.
+	* load-path.cc (dir_info::initialize, dir_info::get_file_list,
+	load_path::do_find_fcn, load_path::do_find_file, genpath,
+	execute_pkg_add_or_del, load_path::do_find_first_of,
+	load_path::do_find_all_first_of): Likewise.
+
+	* help.cc (Flookfor): Avoid doubling directory separator.
+	* dirfns.cc (Fmkdir): Likewise.
+
+	* pt-mat.cc (tree_matrix::rvalue): Produce sq_string if any
+	strings are sq_string objects.
+
+2007-12-10  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (data_property::data): Declare as NDArray instead
+	of Matrix.  Change all uses.
+
+2007-12-10  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h.in (class figure) Add the color property.
+	* graphics.cc (class figure) Ditto.
+
+2007-12-07  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Fnorm): Don't return a scalar stored as a sparse
+	matrix. Convert it to a scalar.
+
+	* graphics.cc (check_limit_val): Delete.
+	(check_limit_vals): Simplify and no longer use check_limit_val.
+
+2007-12-05  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.18+.
+
+2007-12-05  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.18.
+	(OCTAVE_API_VERSION): Now api-v30.
+	(OCTAVE_RELEASE_DATE): Now 2007-12-05.
+
+2007-12-04  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (INCLUDES): Add builtins.h to the list.
+
+	* src/oct-hist.cc (default_history_file): Use += instead of
+	push_back to append character to std::string object.
+
+	* Makefile.in (LIBDLFCN): Delete all uses.
+
+	* toplev.cc (octave_config_info): Remove LIBDLFCN and
+	DLFCN_INCFLAGS from the list.
+	* oct-conf.h.in (OCTAVE_CONF_DLFCN_INCFLAGS, OCTAVE_CONF_LIBDLFCN):
+	Delete. 
+
+	* error.cc (Ferror): Handle error id.
+
+	* load-save.cc (Fsave, Fload): Doc fixes.
+	From Marco Caliari <caliari at sci.univr.it>.
+
+2007-12-04  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h.in (base_properties::get_type
+        base_properties::get___modified__,
+	base_properties::get___myhandle__): New functions.
+
+2007-12-04  Christoph Mayer  <Christoph.Mayer at dlr.de>.
+
+	* toplev.h (clean_up_and_exit, recover_from_exception,
+	do_octave_atexit, global_command, curr_parent_function):
+	Tag with OCTINTERP_API. 
+
+2007-12-03  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/luinc.cc: Make tests conditional on HAVE_UMFPACK.
+	* DLD-FUNCTIONS/spqr.cc: Make tests conditional on HAVE_CXSPARSE.
+
+	* DLD-FUNCTIONS/regexp.cc: Use "%!testif" blocks for conditional
+	tests on PCRE.
+
+	* graphics.cc (class axes): Add color and activepositionproperty
+	properties to axis objects.
+	* graphics.h.in (class axes): ditto.
+
+	* DLD-FUNCTIONS/regexp.cc: Also include sys/types.h for regexp.
+
+2007-11-30  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/sort.cc (operator < (const Complex&, const Complex&),
+	operator > (const Complex&, const Complex&)):
+	Pass args by const reference, not value.
+
+	* src/data.cc, src/matherr.c, src/pr-output.cc, src/sysdep.cc,
+	src/DLD-FUNCTIONS/__dsearchn__.cc, src/DLD-FUNCTIONS/minmax.cc,
+	src/DLD-FUNCTIONS/qz.cc, src/DLD-FUNCTIONS/sort.cc,
+	src/DLD-FUNCTIONS/tsearch.cc: Include lo-math.h instead of cmath
+	or math.h.
+
+2007-11-30  Moritz Borgmann  <octave at moriborg.de>
+
+	* ls-mat5.h (mat5_data_type): Delete trailing comma in enum decl.
+	* oct-stream.cc (octave_base_stream::do_printf): Use
+	OCTAVE_EMPTY_CPP_ARG to avoid annoying Sun compiler warning.
+	* OPERATORS/op-sbm-sbm.cc (DEFDBLCONVFN): Delete useless macro
+	invocation.
+
+	* DLD-FUNCTIONS/typecast.cc (typecast): No longer static.
+
+2007-11-30  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (updating_axis_limits): New static variable.
+	(check_limit_val, check_limit_vals, get_axis_limits): New functions.
+	(axes::update_axis_limits): Make it work.
+	* graphics.h.in (base_properties::get_children): New function.
+	(base_properties::get_xdata, base_properties::get_ydata,
+	base_properties::get_zdata, base_properties::get_ldata,
+	base_properties::get_udata, base_properties::get_xldata,
+	base_properties::get_xudata, base_properties::get_cdata,
+	base_properties::get_properties (void) const):
+	New virtual functions.
+	(graphics_object::get_xdata, graphics_object::get_ydata,
+	graphics_object::get_zdata, graphics_object::get_ldata,
+	graphics_object::get_udata, graphics_object::get_xldata,
+	graphics_object::get_xudata, graphics_object::get_cdata,
+	graphics_object::get_properties (void) const,
+	root_figure::get_properties (void) const,
+	figure::get_properties (void) const,
+	axes::get_properties (void) const,
+	line::get_properties (void) const,
+	text::get_properties (void) const,
+	image::get_properties (void) const,
+	patch::get_properties (void) const,
+	surface::get_properties (void) const)): New functions.
+	(radio_property::radio_property (const radio_values&)):
+	Provide	default value for argument. 
+	(radio_property::radio_property (const radio_values&, const
+	std::string&)): Delete.
+	(axes::xlimmode, axes::ylimmode, axes::zlimmode, axes::climmode,
+	axes::xscale, axes::yscale, axes::zscale): Declare as
+	radio_property instead of octave_value values.  Adjust all uses.
+
+2007-11-29  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (octave_print_internal_template (std::ostream&,
+	const octave_int<T>&, bool)): Rename from octave_print_internal.
+	(PRINT_INT_SCALAR_INTERNAL): New macro.  Use it to define
+	non-template functions for printing scalar octave_int values.
+	(octave_print_internal_template (std::ostream&, const intNDArray<T>&,
+	bool, int)): Rename from octave_print_internal.
+	(PRINT_INT_ARRAY_INTERNAL): New macro.  Use it to define
+	non-template functions for printing scalar octave_int values.
+	* pr-output.h: Declare non-template functions for printing
+	octave_int scalar and array values.
+	Delete declarations of template funtions for printing octave_int
+	scalar and array values.
+
+2007-11-28  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (base_properties::update_axis_limits,
+	axes::update_axis_limits): New functions.
+	* graphics.h.in (class data_property): New class.
+	(graphics_object::update_axis_limits): New function.
+	(base_graphics_object::update_axis_limits): New virtual function.
+	(base_properties::update_axis_limits, axes::update_axis_limits):
+	Provide decls.
+	(class line, class image, class patch, class surface): Use it
+	instead of octave_value for data properties.  Tag data properties
+	with "l" modifier.
+	(class axes): Tag scale properties with "l" modifier.
+	* genprops.awk: Handle "l" modifier.
+
+	* mkbuiltins: Emit #include "builtins.h" for the builtins.cc file.
+	From Christoph Mayer <Christoph.Mayer at dlr.de>.
+
+	* TEMPLATE-INST/Array-tc.cc (resize_fill_value<octave_value>):
+	Delete.
+
+	* Cell.cc (Cell::Cell (const dim_vector&, const string_vector&, bool)):
+	Initialize undefined values to resize_fill_value ().
+
+2007-11-27  John W. Eaton  <jwe at octave.org>
+
+	* TEMPLATE-INST/Array-tc.cc (resize_fill_value<octave_value>):
+	Tag inline.  From Moritz Borgmann <octave at moriborg.de>.
+
+	* pt-bp.cc (tree_breakpoint::visit_decl_command): Also check line
+	number of cmd.
+	* pt-decl.cc (tree_global_command::eval, tree_static_command::eval):
+	Insert MAYBE_DO_BREAKPOINT here.
+
+	* error.cc (Fwarning): If setting state "all" to "error", leave
+	Octave:matlab-incompatible and Octave:single-quote-string warning
+	states unchanged.
+	(warning_enabled): Allow individual warning states to override
+	"warning error all".
+
+	* octave.cc (execute_eval_option_code, execute_command_line_file):
+	Handle interrupts.
+	* toplev.cc (recover_from_exception): Now extern.
+	* toplev.h (recover_from_exception): Provide decl.
+
+	* pt-idx.cc (tree_index_expression::lvalue): Treat object == []
+	the same as undefined.
+
+2007-11-26  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (DO_DOUBLE_CONV): Always use long.
+
+	* oct-stream.cc (do_write): Call float_value and double_value on
+	octave_int<T> objects instead of relying on conversion operators.
+
+	* ls-mat5.cc (read_mat5_binary_element, OCTAVE_MAT5_INTEGER_READ): 
+	Call double_value on octave_int<T> objects
+	instead of relying on conversion operator.
+	(read_mat5_binary_file_header): 
+	Call char_value on octave_int<T> objects
+	instead of relying on conversion operator.
+	(read_mat5_binary_element): 
+	Call bool_value on octave_int<T> objects
+	instead of relying on conversion operator.
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::double_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::scalar_value,
+	OCTAVE_VALUE_INT_MATRIX_T::matrix_value,
+	OCTAVE_VALUE_INT_MATRIX_T::complex_matrix_value,
+	OCTAVE_VALUE_INT_MATRIX_T::array_value,
+	OCTAVE_VALUE_INT_MATRIX_T::complex_array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::double_value, 
+	OCTAVE_VALUE_INT_SCALAR_T::scalar_value,
+	OCTAVE_VALUE_INT_SCALAR_T::matrix_value,
+	OCTAVE_VALUE_INT_SCALAR_T::complex_matrix_value,
+	OCTAVE_VALUE_INT_SCALAR_T::array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::complex_array_value,
+	Call double_value on octave_int<T> objects
+	instead of relying on conversion operator.
+	(OCTAVE_VALUE_INT_MATRIX_T::bool_array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::bool_array_value):
+	Call bool_value on octave_int<T> objects
+	instead of relying on conversion operator.
+	(OCTAVE_VALUE_INT_MATRIX_T::char_array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::char_array_value):
+	Call char_value on octave_int<T> objects
+	instead of relying on conversion operator.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* Sparse-op-defs.h (SPARSE_BASE_REDUCTION_OP): Check that the fill
+	value is not zero before creating the matrices.
+
+	* graphics.cc (class axes): Add the {x|y|z}color color property.
+	* graphics.h.in (class axes): ditto.
+
+	* ov-base.cc (Vsparse_auto_mutate, Fsparse_auto_mutate): New
+	internal variable and built-in function to set it.
+	* ov-base.h (extern bool Vsparse_auto_mutate): Export internal
+	variable to other functions.
+	* ov-re-sparse.cc (octave_sparse_matrix::try_narrowing_conversion
+	(void)), ov-cx-sparse.cc 
+	(octave_sparse_complex_matrix::try_narrowing_conversion (void)), 
+	ov-bool-sparse.cc
+	(octave_sparse_bool_matrix::try_narrowing_conversion (void)):
+	Use Vsparse_auto_mutate flag to determine whether to convert
+	sparse matrices to full matrices if that saves space.
+
+	* DLD-FUNCTIONS/minmax.cc (MINMAX_DOUBLE_BODY): New version of
+	MINMAX_BODY macro without the initialization.
+	(MINMAX_INT_BODY): Macro for min/max for the integer types
+	(MINMAX_BODY): New macro that calls the appropriate instantiation
+	of the other two macros.
+
+	* graphics.cc (class axes): Add __colorbar__ property.
+	* graphics.h.in (class axes): ditto.
+
+	* data.cc (Fnorm): Document the "inf" string argument for matrice
+	and vectors and the "fro" argument for vectors.
+
+	* graphics.h.in (class figure): Add __enhanced__ property to cache
+	whether the terminal supports enhanced mode. Add interpreter
+	property to all text classes, to determine the renderer for the
+	text.
+	* graphics.cc (class figure): ditto.
+
+2007-11-26  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.cc (string_properties): delete class 
+	(property_name): rename class to caseless_str. 
+	(radio_values::possible_vals): change type to caseless_str.
+
+2007-11-26  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* builtins.h (install_builtins): Tag with OCTINTERP_API.
+	* toplev.h (octave_interpreter_ready, octave_initialized): Likewise.
+
+2007-11-14  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mex::foreign_memlist): New data member.
+	(mex::mark_foreign, mex::unmark_foreign): New functions.
+	(mex::free): Don't warn about pointers found in foreign_memlist.
+	(maybe_mark_foreign): New function.
+	(mxArray_octave_value::get_data, mxArray_octave_value::get_ir,
+	mxArray_octave_value::get_jc):
+	Call maybe_mark_foreign on returned pointer.
+
+2007-11-14  David Bateman  <dbateman at free.fr>
+
+	* mex.cc (mxArray_sparse::mxArray_sparse (const mxArray_sparse&)):
+	Also ensure that pr and pi are correctly copied.
+
+2007-11-14  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (@bsd_gcc_kluge_targets_frag@): Delete line for
+	Makefrag.bsd substitution.
+
+	* graphics.h.in (base_properties::tag): New property.
+	(base_properties::get_tag, base_properties::set_tag): New functions.
+	(root_figure::set, root_figure::get, figure::set, figure::get,
+	axes::set, axes::get, line::set, line::get, text::set, text::get,
+	patch::set, patch::get, surface::set, surface::get): Handle tag.
+	
+2007-11-14  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* DLD-FUNCTIONS/regexp.cc: Undo previous change.
+
+2007-11-14  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mex::mark, mex::unmark): Now public.
+	(mex::persistent): Delete.
+	(mexMakeArrayPersistent): Call maybe_unmark_array instead of
+	mex::persistent.
+	(mexMakeMemoryPersistent): Call maybe_unmark instead of
+	mex::persistent.
+	(maybe_unmark (void *)): New function.
+	(mxSetDimensions, mxSetPr, mxSetPi, mxSetData, mxSetImagData,
+	mxSetIr, mxSetJc): Use it.  From David Bateman.
+
+2007-11-13  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* DLD-FUNCTIONS/rand.cc (Frand): Update URL reference in doc string.
+
+2007-11-12  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in, graphics.cc (class text): Add the fontangle and
+	fontweight properties. Add string_property class to handle the
+	string radio values.
+
+2007-11-12  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.17+.
+
+2007-11-12  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in, graphics.cc (class text): Add the fontname and
+	fontsize properties. 
+
+2007-11-10  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.17.
+	(OCTAVE_API_VERSION): Now api-v29.
+	(OCTAVE_RELEASE_DATE): Now 2007-11-10.
+
+2007-11-09  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l: Don't add atexit ("closeplot")
+	to PKG_ADD file.
+
+2007-11-09  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc, graphics.h.in (class patch): Add the field "keylabel".
+
+	* data.cc (Fcputime) [__WIN32__]: Correct scaling of sys and usr times.
+
+	* graphics.cc (is_handle): Handle must be a real scalar.
+
+2007-11-09  Joseph P. Skudlarek  <Jskud at Jskud.com>
+
+	* data.cc (Fislogical): Fix typo in documentation entry.
+
+2007-11-08  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (F__gnuplot_save_data__):
+	Note obsolescence in doc string.
+	(WARN_OBSOLETE): New macro
+	(F__gnuplot_save_data__, Fgnuplot_command_plot,
+	Fgnuplot_command_replot, Fgnuplot_command_splot,
+	Fgnuplot_command_using, Fgnuplot_command_with,
+	Fgnuplot_command_axes, Fgnuplot_command_title,
+	Fgnuplot_command_end, Fgnuplot_use_title_option,
+	F__clear_plot_window__, Fcloseplot, Fpurge_tmp_files,
+	F__gnuplot_raw__, F__gnuplot_send_inline_data__, F__gnuplot_set__,
+	F__gnuplot_show__, F__gnuplot_plot__, F__gnuplot_splot__,
+	F__gnuplot_replot__): Use WARN_OBSOLETE.
+
+2007-11-07  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/regexp.cc: Handle HAVE_PCRE_PCRE_H.  Check
+	HAVE_PCRE_H instead of HAVE_PCRE to decide whether to include pcre.h.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (Fgnuplot_command_plot,
+	Fgnuplot_command_replot, Fgnuplot_command_splot,
+	Fgnuplot_command_using, Fgnuplot_command_with,
+	Fgnuplot_command_axes, Fgnuplot_command_title,
+	Fgnuplot_command_end, Fgnuplot_use_title_option,
+	F__clear_plot_window__, Fcloseplot, Fpurge_tmp_files,
+	F__gnuplot_raw__, F__gnuplot_send_inline_data__, F__gnuplot_set__,
+	F__gnuplot_show__, F__gnuplot_plot__, F__gnuplot_splot__,
+	F__gnuplot_replot__): Note obsolescence in doc string.
+
+2007-11-06  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.h.in (class surface::properties): New properties, 
+	cdata, facecolor, facealpha, edgecolor, linestyle,
+	linewidth, marker, markeredgecolor, markerfacecolor, markersize.
+	* graphics.cc (surface::properties::properties,
+	surface::properties::set, surface::properties::get,
+	surface::properties::factory_defaults): Handle new properities.
+
+2007-11-06  David Bateman  <dbateman at free.fr>
+
+	* data.cc (DATA_REDUCTION): Handle the 'native' and 'double'
+	arguments of the Fsum function.
+	* OPERATORS/op-bm-bm.cc (matrix_to_bool_matrix,
+	scalar_to_bool_matrix): New type conversion functions.
+	(install_bm_bm_ops): Install new type conversions functions.
+
+2007-11-06  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* toplev.cc (Fsystem) [__WIN32__ && ! __CYGWIN__]:
+	Quote the complete command.
+
+2007-11-06  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fnorm): New tests.
+
+	* defun-int.h (DEFINE_FUNX_INSTALLER_FUN3): Don't install function
+	if check_version produces an error.
+
+2007-11-05  John W. Eaton  <jwe at octave.org>
+
+	* pt-idx.cc (tree_index_expression::lvalue): Try to do a better
+	job of computing the number of elements in lvalue expressions when
+	the last indexing element is ".".
+
+2007-11-02  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (fopen_mode_to_ios_mode): Use std::ios::app instead
+	of std::ios::ate.
+
+2007-11-02  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* input.cc, pr-output.cc, bitfcns.cc, DLD-FUNCTIONS/time.cc:
+        Fix broken @examples in help texts.
+
+2007-10-31  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fnorm): Avoid warning about p_val possibly being used
+	uninitialized.
+
+	* version.h (OCTAVE_VERSION): Now 2.9.16+.
+
+2007-10-31  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.16.
+	(OCTAVE_API_VERSION): Now api-v28.
+	(OCTAVE_RELEASE_DATE): Now 2007-10-31.
+
+2007-10-31  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* pt-assign.h (tree_simple_assignment::op_type,
+	tree_multi_assignment::op_type): New functions.
+	* pt-unop.h (tree_unary_expression::op_type): New function.
+
+2007-10-31  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (line::properties::get): Fix property name
+	(markerface -> markerfacecolor).
+
+	* Makefile.in (INCLUDES): Add debug.h to the list.
+
+2007-10-30  John Swensen  <jpswensen at comcast.net>
+
+	* debug.h: New file.
+	* debug.cc (parse_dbfunction_params, do_find_bkpt_list,
+	intmap_to_ov): New functions.
+	(Fdbstop, Fdbclear): Use parse_dbfunction_params.
+	Improve compatibility.
+	(Fdbstatus): Improve compatibility.
+
+	* help.cc (do_which): No longer static.
+	* help.h: Provide decl.
+
+2007-10-30  David Bateman  <dbateman at free.fr>
+
+	* symtab.cc: Doc fixes for small book format.
+
+2007-10-30  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (fopen_mode_to_ios_mode): Handle 'W' as 'w' and 'R'
+	as 'r', but warn about them.
+
+2007-10-29  Thomas Treichl  <Thomas.Treichl at gmx.net>
+
+	* data.cc: Include sytime.h, sys/types.h, and sys/resource.h.
+
+2007-10-25  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (figure::properties::set_currentaxes): 
+	Allow currentfigure to be NaN.
+
+2007-10-25  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* DLD-FUNCTIONS/__contourc__.cc: Use unsigned int instead of uint.
+	(drawcn): Use 1 << k instead of pow (2, k).
+
+2007-10-25  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_record::TYPE): Delete trailing comma in enum decl.
+
+	* ov-base.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Use
+	OCTAVE_EMPTY_CPP_ARG to avoid annoying Sun compiler warning.
+
+	* Makefile.in (graphics.h): Use $(AWK) instead of awk.
+
+	* DLD-FUNCTIONS/time.cc (Ftime, Fmktime): Avoid unnecessary cast.
+
+	* data.cc (Ftic, Ftoc): Call double_value on octave_time objects
+	instead of relying on conversion operator.
+	* ov.cc (octave_value::octave_value (octave_time)): Likewise.
+
+	* variables.cc (symbol_out_of_date): Use explicit conversion to
+	time_t instead of relying on conversion operator.
+	* ov-fcn-handle.cc (octave_fcn_handle::subsref): Likewise.
+
+	* data.cc (tic_toc_timestamp): Rename from __tic_toc_timestamp__.
+	Change all uses.
+
+2007-10-24  David Bateman  <dbateman at free.fr>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::OCTAVE_VALUE_INT_MATRIX_T
+	(const ArrayN<OCTAVE_INT_T>&)): New constructor.
+	* ov.cc (octave_value::octave_value(const ArrayN<T>) with T being
+	octave_int8, octave_uint8, octave_int16, octave_uint16,
+	octave_int32, octave_uint32, octave_int64, octave_uint64): New
+	constructors.
+	* ov.h (octave_value::octave_value(const ArrayN<T>) with T being
+	octave_int8, octave_uint8, octave_int16, octave_uint16,
+	octave_int32, octave_uint32, octave_int64, octave_uint64):
+	Declare them.
+	* DLD-FUNCTIONS/sort.cc (template class octave_sort<T>,
+	template class vec_index<T>, template class
+	octave_sort<vec_index<T> *>,  with T being
+	octave_int8, octave_uint8, octave_int16, octave_uint16,
+	octave_int32, octave_uint32, octave_int64, octave_uint64): New
+	instantiations of sort template classes.
+	(Fsort): Use them.
+
+2007-10-24  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (root_figure::properties::set_currentfigure):
+	Allow currentfigure to be NaN.
+
+	* pt-idx.cc (tree_index_expression::lvalue): Correctly compute
+	number of elements in lvalue expression when last indexing
+	element is ".".
+
+2007-10-23  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (is_handle (const graphics_handle&)): New function.
+	(gh_manager::do_free, reparent, base_properties::set_parent,
+	properties::get_title, properties::get_xlabel,
+	properties::get_ylabel, properties::get_zlabel,
+	properties::remove_child, make_graphics_object, F__go_figure__,
+	F__go_delete__, __go_axes_init__): Call OK on graphics handle
+	object instead of relying on implicit conversion operator.
+	* graphics.h.in (graphics_handle::operator double ()): Delete.
+	(graphics_handle::operator bool ()): Delete.
+	(gh_manager::do_handle_list, gh_manager::do_figure_handle_list,
+	base_properties::adopt): Call VALUE on graphics handle object
+	instead of relying on implicit conversion operator.
+
+	* ov-base.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Call
+	DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2 with "( )" as arg list
+	instead of "()".
+
+	* mxarray.h.in (mxClassID): Delete trailing comma in enum decl.
+
+	* symtab.h (symbol_table::symbol_table): Reduce default table size
+	to 64.
+
+2007-10-22  Kim Hansen  <kimhanse at gmail.com>
+
+	* unwind-prot.cc: Include <cstring>.
+
+2007-10-22  David Bateman  <dbateman at free.fr>
+
+        * data.cc (Ftic, Ftoc, Fcputime): New builtin versions of the
+        benchmarking functions for speed.
+	* oct-map.cc (Octave_map::squeeze, Octave_map::permute): New methods.
+	(Octave_map::index (const octave_value_list&, bool)): Add resize_ok
+	argument, define as const and use const_iterator internally.
+	(Octave_map::index (idx_vector&, ...), Octave_map::index (Array 
+	<idx_vector>&, ...)): New forms of the index function.
+	* oct-map.h (squeeze, permute, indx (const octave_value_list&, bool),
+	index (idx_vector&, ...), index (Array <idx_vector>&, ...)): Add
+	or update declaration.
+	* ov-struct.cc (octave_struct::do_index_op (const octave_value_list&,
+	bool)): New method.
+	* ov-struct.h (do_index_op (const octave_value_list&, bool)): Declare
+	it.
+	(squeeze (void), permute (const Arra<int>&, bool): New methods.
+
+2007-10-19  Kai Habel  <kai.habel at gmx.de>
+
+	* DLD-FUNCTIONS/__contourc__.cc (add_point): Rename from
+	cl_add_point.  Change all uses.
+	(end_contour): Rename from cl_end_contour.  Change all uses.
+	(start_contour): Rename from cl_start_contour.  Change all uses.
+	(drawcn): Rename from cl_drawcn.  New algorithm for locating contours.
+	(mark_facets): New function.
+	(cntr): Rename from cl_cntr.  Change all uses.  New algorithm for
+	locating contours.
+
+2007-10-19  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.cc (octave_cell::subsasgn): If RHS is cs-list, don't
+	fail if shape of LHS is different.
+	* ov-struct.cc (octave_struct::subsasgn): Likewise.
+
+2007-10-19  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* help.cc (Flookfor): Call print_usage instead of usage.
+	* DLD-FUNCTIONS/cellfun.cc (Fmat2cell): Likewise.
+
+2007-10-17  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/spchol.cc (Fsymbfact): Delete special code for METIS.
+
+2007-10-17  Gabriele Pannocchia  <g.pannocchia at ing.unipi.it>
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Fix check for Wact(j).
+
+2007-10-15  Søren Hauberg  <hauberg at gmail.com>
+
+	* error.cc (Ferror): Make text fit on pages when using smallbook.
+	* load-save.cc (Fsave_header_format_string): Ditto.
+        * ov-struct.cc (Fcell2struct): Ditto.
+        * DLD-FUNCTIONS/besselj.cc (Fairy): Ditto.
+        * DLD-FUNCTIONS/urlwrite.cc (Furlwrite, Furlread): Ditto.
+
+2007-10-15  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (axes::properties::get): Fix typo.
+
+2007-10-13  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.15+.
+
+2007-10-13  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.15.
+	(OCTAVE_API_VERSION): Now api-v27.
+	(OCTAVE_RELEASE_DATE): Now 2007-10-13.
+
+2007-10-13  David Bateman  <dbateman at free.fr>
+
+	* graphics.h.in (class patch): Add the faces and vertices properties.
+	* graphics.cc (patch::properties::properties): Initialize faces
+	and vertices.
+	(patch::properties::get): Also fetch faces and vertices.
+	(patch::properties::factory_defaults): Set faces and vertices.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+2007-10-11  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/urlwrite.cc (urlget): Disable use of EPSV mode.
+
+2007-10-11  Brian Gough  <bjg at network-theory.co.uk>
+
+	* DLD-FUNCTIONS/fftn.cc, DLD-FUNCTIONS/regexp.cc, dirfns.cc,
+	input.cc: Spelling fixes.
+
+2007-10-10  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-sbm-sbm.cc (bool_matrix_to_double_matrix):
+	New conversion function.
+	(install_sbm_sbm_ops): Install it.
+
+	* ov-re-mat.cc (double): Handle sparse as a special case.
+
+2007-10-10  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* data.cc, debug.cc, dirfns.cc, error.cc, file-io.cc, help.cc,
+	load-save.cc, ov-fcn-inline.cc, parse.y, pr-output.cc, symtab.cc,
+	syscalls.cc, toplev.cc, variables.cc, DLD-FUNCTIONS/bsxfun.cc,
+	DLD-FUNCTIONS/cellfun.cc, DLD-FUNCTIONS/fft.cc,
+	DLD-FUNCTIONS/fft2.cc, DLD-FUNCTIONS/fftw.cc,
+	DLD-FUNCTIONS/gcd.cc, DLD-FUNCTIONS/lsode.cc,
+	DLD-FUNCTIONS/luinc.cc, DLD-FUNCTIONS/matrix_type.cc,
+	DLD-FUNCTIONS/rand.cc, DLD-FUNCTIONS/regexp.cc,
+	DLD-FUNCTIONS/sparse.cc, DLD-FUNCTIONS/spchol.cc,
+	DLD-FUNCTIONS/splu.cc, DLD-FUNCTIONS/spparms.cc: Spelling fixes.
+
+2007-10-10  Kim Hansen  <kimhanse at gmail.com>
+
+	* DLD-FUNCTIONS/lpsolve.cc: Delete.
+	* Makefile.in (DLD_XSRC): Remove it from the list.
+
+        * data.cc (Fsqueeze): Document 2d behaviour.
+        * ov-range.h (octave_range::squeeze): New function.
+
+2007-10-09  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/urlwrite.cc (urlget_cleanup): New function.
+	(urlget): Protect call to curl_easy_perform with
+	BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE and
+	END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE.
+
+2007-10-09  David Bateman  <dbateman at free.fr>
+
+	* input.cc (accept_line): Drop this function and remove automatic
+	insertion of closing quotes as the transpose operator confuses it.
+	(initialize_command_input): Remove accept_line from here as well.
+	
+2007-10-09  John W. Eaton  <jwe at octave.org>
+
+	* ov-mapper.cc (octave_mapper::apply): If possible, use
+	d_d_map_fcn to handle complex values which have imag(z) == 0.
+
+	* DLD-FUNCTIONS/urlwrite.cc (Furlwrite, Furlread) [! HAVE_CURL]:
+	Throw error instead of returning empty string hiding error message
+	in third return value.
+	(progress_func): Delete.
+	(Furlread): Don't set progress callback for curl.
+	(write_data, form_query_string, urlget): Now static.
+
+2007-10-08  David Bateman  <dbateman at free.fr>
+
+	*  input.cc (quoting_filename): Function to add a leading quote to
+	a string if needed.
+	(accept_line): Function to check if a string needs a closing quote
+	before calling the rl_newline function.
+	(initialize_command_input): Initialize completer_quote_characters,
+	filename_quote_characters, quoting_function,
+	user_accept_line_function.
+
+	* data.cc (template <class T> static make_diag (...)): New
+	template class version of make_diag. Make other make_diag
+	functions depend on it.
+	( static octave_value make_diag (const octave_value&, 
+	octave_idx_type)): Treat all possible internal Octave types.
+
+2007-10-08  John W. Eaton  <jwe at octave.org>
+
+	* load-save.cc 	(save_vars, dump_octave_core):
+	Don't pass INFNAN_WARNED to do_save.
+	(do_save): Delete unused arg, INFNAN_WARNED.
+	Don't pass INFNAN_WARNED to save_ascii_data.
+	* ls-oct-ascii.cc (save_ascii_data_for_plotting):
+	Don't pass INFNAN_WARNED to save_ascii.
+	(save_ascii_data): Delete unused arg, INFNAN_WARNED.
+
+	* ov.h (octave_value::save_ascii): Delete unused arg, INFNAN_WARNED.
+	* ov-base-int.cc (octave_base_int_matrix<T>::save_ascii,
+	octave_base_int_scalar<T>::save_ascii): Likewise.
+	* ov-base-sparse.cc (octave_base_sparse<T>::save_ascii): Likewise.
+	* ov-base.cc (octave_base_value::save_ascii): Likewise.
+	* ov-bool-mat.cc (octave_bool_matrix::save_ascii): Likewise.
+	* ov-bool.cc (octave_bool::save_ascii): Likewise.
+	* ov-cell.cc (octave_cell::save_ascii): Likewise.
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii): Likewise.
+	* ov-fcn-inline.cc (octave_fcn_inline::save_ascii): Likewise.
+	* ov-list.cc (octave_list::save_ascii): Likewise.
+	* ov-struct.cc (octave_struct::save_ascii): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::save_ascii): Likewise.
+	* ov-range.cc (octave_range::save_ascii): Likewise.
+
+	* ov-scalar.cc (octave_scalar::save_ascii): Remove warning about
+	reloading inf/nan values.  Delete unused arg, INFNAN_WARNED.
+	* ov-complex.cc (octave_complex::save_ascii): Likewise.
+	* ov-re-mat.cc (octave_matrix::save_ascii): Likewise.
+	* ov-cx-mat.cc (octave_complex_matrix::save_ascii): Likewise.
+
+	* ov-fcn-inline.cc (Finline): Use DEFUNX instead of DEFUN.
+
+2007-10-08  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* sighandlers.h (can_interrupt): Tag with OCTINERP_API.
+	* sysdep.h (raw_mode, octave_popen, octave_pclose,
+	same_file_internal): Likewise.
+
+2007-10-06  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_base_stream::do_scanf):
+	Always allow MVAL to re resized if NR > 0.
+	(FINISH_CHARACTER_CONVERSION): Likewise.
+
+	* mappers.cc (install_mapper_functions): Undo previous change.
+	Fix doc string for lgamma.
+	(xzlgamma): Delete.
+
+2007-10-05  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h.in (axes::properties): New property, colororder.
+	* graphics.cc (default_colororder): New function.
+	(axes::properties::properties, axes::properties::get,
+	axes::properties::set_defaults,
+	axes::properties::factory_defaults, ): Handle colororder.
+
+	* mappers.cc (xzlgamma): New static function.
+	(install_mapper_functions): Pass xzlgamma for c_c_map for lgamma
+	mapper.  Pass 1 for can_ret_cmplx_for_real and set hi to
+	octave_Inf.
+
+2007-10-04  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/symrcm.cc: Move static functions to top of file to
+	avoid forward decls.
+	(Q_enq): Delete unused arg QH.  Change all uses.
+	(Q_deq): Delete unused arg QT.  Change all uses.
+	(find_starting_node): Delete unused local variable J.
+	(H_heapify_min, H_insert, find_starting_node, Fsymrcm):
+	Move local variable decls to point of first use.
+
+	* OPERATORS/op-streamoff.cc (STREAMOFF_COMP_OP):
+	Avoid control-reaches-end-of-non-void-function warning.
+
+	* pt-const.cc (tree_constant::dup): Avoid unused parameter warning.
+
+	* pr-output.cc (set_real_format, set_real_matrix_format,
+	set_complex_format, set_complex_matrix_format):
+	Delete unused arg, SIGN.  Change uses.
+
+	* oct-map.cc (Octave_map::Octave_map): Avoid shadow warning.
+
+	* load-save.cc (write_header): Use reinterpret_cast to avoid
+	old-style cast warning.
+
+	* data.cc (do_permute): Delete unused arg, FNAME.  Change all uses.
+
+	* sysdep.cc (w32_set_octave_home, w32_set_quiet_shutdown,
+	MINGW_signal_cleanup):
+	Only define if defined (__WIN32__) && !	defined (_POSIX_VERSION).
+
+2007-10-04  Jason Riedy  <jason at acm.org>
+
+        * ls-mat5.cc (read_mat5_binary_data): Map miUTF16 to miUINT16,
+        miUTF32 to miUINT32.  The matfile format currently states that
+        wide UTF formats are in the same byte order as the integers.
+        (read_mat5_binary_element): Replace all UTF16 and UTF32
+        characters with the high bit set (value >127) by '?' and warn
+        that we've done so.
+
+2007-10-04  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* sysdep.cc (w32_set_octave_home): Base OCTAVE_HOME location on
+	octinterp, not the main exe.
+
+2007-10-03  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fnorm): New function.
+	(F__vnorm__): Delete.
+
+2007-10-03  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* DLD-FUNCTIONS/typecast.cc: Include <algorithm>.
+
+2007-10-03  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.cc (Octave_map::Octave_map (const dim_vector&, 
+	const string_vector&)): Delete.
+	(Octave_map::Octave_map (const dim_vector&, const Cell&)):
+	New function.
+	* ov-struct.cc (Fstruct): Allow creation of empty struct arrays
+	with field names.
+
+2007-10-01  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.cc ((color_property::color_property (const
+	octave_value& val)): Undo change from 2007-09-26
+	(patch::properties::properties): use the "a" modifier to
+	face_color & edge_color properties
+	(patch::properties::set): Undo change from 2007-09-26
+	* graphics.h.in	(color_property::color_property
+	(const octave_value& val)): Undo change from 2007-09-26
+
+2007-10-01  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* octave.cc (octave_main): Add "--line-editing" option to force
+	readline line editing.
+
+2007-09-28  David Bateman  <dbateman at free.fr>
+
+	* ov-range.h (int8_array_value, int16_array_value, int32_array_value,
+	int64_array_value, uint8_array_value, uint16_array_value, 
+	int32_array_value, uint64_array_value): New methods
+
+2007-09-28  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.h.in (color_property::colormap_property (const Matrix&)):
+	Use floating point math in calculation of colormap.
+
+2007-09-26  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (color_values::str2rgb): accept upper, lower and
+	mixed-case versions of the string representing the color. Allow
+	black defined as "k" and white as "w".
+	(color_property::color_property (const octave_value& val, 
+	const radio_values &v)): Modify the constructor to also take a
+	radio_values argument. Use it.
+	(patch::properties::set): Change set_facecolor calls to initialize
+	the color_property argument with the available radio_values.
+	* graphics.h.in (color_property::color_property 
+	(const octave_value& val, const radio_values &v)): Also pass a 
+	radio_values argument.
+
+	* ov-range.h (sparse_matrix_value, sparse_complex_matrix_value):
+	New methods.
+
+	* mk-pkg-add: Simplfy the autoload commands.
+	* parse.y (Fautoload): Allow bare filename if file is in the same
+	directory as the script from where the autoload command is run.
+
+2007-09-25  Matthias Drochner  <m.drochner at fz-juelich.de>
+
+	* syscalls.cc (Fpopen2): Doc fix.
+	Use "sort -r" instead of "sort -nr" in test.
+
+2007-09-18  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (input_event_hook, Finput_event_hook): Call
+	command_editor::add_event_hook and
+	command_editor::remove_event_hook intstead of
+	command_editor::set_event_hook and
+	command_editor::restore_event_hook.
+
+2007-09-17  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.14+.
+
+2007-09-17  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.14.
+	(OCTAVE_API_VERSION): Now api-v26.
+	(OCTAVE_RELEASE_DATE): Now 2007-09-17.
+
+	* Makefile.in (DISTFILES): Add genprops.awk to the list.
+
+	* ov-typeinfo.h (cat_op_fcn): Third arg in function pointer
+	typedef is now Array<octave_idx_type> instead of Array<int>.
+
+	* file-io.cc (do_stream_open): Use binary mode by default.
+
+2007-09-14  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* genprop.awk: Handle "a" modifier.
+
+2007-09-14  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.h.in (radio_values::contains): New function.
+	(radio_values::validate): Use it.
+	* graphics.cc (color_property::operator =): Call it instead of
+	validate here.
+
+2007-09-13  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc (glpk): Pass LPX_FX, not LB_DB, to
+	lpx_set_col_bnds when lb[i] == ub[i].
+	From: Zhi Wang <zcwang at umich.edu>.
+
+	* graphics.h.in (colormap_property::colormap_property):
+	Use jet colormap as default.
+
+2007-09-12  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (text::properties::properties): Default color is
+	black, not white.
+	* graphics.h (text::properties::color): Declare as color_property,
+	not octave_value.
+
+	* graphics.h.in (root_figure::defaults, figure::defaults,
+	axes::defaults, line::defaults, text::defaults, image::defaults,
+	patch::defaults, surface::defaults): New functions.
+	* gripes.cc (gripe_not_implemented): New function.
+	* gripes.h: Provide decl.
+
+2007-09-10  John W. Eaton  <jwe at octave.org>
+
+	* genprops.awk: Add missing newline character at end of file.
+	From Alexander Klimov <alserkli at inbox.ru>.
+
+2007-09-10  David Bateman  <dbateman at free.fr>
+
+	* data.cc (do_cat): Avoid invalid indexing into ra_idx vector.
+
+2007-09-06  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/__delaunay__.cc, DLD-FUNCRIONS/__voronoi__.cc,
+	DLD-FUNCTIONS/convhulln.cc: Avoid variables in global scope
+
+2007-09-06  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (stamp-prereq): Add graphics.h to the dependency list.
+
+2007-08-31  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (INCLUDES): Remove graphics.h from the list.
+	(DISTFILES): Include graphics.h.in in the list.
+	(genprops.awk): New file.
+	(graphics.h): New rule.
+	(distclean): Remove graphics.h.
+	* graphics.h.in: New file, from graphics.h.
+	(graphics_handle): Now a class instead of typedef.  Adapt all uses.
+	(OCTAVE_GRAPHICS_PROPERTY_INTERNAL, OCTAVE_GRAPHICS_PROPERTY,
+	OCTAVE_GRAPHICS_MUTABLE_PROPERTY): Delete macros.
+	(class root_figure, class figure, class axes, class line, class
+	text, class image, class patch, class surface): Use genprops.awk
+	to generate property declarations and set/get functions.
+	* graphics.h: Delete.
+	* graphics.cc (nan_to_empty, empty_to_nan): Delete.
+	(root_figure::properties::set, figure::properties::set,
+	axes::properties::set, line::properties::set,
+	text::properties::set, image::properties::set,
+	patch::properties::set, surface::properties::set): Call
+	type-specific set functions to set properties.
+	(root_figure::properties::set_currentfigure,
+	figure::properties::set_currentaxes, figure::properties::set_visible,
+	axes::properties::get_title, axes::properties::get_xlabel,
+	axes::properties::get_ylabel,  axes::properties::get_zlabel,
+	axes::properties::set_title, axes::properties::set_xlabel,
+	axes::properties::set_ylabel,  axes::properties::set_zlabel):
+	Define custom versions.
+
+2007-09-06  David Bateman  <dbateman at free.fr>
+
+        * DLD-FUNCTIONS/bsxfun.cc: New function.
+        * DLD-FUNCTIONS/typecast.cc: New function.
+        * Makefile.in (DLD_XSRC): Add bsxfun.cc and typecast.cc.
+        * ov.cc (do_cat_op): Modify use of Array<int> to 
+        Array<octave_idx_type> and adjust where necessary.
+        * ov.h (do_cat_op): ditto.
+        * data.cc (do_cat): ditto.
+        * pt-mat.cc (tree_matrix::rvalue): ditto.
+
+2007-09-05  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* oct-stream.cc (octave_base_stream::do_printf): Ignore precision
+	portion of format string if printing Inf, NaN, or NA values.
+
+2007-09-05  David Bateman  <dbateman at free.fr>
+
+        * DLD-FUNCTIONS/sort.cc (mx_sort_sparse, mx_sort_sparse_indexed):
+        New template classes for sparse sort functions.
+        (Fsort): Use them.
+        * ov.h (octave_value (const Sparse<double>&, const MatrixType&),
+        octave_value (const Sparse<Complex>&, const MatrixType&)): New
+        constructors.
+        * ov.cc (octave_value::octave_value (const Sparse<double>&, 
+        const MatrixType&), octave_value::octave_value (const 
+        Sparse<Complex>&, const MatrixType&)): Define them.
+        * ov-re-sparse.h (octave_sparse_matrix (const MSparse<double>&,
+        const MatrixType&), octave_sparse_matrix (const Sparse<double>&),
+        octave_sparse_matrix (const Sparse<double>&, const MatrixType&)):
+        New constructors.
+        * ov-cx-sparse.h (octave_sparse_complex_matrix (const MSparse<double>&,
+        const MatrixType&), octave_sparse_complex_matrix (const 
+        Sparse<double>&), octave_sparse_complex_matrix (const
+        Sparse<double>&, const MatrixType&)): ditto.
+
+2007-09-04  Gabriele Pannocchia  <g.pannocchia at ing.unipi.it>
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Use Wact(j) == i - n_eq when
+	checking for blocking constraint.  Don't resize lambda_tmp.  Only
+	compute Y = Aact.pseudo_inverse () if it is needed.
+
+2007-08-31  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* ls-mat-ascii.cc (get_lines_and_columns): Check beg variable for
+	NPOS to avoid segmentation fault. 
+
+	* load-path.cc (load_path::do_find_file): Do not assume paths
+	use forward slashes.
+
+2007-08-30  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc (Fpause): Doc fix.
+
+2007-08-30  Gabriele Pannocchia  <g.pannocchia at ing.unipi.it>
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Resize Wact to n_act-neq, not n_act.
+
+2007-08-29  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (class root_figure::properties):
+	Rename from root_figure::root_figure_properties.
+	(class figure::properties): Rename from figure::figure_properties.
+	(class axes::properties): Rename from axes::axes_properties.
+	(class line::properties): Rename from line::line_properties.
+	(class text::properties): Rename from text::text_properties.
+	(class image::properties): Rename from image::image_properties.
+	(class patch::properties): Rename from patch::patch_properties.
+	(class surface::properties): Rename from surface::surface_properties.
+
+	* base-list.h (octave_base_list::remove): Implement our own
+	remove_if function here.
+
+2007-08-28  John W. Eaton  <jwe at octave.org>
+
+	* graphics.h (base_properties): Move class definition before
+	definition of base_graphics_object class.  Provide forward
+	declaration of base_graphics_object prior to definition of
+	base_properties.
+ 	(base_graphics_object::get_properties): New virtual function.
+	(graphics_object::get_properties, root_figure::get_properties,
+	figure::get_properties, axes::get_properties,
+	line::get_properties, text::get_properties, image::get_properties,
+	patch::get_properties, surface::get_properties): New functions.
+	(root_figure::properties, figure::properties, axes::properties,
+	line::properties, text::properties, image::properties,
+	patch::properties, surface::properties): Data member now private.
+
+2007-08-27  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_find_file): Also files with non
+	rooted relative names.
+	* load-save.cc (find_file_to_load): Likewise.  Also handle
+	appending .mat to files with relative names.
+
+	* graphics.cc (base_properties::mark_modified,
+	base_properties::override_defaults,
+	base_properties::delete_children, figure::get_default,
+	axes::get_default): Move definitions here, from graphics.h.
+	* graphics.h (class gh_manager): Move decl to end of file.
+
+	* Cell.h (Cell::Cell (const octave_value_list&)): Create row
+	vector instead of column vector.
+
+	* pt-idx.cc (tree_index_expression::lvalue): Handle [x.a] =
+	... style assignments.
+	* ov-struct.cc (octave_struct::subsasgn): Handle case of RHS as
+	comma-separated list.
+
+	* ov-cell.cc (gripe_failed_assignment): New function.
+	(octave_cell::subsasgn): Call gripe_failed_assignment if assign
+	methods fail.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+	* symtab.cc (void symbol_table::clear (void)): If the record in
+	the symbol table to clear is a user function that is a sub
+	function with a static parent or if the parent is the current
+	parent function, don't delete the record.
+	(void symbol_table::clear_functions (void)): ditto.
+	(void symbol_table::clear (const std::string&)): ditto.
+	(void symbol_table::clear_function (const std::string&)): ditto.
+
+	* graphics.h (class text): Add property color.
+	* graphics.cc (text::text_properties::text_properties) ditto.
+	(text::text_properties::set): ditto.
+	(text::text_properties::get): ditto.
+	(text::text_properties::factory_defaults): ditto.
+
+2007-08-24  John W. Eaton  <jwe at octave.org>
+
+	* mappers.cc (dummyp): New function.
+	(install_mapper_functions): Use it to handle character data in
+	finite, isinf, isna, and isnan functions.
+
+	* load-path.cc (load_path::do_remove): Call remove_hook function
+	before removing directory from list.
+
+2007-08-24  David Bateman  <dbateman at free.fr>
+
+        * ov-bool-sparse.cc (DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Class
+        is now logical.
+        * ov-re-sparse.cc, ov-cx-sparse.cc 
+        (DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Class is now double.
+        * ov-mapper.cc (octave_mapper::apply): Use is_sparse_type method
+        rather than comparing class name.
+        * ls-mat5.cc (save_mat5_element_length, save_mat5_binary_element):
+        ditto.
+        * pt-mat.cc (tree_matrix:rvalue): sparse matrices are now of class
+        "double" or "logical", create new single type concat clause for
+        them.
+        * mex.cc (get_class_id): No longer need to special case sparse
+        matrices.
+
+        * DLD-FUNCTIONS/__delaunayn__.cc, DLD-FUNCTIONS/convhulln.cc, 
+        DLD-FUNCTIONS/tsearch.cc, DLD-FUNCTIONS/__voronoi__.cc: New
+        functions ported from octave-forge.
+        * DLD-FUCTIONS/__dsearchn__.cc: New file.
+        * DLD-FUNCTIONS/__voronoi__.cc: Return point at infinity and
+        include it in the polygrons of the Voronoi diagram for
+        compatibility.
+        * Makefile.in: Add specific build targets for __delanayn__.cc,
+        convhulln.cc and __voronoi__.cc to link to Qhull.
+        (DLD_SRC): Add new functions.
+        (OCTAVE_LIBS): Add QHULL_LIBS
+
+2007-08-22  David Bateman  <dbateman at free.fr>
+
+	* variables.cc (Fmunlock): Call munlock and not mlock.
+	* symtab.cc (symbol_record::mark_as_formal_parameter): Typo. 
+
+2007-08-10  John W. Eaton  <jwe at octave.org>
+
+	* pt-idx.cc (tree_index_expression::get_struct_index): Improve
+	error message.
+	* ov-struct.cc (Fstruct, Fcell2struct): Trap invalid field names here.
+
+2007-08-10  Peter A. Gustafson  <petegus at umich.edu>
+
+	* graphics.h, graphics.cc (axes::axes_properties): New properties,
+	xaxislocation and yaxislocation.
+
+2007-08-10  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.cc, graphics.h (patch): New class.
+	(axes::axes_properties): New properties, clim and climmode.
+	(surface::surface_properties::surface_properties): Handle patch.
+	(F__go_patch__): New function.
+
+2007-07-30  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_number::mxArray_number (int, const char **)):
+	First arg is now mwSize.
+	(max_str_len): Return mwSize value, not int.
+	* mxarray.h.in (mxArray::mxArray (int, const char **)):
+	First arg is now mwSize.
+	(mxArray::mxArray (mxClassID, mwSize, mwSize, int, mxComplexity)):
+	Third arg is now mwSize.
+	(mxArray::get_string (char *, int)): Second arg is now mwSize.
+
+2007-07-26  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc: Include glpk/glpk.h if
+	HAVE_GLPK_GLPK_H is defined.
+
+2007-07-26  David Bateman  <dbateman at free.fr>
+
+	* pr-output.cc (Frats): Return character array with same number of
+	rows as original value.
+
+2007-07-26  John W. Eaton  <jwe at octave.org>
+
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Rename cur_fcn to xfcn.
+
+	* version.h (OCTAVE_VERSION): Now 2.9.13+.
+
+2007-07-25  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.13
+	(OCTAVE_API_VERSION): Now api-v25.
+	(OCTAVE_RELEASE_DATE): Now 2007-07-25.
+
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Rename fcn to curr_fcn.
+
+2007-07-25  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: 	Adjust DISTFILES to allow out of tree "make dist" 
+	to work.
+
+2007-07-24  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.cc (color_property::operator = (const octave_value&)):
+	New method.
+	* graphics.h: Provide decl.
+
+2007-07-24  Rafael Laboissiere  <rafael at debian.org>
+
+	* oct-conf.h.in (OCTAVE_CONF_RUNTEST): Delete definition.
+	* toplevel.cc (Foctave_config_info): Remove RUNTEST from struct.
+
+2007-07-23  David Bateman  <dbateman at free.fr>
+
+	* pr-output.cc (rat_format, rat_string_len): Global variable
+	controlling behavior of rational approximation. Use throughout.
+	(class pr_rational_float): New class for rational approximation of
+	floats, specifically with the << operator defined.
+	(std::ostream& operator << (std::ostream&, const
+	pr_rational_float&)): Operator to print rational approximations of
+	double values.
+	(std::string rational_approx (double, int)): Function to convert a
+	double value to a string of maximum length giving the rational
+	approximation.
+	(pr_any_float): Include the output of rational approximations.
+	(Fformat): Add the "rat" format as an option.
+	(Frats): New function.
+
+2007-07-23  Aquil H. Abdullah  <aquil.abdullah at gmail.com>
+
+	* mex.cc (mxCreateStructArray): Declare second arg as const.
+	* mexproto.h (mxCreateStructArray): Ditto.
+
+2007-07-20  David Bateman  <dbateman at free.fr>
+
+        * zfstream.cc (BUFSIZE): Increase default buffer size to 256kB
+        (gzfilebuf::underflow): Stash the last 16 characters read, so as
+        to avoid calling pbackfail as much as possible.
+
+2007-07-18  David Bateman  <dbateman at free.fr>
+
+         * zfstream.cc (int_type gzfilebuf::pbackfail (int_type)): New
+         method to putback a character when the putback position in the
+         internal buffer doesn't exist.
+         * zfstream.h (int_type pbackfail (int_type)): Declaration it.
+
+2007-07-14  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* src/ov-bool-sparse.cc (octave_sparse_bool_matrix:load_hdf5):
+	Use OCTAVE_LOCAL_BUFFER for temporary boolean value.
+	
+2007-06-27  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sparse.cc (Fspdiag): Ensure spdiag(zeros(1,0)) returns
+	0x0 matrix. Doc update.
+	* data.cc (Fdiag): Doc update.
+
+2007-06-28  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.cc (octave_cell::subsasgn): Given x = {}, convert to
+	struct for assignments like x(1).f = val;
+
+	* oct-stream.cc (octave_scan_1): New function
+	(octave_scan): Use it.  Handle fmt.width.
+
+	* graphics.h (axes::axes_properties::visible): New data member.
+	* graphics.cc (axes::axes_properties::axes_properties, 
+	axes::axes_properties::set, axes::axes_properties::get, 
+	axes::axes_properties::factory_defaults): Handle visible property.
+
+2007-06-27  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.h (color_values::color_values): Arg is now std:string
+	instead of char.  Call str2rgb, not c2rgb.
+	* graphics.h, graphics.cc: (color_values::str2rgb): Rename from
+	c2rgb.  Handle long color names, not just single char abbreviations.
+
+2007-06-27  David Bateman  <dbateman at free.fr>
+	
+	* src/load-save.cc (Fsave): Ensure header is written for non
+	existent file with "-append".
+	* src/ls-hdf5.h: First steps towards having append work for hdf5.
+	
+2007-06-26  John W. Eaton  <jwe at octave.org>
+
+	* src/load-save.cc (Fsave): Open files correctly for -append.
+	Don't write file headers if appending.  Error for -append -hdf5.
+
+2007-06-25  Olaf Till  <i7tiol at t-online.de>
+
+	* oct-stream.h (octave_stream_list::list): Use std::map.
+	(octave_stream_list::curr_len): Delete data member.
+	(octave_stream_list::octave_stream_list): Fix initializations.
+ 
+	* oct-stream.cc (octave_steam_list::do_insert,
+	octave_steam_list::do_lookup, octave_steam_list::do_remove,
+	octave_steam_list::do_clear, octave_steam_list::do_list_open_files, 
+	octave_steam_list::do_open_file_numbers,
+	octave_steam_list::do_get_file_number):
+ 	Use new octave_stream_list::list type.
+	(octave_stream_list::do_insert): Insert octave_stream with key
+	corresponding to file-descriptor.
+	(octave_stream_list::do_insert, octave_steam_list::insert):
+	Remove const qualifier of argument.
+
+2007-06-18  Søren Hauberg  <hauberg at gmail.com>
+
+        * DLD-FUNCTIONS/__lin_interpn__.cc: Replace octave_NaN with octave_NA.
+
+2007-06-15  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h (OCTAVE_GRAPHICS_PROPERTY_INTERNAL,
+	OCTAVE_GRAPHICS_PROPERTY, OCTAVE_GRAPHICS_MUTABLE_PROPERTY):
+	New macros. Use them to declare individual properties and define
+	accessor methods for each property in the property classes.
+
+2007-06-15  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.cc (Fget, Fset): Handle vectors of handles.
+
+2007-06-14  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc (octave_popen, octave_pclose): New functions.
+	* sysdep.h: Provide decls.
+
+	* oct-procbuf.cc (procbuf::open): Use octave_popen.
+	(procbuf::close): Use octave_pclose.
+	* oct-prcstrm.cc (octave_oprocstream::octave_oprocstream, 
+	octave_iprocstream::ictave_oprocstream): Likewise.
+
+	* graphics.h (text::text_properties::rotation): New data member.
+	* graphics.cc (text::text_properties::text_properties, 
+	text::text_properties::set, text::text_properties::get, 
+	text::text_properties::factory_defaults): Handle rotation property.
+
+2007-06-14  Kai Habel  <kai.habel at gmx.de>
+
+	* graphics.cc (color_values::c2rgb): Also accept 'k' for black.
+
+2007-06-14  David Bateman  <dbateman at free.fr>
+
+	* ov-ch-mat.h (idx_vector index_vector (void) const): Remove
+	definition.
+	* ov-ch-mat.cc (idx_vector index_vector (void) const): Move it
+	here. Special case ":" case for compatibility.
+
+2007-06-13  John W. Eaton  <jwe at octave.org>
+
+	* ov-re-mat.cc (octave_matrix::load_ascii):
+	Do a better job of handling read errors and empty matrices.
+	* ov-cx-mat.cc (octave_complex_matrix::load_ascii): Likewise.
+	* ov-bool-mat.cc (octave_bool_matrix::load_ascii): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::load_ascii): Likewise.
+
+2007-06-13  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/minmax.cc (MINMAX_BODY): Don't treat as single
+	argument if arg2 is empty and nargin=2.
+
+2007-06-13  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.h, graphics.cc: Move class declarations to graphics.h.
+	Move larger functions outside of class declarations in graphics.cc.
+
+2007-06-12  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* DLD-FUNCTIONS/cellfun.cc: Use fullfile to generate filenames
+	instead of assuming / will work as directory separator.
+
+2007-06-12  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/interpn.cc: Remove it.
+	* DLD-FUNCTIONS/__lin_interpn__.cc: Move it. This is now a support
+	function of interpn.m.
+	* Makefile.in (DLD_XSRC): Remove interpn.cc and add __lin_interpn__.cc.
+
+2007-06-07  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-handles.cc (octave_fcn_handle::save_hdf5): More care that
+	all open HDF5 descriptors are closed.
+	(octave_fcn_handle::load_hdf5): Ditto.
+
+2007-06-06  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* utils.cc [__MINGW32__]: Don't define HAVE_C99_VSNPRINTF.
+
+2007-06-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* defaults.h.in, ls-hdf5.h, ov-complex.h, ov-cx-mat.h, ov-intx.h,
+	sysdep.h: Sprinkle with OCTINTERP_API as needed.
+
+2007-06-05  John W. Eaton  <jwe at octave.org>
+
+	* help.h (raw_help): Tag with OCTINTERP_API.
+
+	* Makefile.in (INCLUDES): Remove mxarray.h from the list so that
+	it is not distributed.
+	(EXTRAS): Add mxarray.h to the list so that it is installed.
+
+	* sysdep.cc (same_file_internal) [OCTAVE_USE_WINDOWS_API]:
+	Avoid leaking file handles.
+
+2007-05-08 Michael Weitzel  <michael.weitzel at uni-siegen.de>
+
+	* DLD-FUNCTIONS/symrcm.cc: Fix for queuing error that might cause
+	an infinite loop.
+
+2007-06-04  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fislogical): Rename from Fisbool.
+	Make isbool an alias for islogical.
+
+2007-06-03  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (DISTFILES): Add mxarray.h.in
+	(install-inc): Modify target so that mxarray.h is installed
+	correctly.
+	(distclean): Remove mxarray.h on distclean.
+	* mex.cc: Use mwSize for dimensions and mwIndex for indexing
+	throughout, with the exception of struct key indexes.
+	* mexproto.h: ditto.
+	* mxarray.h: remove.
+	* mxarray.h.in: Copy here and define mwSize, mwIndex, and use
+	throughout. 
+	* ov-bool-mat.cc (octave_bool_matrix::as_mxArray): Use mwSize and
+	mwIndex.
+	* ov-bool-sparse (octave_sparse_bool_matrix::as_mxArray): ditto.
+	* ov-cell.cc (octave_cell:as_mxArray): ditto.
+	* ov-ch-mat.cc (octave_char_matrix:as_mxArray): ditto.
+	* ov-cx-mat.cc (octave_complex_matrix::as_mxArray): ditto.
+	* ov-cx-sparse.cc (octave_sparse_complex_matrix::as_mxArray): ditto.
+	* ov-int.h (as_mxArray): ditto.
+	* ov-range.cc (octave_range:as_mxArray): ditto.
+	* ov-re-mat.cc (octave_matrix:as_mxArray): ditto.
+	* ov-re-sparse.cc (octave_sparse_matrix::as_mxArray): ditto.
+	* ov-struct.cc (octave_struct::as_mxArray): ditto.
+
+2007-06-02  David Bateman  <dbateman at free.fr>
+
+	* graphics.cc (color_property class): g++ doesn't like anonymous
+	enums. Give type to color_type enum.
+
+2007-05-31  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.cc (radio_values, radio_property, color_values):
+	New classes.
+	(color_property class): Handle both color and radio values.
+
+2007-05-31  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (main_loop): Improve bad_alloc error message.
+
+	* octave.cc (execute_command_line_file, execute_eval_option_code):
+	Likewise.
+
+2007-05-31  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* toplev.cc (octave_atexit_functions):
+	Now std::list instead of std::stack.
+	(do_octave_atexit): Adapte to octave_atexit_functions as list.
+	(Fatexit): Allow second arg of false to remove element from list.
+
+	* DLD-FUNCTIONS/symrcm.cc: Use ! instead of "not".
+
+	* sysdep.cc (same_file_internal) [OCTAVE_USE_WINDOWS_API]:
+	Use INVALID_HANDLE_VALUE, not INVALID_FILE_HANDLE.
+
+2007-05-28  G. D. McBain  <geordie_mcbain at yahoo.com.au>
+
+	* ov-list.cc (append): Doc fix.
+
+2007-05-28  John W. Eaton  <jwe at octave.org>
+
+	* pt-loop.cc (DO_ND_LOOP): Avoid parser problem with obsolete g++.
+
+2007-05-23  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.12+.
+
+2007-05-23  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.12.
+	(OCTAVE_RELEASE_DATE): Now 2007-05-23.
+
+	* parse.y (make_anon_fcn_handle): Don't build assignment expression.
+	* ov-fcn-handle.cc (octave_fcn_handle::print_raw):
+	Don't split assignment expression.
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Special case for inline function body evaluation.
+
+2007-05-22  John W. Eaton  <jwe at octave.org>
+
+	* pt-fcn-handle.cc (tree_anon_fcn_handle::rvalue):
+	Set current function as parent of anonymous function handle.
+
+	* Makefile.in (uninstall): Also remove
+	$(DESTDIR)$(octincludedir)/octave, $(DESTDIR)$(octincludedir),
+	$(DESTDIR)$(octlibdir), and $(DESTDIR)$(octfiledir).
+
+2007-05-22  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* debug.cc, error.cc, load-save.cc, oct-hist.cc, sighandlers.cc,
+	symtab.cc: Fix typos.
+
+2007-05-22  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.11+.
+
+2007-05-22  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.11.
+	(OCTAVE_API_VERSION): Now api-v24.
+	(OCTAVE_RELEASE_DATE): Now 2007-05-22.
+
+2007-05-21  David Bateman  <dbateman at free.fr>
+
+	* debug.cc (Fdbstop): handle integer, vector and multiple line
+	arguments.
+	(Fdbclar): ditto. Eliminate extraneous debugging messages.
+
+2007-05-21  Søren Hauberg  <hauberg at gmail.com>
+
+        * load-path.cc (Fpath, Frehash): Replace "LOADPATH" with "load
+	path" in doc strings.
+
+        * parse.y (Feval): Add example.
+
+2007-05-21  David Bateman  <dbateman at free.fr>
+
+	* error.cc (rethrow_error): Use NULL name so that "error:" is not
+	added to the message
+	(Frethrow): Correctly treat empty stack.
+
+2007-05-21  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.h (Octave_map::numel): Return number of array elements,
+	not number of map elements.
+	(Octave_map::nfields): Rename from length.
+	(Octave_map::empty): Delete.
+	Change all uses of empty to check nfields () == 0 instead.
+
+2007-05-21  Søren Hauberg  <soren at hauberg.org>
+
+	* help.cc (Fautoload): Doc fix.
+	* variables.cc (Fiscommand): Doc fix.
+
+2007-05-19  David Bateman  <dbatemna at free.fr>
+
+	* ov-fcn-inline.cc (Fvectorize): Doc fix.
+
+2007-05-16  Søren Hauberg  <soren at hauberg.org>
+
+	* ov.cc (Fsubsref, Fsubsasgn): Doc fix.
+
+2007-05-16  John W. Eaton  <jwe at octave.org>
+
+	* load-path.h (load_path::sys_path): New static data member.
+	(load_path::system_path): New static function.
+	(load_path::do_system_path): New function.
+	* load-path.cc (Vsystem_path): Delete.
+	(load_path::do_initialize): Use sys_path, not Vsystem_path.
+	(Fpathdef): Call load_path::system_path instead of using Vsystem_path.
+	* ls-mat5.cc (read_mat5_binary_element): Likewise.
+	* ov-fcn-handle.cc (octave_fcn_handle::set_fcn): Likewise.
+
+2007-05-16  David Bateman  <dbateman at free.fr>
+
+	* load_pathc.cc (std::string octave_system_path (void)): New
+        function.
+        * load-path.h (std::string octave_system_path (void)): Declare it.
+
+        * load-save.cc (static load_save_format get_file_format
+        (std::istream&, const std::string&)): Add filename argument, and
+        pass it to read_mat5_binary_header. Use new format throughout file.
+        (Fload): Don't allow gzip of matlab v7 files as the files
+        themselves include compression.
+
+        * ls-mat5.cc (arrayclsstype:MAT_FILE_WORKSPACE_CLASS): New class
+        type.
+        (read_mat5_binary_element): Workspaces, don't have dimensions, so
+        don't read them. Implement read of matlab objects, but only use
+        them for inline functions. Implement reading of function and
+        workspace classes.
+        (read_mat5_binary_header): Add filename argument. Read sub-system
+        specific data block given as an offset in bytes 117 to 124.
+        (save_mat5_binary_element): Include saving of inline functions.
+
+        * ls-mat5.h (read_mat5_binary_header): Include filename.
+
+        * ov-fcn-handle.cc (octave_fcn_handle_save_ascii,
+        octave_fcn_handle::load_ascii, octave_fcn_handle::save_binary, 
+        octave_fcn_handle::load_binary, octave_fcn_handle::save_hdf5, 
+        octave_fcn_handle::load_hdf5): Save and reload the local symbol
+        table of the user function associated with anonymous function
+        handles. Save and load the absolute path and the exec_prefix for
+        normal function handles and use then to find equivalent functions
+        between different installations of Octave. Attempt to maintain
+        backward and forward compatibility.
+        (Ffunctions): Additional outputs, including the workspace of
+        anonymous functions, and more compatiable outputs.
+
+        * ov-fcn-handle.h (user_function_value): Expose the user function
+        value of a function handle.
+
+        * ov-fcn-inline.cc (Octave_map octave_fcn_inline::map_value
+        (void) const): Return a structure compatiable with matlab's class
+        implementation of inline functions.
+
+        * ov-fcn-inline.h (map_value): Declare it.
+
+2007-05-14  Bob Weigel  <rweigel at gmu.edu>
+
+	* DLD-FUNCTIONS/svd.cc: Doc fix.
+
+2007-05-14  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* DLD-FUNCTIONS/fft.cc (do_fft): Handle empty matrices.  New tests.
+
+2007-05-14  Søren Hauberg  <soren at hauberg.org>
+
+	* toplev.cc (Fatexit): Simplify example in doc string.
+	* help.cc (Flookfor): Doc fix.
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun):
+	Reformat to avoid long lines in doc string example.
+
+2007-05-13  Søren Hauberg  <soren at hauberg.org>
+
+	* toplev.cc (Fquit): Doc fix.
+	* help.cc (Fhelp): Doc fix.
+	* oct-hist.cc (Fsaving_history): Doc fix.
+
+2007-05-11  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_out_of_date):
+	Always check for files that have gone missing.
+
+2007-05-08 Michael Weitzel  <michael.weitzel at uni-siegen.de>
+
+	* DLD-FUNCTIONS/symrcm.cc: New function for Reverse Cuthill-McKee
+	permutation.
+	
+2007-05-07  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.cc (Octave_map::resize): Handle case of no keys.
+	(keys_ok): Rename from equiv_keys.  Return value is now status.
+	Pass key names as string_vector reference arg.
+	(Octave_map::assign (const octave_value_list&, const Octave_map&)):
+	Call keys_ok, not equiv_keys.  Handle case of no keys.
+
+2007-04-30  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (%.df : %.cc): Use mv instead of
+	$(simple-move-if-change-rule).
+
+2007-04-30  David Bateman  <dbateman at free.fr>
+	
+	* pt-loop.cc (DO_ND_LOOP): New args, CONV and ARG.
+	Use octave_idx_type instead of int for loop counters.
+	Remove redundant assignments to variable "quit" as it is
+	always defined in quit_loop_now.
+	Special case rows = 0 and 1 cases in loops over arrays.
+	Include some of the code that was separate from the macro
+	DO_ND_LOOP in the macro itself
+	(tree_simple_for_command::eval): USE DO_ND_LOOP for all loops.
+	(DO_LOOP): Delete.
+
+2007-04-30  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mex::cleanup): Don't call unmark for elements of the set
+	inside the loop.  From Laurent Mazet <laurent.mazet at motorola.com>.
+
+2007-04-30  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-int-conv.cc: Define sq and dq string conversion
+	operators.  Delete old char_matrix_str conversions.
+	* OPERATORS/op-int-conv.cc (install_int_conv_ops): Install them.
+
+2007-04-27  Benjamin Lindner  <lindnerb at users.sourceforge.net>.
+
+	* octave.cc (execute_startup_files): Call same_file to check for
+	already executed init files.
+
+2007-04-27  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc (same_file_internal): New function.  POSIX code
+	from same_file in utils.cc.  Windows code from
+	Benjamin Lindner  <lindnerb at users.sourceforge.net>.
+	Don't canonicalize file names.
+	Also return false if stat calls fail.
+	* sysdep.h: Provide decl.
+	* utils.cc (same_file): Use same_file_internal.
+
+2007-04-27  David Bateman  <dbateman at free.fr>
+
+	* graphic.cc (get_property_form_handle, set_property_in_handle):
+	New functions.
+	* grahics.h: New file.
+	* mex.cc (mexGet, mexSet): use the above to implement mexGet
+	and mexSet.
+	* Makefile.in (INCLUDES): Add graphics.h
+
+2007-04-26  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Only deal with varargout if ret_list->takes_varargs () is true.
+
+2007-04-26  Søren Hauberg  <soren at hauberg.org>
+
+	* DLD-FUNCTIONS/urlwrite.cc: Doc fix.
+
+2007-04-26  David Bateman  <dbateman at free.fr>
+
+	* pt-loop.cc (tree_simple_for_command::eval (void)): Correct
+	reshaping of dim_vector in for loop for multi-dimensional array.
+
+2007-04-26  John W. Eaton  <jwe at octave.org>
+
+	* load-save.cc (find_file_to_load): Only consider regular files.
+
+2007-04-24  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* graphics.cc (color_property): Eliminate alpha channel from RGB
+	color spec.
+
+2007-04-23  Shai Ayal  <shaiay at users.sourceforge.net>
+
+	* src/graphics.cc (color_property::color_property):
+	New arg A for alpha channel.  Set rgba instead of red, green, blue.
+        (color_property::color_property (char)): New constructor.
+        (color_propery::rgba): New data member.
+	(color_property::red, color_property::green, color_property::blue):
+	Delete.
+        (color_property::validate): Use rgba.
+        (color_property::c2rgba): New function.
+
+2007-04-23  Søren Hauberg  <soren at hauberg.org>
+
+	* data.cc (Fsize_equal): Allow more than two arguments.
+
+2007-04-20  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (deftypefn): 
+	(Vautomatic_replot): Delete static variable.
+	(Fautomatic_replot): Delete function.
+
+	* toplev.cc (Fcasesen): Delete obsolete function.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (gnuplot::makeplot): Check
+	whether caller is "splot", not "gsplot".
+
+2007-04-19  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (is_keyword_token): Delete all_va_args_kw switch case.
+	* octave.gperf: Remove all_va_args_kw from the list.
+
+2007-04-19  Daniel J. Sebald  <daniel.sebald at ieee.org>
+
+	* syscalls.cc: Fix popen2 test to stop trying after 100 times
+	throught the loop.
+
+2007-04-16  Geordie McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* ov-fcn-inline.cc (Fargnames): Doc fix.
+
+2007-04-13  Geordie McBain  <geordie.mcbain at aeromech.usyd.edu.au>
+
+	* DLD-FUNCTIONS/find.cc (Ffind): Doc fix.
+
+2007-04-11  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DOCSTRINGS): Don't echo commands.
+	(doc-files): Use mv, not $(simple-move-if-change-rule).
+
+	* data.cc (Fnot, Fuplus, Fuminus, Ftranspose, Fctranspose, Fplus,
+	Fminus, Fmtimes, Fmrdivide, Fmpower, Fmldivide, Flt, Fle, Feq,
+	Fge, Fgt, Fne, Ftimes, Frdivide, Fpower, Fldivide, Fand, For):
+	New functions.
+
+2007-04-09  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (line::line_properties::markeredgecolor,
+	line::line_properties::markerfacecolor): New properties.
+
+2007-04-06  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (F__vnorm__): New function.
+
+	* pt-fcn-handle.cc (tree_anon_fcn_handle::param_list, 
+	tree_anon_fcn_handle::cmd_list,	tree_anon_fcn_handle::ret_list,
+	tree_anon_fcn_handle::sym_tab): Delete.  Remove all uses.
+	(tree_anon_fcn_handle::fcn): New data member.
+	(tree_anon_fcn_handle::tree_anon_fcn_handle): Initialize it.
+	(tree_anon_fcn_handle::rvalue, tree_anon_fcn_handle::dup):
+	Extract parameter list, return list, function body, and symbol
+	table from fcn.
+	(tree_anon_fcn_handle::parameter_list, tree_anon_fcn_handle::body):
+	Forward request to fcn.
+
+	* ov-usr-fcn.h (octave_user_function::local_sym_tab): Rename from
+	sym_tab.  Change all uses.
+	(octave_user_function::sym_tab): New function.
+
+	* octave.cc (execute_command_line_file): 
+
+2007-04-05  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/regexp.cc (Fregexprep): Correct iteration over 
+	cell arrays so that the source and pattern are iterated seperately 
+	in the same manner as matlab.
+
+2007-04-05  Laurent Mazet  <laurent.mazet at motorola.com>
+
+	* mex.cc (mxArray_octave_value::get_string): Copy nel elements,
+	not buflen elements.
+
+2007-04-05  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (DO_DOUBLE_CONV): New macro.
+	(do_printf): Use it.
+
+2007-04-04  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (octave_yes_or_no): Force interactive_input to use readline.
+
+	* octave.cc (execute_eval_option_code): Catch bad::alloc here.
+
+2007-04-03  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/urlwrite.cc (Furlwrite, Furlread):
+	Use && for logical, not &.
+
+	* DLD-FUNCTIONS/qr.cc (Fqr): Clarify nargin check.
+
+	* error.cc (Frethrow): Add braces to avoid ambiguous if/else.
+	* oct-stream.cc (octave_scan<>): Likewise.
+	* DLD-FUNCTIONS/colamd.cc (Fetree): Likewise.
+	* DLD-FUNCTIONS/sort.cc (mx_sort, mx_sort_indexed): Likewise.
+
+	* ov-fcn-handle.cc (make_fcn_handle): Pass ultimate parent
+	function name to lookup_function.
+
+2007-03-29  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/filter.cc (filter): Fix typo in doc string.
+	From Utkarsh Upadhyay <musically.ut at gmail.com>.
+
+2007-03-28  Rafael Laboissiere  <rafael at debian.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc: Fix #ifdef logic around GLPK_PRE_4_14.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.10+
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.10.
+	(OCTAVE_API_VERSION): Now api-v23.
+	(OCTAVE_RELEASE_DATE): Now 2007-03-27.
+
+	* version.h (OCTAVE_COPYRIGHT): Update for 2007.  Add "and others".
+	(X_OCTAVE_WARRANTY_STATEMENT): Rename from OCTAVE_WARRANTY_STATEMENT.
+	Accept arg.
+	(OCTAVE_WARRANTY_STATEMENT): Define using X_OCTAVE_WARRANTY_STATEMENT.
+	(OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY): Define using
+	X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY.
+	(X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY): Rename
+	from OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY.
+	Accept arg and pass to X_OCTAVE_WARRANTY_STATEMENT.
+	(OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY): Pass empty
+	arg to X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS.
+	(OCTAVE_STARTUP_MESSAGE): Put info about news last.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (dist, conf-dist): Use ln, not $(LN_S).
+
+2007-03-26  Juhani Saastamoinen  <juhani at cs.joensuu.fi>
+
+	* file-io.cc (do_stream_open) [! HAVE_ZLIB]:
+	Call fopen with mode, not tmode.
+
+2007-03-26  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-str-str.cc (DEFCHARNDBINOP): New macro.  Use it to
+	define functions for eq and ne ops.  Also define lt, le, ge, and
+	gt ops.
+
+2007-03-23  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/rand.cc: Make more statistical tests optional.
+
+2007-03-23  John W. Eaton  <jwe at octave.org>
+
+	* bitfcns.cc (Fbitshift): Error if third argument is not a scalar.
+
+2007-03-23  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/rand.cc: Make statistical tests optional and 
+	add tests for fixed sequences.
+
+2007-03-22  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc (base_graphics_object::mark_modified):
+	New virtual function.
+	(base_properties::__modified__): New data member.
+	(base_properties::base_properties): Initialize it.
+	(graphics_object::mark_modified, base_properties::mark_modified, 
+	root_figure::mark_modified, figure::mark_modified,
+	axes::mark_modified, line::mark_modified, text::mark_modified,
+	image::mark_modified, surface::mark_modified,
+	root_figure::root_figure_properties::mark_modified,
+	figure::figure_properties::mark_modified,
+	axes::axes_properties::mark_modified,
+	line::line_properties::mark_modified,
+	text::text_properties::mark_modified,
+	image::image_properties::mark_modified,
+	surface::surface_properties::mark_modified): New functions.
+	(figure::figure_properties::set, figure::figure_properties::get,
+	axes::axes_properties::set, axes::axes_properties::get,
+	line::line_properties::set, line::line_properties::get,
+	text::text_properties::set, text::text_properties::get,
+	image::image_properties::set, image::image_properties::get,
+	surface::surface_properties::set, surface::surface_properties::get):
+	Handle __modified__ property.
+
+	* parse.y (Fautoload): Use warning_with_id.
+
+2007-03-21  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__qp__.cc (ABS): Delete.  Use std::abs instead.
+	(null): Set elements of retval with magnitudes less than eps to 0.
+
+	* error.cc (Fwarning): Allow setting options with struct.
+	If setting options, return previous state.
+
+	* graphics.cc (axes::axes_properties::set_defaults): Reverse sense
+	of mode test for setting outerposition property.
+	(figure::figure_properties::set): If setting visible property,
+	make this figure the current figure.
+	(gh_manager::figure_handle_list, gh_manager::do_figure_handle_list):
+	New functions.
+	(F__go_figure_handles__): New function.
+
+	* sysdep.cc (Fpause): Also call drawnow if nargin == 0.
+	(Fkbhit, Fsleep, Fusleep): Also call drawnow here.
+
+2007-03-20  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun): Correct for shape of return
+	matrix for the case of UniformOutput being true.
+
+2007-03-20  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc (Fpause): Call drawnow.
+
+2007-03-15  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (F__lock_global__): Delete.
+
+2007-03-14  John W. Eaton  <jwe at octave.org>
+
+	* graphics.cc: New file.
+	* Makefile.in (DIST_SRC): Add it to the list.
+
+2007-03-13  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (do_stream_open): Use binary mode if 't' is not
+	specified in mode, but don't add 'b' if it is already present.
+
+2007-03-09  David Bateman  <dbateman at free.fr>
+
+	* data.cc (do_cat):  Also treat case of all empty matrices.
+
+2007-03-08  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_octave_value::set_dimensions,
+	mxArray_octave_value::set_m, mxArray_octave_value::set_n, 
+	mxArray_octave_value::set_class_name,
+	mxArray_octave_value::set_ir, mxArray_octave_value::set_jc,
+	mxArray_octave_value::remove_field,
+	mxArray_octave_value::set_field_by_number):
+	Don't panic; request mutation instead.
+	(class mxArray_octave_value): 
+
+	* mxarray.h (mxArray::set_m, mxArray::set_n,
+	mxArray::set_dimensions): Wrap method call call with
+	DO_VOID_MUTABLE_METHOD.
+
+2007-03-08  David Bateman  <dbateman at free.fr>
+
+	* data.cc (do_cat): Ignore leading empty matrices.
+
+2007-03-07  Bob Weigel  <rweigel at gmu.edu>
+
+	* urlwrite.cc (urlget): Allow URL redirects.
+
+2007-03-05  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/md5sum.cc (Fmd5sum): Treat both files and strings.
+
+2007-03-05  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Check GLPK_PRE_4_14, not
+	GLPK_PRE_4_15.
+
+2007-03-02  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (Fautoload): Undo previous change.
+	Warn if FILE is not an absolute file name.
+
+	* utils.cc (make_absolute): Make copy of arg before 
+
+2007-03-01  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-mat.h	(octave_base_matrix::octave_base_matrix (const MT&), 
+	(octave_base_matrix::octave_base_matrix (const MT&, const MatrixType&)):
+	Use common definition with default argument value.
+	* ov-base-scalar.h (octave_base_scalar<T>::typ): New data member.
+	Initialize in constructors.
+	(octave_base_scalar<T>::matrix_type): New funtions.
+
+2007-03-01  David Bateman  <dbateman at free.fr>
+
+        * DLD-FUNCTIONS/md5sum.cc: New file.
+        * Makefile.in (DLD_XSRC): Add md5sum.cc
+
+2007-03-01  Olli Saarela  <Olli.Saarela at kcl.fi>
+
+	* input.cc (FPS1): Fix @seealso.
+
+2007-03-01  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Special case scalar
+	types and always return "Full" matrix type.
+
+2007-02-28  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (interactive_input): Also call flush_octave_stdout
+	after calling drawnow.
+
+2007-02-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (uninstall): Also remove octave-$(version)$(EXEEXT), 
+	oct-gperf.h, and all .oct files.  Remove PKG_ADD.
+	From Thomas Treichl <Thomas.Treichl at gmx.net>.
+
+	* load-path.h, (load_path::initialize, load_path::do_initialize):
+	New arg, set_initial_path.
+	* load-path.cc (load_path::do_initialize): Don't add system
+	directories to apth if set_initial_path is false.
+	* octave.cc (set_initial_path): New static variable.
+	(NO_INITIAL_PATH_OPTION): New define.
+	(usage_string): Include --no-initial-path in message.
+	(long_opts): Include no-initial-path/NO_INITIAL_PATH_OPTION here.
+	(octave_main): Handle NO_INITIAL_PATH_OPTION.
+	Pass set_initial_path to load_path::initialize.
+
+	* parse.y (Fautoload): Warn about duplicate entries.  Only insert
+	the first found.
+
+2007-02-27  David Bateman  <dbateman at free.fr>
+
+	* error.cc (Vlast_error_file, Vlast_erro_name, Vlast_error_row,
+	Vlast_error_column): New static variables.
+	(verror): Use them to store the location of last error.
+	(rethrow_error, Frethrow, Flasterror): New functions.
+
+        * DLD-FUNCTIONS/regexp.cc (octcellregexp): Wrapper to octregexp
+        function for cases when string or pattern are cell arrays
+        (Fregexp, Fregexpi): Use them.
+        (octregexprep): New function with functionality of old Fregexprep.
+        (Fregexprep): Treat cell arguments.
+
+2007-02-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Use $(LN_S) instead of ln or ln -s.
+
+	* DLD-FUNCTIONS/getrusage.cc: Undef min after including windows.h.
+
+2007-02-25  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/interpn.cc: Include dNDArray.h, not dMatrix.cc.
+
+	* error.h: Include cstdarg.
+	From Juhani Saastamoinen <juhani at cs.joensuu.fi>.
+
+2007-02-23  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (lookup_function): Don't dereference NULL
+	curr_parent_fucntion pointer.
+	* ov-fcn-handle.cc (make_fcn_handle): Call lookup_function with
+	parent set to empty string if call_stack is empty.
+
+	* DLD-FUNCTIONS/dispatch.cc (Fbuiltin): Also adjust argument list
+	in calls to functions that are not overloaded.  Call
+	lookup_by_name to find function instead of searching fbi_symtab
+	directly.
+
+	* help.cc (do_which): Return empty string if file not found.
+
+2007-02-22  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_cell::mxArray_cell (const mxArray_cell&),
+	mxArray_struct::mxArray_struct (const mxArray_struct&)):
+	Avoid calling clone on 0 elements.
+
+	* variables.cc (symbol_out_of_date): If checking nested function,
+	look for file using parent function name.  Delete unused
+	variable NAMES.
+
+	* src/oct-stream.cc (octave_stream::do_gets): If no limit or not
+	at limit, read ahead one character at end of line for compatibility.
+	(octave_stream::gets, octave_stream::getl): Set max_len to -1 if
+	tc_max_len is not defined.
+	* file-io.cc (Ffgets, Ffgetl): If no limit specified, pass
+	undefined octave_value object as max_len in call to
+	octave_stream::gets.
+
+2007-02-21  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mexErrMsgIdAndTxt, mexWarnMsgIdAndTxt): Handle second
+	arg as format and accept variable number of arguments.
+	* mexproto.h: Fix decls.
+
+	* error.h, error.cc (vmessage, vusage, vwarning, verror,
+	vparse_error, vmessage_with_id, vusage_with_id, vwarning_with_id,
+	verror_with_id, vparse_error_with_id): Provide va_list versions of
+	variadic error, warning, and message functions.
+	(message, usage, warning, error, parse_error, message_with_id,
+	usage_with_id, warning_with_id, error_with_id,
+	parse_error_with_id): Call va_list versions.
+
+	* DLD-FUNCTIONS/urlwrite.cc (Furlwrite, Furlread): Return error
+	code and message instead of throwing error if functionality is
+	missing.
+
+	* oct-obj.h (octave_value_list::splice): Set default for
+	replacement list argument.
+
+2007-02-20  Rafael Laboissiere  <rafael at laboissiere.net>
+
+	* DLD-FUNCTIONS/__glpk__.cc: Adapt code for changes in the GLPK
+	API for version 4.15 or later.
+
+2007-02-20  John W. Eaton  <jwe at octave.org>
+
+	* mxarray.h (mxArray::get_scalar): New function.
+	* mex.cc (mxArray_base::get_scalar): New pure virtual function.
+	(mxArray_octave_value::get_scalar, mxArray_matlab::get_scalar,
+	mxArray_number::get_scalar): New functions.
+	(mxGetScalar): Call get_scalar here.
+
+	* mex.cc (mxArray_octave_value::get_dimensions): Cache ndims here.
+	(mxArray_octave_value::get_number_of_dimensions):
+	Call get_dimensions here to cache both ndims and dims.
+
+2007-02-17  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_out_of_date): Don't exit early if looking
+	at nested function.
+
+2007-02-16  John W. Eaton  <jwe at octave.org>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_oct): Clear
+	function if original was loaded from relative path and the name
+	can no longer be found in path.  Mark files found from relative
+	path as relative.
+	(clear): Only warn if there is more than one function to clear.
+
+	* variables.cc (symbol_out_of_date): Don't ignore return value in
+	call to octave_env::make_absolute.
+	(symbol_out_of_date): Clear symbol if original was loaded from
+	relative path and name can no longer be found in path.
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_oct):
+	Also check whether new file is same as the old file.
+
+	* utils.cc (same_file): Move here from variables.cc.
+	* utils.h: (same_file): Provide decl.
+
+	* parse.y (frob_function): Stash parent function name if parsing
+	nested function.
+
+	* ov-fcn-handle.cc (make_fcn_handle): Pass current function name
+	as parent in call to lookup_function.
+
+	* ov-fcn.h (octave_function::parent_fcn_name): New virtual function.
+
+	* ov-usr-fcn.h (octave_user_function::parent_name): New data member.
+	(octave_user_function::stash_parent_function_name,
+	octave_user_function::parent_function_name): New methods.
+	* ov-usr-fcn.cc (octave_user_function::octave_user_function):
+	Initialize parent_name.
+
+	* variables.h, variables.cc (lookup_function): New arg, parent.
+	If not empty, try this first for lookup.
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_mex): If doing
+	path lookup, check relative status. Pass relative to oct_file_in_path.
+	(octave_dynamic_loader::do_load_mex): Likewise, for mex_file_in_path
+
+	* defun-int.h, defun.cc (install_mex_function): New arg, relative.
+	(install_dld_function): Likewise.
+	(octave_dld_fcn_installer): Likewise.
+	(DEFINE_FUNX_INSTALLER_FUN3): Pass relative to install_dld_function.
+
+	* dynamic-ld.h (octave_dynamic_loader::load_oct,
+	octave_dynamic_loader::load_mex,
+	octave_dynamic_loader::do_load_oct
+	octave_dynamic_loader::do_load_mex): New arg, relative.
+
+	* dirfns.h (Vcurrent_directory): Delete unused variable.
+
+	* variables.cc (symbol_out_of_date): Also compare function time
+	stamp to Vlast_chdir_time if function is from relative lookup.
+
+	* dirfns.cc (Vlast_chdir_time): New variable.
+	(octave_change_to_directory): Update it if chdir succeeds.
+	* dirfns.h (Vlast_chdir_time): Provide decl.
+
+	* ov-fcn.h (octave_function::relative): New data member.
+	(octave_function::mark_relative, octave_function::is_relative):
+	New functions.
+
+	* parse.y (fcn_file_from_relative_lookup): New static variable.
+	(load_fcn_from_file): Note whether function file was found from
+	relative path element.
+	(frob_function): Maybe mark function as relative.
+
+	* parse.y (lookup_autoload): Don't call octave_env::make_absolute
+	on return value.
+	* variables.cc (symbol_out_of_date): Make name absolute after call
+	to lookup_autoload.
+
+	* input.cc (interactive_input): New arg, DEBUG.  Don't call
+	drawnow if debugging.
+	(get_user_input): Pass DEBUG to interactive_input.
+
+2007-02-16  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* syscalls.cc (Fpopen2): New function.
+	(pipe): Modify to return input and output file descriptor
+	seperately rather than in a list.
+	
+2007-02-16  Muthiah Annamalai  <muthuspost at gmail.com>
+
+	* debug.cc (Fdbtype): Improve compatibility.
+
+2007-02-16  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (wait_for_input): New function.
+	(run_command_and_return_output): Use it instead of napping.
+
+	* oct-procbuf.h (octave_procbuf::pid): Now const.
+	* procstream.h (procstreambase::pid): Now const.
+	(procstreambase::file_number): New function.
+
+2007-02-15  John W. Eaton  <jwe at octave.org>
+
+	* mxarray.h (mxChar): Use char instead of unsigned short.
+
+	* toplev.cc (Foctave_config_info): Remove
+	OCTAVE_CONF_MKOCTFILE_INCFLAGS and OCTAVE_CONF_MKOCTFILE_LFLAGS
+	from the list.
+	* oct-conf.h.in (OCTAVE_CONF_MKOCTFILE_INCFLAGS,
+	OCTAVE_CONF_MKOCTFILE_LFLAGS): Don't define.
+	(OCTAVE_CONF_INCLUDEDIR, OCTAVE_CONF_OCTINCLUDEDIR,
+	OCTAVE_CONF_OCTLIBDIR, OCTAVE_CONF_PREFIX): New definitions.
+
+2007-02-14  Alexander Barth  <abarth at marine.usf.edu>
+
+	* DLD-FUNCTIONS/interpn.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2007-02-14  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (interactive_input): Check error_state after call to feval.
+
+2007-02-10  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream::rewind): Call seek (0, SEEK_SET)
+	instead of rep->rewind.
+	(octave_base_stream::rewind): Delete Function.
+	* oct-stream.h (octave_base_stream::rewind): Delete decl.
+
+2007-02-09  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (PAD): Adjust to change in write_mat5_tag.
+	(TAGLENGTH): Delete unused macro.
+
+	* ov-struct.cc (octave_struct::load_ascii,
+	octave_struct::load_binary, octave_struct::load_hdf5):
+	Delete obsolete attempt at backward compatibility.
+
+	* ls-mat5.cc (read_mat5_binary_element): Don't attempt to read
+	fieldnames if there are no fields.
+	(write_mat5_tag): Don't use small data element format if bytes == 0.
+
+	* ls-mat5.cc (read_mat5_binary_element): Always create a structure
+	that is at least 1x1.
+	* ov-struct.cc (octave_struct::load_ascii,
+	octave_struct::load_binary, octave_struct::load_hdf5): Likewise.
+
+2007-02-08  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* DLD-FUNCTIONS/__glpk__.cc: Include glplib.h if glpk.h does not.
+	Provide definitions for lib_set_fault_hook and lib_set_print_hook
+	if they are not defined.
+
+2007-02-07  John W. Eaton  <jwe at octave.org>
+
+	* defaults.cc (subst_octave_home):
+	Only substitute at beginning of string.
+
+	* ls-hdf5.cc (save_hdf5_empty): Use OCTAVE_LOCAL_BUFFER.
+	* ov-bool-mat.cc (octave_bool_matrix::save_hdf5,
+	octave_bool_matrix::load_hdf5): Likewise.
+	* ov-bool-sparse.cc (octave_sparse_bool_matrix::save_hdf5,
+	octave_sparse_bool_matrix::load_hdf5): Likewise.
+
+2007-02-07  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* ov-cell.cc (octave_cell::save_hdf5): Correct test for H5Dwrite
+	return value.
+
+2007-02-07  John W. Eaton  <jwe at octave.org>
+
+	* zfstream.cc (gzfilebuf::open_mode): Always append "b" to c_mode.
+
+	* toplev.cc (Foctave_config_info): Use struct for conf_info.
+	Call subst_octave_home on selected values when initializing map.
+	* defaults.cc (subst_octave_home): Now extern.
+	* defaults.h.in: Provide decl.
+
+2007-02-05  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_number::as_octave_value): Fake mxSINGLE_CLASS
+	by returning double-precision values.
+	(mxArray_sparse::as_octave_value): Clarify error message.
+
+	* ov-complex.h (octave_complex): Use std instead of OCTAVE_STD
+	since the latter was unconditionally defined to be std anyway.
+
+2007-02-05  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* ov-complex.h: Tag octave_complex class with OCTINTERP_API.
+
+2007-01-30  John W. Eaton  <jwe at octave.org>
+
+	* Merge of changes from graphics-branch:
+
+	2007-01-26  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__contourc__.cc: New function.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+	2007-01-25  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (Vdrawnow_requested): New static variable.
+	(F__request_drawnow__): New function.
+	(interactive_input): New function.  Update Vlast_prompt_time here.
+	(octave_gets, get_user_input, octave_yes_or_no):
+	Call interactive_input instead of gnu_readline.
+
+	* symtab.h (symbol_record::eternal): New data member.
+	(symbol_record::symbol_record): Initialize it.
+	(symbol_record::make_eternal, symbol_record::is_eternal):
+	Don't forward to symbol_def functions.
+	(symbol_record::symbol_def::make_eternal,
+	symbol_record::symbol_def::is_eternal): Delete.
+	(symbol_record::symbol_def::eternal): Delete data member.
+	(symbol_record::symbol_def::symbol_def): Delete initialization.
+
+	* pt-id.cc (tree_identifier::link_to_global): Include variable
+	name in warning message.
+
+	* variables.cc (F__lock_global__): New function.
+
+	2007-01-11  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.cc (save_ascii_data_for_plotting, save_three_d):
+	Set precision to 6 instead of 4.
+
+2007-01-29  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx): Don't panic if
+	nargout is greater than 3.
+
+2007-01-24  John W. Eaton  <jwe at octave.org>
+
+	* pt-assgn.cc (former_built_in_variables): New static data.
+	(maybe_warn_former_built_in_variable): New static function.
+	(tree_simple_assignment::tree_simple_assignment,
+	tree_multi_assignment::tree_multi_assignment):
+	Move definition here from pt-assign.h
+	Maybe warn about assignment to obsolete built-in variables.
+
+	* version.h (OCTAVE_STARTUP_MESSAGE): Mention "news" function.
+
+	* pt-stmt.cc (tree_statement::eval): Use dynamic_cast, not
+	static_cast.
+
+	* help.cc (help_from_file): Show .oct or .mex file name if one
+	exists in the same directory as the .m file.
+
+2007-01-23  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* strfns.cc (Fstrncmp): New function.
+
+2007-01-17  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (help_from_file, help_from_symbol_table, help_from_list):
+	Rewrite using raw_ versions.
+
+2007-01-17  David Bateman  <dbateman at free.fr>
+
+	* help.cc (raw_help, raw_help_from_file,
+	raw_help_from_symbol_table, raw_help_from_list): New functions.
+	* help.h (raw_help): Provide decl.
+
+2007-01-16  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__pchip_deriv__.cc: Fix dpchim decl for --enable-64.
+	(F__pchip_deriv__): Fix call to dpchim for --enable-64.
+
+	* DLD-FUNCTIONS/fftw.cc: Delete decl for fftw_planner.
+
+2007-01-11  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* load-path.h (class load_path): Tag with OCTINTERP_API.
+
+	* ls-oct-binary.cc (read_binary_data): Use unsigned char, not
+	char, for reading flags and data types.
+
+2007-01-10  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* parse.y (load_fcn_from_file): Delete unused variable NAMES.
+	If NM is absolute, strip directory and extension parts.
+
+2007-01-10  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* DLD-FUNCTIONS/getrusage.cc: Use #ifdef __WIN32__, not __MINGW32__.
+
+2007-01-10  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (load_fcn_from_file): Only compare last two characters
+	when looking for ".m".
+
+2007-01-06  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_CONFIG_STATEMENT): New macro
+	(OCTAVE_NAME_AND_VERSION): Remove config info.
+	(OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY):
+	Use OCTAVE_CONFIG_STATEMENT here.
+
+2007-01-05  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (DLD_XSRC): Add fftw.cc and remove fftw_wisdom.cc
+	* DLD-FUNCTIONS/fftw.cc: New file.
+	* DLD-FUNCTIONS/fftw_wisdom.cc: Delete.
+	* defaults.cc (Vfftw_wisdom_program): Delete variable.
+	(set_default_fftw_wisdom_prog): Delete function that sets it.
+	(install_defaults): Delete set_default_fftw_prog from defaults.
+	(Ffftw_wisdom_program): Delete.
+
+2007-01-04  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::load_ascii,
+	octave_fcn_handle::load_binary):
+	Throw error if handle can't be created.
+
+2007-01-04  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* mex.cc (mxArray_number::mxArray_number (int, const char **)):
+	Correctly index LHS in assignment.
+
+2007-01-03  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fisinteger): New function.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::is_integer_type,
+	OCTAVE_VALUE_INT_SCALAR_T::is_integer_type): New function.
+	* ov.h (octave_value::is_integer_type): New function.
+	* ov-base.h (octave_base_value::is_integer_type): New virtual function.
+
+2007-01-03  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* toplev.cc (Fsystem): Handle async calls on Windows systems.
+
+2007-01-03  David Bateman  <dbateman at free.fr>
+
+	* (OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc, 
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc, 
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc, 
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-scm-cs.cc, 
+	OPERATORS/op-scm-m.cc, OPERATORS/op-scm-s.cc, 
+	OPERATORS/op-scm-scm.cc, OPERATORS/op-scm-sm.cc, 
+	OPERATORS/op-sm-cm.cc, OPERATORS/op-sm-cs.cc, 
+	OPERATORS/op-sm-m.cc, OPERATORS/op-sm-s.cc, 
+	OPERATORS/op-sm-scm.cc, OPERATORS/op-sm-sm.cc, 
+	OPERATORS/op-s-scm.cc, OPERATORS/op-s-sm.cc):
+	Modify div and ldiv functions so that scalars stored as sparse 
+	matrices are special cased.
+
+	* ov-re-sparse.cc (double_value, complex_value): Scalar can be
+	stored as a sparse matrix and so don't warn on implicit conversion
+	to a scalar.
+	* ov-cx-sparse.cc (double_value, complex_value): ditto.
+	* ov-bool-sparse.cc (double_value, complex_value): ditto.
+
+2007-01-03  John W. Eaton  <jwe at octave.org>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_mex): Also check
+	for _mexFunction.
+
+2006-12-30  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-inline.cc: For compatibility, class id is
+	"function_handle", not "inline function".
+
+2006-12-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (%.df : %.cc): Insert a "do not edit" notice in the
+	.df files.
+
+	* mex.cc (mxArray_matlab::get_class_name,
+	mxArray_octave_value::get_class_id): Use "function_handle", not
+	"function handle".
+
+2006-12-14  John W. Eaton  <jwe at octave.org>
+
+	* pt-decl.cc (tree_decl_elt::eval): New function.
+	* pt-decl.h (tree_decl_elt::eval): Provide decl.
+	(tree_decl_elt::is_defined, tree_decl_elt::lvalue_ok, 
+	tree_decl_elt::mark_as_formal_parameter, tree_decl_elt::rvalue,
+	tree_decl_elt::lvalue): New functions.
+
+	* pt-misc.h (class tree_parameter_list): Derive from
+	octave_base_list<tree_decl_elt *> instead of
+	octave_base_list<tree_identifier *>.
+	(tree_parameter_list::tree_parameter_list (tree_identifier *)): Delete.
+	(tree_parameter_list::tree_parameter_list (tree_decl_elt *)):
+	New function.
+	* pt-misc.cc (tree_parameter_list::mark_as_formal_parameters,
+	tree_parameter_list::initialize_undefined_elements,
+	tree_parameter_list::undefine, tree_parameter_list::dup,
+	tree_parameter_list::convert_to_const_vector,
+	tree_parameter_list::is_defined): Handle argument list elements
+	as tree_decl_list objects instead of tree_identifier objects.
+	(tree_parameter_list::define_from_arg_vector): Likewise.
+	Always process entire list, setting default values if possible.
+	Accept ":" to mean "use default argument".
+
+	* parse.y (param_list2): Use decl2 to recognize
+	"identifier '=' expression" in addition to "identifier".
+
+	* parse.y (return_list1, make_anon_fcn_handle, finish_function):
+	Adapt to new definition of tree_parameter_list.
+	* pt-bp.cc (tree_breakpoint::visit_parameter_list): Likewise.
+	* pt-check.cc (tree_checker::visit_parameter_list): Likewise.
+	* pt-pr-code.cc (tree_print_code::visit_parameter_list): Likewise.
+
+2006-12-08  John W. Eaton  <jwe at octave.org>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::array_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::complex_array_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::bool_array_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::char_array_value):
+	Use fortran_vec to avoid expensive indexing operator.
+
+2006-12-08  David Bateman  <dbateman at free.fr>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_SCALAR_T::matrix_value,
+	OCTAVE_VALUE_INT_SCALAR_T::complex_matrix_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::matrix_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::comlex_matrix_value): New functions.
+	(OCTAVE_VALUE_INT_MATRIX_T::array_value, 
+	OCTAVE_VALUE_INT_MATRIX_T::comlex_array_value):
+	Use octave_idx_type instead of int for indexing.
+
+2006-12-04  David Bateman  <dbateman at free.fr>
+
+	* xpow.cc (xpow (const Matrix&, double)): Add matrix type probing
+        to matrix inverse.
+        (xpow (const ComplexMatrix&, double)): ditto.
+        * DLD-FUNCTIONS/inv.cc (Finv): Add matrix type probing.
+
+2006-12-06  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc: Include "Cell.h" here.
+	* input.h: Include "oct-obj.h", not "ov-list.h".
+
+2006-12-06  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* mappers.cc (install_mapper_functions): Undefine isascii before
+	the DEFUN_MAPPER for it.
+
+	* input.cc (get_user_input): Prevent out of bounds array access
+	when checking for EOL.
+
+2006-12-05  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.cc (extract_keyword): If no match and looking for
+	more, skip to end of line before trying another match.
+
+	* pt-mat.cc (tm_row_const::empty): New function.
+	(tm_const::init): Don't append anything if tmp tm_row_const object
+	is empty.
+	(tree_matrix::rvalue): Default return value is Matrix().
+	Don't do anything if tmp tm_const object is empty.
+
+	* dirfns.cc (Fmkdir): Fix thinko in previous change.
+
+2006-12-05  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* DLD-FUNCTIONS/rand.cc: Test for Poisson generator with lambda > 1e8.
+
+2006-12-04  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Fdata): If ndims is greater than nargout and
+	nargout is greater than 1, then collect size of trailing
+	dimensions into retval(end).
+
+	* load-path.cc (load_path::do_find_fcn): Return empty string if
+	tests fail.
+
+        * ov-base-mat.cc (void octave_base_matrix<MT>::assign (const
+	octave_value_list&, const MT&)): Invalidate matrix type on
+	assignment.
+
+2006-11-30  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fftw_wisdom.cc (Ffftw_wisdom):
+	Accept "r" or "w" for second argument.
+
+2006-11-29  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/fftw_wisdom.cc (Ffftw_wisdom): Look in load-path
+	if reading wisdom file, but not if writing.
+
+2006-11-28  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_struct::get_field_by_number):
+	Return 0 if key_num is out of range.
+	(mxArray_struct::set_field_by_number):
+	Do nothing if key_num is out of range.
+	(mxArray_cell::get_cell, mxArray_cell::set_cell):
+	Avoid out-of-bounds indexing
+
+2006-11-28  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* mex.cc (mxArray_matlab::get_n, mxArray_octave_value::get_n):
+	Return product of last N-1 dims.
+
+2006-11-28  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (eat_whitespace): Also handle CRLF as EOL.
+
+	* dirfns.cc (Fmkdir): Handle "mkdir (parent, dir)".
+
+2006-11-21  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (load_path::do_find_file,
+	load_path::do_find_first_of, load_path::do_find_all_first_of): 
+	Call rooted_pathname instead of absolute_pathname.
+	* utils.cc (fcn_file_in_path, oct_file_in_path, mex_file_in_path):
+	Likewise.
+
+2006-11-16  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* oct-hist.cc (default_history_file): Instead of appending
+	"/.octave_hist", append directory separator (but only if
+	necessary), then ".octave_hist".
+
+2006-11-16  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fresize): Fix doc string.
+
+2006-11-15  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (write_data, write_inline_data):
+	New functions.
+	(save_in_tmp_file): Use write_data.
+	(gnuplot::send_inline_data, gnuplot_do_send_inline_data):
+	New functions.
+	(F__gnuplot_send_inline_data__, F__gnuplot_save_data__):
+	New functions.
+
+	* ls-oct-ascii.cc (save_ascii_data_for_plotting):
+	Call save_ascii_data with precision = 4.
+	(save_three_d): Temporarily set precision to 4 for output stream.
+
+2006-11-15  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Cell.h (Cell): Tag class with OCTINTERP_API.
+
+2006-11-13  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (maximum_braindamage): Disable
+	Octave:fopen-file-in-path and Octave:load-file-in-path warnings.
+
+	* load-save.cc (find_file_to_load): New function.
+	(Fload): Call find_file_to_load to search load path for file.
+
+	* file-io.cc (Ffopen): Search load path for file.
+
+	* load-path.cc (path::do_find_first_of, path::do_find_file):
+	Break out of all loops once file is found, not just innermost one.
+
+	* data.cc (Fsize_equal): New function.
+
+2006-11-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* ov.cc (check_subsref_elements, Fsubsref, Fsubsasgn):
+	New functions.
+
+	* ov-re-mat.h, ov-scalar.h, pr-output.h:
+	Sprinkle with OCTINTERP_API as needed.
+
+2006-11-11  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (parse.cc): Avoid creating empty files.
+	(%.df : %cc, builtins.cc, mkbuiltins, PKG_ADD, DOCSTRINGS,
+	doc-files, gendoc.cc, ops.cc, $(OPT_HANDLERS), oct-errno.cc,
+	oct-gperf.h): Use $(simple-move-if-change-rule) here.
+	(lex.cc, __gnuplot_raw__.cc):
+	Use $(destdir-move-if-change-rule) here.
+	(ifndef omit_deps): Don't include stamp-prereq here.
+	($(DEF_FILES), $(MAKEDEPS)): Also depend on stamp-prereq.
+
+2006-11-10  John W. Eaton  <jwe at octave.org>
+
+	* ov-str-mat.cc (octave_char_matrix_str::load_ascii,
+	octave_char_matrix_str::load_binary):
+	Use chMatrix as buffer instead of C string.
+
+2006-11-09  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr-fcn.h (octave_user_function::inline_function):
+	 New data member.
+	(octave_user_function::mark_as_inline_function): Set it.
+	(octave_user_function::is_inline_function): Check it.
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Also skip setting curr_parent_fucntion if evaluating an inline
+	function.
+	(octave_user_function::octave_user_function):
+	 Initialize inline_function.
+	* pt-fcn-handle.cc (tree_anon_fcn_handle::rvalue):
+	Mark user function as inline here.
+
+2006-11-09  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* load-path.cc (load_path::move): Don't use reference to file_info
+	object that will be erased.
+
+2006-11-07  John W. Eaton  <jwe at octave.org>
+
+	* utils.cc (file_in_path): Don't unconditionally return "".
+
+	* pager.cc (default_pager): Don't append options here.
+	(pager_command): New function.
+	(do_sync): Use it.
+	(VPAGER_FLAGS): New variable.
+	(FPAGER_FLAGS): New function.
+
+2006-11-06  John W. Eaton  <jwe at octave.org>
+
+	* oct-hist.cc (default_history_file): If env_file is not empty,
+	just accept it rather than checking to see if it exists.
+
+2006-11-03  Bill Denney  <denney at seas.upenn.edu>
+
+	* help.cc (keywords): Document try and unwind_protect.
+
+2006-11-03  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DLL_CXXDEFS): Rename from XTRA_CXXDEFS.
+	(DLL_CDEFS): Rename from XTRA_CDEFS.
+	Substitute OCTINTERP_DLL_DEFS, not XTRA_OCTINTERP_DEFS.
+
+2006-11-02  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* sysdep.cc (MSVC_init): Also cal w32_sigint_init and
+	w32_set_quiet_shutdown.
+
+2006-11-01  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (octave_value::idx_type_value): New function.
+	* data.cc (fill_matrix, Flinspace, Freshape): Use idx_type_value
+	instead of int_value to extract size args.
+
+2006-10-31  John W. Eaton  <jwe at octave.org>
+
+	* ov-range.h (octave_range::empty_clone): Return octave_matrix
+	object instead of octave_range.
+
+2006-10-29  Juhani Saastamoinen  <juhani at cs.joensuu.fi>
+
+	* ls-mat5.cc (read_mat5_tag): Declare bytes as int32_t, not just int. 
+
+2006-10-28  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (Fatexit): Push function names on the stack even if we
+	don't have atexit or on_exit.
+
+2006-10-28  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* mappers.cc (install_mapper_functions): Undefine toascii before
+	the DEFUN_MAPPER for it.
+
+2006-10-27  John W. Eaton  <jwe at octave.org>
+
+	* mexproto.h: Include oct-dlldefs.h.
+
+	* pr-output.cc (SPECIALIZE_UABS): New macro.
+	Use it to generate specializations of abs for unsigned int types.
+	Instantiate abs for signed int types.
+
+	* load-path.cc (load_path::do_initialize):
+	Use dir_path::path_sep_str instead of ":".
+	Don't append ":::" to xpath when calling do_set.
+
+	* dirfns.cc (Fls, cleanup_iprocstream): Delete.
+
+	* sysdep.cc (Ftilde_expand): If arg is cellstr, return cellstr.
+
+	* ov.h (octave_value::is_cellstr): New function.
+	* ov-base.h (octave_base_value::is_cellstr): New function.
+	* ov-cell.h (octave_cell::is_cellstr): New function.
+	* ov-cell.cc (Fiscellstr): Implement with is_cellstr.
+	* Cell.cc (Cell::Cell (const dim_vector&, const string_vector&, bool)): 
+	New constructor.
+	(Cell::is_cellstr): New function.
+	* Cell.h: Provide decls.
+
+	* defaults.cc (subst_octave_home): If dir_sep_char is not '/',
+	replace before returning.
+	From Michael Goffioul <michael.goffioul at swing.be>.
+
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* cutils.c (octave_strcasecmp, octave-strncasecmp):
+	Move to liboctave/lo-cutils.c.
+	* utils.h: Delete decls.
+	* strcasecmp.c: Move to liboctave/strcasecmp.c.
+	* strncase.c: Move to liboctave/strncase.c.
+	* Makefile.in (DIST_SRC): Delete them from the list.
+
+	* bitfcns.cc (bitshift): If A < 0, return -bitshift (-A, N, MASK).
+
+2006-10-26  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* help.cc (display_help_text): Quote sed patterns with ".
+
+	* file-io.cc: Include file-io.h.
+
+	* TEMPLATE-INST/Array-os.cc, TEMPLATE-INST/Array-sym.cc,
+	TEMPLATE-INST/Array-tc.cc, defun-int.h, error.h, file-io.h,
+	gripes.h, ls-oct-ascii.h, mexproto.h, oct-map.h, oct-obj.h,
+	oct-stream.cc, oct-stream.h, octave.h, ov-base.h,
+	ov-bool-sparse.cc, ov-bool-sparse.h, ov-cx-sparse.cc,
+	ov-cx-sparse.h, ov-fcn.h, ov-re-sparse.cc, ov-re-sparse.h,
+	ov-str-mat.h, ov-typeinfo.cc, ov-typeinfo.h, ov.h, pager.h,
+	parse.h, pr-output.cc, pr-output.h, procstream.h, sighandlers.h,
+	symtab.h, unwind-prot.h, utils.h, variables.h:
+	Sprinkle with OCTINTERP_API as needed.
+
+2006-10-26  John W. Eaton  <jwe at octave.org>
+
+	* ov-bool.h (octave_bool::sparse_matrix_value,
+	octave_bool::sparse_complex_matrix_value
+	octave_bool::sparse_bool_matrix_value): New functions.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* sighandlers.cc: Check defined (RETSIGTYPE_IS_VOID) instead of
+	RETSIGTYPE == void.
+
+	* oct-procbuf.cc (BUFSIZ): Define if not already defined.
+	(octave_procbuf::open): Pass BUFSIZ as size argument to setvbuf.
+
+2006-10-25  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in (XTRA_CDEFS, XTRA_CXXDEFS): Substitute here.
+
+	* oct-procbuf.cc [_MSC_VER]: Define W32POPEN and W32PCLOSE the
+	same as for __MINGW32__.
+	(octave_procbuf::open, octave_procbuf::close) [_MSC_VER]:
+	Use the same code as for __MINGW32__ and __CYGWIN__.
+
+	* oct-prcstrm.cc [_MSC_VER]: Define popen and pclose.
+
+2006-10-25  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc (w32_set_octave_home): Correctly initialize bin_dir.
+	Fill it with '\0' instead of ' '.
+
+2006-10-24  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Filter out $(XTRA_CXXDEFS) from $(ALL_CXXFLAGS) for
+	$(DLD_PICOBJ).
+
+2006-10-24  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.cc (MSC_init): New function.
+	(sysdep_init): Call it.
+	(w32_set_octave_home): New function, based on code from Michael
+	Goffioul <michael.goffioul at swing.be>.
+	(MINGW_init): Call w32_set_octave_home here too.
+
+2006-10-23  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_table::clear_mex_functions): New function.
+	* symtab.h: Provide decl.
+	* vriables.cc (clear_mex_functions): New function.
+	* variables.h Provide decl.
+	* toplev.cc: Call clear_mex_functions instead of delete_symbol_tables.
+
+	* variables.cc (delete_symbol_tables): Delete.
+	* variables.h: Delete decl.
+
+	* mex.cc (mex::unmark_array): New function.
+	(mex::persistent): Define with unmark_array.
+	(maybe_unmark_array): New function.
+	(mxArray_struct::set_field_by_number, mxArray_cell::set_cell):
+	Call maybe_unmark_array on val to avoid freeing val twice on exit
+	from mex function.
+	(mxFree): Call xfree, not free.
+
+2006-10-21  John W. Eaton  <jwe at octave.org>
+
+	* ov-intx.h
+	(OCTAVE_VALUE_INT_MATRIX_T::OCTAVE_TYPE_PREDICATE_FUNCTION,
+	(OCTAVE_VALUE_INT_SCALAR_T::OCTAVE_TYPE_PREDICATE_FUNCTION):
+	Function is now const, so it properly overloads method in base
+	class.
+
+	* mex.cc (mxArray_octave_value::is_uint32):
+	Call val.is_uint32_type, not val.is_int32_type.
+	(mxArray_octave_value::is_uint64):
+	Call val.is_uint64_type, not val.is_int64_type.
+	(mxArray_octave_value::is_uint8):
+	Call val.is_uint8_type, not val.is_int8_type.
+
+2006-10-20  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* ov-mex-fcn.h (octave_mex_function::atexit): New function.
+	(octave_mex_function::exit_fcn_ptr): New data member.
+	* ov-mex-fcn.cc (octave_mex_function::exit_fcn_ptr): New data member.
+	(octave_mex_function::octave_mex_function): Initialize it.
+	(octave_mex_function::~octave_mex_function):
+	If we have an exit function, call it.
+
+2006-10-20  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (delete_symbol_tables): New function.
+	* variables.h: Provide decl.
+	* toplev.cc (do_octave_atexit): Call it.
+
+	* mex.cc (mex::mex): New arg, a pointer to the current mex function.
+	(mex::curr_mex_fcn): New data member.
+	(mex::current_mex_function): New function.
+	(mexAtExit): Set exit function pointer in current mex file object.
+
+2006-10-20  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* mex.cc (enum callstyle): Delete enum definition.
+	(Fortran_mex, C_mex): Delete functions.
+	(call_mex): First arg is now bool.
+	* ov-mex-fcn.cc (call_mex): Fix decl to match new definition.
+	(Fortran_mex, C_mex): Delete decls.
+	(octave_mex_function::do_multi_index_op): Simplify call to call_mex.
+
+2006-10-20  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (handle_identifier): If a command name is found, skip
+	starting command mode if parsing an object index.
+
+2006-10-20  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTION/spqr.cc (dmperm_internal): New function with core
+	of Fdmperm.
+	(Fdmperm): Call dmperm_internal rather then calculating loally.
+	(Fsprank): New function to calculate the strutural rank also using
+	dmperm_internal.
+
+2006-10-19  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::as_mxArrary):
+	Use OCTAVE_LOCAL_BUFFER to allocate tempoarary array of field names.
+
+	* mxarray.h (mxArray::persistent): Delete var and all uses.
+	(mxArray::mark_persistent, mxArray::unmark_persistent,
+	mxArray::is_persistent): Delete functions.
+	* mex.cc (mex::function_name): Use mxArray::strsave, not strsave.
+	(mex::mark_array): New function.
+	(mex::make_value): Use it.
+	(mex::free_value): Return true if we found ptr in arraylist.
+	(mex::persistent (mxArray *)): Remove ptr from arraylist instead
+	of marking it as persistent.
+	(mxArray::malloc): Call ::malloc instead of malloc.
+	(mxArray::calloc): Call ::calloc instead of calloc.
+	(maybe_mark_array): New function.
+	(mxCreateCellArray, mxCreateCellMatrix, mxCreateCharArray,
+	mxCreateCharMatrixFromStrings, mxCreateDoubleMatrix,
+	mxCreateDoubleScalar, mxCreateLogicalArray, mxCreateLogicalMatrix,
+	mxCreateLogicalScalar, mxCreateNumericArray,
+	mxCreateNumericMatrix, mxCreateSparse,
+	mxCreateSparseLogicalMatrix, mxCreateString, mxCreateStructArray,
+	mxCreateStructMatrix, mxDuplicateArray): Use it.
+	(mxDestroyArray): No need to check persistence now.
+	Also delete ptr if mex_context->free_value does not.
+	(call_mex): No need to delete elements of argout now.
+
+2006-10-18  John W. Eaton  <jwe at octave.org>
+
+	* dynamic-ld.cc (octave_shlib_list::remove,
+	octave_shlib_list::do_remove, octave_mex_file_list::remove,
+	octave_mex_file_list::do_remove): New arg, cl_hook.
+	(octave_shlib_list::do_remove): Pass cl_hook to octave_shlib close
+	function.
+	(octave_dynamic_loader::do_load_oct): Don't call close on shl
+	directly.  Pass do_clear_function to octave_shlib_list::remove.  
+
+	* mex.cc (mexUnlock): Don't warn if unlocking a function that is
+	not locked.
+
+	* pt-fcn-handle.cc (tree_anon_fcn_handle::dup):
+	Correctly duplicate symbol table info.
+
+2006-10-17  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* oct-map.h: Include <algorithm>.
+
+2006-10-16  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream_list::do_remove): Handle "all" as a
+	special case.
+
+2006-10-13  Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Adapt rules to use $(LIBPRE).
+
+2006-10-11  John W. Eaton  <jwe at octave.org>
+
+	* mex.h (UINT64_T, uint64_T, INT64_T, int64_T, UINT32_T, uint32_T,
+	INT32_T, int32_T, UINT16_T, uint16_T, INT16_T, int16_T, UINT8_T,
+	uint8_T, INT8_T, int8_T): Conditionally define.
+	From Andy Adler <adler at site.uottawa.ca>.
+
+2006-10-09  John W. Eaton  <jwe at octave.org>
+
+	* oct-conf.h.in (OCTAVE_CONF_CURL_LIBS): Substitute.
+	* toplev.cc (octave_config_info): Add CURL_LIBS to the list.
+
+2006-10-09  Alexander Barth  <abarth at marine.usf.edu>
+
+	* DLD-FUNCTIONS/urlwrite.cc: New file providing urlwrite and urlread.
+
+2006-10-09  John W. Eaton  <jwe at octave.org>
+
+	* pt-mat.cc (tree_matrix::dup): Append new elements to new matrix.
+	* pt-cell.cc (tree_cell::dup): Append new elements to new cell array.
+
+2006-10-04  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.9+.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (F__clear_plot_window__):
+	Rename from Fclearplot.  Only clear plot window.
+
+2006-10-03  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/luinc.cc (Fluinc): Avoid crash if SparseLU or
+	SparseComplexLU constructor fails.
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx):
+	Delete unused variable.
+
+2006-10-03  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (OCT_LINK_DEPS) Include $(CAMD_LIBS) in the list.
+	(octave$(EXEEXT)): Include $(CAMD_LIBS) in link command.
+
+2006-10-02  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.9.
+	(OCTAVE_API_VERSION): Now api-v22.
+	(OCTAVE_RELEASE_DATE): Now 2006-10-02.
+
+	* pr-output.cc (pr_plus_format): Use "inline" instead of "static
+	inline" for template functions to avoid problems when not
+	compiling with 	g++.
+
+	* mex.cc (call_mex): Delete elements of argout.
+	From Kai Labusch <labusch at inb.uni-luebeck.de>.
+
+2006-09-29  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/spfind.cc (sparse_find_non_zero_elem_idx):
+	Leading dimension is NR, not NC.
+
+	* Makefile.in (DEP_5): Include oct-errno.cc in the list.
+
+2006-09-27  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (abs): New template function.  Instantiate for
+	unsigned types.
+
+2006-09-27  David Bateman  <dbateman at free.fr>
+
+	* file-io.cc (Fsprintf): If fmt is an sq_string, return an sq_string.
+
+	* DLD-FUNCTIONS/sparse.cc (spfind, sparse_find): Delete.
+	* DLD-FUNCTIONS/spfind.cc: New file implementating compatible
+	sparse find function.
+	* Makefile.in (DLD_XSRC): Add spfind.cc.
+	
+2006-09-26  Bill Denney  <bill at givebillmoney.com>
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx, Ffind):
+	Handle direction and limit on number of elements to find.
+
+2006-09-26  John W. Eaton  <jwe at octave.org>
+
+	* error.cc (warning_1): Call error_2, not error.
+
+2006-09-15  John W. Eaton  <jwe at octave.org>
+
+	* ops.h (DEFSTRDBLCONVFN): New arg, TFROM.
+	* OPERATORS/op-double-conv.cc: Declare and install sq_string
+	conversions too.
+
+	* ov-base-int.cc (octave_base_int_scalar<T>::convert_to_str_internal,
+	octave_base_int_matrix<T>::convert_to_str_internal):
+	New functions.
+	* ov-base-int.h: Provide decls.
+
+2006-09-15  Søren Hauberg  <soren at hauberg.org>.
+
+	* data.cc (Fsize): If nargout > ndims, fill with 1.
+
+2006-09-15  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc: Fix xerbla decl.
+
+2006-09-13  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/cellfun.cc: Improve error message for uniform
+	output case when results are not scalars.  Avoid shadow decls.
+
+2006-09-13  David Bateman  <dbateman at free.fr>
+
+	* ov-scalar.h (octave_scalar::sparse_matrix_value,
+	octave_scalar::sparse_complex_matrix_value): New extractor functions.
+	* ov-complex.h (octave_complex::sparse_matrix_value,
+	octave_complex::sparse_complex_matrix_value): Ditto.
+	* DLD-FUNCTIONS/spkron.cc (Fspkron): Change example in help.
+
+2006-09-12  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun): Allow matlab compatiable
+	'UniformOutput' and 'ErrorHandler' options.  Change output when
+	called with function handler or inline function to by default have
+	'UniformOutput' set to true.  Allow functions with multiple inputs
+	and outputs. Add test code.  Replace some int with octave_idx_type.
+	(Fnum2cell): Replace some int with octave_idx_type.  Add test code.
+	
+2006-09-11  Yozo Hida  <yozo at cs.berkeley.edu>
+
+	* DLD-FUNCTIONS/gcd.cc (Fgcd): Extend range by using std::floor
+	instead of converting to int.
+
+2006-09-05  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_sparse::as_octave_value): Cast nzmax to
+	octave_idx_type for sparse matrix constructors.
+
+2006-09-01  John W. Eaton  <jwe at octave.org>
+
+	* dirfns.cc: Don't handle nargout == 0 as a special case.
+	(octave_change_to_directory): Perform tilde expansion on directory
+	name here.
+
+2006-08-30  John W. Eaton  <jwe at octave.org>
+
+	* load-save.cc (get_file_format): Fix misplaced #endif.
+
+2006-08-29  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (execute_pkg_add_or_del):
+	Source PKG_ADD or PKG_DEL in base workspace.
+	* parse.y (source_file): New optional arg, context.
+	* parse.h (source_file): Fix decl.
+
+2006-08-25  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.8+.
+
+2006-08-24  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.8.
+	(OCTAVE_API_VERSION): Now api-v21.
+	(OCTAVE_RELEASE_DATE): Now 2006-08-24.
+
+2006-08-23  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (octave_value::save_ascii): Delete strip_nan_and_inf arg.
+	* ov-base.h, ov-base.cc (octave_base_value::save_ascii): Likewise.
+	* ov-base-int.h, ov-base-int.cc	(octave_base_int_matrix<T>::save_ascii,
+	octave_base_int_scalar<T>::save_ascii, ): Likewise.
+	* ov-base-sparse.cc, ov-base-sparse.h
+	(octave_base_sparse<T>::save_ascii): Likewise.
+	* ov-bool-mat.cc, ov-bool-mat.h (octave_bool_matrix::save_ascii):
+	Likewise.
+	* ov-bool.cc, ov-bool.h (octave_bool::save_ascii): Likewise.
+	* ov-cell.cc, ov-cell.h (octave_cell::save_ascii): Likewise.
+	* ov-complex.cc, ov-complex.h (octave_complex::save_ascii): Likewise.
+	* ov-fcn-handle.cc, ov-fcn-handle.h (octave_fcn_handle::save_ascii):
+	Likewise.
+	* ov-fcn-inline.cc, ov-fcn-inline.h (octave_fcn_inline::save_ascii):
+	Likewise.
+	* ov-list.cc, ov-list.h (octave_list::save_ascii): Likewise.
+	* ov-range.cc, ov-range.h (octave_range::save_ascii): Likewise.
+	* ov-scalar.cc, ov-scalar.h (octave_scalar::save_ascii): Likewise.
+	* ov-str-mat.cc, ov-str-mat.h (octave_char_matrix_str::save_ascii):
+	Likewise.
+	* ov-struct.cc, ov-struct.h (octave_struct::save_ascii): Likewise.
+	* ov-re-mat.cc, ov-re-mat.cc (octave_matrix::save_ascii): Likewise.
+	* ov-cx-mat.cc, ov-cx-mat.cc (octave_complex_matrix::save_ascii):
+	Likewise.
+	* ov-cx-mat.cc, ov-cx-mat.cc (octave_complex_matrix::save_ascii):
+	Likewise.
+	* ov-re-mat.cc, ov-re-mat.cc (octave_matrix::save_ascii): Likewise.
+
+	* ls-oct-ascii.cc, ls-oct-ascii.h (save_ascii_data):
+	Delete strip_nan_and_inf arg.
+	(save_ascii_data_for_plotting): Delete strip_nan_and_inf arg from
+	call to save_ascii_data.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (handle_using): Accept "(EXPR)"
+	as components of using clauses.
+	(enum _toktype): New element DOLLAR.
+	Accept "$" in lexer.
+
+	* ls-oct-ascii.cc (save_ascii_data): Delete arg strip_nan_and_inf.
+	Change all uses.
+
+	* ls-oct-ascii.h (save_three_d): Provide decl.
+	* load-save.h (save_ascii_data_for_plotting, save_three_d):
+	Delete decls.
+
+2006-08-22  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (octave_value::save_ascii): strip_nan_and_inf is now int,
+	not bool.
+	* ov-base.h, ov-base.cc (octave_base_value::save_ascii): Likewise.
+	* ov-base-int.h, ov-base-int.cc	(octave_base_int_matrix<T>::save_ascii,
+	octave_base_int_scalar<T>::save_ascii, ): Likewise.
+	* ov-base-sparse.cc, ov-base-sparse.h
+	(octave_base_sparse<T>::save_ascii): Likewise.
+	* ov-bool-mat.cc, ov-bool-mat.h (octave_bool_matrix::save_ascii):
+	Likewise.
+	* ov-bool.cc, ov-bool.h (octave_bool::save_ascii): Likewise.
+	* ov-cell.cc, ov-cell.h (octave_cell::save_ascii): Likewise.
+	* ov-complex.cc, ov-complex.h (octave_complex::save_ascii): Likewise.
+	* ov-fcn-handle.cc, ov-fcn-handle.h (octave_fcn_handle::save_ascii):
+	Likewise.
+	* ov-fcn-inline.cc, ov-fcn-inline.h (octave_fcn_inline::save_ascii):
+	Likewise.
+	* ov-list.cc, ov-list.h (octave_list::save_ascii): Likewise.
+	* ov-range.cc, ov-range.h (octave_range::save_ascii): Likewise.
+	* ov-scalar.cc, ov-scalar.h (octave_scalar::save_ascii): Likewise.
+	* ov-str-mat.cc, ov-str-mat.h (octave_char_matrix_str::save_ascii):
+	Likewise.
+	* ov-struct.cc, ov-struct.h (octave_struct::save_ascii): Likewise.
+	* ov-re-mat.cc, ov-re-mat.cc (octave_matrix::save_ascii): Likewise.
+	* ov-cx-mat.cc, ov-cx-mat.cc (octave_complex_matrix::save_ascii):
+	Likewise.
+
+	* ov-cx-mat.cc, ov-cx-mat.cc (octave_complex_matrix::save_ascii):
+	Don't strip Inf and NaN here.  Call ComplexMatrix::save_ascii to
+	do the real work.
+	* ov-re-mat.cc, ov-re-mat.cc (octave_matrix::save_ascii):
+	Don't strip Inf and NaN here.  Call Matrix::save_ascii to do the
+	real work.
+
+	* ov-re-mat.cc, ov-cx-mat.cc (strip_infnan): Delete.
+	* ls-oct-ascii.cc, ls-oct-ascii.h (save_ascii_data):
+	strip_nan_and_inf is now int, not bool.
+	(strip_infnan): Delete.
+	(save_ascii_data_for_plotting): Call save_ascii_data with
+	strip_nan_and_inf = 2.
+
+	* Makefile.in (INCLUDES): Remove matrix.h from the list.
+
+2006-08-22  David Bateman  <dbateman at free.fr>
+
+	* sparse-xpow.cc: Replace all uses of pow by std::pow.
+	(elem_pow): Simplify for two sparse matrices arguments.
+
+2006-08-22  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.cc: Increase default value of save_precision to 16.
+
+	* ls-mat-ascii.cc (save_mat5_ascii_data): Use scientific format.
+
+2006-08-21  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (read_mat5_binary_data, read_mat5_integer_data,
+	write_mat5_array): Unconditionally enable code for 64-bit int types.
+
+	* ov-fcn-handle.cc (DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA):	
+	For compatibility, set class to function_handle.
+
+2006-08-18  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (set_real_matrix_format): Also always include space
+	for sign if values are int, inf, or nan.
+	(set_complex_format, set_complex_matrix_format): Always include
+	space for sign in real format, but never in imaginary format.
+
+	* gripes.cc (gripe_logical_conversion): New function.
+	* gripes.h: Provide decl.
+	* ov.h (octave_value::bool_value, octave_value::bool_matrix_value,
+	octave_value::bool_array_value): New arg, warn.
+	* ov-base.cc, ov-base.h (octave_base_value::bool_value,
+	octave_base_value::bool_matrix_value, 
+	octave_base_value::bool_array_value): Likewise.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::bool_array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::bool_array_value): Likewise.
+	* ov-range.h (octave_range::bool_array_value): Likewise.
+	* ov-re-mat.cc, ov-re-mat.h (octave_matrix::bool_array_value):
+	Likewise.
+	* ov-re-sparse.cc, ov-re-sparse.h
+	(octave_sparse_matrix::bool_array_value): Likewise.
+	* ov-scalar.h (octave_scalar::bool_value,
+	octave_scalar::bool_array_value): Likewise.
+	* OPERATORS/op-bm-b.cc (oct_assignop_conv_and_assign):
+	Ask for warning from bool_array_value.
+	* OPERATORS/op-bm-bm.cc (oct_assignop_conv_and_assign): Likewise.
+	* ov-bool.h (octave_bool::bool_value,
+	octave_bool::bool_matrix_value, octave_bool::bool_array_value):
+	Likewise.
+	* ov-bool-mat.h (octave_bool_matrix::bool_matrix_value,
+	octave_bool_matrix::bool_array_value): Likewise.
+	* ov-bool-sparse.cc, ov-bool-sparse.h
+	(octave_sparse_bool_matrix::bool_matrix_value,
+	octave_sparse_bool_matrix::bool_array_value): Likewise.
+
+2006-08-18  Benjamin Lindner  <lindnerben at gmx.net>
+
+	* ls-mat5.cc (read_mat5_tag): Declare type as int32_t, not int.
+	(read_mat5_binary_element): Likewise, for len and element_length.
+
+2006-08-18  John W. Eaton  <jwe at octave.org>
+
+	* load-save.h (enum load_save_format): New element, LS_MAT_ASCII_LONG.
+	* load-save.cc (Fload, Fsave): Make -ascii Matlab compatible.
+	(do_save): Handle LS_MAT_ASCII.
+	* ls-mat-ascii.cc (save_mat_ascii_data): New function.
+	* ls-mat-ascii.h: Provide decl.
+
+2006-08-17  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (save_mat5_element_length): Correctly compute element
+	length for character data.  Handle N-d character data
+	(save_mat5_binary_element): Handle N-d character data.
+
+2006-08-16  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (gobble_leading_white_space): New arg, SKIP_CODE.
+	Change all uses.
+
+2006-08-15  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (help_from_file): Call get_help_from_file with new file
+	arg.  Print file info here.
+
+	* parse.y (get_help_from_file): Delete include_file_info arg.
+	Provide two versions, one that returns the file found in a
+	reference arg and one that does not.
+
+	* variables.cc (do_isglobal): New function.
+	(Fisglobal): Use it.
+	(Fis_global): New function.
+
+2006-08-14  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_record_name_compare): Fix casts.
+
+	* ov-cell.cc (octave_cell::subsasgn): Call empty_conv for 0x0
+	objects, not just empty objects.
+
+	* oct-map.h (Octave_map::clear): Also clear key_list.
+
+	* load-path.cc (load_path::find_dir_info, load_path::do_add,
+	load_path::do_remove): Perform tilde expansion on directory here.
+
+2006-07-29  John W. Eaton  <jwe at octave.org>
+
+	* matrix.h: Delete to avoid conflict with liboctave/Matrix.h on
+	case-insensitive filesystems.
+
+	* version.h (OCTAVE_VERSION): Now 2.9.7+.
+
+2006-07-28  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.7.
+	(OCTAVE_API_VERSION): Now api-v20.
+	(OCTAVE_RELEASE_DATE): Now 2006-07-28.
+
+	* load-path.cc (path::do_add): Warn for trailing "//".
+
+	* strfns.cc: Comment out some tests for snapshot.
+
+2006-07-27  John W. Eaton  <jwe at octave.org>
+
+	* defaults.cc (Vlocal_api_arch_lib_dir): New variable.
+	(set_default_local_api_arch_lib_dir): New function.
+	(install_defaults): Call it.
+	(set_exec_path): Put Vlocal_api_arch_lib_dir in the list.
+	* toplev.cc (localapiarchlibdir): Include it in the list.
+	* defaults.h.in (OCTAVE_LOCALAPIARCHLIBDIR): Substitute here.
+
+2006-07-26  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray::as_octave_value (mxArray *)): New static function.
+	(call_mex, mexPutVariable, mexCallMATLAB,
+	mxArray_cell::as_octave_value, mxArray_struct::as_octave_value):
+	Use static version of as_octave_value here.
+	(mxArray_sparse::mxArray_sparse (const mxArray_sparse&)):
+	Check pr, ir, and jc before calling memcpy.
+	(mxArray_number::mxArray_number): Check pr before calling memcpy
+
+	* mxarray.h (mxArray::as_octave_value (mxArray *)): Provide decl.
+	(mxArray::as_octave_value): Now protected.
+
+	* file-io.cc (Ffeof, Fferror): Use DEFUNX instead of DEFUN.
+
+	* mex.cc (xfree): New function.
+	(mex::free): Use it.
+	(mxArray_struct::~mxArray_struct, mxArray_cell::~mxArray_cell):
+	Delete elements with delete, not mxDestroyArray.
+	(mex::cleanup): Don't call mex::free or mex::free_value.
+	(mex::free_value): Add debug warning.
+	(mex::mark, mex::unmark): Fix debug warning.
+	(call_mex): Use unwind_protect frame.
+	(mexUnlock): Use iterator to remove item from mex_lock_count.
+
+	* octave.cc (maximum_braindamage): Use disable_warning instead of
+	bind_internal_variable to disable function-name-clash warning.
+	* error.cc (disable_warning): No longer static.
+	* error.h: Provide decl.
+
+2006-07-25  David Bateman  <dbateman at free.fr>
+
+	* mex.cc (mxArray_octave_value::get_class_id): Handle sparse.
+	(class mxArray_sparse): Derive from mxArray_matlab, not
+	mxArray_number.
+	(mxArray_sparse::as_octave_value): Implement function.
+	* ov-bool-sparse.cc (octave_sparse_bool_matrix::as_mxArray):
+	Implement function.
+	* ov-cx-sparse.cc (octave_sparse_complex_matrix::as_mxArray):
+	Implement function.	
+	* ov-re-sparse.cc (octave_sparse_matrix::as_mxArray):
+	Implement function.
+
+2006-07-25  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mxArray_struct::as_octave_value, call_mex,
+	mexCallMATLAB, mxArray_cell::as_octave_value):
+	Convert NULL mxArray* pointers to empty matrix values.
+	(mxArray_octave_value:get_ir): Fix typo.
+
+2006-07-22  John W. Eaton  <jwe at octave.org>
+
+	* mxarray.h: New file.
+	* mex.h, mexproto.h, mex.cc: New implementation of mxArray and MEX
+	interface.
+
+	* ov.h (octave_value::mex_get_ir, octave_value::mex_get_jc):
+	New functions.
+	* ov-base.h (octave_base_value::mex_get_ir,
+	octave_base_value::mex_get_jc): New virtual functions.
+	* ov-base-sparse.h (octave_base_sparse<T>::mex_get_ir,
+	octave_base_sparse<T>::mex_get_jc): New functions.
+
+	* ov-intx.h (OCTAVE_VALUE_INT_SCALAR_T::as_mxArray,
+	OCTAVE_VALUE_INT_MATRIX_T::as_mxArray): New functions.
+	* ov-int8.h, ov-int16.h, ov-int32.h, ov-int64.h, ov-uint8.h,
+	ov-uint16.h, ov-uint32.h, ov-uint64.h: Define OCTAVE_INT_MX_CLASS
+	before including ov-intx.h.  Undef it after.
+	* ov-range.cc (octave_range::as_mxArray): New function.
+	* ov-range.h: Provide decl.
+	* ov-scalar.cc (octave_scalar::as_mxArray): New function.
+	* ov-scalar.h: Provide decl.
+	* ov-complex.cc (octave_complex::as_mxArray): New function.
+	* ov-complex.h: Provide decl.
+	* ov-re-mat.cc (octave_matrix::as_mxArray): New function.
+	* ov-re-mat.h: Provide decl.
+	* ov-cx-mat.cc (octave_complex_matrix::as_mxArray): New function.
+	* ov-cx-mat.h: Provide decl.
+	* ov-ch-mat.cc (octave_char_matrix::as_mxArray): New function.
+	* ov-ch-mat.h: Provide decl.
+	* ov-bool-mat.cc (octave_bool_matrix::as_mxArray): New function.
+	* ov-bool-mat.h: Provide decl.
+	* ov-bool.cc (octave_bool::as_mxArray): New function.
+	* ov-bool.h: Provide decl.
+
+	* ov-struct.h (octave_struct::numel): New function.
+
+	* ls-mat5.cc (arrayclasstype): Use "MAT_FILE_" instead of "mx" as
+	prefix for element names.
+
+	* ov.h (octave_value::as_mxArray): New function.
+	* ov-base.cc (octave_base_value::as_mxArray): New function.
+	* ov-base.h: Provide decl.
+
+	* ov.h (octave_value::mex_get_data): New function.
+	* ov-base.h (octave_base_value::mex_get_data): New function.
+	* ov-base-scalar.h (octave_base_scalar<ST>::mex_get_data): New function.
+	* ov-base-matrix.h (octave_base_matrix<MT>::mex_get_data): New function.
+	* ov-intx.h (OCTAVE_VALUE_INT_SCALAR_T::mex_get_data): New function.
+
+	* ov.h (octave_value::nfields): New function.
+	* ov-base.cc (octave_base_value::nfields): New virtual function.
+	* ov-base.h: Provide decl.
+	* ov-struct.h (octave_struct::nfields): New function.
+
+2006-07-19  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-bm-bm.cc (oct_assignop_conv_and_assign): New function.
+	(install_bm_bm_ops): Install it for various types.
+	* OPERATORS/op-bm-b.cc (oct_assignop_conv_and_assign): New function.
+	(install_bm_b_ops): Install it for various types.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::bool_array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::bool_array_value): New functions.
+	* ov-range.h (octave_range::bool_array_value): New function.
+	* ov-re-sparse.cc (octave_sparse_matrix::bool_array_value):
+	New function.
+	* ov-re-sparse.h: Provide decl.
+	* ov-re-mat.cc (octave_matrix::bool_array_value): New function.
+	* ov-re-mat.h: Provide decl.
+
+	* ov-base.cc (octave_base_value::numeric_assign):
+	Avoid memory leak when converting LHS.
+
+2006-07-18  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (octave_value::is_int8_type, octave_value::is_int16_type,
+	octave_value::is_int32_type, octave_value::is_int64_type,
+	octave_value::is_uint8_type, octave_value::is_uint16_type,
+	octave_value::is_uint32_type, octave_value::is_uint64_type):
+	New functions. 
+	* ov-base.h (octave_base_value::is_int8_type,
+	octave_base_value::is_int16_type,
+	octave_base_value::is_int32_type,
+	octave_base_value::is_int64_type,
+	octave_base_value::is_uint8_type,
+	octave_base_value::is_uint16_type,
+	octave_base_value::is_uint32_type,
+	octave_base_value::is_uint64_type): New functions.
+	* ov-int8.h, ov-int16.h, ov-int32.h, ov-int16.h, ov-uint8.h,
+	ov-uint16.h, ov-uint32.h, ov-uint16.h: Define OCTAVE_BASE_INT_T.
+	* ov-intx.h: Use OCTAVE_BASE_INT_T to define type-specific predicate.
+
+	* ov.h (octave_value::is_double_type, octave_value::is_single_type):
+	New functions.
+	* ov-base.h (octave_base_value::is_double_type,
+	octave_base_value::is_single_type): New functions.
+	* ov-re-mat.h (octave_matrix::is_double_type): New function.
+	* ov-cx-mat.h (octave_matrix::is_double_type): New function.
+	* ov-scalar.h (octave_scalar::is_double_type): New function.
+	* ov-complex.h (octave_complex::is_double_type): New function.
+	* ov-range.h (octave_range::is_double_type): New function.
+	* ov-re-sparse.h (octave_sparse_matrix::is_double_type): New function.
+	* ov-cx-sparse.h (octave_sparse_complex_matrix::is_double_type):
+	New function.
+	
+2006-07-15  John W. Eaton  <jwe at octave.org>
+
+	* ov-typeinfo.cc: Also instantiate arrays of assignany_ops.
+
+	* oct-errno.cc.in (octave_errno::octave_errno): VALUE field in
+	errno_struct no longer const.
+
+	* DLD-FUNCTIONS/dispatch.cc (octave_dispatch::do_index_op):
+	Declare	resize_ok arg as bool, not int.
+	Provide default value for resize_ok.
+
+2006-07-14  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (do_write): Include explicit instantiations.
+
+	* ov-str-mat.h (octave_char_matrix_sq_str::resize):
+	Include fill arg to match base class.
+	* ov-struct.h (octave_struct::resize): Likewise.
+
+	* ov-base-mat.cc, ov-base-mat.h, ov-base-sparse.cc,
+	ov-base-sparse.h, ov-base.cc, ov-base.h, ov-bool.cc,
+	ov-bool.h, ov-complex.cc, ov-complex.h, ov-intx.h, ov-list.cc,
+	ov-list.h, ov-range.cc, ov-range.h, ov-scalar.cc, ov-scalar.h,
+	ov-str-mat.cc, ov-str-mat.h, ov.h (do_index_op):
+	Declare	resize_ok arg as bool, not int.
+	Provide default value for resize_ok.
+
+	* c-file-ptr-stream.h (c_file_ptr_stream::c_file_ptr_stream):
+	Qualify init.
+
+2006-07-13  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.h (Octave_map::del): Add missing std:: qualifier to use
+	of find template.
+
+2006-07-07  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (octave_value::is_bool_scalar): New function.
+	* ov-base.h (octave_base_value::is_bool_scalar): New function.
+	* ov-bool.h (octave_bool::is_bool_scalar): New function.
+
+	* oct-map.cc (Octave_map::keys): Use assert.
+	(Octave_map::assign): Avoid inserting new key in map unless
+	assignment to cell succeeds.
+
+	* oct-map.h (Octave_map::del): Only touch key_list if map contains key.
+	Assert that key_list contains key.
+
+	* oct-map.h (Octave_map::maybe_add_to_key_list): For efficiency,
+	check map, not key_list.  From Paul Kienzle  <pkienzle at users.sf.net>.
+
+2006-07-06  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Declare mrowsc volatile.
+
+	* ov-struct.cc (octave_struct::print_raw): Print keys in key_list
+	order.
+
+	* oct-map.h (Octave_map::key_list): New data member.
+	(Octave_map::maybe_add_to_key_list): New function.
+	(Octave_map::key_list_iterator, Octave_map::const_key_list_iterator):
+	New typedefs.
+	(Octave_map::del): Also delete key from key_list.
+	* oct-map.cc (Octave_map::keys): Compute return value from
+	key_list instead of map.
+	(Octave_map::assign, Octave_map::contents): Call maybe_add_to_key_list.
+	* oct-map.h, oct-map.cc (Octave_map::Octave_map):
+	Insert keys in key_list.
+
+	* oct-map.h (Octave_map::Octave_map (const dim_vector&,
+	const string_vector&)): New arg, key_list_arg.
+	* oct-map.cc: Move definition here.
+
+2006-07-05  John W. Eaton  <jwe at octave.org>
+
+	* mex.cc (mexGetVariable): Rename from mexGetArray, swap arguments.
+	(mexGetVariablePtr): Rename from mexGetArrayPtr, swap arguments.
+	(mexErrMsgIdAndTxt, mexWarnMsgIdAndTxt): New functions.
+	* mexproto.h: Provide decls.
+	Include decls for as yet unsupported functions.
+	* mex.h: Add enum for class ids.
+	(mexGetArray): Define using mexGetVariable.
+	(mexGetArrayPtr): Define using mexGetVariablePtr.
+
+2006-07-02  John W. Eaton  <jwe at octave.org>
+
+	* ov-str-mat.cc (CHAR_MATRIX_CONV): Omit "warn-" from label.
+	* parse.y (maybe_warn_variable_switch_label): Likewise.
+
+2006-07-01  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (finish_cell): Use finish_matrix to do constant folding.
+
+2006-06-30  John W. Eaton  <jwe at octave.org>
+
+	* ov-base.cc (octave_base_value::numeric_assign):
+	Avoid memory leak when converting LHS.
+
+	* oct-hist.cc (do_history, initialize_history, Fhistory_file):
+	Don't perform tilde expansion on history file name.
+
+	* syscalls.cc (Flstat, Fstat): Don't perform tilde expansion on arg.
+	* input.cc (Fread_readline_init_file): Likewise.
+	* dirfns.cc (Fcd, Freaddir): Likewise.
+
+	* load-path.cc (genpath): Don't perform tilde expansion on name.
+	(load_path::do_add): Don't warn about moving "." to front of list.
+
+2006-06-28  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (Faddpath): Don't treat "." specially here.
+	Don't check directory status here.
+	(Fpath): Handle all args.  Don't treat "." specially here.
+	(Faddpath, Frmpath): Delete unused variable xpath.
+	(load_path::do_add): New function.
+	(load_path::do_prepend, load_path::do_append): Use it.
+	(load_path::do_remove): Really prevent removal of ".".
+	(load_path::do_clear): Clearing doesn't remove ".".
+	(load_path::append, load_path::prepend, load_path::do_append,
+	load_path::do_prepend): New arg, warn.
+
+	* load-path.h: Fix decls.
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp_list):
+	Avoid bug in older versions of g++.
+
+2006-06-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (clean): Also remove $(DLD_OBJ).
+
+	* sighandlers.cc (install_signal_handlers): Don't handle SIGPROF.
+	From Geoffrey Knauth <geoff at knauth.org>.
+
+2006-06-25  John W. Eaton  <jwe at octave.org>
+
+	* mk-pkg-add: Avoid apparently non-portable sed patterns.
+
+2006-06-21  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (do_who): Handle mex.
+
+	* symtab.cc (SYMBOL_DEF::type_as_string, SYMBOL_DEF::which,
+	symbol_table::clear_functions, table::clear_function,
+	symbol_table::clear_function_pattern): 
+	Handle mex.
+	* symtab.h (symbol_record::is_mex_function,
+	symbol_record::symbol_def::is_mex_function): New functions.
+	(symbol_record::TYPE): New value, MEX_FUNCTION.
+	(symbol_record::is_function, symbol_table::user_function_name_list,
+	SYMTAB_ALL_TYPES): Handle MEX_FUNCTION.
+
+	* ov-fcn.h (octave_function::octave_function):
+	Provide default for doc string arg.
+
+	* defun.cc (install_mex_function): New function.
+	* defun-int.h: Provide decl.
+
+	* ov-builtin.cc (any_arg_is_magic_colon): Delete.
+	(octave_builtin::do_multi_index_op): Call has_magic_colon method
+	for args instead of any_arg_is_magic_colon.
+
+	* ov-base.h (octave_base_value::is_mex_function): New function.
+	* ov.h (octave_value::is_mex_function): New function.
+
+	* ov-mex-fcn.h, ov-mex-fcn.cc: New files.
+
+	* parse.y (load_fcn_from_file): Also handle .mex files.
+
+	* dynamic-ld.cc (octave_dynamic_loader::load_oct): Rename from load.
+	(octave_dynamic_loader::do_load_oct): Rename from do_load.
+	* dynamic-ld.h: Fix decls.
+
+	* utils.cc (mex_file_in_path): New function.
+	* utils.h: Provide decl.
+
+	* variables.cc (symbol_out_of_date): Also handle mex files.
+
+	* load-path.cc (load_path::dir_info::get_file_list,
+	load_path::dir_info::get_private_function_map,
+	load_path::do_find_fcn, load_path::add_to_fcn_map,
+	load_path::do_display): Also handle mex files.
+	* load-path.h (load_path::find_mex_file): New static function.
+	(load_path::MEX_FILE): New static data member.
+	(load_path::do_find_fcn): By default, also look for mex files.
+
+	* matrix.h, mex.h, mex.cc: New files from Octave Forge
+	* mexproto.h: New file, extracted from mex.h.
+	* Makefile.in: Add them to the appropriate lists.
+
+2006-06-20  John W. Eaton  <jwe at octave.org>
+
+	* ov-re-mat.cc (octave_matrix::convert_to_str_internal):
+	Don't lose empty dimensions on conversion to char.
+
+	* strfns.cc (Fstrcmp): Handle comparison of cellstr and empty string.
+
+2006-06-16  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (%union): New type, anon_fcn_handle_type.
+	(anon_fcn_handle): Now anon_fcn_handle_type, not tree_constant_type.
+	(make_anon_fcn_handle):	Return tree_anon_fcn_handle, not tree_constant.
+
+	* comment-list.cc (octave_comment_list::dup): New function.
+	* comment-list.h: Provide decl.
+
+	* pt-cmd.cc (tree_no_op_command::dup): New function.
+	* pt-cmd.h: Provide decl.
+	(tree_command::dup): New pure virtual function.
+
+	* pt-loop.cc (tree_while_command::dup, tree_do_until_command::dup,
+	tree_simple_for_command::dup, tree_complex_for_command::dup):
+	New functions.
+	* pt-loop.h: Provide decls.
+
+	* pt-jump.cc (tree_break_command::dup, tree_continue_command::dup,
+	tree_return_command::dup): New functions.
+	* pt-jump.h: Provide decls.
+
+	* pt-except.cc (tree_try_catch_command::dup,
+	tree_unwind_protect_command::dup): New functions.
+	* pt-except.h: Provide decls.
+
+	* pt-select.cc (tree_if_clause::dup, tree_if_command_list::dup,
+	tree_if_command::dup, tree_switch_case::dup,
+	tree_switch_case_list::dup, tree_switch_command::dup):
+	New functions.
+	* pt-select.h: Provide decls.
+
+	* pt-decl.cc (tree_decl_elt::dup, tree_decl_init_list::dup,
+	tree_global_command::dup, tree_static_command::dup): New functions.
+	* pt-decl.h: Provide decls.
+	
+	* pt-exp.h (tree_expression::copy_base): New function.
+	(tree_expression::dup): New pure virtual function.
+	
+	* pt-fcn-handle.cc, pt-fcn-handle.h (tree_anon_fcn_handle): New class.
+
+	* pt-fcn-handle.cc (tree_function_handle::dup): New function.
+	* pt-fcn-handle.h: Provide decl.
+
+	* pt-colon.cc (tree_colon_expression::dup): New function.
+	* pt-colon.h: Provide decl.
+	(tree_colon_expression::tree_colon_expression (tree_expression *,
+	tree_expression *, tree_expression *, int, int)): New constructor.
+	
+	* pt-const.cc (tree_constant::dup): New function.
+	(tree_constant::tree_constant (const octave_value&, const
+	std::string&, int, int)): New constructor.
+	* pt-const.h: Provide decls.
+
+	* pt-idx.cc (tree_index_expression::dup): New functoin.
+	(tree_index_expression::tree_index_expression (int, int)):
+	New constructor.
+	* pt-idx.h: Provide decls.
+
+	* pt-arg-list.cc (tree_argument_list::dup): New function.
+	* pt-arg-list.h: Provide decl.
+
+	* pt-id.cc (tree_identifier::dup): New function.
+	* pt-id.h: Provide decl.
+
+	* pt-cell.cc (tree_cell::dup): New function.
+	* pt-cell.h: Provide decl.
+
+	* pt-mat.cc (tree_matrix::dup): New function.
+	* pt-mat.h: Provide decl.
+
+	* pt-assign.cc (tree_simple_assignment::dup,
+	tree_multi_assignment::dup): New functions.
+	* pt-assign.h: Provide decls.
+
+	* pt-binop.cc (tree_binary_expression::dup,
+	tree_boolean_expression::dup): New functions.
+	* pt-binop.h: Provide decls.
+	
+	* pt-unop.cc (tree_prefix_expression::dup,
+	tree_postfix_expression::dup): New functions.
+	* pt-unop.h: Provide decls.
+
+	* pt-stmt.cc (tree_statement::dup, tree_statement_list::dup):
+	New functions.
+	* pt-stmt.h: Provide decls.
+
+	* pt-misc.cc (tree_parameter_list::dup,
+	tree_return_list::dup): New functions.
+	* pt-misc.h: Provide decls.
+
+	* symtab.cc (symbol_table::dup, symbol_table::inherit,
+	symbol_record:is_automatic_variable): New functions.
+	* symtab.h: Provide decls.
+	(symbol_record::automatic_variable): New data member.
+	(symbol_record::symbol_record): Initialize it.
+	(symbol_record::mark_as_automatic_variable): New function.
+
+	* pt-walk.h (tree_walker::visit_anon_fcn_handle):
+	New pure virtual function.
+	* pt-pr-code.cc (tree_print_code::visit_anon_fcn_handle): New function.
+	* pt-pr-code.h: Provide decl.
+	* pt-bp.cc (tree_breakpoint::visit_anon_fcn_handle): New function.
+	* pt-bp.h: Provide decl.
+	* pt-check.cc (tree_checker::visit_anon_fcn_handle): New function.
+	* pt-check.h: Provide decl.
+
+2006-06-13  John W. Eaton  <jwe at octave.org>
+
+	* pt-stmt.cc (tree_statement_list::eval): Revise previous change
+	to preserve return-last-value-computed semantics.
+
+	* DLD-FUNCTIONS/fsolve.cc (hybrd_info_to_fsolve_info):
+	Warn about invalid values of INFO from MINPACK instead of calling
+	panic_impossible.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Don't assign values returned by evaluation of cmd_list to
+	temporary variable.  Delete unused variable last_computed_value.  
+
+	* pt-stmt.cc (tree_statement_list::eval):
+	Clear retval before each statement is evaluated.
+
+2006-06-12  John W. Eaton  <jwe at octave.org>
+
+	* unwind-prot.h (unwind_protect_fptr): New macro.
+	* load-path.cc (load_path::do_set): Use it instead of
+	unwind_protect_ptr when protecting add_hook function pointer.
+	* dynamic-ld.cc (octave_dynamic_loader::do_load): Use FCN_PTR_CAST
+	here instead of reinterpret_cast.
+
+2006-06-09  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.6+.
+
+2006-06-09  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.6.
+	(OCTAVE_API_VERSION): Now api-v19.
+	(OCTAVE_RELEASE_DATE): Now 2006-06-09.
+
+	* ov-cell.cc (cell::save_hdf5): Use leading zeros to keep elements
+	correctly sorted in the HDF file.
+	From Stephen Fegan <sfegan at astro.ucla.edu>.
+
+2006-06-08  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr-fcn.cc (function::do_multi_index_op): Append contents of
+	varargout to ret_list before calling convert_to_const_vector.
+
+	* pt-arg-list.cc (tree_argument_list::convert_to_const_vector):
+	No need to handle all_va_args here.
+
+	* ov-va-args.h, ov-va-args.cc: Delete files.
+	* Makefile.in (OV_INCLUDES, OV_SRC): Delete from the lists.
+
+	* ov.cc (install_types): Don't register octave_all_va_args type.
+	* ov.h, ov.cc (octave_value::octave_value (octave_value::all_va_args)):
+	Delete.
+	* ov.h (octave_value::is_all_va_args): Delete.
+	(octave_value::enum all_va_args): Delete.
+
+	* pt-pr-code.cc	(tree_print_code::visit_octave_user_function_header):
+	Print "varargout" and "varargin" instead of "...".
+
+	* pt-misc.h, pt-misc.cc	(tree_parameter_list::convert_to_const_vector):
+	Arg is now const Cell& instead of tree_va_return_list*.
+
+	* ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_function::vr_list,
+	octave_user_function::curr_va_arg_number):
+	Delete variables and all uses.
+	(octave_function::octave_va_start, octave_function::octave_va_arg,
+	octave_function::octave_vr_val,	octave_function::has_varargout):
+	Delete functions and all uses.
+
+	* ov-fcn.h (octave_function::octave_va_start,
+	octave_function::octave_va_arg, octave_function::octave_vr_val,
+	octave_function::has_varargout): Delete.
+
+	* ov-usr-fcn.cc (Fva_arg, Fva_start, Fvr_val): Delete.
+
+	* lex.l ({EL}): Don't handle "..." as varargin or varargout.
+	* octave.gperf (all_va_args, ALL_VA_ARGS, all_va_args_kw): Delete.
+	* parse.y (ALL_VA_ARGS): Delete token and all uses.
+
+	* defaults.h.in (OCTAVE_DATAROOTDIR): Substitute here.
+	* toplev.cc (octave_config_info): Add datarootdir to the struct.
+
+2006-06-07  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.cc (octave_cell::subsasgn): Handle c-s list object on
+	RHS if last index is '{'.
+	* pt-assign.cc (tree_multi_assignment::rvalue): Compute all LHS
+	lvalues before evaluating RHS.  If LHS lvalue expects more than
+	one output, pass octave_cs_list object to assign method.
+	* pt-idx.cc (tree_index_expression::lvalue): Compute expected
+	number of values if '{' index appears last.
+	* pt-arg-list.cc (tree_argument_list::lvalue_list): New function.
+	* pt-arg-list.h (tree_argument_list::lvalue_list): Provide decl.
+	* oct-lvalue.h (octave_lvalue::nel): New data member.
+	(octave_lvalue::numel): New functions
+	* oct-obj.cc (octave_value_list::has_magic_colon): New function.
+	* oct-obj.h (octave_value_list::has_magic_colon): Provide decl.
+	* pt-arg-list.cc (tree_argument_list::nargout_count): Delete function.
+	* pt-arg-list.h (tree_argument_list::nargout_count): Delete decl.
+
+2006-06-06  John W. Eaton  <jwe at octave.org>
+
+	* sighandlers.cc (generic_sig_handler, sigint_handler):
+	Use strsignal instead of accessing sys_siglist directly.
+	* siglist.h: Use HAVE_DECL_SYS_SIGLIST instead of SYS_SIGLIST_DECLARED.
+	* siglist.c: Update sys_siglist.
+	(init_signals, strsignal): New functions.
+	* octave.cc (octave_main): Call init_signals here.
+
+	* toplev.cc (Foctave_config_info): Delete LIBPLPLOT from struct.
+
+2006-06-05  John W. Eaton  <jwe at octave.org>
+
+	* pt-assign.cc (Vprint_rhs_assign_val): Delete variable.
+	(Fprint_rhs_assign_val): Delete function.
+	tree_simple_assignment::rvalue, tree_multi_assignment::rvalue):
+	No special case for Vprint_rhs_assign_val.
+
+2006-06-02  John W. Eaton  <jwe at octave.org>
+
+	* pt-arg-list.h (tree_argument_list::mark_as_simple_assign_lhs,
+	tree_argument_list::is_simple_assign_lhs): New functions.
+	(tree_argument_list::simple_assign_lhs): New data member.
+	* parse.y (assign_lhs): Classify LHS here.
+	(make_assign_op): Create simple or multi assign op based on
+	classification of LHS, not its length.
+
+2006-06-01  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DLD_XSRC): Add __pchip_deriv__.cc to the list.
+
+2006-06-01  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/__pchip_deriv__.cc: New file.
+
+2006-05-31  John W. Eaton  <jwe at octave.org>
+
+	* load-path.h (load_path::set_command_line_path): Make it
+	additive.
+
+2006-05-26  John W. Eaton  <jwe at octave.org>
+
+	* load-path.cc (genpath, maybe_add_path_elts, Fgenpath, Frehash,
+	Fpath, Fpathdef): Move here from defaults.cc.
+	* load-path.cc, load-path.h: New files.
+	* Makefile.in (INCLUDES, DIST_SRC): Add them to the lists.
+	* help.cc (make_name_list, simple_help): Use load_path instead of
+	octave_fcn_file_name_cache.
+	(Flookfor): Use load_path instead of Vload_path_dir_path.
+	* octave.cc (octave_main):  Likewise.
+	* parse.y (load_fcn_from_file): Likewise.
+	* utils.cc (Ffile_in_loadpath, file_in_path, fcn_file_in_path,
+	oct_file_in_path): Likewise.
+	* variables.cc (symbol_exist, symbol_out_of_date): Likewise.
+	* DLD-FUNCTIONS/fftw_wisdom.cc (Ffftw_wisdom): Likewise.
+	* utils.cc (Ffind_first_of_in_loadpath): Delete.
+	* input.cc (octave_gets): Call load_path::update here.
+	* dirfns.cc (octave_change_to_directory): Likewise.
+	* defaults.cc (VLOADPATH, VDEFAULT_LOADPATH, Vload_path_dir_path,
+	maybe_add_or_del_packages, update_load_path_dir_path,
+	execute_default_pkg_add_files, set_load_path): Delete.
+	* defaults.h.in (Vload_path_dir_path,
+	execute_default_pkg_add_files, maybe_add_default_load_path,
+	set_load_path): Delete decls.
+
+	* fn-cache.h, fn-cache.cc: Delete.
+	* Makefile.in (INCLUDES, DIST_SRC): Remove them from the lists.
+
+	* input.cc (octave_gets): Only update Vlast_prompt_time if we are
+	interactive and actually printing a prompt.  Don't print prompt if
+	reading startup files or command line files.  Initialize
+	Vlast_prompt_time to 0.
+
+	* pr-output.cc (set_format): Always include space for sign.
+	
+2006-05-23  John W. Eaton  <jwe at octave.org>
+
+	* load-save.cc (Fsave): Use tellp instead of pubseekoff to
+	determine whether we are at beginning of file.
+
+	* ov-intx.h (OCTAVE_VALUE_INT_SCALAR_T::increment, 
+	OCTAVE_VALUE_INT_SCALAR_T::decrement,
+	OCTAVE_VALUE_INT_MATRIX_T::increment,
+	OCTAVE_VALUE_INT_MATRIX_T::decrement): New functions.
+	* OPERATORS/op-int.h (OCTAVE_INSTALL_M_INT_UNOPS,
+	OCTAVE_INSTALL_S_INT_UNOPS, OCTAVE_M_INT_UNOPS,
+	OCTAVE_S_INT_UNOPS): Uncomment increment and decrement ops.
+
+2006-05-19  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (SYMBOL_DEF::document): If definition is a function,
+	also pass doc string to function object.
+	* ov-fcn.h (octave_function::document): New function.
+	* defun.cc (print_usage (octave_function *)): New function.
+	(print_usage (void)): New function.
+	(print_usage (const std::string&)): Provide for backward
+	compatibility.  Ignore arg.
+	(Fprint_usage): Don't accept arg.
+	* defun-int.h (print_usage (void)): Provide decl.
+	(print_usage (const std::string&)): Tag with GCC_ATTR_DEPRECATED.
+
+2006-05-04  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/conv2.cc: New file from Octave Forge.
+	* Makefile.in (DLD_XSRC): Add it to the list
+
+2006-05-17  Bill Denney  <bill at givebillmoney.com>
+
+	* help.cc (keywords): Improve and Texinfoize.
+
+2006-05-17  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (Vwhos_line_format): Show class instead of type.
+	(symbol_table::parse_whos_line_format):
+	Use 't' for "Type" and 'c' for "Class".
+	(symbol_record::print_symbol_info_line): Likewise.
+	(maybe_list_cmp_fcn): Fix casts.
+
+2006-05-11  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (IMAGE_PATH_OPTION): New macro.
+	(usage_string, verbose_usage): Include --image-path option.
+	(long_opts): Include --image-path.
+	(octave_main): Handle IMAGE_PATH_OPTION.
+
+	* toplev.cc (Foctave_config_info): Delete fcnfilepath, imagepath,
+	localfcnfilepath, and localoctfilepath from the struct.
+	* defaults.h.in (OCTAVE_FCNFILEPATH, OCTAVE_IMAGEPATH,
+	OCTAVE_LOCALFCNFILEPATH, OCTAVE_LOCALOCTFILEPATH): Delete variables.
+
+	* octave.cc (octave_main): Call set_exec_path and set_load_path
+	instead of bind_internal_variable.
+
+	* defaults.cc (Fpathdef): Rename from FDEFAULT_LOADPATH.
+	Don't allow default path to be set.
+	(Fpath): Rename from FLOADPATH.  Make Matlab-compatible.
+	(update_load_path_dir_path): No need to pass VDEFAULT_LOADPATH to
+	dir_path constructor now.
+	(update_exec_path, FDEFAULT_EXEC_PATH,
+	set_default_default_exec_path, set_default_exec_path,
+	maybe_add_default_load_path): Delete functions.
+	(VDEFAULT_EXEC_PATH): Delete variable.
+	(FEXEC_PATH): Leading and trailing colons no longer special.
+	(set_exec_path, set_load_path, set_image_path,
+	maybe_add_path_elts): New functions.
+	(install_defaults): Call set_exec_path and set_load_path instead
+	of set_default_exec_path and set_default_path.  Don't call
+	set_default_default_exec_path.  Do call set_image_path.
+	* defaults.cc (genpath, Fgenpath): New functions.
+	(Vlocal_ver_oct_file_dir, Vlocal_api_oct_file_dir,
+	Vlocal_oct_file_dir, Vlocal_ver_fcn_file_dir,
+	Vlocal_api_fcn_file_dir, Vlocal_fcn_file_dir, Vimage_dir):
+	New variables.
+	(set_default_local_ver_oct_file_dir,
+	set_default_local_api_oct_file_dir,
+	set_default_local_oct_file_dir,
+	set_default_local_ver_fcn_file_dir,
+	set_default_local_api_fcn_file_dir,
+	set_default_local_fcn_file_dir, set_default_image_dir):
+	New functions.
+	(install_defaults): Call them.
+	* defaults.h.in (set_exec_path, set_load_path, set_image_path,
+	Vlocal_ver_oct_file_dir, Vlocal_api_oct_file_dir,
+	Vlocal_oct_file_dir, Vlocal_ver_fcn_file_dir,
+	Vlocal_api_fcn_file_dir, Vlocal_fcn_file_dir,
+	Vlocal_fcn_file_dir, Vimage_dir): Provide decls.
+
+2006-05-10  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.cc (Fcellstr): Trim trailing blanks.
+	* Cell.h (Cell::Cell (const string_vector&)): New arg, TRIM.
+
+	* oct-hist.cc (initialize_history, Fhistory_size):
+	Also call command_history::set_size here.
+
+	* defun.cc (Fprint_usage): New function.
+	* help.cc (display_usage_text): New function.
+
+2006-05-09  Keith Goodman  <kwgoodman at gmail.com>
+
+	* DLD-FUNCTIONS/rand.cc: Doc string fix.
+
+2006-05-09  Jorge Barros de Abreu  <ficmatin01 at solar.com.br>
+
+	* data.cc (FInf, FNaN): Fix typo in doc string.
+
+2006-05-08  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DEFUN_PATTERN): Match DEFUNX_DLD.
+	* mkbuiltins: Handle XDEFUNX_DLD_INTERNAL.
+	* mkgendoc: Likewise.
+	* mk-pkg-add: Likewise.  Do all the matching with sed.
+	* defun-int.h 	(DEFINE_FUNX_INSTALLER_FUN, DEFINE_FUNX_INSTALLER_FUN2,
+	DEFINE_FUNX_INSTALLER_FUN3): New macros.
+	(DEFINE_FUN_INSTALLER_FUN3): Define using DEFINE_FUNX_INSTALLER_FUN3.
+	(DEFUNX_DLD_INTERNAL): New macro.
+	* defun-dld.h (DEFUNX_DLD): New macro.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l: Mark __gnuplot_set__ as a
+	command, not a rawcommand.
+
+	* load-save.cc: No need to handle built-in variables.
+	* help.cc (simple_help): No need to handle built-in variables.
+
+	* variables.cc (is_builtin_variable, builtin_string_variable,
+	builtin_real_scalar_variable, builtin_any_variable):
+	Delete functions.
+	(Fexist, Fdocument, do_who, Fwho, link_to_builtin_or_function): 
+	No need to handle built-in variables.
+	* variables.h (is_builtin_variable, builtin_string_variable,
+	builtin_real_scalar_variable, builtin_any_variable): Delete decls.
+
+	* symtab.h (symbol_record::symbol_def::is_builtin_variable,
+	symbol_record::is_builtin_variable): Delete.
+	(symbol_record::TYPE): Remove BUILTIN_VARIABLE from enum.
+	(symbol_record::symbol_def::is_variable, SYMTAB_ALL_TYPES,
+	SYMTAB_VARIABLES): No need to handle built-in variables now.
+	(symbol_record::define_builtin_variable,
+	symbol_record::link_to_builtin_variable): Delete decls.
+	* symtab.cc (record::define, SYMBOL_DEF::type,
+	SYMBOL_DEF::type_as_string): No need to handle built-in variables.
+	(symbol_record::define_builtin_variable): Delete.
+	(symbol_record::variable_reference): No need to attemp to link to
+	built-in variable.
+
+	* utils.cc (check_preference, warn_old_style_preference): Delete.
+	* utils.h (check_preference): Delete decl.
+
+	* defun-int.h: Delete all DEFVAR macros.
+
+	* Makefile.in, mkbuiltins: No need for VAR_FILES.
+
+	* parse.y (current_script_file_name): Delete all uses.
+	(clear_current_script_file_name): Delete function.
+
+	* variables.cc (symbols_of_variables): Delete DEFVAR and function.
+	(bind_ans): Lookup ans in curr_sym_tab, not fbi_sym_tab.
+	SR is no longer static, so we insert value in local scope.
+
+	* defun.cc (bind_builtin_variable): Delete function.
+	* defun-int.h: Delete decl.
+
+	* defaults.cc (fftw_wisdom_program): Rename from fftw_wisdom_prog.
+	Change all uses.
+	(VDEFAULT_LOADPATH): Rename from Vdefault_load_path.  Change all uses.
+	(VLOADPATH): Rename from Vload_path.  Change all uses.
+	(VDEFAULT_EXECPATH): Rename from Vdefault_exec_path.  Change all uses.
+	(VEXECPATH): Rename from Vexec_path.  Change all uses.
+	(VEDITOR): Rename from Veditor.  Change all uses.
+	(Ffftw_wisdom_program, FDEFAULT_LOADPATH, FLOADPATH,
+	FDEFAULT_EXEC_PATH, FEXEC_PATH, FEDITOR, FIMAGEPATH): New functions.
+	(fftw_wisdom_program, default_load_path, loadpath,
+	default_exec_path, exec_path, editor, image_path): Delete functions.
+	(symbols_of_defaults): Delete DEFVARs and function.
+
+	* pr-output.cc (set_output_prec_and_fw): Set Voutput_precision and
+	Voutput_max_field_width directly instead of calling
+	bind_builtin_variable.
+
+	* octave.cc (octave_main, maximum_braindamage):
+	Call bind_internal_variable instead of bind_builtin_variable.
+
+	* pager.cc (Fmore): Set Vpage_screen_output directly instead of
+	calling bind_builtin_variable.
+
+	* error.cc (Fwarning): Set Vdebug_on_warning directly instead of
+	calling bind_builtin_variable.
+
+	* error.cc (initialize_warning_options): Now static.
+	(disable_warning, initialize_default_warning_state): New functions.
+
+	* error.h (initialize_warning_options): Delete decl.
+	(initialize_default_warning_state): Provide decl.
+	* octave.cc (octave_main): Call initialize_default_warning_state
+	instead initialize_warning_options.
+
+	* lex.l (warn_matlab_incompatible, warn_separator_insert,
+	warn_single_quote_string): Delete functions.
+	(symbols_of_lex): Delete DEFVARS.
+	(Vwarn_matlab_incompatible, Vwarn_separator_insert,
+	Vwarn_single_quote_string): Delete variables.
+	(maybe_warn_separator_insert, gripe_single_quote_string,
+	gripe_matlab_incompatible): Call warning_with_id instead of warning.
+
+	* variables.h (SET_NONEMPTY_INTERNAL_STRING_VARIABLE,
+	SET_INTERNAL_VARIABLE_WITH_LIMITS): New macros.
+
+	* ls-oct-ascii.cc (Fsave_precision): New function.
+	(save_precision): Delete function.
+	(symbols_of_ls_oct_ascii): Delete DEFVAR and function.
+
+	* oct-hist.cc (initialize_history): New function.
+	* oct-hist.h: Provide decl.
+	* octave.cc (octave_main): Call initialize_history instead of
+	command_history::read.
+
+	* oct-hist.cc (Fhistory_size, Fhistory_file,
+	Fhistory_timestamp_format_string, Fsaving_history): New functions.
+	(history_size, history_file, history_timestamp_format_string,
+	saving_history): Delete functions.
+	(symbols_of_oct_hist): Delete DEFVARs and function.
+
+	* pt-mat.cc (Fstring_fill_char): New function.
+	(string_fill_char): Delete function.
+	(symbols_of_pt_mat): Delete DEFVAR and function.
+
+	* variables.cc (Fignore_function_time_stamp, ans): New functions.
+	(ignore_function_time_stamp): Delete function.
+	(symbols_of_variables): Delete DEFVARs and function.
+
+	* oct-procbuf.cc: (Vkluge_procbuf_delay): Delete variable.
+	(octave_procbuf::open): Never delay after fork.
+	(kluge_procbuf_delay): Delete function.
+	(symbols_of_oct_procbuf): Delete DEFVAR and function.
+
+	* dirfns.cc (Fconfirm_recursive_rmdir): New function.
+	(confirm_recursive_rmdir): Delete function.
+	(symbols_of_dirfns): Delete DEFVAR and function.
+
+	* error.cc (initialize_warning_options): Now extern.
+	Rename from init_warning_options. 
+	* error.h: Provide decl.
+	* octave.cc (octave_main): Call it here.
+
+	* error.cc (Fbeep_on_error, Fdebug_on_error, Fdebug_on_warning):
+	New functions.
+	(beep_on_error, debug_on_error, debug_on_warning): Delete Functions.
+	(symbols_of_error): Delete DEFVARs and function.
+
+	* help.cc (Finfo_file, Finfo_program, Fmakeinfo_program,
+	Fsuppress_verbose_help_message): New function.
+	(info_file, info_program, makeinfo_program,
+	suppress_verbose_help_message): Delete function.
+	(symbols_of_help): Delete DEFVARs and function.
+	(Vinfo_program): Rename from Vinfo_prog.  Change all uses.
+
+	* input.cc (FPS1, FPS2, FPS4, Fcompletion_append_char,
+	Fecho_executing_commands): New functions.
+	(ps1, ps2, ps4, completion_append_char, echo_executing_commands):
+	Delete functions.
+	(symbols_of_input): Delete DEFVARs and function.
+	(VPS1, VPS2, VPS4): Rename from Vps1, Vps2, Vps4.  Change all uses.
+	(Fecho): Set Vecho_executing_commands directly.
+
+	* load-save.cc (crash_dumps_octave_core, Fdefault_save_options,
+	Foctave_core_file_limit, Foctave_core_file_name,
+	Foctave_core_file_options, Fsave_header_format_string):	
+	New functions.
+	(crash_dumps_octave_core, default_save_options,
+	octave_core_file_limit, octave_core_file_name,
+	octave_core_file_options, save_header_format_string):	
+	Delete functions. 
+	(symbols_of_load_save): Delete DEFVARs and function.
+
+	* ov-base.cc (Fprint_answer_id_name, Fsilent_functions): New functions.
+	(print_answer_id_name, silent_functions): Delete functions.
+	(symbols_of_ov_base): Delete DEFVARs and function.
+
+	* ov-usr-fcn.cc (Fmax_recursion_depth): New function.
+	(max_recursion_depth): Delete function.
+	(symbols_of_ov_usr_fcn): Delete DEFVAR for max_recursion_depth.
+	Delete function.
+
+	* pager.cc (Fpage_output_immediately, Fpage_screen_output, FPAGER):
+	New functions.
+	(page_output_immediately, page_screen_output, pager_binary):
+	Delete functions.
+	(symbols_of_pager): Delete DEFVARs and function.
+	(VPAGER): Rename from Vpager_binary.  Change all uses.
+
+	* pr-output.cc (Ffixed_point_format, Fprint_empty_dimensions,
+	Fsplit_long_rows, Foutput_max_field_width, Foutput_precision,
+	Fstruct_levels_to_print): New functions.
+	(fixed_point_format, print_empty_dimensions, split_long_rows,
+	output_max_field_width, output_precision, struct_levels_to_print):
+	Delete functions.
+	(symbols_of_pr_output): Delete DEFVARs and function.
+
+	* pt-assign.cc (Fprint_rhs_assign_val): New function.
+	(print_rhs_assign_val): Delete function.
+	(symbols_of_pt_assign): Delete DEFVAR.  Delete function.
+
+	* sighandlers.cc (Fdebug_on_interrupt, Fsighup_dumps_octave_core,
+	Fsigterm_dumps_octave_core): New functions.
+	(debug_on_interrupt, sighup_dumps_octave_core,
+	sigterm_dumps_octave_core): Delete functions.
+	(symbols_of_sighanlders): Delete DEFVARs.  Delete function.
+
+	* symtab.cc (Vdebug_symtab_lookups): Now bool.
+	(Fdebug_symtab_lookups, Fwhos_line_format,
+	Fvariables_can_hide_functions): New functions.
+	(debug_symtab_lookups, whos_line_format,
+	variables_can_hide_functions): Delete functions.
+	(symbols_of_symtab): Delete DEFVARs and function.
+
+2006-05-04  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sqqr (Fdmperm): Allow compilation with versions
+	v2.0.0 of CXSparse or later.
+
+2006-05-04  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (set_internal_variable): Move here from
+	DLD-FUNCTIONS/__gnuplot_raw__.l.
+	* variables.h (SET_INTERNAL_VARIABLE): Likewise.
+	(set_internal_variable): Provide decls.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l: Convert all DEFVARs to DEFUN_DLDs.
+	(gnuplot::init): Delete.
+	(gnuplot::gnuplot): Don't call init here.
+	(set_internal_variable): New functions.
+	(SET_INTERNAL_VARIABLE): New macro.
+
+	* Makefile.in: Undo changes of 2006-03-16.
+	* DLD-FUNCTINS/__gnuplot_raw__.l: Move here from __gnuplot_raw__.l.
+	Undo changes of 2006-03-16.
+
+2006-05-03  David Bateman  <dbateman at free.fr>
+
+	* ov-base-mat.h: Add caching of matrix type, and code to supply
+	and copy matrix type.
+	* ov-bool-mat.h: Add caching to constructor.
+	* ov-re-mat.h: ditto.
+	* ov-cx-mat.h: ditto.
+	* ov.cc: Add to the BoolMatrix, Matrix and the ComplexMatrix
+	octave_value constructors, the ability to specify the matrix type.
+	* ov.h: Adapt declaration of above constructors.
+	(MatrixType matrix_type(void) const, MatrixType matrix_type (const
+	MatrixType&)): New functions for probing and setting matrix type.
+	* ov-base.cc (virtual MatrixType matrix_type(void) const, virtual
+	MatrixType matrix_type (const MatrixType&)): New default functions
+	for probing and setting matrix type.
+	* ov-base.h  (virtual MatrixType matrix_type(void) const, virtual
+	MatrixType matrix_type (const MatrixType&)): Declarations.
+	* ov-base-sparse.h: Replace all uses of SparseType with
+	MatrixType. Replace sparse_type function with matrix_type function.
+	* ov-bool-sparse.h: Replace all uses of SparseType with MatrixType.
+	* ov-cx-sparse.h: ditto.
+	* ov-re-sparse.h: ditto.
+	* sparse-xdiv.cc: ditto.
+	* sparse-xdiv.h: ditto.
+	* sparse-xpow.cc: ditto.
+	* DLD-FUNCTIONS/luinc.cc: ditto.
+	* DLD-FUNCTIONS/splu.cc: ditto.
+	* xdiv.cc (xdiv, xleftdiv): Pass the matrix type, simplfy since
+	the matrix solve function now calls lssolve if singular.
+	* xdiv.h (xdvi, xleftdiv): Update the declarations
+	* OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc,
+	OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc,
+	OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc, 
+	OPERATORS/op-cs-cm.cc, OPERATORS/op-cs-m.cc,
+	OPERATORS/op-m-cm.cc, OPERATORS/op-m-cs.cc, 
+	OPERATORS/op-m-m.cc, OPERATORS/op-m-s.cc, 
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc, 
+	OPERATORS/op-s-cm.cc, OPERATORS/op-s-m.cc, 
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-scm-m.cc, 
+	OPERATORS/op-sm-cm.cc, OPERATORS/op-sm-m.cc: Update use of
+	xdiv and xleftdiv functions to allow matrix type caching.
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Update to allow typing
+	 of Matrix, and ComplexMatrix types. Add new test code for this.
+
+	* DLD-FUNCTIONS/cellfun.cc (Fmat2cell): new function.
+
+	* DLD-FUNCTIONS/regexp.cc (class regexp_elem): New class to store
+	matched element in a std::list.
+	(octregexp_list): Take algorithm from octregexp and construct a 
+	list of matches.
+	(octregexp): Rewrite to use linked list of matches.
+	(Fregexprep): New function, working directly in linked list of
+	matches.
+	
+2006-05-02  John W. Eaton  <jwe at octave.org>
+
+	* lex.l ({CCHAR}): Exit rawcommand mode if returning '\n' token.
+
+2006-05-02  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/rand.cc (do_rand): Require real scalar for seed.
+
+2006-05-01  John W. Eaton  <jwe at octave.org>
+
+	* error.h (Vwarning_option): Delete.
+	* variables.cc (looks_like_struct): Remove use from commented code.
+
+	* gripes.cc, gripes.h (gripe_implicit_conversion): New arg, ID.
+	Change all uses.
+
+	* defaults.cc (set_local_site_defaults_file, set_site_defaults_file):
+	Allow filenames to be set from the environment.
+
+	* oct-map.cc (octave_map::resize): No longer const.
+	* ov-struct.h (octave_struct::resize): Deal with it.
+
+	* octave.cc (initialize_error_handlers): Also call
+	set_liboctave_warning_with_id_handler.
+	(execute_startup_files): Check that home_rc is not an empty string.
+	(F__version_info__): Resize vinfo before assigining elements.
+
+	* ov-base.cc (warn_num_to_str, warn_resize_on_range_error):
+	Delete functions.
+	(symbols_of_ov_base): Delete DEFVARS.
+	(Vwarn_num_to_str, Vwarn_resize_on_range_error): Delete variables.
+	(value::convert_to_str): Check state of warning ID
+	Octave:num-to-str instead of using Vwarn_num_to_str.
+	* OPERATORS/op-chm.cc: Likewise.
+	* ov-base.h (Vwarn_num_to_str, Vwarn_resize_on_range_error):
+	Delete decls.
+
+	* ov-list.cc (octave_list::assign): Call warning_with_id instead
+	of warning.
+
+	* parse.y (warn_assign_as_truth_value, warn_associativity_change,
+	warn_function_name_clash, warn_future_time_stamp,
+	warn_missing_semicolon, warn_precedence_change,
+	warn_variable_switch_label, symbols_of_parse):	
+	Delete DEFVARs and functions.
+	(Vwarn_assign_as_truth_value, Vwarn_associativity_change,
+	Vwarn_function_name_clash, Vwarn_future_time_stamp,
+	Vwarn_missing_semicolon, Vwarn_precedence_change,
+	Vwarn_variable_switch_label): Delete variables.
+	* parse.h (Vwarn_future_time_stamp): Delete decl.
+	* parse.y (fold): Check state of warning ID
+	Octave:associativity-change and Octave:precedence-change instead
+	of using Vwarn_associativity_change and Vwarn_precedence_change.
+	(maybe_warn_associativity_change, maybe_warn_missing_semi,
+	maybe_warn_assign_as_truth_value, make_binary_op, make_boolean_op,
+	frob_function): Call warning_with_id instead of warning.	
+	* dynamic-ld.cc (octave_dynamic_loader::do_load): Likewise.
+
+	* ov.cc (warn_fortran_indexing, warn_imag_to_real, symbols_of_ov):
+	Delete DEFVARs and functions.
+	(Vwarn_fortran_indexing, Vwarn_imag_to_real): Delete variables.
+
+	* ov.cc (octave_value::vector_value, octave_value::int_vector_value,
+	octave_value::complex_vector_value): Check state of warning ID
+	Octave:fortran-indexing instead of using Vwarn_fortran_indexing.
+	* ov-cx-sparse.cc (octave_sparse_complex_matrix::double_value,
+	octave_sparse_complex_matrix::complex_value): Likewise.
+	* ov-cx-mat.cc (octave_complex_matrix::matrix_value,
+	octave_complex_matrix::complex_value): Likewise.
+	* ov-re-mat.cc (octave_matrix::complex_value,
+	octave_matrix::double_value): Likewise.
+	* ov-streamoff.cc (octave_streamoff::streamoff_value): Likewise.
+	* ov-re-sparse.cc (octave_sparse_matrix::complex_value,
+	octave_sparse_matrix::double_value): Likewise.
+	* ov-range.cc (octave_range::complex_value,
+	octave_range::double_value): Likewise.
+	* ov-ch-mat.cc (octave_char_matrix::complex_value,
+	octave_char_matrix::double_value): Likewise.
+	* ov-bool-sparse.cc (octave_sparse_bool_matrix::complex_value,
+	octave_sparse_bool_matrix::double_value): Likewise.
+	* ov-bool-mat.cc (octave_bool_matrix::complex_value,
+	octave_bool_matrix::double_value): Likewise.
+
+	* ov-cx-sparse.cc (octave_sparse_complex_matrix::double_value,
+	octave_sparse_complex_matrix::matrix_value,
+	octave_sparse_complex_matrix::sparse_matrix_value): Check state of
+	warning ID Octave:imag-to-real instead of using Vwarn_imag_to_real.
+	* ov-cx-mat.cc (octave_complex_matrix::double_value,
+	octave_complex_matrix::matrix_value,
+	octave_complex_matrix::complex_value,
+	octave_complex_matrix::sparse_matrix_value): Likewise.
+	* ov-complex.cc (octave_complex::double_value,
+	octave_complex::matrix_value, octave_complex::array_value): Likewise.
+
+	* ov.h (Vwarn_fortran_indexing, Vwarn_imag_to_real): Delete decls.
+
+	* pt-mat.cc (warn_empty_list_elements, warn_string_concat):	
+	Delete functions.
+	(symbols_of_pt_mat): Delete DEFVARs.
+	(Vwarn_empty_list_elements, Vwarn_string_concat): Delete variables.
+	(tm_row_const::tm_row_const_rep::eval_warning, tm_const::init,
+	maybe_warn_string_concat): Call warning_with_id instead of warning.
+
+	* ov-str-mat.cc (warn_str_to_num, symbols_of_ov_str_mat):
+	Delete DEFVAR and functions.
+	(Vwarn_str_to_num): Delete variable.
+	(CHAR_MATRIX_CONV): Call warning_with_id instead of warning.
+
+	* utils.cc (warn_neg_dim_as_zero, symbols_of_utils):
+	Delete DEFVAR and functions.
+	(Vwarn_neg_dim_as_zero): Delete variable.
+	(check_dimensions): Call warning_with_id instead of warning.
+
+	* pt-misc.cc (warn_undefined_return_values, symbols_of_pt_misc):
+	Delete DEFVAR and functions.
+	(Vwarn_undefined_return_values): Delete variable.
+	(tree_parameter_list::initialize_undefined_elements):
+	Call warning_with_id instead of warning.
+
+	* dynamic-ld.cc	(warn_reload_forces_clear, symbols_of_dynamic_ld):
+	Delete DEFVAR and functions.
+	(Vwarn_reload_forces_clear): Delete variable.
+	(do_clear_function, octave_dynamic_loader::do_load):	
+	Call warning_with_id instead of warning.
+	* error.cc (warning_enabled): Now extern.
+	(Fwarning): If specific id is not found, return state of "all".
+
+	* error.h: Provide decl.
+
+	* gripes.cc (warn_divide_by_zero, symbols_of_gripes):
+	Delete DEFVAR and functions.
+	(gripe_divide_by_zero): Check whether warning is enabled, then
+	call warning_with_id instead of warning.
+	(Vwarn_divide_by_zero): Delete variable.
+
+2006-04-27  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (Fexist): Fix doc string.
+
+	* help.cc (simple_help): No need to handle built-in constants now.
+	* variables.cc (do_who): Likewise.
+	(symbol_exist): Likewise.
+	(link_to_builtin_or_function): Likewise.
+	* symtab.cc (SYMBOL_DEF::type_as_string): Likewise.
+	(record::read_only_error): Likewise.
+	(SYMBOL_DEF::type): Likewise.
+	(record::variable_reference): Likewise.
+	(symbol_record::define_builtin_const): Delete function.
+
+	* symtab.h (symbol_record::define_builtin_const): Delete decl.
+	(symbol_record::symbol_def::is_constant): Delete function.
+	(symbol_record::symbol_def::is_builtin_constant): Delete function.
+	(symbol_record::symbol_def::is_constant): Delete function.
+	(symbol_record::is_builtin_constant): Delete function.
+	(SYMTAB_ALL_TYPES): No need to handle builtin-constants now.
+	(symbol_record::TYPE): Remove BUILTIN_CONSTANT from enum.
+
+	* defun.cc (install_builtin_constant): Delete function.
+	* defun-int.h (install_builtin_constant): Delete decl.
+
+	* variables.cc (bind_builtin_constant): Delete function.
+	* variables.h (bind_builtin_constant): Delete decl.
+
+	* defun-int.h (DEFCONST, DEFCONSTX, DEFCONST_INTERNAL,
+	DEFCONSTX_INTERNAL): Delete definitions.
+
+	* sighandlers.cc (FSIG): New function to replace DEFCONST in
+	symbols_of_sighandlers. 
+
+	* octave.cc (intern_argv): Set octave_argv instead of calling
+	bind_builtin_variable here.
+	(Fargv, Fprogram_invocation_name, Fprogram_name): New functions to
+	replace DEFCONSTs in symbols_of_toplvev in toplev.cc.
+	(octave_program_invocation_name, octave_program_name):	
+	New static variables.
+	(execute_command_line_file): Use unwind_protect_str to protect
+	octave_program_invocation_name, octave_program_name instead of
+	using a restore function.
+	(restore_program_name): Delete.
+
+	* defaults.cc (FOCTAVE_HOME): New function to replace DEFCONST in
+	symbols_of_defaults.
+
+2006-04-27  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp): Fix for infinite loop in
+	regexp. Include news regexp arguments, and associated tests.
+
+2006-04-26  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc: Also instantiate do_read functions for boolNDArray.
+
+2006-04-26  Bill Denney  <denney at seas.upenn.edu>
+
+ 	* pager.cc (Fterminal_size): Add list_in_columns to @seealso.
+
+2006-04-26  John W. Eaton  <jwe at octave.org>
+
+	* dirfns.cc (Ffilesep): New function to replace DEFCONST in
+	symbols_of_dirfns.
+	(Fpathsep): New function.
+
+	* defaults.cc (set_default_default_exec_path): Use
+	dir_path::path_sep_str instead of std::string (SEPCHAR_STR).
+	(set_default_exec_path): Likewise.
+	(set_default_path): Likewise.
+	(maybe_add_default_load_path): Likewise.  Use dir_path::is_path_sep.
+
+2006-04-18  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/regexp.cc: Include <algorithm>, for transform decl.
+
+	* DLD-FUNCTIONS/ccolamd.cc (Fccolamd, Fcsymamd):	
+	Always return something.
+
+	* sighandlers.cc (octave_set_signal_handler,
+	octave_set_interrupt_handler): New arg, restart_syscalls, with
+	default value true.
+	* sighandlers.h: Fix decls to match.
+	* sysdep.cc (octave_kbhit): Disable restarting of system calls.
+
+	* help.cc (Flookfor): Add std qualifier to transform function.
+	Include <algorithm>, for transform decl.
+
+2006-04-16  John W. Eaton  <jwe at octave.org>
+
+	* pager.h (octave_diary_buf, octave_pager_buf): Use std:stringbuf
+	directly.
+
+	* ls-mat-ascii.cc (read_mat_ascii_data): Use std::istringstream
+	directly.
+	* load-save.cc (parse_save_options): Likewise.
+	* ls-mat5.cc (read_mat5_binary_element): Likewise.
+	* oct-strstrm.h (octave_istrstream::is): Likewise.
+
+	* __gnuplot_raw__.l (printrange, handle_using, gnuplot::do_open,
+	gnuplot::do_set, gnuplot::do_show, gnuplot::makeplot,
+	gnuplot::handle_title): Use std::ostringstream directly.
+	* toplev.cc (run_command_and_return_output): Likewise.
+	* symtab.h (symbol_table::symbol_table): Likewise.
+	* strfns.cc (Flist_in_columns): Likewise.
+	* pt.cc (tree::str_print_code): Likewise.
+	* parse.y (yyerror, fold, finish_matrix): Likewise. 
+	* pr-output.cc (PRINT_ND_ARRAY, octave_print_internal, Fdisp):	
+	Likewise.
+	* symtab.cc (symbol_table::print_descriptor): Likewise.
+	* ov-list.cc (octave_list::print_raw, octave_list::save_ascii,
+	octave_list::save_binary, octave_list::save_hdf5): Likewise.
+	* ov-fcn-inline.cc (octave_fcn_inline::octave_fcn_inline,
+	octave_fcn_inline::load_ascii, octave_fcn_inline::print_raw,
+	Finline): Likewise.
+	* ov-fcn-handle.cc (octave_fcn_handle::load_ascii,
+	octave_fcn_handle::save_binary, octave_fcn_handle::save_hdf5):
+	Likewise.
+	* ov-cs-list.cc (octave_cs_list::print_raw): Likewise.
+	* ov-cell.cc (octave_cell::print_raw, octave_cell::save_hdf5):
+	Likewise.
+	* oct-strstrm.h (octave_ostrstream::os, octave_ostrstream::str):
+	Likewise.
+	* oct-stream.h (scanf_format_list::buf, printf_format_list::buf):
+	Likewise.
+	* oct-stream.cc (scanf_format_list::scanf_format_list,
+	printf_format_list::printf_format_list,
+	octave_base_stream::do_gets, BEGIN_CHAR_CLASS_CONVERSION, 
+	octave_stream_list::do_list_open_files): Likewise.
+	* ls-oct-ascii.h (extract_keyword): Likewise.
+	* load-save.cc (do_load): Likewise.
+	* lex.l (have_continuation, handle_string): Likewise.
+	* input.cc (get_user_input): Likewise.
+	* dirfns.cc (Fls): Likewise.
+	* error.cc (error_message_buffer, vwarning, verror, pr_where):
+	Likewise.
+	* defun.cc (print_usage): Likewise.
+	* help.cc (display_help_text, Ftype, first_help_sentence):
+	Likewise.
+	* ls-mat5.cc (save_mat5_binary_element): Likewise.
+	* DLD-FUNCTIONS/regexp.cc (octregexp): Likewise.
+	* DLD-FUNCTIONS/fftw_wisdom.cc (Ffftw_wisdom): Likewise.
+
+2006-04-13  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (lex.o parse.o __gnuplot_raw__.o, pic/parse.o
+	pic/__gnuplot_raw__.o):	Omit -Wold-style-cast from CXXFLAGS.
+
+	* ls-mat5.cc (READ_INTEGER_DATA): Allocate local buffer to avoid
+	pointer tricks.
+
+	* DLD-FUNCTIONS/regexp.cc (octregexp): Use OCTAVE_LOCAL_BUFFER
+	instead of allocting memory with malloc.
+
+	* DLD-FUNCTIONS/sparse.cc (Fsparse): Use octave_value extractors
+	instead of using get_rep.
+
+	* DLD-FUNCTIONS/dispatch.cc (dispatch_record): Use dynamic_cast,
+	not reinterpret_cast.
+
+	* DLD-FUNCTIONS/besselj.cc (Fairy): Use int_value instead of
+	double_value and cast to extract kind arg.
+	(int_arrayN_to_array): Arg is ArrayN<octave_idx_type>, not ArrayN<int>.
+
+	* OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc,
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc,
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc,
+	OPERATORS/op-s-scm.cc, OPERATORS/op-s-sm.cc,
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-scm-cs.cc,
+	OPERATORS/op-scm-m.cc, OPERATORS/op-scm-s.cc,
+	OPERATORS/op-scm-scm.cc, OPERATORS/op-scm-sm.cc,
+	OPERATORS/op-sm-cm.cc, OPERATORS/op-sm-cs.cc,
+	OPERATORS/op-sm-m.cc, OPERATORS/op-sm-s.cc,
+	OPERATORS/op-sm-scm.cc, OPERATORS/op-sm-sm.cc: No need to cast
+	away const just to cache sparse type.
+	* ov-base-sparse.h (octave_base_sparse::typ): Now mutable.
+	(octave_base_sparse::sparse_type): Now const.
+
+	* OPERATORS/op-cm-scm.cc (DEFBINOP(div)): Explicitly cast args
+	here instead of using CAST_BINOP_ARGS.
+
+	* OPERATORS/op-streamoff.cc (STREAMOFF_COMP_OP): Second arg to 
+	CAST_BINOP_ARGS is also const.
+
+	* DLD-FUNCTIONS/chol.cc (Fcholinv, Fchol2inv): Eliminate nargout
+	arg to avoid unused variable warnings.
+
+	* unwind-prot.h, unwind-prot.cc (unwind_protect::save_bool,
+	unwind_protect::save_int, unwind_protect::save_str,
+	unwind_protect::save_ptr, unwind_protect::save_var):
+	Pointer args now const.
+	(unwind_protect_const_ptr): New macro.
+
+	* symtab.cc (maybe_list_cmp_fcn): Use static_cast instead of X_CAST.
+	* variables.cc (symbol_record_name_compare): Likewise.
+	* ls-mat5.cc (MAT5_DO_WRITE, save_mat5_binary_element): Likewise.
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_hdf5,
+	octave_fcn_handle::load_hdf5): Eliminate unnecessary casts.
+	* ov-fcn-inline.cc (octave_fcn_inline::save_hdf5,
+	octave_fcn_inline::load_hdf5): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::save_hdf5,
+	octave_char_matrix_str::load_hdf5): Likewise.
+	* ov-bool-sparse.cc (octave_sparse_bool_matrix::save_hdf5,
+	octave_sparse_bool_matrix::load_hdf5): Likewise.
+	* ov-cx-sparse.cc (octave_sparse_complex_matrix::save_hdf5,
+	octave_sparse_complex_matrix::load_hdf5): Likewise.
+	* ov-re-sparse.cc (octave_sparse_matrix::save_hdf5,
+	octave_sparse_matrix::load_hdf5): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::save_ascii,
+	octave_char_matrix_str::load_ascii): Likewise.
+	* mappers.cc (xtoascii): Likewise.
+	* load-save.cc (read_binary_file_header, write_header): Likewise.
+	* parse.y (get_help_from_file, parse_fcn_file): Likewise.
+	* DLD-FUNCTIONS/rand.cc (do_rand): Likewise.
+	* ls-hdf5.cc (read_hdf5_data, hdf5_add_attr, save_hdf5_empty,
+	load_hdf5_empty add_hdf5_data): Likewise.
+	* ls-mat4.cc (read_mat_binary_data): Likewise.
+	* ls-mat5.cc (read_mat5_binary_element): Likewise.
+
+	* oct-stream.cc (expand_char_class, octave_base_stream::do_gets):
+	Use static_cast instead of C-style cast.
+	* oct-procbuf.cc (kluge_procbuf_delay): Likewise.
+	* parse.y (gobble_leading_white_space,: Likewise.
+	* DLD-FUNCTIONS/besselj.cc (int_array2_to_matrix,
+	int_arrayN_to_array): Likewise.
+	* DLD-FUNCTIONS/colamd.cc (Fcolamd, Fsymamd): Likewise.
+	* DLD-FUNCTIONS/ccolamd.cc (Fcsymamd): Likewise.
+	* pt-pr-code.cc (tree_print_code::print_comment_elt): Likewise.
+	* DLD-FUNCTIONS/besselj.cc (do_bessel): Likewise.
+	* DLD-FUNCTIONS/spchol.cc (Fsymfact): Likewise.
+	* DLD-FUNCTIONS/sparse.cc (sparse_find): Likewise.
+	* DLD-FUNCTIONS/sort.cc (FloatFlip): Likewise.
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Likewise.
+	* ls-mat5.cc (read_mat5_binary_element, OCTAVE_MAT5_INTEGER_READ,
+	read_mat5_binary_element, save_mat5_binary_element): Likewise.
+
+	* DLD-FUNCTIONS/splu.cc (Fspinv): Use dynamic_cast instead of
+	C-style cast.
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Likewise.
+
+	* DLD-FUNCTIONS/sort.cc (mx_sort): Use reinterpret_cast instead of
+	C-style cast.
+	* ls-mat5.cc (write_mat5_tag): Likewise.
+
+	* ov-typeinfo.h (octave_value_typeinfo::octave_value_typeinfo):
+	Eliminate unnecessary casts in constructor initializers.
+
+	* ops.h (CAST_CONV_ARG, CAST_UNOP_ARG, CAST_BINOP_ARGS,
+	DEFASSIGNANYOP_FN): Use C++ dynamic_cast instead of DYNAMIC_CAST macro.
+
+	* unwind-prot.h (unwind_protect_ptr): Use combination of
+	reinterpret_cast and const_cast instead of X_CAST.
+
+	* dynamic-ld.cc (loader::do_load): Use reinterpret_cast instead of
+	X_CAST.
+	* ov-base-int.cc (octave_base_int_matrix<T>::save_binary,
+	octave_base_int_matrix<T>::load_binary,
+	octave_base_int_scalar<T>::save_binary,
+	octave_base_int_scalar<T>::load_binary): Likewise.
+	* ov-bool-mat.cc (octave_bool_matrix::save_binary,
+	octave_bool_matrix::load_binary): Likewise.
+	* ov-bool-sparse.cc (octave_sparse_bool_matrix::save_binary,
+	octave_sparse_bool_matrix::load_binary): Likewise.
+	* ov-bool.cc (octave_bool::save_binary, octave_bool::load_binary):
+	Likewise.
+	* ov-cell.cc (octave_cell::save_binary, octave_cell::load_binary):
+	Likewise.
+	* ov-complex.cc (octave_complex::save_binary,
+	octave_complex::load_binary): Likewise.
+	* ov-cx-mat.cc (octave_matrix::save_binary,
+	octave_matrix::load_binary): Likewise.
+	* ov-cx-sparse.cc (octave_sparse_complex_matrix::save_binary,
+	octave_sparse_complex_matrix::load_binary): Likewise.
+	* ov-fcn-handle.cc (octave_fcn_handle::save_binary,
+	octave_fcn_handle::load_binary): Likewise.
+	* ov-fcn-inline.cc (octave_fcn_inline::save_binary,
+	octave_fcn_inline::load_binary): Likewise.
+	* ov-list.cc (octave_list::save_binary, octave_list::load_binary):
+	Likewise.
+	* ov-range.cc (octave_range::save_binary, octave_range::load_binary): 
+	Likewise.
+	* ov-re-mat.cc (octave_matrix::save_binary,
+	octave_matrix::load_binary): Likewise.
+	* ov-re-sparse.cc (octave_sparse_matrix::save_binary,
+	octave_sparse_matrix::load_binary): Likewise.
+	* ov-scalar.cc (octave_scalar::save_binary,
+	octave_scalar::load_binary): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::save_binary,
+	(octave_char_matrix_str::load_binary): Likewise.
+	* ov-struct.cc (octave_struct::save_binary,
+	octave_struct::load_binary): Likewise.
+	* ls-oct-binary.cc (save_binary_data, read_binary_data): Likewise.
+	* ls-mat4.cc (read_mat_file_header, save_mat_binary_data): Likewise.
+	* ls-mat5.cc (read_mat5_tag, read_mat5_binary_element,
+	read_mat5_binary_element, read_mat5_binary_file_header,
+	MAT5_DO_WRITE, write_mat5_array, write_mat5_integer_data,
+	save_mat5_binary_element, READ_INTEGER_DATA): Likewise.
+
+2006-04-12  John W. Eaton  <jwe at octave.org>
+
+	* ov.h (OV_REP_TYPE): New macro.
+
+	* DLD-FUNCTIONS/sparse.cc (MINMAX_BODY): No need to cast arg1 to
+	const octave_sparse_matrix&.
+
+	* ov-base.cc (print_answer_id_name, warn_resize_on_range_error,
+	warn_num_to_str, silent_functions): Move here, from ov.cc.
+	(Vwarn_resize_on_range_error, Vsilent_functions): Likewise.
+	(Vprint_answer_id_name): Likewise.  Now static.
+	(symbols_of_ov_base): New function.  Move DEFVARs for
+	print_answer_id_name, warn_resize_on_range_error, warn_num_to_str,
+	and silent_functions here from symbols_of_ov in ov.cc.
+	* ov.h (Vprint_answer_id_name): Delete decl.
+	* ov-base.h (Vwarn_resize_on_range_error, Vwarn_num_to_str):	
+	Move decls here from ov.h.
+
+	* ov-str-mat.cc (warn_str_to_num): Move here, from ov.cc.
+	(Vwarn_str_to_num): Likewise.  Now static.
+	(symbols_of_ov_str_mat): New function.  Move DEFVAR for
+	warn_str_to_num here from symbols_of_ov in ov.cc.
+	* ov.h (Vwarn_str_to_num): Delete decl.
+
+	* ov-struct.cc (octave_struct::load_ascii): Pass loop counter, not
+	count, to read_ascii.
+	* ov-list.cc (octave_list::load_ascii): Likewise.
+
+	* ov-list.cc (octave_list::do_index_op): Allow index to extract
+	multiple items.  Result is always a list.
+
+	* pr-output.cc (struct_levels_to_print): Move here from ov.cc.
+	(Vstruct-levels_to_print): Likewise.
+	(symbols_of_pr_output): Move DEFVAR for struct_levels_to_print here
+	from symbols_of_ov in ov.cc.
+	* pr-output.h (Vstruct_levels_to_print): Nove decl here from ov.h.
+
+	* gripes.cc (warn_divide_by_zero): Move here from ov.cc.
+	(Vwarn_divide_by_zero): Likewise.  Now static.
+	(symbols_of_gripes): New function.  Move DEFVAR for
+	warn_divide_by_zero here from symbols_of_ov in ov.cc.
+	* ov.h (Vwarn_divide_by_zero): Delete decl.
+
+	* load-save.cc (do_load): Declare count octave_idx_type, not int.
+	* ls-oct-ascii.cc, ls-oct-ascii.h (read_ascii_data): Likewise.
+
+	Rearrange octave_value class hierarchy so that rep is a pointer
+	an octave_base_value object and the octave_base_value class
+	stores the reference count.  Virtualness now goes with the
+	octave_base_value class, not the octave_value class.
+
+	* ops.h, ov-base-int.cc, ov-base-int.h, ov-base-mat.h,
+	ov-base-scalar.h, ov-base-sparse.h, ov-base.cc, ov-base.h,
+	ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc,
+	ov-bool-sparse.h, ov-bool.cc, ov-bool.h, ov-cell.cc, ov-cell.h,
+	ov-ch-mat.h, ov-colon.h, ov-complex.cc, ov-complex.h,
+	ov-cs-list.h, ov-cx-mat.cc, ov-cx-mat.h, ov-cx-sparse.cc,
+	ov-cx-sparse.h, ov-fcn-handle.h, ov-fcn-inline.h, ov-fcn.cc,
+	ov-fcn.h, ov-intx.h, ov-list.cc, ov-list.h, ov-range.cc,
+	ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc,
+	ov-re-sparse.h, ov-scalar.h, ov-str-mat.cc, ov-str-mat.h,
+	ov-streamoff.h, ov-struct.cc, ov-struct.h, ov-type-conv.h,
+	ov-typeinfo.cc, ov-typeinfo.h, ov-va-args.h, ov.cc, ov.h,
+	variables.cc, DLD-FUNCTIONS/matrix_type.cc, DLD-FUNCTIONS/splu.cc,
+	OPERATORS/op-chm.cc: Cope with octave_value hierarchy changes
+	(apologies for the lack of detail).
+
+	* ov.cc (octave_value::nil_rep): Delete.
+	* ov.h (octave_value::nil_rep): Delete decl.
+
+	* ov-base.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA,
+	DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA, 
+	DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2,
+	DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA):
+	Move macro definitions here from ov.h.
+	(struct_indent, increment_struct_indent, decrement_struct_indent,
+	list_indent, increment_list_indent, decrement_list_indent):
+	Delete decls.
+
+	* ov-base.cc. ov-base.h (do_index_op, ndims, all, any,
+	convert_to_str, print_with_name, numeric_assign,
+	reset_indent_level, increment_indent_level,
+	decrement_indent_level, current_print_indent_level, newline,
+	indent, reset): Move member functions here from octave_value class.
+	(count, curr_print_indent_level, beginning_of_line):
+	Move data members here from octave_value class.
+	(gripe_indexed_assignment, gripe_assign_conversion_failed,
+	gripe_no_conversion): Move here from ov.cc.
+
+	* ov.h (class octave_xvalue): Delete.
+	(octave_value::octave_value (const octave_xvalue&)): Delete.
+	(anonymous union): Delete.
+	(octave_value::rep): Now a pointer to octave_base_value instead of
+	octave_value.
+
+	(octave_value::internal_rep): Return pointer to octave_base_value,
+	not octave_value.
+	
+2006-04-11  John W. Eaton  <jwe at octave.org>
+
+	* pt-assign.cc (tree_simple_assignment::rvalue,
+	tree_multi_assignment::rvalue):
+	Error if RHS is a comma-separated list.
+
+2006-04-07  John W. Eaton  <jwe at octave.org>
+
+	* defaults.cc (FOCTAVE_VERSION): New function to replace
+	corresponding DEFCONSTX macro in symbols_of_defaults.
+
+	* file-io.cc (FP_tmpdir, FSEEK_SET, FSEEK_CUR, FSEEK_END, Fstdin,
+	Fstdout, Fstderr): New functions to replace DEFCONSTX macros in
+	symbols_of_file_io.
+	(const_value): New static function.
+	(symbols_of_file_io): Delete.
+
+	* syscalls.cc (FF_DUPFD, FF_GETFD, FF_GETFL, FF_SETFD, FF_SETFL,
+	FO_APPEND, FO_ASYNC, FO_CREAT, FO_EXCL, FO_NONBLOCK, FO_RDONLY,
+	FO_RDWR, FO_SYNC, FO_TRUNC, FO_WRONLY, FWNOHANG, FWUNTRACED,
+	FWCONTINUE): New functions to replace DEFCONSTX macros in
+	symbols_of_syscalls.
+	(const_value): New static function.
+	(symbols_of_syscalls): Delete.
+
+	* pr-output.cc (pr_max_internal, pr_min_internal):
+	Return 0 if all values are Inf or NaN.
+	Always leave space for sign when printing Inf or NaN values.
+
+	* parse.y (Fmfilename): Don't let filenames like ../foo fake us out.
+
+	* data.cc (fill_matrix): Create separate versions for int, bool,
+	and double, and Complex values.
+	(FInf, FNaN, Fe, Feps, Fpi, Frealmax, Frealmin, FI, FNA, Ffalse,
+	Ftrue): New functions to replace DEFCONST and DEFCONSTX macros in
+	symbols_of_data.  Provide i, J, and j aliases for I.
+	Provide nan alias for NaN.  Provide inf alias for Inf.
+	(symbols_of_data): Delete.
+
+2006-04-06  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (parse_and_execute, parse_fcn_file):
+	Create octave_script_function object and push it on the call stack. 
+
+	* parse.y (Fmfilename): Check for script or user function file on
+	call stack.
+
+	* ov-builtin.cc (octave_builtin::do_multi_index_op):
+	Use octave_call_stack instead of curr_function to save pointer to
+	current function.
+	* ov-mapper.cc (octave_mapper::do_multi_index_op): Likewise.
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op): Likewise.
+
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Use octave_call_stack instead of
+	curr_function to get pointer to current function.
+	* pt-arg-list.cc (list::convert_to_const_vector): Likewise.
+	* variables.cc (Fmlock, Fmunlock, Fmislocked): Likewise.
+	* input.cc (get_user_input): Likewise.
+	* error.cc (warning_1, error_2): Likewise.  Only enter debug mode
+	if there is a scripting language caller.
+	* ov-usr-fcn.cc (Fva_arg, Fva_start, Fvr_val): Likewise.  Check
+	scripting language caller, not current function.
+
+	* toplev.cc (curr_caller_function, curr_function): Delete.
+	* toplev.h: Delete decls.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Don't protect and set curr_caller_function.
+	* ov-builtin.cc (octave_builtin::do_multi_index_op): Likewise.
+	* ov-mapper.cc (octave_mapper::do_multi_index_op): Likewise.
+
+	* variables.cc (do_who): Use octave_call_stack instead of
+	curr_caller_function to get pointer to calling function.
+	* input.cc (get_user_input): Likewise.
+	* error.cc (pr_where): Likewise.  No need for curr_function now.
+	* parse.y (Fmfilename): Likewise.  Check for scripting language
+	caller, not any calling function.
+
+	* ov-usr-fcn.h (octave_user_script): New class.
+	* ov-fcn.h (octave_function::is_user_script): New virtual function.
+
+	* toplev.h, toplev.cc (octave_call_stack): New class.
+
+	* debug.cc (Fdbwhere): Use get_user_function here.
+
+2006-04-05  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (mk-pkg-add): Use mfilename to simplify.
+	(PKG_ADD): Don't pass --prefix arg to mk-pkg-add.
+	(PKG_ADD.inst): Delete target.
+	(clean): Don't remove PKG_ADD.inst.
+	(install-oct): Don't depend on PKG_ADD.inst.  Install PKG_ADD, not
+	PKG_ADD.inst.
+
+	* parse.y (Fmfilename): New function.
+
+2006-04-04  David Bateman  <dbateman at free.fr>
+
+	* help.cc (Flookfor): Skip overloaded functions.  Lookup help text
+	of autoloaded function, not parent that contains the autoload.
+
+2006-04-03  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Fresize): New function.
+	* oct-map.cc, ov-base-mat.cc, ov-base-sparse.cc, ov-base.cc,
+	ov-bool.cc, ov-complex.cc, ov-range.cc, ov-scalar.cc,
+	ov-str-mat.cc (resize): Add boolean fill argument.
+	* oct-map.h, ov-base-mat.h, ov-base-sparse.h, ov-base.h,
+	ov-bool.h, ov-complex.h, ov-intx.h, ov-range.h, ov-scalar.h,
+	ov-str-mat.h, ov.h (resize): Ditto.
+	
+	* DLD-FUNCTIONS/rand.cc (do_rand): Additional argument for
+        gamma and poisson distributions.  Change "state" and "seed"
+        arguments so that they choose between generators.
+	Add, poisson, gamma and exponential generators.
+	(Frand, Frandn): Update docs for new generators, add tests.
+	(Frande, Frandp, Frandg): New generators, with test code.
+
+	* DLD-FUNCTIONS/daspk.cc (Fdaspk): Allow functions to be passed
+	using function handles, inline functions, and cell arrays of
+	strings, inline and function handles.
+	* DLD-FUNCTIONS/dasrtk.cc (Fdasrt): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (Fdassl): Likewise.
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (Flsode):  Likewise.
+
+	* ls-hdf5.h (hdf5_fstreambase::open): Remove unused arg prot.
+
+2006-03-30  Bill Denney  <denney at seas.upenn.edu>
+
+ 	* data.cc: Include numel in @seealso.
+
+2006-03-30  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/fftw_wisdom.cc: Don't attempt to save wisdom to
+	an empty filename or invalid filename.
+
+2006-03-28  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/matrix_type.cc: Update copyright notice and FSF
+	address.
+
+2006-03-24  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/spchol.cc (Fsymbfact): Use CHOLMOD_NAME to select
+	proper version of row_subtree function.
+
+	* ov-cell.cc (octave_cell::save_hdf5): Use OSSTREAM instead of
+	fixed character buffer and sprintf.
+	* ov-list.cc (octave_list::save_hdf5, octave_list::save_ascii,
+	octave_list::save_binary): Likewise.
+
+	* ov-cell.h (octave_cell::convert_to_str_internal):
+	Undo previous change for pad arg.
+	* ov-cell.cc (octave_cell::all_strings): Reinstate pad arg, pass
+	it on to all_strings.
+	* ov.h (octave_value::all_strings): Reinstate pad arg.
+	* ov-base.cc (octave_base_value::all_strings): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::all_strings): Likewise.
+	* ov.h, ov-base.h, ov-cell.h, ov-str-mat.h: Fix all_strings decls.
+
+2005-10-25  David Bateman  <dbateman at free.fr>
+
+        * data.cc (do_cat): With 1 arg, return [](0x0) for compatibility.
+
+2006-03-23  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.5+.
+
+2006-03-22  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.5.
+	(OCTAVE_API_VERSION): Now api-v18.
+	(OCTAVE_RELEASE_DATE): Now 2006-03-22.
+
+2006-03-21  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.h (octave_cell::convert_to_str_internal):
+	Ignore pad and force args.
+	* ov-cell.cc (octave_cell::all_strings): Delete args.  Never pad.
+	* ov-base.cc (octave_base_value::all_strings): Delete args.
+	Always force string conversion, never pad.
+	* ov-str-mat.cc (octave_char_matrix_str::all_strings):
+	Delete args.  Don't strip whitespace.
+	* ov.h, ov-base.h, ov-cell.h, ov-str-mat.h: Fix all_strings decls.
+	* strfns.cc (Fchar): No args for all_strings.
+
+2006-03-21  David bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/getrusage.cc (Fgetrusage): Use GetProcessTimes for
+	MinGW to obtain user and system times.
+
+2006-03-17  John W. Eaton  <jwe at octave.org>
+
+	* strfns.cc (F__list_in_columns__): New function.
+
+2006-03-16  Bill Denney  <bill at givebillmoney.com>
+
+	* DLD-FUNCTIONS/time.cc: Improve @seealso entries in doc strings.
+
+2006-03-16  John W. Eaton  <jwe at octave.org>
+
+	* __gnuplot_raw__.l (F__gnuplot_show__): Temporarily use DEFCMD
+	instead of DEFUN.
+	(symbols_of___gnuplot_raw__): Temporarily mark __gnuplot_plot__,
+	__gnuplot_set__, __gnuplot_splot__, and __gnuplot_replot__ as raw
+	commands.
+
+	* variables.cc (is_marked_as_rawcommand, unmark_rawcommand,
+	mark_as_rawcommand): Temporarily not static.
+	* variables.h: Temporarily Provide decls.
+
+2006-03-16  David Bateman  <dbateman at free.fr>
+
+	* sparse-xdiv.cc (result_ok): delete.
+	(xdiv, xleftdiv): Simplify to use version of SpareMatrix::solve
+	and SparseComplexMatrix::solve which internally treats rectangular
+	and singular matrices.
+	* DLD-FUNCTIONS/luinc.cc: Remove error test for singular matrix as
+	QR solver now implemented.
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Paranoid check on 
+	error_state. Disable tests for the detection of underdetermined 
+	lower and over-determined upper matrix due to problems with 
+	non minimum norm solutions.
+	* DLD-FUNCTIONS/spqr.cc: Warning for issue of use of Fspqr for
+	under-determined problems.
+
+2006-03-16  John W. Eaton  <jwe at octave.org>
+
+	* __gnuplot_raw__.l: Move here from DLD-FUNCTIONS/__gnuplot_raw__.l.
+	Use DEFUN, not DEFUN_DLD.  Include defun.h, not defun-dld.h.
+	(gnuplot::do_init):Move guts to symbols_of___gnuplot_raw__.
+	(symbols_of___gnuplot_raw__): New function.
+
+	* Makefile.in (DLD_XSRC): Delete __gnuplot_raw__.l from the list.
+	(DIST_SRC): Include __gnuplot_raw__.l in the list.
+	(__gnuplot_raw__.cc): Depend on __gnuplot_raw__.l, not
+	DLD-FUNCTIONS/__gnuplot_raw__.l
+
+	* ls-oct-ascii.h (extract_keyword): Use std::string compare method
+	instead of strncmp.
+	* ls-oct-ascii.cc (extract_keyword): Likewise. 
+
+2006-03-15  William Poetra Yoga Hadisoeseno  <williampoetra at gmail.com>
+
+	* src/data.cc (Frows, Fcolumns): New functions.
+
+	* DLD-FUNCTIONS/time.cc (Fstrptime, Fstrftime): Fix docstring.
+
+	* strfns.cc (Fstrcmp): Fixed docstring.
+
+2006-03-15  John W. Eaton  <jwe at octave.org>
+
+	* pager.cc (Fterminal_size): New function.
+
+	* help.cc (help_from_info): Simplify.
+	(try_info): Use feval to call doc instead of executing info program.
+	(additional_help_message): Point users to doc instead of help -i.
+	From Søren Hauberg <soren at hauberg.org>.
+
+	* toplev.cc (Fsystem): Return output if nargout > 1, not 0.
+
+2006-03-14  Keith Goodman  <kwgoodman at gmail.com>
+
+	* help.cc (Fhelp, Fwhich, Flookfor): Doc string fix.
+
+2006-03-14  John W. Eaton  <jwe at octave.org>
+
+	* defun.cc (print_usage): New arg, extra_msg.
+	
+	* xpow.cc: Omit tests for now.
+
+	* parse.y (QUOTE, TRANSPOSE): For compatibility, now have same
+	precedence as POW and EPOW.
+
+2006-03-14  Bill Denney  <bill at givebillmoney.com>
+
+         * load-save.cc (Fload, Fsave): Update docstring for functional form.
+
+2006-03-14  John W. Eaton  <jwe at octave.org>
+
+	* xpow.cc (elem_xpow): Undo previous change.
+
+2006-03-14  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* xpow.cc: New tests.
+
+2006-03-13  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (fcn_out_of_date): No longer static.
+	* ov-fcn-handle.cc (warn_reload): New function.
+	(octave_fcn_handle::subsref): Implement basic logic for updating
+	when pointed-to function changes.
+
+2006-03-10  John W. Eaton  <jwe at octave.org>
+
+	* xpow.cc (elem_xpow): Only use complex pow if really necessary.
+
+	* symtab.cc (symbol_table::glob, symbol_table::symbol_list,
+	symbol_table::subsymbol_list): Force result to be a column
+	vector.
+
+	* oct-stream.h (octave_stream::stream_ok): Undo previous change.
+	Eliminate who parameter.  Change all callers.
+
+	* variables.cc (do_who): Return more info in structure array for
+	verbose output.
+	* symtab.h (symbol_record::size, symbol_record::class_name,
+	symbol_record::is_sparse_type, symbol_record::is_complex_type,
+	symbol_record::size, symbol_record::symbol_def::class_name,
+	symbol_record::symbol_def::is_sparse_type,
+	symbol_record::symbol_def::is_complex_type): New functions.
+	* ov.h (octave_value::size): New function.
+
+2006-03-09  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (run_command_and_return_output): Swap output and
+	status for compatibility.
+
+	* Makefile.in (defaults.h, oct-conf.h): Force updates.
+
+	* defaults.h.in (OCTAVE_RELEASE): New macro.
+
+	* octave.cc (F__version_info__): New arg, release.
+	(initialize_version_info): Pass release arg to F__version_info__.
+
+	* toplev.cc: Include api_version in the list.
+
+	* Makefile.in (DIST_SRC): Include octave.cc here.
+	(DISTFILES, DEP_5): Not here.
+
+	* octave.cc (F__version_info__): New function.
+	(initialize_version_info): New function.
+	(octave_main): Call initialize_version_info just before reading
+	init files.
+
+	* version.h (OCTAVE_RELEASE_DATE): New macro.
+
+	* ov-fcn-handle.h (octave_fcn_handle::dims): New function.
+
+2006-03-08  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream::stream_ok): Move definition here,
+	from oct-stream.h.  New arg, warn.  If warn is true and stream is
+	invalid, print warning.
+	(octave_stream::error): Always avoid warning message from
+	stream_ok.  Return "invalid stream object" if stream is not ok.
+
+2006-03-08  David Bateman  <dbateman at free.fr>
+
+	* ov-mapper.cc (SPARSE_MAPPER_LOOP_2): Change nnz to nz to remove 
+	shadowed variable warning.
+	* DLD-FUNCTIONS/spqr.cc: Update for new upstream CXSPARSE release.
+
+2006-03-06  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (display_help_text): Force linebreak with @sp.
+
+2006-03-06  Keith Goodman  <kwgoodman at gmail.com>
+ 
+	* bitfcns.cc, data.cc, debug.cc, file-io.cc, help.cc,
+	load-save.cc, mappers.cc, ov-cell.cc, ov-fcn-inline.cc,
+	ov-struct.cc, ov-usr-fcn.cc, ov.cc, pr-output.cc, utils.cc,
+	variables.cc, DLD-FUNCTIONS/ccolamd.cc, DLD-FUNCTIONS/cellfun.cc,
+	DLD-FUNCTIONS/colamd.cc, DLD-FUNCTIONS/daspk.cc,
+	DLD-FUNCTIONS/dasrt.cc, DLD-FUNCTIONS/dassl.cc,
+	DLD-FUNCTIONS/fft.cc, DLD-FUNCTIONS/fft2.cc,
+	DLD-FUNCTIONS/fftn.cc, DLD-FUNCTIONS/fftw_wisdom.cc,
+	DLD-FUNCTIONS/gammainc.cc, DLD-FUNCTIONS/gcd.cc,
+	DLD-FUNCTIONS/luinc.cc,	DLD-FUNCTIONS/sparse.cc,
+	DLD-FUNCTIONS/spchol.cc, DLD-FUNCTIONS/splu.cc,
+	DLD-FUNCTIONS/spqr.cc, DLD-FUNCTIONS/sqrtm.cc:
+	Move @seealso inside @defXXX macro.  Remove "and" from @seealso.
+
+2006-03-04  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (additional_help_message): Don't print "\n" before message.
+	(help_from_symbol_table): If Vsuppress_verbose_help_message is
+	true, don't print which info.
+
+2006-03-03  John W. Eaton  <jwe at octave.org>
+
+	* dirfns.cc (Vconfirm_recursive_rmdir): New static variable.
+	(symbols_of_dirfns): DEFVAR it.
+	(confirm_recursive_rmdir): New function.
+	(Frmdir): Maybe ask for confirmation for recursive removal.
+	Require second arg to be "s".
+
+	* input.cc (octave_yes_or_no): New function.
+	(Fyes_or_no): New function.
+	* input.h (octave_yes_or_no): Provide decl.
+
+2006-03-02  John W. Eaton  <jwe at octave.org>
+
+	* dirfns.cc (Fmkdir, Frmdir): Now commands.
+
+2006-02-20  David Bateman  <dbateman at free.fr>
+
+	* ov.h (virtual bool is_sparse_type (bool)): New virtual function
+	* ov-base.h (bool is_sparse_type (bool)): New function
+	* ov-base-sparse.h (bool is_sparse_type (bool)): New function
+	* DLD-FUNCTIONS/ccolamd.cc, DLD-FUNCTION/colamd.cc, 
+	DLD-FUNCTIONS/__glpk__.cc, DLD-FUNCTIONS/splu.cc,
+	DLD-FUNCTIONS/sparse.cc, DLD-FUNCTIONS/matrix_type.cc, pt-mat.cc:
+	Replace us of 'arg.class_name () == "sparse"' with
+	'arg.is_sparse_type ()'
+	
+2006-02-20  David Bateman  <dbateman at free.fr>
+	
+	* pt-mat.cc (class tm_row_const): Add any_sparse bool variable.
+	(tm_row_const::tm_row_const_rep::do_init_element): Initialize
+	any_sparse variable if any matrice is sparse.
+	(class tm_const): Add any_sparse bool variable.
+	(tm_const::init): Initialize any_sparse variable.
+	(tree_matrix::rvalue): If any matrix is sparse use sparse matrix
+	as initial matrix for concatenation
+	* DLD-FUNCTIONS/matrix_type.cc: Add tests for new rectangular
+	diagonal, permuted diagonal, triangular and permuted triangular
+	matrices
+
+2006-02-20  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (__builtin_delete, __builtin_new): Use std::cerr for
+	messages instead of std::cout.
+	(main_loop, do_octave_atexit): Use octave_stdout, not std::cout.
+
+2006-02-15  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (Fautoload): Return struct array of autoload info if
+	nargin == 0.
+
+2006-02-15  Keith Goodman  <kwgoodman at gmail.com>
+
+	* help.cc (keywords): Doc string fix.
+
+2006-02-15  John W. Eaton  <jwe at octave.org>
+
+	* oct-procbuf.cc (close): Use __CYGWIN__ instead of __CYGWIN32__.
+
+2006-02-13  David Bateman  <dbateman at free.fr>
+
+	* DLD_FUNCTIONS/regexp.cc (octregexp): Add matlab compatiable
+	named tokens. Update the tests
+
+2006-02-10  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (\[{S}*): Maybe set lexer_flags.looking_at_return_list or
+	lexer_flags.looking_at_matrix_or_assign_lhs here.
+	* parse.y 
+	(return_list_beg): Don't use in_return_list here.
+	(assign_lhs, matrix): Don't use in_matrix_or_assign_lhs here.
+	(in_matrix_or_assign_lhs, in_return_list): Delete unused macros.
+	(matrix): Clear lexer_flags.looking_at_matrix_or_assign_lhs in all
+	cases.
+
+2006-02-09  John W. Eaton  <jwe at octave.org>
+
+	* utils.cc (oct_file_in_path): Check len > 4, not len > 2.
+	From Larrie Carr <larrie at telus.net>.
+
+2006-02-09  David Bateman  <dbateman at free.fr>
+
+        * DLD-FUNCTIONS/spqr.cc: New file for sparse QR and dmperm based on
+        CSparse.
+        * DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): dintinguish between
+        rectangular and singular matrices. Add tests.
+        * DLD-FUNCTIONS/luinc.cc: Add tests.
+        * DLD-FUNCTIONS/spkron.cc: Ditto.
+        * Makefile.in (DLD_XSRC): Add spqr.cc.
+        (OCT_LINK_DEPS): Add CSSPARSE_LIBS.
+        * sparse-xdiv.h: Remove conditio of lssolve.
+
+2006-02-08  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (frob_function): Clear ID_NAME from top_level symbol
+	table if we are defining a function at the top-level and a
+	function with the same name is already in the top-level symbol
+	table.
+
+2006-01-31  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-sparse.h (octave_base_sparse<T>::nzmax): New function.
+	* ov.h (octave_value::nzmax): New function.
+	* ov-base.cc (octave_base_value::nzmax): New function.
+	* ov-base.h: Provide decl.
+	* data.cc (Fnzmax): New function.
+	* DLD-FUNCTIONS/sparse.cc (Fnzmax): Delete.
+
+2006-01-31  Kim Hansen  <kim at i9.dk>
+
+	* __glpk__.cc (F__glpk__): Fix for sparse matrices.
+
+2006-01-30  John W. Eaton  <jwe at octave.org>
+
+	* gripes.cc (gripe_wrong_type_arg (const char*, const char*, bool)):
+	New function.
+	(gripe_wrong_type_arg (const char*, const std::string&, bool)):
+	Define using const char*, const char*, bool version.
+	(gripe_wrong_type_arg (const char*, const octave_value&, bool)):
+	Define using const char*, const std::string&, bool version.
+
+	* ov.h (octave_value::nnz): New function.
+	* ov-base.cc (octave_base_value::nnz): New function.
+	* ov-base.h: Provide decl.
+	* ov-base-mat.h (octave_base_matrix<MT>::nnz): New function.
+	* ov-base-scalar.h (octave_base_scalar<MT>::nnz): New function.
+	* Cell.cc (Cell::nnz): New function.
+	* Cell.h: Provide decl.
+	* data.cc (Fnnz): New function.	
+	* DLD-FUNCTIONS/sparse.cc (Fnnz): Delete.
+
+2006-01-13  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::print_raw): Correctly print scalar
+	structs and empty struct arrays.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (Fclearplot): For compatibility,
+	also turn off hold state for current figure.
+
+2006-01-13  Bill Denney  <bill at givebillmoney.com>
+
+ 	* dirfns.cc: Add @seealso{} to docstrings.
+
+2006-01-13  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (display_help_text): Use warning() to print raw Texinfo
+	source.  Don't redirect error output for makeinfo process.
+
+	* DLD-FUNCTIONS/__gnuplot_raw__.l (F__gnuplot_init__): Delete
+	function and PKG_ADD directive.
+	(gnuplot::gnuplot): Call do_init here.
+	(gnuplot::init): Delete static function.
+	(gnuplot::close_all): New static function.
+	(class gnuplot_X): New class.
+	(gnpulot_X::X): New static instance.
+
+2006-01-12  David Bateman  <dbateman at free.fr>
+
+	* help.cc (make_name_list): Add autoload functions to list of
+	available completions.
+	(simple_help): Add autoloaded functions to functions listed
+	(first_help_sentence): Avoid issue with single line help string 
+	that is not terminated in \n.
+	(Flookfor): Check for string match in the keyword/function, etc
+	name. Also look for string match in help of autoloaded functions.
+	Load oct-files to be able to access their help string.
+	* parse.y (string_vector autoloaded_functions (void)): New
+	function to list all autloaded functions.
+	(string_vector reverse_lookup_autoload (const std::string& nm)):
+	Reverse lookup function to match file to autoloaded functions.
+	* parse.h (autoloaded_functions, reverse_lookup_autoload): 
+	Declaration. 
+	
+	* oct-map.cc (maybe_delete_elements): New function.
+	* oct-map.h (maybe_delete_elements): Declare it.
+	* ov-struct.cc (octave_struct::subsref): Handle indexing empty
+	structure.
+	(octave_struct::subsasgn): If rhs is [], delete elements.
+	(octave_struct::print_raw): Handle printing empty structure. 	
+
+	* ls-mat5.cc (read_mat5_binary_element): Allow reading of sparse
+	elements when nnz doesn't equal nzmax. 
+	
+2006-01-10  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sparse.cc (sparse_find): Use Sparse<T>::nonzero() 
+	rather than Sparse<T>::nnz(), due to possibility of overallocation
+	of memory.
+
+2006-01-06  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.cc (Octave_map::transpose): Avoid GCC 3.3.x parse error.
+
+2005-12-14  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream::invalid_stream_error): Delete.
+	* oct-stream.h (octave_stream::stream_ok): Don't fail with error.
+
+2005-12-14  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/regexp.cc: New file.
+
+	* DLD-FUNCTIONS/dispatch.cc: Update tests for string/sq_string 
+	differences.
+
+	* error.cc (Vquiet_warning): New variable.
+	(vwarning): Use Vquiet_warning to prevent warning output.
+	(Fwarning): Include "quiet" option to Fwarning function.
+	Assign retval when using "query".  Typo in error message.
+	(Flastwarn): Clear warning_state when using Flastwarn to probe warning
+	message.
+
+	* ov-struct.cc: Update Fstruct tests for change in error output.
+
+	* Makefile.in: Include regexp when needed with appropriate libraries.
+
+2005-12-13  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: Change references to gplot.l to __gnuplot_raw__.l.
+	* DLD-FUNCTIONS/__gnuplot_raw__.l: Rename from DLD-FUNCTIONS/gplot.l.
+	Remove all references to deprecated gplot, gsplot, graw, gset and
+	gshow functions.
+	* help.cc (static help_list keywords[]): Remove gsplot and gplot.
+
+	* ls-oct-ascii.cc (save_three_d):  Don't strip Inf or NaN.
+	(save_ascii_data_for_plotting): Ditto.
+
+2005-12-13  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream_list::do_insert): Check open state
+	of stream in list instead of whether stream state is OK.
+
+2005-12-12  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-struct.cc (transpose): New function.
+	(install_struct_ops): Install it.
+
+	* oct-map.cc (Octave_map::transpose): New function.
+	* oct-map.h: Provide decl.
+
+2005-12-08  John W. Eaton  <jwe at octave.org>
+
+	* Cell.cc (Cell::column): New function.
+	* pt-loop.cc (DO_ND_LOOP): Simplify.
+	(simple_for_loop_command::eval): Correctly handle N-d numeric and
+	cell arrays when only the first dimension is 0.
+
+2005-12-07  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (NL): Also accept '\r'.
+
+	* error.cc (Vbacktrace_on_warning, warning_options,
+	Vlast_warning_id, Vlast_error_id): New file-scope variables.
+	(Vwarning_frequency, Vwarning_option): Delete unused variables.
+	(set_warning_option): Delete unused function.
+	(Fwarning): Update for compatibility.  Use DEFCMD, not DEFUN.
+	(warning_enabled, check_state): New functions.
+	(warning (const char *fmt, ...)): Use it.
+	(init_warning_options): New function.
+	(symbols_of_error): Call it.
+	(vwarning, Flastwarn): Handle Vlast_warning_id.  Improve compatibility.
+	(handle_message): New arg, ID.  Change all callers.
+	(vwarning, verror, error_1): New arg, ID.  Change all callers.
+	(verror, Flasterr): Handle Vlast_error_id.  Improve compatibility.
+
+	* error.cc (message_with_id, usage_with_id, warning_with_id,
+	error_with_id, parse_error_with_id): New functions.
+	(error_2, warning_1, usage_1): New functions.
+	* error.h (message_with_id, usage_with_id, warning_with_id,
+	error_with_id, parse_error_with_id): Provide decls.
+
+2005-11-30  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/schur.cc (Fschur): Doc string fix.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-11-28  John W. Eaton  <jwe at octave.org>
+
+	* syscalls.cc (Funame): New function.
+
+2005-11-21  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (pr_int): Fix thinko in byte-swapping for bit format.
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun):
+	Use C++ static_cast instead of C-style casts.
+
+2005-11-21  William Poetra Yoga H <williampoetra at yahoo.com>
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellfun):
+	Docstring and error message fixes.
+
+2005-11-17  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/minmax.cc (MINMAX_BODY): Don't cast arg1 to
+	const octave_complex_matrix&.
+
+2005-11-16  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (PKG_ADD.inst): New target.
+	(install-oct): Depend on it.
+	(clean): Remove it.
+
+	* mk-pkg-add: New option --install.  Don't use --prefix option.
+	Delete obsolete comments.
+
+	* Cell.cc (Cell::index): Indexing with () is a no-op, not an error.
+	* oct-map.cc (Octave_map::index): Likewise.
+	* ov-base-mat.cc (octave_base_matrix<MT>::do_index_op): Likewise.
+	* ov-base-sparse.cc (octave_base_sparse<T>::do_index_op): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::do_index_op_internal):
+	Likewise.
+
+2005-11-11  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (install-oct): Fix thinko in previous change.
+
+	* version.h (OCTAVE_VERSION): Now 2.9.4
+	(OCTAVE_API_VERSION): Now api-v17.
+
+	* variables.cc (symbol_out_of_date): Check for autoloads here too.
+
+	* Makefile.in (PKG_ADD): Depend on $(DLD_DEF_FILES), not $(DLD_SRC).
+	(%.df : %.cc): Also insert PKG_ADD commands in .df files.
+	(install-oct): Generate PKG_ADD file for install directory here.
+	Don't depend on PKG-ADD. No need to make .oct file links.
+	(clean): No need to delete links.
+	(stamp-oct-links): Delete target.
+	(distclean): No need to remove stamp-oct-links.
+	(all): Depend on $(OCT_FILES), not stamp-oct-links.
+
+	* mk-pkg-add: New file.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+	* mk-oct-links: Delete.
+	* Makefile.in (DISTFILES): Remove it from the list.
+
+2005-11-10  John W. Eaton  <jwe at octave.org>
+
+	* ov-str-mat.h (octave_char_matrix_str::permute,
+	octave_char_matrix_str::resize): New functions.
+	(octave_char_matrix_sq_str::reshape,
+	octave_char_matrix_sq_str::permute,
+	octave_char_matrix_sq_str::resize): New functions.
+
+	* OPERATORS/op-str-str.cc, OPERATORS/op-str-s.cc,
+	OPERATORS/op-str-m.cc: Use DEFNDCHARCATOP_FN.
+
+	* data.cc (do_cat): No need to handle character arrays specially here.
+
+	* ops.h (DEFNDCHARCATOP_FN): New macro.
+	* OPERATORS/op-int.h (OCTAVE_INT_CHAR_CONCAT_FN, 
+	OCTAVE_CHAR_INT_CONCAT_FN, OCTAVE_INSTALL_INT_CHAR_CONCAT_FN,
+	OCTAVE_INSTALL_CHAR_INT_CONCAT_FN): New macros.
+	* OPERATORS/op-int-concat.cc: Use them do define char/int op functions.
+	(install_int_concat_ops): Install char/int concat ops.
+
+	* ov-scalar.h (class octave_scalar): Provide extractors
+	for all int array types and char array type.
+
+2005-11-09  John W. Eaton  <jwe at octave.org>
+
+	* ov-bool-mat.h (class octave_bool_matrix): Provide extractors
+	for all int array types and char array type.
+	* ov-bool.h (class octave_bool): Likewise.
+
+	* ov-intx.h (class OCTAVE_VALUE_INT_MATRIX_T): Provide extractors
+	for all int array types and char array type.
+	(class OCTAVE_VALUE_INT_SCALAR_T): Provide extractors for all int
+	scalar and array types and char array type.
+
+	* pt-mat.cc (tm_const::class_nm): New data member.
+	(tm_const::tm_const): Initialize it.
+	(tm_const::class_name): New function.
+	(tm_row_const::tm_row_const_rep::class_nm): New data member.
+	(tm_row_const::tm_row_const_rep::tm_row_const_rep): Initialize it.
+	(tm_row_const::class_name): New function.
+	(get_concat_class): New function.
+	(tm_row_const::tm_row_const_rep::do_init_element): Use it.
+	(tm_const::init): Use it.
+
+2005-11-07  John W. Eaton  <jwe at octave.org>
+
+	* strfns.cc (Fstrcmp): If args are not strings or cell arrays of
+	strings, return false.
+
+2005-11-01  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (oct-gperf.h): Avoid extra temporary file.
+	(distclean): Delete oct-errno.cc here.
+	From Quentin Spencer  <qspencer at ieee.org>.
+
+2005-11-01  Quentin Spencer  <qspencer at ieee.org>
+
+	* DLD-FUNCTIONS/spchol.cc: Use C++ true/false instead of
+	preprocessor defined TRUE/FALSE.
+	* Makefile.in (DISTFILES): Add mk-errno-list to the list.
+
+2005-10-30  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l (gnuplot::set_gnuplot_exe,
+	gnuplot::do_set_gnuplot_exe): New functions.
+	(gnuplot_binary): Call gnuplot::set_gnuplot_exe here.
+
+	* DLD-FUNCTIONS/gplot.l (gnuplot::set_gnuplot_use_title_option,
+	gnuplot::do_set_gnuplot_use_title_option): New functions.
+	(gnuplot_use_title_option):
+	Call gnuplot::set_gnuplot_use_title_option here.
+
+2005-10-27  James R. Van Zandt  <jrvz at comcast.net>
+
+	* mappers.cc: Doc fix for lgamma.
+	* DLD-FUNCTIONS/gammainc.cc (Fgammainc): Doc fix.
+
+2005-10-27  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Declare mrowsA volatile.
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::tm_row_const_rep):
+	Ensure that we always have at least two dimensions here.
+	(tm_const::tm_const): Likewise.
+	(tm_const::rows, tm_const::columns): Simplify.
+	(tm_row_const::rows, tm_row_const::columns)): Simplify.
+
+2005-10-26  John W. Eaton  <jwe at octave.org>
+
+	* oct-procbuf.cc (octave_procbuf::open): Cast 0 to void * to avoid
+	new g++ warning.
+	* toplev.cc (Fsystem): Likewise.
+
+	Changes for GCC 4.1, tip from Arno J. Klaassen
+	<arno at heho.snv.jussieu.fr>:
+
+	* ov.h (do_unary_op (octave_value::unary_op, const octave_value&)):
+	Publish externally used friend function.
+	(do_unary_op (octave_value::unary_op, const octave_value&,
+	const octave_value&)): Likewise.
+
+2005-10-25  David Bateman  <dbateman at free.fr>
+
+	* data.cc (do_cat): called with 2 args, should return args(1) 
+	for compatibility.
+
+2005-10-23  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (DLD_XSRC): Add spchol.cc.
+	* sparse-xpow.cc (xpow): Change call to sparse inverse to include
+	SparseType.
+	* DLD-FUNCTIONS/colamd.c (Fsymbfact): Remove.
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): 64-bit fixes and fix
+	for permutation of upper/lower triangular matrices.
+	* DLD-FUNCTIONS/splu.cc (Fspinv): Implemtation of sparse inverse 
+	function.
+	* DLD-FUNCTIONS/spchol.cc (sparse_chol): Static function for core of 
+	the sparse cholesky factorization.
+	(Fspchol): New function for sparse cholesky factorization R'R.
+	(Fsplchol): New function for sparse cholesky factorization LL'.
+	(Fspcholinv): New cholesky inverse function.
+	(Fspchol2inv): New cholesky inverse function.
+	(Fsymbfact): Implementation of symbolic factorization using cholmod.
+
+2005-10-21  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l (read_until): Special case STRING.
+	(handle_string): Restore function.
+	("'", "\""): Call handle string when matching these tokens..
+
+2005-10-20  John W. Eaton  <jwe at octave.org>
+
+	* pt-mat.cc (tm_row_const::all_real): New data member.
+	(tm_row_const::all_real_p): New function.
+	(tm_row_const::tm_row_const_rep::all_real): New data member.
+	(tm_row_const::tm_row_const_rep::all_real_p): New function.
+	(tm_row_const::tm_row_const_rep::init): Set all_real and all_cmplx
+	to true here.
+	(tm_row_const::all_cmplx): Rename from is_cmplx.
+	(tm_row_const::all_complex_p): Rename from complex_p.
+	(tm_row_const::tm_row_const_rep::all_cmplx): Rename from is_cmplx.
+	(tm_row_const::tm_row_const_rep::all_complex_p): Rename from complex_p.
+	(tm_row_const::tm_row_const_rep::init): Set all_real and all_cmplx
+	to true here.
+	(SINGLE_TYPE_CONCAT): New macro.
+	(tree_matrix::rvalue): Use it for single type cases.
+
+	* pt-mat.cc: Sprinkle with OCTAVE_QUIT.
+
+2005-10-18  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (octave_main): If not embedded, call clean_up_and_exit
+	instead of return to exit function.
+
+2005-10-18  Arno J. Klaassen  <arno at heho.snv.jussieu.fr>
+
+	* DLD-FUNCTIONS/gplot.l (gnuplot::handle_title):
+	Omit class name from declaration.
+
+2005-10-17  Keith Goodman  <kwgoodman at gmail.com>
+
+	* DLD-FUNCTIONS/sort.cc: Doc string fix.
+	
+2005-10-17  John W. Eaton  <jwe at octave.org>
+
+	* oct-conf.h.in (OCTAVE_CONF_F77_FLOAT_STORE_FLAG): Substitute
+	OCTAVE_CONF_F77_FLOAT_STORE_FLAG here.
+
+2005-10-14  John W. Eaton  <jwe at octave.org>
+
+	* mk-errno-list: New script.
+	* Makefile.in (oct-errno.cc): Use it.
+
+2005-10-13  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l (F__gnuplot_raw__):
+	Call print_usage with correct function name.
+
+2005-10-12  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l: Major cleanup.
+	Built-in variable gnuplot_has_frames no longer necessary.
+	(gnuplot): New class to manage multiple gnuplot processes.
+	(handle_string): Delete.  It was only used for the case of
+	__gnuplot_plot__ "file", which is no longer allowed.
+
+2005-10-05  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_exist): Chekck for autoloaded functions.
+
+	* parse.y (Fautoload): New function.
+	(autoloading, autoload_map): New static variables.
+	(load_fcn_from_file, frob_function): Handle autoloading.
+	(lookup_autoload): New function.
+	(get_help_from_file): New args, symbol_found and include_file_info.
+	Change all callers.
+
+2005-10-05  David Bateman  <dbateman at free.fr>
+
+	* help.cc (try_info): format in command string for mingw.
+
+2005-09-30  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (octave_value::~octave_value): No need to set rep to zero
+	after deleting.
+
+2005-09-29  John W. Eaton  <jwe at octave.org>
+
+	* syscalls.cc (mk_stat_map): Store mode too.
+	(FS_ISREG, FS_ISDIR, FS_ISCHR, FS_ISBLK, FS_ISFIFO, FS_ISLNK,
+	FS_ISSOCK): New functions.
+	(Fstat): Fix docstring.
+
+2005-09-28  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (printf_value_cache::double_value): Force
+	character strings to be converted to ASCII equivalents.
+
+	* data.cc (Fcomplex): New function.
+
+	* ov-type-conv.h (OCTAVE_TYPE_CONV_BODY3): Return arg unchanged if
+	class name is same as name of conversion.
+
+	* dirfns.cc (Frmdir, Fmkdir): For compatibility, return true for
+	success and false for failure.  Return third value, msgid.
+	(Frmdir): Handle second arg for recursive behavior.
+
+2005-09-23  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (load_fcn_from_file): Don't look in path if file is
+	absolute and has .oct or .m extension.
+
+	* utils.cc (Ferrno_list): New function.
+
+	* oct-errno.h, oct-errno.cc.in: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	(oct-errno.cc): New rule.
+	($(OPT_HANDLERS)): Use $(PERL) instead of just perl.
+
+	* utils.cc: Include oct-errno.h.
+	(Ferrno): Rename from FERRNO.  Allow errno to be set.  Allow
+	lookups of errno codes by name and access to structure containing
+	all errno names and codes.
+
+2005-09-19  John W. Eaton  <jwe at octave.org>
+
+	* pt-bp.cc (tree_breakpoint::visit_index_expression):
+	Avoid dereferencing invalid pointer.
+
+2005-09-19  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (OCT_LINK_DEPS): Include UFsparse libraries.
+
+	* DLD_FUNCTIONS/__glpk__.cc (F__glpk__): Replace isinf with
+	xisinf. Allow sparse matrices as second argument.
+
+	* syscalls.cc: Typos.
+	* sysdep.cc: Typos.
+
+2005-09-16  John W. Eaton  <jwe at octave.org>
+
+	* syscalls.cc (Fwaitpid): Doc fix.  Expect WNOHANG, WUNTRACED,
+	WCONTINUED as args instad of int values.
+	Return values are now [pid, status, msg] instad of [pid, msg].
+	(WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP,
+	WIFSTOPPED, WSTOPSIG, WIFCONTINUED): New functions.
+	(symbols_of_syscalls): DEFCONST WNOHANG, WUNTRACED, and WCONTINUE.
+
+	* oct-procbuf.cc (octave_procbuf::close): Call octave_syscalls::waitpid
+	here instead of calling waitpid directly.
+	* sighandlers.cc (OCL_REP::wait): Likewise.
+	
+	* sysdep.h [__MINGW32__]: Don't define waitpid here.
+
+2005-09-15  John W. Eaton  <jwe at octave.org>
+
+	* sysdep.h [__MINGW32__]: Move to definition of waitpid sysdep.h.
+
+	* sysdep.cc, sighandlers.cc: Rename all win32_ symbols to w32.
+
+	* sysdep.cc (w32_set_quiet_shutdown): New function.
+	* sysdep.h: Provide decl.
+	* sysdep.cc (MINGW_signal_cleanup): Use it.
+	* sighandlers.cc (octave_catch_interrupts): Use it.
+
+	* sysdep.h: Provide decl.
+	(MINGW_SIGNAL_CLEANUP): New macro.
+	(USE_W32_SIGINT): Move definition here.
+	* sighandlers.cc: From here.
+
+	* DLD-FUNCTIONS/cellfun.cc (Fnum2cell): Use print_usage, not usage.
+	* DLD-FUNCTIONS/colamd.cc (Fcolamd, Fsymamd, Fetree): Likewise.
+	(Fcolamd, Fsymamd) [! HAVE_COLAMD]: Return empty octave_value_list
+	object.
+
+	* sysdep.cc (sysdep_cleanup): New function.
+	Move w32 clean up code here.
+	* toplev.cc (clean_up_and_exit): From here.
+	Call sysdep_cleanup here.
+
+2005-09-15  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in (DLD_XSRC): Add ccolamd.cc
+	(OCTAVE_LIBS): Add LIBGLOB.
+	(OCT_LINK_DEPST, octave): Add AMD, COLAMD, CCOLAMD and CHOLMOD 
+	libraries.
+	* default.cc (set_default_exec_path, set_default_path,
+	maybe_add_default_load_path, LOADPATH): Use SEPCHAR_STR and SEPCHAR.
+	* help.cc (display_help_text): Exclude /dev/null on mingw.
+	* oct-procbuf.cc (W32POPEN, W32PCLOSE): Macros for cygwin/mingw.
+	(octave_procbuf::open, octave_probuf::close): Use them.
+	* sighandler.cc (user_abort): New function with core of old
+	sigint_handler.
+	(sigint_handler): Simplify and specialize for w32.
+	(w32_sigint_handler): W32 version of sigint handler.
+	(octave_catch_interrupts): Initialize w32 siginit handler.
+	* sysdep.cc (MINGW_init): New function.
+	(sysdep_init): Use it.
+	* toplev.cc (clean_up_and_exit): Clean w32 signalling shutdown.
+	* DLD-FUNCTIONS/cellfun.cc (Fnum2cell): New function.
+	* DLD-FUNCTIONS/colamd.cc (Fcolamd, Fsymamd): Allow conditional build.
+	Include oct-sparse.h rather than colamd.h.
+	* DLD-FUNCTIONS/ccolamd.cc: New file with Fccolamd a Fcsymamd.
+	
+2005-09-14  John W. Eaton  <jwe at octave.org>
+
+	* ov-complex.cc (octave_complex::try_narrowing_conversion):
+	Don't drop -0i.
+	* ov-cx-mat.cc (octave_complex_matrix::try_narrowing_conversion):
+	Likewise.
+
+2005-09-14  Daniel  <durbano at shbano.com>
+
+	* DLD-FUNCTIONS/besselj.cc, DLD-FUNCTIONS/chol.cc,
+	DLD-FUNCTIONS/fft.cc, DLD-FUNCTIONS/fftw_wisdom.cc, utils.cc:
+	Doc string fixes.
+	From Jorge Barros de Abreu <ficmatin01 at solar.com.br>.
+
+2005-09-14  David Bateman  <dbateman at free.fr>
+
+	* help.cc (Flookfor, print_lookfor, first_help_sentence):
+	New functions.
+
+2005-09-07  Bill Denney  <denney at seas.upenn.edu>
+
+	* dirfns.cc (Fglob): Doc fix.
+
+2005-09-07  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (Fstruct): Allow struct (zeros (0, N)) to create a
+	0xN struct array.
+
+2005-09-04  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/colamd.c (COLAMD_NAME, SYMAMD_NAME): New macros
+	(symetree, make_set, link, finf, etdfs, TreePostorder, coletree,
+	Fcolamd, Fsymamd, Fetree): Update for 64-bit indexing and colamd
+	versin 2.4.
+
+2005-09-01  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_out_of_date): Don't check nested functions.
+
+2005-08-31  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.cc (Octave_map::index): Don't crash if index list is empty.
+	* ov-str-mat.cc (octave_char_matrix_str::do_index_op_internal):
+	Likewise. 
+
+	* oct-map.h (Octave_map::ndims): New function.
+
+2005-08-30  John W. Eaton  <jwe at octave.org>
+
+	* ov-range.h (octave_range::permute): New function.
+
+	* ov-struct.cc (octave_struct::load_ascii,
+	octave_struct::load_binary, octave_struct::load_hdf5): Try harder
+	to read old-style files correctly.
+
+2005-08-25  David Bateman  <dbateman at free.fr>
+
+        * OPERATORS/op-sm-m.cc, OPERATORS/op-sm-cm.cc, OPERATORS/op-scm-m.cc,
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-m-sm.cc, OPERATORS/op-m-scm.cc,
+	OPERATORS/op-cm-sm.cc, OPERATORS/op-cm-scm.cc: Use mixed matrix/sparse
+	multiply operator rather than casting sparse to matrix.
+
+2005-07-18  John W. Eaton  <jwe at octave.org>
+
+	* strfns.cc (Fstrcmp): New function from Søren Hauberg
+	<soren at hauberg.org> and Tom Holroyd <tomh at kurage.nimh.nih.gov>.
+	Adapt to Octave conventions.
+
+2005-07-11  David Bateman  <dbateman at free.fr>
+
+	* ov-fc-inline.cc (Fvectorize): Allow string arguments
+
+2005-07-08  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l (Fhold, Fishold): Delete.
+	(clear_before_plotting): Delete static variable.
+	Delete PKG_ADD line for hold.
+
+2005-07-07  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (pr_plus_format): Delete "static" from template decl.
+
+	* oct-stream.cc (octave_scan): Delete explicit instantiation of
+	octave_scan<double> since a specialization is provided.
+
+	* DLD-FUNCTIONS/matrix_type.cc (Fmatrix_type): Include
+	<algorithm>, for std::transform decl.  Use std qualifier for
+	transform and tolower.
+
+2005-07-05  Antoine Moreau  <antoine.moreau at univ-bpclermont.fr>
+
+	* DLD-FUNCTIONS/betainc.cc (Fbetainc): Fix doc string to match
+	function definition..
+
+2005-07-05  Mats Jansson  <mats.e.jansson at home.se>
+
+         * file-io.cc (Fmkstemp): Check if second argument is true
+         before marking file for deletion.
+
+2005-07-05  John W. Eaton  <jwe at octave.org>
+
+	* ov-str-mat.cc (octave_char_matrix_str::do_index_op_internal):
+	Rename from char_matrix_str::do_index_op.  New arg, type.
+	ov-str-mat.h (octave_char_matrix_str::do_index_op): Define using
+	do_index_op_internal.
+	(octave_char_matrix_sq_str::do_index_op): New function.
+
+2005-07-01  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (end_error): Also handle end_try_catch case.
+
+2005-06-17  John W. Eaton  <jwe at octave.org>
+
+	* help.cc (help_from_list, help_from_symbol_table, 
+	help_from_file): New arg, symbol_found.
+	(builtin_help): Use symbol_found arg to determine whether help
+	text is empty or symbol is not available.
+
+	* symtab.cc (symbol_record::print_info): Print more info.
+
+	* DLD-FUNCTIONS/dispatch.cc (Fdispatch_help): Delete.
+	(dispatch_record): Don't prepend "<>" to help text.
+	(Fdispatch): Don't setup dispatched help.
+
+	* help.cc (extract_help_from_dispatch): New function.
+	(help_from_symbol_table): Use it.
+	* defun.cc (print_usage): Use it.
+
+	* toplev.cc (octave_config_info): Include localapifcnfiledir and
+	localapioctfiledir in the list.
+
+	* symtab.h (symbol_record::alias): New arg, mark_to_clear.
+	(symbol_record::aliases_to_clear): New data member.
+	(symbol_record::push_alias_to_clear): New function.
+	* symtab.cc (symbol_record::alias): If mark_to_clear is true, push
+	this pointer on aliases_to_clear stack for s.
+	(symbol_record::clear): Also clear aliases_to_clear_stack.
+
+	* defun.cc (install_dld_function): Create full file name alias in
+	fbi_sym_tab and hide it from view.
+	Don't call protect or make_eternal on sym_rec.
+
+	* variables.cc (fcn_out_of_date): New function.
+	(symbol_out_of_date): Also check for symbol using full function
+	file name.
+
+	* symtab.h (symbol_record::visible): New data member.
+	(symbol_record::hide, symbol_record::show, symbol_record::is_visible):
+	New functions. 
+
+	* symtab.h (symbol_record::maybe_delete_def): New private function.
+	* symtab.cc (symbol_record::clear, symbol_record::alias,
+	symbol_record::pop_context,
+	symbol_record::define (octave_function *, unsigned int)): Use it.
+	(symbol_table::symbol_list): Only include visible symbols in list.
+
+	* parse.y (frob_function): Hide nested function names.
+
+	* parse.y (frob_function): Create full file name alias in
+	fbi_sym_tab and hide it from view.
+	* defun.cc (install_dld_function): Likewise.
+
+2005-06-16  John W. Eaton  <jwe at octave.org>
+
+	* ov-dld-fcn.cc (octave_dld_function): Check Voct_file_dir to see
+	if function is system file, Vfcn_file_dir.
+	* defaults.cc (set_default_oct_file_dir): New function.
+	(install_defaults): Call it.
+	(Voct_file_dir): New global variable.
+	* defaults.h.in (Voct_file_dir): Provide decl.
+
+	* variables.cc (function_out_of_date_internal): Use
+	Vignore_function_time_stamp only to avoid calling stat.
+	(symbol_out_of_date): Don't check Vignore_function_time_stamp here.
+	(function_out_of_date): Rename from function_out_of_date_internal.
+
+	* defaults.cc (loadpath): Don't do anything if value is unchanged.
+	If loadpath changes, also update Vlast_prompt_time.
+
+2005-06-14  John W. Eaton  <jwe at octave.org>
+
+	* pt-mat.cc (Vwarn_string_concat): Default value now false.
+	(symbols_of_pt_mat): Change initial value here as well.
+
+	* ls-mat5.cc, mappers.cc, oct-stream.cc, pr-output.cc: Change all
+	uses of octave_is_NaN_or_NA to xisnan.
+
+2005-06-14  Keith Goodman  <kwgoodman at gmail.com>
+
+	* input.cc (get_user_input): Renamed debug commands to dbnext,
+	dbstep, and dbcont.
+	* pt.cc: Renamed dbg_next to dbnext in comment string.
+	* pt.h: Renamed dbg_next to dbnext in comment string.
+
+2005-06-14  David Bateman  <dbateman at free.fr>
+
+	* pt-arg-list.cc (F__end__): Return 1 for dimensions larger than ndim.
+
+2005-06-14  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (save_mat5_array_length): Special case for NaN, NA,
+	and Inf values.  Only check if abs value is greater than FLT_MAX.
+
+2005-06-09  David Bateman  <dbateman at free.fr>
+
+	* ls-mat5.cc (save_mat5_element_length): 1 element strings will be
+	saved in a compressed format, so calculate the length accordingly.
+
+2005-05-30  David Bateman  <dbateman at free.fr>
+
+	* ls-mat5.cc (read_mat5_binary_element): Don't convert to string
+	if matrix is not of type mxCHAR_CLASS.
+
+2005-05-23  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (Ffopen): Don't fail with internal error message if
+	we fail to create a valid stream object.
+	(do_stream_open (const std::string&, const std::string&,
+	const std::string&, int&): Always create octave_stream object,
+	even if file pointer returne from fopen is 0.
+
+	* load-save.cc (gripe_file_open): New function.
+	(get_file_format, Fload, Fsave): Use it.
+
+	* DLD-FUNCTIONS/sort.cc (mx_sort, mx_sort_indexed): Return
+	appropriately sized empty values for empty args.
+
+	* debug.cc (Fdbwhere, get_user_function): Look at
+	curr_caller_function, not curr_function, since function is now set
+	inside mapper, built-in (and therefore dld) functions too.
+
+2005-05-21  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc, pr-output.h (Vprint_empty_dimensions): Now extern.
+	* ov-cell.cc (octave_cell::print_raw): Conditionally print
+	dimensions of empty 2-d cell arrays.
+
+	* DLD-FUNCTIONS/sort.cc (mx_sort, mx_sort_indexed): Return empty
+	values for empty args.
+
+	* lex.l (handle_string): If single-quote string, \ and . have no
+	special meaning.
+
+2005-05-18  John W. Eaton  <jwe at octave.org>
+
+	* pt-colon.cc (tree_colon_expression::make_range): Don't require
+	scalars values as range components.
+
+	* version.h (OCTAVE_VERSION): Now 2.9.3
+	(OCTAVE_API_VERSION): Now api-v16.
+
+	* ov-base-sparse.cc (octave_base_sparse<T>::print_raw):
+	Make spacing of output consistent with other parts of Octave.
+
+	* DLD-FUNCTIONS/rand.cc (do_rand): Chop trailing singelton
+	dimensions before generating array.
+
+2005-05-17  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (install_types): Don't call octave_stream::register_type.
+	* ov.h, ov.cc (octave_value::octave_value (const octave_stream&,
+	int): Delete constructor.
+	(octave_value::is_stream, octave_value::stream_value,
+	octave_value::stream_number): Delete functions.
+	* ov-base.h (octave_base_value::is_stream): Delete function.
+	* ov-base.h, ov-base.cc (octave_base_value::stream_value,
+	octave_base_value::stream_number): Delete functions.
+	* file-io.cc (Fisstream): Delete function.
+	* op-file.h, op-file.cc, OPERATORS/op-fil-sbm.cc,
+	OPERATORS/op-fil-scm.cc, OPERATORS/op-fil-sm.cc,
+	* OPERATORS/op-fil-b.cc, OPERATORS/op-fil-bm.cc,
+	OPERATORS/op-fil-cm.cc, OPERATORS/op-fil-cs.cc,
+	OPERATORS/op-fil-m.cc, OPERATORS/op-fil-s.cc,
+	OPERATORS/op-fil-lis.cc, OPERATORS/op-fil-rec.cc,
+	OPERATORS/op-fil-str.cc: Delete files.
+	* Makefile.in (OP_XSRC, SPARSE_OP_XSRC): Delete op-fil-*.cc from
+	the lists.
+	(OV_INCLUDES): Delete op-file.h from the list.
+	(OV_SRC): Delete op-file.cc from the list.
+	* oct-stream.cc, oct-stream.h (octave_stream_list::insert,
+	octave_stream_list::do_insert): Return stream number instead of
+	octave_value.
+
+2005-05-16  David Bateman  <dbateman at free.fr>
+
+	* ls-mat.cc (save_mat5_binary_element): Increase size of 
+	compression buffer.
+	(load_mat5_binary_element): Allow ASCII encoded as UTF8,
+	and give error messages for multi-byte UTF8 and UTF16 and UTF32
+	encodings.
+
+	* ls-hdf5.h (H5T_NATIVE_IDX): New macro defining native indexing
+	type for HDF5 files
+
+	* ls-hdf5.cc (save_hdf5_empty, load_hdf5_empty): Use 
+	H5T_NATIVE_IDX to allow 64-bit indexing.
+	* ov-bool-sparse.cc (save_hdf5, load_hdf5): ditto.
+	* ov-re-sparse.cc (save_hdf5, load_hdf5): ditto.
+	* ov-cx-sparse.cc (save_hdf5, load_hdf5): ditto.
+	* ov-cell.cc (save_hdf5, load_hdf5): ditto.
+
+	* load-save.cc (parse_save_options): Remove -nozip option.
+	(Fsave): If user defines file format, ignore completely the default
+	file format options.
+	
+2005-05-12  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (oct-gperf.h): Try harder to cause Make to exit here
+	if gperf is missing or fails to create a valid file.
+
+2005-05-10  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (<MATRIX_START>{SNLCMT}*\]{S}*): If whitespace was gobbled,
+	unput SPC before returning the token.
+	(<MATRIX_START>{SNLCMT}*\}{S}*): Likewise.
+
+2005-05-09  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (except_command): Make catch clause optional in try
+	statements.
+	* pt-except.cc (tree_try_catch_command::eval):
+	Always buffer error messages.
+
+2005-05-06  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::save_ascii,
+	octave_struct::save_binary, octave_sruct::save_hdf5):
+	Always save cell array.
+	(octave_struct::load_ascii, octave_struct::load_binary,
+	octave_sruct::load_hdf5): Try to read old-style files correctly.
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Use chol2inv to compute inverse
+	from Cholesky factors.
+	(cholinv): Delete.
+
+	* DLD-FUNCTIONS/chol.cc (Fcholinv): New function.
+	(Fchol2inv): New function.
+
+2005-05-05  Keith Goodman  <kwgoodman at gmail.com>
+
+	* ov-usr-fcn.cc	(Fnargout, Fnargin): Update doc strings.
+	* help.cc (keywords): Update doc strings for varargin, varargout.
+
+2005-05-05  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (BEGIN_S_CONVERSION): Correctly handle width
+	specifiers.
+
+2005-05-04  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (read_mat5_binary_element): Implement reading of N-d
+	structure arrays.
+
+	* ov-struct.cc (octave_struct::load_hdf5,
+	octave_struct::load_binary, octave_struct::load_ascii): Assign
+	cell_value to map slot, not octave_value containing the cell.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* error.cc (Flasterr): Don't access argv if an error occurs when
+	creating it.
+
+	* mkgendoc (main): Print header message.
+
+2005-05-02  Bill Denney  <denney at seas.upenn.edu>
+
+	* data.cc, defaults.cc, DLD-FUNCTIONS/qz.cc, file-io.cc,
+	sighandlers.cc, syscalls.cc: Docstring fixes.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (octave_print_internal (std::ostream&,
+	const Range&, bool, int)): Don't print newline at end of broken
+	rows (that is handled by pr_col_num_header).
+	From Keith Goodman <kwgoodman at gmail.com>.
+
+	* Makefile.in (octave$(EXEEXT)): List $(UMFPACK_LIBS) ahead of
+	$(BLAS_LIBS).
+	(OCTAVE_LIBS): Include $(GLPK_LIBS) in the list if dynamic linking
+	is not enabled.
+	From Dmitri A. Sergatskov <dasergatskov at gmail.com>.
+
+2005-05-02  John W. Eaton  <jwe at octave.org>
+
+	* oct-map.h, oct-map.cc (Octave_map::seek, Octave_map::contents):
+	New non-const versions.
+	(Octave_map::assign (const octave_value_list&,
+	const std::string&, const Cell&)): Allow both tmp RHS and LHS to
+	be resized.  For clarity, always resize to new_dims.
+
+2005-05-02  David Bateman  <dbateman at free.fr>
+
+	* ov-re-sparse.cc, ov-cx-sparse.cc (load_binary): read save_type into
+	one byte variable.
+	
+2005-04-29  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (DO_LITERAL_CONVERSION): Cast fmt[i] to unsigned
+	char for comparison.
+
+	* c-file-ptr-stream.h (c_file_ptr_stream): New template class,
+	converted from i_c_file_ptr_stream.
+	(i_c_file_ptr_stream, o_c_file_ptr_stream, io_c_file_ptr_stream):
+	Now typedefs.
+	(i_c_zfile_ptr_stream, o_c_zfile_ptr_stream, io_c_zfile_ptr_stream):
+	New typedefs.
+	* c-file-ptr-stream.h, c-file-ptr-stream.cc (c_zfile_ptr_buf):
+	New class.
+
+	* oct-stdstrm.h (class octave_tstdiostream): New template class,
+	converted from octave_stdiostream.
+	(octave_stdiostream): Now a typedef.
+	[HAVE_ZLIB] (octave_zstdiostream): New a typedef.
+	* oct-stdstrm.cc: Delete.
+	* Makefile.in (DIST_SRC): Remove it from the list.
+
+2005-04-29  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: Add matrix_type.cc and spkron.cc to DLD_XSRC.
+
+	* ls.mat.cc (read_mat5_binary_element): Allow for endian change
+	for compressed data elements.
+
+	* ov-base-sparse.cc (assign): Invalidate matrix type.
+
+	* ov-base-sparse.cc (SparseType sparse_type (void), 
+	SparseType sparse_type (const SparseType&):
+	Functions to read and set sparse matrix type.
+
+	* ov-bool-sparse.cc (load_binary): Remove third argument.
+	(load_hdf5): Cast hsize_t comparisions with int to avoid warning.
+	* ov-cx-sparse.cc (load_hdf5): Ditto.
+	* ov-re-sparse.cc (load_hdf5): Ditto.
+
+	* ov-re-sparse.cc (convert_to_str_internal): Add third argument
+	for string type.
+	* ov-re-sparse.h (convert_to_str_internal): Adject declaration.
+
+	* sparse-xdiv.cc (xdiv, xleftdiv): Pass SparseType as third
+	argument, use it and return it to allow caching of type.
+	* sparse-xdiv.h (xdiv, xleftdiv): Change declarations for third
+	argument of type SparseType.
+
+	* DLD-FUNCTIONS/luinc.cc (Fluinc): Use type_name and not
+	class_name to test for real/complex sparse matrices.
+	Set matrix type.
+
+	* DLD-FUNCTIONS/splu.cc (Fsplu): Set matrix type.
+
+	* OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc,
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc,
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc,
+	OPERATORS/op-s-scm.cc, OPERATORS/op-s-sm.cc,
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-scm-cs.cc,
+	OPERATORS/op-scm-m.cc, OPERATORS/op-scm-s.cc,
+	OPERATORS/op-scm-scm.cc, OPERATORS/op-scm-sm.cc,
+	OPERATORS/op-sm-cm.cc, OPERATORS/op-sm-cs.cc,
+	OPERATORS/op-sm-m.cc, OPERATORS/op-sm-s.cc,
+	OPERATORS/op-sm-scm.cc, OPERATORS/op-sm-sm.cc (div, ldiv):
+	Pass and recache SparseType wirh xdiv/xleftdiv.
+
+2005-04-29  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (maybe_warn_interface_change): Delete function.
+	(fopen_mode_to_ios_mode): Don't call it.
+
+2005-04-27  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::subsref):
+	Check whether function referenced by handle is out of date.
+	(Ffunctions): Tag nameless user function as "command-line".
+
+	* variables.cc (symbol_out_of_date (octave_fucntion *)): New function.
+	(function_out_of_date): New function.
+	* parse.y (load_fcn_from_file (const std::string&, bool)):
+	New function.
+
+	* DLD-FUNCTIONS/gplot.l (gnuplot_init): New function to handle
+	initialization.  If builtin variables have already been installed,
+	simply update our cached values.
+	(F__gnuplot_init__): Call gnuplot_init to do all the real work.
+	(Fclearplot, Fcloseplot, Fhold, Fishold, Fpurge_tmp_files,
+	F__gnuplot_raw__, F__gnuplot_set__, F__gnuplot_plot__,
+	F__gnuplot_splot__, F__gnuplot_replot__, Fgplot, Fgsplot, Fgraw,
+	Fgset, Fgshow): Call gnuplot_init before doing anything.
+
+	* parse.y: (safe_fclose): Delete comment list to avoid memory leak.
+	(parse_and_execute (FILE *)): Also save and restore global_command.
+
+2005-04-26  John W. Eaton  <jwe at octave.org>
+
+	* mkbuiltins (VAR_FILES): Expect $(VAR_FILES) to have .df suffix.
+
+	* Makefile.in (clean): Also remove $(DLD_PICOBJ).
+	Use mk-oct-links --delete to remove links to .oct files. 
+	Remove $(DOC_FILES) not $(DEF_FILES) and $(VAR_FILES).
+
+	* mk-oct-links (mk-oct-links): Handle --delete option.
+	Rename -p option to be --print.  Skip nonexistent .df files.
+
+2005-04-25  John W. Eaton  <jwe at octave.org>
+
+	* oct-hist.cc (default_history_file, default_history_size): Now static.
+	* oct-hist.h: Delete decls.
+
+	* oct-hist.cc (default_history_timestamp_format,
+	default_history_timestamp_format): New functions.
+	(Vdefault_history_timestamp_format): New variable.
+	(symbols_of_oct_hist): DEFVAR it.
+	(octave_history_write_timestamp): New function.
+	* oct-hist.h (octave_history_write_timestamp): Provide decl.
+	* toplev.cc (): call octave_history_write_timestamp here.
+	* octave.cc (maximum_braindamage):
+	Bind history_timestamp_format_string here.
+
+2005-04-22  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.9.2.
+	(OCTAVE_API_VERSION): Now api-v15.
+
+	* pager.cc (default_pager): Also append -X.
+
+	* DLD-FUNCTIONS/dispatch.cc (Fdispatch): Dispatch help on "string"
+	and "sq_string" types.
+	(dispatch_record): Add extra space to force new paragraph after
+	each dispatched function name if we are formatting with Texinfo.
+	Force noindent of preceding "Overloaded function:" tag.
+
+2005-04-21  John W Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (read_mat5_binary_element): Only read sparse matrix
+	values if sizeof (int) == sizeof (octave_idx_type).
+
+	* DLD-FUNCTIONS/colamd.cc: These functions only work if
+	sizeof (int) == sizeof (octave_idx_type).
+
+	* Makefile.in (parse.cc): Expect 14 shift/reduce conflicts.
+
+	* parse.y (USING TITLE WITH AXES COLON OPEN_BRACE CLEAR):
+	Delete unused tokens.
+
+	* DLD-FUNCTIONS/__qp__.cc (qp): Use octave_idx_type where needed.
+
+	* DLD-FUNCTIONS/__qp__.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2005-04-20  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (IDENT): Allow $ in identifiers.
+	* utils.cc (valid_identifier): Likewise.
+
+2005-04-19  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (Fsystem): Move enum exec_type declaration to file
+	scope and rename system_exec_type.  Change all uses.
+
+2005-04-14  David Bateman  <dbateman at free.fr>
+
+	* load-save.cc (Vdefault_save_format, Voctave_core_file_format):
+	Delete variables.
+	(Vdefault_save_options, Voctave_core_file_options): New variables.
+	(get_save_format): Delete function.
+	(parse_save_options (const string_vector&, ...),
+	parse_save_options (const std::string&, ...)): New functions.
+	(dump_octave_core): Allow save_as_floats to be used.
+	(dump_octave_core): Parse save options.
+	(Fsave): Split parsing of options, and default formats.
+	(default_save_format): Delete function and DEFVAR.
+	(default_save_options): New function.  DEFVAR it.
+	(octave_core_file_format): Delete function and DEFVAR.
+	(octave_core_file_options): New function.  DEFVAR it.
+	
+	* octave.cc (default_save_format): Delete binding
+	(default_save_options): New bindings
+
+	* Makefile.in: Add luinc.cc to DLD_XSRC.
+	* DLD-FUNCTIONS/luinc.cc: New file for incomplete LU factorization.
+
+	* ov-bool-sparse.h (index_vector): New function.
+	* ov-re-sparse.cc (index_vector): Ditto.
+	* ov-re-sparse.h (index_vector): Definition.
+
+	* ov-mapper.cc (any_element_less_than, any_element_greater_than):
+	New versions for SparseMatrix
+	(SPARSE_MAPPER_LOOP_2, SPARSE_MAPPER_LOOP_1, SPARSE_MAPPER_LOOP):
+	New macros.
+	(octave_mapper::apply): Add special cases for sparse arguments to
+	the mapper functions
+
+	* ov-re-sparse.cc (streamoff_array_value): Use octave_idx_type.
+	(convert_to_str_internal): New function.
+	* ov-re-sparse.h (convert_to_str_internal): Definition.
+	
+	* DLD-FUNCTIONS/sparse.cc (Fsparse): More care for nargin=2 case.
+
+	* DLD-FUNCTIONS/splu.cc (Fsplu): Use octave_idx_type.
+	
+2005-04-14  John W. Eaton  <jwe at octave.org>
+
+	* strfns.cc (Fchar): If arg is a dq string, return a dq string.
+
+	* pt-mat.cc (Vwarn_string_concat): New static variable.
+	(symbols_of_pt_mat): DEFVAR it.
+	(warn_string_concat): New function.
+	(maybe_warn_string_concat): New function.
+	(tree_matrix::rvalue): If all args are single quoted strings,
+	create a single quoted string object.  If all args are strings
+	(any type), create a double quoted string object.  If a mixture of
+	string types, maybe warn.
+	(class tm_row_const, class tm_row_const_rep, class tm_const):
+	Note whether all values are double or single quoted strings.
+
+	* ov.h (octave_value::is_dq_string): New function.
+
+2005-04-13  John W. Eaton  <jwe at octave.org>
+
+	* strfns.cc (Fchar): Create sq_string objects here.
+
+2005-04-12  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (Ffprintf, Fprintf, Fsprintf):
+	Pass octave_value to octave_stream::printf for FMT.
+	(Fscanf, Fsscanf): Likewise, for octave_stream::scanf and
+	octave_stream::oscanf.
+
+	* oct-stream.cc, oct-stream.h (octave_stream::printf,
+	octave_stream::scanf, octave_stream::oscanf): New versions that
+	accept an octave_value for FMT.
+	(octave_stream::puts): New version that accepts octave_value for
+	value to print.
+	(octave_base_stream::do_scanf): If all_char_conv, force
+	conversion to string to avoid warning.
+
+	* ov-str-mat.h, ov-str-mat.cc (octave_char_matrix_sq_str): New class.
+	(octave_char_matrix_dq_str): New typedef.
+
+	* ov.h, ov.cc: All string constructors now take type argument.
+
+	* ov.cc (install_types): Register octave_char_matrix_sq_str.
+
+	* ov.h (octave_value::convert_to_str): New arg, type.
+	(octave_value::convert_to_str_internal): Likewise.
+	Change all derived classes.
+
+	* ov.h (octave_value::is_sq_string): New predicate.
+
+	* octave.gperf (__FILE__): Now a DQ_STRING.
+
+	* ls-mat4.cc (read_mat_binary_data): Force sq strings here.
+	* ls-mat5.cc (read_mat5_binary_element): And here.
+
+	* lex.l (<COMMAND_START>[\;\,]): Return SQ_STRING, not STRING.
+	(<COMMAND_START>[^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}*): Likewise.
+	(handle_string): Type of string to return depends on delimeter.
+
+	* parse.y (DQ_STRING, SQ_STRING): New token types.
+	(STRING): Delete token type.
+	(string): New non-terminal.
+	(constant): Recognize string here instead of STRING.
+	(word_list): Likewise.
+	(opt_sep): Handle DQ_STRING and SQ_STRING.
+
+	* OPERATORS/op-str-m.cc, OPERATORS/op-str-s.cc,
+	OPERATORS/op-str-str.cc: Define operators for both sq and dq
+	strings.
+
+2005-04-08  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (clean): Use exact filenames instead of *.xxx.
+	Also remove PKG_ADD.
+	(DISTFILES): Add gplot.cc to the list.
+	(maintainer-clean): Remove gplot.cc here.
+
+	* Initial merge of 64-bit changes from Clinton Chee:
+
+	2005-04-07  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.h, ls-oct-ascii.cc (extract_keyword): Now template
+	functions defined in the header file.
+
+	* ls-mat5.cc, ov-base-sparse.h, ov-base.h, ov-bool-sparse.cc
+	ov-cx-sparse.cc, ov-re-sparse.cc, ov.cc, pt-loop.cc,
+	sparse-xdiv.cc, sparse-xpow.cc, DLD-FUNCTIONS/sparse.cc,
+	DLD-FUNCTIONS/spdet.cc:
+	Use octave_idx_type instead of int where needed.
+
+	2005-03-31  Clinton Chee  <chee at parallel.hpc.unsw.edu.au>
+
+	* Cell.cc, Cell.h, data.cc, defaults.cc, dirfns.cc, file-io.cc,
+	gripes.cc, gripes.h, ls-mat-ascii.cc, ls-mat4.cc, ls-oct-ascii.cc,
+	oct-map.cc, oct-map.h, oct-obj.cc, oct-obj.h, oct-stream.cc,
+	oct-stream.h, octave.cc, ops.h, ov-base-mat.cc, ov-base.h,
+	ov-bool-mat.cc, ov-cell.cc, ov-cs-list.cc, ov-cx-mat.cc,
+	ov-intx.h, ov-list.cc, ov-mapper.cc, ov-range.cc, ov-range.h,
+	ov-re-mat.cc, ov-scalar.h, ov-str-mat.cc, ov-struct.cc, ov.cc,
+	ov.h, pr-output.cc, pt-arg-list.cc, pt-cell.cc, pt-loop.cc,
+	pt-mat.cc, pt-select.cc, symtab.h, utils.cc, utils.h, xdiv.cc,
+	xpow.cc:
+	Use octave_idx_type instead of int where needed.
+
+	2005-04-01  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_config_info): Add USE_64_BIT_IDX_T to the list.
+	* oct-conf.h.in (OCTAVE_CONF_USE_64_BIT_IDX_T): Substitute here.
+
+	2005-03-31  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/sort.cc: Don't use unsigned int for index into
+	dim_vector, or cast dim to unsigned int.
+	(Fsort): No need to cast arg before asking for dims.
+
+	* DLD-FUNCTIONS/gcd.cc (Fgcd): Use OCTAVE_LOCAL_BUFFER to allocate
+	local array of NDArray objects.
+
+	2005-03-31  Clinton Chee  <chee at parallel.hpc.unsw.edu.au>
+
+	* DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/besselj.cc,
+	DLD-FUNCTIONS/chol.cc, DLD-FUNCTIONS/colloc.cc,
+	DLD-FUNCTIONS/daspk.cc, DLD-FUNCTIONS/dasrt.cc,
+	DLD-FUNCTIONS/dassl.cc, DLD-FUNCTIONS/det.cc,
+	DLD-FUNCTIONS/eig.cc, DLD-FUNCTIONS/expm.cc, DLD-FUNCTIONS/fft.cc,
+	DLD-FUNCTIONS/fft2.cc, DLD-FUNCTIONS/fftn.cc,
+	DLD-FUNCTIONS/fftw_wisdom.cc, DLD-FUNCTIONS/filter.cc,
+	DLD-FUNCTIONS/find.cc, DLD-FUNCTIONS/fsolve.cc,
+	DLD-FUNCTIONS/gcd.cc, DLD-FUNCTIONS/hess.cc, DLD-FUNCTIONS/inv.cc,
+	DLD-FUNCTIONS/kron.cc, DLD-FUNCTIONS/lu.cc,
+	DLD-FUNCTIONS/minmax.cc, DLD-FUNCTIONS/quad.cc,
+	DLD-FUNCTIONS/qz.cc, DLD-FUNCTIONS/rand.cc,
+	DLD-FUNCTIONS/schur.cc, DLD-FUNCTIONS/sort.cc,
+	DLD-FUNCTIONS/sqrtm.cc, DLD-FUNCTIONS/svd.cc,
+	DLD-FUNCTIONS/syl.cc:
+	Use octave_idx_type instead of int where needed.
+
+2005-04-06  David Bateman  <dbateman at free.fr>
+
+	* Makefile.in: Link to UMFPACK_LIBS. Add zfstream.{cc,h} to build and 
+	dist files.
+
+	* zfstream.cc: New file for C++ binding for fstream like class for 
+	zlib.
+
+	* zfstream.h: Definition for fstream like C++ bindings to zlib.
+
+	* load-save.cc (static bool check_gzip_magic (const std::string&)): 
+	New function to look for GZIP magic 
+	(static load_save_format get_file_format (const istream &file)): New 
+	function split from old get_file_format but passed istream to allow
+	use with zlib istream.
+	(static load_save_format get_file_format (const std::string&, 
+	const std::string&, bool)): Modify the test uncompressed file first, 
+	then compressed version
+	(Fload) Allow -v6, -6, -v7 and -7 options. Split load code to allow
+	use of zlib.
+	(Fsave) Allow -zip, -z, -v6, -6, -v7 and -7 options. Split save code
+	to allow use of zlib.
+
+	* load-save.h: add LS_MAT7_BINARY to load_save_format enum
+
+	* ls-mat5.cc (read_mat5_binary_element): Test for miCOMPRESSED flag for
+	matlab v7 files, and decompress data in memory. Allow reading of matlab
+	logical variables either in mxDOUBLE_CLASS or mxUINT8_CLASS.
+	(int save_mat5_array_length(const double*, ...): New function to 
+	calculate number of bytes used to save NDArray.
+	(int save_mat5_array_length(const Complex*, ...): New function to 
+	calculate number of bytes used to save ComplexNDArray.
+	(int save_mat5_element_length): New function to find number of bytes 
+	needed to save data element.
+	(save_mat5_binary_element): New input arguments, mat7_format and
+	compressing, that define if we are in a matlab v7 format and where we 
+	are currently compressing the data element. If mat7_format use
+	miCOMPRESSED flag for matlab v7 files, and compress data in memory. 
+	Add capability to save logical variables as mxUINT8_CLASS. If v7 
+	format maximum variable length is 63 characters and not 31. Use the
+	save_mat5_element_length function to pre-calculate the number of bytes
+	taken by a variable rather than use a negative seek to correct after 
+	writing (zlib can't do negative seeking)
+
+	* ls-mat5.h: Add to miCOMPRESSED, miUTF8, miUTF16 and miUTF32 flags to 
+	the enum mat5_data_type.
+	(save_mat5_binary_element): Add args mat7_format and compressing to the
+	definition.
+
+2005-04-06  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-scm-scm.cc: Delete #pragma implementation.
+
+2005-04-05  John W. Eaton  <jwe at octave.org>
+
+	* ov-ch-mat.h (octave_char_matrix::index_vector): New function.
+
+	* oct-stream.cc (BEGIN_C_CONVERSION): Clear stream state if
+	we hit EOF after we read something.
+
+	* pt-assign.cc (tree_multi_assignment::rvalue):
+	Allow assignments of the form [a,b,c] = x{:}.
+
+2005-03-30  John W. Eaton  <jwe at octave.org>
+
+	* mappers.cc (install_mapper_functions): Use std:: as needed.
+	* defun-int.h (DEFUN_MAPPER_INTERNAL): Don't use X_CAST on
+	function pointer args.
+
+	* ov-complex.cc, ov-cx-mat.cc, xpow.cc, ls-mat5.cc: Use std:: for
+	Complex functions instead of relying on wrappers from oct-cmplx.h.
+
+	* oct-stream.cc (octave_scan): Initialize c1 to EOF.
+
+2005-03-29  John W. Eaton  <jwe at octave.org>
+
+	* utils.cc (get_dimensions): Produce error instead of warning if
+	given a matrix argument.
+
+	* load-save.cc (Fload, Fsave): Also accept -V4 option.
+
+	* ls-hdf5.h (hdf5_fstreambase::hdf5_fstreambase,
+	hdf5_fstreambase::open): Use & instead of == to test whether mode
+	is std::ios::in or std::ios::out.
+	(hd5_ifstream::istream, hd5_ifstream::open, hd5_ofstream::istream,
+	hd5_ofstream::open): Default mode now includes binary flag.
+
+2005-03-28  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_stream::write): For compatibility, Write
+	zeros instead of seeking if SKIP is nonzero.
+
+	* DLD-FUNCTIONS/gplot.l (Fgraw): Recommend __gnuplot_raw__, not
+	__gnuplot__raw__.
+	(Fgshow): Recommend __gnuplot_show__, not __gnuplot__show__.
+	Don't add "mark_as_rawcommand ("replot")" to PKG_ADD file.
+
+2005-03-26  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (gnu_readline): Don't wrap call to command_editor::readline
+	with {BEGIN,END}_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE.
+
+2005-03-25  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (main_loop): Don't use octave_set_current_context here.
+
+	* pt-loop.cc (simple_for_loop::eval): In for i = matrix ... end,
+	skip loop if matrix is empty.  Likewise for cell arrays.
+
+2005-03-24  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Texinfoize doc string.
+
+	* Makefile.in (install-oct): Always create $(octfiledir) and
+	install PKG_ADD file there.
+
+	* octave.cc (octave_main): Fix logic in test for exit after
+	evaluating --eval option code.
+
+2005-03-23  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Require 9 arguments.
+	Print error messages and return early if value extractions fail.
+	Default for message level now 0.
+	Rename local variable error to be errnum.
+	(glpk_fault_hook): Call message instead of writing to octave_stderr.
+	(glpk_fault_hook): Call error instead of writing to octave_stderr.
+	(glpk): Likewise.
+	Declare mark static.  Delete declaration of fperr.
+	(glpk): Delete unnecessary casts.
+
+	* DLD-FUNCTIONS/__glpk__.cc (OCTAVE_GLPK_GET_REAL_PARAM,
+	OCTAVE_GLPK_GET_INT_PARAM): New macros.
+	(F__glpk__): Use them.
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Accept lpsolver and
+	save_pb in param arg instead of as separate args.
+	Arg list now matches new interface for glpk.m.
+	Don't return lambda and redcosts fields in extra if isMIP.
+
+	* toplev.cc (do_octave_atexit): Call reset_error_handler before
+	each call to feval.
+
+2005-03-22  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in: Add special rule for __glpk__.oct.
+
+	* toplev.cc (octave_config_info): Add GLPK_LIBS to the list.
+	* oct-conf.h.in (OCTAVE_CONF_GLPK_LIBS): Substitute here.
+
+	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__, glpk):
+	Adapt to Octave coding style.
+	(glpk): Move decls closer to first use.
+	(F__glpk__): Eliminate unnecessary loop seting inf values.
+	Ensure that isMIP is initialized.
+	Declare sense, nz, and isMIP volatile to avoid GCC warnings that
+	these variables might be might be clobbered by `longjmp' or `vfork'
+
+	* DLD-FUNCTIONS/__glpk__.cc: New file.
+
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2005-03-21  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (maximum_braindamage):
+	Don't set warn_matlab_incompatible to true.
+
+2005-03-17  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (class bracket_brace_paren_nesting_level): Use static
+	const int members instead of anonymous enum.
+
+2005-03-16  John W. Eaton  <jwe at octave.org>
+
+	* ov-struct.cc (octave_struct::save_ascii): Don't convert Cell
+	object to cs-list.
+	(octave_struct::save_binary): Likewise
+	(octave_struct::save_hdf5): Likewise.
+
+	* DLD-FUNCTIONS/gplot.l (Fset, Fshow): Delete.
+	(F__gnuplot_plot__): Rename from Fgplot.
+	(F__gnuplot_splot__): Rename from Fgsplot.
+	(F__gnuplot_raw__): Rename from Fgraw.
+	(F__gnuplot_set__): Rename from Fgset.
+	(F__gnuplot_show__): Rename from Fgshow.
+	(F__gnuplot_replot__): Rename from Freplot.
+	(WARN_DEPRECATED, DEPRECATED_BODY): New macros.
+	(Fgplot, Fgsplot, Fgraw, Fgset, Fgshow): New functions.
+
+2005-03-15  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (<COMMAND_START>{NL}): Reset lexer_flags.doing_rawcommand
+	state here.
+
+	* version.h (OCTAVE_API_VERSION): Now 2.9.0.
+	(OCTAVE_API_VERSION): Now api-v14.
+
+	* Makefile.in (INCLUDES): Delete sparse-ops.h from the list.
+
+	* cellfun.cc: New function from Octave-forge.  Adapt to Octave
+	coding standards.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2005-03-14  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/dispatch.cc (Fbuiltin):	Avoid crash if symbol
+	lookup fails.
+
+2005-03-10  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (Foctave_config_info): Print error instead of crashing
+	if struct does not contain field we are looking for.
+
+2005-03-09  John W. Eaton  <jwe at octave.org>
+
+	* load-save.cc (Fload, Fsave): Accept -text as an alias for -ascii.
+	Issue warning for future change in meaning of -ascii.
+
+	* Makefile.in (bin-dist): Delete target.
+	(BINDISTFILES, BINDISTLIBS): Delete variables.
+
+2005-03-04  John W. Eaton  <jwe at octave.org>
+
+	* octave.cc (octave_main): Concatenate all --eval arguments.
+
+2005-03-03  John W. Eaton  <jwe at octave.org>
+
+	* input.cc (input_from_command_line_file): Move definition here.
+	* parse.y: From here.
+	* input.h (input_from_command_line_file): Move decl here.
+	* parse.h: From here.
+
+	* input.cc (octave_gets):
+	Don't save history if input is from command line file.
+
+	* parse.y (parse_and_execute, parse_fcn_file, eval_string):
+	Don't alter value of input_from_command_line_file here.
+	(input_from_command_line_file): Default value is false.
+	(eval_string): Turn off line editing here.
+
+	* toplev.cc, toplev.h (main_loop): Delete fun_to_call arg and all uses.
+
+	* octave.cc (fun_to_call): Delete static variable.
+	(persist, code_to_eval): New static variables.
+	(long_opts): Delete --funcall, add --eval and --persist.
+	(usage_string, verbose_usage, octave_main): Likewise.
+	(FUNCALL_OPTION): Delete.
+	(EVAL_OPTION, PERSIST_OPTION): New macros.
+	(maximum_braindamage): Set persist to true.
+	(execute_eval_option_code): New function.
+	(restore_program_name): New function.
+	(execute_command_line_file): New function.
+	(octave_main): Call execute_eval_option code and
+	execute_command_line file.  If persist, go interactive even after
+	evaluating --eval code and/or command-line file.
+
+	* ov-bool-sparse.h, ov-bool-sparse.cc
+	(octave_sparse_bool_matrix::sparse_matrix_value,
+	octave_sparse_bool_matrix::sparse_complex_matrix_value):
+	Accept bool arg.
+
+	* parse.y (looks_like_copyright): Check first 9 characters, not 14.
+
+2005-03-02  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_scan (std::istream&, const
+	scanf_format_elt&, double*)): New specialization to handle Inf,
+	NaN, and NA.
+
+	* parse.y (looks_like_copyright):
+	Rename from looks_like_octave_copyright.  Change all uses.
+	Simply match "Copyright".
+
+2005-03-01  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/odessa.cc: Delete.
+	* Makefile.in (DLD_XSRC): Remove it from the list.
+	(OPT_HANDLERS): Remove ODESSA-opts.cc from the list.
+
+2005-02-28  John W. Eaton  <jwe at octave.org>
+
+	* toplev.cc (octave_config_info): Remove LIBGLOB and GLOB_INCFLAGS
+	from the list.
+	* oct-conf.h.in (OCTAVE_CONF_LIBGLOB, OCTAVE_CONF_GLOB_INCFLAGS):
+	Delete.
+	* Makefile.in (OCTAVE_LIBS): Remove $(LIBGLOB) from the list.
+
+2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	Sparse merge.
+
+	2005-02-25  John W. Eaton  <jwe at octave.org>
+
+	* DLD-SRC/rand.cc (Frand): Accept "state" as an alias for "seed".
+
+	* DLD-SRC/dispatch.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+	2005-02-13  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-inline.h, DLD-FUNCTIONS/spparms.cc, DLD-FUNCTIONS/gcd.cc:
+	Remove additional licensing clause, with authors permission
+
+	* ov-base-sparse.h: New constructor to cache SparseType, not yet
+	used
+	* ov-re-sparse.h: likewise
+	* ov-cx-sparse.h: likewise
+	* ov.h: Likewise
+
+	* sparse-xdiv.cc: Remove spparms umfpack flag
+
+	* DLD-FUNCTIONS/spparms.cc: Warning that umfpack flag is ignored.
+	
+	2005-01-16  David Bateman  <dbateman at free.fr>
+
+	* ls-mat5.cc (read_mat5_integer_data): Change "T &m" to "T *m" and
+	instantiate with values like octave_int8 rather than int8NDArray.
+	Modify function to fit
+	(read_mat5_binary_element): Use new form of read_mat_integer_data
+	to read data directly into sparse matrix
+	(write_mat5_integer_data): Change "const T &m" to "T *m", etc. New
+	instantiation with int.
+	(save_mat5_binary_element): Modify to save sparse data
+	
+	2005-01-15  David Bateman  <dbateman at free.fr>
+
+	* data.cc (do_cat): Use first non-empty matrix as base for 
+	concatenation.
+	* pt-mat.cc (tree_matrix::rvalue): ditto.
+	
+	2005-01-14  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (do_cat_op): When checking for empty args, use
+	all_zero_dims, not numel.
+	* ov.h (octave_value::all_zero_dims): New function.
+
+	* ov-bool-sparse.cc (try_narrowing_conversion): Convert to
+	bool_matrix, not matrix.
+
+	2005-01-13  David Bateman  <dbateman at free.fr>
+
+	* data.cc (make_diag): Use numel not capacity to remove ambiguity.
+	* ov.h (octave_value::capacity): New virtual funtion.
+	* ov-base.h (octave_base_value::capacity): New function calls numel.
+	* data.cc (Freshape): Use arg.numel() rather than arg.dims().numel() 
+	since sparse numel now consistent.
+	* symtab.h (symbol_record::symbol_def::capacity, 
+	symbol_record::capacity): New methods.
+	* symtab.cc (symbol_record::print_symbol_info_line,
+	symbol_table::parse_whos_line_format, symbol_table::maybe_list):
+	used capacity() and not numel() to properly assess size of
+	sparse objects.
+	* ov-base-sparse.h (octave_base_sparse::capacity): New function,
+	(octave_base_sparse::numel): Delete.
+	* ov-re-sparse.cc (octave_sparse_matrix::streamoff_array_value):
+	Only fill from non-zero elements of sparse array.
+	* DLD-FUNCTIONS/splu.cc (Fsplu): Change use of nelem to numel.
+	* ov.cc (do_cat_op): Early return for concatenation with empty
+	objects.
+	
+	2005-01-12  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/find.cc (Ffind): Make it work for character strings.
+
+	2005-01-11  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-double-conv.cc: New conversions for sparse_matrix
+	and sparse_bool_matrix to matrix.
+
+	2005-01-11  David Bateman  <dbateman at free.fr>
+
+	* ov-base-sparse.h (octave_base_sparse::any, 
+	octave_base_sparse::all): Use new constructors, etc as pointed out
+	by JWE.
+
+	2005-01-10  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/sparse.cc (MINMAX_BODY, Fspatan2, make_spdiag):
+	Write retval(0) = result instead of retval(0) = octave_value (result).
+	* DLD-FUNCTIONS/splu.cc (Fsplu): Likewise.
+
+	2005-01-08  David Bateman  <dbateman at free.fr>
+
+	* ls-mat5.cc (read_mat5_integer_data): Instantiate for Array<int>
+	(read_mat5_binary_element): Add code to read sparse matrices
+	saved in matlab v5 format
+
+	2005-01-07  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-bm-sbm.cc, OPERATORS/op-b-sbm.cc,
+	OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc,
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc,
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc,
+	OPERATORS/op-sbm-b.cc, OPERATORS/op-sbm-bm.cc,
+	OPERATORS/op-sbm-sbm.cc, OPERATORS/op-scm-cm.cc,
+	OPERATORS/op-scm-cs.cc, OPERATORS/op-scm-m.cc,
+	OPERATORS/op-scm-s.cc, OPERATORS/op-scm-scm.cc, 
+	OPERATORS/op-scm-sm.cc, OPERATORS/op-sm-cm.cc,
+	OPERATORS/op-sm-cs.cc, OPERATORS/op-sm-m.cc,
+	OPERATORS/op-sm-s.cc, OPERATORS/op-sm-scm.cc,
+	OPERATORS/op-sm-sm.cc, OPERATORS/op-s-scm.cc,
+	OPERATORS/op-s-sm.cc: New octave_value constructors allow
+	macros from ops.h to be used rather than sparse-ops.h. Remove
+	other explicit uses of maybe_mutate.
+
+	* sparse-ops.h: delete file.
+
+	* colamd.cc (Fcolamd, Fsymamd, Fetree): Remove no longer needed 
+	use of get_rep() and use the sparse matrix conversion functions
+	directly.
+
+	* data.cc (Freshape): Use arg.dims().numel() rather than 
+	arg.numel() due to definition of numel for sparse matrices.
+	
+	* sparse.cc (Ffull, Fspfind, SPARSE_DIM_ARG_BODY, MINMAX_BODY,
+	Fspatan2, make_spdiag): Convert to use new octave_value sparse
+	constructors, sparse matrix conversion functions and remove
+	maybe_mutate calls.
+	(Fspreshape): Delete
+
+	* splu.cc (Fsplu): Remove remaining explicit octave_value
+	construction.
+	
+	* ov-base-sparse.h (do_index_op, resize, reshape, permute, squeeze):
+	Move these methods from the derived classes.
+	* ov-base-spase.cc (do_index_op): Move this method from the derived
+	classes.
+	* ov-bool-sparse.h (do_index_op, resize, reshape, permute, squeeze):
+	delete.
+	* ov-re-spase.cc (do_index_op): delete.
+	* ov-cx-sparse.h (do_index_op, resize, reshape, permute, squeeze):
+	delete.
+	* ov-cx-spase.cc (do_index_op): delete.
+	* ov-bool-spase.cc (do_index_op): delete.
+	* ov-re-sparse.h (do_index_op, resize, reshape, permute, squeeze):
+	delete.
+
+	* DLD-FUNCTIONS/spdet.cc (Fspdet): Remove use of SparseDet and
+	SparseComplexDET classes and use DET and ComplexDET classes.
+	
+ 	* DLD-FUNCTIONS/colamd.cc op-bm-sbm.cc OPERATORS/op-b-sbm.cc
+	OPERATORS/op-cm-scm.cc OPERATORS/op-cm-sm.cc OPERATORS/op-cs-scm.cc 
+	OPERATORS/op-cs-sm.cc OPERATORS/op-fil-sbm.cc OPERATORS/op-fil-scm.cc
+	OPERATORS/op-fil-sm.cc OPERATORS/op-m-scm.cc OPERATORS/op-m-sm.cc 
+	OPERATORS/op-sbm-b.cc OPERATORS/op-sbm-bm.cc OPERATORS/op-sbm-sbm.cc 
+	OPERATORS/op-scm-cm.cc OPERATORS/op-scm-cs.cc OPERATORS/op-scm-m.cc
+	OPERATORS/op-scm-s.cc OPERATORS/op-scm-scm.cc OPERATORS/op-scm-sm.cc 
+	OPERATORS/op-sm-cm.cc OPERATORS/op-sm-cs.cc OPERATORS/op-sm-m.cc 
+	OPERATORS/op-sm-s.cc OPERATORS/op-sm-scm.cc OPERATORS/op-sm-sm.cc 
+	OPERATORS/op-s-scm.cc OPERATORS/op-s-sm.cc ov-base-sparse.cc 
+	ov-base-sparse.h ov-bool-sparse.cc ov-bool-sparse.h ov-cx-sparse.cc 
+	ov-cx-sparse.h ov-re-sparse.cc ov-re-sparse.h sparse-base-lu.cc 
+	sparse-base-lu.h DLD-FUNCTIONS/sparse.cc sparse-xdiv.cc sparse-xdiv.h
+	sparse-xpow.cc sparse-xpow.h DLD-FUNCTIONS/spdet.cc 
+	DLD-FUNCTIONS/splu.cc DLD-FUNCTIONS/spparms.cc: Remove additional 
+	licensing clause with authors permission.
+	
+	2005-01-05  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/colamd.cc: Rename from colamdoct.cc. Base colamd.h
+	now found in COLAMD/colamd.h.
+	(Fcolamd): Return value is now used.
+	(Fsymamd): ditto.
+	
+	* Makefile.in: include colamd.cc in DLD_XSRC.
+
+	* ov.h (sparse_matrix_value, sparse_complex_matrix_value,
+	sparse_bool_matrix_value): New virtual functions
+
+	* ov-base.cc (octave_base_value::sparse_matrix_value,
+	octave_base_value::sparse_complex_matrix_value,
+	octave_base_value::sparse_bool_matrix_value): New default sparse
+	matrix extraction functions.
+
+	* ov-base.h (sparse_matrix_value, sparse_complex_matrix_value,
+	sparse_bool_matrix_value): Declare them.
+
+	* ov-re-mat.cc (octave_matrix::sparse_matrix_value,
+	octave_matrix::sparse_complex_matrix_value): Conversion functions.
+
+	* ov-re-mat.h (sparse_matrix_value, sparse_complex_matrix_value):
+	Declare them.
+	
+	* ov-cx-mat.cc (octave_complex_matrix::sparse_matrix_value,
+	octave_complex_matrix::sparse_complex_matrix_value): Conversion 
+	functions.
+
+	* ov-cx-mat.h (sparse_matrix_value, sparse_complex_matrix_value):
+	Declare them.
+
+	* ov-bool-mat.h (sparse_matrix_value, sparse_complex_matrix_value,
+	sparse_bool_matrix_value): Conversion functions.
+
+	* DLD_FUNCTIONS/spdet.cc (Fspdet): Use the above constructors
+	and conversion functions.
+	* DLD_FUNCTIONS/splu.cc (Fsplu): ditto.
+	
+	2004-12-30  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/splu.cc (Fsplu): Avoid shadow warnings.
+
+	* sparse-xpow.cc (elem_xpow): Delete unsed variables.
+	* sparse-xdiv.cc (x_el_div): Likewise.
+
+	* DLD-FUNCTIONS/det.cc (Fdet): Delete unused argument nargout.
+	* DLD-FUNCTIONS/spdet.cc (Fspdet): Likewise.
+
+	* DLD-FUNCTIONS/sparse.cc (Fnzmax): Return a value.
+
+	* ov.cc, ov.h (octave_value::octave_value (const SparseMatrix&),
+	(octave_value::octave_value (const SparseBoolMatrix&),
+	(octave_value::octave_value (const SparseComplexMatrix&)):
+	New constructors.
+
+	2004-12-29  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/sparse.cc (SPARSE_DIM_ARG_BODY): Rename from
+	DEFUN_DLD_SPARSE_DIM_ARG.  Omit HELP arg.  Omit DEFUN_DLD, so the
+	macro only defines the function body.
+	(Fspprod, Fspcumprod, Fspsum, Fspcumsum, Fspsumsq): Define with
+	DEFUN_DLD, not DEFUN_DLD_SPARSE_DIM_ARG.  Use SPARSE_DIM_ARG_BODY
+	to define function body.
+
+	* DLD-FUNCTIONS/sparse.cc (load_sparse_type, sparse_type_loaded):
+	Delete function, variable, and all uses.
+	* ov.cc: Include ov-bool-sparse.h, ov-re-sparse.h, ov-cx-sparse.h.
+	(install_types): Register sparse types.
+
+	Merge of sparse code from David Bateman <dbateman at free.fr> and 
+	Andy Adler <adler at site.uottawa.ca>.
+
+	* sparse-xdiv.cc, sparse-xpow.cc: New files.
+	* Makefile.in (DIST_SRC): Add them to the list.
+
+	* sparse-ops.h sparse-xdiv.h, sparse-xpow.h: New files.
+	* Makefile.in (INCLUDES): Add them to the list.
+
+	* DLD-FUNCTIONS/colamdoct.cc, DLD-FUNCTIONS/sparse.cc,
+	DLD-FUNCTIONS/spdet.cc, DLD-FUNCTIONS/splu.cc,
+	DLD-FUNCTIONS/spparms.cc: New files.
+	* Makefile.in (DLD_XSRC): Add them to the list.
+
+	* ov-base-sparse.cc, ov-base-sparse.h, ov-bool-sparse.cc,
+	ov-bool-sparse.h, ov-cx-sparse.cc, ov-cx-sparse.h,
+	ov-re-sparse.cc, ov-re-sparse.h: New files.
+	* Makefile.in (OV_SPARSE_SRC, OV_SPARSE_INCLUDES): New lists.
+	(OV_SRC): Add $(OV_SPARSE_SRC) to the list.
+	(INCLUDES): Add $(OV_SPARSE_INCLUDES) to the list.
+	
+	* OPERATORS/op-bm-sbm.cc, OPERATORS/op-b-sbm.cc,
+	OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc,
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc,
+	OPERATORS/op-fil-sbm.cc, OPERATORS/op-fil-scm.cc,
+	OPERATORS/op-fil-sm.cc, OPERATORS/op-m-scm.cc,
+	OPERATORS/op-m-sm.cc, OPERATORS/op-sbm-b.cc,
+	OPERATORS/op-sbm-bm.cc, OPERATORS/op-sbm-sbm.cc,
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-scm-cs.cc,
+	OPERATORS/op-scm-m.cc, OPERATORS/op-scm-s.cc,
+	OPERATORS/op-scm-scm.cc, OPERATORS/op-scm-sm.cc,
+	OPERATORS/op-sm-cm.cc, OPERATORS/op-sm-cs.cc,
+	OPERATORS/op-sm-m.cc, OPERATORS/op-sm-s.cc,
+	OPERATORS/op-sm-scm.cc, OPERATORS/op-sm-sm.cc,
+	OPERATORS/op-s-scm.cc, OPERATORS/op-s-sm.cc: New files.
+	* Makefile.in (SPARSE_OP_XSRC): New list.
+	(OP_XSRC): Add $(SPARSE_OP_XSRC) to the list.
+
+2005-02-23  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (fold (tree_binary_expression*)): Skip constant folding
+	for some expressions to preserve warnings.
+	(Vwarn_associativity_change): New static variable.
+	(warn_associativity_change): New function.
+	(symbols_of_parse): DEFVAR warn_associativity_change.
+	(maybe_warn_associativity_change): New function.
+	(make_binary_op): Use it.
+
+2005-02-22  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (POW, EPOW): Use %left associativity for compatibility.
+
+	* ov-base-int.cc (octave_baes_int_matrix<T>::load_binary):
+	Handle arrays with only one dimension.
+	* ov-bool-mat.cc (octave_bool_matrix::load_binary): Likewise.
+	* ov-cell.cc (octave_cell::load_binary): Likewise.
+	* ov-cell.cc (octave_complex_matrix::load_binary): Likewise.
+	* ov-re-mat.cc (octave_matrix::load_binary): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::load_binary): Likewise.
+
+	* ov-mapper.cc (octave_mapper::subsref): Return retval after
+	calling next_subsref.
+
+	* ov-mapper.cc (octave_builtin::subsref): If nargout is 0 and we
+	have additional indexing to perform, set it to 1 before calling
+	do_multi_index_op.
+
+	* oct-map.cc (Octave_map::intfield, Octave_map::stringfield):
+	New functions.
+	* oct-map.h: Provide decls.
+	* DLD-FUNCTIONS/time.cc (extract_tm): Use intfield and stringfield
+	to access map elements.
+
+2005-02-21  John W. Eaton  <jwe at octave.org>
+
+	* ov-builtin.cc (octave_builtin::subsref): If nargout is 0 and we
+	have additional indexing to perform, set it to 1 before calling
+	do_multi_index_op.
+	* ov-usr-fcn.cc (octave_user_function::subsref): Likewise.
+
+	* DLD-FUNCTIONS/gplot.l (send_to_plot_stream):
+	Replot with no previous plot is a no-op.
+	(makeplot): Likewise.
+	(Vautomatic_replot): Don't use this variable in low-level functions.
+
+2005-02-18  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (oct-gperf.h): Remove -E from list of gperf options.
+
+	* data.cc (do_permute): Use zero-based indexing for permutation
+	vector that is passed to octave_value::permute method.
+	Allow permutation vector longer	than number of dimenensions of
+	permuted matrix.
+
+2005-02-17  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_API_VERSION): Now 2.1.64-cvs.
+	(OCTAVE_API_VERSION): Now api-v12-cvs.
+
+2005-02-16  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-mat.h (octave_base_matrix::squeeze): Explicitly convert
+	result of matrix.squeeze() to MT.
+
+2005-02-15  John W. Eaton  <jwe at octave.org>
+
+	* dirfns.cc (deftypefn): Don't print to octave_stdout if nargout > 0.
+
+	* pt-mat.cc (tree_matrix::rvalue): Min size of ra_idx is 2.
+
+	* file-io.cc (Ffclear): New function.
+
+	* sighandlers.h: Define SIGCHLD if it is not already defined and
+	SIGCLD is defined.
+
+	* sighandlers.cc (octave_set_signal_handler): Request system calls
+	restarted if interrupted by signals (except for SIGALRM).
+	* dirfns.cc (Fls): Don't bother with sleeping or checking errno.
+
+2005-02-11  John W. Eaton  <jwe at octave.org>
+
+	* sighandlers.cc (sigpipe_handler): Don't try to take action.
+	Set octave_signal_caught and octave_signals_caught here.
+	(sigchld_handler): Call octave_child_list::wait here.
+	Set octave_signal_caught and octave_signals_caught here.
+	(octave_signals_caught): New static file-scope variable.
+	(sigint_handler): Also set octave_signal_caught.
+
+	* sighandlers.cc (sigpipe_handler): 
+
+	* DLD-FUNCTIONS/gplot.l (plot_stream_event_handler): Rename from
+	plot_stream_death_handler.  Return true if plotter has exited.
+	Call close_plot_stream with false arg.
+	(plot_stream_pid): Delete static file-scope variable and all uses.
+	(close_plot_stream): New arg, remove_from_child_list, with default
+	value of true.  Only call octave_child_list::remove if
+	remove_from_child_list is true.
+
+	* pager.cc (octave_pager_pid, saved_interrupt_handler,
+	interrupt_handler_saved): Delete static file-scope variables and
+	all uses.
+	(clear_external_pager): Do nothing if external_pager is 0.
+	(pager_event_handler): Rename from pager_death_handler.
+	Improve warning message.  Return true if pager has exited.
+	(octave_pager_buf::do_sync): Check errno == EPIPE after write.
+	(flush_octave_stdout): No need to check external_pager before
+	calling clear_external_pager.
+
+	* toplev.cc (recover_from_exception): Set octave_signal_caught to zero.
+	(main_loop): Set octave_signal_hook to octave_signal_handler here.
+
+	* sighandlers.cc (octave_signal_handler): New function.
+	* sighanlders.h: Provide decl.
+
+	* sighandlers.cc (install_signal_handlers): Initialize
+	octave_signals_caught.
+
+	* sighandlers.h (octave_child::status, have_status): New data members.
+	(child_event_handler): Rename from dead_child_handler.
+	Change all uses.
+	(octave_child_list::reap, octave_child_list::wait): New functions.
+	(octave_child_list::length, octave_child_list::do_length,
+	octave_child_list::elem, octave_child_list::do_elem,
+	octave_child_list::list, octave_child_list::curr_len): Delete.
+
+	* sighandlers.h, sighandlers.cc
+	(octave_child_list::octave_child_list_rep): New class.
+
+	* input.cc (gnu_readline, octave_gets, get_user_input):
+	Call OCTAVE_QUIT before doing anything.
+
+	* base-list.h (octave_base_list<T>::remove_if): New function.
+
+	* TEMPLATE-INST/Array-oc.cc: Delete.
+	* Makefile.in (TI_XSRC): Remove from list.
+
+2005-02-10  Driss Ghaddab  <driss.ghaddab at free.fr>
+
+	* cutils.c (octave_usleep) [HAVE_POLL]: Fix typo.
+
+2005-02-10  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (symbol_exist): Don't search path if explicitly
+	asked for a variable or builtin.  From David Bateman
+	<dbateman at free.fr>.
+
+2005-02-09  John W. Eaton  <jwe at octave.org>
+
+	* variables.cc (same_file): New static function.
+	(symbol_out_of_date): Use it.
+
+	* syscalls.cc (Fcanonicalize_file_name): New function.
+
+2005-02-08  Walter Landry  <landry at osc.edu>
+
+	* symtab.h (symbol_record::mark_as_command): Avoid AIX compiler error.
+
+2005-02-07  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx): Return [] instead
+	of [](1x0) for scalar arg of zero.
+
+2005-02-06  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l (tmp_files): Delete.
+	From Todd Neal <tolchz at tolchz.net>.
+
+2005-02-04  John W. Eaton  <jwe at octave.org>
+
+	* sighandlers.cc (octave_child_list::~octave_child_list): Move here.
+	* sighandlers.h: From here.
+
+2005-02-02  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (parse.cc): Expect 12 shift/reduce conflicts.
+	* parse.y (loop_command): Allow "for (k=1:10) ... endfor".
+
+2005-01-27  David Bateman  <dbateman at free.fr>
+
+	* ov-mapper.cc (octave_mapper::apply): Only work on real arguments
+	if c_c_map_fcn or d_d_map_fcn or d_b_map_fcn is defined.xo
+
+2005-01-26  Joel Andersson  <snprintf at gmail.com>
+
+	* help.cc (keywords): Document endswitch.
+
+2005-01-21  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/filter.cc (filter): Avoid slow Marray indexing ops.
+
+2005-01-20  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (EXTRAS): Move ov-base-mat.cc ov-base-scalar.cc here.
+	(OV_SRC): From here.
+
+2005-01-18  John W. Eaton  <jwe at octave.org>
+
+	* ov-complex.h (octave_complex::any): New function.
+	* ov-scalar.h (octave_scalar::any): New function.
+
+	* file-io.cc (Fmkstemp): Fix doc string.  Error message belongs in
+	third output value.  From Mats Jansson <mats.e.jansson at home.se>.
+
+2005-01-12  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/find.cc (Ffind): Make it work for character strings.
+
+2005-01-11  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/gplot.l (UNOP): Avoid trailing comment.
+
+2005-01-10  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.cc (extract_keyword (std::istream&, const
+	string_vector&, std::string&, int&, const bool)):
+	Remove duplicate definition.
+
+2004-12-27  Martin Dalecki  <martin at dalecki.de>
+
+	* Cell.cc, c-file-ptr-stream.cc, comment-list.cc, oct-map.cc,
+	oct-obj.cc, ov-base.cc, ov-base-int.cc, ov-base-mat.cc,
+	ov-base-scalar.cc, ov-bool.cc, ov-bool-mat.cc, ov-builtin.cc,
+	ov.cc, ov-cell.cc, ov-ch-mat.cc, ov-colon.cc, ov-complex.cc,
+	ov-cs-list.cc, ov-cx-mat.cc, ov-dld-fcn.cc, ov-fcn.cc,
+	ov-fcn-handle.cc, ov-fcn-inline.cc, ov-file.cc, ov-int16.cc,
+	ov-int32.cc, ov-int64.cc, ov-int8.cc, ov-list.cc, ov-mapper.cc,
+	ov-range.cc, ov-re-mat.cc, ov-scalar.cc, ov-streamoff.cc,
+	ov-str-mat.cc, ov-struct.cc, ov-typeinfo.cc, ov-uint16.cc,
+	ov-uint32.cc, ov-uint64.cc, ov-uint8.cc, ov-usr-fcn.cc,
+	ov-va-args.cc, procstream.cc, pt-arg-list.cc, pt-assign.cc,
+	pt-binop.cc, pt-bp.cc, pt.cc, pt-cell.cc, pt-check.cc, pt-cmd.cc,
+	pt-colon.cc, pt-const.cc, pt-decl.cc, pt-except.cc, pt-exp.cc,
+	pt-fcn-handle.cc, pt-id.cc, pt-idx.cc, pt-jump.cc, pt-loop.cc,
+	pt-mat.cc, pt-misc.cc, pt-pr-code.cc, pt-select.cc, pt-stmt.cc,
+	pt-unop.cc, symtab.cc, token.cc, unwind-prot.cc:
+	Delete #pragma implementation.
+
+	* Cell.h, c-file-ptr-stream.h, comment-list.h, oct-map.h,
+	oct-obj.h, ov-base.h, ov-base-int.h, ov-base-mat.h,
+	ov-base-scalar.h, ov-bool.h, ov-bool-mat.h, ov-builtin.h,
+	ov-cell.h, ov-ch-mat.h, ov-complex.h, ov-cs-list.h, ov-cx-mat.h,
+	ov-dld-fcn.h, ov-fcn.h, ov-fcn-handle.h, ov-fcn-inline.h,
+	ov-file.h, ov.h, ov-int16.h, ov-int32.h, ov-int64.h, ov-int8.h,
+	ov-list.h, ov-mapper.h, ov-range.h, ov-re-mat.h, ov-scalar.h,
+	ov-streamoff.h, ov-str-mat.h, ov-struct.h, ov-typeinfo.h,
+	ov-uint16.h, ov-uint32.h, ov-uint64.h, ov-uint8.h, ov-usr-fcn.h,
+	procstream.h, pt-arg-list.h, pt-assign.h, pt-binop.h, pt-bp.h,
+	pt-cell.h, pt-check.h, pt-cmd.h, pt-colon.h, pt-const.h,
+	pt-decl.h, pt-except.h, pt-exp.h, pt-fcn-handle.h, pt.h, pt-id.h,
+	pt-idx.h, pt-jump.h, pt-loop.h, pt-mat.h, pt-misc.h, pt-pr-code.h,
+	pt-select.h, pt-stmt.h, pt-unop.h, symtab.h, token.h,
+	unwind-prot.h: Delete #pragma interface.
+
+2004-12-27  John W. Eaton  <jwe at octave.org>
+
+	Merge of changes from Teemu Ikonen <tpikonen at pcu.helsinki.fi> to
+	remove gnuplot from main parser.
+
+	* pt-plot.cc, pt-plot.h: Delete.
+	* Makefile.in (PT_SRC, PT_INCLUDES): Delete them from the lists.
+
+	* DLD-FUNCTIONS/gplot.l: New file.
+	* Makefile.in: Include it in the DLD_XSRC list.
+
+	* dirfns.cc (octave_change_to_directory):
+	Don't call do_external_plotter_cd.
+
+	* symtab.h (symbol_record::TYPE): New element, RAWCOMMAND.
+	(symbol_record::symbol_def::mark_as_rawcommand,
+	symbol_record::symbol_def::unmark_rawcommand,
+	symbol_record::symbol_def::is_rawcommand): New functions.
+	(symbol_record::symbol_def::symbol_type): Bitfield is now 9 bits wide.
+	(symbol_record::mark_as_rawcommand,
+	symbol_record::unmark_rawcommand, symbol_record::is_rawcommand):
+	New functions.
+	(SYMTAB_ALL_TYPES): Include RAWCOMMAND.
+
+	* parse.y (make_plot_command): Delete function.
+	(tree_plot_command_type, subplot_type, subplot_list_type,
+	plot_limits_type, plot_range_type, subplot_using_type,
+	subplot_style_type, subplot_axes_type):
+	Delete non-terminal type decls.
+	(PLOT, STYLE, AXES_TAG): Delete token types.
+	(title, plot_command, plot_command2, plot_options, plot_command1,
+	ranges, ranges1, using, using1, style, axes): Delete non-terminals.
+
+	* toplev.cc (do_octave_atexit): Don't call close_plot_stream.
+
+	* variables.cc (rawcommand_set): New static variable.
+	(is_marked_as_rawcommand, mark_as_rawcommand, unmark_rawcommand,
+	Fiscommand, Fmark_as_rawcommand, Funmark_rawcommand,
+	Fisrawcommand, is_rawcommand_name): New functions.
+	* variables.h: Provide decl for is_rawcommand_name.
+
+	* pt-bp.cc, pt-bp.h, pt-check.cc, pt-check.h, pt-pr-code.cc,
+	pt-pr-code.h, pt-walk.h: Delete all declarations, definitions, and
+	uses of visit_subplot, visit_subplot_axes, visit_subplot_list,
+	visit_subplot_style, and visit_subplot_using methods.
+
+	* lex.h (lexer_flags): New field, doing_rawcommand.
+	* lex.l (<COMMAND_START>[\;\,]): Also handle raw commands here.
+	(lexer_flags::init): Initialize doing_racommand to false.
+	(handle_identifier): Recognize raw commands ere.
+	(handle_string): Don't do string escape conversions on raw command
+	strings.
+
+	* octave.gperf: Delete gplot_kw, gsplot_kw, replot_kw.
+
+	* lex.h (lexer_flags): Delete fields cant_be_identifier,
+	doing_set, in_plot_range, in_plot_using, in_plot_style,
+	in_plot_axes, past_plot_range, and plotting.
+	* lex.l: Delete all uses of these lexer flags and remove all
+	special cases for plotting.
+	(plot_style_token, plot_axes_token, is_plot_keyword): Delete.
+
+	* file-io.cc, file-io.h (tmp_files, mark_for_deletion,
+	cleanup_tmp_files): Move here.
+	* pt-plot.cc, pt-plot.h: From here.
+
+	* Makefile.in (PKG_ADD): New target.
+	(all): Depend on PKG_ADD.
+	(install-oct): Depend on PKG_ADD.  Install PKG_ADD file.
+	(gplot.cc): New target.
+	(stamp-prereq): Depend on gplot.cc.
+	(VAR): Don't include $(DLD_SRC) here.
+	(DLD_OBJ, DLD_DEF_FILES): Include .l files.
+
+	* defun-int.h (DEFVAR, DEFCONST, DEFCONSTX): Move definition here.
+	* defun.h: From here.
+
+2004-12-22  John W. Eaton  <jwe at octave.org>
+
+	* ls-oct-ascii.cc (extract_keyword (std::istream&, const
+	string_vector&, std::string&, int&, const bool): New function.
+	* ls-oct-ascii.h: Provide decl.
+	* ov-bool-mat.cc (octave_bool_matrix::load_ascii):
+	Use new extract_keyword function to avoid calling tellg/seekg.
+	* ov-cell.cc (octave_cell::load_ascii): Likewise.
+	* ov-cx-mat.cc (octave_complex_matrix::load_ascii): Likewise.
+	* ov-re-mat.cc (octave_matrix::load_ascii): Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::load_ascii): Likewise.
+
+2004-12-20  John W. Eaton  <jwe at octave.org>
+
+	* pt-idx.cc (tree_index_expression::has_magic_end): Return true if
+	any argument list element has a magic end token.
+
+2004-12-03  John W. Eaton  <jwe at octave.org>
+  
+  	* version.h (OCTAVE_VERSION): Now 2.1.64.
+
+2004-12-03  Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* file-io.cc: Doc string fixes.
+
+2004-12-02  David Bateman  <dbateman at free.fr>
+
+	* input.cc (get_user_input): Only set nm and line for debugging if
+	both debug is true and curr_caller_function is non-null.
+
+2004-12-02  David Bateman  <dbateman at free.fr>
+
+	* ls-mat5.cc (arrayclasstype): Add mxINT64_CLASS, mxUINT64_CLASS,
+	mxFUNCTION_CLASS enum values.
+	(read_mat5_integer_data): New template function.
+	(OCTAVE_MAT5_INTEGER_READ): New macro.
+	(read_mat5_binary_element): Handle reading integer types.
+	Eliminate automatic conversion from int to double.
+	(write_mat5_integer_data): New template function.
+	Instantiate it for the 8 integer data types
+	(save_mat5_binary_element): Handle integer data types.
+
+	* load-save.cc (Fload): Check file existence here.
+	If file does not exist, append ".mat" to name and try again.
+	(get_file_format): Delete check for file existence.
+
+2004-11-30  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (oct-gperf.h): Use -L C++ instead of -L ANSI_C.
+	Use -Z octave_kw_hash option, delete -H and -N options.
+	* lex.l (is_keyword_token): Use octave_kw_hash::in_word_set
+	instead of octave_kw_lookup.
+	(is_keyword): Likewise.
+
+2004-11-22  John W. Eaton  <jwe at octave.org>
+
+	* pt-arg-list.cc (tree_argument_list::convert_to_const_vector):
+	Check to see whether object is a function or function handle
+	instead of constant.
+
+2004-11-19  John W. Eaton  <jwe at octave.org>
+
+	* ov-str-mat.cc (octave_char_matrix_str::do_index_op):
+	Skip indexing operation if indices are invalid.
+
+	* pr-output.cc (set_range_format, set_complex_matrix_format,
+	set_complex_format, set_real_matrix_format, set_real_format):
+	Also specify std::ios::fixed for bank format.
+
+2004-11-17  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.63.
+	(OCTAVE_API_VERSION): Now api-v12.
+
+2004-11-17  David Bateman  <dbateman at free.fr>
+
+	* pt-arg-list.cc (F__end__): Ask dv for the number of elements
+	instead indexed_object.
+
+2004-11-16  David Bateman  <dbateman at free.fr>
+
+	* ov.h (octave_value::numel): Now virtual.  Call rep->numel ().
+	* ov.cc (octave_value::numel): Delete.
+	* ov-base.h (octave_base_value::numel): New function.
+
+2004-11-12  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.62.
+
+2004-11-09  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-int-concat.cc: New file for mixed integer/other
+	concatentation operators.
+	* Makefile.in (INTTYPE_OP_XSRC): Add it to the list.
+
+	* ops.h (DEFNDCATOP_FN2): New macro.
+
+	* OPERATORS/op-int.h (OCTAVE_CONCAT_FN2,
+	OCTAVE_INSTALL_CONCAT_FN2, OCTAVE_DOUBLE_INT_CONCAT_FN,
+	OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN, OCTAVE_INT_DOUBLE_CONCAT_FN,
+	OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN): New macros.
+
+2004-11-09  David Bateman  <dbateman at free.fr>
+
+	* Cell.cc (concat): Delete.
+	(Cell::concat): New method.
+	* Cell.h: Provide decls.
+	
+	* oct-map.cc (concat): Delete
+	(Octave_map::concat): New method.
+	* oct-map.h: Provide decls.
+	
+	* ov.h (typedef octave_value (*cat_op_fcn) (octave_value&, 
+	const octave_value&, const Array<int>&): Change definition of 
+	cat_op_fcn so first argument is not constant.
+
+	* ops.h (CATOPDECL): First arg is no longer constant.
+	(DEFCATOP_FN, DEFNDCATOP_FN): Change to use new concat methods.
+
+	* OPERATORS/op-chm.cc, OPERATORS/op-str-m.cc, OPERATORS/op-str-s.cc, 
+	OPERATORS/op-str-str.cc (DEFCATOP): Change explicit concat functions
+	to use new concatenation methods.
+
+2004-11-05  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.61.
+
+	* DLD-FUNCTIONS/det.cc (det): Always compute rcond so we can
+	detect numerically singular matrices.
+
+2004-11-04  John W. Eaton  <jwe at octave.org>
+
+	* pt-colon.cc (tree_colon_expression::line,
+	tree_colon_expression::column): New functions.
+	* pt-colon.h: Provide decls.
+
+	* oct-stream.cc (octave_stream::seek (long, int)): Return error
+	(but leave file position unchanged) for attempt to seek beyond end
+	of file.
+
+	* DLD-FUNCTIONS/inv.cc (Finv): Check rcond value returned from
+	LAPACK routines, and be careful to avoid optimizing away the
+	1+rcond == 1.0 check.
+	* DLD-FUNCTIONS/det.cc (Fdet): Likewise.
+
+2004-11-03  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (Fsize): Return 1 if requested dimension is larger than
+	the number of dimensions of the given object.
+
+2004-11-01  Claude Lacoursiere  <claude at hpc2n.umu.se>a
+
+	* ls-hdf5.cc (read_hdf5_data): Expect num_obj to be in distinct group.
+	* ov-cell.cc (octave_cell::load_hdf5): Likewise.
+	* ov-list.cc (octave_list::load_hdf5): Likewise.
+	* ov-struct.cc (octave_struct::load_hdf5): Likewise.
+
+2004-11-01  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/filter.cc (filter (MArray<T>&, MArray<T>&,
+	MArrayN<T>&, MArrayN<T>&, int)): The variable si is now at least 2-D.
+	(Ffilter): Force si to be 2-D, while allowing arbitrary vector
+	orientation.
+
+2004-11-01  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (INSTANTIATE_EYE): New macro.  Use it to instantiate
+	identity matrix functions for various matrix types.
+
+	* variables.cc (do_who): Fix typo in for loop.
+
+2004-10-28  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (save_mat5_binary_element): Save structure elements
+	in correct order.
+
+2004-10-26  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn.h (octave_function::octave_va_arg): No longer const.
+
+2004-10-22  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/filter.cc: Remove some unnecessary parens.
+
+2004-10-22  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/filter.cc (filter (MArray<T>&, MArray<T>&,
+	MArrayN<T>&, MArrayN<T>&, int)): If value to filter is
+	dimensionality 2 it might still be a vector, use special case.
+
+2004-10-21  John W. Eaton  <jwe at octave.org>
+
+	* ov-base.cc (INT_CONV_METHOD): Apply saturation semantics here too.
+
+2004-10-19  John W. Eaton  <jwe at octave.org>
+
+	* ov-range.h (octave_range::write): New function.
+
+2004-10-18  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (symbol_record::dimensions_string_req_first_space,
+	symbol_record::make_dimensions_string): Use dims() for all objects.
+
+2004-10-18  Oyvind Kristiansen  <oyvinkri at stud.ntnu.no>
+
+	* symtab.cc (symbol_table::parse_whos_line_format): Handle
+	size-of-parameter and center-specific format specifiers.
+
+2004-10-18  John W. Eaton  <jwe at octave.org>
+
+	* pt-plot.cc (handle_plot_data): If plotting data from file,
+	always use "using" clause.
+
+2004-10-12  David Bateman  <dbateman at free.fr>
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::do_init_element,
+	tm_const::init): Dimensionality of matrices not necessarily the
+	same.  Check before comparing.
+
+2004-10-06  John W. Eaton  <jwe at octave.org>
+
+	* pt-fcn-handle.h (tree_fcn_handle::name): New function.
+
+2004-10-01  John W. Eaton  <jwe at octave.org>
+
+	* ov-range.h (octave_range::valid_as_scalar_index): Ensure int value.
+	(octave_range::valid_as_zero_index): Likewise.
+
+	* ov-scalar.h (octave_scalar::valid_as_scalar_index): Ensure int value.
+	(octave_scalar::valid_as_zero_index): Likewise.
+
+2004-09-24  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.60.
+	(OCTAVE_API_VERSION): Now api-v11.
+
+	* OPERATORS/op-int.h (OCTAVE_MM_INT_OPS): Include missing matrix
+	by int matrix ops.
+	(OCTAVE_INSTALL_MM_INT_OPS): Install them.
+
+	* OPERATORS/op-i64-i64.cc: Define and install missing int64 by
+	matrix and scalar ops.
+
+2004-09-24  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-inline (Finline): Attempt better auto-detection of
+	symbols that should be recognized as arguments.
+
+2004-09-24  John W. Eaton  <jwe at octave.org>
+
+	* ov-str-mat.cc (default_numeric_conversion_function): Return
+	scalar object if numel == 1.
+
+2004-09-23  John W. Eaton  <jwe at octave.org>
+
+	* ops.h	(DEFSTRDBLCONVFN): New macro.
+	* OPERATORS/op-double-conv.cc: Use it to define new conversion op.
+	Define new range to double matrix conversion.
+	(install_int_conv_ops): Install new ops.	
+
+	* ops.h	(DEFSTRINTCONVFN): New macro.
+	* OPERATORS/op-int-conv.cc: Use it to define new conversion ops.
+	(install_int_conv_ops): Install them.
+
+	* (OCTAVE_SS_INT_OPS2, OCTAVE_SM_INT_OPS2, OCTAVE_MM_INT_OPS2,
+	OCTAVE_INSTALL_SS_INT_OPS2, OCTAVE_INSTALL_SM_INT_OPS2,
+	OCTAVE_INSTALL_MS_INT_OPS2, OCTAVE_INSTALL_MM_INT_OPS2):
+	Delete unused macros.
+
+	* OPERATORS/op-int.h (OCTAVE_SS_INT_BOOL_OPS): New args Z1 and Z2.
+	(OCTAVE_SS_INT_OPS): Pass appropriately typed zero values to
+	OCTAVE_SS_INT_BOOL_OPS.
+	* OPERATORS/op-i64-i64.cc, OPERATORS/op-ui64-ui64.cc: Likewise.
+
+	* pr-output.cc (pr_plus_format): Now template.
+	Specialize for Complex.
+	(octave_print_internal): Lookup print_conv_type using
+	octave_int<T>, not just T.
+
+	* ov-struct.cc (octave_struct::subsref): Pass skip to next_subsref.
+
+	* oct-stream.cc	(do_read): Hitting EOF should not be an error.
+
+2004-09-22  John W. Eaton  <jwe at octave.org>
+
+	* pt-plot.cc (send_to_plot_stream): Skip automatic replot if in
+	multiplot mode.
+
+	* variables.cc (get_global_value): New arg, silent.
+	* variables.h (get_global_value): Default value for silent arg is
+	false.
+
+2004-09-22  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-inline.cc (Finline): When called with a single arg, derive
+	argument of inline function in a compatible manner.
+
+2004-09-22  Federico Zenith  <zenith at chemeng.ntnu.no>
+
+	* DLD-FUNCTIONS/qz.cc (Fqz): New @tex section(s) in doc string for
+	better formating of printed documentation.  Use @var in doc string.
+
+	* DLD-FUNCTIONS/time.cc (Fstrftime): Fix typo in doc string.
+	* error.cc (Flasterr, Flastwarn): Likewise.
+	* mappers.cc (Farg, Fasinh, Fatanh, Ffinite, Fsin, Fsinh, Ftan):
+	Likewise.
+	* file-io.cc (Fmktemp): Likewise.
+	* pt-plot.cc (symbols_of_pt_plot): Fix typos in doc string for
+	gnuplot_has_frames.
+
+	* input.cc (symbols_of_input): Replace --echo-input with new
+	--echo-commands in PS4 doc string.
+
+	* pt-assign.cc (symbols_of_pt_assign): Mark print_rhs_assign_val
+	as built-in in doc string.
+
+	* symtab.cc (symbols_of_symtab): Mark variables_can_hide_functions
+	as built-in in doc string.
+
+2004-09-21  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.59.
+
+	* oct-fstrm.h (octave_fstream::octave_fstream,
+	octave_fstream::create): Set default float format to actual native
+	format, not flt_fmt_native.
+	* oct-iostrm.h (octave_base_iostream::octave_base_iostream,
+	octave_istream::octave_istream, octave_ostream::octave_ostream):
+	Likewise.
+	* oct-prcstrm.h (octave_iprocstream::octave_iprocstream,
+	octave_oprocstream::octave_oprocstream,
+	octave_iprocstream::create, octave_oprocstream::create):
+	Likewise.
+	* oct-stdstrm.h (octave_stdiostream::octave_stdiostream,
+	octave_stdiostream::create):
+	Likewise.
+	* oct-stream.h (octave_base_stream::octave_base_stream):
+	Likewise.
+	* oct-strstrm.h (octave_base_strstream::octave_base_strstream,
+	octave_istrstream::octave_istrstream, octave_istrstream::create):
+	Likewise.
+
+2004-09-21  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Freshape): Allow a single empty dimension argument
+	to flag unknown dimension and calculate its value from the
+	other dimensions.
+
+2004-09-21  John W. Eaton  <jwe at octave.org>
+
+	* symtab.h (symbol_record::~symbol_record): Delete definition if
+	count goes to zero.
+	* symtab.cc (symbol_table::~symbol_table): Move here from symtab.h.
+	Call delete on each symbol record in the table instead of just
+	clearing them.
+
+2004-09-17 David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sort.cc (ascending_compare, descending_compare):
+	Now templates (avoids g++ 3.4.x compile problems).
+	Fix other uses of these functions to also treat them as templates.
+	(mx_sort): For unsigned EIGHT_BYTE_INT versions correct the test 
+	for the position of NaN.  Problems when mode was DESCENDING or
+	UNDEFINED.  Use static_cast<unsigned int> (dim) rather than 
+	(unsigned int) dim.
+	(IFloatFlip): Now static.
+
+2004-09-17  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/det.cc (Fdet): Only compute estimate of the
+	condition number if requested as output.
+
+	* DLD-FUNCTIONS/schur.cc (Fschur): Only compute unitary matrix if
+	requested as output.
+
+2004-09-17  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-inline.cc (octave_fcn_inline::octave_fcn_inline):
+	Call eval_string instead of feval ("eval", ...).
+	Construct anonymous function handle to avoid going through the
+	symbol table.
+
+	* ov-fcn-handle.h (octave_fcn_handle::fcn_val): New function.
+	(octave_fcn_handle::octave_fcn_handle (const std:string&)):
+	New constructor.
+
+2004-09-16  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (frob_function): Clear id_name from curr_sym_tab, not
+	top_level_sym_tab.
+
+	* symtab.cc (maybe_list): Count sizes using size_t, not int.
+
+	* variables.cc (symbol_out_of_date): Always look in LOADPATH.
+
+2004-09-15  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-int-conv.cc: Define and install bool to int
+	conversions.
+	* OPERATORS/op-double-conv.cc: Define and install bool to double
+	conversions.
+
+	* ov.cc (octave_value::assign): Handle subsref for containers.
+	* oct-lvalue.cc (octave_lvale::value): Likewise.
+
+	* DLD-FUNCTIONS/sort.cc (mx_sort): Return octave_value, not
+	octave_value list.
+
+2004-09-15  David Bateman  <dbateman at free.fr>
+
+	* ov.cc (octave_value::octave_value (const ArrayN<char>&, bool)):
+	New Constructor .
+	* ov.h: Provide decl.
+
+	* DLD-FUNCTIONS/sort.cc (sortmode): New enum to define sort direction.
+	(template <class T> class vec_index): New class to contain values and
+	index for indexed sorts, replacing all previous struct versions. 
+	Instantiate for double, Complex, char and octave_value.
+	(template <class T> static octave_value_list mx_sort (ArrayN<T> &, int,
+	sortmode)): New templated version of mx_sort replacing all previous
+	versions, but specific to non indexed sorts. Instantiate for char
+	and double if not IEEE754.
+	(template <> static octave_value_list mx_sort (ArrayN<double> &, 
+	int, sortmode)): Specialized function of mx_sort of IEEE754.
+	(template <class T> static octave_value_list mx_sort_indexed 
+	(ArrayN<T> &, int, sortmode)): New templated version of mx_sort 
+	for indexed sorts. Instantiate for double, Complex, char and 
+	octave_value.
+	(ascending_compare, descending_compare): Comparison functions
+	for double, char, vec_index<double> *, vec_index<Complex> *,
+	vec_index<char> *, vec_index<octave_value>. Fix Complex comparison
+	operator to sort by arg of values if absolute values are equal.
+	(Fsort): Update docs for new mode argument and for sorting of 
+	strings and cell arrays of strings. Implement mode argument to
+	define ascending and descending sorts. Include sorting of cell
+	arrays of strings. Adapt for new templated versions of the mx_sort
+	function.
+
+2004-09-15  John W. Eaton  <jwe at octave.org>
+
+	* ov-cell.cc (octave_cell::subsref): Pass nargout to next_subsref.
+	* ov-builtin.cc (octave_builtin::subsref): Likewise.
+	* ov-fcn-handle.cc (octave_fcn_handle::subsref): Likewise.
+	* ov-list.cc (octave_list::subsref): Likewise.
+	* ov-mapper.cc (octave_mapper::subsref): Likewise.
+	* ov-struct.cc (octave_struct::subsref): Likewise.
+	* ov-usr-fcn.cc (octave_user_function::subsref): Likewise.
+
+	* ov-struct.cc, ov-struct.h (octave_struct::subsref (const
+	std::string&, const std::list<octave_value_list>&, int)):
+	Define this version.
+	(octave_struct::subsref (const std::string&, const
+	std::list<octave_value_list>&)): Panic in this version.
+	* ov-list.cc, ov-list.h: Likewise.
+	* ov-cell.cc, ov-cell.h: Likewise.
+
+	* ov.cc (octave_value::subsref (int, const std::string&, const
+	std::list<octave_value_list>&, size_t)): New function.
+	* ov.h: Provide decl.	
+
+	* ov-cell.h (octave_cell::is_constant): Return false.
+	* ov-struct.h (octave_struct::is_constant): Delete.
+	* ov-list.h (octave_list::is_constant): Delete.
+
+2004-09-14  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sort.cc (mx_sort (charNDArray&, bool, int)):
+	New function to sort character strings.
+	(Fsort): Handle character strings.
+
+2004-09-11  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii):
+	Write directly to OS.
+	(octave_fcn_handle::load_ascii,	octave_fcn_handle::load_binary,
+	octave_fcn_handle::load_hdf5): Check parse status after calling
+	eval_string.  Don't dereference fh unless it is valid.
+
+2004-09-11  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii,
+	octave_fcn_handle::load_ascii, octave_fcn_handle::save_binary,
+	octave_fcn_handle::load_binary, octave_fcn_handle::save_hdf5,
+	octave_fcn_handle::load_hdf5): New functions. 
+	* ov-fcn-handle.h: Provide decls.
+
+	* ov-fcn-inline.cc (octave_fcn_inline::load_ascii):
+	Allow spaces in saved function.
+ 	(octave_fcn_inline::save_hdf5): Properly close all HDF5 objects.
+
+	* ls-oct-ascii.cc (read_ascii_data): Check return type of 
+	<octave_value>.load_ascii for errors reading the variables
+
+	* variables.cc (lookup_function_handle, clear_variable,
+	clear_symbol): New functions.
+	* variables.h: Provide decls.
+
+2004-09-10  John W. Eaton  <jwe at octave.org>
+
+	* ov-builtin.cc (octave_builtin::do_multi_index_op): Use unwind
+	protect frame instead of a single unwind_protect::run.
+	* ov-mapper.cc (octave_mapper::do_multi_index_op): Likewise.
+
+	* data.cc (fill_matrix, identity_matrix):
+	Also allow logical data type.
+
+2004-09-10  David Bateman  <dbateman at free.fr>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::double_value,
+	OCTAVE_VALUE_INT_MATRIX_T::scalar_value,
+	OCTAVE_VALUE_INT_SCALAR_T::double_value,
+	OCTAVE_VALUE_INT_SCALAR_T::scalar_value): New functions.
+
+2004-09-10  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-scalar.h (octave_base_scalar::clone,
+	octave_base_scalar::empty_clone): New functions.
+
+2004-09-09  John W. Eaton  <jwe at octave.org>
+
+	* pt-pr-code.h (tree_print_code::newline): New optional arg, alt_nl.
+	* pt-pr-code.cc (tree_print_code::newline): Use it if not printing
+	newlines.
+	(tree_print_code::visit_statement): If we printed ";", call
+	newline with optional arg set to "".
+	(tree_print_code::printing_newlines): New data member.
+	(tree_print_code::tree_print_code): Initialize it.
+	(tree_print_code::suspend_newline, tree_print_code::resume_newline):
+	New functions.
+	(tree_print_code::newline, tree_print_code::indent): Use it
+
+	* ov-fcn-handle.cc (octave_fcn_handle::print_raw):
+	Print code for anonymous function handles.
+
+2004-09-08  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-handle.cc (Ffunc2str, Ffunctions): Don't call substr(1)
+	on fh_nm, since we no longer need to skip "@" in the name.
+
+	* error.cc (pr_where): Do a better job of printing location info.
+
+	* input.cc (get_user_input): Print location info before the debug
+	prompt.  From Keith Goodman <kwgoodman at gmail.com>.
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Save and set curr_caller_function and curr_caller_statement here.
+	* ov-mapper.cc (octave_mapper::do_multi_index_op): Likewise.
+	* ov-builtin.cc (octave_builtin::do_multi_index_op): Likewise.
+
+	* pt-stmt.cc (curr_caller_statement): New variable.
+	* pt-stmt.h: Provide decl.	
+
+	* toplev.cc (curr_caller_function): New variable.
+	* toplev.h: Provide decl.
+
+	* pt-arg-list.cc (convert_to_const_vector):
+	Unwind-protect index_position before modifying it.
+	Don't protect and set index_position unless stash_object is true.
+
+2004-09-08  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-inline.cc (octave_fcn_inline::save_ascii,
+	octave_fcn_inline::load_ascii, octave_fcn_inline::save_binary,
+	octave_fcn_inline::load_binary, octave_fcn_inline::save_hdf5,
+	octave_fcn_inline::load_hdf5): New functions. 
+	* ov-fcn-inline.h: Provide decls.
+
+2004-09-08  John W. Eaton  <jwe at octave.org>
+
+	* ov.h: Add octave_array_type_traits specialization for
+	boolNDArray element type.
+
+2004-09-07  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc: Instantiate octave_stream::write for Array<bool>.
+	(octave_stream::read): Expand read_fptr_table to include dt_logical.
+
+	* ov-bool.h (octave_bool::write): New function.
+	* ov-bool-mat.h (octave_bool_matrix::write): New function.
+
+	* ov-fcn-inline.h (octave_fcn_inline::octave_fcn_inline): New copy
+	constructor.
+	(octave_fcn_inline::clone, octave_fcn_inline::empty_clone):
+	New functions.
+
+	* ov-fcn-handle.h (octave_fcn_handle::octave_fcn_handle): New copy
+	constructor.
+	(octave_fcn_handle::clone, octave_fcn_handle::empty_clone):
+	New functions.
+
+2004-09-06  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (install_types): Call octave_fcn_inline::register_type.
+
+	* version.h (OCTAVE_API_VERSION): Now api-v10.
+
+	* OPERATORS/op-b-b.cc, OPERATORS/op-bm-bm.cc: Define and install
+	unary plus and unary minus operators.
+
+	* OPERATORS/op-int.h, OPERATORS/op-cm-cm.cc,
+	OPERATORS/op-cs-cs.cc, OPERATORS/op-m-m.cc, OPERATORS/op-range.cc:
+	Define and install unary plus operator.
+
+	* ov.cc (unary_op_as_string): Handle op_uplus too.
+
+	* parse.y (prefix_expr): Build unary plus op here instead of
+	converting to no-op.
+	(make_prefix_op): Accept op_uplus.
+
+2004-09-03  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-b-bm.cc (DEFCONV): Define bool scalar to bool
+	matrix conversion.
+	(install_b_bm_ops): Install it.
+	Install conversion for assignment of bool matrix to indexed bool.
+	* OPERATORS/op-b-b.cc (install_b_b_ops): Install conversion for
+	assignment of bool to indexed bool.
+
+2004-09-03  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-b-b.cc, OPERATORS/op-b-bm.cc, OPERATORS/op-bm-b.cc,
+	OPERATORS/op-bm-bm.cc: Modify concatenation between boolean types
+	so that it returns a boolean.
+
+	* ov-bool.cc (octave_bool::do_index_op): Return boolean matrix.
+
+	* ov-intx.h (do_index_op (const octave_value_list&, int)):
+	New function for indexed subsref of int types.
+
+2004-09-03  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-int.h (OCTAVE_SM_INT_OPS): Define int by double
+	mixed comparison and bool ops.
+	(OCTAVE_INSTALL_SM_INT_OPS): Install them.
+	(OCTAVE_MS_INT_OPS): Define double by int mixed comparison and
+	bool ops.
+	(OCTAVE_INSTALL_MS_INT_OPS): Install them
+
+	* OPERATORS/op-i8-i8.cc, OPERATORS/op-i16-i16.cc,
+	OPERATORS/op-i32-i32.cc, OPERATORS/op-i64-i64.cc,
+	OPERATORS/op-ui8-ui8.cc, OPERATORS/op-ui16-ui16.cc,
+	OPERATORS/op-ui32-ui32.cc, OPERATORS/op-ui64-ui64.cc:
+	Define and install various mixed-type operators.
+
+	* OPERATORS/op-int.h (OCTAVE_MM_INT_OPS): Also define mixed int
+	and double matrix comparison and bool ops.
+	(OCTAVE_INSTALL_MM_INT_OPS): Install them.
+	(OCTAVE_SS_INT_BOOL_OPS, OCTAVE_SM_INT_BOOL_OPS,
+	OCTAVE_MS_INT_BOOL_OPS, OCTAVE_MM_INT_BOOL_OPS):
+	Define logical AND and OR ops.
+	(OCTAVE_INSTALL_SS_INT_BOOL_OPS, OCTAVE_INSTALL_SM_INT_BOOL_OPS,
+	OCTAVE_INSTALL_MS_INT_BOOL_OPS, OCTAVE_INSTALL_MM_INT_BOOL_OPS):
+	Install them.
+	(OCTAVE_MM_INT_CMP_OPS, OCTAVE_MM_INT_BOOL_OPS): Accept prefix arg.
+	(OCTAVE_MM_CONV): New macro.
+	(OCTAVE_MM_INT_OPS): Use it to define complex matrix conversion.
+	(OCTAVE_MIXED_INT_CMP_OPS, OCTAVE_MIXED_INT_BOOL_OPS): New macros.
+
+	* OPERATORS/op-int.h (OCTAVE_MS_INT_OPS): Don't define indexed int
+	matrix = complex scalar assignment ops.
+	(OCTAVE_MS_INT_OPS): Don't define indexed int matrix = complex
+	matrix assignment ops.
+	(OCTAVE_SM_CONV): New macro.
+	(OCTAVE_SM_INT_OPS): Use it to define int scalar -> (int|complex)
+	matrix widening ops.
+	(OCTAVE_RE_INT_ASSIGN_OPS, OCTAVE_CX_INT_ASSIGN_OPS): New macros.
+	(OCTAVE_INT_OPS): Use them here.
+	(OCTAVE_INSTALL_SS_INT_OPS): Install indexed int scalar = scalar
+	and indexed int scalar = complex scalar assignment conversions.
+	(OCTAVE_INSTALL_SM_INT_OPS): Install int scalar -> (int|complex)
+	matrix widening ops.  Install indexed int scalar =
+	(int|real|complex) matrix assignment conversions.
+	(OCTAVE_INSTALL_MS_INT_OPS): Install indexed int matrix = complex
+	scalar assignment conversion.
+	(OCTAVE_INSTALL_MM_INT_OPS): Install int matrix -> complex matrix
+	widening op.  Install indexed int matrix = complex matrix
+	assignment conversion.
+	(OCTAVE_INSTALL_RE_INT_ASSIGN_OPS, OCTAVE_INSTALL_CX_INT_ASSIGN_OPS):
+	New macros.
+	(OCTAVE_INSTALL_INT_OPS): Use them.
+
+	* op-int.h: (OCTAVE_INSTALL_SM_INT_ASSIGNCONV): New macro.
+	* OPERATORS/op-i8-i8.cc, OPERATORS/op-i16-i16.cc,
+	OPERATORS/op-i32-i32.cc, OPERATORS/op-i64-i64.cc,
+	OPERATORS/op-ui8-ui8.cc, OPERATORS/op-ui16-ui16.cc,
+	OPERATORS/op-ui32-ui32.cc, OPERATORS/op-ui64-ui64.cc:
+	Use it to define mixed size integer scalar/integer matrix
+	assignment conversions.
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::complex_array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::complex_array_vale):
+	New functions.
+
+2004-09-02  John W. Eaton  <jwe at octave.org>
+
+	* DLD-FUNCTIONS/quad.cc (Fquad): Pass "__quad_fcn_" instead of
+	"__quad_fcn__" to unique_symbol_name.
+
+	* ov-fcn-inline.cc (octave_fcn_inline): Pass "__inline_" instead
+	of "__inline__" to unique_symbol_name.
+
+	* variables.cc (unique_symbol_name): Make better random symbol name.
+
+2004-09-01  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.58.
+
+	* Makefile.in (OP_INCLUDES): New variable.
+	Include OPERATORS/op-int.h here.
+	* Makefile.in (dist): Also link $(OP_INCLUDES).
+
+	* Makefile.in (DISTFILES): Include $(EXTRAS) in the list.
+
+2004-09-01  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTION/quad.cc: Allow function handle and inline functions.
+	Use a unique function name and delete it on exit.
+
+	* ov.h (is_inline_function): New virtual function.
+	* ov-fcn-inline.h (is_inline_function): New function.
+	* ov-base.h (is_inline_function): New function.
+
+	* ov-fcn-inline.cc (octave_fcn_handle::octave_fcn_handle):
+	Use unique_symbol_name and clear_function instead of manipulating
+	symbol table directly.
+
+	* variables.cc (unique_symbol_name): New function.
+	(clear_function): New function.
+	* variables.h: Provide decls.
+
+	* dynamic-ld.cc (do_clear_function): Rename from clear_function.
+
+2004-09-01  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-i8-i8.cc, OPERATORS/op-i16-i16.cc,
+	OPERATORS/op-i32-i32.cc, OPERATORS/op-i64-i64.cc,
+	OPERATORS/op-ui8-ui8.cc, OPERATORS/op-ui16-ui16.cc,
+	OPERATORS/op-ui32-ui32.cc, OPERATORS/op-ui64-ui64.cc:
+	Define and install mixed assignment ops.
+	* op-int.h: Define mixed integer/double ops.
+	Define simple division ops.
+
+	* ov-complex.h (octave_complex_scalar): New typedef to simplify
+	various macros where naming consistency matters.
+
+2004-08-31  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-int.h (ss_pow, ms_el_pow, mm_el_pow): New power 
+	functions.
+	(sm_el_pow): Return correct type.
+	(OCTAVE_SS_POW_OPS, OCTAVE_SM_POW_OPS, OCTAVE_MS_POW_OPS,
+	OCTAVE_MM_POW_OPS): New macros to define the power operator over
+	integer types.
+	(OCTAVE_SS_INT_OPS, OCTAVE_SM_INT_OPS, OCTAVE_MS_INT_OPS,
+	OCTAVE_MM_INT_OPS): Use the new macros for the power operators.
+	(OCTAVE_INSTALL_SS_INT_OPS, OCTAVE_INSTALL_MS_INT_OPS,
+	OCTAVE_INSTALL_MM_INT_OPS): Install new power functions.
+
+	* OPERATORS/op-int-conv.cc (INT_CONV_FUNCTIONS): Correct return
+	types for unsigned integer scalars and signed integer matrices.
+
+	* ov-type-conv.h (OCTAVE_TYPE_CONV_BODY3): Conversion betwen same
+	types returns the original value.
+
+	* bitfcns.cc (BITOP): Fix for mixed scalar/matrix ops. Allow 
+	octave_range as an argument, by using class_name rather than
+	type_id to test.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.cc (pr_int): Also handle bank_format.
+	(octave_print_internal (std::ostream& os, const intNDArray<T>&,
+	bool, int)): Likewise.
+
+2004-08-31  David Bateman  <dbateman at free.fr>
+
+	* pr-output.cc (pr_int(std::ostream, const T&, int)):
+	New template function to print formatted integer types.
+	Instantiate it for all of the integer types.
+	(octave_print_internal (std::ostream, const intNDArray<T>&, bool,
+	int)): Use pr_int.  Align output up in columns, and check for
+	free_format or plus_format.
+	(octave_print_internal (std::ostream, const octave_int<T>&, bool)):
+	Use pr_int.  Check for free_format and plus_format.
+
+	* ls-hdf5.cc (hdf5_read_next_data): When importing hdf5 files,
+	allow structures and lists (for backward compatibility).  Also
+	allow importation of integer types into octave int and uint types.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* data.cc (fill_matrix, identity_matrix): Convert class name to
+	oct_data_conv::data_type and switch on that.
+	(identity_matrix (int, int)): New template.
+	(identity_matrix (int, int, const std::string&)): Use it.
+
+	* ov.h (octave_type_traits, octave_array_type_traits): Move here.
+	* oct-stream.cc: From here.
+
+2004-08-31  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Fzeros, Fones, Feye): Update help text for optional
+	class argument.
+	(static octave_value identity_matrix (int, int, const std::string&)):
+	New function to create identity matrices with an arbitrary type.
+	(Feye): Call new version of identity matrix function, even for scalars.
+	(static octave_value fill_matrix (const octave_value_list&, double,
+	const char *)): Update to allow arbitrary classes of matrices to be
+	created.
+
+2004-08-31  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat5.cc (read_int): New function.
+
+	* oct-stream.cc (octave_base_stream::do_read,
+	octave_base_stream::read, octave_base_stream::write): Delete.
+	* oct-stream.h: Delete decls.
+
+	* oct-stream.cc (octave_stream::read): Handle block_size and
+	separate input/output types.
+	(octave_stream::write): Handle block_size and various input types.
+	(octave_type_traits, octave_array_type_traits):	New traits classes.
+	(do_read): New templates to read data and perform type conversion.
+	(octave_stream::write (const Array<T>&, int,
+	oct_data_conv::data_type, int, oct_mach_info::float_format),
+	do_write, write_int):
+	New templates to write ints and perform type conversion.
+	Instantiate for various Octave types.
+
+	* ov.cc (octave_value::write): New function.
+	* ov.h: Provide decl.
+	* ov-base.cc (octave_base_value::write): New function.
+	* ov-base.h: Provide decl.
+	* ov-complex.h (octave_complex::write): New function.
+	* ov-cx-mat.h (octave_complex_matrix::write): New function.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::write): New function.
+	(OCTAVE_VALUE_INT_SCALAR_T::write): New function.
+	* ov-re-mat.h (octave_matrix::write): New function.
+	* ov-scalar.h (octave_scalar::write): New function.
+	* ov-str-mat.h (octave_char_matrix_str::write): New function.
+
+	* file-io.cc (Ffread): Handle block size, to/from format in
+	precision argument.
+	(Ffwrite): Handle block size in precision argument.
+
+2004-08-25  David Bateman  <dbateman at free.fr>
+
+	* ov-cell.cc (octave_cell::subsasgn): Delete elements of cell array
+	when type is "(" and rhs is empty.
+
+2004-08-09  John W. Eaton  <jwe at octave.org>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::index_vector,
+	OCTAVE_VALUE_INT_SCALAR_T::index_vector): New functions.
+
+2004-08-06  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-struct.cc: New file.
+	* ov-struct.h (octave_struct::resize (const dim_vector&)):
+	New function.
+	* oct-map.h (Octave_map::resize (const dim_vector&)): New function.
+	* ov-map.cc (Octave_map::reshape):
+	Correct return for same sized reshape.
+	(Octave_map::resize (const dim_vector&)): New function.
+	(concat (const Octave_map&, const Octave_map&, const Array<int>&)):
+	Complete concatenation function.
+	* Makefile.in (OP_XSRC): Include op-struct.cc in the list.
+
+2004-08-05  John W. Eaton  <jwe at octave.org>
+
+	* pt-stmt.h (tree_statement::set_command,
+	(tree_statement::set_expression): New functions.
+
+	* parse.y (param_list_beg): Handle pushing new symbol table
+	context for anonymous function handle parameter lists here.
+	(anon_fcn_handle): New non-terminal.
+	(expression): Include anon_fcn_handle here.
+	(make_anon_fcn_handle): New static function.
+
+2004-08-05  David Bateman  <dbateman at free.fr>
+
+	* ov.cc (octave_value::fcn_inline_value): New virtual function.
+	* ov.h (octave_value::fcn_inline_value): Provide decl.
+	* ov-base.cc (octave_base_value::fcn_inline_value): New function
+	* ov-base.h (octave_base_value::fcn_inline_value): Provide decl.
+	* ov-fcn-handle.cc (octave_fcn_handle::octave_fcn_handle 
+	(const std::string&, const string_vector&, const std::string&),
+	octave_fcn_handle::convert_to_str_internal, Finline, Fargnames,
+	Fformula, Fvectorize): Delete.
+	(octave_fcn_handle::print_raw): Remove inline case.
+	* ov-fcn-handle.h (octave_fcn_handle::fcn_type,
+	octave_fcn_handle::octave_fcn_handle (const std::string&, const
+	string_vector&, const std::string&),
+	octave_fcn_handle::inline_fcn_name,
+	octave_fcn_handle::inline_fcn_text,
+	octave_fcn_handle::inline_fcn_arg_names,
+	octave_fcn_handle::is_inline,
+	octave_fcn_handle::convert_to_str_internal,
+	octave_fcn_handle::typ, octave_fcn_handle::iftext,
+	octave_fcn_handle::ifargs): Delete constructors,
+	functions, and data members (moved to ov-fcn-inline.h).
+	* Makefile.in: Include ov-fcn-inline.h and ov-fcn-inline.cc where
+	appropriate.
+	* ov-fcn-inline.h, ov-fcn-inline.cc: New class.
+
+2004-08-05  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-int.cc (octave_base_int_matrix<T>::save_ascii,
+	octave_base_int_matrix<T>::load_ascii,
+	octave_base_int_matrix<T>::save_binary,
+	octave_base_int_matrix<T>::load_binary,
+	octave_base_int_matrix<T>::save_hdf5,
+	octave_base_int_matrix<T>::load_hdf5,
+	octave_base_int_matrix<T>::try_narrowing_conversion,
+	octave_base_int_scalar<T>::print_raw,
+	octave_base_int_scalar<T>::save_ascii,
+	octave_base_int_scalar<T>::load_ascii,
+	octave_base_int_scalar<T>::save_binary,
+	octave_base_int_scalar<T>::load_binary,
+	octave_base_int_scalar<T>::save_hdf5,
+	octave_base_int_scalar<T>::load_hdf5):
+	Sprinkle with this-> as needed.
+
+	* Makefile.in (EXTRAS): New macro.  Move ov-base-int.cc here from
+	OV_INTTYPE_SRC.
+	(INCLUDES_FOR_INSTALL): New macro.
+	(install-inc, uninstall): Use it instead of INCLUDES.
+
+	* variables.h (symbol_exist): Default for type is now "any".
+
+2004-08-05  David Bateman  <dbateman at free.fr>
+
+	* ov-fcn-handle.cc (octave_fcn_handle (const std::string&, 
+	const string_vector&, const std::string&)): New constructor for inline
+	function handles.
+	(octave_fcn_handle::print_raw): Allow inline functions to be printed.
+	(octave_fcn_handle::convert_to_str_internal): New function to allow
+	Fchar to work on inlined function handles.
+	(Finline, Fformula, Fargnames, Fvectorize): New functions.
+	* ov-fcn-handle.h (octave_fcn_handle (const std::string&, 
+	const string_vector&, const std::string&)): Provide decl.
+	(octave_fcn_handle::convert_to_str_internal): Provide decl.
+	(fcn_type): New enum for the type of function handle.
+	(octave_fcn_handle::inline_fcn_text, octave_fcn_handle::is_inline,
+	octave_fcn_handle::inline_fcn_arg_names): New functions.
+	(octave_fcn_handle::typ, octave_fcn_handle::iftext,
+	octave_fcn_handle::ifargs): New private variables for inline functions.
+
+2004-08-04  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (fcn_handle):
+	Recognize '@' FCN_HANDLE rather than just FCN_HANDLE.
+	Decrement lexer_flags.looking_at_function_handle here.
+	* lex.h (lexical_feedback::looking_at_function_handle):
+	New data member.
+	(lexical_feedback::init): Initialize it.
+	* lex.l (handle_identifier): Only reject keywords if we are
+	looking at a function handle.
+	("@"): Recognize this separately from what follows.
+	Increment lexer_flags.looking_at_function_handle here.
+
+	* ov-fcn-handle.h (octave_fcn_handle::octave_fcn_handle
+	(octave_function*, const std::string)): Delete.
+	* ov.h, ov.cc (octave_value::octave_value (octave_function *)): Delete.
+	(octave_value::octave_value (octave_function *, const std::string)):
+	Delete.
+
+	* ov-fcn-handle.h (octave_fcn_handle::fcn): Now octave_value, not
+	pointer to octave_function.
+	(octave_fcn_handle::octave_fcn_handle (const octave_value&, const
+	std::string)): New constructor.
+	* variables.cc (lookup_function): Return octave_value, not pointer
+	to octave_function.  Change all uses.
+	(lookup_user_function): Return octave_value, not pointer
+	to octave_user_function.  Change all uses.
+
+2004-08-03  John W. Eaton  <jwe at octave.org>
+
+	* ov-usr-fcn.cc (octave_user_fcn::do_multi_index_op): Call
+	install_automatic_vars here.
+	(octave_user_fcn::octave_user_fcn): Not here.
+	(install_automatic_vars): Don't mark argn_sr, nargin_sr,
+	nargout_sr, or varargin_sr as static.
+
+	* oct-stream.cc (octave_scan): Avoid need for pushing two
+	characters back on the input stream.
+
+2004-08-02  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_scan): For %i format, recognize numbers
+	with leading 0x or 0X as hex and leading 0 as octal.
+
+	* OPERATORS/op-fcn-handle.cc: Delete.
+	* Makefile.in (OP_XSRC): Delete it from the list.
+	* pr-output.cc (octave_print_internal (std::ostream&, const
+	std::string&, bool, int): New function.
+	* ov-fcn-handle.cc (octave_value::subsref): New function.
+	* ov-fcn-handle.h (class fcn_handle_elt, class fcn_handle_array):
+	Delete.
+	(class octave_fcn_handle): Derive from octave_base_value, not
+	octave_base_matrix<fcn_handle_array>.
+
+	* ov-cx-mat.cc (try_narrowing_conversion): Also allow complex to
+	real conversion for N-d arrays.
+
+2004-07-30  John W. Eaton  <jwe at octave.org>
+
+	* lex.l (<COMMAND_START>[^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}*):
+	Also recognize \r as a word list separator.
+
+2004-07-27  John W. Eaton  <jwe at octave.org>
+
+	* bitfcns.cc (DO_BITSHIFT): Pass mask to bitshift.
+	(bitshift (double, int, EIGHT_BYTE_INT): New arg, mask.
+	(DO_UBITSHIFT, DO_SBITSHIFT): Use bitshfit, not operator >>.
+	Use nbits function from octave_int type to set bits_in_type.
+
+	* ov-struct.cc (Fisfield): Only print usage message if number of
+	arguments is incorrect.  Return false for invalid arguments.
+	From Andy Adler <adler at site.uottawa.ca>.
+
+2004-07-27  David Bateman  <dbateman at free.fr>
+
+	* Cell.cc (Cell::index): Quit early if an error occurs when
+	creating index vector object.
+
+	* ov-int8.cc, ov-int16.cc, ov-int32.cc, ov-int64.cc, ov-uint8.cc, 
+	ov-uint16.cc, ov-uint32.cc, ov-uint64.cc (HDF5_SAVE_TYPE): Define
+	for HDF5 native format for the type.
+
+	* ov-base-int.h (save_ascii, save_binary, load_binary, save_hdf5):
+	Delete unused arguments.
+
+	* ov-base-int.cc (octave_base_int_matrix::save_ascii,
+	octave_base_int_matrix::save_binary,
+	octave_base_int_scalar::save_ascii,
+	octave_base_int_scalar::save_binary,
+	octave_base_int_scalar::save_hdf5): Delete unused argument.
+
+	* ov-base-int.cc (octave_base_int_matrix::save_binary,
+	octave_base_int_matrix::load_binary,
+	octave_base_int_matrix::save_hdf5,
+	octave_base_int_matrix::load_hdf5,
+	octave_base_int_scalar::save_ascii,
+	octave_base_int_scalar::load_ascii,
+	octave_base_int_scalar::save_binary,
+	octave_base_int_scalar::load_binary,
+	octave_base_int_scalar::save_hdf5,
+	octave_base_int_scalar::load_hdf5): Implement missing functions.
+
+2004-07-23  David Bateman  <dbateman at free.fr>
+
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::array_value,
+	OCTAVE_VALUE_INT_SCALAR_T::array_value): new methods to extract array
+	value from integer types.
+
+	* bitfcns.cc (BITOPX): New Macro renamed from BITOP.
+	(BITOP): Alter to allow different types and call BITOP appropriately.
+	(DO_SBITSHIFT, DO_UBITSHIFT): New macros for signed, unsigned
+	bitshifts.
+
+	(DO_BITSHIFT): Test for shift of more bits than in type, which is
+	undefined.  Generalize to allow double args as well.
+	(Fbitshift): Add int and double types.
+	(Fbitmax): Return 53 bit value which conforms to IEEE754 double
+	mantissa.
+	(Fintmax, Fintmin): New functions.
+	(Fbitget, Fbitset, Fbitcmp): Delete.
+
+	* OPERATORS/op-int.h: Add sm_el_pow function
+
+	* ops.h (CATOPDECL, DEFCATOPX, DEFCATOP, DEFCATOP_FB, DEFNDCATOP_FN, 
+	CATOP_NONCONFORMANT, INSTALL_CATOP): New macros.
+	
+	* OPERATORS/op-b-b.cc, OPERATORS/op-b-bm.cc, OPERATORS/op-bm-b.cc, 
+	OPERATORS/op-bm-bm.cc, OPERATORS/op-cell.cc, OPERATORS/op-chm.cc, 
+	OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc, OPERATORS/op-cm-m.cc, 
+	OPERATORS/op-cm-s.cc, OPERATORS/op-cs-cm.cc, OPERATORS/op-cs-cs.cc, 
+	OPERATORS/op-cs-m.cc, OPERATORS/op-cs-s.cc, OPERATORS/op-m-cm.cc, 
+	OPERATORS/op-m-cs.cc, OPERATORS/op-m-m.cc, OPERATORS/op-m-s.cc, 
+	OPERATORS/op-range.cc, OPERATORS/op-s-cm.cc, OPERATORS/op-s-cs.cc, 
+	OPERATORS/op-s-m.cc, OPERATORS/op-s-s.cc, OPERATORS/op-str-str.cc,
+	OPERATORS/op-str-m.cc, OPERATORS/op-str-s.cc (CATOPDECL, DEFCATOPX,
+	DEFCATOP, DEFCATOP_FB, DEFNDCATOP_FN, CATOP_NONCONFORMANT,
+	INSTALL_CATOP): Use them to define concatenation functions.
+
+	* OPERATORS/op-int.h (OCTAVE_CONCAT_FN, OCTAVE_INSTALL_CONCAT_FN):
+	New macros to define and install concatentaion functions for int/uint
+	types.
+	
+	* TEMPLATE-INST/Array-tc.cc (INSTANTIATE_ARRAY_CAT): Delete.
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::do_init_element):
+	Also append empty elements to the list of elements to be parsed.
+	(tree_matrix::rvalue): Use new concatenation binary operators.
+
+	* data.cc (cat_add_dims): Delete (now dim_vector::concat).
+	(do_cat): Use new concatenation binary operators.
+
+	* ov-typeinfo.cc (cat_op_fcn): Instantiate the array of cat functions.
+	(register_cat_op, do_register_cat_op, do_lookup_cat_op): New functions.
+	(cat_ops): Lookup table of binary concatentaion operators.
+
+	* ov-typeinfo.h (lookup_cat_op): New function.
+
+	* ov.cc (gripe_cat_op, gripe_cat_op_conv, do_cat_op): New functions.
+
+	* ov.h (cat_op_fcn): Definition.
+	(resize, do_cat_op): New functions.
+
+	* ov-intx.h (resize): New_function
+
+	* version.h (OCTAVE_API_VERSION): Bump version to api-v9.
+
+	* Cell.cc, Cell.h, oct-map.cc, oct-map.h (cat): Delete.
+	(concat): New function.
+
+	* Cell.cc, Cell.h (insert): New function
+
+	* ov-base.cc, ov-base.h, ov-scalar.h, ov-complex.h, ov-bool.h, 
+	ov-range.h, ov-base-mat.h, (resize): New function.
+
+
+2004-07-23  John W. Eaton  <jwe at octave.org>
+
+	* symtab.cc (whos_parameter): Move decl here, from symtab.h.
+
+2004-07-23  Oyvind Kristiansen  <oyvinkri at stud.ntnu.no>
+
+	* symtab.cc (symbol_record::subsymbols_list): New method.
+	(symbol_record::maybe_list): Call to subsymbols_list and merge
+	result with the original list of symbols.
+
+	* symtab.cc (symbol_record::make_dimensions_string): New method.
+	(symbol_record::print_symbol_info_line): Print N-d info.  Output
+	for long format now under control of format string.
+	(symbol_table::maybe_list): Headers to whos listing updated.
+	Also print footer info.
+	(symbol_table::print_descriptor): Method printing the 
+	header of whos listings.
+	(symbol_table::parse_whos_line_format): New method.
+	(whos_line_format, Vwhos_line_format): New built-in variables.
+	(symbols_of_symtab): DEFVAR them.
+	(symbol_record::nelem, symbol_record::symbol_def::nelem,
+	symbol_record::byte_size, symbol_record::symbol_def::byte_size):
+	New methods.
+	(symbol_record::dimensions_string_req_first_space): New	method.
+	(symbol_record::dimensions_string_req_total_space): New	method.
+	* symtab.h (whos_parameter): New struct.  Container for one
+	parameter in whos_line_format.
+
+2004-07-22  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* DLD-FUNCTIONS/dassl.cc (Fdassl): Fix doc string.
+	* ov-struct.cc (Fstruct): Likewise.
+	* symtab.cc (Fdebug_symtab_lookups): Likewise.
+
+2004-07-22  David Bateman  <dbateman at free.fr>
+
+	* data.cc (Fsize): Return 1 for dimensions exceeding ndim.
+
+	* ov.cc (octave_value::octave_value (const ArrayN<double>)):
+	New constructor.
+	* ov.h: Provide decl.
+	* ov-cx-mat.h (octave_complex_matrix (const ArrayN<Complex>&)):
+	New constructor.
+	* ov-re-mat.h (octave_complex_matrix (const ArrayN<double>&)):
+	New constructor.
+
+	* ov-re-mat.h (octave_matrix(const ArrayN<double>&)): New constructor
+	* pt-loop.cc (DO_ND_LOOP): New macro for use of NDArray in for loop.
+	(tree_simple_for_command::eval): Use it, and allow iteration over
+	cell arrays.
+
+2004-07-12  John W. Eaton  <jwe at octave.org>
+
+	* ov-intx.h: N-d array and scalar extractor functions take no args.
+
+	* ov.h (octave_value::int8_scalar_value,
+	octave_value::int16_scalar_value, octave_value::int32_scalar_value,
+	octave_value::int64_scalar_value, octave_value::uint8_scalar_value,
+	octave_value::uint16_scalar_value, octave_value::uint32_scalar_value,
+	octave_value::uint64_scalar_value): New functions.
+	* ov-base.cc (octave_base_value::int8_scalar_value,
+	octave_base_value::int16_scalar_value,
+	octave_base_value::int32_scalar_value,
+	octave_base_value::int64_scalar_value,
+	octave_base_value::uint8_scalar_value,
+	octave_base_value::uint16_scalar_value,
+	octave_base_value::uint32_scalar_value,
+	octave_base_value::uint64_scalar_value): New functions.
+	* ov-base.h: Provide decls.
+
+	* lex.l: (Vtoken_count): New static variable.
+	(COUNT_TOK_AND_RETURN): New macro.  Use it everywhere a token is
+	returned to the parser.
+	(F__token_count__): New function.
+
+2004-06-25  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-int-conv.cc: Add conversions for range type.
+
+2004-06-17  John W. Eaton  <jwe at octave.org>
+
+	* bitfcns.cc (bitfcns): New file.
+	* Makefile.in (DIST_SRC): Add it to the list.
+
+2004-06-16  John W. Eaton  <jwe at octave.org>
+
+	* OPERATORS/op-int.h: New file.
+	* OPERATORS/op-i16-i16.cc, OPERATORS/op-i8-i8.cc,
+	OPERATORS/op-ui32-ui32.cc, OPERATORS/op-i32-i32.cc,
+	OPERATORS/op-int-conv.cc, OPERATORS/op-ui64-ui64.cc,
+	OPERATORS/op-i64-i64.cc, OPERATORS/op-ui16-ui16.cc,
+	OPERATORS/op-ui8-ui8.cc: Use new macros from op-int.h.
+
+2004-06-14  John W. Eaton  <jwe at octave.org>
+
+	* pr-output.h, pr-output.cc (octave_print_conv): New traits class.
+	(template <class T> void octave_print_internal (std::ostream&,
+	const intNDArray<T>&, bool, int),
+	(template <class T> void octave_print_internal (std::ostream&,
+	const octave_int<T>&, bool)): New template functions.
+	Instantiate versions for new int types.
+
+	* ov-typeinfo.h (octave_value_typeinfo::type_conv_ops):
+	New data member.
+	(octave_value_typeinfo::register_type_conv_op,
+	octave_value_typeinfo::lookup_type_conv_op,
+	octave_value_typeinfo::do_register_type_conv_op,
+	octave_value_typeinfo::do_lookup_type_conv_op): New functions.
+
+	* ov-re-mat.cc (Fdouble): New function.
+
+	* ov-range.h (octave_range::reshape): Reshape array_value, not
+	matrix_value.
+
+	* ov-base-scalar.h (octave_base_scalar<ST>::all,
+	octave_base_scalar<ST>::any, octave_base_scalar<ST>::is_true): Use
+	ST() instead of 0.0.
+
+	* ov-base-mat.h (octave_base_matrix<MT>::byte_size): New function.
+	
+	* ops.h (INSTALL_COLNVOP, DEFCONVFNX, DEFDBLCONVFN, DEFCONVFN,
+	DEFCONVFN2): New macros.
+
+	* DLD-FUNCTIONS/filter.cc (Ffilter): Kluge type conversions.
+
+	* ov.cc (install_types): Register new integer types.
+
+	* ov.h, ov.cc (octave_value::octave_value (const octave_int8&),
+	octave_value::octave_value (const octave_uint8&),
+	octave_value::octave_value (const octave_int16&),
+	octave_value::octave_value (const octave_uint16&),
+	octave_value::octave_value (const octave_int32&),
+	octave_value::octave_value (const octave_uint32&),
+	octave_value::octave_value (const octave_int64&),
+	octave_value::octave_value (const octave_uint64&),
+	octave_value::octave_value (const int8NDArray&),
+	octave_value::octave_value (const uint8NDArray&),
+	octave_value::octave_value (const int16NDArray&),
+	octave_value::octave_value (const uint16NDArray&),
+	octave_value::octave_value (const int32NDArray&),
+	octave_value::octave_value (const uint32NDArray&),
+	octave_value::octave_value (const int64NDArray&),
+	octave_value::octave_value (const uint64NDArray&)):
+	New constructors.
+
+	* ov.h (octave_value::internal_rep): New function.
+	(DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Also define
+	static_type_id, static_type_name, and static_class_name
+	functions.
+
+	* Cell.h (Cell::reshape (const dim_vector&)): New forwarding
+	function for return type conversion.
+
+	* ov-int16.cc, ov-int16.h, ov-int32.cc, ov-int32.h, ov-int64.cc,
+	ov-int64.h, ov-int8.cc, ov-int8.h, ov-uint16.cc, ov-uint16.h,
+	ov-uint32.cc, ov-uint32.h, ov-uint64.cc, ov-uint64.h, ov-uint8.cc,
+	ov-uint8.h, ov-type-conv.h, ov-int-traits.h,
+	OPERATORS/op-int-conv.cc, OPERATORS/op-double-conv.cc,
+	OPERATORS/op-i16-i16.cc, OPERATORS/op-i32-i32.cc,
+	OPERATORS/op-i64-i64.cc, OPERATORS/op-i8-i8.cc,
+	OPERATORS/op-ui16-ui16.cc, OPERATORS/op-ui32-ui32.cc,
+	OPERATORS/op-ui64-ui64.cc, OPERATORS/op-ui8-ui8.cc: New files.
+	Makefile.in: Add them to the appropriate lists.
+
+2004-06-03  John W. Eaton  <jwe at octave.org>
+
+	* ov-fcn-handle.h (octave_function_handle::is_matrix_type,
+	octave_function_handle::is_numeric_type,
+	octave_function_handle::is_constant,
+	octave_function_handle::is_true): New functions.
+	(octave_function_handle::is_defined): Delete (inherited version is
+	OK).
+
+2004-06-03  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/filter.cc: Fix for length(a)=1 && length(b)=2 case.
+
+2004-05-07  John W. Eaton  <jwe at octave.org>
+
+	* ov.cc (octave_value::print_with_name): Only print name tag if
+	Vprint_answer_id_name is true.
+
+	* octave.cc (intern_argv): Insert __nargin__ in top_level_sym_tab
+	instead of making it a builtin variable.  Mark it static.
+	* ov-usr-fcn.cc (octave_user_function::install_automatic_vars):
+	Mark local automatic variables static.
+
+2004-04-30  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (octave_base_stream::clearerr): New function.
+	(octave_stream::clearerr): New function.
+	(seek (long, int)): Call clearerr here.
+	* oct-stdstrm.h (octave_stdiostream::clear): New function.
+	* c-file-ptr-stream.h (c_file_ptr_buf::clear,
+	i_c_file_ptr_stream::clear, o_c_file_ptr_stream::clear,
+	io_c_file_ptr_stream::clear): New functions.
+
+2004-04-29  David Bateman  <dbateman at free.fr>
+
+	* load-save.cc (Fload, Fsave): Accept -mat as well as -mat-binary.
+
+2004-04-27  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/sort.cc: Add missing "class" keywords to template
+	instantiations.
+
+2004-04-22  John W. Eaton  <jwe at octave.org>
+
+	* pt-plot.cc (Fclearplot): Temporarily turn off automatic_replot.
+	Clear display after resetting title, labels, etc.
+
+2004-04-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-colon.cc (tree_colon_expression::rvalue): Also check for
+	error_state after evaluating each subexpression.
+
+2004-04-22  David Bateman  <dbateman at free.fr>
+
+	* ov-base-scalar.h (octave_base_scalar<ST>::permute): New function.
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::is_true): Make N-d aware.
+
+2004-04-22  John W. Eaton  <jwe at octave.org>
+
+	* oct-stream.cc (printf_value_cache::curr_value): Now NDArray.
+	(printf_value_cache::double_value): Extract N-d array, not Matrix.
+
+2004-04-21  John W. Eaton  <jwe at octave.org>
+
+	* parse.y (function2): Pass id name to frob_function.  Delete id.
+	(frob_function): Accept function name instead of identifier.
+	Don't try to rename symbol table entry.  Lookup symbol record for
+	function name here.  Insert name in symbol table if needed.
+	Operate on symbol record instead of identifier.
+
+2004-04-21  David Bateman  <dbateman at free.fr>
+
+	* DLD_FUNCTIONS/fft.cc(do_fft): Correctly initialize the variable dim
+	for scalar arguments.
+
+	* DLD-FUNCTIONS/minmax.cc: Handle single vector arg correctly.
+
+2004-04-20  John W. Eaton  <jwe at octave.org>
+
+	* ls-mat-ascii.cc (read_mat_ascii_data): Prepend "X" to keywords.
+	Only drop text after last "." in name.
+
+	* lex.l (is_keyword): New function.
+	(Fiskeyword): Use it.
+	* lex.h: Provide decl.
+
+	* lex.l (is_keyword_token): Rename from is_keyword.
+
+2004-04-16  John W. Eaton  <jwe at octave.org>
+
+	* file-io.cc (maybe_warn_interface_change): New function.
+	(fopen_mode_to_ios_mode): Use it.
+
+2004-04-16  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* file-io.cc (fopen_mode_to_ios_mode):  Default to binary mode.
+	(Ffopen): Document 't' and 'b' mode flags.
+
+2004-04-16  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (DLD_XSRC): Add gcd.cc to the list.
+
+2004-04-16  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/gcd.cc: New file.
+
+2004-04-15  David Bateman  <dbateman at free.fr>
+
+	* ov-ch-mat.h: convert_to_str_interal returns charNDArray.
+
+2004-04-12  John W. Eaton  <jwe at octave.org>
+
+	* version.h (OCTAVE_BUGS_STATEMENT): Bug list is now bug at octave.org.
+
+2004-04-08  John W. Eaton  <jwe at octave.org>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::do_index_op): Quit early
+	if an error occurs when creating index vector object.
+
+	* ov.cc (octave_value::numeric_assign): Always call maybe_mutate
+	on return value.
+
+2004-04-06  David Bateman  <dbateman at free.fr>
+
+  	* DLD_FUNCTIONS/sort.cc: Use the new template sort class, adapt for
+	N-d arrays, and allow optional dim argument.
+
+	* DLD_FUNCTIONS/fftn.cc: Save result of transpose operation.
+	Check for failure of transpose.
+
+2004-04-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool.h (octave_bool::bool_array_value): New function.
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::subsasgn): Don't allow
+	expressions like x(i)(j) or x(i){j} when x is empty.
+
+	* load-save.cc (get_file_format): Error if file does not exist.
+	(Fload): Also complain here if specific file type is specified and
+	file does not exist.
+
+2004-04-02  Quentin Spencer  <qspencer at ieee.org>
+
+	* parse.y: Use persistent instead of static in warnings messages.
+
+2004-04-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-decl.cc (tree_static_command::do_init): Initialize to empty
+	matrix by default.
+
+2004-04-02  David Bateman  <dbateman at free.fr>
+
+	* ov-re-mat.cc (octave_matrix::convert_to_str_internal):
+	Return charNDArray.
+	* ov-bool-mat.cc (octave_bool_matrix::convert_to_str_internal):
+	Call array_value.
+	
+	* DLD-FUNCTIONS/besselj.cc, DLD-FUNCTIONS/betainc.cc,
+	DLD-FUNCTIONS/gammainc.cc, DLD-FUNCTIONS/minmax.cc,
+	DLD-FUNCTIONS/filter.cc:
+	Convert for N-d array, better Matlab compatibility.
+
+	* load-save.cc (Fload): Better handling of non existent files.
+	
+2004-03-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-list.cc (octave_list::subsref): Correctly create return value.
+	Return comma-separate list if {-style indexing extracts more than
+	one value.
+
+2004-03-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.57.
+	(OCTAVE_API_VERSION): Now api-v8.
+
+	* ov-cell.cc (octave_cell::save_hdf5): Handle empty cells.
+	(octave_cell::load_hdf5): Likewise.
+
+2004-03-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::subsasgn): If empty,
+	allow type conversion when indexing with "{" and ".".
+
+2004-03-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (init_format_state): Also set compact_format.
+	(pr_col_num_header): Print one newline character before column
+	headers for compact format.
+
+2004-03-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_WWW_STATEMENT): New macro.
+	(OCTAVE_STARTUP_MESSAGE): Include it here.
+	(OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS): And here.
+
+	* octave.cc (verbose_usage): Use OCTAVE_WWW_STATEMENT here.
+
+	* DLD-FUNCTIONS/find.cc (find_nonzero_elem_idx): If there are no
+	nonzero elements, return [](0x1) or [](1x0), not [](0x0).
+	Correctly preserve orientation for row vectors.
+
+2004-03-08  Petter Risholm  <risholm at idi.ntnu.no>
+
+	* data.cc (do_cat): Check for length of args before getting dimension.
+	New arg, fname.  Print usage message corresponding to fname.
+	(Fcat): Pass "cat" as fname arg to do_cat.
+	(Fhorzcat): Pass "horzcat" as fname arg to do_cat.
+	(Fvertcat): Pass "vertcat" as fname arg to do_cat.
+
+2004-03-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.56.
+	(OCTAVE_API_VERSION): Now api-v7.
+
+2004-03-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-struct.cc (Frmfield): New function
+
+	* oct-map.h (Octave_map::contains): Return bool, not int.
+
+	* ov-cell.cc (Fiscellstr): No error if arg is not a cell array.
+	(Fcellstr): Return arg if it is already a cell array of character
+	strings.
+
+2004-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool.cc (octave_bool::load_hdf5, octave_bool::save_hdf5):
+	Avoid unnecessary casts.
+	* ov-bool-mat.cc (octave_bool_matrix::load_hdf5,
+	octave_bool_matrix::save_hdf5): Likewise.
+	* ov-cell.cc (octave_cell::load_hdf5, octave_cell::save_hdf5):
+	Likewise.
+	* ov-complex.cc (octave_complex::load_hdf5,
+	octave_complex::save_hdf5): Likewise.
+	* ov-cx-mat.cc (octave_complex_matrix::load_hdf5,
+	octave_complex_matrix::save_hdf5): Likewise.
+	* ov-range.cc (octave_range::load_hdf5, octave_range::save_hdf5):
+	Likewise.
+	* ov-re-mat.cc (octave_matrix::load_hdf5, octave_matrix::save_hdf5):
+	Likewise.
+	* ov-scalar.cc (octave_scalar::load_hdf5, octave_scalar::save_hdf5):
+	Likewise.
+	* ov-str-mat.cc (octave_char_matrix_str::load_hdf5,
+	octave_char_matrix_str::save_hdf5): Likewise.
+
+2004-03-03 David Bateman  <dbateman at free.fr>
+
+	* ov-cell.cc (octave_cell::save_hdf5, octave_cell::load_hdf5):
+	Make N-d aware.
+
+2004-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y: Delete spaces surrounding = in %name-prefix directive.
+
+2004-03-01  Petter Risholm  <risholm at idi.ntnu.no>
+
+        * Cell.cc (Cell::cat): New function.
+        * Cell.h: Provide decl.
+
+        * oct-map.cc (Octave_map::cat): New function.
+        * oct-map.h: Provide decl.
+
+        * data.cc (Fcat): Speedup implementation.
+
+        * data.cc (Fhorzcat, Fvertcat): New functions.
+
+        * Array-tc.cc: Instantiate cat function.
+
+2004-03-01  David Bateman  <dbateman at free.fr>
+
+	* ls-hdf5.cc (save_hdf5_empty, load_hdf5_empty): New functions
+	to save/load empty matrices keeping their dimensions.
+	* ls-hdf5.h (save_hdf5_empty, load_hdf5_empty): Provide decls.
+
+	* ov-re-mat.cc (save_hdf5, load_hdf5): Cleanup, check empty matrix.
+	* ov-cx-mat.cc (save_hdf5, load_hdf5): Ditto.
+	* ov-bool-mat.cc (save_hdf5, load_hdf5): Ditto.
+
+	* ov-str-mat.cc (save_ascoo, load_ascii, save_binary,
+	load_binary, save_hdf5, load_hdf5): Cleanup, check empty matrix,
+	and save/load N-d arrays.
+ 
+2004-02-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (execute_startup_files): Don't find current directory
+	for absolute name of local_rc until after executing home_rc.
+
+2004-02-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (input_event_hook): Return type is now int.  Return 0.
+
+	* file-io.cc (do_stream_open): Don't call ::error if stream can't
+	be created.  Don't call ::fopen if arch is invalid.  Set error
+	state for stream if fopen fails.
+	* oct-stream.h (octave_stream::error (const char *)): New function.
+	(octave_stream::error (const std::string&)): Now public.
+
+2004-02-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Fftell): Return long integer instead of streamoff_array.
+	(do_stream_open): Create octave_stdiostream instead of octave_fstream.
+
+	* oct-fstrm.cc (octave_fstream::seek, octave_fstream::tell):
+	Always fail.  Signatures now match C library functionsb.
+	* oct-iostrm.cc (octave_base_iostream::seek,
+	octave_base_iostream::tell): Likewise.
+	* oct-strstrm.cc (octave_base_strstream::seek,
+	octave_base_strstream::tell): Likewise.
+
+	* oct-stream.cc (octave_stream::seek, octave_stream::tell):
+	Signatures now match C-library functions.
+
+	* oct-stdstrm.cc (octave_stdiostream::seek, octave_stdiostream::tell):
+	Call io_c_file_ptr_stream::seek and tell.  Signatures now match
+	C-library functions.
+
+	* c-file-ptr-stream.h (c_file_ptr_buf::seek, c_file_ptr_buf::tell): 
+	New functions.
+	(i_c_file_ptr_stream::seek, i_c_file_ptr_stream::tell): Likewise.
+	(o_c_file_ptr_stream::seek, o_c_file_ptr_stream::tell): Likewise.
+	(io_c_file_ptr_stream::seek, io_c_file_ptr_stream::tell): Likewise.
+
+2004-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.55.
+	(OCTAVE_API_VERSION): Now api-v6.
+
+	* sighandlers.cc (sigfpe_handler, sigpipe_handler):
+	Don't increment	octave_interrupt_state if it is less than 0.
+	(sigint_handler): If octave_interrupt_state is less than zero,
+	reset it.
+
+	* pt-except.cc (do_catch_code): Call OCTAVE_QUIT here so the catch
+	code won't run if an interrupt is pending.  Don't run catch code
+	if octave_interrupt_state is less than zero.
+
+2004-02-20  Per Persson  <persquare at mac.com>
+
+	* Makefile.in (OCT_LINK_DEPS, OCTINTERP_LINK_DEPS):
+	Include	$(LIBS) in the list before $(FLIBS).
+
+2004-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (octave_print_internal (std::ostream&, const
+	Range&, bool, int)): Don't print values beyond the limits of the
+	range.
+
+	* sighandlers.cc (sigint_handler): Print message after two
+	consecutive interrupts, dump core after three or more.
+
+	* load-save.cc (dump_octave_core): Handle core size limit.
+	Rename from save_user_variables.  Change all callers.
+	(Fload, dump_octave_core, Fsave): Open HDF5 fils in binary mode.
+	(do_save): Extract switch over file types to separate function.
+
+	* load-save.cc (Voctave_core_file_limit): New variable.
+	(octave_core_file_limit): New function.
+	(symbols_of_load_save): Add DEFVAR for octave_core_file_limit.
+
+	* load-save.cc (Voctave_core_file_name): New variable.
+	(octave_core_file_name): New function.
+	(symbols_of_load_save): Add DEFVAR for octave_core_file_name.
+
+	* load-save.cc (Voctave_core_file_format):
+	Rename from Voctave_core_format.
+	(octave_core_file_format): Rename from octave_core_format.
+	(symbols_of_load_save): Fix DEFVAR to match.
+
+2004-02-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.cc (Fsizeof): New function.
+
+	* ov.h (octave_value::byte_size): New function.
+	* ov-base.h (octave_base_value::byte_size): New function.
+	* ov-base-scalar.h (octave_base_scalar::byte_size): New function.
+	* ov-bool-mat.h (octave_bool_matrix::byte_size): New function.
+	* ov-ch-mat.h (octave_char_matrix::byte_size): New function.
+	* ov-cx-mat.h (octave_complex_matrix::byte_size): New function.
+	* ov-re-mat.h (octave_matrix::byte_size): New function.
+	* ov-range.h (octave_range::byte_size): New function.
+	* ov-cell.cc (octave_cell::byte_size): New function.
+	* ov-cell.h: Provide decl.
+	* ov-struct.cc (octave_struct::byte_size): New function.
+	* ov-struct.h: Provide decl.
+	* ov-streamoff.h (octave_streamoff::byte_size): New function.
+	* ov-list.cc (octave_list::byte_size): New function.
+	* ov-list.h: Provide decl.
+
+	* xpow.cc (elem_xpow (const Matrix&, double)):
+	Convert both operands to Complex if any element of A is negative.
+	(elem_xpow (const NDArray&, double)): Likewise.
+
+2004-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (Voctave_core_format): New static_variable.
+	(octave_core_format): New function.
+	(symbols_of_load_save): Add DEFVAR for octave_core_format.
+	(get_save_format): Rename from get_default_save_format.
+	Pass name of format as arg.  New optional arg, fallback_format.
+	Change all uses.
+	(save_user_variables): Use pass Voctave_core_format to
+	get_save_format here.  Pass LS_BINARY as fallback_format.
+
+	* sighandlers.cc (my_friendly_exit): New optional arg, save_vars.
+	Only call save_user_variables if save_vars is true.
+	(sigint_handler): If interactive, offer to abort and save
+	workspace after three consecutive interrupts.
+	(sigint_handler, sigpipe_handler, sigfpe_handler):
+	Increment octave_interrupt_handler instead of setting it to 1.
+
+2004-02-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.54.
+	(OCTAVE_API_VERSION): Now api-v5.
+
+	* Makefile.in (DLD_XSRC): Always include fftw_wisdom.cc.
+
+	* DLD-FUNCTIONS/fftw_wisdom.cc:
+	Rename from DLD-FUNCTIONS/fft_wisdom.cc.
+	(Vfftw_wisdom_prog): Delete extern decl.
+	(Ffftw_wisdom): Rename from Ffft_wisdom.
+	Use Vfftw_wisdom_prog instead of Vwisdom_prog.
+	Always define function.  Signal error if not configured to use FFTW3.
+
+	* defaults.cc (symbols_of_defaults): Rename WISDOM_PROGRAM to be
+	FFTW_WISDOM_PROGRAM.
+	(Vfftw_wisdom_prog): Rename from Vwisdom_prog.
+	(fftw_wisdom_program): Rename from wisdom_program.
+	For simplicity, always define FFTW_WISDOM_PROGRAM even when not
+	using fftw3.
+	(set_default_wisdom_prog): Look for OCTAVE_FFTW_WISDOM_PROGRAM in
+	the environment instead of OCTAVE_WISDOM_PROGRAM.
+	(set_default_fftw_wisdom_prog): Rename from set_default_wisdom_prog.
+	* defaults.h.in (Vfftw_wisdom_prog): Provide extern decl.
+
+2004-02-16 David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/fft.cc: Adapt for Nd arrays, combine with ifft.cc.
+	* DLD-FUNCTIONS/ifft.cc: Delete.
+	* DLD-FUNCTIONS/fft2.cc: Adapt for Nd arrays, combine with ifft.cc.
+	* DLD-FUNCTIONS/ifft2.cc: Delete.
+	* DLD-FUNCTIONS/fftn.cc: New function for Nd FFT and inverse FFT.
+	* DLD-FUNCTIONS/fft_wisdom.cc: New function to manipulate FFTW 
+	wisdom.
+
+	* Makefile.in: Remove ifft.cc and ifft2.cc.  Add fftn.cc and 
+	ifftn.cc.  Make building of fft-wisdom.cc conditional on the 
+	value of FFTW_LIBS.
+	* defaults.cc (Vwisdom_prog): New variable
+	(set_default_wisdom_prog, wisdom_prog): New functions.
+	(symbols_of_defaults): Add DEFVAR for wisdom_prog.
+	
+2004-02-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-list.cc (octave_list::subsasgn): Call assign for Cell objects
+	here, not the base octave_value::assign.
+
+2004-02-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (yywrap): Don't #undef this symbol.
+
+2004-02-15  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* pt-mat.cc: Make [,] concatenation work for N-d arrays.
+
+2004-02-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (do_cat): Merge with Fcat.
+
+2004-02-15  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ov-cell.cc (Fstruct2cell): New function.
+
+2004-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCTINTERP_LINK_DEPS, OCT_LINK_DEPS): Always define.
+
+	* oct-conf.h.in: Add OCTAVE_CONF_DL_LD, OCTAVE_CONF_DL_LDFLAGS,
+	and OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS.
+	Delete OCTAVE_CONF_MKOCTFILE_SH_LDFLAGS.
+
+	* toplev.cc (octave_config_info): Delete MKOCTFILE_SH_LDFLAGS.
+	Add DL_LD, DL_LDFLAGS, and MKOCTFILE_DL_LDFLAGS to the struct.
+
+2004-02-14  Per Persson  <persquare at mac.com>
+
+	* Makefile.in (%.oct): Use DL_LD instead of SH_LD to build .oct files.
+
+2004-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base-scalar.h (octave_base_scalar::squeeze): New function.
+
+2004-02-13  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* data.cc (Fcat): New function.
+	* data.cc (do_cat): New function.
+	* data.cc (cat_add_dims): New function.
+
+2004-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (main_loop): Call octave_parse, not yyparse.
+	* octave.cc (octave_main): Increment octave_debug, not yydebug.
+	* parse.y (%name-prefix): New directive, set to "octave_".
+	* parse.h: Provide declarations for octave_lex and octave_parse
+	instead of yylex and yyparse.
+	* lex.l (%option prefix): New directive, set to "_octave".
+	Define yylval to be octave_lval.
+	Move definitions of YY_INPUT, YY_FATAL_ERROR, TOK_RETURN,
+	TOK_PUSH_AND_RETURN, BIN_OP_RETURN, XBIN_OP_RETURN here.
+	* lex.h: From here.
+
+2004-02-07  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ov-struct.cc (Fcell2struct): New function.
+	(cell2struct_check_args, cell2struct_construct_idx): Likewise.
+
+2004-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-scalar.h (octave_scalar::empty_clone):
+	Return empty octave_matrix, not an octave_scalar object.
+	* ov-complex.h (octave_complex::empty_clone):
+	Return empty octave_complex_matrix, not an octave_complex object.
+
+2004-02-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.h (octave_user_function::function_name): Delete.
+	(octave_user_function::fcn_name): Delete unused data member.
+	(octave_user_function::stash_function_name): Save name in
+	tree_function::my_name instead of fcn_name.
+	Change all uses of fcn_name to be my_name instead.
+
+	* pt.h, pt.cc (tree::break_function): Now pointer to
+	octave_function rather than octave_user_function object.
+
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Use name instead of function_name
+	to get name from curr_function.
+	* pt-pr-code.cc (tree_print_code::visit_octave_user_function_header):
+	likewise.
+	* debug.cc (Fdbwhere, Fdbtype, ): Likewise
+	* error.cc (pr_where): Likewise.
+	* variables.cc (Fmlock, Fmunlock, Fmislocked): Likewise.
+	(lookup_function, lookup_user_function,	link_to_builtin_or_function):
+	Likewise, for curr_parent_function.
+
+	* debug.cc (get_user_function, Fdbwhere):
+	Cast curr_function to pointer to octave_user_function.
+
+	* ov-mapper.cc (octave_mapper::do_multi_index_op):
+	Save and restore curr_function here.
+	* ov-builtin.cc (octave_builtin::do_multi_index_op): Likewise.
+
+	* toplev.h, toplev.cc (curr_function, curr_parent_function): Now
+	pointers to octave_function rather than octave_user_function objects.
+
+	* ov-usr-fcn.h (octave_user_function::is_user_function): New function.
+	* ov-fcn.h (octave_function::takes_varargs,
+	octave_function::octave_va_start, octave_function::octave_va_arg,
+	octave_function::octave_all_va_args,
+	octave_function::takes_var_return, octave_function::octave_vr_val, 
+	octave_function::is_user_function): New virtual functions.
+
+2004-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-struct.cc (Fstruct): Use new Octave_map constructor to create
+	structures with specified sizes but no keys.
+
+	* ov-struct.cc (Fstruct): New function, from Paul Kienzle
+	<pkienzle at users.sf.net> and Petter Risholm  <risholm at stud.ntnu.no>.
+
+	* oct-map.h (Octave_map::Octave_map): Allow dimension to be
+	specified for map with no keys.
+
+	* ov-struct.cc (fieldnames): Return 0x1 cell array if no fieldnames.
+
+2004-02-05  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::do_index_op):
+	Don't fail if number of indices is greater than 2.
+
+2004-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fsize): Update for N-d objects.
+
+	* ls-mat5.cc (read_mat5_binary_element): Force conversion.
+
+	* ov-base.cc (octave_base_value::char_matrix_value):
+	Pass force arg to convert_to_str.
+
+	* data.cc (Freshape): Chop trailing singletons from new dimensions.
+
+2004-02-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc (defun_usage_message): Only accept one arg, a const
+	std::string& object.  Change all uses.  Pass nul-terminated string
+	to defun_message_1.
+	(defun_usage_message_1): New function, equivalent to old
+	defun_usage_message.
+
+	* ov-base.cc (nint_value): Use fix, not NINT.
+	(INT_CONV_METHOD): Likewise, use fix instead of just casting.
+
+	* data.cc (make_diag): Use int_value instead of nint_value to
+	extract k for Matlab compatibility.
+	(Flinspace): Likewise, for npoints.
+	(fill_matrix): Likewise, for extracting dims.
+	(Fsize): Likewise, for extracting dim argument.  Require int value.
+	* utils.cc (get_dimensions): Likewise.  Use fix, not NINT.
+
+2004-02-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc (verror, error_1): New arg, os.  Use this instead
+	of always printing to std:cerr.  Change all callers.
+
+	* error.cc (defun_usage_message): New function.
+	* error.h: Provide decl.
+	* defun.cc (print_usage): Use it to display error message.
+
+	* error.cc (verror): New arg, save_last_error.  Change all callers.
+	(usage): Set error_state after calling verror.
+
+	* oct-map.cc (Octave_map::assign (const std::string, const Cell&)):
+	Set dimensions to RHS dimensions, not 1x1.
+
+2004-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool.cc, ov-cx-mat.cc, ov-re-mat.cc, ov-str-mat.cc:
+	Include <vector>.
+	* file-io.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, ls-oct-binary.cc:
+	Include <vector>, not <memory> for new defn of OCTAVE_LOCAL_BUFFER.
+	* load-save.cc, ls-mat-ascii.cc, ls-oct-ascii.cc
+	No need to include <memory> now.
+
+	* DLD-FUNCTIONS/eig.cc (Feig): Use new optional arg for EIG to
+	avoid computing eigenvectors if not requested.
+	Based on a patch from David Bateman  <dbateman at free.fr>.
+
+2004-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.cc (all_strings): Always compute total required length
+	of retval.
+
+2004-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.53.
+	(OCTAVE_API_VERSION): Now api-v4.
+
+	* error.cc (pr_where): New arg, print_code with default value true.
+	(warning): Call pr_where with second arg false.
+
+	* file-io.cc (Ffrewind): Only return value if nargout > 0.
+	(Ffprintf): Likewise.
+	(Fprintf): Likewise.
+
+	* file-io.cc (Ffrewind): Return 0 for success, -1 for failure.
+	Make docs match.
+
+	* Makefile.in (distclean): Remove DOCSTRINGS.
+	(maintainer-clean): Remove $(OPT_HANDLERS).
+
+2004-01-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.cc (octave_cell::subsref): Make '{' case N-d aware.
+
+	* ov-scalar.cc (streamoff_array_value): New function.
+	* ov-scalar.h: Provide decl.
+
+	* OPERATORS/op-streamoff.cc (STREAMOFF_COMP_OP): New maco.
+	Use it to define streamoff by matrix, streamoff by scalar, scalar
+	by streamoff, and matrix by streamoff comparison operators.
+	(install_streamoff_ops): Install them.
+
+	* Cell.h (Cell::operator ()): Delete (we inherit them from Array<T>).
+	(maybe_resize, elem_internal): Delete unused functions.
+
+	* ls-mat5.cc (write_mat5_cell_array): Cell& arg is now const.
+
+2004-01-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (is_valid_function): If warn, also print error
+	message if arg is not a string.
+
+	* ov-usr-fcn.cc (Fnargin, Fnargout): New functions.
+
+	* octave.cc (intern_argv): Lookup __nargin__ instead of nargin.
+	* ov-usr-fcn.cc (octave_user_function::install_automatic_vars):
+	Lookup __nargin__ and __nargout__ instead of nargin and nargout.
+
+	* variables.h (at_top_level): Now extern.
+	(lookup_user_function): New function.
+	* variables.cc: Provide decls.
+
+	* ov.h, ov.cc (octave_value::user_function_value):
+	New virtual function.
+	* ov-base.h, ov-base.cc (octave_base_value::user_function_value):
+	Provide default version.
+	* ov-usr-fcn.h (octave_user_function::user_function_value):
+	New function.
+
+	* ov-re-mat.cc (complex_array_value): New function.
+	* ov-re-mat.h: Provide decl.
+
+	* ov-cell.cc (Fiscellstr): Don't return value on usage error.
+
+	* error.cc: (symbols_of_error): Delete DEFVAR for error_text.
+	Define __error_text__ and error_text as aliases for lasterr.
+
+	* error.cc (bind_global_error_variable,	clear_global_error_variable):
+	Delete.
+	* variables.h: Delete decls.
+
+	* parse.y (Feval, Fevalin): Don't call bind_global_error_variable.
+	Don't add clear_global_error_variable to the unwind_protect stack.
+	Increment buffer_error_messages before evaluating "eval" code,
+	decrement it before evaluating "catch" code.	
+
+	* pt-except.cc (do_catch_code): Don't call bind_global_error_variable.
+	Don't add clear_global_error_variable to the unwind_protect stack.
+	Decrement buffer_error_messages here.
+	(tree_try_catch_command::eval): Increment buffer_error_messages here.
+
+	* error.cc, error.h (buffer_error_messages): Now an int.
+
+2004-01-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (octave_config_info): Add float_format,
+	words_big_endian, and words_little_endian to the struct.
+
+2004-01-14  David Bateman  <dbateman at free.fr>
+	
+	* ov-cell.cc (octave_cell::load_hdf5): Fix for HDF5 version 1.6
+	handling of number of objects in a group.
+	* ov-struct.cc (octave_struct::load_hdf5): Likewise.
+	* ov-list.cc (octave_list::load_hdf5): Likewise.
+	* ls-hdf5.cc (read_hdf5_data): Likewise.
+
+2004-01-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ls-hdf5.h: Surround contents with #if defined (HAVE_HDF5).
+
+2004-01-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (convert_to_valid_int, get_size):
+	Use lo_ieee_is_NaN_or_NA instead of xisnan.
+	(octave_base_stream::do_printf): Correct special case check for
+	NA, NaN, Inf, or out of range integers.
+
+	* dirfns.cc (Fglob): Always return list of files as a cell array.
+	(Freaddir): Likewise.
+
+	* dirfns.cc (Fls): If nargout > 0, return ls output.
+
+2004-01-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (Fload): Assume -force by default.
+
+	* oct-stream.cc (octave_base_stream::write):
+	Allow fwrite (fid, "some string") to work.
+
+	* toplev.cc (Fcomputer): Delete.
+	(octave_config_info): Add unix and windows fields to the struct.
+
+2004-01-06  David Bateman  <dbateman at free.fr>
+
+	* ls-hdf5.cc: Fix handle of old versus new format files.
+
+ 	* ls-oct-binary.cc: Split the load/save functionality into the types
+ 	themselves.  Backward compatibility maintained.
+	
+ 	* ov-struct.cc (save_binary, load_binary):
+ 	* ov-str-mat.cc (save_binary, load_binary):
+ 	* ov-scalar.cc (save_binary, load_binary):
+ 	* ov-re-mat.cc (save_binary, load_binary):
+ 	* ov-range.cc (save_binary, load_binary):
+ 	* ov-list.cc (save_binary, load_binary):
+ 	* ov-cx-mat.cc (save_binary, load_binary):
+ 	* ov-complex.cc (save_binary, load_binary):
+ 	* ov-cell.cc (save_binary, load_binary):
+ 	* ov-bool.cc (save_binary, load_binary):
+ 	* ov-bool-mat.cc (save_binary, load_binary):
+	New functions for loading and saving structures in octave binary
+	format.
+
+ 	* ov-str-mat.h (save_binary, load_binary):
+ 	* ov-scalar.h (save_binary, load_binary):
+ 	* ov-re-mat.h (save_binary, load_binary):
+ 	* ov-range.h (save_binary, load_binary):
+ 	* ov-list.h (save_binary, load_binary):
+ 	* ov-cx-mat.h (save_binary, load_binary):
+ 	* ov-complex.h (save_binary, load_binary):
+ 	* ov-cell.h (save_binary, load_binary):
+ 	* ov-bool.h (save_binary, load_binary):
+ 	* ov-bool-mat.h (save_binary, load_binary):
+ 	* ov-struct.h (save_binary, load_binary):
+	Provide decls.
+
+ 	* ov.h (save_binary, load_binary): New virtual functions.
+
+ 	* ov-base.cc (save_binary, load_binary): New functions, for fallbacks
+ 	with error message.
+ 	* ov-base.h: Provide decls.
+
+ 	* load-save.cc: Remove "-import" flag and make it the default.
+ 	* load-save.h: Likewise.
+
+ 	* ls-oct-ascii.cc: Split the load/save functionality into the types
+ 	themselves. Save "string" variables with the name "string" rather than
+ 	string array. Backward compatiability maintained in ov-cs-mat.cc.
+ 	Include new version of extract_keyword that halts if the next value is
+ 	invalid rather that searching for the next valid value.
+ 
+ 	* ls-oct-ascii.h: Extract_keyword header updated.
+	Include definition of OCT_RBV and CELL_ELT_TAG, since they are now
+	used elsewhere.
+ 
+ 	* ls-hdf5.cc: Split load/save functionality into the types themselves.
+ 	The hdf5 format is changed so that each object is a group with a
+ 	dataset "type" being a string with the octave_value type and the
+ 	dataset or group "value" containing the value of the data, struct, etc.
+ 	This allows extensibility. Backward compatibility is maintained. The
+ 	"import" flag is now assumed to always be true and has been removed.
+  
+ 	* ov-struct.cc (save_ascii, load_ascii, save_hdf5, load_hdf5): 
+ 	* ov-str-mat.cc (save_ascii, load_ascii, save_hdf5, load_hdf5): 
+ 	* ov-scalar.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+	* ov-re-mat.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-range.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-list.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-cx-mat.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-complex.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-cell.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-bool.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-bool-mat.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	New functions for loading and saving structures in octave ascii
+	and hdf5 formatted files.
+
+ 	* ov-struct.h (save_ascii, load_ascii, save_hdf5, load_hdf5): 
+ 	* ov-str-mat.h (save_ascii, load_ascii, save_hdf5, load_hdf5): 
+ 	* ov-scalar.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-re-mat.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-range.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-list.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-cx-mat.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-complex.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-cell.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-bool.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	* ov-bool-mat.h (save_ascii, load_ascii, save_hdf5, load_hdf5):
+ 	Provide decls.
+ 
+ 	* ov-typeinfo.cc (octave_value_typeinfo::do_lookup_type): Include
+ 	make_unique so that the stored type value is not used for all loaded
+ 	variables.
+ 
+ 	* ov.h: (save_ascii, load_ascii, save_hdf5 and load_hdf5):
+	New virtual functions.
+ 	
+  	* ov-base.cc (save_ascii, load_ascii, save_hdf5, load_hdf5):
+	New functions, for fallbacks with error message.
+	* ov-base.h: Provide decls.
+
+2003-12-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cx-mat.cc (octave_complex_matrix::assign): RHS arg is N-d.
+	* ov-cx-mat.h: Fix decl.
+
+	* ops.h (DEFNDASSIGNOP_FN): New macro.
+	* OPERATORS/op-bm-b.cc, OPERATORS/op-bm-bm.cc,
+	OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc,
+	OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc, OPERATORS/op-m-m.cc,
+	OPERATORS/op-m-s.cc: Use it instead of DEFASSIGNOP_FN.
+
+2003-12-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xpow.cc (xpow (double, double)): Avoid apparent GNU libm bug.
+
+2003-12-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.cc (symbol_record::print_symbol_info_line):
+	Also check is_static to see if a symbol can be cleared.
+
+2003-12-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (is_keyword): Also allow varargout_kw if
+	lexer_flags.looking_at_return_list is false provided that we are
+	defining a function and we haven't seen the function name yet.
+	* parse.y (return_list): Don't require [] around varargout.
+
+	* DLD-FUNCTIONS/find.cc (DO_FIND_OP): Delete macro.
+	(find_to_fortran_idx): Delete.  Move guts of function to
+	find_nonzero_elem_idx.
+	(find_nonzero_elem_idx): Now a template function.  Handle overall
+	array index here too.  Make it N-d aware.
+
+	* pt-pr-code.cc (tree_print_code::visit_complex_for_command, 
+	tree_print_code::visit_octave_user_function_header,
+	tree_print_code::visit_matrix, tree_print_code::visit_cell,
+	tree_print_code::visit_multi_assignment): Keep track of nearest
+	[, {, or ( nesting level.
+	(tree_print_code::visit_index_expression): Likewise.  Check nesting
+	level to decide how to print index.
+	(tree_print_code::reset): Also reset nesting level stack.
+
+	* pt-pr-code.h (tree_print_code::nesting): New data member.
+	(tree_print_code::tree_print_code): Initialize it.
+
+	* ov-base-mat.h (octave_base_matrix::octave_base_matrix (const MT&)):
+	If arg has no dimensions, resize to be 0x0.
+
+2003-12-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-map.cc (Octave_map::assign): Use Octave_map::contents member
+	function instead of operator [].
+	* ov-struct.cc (octave_struct::subsasgn): Likewise.
+	* DLD-FUNCTIONS/time.cc (extract_tm): Likewise.
+
+	* DLD-FUNCTIONS/time.cc	(mk_tm_map): Use Octave_map::assign member
+	function instead of operator [].
+	* DLD-FUNCTIONS/getrusage.cc (Fgetrusage): Likewise.
+	* DLD-FUNCTIONS/getgrent.cc (mk_gr_map): Likewise.
+	* DLD-FUNCTIONS/getpwent.cc (mk_pw_map): Likewise.
+	* load-save.cc (do_load): Likewise.
+	* ls-hdf5.cc (hdf5_read_next_data): Likewise.
+	* ls-mat5.cc (read_mat5_binary_element): Likewise.
+	* oct-map.cc (Octave_map::reshape): Likewise.
+	* oct-map.cc (Octave_map::index): Likewise.
+	* ov-fcn-handle.cc (Ffunctions): Likewise.
+	* pt-idx.cc (make_arg_struct): Likewise.
+	* sighandlers.cc (make_sig_struct): Likewise.
+	* syscalls.cc (mk_stat_map): Likewise.
+	* toplev.cc (Foctave_config_info): Likewise.
+
+	* ls-hdf5.cc (add_hdf5_data): Temporary Octave_map is now const.
+	* ls-mat5.cc (save_mat5_binary_element): Likewise.
+
+	* oct-map.cc (Octave_map::assign (const std::string&, const
+	octave_value&)): New function.
+	* oct-map.h: Provide decl.
+	(Octave_map::contents (const std::string&)): New function.
+	(Octave_map::operator [] (const std::string&) const): Delete.
+	(Octave_map::operator [] (const std::string&)): Delete.
+
+2003-12-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-cell.cc: Allow transpose for cell arrays.
+	* OPERATORS/op-m-m.cc, OPERATORS/op-cm-cm.cc,
+	OPERATORS/op-bm-bm.cc, OPERATORS/op-streamoff.cc,
+	OPERATORS/op-str-str.cc: Improve error message for attempt to
+	transpose N-d object.
+
+2003-11-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-arg-list.cc (F__end__): Handle N-d objects.
+
+2003-11-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-b-bm.cc: New file.
+
+	* OPERATORS/op-bm-b.cc (op_el_and, op_el_or): Define and install.
+	* OPERATORS/op-bm-bm.cc (op_el_and, op_el_or, assign): Likewise.
+
+	* ov-str-mat.cc (CHAR_MATRIX_CONV): New macro.
+	* ov-str-mat.h (octave_char_matrix_str::double_value,
+	octave_char_matrix_str::matrix_value,
+	octave_char_matrix_str::array_value,
+	octave_char_matrix_str::complex_value,
+	octave_char_matrix_str::complex_matrix_value,
+	(octave_char_matrix_str::complex_array_value): Use it.
+
+	* ov-bool-mat.cc (default_numeric_conversion_function):
+	Convert to NDArray, not Matrix.
+	* ov-str-mat.cc (default_numeric_conversion_function): Likewise.
+
+	* ov-range.h (octave_range::array_value): New function.
+	(octave_range::complex_array_value): Likewise.
+	* ov-ch-mat.h (charNDArray::array_value): New function.
+	(charNDArray::complex_array_value): Likewise.
+	* ov-str-mat.h (octave_char_matrix_str::array_value): Likewise.
+	(octave_char_matrix_str::complex_value): Likewise.
+	(octave_char_matrix_str::complex_matrix_value): Likewise.
+	(octave_char_matrix_str::complex_array_value): Likewise.
+
+	* mappers.cc (acosh, log, log10, sqrt):
+	Use octave_Inf instead of DBL_MAX for range limit.
+
+2003-11-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.52.
+	(OCTAVE_API_VERSION): Now api-v3.
+
+	* DLD-FUNCTIONS/rand.cc (do_rand): Pass function name from arg
+	list in calls to error.
+
+	* ov-cs-list.cc, ov-cs-list.h (octave_cs_list::octave_cs_list):
+	Explicitly initialize base class in constructors.
+
+	* ov.h (octave_value::all_strings): Pass second arg to rep function.
+
+	* ov.h (octave_value::string_value): Pass arg to rep function.
+
+	* DLD-FUNCTIONS/dasrt.cc (dasrt_user_f): Delete unused arg names.
+	* DLD-FUNCTIONS/rand.cc (Frand, Frandn): Likewise.
+	* ls-hdf5.h (hdf5_streambase::hdf5_streambase): Likewise.
+	* ls-hdf5.cc (read_hdf5_data): Likewise.
+	* ls-utils.cc (get_save_type): Likewise.
+	* parse.y (Fassignin): Likewise.
+	* utils.cc (empty_arg): Likewise.
+	* ov-usr-fcn.h (octave_user_function::subsref): Likewise.
+	* ov-base-mat.h (octave_base_matrix::subsref): Likewise.
+	* ov-mapper.h (octave_mapper::subsref): Likewise.
+	* ov-builtin.h (octave_builtin::subsref): Likewise.
+	* ov-complex.cc (octave_complex::complex_array_value): Likewise.
+	* ov-cell.h (octave_cell::subsref): Likewise.
+	* ov-base-scalar.h (octave_base_scalar::subsref): Likewise.
+	* ov-struct.h (octave_struct::subsref): Likewise.
+	* ov-range.h (octave_range::subsref): Likewise.
+	* ov-list.h (octave_list::subsref): Likewise.
+	* ov-base.cc (octave_base_value::print_info): Likewise.
+	* pt-check.cc (tree_checker::visit_subplot_axes): Likewise.
+	* pr-output.cc (octave_print_internal (std::ostream&, double, bool),
+	octave_print_internal (std::ostream&, const Complex&, bool),
+	octave_print_internal (std::ostream&, const ArrayN<std::string>&,
+	bool, int): Likewise.
+	* oct-stream.cc (octave_scan<> (std::istream&, const
+	scanf_format_elt&, char*): Likewise
+	* TEMPLATE-INST/Array-tc.cc (resize_fill_value<octave_value>):
+	Likewise.
+	* pt-bp.cc (tree_breakpoint::visit_octave_user_function,
+	tree_breakpoint::visit_octave_user_function_header,
+	tree_breakpoint::visit_octave_user_function_trailer,
+	tree_breakpoint::visit_plot_limits,
+	tree_breakpoint::visit_plot_range,
+	tree_breakpoint::visit_subplot,
+	tree_breakpoint::visit_subplot_axes,
+	tree_breakpoint::visit_subplot_list,
+	tree_breakpoint::visit_subplot_style,
+	tree_breakpoint::visit_subplot_using): Likewise.
+	* ov.cc (octave_value::column_vector_value,
+	(octave_value::complex_column_vector_value,
+	(octave_value::row_vector_value,
+	octave_value::complex_row_vector_value,
+	octave_value::do_non_const_unary_op): Likewise.
+
+	* load-save.cc: Only include ls-hdf5.h if HAVE_HDF5 is defined.
+	From Melqart <melqart at free.fr>.
+
+	* pr-output.h (octave_fcn_handle::print_as_scalar): Delete.
+
+	* pr-output.cc (octave_print_internal): New version for
+	ArrayN<std::string> objects.
+	* pr-output.h: Provide decl.
+	* ov-fcn-handle.cc (octave_fcn_handle::print_raw): Use it.
+
+	* OPERATORS/op-fcn-handle.cc: New file.
+	* Makefile.in (OP_XSRC): Add it to the list.
+
+	* ov-fcn-handle.h, ov-fcn-handle.cc (octave_fcn_handle):
+	Now an array of function handle objects.
+
+	* ov.h, ov.cc (octave_value::octave_value (const fcn_handle_array&),
+	(octave_value::octave_value (octave_function *f, const std::string&)):
+	New constructors.
+	(octave_value::octave_value (const octave_fcn_handle&)): Delete.
+
+	* ov-base-mat.cc (octave_base_matrix<T>::print_as_scalar):
+	Check dims instead of rows and columns.
+
+	* ov.h (octave_value::is_function_handle): New function.
+	* ov-base.h (octave_base_value::is_function_handle): New function.
+
+2003-11-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool-mat.h (octave_bool_matrix::array_value): Construct return
+	value directly from matrix data member, not matrix.matrix_value ().
+
+	* ov-re-mat.h (octave_matrix::index_vector): Construct idx_vector
+	from NDArray, not Matrix.
+
+	* ov-bool-mat.h (octave_bool_matrix::index_vector): Construct
+	idx_vector from boolNDArray, not boolMatrix.
+
+	* ov.cc (install_types): Also register dld function type.
+
+	* OPERATORS/op-streamoff.cc: Install increment and decrement operators.
+	* ov-streamoff.h (octave_streamoff::increment,
+	octave_streamoff::decrement): New functions.
+
+	* ov-streamoff.h, ov-streamoff.cc: Move streamoff_array class to
+	liboctave/so-array.h and liboctave/so-array.cc.
+
+	* oct-stream.cc (octave_stream::seek): Extract std::streamoff from
+	tc_offset instead of int.
+
+	* ov-re-mat.cc (octave_matrix::double_value): Use numel, not length.
+
+	* ov-re-mat.cc (octave_matrix::streamoff_array_value): New function.
+	* ov-re-mat.h: Provide decl.
+
+	* ov-scalar.cc (octave_scalar::streamoff_value): New function.
+	* ov-scalar.h: Provide decl.
+
+	* ov.cc (octave_value::streamoff_array_value,
+	octave_value::streamoff_value): New functions.
+	* ov.h: Provide decls.
+
+	* ov-base.cc (octave_base_value::streamoff_array_value,
+	octave_base_value::streamoff_value): New functions.
+	* ov-base.h: Provide decls.
+
+	* ov-usr-fcn.cc (install_automatic_vars): Don't do anything unless
+	sym_tab is defined.
+
+	* ov-streamoff.h, ov-streamoff.cc, OPERATORS/op-streamoff.cc:
+	New files.
+
+	* ov-cell.h (octave_value_cell::is_matrix_type): New function.
+
+	* ov-mapper.h (octave_mapper::octave_mapper): No copying.
+	* ov-fcn.h (octave_function::octave_function): Likewise.
+	* ov-usr-fcn.h (octave_function::octave_function): Likewise.
+	* ov-builtin.h (octave_builtin::octave_builtin): Likewise.
+	* ov-dld-fcn.h (octave_dld_function::octave_dld_function): Likewise.
+
+2003-11-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-mapper.h (octave_mapper::octave_mapper): Make public.
+	Provide copy constructor and assignment operator.
+	* ov-fcn.h (octave_function::octave_function): Likewise.
+	* ov-builtin.h (octave_builtin::octave_builtin): Likewise.
+	* ov-dld-fcn.h (octave_dld_function::octave_dld_function): Likewise.
+
+	* ov-typeinfo.cc (octave_value_typeinfo::register_type,
+	octave_value_typeinfo::do_register_type): New arg, val.
+	Save it	in vals array.
+	(octave_value_typeinfo::lookup_type,
+	octave_value_typeinfo::do_lookup_type): New functions.
+	* ov-typeinfo.h: Provide decl.
+	(octave_value_typeinfo::vals): New data member.
+	(octave_value_typeinfo::octave_value_typeinfo): Initialize it.
+
+	* ov.h (DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Pass
+
+	* ov.h (DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Define register_type
+	here.  Also pass an empty object of the to-be-registered type to
+	register_type.
+	(DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Declare register_type
+	here, but don't define it.
+
+2003-11-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-fcn-handle.h (octave_fcn_handle::octave_fcn_handle (void)):
+	New constructor.
+
+	* ov-usr-fcn.h (octave_user_function::octave_user_function):
+	Delete decl for private constructor.
+
+	* ov-str-mat.cc (octave_char_matrix_str::matrix_value):
+	Conversion to matrix is an error unless explicitly forced.
+
+	* ov-str-mat.cc (octave_char_matrix_str::double_value): New function.
+	* ov-str-mat.h: Provide decl.
+
+	* ov-file.cc (print_raw): Use parens around ?: conditional used on
+	RHS of << output operator.
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::seekoff,
+	c_file_ptr_buf::seekpos): Can't use fseek here, so just fail (by
+	returning -1) until we have a better solution.
+
+	* oct-stream.cc (octave_stream::tell): Return std::streamoff, not long.
+	* oct-iostrm.cc (octave_base_iostream::tell): Likewise.
+	* oct-stdstrm.cc (octave_stdiostream::tell): Likewise.
+	* oct-strstrm.cc (octave_base_strstream::tell): Likewise.
+	* oct-stream.h, oct-iostrm.h, oct-stdstrm.h, oct-strstrm.h:
+	Fix decls to match.
+
+2003-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ls-mat-ascii.cc (get_lines_and_columns): Delete second arg in
+	call to istream::seekg.
+
+	* ov-mapper.cc (MAPPER_LOOP_2, any_element_less_than,
+	any_element_greater_than, octave_mapper::apply):
+	Handle N-d arrays.
+
+2003-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ls-mat5.cc (read_mat5_binary_element, save_mat5_binary_element):
+	Handle N-d arrays.
+
+	* lex.l (next_token_is_index_op): New function.
+	(handle_close_bracket): Use it.
+
+	* ls-hdf5.cc, ls-mat-ascii.cc, ls-mat4.cc, ls-mat5.cc,
+	ls-oct-ascii.cc, ls-oct-binary.cc, ls-utils.cc, ls-hdf5.h,
+	ls-mat-ascii.h, ls-mat4.h, ls-mat5.h, ls-oct-ascii.h,
+	ls-oct-binary.h, ls-utils.h: New files, extracted from load-save.cc.
+	* Makefile.in: Add them to the appropriate lists.
+
+2003-11-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (octave_print_internal): Don't indent rows for
+	plus_format.  Use pr_plus_format for Range type with plus_format.
+	(plus_format_chars): New static variable.
+	(set_format_style): Allow optional arg for plus format to set it.
+	(pr_plus_format): Use it.
+
+	* ov-bool.h (octave_bool::array_value,
+	octave_bool::complex_array_value): New functions.
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::do_index_op):
+	Ensure correct number of indices for Array indexing code.
+
+2003-11-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/qz.cc (qz): Use x.data()+offset instead of &a(i,j).
+	First and third args for dlag2 are const.
+
+	* DLD-FUNCTIONS/sort.cc (Fsort): Use const qualifier as appropriate.
+
+	* DLD-FUNCTIONS/balance.cc (balance): Use data() instead of
+	fortran_vec where appropriate in call to dggbak.
+
+	* DLD-FUNCTIONS/dasrt.cc (dasrt_user_j): Simplify inserting x and
+	xdot in arg vector.
+	(dasrt_user_f): Likewise.
+	(dasrt_user_cf): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (dassl_user_function): Likewise.
+	(dassl_user_jacobian): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (lsode_user_function): Likewise.
+	(lsode_user_jacobian): Likewise.
+	* DLD-FUNCTIONS/daspk.cc (daspk_user_function): Likewise.
+	(daspk_user_jacobian): Likewise.
+
+2003-11-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-range.h (octave_range::reshape): New function.
+
+2003-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.51.
+	(OCTAVE_API_VERSION): Now api-v2.
+
+	* version.h (OCTAVE_BUGS_STATEMENT): Also tell people to look at
+	http://www.octave.org/bugs.html.
+
+	* oct-map.cc (Octave_map::assign): Use resize, not resize and fill.
+	* ov-typeinfo.cc (octave_value_typeinfo::do_register_type): Likewise.
+
+	* Cell.cc (Cell::Cell): Pass dim_vector to resize instead of two ints.
+
+2003-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-liboctave-prereq): New target.
+	($(DEF_FILES), $(MAKEDEPS)): Depend on it.	
+	(distclean): Remove it.
+
+	* parse.y (cancel_obj_idx): New rule.
+	(postfix_expr, prefix_expr): Use begin_obj_idx after every
+	postfix_expr on RHS.  Use cancel_obj_idx as soon as possible for
+	cases where we are not working on an index expression.
+
+	* lex.l (maybe_unput_comma, handle_close_bracket):
+	Don't insert comma if we are looking at an object index and the
+	closest nesting level is a brace.
+
+	* parse.y (postfix_expr): Use begin_obj_idx between postfix_expr
+	and the indexing delimiter rather than after it.
+
+	* lex.h (lexical_feedback::braceflag): New member variable.
+	* lex.l	(lexical_feedback::init): Initialize braceflag.
+	(\{{S}*): Increment lexer_flags.braceflag, not
+	lexer_flags.bracketflag.
+	(handle_close_bracket): Handle lexer_flags.braceflag and
+	lexer_flags.bracketflag separately based on bracket_type.
+	Delete unnecesary yyinput/yyunput.
+
+	* lex.l (next_token_is_postfix_unary_op): Also recognize ++ and --.
+
+	* ov-typeinfo.cc (octave_value_typeinfo::register_type,
+	octave_value_typeinfo::do_register_type):
+	New arg, c_name for class name.
+	* ov-base.cc, ov-bool-mat.cc, ov-bool.cc, ov-builtin.cc,
+	ov-cell.cc, ov-ch-mat.cc, ov-colon.cc, ov-complex.cc,
+	ov-cs-list.cc, ov-cx-mat.cc, ov-dld-fcn.cc, ov-fcn-handle.cc,
+	ov-file.cc, ov-list.cc, ov-mapper.cc, ov-range.cc, ov-re-mat.cc,
+	ov-scalar.cc, ov-str-mat.cc, ov-struct.cc, ov-usr-fcn.cc,
+	ov-va-args.cc: Pass class name to DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA.
+	* ov.h (octave_value::class_name): New virtual function.
+	(DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Define c_name, for class name.
+	Pass c_name to octave_value_typeinfo::register_type.
+	(DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Declare static member
+	c_name for class name.  Provide class_name member function.
+
+	* ov-typeinfo.cc (Fclass): New function.
+
+2003-11-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (Fisvarname): Pass correct name to make_argv.
+
+	* ov-cell.cc (Fiscellstr): New function.
+
+	* ov-file.h (octave_file::all, octave_file::any,
+	octave_file::dims, octave_file::is_real_type,
+	octave_file::ist_real_scalar): New functions.
+
+	* lex.l (bracket_brace_paren_nesting_level::is_bracket_or_brace):
+	New function.
+	(handle_close_bracket): New arg, bracket_type.  Change all uses.
+	First arg is now bool.
+	(<MATRIX_START>{SNLCMT}*\}{S}*): New pattern.
+	(maybe_unput_comma): Handle brace nesting level the same as brackets.
+	(handle_close_brace): Likewise.
+	(<MATRIX_START>{S}+): Likewise.
+	(<MATRIX_START>{S}*{COMMENT}{SNLCMT}*): Likewise.
+	(<MATRIX_START>{S}*{NL}{SNLCMT}*): Likewise.
+	({NL}): Likewise.
+	({CCHAR}): Likewise.
+	(")"): Likewise.
+	(\{{S}*): Handle the same as \[{S}*.
+	("}"): Handle the same as \].
+
+	* Makefile.in (stamp-prereq): Add oct-gperf.h, parse.cc, and
+	lex.cc to the list.
+
+2003-11-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.cc (print_as_scalar): New function.
+	* ov-cell.h: Provide decl.
+
+	* ov-cell.cc (octave_cell::print_name_tag): Delete.
+	* ov-cell.h: Delete decl.
+
+	* ov-base-mat.cc (octave_base_matrix::print_name_tag): Delete.
+	* ov-base-mat.h: Delete decl.
+
+	* ov-base.cc (octave_base_value::print_name_tag):
+	Use print_as_scalar here. 
+	* ov.h (octave_base_value::print_as_scalar): New virtual function.
+	* ov-base.h (octave_base_value::print_as_scalar):
+	New default implementation.
+	* ov-base-mat.h (octave_base_matrix::pirnt_as_scalar):
+	Don't declare as virtual here.
+
+	* ov-struct.cc (octave_struct::print_raw): If only printing keys,
+	also print dimensions of fields and overall array.
+
+	* sysdep.cc (Fnative_float_format): New function.
+
+	* input.cc (generate_possible_completions): Also append all
+	possible filename completions here.
+
+2003-11-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc: Explicitly instantiate octave_scan functions.
+
+	* TEMPLATE-INST/Array-c.cc, TEMPLATE-INST/Array-os.cc,
+	TEMPLATE-INST/Array-sym.cc, ov-typeinfo.cc:
+	Use new INSTANTIATE_ARRAY macro.
+
+	* data.cc (do_permute): New function.
+	(Fpermute, Fipermute): Use it.
+
+	* ov-base.cc (octave_base_value::permute): New function.
+	* ov-base.h: Provide decl.
+
+	* ov.h (octave_value::ipermute): New function.
+
+2003-11-11  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* data.cc (Fpermute, Fipermute): New functions.
+	* ov.h (octave_value::permute): New function.
+	* ov-base-mat.h (octave_base_matrix::permute): New function.
+
+2003-11-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-obj.h (octave_value_list): Internal representation is now
+	std::vector instead of Array.
+
+	* ov-list.h, ov-list.cc: Internal representation is now Cell, not
+	octave_value_list.
+	(Flist): Print one-time warning.
+
+	* ov.cc (octave_value::octave_value (const octave_value_list&, bool)):
+	Cope with octave_cs_list not being derived from octave_list.
+
+	* ov-cs-list.cc (octave_cs_list): Handle conversion of Cell array
+	to octave_value_list here.
+
+	* ov-cs-list.h (class octave_cs_list): Derive from
+	octave_base_value, not octave_list.
+
+	* ov-cs-list.h, ov-cs-list.cc: Remove commented-out code.
+
+	* TEMPLATE-INST/Array-tc.cc (resize_fill_value): Use modern
+	specialization syntax.
+
+	* ov-cell.cc (octave_cell::print_raw): Use dim_vector::str.
+
+	* Cell.cc, Cell.h, debug.cc, file-io.cc, load-save.cc,
+	oct-fstrm.cc, oct-iostrm.cc, oct-iostrm.h, oct-map.cc, oct-map.h,
+	oct-prcstrm.cc, oct-stdstrm.h, oct-stream.cc, oct-strstrm.h,
+	octave.cc, ov-base.h, ov-cell.cc, ov.cc, ov.h, pt-cell.h,
+	pt-mat.cc, pt-mat.h, pt-plot.cc, pt-stmt.cc, variables.cc,
+	DLD-FUNCTIONS/rand.cc: Avoid -Wshadow warnings.
+
+2003-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_base_value::is_bool_matrix): New virtual function.
+	* ov-base.h (octave_base_value::is_bool_matrix): New function.
+
+2003-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.cc (octave_value::length): If any dim is zero, return 0.
+
+	* ov-cell.cc (octave_cell::subsref): When indexing with '{', quit
+	early if an error occurs in do_index_op.
+
+	* ov.cc (octave_value::next_subsref): Don't do anything if
+	error_state is true.
+
+	* cutils.c (octave_usleep) [HAVE_SELECT]: Introduce new local
+	scope for declaration of delay.
+	[HAVE_POLL]: Likewise, for delay and pfd.
+
+	* ov-base.cc (octave_base_value::bool_array_value):
+	Function takes no args.
+	* ov-base.h: Likewise, for decl.
+	* ov-bool-mat.h (boolNDArray::bool_array_value): Likewise.
+
+	* ov-fcn.cc, ov-fcn.h (octave_value::clone,
+	octave_value::empty_clone): Return type is octave_value*, not
+	octave_function*.
+
+2003-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-str-mat.h (octave_char_matrix_str::reshape): New function.
+	Force result to be a string.
+
+2003-10-29  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* data.cc (DATA_REDUCTION): Work on NDArray and ComplexNDArray
+	objects instead of Matrix and ComplexMatrix objects.
+
+2003-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool-mat.h (octave_bool_matrix::NDArray,
+	octave_bool_matrix::ComplexNDArray): New functions.
+
+	* ov-complex.cc (octave_complex::array_value,
+	octave_complex::complex_array_value): New functions.
+	* ov-complex.h: Provide decls.
+
+	* ov-scalar.cc (octave_scalar::array_value,
+	octave_scalar::complex_array_value): New functions.
+	* ov-scalar.h: Provide decls.
+
+	* oct-map.cc (Octave_map::reshape): New function.
+	* oct-map.h: Provide decl.
+
+	* ov-struct.h (octave_struct::reshape): New function.
+
+	* Cell.h (Cell:Cell (const Array<octave_value>&): New constructor.
+
+	* data.cc (Freshape): New function.
+	* ov.h (octave_value::reshape): New function.
+	* ov-base-mat.h (octave_base_matrix::reshape): New function.
+	* ov-base.cc (octave_base_value::reshape): New function.
+	* ov-base.h: Provide decl.
+
+	* DLD-FUNCTIONS/balance.cc: lscale and rscale args for dggbak are
+	const.  Use data() instead of fortran_vec where possible.
+	* DLD-FUNCTIONS/qz.cc: Likewise.
+
+	* data.cc (fill_matrix): Remove trailing singletons before
+	allocating the result matrix.
+
+	* input.cc (get_user_input): Don't forget about the diary here.
+
+2003-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-list.h (octave_list::nelem): Delete.
+	(octave_list::dims): New function.
+	* ov-range.h (octave_list::dims): New function.
+	* ov-struct.h (octave_struct::dims): New function.
+	* ov-base-scalar.h (octave_base_scalar::dims): New function.
+
+	* ov.h (octave_value::rows): No longer virtual.
+	* ov.cc (octave_value::rows): Provide common implementation.
+	* ov-base.h (octave_base_value::rows): Delete.
+	* ov-base-mat.h (octave_base_matrix<T>::rows): Delete.
+	* ov-base-scalar.h (octave_base_scalar<T>::rows): Delete.
+	* ov-struct.h (octave_struct::rows): Delete.
+	* ov-range.h (octave_range::rows): Delete.
+
+	* ov.h (octave_value::columns): No longer virtual.
+	* ov.cc (octave_value::columns): Provide common implementation.
+	* ov-base.h (octave_base_value::columns): Delete.
+	* ov-base-mat.h (octave_base_matrix<T>::columns): Delete.
+	* ov-base-scalar.h (octave_base_scalar<T>::columns): Delete.
+	* ov-struct.h (octave_struct::columns): Delete.
+	* ov-range.h (octave_range::columns): Delete.
+
+	* ov.h (octave_value::numel): No longer virtual.
+	* ov.cc (octave_value::numel): Provide common implementation.
+	* ov-base.h (octave_base_value::numel): Delete.
+	* ov-base-mat.h (octave_base_matrix<T>::numel): Delete.
+	* ov-base-scalar.h (octave_base_scalar<T>::numel): Delete.
+	* ov-struct.h (octave_struct::numel): Delete.
+
+	* ov-cs-list.h (octave_cs_list::dims): New function.
+	(octave_cs_list::length): Delete.
+
+	* ov.h (octave_value::ndims): No longer virtual.
+	* ov.cc (octave_value::ndims): Provide common implementation.
+	* ov-base.h (octave_base_value::ndims): Delete.
+	* ov-base-mat.h (octave_base_matrix<T>::ndims): Delete.
+	* ov-base-scalar.h (octave_base_scalar<T>::ndims): Delete.
+	* ov-struct.h (octave_struct::ndims): Delete.
+
+	* ov-cell.cc (Fcell): Make it work for N-d cells.
+
+	* Cell.h (Cell::Cell  (const dim_vector&, const octave_value&)):
+	New constructor.
+
+	* ov.h (octave_value::length): No longer virtual.
+	* ov.cc (octave_value::length): Provide common implementation.
+	* ov-base.h (octave_base_value::length): Delete.
+	* ov-base-mat.h (octave_base_matrix<T>::length): Delete.
+	* ov-base-scalar.h (octave_base_scalar<T>::length): Delete.
+	* ov-struct.h (octave_struct::length): Delete.
+	* ov-cs-list.h (octave_cs_list::length): Delete.
+	* ov-list.h (octave_list::length): Delete.
+	* ov-range.h (octave_range::length): Delete.
+
+	* load-save.cc (save_mat5_binary_element): Use numel instead of
+	array_length.
+	* ov-struct.cc (octave_struct::print_raw): Likewise.
+	* pt-loop.cc (tree_complex_for_command::eval): Likewise.
+	* oct-map.cc (Octave_map::numel): New function.
+	* oct-map.h: Provide decl.
+
+	* oct-map.cc, oct-map.h (Octave_map::array_length): Delete.
+	(common_size): New static function.
+	(Octave_map::assign): Make resizing work for N-d cell objects.
+
+	* oct-map.cc (Octave_map::dims): New function.
+	* oct-map.h: Provide decl.
+
+	* pr-output.cc 	(print_empty_nd_array): New static function.
+	(PRINT_ND_ARRAY): Use it.
+
+	* ov.h (octave_value::is_empty): No longer virtual.  Return value
+	based on numel.
+	* data.cc (Fisempty): Use it.
+	(Fnumel): New function.
+
+	* ov.h (octave_value::numel): New function.
+	* ov-base.h (octave_base_value::numel): Likewise.
+	* ov-base-mat.h (octave_base_matrix<T>::numel): Likewise.
+	* ov-base-scalar.h  (octave_base_scalar<T>::numel): Likewise.
+
+2003-10-27  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::is_true):
+	Only work for 2-dimensional objects.
+	* data.cc (ANY_ALL (FCN)): Allow dim to take values large than 2.
+
+	* ov.h (octave_value::ndims): New function.
+	* ov-base.h (octave_base_value::ndims): Likewise.
+	* ov-base-scalar.h (octave_base_scalar<T>::ndims): Likewise.
+	* ov-base-mat.cc (octave_base_matrix<MT>::ndims): New function.
+	(octave_base_matrix<MT>::length): Move here from ov-base-mat.h.
+	Make it work for N-d arrays.
+	* ov-base-mat.h (octave_base_matrix<MT>::ndims): Provide decl.
+	* data.cc (Fndims): New built-in function.
+
+2003-10-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/qz.cc:
+	Use new F77 arg macros in declarations of external Fortran
+	subroutines and for calling them.
+
+	* ops.h (DEFNDUNOP_OP, DEFNDUNOP_FN): New arg e, to name value
+	extractor function prefix.
+	* OPERATORS/op-bm-bm.cc, OPERATORS/op-cm-cm.cc,	OPERATORS/op-m-m.cc:
+	Change all uses.
+
+	* ov-cx-mat.h (octave_complex_matrix::complex_array_value,
+	octave_char_matrix::char_array_value,
+	octave_bool_matrix::bool_array_value): Rename from array_value.
+	* OPERATORS/op-bm-bm.cc, OPERATORS/op-cm-cm.cc,
+	OPERATORS/op-cm-cs.cc, OPERATORS/op-cm-m.cc,
+	OPERATORS/op-cm-s.cc, OPERATORS/op-cs-cm.cc,
+	OPERATORS/op-m-cm.cc, OPERATORS/op-m-m.cc,
+	OPERATORS/op-s-cm.cc: Use complex_array, char_array, and
+	bool_array as appropriate (instead of just array).
+
+	* ov-base.cc (octave_base_value::array_value,
+	octave_base_value::bool_array_value,
+	octave_base_value::complex_array_value,
+	octave_base_value::char_array_value): Provide default implementations.
+	* ov-base.h: Provide decls.
+
+	* ov.h (octave_value::array_value, octave_value::bool_array_value,
+	octave_value::complex_array_value, octave_value::char_array_value):
+	New virtual functions.
+
+2003-10-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-idx.cc (make_subs_cell): Pass dim_vector object to resize.
+
+	* ov-typeinfo.cc (octave_value_typeinfo::do_register_type):
+	Use resize_and_fill for types.
+
+	* oct-obj.h (octave_value_list::maybe_resize): Use resize_and_fill.
+	(octave_value_list::resize (int, const octave_value&)): Likewise.
+
+	* oct-map.cc (Octave_map::assign): Use resize_and_fill as needed.
+
+	* Cell.h (Cell (void)): Default size is now 0x0.
+
+2003-10-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc,
+	OPERATORS/op-cs-m.cc, OPERATORS/op-m-cm.cc, OPERATORS/op-s-cm.cc:
+	Include headers for N-d operators.
+
+2003-10-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ops.h (DEFNDUNOP_OP, DEFNDUNOP_FN, DEFNDBINOP_OP,
+	DEFNDBINOP_FN): New N-dimensional macros.
+	* OPERATORS/op-bm-bm.cc, OPERATORS/op-cm-cm.cc,
+	OPERATORS/op-cm-cs.cc, OPERATORS/op-cm-m.cc,
+	OPERATORS/op-cm-s.cc, OPERATORS/op-cs-cm.cc,
+	OPERATORS/op-cs-m.cc, OPERATORS/op-m-cm.cc,
+	OPERATORS/op-m-cs.cc, OPERATORS/op-m-m.cc,
+	OPERATORS/op-m-s.cc, OPERATORS/op-s-cm.cc,
+	OPERATORS/op-s-m.cc: Use N-dimensional macros as appropriate.
+
+	* DLD-FUNCTIONS/rand.cc (do_rand, Frand, Frandn):
+	Handle N-dimensions.
+
+	* xpow.cc (elem_xpow (double, const NDArray&),
+	elem_xpow (double, const ComplexNDArray&),
+	elem_xpow (const NDArray&, double),
+	elem_xpow (const NDArray&, const NDArray&),
+	elem_xpow (const NDArray&, const Complex&),
+	elem_xpow (const NDArray&, const ComplexNDArray&),
+	elem_xpow (const Complex&, const NDArray&),
+	elem_xpow (const Complex&, const ComplexNDArray&),
+	elem_xpow (const ComplexNDArray&, double),
+	elem_xpow (const ComplexNDArray&, const NDArray&),
+	elem_xpow (const ComplexNDArray&, const Complex&),
+	elem_xpow (const ComplexNDArray&, const ComplexNDArray&):
+	New functions.
+	* xpow.h: Provide decls.
+
+	* xdiv.cc (x_el_div (double, const NDArray&),
+	x_el_div (double, const ComplexNDArray&),
+	x_el_div (const Complex, const NDArray&),
+	x_el_div (const Complex, const ComplexNDArray&)): New functions.
+	* xdiv.h: Provide decls.
+
+	* ov-bool-mat.h (boolNDArray::array_value): New function.
+	* ov-ch-mat.h (charNDArray::array_value): New function.
+	* ov-cx-mat.h (ComplexNDArray::array_value): New function.
+	* ov-re-mat.h (NDArray::array_value): New function.
+	(NDArray::double_nd_array_value): Delete.
+
+2003-10-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (text_getc): New static function.
+	(gobble_leading_white_space): Use it to simplify EOL processing.
+
+2003-10-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (fopen_mode_to_ios_mode): Ignore "t" in mode string.
+
+	* strfns.cc (Fischar): rename from Fisstr.
+
+2003-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (PRINT_ND_ARRAY): New macro.
+	(octave_print_internal): Use it.
+
+2003-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.cc	(octave_value::octave_value (const ArrayN<octave_value>&,
+	bool)):	New constructor.
+	* ov.h: Provide decl.
+
+	* ov.h (octave_value::squeeze): New virtual function.
+	* ov-base.cc (squeeze): Provide default implementation.
+	* ov-base-mat.h (octave_base_matrix::squeeze): New function.
+	* data.cc (Fsqueeze): New function.
+
+2003-10-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (make_valid_identifier): Return new string.
+	Arg is now string, not char *.
+	(ident_is_all_digits): New function.
+	(hdf5_read_next_data): Use it.
+
+2003-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (input_event_hook): Clear the event hook if hook_fcn
+	does not name a valid function.
+
+2003-10-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mappers.cc (xabs): New function.
+	(install_mapper_functions): Use it instead of abs for complex args
+	in Octave's abs mapper function.
+
+2003-09-27  Joseph P. Skudlarek  <Jskud at Jskud.com>
+ 
+ 	* DLD-FUNCTIONS/minmax.cc (min, max): Use @deftypefn machinery,
+ 	doc missing semantics, and add more examples to texinfo strings.
+
+2003-09-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_mat5_binary_element): Return early if the
+	miMATRIX element has length zero.
+
+2003-09-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.cc (octave_cell::subsasgn): Also attempt empty
+	conversion after extracting single element from cell array to
+	allow things like x{i}.elt = rhs to work.
+
+2003-09-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::dim_vector): New function.
+
+	* ov.h, ov.cc (octave_value::octave_value (const Cell&)):
+	New arg, is_cs_list.
+	(octave_value::octave_value (const NDArray&)):
+	Create octave_matrix object, not octave_double_nd_array object.
+	(octave_value::octave_value (const ComplexNDArray&),
+	octave_value::octave_value (const boolNDArray&),
+	octave_value (const charNDArray&, bool)): New constructors.
+
+	* ov.h, ov.cc (octave_value::nil_rep): New function.
+	(octave_value::octave_value (void)): Use it to initialize empty
+	octave_value objects.
+
+	* ov-list.h, ov-list.cc (octave_list::octave_list (const Cell&)):
+	New constructor.
+	* ov-cs-list.h (octave_cs_list::octave_cs_list (const Cell&)):
+	Likewise.
+
+	* data.cc (Fsize): Handle N-d objects.
+
+	* pr-output.cc (octave_print_internal): New versions for NDArray,
+	ComplexNDArray, boolNDArray, and charNDArray objects.
+	* pr-output.h: Provide decls.
+
+	* ov-re-nd-array.h, ov-re-nd-array.cc: Delete.
+
+	* Cell.h, Cell.cc, ov-base-mat.h, ov-base-mat.cc, ov-bool-mat.h,
+	ov-bool-mat.cc, ov-ch-mat.h, ov-ch-mat.cc, ov-cx-mat.h,
+	ov-cx-mat.cc, ov-re-mat.h, ov-re-mat.cc, ov-str-mat.h,
+	ov-str-mat.cc: Now N-dimensional.
+
+	* oct-map.h, oct-map.cc: Now based on Cell ojects instead of
+	octave_value_list objects.  Change all uses.
+
+	* TEMPLATE-INST/Array-tc.cc: Also instantiate ArrayN objects.
+	Don't instantiate assign funcitons for Array2 objects.
+
+2003-09-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (symbols_of_pt_plot): Default for automatic replot is
+	now true.
+
+	* pr-output.cc (Fformat): Doc fix.
+	(current_output_max_field_width, current_output_precision):
+	New functions.
+	(float_format::float_format (int, int, int)): Use them to provide
+	default values for field width and precision.
+	(print_g): New static variable.
+	(set_real_format, set_real_matrix_format, set_complex_format) 
+	(set_complex_matrix_format, set_range_format): Handle print_g.
+	(pr_float, pr_complex): Don't scale if using print_g.
+	(set_format_style): Accept new "g" and "G" modifiers for short and
+	long formats and set print_g.
+	Set default precision and width for short to 5, 10.
+	Set default precision and width for long to 15, 20.
+
+2003-09-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-m-cs.cc (complex_matrix_conv): Delete function.
+	(install_m_cs_ops): Don't install complex_matrix_conv here.
+
+	* OPERATORS/op-s-cs.cc (complex_matrix_conv): Delete function.
+	(install_s_cs_ops): Don't install complex_matrix_conv here.
+
+	* OPERATORS/op-s-s.cc (matrix_conv): Delete function.
+	(install_s_s_ops): Don't install matrix_conv here.
+
+	* OPERATORS/op-cs-s.cc (complex_matrix_conv): Delete function.
+	(install_cs_s_ops): Don't install complex_matrix_conv here.
+
+	* OPERATORS/op-cs-m.cc (complex_matrix_conv): Delete function.
+	(install_cs_m_ops): Don't install complex_matrix_conv here.
+
+	* OPERATORS/op-cs-cs.cc (complex_matrix_conv): Delete function.
+	(install_cs_cs_ops): Don't install complex_matrix_conv here.
+
+	* ov-typeinfo.cc (do_register_unary_op,
+	do_register_non_const_unary_op, do_register_binary_op,
+	do_register_assign_op, do_register_assignany_op,
+	do_register_pref_assign_conv, do_register_widening_op):
+	Print warning if installing a duplicate function.
+
+2003-09-10  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* data.cc, ov-base.cc, ov-base.h, ov.h, ov.cc, ov-re-mat.h,
+	ov-scalar.h, ov-re-nd-array.h, ov-re-nd-array.cc: Use NDArray, not
+	ArrayN<double>.
+
+2003-09-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::double_nd_array_value): New function.
+	(octave_value::is_real_nd_array): New function.
+
+	* ov-base.cc (octave_base_value::double_nd_array_value): New function.
+	* ov-base.h: Provide decl.
+	(octave_base_value::is_real_nd_array): New function.
+
+2003-09-09  Petter Risholm  <risholm at stud.ntnu.no>
+
+	* ov-re-mat.h (octave_matrix::double_nd_array_value): New function.
+	* ov-scalar.h (octave_scalar::double_nd_array_value): New function.
+
+	* ov-re-nd-array.cc (octave_double_nd_array::assign): New function.
+	(octave_double_nd_array::try_narrowing_conversion): Likewise.
+	(octave_double_nd_array::valid_as_scalar_index): Likewise.
+	(octave_double_nd_array::double_value): Likewise.
+	(octave_double_nd_array::matrix_value): Likewise.
+	(octave_double_nd_array::complex_value): Likewise.
+	(octave_double_nd_array::convert_slice_to_matrix): Likewise.
+	* ov-re-nd-array.h: Provide decls.
+	(octave_double_nd_array::is_real_nd_array): New function.
+	(octave_double_nd_array::double_nd_array_value): New function.
+	(octave_double_nd_array::double_nd_array_value): New function.
+
+	* OPERATORS/op-m-nd.cc, OPERATORS/op-nd-m.cc,
+	OPERATORS/op-nd-nd.cc, OPERATORS/op-nd-s.cc, OPERATORS/op-s-nd.cc:
+	New files.
+	* Makefile.in (OP_XSRC): Add them to the list.
+
+2003-09-09  David Bateman  <dbateman at free.fr>
+
+	* OPERATORS/op-cs-s.cc (DEFBINOP): First arg is complex, second is
+	double.
+
+2003-09-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-cell.cc (tree_cell::rvalue): Don't assume that the number of
+	elements in a tree_argument_list is the same as the number of
+	objects it contains (cs-list objects expand to more than one).
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::do_init_element):
+	New function, extracted from tm_row_const::tm_row_const_rep::init.
+	(tm_row_const::tm_row_const_rep::init): Use it.
+	Also handle cs-list objects.
+
+	* ov-cs-list.cc (octave_cs_list::print_raw): New function.
+	* ov-cs-list.h (octave_cs_list::print_raw): Provide decl.
+	* ov-list.h (octave_list::lst): Now protected instead of private.
+
+2003-09-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (subplot_style::columns_ok): Allow boxes style to
+	have 2 columns as well.
+
+2003-08-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (Fls): Check EAGAIN to avoid losing output.
+	* toplev.cc (run_command_and_return_output): Likewise.
+
+2003-08-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-str-s.cc, OPERATORS/op-str-m.cc: New files.
+	* Makefile.in (OP_XSRC): Add them to the list.
+
+2003-08-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (maybe_add_or_del_packages): Use source_file instead
+	of parse_and_execute.
+	* parse.y (source_file): New function.
+	(Fsource): Use it.
+	* parse.h (source_file): Provide decl.
+
+2003-08-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (octave_vsnprintf): Copy va_list to avoid using more
+	than once.
+
+2003-08-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (octave_vsnprintf): Call octave_raw_vsnprintf instead
+	of calling vsnprintf directly.
+	(octave_vsnprintf) [HAVE_C99_VSNPRINTF]: Declare nchars to be size_t.
+
+2003-08-06  Heine Kolltveit  <kolltvei at idi.ntnu.no>
+
+	* utils.cc (check_dimensions(Array<int>&, char),
+	get_dimensions(octave_value&, char, Array<int>&): New functions.
+	* utils.h (check_dimensions (Array<int>&, char), 
+	get_dimensions (octave_value&, char, Array<int>&)): Provide decl.
+
+	* data.cc (fill_matrix): Also create N-d arrays.
+ 	(Fones, Fzeros): Handle more than 2 args to create N-d arrays.
+
+2003-07-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (make_diag): Use std::abs instead of our own ABS macro.
+
+	* utils.cc (identity_matrix): Move here from data.cc.
+	(identity_matrix): Use std::min instead of our own MIN macro.
+
+	* utils.h (identity_matrix): Provide decl.
+
+	* DLD-FUNCTIONS/svd.cc (Fsvd): Improve handling of empty matrix arg.
+
+	* ov.cc (octave_value(const ArrayN<Complex>&)): New constructor.
+	* ov.h (octave_value(const ArrayN<Complex>&)): Provide decl.
+
+2003-07-30  Heine Kolltveit  <kolltvei at idi.ntnu.no>
+
+	* ov.cc (octave_value(const ArrayN<double>&)): New constructor.
+	* ov.h (octave_value(const ArrayN<double>&)): Provide decl.
+
+2003-07-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (Vpropagate_empty_matrices): Delete decl.
+	* ov.cc: (Vpropagate_empty_matrices): Delete.
+	(propagate_empty_matrices): Delete.
+	(symbols_of_ov): Delete DEFVAR for propagate_empty_matrices.
+
+	* utils.cc (empty_arg): Behave as though propagate_empty_matrices
+	is always 1.
+	* ov-range.cc (octave_range::is_true): Likewise.
+	* ov-base-mat.cc (octave_base_matrix<MT>::is_true): Likewise.
+
+	* octave.cc (maximum_braindamage): Also set
+	warn_matlab_incompatible to TRUE.
+
+	* lex.l (Vwhitespace_in_literal_matrix): Delete.
+	(whitespace_in_literal_matrix): Delete.
+	(symbols_of_lex): Delete DEFVAR for whitespace_in_literal_matrix.
+	(<MATRIX_START>{S}*\,{S}*, <MATRIX_START>{S}+,
+	(<MATRIX_START>{S}*{COMMENT}{SNLCMT}*,
+	<MATRIX_START>{S}*{NL}{SNLCMT}*, maybe_unput_comma): Behave as though
+	old Vwhitespace_in_literal_matrix varaible is always 1.
+
+	* octave.cc (maximum_braindamage): Don't set
+	whitespace_in_literal_matrix.
+
+2003-07-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-lib): Use $(INSTALL), not
+	$(INSTALL_PROGRAM) for $(SHLLIB) files.
+
+2003-07-29  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in: Don't need special system.c for Cygwin.
+	* oct-procbuf.cc: Use popen rather than fork/exec for Windows.
+
+2003-07-28  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* sysdep.cc (CYGWIN_init): Convert TMPDIR to system agnostic path.
+
+2003-07-25  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* help.cc (try_info, display_help_text):
+	Protect spaces in filenames with quotes.
+	* oct-hist.cc (do_edit_history): Likewise.
+	* pt-plot.cc (open_plot_stream): Likewise.
+
+2003-07-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (get_size, octave_base_stream::error,
+	octave_base_stream::do_gets, octave_base_stream::getl,
+	octave_base_stream::gets, octave_base_stream::do_scanf,
+	octave_base_stream::scanf, octave_base_stream::do_oscanf,
+	octave_base_stream::oscanf, do_printf_conv,
+	octave_base_stream::do_printf, octave_base_stream::printf,
+	octave_base_stream::puts, octave_base_stream::invalid_operation,
+	octave_stream::getl, octave_stream::gets, octave_stream::scanf,
+	octave_stream::oscanf, octave_stream::printf, octave_stream::puts,
+	octave_stream::invalid_stream_error): Handle name of calling
+	function for error messages as a std::string object.  Change all
+	callers.
+
+	* file-io.cc (Fprintf, Fputs): New functions, so we can get
+	function prefixes on error messages right.
+	(Ffgetl, Ffgets, Ffprintf, Fsprintf, Fputs, Ffscanf, Fsscanf):
+	Pass name of calling function to octave_stream method.
+
+	* oct-stream.h (octave_base_stream::do_char_scanf,
+	octave_base_stream::do_real_scanf): Delete unused decls.
+
+	* load-save.cc (read_mat5_binary_element): Correctly read struct
+	arrays.
+
+	* pt-misc.cc (tree_parameter_list::initialize_undefined_elements):
+	New args, warnfor and nargout.  Change all callers.
+	(symbols_of_pt_misc): New function.
+	(warn_undefined_return_values): New function.
+
+	* octave.cc (maximum_braindamage): Don't set
+	define_all_return_values.
+
+	* ov-usr-fcn.cc (ov_user_function::do_multi_index_op): Always
+	intiialize undefined elements in ret_list to [].
+	Never return last computed value.
+	(Vreturn_last_computed_value, Vdefine_all_return_values): Delete.
+	(return_last_computed_value, define_all_return_values): Delete.
+	(symbols_of_ov_usr_fcn): Delete DEFVARs for
+	return_last_computed_value, define_all_return_values, and
+	default_return_value.
+
+2003-07-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-misc.cc (tree_parameter_list::convert_to_const_vector):
+	Don't skip undefined elements.
+
+2003-07-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (maximum_braindamage): Don't set
+	default_global_variable_value or initialize_global_variables.
+
+	* pt-decl.cc (Vinitialize_global_variables): Delete.
+	(initialize_global_variables): Delete.
+	(symbols_of_pt_decl): Delete.
+	(tree_global_command::do_init): Default initial value is now
+	always [].
+
+2003-07-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (maximum_braindamage): Don't set default_eval_print_flag.
+
+	* parse.y (Vdefault_eval_print_flag): Delete: 
+	(default_eval_print_flag): Delete.
+	(symbols_of_parse): Delete DEFVAR for default_eval_print_flag.
+	(Feval, Fevalin): Return empty octave_value_list and turn printing
+	on in eval_string if nargout is zero.
+
+	* ov-list.cc (octave_list::assign): Check
+	Vwarn_resize_on_range_error, not Vresize_on_range_error.
+
+	* ov.cc (Vwarn_resize_on_range_error): New variable.
+	(warn_resize_on_range_error): New function.
+	(symbols_of_ov): Add DEFVAR for warn_resize_on_range_error.
+
+	* ov.cc (Vresize_on_range_error): Delete.
+	(resize_on_range_error): Delete.
+	(symbols_of_ov): Delete DEFVAR for resize_on_range_error.
+
+	* pt-mat.cc (Vwarn_empty_list_elements): New variable.
+	(warn_empty_list_elements): New function.
+	(symbols_of_pt_mat): Add DEFVAR for warn_empty_list_elements.
+	(tm_row_const::tm_row_const_rep::init, tm_const::init): 
+	Check Vwarn_empty_list_elements, not Vempty_list_elements_ok.
+
+	* pt-mat.cc (Vempty_list_elements_ok): Delete.
+	(empty_list_elements_ok): Delete.
+	(symbols_of_pt_mat): Delete DEFVAR for empty_list_elements_ok.
+
+2003-07-11  Russell Standish  <R.Standish at unsw.edu.au>
+
+	* TEMPLATE-INST/Array-tc.cc (resize_fill_value): Provide
+	specialization.
+
+2003-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strfns.cc (Fchar): Force string conversions without warnings.
+
+	* ov.h (octave_value::convert_to_str, octave_value::all_strings,
+	octave_value::string_value, octave_value:convert_to_str_internal):
+	New arg, force.  Fix all derived classes to match.
+
+	* strfns.cc (Fchar): Temporarily reset Vwarn_num_to_str to avoid
+	warnings.
+
+	* ov.cc (convert_to_str): New arg, force.
+
+	* octave.cc (maximum_braindamage): Don't set treat_neg_dim_as_zero.
+
+	* utils.cc (Vwarn_neg_dim_as_zero): New variable.
+	(warn_neg_dim_as_zero): New function.
+	(symbols_of_utils): Add DEFVAR for warn_neg_dim_as_zero.
+	(check_dimensions): Check Vwarn_neg_dim_as_zero, not
+	Vtreat_neg_dim_as_zero.
+
+	* utils.cc (Vtreat_neg_dim_as_zero): Delete.
+	(treat_neg_dim_as_zero): Delete.
+	(symbols_of_utils): Delete DEFVAR for treat_neg_dim_as_zero.
+
+2003-07-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (maximum_braindamage): Don't set prefer_column_vectors.
+
+	* ov.cc (Vprefer_column_vectors): Delete.
+	(prefer_column_vectors): Delete.
+	(symbols_of_ov): Delete DEFVAR for prefer_column_vectors.
+
+	* octave.cc (maximum_braindamage): Don't set do_fortran_indexing.
+
+	* ov-re-mat.cc (octave_matrix::double_value,
+	octave_matrix::complex_value): Use Vwarn_fortran_indexing, not
+	Vdo_fortran_indexing.
+	* ov-range.cc (octave_range::double_value,
+	octave_range::complex_value): Likewise.
+	* ov-cx-mat.cc (octave_complex_matrix::double_value,
+	octave_complex_matrix::complex_value): Likewise.
+	* ov-ch-mat.cc (octave_char_matrix::double_value,
+	octave_char_matrix::complex_value): Likewise.
+	* ov-bool-mat.cc (octave_bool_matrix::double_value,
+	octave_bool_matrix::complex_value): Likewise.
+
+	* ov.cc (Vwarn_fortran_indexing): New variable.
+	(warn_fortran_indexing): New function.
+	(symbols_of_ov): Add DEFVAR for warn_fortran_indexing.
+	(octave_value::vector_value, octave_value::int_vector_value,
+	(octave_value::complex_vector_value): Check
+	Vwarn_fortran_indexing, not Vdo_fortran_indexing.
+
+	* ov.h (Vwarn_fortran_indexing): Provide decl.
+
+	* ov.cc (Vdo_fortran_indexing): Delete unused variable.
+	(do_fortran_indexing): Delete unused function.
+	(symbols_of_ov): Delete DEFVAR for do_fortran_indexing.
+	* ov.h (Vdo_fortran_indexing): Delete decl.
+
+	* ov.cc (octave_value::convert_to_str): Call convert_to_str_internal.
+	(octave_value::convert_to_str_internal): New virtual function.
+	Rename all derived class convert_to_str functions to match.	
+
+	* variables.cc (generate_struct_completions): Set
+	discard_warning_messages, not Vwarning_option.  Also protect
+	warning_state.
+
+	* parse.y (fold): Temporarily discard warning messages.
+	Also protect warning_state.
+
+	* error.cc (discard_warning_messages): New variable.
+	(vwarning): Use it.
+	(warning): Don't print backtrace if discard_warning_messages is true.
+
+	* ov.cc (octave_value::convert_to_str):
+	Handle type conversion warning here.
+
+	* gripes.cc (gripe_implicit_conversion):
+	New function accepting std::string args.
+
+	* octave.cc (maximum_braindamage): Don't set
+	implicit_num_to_str_ok or implicit_str_to_num_ok.
+
+	* ov-base.cc (octave_base_value::char_matrix_value):
+	Vimplicit_num_to_str_ok no longer exists.
+	(octave_base_value::all_strings): Likewise.
+	(octave_base_value::string_value): Likewise.
+
+	* ov-str-mat.cc (octave_char_matrix_str::matrix_value): Warn based
+	on Vwarn_str_to_num instead of Vimplicit_str_to_num_ok.
+
+	* ov.cc (Vwarn_num_to_str, Vwarn_str_to_num): New variables.
+	(warn_num_to_str, warn_str_to_num): New functions.
+	(symbols_of_ov): Add DEFVARs for warn_num_to_str and Vwarn_str_to_num.
+	* ov.h (Vwarn_num_to_str, Vwarn_str_to_num): Provide decl.
+
+	* ov.cc (Vimplicit_num_to_str_ok, Vimplicit_str_to_num_ok):
+	Delete unused variables.
+	(implicit_num_to_str_ok, implicit_str_to_num_ok):
+	Delete unused functions.
+	(symbols_of_ov): Delete DEFVARs for implicit_num_to_str_ok and
+	implicit_str_to_num_ok.
+	* ov.h (Vimplicit_num_to_str_ok, Vimplicit_str_to_num_ok):
+	Delete decls.
+
+	* pt-mat.cc (tree_matrix::rvalue): Vimplicit_num_to_str_ok no
+	longer exists.
+
+	* ov.cc (Vwarn_imag_to_real): New variable.
+	(warn_imag_to_real): New function.
+	(symbols_of_ov): Add DEFVAR for warn_imag_to_real.
+	* ov.h (Vwarn_imag_to_real): Provide decl.
+
+	* ov.cc (Vok_to_lose_imaginary_part): Delete unused variable.
+	(ok_to_lose_imaginary_part): Delete unused function.
+	(symbols_of_ov): Delete DEFVAR for ok_to_lose_imaginary_part.
+	* ov.h (Vok_to_lose_imaginary_part): Delete decl.
+
+	* ov-complex.cc (octave_complex::double_value): Warn based on
+	Vwarn_imag_to_real instead of Vok_to_lose_imaginary_part.
+	(octave_complex::matrix_value): Likewise.
+	* ov-cx-mat.cc (octave_complex_matrix::double_value): Likewise.
+	(octave_complex_matrix::matrix_value): Likewise.
+
+	* octave.cc (maximum_braindamage): Don't set ok_to_lose_imaginary_part.
+
+2003-07-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (sig_hup_or_term_handler): New function.
+	(install_signal_handlers): Install sig_hup_or_term_handler for
+	SIGHUP and SIGTERM instead of generic_sig_handler.
+	(Vsighup_dumps_octave_core, Vsigterm_dumps_octave_core):
+	New static variables.
+	(sighup_dumps_octave_core, sigterm_dumps_octave_core):
+	New static functions.
+	(symbols_of_sighandlers): Add DEFVARs for sighup_dumps_octave_core
+	and sigterm_dumps_octave_core.
+
+	* defaults.h.in (OCTAVE_LOCALAPIFCNFILEDIR, OCTAVE_LOCALAPIOCTFILEDIR):
+	Subsitute new variables. 
+
+	* defun.cc (check_version): Compare version to OCTAVE_API_VERSION,
+	not OCTAVE_VERSION.  Mismatch is now fatal.
+	* defun-int.h (DEFINE_FUN_INSTALLER_FUN3): Pass
+	OCTAVE_API_VERSION instead of OCTAVE_VERSION to check_version.
+	* version.h (OCTAVE_API_VERSION): New macro, initial value api-v1.
+
+	* defaults.cc (Vdefault_exec_path): New static variable.
+	(set_default_default_exec_path): New function.
+	(install_defaults): Call it.
+	(exec_path): Use it.
+	(default_exec_path): New function.
+	(symbols_of_defaults): Add DEFVAR for DEFAULT_EXEC_PATH.
+
+2003-07-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.h.in (OCTAVE_LOCALSTARTUPFILEDIR, OCTAVE_STARTUPFILEDIR):
+	Set values directly instead of constructing them.
+
+2003-06-28  Arno J. Klaassen  <arno at heho.snv.jussieu.fr>
+
+	* toplev.cc (octave_config_info): Key for OCTAVE_CONF_DEFS should
+	be DEFS, not UGLY_DEFS.
+
+2003-06-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.50.
+
+2003-06-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (symbol_exist): Distinguish between user and dld
+	functions loaded in memory.
+
+2003-06-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-mat.cc (tm_row_const::init, tm_const::init): Don't ignore
+	empty matrices that have one non-zero dimension.
+
+	* variables.cc (symbol_exist): Use dir_path::find_first_of to
+	search for .oct and .m files.
+
+	* ov-base.cc (octave_base_value::subsasgn): Also allow type
+	conversion for empty numeric objects with more than one index.
+	* ov-base-mat.cc (octave_base_matrix<T>::subsasgn): Likewise.
+
+2003-06-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (do_who): New arg, return_list.  If return_list is
+	true, return values in cell or struct arrays instead of printing.
+	(Fwho, Fwhos): If nargout is 1, ask do_who to return lists of values.
+	* oct-map.h (Octave_map (const std::string&, const octave_value_list&):
+	New constructor.
+
+2003-06-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-idx.cc (tree_index_expression::rvalue):
+	Correctly handle index expressions like x(end).f(end).
+	(tree_index_expression::lvalue): Likewise.
+
+	* pt-arg-list.cc (F__end__): Add nr, nc info to error messages.
+
+2003-06-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (set_format (const Matrix&, int&, double&)): Ask
+	any_element_is_negative to return true for negative zero as well.
+	(set_format (const ComplexMatrix&, int&, int&, double&)): Likewise.
+
+2003-06-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (main_loop): Set octave_interrupt_hook and
+	octave_bad_alloc_hook to unwind_protect::run_all here.
+	(recover_from_exception): Don't call unwind_protect::run_all here.
+
+	* pt-except.cc (do_catch_code): Return immediately if
+	octave_interrupt_immediately is nonzero.
+
+	* sighandlers.cc (sigint_handler): If jumping, don't set
+	octave_interrupt_state.
+
+2003-06-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (get_save_type): Avoid all save types other than
+	LS_DOUBLE to avoid apparent Matlab bugs.
+
+2003-06-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (frob_function, parse_fcn_file): Handle help_buf as
+	stack of strings.
+	* lex.l ({CCHAR}): Handle help_buf as stack of strings.
+	Store text returned from grab_help_text in help_buf here.
+	(reset_parser): Handle help_buf as stack of strings.
+	(prep_for_nested_function): Push empty string onto help_buf stack.
+	(grab_help_text): Return help text instead of storing it in help_buf.
+	* parse.h, parse.y (help_buf): Now a stack of strings.
+
+	* oct-stream.cc (printf_value_cache::string_value): Don't attempt
+	to extract values when none are available.
+
+2003-06-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (Vgnuplot_has_multiplot): Delete variable.
+	(gnuplot_has_multiplot): Delete.
+	(symbols_of_pt_plot): Delete DEFVAR for gnuplot_has_multiplot.
+
+2003-05-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.49.
+
+2003-05-28  Teemu Ikonen  <tpikonen at pcu.helsinki.fi>
+
+	* load-save.cc (save_mat5_binary_element, save_mat_binary_data):
+	Allow saving of non-7-bit ASCII characters.
+
+2003-05-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (FINISH_CHARACTER_CONVERSION,
+	octave_base_stream::do_scanf): Do a better job of resizing for
+	charachter conversions.
+
+2003-05-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cx-mat.cc (octave_complex_matrix::assign): Move definition here.
+	* ov-cx-mat.h: From here.
+
+2003-05-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-range.cc (octave_range::try_narrowing_conversion): Convert to
+	[](1x0) instead of [](0x0) if range is empty.
+
+2003-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Handle DESTDIR.
+
+2003-05-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l: Use yyunput (X, yytext) instead of unput (X) for newer
+	versions of flex.
+
+2003-05-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.48.
+
+2003-05-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.47.
+
+2003-05-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_ascii_data): If saving a range with
+	non-integer base, limit, or increment, save as matrix instead.
+	(get_save_type): Avoid unsigned types.
+
+2003-04-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (initialize_pathsearch): Don't save old and set new
+	value of TEXMFDBS.
+
+	* toplev.cc (restore_texmfdbs_envvar): Delete function.
+	(Fsystem): Don't set and reset TEXMFDBS.
+
+	* toplev.h, toplev.cc (octave_original_texmfdbs): Delete variable.
+
+2003-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/getpwent.cc (Fgetpwnam): Delete unnecessary
+	c_str() method.
+
+2003-04-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc: Include <memory> for auto_ptr.
+
+2003-04-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (octave_config_info): Delete LIBKPATHSEA from struct.
+	* oct-conf.h.in: Don't substitute LIBKPATHSEA.
+
+	* octave.cc (octave_main): Don't call dir_path::set_program_name.
+
+2003-04-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-file.h (octave_file::empty_clone): Create an octave_scalar
+	object, not an octave_file object.
+
+2003-04-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (hdf5_read_next_data): Extract list before
+	assigning to map element.
+	(add_hdf5_data): Prefix faked names with '_' so they are valid
+	identifiers.
+
+2003-03-24  Mats Jansson  <mats.e.jansson at home.se>
+
+	* syscalls.cc (Fkill): Fixed docstring typo.
+
+2003-03-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.h (octave_cell::is_matrix_type): New function.
+
+2003-03-09  Duncan Temple Lang  <duncan at research.bell-labs.com>
+
+	* octave.cc (octave_main): New arg, embedded.
+	* octave.h: Fix decl.
+	* main.c: Pass 0 for embedded here.
+
+2003-03-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.46.
+
+	* oct-conf.h.in: Undo previous change.
+
+	* load-save.cc (read_mat5_binary_element): Handle structure arrays.
+	(save_mat5_binary_element): Likewise.
+
+2003-03-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.cc (octave_cell::subsasgn): Use make_unique in
+	appropriate places to preserve copy on write semantics.
+
+	* oct-conf.h.in: Substitute OCTAVE_CONF_KPATHSEA_INCFLAGS.
+
+	* oct-stdstrm.h (octave_stdiostream::output_stream): Return stream
+	if mode is out, not in.
+
+2003-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strfns.cc (Fchar): New function.
+
+	* ov-cell.cc (octave_cell::all_strings): Allow elements to be
+	string arrays.
+	* ov.cc (octave_value::all_strings, octave_value::convert_to_str):
+	New optional arg, pad.  Change all derived classes.
+
+	* ov-struct.cc (Ffieldnames, Fisfield): Move here from data.cc.
+
+	* data.cc (Ffieldnames): Rename from Fstruct_elements.  Return
+	cell array instead of a string array.
+	(Fisfield): Rename from struct_contains.
+
+2003-02-22  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* toplev.cc: Put config info in array of strings, then convert to map.
+
+2003-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (symbol_exist): For names like foo.bar, don't omit
+	the part after the dot.
+
+2003-02-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (fun_to_call): New static variable.
+	(octave_main): Pass it to main_loop.
+	(long_opts): Accept --funcall.
+	(usage_string, verbose_usage): Add --funcall.
+
+	* toplev.cc (main_loop): New arg, fun_to_call.  If non-empty,
+	evaluate this function before continuing.
+
+2003-02-21  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* file-io.cc (Fmkstemp): Use OCTAVE_LOCAL_BUFFER instead of using
+	std::auto_ptr directly.
+
+2003-02-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h, ov.cc (octave_value (long long int)): New constructor.
+	(octave_value (unsigned long long int)): Likewise.
+
+	* oct-obj.h (octave_value_list::operator delete): Handle systems
+	with or without placement delete.
+
+2003-02-21  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* utils.cc (octave_vsnprintf): Return value of vsnprintf is int,
+	not size_t.  Make sure there is some space left in the buffer for
+	vsnprintf versions which return the number of characters written
+	even when the buffer is too short.
+
+2003-02-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* debug.cc (get_user_function): Use dynamic_cast, not static_cast.
+
+	* ov-usr-fcn.cc (octave_user_function::traceback_error): Now const.
+
+	* ov.cc (octave_value (const octave_fcn_handle&)): New constructor.
+	(octave_value::fcn_handle_value): New virtual function.
+	* ov-base.cc (octave_value::fcn_handle_value): Provide default.
+	* ov-usr-fcn.cc (octave_user_function::stash_fcn_file_name): New
+	arg, nm.  Change all callers.
+	* ov-fcn.h (octave_function::is_nested_function): New virtual function.
+	* parse.y (get_feval_args): New function.
+	(feval (octave_function *, const octave_value_list&, int)): Likewise.
+	(feval (const octave_value_list&, int)): Allow the first arg to be
+	a function handle as well as a string.
+	* variables.cc (load_function): New function.
+	* pt-walk.h, pt-pr-code.h, pt-pr-code.cc, pt-check.h, pt-check.cc,
+	pt-bp.h, pt-bp.cc: Handle new tree_fcn_handle class.
+	* pt-all.h: Include pt-fcn-handle.h.
+	* pt-fcn-handle.h, pt-fcn-handle.cc, ov-fcn-handle.h,
+	ov-fcn-handle.cc: New files.
+
+2003-02-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (FCN_HANDLE): New token type.
+	(fcn_handle): New non-terminal.
+	(primary_expr): Also accept fcn_handle.
+	(tree_fcn_handle_type): New %type.
+	(union): New field, tree_fcn_handle_type.
+	(make_fcn_handle): New function.
+
+	* lex.l (@{IDENT}): Recognize function handle syntax.
+	(@): Don't recognize "@" as a single token.
+
+	* load-save.cc (struct hdf5_callback_data): Provide constructor.
+	(hdf5_callback_data::name, hdf5_callback_data::doc): Now
+	std::string instead of char*.  Change all uses.
+
+2003-02-18  Roger Banks  <rbanks at colsa.com>
+
+	* load-save.cc (read_ascii_data, read_ascii_data,
+	read_mat5_binary_element, save_mat5_binary_element,
+	save_ascii_data): Handle cell arrays.
+	(write_mat5_cell_array): New function.
+
+2003-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DLD_XSRC): Delete log.cc from the list.
+	Add sqrtm.cc to the list.
+
+	* DLD-FUNCTIONS/log.cc: Delete.
+
+2003-02-18  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* DLD-FUNCTIONS/sqrtm.cc: New file.
+
+2003-02-18  David Bateman  <dbateman at free.fr>
+
+	* DLD-FUNCTIONS/lu.cc (Flu): Allow non-square matrices.
+
+2003-02-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_binary_file_header, do_load, do_save,
+	write_header): No longer static.
+	(load_save_format): Move enum decl to load-save.h.
+
+2003-02-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stdstrm.h, oct-stdstrm.cc (octave_base_stdiostream,
+	octave_iostdiostream, octave_istdiostram, octave_ostdiostream):
+	Combine all functionality into one class, octave_stdiostream.
+	Change all uses.	
+
+	* file-io.cc (Ftmpfile, Fmkstemp): New functions.
+	* oct-stdstrm.h (octave_iostdiostream): New class.
+	(octave_istdiostream::octave_istdiostream,
+	octave_istdiostream::create,
+	octave_ostdiostream::octave_ostdiostream, octave_ostdiostream::create, 
+	octave_iostdiostream::octave_iostdiostream,
+	octave_iostdiostream::create): Make close function the last arg.
+	Change all uses.
+
+	* c-file-ptr-stream.h (io_c_file_ptr_stream): New class.
+
+2003-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (maximum_braindamage): Set boolean built-in variables
+	to true and false instead of 1.0 and 0.0.
+	(octave_main): Likewise.
+	* error.cc (Fwarning): Likewise.
+
+	* pager.cc (Fmore): Make the no-arg case work too.
+
+	* ov-str-mat.h (octave_char_matrix_str::is_real_type, 
+	octave_char_matrix_str::is_matrix_type,
+	octave_char_matrix_str::is_numeric_type): Always return false.
+
+2003-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (<CCHAR>): If we are parsing a command, reset start state.
+	Use BEGIN (INITIAL) instead of BEGIN 0.  Use parens around start
+	state in BEGIN statements.
+
+2003-02-13  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* variables.cc (Fmlock, Fmunlock, Fmislocked): New functions.
+
+	* variables.cc (mlock, munlock, mislocked): New functions.
+	* variables.h: Provide decls.
+
+	* symtab.h (symbol_record::unmark_static): New function.
+
+2003-02-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc (reset_error_handler): New function.
+	* toplev.cc (main_loop): Use it here.
+	* lex.l (reset_parser): Don't set error_state and warning_state here.
+	* parse.y (eval_string): Reset parser before calling yyparse.
+
+2003-01-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Ffmod): New function.
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::underflow_common): New
+	function.
+	* c-file-ptr-stream.h (c_file_ptr_buf::underflow,
+	c_file_ptr_buf::uflow): Use it.
+	(c_file_ptr_buf): Derive from std::streambuf, not OCTAVE_STD_FILEBUF.
+	Don't cache file descriptor.
+
+2003-01-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/minmax.cc: Move min and max functions from here to
+	liboctave/dMatrix.cc and liboctave/CMatrix.cc.
+
+2003-01-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/rand.cc: Rewrite to use new octave_rand functions.
+
+2003-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_printf): Handle values
+	outside the range of integers in int conversions for
+	compatibilitiy wtih Matlab.
+
+2003-01-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (get_mat_data_input_line): Handle lines with CR
+	only as separator.
+
+	* oct-stream.cc (octave_base_stream::do_printf): Handle Inf and
+	NaN in int conversions for compatibility with Matlab.
+
+	* data.cc (symbols_of_data): Doc fix for realmin.
+
+	* cutils.c (octave_raw_vsnprintf): New function.
+	* utils.cc (octave_snprintf): Move here from cutils.c.
+	(octave_Vsnprintf): Likewise.  Allow octave_raw_vsnprintf to be
+	interrupted.
+	* utils.h (octave_vsnprintf, octave_snprintf): No longer extern "C".
+
+2003-01-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-loop.cc (tree_complex_for_command::eval): Fix typo.
+
+2003-01-16  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* mk-oct-links: Use $SED if set.
+	* mkbuiltins: Likewise.
+	* mkdefs: Likewise.
+	* mkdocs: Likewise.
+	* mkgendoc: Likewise.
+	* mkops: Likewise.
+
+2003-01-11  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in (gendoc$(BUILD_EXEEXT)): Pass $(BUILD_CXXFLAGS) and
+	$(BUILD_LDFLAGS) to compiler.
+
+2003-01-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (Fassignin): New function.
+
+2003-01-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (make_sig_struct): New function.
+	(symbols_of_sighandlers): Add DEFCONST for SIG struct.
+
+	* syscalls.cc (Fkill): New function.
+
+2003-01-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (get_size): If only one dimension is specified and
+	it is zero, also set the other dimension to zero instead of one.
+
+2003-01-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc [__DECCXX]: Add a kluge for some missing template
+	functions.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.cc (octave_vr_val): Assert vr_list != 0, not vr_list.
+	* variables.cc (builtin_string_variable, builtin_any_variable,
+	builtin_real_scalar_variable, bind_builtin_variable): Likewise.
+
+	* TEMPLATE-INST/Array-tc.cc: Provide specialization of
+	Array<octave_value>::resize_fill_value before instantiation of
+	Array<octave_value>.
+
+	* oct-obj.h (octave_value_list::operator delete): Define version
+	of delete operator to correspond to placement new operator.
+
+	* mkgendoc: In generated code, define __USE_STD_IOSTREAM if using
+	Compaq C++.
+
+	* Makefile.in (distclean): Also remove doc-files and gendoc.cc.
+
+	* input.cc (initialize_command_input): Use const for
+	initialization of char * from literal string.
+
+	* pt-plot.cc (subplot::extract_plot_data): Call single_subsref,
+	not subsref.
+	* ov.h, ov.cc (single_subsref (const std::string&, const
+	octave_value_list&)): Rename from subsref.
+
+	* symtab.cc (symbol_table::rename): Explicitly convert C string to
+	std::string so type of second arg of ?: matches third.
+	(symbol_table::lookup): Likewise.
+
+	* mappers.cc: Remove std:: qualifiers from C library names.
+
+2003-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-exp.h (tree_expression::has_magic_end): New pure virtual function.
+	* pt-id.h (tree_identifier::has_magic_end): New function.
+	* pt-colon.h (tree_colon_expression::has_magic_end): Likewise.
+	* pt-idx.h (tree_index_expression::has_magic_end): Likewise.
+	* pt-const.h (tree_constant::has_magic_end): Likewise.
+	* pt-unop.h (tree_unary_expression::has_magic_end): Likewise.
+	* pt-binop.h (tree_binary_expression::has_magic_end): Likewise.
+	* pt-assign.h (tree_multi_assignment::has_magic_end): Likewise.
+	(tree_simple_assignment::has_magic_end): Likewise.
+	* pt-mat.cc (tree_matrix::has_magic_end): Likewise.
+	* pt-arg-list.cc (tree_argument_list::has_magic_end): Likewise.
+
+	* pt-arg-list.cc (tree_argument_list::append): Check all
+	expression types for magic end token..
+
+	* file-io.cc (Ftmpnam): Improve error checking.
+	(symbols_of_file_io): Move definition of P_tmpdir here from dirfns.cc.
+
+	* dirfns.cc (symbols_of_dirfns): Install new built-in constant
+	P_tmpdir.
+
+2003-01-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (symbols_of_dirfns): New function.
+	Install new built-in constant filesep.
+
+	* utils.cc (Fisvaranme): New function.
+	(valid_identifier): Identifiers can't start with digits!  Doh!
+
+	* lex.l (Fiskeyword): New function.
+
+	* Makefile.in (INCLUDES): Don't forget base-list.h.
+
+	* symtab.cc (symbol_record::define): If definition already exists,
+	redefine it instead of replacing it.
+
+	* variables.cc (symbol_exist): Don't use reference when handling
+	sr->def ().
+
+	* pt-plot.cc (save_in_tmp_file): octave_value arg is now const.
+	* pt-misc.cc (tree_parameter_list::initialize_undefined_elements):
+	Likewise.
+
+	* symtab.cc (symbol_record::clear): Don't do anything if the
+	symbol record is already undefined.
+
+2003-01-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-arg-list.cc (tree_argument_list::append): New function.
+	(tree_argument_list::convert_to_const_vector): Don't save and
+	set pointer to indexed object if list_includes_magic_end is false.
+	* pt-arg-list.h (tree_argument_list::append): Provide decl.
+	(tree_argument_list::list_includes_magic_end): New data member.
+	(tree_argument_list::tree_argument_list): Initialize it.
+
+	* ov-base.cc (octave_base_value::char_matrix_value,
+	octave_base_value::all_strings,	octave_base_value::string_value):
+	Attempt conversions here if Vimplicit_num_to_num_ok is true.
+
+	* ov.cc (Vimplicit_num_to_str_ok): Move here from pt-mat.cc and
+	make extern.
+	* ov.h: Provide decl.
+
+	* oct-stream.cc (printf_value_cache::looking_at_string): Delete.
+	(printf_value_cache::string_value): Just attempt conversion.
+	(octave_base_stream::do_printf): When doing '%s' format,
+	just attempt converstion.
+
+	* file-io.cc (Ffread): Allow size to be omitted even when
+	additional arguments are given.
+
+2002-12-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-arg-list.cc (F__end__): Fail if rows or columns is negative.
+	(tree_argument_list::convert_to_const_vector): Only protect and
+	save pointer to the indexed object if it is a constant.
+
+	* syscalls.cc (Fmkfifo): Use long_value instead of cast.
+
+	* ov.h (octave_value::short_value, octave_value::ushort_value,
+	octave_value::uint_value, octave_value::long_value,
+	octave_value::ulong_value): New functions.
+
+	* syscalls.cc (mk_stat_map, Fgetegid, getgid, geteuid): Likewise.
+	Delete unnecessary casts.
+	* file-io.cc (Ffgetl, Ffgets, Fftell, Fsscanf): Likewise.
+	* toplev.cc (Fsystem): Likewise.
+
+	* ov-file.h (octave_file::double_value,	octave_file::scalar_value):
+	Delete unnecessry cast.
+
+	* ov.cc (octave_value::octave_value): Add constructors for
+	octave_time, short int, unsigned short int, unsigned int, long
+	int, unsigned long int, 
+
+	* ov.h (octave_value::do_subsref (const std::string&, const
+	octave_value_list&)): Rename from subsref.  Change all derived classes.
+
+	* input.cc (generate_completion): Delete unused variable prefix_len.
+
+	* ov.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Delete volatile
+	qualifier for decls of static_type_id and t_id.
+	(DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Likewise, for def of t_id.
+
+2002-12-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (Ffile_in_path): Index args correctly.
+
+	* utils.cc (Ffile_in_path): Call error, not print_usage, for
+	invalid option error.
+	(Ffile_in_loadpath): Likewise.
+
+	* load-save.cc: Use OCTAVE_LOCAL_BUFFER instead of local automatic
+	arrays or using new/delete.
+
+	* lex.l (.): Try another approach to handling EOF here.
+
+	* load-save.cc (read_mat_ascii_data): Use isalpha and isalnum, not
+	::isalpha and ::isalnum.
+
+	* defaults.cc (maybe_add_or_del_packages): SCRIPT_FILE arg is now
+	a const reference type.
+
+	* ov.h (octave_value::subsref, octave_value::subsasgn,
+	octave_value::assign, octave_value::do_non_const_unary_op,
+	octave_value::numeric_assign): TYPE arg is now a const reference
+	type.  Change all derived classes.
+
+	* ov.cc (octave_value::subsref (const std::string&, const
+	octave_value_list&)): Move body here, from ov.h.
+
+	* octave.cc (octave_main): Return 0 at end of function to avoid
+	compiler warnings.
+
+2002-12-30  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* parse.y: Fix typo in doc string.
+
+2002-12-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/lpsolve.cc (Flpsolve): Rename from Flp_solve.
+	(Flpsolve_options): Rename ffrom Flp_solve_options.
+
+2002-12-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (Fevalin): New function.
+
+	* variables.cc (curr_caller_sym_tab): New global variable.
+	* variables.h: Provide decl.
+	(initialize_symbol_tables): Initialize it.
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Protect	and set it here.
+
+2002-12-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (search_path_for_file): Second arg now string_vector.
+	Use find_first_of, not find.
+	(search_path_for_all_files): Second arg now string_vector.
+	Use find_all_first_of, not find_all.
+	(Ffile_in_path): Accept cell array of strings as first argument.
+	(Ffile_in_loadpath): Likewise.
+
+	* dynamic-ld.cc (octave_dynamic_loader::load): New arg, file_name.
+	(octave_dynamic_loader::do_load): Likewise.  If file_name is not
+	empty, use it instead of searching in path.
+
+	* parse.y (load_fcn_from_file): Use find_first_of to perform search.
+
+	* ov-cell.cc (octave_cell::all_strings): New function.
+	* ov-cell.h: Provide decl.
+
+2002-12-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (function_end): If parsing a nested function, set
+	lexer_flags.parsing_nested_function to -1.
+	(frob_function): If lexer_flags.parsing_nested_function is
+	negative, set it to zero.
+	* lex.h (lexical_feedback::parsing_nested_function): Now int.
+	Change uses as needed.
+
+	* lex.l (NESTED_FUNCTION_BEGIN): Rename from NESTED_FUNCTION_START.
+	Now an exclusive start state.
+	(NESTED_FUNCTION_END): New exclusive start state.
+	(is_keyword): When matching a new function keyword in a nested
+	function context, explicitly return END and set start state to
+	NESTED_FUNCTION_END.
+	(.): Accept EOF here too.
+
+	* variables.cc (link_to_builtin_or_function): Maybe prepend parent
+	function name symbol name.
+
+	* parse.y (parent_function_name): New variable.
+	(fcn_name): New non-terminal.
+	(function2): Use it.
+	(parsed_fcn_name): Fold into fcn_name.
+	(function_end): Don't call check_for_garbage_after_fcn_def.
+	Set lexer_flags.parsing_nested_function on EOF.
+	* parse.h: Provide decl for parent_function_name.
+
+	* ov-usr-fcn.h (octave_user_function::mark_as_nested_function,
+	(octave_user_funciton::is_nested_function): New functions.
+	(octave_user_function::nested_function): New data member.
+	(octave_user_function::do_multi_index_op): Maybe protect and set
+	curr_parent_function pointer.
+	* parse.y (frob_function): Maybe mark as nested function.
+
+	* toplev.cc (curr_parent_function): New global variable.
+	* toplev.h: Provide decl.
+
+	* lex.l (check_for_garbage_after_fcn_def): Delete.
+	* lex.h: Delete decl.
+
+	* lex.l (prep_for_nested_function): New function.
+	(<NESTED_FUNCTION_START>): Use it here.
+	(is_keyword): And here.
+	(lookup_identifier): Maybe prepend parent function name.
+
+	* variables.cc (initialize_symbol_tables): Give names to the three
+	main symbol tables.
+	* symtab.cc (symbol_table::lookup, symbol_table::rename): Print
+	debugging info if Vdebug_symtab_lookups is nonzero.
+	(debug_symtab_lookups): New function.
+	(Vdebug_symtab_lookups): New static varaible.
+	(symbols_of_symtab): DEFVAR it.
+	* symtab.h (symbol_table::table_name): New member variable.
+	(symtab_count): New static member variable.
+	(symbol_table::symbol_table): Handle table name.
+
+2002-12-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (frob_function): Don't give nested functions the same
+	name as the function file.
+
+	* lex.h (lexical_feedback::parsing_nested_function): New data member.
+	* lex.l (lexical_feedback::init): Initialize it to false.
+	(<NESTED_FUNCTION_START>): Set lexer_flags.parsing_nested_function
+	to true.
+
+	* parse.y (symtab_context): Now a stack.  Change all uses.
+
+	* lex.l (NESTED_FUNCTION_START): New start state to handle
+	"function" keyword in a nested function context.
+	(prep_for_function): New function.
+	(is_keyword): Allow functions to be nested in function files.
+
+	* lex.l (is_keyword): Maybe ignore END tokens.
+	Increment and decrement end_tokens_expected as appropriate.
+	(handle_identifier): If is_keyword returns -1, return immediately.
+	({IDENT}{S}*): Do nothing if handle_identifier returns -1.
+
+	* parse.y (end_tokens_expected): New variable.
+	(parse_fcn_file): Protect and set it.
+
+	* parse.y (begin_obj_idx): Increment
+	lexer_flags.looking_at_object_index.
+	(postfix_expr): Decrement it as appropriate here.
+
+	* lex.h (lexical_feedback::looking_at_object_index): Now int.
+
+	* parse.y (postfix_expr): Reset	lexer_flags.looking_at_object_index
+	in () and {} cases too.
+
+2002-12-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-arg-list.cc (indexed_object, indexed_position):
+	New file-scope static variables.
+	(tree_argument_list::convert_to_const_vector): New arg, object.
+	Protect and set indexed_object and indexed_position.
+	(F__end__): New function.
+
+	* octave-lvalue.h (octave_lvalue::object): New member function.
+	* pt-idx.cc (make_value_list): New arg, object.  Change all
+	callers.  Pass object to convert_to_const_vector.
+
+	* lex.h (lexical_feedback.looking_at_object_index): New data member.
+	* lex.l (lexical_feedback::init): Initialize it.
+	(is_keyword): If looking at object index, end is not a keyword.
+	(handle_identifier): If end is not a keyword, transform it to __end__.
+	* parse.y (begin_obj_idx): New non-terminal.
+	(postfix_expr): Use it.
+
+	* defun.cc (install_builtin_function): New arg, can_hide_function.
+	* defun-int.h: Fix decl.
+	(DEFCONSTFUN_INTERNAL): New macro.
+	* defun.h (DEFCONSTFUN): New macro.
+	* mkbuiltins (XDEFCONSTFUN_INTERNAL): New macro.
+	* mkgendoc: Likewise.
+	* Makefile.in (DEFUN_PATTERN): Make it work for DEFCONSTFUN too.
+	* symtab.h (symbol_record::can_hide_function): New data member.
+	(symbol_record::symbol_record): Initialize it.
+	* symtab.cc (symbol_record::variable_reference): Also check
+	can_hide_function flag.
+
+2002-12-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/time.cc (extract_tm): Use int_value() instead of
+	casting double_value() to int.
+
+	* ov.cc (octave_value::next_subsref): Arg "skip" is now size_t.
+
+	* oct-obj.h (octave_value_list::octave_value_list (double),
+	octave_value_list::octave_value_list (const Matrix&),
+	octave_value_list::octave_value_list (const DiagMatrix&),
+	octave_value_list::octave_value_list (const RowVector&),
+	octave_value_list::octave_value_list (const ColumnVector&),
+	octave_value_list::octave_value_list (const Complex&),
+	octave_value_list::octave_value_list (const ComplexMatrix&),
+	octave_value_list::octave_value_list (const ComplexDiagMatrix&),
+	octave_value_list::octave_value_list (const ComplexRowVector&),
+	octave_value_list::octave_value_list (const ComplexColumnVector&),
+	octave_value_list::octave_value_list (const char *),
+	octave_value_list::octave_value_list (const std::string&),
+	octave_value_list::octave_value_list (const string_vector&),
+	octave_value_list::octave_value_list (double, double, double),
+	octave_value_list::octave_value_list (const Range&): Delete.
+	Adjust uses of octave_value/octave_value_list to handle this change.
+
+	* ov.cc (octave_value::octave_value (int)): New constructor.
+	* ov.h: Provide decl.
+	In files that construct integer-valued octave_value objects, use
+	ints instead of casing to double.
+
+2002-12-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_mat_ascii_data): Allow commas to separate values.
+	Try harder to convert filenames to valid identifiers in a
+	Matlab-compatible way.
+
+2002-12-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: No need to add $(LIBKPATHSEA) to LINK_DEPS, since
+	it is not included in liboctave.
+
+2002-12-18  JD Cole  <jdcole at san.rr.com>
+
+	* pt-check.cc (tree_checker::visit_subplot_axes,
+	tree_checker::visit_do_until_command): New functions.
+	* pt-check.h: Provide decl.
+
+2002-12-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fclear): Fix off-by-one error.
+
+	* oct-stream.cc (octave_base_stream::do_gets): Correctly read
+	last line of file even if it does not end with new line
+	character.
+
+	* pt-select.cc (equal): Don't look up == op, just try it and see
+	whether it works.
+
+	* oct-stream.cc (printf_format_list::printf_format_list):
+	Handle empty format string.
+
+2002-12-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-mat.cc (class tm_row_const::tm_row_const_rep): Derive from
+	octave_base_list instead of SLList.  Fix tm_row_const member
+	functions as needed, change all uses.
+	(class tm_const): Derive from octave_base_list, not SLList.  Fix
+	member functions as needed, change all uses.
+	* pt-mat.h (class tree_matrix): Derive from octave_base_list
+	instead of including SLList object as data member.  Fix member
+	functions as needed, change all uses.
+
+	* pt-idx.h (tree_index_expression::args,
+	tree_index_expression::arg_nm, tree_index_expression::dyn_field):
+	Now std::list, not SLList.  Fix member functions as needed, change
+	all uses.
+
+	* oct-map.h (Octave_map::map): Now std::map instead of CHMap.
+	Fix member functions as needed, change all uses.
+
+	* oct-lvalue.h (octave_lvalue::idx): Now std::list instead of
+	SLList object.  Fix member functions as needed, change all uses.
+
+	* dynamic-ld.cc (octave_shlib_list::lib_list): Now std::list
+	instead of DLList object.  Fix member functions as needed, change
+	all uses.
+
+	* ov.h (octave_value::subsref, octave_value::subsasgn):
+	Index arg is not std::list, not SLList.  Change all derived
+	classes, all uses.
+
+	* pt-stmt.h (tree_statement_list): Derive from base_octave_list
+	object instead of including SLList object as data member.  Fix
+	member functions as needed, change all uses.
+	* pt-select.h (tree_switch_case_list): Likewise.
+	(tree_if_command_list): Likewise.
+	* pt-misc.h (tree_parameter_list, tree_return_list,
+	tree_va_return_list): Likewise.
+	* pt-plot.h (subplot_list): Likewise.
+	* pt-mat.h (tree_matrix): Likewise.
+	* pt-decl.h (tree_decl_init_list): Likewise.
+	* pt-arg-list.h (tree_argument_list): Likewise.
+	* comment-list.h (octave_comment_list): Likewise.
+
+	* BaseSLList.cc, DLList.cc, Map.cc, SLList.cc, SLStack.cc,
+	Stack.cc: Delete.
+	* Makefile.in (DIST_SRC): Delete them from the list.
+
+	* BaseSLList.h, DLList.h, Map.h, Pix.h, SLList.h, SLStack.h,
+	Stack.h: Delete
+	* Makefile.in (INCLUDES): Delete them from the list.
+
+	* Map-oct-obj.cc, SLList-expr.cc, SLList-misc.cc, SLList-plot.cc,
+	SLList-tc.cc, SLList-tm.cc: Delete.
+	* Makefile.in (TI_XSRC): Delete them from the list.
+
+	* ov-base-mat.cc (octave_base_matrix::assign): Pass
+	MT::resize_fill_value () as third arg for ::assign.	
+
+	* Cell.h (Cell::resize_fill_value): Use empty Matrix object, not
+	undefined octave_value object.
+	(Cell::Cell (int, int, const octave_value&)): Use
+	resize_fill_value () as default value, not undefined octave_value
+	object.
+
+2002-12-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DEFUN_PATTERN): Make it work for DEFCMD too.
+
+	* base-list.h: New file.
+
+2002-12-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (octave_interpreter_ready): New global variable.
+	* toplev.h: Provide decl.
+
+	* octave.cc (octave_main): Call execute_default_pkg_add_files just
+	before executing startup files.  Set octave_interpreter_ready to
+	true before calling execute_default_pkg_add_files.
+
+	* defaults.cc (maybe_add_or_del_packages, default_load_path,
+	update_load_path_dir_path): New static functions. 
+	(set_default_path, loadpath): Call update_load_path_dir_path.
+	(symbols_of_defaults): Use DEFVAR, not DEFCONST for DEFAULT_LOADPATH.
+	(execute_default_pkg_add_files): New function.
+	* defaults.h.in: Provide decl.
+
+	* utils.cc (search_path_for_all_files): New function.
+	(Ffile_in_loadpath, Ffile_in_path): Allow search to return all
+	files in the path.
+
+	* Cell.cc (Cell (const string_vector&)): New constructor.
+
+	* oct-obj.cc (octave_value_list::assign): Allow optional fill
+	value for resizing.
+	* oct-map.cc (Octave_map::assign): Pass fill_value in initial
+	assignment too.
+
+2002-12-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* TEMPLATE-INST/Map-tc.cc, TEMPLATE-INST/Map-fnc.cc: Delete.
+	* Makefile.in (TI_XSRC): Delete them from the list.
+
+	* fn-cache.h (octave_fcn_file_name_cache::cache): Now std::map,
+	not CHMap.
+
+	* TEMPLATE-INST/SLStack-i.cc, TEMPLATE-INST/SLStack-ovl.cc,
+	TEMPLATE-INST/SLStack-pc.cc, TEMPLATE-INST/SLStack-str.cc,
+	TEMPLATE-INST/SLStack-sym.cc, TEMPLATE-INST/SLStack-tok.cc,
+	TEMPLATE-INST/SLStack-ue.cc, TEMPLATE-INST/SLStack-ui.cc:
+	Delete unnecessary files.
+	* Makefile.in (TI_XSRC): Delete them from the list.
+
+	* toplev.cc (octave_atexit_functions): Now std::stack, not SLStack.
+	* pt-plot.cc (tmp_files): Likewise. 
+	* lex.l (token_stack): Likewise.
+	(class bracket_brace_paren_nesting_level): Make context a data
+	member instead of deriving from SLStack object.
+	Use std::stack instead of SLStack.
+	* ov-usr-fcn.h (octave_user_function::saved_args): Likewise.
+	* symtab.h (symbol_record::context): Likewise.
+	(symbol_record::global_link_context): Likewise.
+
+	* unwind-prot.h (unwind_protect::elt_list): Rename from list.
+	Now std::stack, not SLStack.
+
+	* pt-stmt.h (tree_statement_list): Make list member data instead
+	of deriving from SLList object.
+	* pt-select.h (tree_switch_case_list): Likewise.
+	(tree_if_command_list): Likewise.
+	* pt-plot.h (subplot_list): Likewise.
+	* pt-mat.h (tree_matrix): Likewise.
+	* pt-decl.h (tree_decl_init_list): Likewise.
+	* pt-arg-list.h (tree_argument_list): Likewise.
+	* comment-list.h (octave_comment_list): Likewise.
+
+	* defun.h (DEFCMD): Rename from DEFUN_TEXT.  Provide DEFUN_TEXT as
+	an alias for DEFCMD.  Change all uses.
+
+	* variables.cc (at_top_level): New function.
+	(do_who, Fmark_as_command, Funmark_command): Use it.
+
+	* lex.l (COMMAND_START): Rename from TEXT_FCN.  Change all uses.
+	(MATRIX_START): Rename from MATRIX.  Change all uses.
+	* variables.cc (command_function_set): Rename from
+	text_function_set.
+	(mark_as_command): Rename from mark_as_text_function.
+	(is_marked_as_command): Rename from is_marked_as_text_function.
+	(Fmark_as_command): Rename from Fmark_as_text_function.
+	(Funmark_command): Rename from Funmark_text_function.
+	(is_command_name): Rename from is_text_function_name.
+	* symtab.h (symbol_record::COMMAND): Rename from TEXT_FUNCTION.
+	(symbol_record::mark_as_command): Rename from mark_as_text_function.
+	(symbol_record::unmark_command): Rename from
+	symbol_record::unmark_text_function.
+	(symbol_record::is_command): Rename from
+	symbol_record::is_text_function.
+	(symbol_record::symbol_def::mark_as_command): Rename from
+	symbol_record::symbol_def::mark_as_text_function.
+	(symbol_record::symbol_def::unmark_command): Rename from
+	symbol_record::symbol_def::unmark_text_function.
+	(symbol_record::symbol_def::is_command): Rename from
+	symbol_record::symbol_def::is_text_function.
+
+	* pt-jump.h, pt-jump.cc: Undo previous changes.
+	* parse.y: Undo previous changes for brea, continue, and return.
+
+2002-11-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-stmt.cc (tree_statement::eval): Allow the lookup to execute
+	script files.  If script file has been executed, don't bother to
+	call expr->rvalue ().
+
+2002-11-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCTINTERP_LINK_DEPS): Include $(FLIBS) in
+	OCTINTERP_LINK_DEPS.
+
+	* variables.cc (text_function_set): New static data.
+	(mark_as_text_function, unmark_text_function,
+	is_marked_as_text_function, Fmark_as_text_function,
+	Funmark_text_function): New functions.
+	(is_text_function_name): Handle functions marked as text functions
+	in special list, not just those marked in the symbol record.
+	* symtab.h (symbol_record::mark_as_text_function,
+	symbol_record::unmark_text_function,
+	symbol_record::symbol_def::mark_as_text_function,
+	symbol_record::symbol_def::unmark_text_function): New functions.
+
+	* oct-map.h (Octave_map::rows, Octave_map::columns): New functions.
+	* ov-struct.h (octave_struct::rows, octave_struct::columns,
+	octave_struct::length): New functions.
+
+2002-11-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-conf.h.in (OCTAVE_CONF_MKOCTFILE_SH_LDFLAGS): New macro.
+	* toplev.cc (octave_config_info): Add it to the struct.
+
+	* lex.l (<TEXT_FCN>): If yytext begins with # or %, don't
+	recognize it as a string.
+
+	* oct-map.h (Octave_map::operator[]): New const version.
+	* oct-map.cc (equiv_keys): New function.
+	(assign (const idx_vector&, const Octave_map&)): New function.
+	* ov-struct.cc (octave_struct::subsasgn): Use it.
+
+2002-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.40.
+
+	* p-b-b.cc, op-bm-bm.cc, op-chm.cc, op-cm-cm.cc, op-cm-cs.cc,
+	op-cm-m.cc, op-cm-s.cc, op-cs-cm.cc, op-cs-cs.cc, op-cs-m.cc,
+	op-cs-s.cc, op-fil-b.cc, op-fil-bm.cc, op-fil-cm.cc, op-fil-cs.cc,
+	op-fil-lis.cc, op-fil-m.cc, op-fil-rec.cc, op-fil-s.cc,
+	op-fil-str.cc, op-list.cc, op-m-cm.cc, op-m-cs.cc, op-m-m.cc,
+	op-m-s.cc, op-range.cc, op-s-cm.cc, op-s-cs.cc, op-s-m.cc,
+	op-s-s.cc, op-str-str.cc, op-bm-b.cc, op-cell.cc, BaseSLList.cc,
+	BaseSLList.h, ChangeLog, Map.cc, Map.h, SLList.cc, SLList.h,
+	SLStack.cc, SLStack.h, Stack.cc, Stack.h, oct-map.cc, oct-map.h,
+	oct-obj.cc, oct-obj.h, c-file-ptr-stream.cc, c-file-ptr-stream.h,
+	ov-base-mat.cc, ov-base-scalar.cc, ov-base-scalar.h, ov-base.cc,
+	ov-base.h, ov-bool-mat.cc, ov-bool-mat.h, ov-bool.cc, ov-bool.h,
+	ov-builtin.cc, ov-builtin.h, ov-ch-mat.cc, ov-ch-mat.h,
+	ov-colon.cc, ov-complex.cc, ov-complex.h, ov.h, ov-cx-mat.cc,
+	ov-cx-mat.h, ov-fcn.cc, ov-fcn.h, ov-file.cc, ov-file.h,
+	ov-list.cc, ov-list.h, ov-mapper.cc, ov-mapper.h, ov-range.cc,
+	ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-scalar.cc, ov-scalar.h,
+	ov-str-mat.cc, ov-str-mat.h, ov-struct.cc, ov-struct.h,
+	ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h,
+	ov-va-args.cc, ov.cc, ov-base-mat.h, procstream.cc, procstream.h,
+	pt-arg-list.cc, pt-arg-list.h, pt-binop.cc, pt-binop.h,
+	pt-check.cc, pt-check.h, pt-cmd.cc, pt-cmd.h, pt-colon.cc,
+	pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h,
+	pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h, pt-id.cc, pt-id.h,
+	pt-idx.cc, pt-idx.h, pt-jump.cc, pt-jump.h, pt-loop.cc, pt-loop.h,
+	pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h, pt-pr-code.cc,
+	pt-pr-code.h, pt-select.cc, pt-select.h, pt-stmt.cc, pt-stmt.h,
+	pt-unop.cc, pt-unop.h, pt.cc, pt.h, symtab.h, token.cc, token.h,
+	unwind-prot.cc, unwind-prot.h, ov-base-nd-array.cc,
+	ov-re-nd-array.h, ov-re-nd-array.cc, ov-base-nd-array.h,
+	comment-list.h, comment-list.cc, DLList.cc, DLList.h,
+	ov-dld-fcn.h, ov-dld-fcn.cc, Cell.cc, Cell.h, pt-cell.h,
+	pt-cell.cc, ov-cell.h, ov-cell.cc, pt-plot.cc, pt-plot.h,
+	pt-assign.cc, pt-assign.h, pt-bp.cc, pt-bp.h, symtab.cc,
+	ov-cs-list.h, ov-cs-list.cc:
+	Use "defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)" instead of 
+	"! defined (NO_PRAGMA_INTERFACE_IMPLEMENTATION)".
+
+2002-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-obj.h (octave_value_list::~octave_value_list): New function.
+
+2002-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/odessa.cc (odessa_user_j): Put T in args(1), not
+	args(0).
+
+2002-11-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (symtab_context): Now extern.
+	* parse.h: Provide decl.
+	* lex.l (reset_parser): Set it to 0.
+
+2002-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-bp.cc (octave_debug_on_interrupt_state): New global variable.
+	* pt-bp.h: Provide decl.
+	(MAYBE_DO_BREAKPOINT): Check it.
+
+	* sighandlers.cc (sigint_handler): Handle debug_on_interrupt.
+	(Vdebug_on_interrupt): New static variable.
+	(symbols_of_sighandlers): New function.  DEFVAR Vdebug_on_interrupt.
+	(debug_on_interrupt): New function.
+
+	* lex.h (YY_FATAL_ERROR): Use OCTAVE_QUIT here.
+
+	* utils.cc (toplevel): Delete variable.
+
+	* sighandlers.cc (OCTAVE_MEMORY_EXHAUSTED_ERROR): Delete.
+
+2002-11-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (octave_new_handler): Delete.
+	(install_signal_handlers): Don't call set_new_handler.
+	* toplev.cc (main_loop): Handle bad_alloc exception here.
+
+	* sighandlers.cc (octave_new_handler): Allow return after
+	OCTAVE_JUMP_TO_TOP_LEVEL.
+	(sigfpe_handler): Likewise.
+
+2002-11-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (is_variable): New static function.
+	(generate_struct_completions): Only evaluate objects that look
+	like variables.
+
+2002-11-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-jump.h, pt-jump.cc (tree_break_expression,
+	tree_continue_expression, tree_return_expression): Rename from
+	tree_break_command, tree_continue_command, tree_return_command.
+	Implement as expressions that return TRUE instead of commands.
+	Change all uses.
+	* parse.y (make_break_expression, make_continue_expression,
+	make_return_expression): Rename from make_break_command,
+	make_continue_command, make_return_command.  Change all uses.
+	(jump_expr): Rename from jump_command, type is now expression.
+	Use in simple_expr, not command.	
+
+	* toplev.cc (octave_initialized): New global variable.
+	(main_loop): Set it to true here.
+	* sighandlers.cc (sigint_handler): Exit immediately if we have not
+	finished init process.
+
+	* load-save.cc (extract_keyword): Return std::string, not char *.
+	Change all uses.
+	(read_ascii_data): Likewise.
+	(read_binary_data): Likewise.
+	(read_hdf5_data): Likewise.
+	(read_mat_ascii_data): Likewise.
+	(read_mat_binary_data): Likewise.
+	(do_load): Name and doc are now std::string objects, not char *.
+	(install_loaded_variable): Likewise.
+	(read_hdf5_data): Doc is now std::string object, not char *&.
+	(read_mat_ascii_data): Call OCTAVE_QUIT in strategic locations.
+	(get_lines_and_columns): Likewise.
+
+	* toplev.cc (main_loop): Call OCTAVE_QUIT after executing command.
+	* parse.y (parse_and_execute (FILE *)): Likewise.
+
+2002-11-12  Joseph P. Skudlarek  <jskud at jskud.com>
+
+	* input.cc (match_sans_spaces_semi): Rename from match_sans_spaces.
+	Ignore trailing semicolons too.  Change all callers.
+
+2002-11-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.gperf: Allow "persistent" as a synonym for static.
+
+	* defun-int.h (DEFUN_MAPPER_INTERNAL): Don't forget doc string
+	when creating octave_mapper object.
+
+	* sysdep.cc (BSD_init): Avoid failure if FP_X_DNML is not defined.
+
+2002-11-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cutils.c: Be sure to always return buf.
+
+	Undo previous vnprintf changes.  The portable snprintf I found
+	does not handle floating point conversions...
+	
+2002-11-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (liboctinterp.$(LIBEXT)): Include $(XERBLA) here.
+	(octave.$(EXEEXT)): Not here.
+	(liboctinterp.$(SHLEXT)): Include $(PIC_XERBLA) here.
+
+	* main.c: Move decl for xerbla here from octave.cc.
+
+	* cutils.c (octave_vsnprintf): Use portable_snprintf to avoid
+	having to cope with all kinds of buggy implementations.
+
+	* snprintf.c: New file.
+	* Makefile.in (DISTFILES): Add it to the list.
+
+	* oct-snprintf.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+	* oct-snprintf.c: New file.
+	* Makefile.in (DIST_SRC): Add it to the list.
+
+	* toplev.cc (main_loop): Use SET_OCTAVE_INTERRUPT_IMMEDIATELY
+	instead of assigning octave_interrupt_immediately.
+
+2002-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (jump_to_top_level): Delete.
+
+	* toplev.cc (toplevel): Delete.
+	(main_loop): Adapt to new signal/exception handling scheme.
+
+	* sighandlers.cc (octave_signal_mask, octave_save_signal_mask,
+	octave_restore_signal_mask): Move to libcruft/misc/quit.cc.
+	(sigint_handler) [USE_EXCEPTIONS_FOR_INTERRUPTS]: set
+	octave_interrupt_state.  Only jump if octave_interrupt_immediately
+	is true, and then only to enclosing context.
+
+	* lex.h (YY_FATAL_ERROR): Use OCTAVE_JUMP_TO_TOP_LEVEL, not
+	jump_to_top_level.
+	* sighandlers.cc (octave_new_handler, sigfpe_handler, endif,
+	sigpipe_handler): Likewise.
+
+	* input.cc (gnu_readline): Surround call to
+	command_editor::readline with
+	BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE and 
+	END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE.
+
+	* data.cc, oct-stream.cc, ov-cell.cc, ov-mapper.cc, ov-re-mat.cc,
+	ov.cc, pr-output.cc, pt-loop.cc, pt-stmt.cc, xdiv.cc, xpow.cc,
+	DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/besselj.cc,
+	DLD-FUNCTIONS/filter.cc, DLD-FUNCTIONS/find.cc,
+	DLD-FUNCTIONS/kron.cc, DLD-FUNCTIONS/log.cc,
+	DLD-FUNCTIONS/minmax.cc, DLD-FUNCTIONS/qz.cc,
+	DLD-FUNCTIONS/rand.cc, DLD-FUNCTIONS/sort.cc: Sprinkle with
+	OCTAVE_QUIT.
+
+	* DLD-FUNCTIONS/odessa.cc (Fodessa): Correctly extract bsub from
+	function arg.
+
+2002-11-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cutils.c (octave_vsnprintf): Handle C99 snprintf semantics.
+
+	* oct-obj.h (octave_value_list::operator =): Copy names too.
+	(octave_value_list::octave_value_list (const octave_value_list&)):
+	Likewise.
+
+2002-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.39.
+
+	* variables.cc (generate_struct_completions): Temporarily reset
+	discard_error_messages and error_state
+	(looks_like_struct): Temporarily reset Vwarning option,
+	error_state, and discard_error_messages.
+
+	* pt-idx.cc (tree_index_expression::eval_error): Now const.
+	(tree_index_expression::get_struct_index): Require valid identifier.
+	(tree_index_expression::make_arg_struct,
+	tree_index_expression::rvalue, tree_index_expression::lvalue):
+	Handle possible error from get_struct_index.
+
+	* utils.cc (valid_identifier): Move here from load-save.cc.
+	* utils.h: Provide decl.
+
+	* input.cc (generate_possible_completions): Call
+	command_editor::filename_completion_desired here.
+	(generate_possible_completions): Don't generate struct completions
+	if text contains directory separator or "..".
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/odessa.cc (odessa_user_f, odessa_user_j,
+	odessa_user_b): Reorder args for consistency with other solvers.
+	(Fodessa): Use extract_function to set args.
+	(odessa_user_j): Rename from odessa_user_mf.
+
+	* DLD-FUNCTIONS/fsolve.cc (fsolve_user_function, fsolve_user_jacobian):
+	Print warning if user returns complex value.
+	* DLD-FUNCTIONS/quad.cc (quad_user_function): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (lsode_user_function, lsode_user_jacobian):
+	Likewise.
+	* DLD-FUNCTIONS/dassl.cc (dassl_user_function, dassl_user_jacobian):
+	Likewise.
+	* DLD-FUNCTIONS/dasrt.cc (dasrt_user_f, dasrt_user_cf, dasrt_user_j):
+	Likewise. 
+	* DLD-FUNCTIONS/daspk.cc (daspk_user_function, daspk_user_jacobian):
+	Likewise.
+
+	* DLD-FUNCTIONS/daspk.cc (daspk_user_jacobian): New function.
+	(Fdaspk): Handle extracting Jacobian from function argument.
+
+	* DLD-FUNCTIONS/fsolve.cc (fsolve_user_function): New function.
+	(Ffsolve): Handle extracting Jacobian from function argument.
+
+	* Makefile.in (%.oct): Depend on octave$(EXEEXT) so that octave
+	will be built before any .oct files.
+	(all): Depend on stamp-oct-links.
+	(octave$(EXEEXT)): Don't depend on stamp-oct-links.
+
+	* ov-base.cc (octave_base_value::subsasgn): Handle default numeric
+	case here.
+	* ov-base-mat.cc (octave_base_matrix<MT>::subsasgn): Delete.
+
+2002-10-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCT_LINK_DEPS): Add $(BLAS_LIBS), $(FFTW_LIBS), and
+	$(FLIBS).
+
+2002-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_VERSION): Now 2.1.38.
+
+	* utils.cc (octave_vformat): Get return value from
+	streambuf::vform.
+
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Always return solution.
+	Don't barf on nargout == 3.
+
+	* pt-idx.h (tree_index_expression::dyn_field): New data member.
+	* pt-idx.cc (tree_index_expression::tree_index_expression
+	(tree_expression*, tree_expression*, int, int)): New constructor.
+	(tree_index_expression::append (tree_expression*)): New function.
+	(tree_index_expression::get_struct_index): New function.
+	(tree_index_expression::make_arg_struct): Handle dynamic fields.
+	(tree_index_expression::rvalue): Likewise.
+	(tree_index_expression::lvalue): Likewise.
+
+	* parse.y (make_indirect_ref (tree_expression*, tree_expression*)):
+	New function.
+	(indirect_ref_op): New non-terminal.
+	(postfix_expr): Use it.
+	Recognize dynamic struct field references.
+	(parsing_indir): Delete unused non-terminal.
+
+	* lex.l ("("): Set lexer_flags.looking_at_indirect_ref to false here.
+
+	* pt-idx.cc (tree_index_expression::name): Simplify.
+
+2002-10-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-conf.h.in (OCTAVE_CONF_HAVE_DLOPEN_API,
+	OCTAVE_CONF_HAVE_LOADLIBRARY_API, OCTAVE_CONF_HAVE_SHL_LOAD_API):
+	Delete.
+	* toplev.cc (octave_config_info): Delete them from the struct
+
+	* load-save.cc (read_ascii_data): Use octave_read_double and
+	octave_read_complex so that we handle Inf, NaN, and NA.
+	(read_mat_ascii_data): Likewise.
+	(save_ascii_data): Use octave_write_double andoctave_write_complex.
+
+2002-10-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (octave_config_info): Rename WITH_DYNAMIC_LINKING to
+	ENABLE_DYNAMIC_LINKING.
+	* oct-conf.h.in: Likewise.
+	* mkbuiltins: Likewise.
+	* fn-cache.cc (file_name_cache_elt::update): Likewise.
+	* Makefile.in: Likewise.
+
+2002-10-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cutils.c (octave_vsnprintf): Buffer and buffer size now static.
+	* utils.cc (octave_vformat): Don't free buffer returned from
+	octave_vsnprintf here.
+
+	* ov-usr-fcn.cc (va_arg, va_start, vr_val): Only print warning
+	once per session.
+
+	* ov-mapper.cc (octave_mapper::apply): Don't try real_type case if
+	arg is a string and we have a ch_map_fcn.
+
+	* Makefile.in: Add $(LIBKPATHSEA) to $(OCTAVE_LIBS) if
+	$(INCLUDE_LINK_DEPS) is false, not if $(SHARED_LIBS) is false.
+
+2002-10-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/daspk.cc (daspk): Use set_options, not copy. 
+	* DLD-FUNCTIONS/dasrt.cc (dasrt): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (dassl): Likewise.
+	* DLD-FUNCTIONS/fsolve.cc (fsolve): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (lsode): Likewise.
+	* DLD-FUNCTIONS/odessa.cc (Fodessa): Likewise.
+	* DLD-FUNCTIONS/quad.cc (Fquad): Likewise.
+
+2002-10-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-map.cc (Octave_map::assign): Fix typo in resizing.
+
+	* pt-loop.cc (tree_complex_for_command::eval): Only return list
+	for val if struct array has more than one element.
+	(tree_simple_for_command::eval): Likewise.
+
+	* ov-struct.cc (octave_struct::print_raw): Don't create
+	octave_list directly, use octave_value (const octave_value_list&)
+	constructor instead.
+	Call print_with_name for tmp, not val(0).
+
+	* version.h (OCTAVE_VERSION): Now 2.1.37.
+	(OCTAVE_CONTRIB_STATEMENT): New macro.
+	(OCTAVE_STARTUP_MESSAGE): Use it.
+
+2002-10-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (fill_matrix): If nargin is zero, use val, not 0.0.
+
+	* main.c: New file.
+	* octave.h: New file.
+	* octave.cc (octave_main): Rename from main.
+	Include octave.h.
+	* Makefile.in (OBJECTS): Add octave.o, builtins.o, and ops.o to
+	the list.
+	(octave): Depend on and link main.o, not octave.o, builtins.o, and
+	ops.o (they are now in liboctinterp).
+	(DEP_5): Add main.c here.
+
+	* oct-conf.h.in: No need to substitute OCTAVE_CONF_OCTAVE_LITE.
+	* toplev.cc (octave_config_info): Likewise, don't include it in
+	struct.
+
+	* mkbuiltins: Remove check for OCTAVE_LITE, since it is now
+	implied by WITH_DYNAMIC_LINKING.
+	* Makefile.in: Likewise, replace tests for OCTAVE_LITE with tests
+	for WITH_DYNAMIC_LINKING instead.
+
+	* oct-conf.h.in: Use OCTAVE_CONF_HAVE_DLOPEN_API,
+	OCTAVE_CONF_HAVE_LOADLIBRARY_API, and
+	OCTAVE_CONF_HAVE_SHL_LOAD_API instead of OCTAVE_CONF_WITH_DL and
+	OCTAVE_CONF_WITH_SHL.
+	* toplev.cc (octave_config_info): Likewise.
+
+2002-10-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (display_help_text): Quote output file name for Cygwin.
+
+	* Makefile.in (install-lib): Don't bother with versions for
+	$(SHLBIN) files.
+
+	* help.cc (display_help_text): Match zero or more comment
+	characters instead of one or more.
+
+	* Makefile.in (install-oct): Process files from $(DLD_DEF_FILES),
+	not $(DLD_SRC).  Look for them in current directory, not $(srcdir).
+
+2002-10-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-mapper.cc (octave_mapper::apply): Handle real and complex
+	types first.  If the arg is something else, try ch_map_fcn if it
+	is defined.
+
+2002-10-15  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in: If building shared but not static libs, only set
+	XERBLA to the location of the pic object file if FPICFLAG is
+	defined.
+
+2002-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	*  DLD-FUNCTIONS/minmax.cc, DLD-FUNCTIONS/getrusage.cc, data.cc,
+	file-io.cc, ov-base.cc, ov-bool-mat.cc, ov-ch-mat.cc,
+	ov-complex.cc, ov-cx-mat.cc, ov-range.cc, ov-re-mat.cc,
+	ov-re-nd-array.cc: Change all uses of octave_Inf, octave_NA, and
+	octave_NaN to be calls to lo_ieee_Inf_value, lo_ieee_NA_value, and
+	lo_ieee_NaN_value instead of using the constants directly to avoid
+	linking problem with Cygwin.
+
+	* Makefile.in (install): No need to use cd to create links.
+
+2002-10-14  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* Makefile.in: Merge liboctave with liboct-readline and
+	liboct-pathsearch.
+	Use link dependencies for shared libs if INCLUDE_LINK_DEPS.
+	(LIBRARIES): If doing shared libs, include versioned library in	list.
+	(liboctinterp.$(SHLEXT), liboctinterp.$(SHLEXT_VER)): Reverse
+	actions -- build unversioned library, symbolic link adds version
+	info.
+	(install, uninstall): Handle link and load forms of the library
+	separately.
+
+	* toplev.cc (octave_config_info): Remove LIBOCT_READLINE and
+	LIBOCT_PATHSEARCH, add LIBREADLINE.
+	* oct-conf.h.in: Likewise.
+
+2002-10-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_identifier): Don't enter token in local symbol
+	table if the following token is a dot and it looks like a binary
+	operator.
+	(force_local_variable): If name is not a variable, clear it before
+	defining.
+
+	* oct-procbuf.cc (Vkluge_procbuf_delay): Make default 0 for all
+	systems.
+
+	* octave.cc (execute_startup_files, initialize_pathsearch):
+	Use file_ops::dir_sep_str instead of OCTAVE_DIR_SEP_STR.
+	(main): Use file_ops::dir_sep_chars instead of OCTAVE_DIR_SEP_CHARS.
+
+	* ov-re-mat.cc (octave_matrix::convert_to_str): Warn for out of
+	range conversions.  For negative values, set to 0.
+	* ov-scalar.cc (octave_scalar:convert_to_str): Likewise.
+
+	* mappers.cc (xabs): New static function.
+	(install_mapper_functions): Use it for abs for character matrices.
+	Handle ch_map_flag separately from can_ret_cmplx_for_real in
+	all uses of DEFUN_MAPPER.
+	* defun.h (DEFUN_MAPPER): Handle ch_map_flag separately from
+	can_ret_cmplx_for_real.
+	* defun-int.h (DEFUN_MAPPER_INTERNAL): Likewise.
+	* mkbuiltins: Likewise.
+	* mkgendoc: Likewise.
+	* ov-mapper.cc (octave_mapper::apply): Use ch_map_flag and
+	can_ret_cmplx_for_real instead of flag.
+	* ov-mapper.h (octave_mapper::ch_map_flag): Rename from flag.
+	(octave_mapper::can_ret_cmplx_for_real): New data member.
+	(octave_mapper::octave_mapper): Handle it here.
+
+2002-10-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (execute_startup_files): Don't forget directory
+	separator for local initfile.
+
+	* move-if-change: Delete.
+	* Makefile.in (DISTFILES): Delete it from the list.
+
+2002-10-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Use $(EXEEXT) and $(BUILD_EXEEXT) as appropriate.
+
+	* pt-plot.cc (Vgnuplot_binary): Use GNUPLOT_BINARY as default.
+
+	* octave.cc (execute_startup_files): 
+	Use octave_env::getcwd instead of "./".
+	Use OCTAVE_DIR_SEP_STR instead of "/".
+	(initialize_pathsearch): Use OCTAVE_DIR_SEP_STR instead of /.
+	(main): Look for OCTAVE_DIR_SEP_CHARS, not '/'.
+
+2002-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (gendoc): Use $(BUILD_CXX), not $(CXX).
+
+2002-10-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (octave_sleep): Cast result of modf to unsigned int.
+
+2002-10-07  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* sighandlers.cc (my_friendly_exit): If kill is unavailable, use
+	raise.
+
+2002-10-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc (CYGWIN_init): New function.
+	(sysdep_init) [__CYGWIN__]: Call it.
+
+	* pt-plot.cc (subplot::handle_plot_data): Surround file names in
+	single quotes, not double (for Windows).
+	(do_external_plotter_cd): Likewise.
+
+2002-10-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cutils.c (octave_usleep): Call octave_sleep, not sleep.
+
+	* utils.cc (octave_sleep (double)): New function.
+	* utils.h: Provide decl.
+	* sysdep.cc (Fpause, Fsleep): Use it.
+
+	* cutils.c (do_octave_usleep): Merge with octave_usleep.
+	(octave_usleep): Make it work for Windows systems.  From Paul
+	Kienzle <pkienzle at users.sf.net>.
+
+2002-10-03  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* cutils.c (octave_usleep): Make it work for Windows systems.
+
+	* toplev.cc (Fsystem): Error message if fork is not available.
+
+2002-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cutils.c (octave_sleep): Handle Windows, which may not have
+	sleep, but should have Sleep.
+
+	* oct-conf.h.in (OCTAVE_CONF_SED): Add an entry for SED.
+	* toplev.cc (octave_config_info): Likewise.
+	* Makefile.in (oct-gperf.h): Use $(SED), not sed.
+
+2002-09-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (fopen_mode_to_ios_mode): Set ios::ate instead of
+	ios::app for "a+" mode.
+	* oct-stream.cc (octave_stream::mode_as_string): Recognize
+	ios::ate, not ios::app as "a+" mode.
+	(octave_stream::mode_as_string): Use parens since | has lower
+	precedence than ==.
+
+2002-09-26  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* sysdep.cc: Include conio.h if it exists.
+	(octave_kbhit): Rename from kbhit.  Implement with _kbhit if it
+	exists. Change all callers.
+	* cutils.c (octave_sleep): New function.
+	Change all callers of sleep to use octave_sleep instead.
+
+2002-09-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* BaseSLList.cc, BaseSLList.h, Cell.cc, Cell.h, DLList.cc,
+	DLList.h, Map.cc, Map.h, OPERATORS/op-b-b.cc,
+	OPERATORS/op-bm-b.cc, OPERATORS/op-bm-bm.cc, OPERATORS/op-cell.cc,
+	OPERATORS/op-chm.cc, OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc,
+	OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc, OPERATORS/op-cs-cm.cc,
+	OPERATORS/op-cs-cs.cc, OPERATORS/op-cs-m.cc, OPERATORS/op-cs-s.cc,
+	OPERATORS/op-fil-b.cc, OPERATORS/op-fil-bm.cc,
+	OPERATORS/op-fil-cm.cc, OPERATORS/op-fil-cs.cc,
+	OPERATORS/op-fil-lis.cc, OPERATORS/op-fil-m.cc,
+	OPERATORS/op-fil-rec.cc, OPERATORS/op-fil-s.cc,
+	OPERATORS/op-fil-str.cc, OPERATORS/op-list.cc,
+	OPERATORS/op-m-cm.cc, OPERATORS/op-m-cs.cc, OPERATORS/op-m-m.cc,
+	OPERATORS/op-m-s.cc, OPERATORS/op-range.cc, OPERATORS/op-s-cm.cc,
+	OPERATORS/op-s-cs.cc, OPERATORS/op-s-m.cc, OPERATORS/op-s-s.cc,
+	OPERATORS/op-str-str.cc, SLList.cc, SLList.h, SLStack.cc,
+	SLStack.h, Stack.cc, Stack.h, c-file-ptr-stream.cc,
+	c-file-ptr-stream.h, comment-list.cc, comment-list.h, oct-map.cc,
+	oct-map.h, oct-obj.cc, oct-obj.h, ov-base-mat.cc, ov-base-mat.h,
+	ov-base-nd-array.cc, ov-base-nd-array.h, ov-base-scalar.cc,
+	ov-base-scalar.h, ov-base.cc, ov-base.h, ov-bool-mat.cc,
+	ov-bool-mat.h, ov-bool.cc, ov-bool.h, ov-builtin.cc, ov-builtin.h,
+	ov-cell.cc, ov-cell.h, ov-ch-mat.cc, ov-ch-mat.h, ov-colon.cc,
+	ov-complex.cc, ov-complex.h, ov-cs-list.cc ov-cs-list.h,
+	ov-cx-mat.cc, ov-cx-mat.h, ov-dld-fcn.cc, ov-dld-fcn.h, ov-fcn.cc,
+	ov-fcn.h, ov-file.cc, ov-file.h, ov-list.cc, ov-list.h,
+	ov-mapper.cc, ov-mapper.h, ov-range.cc, ov-range.h, ov-re-mat.cc,
+	ov-re-mat.h, ov-re-nd-array.cc, ov-re-nd-array.h, ov-scalar.cc,
+	ov-scalar.h, ov-str-mat.cc, ov-str-mat.h, ov-struct.cc,
+	ov-struct.h, ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc,
+	ov-usr-fcn.h, ov-va-args.cc, ov.cc, ov.h, procstream.cc,
+	procstream.h, pt-arg-list.cc, pt-arg-list.h, pt-assign.cc,
+	pt-assign.h, pt-binop.cc, pt-binop.h, pt-bp.cc, pt-bp.h,
+	pt-cell.cc, pt-cell.h, pt-check.cc, pt-check.h, pt-cmd.cc,
+	pt-cmd.h, pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h,
+	pt-decl.cc, pt-decl.h, pt-except.cc, pt-except.h, pt-exp.cc,
+	pt-exp.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-jump.cc,
+	pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc,
+	pt-misc.h, pt-plot.cc, pt-plot.h, pt-pr-code.cc, pt-pr-code.h,
+	pt-select.cc, pt-select.h, pt-stmt.cc, pt-stmt.h, pt-unop.cc,
+	pt-unop.h, pt.cc, pt.h, symtab.cc, symtab.h, token.cc, token.h,
+	unwind-prot.cc, unwind-prot.h:
+	If __GNUG__, use pragma interface/implementation.  Allow this to
+	be turned off by defining NO_PRAGMA_INTERFACE_IMPLEMENTATION.
+
+2002-09-26  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* mappers.cc (install_mapper_functions): Install erf, not xerf.
+	Install erfc, not xerfc.
+
+	* pt-bp.cc (tree_breakpoint::visit_unwind_protect_command):
+	Rename lst1 and lst2 to avoid dlgs.h conflict.
+
+	* parse.y: Replace TEXT with STRING to avoid winnt.h conflict.
+	* lex.l: Ditto.
+
+	* sysdep.cc (raw_mode): Non-fatal warning if raw_mode is not
+	supported.
+
+	* sighandlers.cc: Don't define handlers for non-existent signals.
+
+	* utils.cc: Don't include unneeded termio headers.
+
+2002-09-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* BaseSLList.cc, BaseSLList.h, Cell.cc, Cell.h, DLList.cc,
+	DLList.h, Map.cc, Map.h, OPERATORS/op-b-b.cc,
+	OPERATORS/op-bm-b.cc, OPERATORS/op-bm-bm.cc, OPERATORS/op-cell.cc,
+	OPERATORS/op-chm.cc, OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc,
+	OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc, OPERATORS/op-cs-cm.cc,
+	OPERATORS/op-cs-cs.cc, OPERATORS/op-cs-m.cc, OPERATORS/op-cs-s.cc,
+	OPERATORS/op-fil-b.cc, OPERATORS/op-fil-bm.cc,
+	OPERATORS/op-fil-cm.cc, OPERATORS/op-fil-cs.cc,
+	OPERATORS/op-fil-lis.cc, OPERATORS/op-fil-m.cc,
+	OPERATORS/op-fil-rec.cc, OPERATORS/op-fil-s.cc,
+	OPERATORS/op-fil-str.cc, OPERATORS/op-list.cc,
+	OPERATORS/op-m-cm.cc, OPERATORS/op-m-cs.cc, OPERATORS/op-m-m.cc,
+	OPERATORS/op-m-s.cc, OPERATORS/op-range.cc, OPERATORS/op-s-cm.cc,
+	OPERATORS/op-s-cs.cc, OPERATORS/op-s-m.cc, OPERATORS/op-s-s.cc,
+	OPERATORS/op-str-str.cc, SLList.cc, SLList.h, SLStack.cc,
+	SLStack.h, Stack.cc, Stack.h, c-file-ptr-stream.cc,
+	c-file-ptr-stream.h, comment-list.cc, comment-list.h, oct-map.cc,
+	oct-map.h, oct-obj.cc, oct-obj.h, ov-base-mat.cc, ov-base-mat.h,
+	ov-base-nd-array.cc, ov-base-nd-array.h, ov-base-scalar.cc,
+	ov-base-scalar.h, ov-base.cc, ov-base.h, ov-bool-mat.cc,
+	ov-bool-mat.h, ov-bool.cc, ov-bool.h, ov-builtin.cc, ov-builtin.h,
+	ov-cell.cc, ov-cell.h, ov-ch-mat.cc, ov-ch-mat.h, ov-colon.cc,
+	ov-complex.cc, ov-complex.h, ov-cs-list.cc ov-cs-list.h,
+	ov-cx-mat.cc, ov-cx-mat.h, ov-dld-fcn.cc, ov-dld-fcn.h, ov-fcn.cc,
+	ov-fcn.h, ov-file.cc, ov-file.h, ov-list.cc, ov-list.h,
+	ov-mapper.cc, ov-mapper.h, ov-range.cc, ov-range.h, ov-re-mat.cc,
+	ov-re-mat.h, ov-re-nd-array.cc, ov-re-nd-array.h, ov-scalar.cc,
+	ov-scalar.h, ov-str-mat.cc, ov-str-mat.h, ov-struct.cc,
+	ov-struct.h, ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc,
+	ov-usr-fcn.h, ov-va-args.cc, ov.cc, ov.h, procstream.cc,
+	procstream.h, pt-arg-list.cc, pt-arg-list.h, pt-assign.cc,
+	pt-assign.h, pt-binop.cc, pt-binop.h, pt-bp.cc, pt-bp.h,
+	pt-cell.cc, pt-cell.h, pt-check.cc, pt-check.h, pt-cmd.cc,
+	pt-cmd.h, pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h,
+	pt-decl.cc, pt-decl.h, pt-except.cc, pt-except.h, pt-exp.cc,
+	pt-exp.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-jump.cc,
+	pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc,
+	pt-misc.h, pt-plot.cc, pt-plot.h, pt-pr-code.cc, pt-pr-code.h,
+	pt-select.cc, pt-select.h, pt-stmt.cc, pt-stmt.h, pt-unop.cc,
+	pt-unop.h, pt.cc, pt.h, symtab.cc, symtab.h, token.cc, token.h,
+	unwind-prot.cc, unwind-prot.h:
+	Use USE_PRAGMA_INTERFACE_IMPLEMENTATION instead of __GNUG__ to
+	decide whether to use the interface/implementation pragmas.
+
+2002-09-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc: Undo previous change.
+
+	* ov-struct.cc (octave_struct::subsasgn): Ensure that indexed
+	object is not shared before calling subsasgn.
+
+2002-09-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc: Use % instead of # as comment character in ascii
+	data files.
+
+2002-08-17  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* c-file-ptr-stream.h (c_file_ptr_buf::c_file_ptr_buf): Add Intel
+	C++ runtime support.
+
+	* Cell.h, gripes.cc, ov-base-scalar.cc, ov-colon.cc, ov-fcn.cc,
+	ov-file.cc, ov-mapper.h, ov-va-args.cc, token.cc, xpow.cc,
+	OPERATORS/op-b-b.cc, OPERATORS/op-bm-b.cc, OPERATORS/op-bm-bm.cc,
+	OPERATORS/op-cell.cc, OPERATORS/op-chm.cc, OPERATORS/op-cm-cm.cc,
+	OPERATORS/op-cm-cs.cc, OPERATORS/op-cm-m.cc, OPERATORS/op-cm-s.cc,
+	OPERATORS/op-cs-cm.cc, OPERATORS/op-cs-cs.cc, OPERATORS/op-cs-m.cc,
+	OPERATORS/op-cs-s.cc, OPERATORS/op-fil-b.cc, OPERATORS/op-fil-bm.cc,
+	OPERATORS/op-fil-cm.cc, OPERATORS/op-fil-cs.cc,
+	OPERATORS/op-fil-lis.cc, OPERATORS/op-fil-m.cc,
+	OPERATORS/op-fil-rec.cc, OPERATORS/op-fil-s.cc,
+	OPERATORS/op-fil-str.cc, OPERATORS/op-list.cc, OPERATORS/op-m-cm.cc,
+	OPERATORS/op-m-cs.cc, OPERATORS/op-m-m.cc, OPERATORS/op-m-s.cc,
+	OPERATORS/op-range.cc, OPERATORS/op-s-cm.cc, OPERATORS/op-s-cs.cc,
+	OPERATORS/op-s-m.cc, OPERATORS/op-s-s.cc, OPERATORS/op-str-str.cc,
+	TEMPLATE-INST/Array-sym.cc, TEMPLATE-INST/Array-tc.cc,
+	TEMPLATE-INST/Map-tc.cc, TEMPLATE-INST/SLList-expr.cc,
+	TEMPLATE-INST/SLList-tc.cc, TEMPLATE-INST/SLList-tm.cc,
+	TEMPLATE-INST/SLStack-sym.cc: Make the implementation of
+	octave_value_list visibile for template instantiation.
+
+2002-08-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/dasrt.cc: Include <iostream> not <iostream.h>.
+
+	* pager.h: Include lo-sstream.h and use macros instead of using
+	strstreambuf class directly.
+
+	* load-save.cc (read_mat_ascii_data): Handle istrstream here too.
+
+	* procstream.h (procstream::procstream): Also accept std::string arg.
+	(iprocstream::iprocstream, iprocstream::open): Likewise.
+	(oprocstream::oprocstream, oprocstream::open): Likewise.
+	(procstreambase::procstreambase, procstreambase::open): Likewise.
+
+	* pt-plot.cc (gnuplot_terminal_type): Now std::string&, not char*.
+	(send_to_plot_stream): Likewise, for cmd arg.
+
+	* pt-plot.h, pt-plot.cc: Include lo-sstream.h and use macros
+	instead of using strstream classes directly.
+	* oct-strstrm.h: Likewise.
+	* error.h, error.cc: Likewise.
+	* oct-stream.h, oct-stream.cc: Likewise.
+	* lex.l: Likewise.
+	* toplev.cc: Likewise.
+	* utils.cc: Likewise.
+	* pt.cc: Likewise.
+	* pr-output.cc: Likewise.
+	* ov-list.cc: Likewise.
+	* ov-cs-list.cc: Likewise.
+	* ov-cell.cc: Likewise.
+	* load-save.cc: Likewise.
+	* help.cc: Likewise.
+	* dirfns.cc: Likewise.
+
+2002-08-15  Paul Kienzle  <pkienzle at jazz.ncnr.nist.gov>
+
+	* input.cc (octave_read): Do a better job of buffering.
+
+2002-08-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DLD_DEF_FILES): New macro.
+	(DEF_5): Delete.
+	(DEF_4): Now only includes $(SOURCES).
+	(DEF_FILES): Append $(DLD_DEF_FILES) here.
+	(stamp-oct-links): Pass $(DLD_DEF_FILES) to mk-oct-links instead
+	of a list of source files.
+	* mk-oct-links: Work on .df files instead of .cc files.
+
+	* parse.y (case_list): Allow it to be empty.
+
+	* ov.cc, ov.h (octave_value::int_vector_value): New function.
+
+2002-08-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCTAVE_LIBS): Only include $(LIBKPATHSEA) if not
+	using shared libraries.
+
+	* ov.cc (octave_value::octave_value (const octave_value_list&, bool)):
+	Don't forget to assign rep.
+
+2002-08-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l: Warn for various Matlab-incompatibilities.
+	No longer accept <> for NOTEQ.
+	(gripe_matlab_incompatible): New function.
+	(maybe_gripe_matlab_incompatible_comment): Likewise.
+	(gripe_matlab_incompatible_continuation): Likewise.
+	(gripe_matlab_incompatible_operator): Likewise.
+	(warn_matlab_incompatible): New function.
+	(Vwarn_matlab_incompatible): New static variable.
+	(symbols_of_lex): Add a DEFVAR for it.
+	
+
+	* file-io.cc (fopen_mode_to_ios_mode): Default value is std::ios::in.
+	Return std::ios::openmode instead of int.
+
+2002-08-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/dasrt.cc (DASRT_ABORT1, DASRT_ABORT2):
+	"##" pastes tokens, not strings.
+
+	* DLD-FUNCTIONS/odessa.cc: Add std:: qualifiers as needed.
+
+2002-08-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fisglobal): Rename from Fis_global.
+	* file-io.cc (Fisstream): Rename from Fis_stream.
+	* data.cc (Fisbool): Rename from Fis_bool.
+	(Fiscomplex): Rename from Fis_complex.
+	(Fislist): Rename from Fis_list.
+	(Fismatrix): Rename from Fis_matrix.
+	(Fisstruct): Rename from Fis_struct.
+
+	* parse.y (switch_case): Make list of command optional.
+
+2002-08-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (pr_max_internal): Use octave_is_NaN_or_NA instead
+	of xisnan.
+	(pr_min_internal): Likewise.
+	(output_max_field_width): Likewise.
+	(output_precision): Likewise.
+	(pr_any_float): Handle NA.
+	* mappers.cc (Fisna, F_is_nan_or_na): New functions.
+	* data.cc (symbols_of_data): New constant, NA.
+
+2002-08-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-binop.h (tree_binary_expression::is_binary_expression):
+	New function, return true.
+	(tree_boolean_expression::is_boolean_expression): New function,
+	return true.
+	* pt-exp.h (tree_expression::is_binary_expression): New function.
+	(tree_expression::is_boolean_expression): Likewise.
+	* parse.y (EXPR_OR_OR): Now lower precedence than EXPR_AND_AND.
+	(EXPR_OR): Now lower precedence than EXPR_AND.
+	(make_boolean_op): Maybe warn about change in precedence.
+	(make_binary_op): Likewise.
+	(Vwarn_precedence_change): New static variable.
+	(warn_precedence_change): New function.
+	(Vwarn_precedence_change): New DEFVAR.
+
+2002-08-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (ANY_ALL): Improve arg checks.
+
+2002-08-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::assign_op): New enum values, op_pow_eq and
+	op_el_pow_eq.
+	* ov.cc (octave_value::assign_op_as_string): Handle them here.
+	(ocatave_value::op_eq_to_binary_op): And here.
+	* parse.y (POW_EQ, EPOW_EQ): New tokens.
+	(assign_expr): Handle them here too.
+	(make_assign_op): And here.
+
+	* lex.l: Recognize {POW}= and {EPOW}=.
+
+2002-08-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base-scalar.h (octave_base_scalar::all): New int arg.
+	(octave_base_scalar::any): Likewise.
+	* ov-range.h (octave_range::all): Likewise.
+	(octave_range::any): Likewise.
+
+	* Makefile.in (doc-files): Use mv, not move-if-change here.
+
+	* variables.cc (symbol_exist): New function.
+	(Fexist): Use it.  Handle optional type arg.  Make return codes
+	more compatible with Matlab.
+
+	* data.cc (ANY_ALL): New macro.
+	(Fany, Fall): Replace guts with ANY_ALL.
+
+2002-08-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fall, Fany): Handle optional DIM argument.
+
+	* ov.h (octave_value::any): New arg, dim.
+	(octave_value::all): Likewise.
+	* ov-base.h (octave_base_value::any): Likewise.
+	(octave_base_value::all): Likewise.
+	* ov-base-mat.h (octave_base_matrix::any): Likewise.
+	(octave_base_matrix::all): Likewise.
+
+	* Makefile.in: Use $@-t instead of $@.t.
+	(doc-files): Use move-if-change when creating doc-files.
+
+	* error.cc (warning): Don't print warning backtrace at top level.
+
+	* ov-cell.cc (octave_cell::print_raw): Print empty dimensions too.
+	(octave_cell::print_name_tag): Don't print new line if cell is empty.
+
+	* octave.cc (intern_argv): Don't install __argv__.
+
+	* defun-int.h (UNDERSCORIFY): Delete.
+	(DEFCONST_INTERNAL): Don't install double underscore versions of
+	constants since they aren't really needed.
+	(DEFCONSTX_INTERNAL): Likewise.
+
+2002-07-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.cc (symbol_table::clear (void)): Clear all records.
+	(symbol_table::clear (const std::string&)): Delete second arg.
+	Clear any symbol that matches, regardless of type.
+
+	* symtab.h (symbol_table::variable_name_list): New function.
+	(symbol_table::global_variable_name_list): Likewise.
+	(symbol_table::user_function_name_list): Likewise.
+
+	* symtab.h, symtab.cc (symbol_table::clear_variables): New function.
+	(symbol_table::clear_functions): Likewise.
+	(symbol_table::clear_globals): Likewise.
+	(symbol_table::clear_variable): New function.
+	(symbol_table::clear_function): Likewise.
+	(symbol_table::clear_global): Likewise.
+	(symbol_table::clear_variable_pattern): New function.
+	(symbol_table::clear_function_pattern): Likewise.
+	(symbol_table::clear_global_pattern): Likewise.
+
+	* variables.cc (name_matches_any_pattern): Rename from
+	var_matches_any_pattern.
+	(is_local_variable): New static inline function.
+	(maybe_warn_exclusive): Likewise.
+	(do_clear_all): Likewise.
+	(do_clear_functions): Likewise.
+	(do_clear_globals): Likewise.
+	(do_clear_variables): Likewise.
+	(do_clear_function): Likewise.
+	(do_clear_global): Likewise.
+	(do_clear_variable): Likewise.
+	(do_clear_symbol): Likewise.
+	(do_clear_function_pattern): Likewise.
+	(do_clear_global_pattern): Likewise.
+	(do_clear_variable_pattern): Likewise.
+	(do_clear_symbol_pattern): Likewise.
+	(do_clear_functions): Likewise.
+	(do_clear_functions): Likewise.
+	(do_clear_globals): Likewise.
+	(do_clear_variables): Likewise.
+	(do_clear_symbols): Likewise.
+	(do_matlab_compatible_clear): Likewise.
+	(CLEAR_OPTION_ERROR): New macro.
+	(Fclear): Rewrite for Matlab compatibility and to cope with new
+	symbol table semantics.
+
+2002-07-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.cc (symbol_table::clear): Simply clear everything.
+	(symbol_table::clear_functions, symbol_table::clear_globals,
+	symbol_table::clear_all): New functions.
+
+	* symtab.h (symbol_record::symbol_def::next_elem): Delete.
+	(symbol_record::symbol_def::symbol_def): Delete intializer.
+
+	* symtab.h, symtab.cc (symbol_record::push_def): Delete.
+	(symbol_record::remove_top_def): Delete.
+	(symbol_record::replace_all_defs): Delete.
+	(symbol_record::hides_fcn): Delete.
+	(symbol_record::hides_builtin): Delete.
+
+	* symtab.h (symbol_table::~symbol_table): Call clear before
+	deleting the table.
+
+	* variables.cc (initialize_symbol_tables): Create fbi_sym_tab too.
+	(Fexist): Look in fbi_sym_tab, not global_sym_tab.
+
+	* parse.y (function_symtab): Rename from global_symtab.
+	Set curr_sym_tab to fbi_sym_tab, not global_sym_tab.
+	Change all uses of global_symtab to be function_symtab instead.
+	(frob_function): Rename and look for function name in fbi_sym_tab,
+	not global_sym_tab.
+	(parse_fcn_file): Clear function name from fbi_sym_tab, not
+	global_sym_tab.
+
+	* load-save.cc (save_vars): Look for built-in vars in fbi_sym_tab.
+	* symtab.cc (symbol_record::link_to_builtin_variable): Likewise.
+	* variables.cc (is_builtin_variable): Likewise.
+	(bind_ans): Likewise.
+	(bind_builtin_constant): Likewise.
+	(bind_builtin_variable): Likewise.
+	(builtin_string_variable): Likewise.
+	(builtin_real_scalar_variable): Likewise.
+	(builtin_any_variable): Likewise.
+	(is_text_function_name): Likewise, for functions.
+	(force_link_to_function): Likewise.
+	(is_builtin_function_name): Likewise.
+	(is_mapper_function_name): Likewise.
+	(is_valid_function): Likewise.
+	(Fclear): Likewise.
+	(F__print_symtab_info__): Likewise.
+	* defun.cc (print_usage): Likewise.
+	(install_builtin_mapper): Likewise.
+	(install_builtin_function): Likewise.
+	(install_dld_function): Likewise.
+	(Falias): Likewise.
+	* dynamic-ld.cc (clear_function): Likewise.
+	* variables.cc (do_who): Likewise, for built-ins and functions.
+	(link_to_builtin_or_function): Likewise.
+	* help.cc (LIST_SYMBOLS): Likewise.
+	(make_name_list): Handle fbi_sym_tab too.
+
+	* variables.cc (fbi_sym_tab): New symbol table.
+	* variables.h (fbi_sym_tab): Provide decl.
+
+2002-07-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.h (symbol_record::alias): Delete unused arg force.
+	Change all callers.
+
+	* variables.cc (link_to_global_variable): Give local variable
+	global value.
+
+	* pt-id.cc (tree_identifier::link_to_global): Warn about global
+	variables that have been defined before being declared global.
+	for a global variable to be used before it is declared global.
+	* pt-decl.cc (tree_global_command::do_init): Handle possible error
+	from tree_identifier::link_to_global.
+
+2002-07-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.cc (silent_functions, Vsilent_functions): Move here.
+	(octave_value::print_with_name): Don't print anything if we are
+	evaluating a function and Vsilent_functions is true.
+
+	* pt-stmt.cc: From here.
+	(symbols_of_pt_stmt): Delete.
+	(tree_statement_list::eval): Don't bother with Vsilent_functions here.
+
+2002-07-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OPT_HANDLERS): New targets.
+	(doc-files): New target.
+	(gendoc.cc): Depend on doc-files, not $(DOC_FILES).
+
+	* DLD-FUNCTIONS/daspk.cc, DLD-FUNCTIONS/dasrt.cc,
+	DLD-FUNCTIONS/dassl.cc, DLD-FUNCTIONS/fsolve.cc,
+	DLD-FUNCTIONS/lsode.cc, DLD-FUNCTIONS/odessa.cc
+	DLD-FUNCTIONS/quad.cc: Replace option handling code with include
+	directive.
+
+2002-07-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-loop.cc (tree_simple_for_command::eval): Once we know the RHS
+	is a matrix type check for real_type, not real_matrix.
+
+2002-07-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/quad.cc (quad): Cope with changes to Quad constructors.
+
+2002-07-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/daspk.cc (Fdaspk): Also return istate and error
+	message.  Only generate error if user is not at least requesting
+	the istate output.
+	* DLD-FUNCTIONS/dasrt.cc (Fdasrt): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (Fdassl): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (Fodessa): Likewise.
+
+2002-07-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/dasrt.cc (Fdasrt): No need to find ng here.
+	(dasrt_user_j): New function.
+	(Fdasrt): Handle Jacobian function.
+
+	* DLD-FUNCTIONS/dassl.cc (dassl_user_jacobian): New function.
+	(Fdassl): Handle Jacobian function.
+
+	* DLD-FUNCTIONS/dasrt.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2002-07-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (@): Handle new token.
+	* parse.y (constant): Accept function handle syntax.
+	(make_constant): Create function handles here.
+
+2002-07-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun.cc (check_version): Improve error message.
+	* error.cc (warning): Only print backtrace once per warning series.
+	Print backtrace before warning messages.
+
+2002-07-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (maybe_unput_comma): Also handle '{' as an indexing op.
+
+	* DLD-FUNCTIONS/odessa.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2002-07-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-assign.cc (tree_multi_assignment::rvalue): Call
+	lhs->nargout_count, not lhs->length.
+
+	* pt-arg-list.cc (tree_argument_list::convert_to_const_vector):
+	Handle cs-list objects here.
+	(tree_argument_list::nargout_count): New function.
+	* pt-arg-list.h: Provide decl.
+
+	* ov-cs-list.h, ov-cs-list.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* ov.cc: Include ov-cs-list.h.
+	New arg, is_cs_list for constructor taking octave_value_list arg.
+	(install_types): Register ov_cs_list.
+	* ov.h (octave_value::is_cs_list): New function.
+	* ov-base.h (octave_base_value::is_cs_list): Likewise.
+	* ov-cell.cc (octave_cell::subsref): Return cs-list for "{" indexing.
+
+2002-07-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-mat.cc (Vempty_list_elements_ok): Default value is now 1.
+	* octave.cc (maximum_braindamage): No longer need to set value here.
+
+	* ov-usr-fcn.cc (Fva_arg, Fva_start, Fvr_val): Warn that these
+	functions are deprecated.
+	* lex.l (EL): Warn that `...' is deprecated.
+	* ov-usr-fcn.cc (octave_user_function::varargout_to_vr_val,
+	octave_user_function::has_varargout): New functions.
+	(Fvr_val): Ensure varargout is not defined.
+	(octave_user_function::do_multi_index_op): Copy values from
+	varargout here.
+
+2002-07-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.h (octave_user_function::varargin_sr): New data member.
+	* ov-usr-fcn.cc (octave_user_function::octave_user_function):
+	Initialize it.
+	(bind_automatic_vars): Handle varargin.  Change	all callers.
+
+	* octave.gperf: Handle varargin and varargout as keywords.
+	* lex.l (is_keyword): Likewise.
+	(IDENT): Move all actions into handle_identifier.
+	(handle_identifier): Now takes no args.
+
+	* lex.l (EL): Return VARARGIN or VARARGOUT, not ELLIPSIS.
+	* parse.y (param_list): Use VARARGIN instead of ELLIPSIS.
+	(return_list): Use VARARGOUT instead of ELLIPSIS.
+
+	* data.cc (make_diag const octave_value&, const octave_value&):
+	Allow first arg to be 1x0 or 0x1.
+
+2002-07-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (loadpath): Comment out previous change.
+
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Return message too.  Only
+	generate error if user is not at least requesting the info output.
+
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Fix typos in setting return value.
+
+2002-07-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (printf_value_cache::double_value): If the current
+	element is empty and there are no more elements in the value list,
+	set curr_state to conversion_error.
+
+	* input.cc (initialize_command_input): Include (, ), {, and } as
+	word break characters.
+
+	* variables.cc (looks_like_struct): Don't evaluate text if it is a
+	function.  From Ben Sapp <bsapp at lanl.gov>.
+
+	* symtab.h (symbol_record::is_function): Also return true if
+	symbol is a text function or a mapper function.
+
+2002-06-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (loadpath): Warn if loadpath doesn't contain
+	leading, trailing, or doubled colon.
+
+	* pt-decl.cc (tree_static_command::eval, tree_global_command::eval):
+	Call error for any non-zero value of error_state.
+	* pt-select.cc (tree_if_command::eval): Likewise.
+	* pt-loop.cc (tree_while_command::eval_error): Don't check error_state.
+	(tree_do_until_command::eval_error): Likewise.
+	(tree_simple_for_command::eval_error): Likewise.
+	(tree_complex_for_command::eval_error): Likewise.
+	* pt-assign.cc (tree_multi_assignment::eval_error): Likewise.
+	(tree_simple_assignment::eval_error): Likewise.
+	* pt-idx.cc (tree_index_expression::eval_error): Likewise.
+	* pt-colon.cc (tree_colon_expression::eval_error): Likewise.
+	(tree_colon_expression::rvalue): Delete rendundant error_state check.
+
+2002-06-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-mapper.cc (MAPPER_LOOP, MAPPER_LOOP_1, MAPPER_LOOP_2): New	macros.
+	(octave_mapper::apply): Use them to inline the mapper loops.
+
+	* pt-unop.cc (tree_prefix_expression::rvalue): Ensure that the
+	operand is defined for op_incr and op_decr.
+	(tree_postfix_expression::rvalue): Likewise.
+	From Ben Sapp <bsapp at lanl.gov>.
+
+2002-06-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-mapper.cc (octave_mapper::apply): Exit loops on error.
+
+2002-06-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-struct.cc (octave_struct::print_raw): Print field names with
+	data types if Vstruct_levels_to_print is 0.
+	(octave_struct::print_name_tag): Don't emit newline if
+	Vstruct_levels_to_print is negative.
+	* ov.cc (struct_levels_to_print): Allow negative values too.
+
+2002-05-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Also return istate and error
+	message.  Only generate error if user is not at least requesting
+	the istate output.
+
+	* load-save.cc (hdf5_import_multidim, hdf5_check_attr,
+	hdf5_callback_data, hdf5_read_next_data, read_hdf5_data,
+	add_hdf5_data): Use 0, not NULL in calls to HDF routines.
+
+	* oct-procbuf.cc (octave_procbuf::open): Use NULL, not 0 as last
+	arg in call to execl.
+
+	* debug.cc (get_user_function): Initialise dbg_fcn to 0, not NULL.
+
+2002-05-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/lsode.cc (LSODE_options::da_set_opt_mf,
+	LSODE_options::da_get_opt_mf): New typedefs.
+	(LSODE_OPTIONS::da_set_fcn, LSODE_OPTIONS::da_get_fcn): New fields.
+	(lsode_option_table): Fill them in.
+	(set_lsode_option (const Array<double>&)): New function.
+	(print_lsode_option_list): Handle vector options.
+	(show_lsode_option_list): Likewise.
+	(Flsode_options): Likewise.
+
+	* DLD-FUNCTIONS/lsode.cc (LSODE_options::s_set_opt_mf,
+	LSODE_options::s_get_opt_mf): New typedefs.
+	(LSODE_OPTIONS::s_set_fcn, LSODE_OPTIONS::s_get_fcn): New fields.
+	(lsode_option_table): Fill them in.
+	(set_lsode_option (const std::string&)): New function.
+	(print_lsode_option_list): Handle string options.
+	(show_lsode_option_list): Likewise.
+	(Flsode_options): Likewise.
+
+2002-05-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* c-file-ptr-stream.h (c_file_ptr_buf::fclose): New function.
+	(c_file_ptr_buf::c_file_ptr_buf): Use it as default argument
+	instead of extern "C" fclose function.
+	(i_c_file_ptr_stream::i_c_file_ptr_stream): Likewise.
+	(o_c_file_ptr_stream::o_c_file_ptr_stream): Likewise.
+	* oct-stdstrm.h (octave_istdiostream::octave_istdiostream): Likewise.
+	(octave_istdiostream::create): Likewise.
+	* oct-stdstrm.h (octave_ostdiostream::octave_ostdiostream): Likewise.
+	(octave_ostdiostream::create): Likewise.
+
+	* oct-prcstrm.cc (cxx_pclose): New static function.
+	(octave_iprocstream::octave_iprocstream): Pass it to
+	octave_istdiostream constructor instead of extern "C" pclose function.
+	(octave_oprocstream::octave_oprocstream): Pass it to
+	octave_ostdiostream constructor instead of extern "C" pclose function.
+
+	* debug.cc (Fdbtype): Use C++ strings, not C strings.
+
+2002-05-22  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* debug.cc: Include cstdlib instead of stdlib.h. Include cstring.
+	(dbtype): Use strchr instead of index.
+	* TEMPLATE-INST/Array-tc.cc (Array<octave_value>::resize_fill_value):
+	Fix template specialization syntax.
+
+2002-05-17  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* c-file-ptr-stream.h (OCTAVE_STD_FILEBUF): New macro to handle
+	various forms of extensions to std::filebuf.
+	(c_file_ptr_buf::c_file_ptr_buf): Use.
+	* pt-idx.cc (tree_index_expression::tree_index_expression): Remove
+	default arguments are from definition.
+	* symtab.cc (SYMBOL_DEF::print_info): Add std::.
+	(symbol_record::print_info): Likewise.
+	(symbol_table::print_info): Likewise.
+
+2002-05-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-map.cc (Octave_map::assign): Resize RHS if it is shorter
+	than existing struct array.
+
+	* ov-cell.cc (octave_cell::subsasgn): If an error has occurred,
+	skip final assignment step.
+	* ov-list.cc (octave_list::subsasgn): Likewise.
+	* oct-lvalue.cc (octave_lvalue::assign): Add parens to clarify intent.
+	(octave_lvalue::do_unary_op): Likewise.
+
+	* parse.y (function_end): Also accept end of input as end of
+	function if input is coming from an eval string.
+
+	* pr-output.cc (pr_any_float): Don't convert -0 to 0.
+
+2002-05-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (generate_completion): If it looks like we are
+	completing a struct, set completion append char to '\0'.
+
+	* variables.cc (generate_struct_completions): Temporarily set
+	warnings off here.
+
+	* error.cc (warning): Don't do anything if Vdebug_option == "off".
+	Only print backtrace if Vdebug_option == "backtrace".
+	(handle_message): Now returns a string containing the text of the
+	formatted message.  Change all callers.
+	(Fwarning): Now a text-style function.  Handle Matlab-compatible
+	warning options.
+	(Flasterr, Flastwarn, set_warning_option): New functions.
+	(Vlast_error_message, Vlast_warning_message, Vwarning_frequency,
+	Vwarning_option): New static variables.
+	(vwarning): Set Vlast_warning_message here too.
+	(verror): Set Vlast_error_message here too.
+
+2002-05-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::get_count): Now const.
+
+	* ov.h, ov.cc (octave_value::do_non_const_unary_op,
+	octave_value::assign): Idx is now a list of octave_value_list
+	objects.
+
+	* ov-base.cc, ov-base.h	(octave_base_value::do_struct_elt_index_op,
+	octave_base_value::struct_elt_ref): Delete.
+	* ov-struct.cc, ov-struct.h (octave_sruct::do_struct_elt_index_op,
+	octave_struct::struct_elt_ref): Delete.
+	* ov.cc, ov.h (octave_value::do_struct_elt_index_op,
+	octave_value::struct_elt_ref, octave_value::assign_struct_elt,
+	octave_value::convert_and_assign, octave_value::try_assignment,
+	octave_value::try_assignment_with_conversion,
+	octave_value::simple_assign): Delete.
+
+	* parse.y (make_index_expression): Type is now a single
+	character.  Change all callers.  If expr is already an index
+	expression, append index to it.
+	(make_indirect_ref): Likewise.
+
+	* pt-pr-code.cc (octave_print_internal (std::ostream&, const
+	Cell&, bool, int)): Now just a dummy function, panic if called.
+
+	* pt-idx.cc (tree_index_expression::make_arg_struct): New function.
+	(tree_index_expression::type): Delete enum, rename from itype, now
+	a string.
+	(tree_index_expression::arg_nm): Now a list of string_vector objects.
+	(tree_index_expression::idx): Now a list of tree_argument_list*
+	objects.
+	(tree_index_expression::is_index_expression): Always return true.
+	(tree_index_expression::apend, make_value_list, make_subs_cell):
+	New functions.
+	
+	* pt-pr-code.cc (visit_index_expression): Handle new definition of
+	tree_index_expression object.
+	* pt-check.cc (visit_index_expression): Likewise.
+	* pt-bp.cc (visit_index_expression): Likewise.
+
+	* ov-usr-fcn.h (octave_user_function::restore_args_passed):
+	Clear args_passed even if nothing was saved.
+
+	* ov-base.cc (octave_base_value::subsasgn,
+	octave_base_value::map_keys, octave_base_value::print_info):
+	New functions.
+
+	* ov.h, ov.cc (octave_value::map_keys, octave_value::print_info,
+	octave_value::subsref, octave_value::subsasgn,
+	octave_value::numeric_assign, octave_value::next_subsref):
+	New functions.
+	(octave_value::empty_conv): New static function.
+	(octave_value (octave_value *, int)): New arg, count.
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::subsref,
+	octave_base_matrix<MT>::subsasgn): New functions.
+	* ov-base-mat.h: Provide decls.
+
+	* ov-builtin.cc (octave_builtin::subsref): New function.
+	* ov-builtin.h: Provide decl.
+
+	* ov-range.cc (octave_range::subsref): New function.
+	* ov-range.h: Provide decl.
+
+	* ov-cell.cc (octave_cell::subsref, octave_cell::subsasgn,
+	octave_cell::list_value, octave_cell::print,
+	octave_cell::print_raw, octave_cell::print_name_tag): New functions.
+	* ov-cell.h: Provide decls.
+
+	* ov-struct.cc (octave_struct::dotref, octave_struct::subsref,
+	octave_struct::subsasgn, gripe_invalid_index,
+	gripe_invalid_index_for_assignment, grip_invalid_index_type,
+	gripe_failed_assignment): New functions.
+	(octave_struct::numeric_conv): New static function.
+	* ov-struct.h: Provide decls.
+	(octave_struct::is_constant): Return true.
+	(octave_struct::map_keys): New function.
+
+	* ov-list.cc (octave_list::subsref, octave_list::subsasgn):
+	New functions.
+	* ov-list.h: Provide decls.
+
+	* ov-usr-fcn.cc (octave_user_function::subsref,
+	octave_user_function::print_symtab_info): New functions.
+	* ov-usr-fcn.h: Provide decl.
+
+	* ov-mapper.cc (octave_mapper::subsref): New function.
+	* ov-mapper.h: Provide decl.
+
+	* ov-base.cc (octave_base_value::subsref,
+	octave_base_value::subsasgn): New functions.
+	* ov-base.h: Provide decls.
+
+	* ov-base.cc (octave_base_value::do_index_op): New arg, resize_ok.
+	* ov-base-mat.cc (octave_base_matrix<MT>::do_index_op): Likewise.
+	* ov-base-nd-array.cc (octave_base_nd_array<AT>::do_index_op): Ditto.
+	* ov-bool-mat.cc (octave_bool::do_index_op): Ditto.
+	* ov-str-mat.cc (octave_char_matrix_str::do_index_op): Ditto.
+	* ov-range.cc (octave_range::do_index_op): Ditto.
+	* ov-list.cc (octave_list::do_index_op): Ditto.
+	* ov.cc (octave_value::do_index_op): Ditto.
+	
+	* ov-base-mat.cc (octave_base_matrix<MT>::print_info): New function.
+
+	* ov-base-mat.h (octave_base_matrix<MT>::empty_clone): New function.
+	* ov-base-nd-array.h (octave_base_nd_array<AT>::empty_clone): Ditto.
+	* ov-base.h (octave_base_value::empty_clone): Ditto.
+	* ov-bool-mat.h (octave_bool::empty_clone): Ditto.
+	* ov-ch-mat.h (octave_char_matrix::empty_clone): Likewise.
+	* ov-colon.h (octave_magic_colon::empty_clone): Likewise.
+	* ov-complex.h (octave_complex::empty_clone): Likewise.
+	* ov-cx-mat.h (octave_complex_matrix::empty_clone): Likewise.
+	* ov-fcn.cc (octave_function::empty_clone): Likewise.
+	* ov-file.h (octave_file::empty_clone): Likewise.
+	* ov-range.h (octave_range::empty_clone): Likewise.
+	* ov-list.h (octave_list::empty_clone): Likewise.
+	* ov-re-mat.h (octave_matrix::empty_clone): Likewise.
+	* ov-re-nd-array.h (octave_double_nd_array::empty_clone): Likewise.
+	* ov-str-mat.h (octave_char_matrix_str::empty_clone): Likewise.
+	* ov-struct.h (octave_struct::empty_clone): Likewise.
+	* ov-va_args.h (octave_all_va_args::empty_clone): Likewise.
+	* ov.h (octave_value::empty_clone): Likewise.
+
+	* ov-base-mat.h (octave_base_matrix<MT>::clone): Now const.
+	* ov-base-nd-array.h (octave_base_nd_array<AT>::clone): Likewise.
+	* ov-base.h (octave_base_value::clone): Likewise.
+	* ov-bool-mat.h (octave_bool::clone): Likewise.
+	* ov-ch-mat.h (octave_char_matrix::clone): Likewise.
+	* ov-colon.h (octave_magic_colon::clone): Likewise.
+	* ov-complex.h (octave_complex::clone): Likewise.
+	* ov-cx-mat.h (octave_complex_matrix::clone): Likewise.
+	* ov-fcn.h (octave_function::clone): Likewise.
+	* ov-file.h (octave_file::clone): Likewise.
+	* ov-range.h (octave_range::clone): Likewise.
+	* ov-list.h (octave_list::clone): Likewise.
+	* ov-re-mat.h (octave_matrix::clone): Likewise.
+	* ov-re-nd-array.h (octave_double_nd_array::clone): Likewise.
+	* ov-str-mat.h (octave_char_matrix_str::clone): Likewise.
+	* ov-struct.h (octave_struct::clone): Likewise.
+	* ov-va_args.h (octave_all_va_args::clone): Likewise.
+	* ov.h (octave_value::clone): Likewise.
+
+	* oct-lvalue.cc (octave_lvalue::assign, octave_lvalue::set_index,
+	octave_lvalue::do_unary_op): Idx is now a list of indices.  Simplify.
+	* oct-lvalue.h (octave_lvalue::value): Simplify.
+	(octave_lvalue::struct_elt_names): Delete data member.
+	(octave_lvalue::type): Now string
+	Update decls.
+
+	* pt-exp.h (tree_expression::is_indirect_ref):
+	Delete virtual function.
+
+	* pt-plot.cc (subplot::extract_plot_data): Use subsref, instead of
+	do_index_op.
+
+	* pt-stmt.cc (tree_statement::eval): Don't try to avoid binding
+	ans for structure references.
+
+	* symtab.cc (symbol_record::symbol_def::print_info): Rename from
+	symbol_record::symbol_def::dump_symbol_info.
+	(symbol_record::print_info): Rename from
+	symbol_record::dump_symbol_info.  Now const..
+	(symbol_record::print_symbol_info_line): Now const.
+	(symbol_table::print_info): Rename from print_stats.  Accept
+	ostream arg.  Now const.  Print more info.
+	* symtab.h: Update decls.
+
+	* toplev.cc (octave_config_info): Indexing a map now returns a
+	list, but we only want to return the first element.
+
+	* variables.cc (generate_struct_completions, looks_like_struct):
+	Simplify using eval_string.
+	(F__print_symtab_info__): Rename from F__dump_symtab_info__.
+	Handle "top-level" and individual function names in addition to
+	"global".
+	(F__print_symbol_info__): Rename from F___dump_symbol_info__.
+
+	* octave.cc (intern_argv): Built-in variable argv is now a cell array.
+
+	* ov-complex.cc (valid_scalar_indices): Delete.
+	* ov-scalar.cc (valid_scalar_indices): Delete.
+
+	* oct-obj.cc (octave_value_list::valid_scalar_indices): New function.
+	(octave_value_list::index): New arg, resize_ok.
+	* oct-obj.h: Provide decls.
+
+	* oct-map.cc (Octave_map::keys): Rename from make_name_list.
+	Change all uses.
+	(Octave_map::assign, Octave_map::index): New functions.
+	* oct-map.h: Provide decls.
+
+	* data.cc (Fstruct_contains): Use map_value instead of
+	do_struct_elt_index_op.
+
+	* Cell.h (Cell (const Array2<octave_value>&, int, int)):
+	New constructor.
+	(Cell::resize_fill_value): New static function.
+
+	* input.cc (initialize_command_input): Set basic and completer
+	word break characters.
+
+2002-05-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::subsref): New function.
+	* ov-base.cc (octave_base_value::subsref): Likewise.
+
+	* ov-struct.cc (octave_struct::print_raw): Print scalar struct
+	arrays more compactly.
+
+	* DLD-FUNCTIONS/time.cc (extract_tm): Handle new struct array def.
+
+	* oct-map.cc (Octave_map::array_len): New data member.
+	(Octave_map::operator[], Octave_map::contsnts): Return
+	octave_value_list, not Octave_value.  Change callers as necessary.
+	(Octave_map::assign): New function.
+	(Octave_map::array_length): New fucntion.
+	* oct-obj.cc (octave_value_list::assign): New function.
+	
+2002-05-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* TEMPLATE-INST/Map-oct-obj.cc: New file.
+	* Makefile.in (TI_XSRC): Add it to the list.
+
+	* oct-map.h (Octave_map): Make CHMap<octave_value_list> a data
+	member instead of deriving from CHMap<octave_value>, in
+	preparation for structure arrays.
+
+	* pt-indir.h, pt-indir.cc: Delete.
+
+	* pt-all.h: Don't include pt-indir.h.
+
+	* Makefile.in (PT_SRC): Delete pt-indir.cc from the list.
+	(PT_INCLUDES): Delete pt-indir.h from the list.
+
+	* pt-walk.h (tree_walker::visit_indirect_ref): Delete.
+	* pt-pr-code.h, pt-pr-code.cc (tree_print_code::visit_indirect_ref):
+	Likewise.
+	* pt-check.h, pt-check.cc (tree_checker::visit_indirect_ref): Likewise.
+	* pt-bp.h, pt-bp.cc (tree_breakpoint::visit_indirect_ref): Likewise.
+
+	* pt-walk.h: Delete forward decl for tree_indirect_ref.
+	* variables.h: Likewise.
+
+	* parse.y (make_indirect_ref): Return tree_index_expression, not
+	tree_indirect_ref.
+
+	* pt-idx.h (tree_index_expression::struct_elt_name): New function.
+
+	* pt-idx.cc (tree_index_expression::lvalue): Handle dot case too.
+	(tree_index_expression::name): Likewise.
+	(tree_index_expression rvalue (int)): Likewise.
+	(tree_index_expression::eval_error): Likewise.
+	* pt-pr-code.cc (visit_index_expression): Likewise.
+	* pt-bp.cc (tree_breakpoint::visit_index_expression): Likewise.
+
+	* pt-idx.h (tree_index_expression::dot): New type enum element.
+	(tree_index_expression::expr_type): New function.
+	(tree_index_expression::tree_index_expression (tree_expression*,
+	const std::string&, int, int)): New constructor.
+	(tree_index_expression::is_index_expression): Return value is now
+	conditional on itype.
+	(tree_index_expression::is_indirect_ref): New function.
+	(tree_index_expression::lvalue_ok): Also return true if itype is dot.
+
+2002-05-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (ABORT_PARSE): Maybe restore symbol table context too.
+
+	* pt-idx.h (tree_index_expression::type): New enum.
+	(tree_index_expression::etype): New data member.
+	* pt-idx.h (tree_index_expression::tree_index_expression):
+	New arg, t, to set type of index.
+	* parse.y (make_index_expression): Likewise.
+	Change all callers.
+
+	* ov-base.cc (cell_conv): New conversion function.
+	(install_base_type_conversions): Install it.
+	Install conversion for indexed assignment of octave_cells to
+	undefined values.
+
+	* TEMPLATE-INST/Array-tc.cc: Instantiate assign functions too.
+	(Array<octave_value>::resize_fill_value (void)):
+	Provide specialization for octave_value.
+
+	* ov-cell.cc (octave_cell::assign (const octave_value_list&,
+	const octave_value&)): New function.
+	* Cell.h (Cell::Cell (const octave_value&)): New function.
+
+	* OPERATORS/op-cell.cc (install_list_ops): Use DEFASSIGNANYOP_FN
+	and INSTALL_ASSIGNANYOP, not DEFASSIGNOP_FN and INSTALL_ASSIGNOP.
+
+2002-05-03  Cai Jianming  <caijianming at yahoo.co.uk>
+
+	* OPERATORS/op-cell.cc: New file.
+	* Makefile.in (OP_XSRC): Include it in the list.
+
+	* parse.y (cell): Return a cell type instead of Matrix type.
+
+	* ov.cc (install_types): Install octave_cell type.
+
+	* pr-output.cc (octave_print_internal): Handle Cells.
+	* pr-output.h (octave_print_internal): Provide decl.
+
+	* ov-cell.h (octave_cell): Derive from octave_base_matrix<Cell>.
+	* ov-cell.cc (do_index_op, assign, print, print_raw,
+	print_name_tag): Delete.
+
+	* Cell.cc (allocator, index): Delete.
+	* Cell.h (Cell): Derive from Array2<octave_value>.
+	Most functions removed since we can use those from Array2 instead.
+
+2002-05-02  Cai Jianming  <caijianming at yahoo.co.uk>
+
+	* ov-base-mat.cc (octave_base_matrix<MT>::assign):
+	New function.
+	* ov-base-mat.h (octave_base_matrix<MT>::assign): Provide decl.
+	* ov-bool-mat.cc (octave_bool_matrix::assign): Delete.
+	* ov-bool-mat.h (octave_bool_matrix:assign): Delete decl
+	* ov-cx-mat.cc (octave_complex_matrix::assign (const
+	octave_value_list& idx, const ComplexMatrix&)): Delete.
+	* ov-cx-mat.h (octave_complex_matrix:assign (const
+	octave_value_list& idx, const ComplexMatrix&)): Replace decl with
+	function.
+	* ov-re-mat.cc (octave_bool_matrix::assign): Delete.
+	* ov-re-mat.h (octave_bool_matrix:assign): Delete decl.
+	
+2002-05-02  Cai Jianming  <caijianming at yahoo.co.uk>
+
+	* OPERATORS/op-bm-b.cc: New file.x
+	* Makefile.in (OP_XSRC): Add it to the list.
+
+2002-04-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (print_version_and_exit): Use
+	OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY, not
+	OCTAVE_NAME_AND_VERSION.
+
+	* octave.cc (verbose_usage): 
+	Use OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY, not
+	OCTAVE_NAME_VERSION_AND_COPYRIGHT.
+
+	* version.h (OCTAVE_COPYING_STATEMENT, OCTAVE_WARRANTY_STATEMENT,
+	OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY,
+	X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS,
+	OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS,
+	OCTAVE_BUGS_STATEMENT): New macros.
+	(OCTAVE_STARTUP_MESSAGE): Define in terms of
+	X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS
+	to include bugs address and amplified warranty information.
+
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Delete unused variable nsteps.
+
+2002-04-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (additional_help_message): Use www.octave.org, not
+	www.che.wisc.edu/octave/octave.html.
+	* octave.cc (verbose_usage): Likewise.
+
+2002-04-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/daspk.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+2002-04-25  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* DLD-FUNCTIONS/kron.cc: New file.
+	* Makefile.in (DLD_SRC): Add it to the list.
+
+2002-04-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (save_symtab): New non-terminal.  Save current symbol
+	table context here.
+	(function_beg): Use it.
+	(symtab_context): New file-scope variable.
+	(recover_from_parsing_function): Restore symbol table context here.
+
+2002-04-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (get_lines_and_columns): Handle CRLF as line
+	separator in addition to LF.
+
+2002-04-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (hdf5_ofstream::hdf5_ofstream):
+	Explicitly List std::ostream(0) in constructor.
+	(hdf5_ifstream::hdf5_ifstream):
+	Explicitly List std::istream(0) in constructor.
+	(hdf5_fstreambase::hdf5_fstreambase): Use std::ios::setstate, not set.
+	(hdf5_fstreambase::close): Likewise.
+	(hdf5_fstreambase::open): Likewise.
+
+2002-04-10  Ben Sapp  <bsapp at lanl.gov>
+
+	* pt-stmt.cc (delete_breakpoint): List breakpoints if line < 0.
+	* debug.cc (get_user_function): Check symbol by name first.
+	(Fdbstop): Rename from Fdbg_set.
+	(Fdbclear): Rename from Fdbg_delete.
+	(Fdbstatus): Rename from Fdbg_list.
+	(Fdbg_where): Rename from Fdbwhere.
+	(do_dbtype, Fdbtype): New functions.
+
+2002-04-10  Peter Van Wieren  <peter.vanwiere at avlna.com>
+
+	* load-save.cc (save_mat5_binary_element): Save elements of 2d
+	character matrices in proper order.
+
+2002-04-09  Paul Kienzle  <pkienzle at users.sf.net>
+
+	* utils.cc (do_string_escapes): Handle \0 too.
+	(undo_string_escape): Likewise.
+
+2002-04-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (octave_config_info): Define struct member EXEEXT, not EXE.
+	* Makefile.in (install-bin): Use $(EXEEXT), not $(EXE).
+	* oct-conf.h.in (OCTAVE_CONF_EXEEXT): Define and substitute
+	OCTAVE_CONF_EXEEXT, not OCTAVE_CONF_EXE.
+
+2002-04-03  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* DLD-FUNCTIONS/balance.cc: Use F77_FUNC instead of F77_FCN.
+	* DLD-FUNCTIONS/qz.cc: Likewise.
+	* DLD-FUNCTIONS/rand.cc: Likewise.
+	* octave.cc: Likewise.
+	* toplev.cc (Foctave_config_info): Delete use of FORTRAN_MAIN_FLAG.
+	* oct-conf.h.in: Delete use of OCTAVE_CONF_FORTRAN_MAIN_FLAG.
+	* syscalls.cc (mk_stat_map):
+	Use HAVE_STRUCT_STAT_ST_RDEV instead of HAVE_ST_RDEV.
+	Use HAVE_STRUCT_STAT_ST_BLKSIZE instead of HAVE_ST_BLKSIZE.
+	Use HAVE_STRUCT_STAT_ST_BLOCKS instead of HAVE_ST_BLOCKS.
+
+2002-04-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l, lex.h (parser_end_of_input): New global variable.
+	(reset_parser): Reset it here.
+	* parse.y (input): Set it to TRUE on EOF.
+	(parse_and_executed): Save and restore it, check it to correctly
+	break out of parse-execute loop.
+	(parse_fcn_file): Likewise.
+	(eval_string): Likewise.
+	* toplev.cc (main_loop): Likewise.	
+
+	* parse.y (input): Call YYACCEPT for END_OF_INPUT.
+	Return no-op command for bare newline.
+	(parse_and_execute): Handle change in yyparse return value semantics.
+
+	* toplev.cc (main_loop): Likewise.
+
+2002-03-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (parse_fcn_file): Call error if there is no input file.
+	(parse_and_execute (FILE *): Protect get_input_from_eval_string.
+	Set get_input_from_eval_string to false before calling yyparse.
+	* lex.l (reset_parser): Also skip yyrestart (stdin) if
+	reading_script_file is true.
+
+2002-03-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-loop.cc (evaluating_looping_command): New global.
+	(tree_while_command::eval): Protect evaluating_looping_command.
+	Set it to true while evaluating loop.
+	(tree_do_until_command::eval): Ditto.
+	(tree_simple_for_command::eval): Ditto.
+	(tree_complex_for_command::eval): Ditto.
+	* pt-loop.h (evaluating_looping_command): Provide decl.
+	* parse.y (parse_fcn_file): Protect get_input_from_eval_string.
+	Set get_input_from_eval_string to false before calling yyparse.
+	(make_break_command): Also check evaluating_looping_command.
+	(make_continue_command): Also check evaluating_looping_command.
+	(eval_string (const std::string&, bool, int&, int)): Loop over
+	yyparse to handle multi-line strings.
+	Move call to unwind_protect::run_frame to end of function.
+	Don't reset parser before calling yyparse.
+	Correctly handle return, break, and continue.
+
+	* input.cc (input_from_eval_string_pending): New global variable.
+	(get_usr_input): Use it.
+	* input.h (input_from_eval_string_pending): Provide decl.
+
+2002-03-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Don't unwind_protect num_named_args (it doesn't change on
+	recursive calls).
+	Do re-initialize curr_va_arg_number to num_named_args after
+	unwind_protecting.
+
+	* ov-usr-fcn.h (octave_user_function::clear_args_passed): Delete.
+	(octave_user_function::saved_args): New data member.
+	(octave_user_function::save_args_passed): New function.
+	(octave_user_function::restore_args_passed): Ditto.
+	* ov-usr-fcn.cc (clear_args_passed): Delete.
+	(restore_args_passed): New function.
+	(octave_user_function::do_multi_index_op): Correctly save and
+	restore args passed for recursive calls.
+
+	* TEMPLATE-INST/SLStack-ovl.cc: New file.
+	* Makefile.in: Add it to the list.
+
+2002-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
+	Handle define_all_return_values after function is evaluated.
+	From Paul Kienzle <pkienzle at jazz.ncnr.nist.gov>.
+
+	* ov-scalar.cc (convert_to_str): Use octave_value (std::string)
+	constructor instead of octave_value (char *) constructor so that
+	setstr (0) will work.
+
+	* pager.cc (octave_pager_buf::sync): Set pointer to beginning
+	of buffer after calling flush_currnt_contents_to_diary.
+	(octave_diary_buf::sync): Call eback only once.
+
+2002-01-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (.): Remove test for EOF since it is already handled
+	separately.
+
+2001-12-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_mat5_binary_element):
+	Extract dimensions directly from tc.
+	Handle ranges the same as real matrices.
+
+2001-11-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (DATA_REDUCTION): If no DIM arg, pass -1 to FCN.
+
+2001-11-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-conf.h.in (FFTW_LIBS, LD_CXX, LIBOCT_PATHSEARCH,
+	LIBOCT_READLINE, MKOCTFILE_LFLAGS): Substitute.
+	* toplev.cc (octave_config_info): Add them to the map.
+
+2001-11-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Don't bother to give OUTPUT
+	matrix a size before calling integration function.
+
+2001-11-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	Makefile.in (OCTAVE_LIBS): Add $(LIBOCT_READLINE) and
+	$(LIBOCT_PATHSEARCH) to the list.
+
+2001-10-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/dassl.cc (dassl_user_function): Allow user
+	supplied RES function to return IDID as second value.
+
+2001-07-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y: Clear help_buf after documenting function.
+
+2001-06-29  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* defun-int.h (DEFINE_FUN_INSTALLER_FUN{2,3}): New macros.
+	(DEFINE_FUN_INSTALLER_FUN): Use.
+	* dynamic-ld.cc ({STRINGIFY, STRINGIFY1}): New macros.
+	(octave_dynamic_loader::mangle_name): Support dynamic linking
+	for GNU v3 and Sun C++ ABI.
+
+2001-06-26  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* c-file-ptr-stream.h (c_file_ptr_buf::c_file_ptr_buf): Add GCC3
+	libstdc++-v3 support.
+	* load-save.cc (save_mat5_binary_element): Cast arguments to the
+	correct type.
+	(save_ascii_data): Eliminate compiler warning.
+	* toplev.cc (system): Prefix std::.
+
+2001-05-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cx-mat.cc: Deleve unnecessary instantiation of assign function.
+	* ov-re-mat.cc: Likewise.
+	* ov-re-nd-array.cc: Likewise.
+	* ov-str-mat.cc: Likewise.
+	* ov-bool-mat.cc: Likewise.
+
+	* load-save.cc (save_ascii_data): When saving string data, get raw
+	string value for matrix row since there may be embedded nuls.
+
+	* pt-mat.cc (Vstring_fill_char): No longer static.
+	* pt-mat.h: Provide declaration.
+
+2001-05-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (initialize_pathsearch): Save initial value of the
+	TEXMFDBS environment variable here.
+	* toplev.cc (restore_texmfdbs_envvar): New function.
+	(Fsystem): Set TEXMFDBS back to original value before running
+	subprocesses.
+
+2001-05-02  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* Makefile.in (octave): Add $(FFTW_LIBS).
+
+2001-04-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/sort.cc (mx_sort): Check for NaNs in comparisons.
+
+2001-04-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCTAVE_LIBS): Delete $(LIBREADLINE) from the list.
+	(octave): Delete TERMLIBS from link command.
+	* oct-conf.h.in: Delete references to LIBREADLINE, TERMLIBS.
+	* toplev.cc (octave_config_info): Delete entries for LIBREADLINE,
+	TERMLIBS.
+
+2001-04-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-lib): Don't use mk-libdir-link.
+	(install-inc): Don't use mk-includedir-link.
+
+2001-04-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (fold (tree_binary_expression *)):
+	Set discard_error_messages here instead of buffer_error_messages.
+	Don't add clear_global_error_variable to the unwind_protect stack.
+	(fold (tree_unary_expression *)): Likewise.
+	(finish_colon_expression): Likewise.
+	(finish_matrix): Likewise.
+
+	* error.cc (panic): Set discard_error_messages to false here.
+	(verror): Return immediately if discard_error_messages is true.
+
+	* error.cc (discard_error_messages): New global variable.
+	* error.h: Provide declaration.
+
+2001-04-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l: If unexpected character is EOF, report EOF error instead
+	of invalid character error.
+
+2001-04-18  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* load-save.cc (read_mat5_binary_element): Cast arguments to the
+	correct type when adding stream positions.
+	* DLD-FUNCTIONS/det.cc (det): Explicity create a Complex value to
+	work around a Sun C++ type conversion bug.
+
+2001-04-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.cc (define_builtin_const): Don't call replace_all_defs
+	here.
+
+	* error.cc (error_message_buffer): Now static.
+	* error.h (error_message_buffer): Delete extern declaration.
+
+2001-03-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/besselj.cc (besselh): Use K arg.
+	From: Thomas Stuart <tstuart at ing.sun.ac.za>.
+
+	* oct-stream.cc (get_size): Don't allow [Inf, N] as a size
+	specification for the read and scanf functions.
+	(get_size): SIZE is now an Array<double> instead of a Matrix object.
+	(read): Likewise.  Change all callers.
+	(scanf): Likewise.  Change all callers.
+
+2001-03-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/det.cc (Fdet): Only return rcond if nargout > 1.
+	* DLD-FUNCTIONS/inv.cc (Finv): Only return rcond if nargout > 1.
+
+2001-03-26  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* DLD-FUNCTIONS/det.cc (Fdet): Suppress warning, but return rcond.
+	* DLD_FUNCTIONS/inv.cc (Finv): Return rcond if requested.
+
+2001-02-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt.h (tree::break_statement): New static member.
+	(tree::break_function): Make const.
+	* pt.cc (tree::break_statement): Initialize here.
+	(tree::break_function): Make const.
+	* pb-bp.h (break_statement): Delete global varaible declaration.
+	* pt-bp.cc (break_statement): Delete global variable definition.
+
+	* pt-bp.h (tree_breakpoint::bp_list): Rename from lst.
+
+	* pt.h: Don't inlcude ov-usr-fcn.h.
+	Provide forward declaration of octave_user_function class.
+
+2001-02-28  Ben Sapp  <bsapp at lanl.gov>
+
+	* debug.cc (get_user_function): Simplify by using curr_function.
+	(Fdbg_where): New function.
+	(Fdbg_list): Now DLD_TEXT instead of DLD_FCN.
+	(Fdbg_set): Likewise.
+	(Fdbg_delete): Likewise. 
+
+	* pt-bp.h (break_statement): New global variable.
+	(MAYBE_DO_BREAKPOINT): Check for dbg_next and dbg_step.
+	Print line, column, and current statement.
+	* pt-bp.cc (break_statement): New global variable
+	(tree_breakpoint::visit_do_until_command): Return immediately if
+	we've already found the line.
+	(tree_breakpoint::visit_colon_expression): Set breakpoint info here.
+	(tree_breakpoint::visit_binary_expression): Recurse here when
+	checking for breakpoints.
+
+	* debug.cc: Move here from DLD-FUNCTIONS/debug.cc.
+	* Makefile.in (DIST_SRC): Add it to the list.
+	(DLD_XSRC): Delete it from the list.
+
+	* pt.h (tree::last_line, tree::break_function): New static members.
+	* pt.cc(tree::last_line, tree::break_function): Initialize them.
+
+	* pt-cell.h (tree_cell::tree_cell): Accept line and column info.
+	* pt-mat.h (tree_matrix::tree_matrix): Likewise.
+
+	* ov-usr-fcn.h (octave_user_function::sym_tab): Delete.
+
+	* input.cc (get_user_input): Handle dbg_next.
+	Set tree:break_function and tree::last_line when doing dbg_step.
+
+2001-02-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_string): Save line and column information in token.
+	(is_keyword): Save line and column information for plot style and
+	axes tokens.
+
+	* toplev.cc (main_loop): Set retval to non-zero value if error
+	occurs when not interactive.
+
+2001-02-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (gobble_leading_white_space): Handle CRLF here too.
+	* lex.l (check_for_garbage_after_fcn_def): Likewise.
+
+	* lex.l: Add numeric value of character to error message for
+	unrecognized characters.
+
+2001-02-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/minmax.cc (EMPTY_RETURN_CHECK): For empty matrix
+	args, make Octave's min	and max behave like Matlab.
+
+2001-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-s-s.cc (el_or, el_and): Return bool value.
+
+2001-02-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-binop.cc (tree_boolean_expression::rvalue):
+	Don't cast result to double.
+
+	* OPERATORS/op-b-b.cc: Allow & and | operators to return bool values.
+
+2001-02-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (DATA_REDUCTION): Undo previous change.
+
+2001-02-13  Matthew W. Roberts  <matt at nephi.tamu.edu>
+
+	* load-save.cc (Fload): Accept -4 as an alias for -v4 and -mat4-binary.
+	(Fsave): Likewise.
+
+2001-02-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (lexical_feedbac::init):
+	Initialize looking_at_matrix_or_assign_lhs too.
+
+2001-02-09  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (DATA_REDUCTION): Allow FCN(x,0) to be equivalent to FCN(x).
+
+2001-02-06  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* oct-stream.cc (octave_scan): Partially implement and specialize
+	for char*.  Delete the old template instantiations.
+	(BEGIN_S_CONVERSION): Use strings instead of ostrstreambuf.
+	(octave_base_stream::do_scanf): Pass correct parameter to
+	do_scan_conv.
+
+2001-02-05  Mumit Khan  <khan at nanotech.wisc.edu>
+
+	* pr-output.cc (set_format): Add std:: namespace qualifier as
+	needed.
+
+	* oct-stream.cc (octave_scan): Implement, and specialize for
+	char*. Delete the old template instantiations.
+	(BEGIN_S_CONVERSION): Use strings instead of ostrstreambuf.
+	(octave_base_stream::do_scanf): Pass correct parameter to
+	do_scan_conv.
+
+	* Makefile.in (TEMPLATE_AR, TEMPLATE_ARFLAGS): Use to create
+	archive libraries containing templates.
+
+	* c-file-ptr-stream.h: Include <fstream>. Use <cstdio> instead of
+	<stdio.h>
+	(c_file_ptr_buf::int_type): Compat typedef for non-ISO libstdc++.
+	(c_file_ptr_buf::{overflow, underflow, uflow, pbackfail): Use.
+	(c_file_ptr_buf::c_file_ptr_buf): Handle various compilers.
+	(c_file_ptr_buf::file_number): New member function.
+	(c_file_ptr_buf::fd): New private data.
+	(i_c_file_ptr_stream::i_c_file_ptr_stream): Initialize stream
+	correctly.
+	(o_c_file_ptr_stream::o_c_file_ptr_stream): Likewise.
+	* c-file-ptr-stream.cc 
+	(c_file_ptr_buf::{overflow, underflow, uflow, pbackfail): Add
+	ISO-compliant EOF handling.
+	* oct-stream.cc (octave_base_stream::file_number): Use 
+	c_file_ptr_buf::file_number to get underlying file descriptor.
+
+	* comment-list.cc: Add missing class qualifier.
+
+	* file-io.cc, load-save.cc, mappers.cc, oct-fstrm.cc, oct-fstrm.h,
+	oct-iostrm.cc, oct-iostrm.h, oct-stdstrm.cc, oct-stdstrm.h,
+	oct-stream.cc, oct-stream.h, oct-strstrm.cc, oct-strstrm.h,
+	ov-base-nd-array.cc, ov-base-scalar.h, ov-complex.cc, ov-cx-mat.cc,
+	pager.cc, pr-output.cc, procstream.h, pt-bp.h, utils.cc:
+	Add std:: namespace qualifier as needed, and replace
+	deprecated or invalid libstdc++-v2 names with standard ones
+	where appropriate.
+
+	* DLD-FUNCTIONS/minmax.cc: Fix docstring.
+
+	* oct-fstrm.cc (octave_fstream::octave_fstream): Maintain fix for
+	libstdc++-v2.
+
+	* oct-stdstrm.cc (octave_ostdiostream::create): Remove default
+	parameter value in definition.
+
+	* oct-stream.cc (octave_stream::mode_as_string): Don't assume 
+	std::iso::openmode is an integral quantity.
+
+	* pager.cc, procstream.h: Initialize streams correctly.
+
+	* utils.cc: Use CXX_ISO_COMPLIANT_LIBRARY guard.
+
+	* ov-base-nd-array.cc (idx_list_to_idx_array): Inline. 
+
+	* ov-base-scalar.h (octave_base_scalar::octave_base_scalar): Use
+	``const ST& s'' instead of ST to workaround gcc3 complex bug.
+
+2001-02-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (next_token_is_bin_op): Remove Checks for spacing except
+	for ops that begin with +, - but are not ++, --, +=, or -=.
+
+2001-02-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (get_user_input): Handle dbg_cont and dbg_step here.
+	* debug.cc (Fdbg_cont): Delete.
+	* pt-bp.h (MAYBE_DO_BREAKPOINT): Check tree::break_next here.
+	* pt.h (tree::break_next): New static member.
+	* pt.cc: Initialize it.
+
+	* parse.h (feval (const octave_value_list&, int)):
+	Set default value for nargout.
+	(feval (const std::string&, const octave_value_list&, int)):
+	Set default values for args and nargout.
+
+2001-02-01  Ben Sapp  <bsapp at lanl.gov>
+
+        * DLD-FUNCTIONS/debug.cc: New file.
+        * pt-bp.h, pt-bp.cc: New files, for breakpoints.
+	* Makefile.in: Add them to the appropriate lists.
+
+        * pt-stmt.cc (tree_statement_list::set_breakpoint,
+	tree_statement_list::delete_breakpoint,
+	tree_statement_list::list_breakpoints): New functions.
+
+	* pt.h (tree::break_point): New data member.
+	(tree::set_breakpoint, tree::delete_breakpoint, tree::is_breakpoint):
+	New virtual functions.
+
+	* pt-mat.cc (tree_matrix::rvalue): Check for breakpoint here.
+	* pt-unop.cc (tree_prefix_expression::rvalue): Likewise.
+	(tree_postfix_expression::rvalue): Likewise.
+	* pt-loop.cc (tree_do_until_command::eval): Likewise.
+	(DO_LOOP): Likewise.
+	(tree_simple_for_command::eval): Likewise.
+	(tree_complex_for_command::eval): Likewise.
+	* pt-assign.cc (tree_simple_assignment::rvalue): Likewise.
+	* pt-binop.cc (tree_binary_expression::rvalue): Likewise.
+	(tree_boolean_expression::rvalue): Likewise.
+	* pt-cell.cc (tree_cell::rvalue): Likewise.
+	* pt-colon.cc (tree_colon_expression::rvalue): Likewise.
+	* pt-except.cc (tree_try_catch_command::eval): Likewise.
+	(tree_unwind_protect_command::eval): Likewise.
+	* pt-id.cc (tree_identifier::rvalue): Likewise.
+	(tree_identifier::lvalue): Likewise.
+	* pt-indir.cc (tree_indirect_ref::rvalue): Likewise.
+	* pt-jump.cc (tree_break_command::eval): Likewise.
+	(tree_continue_command::eval): Likewise.
+	(tree_return_command::eval): Likewise.
+
+2001-01-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Map.h, Map.cc (CHMap<C>::operator = (const CHMap&)): New function.
+	(Map<C>::operator = (const Map&)): Likewise.
+	(Map<C> (const Map&)): Likewise.
+
+	* OPERATORS/op-cm-cs.cc, OPERATORS/op-cm-s.cc,
+	OPERATORS/op-m-cs.cc, OPERATORS/op-m-s.cc:
+	Make ldiv operator work for row vector by scalar ops.
+
+	* OPERATORS/op-cs-cm.cc, OPERATORS/op-cs-m.cc,
+	OPERATORS/op-s-cm.cc, OPERATORS/op-s-m.cc:
+	Make div operator work for scalar by column vector ops.
+
+2001-01-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (safe_fclose): Discard comments at the end of a file.
+
+2001-01-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc (pr_where): Call pr_where_1 with two args, not one, to
+	avoid processing format escapes that might appear in formatted code.
+
+2001-01-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc (vwarning): Write to output_buf, then send formatted
+	message to diary and error streams.
+
+2001-01-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cx-mat.cc (octave_complex_matrix::try_narrowing_conversion): 
+	Handle empty matrix dimensions correctly.
+
+2000-12-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pager.h (octave_pager_buf::diary_skip): New data member.
+	(octave_pager_buf::octave_pager_buf): Initialize it.
+	* pager.cc (octave_pager_buf::set_diary_skip): New function.
+	(octave_pager_stream::set_diary_skip): New function.
+	(octave_pager_buf::sync): Call flush_current_contents_to_diary
+	instead of octave_diary.write.
+	(octave_pager_buf::flush_current_contents_to_diary): Use
+	diary_skip, reset when done.
+	(open_diary_file): Call octave_stdout.set_diary_skip here.
+
+2000-12-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/minmax.cc (EMPTY_RETURN_CHECK): New macro.
+	(min, max): Use it.
+
+	* DLD-FUNCTIONS/minmax.cc (MINMAX_BODY): New macro.  If single arg
+	is empty, return empty matrix result and empty matrix for index.
+	(Fmin, Fmax): Use MINMAX_BODY, so we have consistent definition
+	for min and max functions.
+
+2000-11-30  Joerg Specht  <joerg.specht at ins.uni-stuttgart.de>
+
+	* help.cc (display_help_text): Append new line at end of doc string.
+
+2000-11-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/lsode.cc (LSODE_ABORT1, LSODE_ABORT2): Omit `##'
+	in macro definition since they are not needed to paste strings
+	together and picky compilers choke on them.
+	* DLD-FUNCTIONS/quad.cc (QUAD_ABORT1, QUAD_ABORT2): Likewise.
+	* DLD-FUNCTIONS/fsolve.cc (FSOLVE_ABORT1, FSOLVE_ABORT2): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (DASSL_ABORT1, DASSL_ABORT2): Likewise.
+
+2000-11-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkbuiltins (XDEFUNX_INTERNAL): New macro.
+	* mkgendoc (XDEFUNX_INTERNAL): Likewise.
+	* defun-int.h (DEFUNX_INTERNAL): Use it.
+
+	* defun.h (DEFUNX): New macro.
+	* defun-int.h (DEFUNX_INTERNAL, DECLARE_FUNX): New macro.
+	(DECLARE_FUN): Define in terms of DECLARE_FUNX.
+
+	* mkdefs: Read and print one line at a time, so we can force
+	patterns to match only at the beginning of a line.
+
+	* defun-int.h (UNDERSCORIFY): Omit `##' in macro definition since
+	they are not needed to paste strings together and picky compilers
+	choke on them.
+
+2000-11-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_ascii_data_for_plotting): New function.
+	* pt-plot.cc (save_in_tmp_file): Use it instead of save_ascii_data.
+
+	* load-save.cc (save_ascii_data): Warn if saving Inf or NaN values.
+	New arg, infnan_warned.  Use it to warn just once per set.
+	Now static.
+	(do_save): New arg, infnan_warned.  Pass to save_ascii_data.
+	(save_vars): Initialize infnan_warned here, pass to do_save.
+
+2000-11-16  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* file-io.cc (Ffprintf): If no file id parameter, don't return
+	count of characters if nargout is 0 (for compatibility with
+	Matlab).
+
+2000-11-16  Ben Sapp  <bsapp at lanl.gov>
+
+	* DLD-FUNCTIONS/rand.cc (do_rand): Declare loop counter as
+	volatile int, not just volatile.
+
+2000-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (skip_comments): Allow % as comment character too.
+	(extract_keyword): Likewise.
+
+	* Makefile.in (oct-gperf.h): Remove -a, -g, and -p flags for gperf.
+
+2000-10-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (do_load): Allow result to be returned instead of
+	inserting variables in the symbol table.  Change patterned after
+	patch by Kian Ming Adam Chai <caijianming at yahoo.co.uk>.
+
+2000-10-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (ops.cc): Don't substitute BLAS_LIBS and LIBS here.
+
+	* oct-conf.h.in (OCTAVE_CONF_SPECIAL_MATH_LIB): Delete.
+	(OCTAVE_CONF_BLAS_LIBS): Add.
+	* toplev.cc (octave_config_info): Likewise, add BLAS_LIBS and
+	remove SPECIAL_MATH_LIB from the struct.
+
+	* parse.y (feval (const octave_value_list&, int)): Don't panic
+	while processing arg names if arg.length() and arg_names.length()
+	differ.
+
+2000-10-12  Paul Kienzle  <pkienzle at kienzle.powernet.co.uk>
+
+	* ov-cell.h (octave_cell::is_cell): New function.
+
+	* pt-select.cc (equal): New static function.
+	(tree_switch_case::label_matches): Use it to compare case label
+	against arg.  Handle cell arrays as case labels.
+
+2000-10-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	Change patterned after patch by Cai Jianming
+	<caijianming at yahoo.co.uk> to support for DIM arg in 2.0.x sources.
+
+	* data.cc (DATA_REDUCTION): New macro.  Handle second DIM arg here.
+	(Fcumprod): Replace function body with DATA_REDUCTION.
+	(Fcumsum): Likewise.
+	(Fprod): Likewise.
+	(Fsum): Likewise.
+	(Fsumsq): Likewise.
+
+2000-10-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc (pr_where_2): New function.
+	(pr_where_1): Use it instead of error_1 to avoid setting error_state.
+
+2000-10-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xdiv.cc (xdiv): Warn if execution falls through to lssolve.
+
+2000-09-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (FERRNO): New function (currently commented out).
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::close): Call flush here.
+	(c_file_ptr_buf::~c_file_ptr_buf): Not here.
+	* c-file-ptr-stream.h (c_fie_ptr_buf::close_fcn): New typedef.
+	(c_file_ptr_buf::cf): New data member.  Add default constructor arg.
+	(class c_file_ptr_buf): Derive from filebuf, not streambuf.
+	(i_c_file_ptr_stream, o_c_file_ptr_stream): Handle close function here.
+	* oct-procstrm.cc (octave_iprocstream, octave_oprocstream): Likewise.
+	(octave_iprocstream::do_close, octave_oprocstream::do_close): Delete.
+	* oct-stdstrm.cc (octave_base_stdiostream::~octave_base_stdiostream):
+	Don't do anything.
+	(octave_istdiostream::create): Handle close function here.
+	(octave_istdiostream::octave_istdiostream): Likewise.
+	(octave_ostdiostream::create): Likewise.
+	(octave_ostdiostream::octave_ostdiostream): Likewise.
+	(class octave_base_stdiostream): Don't cache FILE pointer here.
+
+2000-09-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* syscalls.cc (Ffcntl): Don't assume that the file id passed in is
+	the same as the underlying system file id.
+
+2000-08-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y: Use octave_time, not time.
+
+2000-08-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (printf_value_cache::double_value): Also set
+	curr_stat to conversion_error if there are no values at all.
+
+2000-08-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (Flink, Fsymlink, Freadlink): New functions.
+
+2000-08-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (Vsave_header_format_string): New variable.
+	(symbols_of_load_save): DEFVAR it.
+	(save_header_format, default_save_header_format): New functions.
+	(write_header): Use Vsave_header_format_string here.
+
+2000-07-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-pr-code.h (tree_print_code::curr_print_indent_level,
+	(tree_print_code::beginning_of_line): No longer static.
+	(tree_print_code::tree_print_code): Initialize them here.
+	* pt-pr-code.cc: Not here.
+
+	* pt-stmt.cc (tree_statement::eval): Set curr_statement here.
+	(tree_statement_list::eval): Not here.
+
+	Debug-on-error stuff based on a patch submitted by Paul Kienzle
+	<pkienzle at kienzle.powernet.co.uk> for 2.0.x.
+
+	* error.cc (Vdebug_on_warning): New static flag variable.
+	(debug_on_warning): New function.
+	(symbols_of_warning): DEFVAR debug_on_warning.
+	(warning): Handle debug_on_warning here.
+
+	* input.cc (do_keyboard): New function.
+	(Fkeyboard): Use it to do the real work.
+	* pt-stmt.cc (curr_statement): New static variable.
+	(tree_statement::eval): Save and restore it here.
+	* error.cc (Vdebug_on_error): New static flag variable.
+	(debug_on_error): New function.
+	(symbols_of_error): DEFVAR debug_on_error.
+	(pr_where, pr_where_1): New functions.
+	(error): Handle debug_on_error here.
+
+2000-07-20  Joao Cardoso  <jcardoso at inescporto.pt>
+
+	* Makefile.in (octave): Link with $(LD_CXX) instead of $(CXX)
+
+2000-07-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::oscanf): Advance to next
+	format element before attempting to pick up any trailing stuff.
+
+2000-07-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (next_token_is_bin_op): Don't recognize `..' as a binary op.
+
+	* load-save.cc (get_file_format): Call read_mat5_binary_file_header 
+	with third arg true instead of false, so we don't barf if the file
+	is not a matlab v5 binary file.
+
+2000-07-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (octave): Link to ../libcruft/blas-xtra/xerbla.o here.
+
+	* octave.cc (main): Remove kluge to attempt linking our version of
+	xerbla.
+
+2000-07-07  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* load-save.cc (have_h5giterate_bug): New file-scope variable.
+	(hdf5_read_next_data): Only increment current_item if
+	have_h5giterate_bug is true.
+	(read_hdf5_data): Set have_h5giterate_bug here.
+	Only increment hs.current_item if have_h5giterate_bug is true.
+
+2000-07-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::close):
+	Return -1 if file pointer is NULL.
+	Set file pointer to 0 after closing.
+	(c_file_ptr_buf::~c_file_ptr_buf): Call close after flushing.
+
+2000-07-05  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* Makefile.in (BLAS_LIBS): Substitute here.
+	(octave): Use $(BLAS_LIBS) in the final link command.
+
+2000-06-30  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	* Makefile.in (octave): Link $(FLIBS) last.
+	* octave.cc (main): Force our own xerbla to be linked instead of
+	some system version.
+
+2000-06-29  James R. Van Zandt  <jrv at vanzandt.mv.com>
+
+	* load-save.cc (load_save_format): New value, LS_MAT5_BINARY.
+	(arrayclasstype, mat5_data_type): New enums.
+	(read_mat5_binary_data): New function.
+	(read_mat5_tag): New function.
+	(read_mat5_binary_element): New function.
+	(read_mat5_binary_file_header): New function.
+	(get_file_format): Check for mat5 binary format too.
+	(do_load): Handle mat5 binary format.
+	(write_mat5_tag): New function.
+	(write_mat5_array): New function.
+	(class mat5_callback): New class.
+	(save_mat5_binary_element): New functnon.
+	(do_save): Handle mat5 binary format.
+	(write_header): Handle LS_MAT5_BINARY case too.
+	(save_user_variables): Handle LS_MAT5_BINARY case too.
+	(Fsave): Handle LS_MAT5_BINARY case too.
+	(Fload): Handle LS_MAT5_BINARY case too.
+
+2000-06-29  Steven G. Johnson  <stevenj at alum.mit.edu>
+
+	All of the following changes are protected by #ifdef HAVE_HDF5.
+
+	* load-save.cc (load_save_format): New value, LS_HDF5.
+	(make_valid_identifier): New function.
+	(class hdf5_fstreambase, class hdf5_ifstream, class hdf5_ofstream):
+	New classes for reading and writing hdf5 data.
+	(hdf5_types_compatible): New function.
+	(hdf5_import_multidim): New function.
+	(hdf5_check_attr): New function.
+	(hdf5_read_next_data): New function.
+	(hdf5_make_complex_type): New function.
+	(hdf5_make_range_type): New function.
+	(read_hdf5_data): New function.
+	(get_file_format): Handle HDF5 format.
+	(do_load): Handle LS_HDF5 case.
+	(Fload): Handle HDF5 format.
+	(hdf5_add_attr): New function.
+	(save_type_to_hdf5): New function.
+	(add_hdf5_data): New function.
+	(do_save): Handle HDF5 format.
+	(get_default_save_format): Handle LS_HDF5 case.
+	(write_header): Handle LS_HDF5 case.
+	(save_user_variables): Handle HDF5 format.
+	(Fsave): Handle HDF5 format.
+
+2000-06-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (display_help_text): If writing to filter fails, send
+	unformatted text to output stream.
+
+2000-06-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-bm-bm.cc (eq): Define using mx_el_eq, not operator ==.
+	(ne): Likewise, use mx_el_ne, not operator !=.
+
+	* pr-output.cc (Fdisp): Delete.
+
+2000-06-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (float_format::float_format): Set default values
+	for width and precision to -1.
+	(operator << (ostream&, pr_formatted_float&): Set width and
+	precision if values are >= 0.
+	(set_real_format, set_real_matrix_format, set_range_format,
+	set_complex_format, set_complex_matrix_format): If we have all
+	integers, infinities, or nans, set precision equal to field width.
+
+	* load-save.cc (read_ascii_data): Allow empty strings and string
+	vectors to be restored.
+
+	* variables.cc (var_matches_any_pattern): New function.
+	(Fclear): Use it to make exclusive clear work correctly.
+
+2000-06-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-range.h (octave_range::is_numeric_type): New function.
+
+	* sysdep.cc (Fkbhit): Also ask for input if forced_interactive.
+
+2000-06-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (oct-gperf.h): Use $(GPERF) instead of gperf.
+
+2000-05-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/qz.cc (Fqz): When computing finite generalized
+	eigenvalues, don't write past the end of the array.
+
+2000-05-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base-nd-array.h, ov-base-nd-array.cc, ov-re-nd-array.h,
+	ov-re-nd-array.h: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* pt-stmt.h, pt-stmt.cc (class tree_statement):
+	Store comments associated with this parse tree element.
+	* pt-select.h, pt-select.cc (class tree_if_clause,
+	class tree_if_command, class tree_switch_case
+	class tree_switch_command): Likewise.
+	* pt-loop.h, pt-loop.cc (class tree_while_command,
+	class tree_do_until_command, class tree_simple_for_command,
+	class tree_complex_for_command): Likewise.
+	* pt-except.h, pt-except.cc (class tree_try_catch_command,
+	class tree_unwind_protect_command): Likewise.
+	* ov-usr-fcn.h, ov-usr-fcn.cc (class octave_user_function): Likewise.
+	* pt-pr-code.h, pt-pr-code.cc (tree_print_code::print_comment_elt,
+	tree_print_code::print_comment_list,
+	tree_print_code::print_indented_comment): New functions.
+	(tree_print_code::visit_simple_for_command,
+	tree_print_code::visit_complex_for_command,
+	tree_print_code::visit_octave_user_function_header,
+	tree_print_code::visit_octave_user_function_trailer,
+	tree_print_code::visit_if_command, tree_print_code::visit_statement,
+	tree_print_code::visit_switch_case,
+	tree_print_code::visit_switch_command,
+	tree_print_code::visit_try_catch_command,
+	tree_print_code::visit_unwind_protect_command
+	tree_print_code::visit_while_command,
+	tree_print_code::visit_do_until_command): Handle comments.
+	* lex.l, parse.y: Handle comments in parse trees.
+	* comment-list.h, comment-list.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+2000-04-23  etienne grossmann  <etienne at anonimo.isr.ist.utl.pt>
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::eval_error):
+	New args x and y, for dimension mismatch info.
+	Change callers where appropriate.
+	(tm_const::init): Report mismatched column dimensions.
+
+2000-04-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc (kbhit): Also clear cin if at EOF.
+
+2000-04-11  Joao Cardoso  <jcardoso at inescn.pt>
+
+	* sysdep.cc (kbhit): New arg, wait.
+	(raw_mode): Ditto.
+	(Fkbhit): If given an arg, call kbhit with wait = false.
+
+	* DLD-FUNCTIONS/minmax.cc (Fmax, Fmin): Fix doc string.
+
+2000-04-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load): Undo previous change.
+
+2000-04-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load): Also fail with
+	error message if we don't find the mangled function name in the
+	file.
+
+2000-03-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (printf_value_cache::string_value): Return string
+	matrices in a Matlab-compatible way.
+	(printf_value_cache): Redesign the way list_exhausted works.
+
+	* oct-fstrm.cc (octave_fstream::do_close): New function.
+	* oct-stdstrm.cc (octave_istdiostream::do_close): Ditto.
+	(octave_ostdiostream::do_close): Ditto.
+	* c-file-ptr-stream.cc (c_file_ptr_buf::close): Ditto.
+	(i_c_file_ptr_stream::close): Ditto.
+	(o_c_file_ptr_stream::close): Ditto.
+	* oct-prcstrm.cc (octave_iprocstream::do_close): Ditto.
+	(octave_oprocstream::do_close): Ditto.
+	(octave_iprocstram::~octave_iprocstram): Call do_close here.
+	(octave_iprocstram::~octave_oprocstram): Likewise.
+
+	* oct-stream.h (octave_base_stream::do_close): New virtual function.
+	(octave_base_stream::close): If stream is open, call do_close.
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::flush): New function.
+	(c_file_ptr_buf::~c_file_ptr_buf): Use it.
+	(c_file_ptr_buf::overflow): Ditto.
+	(c_file_ptr_buf::sync): Ditto.
+
+2000-03-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-procbuf.cc (octave_procbuf::open): Make output streams line
+	buffered.
+
+2000-03-24  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (my_friendly_exit): Prefix failure messages with
+	panic instead of error.
+
+	* c-file-ptr-stream.cc (c_file_ptr_buf::~c_file_ptr_buf):
+	Avoid dereferencing NULL pointer.
+
+	* oct-stream.cc (printf_format_list::add_elt_to_list,
+	printf_format_list::process_conversion,
+	printf_format_list::finish_conversion): New args, flags, fw, and prec.
+	(printf_format_list::printf_format_list): Save more complete info.
+	(printf_format_list::printme): Print flags, fw, and prec.
+	(octave_base_stream::printf): Simplify.
+	(do_printf_conv): Delete have_arg arg, since it is always true now.
+	(octave_base_stream::do_printf): Handle case of no args and %
+	directly instead of using do_printf_conv.
+	(printf_value_cache::exhausted): Rename from no_more_values.
+	(DO_PCT_CONVERSION): New macro
+	(octave_base_streain::do_scanf, octave_base_streain::do_oscanf):
+	Use it.
+	(scanf_format_list::finish_conversion): `%' counts as a conversion too.
+	Also don't forget to set type for it.
+	(OCTAVE_SCAN_0): Delete.
+	(OCTAVE_SCAN): Rename from OCTAVE_SCAN_1.
+	(octave_base_stream::scanf, octave_base_stream::oscanf): Don't
+	special-case number of conversions here.
+	(octave_base_stream::oscanf, octave_base_stream::do_oscanf): Only
+	cycle through fmt elements if the number of conversions is greater
+	than 0.
+
+	* oct-stream.h (scanf_format_list::next): New arg, `cycle'.
+	(printf_format_list::next): New arg, `cycle'.
+	(printf_format_list::last_elt_p): New function.
+	(printf_format_elt): New fields fw, prec, and flags.
+	Define copy constructor and assignment operator.
+	(scanf_format_elt): Define copy constructor and assignment operator.
+
+2000-03-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (OCTAVE_SCAN_0, OCTAVE_SCAN_1): New macros.
+	(do_scanf_conv, BEGIN_S_CONVERSION, BEGIN_CHAR_CLASS_CONVERSION,
+	do_scanf, scanf, do_oscanf, do_oscanf, oscanf): Use them instead
+	of calling istream::scan directly.
+	(octave_scan): New function.
+	(do_scanf_conv): Second arg is now scanf_format_elt instead of char*.
+	Change all callers.
+
+	* oct-procbuf.h, oct-procbuf.cc (octave_procbuf):
+	Derive from c_file_ptr_buf instead of filebuf.
+
+	* oct-stream.cc (octave_base_stream::printf): Use octave_format
+	instead of ostream::form.  Return number of characters written.
+
+2000-03-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (do_printf_conv): Use octave_format instead of
+	ostream::form.  Return number of characters written.
+	(octave_base_stream::do_printf): Return number of characters written.
+
+	* error.cc (verror, vwarning): Use octave_format instead of
+	ostream::vform.
+
+	* utils.cc (octave_format, octave_vformat): New functions.
+	* cutils.c (octave_snprintf, octave_vsnprintf): New functions.
+
+	* oct-lvalue.h (dummy_val): New static variable.
+	(octave_lvalue::octave_lvalue): Use it to initialize val.
+
+	* variables.cc (is_valid_function): Look in the global symbol
+	table for functions.
+
+2000-03-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (LIBRARIES): Conditionally define.
+	(libraries): Depend on $(LIBRARIES).
+	(octave): Depend on $(LIBRARIES), not libraries.  Also depend on
+	stamp-prereq and stamp-oct-links.
+	(all): Don't depend on stamp-prereq or stamp-oct-links.
+	(liboctinterp.$(LIBEXT), liboctinterp.$(SHELXT)): Delete target
+	before rebuilding.
+
+2000-03-21  Ben Sapp  <bsapp at nua.lampf.lanl.gov>:
+
+	* Makefile.in (libraries): Depend only on library targets, not
+	archive members.
+
+2000-03-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (objects): New target
+
+	* c_file_ptr_stream.h, c_file_ptr_stream.cc: New files.
+	* oct-stdstrm.h, oct-stdstrm.cc, oct-prcstrm.cc:
+	Use c_file_ptr_buf, i_c_file_ptr_stream, and o_c_fie_ptr_stream
+	instead of stdiobuf, istdiostream, and ostdiostream.
+
+	* pr-output.cc (set_real_format, set_real_matrix_format,
+	set_complex_format, set_complex_matrix_format, set_range_format):
+	Do the right thing again for int, NaN, and Inf values.
+
+2000-03-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (pr_plus_format): Rename from do_plus_format.
+	Change all callers.
+	(pr_float, pr_complex): New arg, scale.  Handle scaling here.
+	(float_format): New class for managing details of formatting
+	floats.  Use it instead of character string formats and the
+	nonstandard form() function from the GNU iostream library.
+
+2000-02-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (clean): Also delete gendoc.
+
+2000-02-18  James R. Van Zandt  <jrv at vanzandt.mv.com>
+
+	* load-save.cc (Vcrash_dumps_octave_core): Fix comment for this var.
+
+2000-02-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_number): Don't transorm `[Dd]' to `e' if reading
+	hex.
+
+2000-02-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-inc): Install files in
+	$(octincludedir)/octave.
+	(uninstall): Remove them from the correct directory too.
+
+	* defaults.h, defaults.cc (Vlocal_ver_arch_lib_dir): New variable.
+	* defaults.cc (set_default_local_ver_arch_lib_dir): New function.
+	(install_defaults): Call it.
+	(exec_path): Prepend the versioned form of the local arch lib
+	directory to the standard path.
+	* defaults.h.in (OCTAVE_LOCALVERARCHLIBDIR,
+	OCTAVE_LOCALVERFCNFILEDIR, OCTAVE_LOCALVEROCTFILEDIR):
+	Substitute these too.
+	* toplev.cc (Foctave_config_info): Add them to the struct.
+
+2000-02-08  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (Foctave_config_info): Add MKOCTFILE_INCFLAGS to the
+	struct.
+	* oct-conf.h.in (OCTAVE_CONF_MKOCTFILE_INCFLAGS): Define.
+
+2000-02-07  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/balance.cc (Fbalance): Explicitly request
+	conversion from Matrix to ComplexMatrix.
+	* DLD-FUNCTIONS/qz.cc (Fqz): Likewise.
+
+	* ov-re-mat.h (octave_matrix::complex_matrix_value): Explicitly
+	request conversion from Matrix type.
+
+	* ov-ch-mat.h (octave_char_matrix::matrix_value): Explicitly
+	request conversion from charMatrix type.
+	(octave_char_matrix::complex_matrix_value): Likewise.
+	* ov-bool-mat.h (octave_bool_matrix::matrix_value): Likewise.
+	(octave_bool_matrix::complex_matrix_value): Likewise.
+
+	* ov-range.h (octave_range::complex_matrix_value): Explicitly
+	request conversion from Matrix type.
+
+	* ov-cx-mat.h, ov-re-mat.h: Explicitly request conversions from
+	diagonal matrix types in constructors.
+
+	* mappers.cc (ximag, xreal): Return double, not Complex.
+
+	* error.cc (panic): Turn off buffering of error messages.
+	Don't call flush_octave_stdout here, verror will do it for us.	
+	(verror): Don't call flush_octave_stdout if buffering error messages.
+
+	* pt-except.cc (tree_try_catch_command::eval): Only restore
+	buffer_error_message value (by running the unwind_protect element
+	for it) if it has been saved.
+
+	* help.cc (Ftype): Return value if nargout is NOT equal to zero.
+	Delete unnecessary unwind_protect::begin_frame().
+
+	* toplev.cc (octave_config_info): Stuff lots of new config info in
+	the struct.
+
+	* oct-conf.h.in: Delete TARGET_HOST_TYPE.
+
+2000-02-04  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* siglist.c: Include <signal.h>.
+
+	* lex.l (is_plot_keyword): Add minimum match length in call to
+	almost_match.
+
+	* Makefile.in (%.df : %.cc): Don't pass -c to compiler.
+
+2000-02-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base-mat.cc: Include pr-output.h here.
+
+	* DLD-FUNCTIONS/rand.cc (curr_rand_dist): Return const char *
+	instead of char *.
+
+	* oct-fstrm.cc (octave_fstream::seek, octave_fstream::tell): 
+	Call pubseekoff instead of seekoff.
+
+	* DLD-FUNCTIONS/dassl.cc (print_dassl_option_list): Use stream
+	manipulators instead of GNU iostream-specific form function.
+	* DLD-FUNCTIONS/fsolve.cc (print_fsolve_option_list): Ditto.
+	* DLD-FUNCTIONS/lsode.cc (print_lsode_option_list): Ditto.
+	* DLD-FUNCTIONS/quad.cc (print_quad_option_list): Ditto.
+	* pr-output.cc (pr_scale_header): Ditto.
+
+	* sighandlers.h: Include signal.h here.
+	* sighandlers.cc: Not here.
+
+	* utils.cc: Include setjmp.h, not csetjmp.
+	* toplev.cc: Ditto.
+
+	* sighandlers.cc: Include signal.h, not csignal.
+
+	* pt-plot.h: Don't include csignal.
+	* toplev.cc: Ditto.
+	* oct-hist.cc: Ditto.
+	* octave.cc: Ditto.
+	* pager.cc: Ditto.
+	* input.cc: Ditto.
+	* help.cc: Ditto.
+
+	* pt-plot.cc (send_to_plot_stream): Use operator== and substr
+	method to do limited-length string comparison.
+	* input.cc (generate_completion): Likewise.
+	* ov-dld-fcn.cc (octave_dld_function::octave_dld_function): Likewise.
+	* ov-usr-fcn.cc (octave_user_function::mark_as_system_fcn_file):
+	Likewise.
+
+	* utils.cc (check_preference): Expect exact string matches.
+	* variables.cc (ignore_function_time_stamp): Likewise.
+	* lex.l (whitespace_in_literal_matrix): Likewise.
+
+	* mappers.cc (xconj, ximag, xreal): New functions.  Use them in
+	DEFUN_MAPPER calls.
+
+	* defun-int.h (DEFUN_MAPPER_INTERNAL): Cast function pointer args
+	to octave_mapper constructor.
+
+2000-02-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* procstream.cc (procstreambase::procstreambase,
+	procstreambase::open, procstreambase::close):
+	Call std::ios::setstate, not set.
+
+	* lex.l (plot_axes_token): Declare plot_axes as const char *.
+	Declare tmp const char **.
+
+	* oct-procbuf.h: Include fstream, not streambuf.h.
+
+	* load-save.cc (Fsave): Call pubseekoff instead of seekoff.
+	* oct-strstrm.cc (octave_base_strstream::tell): Likewise.
+	(octave_base_strstream::seek): Likewise.
+
+	* oct-stream.cc (octave_base_stream::read): Rename count to char_count.
+	(octave_base_stream::do_gets): Likewise.
+
+	* octave-stream.cc (octave_base_stream::write): Rename flt_fmt to ffmt.
+	(octave_base_stream::read): Likewise.
+
+	* TEMPLATE-INST/SLStack-sym.cc: Delete meaningless `extern
+	template' declarations.
+	* TEMPLATE-INST/Array-tc.cc: Ditto.
+
+	* TEMPLATE-INST/Map-fnc.cc: Don't try to instantiate goodCHptr or
+	CHptr_to_index here.
+	* TEMPLATE-INST/Map-tc.cc: Likewise.
+	* Map.h (CHNode::goodCHptr, CHNode::CHptr_to_index): Now member
+	functions.  Change all callers.
+
+	* load-save.cc (read_binary_file_header): Declare magic_len `const'.
+
+	* token.h (token::token (const token&), token::operator=):
+	Delete unnecessary definitions.
+
+	* oct-stream.cc (octave_stream::mode_as_string): Use
+	std::ios::binary, not std::ios::bin.
+	* load-save.cc (Fsave, Fload, save_user_variables): Likewise.
+
+	* DLD-FUNCTIONS/qz.cc (Fqz): Use Array<int> class instead of
+	trying to create automatic int array with variable size.
+
+	* variables.cc (F__dump_symbol_info__): Fix continuation char.
+	* mappers.cc (Ftoupper): Likewise.
+	* DLD-FUNCTIONS/besselj.cc (Fairy, Fbesselj): Likewise.
+	* DLD-FUNCTIONS/chol.cc (Fchol): Likewise.
+	* DLD-FUNCTIONS/det.cc (Fdet): Likewise.
+	* DLD-FUNCTIONS/eig.cc (Feig): Likewise.
+	* DLD-FUNCTIONS/gammainc.cc (gammainc): Likewise.
+	* DLD-FUNCTIONS/givens.cc (givens): Likewise.
+	* DLD-FUNCTIONS/hess.cc (hess): Likewise.
+	* DLD-FUNCTIONS/inv.cc (inv): Likewise.
+	* DLD-FUNCTIONS/log.cc (logm): Likewise.
+	* DLD-FUNCTIONS/lu.cc (lu): Likewise.
+	* DLD-FUNCTIONS/qr.cc (qr): Likewise.
+	* DLD-FUNCTIONS/schur.cc (schur): Likewise.
+	* DLD-FUNCTIONS/balance.cc (balance): Likewise.
+	* DLD-FUNCTIONS/svd.cc (svd): Likewise.
+	* DLD-FUNCTIONS/syl.cc (syl): Likewise.
+	* DLD-FUNCTIONS/expm.cc (Fexpm): Likewise.
+
+	* token.h (token::token_type, token::end_tok_type,
+	token::plot_tok_type): Delete extraneous comma from enum decls.
+	* load-save.cc (load_save_format): Likewise.
+
+	* pt-idx.cc (tree_index_expression::tree_index_expression):
+	Delete default arg values.
+	* oct-fstrm.cc (octave_fstream::octave_fstream): Likewise.
+	* oct-stream.cc (octave_stream::octave_stream): Likewise.
+
+	* siglist.h, siglist.c: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	* siglist.c (sys_siglist): Move definition here from sighandlers.cc.
+	* siglist.h (sys_siglist): Move declaration here from sighandlers.h.
+
+	* ov.h, ov-bool.h, ov-bool-mat.h (bool_matrix_value):
+	Delete unnecessary arg.
+
+	* ov.h (octave_value::do_multi_index_op): Rename from do_index_op.
+
+	* ov-fcn.h (octave_function::is_system_fcn_file): Now const.
+
+	* Map.cc (index_to_CHptr): Now a macro.
+	(CHMap<C>::hash): Now a member function.
+
+	* defun-int.h (UNDERSCORIFY): New macro.
+	(DEFCONST_INTERNAL, DEFCONSTX_INTERNAL): Use it.
+
+	* data.cc (Fis_list): Fix continuation char.
+	* defaults.cc (IMAGEPATH): Likewise.
+
+	* Map.cc (CHptr_to_index, goodCHptr): Delete static decl.
+
+	* ov.h (unary_op, binary_op, assign_op): Prepend `op_' to elts.
+	Change all usses
+
+	* All source files: Sprinkle with std:: qualifier as needed.
+
+2000-01-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (install_signal_handlers): Add std:: qualifier
+	for set_net_handler.
+
+	* All source files: Include iostream, fstream, strstream,
+	etc. as needed instead of using forward declarations for these
+	classes.
+
+2000-01-30  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (input_event_hook, Finput_event_hook): New functions.
+	(hook_fcn, user_data): New static variables.
+
+2000-01-28  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-except.cc (do_catch_code): Don't do anything special for
+	tree_return_command::returning, or tree_break_command::breaking.
+
+	* error.cc (vwarning): New function.
+	(warning): Use it instead of calling verror.
+
+	* oct-stream.cc (octave_base_stream::oscanf):
+	Result is now always nconv+1 elements.  Return count of successful
+	conversions in last element.
+	* file-io.cc (Ffscanf, Fsscanf, Fscanf): Fix doc string.
+
+	* pt-except.cc (do_catch_code): Unwind-protect buffer_error_messages.
+	Be sure to run all unwind-protects before returning.
+	(tree_try_catch_command::eval): Add do_catch_code cleanup function
+	to unwind-protect stack before resetting buffer_error_messages.
+	Use unwind-protect to save and restore buffer_error_messages.
+	If there is no catch code, discard the cleanup function and run
+	the unwind-protect for buffer_error_messages.
+
+	* error.cc (bind_global_error_variable): Avoid dereferencing
+	error_message_buffer if it is NULL.
+
+	* parse.y (evaluating_function_body): New global flag.
+	* ov-usr-fcn.cc (octave_user_function::do_index_op):
+	Protect and set it here.
+	* parse.y (make_break_command, make_return_command): Check it here.
+
+	* error.cc (warning_state): New global flag.
+	(warning): Set it here.
+	* lex.l (reset_parser): Clear it here.
+	* parse.y (fold): Check it here.
+
+2000-01-27  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-walk.h (tree_walker::visit_do_until_command): New pure virtual.
+	* pt-pr-code.cc (tree_print_code::visit_do_until_command):
+	New function.
+	* pt-loop.h (tree_do_until_command): New class.
+	(tree_while_command::expr, tree_while_command::list):
+	Now protected instead of private.
+	* parse.y (make_do_until_command): New function.
+	(loop_command): Recognize do-until statement.
+	(DO, UNTIL): New tokens.
+
+	* input.cc (match_sans_spaces): Require non-blank part of test
+	string to match standard string exactly.
+
+2000-01-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.h (scanf_format_elt::char_class): New struct elt.
+	Add arg to constructor.
+	(scanf_format_elt::special_conversion): New enum.
+	* oct-stream.cc (scanf_format_list::add_elt_to_list): New arg,
+	char_class.  Pass it to scanf_format_elt constructor.
+	(scanf_format_list::scanf_format_list): Create separate list
+	elements for whitespace and literal conversions.
+	(expand_char_class): New function.
+	(scanf_format_list::finish_conversion): Extract character class
+	(not including the delimiting brackets) and expand the list of
+	characters.  Pass the result to add_elt_to_list.
+	(scanf_format_list::all_character_conversions): Also accept '^',
+	scanf_format_elt::literal_conversion, and
+	scanf_format_elt::whitespace_conversion types too.
+	(DO_WHITESPACE_CONVERSION, BEGIN_CHAR_CLASS_CONVERSION,
+	BEGIN_C_CONVERSION, BEGIN_S_CONVERSION, DO_LITERAL_CONVERSION):
+	New macros.
+	(octave_base_stream::do_scanf, octave_base_stream::do_oscanf):
+	Use them to avoid code duplication.
+	Handle whitespace, literal text, and character class conversions.
+	(octave_base_stream::oscanf): Loop over all format list elements,
+	not just the first nconv elements.  Clear status flags on is for
+	all streams.
+
+2000-01-25  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xdiv.cc (result_ok): Just check value of info.
+	(solve_singularity_warning): New function.
+	(xleftdiv, xdiv): Pass pointer to solve_singularity_warning to
+	solve function.	
+
+	* lex.l (handle_identifier): Set next_tok_is_eq if we are looking
+	at `=', but not if we are looking at `=='.
+
+	* pt-pr-code.cc (tree_print_code::visit_unwind_protect_command): 
+	Print `unwind_protect_cleanup', not `cleanup_code'.
+
+	* pager.cc (octave_pager_buf::flush_current_contents_to_diary):
+	New function.
+	(octave_pager_stream::flush_current_contents_to_diary):
+	Ditto.
+	(close_diary_file): Use the new octave_pager_stream function to
+	try to flush the current buffer to the diary when it is closed.
+
+	* variables.cc (Fexist): Return 6 for built-in constants.
+
+	* pt-plot.cc (Fgshow): Don't append " " after last arg.
+	(Fgset): Likewise.
+
+2000-01-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base-mat.h (octave_base_matrix::length): Return 0 for empty
+	arrays.
+
+2000-01-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/time.cc (Fstrptime): New function.
+
+	* load-save.cc (Fsave): Add missing else.
+
+2000-01-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/gammainc.cc (Fgammainc): Texinfoize doc string.
+	* ov-typeinfo.cc (Ftypeinfo): Ditto.
+	* parse.y (Vwarn_future_time_stamp): Ditto.
+	* DLD-FUNCTIONS/minmax.cc (Fmax, Fmin): Ditto.
+	* ov-usr-fcn.cc (Fva_arg, Fva_start, Fvr_val): Ditto.
+	* defaults.cc (VOCTAVE_HOME, Frehash): Ditto.
+	* toplev.cc (Fwarranty, Fcasesen): Ditto.
+	* utils.cc (Fdo_string_escapes, Ffile_in_loadpath): Ditto.
+	* variables.cc (F__dump_symtab_info__, F__dump_symbol_info__): Ditto.
+	* ov-list.cc (Flist, Fappend, Fnth, Freverse, Fsplice): Ditto.
+	* input.cc (Fread_readline_init_file): Ditto.
+	* file-io.cc (Fis_stream): Ditto.
+	* ov-cell.cc (Fiscell, Fcell): Ditto.
+	* pt-assign.cc (Vprint_rhs_assign_val): Ditto.
+	* pt-decl.cc (Vinitialize_global_variables): Ditto.
+	* symtab.cc (Vvariables_can_hide_functions): Ditto.
+
+	* pt-plot.cc (Fgraw, Fgset, Fgshow, Vgnuplot_command_plot, 
+	Vgnuplot_command_replot, Vgnuplot_command_splot,
+	Vgnuplot_command_using, Vgnuplot_command_with,
+	Vgnuplot_command_axes, Vgnuplot_command_title,
+	Vgnuplot_command_end): Texinfoize doc strings.
+
+	* oct-procbuf.cc (__kluge_procbuf_delay__): Rename from
+	kluge_procbuf_delay.  Texinfoize doc string.
+
+2000-01-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (gobble_leading_whitespace): Discard first space character
+	after consecutive comment characters.
+	* lex.l (grab_help_text): Ditto.
+
+	* lex.l (Vwhitespace_in_literal_matrix, Vwarn_separator_insert,
+	Vwarn_single_quote_string): Texinfoize doc string.
+
+2000-01-11  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h, ov.cc (octave_value::column_vector_value,
+	octave_value::row_vector_value,
+	octave_value::complex_column_vector_value,
+	octave_value::complex_row_vector_value): New functions.
+	(octave_value::vector_value): Now returns Array<double>.
+	(octave_value::complex_vector_value): Now returns Array<Complex>.
+	Sprinkle conversions where necessary.
+
+	* ov.cc (Vprefer_column_vectors): Now static.
+	* ov.h (octave_value (const ComplexRowVector&),
+	octave_value (const ComplexColumnVector&),
+	octave_value (const RowVector&), octave_value (const ColumnVector&)):
+	Delete second arg.  Change all callers.
+
+	* oct-obj.h (octave_value_list (const RowVector&),
+	octave_value_list (const ColumnVector&),
+	octave_value_list (const ComplexRowVector&),
+	octave_value_list (const ComplexColumnVector&)): Likewise.
+	* ov-cx-mat.h, ov-cx-mat.cc
+	(octave_complex_matrix (const ComplexRowVector&),
+	(octave_complex_matrix (const ComplexColumnVector&)):
+	Delete second arg, simply create object with orientation
+	corresponding to vector arg.  Move constructors to class decl.
+	* ov-re-mat.h, ov-re-mat.cc (octave_matrix (const RowVector&),
+	(octave_matrix (const ColumnVector&)):
+	Delete second arg, simply create object with orientation
+	corresponding to vector arg.  Move constructors to class decl.
+
+2000-01-07  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* mappers.cc (Fconj, Ferf, Ferfc, Fgamma, Fimag, Flgamma, Flog10,
+	Freal, Fround): Add @seealso{...} to doc strings.
+
+2000-01-06  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (do_scanf): Do the right thing again for character
+	conversions.
+
+	* help.cc (display_help_text): Also strip out leading spaces
+	before Texinfo @-commands before sending doc string to makeinfo.
+	(display_help_text): Improve format of `See also' string.
+
+2000-01-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (display_help_text): Pass a definition for @seealso
+	through the filter.
+
+1999-12-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (Vwarn_single_quote_string): New variable.
+	(syms_of_lex): DEFVAR it.
+	(warn_single_quote_string): New function.
+	(gripe_single_quote_string): New function.
+	Use new stuff to allow warnings for code that uses single quote
+	characters to introduce string constants.
+
+1999-12-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkbuiltins: Add #undef quad to generated file.
+
+1999-12-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (Vwarn_separator_insert): New variable.
+	(syms_of_lex): DEFVAR it.
+	(warn_separator_insert): New function.
+	(maybe_warn_separator_insert): New function.
+	Use new stuff to allow warnings for code that might result in
+	auto-insertion of commas or semicolons, depending on the value of
+	whitespace_in_literal_matrix.
+
+	* parse.y (Fsource): Record function file name here too.
+
+1999-12-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (link_to_global_variable): If the local symbol is
+	not a variable, don't bother to clear it.  Instead, just redefine
+	it by aliasing to the global symbol.
+
+1999-11-23  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/balance.cc (Fbalance): Texinfoize doc string.
+	* DLD-FUNCTIONS/det.cc (Fdet): Ditto.
+	* DLD-FUNCTIONS/eig.cc (Feig): Ditto.
+	* DLD-FUNCTIONS/givens.cc (Fgivens): Ditto.
+	* DLD-FUNCTIONS/inv.cc (Finv): Ditto.
+	* DLD-FUNCTIONS/chol.cc (Fchol): Ditto.
+	* DLD-FUNCTIONS/hess.cc (Fhess): Ditto.
+	* DLD-FUNCTIONS/lu.cc (Flu): Ditto.
+	* DLD-FUNCTIONS/qr.cc (Fqr): Ditto.
+	* DLD-FUNCTIONS/schur.cc (Fschur): Ditto.
+	* DLD-FUNCTIONS/svd.cc (Fsvd): Ditto.
+	* DLD-FUNCTIONS/expm.cc (Fexpm): Ditto.
+	* DLD-FUNCTIONS/log.cc (Flogm, Fsqrtm): Ditto.
+	* DLD-FUNCTIONS/syl.cc (Fsyl): Ditto.
+	* DLD-FUNCTIONS/pinv.cc (Fpinv): Ditto.
+	* DLD-FUNCTIONS/qz.cc (Fqz): Ditto.
+	* DLD-FUNCTIONS/dassl.cc (Fdassl, Fdassl_options): Ditto.
+	* DLD-FUNCTIONS/lsode.cc (Flsode, Flsode_options): Ditto.
+	* data.cc (Flength, Fsize, Fisempty): Ditto.
+	* sysdep.cc (Fkbhit): Ditto.
+	* input.cc (Fkeyboard, Finput): Ditto.
+	* variables.cc (ans): Ditto.
+	* pr-output.cc (Fdisp, Fformat): Ditto.
+	* ov.cc (Vprint_answer_id_name): Ditto.
+	* defaults.cc (IMAGEPATH): Ditto.
+	* error.cc (Ferror, Fwarning, Fusage, error_text, beep_on_error):
+	Ditto.
+	* load-save.cc (Fload, Fsave, Vdefault_save_format,
+	Vsave_precision): Ditto.
+	* file-io.cc (Ffflush, Ffopen, Ffclose, Ffputs, Ffgetl, Ffgets,
+	Ffprintf, Fsprintf, Fscanf, Ffscanf, Fsscanf, Ffread, Ffwrite,
+	Ffseek, Fftell, Ffeof, Fferror, Ffreport, Ftmpnam, Vstdin_file,
+	Vstdout_file, Vstderr_file, SEEK_SET, SEEK_CUR, SEEK_END): Ditto.
+	* pager.cc (Vpager_binary, Vpage_output_immediately,
+	Vpage_screen_output, Fmore): Ditto.
+
+1999-11-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (Vtreat_neg_dim_as_zero): Texinfoize doc string.
+	* DLD-FUNCTIONS/find.cc (Ffind): Ditto.
+	* DLD-FUNCTIONS/rand.cc (Frand, Frandn): Ditto.
+	* DLD-FUNCTIONS/sort.cc (Fsort): Ditto.
+	* mappers.cc (Fisinf, Fisnan, Ffinite): Ditto.
+	* data.cc (Fall, Fany, Fdiag, Fones, Fzeros, Feye, Flinspace): Ditto.
+	* defaults.cc (Vloadpath, Vdefault_loadpath): Ditto.
+	* parse.y (Feval, Ffeval, Vdefault_eval_print_flag,
+	Vwarn_missing_semicolon, Vwarn_function_name_clash, Fsource): Ditto.
+	* ov-usr-fcn.cc (Vmax_recursion_depth, Vdefault_return_value,
+	Vdefine_all_return_values, Vreturn_last_computed_value): Ditto.
+	* ov.cc (Vok_to_lose_imaginary_part, Vdo_fortran_indexing,
+	Vprefer_column_vectors, Vresize_on_range_error,
+	Vwarn_divide_by_zero): Ditto.
+	* pt-stmt.cc (Vsilent_functions): Ditto.
+	* variables.cc (Vignore_function_time_stamp): Ditto.
+	* dynamic-ld.cc (Vwarn_reload_forces_clear): Ditto.
+
+1999-11-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/fft.cc (Ffft): Texinfoize doc string.
+	* DLD-FUNCTIONS/ifft.cc (Fifft): Ditto.
+	* DLD-FUNCTIONS/fft2.cc (Ffft2): Ditto.
+	* DLD-FUNCTIONS/ifft2.cc (Fifft2): Ditto.
+	* DLD-FUNCTIONS/filter.cc (Ffilter): Ditto.
+	* DLD-FUNCTIONS/quad.cc (Fquad, Fquad_options): Ditto.
+	* DLD-FUNCTIONS/colloc.cc (Fcolloc): Ditto.
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve, Ffsolve_options): Ditto.
+	* defaults.cc (Veditor): Ditto.
+	* pt-plot.cc (Vautomatic_replot, Vgnuplot_binary,
+	Vgnuplot_has_frames, Vgnuplot_has_multiplot, Fclearplot,
+	Fcloseplot, Fpurge_tmp_files, Fishold, Fhold): 
+
+	* Makefile.in (parse.cc): Expect 11 shift/reduce conflicts now.
+
+1999-11-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (Vwarn_assign_as_truth_value,	Vwarn_variable_switch_label):
+	Texinfoize doc strings.
+
+	* DLD-FUNCTIONS/pinv.cc (Fpinv): Texinfoize doc string.
+
+	* defun-int.h (DEFUN_DLD_INTERNAL): New macro.
+	* defun-dld.h [MAKE_BUILTINS] (DEFUN_DLD): Simply expand to
+	DEFUN_DLD_INTERNAL.
+	* mkbuiltins: Generate code to define DEFUN_DLD_INTERNAL.
+	* mkgendoc: Likewise.
+
+	* Makefile.in (gendoc.o): Don't optimize when creating gendoc.
+	(%.dc : %.cc): Delete rule.
+
+	* pt-decl.cc (Vdefault_global_variable_value): Texinofize doc string.
+	* variables.cc (Fclear, Fdocument, Fexist, Fis_global, Fwho): Ditto.
+	* help.cc (Ftype, Fwhich): Ditto.
+	* ov.cc (Vstruct_levels_to_print, Vimplicit_str_to_num_ok): Ditto.
+	* data.cc (Fis_struct, Fstruct_elements, Fstruct_constains): Ditto.
+	* strfns.cc (Fisstr, Fsetstr): Ditto.
+	* pt-mat.cc: (Fimplicit_num_to_str_ok, Fstring_fill_char): Ditto.
+	* utils.cc (Fundo_string_escapes): Ditto.
+	* mappers.cc: (Fisalnum, Fisalpha, Fisascii, Fiscntrl, Fisdigit,
+	Fisgraph, Fislower, Fisprint, Fispunct, Fisspace, Fisupper,
+	Fisxdigit, Ftoascii, Ftolower, Ftoupper): Ditto.
+
+1999-11-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* syscalls.cc (symbols_of_syscalls): Use DEFCONSTX to define
+	Octave constants for C macros like O_WRONLY.
+
+	* oct-lvalue.cc (octave_lvalue::set_index): Disallow expressions
+	like x(i)(j) = rhs.
+
+1999-11-17  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.cc (symbol_record::type_as_string): New function.
+
+	* symtab.cc (symbol_record::which): New functions.
+	* help.cc (do_which): New functions.
+	(Fwhich): Use them.
+
+	* help.cc (help_from_symbol_table, help_from_file): New functions.
+	(builtin_help): Use them.
+
+	* help.cc (do_type): New function.
+	(symbol_record::type): New function.
+	(Ftype): Use them.
+
+	* help.cc (print_symbol_type): Delete.
+
+	* symtab.cc (symbol_table::name_list): Delete count arg.
+	(symbol_table::symbol_list): Likewise.
+	(symbol_table::glob): Likewise.  Also return Array<symbol_record *>
+	instead of symbol_record **.
+	Change all callers.
+	* help.cc (names, display_symtab_names): Delete count arg.
+
+	* help.cc (print_symbol_type, Ftype): No longer need to look up
+	fcn_file_name in the loadpath.
+
+	* help.cc (print_symbol_type): Handle dld functions.
+	(help_from_symbol_table, help_from_file): New functions.
+	(builtin_help): Use them.
+
+1999-11-16  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-cell.cc (Fiscell, Fcell): New Functions.
+	(octave_cell::do_index_op): New function.
+
+	* utils.cc (get_dimensions): Move here from data.cc and make extern.
+	(Vtreat_neg_dim_as_zero, treat_neg_dim_as_zero): Likewise.
+	(symbols_of_utils): New function.
+
+	* data.cc (fill_matrix (const octave_value_list&, double,
+	const char*)): New function.
+	(Fones, Fzeros): Use it to avoid some code duplication.
+
+1999-11-15  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-cell.h, pt-cell.cc, ov-cell.h, ov-cell.cc, Cell.h, Cell.cc:
+	New files.
+	* Makefile.in: Add them to the appropriate lists.
+	* pt-walk.h (visit_cell (tree_cell&): New pure virtual.
+	* pt-pr-code.cc (tree_print_code::visit_cell (tree_cell&)): New
+	function.
+	* TEMPLATE-INST/Array-tc.cc: Instantiate 2D arrays of octave_value
+	objects.
+	* pt-all.h: Include pt-cell.h.
+	* ov.h, ov.cc (octave_value::is_cell, octave_value::cell_value):
+	New functions.
+	* ov-base.h, ov-base.cc (octave_value::is_cell,
+	octave_value::cell_value): Provide defaults.
+	* lex.h, lex.l: Handle `{' and `}' tokens (for cell arrays).
+	(bracketflag): Rename from braceflag.
+	(handle_close_bracket): Rename from handle_close_brace.
+	(class bracket_brace_paren_nesting_level): Rename from
+	brace_paren_nesting_level.
+	(bracket_brace_paren_nesting_level::bracket, 
+	bracket_brace_paren_nesting_level::is_bracket): New functions to
+	keep count of nesting level for `[' and `]'.
+	(bracket_brace_paren_nesting_level::brace, 
+	bracket_brace_paren_nesting_level::is_brace): Now keeps count of
+	nesting level for `{' and `}'.
+	* parse.y (tree_cell_type): New type.
+	Give '{' the same precedence and associativity as '(' and '.'
+	(matrix_rows, matrix_rows1): Rename from rows, rows1.
+	(cell, cell_rows, cell_rows1): New non-terminals.
+	(cell_or_matrix_row): Rename from matrix_row.
+	(primary_expr): Accept cell here.
+	(postfix_expr): Allow indexing using '{' arg_list '}'.
+	(finish_cell): New function.
+
+1999-11-12  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (jump_to_top_level): No longer declared extern "C".
+
+	* cutils.c (octave_strcasecmp, octave_strncasecmp): New functions.
+	* utils.cc (almost_match): Call octave_strncasecmp instead of
+	calling strncasecmp directly.
+
+1999-11-10  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y: Don't define warn_reload_forces_clear here.
+
+	* Makefile.in (DISTFILES): Include DOCSTRINGS.
+
+1999-11-05  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (install_signal_handlers): Don't install
+	sigwinch_handler.
+
+	* oct-iostrm.h (octave_istream::eof, octave_ostream::eof): Provide
+	implementation for these.
+
+	* oct-stream.cc (octave_base_stream::do_scanf):
+	The stdin stream is only special if we are interactive.
+	(octave_base_stream::scanf): Ditto.
+	(octave_base_stream::do_oscanf): Ditto.
+	(octave_base_stream::oscanf): Ditto.
+
+	* ov.h (octave_value::is_stream): New predicate.
+	* ov-file.h (octave_file::is_stream): Return true.
+	* file-io.cc (Fis_stream): New function.
+
+	* ov-file.h (class octave_file): stream is now an object instead
+	of pointer.
+	* ov-file.cc (octave_file::print_raw): Handle stream as object
+	instead of pointer.  Also print stream status.
+
+	* ov-base.cc (octave_base_value::stream_value): Return object
+	instead of pointer.
+
+	* ov.cc (octave_value::stream_value): Return object instead of pointer.
+	(octave_value::octave_value (const octave_stream&)): Take const
+	reference instead of pointer arg.
+
+	* TEMPLATE-INST/Array-os.cc: Instantiate Arrays of octave_stream
+	objects, not pointers to them.
+
+	* OPERATORS/op-fil-b.cc: Cope with octave_stream class changes.
+	* OPERATORS/op-fil-bm.cc: Likewise.
+	* OPERATORS/op-fil-cm.cc: Likewise.
+	* OPERATORS/op-fil-cs.cc: Likewise.
+	* OPERATORS/op-fil-lis.cc: Likewise.
+	* OPERATORS/op-fil-m.cc: Likewise.
+	* OPERATORS/op-fil-rec.cc: Likewise.
+	* OPERATORS/op-fil-s.cc: Likewise.
+	* OPERATORS/op-fil-str.cc: Likewise.
+	* file-io.cc: Likewise.
+	* syscalls.cc (Fdup): Likewise.
+
+	* oct-fstrm.cc, oct-fstrm.h, oct-iostrm.cc, oct-iostrm.h,
+	oct-prcstrm.cc, oct-prcstrm.h, oct-stdstrm.cc, oct-stdstrm.h,
+	oct-stream.cc, oct-stream.h, oct-strstrm.cc, oct-strstrm.h:
+	Rewrite to allow octave_stream objects to be used like values
+	instead of having to use pointers.
+
+1999-11-03  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_scanf): If it looks like
+	we have a matching failure, then reset the failbit in the stream
+	state.
+	(octave_base_stream::do_oscanf): Likewise.
+
+1999-11-02  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* help.cc (Fhelp): Texinfoize doc string.
+	* input.cc (Fecho, Fcompletion_matches): Ditto.
+	* oct-hist.cc (Fedit_history, Fhistory, Frun_history): Ditto.
+	* pager.cc (Fdiary): Ditto.
+	* sysdep.cc (Fclc): Ditto.
+	* toplev.cc (Fquit, Fatexit): Ditto.
+	
+1999-11-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (yywrap): No longer static.
+	(have_continuation): Declare input character as int, not char, so
+	comparison to EOF will work.
+
+1999-11-01  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun.cc (print_usage): Use display_help_text instead of sending
+	help message directly to octave_stdout.
+
+1999-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun-dld.h (INSTALL_DLD_FCNS, INSTALL_DLD_FCN): Delete definitions.
+	* DLD-FUNCTIONS/dassl.cc: Don't use INSTALL_DLD_FCN or
+	INSTALL_DLD_FCNS macros.  They are not necessary with the new code
+	in dynamic-ld.cc.
+	* DLD-FUNCTIONS/lsode.cc: Ditto.
+	* DLD-FUNCTIONS/fsolve.cc: Ditto.
+	* DLD-FUNCTIONS/quad.cc: Ditto.
+	* DLD-FUNCTIONS/time.cc: Ditto.
+	* DLD-FUNCTIONS/besselj.cc: Ditto.
+	* DLD-FUNCTIONS/getgrent.cc: Ditto.
+	* DLD-FUNCTIONS/getpwent.cc: Ditto.
+	* DLD-FUNCTIONS/inv.cc: Ditto.
+	* DLD-FUNCTIONS/log.cc: Ditto.
+	* DLD-FUNCTIONS/minmax.cc: Ditto.
+	* DLD-FUNCTIONS/rand.cc: Ditto.
+
+	* dynamic-ld.cc, dynamic-ld.h: Major rewrite to allow reloading of
+	dynamically linked functions.
+
+	* symtab.cc (symbol_record::replace_all_defs): Don't allow top
+	definition to be NULL.
+	(symbol_table::clear): Allow dynamically linked functions to be
+	cleared.
+
+	* symtab.h (TYPE): New enum value, DLD_FUCTION.
+	(symbol_type): Now 8 bits wide.
+	(SYMTAB_ALL_TYPES): Include DLD_FUNCTION.
+	(symbol_record::symbol_def::is_function): Also recognize dld functions.
+	(symbol_record::symbol_def::is_dld_function): New function.
+	(symbol_record::is_dld_function): Ditto.
+
+	* defun.cc (install_dld_function): New function.
+	* defun-int.h: Provide declaration here.
+	(octave_dld_fcn_installer): New typedef.
+	(DEFINE_FUN_INSTALLER_FUN): Installer function now takes an
+	oct_shlib object as an arg.  Allow installation of a function to
+	happen more than once.
+
+	* octave.cc (initialize_error_handlers): Call
+	set_liboctave_warning_handler here too.
+
+	* ov-builtin.h (is_builtin_function): Return true.
+	Data member is now protected, not private.
+
+	* ov-fcn.h (is_dynamically_loaded_function): New predicate.
+	(unload): New function.
+	Data members are now protected, not private.
+
+	* ov.h (is_builtin_function, is_dld_function): New predicates.
+	* ov-base.h (is_builtin_function, is_dld_function): Ditto.
+
+	* parse.y (Vwarn_reload_forces_clear): New static flag.
+	(warn_reload_forces_clear): New function.
+	(symbols_of_parse): DEFVAR warn_reload_forces_clear.
+
+	* variables.cc (Fclear): Look for dld functions too.
+
+	* ov-dld-fcn.cc, ov-dld-fcn.h: New files.
+	* Makefile.in (OV_INCLUDES, OV_SRC): Add them to the lists.
+
+	* Makefile.in (DEFVAR_PATTERN): Also match DEFCONSTX.
+
+1999-10-26  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLList.h, DLList.cc: New files.
+	* Makefile.in (INCLUDES, DIST_SRC): Add them to the lists.
+
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Be sure to call
+	unwind_protect::run_frame before returning.
+	* DLD-FUNCTIONS/quad.cc (Fquad): Likewise.
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (Fdassl): Likewise.
+
+	* load-save.cc (read_mat_ascii_data): When reading from
+	tmp_stream, check its state, not the state of is.
+
+	* defun-dld.h (INSTALL_DLD_FCN, INSTALL_DLD_FCNS): New macros.
+	* DLD-FUNCTIONS/dassl.cc: Use them.
+	* DLD-FUNCTIONS/lsode.cc: Ditto.
+	* DLD-FUNCTIONS/fsolve.cc: Ditto.
+	* DLD-FUNCTIONS/quad.cc: Ditto.
+	* DLD-FUNCTIONS/time.cc: Ditto.
+	* DLD-FUNCTIONS/besselj.cc: Ditto.
+	* DLD-FUNCTIONS/getgrent.cc: Ditto.
+	* DLD-FUNCTIONS/getpwent.cc: Ditto.
+	* DLD-FUNCTIONS/inv.cc: Ditto.
+	* DLD-FUNCTIONS/log.cc: Ditto.
+	* DLD-FUNCTIONS/minmax.cc: Ditto.
+	* DLD-FUNCTIONS/rand.cc: Ditto.
+
+	* data.cc (Flinspace): Let linspace functions handle errors.
+
+	* mkgendoc (print_doc_string): Handle quoted names.
+
+	* file-io.cc (symbols_of_file_io): Use DEFCONSTX for SEEK_SET,
+	SEEK_CUR, and SEEK_END.
+
+	* defun.h (DEFCONST): Just pass name, defn, and doc to
+	DEFCONST_INTERNAL.
+	(DEFCONSTX): Likewise, pass name, defn, and doc to DEFCONSTX_INTERNAL.
+	* defun-int.h [MKBUILTINS] (DEFCONST_INTERNAL): Likewise, pass
+	name, defn, and doc to XDEFCONST_INTERNAL.
+	[MKBUILTINS] (DEFCONSTX_INTERNAL): New macro.
+	(INSTALL_CONST): New macro.
+	[! MKBUILTINS] (DEFCONST_INTERNAL): Use it to handle details here.
+	[! MKBUILTINS] (DEFCONSTX_INTERNAL): Ditto.
+	* mkgendoc: Fix definition of XDEFCONST_INTERNAL to match.
+	* mkbuiltins: Ditto.
+
+	* mkdefs: Match spaces before BEGIN_INSTALL_BUILTIN.
+
+	* Makefile.in (DEFUN_PATTERN): Also match DEFUN_MAPPER.
+
+1999-10-26  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* data.cc (VI, VInf, VJ, VNaN, Ve, Veps, Vfalse, Vi, Vinf, Vj,
+	Vnan, Vpi, Vrealmax, Vrealmin): Texinfoize doc strings.
+	* mappers.cc (Fabs, Facos, Facosh, Fangle, Farg, Fasin, Fasinh,
+	Fatan, Fatanh, Fceil, Fconj, Fcos, Fcosh, Ferf, Ferfc, Fexp,
+	Ffinite, Ffix, Ffloor, Fgamma, Fimag, Flgamma, Flog, Flog10,
+	Freal, Fround, Fsign, Fsin, Fsinh, Fsqrt, Ftan, Ftanh): Ditto.
+
+1999-10-23  Ben Sapp  <bsapp at nua.lampf.lanl.gov>
+
+	* data.cc (Fis_matrix): Texinfoize doc string.
+	* ov.cc	(Vpropagate_empty_matrices): Ditto.
+	* pt-mat.cc: (Vempty_list_elements_ok): Ditto.
+	* pr-output.cc (Vfixed_point_format, Voutput_max_field_width,
+	Voutput_precision, Vprint_empty_dimensions, Vsplit_long_rows):
+	Ditto.
+
+1999-10-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.cc (octave_user_function::do_index_op): If
+	Vmax_recursion_depth is exceeded, call unwind_protect::run_frame
+	before returning.
+
+1999-10-21  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* cutils.c (do_octave_usleep): Handle useconds > 1e6.
+
+	* variables.h (is_valid_function): Provide default values for the
+	string argument.
+
+	* symtab.cc (variable_reference): Maybe print warning (or error)
+	about variables that hide functions of the same name.
+	(symbol_record::define (const octave_value&, unsigned int)): Ditto.
+	(Vvariables_can_hide_functions): New static variable.
+	(variables_can_hide_functions, symbols_of_symtab): New functions.
+
+	* cutils.c: New file.
+	* Makefile.in (SOURCES): Add it to the list.
+	* utils.h: Declare octave_usleep here.
+	* dirfns.cc (Fls): Simply all octave_usleep.
+	* oct-procbuf.cc (octave_procbuf::open): Ditto.
+	* sysdep.cc (Fusleep): Ditto.
+	* toplev.cc (run_command_and_return_output): Ditto.
+
+1999-10-20  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (make_diag (const octave_value&, const octave_value&)):
+	Delete special cases for scalars and simply attempt conversion of
+	first arg to a matrix value.  If that fails, we will still see an
+	error message.
+
+	* Makefile.in (DISTFILES): Add mkgendoc to the list.
+
+1999-10-19  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stmp-pic): New target.
+	($(PICOBJS)): Depend on stmp-pic, not pic.
+
+	* ov.h (get_rep): New function.
+
+	* help.cc (display_help_text): Pass definitions for VERSION,
+	OCTAVE_HOME, and TARGETHOSTTYPE to makeinfo.
+
+	* DLD-FUNCTIONS/getgrent.cc: Texinfoize all doc strings.
+	* DLD-FUNCTIONS/getpwent.cc: Ditto.
+	* DLD-FUNCTIONS/getrusage.cc: Ditto.
+	* DLD-FUNCTIONS/time.cc: Ditto.
+
+	* defaults.cc (EXEC_PATH, OCTAVE_VERSION): Texinfoize doc strings.
+	* dirfns.cc (Fcd, Fls, Fpwd, Freaddir, Fmkdir, Frmdir, Frename,
+	Fglob, Ffnmatch): Ditto.
+	* file-io.cc (Fpopen, Fpclose, Fumask): Ditto.
+	* sysdep.cc (Fgetenv, Fputenv, Fpause, Fsleep, Fusleep, Fisieee,
+	Ftilde_expand): Ditto.
+	* toplev.cc (Fcomputer, Fsystem, Foctave_config_info): Ditto.
+	* utils.cc (Ffile_in_path): Ditto.
+	* syscalls.cc (Fdup2, Fexec, Ffcntl, Ffork, Fgetpgrp, Fgetpid,
+	Fgetppid, Fgetegid, Fgetgid, Fgeteuid, Fgetuid, Fmkfifo, Fpipe,
+	Fstat, Funlink, Fwaitpid, F): Ditto.
+	(Flstat): Refer to stat for doc.
+
+
+	* help.cc (looks_like_texinfo): New function.
+	(display_help_text): Use it to see if the doc string looks like
+	Texinfo source.  If so, use makeinfo to format the text before
+	displaying it.
+
+	* mkgendoc: New script.
+	* Makefile.in: Use it to create gendoc.cc, which is compiled and
+	run to create DOCSTRINGS file from sources.
+
+1999-10-18  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (help_from_info): Print `unable to find info' message if
+	try_info returns 127; otherwise, print `not indexed' message.
+	Don't sleep after printing `not indexed' message.
+
+1999-10-14  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (fold (tree_unary_expression *)): New function.
+	(make_prefix_op, make_postfix_op): Use it.
+
+1999-10-13  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (oct-gperf.h): Ask for ANSI-C output from gperf
+	(requires gperf-2.7 or later).
+
+	* sighandlers.cc (sigwinch_handler): New function.
+	(install_signal_handlers): Install it.
+
+Thu Sep 23 19:49:36 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (Fsystem): For async case, use execl instead of
+	system, avoiding the need to exit after executing the subprocess.
+
+Thu Sep  9 17:09:23 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (get_size): Allow zero values.
+	(get_size): New arg, one_elt_size_spec.
+	(do_scanf_conv): New arg, `conv_count'.  Change instantiation
+	requests and all callers.
+	(octave_base_stream::do_scanf): Improve scanning of strings.
+	(octave_base_stream::do_oscanf): Remove size limit on %s conversions.
+
+	* oct-stream.cc (scanf_format_list::all_character_conversions):
+	Don't count %p as a character conversion.
+
+Tue Sep  7 08:31:04 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (set_real_matrix_format, set_complex_matrix_format): 
+	Move check for fixed_point_format ahead of check for
+	int_or_inf_or_nan.
+
+Thu Sep  2 11:54:51 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-obj.cc (make_argv): Correctly handle empty strings as args.
+
+Fri Aug 20 08:17:52 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/quad.cc (quad): Delete unused label.
+
+	* unwind-prot.cc (saved_variable::~saved_variable): Don't try to
+	delete gen_ptr_value here.
+
+Mon Aug 16 21:34:33 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (next_token_is_sep_op): New function.
+	(handle_close_brace, maybe_unput_comma): Use it.
+	(have_continuation): Also handle CRLF here.
+
+Wed Aug 11 16:06:57 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ffopen): Make fopen ("filename") work and imply that
+	MODE = "r".
+
+Wed Jul 21 15:38:52 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (display_names_from_help_list): Sort names before
+	listing them.
+	(print_symbol_type, Ftype): Also handle built-in constants.
+	(LIST_SYMBOLS): Correct call to symbol_table::name_list.
+	(simple_help): List constants here too.  List constants and
+	variables before functions, not after.  Sort names before listing
+	them.
+
+	* variables.cc (do_who): Display built-in constants in a separate
+	section.
+
+	* error.cc (bind_global_error_variable, clear_global_error_variable): 
+	Call bind_builtin_constant, not bind_builtin_variable to set
+	__error_text__.
+	* octave.cc (intern_argv): Likewise, for argv and __argv__.
+
+	* defun.cc (install_builtin_constant): Move function guts to
+	bind_builtin_constant in variables.cc.
+	* variables.cc (bind_builtin_constant): New function.
+
+	* symtab.cc (symbol_record::define, symbol_record::variable_reference):
+	Handle constants the same as functions.
+	(symbol_record::link_to_builtin_variable): New function.
+	(symbol_record::define_builtin_const): New function.
+	(symbol_record::define_as_fcn): Delete unused function.
+	(symbol_record::read_only_error):
+	Handle constants the same as variables.
+	* symtab.h (symbol_record::BUILTIN_CONSTANT): New enum value.
+	(symbol_record::symbol_type): Increase width to 7 bits.
+	(symbol_record::symbol_def::is_constant): New function.
+	(symbol_record::symbol_def::is_builtin_constant): New function.
+	(symbol_record::is_constant): New function.
+	(symbol_record::is_builtin_constant): New function.
+	(SYMTAB_ALL_TYPES): Add symbol_record::BUILTIN_CONSTANT.
+	* variables.cc (link_to_builtin_variable): Delete unused function.
+	(link_to_builtin_or_function): Handle built-in constants here too.
+
+	* defun.cc (install_builtin_variable): Delete inst_as_fcn arg.
+	(install_builtin_constant): New function.
+	(install_builtin_variable_as_function): Delete unused function.
+	* defun.h (DEFVAR_INTERNAL): Delete inst_as_fcn arg.
+	(DEFCONST_INTERNAL): New macro.
+	* defun.h (DEFVAR): Delete inst_as_fcn arg.
+	(DEFCONST, DEFCONSTX): Define using DEFCONST_INTERNAL instead of
+	DEFVAR_INTERNAL.
+	* data.cc, defaults.cc, error.cc, help.cc, input.cc, lex.l,
+	load-save.cc, oct-hist.cc, oct-procbuf.cc, ov-fcn.h,
+	ov-usr-fcn.cc, ov.cc, pager.cc, parse.y, pr-output.cc,
+	pt-assign.cc, pt-decl.cc, pt-mat.cc, pt-plot.cc, pt-stmt.cc,
+	toplev.cc, variables.cc:
+	Change all invocations of DEFVAR to match new definition.
+
+	* data.cc (symbols_of_data): Add DEFCONSTs for true and false.
+
+Thu Jul 15 10:59:42 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fis_bool, Fis_complex, Fisempty, Fisnumeric, Fis_list,
+	Fis_map, Fis_struct): Return bool object.
+	(Fisreal): New function.
+
+	* ov-str-mat.h (octave_char_matrix_str): Only return true if
+	Vimplicit_str_to_num_ok is also true.
+
+	* DLD-FUNCTIONS/time.cc (Ftime): Print usage message if	any
+	arguments are supplied.
+
+	* variables.cc (symbol_out_of_date): Call octave_time for time stamps.
+
+	* fn-cache.h (octave_fcn_file_name_cache::timestamp):
+	Now octave_time object.
+
+	* strftime.c: Move to liboctave directory.
+	* Makefile.in (DIST_SRC): Delete from list.
+
+	* ov-usr-fcn.h (octave_user_function::t_parsed,
+	octave_user_function::t_checked): Now octave_time objects.
+	(octave_user_function::time_parsed,
+	(octave_user_function::time_checked):
+	Return value is now octave_time object.
+	(octave_user_function::mark_fcn_file_up_to_date)):
+	Arg is now octave_time object.
+	
+	* ov-fcn.h (octave_function::mark_fcn_file_up_to_date)):
+	Arg is now octave_time object.
+	(octave_function::time_parsed, octave_function::time_checked):
+	Return value is now octave_time object.
+
+	* input.cc (Vlast_prompt_time): Now an octave_time object.
+	(octave_gets): Call octave_time::stamp() to set Vlast_prompt_time.
+
+	* DLD-FUNCTIONS/time.cc (mk_tm_map, extract_tm, Ftime, Fgmtime,
+	Flocaltime, Fmktime, Fstrftime): Use new classes defined in
+	liboctave/oct-time.cc instead of accessing C functions directly.
+
+Wed Jul 14 17:38:46 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* systime.h: Move to liboctave directory.
+	* Makefile.in (INCLUDES): Delete it from the list
+
+Tue Jul 13 14:34:57 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (sigchld_handler): Only wait for processes in
+	octave_child_list.
+	* toplev.cc (cmd_status): Delete unused static variable.
+	(cmd_death_handler): Delete unused function.
+	(run_command_and_return_output): Don't add cmd_death_handler to
+	octave_child_list.  Simply extract command exit status from
+	calling close() on the procstream object.
+
+Mon Jul 12 22:38:50 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun.h (DEFUN_MAPPER): Handle new args, d_b_map and c_b_map.
+	* defun-int.h (DEFUN_MAPPER_INTERNAL): Likewise.
+	* mappers.cc (install_mapper_functions): Supply new args to
+	all uses of DEFUN_MAPPER.
+	* ov-mapper.cc (octave_mapper::apply): Handle mapper functions
+	that return bool objects.
+	* ov-mapper.h (octave_mapper::d_b_mapper, octave_mapper::c_b_mapper):
+	New typedefs.
+	(octave_mapper::octave_mapper): Handle new mapper function types.
+
+	* DLD-FUNCTIONS/minmax.cc: Do a better job of handling NaNs.
+
+Sun Jul 11 13:15:17 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (do_plus_format (ostream&, double)): New function.
+	(octave_print_internal (ostream&, double, bool)): Use it.
+	(octave_print_internal (ostream&, const Matrix&, bool, int)): Ditto.
+
+	* pr-output.cc (do_plus_format (ostream&, const Complex&)):
+	New function.
+	(octave_print_internal (ostream&, const Complex&, bool)): Use it.
+	(octave_print_internal (ostream&, const ComplexMatrix&, bool, int)):
+	Ditto. 
+
+Sun Jun 20 23:04:00 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc: Include sys/ioctl.h if available.
+
+Sat Jun 19 12:07:16 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (do_who): Make pattern and multiple non-option
+	arguments work.
+
+Mon Jun  7 09:54:51 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (next_token_is_bin_op, next_token_is_postfix_unary_op,
+	handle_number): Delete yytext arg.  Change all callers.
+	(next_token_is_postfix_unary_op): Check the first character
+	obtained from yyinput before calling it again.
+	(next_token_is_bin_op): Do a more thorough check.
+	(handle_identifier): Also enter token in local symbol table if the
+	following token is a dot and it looks like a binary operator.
+	(whitespace_in_literal_matrix): Now static.
+
+	* lex.l: Always use unput, not yyunput.
+
+Fri May 28 11:02:37 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/chol.cc (Fchol): If two output arguments, never
+	produce error message.
+
+Thu May 27 18:28:35 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/chol.cc (Fchol): Also return info as second output.
+
+	* DLD-FUNCTIONS/minmax.cc (max (const ComplexMatrix&, const
+	ComplexMatrix&)): Correct test for real columns only.  
+	(min (const ComplexMatrix&, const ComplexMatrix&)): Likewise.
+
+Wed Apr 14 12:54:25 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/dassl.cc (Fdassl): Prevent recursive calls.
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Likewise.
+	* DLD-FUNCTIONS/quad.cc (Fquad): Likewise.
+
+	* file-io.cc (Fsscanf, Ffscanf): Doc fix.
+
+Sat Mar 27 11:07:51 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::count): New function.
+	* symtab.cc (symbol_record::dump_symbol_info): New function.
+	* symtab.cc (symbol_record::symbol_def::dump_symbol_info): Ditto.
+	* variables.cc (F__dump_symbol_info__): Ditto.
+
+	* pt-misc.cc (tree_parameter_list::clear): New function.
+	* ov-usr-fcn.h (octave_user_function::clear_args_passed): Ditto.
+	* ov-usr-fcn.cc (clear_param_list): New function.
+	(clear_args_passed): New function.
+	(octave_user_function::do_index_op): Use them to decrement
+	reference counts on local variables.
+
+Fri Mar 26 00:51:53 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (libraries): Use the libfoo.a(objects) method of
+	creating static libs.
+
+	* defaults.cc (symbols_of_defaults): Initialize LOADPATH to
+	Vload_path, not ":".
+
+Thu Mar 18 12:09:23 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fisnumeric): Fix typo.
+
+Thu Mar  4 02:17:04 1999  James Macnicol  <jamesm at evans.ee.adfa.oz.au>
+
+	* file-io.cc (Ffread, Ffwrite): Add uint16 and uint32 data types
+	to doc string.
+
+Wed Mar  3 11:55:17 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_string): Allow "" to pass through unchanged if
+	working on a gset command.
+
+Tue Mar  2 01:36:29 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fexist): If a variable isn't defined, only go on
+	to look for a global by the same name if we are at the top level.
+
+Fri Jan 29 02:18:36 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_NAME_AND_VERSION): Say `GNU Octave', not just
+	Octave.
+
+Thu Jan 28 21:29:16 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (Fcomputer): Use CANONICAL_HOST_TYPE, not TARGET_HOST_TYPE.
+	(octave_config_info): Likewise.
+	* version.h: Ditto.
+
+	* sysdep.cc (Fpause): Flush output before getting user input.
+
+Wed Jan 27 14:18:29 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DEFFUN_PATTERN, DEFVAR_PATTERN): Use egrep again.
+	Make the patterns work with stupid egreps that don't like empty
+	elements in alternation patterns.
+
+Fri Jan 22 04:41:48 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_ascii_data): Check for string type first,
+	then range, then the rest.
+	(save_binary_data): Ditto.
+
+	* pager.cc (more_than_a_screenful): Accept length as second arg.
+	Handle long lines properly, assuming the terminal wraps long lines.
+	(octave_pager_buf::do_sync): Accept length of data as second arg.
+	Use write instead of << to put characters on output stream.
+	(octave_pager_buf::sync): Don't assume data ends at first NUL.
+	(octave_diary_buf::sync): Ditto.
+
+Thu Jan 21 22:15:23 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_mat_binary_data): Check for string type
+	first, then range, then the rest.
+
+Wed Jan 20 12:01:14 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_scanf): Handle short and
+	long ints correctly.
+
+Fri Jan 15 13:04:58 1999  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (end_error): Handle case of endswitch too.
+
+	* Makefile.in: Use basic regular expressions and grep instead of
+	egrep to find files that contain DEFVAR, DEFCONST, or DEFUN.
+
+Wed Dec  9 14:14:11 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (octave): Add $(RDYNAMIC_FLAG) to link command.
+
+Fri Dec  4 20:26:33 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/time.cc (Fstrftime): Make it work even when not
+	using the GNU version of strftime, which allows passing NULL for
+	the buffer to determine the required size of the buffer.
+
+Wed Dec  2 22:38:40 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (file_in_loadpath): Expect argc == 2, not 3.
+
+Tue Nov 24 23:38:19 1998  Eric Norum  <eric at skatter.USask.Ca>
+
+	* mkbuiltins: Also strip off leading `./' from file names.
+	* mkops: Ditto.
+
+Tue Nov 24 23:24:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strftime.c: Surround everything with #ifdef HAVE_STRFTIME / #endif.
+
+	* lex.h (YY_FATAL_ERROR): Call yy_falta_error after
+	jump_to_top_level to avoid gcc warning.
+
+Fri Nov 20 13:34:47 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool.h, ov-bool.cc (class octave_bool): Derive from
+	octave_base_scalar and get common functions via derivation.
+	* ov-scalar.h, ov-scalar.cc (class octave_scalar): Ditto.
+	* ov-complex.h, ov-complex.cc (class octave_complex): Ditto.
+
+	* ov-base-scalar.h, ov-base-scalar.cc (class octave_base_scalar):
+	New files for new class definition.  Put common scalar data type
+	stuff here.
+	* Makefile.in (OV_INCLUDES, OV_SRC): Add them to the lists.
+
+Thu Nov 19 14:30:25 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+	
+	* dynamic-ld.cc (octave_dynamic_loader::mangle_name):
+	Prepend underscore here.
+	(octave_dynamic_loader::load_fcn_from_dot_oct_file): Not here.
+
+	* ov-re-mat.h (octave_matrix_value): Delete experimental code for
+	handling structure references for things like .rows, .cols, etc.
+
+Wed Nov 18 01:18:46 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (VAR_FILES): Be more careful about matching.
+	(DEF_FILES): Likewise.
+
+	* ov-base-mat.h, ov-base-mat.cc, ov-bool-mat.h, ov-bool-mat.cc,
+	ov-ch-mat.h, ov-ch-mat.cc, ov-cx-mat.h, ov-cx-mat.cc,
+	ov-re-mat.h, ov-re-mat.cc: Move default definition of all, any,
+	is_matrix_type, is_numeric_type, valid_as_zero_index, and
+	do_index_op to base class.
+	Provide definitions that override the defaults where necessary.
+
+	* mappers.cc: Don't include lo-specfun.h.
+
+Tue Nov 17 14:35:56 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* besselj.cc (Fbesselh, Fairy); New functions.
+	(Fbesselj, Fbessely, Fbesselk, Fbesseli): Update doc strings.
+	(do_bessel): Handle additional args.
+
+Fri Nov 13 14:47:11 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (NUMBER): Allow hexadecimal constants.
+	(looks_like_hex): New function.
+	(handle_number): Check for hexadecimal constants and convert them
+	to unsigned integer values.
+
+Thu Nov 12 11:13:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (gnu_readline): Check for EOF from command_editor::readline.
+
+	* ov-str-mat.h, ov-str-mat.cc (class octave_char_matrix_str):
+	Get common functions via new derivation scheme.
+	
+	* ov-bool-mat.h, ov-bool-mat.cc (class octave_bool_matrix):
+	Derive from octave_base_matrix and get common functions via derivation.
+	* ov-ch-mat.h, ov-ch-mat.cc (class octave_char_matrix): Ditto.
+	* ov-cx-mat.h, ov-cx-mat.cc (class octave_complex_matrix): Ditto.
+	* ov-re-mat.h, ov-re-mat.cc (class octave_real_matrix): Ditto.
+
+	* ov-base-mat.h, ov-base-mat.cc (class octave_base_matrix): New
+	files  for new class definition.  Put common matrix data type
+	stuff here.
+
+	* ov-list.cc (Fnth): New function.
+
+	* ov-list.cc (octave_list::do_index_op): Allow more complex indexing.
+
+	* oct-obj.cc (octave_value_list::index): New function.
+	(octave_value_list::octve_value_list (Array<octave_value>)):
+	New private constructor.
+
+	* ov-list.cc (Fsplice): Fix docstring to match.
+	* oct-obj.cc (octave_value_list::splice): Allow special case
+	splice (x, length(x)+1, 0, y) to be equivalent to append (x, y).
+
+	* ov-list.cc (Fappend): If an arg is a list, concatenate the lists
+	instead of appending arg as a single element.
+
+Wed Nov 11 14:07:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (get_mat_data_input_line): New function.
+	(get_lines_and_columns): Use it here.
+	(read_mat_ascii_data): And here and do our own reading instead of
+	using Matrix::operator<<.
+
+Tue Nov 10 16:12:25 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (make_constant): Initialize retval to 0.
+
+	* toplev.h (clean_up_and_exit (void)): Delete declaration.
+	* toplev.cc (do_octave_atexit): Move guts of clean_up_for_exit
+	here, but ensure that the actions are only executed once.
+	* octave.cc (main): Don't register cleanup_tmp_files with atexit.
+
+	* ov.h, ov.cc (class octave_value): Use DECLARE_OCTAVE_ALLOCATOR
+	and DEFINE_OCTAVE_ALLOCATOR for uniform declaration and definition
+	of allocator functions.  Use DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+	and DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA for uniform declaration
+	and definition of type id functions and data.
+	* ov-usr-fcn.h, ov-usr-fcn.cc (class octave_user_function): Ditto.
+	* ov-scalar.h, ov-scalar.cc (class octave_scalar): Ditto.
+	* ov-re-mat.h ov-re-mat.cc (class octave_matrix): Ditto.
+	* ov-range.h, ov-range.cc (class octave_range): Ditto.
+	* ov-mapper.h, ov-mapper.cc (class octave_mapper): Ditto.
+	* ov-list.h, ov-list.cc (class octave_list): Ditto.
+	* ov-file.h, ov-file.cc (class octave_file): Ditto.
+	* ov-fcn.h, ov-fcn.cc (class octave_function): Ditto.
+	* ov-cx-mat.h, ov-cx-mat.cc (class octave_complex_matrix): Ditto.
+	* ov-complex.h, ov-complex.cc (class octave_complex): Ditto.
+	* ov-ch-mat.h, ov-ch-mat.cc (octave_char_matrix): Ditto.
+	* ov-builtin.h, ov-builtin.cc (class octave_builtin): Ditto.
+	* ov-bool.h, ov-bool.cc (class octave_bool): Ditto.
+	* ov-bool-mat.h, ov-bool-mat.cc (octave_bool_matrix): Ditto.
+
+	* ov.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): New macro.
+	(DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA): Ditto.
+
+Mon Nov  9 16:12:37 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (octave_print_internal): Reorder default args for
+	charMatrix version.
+	(octave_print_internal): New function for boolMatrix.
+
+	* version.h (OCTAVE_STARTUP_MESSAGE): Note that this is a
+	development release.
+
+	* toplev.cc (do_octave_atexit): Call flush_octave_stdout here.
+	(clean_up_for_exit): And here.
+
+Mon Nov  9 15:20:53 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (get_user_input): Check retval.length(), not	retval.length.
+
+Sun Nov  8 19:30:33 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-assign.cc (tree_simple_assignment::rvalue): If etype is
+	asn_eq, don't evaluate ult again because retval is just rhs value.
+	(tree_multi_assignment::rvalue): Likewise.
+
+Fri Nov  6 12:14:29 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-loop.cc (tree_for_command::eval): Move code for string RHS
+	outside if clause for matrix types.
+
+	* pt-idx.cc: Don't forget to define arg_nm.
+	Move contstructor here.
+	* pt-idx.h: From here.
+
+	* data.cc (Fisempty): Also return true for empty strings.
+
+Wed Nov  4 17:21:41 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base.cc (octave_base_value::rows, octave_base_value::columns,
+ 	octave_base_value::length): Delete.
+	* ov-base.h (octave_base_value::rows, octave_base_value::columns,
+ 	octave_base_value::length): Define here.  All return -1 if not
+	defined in a derived class.
+
+	* data.cc (Fis_matrix): Also return true if the arg is a range.
+
+Tue Nov  3 09:40:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fis_bool): New function.
+	Also add alias for islogical.
+
+	* ov.h (octave_value::is_bool_type): New function.
+	* ov-base.h (octave_base_value::is_bool_type): Likewise.
+	* ov-bool.h (octave_bool::is_bool_type): Likewise.
+	* ov-bool-mat.h (octave_bool_matrix::is_bool_type): Likewise.
+
+Mon Nov  2 13:36:04 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_close_brace): Also handle case of ']' followed by
+	other assignment ops (+=, -=, ...).
+
+	* pt-assign.cc (tree_simple_assignment::rvalue): Correctly handle
+	return value and printing for operators other than `='.
+	(tree_multi_assignment::rvalue): Likewise.
+
+	* pt-assign.h (tree_multi_assignment::etype): New data member.
+	* pt-assign.cc 	(tree_multi_assignment::rvalue): Use it instead of
+	assuming `='.
+	(tree_multi_assignment::oper): New function.
+	* pt-pr-code.cc (tree_print_code::visit_multi_assignment): Use
+	it instead of always printing `='. 
+	* parse.y (make_assign_op): Pass expression type to
+	tree_multi_assignment constructor.	
+
+	* Makefile.in (stmp-pic): New target.
+	($(PICOBJ)): Depend on stmp-pic, not pic.
+	(clean): Delete stmp-pic.
+
+Sun Nov  1 23:24:55 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mappers.cc (install_mapper_functions): Add alias for isfinite.
+
+Sat Oct 31 08:46:55 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fisnumeric): New function.
+
+Fri Oct 30 08:39:30 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-lvalue.cc (octave_lvalue::do_unary_op): Make it work for
+	indexed ops too.
+	* ov.cc (octave_value::unary_op_to_assign_op): New function.
+	(octave_value::do_non_const_unary_op): New function for	indexed ops.
+
+	* parse.y (LEFTDIV_EQ, ELEFTDIV_EQ): New tokens.
+	(assign_expr): Add rules for them.
+	(make_assign_op): Handle them here too.
+	* lex.l: Recognize them.
+	* ov.h (octave_value::assign_op): Add ldiv_eq and el_ldiv_eq.
+	* ov.cc (octave_value::assign_op_as_string): Ditto.
+	(octave_value::op_eq_to_binary_op): Ditto.
+	(octave_value::assign): Handle OP= style operators with brute force.
+	(octave_value::simple_assign): New function.
+
+	* parse.y (matrix): Dont' forget to reset
+	lexer_flags.looking_at_matrix_or_assign_lhs.
+
+	* oct-lvalue.cc (octave_lvalue::assign): Don't call change
+	function if error occurs.
+	(octave_lvalue::do_unary_op): If we have an index, fail with message.
+
+Thu Oct 29 09:27:04 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.cc (do_binary_op): Protect against invalid type conversions.
+	(try_assignment_with_conversion): Likewise.
+	(do_unary_op): Likewise.
+
+	* ov.h (OV_UNOP_FN, OV_UNOP_OP, OV_UNOP_FN_OP): New macros.
+	Use them to define not, uminus, transpose, hermitian functions
+	and operators ! and -.
+	(OV_BINOP_FN, OV_BINOP_OP, OV_BINOP_FN_OP): New macros.
+	Use them to define add, sub, mul, div, pow, ldiv, lshift, rshift,
+	lt, le, eq, ge, gt, ne, el_mul, el_div, el_pow, el_ldiv, el_and,
+	el_or, struct_ref, functions and operators <, <=, ==, >=, >, !=,
+	+, -, *, and /.
+
+	* ops.h (CONVDECLX): New macro.
+	* ov-base.cc (matrix_conv, complex_matrix_conv, string_conv):
+	Use it to declare these functions.
+
+	* ops.h (CONVDECL, INSTALL_WIDENOP):
+	Prefix function name with `oct_conv_'.
+	(INSTALL_BINOP, BINOPDECL): Prefix function name with `oct_binop_'.
+	(INSTALL_ASSIGNOP, INSTALL_ASSIGNANYOP, ASSIGNOPDECL):
+	Prefix function name with `oct_assignop_'.
+	(UNOPDECL, DEFNCUNOP_METHOD, INSTALL_UNOP, INSTALL_NCUNOP):
+	Prefix function name with `oct_unop_'.
+
+	* ov-str-mat.cc (default_numeric_conversion_function):
+	Return 0 if conversion fails.
+
+	* parse.y (make_prefix_op, make_postfix_op): Use
+	octave_value::unary_op enum.
+	
+	* pt-unop.cc (tree_prefix_expression::rvalue): Use new unary_op
+	functions from octave_value and octave_lvalue classes.
+	(tree_prefix_expression::rvalue): Likewise.
+
+	* pt-unop.cc (tree_unary_expression::oper): Move here.
+	(tree_prefix_expression::oper, tree_postfix_expression): From here.
+
+	* pt-unop.h (tree_prefix_expression, tree_postfix_expression):
+	Delete enums.
+	(tree_unary_expression): Use octave_value::unary_op enum.
+	* parse.y (make_prefix_op, make_postfix_op): Likewise.
+	
+	* oct-lvalue.h (octave_lvalue::do_unary_op): New function.
+	(octave_lvalue::increment, octave_lvalue::decrement): Delete.
+
+	* ov-typeinfo.h (octave_value_typeinfo::non_const_unary_ops):
+	New data member.
+	* ov-typeinfo.h (octave_value_typeinfo::lookup_non_const_unary_op):
+	New function.
+	* ov-typeinfo.cc (octave_value_typeinfo::register_non_const_unary_op):
+	New function.
+	(octave_value_typeinfo::do_register_non_const_unary_op): Ditto.
+	(octave_value_typeinfo::do_lookup_non_const_unary_op): Ditto.
+
+	* ov.cc (octave_value::do_non_const_unary_op): New function.
+
+	* Makefile.in (OP_XSRC): Add op-chm.cc and op-range.cc to the list.
+
+	* OPERATORS/op-str-str.cc: Define string matrix unary operators here.
+	(install_str_str_ops): Install them here.
+	* ov-bool-mat.h (octave_bool_matrix::transpose,
+	octave_bool_matrix_value::hermitian): Delete.
+
+	* OPERATORS/op-chm.cc: New file.  Define char matrix unary operators.
+	(install_chm_ops): Install them here.
+	* ov-ch-mat.h (octave_char_matrix::transpose,
+	octave_char_matrix_value::hermitian): Delete.
+	* ops.cc (install_ops): Call install_chm_ops.
+
+	* OPERATORS/op-bm-bm.cc: Define bool matrix unary operators here.
+	(install_bm_bm_ops): Install them here.
+	* ov-bool-mat.h (octave_bool_matrix::transpose,
+	octave_bool_matrix_value::hermitian): Delete.
+
+	* ov-bool.h (octave_bool::not, octave_bool::uminus,
+	octave_bool::transpose, octave_bool::hermitian): Delete.
+
+	* OPERATORS/op-cs-cs.cc: Define complex scalar unary operators here.
+	(install_cs_cs_ops): Install them here.
+	* ov-complex.h (octave_complex::not, octave_complex::uminus,
+	octave_complex::transpose, octave_complex::hermitian): Delete.
+
+	* OPERATORS/op-cm-cm.cc: Define complex matrix unary operators here.
+	(install_cm_cm_ops): Install them here.
+	* ov-cx-mat.h (octave_complex_matrix::not,
+	octave_complex_matrix::uminus, octave_complex_matrix::transpose,
+ 	octave_complex_matrix::hermitian): Delete.
+
+	* OPERATORS/op-m-m.cc: Define matrix unary operators here.
+	(install_m_m_ops): Install them here.
+	* ov-re-mat.h (octave_matrix::not, octave_matrix::uminus,
+	octave_matrix::transpose, octave_matrix::hermitian): Delete.
+
+	* OPERATORS/op-range.cc: New file.  Define range unary operators.
+	(install_range_ops): Install them here.
+	* ov-range.h (octave_range::not, octave_range::uminus,
+	octave_range::transpose, octave_range::hermitian): Delete.
+	* ops.cc (install_ops): Call install_range_ops.
+
+	* OPERATORS/op-s-s.cc: Define scalar unary operators here.
+	(install_s_s_ops): Install them here.
+	* ov-scalar.h (octave_scalar::not, octave_scalar::uminus,
+	octave_scalar::transpose, octave_scalar::hermitian): Delete.
+
+	* ops.h (INSTALL_UNOP, CAST_UNOP_ARG, UNOPDECL, DEFUNOPX, DEFUNOP,
+	DEFUNOP_OP, DEFUNOP_FN): New macros.
+
+	* ov.h (unary_op_fcn): New typedef.
+	(octave_value::unary_op): New enum.
+	* ov.cc (octave_value::octave_value): New function.
+
+	* ov.h (octave_value::not, octave_value::uminus,
+	octave_value::transpose, octave_value::hermitian,
+	octave_value::increment, octave_value::decrement): Delete.
+
+	* ov-base.cc (octave_base_value::not, octave_base_value::uminus,
+	octave_base_value::transpose, octave_base_value::hermitian,
+	octave_base_value::increment, octave_base_value::decrement): Delete.
+	
+	* ov.cc (gripe_unary_op): New function.
+	(do_unary_op): New function.
+	* ov-typeinfo.h (octave_value_typeinfo::unary_ops):
+	New data member.
+	* ov-typeinfo.cc (octave_value_info::register_unary_op,
+	octave_value_info::do_register_unary_op,
+	octave_value_info::lookup_unary_op,
+	octave_value_info::do_lookup_unary_op):
+	New functions.
+
+	* ov-list.cc (Fsplice): Use new octave_value::int_value function here.
+	(octave_list::do_index_op): Likewise.
+	(octave_list::assign): Likewise.
+	* toplev.cc (Fquit): Likewise.
+	* syscalls.cc (Fwaitpid): Likewise.
+	(Ffcntl): Likewise.
+	* file-io.cc (do_fread): Likewise.
+	(do_fwrite): Likewise.
+	* data.cc (make_diag): Likewise.
+	(Fsize): Likewise.
+	(get_dimensions): Likewise.
+	(Flinspace): 
+
+	* ov-base.cc (octave_base_value::int_value): New function.
+	(octave_base_value::nint_value): Ditto.
+	* ov.h (octave_value::int_value): Ditto.
+	(octave_value::nint_value): Ditto.
+
+	* ov-list.cc (octave_list::assign): Fix off-by-one error.
+
+Wed Oct 28 11:01:37 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_mat_ascii_data): Try harder to convert file
+	name to valid variable name.
+
+	* data.cc (Fisempty, Fis_matrix): New functions.
+
+	* ov-str-mat.h (octave_char_matrix_str::is_matrix_type): New function.
+
+	* OPERATORS/op-list.cc: New file.
+	* Makefile.in (OP_XSRC): Add it to the list.
+
+	* ov-list.cc (octave_list::assign): New function.
+
+	* ov-typeinfo.h (octave_value_typeinfo::assignany_ops):
+	New data member.
+	* ov-typeinfo.cc (octave_value_info::register_assignany_op,
+	octave_value_info::do_register_assignany_op,
+	octave_value_info::lookup_assignany_op,
+	octave_value_info::do_lookup_assignany_op):
+	New functions.
+	* ov.cc (octave_value::try_assignment (octave_value::assign_op,
+	const octave_value_list&, const octave_value&)): If no assignment
+	operator for particular RHS type exists, try finding one for
+	generic octave_value as RHS type.
+	* ops.h (DEFASSIGNANYOP_FN): New macro.
+
+	* ov-list.cc (Fsplice): New function.
+	* oct-obj.cc (octave_value_list::splice): New function.
+
+	* ov.cc (Vresize_on_range_error): No longer static.
+	* ov.h (Vresize_on_range_error): Provide extern declaration.
+
+	* oct-procbuf.cc (symbols_of_oct_procbuf): Don't declare static.
+
+	* data.cc (Flength): New function.
+	* ov.h (octave_value::length): New virtual function.
+	* ov-base.cc (octave_base_value::length): New function.
+	(octave_base_value::rows, octave_base_value::columns): Move
+	definitions here, from ov-base.h.  Don't return -1.  Instead,
+	gripe about wrong argument type.
+	* ov-bool-mat.h (octave_bool_matrix::length): New function.
+	* ov-bool.h (octave_bool::length): Ditto.
+	* ov-ch-mat.h (octave_char_matrix::length): Ditto.
+	* ov-complex.h (octave_complex::length): Ditto.
+	* ov-cx-mat.h (octave_complex_matrix::length): Ditto.
+	* ov-list.h (octave_list::length): Ditto.
+	* ov-range.h (octave_range::length): Ditto.
+	* ov-re-mat.h (octave_matrix::length): Ditto.
+	* ov-scalar.h (octave_scalar::length): Ditto.
+
+Tue Oct 27 22:19:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-list.cc (octave_list::print_raw): Handle case of empty list.
+	(octave_list::print_name_tag): Likewise.	
+
+	* octave.cc (intern_argv): Built-in variable argv is now a list of
+	strings instead of a string vector.
+	Always bind argv, making it an empty list if there are no args.
+
+Mon Oct 26 08:41:46 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xdiv.cc (mx_leftdiv_conform): Explicitly declare args to be
+	passed as references to const objects.  Fix explicit instantiation
+	requests to match.
+	(mx_div_conform): Likewise.
+
+	* pt-unop.h (tree_prefix_expression): Reorder constructor args to
+	put those with default values last.
+	(tree_postfix_expression): Likewise.
+	* parse.y: Change all callers.	
+
+Fri Oct 23 12:07:32 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (Ffile_in_loadpath): New function.
+
+	* defaults.cc (Vload_path, Vdefault_load_path): Now static.
+
+	* help.cc (simple_help): Use Vload_path_dir_path here instead of
+	trying to reconstruct it from Vload_path.
+	* fn-cache.cc (octave_fcn_file_name_cache::do_list): Likewise.
+	(octave_fcn_file_name_cache::update): Likewise.
+
+	* defaults.cc (octave_loadpath): Construct Vload_path_dir_path
+	using Vdefault_load_path.
+	(set_default_path): Likewise.
+
+	* defaults.h, defaults.cc (maybe_add_default_load_path): Delete.
+
+	* defaults.cc (Vdefault_load_path): New static variable.
+	(set_default_path): Set it.
+	(maybe_add_default_load_path): Use it.
+	(symbols_of_defaults): Add DEFCONST for DEFAULT_LOADPATH.
+	Thanks to Rafael Laboissiere <rafael at icp.inpg.fr>.
+
+	* defaults.cc (set_default_path): If OCTAVE_PATH is set in the
+	environment, call maybe_add_default_load_path on it.
+
+Tue Oct 20 20:58:04 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (maybe_add_default_load_path): If LOADPATH contains
+	an embedded "::", insert the default path there too.
+
+Fri Oct 16 00:52:15 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (in_matrix_or_assign_lhs): New subroutine for lexical
+	feedback.
+	(matrix): Use it.
+	(assign_lhs): Ditto.
+	* lex.h (lexical_feedback::looking_at_matrix_or_assign_lhs): New
+	data member.
+	* lex.l (handle_identifier): Use it to handle keywords like `cd'
+	as variables in contexts like [ab, cd] = foo ().
+
+	* ov-str-mat.h
+	(octave_char_matrix_str::octave_char_matrix_str (char c)): 
+	New constructor.
+	* ov-ch-mat.h (octave_char_matrix::octave_char_matrix (char c)):
+ 	New constructor.
+	* ov.cc (octave_value::octave_value (char c): New constructor.
+
+	* pt-loop.cc (tree_simple_for_command::eval): Handle case of RHS
+	as string.
+
+Thu Oct 15 00:56:47 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/rand.cc: Declare Fortran subroutines as returning
+	int, not int*.
+
+Wed Oct 14 23:51:31 1998  Georg Thimm  <thimm at idiap.ch>
+
+	* load-save.cc (Vcrash_dumps_octave_core): New static variable.
+	(save_user_variables): Only save variables if
+	Vcrash_dumps_octave_core is true.
+	(symbols_of_load_save): Add DEFVAR for it here.
+	(crash_dumps_octave_core): New function.
+	* octave.cc (maximum_braindamage): Bind crash_dumps_octave_core to
+	0.0 here.
+
+Tue Oct 13 22:05:55 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (read_readline_init_file): New function.
+
+Thu Oct  8 13:47:55 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-procbuf.h (octave_procbuf::wstatus): New data member.
+	Initialize in constructors.
+	(octave_procbuf::wait_status): New member function.
+	* oct-procbuf.cc (octave_procbuf::sys_close): Use class data
+	member wstatus, not local variable.
+	* procstream.cc (procstreambase::close): Don't call sys_close directly.
+	Get subprocess exit status by calling wait_status for our procbuf.
+	* pt-plot.cc (close_plot_stream): Send "quit" command to gnuplot
+	before deleting plot_stream.
+
+
+Thu Oct  1 22:39:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fis_complex): New function.
+
+Fri Sep 25 11:50:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (write_header): Rename from write_binary_header.
+	Also write header for Octave ASCII files.
+
+	* load-save.cc (Fsave): Implement -append option.
+
+	* defaults.cc (Frehash): New function.
+
+Fri Sep 25 11:50:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (help_from_info): Improve error message in case that
+	info doesn't work.
+
+Thu Sep 24 10:48:12 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DLD_XSRC): Replace qzval.cc with qz.cc
+
+	* DLD-FUNCTIONS/balance.cc: Update from A. S. Hodel
+	<scotte at eng.auburn.edu>.
+
+	* DLD-FUNCTIONS/qz.cc: New file.
+
+	* DLD-FUNCTIONS/qzval.cc: Delete.
+
+	* parse.y (plot_command1): Don't allow it to be empty.
+	(plot_command): Handle simple `PLOT' and `PLOT ranges' as special
+	cases here.
+
+Wed Sep 23 21:10:08 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l: Change <MATRIX>{SNLCMT}*\n{SNLCMT}* pattern
+	to <MATRIX>{S}*{COMMENT}{SNLCMT}* | <MATRIX>{S}*{NL}{SNLCMT}*.
+
+Fri Sep  4 10:50:00 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ffwrite): Fix doc string.
+
+Wed Sep  2 16:22:23 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (match_sans_spaces): Make it work.
+
+	* toplev.cc (quit): Require nargout == 0.
+
+	* input.cc (get_user_input): Only try matching "exit", "quit", and
+	"return" if debugging.
+
+Tue Sep  1 12:50:24 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc: Use -H as single character equivalent of --no-history.
+
+Sat Aug 29 12:23:12 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-obj.cc (octave_value_list::make_argv): If some values are
+	string vectors, insert all the elements, not just the first.
+
+Tue Aug 18 16:39:50 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_gets): Accept last line of
+	file even if it doesn't end in a newline character.
+
+Tue Aug 18 16:25:49 1998  Mumit Khan  <khan at xraylith.wisc.edu>
+
+	* xdiv.cc (mx_leftdiv_conform, mx_div_conform): Instantiate correct
+	templates.
+
+Thu Jul 30 00:37:43 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-loop.cc (tree_for_command::eval): Check for range first.
+	If error occurs when extracting matrix value, return early.
+	Don't bother to check for string type.
+
+	* ov-ch-mat.h (octave_char_matrix::is_real_matrix): New function.
+
+Tue Jun 23 15:09:54 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (clear_current_script_file_name): New function.
+	(parse_fcn_file): Bind current_script_file_name while script is
+	executing.  Use unwind_protect to clear it once the script is
+	finished.
+
+	* pt-plot.cc (Fgraw): New function.
+
+Mon Jun 22 22:13:38 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (is_valid_function): Provide version that takes
+	function name as string.
+
+	* parse.y (binary_expr): Fix thinko that resulted in incorrect
+	evaluation of -x^y.  Thanks to Richard Allan Holcombe
+	<raholcom at unity.ncsu.edu>.
+	(feval): Don't attempt to copy nonexistent arg names.
+
+Mon Jun 22 21:35:50 1998  Richard Allan Holcombe  <raholcom at unity.ncsu.edu>
+
+	* xpow.cc (xpow): Improve efficiency for matrix^(scalar int) case.
+
+Thu Jun  4 12:42:46 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.cc (octave_user_function::octave_all_va_args): 
+	If num_args_passed < num_named_args, create zero length list.
+
+Thu May 14 16:23:15 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/getrusage.cc: Include sys/types.h too.
+
+Mon May 11 00:38:45 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pager.cc (Fdiary): Don't forget to set write_to_diary file if
+	just given a file name.
+
+	* input.cc (octave_gets): Only send new line character to
+	octave_diary if current_input_line is empty or doesn't already end
+	with a new line character..
+	Don't send input from function files or	scripts to octave_diary.
+
+Sun May  3 19:54:38 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (reset_parser): Also call yyrestart if forced_interactive
+	is true, but not if input_from_startup_file is true.
+
+Tue Apr 28 14:06:20 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-procbuf.cc (Vkluge_procbuf_delay): New static variable.
+	(kluge_procbuf_delay): New function.
+	(symbols_of_oct_procbuf): New function.
+	(octave_procbuf::open): Delay Vkluge_procbuf_delay microseconds
+	after forking.
+
+Thu Apr 23 15:41:08 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (Vload_path_dir_path): New variable.
+	* utils.cc (file_in_path): Use it.
+
+	* utils.cc (search_path_for_file): Undo previous change.
+	(file_in_path): Undo previous change.
+	* defaults.cc (loadpath): Undo previous change.  Tilde expansion
+	is once again handled correctly by the code in
+	liboctave/pathsearch.cc.
+
+Mon Apr 20 21:50:34 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (get_dimensions): Allow zeros ([], 3) to work, for
+	compatibility with Matlab.
+
+	* dynamic-ld.cc [WITH_DL && ! HAVE_DLFCN_H]: Add declarations for
+	dlopen, dlerror, dlsym, and dlclose.
+
+	* octave.gperf: Handle __FILE__ and __LINE__.
+	* lex.l (is_keyword): Likewise.
+	* Makefile.in (oct-gperf.h): Pass -D option to gperf.
+	Postprocess output of gperf to convert name of static variable
+	from lookup to gperf_lookup, to avoid conflict with our	function
+	of the same name defined in variables.cc.
+
+Sat Apr 18 20:17:10 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (USE_GNU_INFO): Delete uses of this macro.
+
+Thu Apr 16 01:00:12 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc: Only include dlfcn.h if HAVE_DLFCN_H.
+
+Wed Apr 15 01:03:05 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (Vlast_prompt_time): New global variable.
+	(octave_gets): Set it.
+	* ov-fcn.h (octave_function::time_checked): New virtual function
+	(octave_function::mark_fcn_file_up_to_date): Ditto.
+	* ov-usr-fcn.h (octave_user_function::time_checked): New function.
+	(octave_user_function::mark_fcn_file_up_to_date): Ditto.
+	(octave_user_function::t_checked): New data member.
+	* variables.cc (symbol_out_of_date): Only check file time stamp if
+	a prompt has been printed since the last time check.
+
+	* pt-plot.h, pt-plot.cc (subplot_axes): New class.
+	(subplot): Handle axes.
+	(Vgnuplot_command_axes): New static variable.
+	(gnuplot_command_axes): New function.
+	(symbols_of_pt_plot): DEFVAR gnuplot_command_axes.
+	* pt-walk.h (tree_walker::visit_subplot_axes): New virtual function.
+	* parse.y (plot_options): Handle axes.
+	* lex.l (plot_axes_token): New function.
+	(is_keyword): Use it.
+	(is_plot_keyword): Recognize "axes" and "axis".
+	* lex.h (class lexical_feedback): New field, in_plot_axes.
+	(lexical_feedback::init): Reset it.
+
+Tue Apr 14 23:32:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (parse_fcn_file): New arg, force_script.  Change callers.
+
+Fri Apr 10 11:01:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (type): Also print values of variables.
+
+Wed Apr  8 01:00:58 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (set_format): Set scale to 1.0 if all elements are
+	int or inf or nan.
+
+	* parse.y (Vwarn_future_time_stamp): New variable.
+	(symbols_of_parse): Add DEFVAR for it.
+	(warn_future_time_stamp): New function.
+	(frob_function_def): Maybe warn about files with future time stamps.
+
+Thu Apr  2 20:43:45 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-arg-list.cc (tree_argument_list::convert_to_const_vector): In
+	error messages, print element numbers starting with 1, not 0.
+
+Sat Mar 28 15:25:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (clean_up_for_exit): New function.
+	(clean_up_and_exit): Use it.
+	* sighandlers.cc (my_friendly_exit): Call it instead of
+	clean_up_and_exit, then do default action for signal.
+
+	* sighandlers.cc (octave_new_handler): Call my_friendly_exit with
+	signal set to SIGABRT if it is defined, or -1 otherwise.
+
+	* error.cc (verror): Fix thinko in attempt to skip `error: ' tag
+	when buffering error messages.
+	* pt-except.cc (tree_try_catch::eval): Reset buffer_error_messages
+	here if	just discarding unwind_protect frame.
+
+Wed Mar 18 12:35:18 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xpow.cc (elem_xpow): For real-scalar .^ matrix case, result is
+	complex only if real-scalar is negative and matrix has some
+	non-integer values.
+
+Tue Mar 17 17:47:50 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (Vgnuplot_command_plot, Vgnuplot_command_replot,
+	Vgnuplot_command_splot, Vgnuplot_command_using,
+	Vgnuplot_command_with, Vgnuplot_command_title,
+	Vgnuplot_command_end): New static variables.
+	(symbols_of_pt_plot): DEFVAR them.
+	(gnuplot_command_plot, gnuplot_command_replot,
+	gnuplot_command_splot, gnuplot_command_using,
+	gnuplot_command_with, gnuplot_command_title,
+	gnuplot_command_end): New functions.
+	(open_plot_stream, send_to_plot_stream, tree_plot_command::eval,
+	subplot_using::print, subplot_style::print, subplot::print, 
+	do_external_plotter_cd, Fgset, Fgshow): Use them instead of the
+	GPLOT_CMD_PLOT, GPLOT_CMD_REPLOT, GPLOT_CMD_SPLOT,
+	GPLOT_CMD_USING, GPLOT_CMD_WITH, GPLOT_CMD_TITLE, and
+	GPLOT_CMD_END macros.
+
+Fri Feb 27 12:25:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (additional_help_message): Fix www address.
+
+Tue Feb 24 00:42:59 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (simple_help): Put additional help message first.
+  	(additional_help_message): Add information about web site and
+	mailing list.
+
+Fri Feb 20 00:41:06 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (GPLOT_CMD_REPLOT): Clear before replot.
+
+	* Makefile.in: Better handling of lib flags for linking.
+
+Thu Feb 19 21:14:30 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-decl.cc (Vinitialize_global_values): New static variable.
+	(initialize_global_variables): New function.
+	(symbols_of_pt_decl): New function.
+	DEFVAR Vinitialize_global_values and initialize_global_variables.
+	(tree_global_command::do_init): If initialize_global_variables is
+	not true and the variable doesn't have an explicit initializer, don't
+	initialize it.  If we are giving it a default value, use the value
+	of the variable defualt_global_variable_value.
+	* octave.cc (maximum_braindamage): Set default_global_variable_value
+	and initialize_global_variables to Matlab-compatible values.
+
+Wed Feb 18 04:35:31 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/besselj.cc: Rename from bessel.cc.
+	* Makefile.in (DLD_XSRC): Likewise.
+
+	* syscalls.cc (Fvfork): Delete.
+
+	* oct-procbuf.cc: Just use fork.
+
+	* parse.y (feval): Provide version that takes function name
+	separate from other args.
+	* parse.h: Declare it.
+
+	* oct-procbuf.cc (octave_procbuf::open): Move declaration of
+	child_std_end outside of child scope and declare volatile.
+
+Mon Feb 16 15:04:28 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y: Include cstdio, for SEEK_SET.
+
+Thu Feb 12 22:07:00 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* system.c: New file.
+	* Makefile.in (SOURCES): Add it to the list.
+
+Fri Feb  6 01:23:18 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::file_number): Rename from fileno.
+	Change all uses.
+
+	* fsolve.cc (fsolve_option_table): Add missing & to function names.
+
+Thu Feb  5 02:27:18 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (Fls): If first attempt at reading process output
+	fails, sleep once and try again.
+	* toplev.cc (run_command_and_return_output): Likewise.
+
+	* oct-procbuf.cc (octave_procbuf::open): Use vfork if it is available.
+
+	* syscalls.cc (Fvfork): New function.
+
+	* ov-bool-mat.cc: Only declare assign function if
+	CXX_NEW_FRIEND_TEMPLATE_DECL is not defined.
+
+	* ov-base.h, ov-bool-mat.h, ov-bool.h, ov-ch-mat.h, ov-complex.h,
+	ov-cx-mat.h, ov-range.h, ov-re-mat.h, ov-scalar.h: Handle default
+	args for *_value functions consistently.
+
+	* symtab.cc (maybe_list_cmp_fcn): Declare args as void*, not
+	void**, then use X_CAST.
+
+	* OPERATORS/op-s-cm.cc: Include mx-cm-s.h.
+
+	* defun-int.h: Include ov-builtin.h, ov-mapper.h, and symtab.h.
+	(install_builtin_mapper, install_builtin_function,
+	install_builtin_variable) Use specific types rather than void * in
+	declaration.
+	* defun.cc (install_builtin_mapper, install_builtin_function,
+	install_builtin_variable): Likewise.  Eliminate casts.
+
+	* load-save.cc (read_binary_data, read_mat_file_header,
+	save_binary_data): Use X_CAST, not static_cast.
+	* unwind-prot.h (unwind_protect::save_ptr): Likewise.
+	* Map.cc (goodCHptr, index_to_CHptr, CHptr_to_index): Likewise.
+	* dynamic-ld.cc (octave_dlopen_dynamic_loder::resolve_reference):
+	Likewise.
+
+	* pt-mat.cc (tm_const::operator bool ()): 
+	(tm_row_const::operator bool ()): Likewise.
+	* oct-stream.cc (printf_value_cache::operator bool ()): Likewise.
+	(scanf_format_list::operator bool ()): Likewise.
+	(printf_format_list::operator bool ()): Likewise.
+	(octave_stream::operator bool ()): Likewise.
+
+Wed Feb  4 13:08:29 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/minmax.cc: Include cmath, not oct-math.h.
+
+	* syscalls.cc (Fdup2): Convert stream to actual system file id.
+
+	* oct-stream.cc (octave_base_stream::fileno, octave_stream::fileno): 
+	New functions.
+
+Tue Feb  3 00:24:44 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (exec_path): Append Vbin_dir to std_path.
+
+	* octave.cc (initialize_pathsearch): Set TEXMFDBS, not TEXMF.
+	Look for OCTAVE_DB_PATH in environment.
+	Simplify using Vdata_dir and Vlibexec_dir.
+
+	* defaults.h.in (Vdata_dir, Vlibexecdir): Declare new vars.
+	defaults.cc: Define them.
+	(set_default_data_dir, set_default_libexecdir): New functions.
+	(install_defaults): Call them.
+
+	* defaults.h.in (OCTAVE_LIBEXECDIR): Define.
+
+Mon Feb  2 02:43:16 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install, uninstall): Use $(octlibdir), not $(libdir).
+	Use mk-libdir-link.
+
+	* defaults.h.in (OCTAVE_OCTLIBDIR): Substitute value.
+	(Vlib_dir): Delete declaration.
+	* defaults.cc (Vlib_dir): Delete.
+	(set_default_lib_dir): Delete.
+	(install_defaults): Don't call set_default_lib_dir.
+	(set_default_info_prog): If oct_info_prog is empty, set default to
+	"info" -- we expect it to be somewhere in the user's path.
+
+	* defun.h (DEFCONST, DEFCONSTX): Eliminate inst_as_fcn and chg_fcn
+	args.  Always pass true for inst_as_fcn and 0 for chg_fcn to
+	DEFVAR when creating built-in values like `e' or `stderr' that can
+	be redefined.  Change all uses.
+
+	* help.cc (Ftype): Handle script files too.
+	(Fwhich): Likewise.
+
+Sat Jan 31 00:00:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-ch-mat.cc (octave_char_matrix::is_true): Make it work.
+	* ov-str-mat.h, ov-str-mat.cc (octave_char_matrix_str::is_true):
+	Delete.
+
+	* load-save.cc (read_ascii_data): Allow strings of length 0.
+	If we don't find data on the first call, fail with error message.
+	(do_load): Pass count of items read to read_ascii_data.
+	Allow `load foo xyz' to work when foo contains only numbers.
+
+Fri Jan 30 23:46:42 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-str-mat.h (octave_char_matrix_str::all): Delete.
+	(octave_char_matrix_str::any): Delete.
+	* ov-ch-mat.h (octave_char_matrix::all, octave_char_matrix::any):
+	Call charMatrix::all, charMatrix::any.
+
+Thu Jan 29 16:25:46 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_mat_binary_data): Handle third digit of MOPT
+	as flag indicating row or column major ordering.
+
+Wed Jan 28 00:18:17 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/dassl.cc (lsode_option_table):
+	Add missing & to function names.
+	* DLD-FUNCTIONS/lsode.cc (lsode_option_table): Likewise.
+	* DLD-FUNCTIONS/quad.cc (quad_option_table): Likewise.
+
+	* Makefile.in (oct-gperf.h): Add -G option to gperf.
+
+	* load-save.cc (get_save_type): Add `UL' and `L' suffixes to large
+	constant values.  For LS_INT, use <= and >= for comparison.
+
+Mon Jan 26 13:17:59 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-usr-fcn.cc (Vmax_recursion_depth): New static variable.
+	(max_recursion_depth): New fucnction
+	(symbols_of_ov_usr_fcn): DEFVAR max_recursion_depth.
+	(octave_user_function::do_index_op): Check Vmax_recursion_depth.
+
+Thu Jan 22 13:45:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc (make_dynamic_loader): Fix typo.
+
+Tue Jan 20 17:02:19 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fexist): If local symbol is undefined, check
+	global table.
+
+	* pr-output.cc (pr_max_internal): Initial value for result is
+	-DBL_MAX, not DBL_MIN.
+
+Thu Jan  8 11:54:33 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xpow.cc (elem_xpow): If second arg of pow is complex, make sure
+	first arg is also complex.
+
+	* symtab.cc (symbol_table::rename): Properly insert new item at
+	the front of the list to avoid losing the rest of the items.
+
+Thu Dec 11 23:30:03 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fclear): Increment index to skip -x arg.
+
+Tue Dec  9 02:45:35 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES): Don't forget Pix.h.
+
+	* BaseSLList.cc: Don't include nonstandard libg++ header files.
+
+Sun Nov 30 14:58:56 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc: Include cmath, not oct-math.
+	* sysdep.cc: Likewise.
+
+	* DLD-FUNCTIONS/bessel.cc: New file.
+	* Makefile.in (DLD_XSRC): Add it to the list.
+
+Thu Nov 27 23:28:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_string): Constructor for string class takes
+	(size_t, char) args, not (char, size_t).
+
+Wed Nov 26 00:39:34 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCTAVE_LIBS): Include $(SPECIAL_MATH_LIB) just
+	ahead of -lcruft.
+
+Thu Nov 20 15:16:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (maximum_braindamage): Bind implicit_num_to_str_ok to 1.
+	* pt-mat.cc (Vimplicit_num_to_str_ok): New static variable.
+	(implicit_num_to_str_ok): New function.
+	(symbols_of_pt_mat): DEFVAR implicit_num_to_str_ok.
+	(tm_row_const::some_str): New data member.
+	(tm_row_const::some_strings_p): New function.
+	(tm_row_const::init): Set some_str.
+	(tm_const::some_str): New data member.
+	(tm_const::some_strings_p): New function.
+	(tm_const::init): Set some_str.
+	(tree_matrix::eval): If Vimplicit_num_to_str_ok is true and some
+	of the elements are strings, force a string conversion before
+	returning.
+
+	* parse.y (fold, finish_colon_expression, finish_matrix):
+	If an error occurs, return the original expression.
+	Use unwind_protect to restore error_state.
+
+	* ov-ch-mat.h (octave_char_matrix::convert_to_str): Result is
+	char_matrix_str, not just char_matrix.
+
+Wed Nov 19 02:05:40 1997  Mumit Khan  <khan at dhaka.xraylith.wisc.edu>
+
+	* DLD-FUNCTIONS/filter.cc: Don't include extern template decls if
+	CXX_NEW_FRIEND_TEMPLATE_DECL is defined.
+	* ov-cx-mat.cc: Likewise.
+	* ov-re-mat.cc: Likewise.
+	* ov-str-mat.cc: Likewise.
+
+	* ov-cx-mat.h (octave_complex_matrix::decrement,
+	octave_complex_matrix):	Use explicit Complex constructor.
+
+Wed Nov 19 00:08:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-decl.cc (tree_global_command::do_init): Initialize global
+	values to `[]'.  Only perform explicit initialization once.
+
+Tue Nov 18 04:27:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (Vfixed_point_format): New variable.
+	(fixed_point_format): New fucntion.
+	(symbols_of_pr_output): Add DEFVAR for fixed_point_format.
+	(set_real_matrix_format): Handle fixed point format
+	(set_complex_matrix_format): Handle fixed point format
+	(set_format): New arg, scale in Matrix, ComplexMatrix, Range versions.
+	(pr_scale_header): New function.
+	(octave_print_internal): Handle fixed point format in Matrix,
+	ComplexMatrix, and Range versions.
+	* octave.cc (maximum_braindamage): Set fixed_point_format to 1.0.
+
+	* utils.cc (do_string_escapes): Move here, from lex.l.
+	Arg is now const string& instead of char*.
+	Return new string object instead of modifying arg in place.
+	(Fdo_string_escapes): New function.
+	* lex.l (handle_string): Use new version of do_string_escapes.
+
+	* lex.l (Vbackslash_escapes): Delete.
+	(backslash_escapes): Delete.
+	(do_string_escapes): Undo previous change.
+	(eat_whitespace, eat_continuation): Undo previous change.
+	(handle_string): Undo previous change.
+	(symbols_of_lex): Undo previous change.
+	* octave.cc (maximum_braindamage): Undo previous change.
+
+Fri Nov 14 01:53:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (eval_string (const string&, bool, int&, int)): No
+	longer static.
+	* parse.h: Provide declaration.
+	* input.cc (get_user_input (const octave_value_list&, bool, int)):
+	New arg, nargout.  Pass it to eval_string.
+	(keyboard): Pass nargout = 0 to get_user_input.
+	(input): Pass nargout to get_user_input.
+
+	* input.cc (get_user_input (const octave_value_list&, bool)):
+	Return octave_value_list() if user enters `quit', `exit', or `return'.
+	If debugging, let eval_string handle the printing chores and
+	reset error_state before asking for more input.
+
+	* input.cc (Fkeyboard): Unconditionally turn on history here.
+
+	* lex.l (have_continuation, have_ellipsis_continuation): Declare
+	arg as bool, not int.  Change callers.
+
+	* lex.l (Vbackslash_escapes): New static variable.
+	(backslash_escapes): New function.
+	(do_string_escapes): Return immediately if ! Vbackslash_escapes.
+	(eat_whitespace, eat_continuation): Only call have_continuation if
+	Vbackslash_escapes.
+	(handle_string): Backslash is only special if Vbackslash_escapes.
+	(symbols_of_lex): Add DEFVAR for backslash_escapes.
+	* octave.cc (maximum_braindamage): Set backslash_escapes to 0.
+
+Thu Nov 13 16:20:40 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fexist): Also return 2 if NAME is a regular file
+	somewhere in the LOADPATH.
+
+	* data.cc (sumsq): Fix doc string.
+
+	* parse.y (Fsource): Call parse_fcn_file, not parse_and_execute.
+
+Tue Oct  7 16:51:01 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun-int.h (DEFINE_FUN_INSTALLER_FUN): Set installed to true
+	after installing the function.
+
+Thu Sep 25 10:17:26 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/filter.cc (Ffilter): Return second output value
+	even when called with only 3 arguments.
+
+Mon Sep 22 16:44:27 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/rand.cc (do_rand): Print error if first of two
+	args is a string but doesn't match "seed".
+	(Frand, Frandn): Fix doc string.
+
+Mon Aug 25 10:42:07 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (get_user_input): Return an empty string if the user
+	just types RET.
+
+Thu Jul 31 22:59:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l <TEXT_FCN>: Ensure that we handle words that begin with
+	single or double quotes as strings.
+
+Thu Jul 17 13:06:48 1997  Klaus Gebhardt  <gebhardt at crunch.ikp.physik.th-darmstadt.de>
+
+	* DLD-FUNCTIONS/rand.cc (Frand): Use F77_XFCN to call getsd,
+	setsd, setall, setcgn, dgenunf, and dgennor since they can call
+	XSTOPX.
+
+Mon Jul 14 12:54:23 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc (octave_dynamic_loader::load_fcn_from_dot_oct_file):
+	If first attempt to load function fails, prepend and underscore
+	and try again.
+
+	* Makefile.in (install-inc): If defaults.h, oct-conf.h, or
+	oct-gperf.h don't exist in the current directory, look in $(srcdir).
+
+Mon Jul  7 21:14:07 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/qr.cc (Fqr): Correctly handle nargout == 0. 
+
+Wed Jul  2 16:47:09 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* matherr.c: New file.  Move matherr function here.
+	* sysdep.cc: From here.
+	* Makefile.in (DIST_SRC): Add matherr.c to the list.
+
+	* error.cc (handle_message): Avoid bug in g++ snapshot.
+
+Thu Jun 26 22:04:09 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (file_in_path): Add default load path to PATH arg if
+	it begins or ends with a colon.
+
+Wed Jun 25 13:31:06 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-lvalue.h (octave_lvalue::struct_elt_ref): Ensure val is unique.
+
+Fri Jun 20 12:33:35 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (cmd_death_handler): New function.
+	(run_command_and_return_output): Insert pid of command in
+	octave_child_list along with pointer to cmd_death_handler so we
+	can get the exit status without having to block SIGCHLD.
+	(cleanup_iprocstream): Remove pid of command from octave_child_list.
+
+Sun Jun 15 16:11:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* OPERATORS/op-cs-s.cc (ldiv): Doh, v1 is complex, v2 is real.
+
+	* Makefile.in (DISTFILES): Add mkops to the list.
+	(dist): Correctly link files in DLD-FUNCTIONS, OPERATORS, and
+	TEMPLATE-INST subdirectories.
+
+Fri Jun  6 04:30:57 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/npsol.cc, DLD-FUNCTIONS/qpsol.cc,
+	DLD-FUNCTIONS/fsqp.cc: Delete.
+	* Makefile.in (DLD_XSRC): Remove them from the list.
+
+	* utils.cc (search_path_for_file): New arg, do_tilde_expansion.
+	If TRUE, perform tilde expansion on path before searching.
+	(file_in_path): Call search_path_for_file with do_tilde_expansion
+	set to false, since we've already performed tilde expansion on the
+	load path.
+
+	* defaults.cc (loadpath): Perform tilde expansion here.
+
+Thu Jun  5 01:42:39 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Make building of static library optional.
+	(liboctave.$(SHLEXT_VER)): Add $(SONAME_FLAGS) to command.
+
+	* dynamic-ld.cc (octave_shl_load_dynamic_loader::resolve_reference): 
+	Call shl_findsym with type set to TYPE_UNDEFINED.
+
+	* Makefile.in (stamp-picdir): Delete.
+	(pic): New target.  Don't worry so much about creating pic
+	directory only when it is really needed.
+	(stamp-interp): Delete.
+	(libraries): New target.  Depend on shared library directly.
+
+Wed Jun  4 00:09:42 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (main): Call dir_path::set_program_name here.
+
+Tue Jun  3 16:47:34 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (symbol_out_of_date): Make it work again.
+
+	* parse.y (parse_and_execute): Move here from toplev.cc
+	(default_eval_print_flag): Likewise.
+	(safe_fclose): Likewise.
+	(eval_string): Likewise.
+	(Fsource): Likewise.
+	(Ffeval): Likewise.
+	(feval): Likewise.
+	(Feval): Likewise.
+	(symbols_of_parse): Define default_eval_print_flag here instead of
+	in varaibles.cc.
+	(looks_like_octave_copyright): Move here from variables.cc
+	(gobble_leading_whitespace): Likeiwse.
+	(is_function_file): Likewise.
+	(restore_input_stream): Likewise.
+	(parse_fcn_file): Likewise.
+	(load_fcn_from_file): Likewise.
+	(get_help_from_file): Likewise.
+
+	* toplev.cc (syms_of_toplev): Define argv, program_name, and
+	program_invocation_name here instead of in variables.cc.
+
+	* parse.h (line_editing): Move here from toplev.h.  Now bool, not int.
+	(reading_startup_message_printed) Likewise.
+	(input_from_startup_file): Likewise.
+	(input_from_command_line_file): Likewise.
+
+	* load-save.cc: Use bool instead of int where appropriate.
+
+	* input.h (enum echo_state): Move here from variables.h.
+	(Vecho_executing_commands): Likewise.  Now bool, not int.
+	* input.cc (echo_executing_commands): Move here from variables.cc.
+	(symbols_of_input): Define echo_executing_commands here instead of
+	in variables.cc.
+
+	* octave.cc (program_invocation_name): Don't define.
+	(intern_argv): Don't set program_invocation_name here.
+	(main): Call octave_env::set_program_name here, not in intern_argv.
+
+	* toplev.cc (quitting_gracefully): Move here from octave.h and
+	make static bool instead of extern int.
+
+	* error.cc (bind_global_error_variable, clear_global_error_variable):
+	Move here from variables.cc.
+	(symbols_of_error): Define error_text here instead of in variables.cc.
+
+	* pager.cc (write_to_diary_file): Now bool, not int.
+	(really_flush_to_pager): Likewise.
+ 	(flushing_to_pager): Likewise.
+	* sighandlers.h (can_interrupt): Likewise.
+	* error.h (buffer_error_messages): Likewise.
+	* oct-hist.h (input_from_tmp_history_file, Vsaving_history): Likewise.
+	* input.h (forced_interactive): Likewise.
+	(get_input_from_eval_string): Likeiwse.
+	(reading_script_file): Likeiwse.
+	(reading_fcn_file): Likeiwse.
+	(interactive): Likewise.
+
+	* unwind-prot.cc (saved_variable::saved_variable (bool *, bool)):
+	Set type_tag to boolean, not int. 
+
+Mon Jun  2 00:40:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.h (Octave_builtin_fcn): Delete typedef.
+
+	* help.cc (make_name_list): Move here from variables.cc.
+	(keyword_help, names): Now static.
+	(struct help_list): Move declaration here from help.h.
+
+	* oct-hist.cc (Vhistory_file, Vhistory_size, Vsaving_history):
+	Move here from variables.cc.
+	(symbols_of_oct_hist): New function.
+
+	* version.h: Protect against multiple inclusion.
+
+	* defun.cc (check_version): New function.
+	* defun-int.h (DEFINE_FUN_INSTALLER_FUN): Use it.
+
+	* help.h, help.cc (additional_help_message): Now extern.
+	(operator_help): Now static. 
+
+	* defun.cc (print_usage): Move here from help.cc
+	* DLD-FUNCTIONS/*.cc, data.cc, dirfns.cc, file-io.cc, input.cc,
+	load-save.cc, octave.cc, ov-list.cc, ov-typeinfo.cc,
+	ov-usr-fcn.cc, pager.cc, pr-output.cc, pt-plot.cc, strfns.cc,
+	syscalls.cc, sysdep.cc, utils.cc, toplev.cc:
+	Don't include help.h.
+
+	* TEMPLATE-INST/Array-sym.cc: New file.
+
+	* load-save.cc (do_load): Don't use ostream::form.
+	* pr-output.cc: Likewise, at least where it is easy to do so.
+	* oct-stream.cc: Ditto.
+
+	* symtab.h (symbol_record::symbol_def::rows): New function.
+	(symbol_record::symbol_def::columns): Ditto.
+	(symbol_record::symbol_def::type_name): Ditto.
+	(symbol_record::rows): Ditto
+	(symbol_record::columns): Ditto
+	(symbol_record::type_name): Ditto
+
+	* symtab.h, symtab.cc (symbol_record::hides_fcn): New function.
+	(symbol_record::hides_builtin): Ditto.
+	(symbol_record::print_symbol_info_line): Ditto.
+	(symbol_table::long_list): Delete.
+	(symbol_table::symbol_list): New function.
+	(symbol_table::maybe_list): Delete argc arg.
+	(symbol_table::name_list): Rename from symbol_table::list.
+	Change all callers.
+
+	* symtab.h, symtab.cc (class symbol_record_info): Delete.
+
+	* symtab.cc (matches_patterns): Use vector form of glob_match.
+
+Sun Jun  1 14:04:26 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-check.h, pt-check.cc: New files, for semantic checking of
+	parse trees.
+
+	* symtab.h (class symbol_def): Now nested in symbol_record class.
+	(enum TYPE): Move from symbol_def to symbol record class.  Change
+	all uses.
+
+	* symtab.h, symtab.cc (symbol_table::maybe_list): New function,
+	from variables.cc.  Change all uses.
+
+	* pt-idx.h (tree_identifier::lvalue_ok): New function.
+	* pt-id.h (tree_index_expression::lvalue_ok): Likewise.
+	* pt-indir.h (tree_indirect_ref::lvalue_ok): Likewise.
+
+	* pt-pr-code.h, pt-pr-code.cc (tree_print_code::visit_oct_obj): Delete.
+	* pt-walk.h (tree_walker::visit_oct_obj): Delete declaration.
+
+	* lex.h (class lexical_feedback): Delete maybe_screwed_again.
+	* lex.l (lexical_feedback::init): Don't set it.
+
+Fri May 30 16:07:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mappers.cc: Include <cfloat> here.
+
+Tue May 27 10:08:43 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (eval_string): Don't index tmp if it is empty.
+
+Sat May 24 00:18:41 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (valid_identifier): Move here and make static.
+	* symtab.h, symtab.cc (valid_identifier): Delete declaration and
+	definition.
+
+Fri May 23 22:54:28 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* symtab.h (symbol_def::symbol_def): Use initializer list instead
+	of calling init_state.
+	(symbol_def::init_state): Delete.
+
+	* symtab.cc (symbol_table::print_stats): New function.
+	* variables.cc (F__dump_symtab_info__): New function.
+
+	* symtab.h, symtab.cc (symbol_table::hash): Return masked value.
+	(symbol_table::table_size): New data member.
+	(symbol_table::symbol_table): Set size of table in constructor.
+	(HASH_TABLE_SIZE): Replace uses with table_size.
+	(HASH_MASK): Delete.
+	* variables.cc (initialize_symbol_tables): Set top-level and
+	global symbol table sizes here.
+
+Thu May 22 13:32:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc (octave_shl_load_dynamic_loader::resolve_reference): 
+	Call shl_findsym with type set to TYPE_PROCEDURE.  Pass the
+	address of the pointer we want to define.
+
+Wed May 21 16:30:25 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/time.cc (extract_tm): Avoid memory leak in dealing
+	with time zone.
+
+	* Makefile.in (install-in): Use new mk-includedir-link macro.
+	(install-lib): Install in $octlibdir.  Use new mk-libdir-link macro.
+
+Tue May 20 01:24:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-list.cc (Flist): Rename from Fmake_list.
+
+Mon May 19 14:45:58 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (maximum_braindamage): Set default_eval_print_flag to 0.
+
+Sat May 17 16:32:23 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (set_default_editor): Default is now Emacs, not vi.
+
+Fri May 16 00:07:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-idx.cc (tree_index_expression::name): New function.
+
+	* pt.cc	(tree::str_print_code): New file, new convenience function.
+	* pt-arg-list.cc (tree_argument_list::get_arg_names): Use it.
+	* pt-assign.cc (tree_simple_assignment::rvalue): Likewise.
+	(tree_multi_assignment::rvalue): Likewise.
+
+	* pt-colon.h (tree_colon_expression::save_base): New data memmber.
+	(tree_colon_expression::preserve_base): New function.
+	* parse.y (finish_colon_expression): When converting to a simple
+	expression, be sure to delete the original colon expression but
+	not the base value.
+
+	* pt-mat.cc (tree_matrix::~tree_matrix): Actually do something.
+
+	* pt-all.h: New file.
+	* parse.y, lex.l, pt-pr-code.cc: Use it.
+
+	* pt.h: Rename from pt-base.h.
+
+	* All parse tree classes: Add private copy constructors and
+	assignment operators to prevent copying.
+
+	* pt-base.cc: Delete.
+
+	* unwind-prot.h, unwind-prot.cc: Make a bit more object-oriented.
+	Change all uses of unwind_protect stuff to match.
+
+	* pt-jump.h, pt-jump.cc (breaking, continuing, returning):
+	Make these flags static members of the corresponding class.
+	Change all uses.
+
+	* pt-assign.cc (tree_simple_assignment_expression::eval,
+	tree_multi_assignment_expression::eval): Clear lvalue index here.
+
+	* oct-lvalue.cc (octave_lvalue::assign): Don't clear index here.
+	* oct-lvalue.h (octave_lvalue::clear_index): New function.
+	(octave_lvalue::set_index): Rename from octave_lvalue::index.
+	Change all callers.
+
+Thu May 15 11:48:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-select.h, pt-select.cc (class tree_if_command_list,
+	class tree_if_clause, class tree_switch_case_list,
+	class tree_switch_case): Move here from pt-misc.h, pt-misc.cc.
+	* pt-decl.h, pt-decl.cc (class tree_decl_init_list,
+	class tree_decl_elt): Move here from pt-mist.h, pt-misc.cc
+
+	* pt-arg-list.h, pt-stmt.h: New files, extracted from pt-misc.h.
+	* pt-arg-list.cc, pt-stmt.cc: New files, extracted from pt-misc.cc.
+
+	* pt-decl.h, pt-except.h, pt-jump.h, pt-loop.h, pt-select.h:
+	New files, extraced from pt-cmd.h.
+	* pt-decl.cc, pt-except.cc, pt-jump.cc, pt-loop.cc, pt-select.cc:
+	New files, extraced from pt-cmd.cc.
+
+	* pt-unop.h, pt-binop.h, pt-colon.h, pt-idx.h, pt-assign.h:
+	New files, extracted from pt-exp.h
+	* pt-unop.cc, pt-binop.cc, pt-colon.cc, pt-idx.cc, pt-assign.cc:
+	New files, extracted from pt-exp.cc
+	* pt-exp.h, pt-exp.cc: Rename from pt-exp-base.h, pt-exp-base.cc.
+
+	* oct-lvalue.h: Rename from oct-var-ref.h.  Rename class from
+	octave_variable_reference to octave_lvalue.  Change all uses.
+	* oct-lvalue.cc: Rename from oct-var-ref.cc.
+
+	* variables.cc (bind_ans): Only bind ans and print result if value
+	is defined.
+
+	* defun.cc: New file.  Move functions for installing objects in
+	the symbol table here from variables.cc.
+
+	* oct-obj.h, oct-obj.cc: Add custom allocator, fwiw.
+
+	* toplev.cc (main_loop): Correctly increment command number.
+
+	* TEMPLATE-INST/SLList-tm.cc: Don't instantiate lists of pointers
+	to tree_matrix_row objects.
+	* TEMPLATE-INST/SLList-misc.cc: Do instantiate lists of pointers
+	to tree_argument_list objects.
+
+	* DLD-FUNCTIONS/dassl.cc: Update to use new octave_function
+	interface to user-supplied functions.
+	* DLD-FUNCTIONS/fsolve.cc: Likewise.
+	* DLD-FUNCTIONS/lsode.cc: Likewise.
+	* DLD-FUNCTIONS/npsol.cc: Likewise.
+	* DLD-FUNCTIONS/quad.cc: Likewise.
+
+	* dynamic-ld.h, dynamic-ld.cc (builtin_fcn_installer typedef):
+	Rename from builtin_fcn.
+	(octave_dynamic_loader::load_fcn_from_dot_oct_file):
+	Simplify by using new installer function defined by DEFUN_DLD.
+
+	* defun-dld.h (DEFUN_DLD): Use DEFINE_FUN_INSTALLER_FUN instead of
+	DEFINE_FUN_STRUCT_FUN.
+	* defun.h (DEFUN_MAPPER): Use DEFUN_MAPPER_INTERNAL.
+	* defun-int.h (DEFVAR_INTERNAL): Rename from DEFVAR_INT and move
+	here from defun.h.  Change all uses.
+	(DEFUN_MAPPER_INTERNAL): New macro.
+	(DEFINE_FUN_INSTALLER_FUN): New macro to define function that the
+	dynamic loader calls to do all the work of installing a new function.
+	(DEFINE_FUN_STRUCT_FUN): Delete.
+
+	* parse.y: Rewrite to handle more general expressions.
+	* lex.l: Corresponding changes.
+
+	* pt-walk.h, pt-pr-code.h, pt-pr-code.cc: Cope with new parse tree
+	object structure.
+
+	* pt-misc.cc (class tree_for_command): Split into
+	tree_simple_for_command and tree_complex_for_command classes.
+
+	* pt-misc.h, pt-misc.cc (tree_statement::eval): Handle identifier
+	lookup and printing and binding ans here.
+	(tree_statement_list::eval): Simplify.
+	(tree_argument_list::all_elements_are_constant): New function.
+	(class tree_decl_elt): Now contains id and expr, not an assignment
+	expression.
+
+	* pt-exp-base.h pt-exp.h pt-id.h pt-indir.h pt-mat.h pt-const.h,
+	pt-exp-base.cc pt-exp.cc pt-id.cc pt-indir.cc pt-mat.cc pt-const.cc:
+	Replace eval functions with rvalue and lvalue functions.
+	Change all uses.
+	(lvalue_ok, rvalue_ok): New functions, for future compile-time
+	semantic checks.
+
+	* oct-var-ref.h (is_defined, is_map): New functions.
+
+	* pt-exp.h (class tree_oct_obj): Delete.
+
+	* variables.cc (extract_function, is_valid_function): Return
+	pointer to octave_function, not octave_symbol.
+	(link_to_global_variable): Rewrite.  Handle errors in
+	symbol_record::mark_as_linked_to_global.
+
+	* symtab.h, symtab.cc (class symbol_def, class symbol_record):
+	Symbols are now stored as octave_value objects only.
+
+	* ov.cc (install_types): Register function types here.
+	* ov-fcn.h, ov-fcn.cc, ov-builtin.h, ov-builtin.cc, ov-mapper.h,
+	ov-mapper.cc, ov-usr-fcn.h, ov-usr-fcn.cc: New classes for
+	functions as values.
+	* ov.h (class octave_value): Don't derive from octave_symbol.
+	* oct-fcn.h, oct-fcn.cc, oct-builtin.h, oct-builtin.cc,
+	oct-mapper.h, oct-mapper.cc, oct-usr-fcn.h, oct-usr-fcn.cc,
+	oct-sym.h, oct-sym.cc: Delete.
+
+Sun May 11 17:51:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (Ftype): Make it work again for functions.
+
+	* pt-pr-code.cc (tree_print_code::print_parens): New function.
+	Use it in other tree_print_code functions to handle printing all
+	the parens that we found when parsing the expression, not just one
+	pair.
+	* pt-exp-base.h (tree_expression::paren_count): Rename from
+	is_in_parens.
+	* parse.y (maybe_warn_assign_as_truth_value): Use new name.
+
+	* parse.y (constant): New non-terminal.
+	(simple_expr1): Use it.
+
+	* parse.y (make_unary_op): Delete.
+	(simple_expr1): Where appropriate, use make_prefix_op and
+	make_postfix_op instead of make_unary_op.  Allow increment and
+	decrement ops to work on expressions, not just identifiers.
+	(make_prefix_op, make_postfix_op): Arg is expression, not identifier.
+	Handle old unary_op cases too.
+	(fold (tree_unary_expression *)): Delete.
+	* pt-exp.h, pt-exp.cc (tree_prefix_expression::eval): Handle unary
+	minus and not here.
+	(tree_postfix_expression::eval): Likewise, for transpose and hermitian.
+	(class tree_prefix_expression, class tree_postfix_expression):
+	Derive from tree_unary_expression.  Delete identifier member.
+	Delete ident member function.
+	(tree_unary_expression): Don't handle evaluation here.
+	* pt-exp-base.h (mark_in_parens): No longer virtual. Return this.
+	(reference): New virtual function.
+	(class tree_expression): Don't handle expression type here.
+	* pt-mvr-base.h (tree_multi_val_ret::tree_multi_val_ret): Likewise.
+	* pt-mvr.h, pt-mvr.cc (tree_multi_assignment_expression): Likewise.
+	* pt-walk.h (visit_unary_expression): Delete declaration.
+	* pt-pr-code.h, pt-pr-code.cc (visit_unary_expression): Delete.
+	(visit_prefix_expression): Use operand(), not ident().
+	new, visit_postfix_expression):
+	* pt-id.h, pt-id.cc (increment, decrement): Delete.
+
+	* pt-misc.cc (tree_parameter_list::define_from_arg_vector): Get a
+	reference to each element and use the assignment operator instead
+	of tree_identifier::define.
+	* pt-id.h, pt-id.cc (tree_identifier::define): Delete versions
+	that take octave_value and octave_symbol args.
+
+Sat May 10 23:32:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-indir.h, pt-indir.cc (tree_indirect_reference::value): Delete.
+
+	* oct-var-ref.cc (octave_variable_ref::assign): Clear idx after
+	assignment.
+
+	* octave_value classes: Add is_constant, is_function, and
+	function_value functions.
+
+	* ov.h, ov.cc (assign): Return void, not reference to octave_value.
+	(do_index_op): Rename, from index.
+	(do_struct_elt_index_op): Rename, from struct_elt_val.
+	Add version that accepts index arg.
+	Change all uses and derived classes to match.
+	* pt-const.h (index): Delete.
+	* oct-var-ref.h, oct-var-ref.cc (value): Handle indexed structure
+	ops here too.
+
+Fri May  9 07:40:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-exp.cc (print_rhs_assign_val, symbols_of_pt_exp): New functions.
+	(Vprint_rhs_assign_val): New static variable.
+	(tree_simple_assignment_expression::eval): Use it to optionally
+	allow the rhs (which is the result) of an assignment to be printed
+	instead of the left.
+
+	* pt-exp.cc (tree_simple_assignment_expression::eval): Use new
+	octave_variabl_reference::index function to handle indexing.
+
+	* oct-var-ref.h, oct-var-ref.cc (idx): New data member.
+	(octave_variable_reference::index): Set it.
+	(octave_variable_reference::assign): Handle indexing here.
+	Delete version of this function htat takes index arg.	
+
+	* variables.h (struct builtin_varaible): Delete.
+	* variables.cc (install_builtin_variable): Take all elts of
+	builtin_variable struct directly.
+	* defun.h (DEFVAR_INT): Call install_builtin_variable directly.
+
+	* symtab.h, defun-int.h: Don't include variables.h.
+
+	* symtab.h (symbol_record::sv_function): Move typedef here.
+	* variables.h: From here.
+
+	* oct-var-ref.h, oct-var-ref.cc: New files for
+	octave_variable_reference class, extracted from variables.h and
+	variables.cc
+	* Makefile.in: Add them to the appropriate lists.
+
+	* oct-obj.h (octave_value_list::empty): New function.
+
+	* variables.h (class octave_variable_reference):  Rewrite to work
+	as a proxy class to store a pointer to octave_value and,
+	optionally, the change function to call and the name of the
+	structure element we are referencing.  Handle assignment,
+	increment, decrement, and value operations.
+
+Thu May  8 23:40:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-re-mat.h, ov-re-mat.cc (struct_elt_ref, struct_elt_val,
+	assign_struct_elt): Provide functions for looking up and setting
+	matrix dimensions.
+
+	* symtab.cc (symbol_record::define): Don't call sv_fcn here.
+	Don't save and restore value here.
+	(symbol_record::define_builtin_var): Do call sv_fcn here.
+	(symbol_record::variable_reference): Don't make value unique here.
+	Return pointer to sv_fcn in octave_variable_reference.
+
+	* pt-misc.cc (tree_parameter_list::initialize_undefined_elements): 
+	Simplify.
+
+	* pt-id.h, pt-id.cc (tree_identifier::reference): Return
+	octave_variable_reference, not octave_value&.
+	* symtab.h, symtab.cc (symbol_record::variable_reference): Ditto.
+	* pt-indir.h, pt-indir.cc (tree_indirect_ref::reference): Ditto.
+	Simplify too.
+
+	* pt-const.h (tree_constant::reference, tree_constant::value,
+	tree_constant::assign):  Delete unnecessary functions.
+	* pt-id.h, pt-id.cc (tree_identifier::assign): Ditto.
+
+	* pt-cmd.cc (tree_for_command::do_for_loop_once): Simplify.
+
+	* ov.h, ov.cc, ov-base.h, ov-base.cc, ov-struct.h, ov-struct.cc
+	(struct_elt_ref): New arg, octave_value* parent.
+	Allow deferred lookup.  Return octave_variable_reference, not
+	octave_value&.
+
+	* ov.h, ov.cc, ov-re-mat.h, ov-re-mat.cc (assign_struct_elt):
+	New virtual functions.
+
+	* ov.h, ov.cc (Vresize_on_range_error): Now static.
+
+	* pt-mvr.cc (tree_index_expression::eval): Delete redundant check
+	of error_state.
+
+Wed May  7 21:17:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (generate_completion): Rename from command_generator.
+	Use string objects instead of char*.
+	(generate_possible_completions): Let qsort also make matches unique.
+	(initialize_command_input): Register generate_completion with the
+	command_editor class.
+	(completion_matches): Simplify using generate_completion.
+
+	* pt-pr-code.cc (tree_print_code::visit_constant): For val, call
+	print_raw, not print.
+
+	* oct-usr-fcn.h (octave_user_function::argn_sr): New data member.
+	(octave_user_function::install_automatic_vars): Rename from
+	install_nargin_and_nargout.
+	(octave_user_function::bind_automatic_vars): Rename from
+	bind_nargin_and_nargout.
+	* oct-usr-fcn.cc (octave_user_function::eval): Extract arg names
+	from args vector and bind them to argn.
+	* oct-obj.h (octave_value_list::names): New data member.
+	* oct-obj.cc (octave_value_list::stash_name_tags): New function.
+	(octave_value_list::name_tags): Ditto.
+	* pt-const.h, pt-const.cc (tree_constant::print_raw): New function.
+	* pt-misc.h, pt-misc.cc (tree_argument_list::get_arg_names):
+	New function.
+	* pt-mvr.h, pt-mvr.cc (class index_expression): Cache arg names.
+	* toplev.cc (feval): Now static.  Handle arg names.
+
+	* mkops: Cope with moving files defining operators to OPERATORS
+	subdirectory.
+
+Tue May  6 00:48:59 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* DLD-FUNCTIONS/getgrent.cc: Use new octave_group class.
+	* DLD-FUNCTIONS/getpwent.cc: Use new octave_passwd class.
+
+	* syscalls.cc: Simplify by using new functions defined in
+	liboctave/oct-syscalls.cc.
+
+	* file-io.cc (Ftmpnam): Accept DIR and PREFIX args.
+
+Mon May  5 00:54:03 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-str-mat.cc (octave_char_matrix_str::print_name_tag): Print
+	empty strings on one line.
+
+	* DLD-FUNCTIONS, OPERATORS, and	TEMPLATE-INST: New subdirectories.
+	Move appropriate files to new directories.
+	* Makefile.in: Add DLD-FUNCTIONS, OPERATORS, and TEMPLATE-INST
+	directories to VPATH.  Fix rules to work with new directory
+	structure.
+
+Sun May  4 22:40:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	*  input.cc (initialize_command_input): Rename from
+	initialize_readline.
+	(gnu_readline, octave_gets, get_user_input): Simplify, return
+	string, not char *.
+
+	* Many of other files: Miscellaneous changes to go along with the
+	changes described in the liboctave/ChangeLog for May 4.  More code
+	moved from here to liboctave.
+	
+Fri May  2 19:50:33 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathlen.h: Move to ../liboctave.
+
+Thu May  1 21:50:44 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (get_struct_elts): New fucntion.
+	(looks_like_struct, generate_struct_completions): Move here from
+	input.cc, rewrite, and make work again.
+
+Wed Apr 30 00:24:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-base.h, ov-bool-mat.cc, ov-bool-mat.h, ov-bool.cc, ov-bool.h,
+	ov-ch-mat.cc, ov-ch-mat.h, ov-complex.cc, ov-complex.h,
+	ov-cx-mat.cc, ov-cx-mat.h, ov-file.cc, ov-file.h, ov-list.cc,
+	ov-range.cc, ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-scalar.cc,
+	ov-scalar.h, ov-str-mat.cc, ov-struct.cc, ov.h (scalar_value):
+	New function.  Same as double_value, but name is consistent with
+	octave_scalar class.
+
+	* op-fil-b.cc, op-fil-cm.cc, op-fil-lis.cc, op-fil-rec.cc,
+	op-fil-str.cc, op-fil-bm.cc, op-fil-cs.cc, op-fil-m.cc,
+	op-fil-s.cc: New files.
+
+	* ops.h (ASSIGNOPDECL, DEFASSIGNOP, DEFASSIGNOP_FN, CONVDECL,
+	DEFCONV, BINOPDECL, DEFBINOPX, DEFBINOP, DEFBINOP_OP, DEFBINOP_FN,
+	BINOP_NONCONFORMANT): New macros.
+	* op-b-b.cc, op-bm-bm.cc, op-cm-cm.cc, op-cm-cs.cc, op-cm-m.cc,
+	op-cm-s.cc, op-cs-cm.cc, op-cs-cs.cc, op-cs-m.cc, op-cs-s.cc,
+	op-m-cm.cc, op-m-cs.cc, op-m-m.cc, op-m-s.cc, op-s-cm.cc,
+	op-s-cs.cc, op-s-m.cc, op-s-s.cc, op-str-str.cc: Use them.
+
+	* Makefile.in (octave): Also depend on ops.o.
+
+	* builtins.h: Delete.
+	* octave.cc: Add extern declaration here.
+
+	* mappers.h: Delete.
+	* Makefile.in (INCLUDES): Delete from list.
+	* mkbuiltins: Add extern declaration in builtins.cc.
+
+	* mkops: New file.
+	* ops.cc: Delete.
+	* Makefile.in (SOURCES): Delete from the list.
+	(ops.cc): New target.
+	(OP_SOURCES): New list.  Move all op-*.cc files here from SOURCES.
+	Add $(OP_SOURCES) to SOURCES list.
+
+	* variables.cc (symbols_of_variables): No longer static.
+	* ov.cc (symbols_of_ov): Rename from symbols_of_value.
+
+	* ov-base.h: Delete declaration for install_base_type_conversions.
+	* op-b-b.h, op-bm-bm.h, op-cm-cm.h, op-cm-cs.h, op-cm-m.h,
+	op-cm-s.h, op-cs-cm.h, op-cs-cs.h, op-cs-m.h, op-cs-s.h,
+	op-m-cm.h, op-m-cs.h, op-m-m.h, op-m-s.h, op-s-cm.h, op-s-cs.h,
+	op-s-m.h, op-s-s.h, op-str-str.h: Delete.
+	* Makefile.in (INCLUDES): Delete them from the list.
+
+Tue Apr 29 22:27:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.h, variables.cc (install_builtin_variables): Delete.
+	* mkbuiltins: Also generate install_builtin_variables function.
+	* Makefile.in: Fix rule to call mkbuiltins with correct args.
+	(clean): Also delete def-files and var-files.
+	* defaults.h.in, dirfns.h, error.h, file-io.h, help.h, input.h,
+	lex.h, load-save.h, oct-usr-fcn.h, pager.h, parse.h, pr-output.cc,
+	pr-output.h, pt-mat.h, pt-misc.h, pt-plot.h, toplev.h:
+	Delete declarations of symbols_of_* functions.
+	* data.h, syscalls.h: Delete.
+
+	* pr-output.cc (octave_print_internal): Leave printing of final
+	new line up to the caller.
+
+	* ov.h, ov.cc (reset_indent_level, increment_indent_level,
+	decrement_indent_level, newline, indent, reset,
+	curr_print_indent_level, beginning_of_line):
+	New functions and static data to manage indent level for printing.
+	(print_as_scalar): Delete.
+	(print, print_with_name): Always require stream arg.
+	Change all callers.
+
+	* oct-stream.h (octave_stream::input_stream): Make publicly available.
+	(octave_stream::output_stream): Likewise.
+
+	* ov-base.h, ov-base.cc, ov.h, ov.cc, ov-file.h ov-base.h
+	(is_file, stream_value, stream_number): New functions.
+	* ov-file.h, ov-file.cc: New files for value class to manage files.
+	* file-io.cc (symbols_of_file_io): Define stdin, stdout, and
+	stderr as octve_file objects, not just integers.
+	(Ffopen, Fpopen): Return octave_file objects, not integer file ids. 
+	* syscalls.cc (Fpipe): Likewise.
+	* oct-stream.h, oct-stream.cc (octave_stream_list::insert):
+	Return octave_file object, not integer file id.
+
+	* ov-base.cc, ov-bool-mat.cc, ov-bool.cc, ov-ch-mat.cc,
+	ov-complex.cc, ov-cx-mat.cc, ov-file.cc, ov-list.cc, ov-range.cc,
+	ov-re-mat.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc, ov.cc
+	(print_name_tag, print_raw): New functions.
+
+	* help.cc (Ftype): Don't cast symbol definition to tree_constant *.
+
+	* variables.cc (link_to_global_variable): Don't try to define
+	symbol with tree_constant objects.
+	(bind_ans): Call symbol_record::define directly and then
+	octave_value::print_with_name instead of creating a temporary
+	assignment expression.
+
+	* pt-pr-code.cc (tree_print_code::indent): Don't use ostream::form.
+
+	* pt-exp-base.h, pt-exp.h, pt-exp.cc (oper): Return string, not
+	char *.  Change all where necessary.
+
+Mon Apr 28 16:33:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value binary_op enum): Add lshift and rshift.
+	(octave_value assign_op enum): Add lshift_eq and rshift_eq.
+	* ov.cc (assign_op_as_string, binary_op_as_string): Include them.
+	* parse.y (LSHIFT_EQ RSHIFT_EQ LSHIFT RSHIFT): New tokens.
+	Add them to the precedence list.
+	(simple_expr): Add new operators.
+	(make_assign_op, make_binary_op): Handle new operators.
+	* lex.l: Recognize new operators.
+
+	* lex.l: Recognize them.
+
+Sun Apr 27 20:17:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-misc.cc (Vsilent_functions, silent_functions):
+	Move here from oct-usr-fcn.cc.
+	(symbols_of_pt_misc): New function.  DEFVAR silent_functions.
+	(tree_statement_list::eval): Handle Vsilent_functions here instead
+	of in octave_user_function::eval.
+	(tree_statement::eval): New functions.
+	(tree_statement_list::eval): Use them.
+	Change print flag arg to silent flag.  Change all callers.
+	* variables.cc (install_builtin_variables): Call symbols_of_pt_misc.
+	* toplev.cc (parse_and_execute): Delete print arg.  Change all callers.
+	(eval_string): Change print flag arg to silent flag.  Change callers.
+
+	* dynamic-ld.h, dynamic-ld.cc: Rewrite to use singleton class.
+	* variables.cc (load_fcn_from_file): Use new dynamic linking class.
+
+	* dynamic-ld.h (Octave_builtin_fcn): Delete typedef.
+	* dynamic-ld.cc: Simplify via the magic of function pointers.
+
+	* pt-fcn.h pt-fcn.cc pt-fvc.h pt-fvc.cc pt-fvc-base.h pt-fvc-base.cc:
+	Delete obsolete files.
+	* Makefile.in: Remove them from various lists.
+
+	* pt-walk.h (visit_octave_user_function): Rename from visit_function.
+	(visit_builtin): Delete.
+	* pt-pr-code.h, pt-pr-code.cc (visit_octave_user_function):
+	Rename from visit_function.
+	(visit_octave_user_function_header): Rename from visit_function_header.
+	(visit_octave_user_function_trailer): Rename from
+	visit_function_trailer.
+
+	* ov.h, ov.cc (eval): New functions.
+
+	* dassl.cc, fsolve.cc, lsode.cc, npsol.cc, qpsol.cc, quad.cc:
+	Declare user-defined functions as a pointer to an octave_symbol
+	object, not as a pointer to a tree_fvc object.
+
+	* symtab.h, symtab.cc: Use new octave_symbol class.
+	* variables.cc (install_builtin_function, install_builtin_mapper,
+	install_builtin_variable, install_builtin_variable_as_function):
+	Make work with new octave_symbol class and symbol table structure.
+
+	* variables.h: Delete declaration of builtin_function struct.
+	* defun-dld.h (DEFUN_DLD): Simplify.
+	* defun-int.h (DEFINE_FUN_STRUCT): Delete.
+	(DEFINE_FUN_STRUCT_FUN): Rewrite to not use static builtin_function
+	object.
+
+	* mappers.h: Delete declaration of builtin_mapper_function struct.
+	* mappers.cc: Declare wrapper functions static.
+	* defun.h (DEFUN_MAPPER): Simplify.
+
+	* oct-sym.h: New file.  Declare base class for Octave symbols.
+	* ov.h: Derive octave_value class from octave_symbol.
+	* oct-fcn.h, oct-fcn.cc: New files to declare and define
+	base class for functions.
+	* oct-builtin.h, oct-builtin.cc: New files to declare and define
+	class for built-in functions.
+	* oct-mapper.h, oct-mapper.cc: New files to declare and define
+	class for mapper functions.
+	* oct-usr-fcn.h, oct-usr-fcn.cc: New files to declare and define
+	base class for user-defined functions.
+	* Makefile.in: Add new files to appropriate lists.
+
+	* pt-id.h, pt-id.cc: Move tree_identifier class here.
+	* pt-fvc.h, pt-fvc.cc: From here.
+
+	* pt-indir.h, pt-indir.cc: Move tree_indirect_ref class here.
+	* pt-fvc.h, pt-fvc.cc: From here.
+
+Thu Apr 24 03:58:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (magic_colon): New nonterminal.
+	(arg_list): Simplify using magic_colon.
+
+	* lex.h (class lexical_feedback): Delete maybe_screwed field.
+	New field, parsed_function name.
+	* lex.l (lexical_feedback::init): Initialize it.
+	(handle_identifier): Don't return SCREW.  Handle switching
+	symbol table context properly for `function f ()' vs `function x ='.
+	(is_keyword): If looking at function keyword, don't set current
+	symbol table to point to the local table.
+	* parse.y (recover_from_parsing_function): New function.
+	(finish_function_def): Use identifier, not token.
+	Simplify parsing of functions.
+
+	* ov-list.h, ov-list.cc: New files to implement generic list type.
+	* ov.cc (list_indent): New global variable.
+	(increment_list_indent, decrement_list_indent): New functions.
+	(install_types): Register octave_list type.
+	* ov-base.cc (octave_base_value::is_list): New function.
+
+	* oct-sym.h: New file.
+	* ov.h (class octave_value): Derive from octave_symbol class.
+
+	* pt-const.h, pt-const.cc: Delete lots of old useless cruft.
+
+	* pt-exp.h, pt-exp.cc (tree_binary_expression): Use type codes for
+	operators from octave_value instead of repeating them here.
+
+	* pt-fvc-base.cc (tree_fvc::increment, tree_fvc::decrement): Delete.
+	* pt-fvc.cc (tree_identifier::increment): Get reference to value
+	and increment that instead of using virutal tree_fvc::increment
+	function.
+
+	* lex.l: Handle +=, -=, *=, /=, .+=, .-=, .*=, ./=, &=, and |= ops.
+	* parse.y (make_assign_op): Rename from make_simple_assignment and
+	handle different op types.
+	(simple_expr1): Do new ops.
+	* pt-misc.cc (initialize_undefined_elements): Pass op to assign.
+	* pt-cmd.cc (tree_for_command::do_for_command_once): Likewise.
+	* pt-fvc.cc (tree_identifier::assign): Pass op.
+	* pt-exp.cc (tree_simple_assignment_expression): Handle new ops.
+	* variables.cc (octave_variable_reference::assign): Likewise.
+	* ov.h (class octave_value): Likewise.
+	* ov.cc (octave_value::assign_op_as_string): New function.
+	(octave_value::assign, octave_value::convert_and_assign,
+	octave_value::try_assignment_with_conversion,
+	octave_value::try_assignment): Pass op.
+	* pt-pr-code.cc (tree_print_code::visit_simple_assignment_expression):
+	Use expr.oper() instead of printing "=".
+	* op-cm-cm.cc, op-cm-cs.cc, op-cm-m.cc, op-cm-s.cc, op-m-m.cc,
+	op-m-s.cc, op-str-str.cc: Pass op to INSTALL_ASSIGNOP.
+	* ops.h (INSTALL_ASSIGNOP): Pass op.
+	* ov-typeinfo.cc (do_register_assign_op): Include op type in table.
+	(do_lookup_assign_op): Use op in lookup.
+
+	* ops.h (INSTALL_UNOP): Delete.
+
+	* input.cc (generate_struct_completions, looks_like_struct):
+	Disable, since they don't work now anyway.
+
+	* help.cc (Ftype): Work with octave_value instead of a pointer to
+	tree_constant.
+	* symtab.cc (symbol_record_info::symbol_record_info): Likewise.
+
+
+Tue Apr 22 22:59:55 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ffprintf): If first arg is a string, assume FID = 1.
+
+Fri Apr 18 20:16:34 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-obj.h, oct-obj.cc: Implement octave_value_list with
+	Array<octave_value> as a data member, not as a class derived from
+	Array<octave_value>.
+	(octave_value_list::length, octave_value_list::resize,
+	octave_value_list::prepend, octave_value_list::append,
+	octave_value_list::reverse): New functions.
+
+	* op-cm-cm.cc, op-cm-cs.cc, op-cm-m.cc, op-cm-s.cc, op-cs-cm.cc,
+	op-cs-m.cc, op-m-cm.cc, op-m-cs.cc, op-m-m.cc, op-m-s.cc,
+	op-s-cm.cc, op-s-m.cc: Use new bool ops from liboctave instead of
+	the macros defined in ops.h.
+
+Thu Apr 17 13:12:22 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (ABORT_PARSE): Handle forced_interactive the same as
+	interactive.
+
+Mon Apr 14 01:46:50 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (octave_read): Don't forget to free input buffer if it
+	exists and has zero length.
+	(gnu_readline): Free buf if fgets returns 0.
+
+Wed Apr  9 00:03:57 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time.cc (mk_tm_map): Only set zone field if HAVE_TM_ZONE or
+	HAVE_TZNAME are defined.
+
+Tue Apr  8 12:39:21 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time.cc (extract_tm): Set tm.tm_zone if HAVE_TM_ZONE is defined,
+	not if HAVE_TMZONE is defined.
+
+	* Makefile.in (%.oct : %.o): Use $(SH_LD), not $(CXX).
+
+Wed Apr  2 21:32:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc, dynamic-ld.h (init_dynamic_linker): Delete
+	function and declaration.
+	* octave.cc (main): Don't call it.
+
+Mon Mar 31 00:37:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-base-exp.h (tree_expression::eval): Give arg a default value.
+	* pt-const.h (tree_constant::eval): Likewise.
+	* pt-exp.h (tree_prefix_expression::eval, tree_colon_expression::eval,
+	tree_postfix_expression::eval, tree_unary_expression::eval,
+	tree_binary_expression::eval, tree_boolean_expression::eval,
+	tree_simple_assignment_expression::eval): Likewise.
+	* pt-fcn.h (tree_function::eval): Likewise.
+	* pt-fvc.h (tree_identifier::eval, tree_indirect_ref::eval,
+	tree_builtin::eval): Likewise.
+	* pt-mat.h (tree_matrix::eval): Likewise.
+	* pt-misc.h (tree_statement_list::eval): Likewise.
+	* pt-mvr-base.h (tree_multi_val_ret::eval): Likewise.
+	* pt-mvr.h (tree_oct_obj::eval, tree_index_expression::eval,
+	tree_multi_assignment_expression::eval): Likewise.
+	* dassl.cc, fsolve.cc, load-save.cc, lsode.cc, npsol.cc, parse.y,
+	pt-cmd.cc, pt-exp-base.cc, pt-exp.cc, pt-fvc.cc, pt-mat.cc,
+	pt-misc.cc, pt-mvr.cc, pt-plot.cc, quad.cc, toplev.cc, variables.cc:
+	Change callers of eval() to use bool instead of int and to make
+	use of default argument value.
+
+	* toplev.h, toplev.cc (parse_and_execute, eval_string): Flag args
+	are now bool instead of int.
+
+	* symtab.h, symtab.cc: Use bool instead of int in more places.
+	* variables.h, variables.cc: Likewise.
+	* lex.h, lex.l: Likewise.
+	* parse.y: Likewise.
+	* help.cc, input.cc, lex.l, load-save.cc, parse.y, pt-fcn.cc:
+	Change callers of symbol_table::lookup to use bool instead of int,
+	and to make use of default arguments.
+
+Fri Mar 28 15:33:11 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (Vwarn_comma_in_declaration): Delete.
+	(symbols_of_parse): Delete DEFVAR for warn_comma_in_declaration.
+	(decl1): Don't allow commas in declarations.
+
+	* lsode.cc (struct LSODE_OPTIONS): Handle integer options.
+	(print_lsode_option_list, set_lsode_option, show_lsode_option): Ditto.
+	(lsode_option_table): Add element for step limit.
+	(lsode_user_jacobian): New function.
+	(Flsode): Allow function name arg to be a 2-element string array
+	specifying the function and jacobian function.
+
+	* variables.cc (get_global_value, set_global_value): New functions.
+
+Wed Mar 26 17:08:27 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	Implement static variable declaration:
+
+	* lex.l (is_keyword): Handle static.
+	* octave.gperf: Likewise.
+	* parse.y (Vwarn_comma_in_declaration): Rename from
+	Vwarn_comma_in_global_decl.
+	Handle new static command.
+	* pt-cmd.h, pt-cmd.cc (class tree_decl_command): New base class
+	for static and global declaration commands.
+	(class tree_global_command): Derive from tree_decl_command.
+	(class tree_static_command): New class, derived from tree_decl_command.
+	* pt-fvc.cc, pt-fvc.h (tree_identifier::mark_as_static): New function.
+	* pt-misc.h, pt-misc.h (class tree_decl_elt): Rename from tree_global.
+	(class tree_decl_init_list): Rename from tree_global_init_list.
+	* pt-pr-code.cc, pt-pr-code.h (tree_print_code::visit_decl_command):
+	Rename from visit_global_command.
+	(tree_print_code::visit_decl_elt): Rename from visit_global.
+	(tree_print_code::visit_decl_init_list): Rename from
+	visit_global_init_list.
+	* pt-walk.h (tree_walker::visit_decl_command): Rename from
+	visit_global_command.
+	(tree_walker::visit_decl_elt): Rename from visit_tree_global.
+	(tree_walker::visit_decl_init_list): Rename from
+	visit_global_init_list.
+	* variables.cc (link_to_global_variable): Trying to make a static
+	variable global is an error.
+	* SLList-misc.cc: Instantiate lists of pointers to tree_decl_elt
+	objects, not tree_global objects.
+	* symtab.h, symtab.cc (symbol_record::tagged_static): New field.
+	(symbol_record::mark_as_static, symbol_record::is_static):
+	New functions.
+	* symtab.cc (symbol_record::init_state): Initialize tagged_static.
+	(symbol_record::clear): Don't clear static variables.
+	* symtab.cc (push_context): Don't do anything for static variables.
+
+Tue Mar 25 17:17:17 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-bool-mat.cc, ov-bool-mat.h, ov-bool.cc, ov-bool.h: New files.
+
+	* defaults.cc (symbols_of_defaults): DEFCONST OCTAVE_HOME.
+
+	* toplev.cc (octave_config_info): Delete use of CXXLIBS.
+	* oct-conf.h.in: Ditto.
+
+	* octave.cc (maximum_braindamage): Don't bind prefer_zero_one_indexing.
+	* ov.h: Don't declare Vprefer_zero_one_indexing.
+	* ov.cc: Don't define Vprefer_zero_one_indexing.
+	(prefer_zero_one_indexing): Delete.
+	(symbols_of_value): Delete DEFVAR for prefer_zero_one_indexing.
+
+	* ov.h, ov.cc, ov-base.h, ov-base.cc: Add constructors and
+	extractors for bool and boolMatrix types. 
+	
+	* ov.cc (install_types): Register octave_bool and
+	octave_bool_matrix types.
+
+	* op-cm-cm.cc, op-cm-cs.cc, op-cm-m.cc, op-cm-s.cc, op-cs-cm.cc,
+	op-cs-m.cc, op-m-cm.cc, op-m-cs.cc, op-m-m.cc, op-m-s.cc,
+	op-s-cm.cc, op-s-m.cc, op-s-s.cc, ov-re-mat.cc:
+	Return boolMatrix instead of Matrix object.
+	* ops.h (BOOL_OP3, MX_MX_BOOL_OP): Likewise.
+
+	* op-b-b.h, op-b-b.cc, op-bm-bm.h, op-bm-bm.cc: New files.
+	* Makefile.in: Add them to the lists.
+	* ops.cc: Include header files here.
+	(install_ops): Call install_b_b_ops() and install_bm_bm_ops() here.
+
+	* variables.cc (symbols_of_variables): Don't rely on default
+	conversion from int to double for value returned from
+	default_history_size().
+
+	* pr-output.cc: Include cstdio.
+
+	* parse.y (param_list_end): Fix typo in last change.
+
+	* quad.cc (quad): Cast integer return values to double.
+	* npsol.cc (show_npsol_option): Likewise.
+	* qpsol.cc (show_qpsol_option): Likewise.
+	* file-io.cc (Fsprintf, Ffwrite): Likewise.
+
+Mon Mar 24 13:11:47 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-typeinfo.cc (typeinfo): If invoked with an argument, return
+	the type of the argument as a string.  Fix doc string.
+
+Thu Mar 20 14:47:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-oct-links (links_dir): Don't use -h option for grep.  It's
+	not needed since we are working on one file at a time anyway.
+
+Mon Mar 17 10:53:29 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (handle_identifier): When handling indirect_ref, set
+	lexer_flags.quote_is_transpose to 1 so that a.b' to work as
+	expected.
+
+	* parse.y (param_list_beg, param_list_end): New nonterminals.
+	(param_list, param_list1): Use them.
+
+Wed Mar 12 16:57:28 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-strip): New target.
+
+Mon Mar 10 22:38:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (clean): Delete .oct files too.
+
+	* toplev.cc (Vdefault_eval_print_flag): New static variable.
+	(eval_string): New arg, print.
+	(Feval): Pass Vdefault_eval_print_flag to eval_string.
+	(default_eval_print_flag): New function.
+	(symbols_of_toplev): New function.
+
+	* variables.cc (install_builtin_variables): Call it.
+
+	* pt-exp.h, pt-exp.cc (class tree_boolean_expression): Rename enum
+	fields `and' and `or' to `bool_and' and `bool_or'.
+	(tree_unary_expression): Rename enum field `not' to `unot'.
+	(class tree_binary_expression): Rename enum fields `and' and `or'
+	to `el_and' and `el_or'.
+	* parse.y: Change all uses.
+
+	* time.cc (extract_tm): Truncate field values instead of rounding.
+	(gmtime, localtime): Likewise, for timeval.
+
+	* ov.h (class octave_value): Delete unused variable freeptr.
+
+	* mappers.cc: Delete functions that are already in
+	liboctave/lo-mappers.cc.
+
+	* oct-strstrm.cc (octave_base_strstream::tell): Use const_cast,
+	not static_cast.
+
+	* help.cc (help_from_list): Add missing const qualifiers.
+	* help.h (struct help_list): Likewise.
+	* lex.l (match_any, plot_style_token): Likewise.
+	* load-save.cc (extract_keyword, ascii_save_type): Likewise.
+	* oct-hist.cc (mk_tmp_hist_file): Likewise.
+	* octave.cc (execute_startup_files): Likewise.
+	* octave.gperf (struct octave_kw): Likewise.
+	* pr-output.cc (pr_any_float): Likewise.
+	* pt-mvr.cc (tree_index_expression::eval_error): Likewise.
+	* pt-exp-base.h, pt-exp.h, pt-exp.cc: Likewise.
+	* parse.y: Likewise.
+
+Sun Mar  9 03:46:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-exp-base.h (tree_expression): Delete extra comma at end of list.
+
+	* dirfns.cc error.cc file-io.cc fsolve.cc input.cc load-save.cc
+	npsol.cc pt-fcn.cc qpsol.cc quad.cc syscalls.cc toplev.cc
+	variables.cc: Eliminate embedded newlines in string constants.
+
+	* Map.cc, data.cc, dirfns.cc, dynamic-ld.cc, file-io.cc,
+	fsolve.cc, getgrent.cc, getpwent.cc, getrusage.cc, help.cc,
+	input.cc, load-save.cc, mappers.cc, minmax.cc, npsol.cc,
+	oct-fstrm.cc, oct-procbuf.h, oct-stdstrm.cc, oct-stdstrm.h,
+	oct-stream.cc, oct-stream.h, oct-strstrm.cc, octave.cc,
+	ov-base.h, ov-range.cc, ov-typeinfo.cc, ov.cc, pr-output.cc,
+	pt-cmd.cc, pt-exp.cc, pt-fcn.cc, pt-fvc.cc, pt-mat.cc,
+	pt-misc.cc, pt-plot.cc, qpsol.cc, quad.cc, sort.cc, strfns.cc,
+	symtab.cc, syscalls.cc, sysdep.cc, time.cc, toplev.cc,
+	unwind-prot.cc, unwind-prot.h, variables.cc, xpow.cc:
+	Use `static_cast<T> (val)' instead of old C-style `(T) val' casts.
+
+Sat Mar  8 02:35:13 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_ascii_data, save_three_d): Where appropriate,
+	use bool instead of int.
+	(save_binary_data, save_mat_binary_data, save_ascii_data):
+	Print warning instead of error for wrong type arg.
+
+	* gripes.cc (gripe_wrong_type_arg): New arg, is_error.
+
+	* pt-plot.cc (save_in_tmp_file): Call save_ascii_data with bool
+	arg, not int.
+
+Fri Mar  7 00:56:16 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dassl.cc (show_dassl_option): For values that are determined
+	automatically, return a string instead of a magic value (-1.0).
+	* fsolve.cc (show_fsolve_option): Likewise.
+	* lsode.cc (show_lsode_option): Likewise.
+	* npsol.cc (show_npsol_option): Likewise.
+	* qpsol.cc (show_qpsol_option): Likewise.
+
+	* variables.cc (extract_function): New function.
+	* dassl.cc (Fdassl): Use it instead of is_valid_function.
+	* fsolve.cc (Ffsolve): Likewise.
+	* npsol.cc (Fnpsol): Likewise.
+	* qpsol.cc (Fqpsol): Likewise.
+	* quad.cc (Fquad): Likewise.
+
+Thu Mar  6 20:07:24 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (my_friendly_exit, octave_new_handler,
+	sigfpe_handler, sigpipe_handler): Don't all error() or warning().
+
+	* pager.cc (pager_death_handler): Don't try to clear pager, just
+	print message to cerr.
+	(do_sync): If the status of the pager is bad or it looks like it
+	is dead, restore the interrupt handler.
+
+	* load-save.cc (extract_keyword (istream&, char*, int&)):
+	Move declaration of buf inside loop, to avoid deleting its guts
+	and then trying to reuse it.
+	(extract_keyword (istream&, char*)): Likewise.
+
+Tue Mar  4 20:36:53 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-fcn.cc (tree_function::eval): Protect function from being
+	redefined while it is being evaluated.
+	(unprotect_function): New function, for use with unwind_protect stuff.
+	* pt-fcn.h (tree_function::symtab_entry): New data member.
+	(tree_function::init): Initialize it to 0.
+	(tree_function::stash_symtab_ptr): New function.
+	* parse.y (frob_function_def): Stash pointer to function's
+	symbol_record in the function definition.
+
+	* symtab.cc (symbol_record::read_only_error): New argument,
+	action.  Change all callers.
+	(symbol_record::rename): Don't allow read-only symbols to be renamed.
+
+	* variables.cc (Fexist): Don't let files with `.' in their names
+	confuse us.
+
+	* symtab.cc (valid_identifier (const string&)): New function.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.5 released.
+
+Sat Mar  1 01:34:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-oct-links): New target.  Make links in build
+	directory too, so that the tests will work.
+
+	* quad.cc: If quad is defined, undefine it.
+
+	* octave.cc: If WITH_KPATHSEARCH is defined, don't define
+	program_invocation_name or program_invocation_short_name.
+
+	* strftime.c: Update to current version from FSF.
+	* time.cc (Fstrftime): Call strftime with buf = 0 to get buffer
+	size, then call again to actually format the time struct.
+
+Fri Feb 28 01:49:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	Implement switch statement:
+
+	* parse.y (Vwarn_variable_switch_label): New static variable.
+	(warn_variable_switch_label): New function.
+	(symbols_of_parse): Provide warn_variable_switch_label as Octave
+	variable here.
+	(make_switch_case, finish_switch_command): New functions.
+	(maybe_warn_variable_switch_label): New function.
+	(end_error): Handle endswitch.
+	(switch_command, case_list, case_list1, switch_case, default_case):
+	New nonterminals.
+	(command): Add switch_command here.
+	* lex.l	(is_keyword): Handle switch, case, otherwise, and endswitch.
+	* octave_gperf: Recognize switch, case, otherwise, and endswitch.
+	* token.h (end_tok_type): New item, switch_end.
+	* pt-cmd.cc (tree_switch_command): New class.
+	* pt-misc.cc (tree_switch_case, tree_switch_case_list): New classes.
+	* pt-pr-code.cc (tree_print_code::visit_switch_case,
+	tree_print_code::visit_switch_case_list,
+	tree_print_code::visit_switch_command): New functions.
+ 	* pt-walk.h (tree_walker::visit_switch_case,
+	tree_walker::visit_switch_case_list,
+	tree_walker::visit_switch_command): New pure virtual declarations.
+	Implement new switch statement.
+	* SLList-misc.cc: Instantiate lists of pointers to
+	tree_switch_case objects too.
+
+	* lex.h, lex.l, parse.y: Delete all references to lexer_flags::iffing.
+
+	* syswait.h: Include sys/wait.h on NeXT systems, but don't use the
+	WIFEXTED, WEXITSTATUS, and WIFSIGNALLED macros defined there.
+	Also define waitpid in terms of wait4.  From Rex A. Dieter
+	<rdieter at math.unl.edu>.
+
+Wed Feb 26 16:43:31 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_scanf): Don't report an
+	error if a conversion fails or we reach EOF.
+
+Tue Feb 25 22:21:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* time.cc (strftime): increase initial buffer size.
+
+Mon Feb 24 17:49:21 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-fvc.cc (tree_builtin::eval): Enable checking for max number
+	of arguments.
+
+	* error.cc (handle_message): Don't fail if args is empty.
+
+Sun Feb 23 22:42:52 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.h (lexical_feedback::looking_at_return_list): New field.
+	(lexical_feedback::looking_at_parameter_list): Ditto.
+	* lex.l (lexical_feedback::init): Initialize them.
+	(handle_identifier): Use them.
+	* parse.y: Likewise.
+
+Fri Feb 21 15:35:18 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l: Require flex 2.5 or later (we really want 2.5.4 or later,
+	but there seems to be no good way to check the patchlevel).
+
+	* oct-stream.cc (octave_base_stream::oscanf): Instead of returning
+	an error, just quit processing after a conversion fails.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+Wed Feb 19 10:30:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (octave_ignore_interrupts,
+	octave_catch_interrupts, octave_set_interrupt_handler):
+	Return old value, not pointer to static data.  Fix all uses.
+	
+	* sighandlers.h (octave_interrupt_handler): Move declaration here.
+	* sighandlers.cc: From here.
+
+	* toplev.cc: Undo previous change.
+
+	* lex.l (handle_identifier): Allow commands like ls, save, etc. to
+	also be used as simple variable names.  Also make it possible to
+	use the normal function call syntax to invoke them.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (%.oct:%.o, %.oct:pic/%.o): Use $(SH_LDFLAGS) here.
+
+	* Version 2.0.3 released.
+
+Tue Feb 18 00:27:49 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (run_command_and_return_output):
+	Block SIGCHLD while running subprocess.
+	(cleanup_iprocstream): Unblock it here.
+
+	* sighandlers.h (BLOCK_SIGNAL, BLOCK_CHILD, UNBLOCK_CHILD): Move here.
+	* sighandlers.cc: From here.
+
+	* toplev.cc (system): Shift then mask exit status.
+
+	* help.cc (try_info): Shift first, then mask exit status.
+
+	* toplev.cc (octave_config_info): Handle option argument.
+
+Fri Feb 14 16:23:30 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_scanf): Don't forget to
+	check to see if the result matrix needs resizing!
+
+	* Makefile.in (bin-dist): Don't write empty strings to LIBRARIES.
+
+Thu Feb 13 03:02:08 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (stamp-prereq): Depend on stamp-picdir.
+	(all): Don't depend on stamp-prereq or stamp-picdir.
+	(stamp-tinst, stamp-interp, libtinst.a, liboctinterp.a):
+	Do depend on stamp-prereq.
+	(stamp-picdir): Silence noise about making pic.
+	(stamp-tinst, stamp-interp): Use $(SH_LD) $(SH_LDFLAGS) instead of
+	$(CXX) -shared.
+
+	* oct-conf.h.in: Reinstate RLD_FLAG.
+	* toplev.cc (octave_config_info): Likewise.
+
+	* data.cc (map_d_m, map_m_d, map_m_m): Rename from map.
+	(Fatan2): Use new function names.
+
+	* pt-fvc.cc (apply_mapper_fcn): Use member function map() instead
+	of friend function.
+
+	* gripes.cc (gripe_wrong_type_arg (const char*, const string&)):
+	New function.
+
+Wed Feb 12 17:27:53 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* syscalls.cc (symbols_of_syscalls): Add O_ASYNC and O_SYNC.
+
+Mon Feb 10 01:22:27 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (Freaddir, Fmkdir, Frmdir, Frename):
+	Also return status and error message.
+
+	* syscalls.cc (Fdup2, Fexec, Ffork, Ffcntl, Funlink, Fmkfifo,
+	Fpipe, Fwaitpid): Also return error message.
+
+Sat Feb  8 17:16:09 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-exp.cc (tree_simple_assignment_expression::eval): Return
+	value of RHS, but (if printing) print complete value of LHS.
+
+	* pr-output.cc (octave_print_internal): Print a new line for empty
+	string matrices.
+
+Wed Feb  5 14:30:44 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (scanf_format_list::process_conversion): Accept
+	but don't actually use h, l, and L modifiers.  Always insert l
+	modifier for floating point conversions.	
+
+Fri Jan 31 13:55:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pager.cc (do_sync): Always flush the cout stream after writing.
+
+Wed Jan 29 08:25:29 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc (exec_path): Don't include bin_dir in std_path.
+
+	* pager.cc (do_sync): Flush the cout stream after writing if
+	running in interactive or forced_interactive mode.
+
+	* mk-oct-links: Rename from mk-oct-links.in.
+	Don't use symbolic links.
+	* Makefile.in: Distribute mk-oct-links, not mk-oct-links.in
+	(mk-oct-links): Delete target.
+	(install-oct, bin-dist): Don't depend on mk-oct-links.
+	Run $(srcdir)/mk-oct-links, not ./mk-oct-links.
+
+	* qr.cc (qr): Doc fix.
+
+Tue Jan 28 10:48:28 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-inc): Create a relative symbolic link.
+	(install-bin): Create a relative symbolic link.
+
+Mon Jan 27 12:12:03 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+	* Makefile.in (CXXFLAGS_NO_PT_FLAGS): Rename from XALL_CXXFLAGS.
+	Substitute bsd_gcc_kluge_targets_frag.
+
+	* sysdep.cc (Fsleep): New function.
+	(Fusleep): New function.
+
+	* toplev.cc (octave_config_info): Don't include RLD_FLAG.
+	* oct-conf.h.in: Don't define RLD_FLAG
+
+Sun Jan 26 19:41:48 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (sigchld_handler): Block SIGCHLD while
+	sigchld_hander is running.
+
+Sat Jan 25 22:36:39 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (bin-dist): Update for 2.x.
+
+Fri Jan 24 10:05:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-oct-links.in: New arg, -p, to just print list of files to link.
+
+	* lex.l (handle_number): Convert `D' or `d' exponents to `e'
+	before scanning.
+
+Thu Jan 23 10:00:00 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-pr-code.h, pt-pr-code.cc (tree_print_code::visit_no_op_command):
+	New function. 
+	* pt-cmd.h, pt-cmd.cc (tree_no_op_command): New class.
+	* parse.y (make_break_command, make_continue_command,
+	make_return_command): Where they don't really make sense, turn
+	these commands into no-ops.  Accept return and break if reading a
+	script file.
+	* toplev.cc (parse_and_execute): Handle return and break in script
+	files.  Quit executing commands if an error occurs when reading a
+	script file.  Set global_command to 0 after deleting it.
+	(main_loop): If not interactive or forced_interactive, handle
+	break and return, and quit executing commands if an error occurs.
+	Set global_command to 0 after deleting it.
+	* error.cc (Ferror): Doc fix.
+	* pt-walk.h (tree_walker): Add declaration for visit_no_op_command.
+
+Wed Jan 22 20:54:12 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (gnu_readline): If not using readline, flush
+	rl_outstream after printing prompt.
+	(octave_gets): Also call flush_octave_stdout() if
+	forced_interactive, not just if interactive.
+	(do_input_echo): If forced_interactive, only echo prompt and
+	command line if also reading a script file.
+
+Tue Jan 21 23:02:34 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* SLList.h: Include "BaseSLList.h", not <BaseSLList.h>.
+
+Mon Jan 20 11:11:12 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (token_stack): Don't declare static.
+	* pt-plot.cc (tmp_files): Likewise.
+	* toplev.cc (octave_atexit_functions): Likewise.
+	* unwind-prot.cc (unwind_protect_list): Likewise.
+
+	* ops.h (MX_MX_BOOL_OP): Correctly handle case of one or both
+	arguments being empty.  Change all callers.
+
+	* oct-stream.cc (printf_value_cache::looking_at_string):
+	Handle empty strings correctly now that they are 0x0.
+
+	* file-io.cc: Don't include "syswait.h" here.
+
+Sun Jan 19 22:38:45 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.h (octave_base_stream::seek): Declare offset arg as
+	streamoff, not streampos.
+	(octave_stream::seek): Likewise.
+	* oct-strstrm.h (octave_base_strstream::seek): Likewise.
+	* oct-stdstrm.h (octave_base_stdiostream::seek): Likewise.
+	* oct-iostrm.h (octave_base_iostream::seek): Likewise.
+	* oct-fstrm.h (octave_fstream::seek): Likewise.
+
+Fri Jan 17 18:13:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ffflush): Handle stdout as a special case.
+
+	* oct-stream.cc (octave_stream_list::do_get_file_number):
+	Do the work for octave_stream::get_file_number.
+	(octave_stream_list::get_file_number): Convert to static function.
+
+Wed Jan  8 11:42:44 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* log.cc (sqrtm): For complex arg case, compute sqrt, not log.
+
+Tue Jan  7 00:16:41 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Mon Jan  6 00:00:07 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-mat.cc (tm_row_const_rep::all_mt): New variable.
+	(tm_row_const::all_empty): New function.
+	(tm_row_const::tm_row_const_rep::init): Set all_mt here.
+	(tm_const::all_mt): New variable.
+	(tm_const::all_emtpy): New function.
+	(tm_const::init): Set all_mt here.
+	(tree_matrix::eval): Return an empty matrix if the list contains
+	only empty elements.  If it contains only empty strings, return an
+	empty string.
+
+Sun Jan  5 12:50:25 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ops.h (SC_MX_BOOL_OP, MX_SC_BOOL_OP): New arg, empty_result.
+	* op-cm-cm.cc, op-cm-cs.cc, op-cm-m.cc, op-cm-s.cc, op-cs-cm.cc,
+	op-cs-m.cc, op-m-cm.cc, op-m-cs.cc, op-m-m.cc, op-m-s.cc,
+	op-s-cm.cc, op-s-m.cc, op-str-str.cc: Change all uses of
+	SC_MX_BOOL_OP and MX_SC_BOOL_OP macros.  Return correct results
+	for empty matrix cases.
+
+	* pt-fcn.cc (tree_function::eval): If Vdefine_all_return_values is
+	true, initialize return values before evaluating function, for
+	compatibility with Matlab.
+
+	* oct-stream.cc (get_size): Correctly set size when arg is scalar.
+
+Thu Jan  2 12:40:10 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-oct): Quote $(OCT_FILES) in for loop to
+	avoid syntax error from ksh.
+
+	* pr-output.cc (octave_print_internal): Avoid unused parameter
+	warning from gcc.
+
+Thu Dec 19 12:13:42 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_base_stream::do_scanf):
+	Don't treat %l{e,f,g} differently from %{e,f,g}.
+	(octave_base_stream::do_oscanf): Likewise.
+
+	* sighandlers.cc (sigchld_handler): Fix typos.
+
+Wed Dec 18 20:17:23 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ffgetl, Ffgets): Also return number of characters	read.
+
+	* ov-range.cc (octave_range::not): New function.
+	* ov-range.h (octave_range::uminus): New function.
+
+	* BaseSLList.cc: Include error.h.
+	(BaseSLList::error): Call ::error() to process error message.
+
+Fri Dec 13 02:38:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.cc (octave_value::convert_and_assign): Preserve lhs value if
+	assignment fails.
+
+Wed Dec 11 12:33:16 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (GPLOT_CMD_END): Don't put semicolons at the end of
+	each plot command; it causes trouble with gnuplot 3.5.
+
+Tue Dec 10 00:31:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+	* pr-output.cc (set_format_style): Don't try to access argv unless
+	argc > 1.
+
+	* SLList-expr.cc SLList-misc.cc SLList-plot.cc SLList-str.cc
+	SLList-tc.cc SLList-tm.cc SLList.h SLStack-i.cc SLStack-pc.cc
+	SLStack-str.cc SLStack-sym.cc SLStack-tok.cc SLStack-ue.cc
+	SLStack-ui.cc, pt-mat.cc: Include Stack.h, Stack.cc, SLStack.cc,
+	and SLList.cc as necessary.
+
+	* Stack.cc, SLStack.cc, SLList.cc: New files.
+	* Makefile.in (SOURCES): Add them to the list.
+
+Mon Dec  9 12:03:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-bin): Use $(EXE) suffix so install will
+	find the right file on cygwin32 systems.
+
+	* ov.h: Declare proper form of do_binary_op as friend to
+	octave_value class.
+
+Sat Dec  7 22:00:10 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (do_printf_conv, do_scanf_conv,
+	do_oscanf_num_conv, do_oscanf_str_conv): Convert to real
+	functions instead of CPP macros, using templates where necessary.
+	(do_oscanf_num_conv, do_oscanf_str_conv): Correctly handle
+	discarded values.
+
+Fri Dec  6 00:20:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.94.
+
+	* Map-*.cc, SLList-*.cc, SLStack-*.cc: Include config.h.
+
+	* ov.h: Don't include SLList.h.
+
+	* SLStack.cc: Delete.  Move everything to SLStack.h.
+
+	* BaseSLList.h, BaseSLList.cc: New files.  Split out the
+	non-template base class parts of SLList.
+
+	* Makefile.in (TEMPLATE_SRC): Delete.  Move files to SOURCES.
+	* Map.h, Map.cc: Add #pragma interface/implementation.
+	* SLStack.h, SLStack.cc: Add #pragma interface/implementation.
+
+	* SLList.h, SLList.cc: New files, from libg++, but with #pragma
+	interface/implementation.
+	* Makefile.in (SOURCES): Add SLList.cc.
+	(INCLUDES): Add SLList.h.
+
+Thu Dec  5 18:36:44 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc: Don't include sun-utils.h.
+
+Tue Dec  3 23:47:09 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* op-str-str.cc (eq, ne): Handle operations with scalars.
+
+Thu Nov 21 12:30:36 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-str-mat.h (octave_char_matrix_str): Provide transpose and
+	hermitian operators.
+	* ov-ch-mat.h (octave_char_matrix): Likewise.
+
+Wed Nov 20 00:35:57 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.h (struct octave_interrupt_handler): Provide
+	forward declaration here.
+	* sighandlers.cc (octave_interrupt_handler): New struct.
+	(octave_catch_interrupts): Rename from catch_interrupts.
+	(octave_ignore_interrupts, octave_set_interrupt_handler):
+	New functions.
+	* help.cc, oct-hist.cc, pager.cc, toplev.cc: Use new functions for
+	handling interrupts so that we can hide the details of whether or
+	not we have to deal with SIGBREAK.
+
+	* pt-plot.cc [! HAVE_POSIX_SIGNALS] (open_plot_stream):
+	Simply ignore and restore the interrupt handler here.
+
+	* sighandlers.cc (MAYBE_REINSTALL_SIGHANDLER): New macro.  Use it
+	instead of always checking MUST_REINSTALL_SIGHANDLERS everywhere.
+	(sigchld_handler): If octave_child_list is empty, wait for any
+	child, but don't hang, and don't collect status info.
+	[__EMX__] (sigchld_handler): Save and restore handlers for SIGINT,
+	SIGBREAK, and SIGCHLD.  Ignore them while waiting on children.
+	(install_signal_handlers): If SIGBREAK exists, handle it like SIGINT.
+
+	* toplev.cc [USE_READLINE] (clean_up_and_exit):
+	Call rl_deprep_terminal() to restore terminal settings.
+
+	* sysdep.cc [__EMX__ && OS2] (Fextproc): New command.
+	[__EMX__ && OS2] (FEXTPROC): Alias for Fextproc.
+
+	* Version 1.93.
+
+	* sysdep.cc (octave_chdir): [__EMX__]: Make copy of string before
+	converting to upper case.
+
+	* getgrent.cc (mk_gr_map): Only set the passwd field if
+	HAVE_GR_PASSWD is defined.
+
+Tue Nov 19 12:01:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc (OS2_init): New function.
+	[__EMX__] (sysdep_init): Call it.
+
+	* lex.l (plot_style_token): Add new plot styles for gnuplot 3.6.
+	* pt-plot.cc (subplot_style::columns_ok): Rename from
+	subplot_style::errorbars. Recognize more styles and do a better
+	job of diagnosing column number/style mismatches.
+
+	* sighandlers.cc (my_friendly_exit): If we are called twice, try
+	to remove the signal handler for SIGABRT and the call abort ().
+
+	* help.cc (Ftype): If a function is defined from a file and
+	transformed text has not been requested, just print the contents
+	of the file.
+
+	* parse.y (fold): New functions for constant folding for binary
+	and unary expressions.  Keep track of original text even when
+	transformations occur.
+	(make_binary_op, make_boolean_op, make_unary_op): Use them.
+	(finish_colon_expression, finish_matrix): Keep track of original
+	text even when transformations occur.
+
+	* help.cc (Ftype): Don't mess with Vps4.
+	Handle new option `-transformed'.
+
+	* pt-const.h, pt-const.cc (tree_constant::print):
+	New arg, pr_orig_text.
+
+	* pt-exp.h, pt-exp.cc (tree_colon_expression::is_range_constant):
+	Delete.
+
+	* pt-exp-base.h (tree_expression::original_text): New virtual function.
+	pt-exp-base.cc (tree_expression::original_text): Default version.
+
+	* pt-pr-code.h (tree_print_code::print_original_text,
+	tree_print_code::prefix): New fields.
+	* pt-pr-code.cc (tree_print_code::visit_constant): Pass
+	print_original_text to tree_constant::print().
+	(tree_print_code::indent): Use prefix instead of Vps4.
+	* pt-fcn.cc (tree_function::print_function_header,
+	tree_function::print_function_trailer): Pass Vps4 to
+	tree_print_code_constructor for prefix.
+	* pt-misc.cc (tree_statement::maybe_echo_code): Pass Vps4 to
+	tree_print_code_constructor for prefix.
+
+	* pt-mat.h, pt-mat.cc (tree_matrix::all_elements_are_constant):
+	Rename from is_matrix_constant.
+	(tree_matrix_row::all_elements_are_constant): Likewise.
+	Change all callers.
+
+Mon Nov 18 14:13:32 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-inc): Try harder to create the link from
+	include/octave to include/octave-VERSION.
+
+Sun Nov 17 14:14:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (parse.cc): Expect 13 shift/reduce conflicts.
+
+	* parse.y (set_stmt_print_flag): New function.
+	(sep_type): New member for bison %union declaration.
+	Simplify rules for statement lists keeping track of the type of
+	the first separator in the values associated with the
+	nonterminals for the separators.
+
+	* lex.l (handle_identifier): Set lexer_flags.doing_set if the
+	token is "gset", not "set".
+
+Sat Nov 16 21:41:26 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (parse.cc, lex.cc): Add special rules for these files.
+	Delete pattern rules for .y and .l files.
+
+Fri Nov 15 13:48:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc: Put semicolons at the ends of all plot commands.
+
+	* defaults.cc (subst_octave_home): Start subsequent searchs from
+	the end of the replaced text.
+
+	* pr-output.cc (pr_any_float): Kluge for SCO systems.
+
+	* pr-output.cc (pr_any_float, pr_complex): Don't declare inline.
+
+	* mappers.cc: Include lo-ieee.h, for isinf and isnan on SCO
+	systems.
+
+Thu Nov 14 00:06:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (Fgset, Fgshow): New commands.
+	(Fshow): Print warning and call gshow.
+	(Fset): Print warning and call gset.
+
+	* variables.cc (parse_fcn_file): Add unwind-protect for file
+	pointer, so the file is always closed.
+	(get_help_from_file): Likewise.
+	* toplev.cc (parse_and_execute): Likewise.
+
+	* Makefile.in (install-oct): Depend on mk-oct-links.
+	(mk-oct-links): New target.
+
+	* Version 1.92.
+
+Wed Nov 13 11:13:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sighandlers.cc (sys_siglist): [__EMX__]: Add definitions.
+
+	* octave.cc (execute_startup_files): Allow init file name ot be
+	specified by an environment variable.
+
+	* dirfns.cc (make_absolute): [__EMX__]: Path is already absolute
+	if it begins with any character followed by a colon.
+
+	* load-save.cc (read_mat_ascii_matrix, get_lines_and_columns,
+	get_complete_line): New functions, for reading headless text files.
+	(load_save_format): Add LS_MAT_ASCII, for headless text files.
+	(do_load): Handle LS_MAT_ASCII files.
+	Thanks to Mel Melchner <mjm at research.att.com> for initial version
+	of this code.
+
+	* sysdep.cc: Conditionally include ieeefp.h.
+	(BSD_init, SCO_init): New functions.
+	(sysdep_init): Conditionally call them here.
+
+Tue Nov 12 00:14:56 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc (open_plot_stream): Don't block SIGCHLD.
+
+	* load-save.cc (read_binary_data): When reading string arrays, be
+	sure to create an octave_char_matrix_str object, not just an
+	octave_char_matrix object.
+	(read_ascii_data): Likewise.
+
+Mon Nov 11 22:52:58 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_binary_data): Don't forget teminating NUL for
+	string that we plan to insert.
+	(read_ascii_data): Likewise.
+
+Sun Nov 10 16:58:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (Ffnmatch): New function.
+
+	* octave.cc (intern_argv): Use new string_vector constructor.
+
+	* ov-str-mat.cc (octave_char_matrix_str::all_strings): Have
+	charMatrix::row_as_string() strip trailing whitespace.
+
+	* dirfns.cc (Fglob): new function.
+
+	* sysdep.cc (oct_tilde_expand): Provide version that works on
+	string vectors too.
+	(Ftilde_expand): Work on string vector args.
+
+	* load-save.cc (save_binary_data): Call char_matrix_value() to
+	extract charMatrix from octave_value object, not all_strings().
+	(save_ascii_data): Likewise.
+	* pt-mat.cc (tree_matrix::eval): Likewise.
+
+	* ov.h (octave_value::all_strings): Return string_vector, not
+	charMatrix.
+	* ov-base.cc (octave_base_value::all_strings): Likewise.
+	* ov-str-mat.h, ov-str-mat.cc (octave_char_matrix_str::all_strings): 
+	Likewise.
+
+Fri Nov  8 09:54:59 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defaults.cc, dynamic-ld.cc, fn-cache.cc, help.cc, oct-hist.cc,
+	octave.cc, pager.cc, pt-fcn.cc, toplev.cc, utils.cc, variables.cc,
+	lex.l: Change #include "" to #include <> for defaults.h,
+	oct-conf.h, oct-gperf.h, y.tab.h, and version.h, to avoid getting
+	them from $srcdir when we really want the version from the build
+	directory.  (Maybe this should be done for all the include files,
+	not just those that are auto-generated?  Hmm.)
+
+	* defaults.h.in (CXXLIB_LIST, CXXLIB_PATH, FLIB_LIST, FLIB_PATH):
+	Delete.
+
+	* Makefile.in (install-oct): Use $(INSTALL_PROGRAM) for .oct files.
+
+Thu Nov  7 07:59:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (gobble_leading_white_space): New arg, update_pos.
+	* (is_function_file): Don't update file position information here.
+
+	* Version 1.91.
+
+	* pt-fvc.cc (tree_indirect_ref::reference): If the lhs object is
+	not a map, convert it to one.
+
+	* ov-typeinfo.h (init_tab_sz): New static member.
+
+	* ov-struct.cc, ov-struct.h: Add hooks for custom memory management.
+	* ov-scalar.cc, ov-scalar.h: Likewise.
+	* ov-re-mat.cc, ov-re-mat.h: Likewise.
+	* ov-range.cc, ov-range.h: Likewise.
+	* ov-cx-mat.cc, ov-cx-mat.h: Likewise.
+	* ov-complex.cc, ov-complex.h: Likewise.
+	* ov-ch-mat.cc, ov-ch-mat.h: Likewise.
+
+Wed Nov  6 12:32:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pager.cc (do_sync): Don't call clear_external_pager() here.
+
+	* pt-const.h (tree_constant::allocator) New static member.
+	(tree_constant::operator new, tree_constant::operator delete):
+	Implement with custom allocator.
+
+	* syscalls.cc (Fgetgid, Fgetegid): New functions.
+
+	* sighandlers.cc (sigchld_handler): If necessary, reinstall
+	handler after call to waitpid().
+
+	* pager.cc (pager_death_handler): Don't use warning() to print
+	message.
+
+	* getgrent.cc: New file.
+	* Makefile.in (DLD_SRC): Add it.
+
+	* ov.cc (octave_value::print_with_name): Call is_map() instead of
+	print_as_structure().
+	* ov-struct.cc (octave_struct::print): Likewise.
+
+	* ov.h, ov.cc, pt-const.h: Delete force_numeric(), make_numeric(),
+	convert_to_matrix_type(), print_as_structure() member functions.
+
+	* variables.cc (is_function_file): Call gobble_leading_whitespace
+	here to strip all leading whitespace and comments.
+	(parse_fcn_file): If reading a function file, call
+	gobble_leading_whitespace again after resetting parser state to
+	grab help text.
+
+Tue Nov  5 13:00:35 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* syscalls.cc (Fgeteuid, Fgetuid): New functions.
+
+	* getpwent.cc: Use gripe_not_supported from gripes.cc, instead of
+	local gripe_not_implemented function.
+
+	* input.cc, sysdep.cc, variables.cc: Only include readline.h and
+	history.h if USE_READLINE is defined.
+
+	* help.cc: Make it compile without warnings even if USE_GNU_INFO
+	is not defined.
+
+	* sighandlers.h (octave_child_list): Don't define
+	HAVE_POSIX_SIGNALS HERE.
+
+	* sighandlers.cc (SIGHANDLER_RETURN): New macro.
+	(generic_sig_handler, sigchld_handler, sigfpe_handler,
+	sigint_handler, sigpipe_handler):  Use it.
+	(sigchld_handler, sigfpe_handler, sigint_handler, sigpipe_handler):
+	Only reinstall signal handler if MUST_REINSTALL_SIGHANDLER is defined.
+
+Sun Nov  3 00:45:30 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-const.cc (tree_constant::print): Just call val.print().
+	* ov-base.cc, ov-ch-mat.cc, ov-colon.cc, ov-complex.cc,
+	ov-cx-mat.cc, ov-range.cc, ov-re-mat.cc, ov-scalar.cc,
+	ov-str-mat.cc, ov-struct.cc ov-va-args.cc, ov.cc (print):
+	Handle pr_as_read_syntax arg.
+
+	* defaults.cc (subst_octave_home): Search for prefix repeatedly in
+	retval, not s.
+
+	* gripes.h: Make declaration of gripes_not_supported match
+	definition.
+
+	* mk-oct-links.in: In sed command, match "DEFUN_DLD *( *", not
+	"DEFUN_DLD_BUILTIN *( *".
+
+	* chol.cc, colloc.cc, dassl.cc, det.cc, eig.cc, expm.cc, fft.cc,
+	fft2.cc, filter.cc, find.cc, fsolve.cc, fsqp.cc, getpwent.cc,
+	getrusage.cc, givens.cc, hess.cc, ifft.cc, ifft2.cc, inv.cc,
+	log.cc, lpsolve.cc, lsode.cc, lu.cc, minmax.cc, npsol.cc, pinv.cc,
+	qpsol.cc, qr.cc, quad.cc, qzval.cc, rand.cc, schur.cc, sort.cc,
+	svd.cc, syl.cc, time.cc: Change all uses of DEFUN_DLD_BUILTIN to
+	be just DEFUN_DLD.
+
+	* defun-dld.h: Eliminate DEFUN_DLD_BUILTIN.
+
+	* syswait.h: Use #ifdef HAVE_SYS_WAIT_H, not #if HAVE_SYS_WAIT_H
+	to decide whether to include sys/wait.h.
+
+	* pt-exp-base.h (tree_expression): Declare oper() here as a
+	virtual member function.
+
+	* pt-pr-code.cc (tree_print_code::visit_constant): Check for
+	string before checking for char_matrix.
+
+	* ov-ch-mat.cc (octave_char_matrix::print): Supply correct number
+	of args to octave_print_internal().
+
+Sat Nov  2 20:44:55 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ftmpnam): Rename from Foctave_temp_file_name.
+
+	* Makefile.in (DLD_SRC): Move time.cc and getrusage.cc here from
+	SOURCES.  Add getpwent.cc.
+
+	* getrusage.cc: Rename from resource.cc.  Make getrusage a
+	loadable function.
+
+	* time.cc: Rename from timefns.cc.  Make time functions loadable.
+
+	* getpwent.cc: New file.
+
+Wed Oct 30 01:06:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* Makefile.in (DISTFILES): Add ChangeLog.
+
+	* ov-range.cc (octave_range::convert_to_str): New function.
+
+	* ov-str-mat.h (octave_char_matrix_str::char_matrix_value):
+	Delete function.  Already handled by octave_char_matrix class.	
+
+	* ov-ch-mat.h (octave_char_matrix::convert_to_str): New function.
+
+	* pager.cc (Fmore): Set page_screen_output to 1.0 or 0.0, not
+	"true" or "false".
+
+	* ov-ch-mat.cc, ov-struct.cc, ov-struct.h, pr-output.cc,
+	pt-cmd.cc, pt-const.cc, pt-const.h, pt-fcn.cc, pt-fvc-base.cc,
+	pt-fvc-base.h, pt-fvc.cc, pt-fvc.h, rand.cc, sighandlers.cc,
+	variables.cc, variables.h: Delete unused code.
+
+	* octave.cc: Only include pwd.h if HAVE_PWD_H.
+
+	* oct-strstrm.h: Include <string>, not <string.h>.
+
+	* defaults.cc, dirfns.cc, file-io.cc, help.cc, input.cc,
+ 	oct-hist.cc, oct-procbuf.cc, oct-procbuf.h, octave.cc, pager.h,
+ 	procstream.h, pt-misc.cc, pt-plot.cc, sighandlers.cc, strftime.c,
+ 	syscalls.cc, sysdep.cc, syswait.h, toplev.cc, utils.cc,
+ 	variables.cc: Only include sys/types.h if HAVE_SYS_TYPES_H.
+
+	* error.h (panic): Use GCC_ATTR_NORETURN macro, not NORETURN.
+	* toplev.h (clean_up_and_exit): Likewise.
+	* utils.h (jump_to_top_level): Likewise.
+
+	* derfaults.h.in, defaults.cc (local_arch_lib_dir): New variable.
+	* defaults.cc (set_default_local_arch_lib_dir): New function.
+	(install_defaults): Call it.
+	(exec_path): Use Vlocal_arch_lib_dir here.
+	* toplev.cc (octave_config_info): Add localarchlibdir to structure.
+
+Tue Oct 29 15:54:27 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-oct): Don't do anything if $(OCT_FILES) is
+	empty.
+
+	* ov-range.cc (octave_range::index): New Function.
+	(octave_range::all, octave_range::any, octave_range::is_true):
+	Make these functions work.
+
+	* ov.cc (octave_value::try_assignment_with_conversion): Remove
+	left over debugging print statements.
+
+Mon Oct 28 10:49:03 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* strftime.c: Add missing #endif for previous change.
+
+Sun Oct 27 14:06:44 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-hist.cc (do_history): Rewite option parsing to avoid
+	(probably bogus) errors from g++ on cygwin32 system.
+
+	* strftime.c: Use autoconf macros TIME_WITH_SYS_TIME and
+	HAVE_SYS_TIME_H to decide which time.h files to include.
+
+	* oct-stream.h, oct-stream.cc (octave_stream::error,
+	octave_base_stream::error): Rename errno => err_num.
+
+Sat Oct 26 10:40:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-hist.cc (do_history): Move declaration of file inside
+	conditional.
+
+	* defun.h (DEFVAR_INT): Set eternal flag with (svc_fcn != 0)
+	instead of (sv_fcn ? 1 : 0)
+
+Fri Oct 25 01:10:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov-ch-mat.h (octave_char_matrix::any): Return 0.0 instead of false.
+	(octave_char_matrix::all): Likewise.
+
+	* input.cc (Fecho): When binding value of echo_executing_commands,
+	cast ECHO_* to double.
+
+	* sighandlers.cc (octave_child_list::do_remove): Delete unused
+	variable `enlarge'.
+
+	* pt-const.h (tree_constant::tree_constant (const tree_constant&)):
+	Don't pass arg to tree_fvc constructor.
+
+	* resource.cc (getrusage): [HAVE_GETRUSAGE && RUSAGE_TIMES_ONLY]:
+	Only fill in time values.
+
+Thu Oct 24 20:37:28 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y: Comment out the %expect declaration so byacc can
+	compile this file.
+	(if_cmd_list): Add missing semicolon.
+	Include <cstdlib> for getenv if using byacc.
+
+	* ov.h: Move typedefs outside of octave_value class scope to avoid
+	problem with cygwin32 beta16 compiler.
+
+Fri Oct 18 13:44:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::index): Undo previous change.
+	* ov.cc (octave_value constructors): Call maybe_mutate() in most
+	cases.
+
+	* ov-complex.cc (octave_complex::index): Avoid implicit type
+	conversion back to scalar type.
+	* ov-scalar.cc (octave_scalar::index): Likewise.
+
+	* ov.h (octave_value::index): Call maybe_mutate() on retval before
+	returning it.
+
+Wed Oct 16 12:00:11 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* ov.h (octave_value::struct_elt_val): New optional arg, silent.
+	* ov-base.h, ov-base.cc, ov-struct.h, ov-struct.cc: Likewise, but
+	for the derived classes the arg is required.
+
+	* data.cc (Fstruct_contains): Require arguments to be struct and
+	string, respectively.  Call octave_value::struct_elt_val with
+	silent flag set.
+
+	* pt-mat.cc (tm_row_const::tm_row_const_rep::eval_error,
+	tm_row_const::tm_row_const_rep::eval_warning): New functions.
+	(tm_row_const::tm_row_const (const tree_matrix_row&): Use them to
+	give better error messages.
+
+	* pt-fvc.cc (tree_identifier::eval): Avoid dereferencing null
+	object_to_eval.
+
+Tue Oct 15 11:35:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* op-cs-cm.cc, op-cs-cs.cc, op-cs-m.cc, op-cs-s.cc
+	(complex_matrix_conv): New functions.
+	Install preferred assignment conversion and widening ops.
+
+	* op-s-cm.cc, op-s-cs.cc (complex_matrix_conv): New functions.
+	Install preferred assignment conversion and widening ops.
+
+	* op-s-m.cc, op-s-s.cc (matrix_conv): New functions.
+	Install preferred assignment conversion and widening ops.
+
+	* ov.cc (octave_value::try_assignment_with_conversion,
+	octave_value::convert_and_assign, octave_value::try_assignment): 
+	New functions.
+	(octave_value::assign): Use them to implement twisted logic for
+	type conversions in assigments.
+
+	* pt-const.h (tree_constant::maybe_mutate): New function.
+	* ov.h (octave_value::maybe_mutate): New function.
+	(octave_value::try_narrowing_conversion): New function.
+	Use just one typedef for widening_op_fcn and numeric_conv_fcn.
+	Change all uses.
+	* ov-base.h, ov-complex.h, ov-complex.cc, ov-cx-mat.h,
+	ov-cx-mat.cc, ov-range.h, ov-range.cc, ov-re-mat.h, ov-re-mat.cc,
+	Provide derived class versions of try try_narrowing_conversion().
+
+	* pr-output.cc (octave_print_internal): Don't bother handing off
+	to scalar/real versions, even when it would seem appropriate.
+
+	* symtab.cc (symbol_def::define (tree_constant *)): Call
+	maybe_mutate on constants here.
+
+Mon Oct 14 11:05:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-fvc.cc (tree_identifier::eval): If retval is undefined and
+	the object to eval is a constant, print	error message.
+
+	* Makefile (distclean): Remove *.oct too.
+
+	* defun-int.h: Include variables.h here.
+
+Sun Oct 13 10:52:28 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (print_symbol_info_line): Never print negative
+	diminsions.
+
+	* symtab.h (octave_symbol_record_info): Store const_type as string.
+	(octave_symbol_record_info::init): Delete.  Fix constructors.
+	(octave_symbol_record_info::type_name): Handle const_type as string.
+
+	* octave.cc (maximum_braindamage): Replace "true" with 1.0 and
+	"false" with 0.0 in calls to bind_builtin_variable().
+	Include sun-utils.h here.
+	(intern_argv): Also bind __argv__.
+
+Sat Oct 12 13:40:21 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (distclean): Also delete mk-oct-links.
+
+Fri Oct 11 13:13:13 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	Changes for Octave's new type system:
+
+	* arith-ops.cc: Delete.
+	* pt-const.h, pt-const.cc: Massive changes.  Most functionality
+	moved to ov.h, ov.cc, and derived classes.
+
+	* variables.h, variables.cc (octave_variable_reference): New class
+	for getting references to variables and structure elements used in
+	assignments or value contexts.
+
+	* symtab.h, symtab.cc (symbol_record::define (const octave_value&),
+	symbol_record::variable_value, symbol_record::variable_reference):
+	New functions.
+	(symbol_record_info::type_name): Rename from type_as_string.
+
+	* pt-fvc-base.h, pt-fvc-base.cc (tree_fvc::increment,
+	tree_fvc::decrement): New functions to replace
+	tree_fvc::bump_value.
+	#if 0 assign and lookup_map_element functions.
+
+	* pt-mvr.cc (tree_multi_assignment_expression::eval):
+	Generated RHS value is now a tree_constant.
+
+	* pt-exp.h, pt-exp.cc (tree_boolean_expression): New class.
+	(tree_unary_expression, tree_binary_expression,
+	tree_boolean_expression): Move codes here from tree_expression.
+	(tree_simple_assignment_expression): Cope with changes to way of
+	doing assignments.
+
+	* pt-exp-base.h, pt-exp-base.cc (enum type): Delete codes for
+	unary and binary ops.
+	(tree_expression::expression_type): Delete.
+	(tree_expression::is_logically_true): Hand off to
+	octave_value::is_true to do real work.
+
+	* pr-output.h, pr-output.cc (any_element_is_inf_or_nan,
+	all_elements_are_ints): Delete.  Call member new functions for
+	these operations.
+	(free_format, plus_format, bank_format, hex_format,
+	compact_format, print_e, print_big_e): Use bool, not int.
+	(octave_print_internal): Hand off to scalar/real versions when
+	appropriate.
+
+	* octave.cc (main): Call initialize_types() and install_ops().
+	(verbose_usage): Add WWW address to output.
+
+	* parse.y (indirect_ref): Handle by making a tree instead of a
+	list using new version of tree_indirect_ref class.
+
+	* parse.y (make_boolean_op): New function.  Use it instead of
+	make_binary_op to create trees for && and || ops.
+	(make_binary_op): Codes come from tree_binary_expression now,
+	instead of tree_expression.
+	(make_unary_op): Codes come from tree_unary_expression now,
+	instead of tree_expression.
+	(make_boolean_op): Codes come from tree_boolean_expression.
+	
+	 *parse.y (tree_constant_type): Change type to tree_constant* from
+	octave_value*, and rename from octave_value_type.  Change uses.
+
+	* defun.h (DEFVAR_INT): Pass octave_value not pointer to
+	octave_value for defn when creating builtin_variable.
+
+	* gripes.h, gripes.cc (gripe_invalid_conversion): Args are
+	strings, not char*.
+	(gripe_implicit_conversion, gripe_divide_by_zero): New extern
+	gripe functions.
+
+	* mkbuiltins: For each file, create a separate static function to
+	install builtins, then create another single extern function to
+	call all of them.
+
+	* pt-fcn.cc (tree_function::bind_nargin_and_nargout):
+	Just pass doubles and let symbol_record::define handle creating
+	new value.
+
+	* pt-pr-code.cc, pt-pr-code.h (visit_constant): Renamed from
+	visit_octave_value.
+	(visit_unary_expression): Use tree_expression::is_prefix_op()
+	instead of switch on op types.
+
+	* pt-walk.h (visit_constant): Renamed from visit_octave_value.
+
+	* pt-misc.cc (initialize_undefined_elements): Get reference to
+	tmp, then assign.
+	* pt-cmd.cc (do_for_loop_once): Likewise, for loop identifier.
+
+	* input.cc (generate_struct_completions, looks_like_struct): Cast
+	tmp_fvc to tree_constant*, not octave_value*.
+	(get_user_input): Call print() on retval, not eval(1).
+
+	* help.cc (Ftype): Cast defn to tree_constant*, not octave_value*.
+
+	* balance.cc: Fix docstring.
+
+	* dassl.cc, fsolve.cc, load-save.cc, lsode.cc, npsol.cc, qpsol.cc,
+	quad.cc:
+	Include pt-fvc.h.
+
+	* data.cc (Fstruct_contains): call octave_value::struct_elt_val,
+	not octave_value::lookup_map_element.
+
+	* dirfns.cc (Fcd): Pass directory name as string directly to
+	bind_builtin_variable instead of creating new octave_value.
+
+	* toplev.cc: Include pt-fvc.h and lo-mappers.h
+
+	* data.cc, error.cc, file-io.cc, load-save.cc, pager.cc,
+	pt-mat.cc, pt-plot.cc, syscalls.cc, toplev.cc:
+	Include variables.h.
+
+	* Array-tc.cc, Map-tc.cc, SLList-misc.cc SLList-tc.cc, data.cc,
+	defaults.cc, dynamic-ld.cc, error.cc, gripes.cc, lex.l, octave.cc,
+	oct-map.h, oct-map.cc, oct-obj.h, pt-cmd.cc, pt-exp.cc, pt-fcn.cc,
+	pt-fvc-base.cc, pt-mat.cc, pt-misc.cc, pt-mvr-base.cc, pt-mvr.h,
+	resource.cc, strfns.cc, sysdep.cc, timefns.cc, toplev.cc:
+	Include ov.h instead of pt-const.h.
+
+	* xpow.cc (any_element_is_negative): Delete.
+	(xpow and elem_xpow functions): Check conformance here.
+
+	* xdiv.cc (mx_leftdiv_conform, mx_div_conform):
+	Now template-based, taking Matrices instead of dimensions as args.
+	Change all callers.
+
+	* op-cm-cm.cc, op-cm-cm.h, op-cm-cs.cc, op-cm-cs.h, op-cm-m.cc,
+ 	op-cm-m.h, op-cm-s.cc, op-cm-s.h, op-cs-cm.cc, op-cs-cm.h,
+ 	op-cs-cs.cc, op-cs-cs.h, op-cs-m.cc, op-cs-m.h, op-cs-s.cc,
+ 	op-cs-s.h, op-m-cm.cc, op-m-cm.h, op-m-cs.cc, op-m-cs.h, op-m-m.cc,
+	op-m-m.h, op-m-s.cc, op-m-s.h, op-s-cm.cc, op-s-cm.h, op-s-cs.cc,
+ 	op-s-cs.h, op-s-m.cc, op-s-m.h, op-s-s.cc, op-s-s.h,
+ 	op-str-str.cc, op-str-str.h, ops.cc, ops.h, ov-base.cc, ov-base.h,
+ 	ov-ch-mat.cc, ov-ch-mat.h, ov-colon.cc, ov-colon.h, ov-complex.cc,
+ 	ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h, ov-range.cc, ov-range.h,
+ 	ov-re-mat.cc, ov-re-mat.h, ov-scalar.cc, ov-scalar.h, ov-str-mat.cc,
+	ov-str-mat.h, ov-struct.cc, ov-struct.h, ov-typeinfo.cc,
+ 	ov-typeinfo.h, ov-va-args.cc, ov-va-args.h, ov.cc, ov.h:
+ 	New files for Octave's new type system.
+	* Makefile.in: Add them to the appropriate lists.
+
+Sat Sep 14 21:58:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mkbuiltins: Use .df instead of .def.
+	Write one function for each .df file, then call them
+	all in install_builtin_functions().
+	* Makefile.in: Handle .df instead of .def.
+
+	* balance.cc (balance): Fix typo in doc string.
+
+Wed Aug 28 21:01:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (verbose_usage): Include WWW address and bug-octave
+	mailing list address.
+
+Tue Aug 20 17:41:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: Only define pattern rules for making .oct files if
+	OCTAVE_LITE is true.
+	Only add pic/ to $(TI_OBJ) if $(SHARED_LIBS) is true.
+	(stamp-picdir): Only create a pic subdirectory if SHARED_LIBS or
+	OCTAVE_LITE is true AND CPICFLAG or CXXPICFLAG is not empty.
+
+	* minmax.cc (Fmin, Fmax): Deal with changes to Matrix class
+	min/max methods.
+
+Thu Jul 25 01:42:38 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (generate_possible_completions): Force the names to be
+	unique.
+
+	* load-save.cc (read_mat_binary_data): Expect to read terminating
+	NUL character in the variable name.
+	(save_mat_binary_data): Likewise, save it here.
+
+Wed Jul 24 05:08:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lsode.cc (Flsode): Don't set the return value if an error
+	occurred during integration.
+	* dassl.cc (Fdassl): Likewise.
+
+	* file-io.cc (symbols_of_file_io): Redefine values of SEEK_SET,
+	SEEK_CUR, and SEEK_END for Matlab compatibility.
+	* oct-stream.cc (seek): Check for compatible values of ORIGIN arg.
+	Also handle "bof", "cof", and "eof".
+
+Fri Jul 19 15:24:36 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-const.cc: When creating octave_value_reps from ComplexMatrix
+	values, check to see if all the elements are actually real.
+
+Tue Jul 16 10:53:42 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (decode_prompt_string): Swap meanings of \h and \H.
+
+Mon Jul 15 16:01:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (run_command_and_return_output): Renamed from do_system.
+	(Fsystem): Make `system ("emacs")' work as one would expect.
+
+Sun Jul 14 17:34:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (Ffopen, Ffread, Ffwrite): Update doc strings,
+	correctly handle default architecture and precision args.
+
+	* load-save.cc (mopt_digit_to_float_format): Rename from
+	get_floating_point_format.
+	(float_format_to_mopt_digit): New function.
+
+	* oct-stream.cc (octave_base_stream::read, octave_base_stream::write):
+	Simplify by calling Matrix::read and Matrix::write to do real work
+	of reading, writing, and format conversion.
+
+	* oct-stream.h (octave_base_stream): Move data_type enum to
+	liboctave/data-conv.h.  Use float_format from
+	liboctave/mach-info.h instead of arch_type enum.
+
+	* sysdep.h, sysdep.cc (octave_words_big_endian, ten_little_endians):
+ 	Delete.  Now part of oct_mach_info class in liboctave.
+
+Tue Jul  9 11:18:59 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* arith-ops.cc, balance.cc, dassl.cc, data.cc, filter.cc, find.cc,
+	fsolve.cc, load-save.cc, log.cc, lsode.cc, minmax.cc, npsol.cc,
+	oct-obj.cc, oct-stream.cc, pr-output.cc, pt-cmd.cc, pt-const.cc,
+	pt-fvc.cc, pt-plot.cc, quad.cc, rand.cc, sighandlers.cc, sort.cc,
+	syscalls.cc, unwind-prot.cc, xdiv.cc, xpow.cc:
+	When indexing arrays, use operator() instead of elem() so that
+	bounds checking can be done consistently.
+
+Mon Jun 24 02:13:27 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-oct): Use INSTALL_PROGRAM, instead of
+	INSTALL_DATA for installing shared libraries.
+
+	* lex.l (grab_help_text): Ignore all initial comment characters,
+	not just the first.
+	* variables.cc (gobble_leading_white_space): Likewise.
+
+Sat Jun 22 22:43:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.h, input.cc (octave_completion_matches_called): New varaible.
+	(Fcompletion_matches): Set it to true on a successful call.
+	* toplev.cc (main_loop): If octave_completion_matches_called is
+	true, don't increment current_command_number.
+
+Thu Jun 13 03:52:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (is_mapper_function_name,
+	is_builtin_function_name): New functions.
+	(Fdocument): Use them.
+	Define as regular function, not a text style function.
+
+Thu Jun  6 00:09:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-plot.cc: Handle new built-in variable `gnuplot_has_frames'.
+
+Wed Jun  5 14:45:04 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (decode_prompt_string): \h now means the whole host
+	name and \H is the host name up to the first `.'.
+
+Thu May 30 23:41:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* fn-cache.cc (octave_fcn_file_name_cache::do_list): Always
+	recompute the lists of function files instead of trying to cache
+	them.
+
+Tue May 28 12:05:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (warn_old_style_preference): New function.
+	(check_preference): Use it.
+
+	* fn-cache.h: Include <ctime> here.
+
+Fri May 24 00:57:14 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (completion_matches): Don't return empty string_vectors.
+
+	* octave.cc (long_opts): Add braindead.
+
+Thu May 23 01:49:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (gnu_readline): New optional arg, force_readline.
+	(get_user_input): Use it.
+
+	* pt-const.cc (OCT_VAL_REP::assign): If converting the rhs to a
+	numeric value, convert a copy, not the actual object.
+	(OCT_VAL_REP::do_index): Prevent s([]) from resulting in a string
+	with zero rows.
+
+	* mappers.cc: Handle toascii here.
+	* strfns.cc: Not here.
+
+	* mappers.cc: Handle tolower and toupper here.
+	* mappers.h: Rename can_return_complex_for_real to flag and
+	overload meaning for ch_mapper.
+	* pt-fvc.cc (apply_mapper_fcn): Handle overloaded meaning.
+
+	* syscalls.cc (stat): Return 3 values instead of just 1.
+	(lstat): Likewise.
+
+Wed May 22 02:34:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-const.cc (OCT_VAL_REP::make_numeric): For string to number
+	conversions, correctly set type tag before calling force_numeric.
+	(do_binary_op): Force string to number conversion if both args are
+	strings and we are doing some sort of comparison operation.
+
+	* Makefile.in (stamp-tinst, stamp-interp): Use SH_TERMLIBS and
+	SH_LIBS instead of TERMLIBS and LIBS.
+
+	* pt-const.cc (do_unary_op): Add special case to handle
+	transposing strings.
+
+	* pt-mat.cc (Vstring_fill_char): New variable.
+	(symbols_of_pt_mat): DEFVAR it.
+
+	* input.cc (generate_struct_completions,
+	generate_possible_completions):	Return string_vector, not char **.
+	Change all callers.
+
+	* pt-const.cc (lookup_map_element): Use substr() correctly.
+
+Tue May 21 21:37:17 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+	* octave.cc: New args --no-site-file and --no-init-file.  Delete
+	--ignore-init-file.  The flag --norc (-f) implies both
+	--no-site-file and --no-init-file.
+
+Fri May 17 01:54:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (Fcompletion_matches): New function.
+
+	* utils.cc (get_fcn_file_names): Delete.
+	* help.cc (simple_help): Use new file name cache instead of
+	calling get_fcn_file_names.
+	* variables.cc (make_name_list): Likewise.
+
+	* fn-cache.h, fn-cache.cc, Map-fnc.cc: New files.
+	* Makefile.in: Add them to the lists.
+
+	* Makefile.in (uninstall): Install in octincludedir, not includedir.
+
+	* pt-plot.h: Include <csignal> here.
+
+Thu May 16 10:52:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (octave_stream::oscanf, octave_base_stream::oscanf,
+ 	octave_base_stream::do_oscanf): New functions for backward
+	compatibility with older versions of Octave.
+	(scanf_format_elt, scanf_format_list): Keep track of width specifier.
+	* file-io.cc (Fscanf): New function.
+	(Fscanf, Ffscanf, Fsscanf): Handle compatibility arg.
+
+Wed May 15 01:00:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-stream.cc (do_scanf): If doing '%c' conversion, unset
+	ios::skipws on input stream.
+
+	* sighandlers.h, sighandlers.cc (octave_child, octave_child_list):
+	New classes for keeping track of the child processes we create.
+	(sigchld_handler): Check in octave_child_list to see if there is
+	anything we can do for the child that died.
+	* pager.cc: Register child pager process.
+	* pt-plot.cc: Likewise, for the plotter.
+	* Array-oc.cc: New file
+	* Makefile.in (TI_SRC): Add it to the list.
+
+	* pager.cc (do_sync): Don't check error_state.
+	(flushing_output_to_pager): New static variable.
+	(flush_octave_stdout): Use it to avoid doing anything if already
+	flushing output.
+
+	* sighandlers.cc (sigchld_handler): Call warning instead of
+	writing directly to cerr.
+	(sigpipe_handler): Call warning instead of message.
+
+	* octave.cc (main): Call install_signal_handlers,
+	initialize_file_io, initialize_symbol_tables, and install_builtins
+	before parsing command line options.
+
+	* user-prefs.h, user-prefs.cc: Delete.
+
+	* utils.cc (check_preference): Move here.
+	* user-prefs.cc: From here.
+
+	* defaults.cc: New file.  Move initialization stuff from
+	variables.cc.  Move DEFVARS for EDITOR, EXEC_PATH, LOADPATH,
+	IMAGEPATH, and OCTAVE_VERSION here.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	INFO_FILE and INFO_PROGRAM.
+	* help.cc: Move all of that here.
+	(symbols_of_help): Add DEFVARS for INFO_FILE and INFO_PROGRAM.
+
+Tue May 14 00:23:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pager.cc (do_sync): Be more defensive about sending stuff to the
+	external pager.
+	* sighandlers.cc (sigchld_handler): For now, only wait for
+	octave_pager_pid.  Don't call error().  Do set octave_pager_pid to
+	-1 if the pager process no longer exists.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	PWD.
+	* dirfns.cc: Move all of that here.
+	(symbols_of_dirfns): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	default_save_format and save_precision.
+	* load-save.cc: Move all of that here.
+	(symbols_of_load_save): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	warn_divide_by_zero.
+	* arith-ops.cc: Move all of that here.
+	(symbols_of_arith_ops): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* mappers.cc: Add wrappers for ctype is* functions so that they
+	will work on systems that only define them as macros.
+
+Mon May 13 00:27:08 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	suppress_verbose_help_message.
+	* help.cc: Move all of that here.
+	(symbols_of_help): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	treat_neg_dim_as_zero.
+	* pt-const.cc: Move all of that here.
+
+	* pager.cc (octave_pager_stream::do_sync): Don't return early if
+	not interactive.
+
+	* data.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* data.cc (symbols_of_data): New function.  Move definition of I,
+	Inf, J, NaN, e, eps, i, inf, j, nan, pi, realmin, and realmax here.
+	* variables.cc: From here.
+	(install_builtin_variables): Call symbols_of_data.
+
+	* file-io.cc (symbols_of_file_io): New function.  Move definition
+	of SEEK_CUR, SEEK_END, SEEK_SET, stdin, stdout, stderr here.
+	* variables.cc: From here.
+	(install_builtin_variables): Call symbols_of_file_io.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	do_fortran_indexing, implicit_str_to_num_ok,
+	ok_to_lose_imaginary_part, prefer_column_vectors,
+	prefer_zero_one_indexing, print_answer_id_name,
+	propagate_empty_matrices, resize_on_range_error, and
+	struct_levels_to_print.
+	* pt-const.cc: Move all of that here.
+	(symbols_of_pt_const): New function.
+	* variables.cc (install_builtin_variables): Call it.
+	* pt-fvc.cc (tree_identifier::assign): Use Vresize_on_range_error
+	instead of user_pref.resize_on_range_error here.
+	* load-save.cc (save_mat_binary_data): Use Vimplicit_str_to_num_ok
+	instead of user_pref.implicit_str_to_num_ok here.
+	* utils.cc (empty_arg): Use Vpropagate_empty_matrices instead of
+	user_pref.propagate_empty_matrices here.
+	* pt-exp-base.cc (tree_expression::is_logically_true): Likewise..
+
+	* pt-fcn.cc (symbols_of_pt_fcn): Also move DEFVAR for
+	default_return_value here.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	ps1, ps2, ps4, and completion_append_char.
+	* input.cc: Move all of that here.
+	(symbols_of_input): New function.
+	* variables.cc (install_builtin_variables): Call it.
+	* pt-pr-code.cc (indent): Use Vps4 instead of user_pref.ps4 here.
+	* help.cc (Ftype): Also here.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	automatic_replot, gnuplot_binary, and gnuplot_has_multiplot.
+	* pt-plot.cc: Move all of that here.
+	(symbols_of_pt_plot): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	beep_on_error.
+	* error.cc: Move all of that here.
+	(symbols_of_error): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	empty_list_elements_ok.
+	* pt-mat.cc: Move all of that here.
+	(symbols_of_pt_mat): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	define_all_return_values, return_last_computed_value, and
+	silent_functions.
+	* pt-fcn.cc: Move all of that here.
+	(symbols_of_pt_fcn): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	whitespace_in_literal_matrix.
+	* lex.l: Move all of that here.
+	(symbols_of_lex): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	warn_assign_as_truth_value, warn_comma_in_global_decl,
+	warn_function_name_clash, and warn_missing_semicolon.
+	* parse.y: Move all of that here.
+	(symbols_of_parse): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	output_precision, output_max_field_width, print_empty_dimensions,
+	and split_long_rows.
+	* pr-output.cc: Move all of that here.
+	(symbols_of_pr_output): New function.
+	* variables.cc (install_builtin_variables): Call it.
+
+	* user-prefs.h, user-prefs.cc: Delete all stuff related to
+	page_screen_output, page_output_immediately, and pager_binary.
+	* pager.cc: Move all of that here.
+
+	* user-prefs.h (check_preference): Provide declaration.
+	* user-prefs.cc (check_preference): Make external.
+
+	* toplev.cc (Foctave_config_info): New function.
+
+	* oct-conf.h.in: New file
+	* Makefile.in (oct-conf.h): New target.
+	Add it to the appropriate lists.
+
+	* sighandlers.cc (sigchld_handler): Don't complain about wait
+	returning a negative value.
+
+	* file-io.cc (Fsscanf, Fsprintf): Pass true for second arg of
+	octave_stream constructor.
+
+	* oct-stream.h (octave_stream): New field, preserve.
+	(octave_stream::~octave_stream): If preserve, don't delete rep.
+
+	* pager.cc (symbols_of_pager): Set default for
+	page_output_immediately to 0.
+
+	* toplev.cc (do_system): Correctly handle return_output.
+	Append ends to output_buf before calling str().
+
+	* variables.cc: If M_PI and M_E are available, use them.
+
+	* mk-oct-links.in (links_dir): If old link exists, delete it first.
+
+Sun May 12 01:46:07 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (DISTFILES): List defaults.h.in and oct-gperf.h here.
+	(INCLUDES): Not here.
+	(install-inc): New target.
+	(uninstall): Also delete libraries and include files.
+	(install-inc): If linkdir is a directory, leave it alone.
+	(TERMLIBS, LIBPLPLOT, LIBDLFCN): Don't substitute here (now in
+	Makeconf).
+
+	* oct-stream.cc (octave_base_stream::do_read): Provide initial
+	value for tmp var.
+
+	* pt-walk.h, pt-pr-code.h, pt-pr-code.cc: New tree-walking classes.
+	* Makefile.in: Add them to the appropriate lists.
+	* pt-fvc-base.h, pt-exp-base.cc, pt-fvc-base.cc, pt-mvr-base.cc,
+	pt-base.cc, pt-mvr.cc, pt-mat.h, pt-mat.cc, pt-fvc.cc,
+	pt-const.cc, pt-cmd.cc, pt-const.h, pt-misc.cc, pt-plot.cc,
+	pt-fcn.cc, pt-plot.h, pt-mvr.h, pt-mvr-base.h, pt-misc.h,
+	pt-fcn.h, pt-exp.h, pt-exp.cc, pt-exp-base.h, pt-fvc.h, pt-cmd.h,
+	pt-base.h:
+	Replace print_code stuff with accept() functions.
+	Add member access functions where necessary.
+	* help.cc (Ftype): Update to use new method of walking trees to
+	print text representation of user-defined functions.
+
+	* file-io.cc (Ffscanf): Update doc string.
+	(Fsscanf): Likewise.
+
+	* oct-stream.cc (octave_base_stream::do_read): Correctly set max_size.
+	Pad mval with zeros on final resize.
+	(octave_base_stream::do_scanf): Likewise.
+	(do_scanf_conv): Correctly resize mval.
+	
+Sat May 11 05:14:09 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pager.cc (octave_pager_buf::sync): Correctly set bypass_pager.
+
+	* lex.l (<MATRIX>{SNLCMT}*\]{S}*): Match SNLCMT, not just SNL.
+
+Fri May  3 11:05:30 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-const.cc (OCT_VAL_REP::set_index): Complain if type can't be
+	indexed.
+
+	* input.cc (get_user_input): Don't increment input line number if
+	input is coming from eval string.
+
+	* user-prefs.cc: Allow empty strings for prompts.
+
+Thu May  2 10:50:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-mvr.h (class tree_oct_obj): Declare values data member const.
+
+Sun Apr 28 03:16:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* user-prefs.h (user_preferences): New field,
+	`page_output_immediately'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(page_output_immediately): New function.
+	* pager.cc (syms_of_pager): Add DEFVAR.
+	(really_flush_to_pager): New file-scope variable.
+	(flush_octave_stdout): Set and restore it.
+	(octave_pager_buf::sync): Check it, user_pref.page_screen_output,
+	and user_pref.page_output_immediately to decide when to really
+	flush output.
+	(more_than_a_screenful): New function.  If paging but not
+	immediately, then check this too.
+
+	* pager.cc (default_pager): Move here from variables.cc.  If pager
+	is less and LESS is not in the environment, append useful flags.
+	(symbols_of_pager): New function.
+	* variables.cc (install_builtin_variables): Call it.
+	Delete pager-related DEFVARs.	
+
+	* syswait.h (WIFSIGNALLED): Define if sys/wait.h doesn't.
+
+	* sighandlers.cc: Handle SIGCHLD.
+
+	* pager.cc, pager.h: Rewrite.
+	* pt-mvr.cc, pt-misc.cc, pt-fcn.cc, pt-const.cc, oct-hist.cc,
+	file-io.cc, help.cc, variables.cc, qpsol.cc, dassl.cc, quad.cc,
+	npsol.cc, lsode.cc, fsolve.cc, load-save.cc, dirfns.cc, octave.cc,
+	toplev.cc, error.cc, input.cc:
+	Write to octave_stdout and octave_diary instead of calling
+	maybe_page_output() or maybe_write_to_diary_file().
+
+	* oct-procbuf.h, oct-procbuf.cc: New files.
+	* procstream.h (class procstreambase): Use octave_procbuf instead
+	of procbuf from libg++, so we can get pids of subprocesses.
+
+Fri Apr 26 01:21:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-const.cc (OCT_VAL_REP::do_index): Call maybe_mutate() before
+	returning.
+
+	* mappers.h (struct Mapper_fcn): Delete.
+	(struct builtin_mapper_function): New field ch_mapper.
+	* pt-fvc.h (tree_builtin): Convert type of mapper_fcn from
+	Mapper_fcn to builtin_mapper_function.
+	* variables.cc (install_builtin_mapper): Likewise, for arg.
+	Simplify, since we don't have to do the copying ourselves now.
+	* pt-fvc.cc (apply_mapper_function): Handle ch_mapper case.
+	* defun.h (DEFUN_MAPPER): Likewise.
+	* mappers.cc (install_builtin_mappers): Likewise.
+	Add ctype is* functions here.
+
+Thu Apr 25 00:57:06 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* arith-ops.h, defun-int.h, defun.h, dynamic-ld.h, gripes.h,
+	load-save.h, oct-map.h, oct-obj.h, oct-stream.h, pt-cmd.h,
+	pt-const.h, pt-exp-base.h, pt-exp.h, pt-fcn.h, pt-fvc-base.h,
+	pt-fvc.h, pt-mat.h, pt-misc.h, pt-mvr-base.h, pt-mvr.h, pt-plot.h,
+	symtab.h, toplev.h, utils.h, variables.h, xpow.h, Array-tc.cc,
+	Map-i.cc, Map-tc.cc, SLList-tc.cc, arith-ops.cc, balance.cc,
+	bogus.cc, chol.cc, colloc.cc, dassl.cc, data.cc, det.cc,
+	dirfns.cc, eig.cc, error.cc, expm.cc, fft.cc, fft2.cc, file-io.cc,
+	filter.cc, find.cc, fsolve.cc, fsqp.cc, givens.cc, gripes.cc,
+	help.cc, hess.cc, ifft.cc, ifft2.cc, input.cc, inv.cc,
+	load-save.cc, log.cc, lpsolve.cc, lsode.cc, lu.cc, minmax.cc,
+	npsol.cc, oct-hist.cc, oct-obj.cc, oct-stream.cc, pager.cc,
+	pinv.cc, pr-output.cc, pt-cmd.cc, pt-const.cc, pt-exp-base.cc,
+	pt-exp.cc, pt-fcn.cc, pt-fvc-base.cc, pt-fvc.cc, pt-mat.cc,
+	pt-misc.cc, pt-mvr-base.cc, pt-mvr.cc, pt-plot.cc, qpsol.cc,
+	qr.cc, quad.cc, qzval.cc, rand.cc, resource.cc, schur.cc, sort.cc,
+	strfns.cc, svd.cc, syl.cc, symtab.cc, syscalls.cc, sysdep.cc,
+	timefns.cc, toplev.cc, utils.cc, variables.cc, xpow.cc, parse.y:
+	Rename tree_constant -> octave_value.
+	Rename Octave_object -> octave_value_list.
+
+Wed Apr 24 22:15:34 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (Fsystem): Merge functionality of async_system and
+	sync_system.
+
+	* oct-fstrm.h, oct-iostrm.h, oct-prcstrm.h, oct-stdstrm.h,
+	oct-stream.h, oct-strstrm.h, oct-fstrm.cc, oct-iostrm.cc,
+	oct-prcstrm.cc, oct-stdstrm.cc, oct-stream.cc, oct-strstrm.cc,
+	Array-os.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	* file-io.cc: Rewrite to use new stream classes.
+
+Tue Apr 23 18:59:25 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* gripes.cc (gripe_not_supported): New function.
+
+	* toplev.cc (do_octave_atexit, Fatexit): New functions.
+	(octave_atexit_functions): New file-scope variable.
+	* octave.cc (main): Register do_octave_atexit with atexit.
+
+	* variables.cc (install_builtin_variables): Call
+	symbols_of_syscalls here.
+
+	* syscalls.h, syscalls.cc: New files.
+
+Mon Apr 22 21:14:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* syscalls.cc: New file.
+	(Flstat, Fmkfifo, Fstat, Funlink, Fwait, Fwaitpid): Move here.
+	* file-io.cc: From here.
+	* Makefile.in (SOURCES): Add syscalls.cc to the list.
+
+Wed Apr 17 18:34:10 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-info.h, file-info.cc: Delete files.
+	* Makefile.in: Remove from lists.
+
+	* toplev.cc (Fquit): Accept exit status argument.
+	(Fflops): Delete (now a function file).
+
+Thu Apr 11 16:20:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l: Recognize `.'.
+	Update current_input_column even for unrecognized characters.
+	Return LEXICAL_ERROR for unrecognized characters.
+
+Mon Apr  8 19:59:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (install_builtin_variables): Split into several
+	functions to make compiling with g++ go faster and consume less
+	memory.
+	
+Sun Apr  7 16:25:35 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (Fsave): Print usage if i == argc.
+	(Fload): Likewise.	
+
+Sat Apr  6 21:26:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (clean): Also delete pic/*.o
+	(maintainer-clean, distclean): Also remove stamp-picdir,
+	stamp-tinst, stamp-interp, and pic directory.
+	(stamp-prereq): New target.
+
+Wed Apr  3 11:19:30 1996  Rick Niles  <niles at axp745.gsfc.nasa.gov>
+
+	* resource.cc: Don't make including sys/resource.h and sys/times.h
+	mutually exclusive.
+
+Fri Mar 29 13:43:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (distclean): Delete so_locations, which is created
+	on DEC Alpha systems.
+
+Thu Mar 28 02:53:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.h (undo_string_escape): Provide extern declaration here.
+
+	* lex.l (NL): Allow \r\n as new line character.
+	(.): Complain if invalid character is found on input
+
+Fri Mar 22 03:47:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* resource.cc (getrusage): If getrusage is missing, try using
+	times to at least fill in the cpu time values.  If neither one is
+	available, return 0 for cpu times instead of NaN.
+	
+	* sighandlers.cc (octave_signal_mask): New file-scope variable.
+	(octave_save_signal_mask, octave_restore_signal_mask): New functions.
+	* toplev.cc (main_loop): Use them.
+
+Wed Mar 20 01:21:28 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (get_fcn_file_names (const string&, int)): Resize
+	retval to value of k, not i.
+	(get_fcn_file_names (int)): In loop for copying names to retval,
+	don't increment j twice.
+
+Mon Mar 18 22:27:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in ($(MAKEDEPS)): Depend on oct-gperf.h.
+
+Fri Mar  1 18:15:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* fsolve.cc (fsolve_options): Delete unused argument nargout.
+
+	* filter.cc: Use MArray instead of Array so that automatic
+	conversions will work again.
+
+Tue Feb 27 04:49:51 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (looks_like_octave_copyright): Make the strings
+	that we are trying to match both have length 29.
+
+	* Makefile.in (install-bin): Use $(INSTALL_PROGRAM), not $(INSTALL).
+
+	* load-save.cc (read_mat_binary_data): Make sure name is
+	NUL terminated.
+
+Mon Feb 26 18:18:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (whos): Make argv from tmp_args, not args.
+
+	* defun.h (DEFCONSTX): Don't stringify name.
+
+Sat Feb 24 01:12:59 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-oct): Make mk-oct-links executable.
+	* mk-oct-links.in (links_dir): Update to match new format of
+	DEFUN_DLD_BUILTIN macro.  Use LN_S, not just LN.
+	(links_dir): 
+
+	* pr-output.cc (octave_print_internal): New arg, extra_indent, for
+	versions of this function that take matrices and ranges.
+	* pt-const.cc (TC_REP::print (ostream&)): Fix printing of structures.
+	Pass struct_indent to octave_print_internal as appropriate.
+	(print_with_name (ostream&, const string&, bool)): Handle spacing
+	around `=' differently for structures.
+
+Fri Feb 23 04:51:04 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* token.cc (token (double, const string&, int, int)): Store orig_text.
+
+Tue Feb 20 20:36:01 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fclear): Fix off-by-one error.
+
+Sat Feb 17 16:54:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-hist.cc (default_history_file): Append "/.octave_hist" to
+	return value, not to home_directory.
+
+Fri Feb 16 18:10:46 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc: (NINT, D_NINT): Move to liboctave.
+
+	* sysdep.cc (octave_ieee_init): Move to liboctave.
+
+	* procstream.h, procstream.cc: Rewrite.
+
+	* pager.cc (cleanup_oprocstream): New static function.
+	* toplev.cc (cleanup_iprocstream): Likewise.
+	* dirfns.cc (cleanup_iprocstream): Likewise.
+
+	* unwind-prot.cc (matrix_cleanup, complex_matrix_cleanup): Delete.
+
+Thu Feb 15 22:03:28 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-obj.cc, oct-obj.h: Move most code to the header.
+
+	* oct-obj.cc (make_argv, all_strings): New member functions.
+	* utils.cc: Moved from here.
+
+	* load-save.cc: Move byte swapping stuff to liboctave.
+	Move float format conversion stuff to liboctave.
+	(all_parts_int, too_large_for_float): Move to liboctave.
+
+	* symtab.cc (valid_identifier): Move here.
+	* load-save.cc: From here.
+
+	* sysdep.cc: Move floating-point format stuff to liboctave.
+	* pr-output.cc: Include float-fmt.h here.
+
+Wed Feb 14 01:49:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun.h, defun-dld.h, defun-int.h: Simplify interface for DEFUN,
+	DEFUN_DLD, DEFVAR, and DEFCONST macros.  Change all uses.
+
+	* qzval.cc: Move guts to liboctave.
+
+Tue Feb 13 10:28:27 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (parse_fcn_file): Also avoid saving history if
+	input is from a script file.
+
+	* help.cc (Ftype): Call unwind_protect_str for user_pref.ps4.
+
+	* npsol.cc (nonlinear_constraints_ok): Now static.
+
+	* npsol.cc (linear_constraints_ok): Now static.
+	* qpsol.cc (linear_constraints_ok): Duplicate here.
+
+	* data.cc (Flinspace): Don't print usage message if nargin == 2.
+
+Sun Feb 11 14:20:32 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-oct-links.in: Rename from mk-oct-links.
+	(LN_S): Use this variable instead of ln.
+	Set -e option for shell.
+	Exit with status of last command.
+	Print message when making link.
+	* Makefile.in (DISTFILES): Add mk-oct-links.in to the list.
+	(install-oct): Run ./mk-oct-links, not $(srcdir)/mk-oct-links.
+
+	* variables.cc (install_builtin_variables): Restore accidentally
+	deleted DEFVAR for save_precision.
+
+Fri Feb  9 11:24:32 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES): Delete statdefs.h from the list (it's
+	now in the liboctave directory).
+
+	* toplev.cc (toplevel): Define here.
+	* octave.cc (toplevel): Not here.
+
+	* toplev.cc (main_loop): New function.
+	* octave.cc (main): Call it here instead of doing main loop
+	actions here.
+
+	* user-prefs.cc (do_fortran_indexing): Also set liboctave_dfi_flag.
+	(prefer_column_vectors): Also set liboctave_pcv_flag.
+	(prefer_zero_one_indexing): Also set liboctave_pzo_flag.
+	(resize_on_range_error): Also set liboctave_rre_flag.
+
+	* variables.cc (restore_command_history): New function.
+	(parse_fcn_file): Use it here in unwind_protect.
+
+	* dynamic-ld.cc (load_octave_oct_file): Reverse sense of test.
+	(load_octave_builtin): Delete.
+	(mangle_octave_oct_file_name): Delete.
+
+	* pt-fvc.cc (tree_builtin::eval): Don't try to dynamically load
+	functions here.
+
+	* pr-output.cc (set_format_style): Decrement argc for first arg too.
+	
+	* input.cc (gnu_readline): If readline returns an empty string,
+	convert it to a string containing a single newline character.
+
+	* octave.cc (octave_argv): Now a static string_vector.
+	(intern_argv): Use string_vector ops, not charMatrix ops.
+	* toplev.cc (octave_argv): Delete definition.
+	* toplev.h (octave_argv): Delete declaration.
+
+Thu Feb  8 10:58:24 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (conf-dist): New target.
+
+Tue Feb  6 10:59:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (Ftype): Correctly handle structure names.
+
+Sun Feb  4 02:02:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* qpsol.cc (Fqpsol): Call set_options(), not copy() to set
+	options for QPSOL objects.
+
+	* npsol.cc (Fnpsol): Call set_options(), not copy() to set
+	options for NPSOL objects.
+
+	* quad.cc (Fquad): Call set_options(), not copy() to set
+	options for Quad objects.
+
+	* dynamic-ld.cc (load_octave_builtin): Don't call destructor on string.
+	(load_octave_oct_file): Likewise.
+	Check oct_file.empty(), not just oct_file.
+
+	* fsolve.cc (Ffsolve): Call set_options(), not copy() to set
+	options for NLEqn object.
+
+	* variables.cc (do_who): Properly set match patterns from argument
+	vector for call to maybe_list.
+
+Sat Feb  3 03:29:33 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (long_opts): Properly set second field using new enum.
+
+	* lsode.cc: Change ODE to LSODE where appropriate.
+	Use LSODE_options, not ODE_options.
+
+	* dassl.cc: Change DAE to DASSL where appropriate.
+	Use DASSL_options, not ODE_options.
+
+Fri Feb  2 01:41:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc: Include unistd.h.
+
+	* parse.y, lex.l: Handle matrix lists without ml or mlnm stacks.
+	* pt-mat.h, pt-mat.cc (tree_matrix):
+	Rewrite to use SLList instead of home brew list.
+	* SLList-tm.cc: New file
+	* Makefile.in: Add it to the lists.
+	* SLStack-tm.cc: Delete.
+	* Makefile.in: Delete it from the lists.
+
+	* All pt-* files: Use bool instead of int where appropriate.
+
+	* Makefile.in (DEP_SOURCES_3): Add octave.cc.
+
+	* pt-const.h (class tree_constant::tree_constant_rep): Make
+	everything in this class public, then it doesn't need to declare
+	the tree_constant class as a friend.
+
+Thu Feb  1 01:42:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.h, lex.l, parse.h, parse.y (class lexical_feedback): New
+	class for lexer flags.  Replace lots of global vars with members
+	of this class.
+
+	* lex.l (class brace_paren_nesting_level): New class to replace
+	nesting_level stack.  nesting_level is now an instance of this
+	class.
+
+	* lex.l (yum_yum): New typedef.
+	(ATE_NOTHING): New global var.
+	(ATE_SPACE_OR_TAB, ATE_NEWLINE): Don't #define these, declare them
+	as const yum_yum.
+	(eat_whitespace, eat_continuation): Return yum_yum, not int.
+
+	* lex.l (SHORT_CIRCUIT_LOGICALS): Delete.  Always do this for ||
+	and && tokens.
+	(yy_flex_alloc, yy_flex_realloc, yy_flex_free, next_char_is_space):
+	Delete.
+
+	* toplev.cc (verbose_flag): Delete definition.
+	* toplev.h (verbose_flag): And declaration.
+	* octave.cc (verbose_flag): Now static.
+
+	* lex.l (lookup_identifier): Arg is now string, not char*.
+	(handle_identifier, is_plot_keyword, is_keyword): Likewise.
+	(strip_trailing_whitespace): Return value is now string, not char*.
+	(plot_style_token): Likewise, for both arg and return value.
+
+	* input.cc (octave_gets_line): Delete.
+	(gnu_readline, octave_gets, octave_read):
+	Properly handle input when using_readline is either true or false.
+	Don't limit length of input lines to flex buffer size.
+	(get_user_input): New function.
+
+	* octave.cc (main): Handle --no-line-editing.
+	* toplev.h (using_readline): Provide external declaration here.
+	* input.h: Not here.
+	* toplev.cc (using_readline): Define here.
+	* input.cc: Not here.
+
+	* toplev.h (no_line_editing): Delete declaration.
+	* input.cc (no_line_editing): Delete definition.
+
+Wed Jan 31 05:28:45 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* input.cc (DEFAULT_ARRAY_SIZE, PROMPT_GROWTH): Delete definitions
+	of unused macros.
+	(read_octal): Now static.
+
+	* givens.cc (Fgivens): Use new functions from matrix classes
+	instead of calling Fortran functions directly.
+	* syl.cc (Fsyl): Likewise.
+	* expm.cc (Fexpm): Likewise.
+
+Mon Jan 29 00:00:48 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc: Use new prog_args class instead of calling getopt
+	directly.
+
+	* getopt.h, getopt.c, getopt1.c: Move to liboctave directory.
+	* Makefile: Remove from lists.
+
+	* utils.cc (strconcat, read_until, discard_until): Delete.
+
+	* pager.cc (terminal_columns, terminal_rows): Move to
+	liboctave/oct-term.cc.
+	* pager.cc, pr-output.cc: Include oct-term.h.
+
+	* utils.cc (list_in_columns): Moved to liboctave/str-vec.cc.
+	Change all callers to use new member function syntax.
+
+	* dirfns.cc (absolute_program): Now static.
+	(absolute_pathname): Delete.
+
+	* pt-plot.cc (save_in_tmp_file): Call oct_tempnam, not
+	octave_tmp_file_name.  Include file-ops.h.	
+	* file-io.cc (do_scanf, Foctave_tmp_file_name): Likewise.
+	* oct-hist.cc (mk_tmp_hist_file): Likewise.
+
+	* file-io.cc (Foctave_tmp_file_name): Move here.
+	* utils.cc: From here.
+
+	* utils.cc (octave_tmp_file_name): Move to liboctave/file-ops.cc.
+
+	* tempname.c, tempnam.c: Move to liboctave directory.
+	* Makefile.in: Remove from lists.
+
+Sun Jan 28 19:00:52 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xdiv.cc (all xdiv functions): Return Matrix or ComplexMatrix,
+	not tree_constant.
+
+	* oct-hist.h, oct-hist.cc, toplev.cc, octave.cc, input.cc,
+	file-io.cc, user-prefs.cc: Rewrite to use new command_history
+	class instead of calling readline history functions directly.
+
+	* utils.cc (get_fcn_file_names): Delete num arg.
+
+Thu Jan 25 20:33:54 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (matches_patterns): Use new glob_match class
+	instead of calling fnmatch directly.
+	* symtab.cc (matches_patterns, symbol_table::glob): Likewise.
+	* variables.cc (Fclear): Likewise.
+
+Wed Jan 24 02:05:22 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* fnmatch.h fnmatch.c: Delete.
+	* Makefile.in: Add glob stuff in the appropriate places, remove
+	fnmatch.h and fnmatch.c from lists.
+
+	* octave.cc (program_invocation_name, program_invocation_short_name):
+	Maybe declare.
+	(initialize_globals): Maybe initialize them.
+
+	* octave.cc (initialize_pathsearch): Define here, not in pathsearch.cc.
+	* pathsearch.h, pathsearch.cc: Remove files.
+	* Makefile.in: Remove them from the lists.
+	
+	* help.cc (simple_help): Ignore directories that don't have any .m
+	or .oct files.
+
+	* utils.cc (search_path_for_file): Use new dir_path class instead
+	of calling kpathsea routines directly.
+	(get_fcn_file_names): Likewise.
+	* help.cc (simple_help): Likewise.
+
+	* dirfns.cc (make_absolute): Don't convert empty arg to "./".
+
+	* sysdir.h: Move to liboctave directory.
+	* Makefile.in: Remove from lists.
+
+	* dirfns.cc (Freaddir): Use new dir_entry class instead of calling
+	readdir directly.  Include dir-ops.h, not sysdir.h.
+	* utils.cc (get_fcn_file_names): Likewise.  Delete unnecessary
+	first arg, change all callers.
+
+Tue Jan 23 00:43:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* safe-xstat.hin, safe-xstat.cin, statdefs.h, file-ops.h,
+	file-ops.cc, filemode.c, mkdir.c, rmdir.c, rename.c:
+	Files moved to liboctave directory.
+	* Makefile.in: Remove them from lists.  Move appropriate rules.
+
+	* acosh.c, asinh.c, atanh.c, erf.c, erfc.c, gamma.c, lgamma.c:
+	Files moved to liboctave directory.
+	* Makefile.in: Remove them from lists.
+	* missing-math.h: Deleted.
+	* pr-output.cc, sysdep.cc, minmax.cc, mappers.cc, expm.cc,
+	arith-ops.cc: Include oct-math.h, not cmath or missing-math.h.
+
+Mon Jan 22 19:33:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (Fexist): Use file_stat instead of calling stat
+	directly.  Include file-ops.h, not statdefs.h.
+	* octave.cc (execute_startup_files): Likewise.
+	* file-io.cc (file_io_get_file, fopen_internal, popen_internal, Fstat):
+	Likewise.
+	(mk_stat_map): Likewise, use file_stat object, not struct stat.
+	* oct-hist.cc (do_history): Likewise.
+
+	* file-ops.h, file-stat.cc: New files.
+	* Makefile.in: Include them.
+	* dirfns.cc: Delete is_newer.  Don't include statdefs.h.
+	* toplev.cc: Don't include statdefs.h.
+
+Sun Jan 21 22:48:03 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-mvr.h, pt-fvc.h, Map.cc, Map.h, dynamic-ld.h,
+	pt-fvc-base.cc, SLList-str.cc, pt-fcn.h, pt-fvc-base.h,
+	SLStack-str.cc, pt-mvr.cc, pt-exp.cc, token.h, token.cc,
+	user-prefs.h, pt-base.cc, user-prefs.cc, dirfns.h, sysdep.h,
+	sysdep.cc, input.h, parse.h, lex.l, parse.y, defun.h, mappers.h,
+	pt-fvc.cc, pt-plot.h, load-save.h, octave.cc, defun-int.h, help.h,
+	variables.h, oct-map.h, oct-obj.h, oct-obj.cc, pt-const.cc,
+	oct-map.cc, input.cc, symtab.h, pt-const.h, pathsearch.cc,
+	pr-output.h, pr-output.cc, toplev.h, timefns.cc, schur.cc,
+	pt-plot.cc, pager.cc, load-save.cc, dynamic-ld.cc, dirfns.cc,
+	data.cc, file-info.h, file-info.cc, colloc.cc, utils.h, qpsol.cc,
+	quad.cc, npsol.cc, lsode.cc, fsolve.cc, dassl.cc, file-io.cc,
+	help.cc, utils.cc, oct-hist.h, oct-hist.cc, symtab.cc, toplev.cc,
+	pt-fcn.cc, unwind-prot.h, unwind-prot.cc, variables.cc:
+	Most functions in these files that deal with character strings
+	have been converted to use the string class insatead of char*.  If
+	you want more detailed information, you'll have to figure it out
+	for yourself.
+
+Sat Jan 20 18:19:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc [WITH_DL]: Define RTLD_LAZY to be 1 if it is not
+	already defined.
+
+Sun Jan 14 07:48:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pt-const.cc (print_as_scalar, print_as_structure):
+	Make these member functions.
+	(tree_constant::print_with_name): New function, moved here from
+	old tree-expr.cc file (where it was called print_constant) and
+	converted to member function.  Change all callers.
+
+Fri Jan 12 01:54:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (initialize_globals): Don't do kpathsearch stuff here.
+	(main): Call initialize_pathsearch() here.
+	
+	* pathsearch.cc: New file.
+	* Makefile.in (SOURCES): Add it to the list
+
+	* oct-hist.h: Rename from octave-hist.h.
+	* oct-hist.cc: Rename from octave-hist.cc.
+	* Makefile.in, parse.y, other .cc files: Cope with it.
+
+	* dynamic-ld.cc: Avoid warnings if !WITH_DYNAMIC_LINKING.
+
+	* load-save.cc (save_ascii_data): string::data() returns const char*.
+
+	* utils.h: Don't provide forward declaration for tree_constant.
+
+	* oct-obj.h: Don't include mx-base.h or provide forward
+	declarations for Matrix and Range types.
+
+	* file-info.h: Don't include oct-obj.h.  Do include cstdio.
+
+	* symtab.h: Don't provide forward declaration for ostream.
+
+	* variables.h: Don't provide forward declarations for istream,
+	ostrstream, tree, builtin_function, or builtin_variable objects.
+
+	* balance.cc, chol.cc, colloc.cc, dassl.cc, det.cc, eig.cc,
+	expm.cc, fft.cc, fft2.cc, filter.cc, find.cc, fsolve.cc, fsqp.cc,
+	givens.cc, hess.cc, ifft.cc, ifft2.cc, inv.cc, log.cc, lpsolve.cc,
+	lsode.cc, lu.cc, minmax.cc, npsol.cc, pinv.cc, qpsol.cc, qr.cc,
+	quad.cc, qzval.cc, rand.cc, schur.cc, sort.cc, svd.cc, syl.cc:
+	Clean up #include statements.
+
+	* pt-const.h: Don't include oct-obj.h or tree-base.h.
+	Provide forward declaration of Octave_object here.
+	* pt-const.cc: Include oct-obj.h here.
+
+	* pt-mat.h, pt-fcn.h, pt-const.h, pt-misc.h, pt-plot.h,
+	pt-exp-base.h, pt-cmd.h, pt-fvc-base.h, pt-mvr-base.h, pt-exp.h,
+	pt-mvr.h, pt-fvc.h: New files, split from tree-expr.h and/or
+	renamed from other tree-*.h files (pt == parse tree).
+	* pt-base.cc, pt-const.cc, pt-exp.cc, pt-fvc-base.cc, pt-mat.cc,
+	pt-mvr-base.cc, pt-plot.cc, pt-cmd.cc, pt-exp-base.cc, pt-fcn.cc,
+	pt-fvc.cc, pt-misc.cc, pt-mvr.cc: Likewse, split from tree-expr.cc
+	and/or other tree-*.cc files.
+	* Makefile.in: Include them in the appropriate lists.
+	* All: Fix #include statements to match.
+
+	* Array-tc.cc: Don't instantiate ArrayRep objects.
+
+Thu Jan 11 02:35:19 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.cc (tree_constant::eval (int, int, const Octave_object&)):
+	Define here instead of in tree-const.h.
+
+Wed Jan 10 04:34:20 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.h (tree_constant::tree_constant (const string&):
+	* tree-const.cc (TC_REP::tree_constant_rep (const string&)):
+	New constructor.
+
+Tue Jan  9 04:10:29 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* rand.cc (do_rand): Use string_value() result directly instead of
+	c_str() conversion.
+	* balance.cc (Fbalance): Likewise.
+
+	* tree-const.cc (TC_REP::string_value()):
+	Handle new definition of charMatrix::row_as_string()
+	* load-save.cc (save_ascii_data): Ditto.
+	(save_binary_data): Ditto.
+	* pr-output.cc (octave_print_internal): Ditto.
+
+	* balance.cc (Fbalance):
+	Handle new definition of TC_REP::string_value()
+	* colloc.cc (Fcolloc): Ditto.
+	* dassl.cc (Fdassl_options): Ditto.
+	* data.cc (Fstruct_contains): Ditto.
+	* dirfns.cc (Fmkdir): Ditto.
+	(Freaddir): Ditto.
+	(Frmdir): Ditto.
+	(Frename): Ditto.
+	* error.cc (handle_message): Ditto.
+	* file-io.cc (process_printf_format): Ditto.
+	(fopen_internal): Ditto.
+	(file_io_get_file): Ditto.
+	(return_valid_file): Ditto.
+	(Flstat): Ditto.
+	(Fstat): Ditto.
+	(unlink_internal): Ditto.
+	(mkfifo_internal): Ditto.
+	(async_system_internal): Ditto.
+	(sync_system_internal): Ditto.
+	(execute_internal): Ditto.
+	(popen_internal): Ditto.
+	(fwrite_internal): Ditto.
+	(fread_internal): Ditto.
+	(do_printf): Ditto.
+	(do_scanf): Ditto.
+	* input.cc (get_user_input): Ditto.
+	* lsode.cc (Flsode_options): Ditto.
+	* npsol.cc (Fnpsol_options):Ditto.
+	* qpsol.cc (Fqpsol_options):Ditto.
+	* quad.cc (Fquad_options): Ditto.
+	* rand.cc (do_rand): Ditto.
+	* schur.cc (Fschur): Ditto.
+	* sysdep.cc (Fputenv): Ditto.
+	(Fgetenv): Ditto.
+	* timefns.cc (extract_tm): Ditto.
+	(Fstrftime): Ditto.
+	* toplev.cc (Fsource): Ditto.
+	(eval_string): Ditto.
+	(Fsystem): Ditto.
+	* tree-plot.cc (subplot::handle_plot_data): Ditto.
+	* variables.cc (is_valid_function): Ditto.
+	(Fis_global): Ditto.
+	(Fexist): Ditto.
+	(builtin_string_variable): Ditto.
+	* utils.cc (make_argv): Ditto.
+	(Fundo_string_escapes): Ditto.
+
+Mon Jan  8 01:54:50 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-bin): Use $(LN_S), not just ln.
+
+	* variables.cc (octave_fcn_file_dir): New function.
+	* tree-expr.cc (mark_as_system_fcn_file): Use it instead of
+	octave_lib_dir.
+
+	* Makefile.in (clean): If $(SHARED_LIBS), also remove shared libs.
+
+	* pr-output.cc (set_format (const ComplexMatrix&, int&, int&)):
+	Unconditionally call all_elements_are_int_or_inf_or_nan().
+	(set_format (const Matrix&, int&, int&)): Likewise.
+
+Sun Jan  7 19:12:39 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc (oct_putenv): New function.
+	* sysdep.cc (Fputenv): Use oct_putenv.
+	* octave.cc (initialize_globals): Likewise.
+
+Sat Jan  6 23:22:37 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc (Fputenv): New function.
+
+	* input.cc (initialize_readline): Call rl_initialize() here.
+
+	* octave.cc: Conditionally define atexit to be on_exit here.
+	* toplev.cc: Not here.
+
+Fri Jan  5 14:01:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc: Don't include <pwd.h> here.
+
+	* octave-hist.cc, tree-plot.cc, utils.cc: Do include "sysdep.h".
+
+	* dirfns.cc, file-io.cc, help.cc, load-save.cc, octave.cc,
+	octave-hist.cc, tree-plot.cc, utils.cc:
+	Don't include <readline/tilde.h>.
+	* sysdep.h: Do include it here.
+
+	* tree-const.cc (TC_REP::assign (tree_constant&, Octave_object&)):
+ 	If we have a matrix or range, call maybe_mutate before returning.
+
+Sun Dec 31 15:56:18 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* npsol.cc (Fnpsol): Improve doc string.
+	* qpsol.cc (Fqpsol): Likewise.
+
+Fri Dec 29 21:46:58 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* defun-dld.h: Make work again for OCTAVE_LITE and
+	WITH_DYNAMIC_LINKING.
+
+	* Makefile.in: Handle shared libraries.
+
+Wed Dec 27 17:47:51 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mk-oct-links: New file.
+	* Makefile.in (install-oct): Use it.
+	* f-*.cc: Rename to *.cc.
+
+	* Makefile.in (install-bin, install-lib, install-oct): New targets.
+	(install): Use them.
+
+Tue Dec 26 21:38:22 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* toplev.cc (reading_startup_message_printed): Move initialization
+	here and make extern.
+
+	* dirfns.cc, dynamic-ld.cc, help.cc, input.cc, octave-hist.cc,
+	octave.cc, sighandlers.cc, sysdep.cc, tree-expr.cc, tree-misc.cc,
+	utils.cc, variables.cc, parse.y, lex.l: Include toplev.h instead
+	of octave.h.
+	* toplev.h: rename from octave.h.
+
+	* octave.cc (main): Delete unused variable saved_sigint_handler.
+
+Sun Dec 24 00:26:54 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.cc: Massive re-write to handle dlopen/dlsym and
+	shl_load/shl_findsym methods of dynamic linking.
+
+	* utils.cc (get_fcn_file_names): Check for .oct files if
+	WITH_DYNAMIC_LINKING, not WITH_DLD.
+
+	* Makefile.in (LIB, TERMLIBS): Substitute values.
+	(octave): Add $(LIBS) to link command and use $(TERMLIBS) instead
+	of -ltermcap.
+
+Sat Dec 23 21:56:12 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dynamic-ld.h, dynamic-ld.cc: Remove old unused code.
+
+	* variables.cc (load_fcn_from_file):
+	Always call load_octave_oct_file.
+
+Wed Dec 20 00:56:57 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pr-output.cc (set_real_format, set_real_matrix_format,
+	set_complex_format, set_complex_matrix_format, set_range_format):
+	New functions.  Ensure the count of the digits to the right of the
+	decimal point is positive.
+
+	* xpow.cc (xpow (const Matrix&, double)): Print warning if
+	inverting singular matrix (but return value anyway, in the name of
+	compatibility).
+	xpow (const ComplexMatrix&, double)): Likewise.
+
+	* f-inv.cc (Finv): If matrix is singular, return result anyway, in
+	the name of compatibility.
+
+	* symtab.cc (symbol_record::pop_context):
+	Don't assert (! context.empty ()).
+
+	* tree-const.cc (TC_REP::char_matrix_value): Don't complain about
+	type conversion if object is an empty matrix.f
+	(TC_REP::assign): If rhs is a string, don't convert to numeric
+	type if rhs is empty or "".
+	Only widen if rhs is not empty.
+	Don't return 0x0 char_matrix if it is supposed to be a string.
+	
+	* arith-ops.h, mappers.h, pr-output.h, xdiv.h, xpow.h: Include
+	oct-cmplx.h in place of forward declaration for class Complex.
+
+	* pr-output.cc, mappers.cc, arith-ops.cc, xdiv.cc, xpow.cc,
+	utils.cc: Include "oct-cmplx.h" instead of <Complex.h>.
+
+	* octave.cc (initialize_error_handlers): Don't call
+	set_Complex_error_handler().
+	(octave_Complex_error_handler): Delete unused function.
+	Delete declaration for set_Complex_error_handler().
+
+	* sighandlers.cc (catch_interrupts): New function.
+	* octave.cc (main): Call catch_interrupts() instead of calling
+	octave_set_signal_handler() directly.
+
+Tue Dec 19 03:22:37 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (looks_like_octave_copyright): Also recognize the
+	string " This program is free software".
+
+Thu Dec 14 01:54:06 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave-hist.cc (clean_up_history): Only write history file if
+	user_pref.saving_history.
+
+	* octave-hist.cc (initialize_history, clean_up_history,
+	do_history): Perform tilde expansion on history file name.
+
+	* octave.cc (main): Check `defined (HAVE_ON_EXIT)' not just
+	`(HAVE_ON_EXIT)'.
+
+	* user-prefs.h (user_preferences): New fields, `history_file' and
+	`history_size'.
+	* user-prefs.cc (init_user_prefs): Initialize them.
+	(sv_history_file, history_size): New functions.
+	* variables.cc (install_builtin_variables): Initialize user-level
+	variables history_file and history_size.
+	* octave-hist.cc (default_history_size): Now extern.
+	(default_history_file): Likewise.
+	(octave_hist_size, octave_hist_file): Use user preference
+	variables instead.
+	* octave.cc (main): Call initialize_history after
+	execute_startup_files.
+
+Fri Dec  8 15:53:59 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* user-prefs.h (user_preferences): New field, `saving_history'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(saving_history): New function.
+	* variables.cc (install_builtin_variables): Initialize user-level
+	variable saving_history.
+	* octave.cc (parse_and_execute): Don't reset value of
+	saving_history here.
+	(main) Use user_pref.saving_history instead of saving_history.
+	* variables.cc (parse_fcn_file): Likewise.
+	* octave-hist.cc (maybe_save_history): Likewise.
+	Don't save history if input_from_startup_file.
+
+Mon Nov 27 23:05:52 1995  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* resource.cc: Include systime.h before <sys/resource.h>.
+
+Tue Nov 14 14:09:40 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* error.cc: Include cstring.
+
+	* tree-expr.cc (print_code): Decrement indent level after printing
+	function body.
+
+	* Makefile.in: Remove references to oct-str.cc, oct-str.h, and
+	Array-string.cc.
+
+	* tree-const.h: Don't include oct-str.h.
+
+Mon Nov  6 11:16:49 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* parse.y (make_plot_command, finish_colon_expression,
+	make_unwind_protect, make_try_command, make_for_command,
+	make_break_command, make_continue_command, make_return_command,
+	start_if_command, finish_if_command, make_elseif_clause,
+	make_simple_assignment, make_multi_val_ret, start_function_def,
+	frob_function_def, finish_function_def, start_matrix,
+	finish_matrix):  New functions.  Use them in the grammar to clean
+	things up a bit.  Possibly convert matrix lists, colon
+	expressions, binary expressions, and unary expressions to constant
+	values.
+	(tree_matrix_type): Delete.
+	(simple_expr1): Handle all expression stuff here, including
+	assignments.
+	(simple_expr): Just check to see that simple_expr1 produced
+	something useful.
+
+	* tree-plot.cc, tree-plot.h: Move most simple constructors to the
+	header file.
+
+	* tree-expr.h (tree_expression::is_constant): Move virtual
+	function definition here.
+	(tree_fvc::is_constant): From here.
+	(tree_expression::is_matrix_constant): New virtual function.
+	(tree_expression::is_range_constant): New virtual function.
+	* tree-expr.cc (tree_matrix::is_matrix_constant): New function.
+	* tree-expr.cc (tree_colon_expression::is_range_constant): New
+	function.
+
+Fri Nov  3 03:42:04 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.cc, utils.h (jump_to_top_level): Declare as extern "C".
+
+	* tree-const.h (tree_constant::eval ()): Only mutate if printing.
+
+	* tree-const.cc (TC_REP::tree_constant_rep (const Complex&),
+	TC_REP::tree_constant_rep (const ComplexMatrix&),
+	TC_REP::tree_constant_rep (const ComplexDiagMatrix&),
+	TC_REP::tree_constant_rep (const ComplexRowVector&),
+	TC_REP::tree_constant_rep (const ComplexColumnVector&)):
+	Also check to see if we can convert to scalar_constant, not just
+	complex_scalar_constant.
+
+	* user-prefs.h (user_preferences): New field, `exec_path'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(sv_exec_path): New function.
+	* variables.cc (install_builtin_variables): Add DEFUN for EXEC_PATH.
+	(default_exec_path): New function.
+	* octave.cc (exec_path): New global variable.
+	Don't set and putenv() exec path here.
+	(long_opts): Add --exec-path option.
+	(main): Handle it.
+	(initialize_globals): Set default value here.
+
+	* user-prefs.h (user_preferences): New field, `info_prog'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(sv_info_prog): New function.
+	* variables.cc (install_builtin_variables): Add DEFUN for INFO_PROGRAM.
+	(default_info_prog): New function.
+	* octave.cc (info_prog): New global variable.
+	(initialize_globals): Set default value here.
+	(long_opts): Add --info-prog option.
+	(main): Handle it.
+	* help.cc (try_info): Use user_pref.info_prog here.
+
+	* octave.cc (initialize_globals): Put arch_dir and bin_dir ahead
+	of shell_path when resetting PATH.
+
+Thu Nov  2 04:30:13 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-rand.cc (Frandn): New function.
+	(do_initialization): New function.
+	(do_rand): New function for doing the real work.
+	(Frand): Use it.
+
+	* octave.cc (parse_and_execute): New arg, warn_for.  If given,
+	print message if file cannot be opened.
+	Set curr_fcn_file_full_name here. 
+	(Fsource): Pass extra arg to parse_and_execute to get warning message.
+
+	* tree-const.h: Handle line and column info for double, Complex,
+	and char* constants.
+
+	* parse.y (maybe_convert_to_ans_assign): Pass along line and
+	column info from expression.
+
+	* parse.y (make_constant): New function.
+	(simple_expr1, word_list): Use it.
+	
+	* input.cc, input.h (curr_fcn_file_full_name): New global.
+	* variables.cc (load_fcn_from_file): Set it here.
+	* parse.y (func_def2, yyerror, maybe_warn_missing_semi): Use it.
+	(func_def2): If !reading_fcn_file, don't call strcmp if
+	curr_fcn_file_name is 0.
+
+	* octave.cc (Fsource): New function.
+	(parse_and_execute): Declare file name const char *.
+	* input.cc (get_input_from_file): Likewise.
+
+Wed Nov  1 13:54:34 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-filter.cc: New file.
+	* Makefile.in (DLD_SRC): Add it to the list.
+
+	* sysdep.h (gethostname): Change declaration to match definition
+	in sysdep.cc.
+
+	* resource.cc: Include sysdep.h here, for octave_NaN.
+
+Tue Oct 31 02:12:18 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.cc (TC_REP::assign): After converting rhs to a
+	numeric type, use the converted value, not the original.
+
+	* dirfns.cc (Fpwd): If nargout == 0, print the directory name
+	instead of returning it.
+
+	* pager.cc (maybe_page_output): Call maybe_write_to_diary_file here.
+	(flush_output_to_pager): Not here.
+
+Mon Oct 30 23:39:43 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (install_builtin_commands): Add DEFVAR for
+	echo_executing_commands.
+
+	* octave-hist.cc (do_edit_history): Handle new echo stuff.
+	* variables.cc (parse_fcn_file): Likewise.
+	* octave.cc (parse_and_execute): Likewise.
+	(main): Likewise.
+	* input.cc (do_input_echo):
+	(Fecho): New function.
+	
+	* tree-expr.cc (tree_function::print_code_function_header,
+	tree_function::print_code_function_trailer): New functions.
+	(tree_function::print_code): Use them.
+	(tree_function::eval): Likewise, if echoing commands.
+	* tree-misc.cc (tree_statement::maybe_echo_code): New function.
+
+	* user-prefs.h (user_preferences): New field, echo_executing_commands.
+	(echo_state): New enum, for various types of echoing we do.
+	* user-prefs.cc (echo_executing_commands): New function.
+
+	* tree-base.cc (print_code_indent): Print PS4 as line prefix.
+	* help.cc (Ftype): Add unwind_protect for ps4 and set it to ""
+	before printing code.
+
+	* tree-misc.h (tree_statement_list): New field, function_body.
+	(tree_statement_list::mark_as_function_body): New function.
+	* parse.y (func_def3): Mark function bodies.
+
+	* pr-output.cc (octave_print_internal): Undo string escapes when
+	printing charMatrix as strings.
+
+Sat Oct 28 17:38:29 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* utils.h (undo_string_escapes): Add missing const in declaration.
+
+Fri Oct 27 03:49:44 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (next_available_file_number): New stack for keeping
+	track of next available file number.
+	(get_next_avail_file_num): New function.
+	(fopen_file_for_user, fopen_internal, popen_internal,
+	execute_internal): Use it.
+
+Mon Oct 23 07:00:09 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.cc (TC_REP::convert_to_matrix_type,
+	tree_constant::convert_to_matrix_type): New arg, make_complex.
+	(TC_REP::set_index): New arg, rhs_is_complex.  Pass it to
+	convert_to_matrix_type.
+	(TC_REP::assign): Pass rhs.is_complex_type() to set_index.
+
+Thu Oct 19 00:38:38 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xpow.cc: Include <climits>.
+
+	* sysdep.cc (Fpause): Do pause even if not interactive.
+
+	* tree-const.cc (TC_REP::assign): Don't make RHS numeric if both
+	RHS and LHS are strings.
+
+Wed Oct 18 22:19:16 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-expm.cc (Fexpm): Avoid taking log of negative number.  Also,
+	don't unnecessarily divide the input matrix by 1.0.
+
+	* input.cc (decode_prompt_string): Recognize \[ and \] too.
+	(initialize_readline): Bind M-p to history-search-backward and M-n
+	to history-search-forward.
+
+Tue Oct 17 04:31:06 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* xpow.cc (xpow): Handle integer powers better for complex^double.
+	(elem_xpow): Likewise.
+
+	* lex.l ({CCHAR}): If nesting_level.top() is BRACE, return ';',
+	not '\n'.
+
+Mon Oct 16 19:03:45 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* help.cc (Fwhich): Fix doc string.
+
+	* variables.cc (Fexist): Update doc string.
+
+Sun Oct 15 22:19:16 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Another massive set of changes to support character matrices
+	with indexing.  The Octave_str_object class is no longer used.
+	Anything having to do with Octave_str_object in the following
+	files has been changed to use charMatrix instead: octave.h,
+	load-save.cc, octave.cc, strfns.cc, data.cc, pr-output.h,
+	pr-output.cc, tree-const.h, dirfns.cc, tree-const.cc,
+	tree-expr.cc.
+
+Sat Oct 14 22:28:18 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-sort.cc (mx_sort): Don't attempt to sort vectors that have
+	only one element, or matrices that have only one row.
+
+Thu Oct 12 02:16:58 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* mappers.cc (install_mapper_functions): Add gammaln as an alias
+	for lgamma.
+
+	* tree-const.h, tree-const.cc: Massive overhaul of indexing and
+	indexed assignment functions.
+	* tc-inlines.h, tc-rep.h: Remove files.
+	* Makefile.in: Remove mention of them here too.
+
+	* Makefile.in: Include $(TI_SRC) in DEP_SOURCES_3, not
+	$(TI_SOURCES).
+	Include $(DLD_SRC) in DEP_SOURCES_3.
+	Include $(TI_SRC) in DEF_FILES_5.
+
+Wed Oct 11 01:26:18 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (INCLUDES): Remove tc-inlines.h and tc-rep.h from
+	the list.
+
+Mon Oct  9 08:31:04 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* lex.l (next_token_is_bin_op): Do match `.+', `.*', etc.
+
+Sun Oct  8 18:19:56 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* idx-vector.h, idx-vector.cc: Delete files.
+	* Makefile.in (SOURCES, INCLUDES): Remove them from lists.
+
+Fri Oct  6 00:52:06 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-svd.cc (Fsvd): If nargout == 0 or nargout == 1, don't ask for
+	U and V.
+
+Wed Oct  4 00:04:57 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-npsol.cc (Fnpsol, Fnpsol_options): Avoid unused variable
+	warnings if NPSOL_MISSING.
+	* f-qpsol.cc (Fqpsol, Fqpsol_options): Likewise for QPSOL_MISSING.
+
+	* Makefile.in (DISTFILES): Add octave.gperf.
+
+	* lex.l (next_token_is_bin_op): Don't ever return true for `.'
+	since that causes problems with things like [ .1 .1 ].
+
+Tue Oct  3 05:30:24 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (is_valid_function): Avoid setting error_state if
+	argument is not a string.
+
+	* parse.y (maybe_warn_missing_semi): New function.
+	(list1, list): Call it if statement not terminated by semicolon.
+	* tree-misc.h (tree_statement::line, tree_statement::column):
+	New functions.
+	* octave.cc (input_from_command_line_file): New global variable.
+	(main): Set it.
+	(parse_and_execute): Unwind-protect it and set it to zero.
+	(eval_string): Likewise.
+	* variables.cc (parse_fcn_file): Likewise.
+
+	* user-prefs.cc (warn_missing_semicolon): New function.
+	* user-prefs.h (user_preferences): New field, warn_missing_semicolon.
+	* variables.cc (install_builtin_variables): DEFVAR it.
+	
+	* tree-expr.cc (tree_expression::is_logically_true): Actually use
+	argument.
+
+Mon Oct  2 19:55:48 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (install_builtin_variables): Reduce the default
+	value of save_precision to 15.
+
+	* variables.cc (builtin_real_scalar_variable): Return 1 for
+	success, 0 for failure.
+
+	* user-prefs.cc (struct_levels_to_print, set_save_precision,
+	set_output_max_field_width, set_output_precision):
+	Change sense of test for builtin_real_scalar_variable return value.
+	(check_preference): Rename from check_str_pref.  Change all callers.
+	Accept value of 0 to be the same as "false" and nonzero to be the
+	same as "true".
+	Delete val to avoid memory leak.
+	* variables.cc (install_builtin_variables): Change initial values
+	from "true" to 1, "false" to 0.
+
+	* variables.cc (install_builtin_variables): Add DEFVAR for
+	gnuplot_has_multiplot.
+
+	* user-prefs.h (user_preferences): New field,
+	`gnuplot_has_multiplot'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(gnuplot_has_multiplot): New function.
+
+Sat Sep 30 16:52:57 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* oct-gperf.h, octave.gperf: Newfiles.
+	* Makefile.in (DISTFILES): Add octave.gperf.
+	(INCLUDES): Add oct-gperf.h.
+	(oct-gperf.h): New rule.
+	(local-dist, dist): Depend on oct-gperf.h.
+	* lex.l (is_keyword): Use perfect hash function to lookup
+	keywords.
+
+Fri Sep 29 04:36:04 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* version.h (OCTAVE_NAME_AND_VERSION): Add TARGET_HOST_TYPE to this.
+
+Thu Sep 28 00:03:51 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-expr.cc (tree_expression::is_logically_true): New function.
+	* tree-cmd.cc (tree_while_command::eval): Use it instead of
+	handling the test directly here.
+	* tree-misc.cc (tree_if_clause::eval): Likewise
+
+	* tree-const.cc (TC_REP::force_numeric): Don't try to print value
+	of str_obj with %s.
+
+	* error.cc (buffer_error_messages): Rename from
+	suppress_octave_error_messages.
+	(error_message_buffer): New global variable.
+	(verror): Handle buffering of messages.
+	(handle_message): New function.
+	(Ferror, Fwarning, Fusage): Use it instead of duplicating code.
+
+	* octave.cc (Feval): Buffer error messages instead of supressing them.
+
+	* lex.l (is_keyword): Recognize `try', `catch', and `end_try_catch'.
+	* parse.y (TRY, CATCH): New tokens.
+	(command): Recognize try-catch block.
+	(end_error): Add cases for unwind_protect_end and try_catch_end.
+	* token.h (end_tok_type): New field, try_catch_end.
+	* tree-cmd.h, tree-cmd.cc (tree_try_catch): New class.
+	* variables.cc (bind_global_error_variable): New Function.
+	(clear_global_error_variable): Likewise.
+	(install_builtin_variables): Add DEFCONST for __error_text__.
+	* help.cc (keywords): Add `try', `catch', and `end_try_catch'.
+
+	* tree-cmd.cc (tree_unwind_protect::eval): Undo previous change.
+
+	* dirfns.cc (Freaddir, Fmkdir, Frmdir):
+	Do tilde expansion on the argument.
+
+Tue Sep 26 00:10:29 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* f-dassl.cc, f-fsolve.cc, f-lsode.cc, f-npsol.cc, f-quad.cc:
+	Don't try to figure out if the user-supplied functions take the
+	correct number of arguments.  Simply let the call fail.
+	* variables.cc (takes_correct_nargs): Delete unused function.
+	* tree-expr.cc (tree_builtin::eval): Don't complain for too many
+	arguments to mapper functions.
+	* tree-expr.h, tree-expr.cc (tree_builtin, tree_function, tree_fvc):
+	Delete unused function max_expected_args.
+
+	* defun.h (DEFUN): Delete unnecessary args nargin_min and nargout_max.
+	New arg unused_arg_flags.
+	(DEFUN_TEXT): Likewise.
+	* defun-dld.h (DEFUN_DLD_BUILTIN): Likewise.
+	* defun-int.h (DEFUN_INTERNAL, DECLARE_FUN, DEFINE_FUN_STRUCT):
+	Do the real work.
+
+	* data.cc, dirfns.cc, dynamic-ld.cc, error.cc, f-balance.cc,
+ 	f-chol.cc, f-colloc.cc, f-dassl.cc, f-det.cc, f-eig.cc, f-expm.cc,
+ 	f-fft.cc, f-fft2.cc, f-find.cc, f-fsolve.cc, f-fsqp.cc,
+ 	f-givens.cc, f-hess.cc, f-ifft.cc, f-ifft2.cc, f-inv.cc, f-log.cc,
+ 	f-lpsolve.cc, f-lsode.cc, f-lu.cc, f-minmax.cc, f-npsol.cc,
+ 	f-pinv.cc, f-qpsol.cc, f-qr.cc, f-quad.cc, f-qzval.cc, f-rand.cc,
+ 	f-schur.cc, f-sort.cc, f-svd.cc, f-syl.cc, file-io.cc, help.cc,
+ 	input.cc, lex.l, load-save.cc, mappers.cc, octave-hist.cc,
+ 	octave.cc, octave.h, pager.cc, pr-output.cc, resource.cc,
+ 	sighandlers.cc, strfns.cc, sysdep.cc, timefns.cc, token.cc,
+ 	tree-const.cc, tree-expr.cc, tree-expr.h, tree-plot.cc,
+ 	unwind-prot.cc, unwind-prot.h, utils.cc, variables.cc,
+ 	variables.h, version.h, xdiv.cc:
+	Avoid unused variable warnings.
+
+	* tree-expr.h (tree_oct_obj::print_value (ostream&)):
+	Delete name of unused arg.
+	(tree_fvc::save (ostream&, int, int): Likewise.
+
+	* tree-const.h (tree_constant::tree_constant (magic_colon)):
+	Delete name of unused arg.
+	(tree_constant::tree_constant (all_va_args)): Likewise
+	(ColumnVector vector_value (int, int)): Likewise.
+	(ComplexColumnVector vector_value (int, int)): Likewise.
+	(Octave_object::eval (int, int, const Octave_object&): Likewise.
+
+	* octave.cc (execute_startup_files): Look for octaverc first in
+	site/m, then in $(version)/m.
+	* variables.cc (get_local_site_defaults): New function.
+	* defaults.h.in (OCTAVE_LOCALFCNFILEDIR, OCTAVE_LOCALSTARTUPFILEDIR):
+	New macros.
+	* Makefile.in (defaults.h): Also substitute ${localfcndir}.
+
+Mon Sep 25 17:01:03 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* variables.cc (install_builtin_variables): Add DEFCONST for "e".
+
+Fri Sep 22 02:18:45 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* dirfns.cc (Fls): Delete ls_command after using it, not before.
+
+	* input.h, input.cc (gnu_readline): Don't declare gnu_readline
+	`extern "C"'.
+
+	* sysdep.h: Only declare gethostname if it is missing, then don't
+	declare it `extern "C"'.
+
+	* dirfns.cc: Don't declare strerror().
+
+	* input.cc (command_generator): Use malloc, not xmalloc.  Don't
+	declare xmalloc.
+	(gnu_readline): Don't declare this `extern "C"'.
+
+	* octave-hist.cc: Don't declare history_get().  It is now in
+	readline/history.h.
+
+	* input.cc: Don't declare history_get().  It is now in
+	readline/readline.h.
+
+	* resource.cc: Don't surround include of sys/resource.h in
+	`extern	"C" { }'.
+
+	* fnmatch.h [__cplusplus]: Surround contents in `extern "C" { }'.
+	* load-save.cc, symtab.cc, variables.cc: Don't surround
+	fnmatch.h include in `extern "C" { }'.
+
+	* help.cc: Don't #undef __FUNCTION_DEF before including
+	readline/tilde.h.
+
+	* dirfuns.cc, file-io.cc, help.cc, load-save.cc, octave-hist.cc,
+	sysdep.cc, tree-plot.cc, utils.cc, variables.cc:
+	Don't surround readline includes in `extern "C" { }'.
+
+	* sysdep.cc: Move all include statements to top of file.
+
+Tue Sep 19 01:58:21 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.cc (Fsystem): Use iprocstream *, and unwind_protect it.
+	* pager.cc (flush_output_to_pager): Likewise.
+	* dirfns.cc (Fls): Likewise.
+	* tree-plot.cc (plot_stream): Now a pointer.
+	(open_plot_stream): Deal with it.
+	(send_to_plot_stream, cleanup_tmp_files, do_external_plotter_cd):
+	Likewise.
+
+	* procstream.cc (cleanup_iprocstream, cleanup_oprocstream):
+	New functions. 
+
+	* procstream.h, procstream.cc (class iprocstream, class oprocstream):
+	Keep track of pbuf.  Initialize it to 0 in default constructors,
+	delete it in destructor.  Don't call close in destructor.
+
+	* sighandlers.cc (octave_set_signal_handler): New function.
+	Use this name instead of signal everywhere.
+	* help.cc (try_info): Likewise.
+	* pager.cc (flush_output_to_pager): Likewise.
+	* octave.cc (main): Likewise.
+	* octave-hist.cc (do_edit_history): Likewise.
+
+	* input.cc (initialize_readline): Set rl_paren_string_delimiters
+	to avoid treating single quotes as string delimiters when doing
+	paren matching.
+
+	* Makefile.in (SOURCES): Don't list Map.cc or SLStack.cc here.
+
+	* tree-const.cc: Do include utils.h.
+
+	* sysdep.cc: Don't surround terminal includes in extern "C".
+	Include them before readline.h.
+
+	* Map.h: Don't include utils.h.
+	(CHNode::CHNode (const char*, const C&, CHNode *t):
+	Do strsave() inline.
+
+	* input.cc (generate_possible_completions): Generate name list
+	even when text == 0.
+	(operate_and_get_next): Don't declare history_stifled, call
+	history_is_stifled () instead.
+	Don't declare history_length, or max_input_history either.
+	Check (where >= history_length - 1) too, as in recent versions of
+	bash.
+	
+	* user-prefs.h (user_prefs): New field, `completion_append_char'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(sv_completion_append_char): New function.
+	* variables.cc (install_builtin_variables): Install
+	completion_append_char.
+	* input.cc (command_generator): Use it.
+
+	* SLList-expr.cc, SLList-misc.cc, SLList-plot.cc, SLList-tc.cc,
+	DLList-fi.cc: Include config.h.
+	* DLList-fi.cc: Include file-info.h, not file-io.h.
+
+Mon Sep 18 11:01:24 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.h (clean_up_and_exit): Tag with NORETURN instead of using
+	typedef trick.
+	* error.h (panic): Likewise.
+	* utils.h (jump_to_top_level): Likewise.
+
+	* file-io.h: Protect from multiple includes with octave_file_io,
+	not octave_files.
+
+	* file-info.h (class file_info): Convert to using std C++ string
+	class from char *.
+	* file-info.cc: Likewise.  Don't include utils.h.
+	* file-io.cc (return_valid_file, fopen_file_for_user,
+	fflush_internal, do_scanf): Use operator ==, not strcmp.
+	(close_files): Call error with file.name ().data (),
+	not file.name ().
+	(freport_internal): Call form with file.mode ().data () and
+	file.name ().data ().
+
+	* file-io.cc, file-io.h: Extract file_info class.
+	* file-info.cc, file-info.h: New files for file_info class.
+
+	* user-prefs.h (user_prefs): New field, `beep_on_error'.
+	* user-prefs.cc (init_user_prefs): Initialize it.
+	(beep_on_error): New function.
+	* variables.cc (install_builtin_variables): Install beep_on_error.
+	* octave.cc (maximum_braindamage): Set beep_on_error to "true".
+	* error.cc (verror): Conditionally beep.
+	(error): Don't reset error_state until after verror is called.
+
+Sun Sep 17 16:41:25 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (read_mat_binary_data, read_ascii_data,
+	save_ascii_data, read_binary_data, save_binary_data):
+	Handle string arrays.
+
+Fri Sep 15 00:24:19 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* user-prefs.cc (struct_levels_to_print,
+	set_output_max_field_width, set_output_precision,
+	set_save_precision): Eliminate unecessary kludge variable.
+	
+	* variables.cc (gobble_leading_white_space): New arg,
+	in_parts.  Change all callers.
+
+	* lex.l (HELP_FCN): Delete start state.  The `help' command is now
+	handled the same as any other text-style function.
+
+	* gripes.cc (gripe_invalid_value_specified): New function
+	* user-prefs.cc: Use it.
+
+	* sysdep.cc (octave_words_big_endian): New global variable.
+	(ten_little_endians): New function.
+	(sysdep_init): Call it.
+	* load-save.cc (words_big_endian): Use this at run-time instead of
+	depending on WORDS_BIGENDIAN at compile-time.
+
+	* symtab.h (SYMTAB_VARIABLES): New macro.
+	* variables.cc (Fclear): Use it instead of just
+	symbol_def::USER_VARIABLE when looking for variables.
+
+	* octave.cc (main): If there is a file to execute, set
+	program_invocation_name and program_name to the name of the file
+	and argv to the remaining args.
+	(intern_argv): Only define argv if there are some remaining
+	arguments.
+
+	* defun.h (DEFVAR_INT): New macro.
+	(DEFVAR): Define in terms of DEFVAR_INT.  Delete args protect and
+	eternal.
+	(DEFCONST): New macro.
+	* variables.cc (install_builtin_variables): Use DEFCONST where
+	appropriate, change uses of DEFVAR to match new definition.
+
+	* variables.cc (bind_builtin_variable): New variant that accepts
+	const tree_constant& value.
+	(install_builtin_variables): Properly alphabetize DEFVAR for this.
+
+	* octave.cc (short_opts): Prefix with `+' to prevent argv
+	permutation.
+	(main): Don't use readline if forced_interactive.
+	(traditional): New file-scope variable.
+	(long_opts, usage_string, verbose_usage): Add `--traditional'.
+	(maximum_braindamage): New function.
+	(main): Call it if --traditional.
+
+	* input.cc (do_input_echo): Print prompt correctly when
+	forced_interactive is either true or false.
+
+Thu Sep 14 00:54:06 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* data.cc (Fstruct_elements): New function.
+
+	* file-io.cc (Fumask): New function.
+
+	* dirfns.cc (Fmkdir, Frmdir, Frename): New functions.
+
+	* Makefile.in: Add rules and dependencies for building safe-stat.o
+	and safe-lstat.o.
+
+	* mkdir.c, rename.c, rmdir.c: New files.
+	* Makefile.in (SOURCES): Include them in the list.
+
+	* safe-xstat.hin, safe-xstat.cin: New files
+	* Makefile.in (DISTFILES): Include them in the list.
+
+	* sighandlers.cc (octave_new_handler): Try to continue on memory
+	exhausted errors.
+	(sigfpe_handler): Improve error message.
+
+	* Makefile.in: Use `ifndef omit_deps', not `ifndef $(omit_deps)'.
+
+	* dirfns.cc (Freaddir): New function.
+
+	* f-sort.cc: Complete rewrite.  Now uses stable sort algorithm and
+	correctly handles complex matrices containing columns of all real
+	numbers.
+
+Wed Sep 13 03:16:40 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* arith-ops.cc: Unconditionally #define DIVIDE_BY_ZERO_ERROR.
+
+	* variables.cc (install_builtin_variables): Unconditionally
+	install NaN and nan.
+
+	* mappers.cc (xisinf): Don't do bogus things if isinf, isnan, or
+	finite are missing.
+	(xfinite): Likewise.
+
+	* sysdep.cc (octave_ieee_init): Don't set octave_NaN and
+	octave_Inf if values are not available.
+
+	* resource.cc (mk_ru_map): Don't use ru_ or tv_ as prefixes to
+	Octave names for the structure members.
+
+Tue Sep 12 02:04:16 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* procstream.h, procstream.cc: Rewrite.
+
+Mon Sep 11 18:42:05 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* filemode.c: New file, from Emacs.
+	* Makefile.in (SOURCES): Add it to the list.
+
+	* file-io.cc (Fstat, Flstat, mk_stat_map): New functions.
+
+	* timefns.cc (mk_tm_map): Don't use tm_ as prefix to Octave names
+	for these structure members.
+	(extract_tm): Likewise.
+	(Flocaltime): Fix doc string to match.
+
+Thu Sep  7 02:04:27 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* load-save.cc (save_user_variables): New function.
+	* sighandlers.cc (my_friendly_exit): Call it before exiting.
+	(sigfpe_handler): New function.
+	(install_signal_handlers) [__alpha__]: Install it.
+
+Wed Sep  6 14:35:10 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-cmd.cc (tree_unwind_protect::eval): Ignore errors and
+	suppress error messages while executing first block of
+	unwind_protect commands.
+
+	* parse.y (end_error): Add missing case for unwind_protect_end.
+
+	* tree-expr.cc (tree_builtin::eval): Complain if no arguments
+	given for mapper functions.
+	(tree_fvc::lookup_map_element): Print error message for invalid
+	structure reference.
+
+Tue Sep  5 02:04:12 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc, input.cc, load-save.cc, octave.cc, sysdep.cc,
+	variables.cc, octave-hist.cc, utils.cc, f-schur.cc, f-rand.cc,
+	f-quad.cc, f-qpsol.cc, f-npsol.cc, f-lsode.cc, f-fsolve.cc,
+	f-dassl.cc, f-colloc.cc, f-balance.cc, error.cc, data.cc:
+	Add const qualifiers where appropriate.
+
+	* dirfns.h: Include <ctime>, for time_t.
+
+	* tempname.c, file-io.cc, help.cc, input.cc, octave-hist.cc,
+	octave.cc, sighandlers.cc, sysdep.cc, tree-expr.cc, tree-misc.cc,
+	tree-plot.cc, utils.cc, variables.cc, sysdir.h:
+	Move #include <sys/type.h> inside #ifdef HAVE_UNISTD_H.
+
+	* syswait.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* file-io.cc, sighandlers.cc: Use it instead of including
+	sys/wait.h directly.
+
+	* octave.cc: Include statdefs.h, not sys/stat.h.
+
+	* sysdir.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* dirfns.cc, utils.cc: Use it instead of including the headers
+	directly.
+
+	* pathlen.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+	* dirfns.cc, input.cc: Use it instead of including sys/param.h
+	directly.
+	* utils.cc: Don't include sys/param.h
+
+Sun Sep  3 18:52:59 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.cc (TC_REP::string_value): Return const char*, not
+	char *.
+
+	* All .cc, .y, .l, .y files: Include <cctype>, not <ctype.h>, and
+	so on for all new C++ versions of these standard C headers.
+
+Thu Aug 31 17:09:38 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* pathsearch.h: Also hide `string'.
+
+	* oct-str.cc, oct-str.h: New files.
+	* Makefile.in: Add to the appropriate lists.
+	* tc-rep.h: Change char* to Octave_string* in anonymous union.
+	* tree-expr.cc (tree_matrix::eval): Handle multiple element strings.
+	* strfns.cc (toascii): Likewise.
+	* tree-const.cc (print_as_string): Likewise.
+	(TC_REP::force_numeric, TC_REP::rows, TC_REP::columns,
+	TC_REP::double_value, TC_REP::complex_value, TC_REP::matrix_value,
+	TC_REP::complex_matrix_value, TC_REP::convert_to_str): Likewise.
+	(TC_REP::print): Call octave_print_internal for string case.
+	(all_strings): New function.
+	Fix constructors to use new data structure.
+	* pr-output.cc (octave_print_internal): Add version for strings.
+	* Array-string.cc: New file.
+
+	* octave.cc (octave_argv): New global variable.
+	(intern_argv): New function.
+	(main): Fix argument parsing to do the right thing for arguments
+	to executable scripts.
+	* variables.cc: Add DEFUNs for argv, program_invocation_name, and
+	program_name.
+
+	* defun.h (DEFVAR): Fix comment.
+
+Thu Aug 24 00:02:00 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* file-io.cc (fgets_internal): Make second arg optional.  Add
+	optional arg `strip_final_newline'.
+	(Ffgets): Change to match new definition of fgets_internal.
+	(Ffgetl): Implement using the new fgets_internal.
+
+	* f-rand.cc (Frand): Update code for sizing return value to match
+	that used by ones, zeros, and eye.
+
+Wed Aug 23 19:52:45 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.cc (do_vector_assign): Don't crash for
+	A(range) = scalar, or A(matrix) = scalar.
+
+	* f-dassl.cc (set_dassl_option): Rename from do_dassl_option.
+	(show_dassl_option): New function.
+	(Fdassl_options): Handle single arg.
+	* f-fsolve.cc (set_fsolve_option): Rename from do_fsolve_option.
+	(show_fsolve_option): New function.
+	(Ffsolve_options): Handle single arg.
+	* f-fsqp.cc (set_fsqp_option): Rename from do_fsqp_option.
+	(show_fsqp_option): New function.
+	(Ffsqp_options): Handle single arg.
+	* f-lpsolve.cc (set_lpsolve_option): Rename from do_lpsolve_option.
+	(show_lpsolve_option): New function.
+	(Flpsolve_options): Handle single arg.
+	* f-lsode.cc (set_lsode_option): Rename from do_lsode_option.
+	(show_lsode_option): New function.
+	(Flsode_options): Handle single arg.
+	* f-npsol.cc (set_npsol_option): Rename from do_npsol_option.
+	(show_npsol_option): New function.
+	(Fnpsol_options): Handle single arg.
+	* f-qpsol.cc (set_qpsol_option): Rename from do_qpsol_option.
+	(show_qpsol_option): New function.
+	(Fqpsol_options): Handle single arg.
+	* f-quad.cc: (set_quad_option): Rename from do_quad_option.
+	(show_quad_option): New function.
+	(Fquad_options): Handle single arg.
+	(Fquad): Doc fix.
+
+Tue Aug 22 00:38:05 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-plot.cc (do_external_plotter_cd): New function.
+	* dirfns.cc (octave_change_to_directory): New function.  If cd is
+	successful, also call do_external_plotter_cd().
+	(Fcd): Call octave_change_to_directory(), not change_to_directory().
+
+	* pr-output.cc (pr_any_float): Change declaration of counter to
+	size_t to avoid gcc warnings.
+
+	* idx-vector.cc, octave-hist.cc, tree-const.cc, tree-expr.cc,
+	tree-misc.cc, utils.cc, xpow.cc, Map.cc:
+	Update for change in for loop variable scope for gcc 2.7.0.
+
+Mon Aug 21 19:34:53 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* tree-const.cc (fortran_style_matrix_assignment): Properly handle
+	case of complex LHS, real RHS.
+
+	* Makefile.in: Only include dependency files if $(omit_deps) is
+	not set.
+
+Wed Jul  5 00:03:58 1995  John Eaton  <jwe at bevo.che.wisc.edu>
+
+	* sysdep.cc: Explicitly include string.h.
+
+Sun Jun 25 00:18:10 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* load-save.cc (too_large_for_float (const Matrix&)):
+	Extract elements as doubles, not Complex.
+
+Sat Jun 24 22:59:15 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* pr-output.cc (any_element_is_inf_or_nan): Declare extern, not static.
+	* f-svd.cc (Fsvd): Call here to avoid trying to take SVD of matrix
+	containing Inf or NaN values.
+
+	* pr-output.cc (bit_format): New file-scope variable.
+	(set_format, pr_any_float): Handle bit_format.
+	(octave_print_internal): Handle bit_format like bank_format.
+	(init_format_state): Initialize bit_format.
+	(set_format_style): Allow `format bit' and `format native-bit'.
+
+Thu Jun  8 15:20:26 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* mappers.cc (arg, imag, signum): If arg is NaN, return NaN.
+
+Mon May 15 14:47:04 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* pager.cc (Fdiary): Initialize diary_file here, not in the
+	file-scope declaration.
+
+	* tree-expr.cc (tree_index_expression::eval):
+	Handle nargin == 0 the same as other cases. 
+
+Tue May  2 10:02:23 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* load-save.cc (do_double_format_conversion): Add missing breaks.
+	(do_float_format_conversion): Likewise.
+
+Mon May  1 13:50:24 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (OCTAVE_LIBS): Add @LIBPLPLOT@ to the list.
+
+	* timefns.cc (Ftime): Handle GETTIMEOFDAY_NO_TZ.
+
+	* Makefile.in (SOURCES): Delete tc-rep.cc, tc-rep-ass.cc, and
+	tc-rep-idx.cc from the list.
+
+	* tree-const.h: Add #pragma interface.
+	* tree-const.cc: Add contents of tc-rep.cc, tc-rep-ass.cc, and
+	tc-idx.cc to this file.  Add #pragma implementation.  This makes
+	tree-const.cc large, but makes the final binary smaller.
+	
+	*  unwind-prot.h unwind-prot.cc token.cc token.h procstream.cc
+	procstream.h idx-vector.cc idx-vector.h symtab.cc symtab.h
+	oct-map.cc oct-map.h oct-obj.cc oct-obj.h tree-plot.h tree-plot.cc
+	tree-misc.cc tree-misc.h tree-expr.cc tree-expr.h tree-cmd.cc
+	tree-cmd.h tree-base.cc tree-base.h:
+	Add #pragma interface/implementation.
+
+	* Makefile.in (OCTAVE_LIBS): Delete @LIBINFO@ from list.
+	* help.cc: Don't include info headers or extern declarations for
+	functions from info.
+	(try_info): Call info as a subprocess.	Delete second arg.
+	Handle SIGINT here, not in help_from_info().
+	(help_from_info): Complain if info doesn't work.
+
+	* defun-dld.h (DEFUN_DLD_BUILTIN) [OCTAVE_LITE && MAKE_BUILTINS]:
+	If ! WITH_DLD, simply emit a character string constant.
+
+Fri Apr 28 15:23:06 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* lex.l ({IDENT}{S}*): Don't delete tok.  That's handled by
+	strip_trailing_whitespace() now.
+	(<HELP_FCN>[^ \t\n]*{S}*|<TEXT_FCN>[^ \t\n\;\,]*{S}*): Ditto.
+
+	* pathsearch.h: Include kpathsea/progname.h.
+	* octave.cc (initialize_globals): Call kpse_set_progname().
+
+	* token.h: Declare copy constructor and operator = private.
+	* token.cc: Abort if copy constructor or operator = is used.
+
+Thu Apr 27 13:54:39 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tree-expr.cc (lookup_map_element): Don't list default argument
+	values here too.
+
+	* pr-output.cc (hex_format): New file-scope variable.
+	(set_format, pr_any_float): Handle hex_format.
+	(octave_print_internal): Handle hex_format like bank_format.
+	(init_format_state): Initialize hex_format.
+	(set_format_style): Allow `format hex' and `format native-hex'.
+
+	* variables.cc (bind_ans): Create ans_id each time with new and
+	ask tree_simple_assignment_expression to handle cleaning it up.
+	This apparently plugs a memory leak.
+
+	* help.cc (Ftype): Don't try to print map constants.  Handle
+	references to structure members.
+
+Wed Apr 26 12:40:59 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* input.cc (generate_struct_completions): New function.
+	(generate_possible_completions): Likewise.
+	(looks_like_struct): Likewise.
+	(command_generator): Handle completion of struct variables.
+
+	* tree-expr.h, tree-expr.cc (tree_fvc::lookup_map_element):
+	Add insert and silent args.
+
+	* oct-map.cc: New file.
+	* Makefile.in (SOURCES): Add it to the list.
+
+Mon Apr 24 09:41:02 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* variables.cc (Fexist): Handle structure references too.
+
+	* tree-const.cc (lookup_map_element (const char*, int, int):
+	New function.
+	(lookup_map_element (SLList<char*>&, int, int): New arg, silent.
+	* tc-rep.cc (lookup_map_element): New arg, silent. If nonzero,
+	don't call error().
+
+	* tc-rep.h (is_empty): Define here.
+	* tree-const.h (is_empty): Hand off to TC_REP::is_empty().
+
+	* data.cc (Fstruct_contains): Call lookup_map_element on args(0)
+	instead of extracting the map and calling contains() on it.
+
+	* parse.y (EPLUS, EMINUS): New tokens.
+	(simple_expr): Handle EPLUS, EMINUS the same as `+' and `-'.
+	* lex.l (".+", ".-"): New patterns.  Match these separately to
+	disallow using them as unary operators.
+
+	* lex.l (next_token_is_bin_op): Simplify by noting that spacing
+	only matters for those tokens that can also be unary ops.
+
+Fri Apr 21 14:34:45 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* load-save.cc (read_ascii_data): Allow reading of empty
+	matrices. 
+
+	* tc-rep-ass.cc (vector_assignment): Only assert that we are not
+	doing fortran-style indexing and that nr <= 1 || nc <= 1.
+	(do_vector_assign): Handle assignment of [] when one dimension is
+	zero and the other is anything.
+
+Thu Apr 20 13:56:21 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tc-rep-ass.cc (delete_rows, delete_columns): Simply return if
+	num_to_delete is 0.
+
+	* lex.l (handle_identifier): Don't match plot option keywords
+	inside parentheses or braces.
+
+	* variables.cc (parse_fcn_file): Also delete tmp_help_txt if
+	running a script.
+
+	* tree-cmd.h (tree_command): Add destructor.
+
+	* tree-expr.h tree_simple_assignment_expression (lhs_idx_expr):
+	Hang on to idx_expr, not just its parts so it can be deleted.
+	(init): Initialize it.
+	* tree-expr.cc (~tree_simple_assignment_expression): Delete it.
+
+	* tree-expr.h (tree_multi_val_ret, tree_oct_obj, tree_fvc,
+	tree_identifier, tree_builtin, tree_function): Add destructors.
+	* tree-expr.cc (tree_function::~tree_function): Delete some stuff.
+
+	* tree-misc.h (tree_va_return_list): Add destructor.
+
+	* octave.cc (__builtin_new, __builtin_delete): Provide our own,
+	for debugging.
+
+	* utils.cc (strconcat): Don't depend on the return value from
+	strcat.
+	(file_in_path): Simplify logic.
+
+	* parse.y (maybe_convert_to_ans_assign): Create ans_id each time
+	with new and ask tree_simple_assignment_expression to handle
+	cleaning it up.  This apparently plugs a memory leak.
+
+	* lex.l (strip_trailing_whitespace): Declare retval static.
+	Delete it before saving next string.
+
+	* error.cc (Ferror): Do call error() for empty string args.
+	(error_1): Don't print anything if fmt is "" or "\n", but do set
+	the error state appropriately.
+
+	* tree-cmd.cc (tree_unwind_protect::eval): Handle return and break
+	in the `try' part of the statement.
+
+Mon Apr 10 19:29:44 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* f-expm.cc, f-givens.cc, f-qzval.cc, f-syl.cc, f-rand.cc:
+	Where appropriate, declare Fortran functions to take reference
+	instead of pointer args.  Change callers.
+
+	* mappers.cc: Declare Fortran functions to take reference instead
+	of pointer args.  Change callers.	
+
+	* gamma.c, lgamma.c, erfc.c, erf.c, atanh.c, asinh.c, acosh.c:
+	Declare Fortran functions to take reference instead of pointer
+	args.
+
+Sun Apr  9 19:38:53 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* file-io.cc (Fpopen, Fpclose, Fexecute, Fsync_system,
+	Fasync_system, Fwaitpid, Fmkfifo, Funlink): New functions.
+
+	* sighandlers.cc (sigchld_handler): New function.
+	(install_signal_handlers): Add call to install
+	sigchld_handler. (This is #if 0'd out, waiting for code to help
+	determine which child exited and what to do about it).
+
+	* tree-expr.h (tree_oct_obj): New class.
+
+	* tree-expr.h (tree_multi_assignment_expression::preserve): New
+	data member.  Add arg with default value to constructors.  Change
+	callers as necessary.
+	* tree-expr.cc (~tree_multi_assignment_expression): Conditionally
+	delete lhs.
+
+	* parse.y (make_multi_val_ret): Pass matrix instead of getting it
+	from the global matrix list.
+	(expression): Extract matrix from matrix list before calling
+	make_multi_val_ret().
+
+	* parse.y (command): Handle new for loop syntax for structures.
+
+	* tree-plot.h (subplot_list): Include tree_print_code() in
+	initializer lists for constructors.
+	* tree-expr.h (tree_statement_list, tree_argument_list,
+	tree_parameter_list, tree_return_list, tree_global_init_list,
+	tree_if_command_list, ): Likewise.
+
+	* tree-cmd.h (tree_for_command::id_list): New data member.
+	(tree_for_command (tree_return_list*, tree_expression*,
+	tree_statement_list*, int, int)): Likewise.
+	* tree-cmd.cc (tree_for_command::eval): Handle for loops with
+	structures.
+	(do_for_loop_once (tree_return_list*, Octave_object&, int&)):
+	New form for handling for loops with structures.
+
+	* sysdep.cc (octave_ieee_init): Determine floating point format
+	here.
+	(native_float_format): New global variable.
+	(Fisieee): Compute return value from native_float_format, not by
+	using preprocessor macros.
+	* sysdep.h (enum floating_point_format): Move declaration here.
+	* load-save.cc: From here.
+	Always define all floating point format conversion routines.
+	(do_double_format_conversion, do_float_format_conversion):
+	Use native_float_format instead of preprocessor macros.
+
+Sat Apr  8 15:41:35 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile (TEMPLATE_SRC): New variable.
+	(DISTFILES): Add $(TEMPLATE_SRC).
+	(SOURCES): Delete Map.cc and SLStack.cc from here.
+
+	* variables.cc (install_builtin_variables): Use OCTAVE_VERSION
+	instead of version_string to initialize OCTAVE_VERSION.
+	* version.h (version_string): Delete.
+
+	* getopt.c (_getopt_internal): Initialize indfound to avoid warning.
+
+Fri Apr  7 15:29:41 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tc-inlines.h (REP_RHS_MATRIX): Just check to see if tc is real
+	or complex.  If conversion fails, return.
+
+Thu Apr  6 00:10:47 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* data.cc (Fstruct_contains): New function.
+
+	* tc-rep.cc (print_code): Add extra parens around while condition
+	to avoid warning.
+	* utils.cc (undo_string_escapes): Likewise.
+	* input.cc (decode_prompt_string): Likewise.  Also rewrite if
+	statement to avoid warning. 
+
+Tue Apr  4 22:54:17 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tree-expr.cc (tree_multi_assignment_expression::eval,
+	tree_simple_assignment_expression::eval):  Call print_constant
+	even if user_pref.print_answer_id_name is false.
+ 
+Mon Apr  3 17:57:14 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tc-inlines.h (TC_REP): Avoid redefinition.
+
+	* tree-const.h (do_binary_op, do_unary_op): Declare as friends of
+	tree_constant class too.
+
+	* tree-plot.h (subplot_using::have_values): Delete data member.
+	* tree-plot.cc (subplot_using::eval): Always recompute values.
+
+Fri Mar 31 10:18:32 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tc-rep.cc (print): Print open brace for structures here.
+	* tree-expr.cc (print_constant): Not here.
+
+	* symtab.cc (define): Don't delete arg if sv_fcn fails.
+
+	* tree-const.cc (print): New function.  Create ostrstream buffer
+	and pass it to rep->print().
+	* tree-const.h (eval (int)): Call print(), not rep->print().
+	* tc-rep.cc (structure_indent_level): New file-scope variable.
+	(print): New arg, output_buf, is stream to print to.
+	Print values of structure elements too.
+
+	* user-prefs.h (user_preferences): New field, struct_levels_to_print.
+	* user-prefs.cc (struct_levels_to_print): New function.
+	* variables.cc (install_builtin_variables): Add DEFVAR for new
+	variable struct_levels_to_print.
+
+	* tree-const.cc (print_as_scalar, print_as_structure): Move here
+	from tree-expr.cc and make extern.
+
+	* tree-expr.cc (print_as_structure): New function.
+	(print_constant): Use it.
+
+	* tree-expr.cc (print_constant): New arg, print_padding.
+	(tree_simple_assignment_expression::eval): Use print_constant
+	instead of duplicating code here.
+	(tree_multi_assignment_expression::eval): Likewise.
+
+Thu Mar 30 13:24:11 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (SOURCES): Add resource.cc.
+	* resource.cc: New file, extracted from timefns.cc.
+	(Fgetrusage): New function.
+	* timefns.cc (cputime): Delete (now implemented in a function file
+	using new getrusage function).
+
+Wed Mar 29 22:52:42 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* Makefile.in (SOURCES): Add strftime.c.
+	* strftime.c: New file, from sh-utils distribution.
+
+	* timefns.cc (mk_tm_map, extract_tm, Ftime, Fgmtime, Flocaltime,
+	Fmktime, Fstrftime): New basic time functions.
+	(Fclock, Fdate): Delete (now implemented in function files using new
+	time functions).
+
+Tue Mar 28 17:51:51 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* file-io.cc (return_valid_file, do_printf, do_scanf,
+	fclose_internal, feof_internal, ferror_internal, fflush_internal,
+	fgets_internal, fopen_internal, fread_internal, freport_internal,
+	frewind_internal, fseek_internal, ftell_internal,
+	fwrite_internal): Declare static.
+	* file-io.h: Delete extern declarations for them.
+
+Fri Mar 24 09:52:50 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* pr-output.cc (pr_col_num_header): New function.
+	(compact_format): New file-scope variable.
+	(set_format_style): Handle loose and compact formats.
+	(octave_print_internal (ostream&, const ComplexMatrix&, int)):
+	Replace duplicate code with call to pr_col_num_header().
+	(octave_print_internal (ostream&, const Matrix&, int): Likewise.
+	(octave_print_internal (ostream&, const Range&, int): Likewise.
+
+Tue Mar 21 08:44:48 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* mappers.cc (xgamma): Always use Slatec library function.
+	* (xlgamma): Likewise.
+	* Makefile.in (SOURCES): Don't include lgamma.c.
+
+Fri Mar 17 22:38:39 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tc-rep.cc (TC_REP::new): Don't try to keep track of newlist_tail.
+	Explicitly initialize newlist to zero.
+	* tree-const.cc (tree_constant::operator new): Likewise.
+
+Fri Mar 10 12:40:24 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* tree-cmd.cc (quit_loop_now): Declare inline.
+	(tree_for_command::do_for_loop_once): Split into two versions, one
+	for the general case and one for when the loop variable is a
+	simple identifier.
+	(DO_LOOP): New macro.  Move tests outside of loop.
+	(tree_for_command::eval): Speed up by checking to see if loop
+	variable is a simple identifier and by using DO_LOOP.
+
+	* tree-const.h: New union of rep and freeptr.  The freeptr element
+	is used for our custom memory management functions.
+
+	* tc-rep.h: Add freeptr element to anonymous union (for our custom
+	memory management functions).
+
+	* tree-const.cc (newlist, newlist_grow_size, newlist_tail): New
+	static variables.
+	(tree_constant::operator new): Always define to allow more
+	efficient allocation of single tree_constants.
+	(tree_constant::operator delete): Likewise, handle deletion of the
+	memory we allocate.
+
+	* tc-rep.cc (newlist, newlist_grow_size, newlist_tail): New static
+	variables.
+	(tree_constant::operator new): Always define to allow more
+	efficient allocation of single tree_constants.
+	(tree_constant::operator delete): Likewise, handle deletion of the
+	memory we allocate.
+
+Fri Mar  3 14:00:08 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* error.cc (verror): Terminate output_buf with ends.
+
+	* statdefs.h: Use C-style comment in first line instead of
+	C++-style comment.
+
+Mon Feb 27 10:11:18 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* parse.y (maybe_convert_to_ans_assign): Only lookup ans once.
+	* variables.cc (bind_ans): New function.
+	* tree-expr.cc (tree_identifier::eval (int)): Use it here.
+	(tree_identifier::eval (int, int, const Octave_object&): And here.
+
+	* tree-expr.cc (install_nargin_and_nargout): New function.
+	* tree-expr.h (tree_function::tree_function (tree_statement_list *,
+	symbol_table *, int, int)): Call it.
+
+	* tree-expr.cc (tree_function::bind_nargin_and_nargout): New function.
+	(tree_function::eval): Call it insead of the one from variables.cc.
+
+	* variables.cc (bind_nargin_and_nargout): #if 0 out.
+
+Sun Feb 26 00:17:06 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* load-save.cc (Fload, Fsave): Free fname returned by tilde_expand().
+	* dirfns.cc (Fls): Likewise.
+
+	* tree-expr.cc (tree_multi_assignment_expression::eval (int, int,
+	const Octave_object&)): Call tree_return_list::operator () (Pix)
+	explicitly.
+
+	* octave.cc (initialize_globals): Put TEXMF in the environment for
+	kpthsea.
+
+	* Makefile.in (OCTAVE_LIBS): Use @LIBINFO@ and @LIBREADLINE@,
+	substituted by configure.  Use kpathsea.a, not libkpathsea, so we
+	don't have to modify the kpathsea Makefile.
+
+Sat Feb 25 18:59:26 1995  John Eaton  <jwe at schoch.che.utexas.edu>
+
+	* pathsearch.cc: New file.
+	* pathsearch.h: New file.
+	* Makefile.in (INCLUDES): Include it in the list.
+	* dynamic-ld.cc, help.cc, utils.cc: Use it instead of repeating
+	identical code multiple times.
+
+	* variables.cc (install_builtin_variables): Only DEFVAR
+	suppress_verbose_help_message if USE_GNU_INFO.
+
+	* help.cc (Fhelp): Only handle -i if USE_GNU_INFO.
+	(additional_help_message): Only print message if USE_GNU_INFO.
+	(builtin_help): New function.
+	(help_from_info): New function.  Print warning if not USE_GNU_INFO.
+
+See ChangeLog.1 in the top level directory for earlier changes.
diff --git a/src/DASPK-opts.cc b/src/DASPK-opts.cc
new file mode 100644
index 0000000..4043a23
--- /dev/null
+++ b/src/DASPK-opts.cc
@@ -0,0 +1,750 @@
+// DO NOT EDIT!
+// Generated automatically from ../liboctave/DASPK-opts.in.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include "DASPK-opts.h"
+
+#include "defun-dld.h"
+#include "pr-output.h"
+
+#include "oct-obj.h"
+#include "utils.h"
+#include "pager.h"
+
+static DASPK_options daspk_opts;
+
+#define MAX_TOKENS 6
+
+struct DASPK_options_struct
+{
+  const char *keyword;
+  const char *kw_tok[MAX_TOKENS + 1];
+  int min_len[MAX_TOKENS + 1];
+  int min_toks_to_match;
+};
+
+#define NUM_OPTIONS 13
+
+static DASPK_options_struct DASPK_options_table [] =
+{
+  { "absolute tolerance",
+    { "absolute", "tolerance", 0, 0, 0, 0, 0, },
+    { 2, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "relative tolerance",
+    { "relative", "tolerance", 0, 0, 0, 0, 0, },
+    { 1, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "compute consistent initial condition",
+    { "compute", "consistent", "initial", "condition", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "use initial condition heuristics",
+    { "use", "initial", "condition", "heuristics", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "initial condition heuristics",
+    { "initial", "condition", "heuristics", 0, 0, 0, 0, },
+    { 3, 1, 0, 0, 0, 0, 0, }, 2, },
+
+  { "print initial condition info",
+    { "print", "initial", "condition", "info", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "exclude algebraic variables from error test",
+    { "exclude", "algebraic", "variables", "from", "error", "test", 0, },
+    { 2, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "algebraic variables",
+    { "algebraic", "variables", 0, 0, 0, 0, 0, },
+    { 2, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "enforce inequality constraints",
+    { "enforce", "inequality", "constraints", 0, 0, 0, 0, },
+    { 2, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "inequality constraint types",
+    { "inequality", "constraint", "types", 0, 0, 0, 0, },
+    { 3, 0, 0, 0, 0, 0, 0, }, 1, },
+
+  { "initial step size",
+    { "initial", "step", "size", 0, 0, 0, 0, },
+    { 3, 1, 0, 0, 0, 0, 0, }, 2, },
+
+  { "maximum order",
+    { "maximum", "order", 0, 0, 0, 0, 0, },
+    { 1, 1, 0, 0, 0, 0, 0, }, 2, },
+
+  { "maximum step size",
+    { "maximum", "step", "size", 0, 0, 0, 0, },
+    { 1, 1, 0, 0, 0, 0, 0, }, 2, },
+};
+
+static void
+print_DASPK_options (std::ostream& os)
+{
+  std::ostringstream buf;
+
+  os << "\n"
+     << "Options for DASPK include:\n\n"
+     << "  keyword                                             value\n"
+     << "  -------                                             -----\n";
+
+  DASPK_options_struct *list = DASPK_options_table;
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[0].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = daspk_opts.absolute_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[1].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = daspk_opts.relative_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[2].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = daspk_opts.compute_consistent_initial_condition ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[3].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = daspk_opts.use_initial_condition_heuristics ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[4].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = daspk_opts.initial_condition_heuristics ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[5].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = daspk_opts.print_initial_condition_info ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[6].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = daspk_opts.exclude_algebraic_variables_from_error_test ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[7].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<octave_idx_type> val = daspk_opts.algebraic_variables ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+	octave_idx_type len = val.length ();
+	Matrix tmp (len, 1);
+	for (octave_idx_type i = 0; i < len; i++)
+	  tmp(i,0) = val(i);
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[8].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = daspk_opts.enforce_inequality_constraints ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[9].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<octave_idx_type> val = daspk_opts.inequality_constraint_types ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+	octave_idx_type len = val.length ();
+	Matrix tmp (len, 1);
+	for (octave_idx_type i = 0; i < len; i++)
+	  tmp(i,0) = val(i);
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[10].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = daspk_opts.initial_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[11].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = daspk_opts.maximum_order ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[12].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = daspk_opts.maximum_step_size ();
+
+    os << val << "\n";
+  }
+
+  os << "\n";
+}
+
+static void
+set_DASPK_options (const std::string& keyword, const octave_value& val)
+{
+  DASPK_options_struct *list = DASPK_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        daspk_opts.set_absolute_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        daspk_opts.set_relative_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        daspk_opts.set_compute_consistent_initial_condition (tmp);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        daspk_opts.set_use_initial_condition_heuristics (tmp);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        daspk_opts.set_initial_condition_heuristics (tmp);
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        daspk_opts.set_print_initial_condition_info (tmp);
+    }
+  else if (keyword_almost_match (list[6].kw_tok, list[6].min_len,
+           keyword, list[6].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        daspk_opts.set_exclude_algebraic_variables_from_error_test (tmp);
+    }
+  else if (keyword_almost_match (list[7].kw_tok, list[7].min_len,
+           keyword, list[7].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<int> tmp = val.int_vector_value ();
+
+      if (! error_state)
+        daspk_opts.set_algebraic_variables (tmp);
+    }
+  else if (keyword_almost_match (list[8].kw_tok, list[8].min_len,
+           keyword, list[8].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        daspk_opts.set_enforce_inequality_constraints (tmp);
+    }
+  else if (keyword_almost_match (list[9].kw_tok, list[9].min_len,
+           keyword, list[9].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<int> tmp = val.int_vector_value ();
+
+      if (! error_state)
+        daspk_opts.set_inequality_constraint_types (tmp);
+    }
+  else if (keyword_almost_match (list[10].kw_tok, list[10].min_len,
+           keyword, list[10].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        daspk_opts.set_initial_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[11].kw_tok, list[11].min_len,
+           keyword, list[11].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        daspk_opts.set_maximum_order (tmp);
+    }
+  else if (keyword_almost_match (list[12].kw_tok, list[12].min_len,
+           keyword, list[12].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        daspk_opts.set_maximum_step_size (tmp);
+    }
+  else
+    {
+      warning ("daspk_options: no match for `%s'", keyword.c_str ());
+    }
+}
+
+static octave_value_list
+show_DASPK_options (const std::string& keyword)
+{
+  octave_value retval;
+
+  DASPK_options_struct *list = DASPK_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = daspk_opts.absolute_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = daspk_opts.relative_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = daspk_opts.compute_consistent_initial_condition ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = daspk_opts.use_initial_condition_heuristics ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = daspk_opts.initial_condition_heuristics ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = daspk_opts.print_initial_condition_info ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[6].kw_tok, list[6].min_len,
+           keyword, list[6].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = daspk_opts.exclude_algebraic_variables_from_error_test ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[7].kw_tok, list[7].min_len,
+           keyword, list[7].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<octave_idx_type> val = daspk_opts.algebraic_variables ();
+
+      if (val.length () == 1)
+        {
+          retval = static_cast<double> (val(0));
+        }
+      else
+        {
+	  octave_idx_type len = val.length ();
+	  ColumnVector tmp (len);
+	  for (octave_idx_type i = 0; i < len; i++)
+	    tmp(i) = val(i);
+          retval = tmp;
+        }
+    }
+  else if (keyword_almost_match (list[8].kw_tok, list[8].min_len,
+           keyword, list[8].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = daspk_opts.enforce_inequality_constraints ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[9].kw_tok, list[9].min_len,
+           keyword, list[9].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<octave_idx_type> val = daspk_opts.inequality_constraint_types ();
+
+      if (val.length () == 1)
+        {
+          retval = static_cast<double> (val(0));
+        }
+      else
+        {
+	  octave_idx_type len = val.length ();
+	  ColumnVector tmp (len);
+	  for (octave_idx_type i = 0; i < len; i++)
+	    tmp(i) = val(i);
+          retval = tmp;
+        }
+    }
+  else if (keyword_almost_match (list[10].kw_tok, list[10].min_len,
+           keyword, list[10].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = daspk_opts.initial_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[11].kw_tok, list[11].min_len,
+           keyword, list[11].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = daspk_opts.maximum_order ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[12].kw_tok, list[12].min_len,
+           keyword, list[12].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = daspk_opts.maximum_step_size ();
+
+      retval = val;
+    }
+  else
+    {
+      warning ("daspk_options: no match for `%s'", keyword.c_str ());
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (daspk_options, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} daspk_options (@var{opt}, @var{val})\n\
+When called with two arguments, this function\n\
+allows you set options parameters for the function @code{daspk}.\n\
+Given one argument, @code{daspk_options} returns the value of the\n\
+corresponding option.  If no arguments are supplied, the names of all\n\
+the available options and their current values are displayed.\n\
+\n\
+Options include\n\
+\n\
+ at table @code\n\
+ at item \"absolute tolerance\"\n\
+Absolute tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector, and the relative\n\
+tolerance must also be a vector of the same length.\n\
+ at item \"relative tolerance\"\n\
+Relative tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector, and the absolute\n\
+tolerance must also be a vector of the same length.\n\
+\n\
+The local error test applied at each integration step is\n\
+\n\
+ at example\n\
+ at group\n\
+  abs (local error in x(i))\n\
+       <= rtol(i) * abs (Y(i)) + atol(i)\n\
+ at end group\n\
+ at end example\n\
+ at item \"compute consistent initial condition\"\n\
+Denoting the differential variables in the state vector by @samp{Y_d}\n\
+and the algebraic variables by @samp{Y_a}, @code{ddaspk} can solve\n\
+one of two initialization problems:\n\
+\n\
+ at enumerate\n\
+ at item Given Y_d, calculate Y_a and Y'_d\n\
+ at item Given Y', calculate Y.\n\
+ at end enumerate\n\
+\n\
+In either case, initial values for the given components are input, and\n\
+initial guesses for the unknown components must also be provided as\n\
+input.  Set this option to 1 to solve the first problem, or 2 to solve\n\
+the second (the default is 0, so you must provide a set of\n\
+initial conditions that are consistent).\n\
+\n\
+If this option is set to a nonzero value, you must also set the\n\
+ at code{\"algebraic variables\"} option to declare which variables in the\n\
+problem are algebraic.\n\
+ at item \"use initial condition heuristics\"\n\
+Set to a nonzero value to use the initial condition heuristics options\n\
+described below.\n\
+ at item \"initial condition heuristics\"\n\
+A vector of the following parameters that can be used to control the\n\
+initial condition calculation.\n\
+\n\
+ at table @code\n\
+ at item MXNIT\n\
+Maximum number of Newton iterations (default is 5).\n\
+ at item MXNJ\n\
+Maximum number of Jacobian evaluations (default is 6).\n\
+ at item MXNH\n\
+Maximum number of values of the artificial stepsize parameter to be\n\
+tried if the @code{\"compute consistent initial condition\"} option has\n\
+been set to 1 (default is 5).\n\
+\n\
+Note that the maximum total number of Newton iterations allowed is\n\
+ at code{MXNIT*MXNJ*MXNH} if the @code{\"compute consistent initial\n\
+condition\"} option has been set to 1 and @code{MXNIT*MXNJ} if it is\n\
+set to 2.\n\
+ at item LSOFF\n\
+Set to a nonzero value to disable the linesearch algorithm (default is\n\
+0).\n\
+ at item STPTOL\n\
+Minimum scaled step in linesearch algorithm (default is eps^(2/3)).\n\
+ at item EPINIT\n\
+Swing factor in the Newton iteration convergence test.  The test is\n\
+applied to the residual vector, premultiplied by the approximate\n\
+Jacobian.  For convergence, the weighted RMS norm of this vector\n\
+(scaled by the error weights) must be less than @code{EPINIT*EPCON},\n\
+where @code{EPCON} = 0.33 is the analogous test constant used in the\n\
+time steps.  The default is @code{EPINIT} = 0.01.\n\
+ at end table\n\
+ at item \"print initial condition info\"\n\
+Set this option to a nonzero value to display detailed information\n\
+about the initial condition calculation (default is 0).\n\
+ at item \"exclude algebraic variables from error test\"\n\
+Set to a nonzero value to exclude algebraic variables from the error\n\
+test.  You must also set the @code{\"algebraic variables\"} option to\n\
+declare which variables in the problem are algebraic (default is 0).\n\
+ at item \"algebraic variables\"\n\
+A vector of the same length as the state vector.  A nonzero element\n\
+indicates that the corresponding element of the state vector is an\n\
+algebraic variable (i.e., its derivative does not appear explicitly\n\
+in the equation set.\n\
+\n\
+This option is required by the\n\
+ at code{compute consistent initial condition\"} and\n\
+ at code{\"exclude algebraic variables from error test\"} options.\n\
+ at item \"enforce inequality constraints\"\n\
+Set to one of the following values to enforce the inequality\n\
+constraints specified by the @code{\"inequality constraint types\"}\n\
+option (default is 0).\n\
+\n\
+ at enumerate\n\
+ at item To have constraint checking only in the initial condition calculation.\n\
+ at item To enforce constraint checking during the integration.\n\
+ at item To enforce both options 1 and 2.\n\
+ at end enumerate\n\
+ at item \"inequality constraint types\"\n\
+A vector of the same length as the state specifying the type of\n\
+inequality constraint.  Each element of the vector corresponds to an\n\
+element of the state and should be assigned one of the following\n\
+codes \n\
+\n\
+ at table @asis\n\
+ at item -2\n\
+Less than zero.\n\
+ at item -1\n\
+Less than or equal to zero.\n\
+ at item 0\n\
+Not constrained.\n\
+ at item 1\n\
+Greater than or equal to zero.\n\
+ at item 2\n\
+Greater than zero.\n\
+ at end table\n\
+\n\
+This option only has an effect if the\n\
+ at code{\"enforce inequality constraints\"} option is nonzero.\n\
+ at item \"initial step size\"\n\
+Differential-algebraic problems may occasionally suffer from severe\n\
+scaling difficulties on the first step.  If you know a great deal\n\
+about the scaling of your problem, you can help to alleviate this\n\
+problem by specifying an initial stepsize (default is computed\n\
+automatically).\n\
+ at item \"maximum order\"\n\
+Restrict the maximum order of the solution method.  This option must\n\
+be between 1 and 5, inclusive (default is 5).\n\
+ at item \"maximum step size\"\n\
+Setting the maximum stepsize will avoid passing over very large\n\
+regions (default is not specified).\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_DASPK_options (octave_stdout);
+    }
+  else if (nargin == 1 || nargin == 2)
+    {
+      std::string keyword = args(0).string_value ();
+
+      if (! error_state)
+        {
+          if (nargin == 1)
+            retval = show_DASPK_options (keyword);
+          else
+            set_DASPK_options (keyword, args(1));
+        }
+      else
+        error ("daspk_options: expecting keyword as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/DASRT-opts.cc b/src/DASRT-opts.cc
new file mode 100644
index 0000000..7508978
--- /dev/null
+++ b/src/DASRT-opts.cc
@@ -0,0 +1,369 @@
+// DO NOT EDIT!
+// Generated automatically from ../liboctave/DASRT-opts.in.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include "DASRT-opts.h"
+
+#include "defun-dld.h"
+#include "pr-output.h"
+
+#include "oct-obj.h"
+#include "utils.h"
+#include "pager.h"
+
+static DASRT_options dasrt_opts;
+
+#define MAX_TOKENS 3
+
+struct DASRT_options_struct
+{
+  const char *keyword;
+  const char *kw_tok[MAX_TOKENS + 1];
+  int min_len[MAX_TOKENS + 1];
+  int min_toks_to_match;
+};
+
+#define NUM_OPTIONS 6
+
+static DASRT_options_struct DASRT_options_table [] =
+{
+  { "absolute tolerance",
+    { "absolute", "tolerance", 0, 0, },
+    { 1, 0, 0, 0, }, 1, },
+
+  { "relative tolerance",
+    { "relative", "tolerance", 0, 0, },
+    { 1, 0, 0, 0, }, 1, },
+
+  { "initial step size",
+    { "initial", "step", "size", 0, },
+    { 1, 0, 0, 0, }, 1, },
+
+  { "maximum order",
+    { "maximum", "order", 0, 0, },
+    { 1, 1, 0, 0, }, 2, },
+
+  { "maximum step size",
+    { "maximum", "step", "size", 0, },
+    { 1, 1, 0, 0, }, 2, },
+
+  { "step limit",
+    { "step", "limit", 0, 0, },
+    { 1, 0, 0, 0, }, 1, },
+};
+
+static void
+print_DASRT_options (std::ostream& os)
+{
+  std::ostringstream buf;
+
+  os << "\n"
+     << "Options for DASRT include:\n\n"
+     << "  keyword                                             value\n"
+     << "  -------                                             -----\n";
+
+  DASRT_options_struct *list = DASRT_options_table;
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[0].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = dasrt_opts.absolute_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[1].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = dasrt_opts.relative_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[2].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = dasrt_opts.initial_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[3].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = dasrt_opts.maximum_order ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[4].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = dasrt_opts.maximum_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[5].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = dasrt_opts.step_limit ();
+
+    os << val << "\n";
+  }
+
+  os << "\n";
+}
+
+static void
+set_DASRT_options (const std::string& keyword, const octave_value& val)
+{
+  DASRT_options_struct *list = DASRT_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        dasrt_opts.set_absolute_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        dasrt_opts.set_relative_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        dasrt_opts.set_initial_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        dasrt_opts.set_maximum_order (tmp);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        dasrt_opts.set_maximum_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        dasrt_opts.set_step_limit (tmp);
+    }
+  else
+    {
+      warning ("dasrt_options: no match for `%s'", keyword.c_str ());
+    }
+}
+
+static octave_value_list
+show_DASRT_options (const std::string& keyword)
+{
+  octave_value retval;
+
+  DASRT_options_struct *list = DASRT_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = dasrt_opts.absolute_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = dasrt_opts.relative_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = dasrt_opts.initial_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = dasrt_opts.maximum_order ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = dasrt_opts.maximum_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = dasrt_opts.step_limit ();
+
+      retval = static_cast<double> (val);
+    }
+  else
+    {
+      warning ("dasrt_options: no match for `%s'", keyword.c_str ());
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (dasrt_options, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dasrt_options (@var{opt}, @var{val})\n\
+When called with two arguments, this function\n\
+allows you set options parameters for the function @code{dasrt}.\n\
+Given one argument, @code{dasrt_options} returns the value of the\n\
+corresponding option.  If no arguments are supplied, the names of all\n\
+the available options and their current values are displayed.\n\
+\n\
+Options include\n\
+\n\
+ at table @code\n\
+ at item \"absolute tolerance\"\n\
+Absolute tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector, and the relative\n\
+tolerance must also be a vector of the same length.\n\
+ at item \"relative tolerance\"\n\
+Relative tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector, and the absolute\n\
+tolerance must also be a vector of the same length.\n\
+\n\
+The local error test applied at each integration step is\n\
+ at example\n\
+ at group\n\
+  abs (local error in x(i)) <= ...\n\
+      rtol(i) * abs (Y(i)) + atol(i)\n\
+ at end group\n\
+ at end example\n\
+ at item \"initial step size\"\n\
+Differential-algebraic problems may occasionally suffer from severe\n\
+scaling difficulties on the first step.  If you know a great deal\n\
+about the scaling of your problem, you can help to alleviate this\n\
+problem by specifying an initial stepsize.\n\
+ at item \"maximum order\"\n\
+Restrict the maximum order of the solution method.  This option must\n\
+be between 1 and 5, inclusive.\n\
+ at item \"maximum step size\"\n\
+Setting the maximum stepsize will avoid passing over very large\n\
+regions.\n\
+ at item \"step limit\"\n\
+Maximum number of integration steps to attempt on a single call to the\n\
+underlying Fortran code.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_DASRT_options (octave_stdout);
+    }
+  else if (nargin == 1 || nargin == 2)
+    {
+      std::string keyword = args(0).string_value ();
+
+      if (! error_state)
+        {
+          if (nargin == 1)
+            retval = show_DASRT_options (keyword);
+          else
+            set_DASRT_options (keyword, args(1));
+        }
+      else
+        error ("dasrt_options: expecting keyword as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/DASSL-opts.cc b/src/DASSL-opts.cc
new file mode 100644
index 0000000..921e862
--- /dev/null
+++ b/src/DASSL-opts.cc
@@ -0,0 +1,442 @@
+// DO NOT EDIT!
+// Generated automatically from ../liboctave/DASSL-opts.in.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include "DASSL-opts.h"
+
+#include "defun-dld.h"
+#include "pr-output.h"
+
+#include "oct-obj.h"
+#include "utils.h"
+#include "pager.h"
+
+static DASSL_options dassl_opts;
+
+#define MAX_TOKENS 4
+
+struct DASSL_options_struct
+{
+  const char *keyword;
+  const char *kw_tok[MAX_TOKENS + 1];
+  int min_len[MAX_TOKENS + 1];
+  int min_toks_to_match;
+};
+
+#define NUM_OPTIONS 8
+
+static DASSL_options_struct DASSL_options_table [] =
+{
+  { "absolute tolerance",
+    { "absolute", "tolerance", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "relative tolerance",
+    { "relative", "tolerance", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "compute consistent initial condition",
+    { "compute", "consistent", "initial", "condition", 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "enforce nonnegativity constraints",
+    { "enforce", "nonnegativity", "constraints", 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "initial step size",
+    { "initial", "step", "size", 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "maximum order",
+    { "maximum", "order", 0, 0, 0, },
+    { 1, 1, 0, 0, 0, }, 2, },
+
+  { "maximum step size",
+    { "maximum", "step", "size", 0, 0, },
+    { 1, 1, 0, 0, 0, }, 2, },
+
+  { "step limit",
+    { "step", "limit", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+};
+
+static void
+print_DASSL_options (std::ostream& os)
+{
+  std::ostringstream buf;
+
+  os << "\n"
+     << "Options for DASSL include:\n\n"
+     << "  keyword                                             value\n"
+     << "  -------                                             -----\n";
+
+  DASSL_options_struct *list = DASSL_options_table;
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[0].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = dassl_opts.absolute_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[1].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = dassl_opts.relative_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[2].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = dassl_opts.compute_consistent_initial_condition ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[3].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = dassl_opts.enforce_nonnegativity_constraints ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[4].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = dassl_opts.initial_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[5].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = dassl_opts.maximum_order ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[6].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = dassl_opts.maximum_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[7].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = dassl_opts.step_limit ();
+
+    os << val << "\n";
+  }
+
+  os << "\n";
+}
+
+static void
+set_DASSL_options (const std::string& keyword, const octave_value& val)
+{
+  DASSL_options_struct *list = DASSL_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        dassl_opts.set_absolute_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        dassl_opts.set_relative_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        dassl_opts.set_compute_consistent_initial_condition (tmp);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        dassl_opts.set_enforce_nonnegativity_constraints (tmp);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        dassl_opts.set_initial_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        dassl_opts.set_maximum_order (tmp);
+    }
+  else if (keyword_almost_match (list[6].kw_tok, list[6].min_len,
+           keyword, list[6].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        dassl_opts.set_maximum_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[7].kw_tok, list[7].min_len,
+           keyword, list[7].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        dassl_opts.set_step_limit (tmp);
+    }
+  else
+    {
+      warning ("dassl_options: no match for `%s'", keyword.c_str ());
+    }
+}
+
+static octave_value_list
+show_DASSL_options (const std::string& keyword)
+{
+  octave_value retval;
+
+  DASSL_options_struct *list = DASSL_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = dassl_opts.absolute_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = dassl_opts.relative_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = dassl_opts.compute_consistent_initial_condition ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = dassl_opts.enforce_nonnegativity_constraints ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = dassl_opts.initial_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = dassl_opts.maximum_order ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[6].kw_tok, list[6].min_len,
+           keyword, list[6].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = dassl_opts.maximum_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[7].kw_tok, list[7].min_len,
+           keyword, list[7].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = dassl_opts.step_limit ();
+
+      retval = static_cast<double> (val);
+    }
+  else
+    {
+      warning ("dassl_options: no match for `%s'", keyword.c_str ());
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (dassl_options, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dassl_options (@var{opt}, @var{val})\n\
+When called with two arguments, this function\n\
+allows you set options parameters for the function @code{dassl}.\n\
+Given one argument, @code{dassl_options} returns the value of the\n\
+corresponding option.  If no arguments are supplied, the names of all\n\
+the available options and their current values are displayed.\n\
+\n\
+Options include\n\
+\n\
+ at table @code\n\
+ at item \"absolute tolerance\"\n\
+Absolute tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector, and the relative\n\
+tolerance must also be a vector of the same length.\n\
+ at item \"relative tolerance\"\n\
+Relative tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector, and the absolute\n\
+tolerance must also be a vector of the same length.\n\
+\n\
+The local error test applied at each integration step is\n\
+\n\
+ at example\n\
+ at group\n\
+  abs (local error in x(i))\n\
+       <= rtol(i) * abs (Y(i)) + atol(i)\n\
+ at end group\n\
+ at end example\n\
+ at item \"compute consistent initial condition\"\n\
+If nonzero, @code{dassl} will attempt to compute a consistent set of initial\n\
+conditions.  This is generally not reliable, so it is best to provide\n\
+a consistent set and leave this option set to zero.\n\
+ at item \"enforce nonnegativity constraints\"\n\
+If you know that the solutions to your equations will always be\n\
+nonnegative, it may help to set this parameter to a nonzero\n\
+value.  However, it is probably best to try leaving this option set to\n\
+zero first, and only setting it to a nonzero value if that doesn't\n\
+work very well.\n\
+ at item \"initial step size\"\n\
+Differential-algebraic problems may occasionally suffer from severe\n\
+scaling difficulties on the first step.  If you know a great deal\n\
+about the scaling of your problem, you can help to alleviate this\n\
+problem by specifying an initial stepsize.\n\
+ at item \"maximum order\"\n\
+Restrict the maximum order of the solution method.  This option must\n\
+be between 1 and 5, inclusive.\n\
+ at item \"maximum step size\"\n\
+Setting the maximum stepsize will avoid passing over very large\n\
+regions  (default is not specified).\n\
+ at item \"step limit\"\n\
+Maximum number of integration steps to attempt on a single call to the\n\
+underlying Fortran code.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_DASSL_options (octave_stdout);
+    }
+  else if (nargin == 1 || nargin == 2)
+    {
+      std::string keyword = args(0).string_value ();
+
+      if (! error_state)
+        {
+          if (nargin == 1)
+            retval = show_DASSL_options (keyword);
+          else
+            set_DASSL_options (keyword, args(1));
+        }
+      else
+        error ("dassl_options: expecting keyword as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__contourc__.cc b/src/DLD-FUNCTIONS/__contourc__.cc
new file mode 100644
index 0000000..788ab75
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__contourc__.cc
@@ -0,0 +1,335 @@
+/* Contour lines for function evaluated on a grid.
+
+Copyright (C) 2007, 2008 Kai Habel
+Copyright (C) 2004, 2007 Shai Ayal
+
+Adapted to an oct file from the stand alone contourl by Victro Munoz
+Copyright (C) 2004 Victor Munoz
+
+Based on contour plot routine (plcont.c) in PLPlot package
+http://plplot.org/
+
+Copyright (C) 1995, 2000, 2001 Maurice LeBrun
+Copyright (C) 2000, 2002 Joao Cardoso
+Copyright (C) 2000, 2001, 2002, 2004  Alan W. Irwin
+Copyright (C) 2004  Andrew Ross
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+static Matrix this_contour;
+static Matrix contourc;
+static int elem;
+
+// This is the quanta in which we increase this_contour.
+#define CONTOUR_QUANT 50
+
+// Add a coordinate point (x,y) to this_contour.
+
+static void
+add_point (double x, double y)
+{
+  if (elem % CONTOUR_QUANT == 0)
+    this_contour = this_contour.append (Matrix (2, CONTOUR_QUANT, 0));
+
+  this_contour (0, elem) = x;
+  this_contour (1, elem) = y;
+  elem++;
+}
+
+// Add contents of current contour to contourc.
+// this_contour.cols () - 1;
+
+static void
+end_contour (void)
+{
+  if (elem > 2)
+    {
+      this_contour (1, 0) = elem - 1;
+      contourc = contourc.append (this_contour.extract_n (0, 0, 2, elem));
+    }
+
+  this_contour = Matrix ();
+  elem = 0;
+}
+
+// Start a new contour, and add contents of current one to contourc.
+
+static void
+start_contour (double lvl, double x, double y)
+{
+  end_contour ();
+  this_contour.resize (2, 0);
+  add_point (lvl, 0);
+  add_point (x, y);
+}
+
+static void
+drawcn (const RowVector& X, const RowVector& Y, const Matrix& Z,
+	double lvl, int r, int c, double ct_x, double ct_y,
+	unsigned int start_edge, bool first, charMatrix& mark)
+{
+  double px[4], py[4], pz[4], tmp;
+  unsigned int stop_edge, next_edge, pt[2];
+  int next_r, next_c;
+
+  //get x, y, and z - lvl for current facet
+  px[0] = px[3] = X(c);
+  px[1] = px[2] = X(c+1);
+
+  py[0] = py[1] = Y(r);
+  py[2] = py[3] = Y(r+1);
+
+  pz[3] = Z(r+1, c) - lvl;
+  pz[2] = Z(r+1, c + 1) - lvl;
+  pz[1] = Z(r, c+1) - lvl;
+  pz[0] = Z(r, c) - lvl;
+
+  // Facet edge and point naming assignment.
+  //
+  //  0-----1   .-0-.
+  //  |     |   |   |
+  //  |     |   3   1
+  //  |     |   |   |
+  //  3-----2   .-2-.
+
+  // Get mark value of current facet.
+  char id = static_cast<char> (mark(r, c));
+
+  // Check startedge s.
+  if (start_edge == 255)
+    {
+      // Find start edge.
+      for (unsigned int k = 0; k < 4; k++)
+        if (static_cast<char> (1 << k) & id)
+          start_edge = k;
+    }
+
+  if (start_edge == 255)
+    return;
+
+  // Decrease mark value of current facet for start edge.
+  mark(r, c) -= static_cast<char> (1 << start_edge);
+
+  // Next point (clockwise).
+  pt[0] = start_edge;
+  pt[1] = (pt[0] + 1) % 4;
+
+  // Calculate contour segment start if first of contour.
+  if (first)
+    {
+      tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]);
+
+      if (xisnan (tmp))
+        ct_x = ct_y = 0.5;
+      else
+	{
+	  ct_x = px[pt[0]] + (px[pt[1]] - px[pt[0]])/(1 + tmp);
+	  ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp);
+	}
+
+      start_contour (lvl, ct_x, ct_y);
+    }
+
+  // Find stop edge.
+  // FIXME -- perhaps this should use a while loop?
+  for (unsigned int k = 1; k <= 4; k++)
+    {
+      if (start_edge == 0 || start_edge == 2)
+        stop_edge = (start_edge + k) % 4;
+      else
+        stop_edge = (start_edge - k) % 4;
+
+      if (static_cast<char> (1 << stop_edge) & id)
+        break;
+    }
+
+  pt[0] = stop_edge;
+  pt[1] = (pt[0] + 1) % 4;
+  tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]);
+
+  if (xisnan (tmp))
+    ct_x = ct_y = 0.5;
+  else
+    {
+      ct_x = px[pt[0]] + (px[pt[1]] - px[pt[0]])/(1 + tmp);
+      ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp);
+    }
+
+  // Add point to contour.
+  add_point (ct_x, ct_y);
+
+  // Decrease id value of current facet for start edge.
+  mark(r, c) -= static_cast<char> (1 << stop_edge);
+
+  // Find next facet.
+  next_c = c;
+  next_r = r;
+
+  if (stop_edge == 0)
+    next_r--; 
+  else if (stop_edge == 1)
+    next_c++;
+  else if (stop_edge == 2)
+    next_r++;
+  else if (stop_edge == 3)
+    next_c--;
+
+  // Check if next facet is not done yet.
+  // Go to next facet.
+  if (next_r >= 0 && next_c >= 0 && next_r < mark.rows ()
+      && next_c < mark.cols () && mark(next_r, next_c) > 0)
+    {
+      next_edge = (stop_edge + 2) % 4;
+      drawcn (X, Y, Z, lvl, next_r, next_c, ct_x, ct_y, next_edge, false, mark);
+    }
+}
+
+static void
+mark_facets (const Matrix& Z, charMatrix& mark, double lvl)
+{
+  unsigned int nr = mark.rows ();
+  unsigned int nc = mark.cols ();
+
+  double f[4];
+
+  for (unsigned int c = 0; c < nc; c++)
+    for (unsigned int r = 0; r < nr; r++)
+      {
+        f[0] = Z(r, c) - lvl;
+        f[1] = Z(r, c+1) - lvl;
+        f[3] = Z(r+1, c) - lvl;
+        f[2] = Z(r+1, c+1) - lvl;
+
+        for (unsigned int i = 0; i < 4; i++)
+          if (fabs(f[i]) < DBL_EPSILON)
+            f[i] = DBL_EPSILON;
+
+        if (f[1] * f[2] < 0)
+	  mark(r, c) += 2;
+
+        if (f[0] * f[3] < 0)
+	  mark(r, c) += 8;
+      }
+
+  for (unsigned int r = 0; r < nr; r++)
+    for (unsigned int c = 0; c < nc; c++)
+      {
+        f[0] = Z(r, c) - lvl;
+        f[1] = Z(r, c+1) - lvl;
+        f[3] = Z(r+1, c) - lvl;
+        f[2] = Z(r+1, c+1) - lvl;
+
+        for (unsigned int i = 0; i < 4; i++)
+          if (fabs(f[i]) < DBL_EPSILON)
+            f[i] = DBL_EPSILON;
+
+        if (f[0] * f[1] < 0)
+	  mark(r, c) += 1;
+
+        if (f[2] * f[3] < 0)
+	  mark(r, c) += 4;
+      }
+}
+
+static void
+cntr (const RowVector& X, const RowVector& Y, const Matrix& Z, double lvl)
+{
+  unsigned int nr = Z.rows ();
+  unsigned int nc = Z.cols ();
+
+  charMatrix mark (nr - 1, nc - 1, 0);
+
+  mark_facets (Z, mark, lvl);
+
+  // Find contours that start at a domain edge.
+
+  for (unsigned int c = 0; c < nc - 1; c++)
+    {
+      // Top.
+      if (mark(0, c) & 1)
+        drawcn (X, Y, Z, lvl, 0, c, 0.0, 0.0, 0, true, mark);
+
+      // Bottom.
+      if (mark(nr - 2, c) & 4)
+	drawcn (X, Y, Z, lvl, nr - 2, c, 0.0, 0.0, 2, true, mark);
+    }
+
+  for (unsigned int r = 0; r < nr - 1; r++)
+    {
+      // Left.
+      if (mark(r, 0) & 8)
+        drawcn (X, Y, Z, lvl, r, 0, 0.0, 0.0, 3, true, mark);
+
+      // Right.
+      if (mark(r, nc - 2) & 2)
+        drawcn (X, Y, Z, lvl, r, nc - 2, 0.0, 0.0, 1, true, mark);
+    }
+
+  for (unsigned int r = 0; r < nr - 1; r++)
+    for (unsigned int c = 0; c < nc - 1; c++)
+      if (mark (r, c) > 0)
+        drawcn (X, Y, Z, lvl, r, c, 0.0, 0.0, 255, true, mark);
+}
+
+DEFUN_DLD (__contourc__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} __contourc__ (@var{x}, @var{y}, @var{z}, @var{levels})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 4)
+    {
+      RowVector X = args (0).row_vector_value ();
+      RowVector Y = args (1).row_vector_value ();
+      Matrix Z = args (2).matrix_value ();
+      RowVector L = args (3).row_vector_value ();
+
+      if (! error_state)
+	{
+	  contourc.resize (2, 0);
+
+	  for (int i = 0; i < L.length (); i++)
+	    cntr (X, Y, Z, L (i));
+
+	  end_contour ();
+
+	  retval = contourc;
+	}
+      else
+	error ("__contourc__: invalid argument values");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__convn__.cc b/src/DLD-FUNCTIONS/__convn__.cc
new file mode 100644
index 0000000..b0e2393
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__convn__.cc
@@ -0,0 +1,240 @@
+/*
+
+Copyright (C) 2008 Soren Hauberg
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+
+#include "dNDArray.h"
+#include "CNDArray.h"
+
+#include "defun-dld.h"
+
+template <class T1, class T2>
+class
+octave_convn_traits
+{
+public:
+  // The return type for a T1 by T2 convn operation.
+  typedef T1 TR;
+};
+
+#define OCTAVE_CONVN_TRAIT(T1, T2, T3) \
+  template<> \
+  class octave_convn_traits <T1, T2> \
+  { \
+  public: \
+    typedef T3 TR; \
+  }
+
+OCTAVE_CONVN_TRAIT (NDArray, NDArray, NDArray);
+OCTAVE_CONVN_TRAIT (ComplexNDArray, NDArray, ComplexNDArray);
+OCTAVE_CONVN_TRAIT (NDArray, ComplexNDArray, ComplexNDArray);
+OCTAVE_CONVN_TRAIT (ComplexNDArray, ComplexNDArray, ComplexNDArray);
+
+OCTAVE_CONVN_TRAIT (FloatNDArray, FloatNDArray, FloatNDArray);
+OCTAVE_CONVN_TRAIT (FloatComplexNDArray, FloatNDArray, FloatComplexNDArray);
+OCTAVE_CONVN_TRAIT (FloatNDArray, FloatComplexNDArray, FloatComplexNDArray);
+OCTAVE_CONVN_TRAIT (FloatComplexNDArray, FloatComplexNDArray, FloatComplexNDArray);
+
+// FIXME -- this function should maybe be available in liboctave?
+template <class MTa, class MTb> 
+octave_value
+convn (const MTa& a, const MTb& b)
+{
+  octave_value retval;
+
+  // Get sizes
+  const octave_idx_type ndims = a.ndims ();
+  const octave_idx_type b_numel = b.numel ();
+
+  const dim_vector a_size = a.dims ();
+  const dim_vector b_size = b.dims ();
+  
+  if (ndims != b.ndims ())
+    {
+      error ("__convn__: first and second argument must have same dimensionality");
+      return retval;
+    }
+
+  // Allocate output
+  dim_vector out_size (a_size);
+  for (octave_idx_type n = 0; n < ndims; n++)
+    out_size(n) = std::max (a_size(n) - b_size(n) + 1,
+			    static_cast<octave_idx_type> (0));
+
+  typedef typename octave_convn_traits<MTa, MTb>::TR MTout;
+
+  MTout out (out_size);
+
+  const octave_idx_type out_numel = out.numel ();
+  
+  // Iterate over every element of 'out'.
+  dim_vector idx_dim (ndims);
+
+  Array<octave_idx_type> a_idx (idx_dim);
+  Array<octave_idx_type> b_idx (idx_dim);
+  Array<octave_idx_type> out_idx (idx_dim, 0);
+
+  for (octave_idx_type i = 0; i < out_numel; i++)
+    {
+      OCTAVE_QUIT;
+
+      // For each neighbour
+      typename MTout::element_type sum = 0;
+
+      for (octave_idx_type n = 0; n < ndims; n++)
+        b_idx(n) = 0;
+
+      for (octave_idx_type j = 0; j < b_numel; j++)
+        {
+          for (octave_idx_type n = 0; n < ndims; n++)
+            a_idx(n) = out_idx(n) + (b_size(n) - 1 - b_idx(n));
+
+          sum += a(a_idx) * b(b_idx);
+
+          b.increment_index (b_idx, b_size);
+      }
+            
+      // Compute filter result
+      out(out_idx) = sum;
+
+      // Prepare for next iteration
+      out.increment_index (out_idx, out_size);
+    }
+    
+  return out;
+}
+
+DEFUN_DLD (__convn__, args, , 
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} __convn__(@var{a}, @var{b})\n\
+Undocumented internal function.\n\
+ at end deftypefn\n\
+")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      if (args(0).is_single_type() || args(1).is_single_type())
+	{
+	  if (args(0).is_real_type ())
+	    {
+	      if (args(1).is_real_type ())
+		{
+		  const FloatNDArray a = args (0).float_array_value ();
+		  const FloatNDArray b = args (1).float_array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else if (args(1).is_complex_type ())
+		{
+		  const FloatNDArray a = args (0).float_array_value ();
+		  const FloatComplexNDArray b = args (1).float_complex_array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else
+		error ("__convn__: invalid call");
+	    }
+	  else if (args(0).is_complex_type ())
+	    {
+	      if (args(1).is_complex_type ())
+		{
+		  const FloatComplexNDArray a = args (0).float_complex_array_value ();
+		  const FloatComplexNDArray b = args (1).float_complex_array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else if (args(1).is_real_type ())
+		{
+		  const FloatComplexNDArray a = args (0).float_complex_array_value ();
+		  const FloatNDArray b = args (1).float_array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else
+		error ("__convn__: invalid call");
+	    }
+	  else
+	    error ("__convn__: invalid call");
+	}
+      else
+	{
+	  if (args(0).is_real_type ())
+	    {
+	      if (args(1).is_real_type ())
+		{
+		  const NDArray a = args (0).array_value ();
+		  const NDArray b = args (1).array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else if (args(1).is_complex_type ())
+		{
+		  const NDArray a = args (0).array_value ();
+		  const ComplexNDArray b = args (1).complex_array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else
+		error ("__convn__: invalid call");
+	    }
+	  else if (args(0).is_complex_type ())
+	    {
+	      if (args(1).is_complex_type ())
+		{
+		  const ComplexNDArray a = args (0).complex_array_value ();
+		  const ComplexNDArray b = args (1).complex_array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else if (args(1).is_real_type ())
+		{
+		  const ComplexNDArray a = args (0).complex_array_value ();
+		  const NDArray b = args (1).array_value ();
+
+		  if (! error_state)
+		    retval = convn (a, b);
+		}
+	      else
+		error ("__convn__: invalid call");
+	    }
+	  else
+	    error ("__convn__: invalid call");
+	}
+    }
+  else
+    print_usage ();
+    
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__delaunayn__.cc b/src/DLD-FUNCTIONS/__delaunayn__.cc
new file mode 100644
index 0000000..dba8ad0
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__delaunayn__.cc
@@ -0,0 +1,224 @@
+/*
+
+Copyright (C) 2000, 2007 Kai Habel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+  16. July 2000 - Kai Habel: first release
+
+  25. September 2002 - Changes by Rafael Laboissiere <rafael at laboissiere.net>
+
+  * Added Qbb option to normalize the input and avoid crashes in Octave.
+  * delaunayn accepts now a second (optional) argument that must be a string
+  containing extra options to the qhull command.
+  * Fixed doc string.  The dimension of the result matrix is [m, dim+1], and
+  not [n, dim-1].
+
+  6. June 2006: Changes by Alexander Barth <abarth at marine.usf.edu>
+
+  * triangulate non-simplicial facets 
+  * allow options to be specified as cell array of strings
+  * change the default options (for compatibility with matlab)
+*/
+
+#include <iostream>
+#include <string>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "oct.h"
+#include "ov-cell.h"
+
+#ifdef HAVE_QHULL
+extern "C" {
+#include <qhull/qhull_a.h>
+}
+
+#ifdef NEED_QHULL_VERSION
+char qh_version[] = "__delaunayn__.oct 2007-08-21";
+#endif
+#endif
+
+DEFUN_DLD (__delaunayn__, args, ,
+	   "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{T} =} __delaunayn__ (@var{P}[, @var{opt}])\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+
+{
+  octave_value_list retval;
+
+#ifdef HAVE_QHULL
+
+  retval(0) = 0.0;
+  std::string options = "";
+
+  int nargin = args.length ();
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  Matrix p (args(0).matrix_value ());
+  const octave_idx_type dim = p.columns ();
+  const octave_idx_type n = p.rows ();
+
+  // default options
+  if (dim <= 3)
+    options = "Qt Qbb Qc";
+  else
+    options = "Qt Qbb Qc Qx";
+
+
+  if (nargin == 2)
+    {
+    if (args(1).is_empty ())
+      {
+	// keep default options
+      }
+    else if (args(1).is_string ()) 
+      {
+	// option string is directly provided
+	options = args(1).string_value ();
+      }
+    else if (args(1).is_cell ()) 
+      {
+	options = "";
+
+	Cell c = args(1).cell_value ();
+	for (octave_idx_type i = 0; i < c.numel (); i++)
+	  {
+
+	    if (! c.elem(i).is_string ()) 
+	      {
+		error ("__delaunayn__: all options must be strings");
+		return retval;
+	      }
+
+	    options = options + c.elem(i).string_value () + " ";
+	  }
+      }
+    else 
+      {
+	error ("__delaunayn__: second argument must be a string, cell of stringsor empty");
+	return retval;
+      }
+    } 
+
+  //octave_stdout << "options " << options << std::endl;
+
+  if (n > dim + 1) 
+    {
+      p = p.transpose ();
+      double *pt_array = p.fortran_vec ();
+      boolT ismalloc = false;
+
+      OCTAVE_LOCAL_BUFFER (char, flags, 250);
+
+      sprintf (flags, "qhull d %s", options.c_str ());
+
+      // If you want some debugging information replace the 0 pointer
+      // with stdout or some other file open for writing.
+
+      FILE *outfile = 0;
+      FILE *errfile = stderr;
+
+      if (! qh_new_qhull (dim, n, pt_array, ismalloc, flags, outfile, errfile))
+	{
+	  // triangulate non-simplicial facets
+	  qh_triangulate (); 
+
+	  facetT *facet;
+	  vertexT *vertex, **vertexp;
+	  octave_idx_type nf = 0, i = 0;
+
+	  FORALLfacets
+	    {
+	      if (! facet->upperdelaunay)
+		nf++;
+
+	      // Double check
+	      if (! facet->simplicial) 
+		{
+		  error ("__delaunayn__: Qhull returned non-simplicial facets -- try delaunayn with different options");
+		  break;
+		}
+	    }
+
+	  Matrix simpl (nf, dim+1);
+
+	  FORALLfacets
+	    {
+	      if (! facet->upperdelaunay) 
+		{
+		  octave_idx_type j = 0;
+
+		  FOREACHvertex_ (facet->vertices)
+		    {
+		      // if delaunayn crashes, enable this check
+#if 0
+		      if (j > dim)
+			{
+			  error ("__delaunayn__: internal error. Qhull returned non-simplicial facets");
+			  return retval;
+			}
+#endif
+
+		      simpl(i, j++) = 1 + qh_pointid(vertex->point);
+		    }
+		  i++;
+		}
+	    }
+
+	  retval(0) = simpl;
+
+	  // free long memory
+	  qh_freeqhull (! qh_ALL);
+
+	  // free short memory and memory allocator
+	  int curlong, totlong;
+	  qh_memfreeshort (&curlong, &totlong);
+
+	  if (curlong || totlong)
+	    warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
+		     totlong, curlong);
+	}
+      else
+	error ("__delaunayn__: qhull failed.");
+    }
+  else if (n == dim + 1) 
+    {
+      // one should check if nx points span a simplex
+      // I will look at this later.
+      RowVector vec (n);
+      for (octave_idx_type i = 0; i < n; i++) 
+	vec(i) = i + 1.0;
+
+      retval(0) = vec;
+    }
+
+#else
+  error ("__delaunayn__: not available in this version of Octave");
+#endif
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__dsearchn__.cc b/src/DLD-FUNCTIONS/__dsearchn__.cc
new file mode 100644
index 0000000..9bb5d67
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__dsearchn__.cc
@@ -0,0 +1,108 @@
+/*
+
+Copyright (C) 2007 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-math.h"
+//FIXME -- Octave sources should use individual include files, not oct.h.
+#include "oct.h"
+
+DEFUN_DLD (__dsearchn__, args, ,
+	"-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{idx}, @var{d}] =} dsearch (@var{x}, @var{xi})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  int nargin = args.length();
+  octave_value_list retval;
+
+  if (nargin != 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  Matrix x = args(0).matrix_value().transpose ();
+  Matrix xi = args(1).matrix_value().transpose ();
+
+  if (! error_state)
+    {
+      if (x.rows() != xi.rows() || x.columns() < 1)
+	error ("__dsearch__: dimensional mismatch");
+      else
+	{
+	  octave_idx_type n = x.rows();
+	  octave_idx_type nx = x.columns();
+	  octave_idx_type nxi = xi.columns();
+
+	  ColumnVector idx (nxi);
+	  double *pidx = idx.fortran_vec ();
+	  ColumnVector dist (nxi);
+	  double *pdist = dist.fortran_vec ();
+
+#define DIST(dd, y, yi, m) \
+  dd = 0.; \
+  for (octave_idx_type k = 0; k < m; k++) \
+   { \
+     double yd = y[k] - yi[k]; \
+     dd += yd * yd; \
+   } \
+  dd = sqrt (dd);
+
+	  const double *pxi = xi.fortran_vec ();
+	  for (octave_idx_type i = 0; i < nxi; i++)
+	    {
+	      double d0;
+	      const double *px = x.fortran_vec ();
+	      DIST(d0, px, pxi, n);
+	      *pidx = 1.;
+	      for (octave_idx_type j = 1; j < nx; j++)
+		{
+		  px += n;
+		  double d;
+		  DIST (d, px, pxi, n);
+		  if (d < d0)
+		    {
+		      d0 = d;
+		      *pidx = static_cast<double>(j + 1);
+		    }
+		  OCTAVE_QUIT;
+ 		}
+
+	      *pdist++ = d0; 
+	      pidx++;
+	      pxi += n;
+	    }
+
+	  retval(1) = dist;
+	  retval(0) = idx;
+	}
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__glpk__.cc b/src/DLD-FUNCTIONS/__glpk__.cc
new file mode 100644
index 0000000..ae3cd45
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__glpk__.cc
@@ -0,0 +1,858 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 Nicolo' Giorgetti
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <csetjmp>
+#include <ctime>
+
+#include "lo-ieee.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "pager.h"
+
+#if defined (HAVE_GLPK)
+
+extern "C"
+{
+#if defined (HAVE_GLPK_GLPK_H)
+#include <glpk/glpk.h>
+#else
+#include <glpk.h>
+#endif
+
+#if 0
+#ifdef GLPK_PRE_4_14
+
+#ifndef _GLPLIB_H
+#include <glplib.h>
+#endif
+#ifndef lib_set_fault_hook
+#define lib_set_fault_hook lib_fault_hook
+#endif
+#ifndef lib_set_print_hook
+#define lib_set_print_hook lib_print_hook
+#endif
+
+#else
+
+void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info);
+void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info);
+
+#endif
+#endif
+}
+
+#define NIntP 17
+#define NRealP 10
+
+int lpxIntParam[NIntP] = {
+  0,
+  1,
+  0,
+  1,
+  0,
+  -1,
+  0,
+  200,
+  1,
+  2,
+  0,
+  1,
+  0,
+  0,
+  2,
+  2,
+  1
+};
+
+int IParam[NIntP] = {
+  LPX_K_MSGLEV,
+  LPX_K_SCALE,
+  LPX_K_DUAL,
+  LPX_K_PRICE,
+  LPX_K_ROUND,
+  LPX_K_ITLIM,
+  LPX_K_ITCNT,
+  LPX_K_OUTFRQ,
+  LPX_K_MPSINFO,
+  LPX_K_MPSOBJ,
+  LPX_K_MPSORIG,
+  LPX_K_MPSWIDE,
+  LPX_K_MPSFREE,
+  LPX_K_MPSSKIP,
+  LPX_K_BRANCH,
+  LPX_K_BTRACK,
+  LPX_K_PRESOL
+};
+
+
+double lpxRealParam[NRealP] = {
+  0.07,
+  1e-7,
+  1e-7,
+  1e-9,
+  -DBL_MAX,
+  DBL_MAX,
+  -1.0,
+  0.0,
+  1e-6,
+  1e-7
+};
+
+int RParam[NRealP] = {
+  LPX_K_RELAX,
+  LPX_K_TOLBND,
+  LPX_K_TOLDJ,
+  LPX_K_TOLPIV,
+  LPX_K_OBJLL,
+  LPX_K_OBJUL,
+  LPX_K_TMLIM,
+  LPX_K_OUTDLY,
+  LPX_K_TOLINT,
+  LPX_K_TOLOBJ
+};
+
+static jmp_buf mark;  //-- Address for long jump to jump to
+
+#if 0
+int
+glpk_fault_hook (void * /* info */, char *msg)
+{
+  error ("CRITICAL ERROR in GLPK: %s", msg);
+  longjmp (mark, -1);
+}
+
+int
+glpk_print_hook (void * /* info */, char *msg)
+{
+  message (0, "%s", msg);
+  return 1;
+}
+#endif
+
+int
+glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
+      double *a, double *b, char *ctype, int *freeLB, double *lb,
+      int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
+      int save_pb, double *xmin, double *fmin, double *status,
+      double *lambda, double *redcosts, double *time, double *mem)
+{
+  int errnum;
+  int typx = 0;
+  int method;
+
+  clock_t t_start = clock();
+
+#if 0
+#ifdef GLPK_PRE_4_14
+  lib_set_fault_hook (0, glpk_fault_hook);
+#else
+  _glp_lib_fault_hook (glpk_fault_hook, 0);
+#endif
+
+  if (lpxIntParam[0] > 1)
+#ifdef GLPK_PRE_4_14
+    lib_set_print_hook (0, glpk_print_hook);
+#else
+    _glp_lib_print_hook (glpk_print_hook, 0);
+#endif
+#endif
+
+  LPX *lp = lpx_create_prob ();
+
+
+  //-- Set the sense of optimization
+  if (sense == 1)
+    lpx_set_obj_dir (lp, LPX_MIN);
+  else
+    lpx_set_obj_dir (lp, LPX_MAX);
+
+  //-- If the problem has integer structural variables switch to MIP
+  if (isMIP)
+    lpx_set_class (lp, LPX_MIP);
+
+  lpx_add_cols (lp, n);
+  for (int i = 0; i < n; i++)
+    {
+      //-- Define type of the structural variables
+      if (! freeLB[i] && ! freeUB[i])
+	{
+	  if (lb[i] != ub[i])
+	    lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]);
+	  else
+	    lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]);
+	}
+      else
+	{
+	  if (! freeLB[i] && freeUB[i])
+            lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]);
+	  else
+	    {
+	      if (freeLB[i] && ! freeUB[i])
+		lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]);
+	      else
+		lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]);
+	    }
+	}
+
+      // -- Set the objective coefficient of the corresponding
+      // -- structural variable. No constant term is assumed.
+      lpx_set_obj_coef(lp,i+1,c[i]);
+
+      if (isMIP)
+	lpx_set_col_kind (lp, i+1, vartype[i]);
+    }
+
+  lpx_add_rows (lp, m);
+
+  for (int i = 0; i < m; i++)
+    {
+      /* If the i-th row has no lower bound (types F,U), the
+         corrispondent parameter will be ignored.
+         If the i-th row has no upper bound (types F,L), the corrispondent
+         parameter will be ignored.
+         If the i-th row is of S type, the i-th LB is used, but
+         the i-th UB is ignored.
+      */
+
+      switch (ctype[i])
+	{
+	case 'F':
+	  typx = LPX_FR;
+	  break;
+
+	case 'U':
+	  typx = LPX_UP;
+	  break;
+
+	case 'L':
+	  typx = LPX_LO;
+	  break;
+
+	case 'S':
+	  typx = LPX_FX;
+	  break;
+
+	case 'D':
+	  typx = LPX_DB;
+	  break;
+	}
+      
+      lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]);
+
+    }
+
+  lpx_load_matrix (lp, nz, rn, cn, a);
+
+  if (save_pb)
+    {
+      static char tmp[] = "outpb.lp";
+      if (lpx_write_cpxlp (lp, tmp) != 0)
+	{
+	  error ("__glpk__: unable to write problem");
+	  longjmp (mark, -1);
+	}
+    }
+
+  //-- scale the problem data (if required)
+  //-- if (scale && (!presol || method == 1)) lpx_scale_prob(lp);
+  //-- LPX_K_SCALE=IParam[1]  LPX_K_PRESOL=IParam[16]
+  if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1))
+    lpx_scale_prob (lp);
+
+  //-- build advanced initial basis (if required)
+  if (lpsolver == 1 && ! lpxIntParam[16])
+    lpx_adv_basis (lp);
+
+  for(int i = 0; i < NIntP; i++)
+    lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]);
+
+  for (int i = 0; i < NRealP; i++)
+    lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]);
+
+  if (lpsolver == 1)
+    method = 'S';
+  else
+    method = 'T';
+
+  switch (method)
+    {
+    case 'S':
+      {
+	if (isMIP)
+	  {
+	    method = 'I';
+	    errnum = lpx_simplex (lp);
+	    errnum = lpx_integer (lp);
+	  }
+	else
+	  errnum = lpx_simplex(lp);
+      }
+     break;
+
+    case 'T':
+      errnum = lpx_interior(lp);
+      break;
+
+    default:
+      break;
+#if 0
+#ifdef GLPK_PRE_4_14
+      insist (method != method);
+#else
+      static char tmp[] = "method != method";
+      glpk_fault_hook (0, tmp);
+#endif
+#endif
+    }
+
+  /*  errnum assumes the following results:
+      errnum = 0 <=> No errors
+      errnum = 1 <=> Iteration limit exceeded.
+      errnum = 2 <=> Numerical problems with basis matrix.
+  */
+  if (errnum == LPX_E_OK)
+    {
+      if (isMIP)
+	{
+	  *status = lpx_mip_status (lp);
+	  *fmin = lpx_mip_obj_val (lp);
+	}
+      else
+	{
+	  if (lpsolver == 1)
+	    {
+	      *status = lpx_get_status (lp);
+	      *fmin = lpx_get_obj_val (lp);
+	    }
+	  else
+	    {
+	      *status = lpx_ipt_status (lp);
+	      *fmin = lpx_ipt_obj_val (lp);
+	    }
+	}
+
+      if (isMIP)
+	{
+	  for (int i = 0; i < n; i++)
+	    xmin[i] = lpx_mip_col_val (lp, i+1);
+	}
+      else
+	{
+	  /* Primal values */
+	  for (int i = 0; i < n; i++)
+	    {
+	      if (lpsolver == 1)
+		xmin[i] = lpx_get_col_prim (lp, i+1);
+	      else
+		xmin[i] = lpx_ipt_col_prim (lp, i+1);
+	    }
+
+	  /* Dual values */
+	  for (int i = 0; i < m; i++)
+	    {
+	      if (lpsolver == 1)
+		lambda[i] = lpx_get_row_dual (lp, i+1);
+	      else
+		lambda[i] = lpx_ipt_row_dual (lp, i+1);
+	    }
+
+	  /* Reduced costs */
+	  for (int i = 0; i < lpx_get_num_cols (lp); i++)
+	    {
+	      if (lpsolver == 1)
+		redcosts[i] = lpx_get_col_dual (lp, i+1);
+	      else
+		redcosts[i] = lpx_ipt_col_dual (lp, i+1);
+	    }
+	}
+
+      *time = (clock () - t_start) / CLOCKS_PER_SEC;
+
+#ifdef GLPK_PRE_4_14
+      *mem = (lib_env_ptr () -> mem_tpeak);
+#else
+      *mem = 0;
+#endif
+
+      lpx_delete_prob (lp);
+      return 0;
+    }
+
+   lpx_delete_prob (lp);
+
+   *status = errnum;
+
+   return errnum;
+}
+
+#endif
+
+#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \
+  do \
+    { \
+      if (PARAM.contains (NAME)) \
+	{ \
+	  Cell tmp = PARAM.contents (NAME); \
+ \
+          if (! tmp.is_empty ()) \
+	    { \
+	      lpxRealParam[IDX] = tmp(0).scalar_value (); \
+ \
+              if (error_state) \
+		{ \
+		  error ("glpk: invalid value in param." NAME); \
+		  return retval; \
+		} \
+	    } \
+	  else \
+	    { \
+	      error ("glpk: invalid value in param." NAME); \
+	      return retval; \
+	    } \
+	} \
+    } \
+  while (0)
+
+#define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \
+  do \
+    { \
+      if (PARAM.contains (NAME)) \
+	{ \
+	  Cell tmp = PARAM.contents (NAME); \
+ \
+          if (! tmp.is_empty ()) \
+	    { \
+	      VAL = tmp(0).int_value (); \
+ \
+              if (error_state) \
+		{ \
+		  error ("glpk: invalid value in param." NAME); \
+		  return retval; \
+		} \
+	    } \
+	  else \
+	    { \
+	      error ("glpk: invalid value in param." NAME); \
+	      return retval; \
+	    } \
+	} \
+    } \
+  while (0)
+
+DEFUN_DLD (__glpk__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  // The list of values to return.  See the declaration in oct-obj.h
+  octave_value_list retval;
+
+#if defined (HAVE_GLPK)
+
+  int nrhs = args.length ();
+
+  if (nrhs != 9)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  //-- 1nd Input. A column array containing the objective function
+  //--            coefficients.
+  volatile int mrowsc = args(0).rows();
+
+  Matrix C (args(0).matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of C");
+      return retval;
+    }
+
+  double *c = C.fortran_vec ();
+  Array<int> rn;
+  Array<int> cn;
+  ColumnVector a;
+  volatile int mrowsA;
+  volatile int nz = 0;
+
+  //-- 2nd Input. A matrix containing the constraints coefficients.
+  // If matrix A is NOT a sparse matrix
+  if (args(1).is_sparse_type ())
+    {
+      SparseMatrix A = args(1).sparse_matrix_value (); // get the sparse matrix
+
+      if (error_state)
+	{
+	  error ("__glpk__: invalid value of A");
+	  return retval;
+	}
+
+      mrowsA = A.rows ();
+      octave_idx_type Anc = A.cols ();
+      octave_idx_type Anz = A.nzmax ();
+      rn.resize (Anz+1);
+      cn.resize (Anz+1);
+      a.resize (Anz+1, 0.0);
+
+      if (Anc != mrowsc)
+	{
+	  error ("__glpk__: invalid value of A");
+	  return retval;
+	}
+
+      for (octave_idx_type j = 0; j < Anc; j++)
+	for (octave_idx_type i = A.cidx(j); i < A.cidx(j+1); i++)
+	  {
+	    nz++;
+	    rn(nz) = A.ridx(i) + 1;
+	    cn(nz) = j + 1;
+	    a(nz) = A.data(i);
+	  }
+    }
+  else
+    {
+      Matrix A (args(1).matrix_value ()); // get the matrix
+
+      if (error_state)
+	{
+	  error ("__glpk__: invalid value of A");
+	  return retval;
+	}
+
+      mrowsA = A.rows ();
+      rn.resize (mrowsA*mrowsc+1);
+      cn.resize (mrowsA*mrowsc+1);
+      a.resize (mrowsA*mrowsc+1, 0.0);
+
+      for (int i = 0; i < mrowsA; i++)
+	{
+	  for (int j = 0; j < mrowsc; j++)
+	    {
+	      if (A(i,j) != 0)
+		{
+		  nz++;
+		  rn(nz) = i + 1;
+		  cn(nz) = j + 1;
+		  a(nz) = A(i,j);
+		}
+	    }
+	}
+
+    }
+
+  //-- 3rd Input. A column array containing the right-hand side value
+  //	           for each constraint in the constraint matrix.
+  Matrix B (args(2).matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of b");
+      return retval;
+    }
+
+  double *b = B.fortran_vec ();
+
+  //-- 4th Input. An array of length mrowsc containing the lower
+  //--            bound on each of the variables.
+  Matrix LB (args(3).matrix_value ());
+
+  if (error_state || LB.length () < mrowsc)
+    {
+      error ("__glpk__: invalid value of lb");
+      return retval;
+    }
+
+  double *lb = LB.fortran_vec ();
+
+  //-- LB argument, default: Free
+  Array<int> freeLB (mrowsc);
+  for (int i = 0; i < mrowsc; i++)
+     {
+       if (xisinf (lb[i]))
+	 {
+	   freeLB(i) = 1;
+	   lb[i] = -octave_Inf;
+	 }
+       else
+	 freeLB(i) = 0;
+     }
+
+  //-- 5th Input. An array of at least length numcols containing the upper
+  //--            bound on each of the variables.
+  Matrix UB (args(4).matrix_value ());
+
+  if (error_state || UB.length () < mrowsc)
+    {
+      error ("__glpk__: invalid value of ub");
+      return retval;
+    }
+
+  double *ub = UB.fortran_vec ();
+
+  Array<int> freeUB (mrowsc);
+  for (int i = 0; i < mrowsc; i++)
+    {
+      if (xisinf (ub[i]))
+	{
+	  freeUB(i) = 1;
+	  ub[i] = octave_Inf;
+	}
+      else
+	freeUB(i) = 0;
+    }
+
+  //-- 6th Input. A column array containing the sense of each constraint
+  //--            in the constraint matrix.
+  charMatrix CTYPE (args(5).char_matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of ctype");
+      return retval;
+    }
+
+  char *ctype = CTYPE.fortran_vec ();
+
+  //-- 7th Input. A column array containing the types of the variables.
+  charMatrix VTYPE (args(6).char_matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of vtype");
+      return retval;
+    }
+
+  Array<int> vartype (mrowsc);
+  volatile int isMIP = 0;
+  for (int i = 0; i < mrowsc ; i++)
+    {
+      if (VTYPE(i,0) == 'I')
+	{
+	  isMIP = 1;
+	  vartype(i) = LPX_IV;
+	}
+      else
+	vartype(i) = LPX_CV;
+    }
+
+  //-- 8th Input. Sense of optimization.
+  volatile int sense;
+  double SENSE = args(7).scalar_value ();
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of sense");
+      return retval;
+    }
+
+  if (SENSE >= 0)
+    sense = 1;
+  else
+    sense = -1;
+
+  //-- 9th Input. A structure containing the control parameters.
+  Octave_map PARAM = args(8).map_value ();
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of param");
+      return retval;
+    }
+
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  //-- Integer parameters
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  //-- Level of messages output by the solver
+  OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]);
+  if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3)
+    {
+      error ("__glpk__: param.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)");
+      return retval;
+    }
+
+  //-- scaling option
+  OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]);
+  if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2)
+    {
+      error ("__glpk__: param.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)");
+      return retval;
+    }
+
+  //-- Dual dimplex option
+  OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]);
+  if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1)
+    {
+      error ("__glpk__: param.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)");
+      return retval;
+    }
+
+  //-- Pricing option
+  OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]);
+  if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1)
+    {
+      error ("__glpk__: param.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])");
+      return retval;
+    }
+
+  //-- Solution rounding option
+  OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]);
+  if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1)
+    {
+      error ("__glpk__: param.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)");
+      return retval;
+    }
+
+  //-- Simplex iterations limit
+  OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]);
+
+  //-- Simplex iterations count
+  OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]);
+
+  //-- Output frequency, in iterations
+  OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]);
+
+  //-- Branching heuristic option
+  OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]);
+  if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2)
+    {
+      error ("__glpk__: param.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]");
+      return retval;
+    }
+
+  //-- Backtracking heuristic option
+  OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]);
+  if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2)
+    {
+      error ("__glpk__: param.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]");
+      return retval;
+    }
+
+  //-- Presolver option
+  OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]);
+  if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1)
+    {
+      error ("__glpk__: param.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
+      return retval;
+    }
+
+  //-- LPsolver option
+  volatile int lpsolver = 1;
+  OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver);
+  if (lpsolver < 1 || lpsolver > 2)
+    {
+      error ("__glpk__: param.lpsolver must be 1 (simplex method) or 2 (interior point method)");
+      return retval;
+    }
+
+  //-- Save option
+  volatile int save_pb = 0;
+  OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb);
+  save_pb = save_pb != 0;
+
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  //-- Real parameters
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  //-- Ratio test option
+  OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0);
+
+  //-- Relative tolerance used to check if the current basic solution
+  //-- is primal feasible
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1);
+
+  //-- Absolute tolerance used to check if the current basic solution
+  //-- is dual feasible
+  OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2);
+
+  //-- Relative tolerance used to choose eligible pivotal elements of
+  //--	the simplex table in the ratio test
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9);
+
+  //-- Assign pointers to the output parameters
+  ColumnVector xmin (mrowsc, octave_NA);
+  ColumnVector fmin (1, octave_NA);
+  ColumnVector status (1);
+  ColumnVector lambda (mrowsA, octave_NA);
+  ColumnVector redcosts (mrowsc, octave_NA);
+  ColumnVector time (1);
+  ColumnVector mem (1);
+
+  int jmpret = setjmp (mark);
+
+  if (jmpret == 0)
+    glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
+	  cn.fortran_vec (), a.fortran_vec (), b, ctype,
+	  freeLB.fortran_vec (), lb, freeUB.fortran_vec (),
+	  ub, vartype.fortran_vec (), isMIP, lpsolver,
+	  save_pb, xmin.fortran_vec (), fmin.fortran_vec (),
+	  status.fortran_vec (), lambda.fortran_vec (),
+	  redcosts.fortran_vec (), time.fortran_vec (),
+	  mem.fortran_vec ());
+
+  Octave_map extra;
+
+  if (! isMIP)
+    {
+      extra.assign ("lambda", octave_value (lambda));
+      extra.assign ("redcosts", octave_value (redcosts));
+    }
+
+  extra.assign ("time", octave_value (time));
+  extra.assign ("mem", octave_value (mem));
+
+  retval(3) = extra;
+  retval(2) = octave_value(status);
+  retval(1) = octave_value(fmin);
+  retval(0) = octave_value(xmin);
+
+#else
+
+  gripe_not_supported ("glpk");
+
+#endif
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__lin_interpn__.cc b/src/DLD-FUNCTIONS/__lin_interpn__.cc
new file mode 100644
index 0000000..f578f99
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__lin_interpn__.cc
@@ -0,0 +1,357 @@
+/*
+
+Copyright (C) 2007, 2008 Alexander Barth
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-ieee.h"
+#include "dNDArray.h"
+#include "oct-locbuf.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+// equivalent to isvector.m
+
+template <class T>
+bool
+isvector (const T& array)
+{
+  const dim_vector dv = array.dims ();
+  return dv.length () == 2 && (dv(0) == 1 || dv(1) == 1);
+}
+
+// lookup a value in a sorted table (lookup.m)
+template <class T>
+octave_idx_type
+lookup (const T *x, octave_idx_type n, T y)
+{
+  octave_idx_type j;
+
+  if (x[0] < x[n-1])
+    {
+      // increasing x
+
+      if (y > x[n-1] || y < x[0])
+	return -1;
+
+#ifdef EXHAUSTIF
+      for (j = 0; j < n - 1; j++)
+	{
+	  if (x[j] <= y && y <= x[j+1])
+	    return j;
+	}
+#else
+      octave_idx_type j0 = 0;
+      octave_idx_type j1 = n - 1;
+
+      while (true)
+	{
+	  j = (j0+j1)/2;
+
+	  if (y <= x[j+1])
+	    {
+	      if (x[j] <= y)
+		return j;
+
+	      j1 = j;
+	    }
+
+	  if (x[j] <= y)
+	    j0 = j;
+	}
+#endif
+    }
+  else
+    {
+      // decreasing x
+      // previous code with x -> -x and y -> -y
+
+      if (y > x[0] || y < x[n-1])
+	return -1;
+
+#ifdef EXHAUSTIF
+      for (j = 0; j < n - 1; j++)
+	{
+	  if (x[j+1] <= y && y <= x[j])
+	    return j;
+	}
+#else
+      octave_idx_type j0 = 0;
+      octave_idx_type j1 = n - 1;
+
+      while (true)
+	{
+	  j = (j0+j1)/2;
+
+	  if (y >= x[j+1])
+	    {
+	      if (x[j] >= y)
+		return j;
+
+	      j1 = j;
+	    }
+
+	  if (x[j] >= y)
+	    j0 = j;
+	}
+#endif
+    }
+}
+
+// n-dimensional linear interpolation
+
+template <class T>
+void
+lin_interpn (int n, const octave_idx_type *size, const octave_idx_type *scale,
+	     octave_idx_type Ni, T extrapval, const T **x,
+	     const T *v, const T **y, T *vi)
+{
+  bool out = false;
+  int bit;
+
+  OCTAVE_LOCAL_BUFFER (T, coef, 2*n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, index, n);
+
+  // loop over all points
+  for (octave_idx_type m = 0; m < Ni; m++)
+    {
+      // loop over all dimensions
+      for (int i = 0; i < n; i++)
+	{
+          index[i] = lookup (x[i], size[i], y[i][m]);
+	  out = index[i] == -1;
+
+	  if (out)
+	    break;
+	  else
+            {
+	      octave_idx_type j = index[i];
+	      coef[2*i+1] = (y[i][m] - x[i][j])/(x[i][j+1] - x[i][j]);
+	      coef[2*i] = 1 - coef[2*i+1];
+	    }
+	}
+
+
+      if (out)
+	vi[m] = extrapval;
+      else
+	{
+	  vi[m] = 0;
+
+	  // loop over all corners of hypercube (1<<n = 2^n)
+	  for (int i = 0; i < (1 << n); i++)
+	    {
+	      T c = 1;
+	      octave_idx_type l = 0;
+
+	      // loop over all dimensions
+	      for (int j = 0; j < n; j++)
+		{
+		  // test if the jth bit in i is set
+		  bit = i >> j & 1;
+		  l += scale[j] * (index[j] + bit);
+		  c *= coef[2*j+bit];
+		}
+
+	      vi[m] += c * v[l];
+	    }
+	}
+    }
+}
+
+template <class T, class M>
+octave_value
+lin_interpn (int n, M *X, const M V, M *Y)
+{
+  octave_value retval;
+
+  M Vi = M (Y[0].dims ());
+
+  OCTAVE_LOCAL_BUFFER (const T *, y, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, size, n);
+
+  for (int i = 0; i < n; i++)
+    {
+      y[i] = Y[i].data ();
+      size[i] =  V.dims()(i);
+    }
+
+  OCTAVE_LOCAL_BUFFER (const T *, x, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, scale, n);
+  
+  const T *v = V.data ();
+  T *vi = Vi.fortran_vec ();
+  octave_idx_type Ni = Vi.numel ();
+
+  T extrapval = octave_NA;
+
+  // offset in memory of each dimension
+
+  scale[0] = 1;
+
+  for (int i = 1; i < n; i++)
+    scale[i] = scale[i-1] * size[i-1];
+
+  // tests if X[0] is a vector, if yes, assume that all elements of X are
+  // in the ndgrid format.
+
+  if (! isvector (X[0]))
+    {
+      for (int i = 0; i < n; i++)
+	{
+	  if (X[i].dims () != V.dims ())
+	    {
+	      error ("interpn: incompatible size of argument number %d", i+1);
+	      return retval;
+	    }
+	  else
+	    {
+              M tmp = M (dim_vector (size[i], 1));
+
+	      for (octave_idx_type j = 0; j < size[i]; j++)
+		tmp(j) =  X[i](scale[i]*j);
+
+              X[i] = tmp;
+	    }
+	}
+    }
+
+  for (int i = 0; i < n; i++)
+    {
+      if (! isvector (X[i]) && X[i].numel () != size[i])
+	{
+	  error ("interpn: incompatible size of argument number %d", i+1);
+	  return retval;
+	}
+      else
+	x[i] = X[i].data ();
+    }
+
+  lin_interpn (n, size, scale, Ni, extrapval, x, v, y, vi);
+
+  retval = Vi;
+
+  return retval;
+}
+
+// Perform @var{n}-dimensional interpolation.  Each element of then
+// @var{n}-dimensional array @var{v} represents a value at a location
+// given by the parameters @var{x1}, @var{x2},..., at var{xn}. The parameters
+// @var{x1}, @var{x2}, @dots{}, @var{xn} are either @var{n}-dimensional
+// arrays of the same size as the array @var{v} in the \"ndgrid\" format
+// or vectors.  The parameters @var{y1}, @var{y2}, @dots{}, @var{yn} are
+// all @var{n}-dimensional arrays of the same size and represent the
+// points at which the array @var{vi} is interpolated.
+//
+//This function only performs linear interpolation.
+
+DEFUN_DLD (__lin_interpn__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{vi} =} __lin_interpn__ (@var{x1}, @var{x2}, @dots{}, @var{xn}, @var{v}, @var{y1}, @var{y2}, @dots{}, @var{yn})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 2 ||  nargin % 2 == 0)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // dimension of the problem
+  int n = (nargin-1)/2;
+
+  if (args(n).is_single_type())
+    {
+      OCTAVE_LOCAL_BUFFER (FloatNDArray, X, n);
+      OCTAVE_LOCAL_BUFFER (FloatNDArray, Y, n);
+
+      const FloatNDArray V = args(n).float_array_value ();
+
+      if (error_state)
+	{
+	  print_usage ();
+	  return retval;
+	}
+
+      for (int i = 0; i < n; i++)
+	{
+	  X[i] = args(i).float_array_value ();
+	  Y[i] = args(n+i+1).float_array_value ();
+
+	  if (error_state)
+	    {
+	      print_usage ();
+	      return retval;
+	    }
+
+	  if (Y[0].dims () != Y[i].dims ())
+	    {
+	      error ("interpn: incompatible size of argument number %d", n+i+2);
+	      return retval;
+	    }
+	}
+
+      retval = lin_interpn<float, FloatNDArray> (n, X, V, Y);
+    }
+  else  
+    {
+      OCTAVE_LOCAL_BUFFER (NDArray, X, n);
+      OCTAVE_LOCAL_BUFFER (NDArray, Y, n);
+
+      const NDArray V = args(n).array_value ();
+
+      if (error_state)
+	{
+	  print_usage ();
+	  return retval;
+	}
+
+      for (int i = 0; i < n; i++)
+	{
+	  X[i] = args(i).array_value ();
+	  Y[i] = args(n+i+1).array_value ();
+
+	  if (error_state)
+	    {
+	      print_usage ();
+	      return retval;
+	    }
+
+	  if (Y[0].dims () != Y[i].dims ())
+	    {
+	      error ("interpn: incompatible size of argument number %d", n+i+2);
+	      return retval;
+	    }
+	}
+      
+      retval = lin_interpn<double, NDArray> (n, X, V, Y);
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__magick_read__.cc b/src/DLD-FUNCTIONS/__magick_read__.cc
new file mode 100644
index 0000000..8a8a428
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc
@@ -0,0 +1,975 @@
+/*
+
+Copyright (C) 2002, 2009 Andy Adler
+Copyright (C) 2008 Thomas L. Scofield
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cmath>
+
+#include "defun-dld.h"
+#include "error.h"
+#include "ov-struct.h"
+
+#ifdef HAVE_MAGICK
+
+#include <GraphicsMagick/Magick++.h>
+
+unsigned int
+scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
+{
+  return (static_cast<unsigned int> (static_cast<double> (quantum)
+                                     / MaxRGB * ((1 << depth) - 1)));
+}
+
+octave_value_list
+read_indexed_images (std::vector<Magick::Image>& imvec,
+                     const Array<int>& frameidx, bool wantalpha)
+{
+  octave_value_list output;
+
+  int rows = imvec[0].baseRows ();
+  int columns = imvec[0].baseColumns ();
+  int nframes = frameidx.length ();
+
+  dim_vector idim = dim_vector ();
+  idim.resize (4);
+  idim(0) = rows;
+  idim(1) = columns;
+  idim(2) = 1;
+  idim(3) = nframes;
+
+  Array<int> idx (dim_vector (4));
+
+  Magick::ImageType type = imvec[0].type ();
+
+  unsigned int mapsize = imvec[0].colorMapSize ();
+  unsigned int i = mapsize;
+  unsigned int depth = 0;
+  while (i >>= 1)
+    depth++;
+  i = 0;
+  depth--;
+  while (depth >>= 1)
+    i++;
+  depth = 1 << i;
+
+  switch (depth)
+    {
+    case 1:
+    case 2:
+    case 4:
+    case 8:
+      {
+        uint8NDArray im = uint8NDArray (idim);
+
+        idx(2) = 0;
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            const Magick::IndexPacket *pix
+              = imvec[frameidx(frame)].getConstIndexes ();
+
+            i = 0;
+            idx(3) = frame;
+
+            for (int y = 0; y < rows; y++)
+              {
+                idx(0) = y;
+                for (int x = 0; x < columns; x++)
+                  {
+                    idx(1) = x;
+                    im(idx) = static_cast<octave_uint8> (pix[i++]);
+                  }
+              }
+          }
+        im.chop_trailing_singletons ();
+        output(0) = octave_value (im);
+      }
+      break;
+
+    case 16:
+      {
+        uint16NDArray im = uint16NDArray (idim);
+
+        idx(2) = 0;
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            const Magick::IndexPacket *pix
+              = imvec[frameidx(frame)].getConstIndexes ();
+
+            i = 0;
+            idx(3) = frame;
+
+            for (int y = 0; y < rows; y++)
+              {
+                idx(0) = y;
+                for (int x = 0; x < columns; x++)
+                  {
+                    idx(1) = x;
+                    im(idx) = static_cast<octave_uint16> (pix[i++]);
+                  }
+              }
+          }
+        im.chop_trailing_singletons ();
+        output(0) = octave_value (im);
+      }
+      break;
+
+    default:
+      error ("__magic_read__: index depths bigger than 16-bit not supported");
+      return octave_value_list ();
+    }
+
+  Matrix map = Matrix (mapsize, 3);
+  Matrix alpha;
+
+  switch (type)
+    {
+    case Magick::PaletteMatteType:
+#if 0
+      warning ("palettematte");
+      Matrix map (mapsize, 3);
+      Matrix alpha (mapsize, 1);
+      for (i = 0; i < mapsize; i++)
+        {
+          warning ("%d", i);
+          Magick::ColorRGB c = imvec[0].colorMap (i);
+          map(i,0) = c.red ();
+          map(i,1) = c.green ();
+          map(i,2) = c.blue ();
+          alpha(i,1) = c.alpha ();
+        }
+      break;
+#endif
+
+    case Magick::PaletteType:
+      alpha = Matrix (0, 0);
+      for (i = 0; i < mapsize; i++)
+        {
+          Magick::ColorRGB c = imvec[0].colorMap (i);
+          map(i,0) = c.red ();
+          map(i,1) = c.green ();
+          map(i,2) = c.blue ();
+        }
+      break;
+
+    default:
+      error ("__magick_read__: unsupported indexed image type");
+      return octave_value_list ();
+    }
+
+  if (wantalpha)
+    output(2) = alpha;
+
+  output(1) = map;
+
+  return output;
+}
+
+template <class T>
+octave_value_list
+read_images (const std::vector<Magick::Image>& imvec,
+             const Array<int>& frameidx, unsigned int depth)
+{
+  octave_value_list retval (3, Matrix ());
+
+  T im;
+
+  int rows = imvec[0].baseRows ();
+  int columns = imvec[0].baseColumns ();
+  int nframes = frameidx.length ();
+
+  dim_vector idim = dim_vector ();
+  idim.resize (4);
+  idim(0) = rows;
+  idim(1) = columns;
+  idim(2) = 1;
+  idim(3) = nframes;
+
+  Array<int> idx (dim_vector (4));
+
+  Magick::ImageType type = imvec[0].type ();
+
+  switch (type)
+    {
+    case Magick::BilevelType:
+    case Magick::GrayscaleType:
+      im = T (idim);
+      for (int frame = 0; frame < nframes; frame++)
+        {
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+          int i = 0;
+          idx(2) = 0;
+          idx(3) = frame;
+
+          for (int y = 0; y < rows; y++)
+            {
+              idx(0) = y;
+              for (int x = 0; x < columns; x++)
+                {
+                  idx(1) = x;
+                  im(idx) = scale_quantum_to_depth (pix[i++].red, depth);
+                }
+            }
+        }
+      break;
+
+    case Magick::GrayscaleMatteType:
+      idim(2) = 2;
+      im = T (idim);
+      for (int frame = 0; frame < nframes; frame++)
+        {
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+          int i = 0;
+          idx(3) = frame;
+
+          for (int y = 0; y < rows; y++)
+            {
+              idx(0) = y;
+              for (int x = 0; x < columns; x++)
+                {
+                  idx(1) = x;
+                  idx(2) = 0;
+                  im(idx) = scale_quantum_to_depth (pix[i].red, depth);
+                  idx(2) = 1;
+                  im(idx) = scale_quantum_to_depth (pix[i].opacity, depth);
+                  i++;
+                }
+            }
+        }
+      break;
+
+    case Magick::PaletteType:
+    case Magick::TrueColorType:
+      idim(2) = 3;
+      im = T (idim);
+      for (int frame = 0; frame < nframes; frame++)
+        {
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+          int i = 0;
+          idx(3) = frame;
+
+          for (int y = 0; y < rows; y++)
+            {
+              idx(0) = y;
+              for (int x = 0; x < columns; x++)
+                {
+                  idx(1) = x;
+                  idx(2) = 0;
+                  im(idx) = scale_quantum_to_depth (pix[i].red, depth);
+                  idx(2) = 1;
+                  im(idx) = scale_quantum_to_depth (pix[i].green, depth);
+                  idx(2) = 2;
+                  im(idx) = scale_quantum_to_depth (pix[i].blue, depth);
+                  i++;
+                }
+            }
+        }
+      break;
+
+    case Magick::PaletteMatteType:
+    case Magick::TrueColorMatteType:
+    case Magick::ColorSeparationType:
+      idim(2) = 4;
+      im = T (idim);
+      for (int frame = 0; frame < nframes; frame++)
+        {
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+          int i = 0;
+          idx(3) = frame;
+
+          for (int y = 0; y < rows; y++)
+            {
+              idx(0) = y;
+              for (int x = 0; x < columns; x++)
+                {
+                  idx(1) = x;
+                  idx(2) = 0;
+                  im(idx) = scale_quantum_to_depth (pix[i].red, depth);
+                  idx(2) = 1;
+                  im(idx) = scale_quantum_to_depth (pix[i].green, depth);
+                  idx(2) = 2;
+                  im(idx) = scale_quantum_to_depth (pix[i].blue, depth);
+                  idx(2) = 3;
+                  im(idx) = scale_quantum_to_depth (pix[i].opacity, depth);
+                  i++;
+                }
+            }
+        }
+      break;
+
+    default:
+      error ("__magick_read__: undefined ImageMagick image type");
+      return retval;
+    }
+
+  im.chop_trailing_singletons ();
+
+  retval(0) = im;
+
+  return retval;
+}
+
+#endif
+
+DEFUN_DLD (__magick_read__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Function File} {@var{m} =} __magick_read__(@var{fname}, @var{index})\n\
+ at deftypefnx{Function File} {[@var{m}, @var{colormap}] =} __magick_read__(@var{fname}, @var{index})\n\
+ at deftypefnx{Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __magick_read__(@var{fname}, @var{index})\n\
+Read images with ImageMagick++.  In general you should not be using this function.\n\
+Instead you should use @code{imread}.\n\
+ at seealso{imread}\n\
+ at end deftypefn")
+{
+  octave_value_list output;
+
+#ifdef HAVE_MAGICK
+
+  if (args.length () > 2 || args.length () < 1 || ! args(0).is_string ()
+      || nargout > 3)
+    {
+      print_usage ();
+      return output;
+    }
+
+  Array<int> frameidx;
+
+  if (args.length () == 2 && args(1).is_real_type ())
+    frameidx = args(1).int_vector_value();
+  else
+    {
+      frameidx = Array<int> (1);
+      frameidx(0) = 1;
+    }
+
+  std::vector<Magick::Image> imvec;
+
+  try
+    {
+      // Read a file into vector of image objects
+      Magick::readImages (&imvec, args(0).string_value ());
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+      return output;
+    }
+
+  for (int i = 0; i < frameidx.length(); i++)
+    {
+      frameidx(i) = frameidx(i) - 1;
+
+      int nframes = imvec.size ();
+
+      if (frameidx(i) >= nframes || frameidx(i) < 0)
+        {
+          error ("__magick_read__: invalid index vector");
+          return output;
+        }
+    }
+
+  Magick::ClassType klass = imvec[0].classType ();
+
+  if (klass == Magick::PseudoClass && nargout > 1)
+    output = read_indexed_images (imvec, frameidx, (nargout == 3));
+  else
+    {
+      unsigned int depth = imvec[0].modulusDepth ();
+      if (depth > 1)
+	{
+	  --depth;
+	  int i = 1;
+	  while (depth >>= 1)
+            i++;
+	  depth = 1 << i;
+	}
+      
+      switch (depth)
+        {
+        case 1:
+          output = read_images<boolNDArray> (imvec, frameidx, depth);
+          break;
+
+        case 2:
+        case 4:
+        case 8:
+          output = read_images<uint8NDArray> (imvec, frameidx, depth) ;
+          break;
+
+        case 16:
+          output = read_images<uint16NDArray> (imvec, frameidx, depth);
+          break;
+
+        case 32:
+        case 64:
+        default:
+          error ("__magick_read__: image depths bigger than 16-bit not supported");
+        }
+    }
+#else
+
+  error ("__magick_read__: not available in this version of Octave");
+
+#endif
+
+  return output;
+}
+
+#ifdef HAVE_MAGICK
+
+static void
+jpg_settings (std::vector<Magick::Image>& imvec,
+              const Octave_map& options,
+              bool)
+{
+  int nframes = static_cast<int>(imvec.size ());
+  bool something_set = 0;
+
+  // Quality setting
+  octave_value result;
+  Octave_map::const_iterator p;
+  bool found_it = 0;
+  for (p = options.begin (); p != options.end (); p++)
+    if (options.key (p) == "Quality")
+      {
+        found_it = 1;
+        result = options.contents (p).elem (0);
+        break;
+      }
+  if (found_it && (! result.is_empty ()))
+    {
+      something_set = 1;
+      if (result.is_real_type ())
+        {
+          int qlev = static_cast<int>(result.int_value ());
+          if (qlev < 0 || qlev > 100)
+            warning ("warning: Quality setting invalid--use default of 75");
+          else
+            for (int fnum = 0; fnum < nframes; fnum++)
+              imvec[fnum].quality (static_cast<unsigned int>(qlev));
+        }
+      else
+        warning ("warning: Quality setting invalid--use default of 75");
+    }
+
+  // Other settings go here
+
+  if (! something_set)
+    warning ("__magick_write__ warning: All write parameters ignored.");
+}
+
+static void
+encode_bool_image (std::vector<Magick::Image>& imvec, const octave_value& img)
+{
+  unsigned int nframes = 1;
+  boolNDArray m = img.bool_array_value ();
+
+  dim_vector dsizes = m.dims ();
+  if (dsizes.length () == 4)
+    nframes = dsizes(3);
+
+  Array<octave_idx_type> idx (dsizes.length ());
+
+  octave_idx_type rows = m.rows ();
+  octave_idx_type columns = m.columns ();
+
+  for (unsigned int ii = 0; ii < nframes; ii++)
+    {
+      Magick::Image im(Magick::Geometry (columns, rows), "black");
+      im.classType (Magick::DirectClass);
+      im.depth (1);
+
+      for (int y=0; y < columns; y++)
+        {
+          idx(1) = y;
+          for (int x=0; x < rows; x++)
+            {
+              if (nframes > 1)
+                {
+                  idx(2) = 0;
+                  idx(3) = ii;
+                }
+              idx(0) = x;
+              if (m(idx))
+                im.pixelColor (y, x, "white");
+            }
+        }
+      imvec.push_back (im);
+    }
+}
+
+template <class T>
+static void
+encode_uint_image (std::vector<Magick::Image>& imvec,
+                   const octave_value& img,
+                   bool has_map)
+{
+  unsigned int bitdepth = 0;
+  T m;
+
+  if (img.is_uint8_type ())
+    {
+      bitdepth = 8;
+      m = img.uint8_array_value ();
+    }
+  else if (img.is_uint16_type ())
+    {
+      bitdepth = 16;
+      m = img.uint16_array_value ();
+    }
+  else
+    error ("__magick_write__: invalid image class");
+
+  dim_vector dsizes = m.dims ();
+  unsigned int nframes = 1;
+  if (dsizes.length () == 4)
+    nframes = dsizes(3);
+  bool is_color = ((dsizes.length () > 2) && (dsizes(2) > 2));
+  bool has_alpha = (dsizes.length () > 2 && (dsizes(2) == 2 || dsizes(2) == 4));
+
+  Array<octave_idx_type> idx (dsizes.length ());
+  octave_idx_type rows = m.rows ();
+  octave_idx_type columns = m.columns ();
+
+  // FIXME -- maybe simply using bit shifting would be better?
+  unsigned int div_factor = pow (2.0, static_cast<int> (bitdepth)) - 1;
+
+  for (unsigned int ii = 0; ii < nframes; ii++)
+    {
+      Magick::Image im(Magick::Geometry (columns, rows), "black");
+      im.depth (bitdepth);
+      if (has_map)
+        im.classType (Magick::PseudoClass);
+      else
+        im.classType (Magick::DirectClass);
+
+      if (is_color)
+        {
+          if (has_alpha)
+            im.type (Magick::TrueColorMatteType);
+          else
+            im.type (Magick::TrueColorType);
+
+          Magick::ColorRGB c;
+          for (int y=0; y < columns; y++)
+            {
+              idx(1) = y;
+              for (int x=0; x < rows; x++)
+                {
+                  idx(0) = x;
+                  if (nframes > 1)
+                    idx(3) = ii;
+
+                  idx(2) = 0;
+                  c.red (static_cast<double>(m(idx)) / div_factor);
+                  idx(2) = 1;
+                  c.green (static_cast<double>(m(idx)) / div_factor);
+                  idx(2) = 2;
+                  c.blue (static_cast<double>(m(idx)) / div_factor);
+
+                  if (has_alpha)
+                    {
+                      idx(2) = 3;
+                      c.alpha (static_cast<double>(m(idx)) / div_factor);
+                    }
+                  im.pixelColor (y, x, c);
+                }
+            }
+        }
+      else
+        {
+          if (has_alpha)
+            im.type (Magick::GrayscaleMatteType);
+          else
+            im.type (Magick::GrayscaleType);
+
+          Magick::ColorGray c;
+
+          for (int y=0; y < columns; y++)
+            {
+              idx(1) = y;
+              for (int x=0; x < rows; x++)
+                {
+                  idx(0) = x;
+                  if (nframes > 1)
+                    {
+                      idx(2) = 0;
+                      idx(3) = ii;
+                    }
+                  if (has_alpha)
+                    {
+                      idx(2) = 1;
+                      c.alpha (static_cast<double>(m(idx)) / div_factor);
+                      idx(2) = 0;
+                    }
+
+                  c.shade (static_cast<double>(m(idx)) / div_factor);
+                  im.pixelColor (y, x, c);
+                }
+            }
+        }
+      imvec.push_back (im);
+    }
+}
+
+static void
+encode_map (std::vector<Magick::Image>& imvec, const NDArray& cmap)
+{
+  unsigned int mapsize = cmap.dim1 ();
+  int nframes = static_cast<int>(imvec.size ());
+
+  for (int fnum = 0; fnum < nframes; fnum++)
+    {
+      imvec[fnum].colorMapSize (mapsize);
+      imvec[fnum].type (Magick::PaletteType);
+    }
+
+  for (unsigned int ii = 0; ii < mapsize; ii++)
+    {
+      Magick::ColorRGB c (cmap(ii,0), cmap(ii,1), cmap(ii,2));
+
+      // FIXME -- is this case needed?
+      if (cmap.dim2 () == 4)
+        c.alpha (cmap(ii,3));
+
+      try
+        {
+          for_each (imvec.begin (), imvec.end (),
+                    Magick::colorMapImage (ii, c));
+        }
+      catch (Magick::Warning& w)
+        {
+          warning ("Magick++ warning: %s", w.what ());
+        }
+      catch (Magick::ErrorCoder& e)
+        {
+          warning ("Magick++ coder error: %s", e.what ());
+        }
+      catch (Magick::Exception& e)
+        {
+          error ("Magick++ exception: %s", e.what ());
+        }
+    }
+}
+
+static void
+write_image (const std::string& filename, const std::string& fmt,
+             const octave_value& img,
+             const octave_value& map = octave_value (),
+             const octave_value& params = octave_value ())
+{
+  std::vector<Magick::Image> imvec;
+
+  bool has_map = map.is_defined ();
+
+  if (has_map)
+    {
+      error ("__magick_write__: direct saving of indexed images not currently supported; use ind2rgb and save converted image");
+      return;
+    }
+
+  if (img.is_bool_type ())
+    encode_bool_image (imvec, img);
+  else if (img.is_uint8_type ())
+    encode_uint_image<uint8NDArray> (imvec, img, has_map);
+  else if (img.is_uint16_type ())
+    encode_uint_image<uint16NDArray> (imvec, img, has_map);
+  else
+    error ("__magick_write__: image type not supported");
+
+  if (! error_state && has_map)
+    {
+      NDArray cmap = map.array_value ();
+
+      if (! error_state)
+        encode_map (imvec, cmap);
+    }
+
+  if (! error_state && params.is_defined ())
+    {
+      Octave_map options = params.map_value ();
+
+      // Insert calls here to handle parameters for various image formats
+      if (fmt == "jpg" || fmt == "jpeg")
+        jpg_settings (imvec, options, has_map);
+      else
+        warning ("warning: your parameter(s) currently not supported");
+    }
+
+  try
+    {
+      Magick::writeImages (imvec.begin (), imvec.end (), filename);
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+    }
+}
+
+#endif
+
+DEFUN_DLD (__magick_write__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Function File} {} __magick_write__(@var{fname}, @var{fmt}, @var{img})\n\
+ at deftypefnx {Function File} {} __magick_write__(@var{fname}, @var{fmt}, @var{img}, @var{map})\n\
+Write images with ImageMagick++.  In general you should not be using this function.\n\
+Instead you should use @code{imwrite}.\n\
+ at seealso{imread}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_MAGICK
+  int nargin = args.length ();
+
+  if (nargin > 2)
+    {
+      std::string filename = args(0).string_value ();
+
+      if (! error_state)
+        {
+          std::string fmt = args(1).string_value ();
+
+          if (! error_state)
+            {
+              if (nargin > 4)
+                write_image (filename, fmt, args(2), args(3), args(4));
+              else if (nargin > 3)
+                if (args(3).is_real_type ())
+                  write_image (filename, fmt, args(2), args(3));
+                else
+                  write_image (filename, fmt, args(2), octave_value(), args(3));
+              else
+                write_image (filename, fmt, args(2));
+            }
+          else
+            error ("__magick_write__: expecting format as second argument");
+        }
+      else
+        error ("__magick_write__: expecting filename as first argument");
+    }
+  else
+    print_usage ();
+#else
+
+  error ("__magick_write__: not available in this version of Octave");
+
+#endif
+
+return retval;
+}
+
+#ifdef HAVE_MAGICK
+
+template<class T>
+static octave_value
+magick_to_octave_value (const T magick)
+{
+  return octave_value (magick);
+}
+
+static octave_value
+magick_to_octave_value (const Magick::EndianType magick)
+{
+  switch (magick)
+    {
+      case Magick::LSBEndian:
+        return octave_value ("little-endian");
+
+      case Magick::MSBEndian:
+        return octave_value ("big-endian");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ResolutionType magick)
+{
+  switch (magick)
+    {
+      case Magick::PixelsPerInchResolution:
+        return octave_value ("pixels per inch");
+
+      case Magick::PixelsPerCentimeterResolution:
+        return octave_value ("pixels per centimeter");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ImageType magick)
+{
+  switch (magick)
+    {
+      case Magick::BilevelType:
+      case Magick::GrayscaleType:
+      case Magick::GrayscaleMatteType:
+        return octave_value ("grayscale");
+
+      case Magick::PaletteType:
+      case Magick::PaletteMatteType:
+        return octave_value ("indexed");
+
+      case Magick::TrueColorType:
+      case Magick::TrueColorMatteType:
+      case Magick::ColorSeparationType:
+        return octave_value ("truecolor");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+// We put this in a try-block because GraphicsMagick will throw
+// exceptions if a parameter isn't present in the current image.
+#define GET_PARAM(NAME, OUTNAME) \
+  try \
+    { \
+      st.assign (OUTNAME, magick_to_octave_value (im.NAME ())); \
+    } \
+  catch (Magick::Warning& w) \
+    { \
+    }
+
+#endif
+
+DEFUN_DLD (__magick_finfo__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable File} {} __magick_finfo__(@var{fname})\n\
+Read image information with GraphicsMagick++.  In general you should\n\
+not be using this function.  Instead you should use @code{imfinfo}.\n\
+ at seealso{imfinfo, imread}\n\
+ at end deftypefn")
+{
+  octave_value_list output;
+
+#ifdef HAVE_MAGICK
+
+  if (args.length () < 1 || ! args (0).is_string ())
+    {
+      print_usage ();
+      return output;
+    }
+
+  const std::string filename = args (0).string_value ();
+
+  try
+    {
+      // Read the file.
+      Magick::Image im;
+      im.read (filename);
+      
+      // Read properties.
+      Octave_map st;
+      st.assign ("Filename", filename);
+      
+      // Annoying CamelCase naming is for Matlab compatibility.
+      GET_PARAM (fileSize, "FileSize")
+      GET_PARAM (rows, "Height")
+      GET_PARAM (columns, "Width")
+      GET_PARAM (depth, "BitDepth")
+      GET_PARAM (magick, "Format")
+      GET_PARAM (format, "LongFormat")
+      GET_PARAM (xResolution, "XResolution")
+      GET_PARAM (yResolution, "YResolution")
+      GET_PARAM (totalColors, "TotalColors")
+      GET_PARAM (tileName, "TileName")
+      GET_PARAM (animationDelay, "AnimationDelay")
+      GET_PARAM (animationIterations, "AnimationIterations")
+      GET_PARAM (endian, "ByteOrder")
+      GET_PARAM (gamma, "Gamma")
+      GET_PARAM (matte, "Matte")
+      GET_PARAM (modulusDepth, "ModulusDepth")
+      GET_PARAM (quality, "Quality")
+      GET_PARAM (quantizeColors, "QuantizeColors")
+      GET_PARAM (resolutionUnits, "ResolutionUnits")
+      GET_PARAM (type, "ColorType")
+      GET_PARAM (view, "View")
+        
+      output (0) = st;
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+      return output;
+    }
+
+#else
+
+  error ("imfinfo: not available in this version of Octave");
+
+#endif
+
+  return output;
+}
+
+#undef GET_PARAM
+      
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; indent-tabs-mode: nil ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/__pchip_deriv__.cc b/src/DLD-FUNCTIONS/__pchip_deriv__.cc
new file mode 100644
index 0000000..18d2b1e
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__pchip_deriv__.cc
@@ -0,0 +1,147 @@
+/* 
+
+Copyright (C) 2002, 2006, 2007 Kai Habel
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dpchim, DPCHIM) (const octave_idx_type& n, const double *x, const double *f,
+			     double *d, const octave_idx_type &incfd,
+			     octave_idx_type *ierr);
+
+  F77_RET_T
+  F77_FUNC (pchim, PCHIM) (const octave_idx_type& n, const float *x, const float *f,
+			   float *d, const octave_idx_type &incfd,
+			   octave_idx_type *ierr);
+}
+
+// Wrapper for SLATEC/PCHIP function DPCHIM to calculate the derivates
+// for piecewise polynomials.
+
+DEFUN_DLD (__pchip_deriv__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} __pchip_deriv__ (@var{x}, @var{y}, @var{dim})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  const int nargin = args.length ();
+
+  bool rows = (nargin == 3 && args (2).uint_value() == 2);
+
+  if (nargin >= 2)
+    {
+      if (args(0).is_single_type () || args(1).is_single_type ())
+	{
+	  FloatColumnVector xvec (args(0).float_vector_value ());
+	  FloatMatrix ymat (args(1).float_matrix_value ());
+
+	  octave_idx_type nx = xvec.length ();
+	  octave_idx_type nyr = ymat.rows ();
+	  octave_idx_type nyc = ymat.columns ();
+
+          if (nx != (rows ? nyc : nyr))
+	    {
+              error ("__pchip_deriv__: dimension mismatch");
+	      return retval;
+	    }
+
+          const float *yvec = ymat.data ();
+	  FloatMatrix dmat (nyr, nyc);
+          float *dvec = dmat.fortran_vec ();
+
+	  octave_idx_type ierr;
+          const octave_idx_type incfd = rows ? nyr : 1;
+          const octave_idx_type inc = rows ? 1 : nyr;
+
+          for (octave_idx_type i = (rows ? nyr : nyc); i > 0; i--)
+	    {
+              F77_FUNC (pchim, PCHIM) (nx, xvec.data (), 
+                                       yvec, dvec, incfd, &ierr);
+
+              yvec += inc;
+              dvec += inc;
+
+	      if (ierr < 0)
+		{
+		  error ("PCHIM error: %i\n", ierr);
+		  return retval;
+		}
+	    }
+
+	  retval = dmat;
+	}
+      else
+	{
+	  ColumnVector xvec (args(0).vector_value ());
+	  Matrix ymat (args(1).matrix_value ());
+
+	  octave_idx_type nx = xvec.length ();
+	  octave_idx_type nyr = ymat.rows ();
+	  octave_idx_type nyc = ymat.columns ();
+
+          if (nx != (rows ? nyc : nyr))
+	    {
+              error ("__pchip_deriv__: dimension mismatch");
+	      return retval;
+	    }
+
+          const double *yvec = ymat.data ();
+	  Matrix dmat (nyr, nyc);
+          double *dvec = dmat.fortran_vec ();
+
+	  octave_idx_type ierr;
+          const octave_idx_type incfd = rows ? nyr : 1;
+          const octave_idx_type inc = rows ? 1 : nyr;
+
+          for (octave_idx_type i = (rows ? nyr : nyc); i > 0; i--)
+	    {
+              F77_FUNC (dpchim, DPCHIM) (nx, xvec.data (), 
+                                         yvec, dvec, incfd, &ierr);
+
+              yvec += inc;
+              dvec += inc;
+
+	      if (ierr < 0)
+		{
+		  error ("DPCHIM error: %i\n", ierr);
+		  return retval;
+		}
+	    }
+
+	  retval = dmat;
+	}
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__qp__.cc b/src/DLD-FUNCTIONS/__qp__.cc
new file mode 100644
index 0000000..5d2300f
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__qp__.cc
@@ -0,0 +1,530 @@
+/*
+
+Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008 Gabriele Pannocchia
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+
+#include "dbleCHOL.h"
+#include "dbleSVD.h"
+#include "mx-m-dm.h"
+#include "EIG.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "pr-output.h"
+#include "utils.h"
+
+static Matrix
+null (const Matrix& A, octave_idx_type& rank)
+{
+  Matrix retval;
+
+  rank = 0;
+
+  if (! A.is_empty ())
+    {
+      SVD A_svd (A);
+
+      DiagMatrix S = A_svd.singular_values ();
+
+      ColumnVector s = S.diag ();
+
+      Matrix V = A_svd.right_singular_matrix ();
+
+      octave_idx_type A_nr = A.rows ();
+      octave_idx_type A_nc = A.cols ();
+
+      octave_idx_type tmp = A_nr > A_nc ? A_nr : A_nc;
+
+      double tol = tmp * s(0) * DBL_EPSILON;
+
+      octave_idx_type n = s.length ();
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  if (s(i) > tol)
+	    rank++;
+	}
+
+      if (rank < A_nc)
+	retval = V.extract (0, rank, A_nc-1, A_nc-1);
+      else
+	retval.resize (A_nc, 0);
+
+      for (octave_idx_type i = 0; i < retval.numel (); i++)
+	if (std::abs (retval(i)) < DBL_EPSILON)
+	  retval(i) = 0;
+    }
+
+  return retval;
+}
+
+static int
+qp (const Matrix& H, const ColumnVector& q,
+    const Matrix& Aeq, const ColumnVector& beq,
+    const Matrix& Ain, const ColumnVector& bin,
+    int maxit,
+    ColumnVector& x, ColumnVector& lambda, int& iter)
+{
+  int info = 0;
+
+  iter = 0;
+
+  double rtol = sqrt (DBL_EPSILON);
+
+  // Problem dimension.
+  octave_idx_type n = x.length ();
+
+  // Dimension of constraints.
+  octave_idx_type n_eq = beq.length ();
+  octave_idx_type n_in = bin.length ();
+
+  // Filling the current active set.
+
+  octave_idx_type n_act = n_eq;
+
+  octave_idx_type n_tot = n_eq + n_in;
+
+  // Equality constraints come first.  We won't check the sign of the
+  // Lagrange multiplier for those.
+
+  Matrix Aact = Aeq;
+  ColumnVector bact = beq;
+  ColumnVector Wact;
+
+  if (n_in > 0)
+    {
+      ColumnVector res = Ain*x - bin;
+
+      for (octave_idx_type i = 0; i < n_in; i++)
+	{
+	  res(i) /= (1.0 + std::abs (bin(i)));
+
+	  if (res(i) < rtol)
+	    {
+	      n_act++;
+	      Aact = Aact.stack (Ain.row (i));
+	      bact.resize (n_act, bin(i));
+	      Wact.resize (n_act-n_eq, i);
+	    }
+	}
+    }
+
+  // Computing the ???
+
+  EIG eigH (H);
+
+  if (error_state)
+    {
+      error ("qp: failed to compute eigenvalues of H");
+      return -1;
+    }
+
+  ColumnVector eigenvalH = real (eigH.eigenvalues ());
+  Matrix eigenvecH = real (eigH.eigenvectors ());
+  double minReal = eigenvalH.min ();
+  octave_idx_type indminR = 0;
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      if (minReal == eigenvalH(i))
+	{
+	  indminR = i;
+	  break;
+	}
+    }
+
+  bool done = false;
+
+  double alpha = 0.0;
+
+  Matrix R;
+  Matrix Y (n, 0, 0.0);
+
+  ColumnVector g (n, 0.0);
+  ColumnVector p (n, 0.0);
+
+  ColumnVector lambda_tmp (n_in, 0.0);
+
+  while (! done)
+    {
+      iter++;
+
+      // Current Gradient
+      // g = q + H * x;
+
+      g = q + H * x;
+
+      if (n_act == 0)
+	{
+	  // There are no active constraints.
+
+	  if (minReal > 0.0)
+	    {
+	      // Inverting the Hessian.  Using the Cholesky
+	      // factorization since the Hessian is positive
+	      // definite.
+
+	      CHOL cholH (H);
+
+	      R = cholH.chol_matrix ();
+
+	      Matrix Hinv = chol2inv (R);
+
+	      // Computing the unconstrained step.
+	      // p = -Hinv * g;
+
+	      p = -Hinv * g;
+
+	      info = 0;
+	    }
+	  else
+	    {
+	      // Finding the negative curvature of H.
+
+	      p = eigenvecH.column (indminR);
+
+	      // Following the negative curvature of H.
+
+	      if (p.transpose () * g > DBL_EPSILON)
+	        p = -p;
+
+	      info = 1;
+	    }
+
+	  // Multipliers are zero.
+          lambda_tmp.fill (0.0);
+	}
+      else
+        {
+	  // There are active constraints.
+
+	  // Computing the null space.
+
+	  octave_idx_type rank;
+
+	  Matrix Z = null (Aact, rank);
+
+	  octave_idx_type dimZ = n - rank;
+
+	  // FIXME -- still remain to handle the case of
+	  // non-full rank active set matrix.
+
+	  // Computing the Y matrix (orthogonal to Z)
+	  Y = Aact.pseudo_inverse ();
+
+	  // Reduced Hessian
+	  Matrix Zt = Z.transpose ();
+	  Matrix rH = Zt * H * Z;
+
+	  octave_idx_type pR = 0;
+
+	  if (dimZ > 0)
+	    {
+	      // Computing the Cholesky factorization (pR = 0 means
+	      // that the reduced Hessian was positive definite).
+
+	      CHOL cholrH (rH, pR);
+	      Matrix tR = cholrH.chol_matrix ();
+	      if (pR == 0)
+		R = tR;
+	    }
+
+	  if (pR == 0)
+	    {
+	      info = 0;
+
+	      // Computing the step pz. 
+	      if (dimZ > 0)
+		{
+		  // Using the Cholesky factorization to invert rH
+
+		  Matrix rHinv = chol2inv (R);
+
+		  ColumnVector pz = -rHinv * Zt * g;
+
+		  // Global step.
+		  p = Z * pz;
+		}
+	      else
+		{
+		  // Global step.
+		  p.fill (0.0);
+		}
+	    }
+	  else
+	    {
+	      info = 1;
+
+	      // Searching for the most negative curvature.
+
+	      EIG eigrH (rH);
+
+	      if (error_state)
+		{
+		  error ("qp: failed to compute eigenvalues of rH");
+		  return -1;
+		}
+
+	      ColumnVector eigenvalrH = real (eigrH.eigenvalues ());
+	      Matrix eigenvecrH = real (eigrH.eigenvectors ());
+	      double mRrH = eigenvalrH.min ();
+	      indminR = 0;
+	      for (octave_idx_type i = 0; i < n; i++)
+		{
+		  if (mRrH == eigenvalH(i))
+		    {
+		      indminR = i;
+		      break;
+		    }
+		}
+
+	      ColumnVector eVrH = eigenvecrH.column (indminR);
+
+	      // Computing the step pz.
+	      p = Z * eVrH;
+
+	      if (p.transpose () * g > DBL_EPSILON)
+		p = -p;
+	    }
+	}
+
+      // Checking the step-size.
+      ColumnVector abs_p (n);
+      for (octave_idx_type i = 0; i < n; i++)
+	abs_p(i) = std::abs (p(i));
+      double max_p = abs_p.max ();
+
+      if (max_p < rtol)
+	{
+	  // The step is null.  Checking constraints.
+	  if (n_act - n_eq == 0)
+	    // Solution is found because no inequality
+	    // constraints are active.
+	    done = true;
+	  else
+	    {
+	      // Computing the multipliers only for the inequality
+	      // constraints that are active.  We do NOT compute
+	      // multipliers for the equality constraints.
+	      Matrix Yt = Y.transpose ();
+	      Yt = Yt.extract_n (n_eq, 0, n_act-n_eq, n);
+	      lambda_tmp = Yt * (g + H * p);
+
+	      // Checking the multipliers.  We remove the most
+	      // negative from the set (if any).
+	      double min_lambda = lambda_tmp.min ();
+	      if (min_lambda >= 0)
+		{
+		  // Solution is found.
+		  done = true;
+		}
+	      else
+		{
+		  octave_idx_type which_eig = 0;
+		  for (octave_idx_type i = 0; i < n_act; i++)
+		    {
+		      if (lambda_tmp(i) == min_lambda)
+			{
+			  which_eig = i;
+			  break;
+			}
+		    }
+
+		  // At least one multiplier is negative, we
+		  // remove it from the set.
+
+		  n_act--;
+		  for (octave_idx_type i = which_eig; i < n_act - n_eq; i++)
+		    {
+		      Wact(i) = Wact(i+1);
+		      for (octave_idx_type j = 0; j < n; j++)
+			Aact(n_eq+i,j) = Aact(n_eq+i+1,j);
+		      bact(n_eq+i) = bact(n_eq+i+1);
+		    }
+
+		  // Resizing the active set.
+		  Wact.resize (n_act-n_eq);
+		  bact.resize (n_act);
+		  Aact.resize (n_act, n);
+		}
+	    }
+	}
+      else
+	{
+	  // The step is not null.
+	  if (n_act - n_eq == n_in)
+	    {
+	      // All inequality constraints were active.  We can
+	      // add the whole step.
+	      x += p;
+	    }
+	  else
+	    {
+	      // Some constraints were not active.  Checking if
+	      // there is a blocking constraint.
+	      alpha = 1.0;
+	      octave_idx_type is_block = -1;
+
+	      for (octave_idx_type i = 0; i < n_in; i++)
+		{
+		  bool found = false;
+
+		  for (octave_idx_type j = 0; j < n_act-n_eq; j++)
+		    {
+		      if (Wact(j) == i)
+			{
+			  found = true;
+			  break;
+			}
+		    }
+
+		  if (! found)
+		    {
+		      // The i-th constraint was not in the set.  Is it a
+		      // blocking constraint?
+
+		      RowVector tmp_row = Ain.row (i);
+		      double tmp = tmp_row * p;
+		      double res = tmp_row * x;
+
+		      if (tmp < 0.0)
+		        {
+			  double alpha_tmp = (bin(i) - res) / tmp;
+
+			  if (alpha_tmp < alpha)
+			    {
+			      alpha = alpha_tmp;
+			      is_block = i;
+			    }
+			}
+		    }
+		}
+
+	      // In is_block there is the index of the blocking
+	      // constraint (if any).
+	      if (is_block >= 0)
+		{
+		  // There is a blocking constraint (index in
+		  // is_block) which is added to the active set.
+		  n_act++;
+		  Aact = Aact.stack (Ain.row (is_block));
+		  bact.resize (n_act, bin(is_block));
+		  Wact.resize (n_act-n_eq, is_block);
+
+		  // Adding the reduced step
+		  x += alpha * p;
+		}
+	      else
+		{
+		  // There are no blocking constraints.  Adding the
+		  // whole step.
+		  x += alpha * p;
+		}
+	    }
+	}
+
+      if (iter == maxit)
+	{
+	  done = true;
+	  // warning ("qp_main: maximum number of iteration reached");
+	  info = 3;
+	}
+    }
+
+  lambda_tmp = Y.transpose () * (g + H * p);
+
+  // Reordering the Lagrange multipliers.
+
+  lambda.resize (n_tot);
+  lambda.fill (0.0);
+  for (octave_idx_type i = 0; i < n_eq; i++)
+    lambda(i) = lambda_tmp(i);
+
+  for (octave_idx_type i = n_eq; i < n_tot; i++)
+    {
+      for (octave_idx_type j = 0; j < n_act-n_eq; j++)
+	{
+	  if (Wact(j) == i - n_eq)
+	    {
+	      lambda(i) = lambda_tmp(n_eq+j);
+	      break;
+	    }
+	}
+    }
+
+  return info;
+}
+
+DEFUN_DLD (__qp__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{x}, @var{lambda}, @var{info}, @var{iter}] =} __qp__ (@var{x0}, @var{H}, @var{q}, @var{Aeq}, @var{beq}, @var{Ain}, @var{bin}, @var{maxit})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 8)
+    {
+      const ColumnVector x0  (args(0) . vector_value ());
+      const Matrix H         (args(1) . matrix_value ());
+      const ColumnVector q   (args(2) . vector_value ());
+      const Matrix Aeq       (args(3) . matrix_value ());
+      const ColumnVector beq (args(4) . vector_value ());
+      const Matrix Ain       (args(5) . matrix_value ());
+      const ColumnVector bin (args(6) . vector_value ());
+      const int maxit        (args(7) . int_value ());
+
+      if (! error_state)
+	{
+	  int iter = 0;
+
+	  // Copying the initial guess in the working variable
+	  ColumnVector x = x0;
+
+	  // Reordering the Lagrange multipliers
+	  ColumnVector lambda;
+
+	  int info = qp (H, q, Aeq, beq, Ain, bin, maxit, x, lambda, iter);
+
+	  if (! error_state)
+	    {
+	      retval(3) = iter;
+	      retval(2) = info;
+	      retval(1) = lambda;
+	      retval(0) = x;
+	    }
+	  else
+	    error ("qp: internal error");
+	}
+      else
+	error ("__qp__: invalid arguments");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/__voronoi__.cc b/src/DLD-FUNCTIONS/__voronoi__.cc
new file mode 100644
index 0000000..d142ac9
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__voronoi__.cc
@@ -0,0 +1,245 @@
+/*
+
+Copyright (C) 2000, 2007, 2008 Kai Habel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+20. Augiust 2000 - Kai Habel: first release
+*/
+
+/*
+2003-12-14 Rafael Laboissiere <rafael at laboissiere.net>
+Added optional second argument to pass options to the underlying
+qhull command
+*/
+
+#include <iostream>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "lo-ieee.h"
+#include "oct.h"
+#include "Cell.h"
+
+#ifdef HAVE_QHULL
+extern "C" {
+#include <qhull/qhull_a.h>
+}
+
+#ifdef NEED_QHULL_VERSION
+char qh_version[] = "__voronoi__.oct 2007-07-24";
+#endif
+#endif
+
+DEFUN_DLD (__voronoi__, args, ,
+        "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{tri} =} __voronoi__ (@var{point})\n\
+ at deftypefnx {Loadable Function} {@var{tri} =} __voronoi__ (@var{point}, @var{options})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_QHULL
+
+  retval(0) = 0.0;
+
+  int nargin = args.length ();
+  if (nargin < 1 || nargin > 2) 
+    {
+      print_usage ();
+      return retval;
+    }
+
+  const char *options;
+
+  if (nargin == 2) 
+    {
+      if (! args (1).is_string ()) 
+	{
+	  error ("__voronoi__: second argument must be a string");
+	  return retval;
+	}
+
+      options = args (1).string_value().c_str ();
+    }
+  else
+    options = "";
+
+  Matrix p (args(0).matrix_value ());
+
+  const octave_idx_type dim = p.columns ();
+  const octave_idx_type np = p.rows ();
+  p = p.transpose ();
+
+  double *pt_array = p.fortran_vec ();
+
+  //double  pt_array[dim * np];
+  //for (int i = 0; i < np; i++) 
+  //  {
+  //    for (int j = 0; j < dim; j++)
+  //	  {
+  //	    pt_array[j+i*dim] = p(i,j);
+  //	  }
+  //  }
+
+  boolT ismalloc = false;
+
+  OCTAVE_LOCAL_BUFFER (char, flags, 250);
+
+  // hmm  lot's of options for qhull here
+  sprintf (flags, "qhull v Fv T0 %s", options);
+
+  // If you want some debugging information replace the 0 pointer
+  // with stdout or some other file open for writing.
+
+  FILE *outfile = 0;
+  FILE *errfile = stderr;
+
+  if (! qh_new_qhull (dim, np, pt_array, ismalloc, flags, outfile, errfile)) 
+    {
+      facetT *facet;
+      vertexT *vertex;
+
+      octave_idx_type i = 0, n = 1, k = 0, m = 0, fidx = 0, j = 0, r = 0;
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, ni, np);
+      
+      for (i = 0; i < np; i++) 
+	ni[i] = 0;
+      qh_setvoronoi_all ();
+      bool infinity_seen = false;
+      facetT *neighbor, **neighborp;
+      coordT *voronoi_vertex;
+
+      FORALLfacets 
+	{
+	  facet->seen = false;
+	}
+
+      FORALLvertices 
+	{
+	  if (qh hull_dim == 3)
+	    qh_order_vertexneighbors (vertex);
+	  infinity_seen = false;
+
+	  FOREACHneighbor_ (vertex)
+	    {
+	      if (! neighbor->upperdelaunay)
+		{
+		  if (! neighbor->seen)
+		    {
+		      n++;
+		      neighbor->seen = true;
+		    }
+		  ni[k]++;
+		}
+	      else if (! infinity_seen)
+		{
+		  infinity_seen = true;
+		  ni[k]++;
+		}
+	    }
+	  k++;
+	}
+
+      Matrix v (n, dim);
+      for (octave_idx_type d = 0; d < dim; d++)
+	v(0,d) = octave_Inf;
+
+      boolMatrix AtInf (np, 1);
+      for (i = 0; i < np; i++) 
+	AtInf(i) = false;
+      octave_value_list F (np, octave_value ());
+      k = 0;
+      i = 0;
+
+      FORALLfacets 
+	{
+	  facet->seen = false;
+	}
+
+      FORALLvertices
+	{
+	  if (qh hull_dim == 3)
+	    qh_order_vertexneighbors(vertex);
+	  infinity_seen = false;
+	  RowVector facet_list (ni[k++]);
+	  m = 0;
+
+	  FOREACHneighbor_(vertex)
+	    {
+	      if (neighbor->upperdelaunay)
+		{
+		  if (! infinity_seen)
+		    {
+		      infinity_seen = true;
+		      facet_list(m++) = 1;
+		      AtInf(j) = true;
+		    }
+		} 
+	      else 
+		{
+		  if (! neighbor->seen)
+		    {
+		      voronoi_vertex = neighbor->center;
+		      fidx = neighbor->id;
+		      i++;
+		      for (octave_idx_type d = 0; d < dim; d++)
+			{
+			  v(i,d) = *(voronoi_vertex++);
+			}
+		      neighbor->seen = true;
+		      neighbor->visitid = i;
+		    }
+		  facet_list(m++) = neighbor->visitid + 1;
+		}
+	    }
+	  F(r++) = facet_list;
+	  j++;
+	}
+
+      Cell C(r, 1);
+      for (i = 0; i < r; i++)
+	C.elem (i) = F(i);
+
+      retval(0) = v;
+      retval(1) = C;
+      AtInf.resize (r, 1);
+      retval(2) = AtInf;
+
+      // free long memory
+      qh_freeqhull (! qh_ALL);
+
+      // free short memory and memory allocator
+      int curlong, totlong;
+      qh_memfreeshort (&curlong, &totlong);
+
+      if (curlong || totlong)
+	warning ("__voronoi__: did not free %d bytes of long memory (%d pieces)", totlong, curlong);
+    }
+  else
+    error ("__voronoi__: qhull failed");
+
+#else
+  error ("__voronoi__: not available in this version of Octave");
+#endif
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/amd.cc b/src/DLD-FUNCTIONS/amd.cc
new file mode 100644
index 0000000..48abf88
--- /dev/null
+++ b/src/DLD-FUNCTIONS/amd.cc
@@ -0,0 +1,213 @@
+/*
+
+Copyright (C) 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This is the octave interface to amd, which bore the copyright given
+// in the help of the functions.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+#include <vector>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "pager.h"
+#include "ov-re-mat.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "oct-map.h"
+
+#include "oct-sparse.h"
+#include "oct-locbuf.h"
+
+#ifdef IDX_TYPE_LONG
+#define AMD_NAME(name) amd_l ## name
+#else
+#define AMD_NAME(name) amd ## name
+#endif
+
+DEFUN_DLD (amd, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} amd (@var{s})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} amd (@var{s}, @var{opts})\n\
+\n\
+Returns the approximate minimum degree permutation of a matrix.  This\n\
+permutation such that the Cholesky factorization of @code{@var{s} (@var{p},\n\
+ at var{p})} tends to be sparser than the Cholesky factorization of @var{s}\n\
+itself.  @code{amd} is typically faster than @code{symamd} but serves a\n\
+similar purpose.\n\
+\n\
+The optional parameter @var{opts} is a structure that controls the\n\
+behavior of @code{amd}.  The fields of these structure are\n\
+\n\
+ at table @asis\n\
+ at item opts.dense\n\
+Determines what @code{amd} considers to be a dense row or column of the\n\
+input matrix.  Rows or columns with more than @code{max(16, (dense *\n\
+sqrt (@var{n})} entries, where @var{n} is the order of the matrix @var{s},\n\
+are ignored by @code{amd} during the calculation of the permutation\n\
+The value of dense must be a positive scalar and its default value is 10.0\n\
+\n\
+ at item opts.aggressive\n\
+If this value is a non zero scalar, then @code{amd} performs aggressive\n\
+absorption.  The default is not to perform aggressive absorption.\n\
+ at end table\n\
+\n\
+The author of the code itself is Timothy A. Davis (davis@@cise.ufl.edu),\n\
+University of Florida (see @url{http://www.cise.ufl.edu/research/sparse/amd}).\n\
+ at seealso{symamd, colamd}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_AMD
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    {
+      octave_idx_type n_row, n_col, nnz;
+      const octave_idx_type *ridx, *cidx;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      scm = args(0).sparse_complex_matrix_value ();
+	      n_row = scm.rows ();
+	      n_col = scm.cols ();
+	      nnz = scm.nzmax ();
+	      ridx = scm.xridx ();
+	      cidx = scm.xcidx ();
+	    }
+	  else
+	    {
+	      sm = args(0).sparse_matrix_value ();
+	      n_row = sm.rows ();
+	      n_col = sm.cols ();
+	      nnz = sm.nzmax ();
+	      ridx = sm.xridx ();
+	      cidx = sm.xcidx ();
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type ())
+	    sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+	  else
+	    sm = SparseMatrix (args(0).matrix_value ());
+	  
+	  n_row = sm.rows ();
+	  n_col = sm.cols ();
+	  nnz = sm.nzmax ();
+	  ridx = sm.xridx ();
+	  cidx = sm.xcidx ();
+	}
+
+      if (!error_state && n_row != n_col)
+	error ("amd: input matrix must be square");
+
+      if (!error_state)
+	{
+	  OCTAVE_LOCAL_BUFFER (double, Control, AMD_CONTROL);
+	  AMD_NAME (_defaults) (Control) ;
+	  if (nargin > 1)
+	    {
+	      Octave_map arg1 = args(1).map_value ();
+	  
+	      if (!error_state)
+		{
+		  if (arg1.contains ("dense"))
+		    {
+		      Cell c = arg1.contents ("dense");
+		      if (c.length() == 1)
+			Control[AMD_DENSE] = c.elem(0).double_value ();
+		      else
+			error ("amd: invalid options structure");
+		    }
+		  if (arg1.contains ("aggressive"))
+		    {
+		      Cell c = arg1.contents ("aggressive");
+		      if (c.length() == 1)
+			Control[AMD_AGGRESSIVE] = c.elem(0).double_value ();
+		      else
+			error ("amd: invalid options structure");
+		    }
+		}
+	    }
+
+	  if (!error_state)
+	    {
+	      OCTAVE_LOCAL_BUFFER (octave_idx_type, P, n_col);
+	      Matrix xinfo (AMD_INFO, 1);
+	      double *Info = xinfo.fortran_vec ();
+
+	      // FIXME -- how can we manage the memory allocation of
+	      // amd in a cleaner manner? 
+	      amd_malloc = malloc;
+	      amd_free = free;
+	      amd_calloc = calloc;
+	      amd_realloc = realloc;
+	      amd_printf = printf;
+
+	      octave_idx_type result = AMD_NAME (_order) (n_col, cidx, ridx, P,
+							  Control, Info);
+
+	      switch (result)
+		{
+		case AMD_OUT_OF_MEMORY:
+		  error ("amd: out of memory");
+		  break;
+		case AMD_INVALID:
+		  error ("amd: input matrix is corrupted");
+		  break;
+		default:
+		  {
+		    if (nargout > 1)
+		      retval(1) = xinfo;
+
+		    Matrix Pout (1, n_col);
+		    for (octave_idx_type i = 0; i < n_col; i++)
+		      Pout.xelem (i) = P[i] + 1;
+
+		    retval (0) = Pout;
+		  }
+		}
+	    }
+	}
+    }
+#else
+
+  error ("amd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/balance.cc b/src/DLD-FUNCTIONS/balance.cc
new file mode 100644
index 0000000..8844388
--- /dev/null
+++ b/src/DLD-FUNCTIONS/balance.cc
@@ -0,0 +1,395 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2006,
+              2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: A. S. Hodel <scotte at eng.auburn.edu>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "CmplxAEPBAL.h"
+#include "fCmplxAEPBAL.h"
+#include "dbleAEPBAL.h"
+#include "floatAEPBAL.h"
+#include "CmplxGEPBAL.h"
+#include "fCmplxGEPBAL.h"
+#include "dbleGEPBAL.h"
+#include "floatGEPBAL.h"
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "f77-fcn.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (balance, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{aa} =} balance (@var{a}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{dd}, @var{aa}] =} balance (@var{a}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{d}, @var{p}, @var{aa}] =} balance (@var{a}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{cc}, @var{dd}, @var{aa}, @var{bb}] =} balance (@var{a}, @var{b}, @var{opt})\n\
+\n\
+Compute @code{aa = dd \\ a * dd} in which @code{aa} is a matrix whose\n\
+row and column norms are roughly equal in magnitude, and\n\
+ at code{dd} = @code{p * d}, in which @code{p} is a permutation\n\
+matrix and @code{d} is a diagonal matrix of powers of two.  This allows\n\
+the equilibration to be computed without roundoff.  Results of\n\
+eigenvalue calculation are typically improved by balancing first.\n\
+\n\
+If two output values are requested, @code{balance} returns \n\
+the diagonal @code{d} and the permutation @code{p} separately as vectors.  \n\
+In this case, @code{dd = eye(n)(:,p) * diag (d)}, where @code{n} is the matrix \n\
+size.  \n\
+\n\
+If four output values are requested, compute @code{aa = cc*a*dd} and\n\
+ at code{bb = cc*b*dd)}, in which @code{aa} and @code{bb} have non-zero\n\
+elements of approximately the same magnitude and @code{cc} and @code{dd}\n\
+are permuted diagonal matrices as in @code{dd} for the algebraic\n\
+eigenvalue problem.\n\
+\n\
+The eigenvalue balancing option @code{opt} may be one of:\n\
+\n\
+ at table @asis\n\
+ at item @code{\"noperm\"}, @code{\"S\"}\n\
+Scale only; do not permute.\n\
+\n\
+ at item @code{\"noscal\"}, @code{\"P\"}\n\
+Permute only; do not scale.\n\
+ at end table\n\
+\n\
+Algebraic eigenvalue balancing uses standard @sc{lapack} routines.\n\
+\n\
+Generalized eigenvalue problem balancing uses Ward's algorithm\n\
+(SIAM Journal on Scientific and Statistical Computing, 1981).\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 3 || nargout < 0 || nargout > 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // determine if it's AEP or GEP
+  bool AEPcase = nargin == 1 || args(1).is_string ();
+
+  // problem dimension
+  octave_idx_type nn = args(0).rows ();
+
+  if (nn != args(0).columns())
+    {
+      gripe_square_matrix_required ("balance");
+      return retval;
+    }
+
+  bool isfloat = args(0).is_single_type () || 
+    (! AEPcase && args(1).is_single_type()); 
+
+  bool complex_case = (args(0).is_complex_type () || 
+		       (! AEPcase && args(1).is_complex_type ()));
+
+  // Extract argument 1 parameter for both AEP and GEP.
+  Matrix aa;
+  ComplexMatrix caa;
+  FloatMatrix faa;
+  FloatComplexMatrix fcaa;
+
+  if (isfloat)
+    {
+      if (complex_case)
+	fcaa = args(0).float_complex_matrix_value ();
+      else
+	faa = args(0).float_matrix_value ();
+    }
+  else
+    {
+      if (complex_case)
+	caa = args(0).complex_matrix_value ();
+      else
+	aa = args(0).matrix_value ();
+    }
+
+  if (error_state)
+    return retval;
+
+  // Treat AEP/GEP cases.
+  if (AEPcase)
+    {  
+      // Algebraic eigenvalue problem.
+      bool noperm = false, noscal = false;
+      if (nargin > 1)
+        {
+          std::string a1s = args(1).string_value ();
+          noperm = a1s == "noperm" || a1s == "S";
+          noscal = a1s == "noscal" || a1s == "P";
+        }
+
+      // balance the AEP
+      if (isfloat)
+	{
+	  if (complex_case)
+	    {
+	      FloatComplexAEPBALANCE result (fcaa, noperm, noscal);
+
+	      if (nargout == 0 || nargout == 1)
+		retval(0) = result.balanced_matrix ();
+	      else if (nargout == 2)
+		{
+		  retval(1) = result.balanced_matrix ();
+		  retval(0) = result.balancing_matrix ();
+		}
+              else
+                {
+                  retval(2) = result.balanced_matrix ();
+                  retval(0) = result.scaling_vector ();
+                  retval(1) = result.permuting_vector ();
+                }
+
+	    }
+	  else
+	    {
+	      FloatAEPBALANCE result (faa, noperm, noscal);
+
+	      if (nargout == 0 || nargout == 1)
+		retval(0) = result.balanced_matrix ();
+	      else if (nargout == 2)
+		{
+		  retval(1) = result.balanced_matrix ();
+		  retval(0) = result.balancing_matrix ();
+		}
+              else
+                {
+                  retval(2) = result.balanced_matrix ();
+                  retval(0) = result.scaling_vector ();
+                  retval(1) = result.permuting_vector ();
+                }
+	    }
+	}
+      else
+	{
+	  if (complex_case)
+	    {
+	      ComplexAEPBALANCE result (caa, noperm, noscal);
+
+	      if (nargout == 0 || nargout == 1)
+		retval(0) = result.balanced_matrix ();
+	      else if (nargout == 2)
+		{
+		  retval(1) = result.balanced_matrix ();
+		  retval(0) = result.balancing_matrix ();
+		}
+              else
+                {
+                  retval(2) = result.balanced_matrix ();
+                  retval(0) = result.scaling_vector ();
+                  retval(1) = result.permuting_vector ();
+                }
+	    }
+	  else
+	    {
+	      AEPBALANCE result (aa, noperm, noscal);
+
+	      if (nargout == 0 || nargout == 1)
+		retval(0) = result.balanced_matrix ();
+	      else if (nargout == 2)
+		{
+		  retval(1) = result.balanced_matrix ();
+		  retval(0) = result.balancing_matrix ();
+		}
+              else
+                {
+                  retval(2) = result.balanced_matrix ();
+                  retval(0) = result.scaling_vector ();
+                  retval(1) = result.permuting_vector ();
+                }
+	    }
+	}
+    }
+  else
+    {
+      std::string bal_job;
+      if (nargout == 1)
+	warning ("balance: used GEP, should have two output arguments");
+
+      // Generalized eigenvalue problem.
+      if (nargin == 2)
+	bal_job = "B";
+      else if (args(2).is_string ())
+	bal_job = args(2).string_value ();
+      else
+	{
+	  error ("balance: GEP argument 3 must be a string");
+	  return retval;
+	}
+
+      if ((nn != args(1).columns ()) || (nn != args(1).rows ()))
+	{
+	  gripe_nonconformant ();
+	  return retval;
+	}
+
+      Matrix bb;
+      ComplexMatrix cbb;
+      FloatMatrix fbb;
+      FloatComplexMatrix fcbb;
+
+      if (isfloat)
+	{
+	  if (complex_case)
+	    fcbb = args(1).float_complex_matrix_value ();
+	  else
+	    fbb = args(1).float_matrix_value ();
+	}
+      else
+	{
+	  if (complex_case)
+	    cbb = args(1).complex_matrix_value ();
+	  else
+	    bb = args(1).matrix_value ();
+	}
+
+      // balance the GEP
+      if (isfloat)
+	{
+	  if (complex_case)
+	    {
+	      FloatComplexGEPBALANCE result (fcaa, fcbb, bal_job);
+
+	      switch (nargout)
+		{
+		case 4:
+		  retval(3) = result.balanced_matrix2 ();
+		  // fall through
+		case 3:
+		  retval(2) = result.balanced_matrix ();
+		  retval(1) = result.balancing_matrix2 ();
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		case 2:
+		  retval(1) = result.balancing_matrix2 ();
+		  // fall through
+		case 1:
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		default:
+		  error ("balance: invalid number of output arguments");
+		  break;
+		}
+	    }
+	  else
+	    {
+	      FloatGEPBALANCE result (faa, fbb, bal_job);
+
+	      switch (nargout)
+		{
+		case 4:
+		  retval(3) = result.balanced_matrix2 ();
+		  // fall through
+		case 3:
+		  retval(2) = result.balanced_matrix ();
+		  retval(1) = result.balancing_matrix2 ();
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		case 2:
+		  retval(1) = result.balancing_matrix2 ();
+		  // fall through
+		case 1:
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		default:
+		  error ("balance: invalid number of output arguments");
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  if (complex_case)
+	    {
+	      ComplexGEPBALANCE result (caa, cbb, bal_job);
+
+	      switch (nargout)
+		{
+		case 4:
+		  retval(3) = result.balanced_matrix2 ();
+		  // fall through
+		case 3:
+		  retval(2) = result.balanced_matrix ();
+		  retval(1) = result.balancing_matrix2 ();
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		case 2:
+		  retval(1) = result.balancing_matrix2 ();
+		  // fall through
+		case 1:
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		default:
+		  error ("balance: invalid number of output arguments");
+		  break;
+		}
+	    }
+	  else
+	    {
+	      GEPBALANCE result (aa, bb, bal_job);
+
+	      switch (nargout)
+		{
+		case 4:
+		  retval(3) = result.balanced_matrix2 ();
+		  // fall through
+		case 3:
+		  retval(2) = result.balanced_matrix ();
+		  retval(1) = result.balancing_matrix2 ();
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		case 2:
+		  retval(1) = result.balancing_matrix2 ();
+		  // fall through
+		case 1:
+		  retval(0) = result.balancing_matrix ();
+		  break;
+		default:
+		  error ("balance: invalid number of output arguments");
+		  break;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/besselj.cc b/src/DLD-FUNCTIONS/besselj.cc
new file mode 100644
index 0000000..f88036a
--- /dev/null
+++ b/src/DLD-FUNCTIONS/besselj.cc
@@ -0,0 +1,922 @@
+/*
+
+Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-specfun.h"
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+enum bessel_type
+{
+  BESSEL_J,
+  BESSEL_Y,
+  BESSEL_I,
+  BESSEL_K,
+  BESSEL_H1,
+  BESSEL_H2
+};
+
+#define DO_BESSEL(type, alpha, x, scaled, ierr, result) \
+  do \
+    { \
+      switch (type) \
+	{ \
+	  case BESSEL_J: \
+	    result = besselj (alpha, x, scaled, ierr); \
+	    break; \
+ \
+	  case BESSEL_Y: \
+	    result = bessely (alpha, x, scaled, ierr); \
+	    break; \
+ \
+	  case BESSEL_I: \
+	    result = besseli (alpha, x, scaled, ierr); \
+	    break; \
+ \
+	  case BESSEL_K: \
+	    result = besselk (alpha, x, scaled, ierr); \
+	    break; \
+ \
+	  case BESSEL_H1: \
+	    result = besselh1 (alpha, x, scaled, ierr); \
+	    break; \
+ \
+	  case BESSEL_H2: \
+	    result = besselh2 (alpha, x, scaled, ierr); \
+	    break; \
+ \
+	  default: \
+	    break; \
+        } \
+    } \
+  while (0)
+
+static void
+gripe_bessel_arg (const char *fn, const char *arg)
+{
+  error ("%s: expecting scalar or matrix as %s argument", fn, arg);
+}
+
+octave_value_list
+do_bessel (enum bessel_type type, const char *fn,
+	   const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 || nargin == 3)
+    {
+      bool scaled = (nargin == 3);
+
+      octave_value alpha_arg = args(0);
+      octave_value x_arg = args(1);
+
+      if (alpha_arg.is_single_type () || x_arg.is_single_type ())
+	{
+	  if (alpha_arg.is_scalar_type ())
+	    {
+	      float alpha = args(0).float_value ();
+
+	      if (! error_state)
+		{
+		  if (x_arg.is_scalar_type ())
+		    {
+		      FloatComplex x = x_arg.float_complex_value ();
+
+		      if (! error_state)
+			{
+			  octave_idx_type ierr;
+			  octave_value result;
+
+			  DO_BESSEL (type, alpha, x, scaled, ierr, result);
+
+			  if (nargout > 1)
+			    retval(1) = static_cast<float> (ierr);
+
+			  retval(0) = result;
+			}
+		      else
+			gripe_bessel_arg (fn, "second");
+		    }
+		  else
+		    {
+		      FloatComplexNDArray x = x_arg.float_complex_array_value ();
+
+		      if (! error_state)
+			{
+			  ArrayN<octave_idx_type> ierr;
+			  octave_value result;
+
+			  DO_BESSEL (type, alpha, x, scaled, ierr, result);
+
+			  if (nargout > 1)
+			    retval(1) = NDArray (ierr);
+
+			  retval(0) = result;
+			}
+		      else
+			gripe_bessel_arg (fn, "second");
+		    }
+		}
+	      else
+		gripe_bessel_arg (fn, "first");
+	    }
+	  else
+	    {
+	      dim_vector dv0 = args(0).dims ();
+	      dim_vector dv1 = args(1).dims ();
+
+	      bool args0_is_row_vector = (dv0 (1) == dv0.numel ());
+	      bool args1_is_col_vector = (dv1 (0) == dv1.numel ());
+
+	      if (args0_is_row_vector && args1_is_col_vector)
+		{
+		  FloatRowVector ralpha = args(0).float_row_vector_value ();
+
+		  if (! error_state)
+		    {
+		      FloatComplexColumnVector cx = 
+			x_arg.float_complex_column_vector_value ();
+
+		      if (! error_state)
+			{
+			  Array2<octave_idx_type> ierr;
+			  octave_value result;
+
+			  DO_BESSEL (type, ralpha, cx, scaled, ierr, result);
+
+			  if (nargout > 1)
+			    retval(1) = NDArray (ierr);
+
+			  retval(0) = result;
+			}
+		      else
+			gripe_bessel_arg (fn, "second");
+		    }
+		  else
+		    gripe_bessel_arg (fn, "first");
+		}
+	      else
+		{
+		  FloatNDArray alpha = args(0).float_array_value ();
+
+		  if (! error_state)
+		    {
+		      if (x_arg.is_scalar_type ())
+			{
+			  FloatComplex x = x_arg.float_complex_value ();
+
+			  if (! error_state)
+			    {
+			      ArrayN<octave_idx_type> ierr;
+			      octave_value result;
+
+			      DO_BESSEL (type, alpha, x, scaled, ierr, result);
+
+			      if (nargout > 1)
+				retval(1) = NDArray (ierr);
+
+			      retval(0) = result;
+			    }
+			  else
+			    gripe_bessel_arg (fn, "second");
+			}
+		      else
+			{
+			  FloatComplexNDArray x = x_arg.float_complex_array_value ();
+
+			  if (! error_state)
+			    {
+			      ArrayN<octave_idx_type> ierr;
+			      octave_value result;
+			  
+			      DO_BESSEL (type, alpha, x, scaled, ierr, result);
+			  
+			      if (nargout > 1)
+				retval(1) = NDArray (ierr);
+
+			      retval(0) = result;
+			    }
+			  else
+			    gripe_bessel_arg (fn, "second");
+			}
+		    }
+		  else
+		    gripe_bessel_arg (fn, "first");
+		}
+	    }
+	}
+      else
+	{
+	  if (alpha_arg.is_scalar_type ())
+	    {
+	      double alpha = args(0).double_value ();
+
+	      if (! error_state)
+		{
+		  if (x_arg.is_scalar_type ())
+		    {
+		      Complex x = x_arg.complex_value ();
+
+		      if (! error_state)
+			{
+			  octave_idx_type ierr;
+			  octave_value result;
+
+			  DO_BESSEL (type, alpha, x, scaled, ierr, result);
+
+			  if (nargout > 1)
+			    retval(1) = static_cast<double> (ierr);
+
+			  retval(0) = result;
+			}
+		      else
+			gripe_bessel_arg (fn, "second");
+		    }
+		  else
+		    {
+		      ComplexNDArray x = x_arg.complex_array_value ();
+
+		      if (! error_state)
+			{
+			  ArrayN<octave_idx_type> ierr;
+			  octave_value result;
+
+			  DO_BESSEL (type, alpha, x, scaled, ierr, result);
+
+			  if (nargout > 1)
+			    retval(1) = NDArray (ierr);
+
+			  retval(0) = result;
+			}
+		      else
+			gripe_bessel_arg (fn, "second");
+		    }
+		}
+	      else
+		gripe_bessel_arg (fn, "first");
+	    }
+	  else
+	    {
+	      dim_vector dv0 = args(0).dims ();
+	      dim_vector dv1 = args(1).dims ();
+
+	      bool args0_is_row_vector = (dv0 (1) == dv0.numel ());
+	      bool args1_is_col_vector = (dv1 (0) == dv1.numel ());
+
+	      if (args0_is_row_vector && args1_is_col_vector)
+		{
+		  RowVector ralpha = args(0).row_vector_value ();
+
+		  if (! error_state)
+		    {
+		      ComplexColumnVector cx = 
+			x_arg.complex_column_vector_value ();
+
+		      if (! error_state)
+			{
+			  Array2<octave_idx_type> ierr;
+			  octave_value result;
+
+			  DO_BESSEL (type, ralpha, cx, scaled, ierr, result);
+
+			  if (nargout > 1)
+			    retval(1) = NDArray (ierr);
+
+			  retval(0) = result;
+			}
+		      else
+			gripe_bessel_arg (fn, "second");
+		    }
+		  else
+		    gripe_bessel_arg (fn, "first");
+		}
+	      else
+		{
+		  NDArray alpha = args(0).array_value ();
+
+		  if (! error_state)
+		    {
+		      if (x_arg.is_scalar_type ())
+			{
+			  Complex x = x_arg.complex_value ();
+
+			  if (! error_state)
+			    {
+			      ArrayN<octave_idx_type> ierr;
+			      octave_value result;
+
+			      DO_BESSEL (type, alpha, x, scaled, ierr, result);
+
+			      if (nargout > 1)
+				retval(1) = NDArray (ierr);
+
+			      retval(0) = result;
+			    }
+			  else
+			    gripe_bessel_arg (fn, "second");
+			}
+		      else
+			{
+			  ComplexNDArray x = x_arg.complex_array_value ();
+
+			  if (! error_state)
+			    {
+			      ArrayN<octave_idx_type> ierr;
+			      octave_value result;
+			  
+			      DO_BESSEL (type, alpha, x, scaled, ierr, result);
+			  
+			      if (nargout > 1)
+				retval(1) = NDArray (ierr);
+
+			      retval(0) = result;
+			    }
+			  else
+			    gripe_bessel_arg (fn, "second");
+			}
+		    }
+		  else
+		    gripe_bessel_arg (fn, "first");
+		}
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (besselj, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{j}, @var{ierr}] =} besselj (@var{alpha}, @var{x}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})\n\
+Compute Bessel or Hankel functions of various kinds:\n\
+\n\
+ at table @code\n\
+ at item besselj\n\
+Bessel functions of the first kind.  If the argument @var{opt} is supplied, \n\
+the result is multiplied by @code{exp(-abs(imag(x)))}.\n\
+ at item bessely\n\
+Bessel functions of the second kind.  If the argument @var{opt} is supplied,\n\
+the result is multiplied by @code{exp(-abs(imag(x)))}.\n\
+ at item besseli\n\
+Modified Bessel functions of the first kind.  If the argument @var{opt} is supplied,\n\
+the result is multiplied by @code{exp(-abs(real(x)))}.\n\
+ at item besselk\n\
+Modified Bessel functions of the second kind.  If the argument @var{opt} is supplied,\n\
+the result is multiplied by @code{exp(x)}.\n\
+ at item besselh\n\
+Compute Hankel functions of the first (@var{k} = 1) or second (@var{k}\n\
+= 2) kind.  If the argument @var{opt} is supplied, the result is multiplied by\n\
+ at code{exp (-I*@var{x})} for @var{k} = 1 or @code{exp (I*@var{x})} for\n\
+ at var{k} = 2.\n\
+ at end table\n\
+\n\
+If @var{alpha} is a scalar, the result is the same size as @var{x}.\n\
+If @var{x} is a scalar, the result is the same size as @var{alpha}.\n\
+If @var{alpha} is a row vector and @var{x} is a column vector, the\n\
+result is a matrix with @code{length (@var{x})} rows and\n\
+ at code{length (@var{alpha})} columns.  Otherwise, @var{alpha} and\n\
+ at var{x} must conform and the result will be the same size.\n\
+\n\
+The value of @var{alpha} must be real.  The value of @var{x} may be\n\
+complex.\n\
+\n\
+If requested, @var{ierr} contains the following status information\n\
+and is the same size as the result.\n\
+\n\
+ at enumerate 0\n\
+ at item\n\
+Normal return.\n\
+ at item\n\
+Input error, return @code{NaN}.\n\
+ at item\n\
+Overflow, return @code{Inf}.\n\
+ at item\n\
+Loss of significance by argument reduction results in less than\n\
+half of machine accuracy.\n\
+ at item\n\
+Complete loss of significance by argument reduction, return @code{NaN}.\n\
+ at item\n\
+Error---no computation, algorithm termination condition not met,\n\
+return @code{NaN}.\n\
+ at end enumerate\n\
+ at end deftypefn")
+{
+  return do_bessel (BESSEL_J, "besselj", args, nargout);
+}
+
+DEFUN_DLD (bessely, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})\n\
+See besselj.\n\
+ at end deftypefn")
+{
+  return do_bessel (BESSEL_Y, "bessely", args, nargout);
+}
+
+DEFUN_DLD (besseli, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})\n\
+See besselj.\n\
+ at end deftypefn")
+{
+  return do_bessel (BESSEL_I, "besseli", args, nargout);
+}
+
+DEFUN_DLD (besselk, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})\n\
+See besselj.\n\
+ at end deftypefn")
+{
+  return do_bessel (BESSEL_K, "besselk", args, nargout);
+}
+
+DEFUN_DLD (besselh, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})\n\
+See besselj.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      retval = do_bessel (BESSEL_H1, "besselh", args, nargout);
+    }
+  else if (nargin == 3 || nargin == 4)
+    {
+      octave_idx_type kind = args(1).int_value ();
+
+      if (! error_state)
+	{
+	  octave_value_list tmp_args;
+
+	  if (nargin == 4)
+	    tmp_args(2) = args(3);
+
+	  tmp_args(1) = args(2);
+	  tmp_args(0) = args(0);
+
+	  if (kind == 1)
+	    retval = do_bessel (BESSEL_H1, "besselh", tmp_args, nargout);
+	  else if (kind == 2)
+	    retval = do_bessel (BESSEL_H2, "besselh", tmp_args, nargout);
+	  else
+	    error ("besselh: expecting K = 1 or 2");
+	}
+      else
+	error ("besselh: invalid value of K");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (airy, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{a}, @var{ierr}] =} airy (@var{k}, @var{z}, @var{opt})\n\
+Compute Airy functions of the first and second kind, and their\n\
+derivatives.\n\
+\n\
+ at example\n\
+ at group\n\
+ K   Function   Scale factor (if 'opt' is supplied)\n\
+---  --------   ---------------------------------------\n\
+ 0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))\n\
+ 1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))\n\
+ 2   Bi (Z)     exp (-abs (real ((2/3) * Z *sqrt (Z))))\n\
+ 3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z *sqrt (Z))))\n\
+ at end group\n\
+ at end example\n\
+\n\
+The function call @code{airy (@var{z})} is equivalent to\n\
+ at code{airy (0, @var{z})}.\n\
+\n\
+The result is the same size as @var{z}.\n\
+\n\
+If requested, @var{ierr} contains the following status information and\n\
+is the same size as the result.\n\
+\n\
+ at enumerate 0\n\
+ at item\n\
+Normal return.\n\
+ at item\n\
+Input error, return @code{NaN}.\n\
+ at item\n\
+Overflow, return @code{Inf}.\n\
+ at item\n\
+Loss of significance by argument reduction results in less than half\n\
+ of machine accuracy.\n\
+ at item\n\
+Complete loss of significance by argument reduction, return @code{NaN}.\n\
+ at item\n\
+Error---no computation, algorithm termination condition not met,\n\
+return @code{NaN}.\n\
+ at end enumerate\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0 && nargin < 4)
+    {
+      bool scale = (nargin == 3);
+
+      int kind = 0;
+
+      if (nargin > 1)
+	{
+	  kind = args(0).int_value ();
+
+	  if (! error_state)
+	    {
+	      if (kind < 0 || kind > 3)
+		error ("airy: expecting K = 0, 1, 2, or 3");
+	    }	      
+	  else
+	    error ("airy: expecting integer value for K");
+	}
+
+      if (! error_state)
+	{
+	  int idx = nargin == 1 ? 0 : 1;
+
+	  if (args (idx).is_single_type ())
+	    {
+	      FloatComplexNDArray z = args(idx).float_complex_array_value ();
+
+	      if (! error_state)
+		{
+		  ArrayN<octave_idx_type> ierr;
+		  octave_value result;
+
+		  if (kind > 1)
+		    result = biry (z, kind == 3, scale, ierr);
+		  else
+		    result = airy (z, kind == 1, scale, ierr);
+
+		  if (nargout > 1)
+		    retval(1) = NDArray (ierr);
+
+		  retval(0) = result;
+		}
+	      else
+		error ("airy: expecting complex matrix for Z");
+	    }
+	  else
+	    {
+	      ComplexNDArray z = args(idx).complex_array_value ();
+
+	      if (! error_state)
+		{
+		  ArrayN<octave_idx_type> ierr;
+		  octave_value result;
+
+		  if (kind > 1)
+		    result = biry (z, kind == 3, scale, ierr);
+		  else
+		    result = airy (z, kind == 1, scale, ierr);
+
+		  if (nargout > 1)
+		    retval(1) = NDArray (ierr);
+
+		  retval(0) = result;
+		}
+	      else
+		error ("airy: expecting complex matrix for Z");
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%! # Test values computed with GP/PARI version 2.3.3
+%!
+%!shared alpha, x, jx, yx, ix, kx, nix
+%!
+%! # Bessel functions, even order, positive and negative x
+%! alpha = 2; x = 1.25;
+%! jx = 0.1710911312405234823613091417;
+%! yx = -1.193199310178553861283790424;
+%! ix = 0.2220184483766341752692212604;
+%! kx = 0.9410016167388185767085460540;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%!assert(besselj(-alpha,x), jx, 100*eps) 
+%!assert(bessely(-alpha,x), yx, 100*eps)
+%!assert(besseli(-alpha,x), ix, 100*eps)
+%!assert(besselk(-alpha,x), kx, 100*eps) 
+%!assert(besselh(-alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(-alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(-alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(-alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(-alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(-alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(-alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(-alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! x *= -1;
+%! yx = -1.193199310178553861283790424 + 0.3421822624810469647226182835*I;
+%! kx = 0.9410016167388185767085460540 - 0.6974915263814386815610060884*I;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! # Bessel functions, odd order, positive and negative x
+%! alpha = 3; x = 2.5;
+%! jx = 0.2166003910391135247666890035;
+%! yx = -0.7560554967536709968379029772;
+%! ix = 0.4743704087780355895548240179;
+%! kx = 0.2682271463934492027663765197;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%!assert(besselj(-alpha,x), -jx, 100*eps) 
+%!assert(bessely(-alpha,x), -yx, 100*eps)
+%!assert(besseli(-alpha,x), ix, 100*eps)
+%!assert(besselk(-alpha,x), kx, 100*eps) 
+%!assert(besselh(-alpha,1,x), -(jx + I*yx), 100*eps)
+%!assert(besselh(-alpha,2,x), -(jx - I*yx), 100*eps)
+%!
+%!assert(besselj(-alpha,x,1), -jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(-alpha,x,1), -yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(-alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(-alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(-alpha,1,x,1), -(jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(-alpha,2,x,1), -(jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! x *= -1;
+%! jx = -jx;
+%! yx = 0.7560554967536709968379029772 - 0.4332007820782270495333780070*I;
+%! ix = -ix;
+%! kx = -0.2682271463934492027663765197 - 1.490278591297463775542004240*I;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! # Bessel functions, fractional order, positive and negative x
+%!
+%! alpha = 3.5; x = 2.75;
+%! jx = 0.1691636439842384154644784389;
+%! yx = -0.8301381935499356070267953387;
+%! ix = 0.3930540878794826310979363668;
+%! kx = 0.2844099013460621170288192503;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! nix = 0.2119931212254662995364461998;
+%!
+%!assert(besselj(-alpha,x), yx, 100*eps) 
+%!assert(bessely(-alpha,x), -jx, 100*eps)
+%!assert(besseli(-alpha,x), nix, 100*eps)
+%!assert(besselk(-alpha,x), kx, 100*eps) 
+%!assert(besselh(-alpha,1,x), -I*(jx + I*yx), 100*eps)
+%!assert(besselh(-alpha,2,x), I*(jx - I*yx), 100*eps)
+%!
+%!assert(besselj(-alpha,x,1), yx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(-alpha,x,1), -jx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(-alpha,x,1), nix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(-alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(-alpha,1,x,1), -I*(jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(-alpha,2,x,1), I*(jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! x *= -1;
+%! jx *= -I;
+%! yx = -0.8301381935499356070267953387*I;
+%! ix *= -I;
+%! kx = -0.9504059335995575096509874508*I;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! # Bessel functions, even order, complex x
+%!
+%! alpha = 2; x = 1.25 + 3.625 * I;
+%! jx = -1.299533366810794494030065917 + 4.370833116012278943267479589*I;
+%! yx = -4.370357232383223896393056727 - 1.283083391453582032688834041*I;
+%! ix = -0.6717801680341515541002273932 - 0.2314623443930774099910228553*I;
+%! kx = -0.01108009888623253515463783379 + 0.2245218229358191588208084197*I;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%!assert(besselj(-alpha,x), jx, 100*eps) 
+%!assert(bessely(-alpha,x), yx, 100*eps)
+%!assert(besseli(-alpha,x), ix, 100*eps)
+%!assert(besselk(-alpha,x), kx, 100*eps) 
+%!assert(besselh(-alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(-alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(-alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(-alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(-alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(-alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(-alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(-alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! # Bessel functions, odd order, complex x
+%!
+%! alpha = 3; x = 2.5 + 1.875 * I;
+%! jx = 0.1330721523048277493333458596 + 0.5386295217249660078754395597*I;
+%! yx = -0.6485072392105829901122401551 + 0.2608129289785456797046996987*I;
+%! ix = -0.6182064685486998097516365709 + 0.4677561094683470065767989920*I;
+%! kx = -0.1568585587733540007867882337 - 0.05185853709490846050505141321*I;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%!assert(besselj(-alpha,x), -jx, 100*eps) 
+%!assert(bessely(-alpha,x), -yx, 100*eps)
+%!assert(besseli(-alpha,x), ix, 100*eps)
+%!assert(besselk(-alpha,x), kx, 100*eps) 
+%!assert(besselh(-alpha,1,x), -(jx + I*yx), 100*eps)
+%!assert(besselh(-alpha,2,x), -(jx - I*yx), 100*eps)
+%!
+%!assert(besselj(-alpha,x,1), -jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(-alpha,x,1), -yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(-alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(-alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(-alpha,1,x,1), -(jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(-alpha,2,x,1), -(jx - I*yx)*exp(I*x), 100*eps)
+%!
+%! # Bessel functions, fractional order, complex x
+%!
+%! alpha = 3.5; x = 1.75 + 4.125 * I;
+%! jx = -3.018566131370455929707009100 - 0.7585648436793900607704057611*I;
+%! yx = 0.7772278839106298215614791107 - 3.018518722313849782683792010*I;
+%! ix = 0.2100873577220057189038160913 - 0.6551765604618246531254970926*I;
+%! kx = 0.1757147290513239935341488069 + 0.08772348296883849205562558311*I;
+%!
+%!assert(besselj(alpha,x), jx, 100*eps) 
+%!assert(bessely(alpha,x), yx, 100*eps)
+%!assert(besseli(alpha,x), ix, 100*eps)
+%!assert(besselk(alpha,x), kx, 100*eps) 
+%!assert(besselh(alpha,1,x), jx + I*yx, 100*eps)
+%!assert(besselh(alpha,2,x), jx - I*yx, 100*eps)
+%!
+%!assert(besselj(alpha,x,1), jx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(alpha,x,1), yx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(alpha,x,1), ix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
+%!
+%!  nix = 0.09822388691172060573913739253 - 0.7110230642207380127317227407*I;
+%!
+%!assert(besselj(-alpha,x), yx, 100*eps) 
+%!assert(bessely(-alpha,x), -jx, 100*eps)
+%!assert(besseli(-alpha,x), nix, 100*eps)
+%!assert(besselk(-alpha,x), kx, 100*eps) 
+%!assert(besselh(-alpha,1,x), -I*(jx + I*yx), 100*eps)
+%!assert(besselh(-alpha,2,x), I*(jx - I*yx), 100*eps)
+%!
+%!assert(besselj(-alpha,x,1), yx*exp(-abs(imag(x))), 100*eps) 
+%!assert(bessely(-alpha,x,1), -jx*exp(-abs(imag(x))), 100*eps)
+%!assert(besseli(-alpha,x,1), nix*exp(-abs(real(x))), 100*eps)
+%!assert(besselk(-alpha,x,1), kx*exp(x), 100*eps) 
+%!assert(besselh(-alpha,1,x,1), -I*(jx + I*yx)*exp(-I*x), 100*eps)
+%!assert(besselh(-alpha,2,x,1), I*(jx - I*yx)*exp(I*x), 100*eps)
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/betainc.cc b/src/DLD-FUNCTIONS/betainc.cc
new file mode 100644
index 0000000..0fbb194
--- /dev/null
+++ b/src/DLD-FUNCTIONS/betainc.cc
@@ -0,0 +1,339 @@
+/*
+
+Copyright (C) 1997, 1999, 2000, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-specfun.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (betainc, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} betainc (@var{x}, @var{a}, @var{b})\n\
+Return the incomplete Beta function,\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+ \\beta (x, a, b) = B (a, b)^{-1} \\int_0^x t^{(a-z)} (1-t)^{(b-1)} dt.\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at c Set example in small font to prevent overfull line\n\
+ at smallexample\n\
+                                      x\n\
+                                     /\n\
+betainc (x, a, b) = beta (a, b)^(-1) | t^(a-1) (1-t)^(b-1) dt.\n\
+                                     /\n\
+                                  t=0\n\
+ at end smallexample\n\
+ at end ifnottex\n\
+\n\
+If x has more than one component, both @var{a} and @var{b} must be\n\
+scalars.  If @var{x} is a scalar, @var{a} and @var{b} must be of\n\
+compatible dimensions.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 3)
+    {
+      octave_value x_arg = args(0);
+      octave_value a_arg = args(1);
+      octave_value b_arg = args(2);
+
+      // FIXME Can we make a template version of the duplicated code below
+      if (x_arg.is_single_type () || a_arg.is_single_type () ||
+	  b_arg.is_single_type ())
+	{
+	  if (x_arg.is_scalar_type ())
+	    {
+	      float x = x_arg.float_value ();
+
+	      if (a_arg.is_scalar_type ())
+		{
+		  float a = a_arg.float_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  float b = b_arg.float_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  FloatNDArray b = b_arg.float_array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	      else
+		{
+		  FloatNDArray a = a_arg.float_array_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  float b = b_arg.float_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  FloatNDArray b = b_arg.float_array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      FloatNDArray x = x_arg.float_array_value ();
+
+	      if (a_arg.is_scalar_type ())
+		{
+		  float a = a_arg.float_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  float b = b_arg.float_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  FloatNDArray b = b_arg.float_array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	      else
+		{
+		  FloatNDArray a = a_arg.float_array_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  float b = b_arg.float_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  FloatNDArray b = b_arg.float_array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  if (x_arg.is_scalar_type ())
+	    {
+	      double x = x_arg.double_value ();
+
+	      if (a_arg.is_scalar_type ())
+		{
+		  double a = a_arg.double_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  double b = b_arg.double_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  NDArray b = b_arg.array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	      else
+		{
+		  NDArray a = a_arg.array_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  double b = b_arg.double_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  NDArray b = b_arg.array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      NDArray x = x_arg.array_value ();
+
+	      if (a_arg.is_scalar_type ())
+		{
+		  double a = a_arg.double_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  double b = b_arg.double_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  NDArray b = b_arg.array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	      else
+		{
+		  NDArray a = a_arg.array_value ();
+
+		  if (! error_state)
+		    {
+		      if (b_arg.is_scalar_type ())
+			{
+			  double b = b_arg.double_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		      else
+			{
+			  NDArray b = b_arg.array_value ();
+
+			  if (! error_state)
+			    retval = betainc (x, a, b);
+			}
+		    }
+		}
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%% test/octave.test/arith/betainc-1.m
+%!test
+%! a=[1, 1.5, 2, 3];
+%! b=[4, 3, 2, 1];
+%! v1=betainc(1,a,b);
+%! v2=[1,1,1,1];
+%! x = [.2, .4, .6, .8];
+%! v3=betainc(x, a, b);
+%! v4 = 1-betainc(1.-x, b, a);
+%! assert(v1, v2, sqrt(eps));
+%! assert(v3, v4, sqrt(eps));
+
+%% Single precision
+%!test
+%! a=single ([1, 1.5, 2, 3]);
+%! b=single ([4, 3, 2, 1]);
+%! v1=betainc(1,a,b);
+%! v2=single ([1,1,1,1]);
+%! x = single ([.2, .4, .6, .8]);
+%! v3=betainc(x, a, b);
+%! v4 = 1-betainc(1.-x, b, a);
+%! assert(v1, v2, sqrt(eps ('single')));
+%! assert(v3, v4, sqrt(eps ('single')));
+
+%% Mixed double/single precision
+%!test
+%! a=single ([1, 1.5, 2, 3]);
+%! b=[4, 3, 2, 1];
+%! v1=betainc(1,a,b);
+%! v2=single ([1,1,1,1]);
+%! x = [.2, .4, .6, .8];
+%! v3=betainc(x, a, b);
+%! v4 = 1-betainc(1.-x, b, a);
+%! assert(v1, v2, sqrt(eps ('single')));
+%! assert(v3, v4, sqrt(eps ('single')));
+
+%% test/octave.test/arith/betainc-2.m
+%!error <Invalid call to betainc.*> betainc();
+
+%% test/octave.test/arith/betainc-3.m
+%!error <Invalid call to betainc.*> betainc(1);
+
+%% test/octave.test/arith/betainc-4.m
+%!error <Invalid call to betainc.*> betainc(1,2);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/DLD-FUNCTIONS/bsxfun.cc b/src/DLD-FUNCTIONS/bsxfun.cc
new file mode 100644
index 0000000..732146b
--- /dev/null
+++ b/src/DLD-FUNCTIONS/bsxfun.cc
@@ -0,0 +1,557 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+#include <list>
+
+#include "lo-mappers.h"
+
+#include "oct-map.h"
+#include "defun-dld.h"
+#include "parse.h"
+#include "variables.h"
+#include "ov-colon.h"
+#include "unwind-prot.h"
+
+static bool
+maybe_update_column (octave_value& Ac, const octave_value& A, 
+		     const dim_vector& dva, const dim_vector& dvc,
+		     octave_idx_type i, octave_value_list &idx)
+{
+  octave_idx_type nd = dva.length ();
+
+  if (i == 0)
+    {
+      idx(0) = octave_value (':');
+      for (octave_idx_type j = 1; j < nd; j++)
+	{
+	  if (dva (j) == 1)
+	    idx (j) = octave_value (1);
+	  else
+	    idx (j) = octave_value ((i % dvc(j)) + 1);
+
+	  i = i / dvc (j);
+	}
+
+      Ac = A;
+      Ac = Ac.single_subsref ("(", idx);
+      return true;
+    }
+  else
+    {
+      bool is_changed = false;
+      octave_idx_type k = i;
+      octave_idx_type k1 = i - 1;
+      for (octave_idx_type j = 1; j < nd; j++)
+	{
+	  if (dva(j) != 1 && k % dvc (j) != k1 % dvc (j))
+	    {
+	      idx (j) = octave_value ((k % dvc(j)) + 1);
+	      is_changed = true;
+	    }
+
+	  k = k / dvc (j);
+	  k1 = k1 / dvc (j);
+	}
+
+      if (is_changed)
+	{
+	  Ac = A;
+	  Ac = Ac.single_subsref ("(", idx);
+	  return true;
+	}
+      else
+	return false;
+    }
+}
+
+#if 0
+// FIXME -- this function is not used; is it OK to delete it?
+static void
+update_index (octave_value_list& idx, const dim_vector& dv, octave_idx_type i)
+{
+  octave_idx_type nd = dv.length ();
+
+  if (i == 0)
+    {
+      for (octave_idx_type j = nd - 1; j > 0; j--)
+	idx(j) = octave_value (static_cast<double>(1));
+      idx(0) = octave_value (':');
+    }
+  else
+    {
+      for (octave_idx_type j = 1; j < nd; j++)
+	{
+	  idx (j) = octave_value (i % dv (j) + 1);
+	  i = i / dv (j);
+	}
+    }
+}
+#endif
+
+static void
+update_index (Array<int>& idx, const dim_vector& dv, octave_idx_type i)
+{
+  octave_idx_type nd = dv.length ();
+
+  idx(0) = 0;
+  for (octave_idx_type j = 1; j < nd; j++)
+    {
+      idx (j) = i % dv (j);
+      i = i / dv (j);
+    }
+}
+
+DEFUN_DLD (bsxfun, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} bsxfun (@var{f}, @var{a}, @var{b})\n\
+Applies a binary function @var{f} element-wise to two matrix arguments\n\
+ at var{a} and @var{b}.  The function @var{f} must be capable of accepting\n\
+two column vector arguments of equal length, or one column vector\n\
+argument and a scalar.\n\
+\n\
+The dimensions of @var{a} and @var{b} must be equal or singleton.  The\n\
+singleton dimensions of the matrices will be expanded to the same\n\
+dimensionality as the other matrix.\n\
+\n\
+ at seealso{arrayfun, cellfun}\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 3)
+    print_usage ();
+  else
+    {
+      octave_function *func = 0;
+      std::string name;
+      std::string fcn_name;
+
+      if (args(0).is_function_handle () || args(0).is_inline_function ())
+	func = args(0).function_value ();
+      else if (args(0).is_string ())
+	{
+	  name = args(0).string_value ();
+	  fcn_name = unique_symbol_name ("__bsxfun_fcn_");
+	  std::string fname = "function y = ";
+	  fname.append (fcn_name);
+	  fname.append ("(x) y = ");
+	  func = extract_function (args(0), "bsxfun", fcn_name, fname,
+				   "; endfunction");
+	}
+      else
+	  error ("bsxfun: first argument must be a string or function handle");
+
+      if (! error_state)
+	{
+	  const octave_value A = args (1);
+	  dim_vector dva = A.dims ();
+	  octave_idx_type nda = dva.length ();
+	  const octave_value B = args (2);
+	  dim_vector dvb = B.dims ();
+	  octave_idx_type ndb = dvb.length ();
+	  octave_idx_type nd = nda;
+      
+	  if (nda > ndb)
+	      dvb.resize (nda, 1);
+	  else if (nda < ndb)
+	    {
+	      dva.resize (ndb, 1);
+	      nd = ndb;
+	    }
+
+	  for (octave_idx_type i = 0; i < nd; i++)
+	    if (dva (i) != dvb (i) && dva (i) != 1 && dvb (i) != 1)
+	      {
+		error ("bsxfun: dimensions don't match");
+		break;
+	      }
+
+	  if (!error_state)
+	    {
+	      // Find the size of the output
+	      dim_vector dvc;
+	      dvc.resize (nd);
+	  
+	      for (octave_idx_type i = 0; i < nd; i++)
+		dvc (i) = (dva (i) < 1  ? dva (i) : (dvb (i) < 1 ? dvb (i) :
+		      (dva (i) > dvb (i) ? dva (i) : dvb (i))));
+
+	      if (dva == dvb || dva.numel () == 1 || dvb.numel () == 1)
+		{
+		  octave_value_list inputs;
+		  inputs (0) = A;
+		  inputs (1) = B;
+		  retval = feval (func, inputs, 1);
+		}
+	      else if (dvc.numel () < 1)
+		{
+		  octave_value_list inputs;
+		  inputs (0) = A.resize (dvc);
+		  inputs (1) = B.resize (dvc);
+		  retval = feval (func, inputs, 1);	      
+		}
+	      else
+		{
+		  octave_idx_type ncount = 1;
+		  for (octave_idx_type i = 1; i < nd; i++)
+		    ncount *= dvc (i);
+
+#define BSXDEF(T) \
+		  T result_ ## T; \
+		  bool have_ ## T = false;
+
+		  BSXDEF(NDArray);
+		  BSXDEF(ComplexNDArray);
+		  BSXDEF(FloatNDArray);
+		  BSXDEF(FloatComplexNDArray);
+		  BSXDEF(boolNDArray);
+		  BSXDEF(int8NDArray);
+		  BSXDEF(int16NDArray);
+		  BSXDEF(int32NDArray);
+		  BSXDEF(int64NDArray);
+		  BSXDEF(uint8NDArray);
+		  BSXDEF(uint16NDArray);
+		  BSXDEF(uint32NDArray);
+		  BSXDEF(uint64NDArray);
+
+		  octave_value Ac ;
+		  octave_value_list idxA;
+		  octave_value Bc;
+		  octave_value_list idxB;
+		  octave_value C;
+		  octave_value_list inputs;
+		  Array<int> ra_idx (dvc.length(), 0);
+
+
+		  for (octave_idx_type i = 0; i < ncount; i++)
+		    {
+		      if (maybe_update_column (Ac, A, dva, dvc, i, idxA))
+			inputs (0) = Ac;
+
+		      if (maybe_update_column (Bc, B, dvb, dvc, i, idxB))
+			inputs (1) = Bc;
+			
+		      octave_value_list tmp = feval (func, inputs, 1);
+
+		      if (error_state)
+			break;
+
+#define BSXINIT(T, CLS, EXTRACTOR) \
+ 		      (result_type == CLS) \
+			{ \
+			    have_ ## T = true; \
+			    result_ ## T = \
+				tmp (0). EXTRACTOR ## _array_value (); \
+			    result_ ## T .resize (dvc); \
+                        }
+
+		      if (i == 0)
+			{
+			  if (! tmp(0).is_sparse_type ())
+			    {
+			      std::string result_type = tmp(0).class_name ();
+			      if (result_type == "double")
+				{
+				  if (tmp(0).is_real_type ())
+				    {
+				      have_NDArray = true;
+				      result_NDArray = tmp(0).array_value ();
+				      result_NDArray.resize (dvc);
+				    }
+				  else
+				    {
+				      have_ComplexNDArray = true;
+				      result_ComplexNDArray = 
+					tmp(0).complex_array_value ();
+				      result_ComplexNDArray.resize (dvc);
+				    }
+				}
+			      else if (result_type == "single")
+				{
+				  if (tmp(0).is_real_type ())
+				    {
+				      have_FloatNDArray = true;
+				      result_FloatNDArray = tmp(0).float_array_value ();
+				      result_FloatNDArray.resize (dvc);
+				    }
+				  else
+				    {
+				      have_ComplexNDArray = true;
+				      result_ComplexNDArray = 
+					tmp(0).complex_array_value ();
+				      result_ComplexNDArray.resize (dvc);
+				    }
+				}
+			      else if BSXINIT(boolNDArray, "logical", bool)
+			      else if BSXINIT(int8NDArray, "int8", int8)
+			      else if BSXINIT(int16NDArray, "int16", int16)
+			      else if BSXINIT(int32NDArray, "int32", int32)
+			      else if BSXINIT(int64NDArray, "int64", int64)
+			      else if BSXINIT(uint8NDArray, "uint8", uint8)
+			      else if BSXINIT(uint16NDArray, "uint16", uint16)
+			      else if BSXINIT(uint32NDArray, "uint32", uint32)
+			      else if BSXINIT(uint64NDArray, "uint64", uint64)
+			      else
+				{
+				  C = tmp (0);
+				  C = C.resize (dvc);
+				}
+			    }
+			}
+		      else
+			{
+			  update_index (ra_idx, dvc, i);
+			  
+			  if (have_FloatNDArray ||
+			      have_FloatComplexNDArray)
+			    {
+			      if (! tmp(0).is_float_type ())
+				{
+				  if (have_FloatNDArray)
+				    {
+				      have_FloatNDArray = false;
+				      C = result_FloatNDArray;
+				    }
+				  else
+				    {
+				      have_FloatComplexNDArray = false;
+				      C = result_FloatComplexNDArray;
+				    }
+				  C = do_cat_op (C, tmp(0), ra_idx);
+				}
+			      else if (tmp(0).is_double_type ())
+				{
+				  if (tmp(0).is_complex_type () && 
+				      have_FloatNDArray)
+				    {
+				      result_ComplexNDArray = 
+					ComplexNDArray (result_FloatNDArray);
+				      result_ComplexNDArray.insert 
+					(tmp(0).complex_array_value(), ra_idx);
+				      have_FloatComplexNDArray = false;
+				      have_ComplexNDArray = true;
+				    }
+				  else
+				    {
+				      result_NDArray = 
+					NDArray (result_FloatNDArray);
+				      result_NDArray.insert 
+					(tmp(0).array_value(), ra_idx);
+				      have_FloatNDArray = false;
+				      have_NDArray = true;
+				    }
+				}
+			      else if (tmp(0).is_real_type ())
+				result_FloatNDArray.insert 
+				  (tmp(0).float_array_value(), ra_idx);
+			      else
+				{
+				  result_FloatComplexNDArray = 
+				    FloatComplexNDArray (result_FloatNDArray);
+				  result_FloatComplexNDArray.insert 
+				    (tmp(0).float_complex_array_value(), ra_idx);
+				  have_FloatNDArray = false;
+				  have_FloatComplexNDArray = true;
+				}
+			    }
+			  else if (have_NDArray)
+			    {
+			      if (! tmp(0).is_float_type ())
+				{
+				  have_NDArray = false;
+				  C = result_NDArray;
+				  C = do_cat_op (C, tmp(0), ra_idx);
+				}
+			      else if (tmp(0).is_real_type ())
+				result_NDArray.insert (tmp(0).array_value(), 
+						       ra_idx);
+			      else
+				{
+				  result_ComplexNDArray = 
+				    ComplexNDArray (result_NDArray);
+				  result_ComplexNDArray.insert 
+				    (tmp(0).complex_array_value(), ra_idx);
+				  have_NDArray = false;
+				  have_ComplexNDArray = true;
+				}
+			    }
+
+#define BSXLOOP(T, CLS, EXTRACTOR) \
+			(have_ ## T) \
+			  { \
+			    if (tmp (0).class_name () != CLS) \
+			      { \
+				have_ ## T = false; \
+				C = result_ ## T; \
+				C = do_cat_op (C, tmp (0), ra_idx); \
+			      } \
+			    else \
+			      result_ ## T .insert \
+				(tmp(0). EXTRACTOR ## _array_value (), \
+				ra_idx); \
+			  }
+
+			  else if BSXLOOP(ComplexNDArray, "double", complex)
+			  else if BSXLOOP(boolNDArray, "logical", bool)
+			  else if BSXLOOP(int8NDArray, "int8", int8)
+			  else if BSXLOOP(int16NDArray, "int16", int16)
+			  else if BSXLOOP(int32NDArray, "int32", int32)
+			  else if BSXLOOP(int64NDArray, "int64", int64)
+			  else if BSXLOOP(uint8NDArray, "uint8", uint8)
+			  else if BSXLOOP(uint16NDArray, "uint16", uint16)
+			  else if BSXLOOP(uint32NDArray, "uint32", uint32)
+			  else if BSXLOOP(uint64NDArray, "uint64", uint64)
+			  else
+			    C = do_cat_op (C, tmp(0), ra_idx);
+			}
+		    }
+
+#define BSXEND(T) \
+		  (have_ ## T) \
+		    retval (0) = result_ ## T;
+
+		  if BSXEND(NDArray)
+		  else if BSXEND(ComplexNDArray)
+		  else if BSXEND(FloatNDArray)
+		  else if BSXEND(FloatComplexNDArray)
+		  else if BSXEND(boolNDArray)
+		  else if BSXEND(int8NDArray)
+		  else if BSXEND(int16NDArray)
+		  else if BSXEND(int32NDArray)
+		  else if BSXEND(int64NDArray)
+		  else if BSXEND(uint8NDArray)
+		  else if BSXEND(uint16NDArray)
+		  else if BSXEND(uint32NDArray)
+		  else if BSXEND(uint64NDArray)
+		  else
+		    retval(0) = C;
+		}
+	    }
+	}
+
+      if (! fcn_name.empty ())
+	clear_function (fcn_name);
+    }	
+
+  return retval;
+}
+
+/*
+
+%!shared a, b, c, f
+%! a = randn (4, 4);
+%! b = mean (a, 1);
+%! c = mean (a, 2);
+%! f = @minus;
+%!error(bsxfun (f));
+%!error(bsxfun (f, a));
+%!error(bsxfun (a, b));
+%!error(bsxfun (a, b, c));
+%!error(bsxfun (f, a, b, c));
+%!error(bsxfun (f, ones(4, 0), ones(4, 4)))
+%!assert(bsxfun (f, ones(4, 0), ones(4, 1)), zeros(4, 0));
+%!assert(bsxfun (f, ones(1, 4), ones(4, 1)), zeros(4, 4));
+%!assert(bsxfun (f, a, b), a - repmat(b, 4, 1));
+%!assert(bsxfun (f, a, c), a - repmat(c, 1, 4));
+%!assert(bsxfun ("minus", ones(1, 4), ones(4, 1)), zeros(4, 4));
+
+%!shared a, b, c, f
+%! a = randn (4, 4);
+%! a(1) *= 1i;
+%! b = mean (a, 1);
+%! c = mean (a, 2);
+%! f = @minus;
+%!error(bsxfun (f));
+%!error(bsxfun (f, a));
+%!error(bsxfun (a, b));
+%!error(bsxfun (a, b, c));
+%!error(bsxfun (f, a, b, c));
+%!error(bsxfun (f, ones(4, 0), ones(4, 4)))
+%!assert(bsxfun (f, ones(4, 0), ones(4, 1)), zeros(4, 0));
+%!assert(bsxfun (f, ones(1, 4), ones(4, 1)), zeros(4, 4));
+%!assert(bsxfun (f, a, b), a - repmat(b, 4, 1));
+%!assert(bsxfun (f, a, c), a - repmat(c, 1, 4));
+%!assert(bsxfun ("minus", ones(1, 4), ones(4, 1)), zeros(4, 4));
+
+%!shared a, b, c, f
+%! a = randn (4, 4);
+%! a(end) *= 1i;
+%! b = mean (a, 1);
+%! c = mean (a, 2);
+%! f = @minus;
+%!error(bsxfun (f));
+%!error(bsxfun (f, a));
+%!error(bsxfun (a, b));
+%!error(bsxfun (a, b, c));
+%!error(bsxfun (f, a, b, c));
+%!error(bsxfun (f, ones(4, 0), ones(4, 4)))
+%!assert(bsxfun (f, ones(4, 0), ones(4, 1)), zeros(4, 0));
+%!assert(bsxfun (f, ones(1, 4), ones(4, 1)), zeros(4, 4));
+%!assert(bsxfun (f, a, b), a - repmat(b, 4, 1));
+%!assert(bsxfun (f, a, c), a - repmat(c, 1, 4));
+%!assert(bsxfun ("minus", ones(1, 4), ones(4, 1)), zeros(4, 4));
+
+%!shared a, b, c, f
+%! a = randn (4, 4);
+%! b = a (1, :);
+%! c = a (:, 1);
+%! f = @(x, y) x == y;
+%!error(bsxfun (f));
+%!error(bsxfun (f, a));
+%!error(bsxfun (a, b));
+%!error(bsxfun (a, b, c));
+%!error(bsxfun (f, a, b, c));
+%!error(bsxfun (f, ones(4, 0), ones(4, 4)))
+%!assert(bsxfun (f, ones(4, 0), ones(4, 1)), zeros(4, 0, "logical"));
+%!assert(bsxfun (f, ones(1, 4), ones(4, 1)), ones(4, 4, "logical"));
+%!assert(bsxfun (f, a, b), a == repmat(b, 4, 1));
+%!assert(bsxfun (f, a, c), a == repmat(c, 1, 4));
+
+%!shared a, b, c, d, f
+%! a = randn (4, 4, 4);
+%! b = mean (a, 1);
+%! c = mean (a, 2);
+%! d = mean (a, 3);
+%! f = @minus;
+%!error(bsxfun (f, ones([4, 0, 4]), ones([4, 4, 4])));
+%!assert(bsxfun (f, ones([4, 0, 4]), ones([4, 1, 4])), zeros([4, 0, 4]));
+%!assert(bsxfun (f, ones([4, 4, 0]), ones([4, 1, 1])), zeros([4, 4, 0]));
+%!assert(bsxfun (f, ones([1, 4, 4]), ones([4, 1, 4])), zeros([4, 4, 4]));
+%!assert(bsxfun (f, ones([4, 4, 1]), ones([4, 1, 4])), zeros([4, 4, 4]));
+%!assert(bsxfun (f, ones([4, 1, 4]), ones([1, 4, 4])), zeros([4, 4, 4]));
+%!assert(bsxfun (f, ones([4, 1, 4]), ones([1, 4, 1])), zeros([4, 4, 4]));
+%!assert(bsxfun (f, a, b), a - repmat(b, [4, 1, 1]));
+%!assert(bsxfun (f, a, c), a - repmat(c, [1, 4, 1]));
+%!assert(bsxfun (f, a, d), a - repmat(d, [1, 1, 4]));
+%!assert(bsxfun ("minus", ones([4, 0, 4]), ones([4, 1, 4])), zeros([4, 0, 4]));
+
+%% The below is a very hard case to treat
+%!assert(bsxfun (f, ones([4, 1, 4, 1]), ones([1, 4, 1, 4])), zeros([4, 4, 4, 4]));
+
+*/
diff --git a/src/DLD-FUNCTIONS/ccolamd.cc b/src/DLD-FUNCTIONS/ccolamd.cc
new file mode 100644
index 0000000..7812135
--- /dev/null
+++ b/src/DLD-FUNCTIONS/ccolamd.cc
@@ -0,0 +1,588 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This is the octave interface to ccolamd, which bore the copyright given
+// in the help of the functions.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+#include <vector>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "pager.h"
+#include "ov-re-mat.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#include "oct-sparse.h"
+#include "oct-locbuf.h"
+
+#ifdef IDX_TYPE_LONG
+#define CCOLAMD_NAME(name) ccolamd_l ## name
+#define CSYMAMD_NAME(name) csymamd_l ## name
+#else
+#define CCOLAMD_NAME(name) ccolamd ## name
+#define CSYMAMD_NAME(name) csymamd ## name
+#endif
+
+DEFUN_DLD (ccolamd, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} ccolamd (@var{s})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{s}, @var{knobs})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{s}, @var{knobs}, @var{cmember})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} ccolamd (@dots{})\n\
+\n\
+Constrained column approximate minimum degree permutation.  @code{@var{p} =\n\
+ccolamd (@var{s})} returns the column approximate minimum degree permutation\n\
+vector for the sparse matrix @var{s}.  For a non-symmetric matrix @var{s},\n\
+ at code{@var{s} (:, @var{p})} tends to have sparser LU factors than @var{s}.\n\
+ at code{chol (@var{s} (:, @var{p})' * @var{s} (:, @var{p}))} also tends to be\n\
+sparser than @code{chol (@var{s}' * @var{s})}.  @code{@var{p} = ccolamd\n\
+(@var{s}, 1)} optimizes the ordering for @code{lu (@var{s} (:, @var{p}))}.\n\
+The ordering is followed by a column elimination tree post-ordering.\n\
+\n\
+ at var{knobs} is an optional one- to five-element input vector, with a default\n\
+value of @code{[0 10 10 1 0]} if not present or empty.  Entries not present\n\
+are set to their defaults.\n\
+\n\
+ at table @code\n\
+ at item @var{knobs}(1)\n\
+if nonzero, the ordering is optimized for @code{lu (S (:, p))}.  It will be a\n\
+poor ordering for @code{chol (@var{s} (:, @var{p})' * @var{s} (:,\n\
+ at var{p}))}.  This is the most important knob for ccolamd.\n\
+\n\
+ at item @var{knob}(2)\n\
+if @var{s} is m-by-n, rows with more than @code{max (16, @var{knobs} (2) *\n\
+sqrt (n))} entries are ignored.\n\
+\n\
+ at item @var{knob}(3)\n\
+columns with more than @code{max (16, @var{knobs} (3) * sqrt (min (@var{m},\n\
+ at var{n})))} entries are ignored and ordered last in the output permutation\n\
+(subject to the cmember constraints).\n\
+\n\
+ at item @var{knob}(4)\n\
+if nonzero, aggressive absorption is performed.\n\
+\n\
+ at item @var{knob}(5)\n\
+if nonzero, statistics and knobs are printed.\n\
+\n\
+ at end table\n\
+\n\
+ at var{cmember} is an optional vector of length n.  It defines the constraints\n\
+on the column ordering.  If @code{@var{cmember} (j) = @var{c}}, then column\n\
+ at var{j} is in constraint set @var{c} (@var{c} must be in the range 1 to\n\
+ at var{n}).  In the output permutation @var{p}, all columns in set 1 appear\n\
+first, followed by all columns in set 2, and so on.  @code{@var{cmember} =\n\
+ones(1,n)} if not present or empty.  @code{ccolamd (@var{s}, [], 1 :\n\
+ at var{n})} returns @code{1 : @var{n}}\n\
+\n\
+ at code{@var{p} = ccolamd (@var{s})} is about the same as @code{@var{p} =\n\
+colamd (@var{s})}.  @var{knobs} and its default values differ.  @code{colamd}\n\
+always does aggressive absorption, and it finds an ordering suitable for\n\
+both @code{lu (@var{s} (:, @var{p}))} and @code{chol (@var{S} (:, @var{p})'\n\
+* @var{s} (:, @var{p}))}; it cannot optimize its ordering for\n\
+ at code{lu (@var{s} (:, @var{p}))} to the extent that\n\
+ at code{ccolamd (@var{s}, 1)} can.\n\
+\n\
+ at var{stats} is an optional 20-element output vector that provides data\n\
+about the ordering and the validity of the input matrix @var{s}.  Ordering\n\
+statistics are in @code{@var{stats} (1 : 3)}.  @code{@var{stats} (1)} and\n\
+ at code{@var{stats} (2)} are the number of dense or empty rows and columns\n\
+ignored by CCOLAMD and @code{@var{stats} (3)} is the number of garbage\n\
+collections performed on the internal data structure used by CCOLAMD\n\
+(roughly of size @code{2.2 * nnz (@var{s}) + 4 * @var{m} + 7 * @var{n}}\n\
+integers).\n\
+\n\
+ at code{@var{stats} (4 : 7)} provide information if CCOLAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if\n\
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is\n\
+unsorted or contains duplicate entries, or zero if no such column exists.\n\
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row\n\
+index in the column index given by @code{@var{stats} (5)}, or zero if no\n\
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate\n\
+or out-of-order row indices.  @code{@var{stats} (8 : 20)} is always zero in\n\
+the current version of CCOLAMD (reserved for future use).\n\
+\n\
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\
+and a grant from Sandia National Lab.  See\n\
+ at url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\
+colamd, symamd, and other related orderings.\n\
+ at seealso{colamd, csymamd}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_CCOLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+ 
+  if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 3)
+    usage ("ccolamd: incorrect number of input and/or output arguments");
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS);      
+      CCOLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin > 1)
+	{
+	  NDArray User_knobs = args(1).array_value ();
+	  int nel_User_knobs = User_knobs.length ();
+
+	  if (nel_User_knobs > 0) 
+	    knobs [CCOLAMD_LU] = (User_knobs (0) != 0);
+	  if (nel_User_knobs > 1) 
+	    knobs [CCOLAMD_DENSE_ROW]  = User_knobs (1);
+	  if (nel_User_knobs > 2) 
+	    knobs [CCOLAMD_DENSE_COL]  = User_knobs (2);
+	  if (nel_User_knobs > 3) 
+	    knobs [CCOLAMD_AGGRESSIVE] = (User_knobs (3) != 0);
+	  if (nel_User_knobs > 4) 
+	    spumoni = (User_knobs (4) != 0);
+
+	  // print knob settings if spumoni is set
+	  if (spumoni)
+	    {
+	      octave_stdout << "\nccolamd version " << CCOLAMD_MAIN_VERSION << "."
+			    <<  CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE 
+			    << ":\nknobs(1): " << User_knobs (0) << ", order for ";
+	      if ( knobs [CCOLAMD_LU] != 0)
+		octave_stdout << "lu(A)\n";
+	      else
+		octave_stdout << "chol(A'*A)\n";
+
+	      if (knobs [CCOLAMD_DENSE_ROW] >= 0)
+		octave_stdout << "knobs(2): " << User_knobs (1) 
+			      << ", rows with > max(16,"
+			      << knobs [CCOLAMD_DENSE_ROW] << "*sqrt(size(A,2)))"
+			      << " entries removed\n";
+	      else
+		octave_stdout << "knobs(2): " << User_knobs (1)
+			      << ", no dense rows removed\n";
+
+	      if (knobs [CCOLAMD_DENSE_COL] >= 0)
+		octave_stdout << "knobs(3): " << User_knobs (2) 
+			      << ", cols with > max(16,"
+			      << knobs [CCOLAMD_DENSE_COL] << "*sqrt(size(A)))"
+			      << " entries removed\n";
+	      else
+		octave_stdout << "knobs(3): " << User_knobs (2)
+			      << ", no dense columns removed\n";
+
+	      if (knobs [CCOLAMD_AGGRESSIVE] != 0)
+		octave_stdout << "knobs(4): " << User_knobs(3) 
+			      << ", aggressive absorption: yes";
+	      else
+		octave_stdout << "knobs(4): " << User_knobs(3) 
+			      << ", aggressive absorption: no";
+ 
+	      octave_stdout << "knobs(5): " << User_knobs (4) 
+			    << ", statistics and knobs printed\n";
+	    }
+	}
+      
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      SparseComplexMatrix scm;
+      SparseMatrix sm;
+
+      if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      scm = args(0). sparse_complex_matrix_value ();
+	      n_row = scm.rows ();
+	      n_col = scm.cols ();
+	      nnz = scm.nzmax ();
+	      ridx = scm.xridx ();
+	      cidx = scm.xcidx ();
+	    }
+	  else
+	    {
+	      sm = args(0).sparse_matrix_value ();
+
+	      n_row = sm.rows ();
+	      n_col = sm.cols ();
+	      nnz = sm.nzmax ();
+	      ridx = sm.xridx ();
+	      cidx = sm.xcidx ();
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type ())
+	    sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+	  else
+	    sm = SparseMatrix (args(0).matrix_value ());
+
+	  n_row = sm.rows ();
+	  n_col = sm.cols ();
+	  nnz = sm.nzmax ();
+	  ridx = sm.xridx ();
+	  cidx = sm.xcidx ();
+	}
+
+      // Allocate workspace for ccolamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
+      for (octave_idx_type i = 0; i < n_col+1; i++)
+	p[i] = cidx [i];
+
+      octave_idx_type Alen = CCOLAMD_NAME (_recommended) (nnz, n_row, n_col);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
+      for (octave_idx_type i = 0; i < nnz; i++)
+	A[i] = ridx [i];
+
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
+
+      if (nargin > 2)
+	{
+	  NDArray in_cmember = args(2).array_value();
+	  octave_idx_type cslen = in_cmember.length();
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
+	  for (octave_idx_type i = 0; i < cslen; i++)
+	    // convert cmember from 1-based to 0-based
+	    cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
+	  
+	  if (cslen != n_col)
+	    error ("ccolamd: cmember must be of length equal to #cols of A");
+	  else
+	    // Order the columns (destroys A)
+	    if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, cmember))
+	      {
+		CCOLAMD_NAME (_report) (stats) ;
+		error ("ccolamd: internal error!");
+		return retval;
+	      }
+	}
+      else
+	{
+	  // Order the columns (destroys A)
+	  if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, 0))
+	    {
+	      CCOLAMD_NAME (_report) (stats) ;
+	      error ("ccolamd: internal error!");
+	      return retval;
+	    }
+	}
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+	out_perm(i) = p [i] + 1;
+
+      retval (0) = out_perm;
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+	CCOLAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+	{
+	  NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
+	  for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
+	    out_stats (i) = stats [i] ;
+	  retval(1) = out_stats;
+
+	  // fix stats (5) and (6), for 1-based information on 
+	  // jumbled matrix.  note that this correction doesn't 
+	  // occur if symamd returns FALSE
+	  out_stats (CCOLAMD_INFO1) ++ ; 
+	  out_stats (CCOLAMD_INFO2) ++ ; 
+	}
+    }
+
+#else
+
+  error ("ccolamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (csymamd, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} csymamd (@var{s})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs}, @var{cmember})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})\n\
+\n\
+For a symmetric positive definite matrix @var{s}, returns the permutation\n\
+vector @var{p} such that @code{@var{s}(@var{p}, at var{p})} tends to have a\n\
+sparser Cholesky factor than @var{s}.  Sometimes @code{csymamd} works well\n\
+for symmetric indefinite matrices too.  The matrix @var{s} is assumed to\n\
+be symmetric; only the strictly lower triangular part is referenced.\n\
+ at var{s} must be square.  The ordering is followed by an elimination tree\n\
+post-ordering.\n\
+\n\
+ at var{knobs} is an optional one- to three-element input vector, with a\n\
+default value of @code{[10 1 0]} if present or empty.  Entries not\n\
+present are set to their defaults.\n\
+\n\
+ at table @code\n\
+ at item @var{knobs}(1)\n\
+If @var{s} is n-by-n, then rows and columns with more than\n\
+ at code{max(16, at var{knobs}(1)*sqrt(n))} entries are ignored, and ordered\n\
+last in the output permutation (subject to the cmember constraints).\n\
+\n\
+ at item @var{knobs}(2)\n\
+If nonzero, aggressive absorption is performed.\n\
+\n\
+ at item @var{knobs}(3)\n\
+If nonzero, statistics and knobs are printed.\n\
+\n\
+ at end table\n\
+\n\
+ at var{cmember} is an optional vector of length n. It defines the constraints\n\
+on the ordering.  If @code{@var{cmember}(j) = @var{s}}, then row/column j is\n\
+in constraint set @var{c} (@var{c} must be in the range 1 to n).  In the\n\
+output permutation @var{p}, rows/columns in set 1 appear first, followed\n\
+by all rows/columns in set 2, and so on.  @code{@var{cmember} = ones(1,n)}\n\
+if not present or empty.  @code{csymamd(@var{s},[],1:n)} returns @code{1:n}.\n\
+\n\
+ at code{@var{p} = csymamd(@var{s})} is about the same as @code{@var{p} =\n\
+symamd(@var{s})}.  @var{knobs} and its default values differ.\n\
+\n\
+ at code{@var{stats} (4:7)} provide information if CCOLAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if\n\
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is\n\
+unsorted or contains duplicate entries, or zero if no such column exists.\n\
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row\n\
+index in the column index given by @code{@var{stats} (5)}, or zero if no\n\
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate\n\
+or out-of-order row indices.  @code{@var{stats} (8:20)} is always zero in\n\
+the current version of CCOLAMD (reserved for future use).\n\
+\n\
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\
+and a grant from Sandia National Lab.  See\n\
+ at url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\
+colamd, symamd, and other related orderings.\n\
+ at seealso{symamd, ccolamd}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#if HAVE_CCOLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+ 
+  if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 3)
+    usage ("ccolamd: incorrect number of input and/or output arguments");
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS);
+      CCOLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin > 1)
+	{
+	  NDArray User_knobs = args(1).array_value ();
+	  int nel_User_knobs = User_knobs.length ();
+	  
+	  if (nel_User_knobs > 0) 
+	    knobs [CCOLAMD_DENSE_ROW] = User_knobs (0);
+	  if (nel_User_knobs > 0) 
+	    knobs [CCOLAMD_AGGRESSIVE] = User_knobs (1);
+	  if (nel_User_knobs > 1) 
+	    spumoni = static_cast<int> (User_knobs (2));
+
+	  // print knob settings if spumoni is set
+	  if (spumoni)
+	    {
+	      octave_stdout << "\ncsymamd version " << CCOLAMD_MAIN_VERSION << "."
+			    <<  CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE << "\n";
+
+	      if (knobs [CCOLAMD_DENSE_ROW] >= 0)
+		octave_stdout << "knobs(1): " << User_knobs (0) 
+			      << ", rows/cols with > max(16,"
+			      << knobs [CCOLAMD_DENSE_ROW] << "*sqrt(size(A,2)))"
+			      << " entries removed\n";
+	      else
+		octave_stdout << "knobs(1): " << User_knobs (0)
+			      << ", no dense rows/cols removed\n";
+
+	      if (knobs [CCOLAMD_AGGRESSIVE] != 0)
+		octave_stdout << "knobs(2): " << User_knobs(1) 
+			      << ", aggressive absorption: yes";
+	      else
+		octave_stdout << "knobs(2): " << User_knobs(1) 
+			      << ", aggressive absorption: no";
+ 
+
+	      octave_stdout << "knobs(3): " << User_knobs (2) 
+			    << ", statistics and knobs printed\n";
+	    }
+	}
+      
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      scm = args(0).sparse_complex_matrix_value ();
+	      n_row = scm.rows ();
+	      n_col = scm.cols ();
+	      nnz = scm.nzmax ();
+	      ridx = scm.xridx ();
+	      cidx = scm.xcidx ();
+	    }
+	  else
+	    {
+	      sm = args(0).sparse_matrix_value ();
+	      n_row = sm.rows ();
+	      n_col = sm.cols ();
+	      nnz = sm.nzmax ();
+	      ridx = sm.xridx ();
+	      cidx = sm.xcidx ();
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type ())
+	    sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+	  else
+	    sm = SparseMatrix (args(0).matrix_value ());
+	  
+	  n_row = sm.rows ();
+	  n_col = sm.cols ();
+	  nnz = sm.nzmax ();
+	  ridx = sm.xridx ();
+	  cidx = sm.xcidx ();
+	}
+
+      if (n_row != n_col)
+	{
+	  error ("symamd: matrix must be square");
+	  return retval;
+	}
+
+      // Allocate workspace for symamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
+
+      if (nargin > 2)
+	{
+	  NDArray in_cmember = args(2).array_value();
+	  octave_idx_type cslen = in_cmember.length();
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
+	  for (octave_idx_type i = 0; i < cslen; i++)
+	    // convert cmember from 1-based to 0-based
+	    cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
+	  
+	  if (cslen != n_col)
+	    error ("ccolamd: cmember must be of length equal to #cols of A");
+	  else
+	    if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, 
+				  &calloc, &free, cmember, -1))
+	      {
+		CSYMAMD_NAME (_report) (stats) ;
+		error ("symamd: internal error!") ;
+		return retval;
+	      }
+	}
+      else
+	{
+	  if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, 
+				&calloc, &free, 0, -1))
+	    {
+	      CSYMAMD_NAME (_report) (stats) ;
+	      error ("symamd: internal error!") ;
+	      return retval;
+	    }
+	}
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+	out_perm(i) = perm [i] + 1;
+
+      retval (0) = out_perm;
+
+      // Return the stats vector
+      if (nargout == 2)
+	{
+	  NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
+	  for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
+	    out_stats (i) = stats [i] ;
+	  retval(1) = out_stats;
+
+	  // fix stats (5) and (6), for 1-based information on 
+	  // jumbled matrix.  note that this correction doesn't 
+	  // occur if symamd returns FALSE
+	  out_stats (CCOLAMD_INFO1) ++ ; 
+	  out_stats (CCOLAMD_INFO2) ++ ; 
+	}
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+	CSYMAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+	{
+	  NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
+	  for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
+	    out_stats (i) = stats [i] ;
+	  retval(1) = out_stats;
+
+	  // fix stats (5) and (6), for 1-based information on 
+	  // jumbled matrix.  note that this correction doesn't 
+	  // occur if symamd returns FALSE
+	  out_stats (CCOLAMD_INFO1) ++ ; 
+	  out_stats (CCOLAMD_INFO2) ++ ; 
+	}
+    }
+
+#else
+
+  error ("csymamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/cellfun.cc b/src/DLD-FUNCTIONS/cellfun.cc
new file mode 100644
index 0000000..5ed803c
--- /dev/null
+++ b/src/DLD-FUNCTIONS/cellfun.cc
@@ -0,0 +1,1333 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008, 2009 Mohamed Kamoun
+Copyright (C) 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+#include <list>
+#include <memory>
+
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "oct-map.h"
+#include "defun-dld.h"
+#include "parse.h"
+#include "variables.h"
+#include "ov-colon.h"
+#include "unwind-prot.h"
+
+// Rationale:
+// The octave_base_value::subsasgn method carries too much overhead for
+// per-element assignment strategy.
+// This class will optimize the most optimistic and most likely case
+// when the output really is scalar by defining a hierarchy of virtual
+// collectors specialized for some scalar types.
+
+class scalar_col_helper
+{
+public:
+  virtual bool collect (octave_idx_type i, const octave_value& val) = 0;
+  virtual octave_value result (void) = 0;
+  virtual ~scalar_col_helper (void) { }
+};
+
+// The default collector represents what was previously done in the main loop.
+// This reuses the existing assignment machinery via octave_value::subsasgn,
+// which can perform all sorts of conversions, but is relatively slow.
+
+class scalar_col_helper_def : public scalar_col_helper
+{
+  std::list<octave_value_list> idx_list;
+  octave_value resval;
+public:
+  scalar_col_helper_def (const octave_value& val, const dim_vector& dims)
+    : idx_list (1), resval (val)
+    {
+      idx_list.front ().resize (1);
+      if (resval.dims () != dims)
+        resval.resize (dims);
+    }
+  ~scalar_col_helper_def (void) { }
+
+  bool collect (octave_idx_type i, const octave_value& val)
+    {
+      if (val.numel () == 1)
+        {
+          idx_list.front ()(0) = static_cast<double> (i + 1);
+          resval = resval.subsasgn ("(", idx_list, val);
+        }
+      else
+        error ("cellfun: expecting all values to be scalars for UniformOutput = true");
+
+      return true;
+    }
+  octave_value result (void)
+    {
+      return resval;
+    }
+};
+
+template <class T>
+struct scalar_query_helper { };
+
+#define DEF_QUERY_HELPER(T, TEST, QUERY) \
+template <> \
+struct scalar_query_helper<T> \
+{ \
+  static bool has_value (const octave_value& val) \
+    { return TEST; } \
+  static T get_value (const octave_value& val) \
+    { return QUERY; } \
+}
+
+DEF_QUERY_HELPER (double, val.is_real_scalar (), val.scalar_value ());
+DEF_QUERY_HELPER (Complex, val.is_complex_scalar (), val.complex_value ());
+DEF_QUERY_HELPER (float, val.is_single_type () && val.is_real_scalar (), 
+                  val.float_scalar_value ());
+DEF_QUERY_HELPER (FloatComplex, val.is_single_type () && val.is_complex_scalar (), 
+                  val.float_complex_value ());
+DEF_QUERY_HELPER (bool, val.is_bool_scalar (), val.bool_value ());
+// FIXME: More?
+
+// This specializes for collecting elements of a single type, by accessing
+// an array directly. If the scalar is not valid, it returns false.
+
+template <class NDA>
+class scalar_col_helper_nda : public scalar_col_helper
+{
+  NDA arrayval;
+  typedef typename NDA::element_type T;
+public:
+  scalar_col_helper_nda (const octave_value& val, const dim_vector& dims)
+    : arrayval (dims)
+    {
+      arrayval(0) = scalar_query_helper<T>::get_value (val);
+    }
+  ~scalar_col_helper_nda (void) { }
+
+  bool collect (octave_idx_type i, const octave_value& val)
+    {
+      bool retval = scalar_query_helper<T>::has_value (val);
+      if (retval)
+        arrayval(i) = scalar_query_helper<T>::get_value (val);
+      return retval;
+    }
+  octave_value result (void)
+    {
+      return arrayval;
+    }
+};
+
+template class scalar_col_helper_nda<NDArray>;
+template class scalar_col_helper_nda<FloatNDArray>;
+template class scalar_col_helper_nda<ComplexNDArray>;
+template class scalar_col_helper_nda<FloatComplexNDArray>;
+template class scalar_col_helper_nda<boolNDArray>;
+
+// the virtual constructor.
+scalar_col_helper *
+make_col_helper (const octave_value& val, const dim_vector& dims)
+{
+  scalar_col_helper *retval;
+
+  if (val.is_bool_scalar ())
+    retval = new scalar_col_helper_nda<boolNDArray> (val, dims);
+  else if (val.is_complex_scalar ())
+    {
+      if (val.is_single_type ())
+        retval = new scalar_col_helper_nda<FloatComplexNDArray> (val, dims);
+      else
+        retval = new scalar_col_helper_nda<ComplexNDArray> (val, dims);
+    }
+  else if (val.is_real_scalar ())
+    {
+      if (val.is_single_type ())
+        retval = new scalar_col_helper_nda<FloatNDArray> (val, dims);
+      else
+        retval = new scalar_col_helper_nda<NDArray> (val, dims);
+    }
+  else
+    retval = new scalar_col_helper_def (val, dims);
+
+  return retval;
+}
+
+DEFUN_DLD (cellfun, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} cellfun (@var{name}, @var{c})\n\
+ at deftypefnx {Loadable Function} {} cellfun (\"size\", @var{c}, @var{k})\n\
+ at deftypefnx {Loadable Function} {} cellfun (\"isclass\", @var{c}, @var{class})\n\
+ at deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c})\n\
+ at deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c}, @var{d})\n\
+ at deftypefnx {Loadable Function} {[@var{a}, @var{b}] =} cellfun (@dots{})\n\
+ at deftypefnx {Loadable Function} {} cellfun (@dots{}, 'ErrorHandler', @var{errfunc})\n\
+ at deftypefnx {Loadable Function} {} cellfun (@dots{}, 'UniformOutput', @var{val})\n\
+\n\
+Evaluate the function named @var{name} on the elements of the cell array\n\
+ at var{c}.  Elements in @var{c} are passed on to the named function\n\
+individually.  The function @var{name} can be one of the functions\n\
+\n\
+ at table @code\n\
+ at item isempty\n\
+Return 1 for empty elements.\n\
+ at item islogical\n\
+Return 1 for logical elements.\n\
+ at item isreal\n\
+Return 1 for real elements.\n\
+ at item length\n\
+Return a vector of the lengths of cell elements.\n\
+ at item ndims\n\
+Return the number of dimensions of each element.\n\
+ at item prodofsize\n\
+Return the product of dimensions of each element.\n\
+ at item size\n\
+Return the size along the @var{k}-th dimension.\n\
+ at item isclass\n\
+Return 1 for elements of @var{class}.\n\
+ at end table\n\
+\n\
+Additionally, @code{cellfun} accepts an arbitrary function @var{func}\n\
+in the form of an inline function, function handle, or the name of a\n\
+function (in a character string).  In the case of a character string\n\
+argument, the function must accept a single argument named @var{x}, and\n\
+it must return a string value.  The function can take one or more arguments,\n\
+with the inputs args given by @var{c}, @var{d}, etc.  Equally the function\n\
+can return one or more output arguments.  For example\n\
+\n\
+ at example\n\
+ at group\n\
+cellfun (@@atan2, @{1, 0@}, @{0, 1@})\n\
+ at result{}ans = [1.57080   0.00000]\n\
+ at end group\n\
+ at end example\n\
+\n\
+Note that the default output argument is an array of the same size as the\n\
+input arguments.\n\
+\n\
+If the parameter 'UniformOutput' is set to true (the default), then the function\n\
+must return a single element which will be concatenated into the\n\
+return value.  If 'UniformOutput' is false, the outputs are concatenated in\n\
+a cell array.  For example\n\
+\n\
+ at example\n\
+ at group\n\
+cellfun (\"tolower(x)\", @{\"Foo\", \"Bar\", \"FooBar\"@},\n\
+         \"UniformOutput\",false)\n\
+ at result{} ans = @{\"foo\", \"bar\", \"foobar\"@}\n\
+ at end group\n\
+ at end example\n\
+\n\
+Given the parameter 'ErrorHandler', then @var{errfunc} defines a function to\n\
+call in case @var{func} generates an error.  The form of the function is\n\
+\n\
+ at example\n\
+function [@dots{}] = errfunc (@var{s}, @dots{})\n\
+ at end example\n\
+\n\
+where there is an additional input argument to @var{errfunc} relative to\n\
+ at var{func}, given by @var{s}.  This is a structure with the elements\n\
+'identifier', 'message' and 'index', giving respectively the error\n\
+identifier, the error message, and the index into the input arguments\n\
+of the element that caused the error.  For example\n\
+\n\
+ at example\n\
+ at group\n\
+function y = foo (s, x), y = NaN; endfunction\n\
+cellfun (@@factorial, @{-1,2@},'ErrorHandler',@@foo)\n\
+ at result{} ans = [NaN 2]\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at seealso{isempty, islogical, isreal, length, ndims, numel, size}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  std::string name = "function";
+  octave_function *func = 0;
+  int nargin = args.length ();
+  nargout = (nargout < 1 ? 1 : nargout);
+
+  if (nargin < 2)
+    {
+      error ("cellfun: you must supply at least 2 arguments");
+      print_usage ();
+      return retval;
+    }
+
+  if (args(0).is_function_handle () || args(0).is_inline_function ())
+    {
+      func = args(0).function_value ();
+
+      if (error_state)
+	return retval;
+    }
+  else if (args(0).is_string ())
+    name = args(0).string_value ();
+  else
+    {
+      error ("cellfun: first argument must be a string or function handle");
+      return retval;
+    }	
+
+  if (! args(1).is_cell ())
+    {
+      error ("cellfun: second argument must be a cell array");
+
+      return retval;
+    }
+  
+  const Cell f_args = args(1).cell_value ();
+  
+  octave_idx_type k = f_args.numel ();
+
+  if (name == "isempty")
+    {      
+      boolNDArray result (f_args.dims ());
+      for (octave_idx_type count = 0; count < k ; count++)
+        result(count) = f_args.elem(count).is_empty ();
+      retval(0) = result;
+    }
+  else if (name == "islogical")
+    {
+      boolNDArray result (f_args.dims ());
+      for (octave_idx_type  count= 0; count < k ; count++)
+        result(count) = f_args.elem(count).is_bool_type ();
+      retval(0) = result;
+    }
+  else if (name == "isreal")
+    {
+      boolNDArray result (f_args.dims ());
+      for (octave_idx_type  count= 0; count < k ; count++)
+        result(count) = f_args.elem(count).is_real_type ();
+      retval(0) = result;
+    }
+  else if (name == "length")
+    {
+      NDArray result (f_args.dims ());
+      for (octave_idx_type  count= 0; count < k ; count++)
+        result(count) = static_cast<double> (f_args.elem(count).length ());
+      retval(0) = result;
+    }
+  else if (name == "ndims")
+    {
+      NDArray result (f_args.dims ());
+      for (octave_idx_type count = 0; count < k ; count++)
+        result(count) = static_cast<double> (f_args.elem(count).ndims ());
+      retval(0) = result;
+    }
+  else if (name == "prodofsize" || name == "numel")
+    {
+      NDArray result (f_args.dims ());
+      for (octave_idx_type count = 0; count < k ; count++)
+        result(count) = static_cast<double> (f_args.elem(count).numel ());
+      retval(0) = result;
+    }
+  else if (name == "size")
+    {
+      if (nargin == 3)
+        {
+          int d = args(2).nint_value () - 1;
+
+          if (d < 0)
+	    error ("cellfun: third argument must be a positive integer");
+
+	  if (! error_state)
+            {
+              NDArray result (f_args.dims ());
+              for (octave_idx_type count = 0; count < k ; count++)
+                {
+                  dim_vector dv = f_args.elem(count).dims ();
+                  if (d < dv.length ())
+	            result(count) = static_cast<double> (dv(d));
+                  else
+	            result(count) = 1.0;
+                }
+              retval(0) = result;
+            }
+        }
+      else
+        error ("not enough arguments for `size'");
+    }
+  else if (name == "isclass")
+    {
+      if (nargin == 3)
+        {
+          std::string class_name = args(2).string_value();
+          boolNDArray result (f_args.dims ());
+          for (octave_idx_type count = 0; count < k ; count++)
+            result(count) = (f_args.elem(count).class_name() == class_name);
+          
+          retval(0) = result;
+        }
+      else
+        error ("not enough arguments for `isclass'");
+    }
+  else 
+    {
+      unwind_protect::begin_frame ("Fcellfun");
+      unwind_protect_int (buffer_error_messages);
+
+      std::string fcn_name;
+      
+      if (! func)
+	{
+	  fcn_name = unique_symbol_name ("__cellfun_fcn_");
+	  std::string fname = "function y = ";
+	  fname.append (fcn_name);
+	  fname.append ("(x) y = ");
+	  func = extract_function (args(0), "cellfun", fcn_name, fname,
+				       "; endfunction");
+	}
+
+      if (! func)
+	error ("unknown function");
+      else
+	{
+	  octave_value_list inputlist;
+	  bool uniform_output = true;
+	  bool have_error_handler = false;
+	  std::string err_name;
+	  octave_function *error_handler = 0;
+	  int offset = 1;
+	  int i = 1;
+	  OCTAVE_LOCAL_BUFFER (Cell, inputs, nargin);
+          // This is to prevent copy-on-write.
+          const Cell *cinputs = inputs;
+
+	  while (i < nargin)
+	    {
+	      if (args(i).is_string())
+		{
+		  std::string arg = args(i++).string_value();
+		  if (i == nargin)
+		    {
+		      error ("cellfun: parameter value is missing");
+		      goto cellfun_err;
+		    }
+
+		  std::transform (arg.begin (), arg.end (), 
+				  arg.begin (), tolower);
+
+		  if (arg == "uniformoutput")
+		    uniform_output = args(i++).bool_value();
+		  else if (arg == "errorhandler")
+		    {
+		      if (args(i).is_function_handle () || 
+			  args(i).is_inline_function ())
+			{
+			  error_handler = args(i).function_value ();
+
+			  if (error_state)
+			    goto cellfun_err;
+			}
+		      else if (args(i).is_string ())
+			{
+			  err_name = unique_symbol_name ("__cellfun_fcn_");
+			  std::string fname = "function y = ";
+			  fname.append (fcn_name);
+			  fname.append ("(x) y = ");
+			  error_handler = extract_function (args(i), "cellfun", 
+							    err_name, fname,
+							    "; endfunction");
+			}
+
+		      if (! error_handler)
+			goto cellfun_err;
+
+		      have_error_handler = true;
+		      i++;
+		    }
+		  else
+		    {
+		      error ("cellfun: unrecognized parameter %s", 
+			     arg.c_str());
+		      goto cellfun_err;
+		    }
+		  offset += 2;
+		}
+	      else
+		{
+		  inputs[i-offset] = args(i).cell_value ();
+		  if (f_args.dims() != inputs[i-offset].dims())
+		    {
+		      error ("cellfun: Dimension mismatch");
+		      goto cellfun_err;
+
+		    }
+		  i++;
+		}
+	    }
+
+          nargin -= offset;
+	  inputlist.resize(nargin);
+
+	  if (have_error_handler)
+	    buffer_error_messages++;
+
+	  if (uniform_output)
+	    {
+              OCTAVE_LOCAL_BUFFER (std::auto_ptr<scalar_col_helper>, retptr, nargout);
+
+	      for (octave_idx_type count = 0; count < k ; count++)
+		{
+		  for (int j = 0; j < nargin; j++)
+		    inputlist(j) = cinputs[j](count);
+
+		  octave_value_list tmp = feval (func, inputlist, nargout);
+
+		  if (error_state && have_error_handler)
+		    {
+		      Octave_map msg;
+		      msg.assign ("identifier", last_error_id ());
+		      msg.assign ("message", last_error_message ());
+		      msg.assign ("index", octave_value(double (count + static_cast<octave_idx_type>(1))));
+		      octave_value_list errlist = inputlist;
+		      errlist.prepend (msg);
+		      buffer_error_messages--;
+		      error_state = 0;
+		      tmp = feval (error_handler, errlist, nargout);
+		      buffer_error_messages++;
+
+		      if (error_state)
+			goto cellfun_err;
+		    }
+
+		  if (tmp.length() < nargout)
+		    {
+		      error ("cellfun: too many output arguments");
+		      goto cellfun_err;
+		    }
+
+		  if (error_state)
+		    break;
+
+		  if (count == 0)
+		    {
+		      for (int j = 0; j < nargout; j++)
+			{
+			  octave_value val = tmp(j);
+
+                          if (val.numel () == 1)
+                            retptr[j].reset (make_col_helper (val, f_args.dims ()));
+                          else
+                            {
+                              error ("cellfun: expecting all values to be scalars for UniformOutput = true");
+                              break;
+                            }
+			}
+		    }
+		  else
+		    {
+		      for (int j = 0; j < nargout; j++)
+			{
+			  octave_value val = tmp(j);
+
+                          if (! retptr[j]->collect (count, val))
+                            {
+                              // FIXME: A more elaborate structure would allow again a virtual
+                              // constructor here.
+                              retptr[j].reset (new scalar_col_helper_def (retptr[j]->result (), 
+                                                                          f_args.dims ()));
+                              retptr[j]->collect (count, val);
+                            }
+                        }
+		    }
+
+		  if (error_state)
+		    break;
+		}
+
+              retval.resize (nargout);
+              for (int j = 0; j < nargout; j++)
+                {
+                  if (retptr[j].get ())
+                    retval(j) = retptr[j]->result ();
+                  else
+                    retval(j) = Matrix ();
+                }
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (Cell, results, nargout);
+	      for (int j = 0; j < nargout; j++)
+		results[j].resize(f_args.dims());
+
+	      for (octave_idx_type count = 0; count < k ; count++)
+		{
+		  for (int j = 0; j < nargin; j++)
+		    inputlist(j) = cinputs[j](count);
+
+		  octave_value_list tmp = feval (func, inputlist, nargout);
+
+		  if (error_state && have_error_handler)
+		    {
+		      Octave_map msg;
+		      msg.assign ("identifier", last_error_id ());
+		      msg.assign ("message", last_error_message ());
+		      msg.assign ("index", octave_value(double (count + static_cast<octave_idx_type>(1))));
+		      octave_value_list errlist = inputlist;
+		      errlist.prepend (msg);
+		      buffer_error_messages--;
+		      error_state = 0;
+		      tmp = feval (error_handler, errlist, nargout);
+		      buffer_error_messages++;
+
+		      if (error_state)
+			goto cellfun_err;
+		    }
+
+		  if (tmp.length() < nargout)
+		    {
+		      error ("cellfun: too many output arguments");
+		      goto cellfun_err;
+		    }
+
+		  if (error_state)
+		    break;
+
+
+		  for (int j = 0; j < nargout; j++)
+		    results[j](count) = tmp(j);
+		}
+
+	      retval.resize(nargout);
+	      for (int j = 0; j < nargout; j++)
+		retval(j) = results[j];
+	    }
+
+	cellfun_err:
+	  if (error_state)
+	    retval = octave_value_list();
+
+	  if (! fcn_name.empty ())
+	    clear_function (fcn_name);
+
+	  if (! err_name.empty ())
+	    clear_function (err_name);
+	}
+
+      unwind_protect::run_frame ("Fcellfun");
+    }
+
+  return retval;
+}
+
+/*
+
+%% Test function to check the "Errorhandler" option
+%!function [z] = cellfunerror (S, varargin)
+%!    z = S;
+%!  endfunction
+
+%% First input argument can be a string, an inline function,
+%% a function_handle or an anonymous function
+%!test
+%!  A = cellfun ("islogical", {true, 0.1, false, i*2});
+%!  assert (A, [true, false, true, false]);
+%!test
+%!  A = cellfun (inline ("islogical (x)", "x"), {true, 0.1, false, i*2});
+%!  assert (A, [true, false, true, false]);
+%!test
+%!  A = cellfun (@islogical, {true, 0.1, false, i*2});
+%!  assert (A, [true, false, true, false]);
+%!test
+%!  A = cellfun (@(x) islogical(x), {true, 0.1, false, i*2});
+%!  assert (A, [true, false, true, false]);
+
+%% First input argument can be the special string "isreal",
+%% "isempty", "islogical", "length", "ndims" or "prodofsize"
+%!test
+%!  A = cellfun ("isreal", {true, 0.1, false, i*2, [], "abc"});
+%!  assert (A, [true, true, true, false, true, false]);
+%!test
+%!  A = cellfun ("isempty", {true, 0.1, false, i*2, [], "abc"});
+%!  assert (A, [false, false, false, false, true, false]);
+%!test
+%!  A = cellfun ("islogical", {true, 0.1, false, i*2, [], "abc"});
+%!  assert (A, [true, false, true, false, false, false]);
+%!test
+%!  A = cellfun ("length", {true, 0.1, false, i*2, [], "abc"});
+%!  assert (A, [1, 1, 1, 1, 0, 3]);
+%!test
+%!  A = cellfun ("ndims", {[1, 2; 3, 4]; (cell (1,2,3,4))});
+%!  assert (A, [2; 4]);
+%!test
+%!  A = cellfun ("prodofsize", {[1, 2; 3, 4], (cell (1,2,3,4))});
+%!  assert (A, [4, 24]);
+
+%% Number of input and output arguments may not be limited to one
+%!test
+%!  A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5});
+%!  assert (A, [6, 7, 8]);
+%!test
+%!  A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5}, \
+%!    "UniformOutput", false);
+%!  assert (A, {6, 7, 8});
+%!test %% Two input arguments of different types
+%!  A = cellfun (@(x,y) islogical (x) && ischar (y), {false, true}, {"a", 3});
+%!  assert (A, [true, false]);
+%!test %% Pass another variable to the anonymous function
+%!  y = true; A = cellfun (@(x) islogical (x) && y, {false, 0.3});
+%!  assert (A, [true, false]);
+%!test %% Three ouptut arguments of different type
+%!  [A, B, C] = cellfun (@find, {10, 11; 0, 12}, "UniformOutput", false);
+%!  assert (isequal (A, {true, true; [], true}));
+%!  assert (isequal (B, {true, true; [], true}));
+%!  assert (isequal (C, {10, 11; [], 12}));
+
+%% Input arguments can be of type cell array of logical
+%!test
+%!  A = cellfun (@(x,y) x == y, {false, true}, {true, true});
+%!  assert (A, [false, true]);
+%!test
+%!  A = cellfun (@(x,y) x == y, {false; true}, {true; true}, \
+%!    "UniformOutput", true);
+%!  assert (A, [false; true]);
+%!test
+%!  A = cellfun (@(x) x, {false, true; false, true}, "UniformOutput", false);
+%!  assert (A, {false, true; false, true});
+%!test %% Three ouptut arguments of same type
+%!  [A, B, C] = cellfun (@find, {true, false; false, true}, \
+%!    "UniformOutput", false);
+%!  assert (isequal (A, {true, []; [], true}));
+%!  assert (isequal (B, {true, []; [], true}));
+%!  assert (isequal (C, {true, []; [], true}));
+%!test
+%!  A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, \
+%!    "ErrorHandler", @cellfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, \
+%!    "UniformOutput", true, "ErrorHandler", @cellfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+
+%% Input arguments can be of type cell array of numeric
+%!test
+%!  A = cellfun (@(x,y) x>y, {1.1, 4.2}, {3.1, 2+6*i});
+%!  assert (A, [false, true]);
+%!test
+%!  A = cellfun (@(x,y) x>y, {1.1, 4.2; 2, 4}, {3.1, 2; 2, 4+2*i}, \
+%!    "UniformOutput", true);
+%!  assert (A, [false, true; false, false]);
+%!test
+%!  A = cellfun (@(x,y) x:y, {1.1, 4}, {3.1, 6}, "UniformOutput", false);
+%!  assert (isequal (A{1}, [1.1, 2.1, 3.1]));
+%!  assert (isequal (A{2}, [4, 5, 6]));
+%!test %% Three ouptut arguments of different type
+%!  [A, B, C] = cellfun (@find, {10, 11; 0, 12}, "UniformOutput", false);
+%!  assert (isequal (A, {true, true; [], true}));
+%!  assert (isequal (B, {true, true; [], true}));
+%!  assert (isequal (C, {10, 11; [], 12}));
+%!test
+%!  A = cellfun (@(x,y) cell2str(x,y), {1.1, 4}, {3.1, 6}, \
+%!    "ErrorHandler", @cellfunerror);
+%!  B = isfield (A(1), "message") && isfield (A(1), "index");
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = cellfun (@(x,y) cell2str(x,y), {1.1, 4}, {3.1, 6}, \
+%!    "UniformOutput", true, "ErrorHandler", @cellfunerror);
+%!  B = isfield (A(1), "message") && isfield (A(1), "index");
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+
+%% Input arguments can be of type cell arrays of character or strings
+%!error %% "UniformOutput" false should be used
+%!  A = cellfun (@(x,y) x>y, {"ad", "c", "ghi"}, {"cc", "d", "fgh"});
+%!test
+%!  A = cellfun (@(x,y) x>y, {"a"; "f"}, {"c"; "d"}, "UniformOutput", true);
+%!  assert (A, [false; true]);
+%!test
+%!  A = cellfun (@(x,y) x:y, {"a", "d"}, {"c", "f"}, "UniformOutput", false);
+%!  assert (A, {"abc", "def"});
+%!test
+%!  A = cellfun (@(x,y) cell2str(x,y), {"a", "d"}, {"c", "f"}, \
+%!    "ErrorHandler", @cellfunerror);
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = cellfun (@(x,y) cell2str(x,y), {"a", "d"}, {"c", "f"}, \
+%!    "UniformOutput", true, "ErrorHandler", @cellfunerror);
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+
+%% Structures cannot be handled by cellfun
+%!error
+%!  vst1.a = 1.1; vst1.b = 4.2; vst2.a = 3.1; vst2.b = 2;
+%!  A = cellfun (@(x,y) (x.a < y.a) && (x.b > y.b), vst1, vst2);
+
+%% Input arguments can be of type cell array of cell arrays
+%!test
+%!  A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}});
+%!  assert (A, [1, 0], 1e-16);
+%!test
+%!  A = cellfun (@(x,y) x{1} < y{1}, {{1.1}; {4.2}}, {{3.1}; {2}}, \
+%!    "UniformOutput", true);
+%!  assert (A, [1; 0], 1e-16);
+%!test
+%!  A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}}, \
+%!    "UniformOutput", false);
+%!  assert (A, {true, false});
+%!test
+%!  A = cellfun (@(x,y) mat2str(x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, \
+%!    "ErrorHandler", @cellfunerror);
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  A = cellfun (@(x,y) mat2str(x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, \
+%!    "UniformOutput", true, "ErrorHandler", @cellfunerror);
+%!  assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
+%!  assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
+%!  assert ([(isfield (A(1), "index")), (isfield (A(2), "index"))], [true, true]);
+%!  assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
+%!  assert ([A(1).index, A(2).index], [1, 2]);
+
+%% Input arguments can be of type cell array of structure arrays
+%!test
+%!  a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3);
+%!  A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b), {a}, {b});
+%!  assert (A, true);
+%!test
+%!  a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3);
+%!  A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, \
+%!    "UniformOutput", true);
+%!  assert (A, true);
+%!test
+%!  a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3);
+%!  A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, \
+%!    "UniformOutput", false);
+%!  assert (A, {true});
+%!test
+%!  a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3);
+%!  A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, \
+%!    "ErrorHandler", @cellfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+%!test %% Overwriting setting of "UniformOutput" true
+%!  a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3);
+%!  A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, \
+%!    "UniformOutput", true, "ErrorHandler", @cellfunerror);
+%!  assert (isfield (A, "identifier"), true);
+%!  assert (isfield (A, "message"), true);
+%!  assert (isfield (A, "index"), true);
+%!  assert (isempty (A.message), false);
+%!  assert (A.index, 1);
+
+%% A lot of other tests
+%!error(cellfun(1))
+%!error(cellfun('isclass',1))
+%!error(cellfun('size',1))
+%!error(cellfun(@sin,{[]},'BadParam',false))
+%!error(cellfun(@sin,{[]},'UniformOuput'))
+%!error(cellfun(@sin,{[]},'ErrorHandler'))
+%!assert(cellfun(@sin,{0,1}),sin([0,1]))
+%!assert(cellfun(inline('sin(x)'),{0,1}),sin([0,1]))
+%!assert(cellfun('sin',{0,1}),sin([0,1]))
+%!assert(cellfun('isempty',{1,[]}),[false,true])
+%!assert(cellfun('islogical',{false,pi}),[true,false])
+%!assert(cellfun('isreal',{1i,1}),[false,true])
+%!assert(cellfun('length',{zeros(2,2),1}),[2,1])
+%!assert(cellfun('prodofsize',{zeros(2,2),1}),[4,1])
+%!assert(cellfun('ndims',{zeros([2,2,2]),1}),[3,2])
+%!assert(cellfun('isclass',{zeros([2,2,2]),'test'},'double'),[true,false])
+%!assert(cellfun('size',{zeros([1,2,3]),1},1),[1,1])
+%!assert(cellfun('size',{zeros([1,2,3]),1},2),[2,1])
+%!assert(cellfun('size',{zeros([1,2,3]),1},3),[3,1])
+%!assert(cellfun(@atan2,{1,1},{1,2}),[atan2(1,1),atan2(1,2)])
+%!assert(cellfun(@atan2,{1,1},{1,2},'UniformOutput',false),{atan2(1,1),atan2(1,2)})
+%!assert(cellfun(@sin,{1,2;3,4}),sin([1,2;3,4]))
+%!assert(cellfun(@atan2,{1,1;1,1},{1,2;1,2}),atan2([1,1;1,1],[1,2;1,2]))
+%!error(cellfun(@factorial,{-1,3}))
+%!assert(cellfun(@factorial,{-1,3},'ErrorHandler',@(x,y) NaN),[NaN,6])
+%!test
+%! [a,b,c]=cellfun(@fileparts,{fullfile("a","b","c.d"),fullfile("e","f","g.h")},'UniformOutput',false);
+%! assert(a,{fullfile("a","b"),fullfile("e","f")})
+%! assert(b,{'c','g'})
+%! assert(c,{'.d','.h'})
+
+*/
+
+DEFUN_DLD (num2cell, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {@var{c} =} num2cell (@var{m})\n\
+ at deftypefnx {Loadable Function} {@var{c} =} num2cell (@var{m}, @var{dim})\n\
+Convert the matrix @var{m} to a cell array.  If @var{dim} is defined, the\n\
+value @var{c} is of dimension 1 in this dimension and the elements of\n\
+ at var{m} are placed in slices in @var{c}.\n\
+ at seealso{mat2cell}\n\
+ at end deftypefn") 
+{
+  int nargin =  args.length();
+  octave_value retval;
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    {
+      dim_vector dv = args(0).dims ();
+      Array<int> sings;
+
+      if (nargin == 2)
+	{
+	  ColumnVector dsings = ColumnVector (args(1).vector_value 
+						  (false, true));
+	  sings.resize (dsings.length());
+
+	  if (!error_state)
+	    for (octave_idx_type i = 0; i < dsings.length(); i++)
+	      if (dsings(i) > dv.length() || dsings(i) < 1 ||
+		  D_NINT(dsings(i)) != dsings(i))
+		{
+		  error ("invalid dimension specified");
+		  break;
+		}
+	      else
+		sings(i) = NINT(dsings(i)) - 1;
+	}
+
+      if (! error_state)
+	{
+	  Array<bool> idx_colon (dv.length());
+	  dim_vector new_dv (dv);
+	  octave_value_list lst (new_dv.length(), octave_value());
+
+	  for (int i = 0; i < dv.length(); i++)
+	    {
+	      idx_colon(i) = false;
+	      for (int j = 0; j < sings.length(); j++)
+		{
+		  if (sings(j) == i)
+		    {
+		      new_dv(i) = 1;
+		      idx_colon(i) = true;
+		      lst(i) = octave_value (octave_value::magic_colon_t); 
+		      break;
+		    }
+		}
+	    }
+
+	  Cell ret (new_dv);
+	  octave_idx_type nel = new_dv.numel();
+	  octave_idx_type ntot = 1;
+
+	  for (int j = 0; j < new_dv.length()-1; j++)
+	    ntot *= new_dv(j);
+
+	  for (octave_idx_type i = 0; i <  nel; i++)
+	    {
+	      octave_idx_type n = ntot;
+	      octave_idx_type ii = i;
+	      for (int j = new_dv.length() - 1; j >= 0 ; j--)
+		{
+		  if (! idx_colon(j))
+		    lst (j) = ii/n + 1;
+		  ii = ii % n;
+		  if (j != 0)
+		    n /= new_dv(j-1);
+		}
+	      ret(i) = args(0).do_index_op(lst, 0);
+	    }
+
+	  retval = ret;
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(num2cell([1,2;3,4]),{1,2;3,4})
+%!assert(num2cell([1,2;3,4],1),{[1;3],[2;4]})
+%!assert(num2cell([1,2;3,4],2),{[1,2];[3,4]})
+
+*/
+
+DEFUN_DLD (mat2cell, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{m}, @var{n})\n\
+ at deftypefnx {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{d1}, @var{d2}, @dots{})\n\
+ at deftypefnx {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{r})\n\
+Convert the matrix @var{a} to a cell array.  If @var{a} is 2-D, then\n\
+it is required that @code{sum (@var{m}) == size (@var{a}, 1)} and\n\
+ at code{sum (@var{n}) == size (@var{a}, 2)}.  Similarly, if @var{a} is\n\
+a multi-dimensional and the number of dimensional arguments is equal\n\
+to the dimensions of @var{a}, then it is required that @code{sum (@var{di})\n\
+== size (@var{a}, i)}.\n\
+\n\
+Given a single dimensional argument @var{r}, the other dimensional\n\
+arguments are assumed to equal @code{size (@var{a}, at var{i})}.\n\
+\n\
+An example of the use of mat2cell is\n\
+\n\
+ at example\n\
+mat2cell (reshape(1:16,4,4),[3,1],[3,1])\n\
+ at result{} @{\n\
+  [1,1] =\n\
+\n\
+     1   5   9\n\
+     2   6  10\n\
+     3   7  11\n\
+\n\
+  [2,1] =\n\
+\n\
+     4   8  12\n\
+\n\
+  [1,2] =\n\
+\n\
+    13\n\
+    14\n\
+    15\n\
+\n\
+  [2,2] = 16\n\
+@}\n\
+ at end example\n\
+ at seealso{num2cell, cell2mat}\n\
+ at end deftypefn")
+{
+  int nargin = args.length();
+  octave_value retval;
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    {
+      dim_vector dv = args(0).dims();
+      dim_vector new_dv;
+      new_dv.resize(dv.length());
+      
+      if (nargin > 2)
+	{
+	  octave_idx_type nmax = -1;
+
+	  if (nargin - 1 != dv.length())
+	    error ("mat2cell: Incorrect number of dimensions");
+	  else
+	    {
+	      for (octave_idx_type j = 0; j < dv.length(); j++)
+		{
+		  ColumnVector d = ColumnVector (args(j+1).vector_value 
+						 (false, true));
+
+		  if (d.length() < 1)
+		    {
+		      error ("mat2cell: dimension can not be empty");
+		      break;
+		    }
+		  else
+		    {
+		      if (nmax < d.length())
+			nmax = d.length();
+
+		      for (octave_idx_type i = 1; i < d.length(); i++)
+			{
+			  OCTAVE_QUIT;
+
+			  if (d(i) >= 0)
+			    d(i) += d(i-1);
+			  else
+			    {
+			      error ("mat2cell: invalid dimensional argument");
+			      break;
+			    }
+			}
+
+		      if (d(0) < 0)
+			error ("mat2cell: invalid dimensional argument");
+		      
+		      if (d(d.length() - 1) != dv(j))
+			error ("mat2cell: inconsistent dimensions");
+
+		      if (error_state)
+			break;
+
+		      new_dv(j) = d.length();
+		    }
+		}
+	    }
+
+	  if (! error_state)
+	    {
+	      // Construct a matrix with the index values
+	      Matrix dimargs(nmax, new_dv.length());
+	      for (octave_idx_type j = 0; j < new_dv.length(); j++)
+		{
+		  OCTAVE_QUIT;
+
+		  ColumnVector d = ColumnVector (args(j+1).vector_value 
+						 (false, true));
+
+		  dimargs(0,j) = d(0);
+		  for (octave_idx_type i = 1; i < d.length(); i++)
+		    dimargs(i,j) = dimargs(i-1,j) + d(i);
+		}
+
+
+	      octave_value_list lst (new_dv.length(), octave_value());
+	      Cell ret (new_dv);
+	      octave_idx_type nel = new_dv.numel();
+	      octave_idx_type ntot = 1;
+
+	      for (int j = 0; j < new_dv.length()-1; j++)
+		ntot *= new_dv(j);
+
+	      for (octave_idx_type i = 0; i <  nel; i++)
+		{
+		  octave_idx_type n = ntot;
+		  octave_idx_type ii = i;
+		  for (octave_idx_type j =  new_dv.length() - 1;  j >= 0; j--)
+		    {
+		      OCTAVE_QUIT;
+		  
+		      octave_idx_type idx = ii / n;
+		      lst (j) = Range((idx == 0 ? 1. : dimargs(idx-1,j)+1.),
+				      dimargs(idx,j));
+		      ii = ii % n;
+		      if (j != 0)
+			n /= new_dv(j-1);
+		    }
+		  ret(i) = args(0).do_index_op(lst, 0);
+		  if (error_state)
+		    break;
+		}
+	  
+	      if (!error_state)
+		retval = ret;
+	    }
+	}
+      else
+	{
+	  ColumnVector d = ColumnVector (args(1).vector_value 
+					 (false, true));
+
+	  double sumd = 0.;
+	  for (octave_idx_type i = 0; i < d.length(); i++)
+	    {
+	      OCTAVE_QUIT;
+
+	      if (d(i) >= 0)
+		sumd += d(i);
+	      else
+		{
+		  error ("mat2cell: invalid dimensional argument");
+		  break;
+		}
+	    }
+
+	  if (sumd != dv(0))
+	    error ("mat2cell: inconsistent dimensions");
+
+	  new_dv(0) = d.length();
+	  for (octave_idx_type i = 1; i < dv.length(); i++)
+	    new_dv(i) = 1;
+
+	  if (! error_state)
+	    {
+	      octave_value_list lst (new_dv.length(), octave_value());
+	      Cell ret (new_dv);
+
+	      for (octave_idx_type i = 1; i < new_dv.length(); i++)
+		lst (i) = Range (1., static_cast<double>(dv(i)));
+	      
+	      double idx = 0.;
+	      for (octave_idx_type i = 0; i <  new_dv(0); i++)
+		{
+		  OCTAVE_QUIT;
+
+		  lst(0) = Range(idx + 1., idx + d(i));
+		  ret(i) = args(0).do_index_op(lst, 0);
+		  idx += d(i);
+		  if (error_state)
+		    break;
+		}
+	  
+	      if (!error_state)
+		retval = ret;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!test
+%! x = reshape(1:20,5,4);
+%! c = mat2cell(x,[3,2],[3,1]);
+%! assert(c,{[1,6,11;2,7,12;3,8,13],[16;17;18];[4,9,14;5,10,15],[19;20]})
+
+%!test
+%! x = 'abcdefghij';
+%! c = mat2cell(x,1,[0,4,2,0,4,0]);
+%! empty1by0str = resize('',1,0);
+%! assert(c,{empty1by0str,'abcd','ef',empty1by0str,'ghij',empty1by0str})
+
+*/
+
+template <class NDA>
+Cell 
+do_cellslices_nda (const NDA& array, const idx_vector& lb, const idx_vector& ub)
+{
+  octave_idx_type n = lb.length (0);
+  Cell retval (1, n);
+  if (array.is_vector ())
+    {
+      for (octave_idx_type i = 0; i < n && ! error_state; i++)
+        retval(i) = array.index (idx_vector (lb(i), ub(i) + 1));
+    }
+  else
+    {
+      dim_vector dv = array.dims ();
+      octave_idx_type nl = 1;
+      for (int i = 0; i < dv.length () - 1; i++) nl *= dv(i);
+      for (octave_idx_type i = 0; i < n && ! error_state; i++)
+        {
+          // Do it with a single index to speed things up.
+          dv(dv.length () - 1) = ub(i) + 1 - lb(i);
+          retval(i) = array.index (idx_vector (nl*lb(i), nl*(ub(i) + 1))).reshape (dv);
+        }
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (cellslices, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{sl} =} cellslices (@var{x}, @var{lb}, @var{ub})\n\
+Given a vector @var{x}, this function produces a cell array of slices from the vector\n\
+determined by the index vectors @var{lb}, @var{ub}, for lower and upper bounds, respectively.\n\
+In other words, it is equivalent to the following code:\n\
+\n\
+ at example\n\
+ at group\n\
+n = length (lb);\n\
+sl = cell (1, n);\n\
+for i = 1:length (lb)\n\
+  sl@{i@} = x(lb(i):ub(i));\n\
+endfor\n\
+ at end group\n\
+ at end example\n\
+\n\
+If @var{X} is a matrix or array, indexing is done along the last dimension.\n\
+ at seealso{mat2cell}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length ();
+  if (nargin == 3)
+    {
+      octave_value x = args(0);
+      idx_vector lb = args(1).index_vector (), ub = args(2).index_vector ();
+      if (! error_state)
+        {
+          if (lb.is_colon () || ub.is_colon ())
+            error ("cellslices: invalid use of colon");
+          else if (lb.length (0) != ub.length (0))
+            error ("cellslices: the lengths of lb and ub must match");
+          else
+            {
+              Cell retcell;
+              if (! x.is_sparse_type () && x.is_matrix_type ())
+                {
+                  // specialize for some dense arrays.
+                  if (x.is_bool_type ())
+                    retcell = do_cellslices_nda (x.bool_array_value (), lb, ub);
+                  else if (x.is_char_matrix ())
+                    retcell = do_cellslices_nda (x.char_array_value (), lb, ub);
+                  else if (x.is_complex_type ())
+                    {
+                      if (x.is_single_type ())
+                        retcell = do_cellslices_nda (x.float_complex_array_value (), lb, ub);
+                      else
+                        retcell = do_cellslices_nda (x.complex_array_value (), lb, ub);
+                    }
+                  else
+                    {
+                      if (x.is_single_type ())
+                        retcell = do_cellslices_nda (x.float_array_value (), lb, ub);
+                      else
+                        retcell = do_cellslices_nda (x.array_value (), lb, ub);
+                    }
+                }
+              else
+                {
+                  // generic code.
+                  octave_idx_type n = lb.length (0);
+                  retcell = Cell (1, n);
+                  octave_idx_type nind = x.dims ().is_vector () ? 1 : x.ndims ();
+                  octave_value_list idx (nind, octave_value::magic_colon_t);
+                  for (octave_idx_type i = 0; i < n && ! error_state; i++)
+                    {
+                      idx(nind-1) = Range (static_cast<double> (lb(i)) + 1,
+                                           static_cast<double> (ub(i)) + 1);
+                      retcell(i) = x.do_index_op (idx);
+                    }
+                }
+              if (! error_state)
+                retval = retcell;
+            }
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+	  
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/chol.cc b/src/DLD-FUNCTIONS/chol.cc
new file mode 100644
index 0000000..2eb988f
--- /dev/null
+++ b/src/DLD-FUNCTIONS/chol.cc
@@ -0,0 +1,1286 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2005, 2006, 2007
+              John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2008, 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxCHOL.h"
+#include "dbleCHOL.h"
+#include "fCmplxCHOL.h"
+#include "floatCHOL.h"
+#include "SparseCmplxCHOL.h"
+#include "SparsedbleCHOL.h"
+#include "oct-spparms.h"
+#include "sparse-util.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (chol, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{r} =} chol (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}] =} chol (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} chol (@var{s})\n\
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} chol (@var{s}, 'vector')\n\
+ at deftypefnx {Loadable Function} {[@var{l}, @dots{}] =} chol (@dots{}, 'lower')\n\
+ at cindex Cholesky factorization\n\
+Compute the Cholesky factor, @var{r}, of the symmetric positive definite\n\
+matrix @var{a}, where\n\
+ at iftex\n\
+ at tex\n\
+$ R^T R = A $.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at var{r}' * @var{r} = @var{a}.\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+Called with one output argument @code{chol} fails if @var{a} or @var{s} is\n\
+not positive definite.  With two or more output arguments @var{p} flags\n\
+whether the matrix was positive definite and @code{chol} does not fail.  A\n\
+zero value indicated that the matrix was positive definite and the @var{r}\n\
+gives the factorization, and @var{p} will have a positive value otherwise.\n\
+\n\
+If called with 3 outputs then a sparsity preserving row/column permutation\n\
+is applied to @var{a} prior to the factorization.  That is @var{r}\n\
+is the factorization of @code{@var{a}(@var{q}, at var{q})} such that\n\
+ at iftex\n\
+ at tex\n\
+$ R^T R = Q^T A Q$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at var{r}' * @var{r} = @var{q}' * @var{a} * @var{q}.\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+The sparsity preserving permutation is generally returned as a matrix.\n\
+However, given the flag 'vector', @var{q} will be returned as a vector\n\
+such that\n\
+ at iftex\n\
+ at tex\n\
+$ R^T R = A (Q, Q)$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at var{r}' * @var{r} = a (@var{q}, @var{q}).\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+Called with either a sparse or full matrix and using the 'lower' flag,\n\
+ at code{chol} returns the lower triangular factorization such that\n\
+ at iftex\n\
+ at tex\n\
+$ L L^T = A $.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at var{l} * @var{l}' = @var{a}.\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+In general the lower triangular factorization is significantly faster for\n\
+sparse matrices.\n\
+ at seealso{cholinv, chol2inv}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  bool LLt = false;
+  bool vecout = false;
+
+  if (nargin < 1 || nargin > 3 || nargout > 3 
+      || (! args(0).is_sparse_type () && nargout > 2))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  int n = 1;
+  while (n < nargin && ! error_state)
+    {
+      std::string tmp = args(n++).string_value ();
+
+      if (! error_state )
+	{
+	  if (tmp.compare ("vector") == 0)
+	    vecout = true;
+	  else if (tmp.compare ("lower") == 0)
+	    LLt = true;
+	  else if (tmp.compare ("upper") == 0)
+	    LLt = false;
+	  else
+	    error ("chol: unexpected second or third input");
+	}
+      else
+	error ("chol: expecting trailing string arguments");
+    }
+
+  if (! error_state)
+    {
+      octave_value arg = args(0);
+    
+      octave_idx_type nr = arg.rows ();
+      octave_idx_type nc = arg.columns ();
+      bool natural = (nargout != 3);
+
+      int arg_is_empty = empty_arg ("chol", nr, nc);
+
+      if (arg_is_empty < 0)
+	return retval;
+      if (arg_is_empty > 0)
+	return octave_value (Matrix ());
+
+      if (arg.is_sparse_type ())
+	{
+	  if (arg.is_real_type ())
+	    {
+	      SparseMatrix m = arg.sparse_matrix_value ();
+
+	      if (! error_state)
+		{
+		  octave_idx_type info;
+		  SparseCHOL fact (m, info, natural);
+		  if (nargout == 3)
+		    {
+		      if (vecout)
+			retval(2) = fact.perm ();
+		      else
+			retval(2) = fact.Q();
+		    }
+
+		  if (nargout > 1 || info == 0)
+		    {
+		      retval(1) = fact.P();
+		      if (LLt)
+			retval(0) = fact.L();
+		      else
+			retval(0) = fact.R();
+		    }
+		  else
+		    error ("chol: matrix not positive definite");
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  octave_idx_type info;
+		  SparseComplexCHOL fact (m, info, natural);
+
+		  if (nargout == 3)
+		    {
+		      if (vecout)
+			retval(2) = fact.perm ();
+		      else
+			retval(2) = fact.Q();
+		    }
+	  
+		  if (nargout > 1 || info == 0)
+		    {
+		      retval(1) = fact.P();
+		      if (LLt)
+			retval(0) = fact.L();
+		      else
+			retval(0) = fact.R();
+		    }
+		  else
+		    error ("chol: matrix not positive definite");
+		}
+	    }
+	  else
+	    gripe_wrong_type_arg ("chol", arg);
+	}
+      else if (arg.is_single_type ())
+	{
+	  if (arg.is_real_type ())
+	    {
+	      FloatMatrix m = arg.float_matrix_value ();
+
+	      if (! error_state)
+		{
+		  octave_idx_type info;
+		  FloatCHOL fact (m, info);
+		  if (nargout == 2 || info == 0)
+		    {
+		      retval(1) = static_cast<float> (info);
+		      if (LLt)
+			retval(0) = fact.chol_matrix ().transpose ();
+		      else
+			retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    error ("chol: matrix not positive definite");
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  octave_idx_type info;
+		  FloatComplexCHOL fact (m, info);
+		  if (nargout == 2 || info == 0)
+		    {
+		      retval(1) = static_cast<float> (info);
+		      if (LLt)
+			retval(0) = fact.chol_matrix ().hermitian ();
+		      else
+			retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    error ("chol: matrix not positive definite");
+		}
+	    }
+	  else
+	    gripe_wrong_type_arg ("chol", arg);
+	}
+      else
+	{
+	  if (arg.is_real_type ())
+	    {
+	      Matrix m = arg.matrix_value ();
+
+	      if (! error_state)
+		{
+		  octave_idx_type info;
+		  CHOL fact (m, info);
+		  if (nargout == 2 || info == 0)
+		    {
+		      retval(1) = static_cast<double> (info);
+		      if (LLt)
+			retval(0) = fact.chol_matrix ().transpose ();
+		      else
+			retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    error ("chol: matrix not positive definite");
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      ComplexMatrix m = arg.complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  octave_idx_type info;
+		  ComplexCHOL fact (m, info);
+		  if (nargout == 2 || info == 0)
+		    {
+		      retval(1) = static_cast<double> (info);
+		      if (LLt)
+			retval(0) = fact.chol_matrix ().hermitian ();
+		      else
+			retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    error ("chol: matrix not positive definite");
+		}
+	    }
+	  else
+	    gripe_wrong_type_arg ("chol", arg);
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(chol ([2, 1; 1, 1]), [sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)], sqrt (eps));
+%!assert(chol (single([2, 1; 1, 1])), single([sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)]), sqrt (eps('single')));
+
+%!error chol ([1, 2; 3, 4]);
+%!error chol ([1, 2; 3, 4; 5, 6]);
+%!error <Invalid call to chol.*> chol ();
+%!error <unexpected second or third input.*> chol (1, 2);
+
+ */
+
+DEFUN_DLD (cholinv, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} cholinv (@var{a})\n\
+Use the Cholesky factorization to compute the inverse of the\n\
+symmetric positive definite matrix @var{a}.\n\
+ at seealso{chol, chol2inv}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+    
+      octave_idx_type nr = arg.rows ();
+      octave_idx_type nc = arg.columns ();
+
+      if (nr == 0 || nc == 0)
+	retval = Matrix ();
+      else
+	{
+	  if (arg.is_sparse_type ())
+	    {
+	      if (arg.is_real_type ())
+		{
+		  SparseMatrix m = arg.sparse_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      octave_idx_type info;
+		      SparseCHOL chol (m, info);
+		      if (info == 0)
+			retval = chol.inverse ();
+		      else
+			error ("cholinv: matrix not positive definite");
+		    }
+		}
+	      else if (arg.is_complex_type ())
+		{
+		  SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      octave_idx_type info;
+		      SparseComplexCHOL chol (m, info);
+		      if (info == 0)
+			retval = chol.inverse ();
+		      else
+			error ("cholinv: matrix not positive definite");
+		    }
+		}
+	      else
+		gripe_wrong_type_arg ("cholinv", arg);
+	    }
+	  else if (arg.is_single_type ())
+	    {
+	      if (arg.is_real_type ())
+		{
+		  FloatMatrix m = arg.float_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      octave_idx_type info;
+		      FloatCHOL chol (m, info);
+		      if (info == 0)
+			retval = chol.inverse ();
+		      else
+			error ("cholinv: matrix not positive definite");
+		    }
+		}
+	      else if (arg.is_complex_type ())
+		{
+		  FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      octave_idx_type info;
+		      FloatComplexCHOL chol (m, info);
+		      if (info == 0)
+			retval = chol.inverse ();
+		      else
+			error ("cholinv: matrix not positive definite");
+		    }
+		}
+	      else
+		gripe_wrong_type_arg ("chol", arg);
+	    }
+	  else
+	    {
+	      if (arg.is_real_type ())
+		{
+		  Matrix m = arg.matrix_value ();
+
+		  if (! error_state)
+		    {
+		      octave_idx_type info;
+		      CHOL chol (m, info);
+		      if (info == 0)
+			retval = chol.inverse ();
+		      else
+			error ("cholinv: matrix not positive definite");
+		    }
+		}
+	      else if (arg.is_complex_type ())
+		{
+		  ComplexMatrix m = arg.complex_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      octave_idx_type info;
+		      ComplexCHOL chol (m, info);
+		      if (info == 0)
+			retval = chol.inverse ();
+		      else
+			error ("cholinv: matrix not positive definite");
+		    }
+		}
+	      else
+		gripe_wrong_type_arg ("chol", arg);
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!shared A, Ainv
+%! A = [2,0.2;0.2,1];
+%! Ainv = inv(A);
+%!test
+%! Ainv1 = cholinv(A);
+%! assert (norm(Ainv-Ainv1),0,1e-10)
+%!testif HAVE_CHOLMOD
+%! Ainv2 = inv(sparse(A));
+%! assert (norm(Ainv-Ainv2),0,1e-10)
+%!testif HAVE_CHOLMOD
+%! Ainv3 = cholinv(sparse(A));
+%! assert (norm(Ainv-Ainv3),0,1e-10)
+%!testif HAVE_CHOLMOD
+%! Ainv4 = spcholinv(sparse(A));
+%! assert (norm(Ainv-Ainv4),0,1e-10)
+
+*/
+
+DEFUN_DLD (chol2inv, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} chol2inv (@var{u})\n\
+Invert a symmetric, positive definite square matrix from its Cholesky\n\
+decomposition, @var{u}.  Note that @var{u} should be an upper-triangular\n\
+matrix with positive diagonal elements.  @code{chol2inv (@var{u})}\n\
+provides @code{inv (@var{u}'*@var{u})} but it is much faster than\n\
+using @code{inv}.\n\
+ at seealso{chol, cholinv}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+    
+      octave_idx_type nr = arg.rows ();
+      octave_idx_type nc = arg.columns ();
+
+      if (nr == 0 || nc == 0)
+	retval = Matrix ();
+      else
+	{
+	  if (arg.is_sparse_type ())
+	    {
+	      if (arg.is_real_type ())
+		{
+		  SparseMatrix r = arg.sparse_matrix_value ();
+
+		  if (! error_state)
+		    retval = chol2inv (r);
+		}
+	      else if (arg.is_complex_type ())
+		{
+		  SparseComplexMatrix r = arg.sparse_complex_matrix_value ();
+
+		  if (! error_state)
+		    retval = chol2inv (r);
+		}
+	      else
+		gripe_wrong_type_arg ("chol2inv", arg);
+	    }
+	  else if (arg.is_single_type ())
+	    {
+	      if (arg.is_real_type ())
+		{
+		  FloatMatrix r = arg.float_matrix_value ();
+
+		  if (! error_state)
+		    retval = chol2inv (r);
+		}
+	      else if (arg.is_complex_type ())
+		{
+		  FloatComplexMatrix r = arg.float_complex_matrix_value ();
+
+		  if (! error_state)
+		    retval = chol2inv (r);
+		}
+	      else
+		gripe_wrong_type_arg ("chol2inv", arg);
+
+	    }
+	  else
+	    {
+	      if (arg.is_real_type ())
+		{
+		  Matrix r = arg.matrix_value ();
+
+		  if (! error_state)
+		    retval = chol2inv (r);
+		}
+	      else if (arg.is_complex_type ())
+		{
+		  ComplexMatrix r = arg.complex_matrix_value ();
+
+		  if (! error_state)
+		    retval = chol2inv (r);
+		}
+	      else
+		gripe_wrong_type_arg ("chol2inv", arg);
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (cholupdate, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholupdate (@var{R}, @var{u}, @var{op})\n\
+Update or downdate a Cholesky factorization.  Given an upper triangular\n\
+matrix @var{R} and a column vector @var{u}, attempt to determine another\n\
+upper triangular matrix @var{R1} such that\n\
+ at itemize @bullet\n\
+ at item\n\
+ at var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\
+if @var{op} is \"+\"\n\
+ at item\n\
+ at var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'\n\
+if @var{op} is \"-\"\n\
+ at end itemize\n\
+\n\
+If @var{op} is \"-\", @var{info} is set to\n\
+ at itemize\n\
+ at item 0 if the downdate was successful,\n\
+ at item 1 if @var{R}'*@var{R} - @var{u}*@var{u}' is not positive definite,\n\
+ at item 2 if @var{R} is singular.\n\
+ at end itemize\n\
+\n\
+If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
+ at seealso{chol, qrupdate}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin > 3 || nargin < 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argu = args(1);
+
+  if (argr.is_numeric_type () && argu.is_numeric_type ()
+      && (nargin < 3 || args(2).is_string ()))
+    {
+      octave_idx_type n = argr.rows ();
+
+      std::string op = (nargin < 3) ? "+" : args(2).string_value ();
+
+      bool down = op == "-";
+
+      if (down || op == "+")
+        if (argr.columns () == n && argu.rows () == n && argu.columns () == 1)
+          {
+            int err = 0;
+	    if (argr.is_single_type () || argu.is_single_type ())
+	      {
+		if (argr.is_real_type () && argu.is_real_type ())
+		  {
+		    // real case
+		    FloatMatrix R = argr.float_matrix_value ();
+		    FloatColumnVector u = argu.float_column_vector_value ();
+
+		    FloatCHOL fact;
+		    fact.set (R);
+
+		    if (down)
+		      err = fact.downdate (u);
+		    else
+		      fact.update (u);
+
+		    retval(0) = fact.chol_matrix ();
+		  }
+		else
+		  {
+		    // complex case
+		    FloatComplexMatrix R = argr.float_complex_matrix_value ();
+		    FloatComplexColumnVector u = argu.float_complex_column_vector_value ();
+
+		    FloatComplexCHOL fact;
+		    fact.set (R);
+
+		    if (down)
+		      err = fact.downdate (u);
+		    else
+		      fact.update (u);
+
+		    retval(0) = fact.chol_matrix ();
+		  }
+	      }
+	    else
+	      {
+		if (argr.is_real_type () && argu.is_real_type ())
+		  {
+		    // real case
+		    Matrix R = argr.matrix_value ();
+		    ColumnVector u = argu.column_vector_value ();
+
+		    CHOL fact;
+		    fact.set (R);
+
+		    if (down)
+		      err = fact.downdate (u);
+		    else
+		      fact.update (u);
+
+		    retval(0) = fact.chol_matrix ();
+		  }
+		else
+		  {
+		    // complex case
+		    ComplexMatrix R = argr.complex_matrix_value ();
+		    ComplexColumnVector u = argu.complex_column_vector_value ();
+
+		    ComplexCHOL fact;
+		    fact.set (R);
+
+		    if (down)
+		      err = fact.downdate (u);
+		    else
+		      fact.update (u);
+
+		    retval(0) = fact.chol_matrix ();
+		  }
+	      }
+
+            if (nargout > 1)
+              retval(1) = err;
+            else if (err == 1)
+              error ("cholupdate: downdate violates positiveness");
+            else if (err == 2)
+              error ("cholupdate: singular matrix");
+          }
+        else
+          error ("cholupdate: dimension mismatch");
+      else
+        error ("cholupdate: op must be \"+\" or \"-\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!shared A, u, Ac, uc
+%! A = [  0.436997  -0.131721   0.124120  -0.061673 ;
+%!       -0.131721   0.738529   0.019851  -0.140295 ;
+%!        0.124120   0.019851   0.354879  -0.059472 ;
+%!       -0.061673  -0.140295  -0.059472   0.600939 ];
+%! 
+%! u = [  0.98950 ;
+%!        0.39844 ;
+%!        0.63484 ;
+%!        0.13351 ];
+%! Ac = [  0.5585528 + 0.0000000i  -0.1662088 - 0.0315341i   0.0107873 + 0.0236411i  -0.0276775 - 0.0186073i ;
+%!        -0.1662088 + 0.0315341i   0.6760061 + 0.0000000i   0.0011452 - 0.0475528i   0.0145967 + 0.0247641i ;
+%!         0.0107873 - 0.0236411i   0.0011452 + 0.0475528i   0.6263149 - 0.0000000i  -0.1585837 - 0.0719763i ;
+%!        -0.0276775 + 0.0186073i   0.0145967 - 0.0247641i  -0.1585837 + 0.0719763i   0.6034234 - 0.0000000i ];
+%! 
+%! uc = [ 0.54267 + 0.91519i ;
+%!        0.99647 + 0.43141i ;
+%!        0.83760 + 0.68977i ;
+%!        0.39160 + 0.90378i ];
+
+
+
+%!test
+%! R = chol(A);
+%! 
+%! R1 = cholupdate(R,u);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - R'*R - u*u',Inf) < 1e1*eps)
+%! 
+%! R1 = cholupdate(R1,u,"-");
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1 - R,Inf) < 1e1*eps)
+%! 
+%!test
+%! R = chol(Ac);
+%! 
+%! R1 = cholupdate(R,uc);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - R'*R - uc*uc',Inf) < 1e1*eps)
+%! 
+%! R1 = cholupdate(R1,uc,"-");
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1 - R,Inf) < 1e1*eps)
+
+%!test
+%! R = chol(single(A));
+%! 
+%! R1 = cholupdate(R,single(u));
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - R'*R - single(u*u'),Inf) < 1e1*eps('single'))
+%! 
+%! R1 = cholupdate(R1,single(u),"-");
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1 - R,Inf) < 2e1*eps('single'))
+%! 
+%!test
+%! R = chol(single(Ac));
+%! 
+%! R1 = cholupdate(R,single(uc));
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - R'*R - single(uc*uc'),Inf) < 1e1*eps('single'))
+%! 
+%! R1 = cholupdate(R1,single(uc),"-");
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1 - R,Inf) < 2e1*eps('single'))
+*/
+
+DEFUN_DLD (cholinsert, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholinsert (@var{R}, @var{j}, @var{u})\n\
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian\n\
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,\n\
+return the Cholesky at tie{}factorization of\n\
+ at var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and\n\
+ at w{p = [1:j-1,j+1:n+1]}.  @w{u(j)} should be positive.\n\
+On return, @var{info} is set to\n\
+ at itemize\n\
+ at item 0 if the insertion was successful,\n\
+ at item 1 if @var{A1} is not positive definite,\n\
+ at item 2 if @var{R} is singular.\n\
+ at end itemize\n\
+\n\
+If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
+ at seealso{chol, cholupdate, choldelete}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argj = args(1);
+  octave_value argu = args(2);
+
+  if (argr.is_numeric_type () && argu.is_numeric_type ()
+      && argj.is_real_scalar ())
+    {
+      octave_idx_type n = argr.rows ();
+      octave_idx_type j = argj.scalar_value ();
+
+      if (argr.columns () == n && argu.rows () == n+1 && argu.columns () == 1)
+        {
+          if (j > 0 && j <= n+1)
+            {
+              int err = 0;
+	      if (argr.is_single_type () || argu.is_single_type ())
+		{
+		  if (argr.is_real_type () && argu.is_real_type ())
+		    {
+		      // real case
+		      FloatMatrix R = argr.float_matrix_value ();
+		      FloatColumnVector u = argu.float_column_vector_value ();
+
+		      FloatCHOL fact;
+		      fact.set (R);
+		      err = fact.insert_sym (u, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    {
+		      // complex case
+		      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+		      FloatComplexColumnVector u = argu.float_complex_column_vector_value ();
+
+		      FloatComplexCHOL fact;
+		      fact.set (R);
+		      err = fact.insert_sym (u, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		}
+	      else
+		{
+		  if (argr.is_real_type () && argu.is_real_type ())
+		    {
+		      // real case
+		      Matrix R = argr.matrix_value ();
+		      ColumnVector u = argu.column_vector_value ();
+
+		      CHOL fact;
+		      fact.set (R);
+		      err = fact.insert_sym (u, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    {
+		      // complex case
+		      ComplexMatrix R = argr.complex_matrix_value ();
+		      ComplexColumnVector u = argu.complex_column_vector_value ();
+
+		      ComplexCHOL fact;
+		      fact.set (R);
+		      err = fact.insert_sym (u, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		}
+
+              if (nargout > 1)
+                retval(1) = err;
+              else if (err == 1)
+                error ("cholinsert: insertion violates positiveness");
+              else if (err == 2)
+                error ("cholinsert: singular matrix");
+              else if (err == 3)
+                error ("cholinsert: diagonal element must be real");
+            }
+          else
+            error ("cholinsert: index out of range");
+        }
+      else
+        error ("cholinsert: dimension mismatch");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! u2 = [  0.35080 ;
+%!         0.63930 ;
+%!         3.31057 ;
+%!        -0.13825 ;
+%!         0.45266 ];
+%!
+%! R = chol(A);
+%! 
+%! j = 3; p = [1:j-1, j+1:5];
+%! R1 = cholinsert(R,j,u2); A1 = R1'*R1;
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(A1(p,p) - A,Inf) < 1e1*eps)
+%! 
+%!test
+%! u2 = [  0.35080  + 0.04298i;
+%!         0.63930  + 0.23778i;
+%!         3.31057  + 0.00000i;
+%!        -0.13825  + 0.19879i;
+%!         0.45266  + 0.50020i];
+%!
+%! R = chol(Ac);
+%! 
+%! j = 3; p = [1:j-1, j+1:5];
+%! R1 = cholinsert(R,j,u2); A1 = R1'*R1;
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(A1(p,p) - Ac,Inf) < 1e1*eps)
+%! 
+
+%!test
+%! u2 = single ([  0.35080 ;
+%!                 0.63930 ;
+%!                 3.31057 ;
+%!                -0.13825 ;
+%!                 0.45266 ]);
+%!
+%! R = chol(single(A));
+%! 
+%! j = 3; p = [1:j-1, j+1:5];
+%! R1 = cholinsert(R,j,u2); A1 = R1'*R1;
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(A1(p,p) - A,Inf) < 1e1*eps('single'))
+%! 
+%!test
+%! u2 = single ([  0.35080  + 0.04298i;
+%!                 0.63930  + 0.23778i;
+%!                 3.31057  + 0.00000i;
+%!                -0.13825  + 0.19879i;
+%!                 0.45266  + 0.50020i]);
+%!
+%! R = chol(single(Ac));
+%! 
+%! j = 3; p = [1:j-1, j+1:5];
+%! R1 = cholinsert(R,j,u2); A1 = R1'*R1;
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(A1(p,p) - single(Ac),Inf) < 1e1*eps('single'))
+%! 
+*/
+
+DEFUN_DLD (choldelete, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})\n\
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian\n\
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,\n\
+return the Cholesky at tie{}factorization of @w{A(p,p)}, where @w{p = [1:j-1,j+1:n+1]}.\n\
+ at seealso{chol, cholupdate, cholinsert}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin != 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argj = args(1);
+
+  if (argr.is_numeric_type () && argj.is_real_scalar ())
+    {
+      octave_idx_type n = argr.rows ();
+      octave_idx_type j = argj.scalar_value ();
+
+      if (argr.columns () == n)
+        {
+          if (j > 0 && j <= n)
+            {
+	      if (argr.is_single_type ())
+		{
+		  if (argr.is_real_type ())
+		    {
+		      // real case
+		      FloatMatrix R = argr.float_matrix_value ();
+
+		      FloatCHOL fact;
+		      fact.set (R);
+		      fact.delete_sym (j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    {
+		      // complex case
+		      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+		      FloatComplexCHOL fact;
+		      fact.set (R);
+		      fact.delete_sym (j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		}
+	      else
+		{
+		  if (argr.is_real_type ())
+		    {
+		      // real case
+		      Matrix R = argr.matrix_value ();
+
+		      CHOL fact;
+		      fact.set (R);
+		      fact.delete_sym (j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    {
+		      // complex case
+		      ComplexMatrix R = argr.complex_matrix_value ();
+
+		      ComplexCHOL fact;
+		      fact.set (R);
+		      fact.delete_sym (j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		}
+            }
+          else
+            error ("choldelete: index out of range");
+        }
+      else
+        error ("choldelete: dimension mismatch");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! R = chol(A);
+%! 
+%! j = 3; p = [1:j-1,j+1:4];
+%! R1 = choldelete(R,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - A(p,p),Inf) < 1e1*eps)
+%! 
+%!test
+%! R = chol(Ac);
+%! 
+%! j = 3; p = [1:j-1,j+1:4];
+%! R1 = choldelete(R,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - Ac(p,p),Inf) < 1e1*eps)
+
+%!test
+%! R = chol(single(A));
+%! 
+%! j = 3; p = [1:j-1,j+1:4];
+%! R1 = choldelete(R,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - single(A(p,p)),Inf) < 1e1*eps('single'))
+%! 
+%!test
+%! R = chol(single(Ac));
+%! 
+%! j = 3; p = [1:j-1,j+1:4];
+%! R1 = choldelete(R,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - single(Ac(p,p)),Inf) < 1e1*eps('single'))
+*/
+
+DEFUN_DLD (cholshift, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{R1} =} cholshift (@var{R}, @var{i}, @var{j})\n\
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian\n\
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,\n\
+return the Cholesky at tie{}factorization of\n\
+ at w{@var{A}(p,p)}, where @w{p} is the permutation @*\n\
+ at code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
+ or @*\n\
+ at code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*\n\
+\n\
+ at seealso{chol, cholinsert, choldelete}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argi = args(1);
+  octave_value argj = args(2);
+
+  if (argr.is_numeric_type () && argi.is_real_scalar () && argj.is_real_scalar ())
+    {
+      octave_idx_type n = argr.rows ();
+      octave_idx_type i = argi.scalar_value ();
+      octave_idx_type j = argj.scalar_value ();
+
+      if (argr.columns () == n)
+        {
+          if (j > 0 && j <= n+1 && i > 0 && i <= n+1)
+            {
+
+	      if (argr.is_single_type () && argi.is_single_type () && 
+		  argj.is_single_type ())
+		{
+		  if (argr.is_real_type ())
+		    {
+		      // real case
+		      FloatMatrix R = argr.float_matrix_value ();
+
+		      FloatCHOL fact;
+		      fact.set (R);
+		      fact.shift_sym (i-1, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    {
+		      // complex case
+		      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+		      FloatComplexCHOL fact;
+		      fact.set (R);
+		      fact.shift_sym (i-1, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		}
+	      else
+		{
+		  if (argr.is_real_type ())
+		    {
+		      // real case
+		      Matrix R = argr.matrix_value ();
+
+		      CHOL fact;
+		      fact.set (R);
+		      fact.shift_sym (i-1, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		  else
+		    {
+		      // complex case
+		      ComplexMatrix R = argr.complex_matrix_value ();
+
+		      ComplexCHOL fact;
+		      fact.set (R);
+		      fact.shift_sym (i-1, j-1);
+
+		      retval(0) = fact.chol_matrix ();
+		    }
+		}
+            }
+          else
+            error ("cholshift: index out of range");
+        }
+      else
+        error ("cholshift: dimension mismatch");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! R = chol(A);
+%! 
+%! i = 1; j = 3; p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - A(p,p),Inf) < 1e1*eps)
+%! 
+%! j = 1; i = 3; p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - A(p,p),Inf) < 1e1*eps)
+%! 
+%!test
+%! R = chol(Ac);
+%! 
+%! i = 1; j = 3; p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - Ac(p,p),Inf) < 1e1*eps)
+%! 
+%! j = 1; i = 3; p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - Ac(p,p),Inf) < 1e1*eps)
+
+%!test
+%! R = chol(single(A));
+%! 
+%! i = 1; j = 3; p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - single(A(p,p)),Inf) < 1e1*eps('single'))
+%! 
+%! j = 1; i = 3; p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - single(A(p,p)),Inf) < 1e1*eps('single'))
+%! 
+%!test
+%! R = chol(single(Ac));
+%! 
+%! i = 1; j = 3; p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - single(Ac(p,p)),Inf) < 1e1*eps('single'))
+%! 
+%! j = 1; i = 3; p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift(R,i,j);
+%! 
+%! assert(norm(triu(R1)-R1,Inf) == 0)
+%! assert(norm(R1'*R1 - single(Ac(p,p)),Inf) < 1e1*eps('single'))
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/DLD-FUNCTIONS/colamd.cc b/src/DLD-FUNCTIONS/colamd.cc
new file mode 100644
index 0000000..c73f844
--- /dev/null
+++ b/src/DLD-FUNCTIONS/colamd.cc
@@ -0,0 +1,779 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This is the octave interface to colamd, which bore the copyright given
+// in the help of the functions.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+#include <vector>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "pager.h"
+#include "ov-re-mat.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#include "oct-sparse.h"
+#include "oct-locbuf.h"
+
+#ifdef IDX_TYPE_LONG
+#define COLAMD_NAME(name) colamd_l ## name
+#define SYMAMD_NAME(name) symamd_l ## name
+#else
+#define COLAMD_NAME(name) colamd ## name
+#define SYMAMD_NAME(name) symamd ## name
+#endif
+
+// The symmetric column elimination tree code take from the Davis LDL code. 
+// Copyright given elsewhere in this file.
+static void
+symetree (const octave_idx_type *ridx, const octave_idx_type *cidx, 
+	  octave_idx_type *Parent, octave_idx_type *P, octave_idx_type n)
+{
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Flag, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Pinv, (P ? n : 0));
+  if (P)
+    // If P is present then compute Pinv, the inverse of P
+    for (octave_idx_type k = 0 ; k < n ; k++)
+      Pinv [P [k]] = k ;
+
+  for (octave_idx_type k = 0 ; k < n ; k++)
+    {
+      // L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k)
+      Parent [k] = n ;	              // parent of k is not yet known 
+      Flag [k] = k ;		      // mark node k as visited 
+      octave_idx_type kk = (P) ? (P [k]) : (k) ;  // kth original, or permuted, column
+      octave_idx_type p2 = cidx [kk+1] ;
+      for (octave_idx_type p = cidx [kk] ; p < p2 ; p++)
+	{
+	  // A (i,k) is nonzero (original or permuted A)
+	  octave_idx_type i = (Pinv) ? (Pinv [ridx [p]]) : (ridx [p]) ;
+	  if (i < k)
+	    {
+	      // follow path from i to root of etree, stop at flagged node 
+	      for ( ; Flag [i] != k ; i = Parent [i])
+		{
+		  // find parent of i if not yet determined
+		  if (Parent [i] == n)
+		    Parent [i] = k ;
+		  Flag [i] = k ;	// mark i as visited
+		}
+	    }
+	}
+    }
+}
+
+// The elimination tree post-ordering code below is taken from SuperLU
+static inline octave_idx_type
+make_set (octave_idx_type i, octave_idx_type *pp)
+{
+  pp[i] = i;
+  return i;
+}
+
+static inline octave_idx_type
+link (octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
+{
+  pp[s] = t;
+  return t;
+}
+
+static inline octave_idx_type
+find (octave_idx_type i, octave_idx_type *pp)
+{
+  register octave_idx_type p, gp;
+    
+  p = pp[i];
+  gp = pp[p];
+
+  while (gp != p)
+    {
+      pp[i] = gp;
+      i = gp;
+      p = pp[i];
+      gp = pp[p];
+    }
+
+  return p;
+}
+
+static octave_idx_type
+etdfs (octave_idx_type v, octave_idx_type *first_kid, 
+       octave_idx_type *next_kid, octave_idx_type *post, 
+       octave_idx_type postnum)
+{
+  for (octave_idx_type w = first_kid[v]; w != -1; w = next_kid[w])
+    postnum = etdfs (w, first_kid, next_kid, post, postnum);
+
+  post[postnum++] = v;
+
+  return postnum;
+}
+
+static void
+tree_postorder (octave_idx_type n, octave_idx_type *parent,
+		octave_idx_type *post)
+{
+  // Allocate storage for working arrays and results
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, first_kid, n+1);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, next_kid, n+1);
+
+  // Set up structure describing children
+  for (octave_idx_type v = 0; v <= n; first_kid[v++] = -1)
+    /* do nothing */;
+
+  for (octave_idx_type v = n-1; v >= 0; v--) 
+    {
+      octave_idx_type dad = parent[v];
+      next_kid[v] = first_kid[dad];
+      first_kid[dad] = v;
+    }
+
+  // Depth-first search from dummy root vertex #n
+  etdfs (n, first_kid, next_kid, post, 0);
+}
+
+static void
+coletree (const octave_idx_type *ridx, const octave_idx_type *colbeg,
+	  octave_idx_type *colend, octave_idx_type *parent, 
+	  octave_idx_type nr, octave_idx_type nc)
+{
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, root, nc);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, pp, nc);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, firstcol, nr);
+
+  // Compute firstcol[row] = first nonzero column in row
+  for (octave_idx_type row = 0; row < nr; firstcol[row++] = nc)
+    /* do nothing */;
+
+  for (octave_idx_type col = 0; col < nc; col++) 
+    for (octave_idx_type p = colbeg[col]; p < colend[col]; p++) 
+      {
+	octave_idx_type row = ridx[p];
+	if (firstcol[row] > col)
+	  firstcol[row] = col;
+      }
+
+  // Compute etree by Liu's algorithm for symmetric matrices,
+  // except use (firstcol[r],c) in place of an edge (r,c) of A.
+  // Thus each row clique in A'*A is replaced by a star
+  // centered at its first vertex, which has the same fill.
+  for (octave_idx_type col = 0; col < nc; col++) 
+    {
+      octave_idx_type cset = make_set (col, pp);
+      root[cset] = col;
+      parent[col] = nc; 
+      for (octave_idx_type p = colbeg[col]; p < colend[col]; p++) 
+	{
+	  octave_idx_type row = firstcol[ridx[p]];
+	  if (row >= col) 
+	    continue;
+	  octave_idx_type rset = find (row, pp);
+	  octave_idx_type rroot = root[rset];
+	  if (rroot != col) 
+	    {
+	      parent[rroot] = col;
+	      cset = link (cset, rset, pp);
+	      root[cset] = col;
+	    }
+	}
+    }
+}
+
+DEFUN_DLD (colamd, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} colamd (@var{s})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} colamd (@var{s}, @var{knobs})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{s})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{s}, @var{knobs})\n\
+\n\
+Column approximate minimum degree permutation.  @code{@var{p} = colamd\n\
+(@var{s})} returns the column approximate minimum degree permutation\n\
+vector for the sparse matrix @var{s}.  For a non-symmetric matrix @var{s},\n\
+ at code{@var{s} (:, at var{p})} tends to have sparser LU factors than @var{s}.\n\
+The Cholesky factorization of @code{@var{s} (:, at var{p})' * @var{s}\n\
+(:, at var{p})} also tends to be sparser than that of @code{@var{s}' *\n\
+ at var{s}}.\n\
+\n\
+ at var{knobs} is an optional one- to three-element input vector.  If @var{s} is\n\
+m-by-n, then rows with more than @code{max(16, at var{knobs}(1)*sqrt(n))} entries\n\
+are ignored.  Columns with more than @code{max(16,knobs(2)*sqrt(min(m,n)))}\n\
+entries are removed prior to ordering, and ordered last in the output\n\
+permutation @var{p}.  Only completely dense rows or columns are removed\n\
+if @code{@var{knobs} (1)} and @code{@var{knobs} (2)} are < 0, respectively.\n\
+If @code{@var{knobs} (3)} is nonzero, @var{stats} and @var{knobs} are\n\
+printed.  The default is @code{@var{knobs} = [10 10 0]}.  Note that\n\
+ at var{knobs} differs from earlier versions of colamd\n\
+\n\
+ at var{stats} is an optional 20-element output vector that provides data\n\
+about the ordering and the validity of the input matrix @var{s}.  Ordering\n\
+statistics are in @code{@var{stats} (1:3)}.  @code{@var{stats} (1)} and\n\
+ at code{@var{stats} (2)} are the number of dense or empty rows and columns\n\
+ignored by COLAMD and @code{@var{stats} (3)} is the number of garbage\n\
+collections performed on the internal data structure used by COLAMD\n\
+(roughly of size @code{2.2 * nnz(@var{s}) + 4 * @var{m} + 7 * @var{n}}\n\
+integers).\n\
+\n\
+Octave built-in functions are intended to generate valid sparse matrices,\n\
+with no duplicate entries, with ascending row indices of the nonzeros\n\
+in each column, with a non-negative number of entries in each column (!)\n\
+and so on.  If a matrix is invalid, then COLAMD may or may not be able\n\
+to continue.  If there are duplicate entries (a row index appears two or\n\
+more times in the same column) or if the row indices in a column are out\n\
+of order, then COLAMD can correct these errors by ignoring the duplicate\n\
+entries and sorting each column of its internal copy of the matrix\n\
+ at var{s} (the input matrix @var{s} is not repaired, however).  If a matrix\n\
+is invalid in other ways then COLAMD cannot continue, an error message is\n\
+printed, and no output arguments (@var{p} or @var{stats}) are returned.\n\
+COLAMD is thus a simple way to check a sparse matrix to see if it's\n\
+valid.\n\
+\n\
+ at code{@var{stats} (4:7)} provide information if COLAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if\n\
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is\n\
+unsorted or contains duplicate entries, or zero if no such column exists.\n\
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row\n\
+index in the column index given by @code{@var{stats} (5)}, or zero if no\n\
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate\n\
+or out-of-order row indices.  @code{@var{stats} (8:20)} is always zero in\n\
+the current version of COLAMD (reserved for future use).\n\
+\n\
+The ordering is followed by a column elimination tree post-ordering.\n\
+\n\
+The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
+Davis (davis@@cise.ufl.edu), University of Florida.  The algorithm was\n\
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
+Ng, Oak Ridge National Laboratory.  (see\n\
+ at url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
+ at seealso{colperm, symamd}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_COLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+ 
+  if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 2)
+    print_usage ();
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, COLAMD_KNOBS);      
+      COLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin == 2)
+	{
+	  NDArray User_knobs = args(1).array_value ();
+	  int nel_User_knobs = User_knobs.length ();
+	  
+	  if (nel_User_knobs > 0) 
+	    knobs [COLAMD_DENSE_ROW] = User_knobs (0);
+	  if (nel_User_knobs > 1) 
+	    knobs [COLAMD_DENSE_COL] = User_knobs (1) ;
+	  if (nel_User_knobs > 2) 
+	    spumoni = static_cast<int> (User_knobs (2));
+
+	  // print knob settings if spumoni is set
+	  if (spumoni)
+	    {
+
+	      octave_stdout << "\ncolamd version " << COLAMD_MAIN_VERSION << "."
+			    <<  COLAMD_SUB_VERSION << ", " << COLAMD_DATE << ":\n";
+
+	      if (knobs [COLAMD_DENSE_ROW] >= 0)
+		octave_stdout << "knobs(1): " << User_knobs (0) 
+			      << ", rows with > max(16,"
+			      << knobs [COLAMD_DENSE_ROW] << "*sqrt(size(A,2)))"
+			      << " entries removed\n";
+	      else
+		octave_stdout << "knobs(1): " << User_knobs (0)
+			      << ", only completely dense rows removed\n";
+
+	      if (knobs [COLAMD_DENSE_COL] >= 0)
+		octave_stdout << "knobs(2): " << User_knobs (1) 
+			      << ", cols with > max(16,"
+			      << knobs [COLAMD_DENSE_COL] << "*sqrt(size(A)))"
+			      << " entries removed\n";
+	      else
+		octave_stdout << "knobs(2): " << User_knobs (1)
+			      << ", only completely dense columns removed\n";
+
+	      octave_stdout << "knobs(3): " << User_knobs (2) 
+			    << ", statistics and knobs printed\n";
+
+	    }
+	}
+      
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      SparseComplexMatrix scm;
+      SparseMatrix sm;
+
+      if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      scm = args(0). sparse_complex_matrix_value ();
+	      n_row = scm.rows ();
+	      n_col = scm.cols ();
+	      nnz = scm.nzmax ();
+	      ridx = scm.xridx ();
+	      cidx = scm.xcidx ();
+	    }
+	  else
+	    {
+	      sm = args(0).sparse_matrix_value ();
+
+	      n_row = sm.rows ();
+	      n_col = sm.cols ();
+	      nnz = sm.nzmax ();
+	      ridx = sm.xridx ();
+	      cidx = sm.xcidx ();
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type ())
+	    sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+	  else
+	    sm = SparseMatrix (args(0).matrix_value ());
+
+	  n_row = sm.rows ();
+	  n_col = sm.cols ();
+	  nnz = sm.nzmax ();
+	  ridx = sm.xridx ();
+	  cidx = sm.xcidx ();
+	}
+
+      // Allocate workspace for colamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
+      for (octave_idx_type i = 0; i < n_col+1; i++)
+	p[i] = cidx [i];
+
+      octave_idx_type Alen = COLAMD_NAME (_recommended) (nnz, n_row, n_col);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
+      for (octave_idx_type i = 0; i < nnz; i++)
+	A[i] = ridx [i];
+
+      // Order the columns (destroys A)
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
+      if (! COLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats))
+	{
+	  COLAMD_NAME (_report) (stats) ;
+	  error ("colamd: internal error!");
+	  return retval;
+	}
+
+      // column elimination tree post-ordering (reuse variables)
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col + 1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, colend, n_col + 1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
+
+      for (octave_idx_type i = 0; i < n_col; i++)
+	{
+	  colbeg[i] = cidx[p[i]];
+	  colend[i] = cidx[p[i]+1];
+	}
+
+      coletree (ridx, colbeg, colend, etree, n_row, n_col);
+
+      // Calculate the tree post-ordering
+      tree_postorder (n_col, etree, colbeg);
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+	out_perm(i) = p [colbeg [i]] + 1;
+
+      retval(0) = out_perm;
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+	COLAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+	{
+	  NDArray out_stats (dim_vector (1, COLAMD_STATS));
+	  for (octave_idx_type i = 0 ; i < COLAMD_STATS ; i++)
+	    out_stats (i) = stats [i] ;
+	  retval(1) = out_stats;
+
+	  // fix stats (5) and (6), for 1-based information on 
+	  // jumbled matrix.  note that this correction doesn't 
+	  // occur if symamd returns FALSE
+	  out_stats (COLAMD_INFO1) ++ ; 
+	  out_stats (COLAMD_INFO2) ++ ; 
+	}
+    }
+
+#else
+
+  error ("colamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (symamd, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} symamd (@var{s})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} symamd (@var{s}, @var{knobs})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{s})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{s}, @var{knobs})\n\
+\n\
+For a symmetric positive definite matrix @var{s}, returns the permutation\n\
+vector p such that @code{@var{s} (@var{p}, @var{p})} tends to have a\n\
+sparser Cholesky factor than @var{s}.  Sometimes SYMAMD works well for\n\
+symmetric indefinite matrices too.  The matrix @var{s} is assumed to be\n\
+symmetric; only the strictly lower triangular part is referenced.  @var{s}\n\
+must be square.\n\
+\n\
+ at var{knobs} is an optional one- to two-element input vector.  If @var{s} is\n\
+n-by-n, then rows and columns with more than\n\
+ at code{max(16, at var{knobs}(1)*sqrt(n))} entries are removed prior to ordering,\n\
+and ordered last in the output permutation @var{p}.  No rows/columns are\n\
+removed if @code{@var{knobs}(1) < 0}.  If @code{@var{knobs} (2)} is nonzero,\n\
+ at code{stats} and @var{knobs} are printed.  The default is @code{@var{knobs} \n\
+= [10 0]}.  Note that @var{knobs} differs from earlier versions of symamd.\n\
+\n\
+ at var{stats} is an optional 20-element output vector that provides data\n\
+about the ordering and the validity of the input matrix @var{s}.  Ordering\n\
+statistics are in @code{@var{stats} (1:3)}.  @code{@var{stats} (1) =\n\
+ at var{stats} (2)} is the number of dense or empty rows and columns\n\
+ignored by SYMAMD and @code{@var{stats} (3)} is the number of garbage\n\
+collections performed on the internal data structure used by SYMAMD\n\
+(roughly of size @code{8.4 * nnz (tril (@var{s}, -1)) + 9 * @var{n}}\n\
+integers).\n\
+\n\
+Octave built-in functions are intended to generate valid sparse matrices,\n\
+with no duplicate entries, with ascending row indices of the nonzeros\n\
+in each column, with a non-negative number of entries in each column (!)\n\
+and so on.  If a matrix is invalid, then SYMAMD may or may not be able\n\
+to continue.  If there are duplicate entries (a row index appears two or\n\
+more times in the same column) or if the row indices in a column are out\n\
+of order, then SYMAMD can correct these errors by ignoring the duplicate\n\
+entries and sorting each column of its internal copy of the matrix S (the\n\
+input matrix S is not repaired, however).  If a matrix is invalid in\n\
+other ways then SYMAMD cannot continue, an error message is printed, and\n\
+no output arguments (@var{p} or @var{stats}) are returned.  SYMAMD is\n\
+thus a simple way to check a sparse matrix to see if it's valid.\n\
+\n\
+ at code{@var{stats} (4:7)} provide information if SYMAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1\n\
+if invalid.  @code{@var{stats} (5)} is the rightmost column index that\n\
+is unsorted or contains duplicate entries, or zero if no such column\n\
+exists.  @code{@var{stats} (6)} is the last seen duplicate or out-of-order\n\
+row index in the column index given by @code{@var{stats} (5)}, or zero\n\
+if no such row index exists.  @code{@var{stats} (7)} is the number of\n\
+duplicate or out-of-order row indices.  @code{@var{stats} (8:20)} is\n\
+always zero in the current version of SYMAMD (reserved for future use).\n\
+\n\
+The ordering is followed by a column elimination tree post-ordering.\n\
+\n\
+\n\
+The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
+Davis (davis@@cise.ufl.edu), University of Florida.  The algorithm was\n\
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
+Ng, Oak Ridge National Laboratory.  (see\n\
+ at url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
+ at seealso{colperm, colamd}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_COLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+ 
+  if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 2)
+    print_usage ();
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, COLAMD_KNOBS);
+      COLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin == 2)
+	{
+	  NDArray User_knobs = args(1).array_value ();
+	  int nel_User_knobs = User_knobs.length ();
+	  
+	  if (nel_User_knobs > 0) 
+	    knobs [COLAMD_DENSE_ROW] = User_knobs (COLAMD_DENSE_ROW);
+	  if (nel_User_knobs > 1) 
+	    spumoni = static_cast<int> (User_knobs (1));
+	}
+
+      // print knob settings if spumoni is set
+      if (spumoni > 0)
+	octave_stdout << "symamd: dense row/col fraction: " 
+		      << knobs [COLAMD_DENSE_ROW] << std::endl;
+      
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      scm = args(0).sparse_complex_matrix_value ();
+	      n_row = scm.rows ();
+	      n_col = scm.cols ();
+	      nnz = scm.nzmax ();
+	      ridx = scm.xridx ();
+	      cidx = scm.xcidx ();
+	    }
+	  else
+	    {
+	      sm = args(0).sparse_matrix_value ();
+	      n_row = sm.rows ();
+	      n_col = sm.cols ();
+	      nnz = sm.nzmax ();
+	      ridx = sm.xridx ();
+	      cidx = sm.xcidx ();
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type ())
+	    sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+	  else
+	    sm = SparseMatrix (args(0).matrix_value ());
+	  
+	  n_row = sm.rows ();
+	  n_col = sm.cols ();
+	  nnz = sm.nzmax ();
+	  ridx = sm.xridx ();
+	  cidx = sm.xcidx ();
+	}
+
+      if (n_row != n_col)
+	{
+	  error ("symamd: matrix must be square");
+	  return retval;
+	}
+
+      // Allocate workspace for symamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
+      if (!SYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, &calloc, &free))
+	{
+	  SYMAMD_NAME (_report) (stats) ;
+	  error ("symamd: internal error!") ;
+	  return retval;
+	}
+
+      // column elimination tree post-ordering
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
+      symetree (ridx, cidx, etree, perm, n_col);
+
+      // Calculate the tree post-ordering
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
+      tree_postorder (n_col, etree, post);
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+	out_perm(i) = perm [post [i]] + 1;
+
+      retval(0) = out_perm;
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+	SYMAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+	{
+	  NDArray out_stats (dim_vector (1, COLAMD_STATS));
+	  for (octave_idx_type i = 0 ; i < COLAMD_STATS ; i++)
+	    out_stats (i) = stats [i] ;
+	  retval(1) = out_stats;
+
+	  // fix stats (5) and (6), for 1-based information on 
+	  // jumbled matrix.  note that this correction doesn't 
+	  // occur if symamd returns FALSE
+	  out_stats (COLAMD_INFO1) ++ ; 
+	  out_stats (COLAMD_INFO2) ++ ; 
+	}
+    }
+
+#else
+
+  error ("symamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (etree, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} etree (@var{s})\n\
+ at deftypefnx {Loadable Function} {@var{p} =} etree (@var{s}, @var{typ})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{s}, @var{typ})\n\
+\n\
+Returns the elimination tree for the matrix @var{s}.  By default @var{s}\n\
+is assumed to be symmetric and the symmetric elimination tree is\n\
+returned.  The argument @var{typ} controls whether a symmetric or\n\
+column elimination tree is returned.  Valid values of @var{typ} are\n\
+'sym' or 'col', for symmetric or column elimination tree respectively\n\
+\n\
+Called with a second argument, @dfn{etree} also returns the postorder\n\
+permutations on the tree.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 2)
+    print_usage ();
+  else
+    {
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      bool is_sym = true;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      scm = args(0).sparse_complex_matrix_value ();
+	      n_row = scm.rows ();
+	      n_col = scm.cols ();
+	      nnz = scm.nzmax ();
+	      ridx = scm.xridx ();
+	      cidx = scm.xcidx ();
+	    }
+	  else
+	    {
+	      sm = args(0).sparse_matrix_value ();
+	      n_row = sm.rows ();
+	      n_col = sm.cols ();
+	      nnz = sm.nzmax ();
+	      ridx = sm.xridx ();
+	      cidx = sm.xcidx ();
+	    }
+
+	}
+      else
+	{
+	  error ("etree: must be called with a sparse matrix");
+	  return retval;
+	}
+
+      if (nargin == 2)
+	{
+	  if (args(1).is_string ())
+	    {
+	      std::string str = args(1).string_value ();
+	      if (str.find ("C") == 0 || str.find ("c") == 0)
+		is_sym = false;
+	    }
+	  else
+	    {
+	      error ("etree: second argument must be a string");
+	      return retval;
+	    }
+	}
+
+      // column elimination tree post-ordering (reuse variables)
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
+
+      if (is_sym)
+	{
+	  if (n_row != n_col)
+	    {
+	      error ("etree: matrix is marked as symmetric, but not square");
+	      return retval;
+	    }
+
+	  symetree (ridx, cidx, etree, 0, n_col);
+	}
+      else
+	{
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col);
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, colend, n_col);
+
+	  for (octave_idx_type i = 0; i < n_col; i++)
+	    {
+	      colbeg[i] = cidx[i];
+	      colend[i] = cidx[i+1];
+	    }
+
+	  coletree (ridx, colbeg, colend, etree, n_row, n_col);
+	}
+
+      NDArray tree (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+	// We flag a root with n_col while Matlab does it with zero
+	// Convert for matlab compatiable output
+	if (etree[i] == n_col)
+	  tree(i) = 0;
+	else
+	  tree(i) = etree[i] + 1;
+
+      retval(0) = tree;
+
+      if (nargout == 2)
+	{
+	  // Calculate the tree post-ordering
+	  OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
+	  tree_postorder (n_col, etree, post);
+
+	  NDArray postorder (dim_vector (1, n_col));
+	  for (octave_idx_type i = 0; i < n_col; i++)
+	    postorder(i) = post[i] + 1;
+
+	  retval(1) = postorder;
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/colloc.cc b/src/DLD-FUNCTIONS/colloc.cc
new file mode 100644
index 0000000..16c23ef
--- /dev/null
+++ b/src/DLD-FUNCTIONS/colloc.cc
@@ -0,0 +1,146 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "CollocWt.h"
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (colloc, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{r}, @var{amat}, @var{bmat}, @var{q}] =} colloc (@var{n}, \"left\", \"right\")\n\
+Compute derivative and integral weight matrices for orthogonal\n\
+collocation using the subroutines given in J. Villadsen and\n\
+M. L. Michelsen, @cite{Solution of Differential Equation Models by\n\
+Polynomial Approximation}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (! args(0).is_scalar_type ())
+    {
+      error ("colloc: first argument must be a scalar");
+      return retval;
+    }
+
+  double tmp = args(0).double_value ();
+
+  if (error_state)
+    return retval;
+
+  if (xisnan (tmp))
+    {
+      error ("colloc: NaN is invalid as NCOL");
+      return retval;
+    }
+
+  octave_idx_type ncol = NINTbig (tmp);
+  if (ncol < 0)
+    {
+      error ("colloc: first argument must be non-negative");
+      return retval;
+    }
+
+  octave_idx_type ntot = ncol;
+  octave_idx_type left = 0;
+  octave_idx_type right = 0;
+
+  for (int i = 1; i < nargin; i++)
+    {
+      if (args(i).is_defined ())
+	{
+	  if (! args(i).is_string ())
+	    {
+	      error ("colloc: expecting string argument");
+	      return retval;
+	    }
+
+	  std::string s = args(i).string_value ();
+
+	  if ((s.length () == 1 && (s[0] == 'R' || s[0] == 'r'))
+	      || s == "right")
+	    {
+	      right = 1;
+	    }
+	  else if ((s.length () == 1 && (s[0] == 'L' || s[0] == 'l'))
+		   || s == "left")
+	    {
+	      left = 1;
+	    }
+	  else
+	    {
+	      error ("colloc: unrecognized argument");
+	      return retval;
+	    }
+	}
+      else
+	{
+	  error ("colloc: unexpected empty argument");
+	  return retval;
+	}
+    }
+
+  ntot += left + right;
+  if (ntot < 1)
+    {
+      error ("colloc: the total number of roots must be positive");
+      return retval;
+    }
+  
+  CollocWt wts (ncol, left, right);
+
+  ColumnVector r = wts.roots ();
+  Matrix A = wts.first ();
+  Matrix B = wts.second ();
+  ColumnVector q = wts.quad_weights ();
+
+  retval(3) = q;
+  retval(2) = B;
+  retval(1) = A;
+  retval(0) = r;
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/DLD-FUNCTIONS/conv2.cc b/src/DLD-FUNCTIONS/conv2.cc
new file mode 100644
index 0000000..8c8911b
--- /dev/null
+++ b/src/DLD-FUNCTIONS/conv2.cc
@@ -0,0 +1,437 @@
+/*
+
+Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+              Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+enum Shape { SHAPE_FULL, SHAPE_SAME, SHAPE_VALID };
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern MArray2<double>
+conv2 (MArray<double>&, MArray<double>&, MArray2<double>&, Shape);
+
+extern MArray2<Complex>
+conv2 (MArray<Complex>&, MArray<Complex>&, MArray2<Complex>&, Shape);
+
+extern MArray2<float>
+conv2 (MArray<float>&, MArray<float>&, MArray2<float>&, Shape);
+
+extern MArray2<FloatComplex>
+conv2 (MArray<FloatComplex>&, MArray<FloatComplex>&, MArray2<FloatComplex>&, Shape);
+#endif
+
+template <class T>
+MArray2<T>
+conv2 (MArray<T>& R, MArray<T>& C, MArray2<T>& A, Shape ishape)
+{
+  octave_idx_type  Rn =  R.length ();
+  octave_idx_type  Cm =  C.length ();
+  octave_idx_type  Am = A.rows ();
+  octave_idx_type  An = A.columns ();
+
+  // Calculate the size of the output matrix:
+  // in order to stay Matlab compatible, it is based
+  // on the third parameter if it's separable, and the
+  // first if it's not
+
+  octave_idx_type outM = 0;
+  octave_idx_type outN = 0;
+  octave_idx_type edgM = 0;
+  octave_idx_type edgN = 0;
+
+  switch (ishape)
+    {
+      case SHAPE_FULL:
+        outM = Am + Cm - 1;
+        outN = An + Rn - 1;
+        edgM = Cm - 1;
+        edgN = Rn - 1;
+        break;
+
+      case SHAPE_SAME:
+        outM = Am;
+        outN = An;
+        // Follow the Matlab convention (ie + instead of -)
+        edgM = (Cm - 1) /2;
+        edgN = (Rn - 1) /2;
+        break;
+
+      case SHAPE_VALID:
+        outM = Am - Cm + 1;
+        outN = An - Rn + 1;
+        if (outM < 0)
+	  outM = 0;
+        if (outN < 0)
+	  outN = 0;
+        edgM = edgN = 0;
+        break;
+
+      default:
+        error ("conv2: invalid value of parameter ishape");
+    }
+
+  MArray2<T> O (outM, outN);
+
+  // X accumulates the 1-D conv for each row, before calculating
+  //    the convolution in the other direction
+  // There is no efficiency advantage to doing it in either direction
+  //     first
+
+  MArray<T> X (An);
+
+  for (octave_idx_type oi = 0; oi < outM; oi++)
+    {
+      for (octave_idx_type oj = 0; oj < An; oj++)
+        {
+	  T sum = 0;
+
+	  octave_idx_type ci = Cm - 1 - MAX(0, edgM-oi);
+          octave_idx_type ai = MAX(0, oi-edgM);
+	  const T* Ad = A.data() + ai + Am*oj;
+	  const T* Cd = C.data() + ci;
+	  for ( ; ci >= 0 && ai < Am; ci--, Cd--, ai++, Ad++)
+	    sum += (*Ad) * (*Cd);
+
+	  X(oj) = sum;
+        }
+
+      for (octave_idx_type oj = 0; oj < outN; oj++)
+        {
+          T sum = 0;
+
+          octave_idx_type rj = Rn - 1 - MAX(0, edgN-oj);
+          octave_idx_type aj = MAX(0, oj-edgN) ;
+          const T* Xd = X.data() + aj;
+          const T* Rd = R.data() + rj;
+
+          for ( ; rj >= 0 && aj < An; rj--, Rd--, aj++, Xd++)
+	    sum += (*Xd) * (*Rd);
+
+          O(oi,oj)=  sum;
+        }
+    }
+
+  return O;
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern MArray2<double>
+conv2 (MArray2<double>&, MArray2<double>&, Shape);
+
+extern MArray2<Complex>
+conv2 (MArray2<Complex>&, MArray2<Complex>&, Shape);
+
+extern MArray2<float>
+conv2 (MArray2<float>&, MArray2<float>&, Shape);
+
+extern MArray2<FloatComplex>
+conv2 (MArray2<FloatComplex>&, MArray2<FloatComplex>&, Shape);
+#endif
+
+template <class T>
+MArray2<T>
+conv2 (MArray2<T>&A, MArray2<T>&B, Shape ishape)
+{
+  // Convolution works fastest if we choose the A matrix to be
+  // the largest.
+
+  // Here we calculate the size of the output matrix,
+  // in order to stay Matlab compatible, it is based
+  // on the third parameter if it's separable, and the
+  // first if it's not
+
+  // NOTE in order to be Matlab compatible, we give argueably
+  // wrong sizes for 'valid' if the smallest matrix is first
+
+  octave_idx_type Am = A.rows ();
+  octave_idx_type An = A.columns ();
+  octave_idx_type Bm = B.rows ();
+  octave_idx_type Bn = B.columns ();
+
+  octave_idx_type outM = 0;
+  octave_idx_type outN = 0;
+  octave_idx_type edgM = 0;
+  octave_idx_type edgN = 0;
+
+  switch (ishape)
+    {
+      case SHAPE_FULL:
+        outM = Am + Bm - 1;
+        outN = An + Bn - 1;
+        edgM = Bm - 1;
+        edgN = Bn - 1;
+        break;
+
+      case SHAPE_SAME:
+        outM = Am;
+        outN = An;
+        edgM = (Bm - 1) /2;
+        edgN = (Bn - 1) /2;
+        break;
+
+      case SHAPE_VALID:
+        outM = Am - Bm + 1;
+        outN = An - Bn + 1;
+	if (outM < 0)
+	  outM = 0;
+	if (outN < 0)
+	  outN = 0;
+        edgM = edgN = 0;
+        break;
+    }
+
+  MArray2<T> O (outM, outN);
+
+  for (octave_idx_type oi = 0; oi < outM; oi++)
+    {
+      for (octave_idx_type oj = 0; oj < outN; oj++)
+        {
+          T sum = 0;
+
+          for (octave_idx_type bj = Bn - 1 - MAX (0, edgN-oj), aj= MAX (0, oj-edgN);
+	       bj >= 0 && aj < An; bj--, aj++)
+            {
+              octave_idx_type bi = Bm - 1 - MAX (0, edgM-oi);
+              octave_idx_type ai = MAX (0, oi-edgM);
+              const T* Ad = A.data () + ai + Am*aj;
+              const T* Bd = B.data () + bi + Bm*bj;
+
+              for ( ; bi >= 0 && ai < Am; bi--, Bd--, ai++, Ad++)
+                {
+                  sum += (*Ad) * (*Bd);
+		  // Comment: it seems to be 2.5 x faster than this:
+		  //        sum+= A(ai,aj) * B(bi,bj);
+                }
+            }
+
+          O(oi,oj) = sum;
+        }
+    }
+
+  return O;
+}
+
+/*
+%!test
+%! b = [0,1,2,3;1,8,12,12;4,20,24,21;7,22,25,18];
+%! assert(conv2([0,1;1,2],[1,2,3;4,5,6;7,8,9]),b);
+
+%!test
+%! b = single([0,1,2,3;1,8,12,12;4,20,24,21;7,22,25,18]);
+%! assert(conv2(single([0,1;1,2]),single([1,2,3;4,5,6;7,8,9])),b);
+*/
+
+DEFUN_DLD (conv2, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {y =} conv2 (@var{a}, @var{b}, @var{shape})\n\
+ at deftypefnx {Loadable Function} {y =} conv2 (@var{v1}, @var{v2}, @var{M}, @var{shape})\n\
+\n\
+Returns 2D convolution of @var{a} and @var{b} where the size\n\
+of @var{c} is given by\n\
+\n\
+ at table @asis\n\
+ at item @var{shape}= 'full'\n\
+returns full 2-D convolution\n\
+ at item @var{shape}= 'same'\n\
+same size as a. 'central' part of convolution\n\
+ at item @var{shape}= 'valid'\n\
+only parts which do not include zero-padded edges\n\
+ at end table\n\
+\n\
+By default @var{shape} is 'full'.  When the third argument is a matrix\n\
+returns the convolution of the matrix @var{M} by the vector @var{v1}\n\
+in the column direction and by vector @var{v2} in the row direction\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  octave_value tmp;
+  int nargin = args.length ();
+  std::string shape= "full"; //default
+  bool separable= false;
+  Shape ishape;
+
+  if (nargin < 2)
+    {
+     print_usage ();
+     return retval;
+    }
+  else if (nargin == 3)
+    {
+      if (args(2).is_string ())
+        shape = args(2).string_value ();
+      else
+        separable = true;
+    }
+  else if (nargin >= 4)
+    {
+      separable = true;
+      shape = args(3).string_value ();
+    }
+
+  if (shape == "full")
+    ishape = SHAPE_FULL;
+  else if (shape == "same")
+    ishape = SHAPE_SAME;
+  else if (shape == "valid")
+    ishape = SHAPE_VALID;
+  else
+    {
+      error ("conv2: shape type not valid");
+      print_usage ();
+      return retval;
+    }
+
+   if (separable)
+     {
+      // If user requests separable, check first two params are vectors
+
+       if (! (1 == args(0).rows () || 1 == args(0).columns ())
+	   || ! (1 == args(1).rows () || 1 == args(1).columns ()))
+         {
+	   print_usage ();
+	   return retval;
+         }
+
+       if (args(0).is_single_type () || 
+	   args(1).is_single_type () || 
+	   args(2).is_single_type ())
+	 {
+	   if (args(0).is_complex_type ()
+	       || args(1).is_complex_type ()
+	       || args(2).is_complex_type ())
+	     {
+	       FloatComplexColumnVector v1 (args(0).float_complex_vector_value ());
+	       FloatComplexColumnVector v2 (args(1).float_complex_vector_value ());
+	       FloatComplexMatrix a (args(2).float_complex_matrix_value ());
+	       FloatComplexMatrix c (conv2 (v1, v2, a, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	   else
+	     {
+	       FloatColumnVector v1 (args(0).float_vector_value ());
+	       FloatColumnVector v2 (args(1).float_vector_value ());
+	       FloatMatrix a (args(2).float_matrix_value ());
+	       FloatMatrix c (conv2 (v1, v2, a, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	 }
+       else
+	 {
+	   if (args(0).is_complex_type ()
+	       || args(1).is_complex_type ()
+	       || args(2).is_complex_type ())
+	     {
+	       ComplexColumnVector v1 (args(0).complex_vector_value ());
+	       ComplexColumnVector v2 (args(1).complex_vector_value ());
+	       ComplexMatrix a (args(2).complex_matrix_value ());
+	       ComplexMatrix c (conv2 (v1, v2, a, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	   else
+	     {
+	       ColumnVector v1 (args(0).vector_value ());
+	       ColumnVector v2 (args(1).vector_value ());
+	       Matrix a (args(2).matrix_value ());
+	       Matrix c (conv2 (v1, v2, a, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	 }
+     } // if (separable)
+   else
+     {
+       if (args(0).is_single_type () || 
+	   args(1).is_single_type ())
+	 {
+	   if (args(0).is_complex_type ()
+	       || args(1).is_complex_type ())
+	     {
+	       FloatComplexMatrix a (args(0).float_complex_matrix_value ());
+	       FloatComplexMatrix b (args(1).float_complex_matrix_value ());
+	       FloatComplexMatrix c (conv2 (a, b, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	   else
+	     {
+	       FloatMatrix a (args(0).float_matrix_value ());
+	       FloatMatrix b (args(1).float_matrix_value ());
+	       FloatMatrix c (conv2 (a, b, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	 }
+       else
+	 {
+	   if (args(0).is_complex_type ()
+	       || args(1).is_complex_type ())
+	     {
+	       ComplexMatrix a (args(0).complex_matrix_value ());
+	       ComplexMatrix b (args(1).complex_matrix_value ());
+	       ComplexMatrix c (conv2 (a, b, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	   else
+	     {
+	       Matrix a (args(0).matrix_value ());
+	       Matrix b (args(1).matrix_value ());
+	       Matrix c (conv2 (a, b, ishape));
+	       if (! error_state)
+		 retval = c;
+	     }
+	 }
+
+     } // if (separable)
+
+   return retval;
+}
+
+template MArray2<double>
+conv2 (MArray<double>&, MArray<double>&, MArray2<double>&, Shape);
+
+template MArray2<double>
+conv2 (MArray2<double>&, MArray2<double>&, Shape);
+
+template MArray2<Complex>
+conv2 (MArray<Complex>&, MArray<Complex>&, MArray2<Complex>&, Shape);
+
+template MArray2<Complex>
+conv2 (MArray2<Complex>&, MArray2<Complex>&, Shape);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/convhulln.cc b/src/DLD-FUNCTIONS/convhulln.cc
new file mode 100644
index 0000000..0ad6812
--- /dev/null
+++ b/src/DLD-FUNCTIONS/convhulln.cc
@@ -0,0 +1,236 @@
+/*
+
+Copyright (C) 2000, 2007, 2008, 2009 Kai Habel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+29. July 2000 - Kai Habel: first release
+2002-04-22 Paul Kienzle
+* Use warning(...) function rather than writing to cerr
+2006-05-01 Tom Holroyd
+* add support for consistent winding in all dimensions; output is
+* guaranteed to be simplicial.
+*/
+
+#include <sstream>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "oct.h"
+#include "Cell.h"
+
+#ifdef HAVE_QHULL
+#if defined(HAVE__SNPRINTF) && !defined(HAVE_SNPRINTF)
+#define snprintf _snprintf
+#endif
+
+extern "C" {
+#include <qhull/qhull_a.h>
+}
+
+#ifdef NEED_QHULL_VERSION
+char qh_version[] = "convhulln.oct 2007-07-24";
+#endif
+#endif
+
+DEFUN_DLD (convhulln, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{h} =} convhulln (@var{p})\n\
+ at deftypefnx {Loadable Function} {@var{h} =} convhulln (@var{p}, @var{opt})\n\
+ at deftypefnx {Loadable Function} {[@var{h}, @var{v}] =} convhulln (@dots{})\n\
+Return an index vector to the points of the enclosing convex hull.\n\
+The input matrix of size [n, dim] contains n points of dimension dim.\n\n\
+If a second optional argument is given, it must be a string or cell array\n\
+of strings containing options for the underlying qhull command.  (See\n\
+the Qhull documentation for the available options.)  The default options\n\
+are \"s Qci Tcv\".\n\
+If the second output @var{V} is requested the volume of the convex hull is\n\
+calculated.\n\n\
+ at seealso{convhull, delaunayn}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_QHULL
+  std::string options;
+
+  int nargin = args.length ();
+  if (nargin < 1 || nargin > 2) 
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (nargin == 2) 
+    {
+      if (args (1).is_string ()) 
+	options = args(1).string_value ();
+      else if (args(1).is_cell ())
+	{
+	  Cell c = args(1).cell_value ();
+	  options = "";
+	  for (octave_idx_type i = 0; i < c.numel (); i++)
+	    {
+	      if (! c.elem(i).is_string ())
+		{
+		  error ("convhulln: second argument must be a string or cell array of strings");
+		  return retval;
+		}
+
+	      options = options + c.elem(i).string_value() + " ";
+	    }
+	}
+      else
+	{
+	  error ("convhulln: second argument must be a string or cell array of strings");
+	  return retval;
+	}
+    }
+  else
+    // turn on some consistency checks
+    options = "s Qci Tcv";
+
+  Matrix p (args(0).matrix_value ());
+
+  const octave_idx_type dim = p.columns ();
+  const octave_idx_type n = p.rows ();
+  p = p.transpose ();
+
+  double *pt_array = p.fortran_vec ();
+
+  boolT ismalloc = False;
+
+  OCTAVE_LOCAL_BUFFER (char, flags, 250);
+
+  // hmm, lots of options for qhull here
+  // QJ guarantees that the output will be triangles
+  snprintf (flags, 250, "qhull QJ %s", options.c_str ());
+
+  if (! qh_new_qhull (dim, n, pt_array, ismalloc, flags, 0, stderr)) 
+    {
+      // If you want some debugging information replace the NULL
+      // pointer with stdout
+
+      vertexT *vertex, **vertexp;
+      facetT *facet;
+      setT *vertices;
+      unsigned int nf = qh num_facets;
+
+      Matrix idx (nf, dim);
+
+      octave_idx_type j, i = 0;
+      FORALLfacets 
+	{
+	  j = 0;
+	  if (! facet->simplicial)
+	    // should never happen with QJ
+	    error ("convhulln: non-simplicial facet");
+
+	  if (dim == 3) 
+	    {
+	      vertices = qh_facet3vertex (facet);
+	      FOREACHvertex_ (vertices)
+		idx(i, j++) = 1 + qh_pointid(vertex->point);
+	      qh_settempfree (&vertices);
+	    } 
+	  else 
+	    {
+	      if (facet->toporient ^ qh_ORIENTclock) 
+		{
+		  FOREACHvertex_ (facet->vertices)
+		    idx(i, j++) = 1 + qh_pointid(vertex->point);
+		} 
+	      else 
+		{
+		  FOREACHvertexreverse12_ (facet->vertices)
+		    idx(i, j++) = 1 + qh_pointid(vertex->point);
+		}
+	    }
+	  if (j < dim)
+	    // likewise but less fatal
+	    warning ("facet %d only has %d vertices", i, j);
+	  i++;
+	}
+
+      if (nargout == 2)
+        // calculate volume of convex hull
+        // taken from qhull src/geom2.c
+        {
+          realT area;
+          realT dist;
+
+          FORALLfacets
+	    {
+	      if (! facet->normal)
+		continue;
+
+	      if (facet->upperdelaunay && qh ATinfinity)
+		continue;
+
+	      facet->f.area = area = qh_facetarea (facet);
+	      facet->isarea = True;
+
+	      if (qh DELAUNAY)
+		{
+		  if (facet->upperdelaunay == qh UPPERdelaunay)
+		    qh totarea += area;
+		}
+	      else
+		{
+		  qh totarea += area;
+		  qh_distplane (qh interior_point, facet, &dist);
+		  qh totvol += -dist * area/ qh hull_dim;
+		}
+	    }
+
+          retval(1) = octave_value (qh totvol);
+        }
+
+      retval(0) = octave_value (idx);
+    }
+
+  // free long memory
+  qh_freeqhull (! qh_ALL);
+
+  // free short memory and memory allocator
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong) 
+    warning ("convhulln: did not free %d bytes of long memory (%d pieces)",
+	    totlong, curlong);
+#else
+  error ("convhulln: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/*
+%!test
+%! cube = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1];
+%! [h, v] = convhulln(cube,'Pp');
+%! assert (v, 1.0, 1e6*eps);
+%!test
+%! tetrahedron = [1 1 1;-1 -1 1;-1 1 -1;1 -1 -1];
+%! [h, v] = convhulln(tetrahedron,'Pp');
+%! assert (v, 8/3, 1e6*eps);
+*/
diff --git a/src/DLD-FUNCTIONS/daspk.cc b/src/DLD-FUNCTIONS/daspk.cc
new file mode 100644
index 0000000..fd89d40
--- /dev/null
+++ b/src/DLD-FUNCTIONS/daspk.cc
@@ -0,0 +1,492 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <iomanip>
+#include <iostream>
+
+#include "DASPK.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#include "DASPK-opts.cc"
+
+// Global pointer for user defined function required by daspk.
+static octave_function *daspk_fcn;
+
+// Global pointer for optional user defined jacobian function.
+static octave_function *daspk_jac;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_fcn_imaginary = false;
+static bool warned_jac_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+ColumnVector
+daspk_user_function (const ColumnVector& x, const ColumnVector& xdot,
+		     double t, octave_idx_type& ires)
+{
+  ColumnVector retval;
+
+  assert (x.capacity () == xdot.capacity ());
+
+  octave_value_list args;
+
+  args(2) = t;
+  args(1) = xdot;
+  args(0) = x;
+
+  if (daspk_fcn)
+    {
+      octave_value_list tmp = daspk_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("daspk");
+	  return retval;
+	}
+
+      int tlen = tmp.length ();
+      if (tlen > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_fcn_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("daspk: ignoring imaginary part returned from user-supplied function");
+	      warned_fcn_imaginary = true;
+	    }
+
+	  retval = ColumnVector (tmp(0).vector_value ());
+
+	  if (tlen > 1)
+	    ires = tmp(1).int_value ();
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("daspk");
+	}
+      else
+	gripe_user_supplied_eval ("daspk");
+    }
+
+  return retval;
+}
+
+Matrix
+daspk_user_jacobian (const ColumnVector& x, const ColumnVector& xdot,
+		     double t, double cj)
+{
+  Matrix retval;
+
+  assert (x.capacity () == xdot.capacity ());
+
+  octave_value_list args;
+
+  args(3) = cj;
+  args(2) = t;
+  args(1) = xdot;
+  args(0) = x;
+
+  if (daspk_jac)
+    {
+      octave_value_list tmp = daspk_jac->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("daspk");
+	  return retval;
+	}
+
+      int tlen = tmp.length ();
+      if (tlen > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_jac_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("daspk: ignoring imaginary part returned from user-supplied jacobian function");
+	      warned_jac_imaginary = true;
+	    }
+
+	  retval = tmp(0).matrix_value ();
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("daspk");
+	}
+      else
+	gripe_user_supplied_eval ("daspk");
+    }
+
+  return retval;
+}
+
+#define DASPK_ABORT() \
+  do \
+    { \
+      unwind_protect::run_frame ("Fdaspk"); \
+      return retval; \
+    } \
+  while (0)
+
+#define DASPK_ABORT1(msg) \
+  do \
+    { \
+      ::error ("daspk: " msg); \
+      DASPK_ABORT (); \
+    } \
+  while (0)
+
+#define DASPK_ABORT2(fmt, arg) \
+  do \
+    { \
+      ::error ("daspk: " fmt, arg); \
+      DASPK_ABORT (); \
+    } \
+  while (0)
+
+DEFUN_DLD (daspk, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} daspk (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})\n\
+Solve the set of differential-algebraic equations\n\
+ at tex\n\
+$$ 0 = f (x, \\dot{x}, t) $$\n\
+with\n\
+$$ x(t_0) = x_0, \\dot{x}(t_0) = \\dot{x}_0 $$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+0 = f (x, xdot, t)\n\
+ at end example\n\
+\n\
+with\n\
+\n\
+ at example\n\
+x(t_0) = x_0, xdot(t_0) = xdot_0\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+The solution is returned in the matrices @var{x} and @var{xdot},\n\
+with each row in the result matrices corresponding to one of the\n\
+elements in the vector @var{t}.  The first element of @var{t}\n\
+should be @math{t_0} and correspond to the initial state of the\n\
+system @var{x_0} and its derivative @var{xdot_0}, so that the first\n\
+row of the output @var{x} is @var{x_0} and the first row\n\
+of the output @var{xdot} is @var{xdot_0}.\n\
+\n\
+The first argument, @var{fcn}, is a string, inline, or function handle\n\
+that names the function @math{f} to call to compute the vector of\n\
+residuals for the set of equations.  It must have the form\n\
+\n\
+ at example\n\
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
+ at end example\n\
+\n\
+ at noindent\n\
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\
+scalar.\n\
+\n\
+If @var{fcn} is a two-element string array or a two-element cell array\n\
+of strings, inline functions, or function handles, the first element names\n\
+the function @math{f} described above, and the second element names a\n\
+function to compute the modified Jacobian\n\
+ at tex\n\
+$$\n\
+J = {\\partial f \\over \\partial x}\n\
+  + c {\\partial f \\over \\partial \\dot{x}}\n\
+$$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+      df       df\n\
+jac = -- + c ------\n\
+      dx     d xdot\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+The modified Jacobian function must have the form\n\
+\n\
+ at example\n\
+ at group\n\
+\n\
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})\n\
+\n\
+ at end group\n\
+ at end example\n\
+\n\
+The second and third arguments to @code{daspk} specify the initial\n\
+condition of the states and their derivatives, and the fourth argument\n\
+specifies a vector of output times at which the solution is desired,\n\
+including the time corresponding to the initial condition.\n\
+\n\
+The set of initial states and derivatives are not strictly required to\n\
+be consistent.  If they are not consistent, you must use the\n\
+ at code{daspk_options} function to provide additional information so\n\
+that @code{daspk} can compute a consistent starting point.\n\
+\n\
+The fifth argument is optional, and may be used to specify a set of\n\
+times that the DAE solver should not integrate past.  It is useful for\n\
+avoiding difficulties with singularities and points where there is a\n\
+discontinuity in the derivative.\n\
+\n\
+After a successful computation, the value of @var{istate} will be\n\
+greater than zero (consistent with the Fortran version of @sc{Daspk}).\n\
+\n\
+If the computation is not successful, the value of @var{istate} will be\n\
+less than zero and @var{msg} will contain additional information.\n\
+\n\
+You can use the function @code{daspk_options} to set optional\n\
+parameters for @code{daspk}.\n\
+ at seealso{dassl}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  warned_fcn_imaginary = false;
+  warned_jac_imaginary = false;
+
+  unwind_protect::begin_frame ("Fdaspk");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    DASPK_ABORT1 ("invalid recursive call");
+
+  int nargin = args.length ();
+
+  if (nargin > 3 && nargin < 6)
+    {
+      std::string fcn_name, fname, jac_name, jname;
+      daspk_fcn = 0;
+      daspk_jac = 0;
+
+      octave_value f_arg = args(0);
+
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		daspk_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__daspk_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x, xdot, t) y = ");
+		  daspk_fcn = extract_function
+		    (c(0), "daspk", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (daspk_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    daspk_jac = c(1).function_value ();
+		  else
+		    {
+		      jac_name = unique_symbol_name ("__daspk_jac__");
+		      jname = "function jac = ";
+		      jname.append(jac_name);
+		      jname.append (" (x, xdot, t, cj) jac = ");
+		      daspk_jac = extract_function
+			(c(1), "daspk", jac_name, jname, "; endfunction");
+
+		      if (!daspk_jac)
+			{
+			  if (fcn_name.length())
+			    clear_function (fcn_name);
+			  daspk_fcn = 0;
+			}
+		    }
+		}
+	    }
+	  else
+	    DASPK_ABORT1 ("incorrect number of elements in cell array");
+	}
+
+      if (!daspk_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    daspk_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__daspk_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x, xdot, t) y = ");
+		      daspk_fcn = extract_function
+			(f_arg, "daspk", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
+
+		case 2:
+		  {
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__daspk_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x, xdot, t) y = ");
+			daspk_fcn = extract_function
+			  (tmp(0), "daspk", fcn_name, fname, "; endfunction");
+
+			if (daspk_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__daspk_jac__");
+			    jname = "function jac = ";
+			    jname.append(jac_name);
+			    jname.append (" (x, xdot, t, cj) jac = ");
+			    daspk_jac = extract_function
+			      (tmp(1), "daspk", jac_name, jname,
+			       "; endfunction");
+
+			    if (!daspk_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				daspk_fcn = 0;
+			      }
+			  }
+		      }
+		  }
+		}
+	    }
+	}
+
+      if (error_state || ! daspk_fcn)
+	DASPK_ABORT ();
+
+      ColumnVector state = ColumnVector (args(1).vector_value ());
+
+      if (error_state)
+	DASPK_ABORT1 ("expecting state vector as second argument");
+
+      ColumnVector deriv (args(2).vector_value ());
+
+      if (error_state)
+	DASPK_ABORT1 ("expecting derivative vector as third argument");
+
+      ColumnVector out_times (args(3).vector_value ());
+
+      if (error_state)
+	DASPK_ABORT1 ("expecting output time vector as fourth argument");
+
+      ColumnVector crit_times;
+      int crit_times_set = 0;
+      if (nargin > 4)
+	{
+	  crit_times = ColumnVector (args(4).vector_value ());
+
+	  if (error_state)
+	    DASPK_ABORT1 ("expecting critical time vector as fifth argument");
+
+	  crit_times_set = 1;
+	}
+
+      if (state.capacity () != deriv.capacity ())
+	DASPK_ABORT1 ("x and xdot must have the same size");
+
+      double tzero = out_times (0);
+
+      DAEFunc func (daspk_user_function);
+      if (daspk_jac)
+	func.set_jacobian_function (daspk_user_jacobian);
+
+      DASPK dae (state, deriv, tzero, func);
+      dae.set_options (daspk_opts);
+
+      Matrix output;
+      Matrix deriv_output;
+
+      if (crit_times_set)
+	output = dae.integrate (out_times, deriv_output, crit_times);
+      else
+	output = dae.integrate (out_times, deriv_output);
+
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
+      if (! error_state)
+	{
+	  std::string msg = dae.error_message ();
+
+	  retval(3) = msg;
+	  retval(2) = static_cast<double> (dae.integration_state ());
+
+	  if (dae.integration_ok ())
+	    {
+	      retval(1) = deriv_output;
+	      retval(0) = output;
+	    }
+	  else
+	    {
+	      retval(1) = Matrix ();
+	      retval(0) = Matrix ();
+
+	      if (nargout < 3)
+		error ("daspk: %s", msg.c_str ());
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Fdaspk");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/dasrt.cc b/src/DLD-FUNCTIONS/dasrt.cc
new file mode 100644
index 0000000..612d89e
--- /dev/null
+++ b/src/DLD-FUNCTIONS/dasrt.cc
@@ -0,0 +1,599 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "DASRT.h"
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "parse.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#include "DASRT-opts.cc"
+
+// Global pointers for user defined function required by dasrt.
+static octave_function *dasrt_f;
+static octave_function *dasrt_j;
+static octave_function *dasrt_cf;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_fcn_imaginary = false;
+static bool warned_jac_imaginary = false;
+static bool warned_cf_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+static ColumnVector
+dasrt_user_f (const ColumnVector& x, const ColumnVector& xdot,
+	      double t, octave_idx_type&)
+{
+  ColumnVector retval;
+
+  assert (x.capacity () == xdot.capacity ());
+
+  octave_value_list args;
+
+  args(2) = t;
+  args(1) = xdot;
+  args(0) = x;
+
+  if (dasrt_f)
+    {
+      octave_value_list tmp = dasrt_f->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("dasrt");
+	  return retval;
+	}
+
+      if (tmp.length () > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_fcn_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("dasrt: ignoring imaginary part returned from user-supplied function");
+	      warned_fcn_imaginary = true;
+	    }
+
+	  retval = ColumnVector (tmp(0).vector_value ());
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("dasrt");
+	}
+      else
+	gripe_user_supplied_eval ("dasrt");
+    }
+
+  return retval;
+}
+
+static ColumnVector
+dasrt_user_cf (const ColumnVector& x, double t)
+{
+  ColumnVector retval;
+
+  octave_value_list args;
+
+  args(1) = t;
+  args(0) = x;
+
+  if (dasrt_cf)
+    {
+      octave_value_list tmp = dasrt_cf->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("dasrt");
+	  return retval;
+	}
+
+      if (tmp.length () > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_cf_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("dasrt: ignoring imaginary part returned from user-supplied constraint function");
+	      warned_cf_imaginary = true;
+	    }
+
+	  retval = ColumnVector (tmp(0).vector_value ());
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("dasrt");
+	}
+      else
+	gripe_user_supplied_eval ("dasrt");
+    }
+
+  return retval;
+}
+
+static Matrix
+dasrt_user_j (const ColumnVector& x, const ColumnVector& xdot,
+	      double t, double cj)
+{
+  Matrix retval;
+
+  assert (x.capacity () == xdot.capacity ());
+
+  octave_value_list args;
+
+  args(3) = cj;
+  args(2) = t;
+  args(1) = xdot;
+  args(0) = x;
+
+  if (dasrt_j)
+    {
+      octave_value_list tmp = dasrt_j->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("dasrt");
+	  return retval;
+	}
+
+      int tlen = tmp.length ();
+      if (tlen > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_jac_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("dasrt: ignoring imaginary part returned from user-supplied jacobian function");
+	      warned_jac_imaginary = true;
+	    }
+
+	  retval = tmp(0).matrix_value ();
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("dasrt");
+	}
+      else
+	gripe_user_supplied_eval ("dasrt");
+    }
+
+  return retval;
+}
+
+#define DASRT_ABORT \
+  do \
+    { \
+      unwind_protect::run_frame ("Fdasrt"); \
+      return retval; \
+    } \
+  while (0)
+
+#define DASRT_ABORT1(msg) \
+  do \
+    { \
+      ::error ("dasrt: " msg); \
+      DASRT_ABORT; \
+    } \
+  while (0)
+
+#define DASRT_ABORT2(fmt, arg) \
+  do \
+    { \
+      ::error ("dasrt: " fmt, arg); \
+      DASRT_ABORT; \
+    } \
+  while (0)
+
+DEFUN_DLD (dasrt, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{t_out}, @var{istat}, @var{msg}] =} dasrt (@var{fcn} [, @var{g}], @var{x_0}, @var{xdot_0}, @var{t} [, @var{t_crit}])\n\
+Solve the set of differential-algebraic equations\n\
+ at tex\n\
+$$ 0 = f (x, \\dot{x}, t) $$\n\
+with\n\
+$$ x(t_0) = x_0, \\dot{x}(t_0) = \\dot{x}_0 $$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+0 = f (x, xdot, t)\n\
+ at end example\n\
+\n\
+with\n\
+\n\
+ at example\n\
+x(t_0) = x_0, xdot(t_0) = xdot_0\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+with functional stopping criteria (root solving).\n\
+\n\
+The solution is returned in the matrices @var{x} and @var{xdot},\n\
+with each row in the result matrices corresponding to one of the\n\
+elements in the vector @var{t_out}.  The first element of @var{t}\n\
+should be @math{t_0} and correspond to the initial state of the\n\
+system @var{x_0} and its derivative @var{xdot_0}, so that the first\n\
+row of the output @var{x} is @var{x_0} and the first row\n\
+of the output @var{xdot} is @var{xdot_0}.\n\
+\n\
+The vector @var{t} provides an upper limit on the length of the\n\
+integration.  If the stopping condition is met, the vector\n\
+ at var{t_out} will be shorter than @var{t}, and the final element of\n\
+ at var{t_out} will be the point at which the stopping condition was met,\n\
+and may not correspond to any element of the vector @var{t}.\n\
+\n\
+The first argument, @var{fcn}, is a string, inline, or function handle\n\
+that names the function @math{f} to call to compute the vector of\n\
+residuals for the set of equations.  It must have the form\n\
+\n\
+ at example\n\
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
+ at end example\n\
+\n\
+ at noindent\n\
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\
+scalar.\n\
+\n\
+If @var{fcn} is a two-element string array or a two-element cell array\n\
+of strings, inline functions, or function handles, the first element names\n\
+the function @math{f} described above, and the second element names a\n\
+function to compute the modified Jacobian\n\
+\n\
+ at tex\n\
+$$\n\
+J = {\\partial f \\over \\partial x}\n\
+  + c {\\partial f \\over \\partial \\dot{x}}\n\
+$$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+      df       df\n\
+jac = -- + c ------\n\
+      dx     d xdot\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+\n\
+The modified Jacobian function must have the form\n\
+\n\
+ at example\n\
+ at group\n\
+\n\
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})\n\
+\n\
+ at end group\n\
+ at end example\n\
+\n\
+The optional second argument names a function that defines the\n\
+constraint functions whose roots are desired during the integration.\n\
+This function must have the form\n\
+\n\
+ at example\n\
+ at var{g_out} = g (@var{x}, @var{t})\n\
+ at end example\n\
+\n\
+and return a vector of the constraint function values.\n\
+If the value of any of the constraint functions changes sign, @sc{Dasrt}\n\
+will attempt to stop the integration at the point of the sign change.\n\
+\n\
+If the name of the constraint function is omitted, @code{dasrt} solves\n\
+the same problem as @code{daspk} or @code{dassl}.\n\
+\n\
+Note that because of numerical errors in the constraint functions\n\
+due to roundoff and integration error, @sc{Dasrt} may return false\n\
+roots, or return the same root at two or more nearly equal values of\n\
+ at var{T}.  If such false roots are suspected, the user should consider\n\
+smaller error tolerances or higher precision in the evaluation of the\n\
+constraint functions.\n\
+\n\
+If a root of some constraint function defines the end of the problem,\n\
+the input to @sc{Dasrt} should nevertheless allow integration to a\n\
+point slightly past that root, so that @sc{Dasrt} can locate the root\n\
+by interpolation.\n\
+\n\
+The third and fourth arguments to @code{dasrt} specify the initial\n\
+condition of the states and their derivatives, and the fourth argument\n\
+specifies a vector of output times at which the solution is desired,\n\
+including the time corresponding to the initial condition.\n\
+\n\
+The set of initial states and derivatives are not strictly required to\n\
+be consistent.  In practice, however, @sc{Dassl} is not very good at\n\
+determining a consistent set for you, so it is best if you ensure that\n\
+the initial values result in the function evaluating to zero.\n\
+\n\
+The sixth argument is optional, and may be used to specify a set of\n\
+times that the DAE solver should not integrate past.  It is useful for\n\
+avoiding difficulties with singularities and points where there is a\n\
+discontinuity in the derivative.\n\
+\n\
+After a successful computation, the value of @var{istate} will be\n\
+greater than zero (consistent with the Fortran version of @sc{Dassl}).\n\
+\n\
+If the computation is not successful, the value of @var{istate} will be\n\
+less than zero and @var{msg} will contain additional information.\n\
+\n\
+You can use the function @code{dasrt_options} to set optional\n\
+parameters for @code{dasrt}.\n\
+ at seealso{daspk, dasrt, lsode}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  warned_fcn_imaginary = false;
+  warned_jac_imaginary = false;
+  warned_cf_imaginary = false;
+
+  unwind_protect::begin_frame ("Fdasrt");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    DASRT_ABORT1 ("invalid recursive call");
+
+  int argp = 0;
+
+  int nargin = args.length ();
+
+  if (nargin < 4 || nargin > 6)
+    {
+      print_usage ();
+      unwind_protect::run_frame ("Fdasrt");
+      return retval;
+    }
+
+  std::string fcn_name, fname, jac_name, jname;
+  dasrt_f = 0;
+  dasrt_j = 0;
+  dasrt_cf = 0;
+
+  // Check all the arguments.  Are they the right animals?
+
+  // Here's where I take care of f and j in one shot:
+
+  octave_value f_arg = args(0);
+
+  if (f_arg.is_cell ())
+    {
+      Cell c = f_arg.cell_value ();
+      if (c.length() == 1)
+	f_arg = c(0);
+      else if (c.length() == 2)
+	{
+	  if (c(0).is_function_handle () || c(0).is_inline_function ())
+	    dasrt_f = c(0).function_value ();
+	  else
+	    {
+	      fcn_name = unique_symbol_name ("__dasrt_fcn__");
+	      fname = "function y = ";
+	      fname.append (fcn_name);
+	      fname.append (" (x, xdot, t) y = ");
+	      dasrt_f = extract_function
+		(c(0), "dasrt", fcn_name, fname, "; endfunction");
+	    }
+
+	  if (dasrt_f)
+	    {
+	      if (c(1).is_function_handle () || c(1).is_inline_function ())
+		dasrt_j = c(1).function_value ();
+	      else
+		{
+		  jac_name = unique_symbol_name ("__dasrt_jac__");
+		  jname = "function jac = ";
+		  jname.append(jac_name);
+		  jname.append (" (x, xdot, t, cj) jac = ");
+		  dasrt_j = extract_function
+		    (c(1), "dasrt", jac_name, jname, "; endfunction");
+
+		  if (!dasrt_j)
+		    {
+		      if (fcn_name.length())
+			clear_function (fcn_name);
+		      dasrt_f = 0;
+		    }
+		}
+	    }
+	}
+      else
+	DASRT_ABORT1 ("incorrect number of elements in cell array");
+    }
+
+  if (!dasrt_f && ! f_arg.is_cell())
+    {
+      if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	dasrt_f = f_arg.function_value ();
+      else
+	{
+	  switch (f_arg.rows ())
+	    {
+	    case 1:
+	      fcn_name = unique_symbol_name ("__dasrt_fcn__");
+	      fname = "function y = ";
+	      fname.append (fcn_name);
+	      fname.append (" (x, xdot, t) y = ");
+	      dasrt_f = extract_function
+		(f_arg, "dasrt", fcn_name, fname, "; endfunction");
+	      break;
+      
+	    case 2:
+	      {
+		string_vector tmp = args(0).all_strings ();
+	
+		if (! error_state)
+		  {
+		    fcn_name = unique_symbol_name ("__dasrt_fcn__");
+		    fname = "function y = ";
+		    fname.append (fcn_name);
+		    fname.append (" (x, xdot, t) y = ");
+		    dasrt_f = extract_function
+		      (tmp(0), "dasrt", fcn_name, fname, "; endfunction");
+	    
+		    if (dasrt_f)
+		      {
+			jac_name = unique_symbol_name ("__dasrt_jac__");
+			jname = "function jac = ";
+			jname.append(jac_name);
+			jname.append (" (x, xdot, t, cj) jac = ");
+			dasrt_j = extract_function
+			  (tmp(1), "dasrt", jac_name, jname, "; endfunction");
+
+			if (! dasrt_j)
+			  dasrt_f = 0;
+		      }
+		  }
+	      }
+	      break;
+      
+	    default:
+	      DASRT_ABORT1
+		("first arg should be a string or 2-element string array");
+	    }
+	}
+    }
+  
+  if (error_state || (! dasrt_f))
+    DASRT_ABORT;
+  
+  DAERTFunc func (dasrt_user_f);
+  
+  argp++;
+  
+  if (args(1).is_function_handle() || args(1).is_inline_function())
+    {
+      dasrt_cf = args(1).function_value();
+
+      if (! dasrt_cf)
+	DASRT_ABORT1 ("expecting function name as argument 2");
+
+      argp++;
+
+      func.set_constraint_function (dasrt_user_cf);
+    }
+  else if (args(1).is_string ())
+    {
+      dasrt_cf = is_valid_function (args(1), "dasrt", true);
+      if (! dasrt_cf)
+	DASRT_ABORT1 ("expecting function name as argument 2");
+
+      argp++;
+
+      func.set_constraint_function (dasrt_user_cf);
+    }
+
+  ColumnVector state (args(argp++).vector_value ());
+
+  if (error_state)
+    DASRT_ABORT2 ("expecting state vector as argument %d", argp);
+
+  ColumnVector stateprime (args(argp++).vector_value ());
+
+  if (error_state)
+    DASRT_ABORT2 
+       ("expecting time derivative of state vector as argument %d", argp);
+
+  ColumnVector out_times (args(argp++).vector_value ());
+
+  if (error_state)
+    DASRT_ABORT2
+	("expecting output time vector as %s argument %d", argp);
+
+  double tzero = out_times (0);
+
+  ColumnVector crit_times;
+
+  bool crit_times_set = false;
+
+  if (argp < nargin)
+    {
+      crit_times = ColumnVector (args(argp++).vector_value ());
+
+      if (error_state)
+	DASRT_ABORT2
+	  ("expecting critical time vector as argument %d", argp);
+
+      crit_times_set = true;
+    }
+
+  if (dasrt_j)
+    func.set_jacobian_function (dasrt_user_j);
+
+  DASRT_result output;
+
+  DASRT dae = DASRT (state, stateprime, tzero, func);
+
+  dae.set_options (dasrt_opts);
+
+  if (crit_times_set)
+    output = dae.integrate (out_times, crit_times);
+  else
+    output = dae.integrate (out_times);
+
+  if (fcn_name.length())
+    clear_function (fcn_name);
+  if (jac_name.length())
+    clear_function (jac_name);
+
+  if (! error_state)
+    {
+      std::string msg = dae.error_message ();
+
+      retval(4) = msg;
+      retval(3) = static_cast<double> (dae.integration_state ());
+
+      if (dae.integration_ok ())
+	{
+	  retval(2) = output.times ();
+	  retval(1) = output.deriv ();
+	  retval(0) = output.state ();
+	}
+      else
+	{
+	  retval(2) = Matrix ();
+	  retval(1) = Matrix ();
+	  retval(0) = Matrix ();
+
+	  if (nargout < 4)
+	    error ("dasrt: %s", msg.c_str ());
+	}
+    }
+
+  unwind_protect::run_frame ("Fdasrt");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/dassl.cc b/src/DLD-FUNCTIONS/dassl.cc
new file mode 100644
index 0000000..81e7738
--- /dev/null
+++ b/src/DLD-FUNCTIONS/dassl.cc
@@ -0,0 +1,579 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <iomanip>
+#include <iostream>
+
+#include "DASSL.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#include "DASSL-opts.cc"
+
+// Global pointer for user defined function required by dassl.
+static octave_function *dassl_fcn;
+
+// Global pointer for optional user defined jacobian function.
+static octave_function *dassl_jac;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_fcn_imaginary = false;
+static bool warned_jac_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+ColumnVector
+dassl_user_function (const ColumnVector& x, const ColumnVector& xdot,
+		     double t, octave_idx_type& ires)
+{
+  ColumnVector retval;
+
+  assert (x.capacity () == xdot.capacity ());
+
+  octave_value_list args;
+
+  args(2) = t;
+  args(1) = xdot;
+  args(0) = x;
+
+  if (dassl_fcn)
+    {
+      octave_value_list tmp = dassl_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("dassl");
+	  return retval;
+	}
+
+      int tlen = tmp.length ();
+      if (tlen > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_fcn_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("dassl: ignoring imaginary part returned from user-supplied function");
+	      warned_fcn_imaginary = true;
+	    }
+
+	  retval = ColumnVector (tmp(0).vector_value ());
+
+	  if (tlen > 1)
+	    ires = tmp(1).int_value ();
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("dassl");
+	}
+      else
+	gripe_user_supplied_eval ("dassl");
+    }
+
+  return retval;
+}
+
+Matrix
+dassl_user_jacobian (const ColumnVector& x, const ColumnVector& xdot,
+		     double t, double cj)
+{
+  Matrix retval;
+
+  assert (x.capacity () == xdot.capacity ());
+
+  octave_value_list args;
+
+  args(3) = cj;
+  args(2) = t;
+  args(1) = xdot;
+  args(0) = x;
+
+  if (dassl_jac)
+    {
+      octave_value_list tmp = dassl_jac->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("dassl");
+	  return retval;
+	}
+
+      int tlen = tmp.length ();
+      if (tlen > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_jac_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("dassl: ignoring imaginary part returned from user-supplied jacobian function");
+	      warned_jac_imaginary = true;
+	    }
+
+	  retval = tmp(0).matrix_value ();
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("dassl");
+	}
+      else
+	gripe_user_supplied_eval ("dassl");
+    }
+
+  return retval;
+}
+
+#define DASSL_ABORT() \
+  do \
+    { \
+      unwind_protect::run_frame ("Fdassl"); \
+      return retval; \
+    } \
+  while (0)
+
+#define DASSL_ABORT1(msg) \
+  do \
+    { \
+      ::error ("dassl: " msg); \
+      DASSL_ABORT (); \
+    } \
+  while (0)
+
+#define DASSL_ABORT2(fmt, arg) \
+  do \
+    { \
+      ::error ("dassl: " fmt, arg); \
+      DASSL_ABORT (); \
+    } \
+  while (0)
+
+DEFUN_DLD (dassl, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} dassl (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})\n\
+Solve the set of differential-algebraic equations\n\
+ at iftex\n\
+ at tex\n\
+$$ 0 = f (x, \\dot{x}, t) $$\n\
+with\n\
+$$ x(t_0) = x_0, \\dot{x}(t_0) = \\dot{x}_0 $$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+0 = f (x, xdot, t)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+with\n\
+\n\
+ at example\n\
+x(t_0) = x_0, xdot(t_0) = xdot_0\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+The solution is returned in the matrices @var{x} and @var{xdot},\n\
+with each row in the result matrices corresponding to one of the\n\
+elements in the vector @var{t}.  The first element of @var{t}\n\
+should be @math{t_0} and correspond to the initial state of the\n\
+system @var{x_0} and its derivative @var{xdot_0}, so that the first\n\
+row of the output @var{x} is @var{x_0} and the first row\n\
+of the output @var{xdot} is @var{xdot_0}.\n\
+\n\
+The first argument, @var{fcn}, is a string, inline, or function handle\n\
+that names the function @math{f} to call to compute the vector of\n\
+residuals for the set of equations.  It must have the form\n\
+\n\
+ at example\n\
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
+ at end example\n\
+\n\
+ at noindent\n\
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\
+scalar.\n\
+\n\
+If @var{fcn} is a two-element string array or a two-element cell array\n\
+of strings, inline functions, or function handles, the first element names\n\
+the function @math{f} described above, and the second element names a\n\
+function to compute the modified Jacobian\n\
+\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+J = {\\partial f \\over \\partial x}\n\
+  + c {\\partial f \\over \\partial \\dot{x}}\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at example\n\
+ at group\n\
+      df       df\n\
+jac = -- + c ------\n\
+      dx     d xdot\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+The modified Jacobian function must have the form\n\
+\n\
+ at example\n\
+ at group\n\
+\n\
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})\n\
+\n\
+ at end group\n\
+ at end example\n\
+\n\
+The second and third arguments to @code{dassl} specify the initial\n\
+condition of the states and their derivatives, and the fourth argument\n\
+specifies a vector of output times at which the solution is desired,\n\
+including the time corresponding to the initial condition.\n\
+\n\
+The set of initial states and derivatives are not strictly required to\n\
+be consistent.  In practice, however, @sc{Dassl} is not very good at\n\
+determining a consistent set for you, so it is best if you ensure that\n\
+the initial values result in the function evaluating to zero.\n\
+\n\
+The fifth argument is optional, and may be used to specify a set of\n\
+times that the DAE solver should not integrate past.  It is useful for\n\
+avoiding difficulties with singularities and points where there is a\n\
+discontinuity in the derivative.\n\
+\n\
+After a successful computation, the value of @var{istate} will be\n\
+greater than zero (consistent with the Fortran version of @sc{Dassl}).\n\
+\n\
+If the computation is not successful, the value of @var{istate} will be\n\
+less than zero and @var{msg} will contain additional information.\n\
+\n\
+You can use the function @code{dassl_options} to set optional\n\
+parameters for @code{dassl}.\n\
+ at seealso{daspk, dasrt, lsode}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  warned_fcn_imaginary = false;
+  warned_jac_imaginary = false;
+
+  unwind_protect::begin_frame ("Fdassl");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    DASSL_ABORT1 ("invalid recursive call");
+
+  int nargin = args.length ();
+
+  if (nargin > 3 && nargin < 6 && nargout < 5)
+    {
+      std::string fcn_name, fname, jac_name, jname;
+      dassl_fcn = 0;
+      dassl_jac = 0;
+
+      octave_value f_arg = args(0);
+
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		dassl_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__dassl_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x, xdot, t) y = ");
+		  dassl_fcn = extract_function
+		    (c(0), "dassl", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (dassl_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    dassl_jac = c(1).function_value ();
+		  else
+		    {
+			jac_name = unique_symbol_name ("__dassl_jac__");
+			jname = "function jac = ";
+			jname.append(jac_name);
+			jname.append (" (x, xdot, t, cj) jac = ");
+			dassl_jac = extract_function
+			  (c(1), "dassl", jac_name, jname, "; endfunction");
+
+			if (!dassl_jac)
+			  {
+			    if (fcn_name.length())
+			      clear_function (fcn_name);
+			    dassl_fcn = 0;
+			  }
+		    }
+		}
+	    }
+	  else
+	    DASSL_ABORT1 ("incorrect number of elements in cell array");
+	}
+
+      if (!dassl_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    dassl_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__dassl_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x, xdot, t) y = ");
+		      dassl_fcn = extract_function
+			(f_arg, "dassl", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
+
+		case 2:
+		  {
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__dassl_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x, xdot, t) y = ");
+			dassl_fcn = extract_function
+			  (tmp(0), "dassl", fcn_name, fname, "; endfunction");
+
+			if (dassl_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__dassl_jac__");
+			    jname = "function jac = ";
+			    jname.append(jac_name);
+			    jname.append (" (x, xdot, t, cj) jac = ");
+			    dassl_jac = extract_function
+			      (tmp(1), "dassl", jac_name, jname, 
+			       "; endfunction");
+
+			    if (!dassl_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				dassl_fcn = 0;
+			      }
+			  }
+		      }
+		  }
+		}
+	    }
+	}
+
+      if (error_state || ! dassl_fcn)
+	DASSL_ABORT ();
+
+      ColumnVector state = ColumnVector (args(1).vector_value ());
+
+      if (error_state)
+	DASSL_ABORT1 ("expecting state vector as second argument");
+
+      ColumnVector deriv (args(2).vector_value ());
+
+      if (error_state)
+	DASSL_ABORT1 ("expecting derivative vector as third argument");
+
+      ColumnVector out_times (args(3).vector_value ());
+
+      if (error_state)
+	DASSL_ABORT1 ("expecting output time vector as fourth argument");
+
+      ColumnVector crit_times;
+      int crit_times_set = 0;
+      if (nargin > 4)
+	{
+	  crit_times = ColumnVector (args(4).vector_value ());
+
+	  if (error_state)
+	    DASSL_ABORT1 ("expecting critical time vector as fifth argument");
+
+	  crit_times_set = 1;
+	}
+
+      if (state.capacity () != deriv.capacity ())
+	DASSL_ABORT1 ("x and xdot must have the same size");
+
+      double tzero = out_times (0);
+
+      DAEFunc func (dassl_user_function);
+      if (dassl_jac)
+	func.set_jacobian_function (dassl_user_jacobian);
+
+      DASSL dae (state, deriv, tzero, func);
+
+      dae.set_options (dassl_opts);
+
+      Matrix output;
+      Matrix deriv_output;
+
+      if (crit_times_set)
+	output = dae.integrate (out_times, deriv_output, crit_times);
+      else
+	output = dae.integrate (out_times, deriv_output);
+
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
+      if (! error_state)
+	{
+	  std::string msg = dae.error_message ();
+
+	  retval(3) = msg;
+	  retval(2) = static_cast<double> (dae.integration_state ());
+
+	  if (dae.integration_ok ())
+	    {
+	      retval(1) = deriv_output;
+	      retval(0) = output;
+	    }
+	  else
+	    {
+	      retval(1) = Matrix ();
+	      retval(0) = Matrix ();
+
+	      if (nargout < 3)
+		error ("dassl: %s", msg.c_str ());
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Fdassl");
+
+  return retval;
+}
+
+/*
+
+%% dassl-1.m
+%%
+%% Test dassl() function
+%%
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         20 May 1998
+%%
+%% Problem
+%%
+%%    y1' = -y2,   y1(0) = 1
+%%    y2' =  y1,   y2(0) = 0
+%%
+%% Solution
+%%
+%%    y1(t) = cos(t)
+%%    y2(t) = sin(t)
+%!function res = f (x, xdot, t)
+%!  res = [xdot(1)+x(2); xdot(2)-x(1)];
+%!test
+%! 
+%! x0 = [1; 0];
+%! xdot0 = [0; 1];
+%! t = (0:1:10)';
+%! 
+%! tol = 100 * dassl_options ("relative tolerance");
+%! 
+%! 
+%! [x, xdot] = dassl ("f", x0, xdot0, t);
+%! 
+%! y = [cos(t), sin(t)];
+%! 
+%! assert(all (all (abs (x - y) < tol)));
+
+%% dassl-2.m
+%%
+%% Test dassl() function
+%%
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         20 May 1998
+%%
+%% Based on SLATEC quick check for DASSL by Linda Petzold
+%%
+%% Problem
+%%
+%%   x1' + 10*x1 = 0,   x1(0) = 1
+%%   x1  + x2    = 1,   x2(0) = 0
+%% 
+%%
+%% Solution
+%%
+%%  x1(t) = exp(-10*t)
+%%  x2(t) = 1 - x(1)
+%!function res = f (x, xdot, t)
+%!  res = [xdot(1)+10*x(1); x(1)+x(2)-1];
+%!test
+%! 
+%! x0 = [1; 0];
+%! xdot0 = [-10; 10];
+%! t = (0:0.2:1)';
+%! 
+%! tol = 500 * dassl_options ("relative tolerance");
+%! 
+%! 
+%! [x, xdot] = dassl ("f", x0, xdot0, t);
+%! 
+%! y = [exp(-10*t), 1-exp(-10*t)];
+%! 
+%! assert(all (all (abs (x - y) < tol)));
+
+%!test
+%! dassl_options ("absolute tolerance", eps);
+%! assert(dassl_options ("absolute tolerance") == eps);
+
+%!error <Invalid call to dassl_options.*> dassl_options ("foo", 1, 2);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/det.cc b/src/DLD-FUNCTIONS/det.cc
new file mode 100644
index 0000000..ba1b823
--- /dev/null
+++ b/src/DLD-FUNCTIONS/det.cc
@@ -0,0 +1,253 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DET.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "ops.h"
+
+#include "ov-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-re-diag.h"
+#include "ov-cx-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-perm.h"
+
+#define MAYBE_CAST(VAR, CLASS) \
+  const CLASS *VAR = arg.type_id () == CLASS::static_type_id () ? \
+   dynamic_cast<const CLASS *> (&arg.get_rep ()) : 0
+
+DEFUN_DLD (det, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{d}, @var{rcond}] =} det (@var{a})\n\
+Compute the determinant of @var{a} using @sc{lapack} for full and UMFPACK\n\
+for sparse matrices.  Return an estimate of the reciprocal condition number\n\
+if requested.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+    
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  if (nr == 0 && nc == 0)
+    {
+      retval(0) = 1.0;
+      return retval;
+    }
+
+  int arg_is_empty = empty_arg ("det", nr, nc);
+  if (arg_is_empty < 0)
+    return retval;
+  if (arg_is_empty > 0)
+    return octave_value (Matrix (1, 1, 1.0));
+
+
+  if (nr != nc)
+    {
+      gripe_square_matrix_required ("det");
+      return retval;
+    }
+
+  bool isfloat = arg.is_single_type ();
+
+  if (arg.is_diag_matrix ())
+    {
+      if (arg.is_complex_type ())
+        {
+          if (isfloat)
+            {
+              retval(0) = arg.float_complex_diag_matrix_value ().determinant ().value ();
+              if (nargout > 1)
+                retval(1) = arg.float_complex_diag_matrix_value ().rcond ();
+            }
+          else
+            {
+              retval(0) = arg.complex_diag_matrix_value ().determinant ().value ();
+              if (nargout > 1)
+                retval(1) = arg.complex_diag_matrix_value ().rcond ();
+            }
+        }
+      else
+        {
+          if (isfloat)
+            {
+              retval(0) = arg.float_diag_matrix_value ().determinant ().value ();
+              if (nargout > 1)
+                retval(1) = arg.float_diag_matrix_value ().rcond ();
+            }
+          else
+            {
+              retval(0) = arg.diag_matrix_value ().determinant ().value ();
+              if (nargout > 1)
+                retval(1) = arg.diag_matrix_value ().rcond ();
+            }
+        }
+    }
+  else if (arg.is_perm_matrix ())
+    {
+      retval(0) = static_cast<double> (arg.perm_matrix_value ().determinant ());
+      if (nargout > 1)
+        retval(1) = 1.0;
+    }
+  else if (arg.is_single_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	  octave_idx_type info;
+	  float rcond = 0.0;
+	  // Always compute rcond, so we can detect numerically
+	  // singular matrices.
+	  FloatMatrix m = arg.float_matrix_value ();
+	  if (! error_state)
+	    {
+              MAYBE_CAST (rep, octave_float_matrix);
+              MatrixType mtype = rep ? rep -> matrix_type () : MatrixType ();
+	      FloatDET det = m.determinant (mtype, info, rcond);
+	      retval(1) = rcond;
+	      retval(0) = info == -1 ? static_cast<float>(0.0) : det.value ();
+              if (rep) rep->matrix_type (mtype);
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  octave_idx_type info;
+	  float rcond = 0.0;
+	  // Always compute rcond, so we can detect numerically
+	  // singular matrices.
+	  FloatComplexMatrix m = arg.float_complex_matrix_value ();
+	  if (! error_state)
+	    {
+              MAYBE_CAST (rep, octave_float_complex_matrix);
+              MatrixType mtype = rep ? rep -> matrix_type () : MatrixType ();
+	      FloatComplexDET det = m.determinant (mtype, info, rcond);
+	      retval(1) = rcond;
+	      retval(0) = info == -1 ? FloatComplex (0.0) : det.value ();
+              if (rep) rep->matrix_type (mtype);
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  octave_idx_type info;
+	  double rcond = 0.0;
+	  // Always compute rcond, so we can detect numerically
+	  // singular matrices.
+	  if (arg.is_sparse_type ())
+	    {
+	      SparseMatrix m = arg.sparse_matrix_value ();
+	      if (! error_state)
+		{
+		  DET det = m.determinant (info, rcond);
+		  retval(1) = rcond;
+		  retval(0) = info == -1 ? 0.0 : det.value ();
+		}
+	    }
+	  else
+	    {
+	      Matrix m = arg.matrix_value ();
+	      if (! error_state)
+		{
+                  MAYBE_CAST (rep, octave_matrix);
+                  MatrixType mtype = rep ? rep -> matrix_type () : MatrixType ();
+		  DET det = m.determinant (mtype, info, rcond);
+		  retval(1) = rcond;
+		  retval(0) = info == -1 ? 0.0 : det.value ();
+                  if (rep) rep->matrix_type (mtype);
+		}
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  octave_idx_type info;
+	  double rcond = 0.0;
+	  // Always compute rcond, so we can detect numerically
+	  // singular matrices.
+	  if (arg.is_sparse_type ())
+	    {
+	      SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+	      if (! error_state)
+		{
+		  ComplexDET det = m.determinant (info, rcond);
+		  retval(1) = rcond;
+		  retval(0) = info == -1 ? Complex (0.0) : det.value ();
+		}
+	    }
+	  else
+	    {
+	      ComplexMatrix m = arg.complex_matrix_value ();
+	      if (! error_state)
+		{
+                  MAYBE_CAST (rep, octave_complex_matrix);
+                  MatrixType mtype = rep ? rep -> matrix_type () : MatrixType ();
+		  ComplexDET det = m.determinant (mtype, info, rcond);
+		  retval(1) = rcond;
+		  retval(0) = info == -1 ? Complex (0.0) : det.value ();
+                  if (rep) rep->matrix_type (mtype);
+		}
+	    }
+	}
+      else
+	gripe_wrong_type_arg ("det", arg);
+    }
+  return retval;
+}
+
+/*
+
+%!assert(det ([1, 2; 3, 4]), -2, 10 * eps);
+%!assert(det (single([1, 2; 3, 4])), single(-2), 10 * eps ('single'));
+%!error <Invalid call to det.*> det ();
+%!error <Invalid call to det.*> det (1, 2);
+%!error det ([1, 2; 3, 4; 5, 6]);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/dispatch.cc b/src/DLD-FUNCTIONS/dispatch.cc
new file mode 100644
index 0000000..fb48594
--- /dev/null
+++ b/src/DLD-FUNCTIONS/dispatch.cc
@@ -0,0 +1,276 @@
+/*
+
+Copyright (C) 2001, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton and Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "Cell.h"
+#include "oct-map.h"
+#include "defun-dld.h"
+#include "ov.h"
+#include "ov-fcn.h"
+#include "ov-typeinfo.h"
+#include "pager.h"
+#include "parse.h"
+#include "symtab.h"
+#include "variables.h"
+
+DEFUN_DLD (builtin, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@dots{}]} builtin (@var{f}, @dots{})\n\
+Call the base function @var{f} even if @var{f} is overloaded to\n\
+some other function for the given type signature.\n\
+ at seealso{dispatch}\n\
+ at end deftypefn")
+{
+  octave_value_list retval; 
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      const std::string name (args(0).string_value ());
+ 
+      if (! error_state)
+	{
+	  octave_value fcn = symbol_table::find_function (name);
+
+	  if (fcn.is_defined ())
+	    retval = feval (fcn.function_value (), args.splice (0, 1),
+			    nargout);
+	  else
+	    error ("builtin: lookup for symbol `%s' failed", name.c_str ());
+	}
+      else
+	error ("builtin: expecting function name as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (dispatch, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dispatch (@var{f}, @var{r}, @var{type})\n\
+\n\
+Replace the function @var{f} with a dispatch so that function @var{r}\n\
+is called when @var{f} is called with the first argument of the named\n\
+ at var{type}.  If the type is @var{any} then call @var{r} if no other type\n\
+matches.  The original function @var{f} is accessible using\n\
+ at code{builtin (@var{f}, @dots{})}.\n\
+\n\
+If @var{r} is omitted, clear dispatch function associated with @var{type}.\n\
+\n\
+If both @var{r} and @var{type} are omitted, list dispatch functions\n\
+for @var{f}.\n\
+ at seealso{builtin}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  std::string f, r, t;
+
+  if (nargin > 0 && nargin < 4)
+    {
+      if (nargin > 0)
+	{
+	  f = args(0).string_value ();
+
+	  if (error_state)
+	    {
+	      error ("dispatch: expecting first argument to be function name");
+	      return retval;
+	    }
+	}
+
+      if (nargin > 1)
+	{
+	  r = args(1).string_value ();
+
+	  if (error_state)
+	    {
+	      error ("dispatch: expecting second argument to be function name");
+	      return retval;
+	    }
+	}
+
+      if (nargin > 2)
+	{
+	  t = args(2).string_value ();
+
+	  if (error_state)
+	    {
+	      error ("dispatch: expecting third argument to be type name");
+	      return retval;
+	    }
+	}
+
+      if (nargin == 1)
+	{
+	  if (nargout > 0)
+	    {
+	      symbol_table::fcn_info::dispatch_map_type dm
+		= symbol_table::get_dispatch (f);
+
+	      size_t len = dm.size ();
+
+	      Cell type_field (len, 1);
+	      Cell name_field (len, 1);
+
+	      symbol_table::fcn_info::dispatch_map_type::const_iterator p
+		= dm.begin ();
+
+	      for (size_t i = 0; i < len; i++)
+		{
+		  type_field(i) = p->first;
+		  name_field(i) = p->second;
+
+		  p++;
+		}
+
+	      Octave_map m;
+
+	      m.assign ("type", type_field);
+	      m.assign ("name", name_field);
+
+	      retval = m;
+	    }
+	  else
+	    symbol_table::print_dispatch (octave_stdout, f);
+	}
+      else if (nargin == 2)
+	{
+	  t = r;
+	  symbol_table::clear_dispatch (f, t);
+	}
+      else
+	symbol_table::add_dispatch (f, t, r);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test # builtin function replacement
+%! dispatch('sin','length','string')
+%! assert(sin("abc"),3)
+%! assert(sin(0),0,10*eps); 
+%!test # 'any' function
+%! dispatch('sin','exp','any')
+%! assert(sin(0),1,eps);
+%! assert(sin("abc"),3);
+%!test # 'builtin' function
+%! assert(builtin('sin',0),0,eps);
+%! builtin('eval','x=1;');
+%! assert(x,1);
+%!test # clear function mapping
+%! dispatch('sin','string')
+%! dispatch('sin','any')
+%! assert(sin(0),0,10*eps);
+%!test # oct-file replacement
+%! dispatch('fft','length','string')
+%! assert(fft([1,1]),[2,0]);
+%! assert(fft("abc"),3)
+%! dispatch('fft','string');
+%!test # m-file replacement
+%! dispatch('hamming','length','string')
+%! assert(hamming(1),1)
+%! assert(hamming("abc"),3)
+%! dispatch('hamming','string')
+
+%!test # override preloaded builtin
+%! evalin('base','cos(1);');
+%! dispatch('cos','length','string')
+%! evalin('base','assert(cos("abc"),3)');
+%! evalin('base','assert(cos(0),1,eps)');
+%! dispatch('cos','string')
+%!test # override pre-loaded oct-file
+%! evalin('base','qr(1);');
+%! dispatch('qr','length','string')
+%! evalin('base','assert(qr("abc"),3)');
+%! evalin('base','assert(qr(1),1)');
+%! dispatch('qr','string');
+%!test # override pre-loaded m-file
+%! evalin('base','hanning(1);');
+%! dispatch('hanning','length','string')
+%! evalin('base','assert(hanning("abc"),3)');
+%! evalin('base','assert(hanning(1),1)');
+%! dispatch('hanning','string');
+
+## The following tests have been disabled because creating functions
+## on the fly causes trouble (filesystem timestamp resolution?) and so
+## leads people to complain about the failed tests when the dispatch
+## mechanism is working fine, but it is really the creation of the
+## functions that is failing.  And anyway, this method of function
+## dispatch should be considered obsolete and probably removed from
+## Octave now that we have classes.
+##
+## FIXME I would rather not create dispatch_x/dispatch_y
+## in the current directory!  I don't want them installed accidentally.
+## 
+## %!function echo_to_file (str, name)
+## %!  fid = fopen (name, 'w');
+## %!  if (fid != -1)
+## %!    fprintf (fid, str);
+## %!    fprintf (fid, '\n');
+## %!    fclose (fid);
+## %!  endif
+## 
+## %!test # replace base m-file
+## %! echo_to_file ('function a=dispatch_x(a)', "dispatch_x.m");
+## %! dispatch('dispatch_x','length','string')
+## %! assert(dispatch_x(3),3)
+## %! assert(dispatch_x("a"),1)
+## %! sleep (2);
+## %! echo_to_file ('function a=dispatch_x(a),++a;', "dispatch_x.m");
+## %! rehash();
+## %! assert(dispatch_x(3),4)
+## %! assert(dispatch_x("a"),1)
+## %!test 
+## %! unlink("dispatch_x.m");
+## 
+## %!test # replace dispatch m-file
+## %! echo_to_file ('function a=dispatch_y(a)', "dispatch_y.m");
+## %! dispatch('hello','dispatch_y','complex scalar')
+## %! assert(hello(3i),3i)
+## %! sleep (2);
+## %! echo_to_file ('function a=dispatch_y(a),++a;', "dispatch_y.m");
+## %! rehash();
+## %! assert(hello(3i),1+3i)
+## %!test 
+## %! unlink("dispatch_y.m");
+
+FIXME add tests for preservation of mark_as_command status.
+
+*/
diff --git a/src/DLD-FUNCTIONS/dlmread.cc b/src/DLD-FUNCTIONS/dlmread.cc
new file mode 100644
index 0000000..3176719
--- /dev/null
+++ b/src/DLD-FUNCTIONS/dlmread.cc
@@ -0,0 +1,437 @@
+/*
+
+Copyright (C) 2008, 2009 Jonathan Stickel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Adapted from previous version of dlmread.occ as authored by Kai
+// Habel, but core code has been completely re-written.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <fstream>
+
+#include "file-ops.h"
+#include "lo-ieee.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+static bool
+read_cell_spec (std::istream& is, unsigned long& row, unsigned long& col)
+{
+  bool stat = false;
+
+  if (is.peek () == std::istream::traits_type::eof ())
+    stat = true;
+  else
+    {
+      if (::isalpha (is.peek ()))
+	{
+	  col = 0;
+	  while (is && ::isalpha (is.peek ()))
+	    {
+	      char ch = is.get ();
+	      col *= 26;
+	      if (ch >= 'a')
+		col += ch - 'a';
+	      else
+		col += ch - 'A';
+	    }
+
+	  if (is)
+	    {
+	      is >> row;
+	      row --;
+	      if (is)
+		stat = true;
+	    }
+	}
+    }
+
+  return stat;
+}
+
+static bool
+parse_range_spec (const octave_value& range_spec,
+		  unsigned long& rlo, unsigned long& clo,
+		  unsigned long& rup, unsigned long& cup)
+{
+  bool stat = true;
+
+  if (range_spec.is_string ())
+    {
+      std::istringstream is (range_spec.string_value ());
+      char ch = is.peek ();
+
+      if (ch == '.' || ch == ':')
+	{
+	  rlo = 0;
+	  clo = 0;
+	  ch = is.get ();
+	  if (ch == '.')
+	    {
+	      ch = is.get ();
+	      if (ch != '.')
+		stat = false;
+	    }
+	}
+      else
+	{
+	  stat = read_cell_spec (is, rlo, clo);
+
+	  if (stat)
+	    {
+	      ch = is.peek ();
+	  
+	      if (ch == '.' || ch == ':')
+		{
+		  ch = is.get ();
+		  if (ch == '.')
+		    {
+		      ch = is.get ();
+		      if (!is || ch != '.')
+			stat = false;
+		    }
+
+		  rup = ULONG_MAX - 1;
+		  cup = ULONG_MAX - 1;
+		}
+	      else
+		{
+		  rup = rlo;
+		  cup = clo;
+		  if (!is || !is.eof ())
+		    stat = false;
+		}
+	    }
+	}
+
+      if (stat && is && !is.eof ())
+	stat = read_cell_spec (is, rup, cup);
+
+      if (!is || !is.eof ())
+	stat = false;
+    }
+  else if (range_spec.is_real_matrix () && range_spec.numel () == 4)
+    {
+      ColumnVector range(range_spec.vector_value ());
+      // double --> unsigned int     
+      rlo = static_cast<unsigned long> (range(0));
+      clo = static_cast<unsigned long> (range(1));
+      rup = static_cast<unsigned long> (range(2));
+      cup = static_cast<unsigned long> (range(3));
+    }
+  else 
+    stat = false;
+
+  return stat;
+}
+
+DEFUN_DLD (dlmread, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{data} =} dlmread (@var{file})\n\
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep})\n\
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{r0}, @var{c0})\n\
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{range})\n\
+Read the matrix @var{data} from a text file.  If not defined the separator\n\
+between fields is determined from the file itself.  Otherwise the\n\
+separation character is defined by @var{sep}.\n\
+\n\
+Given two scalar arguments @var{r0} and @var{c0}, these define the starting\n\
+row and column of the data to be read.  These values are indexed from zero,\n\
+such that the first row corresponds to an index of zero.\n\
+\n\
+The @var{range} parameter must be a 4 element vector containing the upper\n\
+left and lower right corner @code{[@var{R0}, at var{C0}, at var{R1}, at var{C1}]} or\n\
+a spreadsheet style range such as 'A2..Q15'.  The lowest index value is zero.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 4) 
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (!args(0).is_string ())
+    {
+      error ("dlmread: 1st argument must be a string");
+      return retval;
+    }
+  
+  std::string fname (args(0).string_value ());
+  if (error_state)
+    return retval;
+
+  std::string tname = file_ops::tilde_expand (fname);
+
+  std::ifstream file (tname.c_str ());
+  if (!file)
+    {
+      error ("dlmread: unable to open file `%s'", fname.c_str ());
+      return retval;
+    }
+  
+  // Set default separator.
+  std::string sep;
+  if (nargin > 1)
+    {
+      if (args(1).is_sq_string ())
+	sep = do_string_escapes (args(1).string_value ());
+      else
+	sep = args(1).string_value ();
+
+      if (error_state)
+	return retval;
+    }
+  
+  // Take a subset if a range was given.
+  unsigned long r0 = 0, c0 = 0, r1 = ULONG_MAX-1, c1 = ULONG_MAX-1;
+  if (nargin > 2)
+    {
+      if (nargin == 3)
+	{
+	  if (!parse_range_spec (args (2), r0, c0, r1, c1))
+	    error ("dlmread: error parsing range");
+	} 
+      else if (nargin == 4) 
+	{
+	  r0 = args(2).ulong_value ();
+	  c0 = args(3).ulong_value ();
+
+	  if (error_state)
+	    return retval;
+	}
+    }
+
+  if (!error_state)
+    {
+      unsigned long i = 0, j = 0, r = 1, c = 1, rmax = 0, cmax = 0;
+
+      Matrix rdata;
+      ComplexMatrix cdata;
+
+      bool iscmplx = false;
+      bool sepflag = false;
+
+      unsigned long maxrows = r1 - r0;
+
+      std::string line;
+
+      // Skip the r0 leading lines as these might be a header.
+      for (unsigned long m = 0; m < r0; m++)
+	getline (file, line);
+      r1 -= r0;
+
+      // Read in the data one field at a time, growing the data matrix
+      // as needed.
+      while (getline (file, line))
+	{
+	  // Skip blank lines for compatibility.
+	  if (line.find_first_not_of (" \t") == std::string::npos)
+	    continue;
+
+	  // To be compatible with matlab, blank separator should
+	  // correspond to whitespace as delimter.
+	  if (!sep.length ())
+	    {
+	      size_t n = line.find_first_of (",:; \t", 
+					     line.find_first_of ("0123456789"));
+	      if (n == std::string::npos)
+		{
+		  sep = " \t";
+		  sepflag = true;
+		}
+	      else
+		{
+		  char ch = line.at (n);
+
+		  switch (line.at (n))
+		    {
+		    case ' ':
+		    case '\t':
+		      sepflag = true;
+		      sep = " \t";
+		      break;
+
+		    default:
+		      sep = ch;
+		      break;
+		    }
+		}
+	    }
+
+	  r = (r > i + 1 ? r : i + 1);
+	  j = 0;
+	  size_t pos1 = 0;
+	  do
+	    {
+	      size_t pos2 = line.find_first_of (sep, pos1);
+	      std::string str = line.substr (pos1, pos2 - pos1);
+
+	      if (sepflag && pos2 != std::string::npos)
+		// Treat consecutive separators as one.
+		pos2 = line.find_first_not_of (sep, pos2) - 1;
+
+	      c = (c > j + 1 ? c : j + 1);
+	      if (r > rmax || c > cmax)
+		{ 
+		  // Use resize_and_fill for the case of not-equal
+		  // length rows.
+		  if (iscmplx)
+		    cdata.resize_fill (r, c, 0);
+		  else
+		    rdata.resize_fill (r, c, 0);
+		  rmax = r;
+		  cmax = c;
+		}
+
+	      std::istringstream tmp_stream (str);
+	      double x = octave_read_double (tmp_stream);
+	      if (tmp_stream)
+		{
+		  if (tmp_stream.eof ())
+		    if (iscmplx)
+		      cdata(i,j++) = x;
+		    else
+		      rdata(i,j++) = x;
+		  else
+		    {
+		      double y = octave_read_double (tmp_stream);
+
+		      if (!iscmplx && y != 0.)
+			{
+			  iscmplx = true;
+			  cdata = ComplexMatrix (rdata);
+			}
+
+		      if (iscmplx)
+			cdata(i,j++) = Complex (x, y);
+		      else
+			rdata(i,j++) = x;
+		    }
+		}
+	      else if (iscmplx)
+		cdata(i,j++) = 0.;
+	      else
+		rdata(i,j++) = 0.;
+
+	      if (pos2 != std::string::npos)
+		pos1 = pos2 + 1;
+	      else
+		pos1 = std::string::npos;
+
+	    }
+	  while (pos1 != std::string::npos);
+
+	  if (nargin == 3 && i == maxrows)
+	    break;
+
+	  i++;
+	}
+ 
+      if (nargin > 2)
+	{
+	  if (nargin == 3)
+	    {
+	      if (r1 >= r)
+		r1 = r - 1;
+	      if (c1 >= c)
+		c1 = c - 1;
+	    }
+	  else if (nargin == 4) 
+	    {
+	      // If r1 and c1 are not given, use what was found to be
+	      // the maximum.
+	      r1 = r - 1;
+	      c1 = c - 1;
+	    }
+
+	  // Now take the subset of the matrix.
+	  if (iscmplx)
+	    {
+	      cdata = cdata.extract (0, c0, r1, c1);
+	      cdata.resize (r1 + 1, c1 - c0 + 1);
+	    }
+	  else
+	    {
+	      rdata = rdata.extract (0, c0, r1, c1);
+	      rdata.resize (r1 + 1, c1 - c0 + 1);
+	    }
+	}
+  
+      if (iscmplx)
+	retval(0) = cdata;
+      else
+	retval(0) = rdata;
+    }
+
+  return retval;
+}
+
+/*
+
+%!shared file
+%! file = tmpnam (); 
+%! fid = fopen (file, "wt");
+%! fwrite (fid, "1, 2, 3\n4, 5, 6\n7, 8, 9\n10, 11, 12");
+%! fclose (fid);
+
+%!assert (dlmread (file), [1, 2, 3; 4, 5, 6; 7, 8, 9;10, 11, 12]);
+%!assert (dlmread (file, ","), [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ",", [1, 0, 2, 1]), [4, 5; 7, 8]);
+%!assert (dlmread (file, ",", "B1..C2"), [2, 3; 5, 6]);
+%!assert (dlmread (file, ",", "B1:C2"), [2, 3; 5, 6]);
+%!assert (dlmread (file, ",", "..C2"), [1, 2, 3; 4, 5, 6]);
+%!assert (dlmread (file, ",", 0, 1), [2, 3; 5, 6; 8, 9; 11, 12]);
+%!assert (dlmread (file, ",", "B1.."), [2, 3; 5, 6; 8, 9; 11, 12]);
+%!error (dlmread (file, ",", [0 1]))
+
+%!test
+%! unlink (file);
+
+%!shared file
+%! file = tmpnam (); 
+%! fid = fopen (file, "wt");
+%! fwrite (fid, "1, 2, 3\n4+4i, 5, 6\n7, 8, 9\n10, 11, 12");
+%! fclose (fid);
+
+%!assert (dlmread (file), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ","), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ",", [1, 0, 2, 1]), [4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", "A2..B3"), [4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", "A2:B3"), [4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", "..B3"), [1, 2; 4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", 1, 0), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ",", "A2.."), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!error (dlmread (file, ",", [0 1]))
+
+%!test
+%! unlink (file);
+
+*/
diff --git a/src/DLD-FUNCTIONS/dmperm.cc b/src/DLD-FUNCTIONS/dmperm.cc
new file mode 100644
index 0000000..e0af39a
--- /dev/null
+++ b/src/DLD-FUNCTIONS/dmperm.cc
@@ -0,0 +1,236 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#include "oct-sparse.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "SparseQR.h"
+#include "SparseCmplxQR.h"
+
+#ifdef IDX_TYPE_LONG
+#define CXSPARSE_NAME(name) cs_dl ## name
+#else
+#define CXSPARSE_NAME(name) cs_di ## name
+#endif
+
+static RowVector
+put_int (octave_idx_type *p, octave_idx_type n)
+{
+  RowVector ret (n);
+  for (octave_idx_type i = 0; i < n; i++)
+    ret.xelem(i) = p[i] + 1;
+  return ret;
+}
+
+#if HAVE_CXSPARSE
+static octave_value_list
+dmperm_internal (bool rank, const octave_value arg, int nargout)
+{
+  octave_value_list retval;
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+  SparseMatrix m;
+  SparseComplexMatrix cm;
+  CXSPARSE_NAME () csm;
+  csm.m = nr;
+  csm.n = nc;
+  csm.x = 0;
+  csm.nz = -1;
+
+  if (arg.is_real_type ())
+    {
+      m = arg.sparse_matrix_value ();
+      csm.nzmax = m.nnz();
+      csm.p = m.xcidx ();
+      csm.i = m.xridx ();
+    }
+  else
+    {
+      cm = arg.sparse_complex_matrix_value ();
+      csm.nzmax = cm.nnz();
+      csm.p = cm.xcidx ();
+      csm.i = cm.xridx ();
+    }
+
+  if (!error_state)
+    {
+      if (nargout <= 1 || rank)
+	{
+#if defined(CS_VER) && (CS_VER >= 2)
+	  octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm, 0);
+#else
+	  octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm);
+#endif
+	  if (rank)
+	    {
+	      octave_idx_type r = 0;
+	      for (octave_idx_type i = 0; i < nc; i++)
+		if (jmatch[nr+i] >= 0)
+		  r++;
+	      retval(0) = static_cast<double>(r);
+	    }
+	  else
+	    retval(0) = put_int (jmatch + nr, nc);
+	  CXSPARSE_NAME (_free) (jmatch);
+	}
+      else
+	{
+#if defined(CS_VER) && (CS_VER >= 2)
+	  CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm, 0);
+#else
+	  CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm);
+#endif
+
+	  //retval(5) = put_int (dm->rr, 5);
+	  //retval(4) = put_int (dm->cc, 5);
+#if defined(CS_VER) && (CS_VER >= 2)
+	  retval(3) = put_int (dm->s, dm->nb+1);
+	  retval(2) = put_int (dm->r, dm->nb+1);
+	  retval(1) = put_int (dm->q, nc);
+	  retval(0) = put_int (dm->p, nr);
+#else
+	  retval(3) = put_int (dm->S, dm->nb+1);
+	  retval(2) = put_int (dm->R, dm->nb+1);
+	  retval(1) = put_int (dm->Q, nc);
+	  retval(0) = put_int (dm->P, nr);
+#endif
+	  CXSPARSE_NAME (_dfree) (dm);
+	}
+    }
+  return retval;
+}
+#endif
+
+DEFUN_DLD (dmperm, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} dmperm (@var{s})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{q}, @var{r}, @var{s}] =} dmperm (@var{s})\n\
+\n\
+ at cindex Dulmage-Mendelsohn decomposition\n\
+Perform a Dulmage-Mendelsohn permutation on the sparse matrix @var{s}.\n\
+With a single output argument @dfn{dmperm} performs the row permutations\n\
+ at var{p} such that @code{@var{s} (@var{p},:)} has no zero elements on the\n\
+diagonal.\n\
+\n\
+Called with two or more output arguments, returns the row and column\n\
+permutations, such that @code{@var{s} (@var{p}, @var{q})} is in block\n\
+triangular form.  The values of @var{r} and @var{s} define the boundaries\n\
+of the blocks.  If @var{s} is square then @code{@var{r} == @var{s}}.\n\
+\n\
+The method used is described in: A. Pothen & C.-J. Fan. Computing the block\n\
+triangular form of a sparse matrix. ACM Trans. Math. Software,\n\
+16(4):303-324, 1990.\n\
+ at seealso{colamd, ccolamd}\n\
+ at end deftypefn")
+{
+  int nargin = args.length();
+  octave_value_list retval;
+  
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#if HAVE_CXSPARSE
+  retval = dmperm_internal (false, args(0), nargout);
+#else
+  error ("dmperm: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/* 
+
+%!testif HAVE_CXSPARSE
+%! n=20;
+%! a=speye(n,n);a=a(randperm(n),:);
+%! assert(a(dmperm(a),:),speye(n))
+
+%!testif HAVE_CXSPARSE
+%! n=20;
+%! d=0.2;
+%! a=tril(sprandn(n,n,d),-1)+speye(n,n);
+%! a=a(randperm(n),randperm(n));
+%! [p,q,r,s]=dmperm(a);
+%! assert(tril(a(p,q),-1),sparse(n,n))
+
+*/
+
+DEFUN_DLD (sprank, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} sprank (@var{s})\n\
+\n\
+ at cindex Structural Rank\n\
+Calculates the structural rank of a sparse matrix @var{s}.  Note that\n\
+only the structure of the matrix is used in this calculation based on\n\
+a Dulmage-Mendelsohn permutation to block triangular form.  As such the numerical\n\
+rank of the matrix @var{s} is bounded by @code{sprank (@var{s}) >=\n\
+rank (@var{s})}.  Ignoring floating point errors @code{sprank (@var{s}) ==\n\
+rank (@var{s})}.\n\
+ at seealso{dmperm}\n\
+ at end deftypefn")
+{
+  int nargin = args.length();
+  octave_value_list retval;
+  
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#if HAVE_CXSPARSE
+  retval = dmperm_internal (true, args(0), nargout);
+#else
+  error ("sprank: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/* 
+
+%!error(sprank(1,2));
+%!testif HAVE_CXSPARSE
+%! assert(sprank(speye(20)), 20)
+%!testif HAVE_CXSPARSE
+%! assert(sprank([1,0,2,0;2,0,4,0]),2)
+
+*/
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/eig.cc b/src/DLD-FUNCTIONS/eig.cc
new file mode 100644
index 0000000..66d6d93
--- /dev/null
+++ b/src/DLD-FUNCTIONS/eig.cc
@@ -0,0 +1,342 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "EIG.h"
+#include "fEIG.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (eig, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {@var{lambda} =} eig (@var{a})\n\
+ at deftypefnx {Loadable Function} {@var{lambda} =} eig (@var{a}, @var{b})\n\
+ at deftypefnx {Loadable Function} {[@var{v}, @var{lambda}] =} eig (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{v}, @var{lambda}] =} eig (@var{a}, @var{b})\n\
+The eigenvalues (and eigenvectors) of a matrix are computed in a several\n\
+step process which begins with a Hessenberg decomposition, followed by a\n\
+Schur decomposition, from which the eigenvalues are apparent.  The\n\
+eigenvectors, when desired, are computed by further manipulations of the\n\
+Schur decomposition.\n\
+\n\
+The eigenvalues returned by @code{eig} are not ordered.\n\
+ at seealso{eigs}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 2 || nargin == 0 || nargout > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg_a, arg_b;
+
+  octave_idx_type nr_a = 0, nr_b = 0;
+  octave_idx_type nc_a = 0, nc_b = 0;
+
+  arg_a = args(0);
+  nr_a = arg_a.rows ();
+  nc_a = arg_a.columns ();
+
+  int arg_is_empty = empty_arg ("eig", nr_a, nc_a);
+  if (arg_is_empty < 0)
+    return retval;
+  else if (arg_is_empty > 0)
+    return octave_value_list (2, Matrix ());
+
+  if (!(arg_a.is_single_type () || arg_a.is_double_type ()))
+    {
+      gripe_wrong_type_arg ("eig", arg_a);
+      return retval;
+    }
+
+  if (nargin == 2)
+    {
+      arg_b = args(1);
+      nr_b = arg_b.rows ();
+      nc_b = arg_b.columns ();
+
+      arg_is_empty = empty_arg ("eig", nr_b, nc_b);
+      if (arg_is_empty < 0)
+        return retval;
+      else if (arg_is_empty > 0)
+        return octave_value_list (2, Matrix ());
+
+      if (!(arg_b.is_single_type() || arg_b.is_double_type ()))
+	{
+	  gripe_wrong_type_arg ("eig", arg_b);
+	  return retval;
+	}
+    }
+
+  if (nr_a != nc_a)
+    {
+      gripe_square_matrix_required ("eig");
+      return retval;
+    }
+
+  if (nargin == 2 && nr_b != nc_b)
+    {
+      gripe_square_matrix_required ("eig");
+      return retval;
+    }
+
+  Matrix tmp_a, tmp_b;
+  ComplexMatrix ctmp_a, ctmp_b;
+  FloatMatrix ftmp_a, ftmp_b;
+  FloatComplexMatrix fctmp_a, fctmp_b;
+
+  if (arg_a.is_single_type ())
+    {
+      FloatEIG result;
+
+      if (nargin == 1)
+	{
+	  if (arg_a.is_real_type ())
+	    {
+	      ftmp_a = arg_a.float_matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = FloatEIG (ftmp_a, nargout > 1);
+	    }
+	  else
+	    {
+	      fctmp_a = arg_a.float_complex_matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = FloatEIG (fctmp_a, nargout > 1);
+	    }
+	}
+      else if (nargin == 2)
+	{
+	  if (arg_a.is_real_type () && arg_b.is_real_type ())
+	    {
+	      ftmp_a = arg_a.float_matrix_value ();
+	      ftmp_b = arg_b.float_matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = FloatEIG (ftmp_a, ftmp_b, nargout > 1);
+	    }
+	  else
+	    {
+	      fctmp_a = arg_a.float_complex_matrix_value ();
+	      fctmp_b = arg_b.float_complex_matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = FloatEIG (fctmp_a, fctmp_b, nargout > 1);
+	    }
+	}
+
+      if (! error_state)
+	{
+	  if (nargout == 0 || nargout == 1)
+	    {
+	      retval(0) = result.eigenvalues ();
+	    }
+	  else
+	    {
+	      // Blame it on Matlab.
+
+	      FloatComplexDiagMatrix d (result.eigenvalues ());
+
+	      retval(1) = d;
+	      retval(0) = result.eigenvectors ();
+	    }
+	}
+    }
+  else
+    {
+      EIG result;
+
+      if (nargin == 1)
+	{
+	  if (arg_a.is_real_type ())
+	    {
+	      tmp_a = arg_a.matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = EIG (tmp_a, nargout > 1);
+	    }
+	  else
+	    {
+	      ctmp_a = arg_a.complex_matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = EIG (ctmp_a, nargout > 1);
+	    }
+	}
+      else if (nargin == 2)
+	{
+	  if (arg_a.is_real_type () && arg_b.is_real_type ())
+	    {
+	      tmp_a = arg_a.matrix_value ();
+	      tmp_b = arg_b.matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = EIG (tmp_a, tmp_b, nargout > 1);
+	    }
+	  else 
+	    {
+	      ctmp_a = arg_a.complex_matrix_value ();
+	      ctmp_b = arg_b.complex_matrix_value ();
+
+	      if (error_state)
+	        return retval;
+	      else
+	        result = EIG (ctmp_a, ctmp_b, nargout > 1);
+	    }
+	}
+
+      if (! error_state)
+	{
+	  if (nargout == 0 || nargout == 1)
+	    {
+	      retval(0) = result.eigenvalues ();
+	    }
+	  else
+	    {
+	      // Blame it on Matlab.
+
+	      ComplexDiagMatrix d (result.eigenvalues ());
+
+	      retval(1) = d;
+	      retval(0) = result.eigenvectors ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(eig ([1, 2; 2, 1]), [-1; 3], sqrt (eps));
+
+%!test
+%! [v, d] = eig ([1, 2; 2, 1]);
+%! x = 1 / sqrt (2);
+%! assert(d, [-1, 0; 0, 3], sqrt (eps));
+%! assert(v, [-x, x; x, x], sqrt (eps));
+
+%!assert(eig (single ([1, 2; 2, 1])), single([-1; 3]), sqrt (eps('single')));
+
+%!test
+%! [v, d] = eig (single([1, 2; 2, 1]));
+%! x = single(1 / sqrt (2));
+%! assert(d, single([-1, 0; 0, 3]), sqrt (eps('single')));
+%! assert(v, [-x, x; x, x], sqrt (eps('single')));
+
+%!test
+%! A = [1, 2; -1, 1]; B = [3, 3; 1, 2];
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
+
+%!test
+%! A = single([1, 2; -1, 1]); B = single([3, 3; 1, 2]);
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps('single')));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps('single')));
+
+%!test
+%! A = [1, 2; 2, 1]; B = [3, -2; -2, 3];
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
+
+%!test
+%! A = single([1, 2; 2, 1]); B = single([3, -2; -2, 3]);
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps('single')));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps('single')));
+
+%!test
+%! A = [1+3i, 2+i; 2-i, 1+3i]; B = [5+9i, 2+i; 2-i, 5+9i];
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
+
+%!test
+%! A = single([1+3i, 2+i; 2-i, 1+3i]); B = single([5+9i, 2+i; 2-i, 5+9i]);
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps('single')));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps('single')));
+
+%!test
+%! A = [1+3i, 2+3i; 3-8i, 8+3i]; B = [8+i, 3+i; 4-9i, 3+i];
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
+
+%!test
+%! A = single([1+3i, 2+3i; 3-8i, 8+3i]); B = single([8+i, 3+i; 4-9i, 3+i]);
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps('single')));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps('single')));
+
+%!test
+%! A = [1, 2; 3, 8]; B = [8, 3; 4, 3];
+%! [v, d] = eig (A, B);
+%! assert(A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
+%! assert(A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
+
+%!error <Invalid call to eig.*> eig ();
+%!error <Invalid call to eig.*> eig ([1, 2; 3, 4], [4, 3; 2, 1], 1);
+%!error eig ([1, 2; 3, 4], 2);
+%!error eig ([1, 2; 3, 4; 5, 6]);
+%!error eig ("abcd");
+%!error eig ([1 2 ; 2 3], "abcd");
+%!error eig (false, [1 2 ; 2 3]);
+
+ */
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/eigs.cc b/src/DLD-FUNCTIONS/eigs.cc
new file mode 100755
index 0000000..8332aff
--- /dev/null
+++ b/src/DLD-FUNCTIONS/eigs.cc
@@ -0,0 +1,1517 @@
+/*
+
+Copyright (C) 2005, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "quit.h"
+#include "variables.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "oct-map.h"
+#include "pager.h"
+#include "unwind-prot.h"
+
+#include "eigs-base.cc"
+
+// Global pointer for user defined function.
+static octave_function *eigs_fcn = 0;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+ColumnVector
+eigs_func (const ColumnVector &x, int &eigs_error)
+{
+  ColumnVector retval;
+  octave_value_list args;
+  args(0) = x;
+
+  if (eigs_fcn)
+    {
+      octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  eigs_error = 1;
+	  gripe_user_supplied_eval ("eigs");
+	  return retval;
+	}
+
+      if (tmp.length () && tmp(0).is_defined ())
+	{
+	  if (! warned_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("eigs: ignoring imaginary part returned from user-supplied function");
+	      warned_imaginary = true;
+	    }
+
+	  retval = ColumnVector (tmp(0).vector_value ());
+
+	  if (error_state)
+	    {
+	      eigs_error = 1;
+	      gripe_user_supplied_eval ("eigs");
+	    }
+	}
+      else
+	{
+	  eigs_error = 1;
+	  gripe_user_supplied_eval ("eigs");
+	}
+    }
+
+  return retval;
+}
+
+ComplexColumnVector
+eigs_complex_func (const ComplexColumnVector &x, int &eigs_error)
+{
+  ComplexColumnVector retval;
+  octave_value_list args;
+  args(0) = x;
+
+  if (eigs_fcn)
+    {
+      octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  eigs_error = 1;
+	  gripe_user_supplied_eval ("eigs");
+	  return retval;
+	}
+
+      if (tmp.length () && tmp(0).is_defined ())
+	{
+	  retval = ComplexColumnVector (tmp(0).complex_vector_value ());
+
+	  if (error_state)
+	    {
+	      eigs_error = 1;
+	      gripe_user_supplied_eval ("eigs");
+	    }
+	}
+      else
+	{
+	  eigs_error = 1;
+	  gripe_user_supplied_eval ("eigs");
+	}
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (eigs, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{d}} = eigs (@var{a})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k}, @var{sigma})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k}, @var{sigma}, at var{opts})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k}, @var{sigma})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k}, @var{sigma}, @var{opts})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k}, @var{sigma})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k}, @var{sigma})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k}, @var{sigma}, @var{opts})\n\
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}]} = eigs (@var{a}, @dots{})\n\
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}]} = eigs (@var{af}, @var{n}, @dots{})\n\
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}, @var{flag}]} = eigs (@var{a}, @dots{})\n\
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}, @var{flag}]} = eigs (@var{af}, @var{n}, @dots{})\n\
+Calculate a limited number of eigenvalues and eigenvectors of @var{a},\n\
+based on a selection criteria.  The number eigenvalues and eigenvectors to\n\
+calculate is given by @var{k} whose default value is 6.\n\
+\n\
+By default @code{eigs} solve the equation\n\
+ at iftex\n\
+ at tex\n\
+$A \\nu = \\lambda \\nu$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifinfo\n\
+ at code{A * v = lambda * v}\n\
+ at end ifinfo\n\
+, where\n\
+ at iftex\n\
+ at tex\n\
+$\\lambda$ is a scalar representing one of the eigenvalues, and $\\nu$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifinfo\n\
+ at code{lambda} is a scalar representing one of the eigenvalues, and @code{v}\n\
+ at end ifinfo\n\
+is the corresponding eigenvector.  If given the positive definite matrix\n\
+ at var{B} then @code{eigs} solves the general eigenvalue equation\n\
+ at iftex\n\
+ at tex\n\
+$A \\nu = \\lambda B \\nu$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifinfo\n\
+ at code{A * v = lambda * B * v}\n\
+ at end ifinfo\n\
+.\n\
+\n\
+The argument @var{sigma} determines which eigenvalues are returned.\n\
+ at var{sigma} can be either a scalar or a string.  When @var{sigma} is a scalar,\n\
+the @var{k} eigenvalues closest to @var{sigma} are returned.  If @var{sigma}\n\
+is a string, it must have one of the values\n\
+\n\
+ at table @asis\n\
+ at item 'lm'\n\
+Largest magnitude (default).\n\
+\n\
+ at item 'sm'\n\
+Smallest magnitude.\n\
+\n\
+ at item 'la'\n\
+Largest Algebraic (valid only for real symmetric problems).\n\
+\n\
+ at item 'sa'\n\
+Smallest Algebraic (valid only for real symmetric problems).\n\
+\n\
+ at item 'be'\n\
+Both ends, with one more from the high-end if @var{k} is odd (valid only for\n\
+real symmetric problems).\n\
+\n\
+ at item 'lr'\n\
+Largest real part (valid only for complex or unsymmetric problems).\n\
+\n\
+ at item 'sr'\n\
+Smallest real part (valid only for complex or unsymmetric problems).\n\
+\n\
+ at item 'li'\n\
+Largest imaginary part (valid only for complex or unsymmetric problems).\n\
+\n\
+ at item 'si'\n\
+Smallest imaginary part (valid only for complex or unsymmetric problems).\n\
+ at end table\n\
+\n\
+If @var{opts} is given, it is a structure defining some of the options that\n\
+ at code{eigs} should use.  The fields of the structure @var{opts} are\n\
+\n\
+ at table @code\n\
+ at item issym\n\
+If @var{af} is given, then flags whether the function @var{af} defines a\n\
+symmetric problem.  It is ignored if @var{a} is given.  The default is false.\n\
+\n\
+ at item isreal\n\
+If @var{af} is given, then flags whether the function @var{af} defines a\n\
+real problem.  It is ignored if @var{a} is given.  The default is true.\n\
+\n\
+ at item tol\n\
+Defines the required convergence tolerance, given as @code{tol * norm (A)}.\n\
+The default is @code{eps}.\n\
+\n\
+ at item maxit\n\
+The maximum number of iterations.  The default is 300.\n\
+\n\
+ at item p\n\
+The number of Lanzcos basis vectors to use.  More vectors will result in\n\
+faster convergence, but a larger amount of memory.  The optimal value of 'p'\n\
+is problem dependent and should be in the range @var{k} to @var{n}.  The\n\
+default value is @code{2 * @var{k}}.\n\
+\n\
+ at item v0\n\
+The starting vector for the computation.  The default is to have @sc{Arpack}\n\
+randomly generate a starting vector.\n\
+\n\
+ at item disp\n\
+The level of diagnostic printout.  If @code{disp} is 0 then there is no\n\
+printout.  The default value is 1.\n\
+\n\
+ at item cholB\n\
+Flag if @code{chol (@var{b})} is passed rather than @var{b}.  The default is\n\
+false.\n\
+\n\
+ at item permB\n\
+The permutation vector of the Cholesky factorization of @var{b} if\n\
+ at code{cholB} is true.  That is @code{chol ( @var{b} (permB, permB))}.  The\n\
+default is @code{1:@var{n}}.\n\
+\n\
+ at end table\n\
+\n\
+It is also possible to represent @var{a} by a function denoted @var{af}.\n\
+ at var{af} must be followed by a scalar argument @var{n} defining the length\n\
+of the vector argument accepted by @var{af}.  @var{af} can be passed either\n\
+as an inline function, function handle or as a string.  In the case where\n\
+ at var{af} is passed as a string, the name of the string defines the function\n\
+to use.\n\
+\n\
+ at var{af} is a function of the form @code{function y = af (x), y = @dots{};\n\
+endfunction}, where the required return value of @var{af} is determined by\n\
+the value of @var{sigma}, and are\n\
+\n\
+ at table @code\n\
+ at item A * x\n\
+If @var{sigma} is not given or is a string other than 'sm'.\n\
+\n\
+ at item A \\ x\n\
+If @var{sigma} is 'sm'.\n\
+\n\
+ at item (A - sigma * I) \\ x\n\
+for standard eigenvalue problem, where @code{I} is the identity matrix of\n\
+the same size as @code{A}.  If @var{sigma} is zero, this reduces the\n\
+ at code{A \\ x}.\n\
+\n\
+ at item (A - sigma * B) \\ x\n\
+for the general eigenvalue problem.\n\
+ at end table\n\
+\n\
+The return arguments of @code{eigs} depends on the number of return\n\
+arguments.  With a single return argument, a vector @var{d} of length @var{k}\n\
+is returned, represent the @var{k} eigenvalues that have been found.  With two\n\
+return arguments, @var{v} is a @var{n}-by- at var{k} matrix whose columns are\n\
+the @var{k} eigenvectors corresponding to the returned eigenvalues.  The\n\
+eigenvalues themselves are then returned in @var{d} in the form of a\n\
+ at var{n}-by- at var{k} matrix, where the elements on the diagonal are the\n\
+eigenvalues.\n\
+\n\
+Given a third return argument @var{flag}, @code{eigs} also returns the status\n\
+of the convergence.  If @var{flag} is 0, then all eigenvalues have converged,\n\
+otherwise not.\n\
+\n\
+This function is based on the @sc{Arpack} package, written by R Lehoucq,\n\
+K Maschhoff, D Sorensen and C Yang.  For more information see\n\
+ at url{http://www.caam.rice.edu/software/ARPACK/}.\n\
+\n\
+ at end deftypefn\n\
+ at seealso{eig, svds}")
+{
+  octave_value_list retval;
+#ifdef HAVE_ARPACK
+  int nargin = args.length ();
+  std::string fcn_name;
+  octave_idx_type n = 0;
+  octave_idx_type k = 6;
+  Complex sigma = 0.;
+  double sigmar, sigmai;
+  bool have_sigma = false;
+  std::string typ = "LM";
+  Matrix amm, bmm, bmt;
+  ComplexMatrix acm, bcm, bct;
+  SparseMatrix asmm, bsmm, bsmt;
+  SparseComplexMatrix ascm, bscm, bsct;
+  int b_arg = 0;
+  bool have_b = false;
+  bool have_a_fun = false;
+  bool a_is_complex = false;
+  bool b_is_complex = false;
+  bool symmetric = false;
+  bool cholB = false;
+  bool a_is_sparse = false;
+  ColumnVector permB;
+  int arg_offset = 0;
+  double tol = DBL_EPSILON;
+  int maxit = 300;
+  int disp = 0;
+  octave_idx_type p = -1;
+  ColumnVector resid;
+  ComplexColumnVector cresid;
+  octave_idx_type info = 1;
+  char bmat = 'I';
+
+  warned_imaginary = false;
+
+  unwind_protect::begin_frame ("Feigs");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    {
+      error ("eigs: invalid recursive call");
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      unwind_protect::run_frame ("Feigs");
+      return retval;
+    }
+
+  if (nargin == 0)
+    print_usage ();
+  else if (args(0).is_function_handle () || args(0).is_inline_function ()
+	   || args(0).is_string ())
+    {
+      if (args(0).is_string ())
+	{
+	  std::string name = args(0).string_value ();
+	  std::string fname = "function y = ";
+	  fcn_name = unique_symbol_name ("__eigs_fcn_");
+	  fname.append (fcn_name);
+	  fname.append ("(x) y = ");
+	  eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname,
+				       "; endfunction");
+	}
+      else
+	eigs_fcn = args(0).function_value ();
+
+      if (!eigs_fcn)
+	{
+	  error ("eigs: unknown function");
+	  return retval;
+	}
+
+      if (nargin < 2)
+	{
+	  error ("eigs: incorrect number of arguments");
+	  return retval;
+	}
+      else
+	{
+	  n = args(1).nint_value ();
+	  arg_offset = 1;
+	  have_a_fun = true;
+	}
+    }
+  else
+    {
+      if (args(0).is_complex_type ())
+	{
+	  if (args(0).is_sparse_type ())
+	    {
+	      ascm = (args(0).sparse_complex_matrix_value());
+	      a_is_sparse = true;
+	    }
+	  else
+	    acm = (args(0).complex_matrix_value());
+	  a_is_complex = true;
+	  symmetric = false; // ARAPACK doesn't special case complex symmetric
+	}
+      else
+	{
+	  if (args(0).is_sparse_type ())
+	    {
+	      asmm = (args(0).sparse_matrix_value());
+	      a_is_sparse = true;
+	      symmetric = asmm.is_symmetric();
+	    }
+	  else
+	    {
+	      amm = (args(0).matrix_value());
+	      symmetric = amm.is_symmetric();
+	    }
+	}
+
+    }
+
+  // Note hold off reading B till later to avoid issues of double 
+  // copies of the matrix if B is full/real while A is complex..
+  if (!error_state && nargin > 1 + arg_offset && 
+      !(args(1 + arg_offset).is_real_scalar ()))
+    {
+      if (args(1+arg_offset).is_complex_type ())
+	{
+	  b_arg = 1+arg_offset;
+	  have_b = true;
+	  bmat = 'G';
+	  b_is_complex = true;
+	  arg_offset++;
+	}
+      else
+	{
+	  b_arg = 1+arg_offset;
+	  have_b = true;
+	  bmat = 'G';
+	  arg_offset++;
+	}
+    }
+
+  if (!error_state && nargin > (1+arg_offset))
+    k = args(1+arg_offset).nint_value ();
+
+  if (!error_state && nargin > (2+arg_offset))
+    {
+      if (args(2+arg_offset).is_string ())
+	{
+	  typ = args(2+arg_offset).string_value ();
+
+	  // Use STL function to convert to upper case
+	  transform (typ.begin (), typ.end (), typ.begin (), toupper);
+
+	  sigma = 0.;
+	}
+      else
+	{
+	  sigma = args(2+arg_offset).complex_value ();
+
+	  if (! error_state)
+	    have_sigma = true;
+	  else
+	    {
+	      error ("eigs: sigma must be a scalar or a string");
+	      return retval;
+	    }
+	}
+    }
+
+  sigmar = std::real (sigma);
+  sigmai = std::imag (sigma);
+
+  if (!error_state && nargin > (3+arg_offset))
+    {
+      if (args(3+arg_offset).is_map ())
+	{
+	  Octave_map map = args(3+arg_offset).map_value ();
+
+	  // issym is ignored if A is not a function
+	  if (map.contains ("issym") && have_a_fun)
+	      symmetric = map.contents ("issym")(0).double_value () != 0.;
+
+	  // isreal is ignored if A is not a function
+	  if (map.contains ("isreal") && have_a_fun)
+	      a_is_complex = ! (map.contents ("isreal")(0).double_value () != 0.);
+
+	  if (map.contains ("tol"))
+	    tol = map.contents ("tol")(0).double_value ();
+
+	  if (map.contains ("maxit"))
+	    maxit = map.contents ("maxit")(0).nint_value ();
+
+	  if (map.contains ("p"))
+	    p = map.contents ("p")(0).nint_value ();
+
+	  if (map.contains ("v0"))
+	    {
+	      if (a_is_complex || b_is_complex)
+		cresid = ComplexColumnVector 
+		  (map.contents ("v0")(0).complex_vector_value());
+	      else
+		resid = ColumnVector (map.contents ("v0")(0).vector_value());
+	    }
+
+	  if (map.contains ("disp"))
+	    disp = map.contents ("disp")(0).nint_value ();
+
+	  if (map.contains ("cholB"))
+	    cholB = map.contents ("cholB")(0).double_value () != 0.;
+
+	  if (map.contains ("permB"))
+	    permB = ColumnVector (map.contents ("permB")(0).vector_value ()) 
+	      - 1.0;
+	}
+      else
+	{
+	  error ("eigs: options argument must be a structure");
+	  return retval;
+	}
+    }
+
+  if (nargin > (4+arg_offset))
+    {
+      error ("eigs: incorrect number of arguments");
+      return retval;
+    }
+
+  if (have_b)
+    {
+      if (a_is_complex || b_is_complex)
+	{
+	  if (a_is_sparse)
+	    bscm = args(b_arg).sparse_complex_matrix_value ();
+	  else
+	    bcm = args(b_arg).complex_matrix_value ();
+	}
+      else
+	{
+	  if (a_is_sparse)
+	    bsmm = args(b_arg).sparse_matrix_value ();
+	  else
+	    bmm = args(b_arg).matrix_value ();
+	}
+    }
+
+  // Mode 1 for SM mode seems unstable for some reason. 
+  // Use Mode 3 instead, with sigma = 0.
+  if (!error_state && !have_sigma && typ == "SM")
+    have_sigma = true;
+
+  if (!error_state)
+    {
+      octave_idx_type nconv;
+      if (a_is_complex || b_is_complex)
+	{
+	  ComplexMatrix eig_vec;
+	  ComplexColumnVector eig_val;
+
+
+	  if (have_a_fun)
+	    nconv = EigsComplexNonSymmetricFunc 
+	      (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val,
+	       cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	  else if (have_sigma)
+	    {
+	      if (a_is_sparse)
+		nconv = EigsComplexNonSymmetricMatrixShift
+		  (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB,
+		   cresid, octave_stdout, tol, (nargout > 1), cholB, disp, 
+		   maxit);
+	      else
+		nconv = EigsComplexNonSymmetricMatrixShift
+		  (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
+		   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	    }
+	  else
+	    {
+	      if (a_is_sparse)
+		nconv = EigsComplexNonSymmetricMatrix
+		  (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB, cresid,
+		   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	      else
+		nconv = EigsComplexNonSymmetricMatrix
+		  (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
+		   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	    }
+
+	  if (nargout < 2)
+	    retval (0) = eig_val;
+	  else
+	    {
+	      retval(2) = double (info);
+	      retval(1) = ComplexDiagMatrix (eig_val);
+	      retval(0) = eig_vec;
+	    }
+	}
+      else if (sigmai != 0.)
+	{
+	  // Promote real problem to a complex one.
+	  ComplexMatrix eig_vec;
+	  ComplexColumnVector eig_val;
+
+	  if (have_a_fun)
+	    nconv = EigsComplexNonSymmetricFunc 
+	      (eigs_complex_func, n, typ,  sigma, k, p, info, eig_vec, eig_val,
+	       cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	  else
+	    {
+	      if (a_is_sparse)
+		nconv = EigsComplexNonSymmetricMatrixShift 
+		  (SparseComplexMatrix (asmm), sigma, k, p, info, eig_vec,
+		   eig_val, SparseComplexMatrix (bsmm), permB, cresid,
+		   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	      else
+		nconv = EigsComplexNonSymmetricMatrixShift 
+		  (ComplexMatrix (amm), sigma, k, p, info, eig_vec,
+		   eig_val, ComplexMatrix (bmm), permB, cresid,
+		   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+	    }
+
+	  if (nargout < 2)
+	    retval (0) = eig_val;
+	  else
+	    {
+	      retval(2) = double (info);
+	      retval(1) = ComplexDiagMatrix (eig_val);
+	      retval(0) = eig_vec;
+	    }
+	}
+      else
+	{
+	  if (symmetric)
+	    {
+	      Matrix eig_vec;
+	      ColumnVector eig_val;
+
+	      if (have_a_fun)
+		nconv = EigsRealSymmetricFunc 
+		  (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
+		   resid, octave_stdout, tol, (nargout > 1), cholB, disp, 
+		   maxit);
+	      else if (have_sigma)
+		{
+		  if (a_is_sparse)
+		    nconv = EigsRealSymmetricMatrixShift 
+		      (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp, 
+		       maxit);
+		  else
+		    nconv = EigsRealSymmetricMatrixShift 
+		      (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+		       maxit);
+		}
+	      else
+		{
+		  if (a_is_sparse)
+		    nconv = EigsRealSymmetricMatrix 
+		      (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+		       maxit);
+		  else
+		    nconv = EigsRealSymmetricMatrix 
+		      (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+		       maxit);
+		}
+
+	      if (nargout < 2)
+		retval (0) = eig_val;
+	      else
+		{
+		  retval(2) = double (info);
+		  retval(1) = DiagMatrix (eig_val);
+		  retval(0) = eig_vec;
+		}
+	    }
+	  else
+	    {
+	      ComplexMatrix eig_vec;
+	      ComplexColumnVector eig_val;
+
+	      if (have_a_fun)
+		nconv = EigsRealNonSymmetricFunc 
+		  (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
+		   resid, octave_stdout, tol, (nargout > 1), cholB, disp, 
+		   maxit);
+	      else if (have_sigma)
+		{
+		  if (a_is_sparse)
+		    nconv = EigsRealNonSymmetricMatrixShift 
+		      (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp, 
+		       maxit);
+		  else
+		    nconv = EigsRealNonSymmetricMatrixShift 
+		      (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+		       maxit);
+		}
+	      else
+		{
+		  if (a_is_sparse)
+		    nconv = EigsRealNonSymmetricMatrix 
+		      (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+		       maxit);
+		  else
+		    nconv = EigsRealNonSymmetricMatrix 
+		      (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
+		       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+		       maxit);
+		}
+
+	      if (nargout < 2)
+		retval (0) = eig_val;
+	      else
+		{
+		  retval(2) = double (info);
+		  retval(1) = ComplexDiagMatrix (eig_val);
+		  retval(0) = eig_vec;
+		}
+	    }
+	}
+
+      if (nconv <= 0)
+	warning ("eigs: None of the %d requested eigenvalues converged", k);
+      else if (nconv < k)
+	warning ("eigs: Only %d of the %d requested eigenvalues converged", 
+		 nconv, k);
+    }
+
+  if (! fcn_name.empty ())
+    clear_function (fcn_name);
+
+  unwind_protect::run_frame ("Feigs");
+#else
+  error ("eigs: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/* #### SPARSE MATRIX VERSIONS #### */
+
+/*
+
+%% Real positive definite tests, n must be even
+%!shared n, k, A, d0, d2
+%! n = 20;
+%! k = 4;
+%! A = sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]);
+%! d0 = eig (A);
+%! d2 = sort(d0);
+%! [dum, idx] = sort( abs(d0));
+%! d0 = d0(idx);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A,k+1);
+%! assert (d1, d0(end:-1:(end-k)),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lm');
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sm');
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'la');
+%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sa');
+%! assert (d1, d2(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'be');
+%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1, 'be');
+%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [dum,idx0] = sort (abs(d0 - 4.1));
+%! [dum,idx1] = sort (abs(d1 - 4.1));
+%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs(A, speye(n), k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs(A,k,4.1), eigs(A,speye(n),k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, speye(n), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, speye(n)(q,q), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, speye(n), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, speye(n)(q,q), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs(A,k,4.1), eigs(A,speye(n),k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 1; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'lm', opts);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 1; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'sm', opts);
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye(n)) \ x;
+%! opts.issym = 1; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (d1, eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! AA = speye (10);
+%! fn = @(x) AA * x;
+%! opts.issym = 1; opts.isreal = 1;
+%! assert (eigs (fn, 10, AA, 3, 'lm', opts), [1; 1; 1]);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'la');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sa');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'be');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+
+*/
+
+/*
+
+%% Real unsymmetric tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A =  sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]);
+%! d0 = eig (A);
+%! [dum, idx] = sort(abs(d0));
+%! d0 = d0(idx);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A,k+1);
+%! assert (abs(d1), abs(d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sm');
+%! assert (abs(d1), abs(d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lr');
+%! [dum, idx] = sort (real(d0));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sr');
+%! [dum, idx] = sort (real(abs(d0)));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'li');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'si');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [dum,idx0] = sort (abs(d0 - 4.1));
+%! [dum,idx1] = sort (abs(d1 - 4.1));
+%! assert (abs(d1(idx1)), abs(d0(idx0(1:k))), 1e-11);
+%! assert (sort(imag(d1(idx1))), sort(imag(d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs(A, speye(n), k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, speye(n), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, speye(n)(q,q), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, speye(n), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, speye(n)(q,q), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs(eigs(A,k,4.1)), abs(eigs(A,speye(n),k,4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort(imag(eigs(A,k,4.1))), sort(imag(eigs(A,speye(n),k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'sm', opts);
+%! assert (abs(d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye(n)) \ x;
+%! opts.issym = 0; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'li');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'si');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+
+*/
+
+/*
+
+%% Complex hermitian tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A = sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]);
+%! d0 = eig (A);
+%! [dum, idx] = sort(abs(d0));
+%! d0 = d0(idx);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A,k+1);
+%! assert (abs(d1), abs(d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sm');
+%! assert (abs(d1), abs(d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lr');
+%! [dum, idx] = sort (real(abs(d0)));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sr');
+%! [dum, idx] = sort (real(abs(d0)));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'li');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'si');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [dum,idx0] = sort (abs(d0 - 4.1));
+%! [dum,idx1] = sort (abs(d1 - 4.1));
+%! assert (abs(d1(idx1)), abs(d0(idx0(1:k))), 1e-11);
+%! assert (sort(imag(d1(idx1))), sort(imag(d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs(A, speye(n), k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, speye(n), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, speye(n)(q,q), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, speye(n), k, 4.1, opts);
+%! assert (abs(abs(d1)), abs(eigs(A,k,4.1)), 1e-11);
+%! assert (sort(imag(abs(d1))), sort(imag(eigs(A,k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, speye(n)(q,q), k, 4.1, opts);
+%! assert (abs(abs(d1)), abs(eigs(A,k,4.1)), 1e-11);
+%! assert (sort(imag(abs(d1))), sort(imag(eigs(A,k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs(eigs(A,k,4.1)), abs(eigs(A,speye(n),k,4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort(imag(eigs(A,k,4.1))), sort(imag(eigs(A,speye(n),k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0; opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0; opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 'sm', opts);
+%! assert (abs(d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye(n)) \ x;
+%! opts.issym = 0; opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'li');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'si');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*speye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+
+*/
+
+/* #### FULL MATRIX VERSIONS #### */
+
+/*
+
+%% Real positive definite tests, n must be even
+%!shared n, k, A, d0, d2
+%! n = 20;
+%! k = 4;
+%! A = full(sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]));
+%! d0 = eig (A);
+%! d2 = sort(d0);
+%! [dum, idx] = sort( abs(d0));
+%! d0 = d0(idx);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A,k+1);
+%! assert (d1, d0(end:-1:(end-k)),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lm');
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sm');
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'la');
+%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sa');
+%! assert (d1, d2(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'be');
+%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1, 'be');
+%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [dum,idx0] = sort (abs(d0 - 4.1));
+%! [dum,idx1] = sort (abs(d1 - 4.1));
+%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs(A, eye(n), k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs(A,k,4.1), eigs(A,eye(n),k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, eye(n), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, eye(n)(q,q), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, eye(n), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, eye(n)(q,q), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs(A,k,4.1), eigs(A,eye(n),k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 1; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'lm', opts);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 1; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'sm', opts);
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye(n)) \ x;
+%! opts.issym = 1; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (d1, eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'la');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sa');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'be');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+
+*/
+
+/*
+
+%% Real unsymmetric tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A =  full(sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]));
+%! d0 = eig (A);
+%! [dum, idx] = sort(abs(d0));
+%! d0 = d0(idx);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A,k+1);
+%! assert (abs(d1), abs(d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sm');
+%! assert (abs(d1), abs(d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lr');
+%! [dum, idx] = sort (real(d0));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sr');
+%! [dum, idx] = sort (real(abs(d0)));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'li');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'si');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [dum,idx0] = sort (abs(d0 - 4.1));
+%! [dum,idx1] = sort (abs(d1 - 4.1));
+%! assert (abs(d1(idx1)), abs(d0(idx0(1:k))), 1e-11);
+%! assert (sort(imag(d1(idx1))), sort(imag(d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs(A, eye(n), k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, eye(n), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, eye(n)(q,q), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, eye(n), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, eye(n)(q,q), k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs(eigs(A,k,4.1)), abs(eigs(A,eye(n),k,4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort(imag(eigs(A,k,4.1))), sort(imag(eigs(A,eye(n),k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 'sm', opts);
+%! assert (abs(d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye(n)) \ x;
+%! opts.issym = 0; opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'li');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'si');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+
+*/
+
+/*
+
+%% Complex hermitian tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A = full(sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]));
+%! d0 = eig (A);
+%! [dum, idx] = sort(abs(d0));
+%! d0 = d0(idx);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A,k+1);
+%! assert (abs(d1), abs(d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sm');
+%! assert (abs(d1), abs(d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'lr');
+%! [dum, idx] = sort (real(abs(d0)));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'sr');
+%! [dum, idx] = sort (real(abs(d0)));
+%! d2 = d0(idx);
+%! assert (real(d1), real(d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'li');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 'si');
+%! [dum, idx] = sort (imag(abs(d0)));
+%! d2 = d0(idx);
+%! assert (sort(imag(d1)), sort(imag(d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [dum,idx0] = sort (abs(d0 - 4.1));
+%! [dum,idx1] = sort (abs(d1 - 4.1));
+%! assert (abs(d1(idx1)), abs(d0(idx0(1:k))), 1e-11);
+%! assert (sort(imag(d1(idx1))), sort(imag(d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs(A, eye(n), k, 'lm');
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, eye(n), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, eye(n)(q,q), k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! d1 = eigs(A, eye(n), k, 4.1, opts);
+%! assert (abs(abs(d1)), abs(eigs(A,k,4.1)), 1e-11);
+%! assert (sort(imag(abs(d1))), sort(imag(eigs(A,k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB=true;
+%! q = [2:n,1];
+%! opts.permB=q;
+%! d1 = eigs(A, eye(n)(q,q), k, 4.1, opts);
+%! assert (abs(abs(d1)), abs(eigs(A,k,4.1)), 1e-11);
+%! assert (sort(imag(abs(d1))), sort(imag(eigs(A,k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs(eigs(A,k,4.1)), abs(eigs(A,eye(n),k,4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort(imag(eigs(A,k,4.1))), sort(imag(eigs(A,eye(n),k,4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0; opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 'lm', opts);
+%! assert (abs(d1), abs(d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0; opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 'sm', opts);
+%! assert (abs(d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye(n)) \ x;
+%! opts.issym = 0; opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs(d1), eigs(A,k,4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sm');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'lr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'sr');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'li');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs(A, k, 'si');
+%! d1 = diag(d1);
+%! for i=1:k
+%!  assert(max(abs((A - d1(i)*eye(n))*v1(:,i))),0.,1e-11)
+%! endfor
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/fft.cc b/src/DLD-FUNCTIONS/fft.cc
new file mode 100644
index 0000000..f6b99f8
--- /dev/null
+++ b/src/DLD-FUNCTIONS/fft.cc
@@ -0,0 +1,322 @@
+/*
+
+Copyright (C) 1997, 1999, 2002, 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#if defined (HAVE_FFTW3)
+#define FFTSRC "@sc{fftw}"
+#else
+#define FFTSRC "@sc{fftpack}"
+#endif
+
+static octave_value
+do_fft (const octave_value_list &args, const char *fcn, int type)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+  dim_vector dims = arg.dims ();
+  octave_idx_type n_points = -1;
+  int dim = -1;
+  
+  if (nargin > 1)
+    {
+      if (! args(1).is_empty ())
+	{
+	  double dval = args(1).double_value ();
+	  if (xisnan (dval))
+	    error ("%s: NaN is invalid as the N_POINTS", fcn);
+	  else
+	    {
+	      n_points = NINTbig (dval);
+	      if (n_points < 0)
+		error ("%s: number of points must be greater than zero", fcn);
+	    }
+	}
+    }
+
+  if (error_state)
+    return retval;
+
+  if (nargin > 2)
+    {
+      double dval = args(2).double_value ();
+      if (xisnan (dval))
+	error ("%s: NaN is invalid as the N_POINTS", fcn);
+      else if (dval < 1 || dval > dims.length ())
+	error ("%s: invalid dimension along which to perform fft", fcn);
+      else
+	// to be safe, cast it back to int since dim is an int
+	dim = NINT (dval) - 1;
+    }
+
+  if (error_state)
+    return retval;
+
+  for (octave_idx_type i = 0; i < dims.length (); i++)
+    if (dims(i) < 0)
+      return retval;
+
+  if (dim < 0)
+    {
+      for (octave_idx_type i = 0; i < dims.length (); i++)
+	if (dims(i) > 1)
+	  {
+	    dim = i;
+	    break;
+	  }
+
+      // And if the first argument is scalar?
+      if (dim < 0)
+	dim = 1;
+    }
+
+  if (n_points < 0)
+    n_points = dims (dim);
+  else
+    dims (dim) = n_points;
+
+  if (dims.any_zero () || n_points == 0)
+    {
+      if (arg.is_single_type ())
+	return octave_value (FloatNDArray (dims));
+      else
+	return octave_value (NDArray (dims));
+    }
+
+  if (arg.is_single_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	  FloatNDArray nda = arg.float_array_value ();
+
+	  if (! error_state)
+	    {
+	      nda.resize (dims, 0.0);
+	      retval = (type != 0 ? nda.ifourier (dim) : nda.fourier (dim));
+	    }
+	}
+      else
+	{
+	  FloatComplexNDArray cnda = arg.float_complex_array_value ();
+
+	  if (! error_state)
+	    {
+	      cnda.resize (dims, 0.0);
+	      retval = (type != 0 ? cnda.ifourier (dim) : cnda.fourier (dim));
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  NDArray nda = arg.array_value ();
+
+	  if (! error_state)
+	    {
+	      nda.resize (dims, 0.0);
+	      retval = (type != 0 ? nda.ifourier (dim) : nda.fourier (dim));
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  ComplexNDArray cnda = arg.complex_array_value ();
+
+	  if (! error_state)
+	    {
+	      cnda.resize (dims, 0.0);
+	      retval = (type != 0 ? cnda.ifourier (dim) : cnda.fourier (dim));
+	    }
+	}
+      else
+	{
+	  gripe_wrong_type_arg (fcn, arg);
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!error(fft())
+%!assert(fft([]), [])
+%!assert(fft(zeros(10,0)), zeros(10,0))
+%!assert(fft(zeros(0,10)), zeros(0,10))
+%!assert(fft(0), 0)
+%!assert(fft(1), 1)
+%!assert(fft(ones(2,2)), [2,2; 0,0])
+%!assert(fft(eye(2,2)), [1,1; 1,-1])
+
+%!assert(fft(single([])), single([]))
+%!assert(fft(zeros(10,0,'single')), zeros(10,0,'single'))
+%!assert(fft(zeros(0,10,'single')), zeros(0,10,'single'))
+%!assert(fft(single(0)), single(0))
+%!assert(fft(single(1)), single(1))
+%!assert(fft(ones(2,2,'single')), single([2,2; 0,0]))
+%!assert(fft(eye(2,2,'single')), single([1,1; 1,-1]))
+
+*/
+
+
+DEFUN_DLD (fft, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} fft (@var{a}, @var{n}, @var{dim})\n\
+Compute the FFT of @var{a} using subroutines from\n"
+FFTSRC
+".  The FFT is calculated along the first non-singleton dimension of the\n\
+array.  Thus if @var{a} is a matrix, @code{fft (@var{a})} computes the\n\
+FFT for each column of @var{a}.\n\
+\n\
+If called with two arguments, @var{n} is expected to be an integer\n\
+specifying the number of elements of @var{a} to use, or an empty\n\
+matrix to specify that its value should be ignored.  If @var{n} is\n\
+larger than the dimension along which the FFT is calculated, then\n\
+ at var{a} is resized and padded with zeros.  Otherwise, if @var{n} is\n\
+smaller than the dimension along which the FFT is calculated, then\n\
+ at var{a} is truncated.\n\
+\n\
+If called with three arguments, @var{dim} is an integer specifying the\n\
+dimension of the matrix along which the FFT is performed\n\
+ at seealso{ifft, fft2, fftn, fftw}\n\
+ at end deftypefn")
+{
+  return do_fft (args, "fft", 0);
+}
+
+
+DEFUN_DLD (ifft, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} ifft (@var{a}, @var{n}, @var{dim})\n\
+Compute the inverse FFT of @var{a} using subroutines from\n"
+FFTSRC
+".  The inverse FFT is calculated along the first non-singleton dimension\n\
+of the array.  Thus if @var{a} is a matrix, @code{fft (@var{a})} computes\n\
+the inverse FFT for each column of @var{a}.\n\
+\n\
+If called with two arguments, @var{n} is expected to be an integer\n\
+specifying the number of elements of @var{a} to use, or an empty\n\
+matrix to specify that its value should be ignored.  If @var{n} is\n\
+larger than the dimension along which the inverse FFT is calculated, then\n\
+ at var{a} is resized and padded with zeros.  Otherwise, if at var{n} is\n\
+smaller than the dimension along which the inverse FFT is calculated,\n\
+then @var{a} is truncated.\n\
+\n\
+If called with three arguments, @var{dim} is an integer specifying the\n\
+dimension of the matrix along which the inverse FFT is performed\n\
+ at seealso{fft, ifft2, ifftn, fftw}\n\
+ at end deftypefn")
+{
+  return do_fft (args, "ifft", 1);
+}
+
+/*
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! N=64;
+%! n=4;
+%! t = 2*pi*(0:1:N-1)/N;
+%! s = cos(n*t);
+%! S = fft(s);
+%! 
+%! answer = zeros (size(t));
+%! answer(n+1) = N/2;
+%! answer(N-n+1) = N/2;
+%! 
+%! assert(S, answer, 4*N*eps);
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! N=64;
+%! n=7;
+%! t = 2*pi*(0:1:N-1)/N;
+%! s = cos(n*t);
+%! 
+%! S = zeros (size(t));
+%! S(n+1) = N/2;
+%! S(N-n+1) = N/2;
+%! 
+%! assert(ifft(S), s, 4*N*eps);
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! N=64;
+%! n=4;
+%! t = single (2*pi*(0:1:N-1)/N);
+%! s = cos(n*t);
+%! S = fft(s);
+%! 
+%! answer = zeros (size(t),'single');
+%! answer(n+1) = N/2;
+%! answer(N-n+1) = N/2;
+%! 
+%! assert(S, answer, 4*N*eps('single'));
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! N=64;
+%! n=7;
+%! t = 2*pi*(0:1:N-1)/N;
+%! s = cos(n*t);
+%! 
+%! S = zeros (size(t),'single');
+%! S(n+1) = N/2;
+%! S(N-n+1) = N/2;
+%! 
+%! assert(ifft(S), s, 4*N*eps('single'));
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/fft2.cc b/src/DLD-FUNCTIONS/fft2.cc
new file mode 100644
index 0000000..8e64c30
--- /dev/null
+++ b/src/DLD-FUNCTIONS/fft2.cc
@@ -0,0 +1,299 @@
+/*
+
+Copyright (C) 1997, 1999, 2002, 2004, 2005, 2006, 2007, 2008,
+              2009 David Bateman
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+// This function should be merged with Fifft.
+
+#if defined (HAVE_FFTW3)
+#define FFTSRC "@sc{fftw}"
+#else
+#define FFTSRC "@sc{fftpack}"
+#endif
+
+static octave_value
+do_fft2 (const octave_value_list &args, const char *fcn, int type)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+  dim_vector dims = arg.dims ();
+  octave_idx_type n_rows = -1;
+  
+  if (nargin > 1)
+    {
+      double dval = args(1).double_value ();
+      if (xisnan (dval))
+	error ("%s: NaN is invalid as the N_ROWS", fcn);
+      else
+	{
+	  n_rows = NINTbig (dval);
+	  if (n_rows < 0)
+	    error ("%s: number of rows must be greater than zero", fcn);
+	}
+    }
+
+  if (error_state)
+    return retval;
+
+  octave_idx_type n_cols = -1;
+  if (nargin > 2)
+    {
+      double dval = args(2).double_value ();
+      if (xisnan (dval))
+	error ("%s: NaN is invalid as the N_COLS", fcn);
+      else
+	{
+	  n_cols = NINTbig (dval);
+	  if (n_cols < 0)
+	    error ("%s: number of columns must be greater than zero", fcn);
+	}
+    }
+
+  if (error_state)
+    return retval;
+
+  for (int i = 0; i < dims.length (); i++)
+    if (dims(i) < 0)
+      return retval;
+
+  if (n_rows < 0)
+    n_rows = dims (0);
+  else
+    dims (0) = n_rows;
+
+  if (n_cols < 0)
+    n_cols = dims (1);
+  else
+    dims (1) = n_cols;
+
+  if (dims.all_zero () || n_rows == 0 || n_cols == 0)
+    {
+      if (arg.is_single_type ())
+	return octave_value (FloatMatrix ());
+      else
+	return octave_value (Matrix ());
+    }
+
+  if (arg.is_single_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	  FloatNDArray nda = arg.float_array_value ();
+
+	  if (! error_state)
+	    {
+	      nda.resize (dims, 0.0);
+	      retval = (type != 0 ? nda.ifourier2d () : nda.fourier2d ());
+	    }
+	}
+      else
+	{
+	  FloatComplexNDArray cnda = arg.float_complex_array_value ();
+
+	  if (! error_state)
+	    {
+	      cnda.resize (dims, 0.0);
+	      retval = (type != 0 ? cnda.ifourier2d () : cnda.fourier2d ());
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  NDArray nda = arg.array_value ();
+
+	  if (! error_state)
+	    {
+	      nda.resize (dims, 0.0);
+	      retval = (type != 0 ? nda.ifourier2d () : nda.fourier2d ());
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  ComplexNDArray cnda = arg.complex_array_value ();
+
+	  if (! error_state)
+	    {
+	      cnda.resize (dims, 0.0);
+	      retval = (type != 0 ? cnda.ifourier2d () : cnda.fourier2d ());
+	    }
+	}
+      else
+	{
+	  gripe_wrong_type_arg (fcn, arg);
+	}
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (fft2, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} fft2 (@var{a}, @var{n}, @var{m})\n\
+Compute the two-dimensional FFT of @var{a} using subroutines from\n"
+FFTSRC
+".  The optional arguments @var{n} and @var{m} may be used specify the\n\
+number of rows and columns of @var{a} to use.  If either of these is\n\
+larger than the size of @var{a}, @var{a} is resized and padded with\n\
+zeros.\n\
+\n\
+If @var{a} is a multi-dimensional matrix, each two-dimensional sub-matrix\n\
+of @var{a} is treated separately\n\
+ at seealso {ifft2, fft, fftn, fftw}\n\
+ at end deftypefn")
+{
+  return do_fft2 (args, "fft2", 0);
+}
+
+
+DEFUN_DLD (ifft2, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} fft2 (@var{a}, @var{n}, @var{m})\n\
+Compute the inverse two-dimensional FFT of @var{a} using subroutines from\n"
+FFTSRC
+".  The optional arguments @var{n} and @var{m} may be used specify the\n\
+number of rows and columns of @var{a} to use.  If either of these is\n\
+larger than the size of @var{a}, @var{a} is resized and padded with\n\
+zeros.\n\
+\n\
+If @var{a} is a multi-dimensional matrix, each two-dimensional sub-matrix\n\
+of @var{a} is treated separately\n\
+ at seealso {fft2, ifft, ifftn, fftw}\n\
+ at end deftypefn")
+{
+  return do_fft2 (args, "ifft2", 1);
+}
+
+/*
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! M=16;
+%! N=8;
+%! 
+%! m=5;
+%! n=3;
+%! 
+%! x = 2*pi*(0:1:M-1)/M;
+%! y = 2*pi*(0:1:N-1)/N;
+%! sx = cos(m*x);
+%! sy = sin(n*y);
+%! s=kron(sx',sy);
+%! S = fft2(s);
+%! answer = kron(fft(sx)',fft(sy));
+%! assert(S, answer, 4*M*N*eps);
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! M=12;
+%! N=7;
+%! 
+%! m=3;
+%! n=2;
+%! 
+%! x = 2*pi*(0:1:M-1)/M;
+%! y = 2*pi*(0:1:N-1)/N;
+%! 
+%! sx = cos(m*x);
+%! sy = cos(n*y);
+%! 
+%! S = kron(fft(sx)',fft(sy));
+%! answer=kron(sx',sy);
+%! s = ifft2(S);
+%! 
+%! assert(s, answer, 30*eps);
+
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! M=16;
+%! N=8;
+%! 
+%! m=5;
+%! n=3;
+%! 
+%! x = 2*pi*(0:1:M-1)/M;
+%! y = 2*pi*(0:1:N-1)/N;
+%! sx = single(cos(m*x));
+%! sy = single(sin(n*y));
+%! s=kron(sx',sy);
+%! S = fft2(s);
+%! answer = kron(fft(sx)',fft(sy));
+%! assert(S, answer, 4*M*N*eps('single'));
+
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         02 May 2000
+%!test
+%! M=12;
+%! N=7;
+%! 
+%! m=3;
+%! n=2;
+%! 
+%! x = single(2*pi*(0:1:M-1)/M);
+%! y = single(2*pi*(0:1:N-1)/N);
+%! 
+%! sx = cos(m*x);
+%! sy = cos(n*y);
+%! 
+%! S = kron(fft(sx)',fft(sy));
+%! answer=kron(sx',sy);
+%! s = ifft2(S);
+%! 
+%! assert(s, answer, 30*eps('single'));
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/fftn.cc b/src/DLD-FUNCTIONS/fftn.cc
new file mode 100644
index 0000000..e1846d0
--- /dev/null
+++ b/src/DLD-FUNCTIONS/fftn.cc
@@ -0,0 +1,190 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+// This function should be merged with Fifft.
+
+#if defined (HAVE_FFTW3)
+#define FFTSRC "@sc{fftw}"
+#else
+#define FFTSRC "@sc{fftpack}"
+#endif
+
+static octave_value
+do_fftn (const octave_value_list &args, const char *fcn, int type)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+  dim_vector dims = arg.dims ();
+  
+  for (int i = 0; i < dims.length (); i++)
+    if (dims(i) < 0)
+      return retval;
+
+  if (nargin > 1)
+    {
+      Matrix val = args(1).matrix_value ();
+      if (val.rows () > val.columns ())
+	val = val.transpose ();
+
+      if (error_state || val.columns () != dims.length () || val.rows () != 1)
+	error ("%s: second argument must be a vector of length dim", fcn);
+      else
+	{
+	  for (int i = 0; i < dims.length (); i++)
+	    {
+	      if (xisnan (val(i,0)))
+		error ("%s: NaN is invalid as a dimension", fcn);
+	      else if (NINTbig (val(i,0)) < 0)
+		error ("%s: all dimension must be greater than zero", fcn);
+	      else
+		{
+		  dims(i) = NINTbig(val(i,0));
+		}
+	    }
+	}
+    }
+
+  if (error_state)
+    return retval;
+
+  if (dims.all_zero ())
+    {
+      if (arg.is_single_type ())
+	return octave_value (FloatMatrix ());
+      else
+	return octave_value (Matrix ());
+    }
+
+  if (arg.is_single_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	  FloatNDArray nda = arg.float_array_value ();
+
+	  if (! error_state)
+	    {
+	      nda.resize (dims, 0.0);
+	      retval = (type != 0 ? nda.ifourierNd () : nda.fourierNd ());
+	    }
+	}
+      else
+	{
+	  FloatComplexNDArray cnda = arg.float_complex_array_value ();
+
+	  if (! error_state)
+	    {
+	      cnda.resize (dims, 0.0);
+	      retval = (type != 0 ? cnda.ifourierNd () : cnda.fourierNd ());
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  NDArray nda = arg.array_value ();
+
+	  if (! error_state)
+	    {
+	      nda.resize (dims, 0.0);
+	      retval = (type != 0 ? nda.ifourierNd () : nda.fourierNd ());
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  ComplexNDArray cnda = arg.complex_array_value ();
+
+	  if (! error_state)
+	    {
+	      cnda.resize (dims, 0.0);
+	      retval = (type != 0 ? cnda.ifourierNd () : cnda.fourierNd ());
+	    }
+	}
+      else
+	{
+	  gripe_wrong_type_arg (fcn, arg);
+	}
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (fftn, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} fftn (@var{a}, @var{size})\n\
+Compute the N-dimensional FFT of @var{a} using subroutines from\n"
+FFTSRC
+".  The optional vector argument @var{size} may be used specify the\n\
+dimensions of the array to be used.  If an element of @var{size} is\n\
+smaller than the corresponding dimension, then the dimension is\n\
+truncated prior to performing the FFT.  Otherwise if an element\n\
+of @var{size} is larger than the corresponding dimension @var{a}\n\
+is resized and padded with zeros.\n\
+ at seealso {ifftn, fft, fft2, fftw}\n\
+ at end deftypefn")
+{
+  return do_fftn (args, "fftn", 0);
+}
+
+DEFUN_DLD (ifftn, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} ifftn (@var{a}, @var{size})\n\
+Compute the inverse N-dimensional FFT of @var{a} using subroutines from\n"
+FFTSRC
+".  The optional vector argument @var{size} may be used specify the\n\
+dimensions of the array to be used.  If an element of @var{size} is\n\
+smaller than the corresponding dimension, then the dimension is\n\
+truncated prior to performing the inverse FFT.  Otherwise if an element\n\
+of @var{size} is larger than the corresponding dimension @var{a}\n\
+is resized and padded with zeros.\n\
+ at seealso {fftn, ifft, ifft2, fftw}\n\
+ at end deftypefn")
+{
+  return do_fftn (args, "ifftn", 1);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/fftw.cc b/src/DLD-FUNCTIONS/fftw.cc
new file mode 100644
index 0000000..4587e87
--- /dev/null
+++ b/src/DLD-FUNCTIONS/fftw.cc
@@ -0,0 +1,269 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+#include "ov.h"
+#include "defun-dld.h"
+#include "error.h"
+
+#if defined (HAVE_FFTW3)
+#include "oct-fftw.h"
+#endif
+
+DEFUN_DLD (fftw, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{method} =} fftw ('planner')\n\
+ at deftypefnx {Loadable Function} {} fftw ('planner', @var{method})\n\
+ at deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom')\n\
+ at deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom', @var{wisdom})\n\
+\n\
+Manage @sc{fftw} wisdom data.  Wisdom data can be used to significantly\n\
+accelerate the calculation of the FFTs but implies an initial cost\n\
+in its calculation.  When the @sc{fftw} libraries are initialized, they read\n\
+a system wide wisdom file (typically in @file{/etc/fftw/wisdom}), allowing wisdom\n\
+to be shared between applications other than Octave.  Alternatively, the\n\
+ at code{fftw} function can be used to import wisdom.  For example\n\
+\n\
+ at example\n\
+ at var{wisdom} = fftw ('dwisdom')\n\
+ at end example\n\
+\n\
+will save the existing wisdom used by Octave to the string @var{wisdom}.\n\
+This string can then be saved to a file and restored using the @code{save}\n\
+and @code{load} commands respectively.  This existing wisdom can be reimported\n\
+as follows\n\
+\n\
+ at example\n\
+fftw ('dwisdom', @var{wisdom})\n\
+ at end example \n\
+\n\
+If @var{wisdom} is an empty matrix, then the wisdom used is cleared.\n\
+\n\
+During the calculation of Fourier transforms further wisdom is generated.\n\
+The fashion in which this wisdom is generated is equally controlled by\n\
+the @code{fftw} function.  There are five different manners in which the\n\
+wisdom can be treated, these being\n\
+\n\
+ at table @asis\n\
+ at item 'estimate'\n\
+This specifies that no run-time measurement of the optimal means of\n\
+calculating a particular is performed, and a simple heuristic is used\n\
+to pick a (probably sub-optimal) plan.  The advantage of this method is\n\
+that there is little or no overhead in the generation of the plan, which\n\
+is appropriate for a Fourier transform that will be calculated once.\n\
+\n\
+ at item 'measure'\n\
+In this case a range of algorithms to perform the transform is considered\n\
+and the best is selected based on their execution time.\n\
+\n\
+ at item 'patient'\n\
+This is like 'measure', but a wider range of algorithms is considered.\n\
+\n\
+ at item 'exhaustive'\n\
+This is like 'measure', but all possible algorithms that may be used to\n\
+treat the transform are considered.\n\
+\n\
+ at item 'hybrid'\n\
+As run-time measurement of the algorithm can be expensive, this is a\n\
+compromise where 'measure' is used for transforms up to the size of 8192\n\
+and beyond that the 'estimate' method is used.\n\
+ at end table\n\
+\n\
+The default method is 'estimate', and the method currently being used can\n\
+be probed with\n\
+\n\
+ at example\n\
+ at var{method} = fftw ('planner')\n\
+ at end example\n\
+\n\
+and the method used can be set using\n\
+\n\
+ at example\n\
+fftw ('planner', @var{method})\n\
+ at end example\n\
+\n\
+Note that calculated wisdom will be lost when restarting Octave.  However,\n\
+the wisdom data can be reloaded if it is saved to a file as described\n\
+above.  Saved wisdom files should not be used on different platforms since\n\
+they will not be efficient and the point of calculating the wisdom is lost.\n\
+ at seealso{fft, ifft, fft2, ifft2, fftn, ifftn}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length();
+
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#if defined (HAVE_FFTW3)
+  if (args(0).is_string ())
+    {
+      std::string arg0 = args(0).string_value ();
+
+      if (!error_state)
+	{
+	  // Use STL function to convert to lower case
+	  std::transform (arg0.begin (), arg0.end (), arg0.begin (), tolower);
+	  
+	  if (nargin == 2)
+	    {
+	      std::string arg1 = args(1).string_value ();
+	      if (!error_state)
+		{
+		  if (arg0 == "planner")
+		    {
+		      std::transform (arg1.begin (), arg1.end (), 
+				      arg1.begin (), tolower);
+		      octave_fftw_planner::FftwMethod meth
+			= octave_fftw_planner::UNKNOWN;
+		      octave_float_fftw_planner::FftwMethod methf
+			= octave_float_fftw_planner::UNKNOWN;
+
+		      if (arg1 == "estimate")
+			{
+			  meth = octave_fftw_planner::ESTIMATE;
+			  methf = octave_float_fftw_planner::ESTIMATE;
+			}
+		      else if (arg1 == "measure")
+			{
+			  meth = octave_fftw_planner::MEASURE;
+			  methf = octave_float_fftw_planner::MEASURE;
+			}
+		      else if (arg1 == "patient")
+			{
+			  meth = octave_fftw_planner::PATIENT;
+			  methf = octave_float_fftw_planner::PATIENT;
+			}
+		      else if (arg1 == "exhaustive")
+			{
+			  meth = octave_fftw_planner::EXHAUSTIVE;
+			  methf = octave_float_fftw_planner::EXHAUSTIVE;
+			}
+		      else if (arg1 == "hybrid")
+			{
+			  meth = octave_fftw_planner::HYBRID;
+			  methf = octave_float_fftw_planner::HYBRID;
+			}
+		      else
+			error ("unrecognized planner method");
+
+		      if (!error_state)
+			{
+			  meth = fftw_planner.method (meth);
+			  float_fftw_planner.method (methf);
+
+			  if (meth == octave_fftw_planner::MEASURE)
+			    retval = octave_value ("measure");
+			  else if (meth == octave_fftw_planner::PATIENT)
+			    retval = octave_value ("patient");
+			  else if (meth == octave_fftw_planner::EXHAUSTIVE)
+			    retval = octave_value ("exhaustive");
+			  else if (meth == octave_fftw_planner::HYBRID)
+			    retval = octave_value ("hybrid");
+			  else
+			    retval = octave_value ("estimate");
+			}
+		    }
+		  else if (arg0 == "dwisdom")
+		    {
+		      char *str = fftw_export_wisdom_to_string ();
+
+		      if (arg1.length() < 1)
+			fftw_forget_wisdom ();
+		      else if (! fftw_import_wisdom_from_string (arg1.c_str()))
+			error ("could not import supplied wisdom");
+
+		      if (!error_state)
+			retval = octave_value (std::string (str));
+
+		      free (str);
+		    }
+		  else if (arg0 == "swisdom")
+		    {
+		      char *str = fftwf_export_wisdom_to_string ();
+
+		      if (arg1.length() < 1)
+			fftwf_forget_wisdom ();
+		      else if (! fftwf_import_wisdom_from_string (arg1.c_str()))
+			error ("could not import supplied wisdom");
+
+		      if (!error_state)
+			retval = octave_value (std::string (str));
+
+		      free (str);
+		    }
+		  else
+		    error ("unrecognized argument");
+		}
+	    }
+	  else
+	    {
+	      if (arg0 == "planner")
+		{
+		  octave_fftw_planner::FftwMethod meth = 
+		    fftw_planner.method ();
+
+		  if (meth == octave_fftw_planner::MEASURE)
+		    retval = octave_value ("measure");
+		  else if (meth == octave_fftw_planner::PATIENT)
+		    retval = octave_value ("patient");
+		  else if (meth == octave_fftw_planner::EXHAUSTIVE)
+		    retval = octave_value ("exhaustive");
+		  else if (meth == octave_fftw_planner::HYBRID)
+		    retval = octave_value ("hybrid");
+		  else
+		    retval = octave_value ("estimate");
+		}
+	      else if (arg0 == "dwisdom")
+		{
+		  char *str = fftw_export_wisdom_to_string ();
+		  retval = octave_value (std::string (str));
+		  free (str);
+		}
+	      else if (arg0 == "swisdom")
+		{
+		  char *str = fftwf_export_wisdom_to_string ();
+		  retval = octave_value (std::string (str));
+		  free (str);
+		}
+	      else
+		error ("unrecognized argument");
+	    }
+	}
+    }
+#else
+
+  warning ("fftw: this copy of Octave was not configured to use FFTW3");
+
+#endif
+
+  return retval;
+}
+
diff --git a/src/DLD-FUNCTIONS/filter.cc b/src/DLD-FUNCTIONS/filter.cc
new file mode 100644
index 0000000..49a75a8
--- /dev/null
+++ b/src/DLD-FUNCTIONS/filter.cc
@@ -0,0 +1,696 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Based on Tony Richardson's filter.m.
+//
+// Originally translated to C++ by KH (Kurt.Hornik at wu-wien.ac.at)
+// with help from Fritz Leisch and Andreas Weingessel on Oct 20, 1994.
+//
+// Rewritten to use templates to handle both real and complex cases by
+// jwe, Wed Nov  1 19:15:29 1995.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern MArrayN<double>
+filter (MArray<double>&, MArray<double>&, MArrayN<double>&, int dim);
+
+extern MArrayN<Complex>
+filter (MArray<Complex>&, MArray<Complex>&, MArrayN<Complex>&, int dim);
+
+extern MArrayN<float>
+filter (MArray<float>&, MArray<float>&, MArrayN<float>&, int dim);
+
+extern MArrayN<FloatComplex>
+filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArrayN<FloatComplex>&, int dim);
+#endif
+
+template <class T>
+MArrayN<T>
+filter (MArray<T>& b, MArray<T>& a, MArrayN<T>& x, MArrayN<T>& si, 
+	int dim = 0)
+{
+  MArrayN<T> y;
+
+  octave_idx_type a_len  = a.length ();
+  octave_idx_type b_len  = b.length ();
+
+  octave_idx_type ab_len = a_len > b_len ? a_len : b_len;
+
+  b.resize (ab_len, 0.0);
+  if (a_len > 1)
+    a.resize (ab_len, 0.0);
+
+  T norm = a (0);
+
+  if (norm == static_cast<T>(0.0))
+    {
+      error ("filter: the first element of a must be non-zero");
+      return y;
+    }
+
+  dim_vector x_dims = x.dims ();
+  if (dim < 0 || dim > x_dims.length ())
+    {
+      error ("filter: filtering over invalid dimension");
+      return y;
+    }
+
+  octave_idx_type x_len = x_dims(dim);
+
+  dim_vector si_dims = si.dims ();
+  octave_idx_type si_len = si_dims(0);
+
+  if (si_len != ab_len - 1)
+    {
+      error ("filter: first dimension of si must be of length max (length (a), length (b)) - 1");
+      return y;
+    }
+
+  if (si_dims.length () != x_dims.length ())
+    {
+      error ("filter: dimensionality of si and x must agree");
+      return y;
+    }
+
+  octave_idx_type si_dim = 0;
+  for (octave_idx_type i = 0; i < x_dims.length (); i++)
+    {
+      if (i == dim)
+	continue;
+     
+      if (x_dims(i) == 1)
+	continue;
+ 
+      if (si_dims(++si_dim) != x_dims(i))
+	{
+	  error ("filter: dimensionality of si and x must agree");
+	  return y;
+	}
+    }
+
+  if (norm != static_cast<T>(1.0))
+    {
+      a = a / norm;
+      b = b / norm;
+    }
+
+  if (a_len <= 1 && si_len <= 0)
+    return b(0) * x;
+
+  y.resize (x_dims, 0.0);
+
+  int x_stride = 1;
+  for (int i = 0; i < dim; i++)
+    x_stride *= x_dims(i);
+
+  octave_idx_type x_num = x_dims.numel () / x_len;
+  for (octave_idx_type num = 0; num < x_num; num++)
+    {
+      octave_idx_type x_offset;
+      if (x_stride == 1)
+	x_offset = num * x_len;
+      else
+	{
+	  octave_idx_type x_offset2 = 0;
+	  x_offset = num;
+	  while (x_offset >= x_stride)
+	    {
+	      x_offset -= x_stride;
+	      x_offset2++;
+	    }
+	  x_offset += x_offset2 * x_stride * x_len;
+	}
+      octave_idx_type si_offset = num * si_len;
+
+      if (a_len > 1)
+	{
+	  T *py = y.fortran_vec ();
+	  T *psi = si.fortran_vec ();
+
+	  const T *pa = a.data ();
+	  const T *pb = b.data ();
+	  const T *px = x.data ();
+
+	  psi += si_offset;
+
+	  for (octave_idx_type i = 0, idx = x_offset; i < x_len; i++, idx += x_stride)
+	    {
+	      py[idx] = psi[0] + pb[0] * px[idx];
+
+	      if (si_len > 0)
+		{
+		  for (octave_idx_type j = 0; j < si_len - 1; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      psi[j] = psi[j+1] - pa[j+1] * py[idx] + pb[j+1] * px[idx];
+		    }
+
+		  psi[si_len-1] = pb[si_len] * px[idx] - pa[si_len] * py[idx];
+		}
+	      else
+		{
+		  OCTAVE_QUIT;
+
+		  psi[0] = pb[si_len] * px[idx] - pa[si_len] * py[idx];
+		}
+	    }
+	}
+      else if (si_len > 0)
+	{
+	  T *py = y.fortran_vec ();
+	  T *psi = si.fortran_vec ();
+
+	  const T *pb = b.data ();
+	  const T *px = x.data ();
+
+	  psi += si_offset;
+
+	  for (octave_idx_type i = 0, idx = x_offset; i < x_len; i++, idx += x_stride)
+	    {
+	      py[idx] = psi[0] + pb[0] * px[idx];
+
+	      if (si_len > 1)
+		{
+		  for (octave_idx_type j = 0; j < si_len - 1; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      psi[j] = psi[j+1] + pb[j+1] * px[idx];
+		    }
+
+		  psi[si_len-1] = pb[si_len] * px[idx];
+		}
+	      else
+		{
+		  OCTAVE_QUIT;
+
+		  psi[0] = pb[1] * px[idx];
+		}
+	    }
+	}
+    }
+  
+  return y;
+}
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern MArrayN<double>
+filter (MArray<double>&, MArray<double>&, MArrayN<double>&,
+	MArrayN<double>&, int dim);
+
+extern MArrayN<Complex>
+filter (MArray<Complex>&, MArray<Complex>&, MArrayN<Complex>&,
+	MArrayN<Complex>&, int dim);
+
+extern MArrayN<float>
+filter (MArray<float>&, MArray<float>&, MArrayN<float>&,
+	MArrayN<float>&, int dim);
+
+extern MArrayN<FloatComplex>
+filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArrayN<FloatComplex>&,
+	MArrayN<FloatComplex>&, int dim);
+#endif
+
+template <class T>
+MArrayN<T>
+filter (MArray<T>& b, MArray<T>& a, MArrayN<T>& x, int dim = -1)
+{
+  dim_vector x_dims = x.dims();
+
+  if (dim < 0)
+    {
+      // Find first non-singleton dimension
+      while (dim < x_dims.length () && x_dims(dim) <= 1)
+	dim++;
+  
+      // All dimensions singleton, pick first dimension
+      if (dim == x_dims.length ())
+	dim = 0;
+    }
+  else
+    if (dim < 0 || dim > x_dims.length ())
+      {
+	error ("filter: filtering over invalid dimension");
+	return MArrayN<T> ();
+      }
+
+  octave_idx_type a_len = a.length ();
+  octave_idx_type b_len = b.length ();
+
+  octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
+  dim_vector si_dims = x.dims ();
+  for (int i = dim; i > 0; i--)
+    si_dims(i) = si_dims(i-1);
+  si_dims(0) = si_len;
+  
+  MArrayN<T> si (si_dims, T (0.0));
+
+  return filter (b, a, x, si, dim);
+}
+
+DEFUN_DLD (filter, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {y =} filter (@var{b}, @var{a}, @var{x})\n\
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si})\n\
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, [], @var{dim})\n\
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}, @var{dim})\n\
+Return the solution to the following linear, time-invariant difference\n\
+equation:\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+\\sum_{k=0}^N a_{k+1} y_{n-k} = \\sum_{k=0}^M b_{k+1} x_{n-k}, \\qquad\n\
+ 1 \\le n \\le P\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at c Set example in small font to prevent overfull line\n\
+ at smallexample\n\
+   N                   M\n\
+  SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k)      for 1<=n<=length(x)\n\
+  k=0                 k=0\n\
+ at end smallexample\n\
+ at end ifnottex\n\
+\n\
+ at noindent\n\
+where\n\
+ at ifnottex\n\
+ N=length(a)-1 and M=length(b)-1.\n\
+ at end ifnottex\n\
+ at iftex\n\
+ at tex\n\
+ $a \\in \\Re^{N-1}$, $b \\in \\Re^{M-1}$, and $x \\in \\Re^P$.\n\
+ at end tex\n\
+ at end iftex\n\
+over the first non-singleton dimension of @var{x} or over @var{dim} if\n\
+supplied.  An equivalent form of this equation is:\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+y_n = -\\sum_{k=1}^N c_{k+1} y_{n-k} + \\sum_{k=0}^M d_{k+1} x_{n-k}, \\qquad\n\
+ 1 \\le n \\le P\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at c Set example in small font to prevent overfull line\n\
+ at smallexample\n\
+            N                   M\n\
+  y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k)  for 1<=n<=length(x)\n\
+           k=1                 k=0\n\
+ at end smallexample\n\
+ at end ifnottex\n\
+\n\
+ at noindent\n\
+where\n\
+ at ifnottex\n\
+ c = a/a(1) and d = b/a(1).\n\
+ at end ifnottex\n\
+ at iftex\n\
+ at tex\n\
+$c = a/a_1$ and $d = b/a_1$.\n\
+ at end tex\n\
+ at end iftex\n\
+\n\
+If the fourth argument @var{si} is provided, it is taken as the\n\
+initial state of the system and the final state is returned as\n\
+ at var{sf}.  The state vector is a column vector whose length is\n\
+equal to the length of the longest coefficient vector minus one.\n\
+If @var{si} is not supplied, the initial state vector is set to all\n\
+zeros.\n\
+\n\
+In terms of the z-transform, y is the result of passing the discrete-\n\
+time signal x through a system characterized by the following rational\n\
+system function:\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+H(z) = {\\displaystyle\\sum_{k=0}^M d_{k+1} z^{-k}\n\
+        \\over 1 + \\displaystyle\\sum_{k+1}^N c_{k+1} z^{-k}}\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+             M\n\
+            SUM d(k+1) z^(-k)\n\
+            k=0\n\
+  H(z) = ----------------------\n\
+               N\n\
+          1 + SUM c(k+1) z^(-k)\n\
+              k=1\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin  = args.length ();
+
+  if (nargin < 3 || nargin > 5)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  const char *errmsg = "filter: arguments a and b must be vectors";
+
+  int dim;
+  dim_vector x_dims = args(2).dims ();
+
+  if (nargin == 5)
+    {
+      dim = args(4).nint_value() - 1;
+      if (dim < 0 || dim >= x_dims.length ())
+	{
+	  error ("filter: filtering over invalid dimension");
+	  return retval;
+	}
+    }
+  else
+    {
+      // Find first non-singleton dimension
+      dim = 0;
+      while (dim < x_dims.length () && x_dims(dim) <= 1)
+	dim++;
+  
+      // All dimensions singleton, pick first dimension
+      if (dim == x_dims.length ())
+	dim = 0;
+    }
+
+  bool isfloat = (args(0).is_single_type ()
+		  || args(1).is_single_type ()
+		  || args(2).is_single_type ()
+		  || (nargin >= 4 && args(3).is_single_type ()));
+    
+  if (args(0).is_complex_type ()
+      || args(1).is_complex_type ()
+      || args(2).is_complex_type ()
+      || (nargin >= 4 && args(3).is_complex_type ()))
+    {
+      if (isfloat)
+	{
+	  FloatComplexColumnVector b (args(0).float_complex_vector_value ());
+	  FloatComplexColumnVector a (args(1).float_complex_vector_value ());
+
+	  FloatComplexNDArray x (args(2).float_complex_array_value ());
+
+	  if (! error_state)
+	    {
+	      FloatComplexNDArray si;
+
+	      if (nargin == 3 || args(3).is_empty ())
+		{
+		  octave_idx_type a_len = a.length ();
+		  octave_idx_type b_len = b.length ();
+
+		  octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
+
+		  dim_vector si_dims = x.dims ();
+		  for (int i = dim; i > 0; i--)
+		    si_dims(i) = si_dims(i-1);
+		  si_dims(0) = si_len;
+
+		  si.resize (si_dims, 0.0);
+		}
+	      else
+		{
+		  dim_vector si_dims = args (3).dims ();
+		  bool si_is_vector = true;
+		  for (int i = 0; i < si_dims.length (); i++)
+		    if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ())
+		      {
+			si_is_vector = false;
+			break;
+		      }
+
+		  si = args(3).float_complex_array_value ();
+
+		  if (si_is_vector)
+		    si = si.reshape (dim_vector (si.numel (), 1));
+		}
+
+	      if (! error_state)
+		{
+		  FloatComplexNDArray y (filter (b, a, x, si, dim));
+
+		  if (nargout == 2)
+		    retval(1) = si;
+
+		  retval(0) = y;
+		}
+	      else
+		error (errmsg);
+	    }
+	  else
+	    error (errmsg);
+	}
+      else
+	{
+	  ComplexColumnVector b (args(0).complex_vector_value ());
+	  ComplexColumnVector a (args(1).complex_vector_value ());
+
+	  ComplexNDArray x (args(2).complex_array_value ());
+
+	  if (! error_state)
+	    {
+	      ComplexNDArray si;
+
+	      if (nargin == 3 || args(3).is_empty ())
+		{
+		  octave_idx_type a_len = a.length ();
+		  octave_idx_type b_len = b.length ();
+
+		  octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
+
+		  dim_vector si_dims = x.dims ();
+		  for (int i = dim; i > 0; i--)
+		    si_dims(i) = si_dims(i-1);
+		  si_dims(0) = si_len;
+
+		  si.resize (si_dims, 0.0);
+		}
+	      else
+		{
+		  dim_vector si_dims = args (3).dims ();
+		  bool si_is_vector = true;
+		  for (int i = 0; i < si_dims.length (); i++)
+		    if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ())
+		      {
+			si_is_vector = false;
+			break;
+		      }
+
+		  si = args(3).complex_array_value ();
+
+		  if (si_is_vector)
+		    si = si.reshape (dim_vector (si.numel (), 1));
+		}
+
+	      if (! error_state)
+		{
+		  ComplexNDArray y (filter (b, a, x, si, dim));
+
+		  if (nargout == 2)
+		    retval(1) = si;
+
+		  retval(0) = y;
+		}
+	      else
+		error (errmsg);
+	    }
+	  else
+	    error (errmsg);
+	}
+    }
+  else
+    {
+      if (isfloat)
+	{
+	  FloatColumnVector b (args(0).float_vector_value ());
+	  FloatColumnVector a (args(1).float_vector_value ());
+
+	  FloatNDArray x (args(2).float_array_value ());
+
+	  if (! error_state)
+	    {
+	      FloatNDArray si;
+
+	      if (nargin == 3 || args(3).is_empty ())
+		{
+		  octave_idx_type a_len = a.length ();
+		  octave_idx_type b_len = b.length ();
+
+		  octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
+
+		  dim_vector si_dims = x.dims ();
+		  for (int i = dim; i > 0; i--)
+		    si_dims(i) = si_dims(i-1);
+		  si_dims(0) = si_len;
+
+		  si.resize (si_dims, 0.0);
+		}
+	      else
+		{
+		  dim_vector si_dims = args (3).dims ();
+		  bool si_is_vector = true;
+		  for (int i = 0; i < si_dims.length (); i++)
+		    if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ())
+		      {
+			si_is_vector = false;
+			break;
+		      }
+
+		  si = args(3).float_array_value ();
+
+		  if (si_is_vector)
+		    si = si.reshape (dim_vector (si.numel (), 1));
+		}
+
+	      if (! error_state)
+		{
+		  FloatNDArray y (filter (b, a, x, si, dim));
+
+		  if (nargout == 2)
+		    retval(1) = si;
+
+		  retval(0) = y;
+		}
+	      else
+		error (errmsg);
+	    }
+	  else
+	    error (errmsg);
+	}
+      else
+	{
+	  ColumnVector b (args(0).vector_value ());
+	  ColumnVector a (args(1).vector_value ());
+
+	  NDArray x (args(2).array_value ());
+
+	  if (! error_state)
+	    {
+	      NDArray si;
+
+	      if (nargin == 3 || args(3).is_empty ())
+		{
+		  octave_idx_type a_len = a.length ();
+		  octave_idx_type b_len = b.length ();
+
+		  octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
+
+		  dim_vector si_dims = x.dims ();
+		  for (int i = dim; i > 0; i--)
+		    si_dims(i) = si_dims(i-1);
+		  si_dims(0) = si_len;
+
+		  si.resize (si_dims, 0.0);
+		}
+	      else
+		{
+		  dim_vector si_dims = args (3).dims ();
+		  bool si_is_vector = true;
+		  for (int i = 0; i < si_dims.length (); i++)
+		    if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ())
+		      {
+			si_is_vector = false;
+			break;
+		      }
+
+		  si = args(3).array_value ();
+
+		  if (si_is_vector)
+		    si = si.reshape (dim_vector (si.numel (), 1));
+		}
+
+	      if (! error_state)
+		{
+		  NDArray y (filter (b, a, x, si, dim));
+
+		  if (nargout == 2)
+		    retval(1) = si;
+
+		  retval(0) = y;
+		}
+	      else
+		error (errmsg);
+	    }
+	  else
+	    error (errmsg);
+	}
+    }
+
+  return retval;
+}
+
+template MArrayN<double>
+filter (MArray<double>&, MArray<double>&, MArrayN<double>&,
+	MArrayN<double>&, int dim);
+
+template MArrayN<double>
+filter (MArray<double>&, MArray<double>&, MArrayN<double>&, int dim);
+
+template MArrayN<Complex>
+filter (MArray<Complex>&, MArray<Complex>&, MArrayN<Complex>&,
+	MArrayN<Complex>&, int dim);
+
+template MArrayN<Complex>
+filter (MArray<Complex>&, MArray<Complex>&, MArrayN<Complex>&, int dim);
+
+template MArrayN<float>
+filter (MArray<float>&, MArray<float>&, MArrayN<float>&,
+	MArrayN<float>&, int dim);
+
+template MArrayN<float>
+filter (MArray<float>&, MArray<float>&, MArrayN<float>&, int dim);
+
+template MArrayN<FloatComplex>
+filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArrayN<FloatComplex>&,
+	MArrayN<FloatComplex>&, int dim);
+
+template MArrayN<FloatComplex>
+filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArrayN<FloatComplex>&, int dim);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/  
diff --git a/src/DLD-FUNCTIONS/find.cc b/src/DLD-FUNCTIONS/find.cc
new file mode 100644
index 0000000..3ce206f
--- /dev/null
+++ b/src/DLD-FUNCTIONS/find.cc
@@ -0,0 +1,656 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+
+// Find at most N_TO_FIND nonzero elements in NDA.  Search forward if
+// DIRECTION is 1, backward if it is -1.  NARGOUT is the number of
+// output arguments.  If N_TO_FIND is -1, find all nonzero elements.
+
+template <typename T>
+octave_value_list
+find_nonzero_elem_idx (const Array<T>& nda, int nargout, 
+		       octave_idx_type n_to_find, int direction)
+{
+  octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
+
+  Array<octave_idx_type> idx;
+  if (n_to_find >= 0)
+    idx = nda.find (n_to_find, direction == -1);
+  else
+    idx = nda.find ();
+
+  switch (nargout)
+    {
+    default:
+    case 3:
+      retval(2) = ArrayN<T> (nda.index (idx_vector (idx)));
+      // Fall through!
+
+    case 2:
+      {
+        Array<octave_idx_type> jdx (idx.dims ());
+        octave_idx_type n = idx.length (), nr = nda.rows ();
+        for (octave_idx_type i = 0; i < n; i++)
+          {
+            jdx.xelem (i) = idx.xelem (i) / nr;
+            idx.xelem (i) %= nr;
+          }
+        retval(1) = NDArray (jdx, true);
+      }
+      // Fall through!
+
+    case 1:
+    case 0:
+      retval(0) = NDArray (idx, true);
+      break;
+    }
+
+  return retval;
+}
+
+#define INSTANTIATE_FIND_ARRAY(T) \
+template octave_value_list find_nonzero_elem_idx (const Array<T>&, int, \
+						  octave_idx_type, int)
+
+INSTANTIATE_FIND_ARRAY(double);
+INSTANTIATE_FIND_ARRAY(float);
+INSTANTIATE_FIND_ARRAY(Complex);
+INSTANTIATE_FIND_ARRAY(FloatComplex);
+INSTANTIATE_FIND_ARRAY(bool);
+INSTANTIATE_FIND_ARRAY(octave_int8);
+INSTANTIATE_FIND_ARRAY(octave_int16);
+INSTANTIATE_FIND_ARRAY(octave_int32);
+INSTANTIATE_FIND_ARRAY(octave_int64);
+INSTANTIATE_FIND_ARRAY(octave_uint8);
+INSTANTIATE_FIND_ARRAY(octave_uint16);
+INSTANTIATE_FIND_ARRAY(octave_uint32);
+INSTANTIATE_FIND_ARRAY(octave_uint64);
+
+template <typename T>
+octave_value_list
+find_nonzero_elem_idx (const Sparse<T>& v, int nargout, 
+		       octave_idx_type n_to_find, int direction)
+{
+  octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
+
+
+  octave_idx_type nc = v.cols();
+  octave_idx_type nr = v.rows();
+  octave_idx_type nz = v.nnz();
+
+  // Search in the default range.
+  octave_idx_type start_nc = -1;
+  octave_idx_type end_nc = -1;
+  octave_idx_type count;
+ 
+  // Search for the range to search
+  if (n_to_find < 0)
+    {
+      start_nc = 0;
+      end_nc = nc;
+      n_to_find = nz;
+      count = nz;
+    }
+  else if (direction > 0)
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  OCTAVE_QUIT;
+	  if (v.cidx(j) == 0 && v.cidx(j+1) != 0)
+	    start_nc = j;
+	  if (v.cidx(j+1) >= n_to_find)
+	    {
+	      end_nc = j + 1;
+	      break;
+	    }
+	}
+    }
+  else
+    {
+      for (octave_idx_type j = nc; j > 0; j--)
+	{
+	  OCTAVE_QUIT;
+	  if (v.cidx(j) == nz && v.cidx(j-1) != nz)
+	    end_nc = j;
+	  if (nz - v.cidx(j-1) >= n_to_find)
+	    {
+	      start_nc = j - 1;
+	      break;
+	    }
+	}
+    }
+
+  count = (n_to_find > v.cidx(end_nc) - v.cidx(start_nc) ? 
+	   v.cidx(end_nc) - v.cidx(start_nc) : n_to_find);
+
+  // If the original argument was a row vector, force a row vector of
+  // the overall indices to be returned.  But see below for scalar
+  // case...
+
+  octave_idx_type result_nr = count;
+  octave_idx_type result_nc = 1;
+
+  bool scalar_arg = false;
+
+  if (v.rows () == 1)
+    {
+      result_nr = 1;
+      result_nc = count;
+
+      scalar_arg = (v.columns () == 1);
+    }
+
+  Matrix idx (result_nr, result_nc);
+
+  Matrix i_idx (result_nr, result_nc);
+  Matrix j_idx (result_nr, result_nc);
+
+  ArrayN<T> val (dim_vector (result_nr, result_nc));
+
+  if (count > 0)
+    {
+      // Search for elements to return.  Only search the region where
+      // there are elements to be found using the count that we want
+      // to find.
+      for (octave_idx_type j = start_nc, cx = 0; j < end_nc; j++) 
+	for (octave_idx_type i = v.cidx(j); i < v.cidx(j+1); i++ ) 
+	  {
+	    OCTAVE_QUIT;
+	    if (direction < 0 && i < nz - count)
+	      continue;
+	    i_idx(cx) = static_cast<double> (v.ridx(i) + 1);
+	    j_idx(cx) = static_cast<double> (j + 1);
+	    idx(cx) = j * nr + v.ridx(i) + 1; 
+	    val(cx) = v.data(i);
+	    cx++;
+	    if (cx == count)
+	      break;
+	  }
+    }
+  else if (scalar_arg)
+    {
+      idx.resize (0, 0);
+
+      i_idx.resize (0, 0);
+      j_idx.resize (0, 0);
+
+      val.resize (dim_vector (0, 0));
+    }
+
+  switch (nargout)
+    {
+    case 0:
+    case 1:
+      retval(0) = idx;
+      break;
+
+    case 5:
+      retval(4) = nc;
+      // Fall through
+
+    case 4:
+      retval(3) = nr;
+      // Fall through
+
+    case 3:
+      retval(2) = val;
+      // Fall through!
+
+    case 2:
+      retval(1) = j_idx;
+      retval(0) = i_idx;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return retval;
+}
+
+template octave_value_list find_nonzero_elem_idx (const Sparse<double>&, int,
+						  octave_idx_type, int);
+
+template octave_value_list find_nonzero_elem_idx (const Sparse<Complex>&, int,
+						  octave_idx_type, int);
+
+template octave_value_list find_nonzero_elem_idx (const Sparse<bool>&, int,
+						  octave_idx_type, int);
+
+octave_value_list
+find_nonzero_elem_idx (const PermMatrix& v, int nargout, 
+		       octave_idx_type n_to_find, int direction)
+{
+  // There are far fewer special cases to handle for a PermMatrix.
+  octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
+
+  octave_idx_type nc = v.cols();
+  octave_idx_type start_nc, end_nc, count;
+ 
+  // Determine the range to search.
+  if (n_to_find < 0 || n_to_find >= nc)
+    {
+      start_nc = 0;
+      end_nc = nc;
+      n_to_find = nc;
+      count = nc;
+    }
+  else if (direction > 0)
+    {
+      start_nc = 0;
+      end_nc = n_to_find;
+      count = n_to_find;
+    }
+  else
+    {
+      start_nc = nc - n_to_find;
+      end_nc = nc;
+      count = n_to_find;
+    }
+
+  bool scalar_arg = (v.rows () == 1 && v.cols () == 1);
+
+  Matrix idx (count, 1);
+  Matrix i_idx (count, 1);
+  Matrix j_idx (count, 1);
+  // Every value is 1.
+  ArrayN<double> val (dim_vector (count, 1), 1.0);
+
+  if (count > 0)
+    {
+      const octave_idx_type* p = v.data ();
+      if (v.is_col_perm ())
+        {
+          for (octave_idx_type k = 0; k < count; k++) 
+            {
+              OCTAVE_QUIT;
+              const octave_idx_type j = start_nc + k;
+              const octave_idx_type i = p[j];
+              i_idx(k) = static_cast<double> (1+i);
+              j_idx(k) = static_cast<double> (1+j);
+              idx(k) = j * nc + i + 1;
+            }
+        }
+      else
+        {
+          for (octave_idx_type k = 0; k < count; k++) 
+            {
+              OCTAVE_QUIT;
+              const octave_idx_type i = start_nc + k;
+              const octave_idx_type j = p[i];
+              // Scatter into the index arrays according to
+              // j adjusted by the start point.
+              const octave_idx_type koff = j - start_nc;
+              i_idx(koff) = static_cast<double> (1+i);
+              j_idx(koff) = static_cast<double> (1+j);
+              idx(koff) = j * nc + i + 1;
+            }
+        }
+    }
+  else if (scalar_arg)
+    {
+      // Same odd compatibility case as the other overrides.
+      idx.resize (0, 0);
+      i_idx.resize (0, 0);
+      j_idx.resize (0, 0);
+      val.resize (dim_vector (0, 0));
+    }
+
+  switch (nargout)
+    {
+    case 0:
+    case 1:
+      retval(0) = idx;
+      break;
+
+    case 5:
+      retval(4) = nc;
+      // Fall through
+
+    case 4:
+      retval(3) = nc;
+      // Fall through
+
+    case 3:
+      retval(2) = val;
+      // Fall through!
+
+    case 2:
+      retval(1) = j_idx;
+      retval(0) = i_idx;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (find, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} find (@var{x})\n\
+ at deftypefnx {Loadable Function} {} find (@var{x}, @var{n})\n\
+ at deftypefnx {Loadable Function} {} find (@var{x}, @var{n}, @var{direction})\n\
+Return a vector of indices of nonzero elements of a matrix, as a row if\n\
+ at var{x} is a row or as a column otherwise.  To obtain a single index for\n\
+each matrix element, Octave pretends that the columns of a matrix form one\n\
+long vector (like Fortran arrays are stored).  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+find (eye (2))\n\
+     @result{} [ 1; 4 ]\n\
+ at end group\n\
+ at end example\n\
+\n\
+If two outputs are requested, @code{find} returns the row and column\n\
+indices of nonzero elements of a matrix.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+[i, j] = find (2 * eye (2))\n\
+     @result{} i = [ 1; 2 ]\n\
+     @result{} j = [ 1; 2 ]\n\
+ at end group\n\
+ at end example\n\
+\n\
+If three outputs are requested, @code{find} also returns a vector\n\
+containing the nonzero values.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+[i, j, v] = find (3 * eye (2))\n\
+     @result{} i = [ 1; 2 ]\n\
+     @result{} j = [ 1; 2 ]\n\
+     @result{} v = [ 3; 3 ]\n\
+ at end group\n\
+ at end example\n\
+\n\
+If two inputs are given, @var{n} indicates the maximum number of\n\
+elements to find from the beginning of the matrix or vector.\n\
+\n\
+If three inputs are given, @var{direction} should be one of \"first\" or\n\
+\"last\", requesting only the first or last @var{n} indices, respectively.\n\
+However, the indices are always returned in ascending order.\n\
+\n\
+Note that this function is particularly useful for sparse matrices, as\n\
+it extracts the non-zero elements as vectors, which can then be used to\n\
+create the original matrix.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+sz = size(a);\n\
+[i, j, v] = find (a);\n\
+b = sparse(i, j, v, sz(1), sz(2));\n\
+ at end group\n\
+ at end example\n\
+ at seealso{sparse}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 3 || nargin < 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // Setup the default options.
+  octave_idx_type n_to_find = -1;
+  if (nargin > 1)
+    {
+      double val = args(1).scalar_value ();
+
+      if (error_state || (! xisinf (val) && (val < 0 || val != xround (val))))
+	{
+	  error ("find: expecting second argument to be a nonnegative integer");
+	  return retval;
+	}
+      else
+        n_to_find = val;
+    }
+
+  // Direction to do the searching (1 == forward, -1 == reverse).
+  int direction = 1;
+  if (nargin > 2)
+    {
+      direction = 0;
+
+      std::string s_arg = args(2).string_value ();
+
+      if (! error_state)
+	{
+	  if (s_arg == "first")
+	    direction = 1;
+	  else if (s_arg == "last")
+	    direction = -1;
+	}
+
+      if (direction == 0)
+	{
+	  error ("find: expecting third argument to be \"first\" or \"last\"");
+	  return retval;
+	}
+    }
+
+  octave_value arg = args(0);
+
+  if (arg.is_bool_type ())
+    {
+      if (arg.is_sparse_type ())
+        {
+	  SparseBoolMatrix v = arg.sparse_bool_matrix_value ();
+
+	  if (! error_state)
+	    retval = find_nonzero_elem_idx (v, nargout, 
+					    n_to_find, direction);
+        }
+      else
+        {
+          boolNDArray v = arg.bool_array_value ();
+
+	  if (! error_state)
+	    retval = find_nonzero_elem_idx (v, nargout, 
+					    n_to_find, direction);
+        }
+    }
+  else if (arg.is_integer_type ())
+    {
+#define DO_INT_BRANCH(INTT) \
+      else if (arg.is_ ## INTT ## _type ()) \
+        { \
+          INTT ## NDArray v = arg.INTT ## _array_value (); \
+          \
+	  if (! error_state) \
+	    retval = find_nonzero_elem_idx (v, nargout, \
+					    n_to_find, direction);\
+        }
+
+      if (false)
+        ;
+      DO_INT_BRANCH (int8)
+      DO_INT_BRANCH (int16)
+      DO_INT_BRANCH (int32)
+      DO_INT_BRANCH (int64)
+      DO_INT_BRANCH (uint8)
+      DO_INT_BRANCH (uint16)
+      DO_INT_BRANCH (uint32)
+      DO_INT_BRANCH (uint64)
+      else
+        panic_impossible ();
+    }
+  else if (arg.is_sparse_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	  SparseMatrix v = arg.sparse_matrix_value ();
+
+	  if (! error_state)
+	    retval = find_nonzero_elem_idx (v, nargout, 
+					    n_to_find, direction);
+	}
+      else if (arg.is_complex_type ())
+	{
+	  SparseComplexMatrix v = arg.sparse_complex_matrix_value ();
+
+	  if (! error_state)
+	    retval = find_nonzero_elem_idx (v, nargout, 
+					    n_to_find, direction);
+	}
+      else 
+	gripe_wrong_type_arg ("find", arg);
+    }
+  else if (arg.is_perm_matrix ()) {
+    PermMatrix P = arg.perm_matrix_value ();
+
+    if (! error_state)
+      retval = find_nonzero_elem_idx (P, nargout, n_to_find, direction);
+  }
+  else
+    {
+      if (arg.is_single_type ())
+	{
+	  if (arg.is_real_type ())
+	    {
+	      FloatNDArray nda = arg.float_array_value ();
+
+	      if (! error_state)
+		retval = find_nonzero_elem_idx (nda, nargout, 
+						n_to_find, direction);
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      FloatComplexNDArray cnda = arg.float_complex_array_value ();
+
+	      if (! error_state)
+		retval = find_nonzero_elem_idx (cnda, nargout, 
+						n_to_find, direction);
+	    }
+	}
+      else
+	{
+	  if (arg.is_real_type ())
+	    {
+	      NDArray nda = arg.array_value ();
+
+	      if (! error_state)
+		retval = find_nonzero_elem_idx (nda, nargout, 
+						n_to_find, direction);
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      ComplexNDArray cnda = arg.complex_array_value ();
+
+	      if (! error_state)
+		retval = find_nonzero_elem_idx (cnda, nargout, 
+						n_to_find, direction);
+	    }
+	  else if (arg.is_string ())
+	    {
+	      charNDArray cnda = arg.char_array_value ();
+
+	      if (! error_state)
+		retval = find_nonzero_elem_idx (cnda, nargout, 
+						n_to_find, direction);
+	    }
+	  else
+	    {
+	      gripe_wrong_type_arg ("find", arg);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+%!assert(find ([1, 0, 1, 0, 1]), [1, 3, 5]);
+%!assert(find ([1; 0; 3; 0; 1]), [1; 3; 5]);
+%!assert(find ([0, 0, 2; 0, 3, 0; -1, 0, 0]), [3; 5; 7]);
+
+%!test
+%! [i, j, v] = find ([0, 0, 2; 0, 3, 0; -1, 0, 0]);
+%! 
+%! assert(i, [3; 2; 1]);
+%! assert(j, [1; 2; 3]);
+%! assert(v, [-1; 3; 2]);
+
+%!assert(find (single([1, 0, 1, 0, 1])), [1, 3, 5]);
+%!assert(find (single([1; 0; 3; 0; 1])), [1; 3; 5]);
+%!assert(find (single([0, 0, 2; 0, 3, 0; -1, 0, 0])), [3; 5; 7]);
+
+%!test
+%! [i, j, v] = find (single([0, 0, 2; 0, 3, 0; -1, 0, 0]));
+%! 
+%! assert(i, [3; 2; 1]);
+%! assert(j, [1; 2; 3]);
+%! assert(v, single([-1; 3; 2]));
+
+%!test
+%! pcol = [5 1 4 3 2];
+%! P = eye (5) (:, pcol);
+%! [i, j, v] = find (P);
+%! [ifull, jfull, vfull] = find (full (P));
+%! assert (i, ifull);
+%! assert (j, jfull);
+%! assert (all (v == 1));
+
+%!test
+%! prow = [5 1 4 3 2];
+%! P = eye (5) (prow, :);
+%! [i, j, v] = find (P);
+%! [ifull, jfull, vfull] = find (full (P));
+%! assert (i, ifull);
+%! assert (j, jfull);
+%! assert (all (v == 1));
+
+%!assert (find ([2 0 1 0 5 0], 1), 1)
+%!assert (find ([2 0 1 0 5 0], 2, "last"), [3, 5])
+
+%!assert (find ([2 0 1 0 5 0], Inf), [1, 3, 5])
+%!assert (find ([2 0 1 0 5 0], Inf, "last"), [1, 3, 5])
+
+%!error <Invalid call to find.*> find ();
+
+ */
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/fltk_backend.cc b/src/DLD-FUNCTIONS/fltk_backend.cc
new file mode 100644
index 0000000..5243afd
--- /dev/null
+++ b/src/DLD-FUNCTIONS/fltk_backend.cc
@@ -0,0 +1,912 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 Shai Ayal
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+To initialize:
+
+  backend ("fltk");
+  plot (randn (1e3, 1));
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (HAVE_FLTK)
+
+#include <map>
+#include <set>
+#include <sstream>
+#include <iostream>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Gl_Window.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_draw.H>
+#include <FL/gl.h>
+
+#ifdef min
+#undef min
+#undef max
+#endif
+
+#include "cmd-edit.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gl-render.h"
+#include "graphics.h"
+#include "parse.h"
+#include "variables.h"
+
+#define FLTK_BACKEND_NAME "fltk"
+
+const char* help_text = "\
+Keyboard Shortcuts\n\
+a - autoscale\n\
+g - toggle grid\n\
+\n\
+Mouse\n\
+left drag - zoom\n\
+right click - unzoom\n\
+double click - copy coordinates to clipboard\
+";
+
+class OpenGL_fltk : public Fl_Gl_Window
+{
+public:
+  OpenGL_fltk (int xx, int yy, int ww, int hh, double num)
+    : Fl_Gl_Window (xx, yy, ww, hh, 0), number (num), in_zoom (false)
+  {
+    // ask for double buffering and a depth buffer
+    mode (FL_DEPTH | FL_DOUBLE);
+  }
+
+  ~OpenGL_fltk (void) { }
+
+  void zoom (bool z) { in_zoom = z; }
+  bool zoom (void) { return in_zoom; }
+  void set_zoom_box (const Matrix& zb) { zoom_box = zb; }
+
+private:
+  double number;
+  opengl_renderer renderer;
+  bool in_zoom;
+
+  // (x1,y1,x2,y2)
+  Matrix zoom_box;
+
+  void setup_viewport (int _w, int _h)
+  {
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    glViewport (0, 0, _w, _h);
+  }
+
+  void draw (void)
+  {
+    if (!valid ())
+      {
+	valid (1);
+	setup_viewport (w (), h ());
+      }
+
+    renderer.draw (gh_manager::lookup (number));
+  }
+
+  void resize (int _x,int _y,int _w,int _h)
+  {
+    Fl_Gl_Window::resize (_x, _y, _w, _h);
+    setup_viewport (_w, _h);
+    redraw ();
+  }
+
+  void draw_overlay (void)
+  {
+    if (!in_zoom)
+      return;
+
+    if (!valid())
+      {
+	valid(1);
+	setup_viewport (w (), h ());
+      }
+
+    glPushMatrix ();
+
+    glMatrixMode (GL_MODELVIEW);
+    glLoadIdentity ();
+
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    gluOrtho2D (0.0, w (), 0.0, h ());
+
+    glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT);
+    glDisable (GL_DEPTH_TEST);
+
+    glLineWidth (1);
+    glBegin (GL_LINE_STRIP);
+    gl_color(0);
+    glVertex2d (zoom_box(0), h () - zoom_box(1));
+    glVertex2d (zoom_box(0), h () - zoom_box(3));
+    glVertex2d (zoom_box(2), h () - zoom_box(3));
+    glVertex2d (zoom_box(2), h () - zoom_box(1));
+    glVertex2d (zoom_box(0), h () - zoom_box(1));
+    glEnd ();
+
+    glPopAttrib ();
+    glPopMatrix ();
+  }
+
+  int handle (int event)
+  {
+    int retval = Fl_Gl_Window::handle (event);
+
+    switch (event)
+      {
+      case FL_ENTER:
+	window ()->cursor (FL_CURSOR_CROSS);
+	return 1;
+
+      case FL_LEAVE:
+	window ()->cursor (FL_CURSOR_DEFAULT);
+	return 1;
+      }
+
+    return retval;
+  }
+};
+
+class plot_window : public Fl_Window
+{
+public:
+  plot_window (int _x, int _y, int _w, int _h, figure::properties& _fp)
+    : Fl_Window (_x, _y, _w, _h, "octave"), fp (_fp)
+  {
+    callback (window_close, static_cast<void*> (this));
+
+    begin ();
+    {
+      canvas = new
+	OpenGL_fltk (0, 0, _w , _h - status_h, number ());
+
+      autoscale = new
+	Fl_Button (0,
+		   _h - status_h,
+		   status_h,
+		   status_h,
+		   "A");
+      autoscale->callback (button_callback, static_cast<void*> (this));
+
+      togglegrid = new
+	Fl_Button (status_h,
+		   _h - status_h,
+		   status_h,
+		   status_h,
+		   "G");
+      togglegrid->callback (button_callback, static_cast<void*> (this));
+
+      help = new
+	Fl_Button (2*status_h,
+		   _h - status_h,
+		   status_h,
+		   status_h,
+		   "H");
+      help->callback (button_callback, static_cast<void*> (this));
+
+      status = new
+	Fl_Output (3*status_h,
+		   _h - status_h,
+		   _w > 2*status_h ? _w - status_h : 0,
+		   status_h, "");
+
+      status->textcolor (FL_BLACK);
+      status->color (FL_GRAY);
+      status->textfont (FL_COURIER);
+      status->textsize (10);
+      status->box (FL_ENGRAVED_BOX);
+
+      // This allows us to have a valid OpenGL context right away
+      canvas->mode (FL_DEPTH | FL_DOUBLE );
+      show ();
+      canvas->show ();
+      canvas->make_current ();
+    }
+    end ();
+
+    status->show ();
+    autoscale->show ();
+    togglegrid->show ();
+
+    resizable (canvas);
+    size_range (4*status_h, 2*status_h);
+
+    std::stringstream name;
+    name << "octave: figure " << number ();
+    label (name.str ().c_str ());
+  }
+
+  ~plot_window (void)
+  {
+    canvas->hide ();
+    status->hide ();
+    this->hide ();
+    delete canvas;
+    delete status;
+  }
+
+  // FIXME -- this could change
+  double number (void) { return fp.get___myhandle__ ().value (); }
+
+  void mark_modified (void)
+  {
+    damage (FL_DAMAGE_ALL);
+    canvas->damage (FL_DAMAGE_ALL);
+  }
+
+private:
+  // figure properties
+  figure::properties& fp;
+
+  // status area height
+  static const int status_h = 20;
+
+  // window callback
+  static void window_close (Fl_Widget*, void* data)
+  {
+    octave_value_list args;
+    args(0) = static_cast<plot_window*> (data)->number ();
+    feval ("close", args);
+  }
+
+  // button callbacks
+  static void button_callback (Fl_Widget* ww, void* data)
+  {
+    static_cast<plot_window*> (data)->button_press (ww);
+  }
+
+  void button_press (Fl_Widget* widg)
+  {
+    if (widg == autoscale)
+      axis_auto ();
+
+    if (widg == togglegrid)
+      toggle_grid ();
+
+    if (widg == help)
+      fl_message ("%s", help_text);
+  }
+
+  OpenGL_fltk* canvas;
+  Fl_Button* autoscale;
+  Fl_Button* togglegrid;
+  Fl_Button* help;
+  Fl_Output* status;
+
+  void axis_auto (void)
+  {
+    octave_value_list args;
+    args(0) = "auto";
+    feval ("axis",args);
+    mark_modified ();
+  }
+
+  void toggle_grid (void)
+  {
+    feval ("grid");
+    mark_modified ();
+  }
+
+  void pixel2pos (int px, int py, double& xx, double& yy) const
+  {
+    graphics_object ax = gh_manager::get_object (fp.get_currentaxes ());
+
+    if (ax && ax.isa ("axes"))
+      {
+	axes::properties& ap =
+	  dynamic_cast<axes::properties&> (ax.get_properties ());
+	ColumnVector pp = ap.pixel2coord (px, py);
+	xx = pp(0);
+	yy = pp(1);
+      }
+  }
+
+  graphics_handle pixel2axes (int /* px */, int /* py */)
+  {
+    Matrix kids = fp.get_children ();
+
+    for (octave_idx_type n = 0; n < kids.numel (); n++)
+      {
+	graphics_object ax = gh_manager::get_object (kids (n));
+	if (ax && ax.isa ("axes"))
+	  {
+#if 0
+	     axes::properties& ap =
+	       dynamic_cast<axes::properties&> (ax.get_properties ());
+
+	     // std::cout << "\npixpos="<<pixpos<<"(px,py)=("<<px<<","<<py<<")\n";
+	     if (px >= pixpos(0) && px <= pixpos(2)
+		 && py >= pixpos(1) && py <= pixpos(3))
+	       return ap.get___myhandle__ ();
+#endif
+	  }
+      }
+
+    return graphics_handle ();
+  }
+
+  void pixel2status (int px0, int py0, int px1 = -1, int py1 = -1)
+  {
+    double x0, y0, x1, y1;
+    std::stringstream cbuf;
+
+    pixel2pos (px0, py0, x0, y0);
+    cbuf << "[" << x0 << ", " << y0 << "]";
+    if (px1 >= 0)
+      {
+	pixel2pos (px1, py1, x1, y1);
+	cbuf << " -> ["<< x1 << ", " << y1 << "]";
+      }
+
+    status->value (cbuf.str ().c_str ());
+    status->redraw ();
+  }
+
+  void resize (int _x,int _y,int _w,int _h)
+  {
+    Fl_Window::resize (_x, _y, _w, _h);
+
+    Matrix pos (1,4,0);
+    pos(0) = _x;
+    pos(1) = _y;
+    pos(2) = _w;
+    pos(3) = _h - status_h;
+
+    fp.set_position (pos);
+  }
+
+  void draw (void)
+  {
+    Matrix pos = fp.get_position ().matrix_value ();
+    Fl_Window::resize (pos(0), pos(1) , pos(2), pos(3) + status_h);
+
+    return Fl_Window::draw ();
+  }
+
+  int handle (int event)
+  {
+    static int px0,py0;
+    static graphics_handle h0 = graphics_handle ();
+
+    int retval = Fl_Window::handle (event);
+
+    // we only handle events which are in the canvas area
+    if (Fl::event_y () >= h() - status_h)
+      return retval;
+
+    switch (event)
+      {
+      case FL_KEYDOWN:
+	switch(Fl::event_key ())
+	  {
+	  case 'a':
+	  case 'A':
+	    axis_auto ();
+	    break;
+
+	  case 'g':
+	  case 'G':
+	    toggle_grid ();
+	    break;
+	  }
+	break;
+
+      case FL_MOVE:
+	pixel2status (Fl::event_x (), Fl::event_y ());
+	break;
+
+      case FL_PUSH:
+	if (Fl::event_button () == 1)
+	  {
+	    px0 = Fl::event_x ();
+	    py0 = Fl::event_y ();
+	    h0 = pixel2axes (Fl::event_x (), Fl::event_y ());
+	    return 1;
+	  }
+	break;
+
+      case FL_DRAG:
+	pixel2status (px0, py0, Fl::event_x (), Fl::event_y ());
+	if (Fl::event_button () == 1)
+	  {
+	    canvas->zoom (true);
+	    Matrix zoom_box (1,4,0);
+	    zoom_box (0) = px0;
+	    zoom_box (1) = py0;
+	    zoom_box (2) =  Fl::event_x ();
+	    zoom_box (3) =  Fl::event_y ();
+	    canvas->set_zoom_box (zoom_box);
+	    canvas->redraw_overlay ();
+	    return 1;
+	  }
+	break;
+
+      case FL_RELEASE:
+	if (Fl::event_button () == 1)
+	  {
+	    // end of drag -- zoom
+	    if (canvas->zoom ())
+	      {
+		canvas->zoom (false);
+		double x0,y0,x1,y1;
+		graphics_object ax =
+		  gh_manager::get_object (fp.get_currentaxes ());
+		if (ax && ax.isa ("axes"))
+		  {
+		    axes::properties& ap =
+		      dynamic_cast<axes::properties&> (ax.get_properties ());
+		    pixel2pos (px0, py0, x0, y0);
+		    pixel2pos (Fl::event_x (), Fl::event_y (), x1, y1);
+		    Matrix xl (1,2,0);
+		    Matrix yl (1,2,0);
+		    if (x0 < x1)
+		      {
+			xl(0) = x0;
+			xl(1) = x1;
+		      }
+		    else
+		      {
+			xl(0) = x1;
+			xl(1) = x0;
+		      }
+
+		    if (y0 < y1)
+		      {
+			yl(0) = y0;
+			yl(1) = y1;
+		      }
+		    else
+		      {
+			yl(0) = y1;
+			yl(1) = y0;
+		      }
+		    ap.zoom (xl, yl);
+		    mark_modified ();
+		  }
+	      }
+	    // one click -- select axes
+	    else if ( Fl::event_clicks () == 0)
+	      {
+		std::cout << "ca="<< h0.value ()<<"\n";
+		if (h0.ok ())
+		  fp.set_currentaxes (h0.value());
+		return 1;
+	      }
+	  }
+	else if (Fl::event_button () == 3)
+	  {
+	    graphics_object ax =
+	      gh_manager::get_object (fp.get_currentaxes ());
+	    if (ax && ax.isa ("axes"))
+	      {
+		axes::properties& ap =
+		  dynamic_cast<axes::properties&> (ax.get_properties ());
+		ap.unzoom ();
+		mark_modified ();
+	      }
+	  }
+	break;
+      }
+
+    return retval;
+  }
+};
+
+class figure_manager
+{
+public:
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new figure_manager ();
+
+    if (! instance)
+      {
+	::error ("unable to create figure_manager object!");
+
+	retval = false;
+      }
+
+    return retval;
+  }
+
+  ~figure_manager (void)
+  {
+    close_all ();
+  }
+
+  static void close_all (void)
+  {
+    if (instance_ok ())
+      instance->do_close_all ();
+  }
+
+  static void new_window (figure::properties& fp)
+  {
+    if (instance_ok ())
+      instance->do_new_window (fp);
+  }
+
+  static void delete_window (int idx)
+  {
+    if (instance_ok ())
+      instance->do_delete_window (idx);
+  }
+
+  static void delete_window (std::string idx_str)
+  {
+    delete_window (str2idx (idx_str));
+  }
+
+  static void mark_modified (int idx)
+  {
+    if (instance_ok ())
+      instance->do_mark_modified (idx);
+  }
+
+  static void mark_modified (const graphics_handle& gh)
+  {
+    mark_modified (hnd2idx (gh));
+  }
+
+  static Matrix get_size (int idx)
+  {
+    return instance_ok () ? instance->do_get_size (idx) : Matrix ();
+  }
+
+  static Matrix get_size (const graphics_handle& gh)
+  {
+    return get_size (hnd2idx (gh));
+  }
+
+private:
+
+  static figure_manager *instance;
+
+  figure_manager (void) { }
+
+  // No copying!
+  figure_manager (const figure_manager&);
+  figure_manager& operator = (const figure_manager&);
+
+  // singelton -- hide all of the above
+
+  static int curr_index;
+  typedef std::map<int, plot_window*> window_map;
+  typedef window_map::iterator wm_iterator;;
+  window_map windows;
+
+  static std::string fltk_idx_header;
+
+  void do_close_all (void)
+  {
+    wm_iterator win;
+    for (win = windows.begin (); win != windows.end (); win++)
+      delete win->second;
+    windows.clear ();
+  }
+
+  void do_new_window (figure::properties& fp)
+  {
+    int x, y, w, h;
+
+    int idx = figprops2idx (fp);
+    if (idx >= 0 && windows.find (idx) == windows.end ())
+      {
+	default_size (x, y, w, h);
+	idx2figprops (curr_index , fp);
+	windows[curr_index++] = new plot_window (x, y, w, h, fp);
+      }
+  }
+
+  void do_delete_window (int idx)
+  {
+    wm_iterator win;
+    if ((win = windows.find (idx)) != windows.end ())
+      {
+	delete win->second;
+	windows.erase (win);
+      }
+  }
+
+  void do_mark_modified (int idx)
+  {
+    wm_iterator win;
+    if ((win = windows.find (idx)) != windows.end ())
+      {
+	win->second->mark_modified ();
+      }
+  }
+
+  Matrix do_get_size (int idx)
+  {
+    Matrix sz (1, 2, 0.0);
+
+    wm_iterator win;
+    if ((win = windows.find (idx)) != windows.end ())
+      {
+	sz(0) = win->second->w ();
+	sz(1) = win->second->h ();
+      }
+
+    return sz;
+  }
+
+  // FIXME -- default size should be configurable.
+  void default_size (int& x, int& y, int& w, int& h)
+  {
+    x = 0;
+    y = 0;
+    w = 640;
+    h = 480;
+  }
+
+  static int str2idx (const caseless_str clstr)
+  {
+    int ind;
+    if (clstr.find (fltk_idx_header,0) == 0)
+      {
+	std::istringstream istr (clstr.substr (fltk_idx_header.size ()));
+	if (istr >> ind)
+	  return ind;
+      }
+    error ("fltk_backend: could not recognize fltk index");
+    return -1;
+  }
+
+  void idx2figprops (int idx, figure::properties& fp)
+  {
+    std::ostringstream ind_str;
+    ind_str << fltk_idx_header << idx;
+    fp.set___plot_stream__ (ind_str.str ());
+  }
+
+  static int figprops2idx (const figure::properties& fp)
+  {
+    if (fp.get___backend__ () == FLTK_BACKEND_NAME)
+      {
+	octave_value ps = fp.get___plot_stream__ ();
+	if (ps.is_string ())
+	  return str2idx (ps.string_value ());
+	else
+	  return 0;
+      }
+    error ("fltk_backend:: figure is not fltk");
+    return -1;
+  }
+
+  static int hnd2idx (const double h)
+  {
+    graphics_object fobj = gh_manager::get_object (h);
+    if (fobj &&  fobj.isa ("figure"))
+      {
+	figure::properties& fp =
+	  dynamic_cast<figure::properties&> (fobj.get_properties ());
+	return figprops2idx (fp);
+      }
+    error ("fltk_backend:: not a figure");
+    return -1;
+  }
+
+  static int hnd2idx (const graphics_handle& fh)
+  {
+    return hnd2idx (fh.value ());
+  }
+};
+
+figure_manager *figure_manager::instance = 0;
+
+std::string figure_manager::fltk_idx_header="fltk index=";
+int figure_manager::curr_index = 1;
+
+class fltk_backend : public base_graphics_backend
+{
+public:
+  fltk_backend (void)
+    : base_graphics_backend (FLTK_BACKEND_NAME) { }
+
+  ~fltk_backend (void) { }
+
+  bool is_valid (void) const { return true; }
+
+  void object_destroyed (const graphics_object& go)
+  {
+    if (go.isa ("figure"))
+      {
+	octave_value ov = go.get (caseless_str ("__plot_stream__"));
+	figure_manager::delete_window (ov.string_value ());
+      }
+  }
+
+  void property_changed (const graphics_object& go, int id)
+  {
+    if (go.isa ("figure"))
+      {
+	octave_value ov = go.get (caseless_str ("__plot_stream__"));
+	
+	if (! ov.is_empty ())
+	  {
+	    switch (id)
+	      {
+	      case base_properties::VISIBLE:
+		// FIXME -- something to do here.
+		break;
+	      }
+	  }
+      }
+  }
+
+  void redraw_figure (const graphics_object& go) const
+  {
+    figure_manager::mark_modified (go.get_handle ());
+  }
+
+  void print_figure (const graphics_object& /*go*/,
+		     const std::string& /*term*/,
+		     const std::string& /*file*/, bool /*mono*/,
+		     const std::string& /*debug_file*/) const { }
+
+  Matrix get_canvas_size (const graphics_handle& fh) const
+  {
+    return figure_manager::get_size (fh);
+  }
+
+  double get_screen_resolution (void) const
+  {
+    // FLTK doesn't give this info
+    return 72.0;
+  }
+
+  Matrix get_screen_size (void) const
+  {
+    Matrix sz (1, 2, 0.0);
+    sz(0) = Fl::w ();
+    sz(1) = Fl::h ();
+    return sz;
+  }
+};
+
+static bool backend_registered = false;
+// give FLTK no more than 0.01 sec to do it's stuff
+static double fltk_maxtime = 1e-2;
+
+static int
+__fltk_redraw__ (void)
+{
+  if (backend_registered)
+    {
+      // we scan all figures and add those which use FLTK as a backend
+      graphics_object obj = gh_manager::get_object (0);
+      if (obj && obj.isa ("root"))
+	{
+	  base_properties& props = obj.get_properties ();
+	  Matrix children = props.get_children ();
+
+	  for (octave_idx_type n = 0; n < children.numel (); n++)
+	    {
+	      graphics_object fobj = gh_manager::get_object (children (n));
+	      if (fobj && fobj.isa ("figure"))
+		{
+		  figure::properties& fp =
+		      dynamic_cast<figure::properties&> (fobj.get_properties ());
+		  if (fp.get___backend__ () == FLTK_BACKEND_NAME)
+		    figure_manager::new_window (fp);
+		}
+	    }
+	}
+
+      Fl::wait (fltk_maxtime);
+    }
+
+  return 0;
+}
+
+DEFUN_DLD (__fltk_redraw__, , , "")
+{
+  __fltk_redraw__ ();
+
+  return octave_value ();
+}
+
+// call this to init the fltk backend
+DEFUN_DLD (__init_fltk__, , , "")
+{
+  if (! backend_registered)
+    {
+      mlock ();
+
+      graphics_backend::register_backend (new fltk_backend);
+      backend_registered = true;
+      
+      octave_value_list args;
+      args(0) = "__fltk_redraw__";
+      feval ("add_input_event_hook", args, 0);
+    }
+
+  octave_value retval;
+  return retval;
+}
+
+
+// call this to delete the fltk backend
+DEFUN_DLD (__remove_fltk__, , , "")
+{
+  if (backend_registered)
+    {
+      munlock ("__init_fltk__");
+
+      figure_manager::close_all ();
+      graphics_backend::unregister_backend (FLTK_BACKEND_NAME);
+      backend_registered = false;
+
+      octave_value_list args;
+      args(0) = "__fltk_redraw__";
+      feval ("remove_input_event_hook", args, 0);
+
+      // FIXME ???
+      // give FLTK 10 seconds to wrap it up
+      Fl::wait(10);
+    }
+
+  octave_value retval;
+  return retval;	
+}
+
+DEFUN_DLD (__fltk_maxtime__, args, ,"")
+{
+  octave_value retval = fltk_maxtime;
+
+  if (args.length () == 1)
+    {
+      if (args(0).is_real_scalar ())
+      fltk_maxtime = args(0).double_value ();
+    else
+      error ("argument must be a real scalar");
+    }
+
+  return retval;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/gammainc.cc b/src/DLD-FUNCTIONS/gammainc.cc
new file mode 100644
index 0000000..ed579cb
--- /dev/null
+++ b/src/DLD-FUNCTIONS/gammainc.cc
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 1997, 1999, 2000, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-specfun.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (gammainc, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} gammainc (@var{x}, @var{a})\n\
+Compute the normalized incomplete gamma function,\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+ \\gamma (x, a) = {\\displaystyle\\int_0^x e^{-t} t^{a-1} dt \\over \\Gamma (a)}\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at smallexample\n\
+                                x\n\
+                      1        /\n\
+gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt\n\
+                  gamma (a)    /\n\
+                            t=0\n\
+ at end smallexample\n\
+\n\
+ at end ifnottex\n\
+with the limiting value of 1 as @var{x} approaches infinity.\n\
+The standard notation is @math{P(a,x)}, e.g., Abramowitz and Stegun (6.5.1).\n\
+\n\
+If @var{a} is scalar, then @code{gammainc (@var{x}, @var{a})} is returned\n\
+for each element of @var{x} and vice versa.\n\
+\n\
+If neither @var{x} nor @var{a} is scalar, the sizes of @var{x} and\n\
+ at var{a} must agree, and @var{gammainc} is applied element-by-element.\n\
+ at seealso{gamma, lgamma}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      octave_value x_arg = args(0);
+      octave_value a_arg = args(1);
+
+      // FIXME Can we make a template version of the duplicated code below
+      if (x_arg.is_single_type () || a_arg.is_single_type ())
+	{
+	  if (x_arg.is_scalar_type ())
+	    {
+	      float x = x_arg.float_value ();
+
+	      if (! error_state)
+		{
+		  if (a_arg.is_scalar_type ())
+		    {
+		      float a = a_arg.float_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		  else
+		    {
+		      FloatNDArray a = a_arg.float_array_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		}
+	    }
+	  else
+	    {
+	      FloatNDArray x = x_arg.float_array_value ();
+
+	      if (! error_state)
+		{
+		  if (a_arg.is_scalar_type ())
+		    {
+		      float a = a_arg.float_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		  else
+		    {
+		      FloatNDArray a = a_arg.float_array_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  if (x_arg.is_scalar_type ())
+	    {
+	      double x = x_arg.double_value ();
+
+	      if (! error_state)
+		{
+		  if (a_arg.is_scalar_type ())
+		    {
+		      double a = a_arg.double_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		  else
+		    {
+		      NDArray a = a_arg.array_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		}
+	    }
+	  else
+	    {
+	      NDArray x = x_arg.array_value ();
+
+	      if (! error_state)
+		{
+		  if (a_arg.is_scalar_type ())
+		    {
+		      double a = a_arg.double_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		  else
+		    {
+		      NDArray a = a_arg.array_value ();
+
+		      if (! error_state)
+			retval = gammainc (x, a);
+		    }
+		}
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = [.5 .5 .5 .5 .5];
+%! x = [0 1 2 3 4];
+%! v1 = sqrt(pi)*erf(x)./gamma(a);
+%! v3 = gammainc(x.*x,a);
+%! assert(v1, v3, sqrt(eps));
+
+%!test
+%! a = single ([.5 .5 .5 .5 .5]);
+%! x = single([0 1 2 3 4]);
+%! v1 = sqrt(pi('single'))*erf(x)./gamma(a);
+%! v3 = gammainc(x.*x,a);
+%! assert(v1, v3, sqrt(eps('single')));
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/DLD-FUNCTIONS/gcd.cc b/src/DLD-FUNCTIONS/gcd.cc
new file mode 100644
index 0000000..2b90e6e
--- /dev/null
+++ b/src/DLD-FUNCTIONS/gcd.cc
@@ -0,0 +1,531 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dNDArray.h"
+#include "CNDArray.h"
+#include "fNDArray.h"
+#include "fCNDArray.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+// FIXME -- should probably handle Inf, NaN.
+
+static inline bool
+is_integer_value (double x)
+{
+  return x == std::floor (x);
+}
+
+static inline bool
+is_integer_value (float x)
+{
+  return x == std::floor (x);
+}
+
+DEFUN_DLD (gcd, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {@var{g} =} gcd (@var{a})\n\
+ at deftypefnx {Loadable Function} {@var{g} =} gcd (@var{a1}, @var{a2}, @dots{})\n\
+ at deftypefnx {Loadable Function} {[@var{g}, @var{v1}, @dots{}] =} gcd (@var{a1}, @var{a2}, @dots{})\n\
+\n\
+Compute the greatest common divisor of the elements of @var{a}.  If more\n\
+than one argument is given all arguments must be the same size or scalar.\n\
+  In this case the greatest common divisor is calculated for each element\n\
+individually.  All elements must be integers.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+gcd ([15, 20])\n\
+    @result{}  5\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+and\n\
+\n\
+ at example\n\
+ at group\n\
+gcd ([15, 9], [20, 18])\n\
+    @result{}  5  9\n\
+ at end group\n\
+ at end example\n\
+\n\
+Optional return arguments @var{v1}, etc., contain integer vectors such\n\
+that,\n\
+\n\
+ at tex\n\
+$g = v_1 a_1 + v_2 a_2 + \\cdots$\n\
+ at end tex\n\
+ at ifnottex\n\
+ at example\n\
+ at var{g} = @var{v1} .* @var{a1} + @var{v2} .* @var{a2} + @dots{}\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+For backward compatibility with previous versions of this function, when\n\
+all arguments are scalar, a single return argument @var{v1} containing\n\
+all of the values of @var{v1}, @dots{} is acceptable.\n\
+ at seealso{lcm, factor}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  bool all_args_scalar = true;
+  bool any_single = false;
+
+  dim_vector dv(1);
+
+  for (int i = 0; i < nargin; i++)
+    {
+      if (! args(i).is_scalar_type ())
+	{
+	  if (! args(i).is_matrix_type ())
+	    {
+	      error ("gcd: invalid argument type");
+	      return retval;
+	    }
+
+	  if (all_args_scalar)
+	    {
+	      all_args_scalar = false;
+	      dv = args(i).dims ();
+	    }
+	  else
+	    {
+	      if (dv != args(i).dims ())
+		{
+		  error ("gcd: all arguments must be the same size or scalar");
+		  return retval;
+		}
+	    }
+	}
+      if (!any_single && args(i).is_single_type ())
+	any_single = true;
+    }
+
+  if (any_single)
+    {
+      if (nargin == 1)
+	{
+	  FloatNDArray gg = args(0).float_array_value ();
+
+	  int nel = dv.numel ();
+
+	  FloatNDArray v (dv);
+
+	  FloatRowVector x (3);
+	  FloatRowVector y (3);
+
+	  float g = std::abs (gg(0));
+
+	  if (! is_integer_value (g))
+	    {
+	      error ("gcd: all arguments must be integer");
+	      return retval;
+	    }
+
+	  v(0) = signum (gg(0));
+      
+	  for (int k = 1; k < nel; k++)
+	    {
+	      x(0) = g;
+	      x(1) = 1;
+	      x(2) = 0;
+
+	      y(0) = std::abs (gg(k));
+	      y(1) = 0;
+	      y(2) = 1;
+
+	      if (! is_integer_value (y(0)))
+		{
+		  error ("gcd: all arguments must be integer");
+		  return retval;
+		}
+
+	      while (y(0) > 0)
+		{
+		  FloatRowVector r = x - y * std::floor (x(0) / y(0));
+		  x = y;
+		  y = r;
+		}
+
+	      g = x(0);
+
+	      for (int i = 0; i < k; i++) 
+		v(i) *= x(1);
+
+	      v(k) = x(2) * signum (gg(k));
+	    }
+
+	  retval (1) = v;
+	  retval (0) = g;
+	}
+      else if (all_args_scalar && nargout < 3)
+	{
+	  float g = args(0).float_value ();
+
+	  if (error_state || ! is_integer_value (g))
+	    {
+	      error ("gcd: all arguments must be integer");
+	      return retval;
+	    }
+
+	  FloatRowVector v (nargin, 0);
+	  FloatRowVector x (3);
+	  FloatRowVector y (3);
+
+	  v(0) = signum (g);
+
+	  g = std::abs(g);
+      
+	  for (int k = 1; k < nargin; k++)
+	    {
+	      x(0) = g;
+	      x(1) = 1;
+	      x(2) = 0;
+
+	      y(0) = args(k).float_value ();
+	      y(1) = 0;
+	      y(2) = 1;
+
+	      float sgn = signum (y(0));
+
+	      y(0) = std::abs (y(0));
+
+	      if (error_state || ! is_integer_value (g))
+		{
+		  error ("gcd: all arguments must be integer");
+		  return retval;
+		}
+
+	      while (y(0) > 0)
+		{
+		  FloatRowVector r = x - y * std::floor (x(0) / y(0));
+		  x = y;
+		  y = r;
+		}
+
+	      g = x(0);
+
+	      for (int i = 0; i < k; i++) 
+		v(i) *= x(1);
+
+	      v(k) = x(2) * sgn;
+	    }
+
+	  retval (1) = v;
+	  retval (0) = g;
+	}
+      else
+	{
+	  // FIXME -- we need to handle a possible mixture of scalar and
+	  // array values here.
+
+	  FloatNDArray g = args(0).float_array_value ();
+
+	  OCTAVE_LOCAL_BUFFER (FloatNDArray, v, nargin);
+
+	  int nel = dv.numel ();
+
+	  v[0].resize(dv);
+
+	  for (int i = 0; i < nel; i++)
+	    {
+	      v[0](i) = signum (g(i));
+	      g(i) = std::abs (g(i));
+
+	      if (! is_integer_value (g(i)))
+		{
+		  error ("gcd: all arguments must be integer");
+		  return retval;
+		}
+	    }
+
+	  FloatRowVector x (3);
+	  FloatRowVector y (3);
+
+	  for (int k = 1; k < nargin; k++)
+	    {
+	      FloatNDArray gnew = args(k).float_array_value ();
+
+	      v[k].resize(dv);
+
+	      for (int n = 0; n < nel; n++)
+		{
+		  x(0) = g(n);
+		  x(1) = 1;
+		  x(2) = 0;
+
+		  y(0) = std::abs (gnew(n));
+		  y(1) = 0;
+		  y(2) = 1; 
+
+		  if (! is_integer_value (y(0)))
+		    {
+		      error ("gcd: all arguments must be integer");
+		      return retval;
+		    }
+
+		  while (y(0) > 0)
+		    {
+		      FloatRowVector r = x - y * std::floor (x(0) / y(0));
+		      x = y;
+		      y = r;
+		    }
+
+		  g(n) = x(0);
+
+		  for (int i = 0; i < k; i++) 
+		    v[i](n) *= x(1);
+
+		  v[k](n) = x(2) * signum (gnew(n));
+		}
+	    }
+
+	  for (int k = 0; k < nargin; k++)
+	    retval(1+k) = v[k];
+
+	  retval (0) = g;
+	}
+    }
+  else if (nargin == 1)
+    {
+      NDArray gg = args(0).array_value ();
+
+      int nel = dv.numel ();
+
+      NDArray v (dv);
+
+      RowVector x (3);
+      RowVector y (3);
+
+      double g = std::abs (gg(0));
+
+      if (! is_integer_value (g))
+	{
+	  error ("gcd: all arguments must be integer");
+	  return retval;
+	}
+
+      v(0) = signum (gg(0));
+      
+      for (int k = 1; k < nel; k++)
+	{
+	  x(0) = g;
+	  x(1) = 1;
+	  x(2) = 0;
+
+	  y(0) = std::abs (gg(k));
+	  y(1) = 0;
+	  y(2) = 1;
+
+	  if (! is_integer_value (y(0)))
+	    {
+	      error ("gcd: all arguments must be integer");
+	      return retval;
+	    }
+
+	  while (y(0) > 0)
+	    {
+	      RowVector r = x - y * std::floor (x(0) / y(0));
+	      x = y;
+	      y = r;
+	    }
+
+	  g = x(0);
+
+	  for (int i = 0; i < k; i++) 
+	    v(i) *= x(1);
+
+	  v(k) = x(2) * signum (gg(k));
+	}
+
+      retval (1) = v;
+      retval (0) = g;
+    }
+  else if (all_args_scalar && nargout < 3)
+    {
+      double g = args(0).double_value ();
+
+      if (error_state || ! is_integer_value (g))
+	{
+	  error ("gcd: all arguments must be integer");
+	  return retval;
+	}
+
+      RowVector v (nargin, 0);
+      RowVector x (3);
+      RowVector y (3);
+
+      v(0) = signum (g);
+
+      g = std::abs(g);
+      
+      for (int k = 1; k < nargin; k++)
+	{
+	  x(0) = g;
+	  x(1) = 1;
+	  x(2) = 0;
+
+	  y(0) = args(k).double_value ();
+	  y(1) = 0;
+	  y(2) = 1;
+
+	  double sgn = signum (y(0));
+
+	  y(0) = std::abs (y(0));
+
+	  if (error_state || ! is_integer_value (g))
+	    {
+	      error ("gcd: all arguments must be integer");
+	      return retval;
+	    }
+
+	  while (y(0) > 0)
+	    {
+	      RowVector r = x - y * std::floor (x(0) / y(0));
+	      x = y;
+	      y = r;
+	    }
+
+	  g = x(0);
+
+	  for (int i = 0; i < k; i++) 
+	    v(i) *= x(1);
+
+	  v(k) = x(2) * sgn;
+	}
+
+      retval (1) = v;
+      retval (0) = g;
+    }
+  else
+    {
+      // FIXME -- we need to handle a possible mixture of scalar and
+      // array values here.
+
+      NDArray g = args(0).array_value ();
+
+      OCTAVE_LOCAL_BUFFER (NDArray, v, nargin);
+
+      int nel = dv.numel ();
+
+      v[0].resize(dv);
+
+      for (int i = 0; i < nel; i++)
+	{
+	  v[0](i) = signum (g(i));
+	  g(i) = std::abs (g(i));
+
+	  if (! is_integer_value (g(i)))
+	    {
+	      error ("gcd: all arguments must be integer");
+	      return retval;
+	    }
+	}
+
+      RowVector x (3);
+      RowVector y (3);
+
+      for (int k = 1; k < nargin; k++)
+	{
+	  NDArray gnew = args(k).array_value ();
+
+	  v[k].resize(dv);
+
+	  for (int n = 0; n < nel; n++)
+	    {
+	      x(0) = g(n);
+	      x(1) = 1;
+	      x(2) = 0;
+
+	      y(0) = std::abs (gnew(n));
+	      y(1) = 0;
+	      y(2) = 1; 
+
+	      if (! is_integer_value (y(0)))
+		{
+		  error ("gcd: all arguments must be integer");
+		  return retval;
+		}
+
+	      while (y(0) > 0)
+		{
+		  RowVector r = x - y * std::floor (x(0) / y(0));
+		  x = y;
+		  y = r;
+		}
+
+	      g(n) = x(0);
+
+	      for (int i = 0; i < k; i++) 
+		v[i](n) *= x(1);
+
+	      v[k](n) = x(2) * signum (gnew(n));
+	    }
+	}
+
+      for (int k = 0; k < nargin; k++)
+	retval(1+k) = v[k];
+
+      retval (0) = g;
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(gcd (200, 300, 50, 35), gcd ([200, 300, 50, 35]))
+%!assert(gcd ([200, 300, 50, 35]), 5);
+%!assert(gcd (single(200), single(300), single(50), single(35)), gcd (single([200, 300, 50, 35])))
+%!assert(gcd (single([200, 300, 50, 35])), single(5));
+
+%!error <Invalid call to gcd.*> gcd ();
+
+%!test
+%! s.a = 1;
+%! fail("gcd (s)");
+
+ */
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/getgrent.cc b/src/DLD-FUNCTIONS/getgrent.cc
new file mode 100644
index 0000000..2f46309
--- /dev/null
+++ b/src/DLD-FUNCTIONS/getgrent.cc
@@ -0,0 +1,224 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "oct-group.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "ov.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+// Group file functions.  (Why not?)
+
+static octave_value
+mk_gr_map (const octave_group& gr)
+{
+  octave_value retval;
+
+  if (gr)
+    {
+      Octave_map m;
+
+      m.assign ("name", gr.name ());
+      m.assign ("passwd", gr.passwd ());
+      m.assign ("gid", static_cast<double> (gr.gid ()));
+      m.assign ("mem", octave_value (gr.mem ()));
+
+      retval = m;
+    }
+  else
+    retval = 0;
+
+  return retval;
+}
+
+DEFUN_DLD (getgrent, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrent ()\n\
+Return an entry from the group database, opening it if necessary.\n\
+Once the end of the data has been reached, @code{getgrent} returns 0.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = 0;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = mk_gr_map (octave_group::getgrent (msg));
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (getgrgid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrgid (@var{gid}).\n\
+Return the first entry from the group database with the group ID\n\
+ at var{gid}.  If the group ID does not exist in the database,\n\
+ at code{getgrgid} returns 0.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = 0;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      double dval = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  if (D_NINT (dval) == dval)
+	    {
+	      gid_t gid = static_cast<gid_t> (dval);
+
+	      std::string msg;
+
+	      retval(0) = mk_gr_map (octave_group::getgrgid (gid, msg));
+	      retval(1) = msg;
+	    }
+	  else
+	    error ("getgrgid: argument must be an integer");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (getgrnam, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrnam (@var{name})\n\
+Return the first entry from the group database with the group name\n\
+ at var{name}.  If the group name does not exist in the database,\n\
+ at code{getgrnam} returns 0.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = 0;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string s = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string msg;
+
+	  retval(0) = mk_gr_map (octave_group::getgrnam (s.c_str (), msg));
+	  retval(1) = msg;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (setgrent, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} setgrent ()\n\
+Return the internal pointer to the beginning of the group database.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = static_cast<double> (octave_group::setgrent (msg));
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (endgrent, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} endgrent ()\n\
+Close the group database.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = static_cast<double> (octave_group::endgrent (msg));
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/getpwent.cc b/src/DLD-FUNCTIONS/getpwent.cc
new file mode 100644
index 0000000..6dc9972
--- /dev/null
+++ b/src/DLD-FUNCTIONS/getpwent.cc
@@ -0,0 +1,228 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "oct-passwd.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "ov.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+// Password file functions.  (Why not?)
+
+static octave_value
+mk_pw_map (const octave_passwd& pw)
+{
+  octave_value retval;
+
+  if (pw)
+    {
+      Octave_map m;
+
+      m.assign ("name", pw.name ());
+      m.assign ("passwd", pw.passwd ());
+      m.assign ("uid", static_cast<double> (pw.uid ()));
+      m.assign ("gid", static_cast<double> (pw.gid ()));
+      m.assign ("gecos", pw.gecos ());
+      m.assign ("dir", pw.dir ());
+      m.assign ("shell", pw.shell ());
+
+      retval = m;
+    }
+  else
+    retval = 0;
+
+  return retval;
+}
+
+DEFUN_DLD (getpwent, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwent ()\n\
+Return a structure containing an entry from the password database,\n\
+opening it if necessary.  Once the end of the data has been reached,\n\
+ at code{getpwent} returns 0.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = 0;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = mk_pw_map (octave_passwd::getpwent (msg));
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (getpwuid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwuid (@var{uid}).\n\
+Return a structure containing the first entry from the password database\n\
+with the user ID @var{uid}.  If the user ID does not exist in the\n\
+database, @code{getpwuid} returns 0.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = 0;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      double dval = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  if (D_NINT (dval) == dval)
+	    {
+	      uid_t uid = static_cast<uid_t> (dval);
+
+	      std::string msg;
+
+	      retval(0) = mk_pw_map (octave_passwd::getpwuid (uid, msg));
+	      retval(1) = msg;
+	    }
+	  else
+	    error ("getpwuid: argument must be an integer");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (getpwnam, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwnam (@var{name})\n\
+Return a structure containing the first entry from the password database\n\
+with the user name @var{name}.  If the user name does not exist in the\n\
+database, @code{getpwname} returns 0.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = 0.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string s = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string msg;
+
+	  retval(0) = mk_pw_map (octave_passwd::getpwnam (s, msg));
+	  retval(1) = msg;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (setpwent, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} setpwent ()\n\
+Return the internal pointer to the beginning of the password database.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = static_cast<double> (octave_passwd::setpwent (msg));
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (endpwent, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} endpwent ()\n\
+Close the password database.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = static_cast<double> (octave_passwd::endpwent (msg));
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/getrusage.cc b/src/DLD-FUNCTIONS/getrusage.cc
new file mode 100644
index 0000000..f978812
--- /dev/null
+++ b/src/DLD-FUNCTIONS/getrusage.cc
@@ -0,0 +1,255 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2002, 2003, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "systime.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#if defined (__WIN32__)
+#include <windows.h>
+#ifdef min
+#undef min
+#undef max
+#endif
+#endif
+
+#if defined (HAVE_TIMES) && defined (HAVE_SYS_TIMES_H)
+
+#if defined (HAVE_SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+#include <sys/times.h>
+
+#if !defined (HZ)
+#if defined (CLK_TCK)
+#define HZ CLK_TCK
+#elif defined (USG)
+#define HZ 100
+#else
+#define HZ 60
+#endif
+#endif
+
+#endif
+
+#include "defun-dld.h"
+#include "oct-map.h"
+#include "sysdep.h"
+#include "ov.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#ifndef RUSAGE_SELF
+#define RUSAGE_SELF 0
+#endif
+
+// System resource functions.
+
+DEFUN_DLD (getrusage, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} getrusage ()\n\
+Return a structure containing a number of statistics about the current\n\
+Octave process.  Not all fields are available on all systems.  If it is\n\
+not possible to get CPU time statistics, the CPU time slots are set to\n\
+zero.  Other missing data are replaced by NaN.  Here is a list of all\n\
+the possible fields that can be present in the structure returned by\n\
+ at code{getrusage}:\n\
+\n\
+ at table @code\n\
+ at item idrss\n\
+Unshared data size.\n\
+\n\
+ at item inblock\n\
+Number of block input operations.\n\
+\n\
+ at item isrss\n\
+Unshared stack size.\n\
+\n\
+ at item ixrss\n\
+Shared memory size.\n\
+\n\
+ at item majflt\n\
+Number of major page faults.\n\
+\n\
+ at item maxrss\n\
+Maximum data size.\n\
+\n\
+ at item minflt\n\
+Number of minor page faults.\n\
+\n\
+ at item msgrcv\n\
+Number of messages received.\n\
+\n\
+ at item msgsnd\n\
+Number of messages sent.\n\
+\n\
+ at item nivcsw\n\
+Number of involuntary context switches.\n\
+\n\
+ at item nsignals\n\
+Number of signals received.\n\
+\n\
+ at item nswap\n\
+Number of swaps.\n\
+\n\
+ at item nvcsw\n\
+Number of voluntary context switches.\n\
+\n\
+ at item oublock\n\
+Number of block output operations.\n\
+\n\
+ at item stime\n\
+A structure containing the system CPU time used.  The structure has the\n\
+elements @code{sec} (seconds) @code{usec} (microseconds).\n\
+\n\
+ at item utime\n\
+A structure containing the user CPU time used.  The structure has the\n\
+elements @code{sec} (seconds) @code{usec} (microseconds).\n\
+ at end table\n\
+ at end deftypefn")
+{
+  Octave_map m;
+  Octave_map tv_tmp;
+
+  // FIXME -- maybe encapsulate all of this in a liboctave class
+#if defined (HAVE_GETRUSAGE)
+
+  struct rusage ru;
+
+  getrusage (RUSAGE_SELF, &ru);
+
+  tv_tmp.assign ("sec", static_cast<double> (ru.ru_utime.tv_sec));
+  tv_tmp.assign ("usec", static_cast<double> (ru.ru_utime.tv_usec));
+  m.assign ("utime", octave_value (tv_tmp));
+
+  tv_tmp.assign ("sec", static_cast<double> (ru.ru_stime.tv_sec));
+  tv_tmp.assign ("usec", static_cast<double> (ru.ru_stime.tv_usec));
+  m.assign ("stime", octave_value (tv_tmp));
+
+#if ! defined (RUSAGE_TIMES_ONLY)
+  m.assign ("maxrss", static_cast<double> (ru.ru_maxrss));
+  m.assign ("ixrss", static_cast<double> (ru.ru_ixrss));
+  m.assign ("idrss", static_cast<double> (ru.ru_idrss));
+  m.assign ("isrss", static_cast<double> (ru.ru_isrss));
+  m.assign ("minflt", static_cast<double> (ru.ru_minflt));
+  m.assign ("majflt", static_cast<double> (ru.ru_majflt));
+  m.assign ("nswap", static_cast<double> (ru.ru_nswap));
+  m.assign ("inblock", static_cast<double> (ru.ru_inblock));
+  m.assign ("oublock", static_cast<double> (ru.ru_oublock));
+  m.assign ("msgsnd", static_cast<double> (ru.ru_msgsnd));
+  m.assign ("msgrcv", static_cast<double> (ru.ru_msgrcv));
+  m.assign ("nsignals", static_cast<double> (ru.ru_nsignals));
+  m.assign ("nvcsw", static_cast<double> (ru.ru_nvcsw));
+  m.assign ("nivcsw", static_cast<double> (ru.ru_nivcsw));
+#endif
+
+#else
+#if defined (HAVE_TIMES) && defined (HAVE_SYS_TIMES_H)
+
+  struct tms t;
+
+  times (&t);
+
+  unsigned long ticks;
+  unsigned long seconds;
+  unsigned long fraction;
+
+  ticks = t.tms_utime + t.tms_cutime;
+  fraction = ticks % HZ;
+  seconds = ticks / HZ;
+
+  tv_tmp.assign ("sec", static_cast<double> (seconds));
+  tv_tmp.assign ("usec", static_cast<double> (fraction * 1e6 / HZ));
+  m.assign ("utime", octave_value (tv_tmp));
+
+  ticks = t.tms_stime + t.tms_cstime;
+  fraction = ticks % HZ;
+  seconds = ticks / HZ;
+
+  tv_tmp.assign ("sec", static_cast<double> (seconds));
+  tv_tmp.assign ("usec", static_cast<double> (fraction * 1e6 / HZ));
+  m.assign ("stime", octave_value (tv_tmp));
+
+#elif defined (__WIN32__)
+  HANDLE hProcess = GetCurrentProcess ();
+  FILETIME ftCreation, ftExit, ftUser, ftKernel;
+  GetProcessTimes (hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
+
+  int64_t itmp = *(reinterpret_cast<int64_t *> (&ftUser));
+  tv_tmp.assign ("sec", static_cast<double> (itmp / 10000000U));
+  tv_tmp.assign ("usec", static_cast<double> (itmp % 10000000U) / 10.);
+  m.assign ("utime", octave_value (tv_tmp));
+
+  itmp = *(reinterpret_cast<int64_t *> (&ftKernel));
+  tv_tmp.assign ("sec", static_cast<double> (itmp / 10000000U));
+  tv_tmp.assign ("usec", static_cast<double> (itmp % 10000000U) / 10.);
+  m.assign ("stime", octave_value (tv_tmp));
+#else
+
+  tv_tmp.assign ("sec", 0);
+  tv_tmp.assign ("usec", 0);
+  m.assign ("utime", octave_value (tv_tmp));
+
+  tv_tmp.assign ("sec", 0);
+  tv_tmp.assign ("usec", 0);
+  m.assign ("stime", octave_value (tv_tmp));
+
+#endif
+
+  double tmp = lo_ieee_nan_value ();
+
+  m.assign ("maxrss", tmp);
+  m.assign ("ixrss", tmp);
+  m.assign ("idrss", tmp);
+  m.assign ("isrss", tmp);
+  m.assign ("minflt", tmp);
+  m.assign ("majflt", tmp);
+  m.assign ("nswap", tmp);
+  m.assign ("inblock", tmp);
+  m.assign ("oublock", tmp);
+  m.assign ("msgsnd", tmp);
+  m.assign ("msgrcv", tmp);
+  m.assign ("nsignals", tmp);
+  m.assign ("nvcsw", tmp);
+  m.assign ("nivcsw", tmp);
+
+#endif
+
+  return octave_value (m);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/givens.cc b/src/DLD-FUNCTIONS/givens.cc
new file mode 100644
index 0000000..cd5598b
--- /dev/null
+++ b/src/DLD-FUNCTIONS/givens.cc
@@ -0,0 +1,214 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Originally written by A. S. Hodel <scotte at eng.auburn.edu>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+DEFUN_DLD (givens, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{g} =} givens (@var{x}, @var{y})\n\
+ at deftypefnx {Loadable Function} {[@var{c}, @var{s}] =} givens (@var{x}, @var{y})\n\
+ at iftex\n\
+ at tex\n\
+Return a $2\\times 2$ orthogonal matrix\n\
+$$\n\
+ G = \\left[\\matrix{c & s\\cr -s'& c\\cr}\\right]\n\
+$$\n\
+such that\n\
+$$\n\
+ G \\left[\\matrix{x\\cr y}\\right] = \\left[\\matrix{\\ast\\cr 0}\\right]\n\
+$$\n\
+with $x$ and $y$ scalars.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+Return a 2 by 2 orthogonal matrix\n\
+ at code{@var{g} = [@var{c} @var{s}; - at var{s}' @var{c}]} such that\n\
+ at code{@var{g} [@var{x}; @var{y}] = [*; 0]} with @var{x} and @var{y} scalars.\n\
+ at end ifnottex\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+givens (1, 1)\n\
+     @result{}   0.70711   0.70711\n\
+         -0.70711   0.70711\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 2 || nargout > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+  else
+    {
+      if (args(0).is_single_type () || args(1).is_single_type ())
+	{
+	  if (args(0).is_complex_type () || args(1).is_complex_type ())
+	    {
+	      FloatComplex cx = args(0).float_complex_value ();
+	      FloatComplex cy = args(1).float_complex_value ();
+
+	      if (! error_state)
+		{
+		  FloatComplexMatrix result = Givens (cx, cy);
+
+		  if (! error_state)
+		    {
+		      switch (nargout)
+			{
+			case 0:
+			case 1:
+			  retval(0) = result;
+			  break;
+   
+			case 2:
+			  retval(1) = result (0, 1);
+			  retval(0) = result (0, 0);
+			  break;
+
+			default:
+			  error ("givens: invalid number of output arguments");
+			  break;
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      float x = args(0).float_value ();
+	      float y = args(1).float_value ();
+
+	      if (! error_state)
+		{
+		  FloatMatrix result = Givens (x, y);
+
+		  if (! error_state)
+		    {
+		      switch (nargout)
+			{
+			case 0:
+			case 1:
+			  retval(0) = result;
+			  break;
+   
+			case 2:
+			  retval(1) = result (0, 1);
+			  retval(0) = result (0, 0);
+			  break;
+
+			default:
+			  error ("givens: invalid number of output arguments");
+			  break;
+			}
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type () || args(1).is_complex_type ())
+	    {
+	      Complex cx = args(0).complex_value ();
+	      Complex cy = args(1).complex_value ();
+
+	      if (! error_state)
+		{
+		  ComplexMatrix result = Givens (cx, cy);
+
+		  if (! error_state)
+		    {
+		      switch (nargout)
+			{
+			case 0:
+			case 1:
+			  retval(0) = result;
+			  break;
+   
+			case 2:
+			  retval(1) = result (0, 1);
+			  retval(0) = result (0, 0);
+			  break;
+
+			default:
+			  error ("givens: invalid number of output arguments");
+			  break;
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      double x = args(0).double_value ();
+	      double y = args(1).double_value ();
+
+	      if (! error_state)
+		{
+		  Matrix result = Givens (x, y);
+
+		  if (! error_state)
+		    {
+		      switch (nargout)
+			{
+			case 0:
+			case 1:
+			  retval(0) = result;
+			  break;
+   
+			case 2:
+			  retval(1) = result (0, 1);
+			  retval(0) = result (0, 0);
+			  break;
+
+			default:
+			  error ("givens: invalid number of output arguments");
+			  break;
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/hess.cc b/src/DLD-FUNCTIONS/hess.cc
new file mode 100644
index 0000000..beeef72
--- /dev/null
+++ b/src/DLD-FUNCTIONS/hess.cc
@@ -0,0 +1,178 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxHESS.h"
+#include "dbleHESS.h"
+#include "fCmplxHESS.h"
+#include "floatHESS.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (hess, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{h} =} hess (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{p}, @var{h}] =} hess (@var{a})\n\
+ at cindex Hessenberg decomposition\n\
+Compute the Hessenberg decomposition of the matrix @var{a}.\n\
+\n\
+The Hessenberg decomposition is usually used as the first step in an\n\
+eigenvalue computation, but has other applications as well (see Golub,\n\
+Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).  The\n\
+Hessenberg decomposition is\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+A = PHP^T\n\
+$$\n\
+where $P$ is a square unitary matrix ($P^HP = I$), and $H$\n\
+is upper Hessenberg ($H_{i,j} = 0, \\forall i \\ge j+1$).\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{p * h * p' = a} where @code{p} is a square unitary matrix\n\
+(@code{p' * p = I}, using complex-conjugate transposition) and @code{h}\n\
+is upper Hessenberg (@code{i >= j+1 => h (i, j) = 0}).\n\
+ at end ifnottex\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 1 || nargout > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  int arg_is_empty = empty_arg ("hess", nr, nc);
+
+  if (arg_is_empty < 0)
+    return retval;
+  else if (arg_is_empty > 0)
+    return octave_value_list (2, Matrix ());
+
+  if (nr != nc)
+    {
+      gripe_square_matrix_required ("hess");
+      return retval;
+    }
+
+  if (arg.is_single_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	 FloatMatrix tmp = arg.float_matrix_value ();
+
+	  if (! error_state)
+	    {
+	      FloatHESS result (tmp);
+
+	      retval(1) = result.hess_matrix ();
+	      retval(0) = result.unitary_hess_matrix ();
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  FloatComplexMatrix ctmp = arg.float_complex_matrix_value ();
+
+	  if (! error_state)
+	    {
+	      FloatComplexHESS result (ctmp);
+
+	      retval(1) = result.hess_matrix ();
+	      retval(0) = result.unitary_hess_matrix ();
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  Matrix tmp = arg.matrix_value ();
+
+	  if (! error_state)
+	    {
+	      HESS result (tmp);
+
+	      retval(1) = result.hess_matrix ();
+	      retval(0) = result.unitary_hess_matrix ();
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  ComplexMatrix ctmp = arg.complex_matrix_value ();
+
+	  if (! error_state)
+	    {
+	      ComplexHESS result (ctmp);
+
+	      retval(1) = result.hess_matrix ();
+	      retval(0) = result.unitary_hess_matrix ();
+	    }
+	}
+      else
+	{
+	  gripe_wrong_type_arg ("hess", arg);
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = [1, 2, 3; 5, 4, 6; 8, 7, 9];
+%! [p, h] = hess (a);
+%! assert(p * h * p', a, sqrt(eps));
+
+%!test
+%! a = single([1, 2, 3; 5, 4, 6; 8, 7, 9]);
+%! [p, h] = hess (a);
+%! assert(p * h * p', a, sqrt(eps ('single')));
+
+%!error <Invalid call to hess.*> hess ();
+%!error <Invalid call to hess.*> hess ([1, 2; 3, 4], 2);
+%!error hess ([1, 2; 3, 4; 5, 6]);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/hex2num.cc b/src/DLD-FUNCTIONS/hex2num.cc
new file mode 100644
index 0000000..2cb7bfa
--- /dev/null
+++ b/src/DLD-FUNCTIONS/hex2num.cc
@@ -0,0 +1,190 @@
+/*
+
+Copyright (C) 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (hex2num, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{n} =} hex2num (@var{s})\n\
+Typecast the 16 character hexadecimal character matrix to an IEEE 754\n\
+double precision number.  If fewer than 16 characters are given the\n\
+strings are right padded with '0' characters.\n\
+\n\
+Given a string matrix, @code{hex2num} treats each row as a separate\n\
+number.\n\
+\n\
+ at example\n\
+ at group\n\
+hex2num ([\"4005bf0a8b145769\";\"4024000000000000\"])\n\
+ at result{} [2.7183; 10.000]\n\
+ at end group\n\
+ at end example\n\
+ at seealso{num2hex, hex2dec, dec2hex}\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      const charMatrix cmat = args(0).char_matrix_value ();
+
+      if (cmat.columns () > 16)
+	error ("hex2num: expecting no more than a 16 character string");
+      else if (! error_state)
+	{
+	  octave_idx_type nr = cmat.rows ();
+	  octave_idx_type nc = cmat.columns ();
+	  ColumnVector m (nr);
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      union
+	      {
+		uint64_t ival;
+		double dval;
+	      } num;
+
+	      for (octave_idx_type j = 0; j < nc; j++)
+		{
+		  unsigned char ch = cmat.elem (i, j);
+
+		  if (isxdigit (ch))
+		    {
+		      num.ival <<= 4;
+		      if (ch >= 'a')
+			num.ival += static_cast<uint64_t> (ch - 'a' + 10);
+		      else if (ch >= 'A')
+			num.ival += static_cast<uint64_t> (ch - 'A' + 10);
+		      else
+			num.ival += static_cast<uint64_t> (ch - '0');
+		    }
+		  else
+		    {
+		      error ("hex2num: illegal character found in string");
+		      break;
+		    }
+		}
+
+	      if (error_state)
+		break;
+	      else
+		{
+		  if (nc < 16)
+		    num.ival <<= (16 - nc) * 4;
+
+		  m(i) = num.dval;
+		}
+	    }
+
+	  if (! error_state)
+	    retval =  m;
+	}
+    }
+
+  return retval;
+}
+
+/*
+%!assert (hex2num(['c00';'bff';'000';'3ff';'400']),[-2:2]')
+*/
+
+DEFUN_DLD (num2hex, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{s} =} num2hex (@var{n})\n\
+Typecast a double precision number or vector to a 16 character hexadecimal\n\
+string of the IEEE 754 representation of the number.  For example\n\
+\n\
+ at example\n\
+ at group\n\
+num2hex ([-1, 1, e, Inf, NaN, NA]);\n\
+ at result{} \"bff0000000000000\n\
+    3ff0000000000000\n\
+    4005bf0a8b145769\n\
+    7ff0000000000000\n\
+    fff8000000000000\n\
+    7ff00000000007a2\"\n\
+ at end group\n\
+ at end example\n\
+ at seealso{hex2num, hex2dec, dec2hex}\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      const ColumnVector v (args(0).vector_value ());
+
+      if (! error_state)
+	{
+	  octave_idx_type nr = v.length ();
+	  charMatrix m (nr, 16);
+	  const double *pv = v.fortran_vec ();
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      union
+	      {
+		uint64_t ival;
+		double dval;
+	      } num;
+
+	      num.dval = *pv++;
+
+	      for (octave_idx_type j = 0; j < 16; j++)
+		{
+		  unsigned char ch = 
+		    static_cast<char> (num.ival >> ((15 - j) * 4) & 0xF);
+		  if (ch >= 10)
+		    ch += 'a' - 10;
+		  else
+		    ch += '0';
+
+		  m.elem (i, j) = ch;
+		}
+	    }
+	  
+	  retval = octave_value (m, true);
+	}
+    }
+
+  return retval;
+}
+
+/*
+%!assert (num2hex (-2:2),['c000000000000000';'bff0000000000000';'0000000000000000';'3ff0000000000000';'4000000000000000'])
+*/
diff --git a/src/DLD-FUNCTIONS/inv.cc b/src/DLD-FUNCTIONS/inv.cc
new file mode 100644
index 0000000..36ccda2
--- /dev/null
+++ b/src/DLD-FUNCTIONS/inv.cc
@@ -0,0 +1,250 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ops.h"
+#include "ov-re-diag.h"
+#include "ov-cx-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-perm.h"
+#include "utils.h"
+
+DEFUN_DLD (inv, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inv (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{x}, @var{rcond}] =} inverse (@var{a})\n\
+Compute the inverse of the square matrix @var{a}.  Return an estimate\n\
+of the reciprocal condition number if requested, otherwise warn of an\n\
+ill-conditioned matrix if the reciprocal condition number is small.\n\
+\n\
+If called with a sparse matrix, then in general @var{x} will be a full\n\
+matrix, and so if possible forming the inverse of a sparse matrix should\n\
+be avoided.  It is significantly more accurate and faster to do\n\
+ at code{@var{y} = @var{a} \\ @var{b}}, rather than\n\
+ at code{@var{y} = inv (@var{a}) * @var{b}}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  int arg_is_empty = empty_arg ("inverse", nr, nc);
+
+  if (arg_is_empty < 0)
+    return retval;
+  else if (arg_is_empty > 0)
+    return octave_value (Matrix ());
+
+  if (nr != nc)
+    {
+      gripe_square_matrix_required ("inverse");
+      return retval;
+    }
+
+  octave_value result;
+  octave_idx_type info;
+  double rcond = 0.0;
+  float frcond = 0.0;
+  bool isfloat = arg.is_single_type ();
+
+  if (arg.is_diag_matrix ())
+    {
+      rcond = 1.0;
+      frcond = 1.0f;
+      if (arg.is_complex_type ())
+        {
+          if (isfloat)
+            {
+              result = arg.float_complex_diag_matrix_value ().inverse (info);
+              if (nargout > 1)
+                frcond = arg.float_complex_diag_matrix_value ().rcond ();
+            }
+          else
+            {
+              result = arg.complex_diag_matrix_value ().inverse (info);
+              if (nargout > 1)
+                rcond = arg.complex_diag_matrix_value ().rcond ();
+            }
+        }
+      else
+        {
+          if (isfloat)
+            {
+              result = arg.float_diag_matrix_value ().inverse (info);
+              if (nargout > 1)
+                frcond = arg.float_diag_matrix_value ().rcond ();
+            }
+          else
+            {
+              result = arg.diag_matrix_value ().inverse (info);
+              if (nargout > 1)
+                rcond = arg.diag_matrix_value ().rcond ();
+            }
+        }
+    }
+  else if (arg.is_perm_matrix ())
+    {
+      rcond = 1.0;
+      info = 0;
+      result = arg.perm_matrix_value ().inverse ();
+    }
+  else if (isfloat)
+    {
+      if (arg.is_real_type ())
+	{
+	  FloatMatrix m = arg.float_matrix_value ();
+	  if (! error_state)
+	    {
+	      MatrixType mattyp = args(0).matrix_type ();
+	      result = m.inverse (mattyp, info, frcond, 1);
+	      args(0).matrix_type (mattyp);
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  FloatComplexMatrix m = arg.float_complex_matrix_value ();
+	  if (! error_state)
+	    {
+	      MatrixType mattyp = args(0).matrix_type ();
+	      result = m.inverse (mattyp, info, frcond, 1);
+	      args(0).matrix_type (mattyp);
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  if (arg.is_sparse_type ())
+	    {
+	      SparseMatrix m = arg.sparse_matrix_value ();
+	      if (! error_state)
+		{
+		  MatrixType mattyp = args(0).matrix_type ();
+		  result = m.inverse (mattyp, info, rcond, 1);
+		  args(0).matrix_type (mattyp);
+		}
+	    }
+	  else
+	    {
+	      Matrix m = arg.matrix_value ();
+	      if (! error_state)
+		{
+		  MatrixType mattyp = args(0).matrix_type ();
+		  result = m.inverse (mattyp, info, rcond, 1);
+		  args(0).matrix_type (mattyp);
+		}
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  if (arg.is_sparse_type ())
+	    {
+	      SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+	      if (! error_state)
+		{
+		  MatrixType mattyp = args(0).matrix_type ();
+		  result = m.inverse (mattyp, info, rcond, 1);
+		  args(0).matrix_type (mattyp);
+		}
+	    }
+	  else
+	    {
+	      ComplexMatrix m = arg.complex_matrix_value ();
+	      if (! error_state)
+		{
+		  MatrixType mattyp = args(0).matrix_type ();
+		  result = m.inverse (mattyp, info, rcond, 1);
+		  args(0).matrix_type (mattyp);
+		}
+	    }
+	}
+      else
+	gripe_wrong_type_arg ("inv", arg);
+    }
+
+  if (! error_state)
+    {
+      if (nargout > 1)
+	retval(1) = isfloat ? octave_value (frcond) : octave_value (rcond);
+
+      retval(0) = result;
+
+      volatile double xrcond = rcond;
+      xrcond += 1.0;
+      if (nargout < 2 && (info == -1 || xrcond == 1.0))
+	warning ("inverse: matrix singular to machine precision, rcond = %g", 
+		 rcond);
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(inv ([1, 2; 3, 4]), [-2, 1; 1.5, -0.5], sqrt (eps))
+%!assert(inv (single([1, 2; 3, 4])), single([-2, 1; 1.5, -0.5]), sqrt (eps ('single')))
+
+%!error <Invalid call to inv.*> inv ();
+%!error <Invalid call to inv.*> inv ([1, 2; 3, 4], 2);
+%!error inv ([1, 2; 3, 4; 5, 6]);
+
+ */
+
+// FIXME -- this should really be done with an alias, but
+// alias_builtin() won't do the right thing if we are actually using
+// dynamic linking.
+
+DEFUN_DLD (inverse, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} inverse (@var{a})\n\
+See inv.\n\
+ at end deftypefn")
+{
+  return Finv (args, nargout);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/kron.cc b/src/DLD-FUNCTIONS/kron.cc
new file mode 100644
index 0000000..b6ed1e6
--- /dev/null
+++ b/src/DLD-FUNCTIONS/kron.cc
@@ -0,0 +1,244 @@
+/*
+
+Copyright (C) 2002, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Paul Kienzle <pkienzle at users.sf.net>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dMatrix.h"
+#include "CMatrix.h"
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern void
+kron (const Array2<double>&, const Array2<double>&, Array2<double>&);
+
+extern void
+kron (const Array2<Complex>&, const Array2<Complex>&, Array2<Complex>&);
+
+extern void
+kron (const Array2<float>&, const Array2<float>&, Array2<float>&);
+
+extern void
+kron (const Array2<FlaotComplex>&, const Array2<FloatComplex>&, 
+      Array2<FloatComplex>&);
+#endif
+
+template <class T>
+void
+kron (const Array2<T>& A, const Array2<T>& B, Array2<T>& C)
+{
+  C.resize (A.rows () * B.rows (), A.columns () * B.columns ());
+
+  octave_idx_type Ac, Ar, Cc, Cr;
+
+  for (Ac = Cc = 0; Ac < A.columns (); Ac++, Cc += B.columns ())
+    for (Ar = Cr = 0; Ar < A.rows (); Ar++, Cr += B.rows ())
+      {
+	const T v = A (Ar, Ac);
+	for (octave_idx_type Bc = 0; Bc < B.columns (); Bc++)
+	  for (octave_idx_type Br = 0; Br < B.rows (); Br++)
+	    {
+	      OCTAVE_QUIT;
+	      C.xelem (Cr+Br, Cc+Bc) = v * B.elem (Br, Bc);
+	    }
+      }
+}
+
+template void
+kron (const Array2<double>&, const Array2<double>&, Array2<double>&);
+
+template void
+kron (const Array2<Complex>&, const Array2<Complex>&, Array2<Complex>&);
+
+template void
+kron (const Array2<float>&, const Array2<float>&, Array2<float>&);
+
+template void
+kron (const Array2<FloatComplex>&, const Array2<FloatComplex>&, 
+      Array2<FloatComplex>&);
+
+#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
+extern void
+kron (const Sparse<double>&, const Sparse<double>&, Sparse<double>&);
+
+extern void
+kron (const Sparse<Complex>&, const Sparse<Complex>&, Sparse<Complex>&);
+#endif
+
+template <class T>
+void
+kron (const Sparse<T>& A, const Sparse<T>& B, Sparse<T>& C)
+{
+  octave_idx_type idx = 0;
+  C = Sparse<T> (A.rows () * B.rows (), A.columns () * B.columns (), 
+		 A.nzmax () * B.nzmax ());
+
+  C.cidx (0) = 0;
+
+  for (octave_idx_type Aj = 0; Aj < A.columns (); Aj++)
+    for (octave_idx_type Bj = 0; Bj < B.columns (); Bj++)
+      {
+	for (octave_idx_type Ai = A.cidx (Aj); Ai < A.cidx (Aj+1); Ai++)
+	  {
+	    octave_idx_type Ci = A.ridx(Ai) * B.rows ();
+	    const T v = A.data (Ai);
+
+	    for (octave_idx_type Bi = B.cidx (Bj); Bi < B.cidx (Bj+1); Bi++)
+	      {
+		OCTAVE_QUIT;
+		C.data (idx) = v * B.data (Bi);
+		C.ridx (idx++) = Ci + B.ridx (Bi);
+	      }
+	  }
+	C.cidx (Aj * B.columns () + Bj + 1) = idx;
+      }
+}
+
+template void
+kron (const Sparse<double>&, const Sparse<double>&, Sparse<double>&);
+
+template void
+kron (const Sparse<Complex>&, const Sparse<Complex>&, Sparse<Complex>&);
+
+
+DEFUN_DLD (kron, args, nargout, "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} kron (@var{a}, @var{b})\n\
+Form the kronecker product of two matrices, defined block by block as\n\
+\n\
+ at example\n\
+x = [a(i, j) b]\n\
+ at end example\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+kron (1:4, ones (3, 1))\n\
+      @result{}  1  2  3  4\n\
+          1  2  3  4\n\
+          1  2  3  4\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 2 || nargout > 1)
+    {
+      print_usage ();
+    }
+  else if (args(0).is_sparse_type () || args(1).is_sparse_type ())
+    {
+      if (args(0).is_complex_type () || args(1).is_complex_type ())
+	{
+	  SparseComplexMatrix a (args(0).sparse_complex_matrix_value());
+	  SparseComplexMatrix b (args(1).sparse_complex_matrix_value());
+
+	  if (! error_state)
+	    {
+	      SparseComplexMatrix c;
+	      kron (a, b, c);
+	      retval(0) = c;
+	    }
+	}
+      else
+	{
+	  SparseMatrix a (args(0).sparse_matrix_value ());
+	  SparseMatrix b (args(1).sparse_matrix_value ());
+
+	  if (! error_state)
+	    {
+	      SparseMatrix c;
+	      kron (a, b, c);
+	      retval (0) = c;
+	    }
+	}
+    }
+  else 
+    {
+      if (args(0).is_single_type () || args(1).is_single_type ())
+	{
+	  if (args(0).is_complex_type () || args(1).is_complex_type ())
+	    {
+	      FloatComplexMatrix a (args(0).float_complex_matrix_value());
+	      FloatComplexMatrix b (args(1).float_complex_matrix_value());
+
+	      if (! error_state)
+		{
+		  FloatComplexMatrix c;
+		  kron (a, b, c);
+		  retval(0) = c;
+		}
+	    }
+	  else
+	    {
+	      FloatMatrix a (args(0).float_matrix_value ());
+	      FloatMatrix b (args(1).float_matrix_value ());
+
+	      if (! error_state)
+		{
+		  FloatMatrix c;
+		  kron (a, b, c);
+		  retval (0) = c;
+		}
+	    }
+	}
+      else
+	{
+	  if (args(0).is_complex_type () || args(1).is_complex_type ())
+	    {
+	      ComplexMatrix a (args(0).complex_matrix_value());
+	      ComplexMatrix b (args(1).complex_matrix_value());
+
+	      if (! error_state)
+		{
+		  ComplexMatrix c;
+		  kron (a, b, c);
+		  retval(0) = c;
+		}
+	    }
+	  else
+	    {
+	      Matrix a (args(0).matrix_value ());
+	      Matrix b (args(1).matrix_value ());
+
+	      if (! error_state)
+		{
+		  Matrix c;
+		  kron (a, b, c);
+		  retval (0) = c;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/lookup.cc b/src/DLD-FUNCTIONS/lookup.cc
new file mode 100644
index 0000000..b24a24a
--- /dev/null
+++ b/src/DLD-FUNCTIONS/lookup.cc
@@ -0,0 +1,281 @@
+/*
+
+Copyright (C) 2008, 2009 VZLU Prague a.s., Czech Republic
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Jaroslav Hajek <highegg at gmail.com>
+
+#include <cctype>
+#include <functional>
+#include <algorithm>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dNDArray.h"
+#include "CNDArray.h"
+
+#include "Cell.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+
+static
+bool
+contains_char (const std::string& str, char c)
+{
+  return (str.find (c) != std::string::npos 
+	  || str.find (std::toupper (c)) != std::string::npos);
+}
+
+// case-insensitive character comparison functors
+struct icmp_char_lt : public std::binary_function<char, char, bool>
+{
+  bool operator () (char x, char y) const
+    { return std::toupper (x) < std::toupper (y); }
+};
+
+struct icmp_char_gt : public std::binary_function<char, char, bool>
+{
+  bool operator () (char x, char y) const
+    { return std::toupper (x) > std::toupper (y); }
+};
+
+// FIXME: maybe these should go elsewhere?
+// case-insensitive ascending comparator
+static bool
+stri_comp_lt (const std::string& a, const std::string& b)
+{
+  return std::lexicographical_compare (a.begin (), a.end (), 
+                                       b.begin (), b.end (),
+                                       icmp_char_lt());
+}
+
+// case-insensitive descending comparator
+static bool
+stri_comp_gt (const std::string& a, const std::string& b)
+{
+  return std::lexicographical_compare (a.begin (), a.end (), 
+                                       b.begin (), b.end (),
+                                       icmp_char_gt());
+}
+
+template <class T>
+inline sortmode 
+get_sort_mode (const Array<T>& array,
+               typename octave_sort<T>::compare_fcn_type desc_comp
+               = octave_sort<T>::descending_compare)
+{
+  octave_idx_type n = array.numel ();
+  if (n > 1 && desc_comp (array (0), array (n-1)))
+    return DESCENDING;
+  else
+    return ASCENDING;
+}
+
+// FIXME: perhaps there should be octave_value::lookup?
+// The question is, how should it behave w.r.t. the second argument's type. 
+// We'd need a dispatch on two arguments. Hmmm...
+
+#define INT_ARRAY_LOOKUP(TYPE) \
+  (table.is_ ## TYPE ## _type () && y.is_ ## TYPE ## _type ()) \
+    idx = table.TYPE ## _array_value ().lookup (y.TYPE ## _array_value (), \
+                                                UNSORTED, left_inf, right_inf);
+
+DEFUN_DLD (lookup, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{idx} =} lookup (@var{table}, @var{y}, @var{opt})\n\
+Lookup values in a sorted table.  Usually used as a prelude to\n\
+interpolation.\n\
+\n\
+If table is strictly increasing and @code{idx = lookup (table, y)}, then\n\
+ at code{table(idx(i)) <= y(i) < table(idx(i+1))} for all @code{y(i)}\n\
+within the table.  If @code{y(i) < table (1)} then\n\
+ at code{idx(i)} is 0. If @code{y(i) >= table(end)} then\n\
+ at code{idx(i)} is @code{table(n)}.\n\
+\n\
+If the table is strictly decreasing, then the tests are reversed.\n\
+There are no guarantees for tables which are non-monotonic or are not\n\
+strictly monotonic.\n\
+\n\
+The algorithm used by lookup is standard binary search, with optimizations\n\
+to speed up the case of partially ordered arrays (dense downsampling).\n\
+In particular, looking up a single entry is of logarithmic complexity\n\
+(unless a conversion occurs due to non-numeric or unequal types).\n\
+\n\
+ at var{table} and @var{y} can also be cell arrays of strings\n\
+(or @var{y} can be a single string).  In this case, string lookup\n\
+is performed using lexicographical comparison.\n\
+\n\
+If @var{opts} is specified, it shall be a string with letters indicating\n\
+additional options.\n\
+For numeric lookup, 'l' in @var{opts} indicates that\n\
+the leftmost subinterval shall be extended to infinity (i.e., all indices\n\
+at least 1), and 'r' indicates that the rightmost subinterval shall be\n\
+extended to infinity (i.e., all indices at most n-1).\n\
+\n\
+For string lookup, 'i' indicates case-insensitive comparison.\n\
+ at end deftypefn") 
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 2 || nargin > 3 || (nargin == 3 && ! args(2).is_string ()))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value table = args(0), y = args(1);
+  if (table.ndims () > 2 || (table.columns () > 1 && table.rows () > 1))
+    warning ("lookup: table is not a vector");
+
+  bool num_case = table.is_numeric_type () && y.is_numeric_type ();
+  bool str_case = table.is_cellstr () && (y.is_string () || y.is_cellstr ());
+
+  if (num_case) 
+    {
+      bool left_inf = false;
+      bool right_inf = false;
+
+      if (nargin == 3)
+        {
+          std::string opt = args(2).string_value ();
+          left_inf = contains_char (opt, 'l');
+          right_inf = contains_char (opt, 'r');
+        }
+
+      // In the case of a complex array, absolute values will be used for compatibility
+      // (though it's not too meaningful).
+      
+      if (table.is_complex_type ())
+        table = table.abs ();
+
+      if (y.is_complex_type ())
+        y = y.abs ();
+
+      Array<octave_idx_type> idx;
+
+      // PS: I learned this from data.cc
+      if INT_ARRAY_LOOKUP (int8)
+      else if INT_ARRAY_LOOKUP (int16)
+      else if INT_ARRAY_LOOKUP (int32)
+      else if INT_ARRAY_LOOKUP (int64)
+      else if INT_ARRAY_LOOKUP (uint8)
+      else if INT_ARRAY_LOOKUP (uint16)
+      else if INT_ARRAY_LOOKUP (uint32)
+      else if INT_ARRAY_LOOKUP (uint64)
+      else if (table.is_single_type () || y.is_single_type ())
+        idx = table.float_array_value ().lookup (y.float_array_value (), 
+                                                 UNSORTED, left_inf, right_inf);
+      else
+        idx = table.array_value ().lookup (y.array_value (), 
+                                           UNSORTED, left_inf, right_inf);
+
+      retval(0) = NDArray (idx);
+
+    }
+  else if (str_case)
+    {
+      Array<std::string> str_table = table.cellstr_value ();
+      
+      // Here we'll use octave_sort directly to avoid converting the array
+      // for case-insensitive comparison.
+
+      bool icase = false;
+
+      // check for case-insensitive option
+      if (nargin == 3)
+        {
+          std::string opt = args(2).string_value ();
+          icase = contains_char (opt, 'i');
+        }
+
+      sortmode mode = (icase ? get_sort_mode (str_table, stri_comp_gt)
+                       : get_sort_mode (str_table));
+
+      bool (*str_comp) (const std::string&, const std::string&);
+
+      // pick the correct comparator
+      if (mode == DESCENDING)
+        str_comp = icase ? stri_comp_gt : octave_sort<std::string>::descending_compare;
+      else
+        str_comp = icase ? stri_comp_lt : octave_sort<std::string>::ascending_compare;
+
+      octave_sort<std::string> lsort (str_comp);
+      if (y.is_cellstr ())
+        {
+          Array<std::string> str_y = y.cellstr_value ();
+
+          Array<octave_idx_type> idx (str_y.dims ());
+
+          lsort.lookup (str_table.data (), str_table.nelem (), str_y.data (),
+                        str_y.nelem (), idx.fortran_vec ());
+
+          retval(0) = NDArray (idx);
+        }
+      else if (y.is_string ())
+        {
+          std::string str_y = y.string_value ();
+
+          octave_idx_type idx;
+
+          lsort.lookup (str_table.data (), str_table.nelem (), &str_y,
+                        1, &idx);
+
+          retval(0) = idx;
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
+
+}  
+
+/*
+%!assert (real(lookup(1:3, 0.5)), 0)     # value before table
+%!assert (real(lookup(1:3, 3.5)), 3)     # value after table error
+%!assert (real(lookup(1:3, 1.5)), 1)     # value within table error
+%!assert (real(lookup(1:3, [3,2,1])), [3,2,1])
+%!assert (real(lookup([1:4]', [1.2, 3.5]')), [1, 3]');
+%!assert (real(lookup([1:4], [1.2, 3.5]')), [1, 3]');
+%!assert (real(lookup([1:4]', [1.2, 3.5])), [1, 3]);
+%!assert (real(lookup([1:4], [1.2, 3.5])), [1, 3]);
+%!assert (real(lookup(1:3, [3, 2, 1])), [3, 2, 1]);
+%!assert (real(lookup([3:-1:1], [3.5, 3, 1.2, 2.5, 2.5])), [0, 1, 2, 1, 1])
+%!assert (isempty(lookup([1:3], [])))
+%!assert (isempty(lookup([1:3]', [])))
+%!assert (real(lookup(1:3, [1, 2; 3, 0.5])), [1, 2; 3, 0]);
+%!
+%!assert (real(lookup({"apple","lemon","orange"}, {"banana","kiwi"; "ananas","mango"})), [1,1;0,2])
+%!assert (real(lookup({"apple","lemon","orange"}, "potato")), 3)
+%!assert (real(lookup({"orange","lemon","apple"}, "potato")), 0)
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/lsode.cc b/src/DLD-FUNCTIONS/lsode.cc
new file mode 100644
index 0000000..35a324c
--- /dev/null
+++ b/src/DLD-FUNCTIONS/lsode.cc
@@ -0,0 +1,557 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <iomanip>
+#include <iostream>
+
+#include "LSODE.h"
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pr-output.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#include "LSODE-opts.cc"
+
+// Global pointer for user defined function required by lsode.
+static octave_function *lsode_fcn;
+
+// Global pointer for optional user defined jacobian function used by lsode.
+static octave_function *lsode_jac;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_fcn_imaginary = false;
+static bool warned_jac_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+ColumnVector
+lsode_user_function (const ColumnVector& x, double t)
+{
+  ColumnVector retval;
+
+  octave_value_list args;
+  args(1) = t;
+  args(0) = x;
+
+  if (lsode_fcn)
+    {
+      octave_value_list tmp = lsode_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("lsode");
+	  return retval;
+	}
+
+      if (tmp.length () > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_fcn_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("lsode: ignoring imaginary part returned from user-supplied function");
+	      warned_fcn_imaginary = true;
+	    }
+
+	  retval = ColumnVector (tmp(0).vector_value ());
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("lsode");
+	}
+      else
+	gripe_user_supplied_eval ("lsode");
+    }
+
+  return retval;
+}
+
+Matrix
+lsode_user_jacobian (const ColumnVector& x, double t)
+{
+  Matrix retval;
+
+  octave_value_list args;
+  args(1) = t;
+  args(0) = x;
+
+  if (lsode_jac)
+    {
+      octave_value_list tmp = lsode_jac->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  gripe_user_supplied_eval ("lsode");
+	  return retval;
+	}
+
+      if (tmp.length () > 0 && tmp(0).is_defined ())
+	{
+	  if (! warned_jac_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("lsode: ignoring imaginary part returned from user-supplied jacobian function");
+	      warned_jac_imaginary = true;
+	    }
+
+	  retval = tmp(0).matrix_value ();
+
+	  if (error_state || retval.length () == 0)
+	    gripe_user_supplied_eval ("lsode");
+	}
+      else
+	gripe_user_supplied_eval ("lsode");
+    }
+
+  return retval;
+}
+
+#define LSODE_ABORT() \
+  do \
+    { \
+      unwind_protect::run_frame ("Flsode"); \
+      return retval; \
+    } \
+  while (0)
+ 
+#define LSODE_ABORT1(msg) \
+  do \
+    { \
+      ::error ("lsode: " msg); \
+      LSODE_ABORT (); \
+    } \
+  while (0)
+
+#define LSODE_ABORT2(fmt, arg) \
+  do \
+    { \
+      ::error ("lsode: " fmt, arg); \
+      LSODE_ABORT (); \
+    } \
+  while (0)
+
+DEFUN_DLD (lsode, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{x}, @var{istate}, @var{msg}] =} lsode (@var{fcn}, @var{x_0}, @var{t}, @var{t_crit})\n\
+Solve the set of differential equations\n\
+ at tex\n\
+$$ {dx \\over dt} = f (x, t) $$\n\
+with\n\
+$$ x(t_0) = x_0 $$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+dx\n\
+-- = f(x, t)\n\
+dt\n\
+ at end group\n\
+ at end example\n\
+\n\
+with\n\
+\n\
+ at example\n\
+x(t_0) = x_0\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+The solution is returned in the matrix @var{x}, with each row\n\
+corresponding to an element of the vector @var{t}.  The first element\n\
+of @var{t} should be @math{t_0} and should correspond to the initial\n\
+state of the system @var{x_0}, so that the first row of the output\n\
+is @var{x_0}.\n\
+\n\
+The first argument, @var{fcn}, is a string, inline, or function handle\n\
+that names the function @math{f} to call to compute the vector of right\n\
+hand sides for the set of equations.  The function must have the form\n\
+\n\
+ at example\n\
+ at var{xdot} = f (@var{x}, @var{t})\n\
+ at end example\n\
+\n\
+ at noindent\n\
+in which @var{xdot} and @var{x} are vectors and @var{t} is a scalar.\n\
+\n\
+If @var{fcn} is a two-element string array or a two-element cell array\n\
+of strings, inline functions, or function handles, the first element names\n\
+the function @math{f} described above, and the second element names a\n\
+function to compute the Jacobian of @math{f}.  The Jacobian function\n\
+must have the form\n\
+\n\
+ at example\n\
+ at var{jac} = j (@var{x}, @var{t})\n\
+ at end example\n\
+\n\
+in which @var{jac} is the matrix of partial derivatives\n\
+ at tex\n\
+$$ J = {\\partial f_i \\over \\partial x_j} = \\left[\\matrix{\n\
+{\\partial f_1 \\over \\partial x_1}\n\
+  & {\\partial f_1 \\over \\partial x_2}\n\
+  & \\cdots\n\
+  & {\\partial f_1 \\over \\partial x_N} \\cr\n\
+{\\partial f_2 \\over \\partial x_1}\n\
+  & {\\partial f_2 \\over \\partial x_2}\n\
+  & \\cdots\n\
+  & {\\partial f_2 \\over \\partial x_N} \\cr\n\
+ \\vdots & \\vdots & \\ddots & \\vdots \\cr\n\
+{\\partial f_3 \\over \\partial x_1}\n\
+  & {\\partial f_3 \\over \\partial x_2}\n\
+  & \\cdots\n\
+  & {\\partial f_3 \\over \\partial x_N} \\cr}\\right]$$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+             | df_1  df_1       df_1 |\n\
+             | ----  ----  ...  ---- |\n\
+             | dx_1  dx_2       dx_N |\n\
+             |                       |\n\
+             | df_2  df_2       df_2 |\n\
+             | ----  ----  ...  ---- |\n\
+      df_i   | dx_1  dx_2       dx_N |\n\
+jac = ---- = |                       |\n\
+      dx_j   |  .    .     .    .    |\n\
+             |  .    .      .   .    |\n\
+             |  .    .       .  .    |\n\
+             |                       |\n\
+             | df_N  df_N       df_N |\n\
+             | ----  ----  ...  ---- |\n\
+             | dx_1  dx_2       dx_N |\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+\n\
+The second and third arguments specify the initial state of the system,\n\
+ at math{x_0}, and the initial value of the independent variable @math{t_0}.\n\
+\n\
+The fourth argument is optional, and may be used to specify a set of\n\
+times that the ODE solver should not integrate past.  It is useful for\n\
+avoiding difficulties with singularities and points where there is a\n\
+discontinuity in the derivative.\n\
+\n\
+After a successful computation, the value of @var{istate} will be 2\n\
+(consistent with the Fortran version of @sc{Lsode}).\n\
+\n\
+If the computation is not successful, @var{istate} will be something\n\
+other than 2 and @var{msg} will contain additional information.\n\
+\n\
+You can use the function @code{lsode_options} to set optional\n\
+parameters for @code{lsode}.\n\
+ at seealso{daspk, dassl, dasrt}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  warned_fcn_imaginary = false;
+  warned_jac_imaginary = false;
+
+  unwind_protect::begin_frame ("Flsode");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    LSODE_ABORT1 ("invalid recursive call");
+
+  int nargin = args.length ();
+
+  if (nargin > 2 && nargin < 5 && nargout < 4)
+    {
+      std::string fcn_name, fname, jac_name, jname;
+      lsode_fcn = 0;
+      lsode_jac = 0;
+
+      octave_value f_arg = args(0);
+
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		lsode_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__lsode_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x, t) y = ");
+		  lsode_fcn = extract_function
+		    (c(0), "lsode", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (lsode_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    lsode_jac = c(1).function_value ();
+		  else
+		    {
+			jac_name = unique_symbol_name ("__lsode_jac__");
+			jname = "function jac = ";
+			jname.append(jac_name);
+			jname.append (" (x, t) jac = ");
+			lsode_jac = extract_function
+			  (c(1), "lsode", jac_name, jname, "; endfunction");
+
+		      if (!lsode_jac)
+			{
+			  if (fcn_name.length())
+			    clear_function (fcn_name);
+			  lsode_fcn = 0;
+			}
+		    }
+		}
+	    }
+	  else
+	    LSODE_ABORT1 ("incorrect number of elements in cell array");
+	}
+
+      if (!lsode_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    lsode_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__lsode_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x, t) y = ");
+		      lsode_fcn = extract_function
+			(f_arg, "lsode", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
+
+		case 2:
+		  {
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__lsode_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x, t) y = ");
+			lsode_fcn = extract_function
+			  (tmp(0), "lsode", fcn_name, fname, "; endfunction");
+
+			if (lsode_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__lsode_jac__");
+			    jname = "function jac = ";
+			    jname.append(jac_name);
+			    jname.append (" (x, t) jac = ");
+			    lsode_jac = extract_function
+			      (tmp(1), "lsode", jac_name, jname,
+			      "; endfunction");
+
+			    if (!lsode_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				lsode_fcn = 0;
+			      }
+			  }
+		      }
+		  }
+		  break;
+
+		default:
+		  LSODE_ABORT1
+		    ("first arg should be a string or 2-element string array");
+		}
+	    }
+	}
+
+      if (error_state || ! lsode_fcn)
+	LSODE_ABORT ();
+
+      ColumnVector state (args(1).vector_value ());
+
+      if (error_state)
+	LSODE_ABORT1 ("expecting state vector as second argument");
+
+      ColumnVector out_times (args(2).vector_value ());
+
+      if (error_state)
+	LSODE_ABORT1 ("expecting output time vector as third argument");
+
+      ColumnVector crit_times;
+
+      int crit_times_set = 0;
+      if (nargin > 3)
+	{
+	  crit_times = ColumnVector (args(3).vector_value ());
+
+	  if (error_state)
+	    LSODE_ABORT1 ("expecting critical time vector as fourth argument");
+
+	  crit_times_set = 1;
+	}
+
+      double tzero = out_times (0);
+
+      ODEFunc func (lsode_user_function);
+      if (lsode_jac)
+	func.set_jacobian_function (lsode_user_jacobian);
+
+      LSODE ode (state, tzero, func);
+
+      ode.set_options (lsode_opts);
+
+      Matrix output;
+      if (crit_times_set)
+	output = ode.integrate (out_times, crit_times);
+      else
+	output = ode.integrate (out_times);
+
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
+      if (! error_state)
+	{
+	  std::string msg = ode.error_message ();
+
+	  retval(2) = msg;
+	  retval(1) = static_cast<double> (ode.integration_state ());
+
+	  if (ode.integration_ok ())
+	    retval(0) = output;
+	  else
+	    {
+	      retval(0) = Matrix ();
+
+	      if (nargout < 2)
+		error ("lsode: %s", msg.c_str ());
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Flsode");
+
+  return retval;
+}
+
+/*
+
+%% dassl-1.m
+%%
+%% Test lsode() function
+%%
+%% Author: David Billinghurst (David.Billinghurst at riotinto.com.au)
+%%         Comalco Research and Technology
+%%         20 May 1998
+%%
+%% Problem
+%%
+%%    y1' = -y2,   y1(0) = 1
+%%    y2' =  y1,   y2(0) = 0
+%%
+%% Solution
+%%
+%%    y1(t) = cos(t)
+%%    y2(t) = sin(t)
+%!function xdot = f (x, t)
+%!  xdot = [-x(2); x(1)];
+%!test
+%! 
+%! x0 = [1; 0];
+%! xdot0 = [0; 1];
+%! t = (0:1:10)';
+%! 
+%! tol = 500 * lsode_options ("relative tolerance");
+%! 
+%! 
+%! x = lsode ("f", x0, t);
+%! 
+%! y = [cos(t), sin(t)];
+%! 
+%! assert(all (all (abs (x - y) < tol)));
+
+%!function xdotdot = f (x, t)
+%!  xdotdot = [x(2); -x(1)];
+%!test
+%! 
+%! x0 = [1; 0];
+%! t = [0; 2*pi];
+%! tol = 100 * dassl_options ("relative tolerance");
+%! 
+%! x = lsode ("f", x0, t);
+%! 
+%! y = [1, 0; 1, 0];
+%! 
+%! assert(all (all (abs (x - y) < tol)));
+
+%!function xdot = f (x, t)
+%!  xdot = x;
+%!test
+%! 
+%! x0 = 1;
+%! t = [0; 1];
+%! tol = 100 * dassl_options ("relative tolerance");
+%! 
+%! x = lsode ("f", x0, t);
+%! 
+%! y = [1; e];
+%! 
+%! assert(all (all (abs (x - y) < tol)));
+
+%!test
+%! lsode_options ("absolute tolerance", eps);
+%! assert(lsode_options ("absolute tolerance") == eps);
+
+%!error <Invalid call to lsode_options.*> lsode_options ("foo", 1, 2);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/lu.cc b/src/DLD-FUNCTIONS/lu.cc
new file mode 100644
index 0000000..3f34e8d
--- /dev/null
+++ b/src/DLD-FUNCTIONS/lu.cc
@@ -0,0 +1,591 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2003, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxLU.h"
+#include "dbleLU.h"
+#include "fCmplxLU.h"
+#include "floatLU.h"
+#include "SparseCmplxLU.h"
+#include "SparsedbleLU.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+template <class MT>
+static octave_value
+maybe_set_triangular (const MT& m, MatrixType::matrix_type t = MatrixType::Upper)
+{
+  typedef typename MT::element_type T;
+  octave_value retval;
+  octave_idx_type r = m.rows (), c = m.columns ();
+  if (r == c)
+    {
+      const T zero = T();
+      octave_idx_type i = 0;
+      for (;i != r && m(i,i) != zero; i++) ;
+      if (i == r)
+        retval = octave_value (m, MatrixType (t));
+      else
+        retval = m;
+    }
+  else
+    retval = m;
+
+  return retval;
+}
+
+DEFUN_DLD (lu, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}] =} lu (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} lu (@var{s})\n\
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}] =} lu (@var{s})\n\
+ at deftypefnx {Loadable Function} {[@dots{}] =} lu (@var{s}, @var{thres})\n\
+ at deftypefnx {Loadable Function} {@var{y} =} lu (@dots{})\n\
+ at deftypefnx {Loadable Function} {[@dots{}] =} lu (@dots{}, 'vector')\n\
+ at cindex LU decomposition\n\
+Compute the LU decomposition of @var{a}.  If @var{a} is full subroutines from\n\
+ at sc{lapack} are used and if @var{a} is sparse then UMFPACK is used.  The\n\
+result is returned in a permuted form, according to the optional return\n\
+value @var{p}.  For example, given the matrix @code{a = [1, 2; 3, 4]},\n\
+\n\
+ at example\n\
+[l, u, p] = lu (a)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns\n\
+\n\
+ at example\n\
+ at group\n\
+l =\n\
+\n\
+  1.00000  0.00000\n\
+  0.33333  1.00000\n\
+\n\
+u =\n\
+\n\
+  3.00000  4.00000\n\
+  0.00000  0.66667\n\
+\n\
+p =\n\
+\n\
+  0  1\n\
+  1  0\n\
+ at end group\n\
+ at end example\n\
+\n\
+The matrix is not required to be square.\n\
+\n\
+Called with two or three output arguments and a spare input matrix,\n\
+then @dfn{lu} does not attempt to perform sparsity preserving column\n\
+permutations.  Called with a fourth output argument, the sparsity\n\
+preserving column transformation @var{Q} is returned, such that\n\
+ at code{@var{p} * @var{a} * @var{q} = @var{l} * @var{u}}.\n\
+\n\
+Called with a fifth output argument and a sparse input matrix, then\n\
+ at dfn{lu} attempts to use a scaling factor @var{r} on the input matrix\n\
+such that @code{@var{p} * (@var{r} \\ @var{a}) * @var{q} = @var{l} * @var{u}}.\n\
+This typically leads to a sparser and more stable factorization.\n\
+\n\
+An additional input argument @var{thres}, that defines the pivoting\n\
+threshold can be given.  @var{thres} can be a scalar, in which case\n\
+it defines UMFPACK pivoting tolerance for both symmetric and unsymmetric\n\
+cases.  If @var{thres} is a two element vector, then the first element\n\
+defines the pivoting tolerance for the unsymmetric UMFPACK pivoting\n\
+strategy and the second the symmetric strategy.  By default, the values\n\
+defined by @code{spparms} are used and are by default @code{[0.1, 0.001]}.\n\
+\n\
+Given the string argument 'vector', @dfn{lu} returns the values of @var{p}\n\
+ at var{q} as vector values, such that for full matrix, @code{@var{a}\n\
+(@var{p},:) = @var{l} * @var{u}}, and @code{@var{r}(@var{p},:) * @var{a}\n\
+(:, @var{q}) = @var{l} * @var{u}}.\n\
+\n\
+With two output arguments, returns the permuted forms of the upper and\n\
+lower triangular matrices, such that @code{@var{a} = @var{l} * @var{u}}.\n\
+With one output argument @var{y}, then the matrix returned by the @sc{lapack}\n\
+routines is returned.  If the input matrix is sparse then the matrix @var{l}\n\
+is embedded into @var{u} to give a return value similar to the full case.\n\
+For both full and sparse matrices, @dfn{lu} looses the permutation\n\
+information.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  bool issparse = (nargin > 0 && args(0).is_sparse_type ());
+  bool scale = (nargout  == 5);
+
+  if (nargin < 1 || (issparse && (nargin > 3 || nargout > 5)) 
+      || (!issparse && (nargin > 2 || nargout > 3)))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  bool vecout = false;
+  Matrix thres;
+
+  int n = 1;
+  while (n < nargin && ! error_state)
+    {
+      if (args (n).is_string ())
+	{
+	  std::string tmp = args(n++).string_value ();
+
+	  if (! error_state )
+	    {
+	      if (tmp.compare ("vector") == 0)
+		vecout = true;
+	      else
+		error ("lu: unrecognized string argument");
+	    }
+	}
+      else
+	{
+	  Matrix tmp = args(n++).matrix_value ();
+
+	  if (! error_state )
+	    {
+	      if (!issparse)
+		error ("lu: can not define pivoting threshold for full matrices");
+	      else if (tmp.nelem () == 1)
+		{
+		  thres.resize(1,2);
+		  thres(0) = tmp(0);
+		  thres(1) = tmp(0);
+		}
+	      else if (tmp.nelem () == 2)
+		thres = tmp;
+	      else
+		error ("lu: expecting 2 element vector for thres");
+	    }
+	}
+    }
+
+  octave_value arg = args(0);
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  int arg_is_empty = empty_arg ("lu", nr, nc);
+
+  if (issparse)
+    {
+      if (arg_is_empty < 0)
+	return retval;
+      else if (arg_is_empty > 0)
+	return octave_value_list (5, SparseMatrix ());
+
+      ColumnVector Qinit;
+      if (nargout < 4)
+	{
+	  Qinit.resize (nc);
+	  for (octave_idx_type i = 0; i < nc; i++)
+	    Qinit (i) = i;
+	}
+
+      if (arg.is_real_type ())
+	{
+	  SparseMatrix m = arg.sparse_matrix_value ();
+
+	  switch (nargout)
+	    {
+	    case 0:
+	    case 1:
+	    case 2:
+	      {
+		SparseLU fact (m, Qinit, thres, false, true);
+
+		if (nargout < 2)
+		  retval (0) = fact.Y ();
+		else
+		  {
+		    PermMatrix P = fact.Pr_mat ();
+		    SparseMatrix L = P.transpose () * fact.L ();
+		    retval(1) = octave_value (fact.U (), 
+					      MatrixType (MatrixType::Upper));
+
+		    retval(0) = octave_value (L, 
+			MatrixType (MatrixType::Permuted_Lower, 
+				    nr, fact.row_perm ()));
+		  }
+	      }
+	      break;
+
+	    case 3:
+	      {
+		SparseLU fact (m, Qinit, thres, false, true);
+
+		if (vecout)
+		  retval (2) = fact.Pr_vec ();
+		else
+		  retval(2) = fact.Pr_mat ();
+
+		retval(1) = octave_value (fact.U (), 
+					  MatrixType (MatrixType::Upper));
+		retval(0) = octave_value (fact.L (), 
+					  MatrixType (MatrixType::Lower));
+	      }
+	      break;
+
+	    case 4:
+	    default:
+	      {
+		SparseLU fact (m, thres, scale);
+
+		if (scale)
+		  retval(4) = fact.R ();
+
+		if (vecout)
+		  {
+		    retval(3) = fact.Pc_vec ();
+		    retval(2) = fact.Pr_vec ();
+		  }
+		else
+		  {
+		    retval(3) = fact.Pc_mat ();
+		    retval(2) = fact.Pr_mat ();
+		  }
+		retval(1) = octave_value (fact.U (), 
+					  MatrixType (MatrixType::Upper));
+		retval(0) = octave_value (fact.L (), 
+					  MatrixType (MatrixType::Lower));
+	      }
+	      break;
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+
+	  switch (nargout)
+	    {
+	    case 0:
+	    case 1:
+	    case 2:
+	      {
+		SparseComplexLU fact (m, Qinit, thres, false, true);
+
+		if (nargout < 2)
+		  retval (0) = fact.Y ();
+		else
+		  {
+		    PermMatrix P = fact.Pr_mat ();
+		    SparseComplexMatrix L = P.transpose () * fact.L ();
+		    retval(1) = octave_value (fact.U (), 
+					      MatrixType (MatrixType::Upper));
+
+		    retval(0) = octave_value (L, 
+			MatrixType (MatrixType::Permuted_Lower, 
+				    nr, fact.row_perm ()));
+		  }
+	      }
+	      break;
+
+	    case 3:
+	      {
+		SparseComplexLU fact (m, Qinit, thres, false, true);
+
+		if (vecout)
+		  retval (2) = fact.Pr_vec ();
+		else
+		  retval(2) = fact.Pr_mat ();
+
+		retval(1) = octave_value (fact.U (), 
+					  MatrixType (MatrixType::Upper));
+		retval(0) = octave_value (fact.L (), 
+					  MatrixType (MatrixType::Lower));
+	      }
+	      break;
+
+	    case 4:
+	    default:
+	      {
+		SparseComplexLU fact (m, thres, scale);
+
+		if (scale)
+		  retval(4) = fact.R ();
+
+		if (vecout)
+		  {
+		    retval(3) = fact.Pc_vec ();
+		    retval(2) = fact.Pr_vec ();
+		  }
+		else
+		  {
+		    retval(3) = fact.Pc_mat ();
+		    retval(2) = fact.Pr_mat ();
+		  }
+		retval(1) = octave_value (fact.U (), 
+					  MatrixType (MatrixType::Upper));
+		retval(0) = octave_value (fact.L (), 
+					  MatrixType (MatrixType::Lower));
+	      }
+	      break;
+	    }
+	}
+      else
+	gripe_wrong_type_arg ("lu", arg);
+    }
+  else
+    {
+      if (arg_is_empty < 0)
+	return retval;
+      else if (arg_is_empty > 0)
+	return octave_value_list (3, Matrix ());
+
+      if (arg.is_real_type ())
+	{
+	  if (arg.is_single_type ())
+	    {
+	      FloatMatrix m = arg.float_matrix_value ();
+
+	      if (! error_state)
+		{
+		  FloatLU fact (m);
+
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      retval(0) = fact.Y ();
+		      break;
+
+		    case 2:
+		      {
+			PermMatrix P = fact.P ();
+			FloatMatrix L = P.transpose () * fact.L ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = L;
+		      }
+		      break;
+
+		    case 3:
+		    default:
+		      {
+			if (vecout)
+			  retval(2) = fact.P_vec ();
+			else
+			  retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = maybe_set_triangular (fact.L (), MatrixType::Lower);
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else
+	    {
+	      Matrix m = arg.matrix_value ();
+
+	      if (! error_state)
+		{
+		  LU fact (m);
+
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      retval(0) = fact.Y ();
+		      break;
+
+		    case 2:
+		      {
+			PermMatrix P = fact.P ();
+			Matrix L = P.transpose () * fact.L ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = L;
+		      }
+		      break;
+
+		    case 3:
+		    default:
+		      {
+			if (vecout)
+			  retval(2) = fact.P_vec ();
+			else
+			  retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = maybe_set_triangular (fact.L (), MatrixType::Lower);
+		      }
+		      break;
+		    }
+		}
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  if (arg.is_single_type ())
+	    {
+	      FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  FloatComplexLU fact (m);
+
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      retval(0) = fact.Y ();
+		      break;
+
+		    case 2:
+		      {
+			PermMatrix P = fact.P ();
+			FloatComplexMatrix L = P.transpose () * fact.L ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = L;
+		      }
+		      break;
+
+		    case 3:
+		    default:
+		      {
+			if (vecout)
+			  retval(2) = fact.P_vec ();
+			else
+			  retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = maybe_set_triangular (fact.L (), MatrixType::Lower);
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else
+	    {
+	      ComplexMatrix m = arg.complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  ComplexLU fact (m);
+
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      retval(0) = fact.Y ();
+		      break;
+
+		    case 2:
+		      {
+			PermMatrix P = fact.P ();
+			ComplexMatrix L = P.transpose () * fact.L ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = L;
+		      }
+		      break;
+
+		    case 3:
+		    default:
+		      {
+			if (vecout)
+			  retval(2) = fact.P_vec ();
+			else
+			  retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.U (), MatrixType::Upper);
+			retval(0) = maybe_set_triangular (fact.L (), MatrixType::Lower);
+		      }
+		      break;
+		    }
+		}
+	    }
+	}
+      else
+	gripe_wrong_type_arg ("lu", arg);
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(lu ([1, 2; 3, 4]), [3, 4; 1/3, 2/3], eps);
+
+%!test
+%! [l, u] = lu ([1, 2; 3, 4]);
+%! assert(l, [1/3, 1; 1, 0], sqrt (eps));
+%! assert(u, [3, 4; 0, 2/3], sqrt (eps));
+
+%!test
+%! [l, u, p] = lu ([1, 2; 3, 4]);
+%! assert(l, [1, 0; 1/3, 1], sqrt (eps));
+%! assert(u, [3, 4; 0, 2/3], sqrt (eps));
+%! assert(p(:,:), [0, 1; 1, 0], sqrt (eps));
+
+%!test
+%! [l, u, p] = lu ([1, 2; 3, 4],'vector');
+%! assert(l, [1, 0; 1/3, 1], sqrt (eps));
+%! assert(u, [3, 4; 0, 2/3], sqrt (eps));
+%! assert(p, [2;1], sqrt (eps));
+
+%!test
+%! [l u p] = lu ([1, 2; 3, 4; 5, 6]);
+%! assert(l, [1, 0; 1/5, 1; 3/5, 1/2], sqrt (eps));
+%! assert(u, [5, 6; 0, 4/5], sqrt (eps));
+%! assert(p(:,:), [0, 0, 1; 1, 0, 0; 0 1 0], sqrt (eps));
+
+%!assert(lu (single([1, 2; 3, 4])), single([3, 4; 1/3, 2/3]), eps('single'));
+
+%!test
+%! [l, u] = lu (single([1, 2; 3, 4]));
+%! assert(l, single([1/3, 1; 1, 0]), sqrt (eps('single')));
+%! assert(u, single([3, 4; 0, 2/3]), sqrt (eps('single')));
+
+%!test
+%! [l, u, p] = lu (single([1, 2; 3, 4]));
+%! assert(l, single([1, 0; 1/3, 1]), sqrt (eps('single')));
+%! assert(u, single([3, 4; 0, 2/3]), sqrt (eps('single')));
+%! assert(p(:,:), single([0, 1; 1, 0]), sqrt (eps('single')));
+
+%!test
+%! [l, u, p] = lu (single([1, 2; 3, 4]),'vector');
+%! assert(l, single([1, 0; 1/3, 1]), sqrt (eps('single')));
+%! assert(u, single([3, 4; 0, 2/3]), sqrt (eps('single')));
+%! assert(p, single([2;1]), sqrt (eps('single')));
+
+%!test
+%! [l u p] = lu (single([1, 2; 3, 4; 5, 6]));
+%! assert(l, single([1, 0; 1/5, 1; 3/5, 1/2]), sqrt (eps('single')));
+%! assert(u, single([5, 6; 0, 4/5]), sqrt (eps('single')));
+%! assert(p(:,:), single([0, 0, 1; 1, 0, 0; 0 1 0]), sqrt (eps('single')));
+
+%!error <Invalid call to lu.*> lu ();
+%!error lu ([1, 2; 3, 4], 2);
+
+ */
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/luinc.cc b/src/DLD-FUNCTIONS/luinc.cc
new file mode 100644
index 0000000..c2e2d4a
--- /dev/null
+++ b/src/DLD-FUNCTIONS/luinc.cc
@@ -0,0 +1,374 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "oct-map.h"
+
+#include "MatrixType.h"
+#include "SparseCmplxLU.h"
+#include "SparsedbleLU.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+DEFUN_DLD (luinc, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, '0')\n\
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, @var{droptol})\n\
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, @var{opts})\n\
+ at cindex LU decomposition\n\
+Produce the incomplete LU factorization of the sparse matrix @var{a}.\n\
+Two types of incomplete factorization are possible, and the type\n\
+is determined by the second argument to @dfn{luinc}.\n\
+\n\
+Called with a second argument of '0', the zero-level incomplete\n\
+LU factorization is produced.  This creates a factorization of @var{a}\n\
+where the position of the non-zero arguments correspond to the same\n\
+positions as in the matrix @var{a}.\n\
+\n\
+Alternatively, the fill-in of the incomplete LU factorization can\n\
+be controlled through the variable @var{droptol} or the structure\n\
+ at var{opts}.  The UMFPACK multifrontal factorization code by Tim A.\n\
+Davis is used for the incomplete LU factorization, (availability\n\
+ at url{http://www.cise.ufl.edu/research/sparse/umfpack/})\n\
+\n\
+ at var{droptol} determines the values below which the values in the LU\n\
+factorization are dropped and replaced by zero.  It must be a positive\n\
+scalar, and any values in the factorization whose absolute value are\n\
+less than this value are dropped, expect if leaving them increase the\n\
+sparsity of the matrix.  Setting @var{droptol} to zero results in a\n\
+complete LU factorization which is the default.\n\
+\n\
+ at var{opts} is a structure containing one or more of the fields\n\
+\n\
+ at table @code\n\
+ at item droptol\n\
+The drop tolerance as above.  If @var{opts} only contains @code{droptol}\n\
+then this is equivalent to using the variable @var{droptol}.\n\
+\n\
+ at item milu\n\
+A logical variable flagging whether to use the modified incomplete LU\n\
+factorization.  In the case that @code{milu} is true, the dropped values\n\
+are subtracted from the diagonal of the matrix U of the factorization.\n\
+The default is @code{false}.\n\
+\n\
+ at item udiag\n\
+A logical variable that flags whether zero elements on the diagonal of U\n\
+should be replaced with @var{droptol} to attempt to avoid singular\n\
+factors.  The default is @code{false}.\n\
+\n\
+ at item thresh\n\
+Defines the pivot threshold in the interval [0,1].  Values outside that\n\
+range are ignored.\n\
+ at end table\n\
+\n\
+All other fields in @var{opts} are ignored.  The outputs from @dfn{luinc}\n\
+are the same as for @dfn{lu}.\n\
+\n\
+Given the string argument 'vector', @dfn{luinc} returns the values of @var{p}\n\
+ at var{q} as vector values.\n\
+ at seealso{sparse, lu}\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin == 0)
+    print_usage ();
+  else if (nargin < 2 || nargin > 3)
+    error ("luinc: incorrect number of arguments");
+  else
+    {
+      bool zero_level = false;
+      bool milu = false;
+      bool udiag = false;
+      Matrix thresh;
+      double droptol = -1.;
+      bool vecout;
+
+      if (args(1).is_string ())
+	{
+	  if (args(1).string_value () == "0")
+	    zero_level = true;
+	  else
+	    error ("luinc: unrecognized string argument");
+	}
+      else if (args(1).is_map ())
+	{
+	  Octave_map map = args(1).map_value ();
+
+	  if (map.contains ("droptol"))
+	    droptol = map.contents ("droptol")(0).double_value ();
+
+	  if (map.contains ("milu"))
+	    {
+	      double tmp = map.contents ("milu")(0).double_value ();
+
+	      milu = (tmp == 0. ? false : true);
+	    }
+
+	  if (map.contains ("udiag"))
+	    {
+	      double tmp = map.contents ("udiag")(0).double_value ();
+
+	      udiag = (tmp == 0. ? false : true);
+	    }
+
+	  if (map.contains ("thresh"))
+	    {
+	      thresh = map.contents ("thresh")(0).matrix_value ();
+
+	      if (thresh.nelem () == 1)
+		{
+		  thresh.resize(1,2);
+		  thresh(1) = thresh(0);
+		}
+	      else if (thresh.nelem () != 2)
+		error ("chol: expecting 2 element vector for thresh");
+	    }
+	}
+      else
+	droptol = args(1).double_value ();
+
+      if (nargin == 3)
+	{
+	  std::string tmp = args(2).string_value ();
+
+	  if (! error_state )
+	    {
+	      if (tmp.compare ("vector") == 0)
+		vecout = true;
+	      else
+		error ("luinc: unrecognized string argument");
+	    }
+	}
+
+      // FIXME Add code for zero-level factorization
+      if (zero_level)
+	error ("luinc: zero-level factorization not implemented");
+
+      if (!error_state)
+	{
+	  if (args(0).type_name () == "sparse matrix") 
+	    {
+	      SparseMatrix sm = args(0).sparse_matrix_value ();
+	      octave_idx_type sm_nr = sm.rows ();
+	      octave_idx_type sm_nc = sm.cols ();
+	      ColumnVector Qinit (sm_nc);
+
+	      for (octave_idx_type i = 0; i < sm_nc; i++)
+		Qinit (i) = i;
+
+	      if (! error_state)
+		{
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		    case 2:
+		      {
+			SparseLU fact (sm, Qinit, thresh, false, true, droptol,
+				       milu, udiag);
+
+			if (! error_state)
+			  {
+			    SparseMatrix P = fact.Pr ();
+			    SparseMatrix L = P.transpose () * fact.L ();
+			    retval(1) = octave_value (fact.U (),
+						      MatrixType (MatrixType::Upper));
+			    retval(0) = octave_value (L, MatrixType 
+						      (MatrixType::Permuted_Lower, 
+						       sm_nr, fact.row_perm ()));
+			  }
+		      }
+		      break;
+
+		    case 3:
+		      {
+			SparseLU fact (sm, Qinit, thresh, false, true, droptol,
+				       milu, udiag);
+
+			if (! error_state)
+			  {
+			    if (vecout)
+			      retval(2) = fact.Pr_vec ();
+			    else
+			      retval(2) = fact.Pr ();
+			    retval(1) = octave_value (fact.U (),
+						      MatrixType (MatrixType::Upper));
+			    retval(0) = octave_value (fact.L (),
+						      MatrixType (MatrixType::Lower));
+			  }
+		      }
+		      break;
+
+		    case 4:
+		    default:
+		      {
+			SparseLU fact (sm, Qinit, thresh, false, false, droptol,
+				       milu, udiag);
+
+			if (! error_state)
+			  {
+			    if (vecout)
+			      {
+				retval(3) = fact.Pc_vec ();
+				retval(2) = fact.Pr_vec ();
+			      }
+			    else
+			      {
+				retval(3) = fact.Pc ();
+				retval(2) = fact.Pr ();
+			      }
+			    retval(1) = octave_value (fact.U (),
+						      MatrixType (MatrixType::Upper));
+			    retval(0) = octave_value (fact.L (),
+						      MatrixType (MatrixType::Lower));
+			  }
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else if (args(0).type_name () == "sparse complex matrix") 
+	    {
+	      SparseComplexMatrix sm = 
+		args(0).sparse_complex_matrix_value ();
+	      octave_idx_type sm_nr = sm.rows ();
+	      octave_idx_type sm_nc = sm.cols ();
+	      ColumnVector Qinit (sm_nc);
+
+	      for (octave_idx_type i = 0; i < sm_nc; i++)
+		Qinit (i) = i;
+
+	      if (! error_state)
+		{
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		    case 2:
+		      {
+			SparseComplexLU fact (sm, Qinit, thresh, false, true, 
+					      droptol, milu, udiag);
+
+
+			if (! error_state)
+			  {
+			    SparseMatrix P = fact.Pr ();
+			    SparseComplexMatrix L = P.transpose () * fact.L ();
+			    retval(1) = octave_value (fact.U (),
+						      MatrixType (MatrixType::Upper));
+			    retval(0) = octave_value (L, MatrixType 
+						      (MatrixType::Permuted_Lower, 
+						       sm_nr, fact.row_perm ()));
+			  }
+		      }
+		      break;
+
+		    case 3:
+		      {
+			SparseComplexLU fact (sm, Qinit, thresh, false, true,
+					      droptol, milu, udiag);
+
+			if (! error_state)
+			  {
+			    if (vecout)
+			      retval(2) = fact.Pr_vec ();
+			    else
+			      retval(2) = fact.Pr ();
+			    retval(1) = octave_value (fact.U (),
+						      MatrixType (MatrixType::Upper));
+			    retval(0) = octave_value (fact.L (),
+						      MatrixType (MatrixType::Lower));
+			  }
+		      }
+		      break;
+
+		    case 4:
+		    default:
+		      {
+			SparseComplexLU fact (sm, Qinit, thresh, false, false,
+					      droptol, milu, udiag);
+
+			if (! error_state)
+			  {
+			    if (vecout)
+			      {
+				retval(3) = fact.Pc_vec ();
+				retval(2) = fact.Pr_vec ();
+			      }
+			    else
+			      {
+				retval(3) = fact.Pc ();
+				retval(2) = fact.Pr ();
+			      }
+			    retval(1) = octave_value (fact.U (),
+						      MatrixType (MatrixType::Upper));
+			    retval(0) = octave_value (fact.L (),
+						      MatrixType (MatrixType::Lower));
+			  }
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else
+	    error ("luinc: first argument must be sparse");
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!testif HAVE_UMFPACK
+%! a=sparse([1,2,0,0;0,1,2,0;1e-14,0,3,0;0,0,0,1]);
+%! [l,u]=luinc(a,1e-10);
+%! assert(l*u, sparse([1,2,0,0;0,1,2,0;0,0,3,0;0,0,0,1]),1e-10);
+%! opts.droptol=1e-10;
+%! [l,u]=luinc(a,opts);
+%! assert(l*u, sparse([1,2,0,0;0,1,2,0;0,0,3,0;0,0,0,1]),1e-10);
+
+%!testif HAVE_UMFPACK
+%! a=sparse([1i,2,0,0;0,1,2,0;1e-14,0,3,0;0,0,0,1]);
+%! [l,u]=luinc(a,1e-10);
+%! assert(l*u, sparse([1i,2,0,0;0,1,2,0;0,0,3,0;0,0,0,1]),1e-10);
+%! opts.droptol=1e-10;
+%! [l,u]=luinc(a,opts);
+%! assert(l*u, sparse([1i,2,0,0;0,1,2,0;0,0,3,0;0,0,0,1]),1e-10);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/matrix_type.cc b/src/DLD-FUNCTIONS/matrix_type.cc
new file mode 100644
index 0000000..73b6666
--- /dev/null
+++ b/src/DLD-FUNCTIONS/matrix_type.cc
@@ -0,0 +1,613 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "ov-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "MatrixType.h"
+#include "oct-locbuf.h"
+
+DEFUN_DLD (matrix_type, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{type} =} matrix_type (@var{a})\n\
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, @var{type})\n\
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'upper', @var{perm})\n\
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'lower', @var{perm})\n\
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'banded', @var{nl}, @var{nu})\n\
+Identify the matrix type or mark a matrix as a particular type.  This allows rapid\n\
+for solutions of linear equations involving @var{a} to be performed.  Called with a\n\
+single argument, @code{matrix_type} returns the type of the matrix and caches it for\n\
+future use.  Called with more than one argument, @code{matrix_type} allows the type\n\
+of the matrix to be defined.\n\
+\n\
+The possible matrix types depend on whether the matrix is full or sparse, and can be\n\
+one of the following\n\
+\n\
+ at table @asis\n\
+ at item 'unknown'\n\
+Remove any previously cached matrix type, and mark type as unknown\n\
+\n\
+ at item 'full'\n\
+Mark the matrix as full.\n\
+\n\
+ at item 'positive definite'\n\
+Probable full positive definite matrix.\n\
+\n\
+ at item 'diagonal'\n\
+Diagonal Matrix.  (Sparse matrices only)\n\
+\n\
+ at item 'permuted diagonal'\n\
+Permuted Diagonal matrix.  The permutation does not need to be specifically\n\
+indicated, as the structure of the matrix explicitly gives this.  (Sparse matrices\n\
+only)\n\
+\n\
+ at item 'upper'\n\
+Upper triangular.  If the optional third argument @var{perm} is given, the matrix is\n\
+assumed to be a permuted upper triangular with the permutations defined by the\n\
+vector @var{perm}.\n\
+\n\
+ at item 'lower'\n\
+Lower triangular.  If the optional third argument @var{perm} is given, the matrix is\n\
+assumed to be a permuted lower triangular with the permutations defined by the\n\
+vector @var{perm}.\n\
+\n\
+ at item 'banded'\n\
+ at itemx 'banded positive definite'\n\
+Banded matrix with the band size of @var{nl} below the diagonal and @var{nu} above\n\
+it.  If @var{nl} and @var{nu} are 1, then the matrix is tridiagonal and treated\n\
+with specialized code.  In addition the matrix can be marked as probably a\n\
+positive definite (Sparse matrices only)\n\
+\n\
+ at item 'singular'\n\
+The matrix is assumed to be singular and will be treated with a minimum norm solution\n\
+\n\
+ at end table\n\
+\n\
+Note that the matrix type will be discovered automatically on the first attempt to\n\
+solve a linear equation involving @var{a}.  Therefore @code{matrix_type} is only\n\
+useful to give Octave hints of the matrix type.  Incorrectly defining the\n\
+matrix type will result in incorrect results from solutions of linear equations,\n\
+and so it is entirely the responsibility of the user to correctly identify the\n\
+matrix type.\n\
+\n\
+Also the test for positive definiteness is a low-cost test for a hermitian\n\
+matrix with a real positive diagonal.  This does not guarantee that the matrix\n\
+is positive definite, but only that it is a probable candidate.  When such a\n\
+matrix is factorized, a Cholesky factorization is first attempted, and if\n\
+that fails the matrix is then treated with an LU factorization.  Once the\n\
+matrix has been factorized, @code{matrix_type} will return the correct\n\
+classification of the matrix.\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin == 0)
+    print_usage ();
+  else if (nargin > 4)
+    error ("matrix_type: incorrect number of arguments");
+  else
+    {
+      if (args(0).is_scalar_type())
+	{
+	  if (nargin == 1)
+	    retval = octave_value ("Full");
+	  else
+	    retval = args(0);
+	}
+      else if (args(0).is_sparse_type ())
+	{
+	  if (nargin == 1)
+	    {
+	      MatrixType mattyp;
+
+	      if (args(0).is_complex_type ()) 
+		{
+		  mattyp = args(0).matrix_type ();
+
+		  if (mattyp.is_unknown ())
+		    {
+		      SparseComplexMatrix m = 
+			args(0).sparse_complex_matrix_value ();
+		      if (!error_state)
+			{
+			  mattyp = MatrixType (m);
+			  args(0).matrix_type (mattyp);
+			}
+		    }
+		}
+	      else
+		{
+		  mattyp = args(0).matrix_type ();
+
+		  if (mattyp.is_unknown ())
+		    {
+		      SparseMatrix m = args(0).sparse_matrix_value ();
+		      if (!error_state)
+			{
+			  mattyp = MatrixType (m);
+			  args(0).matrix_type (mattyp);
+			}
+		    }
+		}
+
+	      int typ = mattyp.type ();
+
+	      if (typ == MatrixType::Diagonal)
+		retval = octave_value ("Diagonal");
+	      else if (typ == MatrixType::Permuted_Diagonal)
+		retval = octave_value ("Permuted Diagonal");
+	      else if (typ == MatrixType::Upper)
+		retval = octave_value ("Upper");
+	      else if (typ == MatrixType::Permuted_Upper)
+		retval = octave_value ("Permuted Upper");
+	      else if (typ == MatrixType::Lower)
+		retval = octave_value ("Lower");
+	      else if (typ == MatrixType::Permuted_Lower)
+		retval = octave_value ("Permuted Lower");
+	      else if (typ == MatrixType::Banded)
+		retval = octave_value ("Banded");
+	      else if (typ == MatrixType::Banded_Hermitian)
+		retval = octave_value ("Banded Positive Definite");
+	      else if (typ == MatrixType::Tridiagonal)
+		retval = octave_value ("Tridiagonal");
+	      else if (typ == MatrixType::Tridiagonal_Hermitian)
+		retval = octave_value ("Tridiagonal Positive Definite");
+	      else if (typ == MatrixType::Hermitian)
+		retval = octave_value ("Positive Definite");
+	      else if (typ == MatrixType::Rectangular)
+		{
+		  if (args(0).rows() == args(0).columns())
+		    retval = octave_value ("Singular");
+		  else
+		    retval = octave_value ("Rectangular");
+		}
+	      else if (typ == MatrixType::Full)
+		retval = octave_value ("Full");
+	      else
+		// This should never happen!!!
+		retval = octave_value ("Unknown");
+	    }
+	  else
+	    {
+	      // Ok, we're changing the matrix type
+	      std::string str_typ = args(1).string_value ();
+
+	      // FIXME -- why do I have to explicitly call the constructor?
+	      MatrixType mattyp = MatrixType ();
+
+	      octave_idx_type nl = 0;
+	      octave_idx_type nu = 0;
+	      
+	      if (error_state)
+		error ("Matrix type must be a string");
+	      else
+		{
+		  // Use STL function to convert to lower case
+		  std::transform (str_typ.begin (), str_typ.end (),
+				  str_typ.begin (), tolower);
+
+		  if (str_typ == "diagonal")
+		    mattyp.mark_as_diagonal ();
+		  if (str_typ == "permuted diagonal")
+		    mattyp.mark_as_permuted_diagonal ();
+		  else if (str_typ == "upper")
+		    mattyp.mark_as_upper_triangular ();
+		  else if (str_typ == "lower")
+		    mattyp.mark_as_lower_triangular ();
+		  else if (str_typ == "banded" || str_typ == "banded positive definite")
+		    {
+		      if (nargin != 4)
+			error ("matrix_type: banded matrix type requires 4 arguments");
+		      else
+			{
+			  nl = args(2).nint_value ();
+			  nu = args(3).nint_value ();
+
+			  if (error_state)
+			    error ("matrix_type: band size must be integer");
+			  else
+			    {
+			      if (nl == 1 && nu == 1)
+				mattyp.mark_as_tridiagonal ();
+			      else
+				mattyp.mark_as_banded (nu, nl);
+			      
+			      if (str_typ == "banded positive definite")
+				mattyp.mark_as_symmetric ();
+			    }
+			}
+		    }
+		  else if (str_typ == "positive definite")
+		    {
+		      mattyp.mark_as_full ();
+		      mattyp.mark_as_symmetric ();
+		    }
+		  else if (str_typ == "singular")
+		    mattyp.mark_as_rectangular ();
+		  else if (str_typ == "full")
+		    mattyp.mark_as_full ();
+		  else if (str_typ == "unknown")
+		    mattyp.invalidate_type ();
+		  else
+		    error ("matrix_type: Unknown matrix type %s", str_typ.c_str());
+
+		  if (! error_state)
+		    {
+		      if (nargin == 3 && (str_typ == "upper" || str_typ == "lower"))
+			{
+			  const ColumnVector perm = 
+			    ColumnVector (args (2).vector_value ());
+
+			  if (error_state)
+			    error ("matrix_type: Invalid permutation vector");
+			  else
+			    {
+			      octave_idx_type len = perm.length ();
+			      dim_vector dv = args(0).dims ();
+			      
+			      if (len != dv(0))
+				error ("matrix_type: Invalid permutation vector");
+			      else
+				{
+				  OCTAVE_LOCAL_BUFFER (octave_idx_type, p, len);
+
+				  for (octave_idx_type i = 0; i < len; i++)
+				    p[i] = static_cast<octave_idx_type> (perm (i)) - 1; 
+
+				  if (str_typ == "upper")
+				    mattyp.mark_as_permuted (len, p);
+				  else
+				    mattyp.mark_as_permuted (len, p);
+				}
+			    }
+			}
+		      else if (nargin != 2 && str_typ != "banded positive definite" &&
+			       str_typ != "banded")
+			error ("matrix_type: Invalid number of arguments");
+
+		      if (! error_state)
+			{
+			  // Set the matrix type
+			  if (args(0).is_complex_type ())
+			    retval = 
+			      octave_value (args(0).sparse_complex_matrix_value (), 
+					    mattyp);
+			  else
+			    retval = octave_value (args(0).sparse_matrix_value (), 
+						   mattyp);
+			}
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  if (nargin == 1)
+	    {
+	      MatrixType mattyp;
+
+	      if (args(0).is_complex_type ())
+		{
+		  mattyp = args(0).matrix_type ();
+
+		  if (mattyp.is_unknown ())
+		    {
+		      if (args(0).is_single_type ())
+			{
+			  FloatComplexMatrix m = args(0).float_complex_matrix_value ();
+			  if (!error_state)
+			    {
+			      mattyp = MatrixType (m);
+			      args(0).matrix_type (mattyp);
+			    }
+			}
+		      else
+			{
+			  ComplexMatrix m = args(0).complex_matrix_value ();
+			  if (!error_state)
+			    {
+			      mattyp = MatrixType (m);
+			      args(0).matrix_type (mattyp);
+			    }
+			}
+		    }
+		}
+	      else
+		{
+		  mattyp = args(0).matrix_type ();
+
+		  if (mattyp.is_unknown ())
+		    {
+		      if (args(0).is_single_type ())
+			{
+			  FloatMatrix m = args(0).float_matrix_value ();
+			  if (!error_state)
+			    {
+			      mattyp = MatrixType (m);
+			      args(0).matrix_type (mattyp);
+			    }
+			}
+		      else
+			{
+			  Matrix m = args(0).matrix_value ();
+			  if (!error_state)
+			    {
+			      mattyp = MatrixType (m);
+			      args(0).matrix_type (mattyp);
+			    }
+			}
+		    }
+		}
+
+	      int typ = mattyp.type ();
+
+	      if (typ == MatrixType::Upper)
+		retval = octave_value ("Upper");
+	      else if (typ == MatrixType::Permuted_Upper)
+		retval = octave_value ("Permuted Upper");
+	      else if (typ == MatrixType::Lower)
+		retval = octave_value ("Lower");
+	      else if (typ == MatrixType::Permuted_Lower)
+		retval = octave_value ("Permuted Lower");
+	      else if (typ == MatrixType::Hermitian)
+		retval = octave_value ("Positive Definite");
+	      else if (typ == MatrixType::Rectangular)
+		{
+		  if (args(0).rows() == args(0).columns())
+		    retval = octave_value ("Singular");
+		  else
+		    retval = octave_value ("Rectangular");
+		}
+	      else if (typ == MatrixType::Full)
+		retval = octave_value ("Full");
+	      else
+		// This should never happen!!!
+		retval = octave_value ("Unknown");
+	    }
+	  else
+	    {
+	      // Ok, we're changing the matrix type
+	      std::string str_typ = args(1).string_value ();
+
+	      // FIXME -- why do I have to explicitly call the constructor?
+	      MatrixType mattyp = MatrixType (MatrixType::Unknown, true);
+
+	      if (error_state)
+		error ("Matrix type must be a string");
+	      else
+		{
+		  // Use STL function to convert to lower case
+		  std::transform (str_typ.begin (), str_typ.end (),
+				  str_typ.begin (), tolower);
+
+		  if (str_typ == "upper")
+		    mattyp.mark_as_upper_triangular ();
+		  else if (str_typ == "lower")
+		    mattyp.mark_as_lower_triangular ();
+		  else if (str_typ == "positive definite")
+		    {
+		      mattyp.mark_as_full ();
+		      mattyp.mark_as_symmetric ();
+		    }
+		  else if (str_typ == "singular")
+		    mattyp.mark_as_rectangular ();
+		  else if (str_typ == "full")
+		    mattyp.mark_as_full ();
+		  else if (str_typ == "unknown")
+		    mattyp.invalidate_type ();
+		  else
+		    error ("matrix_type: Unknown matrix type %s", str_typ.c_str());
+
+		  if (! error_state)
+		    {
+		      if (nargin == 3 && (str_typ == "upper" 
+					  || str_typ == "lower"))
+			{
+			  const ColumnVector perm = 
+			    ColumnVector (args (2).vector_value ());
+
+			  if (error_state)
+			    error ("matrix_type: Invalid permutation vector");
+			  else
+			    {
+			      octave_idx_type len = perm.length ();
+			      dim_vector dv = args(0).dims ();
+			      
+			      if (len != dv(0))
+				error ("matrix_type: Invalid permutation vector");
+			      else
+				{
+				  OCTAVE_LOCAL_BUFFER (octave_idx_type, p, len);
+
+				  for (octave_idx_type i = 0; i < len; i++)
+				    p[i] = static_cast<octave_idx_type> (perm (i)) - 1; 
+
+				  if (str_typ == "upper")
+				    mattyp.mark_as_permuted (len, p);
+				  else
+				    mattyp.mark_as_permuted (len, p);
+				}
+			    }
+			}
+		      else if (nargin != 2)
+			error ("matrix_type: Invalid number of arguments");
+
+		      if (! error_state)
+			{
+			  // Set the matrix type
+			  if (args(0).is_single_type ())
+			    {
+			      if (args(0).is_complex_type())
+				retval = octave_value 
+				  (args(0).float_complex_matrix_value (), 
+				   mattyp);
+			      else
+				retval = octave_value 
+				  (args(0).float_matrix_value (), 
+				   mattyp);
+			    }
+			  else
+			    {
+			      if (args(0).is_complex_type())
+				retval = octave_value 
+				  (args(0).complex_matrix_value (), 
+				   mattyp);
+			      else
+				retval = octave_value 
+				  (args(0).matrix_value (), 
+				   mattyp);
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+## FIXME
+## Disable tests for lower under-determined and upper over-determined 
+## matrices as this detection is disabled in MatrixType due to issues
+## of non minimum norm solution being found.
+ 
+%!assert(matrix_type(speye(10,10)),"Diagonal");
+%!assert(matrix_type(speye(10,10)([2:10,1],:)),"Permuted Diagonal");
+%!assert(matrix_type([[speye(10,10);sparse(1,10)],[1;sparse(9,1);1]]),"Upper");
+%!assert(matrix_type([[speye(10,10);sparse(1,10)],[1;sparse(9,1);1]](:,[2,1,3:11])),"Permuted Upper");
+%!assert(matrix_type([speye(10,10),sparse(10,1);1,sparse(1,9),1]),"Lower");
+%!assert(matrix_type([speye(10,10),sparse(10,1);1,sparse(1,9),1]([2,1,3:11],:)),"Permuted Lower");
+%!test
+%! bnd=spparms("bandden");
+%! spparms("bandden",0.5);
+%! a = spdiags(rand(10,3)-0.5,[-1,0,1],10,10);
+%! assert(matrix_type(a),"Tridiagonal");
+%! assert(matrix_type(a'+a+2*speye(10)),"Tridiagonal Positive Definite");
+%! spparms("bandden",bnd);
+%!test
+%! bnd=spparms("bandden");
+%! spparms("bandden",0.5);
+%! a = spdiags(randn(10,4),[-2:1],10,10);
+%! assert(matrix_type(a),"Banded");
+%! assert(matrix_type(a'*a),"Banded Positive Definite");
+%! spparms("bandden",bnd);
+%!test
+%! a=[speye(10,10),[sparse(9,1);1];-1,sparse(1,9),1];
+%! assert(matrix_type(a),"Full");
+%! assert(matrix_type(a'*a),"Positive Definite");
+%!assert(matrix_type(speye(10,11)),"Diagonal");
+%!assert(matrix_type(speye(10,11)([2:10,1],:)),"Permuted Diagonal");
+%!assert(matrix_type(speye(11,10)),"Diagonal");
+%!assert(matrix_type(speye(11,10)([2:11,1],:)),"Permuted Diagonal");
+%#!assert(matrix_type([[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]]),"Upper");
+%#!assert(matrix_type([[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]](:,[2,1,3:12])),"Permuted Upper");
+%!assert(matrix_type([speye(11,9),[1;sparse(8,1);1;0]]),"Upper");
+%!assert(matrix_type([speye(11,9),[1;sparse(8,1);1;0]](:,[2,1,3:10])),"Permuted Upper");
+%#!assert(matrix_type([speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]]),"Lower");
+%#!assert(matrix_type([speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]]([2,1,3:12],:)),"Permuted Lower");
+%!assert(matrix_type([speye(9,11);[1,sparse(1,8),1,0]]),"Lower");
+%!assert(matrix_type([speye(9,11);[1,sparse(1,8),1,0]]([2,1,3:10],:)),"Permuted Lower");
+%!assert(matrix_type(spdiags(randn(10,4),[-2:1],10,9)),"Rectangular")
+
+%!assert(matrix_type(1i*speye(10,10)),"Diagonal");
+%!assert(matrix_type(1i*speye(10,10)([2:10,1],:)),"Permuted Diagonal");
+%!assert(matrix_type([[speye(10,10);sparse(1,10)],[1i;sparse(9,1);1]]),"Upper");
+%!assert(matrix_type([[speye(10,10);sparse(1,10)],[1i;sparse(9,1);1]](:,[2,1,3:11])),"Permuted Upper");
+%!assert(matrix_type([speye(10,10),sparse(10,1);1i,sparse(1,9),1]),"Lower");
+%!assert(matrix_type([speye(10,10),sparse(10,1);1i,sparse(1,9),1]([2,1,3:11],:)),"Permuted Lower");
+%!test
+%! bnd=spparms("bandden");
+%! spparms("bandden",0.5);
+%! assert(matrix_type(spdiags(1i*randn(10,3),[-1,0,1],10,10)),"Tridiagonal");
+%! a = 1i*(rand(9,1)-0.5);a=[[a;0],ones(10,1),[0;-a]];
+%! assert(matrix_type(spdiags(a,[-1,0,1],10,10)),"Tridiagonal Positive Definite");
+%! spparms("bandden",bnd);
+%!test
+%! bnd=spparms("bandden");
+%! spparms("bandden",0.5);
+%! assert(matrix_type(spdiags(1i*randn(10,4),[-2:1],10,10)),"Banded");
+%! a = 1i*(rand(9,2)-0.5);a=[[a;[0,0]],ones(10,1),[[0;-a(:,2)],[0;0;-a(1:8,1)]]];
+%! assert(matrix_type(spdiags(a,[-2:2],10,10)),"Banded Positive Definite");
+%! spparms("bandden",bnd);
+%!test
+%! a=[speye(10,10),[sparse(9,1);1i];-1,sparse(1,9),1];
+%! assert(matrix_type(a),"Full");
+%! assert(matrix_type(a'*a),"Positive Definite");
+%!assert(matrix_type(1i*speye(10,11)),"Diagonal");
+%!assert(matrix_type(1i*speye(10,11)([2:10,1],:)),"Permuted Diagonal");
+%!assert(matrix_type(1i*speye(11,10)),"Diagonal");
+%!assert(matrix_type(1i*speye(11,10)([2:11,1],:)),"Permuted Diagonal");
+%#!assert(matrix_type([[speye(10,10);sparse(1,10)],[[1i,1i];sparse(9,2);[1i,1i]]]),"Upper");
+%#!assert(matrix_type([[speye(10,10);sparse(1,10)],[[1i,1i];sparse(9,2);[1i,1i]]](:,[2,1,3:12])),"Permuted Upper");
+%!assert(matrix_type([speye(11,9),[1i;sparse(8,1);1i;0]]),"Upper");
+%!assert(matrix_type([speye(11,9),[1i;sparse(8,1);1i;0]](:,[2,1,3:10])),"Permuted Upper");
+%#!assert(matrix_type([speye(10,10),sparse(10,1);[1i;1i],sparse(2,9),[1i;1i]]),"Lower");
+%#!assert(matrix_type([speye(10,10),sparse(10,1);[1i;1i],sparse(2,9),[1i;1i]]([2,1,3:12],:)),"Permuted Lower");
+%!assert(matrix_type([speye(9,11);[1i,sparse(1,8),1i,0]]),"Lower");
+%!assert(matrix_type([speye(9,11);[1i,sparse(1,8),1i,0]]([2,1,3:10],:)),"Permuted Lower");
+%!assert(matrix_type(1i*spdiags(randn(10,4),[-2:1],10,9)),"Rectangular")
+
+%!test
+%! a = matrix_type(spdiags(randn(10,3),[-1,0,1],10,10),"Singular");
+%! assert(matrix_type(a),"Singular");
+
+%!assert(matrix_type(triu(ones(10,10))),"Upper");
+%!assert(matrix_type(triu(ones(10,10),-1)),"Full");
+%!assert(matrix_type(tril(ones(10,10))),"Lower");
+%!assert(matrix_type(tril(ones(10,10),1)),"Full");
+%!assert(matrix_type(10*eye(10,10) + ones(10,10)), "Positive Definite"); 
+%!assert(matrix_type(ones(11,10)),"Rectangular")
+%!test
+%! a = matrix_type(ones(10,10),"Singular");
+%! assert(matrix_type(a),"Singular");
+
+%!assert(matrix_type(triu(1i*ones(10,10))),"Upper");
+%!assert(matrix_type(triu(1i*ones(10,10),-1)),"Full");
+%!assert(matrix_type(tril(1i*ones(10,10))),"Lower");
+%!assert(matrix_type(tril(1i*ones(10,10),1)),"Full");
+%!assert(matrix_type(10*eye(10,10) + 1i*triu(ones(10,10),1) -1i*tril(ones(10,10),-1)), "Positive Definite"); 
+%!assert(matrix_type(ones(11,10)),"Rectangular")
+%!test
+%! a = matrix_type(ones(10,10),"Singular");
+%! assert(matrix_type(a),"Singular");
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/max.cc b/src/DLD-FUNCTIONS/max.cc
new file mode 100644
index 0000000..9f14365
--- /dev/null
+++ b/src/DLD-FUNCTIONS/max.cc
@@ -0,0 +1,1006 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008 John W. Eaton
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-math.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+
+#include "ov-cx-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#define MINMAX_DOUBLE_SBODY(FCN) \
+{ \
+  if (nargout == 1 || nargout == 0) \
+    { \
+      if (arg1.is_real_type ()) \
+	{ \
+	  NDArray m = arg1.array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      NDArray n = m. FCN (dim); \
+	      retval(0) = n; \
+	    } \
+	} \
+      else if (arg1.is_complex_type ()) \
+	{ \
+	  ComplexNDArray m = arg1.complex_array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      ComplexNDArray n = m. FCN (dim); \
+	      retval(0) = n; \
+	    } \
+	} \
+      else \
+	gripe_wrong_type_arg (#FCN, arg1); \
+    } \
+  else if (nargout == 2) \
+    { \
+      ArrayN<octave_idx_type> index; \
+ \
+      if (arg1.is_real_type ()) \
+	{ \
+	  NDArray m = arg1.array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      NDArray n = m. FCN (index, dim);	\
+	      retval(0) = n; \
+	    } \
+	} \
+      else if (arg1.is_complex_type ()) \
+	{ \
+	  ComplexNDArray m = arg1.complex_array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      ComplexNDArray n = m. FCN (index, dim);	\
+	      retval(0) = n; \
+	    } \
+	} \
+      else \
+	gripe_wrong_type_arg (#FCN, arg1); \
+ \
+      octave_idx_type len = index.numel (); \
+ \
+      if (len > 0) \
+	retval(1) = NDArray (index, true, true);	\
+      else \
+	retval(1) = NDArray (); \
+    } \
+}
+
+#define MINMAX_DOUBLE_BODY(FCN) \
+{ \
+  bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3);	\
+  if (single_arg) \
+    MINMAX_DOUBLE_SBODY (FCN) \
+  else \
+    { \
+      int arg1_is_scalar = arg1.is_scalar_type (); \
+      int arg2_is_scalar = arg2.is_scalar_type (); \
+ \
+      int arg1_is_complex = arg1.is_complex_type (); \
+      int arg2_is_complex = arg2.is_complex_type (); \
+ \
+      if (arg1_is_scalar) \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      Complex c1 = arg1.complex_value (); \
+	      ComplexNDArray m2 = arg2.complex_array_value (); \
+	      if (! error_state) \
+		{ \
+		  ComplexNDArray result = FCN (c1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	  else \
+	    { \
+	      double d1 = arg1.double_value (); \
+	      NDArray m2 = arg2.array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  NDArray result = FCN (d1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+      else if (arg2_is_scalar) \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      ComplexNDArray m1 = arg1.complex_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  Complex c2 = arg2.complex_value (); \
+		  ComplexNDArray result = FCN (m1, c2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	  else \
+	    { \
+	      NDArray m1 = arg1.array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  double d2 = arg2.double_value (); \
+		  NDArray result = FCN (m1, d2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+      else \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      ComplexNDArray m1 = arg1.complex_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  ComplexNDArray m2 = arg2.complex_array_value (); \
+ \
+		  if (! error_state) \
+		    { \
+		      ComplexNDArray result = FCN (m1, m2); \
+		      if (! error_state) \
+			retval(0) = result; \
+		    } \
+		} \
+	    } \
+	  else \
+	    { \
+	      NDArray m1 = arg1.array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  NDArray m2 = arg2.array_value (); \
+ \
+		  if (! error_state) \
+		    { \
+		      NDArray result = FCN (m1, m2); \
+		      if (! error_state) \
+			retval(0) = result; \
+		    } \
+		} \
+	    } \
+	} \
+    } \
+}
+
+#define MINMAX_SINGLE_SBODY(FCN) \
+{ \
+  if (nargout == 1 || nargout == 0) \
+    { \
+      if (arg1.is_real_type ()) \
+	{ \
+	  FloatNDArray m = arg1.float_array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      FloatNDArray n = m. FCN (dim); \
+	      retval(0) = n; \
+	    } \
+	} \
+      else if (arg1.is_complex_type ()) \
+	{ \
+	  FloatComplexNDArray m = arg1.float_complex_array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      FloatComplexNDArray n = m. FCN (dim); \
+	      retval(0) = n; \
+	    } \
+	} \
+      else \
+	gripe_wrong_type_arg (#FCN, arg1); \
+    } \
+  else if (nargout == 2) \
+    { \
+      ArrayN<octave_idx_type> index; \
+ \
+      if (arg1.is_real_type ()) \
+	{ \
+	  FloatNDArray m = arg1.float_array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      FloatNDArray n = m. FCN (index, dim);	\
+	      retval(0) = n; \
+	    } \
+	} \
+      else if (arg1.is_complex_type ()) \
+	{ \
+	  FloatComplexNDArray m = arg1.float_complex_array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      FloatComplexNDArray n = m. FCN (index, dim);	\
+	      retval(0) = n; \
+	    } \
+	} \
+      else \
+	gripe_wrong_type_arg (#FCN, arg1); \
+ \
+      octave_idx_type len = index.numel (); \
+ \
+      if (len > 0) \
+	retval(1) = NDArray (index, true, true);	\
+      else \
+	retval(1) = NDArray (); \
+    } \
+}
+
+#define MINMAX_SINGLE_BODY(FCN) \
+{ \
+  bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3);	\
+  if (single_arg) \
+    MINMAX_SINGLE_SBODY(FCN) \
+  else \
+    { \
+      int arg1_is_scalar = arg1.is_scalar_type (); \
+      int arg2_is_scalar = arg2.is_scalar_type (); \
+ \
+      int arg1_is_complex = arg1.is_complex_type (); \
+      int arg2_is_complex = arg2.is_complex_type (); \
+ \
+      if (arg1_is_scalar) \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      FloatComplex c1 = arg1.float_complex_value (); \
+	      FloatComplexNDArray m2 = arg2.float_complex_array_value (); \
+	      if (! error_state) \
+		{ \
+		  FloatComplexNDArray result = FCN (c1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	  else \
+	    { \
+	      float d1 = arg1.float_value (); \
+	      FloatNDArray m2 = arg2.float_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  FloatNDArray result = FCN (d1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+      else if (arg2_is_scalar) \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      FloatComplexNDArray m1 = arg1.float_complex_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  FloatComplex c2 = arg2.float_complex_value (); \
+		  FloatComplexNDArray result = FCN (m1, c2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	  else \
+	    { \
+	      FloatNDArray m1 = arg1.float_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  float d2 = arg2.float_value (); \
+		  FloatNDArray result = FCN (m1, d2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+      else \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      FloatComplexNDArray m1 = arg1.float_complex_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  FloatComplexNDArray m2 = arg2.float_complex_array_value (); \
+ \
+		  if (! error_state) \
+		    { \
+		      FloatComplexNDArray result = FCN (m1, m2); \
+		      if (! error_state) \
+			retval(0) = result; \
+		    } \
+		} \
+	    } \
+	  else \
+	    { \
+	      FloatNDArray m1 = arg1.float_array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  FloatNDArray m2 = arg2.float_array_value (); \
+ \
+		  if (! error_state) \
+		    { \
+		      FloatNDArray result = FCN (m1, m2); \
+		      if (! error_state) \
+			retval(0) = result; \
+		    } \
+		} \
+	    } \
+	} \
+    } \
+}
+
+#define MINMAX_INT_SBODY(FCN, TYP) \
+{ \
+  if (nargout == 1 || nargout == 0) \
+    { \
+      TYP ## NDArray m = arg1. TYP ## _array_value (); \
+ \
+      if (! error_state) \
+	{ \
+	  TYP ## NDArray n = m. FCN (dim); \
+	  retval(0) = n; \
+	} \
+    } \
+  else if (nargout == 2) \
+    { \
+      ArrayN<octave_idx_type> index; \
+ \
+      TYP ## NDArray m = arg1. TYP ## _array_value (); \
+ \
+      if (! error_state) \
+        { \
+	  TYP ## NDArray n = m. FCN (index, dim);	\
+	  retval(0) = n; \
+	} \
+ \
+      octave_idx_type len = index.numel (); \
+ \
+      if (len > 0) \
+	retval(1) = NDArray (index, true, true);	\
+      else \
+	retval(1) = NDArray (); \
+    } \
+}
+
+#define MINMAX_INT_BODY(FCN, TYP) \
+ { \
+  bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3);	\
+  if (single_arg) \
+    MINMAX_INT_SBODY (FCN, TYP) \
+  else \
+    { \
+      int arg1_is_scalar = arg1.is_scalar_type (); \
+      int arg2_is_scalar = arg2.is_scalar_type (); \
+ \
+      if (arg1_is_scalar) \
+	{ \
+	  octave_ ## TYP d1 = arg1. TYP ## _scalar_value (); \
+	  TYP ## NDArray m2 = arg2. TYP ## _array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      TYP ## NDArray result = FCN (d1, m2); \
+	      if (! error_state) \
+		retval(0) = result; \
+	    } \
+	} \
+      else if (arg2_is_scalar) \
+	{ \
+	  TYP ## NDArray m1 = arg1. TYP ## _array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      octave_ ## TYP d2 = arg2. TYP ## _scalar_value (); \
+	      TYP ## NDArray result = FCN (m1, d2); \
+	      if (! error_state) \
+		retval(0) = result; \
+	    } \
+	} \
+      else \
+	{ \
+	  TYP ## NDArray m1 = arg1. TYP ## _array_value (); \
+ \
+	  if (! error_state) \
+	    { \
+	      TYP ## NDArray m2 = arg2. TYP ## _array_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  TYP ## NDArray result = FCN (m1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+    } \
+}
+
+#define MINMAX_SPARSE_BODY(FCN) \
+{ \
+  bool single_arg = (nargin == 1) || arg2.is_empty();	\
+ \
+  if (single_arg && (nargout == 1 || nargout == 0)) \
+    { \
+      if (arg1.is_real_type ()) \
+	retval(0) = arg1.sparse_matrix_value () .FCN (dim); \
+      else if (arg1.is_complex_type ()) \
+	retval(0) = arg1.sparse_complex_matrix_value () .FCN (dim); \
+      else \
+	gripe_wrong_type_arg (#FCN, arg1); \
+    } \
+  else if (single_arg && nargout == 2) \
+    { \
+      Array2<octave_idx_type> index; \
+ \
+      if (arg1.is_real_type ()) \
+	retval(0) = arg1.sparse_matrix_value () .FCN (index, dim); \
+      else if (arg1.is_complex_type ()) \
+	retval(0) = arg1.sparse_complex_matrix_value () .FCN (index, dim); \
+      else \
+	gripe_wrong_type_arg (#FCN, arg1); \
+ \
+      octave_idx_type len = index.numel (); \
+ \
+      if (len > 0) \
+	retval(1) = NDArray (index, true, true);	\
+      else \
+	retval(1) = NDArray (); \
+    } \
+  else \
+    { \
+      int arg1_is_scalar = arg1.is_scalar_type (); \
+      int arg2_is_scalar = arg2.is_scalar_type (); \
+ \
+      int arg1_is_complex = arg1.is_complex_type (); \
+      int arg2_is_complex = arg2.is_complex_type (); \
+ \
+      if (arg1_is_scalar) \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      Complex c1 = arg1.complex_value (); \
+	      \
+	      SparseComplexMatrix m2 = arg2.sparse_complex_matrix_value (); \
+	      \
+	      if (! error_state) \
+		{ \
+		  SparseComplexMatrix result = FCN (c1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	  else \
+	    { \
+	      double d1 = arg1.double_value (); \
+	      SparseMatrix m2 = arg2.sparse_matrix_value (); \
+	      \
+	      if (! error_state) \
+		{ \
+		  SparseMatrix result = FCN (d1, m2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+      else if (arg2_is_scalar) \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      SparseComplexMatrix m1 = arg1.sparse_complex_matrix_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  Complex c2 = arg2.complex_value (); \
+		  SparseComplexMatrix result = FCN (m1, c2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	  else \
+	    { \
+	      SparseMatrix m1 = arg1.sparse_matrix_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  double d2 = arg2.double_value (); \
+		  SparseMatrix result = FCN (m1, d2); \
+		  if (! error_state) \
+		    retval(0) = result; \
+		} \
+	    } \
+	} \
+      else \
+	{ \
+	  if (arg1_is_complex || arg2_is_complex) \
+	    { \
+	      SparseComplexMatrix m1 = arg1.sparse_complex_matrix_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  SparseComplexMatrix m2 = arg2.sparse_complex_matrix_value (); \
+ \
+		  if (! error_state) \
+		    { \
+		      SparseComplexMatrix result = FCN (m1, m2); \
+		      if (! error_state) \
+			retval(0) = result; \
+		    } \
+		} \
+	    } \
+	  else \
+	    { \
+	      SparseMatrix m1 = arg1.sparse_matrix_value (); \
+ \
+	      if (! error_state) \
+		{ \
+		  SparseMatrix m2 = arg2.sparse_matrix_value (); \
+ \
+		  if (! error_state) \
+		    { \
+		      SparseMatrix result = FCN (m1, m2); \
+		      if (! error_state) \
+			retval(0) = result; \
+		    } \
+		} \
+	    } \
+	} \
+    } \
+}
+
+
+#define MINMAX_BODY(FCN) \
+ \
+  octave_value_list retval;  \
+ \
+  int nargin = args.length (); \
+ \
+  if (nargin < 1 || nargin > 3 || nargout > 2) \
+    { \
+      print_usage (); \
+      return retval; \
+    } \
+ \
+  octave_value arg1; \
+  octave_value arg2; \
+  octave_value arg3; \
+ \
+  switch (nargin) \
+    { \
+    case 3: \
+      arg3 = args(2); \
+ \
+    case 2: \
+      arg2 = args(1); \
+ \
+    case 1: \
+      arg1 = args(0); \
+      break; \
+ \
+    default: \
+      panic_impossible (); \
+      break; \
+    } \
+ \
+  int dim; \
+  dim_vector dv = arg1.dims (); \
+  if (error_state) \
+    { \
+      gripe_wrong_type_arg (#FCN, arg1);  \
+      return retval; \
+    } \
+ \
+  if (nargin == 3) \
+    { \
+      dim = arg3.nint_value () - 1;  \
+      if (dim < 0 || dim >= dv.length ()) \
+        { \
+	  error ("%s: invalid dimension", #FCN); \
+	  return retval; \
+	} \
+    } \
+  else \
+    { \
+      dim = 0; \
+      while ((dim < dv.length ()) && (dv (dim) <= 1)) \
+	dim++; \
+      if (dim == dv.length ()) \
+	dim = 0; \
+    } \
+ \
+  if (arg1.is_integer_type ()) \
+    { \
+      if (arg1.is_uint8_type ()) \
+        MINMAX_INT_BODY (FCN, uint8) \
+      else if (arg1.is_uint16_type ()) \
+        MINMAX_INT_BODY (FCN, uint16) \
+      else if (arg1.is_uint32_type ()) \
+        MINMAX_INT_BODY (FCN, uint32) \
+      else if (arg1.is_uint64_type ()) \
+        MINMAX_INT_BODY (FCN, uint64) \
+      else if (arg1.is_int8_type ()) \
+        MINMAX_INT_BODY (FCN, int8) \
+      else if (arg1.is_int16_type ()) \
+        MINMAX_INT_BODY (FCN, int16) \
+      else if (arg1.is_int32_type ()) \
+        MINMAX_INT_BODY (FCN, int32) \
+      else if (arg1.is_int64_type ()) \
+        MINMAX_INT_BODY (FCN, int64) \
+    } \
+  else if (arg1.is_sparse_type ()) \
+    MINMAX_SPARSE_BODY (FCN) \
+  else if (arg1.is_single_type ()) \
+    MINMAX_SINGLE_BODY (FCN) \
+  else \
+    MINMAX_DOUBLE_BODY (FCN) \
+ \
+ return retval;
+
+DEFUN_DLD (min, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {} min (@var{x})\n\
+ at deftypefnx {Loadable Function} {} min (@var{x}, @var{y})\n\
+ at deftypefnx {Loadable Function} {} min (@var{x}, @var{y}, @var{dim})\n\
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} min (@var{x})\n\
+For a vector argument, return the minimum value.  For a matrix\n\
+argument, return the minimum value from each column, as a row\n\
+vector, or over the dimension @var{dim} if defined.  For two matrices\n\
+(or a matrix and scalar), return the pair-wise minimum.\n\
+Thus,\n\
+\n\
+ at example\n\
+min (min (@var{x}))\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns the smallest element of @var{x}, and\n\
+\n\
+ at example\n\
+ at group\n\
+min (2:5, pi)\n\
+    @result{}  2.0000  3.0000  3.1416  3.1416\n\
+ at end group\n\
+ at end example\n\
+ at noindent\n\
+compares each element of the range @code{2:5} with @code{pi}, and\n\
+returns a row vector of the minimum values.\n\
+\n\
+For complex arguments, the magnitude of the elements are used for\n\
+comparison.\n\
+\n\
+If called with one input and two output arguments,\n\
+ at code{min} also returns the first index of the\n\
+minimum value(s).  Thus,\n\
+\n\
+ at example\n\
+ at group\n\
+[x, ix] = min ([1, 3, 0, 2, 0])\n\
+    @result{}  x = 0\n\
+        ix = 3\n\
+ at end group\n\
+ at end example\n\
+ at seealso{max, cummin, cummax}\n\
+ at end deftypefn")
+{
+  MINMAX_BODY (min);
+}
+
+/*
+
+%% test/octave.test/arith/min-1.m
+%!assert (min ([1, 4, 2, 3]) == 1);
+%!assert (min ([1; -10; 5; -2]) == -10);
+
+%% test/octave.test/arith/min-2.m
+%!assert(all (min ([4, i; -2, 2]) == [-2, i]));
+
+%% test/octave.test/arith/min-3.m
+%!error <Invalid call to min.*> min ();
+
+%% test/octave.test/arith/min-4.m
+%!error <Invalid call to min.*> min (1, 2, 3, 4);
+
+%!test
+%! x = reshape (1:8,[2,2,2]);
+%! assert (max (x,[],1), reshape ([2, 4, 6, 8], [1,2,2]));
+%! assert (max (x,[],2), reshape ([3, 4, 7, 8], [2,1,2]));
+%! [y, i ] = max (x, [], 3);
+%! assert (y, [5, 7; 6, 8]);
+%! assert (ndims(y), 2);
+%! assert (i, [2, 2; 2, 2]);
+%! assert (ndims(i), 2);
+
+*/
+
+DEFUN_DLD (max, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {} max (@var{x})\n\
+ at deftypefnx {Loadable Function} {} max (@var{x}, @var{y})\n\
+ at deftypefnx {Loadable Function} {} max (@var{x}, @var{y}, @var{dim})\n\
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} max (@var{x})\n\
+For a vector argument, return the maximum value.  For a matrix\n\
+argument, return the maximum value from each column, as a row\n\
+vector, or over the dimension @var{dim} if defined.  For two matrices\n\
+(or a matrix and scalar), return the pair-wise maximum.\n\
+Thus,\n\
+\n\
+ at example\n\
+max (max (@var{x}))\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns the largest element of the matrix @var{x}, and\n\
+\n\
+ at example\n\
+ at group\n\
+max (2:5, pi)\n\
+    @result{}  3.1416  3.1416  4.0000  5.0000\n\
+ at end group\n\
+ at end example\n\
+ at noindent\n\
+compares each element of the range @code{2:5} with @code{pi}, and\n\
+returns a row vector of the maximum values.\n\
+\n\
+For complex arguments, the magnitude of the elements are used for\n\
+comparison.\n\
+\n\
+If called with one input and two output arguments,\n\
+ at code{max} also returns the first index of the\n\
+maximum value(s).  Thus,\n\
+\n\
+ at example\n\
+ at group\n\
+[x, ix] = max ([1, 3, 5, 2, 5])\n\
+    @result{}  x = 5\n\
+        ix = 3\n\
+ at end group\n\
+ at end example\n\
+ at seealso{min, cummax, cummin}\n\
+ at end deftypefn")
+{
+  MINMAX_BODY (max);
+}
+
+/* 
+
+%% test/octave.test/arith/max-1.m
+%!assert (max ([1, 4, 2, 3]) == 4);
+%!assert (max ([1; -10; 5; -2]) == 5);
+ 
+%% test/octave.test/arith/max-2.m
+%!assert(all (max ([4, i 4.999; -2, 2, 3+4i]) == [4, 2, 3+4i]));
+
+%% test/octave.test/arith/max-3.m
+%!error <Invalid call to max.*> max ();
+
+%% test/octave.test/arith/max-4.m
+%!error <Invalid call to max.*> max (1, 2, 3, 4);
+
+%!test
+%! x = reshape (1:8,[2,2,2]);
+%! assert (min (x,[],1), reshape ([1, 3, 5, 7], [1,2,2]));
+%! assert (min (x,[],2), reshape ([1, 2, 5, 6], [2,1,2]));
+%! [y, i ] = min (x, [], 3);
+%! assert (y, [1, 3; 2, 4]);
+%! assert (ndims(y), 2);
+%! assert (i, [1, 1; 1, 1]);
+%! assert (ndims(i), 2);
+
+
+*/
+
+#define CUMMINMAX_BODY(FCN) \
+ \
+  octave_value_list retval;  \
+ \
+  int nargin = args.length (); \
+ \
+  if (nargin < 1 || nargin > 2 || nargout > 2) \
+    { \
+      print_usage (); \
+      return retval; \
+    } \
+ \
+  octave_value arg1; \
+  octave_value arg2; \
+ \
+  switch (nargin) \
+    { \
+    case 2: \
+      arg2 = args(1); \
+ \
+    case 1: \
+      arg1 = args(0); \
+      break; \
+ \
+    default: \
+      panic_impossible (); \
+      break; \
+    } \
+ \
+  int dim; \
+  dim_vector dv = arg1.dims (); \
+  if (error_state) \
+    { \
+      gripe_wrong_type_arg (#FCN, arg1);  \
+      return retval; \
+    } \
+ \
+  if (nargin == 2) \
+    { \
+      dim = arg2.nint_value () - 1;  \
+      if (dim < 0 || dim >= dv.length ()) \
+        { \
+	  error ("%s: invalid dimension", #FCN); \
+	  return retval; \
+	} \
+    } \
+  else \
+    { \
+      dim = 0; \
+      while ((dim < dv.length ()) && (dv (dim) <= 1)) \
+	dim++; \
+      if (dim == dv.length ()) \
+	dim = 0; \
+    } \
+ \
+  if (arg1.is_integer_type ()) \
+    { \
+      if (arg1.is_uint8_type ()) \
+        MINMAX_INT_SBODY (FCN, uint8) \
+      else if (arg1.is_uint16_type ()) \
+        MINMAX_INT_SBODY (FCN, uint16) \
+      else if (arg1.is_uint32_type ()) \
+        MINMAX_INT_SBODY (FCN, uint32) \
+      else if (arg1.is_uint64_type ()) \
+        MINMAX_INT_SBODY (FCN, uint64) \
+      else if (arg1.is_int8_type ()) \
+        MINMAX_INT_SBODY (FCN, int8) \
+      else if (arg1.is_int16_type ()) \
+        MINMAX_INT_SBODY (FCN, int16) \
+      else if (arg1.is_int32_type ()) \
+        MINMAX_INT_SBODY (FCN, int32) \
+      else if (arg1.is_int64_type ()) \
+        MINMAX_INT_SBODY (FCN, int64) \
+    } \
+  else if (arg1.is_single_type ()) \
+    MINMAX_SINGLE_SBODY (FCN) \
+  else \
+    MINMAX_DOUBLE_SBODY (FCN) \
+ \
+ return retval;
+
+DEFUN_DLD (cummin, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {} cummin (@var{x})\n\
+ at deftypefnx {Loadable Function} {} cummin (@var{x}, @var{dim})\n\
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} cummin (@var{x})\n\
+Return the cumulative minimum values along dimension @var{dim}.  If @var{dim}\n\
+is unspecified it defaults to column-wise operation.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+cummin ([5 4 6 2 3 1])\n\
+    @result{}  5  4  4  2  2  1\n\
+ at end group\n\
+ at end example\n\
+\n\
+\n\
+The call\n\
+ at example\n\
+  [w, iw] = cummin (x, dim)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+is equivalent to the following code:\n\
+ at example\n\
+ at group\n\
+w = iw = zeros (size (x));\n\
+idxw = idxx = repmat (@{':'@}, 1, ndims (x));\n\
+for i = 1:size (x, dim)\n\
+  idxw@{dim@} = i; idxx@{dim@} = 1:i;\n\
+  [w(idxw@{:@}), iw(idxw@{:@})] = min(x(idxx@{:@}), [], dim);\n\
+endfor\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+but computed in a much faster manner.\n\
+ at seealso{cummax, min, max}\n\
+ at end deftypefn")
+{
+  CUMMINMAX_BODY (cummin);
+}
+
+DEFUN_DLD (cummax, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Loadable Function} {} cummax (@var{x})\n\
+ at deftypefnx {Loadable Function} {} cummax (@var{x}, @var{dim})\n\
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} cummax (@var{x})\n\
+Return the cumulative maximum values along dimension @var{dim}.  If @var{dim}\n\
+is unspecified it defaults to column-wise operation.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+cummax ([1 3 2 6 4 5])\n\
+    @result{}  1  3  3  6  6  6\n\
+ at end group\n\
+ at end example\n\
+\n\
+The call\n\
+ at example\n\
+[w, iw] = cummax (x, dim)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+is equivalent to the following code:\n\
+ at example\n\
+ at group\n\
+w = iw = zeros (size (x));\n\
+idxw = idxx = repmat (@{':'@}, 1, ndims (x));\n\
+for i = 1:size (x, dim)\n\
+  idxw@{dim@} = i; idxx@{dim@} = 1:i;\n\
+  [w(idxw@{:@}), iw(idxw@{:@})] = max(x(idxx@{:@}), [], dim);\n\
+endfor\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+but computed in a much faster manner.\n\
+ at seealso{cummin, max, min}\n\
+ at end deftypefn")
+{
+  CUMMINMAX_BODY (cummax);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/md5sum.cc b/src/DLD-FUNCTIONS/md5sum.cc
new file mode 100644
index 0000000..31d73f1
--- /dev/null
+++ b/src/DLD-FUNCTIONS/md5sum.cc
@@ -0,0 +1,88 @@
+/*
+
+Copyright (C) 2007, 2009 David Bateman
+
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <string>
+#include <vector>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "defun-dld.h"
+#include "file-stat.h"
+#include "file-ops.h"
+#include "gripes.h"
+#include "load-path.h"
+#include "oct-env.h"
+#include "oct-md5.h"
+
+DEFUN_DLD (md5sum, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} md5sum (@var{file})\n\
+ at deftypefnx {Loadable Function} {} md5sum (@var{str}, @var{opt})\n\
+Calculates the MD5 sum of the file @var{file}.  If the second parameter\n\
+ at var{opt} exists and is true, then calculate the MD5 sum of the\n\
+string @var{str}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin != 1 && nargin != 2)
+    print_usage();
+  else
+    {
+      bool have_str = false;
+      std::string str = args(0).string_value();
+
+      if (nargin == 2)
+	have_str = args(1).bool_value();
+	
+      if (!error_state)
+	{
+	  if (have_str)
+	    retval = oct_md5 (str);
+	  else
+	    {
+	      file_stat fs (str);
+
+	      if (! fs.exists ())
+		{
+		  std::string tmp = octave_env::make_absolute
+		    (load_path::find_file (str), octave_env::getcwd ());
+
+		  if (! tmp.empty ())
+		    {
+		      warning_with_id ("Octave:md5sum-file-in-path",
+				       "md5sum: file found in load path");
+		      str = tmp;
+		    }
+		}
+
+	      retval = oct_md5_file (str);
+	    }
+	}
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/pinv.cc b/src/DLD-FUNCTIONS/pinv.cc
new file mode 100644
index 0000000..a7f7ae1
--- /dev/null
+++ b/src/DLD-FUNCTIONS/pinv.cc
@@ -0,0 +1,177 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2002, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "ops.h"
+#include "ov-re-diag.h"
+#include "ov-cx-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-perm.h"
+
+DEFUN_DLD (pinv, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} pinv (@var{x}, @var{tol})\n\
+Return the pseudoinverse of @var{x}.  Singular values less than\n\
+ at var{tol} are ignored.  \n\
+\n\
+If the second argument is omitted, it is assumed that\n\
+\n\
+ at example\n\
+tol = max (size (@var{x})) * sigma_max (@var{x}) * eps,\n\
+ at end example\n\
+\n\
+ at noindent\n\
+where @code{sigma_max (@var{x})} is the maximal singular value of @var{x}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  int arg_is_empty = empty_arg ("pinv", arg.rows (), arg.columns ());
+
+  if (arg_is_empty < 0)
+    return retval;
+  else if (arg_is_empty > 0)
+    return octave_value (Matrix ());
+
+  bool isfloat = arg.is_single_type ();
+
+  if (arg.is_diag_matrix ())
+    {
+      if (nargin == 2)
+        warning ("pinv: tol is ignored for diagonal matrices");
+
+      if (arg.is_complex_type ())
+        {
+          if (isfloat)
+            retval = arg.float_complex_diag_matrix_value ().pseudo_inverse ();
+          else
+            retval = arg.complex_diag_matrix_value ().pseudo_inverse ();
+        }
+      else
+        {
+          if (isfloat)
+            retval = arg.float_diag_matrix_value ().pseudo_inverse ();
+          else
+            retval = arg.diag_matrix_value ().pseudo_inverse ();
+        }
+    }
+  else if (arg.is_perm_matrix ())
+    {
+      retval = arg.perm_matrix_value ().inverse ();
+    }
+  else if (isfloat)
+    {
+      float tol = 0.0;
+      if (nargin == 2)
+	tol = args(1).float_value ();
+
+      if (error_state)
+	return retval;
+
+      if (tol < 0.0)
+	{
+	  error ("pinv: tol must be greater than zero");
+	  return retval;
+	}
+
+      if (arg.is_real_type ())
+	{
+	  FloatMatrix m = arg.float_matrix_value ();
+
+	  if (! error_state)
+	    retval = m.pseudo_inverse (tol);
+	}
+      else if (arg.is_complex_type ())
+	{
+	  FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+	  if (! error_state)
+	    retval = m.pseudo_inverse (tol);
+	}
+      else
+	{
+	  gripe_wrong_type_arg ("pinv", arg);
+	}
+    }
+  else
+    {
+      double tol = 0.0;
+      if (nargin == 2)
+	tol = args(1).double_value ();
+
+      if (error_state)
+	return retval;
+
+      if (tol < 0.0)
+	{
+	  error ("pinv: tol must be greater than zero");
+	  return retval;
+	}
+
+      if (arg.is_real_type ())
+	{
+	  Matrix m = arg.matrix_value ();
+
+	  if (! error_state)
+	    retval = m.pseudo_inverse (tol);
+	}
+      else if (arg.is_complex_type ())
+	{
+	  ComplexMatrix m = arg.complex_matrix_value ();
+
+	  if (! error_state)
+	    retval = m.pseudo_inverse (tol);
+	}
+      else
+	{
+	  gripe_wrong_type_arg ("pinv", arg);
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/qr.cc b/src/DLD-FUNCTIONS/qr.cc
new file mode 100644
index 0000000..661a6f2
--- /dev/null
+++ b/src/DLD-FUNCTIONS/qr.cc
@@ -0,0 +1,1614 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2005, 2006, 2007 John W. Eaton
+Copyright (C) 2008, 2009 Jaroslav Hajek
+Copyright (C) 2008, 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxQR.h"
+#include "CmplxQRP.h"
+#include "dbleQR.h"
+#include "dbleQRP.h"
+#include "fCmplxQR.h"
+#include "fCmplxQRP.h"
+#include "floatQR.h"
+#include "floatQRP.h"
+#include "SparseQR.h"
+#include "SparseCmplxQR.h"
+
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+template <class MT>
+static octave_value
+maybe_set_triangular (const MT& m, MatrixType::matrix_type t = MatrixType::Upper)
+{
+  typedef typename MT::element_type T;
+  octave_value retval;
+  octave_idx_type r = m.rows (), c = m.columns ();
+  if (r == c)
+    {
+      const T zero = T();
+      octave_idx_type i = 0;
+      for (;i != r && m(i,i) != zero; i++) ;
+      if (i == r)
+        retval = octave_value (m, MatrixType (t));
+      else
+        retval = m;
+    }
+  else
+    retval = m;
+
+  return retval;
+}
+
+// [Q, R] = qr (X):      form Q unitary and R upper triangular such
+//                        that Q * R = X
+//
+// [Q, R] = qr (X, 0):    form the economy decomposition such that if X is
+//                        m by n then only the first n columns of Q are
+//                        computed.
+//
+// [Q, R, P] = qr (X):    form QRP factorization of X where
+//                        P is a permutation matrix such that
+//                        A * P = Q * R
+//
+// [Q, R, P] = qr (X, 0): form the economy decomposition with
+//                        permutation vector P such that Q * R = X (:, P)
+//
+// qr (X) alone returns the output of the LAPACK routine dgeqrf, such
+// that R = triu (qr (X))
+
+DEFUN_DLD (qr, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{q}, @var{r}, @var{p}] =} qr (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{q}, @var{r}, @var{p}] =} qr (@var{a}, '0')\n\
+ at cindex QR factorization\n\
+Compute the QR factorization of @var{a}, using standard @sc{lapack}\n\
+subroutines.  For example, given the matrix @code{a = [1, 2; 3, 4]},\n\
+\n\
+ at example\n\
+[q, r] = qr (a)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns\n\
+\n\
+ at example\n\
+ at group\n\
+q =\n\
+\n\
+  -0.31623  -0.94868\n\
+  -0.94868   0.31623\n\
+\n\
+r =\n\
+\n\
+  -3.16228  -4.42719\n\
+   0.00000  -0.63246\n\
+ at end group\n\
+ at end example\n\
+\n\
+The @code{qr} factorization has applications in the solution of least\n\
+squares problems\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+\\min_x \\left\\Vert A x - b \\right\\Vert_2\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at code{min norm(A x - b)}\n\
+ at end example\n\
+\n\
+ at end ifnottex\n\
+for overdetermined systems of equations (i.e.,\n\
+ at iftex\n\
+ at tex\n\
+$A$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{a}\n\
+ at end ifnottex\n\
+ is a tall, thin matrix).  The QR factorization is\n\
+ at iftex\n\
+ at tex\n\
+$QR = A$ where $Q$ is an orthogonal matrix and $R$ is upper triangular.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{q * r = a} where @code{q} is an orthogonal matrix and @code{r} is\n\
+upper triangular.\n\
+ at end ifnottex\n\
+\n\
+If given a second argument of '0', @code{qr} returns an economy-sized\n\
+QR factorization, omitting zero rows of @var{R} and the corresponding\n\
+columns of @var{Q}.\n\
+\n\
+If the matrix @var{a} is full, the permuted QR factorization\n\
+ at code{[@var{q}, @var{r}, @var{p}] = qr (@var{a})} forms the QR factorization\n\
+such that the diagonal entries of @code{r} are decreasing in magnitude\n\
+order.  For example,given the matrix @code{a = [1, 2; 3, 4]},\n\
+\n\
+ at example\n\
+[q, r, p] = qr(a)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns\n\
+\n\
+ at example\n\
+ at group\n\
+q = \n\
+\n\
+  -0.44721  -0.89443\n\
+  -0.89443   0.44721\n\
+\n\
+r =\n\
+\n\
+  -4.47214  -3.13050\n\
+   0.00000   0.44721\n\
+\n\
+p =\n\
+\n\
+   0  1\n\
+   1  0\n\
+ at end group\n\
+ at end example\n\
+\n\
+The permuted @code{qr} factorization @code{[q, r, p] = qr (a)}\n\
+factorization allows the construction of an orthogonal basis of\n\
+ at code{span (a)}.\n\
+\n\
+If the matrix @var{a} is sparse, then compute the sparse QR factorization\n\
+of @var{a}, using @sc{CSparse}.  As the matrix @var{Q} is in general a full\n\
+matrix, this function returns the @var{Q}-less factorization @var{r} of\n\
+ at var{a}, such that @code{@var{r} = chol (@var{a}' * @var{a})}.\n\
+\n\
+If the final argument is the scalar @code{0} and the number of rows is\n\
+larger than the number of columns, then an economy factorization is\n\
+returned.  That is @var{r} will have only @code{size (@var{a},1)} rows.\n\
+\n\
+If an additional matrix @var{b} is supplied, then @code{qr} returns\n\
+ at var{c}, where @code{@var{c} = @var{q}' * @var{b}}.  This allows the\n\
+least squares approximation of @code{@var{a} \\ @var{b}} to be calculated\n\
+as\n\
+\n\
+ at example\n\
+ at group\n\
+[@var{c}, at var{r}] = spqr (@var{a}, at var{b})\n\
+ at var{x} = @var{r} \\ @var{c}\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > (args(0).is_sparse_type() ? 3 : 2))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  int arg_is_empty = empty_arg ("qr", arg.rows (), arg.columns ());
+
+  if (arg_is_empty < 0)
+    return retval;
+
+  if (arg.is_sparse_type ())
+    {
+      bool economy = false;
+      bool is_cmplx = false;
+      int have_b = 0;
+
+      if (arg.is_complex_type ())
+	is_cmplx = true;
+      if (nargin > 1)
+	{
+	  have_b = 1;
+	  if (args(nargin-1).is_scalar_type ())
+	    {
+	      int val = args(nargin-1).int_value ();
+	      if (val == 0)
+		{
+		  economy = true;
+		  have_b = (nargin > 2 ? 2 : 0);
+		}
+	    }
+	  if (have_b > 0 && args(have_b).is_complex_type ())
+	    is_cmplx = true;
+	}
+	
+      if (!error_state)
+	{
+	  if (have_b && nargout < 2)
+	    error ("qr: incorrect number of output arguments");
+	  else if (is_cmplx)
+	    {
+	      SparseComplexQR q (arg.sparse_complex_matrix_value ());
+	      if (!error_state)
+		{
+		  if (have_b > 0)
+		    {
+		      retval(1) = q.R (economy);
+		      retval(0) = q.C (args(have_b).complex_matrix_value ());
+		      if (arg.rows() < arg.columns())
+			warning ("qr: non minimum norm solution for under-determined problem");
+		    }
+		  else if (nargout > 1)
+		    {
+		      retval(1) = q.R (economy);
+		      retval(0) = q.Q ();
+		    }
+		  else
+		    retval(0) = q.R (economy);
+		}
+	    }
+	  else
+	    {
+	      SparseQR q (arg.sparse_matrix_value ());
+	      if (!error_state)
+		{
+		  if (have_b > 0)
+		    {
+		      retval(1) = q.R (economy);
+		      retval(0) = q.C (args(have_b).matrix_value ());
+		      if (args(0).rows() < args(0).columns())
+			warning ("qr: non minimum norm solution for under-determined problem");
+		    }
+		  else if (nargout > 1)
+		    {
+		      retval(1) = q.R (economy);
+		      retval(0) = q.Q ();
+		    }
+		  else
+		    retval(0) = q.R (economy);
+		}
+	    }
+	}
+    }
+  else
+    {
+      QR::type type = (nargout == 0 || nargout == 1) ? QR::raw
+	: (nargin == 2 ? QR::economy : QR::std);
+
+      if (arg.is_single_type ())
+	{
+	  if (arg.is_real_type ())
+	    {
+	      FloatMatrix m = arg.float_matrix_value ();
+
+	      if (! error_state)
+		{
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      {
+			FloatQR fact (m, type);
+			retval(0) = fact.R ();
+		      }
+		      break;
+
+		    case 2:
+		      {
+			FloatQR fact (m, type);
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+
+		    default:
+		      {
+			FloatQRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      {
+			FloatComplexQR fact (m, type);
+			retval(0) = fact.R ();
+		      }
+		      break;
+
+		    case 2:
+		      {
+			FloatComplexQR fact (m, type);
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+
+		    default:
+		      {
+			FloatComplexQRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  if (arg.is_real_type ())
+	    {
+	      Matrix m = arg.matrix_value ();
+
+	      if (! error_state)
+		{
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      {
+			QR fact (m, type);
+			retval(0) = fact.R ();
+		      }
+		      break;
+
+		    case 2:
+		      {
+			QR fact (m, type);
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+
+		    default:
+		      {
+			QRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      ComplexMatrix m = arg.complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  switch (nargout)
+		    {
+		    case 0:
+		    case 1:
+		      {
+			ComplexQR fact (m, type);
+			retval(0) = fact.R ();
+		      }
+		      break;
+
+		    case 2:
+		      {
+			ComplexQR fact (m, type);
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+
+		    default:
+		      {
+			ComplexQRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+			retval(1) = maybe_set_triangular (fact.R ());
+			retval(0) = fact.Q ();
+		      }
+		      break;
+		    }
+		}
+	    }
+	  else
+	    gripe_wrong_type_arg ("qr", arg);
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = [0, 2, 1; 2, 1, 2];
+%! 
+%! [q, r] = qr (a);
+%! 
+%! [qe, re] = qr (a, 0);
+%! 
+%! assert (q * r, a, sqrt (eps));
+%! assert (qe * re, a, sqrt (eps));
+
+%!test
+%! a = [0, 2, 1; 2, 1, 2];
+%! 
+%! [q, r, p] = qr (a);  # not giving right dimensions. FIXME
+%! 
+%! [qe, re, pe] = qr (a, 0);
+%! 
+%! assert (q * r, a * p, sqrt (eps));
+%! assert (qe * re, a(:, pe), sqrt (eps));
+
+%!test
+%! a = [0, 2; 2, 1; 1, 2];
+%! 
+%! [q, r] = qr (a);
+%! 
+%! [qe, re] = qr (a, 0);
+%! 
+%! assert (q * r, a, sqrt (eps));
+%! assert (qe * re, a, sqrt (eps));
+
+%!test
+%! a = [0, 2; 2, 1; 1, 2];
+%! 
+%! [q, r, p] = qr (a);
+%! 
+%! [qe, re, pe] = qr (a, 0);
+%! 
+%! assert (q * r, a * p, sqrt (eps));
+%! assert (qe * re, a(:, pe), sqrt (eps));
+
+%!error <Invalid call to qr.*> qr ();
+%!error <Invalid call to qr.*> qr ([1, 2; 3, 4], 0, 2);
+
+%!function retval = testqr (q, r, a, p)
+%!  tol = 100*eps (class(q));
+%!  retval = 0;
+%!  if (nargin == 3)
+%!    n1 = norm (q*r-a);
+%!    n2 = norm (q'*q-eye(columns(q)));
+%!    retval = (n1 < tol && n2 < tol);
+%!  else
+%!    n1 = norm (q'*q-eye(columns(q)));
+%!    retval = (n1 < tol);
+%!    if (isvector (p))
+%!      n2 = norm (q*r-a(:,p));
+%!      retval = (retval && n2 < tol);
+%!    else
+%!      n2 = norm (q*r - a*p);
+%!      retval = (retval && n2 < tol);
+%!    endif
+%!  endif
+%!test
+%! 
+%! t = ones (24, 1);
+%! j = 1;
+%! 
+%! if false # eliminate big matrix tests
+%!   a = rand(5000,20);
+%!   [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%!   [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%!   [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%!   [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! 
+%!   a = a+1i*eps;
+%!   [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%!   [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%!   [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%!   [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! endif
+%! 
+%! a = [ ones(1,15); sqrt(eps)*eye(15) ];
+%! [q,r]=qr(a); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a'); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a'); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = a+1i*eps;
+%! [q,r]=qr(a); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a'); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a'); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = [ ones(1,15); sqrt(eps)*eye(15) ];
+%! [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = a+1i*eps;
+%! [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = [
+%! 611   196  -192   407    -8   -52   -49    29
+%! 196   899   113  -192   -71   -43    -8   -44
+%! -192   113   899   196    61    49     8    52
+%! 407  -192   196   611     8    44    59   -23
+%! -8   -71    61     8   411  -599   208   208
+%! -52   -43    49    44  -599   411   208   208
+%! -49    -8     8    59   208   208    99  -911
+%! 29   -44    52   -23   208   208  -911    99
+%! ];
+%! [q,r] = qr(a);
+%! 
+%! assert(all (t) && norm(q*r-a) < 5000*eps);
+
+%!test
+%! a = single ([0, 2, 1; 2, 1, 2]);
+%! 
+%! [q, r] = qr (a);
+%! 
+%! [qe, re] = qr (a, 0);
+%! 
+%! assert (q * r, a, sqrt (eps ('single')));
+%! assert (qe * re, a, sqrt (eps ('single')));
+
+%!test
+%! a = single([0, 2, 1; 2, 1, 2]);
+%! 
+%! [q, r, p] = qr (a);  # not giving right dimensions. FIXME
+%! 
+%! [qe, re, pe] = qr (a, 0);
+%! 
+%! assert (q * r, a * p, sqrt (eps('single')));
+%! assert (qe * re, a(:, pe), sqrt (eps('single')));
+
+%!test
+%! a = single([0, 2; 2, 1; 1, 2]);
+%! 
+%! [q, r] = qr (a);
+%! 
+%! [qe, re] = qr (a, 0);
+%! 
+%! assert (q * r, a, sqrt (eps('single')));
+%! assert (qe * re, a, sqrt (eps('single')));
+
+%!test
+%! a = single([0, 2; 2, 1; 1, 2]);
+%! 
+%! [q, r, p] = qr (a);
+%! 
+%! [qe, re, pe] = qr (a, 0);
+%! 
+%! assert (q * r, a * p, sqrt (eps('single')));
+%! assert (qe * re, a(:, pe), sqrt (eps('single')));
+
+%!error <Invalid call to qr.*> qr ();
+%!error <Invalid call to qr.*> qr ([1, 2; 3, 4], 0, 2);
+
+%!test
+%! 
+%! t = ones (24, 1);
+%! j = 1;
+%! 
+%! if false # eliminate big matrix tests
+%!   a = rand(5000,20);
+%!   [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%!   [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%!   [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%!   [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! 
+%!   a = a+1i*eps('single');
+%!   [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%!   [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%!   [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%!   [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! endif
+%! 
+%! a = [ ones(1,15); sqrt(eps('single'))*eye(15) ];
+%! [q,r]=qr(a); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a'); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a'); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = a+1i*eps('single');
+%! [q,r]=qr(a); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a'); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a'); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = [ ones(1,15); sqrt(eps('single'))*eye(15) ];
+%! [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = a+1i*eps('single');
+%! [q,r]=qr(a,0); t(j++) = testqr(q,r,a);
+%! [q,r]=qr(a',0); t(j++) = testqr(q,r,a');
+%! [q,r,p]=qr(a,0); t(j++) = testqr(q,r,a,p);
+%! [q,r,p]=qr(a',0); t(j++) = testqr(q,r,a',p);
+%! 
+%! a = [
+%! 611   196  -192   407    -8   -52   -49    29
+%! 196   899   113  -192   -71   -43    -8   -44
+%! -192   113   899   196    61    49     8    52
+%! 407  -192   196   611     8    44    59   -23
+%! -8   -71    61     8   411  -599   208   208
+%! -52   -43    49    44  -599   411   208   208
+%! -49    -8     8    59   208   208    99  -911
+%! 29   -44    52   -23   208   208  -911    99
+%! ];
+%! [q,r] = qr(a);
+%! 
+%! assert(all (t) && norm(q*r-a) < 5000*eps('single'));
+
+%% The deactivated tests below can't be tested till rectangular back-subs is
+%% implemented for sparse matrices.
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = sprandn(n,n,d)+speye(n,n);
+%! r = qr(a);
+%! assert(r'*r,a'*a,1e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = sprandn(n,n,d)+speye(n,n);
+%! q = symamd(a);
+%! a = a(q,q);
+%! r = qr(a);
+%! assert(r'*r,a'*a,1e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = sprandn(n,n,d)+speye(n,n);
+%! [c,r] = qr(a,ones(n,1));
+%! assert (r\c,full(a)\ones(n,1),10e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = sprandn(n,n,d)+speye(n,n);
+%! b = randn(n,2);
+%! [c,r] = qr(a,b);
+%! assert (r\c,full(a)\b,10e-10)
+
+%% Test under-determined systems!!
+%!#testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = sprandn(n,n+1,d)+speye(n,n+1);
+%! b = randn(n,2);
+%! [c,r] = qr(a,b);
+%! assert (r\c,full(a)\b,10e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = 1i*sprandn(n,n,d)+speye(n,n);
+%! r = qr(a);
+%! assert(r'*r,a'*a,1e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = 1i*sprandn(n,n,d)+speye(n,n);
+%! q = symamd(a);
+%! a = a(q,q);
+%! r = qr(a);
+%! assert(r'*r,a'*a,1e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = 1i*sprandn(n,n,d)+speye(n,n);
+%! [c,r] = qr(a,ones(n,1));
+%! assert (r\c,full(a)\ones(n,1),10e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = 1i*sprandn(n,n,d)+speye(n,n);
+%! b = randn(n,2);
+%! [c,r] = qr(a,b);
+%! assert (r\c,full(a)\b,10e-10)
+
+%% Test under-determined systems!!
+%!#testif HAVE_CXSPARSE
+%! n = 20; d= 0.2;
+%! a = 1i*sprandn(n,n+1,d)+speye(n,n+1);
+%! b = randn(n,2);
+%! [c,r] = qr(a,b);
+%! assert (r\c,full(a)\b,10e-10)
+
+%!error qr(sprandn(10,10,0.2),ones(10,1));
+
+*/
+
+static
+bool check_qr_dims (const octave_value& q, const octave_value& r,
+                    bool allow_ecf = false)
+{
+  octave_idx_type m = q.rows (), k = r.rows (), n = r.columns ();
+  return ((q.ndims () == 2 && r.ndims () == 2 && k == q.columns ())
+            && (m == k || (allow_ecf && k == n && k < m)));
+}
+
+static 
+bool check_index (const octave_value& i, bool vector_allowed = false)
+{
+  return ((i.is_real_type () || i.is_integer_type ()) 
+          && (i.is_scalar_type () || vector_allowed));
+}
+
+DEFUN_DLD (qrupdate, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrupdate (@var{Q}, @var{R}, @var{u}, @var{v})\n\
+Given a QR at tie{}factorization of a real or complex matrix\n\
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization\n\
+of @w{@var{A} + @var{u}*@var{v}'}, where @var{u} and @var{v} are\n\
+column vectors (rank-1 update) or matrices with equal number of columns\n\
+(rank-k update).  Notice that the latter case is done as a sequence of rank-1 updates;\n\
+thus, for k large enough, it will be both faster and more accurate to recompute\n\
+the factorization from scratch.\n\
+\n\
+The QR factorization supplied may be either full\n\
+(Q is square) or economized (R is square).\n\
+\n\
+ at seealso{qr, qrinsert, qrdelete}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argu = args(2);
+  octave_value argv = args(3);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type () 
+      && argu.is_numeric_type () && argv.is_numeric_type ())
+    {
+      if (check_qr_dims (argq, argr, true))
+        {
+          if (argq.is_real_type () 
+	      && argr.is_real_type () 
+	      && argu.is_real_type () 
+	      && argv.is_real_type ())
+            {
+	      // all real case
+	      if (argq.is_single_type () 
+		  || argr.is_single_type () 
+		  || argu.is_single_type () 
+		  || argv.is_single_type ())
+		{
+		  FloatMatrix Q = argq.float_matrix_value ();
+		  FloatMatrix R = argr.float_matrix_value ();
+		  FloatMatrix u = argu.float_matrix_value ();
+		  FloatMatrix v = argv.float_matrix_value ();
+
+		  FloatQR fact (Q, R);
+		  fact.update (u, v);
+
+		  retval(1) = fact.R ();
+		  retval(0) = fact.Q ();
+		}
+	      else
+		{
+		  Matrix Q = argq.matrix_value ();
+		  Matrix R = argr.matrix_value ();
+		  Matrix u = argu.matrix_value ();
+		  Matrix v = argv.matrix_value ();
+
+		  QR fact (Q, R);
+		  fact.update (u, v);
+
+		  retval(1) = fact.R ();
+		  retval(0) = fact.Q ();
+		}
+            }
+          else
+            {
+              // complex case
+	      if (argq.is_single_type () 
+		  || argr.is_single_type () 
+		  || argu.is_single_type () 
+		  || argv.is_single_type ())
+		{
+		  FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+		  FloatComplexMatrix R = argr.float_complex_matrix_value ();
+		  FloatComplexMatrix u = argu.float_complex_matrix_value ();
+		  FloatComplexMatrix v = argv.float_complex_matrix_value ();
+
+		  FloatComplexQR fact (Q, R);
+		  fact.update (u, v);
+              
+		  retval(1) = fact.R ();
+		  retval(0) = fact.Q ();
+		}
+	      else
+		{
+		  ComplexMatrix Q = argq.complex_matrix_value ();
+		  ComplexMatrix R = argr.complex_matrix_value ();
+		  ComplexMatrix u = argu.complex_matrix_value ();
+		  ComplexMatrix v = argv.complex_matrix_value ();
+
+		  ComplexQR fact (Q, R);
+		  fact.update (u, v);
+              
+		  retval(1) = fact.R ();
+		  retval(0) = fact.Q ();
+		}
+            }
+        }
+      else
+	error ("qrupdate: dimensions mismatch");
+    }
+  else
+    error ("qrupdate: expecting numeric arguments");
+
+  return retval;
+}
+/*
+%!shared A, u, v, Ac, uc, vc
+%! A = [0.091364  0.613038  0.999083;
+%!      0.594638  0.425302  0.603537;
+%!      0.383594  0.291238  0.085574;
+%!      0.265712  0.268003  0.238409;
+%!      0.669966  0.743851  0.445057 ];
+%!
+%! u = [0.85082;  
+%!      0.76426;  
+%!      0.42883;  
+%!      0.53010;  
+%!      0.80683 ];
+%!
+%! v = [0.98810;
+%!      0.24295;
+%!      0.43167 ];
+%!
+%! Ac = [0.620405 + 0.956953i  0.480013 + 0.048806i  0.402627 + 0.338171i;
+%!      0.589077 + 0.658457i  0.013205 + 0.279323i  0.229284 + 0.721929i;
+%!      0.092758 + 0.345687i  0.928679 + 0.241052i  0.764536 + 0.832406i;
+%!      0.912098 + 0.721024i  0.049018 + 0.269452i  0.730029 + 0.796517i;
+%!      0.112849 + 0.603871i  0.486352 + 0.142337i  0.355646 + 0.151496i ];
+%!
+%! uc = [0.20351 + 0.05401i;
+%!      0.13141 + 0.43708i;
+%!      0.29808 + 0.08789i;
+%!      0.69821 + 0.38844i;
+%!      0.74871 + 0.25821i ];
+%!
+%! vc = [0.85839 + 0.29468i;
+%!      0.20820 + 0.93090i;
+%!      0.86184 + 0.34689i ];
+%!
+
+%!test
+%! [Q,R] = qr(A);
+%! [Q,R] = qrupdate(Q,R,u,v);
+%! assert(norm(vec(Q'*Q - eye(5)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - A - u*v'),Inf) < norm(A)*1e1*eps)
+%! 
+%!test
+%! [Q,R] = qr(Ac);
+%! [Q,R] = qrupdate(Q,R,uc,vc);
+%! assert(norm(vec(Q'*Q - eye(5)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - Ac - uc*vc'),Inf) < norm(Ac)*1e1*eps)
+
+%!test
+%! [Q,R] = qr(single(A));
+%! [Q,R] = qrupdate(Q,R,single(u),single(v));
+%! assert(norm(vec(Q'*Q - eye(5,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - single(A) - single(u)*single(v)'),Inf) < norm(single(A))*1e1*eps('single'))
+%! 
+%!test
+%! [Q,R] = qr(single(Ac));
+%! [Q,R] = qrupdate(Q,R,single(uc),single(vc));
+%! assert(norm(vec(Q'*Q - eye(5,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - single(Ac) - single(uc)*single(vc)'),Inf) < norm(single(Ac))*1e1*eps('single'))
+*/
+
+DEFUN_DLD (qrinsert, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrinsert (@var{Q}, @var{R}, @var{j}, @var{x}, @var{orient})\n\
+Given a QR at tie{}factorization of a real or complex matrix\n\
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization of\n\
+ at w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be\n\
+inserted into @var{A} (if @var{orient} is @code{\"col\"}), or the\n\
+QR at tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}\n\
+is a row vector to be inserted into @var{A} (if @var{orient} is\n\
+ at code{\"row\"}).\n\
+\n\
+The default value of @var{orient} is @code{\"col\"}.\n\
+If @var{orient} is @code{\"col\"},\n\
+ at var{u} may be a matrix and @var{j} an index vector\n\
+resulting in the QR at tie{}factorization of a matrix @var{B} such that\n\
+ at w{B(:, at var{j})} gives @var{u} and @w{B(:, at var{j}) = []} gives @var{A}.\n\
+Notice that the latter case is done as a sequence of k insertions;\n\
+thus, for k large enough, it will be both faster and more accurate to recompute\n\
+the factorization from scratch.\n\
+\n\
+If @var{orient} is @code{\"col\"},\n\
+the QR factorization supplied may be either full\n\
+(Q is square) or economized (R is square).\n\
+\n\
+If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
+ at seealso{qr, qrupdate, qrdelete}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin < 4 || nargin > 5)
+    {
+      print_usage ();
+      return retval;
+    }
+  
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argj = args(2);
+  octave_value argx = args(3);
+      
+  if (argq.is_numeric_type () && argr.is_numeric_type ()
+      && argx.is_numeric_type ()
+      && (nargin < 5 || args(4).is_string ()))
+    {
+      std::string orient = (nargin < 5) ? "col" : args(4).string_value ();
+
+      bool col = orient == "col";
+
+      if (col || orient == "row")
+        if (check_qr_dims (argq, argr, col) 
+            && (col || argx.rows () == 1))
+          {
+            if (check_index (argj, col))
+              {
+                MArray<octave_idx_type> j
+		  = argj.octave_idx_type_vector_value ();
+
+                if (argq.is_real_type () 
+		    && argr.is_real_type () 
+		    && argx.is_real_type ())
+                  {
+                    // real case
+		    if (argq.is_single_type () 
+			|| argr.is_single_type () 
+			|| argx.is_single_type ())
+		      {
+			FloatMatrix Q = argq.float_matrix_value ();
+			FloatMatrix R = argr.float_matrix_value ();
+			FloatMatrix x = argx.float_matrix_value ();
+
+			FloatQR fact (Q, R);
+
+			if (col) 
+			  fact.insert_col (x, j-1);
+			else 
+			  fact.insert_row (x.row (0), j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+
+		      }
+		    else
+		      {
+			Matrix Q = argq.matrix_value ();
+			Matrix R = argr.matrix_value ();
+			Matrix x = argx.matrix_value ();
+
+			QR fact (Q, R);
+
+			if (col) 
+			  fact.insert_col (x, j-1);
+			else 
+			  fact.insert_row (x.row (0), j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+
+		      }
+                  }
+                else
+                  {
+                    // complex case
+		    if (argq.is_single_type () 
+			|| argr.is_single_type () 
+			|| argx.is_single_type ())
+		      {
+			FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+			FloatComplexMatrix R = argr.float_complex_matrix_value ();
+			FloatComplexMatrix x = argx.float_complex_matrix_value ();
+
+			FloatComplexQR fact (Q, R);
+
+			if (col) 
+			  fact.insert_col (x, j-1);
+			else 
+			  fact.insert_row (x.row (0), j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+		      }
+		    else
+		      {
+			ComplexMatrix Q = argq.complex_matrix_value ();
+			ComplexMatrix R = argr.complex_matrix_value ();
+			ComplexMatrix x = argx.complex_matrix_value ();
+
+			ComplexQR fact (Q, R);
+
+			if (col) 
+			  fact.insert_col (x, j-1);
+			else 
+			  fact.insert_row (x.row (0), j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+		      }
+                  }
+
+              }
+            else
+              error ("qrinsert: invalid index");
+          }
+        else
+          error ("qrinsert: dimension mismatch");
+
+      else
+        error ("qrinsert: orient must be \"col\" or \"row\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! [Q,R] = qr(A);
+%! [Q,R] = qrinsert(Q,R,3,u);
+%! assert(norm(vec(Q'*Q - eye(5)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [A(:,1:2) u A(:,3)]),Inf) < norm(A)*1e1*eps)
+%!test
+%! [Q,R] = qr(Ac);
+%! [Q,R] = qrinsert(Q,R,3,uc);
+%! assert(norm(vec(Q'*Q - eye(5)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [Ac(:,1:2) uc Ac(:,3)]),Inf) < norm(Ac)*1e1*eps)
+%!test
+%! x = [0.85082  0.76426  0.42883 ];
+%!
+%! [Q,R] = qr(A);
+%! [Q,R] = qrinsert(Q,R,3,x,'row');
+%! assert(norm(vec(Q'*Q - eye(6)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [A(1:2,:);x;A(3:5,:)]),Inf) < norm(A)*1e1*eps)
+%!test
+%! x = [0.20351 + 0.05401i  0.13141 + 0.43708i  0.29808 + 0.08789i ];
+%!
+%! [Q,R] = qr(Ac);
+%! [Q,R] = qrinsert(Q,R,3,x,'row');
+%! assert(norm(vec(Q'*Q - eye(6)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [Ac(1:2,:);x;Ac(3:5,:)]),Inf) < norm(Ac)*1e1*eps)
+
+%!test
+%! [Q,R] = qr(single(A));
+%! [Q,R] = qrinsert(Q,R,3,single(u));
+%! assert(norm(vec(Q'*Q - eye(5,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - single([A(:,1:2) u A(:,3)])),Inf) < norm(single(A))*1e1*eps('single'))
+%!test
+%! [Q,R] = qr(single(Ac));
+%! [Q,R] = qrinsert(Q,R,3,single(uc));
+%! assert(norm(vec(Q'*Q - eye(5,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - single([Ac(:,1:2) uc Ac(:,3)])),Inf) < norm(single(Ac))*1e1*eps('single'))
+%!test
+%! x = single([0.85082  0.76426  0.42883 ]);
+%!
+%! [Q,R] = qr(single(A));
+%! [Q,R] = qrinsert(Q,R,3,x,'row');
+%! assert(norm(vec(Q'*Q - eye(6,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - single([A(1:2,:);x;A(3:5,:)])),Inf) < norm(single(A))*1e1*eps('single'))
+%!test
+%! x = single([0.20351 + 0.05401i  0.13141 + 0.43708i  0.29808 + 0.08789i ]);
+%!
+%! [Q,R] = qr(single(Ac));
+%! [Q,R] = qrinsert(Q,R,3,x,'row');
+%! assert(norm(vec(Q'*Q - eye(6,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - single([Ac(1:2,:);x;Ac(3:5,:)])),Inf) < norm(single(Ac))*1e1*eps('single'))
+*/
+
+DEFUN_DLD (qrdelete, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrdelete (@var{Q}, @var{R}, @var{j}, @var{orient})\n\
+Given a QR at tie{}factorization of a real or complex matrix\n\
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization of\n\
+ at w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted\n\
+(if @var{orient} is \"col\"), or the QR at tie{}factorization of\n\
+ at w{[A(1:j-1,:);A(:,j+1:n)]}, i.e., @var{A} with one row deleted (if\n\
+ at var{orient} is \"row\").\n\
+\n\
+The default value of @var{orient} is \"col\".\n\
+\n\
+If @var{orient} is @code{\"col\"},\n\
+ at var{j} may be an index vector\n\
+resulting in the QR at tie{}factorization of a matrix @var{B} such that\n\
+ at w{A(:, at var{j}) = []} gives @var{B}.\n\
+Notice that the latter case is done as a sequence of k deletions;\n\
+thus, for k large enough, it will be both faster and more accurate to recompute\n\
+the factorization from scratch.\n\
+\n\
+If @var{orient} is @code{\"col\"},\n\
+the QR factorization supplied may be either full\n\
+(Q is square) or economized (R is square).\n\
+\n\
+If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
+ at seealso{qr, qrinsert, qrupdate}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin < 3 || nargin > 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argj = args(2);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type ()
+      && (nargin < 4 || args(3).is_string ()))
+    {
+      std::string orient = (nargin < 4) ? "col" : args(3).string_value ();
+
+      bool col = orient == "col";
+
+      if (col || orient == "row")
+        if (check_qr_dims (argq, argr, col))
+          {
+            if (check_index (argj, col))
+              {
+                MArray<octave_idx_type> j
+		  = argj.octave_idx_type_vector_value ();
+
+                if (argq.is_real_type ()
+		    && argr.is_real_type ())
+                  {
+                    // real case
+		    if (argq.is_single_type ()
+			|| argr.is_single_type ())
+		      {
+			FloatMatrix Q = argq.float_matrix_value ();
+			FloatMatrix R = argr.float_matrix_value ();
+
+			FloatQR fact (Q, R);
+
+			if (col) 
+                          fact.delete_col (j-1);
+			else 
+			  fact.delete_row (j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+		      }
+		    else
+		      {
+			Matrix Q = argq.matrix_value ();
+			Matrix R = argr.matrix_value ();
+
+			QR fact (Q, R);
+
+			if (col) 
+                          fact.delete_col (j-1);
+			else 
+			  fact.delete_row (j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+		      }
+                  }
+                else
+                  {
+                    // complex case
+		    if (argq.is_single_type ()
+			|| argr.is_single_type ())
+		      {
+			FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+			FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+			FloatComplexQR fact (Q, R);
+
+			if (col) 
+                          fact.delete_col (j-1);
+			else 
+			  fact.delete_row (j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+		      }
+		    else
+		      {
+			ComplexMatrix Q = argq.complex_matrix_value ();
+			ComplexMatrix R = argr.complex_matrix_value ();
+
+			ComplexQR fact (Q, R);
+
+			if (col) 
+                          fact.delete_col (j-1);
+			else 
+			  fact.delete_row (j(0)-1);
+
+			retval(1) = fact.R ();
+			retval(0) = fact.Q ();
+		      }
+                  }
+              }
+            else
+              error ("qrdelete: invalid index");
+          }
+        else
+          error ("qrdelete: dimension mismatch");
+
+      else
+        error ("qrdelete: orient must be \"col\" or \"row\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+ 
+/*
+%!test
+%! AA = [0.091364  0.613038  0.027504  0.999083;
+%!       0.594638  0.425302  0.562834  0.603537;
+%!       0.383594  0.291238  0.742073  0.085574;
+%!       0.265712  0.268003  0.783553  0.238409;
+%!       0.669966  0.743851  0.457255  0.445057 ];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3);
+%! assert(norm(vec(Q'*Q - eye(5)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(:,1:2) AA(:,4)]),Inf) < norm(AA)*1e1*eps)
+%! 
+%!test
+%! AA = [0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!       0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!       0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!       0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!       0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ] * I;
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3);
+%! assert(norm(vec(Q'*Q - eye(5)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(:,1:2) AA(:,4)]),Inf) < norm(AA)*1e1*eps)
+%!
+%!test
+%! AA = [0.091364  0.613038  0.027504  0.999083;
+%!       0.594638  0.425302  0.562834  0.603537;
+%!       0.383594  0.291238  0.742073  0.085574;
+%!       0.265712  0.268003  0.783553  0.238409;
+%!       0.669966  0.743851  0.457255  0.445057 ];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3,'row');
+%! assert(norm(vec(Q'*Q - eye(4)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(1:2,:);AA(4:5,:)]),Inf) < norm(AA)*1e1*eps)
+%! 
+%!test
+%! AA = [0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!       0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!       0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!       0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!       0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ] * I;
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3,'row');
+%! assert(norm(vec(Q'*Q - eye(4)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(1:2,:);AA(4:5,:)]),Inf) < norm(AA)*1e1*eps)
+
+%!test
+%! AA = single([0.091364  0.613038  0.027504  0.999083;
+%!              0.594638  0.425302  0.562834  0.603537;
+%!              0.383594  0.291238  0.742073  0.085574;
+%!              0.265712  0.268003  0.783553  0.238409;
+%!              0.669966  0.743851  0.457255  0.445057 ]);
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3);
+%! assert(norm(vec(Q'*Q - eye(5,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(:,1:2) AA(:,4)]),Inf) < norm(AA)*1e1*eps('single'))
+%! 
+%!test
+%! AA = single([0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!              0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!              0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!              0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!              0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ]) * I;
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3);
+%! assert(norm(vec(Q'*Q - eye(5,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(:,1:2) AA(:,4)]),Inf) < norm(AA)*1e1*eps('single'))
+%!
+%!test
+%! AA = single([0.091364  0.613038  0.027504  0.999083;
+%!              0.594638  0.425302  0.562834  0.603537;
+%!              0.383594  0.291238  0.742073  0.085574;
+%!              0.265712  0.268003  0.783553  0.238409;
+%!              0.669966  0.743851  0.457255  0.445057 ]);
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3,'row');
+%! assert(norm(vec(Q'*Q - eye(4,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(1:2,:);AA(4:5,:)]),Inf) < norm(AA)*1e1*eps('single'))
+%! 
+%!test
+%! AA = single([0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!              0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!              0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!              0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!              0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ]) * I;
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrdelete(Q,R,3,'row');
+%! assert(norm(vec(Q'*Q - eye(4,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - [AA(1:2,:);AA(4:5,:)]),Inf) < norm(AA)*1e1*eps('single'))
+*/
+
+DEFUN_DLD (qrshift, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrshift (@var{Q}, @var{R}, @var{i}, @var{j})\n\
+Given a QR at tie{}factorization of a real or complex matrix\n\
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization\n\
+of @w{@var{A}(:,p)}, where @w{p} is the permutation @*\n\
+ at code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
+ or @*\n\
+ at code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*\n\
+\n\
+ at seealso{qr, qrinsert, qrdelete}\n\
+ at end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argi = args(2);
+  octave_value argj = args(3);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type ())
+    {
+      if (check_qr_dims (argq, argr, true))
+        {
+          if (check_index (argi) && check_index (argj))
+            {
+              octave_idx_type i = argi.int_value ();
+              octave_idx_type j = argj.int_value ();
+
+              if (argq.is_real_type () 
+                  && argr.is_real_type ())
+                {
+                  // all real case
+		  if (argq.is_single_type () 
+		      && argr.is_single_type ())
+		    {
+		      FloatMatrix Q = argq.float_matrix_value ();
+		      FloatMatrix R = argr.float_matrix_value ();
+
+		      FloatQR fact (Q, R);
+		      fact.shift_cols (i-1, j-1);
+
+		      retval(1) = fact.R ();
+		      retval(0) = fact.Q ();
+		    }
+		  else
+		    {
+		      Matrix Q = argq.matrix_value ();
+		      Matrix R = argr.matrix_value ();
+
+		      QR fact (Q, R);
+		      fact.shift_cols (i-1, j-1);
+
+		      retval(1) = fact.R ();
+		      retval(0) = fact.Q ();
+		    }
+                }
+              else
+                {
+                  // complex case
+		  if (argq.is_single_type () 
+		      && argr.is_single_type ())
+		    {
+		      FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+		      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+		      FloatComplexQR fact (Q, R);
+		      fact.shift_cols (i-1, j-1);
+                  
+		      retval(1) = fact.R ();
+		      retval(0) = fact.Q ();
+		    }
+		  else
+		    {
+		      ComplexMatrix Q = argq.complex_matrix_value ();
+		      ComplexMatrix R = argr.complex_matrix_value ();
+
+		      ComplexQR fact (Q, R);
+		      fact.shift_cols (i-1, j-1);
+                  
+		      retval(1) = fact.R ();
+		      retval(0) = fact.Q ();
+		    }
+                }
+            }
+          else
+            error ("qrshift: invalid index");
+        }
+      else
+	error ("qrshift: dimensions mismatch");
+    }
+  else
+    error ("qrshift: expecting numeric arguments");
+
+  return retval;
+}
+/*
+%!test
+%! AA = A.';
+%! i = 2; j = 4; p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps)
+%! 
+%! j = 2; i = 4; p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps)
+%! 
+%!test
+%! AA = Ac.';
+%! i = 2; j = 4; p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps)
+%! 
+%! j = 2; i = 4; p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3)),Inf) < 1e1*eps)
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps)
+
+
+%!test
+%! AA = single (A).';
+%! i = 2; j = 4; p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps('single'))
+%! 
+%! j = 2; i = 4; p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps('single'))
+%! 
+%!test
+%! AA = single(Ac).';
+%! i = 2; j = 4; p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps('single'))
+%! 
+%! j = 2; i = 4; p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr(AA);
+%! [Q,R] = qrshift(Q,R,i,j);
+%! assert(norm(vec(Q'*Q - eye(3,'single')),Inf) < 1e1*eps('single'))
+%! assert(norm(vec(triu(R)-R),Inf) == 0)
+%! assert(norm(vec(Q*R - AA(:,p)),Inf) < norm(AA)*1e1*eps('single'))
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/quad.cc b/src/DLD-FUNCTIONS/quad.cc
new file mode 100644
index 0000000..57b4823
--- /dev/null
+++ b/src/DLD-FUNCTIONS/quad.cc
@@ -0,0 +1,517 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <iomanip>
+#include <iostream>
+
+#include "Quad.h"
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "pager.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#include "Quad-opts.cc"
+
+#if defined (quad)
+#undef quad
+#endif
+
+// Global pointer for user defined function required by quadrature functions.
+static octave_function *quad_fcn;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+double
+quad_user_function (double x)
+{
+  double retval = 0.0;
+
+  octave_value_list args;
+  args(0) = x;
+
+  if (quad_fcn)
+    {
+      octave_value_list tmp = quad_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  quad_integration_error = 1;  // FIXME
+	  gripe_user_supplied_eval ("quad");
+	  return retval;
+	}
+
+      if (tmp.length () && tmp(0).is_defined ())
+	{
+	  if (! warned_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("quad: ignoring imaginary part returned from user-supplied function");
+	      warned_imaginary = true;
+	    }
+
+	  retval = tmp(0).double_value ();
+
+	  if (error_state)
+	    {
+	      quad_integration_error = 1;  // FIXME
+	      gripe_user_supplied_eval ("quad");
+	    }
+	}
+      else
+	{
+	  quad_integration_error = 1;  // FIXME
+	  gripe_user_supplied_eval ("quad");
+	}
+    }
+
+  return retval;
+}
+
+float
+quad_float_user_function (float x)
+{
+  float retval = 0.0;
+
+  octave_value_list args;
+  args(0) = x;
+
+  if (quad_fcn)
+    {
+      octave_value_list tmp = quad_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+	{
+	  quad_integration_error = 1;  // FIXME
+	  gripe_user_supplied_eval ("quad");
+	  return retval;
+	}
+
+      if (tmp.length () && tmp(0).is_defined ())
+	{
+	  if (! warned_imaginary && tmp(0).is_complex_type ())
+	    {
+	      warning ("quad: ignoring imaginary part returned from user-supplied function");
+	      warned_imaginary = true;
+	    }
+
+	  retval = tmp(0).float_value ();
+
+	  if (error_state)
+	    {
+	      quad_integration_error = 1;  // FIXME
+	      gripe_user_supplied_eval ("quad");
+	    }
+	}
+      else
+	{
+	  quad_integration_error = 1;  // FIXME
+	  gripe_user_supplied_eval ("quad");
+	}
+    }
+
+  return retval;
+}
+
+#define QUAD_ABORT() \
+  do \
+    { \
+      if (fcn_name.length()) \
+	clear_function (fcn_name); \
+      unwind_protect::run_frame ("Fquad"); \
+      return retval; \
+    } \
+  while (0)
+
+#define QUAD_ABORT1(msg) \
+  do \
+    { \
+      ::error ("quad: " msg); \
+      QUAD_ABORT (); \
+    } \
+  while (0)
+
+#define QUAD_ABORT2(fmt, arg) \
+  do \
+    { \
+      ::error ("quad: " fmt, arg); \
+      QUAD_ABORT (); \
+    } \
+  while (0)
+
+DEFUN_DLD (quad, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{v}, @var{ier}, @var{nfun}, @var{err}] =} quad (@var{f}, @var{a}, @var{b}, @var{tol}, @var{sing})\n\
+Integrate a nonlinear function of one variable using Quadpack.\n\
+The first argument is the name of the function, the function handle or\n\
+the inline function to call to compute the value of the integrand.  It\n\
+must have the form\n\
+\n\
+ at example\n\
+y = f (x)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+where @var{y} and @var{x} are scalars.\n\
+\n\
+The second and third arguments are limits of integration.  Either or\n\
+both may be infinite.\n\
+\n\
+The optional argument @var{tol} is a vector that specifies the desired\n\
+accuracy of the result.  The first element of the vector is the desired\n\
+absolute tolerance, and the second element is the desired relative\n\
+tolerance.  To choose a relative test only, set the absolute\n\
+tolerance to zero.  To choose an absolute test only, set the relative\n\
+tolerance to zero.  \n\
+\n\
+The optional argument @var{sing} is a vector of values at which the\n\
+integrand is known to be singular.\n\
+\n\
+The result of the integration is returned in @var{v} and @var{ier}\n\
+contains an integer error code (0 indicates a successful integration).\n\
+The value of @var{nfun} indicates how many function evaluations were\n\
+required, and @var{err} contains an estimate of the error in the\n\
+solution.\n\
+\n\
+You can use the function @code{quad_options} to set optional\n\
+parameters for @code{quad}.\n\
+\n\
+It should be noted that since @code{quad} is written in Fortran it\n\
+cannot be called recursively.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  std::string fcn_name;
+
+  warned_imaginary = false;
+
+  unwind_protect::begin_frame ("Fquad");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    QUAD_ABORT1 ("invalid recursive call");
+
+  int nargin = args.length ();
+
+  if (nargin > 2 && nargin < 6 && nargout < 5)
+    {
+      if (args(0).is_function_handle () || args(0).is_inline_function ())
+	quad_fcn = args(0).function_value ();
+      else
+	{
+	  fcn_name = unique_symbol_name ("__quad_fcn_");
+	  std::string fname = "function y = ";
+	  fname.append (fcn_name);
+	  fname.append ("(x) y = ");
+	  quad_fcn = extract_function (args(0), "quad", fcn_name, fname,
+				       "; endfunction");
+	}
+
+      if (! quad_fcn)
+	QUAD_ABORT ();
+
+      if (args(1).is_single_type () || args(2).is_single_type ())
+	{
+	  float a = args(1).float_value ();
+
+	  if (error_state)
+	    QUAD_ABORT1 ("expecting second argument to be a scalar");
+
+	  float b = args(2).float_value ();
+
+	  if (error_state)
+	    QUAD_ABORT1 ("expecting third argument to be a scalar");
+
+	  int indefinite = 0;
+	  FloatIndefQuad::IntegralType indef_type = FloatIndefQuad::doubly_infinite;
+	  float bound = 0.0;
+	  if (xisinf (a) && xisinf (b))
+	    {
+	      indefinite = 1;
+	      indef_type = FloatIndefQuad::doubly_infinite;
+	    }
+	  else if (xisinf (a))
+	    {
+	      indefinite = 1;
+	      bound = b;
+	      indef_type = FloatIndefQuad::neg_inf_to_bound;
+	    }
+	  else if (xisinf (b))
+	    {
+	      indefinite = 1;
+	      bound = a;
+	      indef_type = FloatIndefQuad::bound_to_inf;
+	    }
+
+	  octave_idx_type ier = 0;
+	  octave_idx_type nfun = 0;
+	  float abserr = 0.0;
+	  float val = 0.0;
+	  bool have_sing = false;
+	  FloatColumnVector sing;
+	  FloatColumnVector tol;
+
+	  switch (nargin)
+	    {
+	    case 5:
+	      if (indefinite)
+		QUAD_ABORT1 ("singularities not allowed on infinite intervals");
+
+	      have_sing = true;
+
+	      sing = FloatColumnVector (args(4).float_vector_value ());
+
+	      if (error_state)
+		QUAD_ABORT1 ("expecting vector of singularities as fourth argument");
+
+	    case 4:
+	      tol = FloatColumnVector (args(3).float_vector_value ());
+
+	      if (error_state)
+		QUAD_ABORT1 ("expecting vector of tolerances as fifth argument");
+
+	      switch (tol.capacity ())
+		{
+		case 2:
+		  quad_opts.set_single_precision_relative_tolerance (tol (1));
+
+		case 1:
+		  quad_opts.set_single_precision_absolute_tolerance (tol (0));
+		  break;
+
+		default:
+		  QUAD_ABORT1 ("expecting tol to contain no more than two values");
+		}
+
+	    case 3:
+	      if (indefinite)
+		{
+		  FloatIndefQuad iq (quad_float_user_function, bound, 
+				     indef_type);
+		  iq.set_options (quad_opts);
+		  val = iq.float_integrate (ier, nfun, abserr);
+		}
+	      else
+		{
+		  if (have_sing)
+		    {
+		      FloatDefQuad dq (quad_float_user_function, a, b, sing);
+		      dq.set_options (quad_opts);
+		      val = dq.float_integrate (ier, nfun, abserr);
+		    }
+		  else
+		    {
+		      FloatDefQuad dq (quad_float_user_function, a, b);
+		      dq.set_options (quad_opts);
+		      val = dq.float_integrate (ier, nfun, abserr);
+		    }
+		}
+	      break;
+
+	    default:
+	      panic_impossible ();
+	      break;
+	    }
+
+	  retval(3) = abserr;
+	  retval(2) = nfun;
+	  retval(1) = ier;
+	  retval(0) = val;
+
+	}
+      else
+	{
+	  double a = args(1).double_value ();
+
+	  if (error_state)
+	    QUAD_ABORT1 ("expecting second argument to be a scalar");
+
+	  double b = args(2).double_value ();
+
+	  if (error_state)
+	    QUAD_ABORT1 ("expecting third argument to be a scalar");
+
+	  int indefinite = 0;
+	  IndefQuad::IntegralType indef_type = IndefQuad::doubly_infinite;
+	  double bound = 0.0;
+	  if (xisinf (a) && xisinf (b))
+	    {
+	      indefinite = 1;
+	      indef_type = IndefQuad::doubly_infinite;
+	    }
+	  else if (xisinf (a))
+	    {
+	      indefinite = 1;
+	      bound = b;
+	      indef_type = IndefQuad::neg_inf_to_bound;
+	    }
+	  else if (xisinf (b))
+	    {
+	      indefinite = 1;
+	      bound = a;
+	      indef_type = IndefQuad::bound_to_inf;
+	    }
+
+	  octave_idx_type ier = 0;
+	  octave_idx_type nfun = 0;
+	  double abserr = 0.0;
+	  double val = 0.0;
+	  bool have_sing = false;
+	  ColumnVector sing;
+	  ColumnVector tol;
+
+	  switch (nargin)
+	    {
+	    case 5:
+	      if (indefinite)
+		QUAD_ABORT1 ("singularities not allowed on infinite intervals");
+
+	      have_sing = true;
+
+	      sing = ColumnVector (args(4).vector_value ());
+
+	      if (error_state)
+		QUAD_ABORT1 ("expecting vector of singularities as fourth argument");
+
+	    case 4:
+	      tol = ColumnVector (args(3).vector_value ());
+
+	      if (error_state)
+		QUAD_ABORT1 ("expecting vector of tolerances as fifth argument");
+
+	      switch (tol.capacity ())
+		{
+		case 2:
+		  quad_opts.set_relative_tolerance (tol (1));
+
+		case 1:
+		  quad_opts.set_absolute_tolerance (tol (0));
+		  break;
+
+		default:
+		  QUAD_ABORT1 ("expecting tol to contain no more than two values");
+		}
+
+	    case 3:
+	      if (indefinite)
+		{
+		  IndefQuad iq (quad_user_function, bound, indef_type);
+		  iq.set_options (quad_opts);
+		  val = iq.integrate (ier, nfun, abserr);
+		}
+	      else
+		{
+		  if (have_sing)
+		    {
+		      DefQuad dq (quad_user_function, a, b, sing);
+		      dq.set_options (quad_opts);
+		      val = dq.integrate (ier, nfun, abserr);
+		    }
+		  else
+		    {
+		      DefQuad dq (quad_user_function, a, b);
+		      dq.set_options (quad_opts);
+		      val = dq.integrate (ier, nfun, abserr);
+		    }
+		}
+	      break;
+
+	    default:
+	      panic_impossible ();
+	      break;
+	    }
+
+	  retval(3) = abserr;
+	  retval(2) = nfun;
+	  retval(1) = ier;
+	  retval(0) = val;
+	}
+
+      if (fcn_name.length())
+	clear_function (fcn_name);
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Fquad");
+
+  return retval;
+}
+
+/*
+
+%!function y = f (x) 
+%! y = x + 1;
+%!test
+%! [v, ier, nfun, err] = quad ("f", 0, 5);
+%! assert(ier == 0 && abs (v - 17.5) < sqrt (eps) && nfun > 0 && 
+%!        err < sqrt (eps))
+%!test
+%! [v, ier, nfun, err] = quad ("f", single(0), single(5));
+%! assert(ier == 0 && abs (v - 17.5) < sqrt (eps ("single")) && nfun > 0 && 
+%!        err < sqrt (eps ("single")))
+
+%!function y = f (x)
+%!  y = x .* sin (1 ./ x) .* sqrt (abs (1 - x));
+%!test
+%!  [v, ier, nfun, err] = quad ("f", 0.001, 3);
+%! assert((ier == 0 || ier == 1) && abs (v - 1.98194120273598) < sqrt (eps) && nfun > 0);
+%!test
+%!  [v, ier, nfun, err] = quad ("f", single(0.001), single(3));
+%! assert((ier == 0 || ier == 1) && abs (v - 1.98194120273598) < sqrt (eps ("single")) && nfun > 0);
+
+%!error <Invalid call to quad.*> quad ();
+
+%!error <Invalid call to quad.*> quad ("f", 1, 2, 3, 4, 5);
+
+%!test
+%! quad_options ("absolute tolerance", eps);
+%! assert(quad_options ("absolute tolerance") == eps);
+
+%!error <Invalid call to quad_options.*> quad_options (1, 2, 3);
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/qz.cc b/src/DLD-FUNCTIONS/qz.cc
new file mode 100644
index 0000000..e3aa3ac
--- /dev/null
+++ b/src/DLD-FUNCTIONS/qz.cc
@@ -0,0 +1,997 @@
+/*
+
+Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 A. S. Hodel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Generalized eigenvalue balancing via LAPACK
+
+// Author: A. S. Hodel <scotte at eng.auburn.edu>
+
+#undef DEBUG
+#undef DEBUG_SORT
+#undef DEBUG_EIG
+
+#include "config.h"
+
+#include <cfloat>
+
+#include <iostream>
+#include <iomanip>
+
+#include "CmplxQRP.h"
+#include "dbleQR.h"
+#include "f77-fcn.h"
+#include "lo-math.h"
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov.h"
+#include "pager.h"
+#if defined (DEBUG) || defined (DEBUG_SORT)
+#include "pr-output.h"
+#endif
+#include "symtab.h"
+#include "utils.h"
+#include "variables.h"
+
+typedef octave_idx_type (*sort_function) (const octave_idx_type& LSIZE, const double& ALPHA,
+			      const double& BETA, const double& S,
+			      const double& P);
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (dggbal, DGGBAL) (F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, double* A, const octave_idx_type& LDA,
+			     double* B, const octave_idx_type& LDB, octave_idx_type& ILO,
+			     octave_idx_type& IHI, double* LSCALE, double* RSCALE,
+			     double* WORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dggbak, DGGBAK) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO,
+			     const octave_idx_type& IHI, const double* LSCALE,
+			     const double* RSCALE, octave_idx_type& M, double* V,
+			     const octave_idx_type& LDV, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dgghrd, DGGHRD) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO,
+			     const octave_idx_type& IHI, double* A,
+			     const octave_idx_type& LDA, double* B,
+			     const octave_idx_type& LDB, double* Q,
+			     const octave_idx_type& LDQ, double* Z,
+			     const octave_idx_type& LDZ, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dhgeqz, DHGEQZ) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     const octave_idx_type& N, const octave_idx_type& ILO, const octave_idx_type& IHI,
+			     double* A, const octave_idx_type& LDA, double* B,
+			     const octave_idx_type& LDB, double* ALPHAR,
+			     double* ALPHAI, double* BETA, double* Q,
+			     const octave_idx_type& LDQ, double* Z,
+			     const octave_idx_type& LDZ, double* WORK,
+			     const octave_idx_type& LWORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (dlag2, DLAG2) (const double* A, const octave_idx_type& LDA, const double* B,
+			   const octave_idx_type& LDB, const double& SAFMIN,
+			   double& SCALE1, double& SCALE2,
+			   double& WR1, double& WR2, double& WI);
+
+  // Van Dooren's code (netlib.org: toms/590) for reordering
+  // GEP.  Only processes Z, not Q.
+  F77_RET_T
+  F77_FUNC (dsubsp, DSUBSP) (const octave_idx_type& NMAX, const octave_idx_type& N, double* A,
+			     double* B, double* Z, sort_function,
+			     const double& EPS, octave_idx_type& NDIM, octave_idx_type& FAIL,
+			     octave_idx_type* IND);
+
+  // documentation for DTGEVC incorrectly states that VR, VL are
+  // complex*16; they are declared in DTGEVC as double precision
+  // (probably a cut and paste problem fro ZTGEVC)
+  F77_RET_T
+  F77_FUNC (dtgevc, DTGEVC) (F77_CONST_CHAR_ARG_DECL,
+			     F77_CONST_CHAR_ARG_DECL,
+			     octave_idx_type* SELECT, const octave_idx_type& N, double* A,
+			     const octave_idx_type& LDA, double* B,
+			     const octave_idx_type& LDB, double* VL,
+			     const octave_idx_type& LDVL, double* VR,
+			     const octave_idx_type& LDVR, const octave_idx_type& MM,
+			     octave_idx_type& M, double* WORK, octave_idx_type& INFO
+			     F77_CHAR_ARG_LEN_DECL
+			     F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xdlamch, XDLAMCH) (F77_CONST_CHAR_ARG_DECL,
+			       double& retval
+			       F77_CHAR_ARG_LEN_DECL);
+
+  F77_RET_T
+  F77_FUNC (xdlange, XDLANGE) (F77_CONST_CHAR_ARG_DECL,
+			       const octave_idx_type&, const octave_idx_type&, const double*,
+			       const octave_idx_type&, double*, double&
+			       F77_CHAR_ARG_LEN_DECL);
+}
+
+// fcrhp, fin, fout, folhp:
+// routines for ordering of generalized eigenvalues
+// return 1 if  test is passed, 0 otherwise
+//    fin: |lambda| < 1
+//    fout: |lambda| >= 1
+//    fcrhp: real(lambda) >= 0
+//    folhp: real(lambda) < 0
+
+static octave_idx_type
+fcrhp (const octave_idx_type& lsize, const double& alpha,
+       const double& beta, const double& s, const double&)
+{
+  if (lsize == 1)
+    return (alpha*beta >= 0 ? 1 : -1);
+  else
+    return (s >= 0 ? 1 : -1);
+}
+
+static octave_idx_type
+fin (const octave_idx_type& lsize, const double& alpha,
+     const double& beta, const double&, const double& p)
+{
+  octave_idx_type retval;
+
+  if (lsize == 1)
+    retval = (fabs (alpha) < fabs (beta) ? 1 : -1);
+  else
+    retval = (fabs (p) < 1 ? 1 : -1);
+
+#ifdef DEBUG
+  std::cout << "qz: fin: retval=" << retval << std::endl;
+#endif
+
+  return retval;
+}
+
+static octave_idx_type
+folhp (const octave_idx_type& lsize, const double& alpha,
+       const double& beta, const double& s, const double&)
+{
+  if (lsize == 1)
+    return (alpha*beta < 0 ? 1 : -1);
+  else
+    return (s < 0 ? 1 : -1);
+}
+
+static octave_idx_type
+fout (const octave_idx_type& lsize, const double& alpha,
+      const double& beta, const double&, const double& p)
+{
+  if (lsize == 1)
+    return (fabs (alpha) >= fabs (beta) ? 1 : -1);
+  else
+    return (fabs (p) >= 1 ? 1 : -1);
+}
+
+DEFUN_DLD (qz, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{lambda} =} qz (@var{a}, @var{b})\n\
+Generalized eigenvalue problem @math{A x = s B x},\n\
+ at var{QZ} decomposition.  There are three ways to call this function:\n\
+ at enumerate\n\
+ at item @code{lambda = qz(A,B)}\n\
+\n\
+Computes the generalized eigenvalues\n\
+ at iftex\n\
+ at tex\n\
+$\\lambda$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at var{lambda}\n\
+ at end ifnottex\n\
+of @math{(A - s B)}.\n\
+ at item @code{[AA, BB, Q, Z, V, W, lambda] = qz (A, B)}\n\
+\n\
+Computes qz decomposition, generalized eigenvectors, and \n\
+generalized eigenvalues of @math{(A - sB)}\n\
+ at iftex\n\
+ at tex\n\
+$$ AV = BV{ \\rm diag }(\\lambda) $$\n\
+$$ W^T A = { \\rm diag }(\\lambda)W^T B $$\n\
+$$ AA = Q^T AZ, BB = Q^T BZ $$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at example\n\
+ at group\n\
+\n\
+    A*V = B*V*diag(lambda)\n\
+    W'*A = diag(lambda)*W'*B\n\
+    AA = Q'*A*Z, BB = Q'*B*Z\n\
+\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+with @var{Q} and @var{Z} orthogonal (unitary)= @var{I}\n\
+\n\
+ at item @code{[AA,BB,Z@{, lambda@}] = qz(A,B,opt)}\n\
+\n\
+As in form [2], but allows ordering of generalized eigenpairs\n\
+for (e.g.) solution of discrete time algebraic Riccati equations.\n\
+Form 3 is not available for complex matrices, and does not compute\n\
+the generalized eigenvectors @var{V}, @var{W}, nor the orthogonal matrix @var{Q}.\n\
+ at table @var\n\
+ at item opt\n\
+for ordering eigenvalues of the GEP pencil.  The leading block\n\
+of the revised pencil contains all eigenvalues that satisfy:\n\
+ at table @code\n\
+ at item \"N\"\n\
+= unordered (default) \n\
+\n\
+ at item \"S\"\n\
+= small: leading block has all |lambda| <=1 \n\
+\n\
+ at item \"B\"\n\
+= big: leading block has all |lambda| >= 1 \n\
+\n\
+ at item \"-\"\n\
+= negative real part: leading block has all eigenvalues\n\
+in the open left half-plane\n\
+\n\
+ at item \"+\"\n\
+= non-negative real part: leading block has all eigenvalues\n\
+in the closed right half-plane\n\
+ at end table\n\
+ at end table\n\
+ at end enumerate\n\
+\n\
+Note: qz performs permutation balancing, but not scaling (see balance).\n\
+Order of output arguments was selected for compatibility with @sc{matlab}\n\
+\n\
+ at seealso{balance, eig, schur}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+#ifdef DEBUG
+  std::cout << "qz: nargin = " << nargin << ", nargout = " << nargout << std::endl;
+#endif
+
+  if (nargin < 2 || nargin > 3 || nargout > 7)
+    {
+      print_usage ();
+      return retval;
+    }
+  else if (nargin == 3 && (nargout < 3 || nargout > 4))
+    {
+      error ("qz: invalid number of output arguments for form [3] call");
+      return retval;
+    }
+
+#ifdef DEBUG
+  std::cout << "qz: determine ordering option" << std::endl;
+#endif
+
+  // Determine ordering option
+  volatile char ord_job = 0;
+  static double safmin;
+
+  if (nargin == 2)
+    ord_job = 'N';
+  else if (!args(2).is_string ())
+    {
+      error ("qz: argument 3 must be a string");
+      return retval;
+    }
+  else
+    {
+      std::string tmp = args(2).string_value ();
+
+      if (! tmp.empty ())
+	ord_job = tmp[0];
+
+      if (! (ord_job == 'N' || ord_job == 'n'
+	     || ord_job == 'S' || ord_job == 's'
+	     || ord_job == 'B' || ord_job == 'b'
+	     || ord_job == '+' || ord_job == '-'))
+	{
+	  error ("qz: invalid order option");
+	  return retval;
+	}
+
+      // overflow constant required by dlag2
+      F77_FUNC (xdlamch, XDLAMCH) (F77_CONST_CHAR_ARG2 ("S", 1),
+				   safmin
+				   F77_CHAR_ARG_LEN (1));
+
+#ifdef DEBUG_EIG
+      std::cout << "qz: initial value of safmin=" << setiosflags (std::ios::scientific)
+	   << safmin << std::endl;
+#endif
+
+      // some machines (e.g., DEC alpha) get safmin = 0;
+      // for these, use eps instead to avoid problems in dlag2
+      if (safmin == 0)
+	{
+#ifdef DEBUG_EIG
+	  std::cout << "qz: DANGER WILL ROBINSON: safmin is 0!" << std::endl;
+#endif
+
+	  F77_FUNC (xdlamch, XDLAMCH) (F77_CONST_CHAR_ARG2 ("E", 1),
+				       safmin
+				       F77_CHAR_ARG_LEN (1));
+
+#ifdef DEBUG_EIG
+	  std::cout << "qz: safmin set to " << setiosflags (std::ios::scientific)
+	       << safmin << std::endl;
+#endif
+	}
+    }
+
+#ifdef DEBUG
+  std::cout << "qz: check argument 1" << std::endl;
+#endif
+
+  // Argument 1: check if it's o.k. dimensioned
+  octave_idx_type nn = args(0).rows ();
+
+#ifdef DEBUG
+  std::cout << "argument 1 dimensions: (" << nn << "," << args(0).columns () << ")"
+       << std::endl;
+#endif
+
+  int arg_is_empty = empty_arg ("qz", nn, args(0).columns ());
+
+  if (arg_is_empty < 0)
+    {
+      gripe_empty_arg ("qz: parameter 1", 0);
+      return retval;
+    }
+  else if (arg_is_empty > 0)
+    {
+      gripe_empty_arg ("qz: parameter 1; continuing", 0);
+      return octave_value_list (2, Matrix ());
+    }
+  else if (args(0).columns () != nn)
+    {
+      gripe_square_matrix_required ("qz");
+      return retval;
+    }
+
+  // Argument 1: dimensions look good; get the value
+  Matrix aa;
+  ComplexMatrix caa;
+
+  if (args(0).is_complex_type ())
+    caa = args(0).complex_matrix_value ();
+  else
+    aa = args(0).matrix_value ();
+
+  if (error_state)
+    return retval;
+
+#ifdef DEBUG
+  std::cout << "qz: check argument 2" << std::endl;
+#endif
+
+  // Extract argument 2 (bb, or cbb if complex)
+  if ((nn != args(1).columns ()) || (nn != args(1).rows ()))
+    {
+      gripe_nonconformant ();
+      return retval;
+    }
+
+  Matrix bb;
+  ComplexMatrix cbb;
+
+  if (args(1).is_complex_type ())
+    cbb = args(1).complex_matrix_value ();
+  else
+    bb = args(1).matrix_value ();
+
+  if (error_state)
+    return retval;
+
+  // Both matrices loaded, now let's check what kind of arithmetic:
+  //declared static to avoid compiler warnings about long jumps, vforks.
+
+  static int complex_case
+    = (args(0).is_complex_type () || args(1).is_complex_type ());
+
+  if (nargin == 3 && complex_case)
+    {
+      error ("qz: cannot re-order complex qz decomposition.");
+      return retval;
+    }
+
+  // first, declare variables used in both the real and complex case
+  Matrix QQ(nn,nn), ZZ(nn,nn), VR(nn,nn), VL(nn,nn);
+  RowVector alphar(nn), alphai(nn), betar(nn);
+
+  ComplexMatrix CQ(nn,nn), CZ(nn,nn), CVR(nn,nn), CVL(nn,nn);
+  octave_idx_type ilo, ihi, info;
+  char compq = (nargout >= 3 ? 'V' : 'N');
+  char compz = (nargout >= 4 ? 'V' : 'N');
+
+  // initialize Q, Z to identity if we need either of them
+  if (compq == 'V' || compz == 'V')
+    for (octave_idx_type ii = 0; ii < nn; ii++)
+      for (octave_idx_type jj = 0; jj < nn; jj++)
+	{
+	  OCTAVE_QUIT;
+	  QQ(ii,jj) = ZZ(ii,jj) = (ii == jj ? 1.0 : 0.0);
+	}
+
+  // always perform permutation balancing
+  const char bal_job = 'P';
+  RowVector lscale(nn), rscale(nn), work(6*nn);
+
+  if (complex_case)
+    {
+      error ("Complex case not implemented yet");
+      return retval;
+    }
+  else
+    {
+#ifdef DEBUG
+      if (compq == 'V')
+	std::cout << "qz: performing balancing; QQ=" << std::endl << QQ << std::endl;
+#endif
+
+      F77_XFCN (dggbal, DGGBAL,
+		(F77_CONST_CHAR_ARG2 (&bal_job, 1),
+		 nn, aa.fortran_vec (), nn, bb.fortran_vec (),
+		 nn, ilo, ihi, lscale.fortran_vec (),
+		 rscale.fortran_vec (), work.fortran_vec (), info
+		 F77_CHAR_ARG_LEN (1)));
+    }
+
+  // Since we just want the balancing matrices, we can use dggbal
+  // for both the real and complex cases;
+  // left first
+
+  if (compq == 'V')
+    {
+      F77_XFCN (dggbak, DGGBAK,
+		(F77_CONST_CHAR_ARG2 (&bal_job, 1),
+		 F77_CONST_CHAR_ARG2 ("L", 1),
+		 nn, ilo, ihi, lscale.data (), rscale.data (),
+		 nn, QQ.fortran_vec (), nn, info
+		 F77_CHAR_ARG_LEN (1)
+		 F77_CHAR_ARG_LEN (1)));
+
+#ifdef DEBUG
+      if (compq == 'V')
+	std::cout << "qz: balancing done; QQ=" << std::endl << QQ << std::endl;
+#endif
+  }
+
+  // then right
+  if (compz == 'V')
+    {
+      F77_XFCN (dggbak, DGGBAK,
+		(F77_CONST_CHAR_ARG2 (&bal_job, 1),
+		 F77_CONST_CHAR_ARG2 ("R", 1),
+		 nn, ilo, ihi, lscale.data (), rscale.data (),
+		 nn, ZZ.fortran_vec (), nn, info
+		 F77_CHAR_ARG_LEN (1)
+		 F77_CHAR_ARG_LEN (1)));
+
+#ifdef DEBUG
+      if (compz == 'V')
+	std::cout << "qz: balancing done; ZZ=" << std::endl << ZZ << std::endl;
+#endif
+    }
+
+  static char qz_job;
+  qz_job = (nargout < 2 ? 'E' : 'S');	
+
+  if (complex_case)
+    {
+      // complex case
+      if (args(0).is_real_type ())
+	caa = ComplexMatrix (aa);
+
+      if (args(1).is_real_type ())
+	cbb = ComplexMatrix (bb);
+
+      if (compq == 'V')
+	CQ = ComplexMatrix (QQ);
+
+      if (compz == 'V')
+	CZ = ComplexMatrix (ZZ);
+
+      error ("complex case not done yet");
+      return retval;
+    }
+  else  	// real matrices case
+    {
+#ifdef DEBUG
+      std::cout << "qz: peforming qr decomposition of bb" << std::endl;
+#endif
+
+      // compute the QR factorization of bb
+      QR bqr (bb);
+
+#ifdef DEBUG
+      std::cout << "qz: qr (bb) done; now peforming qz decomposition" << std::endl;
+#endif
+
+      bb = bqr.R ();
+
+#ifdef DEBUG
+      std::cout << "qz: extracted bb" << std::endl;
+#endif
+
+      aa = (bqr.Q ()).transpose ()*aa;
+
+#ifdef DEBUG
+      std::cout << "qz: updated aa " << std::endl;
+      std::cout << "bqr.Q () = " << std::endl << bqr.Q () << std::endl;
+
+      if (compq == 'V')
+	std::cout << "QQ =" << QQ << std::endl;
+#endif
+
+      if (compq == 'V')
+	QQ = QQ*bqr.Q ();
+
+#ifdef DEBUG
+      std::cout << "qz: precursors done..." << std::endl;
+#endif
+
+#ifdef DEBUG
+      std::cout << "qz: compq = " << compq << ", compz = " << compz << std::endl;
+#endif
+
+      // reduce  to generalized hessenberg form
+      F77_XFCN (dgghrd, DGGHRD,
+		(F77_CONST_CHAR_ARG2 (&compq, 1),
+		 F77_CONST_CHAR_ARG2 (&compz, 1),
+		 nn, ilo, ihi, aa.fortran_vec (),
+		 nn, bb.fortran_vec (), nn, QQ.fortran_vec (), nn,
+		 ZZ.fortran_vec (), nn, info
+		 F77_CHAR_ARG_LEN (1)
+		 F77_CHAR_ARG_LEN (1)));
+
+      // check if just computing generalized eigenvalues or if we're
+      // actually computing the decomposition
+
+      // reduce to generalized Schur form
+      F77_XFCN (dhgeqz, DHGEQZ,
+		(F77_CONST_CHAR_ARG2 (&qz_job, 1),
+		 F77_CONST_CHAR_ARG2 (&compq, 1),
+		 F77_CONST_CHAR_ARG2 (&compz, 1),
+		 nn, ilo, ihi, aa.fortran_vec (), nn, bb.fortran_vec (),
+		 nn, alphar.fortran_vec (), alphai.fortran_vec (),
+		 betar.fortran_vec (), QQ.fortran_vec (), nn,
+		 ZZ.fortran_vec (), nn, work.fortran_vec (), nn, info
+		 F77_CHAR_ARG_LEN (1)
+		 F77_CHAR_ARG_LEN (1)
+		 F77_CHAR_ARG_LEN (1)));
+    }
+
+  // order the QZ decomposition?
+  if (! (ord_job == 'N' || ord_job == 'n'))
+    {
+      if (complex_case)
+	{
+	  // probably not needed, but better be safe
+	  error ("qz: cannot re-order complex qz decomposition.");
+	  return retval;
+	}
+      else
+	{
+#ifdef DEBUG_SORT
+	  std::cout << "qz: ordering eigenvalues: ord_job = "
+		    << ord_job << std::endl;
+#endif
+
+	  // declared static to avoid vfork/long jump compiler complaints
+	  static sort_function sort_test;
+	  sort_test = 0;
+
+	  switch (ord_job)
+	    {
+	    case 'S':
+	    case 's':
+	      sort_test = &fin;
+	      break;
+
+	    case 'B':
+	    case 'b':
+	      sort_test = &fout;
+	      break;
+
+	    case '+':
+	      sort_test = &fcrhp;
+	      break;
+
+	    case '-':
+	      sort_test = &folhp;
+	      break;
+
+	    default:
+	      // invalid order option (should never happen, since we
+	      // checked the options at the top).
+	      panic_impossible ();
+	      break;
+	    }
+
+	  octave_idx_type ndim, fail;
+	  double inf_norm;
+
+	  F77_XFCN (xdlange, XDLANGE,
+		    (F77_CONST_CHAR_ARG2 ("I", 1),
+		     nn, nn, aa.data (), nn, work.fortran_vec (), inf_norm
+		     F77_CHAR_ARG_LEN (1)));
+
+	  double eps = DBL_EPSILON*inf_norm*nn;
+
+#ifdef DEBUG_SORT
+	  std::cout << "qz: calling dsubsp: aa=" << std::endl;
+	  octave_print_internal (std::cout, aa, 0);
+	  std::cout << std::endl << "bb="  << std::endl;
+	  octave_print_internal (std::cout, bb, 0);
+	  if (compz == 'V')
+	    {
+	      std::cout << std::endl << "ZZ="  << std::endl;
+	      octave_print_internal (std::cout, ZZ, 0);
+	    }
+	  std::cout << std::endl;
+	  std::cout << "alphar = " << std::endl;
+	  octave_print_internal (std::cout, (Matrix) alphar, 0);
+	  std::cout << std::endl << "alphai = " << std::endl;
+	  octave_print_internal (std::cout, (Matrix) alphai, 0);
+	  std::cout << std::endl << "beta = " << std::endl;
+	  octave_print_internal (std::cout, (Matrix) betar, 0);
+	  std::cout << std::endl;
+#endif
+
+	  Array<octave_idx_type> ind (nn);
+
+	  F77_XFCN (dsubsp, DSUBSP,
+		    (nn, nn, aa.fortran_vec (), bb.fortran_vec (),
+		     ZZ.fortran_vec (), sort_test, eps, ndim, fail,
+		     ind.fortran_vec ()));
+
+#ifdef DEBUG
+	  std::cout << "qz: back from dsubsp: aa=" << std::endl;
+	  octave_print_internal (std::cout, aa, 0);
+	  std::cout << std::endl << "bb="  << std::endl;
+	  octave_print_internal (std::cout, bb, 0);
+	  if (compz == 'V')
+	    {
+	      std::cout << std::endl << "ZZ="  << std::endl;
+	      octave_print_internal (std::cout, ZZ, 0);
+	    }
+	  std::cout << std::endl;
+#endif
+
+	  // manually update alphar, alphai, betar
+	  static int jj;
+
+	  jj=0;
+	  while (jj < nn)
+	    {
+#ifdef DEBUG_EIG
+	      std::cout << "computing gen eig #" << jj << std::endl;
+#endif
+
+	      static int zcnt;	// number of zeros in this block
+
+	      if (jj == (nn-1))
+		zcnt = 1;
+	      else if (aa(jj+1,jj) == 0)
+		zcnt = 1;
+	      else zcnt = 2;
+
+	      if (zcnt == 1)  // real zero
+		{
+#ifdef DEBUG_EIG
+		  std::cout << "  single gen eig:" << std::endl;
+		  std::cout << "  alphar(" << jj << ") = " << aa(jj,jj) << std::endl;
+		  std::cout << "  betar( " << jj << ") = " << bb(jj,jj) << std::endl;
+		  std::cout << "  alphai(" << jj << ") = 0" << std::endl;
+#endif
+
+		  alphar(jj) = aa(jj,jj);
+		  alphai(jj) = 0;
+		  betar(jj) = bb(jj,jj);
+		}
+	      else
+		{
+		  // complex conjugate pair
+#ifdef DEBUG_EIG
+		  std::cout << "qz: calling dlag2:" << std::endl;
+		  std::cout << "safmin="
+		       << setiosflags (std::ios::scientific) << safmin << std::endl;
+
+		  for (int idr = jj; idr <= jj+1; idr++)
+		    {
+		      for (int idc = jj; idc <= jj+1; idc++)
+			{
+			  std::cout << "aa(" << idr << "," << idc << ")="
+			       << aa(idr,idc) << std::endl;
+			  std::cout << "bb(" << idr << "," << idc << ")="
+			       << bb(idr,idc) << std::endl;
+			}
+		    }
+#endif
+
+		  // FIXME -- probably should be using
+		  // fortran_vec instead of &aa(jj,jj) here.
+
+		  double scale1, scale2, wr1, wr2, wi;
+		  const double *aa_ptr = aa.data () + jj*nn+jj;
+		  const double *bb_ptr = bb.data () + jj*nn+jj;
+		  F77_XFCN (dlag2, DLAG2,
+			    (aa_ptr, nn, bb_ptr, nn, safmin,
+			     scale1, scale2, wr1, wr2, wi));
+
+#ifdef DEBUG_EIG
+		  std::cout << "dlag2 returns: scale1=" << scale1
+		       << "\tscale2=" << scale2 << std::endl
+		       << "\twr1=" << wr1 << "\twr2=" << wr2
+		       << "\twi=" << wi << std::endl;
+#endif
+
+		  // just to be safe, check if it's a real pair
+		  if (wi == 0)
+		    {
+		      alphar(jj) = wr1;
+		      alphai(jj) = 0;
+		      betar(jj) = scale1;
+		      alphar(jj+1) = wr2;
+		      alphai(jj+1) = 0;
+		      betar(jj+1) = scale2;
+		    }
+		  else
+		    {
+		      alphar(jj) = alphar(jj+1)=wr1;
+		      alphai(jj) = -(alphai(jj+1) = wi);
+		      betar(jj)  = betar(jj+1) = scale1;
+		    }
+		}
+
+	      // advance past this block
+	      jj += zcnt;
+	    }
+
+#ifdef DEBUG_SORT
+	  std::cout << "qz: back from dsubsp: aa=" << std::endl;
+	  octave_print_internal (std::cout, aa, 0);
+	  std::cout << std::endl << "bb="  << std::endl;
+	  octave_print_internal (std::cout, bb, 0);
+
+	  if (compz == 'V')
+	    {
+	      std::cout << std::endl << "ZZ="  << std::endl;
+	      octave_print_internal (std::cout, ZZ, 0);
+	    }
+	  std::cout << std::endl << "qz: ndim=" << ndim << std::endl
+	       << "fail=" << fail << std::endl;
+	  std::cout << "alphar = " << std::endl;
+	  octave_print_internal (std::cout, (Matrix) alphar, 0);
+	  std::cout << std::endl << "alphai = " << std::endl;
+	  octave_print_internal (std::cout, (Matrix) alphai, 0);
+	  std::cout << std::endl << "beta = " << std::endl;
+	  octave_print_internal (std::cout, (Matrix) betar, 0);
+	  std::cout << std::endl;
+#endif
+	}
+    }
+
+  // compute  generalized eigenvalues?
+  ComplexColumnVector gev;
+
+  if (nargout < 2 || nargout == 7 || (nargin == 3 && nargout == 4))
+    {
+      if (complex_case)
+	{
+	  error ("complex case not yet implemented");
+	  return retval;
+	}
+      else
+	{
+#ifdef DEBUG
+	  std::cout << "qz: computing generalized eigenvalues" << std::endl;
+#endif
+
+	  // return finite generalized eigenvalues
+	  int cnt = 0;
+
+	  for (int ii = 0; ii < nn; ii++)
+	    if (betar(ii) != 0)
+	      cnt++;
+
+	  ComplexColumnVector tmp(cnt);
+
+	  cnt = 0;
+	  for (int ii = 0; ii < nn; ii++)
+	    if (betar(ii) != 0)
+	      tmp(cnt++) = Complex(alphar(ii), alphai(ii))/betar(ii);
+	  gev = tmp;
+	}
+    }
+
+  // right, left eigenvector matrices
+  if (nargout >= 5)
+    {
+      char side = (nargout == 5 ? 'R' : 'B');	// which side to compute?
+      char howmny = 'B';  // compute all of them and backtransform
+      octave_idx_type *select = 0; // dummy pointer; select is not used.
+      octave_idx_type m;
+
+      if (complex_case)
+	{
+	  error ("complex type not yet implemented");
+	  return retval;
+	}
+      else
+	{
+#ifdef DEBUG
+	  std::cout << "qz: computing  generalized eigenvectors" << std::endl;
+#endif
+
+	  VL = QQ;
+	  VR = ZZ;
+
+	  F77_XFCN (dtgevc, DTGEVC,
+		    (F77_CONST_CHAR_ARG2 (&side, 1),
+		     F77_CONST_CHAR_ARG2 (&howmny, 1),
+		     select, nn, aa.fortran_vec (), nn, bb.fortran_vec (),
+		     nn, VL.fortran_vec (), nn, VR.fortran_vec (), nn, nn,
+		     m, work.fortran_vec (), info
+		     F77_CHAR_ARG_LEN (1)
+		     F77_CHAR_ARG_LEN (1)));
+
+	  // now construct the complex form of VV, WW
+	  int jj = 0;
+
+	  while (jj < nn)
+	    {
+	      OCTAVE_QUIT;
+
+	      // see if real or complex eigenvalue
+	      int cinc = 2;	// column increment; assume complex eigenvalue
+
+	      if (jj == (nn-1))
+		cinc = 1;	// single column
+	      else if (aa(jj+1,jj) == 0)
+		cinc = 1;
+
+	      // now copy the eigenvector (s) to CVR, CVL
+	      if (cinc == 1)
+		{
+		  for (int ii = 0; ii < nn; ii++)
+		    CVR(ii,jj) = VR(ii,jj);
+
+		  if (side == 'B')
+		    for (int ii = 0; ii < nn; ii++)
+		      CVL(ii,jj) = VL(ii,jj);
+		}
+	      else
+		{
+		  // double column; complex vector
+
+		  for (int ii = 0; ii < nn; ii++)
+		    {
+		      CVR(ii,jj) = Complex (VR(ii,jj), VR(ii,jj+1));
+		      CVR(ii,jj+1) = Complex (VR(ii,jj), -VR(ii,jj+1));
+		    }
+
+		  if (side == 'B')
+		    for (int ii = 0; ii < nn; ii++)
+		      {
+			CVL(ii,jj) = Complex (VL(ii,jj), VL(ii,jj+1));
+			CVL(ii,jj+1) = Complex (VL(ii,jj), -VL(ii,jj+1));
+		      }
+		}
+
+	      // advance to next eigenvectors (if any)
+	      jj += cinc;
+	    }
+	}
+    }
+
+  switch (nargout)
+    {
+    case 7:
+      retval(6) = gev;
+
+    case 6:	// return eigenvectors
+      retval(5) = CVL;
+
+    case 5:	// return eigenvectors
+      retval(4) = CVR;
+
+    case 4:
+      if (nargin == 3)
+	{
+#ifdef DEBUG
+	  std::cout << "qz: sort: retval(3) = gev = " << std::endl;
+	  octave_print_internal (std::cout, gev);
+	  std::cout << std::endl;
+#endif
+	  retval(3) = gev;
+	}
+      else
+	retval(3) = ZZ;
+
+    case 3:
+      if (nargin == 3)
+	retval(2) = ZZ;
+      else
+	retval(2) = QQ;
+
+    case 2:
+#ifdef DEBUG
+      std::cout << "qz: retval (1) = bb = " << std::endl;
+      octave_print_internal (std::cout, bb, 0);
+      std::cout << std::endl << "qz: retval(0) = aa = " <<std::endl;
+      octave_print_internal (std::cout, aa, 0);
+      std::cout << std::endl;
+#endif
+      retval(1) = bb;
+      retval(0) = aa;
+      break;
+
+    case 1:
+    case 0:
+#ifdef DEBUG
+      std::cout << "qz: retval(0) = gev = " << gev << std::endl;
+#endif
+      retval(0) = gev;
+      break;
+
+    default:
+      error ("qz: too many return arguments.");
+      break;
+  }
+
+#ifdef DEBUG
+  std::cout << "qz: exiting (at long last)" << std::endl;
+#endif
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/rand.cc b/src/DLD-FUNCTIONS/rand.cc
new file mode 100644
index 0000000..2d73bad
--- /dev/null
+++ b/src/DLD-FUNCTIONS/rand.cc
@@ -0,0 +1,1024 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctime>
+
+#include <string>
+
+#include "f77-fcn.h"
+#include "lo-mappers.h"
+#include "oct-rand.h"
+#include "quit.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "unwind-prot.h"
+#include "utils.h"
+
+/*
+%!shared __random_statistical_tests__
+%! % Flag whether the statistical tests should be run in "make check" or not
+%! __random_statistical_tests__ = 0;
+*/
+
+static octave_value
+do_rand (const octave_value_list& args, int nargin, const char *fcn,
+	 bool additional_arg = false)
+{
+  octave_value retval;
+  NDArray a;
+  int idx = 0;
+  dim_vector dims;
+
+  if (additional_arg)
+    {
+      if (nargin == 0)
+	{
+	  error ("%s: expecting at least one argument", fcn);
+	  goto done;
+	}
+      else if (args(0).is_string())
+	additional_arg = false;
+      else
+	{
+	  a = args(0).array_value ();
+	  if (error_state)
+	    {
+	      error ("%s: expecting scalar or matrix arguments", fcn);
+	      goto done;
+	    }
+	  idx++;
+	  nargin--;
+	}
+    }
+
+  switch (nargin)
+    {
+    case 0:
+      {
+	if (additional_arg)
+	  dims = a.dims ();
+	else
+	  {
+	    dims.resize (2);
+
+	    dims(0) = 1;
+	    dims(1) = 1;
+	  }
+	goto gen_matrix;
+      }
+      break;
+
+    case 1:
+      {
+	octave_value tmp = args(idx);
+
+	if (tmp.is_string ())
+	  {
+	    std::string s_arg = tmp.string_value ();
+
+	    if (s_arg == "dist")
+	      {
+		retval = octave_rand::distribution ();
+	      }
+	    else if (s_arg == "seed")
+	      {
+		retval = octave_rand::seed ();
+	      }
+	    else if (s_arg == "state" || s_arg == "twister")
+	      {
+		retval = octave_rand::state (fcn);
+	      }
+	    else if (s_arg == "uniform")
+	      {
+		octave_rand::uniform_distribution ();
+	      }
+	    else if (s_arg == "normal")
+	      {
+		octave_rand::normal_distribution ();
+	      }
+	    else if (s_arg == "exponential")
+	      {
+		octave_rand::exponential_distribution ();
+	      }
+	    else if (s_arg == "poisson")
+	      {
+		octave_rand::poisson_distribution ();
+	      }
+	    else if (s_arg == "gamma")
+	      {
+		octave_rand::gamma_distribution ();
+	      }
+	    else
+	      error ("%s: unrecognized string argument", fcn);
+	  }
+	else if (tmp.is_scalar_type ())
+	  {
+	    double dval = tmp.double_value ();
+
+	    if (xisnan (dval))
+	      {
+		error ("%s: NaN is invalid a matrix dimension", fcn);
+	      }
+	    else
+	      {
+		dims.resize (2);
+
+		dims(0) = NINTbig (tmp.double_value ());
+		dims(1) = NINTbig (tmp.double_value ());
+
+		if (! error_state)
+		  goto gen_matrix;
+	      }
+	  }
+	else if (tmp.is_range ())
+	  {
+	    Range r = tmp.range_value ();
+
+	    if (r.all_elements_are_ints ())
+	      {
+		octave_idx_type n = r.nelem ();
+
+		dims.resize (n);
+
+		octave_idx_type base = NINTbig (r.base ());
+		octave_idx_type incr = NINTbig (r.inc ());
+		octave_idx_type lim = NINTbig (r.limit ());
+
+		if (base < 0 || lim < 0)
+		  error ("%s: all dimensions must be nonnegative", fcn);
+		else
+		  {
+		    for (octave_idx_type i = 0; i < n; i++)
+		      {
+			dims(i) = base;
+			base += incr;
+		      }
+
+		    goto gen_matrix;
+		  }
+	      }
+	    else
+	      error ("%s: expecting all elements of range to be integers",
+		     fcn);
+	  }
+	else if (tmp.is_matrix_type ())
+	  {
+	    Array<int> iv = tmp.int_vector_value (true);
+
+	    if (! error_state)
+	      {
+		octave_idx_type len = iv.length ();
+
+		dims.resize (len);
+
+		for (octave_idx_type i = 0; i < len; i++)
+		  {
+		    octave_idx_type elt = iv(i);
+
+		    if (elt < 0)
+		      {
+			error ("%s: all dimensions must be nonnegative", fcn);
+			goto done;
+		      }
+
+		    dims(i) = iv(i);
+		  }
+
+		goto gen_matrix;
+	      }
+	    else
+	      error ("%s: expecting integer vector", fcn);
+	  }
+	else
+	  {
+	    gripe_wrong_type_arg ("rand", tmp);
+	    return retval;
+	  }
+      }
+      break;
+
+    default:
+      {
+	octave_value tmp = args(idx);
+
+	if (nargin == 2 && tmp.is_string ())
+	  {
+	    std::string ts = tmp.string_value ();
+
+	    if (ts == "seed")
+	      {
+		if (args(idx+1).is_real_scalar ())
+		  {
+		    double d = args(idx+1).double_value ();
+
+		    if (! error_state)
+		      octave_rand::seed (d);
+		  }
+		else
+		  error ("%s: seed must be a real scalar", fcn);
+	      }
+	    else if (ts == "state" || ts == "twister")
+	      {
+		ColumnVector s = 
+		  ColumnVector (args(idx+1).vector_value(false, true));
+
+		if (! error_state)
+		  octave_rand::state (s, fcn);
+	      }
+	    else
+	      error ("%s: unrecognized string argument", fcn);
+	  }
+	else
+	  {
+	    dims.resize (nargin);
+
+	    for (int i = 0; i < nargin; i++)
+	      {
+		dims(i) = args(idx+i).int_value ();
+
+		if (error_state)
+		  {
+		    error ("%s: expecting integer arguments", fcn);
+		    goto done;
+		  }
+	      }
+
+	    goto gen_matrix;
+	  }
+      }
+      break;
+    }
+
+ done:
+
+  return retval;
+
+ gen_matrix:
+
+  dims.chop_trailing_singletons ();
+
+  if (additional_arg)
+    {
+      if (a.length() == 1)
+	return octave_rand::nd_array (dims, a(0));
+      else
+	{
+	  if (a.dims() != dims)
+	    {
+	      error ("%s: mismatch in argument size", fcn);
+	      return retval;
+	    }
+	  octave_idx_type len = a.length ();
+	  NDArray m (dims);
+	  double *v = m.fortran_vec ();
+	  for (octave_idx_type i = 0; i < len; i++)
+	    v[i] = octave_rand::scalar (a(i));
+	  return m;
+	}
+    }
+  else
+    return octave_rand::nd_array (dims);
+}
+
+DEFUN_DLD (rand, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} rand (@var{x})\n\
+ at deftypefnx {Loadable Function} {} rand (@var{n}, @var{m})\n\
+ at deftypefnx {Loadable Function} {} rand (\"state\", @var{x})\n\
+ at deftypefnx {Loadable Function} {} rand (\"seed\", @var{x})\n\
+Return a matrix with random elements uniformly distributed on the\n\
+interval (0, 1).  The arguments are handled the same as the arguments\n\
+for @code{eye}.\n\
+\n\
+You can query the state of the random number generator using the\n\
+form\n\
+\n\
+ at example\n\
+v = rand (\"state\")\n\
+ at end example\n\
+\n\
+This returns a column vector @var{v} of length 625.  Later, you can\n\
+restore the random number generator to the state @var{v}\n\
+using the form\n\
+\n\
+ at example\n\
+rand (\"state\", v)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+You may also initialize the state vector from an arbitrary vector of\n\
+length <= 625 for @var{v}.  This new state will be a hash based on the\n\
+value of @var{v}, not @var{v} itself.\n\
+\n\
+By default, the generator is initialized from @code{/dev/urandom} if it is\n\
+available, otherwise from cpu time, wall clock time and the current\n\
+fraction of a second.\n\
+\n\
+To compute the pseudo-random sequence, @code{rand} uses the Mersenne\n\
+Twister with a period of @math{2^{19937}-1} (See M. Matsumoto and T. Nishimura,\n\
+ at cite{Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator}, ACM Trans. on\n\
+Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998,\n\
+ at url{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html}).\n\
+Do @strong{not} use for cryptography without securely hashing\n\
+several returned values together, otherwise the generator state\n\
+can be learned after reading 624 consecutive values.\n\
+\n\
+Older versions of Octave used a different random number generator.\n\
+The new generator is used by default\n\
+as it is significantly faster than the old generator, and produces\n\
+random numbers with a significantly longer cycle time.  However, in\n\
+some circumstances it might be desirable to obtain the same random\n\
+sequences as used by the old generators.  To do this the keyword\n\
+\"seed\" is used to specify that the old generators should be use,\n\
+as in\n\
+\n\
+ at example\n\
+rand (\"seed\", val)\n\
+ at end example\n\
+\n\
+which sets the seed of the generator to @var{val}.  The seed of the\n\
+generator can be queried with\n\
+\n\
+ at example\n\
+s = rand (\"seed\")\n\
+ at end example\n\
+\n\
+However, it should be noted that querying the seed will not cause\n\
+ at code{rand} to use the old generators, only setting the seed will.\n\
+To cause @code{rand} to once again use the new generators, the\n\
+keyword \"state\" should be used to reset the state of the @code{rand}.\n\
+ at seealso{randn, rande, randg, randp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  retval = do_rand (args, nargin, "rand");
+
+  return retval;
+}
+
+// FIXME -- The old generator (selected when "seed" is set) will not
+// work properly if compiled to use 64-bit integers.
+
+/*
+%!test # 'state' can be a scalar
+%! rand('state',12); x = rand(1,4);
+%! rand('state',12); y = rand(1,4);
+%! assert(x,y);
+%!test # 'state' can be a vector
+%! rand('state',[12,13]); x=rand(1,4);
+%! rand('state',[12;13]); y=rand(1,4);
+%! assert(x,y);
+%!test # querying 'state' doesn't disturb sequence
+%! rand('state',12); rand(1,2); x=rand(1,2);
+%! rand('state',12); rand(1,2);
+%! s=rand('state'); y=rand(1,2);
+%! assert(x,y);
+%! rand('state',s); z=rand(1,2);
+%! assert(x,z);
+%!test # 'seed' must be a scalar
+%! rand('seed',12); x = rand(1,4);
+%! rand('seed',12); y = rand(1,4);
+%! assert(x,y);
+%!error(rand('seed',[12,13]))
+%!test # querying 'seed' returns a value which can be used later
+%! s=rand('seed'); x=rand(1,2);
+%! rand('seed',s); y=rand(1,2);
+%! assert(x,y);
+%!test # querying 'seed' doesn't disturb sequence
+%! rand('seed',12); rand(1,2); x=rand(1,2);
+%! rand('seed',12); rand(1,2);
+%! s=rand('seed'); y=rand(1,2);
+%! assert(x,y);
+%! rand('seed',s); z=rand(1,2);
+%! assert(x,z);
+*/
+
+/*
+%!test
+%! % Test fixed state
+%! rand("state",1);
+%! assert (rand(1,6), [0.1343642441124013 0.8474337369372327 0.763774618976614 0.2550690257394218 0.495435087091941 0.4494910647887382],1e-6);
+%!test
+%! % Test fixed seed
+%! rand("seed",1);
+%! assert (rand(1,6), [0.8668024251237512 0.9126510815694928 0.09366085007786751 0.1664607301354408 0.7408077004365623 0.7615650338120759],1e-6);
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   rand("state",12);
+%!   x = rand(100000,1);
+%!   assert(max(x)<1.); %*** Please report this!!! ***
+%!   assert(min(x)>0.); %*** Please report this!!! ***
+%!   assert(mean(x),0.5,0.0024);
+%!   assert(var(x),1/48,0.0632);
+%!   assert(skewness(x),0,0.012); 
+%!   assert(kurtosis(x),-6/5,0.0094);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   rand("seed",12);
+%!   x = rand(100000,1);
+%!   assert(max(x)<1.); %*** Please report this!!! ***
+%!   assert(min(x)>0.); %*** Please report this!!! ***
+%!   assert(mean(x),0.5,0.0024);
+%!   assert(var(x),1/48,0.0632);
+%!   assert(skewness(x),0,0.012); 
+%!   assert(kurtosis(x),-6/5,0.0094);
+%! endif
+*/
+
+
+static std::string current_distribution = octave_rand::distribution ();
+
+static void
+reset_rand_generator (void *)
+{
+  octave_rand::distribution (current_distribution);
+}
+
+DEFUN_DLD (randn, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} randn (@var{x})\n\
+ at deftypefnx {Loadable Function} {} randn (@var{n}, @var{m})\n\
+ at deftypefnx {Loadable Function} {} randn (\"state\", @var{x})\n\
+ at deftypefnx {Loadable Function} {} randn (\"seed\", @var{x})\n\
+Return a matrix with normally distributed pseudo-random\n\
+elements having zero mean and variance one.  The arguments are\n\
+handled the same as the arguments for @code{rand}.\n\
+\n\
+By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique'' to\n\
+transform from a uniform to a normal distribution.  (G. Marsaglia and\n\
+W.W. Tsang, @cite{Ziggurat method for generating random variables},\n\
+J. Statistical Software, vol 5, 2000,\n\
+ at url{http://www.jstatsoft.org/v05/i08/})\n\
+\n\
+ at seealso{rand, rande, randg, randp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  unwind_protect::begin_frame ("randn");
+
+  // This relies on the fact that elements are popped from the unwind
+  // stack in the reverse of the order they are pushed
+  // (i.e. current_distribution will be reset before calling
+  // reset_rand_generator()).
+
+  unwind_protect::add (reset_rand_generator, 0);
+  unwind_protect_str (current_distribution);
+
+  current_distribution = "normal";
+
+  octave_rand::distribution (current_distribution);
+
+  retval = do_rand (args, nargin, "randn");
+
+  unwind_protect::run_frame ("randn");
+
+  return retval;
+}
+
+/*
+%!test
+%! % Test fixed state
+%! randn("state",1);
+%! assert (randn(1,6), [-2.666521678978671 -0.7381719971724564 1.507903992673601 0.6019427189162239 -0.450661261143348 -0.7054431351574116],1e-6);
+%!test
+%! % Test fixed seed
+%! randn("seed",1);
+%! assert (randn(1,6), [-1.039402365684509 -1.25938892364502 0.1968704611063004 0.3874166905879974 -0.5976632833480835 -0.6615074276924133],1e-6);
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randn("state",12);
+%!   x = randn(100000,1);
+%!   assert(mean(x),0,0.01);
+%!   assert(var(x),1,0.02);
+%!   assert(skewness(x),0,0.02);
+%!   assert(kurtosis(x),0,0.04);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randn("seed",12);
+%!   x = randn(100000,1);
+%!   assert(mean(x),0,0.01);
+%!   assert(var(x),1,0.02);
+%!   assert(skewness(x),0,0.02);
+%!   assert(kurtosis(x),0,0.04);
+%! endif
+*/
+
+DEFUN_DLD (rande, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} rande (@var{x})\n\
+ at deftypefnx {Loadable Function} {} rande (@var{n}, @var{m})\n\
+ at deftypefnx {Loadable Function} {} rande (\"state\", @var{x})\n\
+ at deftypefnx {Loadable Function} {} rande (\"seed\", @var{x})\n\
+Return a matrix with exponentially distributed random elements.  The\n\
+arguments are handled the same as the arguments for @code{rand}.\n\
+\n\
+By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique'' to\n\
+transform from a uniform to a exponential distribution.  (G. Marsaglia and\n\
+W.W. Tsang, @cite{Ziggurat method for generating random variables},\n\
+J. Statistical Software, vol 5, 2000,\n\
+ at url{http://www.jstatsoft.org/v05/i08/})\n\
+ at seealso{rand, randn, randg, randp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  unwind_protect::begin_frame ("rande");
+
+  // This relies on the fact that elements are popped from the unwind
+  // stack in the reverse of the order they are pushed
+  // (i.e. current_distribution will be reset before calling
+  // reset_rand_generator()).
+
+  unwind_protect::add (reset_rand_generator, 0);
+  unwind_protect_str (current_distribution);
+
+  current_distribution = "exponential";
+
+  octave_rand::distribution (current_distribution);
+
+  retval = do_rand (args, nargin, "rande");
+
+  unwind_protect::run_frame ("rande");
+
+  return retval;
+}
+
+/*
+%!test
+%! % Test fixed state
+%! rande("state",1);
+%! assert (rande(1,6), [3.602973885835625 0.1386190677555021 0.6743112889616958 0.4512830847258422 0.7255744741233175 0.3415969205292291],1e-6);
+%!test
+%! % Test fixed seed
+%! rande("seed",1);
+%! assert (rande(1,6), [0.06492075175653866 1.717980206012726 0.4816154008731246 0.5231300676241517 0.103910739364359 1.668931916356087],1e-6);
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally
+%!   rande("state",1);
+%!   x = rande(100000,1);
+%!   assert(min(x)>0); % *** Please report this!!! ***
+%!   assert(mean(x),1,0.01);
+%!   assert(var(x),1,0.03);
+%!   assert(skewness(x),2,0.06);
+%!   assert(kurtosis(x),6,0.7);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally
+%!   rande("seed",1);
+%!   x = rande(100000,1);
+%!   assert(min(x)>0); % *** Please report this!!! ***
+%!   assert(mean(x),1,0.01);
+%!   assert(var(x),1,0.03);
+%!   assert(skewness(x),2,0.06);
+%!   assert(kurtosis(x),6,0.7);
+%! endif
+*/
+
+DEFUN_DLD (randg, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} randg (@var{a}, @var{x})\n\
+ at deftypefnx {Loadable Function} {} randg (@var{a}, @var{n}, @var{m})\n\
+ at deftypefnx {Loadable Function} {} randg (\"state\", @var{x})\n\
+ at deftypefnx {Loadable Function} {} randg (\"seed\", @var{x})\n\
+Return a matrix with @code{gamma(@var{a},1)} distributed random elements.\n\
+The arguments are handled the same as the arguments for @code{rand},\n\
+except for the argument @var{a}.\n\
+\n\
+This can be used to generate many distributions:\n\
+\n\
+ at table @asis\n\
+ at item @code{gamma (a, b)} for @code{a > -1}, @code{b > 0}\n\
+ at example\n\
+r = b * randg (a)\n\
+ at end example\n\
+ at item @code{beta (a, b)} for @code{a > -1}, @code{b > -1}\n\
+ at example\n\
+ at group\n\
+r1 = randg (a, 1)\n\
+r = r1 / (r1 + randg (b, 1))\n\
+ at end group\n\
+ at end example\n\
+ at item @code{Erlang (a, n)}\n\
+ at example\n\
+r = a * randg (n)\n\
+ at end example\n\
+ at item @code{chisq (df)} for @code{df > 0}\n\
+ at example\n\
+r = 2 * randg (df / 2)\n\
+ at end example\n\
+ at item @code{t(df)} for @code{0 < df < inf} (use randn if df is infinite)\n\
+ at example\n\
+r = randn () / sqrt (2 * randg (df / 2) / df)\n\
+ at end example\n\
+ at item @code{F (n1, n2)} for @code{0 < n1}, @code{0 < n2}\n\
+ at example\n\
+ at group\n\
+## r1 equals 1 if n1 is infinite\n\
+r1 = 2 * randg (n1 / 2) / n1\n\
+## r2 equals 1 if n2 is infinite\n\
+r2 = 2 * randg (n2 / 2) / n2\n\
+r = r1 / r2\n\n\
+ at end group\n\
+ at end example\n\
+ at item negative @code{binomial (n, p)} for @code{n > 0}, @code{0 < p <= 1}\n\
+ at example\n\
+r = randp ((1 - p) / p * randg (n))\n\
+ at end example\n\
+ at item non-central @code{chisq (df, L)}, for @code{df >= 0} and @code{L > 0}\n\
+(use chisq if @code{L = 0})\n\
+ at example\n\
+ at group\n\
+r = randp (L / 2)\n\
+r(r > 0) = 2 * randg (r(r > 0))\n\
+r(df > 0) += 2 * randg (df(df > 0)/2)\n\
+ at end group\n\
+ at end example\n\
+ at item @code{Dirichlet (a1, @dots{} ak)}\n\
+ at example\n\
+ at group\n\
+r = (randg (a1), @dots{}, randg (ak))\n\
+r = r / sum (r)\n\
+ at end group\n\
+ at end example\n\
+ at end table\n\
+ at seealso{rand, randn, rande, randp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1)
+    error ("randg: insufficient arguments");
+  else
+    {
+      unwind_protect::begin_frame ("randg");
+
+      // This relies on the fact that elements are popped from the unwind
+      // stack in the reverse of the order they are pushed
+      // (i.e. current_distribution will be reset before calling
+      // reset_rand_generator()).
+
+      unwind_protect::add (reset_rand_generator, 0);
+      unwind_protect_str (current_distribution);
+
+      current_distribution = "gamma";
+
+      octave_rand::distribution (current_distribution);
+
+      retval = do_rand (args, nargin, "randg", true);
+
+      unwind_protect::run_frame ("randg");
+    }
+
+  return retval;
+}
+
+/*
+%!test
+%! randg("state",12)
+%!assert(randg([-inf,-1,0,inf,nan]),[nan,nan,nan,nan,nan]) % *** Please report
+
+
+%!test
+%! % Test fixed state
+%! randg("state",1);
+%! assert (randg(0.1,1,6), [0.0103951513331241 8.335671459898252e-05 0.00138691397249762 0.000587308416993855 0.495590518784736 2.3921917414795e-12],1e-6);
+%!test
+%! % Test fixed state
+%! randg("state",1);
+%! assert (randg(0.95,1,6), [3.099382433255327 0.3974529788871218 0.644367450750855 1.143261091802246 1.964111762696822 0.04011915547957939],1e-6);
+%!test
+%! % Test fixed state
+%! randg("state",1);
+%! assert (randg(1,1,6), [0.2273389379645993 1.288822625058359 0.2406335209340746 1.218869553370733 1.024649860162554 0.09631230343599533],1e-6);
+%!test
+%! % Test fixed state
+%! randg("state",1);
+%! assert (randg(10,1,6), [3.520369644331133 15.15369864472106 8.332112081991205 8.406211067432674 11.81193475187611 10.88792728177059],1e-5);
+%!test
+%! % Test fixed state
+%! randg("state",1);
+%! assert (randg(100,1,6), [75.34570255262264 115.4911985594699 95.23493031356388 95.48926019250911 106.2397448229803 103.4813150404118],1e-4);
+%!test
+%! % Test fixed seed
+%! randg("seed",1);
+%! assert (randg(0.1,1,6), [0.07144210487604141 0.460641473531723 0.4749028384685516 0.06823389977216721 0.000293838675133884 1.802567535340305e-12],1e-6);
+%!test
+%! % Test fixed seed
+%! randg("seed",1);
+%! assert (randg(0.95,1,6), [1.664905071258545 1.879976987838745 1.905677795410156 0.9948706030845642 0.5606933236122131 0.0766092911362648],1e-6);
+%!test
+%! % Test fixed seed
+%! randg("seed",1);
+%! assert (randg(1,1,6), [0.03512085229158401 0.6488978862762451 0.8114678859710693 0.1666885763406754 1.60791552066803 1.90356981754303],1e-6);
+%!test
+%! % Test fixed seed
+%! randg("seed",1);
+%! assert (randg(10,1,6), [6.566435813903809 10.11648464202881 10.73162078857422 7.747178077697754 6.278522491455078 6.240195751190186],1e-5);
+%!test
+%! % Test fixed seed
+%! randg("seed",1);
+%! assert (randg(100,1,6), [89.40208435058594 101.4734725952148 103.4020004272461 93.62763214111328 88.33104705810547 88.1871337890625],1e-4);
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("state",12)
+%!   a=0.1; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.01);
+%!   assert(var(x),     a,         0.01);
+%!   assert(skewness(x),2/sqrt(a), 1.);
+%!   assert(kurtosis(x),6/a,       50.);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("state",12)
+%!   a=0.95; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.01);
+%!   assert(var(x),     a,         0.04);
+%!   assert(skewness(x),2/sqrt(a), 0.2);
+%!   assert(kurtosis(x),6/a,       2.);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("state",12)
+%!   a=1; x = randg(a,100000,1);
+%!   assert(mean(x),a,             0.01);
+%!   assert(var(x),a,              0.04);
+%!   assert(skewness(x),2/sqrt(a), 0.2);
+%!   assert(kurtosis(x),6/a,       2.);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("state",12)
+%!   a=10; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.1);
+%!   assert(var(x),     a,         0.5);
+%!   assert(skewness(x),2/sqrt(a), 0.1);
+%!   assert(kurtosis(x),6/a,       0.5);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("state",12)
+%!   a=100; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.2);
+%!   assert(var(x),     a,         2.);
+%!   assert(skewness(x),2/sqrt(a), 0.05);
+%!   assert(kurtosis(x),6/a,       0.2);
+%! endif
+%!test
+%! randg("seed",12)
+%!assert(randg([-inf,-1,0,inf,nan]),[nan,nan,nan,nan,nan]) % *** Please report
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("seed",12)
+%!   a=0.1; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.01);
+%!   assert(var(x),     a,         0.01);
+%!   assert(skewness(x),2/sqrt(a), 1.);
+%!   assert(kurtosis(x),6/a,       50.);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("seed",12)
+%!   a=0.95; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.01);
+%!   assert(var(x),     a,         0.04);
+%!   assert(skewness(x),2/sqrt(a), 0.2);
+%!   assert(kurtosis(x),6/a,       2.);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("seed",12)
+%!   a=1; x = randg(a,100000,1);
+%!   assert(mean(x),a,             0.01);
+%!   assert(var(x),a,              0.04);
+%!   assert(skewness(x),2/sqrt(a), 0.2);
+%!   assert(kurtosis(x),6/a,       2.);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("seed",12)
+%!   a=10; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.1);
+%!   assert(var(x),     a,         0.5);
+%!   assert(skewness(x),2/sqrt(a), 0.1);
+%!   assert(kurtosis(x),6/a,       0.5);
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randg("seed",12)
+%!   a=100; x = randg(a,100000,1);
+%!   assert(mean(x),    a,         0.2);
+%!   assert(var(x),     a,         2.);
+%!   assert(skewness(x),2/sqrt(a), 0.05);
+%!   assert(kurtosis(x),6/a,       0.2);
+%! endif
+*/
+
+
+DEFUN_DLD (randp, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} randp (@var{l}, @var{x})\n\
+ at deftypefnx {Loadable Function} {} randp (@var{l}, @var{n}, @var{m})\n\
+ at deftypefnx {Loadable Function} {} randp (\"state\", @var{x})\n\
+ at deftypefnx {Loadable Function} {} randp (\"seed\", @var{x})\n\
+Return a matrix with Poisson distributed random elements with mean value parameter given by the first argument, @var{l}.  The arguments\n\
+are handled the same as the arguments for @code{rand}, except for the\n\
+argument @var{l}.\n\
+\n\
+Five different algorithms are used depending on the range of @var{l}\n\
+and whether or not @var{l} is a scalar or a matrix.\n\
+\n\
+ at table @asis\n\
+ at item For scalar @var{l} <= 12, use direct method.\n\
+Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.\n\
+ at item For scalar @var{l} > 12, use rejection method.[1]\n\
+Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.\n\
+ at item For matrix @var{l} <= 10, use inversion method.[2]\n\
+Stadlober E., et al., WinRand source code, available via FTP.\n\
+ at item For matrix @var{l} > 10, use patchwork rejection method.\n\
+Stadlober E., et al., WinRand source code, available via FTP, or\n\
+H. Zechner, 'Efficient sampling from continuous and discrete\n\
+unimodal distributions', Doctoral Dissertation, 156pp., Technical\n\
+University Graz, Austria, 1994.\n\
+ at item For @var{l} > 1e8, use normal approximation.\n\
+L. Montanet, et al., 'Review of Particle Properties', Physical Review\n\
+D 50 p1284, 1994\n\
+ at end table\n\
+ at seealso{rand, randn, rande, randg}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1)
+    error ("randp: insufficient arguments");
+  else
+    {
+      unwind_protect::begin_frame ("randp");
+
+      // This relies on the fact that elements are popped from the unwind
+      // stack in the reverse of the order they are pushed
+      // (i.e. current_distribution will be reset before calling
+      // reset_rand_generator()).
+
+      unwind_protect::add (reset_rand_generator, 0);
+      unwind_protect_str (current_distribution);
+
+      current_distribution = "poisson";
+
+      octave_rand::distribution (current_distribution);
+
+      retval = do_rand (args, nargin, "randp", true);
+
+      unwind_protect::run_frame ("randp");
+    }
+
+  return retval;
+}
+
+/*
+%!test
+%! randp("state",12)
+%!assert(randp([-inf,-1,0,inf,nan]),[nan,nan,0,nan,nan]); % *** Please report
+%!test
+%! % Test fixed state
+%! randp("state",1);
+%! assert(randp(5,1,6),[5 5 3 7 7 3])
+%!test
+%! % Test fixed state
+%! randp("state",1);
+%! assert(randp(15,1,6),[13 15 8 18 18 15])
+%!test
+%! % Test fixed state
+%! randp("state",1);
+%! assert(randp(1e9,1,6),[999915677 999976657 1000047684 1000019035 999985749 999977692],-1e-6)
+%!test
+%! % Test fixed state
+%! randp("seed",1);
+%! %%assert(randp(5,1,6),[8 2 3 6 6 8])
+%! assert(randp(5,1,5),[8 2 3 6 6])
+%!test
+%! % Test fixed state
+%! randp("seed",1);
+%! assert(randp(15,1,6),[15 16 12 10 10 12])
+%!test
+%! % Test fixed state
+%! randp("seed",1);
+%! assert(randp(1e9,1,6),[1000006208 1000012224 999981120 999963520 999963072 999981440],-1e-6)
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randp("state",12)
+%!   for a=[5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
+%!     x = randp(a(1),100000,1);
+%!     assert(min(x)>=0); % *** Please report this!!! ***
+%!     assert(mean(x),a(1),a(2));
+%!     assert(var(x),a(1),0.02*a(1));
+%!     assert(skewness(x),1/sqrt(a(1)),a(3));
+%!     assert(kurtosis(x),1/a(1),3*a(3));
+%!   endfor
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randp("state",12)
+%!   for a=[5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
+%!     x = randp(a(1)*ones(100000,1),100000,1);
+%!     assert(min(x)>=0); % *** Please report this!!! ***
+%!     assert(mean(x),a(1),a(2));
+%!     assert(var(x),a(1),0.02*a(1));
+%!     assert(skewness(x),1/sqrt(a(1)),a(3));
+%!     assert(kurtosis(x),1/a(1),3*a(3));
+%!   endfor
+%! endif
+%!test
+%! randp("seed",12)
+%!assert(randp([-inf,-1,0,inf,nan]),[nan,nan,0,nan,nan]); % *** Please report
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randp("seed",12)
+%!   for a=[5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
+%!     x = randp(a(1),100000,1);
+%!     assert(min(x)>=0); % *** Please report this!!! ***
+%!     assert(mean(x),a(1),a(2));
+%!     assert(var(x),a(1),0.02*a(1));
+%!     assert(skewness(x),1/sqrt(a(1)),a(3));
+%!     assert(kurtosis(x),1/a(1),3*a(3));
+%!   endfor
+%! endif
+%!test
+%! if (__random_statistical_tests__)
+%!   % statistical tests may fail occasionally.
+%!   randp("seed",12)
+%!   for a=[5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
+%!     x = randp(a(1)*ones(100000,1),100000,1);
+%!     assert(min(x)>=0); % *** Please report this!!! ***
+%!     assert(mean(x),a(1),a(2));
+%!     assert(var(x),a(1),0.02*a(1));
+%!     assert(skewness(x),1/sqrt(a(1)),a(3));
+%!     assert(kurtosis(x),1/a(1),3*a(3));
+%!   endfor
+%! endif
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/rcond.cc b/src/DLD-FUNCTIONS/rcond.cc
new file mode 100644
index 0000000..675913c
--- /dev/null
+++ b/src/DLD-FUNCTIONS/rcond.cc
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (rcond, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{c} =} rcond (@var{a})\n\
+Compute the 1-norm estimate of the reciprocal condition as returned\n\
+by @sc{lapack}.  If the matrix is well-conditioned then @var{c} will be near\n\
+1 and if the matrix is poorly conditioned it will be close to zero.\n\
+\n\
+The matrix @var{a} must not be sparse.  If the matrix is sparse then\n\
+ at code{condest (@var{a})} or @code{rcond (full (@var{a}))} should be used\n\
+instead.\n\
+ at seealso{inv}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else if (args(0).is_sparse_type ())
+    error ("rcond: for sparse matrices use 'rcond (full (a))' or 'condest (a)' instead");
+  else if (args(0).is_single_type ())
+    {
+      if (args(0).is_complex_type ())
+	{
+	  FloatComplexMatrix m = args(0).float_complex_matrix_value ();
+	  MatrixType mattyp;
+	  retval = m.rcond (mattyp);
+	  args(0).matrix_type (mattyp);
+	}
+      else
+	{
+	  FloatMatrix m = args(0).float_matrix_value ();
+	  MatrixType mattyp;
+	  retval = m.rcond (mattyp);
+	  args(0).matrix_type (mattyp);
+	}
+    }
+  else if (args(0).is_complex_type ())
+    {
+      ComplexMatrix m = args(0).complex_matrix_value ();
+      MatrixType mattyp;
+      retval = m.rcond (mattyp);
+      args(0).matrix_type (mattyp);
+    }
+  else
+    {
+      Matrix m = args(0).matrix_value ();
+      MatrixType mattyp;
+      retval = m.rcond (mattyp);
+      args(0).matrix_type (mattyp);
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/regexp.cc b/src/DLD-FUNCTIONS/regexp.cc
new file mode 100644
index 0000000..0dda794
--- /dev/null
+++ b/src/DLD-FUNCTIONS/regexp.cc
@@ -0,0 +1,1726 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 2002, 2003, 2004, 2005 Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+#include <sstream>
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#include "Cell.h"
+#include "oct-map.h"
+#include "str-vec.h"
+#include "quit.h"
+#include "parse.h"
+#include "oct-locbuf.h"
+
+#if defined (HAVE_PCRE)
+#include <pcre.h>
+#elif defined (HAVE_REGEX)
+#if defined (__MINGW32__)
+#define __restrict
+#endif
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#include <regex.h>
+#endif
+
+// Define the maximum number of retries for a pattern that 
+// possibly results in an infinite recursion.
+#define PCRE_MATCHLIMIT_MAX 10
+
+// The regexp is constructed as a linked list to avoid resizing the
+// return values in arrays at each new match.
+
+// FIXME don't bother collecting and composing return values the user
+// doesn't want.
+
+class regexp_elem
+{
+public:
+  regexp_elem (const string_vector& _named_token, const Cell& _t, 
+	       const std::string& _m, const Matrix& _te, double _s, 
+	       double _e) :
+    named_token (_named_token), t (_t), m (_m), te (_te), s (_s), e (_e) { }
+
+  regexp_elem (const regexp_elem &a) : named_token (a.named_token), t (a.t), 
+				       m (a.m), te (a.te), s (a.s), e (a.e)
+				       { }
+
+  string_vector named_token;
+  Cell t;
+  std::string m;
+  Matrix te;
+  double s;
+  double e;
+};
+
+typedef std::list<regexp_elem>::const_iterator const_iterator;
+
+#define MAXLOOKBEHIND 10
+static bool lookbehind_warned = false;
+
+static int
+octregexp_list (const octave_value_list &args, const std::string &nm, 
+		bool case_insensitive, std::list<regexp_elem> &lst, 
+		string_vector &named, int &nopts, bool &once)
+{
+  int sz = 0;
+#if defined (HAVE_REGEX) || defined (HAVE_PCRE) 
+  int nargin = args.length();
+  bool lineanchors = false;
+  bool dotexceptnewline = false;
+  bool freespacing = false;
+
+  nopts = nargin - 2;
+  once = false;
+
+  std::string buffer = args(0).string_value ();
+  size_t max_length = (buffer.length () > MAXLOOKBEHIND ? 
+		       MAXLOOKBEHIND: buffer.length ());
+
+  if (error_state)
+    {
+      gripe_wrong_type_arg (nm.c_str(), args(0));
+      return 0;
+    }
+
+  std::string pattern = args(1).string_value ();
+  if (error_state)
+    {
+      gripe_wrong_type_arg (nm.c_str(), args(1));
+      return 0;
+    }
+
+  for (int i = 2; i < nargin; i++)
+    {
+      std::string str = args(i).string_value();
+      if (error_state)
+	{
+	  error ("%s: optional arguments must be strings", nm.c_str());
+	  break;
+	}
+      std::transform (str.begin (), str.end (), str.begin (), tolower);
+      if (str.find("once", 0) == 0)
+	{
+	  once = true;
+	  nopts--;
+	}
+      else if (str.find("matchcase", 0) == 0)
+	{
+	  case_insensitive = false;
+	  nopts--;
+	}
+      else if (str.find("ignorecase", 0) == 0)
+	{
+	  case_insensitive = true;
+	  nopts--;
+	}
+      else if (str.find("dotall", 0) == 0)
+	{
+	  dotexceptnewline = false;
+	  nopts--;
+	}
+      else if (str.find("stringanchors", 0) == 0)
+	{
+	  lineanchors = false;
+	  nopts--;
+	}
+      else if (str.find("literalspacing", 0) == 0)
+	{
+	  freespacing = false;
+	  nopts--;
+	}
+#if HAVE_PCRE
+      // Only accept these options with pcre
+      else if (str.find("dotexceptnewline", 0) == 0)
+	{
+	  dotexceptnewline = true;
+	  nopts--;
+	}
+      else if (str.find("lineanchors", 0) == 0)
+	{
+	  lineanchors = true;
+	  nopts--;
+	}
+      else if (str.find("freespacing", 0) == 0)
+	{
+	  freespacing = true;
+	  nopts--;
+	}
+      else if (str.find("start", 0) && str.find("end", 0) &&
+	       str.find("tokenextents", 0) && str.find("match", 0) &&
+	       str.find("tokens", 0) && str.find("names", 0))
+	error ("%s: unrecognized option", nm.c_str());
+#else
+      else if (str.find("names", 0) == 0 ||
+	       str.find("dotexceptnewline", 0) == 0 ||
+	       str.find("lineanchors", 0) == 0 ||
+	       str.find("freespacing", 0) == 0)
+       error ("%s: %s not implemented in this version", str.c_str(), nm.c_str());
+      else if (str.find("start", 0) && str.find("end", 0) &&
+	       str.find("tokenextents", 0) && str.find("match", 0) &&
+	       str.find("tokens", 0))
+	error ("%s: unrecognized option", nm.c_str());
+#endif
+    }
+
+  if (!error_state)
+    {
+      Cell t;
+      std::string m;
+      double s, e;
+
+      // named tokens "(?<name>...)" are only treated with PCRE not regex.
+#if HAVE_PCRE
+      
+      size_t pos = 0;
+      size_t new_pos;
+      int nnames = 0;
+      int inames = 0;
+      std::ostringstream buf;
+      Array<int> named_idx;
+
+      while ((new_pos = pattern.find ("(?",pos)) != std::string::npos)
+	{
+	  if (pattern.at (new_pos + 2) == '<' &&  
+	      !(pattern.at (new_pos + 3) == '=' ||
+		pattern.at (new_pos + 3) == '!'))
+	    {
+	      // The syntax of named tokens in pcre is "(?P<name>...)" while
+	      // we need a syntax "(?<name>...)", so fix that here. Also an 
+	      // expression like 
+	      // "(?<first>\w+)\s+(?<last>\w+)|(?<last>\w+),\s+(?<first>\w+)" 
+	      // should be perfectly legal, while pcre does not allow the same
+	      // named token name on both sides of the alternative. Also fix
+	      // that here by replacing name tokens by dummy names, and dealing
+	      // with the dummy names later.
+
+	      size_t tmp_pos = pattern.find_first_of ('>',new_pos);
+
+	      if (tmp_pos == std::string::npos)
+		{
+		  error ("syntax error in pattern");
+		  break;
+		}
+
+	      std::string tmp_name = 
+		pattern.substr(new_pos+3,tmp_pos-new_pos-3);
+	      bool found = false;
+
+	      for (int i = 0; i < nnames; i++)
+		if (named(i) == tmp_name)
+		  {
+		    named_idx.resize(inames+1);
+		    named_idx(inames) = i;
+		    found = true;
+		    break;
+		  }
+	      if (! found)
+		{
+		  named_idx.resize(inames+1);
+		  named_idx(inames) = nnames;
+		  named.append(tmp_name);
+		  nnames++;
+		}
+
+	      if (new_pos - pos > 0)
+		buf << pattern.substr(pos,new_pos-pos);
+	      if (inames < 10)
+		buf << "(?P<n00" << inames++;
+	      else if (inames < 100)
+		buf << "(?P<n0" << inames++;
+	      else
+		buf << "(?P<n" << inames++;
+	      pos = tmp_pos;
+	    }
+	  else if (pattern.at (new_pos + 2) == '<')
+	    {
+	      // Find lookbehind operators of arbitrary length (ie like 
+	      // "(?<=[a-z]*)") and replace with a maximum length operator 
+	      // as PCRE can not yet handle arbitrary length lookahead 
+	      // operators. Use the string length as the maximum length to 
+	      // avoid issues.
+
+	      int brackets = 1;
+	      size_t tmp_pos1 = new_pos + 2;
+	      size_t tmp_pos2 = tmp_pos1;
+	      while (tmp_pos1 <= pattern.length () && brackets > 0)
+		{
+		  char ch = pattern.at (tmp_pos1);
+		  if (ch == '(')
+		    brackets++;
+		  else if (ch == ')')
+		    {
+		      if (brackets > 1)
+			tmp_pos2 = tmp_pos1;
+
+		      brackets--;
+		    }
+		  tmp_pos1++;
+		}
+
+	      if (brackets != 0)
+		{
+		  buf << pattern.substr (pos, new_pos - pos) << "(?";
+		  pos = new_pos + 2;
+		}
+	      else
+		{
+		  size_t tmp_pos3 = pattern.find_first_of ("*+", tmp_pos2);
+		  if (tmp_pos3 != std::string::npos && tmp_pos3 < tmp_pos1)
+		    {
+		      if (!lookbehind_warned)
+			{
+			  lookbehind_warned = true;
+			  warning ("%s: arbitrary length lookbehind patterns are only support up to length %d", nm.c_str(), MAXLOOKBEHIND);
+			}
+
+		      buf << pattern.substr (pos, new_pos - pos) << "(";
+
+		      size_t i;
+		      if (pattern.at (tmp_pos3) == '*')
+			i = 0;
+		      else
+			i = 1;
+
+		      for (; i < max_length + 1; i++)
+			{
+			  buf << pattern.substr(new_pos, tmp_pos3 - new_pos)
+			      << "{" << i << "}";
+			  buf << pattern.substr(tmp_pos3 + 1, 
+						tmp_pos1 - tmp_pos3 - 1);
+			  if (i != max_length)
+			    buf << "|";
+			}
+		      buf << ")";
+		    }
+		  else
+		    buf << pattern.substr (pos, tmp_pos1 - pos);
+		  pos = tmp_pos1;
+		}
+	    }
+	  else
+	    {
+	      buf << pattern.substr (pos, new_pos - pos) << "(?";
+	      pos = new_pos + 2;
+	    }
+
+	}
+
+      buf << pattern.substr(pos);
+
+      if (error_state)
+	return 0;
+
+      // Compile expression
+      pcre *re;
+      const char *err;
+      int erroffset;
+      std::string buf_str = buf.str ();
+      re = pcre_compile (buf_str.c_str (),
+			 (case_insensitive ? PCRE_CASELESS : 0) |
+			 (dotexceptnewline ? 0 : PCRE_DOTALL) |
+			 (lineanchors ? PCRE_MULTILINE : 0) |
+			 (freespacing ? PCRE_EXTENDED : 0),
+			 &err, &erroffset, 0);
+    
+      if (re == 0) {
+	error("%s: %s at position %d of expression", nm.c_str(), 
+	      err, erroffset);
+	return 0;
+      }
+
+      int subpatterns;
+      int namecount;
+      int nameentrysize;
+      char *nametable;
+      int idx = 0;
+
+      pcre_fullinfo(re, 0, PCRE_INFO_CAPTURECOUNT,  &subpatterns);
+      pcre_fullinfo(re, 0, PCRE_INFO_NAMECOUNT, &namecount);
+      pcre_fullinfo(re, 0, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
+      pcre_fullinfo(re, 0, PCRE_INFO_NAMETABLE, &nametable);
+
+      OCTAVE_LOCAL_BUFFER(int, ovector, (subpatterns+1)*3);
+      OCTAVE_LOCAL_BUFFER(int, nidx, namecount);
+
+      for (int i = 0; i < namecount; i++)
+	{
+	  // Index of subpattern in first two bytes MSB first of name.
+	  // Extract index.
+	  nidx[i] = (static_cast<int>(nametable[i*nameentrysize])) << 8 |
+	    static_cast<int>(nametable[i*nameentrysize+1]);
+	}
+
+      while(true)
+	{
+	  OCTAVE_QUIT;
+
+	  int matches = pcre_exec(re, 0, buffer.c_str(), 
+				  buffer.length(), idx, 
+				  (idx ? PCRE_NOTBOL : 0),
+				  ovector, (subpatterns+1)*3);
+
+	  if (matches == PCRE_ERROR_MATCHLIMIT)
+	    {
+	      // try harder; start with default value for MATCH_LIMIT and increase it
+	      warning("Your pattern caused PCRE to hit its MATCH_LIMIT.\nTrying harder now, but this will be slow.");
+	      pcre_extra pe;
+	      pcre_config(PCRE_CONFIG_MATCH_LIMIT, static_cast <void *> (&pe.match_limit));
+	      pe.flags = PCRE_EXTRA_MATCH_LIMIT;
+
+	      int i = 0;
+	      while (matches == PCRE_ERROR_MATCHLIMIT &&
+		     i++ < PCRE_MATCHLIMIT_MAX)
+		{
+		  OCTAVE_QUIT;
+
+		  pe.match_limit *= 10;
+		  matches = pcre_exec(re, &pe, buffer.c_str(), 
+				      buffer.length(), idx, 
+				      (idx ? PCRE_NOTBOL : 0),
+				      ovector, (subpatterns+1)*3);
+		}
+	    }
+
+	  if (matches < 0 && matches != PCRE_ERROR_NOMATCH)
+	    {
+	      error ("%s: internal error calling pcre_exec\nError code from pcre_exec is %i", nm.c_str(), matches);
+	      pcre_free(re);
+	      return 0;
+	    }
+	  else if (matches == PCRE_ERROR_NOMATCH)
+	    break;
+	  else if (ovector[1] <= ovector[0])
+	    {
+	      // FIXME: Zero sized match!! Is this the right thing to do?
+	      idx = ovector[0] + 1;
+	      continue;
+	    }
+	  else
+	    {
+	      int pos_match = 0;
+	      Matrix te(matches-1,2);
+	      for (int i = 1; i < matches; i++)
+		{
+		  if (ovector[2*i] >= 0 && ovector[2*i+1] > 0)
+		    {
+		      te(pos_match,0) = double (ovector[2*i]+1);
+		      te(pos_match++,1) = double (ovector[2*i+1]);
+		    }
+		}
+	      te.resize(pos_match,2);
+	      s = double (ovector[0]+1);
+	      e = double (ovector[1]);
+
+	      const char **listptr;
+	      int status = pcre_get_substring_list(buffer.c_str(), ovector, 
+						   matches, &listptr);
+
+	      if (status == PCRE_ERROR_NOMEMORY) {
+		error("%s: cannot allocate memory in pcre_get_substring_list",
+		      nm.c_str());
+		pcre_free(re);
+		return 0;
+	      }
+
+	      Cell cell_t (dim_vector(1,pos_match));
+	      pos_match = 0;
+	      for (int i = 1; i < matches; i++)
+		if (ovector[2*i] >= 0 && ovector[2*i+1] > 0)
+		  cell_t(pos_match++) = std::string(*(listptr+i));
+
+	      m =  std::string(*listptr);
+	      t = cell_t;
+
+	      string_vector named_tokens(nnames);
+	      if (namecount > 0)
+		for (int i = 1; i < matches; i++)
+		  {
+		    if (ovector[2*i] >= 0 && ovector[2*i+1] > 0)	
+		      {
+			named_tokens(named_idx(i-1)) = 
+			  std::string(*(listptr+nidx[i-1]));
+		      }
+		  }
+
+	      pcre_free_substring_list(listptr);
+
+	      regexp_elem new_elem (named_tokens, t, m, te, s, e);
+	      lst.push_back (new_elem);
+	      idx = ovector[1];
+	      sz++;
+
+	      if (once)
+		break;
+
+	    }
+	}
+
+      pcre_free(re);
+#else
+      regex_t compiled;
+      int err=regcomp(&compiled, pattern.c_str(), REG_EXTENDED | 
+		      (case_insensitive ? REG_ICASE : 0));
+      if (err)
+	{
+	  int len = regerror(err, &compiled, 0, 0);
+	  OCTAVE_LOCAL_BUFFER (char, errmsg, len);
+	  regerror(err, &compiled, errmsg, len);
+	  error("%s: %s in pattern (%s)", nm.c_str(), errmsg, 
+		pattern.c_str());
+	  regfree(&compiled);
+	  return 0;
+	}
+
+      int subexpr = 1;
+      int idx = 0;
+      for (unsigned int i=0; i < pattern.length(); i++)
+	  subexpr += ( pattern[i] == '(' ? 1 : 0 );
+      OCTAVE_LOCAL_BUFFER (regmatch_t, match, subexpr );
+
+      while(true)
+	{
+	  OCTAVE_QUIT; 
+
+	  if (regexec(&compiled, buffer.c_str() + idx, subexpr, 
+		      match, (idx ? REG_NOTBOL : 0)) == 0) 
+	    {
+	      // Count actual matches
+	      int matches = 0;
+	      while (matches < subexpr && match[matches].rm_so >= 0) 
+		matches++;
+
+	      if (matches == 0 || match[0].rm_eo == 0)
+		break;
+
+	      s = double (match[0].rm_so+1+idx);
+	      e = double (match[0].rm_eo+idx);
+	      Matrix te(matches-1,2);
+	      for (int i = 1; i < matches; i++)
+		{
+		  te(i-1,0) = double (match[i].rm_so+1+idx);
+		  te(i-1,1) = double (match[i].rm_eo+idx);
+		}
+
+	      m =  buffer.substr (match[0].rm_so+idx, 
+					 match[0].rm_eo-match[0].rm_so);
+
+	      Cell cell_t (dim_vector(1,matches-1));
+	      for (int i = 1; i < matches; i++)
+		cell_t(i-1) = buffer.substr (match[i].rm_so+idx, 
+					     match[i].rm_eo-match[i].rm_so);
+	      t = cell_t;
+
+	      idx += match[0].rm_eo;
+
+	      string_vector sv;
+	      regexp_elem new_elem (sv, t, m, te, s, e);
+	      lst.push_back (new_elem);
+	      sz++;
+
+	      if (once)
+		break;
+	    }
+	  else
+	    break;
+	}
+      regfree(&compiled);
+#endif
+    }
+#else
+  error ("%s: not available in this version of Octave", nm.c_str());
+#endif
+  return sz;
+}
+
+static octave_value_list
+octregexp (const octave_value_list &args, int nargout, const std::string &nm,
+	   bool case_insensitive)
+{
+  octave_value_list retval;
+  int nargin = args.length();
+  std::list<regexp_elem> lst;
+  string_vector named;
+  int nopts;
+  bool once;
+  int sz = octregexp_list (args, nm, case_insensitive, lst, named, nopts, once);
+
+  if (! error_state)
+    {
+      // Converted the linked list in the correct form for the return values
+
+      octave_idx_type i = 0;
+#ifdef HAVE_PCRE
+      Octave_map nmap;
+      if (sz == 1)
+	{
+	  for (int j = 0; j < named.length(); j++)
+	    nmap.assign (named(j), lst.begin()->named_token(j));
+	  retval(5) = nmap;
+	}
+      else
+	{
+	  for (int j = 0; j < named.length (); j++)
+	    {
+	      i = 0;
+	      Cell tmp(dim_vector (1, sz));
+	      for (const_iterator p = lst.begin(); p != lst.end(); p++)
+		tmp(i++) = p->named_token(j);
+	      nmap.assign (named(j), octave_value (tmp));
+	    }
+	  retval(5) = nmap;
+	}
+#else
+      retval(5) = Octave_map();
+#endif
+
+      if (once)
+        retval(4) = sz ? lst.front ().t : Cell();
+      else
+        {
+          Cell t (dim_vector(1, sz));
+          i = 0;
+          for (const_iterator p = lst.begin(); p != lst.end(); p++)
+            t(i++) = p->t;
+          retval(4) = t;
+        }
+
+      if (once)
+        retval(3) = sz ? lst.front ().m : std::string();
+      else
+        {
+          Cell m (dim_vector(1, sz));
+          i = 0;
+          for (const_iterator p = lst.begin(); p != lst.end(); p++)
+            m(i++) = p->m;
+          retval(3) = m;
+        }
+
+      if (once)
+        retval(2) = sz ? lst.front ().te : Matrix();
+      else
+        {
+          Cell te (dim_vector(1, sz));
+          i = 0;
+          for (const_iterator p = lst.begin(); p != lst.end(); p++)
+            te(i++) = p->te;
+          retval(2) = te;
+        }
+
+      if (once)
+        {
+          if (sz)
+            retval(1) = lst.front ().e;
+          else
+            retval(1) = Matrix();
+        }
+      else
+        {
+          NDArray e (dim_vector(1, sz));
+          i = 0;
+          for (const_iterator p = lst.begin(); p != lst.end(); p++)
+            e(i++) = p->e;
+          retval(1) = e;
+        }
+
+      if (once)
+        {
+          if (sz)
+            retval(0) = lst.front ().s;
+          else
+            retval(0) = Matrix();
+        }
+      else
+        {
+      NDArray s (dim_vector(1, sz));
+      i = 0;
+      for (const_iterator p = lst.begin(); p != lst.end(); p++)
+	s(i++) = p->s;
+      retval(0) = s;
+        }
+
+      // Alter the order of the output arguments
+      if (nopts > 0)
+	{
+	  int n = 0;
+	  octave_value_list new_retval;
+	  new_retval.resize(nargout);
+
+	  OCTAVE_LOCAL_BUFFER (int, arg_used, 6);
+	  for (int j = 0; j < 6; j++)
+	    arg_used[j] = false;
+	  
+	  for (int j = 2; j < nargin; j++)
+	    {
+	      int k = 0;
+	      std::string str = args(j).string_value();
+	      std::transform (str.begin (), str.end (), str.begin (), tolower);
+	      if (str.find("once", 0) == 0
+		  || str.find("stringanchors", 0) == 0
+		  || str.find("lineanchors", 0) == 0
+		  || str.find("matchcase", 0) == 0
+		  || str.find("ignorecase", 0) == 0
+		  || str.find("dotall", 0) == 0
+		  || str.find("dotexceptnewline", 0) == 0
+		  || str.find("literalspacing", 0) == 0
+		  || str.find("freespacing", 0) == 0
+	      )
+		continue;
+	      else if (str.find("start", 0) == 0)
+		k = 0;
+	      else if (str.find("end", 0) == 0)
+		k = 1;
+	      else if (str.find("tokenextents", 0) == 0)
+		k = 2;
+	      else if (str.find("match", 0) == 0)
+		k = 3;
+	      else if (str.find("tokens", 0) == 0)
+		k = 4;
+	      else if (str.find("names", 0) == 0)
+		k = 5;
+
+	      new_retval(n++) = retval(k);
+	      arg_used[k] = true;
+
+	      if (n == nargout)
+		break;
+	    }
+
+	  // Fill in the rest of the arguments
+	  if (n < nargout)
+	    {
+	      for (int j = 0; j < 6; j++)
+		{
+		  if (! arg_used[j])
+		    new_retval(n++) = retval(j);
+		}
+	    }
+
+	  retval = new_retval;
+	}
+    }
+
+  return retval;
+}
+
+static octave_value_list
+octcellregexp (const octave_value_list &args, int nargout, const std::string &nm,
+	       bool case_insensitive)
+{
+  octave_value_list retval;
+
+  if (args(0).is_cell())
+    {
+      OCTAVE_LOCAL_BUFFER (Cell, newretval, nargout);
+      octave_value_list new_args = args;
+      Cell cellstr = args(0).cell_value();
+      if (args(1).is_cell())
+	{
+	  Cell cellpat = args(1).cell_value();
+
+	  if (cellpat.numel() == 1)
+	    {
+	      for (int j = 0; j < nargout; j++)
+		newretval[j].resize(cellstr.dims());
+
+	      new_args(1) = cellpat(0);
+
+	      for (octave_idx_type i = 0; i < cellstr.numel (); i++)
+		{
+		  new_args(0) = cellstr(i);
+		  octave_value_list tmp = octregexp (new_args, nargout, nm, 
+						     case_insensitive);
+
+		  if (error_state)
+		    break;
+
+		  for (int j = 0; j < nargout; j++)
+		    newretval[j](i) = tmp(j);
+		}
+	    }
+	  else if (cellstr.numel() == 1)
+	    {
+	      for (int j = 0; j < nargout; j++)
+		newretval[j].resize(cellpat.dims());
+
+	      new_args(0) = cellstr(0);
+
+	      for (octave_idx_type i = 0; i < cellpat.numel (); i++)
+		{
+		  new_args(1) = cellpat(i);
+		  octave_value_list tmp = octregexp (new_args, nargout, nm, 
+						     case_insensitive);
+
+		  if (error_state)
+		    break;
+
+		  for (int j = 0; j < nargout; j++)
+		    newretval[j](i) = tmp(j);
+		}
+	    }
+	  else if (cellstr.numel() == cellpat.numel())
+	    {
+
+	      if (cellstr.dims() != cellpat.dims())
+		error ("%s: Inconsistent cell array dimensions", nm.c_str());
+	      else
+		{
+		  for (int j = 0; j < nargout; j++)
+		    newretval[j].resize(cellstr.dims());
+
+		  for (octave_idx_type i = 0; i < cellstr.numel (); i++)
+		    {
+		      new_args(0) = cellstr(i);
+		      new_args(1) = cellpat(i);
+
+		      octave_value_list tmp = octregexp (new_args, nargout, nm, 
+							 case_insensitive);
+
+		      if (error_state)
+			break;
+
+		      for (int j = 0; j < nargout; j++)
+			newretval[j](i) = tmp(j);
+		    }
+		}
+	    }
+	  else
+	    error ("regexp: cell array arguments must be scalar or equal size");
+	}
+      else
+	{
+	  for (int j = 0; j < nargout; j++)
+	    newretval[j].resize(cellstr.dims());
+
+	  for (octave_idx_type i = 0; i < cellstr.numel (); i++)
+	    {
+	      new_args(0) = cellstr(i);
+	      octave_value_list tmp = octregexp (new_args, nargout, nm, case_insensitive);
+
+	      if (error_state)
+		break;
+
+	      for (int j = 0; j < nargout; j++)
+		newretval[j](i) = tmp(j);
+	    }
+	}
+
+      if (!error_state)
+	for (int j = 0; j < nargout; j++)
+	  retval(j) = octave_value (newretval[j]);
+    }
+  else if (args(1).is_cell())
+    {
+      OCTAVE_LOCAL_BUFFER (Cell, newretval, nargout);
+      octave_value_list new_args = args;
+      Cell cellpat = args(1).cell_value();
+
+      for (int j = 0; j < nargout; j++)
+	newretval[j].resize(cellpat.dims());
+
+      for (octave_idx_type i = 0; i < cellpat.numel (); i++)
+	{
+	  new_args(1) = cellpat(i);
+	  octave_value_list tmp = octregexp (new_args, nargout, nm, case_insensitive);
+
+	  if (error_state)
+	    break;
+
+	  for (int j = 0; j < nargout; j++)
+	    newretval[j](i) = tmp(j);
+	}
+
+      if (!error_state)
+	for (int j = 0; j < nargout; j++)
+	  retval(j) = octave_value (newretval[j]);
+    }
+  else
+    retval = octregexp (args, nargout, nm, case_insensitive);
+
+  return retval;
+
+}
+
+DEFUN_DLD (regexp, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{s}, @var{e}, @var{te}, @var{m}, @var{t}, @var{nm}] =} regexp (@var{str}, @var{pat})\n\
+ at deftypefnx {Loadable Function} {[@dots{}] =} regexp (@var{str}, @var{pat}, @var{opts}, @dots{})\n\
+\n\
+Regular expression string matching.  Matches @var{pat} in @var{str} and\n\
+returns the position and matching substrings or empty values if there are\n\
+none.\n\
+\n\
+The matched pattern @var{pat} can include any of the standard regex\n\
+operators, including:\n\
+\n\
+ at table @code\n\
+ at item .\n\
+Match any character\n\
+ at item * + ? @{@}\n\
+Repetition operators, representing\n\
+ at table @code\n\
+ at item *\n\
+Match zero or more times\n\
+ at item +\n\
+Match one or more times\n\
+ at item ?\n\
+Match zero or one times\n\
+ at item @{@}\n\
+Match range operator, which is of the form @code{@{@var{n}@}} to match exactly\n\
+ at var{n} times, @code{@{@var{m},@}} to match @var{m} or more times,\n\
+ at code{@{@var{m}, at var{n}@}} to match between @var{m} and @var{n} times.\n\
+ at end table\n\
+ at item [@dots{}] [^@dots{}]\n\
+List operators, where for example @code{[ab]c} matches @code{ac} and @code{bc}\n\
+ at item ()\n\
+Grouping operator\n\
+ at item |\n\
+Alternation operator.  Match one of a choice of regular expressions.  The\n\
+alternatives must be delimited by the grouping operator @code{()} above\n\
+ at item ^ $\n\
+Anchoring operator.  @code{^} matches the start of the string @var{str} and\n\
+ at code{$} the end\n\
+ at end table\n\
+\n\
+In addition the following escaped characters have special meaning.  It should\n\
+be noted that it is recommended to quote @var{pat} in single quotes rather\n\
+than double quotes, to avoid the escape sequences being interpreted by Octave\n\
+before being passed to @code{regexp}.\n\
+\n\
+ at table @code\n\
+ at item \\b\n\
+Match a word boundary\n\
+ at item \\B\n\
+Match within a word\n\
+ at item \\w\n\
+Matches any word character\n\
+ at item \\W\n\
+Matches any non word character\n\
+ at item \\<\n\
+Matches the beginning of a word\n\
+ at item \\>\n\
+Matches the end of a word\n\
+ at item \\s\n\
+Matches any whitespace character\n\
+ at item \\S\n\
+Matches any non whitespace character\n\
+ at item \\d\n\
+Matches any digit\n\
+ at item \\D\n\
+Matches any non-digit\n\
+ at end table\n\
+\n\
+The outputs of @code{regexp} by default are in the order as given below\n\
+\n\
+ at table @asis\n\
+ at item @var{s}\n\
+The start indices of each of the matching substrings\n\
+\n\
+ at item @var{e}\n\
+The end indices of each matching substring\n\
+\n\
+ at item @var{te}\n\
+The extents of each of the matched token surrounded by @code{(@dots{})} in\n\
+ at var{pat}.\n\
+\n\
+ at item @var{m}\n\
+A cell array of the text of each match.\n\
+\n\
+ at item @var{t}\n\
+A cell array of the text of each token matched.\n\
+\n\
+ at item @var{nm}\n\
+A structure containing the text of each matched named token, with the name\n\
+being used as the fieldname.  A named token is denoted as\n\
+ at code{(?<name>@dots{})}\n\
+ at end table\n\
+\n\
+Particular output arguments or the order of the output arguments can be\n\
+selected by additional @var{opts} arguments.  These are strings and the\n\
+correspondence between the output arguments and the optional argument\n\
+are\n\
+\n\
+ at multitable @columnfractions 0.2 0.3 0.3 0.2\n\
+ at item @tab 'start'        @tab @var{s}  @tab\n\
+ at item @tab 'end'          @tab @var{e}  @tab\n\
+ at item @tab 'tokenExtents' @tab @var{te} @tab\n\
+ at item @tab 'match'        @tab @var{m}  @tab\n\
+ at item @tab 'tokens'       @tab @var{t}  @tab\n\
+ at item @tab 'names'        @tab @var{nm}  @tab\n\
+ at end multitable\n\
+\n\
+A further optional argument is 'once', that limits the number of returned\n\
+matches to the first match.  Additional arguments are\n\
+\n\
+ at table @asis\n\
+ at item matchcase\n\
+Make the matching case sensitive.\n\
+ at item ignorecase\n\
+Make the matching case insensitive.\n\
+ at item stringanchors\n\
+Match the anchor characters at the beginning and end of the string.\n\
+ at item lineanchors\n\
+Match the anchor characters at the beginning and end of the line.\n\
+ at item dotall\n\
+The character @code{.} matches the newline character.\n\
+ at item dotexceptnewline\n\
+The character @code{.} matches all but the newline character.\n\
+ at item freespacing\n\
+The pattern can include arbitrary whitespace and comments starting with\n\
+ at code{#}.\n\
+ at item literalspacing\n\
+The pattern is taken literally.\n\
+ at end table\n\
+ at seealso{regexpi, regexprep}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length();
+
+  if (nargin < 2)
+    print_usage ();
+  else if (args(0).is_cell() || args(1).is_cell())
+    retval = octcellregexp (args, nargout, "regexp", false);
+  else
+    retval = octregexp (args, nargout, "regexp", false);
+
+  return retval;
+}
+
+/*
+
+## PCRE_ERROR_MATCHLIMIT test
+%!test
+%! s=sprintf('\t4\n0000\t-0.00\t-0.0000\t4\t-0.00\t-0.0000\t4\n0000\t-0.00\t-0.0000\t0\t-0.00\t-');
+%! ws = warning("query");
+%! unwind_protect
+%!   warning("off");
+%!   regexp(s, '(\s*-*\d+[.]*\d*\s*)+\n');
+%! unwind_protect_cleanup
+%!   warning(ws);
+%! end_unwind_protect
+
+## seg-fault test
+%!assert(regexp("abcde","."),[1,2,3,4,5])
+
+## Check that anchoring of pattern works correctly
+%!assert(regexp('abcabc','^abc'),1);
+%!assert(regexp('abcabc','abc$'),4);
+%!assert(regexp('abcabc','^abc$'),zeros(1,0));
+
+%!test
+%! [s, e, te, m, t] = regexp(' No Match ', 'f(.*)uck');
+%! assert (s,zeros(1,0))
+%! assert (e,zeros(1,0))
+%! assert (te,cell(1,0))
+%! assert (m, cell(1,0))
+%! assert (t, cell(1,0))
+
+%!test
+%! [s, e, te, m, t] = regexp(' FiRetrUck ', 'f(.*)uck');
+%! assert (s,zeros(1,0))
+%! assert (e,zeros(1,0))
+%! assert (te,cell(1,0))
+%! assert (m, cell(1,0))
+%! assert (t, cell(1,0))
+
+%!test
+%! [s, e, te, m, t] = regexp(' firetruck ', 'f(.*)uck');
+%! assert (s,2)
+%! assert (e,10)
+%! assert (te{1},[3,7])
+%! assert (m{1}, 'firetruck')
+%! assert (t{1}{1}, 'iretr')
+
+%!test
+%! [s, e, te, m, t] = regexp('short test string','\w*r\w*');
+%! assert (s,[1,12])
+%! assert (e,[5,17])
+%! assert (size(te), [1,2])
+%! assert (isempty(te{1}))
+%! assert (isempty(te{2}))
+%! assert (m{1},'short')
+%! assert (m{2},'string')
+%! assert (size(t), [1,2])
+%! assert (isempty(t{1}))
+%! assert (isempty(t{2}))
+
+%!test
+%! [s, e, te, m, t] = regexp('short test string','\w*r\w*','once');
+%! assert (s,1)
+%! assert (e,5)
+%! assert (isempty(te))
+%! assert (m,'short')
+%! assert (isempty(t))
+
+%!test
+%! [m, te, e, s, t] = regexp('short test string','\w*r\w*','once', 'match', 'tokenExtents', 'end', 'start', 'tokens');
+%! assert (s,1)
+%! assert (e,5)
+%! assert (isempty(te))
+%! assert (m,'short')
+%! assert (isempty(t))
+
+%!testif HAVE_PCRE
+%! ## This test is expected to fail if PCRE is not installed
+%! [s, e, te, m, t, nm] = regexp('short test string','(?<word1>\w*t)\s*(?<word2>\w*t)');
+%! assert (s,1)
+%! assert (e,10)
+%! assert (size(te), [1,1])
+%! assert (te{1}, [1 5; 7, 10])
+%! assert (m{1},'short test')
+%! assert (size(t),[1,1])
+%! assert (t{1}{1},'short')
+%! assert (t{1}{2},'test')
+%! assert (size(nm), [1,1])
+%! assert (!isempty(fieldnames(nm)))
+%! assert (sort(fieldnames(nm)),{'word1';'word2'})
+%! assert (nm.word1,'short')
+%! assert (nm.word2,'test')
+
+%!testif HAVE_PCRE
+%! ## This test is expected to fail if PCRE is not installed
+%! [nm, m, te, e, s, t] = regexp('short test string','(?<word1>\w*t)\s*(?<word2>\w*t)', 'names', 'match', 'tokenExtents', 'end', 'start', 'tokens');
+%! assert (s,1)
+%! assert (e,10)
+%! assert (size(te), [1,1])
+%! assert (te{1}, [1 5; 7, 10])
+%! assert (m{1},'short test')
+%! assert (size(t),[1,1])
+%! assert (t{1}{1},'short')
+%! assert (t{1}{2},'test')
+%! assert (size(nm), [1,1])
+%! assert (!isempty(fieldnames(nm)))
+%! assert (sort(fieldnames(nm)),{'word1';'word2'})
+%! assert (nm.word1,'short')
+%! assert (nm.word2,'test')
+
+%!testif HAVE_PCRE
+%! ## This test is expected to fail if PCRE is not installed
+%! [t, nm] = regexp("John Davis\nRogers, James",'(?<first>\w+)\s+(?<last>\w+)|(?<last>\w+),\s+(?<first>\w+)','tokens','names');
+%! assert (size(t), [1,2]);
+%! assert (t{1}{1},'John');
+%! assert (t{1}{2},'Davis');
+%! assert (t{2}{1},'Rogers');
+%! assert (t{2}{2},'James');
+%! assert (size(nm), [1,1]);
+%! assert (nm.first{1},'John');
+%! assert (nm.first{2},'James');
+%! assert (nm.last{1},'Davis');
+%! assert (nm.last{2},'Rogers');
+
+%!assert(regexp("abc\nabc",'.'),[1:7])
+%!assert(regexp("abc\nabc",'.','dotall'),[1:7])
+%!testif HAVE_PCRE
+%! assert(regexp("abc\nabc",'(?s).'),[1:7])
+%! assert(regexp("abc\nabc",'.','dotexceptnewline'),[1,2,3,5,6,7])
+%! assert(regexp("abc\nabc",'(?-s).'),[1,2,3,5,6,7])
+
+%!assert(regexp("caseCaSe",'case'),1)
+%!assert(regexp("caseCaSe",'case',"matchcase"),1)
+%!assert(regexp("caseCaSe",'case',"ignorecase"),[1,5])
+%!testif HAVE_PCRE
+%! assert(regexp("caseCaSe",'(?-i)case'),1)
+%! assert(regexp("caseCaSe",'(?i)case'),[1,5])
+
+%!assert (regexp("abc\nabc",'c$'),7)
+%!assert (regexp("abc\nabc",'c$',"stringanchors"),7)
+%!testif HAVE_PCRE
+%! assert (regexp("abc\nabc",'(?-m)c$'),7)
+%! assert (regexp("abc\nabc",'c$',"lineanchors"),[3,7])
+%! assert (regexp("abc\nabc",'(?m)c$'),[3,7])
+
+%!assert (regexp("this word",'s w'),4)
+%!assert (regexp("this word",'s w','literalspacing'),4)
+%!testif HAVE_PCRE
+%! assert (regexp("this word",'(?-x)s w','literalspacing'),4)
+%! assert (regexp("this word",'s w','freespacing'),zeros(1,0))
+%! assert (regexp("this word",'(?x)s w'),zeros(1,0))
+
+%!error regexp('string', 'tri', 'BadArg');
+%!error regexp('string');
+
+%!assert(regexp({'asdfg-dfd';'-dfd-dfd-';'qasfdfdaq'},'-'),{6;[1,5,9];zeros(1,0)})
+%!assert(regexp({'asdfg-dfd','-dfd-dfd-','qasfdfdaq'},'-'),{6,[1,5,9],zeros(1,0)})
+%!assert(regexp({'asdfg-dfd';'-dfd-dfd-';'qasfdfdaq'},{'-';'f';'q'}),{6;[3,7];[1,9]})
+%!assert(regexp('Strings',{'t','s'}),{2,7})
+
+## Test case for lookaround operators
+%!assert(regexp('Iraq','q(?!u)'),4)
+%!assert(regexp('quit','q(?!u)'), zeros(1,0))
+%!assert(regexp('quit','q(?=u)','match'), {'q'})
+%!assert(regexp("quit",'q(?=u+)','match'), {'q'})
+%!assert(regexp("qit",'q(?=u+)','match'), cell(1,0))
+%!assert(regexp("qit",'q(?=u*)','match'), {'q'})
+
+%!assert(regexp('thingamabob','(?<=a)b'), 9)
+
+*/
+
+DEFUN_DLD (regexpi, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{s}, @var{e}, @var{te}, @var{m}, @var{t}, @var{nm}] =} regexpi (@var{str}, @var{pat})\n\
+ at deftypefnx {Loadable Function} {[@dots{}] =} regexpi (@var{str}, @var{pat}, @var{opts}, @dots{})\n\
+\n\
+Case insensitive regular expression string matching.  Matches @var{pat} in\n\
+ at var{str} and returns the position and matching substrings or empty values\n\
+if there are none.  @xref{doc-regexp,,regexp}, for more details\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length();
+
+  if (nargin < 2)
+    print_usage ();
+  else if (args(0).is_cell() || args(1).is_cell())
+    retval = octcellregexp (args, nargout, "regexpi", true);
+  else
+    retval = octregexp (args, nargout, "regexpi", true);
+
+  return retval;
+}
+
+/*
+
+## seg-fault test
+%!assert(regexpi("abcde","."),[1,2,3,4,5])
+
+## Check that anchoring of pattern works correctly
+%!assert(regexpi('abcabc','^abc'),1);
+%!assert(regexpi('abcabc','abc$'),4);
+%!assert(regexpi('abcabc','^abc$'),zeros(1,0));
+
+%!test
+%! [s, e, te, m, t] = regexpi(' No Match ', 'f(.*)uck');
+%! assert (s,zeros(1,0))
+%! assert (e,zeros(1,0))
+%! assert (te,cell(1,0))
+%! assert (m, cell(1,0))
+%! assert (t, cell(1,0))
+
+%!test
+%! [s, e, te, m, t] = regexpi(' FiRetrUck ', 'f(.*)uck');
+%! assert (s,2)
+%! assert (e,10)
+%! assert (te{1},[3,7])
+%! assert (m{1}, 'FiRetrUck')
+%! assert (t{1}{1}, 'iRetr')
+
+%!test
+%! [s, e, te, m, t] = regexpi(' firetruck ', 'f(.*)uck');
+%! assert (s,2)
+%! assert (e,10)
+%! assert (te{1},[3,7])
+%! assert (m{1}, 'firetruck')
+%! assert (t{1}{1}, 'iretr')
+
+%!test
+%! [s, e, te, m, t] = regexpi('ShoRt Test String','\w*r\w*');
+%! assert (s,[1,12])
+%! assert (e,[5,17])
+%! assert (size(te), [1,2])
+%! assert (isempty(te{1}))
+%! assert (isempty(te{2}))
+%! assert (m{1},'ShoRt')
+%! assert (m{2},'String')
+%! assert (size(t), [1,2])
+%! assert (isempty(t{1}))
+%! assert (isempty(t{2}))
+
+%!test
+%! [s, e, te, m, t] = regexpi('ShoRt Test String','\w*r\w*','once');
+%! assert (s,1)
+%! assert (e,5)
+%! assert (isempty(te))
+%! assert (m,'ShoRt')
+%! assert (isempty(t))
+
+%!test
+%! [m, te, e, s, t] = regexpi('ShoRt Test String','\w*r\w*','once', 'match', 'tokenExtents', 'end', 'start', 'tokens');
+%! assert (s,1)
+%! assert (e,5)
+%! assert (isempty(te))
+%! assert (m,'ShoRt')
+%! assert (isempty(t))
+
+%!testif HAVE_PCRE
+%! ## This test is expected to fail if PCRE is not installed
+%! [s, e, te, m, t, nm] = regexpi('ShoRt Test String','(?<word1>\w*t)\s*(?<word2>\w*t)');
+%! assert (s,1)
+%! assert (e,10)
+%! assert (size(te), [1,1])
+%! assert (te{1}, [1 5; 7, 10])
+%! assert (m{1},'ShoRt Test')
+%! assert (size(t),[1,1])
+%! assert (t{1}{1},'ShoRt')
+%! assert (t{1}{2},'Test')
+%! assert (size(nm), [1,1])
+%! assert (!isempty(fieldnames(nm)))
+%! assert (sort(fieldnames(nm)),{'word1';'word2'})
+%! assert (nm.word1,'ShoRt')
+%! assert (nm.word2,'Test')
+
+%!testif HAVE_PCRE
+%! ## This test is expected to fail if PCRE is not installed
+%! [nm, m, te, e, s, t] = regexpi('ShoRt Test String','(?<word1>\w*t)\s*(?<word2>\w*t)', 'names', 'match', 'tokenExtents', 'end', 'start', 'tokens');
+%! assert (s,1)
+%! assert (e,10)
+%! assert (size(te), [1,1])
+%! assert (te{1}, [1 5; 7, 10])
+%! assert (m{1},'ShoRt Test')
+%! assert (size(t),[1,1])
+%! assert (t{1}{1},'ShoRt')
+%! assert (t{1}{2},'Test')
+%! assert (size(nm), [1,1])
+%! assert (!isempty(fieldnames(nm)))
+%! assert (sort(fieldnames(nm)),{'word1';'word2'})
+%! assert (nm.word1,'ShoRt')
+%! assert (nm.word2,'Test')
+
+%!assert(regexpi("abc\nabc",'.'),[1:7])
+%!assert(regexpi("abc\nabc",'.','dotall'),[1:7])
+%!testif HAVE_PCRE
+%! assert(regexpi("abc\nabc",'(?s).'),[1:7])
+%! assert(regexpi("abc\nabc",'.','dotexceptnewline'),[1,2,3,5,6,7])
+%! assert(regexpi("abc\nabc",'(?-s).'),[1,2,3,5,6,7])
+
+%!assert(regexpi("caseCaSe",'case'),[1,5])
+%!assert(regexpi("caseCaSe",'case',"matchcase"),1)
+%!assert(regexpi("caseCaSe",'case',"ignorecase"),[1,5])
+%!testif HAVE_PCRE
+%! assert(regexpi("caseCaSe",'(?-i)case'),1)
+%! assert(regexpi("caseCaSe",'(?i)case'),[1,5])
+
+%!assert (regexpi("abc\nabc",'c$'),7)
+%!assert (regexpi("abc\nabc",'c$',"stringanchors"),7)
+%!testif HAVE_PCRE
+%! assert (regexpi("abc\nabc",'(?-m)c$'),7)
+%! assert (regexpi("abc\nabc",'c$',"lineanchors"),[3,7])
+%! assert (regexpi("abc\nabc",'(?m)c$'),[3,7])
+
+%!assert (regexpi("this word",'s w'),4)
+%!assert (regexpi("this word",'s w','literalspacing'),4)
+%!testif HAVE_PCRE
+%! assert (regexpi("this word",'(?-x)s w','literalspacing'),4)
+%! assert (regexpi("this word",'s w','freespacing'),zeros(1,0))
+%! assert (regexpi("this word",'(?x)s w'),zeros(1,0))
+
+%!error regexpi('string', 'tri', 'BadArg');
+%!error regexpi('string');
+
+%!assert(regexpi({'asdfg-dfd';'-dfd-dfd-';'qasfdfdaq'},'-'),{6;[1,5,9];zeros(1,0)})
+%!assert(regexpi({'asdfg-dfd','-dfd-dfd-','qasfdfdaq'},'-'),{6,[1,5,9],zeros(1,0)})
+%!assert(regexpi({'asdfg-dfd';'-dfd-dfd-';'qasfdfdaq'},{'-';'f';'q'}),{6;[3,7];[1,9]})
+%!assert(regexpi('Strings',{'t','s'}),{2,[1,7]})
+
+*/
+
+
+static octave_value
+octregexprep (const octave_value_list &args, const std::string &nm)
+{
+  octave_value retval;
+  int nargin = args.length();
+
+  // Make sure we have string,pattern,replacement
+  const std::string buffer = args(0).string_value ();
+  if (error_state) return retval;
+  const std::string pattern = args(1).string_value ();
+  if (error_state) return retval;
+  const std::string replacement = args(2).string_value ();
+  if (error_state) return retval;
+  
+  // Pack options excluding 'tokenize' and various output
+  // reordering strings into regexp arg list
+  octave_value_list regexpargs(nargin-1,octave_value());
+  regexpargs(0) = args(0);
+  regexpargs(1) = args(1);
+  int len=2;
+  for (int i = 3; i < nargin; i++) 
+    {
+      const std::string opt = args(i).string_value();
+      if (opt != "tokenize" && opt != "start" && opt != "end"
+	  && opt != "tokenextents" && opt != "match" && opt != "tokens"
+	  && opt != "names"  && opt != "warnings") 
+	{
+	  regexpargs(len++) = args(i);
+	}
+    }
+  regexpargs.resize(len);
+  
+  // Identify replacement tokens; build a vector of group numbers in
+  // the replacement string so that we can quickly calculate the size 
+  // of the replacement.
+  int tokens = 0;
+  for (size_t i=1; i < replacement.size(); i++) 
+    {
+      if (replacement[i-1]=='$' && isdigit(replacement[i])) 
+	{
+	  tokens++, i++;
+	}
+    }
+  std::vector<int> token(tokens);
+  int kk = 0;
+  for (size_t i = 1; i < replacement.size(); i++) 
+    {
+      if (replacement[i-1]=='$' && isdigit(replacement[i])) 
+	{
+	  token[kk++] = replacement[i]-'0';
+	  i++;
+	}
+    }
+
+  // Perform replacement
+  std::string rep;
+  if (tokens > 0) 
+    {
+      std::list<regexp_elem> lst;
+      string_vector named;
+      int nopts;
+      bool once;
+      int sz = octregexp_list (regexpargs, nm , false, lst, named, nopts, once);
+
+      if (error_state)
+	return retval;
+      if (sz == 0)
+	{
+	  retval = args(0);
+	  return retval;
+	}
+
+      // Determine replacement length
+      const size_t replen = replacement.size() - 2*tokens;
+      int delta = 0;
+      const_iterator p = lst.begin();
+      for (int i = 0; i < sz; i++) 
+	{
+	  OCTAVE_QUIT;
+
+	  const Matrix pairs(p->te);
+	  size_t pairlen = 0;
+	  for (int j = 0; j < tokens; j++) 
+	    {
+	      if (token[j] == 0) 
+		pairlen += static_cast<size_t>(p->e - p->s) + 1;
+	      else if (token[j] <= pairs.rows()) 
+		pairlen += static_cast<size_t>(pairs(token[j]-1,1) - 
+					       pairs(token[j]-1,0)) + 1;
+	    }
+	  delta += static_cast<int>(replen + pairlen) - 
+	    static_cast<int>(p->e - p->s + 1);
+	  p++;
+	}
+      
+      // Build replacement string
+      rep.reserve(buffer.size()+delta);
+      size_t from = 0;
+      p = lst.begin();
+      for (int i=0; i < sz; i++) 
+	{
+	  OCTAVE_QUIT;
+
+	  const Matrix pairs(p->te);
+	  rep.append(&buffer[from], static_cast<size_t>(p->s - 1) - from);
+	  from = static_cast<size_t>(p->e - 1) + 1;
+	  for (size_t j = 1; j < replacement.size(); j++) 
+	    {
+	      if (replacement[j-1]=='$' && isdigit(replacement[j])) 
+		{
+		  int k = replacement[j]-'0';
+		  if (k == 0) 
+		    { 
+		      // replace with entire match
+		      rep.append(&buffer[static_cast<size_t>(p->e - 1)],
+				 static_cast<size_t>(p->e - p->s) + 1);
+		    } 
+		  else if (k <= pairs.rows()) 
+		    {
+		      // replace with group capture
+		      rep.append(&buffer[static_cast<size_t>(pairs(k-1,0)-1)],
+				 static_cast<size_t>(pairs(k-1,1) - 
+						     pairs(k-1,0))+1);
+		    }
+		  else 
+		    {
+		      // replace with nothing
+		    }
+		  j++;
+		} 
+	      else 
+		{
+		  rep.append(1,replacement[j-1]);
+		}
+	      if (j+1 == replacement.size()) 
+		{
+		  rep.append(1,replacement[j]);
+		}
+	    }
+	  p++;
+	}
+      rep.append(&buffer[from],buffer.size()-from);
+    } 
+  else 
+    {
+      std::list<regexp_elem> lst;
+      string_vector named;
+      int nopts;
+      bool once;
+      int sz = octregexp_list (regexpargs, nm, false, lst, named, nopts, once);
+
+      if (error_state)
+	return retval;
+      if (sz == 0)
+	{
+	  retval = args(0);
+	  return retval;
+	}
+
+      // Determine replacement length
+      const size_t replen = replacement.size();
+      int delta = 0;
+      const_iterator p = lst.begin();
+      for (int i = 0; i < sz; i++) 
+	{
+          OCTAVE_QUIT;
+	  delta += static_cast<int>(replen) - 
+	    static_cast<int>(p->e - p->s + 1);
+	  p++;
+	}
+
+      // Build replacement string
+      rep.reserve(buffer.size()+delta);
+      size_t from = 0;
+      p = lst.begin();
+      for (int i=0; i < sz; i++) 
+	{
+          OCTAVE_QUIT;
+	  rep.append(&buffer[from], static_cast<size_t>(p->s - 1) - from);
+	  from = static_cast<size_t>(p->e - 1) + 1;
+	  rep.append(replacement);
+	  p++;
+	}
+      rep.append(&buffer[from],buffer.size()-from);
+    }
+  
+  retval = rep;
+  return retval;
+}
+
+DEFUN_DLD (regexprep, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function}  {@var{string} =} regexprep (@var{string}, @var{pat}, @var{repstr}, @var{options})\n\
+Replace matches of @var{pat} in  @var{string} with @var{repstr}.\n\
+\n\
+\n\
+The replacement can contain @code{$i}, which substitutes\n\
+for the ith set of parentheses in the match string.  E.g.,\n\
+ at example\n\
+ at group\n\
+\n\
+   regexprep(\"Bill Dunn\",'(\\w+) (\\w+)','$2, $1')\n\
+\n\
+ at end group\n\
+ at end example\n\
+returns \"Dunn, Bill\"\n\
+\n\
+ at var{options} may be zero or more of\n\
+ at table @samp\n\
+\n\
+ at item once\n\
+Replace only the first occurrence of @var{pat} in the result.\n\
+\n\
+ at item warnings\n\
+This option is present for compatibility but is ignored.\n\
+\n\
+ at item ignorecase or matchcase\n\
+Ignore case for the pattern matching (see @code{regexpi}).\n\
+Alternatively, use (?i) or (?-i) in the pattern.\n\
+\n\
+ at item lineanchors and stringanchors\n\
+Whether characters ^ and $ match the beginning and ending of lines.\n\
+Alternatively, use (?m) or (?-m) in the pattern.\n\
+\n\
+ at item dotexceptnewline and dotall\n\
+Whether . matches newlines in the string.\n\
+Alternatively, use (?s) or (?-s) in the pattern.\n\
+\n\
+ at item freespacing or literalspacing\n\
+Whether whitespace and # comments can be used to make the regular expression more readable.\n\
+Alternatively, use (?x) or (?-x) in the pattern.\n\
+\n\
+ at end table\n\
+ at seealso{regexp,regexpi,strrep}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length();
+
+  if (nargin < 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (args(0).is_cell() || args(1).is_cell() || args(2).is_cell())
+    {
+      Cell str;
+      Cell pat;
+      Cell rep;
+      dim_vector dv0;
+      dim_vector dv1(1,1);
+
+      if (args(0).is_cell())
+	str = args(0).cell_value();
+      else
+	str = Cell (args(0));
+
+      if (args(1).is_cell())
+	pat = args(1).cell_value();
+      else
+	pat = Cell (args(1));
+
+      if (args(2).is_cell())
+	rep = args(2).cell_value();
+      else
+	rep = Cell (args(2));
+
+      dv0 = str.dims();
+      if (pat.numel() != 1)
+	{
+	  dv1 = pat.dims();
+	  if (rep.numel() != 1 && dv1 != rep.dims())
+	    error ("regexprep: Inconsistent cell array dimensions");
+	}
+      else if (rep.numel() != 1)
+	dv1 = rep.dims();
+
+      if (!error_state)
+	{
+	  Cell ret (dv0);
+	  octave_value_list new_args = args;
+
+	  for (octave_idx_type i = 0; i < dv0.numel(); i++)
+	    {
+	      new_args(0) = str(i);
+	      if (pat.numel() == 1)
+		new_args(1) = pat(0);
+	      if (rep.numel() == 1)
+		new_args(2) = rep(0);
+	      for (octave_idx_type j = 0; j < dv1.numel(); j++)
+		{
+		  if (pat.numel() != 1)
+		    new_args(1) = pat(j);
+		  if (rep.numel() != 1)
+		    new_args(2) = rep(j);
+		  new_args(0) = octregexprep (new_args, "regexprep");
+
+		  if (error_state)
+		    break;
+		}
+
+	      if (error_state)
+		break;
+
+	      ret(i) = new_args(0);
+	    }
+
+	  if (!error_state)
+	    retval = octave_value (ret);
+	}
+    }
+  else
+    retval = octregexprep (args, "regexprep");
+
+  return retval;
+}
+
+/*
+%!test  # Replace with empty
+%! xml = '<!-- This is some XML --> <tag v="hello">some stuff<!-- sample tag--></tag>';
+%! t = regexprep(xml,'<[!?][^>]*>','');
+%! assert(t,' <tag v="hello">some stuff</tag>')
+
+%!test  # Replace with non-empty
+%! xml = '<!-- This is some XML --> <tag v="hello">some stuff<!-- sample tag--></tag>';
+%! t = regexprep(xml,'<[!?][^>]*>','?');
+%! assert(t,'? <tag v="hello">some stuff?</tag>')
+
+%!test  # Check that 'tokenize' is ignored
+%! xml = '<!-- This is some XML --> <tag v="hello">some stuff<!-- sample tag--></tag>';
+%! t = regexprep(xml,'<[!?][^>]*>','','tokenize');
+%! assert(t,' <tag v="hello">some stuff</tag>')
+
+%!testif HAVE_PCRE # Capture replacement
+%! data = "Bob Smith\nDavid Hollerith\nSam Jenkins";
+%! result = "Smith, Bob\nHollerith, David\nJenkins, Sam";
+%! t = regexprep(data,'(?m)^(\w+)\s+(\w+)$','$2, $1');
+%! assert(t,result)
+
+# Return the original if no match
+%!assert(regexprep('hello','world','earth'),'hello')
+
+## Test a general replacement
+%!assert(regexprep("a[b]c{d}e-f=g", "[^A-Za-z0-9_]", "_"), "a_b_c_d_e_f_g");
+
+## Make sure it works at the beginning and end
+%!assert(regexprep("a[b]c{d}e-f=g", "a", "_"), "_[b]c{d}e-f=g");
+%!assert(regexprep("a[b]c{d}e-f=g", "g", "_"), "a[b]c{d}e-f=_");
+
+## Options
+%!assert(regexprep("a[b]c{d}e-f=g", "[^A-Za-z0-9_]", "_", "once"), "a_b]c{d}e-f=g");
+%!assert(regexprep("a[b]c{d}e-f=g", "[^A-Z0-9_]", "_", "ignorecase"), "a_b_c_d_e_f_g");
+
+## Option combinations
+%!assert(regexprep("a[b]c{d}e-f=g", "[^A-Z0-9_]", "_", "once", "ignorecase"), "a_b]c{d}e-f=g");
+
+## End conditions on replacement
+%!assert(regexprep("abc","(b)",".$1"),"a.bc");
+%!assert(regexprep("abc","(b)","$1"),"abc");
+%!assert(regexprep("abc","(b)","$1."),"ab.c");
+%!assert(regexprep("abc","(b)","$1.."),"ab..c");
+
+## Test cell array arguments
+%!assert(regexprep("abc",{"b","a"},"?"),{"??c"})
+%!assert(regexprep({"abc","cba"},"b","?"),{"a?c","c?a"})
+%!assert(regexprep({"abc","cba"},{"b","a"},{"?","!"}),{"!?c","c?!"})
+
+# Nasty lookbehind expression
+%!assert(regexprep('x^(-1)+y(-1)+z(-1)=0','(?<=[a-z]+)\(\-[1-9]*\)','_minus1'),'x^(-1)+y_minus1+z_minus1=0')
+
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/schur.cc b/src/DLD-FUNCTIONS/schur.cc
new file mode 100644
index 0000000..989382d
--- /dev/null
+++ b/src/DLD-FUNCTIONS/schur.cc
@@ -0,0 +1,417 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "CmplxSCHUR.h"
+#include "dbleSCHUR.h"
+#include "fCmplxSCHUR.h"
+#include "floatSCHUR.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (schur, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{s} =} schur (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{u}, @var{s}] =} schur (@var{a}, @var{opt})\n\
+ at cindex Schur decomposition\n\
+The Schur decomposition is used to compute eigenvalues of a\n\
+square matrix, and has applications in the solution of algebraic\n\
+Riccati equations in control (see @code{are} and @code{dare}).\n\
+ at code{schur} always returns\n\
+ at iftex\n\
+ at tex\n\
+$S = U^T A U$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s = u' * a * u}\n\
+ at end ifnottex\n\
+where\n\
+ at iftex\n\
+ at tex\n\
+$U$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{u}\n\
+ at end ifnottex\n\
+ is a unitary matrix\n\
+ at iftex\n\
+ at tex\n\
+($U^T U$ is identity)\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+(@code{u'* u} is identity)\n\
+ at end ifnottex\n\
+and\n\
+ at iftex\n\
+ at tex\n\
+$S$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}\n\
+ at end ifnottex\n\
+is upper triangular.  The eigenvalues of\n\
+ at iftex\n\
+ at tex\n\
+$A$ (and $S$)\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{a} (and @code{s})\n\
+ at end ifnottex\n\
+are the diagonal elements of\n\
+ at iftex\n\
+ at tex\n\
+$S$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}.\n\
+ at end ifnottex\n\
+If the matrix\n\
+ at iftex\n\
+ at tex\n\
+$A$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{a}\n\
+ at end ifnottex\n\
+is real, then the real Schur decomposition is computed, in which the\n\
+matrix\n\
+ at iftex\n\
+ at tex\n\
+$U$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{u}\n\
+ at end ifnottex\n\
+is orthogonal and\n\
+ at iftex\n\
+ at tex\n\
+$S$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}\n\
+ at end ifnottex\n\
+is block upper triangular\n\
+with blocks of size at most\n\
+ at iftex\n\
+ at tex\n\
+$2\\times 2$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{2 x 2}\n\
+ at end ifnottex\n\
+along the diagonal.  The diagonal elements of\n\
+ at iftex\n\
+ at tex\n\
+$S$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}\n\
+ at end ifnottex\n\
+(or the eigenvalues of the\n\
+ at iftex\n\
+ at tex\n\
+$2\\times 2$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{2 x 2}\n\
+ at end ifnottex\n\
+blocks, when\n\
+appropriate) are the eigenvalues of\n\
+ at iftex\n\
+ at tex\n\
+$A$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{a}\n\
+ at end ifnottex\n\
+and\n\
+ at iftex\n\
+ at tex\n\
+$S$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}.\n\
+ at end ifnottex\n\
+\n\
+The eigenvalues are optionally ordered along the diagonal according to\n\
+the value of @code{opt}.  @code{opt = \"a\"} indicates that all\n\
+eigenvalues with negative real parts should be moved to the leading\n\
+block of\n\
+ at iftex\n\
+ at tex\n\
+$S$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}\n\
+ at end ifnottex\n\
+(used in @code{are}), @code{opt = \"d\"} indicates that all eigenvalues\n\
+with magnitude less than one should be moved to the leading block of\n\
+ at iftex\n\
+ at tex\n\
+$S$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}\n\
+ at end ifnottex\n\
+(used in @code{dare}), and @code{opt = \"u\"}, the default, indicates that\n\
+no ordering of eigenvalues should occur.  The leading\n\
+ at iftex\n\
+ at tex\n\
+$k$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{k}\n\
+ at end ifnottex\n\
+columns of\n\
+ at iftex\n\
+ at tex\n\
+$U$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{u}\n\
+ at end ifnottex\n\
+always span the\n\
+ at iftex\n\
+ at tex\n\
+$A$-invariant\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{a}-invariant\n\
+ at end ifnottex\n\
+subspace corresponding to the\n\
+ at iftex\n\
+ at tex\n\
+$k$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{k}\n\
+ at end ifnottex\n\
+leading eigenvalues of\n\
+ at iftex\n\
+ at tex\n\
+$S$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{s}.\n\
+ at end ifnottex\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2 || nargout > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  std::string ord;
+
+  if (nargin == 2)
+    {
+      ord = args(1).string_value (); 
+
+      if (error_state)
+	{
+	  error ("schur: expecting string as second argument");
+	  return retval;
+	}
+    }
+
+  char ord_char = ord.empty () ? 'U' : ord[0];
+
+  if (ord_char != 'U' && ord_char != 'A' && ord_char != 'D'
+      && ord_char != 'u' && ord_char != 'a' && ord_char != 'd')
+    {
+      warning ("schur: incorrect ordered schur argument `%c'",
+	       ord.c_str ());
+      return retval;
+    }
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  int arg_is_empty = empty_arg ("schur", nr, nc);
+
+  if (arg_is_empty < 0)
+    return retval;
+  else if (arg_is_empty > 0)
+    return octave_value_list (2, Matrix ());
+
+  if (nr != nc)
+    {
+      gripe_square_matrix_required ("schur");
+      return retval;
+    }
+
+  if (arg.is_single_type ())
+    {
+      if (arg.is_real_type ())
+	{
+	  FloatMatrix tmp = arg.float_matrix_value ();
+
+	  if (! error_state)
+	    {
+	      if (nargout == 0 || nargout == 1)
+		{
+		  FloatSCHUR result (tmp, ord, false);
+		  retval(0) = result.schur_matrix ();
+		}
+	      else
+		{
+		  FloatSCHUR result (tmp, ord, true);
+		  retval(1) = result.schur_matrix ();
+		  retval(0) = result.unitary_matrix ();
+		}
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  FloatComplexMatrix ctmp = arg.float_complex_matrix_value ();
+
+	  if (! error_state)
+	    {
+ 
+	      if (nargout == 0 || nargout == 1)
+		{
+		  FloatComplexSCHUR result (ctmp, ord, false);
+		  retval(0) = result.schur_matrix ();
+		}
+	      else
+		{
+		  FloatComplexSCHUR result (ctmp, ord, true);
+		  retval(1) = result.schur_matrix ();
+		  retval(0) = result.unitary_matrix ();
+		}
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_type ())
+	{
+	  Matrix tmp = arg.matrix_value ();
+
+	  if (! error_state)
+	    {
+	      if (nargout == 0 || nargout == 1)
+		{
+		  SCHUR result (tmp, ord, false);
+		  retval(0) = result.schur_matrix ();
+		}
+	      else
+		{
+		  SCHUR result (tmp, ord, true);
+		  retval(1) = result.schur_matrix ();
+		  retval(0) = result.unitary_matrix ();
+		}
+	    }
+	}
+      else if (arg.is_complex_type ())
+	{
+	  ComplexMatrix ctmp = arg.complex_matrix_value ();
+
+	  if (! error_state)
+	    {
+ 
+	      if (nargout == 0 || nargout == 1)
+		{
+		  ComplexSCHUR result (ctmp, ord, false);
+		  retval(0) = result.schur_matrix ();
+		}
+	      else
+		{
+		  ComplexSCHUR result (ctmp, ord, true);
+		  retval(1) = result.schur_matrix ();
+		  retval(0) = result.unitary_matrix ();
+		}
+	    }
+	}
+      else
+	{
+	  gripe_wrong_type_arg ("schur", arg);
+	}
+    }
+ 
+  return retval; 
+}
+
+/*
+
+%!test
+%! a = [1, 2, 3; 4, 5, 9; 7, 8, 6];
+%! [u, s] = schur (a);
+%! assert(u' * a * u, s, sqrt (eps));
+
+%!test
+%! a = single([1, 2, 3; 4, 5, 9; 7, 8, 6]);
+%! [u, s] = schur (a);
+%! assert(u' * a * u, s, sqrt (eps('single')));
+
+%!test
+%! fail("schur ([1, 2; 3, 4], 2)","warning");
+
+%!error <Invalid call to schur.*> schur ();
+%!error schur ([1, 2, 3; 4, 5, 6]);
+
+ */
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/sparse.cc b/src/DLD-FUNCTIONS/sparse.cc
new file mode 100644
index 0000000..58cf6b4
--- /dev/null
+++ b/src/DLD-FUNCTIONS/sparse.cc
@@ -0,0 +1,374 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+#include <string>
+
+#include "variables.h"
+#include "utils.h"
+#include "pager.h"
+#include "defun-dld.h"
+#include "gripes.h"
+#include "quit.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "ov-bool-sparse.h"
+
+DEFUN_DLD (issparse, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} issparse (@var{expr})\n\
+Return 1 if the value of the expression @var{expr} is a sparse matrix.\n\
+ at end deftypefn") 
+{
+   if (args.length() != 1) 
+     {
+       print_usage ();
+       return octave_value ();
+     }
+   else 
+     return octave_value (args(0).is_sparse_type ());
+}
+
+DEFUN_DLD (sparse, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{s} =} sparse (@var{a})\n\
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})\n\
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})\n\
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, \"unique\")\n\
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{m}, @var{n})\n\
+Create a sparse matrix from the full matrix or row, column, value triplets.\n\
+If @var{a} is a full matrix, convert it to a sparse matrix representation,\n\
+removing all zero values in the process.\n\
+\n\
+Given the integer index vectors @var{i} and @var{j}, a 1-by- at code{nnz} vector\n\
+of real of complex values @var{sv}, overall dimensions @var{m} and @var{n}\n\
+of the sparse matrix.  The argument @code{nzmax} is ignored but accepted for\n\
+compatibility with @sc{matlab}.  If @var{m} or @var{n} are not specified their\n\
+values are derived from the maximum index in the vectors @var{i} and @var{j}\n\
+as given by @code{@var{m} = max (@var{i})}, @code{@var{n} = max (@var{j})}.\n\
+\n\
+ at strong{Note}: if multiple values are specified with the same\n\
+ at var{i}, @var{j} indices, the corresponding values in @var{s} will\n\
+be added.\n\
+\n\
+The following are all equivalent:\n\
+\n\
+ at example\n\
+ at group\n\
+s = sparse (i, j, s, m, n)\n\
+s = sparse (i, j, s, m, n, \"summation\")\n\
+s = sparse (i, j, s, m, n, \"sum\")\n\
+ at end group\n\
+ at end example\n\
+\n\
+Given the option \"unique\". if more than two values are specified for the\n\
+same @var{i}, @var{j} indices, the last specified value will be used.\n\
+\n\
+ at code{sparse(@var{m}, @var{n})} is equivalent to\n\
+ at code{sparse ([], [], [], @var{m}, @var{n}, 0)}\n\
+\n\
+If any of @var{sv}, @var{i} or @var{j} are scalars, they are expanded\n\
+to have a common size.\n\
+ at seealso{full}\n\
+ at end deftypefn")
+{
+   octave_value retval;
+
+   // WARNING: This function should always use constructions like
+   //   retval = new octave_sparse_matrix (sm);
+   // To avoid calling the maybe_mutate function. This is the only
+   // function that should not call maybe_mutate
+
+   int nargin= args.length();
+   if (nargin < 1 || (nargin == 4 && !args(3).is_string ()) || nargin > 6) 
+     {
+       print_usage ();
+       return retval;
+     }
+
+   bool use_complex = false;
+   bool use_bool = false;
+   if (nargin > 2)
+     {
+       use_complex= args(2).is_complex_type();
+       use_bool = args(2).is_bool_type ();
+     }
+   else
+     {
+       use_complex= args(0).is_complex_type();
+       use_bool = args(0).is_bool_type ();
+     }
+
+   if (nargin == 1)
+     {
+       octave_value arg = args (0);
+
+       if (arg.is_sparse_type ())
+	 {
+	   if (use_complex) 
+	     {
+	       SparseComplexMatrix sm = arg.sparse_complex_matrix_value ();
+	       retval = new octave_sparse_complex_matrix (sm);
+	     }
+	   else if (use_bool) 
+	     {
+	       SparseBoolMatrix sm = arg.sparse_bool_matrix_value ();
+	       retval = new octave_sparse_bool_matrix (sm);
+	     }
+	   else
+	     {
+	       SparseMatrix sm = arg.sparse_matrix_value ();
+	       retval = new octave_sparse_matrix (sm);
+	     }
+	 }
+       else if (arg.is_diag_matrix ())
+         {
+           if (arg.is_complex_type ())
+             {
+	       SparseComplexMatrix sm = arg.sparse_complex_matrix_value ();
+	       retval = new octave_sparse_complex_matrix (sm);
+             }
+           else
+             {
+	       SparseMatrix sm = arg.sparse_matrix_value ();
+	       retval = new octave_sparse_matrix (sm);
+             }
+         }
+       else if (arg.is_perm_matrix ())
+         {
+           SparseMatrix sm = arg.sparse_matrix_value ();
+           retval = new octave_sparse_matrix (sm);
+         }
+       else
+	 {
+	   if (use_complex) 
+	     {
+	       SparseComplexMatrix sm (args (0).complex_matrix_value ());
+	       if (error_state) 
+		 return retval;
+	       retval = new octave_sparse_complex_matrix (sm);
+	     } 
+	   else if (use_bool) 
+	     {
+	       SparseBoolMatrix sm (args (0).bool_matrix_value ());
+	       if (error_state) 
+		 return retval;
+	       retval = new octave_sparse_bool_matrix (sm);
+	     } 
+	   else 
+	     {
+	       SparseMatrix sm (args (0).matrix_value ());
+	       if (error_state) 
+		 return retval;
+	       retval = new octave_sparse_matrix (sm);
+	     }
+	 }
+     }
+   else 
+     {
+       octave_idx_type m = 1, n = 1;
+       if (nargin == 2) 
+	 {
+	   if (args(0).numel () == 1 && args(1).numel () == 1)
+	     {
+	       m = args(0).int_value();
+	       n = args(1).int_value();
+	       if (error_state) return retval;
+
+	       if (use_complex) 
+		 retval = new octave_sparse_complex_matrix 
+		   (SparseComplexMatrix (m, n));
+	       else if (use_bool) 
+		 retval = new octave_sparse_bool_matrix 
+		   (SparseBoolMatrix (m, n));
+	       else
+		 retval = new octave_sparse_matrix 
+		   (SparseMatrix (m, n));
+	     }
+	   else
+	     error ("sparse: expecting scalar values");
+	 }
+       else 
+	 {
+	   if (args(0).is_empty () || args (1).is_empty () 
+	       || args(2).is_empty ())
+	     {
+	       if (nargin > 4)
+		 {
+		   m = args(3).int_value();
+		   n = args(4).int_value();
+		 }
+
+	       if (use_bool)
+		 retval = new octave_sparse_bool_matrix 
+		   (SparseBoolMatrix (m, n));
+	       else
+		 retval = new octave_sparse_matrix (SparseMatrix (m, n));
+	     }
+	   else
+	     {
+// 
+//  I use this clumsy construction so that we can use
+//  any orientation of args
+	       ColumnVector ridxA = ColumnVector (args(0).vector_value 
+					      (false, true));
+	       ColumnVector cidxA = ColumnVector (args(1).vector_value 
+						  (false, true));
+	       ColumnVector coefA;
+	       boolNDArray coefAB;
+	       ComplexColumnVector coefAC;
+	       bool assemble_do_sum = true; // this is the default in matlab6
+
+	       if (use_complex) 
+		 {
+		   if (args(2).is_empty ())
+		     coefAC = ComplexColumnVector (0);
+		   else
+		     coefAC = ComplexColumnVector 
+		       (args(2).complex_vector_value (false, true));
+		 }
+	       else if (use_bool)
+		 {
+		   if (args(2).is_empty ())
+		     coefAB = boolNDArray (dim_vector (1, 0));
+		   else
+		     coefAB = args(2).bool_array_value ();
+		   dim_vector AB_dims = coefAB.dims ();
+		   if (AB_dims.length() > 2 || (AB_dims(0) != 1 && 
+						AB_dims(1) != 1))
+		     error ("sparse: vector arguments required");
+		 }
+	       else 
+		 if (args(2).is_empty ())
+		   coefA = ColumnVector (0);
+		 else
+		   coefA = ColumnVector (args(2).vector_value (false, true));
+
+	       if (error_state)
+		 return retval;
+
+	       // Confirm that i,j,s all have the same number of elements
+	       octave_idx_type ns;
+	       if (use_complex) 
+		 ns = coefAC.length();
+	       else if (use_bool) 
+		 ns = coefAB.length();
+	       else 
+		 ns = coefA.length();
+
+	       octave_idx_type ni = ridxA.length();
+	       octave_idx_type nj = cidxA.length();
+	       octave_idx_type nnz = (ni > nj ? ni : nj);
+	       if ((ns != 1 && ns != nnz) ||
+		   (ni != 1 && ni != nnz) ||
+		   (nj != 1 && nj != nnz)) 
+		 {
+		   error ("sparse i, j and s must have the same length");
+		   return retval;
+		 }
+
+	       if (nargin == 3 || nargin == 4) 
+		 {
+		   m = static_cast<octave_idx_type> (ridxA.max());
+		   n = static_cast<octave_idx_type> (cidxA.max());
+
+		   // if args(3) is not string, then ignore the value
+		   // otherwise check for summation or unique
+		   if (nargin == 4 && args(3).is_string())
+		     {
+		       std::string vv= args(3).string_value();
+		       if (error_state) return retval;
+		       
+		       if ( vv == "summation" ||
+			    vv == "sum" ) 
+			 assemble_do_sum = true;
+		       else
+			 if ( vv == "unique" )
+			   assemble_do_sum = false;
+			 else {
+			   error("sparse repeat flag must be 'sum' or 'unique'");
+			   return retval;
+			 }
+		     }
+		 } 
+	       else 
+		 {
+		   m = args(3).int_value();
+		   n = args(4).int_value();
+		   if (error_state) 
+		     return retval;
+
+		   // if args(5) is not string, then ignore the value
+		   // otherwise check for summation or unique
+		   if (nargin >= 6 && args(5).is_string())
+		     {
+		       std::string vv= args(5).string_value();
+		       if (error_state) return retval;
+		       
+		       if ( vv == "summation" ||
+			    vv == "sum" ) 
+			 assemble_do_sum = true;
+		       else
+			 if ( vv == "unique" )
+			   assemble_do_sum = false;
+			 else {
+			   error("sparse repeat flag must be 'sum' or 'unique'");
+			   return retval;
+			 }
+		     }
+		   
+		 }
+
+	       // Convert indexing to zero-indexing used internally
+	       ridxA -= 1.;
+	       cidxA -= 1.;
+
+	       if (use_complex) 
+		 retval = new octave_sparse_complex_matrix 
+		   (SparseComplexMatrix (coefAC, ridxA, cidxA, m, n, 
+					 assemble_do_sum));
+	       else if (use_bool) 
+		 retval = new octave_sparse_bool_matrix 
+		   (SparseBoolMatrix (coefAB, ridxA, cidxA, m, n, 
+				      assemble_do_sum));
+	       else
+		 retval = new octave_sparse_matrix 
+		   (SparseMatrix (coefA, ridxA, cidxA, m, n, 
+				  assemble_do_sum));
+	     }
+	 }
+     }
+
+   return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/spparms.cc b/src/DLD-FUNCTIONS/spparms.cc
new file mode 100644
index 0000000..47c74a5
--- /dev/null
+++ b/src/DLD-FUNCTIONS/spparms.cc
@@ -0,0 +1,171 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "ov.h"
+#include "pager.h"
+#include "error.h"
+#include "gripes.h"
+
+#include "oct-spparms.h"
+
+DEFUN_DLD (spparms, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} { } spparms ()\n\
+ at deftypefnx {Loadable Function} {@var{vals} =} spparms ()\n\
+ at deftypefnx {Loadable Function} {[@var{keys}, @var{vals}] =} spparms ()\n\
+ at deftypefnx {Loadable Function} {@var{val} =} spparms (@var{key})\n\
+ at deftypefnx {Loadable Function} { } spparms (@var{vals})\n\
+ at deftypefnx {Loadable Function} { } spparms ('defaults')\n\
+ at deftypefnx {Loadable Function} { } spparms ('tight')\n\
+ at deftypefnx {Loadable Function} { } spparms (@var{key}, @var{val})\n\
+Sets or displays the parameters used by the sparse solvers and factorization\n\
+functions.  The first four calls above get information about the current\n\
+settings, while the others change the current settings.  The parameters are\n\
+stored as pairs of keys and values, where the values are all floats and the\n\
+keys are one of the following strings:\n\
+\n\
+ at table @code\n\
+ at item spumoni\n\
+Printing level of debugging information of the solvers (default 0)\n\
+ at item ths_rel\n\
+Included for compatibility.  Not used.  (default 1)\n\
+ at item ths_abs\n\
+Included for compatibility.  Not used.  (default 1)\n\
+ at item exact_d\n\
+Included for compatibility.  Not used.  (default 0)\n\
+ at item supernd\n\
+Included for compatibility.  Not used.  (default 3)\n\
+ at item rreduce\n\
+Included for compatibility.  Not used.  (default 3)\n\
+ at item wh_frac\n\
+Included for compatibility.  Not used.  (default 0.5)\n\
+ at item autommd\n\
+Flag whether the LU/QR and the '\\' and '/' operators will automatically\n\
+use the sparsity preserving mmd functions (default 1)\n\
+ at item autoamd\n\
+Flag whether the LU and the '\\' and '/' operators will automatically\n\
+use the sparsity preserving amd functions (default 1)\n\
+ at item piv_tol\n\
+The pivot tolerance of the UMFPACK solvers (default 0.1)\n\
+ at item sym_tol\n\
+The pivot tolerance of the UMFPACK symmetric solvers (default 0.001)\n\
+ at item bandden\n\
+The density of non-zero elements in a banded matrix before it is treated\n\
+by the @sc{lapack} banded solvers (default 0.5)\n\
+ at item umfpack\n\
+Flag whether the UMFPACK or mmd solvers are used for the LU, '\\' and\n\
+'/' operations (default 1)\n\
+ at end table\n\
+\n\
+The value of individual keys can be set with @code{spparms (@var{key},\n\
+ at var{val})}.  The default values can be restored with the special keyword\n\
+'defaults'.  The special keyword 'tight' can be used to set the mmd solvers\n\
+to attempt for a sparser solution at the potential cost of longer running\n\
+time.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      if (nargout == 0)
+	octave_sparse_params::print_info (octave_stdout, "");
+      else if (nargout == 1)
+	retval(0) =  octave_sparse_params::get_vals ();
+      else if (nargout == 2)
+	{
+	  retval (0) = octave_sparse_params::get_keys ();
+	  retval (1) = octave_sparse_params::get_vals ();
+	}
+      else
+	error ("spparms: too many output arguments"); 
+    }
+  else if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	{
+	  std::string str = args(0).string_value ();
+	  int len = str.length ();
+	  for (int i = 0; i < len; i++)
+	    str [i] = tolower (str [i]);
+
+	  if (str == "defaults")
+	    octave_sparse_params::defaults ();
+	  else if (str == "tight")
+	    octave_sparse_params::tight ();
+	  else
+	    {
+	      double val = octave_sparse_params::get_key (str);
+	      if (xisnan (val))
+		error ("spparams: unrecognized key");
+	      else
+		retval (0) = val;
+	    }
+	}
+      else
+	{
+	  NDArray vals = args(0).array_value ();
+
+	  if (error_state)
+	    error ("spparms: input must be a string or a vector");
+	  else if (vals.numel () > OCTAVE_SPARSE_CONTROLS_SIZE)
+	    error ("spparams: too many elements in values vector");
+	  else
+	    octave_sparse_params::set_vals (vals);
+	}
+    }
+  else if (nargin == 2)
+    {
+      if (args(0).is_string ())
+	{
+	  std::string str = args(0).string_value ();
+	  
+	  double val = args(1).double_value ();
+
+	  if (error_state)
+	    error ("spparms: second argument must be a real scalar");
+          else if (str == "umfpack")
+	    warning ("spparms: request to disable umfpack solvers ignored");
+	  else if (!octave_sparse_params::set_key (str, val))
+	    error ("spparms: key not found");
+	}
+      else
+	error ("spparms: first argument must be a string");
+    }
+  else
+    error ("spparms: too many input arguments");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/sqrtm.cc b/src/DLD-FUNCTIONS/sqrtm.cc
new file mode 100644
index 0000000..fb8f100
--- /dev/null
+++ b/src/DLD-FUNCTIONS/sqrtm.cc
@@ -0,0 +1,466 @@
+/*
+
+Copyright (C) 2001, 2003, 2005, 2006, 2007, 2008 Ross Lippert and Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <float.h>
+
+#include "CmplxSCHUR.h"
+#include "fCmplxSCHUR.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "utils.h"
+
+template <class T>
+static inline T
+getmin (T x, T y)
+{
+  return x < y ? x : y;
+}
+
+template <class T>
+static inline T
+getmax (T x, T y)
+{
+  return x > y ? x : y;
+}
+
+static double
+frobnorm (const ComplexMatrix& A)
+{
+  double sum = 0;
+
+  for (octave_idx_type i = 0; i < A.rows (); i++)
+    for (octave_idx_type j = 0; j < A.columns (); j++)
+      sum += real (A(i,j) * conj (A(i,j)));
+
+  return sqrt (sum);
+}
+
+static double
+frobnorm (const Matrix& A)
+{
+  double sum = 0;
+  for (octave_idx_type i = 0; i < A.rows (); i++)
+    for (octave_idx_type j = 0; j < A.columns (); j++)
+      sum += A(i,j) * A(i,j);
+
+  return sqrt (sum);
+}
+
+static float
+frobnorm (const FloatComplexMatrix& A)
+{
+  float sum = 0;
+
+  for (octave_idx_type i = 0; i < A.rows (); i++)
+    for (octave_idx_type j = 0; j < A.columns (); j++)
+      sum += real (A(i,j) * conj (A(i,j)));
+
+  return sqrt (sum);
+}
+
+static float
+frobnorm (const FloatMatrix& A)
+{
+  float sum = 0;
+  for (octave_idx_type i = 0; i < A.rows (); i++)
+    for (octave_idx_type j = 0; j < A.columns (); j++)
+      sum += A(i,j) * A(i,j);
+
+  return sqrt (sum);
+}
+
+static ComplexMatrix
+sqrtm_from_schur (const ComplexMatrix& U, const ComplexMatrix& T)
+{
+  const octave_idx_type n = U.rows ();
+
+  ComplexMatrix R (n, n, 0.0);
+
+  for (octave_idx_type j = 0; j < n; j++)
+    R(j,j) = sqrt (T(j,j));
+
+  const double fudge = sqrt (DBL_MIN);
+
+  for (octave_idx_type p = 0; p < n-1; p++)
+    {
+      for (octave_idx_type i = 0; i < n-(p+1); i++)
+	{
+	  const octave_idx_type j = i + p + 1;
+
+	  Complex s = T(i,j);
+
+	  for (octave_idx_type k = i+1; k < j; k++)
+	    s -= R(i,k) * R(k,j);
+
+	  // dividing
+	  //     R(i,j) = s/(R(i,i)+R(j,j));
+	  // screwing around to not / 0
+
+	  const Complex d = R(i,i) + R(j,j) + fudge;
+	  const Complex conjd = conj (d);
+
+	  R(i,j) =  (s*conjd)/(d*conjd);
+	}
+    }
+
+  return U * R * U.hermitian ();
+}
+
+static FloatComplexMatrix
+sqrtm_from_schur (const FloatComplexMatrix& U, const FloatComplexMatrix& T)
+{
+  const octave_idx_type n = U.rows ();
+
+  FloatComplexMatrix R (n, n, 0.0);
+
+  for (octave_idx_type j = 0; j < n; j++)
+    R(j,j) = sqrt (T(j,j));
+
+  const float fudge = sqrt (FLT_MIN);
+
+  for (octave_idx_type p = 0; p < n-1; p++)
+    {
+      for (octave_idx_type i = 0; i < n-(p+1); i++)
+	{
+	  const octave_idx_type j = i + p + 1;
+
+	  FloatComplex s = T(i,j);
+
+	  for (octave_idx_type k = i+1; k < j; k++)
+	    s -= R(i,k) * R(k,j);
+
+	  // dividing
+	  //     R(i,j) = s/(R(i,i)+R(j,j));
+	  // screwing around to not / 0
+
+	  const FloatComplex d = R(i,i) + R(j,j) + fudge;
+	  const FloatComplex conjd = conj (d);
+
+	  R(i,j) =  (s*conjd)/(d*conjd);
+	}
+    }
+
+  return U * R * U.hermitian ();
+}
+
+DEFUN_DLD (sqrtm, args, nargout,
+ "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{result}, @var{error_estimate}] =} sqrtm (@var{a})\n\
+Compute the matrix square root of the square matrix @var{a}.\n\
+\n\
+Ref: Nicholas J. Higham.  A new sqrtm for @sc{matlab}.  Numerical Analysis\n\
+Report No. 336, Manchester Centre for Computational Mathematics,\n\
+Manchester, England, January 1999.\n\
+ at seealso{expm, logm}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  octave_idx_type n = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  int arg_is_empty = empty_arg ("sqrtm", n, nc);
+
+  if (arg_is_empty < 0)
+    return retval;
+  else if (arg_is_empty > 0)
+    return octave_value (Matrix ());
+
+  if (n != nc)
+    {
+      gripe_square_matrix_required ("sqrtm");
+      return retval;
+    }
+
+  retval(1) = lo_ieee_inf_value ();
+  retval(0) = lo_ieee_nan_value ();
+
+
+  if (arg.is_single_type ())
+    {
+      if (arg.is_real_scalar ())
+	{
+	  float d = arg.float_value ();
+	  if (d > 0.0)
+	    {
+	      retval(0) = sqrt (d);
+	      retval(1) = 0.0;
+	    }
+	  else
+	    {
+	      retval(0) = FloatComplex (0.0, sqrt (d));
+	      retval(1) = 0.0;
+	    }
+	}
+      else if (arg.is_complex_scalar ())
+	{
+	  FloatComplex c = arg.float_complex_value ();
+	  retval(0) = sqrt (c);
+	  retval(1) = 0.0;
+	}
+      else if (arg.is_matrix_type ())
+	{
+	  float err, minT;
+
+	  if (arg.is_real_matrix ())
+	    {
+	      FloatMatrix A = arg.float_matrix_value();
+
+	      if (error_state)
+		return retval;
+
+	      // FIXME -- eventually, FloatComplexSCHUR will accept a
+	      // real matrix arg.
+
+	      FloatComplexMatrix Ac (A);
+
+	      const FloatComplexSCHUR schur (Ac, std::string ());
+
+	      if (error_state)
+		return retval;
+
+	      const FloatComplexMatrix U (schur.unitary_matrix ());
+	      const FloatComplexMatrix T (schur.schur_matrix ());
+	      const FloatComplexMatrix X (sqrtm_from_schur (U, T));
+
+	      // Check for minimal imaginary part
+	      float normX = 0.0;
+	      float imagX = 0.0;
+	      for (octave_idx_type i = 0; i < n; i++)
+		for (octave_idx_type j = 0; j < n; j++)
+		  {
+		    imagX = getmax (imagX, imag (X(i,j)));
+		    normX = getmax (normX, abs (X(i,j)));
+		  }
+
+	      if (imagX < normX * 100 * FLT_EPSILON)
+		retval(0) = real (X);
+	      else
+		retval(0) = X;
+
+	      // Compute error
+	      // FIXME can we estimate the error without doing the
+	      // matrix multiply?
+
+	      err = frobnorm (X*X - FloatComplexMatrix (A)) / frobnorm (A);
+
+	      if (xisnan (err))
+		err = lo_ieee_float_inf_value ();
+
+	      // Find min diagonal
+	      minT = lo_ieee_float_inf_value ();
+	      for (octave_idx_type i=0; i < n; i++)
+		minT = getmin(minT, abs(T(i,i)));
+	    }
+	  else
+	    {
+	      FloatComplexMatrix A = arg.float_complex_matrix_value ();
+
+	      if (error_state)
+		return retval;
+
+	      const FloatComplexSCHUR schur (A, std::string ());
+
+	      if (error_state)
+		return retval;
+
+	      const FloatComplexMatrix U (schur.unitary_matrix ());
+	      const FloatComplexMatrix T (schur.schur_matrix ());
+	      const FloatComplexMatrix X (sqrtm_from_schur (U, T));
+
+	      retval(0) = X;
+
+	      err = frobnorm (X*X - A) / frobnorm (A);
+
+	      if (xisnan (err))
+		err = lo_ieee_float_inf_value ();
+
+	      minT = lo_ieee_float_inf_value ();
+	      for (octave_idx_type i = 0; i < n; i++)
+		minT = getmin (minT, abs (T(i,i)));
+	    }
+
+	  retval(1) = err;
+
+	  if (nargout < 2)
+	    {
+	      if (err > 100*(minT+FLT_EPSILON)*n)
+		{
+		  if (minT == 0.0)
+		    error ("sqrtm: A is singular, sqrt may not exist");
+		  else if (minT <= sqrt (FLT_MIN))
+		    error ("sqrtm: A is nearly singular, failed to find sqrt");
+		  else
+		    error ("sqrtm: failed to find sqrt");
+		}
+	    }
+	}
+    }
+  else
+    {
+      if (arg.is_real_scalar ())
+	{
+	  double d = arg.double_value ();
+	  if (d > 0.0)
+	    {
+	      retval(0) = sqrt (d);
+	      retval(1) = 0.0;
+	    }
+	  else
+	    {
+	      retval(0) = Complex (0.0, sqrt (d));
+	      retval(1) = 0.0;
+	    }
+	}
+      else if (arg.is_complex_scalar ())
+	{
+	  Complex c = arg.complex_value ();
+	  retval(0) = sqrt (c);
+	  retval(1) = 0.0;
+	}
+      else if (arg.is_matrix_type ())
+	{
+	  double err, minT;
+
+	  if (arg.is_real_matrix ())
+	    {
+	      Matrix A = arg.matrix_value();
+
+	      if (error_state)
+		return retval;
+
+	      // FIXME -- eventually, ComplexSCHUR will accept a
+	      // real matrix arg.
+
+	      ComplexMatrix Ac (A);
+
+	      const ComplexSCHUR schur (Ac, std::string ());
+
+	      if (error_state)
+		return retval;
+
+	      const ComplexMatrix U (schur.unitary_matrix ());
+	      const ComplexMatrix T (schur.schur_matrix ());
+	      const ComplexMatrix X (sqrtm_from_schur (U, T));
+
+	      // Check for minimal imaginary part
+	      double normX = 0.0;
+	      double imagX = 0.0;
+	      for (octave_idx_type i = 0; i < n; i++)
+		for (octave_idx_type j = 0; j < n; j++)
+		  {
+		    imagX = getmax (imagX, imag (X(i,j)));
+		    normX = getmax (normX, abs (X(i,j)));
+		  }
+
+	      if (imagX < normX * 100 * DBL_EPSILON)
+		retval(0) = real (X);
+	      else
+		retval(0) = X;
+
+	      // Compute error
+	      // FIXME can we estimate the error without doing the
+	      // matrix multiply?
+
+	      err = frobnorm (X*X - ComplexMatrix (A)) / frobnorm (A);
+
+	      if (xisnan (err))
+		err = lo_ieee_inf_value ();
+
+	      // Find min diagonal
+	      minT = lo_ieee_inf_value ();
+	      for (octave_idx_type i=0; i < n; i++)
+		minT = getmin(minT, abs(T(i,i)));
+	    }
+	  else
+	    {
+	      ComplexMatrix A = arg.complex_matrix_value ();
+
+	      if (error_state)
+		return retval;
+
+	      const ComplexSCHUR schur (A, std::string ());
+
+	      if (error_state)
+		return retval;
+
+	      const ComplexMatrix U (schur.unitary_matrix ());
+	      const ComplexMatrix T (schur.schur_matrix ());
+	      const ComplexMatrix X (sqrtm_from_schur (U, T));
+
+	      retval(0) = X;
+
+	      err = frobnorm (X*X - A) / frobnorm (A);
+
+	      if (xisnan (err))
+		err = lo_ieee_inf_value ();
+
+	      minT = lo_ieee_inf_value ();
+	      for (octave_idx_type i = 0; i < n; i++)
+		minT = getmin (minT, abs (T(i,i)));
+	    }
+
+	  retval(1) = err;
+
+	  if (nargout < 2)
+	    {
+	      if (err > 100*(minT+DBL_EPSILON)*n)
+		{
+		  if (minT == 0.0)
+		    error ("sqrtm: A is singular, sqrt may not exist");
+		  else if (minT <= sqrt (DBL_MIN))
+		    error ("sqrtm: A is nearly singular, failed to find sqrt");
+		  else
+		    error ("sqrtm: failed to find sqrt");
+		}
+	    }
+	}
+      else
+	gripe_wrong_type_arg ("sqrtm", arg);
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/svd.cc b/src/DLD-FUNCTIONS/svd.cc
new file mode 100644
index 0000000..f228c8c
--- /dev/null
+++ b/src/DLD-FUNCTIONS/svd.cc
@@ -0,0 +1,372 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2003, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxSVD.h"
+#include "dbleSVD.h"
+#include "fCmplxSVD.h"
+#include "floatSVD.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "pr-output.h"
+#include "utils.h"
+
+DEFUN_DLD (svd, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{s} =} svd (@var{a})\n\
+ at deftypefnx {Loadable Function} {[@var{u}, @var{s}, @var{v}] =} svd (@var{a})\n\
+ at cindex singular value decomposition\n\
+Compute the singular value decomposition of @var{a}\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+ A = U S V^H\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+A = U*S*V'\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+The function @code{svd} normally returns the vector of singular values.\n\
+If asked for three return values, it computes\n\
+ at iftex\n\
+ at tex\n\
+$U$, $S$, and $V$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+U, S, and V.\n\
+ at end ifnottex\n\
+For example,\n\
+\n\
+ at example\n\
+svd (hilb (3))\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns\n\
+\n\
+ at example\n\
+ at group\n\
+ans =\n\
+\n\
+  1.4083189\n\
+  0.1223271\n\
+  0.0026873\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+and\n\
+\n\
+ at example\n\
+[u, s, v] = svd (hilb (3))\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns\n\
+\n\
+ at example\n\
+ at group\n\
+u =\n\
+\n\
+  -0.82704   0.54745   0.12766\n\
+  -0.45986  -0.52829  -0.71375\n\
+  -0.32330  -0.64901   0.68867\n\
+\n\
+s =\n\
+\n\
+  1.40832  0.00000  0.00000\n\
+  0.00000  0.12233  0.00000\n\
+  0.00000  0.00000  0.00269\n\
+\n\
+v =\n\
+\n\
+  -0.82704   0.54745   0.12766\n\
+  -0.45986  -0.52829  -0.71375\n\
+  -0.32330  -0.64901   0.68867\n\
+ at end group\n\
+ at end example\n\
+\n\
+If given a second argument, @code{svd} returns an economy-sized\n\
+decomposition, eliminating the unnecessary rows or columns of @var{u} or\n\
+ at var{v}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2 || nargout == 2 || nargout > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  bool isfloat = arg.is_single_type ();
+
+  if (nr == 0 || nc == 0)
+    {
+      if (isfloat)
+	{
+	  if (nargout == 3)
+	    {
+	      retval(3) = float_identity_matrix (nr, nr);
+	      retval(2) = FloatMatrix (nr, nc);
+	      retval(1) = float_identity_matrix (nc, nc);
+	    }
+	  else
+	    retval(0) = FloatMatrix (0, 1);
+	}
+      else
+	{
+	  if (nargout == 3)
+	    {
+	      retval(3) = identity_matrix (nr, nr);
+	      retval(2) = Matrix (nr, nc);
+	      retval(1) = identity_matrix (nc, nc);
+	    }
+	  else
+	    retval(0) = Matrix (0, 1);
+	}
+    }
+  else
+    {
+      SVD::type type = ((nargout == 0 || nargout == 1)
+			? SVD::sigma_only
+			: (nargin == 2) ? SVD::economy : SVD::std);
+
+      if (isfloat)
+	{
+	  if (arg.is_real_type ())
+	    {
+	      FloatMatrix tmp = arg.float_matrix_value ();
+
+	      if (! error_state)
+		{
+		  if (tmp.any_element_is_inf_or_nan ())
+		    {
+		      error ("svd: cannot take SVD of matrix containing Inf or NaN values"); 
+		      return retval;
+		    }
+
+		  FloatSVD result (tmp, type);
+
+		  FloatDiagMatrix sigma = result.singular_values ();
+
+		  if (nargout == 0 || nargout == 1)
+		    {
+		      retval(0) = sigma.diag ();
+		    }
+		  else
+		    {
+		      retval(2) = result.right_singular_matrix ();
+		      retval(1) = sigma;
+		      retval(0) = result.left_singular_matrix ();
+		    }
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      FloatComplexMatrix ctmp = arg.float_complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  if (ctmp.any_element_is_inf_or_nan ())
+		    {
+		      error ("svd: cannot take SVD of matrix containing Inf or NaN values"); 
+		      return retval;
+		    }
+
+		  FloatComplexSVD result (ctmp, type);
+
+		  FloatDiagMatrix sigma = result.singular_values ();
+
+		  if (nargout == 0 || nargout == 1)
+		    {
+		      retval(0) = sigma.diag ();
+		    }
+		  else
+		    {
+		      retval(2) = result.right_singular_matrix ();
+		      retval(1) = sigma;
+		      retval(0) = result.left_singular_matrix ();
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  if (arg.is_real_type ())
+	    {
+	      Matrix tmp = arg.matrix_value ();
+
+	      if (! error_state)
+		{
+		  if (tmp.any_element_is_inf_or_nan ())
+		    {
+		      error ("svd: cannot take SVD of matrix containing Inf or NaN values"); 
+		      return retval;
+		    }
+
+		  SVD result (tmp, type);
+
+		  DiagMatrix sigma = result.singular_values ();
+
+		  if (nargout == 0 || nargout == 1)
+		    {
+		      retval(0) = sigma.diag ();
+		    }
+		  else
+		    {
+		      retval(2) = result.right_singular_matrix ();
+		      retval(1) = sigma;
+		      retval(0) = result.left_singular_matrix ();
+		    }
+		}
+	    }
+	  else if (arg.is_complex_type ())
+	    {
+	      ComplexMatrix ctmp = arg.complex_matrix_value ();
+
+	      if (! error_state)
+		{
+		  if (ctmp.any_element_is_inf_or_nan ())
+		    {
+		      error ("svd: cannot take SVD of matrix containing Inf or NaN values"); 
+		      return retval;
+		    }
+
+		  ComplexSVD result (ctmp, type);
+
+		  DiagMatrix sigma = result.singular_values ();
+
+		  if (nargout == 0 || nargout == 1)
+		    {
+		      retval(0) = sigma.diag ();
+		    }
+		  else
+		    {
+		      retval(2) = result.right_singular_matrix ();
+		      retval(1) = sigma;
+		      retval(0) = result.left_singular_matrix ();
+		    }
+		}
+	    }
+	  else
+	    {
+	      gripe_wrong_type_arg ("svd", arg);
+	      return retval;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(svd ([1, 2; 2, 1]), [3; 1], sqrt (eps));
+
+%!test
+%! [u, s, v] = svd ([1, 2; 2, 1]);
+%! x = 1 / sqrt (2);
+%! assert (u, [-x, -x; -x, x], sqrt (eps));
+%! assert (s, [3, 0; 0, 1], sqrt (eps));
+%! assert (v, [-x, x; -x, -x], sqrt (eps));
+
+%!test
+%! a = [1, 2, 3; 4, 5, 6];
+%! [u, s, v] = svd (a);
+%! assert (u * s * v', a, sqrt (eps));
+
+%!test
+%! a = [1, 2; 3, 4; 5, 6];
+%! [u, s, v] = svd (a);
+%! assert (u * s * v', a, sqrt (eps));
+
+%!test
+%! a = [1, 2, 3; 4, 5, 6];
+%! [u, s, v] = svd (a, 1);
+%! assert (u * s * v', a, sqrt (eps));
+
+%!test
+%! a = [1, 2; 3, 4; 5, 6];
+%! [u, s, v] = svd (a, 1);
+%! assert (u * s * v', a, sqrt (eps));
+
+%!assert(svd (single([1, 2; 2, 1])), single([3; 1]), sqrt (eps('single')));
+
+%!test
+%! [u, s, v] = svd (single([1, 2; 2, 1]));
+%! x = single (1 / sqrt (2));
+%! assert (u, [-x, -x; -x, x], sqrt (eps('single')));
+%! assert (s, single([3, 0; 0, 1]), sqrt (eps('single')));
+%! assert (v, [-x, x; -x, -x], sqrt (eps('single')));
+
+%!test
+%! a = single([1, 2, 3; 4, 5, 6]);
+%! [u, s, v] = svd (a);
+%! assert (u * s * v', a, sqrt (eps('single')));
+
+%!test
+%! a = single([1, 2; 3, 4; 5, 6]);
+%! [u, s, v] = svd (a);
+%! assert (u * s * v', a, sqrt (eps('single')));
+
+%!test
+%! a = single([1, 2, 3; 4, 5, 6]);
+%! [u, s, v] = svd (a, 1);
+%! assert (u * s * v', a, sqrt (eps('single')));
+
+%!test
+%! a = single([1, 2; 3, 4; 5, 6]);
+%! [u, s, v] = svd (a, 1);
+%! assert (u * s * v', a, sqrt (eps('single')));
+
+%!error <Invalid call to svd.*> svd ();
+%!error <Invalid call to svd.*> svd ([1, 2; 4, 5], 2, 3);
+%!error <Invalid call to svd.*> [u, v] = svd ([1, 2; 3, 4]);
+
+ */
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/syl.cc b/src/DLD-FUNCTIONS/syl.cc
new file mode 100644
index 0000000..0c9877a
--- /dev/null
+++ b/src/DLD-FUNCTIONS/syl.cc
@@ -0,0 +1,228 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: A. S. Hodel <scotte at eng.auburn.edu>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (syl, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{x} =} syl (@var{a}, @var{b}, @var{c})\n\
+Solve the Sylvester equation\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+ A X + X B + C = 0\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+A X + X B + C = 0\n\
+ at end example\n\
+ at end ifnottex\n\
+using standard @sc{lapack} subroutines.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])\n\
+     @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 3 || nargout > 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg_a = args(0);
+  octave_value arg_b = args(1);
+  octave_value arg_c = args(2);
+
+  octave_idx_type a_nr = arg_a.rows ();
+  octave_idx_type a_nc = arg_a.columns ();
+
+  octave_idx_type b_nr = arg_b.rows ();
+  octave_idx_type b_nc = arg_b.columns ();
+
+  octave_idx_type c_nr = arg_c.rows ();
+  octave_idx_type c_nc = arg_c.columns ();
+
+  int arg_a_is_empty = empty_arg ("syl", a_nr, a_nc);
+  int arg_b_is_empty = empty_arg ("syl", b_nr, b_nc);
+  int arg_c_is_empty = empty_arg ("syl", c_nr, c_nc);
+
+  bool isfloat = arg_a.is_single_type () || arg_b.is_single_type () ||
+    arg_c.is_single_type ();
+
+  if (arg_a_is_empty > 0 && arg_b_is_empty > 0 && arg_c_is_empty > 0)
+    if (isfloat)
+      return octave_value (FloatMatrix ());
+    else
+      return octave_value (Matrix ());
+  else if (arg_a_is_empty || arg_b_is_empty || arg_c_is_empty)
+    return retval;
+
+  // Arguments are not empty, so check for correct dimensions.
+
+  if (a_nr != a_nc || b_nr != b_nc)
+    {
+      gripe_square_matrix_required ("syl: first two parameters:");
+      return retval;
+    }
+  else if (a_nr != c_nr || b_nr != c_nc)
+    {
+      gripe_nonconformant ();
+      return retval;
+    }
+  
+  // Dimensions look o.k., let's solve the problem.
+  if (isfloat)
+    {
+      if (arg_a.is_complex_type ()
+	  || arg_b.is_complex_type ()
+	  || arg_c.is_complex_type ())
+	{
+	  // Do everything in complex arithmetic;
+
+	  FloatComplexMatrix ca = arg_a.float_complex_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  FloatComplexMatrix cb = arg_b.float_complex_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  FloatComplexMatrix cc = arg_c.float_complex_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  retval = Sylvester (ca, cb, cc);
+	}
+      else
+	{
+	  // Do everything in real arithmetic.
+
+	  FloatMatrix ca = arg_a.float_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  FloatMatrix cb = arg_b.float_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  FloatMatrix cc = arg_c.float_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  retval = Sylvester (ca, cb, cc);
+	}
+    }
+  else
+    {
+      if (arg_a.is_complex_type ()
+	  || arg_b.is_complex_type ()
+	  || arg_c.is_complex_type ())
+	{
+	  // Do everything in complex arithmetic;
+
+	  ComplexMatrix ca = arg_a.complex_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  ComplexMatrix cb = arg_b.complex_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  ComplexMatrix cc = arg_c.complex_matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  retval = Sylvester (ca, cb, cc);
+	}
+      else
+	{
+	  // Do everything in real arithmetic.
+
+	  Matrix ca = arg_a.matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  Matrix cb = arg_b.matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  Matrix cc = arg_c.matrix_value ();
+
+	  if (error_state)
+	    return retval;
+
+	  retval = Sylvester (ca, cb, cc);
+	}
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12]), [-1/2, -2/3; -2/3, -1/2], sqrt (eps));
+%!assert(syl (single([1, 2; 3, 4]), single([5, 6; 7, 8]), single([9, 10; 11, 12])), single([-1/2, -2/3; -2/3, -1/2]), sqrt (eps('single')));
+
+%!error <Invalid call to syl.*> syl ();
+%!error <Invalid call to syl.*> syl (1, 2, 3, 4);
+%!error syl ([1, 2; 3, 4], [1, 2, 3; 4, 5, 6], [4, 3]);
+
+ */
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/symbfact.cc b/src/DLD-FUNCTIONS/symbfact.cc
new file mode 100644
index 0000000..826d7c6
--- /dev/null
+++ b/src/DLD-FUNCTIONS/symbfact.cc
@@ -0,0 +1,366 @@
+/*
+
+Copyright (C) 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SparseCmplxCHOL.h"
+#include "SparsedbleCHOL.h"
+#include "oct-spparms.h"
+#include "sparse-util.h"
+#include "oct-locbuf.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (symbfact, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{count}, @var{h}, @var{parent}, @var{post}, @var{r}] =} symbfact (@var{s}, @var{typ}, @var{mode})\n\
+\n\
+Performs a symbolic factorization analysis on the sparse matrix @var{s}.\n\
+Where\n\
+\n\
+ at table @asis\n\
+ at item @var{s}\n\
+ at var{s} is a complex or real sparse matrix.\n\
+\n\
+ at item @var{typ}\n\
+Is the type of the factorization and can be one of\n\
+\n\
+ at table @code\n\
+ at item sym\n\
+Factorize @var{s}.  This is the default.\n\
+\n\
+ at item col\n\
+Factorize @code{@var{s}' * @var{s}}.\n\
+ at item row\n\
+Factorize @code{@var{s} * @var{s}'}.\n\
+ at item lo\n\
+Factorize @code{@var{s}'}\n\
+ at end table\n\
+\n\
+ at item @var{mode}\n\
+The default is to return the Cholesky factorization for @var{r}, and if\n\
+ at var{mode} is 'L', the conjugate transpose of the Cholesky factorization\n\
+is returned.  The conjugate transpose version is faster and uses less\n\
+memory, but returns the same values for @var{count}, @var{h}, @var{parent}\n\
+and @var{post} outputs.\n\
+ at end table\n\
+\n\
+The output variables are\n\
+\n\
+ at table @asis\n\
+ at item @var{count}\n\
+The row counts of the Cholesky factorization as determined by @var{typ}.\n\
+\n\
+ at item @var{h}\n\
+The height of the elimination tree.\n\
+\n\
+ at item @var{parent}\n\
+The elimination tree itself.\n\
+\n\
+ at item @var{post}\n\
+A sparse boolean matrix whose structure is that of the Cholesky\n\
+factorization as determined by @var{typ}.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin < 1  || nargin > 3 || nargout > 5)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#ifdef HAVE_CHOLMOD
+
+  cholmod_common Common;
+  cholmod_common *cm = &Common;
+  CHOLMOD_NAME(start) (cm);
+
+  double spu = octave_sparse_params::get_key ("spumoni");
+  if (spu == 0.)
+    {
+      cm->print = -1;
+      cm->print_function = 0;
+    }
+  else
+    {
+      cm->print = static_cast<int> (spu) + 2;
+      cm->print_function =&SparseCholPrint;
+    }
+
+  cm->error_handler = &SparseCholError;
+  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+  double dummy;
+  cholmod_sparse Astore;
+  cholmod_sparse *A = &Astore;
+  A->packed = true;
+  A->sorted = true;
+  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+  A->itype = CHOLMOD_LONG;
+#else
+  A->itype = CHOLMOD_INT;
+#endif
+  A->dtype = CHOLMOD_DOUBLE;
+  A->stype = 1;
+  A->x = &dummy;
+
+  if (args(0).is_real_type ())
+    {
+      const SparseMatrix a = args(0).sparse_matrix_value();
+      A->nrow = a.rows();
+      A->ncol = a.cols();
+      A->p = a.cidx();
+      A->i = a.ridx();
+      A->nzmax = a.nnz();
+      A->xtype = CHOLMOD_REAL;
+
+      if (a.rows() > 0 && a.cols() > 0)
+	A->x = a.data();
+    }
+  else if (args(0).is_complex_type ())
+    {
+      const SparseComplexMatrix a = args(0).sparse_complex_matrix_value();
+      A->nrow = a.rows();
+      A->ncol = a.cols();
+      A->p = a.cidx();
+      A->i = a.ridx();
+      A->nzmax = a.nnz();
+      A->xtype = CHOLMOD_COMPLEX;
+
+      if (a.rows() > 0 && a.cols() > 0)
+	A->x = a.data();
+    }
+  else
+    gripe_wrong_type_arg ("symbfact", args(0));
+
+  octave_idx_type coletree = false;
+  octave_idx_type n = A->nrow;
+
+  if (nargin > 1)
+    {
+      char ch;
+      std::string str = args(1).string_value();
+      ch = tolower (str.c_str()[0]);
+      if (ch == 'r')
+	A->stype = 0;
+      else if (ch == 'c')
+	{
+	  n = A->ncol;
+	  coletree = true;
+	  A->stype = 0;
+	}
+      else if (ch == 's')
+	A->stype = 1;
+      else if (ch == 's')
+	A->stype = -1;
+      else
+	error ("Unrecognized typ in symbolic factorization");
+    }
+
+  if (A->stype && A->nrow != A->ncol)
+    error ("Matrix must be square");
+
+  if (!error_state)
+    {
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, Parent, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, Post, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, ColCount, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, First, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, Level, n);
+
+      cholmod_sparse *F = CHOLMOD_NAME(transpose) (A, 0, cm);
+      cholmod_sparse *Aup, *Alo;
+
+      if (A->stype == 1 || coletree)
+	{
+	  Aup = A ;
+	  Alo = F ;
+	}
+      else
+	{
+	  Aup = F ;
+	  Alo = A ;
+	}
+
+      CHOLMOD_NAME(etree) (Aup, Parent, cm);
+
+      if (cm->status < CHOLMOD_OK)
+	{
+	  error("matrix corrupted");
+	  goto symbfact_error;
+	}
+
+      if (CHOLMOD_NAME(postorder) (Parent, n, 0, Post, cm) != n)
+	{
+	  error("postorder failed");
+	  goto symbfact_error;
+	}
+
+      CHOLMOD_NAME(rowcolcounts) (Alo, 0, 0, Parent, Post, 0,
+				  ColCount, First, Level, cm);
+
+      if (cm->status < CHOLMOD_OK)
+	{
+	  error("matrix corrupted");
+	  goto symbfact_error;
+	}
+
+      if (nargout > 4)
+	{
+	  cholmod_sparse *A1, *A2;
+
+	  if (A->stype == 1)
+	    {
+	      A1 = A;
+	      A2 = 0;
+	    }
+	  else if (A->stype == -1)
+	    {
+	      A1 = F;
+	      A2 = 0;
+	    }
+	  else if (coletree)
+	    {
+	      A1 = F;
+	      A2 = A;
+	    }
+	  else
+	    {
+	      A1 = A;
+	      A2 = F;
+	    }
+
+	  // count the total number of entries in L
+	  octave_idx_type lnz = 0 ;
+	  for (octave_idx_type j = 0 ; j < n ; j++)
+	    lnz += ColCount [j] ;
+	
+
+	  // allocate the output matrix L (pattern-only)
+	  SparseBoolMatrix L (n, n, lnz);
+
+	  // initialize column pointers
+	  lnz = 0;
+	  for (octave_idx_type j = 0 ; j < n ; j++)
+	    {
+	      L.xcidx(j) = lnz;
+	      lnz += ColCount [j];
+	    }
+	  L.xcidx(n) = lnz;
+
+
+	  /* create a copy of the column pointers */
+	  octave_idx_type *W = First;
+	  for (octave_idx_type j = 0 ; j < n ; j++)
+	    W [j] = L.xcidx(j);
+
+	  // get workspace for computing one row of L
+	  cholmod_sparse *R = cholmod_allocate_sparse (n, 1, n, false, true, 
+						       0, CHOLMOD_PATTERN, cm);
+	  octave_idx_type *Rp = static_cast<octave_idx_type *>(R->p);
+	  octave_idx_type *Ri = static_cast<octave_idx_type *>(R->i);
+
+	  // compute L one row at a time
+	  for (octave_idx_type k = 0 ; k < n ; k++)
+	    {
+	      // get the kth row of L and store in the columns of L
+	      CHOLMOD_NAME (row_subtree) (A1, A2, k, Parent, R, cm) ;
+	      for (octave_idx_type p = 0 ; p < Rp [1] ; p++)
+		L.xridx (W [Ri [p]]++) = k ;
+
+	      // add the diagonal entry
+	      L.xridx (W [k]++) = k ;
+	    }
+
+	  // free workspace
+	  cholmod_free_sparse (&R, cm) ;
+
+
+	  // transpose L to get R, or leave as is
+	  if (nargin < 3)
+	    L = L.transpose ();
+
+	  // fill numerical values of L with one's
+	  for (octave_idx_type p = 0 ; p < lnz ; p++)
+	    L.xdata(p) = true;
+
+	  retval(4) = L;
+	}
+
+      ColumnVector tmp (n);
+      if (nargout > 3)
+	{
+	  for (octave_idx_type i = 0; i < n; i++)
+	    tmp(i) = Post[i] + 1;
+	  retval(3) = tmp;
+	}
+
+      if (nargout > 2)
+	{
+	  for (octave_idx_type i = 0; i < n; i++)
+	    tmp(i) = Parent[i] + 1;
+	  retval(2) = tmp;
+	}
+
+      if (nargout > 1)
+	{
+	  /* compute the elimination tree height */
+	  octave_idx_type height = 0 ;
+	  for (int i = 0 ; i < n ; i++)
+	    height = (height > Level[i] ? height : Level[i]);
+	  height++ ;
+	  retval(1) = static_cast<double> (height);
+	}
+
+      for (octave_idx_type i = 0; i < n; i++)
+	tmp(i) = ColCount[i];
+      retval(0) = tmp;
+    }
+
+ symbfact_error:
+#else
+  error ("symbfact: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/DLD-FUNCTIONS/symrcm.cc b/src/DLD-FUNCTIONS/symrcm.cc
new file mode 100644
index 0000000..96ff8fe
--- /dev/null
+++ b/src/DLD-FUNCTIONS/symrcm.cc
@@ -0,0 +1,710 @@
+/*
+
+Copyright (C) 2007, 2008 Michael Weitzel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+An implementation of the Reverse Cuthill-McKee algorithm (symrcm)
+
+The implementation of this algorithm is based in the descriptions found in
+
+ at INPROCEEDINGS{,
+	author = {E. Cuthill and J. McKee},
+	title = {Reducing the Bandwidth of Sparse Symmetric Matrices},
+	booktitle = {Proceedings of the 24th ACM National Conference},
+	publisher = {Brandon Press},
+	pages = {157 -- 172},
+	location = {New Jersey},
+	year = {1969}
+}
+
+ at BOOK{,
+	author = {Alan George and Joseph W. H. Liu},
+	title = {Computer Solution of Large Sparse Positive Definite Systems},
+	publisher = {Prentice Hall Series in Computational Mathematics},
+	ISBN = {0-13-165274-5},
+	year = {1981}
+}
+
+The algorithm represents a heuristic approach to the NP-complete minimum
+bandwidth problem.
+
+Written by Michael Weitzel <michael.weitzel@@uni-siegen.de>
+                           <weitzel@@ldknet.org>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "utils.h"
+#include "oct-locbuf.h"
+
+#include "ov-re-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "oct-sparse.h"
+
+// A node struct for the Cuthill-McKee algorithm
+struct CMK_Node
+{
+  // the node's id (matrix row index)
+  octave_idx_type id;
+  // the node's degree
+  octave_idx_type deg;
+  // minimal distance to the root of the spanning tree
+  octave_idx_type dist;
+};
+
+// A simple queue.
+// Queues Q have a fixed maximum size N (rows,cols of the matrix) and are
+// stored in an array. qh and qt point to queue head and tail.
+
+// Enqueue operation (adds a node "o" at the tail)
+
+inline static void 
+Q_enq (CMK_Node *Q, octave_idx_type N, octave_idx_type& qt, const CMK_Node& o)
+{	
+  Q[qt] = o;
+  qt = (qt + 1) % (N + 1);
+}
+
+// Dequeue operation (removes a node from the head)
+
+inline static CMK_Node 
+Q_deq (CMK_Node * Q, octave_idx_type N, octave_idx_type& qh)
+{
+  CMK_Node r = Q[qh];
+  qh = (qh + 1) % (N + 1);
+  return r;
+}
+
+// Predicate (queue empty)
+#define Q_empty(Q, N, qh, qt)	((qh) == (qt))
+
+// A simple, array-based binary heap (used as a priority queue for nodes)
+
+// the left descendant of entry i
+#define LEFT(i)		(((i) << 1) + 1)	// = (2*(i)+1)
+// the right descendant of entry i
+#define RIGHT(i)	(((i) << 1) + 2)	// = (2*(i)+2)
+// the parent of entry i
+#define PARENT(i)	(((i) - 1) >> 1)	// = floor(((i)-1)/2)
+
+// Builds a min-heap (the root contains the smallest element). A is an array
+// with the graph's nodes, i is a starting position, size is the length of A.
+
+static void 
+H_heapify_min (CMK_Node *A, octave_idx_type i, octave_idx_type size)
+{
+  octave_idx_type j = i;
+  for (;;)
+    {
+      octave_idx_type l = LEFT(j);
+      octave_idx_type r = RIGHT(j);
+
+      octave_idx_type smallest;
+      if (l < size && A[l].deg < A[j].deg)
+	smallest = l;
+      else
+	smallest = j;
+
+      if (r < size && A[r].deg < A[smallest].deg)
+	smallest = r;
+
+      if (smallest != j)
+	{
+	  CMK_Node tmp = A[j];
+	  A[j] = A[smallest];
+	  A[smallest] = tmp;
+	  j = smallest;
+	}
+      else 
+	break;
+    }
+}
+
+// Heap operation insert. Running time is O(log(n))
+
+static void 
+H_insert (CMK_Node *H, octave_idx_type& h, const CMK_Node& o)
+{
+  octave_idx_type i = h++;
+
+  H[i] = o;
+
+  if (i == 0) 
+    return;
+  do
+    {
+      octave_idx_type p = PARENT(i);
+      if (H[i].deg < H[p].deg)
+	{
+	  CMK_Node tmp = H[i];
+	  H[i] = H[p];
+	  H[p] = tmp;
+
+	  i = p;
+	}
+      else 
+	break;
+    }
+  while (i > 0);
+}
+
+// Heap operation remove-min. Removes the smalles element in O(1) and
+// reorganizes the heap optionally in O(log(n))
+
+inline static CMK_Node 
+H_remove_min (CMK_Node *H, octave_idx_type& h, int reorg/*=1*/)
+{
+  CMK_Node r = H[0];
+  H[0] = H[--h];
+  if (reorg) 
+    H_heapify_min(H, 0, h);
+  return r;
+}
+
+// Predicate (heap empty)
+#define H_empty(H, h)	((h) == 0)
+
+// Helper function for the Cuthill-McKee algorithm. Tries to determine a
+// pseudo-peripheral node of the graph as starting node.
+
+static octave_idx_type 
+find_starting_node (octave_idx_type N, const octave_idx_type *ridx, 
+		    const octave_idx_type *cidx, const octave_idx_type *ridx2, 
+		    const octave_idx_type *cidx2, octave_idx_type *D, 
+		    octave_idx_type start)
+{
+  CMK_Node w;
+
+  OCTAVE_LOCAL_BUFFER (CMK_Node, Q, N+1);
+  boolNDArray btmp (dim_vector (1, N), false);
+  bool *visit = btmp.fortran_vec ();
+
+  octave_idx_type qh = 0;
+  octave_idx_type qt = 0;
+  CMK_Node x;
+  x.id = start;
+  x.deg = D[start];
+  x.dist = 0;
+  Q_enq (Q, N, qt, x);
+  visit[start] = true;
+
+  // distance level
+  octave_idx_type level = 0;
+  // current largest "eccentricity"
+  octave_idx_type max_dist = 0;
+
+  for (;;)
+    {
+      while (! Q_empty (Q, N, qh, qt))
+	{
+	  CMK_Node v = Q_deq (Q, N, qh);
+
+	  if (v.dist > x.dist || (v.id != x.id && v.deg > x.deg))
+	    x = v;
+
+	  octave_idx_type i = v.id;
+
+	  // add all unvisited neighbors to the queue
+	  octave_idx_type j1 = cidx[i];
+	  octave_idx_type j2 = cidx2[i];
+	  while (j1 < cidx[i+1] || j2 < cidx2[i+1])
+	    {
+	      OCTAVE_QUIT;
+
+	      if (j1 == cidx[i+1])
+		{
+		  octave_idx_type r2 = ridx2[j2++];
+		  if (! visit[r2])
+		    {
+		      // the distance of node j is dist(i)+1
+		      w.id = r2;
+		      w.deg = D[r2];
+		      w.dist = v.dist+1;
+		      Q_enq (Q, N, qt, w);
+		      visit[r2] = true;
+
+		      if (w.dist > level)
+			level = w.dist;
+		    }
+		}
+	      else if (j2 == cidx2[i+1])
+		{
+		  octave_idx_type r1 = ridx[j1++];
+		  if (! visit[r1])
+		    {
+		      // the distance of node j is dist(i)+1
+		      w.id = r1;
+		      w.deg = D[r1];
+		      w.dist = v.dist+1;
+		      Q_enq (Q, N, qt, w);
+		      visit[r1] = true;
+
+		      if (w.dist > level)
+			level = w.dist;
+		    }
+		}
+	      else
+		{
+		  octave_idx_type r1 = ridx[j1];
+		  octave_idx_type r2 = ridx2[j2];
+		  if (r1 <= r2)
+		    {
+		      if (! visit[r1])
+			{
+			  w.id = r1;
+			  w.deg = D[r1];
+			  w.dist = v.dist+1;
+			  Q_enq (Q, N, qt, w);
+			  visit[r1] = true;
+
+			  if (w.dist > level)
+			    level = w.dist;
+			}
+		      j1++;
+		      if (r1 == r2)
+			j2++;
+		    }
+		  else
+		    {
+		      if (! visit[r2])
+			{
+			  w.id = r2;
+			  w.deg = D[r2];
+			  w.dist = v.dist+1;
+			  Q_enq (Q, N, qt, w);
+			  visit[r2] = true;
+
+			  if (w.dist > level)
+			    level = w.dist;
+			}
+		      j2++;
+		    }
+		}
+	    }
+	} // finish of BFS
+
+      if (max_dist < x.dist)
+	{
+	  max_dist = x.dist;
+
+	  for (octave_idx_type i = 0; i < N; i++)
+	    visit[i] = false;
+
+	  visit[x.id] = true;
+	  x.dist = 0;
+	  qt = qh = 0;
+	  Q_enq (Q, N, qt, x);
+	}
+      else
+	break;
+    }
+  return x.id;
+}
+
+// Calculates the node's degrees. This means counting the non-zero elements
+// in the symmetric matrix' rows. This works for non-symmetric matrices 
+// as well.
+
+static octave_idx_type 
+calc_degrees (octave_idx_type N, const octave_idx_type *ridx, 
+	      const octave_idx_type *cidx, octave_idx_type *D)
+{
+  octave_idx_type max_deg = 0;
+
+  for (octave_idx_type i = 0; i < N; i++) 
+    D[i] = 0;
+
+  for (octave_idx_type j = 0; j < N; j++)
+    {
+      for (octave_idx_type i = cidx[j]; i < cidx[j+1]; i++)
+	{
+	  OCTAVE_QUIT;
+	  octave_idx_type k = ridx[i];
+	  // there is a non-zero element (k,j)
+	  D[k]++;
+	  if (D[k] > max_deg) 
+	    max_deg = D[k];
+	  // if there is no element (j,k) there is one in
+	  // the symmetric matrix:
+	  if (k != j)
+	    {
+	      bool found = false;
+	      for (octave_idx_type l = cidx[k]; l < cidx[k + 1]; l++)
+		{
+		  OCTAVE_QUIT;
+
+		  if (ridx[l] == j)
+		    {
+		      found = true;
+		      break;
+		    }
+		  else if (ridx[l] > j)
+		    break;
+		}
+
+	      if (! found)
+		{
+		  // A(j,k) == 0
+		  D[j]++;
+		  if (D[j] > max_deg) 
+		    max_deg = D[j];
+		}
+	    }
+	}
+    }
+  return max_deg;
+}
+
+// Transpose of the structure of a square sparse matrix
+
+static void
+transpose (octave_idx_type N, const octave_idx_type *ridx, 
+	   const octave_idx_type *cidx, octave_idx_type *ridx2, 
+	   octave_idx_type *cidx2)
+{
+  octave_idx_type nz = cidx[N];
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, w, N + 1);
+  for (octave_idx_type i = 0; i < N; i++)
+    w[i] = 0;
+  for (octave_idx_type i = 0; i < nz; i++)
+    w[ridx[i]]++;
+  nz = 0;
+  for (octave_idx_type i = 0; i < N; i++)
+    {
+      OCTAVE_QUIT;
+      cidx2[i] = nz;
+      nz += w[i];
+      w[i] = cidx2[i];
+    }
+  cidx2[N] = nz;
+  w[N] = nz;
+
+  for (octave_idx_type j = 0; j < N; j++)
+    for (octave_idx_type k = cidx[j]; k < cidx[j + 1]; k++)
+      {
+	OCTAVE_QUIT;
+	octave_idx_type q = w [ridx[k]]++;
+	ridx2[q] = j;
+      }
+}
+
+// An implementation of the Cuthill-McKee algorithm.
+DEFUN_DLD (symrcm, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{p} =} symrcm (@var{S})\n\
+Symmetric reverse Cuthill-McKee permutation of @var{S}.\n\
+Return a permutation vector @var{p} such that\n\
+ at code{@var{S} (@var{p}, @var{p})} tends to have its diagonal elements\n\
+closer to the diagonal than @var{S}.  This is a good preordering for LU\n\
+or Cholesky factorization of matrices that come from 'long, skinny'\n\
+problems.  It works for both symmetric and asymmetric @var{S}.\n\
+\n\
+The algorithm represents a heuristic approach to the NP-complete\n\
+bandwidth minimization problem.  The implementation is based in the\n\
+descriptions found in\n\
+\n\
+E. Cuthill, J. McKee: Reducing the Bandwidth of Sparse Symmetric\n\
+Matrices. Proceedings of the 24th ACM National Conference, 157--172\n\
+1969, Brandon Press, New Jersey.\n\
+\n\
+Alan George, Joseph W. H. Liu: Computer Solution of Large Sparse\n\
+Positive Definite Systems, Prentice Hall Series in Computational\n\
+Mathematics, ISBN 0-13-165274-5, 1981.\n\
+\n\
+ at seealso{colperm, colamd, symamd}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  // the parameter of the matrix is converted into a sparse matrix 
+  //(if necessary)
+  octave_idx_type *cidx;
+  octave_idx_type *ridx;
+  SparseMatrix Ar;
+  SparseComplexMatrix Ac;
+
+  if (arg.is_real_type ())
+    {
+      Ar = arg.sparse_matrix_value ();
+      // Note cidx/ridx are const, so use xridx and xcidx...
+      cidx = Ar.xcidx ();
+      ridx = Ar.xridx ();
+    }
+  else
+    {
+      Ac = arg.sparse_complex_matrix_value ();
+      cidx = Ac.xcidx ();
+      ridx = Ac.xridx ();
+    }
+
+  if (error_state)
+    return retval;
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  if (nr != nc)
+    {
+      gripe_square_matrix_required ("symrcm");
+      return retval;
+    }
+
+  if (nr == 0 && nc == 0)
+    return octave_value (NDArray (dim_vector (1, 0)));
+
+  // sizes of the heaps
+  octave_idx_type s = 0;
+
+  // head- and tail-indices for the queue
+  octave_idx_type qt = 0, qh = 0;
+  CMK_Node v, w;
+  // dimension of the matrix
+  octave_idx_type N = nr;
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, cidx2, N + 1);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, ridx2, cidx[N]);
+  transpose (N, ridx, cidx, ridx2, cidx2);
+
+  // the permutation vector
+  NDArray P (dim_vector (1, N));
+
+  // compute the node degrees
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, D, N);
+  octave_idx_type max_deg = calc_degrees (N, ridx, cidx, D);
+
+  // if none of the nodes has a degree > 0 (a matrix of zeros)
+  // the return value corresponds to the identity permutation
+  if (max_deg == 0)
+    {
+      for (octave_idx_type i = 0; i < N; i++) 
+	P(i) = i;
+      return octave_value (P);
+    }
+
+  // a heap for the a node's neighbors. The number of neighbors is
+  // limited by the maximum degree max_deg:
+  OCTAVE_LOCAL_BUFFER (CMK_Node, S, max_deg);
+
+  // a queue for the BFS. The array is always one element larger than
+  // the number of entries that are stored.
+  OCTAVE_LOCAL_BUFFER (CMK_Node, Q, N+1);
+
+  // a counter (for building the permutation)
+  octave_idx_type c = -1;
+
+  // upper bound for the bandwidth (=quality of solution)
+  // initialize the bandwidth of the graph with 0. B contains the
+  // the maximum of the theoretical lower limits of the subgraphs
+  // bandwidths.
+  octave_idx_type B = 0;
+
+  // mark all nodes as unvisited; with the exception of the nodes
+  // that have degree==0 and build a CC of the graph.
+	
+  boolNDArray btmp (dim_vector (1, N), false);
+  bool *visit = btmp.fortran_vec ();
+
+  do
+    {
+      // locate an unvisited starting node of the graph
+      octave_idx_type i;
+      for (i = 0; i < N; i++)
+	if (! visit[i]) 
+	  break;
+
+      // locate a probably better starting node
+      v.id = find_starting_node (N, ridx, cidx, ridx2, cidx2, D, i);
+		
+      // mark the node as visited and enqueue it (a starting node
+      // for the BFS). Since the node will be a root of a spanning
+      // tree, its dist is 0.
+      v.deg = D[v.id];
+      v.dist = 0;
+      visit[v.id] = true;
+      Q_enq (Q, N, qt, v);
+
+      // lower bound for the bandwidth of a subgraph
+      // keep a "level" in the spanning tree (= min. distance to the
+      // root) for determining the bandwidth of the computed
+      // permutation P
+      octave_idx_type Bsub = 0;
+      // min. dist. to the root is 0
+      octave_idx_type level = 0;
+      // the root is the first/only node on level 0
+      octave_idx_type level_N = 1;
+	
+      while (! Q_empty (Q, N, qh, qt))
+	{
+	  v = Q_deq (Q, N, qh);
+	  i = v.id;
+
+	  c++;
+
+	  // for computing the inverse permutation P where
+	  // A(inv(P),inv(P)) or P'*A*P is banded
+	  //	     P(i) = c;
+			
+	  // for computing permutation P where
+	  // A(P(i),P(j)) or P*A*P' is banded
+	  P(c) = i;
+
+	  // put all unvisited neighbors j of node i on the heap
+	  s = 0;
+	  octave_idx_type j1 = cidx[i];
+	  octave_idx_type j2 = cidx2[i];
+
+	  OCTAVE_QUIT;
+	  while (j1 < cidx[i+1] || j2 < cidx2[i+1])
+	    {
+	      OCTAVE_QUIT;
+	      if (j1 == cidx[i+1])
+		{
+		  octave_idx_type r2 = ridx2[j2++];
+		  if (! visit[r2])
+		    {
+		      // the distance of node j is dist(i)+1
+		      w.id = r2;
+		      w.deg = D[r2];
+		      w.dist = v.dist+1;
+		      H_insert(S, s, w);
+		      visit[r2] = true;
+		    }
+		}
+	      else if (j2 == cidx2[i+1])
+		{
+		  octave_idx_type r1 = ridx[j1++];
+		  if (! visit[r1])
+		    {
+		      w.id = r1;
+		      w.deg = D[r1];
+		      w.dist = v.dist+1;
+		      H_insert(S, s, w);
+		      visit[r1] = true;
+		    }
+		}
+	      else
+		{
+		  octave_idx_type r1 = ridx[j1];
+		  octave_idx_type r2 = ridx2[j2];
+		  if (r1 <= r2)
+		    {
+		      if (! visit[r1])
+			{
+			  w.id = r1;
+			  w.deg = D[r1];
+			  w.dist = v.dist+1;
+			  H_insert(S, s, w);
+			  visit[r1] = true;
+			}
+		      j1++;
+		      if (r1 == r2)
+			j2++;
+		    }
+		  else
+		    {
+		      if (! visit[r2])
+			{
+			  w.id = r2;
+			  w.deg = D[r2];
+			  w.dist = v.dist+1;
+			  H_insert(S, s, w);
+			  visit[r2] = true;
+			}
+		      j2++;
+		    }
+		}
+	    }
+
+	  // add the neighbors to the queue (sorted by node degree)
+	  while (! H_empty (S, s))
+	    {
+	      OCTAVE_QUIT;
+
+	      // locate a neighbor of i with minimal degree in O(log(N))
+	      v = H_remove_min(S, s, 1);
+	
+	      // entered the BFS a new level?
+	      if (v.dist > level)
+		{
+		  // adjustment of bandwith:
+		  // "[...] the minimum bandwidth that
+		  // can be obtained [...] is the
+		  //  maximum number of nodes per level"
+		  if (Bsub < level_N)
+		    Bsub = level_N;
+	
+		  level = v.dist;
+		  // v is the first node on the new level
+		  level_N = 1;
+		}
+	      else
+		{
+		  // there is no new level but another node on
+		  // this level:
+		  level_N++;
+		}
+	
+	      // enqueue v in O(1)
+	      Q_enq (Q, N, qt, v);
+	    }
+	
+	  // synchronize the bandwidth with level_N once again:
+	  if (Bsub < level_N)
+	    Bsub = level_N;
+	}
+      // finish of BFS. If there are still unvisited nodes in the graph
+      // then it is split into CCs. The computed bandwidth is the maximum
+      // of all subgraphs. Update:
+      if (Bsub > B)
+	B = Bsub;
+    }
+  // are there any nodes left?
+  while (c+1 < N);
+
+  // compute the reverse-ordering
+  s = N / 2 - 1;
+  for (octave_idx_type i = 0, j = N - 1; i <= s; i++, j--)
+    {
+      double tmp = P.elem(i);
+      P.elem(i) = P.elem(j);
+      P.elem(j) = tmp;
+    }
+
+  // increment all indices, since Octave is not C
+  return octave_value (P+1);
+}
diff --git a/src/DLD-FUNCTIONS/time.cc b/src/DLD-FUNCTIONS/time.cc
new file mode 100644
index 0000000..7981075
--- /dev/null
+++ b/src/DLD-FUNCTIONS/time.cc
@@ -0,0 +1,527 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-map.h"
+#include "oct-time.h"
+#include "ov.h"
+#include "oct-obj.h"
+
+// Date and time functions.
+
+static Octave_map
+mk_tm_map (const octave_base_tm& t)
+{
+  Octave_map m;
+
+  m.assign ("usec", static_cast<double> (t.usec ()));
+  m.assign ("sec", static_cast<double> (t.sec ()));
+  m.assign ("min", static_cast<double> (t.min ()));
+  m.assign ("hour", static_cast<double> (t.hour ()));
+  m.assign ("mday", static_cast<double> (t.mday ()));
+  m.assign ("mon", static_cast<double> (t.mon ()));
+  m.assign ("year", static_cast<double> (t.year ()));
+  m.assign ("wday", static_cast<double> (t.wday ()));
+  m.assign ("yday", static_cast<double> (t.yday ()));
+  m.assign ("isdst", static_cast<double> (t.isdst ()));
+  m.assign ("zone", t.zone ());
+
+  return m;
+}
+
+static octave_base_tm
+extract_tm (Octave_map &m)
+{
+  octave_base_tm tm;
+
+  tm.usec (m.intfield ("usec"));
+  tm.sec (m.intfield ("sec"));
+  tm.min (m.intfield ("min"));
+  tm.hour (m.intfield ("hour"));
+  tm.mday (m.intfield ("mday"));
+  tm.mon (m.intfield ("mon"));
+  tm.year (m.intfield ("year"));
+  tm.wday (m.intfield ("wday"));
+  tm.yday (m.intfield ("yday"));
+  tm.isdst (m.intfield ("isdst"));
+  tm.zone (m.stringfield ("zone"));
+
+  return tm;
+}
+
+DEFUN_DLD (time, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} time ()\n\
+Return the current time as the number of seconds since the epoch.  The\n\
+epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan\n\
+1970.  For example, on Monday February 17, 1997 at 07:15:06 CUT, the\n\
+value returned by @code{time} was 856163706.\n\
+ at seealso{strftime, strptime, localtime, gmtime, mktime, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = octave_time ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(time () > 0);
+
+*/
+
+DEFUN_DLD (gmtime, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} gmtime (@var{t})\n\
+Given a value returned from time (or any non-negative integer),\n\
+return a time structure corresponding to CUT.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+gmtime (time ())\n\
+     @result{} @{\n\
+           usec = 0\n\
+           year = 97\n\
+           mon = 1\n\
+           mday = 17\n\
+           sec = 6\n\
+           zone = CST\n\
+           min = 15\n\
+           wday = 1\n\
+           hour = 7\n\
+           isdst = 0\n\
+           yday = 47\n\
+         @}\n\
+ at end group\n\
+ at end example\n\
+ at seealso{strftime, strptime, localtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      double tmp = args(0).double_value ();
+
+      if (! error_state)
+	retval = octave_value (mk_tm_map (octave_gmtime (tmp)));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! ts = gmtime (time ());
+%! assert((isstruct (ts)
+%! && struct_contains (ts, "usec")
+%! && struct_contains (ts, "year")
+%! && struct_contains (ts, "mon")
+%! && struct_contains (ts, "mday")
+%! && struct_contains (ts, "sec")
+%! && struct_contains (ts, "min")
+%! && struct_contains (ts, "wday")
+%! && struct_contains (ts, "hour")
+%! && struct_contains (ts, "isdst")
+%! && struct_contains (ts, "yday")));
+
+%!error <Invalid call to gmtime.*> gmtime ();
+
+%!error <Invalid call to gmtime.*> gmtime (1, 2);
+
+*/
+
+DEFUN_DLD (localtime, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} localtime (@var{t})\n\
+Given a value returned from time (or any non-negative integer),\n\
+return a time structure corresponding to the local time zone.\n\
+\n\
+ at example\n\
+ at group\n\
+localtime (time ())\n\
+     @result{} @{\n\
+           usec = 0\n\
+           year = 97\n\
+           mon = 1\n\
+           mday = 17\n\
+           sec = 6\n\
+           zone = CST\n\
+           min = 15\n\
+           wday = 1\n\
+           hour = 1\n\
+           isdst = 0\n\
+           yday = 47\n\
+         @}\n\
+ at end group\n\
+ at end example\n\
+ at seealso{strftime, strptime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      double tmp = args(0).double_value ();
+
+      if (! error_state)
+	retval = octave_value (mk_tm_map (octave_localtime (tmp)));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! ts = localtime (time ());
+%! assert((isstruct (ts)
+%! && struct_contains (ts, "usec")
+%! && struct_contains (ts, "year")
+%! && struct_contains (ts, "mon")
+%! && struct_contains (ts, "mday")
+%! && struct_contains (ts, "sec")
+%! && struct_contains (ts, "min")
+%! && struct_contains (ts, "wday")
+%! && struct_contains (ts, "hour")
+%! && struct_contains (ts, "isdst")
+%! && struct_contains (ts, "yday")));
+
+%!error <Invalid call to localtime.*> localtime ();
+
+%!error <Invalid call to localtime.*> localtime (1, 2);
+
+*/
+
+DEFUN_DLD (mktime, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} mktime (@var{tm_struct})\n\
+Convert a time structure corresponding to the local time to the number\n\
+of seconds since the epoch.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+mktime (localtime (time ()))\n\
+     @result{} 856163706\n\
+ at end group\n\
+ at end example\n\
+ at seealso{strftime, strptime, localtime, gmtime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      Octave_map map = args(0).map_value ();
+
+      if (! error_state)
+	{
+	  octave_base_tm tm = extract_tm (map);
+
+	  if (! error_state)
+	    retval = octave_time (tm);
+	  else
+	    error ("mktime: invalid TMSTRUCT argument");
+	}
+      else
+	error ("mktime: expecting structure argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! t = time ();
+%! assert(fix (mktime (localtime (t))) == fix (t));
+
+%!error <Invalid call to mktime.*> mktime ();
+
+%!error <Invalid call to mktime.*> mktime (1, 2, 3);
+
+*/
+
+DEFUN_DLD (strftime, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} strftime (@var{fmt}, @var{tm_struct})\n\
+Format the time structure @var{tm_struct} in a flexible way using the\n\
+format string @var{fmt} that contains @samp{%} substitutions\n\
+similar to those in @code{printf}.  Except where noted, substituted\n\
+fields have a fixed size; numeric fields are padded if necessary.\n\
+Padding is with zeros by default; for fields that display a single\n\
+number, padding can be changed or inhibited by following the @samp{%}\n\
+with one of the modifiers described below.  Unknown field specifiers are\n\
+copied as normal characters.  All other characters are copied to the\n\
+output without change.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+strftime (\"%r (%Z) %A %e %B %Y\", localtime (time ()))\n\
+     @result{} \"01:15:06 AM (CST) Monday 17 February 1997\"\n\
+ at end group\n\
+ at end example\n\
+\n\
+Octave's @code{strftime} function supports a superset of the ANSI C\n\
+field specifiers.\n\
+\n\
+ at noindent\n\
+Literal character fields:\n\
+\n\
+ at table @code\n\
+ at item %\n\
+% character.\n\
+\n\
+ at item n\n\
+Newline character.\n\
+\n\
+ at item t\n\
+Tab character.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+Numeric modifiers (a nonstandard extension):\n\
+\n\
+ at table @code\n\
+ at item - (dash)\n\
+Do not pad the field.\n\
+\n\
+ at item _ (underscore)\n\
+Pad the field with spaces.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+Time fields:\n\
+\n\
+ at table @code\n\
+ at item %H\n\
+Hour (00-23).\n\
+\n\
+ at item %I\n\
+Hour (01-12).\n\
+\n\
+ at item %k\n\
+Hour (0-23).\n\
+\n\
+ at item %l\n\
+Hour (1-12).\n\
+\n\
+ at item %M\n\
+Minute (00-59).\n\
+\n\
+ at item %p\n\
+Locale's AM or PM.\n\
+\n\
+ at item %r\n\
+Time, 12-hour (hh:mm:ss [AP]M).\n\
+\n\
+ at item %R\n\
+Time, 24-hour (hh:mm).\n\
+\n\
+ at item %s\n\
+Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).\n\
+\n\
+ at item %S\n\
+Second (00-61).\n\
+\n\
+ at item %T\n\
+Time, 24-hour (hh:mm:ss).\n\
+\n\
+ at item %X\n\
+Locale's time representation (%H:%M:%S).\n\
+\n\
+ at item %Z\n\
+Time zone (EDT), or nothing if no time zone is determinable.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+Date fields:\n\
+\n\
+ at table @code\n\
+ at item %a\n\
+Locale's abbreviated weekday name (Sun-Sat).\n\
+\n\
+ at item %A\n\
+Locale's full weekday name, variable length (Sunday-Saturday).\n\
+\n\
+ at item %b\n\
+Locale's abbreviated month name (Jan-Dec).\n\
+\n\
+ at item %B\n\
+Locale's full month name, variable length (January-December).\n\
+\n\
+ at item %c\n\
+Locale's date and time (Sat Nov 04 12:02:33 EST 1989).\n\
+\n\
+ at item %C\n\
+Century (00-99).\n\
+\n\
+ at item %d\n\
+Day of month (01-31).\n\
+\n\
+ at item %e\n\
+Day of month ( 1-31).\n\
+\n\
+ at item %D\n\
+Date (mm/dd/yy).\n\
+\n\
+ at item %h\n\
+Same as %b.\n\
+\n\
+ at item %j\n\
+Day of year (001-366).\n\
+\n\
+ at item %m\n\
+Month (01-12).\n\
+\n\
+ at item %U\n\
+Week number of year with Sunday as first day of week (00-53).\n\
+\n\
+ at item %w\n\
+Day of week (0-6).\n\
+\n\
+ at item %W\n\
+Week number of year with Monday as first day of week (00-53).\n\
+\n\
+ at item %x\n\
+Locale's date representation (mm/dd/yy).\n\
+\n\
+ at item %y\n\
+Last two digits of year (00-99).\n\
+\n\
+ at item %Y\n\
+Year (1970-).\n\
+ at end table\n\
+ at seealso{strptime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      std::string fmt = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  Octave_map map = args(1).map_value ();
+
+	  if (! error_state)
+	    {
+	      octave_base_tm tm = extract_tm (map);
+
+	      if (! error_state)
+		retval = tm.strftime (fmt);
+	      else
+		error ("strftime: invalid TMSTRUCT argument");
+	    }
+	  else
+	    error ("strftime: expecting structure as second argument");
+	}
+      else
+	error ("strftime: expecting format string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert((ischar (strftime ("%%%n%t%H%I%k%l", localtime (time ())))
+%! && ischar (strftime ("%M%p%r%R%s%S%T", localtime (time ())))
+%! && ischar (strftime ("%X%Z%z%a%A%b%B", localtime (time ())))
+%! && ischar (strftime ("%c%C%d%e%D%h%j", localtime (time ())))
+%! && ischar (strftime ("%m%U%w%W%x%y%Y", localtime (time ())))));
+
+%!error <Invalid call to strftime.*> strftime ();
+
+%!error <Invalid call to strftime.*> strftime ("foo", localtime (time ()), 1);
+
+*/
+
+DEFUN_DLD (strptime, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{tm_struct}, @var{nchars}] =} strptime (@var{str}, @var{fmt})\n\
+Convert the string @var{str} to the time structure @var{tm_struct} under\n\
+the control of the format string @var{fmt}.\n\
+\n\
+If @var{fmt} fails to match, @var{nchars} is 0; otherwise it is set to the\n\
+position of last matched character plus 1. Always check for this unless\n\
+you're absolutely sure the date string will be parsed correctly.\n\
+ at seealso{strftime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 2)
+    {
+      std::string str = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string fmt = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      octave_strptime t (str, fmt);
+
+	      retval(1) = t.characters_converted ();
+	      retval(0) = octave_value (mk_tm_map (t));
+	    }
+	  else
+	    error ("strptime: expecting format string as second argument");
+	}
+      else
+	error ("strptime: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/DLD-FUNCTIONS/tsearch.cc b/src/DLD-FUNCTIONS/tsearch.cc
new file mode 100644
index 0000000..b3e1e7c
--- /dev/null
+++ b/src/DLD-FUNCTIONS/tsearch.cc
@@ -0,0 +1,178 @@
+/*
+
+Copyright (C) 2002, 2007, 2009 Andreas Stahel
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Andreas Stahel <Andreas.Stahel at hta-bi.bfh.ch>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "oct.h"
+#include "parse.h"
+#include "lo-ieee.h"
+#include "lo-math.h"
+
+inline double max(double a, double b, double c)
+{
+  if (a < b) 
+    return ( b < c ? c : b );
+  else 
+    return ( a < c ? c : a );
+}
+
+inline double min(double a, double b, double c)
+{
+  if (a > b) 
+    return ( b > c ? c : b );
+  else 
+    return ( a > c ? c : a );
+}
+
+#define REF(x,k,i) x(static_cast<octave_idx_type>(elem((k), (i))) - 1)
+
+// for large data set the algorithm is very slow
+// one should presort (how?) either the elements of the points of evaluation
+// to cut down the time needed to decide which triangle contains the 
+// given point 
+
+// e.g., build up a neighbouring triangle structure and use a simplex-like
+// method to traverse it
+
+DEFUN_DLD (tsearch, args, ,
+	"-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})\n\
+Searches for the enclosing Delaunay convex hull.  For @code{@var{t} =\n\
+delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the\n\
+points @code{(@var{xi}, @var{yi})}.  For points outside the convex hull,\n\
+ at var{idx} is NaN.\n\
+ at seealso{delaunay, delaunayn}\n\
+ at end deftypefn")
+{
+  const double eps=1.0e-12;
+
+  octave_value_list retval;
+  const int nargin = args.length ();
+  if ( nargin != 5 ) {
+    print_usage ();
+    return retval;
+  }
+  
+  const ColumnVector x(args(0).vector_value());
+  const ColumnVector y(args(1).vector_value());
+  const Matrix elem(args(2).matrix_value());
+  const ColumnVector xi(args(3).vector_value());
+  const ColumnVector yi(args(4).vector_value());
+
+  if (error_state) return retval;
+
+  const octave_idx_type nelem = elem.rows();
+
+  ColumnVector minx(nelem);
+  ColumnVector maxx(nelem);
+  ColumnVector miny(nelem);
+  ColumnVector maxy(nelem);
+  for(octave_idx_type k = 0; k < nelem; k++) 
+    {
+      minx(k) = min(REF(x,k,0), REF(x,k,1), REF(x,k,2)) - eps;
+      maxx(k) = max(REF(x,k,0), REF(x,k,1), REF(x,k,2)) + eps;
+      miny(k) = min(REF(y,k,0), REF(y,k,1), REF(y,k,2)) - eps;
+      maxy(k) = max(REF(y,k,0), REF(y,k,1), REF(y,k,2)) + eps;
+    }
+
+  const octave_idx_type np = xi.length();
+  ColumnVector values(np);
+
+  double x0 = 0.0, y0 = 0.0;
+  double a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, det = 0.0;
+
+  octave_idx_type k = nelem; // k is a counter of elements
+  for(octave_idx_type kp = 0; kp < np; kp++) 
+    {
+      const double xt = xi(kp); 
+      const double yt = yi(kp);
+    
+      // check if last triangle contains the next point
+      if (k < nelem) 
+	{ 
+	  const double dx1 = xt - x0;
+	  const double dx2 = yt - y0;
+	  const double c1 = (a22 * dx1 - a21 * dx2) / det;
+	  const double c2 = (-a12 * dx1 + a11 * dx2) / det;
+	  if ( c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps)) 
+	    {
+	      values(kp) = double(k+1);
+	      continue;
+	    }
+	}
+    
+      // it doesn't, so go through all elements
+      for (k = 0; k < nelem; k++) 
+	{ 
+	  OCTAVE_QUIT;
+	  if (xt >= minx(k) && xt <= maxx(k) && 
+	      yt >= miny(k) && yt <= maxy(k) )
+	    {
+	      // element inside the minimum rectangle: examine it closely
+	      x0  = REF(x,k,0);
+	      y0  = REF(y,k,0);
+	      a11 = REF(x,k,1)-x0;
+	      a12 = REF(y,k,1)-y0;
+	      a21 = REF(x,k,2)-x0;
+	      a22 = REF(y,k,2)-y0;
+	      det = a11 * a22 - a21 * a12;
+	
+	      // solve the system
+	      const double dx1 = xt - x0;
+	      const double dx2 = yt - y0;
+	      const double c1 = (a22 * dx1 - a21 * dx2) / det;
+	      const double c2 = (-a12 * dx1 + a11 * dx2) / det;
+	      if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps))) 
+		{
+		  values(kp) = double(k+1);
+		  break;
+		}
+	    } //endif # examine this element closely
+	} //endfor # each element
+
+      if (k == nelem) 
+	values(kp) = lo_ieee_nan_value ();
+    
+    } //endfor # kp
+  
+  retval(0) = values;
+  
+  return retval;
+}
+
+/*
+%!shared x, y, tri
+%! x = [-1;-1;1];
+%! y = [-1;1;-1];
+%! tri = [1, 2, 3];
+%!error (tsearch())
+%!assert (tsearch (x,y,tri,-1,-1), 1)
+%!assert (tsearch (x,y,tri, 1,-1), 1)
+%!assert (tsearch (x,y,tri,-1, 1), 1)
+%!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
+%!assert (tsearch (x,y,tri, 1, 1), NaN)
+
+*/
diff --git a/src/DLD-FUNCTIONS/typecast.cc b/src/DLD-FUNCTIONS/typecast.cc
new file mode 100644
index 0000000..76f0a39
--- /dev/null
+++ b/src/DLD-FUNCTIONS/typecast.cc
@@ -0,0 +1,217 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+#include <string>
+
+#include "oct.h"
+
+template <class LT, class RT>
+/* static */ void
+typecast (const Array<RT>& x, Array<LT>& y)
+{
+  octave_idx_type n = x.length ();
+  size_t ns = sizeof (RT);
+  size_t ms = sizeof (LT);
+
+  if (n * ns % ms != 0)
+    error ("typecast: incorrect number of input values to make output value");
+  else
+    {
+      octave_idx_type m = n * ns / ms;
+      dim_vector dv = x.dims ();
+      for (octave_idx_type i = 0; i < dv.length(); i++)
+	if (dv(i) == n)
+	  {
+	    dv(i) = m;
+	    break;
+	  }
+      y.resize (dv);
+      const unsigned char *xp
+	= reinterpret_cast<const unsigned char *> (x.fortran_vec ());
+      unsigned char *yp = reinterpret_cast<unsigned char *>(y.fortran_vec ());
+      for (octave_idx_type i = 0; 
+	   i < n * static_cast<octave_idx_type>(ns); i++)
+	*yp++ = *xp++;
+    }
+}
+
+template <class T>
+static octave_value
+typecast (const T& x, std::string type)
+{
+  octave_value retval;
+  if (type == "uint8")
+    {
+      uint8NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "uint16")
+    {
+      uint16NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "uint32")
+    {
+      uint32NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "uint64")
+    {
+      uint64NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "int8")
+    {
+      int8NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "int16")
+    {
+      int16NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "int32")
+    {
+      int32NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "int64")
+    {
+      int64NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else if (type == "single")
+    {
+      FloatNDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+  else
+    {
+      NDArray y;
+      typecast (x, y);
+      retval = octave_value (y);
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (typecast, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} typecast (@var{x}, @var{type})\n\
+Convert from one datatype to another without changing the underlying\n\
+data.  The argument @var{type} defines the type of the return argument\n\
+and must be one of 'uint8', 'uint16', 'uint32', 'uint64', 'int8', 'int16',\n\
+'int32', 'int64', 'single' or 'double'.\n\
+\n\
+An example of the use of typecast on a little-endian machine is\n\
+\n\
+ at example\n\
+ at group\n\
+ at var{x} = uint16 ([1, 65535]);\n\
+typecast (@var{x}, 'uint8')\n\
+ at result{} [   0,   1, 255, 255]\n\
+ at end group\n\
+ at end example\n\
+ at seealso{cast, swapbytes}\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin != 2)
+    print_usage ();
+  else
+    {
+      std::string type = args (1).string_value ();
+
+      if (! error_state)
+	{
+	  std::transform (type.begin (), type.end (), type.begin (), tolower);
+
+	  if (type != "uint8" && type != "uint16"
+		   && type != "uint32" && type != "uint64"
+		   && type != "int8" && type != "int16"
+		   && type != "int32" && type != "int64"
+		   && type != "single" && type != "double")
+	    error ("typecast: unrecognized or invalid type");
+	  else if (args(0).is_sparse_type () || args(0).is_complex_type ())
+	    error ("typecast: sparse and complex types are invalid");
+	  else
+	    {
+	      dim_vector dv = args(0).dims ();
+	      bool seen = false;
+
+	      for (octave_idx_type i = 0; i < dv.length(); i++)
+		if (dv (i) != 1)
+		  {
+		    if (seen)
+		      {
+			error ("typecast: argument must be a vector");
+			break;
+		      }
+		    else
+		      seen = true;
+		  }
+
+	      if (!error_state)
+		{
+		  if (args(0).is_uint8_type ())
+		    retval = typecast (args(0).uint8_array_value (), type); 
+		  else if (args(0).is_uint16_type ())
+		    retval = typecast (args(0).uint16_array_value (), type); 
+		  else if (args(0).is_uint32_type ())
+		    retval = typecast (args(0).uint32_array_value (), type); 
+		  else if (args(0).is_uint64_type ())
+		    retval = typecast (args(0).uint64_array_value (), type); 
+		  else if (args(0).is_int8_type ())
+		    retval = typecast (args(0).int8_array_value (), type); 
+		  else if (args(0).is_int16_type ())
+		    retval = typecast (args(0).int16_array_value (), type); 
+		  else if (args(0).is_int32_type ())
+		    retval = typecast (args(0).int32_array_value (), type); 
+		  else if (args(0).is_int64_type ())
+		    retval = typecast (args(0).int64_array_value (), type); 
+		  else if (args(0).is_single_type ())
+		    retval = typecast (args(0).float_array_value (), type);
+		  else
+		    retval = typecast (args(0).array_value (), type);
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
diff --git a/src/DLD-FUNCTIONS/urlwrite.cc b/src/DLD-FUNCTIONS/urlwrite.cc
new file mode 100644
index 0000000..4f9aeac
--- /dev/null
+++ b/src/DLD-FUNCTIONS/urlwrite.cc
@@ -0,0 +1,484 @@
+// urlwrite and urlread, a curl front-end for octave
+/*
+
+Copyright (C) 2006, 2007, 2008 Alexander Barth
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Alexander Barth <abarth at marine.usf.edu>
+// Adapted-By: jwe
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <fstream>
+#include <iomanip>
+
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "unwind-prot.h"
+
+#if defined (HAVE_CURL)
+
+#include <curl/curl.h>
+#include <curl/types.h>
+#include <curl/easy.h>
+
+// Write callback function for curl.
+
+static int
+write_data (void *buffer, size_t size, size_t nmemb, void *streamp)
+{
+  // *stream is actually an ostream object.
+  std::ostream& stream = *(static_cast<std::ostream*> (streamp));
+  stream.write (static_cast<const char*> (buffer), size*nmemb);
+  return (stream.fail () ? 0 : size * nmemb);
+}
+
+// Form the query string based on param.
+
+static std::string
+form_query_string (CURL *curl, const Cell& param)
+{
+  std::ostringstream query;
+
+  for (int i = 0; i < param.numel (); i += 2)
+    {
+      std::string name = param(i).string_value ();
+      std::string text = param(i+1).string_value ();
+
+      // Encode strings.
+      char *enc_name = curl_easy_escape (curl, name.c_str (), name.length ());
+      char *enc_text = curl_easy_escape (curl, text.c_str (), text.length ());
+
+      query << enc_name << "=" << enc_text;
+
+      curl_free (enc_name);
+      curl_free (enc_text);
+
+      if (i < param.numel()-1)
+	query << "&";
+    }
+
+  query.flush ();
+
+  return query.str ();
+}
+
+// curl front-end
+
+static void
+urlget_cleanup (CURL *curl)
+{
+  curl_easy_cleanup (curl);
+  curl_global_cleanup ();
+}
+
+static CURLcode
+urlget (const std::string& url, const std::string& method,
+	const Cell& param, std::ostream& stream)
+{
+  CURL *curl;
+
+  curl_global_init(CURL_GLOBAL_DEFAULT);
+
+  curl = curl_easy_init();
+
+  if (! curl)
+    return CURLE_FAILED_INIT;
+
+  // handle paramters of GET or POST request
+
+  std::string query_string = form_query_string (curl,param);
+  //octave_stdout << "query_string " << query_string << std::endl;
+
+  if (method == "get")
+    {
+      query_string = url + "?" + query_string;
+      curl_easy_setopt (curl, CURLOPT_URL, query_string.c_str ());
+    }
+  else if (method == "post")
+    {
+      curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
+      curl_easy_setopt (curl, CURLOPT_POSTFIELDS, query_string.c_str ());
+    }
+  else
+    curl_easy_setopt (curl, CURLOPT_URL, url.c_str());
+
+  // Define our callback to get called when there's data to be written.
+  curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
+
+  // Set a pointer to our struct to pass to the callback.
+  curl_easy_setopt (curl, CURLOPT_WRITEDATA, static_cast<void*> (&stream));
+
+  // Follow redirects.
+  curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, true);
+
+  // Don't use EPSV since connecting to sites that don't support it
+  // will hang for some time (3 minutes?) before moving on to try PASV
+  // instead.
+  curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, false);
+
+  curl_easy_setopt (curl, CURLOPT_NOPROGRESS, true);
+  curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, url.c_str ());
+  curl_easy_setopt (curl, CURLOPT_FAILONERROR, true);
+
+  // Switch on full protocol/debug output.
+  // curl_easy_setopt (curl, CURLOPT_VERBOSE, true);
+
+  CURLcode res = CURLE_OK;
+
+  // To understand the following, see the definitions of these macros
+  // in libcruft/misc/quit.h.  The idea is that we call sigsetjmp here
+  // then the signal handler calls siglongjmp to get back here
+  // immediately.  Then we perform some cleanup and throw an interrupt
+  // exception which will get us back to the top level, cleaning up
+  // any local C++ objects on the stack as we go.
+
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1;
+
+  // We were interrupted (this code is inside a block that is only
+  // called when siglongjmp is called from a signal handler).
+
+  // Is there a better error code to use?  Maybe it doesn't matter
+  // because we are about to throw an execption.
+
+  res = CURLE_ABORTED_BY_CALLBACK;
+  urlget_cleanup (curl);
+  octave_rethrow_exception ();
+
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2;
+
+  res = curl_easy_perform (curl);
+
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  // If we are not interuppted, we will end up here, so we still need
+  // to clean up.
+
+  urlget_cleanup (curl);
+
+  return res;
+}
+
+#endif
+
+static bool urlwrite_delete_file;
+
+static std::string urlwrite_filename;
+
+static void
+urlwrite_cleanup_file (void *)
+{
+  if (urlwrite_delete_file)
+    file_ops::unlink (urlwrite_filename);
+}
+
+DEFUN_DLD (urlwrite, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} urlwrite (@var{URL}, @var{localfile})\n\
+ at deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})\n\
+ at deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})\n\
+ at deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})\n\
+Download a remote file specified by its @var{URL} and save it as\n\
+ at var{localfile}.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+urlwrite (\"ftp://ftp.octave.org/pub/octave/README\", \n\
+          \"README.txt\");\n\
+ at end group\n\
+ at end example\n\
+\n\
+The full path of the downloaded file is returned in @var{f}.  The\n\
+variable @var{success} is 1 if the download was successful,\n\
+otherwise it is 0 in which case @var{message} contains an error\n\
+message.  If no output argument is specified and if an error occurs,\n\
+then the error is signaled through Octave's error handling mechanism.\n\
+\n\
+This function uses libcurl.  Curl supports, among others, the HTTP,\n\
+FTP and FILE protocols.  Username and password may be specified in\n\
+the URL, for example:\n\
+\n\
+ at example\n\
+ at group\n\
+urlwrite (\"http://username:password@@example.com/file.txt\",\n\
+          \"file.txt\");\n\
+ at end group\n\
+ at end example\n\
+\n\
+GET and POST requests can be specified by @var{method} and @var{param}.\n\
+The parameter @var{method} is either @samp{get} or @samp{post}\n\
+and @var{param} is a cell array of parameter and value pairs.\n\
+For example:\n\
+\n\
+ at example\n\
+ at group\n\
+urlwrite (\"http://www.google.com/search\", \"search.html\",\n\
+          \"get\", @{\"query\", \"octave\"@});\n\
+ at end group\n\
+ at end example\n\
+ at seealso{urlread}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+#if defined (HAVE_CURL)
+
+  int nargin = args.length ();
+
+  // verify arguments
+  if (nargin != 2 && nargin != 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string url = args(0).string_value();
+
+  if (error_state)
+    {
+      error ("urlwrite: url must be a character string");
+      return retval;
+    }
+
+  // name to store the file if download is succesful
+  std::string filename = args(1).string_value();
+
+  urlwrite_filename = filename;
+
+  if (error_state)
+    {
+      error ("urlwrite: localfile must be a character string");
+      return retval;
+    }
+
+  std::string method;
+  Cell param; // empty cell array
+
+  if (nargin == 4)
+    {
+      method = args(2).string_value();
+
+      if (error_state)
+        {
+          error ("urlwrite: method can only be \"get\" or \"post\"");
+          return retval;
+        }
+
+      if (method != "get" && method != "post")
+	{
+	  error ("urlwrite: method can only be \"get\" or \"post\"");
+	  return retval;
+	}
+
+      param = args(3).cell_value();
+
+      if (error_state)
+	{
+	  error ("urlwrite: parameters for get and post requests must be given as a cell");
+	  return retval;
+	}
+
+
+      if (param.numel () % 2 == 1 )
+	{
+	  error ("urlwrite: number of elements in param must be even");
+	  return retval;
+	}
+    }
+
+  // The file should only be deleted if it doesn't initially exist, we
+  // create it, and the download fails.  We use unwind_protect to do
+  // it so that the deletion happens no matter how we exit the function.
+
+  file_stat fs (filename);
+
+  urlwrite_delete_file = ! fs.exists ();
+
+  std::ofstream ofile (filename.c_str(), std::ios::out | std::ios::binary);
+
+  if (! ofile.is_open ())
+    {
+      error ("urlwrite: unable to open file");
+      return retval;
+    }
+
+  unwind_protect::add (urlwrite_cleanup_file);
+
+  CURLcode res = urlget (url, method, param, ofile);
+
+  ofile.close ();
+
+  urlwrite_delete_file = (res != CURLE_OK);
+
+  unwind_protect::run ();
+
+  if (nargout > 0)
+    {
+      if (res == CURLE_OK)
+	{
+	  retval(2) = std::string ();
+	  retval(1) = true;
+	  retval(0) = octave_env::make_absolute (filename, octave_env::getcwd ());
+	}
+      else
+	{
+	  retval(2) = std::string (curl_easy_strerror (res));
+	  retval(1) = false;
+	  retval(0) = std::string ();
+	}
+    }
+
+  if (nargout < 2 && res != CURLE_OK)
+    error ("urlwrite: curl: %s", curl_easy_strerror (res));
+
+#else
+  error ("urlwrite: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (urlread, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{s} =} urlread (@var{url})\n\
+ at deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})\n\
+ at deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})\n\
+ at deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})\n\
+Download a remote file specified by its @var{URL} and return its content\n\
+in string @var{s}.  For example,\n\
+\n\
+ at example\n\
+s = urlread (\"ftp://ftp.octave.org/pub/octave/README\");\n\
+ at end example\n\
+\n\
+The variable @var{success} is 1 if the download was successful,\n\
+otherwise it is 0 in which case @var{message} contains an error\n\
+message.  If no output argument is specified and if an error occurs,\n\
+then the error is signaled through Octave's error handling mechanism.\n\
+\n\
+This function uses libcurl.  Curl supports, among others, the HTTP,\n\
+FTP and FILE protocols.  Username and password may be specified in the\n\
+URL.  For example,\n\
+\n\
+ at example\n\
+s = urlread (\"http://user:password@@example.com/file.txt\");\n\
+ at end example\n\
+\n\
+GET and POST requests can be specified by @var{method} and @var{param}.\n\
+The parameter @var{method} is either @samp{get} or @samp{post}\n\
+and @var{param} is a cell array of parameter and value pairs.\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+s = urlread (\"http://www.google.com/search\", \"get\",\n\
+             @{\"query\", \"octave\"@});\n\
+ at end group\n\
+ at end example\n\
+ at seealso{urlwrite}\n\
+ at end deftypefn")
+{
+  // Octave's return value
+  octave_value_list retval;
+
+#if defined (HAVE_CURL)
+
+  int nargin = args.length ();
+
+  // verify arguments
+  if (nargin != 1  && nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string url = args(0).string_value();
+
+  if (error_state)
+    {
+      error ("urlread: url must be a character string");
+      return retval;
+    }
+
+  std::string method;
+  Cell param; // empty cell array
+
+  if (nargin == 3)
+    {
+      method = args(1).string_value();
+
+      if (error_state)
+	{
+	  error ("urlread: method can only be \"get\" or \"post\"");
+	  return retval;
+	}
+
+      if (method != "get" && method != "post")
+	{
+	  error ("urlread: method can only be \"get\" or \"post\"");
+	  return retval;
+	}
+
+      param = args(2).cell_value();
+
+      if (error_state)
+	{
+	  error ("urlread: parameters for get and post requests must be given as a cell");
+	  return retval;
+	}
+
+      if (param.numel () % 2 == 1 )
+	{
+	  error ("urlread: number of elements in param must be even");
+	  return retval;
+	}
+    }
+
+  std::ostringstream buf;
+
+  CURLcode res = urlget (url, method, param, buf);
+
+  if (nargout > 0)
+    {
+      retval(0) = buf.str ();
+      retval(1) = res == CURLE_OK;
+      // Return empty string if no error occured.
+      retval(2) = std::string (res == CURLE_OK ? "" : curl_easy_strerror (res));
+    }
+
+  if (nargout < 2 && res != CURLE_OK)
+    error ("urlread: curl: %s", curl_easy_strerror (res));
+
+#else
+  error ("urlread: not available in this version of Octave");
+#endif
+
+  return retval;
+}
diff --git a/src/DOCSTRINGS b/src/DOCSTRINGS
new file mode 100644
index 0000000..8b52872
--- /dev/null
+++ b/src/DOCSTRINGS
@@ -0,0 +1,11889 @@
+### DO NOT EDIT!
+###
+### This file is generated automatically from the Octave sources.
+### Edit those files instead and run make to update this file.
+
+__contourc__
+ at c ./DLD-FUNCTIONS/__contourc__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} __contourc__ (@var{x}, @var{y}, @var{z}, @var{levels})
+Undocumented internal function.
+ at end deftypefn
+__convn__
+ at c ./DLD-FUNCTIONS/__convn__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} __convn__(@var{a}, @var{b})
+Undocumented internal function.
+ at end deftypefn
+
+__delaunayn__
+ at c ./DLD-FUNCTIONS/__delaunayn__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{T} =} __delaunayn__ (@var{P}[, @var{opt}])
+Undocumented internal function.
+ at end deftypefn
+__dsearchn__
+ at c ./DLD-FUNCTIONS/__dsearchn__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{idx}, @var{d}] =} dsearch (@var{x}, @var{xi})
+Undocumented internal function.
+ at end deftypefn
+__glpk__
+ at c ./DLD-FUNCTIONS/__glpk__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})
+Undocumented internal function.
+ at end deftypefn
+__lin_interpn__
+ at c ./DLD-FUNCTIONS/__lin_interpn__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{vi} =} __lin_interpn__ (@var{x1}, @var{x2}, @dots{}, @var{xn}, @var{v}, @var{y1}, @var{y2}, @dots{}, @var{yn})
+Undocumented internal function.
+ at end deftypefn
+__magick_read__
+ at c ./DLD-FUNCTIONS/__magick_read__.cc
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{m} =} __magick_read__(@var{fname}, @var{index})
+ at deftypefnx{Function File} {[@var{m}, @var{colormap}] =} __magick_read__(@var{fname}, @var{index})
+ at deftypefnx{Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __magick_read__(@var{fname}, @var{index})
+Read images with ImageMagick++.  In general you should not be using this function.
+Instead you should use @code{imread}.
+ at seealso{imread}
+ at end deftypefn
+__magick_write__
+ at c ./DLD-FUNCTIONS/__magick_read__.cc
+-*- texinfo -*-
+ at deftypefn {Function File} {} __magick_write__(@var{fname}, @var{fmt}, @var{img})
+ at deftypefnx {Function File} {} __magick_write__(@var{fname}, @var{fmt}, @var{img}, @var{map})
+Write images with ImageMagick++.  In general you should not be using this function.
+Instead you should use @code{imwrite}.
+ at seealso{imread}
+ at end deftypefn
+__magick_finfo__
+ at c ./DLD-FUNCTIONS/__magick_read__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable File} {} __magick_finfo__(@var{fname})
+Read image information with GraphicsMagick++.  In general you should
+not be using this function.  Instead you should use @code{imfinfo}.
+ at seealso{imfinfo, imread}
+ at end deftypefn
+__pchip_deriv__
+ at c ./DLD-FUNCTIONS/__pchip_deriv__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} __pchip_deriv__ (@var{x}, @var{y}, @var{dim})
+Undocumented internal function.
+ at end deftypefn
+__qp__
+ at c ./DLD-FUNCTIONS/__qp__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{x}, @var{lambda}, @var{info}, @var{iter}] =} __qp__ (@var{x0}, @var{H}, @var{q}, @var{Aeq}, @var{beq}, @var{Ain}, @var{bin}, @var{maxit})
+Undocumented internal function.
+ at end deftypefn
+__voronoi__
+ at c ./DLD-FUNCTIONS/__voronoi__.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{tri} =} __voronoi__ (@var{point})
+ at deftypefnx {Loadable Function} {@var{tri} =} __voronoi__ (@var{point}, @var{options})
+Undocumented internal function.
+ at end deftypefn
+amd
+ at c ./DLD-FUNCTIONS/amd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} amd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} amd (@var{s}, @var{opts})
+
+Returns the approximate minimum degree permutation of a matrix.  This
+permutation such that the Cholesky factorization of @code{@var{s} (@var{p},
+ at var{p})} tends to be sparser than the Cholesky factorization of @var{s}
+itself.  @code{amd} is typically faster than @code{symamd} but serves a
+similar purpose.
+
+The optional parameter @var{opts} is a structure that controls the
+behavior of @code{amd}.  The fields of these structure are
+
+ at table @asis
+ at item opts.dense
+Determines what @code{amd} considers to be a dense row or column of the
+input matrix.  Rows or columns with more than @code{max(16, (dense *
+sqrt (@var{n})} entries, where @var{n} is the order of the matrix @var{s},
+are ignored by @code{amd} during the calculation of the permutation
+The value of dense must be a positive scalar and its default value is 10.0
+
+ at item opts.aggressive
+If this value is a non zero scalar, then @code{amd} performs aggressive
+absorption.  The default is not to perform aggressive absorption.
+ at end table
+
+The author of the code itself is Timothy A. Davis (davis@@cise.ufl.edu),
+University of Florida (see @url{http://www.cise.ufl.edu/research/sparse/amd}).
+ at seealso{symamd, colamd}
+ at end deftypefn
+balance
+ at c ./DLD-FUNCTIONS/balance.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{aa} =} balance (@var{a}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{dd}, @var{aa}] =} balance (@var{a}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{d}, @var{p}, @var{aa}] =} balance (@var{a}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{cc}, @var{dd}, @var{aa}, @var{bb}] =} balance (@var{a}, @var{b}, @var{opt})
+
+Compute @code{aa = dd \ a * dd} in which @code{aa} is a matrix whose
+row and column norms are roughly equal in magnitude, and
+ at code{dd} = @code{p * d}, in which @code{p} is a permutation
+matrix and @code{d} is a diagonal matrix of powers of two.  This allows
+the equilibration to be computed without roundoff.  Results of
+eigenvalue calculation are typically improved by balancing first.
+
+If two output values are requested, @code{balance} returns 
+the diagonal @code{d} and the permutation @code{p} separately as vectors.  
+In this case, @code{dd = eye(n)(:,p) * diag (d)}, where @code{n} is the matrix 
+size.  
+
+If four output values are requested, compute @code{aa = cc*a*dd} and
+ at code{bb = cc*b*dd)}, in which @code{aa} and @code{bb} have non-zero
+elements of approximately the same magnitude and @code{cc} and @code{dd}
+are permuted diagonal matrices as in @code{dd} for the algebraic
+eigenvalue problem.
+
+The eigenvalue balancing option @code{opt} may be one of:
+
+ at table @asis
+ at item @code{"noperm"}, @code{"S"}
+Scale only; do not permute.
+
+ at item @code{"noscal"}, @code{"P"}
+Permute only; do not scale.
+ at end table
+
+Algebraic eigenvalue balancing uses standard @sc{lapack} routines.
+
+Generalized eigenvalue problem balancing uses Ward's algorithm
+(SIAM Journal on Scientific and Statistical Computing, 1981).
+ at end deftypefn
+besselj
+ at c ./DLD-FUNCTIONS/besselj.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{j}, @var{ierr}] =} besselj (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})
+Compute Bessel or Hankel functions of various kinds:
+
+ at table @code
+ at item besselj
+Bessel functions of the first kind.  If the argument @var{opt} is supplied, 
+the result is multiplied by @code{exp(-abs(imag(x)))}.
+ at item bessely
+Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(-abs(imag(x)))}.
+ at item besseli
+Modified Bessel functions of the first kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(-abs(real(x)))}.
+ at item besselk
+Modified Bessel functions of the second kind.  If the argument @var{opt} is supplied,
+the result is multiplied by @code{exp(x)}.
+ at item besselh
+Compute Hankel functions of the first (@var{k} = 1) or second (@var{k}
+= 2) kind.  If the argument @var{opt} is supplied, the result is multiplied by
+ at code{exp (-I*@var{x})} for @var{k} = 1 or @code{exp (I*@var{x})} for
+ at var{k} = 2.
+ at end table
+
+If @var{alpha} is a scalar, the result is the same size as @var{x}.
+If @var{x} is a scalar, the result is the same size as @var{alpha}.
+If @var{alpha} is a row vector and @var{x} is a column vector, the
+result is a matrix with @code{length (@var{x})} rows and
+ at code{length (@var{alpha})} columns.  Otherwise, @var{alpha} and
+ at var{x} must conform and the result will be the same size.
+
+The value of @var{alpha} must be real.  The value of @var{x} may be
+complex.
+
+If requested, @var{ierr} contains the following status information
+and is the same size as the result.
+
+ at enumerate 0
+ at item
+Normal return.
+ at item
+Input error, return @code{NaN}.
+ at item
+Overflow, return @code{Inf}.
+ at item
+Loss of significance by argument reduction results in less than
+half of machine accuracy.
+ at item
+Complete loss of significance by argument reduction, return @code{NaN}.
+ at item
+Error---no computation, algorithm termination condition not met,
+return @code{NaN}.
+ at end enumerate
+ at end deftypefn
+bessely
+ at c ./DLD-FUNCTIONS/besselj.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{y}, @var{ierr}] =} bessely (@var{alpha}, @var{x}, @var{opt})
+See besselj.
+ at end deftypefn
+besseli
+ at c ./DLD-FUNCTIONS/besselj.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{i}, @var{ierr}] =} besseli (@var{alpha}, @var{x}, @var{opt})
+See besselj.
+ at end deftypefn
+besselk
+ at c ./DLD-FUNCTIONS/besselj.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{k}, @var{ierr}] =} besselk (@var{alpha}, @var{x}, @var{opt})
+See besselj.
+ at end deftypefn
+besselh
+ at c ./DLD-FUNCTIONS/besselj.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{h}, @var{ierr}] =} besselh (@var{alpha}, @var{k}, @var{x}, @var{opt})
+See besselj.
+ at end deftypefn
+airy
+ at c ./DLD-FUNCTIONS/besselj.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{a}, @var{ierr}] =} airy (@var{k}, @var{z}, @var{opt})
+Compute Airy functions of the first and second kind, and their
+derivatives.
+
+ at example
+ at group
+ K   Function   Scale factor (if 'opt' is supplied)
+---  --------   ---------------------------------------
+ 0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))
+ 1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))
+ 2   Bi (Z)     exp (-abs (real ((2/3) * Z *sqrt (Z))))
+ 3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z *sqrt (Z))))
+ at end group
+ at end example
+
+The function call @code{airy (@var{z})} is equivalent to
+ at code{airy (0, @var{z})}.
+
+The result is the same size as @var{z}.
+
+If requested, @var{ierr} contains the following status information and
+is the same size as the result.
+
+ at enumerate 0
+ at item
+Normal return.
+ at item
+Input error, return @code{NaN}.
+ at item
+Overflow, return @code{Inf}.
+ at item
+Loss of significance by argument reduction results in less than half
+ of machine accuracy.
+ at item
+Complete loss of significance by argument reduction, return @code{NaN}.
+ at item
+Error---no computation, algorithm termination condition not met,
+return @code{NaN}.
+ at end enumerate
+ at end deftypefn
+betainc
+ at c ./DLD-FUNCTIONS/betainc.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} betainc (@var{x}, @var{a}, @var{b})
+Return the incomplete Beta function,
+ at iftex
+ at tex
+$$
+ \beta (x, a, b) = B (a, b)^{-1} \int_0^x t^{(a-z)} (1-t)^{(b-1)} dt.
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+                                      x
+                                     /
+betainc (x, a, b) = beta (a, b)^(-1) | t^(a-1) (1-t)^(b-1) dt.
+                                     /
+                                  t=0
+ at end smallexample
+ at end ifnottex
+
+If x has more than one component, both @var{a} and @var{b} must be
+scalars.  If @var{x} is a scalar, @var{a} and @var{b} must be of
+compatible dimensions.
+ at end deftypefn
+bitand
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})
+Return the bitwise AND of non-negative integers.
+ at var{x}, @var{y} must be in the range [0,bitmax]
+ at seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}
+ at end deftypefn
+bitor
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})
+Return the bitwise OR of non-negative integers.
+ at var{x}, @var{y} must be in the range [0,bitmax]
+ at seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}
+ at end deftypefn
+bitxor
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})
+Return the bitwise XOR of non-negative integers.
+ at var{x}, @var{y} must be in the range [0,bitmax]
+ at seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}
+ at end deftypefn
+bitshift
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})
+ at deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})
+Return a @var{k} bit shift of @var{n}-digit unsigned
+integers in @var{a}.  A positive @var{k} leads to a left shift.
+A negative value to a right shift.  If @var{n} is omitted it defaults
+to log2(bitmax)+1.
+ at var{n} must be in the range [1,log2(bitmax)+1] usually [1,33]
+
+ at example
+ at group
+bitshift (eye (3), 1)
+ at result{}
+ at group
+2 0 0
+0 2 0
+0 0 2
+ at end group
+
+bitshift (10, [-2, -1, 0, 1, 2])
+ at result{} 2   5  10  20  40
+ at c FIXME -- restore this example when third arg is allowed to be an array.
+ at c 
+ at c 
+ at c bitshift ([1, 10], 2, [3,4])
+ at c @result{} 4  8
+ at end group
+ at end example
+ at seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax}
+ at end deftypefn
+bitmax
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} bitmax ()
+Return the largest integer that can be represented as a floating point
+value.  On IEEE-754 compatible systems, @code{bitmax} is @code{2^53 - 1}.
+ at end deftypefn
+intmax
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} intmax (@var{type})
+Return the largest integer that can be represented in an integer type.
+The variable @var{type} can be
+
+ at table @code
+ at item int8
+signed 8-bit integer.
+ at item int16
+signed 16-bit integer.
+ at item int32
+signed 32-bit integer.
+ at item int64
+signed 64-bit integer.
+ at item uint8
+unsigned 8-bit integer.
+ at item uint16
+unsigned 16-bit integer.
+ at item uint32
+unsigned 32-bit integer.
+ at item uint64
+unsigned 64-bit integer.
+ at end table
+
+The default for @var{type} is @code{uint32}.
+ at seealso{intmin, bitmax}
+ at end deftypefn
+intmin
+ at c bitfcns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} intmin (@var{type})
+Return the smallest integer that can be represented in an integer type.
+The variable @var{type} can be
+
+ at table @code
+ at item int8
+signed 8-bit integer.
+ at item int16
+signed 16-bit integer.
+ at item int32
+signed 32-bit integer.
+ at item int64
+signed 64-bit integer.
+ at item uint8
+unsigned 8-bit integer.
+ at item uint16
+unsigned 16-bit integer.
+ at item uint32
+unsigned 32-bit integer.
+ at item uint64
+unsigned 64-bit integer.
+ at end table
+
+The default for @var{type} is @code{uint32}.
+ at seealso{intmax, bitmax}
+ at end deftypefn
+bsxfun
+ at c ./DLD-FUNCTIONS/bsxfun.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} bsxfun (@var{f}, @var{a}, @var{b})
+Applies a binary function @var{f} element-wise to two matrix arguments
+ at var{a} and @var{b}.  The function @var{f} must be capable of accepting
+two column vector arguments of equal length, or one column vector
+argument and a scalar.
+
+The dimensions of @var{a} and @var{b} must be equal or singleton.  The
+singleton dimensions of the matrices will be expanded to the same
+dimensionality as the other matrix.
+
+ at seealso{arrayfun, cellfun}
+ at end deftypefn
+ccolamd
+ at c ./DLD-FUNCTIONS/ccolamd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} ccolamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{s}, @var{knobs}, @var{cmember})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} ccolamd (@dots{})
+
+Constrained column approximate minimum degree permutation.  @code{@var{p} =
+ccolamd (@var{s})} returns the column approximate minimum degree permutation
+vector for the sparse matrix @var{s}.  For a non-symmetric matrix @var{s},
+ at code{@var{s} (:, @var{p})} tends to have sparser LU factors than @var{s}.
+ at code{chol (@var{s} (:, @var{p})' * @var{s} (:, @var{p}))} also tends to be
+sparser than @code{chol (@var{s}' * @var{s})}.  @code{@var{p} = ccolamd
+(@var{s}, 1)} optimizes the ordering for @code{lu (@var{s} (:, @var{p}))}.
+The ordering is followed by a column elimination tree post-ordering.
+
+ at var{knobs} is an optional one- to five-element input vector, with a default
+value of @code{[0 10 10 1 0]} if not present or empty.  Entries not present
+are set to their defaults.
+
+ at table @code
+ at item @var{knobs}(1)
+if nonzero, the ordering is optimized for @code{lu (S (:, p))}.  It will be a
+poor ordering for @code{chol (@var{s} (:, @var{p})' * @var{s} (:,
+ at var{p}))}.  This is the most important knob for ccolamd.
+
+ at item @var{knob}(2)
+if @var{s} is m-by-n, rows with more than @code{max (16, @var{knobs} (2) *
+sqrt (n))} entries are ignored.
+
+ at item @var{knob}(3)
+columns with more than @code{max (16, @var{knobs} (3) * sqrt (min (@var{m},
+ at var{n})))} entries are ignored and ordered last in the output permutation
+(subject to the cmember constraints).
+
+ at item @var{knob}(4)
+if nonzero, aggressive absorption is performed.
+
+ at item @var{knob}(5)
+if nonzero, statistics and knobs are printed.
+
+ at end table
+
+ at var{cmember} is an optional vector of length n.  It defines the constraints
+on the column ordering.  If @code{@var{cmember} (j) = @var{c}}, then column
+ at var{j} is in constraint set @var{c} (@var{c} must be in the range 1 to
+ at var{n}).  In the output permutation @var{p}, all columns in set 1 appear
+first, followed by all columns in set 2, and so on.  @code{@var{cmember} =
+ones(1,n)} if not present or empty.  @code{ccolamd (@var{s}, [], 1 :
+ at var{n})} returns @code{1 : @var{n}}
+
+ at code{@var{p} = ccolamd (@var{s})} is about the same as @code{@var{p} =
+colamd (@var{s})}.  @var{knobs} and its default values differ.  @code{colamd}
+always does aggressive absorption, and it finds an ordering suitable for
+both @code{lu (@var{s} (:, @var{p}))} and @code{chol (@var{S} (:, @var{p})'
+* @var{s} (:, @var{p}))}; it cannot optimize its ordering for
+ at code{lu (@var{s} (:, @var{p}))} to the extent that
+ at code{ccolamd (@var{s}, 1)} can.
+
+ at var{stats} is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix @var{s}.  Ordering
+statistics are in @code{@var{stats} (1 : 3)}.  @code{@var{stats} (1)} and
+ at code{@var{stats} (2)} are the number of dense or empty rows and columns
+ignored by CCOLAMD and @code{@var{stats} (3)} is the number of garbage
+collections performed on the internal data structure used by CCOLAMD
+(roughly of size @code{2.2 * nnz (@var{s}) + 4 * @var{m} + 7 * @var{n}}
+integers).
+
+ at code{@var{stats} (4 : 7)} provide information if CCOLAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists.
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row
+index in the column index given by @code{@var{stats} (5)}, or zero if no
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate
+or out-of-order row indices.  @code{@var{stats} (8 : 20)} is always zero in
+the current version of CCOLAMD (reserved for future use).
+
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),
+and a grant from Sandia National Lab.  See
+ at url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,
+colamd, symamd, and other related orderings.
+ at seealso{colamd, csymamd}
+ at end deftypefn
+csymamd
+ at c ./DLD-FUNCTIONS/ccolamd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} csymamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs}, @var{cmember})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})
+
+For a symmetric positive definite matrix @var{s}, returns the permutation
+vector @var{p} such that @code{@var{s}(@var{p}, at var{p})} tends to have a
+sparser Cholesky factor than @var{s}.  Sometimes @code{csymamd} works well
+for symmetric indefinite matrices too.  The matrix @var{s} is assumed to
+be symmetric; only the strictly lower triangular part is referenced.
+ at var{s} must be square.  The ordering is followed by an elimination tree
+post-ordering.
+
+ at var{knobs} is an optional one- to three-element input vector, with a
+default value of @code{[10 1 0]} if present or empty.  Entries not
+present are set to their defaults.
+
+ at table @code
+ at item @var{knobs}(1)
+If @var{s} is n-by-n, then rows and columns with more than
+ at code{max(16, at var{knobs}(1)*sqrt(n))} entries are ignored, and ordered
+last in the output permutation (subject to the cmember constraints).
+
+ at item @var{knobs}(2)
+If nonzero, aggressive absorption is performed.
+
+ at item @var{knobs}(3)
+If nonzero, statistics and knobs are printed.
+
+ at end table
+
+ at var{cmember} is an optional vector of length n. It defines the constraints
+on the ordering.  If @code{@var{cmember}(j) = @var{s}}, then row/column j is
+in constraint set @var{c} (@var{c} must be in the range 1 to n).  In the
+output permutation @var{p}, rows/columns in set 1 appear first, followed
+by all rows/columns in set 2, and so on.  @code{@var{cmember} = ones(1,n)}
+if not present or empty.  @code{csymamd(@var{s},[],1:n)} returns @code{1:n}.
+
+ at code{@var{p} = csymamd(@var{s})} is about the same as @code{@var{p} =
+symamd(@var{s})}.  @var{knobs} and its default values differ.
+
+ at code{@var{stats} (4:7)} provide information if CCOLAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists.
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row
+index in the column index given by @code{@var{stats} (5)}, or zero if no
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate
+or out-of-order row indices.  @code{@var{stats} (8:20)} is always zero in
+the current version of CCOLAMD (reserved for future use).
+
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),
+and a grant from Sandia National Lab.  See
+ at url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,
+colamd, symamd, and other related orderings.
+ at seealso{symamd, ccolamd}
+ at end deftypefn
+cellfun
+ at c ./DLD-FUNCTIONS/cellfun.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} cellfun (@var{name}, @var{c})
+ at deftypefnx {Loadable Function} {} cellfun ("size", @var{c}, @var{k})
+ at deftypefnx {Loadable Function} {} cellfun ("isclass", @var{c}, @var{class})
+ at deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c})
+ at deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c}, @var{d})
+ at deftypefnx {Loadable Function} {[@var{a}, @var{b}] =} cellfun (@dots{})
+ at deftypefnx {Loadable Function} {} cellfun (@dots{}, 'ErrorHandler', @var{errfunc})
+ at deftypefnx {Loadable Function} {} cellfun (@dots{}, 'UniformOutput', @var{val})
+
+Evaluate the function named @var{name} on the elements of the cell array
+ at var{c}.  Elements in @var{c} are passed on to the named function
+individually.  The function @var{name} can be one of the functions
+
+ at table @code
+ at item isempty
+Return 1 for empty elements.
+ at item islogical
+Return 1 for logical elements.
+ at item isreal
+Return 1 for real elements.
+ at item length
+Return a vector of the lengths of cell elements.
+ at item ndims
+Return the number of dimensions of each element.
+ at item prodofsize
+Return the product of dimensions of each element.
+ at item size
+Return the size along the @var{k}-th dimension.
+ at item isclass
+Return 1 for elements of @var{class}.
+ at end table
+
+Additionally, @code{cellfun} accepts an arbitrary function @var{func}
+in the form of an inline function, function handle, or the name of a
+function (in a character string).  In the case of a character string
+argument, the function must accept a single argument named @var{x}, and
+it must return a string value.  The function can take one or more arguments,
+with the inputs args given by @var{c}, @var{d}, etc.  Equally the function
+can return one or more output arguments.  For example
+
+ at example
+ at group
+cellfun (@@atan2, @{1, 0@}, @{0, 1@})
+ at result{}ans = [1.57080   0.00000]
+ at end group
+ at end example
+
+Note that the default output argument is an array of the same size as the
+input arguments.
+
+If the parameter 'UniformOutput' is set to true (the default), then the function
+must return a single element which will be concatenated into the
+return value.  If 'UniformOutput' is false, the outputs are concatenated in
+a cell array.  For example
+
+ at example
+ at group
+cellfun ("tolower(x)", @{"Foo", "Bar", "FooBar"@},
+         "UniformOutput",false)
+ at result{} ans = @{"foo", "bar", "foobar"@}
+ at end group
+ at end example
+
+Given the parameter 'ErrorHandler', then @var{errfunc} defines a function to
+call in case @var{func} generates an error.  The form of the function is
+
+ at example
+function [@dots{}] = errfunc (@var{s}, @dots{})
+ at end example
+
+where there is an additional input argument to @var{errfunc} relative to
+ at var{func}, given by @var{s}.  This is a structure with the elements
+'identifier', 'message' and 'index', giving respectively the error
+identifier, the error message, and the index into the input arguments
+of the element that caused the error.  For example
+
+ at example
+ at group
+function y = foo (s, x), y = NaN; endfunction
+cellfun (@@factorial, @{-1,2@},'ErrorHandler',@@foo)
+ at result{} ans = [NaN 2]
+ at end group
+ at end example
+
+ at seealso{isempty, islogical, isreal, length, ndims, numel, size}
+ at end deftypefn
+num2cell
+ at c ./DLD-FUNCTIONS/cellfun.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {@var{c} =} num2cell (@var{m})
+ at deftypefnx {Loadable Function} {@var{c} =} num2cell (@var{m}, @var{dim})
+Convert the matrix @var{m} to a cell array.  If @var{dim} is defined, the
+value @var{c} is of dimension 1 in this dimension and the elements of
+ at var{m} are placed in slices in @var{c}.
+ at seealso{mat2cell}
+ at end deftypefn
+mat2cell
+ at c ./DLD-FUNCTIONS/cellfun.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{m}, @var{n})
+ at deftypefnx {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{d1}, @var{d2}, @dots{})
+ at deftypefnx {Loadable Function} {@var{b} =} mat2cell (@var{a}, @var{r})
+Convert the matrix @var{a} to a cell array.  If @var{a} is 2-D, then
+it is required that @code{sum (@var{m}) == size (@var{a}, 1)} and
+ at code{sum (@var{n}) == size (@var{a}, 2)}.  Similarly, if @var{a} is
+a multi-dimensional and the number of dimensional arguments is equal
+to the dimensions of @var{a}, then it is required that @code{sum (@var{di})
+== size (@var{a}, i)}.
+
+Given a single dimensional argument @var{r}, the other dimensional
+arguments are assumed to equal @code{size (@var{a}, at var{i})}.
+
+An example of the use of mat2cell is
+
+ at example
+mat2cell (reshape(1:16,4,4),[3,1],[3,1])
+ at result{} @{
+  [1,1] =
+
+     1   5   9
+     2   6  10
+     3   7  11
+
+  [2,1] =
+
+     4   8  12
+
+  [1,2] =
+
+    13
+    14
+    15
+
+  [2,2] = 16
+@}
+ at end example
+ at seealso{num2cell, cell2mat}
+ at end deftypefn
+cellslices
+ at c ./DLD-FUNCTIONS/cellfun.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{sl} =} cellslices (@var{x}, @var{lb}, @var{ub})
+Given a vector @var{x}, this function produces a cell array of slices from the vector
+determined by the index vectors @var{lb}, @var{ub}, for lower and upper bounds, respectively.
+In other words, it is equivalent to the following code:
+
+ at example
+ at group
+n = length (lb);
+sl = cell (1, n);
+for i = 1:length (lb)
+  sl@{i@} = x(lb(i):ub(i));
+endfor
+ at end group
+ at end example
+
+If @var{X} is a matrix or array, indexing is done along the last dimension.
+ at seealso{mat2cell}
+ at end deftypefn
+chol
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{r} =} chol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}] =} chol (@var{a})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} chol (@var{s})
+ at deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} chol (@var{s}, 'vector')
+ at deftypefnx {Loadable Function} {[@var{l}, @dots{}] =} chol (@dots{}, 'lower')
+ at cindex Cholesky factorization
+Compute the Cholesky factor, @var{r}, of the symmetric positive definite
+matrix @var{a}, where
+ at iftex
+ at tex
+$ R^T R = A $.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{r}' * @var{r} = @var{a}.
+ at end example
+ at end ifnottex
+
+Called with one output argument @code{chol} fails if @var{a} or @var{s} is
+not positive definite.  With two or more output arguments @var{p} flags
+whether the matrix was positive definite and @code{chol} does not fail.  A
+zero value indicated that the matrix was positive definite and the @var{r}
+gives the factorization, and @var{p} will have a positive value otherwise.
+
+If called with 3 outputs then a sparsity preserving row/column permutation
+is applied to @var{a} prior to the factorization.  That is @var{r}
+is the factorization of @code{@var{a}(@var{q}, at var{q})} such that
+ at iftex
+ at tex
+$ R^T R = Q^T A Q$.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{r}' * @var{r} = @var{q}' * @var{a} * @var{q}.
+ at end example
+ at end ifnottex
+
+The sparsity preserving permutation is generally returned as a matrix.
+However, given the flag 'vector', @var{q} will be returned as a vector
+such that
+ at iftex
+ at tex
+$ R^T R = A (Q, Q)$.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{r}' * @var{r} = a (@var{q}, @var{q}).
+ at end example
+ at end ifnottex
+
+Called with either a sparse or full matrix and using the 'lower' flag,
+ at code{chol} returns the lower triangular factorization such that
+ at iftex
+ at tex
+$ L L^T = A $.
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at var{l} * @var{l}' = @var{a}.
+ at end example
+ at end ifnottex
+
+In general the lower triangular factorization is significantly faster for
+sparse matrices.
+ at seealso{cholinv, chol2inv}
+ at end deftypefn
+cholinv
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} cholinv (@var{a})
+Use the Cholesky factorization to compute the inverse of the
+symmetric positive definite matrix @var{a}.
+ at seealso{chol, chol2inv}
+ at end deftypefn
+chol2inv
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} chol2inv (@var{u})
+Invert a symmetric, positive definite square matrix from its Cholesky
+decomposition, @var{u}.  Note that @var{u} should be an upper-triangular
+matrix with positive diagonal elements.  @code{chol2inv (@var{u})}
+provides @code{inv (@var{u}'*@var{u})} but it is much faster than
+using @code{inv}.
+ at seealso{chol, cholinv}
+ at end deftypefn
+cholupdate
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholupdate (@var{R}, @var{u}, @var{op})
+Update or downdate a Cholesky factorization.  Given an upper triangular
+matrix @var{R} and a column vector @var{u}, attempt to determine another
+upper triangular matrix @var{R1} such that
+ at itemize @bullet
+ at item
+ at var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'
+if @var{op} is "+"
+ at item
+ at var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'
+if @var{op} is "-"
+ at end itemize
+
+If @var{op} is "-", @var{info} is set to
+ at itemize
+ at item 0 if the downdate was successful,
+ at item 1 if @var{R}'*@var{R} - @var{u}*@var{u}' is not positive definite,
+ at item 2 if @var{R} is singular.
+ at end itemize
+
+If @var{info} is not present, an error message is printed in cases 1 and 2.
+ at seealso{chol, qrupdate}
+ at end deftypefn
+cholinsert
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholinsert (@var{R}, @var{j}, @var{u})
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,
+return the Cholesky at tie{}factorization of
+ at var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and
+ at w{p = [1:j-1,j+1:n+1]}.  @w{u(j)} should be positive.
+On return, @var{info} is set to
+ at itemize
+ at item 0 if the insertion was successful,
+ at item 1 if @var{A1} is not positive definite,
+ at item 2 if @var{R} is singular.
+ at end itemize
+
+If @var{info} is not present, an error message is printed in cases 1 and 2.
+ at seealso{chol, cholupdate, choldelete}
+ at end deftypefn
+choldelete
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,
+return the Cholesky at tie{}factorization of @w{A(p,p)}, where @w{p = [1:j-1,j+1:n+1]}.
+ at seealso{chol, cholupdate, cholinsert}
+ at end deftypefn
+cholshift
+ at c ./DLD-FUNCTIONS/chol.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{R1} =} cholshift (@var{R}, @var{i}, @var{j})
+Given a Cholesky at tie{}factorization of a real symmetric or complex hermitian
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper triangular,
+return the Cholesky at tie{}factorization of
+ at w{@var{A}(p,p)}, where @w{p} is the permutation @*
+ at code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*
+ or @*
+ at code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*
+
+ at seealso{chol, cholinsert, choldelete}
+ at end deftypefn
+colamd
+ at c ./DLD-FUNCTIONS/colamd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} colamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} colamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{s})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{s}, @var{knobs})
+
+Column approximate minimum degree permutation.  @code{@var{p} = colamd
+(@var{s})} returns the column approximate minimum degree permutation
+vector for the sparse matrix @var{s}.  For a non-symmetric matrix @var{s},
+ at code{@var{s} (:, at var{p})} tends to have sparser LU factors than @var{s}.
+The Cholesky factorization of @code{@var{s} (:, at var{p})' * @var{s}
+(:, at var{p})} also tends to be sparser than that of @code{@var{s}' *
+ at var{s}}.
+
+ at var{knobs} is an optional one- to three-element input vector.  If @var{s} is
+m-by-n, then rows with more than @code{max(16, at var{knobs}(1)*sqrt(n))} entries
+are ignored.  Columns with more than @code{max(16,knobs(2)*sqrt(min(m,n)))}
+entries are removed prior to ordering, and ordered last in the output
+permutation @var{p}.  Only completely dense rows or columns are removed
+if @code{@var{knobs} (1)} and @code{@var{knobs} (2)} are < 0, respectively.
+If @code{@var{knobs} (3)} is nonzero, @var{stats} and @var{knobs} are
+printed.  The default is @code{@var{knobs} = [10 10 0]}.  Note that
+ at var{knobs} differs from earlier versions of colamd
+
+ at var{stats} is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix @var{s}.  Ordering
+statistics are in @code{@var{stats} (1:3)}.  @code{@var{stats} (1)} and
+ at code{@var{stats} (2)} are the number of dense or empty rows and columns
+ignored by COLAMD and @code{@var{stats} (3)} is the number of garbage
+collections performed on the internal data structure used by COLAMD
+(roughly of size @code{2.2 * nnz(@var{s}) + 4 * @var{m} + 7 * @var{n}}
+integers).
+
+Octave built-in functions are intended to generate valid sparse matrices,
+with no duplicate entries, with ascending row indices of the nonzeros
+in each column, with a non-negative number of entries in each column (!)
+and so on.  If a matrix is invalid, then COLAMD may or may not be able
+to continue.  If there are duplicate entries (a row index appears two or
+more times in the same column) or if the row indices in a column are out
+of order, then COLAMD can correct these errors by ignoring the duplicate
+entries and sorting each column of its internal copy of the matrix
+ at var{s} (the input matrix @var{s} is not repaired, however).  If a matrix
+is invalid in other ways then COLAMD cannot continue, an error message is
+printed, and no output arguments (@var{p} or @var{stats}) are returned.
+COLAMD is thus a simple way to check a sparse matrix to see if it's
+valid.
+
+ at code{@var{stats} (4:7)} provide information if COLAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if
+invalid.  @code{@var{stats} (5)} is the rightmost column index that is
+unsorted or contains duplicate entries, or zero if no such column exists.
+ at code{@var{stats} (6)} is the last seen duplicate or out-of-order row
+index in the column index given by @code{@var{stats} (5)}, or zero if no
+such row index exists.  @code{@var{stats} (7)} is the number of duplicate
+or out-of-order row indices.  @code{@var{stats} (8:20)} is always zero in
+the current version of COLAMD (reserved for future use).
+
+The ordering is followed by a column elimination tree post-ordering.
+
+The authors of the code itself are Stefan I. Larimore and Timothy A.
+Davis (davis@@cise.ufl.edu), University of Florida.  The algorithm was
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+Ng, Oak Ridge National Laboratory.  (see
+ at url{http://www.cise.ufl.edu/research/sparse/colamd})
+ at seealso{colperm, symamd}
+ at end deftypefn
+symamd
+ at c ./DLD-FUNCTIONS/colamd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} symamd (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} symamd (@var{s}, @var{knobs})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{s})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{s}, @var{knobs})
+
+For a symmetric positive definite matrix @var{s}, returns the permutation
+vector p such that @code{@var{s} (@var{p}, @var{p})} tends to have a
+sparser Cholesky factor than @var{s}.  Sometimes SYMAMD works well for
+symmetric indefinite matrices too.  The matrix @var{s} is assumed to be
+symmetric; only the strictly lower triangular part is referenced.  @var{s}
+must be square.
+
+ at var{knobs} is an optional one- to two-element input vector.  If @var{s} is
+n-by-n, then rows and columns with more than
+ at code{max(16, at var{knobs}(1)*sqrt(n))} entries are removed prior to ordering,
+and ordered last in the output permutation @var{p}.  No rows/columns are
+removed if @code{@var{knobs}(1) < 0}.  If @code{@var{knobs} (2)} is nonzero,
+ at code{stats} and @var{knobs} are printed.  The default is @code{@var{knobs} 
+= [10 0]}.  Note that @var{knobs} differs from earlier versions of symamd.
+
+ at var{stats} is an optional 20-element output vector that provides data
+about the ordering and the validity of the input matrix @var{s}.  Ordering
+statistics are in @code{@var{stats} (1:3)}.  @code{@var{stats} (1) =
+ at var{stats} (2)} is the number of dense or empty rows and columns
+ignored by SYMAMD and @code{@var{stats} (3)} is the number of garbage
+collections performed on the internal data structure used by SYMAMD
+(roughly of size @code{8.4 * nnz (tril (@var{s}, -1)) + 9 * @var{n}}
+integers).
+
+Octave built-in functions are intended to generate valid sparse matrices,
+with no duplicate entries, with ascending row indices of the nonzeros
+in each column, with a non-negative number of entries in each column (!)
+and so on.  If a matrix is invalid, then SYMAMD may or may not be able
+to continue.  If there are duplicate entries (a row index appears two or
+more times in the same column) or if the row indices in a column are out
+of order, then SYMAMD can correct these errors by ignoring the duplicate
+entries and sorting each column of its internal copy of the matrix S (the
+input matrix S is not repaired, however).  If a matrix is invalid in
+other ways then SYMAMD cannot continue, an error message is printed, and
+no output arguments (@var{p} or @var{stats}) are returned.  SYMAMD is
+thus a simple way to check a sparse matrix to see if it's valid.
+
+ at code{@var{stats} (4:7)} provide information if SYMAMD was able to
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1
+if invalid.  @code{@var{stats} (5)} is the rightmost column index that
+is unsorted or contains duplicate entries, or zero if no such column
+exists.  @code{@var{stats} (6)} is the last seen duplicate or out-of-order
+row index in the column index given by @code{@var{stats} (5)}, or zero
+if no such row index exists.  @code{@var{stats} (7)} is the number of
+duplicate or out-of-order row indices.  @code{@var{stats} (8:20)} is
+always zero in the current version of SYMAMD (reserved for future use).
+
+The ordering is followed by a column elimination tree post-ordering.
+
+
+The authors of the code itself are Stefan I. Larimore and Timothy A.
+Davis (davis@@cise.ufl.edu), University of Florida.  The algorithm was
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+Ng, Oak Ridge National Laboratory.  (see
+ at url{http://www.cise.ufl.edu/research/sparse/colamd})
+ at seealso{colperm, colamd}
+ at end deftypefn
+etree
+ at c ./DLD-FUNCTIONS/colamd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} etree (@var{s})
+ at deftypefnx {Loadable Function} {@var{p} =} etree (@var{s}, @var{typ})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{s}, @var{typ})
+
+Returns the elimination tree for the matrix @var{s}.  By default @var{s}
+is assumed to be symmetric and the symmetric elimination tree is
+returned.  The argument @var{typ} controls whether a symmetric or
+column elimination tree is returned.  Valid values of @var{typ} are
+'sym' or 'col', for symmetric or column elimination tree respectively
+
+Called with a second argument, @dfn{etree} also returns the postorder
+permutations on the tree.
+ at end deftypefn
+colloc
+ at c ./DLD-FUNCTIONS/colloc.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{r}, @var{amat}, @var{bmat}, @var{q}] =} colloc (@var{n}, "left", "right")
+Compute derivative and integral weight matrices for orthogonal
+collocation using the subroutines given in J. Villadsen and
+M. L. Michelsen, @cite{Solution of Differential Equation Models by
+Polynomial Approximation}.
+ at end deftypefn
+conv2
+ at c ./DLD-FUNCTIONS/conv2.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {y =} conv2 (@var{a}, @var{b}, @var{shape})
+ at deftypefnx {Loadable Function} {y =} conv2 (@var{v1}, @var{v2}, @var{M}, @var{shape})
+
+Returns 2D convolution of @var{a} and @var{b} where the size
+of @var{c} is given by
+
+ at table @asis
+ at item @var{shape}= 'full'
+returns full 2-D convolution
+ at item @var{shape}= 'same'
+same size as a. 'central' part of convolution
+ at item @var{shape}= 'valid'
+only parts which do not include zero-padded edges
+ at end table
+
+By default @var{shape} is 'full'.  When the third argument is a matrix
+returns the convolution of the matrix @var{M} by the vector @var{v1}
+in the column direction and by vector @var{v2} in the row direction
+ at end deftypefn
+convhulln
+ at c ./DLD-FUNCTIONS/convhulln.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{h} =} convhulln (@var{p})
+ at deftypefnx {Loadable Function} {@var{h} =} convhulln (@var{p}, @var{opt})
+ at deftypefnx {Loadable Function} {[@var{h}, @var{v}] =} convhulln (@dots{})
+Return an index vector to the points of the enclosing convex hull.
+The input matrix of size [n, dim] contains n points of dimension dim.
+
+If a second optional argument is given, it must be a string or cell array
+of strings containing options for the underlying qhull command.  (See
+the Qhull documentation for the available options.)  The default options
+are "s Qci Tcv".
+If the second output @var{V} is requested the volume of the convex hull is
+calculated.
+
+ at seealso{convhull, delaunayn}
+ at end deftypefn
+daspk_options
+ at c ./DLD-FUNCTIONS/daspk.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} daspk_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{daspk}.
+Given one argument, @code{daspk_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+ at item "relative tolerance"
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i))
+       <= rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+ at item "compute consistent initial condition"
+Denoting the differential variables in the state vector by @samp{Y_d}
+and the algebraic variables by @samp{Y_a}, @code{ddaspk} can solve
+one of two initialization problems:
+
+ at enumerate
+ at item Given Y_d, calculate Y_a and Y'_d
+ at item Given Y', calculate Y.
+ at end enumerate
+
+In either case, initial values for the given components are input, and
+initial guesses for the unknown components must also be provided as
+input.  Set this option to 1 to solve the first problem, or 2 to solve
+the second (the default is 0, so you must provide a set of
+initial conditions that are consistent).
+
+If this option is set to a nonzero value, you must also set the
+ at code{"algebraic variables"} option to declare which variables in the
+problem are algebraic.
+ at item "use initial condition heuristics"
+Set to a nonzero value to use the initial condition heuristics options
+described below.
+ at item "initial condition heuristics"
+A vector of the following parameters that can be used to control the
+initial condition calculation.
+
+ at table @code
+ at item MXNIT
+Maximum number of Newton iterations (default is 5).
+ at item MXNJ
+Maximum number of Jacobian evaluations (default is 6).
+ at item MXNH
+Maximum number of values of the artificial stepsize parameter to be
+tried if the @code{"compute consistent initial condition"} option has
+been set to 1 (default is 5).
+
+Note that the maximum total number of Newton iterations allowed is
+ at code{MXNIT*MXNJ*MXNH} if the @code{"compute consistent initial
+condition"} option has been set to 1 and @code{MXNIT*MXNJ} if it is
+set to 2.
+ at item LSOFF
+Set to a nonzero value to disable the linesearch algorithm (default is
+0).
+ at item STPTOL
+Minimum scaled step in linesearch algorithm (default is eps^(2/3)).
+ at item EPINIT
+Swing factor in the Newton iteration convergence test.  The test is
+applied to the residual vector, premultiplied by the approximate
+Jacobian.  For convergence, the weighted RMS norm of this vector
+(scaled by the error weights) must be less than @code{EPINIT*EPCON},
+where @code{EPCON} = 0.33 is the analogous test constant used in the
+time steps.  The default is @code{EPINIT} = 0.01.
+ at end table
+ at item "print initial condition info"
+Set this option to a nonzero value to display detailed information
+about the initial condition calculation (default is 0).
+ at item "exclude algebraic variables from error test"
+Set to a nonzero value to exclude algebraic variables from the error
+test.  You must also set the @code{"algebraic variables"} option to
+declare which variables in the problem are algebraic (default is 0).
+ at item "algebraic variables"
+A vector of the same length as the state vector.  A nonzero element
+indicates that the corresponding element of the state vector is an
+algebraic variable (i.e., its derivative does not appear explicitly
+in the equation set.
+
+This option is required by the
+ at code{compute consistent initial condition"} and
+ at code{"exclude algebraic variables from error test"} options.
+ at item "enforce inequality constraints"
+Set to one of the following values to enforce the inequality
+constraints specified by the @code{"inequality constraint types"}
+option (default is 0).
+
+ at enumerate
+ at item To have constraint checking only in the initial condition calculation.
+ at item To enforce constraint checking during the integration.
+ at item To enforce both options 1 and 2.
+ at end enumerate
+ at item "inequality constraint types"
+A vector of the same length as the state specifying the type of
+inequality constraint.  Each element of the vector corresponds to an
+element of the state and should be assigned one of the following
+codes 
+
+ at table @asis
+ at item -2
+Less than zero.
+ at item -1
+Less than or equal to zero.
+ at item 0
+Not constrained.
+ at item 1
+Greater than or equal to zero.
+ at item 2
+Greater than zero.
+ at end table
+
+This option only has an effect if the
+ at code{"enforce inequality constraints"} option is nonzero.
+ at item "initial step size"
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize (default is computed
+automatically).
+ at item "maximum order"
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive (default is 5).
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions (default is not specified).
+ at end table
+ at end deftypefn
+daspk
+ at c ./DLD-FUNCTIONS/daspk.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} daspk (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
+Solve the set of differential-algebraic equations
+ at tex
+$$ 0 = f (x, \dot{x}, t) $$
+with
+$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
+ at end tex
+ at ifnottex
+
+ at example
+0 = f (x, xdot, t)
+ at end example
+
+with
+
+ at example
+x(t_0) = x_0, xdot(t_0) = xdot_0
+ at end example
+
+ at end ifnottex
+The solution is returned in the matrices @var{x} and @var{xdot},
+with each row in the result matrices corresponding to one of the
+elements in the vector @var{t}.  The first element of @var{t}
+should be @math{t_0} and correspond to the initial state of the
+system @var{x_0} and its derivative @var{xdot_0}, so that the first
+row of the output @var{x} is @var{x_0} and the first row
+of the output @var{xdot} is @var{xdot_0}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+ at example
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})
+ at end example
+
+ at noindent
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
+scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the modified Jacobian
+ at tex
+$$
+J = {\partial f \over \partial x}
+  + c {\partial f \over \partial \dot{x}}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+      df       df
+jac = -- + c ------
+      dx     d xdot
+ at end group
+ at end example
+ at end ifnottex
+
+The modified Jacobian function must have the form
+
+ at example
+ at group
+
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})
+
+ at end group
+ at end example
+
+The second and third arguments to @code{daspk} specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+The set of initial states and derivatives are not strictly required to
+be consistent.  If they are not consistent, you must use the
+ at code{daspk_options} function to provide additional information so
+that @code{daspk} can compute a consistent starting point.
+
+The fifth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be
+greater than zero (consistent with the Fortran version of @sc{Daspk}).
+
+If the computation is not successful, the value of @var{istate} will be
+less than zero and @var{msg} will contain additional information.
+
+You can use the function @code{daspk_options} to set optional
+parameters for @code{daspk}.
+ at seealso{dassl}
+ at end deftypefn
+dasrt_options
+ at c ./DLD-FUNCTIONS/dasrt.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dasrt_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{dasrt}.
+Given one argument, @code{dasrt_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+ at item "relative tolerance"
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+ at example
+ at group
+  abs (local error in x(i)) <= ...
+      rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+ at item "initial step size"
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize.
+ at item "maximum order"
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive.
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions.
+ at item "step limit"
+Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code.
+ at end table
+ at end deftypefn
+dasrt
+ at c ./DLD-FUNCTIONS/dasrt.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{t_out}, @var{istat}, @var{msg}] =} dasrt (@var{fcn} [, @var{g}], @var{x_0}, @var{xdot_0}, @var{t} [, @var{t_crit}])
+Solve the set of differential-algebraic equations
+ at tex
+$$ 0 = f (x, \dot{x}, t) $$
+with
+$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
+ at end tex
+ at ifnottex
+
+ at example
+0 = f (x, xdot, t)
+ at end example
+
+with
+
+ at example
+x(t_0) = x_0, xdot(t_0) = xdot_0
+ at end example
+
+ at end ifnottex
+with functional stopping criteria (root solving).
+
+The solution is returned in the matrices @var{x} and @var{xdot},
+with each row in the result matrices corresponding to one of the
+elements in the vector @var{t_out}.  The first element of @var{t}
+should be @math{t_0} and correspond to the initial state of the
+system @var{x_0} and its derivative @var{xdot_0}, so that the first
+row of the output @var{x} is @var{x_0} and the first row
+of the output @var{xdot} is @var{xdot_0}.
+
+The vector @var{t} provides an upper limit on the length of the
+integration.  If the stopping condition is met, the vector
+ at var{t_out} will be shorter than @var{t}, and the final element of
+ at var{t_out} will be the point at which the stopping condition was met,
+and may not correspond to any element of the vector @var{t}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+ at example
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})
+ at end example
+
+ at noindent
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
+scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the modified Jacobian
+
+ at tex
+$$
+J = {\partial f \over \partial x}
+  + c {\partial f \over \partial \dot{x}}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+      df       df
+jac = -- + c ------
+      dx     d xdot
+ at end group
+ at end example
+
+ at end ifnottex
+
+The modified Jacobian function must have the form
+
+ at example
+ at group
+
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})
+
+ at end group
+ at end example
+
+The optional second argument names a function that defines the
+constraint functions whose roots are desired during the integration.
+This function must have the form
+
+ at example
+ at var{g_out} = g (@var{x}, @var{t})
+ at end example
+
+and return a vector of the constraint function values.
+If the value of any of the constraint functions changes sign, @sc{Dasrt}
+will attempt to stop the integration at the point of the sign change.
+
+If the name of the constraint function is omitted, @code{dasrt} solves
+the same problem as @code{daspk} or @code{dassl}.
+
+Note that because of numerical errors in the constraint functions
+due to roundoff and integration error, @sc{Dasrt} may return false
+roots, or return the same root at two or more nearly equal values of
+ at var{T}.  If such false roots are suspected, the user should consider
+smaller error tolerances or higher precision in the evaluation of the
+constraint functions.
+
+If a root of some constraint function defines the end of the problem,
+the input to @sc{Dasrt} should nevertheless allow integration to a
+point slightly past that root, so that @sc{Dasrt} can locate the root
+by interpolation.
+
+The third and fourth arguments to @code{dasrt} specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+The set of initial states and derivatives are not strictly required to
+be consistent.  In practice, however, @sc{Dassl} is not very good at
+determining a consistent set for you, so it is best if you ensure that
+the initial values result in the function evaluating to zero.
+
+The sixth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be
+greater than zero (consistent with the Fortran version of @sc{Dassl}).
+
+If the computation is not successful, the value of @var{istate} will be
+less than zero and @var{msg} will contain additional information.
+
+You can use the function @code{dasrt_options} to set optional
+parameters for @code{dasrt}.
+ at seealso{daspk, dasrt, lsode}
+ at end deftypefn
+dassl_options
+ at c ./DLD-FUNCTIONS/dassl.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dassl_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{dassl}.
+Given one argument, @code{dassl_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the relative
+tolerance must also be a vector of the same length.
+ at item "relative tolerance"
+Relative tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector, and the absolute
+tolerance must also be a vector of the same length.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i))
+       <= rtol(i) * abs (Y(i)) + atol(i)
+ at end group
+ at end example
+ at item "compute consistent initial condition"
+If nonzero, @code{dassl} will attempt to compute a consistent set of initial
+conditions.  This is generally not reliable, so it is best to provide
+a consistent set and leave this option set to zero.
+ at item "enforce nonnegativity constraints"
+If you know that the solutions to your equations will always be
+nonnegative, it may help to set this parameter to a nonzero
+value.  However, it is probably best to try leaving this option set to
+zero first, and only setting it to a nonzero value if that doesn't
+work very well.
+ at item "initial step size"
+Differential-algebraic problems may occasionally suffer from severe
+scaling difficulties on the first step.  If you know a great deal
+about the scaling of your problem, you can help to alleviate this
+problem by specifying an initial stepsize.
+ at item "maximum order"
+Restrict the maximum order of the solution method.  This option must
+be between 1 and 5, inclusive.
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified).
+ at item "step limit"
+Maximum number of integration steps to attempt on a single call to the
+underlying Fortran code.
+ at end table
+ at end deftypefn
+dassl
+ at c ./DLD-FUNCTIONS/dassl.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} dassl (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
+Solve the set of differential-algebraic equations
+ at iftex
+ at tex
+$$ 0 = f (x, \dot{x}, t) $$
+with
+$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+0 = f (x, xdot, t)
+ at end example
+
+ at noindent
+with
+
+ at example
+x(t_0) = x_0, xdot(t_0) = xdot_0
+ at end example
+
+ at end ifnottex
+The solution is returned in the matrices @var{x} and @var{xdot},
+with each row in the result matrices corresponding to one of the
+elements in the vector @var{t}.  The first element of @var{t}
+should be @math{t_0} and correspond to the initial state of the
+system @var{x_0} and its derivative @var{xdot_0}, so that the first
+row of the output @var{x} is @var{x_0} and the first row
+of the output @var{xdot} is @var{xdot_0}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of
+residuals for the set of equations.  It must have the form
+
+ at example
+ at var{res} = f (@var{x}, @var{xdot}, @var{t})
+ at end example
+
+ at noindent
+in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
+scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the modified Jacobian
+
+ at iftex
+ at tex
+$$
+J = {\partial f \over \partial x}
+  + c {\partial f \over \partial \dot{x}}
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+ at example
+ at group
+      df       df
+jac = -- + c ------
+      dx     d xdot
+ at end group
+ at end example
+ at end ifnottex
+
+The modified Jacobian function must have the form
+
+ at example
+ at group
+
+ at var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})
+
+ at end group
+ at end example
+
+The second and third arguments to @code{dassl} specify the initial
+condition of the states and their derivatives, and the fourth argument
+specifies a vector of output times at which the solution is desired,
+including the time corresponding to the initial condition.
+
+The set of initial states and derivatives are not strictly required to
+be consistent.  In practice, however, @sc{Dassl} is not very good at
+determining a consistent set for you, so it is best if you ensure that
+the initial values result in the function evaluating to zero.
+
+The fifth argument is optional, and may be used to specify a set of
+times that the DAE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be
+greater than zero (consistent with the Fortran version of @sc{Dassl}).
+
+If the computation is not successful, the value of @var{istate} will be
+less than zero and @var{msg} will contain additional information.
+
+You can use the function @code{dassl_options} to set optional
+parameters for @code{dassl}.
+ at seealso{daspk, dasrt, lsode}
+ at end deftypefn
+all
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} all (@var{x}, @var{dim})
+The function @code{all} behaves like the function @code{any}, except
+that it returns true only if all the elements of a vector, or all the
+elements along dimension @var{dim} of a matrix, are nonzero.
+ at end deftypefn
+any
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} any (@var{x}, @var{dim})
+For a vector argument, return 1 if any element of the vector is
+nonzero.
+
+For a matrix argument, return a row vector of ones and
+zeros with each element indicating whether any of the elements of the
+corresponding column of the matrix are nonzero.  For example,
+
+ at example
+ at group
+any (eye (2, 4))
+     @result{} [ 1, 1, 0, 0 ]
+ at end group
+ at end example
+
+If the optional argument @var{dim} is supplied, work along dimension
+ at var{dim}.  For example,
+
+ at example
+ at group
+any (eye (2, 4), 2)
+     @result{} [ 1; 1 ]
+ at end group
+ at end example
+ at end deftypefn
+atan2
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} atan2 (@var{y}, @var{x})
+Compute atan (@var{y} / @var{x}) for corresponding elements of @var{y}
+and @var{x}.  Signal an error if @var{y} and @var{x} do not match in size
+and orientation.
+ at end deftypefn
+hypot
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} hypot (@var{x}, @var{y})
+Compute the element-by-element square root of the sum of the squares of
+ at var{x} and @var{y}.  This is equivalent to
+ at code{sqrt (@var{x}.^2 + @var{y}.^2)}, but calculated in a manner that
+avoids overflows for large values of @var{x} or @var{y}.
+ at end deftypefn
+log2
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} log2 (@var{x})
+ at deftypefnx {Mapping Function} {[@var{f}, @var{e}] =} log2 (@var{x})
+Compute the base-2 logarithm of each element of @var{x}.
+
+If called with two output arguments, split @var{x} into
+binary mantissa and exponent so that
+ at tex
+${1 \over 2} \le \left| f \right| < 1$
+ at end tex
+ at ifnottex
+ at code{1/2 <= abs(f) < 1}
+ at end ifnottex
+and @var{e} is an integer.  If
+ at tex
+$x = 0$, $f = e = 0$.
+ at end tex
+ at ifnottex
+ at code{x = 0}, @code{f = e = 0}.
+ at end ifnottex
+ at seealso{pow2, log, log10, exp}
+ at end deftypefn
+fmod
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})
+Compute the floating point remainder of dividing @var{x} by @var{y}
+using the C library function @code{fmod}.  The result has the same
+sign as @var{x}.  If @var{y} is zero, the result is implementation-dependent.
+ at seealso{mod, rem}
+ at end deftypefn
+cumprod
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} cumprod (@var{x})
+ at deftypefnx {Built-in Function} {} cumprod (@var{x}, @var{dim})
+Cumulative product of elements along dimension @var{dim}.  If
+ at var{dim} is omitted, it defaults to 1 (column-wise cumulative
+products).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the cumulative product of the elements as a vector with the
+same orientation as @var{x}.
+ at seealso{prod, cumsum}
+ at end deftypefn
+cumsum
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} cumsum (@var{x})
+ at deftypefnx {Built-in Function} {} cumsum (@var{x}, @var{dim})
+ at deftypefnx {Built-in Function} {} cumsum (@dots{}, 'native')
+Cumulative sum of elements along dimension @var{dim}.  If @var{dim}
+is omitted, it defaults to 1 (column-wise cumulative sums).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the cumulative sum of the elements as a vector with the
+same orientation as @var{x}.
+
+The "native" argument implies the summation is performed in native type.
+ See @code{sum} for a complete description and example of the use of
+"native".
+ at seealso{sum, cumprod}
+ at end deftypefn
+diag
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} diag (@var{v}, @var{k})
+Return a diagonal matrix with 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
+ at var{-k}-th sub-diagonal.  The default value of @var{k} is 0, and the
+vector is placed on the main diagonal.  For example,
+
+ at example
+ at group
+diag ([1, 2, 3], 1)
+     @result{}  0  1  0  0
+         0  0  2  0
+         0  0  0  3
+         0  0  0  0
+ at end group
+ at end example
+
+ at noindent
+Given a matrix argument, instead of a vector, @code{diag} extracts the
+ at var{k}-th diagonal of the matrix.
+ at end deftypefn
+prod
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} prod (@var{x})
+ at deftypefnx {Built-in Function} {} prod (@var{x}, @var{dim})
+Product of elements along dimension @var{dim}.  If @var{dim} is
+omitted, it defaults to 1 (column-wise products).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the product of the elements.
+ at seealso{cumprod, sum}
+ at end deftypefn
+horzcat
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} horzcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})
+Return the horizontal concatenation of N-d array objects, @var{array1},
+ at var{array2}, @dots{}, @var{arrayN} along dimension 2.
+ at seealso{cat, vertcat}
+ at end deftypefn
+vertcat
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} vertcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})
+Return the vertical concatenation of N-d array objects, @var{array1},
+ at var{array2}, @dots{}, @var{arrayN} along dimension 1.
+ at seealso{cat, horzcat}
+ at end deftypefn
+cat
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} cat (@var{dim}, @var{array1}, @var{array2}, @dots{}, @var{arrayN})
+Return the concatenation of N-d array objects, @var{array1},
+ at var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.
+
+ at example
+ at group
+A = ones (2, 2);
+B = zeros (2, 2);
+cat (2, A, B)
+ at result{} ans =
+
+     1 1 0 0
+     1 1 0 0
+ at end group
+ at end example
+
+Alternatively, we can concatenate @var{A} and @var{B} along the
+second dimension the following way:
+
+ at example
+ at group
+[A, B].
+ at end group
+ at end example
+
+ at var{dim} can be larger than the dimensions of the N-d array objects
+and the result will thus have @var{dim} dimensions as the
+following example shows:
+ at example
+ at group
+cat (4, ones(2, 2), zeros (2, 2))
+ at result{} ans =
+
+   ans(:,:,1,1) =
+
+     1 1
+     1 1
+
+   ans(:,:,1,2) =
+     0 0
+     0 0
+ at end group
+ at end example
+ at seealso{horzcat, vertcat}
+ at end deftypefn
+permute
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} permute (@var{a}, @var{perm})
+Return the generalized transpose for an N-d array object @var{a}.
+The permutation vector @var{perm} must contain the elements
+ at code{1:ndims(a)} (in any order, but each element must appear just once).
+ at seealso{ipermute}
+ at end deftypefn
+ipermute
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ipermute (@var{a}, @var{iperm})
+The inverse of the @code{permute} function.  The expression
+
+ at example
+ipermute (permute (a, perm), perm)
+ at end example
+returns the original array @var{a}.
+ at seealso{permute}
+ at end deftypefn
+length
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} length (@var{a})
+Return the `length' of the object @var{a}.  For matrix objects, the
+length is the number of rows or columns, whichever is greater (this
+odd definition is used for compatibility with @sc{matlab}).
+ at end deftypefn
+ndims
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ndims (@var{a})
+Returns the number of dimensions of array @var{a}.
+For any array, the result will always be larger than or equal to 2.
+Trailing singleton dimensions are not counted.
+ at end deftypefn
+numel
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} numel (@var{a})
+Returns the number of elements in the object @var{a}.
+ at seealso{size}
+ at end deftypefn
+size
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} size (@var{a}, @var{n})
+Return the number rows and columns of @var{a}.
+
+With one input argument and one output argument, the result is returned
+in a row vector.  If there are multiple output arguments, the number of
+rows is assigned to the first, and the number of columns to the second,
+etc.  For example,
+
+ at example
+ at group
+size ([1, 2; 3, 4; 5, 6])
+     @result{} [ 3, 2 ]
+
+[nr, nc] = size ([1, 2; 3, 4; 5, 6])
+     @result{} nr = 3
+     @result{} nc = 2
+ at end group
+ at end example
+
+If given a second argument, @code{size} will return the size of the
+corresponding dimension.  For example
+
+ at example
+ at group
+size ([1, 2; 3, 4; 5, 6], 2)
+     @result{} 2
+ at end group
+ at end example
+
+ at noindent
+returns the number of columns in the given matrix.
+ at seealso{numel}
+ at end deftypefn
+size_equal
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} size_equal (@var{a}, @var{b}, @dots{})
+Return true if the dimensions of all arguments agree.
+Trailing singleton dimensions are ignored.
+Called with a single argument, size_equal returns true.
+ at seealso{size, numel}
+ at end deftypefn
+nnz
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{scalar} =} nnz (@var{a})
+Returns the number of non zero elements in @var{a}.
+ at seealso{sparse}
+ at end deftypefn
+nzmax
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{scalar} =} nzmax (@var{SM})
+Return the amount of storage allocated to the sparse matrix @var{SM}.
+Note that Octave tends to crop unused memory at the first opportunity
+for sparse objects.  There are some cases of user created sparse objects
+where the value returned by @dfn{nzmax} will not be the same as @dfn{nnz},
+but in general they will give the same result.
+ at seealso{sparse, spalloc}
+ at end deftypefn
+rows
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rows (@var{a})
+Return the number of rows of @var{a}.
+ at seealso{size, numel, columns, length, isscalar, isvector, ismatrix}
+ at end deftypefn
+columns
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} columns (@var{a})
+Return the number of columns of @var{a}.
+ at seealso{size, numel, rows, length, isscalar, isvector, ismatrix}
+ at end deftypefn
+sum
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} sum (@var{x})
+ at deftypefnx {Built-in Function} {} sum (@var{x}, @var{dim})
+ at deftypefnx {Built-in Function} {} sum (@dots{}, 'native')
+Sum of elements along dimension @var{dim}.  If @var{dim} is
+omitted, it defaults to 1 (column-wise sum).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the sum of the elements.
+
+If the optional argument 'native' is given, then the sum is performed
+in the same type as the original argument, rather than in the default
+double type.  For example
+
+ at example
+ at group
+sum ([true, true])
+  @result{} 2
+sum ([true, true], 'native')
+  @result{} true
+ at end group
+ at end example
+ at seealso{cumsum, sumsq, prod}
+ at end deftypefn
+sumsq
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} sumsq (@var{x})
+ at deftypefnx {Built-in Function} {} sumsq (@var{x}, @var{dim})
+Sum of squares of elements along dimension @var{dim}.  If @var{dim}
+is omitted, it defaults to 1 (column-wise sum of squares).
+
+As a special case, if @var{x} is a vector and @var{dim} is omitted,
+return the sum of squares of the elements.
+
+This function is conceptually equivalent to computing
+ at example
+sum (x .* conj (x), dim)
+ at end example
+but it uses less memory and avoids calling @code{conj} if @var{x} is real.
+ at seealso{sum}
+ at end deftypefn
+islogical
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} islogical (@var{x})
+Return true if @var{x} is a logical object.
+ at end deftypefn
+isinteger
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isinteger (@var{x})
+Return true if @var{x} is an integer object (int8, uint8, int16, etc.).
+Note that @code{isinteger (14)} is false because numeric constants in
+Octave are double precision floating point values.
+ at seealso{isreal, isnumeric, class, isa}
+ at end deftypefn
+iscomplex
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} iscomplex (@var{x})
+Return true if @var{x} is a complex-valued numeric object.
+ at end deftypefn
+isfloat
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isfloat (@var{x})
+Return true if @var{x} is a floating-point numeric object.
+ at end deftypefn
+complex
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} complex (@var{x})
+ at deftypefnx {Built-in Function} {} complex (@var{re}, @var{im})
+Return a complex result from real arguments.  With 1 real argument @var{x},
+return the complex result @code{@var{x} + 0i}.  With 2 real arguments,
+return the complex result @code{@var{re} + @var{im}}.  @code{complex} can
+often be more convenient than expressions such as @code{a + i*b}.
+For example:
+
+ at example
+complex ([1, 2], [3, 4])
+ at result{}
+   1 + 3i   2 + 4i
+ at end example
+ at seealso{real, imag, iscomplex}
+ at end deftypefn
+isreal
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isreal (@var{x})
+Return true if @var{x} is a real-valued numeric object.
+ at end deftypefn
+isempty
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isempty (@var{a})
+Return 1 if @var{a} is an empty matrix (either the number of rows, or
+the number of columns, or both are zero).  Otherwise, return 0.
+ at end deftypefn
+isnumeric
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isnumeric (@var{x})
+Return nonzero if @var{x} is a numeric object.
+ at end deftypefn
+islist
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} islist (@var{x})
+Return nonzero if @var{x} is a list.
+ at end deftypefn
+ismatrix
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ismatrix (@var{a})
+Return 1 if @var{a} is a matrix.  Otherwise, return 0.
+ at end deftypefn
+ones
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ones (@var{x})
+ at deftypefnx {Built-in Function} {} ones (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} ones (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} ones (@dots{}, @var{class})
+Return a matrix or N-dimensional array whose elements are all 1.
+The arguments are handled the same as the arguments for @code{eye}.
+
+If you need to create a matrix whose values are all the same, you should
+use an expression like
+
+ at example
+val_matrix = val * ones (n, m)
+ at end example
+
+The optional argument @var{class}, allows @code{ones} to return an array of
+the specified type, for example
+
+ at example
+val = ones (n,m, "uint8")
+ at end example
+ at end deftypefn
+zeros
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} zeros (@var{x})
+ at deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} zeros (@dots{}, @var{class})
+Return a matrix or N-dimensional array whose elements are all 0.
+The arguments are handled the same as the arguments for @code{eye}.
+
+The optional argument @var{class}, allows @code{zeros} to return an array of
+the specified type, for example
+
+ at example
+val = zeros (n,m, "uint8")
+ at end example
+ at end deftypefn
+Inf
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} Inf
+ at deftypefnx {Built-in Function} {} Inf (@var{n})
+ at deftypefnx {Built-in Function} {} Inf (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} Inf (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} Inf (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the IEEE representation for positive infinity.
+
+Infinity is produced when results are too large to be represented using the
+the IEEE floating point format for numbers.  Two common examples which
+produce infinity are division by zero and overflow.
+ at example
+ at group
+[1/0 e^800]
+ at result{}
+Inf   Inf
+ at end group
+ at end example
+
+When called with no arguments, return a scalar with the value @samp{Inf}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{isinf}
+ at end deftypefn
+NaN
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} NaN
+ at deftypefnx {Built-in Function} {} NaN (@var{n})
+ at deftypefnx {Built-in Function} {} NaN (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} NaN (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} NaN (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the IEEE symbol NaN (Not a Number).
+NaN is the result of operations which do not produce a well defined numerical
+result.  Common operations which produce a NaN are arithmetic with infinity
+ at tex
+($\infty - \infty$), zero divided by zero ($0/0$),
+ at end tex
+ at ifnottex
+(Inf - Inf), zero divided by zero (0/0),
+ at end ifnottex
+and any operation involving another NaN value (5 + NaN).
+
+Note that NaN always compares not equal to NaN (NaN != NaN).  This behavior
+is specified by the IEEE standard for floating point arithmetic.  To
+find NaN values, use the @code{isnan} function.
+
+When called with no arguments, return a scalar with the value @samp{NaN}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{isnan}
+ at end deftypefn
+e
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} e
+ at deftypefnx {Built-in Function} {} e (@var{n})
+ at deftypefnx {Built-in Function} {} e (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} e (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} e (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the base of natural logarithms.  The constant
+ at tex
+$e$ satisfies the equation $\log (e) = 1$.
+ at end tex
+ at ifnottex
+ at samp{e} satisfies the equation @code{log} (e) = 1.
+ at end ifnottex
+
+When called with no arguments, return a scalar with the value @math{e}.  When
+called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+eps
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} eps
+ at deftypefnx {Built-in Function} {} eps (@var{x})
+ at deftypefnx {Built-in Function} {} eps (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} eps (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} eps (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all eps,
+the machine precision.  More precisely, @code{eps} is the relative spacing
+between any two adjacent numbers in the machine's floating point system.
+This number is obviously system dependent.  On machines that support IEEE
+floating point arithmetic, @code{eps} is approximately
+ at tex
+$2.2204\times10^{-16}$ for double precision and $1.1921\times10^{-7}$
+ at end tex
+ at ifnottex
+2.2204e-16 for double precision and 1.1921e-07
+ at end ifnottex
+for single precision.
+
+When called with no arguments, return a scalar with the value
+ at code{eps(1.0)}.
+Given a single argument @var{x}, return the distance between @var{x} and
+the next largest value.
+When called with more than one argument the first two arguments are taken as
+the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+pi
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} pi
+ at deftypefnx {Built-in Function} {} pi (@var{n})
+ at deftypefnx {Built-in Function} {} pi (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} pi (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} pi (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the ratio of the circumference of a circle to its
+ at tex
+diameter($\pi$).
+ at end tex
+ at ifnottex
+diameter.
+ at end ifnottex
+Internally, @code{pi} is computed as @samp{4.0 * atan (1.0)}.
+
+When called with no arguments, return a scalar with the value of
+ at tex
+$\pi$.
+ at end tex
+ at ifnottex
+pi.
+ at end ifnottex
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+realmax
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} realmax
+ at deftypefnx {Built-in Function} {} realmax (@var{n})
+ at deftypefnx {Built-in Function} {} realmax (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} realmax (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} realmax (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the largest floating point number that is representable.  The actual
+value is system dependent.  On machines that support IEEE
+floating point arithmetic, @code{realmax} is approximately
+ at tex
+$1.7977\times10^{308}$ for double precision and $3.4028\times10^{38}$
+ at end tex
+ at ifnottex
+1.7977e+308 for double precision and 3.4028e+38
+ at end ifnottex
+for single precision.
+
+When called with no arguments, return a scalar with the value
+ at code{realmax("double")}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{realmin, intmax, bitmax}
+ at end deftypefn
+realmin
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} realmin
+ at deftypefnx {Built-in Function} {} realmin (@var{n})
+ at deftypefnx {Built-in Function} {} realmin (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} realmin (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} realmin (@dots{}, @var{class})
+Return a scalar, matrix or N-dimensional array whose elements are all equal
+to the smallest normalized floating point number that is representable.
+The actual value is system dependent.  On machines that support
+IEEE floating point arithmetic, @code{realmin} is approximately
+ at tex
+$2.2251\times10^{-308}$ for double precision and $1.1755\times10^{-38}$
+ at end tex
+ at ifnottex
+2.2251e-308 for double precision and 1.1755e-38
+ at end ifnottex
+for single precision.
+
+When called with no arguments, return a scalar with the value
+ at code{realmin("double")}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{realmax, intmin}
+ at end deftypefn
+I
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} I
+ at deftypefnx {Built-in Function} {} I (@var{n})
+ at deftypefnx {Built-in Function} {} I (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} I (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} I (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the pure imaginary unit, defined as
+ at tex
+$\sqrt{-1}$.
+ at end tex
+ at ifnottex
+ at code{sqrt (-1)}.
+ at end ifnottex
+ I, and its equivalents i, J, and j, are functions so any of the names may
+be reused for other purposes (such as i for a counter variable).
+
+When called with no arguments, return a scalar with the value @math{i}.  When
+called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at end deftypefn
+NA
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} NA
+ at deftypefnx {Built-in Function} {} NA (@var{n})
+ at deftypefnx {Built-in Function} {} NA (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} NA (@var{n}, @var{m}, @var{k}, @dots{})
+ at deftypefnx {Built-in Function} {} NA (@dots{}, @var{class})
+Return a scalar, matrix, or N-dimensional array whose elements are all equal
+to the special constant used to designate missing values.
+
+Note that NA always compares not equal to NA (NA != NA).
+To find NA values, use the @code{isna} function.
+
+When called with no arguments, return a scalar with the value @samp{NA}.
+When called with a single argument, return a square matrix with the dimension
+specified.  When called with more than one scalar argument the first two
+arguments are taken as the number of rows and columns and any further
+arguments specify additional matrix dimensions.
+The optional argument @var{class} specifies the return type and may be
+either "double" or "single".
+ at seealso{isna}
+ at end deftypefn
+false
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} false (@var{x})
+ at deftypefnx {Built-in Function} {} false (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} false (@var{n}, @var{m}, @var{k}, @dots{})
+Return a matrix or N-dimensional array whose elements are all logical 0.
+The arguments are handled the same as the arguments for @code{eye}.
+ at end deftypefn
+true
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} true (@var{x})
+ at deftypefnx {Built-in Function} {} true (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} true (@var{n}, @var{m}, @var{k}, @dots{})
+Return a matrix or N-dimensional array whose elements are all logical 1.
+The arguments are handled the same as the arguments for @code{eye}.
+ at end deftypefn
+eye
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} eye (@var{x})
+ at deftypefnx {Built-in Function} {} eye (@var{n}, @var{m})
+ at deftypefnx {Built-in Function} {} eye (@dots{}, @var{class})
+Return an identity matrix.  If invoked with a single scalar argument,
+ at code{eye} returns a square matrix with the dimension specified.  If you
+supply two scalar arguments, @code{eye} takes them to be the number of
+rows and columns.  If given a vector with two elements, @code{eye} uses
+the values of the elements as the number of rows and columns,
+respectively.  For example,
+
+ at example
+ at group
+eye (3)
+     @result{}  1  0  0
+         0  1  0
+         0  0  1
+ at end group
+ at end example
+
+The following expressions all produce the same result:
+
+ at example
+ at group
+eye (2)
+ at equiv{}
+eye (2, 2)
+ at equiv{}
+eye (size ([1, 2; 3, 4])
+ at end group
+ at end example
+
+The optional argument @var{class}, allows @code{eye} to return an array of
+the specified type, like
+
+ at example
+val = zeros (n,m, "uint8")
+ at end example
+
+Calling @code{eye} with no arguments is equivalent to calling it
+with an argument of 1.  This odd definition is for compatibility
+with @sc{matlab}.
+ at end deftypefn
+linspace
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} linspace (@var{base}, @var{limit}, @var{n})
+Return a row vector with @var{n} linearly spaced elements between
+ at var{base} and @var{limit}.  If the number of elements is greater than one,
+then the @var{base} and @var{limit} are always included in
+the range.  If @var{base} is greater than @var{limit}, the elements are
+stored in decreasing order.  If the number of points is not specified, a
+value of 100 is used.
+
+The @code{linspace} function always returns a row vector.
+
+For compatibility with @sc{matlab}, return the second argument if
+fewer than two values are requested.
+ at end deftypefn
+resize
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} resize (@var{x}, @var{m})
+ at deftypefnx {Built-in Function} {} resize (@var{x}, @var{m}, @var{n})
+ at deftypefnx {Built-in Function} {} resize (@var{x}, @var{m}, @var{n}, @dots{})
+Resize @var{x} cutting off elements as necessary.
+
+In the result, element with certain indices is equal to the corresponding
+element of @var{x} if the indices are within the bounds of @var{x};
+otherwise, the element is set to zero.
+
+In other words, the statement
+
+ at example
+  y = resize (x, dv);
+ at end example
+
+ at noindent
+is equivalent to the following code:
+
+ at example
+ at group
+  y = zeros (dv, class (x));
+  sz = min (dv, size (x));
+  for i = 1:length (sz), idx@{i@} = 1:sz(i); endfor
+  y(idx@{:@}) = x(idx@{:@});
+ at end group
+ at end example
+
+ at noindent
+but is performed more efficiently.
+
+If only @var{m} is supplied and it is a scalar, the dimension of the
+result is @var{m}-by- at var{m}.  If @var{m} is a vector, then the
+dimensions of the result are given by the elements of @var{m}.
+If both @var{m} and @var{n} are scalars, then the dimensions of
+the result are @var{m}-by- at var{n}.
+
+An object can be resized to more dimensions than it has;
+in such case the missing dimensions are assumed to be 1.
+Resizing an object to fewer dimensions is not possible.
+ at seealso{reshape, postpad}
+ at end deftypefn
+reshape
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} reshape (@var{a}, @var{m}, @var{n}, @dots{})
+ at deftypefnx {Built-in Function} {} reshape (@var{a}, @var{size})
+Return a matrix with the given dimensions whose elements are taken
+from the matrix @var{a}.  The elements of the matrix are accessed in
+column-major order (like Fortran arrays are stored).
+
+For example,
+
+ at example
+ at group
+reshape ([1, 2, 3, 4], 2, 2)
+     @result{}  1  3
+         2  4
+ at end group
+ at end example
+
+ at noindent
+Note that the total number of elements in the original
+matrix must match the total number of elements in the new matrix.
+
+A single dimension of the return matrix can be unknown and is flagged
+by an empty argument.
+ at end deftypefn
+squeeze
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} squeeze (@var{x})
+Remove singleton dimensions from @var{x} and return the result.
+Note that for compatibility with @sc{matlab}, all objects have
+a minimum of two dimensions and row vectors are left unchanged.
+ at end deftypefn
+full
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{FM} =} full (@var{SM})
+ returns a full storage matrix from a sparse, diagonal, permutation matrix or a range.
+ at seealso{sparse}
+ at end deftypefn
+norm
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} norm (@var{a}, @var{p}, @var{opt})
+Compute the p-norm of the matrix @var{a}.  If the second argument is
+missing, @code{p = 2} is assumed.
+
+If @var{a} is a matrix (or sparse matrix):
+
+ at table @asis
+ at item @var{p} = @code{1}
+1-norm, the largest column sum of the absolute values of @var{a}.
+
+ at item @var{p} = @code{2}
+Largest singular value of @var{a}.
+
+ at item @var{p} = @code{Inf} or @code{"inf"}
+ at cindex infinity norm
+Infinity norm, the largest row sum of the absolute values of @var{a}.
+
+ at item @var{p} = @code{"fro"}
+ at cindex Frobenius norm
+Frobenius norm of @var{a}, @code{sqrt (sum (diag (@var{a}' * @var{a})))}.
+
+ at item other @var{p}, @code{@var{p} > 1}
+ at cindex general p-norm 
+maximum @code{norm (A*x, p)} such that @code{norm (x, p) == 1}
+ at end table
+
+If @var{a} is a vector or a scalar:
+
+ at table @asis
+ at item @var{p} = @code{Inf} or @code{"inf"}
+ at code{max (abs (@var{a}))}.
+
+ at item @var{p} = @code{-Inf}
+ at code{min (abs (@var{a}))}.
+
+ at item @var{p} = @code{"fro"}
+Frobenius norm of @var{a}, @code{sqrt (sumsq (abs (a)))}.
+
+ at item @var{p} = 0
+Hamming norm - the number of nonzero elements.
+
+ at item other @var{p}, @code{@var{p} > 1}
+p-norm of @var{a}, @code{(sum (abs (@var{a}) .^ @var{p})) ^ (1/@var{p})}.
+
+ at item other @var{p} @code{@var{p} < 1}
+the p-pseudonorm defined as above.
+ at end table
+
+If @code{"rows"} is given as @var{opt}, the norms of all rows of the matrix @var{a} are
+returned as a column vector.  Similarly, if @code{"columns"} or @code{"cols"} is passed
+column norms are computed.
+ at seealso{cond, svd}
+ at end deftypefn
+not
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} not (@var{x})
+This function is equivalent to @code{! x}.
+ at end deftypefn
+uplus
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} uplus (@var{x})
+This function is equivalent to @code{+ x}.
+ at end deftypefn
+uminus
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} uminus (@var{x})
+This function is equivalent to @code{- x}.
+ at end deftypefn
+transpose
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} transpose (@var{x})
+This function is equivalent to @code{x.'}.
+ at end deftypefn
+ctranspose
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ctranspose (@var{x})
+This function is equivalent to @code{x'}.
+ at end deftypefn
+plus
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} plus (@var{x}, @var{y})
+This function is equivalent to @code{x + y}.
+ at end deftypefn
+minus
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} minus (@var{x}, @var{y})
+This function is equivalent to @code{x - y}.
+ at end deftypefn
+mtimes
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mtimes (@var{x}, @var{y})
+This function is equivalent to @code{x * y}.
+ at end deftypefn
+mrdivide
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mrdivide (@var{x}, @var{y})
+This function is equivalent to @code{x / y}.
+ at end deftypefn
+mpower
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mpower (@var{x}, @var{y})
+This function is equivalent to @code{x ^ y}.
+ at end deftypefn
+mldivide
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mldivide (@var{x}, @var{y})
+This function is equivalent to @code{x \ y}.
+ at end deftypefn
+lt
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} lt (@var{x}, @var{y})
+This function is equivalent to @code{x < y}.
+ at end deftypefn
+le
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} le (@var{x}, @var{y})
+This function is equivalent to @code{x <= y}.
+ at end deftypefn
+eq
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} eq (@var{x}, @var{y})
+This function is equivalent to @code{x == y}.
+ at end deftypefn
+ge
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ge (@var{x}, @var{y})
+This function is equivalent to @code{x >= y}.
+ at end deftypefn
+gt
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} gt (@var{x}, @var{y})
+This function is equivalent to @code{x > y}.
+ at end deftypefn
+ne
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ne (@var{x}, @var{y})
+This function is equivalent to @code{x != y}.
+ at end deftypefn
+times
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} times (@var{x}, @var{y})
+This function is equivalent to @code{x .* y}.
+ at end deftypefn
+rdivide
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rdivide (@var{x}, @var{y})
+This function is equivalent to @code{x ./ y}.
+ at end deftypefn
+power
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} power (@var{x}, @var{y})
+This function is equivalent to @code{x .^ y}.
+ at end deftypefn
+ldivide
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ldivide (@var{x}, @var{y})
+This function is equivalent to @code{x .\ y}.
+ at end deftypefn
+and
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} and (@var{x}, @var{y})
+This function is equivalent to @code{x & y}.
+ at end deftypefn
+or
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} or (@var{x}, @var{y})
+This function is equivalent to @code{x | y}.
+ at end deftypefn
+tic
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} tic ()
+ at deftypefnx {Built-in Function} {} toc ()
+Set or check a wall-clock timer.  Calling @code{tic} without an
+output argument sets the timer.  Subsequent calls to @code{toc}
+return the number of seconds since the timer was set.  For example,
+
+ at example
+ at group
+tic ();
+# many computations later at dots{}
+elapsed_time = toc ();
+ at end group
+ at end example
+
+ at noindent
+will set the variable @code{elapsed_time} to the number of seconds since
+the most recent call to the function @code{tic}.
+
+If called with one output argument then this function returns a scalar
+of type @code{uint64} and the wall-clock timer is not started.
+
+ at example
+ at group
+t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6
+     @result{} 5
+ at end group
+ at end example
+
+Nested timing with @code{tic} and @code{toc} is not supported.
+Therefore @code{toc} will always return the elapsed time from the most
+recent call to @code{tic}.
+
+If you are more interested in the CPU time that your process used, you
+should use the @code{cputime} function instead.  The @code{tic} and
+ at code{toc} functions report the actual wall clock time that elapsed
+between the calls.  This may include time spent processing other jobs or
+doing nothing at all.  For example,
+
+ at example
+ at group
+tic (); sleep (5); toc ()
+     @result{} 5
+t = cputime (); sleep (5); cputime () - t
+     @result{} 0
+ at end group
+ at end example
+
+ at noindent
+(This example also illustrates that the CPU timer may have a fairly
+coarse resolution.)
+ at end deftypefn
+toc
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} toc ()
+See tic.
+ at end deftypefn
+cputime
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{total}, @var{user}, @var{system}] =} cputime ();
+Return the CPU time used by your Octave session.  The first output is
+the total time spent executing your process and is equal to the sum of
+second and third outputs, which are the number of CPU seconds spent
+executing in user mode and the number of CPU seconds spent executing in
+system mode, respectively.  If your system does not have a way to report
+CPU time usage, @code{cputime} returns 0 for each of its output values.
+Note that because Octave used some CPU time to start, it is reasonable
+to check to see if @code{cputime} works by checking to see if the total
+CPU time used is nonzero.
+ at end deftypefn
+sort
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{mode})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim}, @var{mode})
+Return a copy of @var{x} with the elements arranged in increasing
+order.  For matrices, @code{sort} orders the elements in each column.
+
+For example,
+
+ at example
+ at group
+sort ([1, 2; 2, 3; 3, 1])
+     @result{}  1  1
+         2  2
+         3  3
+ at end group
+ at end example
+
+The @code{sort} function may also be used to produce a matrix
+containing the original row indices of the elements in the sorted
+matrix.  For example,
+
+ at example
+ at group
+[s, i] = sort ([1, 2; 2, 3; 3, 1])
+     @result{} s = 1  1
+            2  2
+            3  3
+     @result{} i = 1  3
+            2  1
+            3  2
+ at end group
+ at end example
+
+If the optional argument @var{dim} is given, then the matrix is sorted
+along the dimension defined by @var{dim}.  The optional argument @code{mode}
+defines the order in which the values will be sorted.  Valid values of
+ at code{mode} are `ascend' or `descend'.
+
+For equal elements, the indices are such that the equal elements are listed
+in the order that appeared in the original list.
+
+The @code{sort} function may also be used to sort strings and cell arrays
+of strings, in which case the dictionary order of the strings is used.
+
+The algorithm used in @code{sort} is optimized for the sorting of partially
+ordered lists.
+ at end deftypefn
+__sort_rows_idx__
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __sort_rows_idx__ (@var{a}, @var{mode})
+Undocumented internal function.
+ at end deftypefn
+
+issorted
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} issorted (@var{a}, @var{rows})
+Returns true if the array is sorted, ascending or descending.
+NaNs are treated as by @code{sort}.  If @var{rows} is supplied and
+has the value "rows", checks whether the array is sorted by rows
+as if output by @code{sortrows} (with no options).
+
+This function does not yet support sparse matrices.
+ at seealso{sortrows, sort}
+ at end deftypefn
+
+__accumarray_sum__
+ at c data.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __accumarray_sum__ (@var{idx}, @var{vals}, @var{n})
+Undocumented internal function.
+ at end deftypefn
+dbstop
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{rline} =} dbstop (@var{func}, @var{line}, @dots{})
+Set a breakpoint in a function
+ at table @code
+ at item func
+String representing the function name.  When already in debug
+mode this should be left out and only the line should be given.
+ at item line
+Line number you would like the breakpoint to be set on.  Multiple
+lines might be given as separate arguments or as a vector.
+ at end table
+
+The rline returned is the real line that the breakpoint was set at.
+ at seealso{dbclear, dbstatus, dbstep}
+ at end deftypefn
+dbclear
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dbclear (@var{func}, @var{line}, @dots{})
+Delete a breakpoint in a function
+ at table @code
+ at item func
+String representing the function name.  When already in debug
+mode this should be left out and only the line should be given.
+ at item line
+Line number where you would like to remove the breakpoint.  Multiple
+lines might be given as separate arguments or as a vector.
+ at end table
+No checking is done to make sure that the line you requested is really
+a breakpoint.  If you get the wrong line nothing will happen.
+ at seealso{dbstop, dbstatus, dbwhere}
+ at end deftypefn
+dbstatus
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {lst =} dbstatus (@var{func})
+Return a vector containing the lines on which a function has 
+breakpoints set.
+ at table @code
+ at item func
+String representing the function name.  When already in debug
+mode this should be left out.
+ at end table
+ at seealso{dbclear, dbwhere}
+ at end deftypefn
+dbwhere
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dbwhere ()
+Show where we are in the code
+ at seealso{dbclear, dbstatus, dbstop}
+ at end deftypefn
+dbtype
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dbtype ()
+List script file with line numbers.
+ at seealso{dbclear, dbstatus, dbstop}
+ at end deftypefn
+dbstack
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{stack}, @var{idx}]} dbstack (@var{n})
+Print or return current stack information.  With optional argument
+ at var{n}, omit the @var{n} innermost stack frames.
+ at seealso{dbclear, dbstatus, dbstop}
+ at end deftypefn
+dbup
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dbup (@var{n})
+In debugging mode, move up the execution stack @var{n} frames.
+If @var{n} is omitted, move up one frame.
+ at seealso{dbstack}
+ at end deftypefn
+dbdown
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dbdown (@var{n})
+In debugging mode, move down the execution stack @var{n} frames.
+If @var{n} is omitted, move down one frame.
+ at seealso{dbstack}
+ at end deftypefn
+dbstep
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Command} {} dbstep @var{n}
+ at deftypefnx {Command} {} dbstep in
+ at deftypefnx {Command} {} dbstep out
+In debugging mode, execute the next @var{n} lines of code.  If @var{n} is
+omitted execute the next line of code.  If the next line of code is itself
+defined in terms of an m-file remain in the existing function.
+
+Using @code{dbstep in} will cause execution of the next line to step into
+any m-files defined on the next line.  Using @code{dbstep out} with cause
+execution to continue until the current function returns.
+ at seealso{dbcont, dbquit}
+ at end deftypefn
+dbcont
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Command} {} dbcont ()
+In debugging mode, quit debugging mode and continue execution.
+ at seealso{dbstep, dbstep}
+ at end deftypefn
+dbquit
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Command} {} dbquit ()
+In debugging mode, quit debugging mode and return to the top level.
+ at seealso{dbstep, dbcont}
+ at end deftypefn
+isdebugmode
+ at c debug.cc
+-*- texinfo -*-
+ at deftypefn {Command} {} isdebugmode ()
+Return true if debug mode is on, otherwise false.
+ at seealso{dbstack, dbclear, dbstop, dbstatus}
+ at end deftypefn
+EDITOR
+ at c defaults.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} EDITOR ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} EDITOR (@var{new_val})
+Query or set the internal variable that specifies the editor to
+use with the @code{edit_history} command.  The default value is taken from
+the environment variable @w{@code{EDITOR}} when Octave starts.  If the
+environment variable is not initialized, @w{@code{EDITOR}} will be set to
+ at code{"emacs"}.
+ at seealso{edit_history}
+ at end deftypefn
+EXEC_PATH
+ at c defaults.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} EXEC_PATH ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} EXEC_PATH (@var{new_val})
+Query or set the internal variable that specifies a colon separated
+list of directories to search when executing external programs.
+Its initial value is taken from the environment variable
+ at w{@code{OCTAVE_EXEC_PATH}} (if it exists) or @code{PATH}, but that
+value can be overridden by the command line argument
+ at code{--exec-path PATH}.  At startup, an additional set of
+directories (including the shell PATH) is appended to the path
+specified in the environment or on the command line.  If you use
+the @w{@code{EXEC_PATH}} function to modify the path, you should take
+care to preserve these additional directories.
+ at end deftypefn
+IMAGE_PATH
+ at c defaults.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} IMAGE_PATH ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} IMAGE_PATH (@var{new_val})
+Query or set the internal variable that specifies a colon separated
+list of directories in which to search for image files.
+ at end deftypefn
+OCTAVE_HOME
+ at c defaults.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} OCTAVE_HOME ()
+Return the name of the top-level Octave installation directory.
+ at end deftypefn
+OCTAVE_VERSION
+ at c defaults.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} OCTAVE_VERSION ()
+Return the version number of Octave, as a string.
+ at end deftypefn
+det
+ at c ./DLD-FUNCTIONS/det.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{d}, @var{rcond}] =} det (@var{a})
+Compute the determinant of @var{a} using @sc{lapack} for full and UMFPACK
+for sparse matrices.  Return an estimate of the reciprocal condition number
+if requested.
+ at end deftypefn
+cd
+ at c dirfns.cc
+-*- texinfo -*-
+ at deffn {Command} cd dir
+ at deffnx {Command} chdir dir
+Change the current working directory to @var{dir}.  If @var{dir} is
+omitted, the current directory is changed to the user's home
+directory.  For example,
+
+ at example
+cd ~/octave
+ at end example
+
+ at noindent
+Changes the current working directory to @file{~/octave}.  If the
+directory does not exist, an error message is printed and the working
+directory is not changed.
+ at seealso{mkdir, rmdir, dir}
+ at end deffn
+pwd
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} pwd ()
+Return the current working directory.
+ at seealso{dir, ls}
+ at end deftypefn
+readdir
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})
+Return names of the files in the directory @var{dir} as a cell array of
+strings.  If an error occurs, return an empty cell array in @var{files}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{dir, glob}
+ at end deftypefn
+mkdir
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{dir})
+ at deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{parent}, @var{dir})
+Create a directory named @var{dir} in the directory @var{parent}.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a
+system-dependent error message, and @var{msgid} contains a unique
+message identifier.
+ at seealso{rmdir}
+ at end deftypefn
+rmdir
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir})
+ at deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir}, @code{"s"})
+Remove the directory named @var{dir}.
+
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a
+system-dependent error message, and @var{msgid} contains a unique
+message identifier.
+
+If the optional second parameter is supplied with value @code{"s"},
+recursively remove all subdirectories as well.
+ at seealso{mkdir, confirm_recursive_rmdir}
+ at end deftypefn
+link
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})
+Create a new link (also known as a hard link) to an existing file.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{symlink}
+ at end deftypefn
+symlink
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})
+Create a symbolic link @var{new} which contains the string @var{old}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{link, readlink}
+ at end deftypefn
+readlink
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})
+Read the value of the symbolic link @var{symlink}.
+
+If successful, @var{result} contains the contents of the symbolic link
+ at var{symlink}, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{link, symlink}
+ at end deftypefn
+rename
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})
+Change the name of file @var{old} to @var{new}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at seealso{ls, dir}
+ at end deftypefn
+glob
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} glob (@var{pattern})
+Given an array of strings (as a char array or a cell array) in
+ at var{pattern}, return a cell array of file names that match any of
+them, or an empty cell array if no patterns match.  Tilde expansion
+is performed on each of the patterns before looking for matching file
+names.  For example,
+
+ at example
+ at group
+glob ("/vm*")
+     @result{} "/vmlinuz"
+ at end group
+ at end example
+ at seealso{dir, ls, stat, readdir}
+ at end deftypefn
+fnmatch
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})
+Return 1 or zero for each element of @var{string} that matches any of
+the elements of the string array @var{pattern}, using the rules of
+filename pattern matching.  For example,
+
+ at example
+ at group
+fnmatch ("a*b", @{"ab"; "axyzb"; "xyzab"@})
+     @result{} [ 1; 1; 0 ]
+ at end group
+ at end example
+ at end deftypefn
+filesep
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} filesep ()
+ at deftypefnx {Built-in Function} {} filesep ('all')
+Return the system-dependent character used to separate directory names.
+
+If 'all' is given, the function return all valid file separators in
+the form of a string.  The list of file separators is system-dependent.
+It is / (forward slash) under UNIX or Mac OS X, / and \ (forward and
+backward slashes) under Windows.
+ at seealso{pathsep, dir, ls}
+ at end deftypefn
+pathsep
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} pathsep ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} pathsep (@var{new_val})
+Query or set the character used to separate directories in
+a path.
+ at seealso{filesep, dir, ls}
+ at end deftypefn
+confirm_recursive_rmdir
+ at c dirfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} confirm_recursive_rmdir ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} confirm_recursive_rmdir (@var{new_val})
+Query or set the internal variable that controls whether Octave
+will ask for confirmation before recursively removing a directory tree.
+ at end deftypefn
+builtin
+ at c ./DLD-FUNCTIONS/dispatch.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@dots{}]} builtin (@var{f}, @dots{})
+Call the base function @var{f} even if @var{f} is overloaded to
+some other function for the given type signature.
+ at seealso{dispatch}
+ at end deftypefn
+dispatch
+ at c ./DLD-FUNCTIONS/dispatch.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} dispatch (@var{f}, @var{r}, @var{type})
+
+Replace the function @var{f} with a dispatch so that function @var{r}
+is called when @var{f} is called with the first argument of the named
+ at var{type}.  If the type is @var{any} then call @var{r} if no other type
+matches.  The original function @var{f} is accessible using
+ at code{builtin (@var{f}, @dots{})}.
+
+If @var{r} is omitted, clear dispatch function associated with @var{type}.
+
+If both @var{r} and @var{type} are omitted, list dispatch functions
+for @var{f}.
+ at seealso{builtin}
+ at end deftypefn
+dlmread
+ at c ./DLD-FUNCTIONS/dlmread.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{data} =} dlmread (@var{file})
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep})
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{r0}, @var{c0})
+ at deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{range})
+Read the matrix @var{data} from a text file.  If not defined the separator
+between fields is determined from the file itself.  Otherwise the
+separation character is defined by @var{sep}.
+
+Given two scalar arguments @var{r0} and @var{c0}, these define the starting
+row and column of the data to be read.  These values are indexed from zero,
+such that the first row corresponds to an index of zero.
+
+The @var{range} parameter must be a 4 element vector containing the upper
+left and lower right corner @code{[@var{R0}, at var{C0}, at var{R1}, at var{C1}]} or
+a spreadsheet style range such as 'A2..Q15'.  The lowest index value is zero.
+ at end deftypefn
+dmperm
+ at c ./DLD-FUNCTIONS/dmperm.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} dmperm (@var{s})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{q}, @var{r}, @var{s}] =} dmperm (@var{s})
+
+ at cindex Dulmage-Mendelsohn decomposition
+Perform a Dulmage-Mendelsohn permutation on the sparse matrix @var{s}.
+With a single output argument @dfn{dmperm} performs the row permutations
+ at var{p} such that @code{@var{s} (@var{p},:)} has no zero elements on the
+diagonal.
+
+Called with two or more output arguments, returns the row and column
+permutations, such that @code{@var{s} (@var{p}, @var{q})} is in block
+triangular form.  The values of @var{r} and @var{s} define the boundaries
+of the blocks.  If @var{s} is square then @code{@var{r} == @var{s}}.
+
+The method used is described in: A. Pothen & C.-J. Fan. Computing the block
+triangular form of a sparse matrix. ACM Trans. Math. Software,
+16(4):303-324, 1990.
+ at seealso{colamd, ccolamd}
+ at end deftypefn
+sprank
+ at c ./DLD-FUNCTIONS/dmperm.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} sprank (@var{s})
+
+ at cindex Structural Rank
+Calculates the structural rank of a sparse matrix @var{s}.  Note that
+only the structure of the matrix is used in this calculation based on
+a Dulmage-Mendelsohn permutation to block triangular form.  As such the numerical
+rank of the matrix @var{s} is bounded by @code{sprank (@var{s}) >=
+rank (@var{s})}.  Ignoring floating point errors @code{sprank (@var{s}) ==
+rank (@var{s})}.
+ at seealso{dmperm}
+ at end deftypefn
+eig
+ at c ./DLD-FUNCTIONS/eig.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {@var{lambda} =} eig (@var{a})
+ at deftypefnx {Loadable Function} {@var{lambda} =} eig (@var{a}, @var{b})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{lambda}] =} eig (@var{a})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{lambda}] =} eig (@var{a}, @var{b})
+The eigenvalues (and eigenvectors) of a matrix are computed in a several
+step process which begins with a Hessenberg decomposition, followed by a
+Schur decomposition, from which the eigenvalues are apparent.  The
+eigenvectors, when desired, are computed by further manipulations of the
+Schur decomposition.
+
+The eigenvalues returned by @code{eig} are not ordered.
+ at seealso{eigs}
+ at end deftypefn
+eigs
+ at c ./DLD-FUNCTIONS/eigs.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{d}} = eigs (@var{a})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{k}, @var{sigma}, at var{opts})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{a}, @var{b}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k}, @var{sigma})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Loadable Function} {@var{d}} = eigs (@var{af}, @var{n}, @var{b}, @var{k}, @var{sigma}, @var{opts})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}]} = eigs (@var{a}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}]} = eigs (@var{af}, @var{n}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}, @var{flag}]} = eigs (@var{a}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{v}, @var{d}, @var{flag}]} = eigs (@var{af}, @var{n}, @dots{})
+Calculate a limited number of eigenvalues and eigenvectors of @var{a},
+based on a selection criteria.  The number eigenvalues and eigenvectors to
+calculate is given by @var{k} whose default value is 6.
+
+By default @code{eigs} solve the equation
+ at iftex
+ at tex
+$A \nu = \lambda \nu$
+ at end tex
+ at end iftex
+ at ifinfo
+ at code{A * v = lambda * v}
+ at end ifinfo
+, where
+ at iftex
+ at tex
+$\lambda$ is a scalar representing one of the eigenvalues, and $\nu$
+ at end tex
+ at end iftex
+ at ifinfo
+ at code{lambda} is a scalar representing one of the eigenvalues, and @code{v}
+ at end ifinfo
+is the corresponding eigenvector.  If given the positive definite matrix
+ at var{B} then @code{eigs} solves the general eigenvalue equation
+ at iftex
+ at tex
+$A \nu = \lambda B \nu$
+ at end tex
+ at end iftex
+ at ifinfo
+ at code{A * v = lambda * B * v}
+ at end ifinfo
+.
+
+The argument @var{sigma} determines which eigenvalues are returned.
+ at var{sigma} can be either a scalar or a string.  When @var{sigma} is a scalar,
+the @var{k} eigenvalues closest to @var{sigma} are returned.  If @var{sigma}
+is a string, it must have one of the values
+
+ at table @asis
+ at item 'lm'
+Largest magnitude (default).
+
+ at item 'sm'
+Smallest magnitude.
+
+ at item 'la'
+Largest Algebraic (valid only for real symmetric problems).
+
+ at item 'sa'
+Smallest Algebraic (valid only for real symmetric problems).
+
+ at item 'be'
+Both ends, with one more from the high-end if @var{k} is odd (valid only for
+real symmetric problems).
+
+ at item 'lr'
+Largest real part (valid only for complex or unsymmetric problems).
+
+ at item 'sr'
+Smallest real part (valid only for complex or unsymmetric problems).
+
+ at item 'li'
+Largest imaginary part (valid only for complex or unsymmetric problems).
+
+ at item 'si'
+Smallest imaginary part (valid only for complex or unsymmetric problems).
+ at end table
+
+If @var{opts} is given, it is a structure defining some of the options that
+ at code{eigs} should use.  The fields of the structure @var{opts} are
+
+ at table @code
+ at item issym
+If @var{af} is given, then flags whether the function @var{af} defines a
+symmetric problem.  It is ignored if @var{a} is given.  The default is false.
+
+ at item isreal
+If @var{af} is given, then flags whether the function @var{af} defines a
+real problem.  It is ignored if @var{a} is given.  The default is true.
+
+ at item tol
+Defines the required convergence tolerance, given as @code{tol * norm (A)}.
+The default is @code{eps}.
+
+ at item maxit
+The maximum number of iterations.  The default is 300.
+
+ at item p
+The number of Lanzcos basis vectors to use.  More vectors will result in
+faster convergence, but a larger amount of memory.  The optimal value of 'p'
+is problem dependent and should be in the range @var{k} to @var{n}.  The
+default value is @code{2 * @var{k}}.
+
+ at item v0
+The starting vector for the computation.  The default is to have @sc{Arpack}
+randomly generate a starting vector.
+
+ at item disp
+The level of diagnostic printout.  If @code{disp} is 0 then there is no
+printout.  The default value is 1.
+
+ at item cholB
+Flag if @code{chol (@var{b})} is passed rather than @var{b}.  The default is
+false.
+
+ at item permB
+The permutation vector of the Cholesky factorization of @var{b} if
+ at code{cholB} is true.  That is @code{chol ( @var{b} (permB, permB))}.  The
+default is @code{1:@var{n}}.
+
+ at end table
+
+It is also possible to represent @var{a} by a function denoted @var{af}.
+ at var{af} must be followed by a scalar argument @var{n} defining the length
+of the vector argument accepted by @var{af}.  @var{af} can be passed either
+as an inline function, function handle or as a string.  In the case where
+ at var{af} is passed as a string, the name of the string defines the function
+to use.
+
+ at var{af} is a function of the form @code{function y = af (x), y = @dots{};
+endfunction}, where the required return value of @var{af} is determined by
+the value of @var{sigma}, and are
+
+ at table @code
+ at item A * x
+If @var{sigma} is not given or is a string other than 'sm'.
+
+ at item A \ x
+If @var{sigma} is 'sm'.
+
+ at item (A - sigma * I) \ x
+for standard eigenvalue problem, where @code{I} is the identity matrix of
+the same size as @code{A}.  If @var{sigma} is zero, this reduces the
+ at code{A \ x}.
+
+ at item (A - sigma * B) \ x
+for the general eigenvalue problem.
+ at end table
+
+The return arguments of @code{eigs} depends on the number of return
+arguments.  With a single return argument, a vector @var{d} of length @var{k}
+is returned, represent the @var{k} eigenvalues that have been found.  With two
+return arguments, @var{v} is a @var{n}-by- at var{k} matrix whose columns are
+the @var{k} eigenvectors corresponding to the returned eigenvalues.  The
+eigenvalues themselves are then returned in @var{d} in the form of a
+ at var{n}-by- at var{k} matrix, where the elements on the diagonal are the
+eigenvalues.
+
+Given a third return argument @var{flag}, @code{eigs} also returns the status
+of the convergence.  If @var{flag} is 0, then all eigenvalues have converged,
+otherwise not.
+
+This function is based on the @sc{Arpack} package, written by R Lehoucq,
+K Maschhoff, D Sorensen and C Yang.  For more information see
+ at url{http://www.caam.rice.edu/software/ARPACK/}.
+
+ at end deftypefn
+ at seealso{eig, svds}
+rethrow
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rethrow (@var{err})
+Reissues a previous error as defined by @var{err}.  @var{err} is a structure
+that must contain at least the 'message' and 'identifier' fields.  @var{err}
+can also contain a field 'stack' that gives information on the assumed
+location of the error.  Typically @var{err} is returned from
+ at code{lasterror}.
+ at seealso{lasterror, lasterr, error}
+ at end deftypefn
+error
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} error (@var{template}, @dots{})
+ at deftypefnx {Built-in Function} {} error (@var{id}, @var{template}, @dots{})
+Format the optional arguments under the control of the template string
+ at var{template} using the same rules as the @code{printf} family of
+functions (@pxref{Formatted Output}) and print the resulting message
+on the @code{stderr} stream.  The message is prefixed by the character
+string @samp{error: }.
+
+Calling @code{error} also sets Octave's internal error state such that
+control will return to the top level without evaluating any more
+commands.  This is useful for aborting from functions or scripts.
+
+If the error message does not end with a new line character, Octave will
+print a traceback of all the function calls leading to the error.  For
+example, given the following function definitions:
+
+ at example
+ at group
+function f () g (); end
+function g () h (); end
+function h () nargin == 1 || error ("nargin != 1"); end
+ at end group
+ at end example
+
+ at noindent
+calling the function @code{f} will result in a list of messages that
+can help you to quickly locate the exact location of the error:
+
+ at example
+ at group
+f ()
+error: nargin != 1
+error: called from:
+error:   error at line -1, column -1
+error:   h at line 1, column 27
+error:   g at line 1, column 15
+error:   f at line 1, column 15
+ at end group
+ at end example
+
+If the error message ends in a new line character, Octave will print the
+message but will not display any traceback messages as it returns
+control to the top level.  For example, modifying the error message
+in the previous example to end in a new line causes Octave to only print
+a single message:
+
+ at example
+ at group
+function h () nargin == 1 || error ("nargin != 1\n"); end
+f ()
+error: nargin != 1
+ at end group
+ at end example
+ at end deftypefn
+warning
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} warning (@var{template}, @dots{})
+ at deftypefnx {Built-in Function} {} warning (@var{id}, @var{template}, @dots{})
+Format the optional arguments under the control of the template string
+ at var{template} using the same rules as the @code{printf} family of
+functions (@pxref{Formatted Output}) and print the resulting message
+on the @code{stderr} stream.  The message is prefixed by the character
+string @samp{warning: }.
+You should use this function when you want to notify the user
+of an unusual condition, but only when it makes sense for your program
+to go on.
+
+The optional message identifier allows users to enable or disable
+warnings tagged by @var{id}.  The special identifier @samp{"all"} may
+be used to set the state of all warnings.
+
+ at deftypefnx {Built-in Function} {} warning ("on", @var{id})
+ at deftypefnx {Built-in Function} {} warning ("off", @var{id})
+ at deftypefnx {Built-in Function} {} warning ("error", @var{id})
+ at deftypefnx {Built-in Function} {} warning ("query", @var{id})
+Set or query the state of a particular warning using the identifier
+ at var{id}.  If the identifier is omitted, a value of @samp{"all"} is
+assumed.  If you set the state of a warning to @samp{"error"}, the
+warning named by @var{id} is handled as if it were an error instead.
+ at seealso{warning_ids}
+ at end deftypefn
+lasterror
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{err} =} lasterror (@var{err})
+ at deftypefnx {Built-in Function} {} lasterror ('reset')
+Returns or sets the last error message.  Called without any arguments
+returns a structure containing the last error message, as well as other
+information related to this error.  The elements of this structure are:
+
+ at table @asis
+ at item 'message'
+The text of the last error message
+ at item 'identifier'
+The message identifier of this error message
+ at item 'stack'
+A structure containing information on where the message occurred.  This might
+be an empty structure if this in the case where this information cannot
+be obtained.  The fields of this structure are:
+
+ at table @asis
+ at item 'file'
+The name of the file where the error occurred
+ at item 'name'
+The name of function in which the error occurred
+ at item 'line'
+The line number at which the error occurred
+ at item 'column'
+An optional field with the column number at which the error occurred
+ at end table
+ at end table
+
+The @var{err} structure may also be passed to @code{lasterror} to set the
+information about the last error.  The only constraint on @var{err} in that
+case is that it is a scalar structure.  Any fields of @var{err} that match
+the above are set to the value passed in @var{err}, while other fields are
+set to their default values.
+
+If @code{lasterror} is called with the argument 'reset', all values take
+their default values.
+ at end deftypefn
+lasterr
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lasterr (@var{msg}, @var{msgid})
+Without any arguments, return the last error message.  With one
+argument, set the last error message to @var{msg}.  With two arguments,
+also set the last message identifier.
+ at end deftypefn
+lastwarn
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lastwarn (@var{msg}, @var{msgid})
+Without any arguments, return the last warning message.  With one
+argument, set the last warning message to @var{msg}.  With two arguments,
+also set the last message identifier.
+ at end deftypefn
+usage
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} usage (@var{msg})
+Print the message @var{msg}, prefixed by the string @samp{usage: }, and
+set Octave's internal error state such that control will return to the
+top level without evaluating any more commands.  This is useful for
+aborting from functions.
+
+After @code{usage} is evaluated, Octave will print a traceback of all
+the function calls leading to the usage message.
+
+You should use this function for reporting problems errors that result
+from an improper call to a function, such as calling a function with an
+incorrect number of arguments, or with arguments of the wrong type.  For
+example, most functions distributed with Octave begin with code like
+this
+
+ at example
+ at group
+if (nargin != 2)
+  usage ("foo (a, b)");
+endif
+ at end group
+ at end example
+
+ at noindent
+to check for the proper number of arguments.
+ at end deftypefn
+beep_on_error
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} beep_on_error ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} beep_on_error (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to ring the terminal bell before printing an error message.
+ at end deftypefn
+debug_on_error
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_error ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_error (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to enter the debugger when an error is encountered.  This will also
+inhibit printing of the normal traceback message (you will only see
+the top-level error message).
+ at end deftypefn
+debug_on_warning
+ at c error.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_warning ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_warning (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to enter the debugger when a warning is encountered.
+ at end deftypefn
+fft
+ at c ./DLD-FUNCTIONS/fft.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} fft (@var{a}, @var{n}, @var{dim})
+Compute the FFT of @var{a} using subroutines from
+ at sc{fftw}.  The FFT is calculated along the first non-singleton dimension of the
+array.  Thus if @var{a} is a matrix, @code{fft (@var{a})} computes the
+FFT for each column of @var{a}.
+
+If called with two arguments, @var{n} is expected to be an integer
+specifying the number of elements of @var{a} to use, or an empty
+matrix to specify that its value should be ignored.  If @var{n} is
+larger than the dimension along which the FFT is calculated, then
+ at var{a} is resized and padded with zeros.  Otherwise, if @var{n} is
+smaller than the dimension along which the FFT is calculated, then
+ at var{a} is truncated.
+
+If called with three arguments, @var{dim} is an integer specifying the
+dimension of the matrix along which the FFT is performed
+ at seealso{ifft, fft2, fftn, fftw}
+ at end deftypefn
+ifft
+ at c ./DLD-FUNCTIONS/fft.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} ifft (@var{a}, @var{n}, @var{dim})
+Compute the inverse FFT of @var{a} using subroutines from
+ at sc{fftw}.  The inverse FFT is calculated along the first non-singleton dimension
+of the array.  Thus if @var{a} is a matrix, @code{fft (@var{a})} computes
+the inverse FFT for each column of @var{a}.
+
+If called with two arguments, @var{n} is expected to be an integer
+specifying the number of elements of @var{a} to use, or an empty
+matrix to specify that its value should be ignored.  If @var{n} is
+larger than the dimension along which the inverse FFT is calculated, then
+ at var{a} is resized and padded with zeros.  Otherwise, if at var{n} is
+smaller than the dimension along which the inverse FFT is calculated,
+then @var{a} is truncated.
+
+If called with three arguments, @var{dim} is an integer specifying the
+dimension of the matrix along which the inverse FFT is performed
+ at seealso{fft, ifft2, ifftn, fftw}
+ at end deftypefn
+fft2
+ at c ./DLD-FUNCTIONS/fft2.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} fft2 (@var{a}, @var{n}, @var{m})
+Compute the two-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional arguments @var{n} and @var{m} may be used specify the
+number of rows and columns of @var{a} to use.  If either of these is
+larger than the size of @var{a}, @var{a} is resized and padded with
+zeros.
+
+If @var{a} is a multi-dimensional matrix, each two-dimensional sub-matrix
+of @var{a} is treated separately
+ at seealso {ifft2, fft, fftn, fftw}
+ at end deftypefn
+ifft2
+ at c ./DLD-FUNCTIONS/fft2.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} fft2 (@var{a}, @var{n}, @var{m})
+Compute the inverse two-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional arguments @var{n} and @var{m} may be used specify the
+number of rows and columns of @var{a} to use.  If either of these is
+larger than the size of @var{a}, @var{a} is resized and padded with
+zeros.
+
+If @var{a} is a multi-dimensional matrix, each two-dimensional sub-matrix
+of @var{a} is treated separately
+ at seealso {fft2, ifft, ifftn, fftw}
+ at end deftypefn
+fftn
+ at c ./DLD-FUNCTIONS/fftn.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} fftn (@var{a}, @var{size})
+Compute the N-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional vector argument @var{size} may be used specify the
+dimensions of the array to be used.  If an element of @var{size} is
+smaller than the corresponding dimension, then the dimension is
+truncated prior to performing the FFT.  Otherwise if an element
+of @var{size} is larger than the corresponding dimension @var{a}
+is resized and padded with zeros.
+ at seealso {ifftn, fft, fft2, fftw}
+ at end deftypefn
+ifftn
+ at c ./DLD-FUNCTIONS/fftn.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} ifftn (@var{a}, @var{size})
+Compute the inverse N-dimensional FFT of @var{a} using subroutines from
+ at sc{fftw}.  The optional vector argument @var{size} may be used specify the
+dimensions of the array to be used.  If an element of @var{size} is
+smaller than the corresponding dimension, then the dimension is
+truncated prior to performing the inverse FFT.  Otherwise if an element
+of @var{size} is larger than the corresponding dimension @var{a}
+is resized and padded with zeros.
+ at seealso {fftn, ifft, ifft2, fftw}
+ at end deftypefn
+fftw
+ at c ./DLD-FUNCTIONS/fftw.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{method} =} fftw ('planner')
+ at deftypefnx {Loadable Function} {} fftw ('planner', @var{method})
+ at deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom')
+ at deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom', @var{wisdom})
+
+Manage @sc{fftw} wisdom data.  Wisdom data can be used to significantly
+accelerate the calculation of the FFTs but implies an initial cost
+in its calculation.  When the @sc{fftw} libraries are initialized, they read
+a system wide wisdom file (typically in @file{/etc/fftw/wisdom}), allowing wisdom
+to be shared between applications other than Octave.  Alternatively, the
+ at code{fftw} function can be used to import wisdom.  For example
+
+ at example
+ at var{wisdom} = fftw ('dwisdom')
+ at end example
+
+will save the existing wisdom used by Octave to the string @var{wisdom}.
+This string can then be saved to a file and restored using the @code{save}
+and @code{load} commands respectively.  This existing wisdom can be reimported
+as follows
+
+ at example
+fftw ('dwisdom', @var{wisdom})
+ at end example 
+
+If @var{wisdom} is an empty matrix, then the wisdom used is cleared.
+
+During the calculation of Fourier transforms further wisdom is generated.
+The fashion in which this wisdom is generated is equally controlled by
+the @code{fftw} function.  There are five different manners in which the
+wisdom can be treated, these being
+
+ at table @asis
+ at item 'estimate'
+This specifies that no run-time measurement of the optimal means of
+calculating a particular is performed, and a simple heuristic is used
+to pick a (probably sub-optimal) plan.  The advantage of this method is
+that there is little or no overhead in the generation of the plan, which
+is appropriate for a Fourier transform that will be calculated once.
+
+ at item 'measure'
+In this case a range of algorithms to perform the transform is considered
+and the best is selected based on their execution time.
+
+ at item 'patient'
+This is like 'measure', but a wider range of algorithms is considered.
+
+ at item 'exhaustive'
+This is like 'measure', but all possible algorithms that may be used to
+treat the transform are considered.
+
+ at item 'hybrid'
+As run-time measurement of the algorithm can be expensive, this is a
+compromise where 'measure' is used for transforms up to the size of 8192
+and beyond that the 'estimate' method is used.
+ at end table
+
+The default method is 'estimate', and the method currently being used can
+be probed with
+
+ at example
+ at var{method} = fftw ('planner')
+ at end example
+
+and the method used can be set using
+
+ at example
+fftw ('planner', @var{method})
+ at end example
+
+Note that calculated wisdom will be lost when restarting Octave.  However,
+the wisdom data can be reloaded if it is saved to a file as described
+above.  Saved wisdom files should not be used on different platforms since
+they will not be efficient and the point of calculating the wisdom is lost.
+ at seealso{fft, ifft, fft2, ifft2, fftn, ifftn}
+ at end deftypefn
+fclose
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fclose (@var{fid})
+Closes the specified file.  If successful, @code{fclose} returns 0,
+otherwise, it returns -1.
+ at seealso{fopen, fseek, ftell}
+ at end deftypefn
+fclear
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fclear (@var{fid})
+Clear the stream state for the specified file.
+ at end deftypefn
+fflush
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fflush (@var{fid})
+Flush output to @var{fid}.  This is useful for ensuring that all
+pending output makes it to the screen before some other event occurs.
+For example, it is always a good idea to flush the standard output
+stream before calling @code{input}.
+
+ at code{fflush} returns 0 on success and an OS dependent error value
+(@minus{}1 on unix) on error.
+ at seealso{fopen, fclose}
+ at end deftypefn
+fgetl
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fgetl (@var{fid}, @var{len})
+Read characters from a file, stopping after a newline, or EOF,
+or @var{len} characters have been read.  The characters read, excluding
+the possible trailing newline, are returned as a string.
+
+If @var{len} is omitted, @code{fgetl} reads until the next newline
+character.
+
+If there are no more characters to read, @code{fgetl} returns @minus{}1.
+ at seealso{fread, fscanf}
+ at end deftypefn
+fgets
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fgets (@var{fid}, @var{len})
+Read characters from a file, stopping after a newline, or EOF,
+or @var{len} characters have been read.  The characters read, including
+the possible trailing newline, are returned as a string.
+
+If @var{len} is omitted, @code{fgets} reads until the next newline
+character.
+
+If there are no more characters to read, @code{fgets} returns @minus{}1.
+ at seealso{fputs, fopen, fread, fscanf}
+ at end deftypefn
+fopen
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})
+ at deftypefnx {Built-in Function} {@var{fid_list} =} fopen ("all")
+ at deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})
+The first form of the @code{fopen} function opens the named file with
+the specified mode (read-write, read-only, etc.) and architecture
+interpretation (IEEE big endian, IEEE little endian, etc.), and returns
+an integer value that may be used to refer to the file later.  If an
+error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the
+corresponding system error message.  The @var{mode} is a one or two
+character string that specifies whether the file is to be opened for
+reading, writing, or both.
+
+The second form of the @code{fopen} function returns a vector of file ids
+corresponding to all the currently open files, excluding the
+ at code{stdin}, @code{stdout}, and @code{stderr} streams.
+
+The third form of the @code{fopen} function returns information about the
+open file given its file id.
+
+For example,
+
+ at example
+myfile = fopen ("splat.dat", "r", "ieee-le");
+ at end example
+
+ at noindent
+opens the file @file{splat.dat} for reading.  If necessary, binary
+numeric values will be read assuming they are stored in IEEE format with
+the least significant bit first, and then converted to the native
+representation.
+
+Opening a file that is already open simply opens it again and returns a
+separate file id.  It is not an error to open a file several times,
+though writing to the same file through several different file ids may
+produce unexpected results.
+
+The possible values @samp{mode} may have are
+
+ at table @asis
+ at item @samp{r}
+Open a file for reading.
+
+ at item @samp{w}
+Open a file for writing.  The previous contents are discarded.
+
+ at item @samp{a}
+Open or create a file for writing at the end of the file.
+
+ at item @samp{r+}
+Open an existing file for reading and writing.
+
+ at item @samp{w+}
+Open a file for reading or writing.  The previous contents are
+discarded.
+
+ at item @samp{a+}
+Open or create a file for reading or writing at the end of the
+file.
+ at end table
+
+Append a "t" to the mode string to open the file in text mode or a
+"b" to open in binary mode.  On Windows and Macintosh systems, text
+mode reading and writing automatically converts linefeeds to the
+appropriate line end character for the system (carriage-return linefeed
+on Windows, carriage-return on Macintosh).  The default if no mode is
+specified is binary mode.
+
+Additionally, you may append a "z" to the mode string to open a
+gzipped file for reading or writing.  For this to be successful, you
+must also open the file in binary mode.
+
+The parameter @var{arch} is a string specifying the default data format
+for the file.  Valid values for @var{arch} are:
+
+ at table @asis
+ at samp{native}
+The format of the current machine (this is the default).
+
+ at samp{ieee-be}
+IEEE big endian format.
+
+ at samp{ieee-le}
+IEEE little endian format.
+
+ at samp{vaxd}
+VAX D floating format.
+
+ at samp{vaxg}
+VAX G floating format.
+
+ at samp{cray}
+Cray floating format.
+ at end table
+
+ at noindent
+however, conversions are currently only supported for @samp{native}
+ at samp{ieee-be}, and @samp{ieee-le} formats.
+ at seealso{fclose, fgets, fputs, fread, fseek, ferror, fprintf, fscanf, ftell, fwrite}
+ at end deftypefn
+freport
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} freport ()
+Print a list of which files have been opened, and whether they are open
+for reading, writing, or both.  For example,
+
+ at example
+ at group
+freport ()
+
+     @print{}  number  mode  name
+     @print{} 
+     @print{}       0     r  stdin
+     @print{}       1     w  stdout
+     @print{}       2     w  stderr
+     @print{}       3     r  myfile
+ at end group
+ at end example
+ at end deftypefn
+frewind
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} frewind (@var{fid})
+Move the file pointer to the beginning of the file @var{fid}, returning
+0 for success, and -1 if an error was encountered.  It is equivalent to
+ at code{fseek (@var{fid}, 0, SEEK_SET)}.
+ at end deftypefn
+fseek
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})
+Set the file pointer to any location within the file @var{fid}.
+
+The pointer is positioned @var{offset} characters from the @var{origin},
+which may be one of the predefined variables @w{@code{SEEK_CUR}} (current
+position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of
+file) or strings "cof", "bof" or "eof".  If @var{origin} is omitted,
+ at w{@code{SEEK_SET}} is assumed.  The offset must be zero, or a value returned
+by @code{ftell} (in which case @var{origin} must be @w{@code{SEEK_SET}}).
+
+Return 0 on success and -1 on error.
+ at seealso{ftell, fopen, fclose}
+ at end deftypefn
+ftell
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ftell (@var{fid})
+Return the position of the file pointer as the number of characters
+from the beginning of the file @var{fid}.
+ at seealso{fseek, fopen, fclose}
+ at end deftypefn
+fprintf
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})
+This function is just like @code{printf}, except that the output is
+written to the stream @var{fid} instead of @code{stdout}.
+If @var{fid} is omitted, the output is written to @code{stdout}.
+ at seealso{printf, sprintf, fread, fscanf, fopen, fclose}
+ at end deftypefn
+printf
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} printf (@var{template}, @dots{})
+Print optional arguments under the control of the template string
+ at var{template} to the stream @code{stdout} and return the number of
+characters printed.
+ at ifclear OCTAVE_MANUAL
+
+See the Formatted Output section of the GNU Octave manual for a
+complete description of the syntax of the template string.
+ at end ifclear
+ at seealso{fprintf, sprintf, scanf}
+ at end deftypefn
+fputs
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})
+Write a string to a file with no formatting.
+
+Return a non-negative number on success and EOF on error.
+ at seealso{scanf, sscanf, fread, fprintf, fgets, fscanf}
+ at end deftypefn
+puts
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} puts (@var{string})
+Write a string to the standard output with no formatting.
+
+Return a non-negative number on success and EOF on error.
+ at end deftypefn
+sprintf
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})
+This is like @code{printf}, except that the output is returned as a
+string.  Unlike the C library function, which requires you to provide a
+suitably sized string as an argument, Octave's @code{sprintf} function
+returns the string, automatically sized to hold all of the items
+converted.
+ at seealso{printf, fprintf, sscanf}
+ at end deftypefn
+fscanf
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{size})
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} fscanf (@var{fid}, @var{template}, "C")
+In the first form, read from @var{fid} according to @var{template},
+returning the result in the matrix @var{val}.
+
+The optional argument @var{size} specifies the amount of data to read
+and may be one of
+
+ at table @code
+ at item Inf
+Read as much as possible, returning a column vector.
+
+ at item @var{nr}
+Read up to @var{nr} elements, returning a column vector.
+
+ at item [@var{nr}, Inf]
+Read as much as possible, returning a matrix with @var{nr} rows.  If the
+number of elements read is not an exact multiple of @var{nr}, the last
+column is padded with zeros.
+
+ at item [@var{nr}, @var{nc}]
+Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with
+ at var{nr} rows.  If the number of elements read is not an exact multiple
+of @var{nr}, the last column is padded with zeros.
+ at end table
+
+ at noindent
+If @var{size} is omitted, a value of @code{Inf} is assumed.
+
+A string is returned if @var{template} specifies only character
+conversions.
+
+The number of items successfully read is returned in @var{count}.
+
+In the second form, read from @var{fid} according to @var{template},
+with each conversion specifier in @var{template} corresponding to a
+single scalar return value.  This form is more `C-like', and also
+compatible with previous versions of Octave.  The number of successful
+conversions is returned in @var{count}
+ at ifclear OCTAVE_MANUAL
+
+See the Formatted Input section of the GNU Octave manual for a
+complete description of the syntax of the template string.
+ at end ifclear
+ at seealso{scanf, sscanf, fread, fprintf, fgets, fputs}
+ at end deftypefn
+sscanf
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{size})
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} sscanf (@var{string}, @var{template}, "C")
+This is like @code{fscanf}, except that the characters are taken from the
+string @var{string} instead of from a stream.  Reaching the end of the
+string is treated as an end-of-file condition.
+ at seealso{fscanf, scanf, sprintf}
+ at end deftypefn
+scanf
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} scanf (@var{template}, @var{size})
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] =} scanf (@var{template}, "C")
+This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.
+
+It is currently not useful to call @code{scanf} in interactive
+programs.
+ at seealso{fscanf, sscanf, printf}
+ at end deftypefn
+fread
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})
+Read binary data of type @var{precision} from the specified file ID
+ at var{fid}.
+
+The optional argument @var{size} specifies the amount of data to read
+and may be one of
+
+ at table @code
+ at item Inf
+Read as much as possible, returning a column vector.
+
+ at item @var{nr}
+Read up to @var{nr} elements, returning a column vector.
+
+ at item [@var{nr}, Inf]
+Read as much as possible, returning a matrix with @var{nr} rows.  If the
+number of elements read is not an exact multiple of @var{nr}, the last
+column is padded with zeros.
+
+ at item [@var{nr}, @var{nc}]
+Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with
+ at var{nr} rows.  If the number of elements read is not an exact multiple
+of @var{nr}, the last column is padded with zeros.
+ at end table
+
+ at noindent
+If @var{size} is omitted, a value of @code{Inf} is assumed.
+
+The optional argument @var{precision} is a string specifying the type of
+data to read and may be one of
+
+ at table @code
+ at item "schar"
+ at itemx "signed char"
+Signed character.
+
+ at item "uchar"
+ at itemx "unsigned char"
+Unsigned character.
+
+ at item "int8"
+ at itemx "integer*1"
+
+8-bit signed integer.
+
+ at item "int16"
+ at itemx "integer*2"
+16-bit signed integer.
+
+ at item "int32"
+ at itemx "integer*4"
+32-bit signed integer.
+
+ at item "int64"
+ at itemx "integer*8"
+64-bit signed integer.
+
+ at item "uint8"
+8-bit unsigned integer.
+
+ at item "uint16"
+16-bit unsigned integer.
+
+ at item "uint32"
+32-bit unsigned integer.
+
+ at item "uint64"
+64-bit unsigned integer.
+
+ at item "single"
+ at itemx "float32"
+ at itemx "real*4"
+32-bit floating point number.
+
+ at item "double"
+ at itemx "float64"
+ at itemx "real*8"
+64-bit floating point number.
+
+ at item "char"
+ at itemx "char*1"
+Single character.
+
+ at item "short"
+Short integer (size is platform dependent).
+
+ at item "int"
+Integer (size is platform dependent).
+
+ at item "long"
+Long integer (size is platform dependent).
+
+ at item "ushort"
+ at itemx "unsigned short"
+Unsigned short integer (size is platform dependent).
+
+ at item "uint"
+ at itemx "unsigned int"
+Unsigned integer (size is platform dependent).
+
+ at item "ulong"
+ at itemx "unsigned long"
+Unsigned long integer (size is platform dependent).
+
+ at item "float"
+Single precision floating point number (size is platform dependent).
+ at end table
+
+ at noindent
+The default precision is @code{"uchar"}.
+
+The @var{precision} argument may also specify an optional repeat
+count.  For example, @samp{32*single} causes @code{fread} to read
+a block of 32 single precision floating point numbers.  Reading in
+blocks is useful in combination with the @var{skip} argument.
+
+The @var{precision} argument may also specify a type conversion.
+For example, @samp{int16=>int32} causes @code{fread} to read 16-bit
+integer values and return an array of 32-bit integer values.  By
+default, @code{fread} returns a double precision array.  The special
+form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.
+
+The conversion and repeat counts may be combined.  For example, the
+specification @samp{32*single=>single} causes @code{fread} to read
+blocks of single precision floating point values and return an array
+of single precision values instead of the default array of double
+precision values.
+
+The optional argument @var{skip} specifies the number of bytes to skip
+after each element (or block of elements) is read.  If it is not
+specified, a value of 0 is assumed.  If the final block read is not
+complete, the final skip is omitted.  For example,
+
+ at example
+fread (f, 10, "3*single=>single", 8)
+ at end example
+
+ at noindent
+will omit the final 8-byte skip because the last read will not be
+a complete block of 3 values.
+
+The optional argument @var{arch} is a string specifying the data format
+for the file.  Valid values are
+
+ at table @code
+ at item "native"
+The format of the current machine.
+
+ at item "ieee-be"
+IEEE big endian.
+
+ at item "ieee-le"
+IEEE little endian.
+
+ at item "vaxd"
+VAX D floating format.
+
+ at item "vaxg"
+VAX G floating format.
+
+ at item "cray"
+Cray floating format.
+ at end table
+
+ at noindent
+Conversions are currently only supported for @code{"ieee-be"} and
+ at code{"ieee-le"} formats.
+
+The data read from the file is returned in @var{val}, and the number of
+values read is returned in @code{count}
+ at seealso{fwrite, fopen, fclose}
+ at end deftypefn
+fwrite
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})
+Write data in binary form of type @var{precision} to the specified file
+ID @var{fid}, returning the number of values successfully written to the
+file.
+
+The argument @var{data} is a matrix of values that are to be written to
+the file.  The values are extracted in column-major order.
+
+The remaining arguments @var{precision}, @var{skip}, and @var{arch} are
+optional, and are interpreted as described for @code{fread}.
+
+The behavior of @code{fwrite} is undefined if the values in @var{data}
+are too large to fit in the specified precision.
+ at seealso{fread, fopen, fclose}
+ at end deftypefn
+feof
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} feof (@var{fid})
+Return 1 if an end-of-file condition has been encountered for a given
+file and 0 otherwise.  Note that it will only return 1 if the end of the
+file has already been encountered, not if the next read operation will
+result in an end-of-file condition.
+ at seealso{fread, fopen, fclose}
+ at end deftypefn
+ferror
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ferror (@var{fid})
+Return 1 if an error condition has been encountered for a given file
+and 0 otherwise.  Note that it will only return 1 if an error has
+already been encountered, not if the next operation will result in an
+error condition.
+ at end deftypefn
+popen
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})
+Start a process and create a pipe.  The name of the command to run is
+given by @var{command}.  The file identifier corresponding to the input
+or output stream of the process is returned in @var{fid}.  The argument
+ at var{mode} may be
+
+ at table @code
+ at item "r"
+The pipe will be connected to the standard output of the process, and
+open for reading.
+
+ at item "w"
+The pipe will be connected to the standard input of the process, and
+open for writing.
+ at end table
+
+For example,
+
+ at example
+ at group
+fid = popen ("ls -ltr / | tail -3", "r");
+while (ischar (s = fgets (fid)))
+  fputs (stdout, s);
+endwhile
+     @print{} drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc
+     @print{} drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib
+     @print{} drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp
+ at end group
+ at end example
+ at end deftypefn
+pclose
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} pclose (@var{fid})
+Close a file identifier that was opened by @code{popen}.  You may also
+use @code{fclose} for the same purpose.
+ at end deftypefn
+tmpnam
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})
+Return a unique temporary file name as a string.
+
+If @var{prefix} is omitted, a value of @code{"oct-"} is used.
+If @var{dir} is also omitted, the default directory for temporary files
+is used.  If @var{dir} is provided, it must exist, otherwise the default
+directory for temporary files is used.  Since the named file is not
+opened, by @code{tmpnam}, it is possible (though relatively unlikely)
+that it will not be available by the time your program attempts to open it.
+ at seealso{tmpfile, mkstemp, P_tmpdir}
+ at end deftypefn
+tmpfile
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()
+Return the file ID corresponding to a new temporary file with a unique
+name.  The file is opened in binary read/write (@code{"w+b"}) mode.
+The file will be deleted automatically when it is closed or when Octave
+exits.
+
+If successful, @var{fid} is a valid file ID and @var{msg} is an empty
+string.  Otherwise, @var{fid} is -1 and @var{msg} contains a
+system-dependent error message.
+ at seealso{tmpnam, mkstemp, P_tmpdir}
+ at end deftypefn
+mkstemp
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})
+Return the file ID corresponding to a new temporary file with a unique
+name created from @var{template}.  The last six characters of @var{template}
+must be @code{XXXXXX} and these are replaced with a string that makes the
+filename unique.  The file is then created with mode read/write and
+permissions that are system dependent (on GNU/Linux systems, the permissions
+will be 0600 for versions of glibc 2.0.7 and later).  The file is opened
+with the @w{@code{O_EXCL}} flag.
+
+If the optional argument @var{delete} is supplied and is true,
+the file will be deleted automatically when Octave exits, or when
+the function @code{purge_tmp_files} is called.
+
+If successful, @var{fid} is a valid file ID, @var{name} is the name of
+the file, and @var{msg} is an empty string.  Otherwise, @var{fid}
+is -1, @var{name} is empty, and @var{msg} contains a system-dependent
+error message.
+ at seealso{tmpfile, tmpnam, P_tmpdir}
+ at end deftypefn
+umask
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} umask (@var{mask})
+Set the permission mask for file creation.  The parameter @var{mask}
+is an integer, interpreted as an octal number.  If successful,
+returns the previous value of the mask (as an integer to be
+interpreted as an octal number); otherwise an error message is printed.
+ at end deftypefn
+P_tmpdir
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} P_tmpdir ()
+Return the default name of the directory for temporary files on
+this system.  The name of this directory is system dependent.
+ at end deftypefn
+SEEK_SET
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} SEEK_SET ()
+ at deftypefnx {Built-in Function} {} SEEK_CUR ()
+ at deftypefnx {Built-in Function} {} SEEK_END ()
+Return the value required to request that @code{fseek} perform
+one of the following actions:
+ at table @code
+ at item SEEK_SET
+Position file relative to the beginning.
+
+ at item SEEK_CUR
+Position file relative to the current position.
+
+ at item SEEK_END
+Position file relative to the end.
+ at end table
+ at end deftypefn
+SEEK_CUR
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} SEEK_CUR ()
+See SEEK_SET.
+ at end deftypefn
+SEEK_END
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} SEEK_END ()
+See SEEK_SET.
+ at end deftypefn
+stdin
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} stdin ()
+Return the numeric value corresponding to the standard input stream.
+When Octave is used interactively, this is filtered through the command
+line editing functions.
+ at seealso{stdout, stderr}
+ at end deftypefn
+stdout
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} stdout ()
+Return the numeric value corresponding to the standard output stream.
+Data written to the standard output is normally filtered through the pager.
+ at seealso{stdin, stderr}
+ at end deftypefn
+stderr
+ at c file-io.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} stderr ()
+Return the numeric value corresponding to the standard error stream.
+Even if paging is turned on, the standard error is not sent to the
+pager.  It is useful for error messages and prompts.
+ at seealso{stdin, stdout}
+ at end deftypefn
+filter
+ at c ./DLD-FUNCTIONS/filter.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {y =} filter (@var{b}, @var{a}, @var{x})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, [], @var{dim})
+ at deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}, @var{dim})
+Return the solution to the following linear, time-invariant difference
+equation:
+ at iftex
+ at 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
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+   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
+ at end smallexample
+ at end ifnottex
+
+ at noindent
+where
+ at ifnottex
+ N=length(a)-1 and M=length(b)-1.
+ at end ifnottex
+ at iftex
+ at tex
+ $a \in \Re^{N-1}$, $b \in \Re^{M-1}$, and $x \in \Re^P$.
+ at end tex
+ at end iftex
+over the first non-singleton dimension of @var{x} or over @var{dim} if
+supplied.  An equivalent form of this equation is:
+ at iftex
+ at 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
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+            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
+ at end smallexample
+ at end ifnottex
+
+ at noindent
+where
+ at ifnottex
+ c = a/a(1) and d = b/a(1).
+ at end ifnottex
+ at iftex
+ at tex
+$c = a/a_1$ and $d = b/a_1$.
+ at end tex
+ at end iftex
+
+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
+ at 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.
+
+In terms of the z-transform, y is the result of passing the discrete-
+time signal x through a system characterized by the following rational
+system function:
+ at iftex
+ at tex
+$$
+H(z) = {\displaystyle\sum_{k=0}^M d_{k+1} z^{-k}
+        \over 1 + \displaystyle\sum_{k+1}^N c_{k+1} z^{-k}}
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at group
+             M
+            SUM d(k+1) z^(-k)
+            k=0
+  H(z) = ----------------------
+               N
+          1 + SUM c(k+1) z^(-k)
+              k=1
+ at end group
+ at end example
+ at end ifnottex
+ at end deftypefn
+find
+ at c ./DLD-FUNCTIONS/find.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} find (@var{x})
+ at deftypefnx {Loadable Function} {} find (@var{x}, @var{n})
+ at deftypefnx {Loadable Function} {} find (@var{x}, @var{n}, @var{direction})
+Return a vector of indices of nonzero elements of a matrix, as a row if
+ at var{x} is a row or as a column otherwise.  To obtain a single index for
+each matrix element, Octave pretends that the columns of a matrix form one
+long vector (like Fortran arrays are stored).  For example,
+
+ at example
+ at group
+find (eye (2))
+     @result{} [ 1; 4 ]
+ at end group
+ at end example
+
+If two outputs are requested, @code{find} returns the row and column
+indices of nonzero elements of a matrix.  For example,
+
+ at example
+ at group
+[i, j] = find (2 * eye (2))
+     @result{} i = [ 1; 2 ]
+     @result{} j = [ 1; 2 ]
+ at end group
+ at end example
+
+If three outputs are requested, @code{find} also returns a vector
+containing the nonzero values.  For example,
+
+ at example
+ at group
+[i, j, v] = find (3 * eye (2))
+     @result{} i = [ 1; 2 ]
+     @result{} j = [ 1; 2 ]
+     @result{} v = [ 3; 3 ]
+ at end group
+ at end example
+
+If two inputs are given, @var{n} indicates the maximum number of
+elements to find from the beginning of the matrix or vector.
+
+If three inputs are given, @var{direction} should be one of "first" or
+"last", requesting only the first or last @var{n} indices, respectively.
+However, the indices are always returned in ascending order.
+
+Note that this function is particularly useful for sparse matrices, as
+it extracts the non-zero elements as vectors, which can then be used to
+create the original matrix.  For example,
+
+ at example
+ at group
+sz = size(a);
+[i, j, v] = find (a);
+b = sparse(i, j, v, sz(1), sz(2));
+ at end group
+ at end example
+ at seealso{sparse}
+ at end deftypefn
+__fltk_redraw__
+ at c ./DLD-FUNCTIONS/fltk_backend.cc
+
+__init_fltk__
+ at c ./DLD-FUNCTIONS/fltk_backend.cc
+
+__remove_fltk__
+ at c ./DLD-FUNCTIONS/fltk_backend.cc
+
+__fltk_maxtime__
+ at c ./DLD-FUNCTIONS/fltk_backend.cc
+
+gammainc
+ at c ./DLD-FUNCTIONS/gammainc.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} gammainc (@var{x}, @var{a})
+Compute the normalized incomplete gamma function,
+ at iftex
+ at tex
+$$
+ \gamma (x, a) = {\displaystyle\int_0^x e^{-t} t^{a-1} dt \over \Gamma (a)}
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at smallexample
+                                x
+                      1        /
+gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
+                  gamma (a)    /
+                            t=0
+ at end smallexample
+
+ at end ifnottex
+with the limiting value of 1 as @var{x} approaches infinity.
+The standard notation is @math{P(a,x)}, e.g., Abramowitz and Stegun (6.5.1).
+
+If @var{a} is scalar, then @code{gammainc (@var{x}, @var{a})} is returned
+for each element of @var{x} and vice versa.
+
+If neither @var{x} nor @var{a} is scalar, the sizes of @var{x} and
+ at var{a} must agree, and @var{gammainc} is applied element-by-element.
+ at seealso{gamma, lgamma}
+ at end deftypefn
+gcd
+ at c ./DLD-FUNCTIONS/gcd.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {@var{g} =} gcd (@var{a})
+ at deftypefnx {Loadable Function} {@var{g} =} gcd (@var{a1}, @var{a2}, @dots{})
+ at deftypefnx {Loadable Function} {[@var{g}, @var{v1}, @dots{}] =} gcd (@var{a1}, @var{a2}, @dots{})
+
+Compute the greatest common divisor of the elements of @var{a}.  If more
+than one argument is given all arguments must be the same size or scalar.
+  In this case the greatest common divisor is calculated for each element
+individually.  All elements must be integers.  For example,
+
+ at example
+ at group
+gcd ([15, 20])
+    @result{}  5
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+ at group
+gcd ([15, 9], [20, 18])
+    @result{}  5  9
+ at end group
+ at end example
+
+Optional return arguments @var{v1}, etc., contain integer vectors such
+that,
+
+ at tex
+$g = v_1 a_1 + v_2 a_2 + \cdots$
+ at end tex
+ at ifnottex
+ at example
+ at var{g} = @var{v1} .* @var{a1} + @var{v2} .* @var{a2} + @dots{}
+ at end example
+ at end ifnottex
+
+For backward compatibility with previous versions of this function, when
+all arguments are scalar, a single return argument @var{v1} containing
+all of the values of @var{v1}, @dots{} is acceptable.
+ at seealso{lcm, factor}
+ at end deftypefn
+getgrent
+ at c ./DLD-FUNCTIONS/getgrent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrent ()
+Return an entry from the group database, opening it if necessary.
+Once the end of the data has been reached, @code{getgrent} returns 0.
+ at end deftypefn
+getgrgid
+ at c ./DLD-FUNCTIONS/getgrent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrgid (@var{gid}).
+Return the first entry from the group database with the group ID
+ at var{gid}.  If the group ID does not exist in the database,
+ at code{getgrgid} returns 0.
+ at end deftypefn
+getgrnam
+ at c ./DLD-FUNCTIONS/getgrent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{grp_struct} =} getgrnam (@var{name})
+Return the first entry from the group database with the group name
+ at var{name}.  If the group name does not exist in the database,
+ at code{getgrnam} returns 0.
+ at end deftypefn
+setgrent
+ at c ./DLD-FUNCTIONS/getgrent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} setgrent ()
+Return the internal pointer to the beginning of the group database.
+ at end deftypefn
+endgrent
+ at c ./DLD-FUNCTIONS/getgrent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} endgrent ()
+Close the group database.
+ at end deftypefn
+getpwent
+ at c ./DLD-FUNCTIONS/getpwent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwent ()
+Return a structure containing an entry from the password database,
+opening it if necessary.  Once the end of the data has been reached,
+ at code{getpwent} returns 0.
+ at end deftypefn
+getpwuid
+ at c ./DLD-FUNCTIONS/getpwent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwuid (@var{uid}).
+Return a structure containing the first entry from the password database
+with the user ID @var{uid}.  If the user ID does not exist in the
+database, @code{getpwuid} returns 0.
+ at end deftypefn
+getpwnam
+ at c ./DLD-FUNCTIONS/getpwent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{pw_struct} =} getpwnam (@var{name})
+Return a structure containing the first entry from the password database
+with the user name @var{name}.  If the user name does not exist in the
+database, @code{getpwname} returns 0.
+ at end deftypefn
+setpwent
+ at c ./DLD-FUNCTIONS/getpwent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} setpwent ()
+Return the internal pointer to the beginning of the password database.
+ at end deftypefn
+endpwent
+ at c ./DLD-FUNCTIONS/getpwent.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} endpwent ()
+Close the password database.
+ at end deftypefn
+getrusage
+ at c ./DLD-FUNCTIONS/getrusage.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} getrusage ()
+Return a structure containing a number of statistics about the current
+Octave process.  Not all fields are available on all systems.  If it is
+not possible to get CPU time statistics, the CPU time slots are set to
+zero.  Other missing data are replaced by NaN.  Here is a list of all
+the possible fields that can be present in the structure returned by
+ at code{getrusage}:
+
+ at table @code
+ at item idrss
+Unshared data size.
+
+ at item inblock
+Number of block input operations.
+
+ at item isrss
+Unshared stack size.
+
+ at item ixrss
+Shared memory size.
+
+ at item majflt
+Number of major page faults.
+
+ at item maxrss
+Maximum data size.
+
+ at item minflt
+Number of minor page faults.
+
+ at item msgrcv
+Number of messages received.
+
+ at item msgsnd
+Number of messages sent.
+
+ at item nivcsw
+Number of involuntary context switches.
+
+ at item nsignals
+Number of signals received.
+
+ at item nswap
+Number of swaps.
+
+ at item nvcsw
+Number of voluntary context switches.
+
+ at item oublock
+Number of block output operations.
+
+ at item stime
+A structure containing the system CPU time used.  The structure has the
+elements @code{sec} (seconds) @code{usec} (microseconds).
+
+ at item utime
+A structure containing the user CPU time used.  The structure has the
+elements @code{sec} (seconds) @code{usec} (microseconds).
+ at end table
+ at end deftypefn
+givens
+ at c ./DLD-FUNCTIONS/givens.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{g} =} givens (@var{x}, @var{y})
+ at deftypefnx {Loadable Function} {[@var{c}, @var{s}] =} givens (@var{x}, @var{y})
+ at iftex
+ at tex
+Return a $2\times 2$ orthogonal matrix
+$$
+ G = \left[\matrix{c & s\cr -s'& c\cr}\right]
+$$
+such that
+$$
+ G \left[\matrix{x\cr y}\right] = \left[\matrix{\ast\cr 0}\right]
+$$
+with $x$ and $y$ scalars.
+ at end tex
+ at end iftex
+ at ifnottex
+Return a 2 by 2 orthogonal matrix
+ at code{@var{g} = [@var{c} @var{s}; - at var{s}' @var{c}]} such that
+ at code{@var{g} [@var{x}; @var{y}] = [*; 0]} with @var{x} and @var{y} scalars.
+ at end ifnottex
+
+For example,
+
+ at example
+ at group
+givens (1, 1)
+     @result{}   0.70711   0.70711
+         -0.70711   0.70711
+ at end group
+ at end example
+ at end deftypefn
+ishandle
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ishandle (@var{h})
+Return true if @var{h} is a graphics handle and false otherwise.
+ at end deftypefn
+set
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} set (@var{h}, @var{p}, @var{v}, @dots{})
+Set the named property value or vector @var{p} to the value @var{v}
+for the graphics handle @var{h}.
+ at end deftypefn
+get
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} get (@var{h}, @var{p})
+Return the named property @var{p} from the graphics handle @var{h}.
+If @var{p} is omitted, return the complete property list for @var{h}.
+If @var{h} is a vector, return a cell array including the property
+values or lists respectively.
+ at end deftypefn
+__get__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __get__ (@var{h})
+Undocumented internal function.
+ at end deftypefn
+__go_figure__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_figure__ (@var{fignum})
+Undocumented internal function.
+ at end deftypefn
+__go_axes__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_axes__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_line__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_line__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_text__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_text__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_image__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_image__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_surface__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_surface__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_patch__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_patch__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_hggroup__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_hggroup__ (@var{parent})
+Undocumented internal function.
+ at end deftypefn
+__go_delete__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_delete__ (@var{h})
+Undocumented internal function.
+ at end deftypefn
+__go_axes_init__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_axes_init__ (@var{h}, @var{mode})
+Undocumented internal function.
+ at end deftypefn
+__go_handles__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_handles__ ()
+Undocumented internal function.
+ at end deftypefn
+__go_figure_handles__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_figure_handles__ ()
+Undocumented internal function.
+ at end deftypefn
+__go_execute_callback__
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __go_execute_callback__ (@var{h}, @var{name})
+ at deftypefnx {Built-in Function} {} __go_execute_callback__ (@var{h}, @var{name}, @var{param})
+Undocumented internal function.
+ at end deftypefn
+available_backends
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} available_backends ()
+Return a cell array of registered graphics backends.
+ at end deftypefn
+drawnow
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} drawnow ()
+ at deftypefnx {Built-in Function} {} drawnow ("expose")
+ at deftypefnx {Built-in Function} {} drawnow (@var{term}, @var{file}, @var{mono}, @var{debug_file})
+Update figure windows and their children.  The event queue is flushed and
+any callbacks generated are executed.  With the optional argument
+ at code{"expose"}, only graphic objects are updated and no other events or
+callbacks are processed.
+The third calling form of @code{drawnow} is for debugging and is
+undocumented.
+ at end deftypefn
+addlistener
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} addlistener (@var{h}, @var{prop}, @var{fcn})
+Register @var{fcn} as listener for the property @var{prop} of the graphics
+object @var{h}.  Property listeners are executed (in order of registration)
+when the property is set.  The new value is already available when the
+listeners are executed.
+
+ at var{prop} must be a string naming a valid property in @var{h}.
+
+ at var{fcn} can be a function handle, a string or a cell array whose first
+element is a function handle.  If @var{fcn} is a function handle, the
+corresponding function should accept at least 2 arguments, that will be
+set to the object handle and the empty matrix respectively.  If @var{fcn}
+is a string, it must be any valid octave expression.  If @var{fcn} is a cell
+array, the first element must be a function handle with the same signature
+as described above.  The next elements of the cell array are passed
+as additional arguments to the function.
+
+Example:
+
+ at example
+ at group
+function my_listener (h, dummy, p1)
+  fprintf ("my_listener called with p1=%s\n", p1);
+endfunction
+
+addlistener (gcf, "position", @{@@my_listener, "my string"@})
+ at end group
+ at end example
+
+ at end deftypefn
+dellistener
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} dellistener (@var{h}, @var{prop}, @var{fcn})
+Remove the registration of @var{fcn} as a listener for the property
+ at var{prop} of the graphics object @var{h}.  The function @var{fcn} must
+be the same variable (not just the same value), as was passed to the
+original call to @code{addlistener}.
+
+If @var{fcn} is not defined then all listener functions of @var{prop}
+are removed.
+
+Example:
+
+ at example
+ at group
+function my_listener (h, dummy, p1)
+  fprintf ("my_listener called with p1=%s\n", p1);
+endfunction
+
+c = @{@@my_listener, "my string"@};
+addlistener (gcf, "position", c);
+dellistener (gcf, "position", c);
+ at end group
+ at end example
+
+ at end deftypefn
+addproperty
+ at c graphics.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} addproperty (@var{name}, @var{h}, @var{type}, [@var{arg}, @dots{}])
+Create a new property named @var{name} in graphics object @var{h}.
+ at var{type} determines the type of the property to create.  @var{args}
+usually contains the default value of the property, but additional
+arguments might be given, depending on the type of the property.
+
+The supported property types are:
+
+ at table @code
+ at item string
+A string property.  @var{arg} contains the default string value.
+ at item any
+An un-typed property.  This kind of property can hold any octave
+value.  @var{args} contains the default value.
+ at item radio
+A string property with a limited set of accepted values.  The first
+argument must be a string with all accepted values separated by
+a vertical bar ('|').  The default value can be marked by enclosing
+it with a '@{' '@}' pair.  The default value may also be given as
+an optional second string argument.
+ at item boolean
+A boolean property.  This property type is equivalent to a radio
+property with "on|off" as accepted values.  @var{arg} contains
+the default property value.
+ at item double
+A scalar double property.  @var{arg} contains the default value.
+ at item handle
+A handle property.  This kind of property holds the handle of a
+graphics object.  @var{arg} contains the default handle value.
+When no default value is given, the property is initialized to
+the empty matrix.
+ at item data
+A data (matrix) property.  @var{arg} contains the default data
+value.  When no default value is given, the data is initialized to
+the empty matrix.
+ at item color
+A color property.  @var{arg} contains the default color value.
+When no default color is given, the property is set to black.
+An optional second string argument may be given to specify an
+additional set of accepted string values (like a radio property).
+ at end table
+
+ at var{type} may also be the concatenation of a core object type and
+a valid property name for that object type.  The property created
+then has the same characteristics as the referenced property (type,
+possible values, hidden state at dots{}).  This allows to clone an existing
+property into the graphics object @var{h}.
+
+Examples:
+
+ at example
+ at group
+addproperty ("my_property", gcf, "string", "a string value");
+addproperty ("my_radio", gcf, "radio", "val_1|val_2|@{val_3@}");
+addproperty ("my_style", gcf, "linelinestyle", "--");
+ at end group
+ at end example
+
+ at end deftypefn
+get_help_text
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{text}, @var{format}] =} get_help_text (@var{name})
+Returns the help text of a given function.
+
+This function returns the raw help text @var{text} and an indication of
+its format for the function @var{name}.  The format indication @var{format}
+is a string that can be either @t{"texinfo"}, @t{"html"}, or
+ at t{"plain text"}.
+
+To convert the help text to other formats, use the @code{makeinfo} function.
+
+ at seealso{makeinfo}
+ at end deftypefn
+__operators__
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Function File} __operators__ ()
+Undocumented internal function.
+ at end deftypefn
+__keywords__
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Function File} __keywords__ ()
+Undocumented internal function.
+ at end deftypefn
+__builtins__
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Function File} __builtins__ ()
+Undocumented internal function.
+ at end deftypefn
+__which__
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __which__ (@var{name}, @dots{})
+Undocumented internal function.
+ at end deftypefn
+__list_functions__
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Function File} {@var{retval} =} __list_functions__ ()
+ at deftypefnx{Function File} {@var{retval} =} __list_functions__ (@var{directory})
+Undocumented internal function.
+ at end deftypefn
+doc_cache_file
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} doc_cache_file ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} doc_cache_file (@var{new_val})
+Query or set the internal variable that specifies the name of the
+Octave documentation cache file.  A cache file significantly improves
+the performance of the @code{lookfor} command.  The default value is 
+ at file{@var{octave-home}/share/octave/@var{version}/etc/doc-cache},
+in which @var{octave-home} is the root directory of the Octave installation,
+and @var{version} is the Octave version number.
+The default value may be overridden by the environment variable
+ at w{@code{OCTAVE_DOC_CACHE_FILE}}, or the command line argument
+ at samp{--doc-cache-file NAME}.
+ at seealso{lookfor, info_program, doc, help, makeinfo_program}
+ at end deftypefn
+info_file
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} info_file ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} info_file (@var{new_val})
+Query or set the internal variable that specifies the name of the
+Octave info file.  The default value is
+ at file{@var{octave-home}/info/octave.info}, in
+which @var{octave-home} is the root directory of the Octave installation.
+The default value may be overridden by the environment variable
+ at w{@code{OCTAVE_INFO_FILE}}, or the command line argument
+ at samp{--info-file NAME}.
+ at seealso{info_program, doc, help, makeinfo_program}
+ at end deftypefn
+info_program
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} info_program ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} info_program (@var{new_val})
+Query or set the internal variable that specifies the name of the
+info program to run.  The default value is
+ at file{@var{octave-home}/libexec/octave/@var{version}/exec/@var{arch}/info}
+in which @var{octave-home} is the root directory of the Octave installation,
+ at var{version} is the Octave version number, and @var{arch}
+is the system type (for example, @code{i686-pc-linux-gnu}).  The
+default value may be overridden by the environment variable
+ at w{@code{OCTAVE_INFO_PROGRAM}}, or the command line argument
+ at samp{--info-program NAME}.
+ at seealso{info_file, doc, help, makeinfo_program}
+ at end deftypefn
+makeinfo_program
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} makeinfo_program ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} makeinfo_program (@var{new_val})
+Query or set the internal variable that specifies the name of the
+program that Octave runs to format help text containing
+Texinfo markup commands.  The default value is @code{makeinfo}.
+ at seealso{info_file, info_program, doc, help}
+ at end deftypefn
+suppress_verbose_help_message
+ at c help.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} suppress_verbose_help_message ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} suppress_verbose_help_message (@var{new_val})
+Query or set the internal variable that controls whether Octave
+will add additional help information to the end of the output from
+the @code{help} command and usage messages for built-in commands.
+ at end deftypefn
+hess
+ at c ./DLD-FUNCTIONS/hess.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{h} =} hess (@var{a})
+ at deftypefnx {Loadable Function} {[@var{p}, @var{h}] =} hess (@var{a})
+ at cindex Hessenberg decomposition
+Compute the Hessenberg decomposition of the matrix @var{a}.
+
+The Hessenberg decomposition is usually used as the first step in an
+eigenvalue computation, but has other applications as well (see Golub,
+Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).  The
+Hessenberg decomposition is
+ at iftex
+ at tex
+$$
+A = PHP^T
+$$
+where $P$ is a square unitary matrix ($P^HP = I$), and $H$
+is upper Hessenberg ($H_{i,j} = 0, \forall i \ge j+1$).
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{p * h * p' = a} where @code{p} is a square unitary matrix
+(@code{p' * p = I}, using complex-conjugate transposition) and @code{h}
+is upper Hessenberg (@code{i >= j+1 => h (i, j) = 0}).
+ at end ifnottex
+ at end deftypefn
+hex2num
+ at c ./DLD-FUNCTIONS/hex2num.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{n} =} hex2num (@var{s})
+Typecast the 16 character hexadecimal character matrix to an IEEE 754
+double precision number.  If fewer than 16 characters are given the
+strings are right padded with '0' characters.
+
+Given a string matrix, @code{hex2num} treats each row as a separate
+number.
+
+ at example
+ at group
+hex2num (["4005bf0a8b145769";"4024000000000000"])
+ at result{} [2.7183; 10.000]
+ at end group
+ at end example
+ at seealso{num2hex, hex2dec, dec2hex}
+ at end deftypefn
+num2hex
+ at c ./DLD-FUNCTIONS/hex2num.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{s} =} num2hex (@var{n})
+Typecast a double precision number or vector to a 16 character hexadecimal
+string of the IEEE 754 representation of the number.  For example
+
+ at example
+ at group
+num2hex ([-1, 1, e, Inf, NaN, NA]);
+ at result{} "bff0000000000000
+    3ff0000000000000
+    4005bf0a8b145769
+    7ff0000000000000
+    fff8000000000000
+    7ff00000000007a2"
+ at end group
+ at end example
+ at seealso{hex2num, hex2dec, dec2hex}
+ at end deftypefn
+input
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} input (@var{prompt})
+ at deftypefnx {Built-in Function} {} input (@var{prompt}, "s")
+Print a prompt and wait for user input.  For example,
+
+ at example
+input ("Pick a number, any number! ")
+ at end example
+
+ at noindent
+prints the prompt
+
+ at example
+Pick a number, any number!
+ at end example
+
+ at noindent
+and waits for the user to enter a value.  The string entered by the user
+is evaluated as an expression, so it may be a literal constant, a
+variable name, or any other valid expression.
+
+Currently, @code{input} only returns one value, regardless of the number
+of values produced by the evaluation of the expression.
+
+If you are only interested in getting a literal string value, you can
+call @code{input} with the character string @code{"s"} as the second
+argument.  This tells Octave to return the string entered by the user
+directly, without evaluating it first.
+
+Because there may be output waiting to be displayed by the pager, it is
+a good idea to always call @code{fflush (stdout)} before calling
+ at code{input}.  This will ensure that all pending output is written to
+the screen before your prompt.  @xref{Input and Output}.
+ at end deftypefn
+yes_or_no
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} yes_or_no (@var{prompt})
+Ask the user a yes-or-no question.  Return 1 if the answer is yes.
+Takes one argument, which is the string to display to ask the
+question.  It should end in a space; @samp{yes-or-no-p} adds
+ at samp{(yes or no) } to it.  The user must confirm the answer with
+RET and can edit it until it has been confirmed.
+ at end deftypefn
+keyboard
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} keyboard ()
+ at deftypefnx {Built-in Function} {} keyboard (@var{prompt})
+This function is normally used for simple debugging.  When the
+ at code{keyboard} function is executed, Octave prints a prompt and waits
+for user input.  The input strings are then evaluated and the results
+are printed.  This makes it possible to examine the values of variables
+within a function, and to assign new values if necessary.  To leave the
+prompt and return to normal execution type @samp{return} or @samp{dbcont}.
+The @code{keyboard} function does not return an exit status.
+
+If @code{keyboard} is invoked without arguments, a default prompt of
+ at samp{debug> } is used.
+ at seealso{dbcont, dbquit}
+ at end deftypefn
+echo
+ at c input.cc
+-*- texinfo -*-
+ at deffn {Command} echo options
+Control whether commands are displayed as they are executed.  Valid
+options are:
+
+ at table @code
+ at item on
+Enable echoing of commands as they are executed in script files.
+
+ at item off
+Disable echoing of commands as they are executed in script files.
+
+ at item on all
+Enable echoing of commands as they are executed in script files and
+functions.
+
+ at item off all
+Disable echoing of commands as they are executed in script files and
+functions.
+ at end table
+
+ at noindent
+With no arguments, @code{echo} toggles the current echo state.
+ at end deffn
+completion_matches
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} completion_matches (@var{hint})
+Generate possible completions given @var{hint}.
+
+This function is provided for the benefit of programs like Emacs which
+might be controlling Octave and handling user input.  The current
+command number is not incremented when this function is called.  This is
+a feature, not a bug.
+ at end deftypefn
+read_readline_init_file
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} read_readline_init_file (@var{file})
+Read the readline library initialization file @var{file}.  If
+ at var{file} is omitted, read the default initialization file (normally
+ at file{~/.inputrc}).
+
+ at xref{Readline Init File, , , readline, GNU Readline Library},
+for details.
+ at end deftypefn
+re_read_readline_init_file
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} re_read_readline_init_file ()
+Re-read the last readline library initialization file that was read.
+ at xref{Readline Init File, , , readline, GNU Readline Library},
+for details.
+ at end deftypefn
+add_input_event_hook
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} add_input_event_hook (@var{fcn}, @var{data})
+Add the named function @var{fcn} to the list of functions to call
+periodically when Octave is waiting for input.  The function should
+have the form
+ at example
+ at var{fcn} (@var{data})
+ at end example
+
+If @var{data} is omitted, Octave calls the function without any
+arguments.
+ at seealso{remove_input_event_hook}
+ at end deftypefn
+remove_input_event_hook
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} remove_input_event_hook (@var{fcn})
+Remove the named function @var{fcn} to the list of functions to call
+periodically when Octave is waiting for input.
+ at seealso{add_input_event_hook}
+ at end deftypefn
+PS1
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} PS1 ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS1 (@var{new_val})
+Query or set the primary prompt string.  When executing interactively,
+Octave displays the primary prompt when it is ready to read a command.
+
+The default value of the primary prompt string is @code{"\s:\#> "}.
+To change it, use a command like
+
+ at example
+octave:13> PS1 ("\\u@@\\H> ")
+ at end example
+
+ at noindent
+which will result in the prompt @samp{boris@@kremvax> } for the user
+ at samp{boris} logged in on the host @samp{kremvax.kgb.su}.  Note that two
+backslashes are required to enter a backslash into a double-quoted
+character string.
+ at xref{Strings}.
+ at seealso{PS2, PS4}
+ at end deftypefn
+PS2
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} PS2 ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS2 (@var{new_val})
+Query or set the secondary prompt string.  The secondary prompt is
+printed when Octave is expecting additional input to complete a
+command.  For example, if you are typing a @code{for} loop that spans several
+lines, Octave will print the secondary prompt at the beginning of
+each line after the first.  The default value of the secondary prompt
+string is @code{"> "}.
+ at seealso{PS1, PS4}
+ at end deftypefn
+PS4
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} PS4 ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS4 (@var{new_val})
+Query or set the character string used to prefix output produced
+when echoing commands is enabled.
+The default value is @code{"+ "}.
+ at xref{Diary and Echo Commands}, for a description of echoing commands.
+ at seealso{echo, echo_executing_commands, PS1, PS2}
+ at end deftypefn
+completion_append_char
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} completion_append_char ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} completion_append_char (@var{new_val})
+Query or set the internal character variable that is appended to
+successful command-line completion attempts.  The default
+value is @code{" "} (a single space).
+ at end deftypefn
+echo_executing_commands
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} echo_executing_commands ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} echo_executing_commands (@var{new_val})
+Query or set the internal variable that controls the echo state.
+It may be the sum of the following values:
+
+ at table @asis
+ at item 1
+Echo commands read from script files.
+
+ at item 2
+Echo commands from functions.
+
+ at item 4
+Echo commands read from command line.
+ at end table
+
+More than one state can be active at once.  For example, a value of 3 is
+equivalent to the command @kbd{echo on all}.
+
+The value of @code{echo_executing_commands} may be set by the @kbd{echo}
+command or the command line option @code{--echo-commands}.
+ at end deftypefn
+__request_drawnow__
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __request_drawnow__ ()
+ at deftypefnx {Built-in Function} {} __request_drawnow__ (@var{flag})
+Undocumented internal function.
+ at end deftypefn
+__gud_mode__
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __gud_mode__ ()
+Undocumented internal function.
+ at end deftypefn
+filemarker
+ at c input.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} filemarker ()
+Returns or sets the character used to separate filename from the
+the subfunction names contained within the file.  This can be used in
+a generic manner to interact with subfunctions.  For example
+
+ at example
+help (["myfunc", filemarker, "mysubfunc"])
+ at end example
+
+ at noindent
+returns the help string associated with the sub-function @code{mysubfunc}
+of the function @code{myfunc}.  Another use of @code{filemarker} is when
+debugging it allows easier placement of breakpoints within sub-functions.
+For example
+
+ at example
+dbstop (["myfunc", filemarker, "mysubfunc"])
+ at end example
+
+ at noindent
+will set a breakpoint at the first line of the subfunction @code{mysubfunc}.
+ at end deftypefn
+inv
+ at c ./DLD-FUNCTIONS/inv.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inv (@var{a})
+ at deftypefnx {Loadable Function} {[@var{x}, @var{rcond}] =} inverse (@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.
+
+If called with a sparse matrix, then in general @var{x} will be a full
+matrix, and so if possible forming the inverse of a sparse matrix should
+be avoided.  It is significantly more accurate and faster to do
+ at code{@var{y} = @var{a} \ @var{b}}, rather than
+ at code{@var{y} = inv (@var{a}) * @var{b}}.
+ at end deftypefn
+inverse
+ at c ./DLD-FUNCTIONS/inv.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} inverse (@var{a})
+See inv.
+ at end deftypefn
+kron
+ at c ./DLD-FUNCTIONS/kron.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} kron (@var{a}, @var{b})
+Form the kronecker product of two matrices, defined block by block as
+
+ at example
+x = [a(i, j) b]
+ at end example
+
+For example,
+
+ at example
+ at group
+kron (1:4, ones (3, 1))
+      @result{}  1  2  3  4
+          1  2  3  4
+          1  2  3  4
+ at end group
+ at end example
+ at end deftypefn
+iskeyword
+ at c lex.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} iskeyword (@var{name})
+Return true if @var{name} is an Octave keyword.  If @var{name}
+is omitted, return a list of keywords.
+ at end deftypefn
+__display_tokens__
+ at c lex.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __display_tokens__ ()
+Query or set the internal variable that determines whether Octave's
+lexer displays tokens as they are read.
+ at end deftypefn
+__token_count__
+ at c lex.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __token_count__ ()
+Number of language tokens processed since Octave startup.
+ at end deftypefn
+__lexer_debug_flag__
+ at c lex.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{old_val} =} __lexer_debug_flag__ (@var{new_val}))
+Undocumented internal function.
+ at end deftypefn
+genpath
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} genpath (@var{dir})
+Return a path constructed from @var{dir} and all its subdirectories.
+ at end deftypefn
+rehash
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rehash ()
+Reinitialize Octave's load path directory cache.
+ at end deftypefn
+command_line_path
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} command_line_path (@dots{})
+Return the command line path variable.
+
+ at seealso{path, addpath, rmpath, genpath, pathdef, savepath, pathsep}
+ at end deftypefn
+restoredefaultpath
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} restoredefaultpath (@dots{})
+Restore Octave's path to it's initial state at startup.
+
+ at seealso{path, addpath, rmpath, genpath, pathdef, savepath, pathsep}
+ at end deftypefn
+__pathorig__
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} __pathorig__ ()
+Undocumented internal function.
+ at end deftypefn
+path
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} path (@dots{})
+Modify or display Octave's load path.
+
+If @var{nargin} and @var{nargout} are zero, display the elements of
+Octave's load path in an easy to read format.
+
+If @var{nargin} is zero and nargout is greater than zero, return the
+current load path.
+
+If @var{nargin} is greater than zero, concatenate the arguments,
+separating them with @code{pathsep()}.  Set the internal search path
+to the result and return it.
+
+No checks are made for duplicate elements.
+ at seealso{addpath, rmpath, genpath, pathdef, savepath, pathsep}
+ at end deftypefn
+addpath
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})
+ at deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})
+Add @var{dir1}, @dots{} to the current function search path.  If
+ at var{option} is @samp{"-begin"} or 0 (the default), prepend the
+directory name to the current path.  If @var{option} is @samp{"-end"}
+or 1, append the directory name to the current path.
+Directories added to the path must exist.
+ at seealso{path, rmpath, genpath, pathdef, savepath, pathsep}
+ at end deftypefn
+rmpath
+ at c load-path.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rmpath (@var{dir1}, @dots{})
+Remove @var{dir1}, @dots{} from the current function search path.
+
+ at seealso{path, addpath, genpath, pathdef, savepath, pathsep}
+ at end deftypefn
+load
+ at c load-save.cc
+-*- texinfo -*-
+ at deffn  {Command} load file
+ at deffnx {Command} load options file
+ at deffnx {Command} load options file v1 v2 @dots{}
+ at deffnx {Command} S = load("options", "file", "v1", "v2", @dots{})
+Load the named variables @var{v1}, @var{v2}, @dots{}, from the file
+ at var{file}.  If no variables are specified then all variables found in the
+file will be loaded.  As with @code{save}, the list of variables to extract
+can be full names or use a pattern syntax.  The format of the file is
+automatically detected but may be overridden by supplying the appropriate
+option.
+
+If load is invoked using the functional form
+
+ at example
+load ("-option1", @dots{}, "file", "v1", @dots{})
+ at end example
+
+ at noindent
+then the @var{options}, @var{file}, and variable name arguments
+(@var{v1}, @dots{}) must be specified as character strings.
+
+If a variable that is not marked as global is loaded from a file when a
+global symbol with the same name already exists, it is loaded in the
+global symbol table.  Also, if a variable is marked as global in a file
+and a local symbol exists, the local symbol is moved to the global
+symbol table and given the value from the file.
+
+If invoked with a single output argument, Octave returns data instead
+of inserting variables in the symbol table.  If the data file contains
+only numbers (TAB- or space-delimited columns), a matrix of values is
+returned.  Otherwise, @code{load} returns a structure with members
+ corresponding to the names of the variables in the file.
+
+The @code{load} command can read data stored in Octave's text and
+binary formats, and @sc{matlab}'s binary format.  If compiled with zlib
+support, it can also load gzip-compressed files.  It will automatically
+detect the type of file and do conversion from different floating point
+formats (currently only IEEE big and little endian, though other formats
+may be added in the future).
+
+Valid options for @code{load} are listed in the following table.
+
+ at table @code
+ at item -force
+This option is accepted for backward compatibility but is ignored.
+Octave now overwrites variables currently in memory with
+those of the same name found in the file.
+
+ at item -ascii
+Force Octave to assume the file contains columns of numbers in text format
+without any header or other information.  Data in the file will be loaded
+as a single numeric matrix with the name of the variable derived from the
+name of the file.
+
+ at item -binary
+Force Octave to assume the file is in Octave's binary format.
+
+ at item -hdf5
+Force Octave to assume the file is in HDF5 format.
+(HDF5 is a free, portable binary format developed by the National
+Center for Supercomputing Applications at the University of Illinois.)
+Note that Octave can read HDF5 files not created by itself, but may
+skip some datasets in formats that it cannot support.
+
+ at item -import
+This option is accepted for backward compatibility but is ignored.
+Octave can now support multi-dimensional HDF data and automatically
+modifies variable names if they are invalid Octave identifiers.
+
+ at item -mat
+ at itemx -mat-binary
+ at itemx -6
+ at itemx -v6
+ at itemx -7
+ at itemx -v7
+Force Octave to assume the file is in @sc{matlab}'s version 6 or 7 binary
+format.
+
+ at item  -mat4-binary
+ at itemx -4
+ at itemx -v4
+ at itemx -V4
+Force Octave to assume the file is in the binary format written by
+ at sc{matlab} version 4.
+
+ at item -text
+Force Octave to assume the file is in Octave's text format.
+ at end table
+ at seealso{save, dlmwrite, csvwrite, fwrite}
+ at end deffn
+save
+ at c load-save.cc
+-*- texinfo -*-
+ at deffn  {Command} save file
+ at deffnx {Command} save options file
+ at deffnx {Command} save options file @var{v1} @var{v2} @dots{}
+ at deffnx {Command} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}
+Save the named variables @var{v1}, @var{v2}, @dots{}, in the file
+ at var{file}.  The special filename @samp{-} may be used to write
+output to the terminal.  If no variable names are listed, Octave saves
+all the variables in the current scope.  Otherwise, full variable names or
+pattern syntax can be used to specify the variables to save.
+If the @code{-struct} modifier is used, fields @var{f1} @var{f2} @dots{}
+of the scalar structure @var{STRUCT} are saved as if they were variables
+with corresponding names.
+Valid options for the @code{save} command are listed in the following table.
+Options that modify the output format override the format specified by 
+ at code{default_save_options}.
+
+If save is invoked using the functional form
+
+ at example
+save ("-option1", @dots{}, "file", "v1", @dots{})
+ at end example
+
+ at noindent
+then the @var{options}, @var{file}, and variable name arguments
+(@var{v1}, @dots{}) must be specified as character strings.
+
+ at table @code
+ at item -ascii
+Save a single matrix in a text file without header or any other information.
+
+ at item -binary
+Save the data in Octave's binary data format.
+
+ at item -float-binary
+Save the data in Octave's binary data format but only using single
+precision.  Only use this format if you know that all the
+values to be saved can be represented in single precision.
+
+ at item -hdf5
+Save the data in HDF5 format.
+(HDF5 is a free, portable binary format developed by the National
+Center for Supercomputing Applications at the University of Illinois.)
+
+ at item -float-hdf5
+Save the data in HDF5 format but only using single precision.
+Only use this format if you know that all the
+values to be saved can be represented in single precision.
+
+ at item -V7
+ at itemx -v7
+ at itemx -7
+ at itemx -mat7-binary
+Save the data in @sc{matlab}'s v7 binary data format.
+
+ at item -V6
+ at itemx -v6
+ at itemx -6
+ at itemx -mat
+ at itemx -mat-binary
+Save the data in @sc{matlab}'s v6 binary data format.
+
+ at item -V4
+ at itemx -v4
+ at itemx -4
+ at itemx -mat4-binary
+Save the data in the binary format written by @sc{matlab} version 4.
+
+ at item -text
+Save the data in Octave's text data format.  (default).
+
+ at item -zip
+ at itemx -z
+Use the gzip algorithm to compress the file.  This works equally on files that
+are compressed with gzip outside of octave, and gzip can equally be used to
+convert the files for backward compatibility.
+ at end table
+
+The list of variables to save may use wildcard patterns containing
+the following special characters:
+ at table @code
+ at item ?
+Match any single character.
+
+ at item *
+Match zero or more characters.
+
+ at item [ @var{list} ]
+Match the list of characters specified by @var{list}.  If the first
+character is @code{!} or @code{^}, match all characters except those
+specified by @var{list}.  For example, the pattern @code{[a-zA-Z]} will
+match all lower and upper case alphabetic characters.  
+
+Wildcards may also be used in the field name specifications when using
+the @code{-struct} modifier (but not in the struct name itself).
+
+ at end table
+
+Except when using the @sc{matlab} binary data file format or the
+ at samp{-ascii} format, saving global
+variables also saves the global status of the variable.  If the variable
+is restored at a later time using @samp{load}, it will be restored as a
+global variable.
+
+The command
+
+ at example
+save -binary data a b*
+ at end example
+
+ at noindent
+saves the variable @samp{a} and all variables beginning with @samp{b} to
+the file @file{data} in Octave's binary format.
+ at seealso{load, default_save_options, dlmread, csvread, fread}
+ at end deffn
+crash_dumps_octave_core
+ at c load-save.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} crash_dumps_octave_core ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})
+Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it
+crashes or receives a hangup, terminate or similar signal.
+ at seealso{octave_core_file_limit, octave_core_file_name, octave_core_file_options}
+ at end deftypefn
+default_save_options
+ at c load-save.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {@var{val} =} default_save_options ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} default_save_options (@var{new_val})
+Query or set the internal variable that specifies the default options
+for the @code{save} command, and defines the default format.
+Typical values include @code{"-ascii"}, @code{"-text -zip"}.
+The default value is @code{-text}.
+ at seealso{save}
+ at end deftypefn
+octave_core_file_limit
+ at c load-save.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_limit ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_limit (@var{new_val})
+Query or set the internal variable that specifies the maximum amount
+of memory (in kilobytes) of the top-level workspace that Octave will
+attempt to save when writing data to the crash dump file (the name of
+the file is specified by @var{octave_core_file_name}).  If
+ at var{octave_core_file_options} flags specify a binary format,
+then @var{octave_core_file_limit} will be approximately the maximum
+size of the file.  If a text file format is used, then the file could
+be much larger than the limit.  The default value is -1 (unlimited)
+ at seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}
+ at end deftypefn
+octave_core_file_name
+ at c load-save.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_name ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_name (@var{new_val})
+Query or set the internal variable that specifies the name of the file
+used for saving data from the top-level workspace if Octave aborts.
+The default value is @code{"octave-core"}
+ at seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}
+ at end deftypefn
+octave_core_file_options
+ at c load-save.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_options ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_options (@var{new_val})
+Query or set the internal variable that specifies the options used for
+saving the workspace data if Octave aborts.  The value of
+ at code{octave_core_file_options} should follow the same format as the
+options for the @code{save} function.  The default value is Octave's binary
+format.
+ at seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}
+ at end deftypefn
+save_header_format_string
+ at c load-save.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {@var{val} =} save_header_format_string ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} save_header_format_string (@var{new_val})
+Query or set the internal variable that specifies the format
+string used for the comment line written at the beginning of
+text-format data files saved by Octave.  The format string is
+passed to @code{strftime} and should begin with the character
+ at samp{#} and contain no newline characters.  If the value of
+ at code{save_header_format_string} is the empty string,
+the header comment is omitted from text-format data files.  The
+default value is
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>"
+ at end smallexample
+ at seealso{strftime, save}
+ at end deftypefn
+lookup
+ at c ./DLD-FUNCTIONS/lookup.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{idx} =} lookup (@var{table}, @var{y}, @var{opt})
+Lookup values in a sorted table.  Usually used as a prelude to
+interpolation.
+
+If table is strictly increasing and @code{idx = lookup (table, y)}, then
+ at code{table(idx(i)) <= y(i) < table(idx(i+1))} for all @code{y(i)}
+within the table.  If @code{y(i) < table (1)} then
+ at code{idx(i)} is 0. If @code{y(i) >= table(end)} then
+ at code{idx(i)} is @code{table(n)}.
+
+If the table is strictly decreasing, then the tests are reversed.
+There are no guarantees for tables which are non-monotonic or are not
+strictly monotonic.
+
+The algorithm used by lookup is standard binary search, with optimizations
+to speed up the case of partially ordered arrays (dense downsampling).
+In particular, looking up a single entry is of logarithmic complexity
+(unless a conversion occurs due to non-numeric or unequal types).
+
+ at var{table} and @var{y} can also be cell arrays of strings
+(or @var{y} can be a single string).  In this case, string lookup
+is performed using lexicographical comparison.
+
+If @var{opts} is specified, it shall be a string with letters indicating
+additional options.
+For numeric lookup, 'l' in @var{opts} indicates that
+the leftmost subinterval shall be extended to infinity (i.e., all indices
+at least 1), and 'r' indicates that the rightmost subinterval shall be
+extended to infinity (i.e., all indices at most n-1).
+
+For string lookup, 'i' indicates case-insensitive comparison.
+ at end deftypefn
+save_precision
+ at c ls-oct-ascii.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} save_precision ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} save_precision (@var{new_val})
+Query or set the internal variable that specifies the number of
+digits to keep when saving data in text format.
+ at end deftypefn
+lsode_options
+ at c ./DLD-FUNCTIONS/lsode.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} lsode_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{lsode}.
+Given one argument, @code{lsode_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance.  May be either vector or scalar.  If a vector, it
+must match the dimension of the state vector.
+ at item "relative tolerance"
+Relative tolerance parameter.  Unlike the absolute tolerance, this
+parameter may only be a scalar.
+
+The local error test applied at each integration step is
+
+ at example
+ at group
+  abs (local error in x(i)) <= ...
+      rtol * abs (y(i)) + atol(i)
+ at end group
+ at end example
+ at item "integration method"
+A string specifying the method of integration to use to solve the ODE
+system.  Valid values are
+
+ at table @asis
+ at item "adams"
+ at itemx "non-stiff"
+No Jacobian used (even if it is available).
+ at item "bdf"
+ at item "stiff"
+Use stiff backward differentiation formula (BDF) method.  If a
+function to compute the Jacobian is not supplied, @code{lsode} will
+compute a finite difference approximation of the Jacobian matrix.
+ at end table
+ at item "initial step size"
+The step size to be attempted on the first step (default is determined
+automatically).
+ at item "maximum order"
+Restrict the maximum order of the solution method.  If using the Adams
+method, this option must be between 1 and 12.  Otherwise, it must be
+between 1 and 5, inclusive.
+ at item "maximum step size"
+Setting the maximum stepsize will avoid passing over very large
+regions  (default is not specified).
+ at item "minimum step size"
+The minimum absolute step size allowed (default is 0).
+ at item "step limit"
+Maximum number of steps allowed (default is 100000).
+ at end table
+ at end deftypefn
+lsode
+ at c ./DLD-FUNCTIONS/lsode.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{x}, @var{istate}, @var{msg}] =} lsode (@var{fcn}, @var{x_0}, @var{t}, @var{t_crit})
+Solve the set of differential equations
+ at tex
+$$ {dx \over dt} = f (x, t) $$
+with
+$$ x(t_0) = x_0 $$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+dx
+-- = f(x, t)
+dt
+ at end group
+ at end example
+
+with
+
+ at example
+x(t_0) = x_0
+ at end example
+
+ at end ifnottex
+The solution is returned in the matrix @var{x}, with each row
+corresponding to an element of the vector @var{t}.  The first element
+of @var{t} should be @math{t_0} and should correspond to the initial
+state of the system @var{x_0}, so that the first row of the output
+is @var{x_0}.
+
+The first argument, @var{fcn}, is a string, inline, or function handle
+that names the function @math{f} to call to compute the vector of right
+hand sides for the set of equations.  The function must have the form
+
+ at example
+ at var{xdot} = f (@var{x}, @var{t})
+ at end example
+
+ at noindent
+in which @var{xdot} and @var{x} are vectors and @var{t} is a scalar.
+
+If @var{fcn} is a two-element string array or a two-element cell array
+of strings, inline functions, or function handles, the first element names
+the function @math{f} described above, and the second element names a
+function to compute the Jacobian of @math{f}.  The Jacobian function
+must have the form
+
+ at example
+ at var{jac} = j (@var{x}, @var{t})
+ at end example
+
+in which @var{jac} is the matrix of partial derivatives
+ at tex
+$$ J = {\partial f_i \over \partial x_j} = \left[\matrix{
+{\partial f_1 \over \partial x_1}
+  & {\partial f_1 \over \partial x_2}
+  & \cdots
+  & {\partial f_1 \over \partial x_N} \cr
+{\partial f_2 \over \partial x_1}
+  & {\partial f_2 \over \partial x_2}
+  & \cdots
+  & {\partial f_2 \over \partial x_N} \cr
+ \vdots & \vdots & \ddots & \vdots \cr
+{\partial f_3 \over \partial x_1}
+  & {\partial f_3 \over \partial x_2}
+  & \cdots
+  & {\partial f_3 \over \partial x_N} \cr}\right]$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+             | df_1  df_1       df_1 |
+             | ----  ----  ...  ---- |
+             | dx_1  dx_2       dx_N |
+             |                       |
+             | df_2  df_2       df_2 |
+             | ----  ----  ...  ---- |
+      df_i   | dx_1  dx_2       dx_N |
+jac = ---- = |                       |
+      dx_j   |  .    .     .    .    |
+             |  .    .      .   .    |
+             |  .    .       .  .    |
+             |                       |
+             | df_N  df_N       df_N |
+             | ----  ----  ...  ---- |
+             | dx_1  dx_2       dx_N |
+ at end group
+ at end example
+
+ at end ifnottex
+
+The second and third arguments specify the initial state of the system,
+ at math{x_0}, and the initial value of the independent variable @math{t_0}.
+
+The fourth argument is optional, and may be used to specify a set of
+times that the ODE solver should not integrate past.  It is useful for
+avoiding difficulties with singularities and points where there is a
+discontinuity in the derivative.
+
+After a successful computation, the value of @var{istate} will be 2
+(consistent with the Fortran version of @sc{Lsode}).
+
+If the computation is not successful, @var{istate} will be something
+other than 2 and @var{msg} will contain additional information.
+
+You can use the function @code{lsode_options} to set optional
+parameters for @code{lsode}.
+ at seealso{daspk, dassl, dasrt}
+ at end deftypefn
+lu
+ at c ./DLD-FUNCTIONS/lu.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}] =} lu (@var{a})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} lu (@var{s})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}] =} lu (@var{s})
+ at deftypefnx {Loadable Function} {[@dots{}] =} lu (@var{s}, @var{thres})
+ at deftypefnx {Loadable Function} {@var{y} =} lu (@dots{})
+ at deftypefnx {Loadable Function} {[@dots{}] =} lu (@dots{}, 'vector')
+ at cindex LU decomposition
+Compute the LU decomposition of @var{a}.  If @var{a} is full subroutines from
+ at sc{lapack} are used and if @var{a} is sparse then UMFPACK is used.  The
+result is returned in a permuted form, according to the optional return
+value @var{p}.  For example, given the matrix @code{a = [1, 2; 3, 4]},
+
+ at example
+[l, u, p] = lu (a)
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+l =
+
+  1.00000  0.00000
+  0.33333  1.00000
+
+u =
+
+  3.00000  4.00000
+  0.00000  0.66667
+
+p =
+
+  0  1
+  1  0
+ at end group
+ at end example
+
+The matrix is not required to be square.
+
+Called with two or three output arguments and a spare input matrix,
+then @dfn{lu} does not attempt to perform sparsity preserving column
+permutations.  Called with a fourth output argument, the sparsity
+preserving column transformation @var{Q} is returned, such that
+ at code{@var{p} * @var{a} * @var{q} = @var{l} * @var{u}}.
+
+Called with a fifth output argument and a sparse input matrix, then
+ at dfn{lu} attempts to use a scaling factor @var{r} on the input matrix
+such that @code{@var{p} * (@var{r} \ @var{a}) * @var{q} = @var{l} * @var{u}}.
+This typically leads to a sparser and more stable factorization.
+
+An additional input argument @var{thres}, that defines the pivoting
+threshold can be given.  @var{thres} can be a scalar, in which case
+it defines UMFPACK pivoting tolerance for both symmetric and unsymmetric
+cases.  If @var{thres} is a two element vector, then the first element
+defines the pivoting tolerance for the unsymmetric UMFPACK pivoting
+strategy and the second the symmetric strategy.  By default, the values
+defined by @code{spparms} are used and are by default @code{[0.1, 0.001]}.
+
+Given the string argument 'vector', @dfn{lu} returns the values of @var{p}
+ at var{q} as vector values, such that for full matrix, @code{@var{a}
+(@var{p},:) = @var{l} * @var{u}}, and @code{@var{r}(@var{p},:) * @var{a}
+(:, @var{q}) = @var{l} * @var{u}}.
+
+With two output arguments, returns the permuted forms of the upper and
+lower triangular matrices, such that @code{@var{a} = @var{l} * @var{u}}.
+With one output argument @var{y}, then the matrix returned by the @sc{lapack}
+routines is returned.  If the input matrix is sparse then the matrix @var{l}
+is embedded into @var{u} to give a return value similar to the full case.
+For both full and sparse matrices, @dfn{lu} looses the permutation
+information.
+ at end deftypefn
+luinc
+ at c ./DLD-FUNCTIONS/luinc.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, '0')
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, @var{droptol})
+ at deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} luinc (@var{a}, @var{opts})
+ at cindex LU decomposition
+Produce the incomplete LU factorization of the sparse matrix @var{a}.
+Two types of incomplete factorization are possible, and the type
+is determined by the second argument to @dfn{luinc}.
+
+Called with a second argument of '0', the zero-level incomplete
+LU factorization is produced.  This creates a factorization of @var{a}
+where the position of the non-zero arguments correspond to the same
+positions as in the matrix @var{a}.
+
+Alternatively, the fill-in of the incomplete LU factorization can
+be controlled through the variable @var{droptol} or the structure
+ at var{opts}.  The UMFPACK multifrontal factorization code by Tim A.
+Davis is used for the incomplete LU factorization, (availability
+ at url{http://www.cise.ufl.edu/research/sparse/umfpack/})
+
+ at var{droptol} determines the values below which the values in the LU
+factorization are dropped and replaced by zero.  It must be a positive
+scalar, and any values in the factorization whose absolute value are
+less than this value are dropped, expect if leaving them increase the
+sparsity of the matrix.  Setting @var{droptol} to zero results in a
+complete LU factorization which is the default.
+
+ at var{opts} is a structure containing one or more of the fields
+
+ at table @code
+ at item droptol
+The drop tolerance as above.  If @var{opts} only contains @code{droptol}
+then this is equivalent to using the variable @var{droptol}.
+
+ at item milu
+A logical variable flagging whether to use the modified incomplete LU
+factorization.  In the case that @code{milu} is true, the dropped values
+are subtracted from the diagonal of the matrix U of the factorization.
+The default is @code{false}.
+
+ at item udiag
+A logical variable that flags whether zero elements on the diagonal of U
+should be replaced with @var{droptol} to attempt to avoid singular
+factors.  The default is @code{false}.
+
+ at item thresh
+Defines the pivot threshold in the interval [0,1].  Values outside that
+range are ignored.
+ at end table
+
+All other fields in @var{opts} are ignored.  The outputs from @dfn{luinc}
+are the same as for @dfn{lu}.
+
+Given the string argument 'vector', @dfn{luinc} returns the values of @var{p}
+ at var{q} as vector values.
+ at seealso{sparse, lu}
+ at end deftypefn
+abs
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} abs (@var{z})
+Compute the magnitude of @var{z}, defined as
+ at tex
+$|z| = \sqrt{x^2 + y^2}$.
+ at end tex
+ at ifnottex
+|@var{z}| = @code{sqrt (x^2 + y^2)}.
+ at end ifnottex
+
+For example,
+
+ at example
+ at group
+abs (3 + 4i)
+     @result{} 5
+ at end group
+ at end example
+ at end deftypefn
+acos
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} acos (@var{x})
+Compute the inverse cosine in radians for each element of @var{x}.
+ at seealso{cos, acosd}
+ at end deftypefn
+acosh
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} acosh (@var{x})
+Compute the inverse hyperbolic cosine for each element of @var{x}.
+ at seealso{cosh}
+ at end deftypefn
+angle
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} angle (@var{z})
+See arg.
+ at end deftypefn
+arg
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} arg (@var{z})
+ at deftypefnx {Mapping Function} {} angle (@var{z})
+Compute the argument of @var{z}, defined as,
+ at tex
+$\theta = atan2 (y, x),$
+ at end tex
+ at ifnottex
+ at var{theta} = @code{atan2 (@var{y}, @var{x})},
+ at end ifnottex
+in radians.
+
+For example,
+
+ at example
+ at group
+arg (3 + 4i)
+     @result{} 0.92730
+ at end group
+ at end example
+ at end deftypefn
+asin
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} asin (@var{x})
+Compute the inverse sine in radians for each element of @var{x}.
+ at seealso{sin, asind}
+ at end deftypefn
+asinh
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} asinh (@var{x})
+Compute the inverse hyperbolic sine for each element of @var{x}.
+ at seealso{sinh}
+ at end deftypefn
+atan
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} atan (@var{x})
+Compute the inverse tangent in radians for each element of @var{x}.
+ at seealso{tan, atand}
+ at end deftypefn
+atanh
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} atanh (@var{x})
+Compute the inverse hyperbolic tangent for each element of @var{x}.
+ at seealso{tanh}
+ at end deftypefn
+ceil
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} ceil (@var{x})
+Return the smallest integer not less than @var{x}.  This is equivalent to
+rounding towards positive infinity.  If @var{x} is
+complex, return @code{ceil (real (@var{x})) + ceil (imag (@var{x})) * I}.
+ at example
+ at group
+ceil ([-2.7, 2.7])
+   @result{}  -2   3
+ at end group
+ at end example
+ at seealso{floor, round, fix}
+ at end deftypefn
+conj
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} conj (@var{z})
+Return the complex conjugate of @var{z}, defined as
+ at tex
+$\bar{z} = x - iy$.
+ at end tex
+ at ifnottex
+ at code{conj (@var{z})} = @var{x} - @var{i}@var{y}.
+ at end ifnottex
+ at seealso{real, imag}
+ at end deftypefn
+cos
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} cos (@var{x})
+Compute the cosine for each element of @var{x} in radians.
+ at seealso{acos, cosd, cosh}
+ at end deftypefn
+cosh
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} cosh (@var{x})
+Compute the hyperbolic cosine for each element of @var{x}.
+ at seealso{acosh, sinh, tanh}
+ at end deftypefn
+erf
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} erf (@var{z})
+Computes the error function,
+ at iftex
+ at tex
+$$
+ {\rm erf} (z) = {2 \over \sqrt{\pi}}\int_0^z e^{-t^2} dt
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at group
+                         z
+                        /
+erf (z) = (2/sqrt (pi)) | e^(-t^2) dt
+                        /
+                     t=0
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{erfc, erfinv}
+ at end deftypefn
+erfc
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} erfc (@var{z})
+Computes the complementary error function,
+ at iftex
+ at tex
+$1 - {\rm erf} (z)$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{1 - erf (@var{z})}.
+ at end ifnottex
+ at seealso{erf, erfinv}
+ at end deftypefn
+exp
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} exp (@var{x})
+Compute
+ at tex
+$e^{x}$
+ at end tex
+ at ifnottex
+ at code{e^x}
+ at end ifnottex
+for each element of @var{x}.  To compute the matrix
+exponential, see @ref{Linear Algebra}.
+ at seealso{log}
+ at end deftypefn
+expm1
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} expm1 (@var{x})
+Compute
+ at tex
+$ e^{x} - 1 $
+ at end tex
+ at ifnottex
+ at code{exp (@var{x}) - 1}
+ at end ifnottex
+accurately in the neighborhood of zero.
+ at seealso{exp}
+ at end deftypefn
+finite
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} finite (@var{x})
+Return 1 for elements of @var{x} that are finite values and zero
+otherwise.  For example,
+
+ at example
+ at group
+finite ([13, Inf, NA, NaN])
+     @result{} [ 1, 0, 0, 0 ]
+ at end group
+ at end example
+ at end deftypefn
+fix
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} fix (@var{x})
+Truncate fractional portion of @var{x} and return the integer portion.  This
+is equivalent to rounding towards zero.  If @var{x} is complex, return
+ at code{fix (real (@var{x})) + fix (imag (@var{x})) * I}.
+ at example
+ at group
+fix ([-2.7, 2.7])
+   @result{} -2   2
+ at end group
+ at end example
+ at seealso{ceil, floor, round}
+ at end deftypefn
+floor
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} floor (@var{x})
+Return the largest integer not greater than @var{x}.  This is equivalent to
+rounding towards negative infinity.  If @var{x} is
+complex, return @code{floor (real (@var{x})) + floor (imag (@var{x})) * I}.
+ at example
+ at group
+floor ([-2.7, 2.7])
+     @result{} -3   2
+ at end group
+ at end example
+ at seealso{ceil, round, fix}
+ at end deftypefn
+gamma
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} gamma (@var{z})
+Computes the Gamma function,
+ at iftex
+ at tex
+$$
+ \Gamma (z) = \int_0^\infty t^{z-1} e^{-t} dt.
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at group
+            infinity
+            /
+gamma (z) = | t^(z-1) exp (-t) dt.
+            /
+         t=0
+ at end group
+ at end example
+ at end ifnottex
+ at seealso{gammainc, lgamma}
+ at end deftypefn
+imag
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} imag (@var{z})
+Return the imaginary part of @var{z} as a real number.
+ at seealso{real, conj}
+ at end deftypefn
+isalnum
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isalnum (@var{s})
+Return 1 for characters that are letters or digits (@code{isalpha
+(@var{s})} or @code{isdigit (@var{s})} is true).
+ at end deftypefn
+isalpha
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isalpha (@var{s})
+ at deftypefnx {Mapping Function} {} isletter (@var{s})
+Return true for characters that are letters (@code{isupper (@var{s})}
+or @code{islower (@var{s})} is true).
+ at end deftypefn
+isascii
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isascii (@var{s})
+Return 1 for characters that are ASCII (in the range 0 to 127 decimal).
+ at end deftypefn
+iscntrl
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} iscntrl (@var{s})
+Return 1 for control characters.
+ at end deftypefn
+isdigit
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isdigit (@var{s})
+Return 1 for characters that are decimal digits.
+ at end deftypefn
+isinf
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isinf (@var{x})
+Return 1 for elements of @var{x} that are infinite and zero
+otherwise.  For example,
+
+ at example
+ at group
+isinf ([13, Inf, NA, NaN])
+     @result{} [ 0, 1, 0, 0 ]
+ at end group
+ at end example
+ at end deftypefn
+isgraph
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isgraph (@var{s})
+Return 1 for printable characters (but not the space character).
+ at end deftypefn
+islower
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} islower (@var{s})
+Return 1 for characters that are lower case letters.
+ at end deftypefn
+isna
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isna (@var{x})
+Return 1 for elements of @var{x} that are NA (missing) values and zero
+otherwise.  For example,
+
+ at example
+ at group
+isna ([13, Inf, NA, NaN])
+     @result{} [ 0, 0, 1, 0 ]
+ at end group
+ at end example
+ at seealso{isnan}
+ at end deftypefn
+isnan
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isnan (@var{x})
+Return 1 for elements of @var{x} that are NaN values and zero
+otherwise.  NA values are also considered NaN values.  For example,
+
+ at example
+ at group
+isnan ([13, Inf, NA, NaN])
+     @result{} [ 0, 0, 1, 1 ]
+ at end group
+ at end example
+ at seealso{isna}
+ at end deftypefn
+isprint
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isprint (@var{s})
+Return 1 for printable characters (including the space character).
+ at end deftypefn
+ispunct
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} ispunct (@var{s})
+Return 1 for punctuation characters.
+ at end deftypefn
+isspace
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isspace (@var{s})
+Return 1 for whitespace characters (space, formfeed, newline,
+carriage return, tab, and vertical tab).
+ at end deftypefn
+isupper
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isupper (@var{s})
+Return 1 for upper case letters.
+ at end deftypefn
+isxdigit
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} isxdigit (@var{s})
+Return 1 for characters that are hexadecimal digits.
+ at end deftypefn
+lgamma
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} lgamma (@var{x})
+ at deftypefnx {Mapping Function} {} gammaln (@var{x})
+Return the natural logarithm of the gamma function of @var{x}.
+ at seealso{gamma, gammainc}
+ at end deftypefn
+log
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} log (@var{x})
+Compute the natural logarithm,
+ at tex
+$\ln{(x)},$
+ at end tex
+ at ifnottex
+ at code{ln (@var{x})},
+ at end ifnottex
+for each element of @var{x}.  To compute the
+matrix logarithm, see @ref{Linear Algebra}.
+ at seealso{exp, log1p, log2, log10, logspace}
+ at end deftypefn
+log10
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} log10 (@var{x})
+Compute the base-10 logarithm of each element of @var{x}.
+ at seealso{log, log2, logspace, exp}
+ at end deftypefn
+log1p
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} log1p (@var{x})
+Compute
+ at tex
+$\ln{(1 + x)}$
+ at end tex
+ at ifnottex
+ at code{log (1 + @var{x})}
+ at end ifnottex
+accurately in the neighborhood of zero.
+ at seealso{log, exp, expm1}
+ at end deftypefn
+real
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} real (@var{z})
+Return the real part of @var{z}.
+ at seealso{imag, conj}
+ at end deftypefn
+round
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} round (@var{x})
+Return the integer nearest to @var{x}.  If @var{x} is complex, return
+ at code{round (real (@var{x})) + round (imag (@var{x})) * I}.
+ at example
+ at group
+round ([-2.7, 2.7])
+     @result{} -3   3
+ at end group
+ at end example
+ at seealso{ceil, floor, fix}
+ at end deftypefn
+roundb
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} roundb (@var{x})
+Return the integer nearest to @var{x}.  If there are two nearest
+integers, return the even one (banker's rounding).  If @var{x} is complex,
+return @code{roundb (real (@var{x})) + roundb (imag (@var{x})) * I}.
+ at seealso{round}
+ at end deftypefn
+sign
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} sign (@var{x})
+Compute the @dfn{signum} function, which is defined as
+ at tex
+$$
+{\rm sign} (@var{x}) = \cases{1,&$x>0$;\cr 0,&$x=0$;\cr -1,&$x<0$.\cr}
+$$
+ at end tex
+ at ifnottex
+
+ at example
+ at group
+           -1, x < 0;
+sign (x) =  0, x = 0;
+            1, x > 0.
+ at end group
+ at end example
+ at end ifnottex
+
+For complex arguments, @code{sign} returns @code{x ./ abs (@var{x})}.
+ at end deftypefn
+sin
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} sin (@var{x})
+Compute the sine for each element of @var{x} in radians.
+ at seealso{asin, sind, sinh}
+ at end deftypefn
+sinh
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} sinh (@var{x})
+Compute the hyperbolic sine for each element of @var{x}.
+ at seealso{asinh, cosh, tanh}
+ at end deftypefn
+sqrt
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} sqrt (@var{x})
+Compute the square root of each element of @var{x}.  If @var{x} is negative,
+a complex result is returned.  To compute the matrix square root, see
+ at ref{Linear Algebra}.
+ at seealso{realsqrt}
+ at end deftypefn
+tan
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} tan (@var{z})
+Compute the tangent for each element of @var{x} in radians.
+ at seealso{atan, tand, tanh}
+ at end deftypefn
+tanh
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} tanh (@var{x})
+Compute hyperbolic tangent for each element of @var{x}.
+ at seealso{atanh, sinh, cosh}
+ at end deftypefn
+toascii
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} toascii (@var{s})
+Return ASCII representation of @var{s} in a matrix.  For example,
+
+ at example
+ at group
+toascii ("ASCII")
+     @result{} [ 65, 83, 67, 73, 73 ]
+ at end group
+
+ at end example
+ at seealso{char}
+ at end deftypefn
+tolower
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Mapping Function} {} tolower (@var{s})
+ at deftypefnx {Mapping Function} {} lower (@var{s})
+Return a copy of the string or cell string @var{s}, with each upper-case
+character replaced by the corresponding lower-case one; non-alphabetic
+characters are left unchanged.  For example,
+
+ at example
+ at group
+tolower ("MiXeD cAsE 123")
+     @result{} "mixed case 123"
+ at end group
+ at end example
+ at seealso{toupper}
+ at end deftypefn
+toupper
+ at c mappers.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} toupper (@var{s})
+ at deftypefnx {Built-in Function} {} upper (@var{s})
+Return a copy of the string or cell string @var{s}, with each lower-case
+character replaced by the corresponding upper-case one; non-alphabetic
+characters are left unchanged.  For example,
+
+ at example
+ at group
+toupper ("MiXeD cAsE 123")
+     @result{} "MIXED CASE 123"
+ at end group
+ at end example
+ at seealso{tolower}
+ at end deftypefn
+matrix_type
+ at c ./DLD-FUNCTIONS/matrix_type.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{type} =} matrix_type (@var{a})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, @var{type})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'upper', @var{perm})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'lower', @var{perm})
+ at deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, 'banded', @var{nl}, @var{nu})
+Identify the matrix type or mark a matrix as a particular type.  This allows rapid
+for solutions of linear equations involving @var{a} to be performed.  Called with a
+single argument, @code{matrix_type} returns the type of the matrix and caches it for
+future use.  Called with more than one argument, @code{matrix_type} allows the type
+of the matrix to be defined.
+
+The possible matrix types depend on whether the matrix is full or sparse, and can be
+one of the following
+
+ at table @asis
+ at item 'unknown'
+Remove any previously cached matrix type, and mark type as unknown
+
+ at item 'full'
+Mark the matrix as full.
+
+ at item 'positive definite'
+Probable full positive definite matrix.
+
+ at item 'diagonal'
+Diagonal Matrix.  (Sparse matrices only)
+
+ at item 'permuted diagonal'
+Permuted Diagonal matrix.  The permutation does not need to be specifically
+indicated, as the structure of the matrix explicitly gives this.  (Sparse matrices
+only)
+
+ at item 'upper'
+Upper triangular.  If the optional third argument @var{perm} is given, the matrix is
+assumed to be a permuted upper triangular with the permutations defined by the
+vector @var{perm}.
+
+ at item 'lower'
+Lower triangular.  If the optional third argument @var{perm} is given, the matrix is
+assumed to be a permuted lower triangular with the permutations defined by the
+vector @var{perm}.
+
+ at item 'banded'
+ at itemx 'banded positive definite'
+Banded matrix with the band size of @var{nl} below the diagonal and @var{nu} above
+it.  If @var{nl} and @var{nu} are 1, then the matrix is tridiagonal and treated
+with specialized code.  In addition the matrix can be marked as probably a
+positive definite (Sparse matrices only)
+
+ at item 'singular'
+The matrix is assumed to be singular and will be treated with a minimum norm solution
+
+ at end table
+
+Note that the matrix type will be discovered automatically on the first attempt to
+solve a linear equation involving @var{a}.  Therefore @code{matrix_type} is only
+useful to give Octave hints of the matrix type.  Incorrectly defining the
+matrix type will result in incorrect results from solutions of linear equations,
+and so it is entirely the responsibility of the user to correctly identify the
+matrix type.
+
+Also the test for positive definiteness is a low-cost test for a hermitian
+matrix with a real positive diagonal.  This does not guarantee that the matrix
+is positive definite, but only that it is a probable candidate.  When such a
+matrix is factorized, a Cholesky factorization is first attempted, and if
+that fails the matrix is then treated with an LU factorization.  Once the
+matrix has been factorized, @code{matrix_type} will return the correct
+classification of the matrix.
+ at end deftypefn
+min
+ at c ./DLD-FUNCTIONS/max.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {} min (@var{x})
+ at deftypefnx {Loadable Function} {} min (@var{x}, @var{y})
+ at deftypefnx {Loadable Function} {} min (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} min (@var{x})
+For a vector argument, return the minimum value.  For a matrix
+argument, return the minimum value from each column, as a row
+vector, or over the dimension @var{dim} if defined.  For two matrices
+(or a matrix and scalar), return the pair-wise minimum.
+Thus,
+
+ at example
+min (min (@var{x}))
+ at end example
+
+ at noindent
+returns the smallest element of @var{x}, and
+
+ at example
+ at group
+min (2:5, pi)
+    @result{}  2.0000  3.0000  3.1416  3.1416
+ at end group
+ at end example
+ at noindent
+compares each element of the range @code{2:5} with @code{pi}, and
+returns a row vector of the minimum values.
+
+For complex arguments, the magnitude of the elements are used for
+comparison.
+
+If called with one input and two output arguments,
+ at code{min} also returns the first index of the
+minimum value(s).  Thus,
+
+ at example
+ at group
+[x, ix] = min ([1, 3, 0, 2, 0])
+    @result{}  x = 0
+        ix = 3
+ at end group
+ at end example
+ at seealso{max, cummin, cummax}
+ at end deftypefn
+max
+ at c ./DLD-FUNCTIONS/max.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {} max (@var{x})
+ at deftypefnx {Loadable Function} {} max (@var{x}, @var{y})
+ at deftypefnx {Loadable Function} {} max (@var{x}, @var{y}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} max (@var{x})
+For a vector argument, return the maximum value.  For a matrix
+argument, return the maximum value from each column, as a row
+vector, or over the dimension @var{dim} if defined.  For two matrices
+(or a matrix and scalar), return the pair-wise maximum.
+Thus,
+
+ at example
+max (max (@var{x}))
+ at end example
+
+ at noindent
+returns the largest element of the matrix @var{x}, and
+
+ at example
+ at group
+max (2:5, pi)
+    @result{}  3.1416  3.1416  4.0000  5.0000
+ at end group
+ at end example
+ at noindent
+compares each element of the range @code{2:5} with @code{pi}, and
+returns a row vector of the maximum values.
+
+For complex arguments, the magnitude of the elements are used for
+comparison.
+
+If called with one input and two output arguments,
+ at code{max} also returns the first index of the
+maximum value(s).  Thus,
+
+ at example
+ at group
+[x, ix] = max ([1, 3, 5, 2, 5])
+    @result{}  x = 5
+        ix = 3
+ at end group
+ at end example
+ at seealso{min, cummax, cummin}
+ at end deftypefn
+cummin
+ at c ./DLD-FUNCTIONS/max.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {} cummin (@var{x})
+ at deftypefnx {Loadable Function} {} cummin (@var{x}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} cummin (@var{x})
+Return the cumulative minimum values along dimension @var{dim}.  If @var{dim}
+is unspecified it defaults to column-wise operation.  For example,
+
+ at example
+ at group
+cummin ([5 4 6 2 3 1])
+    @result{}  5  4  4  2  2  1
+ at end group
+ at end example
+
+
+The call
+ at example
+  [w, iw] = cummin (x, dim)
+ at end example
+
+ at noindent
+is equivalent to the following code:
+ at example
+ at group
+w = iw = zeros (size (x));
+idxw = idxx = repmat (@{':'@}, 1, ndims (x));
+for i = 1:size (x, dim)
+  idxw@{dim@} = i; idxx@{dim@} = 1:i;
+  [w(idxw@{:@}), iw(idxw@{:@})] = min(x(idxx@{:@}), [], dim);
+endfor
+ at end group
+ at end example
+
+ at noindent
+but computed in a much faster manner.
+ at seealso{cummax, min, max}
+ at end deftypefn
+cummax
+ at c ./DLD-FUNCTIONS/max.cc
+-*- texinfo -*-
+ at deftypefn  {Loadable Function} {} cummax (@var{x})
+ at deftypefnx {Loadable Function} {} cummax (@var{x}, @var{dim})
+ at deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} cummax (@var{x})
+Return the cumulative maximum values along dimension @var{dim}.  If @var{dim}
+is unspecified it defaults to column-wise operation.  For example,
+
+ at example
+ at group
+cummax ([1 3 2 6 4 5])
+    @result{}  1  3  3  6  6  6
+ at end group
+ at end example
+
+The call
+ at example
+[w, iw] = cummax (x, dim)
+ at end example
+
+ at noindent
+is equivalent to the following code:
+ at example
+ at group
+w = iw = zeros (size (x));
+idxw = idxx = repmat (@{':'@}, 1, ndims (x));
+for i = 1:size (x, dim)
+  idxw@{dim@} = i; idxx@{dim@} = 1:i;
+  [w(idxw@{:@}), iw(idxw@{:@})] = max(x(idxx@{:@}), [], dim);
+endfor
+ at end group
+ at end example
+
+ at noindent
+but computed in a much faster manner.
+ at seealso{cummin, max, min}
+ at end deftypefn
+md5sum
+ at c ./DLD-FUNCTIONS/md5sum.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} md5sum (@var{file})
+ at deftypefnx {Loadable Function} {} md5sum (@var{str}, @var{opt})
+Calculates the MD5 sum of the file @var{file}.  If the second parameter
+ at var{opt} exists and is true, then calculate the MD5 sum of the
+string @var{str}.
+ at end deftypefn
+edit_history
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deffn {Command} edit_history [@var{first}] [@var{last}]
+If invoked with no arguments, @code{edit_history} allows you to edit the
+history list using the editor named by the variable @w{@code{EDITOR}}.  The
+commands to be edited are first copied to a temporary file.  When you
+exit the editor, Octave executes the commands that remain in the file.
+It is often more convenient to use @code{edit_history} to define functions 
+rather than attempting to enter them directly on the command line.
+By default, the block of commands is executed as soon as you exit the
+editor.  To avoid executing any commands, simply delete all the lines
+from the buffer before exiting the editor.
+
+The @code{edit_history} command takes two optional arguments specifying
+the history numbers of first and last commands to edit.  For example,
+the command
+
+ at example
+edit_history 13
+ at end example
+
+ at noindent
+extracts all the commands from the 13th through the last in the history
+list.  The command
+
+ at example
+edit_history 13 169
+ at end example
+
+ at noindent
+only extracts commands 13 through 169.  Specifying a larger number for
+the first command than the last command reverses the list of commands
+before placing them in the buffer to be edited.  If both arguments are
+omitted, the previous command in the history list is used.
+ at seealso{run_history}
+ at end deffn
+history
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deffn {Command} history options
+If invoked with no arguments, @code{history} displays a list of commands
+that you have executed.  Valid options are:
+
+ at table @code
+ at item -w @var{file}
+Write the current history to the file @var{file}.  If the name is
+omitted, use the default history file (normally @file{~/.octave_hist}).
+
+ at item -r @var{file}
+Read the file @var{file}, replacing the current history list with its
+contents.  If the name is omitted, use the default history file
+(normally @file{~/.octave_hist}).
+
+ at item @var{n}
+Display only the most recent @var{n} lines of history.
+
+ at item -q
+Don't number the displayed lines of history.  This is useful for cutting
+and pasting commands using the X Window System.
+ at end table
+
+For example, to display the five most recent commands that you have
+typed without displaying line numbers, use the command
+ at kbd{history -q 5}.
+ at end deffn
+run_history
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deffn {Command} run_history [@var{first}] [@var{last}]
+Similar to @code{edit_history}, except that the editor is not invoked,
+and the commands are simply executed as they appear in the history list.
+ at seealso{edit_history}
+ at end deffn
+history_size
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} history_size ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_size (@var{new_val})
+Query or set the internal variable that specifies how many entries
+to store in the history file.  The default value is @code{1024},
+but may be overridden by the environment variable @w{@code{OCTAVE_HISTSIZE}}.
+ at seealso{history_file, history_timestamp_format_string, saving_history}
+ at end deftypefn
+history_file
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} history_file ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_file (@var{new_val})
+Query or set the internal variable that specifies the name of the
+file used to store command history.  The default value is
+ at file{~/.octave_hist}, but may be overridden by the environment
+variable @w{@code{OCTAVE_HISTFILE}}.
+ at seealso{history_size, saving_history, history_timestamp_format_string}
+ at end deftypefn
+history_timestamp_format_string
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} history_timestamp_format_string ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_timestamp_format_string (@var{new_val})
+Query or set the internal variable that specifies the format string
+for the comment line that is written to the history file when Octave
+exits.  The format string is passed to @code{strftime}.  The default
+value is
+
+ at example
+"# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>"
+ at end example
+ at seealso{strftime, history_file, history_size, saving_history}
+ at end deftypefn
+saving_history
+ at c oct-hist.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} saving_history ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} saving_history (@var{new_val})
+Query or set the internal variable that controls whether commands entered
+on the command line are saved in the history file.
+ at seealso{history_file, history_size, history_timestamp_format_string}
+ at end deftypefn
+__version_info__
+ at c octave.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {retval =} __version_info__ (@var{name}, @var{version}, @var{release}, @var{date})
+Undocumented internal function.
+ at end deftypefn
+argv
+ at c octave.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} argv ()
+Return the command line arguments passed to Octave.  For example,
+if you invoked Octave using the command
+
+ at example
+octave --no-line-editing --silent
+ at end example
+
+ at noindent
+ at code{argv} would return a cell array of strings with the elements
+ at code{--no-line-editing} and @code{--silent}.
+
+If you write an executable Octave script, @code{argv} will return the
+list of arguments passed to the script.  @xref{Executable Octave Programs},
+for an example of how to create an executable Octave script.
+ at end deftypefn
+program_invocation_name
+ at c octave.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} program_invocation_name ()
+Return the name that was typed at the shell prompt to run Octave.
+
+If executing a script from the command line (e.g., @code{octave foo.m})
+or using an executable Octave script, the program name is set to the
+name of the script.  @xref{Executable Octave Programs}, for an example of
+how to create an executable Octave script.
+ at seealso{program_name}
+ at end deftypefn
+program_name
+ at c octave.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} program_name ()
+Return the last component of the value returned by
+ at code{program_invocation_name}.
+ at seealso{program_invocation_name}
+ at end deftypefn
+sparse_auto_mutate
+ at c ov-base.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} sparse_auto_mutate ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} sparse_auto_mutate (@var{new_val})
+Query or set the internal variable that controls whether Octave will
+automatically mutate sparse matrices to real matrices to save memory.
+For example,
+
+ at example
+ at group
+s = speye(3);
+sparse_auto_mutate (false)
+s (:, 1) = 1;
+typeinfo (s)
+ at result{} sparse matrix
+sparse_auto_mutate (true)
+s (1, :) = 1;
+typeinfo (s)
+ at result{} matrix
+ at end group
+ at end example
+ at end deftypefn
+iscell
+ at c ov-cell.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} iscell (@var{x})
+Return true if @var{x} is a cell array object.  Otherwise, return
+false.
+ at end deftypefn
+cell
+ at c ov-cell.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} cell (@var{x})
+ at deftypefnx {Built-in Function} {} cell (@var{n}, @var{m})
+Create a new cell array object.  If invoked with a single scalar
+argument, @code{cell} returns a square cell array with the dimension
+specified.  If you supply two scalar arguments, @code{cell} takes
+them to be the number of rows and columns.  If given a vector with two
+elements, @code{cell} uses the values of the elements as the number of
+rows and columns, respectively.
+ at end deftypefn
+iscellstr
+ at c ov-cell.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} iscellstr (@var{cell})
+Return true if every element of the cell array @var{cell} is a
+character string
+ at end deftypefn
+cellstr
+ at c ov-cell.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} cellstr (@var{string})
+Create a new cell array object from the elements of the string
+array @var{string}.
+ at end deftypefn
+struct2cell
+ at c ov-cell.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} struct2cell (@var{S})
+Create a new cell array from the objects stored in the struct object.
+If @var{f} is the number of fields in the structure, the resulting
+cell array will have a dimension vector corresponding to
+ at code{[@var{F} size(@var{S})]}.
+ at seealso{cell2struct, fieldnames}
+ at end deftypefn
+class
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} class (@var{expr})
+ at deftypefnx {Built-in Function} {} class (@var{s}, @var{id})
+ at deftypefnx {Built-in Function} {} class (@var{s}, @var{id}, @var{p}, @dots{})
+Return the class of the expression @var{expr} or create a class with
+fields from structure @var{s} and name (string) @var{id}.  Additional
+arguments name a list of parent classes from which the new class is
+derived.
+ at end deftypefn
+__isa_parent__
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __isa_parent__ (@var{class}, @var{name})
+Undocumented internal function.
+ at end deftypefn
+__parent_classes__
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __parent_classes__ (@var{x})
+Undocumented internal function.
+ at end deftypefn
+isobject
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isobject (@var{x})
+Return true if @var{x} is a class object.
+ at end deftypefn
+ismethod
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ismethod (@var{x}, @var{method})
+Return true if @var{x} is a class object and the string @var{method}
+is a method of this class.
+ at end deftypefn
+methods
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} methods (@var{x})
+ at deftypefnx {Built-in Function} {} methods ("classname")
+Return a cell array containing the names of the methods for the
+object @var{x} or the named class.
+ at end deftypefn
+superiorto
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} superiorto (@var{class_name}, @dots{})
+When called from a class constructor, mark the object currently
+constructed as having a higher precedence than @var{class_name}.
+More that one such class can be specified in a single call.
+This function may only be called from a class constructor.
+ at end deftypefn
+inferiorto
+ at c ov-class.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} inferiorto (@var{class_name}, @dots{})
+When called from a class constructor, mark the object currently
+constructed as having a lower precedence than @var{class_name}.
+More that one such class can be specified in a single call.
+This function may only be called from a class constructor.
+ at end deftypefn
+functions
+ at c ov-fcn-handle.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} functions (@var{fcn_handle})
+Return a struct containing information about the function handle
+ at var{fcn_handle}.
+ at end deftypefn
+func2str
+ at c ov-fcn-handle.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} func2str (@var{fcn_handle})
+Return a string containing the name of the function referenced by
+the function handle @var{fcn_handle}.
+ at end deftypefn
+str2func
+ at c ov-fcn-handle.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} str2func (@var{fcn_name})
+Return a function handle constructed from the string @var{fcn_name}.
+ at end deftypefn
+inline
+ at c ov-fcn-inline.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} inline (@var{str})
+ at deftypefnx {Built-in Function} {} inline (@var{str}, @var{arg1}, @dots{})
+ at deftypefnx {Built-in Function} {} inline (@var{str}, @var{n})
+Create an inline function from the character string @var{str}.
+If called with a single argument, the arguments of the generated
+function are extracted from the function itself.  The generated
+function arguments will then be in alphabetical order.  It should
+be noted that i, and j are ignored as arguments due to the
+ambiguity between their use as a variable or their use as an inbuilt
+constant.  All arguments followed by a parenthesis are considered
+to be functions.
+
+If the second and subsequent arguments are character strings,
+they are the names of the arguments of the function.
+
+If the second argument is an integer @var{n}, the arguments are
+ at code{"x"}, @code{"P1"}, @dots{}, @code{"P at var{N}"}.
+ at seealso{argnames, formula, vectorize}
+ at end deftypefn
+formula
+ at c ov-fcn-inline.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} formula (@var{fun})
+Return a character string representing the inline function @var{fun}.
+Note that @code{char (@var{fun})} is equivalent to
+ at code{formula (@var{fun})}.
+ at seealso{argnames, inline, vectorize}
+ at end deftypefn
+argnames
+ at c ov-fcn-inline.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} argnames (@var{fun})
+Return a cell array of character strings containing the names of
+the arguments of the inline function @var{fun}.
+ at seealso{inline, formula, vectorize}
+ at end deftypefn
+vectorize
+ at c ov-fcn-inline.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} vectorize (@var{fun})
+Create a vectorized version of the inline function @var{fun}
+by replacing all occurrences of @code{*}, @code{/}, etc., with
+ at code{.*}, @code{./}, etc.
+ at end deftypefn
+single
+ at c ov-flt-re-mat.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} single (@var{x})
+Convert @var{x} to single precision type.
+ at seealso{double}
+ at end deftypefn
+int16
+ at c ov-int16.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} int16 (@var{x})
+Convert @var{x} to 16-bit integer type.
+ at end deftypefn
+int32
+ at c ov-int32.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} int32 (@var{x})
+Convert @var{x} to 32-bit integer type.
+ at end deftypefn
+int64
+ at c ov-int64.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} int64 (@var{x})
+Convert @var{x} to 64-bit integer type.
+ at end deftypefn
+int8
+ at c ov-int8.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} int8 (@var{x})
+Convert @var{x} to 8-bit integer type.
+ at end deftypefn
+list
+ at c ov-list.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} list (@var{a1}, @var{a2}, @dots{})
+Create a new list with elements given by the arguments @var{a1},
+ at var{a2}, @dots{}.
+ at end deftypefn
+nth
+ at c ov-list.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} nth (@var{list}, @var{n})
+Return the @var{n}-th element of @var{list}.
+ at end deftypefn
+append
+ at c ov-list.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} append (@var{list}, @var{a1}, @var{a2}, @dots{})
+Return a new list created by appending @var{a1}, @var{a2}, @dots{}, to
+ at var{list}.  If any of the arguments to be appended is a list, its
+elements are appended individually.  For example,
+
+ at example
+ at group
+x = list (1, 2);
+y = list (3, 4);
+append (x, y);
+ at end group
+ at end example
+
+ at noindent
+results in the list containing the four elements @samp{(1 2 3 4)}, not
+a list containing the three elements @samp{(1 2 (3 4))}.
+ at end deftypefn
+reverse
+ at c ov-list.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} reverse (@var{list})
+Return a new list created by reversing the elements of @var{list}.
+ at end deftypefn
+splice
+ at c ov-list.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} splice (@var{list_1}, @var{offset}, @var{length}, @var{list_2})
+Replace @var{length} elements of @var{list_1} beginning at
+ at var{offset} with the contents of @var{list_2} (if any).  If
+ at var{length} is omitted, all elements from @var{offset} to the end of
+ at var{list_1} are replaced.  As a special case, if @var{offset} is one
+greater than the length of @var{list_1} and @var{length} is 0, splice
+is equivalent to @code{append (@var{list_1}, @var{list_2})}.
+ at end deftypefn
+isnull
+ at c ov-null-mat.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isnull (@var{x})
+Return 1 if @var{x} is a special null matrix, string or single quoted string.
+Indexed assignment with such a value as right-hand side should delete array elements.
+This function should be used when overloading indexed assignment for user-defined 
+classes instead of @code{isempty}, to distinguish the cases:
+ at table @asis
+ at item @code{A(I) = []}
+This should delete elements if @code{I} is nonempty.
+ at item @code{X = []; A(I) = X}
+This should give an error if @code{I} is nonempty.
+ at end table
+ at end deftypefn
+double
+ at c ov-re-mat.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} double (@var{x})
+Convert @var{x} to double precision type.
+ at seealso{single}
+ at end deftypefn
+struct
+ at c ov-struct.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} struct ("field", @var{value}, "field", @var{value}, @dots{})
+
+Create a structure and initialize its value.
+
+If the values are cell arrays, create a structure array and initialize
+its values.  The dimensions of each cell array of values must match.
+Singleton cells and non-cell values are repeated so that they fill
+the entire array.  If the cells are empty, create an empty structure
+array with the specified field names.
+
+If the argument is an object, return the underlying struct.
+ at end deftypefn
+isstruct
+ at c ov-struct.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isstruct (@var{expr})
+Return 1 if the value of the expression @var{expr} is a structure.
+ at end deftypefn
+fieldnames
+ at c ov-struct.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fieldnames (@var{struct})
+Return a cell array of strings naming the elements of the structure
+ at var{struct}.  It is an error to call @code{fieldnames} with an
+argument that is not a structure.
+ at end deftypefn
+isfield
+ at c ov-struct.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isfield (@var{expr}, @var{name})
+Return true if the expression @var{expr} is a structure and it includes an
+element named @var{name}.  The first argument must be a structure and
+the second must be a string.
+ at end deftypefn
+cell2struct
+ at c ov-struct.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} cell2struct (@var{cell}, @var{fields}, @var{dim})
+Convert @var{cell} to a structure.  The number of fields in @var{fields}
+must match the number of elements in @var{cell} along dimension @var{dim},
+that is @code{numel (@var{fields}) == size (@var{cell}, @var{dim})}.
+
+ at example
+ at group
+A = cell2struct (@{'Peter', 'Hannah', 'Robert';
+                   185, 170, 168@},
+                 @{'Name','Height'@}, 1);
+A(1)
+ at result{} ans =
+      @{
+        Height = 185
+        Name   = Peter
+      @}
+
+ at end group
+ at end example
+ at end deftypefn
+rmfield
+ at c ov-struct.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rmfield (@var{s}, @var{f})
+Remove field @var{f} from the structure @var{s}.  If @var{f} is a
+cell array of character strings or a character array, remove the
+named fields.
+ at seealso{cellstr, iscellstr, setfield}
+ at end deftypefn
+typeinfo
+ at c ov-typeinfo.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} typeinfo (@var{expr})
+
+Return the type of the expression @var{expr}, as a string.  If
+ at var{expr} is omitted, return an array of strings containing all the
+currently installed data types.
+ at end deftypefn
+uint16
+ at c ov-uint16.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} uint16 (@var{x})
+Convert @var{x} to unsigned 16-bit integer type.
+ at end deftypefn
+uint32
+ at c ov-uint32.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} uint32 (@var{x})
+Convert @var{x} to unsigned 32-bit integer type.
+ at end deftypefn
+uint64
+ at c ov-uint64.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} uint64 (@var{x})
+Convert @var{x} to unsigned 64-bit integer type.
+ at end deftypefn
+uint8
+ at c ov-uint8.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} uint8 (@var{x})
+Convert @var{x} to unsigned 8-bit integer type.
+ at end deftypefn
+nargin
+ at c ov-usr-fcn.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} nargin ()
+ at deftypefnx {Built-in Function} {} nargin (@var{fcn_name})
+Within a function, return the number of arguments passed to the function.
+At the top level, return the number of command line arguments passed to
+Octave.  If called with the optional argument @var{fcn_name}, return the
+maximum number of arguments the named function can accept, or -1 if the
+function accepts a variable number of arguments.
+ at seealso{nargout, varargin, varargout}
+ at end deftypefn
+nargout
+ at c ov-usr-fcn.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} nargout ()
+ at deftypefnx {Built-in Function} {} nargout (@var{fcn_name})
+Within a function, return the number of values the caller expects to
+receive.  If called with the optional argument @var{fcn_name}, return the
+maximum number of values the named function can produce, or -1 if the
+function can produce a variable number of values.
+
+For example,
+
+ at example
+f ()
+ at end example
+
+ at noindent
+will cause @code{nargout} to return 0 inside the function @code{f} and
+
+ at example
+[s, t] = f ()
+ at end example
+
+ at noindent
+will cause @code{nargout} to return 2 inside the function
+ at code{f}.
+
+At the top level, @code{nargout} is undefined.
+ at seealso{nargin, varargin, varargout}
+ at end deftypefn
+max_recursion_depth
+ at c ov-usr-fcn.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} max_recursion_depth ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} max_recursion_depth (@var{new_val})
+Query or set the internal limit on the number of times a function may
+be called recursively.  If the limit is exceeded, an error message is
+printed and control returns to the top level.
+ at end deftypefn
+sizeof
+ at c ov.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} sizeof (@var{val})
+Return the size of @var{val} in bytes
+ at end deftypefn
+subsref
+ at c ov.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})
+Perform the subscripted element selection operation according to
+the subscript specified by @var{idx}.
+
+The subscript @var{idx} is expected to be a structure array with
+fields @samp{type} and @samp{subs}.  Valid values for @samp{type}
+are @samp{"()"}, @samp{"@{@}"}, and @samp{"."}.
+The @samp{subs} field may be either @samp{":"} or a cell array
+of index values.
+
+The following example shows how to extract the two first columns of
+a matrix
+
+ at example
+ at group
+val = magic(3)
+     @result{} val = [ 8   1   6
+                3   5   7
+                4   9   2 ]
+idx.type = "()";
+idx.subs = @{":", 1:2@};
+subsref(val, idx)
+     @result{} [ 8   1 
+          3   5 
+          4   9 ]
+ at end group
+ at end example
+
+ at noindent
+Note that this is the same as writing @code{val(:,1:2)}.
+ at seealso{subsasgn, substruct}
+ at end deftypefn
+subsasgn
+ at c ov.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} subsasgn (@var{val}, @var{idx}, @var{rhs})
+Perform the subscripted assignment operation according to
+the subscript specified by @var{idx}.
+
+The subscript @var{idx} is expected to be a structure array with
+fields @samp{type} and @samp{subs}.  Valid values for @samp{type}
+are @samp{"()"}, @samp{"@{@}"}, and @samp{"."}.
+The @samp{subs} field may be either @samp{":"} or a cell array
+of index values.
+
+The following example shows how to set the two first columns of a
+3-by-3 matrix to zero.
+
+ at example
+ at group
+val = magic(3);
+idx.type = "()";
+idx.subs = @{":", 1:2@};
+subsasgn (val, idx, 0)
+     @result{} [ 0   0   6
+          0   0   7
+          0   0   2 ]
+ at end group
+ at end example
+
+Note that this is the same as writing @code{val(:,1:2) = 0}.
+ at seealso{subsref, substruct}
+ at end deftypefn
+diary
+ at c pager.cc
+-*- texinfo -*-
+ at deffn {Command} diary options
+Record a list of all commands @emph{and} the output they produce, mixed
+together just as you see them on your terminal.  Valid options are:
+
+ at table @code
+ at item on
+Start recording your session in a file called @file{diary} in your
+current working directory.
+
+ at item off
+Stop recording your session in the diary file.
+
+ at item @var{file}
+Record your session in the file named @var{file}.
+ at end table
+
+With no arguments, @code{diary} toggles the current diary state.
+ at end deffn
+more
+ at c pager.cc
+-*- texinfo -*-
+ at deffn {Command} more
+ at deffnx {Command} more on
+ at deffnx {Command} more off
+Turn output pagination on or off.  Without an argument, @code{more}
+toggles the current state.
+The current state can be determined via @code{page_screen_output}.
+ at end deffn
+terminal_size
+ at c pager.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} terminal_size ()
+Return a two-element row vector containing the current size of the
+terminal window in characters (rows and columns).
+ at seealso{list_in_columns}
+ at end deftypefn
+page_output_immediately
+ at c pager.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} page_output_immediately ()
+ at deftypefnx {Built-in Function} {@var{val} =} page_output_immediately (@var{new_val})
+Query or set the internal variable that controls whether Octave sends
+output to the pager as soon as it is available.  Otherwise, Octave
+buffers its output and waits until just before the prompt is printed to
+flush it to the pager.
+ at end deftypefn
+page_screen_output
+ at c pager.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} page_screen_output ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} page_screen_output (@var{new_val})
+Query or set the internal variable that controls whether output intended
+for the terminal window that is longer than one page is sent through a
+pager.  This allows you to view one screenful at a time.  Some pagers
+(such as @code{less}---see @ref{Installation}) are also capable of moving
+backward on the output.
+ at end deftypefn
+PAGER
+ at c pager.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} PAGER ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PAGER (@var{new_val})
+Query or set the internal variable that specifies the program to use
+to display terminal output on your system.  The default value is
+normally @code{"less"}, @code{"more"}, or
+ at code{"pg"}, depending on what programs are installed on your system.
+ at xref{Installation}.
+ at seealso{more, page_screen_output, page_output_immediately, PAGER_FLAGS}
+ at end deftypefn
+PAGER_FLAGS
+ at c pager.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} PAGER_FLAGS ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} PAGER_FLAGS (@var{new_val})
+Query or set the internal variable that specifies the options to pass
+to the pager.
+ at seealso{PAGER}
+ at end deftypefn
+autoload
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})
+Define @var{function} to autoload from @var{file}.
+
+The second argument, @var{file}, should be an absolute file name or
+a file name in the same directory as the function or script from which
+the autoload command was run.  @var{file} should not depend on the
+Octave load path.
+
+Normally, calls to @code{autoload} appear in PKG_ADD script files that
+are evaluated when a directory is added to the Octave's load path.  To
+avoid having to hardcode directory names in @var{file}, if @var{file}
+is in the same directory as the PKG_ADD script then
+
+ at example
+autoload ("foo", "bar.oct");
+ at end example
+
+will load the function @code{foo} from the file @code{bar.oct}.  The above
+when @code{bar.oct} is not in the same directory or uses like
+
+ at example
+autoload ("foo", file_in_loadpath ("bar.oct"))
+ at end example
+
+ at noindent
+are strongly discouraged, as their behavior might be unpredictable.
+
+With no arguments, return a structure containing the current autoload map.
+ at seealso{PKG_ADD}
+ at end deftypefn
+mfilename
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mfilename ()
+ at deftypefnx {Built-in Function} {} mfilename (@code{"fullpath"})
+ at deftypefnx {Built-in Function} {} mfilename (@code{"fullpathext"})
+Return the name of the currently executing file.  At the top-level,
+return the empty string.  Given the argument @code{"fullpath"},
+include the directory part of the file name, but not the extension.
+Given the argument @code{"fullpathext"}, include the directory part
+of the file name and the extension.
+ at end deftypefn
+source
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} source (@var{file})
+Parse and execute the contents of @var{file}.  This is equivalent to
+executing commands from a script file, but without requiring the file to
+be named @file{@var{file}.m}.
+ at end deftypefn
+feval
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} feval (@var{name}, @dots{})
+Evaluate the function named @var{name}.  Any arguments after the first
+are passed on to the named function.  For example,
+
+ at example
+feval ("acos", -1)
+     @result{} 3.1416
+ at end example
+
+ at noindent
+calls the function @code{acos} with the argument @samp{-1}.
+
+The function @code{feval} is necessary in order to be able to write
+functions that call user-supplied functions, because Octave does not
+have a way to declare a pointer to a function (like C) or to declare a
+special kind of variable that can be used to hold the name of a function
+(like @code{EXTERNAL} in Fortran).  Instead, you must refer to functions
+by name, and use @code{feval} to call them.
+ at end deftypefn
+eval
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} eval (@var{try}, @var{catch})
+Parse the string @var{try} and evaluate it as if it were an Octave
+program.  If that fails, evaluate the optional string @var{catch}.
+The string @var{try} is evaluated in the current context,
+so any results remain available after @code{eval} returns.
+
+The following example makes the variable @var{a} with the approximate
+value 3.1416 available.
+
+ at example
+eval("a = acos(-1);");
+ at end example
+
+If an error occurs during the evaluation of @var{try} the @var{catch}
+string is evaluated, as the following example shows:
+
+ at example
+eval ('error ("This is a bad example");',
+      'printf ("This error occurred:\n%s\n", lasterr ());');
+     @print{} This error occurred:
+        This is a bad example
+ at end example
+ at end deftypefn
+assignin
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})
+Assign @var{value} to @var{varname} in context @var{context}, which
+may be either @code{"base"} or @code{"caller"}.
+ at end deftypefn
+evalin
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})
+Like @code{eval}, except that the expressions are evaluated in the
+context @var{context}, which may be either @code{"caller"} or
+ at code{"base"}.
+ at end deftypefn
+__parser_debug_flag__
+ at c parse.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{old_val} =} __parser_debug_flag__ (@var{new_val}))
+Undocumented internal function.
+ at end deftypefn
+pinv
+ at c ./DLD-FUNCTIONS/pinv.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} pinv (@var{x}, @var{tol})
+Return the pseudoinverse of @var{x}.  Singular values less than
+ at var{tol} are ignored.  
+
+If the second argument is omitted, it is assumed that
+
+ at example
+tol = max (size (@var{x})) * sigma_max (@var{x}) * eps,
+ at end example
+
+ at noindent
+where @code{sigma_max (@var{x})} is the maximal singular value of @var{x}.
+ at end deftypefn
+rats
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} rats (@var{x}, @var{len})
+Convert @var{x} into a rational approximation represented as a string.
+You can convert the string back into a matrix as follows:
+
+ at example
+ at group
+   r = rats(hilb(4));
+   x = str2num(r)
+ at end group
+ at end example
+
+The optional second argument defines the maximum length of the string
+representing the elements of @var{x}.  By default @var{len} is 9.
+ at seealso{format, rat}
+ at end deftypefn
+disp
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} disp (@var{x})
+Display the value of @var{x}.  For example,
+
+ at example
+ at group
+disp ("The value of pi is:"), disp (pi)
+
+     @print{} the value of pi is:
+     @print{} 3.1416
+ at end group
+ at end example
+
+ at noindent
+Note that the output from @code{disp} always ends with a newline.
+
+If an output value is requested, @code{disp} prints nothing and
+returns the formatted output in a string.
+ at seealso{fdisp}
+ at end deftypefn
+fdisp
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})
+Display the value of @var{x} on the stream @var{fid}.  For example,
+
+ at example
+ at group
+fdisp (stdout, "The value of pi is:"), fdisp (stdout, pi)
+
+     @print{} the value of pi is:
+     @print{} 3.1416
+ at end group
+ at end example
+
+ at noindent
+Note that the output from @code{fdisp} always ends with a newline.
+ at seealso{disp}
+ at end deftypefn
+format
+ at c pr-output.cc
+-*- texinfo -*-
+ at deffn  {Command} format
+ at deffnx {Command} format options
+Reset or specify the format of the output produced by @code{disp} and
+Octave's normal echoing mechanism.  This command only affects the display
+of numbers but not how they are stored or computed.  To change the internal
+representation from the default double use one of the conversion functions
+such as @code{single}, @code{uint8}, @code{int64}, etc.
+
+By default, Octave displays 5 significant digits in a human readable form
+(option @samp{short} paired with @samp{loose} format for matrices).
+If @code{format} is invoked without any options, this default format
+is restored.
+
+Valid formats for floating point numbers are listed in the following
+table.
+
+ at table @code
+ at item short
+Fixed point format with 5 significant figures in a field that is a maximum
+of 10 characters wide.  (default).
+
+If Octave is unable to format a matrix so that columns line up on the
+decimal point and all numbers fit within the maximum field width then
+it switches to an exponential @samp{e} format.
+
+ at item long
+Fixed point format with 15 significant figures in a field that is a maximum
+of 20 characters wide.
+
+As with the @samp{short} format, Octave will switch to an exponential
+ at samp{e} format if it is unable to format a matrix properly using the
+current format.
+
+ at item  short e
+ at itemx long e
+Exponential format.  The number to be represented is split between a mantissa
+and an exponent (power of 10).  The mantissa has 5 significant digits in the
+short format and 15 digits in the long format.
+For example, with the @samp{short e} format, @code{pi} is displayed as
+ at code{3.1416e+00}.
+
+ at item  short E
+ at itemx long E
+Identical to @samp{short e} or @samp{long e} but displays an uppercase
+ at samp{E} to indicate the exponent.
+For example, with the @samp{long E} format, @code{pi} is displayed as
+ at code{3.14159265358979E+00}.
+
+ at item  short g
+ at itemx long g
+Optimally choose between fixed point and exponential format based on
+the magnitude of the number.
+For example, with the @samp{short g} format,
+ at code{pi .^ [2; 4; 8; 16; 32]} is displayed as
+
+ at example
+ at group
+ans =
+
+      9.8696
+      97.409
+      9488.5
+  9.0032e+07
+  8.1058e+15
+ at end group
+ at end example
+
+ at item long G
+ at itemx short G
+Identical to @samp{short g} or @samp{long g} but displays an uppercase
+ at samp{E} to indicate the exponent.
+
+ at item free
+ at itemx none
+Print output in free format, without trying to line up columns of
+matrices on the decimal point.  This also causes complex numbers to be
+formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead
+of like this @samp{0.60419 + 0.60709i}.
+ at end table
+
+The following formats affect all numeric output (floating point and
+integer types).
+
+ at table @code
+ at item  +
+ at itemx + @var{chars}
+ at itemx plus
+ at itemx plus @var{chars}
+Print a @samp{+} symbol for nonzero matrix elements and a space for zero
+matrix elements.  This format can be very useful for examining the
+structure of a large sparse matrix.
+
+The optional argument @var{chars} specifies a list of 3 characters to use
+for printing values greater than zero, less than zero and equal to zero.
+For example, with the @samp{+ "+-."} format, @code{[1, 0, -1; -1, 0, 1]}
+is displayed as
+
+ at example
+ at group
+ans =
+
++.-
+-.+
+ at end group
+ at end example
+
+ at item bank
+Print in a fixed format with two digits to the right of the decimal
+point.
+
+ at item native-hex
+Print the hexadecimal representation of numbers as they are stored in
+memory.  For example, on a workstation which stores 8 byte real values
+in IEEE format with the least significant byte first, the value of
+ at code{pi} when printed in @code{native-hex} format is @code{400921fb54442d18}.
+
+ at item hex
+The same as @code{native-hex}, but always print the most significant
+byte first.
+ at item native-bit
+Print the bit representation of numbers as stored in memory.
+For example, the value of @code{pi} is
+
+ at example
+ at group
+01000000000010010010000111111011
+01010100010001000010110100011000
+ at end group
+ at end example
+
+(shown here in two 32 bit sections for typesetting purposes) when
+printed in native-bit format on a workstation which stores 8 byte real values
+in IEEE format with the least significant byte first.
+ at item bit
+The same as @code{native-bit}, but always print the most significant
+bits first.
+
+ at item rat
+Print a rational approximation, i.e., values are approximated
+as the ratio of small integers.
+For example, with the @samp{rat} format,
+ at code{pi} is displayed as @code{355/113}.
+ at end table
+
+The following two options affect the display of all matrices.
+
+ at table @code
+ at item compact
+Remove extra blank space around column number labels producing more compact
+output with more data per page.
+ at item loose
+Insert blank lines above and below column number labels to produce a more
+readable output with less data per page.  (default).
+ at end table
+ at end deffn
+fixed_point_format
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} fixed_point_format ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} fixed_point_format (@var{new_val})
+Query or set the internal variable that controls whether Octave will
+use a scaled format to print matrix values such that the largest
+element may be written with a single leading digit with the scaling
+factor is printed on the first line of output.  For example,
+
+ at example
+ at group
+octave:1> logspace (1, 7, 5)'
+ans =
+
+  1.0e+07  *
+
+  0.00000
+  0.00003
+  0.00100
+  0.03162
+  1.00000
+ at end group
+ at end example
+
+ at noindent
+Notice that first value appears to be zero when it is actually 1.  For
+this reason, you should be careful when setting
+ at code{fixed_point_format} to a nonzero value.
+ at end deftypefn
+print_empty_dimensions
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} print_empty_dimensions ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} print_empty_dimensions (@var{new_val})
+Query or set the internal variable that controls whether the
+dimensions of empty matrices are printed along with the empty matrix
+symbol, @samp{[]}.  For example, the expression
+
+ at example
+zeros (3, 0)
+ at end example
+
+ at noindent
+will print
+
+ at example
+ans = [](3x0)
+ at end example
+ at end deftypefn
+split_long_rows
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} split_long_rows ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} split_long_rows (@var{new_val})
+Query or set the internal variable that controls whether rows of a matrix
+may be split when displayed to a terminal window.  If the rows are split,
+Octave will display the matrix in a series of smaller pieces, each of
+which can fit within the limits of your terminal width and each set of
+rows is labeled so that you can easily see which columns are currently
+being displayed.  For example:
+
+ at example
+ at group
+octave:13> rand (2,10)
+ans =
+
+ Columns 1 through 6:
+
+  0.75883  0.93290  0.40064  0.43818  0.94958  0.16467
+  0.75697  0.51942  0.40031  0.61784  0.92309  0.40201
+
+ Columns 7 through 10:
+
+  0.90174  0.11854  0.72313  0.73326
+  0.44672  0.94303  0.56564  0.82150
+ at end group
+ at end example
+ at end deftypefn
+output_max_field_width
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} output_max_field_width ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} output_max_field_width (@var{new_val})
+Query or set the internal variable that specifies the maximum width
+of a numeric output field.
+ at seealso{format, output_precision}
+ at end deftypefn
+output_precision
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} output_precision ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} output_precision (@var{new_val})
+Query or set the internal variable that specifies the minimum number of
+significant figures to display for numeric output.
+ at seealso{format, output_max_field_width}
+ at end deftypefn
+struct_levels_to_print
+ at c pr-output.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} struct_levels_to_print ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} struct_levels_to_print (@var{new_val})
+Query or set the internal variable that specifies the number of
+structure levels to display.
+ at end deftypefn
+__end__
+ at c pt-arg-list.cc
+internal function
+silent_functions
+ at c pt-eval.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} silent_functions ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} silent_functions (@var{new_val})
+Query or set the internal variable that controls whether internal
+output from a function is suppressed.  If this option is disabled,
+Octave will display the results produced by evaluating expressions
+within a function body that are not terminated with a semicolon.
+ at end deftypefn
+string_fill_char
+ at c pt-mat.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} string_fill_char ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} string_fill_char (@var{new_val})
+Query or set the internal variable used to pad all rows of a character
+matrix to the same length.  It must be a single character.  The default
+value is @code{" "} (a single space).  For example,
+
+ at example
+ at group
+string_fill_char ("X");
+[ "these"; "are"; "strings" ]
+     @result{} "theseXX"
+        "areXXXX"
+        "strings"
+ at end group
+ at end example
+ at end deftypefn
+qr
+ at c ./DLD-FUNCTIONS/qr.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{q}, @var{r}, @var{p}] =} qr (@var{a})
+ at deftypefnx {Loadable Function} {[@var{q}, @var{r}, @var{p}] =} qr (@var{a}, '0')
+ at cindex QR factorization
+Compute the QR factorization of @var{a}, using standard @sc{lapack}
+subroutines.  For example, given the matrix @code{a = [1, 2; 3, 4]},
+
+ at example
+[q, r] = qr (a)
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+q =
+
+  -0.31623  -0.94868
+  -0.94868   0.31623
+
+r =
+
+  -3.16228  -4.42719
+   0.00000  -0.63246
+ at end group
+ at end example
+
+The @code{qr} factorization has applications in the solution of least
+squares problems
+ at iftex
+ at tex
+$$
+\min_x \left\Vert A x - b \right\Vert_2
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+ at code{min norm(A x - b)}
+ at end example
+
+ at end ifnottex
+for overdetermined systems of equations (i.e.,
+ at iftex
+ at tex
+$A$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}
+ at end ifnottex
+ is a tall, thin matrix).  The QR factorization is
+ at iftex
+ at tex
+$QR = A$ where $Q$ is an orthogonal matrix and $R$ is upper triangular.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{q * r = a} where @code{q} is an orthogonal matrix and @code{r} is
+upper triangular.
+ at end ifnottex
+
+If given a second argument of '0', @code{qr} returns an economy-sized
+QR factorization, omitting zero rows of @var{R} and the corresponding
+columns of @var{Q}.
+
+If the matrix @var{a} is full, the permuted QR factorization
+ at code{[@var{q}, @var{r}, @var{p}] = qr (@var{a})} forms the QR factorization
+such that the diagonal entries of @code{r} are decreasing in magnitude
+order.  For example,given the matrix @code{a = [1, 2; 3, 4]},
+
+ at example
+[q, r, p] = qr(a)
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+q = 
+
+  -0.44721  -0.89443
+  -0.89443   0.44721
+
+r =
+
+  -4.47214  -3.13050
+   0.00000   0.44721
+
+p =
+
+   0  1
+   1  0
+ at end group
+ at end example
+
+The permuted @code{qr} factorization @code{[q, r, p] = qr (a)}
+factorization allows the construction of an orthogonal basis of
+ at code{span (a)}.
+
+If the matrix @var{a} is sparse, then compute the sparse QR factorization
+of @var{a}, using @sc{CSparse}.  As the matrix @var{Q} is in general a full
+matrix, this function returns the @var{Q}-less factorization @var{r} of
+ at var{a}, such that @code{@var{r} = chol (@var{a}' * @var{a})}.
+
+If the final argument is the scalar @code{0} and the number of rows is
+larger than the number of columns, then an economy factorization is
+returned.  That is @var{r} will have only @code{size (@var{a},1)} rows.
+
+If an additional matrix @var{b} is supplied, then @code{qr} returns
+ at var{c}, where @code{@var{c} = @var{q}' * @var{b}}.  This allows the
+least squares approximation of @code{@var{a} \ @var{b}} to be calculated
+as
+
+ at example
+ at group
+[@var{c}, at var{r}] = spqr (@var{a}, at var{b})
+ at var{x} = @var{r} \ @var{c}
+ at end group
+ at end example
+ at end deftypefn
+qrupdate
+ at c ./DLD-FUNCTIONS/qr.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrupdate (@var{Q}, @var{R}, @var{u}, @var{v})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization
+of @w{@var{A} + @var{u}*@var{v}'}, where @var{u} and @var{v} are
+column vectors (rank-1 update) or matrices with equal number of columns
+(rank-k update).  Notice that the latter case is done as a sequence of rank-1 updates;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+The QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+ at seealso{qr, qrinsert, qrdelete}
+ at end deftypefn
+qrinsert
+ at c ./DLD-FUNCTIONS/qr.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrinsert (@var{Q}, @var{R}, @var{j}, @var{x}, @var{orient})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization of
+ at w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be
+inserted into @var{A} (if @var{orient} is @code{"col"}), or the
+QR at tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}
+is a row vector to be inserted into @var{A} (if @var{orient} is
+ at code{"row"}).
+
+The default value of @var{orient} is @code{"col"}.
+If @var{orient} is @code{"col"},
+ at var{u} may be a matrix and @var{j} an index vector
+resulting in the QR at tie{}factorization of a matrix @var{B} such that
+ at w{B(:, at var{j})} gives @var{u} and @w{B(:, at var{j}) = []} gives @var{A}.
+Notice that the latter case is done as a sequence of k insertions;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+If @var{orient} is @code{"col"},
+the QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+If @var{orient} is @code{"row"}, full factorization is needed.
+ at seealso{qr, qrupdate, qrdelete}
+ at end deftypefn
+qrdelete
+ at c ./DLD-FUNCTIONS/qr.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrdelete (@var{Q}, @var{R}, @var{j}, @var{orient})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization of
+ at w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted
+(if @var{orient} is "col"), or the QR at tie{}factorization of
+ at w{[A(1:j-1,:);A(:,j+1:n)]}, i.e., @var{A} with one row deleted (if
+ at var{orient} is "row").
+
+The default value of @var{orient} is "col".
+
+If @var{orient} is @code{"col"},
+ at var{j} may be an index vector
+resulting in the QR at tie{}factorization of a matrix @var{B} such that
+ at w{A(:, at var{j}) = []} gives @var{B}.
+Notice that the latter case is done as a sequence of k deletions;
+thus, for k large enough, it will be both faster and more accurate to recompute
+the factorization from scratch.
+
+If @var{orient} is @code{"col"},
+the QR factorization supplied may be either full
+(Q is square) or economized (R is square).
+
+If @var{orient} is @code{"row"}, full factorization is needed.
+ at seealso{qr, qrinsert, qrupdate}
+ at end deftypefn
+qrshift
+ at c ./DLD-FUNCTIONS/qr.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrshift (@var{Q}, @var{R}, @var{i}, @var{j})
+Given a QR at tie{}factorization of a real or complex matrix
+ at w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and
+ at var{R}@tie{}upper trapezoidal, return the QR at tie{}factorization
+of @w{@var{A}(:,p)}, where @w{p} is the permutation @*
+ at code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*
+ or @*
+ at code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*
+
+ at seealso{qr, qrinsert, qrdelete}
+ at end deftypefn
+quad_options
+ at c ./DLD-FUNCTIONS/quad.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} quad_options (@var{opt}, @var{val})
+When called with two arguments, this function
+allows you set options parameters for the function @code{quad}.
+Given one argument, @code{quad_options} returns the value of the
+corresponding option.  If no arguments are supplied, the names of all
+the available options and their current values are displayed.
+
+Options include
+
+ at table @code
+ at item "absolute tolerance"
+Absolute tolerance; may be zero for pure relative error test.
+ at item "relative tolerance"
+Nonnegative relative tolerance.  If the absolute tolerance is zero,
+the relative tolerance must be greater than or equal to 
+ at code{max (50*eps, 0.5e-28)}.
+ at item "single precision absolute tolerance"
+Absolute tolerance for single precision; may be zero for pure relative 
+error test.
+ at item "single precision relative tolerance"
+Nonnegative relative tolerance for single precision.  If the absolute
+tolerance is zero, the relative tolerance must be greater than or equal to 
+ at code{max (50*eps, 0.5e-28)}.
+ at end table
+ at end deftypefn
+quad
+ at c ./DLD-FUNCTIONS/quad.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{v}, @var{ier}, @var{nfun}, @var{err}] =} quad (@var{f}, @var{a}, @var{b}, @var{tol}, @var{sing})
+Integrate a nonlinear function of one variable using Quadpack.
+The first argument is the name of the function, the function handle or
+the inline function to call to compute the value of the integrand.  It
+must have the form
+
+ at example
+y = f (x)
+ at end example
+
+ at noindent
+where @var{y} and @var{x} are scalars.
+
+The second and third arguments are limits of integration.  Either or
+both may be infinite.
+
+The optional argument @var{tol} is a vector that specifies the desired
+accuracy of the result.  The first element of the vector is the desired
+absolute tolerance, and the second element is the desired relative
+tolerance.  To choose a relative test only, set the absolute
+tolerance to zero.  To choose an absolute test only, set the relative
+tolerance to zero.  
+
+The optional argument @var{sing} is a vector of values at which the
+integrand is known to be singular.
+
+The result of the integration is returned in @var{v} and @var{ier}
+contains an integer error code (0 indicates a successful integration).
+The value of @var{nfun} indicates how many function evaluations were
+required, and @var{err} contains an estimate of the error in the
+solution.
+
+You can use the function @code{quad_options} to set optional
+parameters for @code{quad}.
+
+It should be noted that since @code{quad} is written in Fortran it
+cannot be called recursively.
+ at end deftypefn
+qz
+ at c ./DLD-FUNCTIONS/qz.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{lambda} =} qz (@var{a}, @var{b})
+Generalized eigenvalue problem @math{A x = s B x},
+ at var{QZ} decomposition.  There are three ways to call this function:
+ at enumerate
+ at item @code{lambda = qz(A,B)}
+
+Computes the generalized eigenvalues
+ at iftex
+ at tex
+$\lambda$
+ at end tex
+ at end iftex
+ at ifnottex
+ at var{lambda}
+ at end ifnottex
+of @math{(A - s B)}.
+ at item @code{[AA, BB, Q, Z, V, W, lambda] = qz (A, B)}
+
+Computes qz decomposition, generalized eigenvectors, and 
+generalized eigenvalues of @math{(A - sB)}
+ at iftex
+ at tex
+$$ AV = BV{ \rm diag }(\lambda) $$
+$$ W^T A = { \rm diag }(\lambda)W^T B $$
+$$ AA = Q^T AZ, BB = Q^T BZ $$
+ at end tex
+ at end iftex
+ at ifnottex
+ at example
+ at group
+
+    A*V = B*V*diag(lambda)
+    W'*A = diag(lambda)*W'*B
+    AA = Q'*A*Z, BB = Q'*B*Z
+
+ at end group
+ at end example
+ at end ifnottex
+with @var{Q} and @var{Z} orthogonal (unitary)= @var{I}
+
+ at item @code{[AA,BB,Z@{, lambda@}] = qz(A,B,opt)}
+
+As in form [2], but allows ordering of generalized eigenpairs
+for (e.g.) solution of discrete time algebraic Riccati equations.
+Form 3 is not available for complex matrices, and does not compute
+the generalized eigenvectors @var{V}, @var{W}, nor the orthogonal matrix @var{Q}.
+ at table @var
+ at item opt
+for ordering eigenvalues of the GEP pencil.  The leading block
+of the revised pencil contains all eigenvalues that satisfy:
+ at table @code
+ at item "N"
+= unordered (default) 
+
+ at item "S"
+= small: leading block has all |lambda| <=1 
+
+ at item "B"
+= big: leading block has all |lambda| >= 1 
+
+ at item "-"
+= negative real part: leading block has all eigenvalues
+in the open left half-plane
+
+ at item "+"
+= non-negative real part: leading block has all eigenvalues
+in the closed right half-plane
+ at end table
+ at end table
+ at end enumerate
+
+Note: qz performs permutation balancing, but not scaling (see balance).
+Order of output arguments was selected for compatibility with @sc{matlab}
+
+ at seealso{balance, eig, schur}
+ at end deftypefn
+rand
+ at c ./DLD-FUNCTIONS/rand.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} rand (@var{x})
+ at deftypefnx {Loadable Function} {} rand (@var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} rand ("state", @var{x})
+ at deftypefnx {Loadable Function} {} rand ("seed", @var{x})
+Return a matrix with random elements uniformly distributed on the
+interval (0, 1).  The arguments are handled the same as the arguments
+for @code{eye}.
+
+You can query the state of the random number generator using the
+form
+
+ at example
+v = rand ("state")
+ at end example
+
+This returns a column vector @var{v} of length 625.  Later, you can
+restore the random number generator to the state @var{v}
+using the form
+
+ at example
+rand ("state", v)
+ at end example
+
+ at noindent
+You may also initialize the state vector from an arbitrary vector of
+length <= 625 for @var{v}.  This new state will be a hash based on the
+value of @var{v}, not @var{v} itself.
+
+By default, the generator is initialized from @code{/dev/urandom} if it is
+available, otherwise from cpu time, wall clock time and the current
+fraction of a second.
+
+To compute the pseudo-random sequence, @code{rand} uses the Mersenne
+Twister with a period of @math{2^{19937}-1} (See M. Matsumoto and T. Nishimura,
+ at cite{Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator}, ACM Trans. on
+Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998,
+ at url{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html}).
+Do @strong{not} use for cryptography without securely hashing
+several returned values together, otherwise the generator state
+can be learned after reading 624 consecutive values.
+
+Older versions of Octave used a different random number generator.
+The new generator is used by default
+as it is significantly faster than the old generator, and produces
+random numbers with a significantly longer cycle time.  However, in
+some circumstances it might be desirable to obtain the same random
+sequences as used by the old generators.  To do this the keyword
+"seed" is used to specify that the old generators should be use,
+as in
+
+ at example
+rand ("seed", val)
+ at end example
+
+which sets the seed of the generator to @var{val}.  The seed of the
+generator can be queried with
+
+ at example
+s = rand ("seed")
+ at end example
+
+However, it should be noted that querying the seed will not cause
+ at code{rand} to use the old generators, only setting the seed will.
+To cause @code{rand} to once again use the new generators, the
+keyword "state" should be used to reset the state of the @code{rand}.
+ at seealso{randn, rande, randg, randp}
+ at end deftypefn
+randn
+ at c ./DLD-FUNCTIONS/rand.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} randn (@var{x})
+ at deftypefnx {Loadable Function} {} randn (@var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} randn ("state", @var{x})
+ at deftypefnx {Loadable Function} {} randn ("seed", @var{x})
+Return a matrix with normally distributed pseudo-random
+elements having zero mean and variance one.  The arguments are
+handled the same as the arguments for @code{rand}.
+
+By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique'' to
+transform from a uniform to a normal distribution.  (G. Marsaglia and
+W.W. Tsang, @cite{Ziggurat method for generating random variables},
+J. Statistical Software, vol 5, 2000,
+ at url{http://www.jstatsoft.org/v05/i08/})
+
+ at seealso{rand, rande, randg, randp}
+ at end deftypefn
+rande
+ at c ./DLD-FUNCTIONS/rand.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} rande (@var{x})
+ at deftypefnx {Loadable Function} {} rande (@var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} rande ("state", @var{x})
+ at deftypefnx {Loadable Function} {} rande ("seed", @var{x})
+Return a matrix with exponentially distributed random elements.  The
+arguments are handled the same as the arguments for @code{rand}.
+
+By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique'' to
+transform from a uniform to a exponential distribution.  (G. Marsaglia and
+W.W. Tsang, @cite{Ziggurat method for generating random variables},
+J. Statistical Software, vol 5, 2000,
+ at url{http://www.jstatsoft.org/v05/i08/})
+ at seealso{rand, randn, randg, randp}
+ at end deftypefn
+randg
+ at c ./DLD-FUNCTIONS/rand.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} randg (@var{a}, @var{x})
+ at deftypefnx {Loadable Function} {} randg (@var{a}, @var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} randg ("state", @var{x})
+ at deftypefnx {Loadable Function} {} randg ("seed", @var{x})
+Return a matrix with @code{gamma(@var{a},1)} distributed random elements.
+The arguments are handled the same as the arguments for @code{rand},
+except for the argument @var{a}.
+
+This can be used to generate many distributions:
+
+ at table @asis
+ at item @code{gamma (a, b)} for @code{a > -1}, @code{b > 0}
+ at example
+r = b * randg (a)
+ at end example
+ at item @code{beta (a, b)} for @code{a > -1}, @code{b > -1}
+ at example
+ at group
+r1 = randg (a, 1)
+r = r1 / (r1 + randg (b, 1))
+ at end group
+ at end example
+ at item @code{Erlang (a, n)}
+ at example
+r = a * randg (n)
+ at end example
+ at item @code{chisq (df)} for @code{df > 0}
+ at example
+r = 2 * randg (df / 2)
+ at end example
+ at item @code{t(df)} for @code{0 < df < inf} (use randn if df is infinite)
+ at example
+r = randn () / sqrt (2 * randg (df / 2) / df)
+ at end example
+ at item @code{F (n1, n2)} for @code{0 < n1}, @code{0 < n2}
+ at example
+ at group
+## r1 equals 1 if n1 is infinite
+r1 = 2 * randg (n1 / 2) / n1
+## r2 equals 1 if n2 is infinite
+r2 = 2 * randg (n2 / 2) / n2
+r = r1 / r2
+
+ at end group
+ at end example
+ at item negative @code{binomial (n, p)} for @code{n > 0}, @code{0 < p <= 1}
+ at example
+r = randp ((1 - p) / p * randg (n))
+ at end example
+ at item non-central @code{chisq (df, L)}, for @code{df >= 0} and @code{L > 0}
+(use chisq if @code{L = 0})
+ at example
+ at group
+r = randp (L / 2)
+r(r > 0) = 2 * randg (r(r > 0))
+r(df > 0) += 2 * randg (df(df > 0)/2)
+ at end group
+ at end example
+ at item @code{Dirichlet (a1, @dots{} ak)}
+ at example
+ at group
+r = (randg (a1), @dots{}, randg (ak))
+r = r / sum (r)
+ at end group
+ at end example
+ at end table
+ at seealso{rand, randn, rande, randp}
+ at end deftypefn
+randp
+ at c ./DLD-FUNCTIONS/rand.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} randp (@var{l}, @var{x})
+ at deftypefnx {Loadable Function} {} randp (@var{l}, @var{n}, @var{m})
+ at deftypefnx {Loadable Function} {} randp ("state", @var{x})
+ at deftypefnx {Loadable Function} {} randp ("seed", @var{x})
+Return a matrix with Poisson distributed random elements with mean value parameter given by the first argument, @var{l}.  The arguments
+are handled the same as the arguments for @code{rand}, except for the
+argument @var{l}.
+
+Five different algorithms are used depending on the range of @var{l}
+and whether or not @var{l} is a scalar or a matrix.
+
+ at table @asis
+ at item For scalar @var{l} <= 12, use direct method.
+Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.
+ at item For scalar @var{l} > 12, use rejection method.[1]
+Press, et al., 'Numerical Recipes in C', Cambridge University Press, 1992.
+ at item For matrix @var{l} <= 10, use inversion method.[2]
+Stadlober E., et al., WinRand source code, available via FTP.
+ at item For matrix @var{l} > 10, use patchwork rejection method.
+Stadlober E., et al., WinRand source code, available via FTP, or
+H. Zechner, 'Efficient sampling from continuous and discrete
+unimodal distributions', Doctoral Dissertation, 156pp., Technical
+University Graz, Austria, 1994.
+ at item For @var{l} > 1e8, use normal approximation.
+L. Montanet, et al., 'Review of Particle Properties', Physical Review
+D 50 p1284, 1994
+ at end table
+ at seealso{rand, randn, rande, randg}
+ at end deftypefn
+rcond
+ at c ./DLD-FUNCTIONS/rcond.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{c} =} rcond (@var{a})
+Compute the 1-norm estimate of the reciprocal condition as returned
+by @sc{lapack}.  If the matrix is well-conditioned then @var{c} will be near
+1 and if the matrix is poorly conditioned it will be close to zero.
+
+The matrix @var{a} must not be sparse.  If the matrix is sparse then
+ at code{condest (@var{a})} or @code{rcond (full (@var{a}))} should be used
+instead.
+ at seealso{inv}
+ at end deftypefn
+regexp
+ at c ./DLD-FUNCTIONS/regexp.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{s}, @var{e}, @var{te}, @var{m}, @var{t}, @var{nm}] =} regexp (@var{str}, @var{pat})
+ at deftypefnx {Loadable Function} {[@dots{}] =} regexp (@var{str}, @var{pat}, @var{opts}, @dots{})
+
+Regular expression string matching.  Matches @var{pat} in @var{str} and
+returns the position and matching substrings or empty values if there are
+none.
+
+The matched pattern @var{pat} can include any of the standard regex
+operators, including:
+
+ at table @code
+ at item .
+Match any character
+ at item * + ? @{@}
+Repetition operators, representing
+ at table @code
+ at item *
+Match zero or more times
+ at item +
+Match one or more times
+ at item ?
+Match zero or one times
+ at item @{@}
+Match range operator, which is of the form @code{@{@var{n}@}} to match exactly
+ at var{n} times, @code{@{@var{m},@}} to match @var{m} or more times,
+ at code{@{@var{m}, at var{n}@}} to match between @var{m} and @var{n} times.
+ at end table
+ at item [@dots{}] [^@dots{}]
+List operators, where for example @code{[ab]c} matches @code{ac} and @code{bc}
+ at item ()
+Grouping operator
+ at item |
+Alternation operator.  Match one of a choice of regular expressions.  The
+alternatives must be delimited by the grouping operator @code{()} above
+ at item ^ $
+Anchoring operator.  @code{^} matches the start of the string @var{str} and
+ at code{$} the end
+ at end table
+
+In addition the following escaped characters have special meaning.  It should
+be noted that it is recommended to quote @var{pat} in single quotes rather
+than double quotes, to avoid the escape sequences being interpreted by Octave
+before being passed to @code{regexp}.
+
+ at table @code
+ at item \b
+Match a word boundary
+ at item \B
+Match within a word
+ at item \w
+Matches any word character
+ at item \W
+Matches any non word character
+ at item \<
+Matches the beginning of a word
+ at item \>
+Matches the end of a word
+ at item \s
+Matches any whitespace character
+ at item \S
+Matches any non whitespace character
+ at item \d
+Matches any digit
+ at item \D
+Matches any non-digit
+ at end table
+
+The outputs of @code{regexp} by default are in the order as given below
+
+ at table @asis
+ at item @var{s}
+The start indices of each of the matching substrings
+
+ at item @var{e}
+The end indices of each matching substring
+
+ at item @var{te}
+The extents of each of the matched token surrounded by @code{(@dots{})} in
+ at var{pat}.
+
+ at item @var{m}
+A cell array of the text of each match.
+
+ at item @var{t}
+A cell array of the text of each token matched.
+
+ at item @var{nm}
+A structure containing the text of each matched named token, with the name
+being used as the fieldname.  A named token is denoted as
+ at code{(?<name>@dots{})}
+ at end table
+
+Particular output arguments or the order of the output arguments can be
+selected by additional @var{opts} arguments.  These are strings and the
+correspondence between the output arguments and the optional argument
+are
+
+ at multitable @columnfractions 0.2 0.3 0.3 0.2
+ at item @tab 'start'        @tab @var{s}  @tab
+ at item @tab 'end'          @tab @var{e}  @tab
+ at item @tab 'tokenExtents' @tab @var{te} @tab
+ at item @tab 'match'        @tab @var{m}  @tab
+ at item @tab 'tokens'       @tab @var{t}  @tab
+ at item @tab 'names'        @tab @var{nm}  @tab
+ at end multitable
+
+A further optional argument is 'once', that limits the number of returned
+matches to the first match.  Additional arguments are
+
+ at table @asis
+ at item matchcase
+Make the matching case sensitive.
+ at item ignorecase
+Make the matching case insensitive.
+ at item stringanchors
+Match the anchor characters at the beginning and end of the string.
+ at item lineanchors
+Match the anchor characters at the beginning and end of the line.
+ at item dotall
+The character @code{.} matches the newline character.
+ at item dotexceptnewline
+The character @code{.} matches all but the newline character.
+ at item freespacing
+The pattern can include arbitrary whitespace and comments starting with
+ at code{#}.
+ at item literalspacing
+The pattern is taken literally.
+ at end table
+ at seealso{regexpi, regexprep}
+ at end deftypefn
+regexpi
+ at c ./DLD-FUNCTIONS/regexp.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{s}, @var{e}, @var{te}, @var{m}, @var{t}, @var{nm}] =} regexpi (@var{str}, @var{pat})
+ at deftypefnx {Loadable Function} {[@dots{}] =} regexpi (@var{str}, @var{pat}, @var{opts}, @dots{})
+
+Case insensitive regular expression string matching.  Matches @var{pat} in
+ at var{str} and returns the position and matching substrings or empty values
+if there are none.  @xref{doc-regexp,,regexp}, for more details
+ at end deftypefn
+regexprep
+ at c ./DLD-FUNCTIONS/regexp.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function}  {@var{string} =} regexprep (@var{string}, @var{pat}, @var{repstr}, @var{options})
+Replace matches of @var{pat} in  @var{string} with @var{repstr}.
+
+
+The replacement can contain @code{$i}, which substitutes
+for the ith set of parentheses in the match string.  E.g.,
+ at example
+ at group
+
+   regexprep("Bill Dunn",'(\w+) (\w+)','$2, $1')
+
+ at end group
+ at end example
+returns "Dunn, Bill"
+
+ at var{options} may be zero or more of
+ at table @samp
+
+ at item once
+Replace only the first occurrence of @var{pat} in the result.
+
+ at item warnings
+This option is present for compatibility but is ignored.
+
+ at item ignorecase or matchcase
+Ignore case for the pattern matching (see @code{regexpi}).
+Alternatively, use (?i) or (?-i) in the pattern.
+
+ at item lineanchors and stringanchors
+Whether characters ^ and $ match the beginning and ending of lines.
+Alternatively, use (?m) or (?-m) in the pattern.
+
+ at item dotexceptnewline and dotall
+Whether . matches newlines in the string.
+Alternatively, use (?s) or (?-s) in the pattern.
+
+ at item freespacing or literalspacing
+Whether whitespace and # comments can be used to make the regular expression more readable.
+Alternatively, use (?x) or (?-x) in the pattern.
+
+ at end table
+ at seealso{regexp,regexpi,strrep}
+ at end deftypefn
+schur
+ at c ./DLD-FUNCTIONS/schur.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{s} =} schur (@var{a})
+ at deftypefnx {Loadable Function} {[@var{u}, @var{s}] =} schur (@var{a}, @var{opt})
+ at cindex Schur decomposition
+The Schur decomposition is used to compute eigenvalues of a
+square matrix, and has applications in the solution of algebraic
+Riccati equations in control (see @code{are} and @code{dare}).
+ at code{schur} always returns
+ at iftex
+ at tex
+$S = U^T A U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s = u' * a * u}
+ at end ifnottex
+where
+ at iftex
+ at tex
+$U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{u}
+ at end ifnottex
+ is a unitary matrix
+ at iftex
+ at tex
+($U^T U$ is identity)
+ at end tex
+ at end iftex
+ at ifnottex
+(@code{u'* u} is identity)
+ at end ifnottex
+and
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+is upper triangular.  The eigenvalues of
+ at iftex
+ at tex
+$A$ (and $S$)
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a} (and @code{s})
+ at end ifnottex
+are the diagonal elements of
+ at iftex
+ at tex
+$S$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}.
+ at end ifnottex
+If the matrix
+ at iftex
+ at tex
+$A$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}
+ at end ifnottex
+is real, then the real Schur decomposition is computed, in which the
+matrix
+ at iftex
+ at tex
+$U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{u}
+ at end ifnottex
+is orthogonal and
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+is block upper triangular
+with blocks of size at most
+ at iftex
+ at tex
+$2\times 2$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{2 x 2}
+ at end ifnottex
+along the diagonal.  The diagonal elements of
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+(or the eigenvalues of the
+ at iftex
+ at tex
+$2\times 2$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{2 x 2}
+ at end ifnottex
+blocks, when
+appropriate) are the eigenvalues of
+ at iftex
+ at tex
+$A$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}
+ at end ifnottex
+and
+ at iftex
+ at tex
+$S$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}.
+ at end ifnottex
+
+The eigenvalues are optionally ordered along the diagonal according to
+the value of @code{opt}.  @code{opt = "a"} indicates that all
+eigenvalues with negative real parts should be moved to the leading
+block of
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+(used in @code{are}), @code{opt = "d"} indicates that all eigenvalues
+with magnitude less than one should be moved to the leading block of
+ at iftex
+ at tex
+$S$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}
+ at end ifnottex
+(used in @code{dare}), and @code{opt = "u"}, the default, indicates that
+no ordering of eigenvalues should occur.  The leading
+ at iftex
+ at tex
+$k$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{k}
+ at end ifnottex
+columns of
+ at iftex
+ at tex
+$U$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{u}
+ at end ifnottex
+always span the
+ at iftex
+ at tex
+$A$-invariant
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{a}-invariant
+ at end ifnottex
+subspace corresponding to the
+ at iftex
+ at tex
+$k$
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{k}
+ at end ifnottex
+leading eigenvalues of
+ at iftex
+ at tex
+$S$.
+ at end tex
+ at end iftex
+ at ifnottex
+ at code{s}.
+ at end ifnottex
+ at end deftypefn
+SIG
+ at c sighandlers.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} SIG ()
+Return a structure containing Unix signal names and their defined values.
+ at end deftypefn
+debug_on_interrupt
+ at c sighandlers.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_interrupt (@var{new_val})
+Query or set the internal variable that controls whether Octave will try
+to enter debugging mode when it receives an interrupt signal (typically
+generated with @kbd{C-c}).  If a second interrupt signal is received
+before reaching the debugging mode, a normal interrupt will occur.
+ at end deftypefn
+sighup_dumps_octave_core
+ at c sighandlers.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})
+Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it receives
+a hangup signal.
+ at end deftypefn
+sigterm_dumps_octave_core
+ at c sighandlers.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})
+Query or set the internal variable that controls whether Octave tries
+to save all current variables to the file "octave-core" if it receives
+a terminate signal.
+ at end deftypefn
+issparse
+ at c ./DLD-FUNCTIONS/sparse.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} issparse (@var{expr})
+Return 1 if the value of the expression @var{expr} is a sparse matrix.
+ at end deftypefn
+sparse
+ at c ./DLD-FUNCTIONS/sparse.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{s} =} sparse (@var{a})
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, "unique")
+ at deftypefnx {Loadable Function} {@var{s} =} sparse (@var{m}, @var{n})
+Create a sparse matrix from the full matrix or row, column, value triplets.
+If @var{a} is a full matrix, convert it to a sparse matrix representation,
+removing all zero values in the process.
+
+Given the integer index vectors @var{i} and @var{j}, a 1-by- at code{nnz} vector
+of real of complex values @var{sv}, overall dimensions @var{m} and @var{n}
+of the sparse matrix.  The argument @code{nzmax} is ignored but accepted for
+compatibility with @sc{matlab}.  If @var{m} or @var{n} are not specified their
+values are derived from the maximum index in the vectors @var{i} and @var{j}
+as given by @code{@var{m} = max (@var{i})}, @code{@var{n} = max (@var{j})}.
+
+ at strong{Note}: if multiple values are specified with the same
+ at var{i}, @var{j} indices, the corresponding values in @var{s} will
+be added.
+
+The following are all equivalent:
+
+ at example
+ at group
+s = sparse (i, j, s, m, n)
+s = sparse (i, j, s, m, n, "summation")
+s = sparse (i, j, s, m, n, "sum")
+ at end group
+ at end example
+
+Given the option "unique". if more than two values are specified for the
+same @var{i}, @var{j} indices, the last specified value will be used.
+
+ at code{sparse(@var{m}, @var{n})} is equivalent to
+ at code{sparse ([], [], [], @var{m}, @var{n}, 0)}
+
+If any of @var{sv}, @var{i} or @var{j} are scalars, they are expanded
+to have a common size.
+ at seealso{full}
+ at end deftypefn
+spparms
+ at c ./DLD-FUNCTIONS/spparms.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} { } spparms ()
+ at deftypefnx {Loadable Function} {@var{vals} =} spparms ()
+ at deftypefnx {Loadable Function} {[@var{keys}, @var{vals}] =} spparms ()
+ at deftypefnx {Loadable Function} {@var{val} =} spparms (@var{key})
+ at deftypefnx {Loadable Function} { } spparms (@var{vals})
+ at deftypefnx {Loadable Function} { } spparms ('defaults')
+ at deftypefnx {Loadable Function} { } spparms ('tight')
+ at deftypefnx {Loadable Function} { } spparms (@var{key}, @var{val})
+Sets or displays the parameters used by the sparse solvers and factorization
+functions.  The first four calls above get information about the current
+settings, while the others change the current settings.  The parameters are
+stored as pairs of keys and values, where the values are all floats and the
+keys are one of the following strings:
+
+ at table @code
+ at item spumoni
+Printing level of debugging information of the solvers (default 0)
+ at item ths_rel
+Included for compatibility.  Not used.  (default 1)
+ at item ths_abs
+Included for compatibility.  Not used.  (default 1)
+ at item exact_d
+Included for compatibility.  Not used.  (default 0)
+ at item supernd
+Included for compatibility.  Not used.  (default 3)
+ at item rreduce
+Included for compatibility.  Not used.  (default 3)
+ at item wh_frac
+Included for compatibility.  Not used.  (default 0.5)
+ at item autommd
+Flag whether the LU/QR and the '\' and '/' operators will automatically
+use the sparsity preserving mmd functions (default 1)
+ at item autoamd
+Flag whether the LU and the '\' and '/' operators will automatically
+use the sparsity preserving amd functions (default 1)
+ at item piv_tol
+The pivot tolerance of the UMFPACK solvers (default 0.1)
+ at item sym_tol
+The pivot tolerance of the UMFPACK symmetric solvers (default 0.001)
+ at item bandden
+The density of non-zero elements in a banded matrix before it is treated
+by the @sc{lapack} banded solvers (default 0.5)
+ at item umfpack
+Flag whether the UMFPACK or mmd solvers are used for the LU, '\' and
+'/' operations (default 1)
+ at end table
+
+The value of individual keys can be set with @code{spparms (@var{key},
+ at var{val})}.  The default values can be restored with the special keyword
+'defaults'.  The special keyword 'tight' can be used to set the mmd solvers
+to attempt for a sparser solution at the potential cost of longer running
+time.
+ at end deftypefn
+sqrtm
+ at c ./DLD-FUNCTIONS/sqrtm.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{result}, @var{error_estimate}] =} sqrtm (@var{a})
+Compute the matrix square root of the square matrix @var{a}.
+
+Ref: Nicholas J. Higham.  A new sqrtm for @sc{matlab}.  Numerical Analysis
+Report No. 336, Manchester Centre for Computational Mathematics,
+Manchester, England, January 1999.
+ at seealso{expm, logm}
+ at end deftypefn
+char
+ at c strfns.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} char (@var{x})
+ at deftypefnx {Built-in Function} {} char (@var{x}, @dots{})
+ at deftypefnx {Built-in Function} {} char (@var{s1}, @var{s2}, @dots{})
+ at deftypefnx {Built-in Function} {} char (@var{cell_array})
+Create a string array from one or more numeric matrices, character
+matrices, or cell arrays.  Arguments are concatenated vertically.
+The returned values are padded with blanks as needed to make each row
+of the string array have the same length.  Empty input strings are
+significant and will concatenated in the output.
+
+For numerical input, each element is converted
+to the corresponding ASCII character.  A range error results if an input
+is outside the ASCII range (0-255).
+
+For cell arrays, each element is concatenated separately.  Cell arrays converted through
+ at code{char} can mostly be converted back with @code{cellstr}.
+For example,
+
+ at example
+ at group
+char ([97, 98, 99], "", @{"98", "99", 100@}, "str1", ["ha", "lf"])
+     @result{} ["abc    "
+         "       "
+         "98     "
+         "99     "
+         "d      "
+         "str1   "
+         "half   "]
+ at end group
+ at end example
+ at seealso{strvcat, cellstr}
+ at end deftypefn
+strvcat
+ at c strfns.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {} strvcat (@var{x})
+ at deftypefnx {Built-in Function} {} strvcat (@var{x}, @dots{})
+ at deftypefnx {Built-in Function} {} strvcat (@var{s1}, @var{s2}, @dots{})
+ at deftypefnx {Built-in Function} {} strvcat (@var{cell_array})
+Create a character array from one or more numeric matrices, character
+matrices, or cell arrays.  Arguments are concatenated vertically.
+The returned values are padded with blanks as needed to make each row
+of the string array have the same length.  Unlike @code{char}, empty
+strings are removed and will not appear in the output.
+
+For numerical input, each element is converted
+to the corresponding ASCII character.  A range error results if an input
+is outside the ASCII range (0-255).
+
+For cell arrays, each element is concatenated separately.  Cell arrays converted through
+ at code{strvcat} can mostly be converted back with @code{cellstr}.
+For example,
+
+ at example
+ at group
+strvcat ([97, 98, 99], "", @{"98", "99", 100@}, "str1", ["ha", "lf"])
+     @result{} ["abc    "
+         "98     "
+         "99     "
+         "d      "
+         "str1   "
+         "half   "]
+ at end group
+ at end example
+ at seealso{char, strcat, cstrcat}
+ at end deftypefn
+ischar
+ at c strfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} ischar (@var{a})
+Return 1 if @var{a} is a character array.  Otherwise, return 0.
+ at end deftypefn
+strcmp
+ at c strfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} strcmp (@var{s1}, @var{s2})
+Return 1 if the character strings @var{s1} and @var{s2} are the same,
+and 0 otherwise.
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmp
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{strcmpi, strncmp, strncmpi}
+ at end deftypefn
+strncmp
+ at c strfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} strncmp (@var{s1}, @var{s2}, @var{n})
+Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2} are the same,
+and 0 otherwise.
+
+ at example
+ at group
+strncmp ("abce", "abcd", 3)
+     @result{} 1
+ at end group
+ at end example
+
+If either @var{s1} or @var{s2} is a cell array of strings, then an array
+of the same size is returned, containing the values described above for
+every member of the cell array.  The other argument may also be a cell
+array of strings (of the same size or with only one element), char matrix
+or character string.
+
+ at example
+ at group
+strncmp ("abce", @{"abcd", "bca", "abc"@}, 3)
+     @result{} [1, 0, 1]
+ at end group
+ at end example
+
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmp
+function returns 1 if the character strings are equal, and 0 otherwise.
+This is just the opposite of the corresponding C library function.
+ at seealso{strncmpi, strcmp, strcmpi}
+ at end deftypefn
+list_in_columns
+ at c strfns.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} list_in_columns (@var{arg}, @var{width})
+Return a string containing the elements of @var{arg} listed in
+columns with an overall maximum width of @var{width}.  The argument
+ at var{arg} must be a cell array of character strings or a character array.
+If @var{width} is not specified, the width of the terminal screen is used.
+Newline characters are used to break the lines in the output string.
+For example:
+
+ at example
+ at group
+list_in_columns (@{"abc", "def", "ghijkl", "mnop", "qrs", "tuv"@}, 20)
+     @result{} ans = abc     mnop
+            def     qrs
+            ghijkl  tuv
+
+whos ans
+     @result{}
+     Variables in the current scope:
+
+       Attr Name        Size                     Bytes  Class
+       ==== ====        ====                     =====  =====
+            ans         1x37                        37  char
+
+     Total is 37 elements using 37 bytes
+ at end group
+ at end example
+
+ at seealso{terminal_size}
+ at end deftypefn
+svd
+ at c ./DLD-FUNCTIONS/svd.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{s} =} svd (@var{a})
+ at deftypefnx {Loadable Function} {[@var{u}, @var{s}, @var{v}] =} svd (@var{a})
+ at cindex singular value decomposition
+Compute the singular value decomposition of @var{a}
+ at iftex
+ at tex
+$$
+ A = U S V^H
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+A = U*S*V'
+ at end example
+ at end ifnottex
+
+The function @code{svd} normally returns the vector of singular values.
+If asked for three return values, it computes
+ at iftex
+ at tex
+$U$, $S$, and $V$.
+ at end tex
+ at end iftex
+ at ifnottex
+U, S, and V.
+ at end ifnottex
+For example,
+
+ at example
+svd (hilb (3))
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+ans =
+
+  1.4083189
+  0.1223271
+  0.0026873
+ at end group
+ at end example
+
+ at noindent
+and
+
+ at example
+[u, s, v] = svd (hilb (3))
+ at end example
+
+ at noindent
+returns
+
+ at example
+ at group
+u =
+
+  -0.82704   0.54745   0.12766
+  -0.45986  -0.52829  -0.71375
+  -0.32330  -0.64901   0.68867
+
+s =
+
+  1.40832  0.00000  0.00000
+  0.00000  0.12233  0.00000
+  0.00000  0.00000  0.00269
+
+v =
+
+  -0.82704   0.54745   0.12766
+  -0.45986  -0.52829  -0.71375
+  -0.32330  -0.64901   0.68867
+ at end group
+ at end example
+
+If given a second argument, @code{svd} returns an economy-sized
+decomposition, eliminating the unnecessary rows or columns of @var{u} or
+ at var{v}.
+ at end deftypefn
+syl
+ at c ./DLD-FUNCTIONS/syl.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{x} =} syl (@var{a}, @var{b}, @var{c})
+Solve the Sylvester equation
+ at iftex
+ at tex
+$$
+ A X + X B + C = 0
+$$
+ at end tex
+ at end iftex
+ at ifnottex
+
+ at example
+A X + X B + C = 0
+ at end example
+ at end ifnottex
+using standard @sc{lapack} subroutines.  For example,
+
+ at example
+ at group
+syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
+     @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]
+ at end group
+ at end example
+ at end deftypefn
+symbfact
+ at c ./DLD-FUNCTIONS/symbfact.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{count}, @var{h}, @var{parent}, @var{post}, @var{r}] =} symbfact (@var{s}, @var{typ}, @var{mode})
+
+Performs a symbolic factorization analysis on the sparse matrix @var{s}.
+Where
+
+ at table @asis
+ at item @var{s}
+ at var{s} is a complex or real sparse matrix.
+
+ at item @var{typ}
+Is the type of the factorization and can be one of
+
+ at table @code
+ at item sym
+Factorize @var{s}.  This is the default.
+
+ at item col
+Factorize @code{@var{s}' * @var{s}}.
+ at item row
+Factorize @code{@var{s} * @var{s}'}.
+ at item lo
+Factorize @code{@var{s}'}
+ at end table
+
+ at item @var{mode}
+The default is to return the Cholesky factorization for @var{r}, and if
+ at var{mode} is 'L', the conjugate transpose of the Cholesky factorization
+is returned.  The conjugate transpose version is faster and uses less
+memory, but returns the same values for @var{count}, @var{h}, @var{parent}
+and @var{post} outputs.
+ at end table
+
+The output variables are
+
+ at table @asis
+ at item @var{count}
+The row counts of the Cholesky factorization as determined by @var{typ}.
+
+ at item @var{h}
+The height of the elimination tree.
+
+ at item @var{parent}
+The elimination tree itself.
+
+ at item @var{post}
+A sparse boolean matrix whose structure is that of the Cholesky
+factorization as determined by @var{typ}.
+ at end table
+ at end deftypefn
+symrcm
+ at c ./DLD-FUNCTIONS/symrcm.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{p} =} symrcm (@var{S})
+Symmetric reverse Cuthill-McKee permutation of @var{S}.
+Return a permutation vector @var{p} such that
+ at code{@var{S} (@var{p}, @var{p})} tends to have its diagonal elements
+closer to the diagonal than @var{S}.  This is a good preordering for LU
+or Cholesky factorization of matrices that come from 'long, skinny'
+problems.  It works for both symmetric and asymmetric @var{S}.
+
+The algorithm represents a heuristic approach to the NP-complete
+bandwidth minimization problem.  The implementation is based in the
+descriptions found in
+
+E. Cuthill, J. McKee: Reducing the Bandwidth of Sparse Symmetric
+Matrices. Proceedings of the 24th ACM National Conference, 157--172
+1969, Brandon Press, New Jersey.
+
+Alan George, Joseph W. H. Liu: Computer Solution of Large Sparse
+Positive Definite Systems, Prentice Hall Series in Computational
+Mathematics, ISBN 0-13-165274-5, 1981.
+
+ at seealso{colperm, colamd, symamd}
+ at end deftypefn
+ignore_function_time_stamp
+ at c symtab.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{val} =} ignore_function_time_stamp ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})
+Query or set the internal variable that controls whether Octave checks
+the time stamp on files each time it looks up functions defined in
+function files.  If the internal variable is set to @code{"system"},
+Octave will not automatically recompile function files in subdirectories of
+ at file{@var{octave-home}/lib/@var{version}} if they have changed since
+they were last compiled, but will recompile other function files in the
+search path if they change.  If set to @code{"all"}, Octave will not
+recompile any function files unless their definitions are removed with
+ at code{clear}.  If set to "none", Octave will always check time stamps
+on files to determine whether functions defined in function files
+need to recompiled.
+ at end deftypefn
+__current_scope__
+ at c symtab.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{scope}, @var{context}]} __dump_symtab_info__ ()
+Undocumented internal function.
+ at end deftypefn
+__dump_symtab_info__
+ at c symtab.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} __dump_symtab_info__ ()
+ at deftypefnx {Built-in Function} {} __dump_symtab_info__ (@var{scope})
+ at deftypefnx {Built-in Function} {} __dump_symtab_info__ ("scopes")
+ at deftypefnx {Built-in Function} {} __dump_symtab_info__ ("functions")
+Undocumented internal function.
+ at end deftypefn
+dup2
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} dup2 (@var{old}, @var{new})
+Duplicate a file descriptor.
+
+If successful, @var{fid} is greater than zero and contains the new file
+ID.  Otherwise, @var{fid} is negative and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+exec
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} exec (@var{file}, @var{args})
+Replace current process with a new process.  Calling @code{exec} without
+first calling @code{fork} will terminate your current Octave process and
+replace it with the program named by @var{file}.  For example,
+
+ at example
+exec ("ls" "-l")
+ at end example
+
+ at noindent
+will run @code{ls} and return you to your shell prompt.
+
+If successful, @code{exec} does not return.  If @code{exec} does return,
+ at var{err} will be nonzero, and @var{msg} will contain a system-dependent
+error message.
+ at end deftypefn
+popen2
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args})
+Start a subprocess with two-way communication.  The name of the process
+is given by @var{command}, and @var{args} is an array of strings
+containing options for the command.  The file identifiers for the input
+and output streams of the subprocess are returned in @var{in} and
+ at var{out}.  If execution of the command is successful, @var{pid}
+contains the process ID of the subprocess.  Otherwise, @var{pid} is
+ at minus{}1.
+
+For example,
+
+ at example
+[in, out, pid] = popen2 ("sort", "-r");
+fputs (in, "these\nare\nsome\nstrings\n");
+fclose (in);
+EAGAIN = errno ("EAGAIN");
+done = false;
+do
+  s = fgets (out);
+  if (ischar (s))
+    fputs (stdout, s);
+  elseif (errno () == EAGAIN)
+    sleep (0.1);
+    fclear (out);
+  else
+    done = true;
+  endif
+until (done)
+fclose (out);
+waitpid (pid);
+     @print{} these
+     @print{} strings
+     @print{} some
+     @print{} are
+ at end example
+
+Note that @code{popen2}, unlike @code{popen}, will not "reap" the
+child process.  If you don't use @code{waitpid} to check the child's
+exit status, it will linger until Octave exits.
+ at end deftypefn
+fcntl
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg})
+Change the properties of the open file @var{fid}.  The following values
+may be passed as @var{request}:
+
+ at vtable @code
+ at item F_DUPFD
+Return a duplicate file descriptor.
+
+ at item F_GETFD
+Return the file descriptor flags for @var{fid}.
+
+ at item F_SETFD
+Set the file descriptor flags for @var{fid}.
+
+ at item F_GETFL
+Return the file status flags for @var{fid}.  The following codes may be
+returned (some of the flags may be undefined on some systems).
+
+ at vtable @code
+ at item O_RDONLY
+Open for reading only.
+
+ at item O_WRONLY
+Open for writing only.
+
+ at item O_RDWR
+Open for reading and writing.
+
+ at item O_APPEND
+Append on each write.
+
+ at item O_CREAT
+Create the file if it does not exist.
+
+ at item O_NONBLOCK
+Nonblocking mode.
+
+ at item O_SYNC
+Wait for writes to complete.
+
+ at item O_ASYNC
+Asynchronous I/O.
+ at end vtable
+
+ at item F_SETFL
+Set the file status flags for @var{fid} to the value specified by
+ at var{arg}.  The only flags that can be changed are @w{@code{O_APPEND}} and
+ at w{@code{O_NONBLOCK}}.
+ at end vtable
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+fork
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{pid}, @var{msg}] =} fork ()
+Create a copy of the current process.
+
+Fork can return one of the following values:
+
+ at table @asis
+ at item > 0
+You are in the parent process.  The value returned from @code{fork} is
+the process id of the child process.  You should probably arrange to
+wait for any child processes to exit.
+
+ at item 0
+You are in the child process.  You can call @code{exec} to start another
+process.  If that fails, you should probably call @code{exit}.
+
+ at item < 0
+The call to @code{fork} failed for some reason.  You must take evasive
+action.  A system dependent error message will be waiting in @var{msg}.
+ at end table
+ at end deftypefn
+getpgrp
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {pgid =} getpgrp ()
+Return the process group id of the current process.
+ at end deftypefn
+getpid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {pid =} getpid ()
+Return the process id of the current process.
+ at end deftypefn
+getppid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {pid =} getppid ()
+Return the process id of the parent process.
+ at end deftypefn
+getegid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {egid =} getegid ()
+Return the effective group id of the current process.
+ at end deftypefn
+getgid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {gid =} getgid ()
+Return the real group id of the current process.
+ at end deftypefn
+geteuid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {euid =} geteuid ()
+Return the effective user id of the current process.
+ at end deftypefn
+getuid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {uid =} getuid ()
+Return the real user id of the current process.
+ at end deftypefn
+kill
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} kill (@var{pid}, @var{sig})
+Send signal @var{sig} to process @var{pid}.
+
+If @var{pid} is positive, then signal @var{sig} is sent to @var{pid}.
+
+If @var{pid} is 0, then signal @var{sig} is sent to every process
+in the process group of the current process.
+
+If @var{pid} is -1, then signal @var{sig} is sent to every process
+except process 1.
+
+If @var{pid} is less than -1, then signal @var{sig} is sent to every
+process in the process group @var{-pid}.
+
+If @var{sig} is 0, then no signal is sent, but error checking is still
+performed.
+
+Return 0 if successful, otherwise return -1.
+ at end deftypefn
+fstat
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} fstat (@var{fid})
+Return information about the open file @var{fid}.  See @code{stat}
+for a description of the contents of @var{info}.
+ at end deftypefn
+lstat
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})
+See stat.
+ at end deftypefn
+mkfifo
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})
+Create a @var{fifo} special file named @var{name} with file mode @var{mode}
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+pipe
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe ()
+Create a pipe and return the reading and writing ends of the pipe
+into @var{read_fd} and @var{write_fd} respectively.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+stat
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{file})
+ at deftypefnx {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})
+Return a structure @var{s} containing the following information about
+ at var{file}.
+
+ at table @code
+ at item dev
+ID of device containing a directory entry for this file.
+
+ at item ino
+File number of the file.
+
+ at item mode
+File mode, as an integer.  Use the functions @w{@code{S_ISREG}},
+ at w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}}, @w{@code{S_ISFIFO}},
+ at w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract information from this
+value.
+
+ at item modestr
+File mode, as a string of ten letters or dashes as would be returned by
+ at kbd{ls -l}.
+
+ at item nlink
+Number of links.
+
+ at item uid
+User ID of file's owner.
+
+ at item gid
+Group ID of file's group.
+
+ at item rdev
+ID of device for block or character special files.
+
+ at item size
+Size in bytes.
+
+ at item atime
+Time of last access in the same form as time values returned from
+ at code{time}.  @xref{Timing Utilities}.
+
+ at item mtime
+Time of last modification in the same form as time values returned from
+ at code{time}.  @xref{Timing Utilities}.
+
+ at item ctime
+Time of last file status change in the same form as time values
+returned from @code{time}.  @xref{Timing Utilities}.
+
+ at item blksize
+Size of blocks in the file.
+
+ at item blocks
+Number of blocks allocated for file.
+ at end table
+
+If the call is successful @var{err} is 0 and @var{msg} is an empty
+string.  If the file does not exist, or some other error occurs, @var{s}
+is an empty matrix, @var{err} is @minus{}1, and @var{msg} contains the
+corresponding system error message.
+
+If @var{file} is a symbolic link, @code{stat} will return information
+about the actual file that is referenced by the link.  Use @code{lstat}
+if you want information about the symbolic link itself.
+
+For example,
+
+ at example
+[s, err, msg] = stat ("/vmlinuz")
+      @result{} s =
+        @{
+          atime = 855399756
+          rdev = 0
+          ctime = 847219094
+          uid = 0
+          size = 389218
+          blksize = 4096
+          mtime = 847219094
+          gid = 6
+          nlink = 1
+          blocks = 768
+          mode = -rw-r--r--
+          modestr = -rw-r--r--
+          ino = 9316
+          dev = 2049
+        @}
+     @result{} err = 0
+     @result{} msg = 
+ at end example
+ at end deftypefn
+S_ISREG
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISREG (@var{mode})
+Return true if @var{mode} corresponds to a regular file.  The value
+of @var{mode} is assumed to be returned from a call to @code{stat}.
+ at seealso{stat, lstat}
+ at end deftypefn
+S_ISDIR
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISDIR (@var{mode})
+Return true if @var{mode} corresponds to a directory.  The value
+of @var{mode} is assumed to be returned from a call to @code{stat}.
+ at seealso{stat, lstat}
+ at end deftypefn
+S_ISCHR
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISCHR (@var{mode})
+Return true if @var{mode} corresponds to a character devicey.  The value
+of @var{mode} is assumed to be returned from a call to @code{stat}.
+ at seealso{stat, lstat}
+ at end deftypefn
+S_ISBLK
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISBLK (@var{mode})
+Return true if @var{mode} corresponds to a block device.  The value
+of @var{mode} is assumed to be returned from a call to @code{stat}.
+ at seealso{stat, lstat}
+ at end deftypefn
+S_ISFIFO
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISFIFO (@var{mode})
+Return true if @var{mode} corresponds to a fifo.  The value
+of @var{mode} is assumed to be returned from a call to @code{stat}.
+ at seealso{stat, lstat}
+ at end deftypefn
+S_ISLNK
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISLNK (@var{mode})
+Return true if @var{mode} corresponds to a symbolic link.  The value
+of @var{mode} is assumed to be returned from a call to @code{stat}.
+ at seealso{stat, lstat}
+ at end deftypefn
+S_ISSOCK
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} S_ISSOCK (@var{mode})
+ at seealso{stat, lstat}
+ at end deftypefn
+uname
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{uts}, @var{err}, @var{msg}] =} uname ()
+Return system information in the structure.  For example,
+
+ at example
+ at group
+uname ()
+     @result{} @{
+           sysname = x86_64
+           nodename = segfault
+           release = 2.6.15-1-amd64-k8-smp
+           version = Linux
+           machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006
+         @}
+ at end group
+ at end example
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+unlink
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} unlink (@var{file})
+Delete the file named @var{file}.
+
+If successful, @var{err} is 0 and @var{msg} is an empty string.
+Otherwise, @var{err} is nonzero and @var{msg} contains a
+system-dependent error message.
+ at end deftypefn
+waitpid
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{pid}, @var{status}, @var{msg}] =} waitpid (@var{pid}, @var{options})
+Wait for process @var{pid} to terminate.  The @var{pid} argument can be:
+
+ at table @asis
+ at item @minus{}1
+Wait for any child process.
+
+ at item 0
+Wait for any child process whose process group ID is equal to that of
+the Octave interpreter process.
+
+ at item > 0
+Wait for termination of the child process with ID @var{pid}.
+ at end table
+
+The @var{options} argument can be a bitwise OR of zero or more of
+the following constants:
+
+ at table @code
+ at item 0
+Wait until signal is received or a child process exits (this is the
+default if the @var{options} argument is missing).
+
+ at item WNOHANG
+Do not hang if status is not immediately available.
+
+ at item WUNTRACED
+Report the status of any child processes that are stopped, and whose
+status has not yet been reported since they stopped.
+
+ at item WCONTINUE
+Return if a stopped child has been resumed by delivery of @code{SIGCONT}.
+This value may not be meaningful on all systems.
+ at end table
+
+If the returned value of @var{pid} is greater than 0, it is the process
+ID of the child process that exited.  If an error occurs, @var{pid} will
+be less than zero and @var{msg} will contain a system-dependent error
+message.  The value of @var{status} contains additional system-dependent
+information about the subprocess that exited.
+ at seealso{WCONTINUE, WCOREDUMP, WEXITSTATUS, WIFCONTINUED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED}
+ at end deftypefn
+WIFEXITED
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WIFEXITED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child terminated normally.
+ at seealso{waitpid, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}
+ at end deftypefn
+WEXITSTATUS
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WEXITSTATUS (@var{status})
+Given @var{status} from a call to @code{waitpid}, return the exit
+status of the child.  This function should only be employed if
+ at code{WIFEXITED} returned true.
+ at seealso{waitpid, WIFEXITED, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}
+ at end deftypefn
+WIFSIGNALED
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WIFSIGNALED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child process was terminated by a signal.
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}
+ at end deftypefn
+WTERMSIG
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WTERMSIG (@var{status})
+Given @var{status} from a call to @code{waitpid}, return the number of
+the signal that caused the child process to terminate.  This function
+should only be employed if @code{WIFSIGNALED} returned true.
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}
+ at end deftypefn
+WCOREDUMP
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WCOREDUMP (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child produced a core dump.  This function should only be employed if
+ at code{WIFSIGNALED} returned true.  The macro used to implement this
+function is not specified in POSIX.1-2001 and is not available on some
+Unix implementations (e.g., AIX, SunOS).
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}
+ at end deftypefn
+WIFSTOPPED
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WIFSTOPPED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child process was stopped by delivery of a signal; this is only
+possible if the call was done using @code{WUNTRACED} or when the child
+is being traced (see ptrace(2)).
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WSTOPSIG, WIFCONTINUED}
+ at end deftypefn
+WSTOPSIG
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WSTOPSIG (@var{status})
+Given @var{status} from a call to @code{waitpid}, return the number of
+the signal which caused the child to stop.  This function should only
+be employed if @code{WIFSTOPPED} returned true.
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WIFCONTINUED}
+ at end deftypefn
+WIFCONTINUED
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WIFCONTINUED (@var{status})
+Given @var{status} from a call to @code{waitpid}, return true if the
+child process was resumed by delivery of @code{SIGCONT}.
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG}
+ at end deftypefn
+canonicalize_file_name
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {[@var{cname}, @var{status}, @var{msg}]} canonicalize_file_name (@var{name})
+Return the canonical name of file @var{name}.
+ at end deftypefn
+F_DUPFD
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} F_DUPFD ()
+Return the value required to request that @code{fcntl} return a
+duplicate file descriptor.
+ at seealso{fcntl, F_GETFD, F_GETFL, F_SETFD, F_SETFL}
+ at end deftypefn
+F_GETFD
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} F_GETFD ()
+Return the value required to request that @code{fcntl} to return the
+file descriptor flags.
+ at seealso{fcntl, F_DUPFD, F_GETFL, F_SETFD, F_SETFL}
+ at end deftypefn
+F_GETFL
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} F_GETFL ()
+Return the value required to request that @code{fcntl} to return the
+file status flags.
+ at seealso{fcntl, F_DUPFD, F_GETFD, F_SETFD, F_SETFL}
+ at end deftypefn
+F_SETFD
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} F_SETFD ()
+Return the value required to request that @code{fcntl} to set the file
+descriptor flags.
+ at seealso{fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFL}
+ at end deftypefn
+F_SETFL
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} F_SETFL ()
+Return the value required to request that @code{fcntl} to set the file
+status flags.
+ at seealso{fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFD}
+ at end deftypefn
+O_APPEND
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_APPEND ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate each write operation appends,
+or that may be passed to @code{fcntl} to set the write mode to append.\n at seealso{fcntl, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_ASYNC
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_ASYNC ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate asynchronous I/O.
+ at seealso{fcntl, O_APPEND, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_CREAT
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_CREAT ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that a file should be
+created if it does not exist.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_EXCL
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_EXCL ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that file locking is used.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_NONBLOCK
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_NONBLOCK ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that non-blocking I/O is in use,
+or that may be passsed to @code{fcntl} to set non-blocking I/O.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_RDONLY
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_RDONLY ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that a file is open for
+reading only.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_RDWR
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_RDWR ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that a file is open for both
+reading and writing.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_SYNC, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_SYNC
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_SYNC ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that a file is open for
+synchronous I/O.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY}
+ at end deftypefn
+O_TRUNC
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Variable} O_TRUNC ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that if file exists, it should
+be truncated when writing.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_WRONLY}
+ at end deftypefn
+O_WRONLY
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} O_WRONLY ()
+Return the numerical value of the file status flag that may be
+returned by @code{fcntl} to indicate that a file is open for
+writing only.
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC}
+ at end deftypefn
+WNOHANG
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WNOHANG ()
+Return the numerical value of the option argument that may be
+passed to @code{waitpid} to indicate that it should return its
+status immediately instead of waiting for a process to exit.
+ at seealso{waitpid, WUNTRACED, WCONTINUE}
+ at end deftypefn
+WUNTRACED
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} WUNTRACED ()
+Return the numerical value of the option argument that may be
+passed to @code{waitpid} to indicate that it should also return
+if the child process has stopped but is not traced via the
+ at code{ptrace} system call
+ at seealso{waitpid, WNOHANG, WCONTINUE}
+ at end deftypefn
+WCONTINUE
+ at c syscalls.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} WCONINTUE ()
+Return the numerical value of the option argument that may be
+passed to @code{waitpid} to indicate that it should also return
+if a stopped child has been resumed by delivery of a @code{SIGCONT}
+signal.
+ at seealso{waitpid, WNOHANG, WUNTRACED}
+ at end deftypefn
+clc
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} clc ()
+ at deftypefnx {Built-in Function} {} home ()
+Clear the terminal screen and move the cursor to the upper left corner.
+ at end deftypefn
+getenv
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} getenv (@var{var})
+Return the value of the environment variable @var{var}.  For example,
+
+ at example
+getenv ("PATH")
+ at end example
+
+ at noindent
+returns a string containing the value of your path.
+ at end deftypefn
+putenv
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} putenv (@var{var}, @var{value})
+ at deftypefnx {Built-in Function} {} setenv (@var{var}, @var{value})
+Set the value of the environment variable @var{var} to @var{value}.
+ at end deftypefn
+kbhit
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} kbhit ()
+Read a single keystroke from the keyboard.  If called with one
+argument, don't wait for a keypress.  For example,
+
+ at example
+x = kbhit ();
+ at end example
+
+ at noindent
+will set @var{x} to the next character typed at the keyboard as soon as
+it is typed.
+
+ at example
+x = kbhit (1);
+ at end example
+
+ at noindent
+identical to the above example, but don't wait for a keypress,
+returning the empty string if no key is available.
+ at end deftypefn
+pause
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} pause (@var{seconds})
+Suspend the execution of the program.  If invoked without any arguments,
+Octave waits until you type a character.  With a numeric argument, it
+pauses for the given number of seconds.  For example, the following
+statement prints a message and then waits 5 seconds before clearing the
+screen.
+
+ at example
+ at group
+fprintf (stderr, "wait please...\n");
+pause (5);
+clc;
+ at end group
+ at end example
+ at end deftypefn
+sleep
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} sleep (@var{seconds})
+Suspend the execution of the program for the given number of seconds.
+ at end deftypefn
+usleep
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} usleep (@var{microseconds})
+Suspend the execution of the program for the given number of
+microseconds.  On systems where it is not possible to sleep for periods
+of time less than one second, @code{usleep} will pause the execution for
+ at code{round (@var{microseconds} / 1e6)} seconds.
+ at end deftypefn
+isieee
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isieee ()
+Return 1 if your computer claims to conform to the IEEE standard for
+floating point calculations.
+ at end deftypefn
+native_float_format
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} native_float_format ()
+Return the native floating point format as a string
+ at end deftypefn
+tilde_expand
+ at c sysdep.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} tilde_expand (@var{string})
+Performs tilde expansion on @var{string}.  If @var{string} begins with a
+tilde character, (@samp{~}), all of the characters preceding the first
+slash (or all characters, if there is no slash) are treated as a
+possible user name, and the tilde and the following characters up to the
+slash are replaced by the home directory of the named user.  If the
+tilde is followed immediately by a slash, the tilde is replaced by the
+home directory of the user running Octave.  For example,
+
+ at example
+ at group
+tilde_expand ("~joeuser/bin")
+     @result{} "/home/joeuser/bin"
+tilde_expand ("~/bin")
+     @result{} "/home/jwe/bin"
+ at end group
+ at end example
+ at end deftypefn
+time
+ at c ./DLD-FUNCTIONS/time.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} time ()
+Return the current time as the number of seconds since the epoch.  The
+epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan
+1970.  For example, on Monday February 17, 1997 at 07:15:06 CUT, the
+value returned by @code{time} was 856163706.
+ at seealso{strftime, strptime, localtime, gmtime, mktime, now, date, clock, datenum, datestr, datevec, calendar, weekday}
+ at end deftypefn
+gmtime
+ at c ./DLD-FUNCTIONS/time.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} gmtime (@var{t})
+Given a value returned from time (or any non-negative integer),
+return a time structure corresponding to CUT.  For example,
+
+ at example
+ at group
+gmtime (time ())
+     @result{} @{
+           usec = 0
+           year = 97
+           mon = 1
+           mday = 17
+           sec = 6
+           zone = CST
+           min = 15
+           wday = 1
+           hour = 7
+           isdst = 0
+           yday = 47
+         @}
+ at end group
+ at end example
+ at seealso{strftime, strptime, localtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}
+ at end deftypefn
+localtime
+ at c ./DLD-FUNCTIONS/time.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} localtime (@var{t})
+Given a value returned from time (or any non-negative integer),
+return a time structure corresponding to the local time zone.
+
+ at example
+ at group
+localtime (time ())
+     @result{} @{
+           usec = 0
+           year = 97
+           mon = 1
+           mday = 17
+           sec = 6
+           zone = CST
+           min = 15
+           wday = 1
+           hour = 1
+           isdst = 0
+           yday = 47
+         @}
+ at end group
+ at end example
+ at seealso{strftime, strptime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}
+ at end deftypefn
+mktime
+ at c ./DLD-FUNCTIONS/time.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} mktime (@var{tm_struct})
+Convert a time structure corresponding to the local time to the number
+of seconds since the epoch.  For example,
+
+ at example
+ at group
+mktime (localtime (time ()))
+     @result{} 856163706
+ at end group
+ at end example
+ at seealso{strftime, strptime, localtime, gmtime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}
+ at end deftypefn
+strftime
+ at c ./DLD-FUNCTIONS/time.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} strftime (@var{fmt}, @var{tm_struct})
+Format the time structure @var{tm_struct} in a flexible way using the
+format string @var{fmt} that contains @samp{%} substitutions
+similar to those in @code{printf}.  Except where noted, substituted
+fields have a fixed size; numeric fields are padded if necessary.
+Padding is with zeros by default; for fields that display a single
+number, padding can be changed or inhibited by following the @samp{%}
+with one of the modifiers described below.  Unknown field specifiers are
+copied as normal characters.  All other characters are copied to the
+output without change.  For example,
+
+ at example
+ at group
+strftime ("%r (%Z) %A %e %B %Y", localtime (time ()))
+     @result{} "01:15:06 AM (CST) Monday 17 February 1997"
+ at end group
+ at end example
+
+Octave's @code{strftime} function supports a superset of the ANSI C
+field specifiers.
+
+ at noindent
+Literal character fields:
+
+ at table @code
+ at item %
+% character.
+
+ at item n
+Newline character.
+
+ at item t
+Tab character.
+ at end table
+
+ at noindent
+Numeric modifiers (a nonstandard extension):
+
+ at table @code
+ at item - (dash)
+Do not pad the field.
+
+ at item _ (underscore)
+Pad the field with spaces.
+ at end table
+
+ at noindent
+Time fields:
+
+ at table @code
+ at item %H
+Hour (00-23).
+
+ at item %I
+Hour (01-12).
+
+ at item %k
+Hour (0-23).
+
+ at item %l
+Hour (1-12).
+
+ at item %M
+Minute (00-59).
+
+ at item %p
+Locale's AM or PM.
+
+ at item %r
+Time, 12-hour (hh:mm:ss [AP]M).
+
+ at item %R
+Time, 24-hour (hh:mm).
+
+ at item %s
+Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).
+
+ at item %S
+Second (00-61).
+
+ at item %T
+Time, 24-hour (hh:mm:ss).
+
+ at item %X
+Locale's time representation (%H:%M:%S).
+
+ at item %Z
+Time zone (EDT), or nothing if no time zone is determinable.
+ at end table
+
+ at noindent
+Date fields:
+
+ at table @code
+ at item %a
+Locale's abbreviated weekday name (Sun-Sat).
+
+ at item %A
+Locale's full weekday name, variable length (Sunday-Saturday).
+
+ at item %b
+Locale's abbreviated month name (Jan-Dec).
+
+ at item %B
+Locale's full month name, variable length (January-December).
+
+ at item %c
+Locale's date and time (Sat Nov 04 12:02:33 EST 1989).
+
+ at item %C
+Century (00-99).
+
+ at item %d
+Day of month (01-31).
+
+ at item %e
+Day of month ( 1-31).
+
+ at item %D
+Date (mm/dd/yy).
+
+ at item %h
+Same as %b.
+
+ at item %j
+Day of year (001-366).
+
+ at item %m
+Month (01-12).
+
+ at item %U
+Week number of year with Sunday as first day of week (00-53).
+
+ at item %w
+Day of week (0-6).
+
+ at item %W
+Week number of year with Monday as first day of week (00-53).
+
+ at item %x
+Locale's date representation (mm/dd/yy).
+
+ at item %y
+Last two digits of year (00-99).
+
+ at item %Y
+Year (1970-).
+ at end table
+ at seealso{strptime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}
+ at end deftypefn
+strptime
+ at c ./DLD-FUNCTIONS/time.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {[@var{tm_struct}, @var{nchars}] =} strptime (@var{str}, @var{fmt})
+Convert the string @var{str} to the time structure @var{tm_struct} under
+the control of the format string @var{fmt}.
+
+If @var{fmt} fails to match, @var{nchars} is 0; otherwise it is set to the
+position of last matched character plus 1. Always check for this unless
+you're absolutely sure the date string will be parsed correctly.
+ at seealso{strftime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}
+ at end deftypefn
+quit
+ at c toplev.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} exit (@var{status})
+ at deftypefnx {Built-in Function} {} quit (@var{status})
+Exit the current Octave session.  If the optional integer value
+ at var{status} is supplied, pass that value to the operating system as the
+Octave's exit status.  The default value is zero.
+ at end deftypefn
+warranty
+ at c toplev.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} warranty ()
+Describe the conditions for copying and distributing Octave.
+ at end deftypefn
+system
+ at c toplev.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} system (@var{string}, @var{return_output}, @var{type})
+Execute a shell command specified by @var{string}.  The second
+argument is optional.  If @var{type} is @code{"async"}, the process
+is started in the background and the process id of the child process
+is returned immediately.  Otherwise, the process is started, and
+Octave waits until it exits.  If the @var{type} argument is omitted, a
+value of @code{"sync"} is assumed.
+
+If two input arguments are given (the actual value of
+ at var{return_output} is irrelevant) and the subprocess is started
+synchronously, or if @var{system} is called with one input argument and
+one or more output arguments, the output from the command is returned.
+Otherwise, if the subprocess is executed synchronously, its output is
+sent to the standard output.  To send the output of a command executed
+with @var{system} through the pager, use a command like
+
+ at example
+disp (system (cmd, 1));
+ at end example
+
+ at noindent
+or
+
+ at example
+printf ("%s\n", system (cmd, 1));
+ at end example
+
+The @code{system} function can return two values.  The first is the
+exit status of the command and the second is any output from the
+command that was written to the standard output stream.  For example,
+
+ at example
+[status, output] = system ("echo foo; exit 2");
+ at end example
+
+ at noindent
+will set the variable @code{output} to the string @samp{foo}, and the
+variable @code{status} to the integer @samp{2}.
+ at end deftypefn
+atexit
+ at c toplev.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} atexit (@var{fcn})
+ at deftypefnx {Built-in Function} {} atexit (@var{fcn}, @var{flag})
+Register a function to be called when Octave exits.  For example,
+
+ at example
+ at group
+function last_words ()
+  disp ("Bye bye");
+endfunction
+atexit ("last_words");
+ at end group
+ at end example
+
+ at noindent
+will print the message "Bye bye" when Octave exits.
+
+The additional argument @var{flag} will register or unregister
+ at var{fcn} from the list of functions to be called when Octave
+exits.  If @var{flag} is true, the function is registered, and if
+ at var{flag} is false, it is unregistered.  For example,
+after registering the function @code{last_words} above,
+
+ at example
+atexit ("last_words", false);
+ at end example
+
+ at noindent
+will remove the function from the list and Octave will not call
+ at code{last_words} when it exits.
+
+Note that @code{atexit} only removes the first occurrence of a function
+from the list, so if a function was placed in the list multiple
+times with @code{atexit}, it must also be removed from the list
+multiple times.
+ at end deftypefn
+octave_config_info
+ at c toplev.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} octave_config_info (@var{option})
+Return a structure containing configuration and installation
+information for Octave.
+
+if @var{option} is a string, return the configuration information for the
+specified option.
+
+ at end deftypefn
+tsearch
+ at c ./DLD-FUNCTIONS/tsearch.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})
+Searches for the enclosing Delaunay convex hull.  For @code{@var{t} =
+delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the
+points @code{(@var{xi}, @var{yi})}.  For points outside the convex hull,
+ at var{idx} is NaN.
+ at seealso{delaunay, delaunayn}
+ at end deftypefn
+typecast
+ at c ./DLD-FUNCTIONS/typecast.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} typecast (@var{x}, @var{type})
+Convert from one datatype to another without changing the underlying
+data.  The argument @var{type} defines the type of the return argument
+and must be one of 'uint8', 'uint16', 'uint32', 'uint64', 'int8', 'int16',
+'int32', 'int64', 'single' or 'double'.
+
+An example of the use of typecast on a little-endian machine is
+
+ at example
+ at group
+ at var{x} = uint16 ([1, 65535]);
+typecast (@var{x}, 'uint8')
+ at result{} [   0,   1, 255, 255]
+ at end group
+ at end example
+ at seealso{cast, swapbytes}
+ at end deftypefn
+urlwrite
+ at c ./DLD-FUNCTIONS/urlwrite.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {} urlwrite (@var{URL}, @var{localfile})
+ at deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})
+ at deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})
+ at deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})
+Download a remote file specified by its @var{URL} and save it as
+ at var{localfile}.  For example,
+
+ at example
+ at group
+urlwrite ("ftp://ftp.octave.org/pub/octave/README", 
+          "README.txt");
+ at end group
+ at end example
+
+The full path of the downloaded file is returned in @var{f}.  The
+variable @var{success} is 1 if the download was successful,
+otherwise it is 0 in which case @var{message} contains an error
+message.  If no output argument is specified and if an error occurs,
+then the error is signaled through Octave's error handling mechanism.
+
+This function uses libcurl.  Curl supports, among others, the HTTP,
+FTP and FILE protocols.  Username and password may be specified in
+the URL, for example:
+
+ at example
+ at group
+urlwrite ("http://username:password@@example.com/file.txt",
+          "file.txt");
+ at end group
+ at end example
+
+GET and POST requests can be specified by @var{method} and @var{param}.
+The parameter @var{method} is either @samp{get} or @samp{post}
+and @var{param} is a cell array of parameter and value pairs.
+For example:
+
+ at example
+ at group
+urlwrite ("http://www.google.com/search", "search.html",
+          "get", @{"query", "octave"@});
+ at end group
+ at end example
+ at seealso{urlread}
+ at end deftypefn
+urlread
+ at c ./DLD-FUNCTIONS/urlwrite.cc
+-*- texinfo -*-
+ at deftypefn {Loadable Function} {@var{s} =} urlread (@var{url})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})
+ at deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})
+ at deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})
+Download a remote file specified by its @var{URL} and return its content
+in string @var{s}.  For example,
+
+ at example
+s = urlread ("ftp://ftp.octave.org/pub/octave/README");
+ at end example
+
+The variable @var{success} is 1 if the download was successful,
+otherwise it is 0 in which case @var{message} contains an error
+message.  If no output argument is specified and if an error occurs,
+then the error is signaled through Octave's error handling mechanism.
+
+This function uses libcurl.  Curl supports, among others, the HTTP,
+FTP and FILE protocols.  Username and password may be specified in the
+URL.  For example,
+
+ at example
+s = urlread ("http://user:password@@example.com/file.txt");
+ at end example
+
+GET and POST requests can be specified by @var{method} and @var{param}.
+The parameter @var{method} is either @samp{get} or @samp{post}
+and @var{param} is a cell array of parameter and value pairs.
+For example,
+
+ at example
+ at group
+s = urlread ("http://www.google.com/search", "get",
+             @{"query", "octave"@});
+ at end group
+ at end example
+ at seealso{urlwrite}
+ at end deftypefn
+isvarname
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isvarname (@var{name})
+Return true if @var{name} is a valid variable name
+ at end deftypefn
+file_in_loadpath
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} file_in_loadpath (@var{file})
+ at deftypefnx {Built-in Function} {} file_in_loadpath (@var{file}, "all")
+
+Return the absolute name of @var{file} if it can be found in
+the list of directories specified by @code{path}.
+If no file is found, return an empty matrix.
+
+If the first argument is a cell array of strings, search each
+directory of the loadpath for element of the cell array and return
+the first that matches.
+
+If the second optional argument @code{"all"} is supplied, return
+a cell array containing the list of all files that have the same
+name in the path.  If no files are found, return an empty cell array.
+ at seealso{file_in_path, path}
+ at end deftypefn
+file_in_path
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} file_in_path (@var{path}, @var{file})
+ at deftypefnx {Built-in Function} {} file_in_path (@var{path}, @var{file}, "all")
+Return the absolute name of @var{file} if it can be found in
+ at var{path}.  The value of @var{path} should be a colon-separated list of
+directories in the format described for @code{path}.  If no file
+is found, return an empty matrix.  For example,
+
+ at example
+ at group
+file_in_path (EXEC_PATH, "sh")
+     @result{} "/bin/sh"
+ at end group
+ at end example
+
+If the second argument is a cell array of strings, search each
+directory of the path for element of the cell array and return
+the first that matches.
+
+If the third optional argument @code{"all"} is supplied, return
+a cell array containing the list of all files that have the same
+name in the path.  If no files are found, return an empty cell array.
+ at seealso{file_in_loadpath}
+ at end deftypefn
+do_string_escapes
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} do_string_escapes (@var{string})
+Convert special characters in @var{string} to their escaped forms.
+ at end deftypefn
+undo_string_escapes
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} undo_string_escapes (@var{s})
+Converts special characters in strings back to their escaped forms.  For
+example, the expression
+
+ at example
+bell = "\a";
+ at end example
+
+ at noindent
+assigns the value of the alert character (control-g, ASCII code 7) to
+the string variable @code{bell}.  If this string is printed, the
+system will ring the terminal bell (if it is possible).  This is
+normally the desired outcome.  However, sometimes it is useful to be
+able to print the original representation of the string, with the
+special characters replaced by their escape sequences.  For example,
+
+ at example
+ at group
+octave:13> undo_string_escapes (bell)
+ans = \a
+ at end group
+ at end example
+
+ at noindent
+replaces the unprintable alert character with its printable
+representation.
+ at end deftypefn
+is_absolute_filename
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} is_absolute_filename (@var{file})
+Return true if @var{file} is an absolute filename.
+ at end deftypefn
+is_rooted_relative_filename
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} is_rooted_relative_filename (@var{file})
+Return true if @var{file} is a rooted-relative filename.
+ at end deftypefn
+make_absolute_filename
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} make_absolute_filename (@var{file})
+Return the full name of @var{file}, relative to the current directory.
+ at end deftypefn
+find_dir_in_path
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} find_dir_in_path (@var{dir})
+Return the full name of the path element matching @var{dir}.  The
+match is performed at the end of each path element.  For example, if
+ at var{dir} is @code{"foo/bar"}, it matches the path element
+ at code{"/some/dir/foo/bar"}, but not @code{"/some/dir/foo/bar/baz"}
+or @code{"/some/dir/allfoo/bar"}.
+ at end deftypefn
+errno
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {@var{err} =} errno ()
+ at deftypefnx {Built-in Function} {@var{err} =} errno (@var{val})
+ at deftypefnx {Built-in Function} {@var{err} =} errno (@var{name})
+Return the current value of the system-dependent variable errno,
+set its value to @var{val} and return the previous value, or return
+the named error code given @var{name} as a character string, or -1
+if @var{name} is not found.
+ at end deftypefn
+errno_list
+ at c utils.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} errno_list ()
+Return a structure containing the system-dependent errno values.
+ at end deftypefn
+isglobal
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isglobal (@var{name})
+Return 1 if @var{name} is globally visible.  Otherwise, return 0.  For
+example,
+
+ at example
+ at group
+global x
+isglobal ("x")
+     @result{} 1
+ at end group
+ at end example
+ at end deftypefn
+is_global
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} isglobal (@var{name})
+This function has been deprecated.  Use isglobal instead.
+ at end deftypefn
+exist
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} exist (@var{name}, @var{type})
+Return 1 if the name exists as a variable, 2 if the name is an
+absolute file name, an ordinary file in Octave's @code{path}, or (after
+appending @samp{.m}) a function file in Octave's @code{path}, 3 if the
+name is a @samp{.oct} or @samp{.mex} file in Octave's @code{path},
+5 if the name is a built-in function, 7 if the name is a directory, or 103
+if the name is a function not associated with a file (entered on
+the command line).
+
+Otherwise, return 0.
+
+This function also returns 2 if a regular file called @var{name}
+exists in Octave's search path.  If you want information about
+other types of files, you should use some combination of the functions
+ at code{file_in_path} and @code{stat} instead.
+
+If the optional argument @var{type} is supplied, check only for
+symbols of the specified type.  Valid types are
+
+ at table @samp
+ at item "var"
+Check only for variables.
+ at item "builtin"
+Check only for built-in functions.
+ at item "file"
+Check only for files.
+ at item "dir"
+Check only for directories.
+ at end table
+ at end deftypefn
+who
+ at c variables.cc
+-*- texinfo -*-
+ at deffn  {Command} who
+ at deffnx {Command} who pattern @dots{}
+ at deffnx {Command} who option pattern @dots{}
+ at deffnx {Command} C = who("pattern", @dots{})
+List currently defined variables matching the given patterns.  Valid
+pattern syntax is the same as described for the @code{clear} command.
+If no patterns are supplied, all variables are listed.
+By default, only variables visible in the local scope are displayed.
+
+The following are valid options but may not be combined.
+
+ at table @code
+ at item global
+List variables in the global scope rather than the current scope.
+ at item -regexp
+The patterns are considered to be regular expressions when matching the
+variables to display.  The same pattern syntax accepted by
+the @code{regexp} function is used.
+ at item -file
+The next argument is treated as a filename.  All variables found within the
+specified file are listed.  No patterns are accepted when reading variables
+from a file.
+ at end table
+
+If called as a function, return a cell array of defined variable names
+matching the given patterns.
+ at seealso{whos, regexp}
+ at end deffn
+whos
+ at c variables.cc
+-*- texinfo -*-
+ at deffn  {Command} whos
+ at deffnx {Command} whos pattern @dots{}
+ at deffnx {Command} whos option pattern @dots{}
+ at deffnx {Command} S = whos("pattern", @dots{})
+Provide detailed information on currently defined variables matching the
+given patterns.  Options and pattern syntax are the same as for the
+ at code{who} command.  Extended information about each variable is
+summarized in a table with the following default entries.
+
+ at table @asis
+ at item Attr
+Attributes of the listed variable.  Possible attributes are:
+ at table @asis
+ at item blank
+Variable in local scope
+ at item @code{g}
+Variable with global scope
+ at item @code{p}
+Persistent variable
+ at end table
+ at item Name
+The name of the variable.
+ at item Size
+The logical size of the variable.  A scalar is 1x1, a vector is 1xN or Nx1,
+a 2-D matrix is MxN.
+ at item Bytes
+The amount of memory currently used to store the variable.
+ at item Class
+The class of the variable.  Examples include double, single, char, uint16,
+cell, and struct.
+ at end table
+
+The table can be customized to display more or less information through
+the function @code{whos_line_format}.
+
+If @code{whos} is called as a function, return a struct array of defined
+variable names matching the given patterns.  Fields in the structure
+describing each variable are: name, size, bytes, class, global, sparse, 
+complex, nesting, persistent.
+ at seealso{who, whos_line_format}
+ at end deffn
+mlock
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mlock ()
+Lock the current function into memory so that it can't be cleared.
+ at seealso{munlock, mislocked, persistent}
+ at end deftypefn
+munlock
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} munlock (@var{fcn})
+Unlock the named function.  If no function is named
+then unlock the current function.
+ at seealso{mlock, mislocked, persistent}
+ at end deftypefn
+mislocked
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn {Built-in Function} {} mislocked (@var{fcn})
+Return true if the named function is locked.  If no function is named
+then return true if the current function is locked.
+ at seealso{mlock, munlock, persistent}
+ at end deftypefn
+clear
+ at c variables.cc
+-*- texinfo -*-
+ at deffn {Command} clear [options] pattern @dots{}
+Delete the names matching the given patterns from the symbol table.  The
+pattern may contain the following special characters:
+
+ at table @code
+ at item ?
+Match any single character.
+
+ at item *
+Match zero or more characters.
+
+ at item [ @var{list} ]
+Match the list of characters specified by @var{list}.  If the first
+character is @code{!} or @code{^}, match all characters except those
+specified by @var{list}.  For example, the pattern @samp{[a-zA-Z]} will
+match all lower and upper case alphabetic characters.
+ at end table
+
+For example, the command
+
+ at example
+clear foo b*r
+ at end example
+
+ at noindent
+clears the name @code{foo} and all names that begin with the letter
+ at code{b} and end with the letter @code{r}.
+
+If @code{clear} is called without any arguments, all user-defined
+variables (local and global) are cleared from the symbol table.  If
+ at code{clear} is called with at least one argument, only the visible
+names matching the arguments are cleared.  For example, suppose you have
+defined a function @code{foo}, and then hidden it by performing the
+assignment @code{foo = 2}.  Executing the command @kbd{clear foo} once
+will clear the variable definition and restore the definition of
+ at code{foo} as a function.  Executing @kbd{clear foo} a second time will
+clear the function definition.
+
+The following options are available in both long and short form
+ at table @code
+ at item -all, -a
+Clears all local and global user-defined variables and all functions
+from the symbol table.
+
+ at item -exclusive, -x
+Clears the variables that don't match the following pattern.
+
+ at item -functions, -f
+Clears the function names and the built-in symbols names.
+ at item -global, -g
+Clears the global symbol names.
+ at item -variables, -v
+Clears the local variable names.
+ at item -classes, -c
+Clears the class structure table and clears all objects.
+ at item -regexp, -r
+The arguments are treated as regular expressions as any variables that
+match will be cleared.
+ at end table
+With the exception of @code{exclusive}, all long options can be used 
+without the dash as well.
+ at end deffn
+whos_line_format
+ at c variables.cc
+-*- texinfo -*-
+ at deftypefn  {Built-in Function} {@var{val} =} whos_line_format ()
+ at deftypefnx {Built-in Function} {@var{old_val} =} whos_line_format (@var{new_val})
+Query or set the format string used by the command @code{whos}.
+
+A full format string is:
+
+ at c Set example in small font to prevent overfull line
+ at smallexample
+%[modifier]<command>[:width[:left-min[:balance]]];
+ at end smallexample
+
+The following command sequences are available:
+
+ at table @code
+ at item %a
+Prints attributes of variables (g=global, p=persistent,
+f=formal parameter, a=automatic variable).
+ at item %b
+Prints number of bytes occupied by variables.
+ at item %c
+Prints class names of variables.
+ at item %e
+Prints elements held by variables.
+ at item %n
+Prints variable names.
+ at item %s
+Prints dimensions of variables.
+ at item %t
+Prints type names of variables.
+ at end table
+
+Every command may also have an alignment modifier:
+
+ at table @code
+ at item l
+Left alignment.
+ at item r
+Right alignment (default).
+ at item c
+Column-aligned (only applicable to command %s).
+ at end table
+
+The @code{width} parameter is a positive integer specifying the minimum
+number of columns used for printing.  No maximum is needed as the field will
+auto-expand as required.
+
+The parameters @code{left-min} and @code{balance} are only available when the
+column-aligned modifier is used with the command @samp{%s}.
+ at code{balance} specifies the column number within the field width which will
+be aligned between entries.  Numbering starts from 0 which indicates the
+leftmost column.  @code{left-min} specifies the minimum field width to the
+left of the specified balance column.
+
+The default format is
+ at code{"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\n"}.
+ at seealso{whos}
+ at end deftypefn
diff --git a/src/LSODE-opts.cc b/src/LSODE-opts.cc
new file mode 100644
index 0000000..1cf786a
--- /dev/null
+++ b/src/LSODE-opts.cc
@@ -0,0 +1,423 @@
+// DO NOT EDIT!
+// Generated automatically from ../liboctave/LSODE-opts.in.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include "LSODE-opts.h"
+
+#include "defun-dld.h"
+#include "pr-output.h"
+
+#include "oct-obj.h"
+#include "utils.h"
+#include "pager.h"
+
+static LSODE_options lsode_opts;
+
+#define MAX_TOKENS 3
+
+struct LSODE_options_struct
+{
+  const char *keyword;
+  const char *kw_tok[MAX_TOKENS + 1];
+  int min_len[MAX_TOKENS + 1];
+  int min_toks_to_match;
+};
+
+#define NUM_OPTIONS 8
+
+static LSODE_options_struct LSODE_options_table [] =
+{
+  { "absolute tolerance",
+    { "absolute", "tolerance", 0, 0, },
+    { 1, 0, 0, 0, }, 1, },
+
+  { "relative tolerance",
+    { "relative", "tolerance", 0, 0, },
+    { 1, 0, 0, 0, }, 1, },
+
+  { "integration method",
+    { "integration", "method", 0, 0, },
+    { 3, 0, 0, 0, }, 1, },
+
+  { "initial step size",
+    { "initial", "step", "size", 0, },
+    { 3, 0, 0, 0, }, 1, },
+
+  { "maximum order",
+    { "maximum", "order", 0, 0, },
+    { 2, 1, 0, 0, }, 2, },
+
+  { "maximum step size",
+    { "maximum", "step", "size", 0, },
+    { 2, 1, 0, 0, }, 2, },
+
+  { "minimum step size",
+    { "minimum", "step", "size", 0, },
+    { 2, 0, 0, 0, }, 1, },
+
+  { "step limit",
+    { "step", "limit", 0, 0, },
+    { 1, 0, 0, 0, }, 1, },
+};
+
+static void
+print_LSODE_options (std::ostream& os)
+{
+  std::ostringstream buf;
+
+  os << "\n"
+     << "Options for LSODE include:\n\n"
+     << "  keyword                                             value\n"
+     << "  -------                                             -----\n";
+
+  LSODE_options_struct *list = LSODE_options_table;
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[0].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    Array<double> val = lsode_opts.absolute_tolerance ();
+
+    if (val.length () == 1)
+      {
+        os << val(0) << "\n";
+      }
+    else
+      {
+        os << "\n\n";
+        Matrix tmp = Matrix (ColumnVector (val));
+        octave_print_internal (os, tmp, false, 2);
+        os << "\n\n";
+      }
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[1].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = lsode_opts.relative_tolerance ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[2].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    os << lsode_opts.integration_method () << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[3].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = lsode_opts.initial_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[4].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = lsode_opts.maximum_order ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[5].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = lsode_opts.maximum_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[6].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = lsode_opts.minimum_step_size ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[7].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    int val = lsode_opts.step_limit ();
+
+    os << val << "\n";
+  }
+
+  os << "\n";
+}
+
+static void
+set_LSODE_options (const std::string& keyword, const octave_value& val)
+{
+  LSODE_options_struct *list = LSODE_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> tmp = val.vector_value ();
+
+      if (! error_state)
+        lsode_opts.set_absolute_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        lsode_opts.set_relative_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      std::string tmp = val.string_value ();
+
+      if (! error_state)
+        lsode_opts.set_integration_method (tmp);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        lsode_opts.set_initial_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        lsode_opts.set_maximum_order (tmp);
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        lsode_opts.set_maximum_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[6].kw_tok, list[6].min_len,
+           keyword, list[6].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        lsode_opts.set_minimum_step_size (tmp);
+    }
+  else if (keyword_almost_match (list[7].kw_tok, list[7].min_len,
+           keyword, list[7].min_toks_to_match, MAX_TOKENS))
+    {
+      int tmp = val.int_value ();
+
+      if (! error_state)
+        lsode_opts.set_step_limit (tmp);
+    }
+  else
+    {
+      warning ("lsode_options: no match for `%s'", keyword.c_str ());
+    }
+}
+
+static octave_value_list
+show_LSODE_options (const std::string& keyword)
+{
+  octave_value retval;
+
+  LSODE_options_struct *list = LSODE_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      Array<double> val = lsode_opts.absolute_tolerance ();
+
+      if (val.length () == 1)
+        {
+          retval = val(0);
+        }
+      else
+        {
+          retval = ColumnVector (val);
+        }
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = lsode_opts.relative_tolerance ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      retval = lsode_opts.integration_method ();
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = lsode_opts.initial_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[4].kw_tok, list[4].min_len,
+           keyword, list[4].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = lsode_opts.maximum_order ();
+
+      retval = static_cast<double> (val);
+    }
+  else if (keyword_almost_match (list[5].kw_tok, list[5].min_len,
+           keyword, list[5].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = lsode_opts.maximum_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[6].kw_tok, list[6].min_len,
+           keyword, list[6].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = lsode_opts.minimum_step_size ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[7].kw_tok, list[7].min_len,
+           keyword, list[7].min_toks_to_match, MAX_TOKENS))
+    {
+      int val = lsode_opts.step_limit ();
+
+      retval = static_cast<double> (val);
+    }
+  else
+    {
+      warning ("lsode_options: no match for `%s'", keyword.c_str ());
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (lsode_options, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} lsode_options (@var{opt}, @var{val})\n\
+When called with two arguments, this function\n\
+allows you set options parameters for the function @code{lsode}.\n\
+Given one argument, @code{lsode_options} returns the value of the\n\
+corresponding option.  If no arguments are supplied, the names of all\n\
+the available options and their current values are displayed.\n\
+\n\
+Options include\n\
+\n\
+ at table @code\n\
+ at item \"absolute tolerance\"\n\
+Absolute tolerance.  May be either vector or scalar.  If a vector, it\n\
+must match the dimension of the state vector.\n\
+ at item \"relative tolerance\"\n\
+Relative tolerance parameter.  Unlike the absolute tolerance, this\n\
+parameter may only be a scalar.\n\
+\n\
+The local error test applied at each integration step is\n\
+\n\
+ at example\n\
+ at group\n\
+  abs (local error in x(i)) <= ...\n\
+      rtol * abs (y(i)) + atol(i)\n\
+ at end group\n\
+ at end example\n\
+ at item \"integration method\"\n\
+A string specifying the method of integration to use to solve the ODE\n\
+system.  Valid values are\n\
+\n\
+ at table @asis\n\
+ at item \"adams\"\n\
+ at itemx \"non-stiff\"\n\
+No Jacobian used (even if it is available).\n\
+ at item \"bdf\"\n\
+ at item \"stiff\"\n\
+Use stiff backward differentiation formula (BDF) method.  If a\n\
+function to compute the Jacobian is not supplied, @code{lsode} will\n\
+compute a finite difference approximation of the Jacobian matrix.\n\
+ at end table\n\
+ at item \"initial step size\"\n\
+The step size to be attempted on the first step (default is determined\n\
+automatically).\n\
+ at item \"maximum order\"\n\
+Restrict the maximum order of the solution method.  If using the Adams\n\
+method, this option must be between 1 and 12.  Otherwise, it must be\n\
+between 1 and 5, inclusive.\n\
+ at item \"maximum step size\"\n\
+Setting the maximum stepsize will avoid passing over very large\n\
+regions  (default is not specified).\n\
+ at item \"minimum step size\"\n\
+The minimum absolute step size allowed (default is 0).\n\
+ at item \"step limit\"\n\
+Maximum number of steps allowed (default is 100000).\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_LSODE_options (octave_stdout);
+    }
+  else if (nargin == 1 || nargin == 2)
+    {
+      std::string keyword = args(0).string_value ();
+
+      if (! error_state)
+        {
+          if (nargin == 1)
+            retval = show_LSODE_options (keyword);
+          else
+            set_LSODE_options (keyword, args(1));
+        }
+      else
+        error ("lsode_options: expecting keyword as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..e794972
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,681 @@
+# Makefile for octave's src directory
+#
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+#               2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@:@srcdir@/DLD-FUNCTIONS:@srcdir@/OPERATORS:@srcdir@/TEMPLATE-INST
+
+include $(TOPDIR)/Makeconf
+
+DLL_CDEFS = @OCTINTERP_DLL_DEFS@
+DLL_CXXDEFS = @OCTINTERP_DLL_DEFS@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+PT_FLAGS = -fexternal-templates -fno-implicit-templates
+CXXFLAGS_NO_PT_FLAGS = $(filter-out $(PT_FLAGS), $(ALL_CXXFLAGS))
+
+%.df : %.cc
+	@echo making $@ from $<
+	@(echo "// DO NOT EDIT!  Generated automatically by mkdefs." ; \
+	  echo " XDEFUN_FILE_NAME (\"$<\")" ; \
+	  egrep '^(///*|/\*) *PKG_ADD:' $< ; \
+	  $(CXXCPP) $(CPPFLAGS) $(CXXFLAGS_NO_PT_FLAGS) -DMAKE_BUILTINS $< \
+	    | $(srcdir)/mkdefs) > $@-t
+	@mv $@-t $@
+
+# How to make a .oct file from a .o file:
+
+ifeq ($(ENABLE_DYNAMIC_LINKING), true)
+  ifdef CXXPICFLAG
+    %.oct : pic/%.o octave$(EXEEXT)
+	  $(DL_LD) $(DL_LDFLAGS) -o $@ $< $(OCT_LINK_DEPS)
+  else
+    %.oct : %.o octave$(EXEEXT)
+	  $(DL_LD) $(DL_LDFLAGS) -o $@ $< $(OCT_LINK_DEPS)
+  endif
+endif
+
+OPT_BASE := $(addsuffix -opts, DASPK DASRT DASSL LSODE Quad)
+OPT_HANDLERS := $(addsuffix .cc, $(OPT_BASE))
+OPT_IN := $(addprefix ../liboctave/, $(addsuffix .in, $(OPT_BASE)))
+OPT_INC := $(addprefix ../liboctave/, $(addsuffix .h, $(OPT_BASE)))
+
+DLD_XSRC := amd.cc balance.cc besselj.cc betainc.cc bsxfun.cc \
+	cellfun.cc chol.cc ccolamd.cc colamd.cc colloc.cc \
+	conv2.cc convhulln.cc daspk.cc dasrt.cc dassl.cc det.cc \
+	dispatch.cc dlmread.cc dmperm.cc eig.cc eigs.cc fft.cc \
+	fft2.cc fftn.cc fftw.cc filter.cc find.cc fltk_backend.cc \
+	gammainc.cc gcd.cc getgrent.cc getpwent.cc getrusage.cc \
+	givens.cc hess.cc hex2num.cc inv.cc kron.cc lookup.cc \
+	lsode.cc lu.cc luinc.cc matrix_type.cc max.cc md5sum.cc \
+	pinv.cc qr.cc quad.cc qz.cc rand.cc rcond.cc regexp.cc \
+	schur.cc sparse.cc spparms.cc sqrtm.cc svd.cc syl.cc \
+	symrcm.cc symbfact.cc time.cc tsearch.cc typecast.cc \
+	urlwrite.cc __contourc__.cc __delaunayn__.cc \
+	__dsearchn__.cc __glpk__.cc __lin_interpn__.cc \
+	__magick_read__.cc __pchip_deriv__.cc __qp__.cc \
+	__voronoi__.cc __convn__.cc
+
+DLD_SRC := $(addprefix DLD-FUNCTIONS/, $(DLD_XSRC))
+
+DLD_OBJ_1 := $(patsubst %.l, %.o, $(DLD_XSRC))
+DLD_OBJ := $(patsubst %.cc, %.o, $(DLD_OBJ_1))
+
+ifeq ($(ENABLE_DYNAMIC_LINKING), true)
+  OCT_FILES := $(patsubst %.o, %.oct, $(DLD_OBJ))
+  ifdef CXXPICFLAG
+    DLD_PICOBJ := $(addprefix pic/, $(DLD_OBJ))
+  else
+    DLD_PICOBJ := $(DLD_OBJ)
+  endif
+else
+  DLD_STATIC_OBJ := $(DLD_OBJ)
+endif
+
+OV_INTTYPE_INC := ov-base-int.h ov-int-traits.h ov-intx.h \
+	ov-int8.h ov-int16.h ov-int32.h ov-int64.h \
+	ov-uint8.h ov-uint16.h ov-uint32.h ov-uint64.h
+
+OV_INCLUDES := ov-re-mat.h ov-cx-mat.h ov-ch-mat.h ov-cs-list.h ov-list.h \
+	ov-struct.h ov-scalar.h ov-range.h ov-complex.h \
+	ov-colon.h ov-base.h ov-base-mat.h ov-base-scalar.h \
+	ov-str-mat.h ov-bool-mat.h ov-null-mat.h ov-bool.h \
+	ov-base-diag.h ov-re-diag.h ov-flt-re-diag.h ov-cx-diag.h \
+	ov-flt-cx-diag.h ov-perm.h \
+	ov-cell.h ov.h ov-fcn.h ov-builtin.h ov-dld-fcn.h \
+	ov-mex-fcn.h ov-usr-fcn.h ov-fcn-handle.h \
+	ov-fcn-inline.h ov-class.h ov-typeinfo.h ov-type-conv.h \
+	ov-flt-re-mat.h ov-flt-cx-mat.h ov-float.h ov-flt-complex.h \
+	$(OV_INTTYPE_INC)
+
+OV_SPARSE_INCLUDES := \
+	ov-base-sparse.h ov-bool-sparse.h ov-cx-sparse.h ov-re-sparse.h
+
+PT_INCLUDES := pt.h pt-all.h pt-arg-list.h pt-assign.h pt-binop.h \
+        pt-bp.h pt-cbinop.h pt-cell.h pt-check.h pt-cmd.h pt-colon.h \
+	pt-const.h pt-decl.h pt-eval.h pt-except.h pt-exp.h pt-fcn-handle.h \
+	pt-id.h pt-idx.h pt-jump.h pt-loop.h pt-mat.h pt-misc.h \
+	pt-pr-code.h pt-select.h pt-stmt.h pt-unop.h pt-walk.h
+
+INCLUDES := Cell.h base-list.h builtins.h c-file-ptr-stream.h \
+	comment-list.h debug.h defun-dld.h defun-int.h defun.h \
+	dirfns.h display.h dynamic-ld.h error.h file-io.h gl-render.h \
+	gripes.h help.h input.h lex.h load-path.h load-save.h ls-hdf5.h \
+	ls-mat-ascii.h ls-mat4.h ls-mat5.h ls-oct-ascii.h ls-ascii-helper.h \
+	ls-oct-binary.h ls-utils.h mex.h mexproto.h oct-errno.h \
+	oct-fstrm.h oct-hdf5.h oct-hist.h oct-iostrm.h oct-map.h oct-obj.h \
+	oct-prcstrm.h oct-procbuf.h oct-stdstrm.h oct-stream.h \
+	zfstream.h oct-strstrm.h oct-lvalue.h oct.h octave.h ops.h \
+	pager.h parse.h pr-output.h procstream.h sighandlers.h \
+	siglist.h sparse-xdiv.h sparse-xpow.h symtab.h sysdep.h \
+	token.h toplev.h unwind-prot.h utils.h variables.h \
+	version.h xdiv.h xnorm.h xpow.h \
+	$(OV_INCLUDES) \
+	$(PT_INCLUDES) \
+	$(OV_SPARSE_INCLUDES)
+
+TI_XSRC := Array-os.cc Array-tc.cc
+
+TI_SRC := $(addprefix TEMPLATE-INST/, $(TI_XSRC))
+
+INTTYPE_OP_XSRC := op-int-concat.cc op-int-conv.cc \
+	op-i8-i8.cc op-i16-i16.cc op-i32-i32.cc op-i64-i64.cc \
+	op-ui8-ui8.cc op-ui16-ui16.cc op-ui32-ui32.cc op-ui64-ui64.cc
+
+SPARSE_OP_XSRC := op-bm-sbm.cc op-b-sbm.cc op-cm-scm.cc op-cm-sm.cc \
+	op-cs-scm.cc op-cs-sm.cc op-m-scm.cc op-m-sm.cc op-sbm-b.cc \
+	op-sbm-bm.cc op-sbm-sbm.cc op-scm-cm.cc op-scm-cs.cc op-scm-m.cc \
+	op-scm-s.cc op-scm-scm.cc op-scm-sm.cc op-sm-cm.cc \
+	op-sm-cs.cc op-sm-m.cc op-sm-s.cc op-sm-scm.cc op-sm-sm.cc \
+	op-s-scm.cc op-s-sm.cc
+
+DOUBLE_OP_XSRC := op-double-conv.cc op-cm-cm.cc op-cm-cs.cc op-cm-m.cc \
+	op-cm-s.cc op-cs-cm.cc op-cs-cs.cc op-cs-m.cc \
+	op-cs-s.cc op-m-cm.cc \
+	op-m-cs.cc op-m-m.cc op-m-s.cc op-s-cm.cc \
+	op-s-cs.cc op-s-m.cc op-s-s.cc 
+
+FLOAT_OP_XSRC := op-float-conv.cc op-fcm-fcm.cc op-fcm-fcs.cc op-fcm-fm.cc \
+	op-fcm-fs.cc op-fcs-fcm.cc op-fcs-fcs.cc op-fcs-fm.cc \
+	op-fcs-fs.cc op-fm-fcm.cc \
+	op-fm-fcs.cc op-fm-fm.cc op-fm-fs.cc op-fs-fcm.cc \
+	op-fs-fcs.cc op-fs-fm.cc op-fs-fs.cc 
+
+DIAG_OP_XSRC := op-cdm-cdm.cc op-cdm-cm.cc op-cdm-cs.cc op-cdm-dm.cc \
+	op-cdm-m.cc op-cdm-s.cc op-cm-cdm.cc op-cm-dm.cc op-dm-cdm.cc \
+	op-dm-cm.cc op-dm-cs.cc op-dm-dm.cc op-dm-m.cc op-dm-s.cc \
+	op-m-cdm.cc op-m-dm.cc op-dm-sm.cc op-dm-scm.cc
+
+FDIAG_OP_XSRC := op-fcdm-fcdm.cc op-fcdm-fcm.cc op-fcdm-fcs.cc op-fcdm-fdm.cc \
+	op-fcdm-fm.cc op-fcdm-fs.cc op-fcm-fcdm.cc op-fcm-fdm.cc \
+	op-fdm-fcdm.cc op-fdm-fcm.cc op-fdm-fcs.cc op-fdm-fdm.cc \
+	op-fdm-fm.cc op-fdm-fs.cc op-fm-fcdm.cc op-fm-fdm.cc
+
+PERM_OP_XSRC := op-cm-pm.cc op-fcm-pm.cc op-fm-pm.cc op-pm-fcm.cc \
+	op-pm-fm.cc op-m-pm.cc op-pm-cm.cc op-pm-m.cc op-pm-pm.cc \
+	op-pm-sm.cc op-pm-scm.cc
+
+OP_XSRC :=  op-b-b.cc op-b-bm.cc op-bm-b.cc op-bm-bm.cc op-cell.cc \
+	op-chm.cc op-class.cc op-list.cc op-range.cc op-str-m.cc \
+	op-str-s.cc op-str-str.cc op-struct.cc \
+	$(DOUBLE_OP_XSRC) $(FLOAT_OP_XSRC) $(INTTYPE_OP_XSRC) \
+	$(SPARSE_OP_XSRC) $(DIAG_OP_XSRC) $(FDIAG_OP_XSRC) $(PERM_OP_XSRC)
+
+OP_SRC := $(addprefix OPERATORS/, $(OP_XSRC))
+
+OP_INCLUDES := OPERATORS/op-int.h \
+	OPERATORS/op-dm-template.cc OPERATORS/op-dms-template.cc OPERATORS/op-pm-template.cc
+
+OV_INTTYPE_SRC := \
+	ov-int8.cc ov-int16.cc ov-int32.cc ov-int64.cc \
+	ov-uint8.cc ov-uint16.cc ov-uint32.cc ov-uint64.cc
+
+OV_SPARSE_SRC := \
+	ov-base-sparse.cc ov-bool-sparse.cc ov-cx-sparse.cc ov-re-sparse.cc
+
+OV_SRC := ov-base.cc ov-ch-mat.cc \
+	ov-cs-list.cc ov-list.cc ov-re-mat.cc ov-cx-mat.cc \
+	ov-range.cc ov-scalar.cc ov-complex.cc ov-str-mat.cc \
+	ov-struct.cc \
+	ov-colon.cc ov-bool-mat.cc ov-bool.cc ov-null-mat.cc ov-cell.cc \
+	ov.cc ov-fcn.cc ov-builtin.cc ov-dld-fcn.cc \
+	ov-mex-fcn.cc ov-usr-fcn.cc ov-fcn-handle.cc ov-fcn-inline.cc \
+	ov-class.cc ov-typeinfo.cc \
+	ov-flt-re-mat.cc ov-flt-cx-mat.cc ov-float.cc ov-flt-complex.cc \
+	ov-re-diag.cc ov-flt-re-diag.cc ov-cx-diag.cc ov-flt-cx-diag.cc \
+	ov-perm.cc \
+	$(OV_INTTYPE_SRC) \
+	$(OV_SPARSE_SRC)
+
+PT_SRC := pt.cc pt-arg-list.cc pt-assign.cc pt-bp.cc pt-binop.cc \
+	pt-cbinop.cc pt-cell.cc pt-check.cc pt-cmd.cc pt-colon.cc \
+	pt-const.cc pt-decl.cc pt-eval.cc pt-except.cc pt-exp.cc \
+	pt-fcn-handle.cc pt-id.cc pt-idx.cc pt-jump.cc pt-loop.cc \
+	pt-mat.cc pt-misc.cc pt-pr-code.cc pt-select.cc pt-stmt.cc \
+	pt-unop.cc
+
+DIST_SRC := Cell.cc bitfcns.cc c-file-ptr-stream.cc comment-list.cc \
+	cutils.c data.cc debug.cc defaults.cc defun.cc dirfns.cc \
+	display.cc dynamic-ld.cc error.cc file-io.cc gl-render.cc \
+	graphics.cc gripes.cc help.cc input.cc lex.l load-path.cc \
+	load-save.cc ls-hdf5.cc ls-mat-ascii.cc ls-mat4.cc \
+	ls-mat5.cc ls-oct-ascii.cc ls-ascii-helper.cc \
+	ls-oct-binary.cc ls-utils.cc main.c mappers.cc matherr.c \
+	mex.cc oct-fstrm.cc oct-hist.cc oct-iostrm.cc oct-map.cc \
+	oct-obj.cc oct-prcstrm.cc oct-procbuf.cc oct-stream.cc \
+	octave.cc zfstream.cc oct-strstrm.cc oct-lvalue.cc pager.cc \
+	parse.y pr-output.cc procstream.cc sighandlers.cc \
+	siglist.c sparse-xdiv.cc sparse-xpow.cc strfns.cc \
+	syscalls.cc symtab.cc sysdep.cc token.cc toplev.cc \
+	unwind-prot.cc utils.cc variables.cc xdiv.cc xnorm.cc xpow.cc \
+	$(OV_SRC) \
+	$(PT_SRC)
+
+SOURCES := $(DIST_SRC) $(OP_SRC) $(TI_SRC)
+
+BUILT_EXTRAS := graphics.h mxarray.h
+
+EXTRAS := ov-base-int.cc ov-base-mat.cc ov-base-diag.cc ov-base-scalar.cc graphics-props.cc
+
+EXTRA_OBJECTS := oct-errno.o octave.o builtins.o ops.o
+
+INCLUDES_FOR_INSTALL := $(INCLUDES) $(EXTRAS) $(BUILT_EXTRAS)
+
+OBJECTS_4 := $(notdir $(SOURCES))
+OBJECTS_3 := $(patsubst %.l, %.o, $(OBJECTS_4))
+OBJECTS_2 := $(patsubst %.y, %.o, $(OBJECTS_3))
+OBJECTS_1 := $(patsubst %.c, %.o, $(OBJECTS_2))
+OBJECTS := $(patsubst %.cc, %.o, $(OBJECTS_1)) $(EXTRA_OBJECTS)
+
+ifeq ($(SHARED_LIBS), true)
+  ifdef CXXPICFLAG
+    PICOBJ := $(addprefix pic/, $(OBJECTS))
+  else
+    PICOBJ := $(OBJECTS)
+  endif
+endif
+
+# Ugh.
+
+DEP_5 := $(SOURCES) $(DLD_SRC) builtins.cc oct-errno.cc ops.cc main.c
+DEP_4 := $(notdir $(DEP_5))
+DEP_3 := $(patsubst %.l, %.cc, $(DEP_4))
+DEP_2 := $(patsubst %.y, %.cc, $(DEP_3))
+DEP_1 := $(patsubst %.c, %.d, $(DEP_2))
+MAKEDEPS := $(patsubst %.cc, %.d, $(DEP_1))
+
+# Some stupid egreps don't like empty elements in alternation patterns,
+# so we have to repeat ourselves because some stupid egreps don't like
+# empty elements in alternation patterns.
+
+DEFUN_PATTERN = "^[ \t]*DEF(CONSTFUN|CMD|UN|UN_DLD|UNX_DLD|UN_TEXT)[ \t]*\\("
+
+DLD_DEF_FILES_1 := $(patsubst %.l, %.df, $(DLD_XSRC))
+DLD_DEF_FILES := $(patsubst %.cc, %.df, $(DLD_DEF_FILES_1))
+
+DEF_4 := $(addprefix $(srcdir)/, $(SOURCES))
+DEF_3 := $(notdir $(shell egrep -l $(DEFUN_PATTERN) $(DEF_4)))
+DEF_2 := $(patsubst %.y, %.df, $(DEF_3))
+DEF_1 := $(patsubst %.l, %.df, $(DEF_2))
+DEF_FILES := $(patsubst %.cc, %.df, $(DEF_1)) $(DLD_DEF_FILES)
+
+DOC_FILES := $(sort $(DEF_FILES))
+
+OCTAVE_LFLAGS = -L$(TOPDIR)/liboctave -L$(TOPDIR)/libcruft \
+  -L$(TOPDIR)/src $(RLD_FLAG)
+
+ifeq ($(ENABLE_DYNAMIC_LINKING), true)
+  OCTAVE_LIBS = $(LIBOCTINTERP) $(LIBOCTAVE) \
+    $(SPECIAL_MATH_LIB) $(LIBCRUFT) \
+    $(LIBPLPLOT) $(LIBGLOB)
+else
+  OCTAVE_LIBS = $(LIBOCTINTERP) $(LIBOCTAVE) $(QHULL_LIBS) \
+    $(GLPK_LIBS) $(MAGICK_LIBS) $(REGEX_LIBS) $(SPECIAL_MATH_LIB) $(LIBCRUFT) \
+    $(LIBPLPLOT) $(LIBGLOB)
+endif
+
+OCTINTERP_LINK_DEPS = \
+  -L../liboctave $(LIBOCTAVE) -L../libcruft $(LIBCRUFT) $(LIBS) $(FLIBS) \
+  $(X11_LIBS) $(OPENGL_LIBS) $(CARBON_LIBS)
+
+OCT_LINK_DEPS = \
+  -L../libcruft $(LIBCRUFT) -L../liboctave $(LIBOCTAVE) \
+  -L. $(LIBOCTINTERP) $(CHOLMOD_LIBS) $(UMFPACK_LIBS) $(AMD_LIBS) \
+   $(CAMD_LIBS) $(COLAMD_LIBS) $(CCOLAMD_LIBS) $(CXSPARSE_LIBS) $(BLAS_LIBS) \
+   $(FFTW_LIBS) $(QRUPDATE_LIBS) $(ARPACK_LIBS) $(LIBS) $(FLIBS)
+
+BUILT_DISTFILES = DOCSTRINGS oct-gperf.h parse.cc lex.cc y.tab.h \
+	$(OPT_HANDLERS) $(BUILT_EXTRAS)
+
+DISTFILES = Makefile.in ChangeLog genprops.awk mkdefs mkops mkgendoc \
+	mkbuiltins mk-errno-list mk-pkg-add \
+	defaults.h.in graphics.h.in mxarray.h.in oct-conf.h.in \
+	oct-errno.cc.in octave.gperf \
+	$(INCLUDES) $(DIST_SRC) $(EXTRAS)
+
+all: octave$(EXEEXT) $(OCT_FILES) PKG_ADD DOCSTRINGS
+.PHONY: all
+
+objects: $(OBJECTS)
+
+lex.o parse.o pic/lex.o pic/parse.o: \
+	ALL_CXXFLAGS := $(filter-out -Wold-style-cast, $(ALL_CXXFLAGS))
+
+$(DLD_PICOBJ): \
+	ALL_CXXFLAGS := $(filter-out $(DLL_CXXDEFS), $(ALL_CXXFLAGS))
+
+fltk_backend.o pic/fltk_backend.o: \
+	ALL_CXXFLAGS := $(filter-out $(DLL_CXXDEFS), $(ALL_CXXFLAGS) $(GRAPHICS_CFLAGS))
+
+XERBLA = ../libcruft/blas-xtra/xerbla.o
+ifdef FPICFLAG
+  PIC_XERBLA = ../libcruft/blas-xtra/pic/xerbla.o
+else
+  PIC_XERBLA = $(XERBLA)
+endif
+
+ifeq ($(SHARED_LIBS), true)
+  ifeq ($(STATIC_LIBS), true)
+    LIBRARIES = $(LIBPRE)octinterp.$(LIBEXT) $(SHLPRE)octinterp.$(SHLEXT_VER)
+  else
+    LIBRARIES = $(SHLPRE)octinterp.$(SHLEXT_VER)
+  endif
+else
+  ifeq ($(STATIC_LIBS), true)
+    LIBRARIES = $(LIBPRE)octinterp.$(LIBEXT)
+  else
+    ## This is not going to work, but hey, you asked for it...
+    LIBRARIES =
+  endif
+endif
+
+libraries: $(LIBRARIES)
+.PHONY: libraries
+
+$(LIBPRE)octinterp.$(LIBEXT): $(OBJECTS) $(XERBLA)
+	rm -f $@
+	$(TEMPLATE_AR) $(TEMPLATE_ARFLAGS) $@ $^
+	$(RANLIB) $@
+
+$(SHLPRE)octinterp.$(SHLEXT_VER): $(SHLPRE)octinterp.$(SHLEXT)
+	rm -f $@
+	$(LN_S) $< $@
+
+$(SHLPRE)octinterp.$(SHLEXT): $(PICOBJ) $(PIC_XERBLA)
+	rm -f $@
+	$(SH_LD) $(SH_LDFLAGS) $(SONAME_FLAGS) -o $@ $^ $(OCTINTERP_LINK_DEPS)
+
+octave$(EXEEXT): $(LIBRARIES) main.o $(DLD_STATIC_OBJ)
+	$(LD_CXX) $(CPPFLAGS) $(ALL_CXXFLAGS) $(RDYNAMIC_FLAG) \
+	$(ALL_LDFLAGS) -o $@ \
+	main.o $(DLD_STATIC_OBJ) \
+	$(OCTAVE_LFLAGS) \
+	$(OCTAVE_LIBS) \
+	$(LEXLIB) $(UMFPACK_LIBS) $(AMD_LIBS) $(CAMD_LIBS) $(COLAMD_LIBS) \
+	$(CHOLMOD_LIBS) $(CCOLAMD_LIBS) $(CXSPARSE_LIBS) $(BLAS_LIBS) \
+	$(FFTW_LIBS) $(QRUPDATE_LIBS) $(ARPACK_LIBS) $(OPENGL_LIBS) \
+	$(X11_LIBS) $(CARBON_LIBS) $(LIBS) $(FLIBS)
+
+stmp-pic: pic
+	@if [ -f stmp-pic ]; then \
+	  true; \
+	else \
+	  echo "touch stmp-pic"; \
+	  touch stmp-pic; \
+	fi
+
+pic:
+	@if [ -d pic ]; then \
+	  true; \
+	else \
+	  echo "mkdir pic"; \
+	  mkdir pic; \
+	fi
+
+$(PICOBJ): stmp-pic
+
+builtins.cc: $(DEF_FILES) mkbuiltins
+	@echo making $@
+	@echo DEF_FILES = $(DEF_FILES)
+	@echo $(DEF_FILES) > def-files
+	@$(srcdir)/mkbuiltins def-files > $@-t
+	@mv $@-t $@
+
+## FIXME -- maybe genprops.awk should write both output files?
+## Or maybe there should be separate commands to generate each file?
+graphics.h graphics-props.cc: graphics.h.in genprops.awk
+	@echo making graphics.h and graphics-props.cc
+	@$(AWK) -f $(srcdir)/genprops.awk $< > graphics.h-t
+	@mv graphics.h-t graphics.h
+
+PKG_ADD: $(DLD_DEF_FILES)
+	$(srcdir)/mk-pkg-add $(DLD_DEF_FILES) > $@-t
+	@mv $@-t $@
+
+DOCSTRINGS: gendoc$(BUILD_EXEEXT)
+	@echo making $@
+	@./gendoc > $@-t
+	@mv $@-t $@
+
+doc-files: $(DOC_FILES)
+	@echo making $@
+	@echo DOC_FILES = $(DOC_FILES)
+	@echo $(DOC_FILES) > $@-t
+	mv $@-t $@
+
+gendoc.cc: doc-files mkgendoc
+	@echo making $@
+	@$(srcdir)/mkgendoc doc-files > $@-t
+	@mv $@-t $@
+
+gendoc$(BUILD_EXEEXT): gendoc.cc
+	$(BUILD_CXX) $(BUILD_CXXFLAGS) -o $@ $^ $(BUILD_LDFLAGS)
+
+ops.cc: $(OP_SRC) mkops
+	@echo making $@ from $(OP_SRC)
+	@$(srcdir)/mkops $(OP_SRC) > $@-t
+	@mv $@-t $@
+
+PREREQ := defaults.h graphics.h oct-conf.h oct-errno.cc oct-gperf.h parse.cc lex.cc 
+
+$(DEF_FILES): $(OPT_INC) mkdefs 
+
+ifndef omit_deps
+$(MAKEDEPS): $(OPT_INC) $(OPT_HANDLERS) $(PREREQ)
+endif
+
+check: all
+.PHONY: check
+
+install: install-bin install-oct install-lib install-inc
+.PHONY: install
+
+install-strip:
+	$(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM) -s" install
+.PHONY: install-strip
+
+install-bin:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
+	rm -f $(DESTDIR)$(bindir)/octave$(EXEEXT)
+	$(INSTALL_PROGRAM) octave$(EXEEXT) $(DESTDIR)$(bindir)/octave-$(version)$(EXEEXT)
+	cd $(DESTDIR)$(bindir) ; $(LN_S) octave-$(version)$(EXEEXT) octave$(EXEEXT)
+.PHONY: install-bin
+
+install-oct:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octfiledir)
+	$(INSTALL_DATA) PKG_ADD $(DESTDIR)$(octfiledir)/PKG_ADD
+	if [ -n "$(OCT_FILES)" ]; then \
+	  xfiles="$(OCT_FILES)"; \
+	  for f in $$xfiles; do \
+	    $(INSTALL_PROGRAM) $$f $(DESTDIR)$(octfiledir)/$$f; \
+	  done; \
+	fi
+.PHONY: install-oct
+
+install-lib:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octlibdir)
+	if $(STATIC_LIBS); then \
+	  rm -f $(DESTDIR)$(octlibdir)/$(LIBPRE)octinterp.$(LIBEXT); \
+	  $(INSTALL_DATA) $(LIBPRE)octinterp.$(LIBEXT) \
+	    $(DESTDIR)$(octlibdir)/$(LIBPRE)octinterp.$(LIBEXT); \
+	  $(RANLIB) $(DESTDIR)$(octlibdir)/$(LIBPRE)octinterp.$(LIBEXT); \
+	fi
+	if $(SHARED_LIBS); then \
+	  rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB_VER); \
+	  $(INSTALL) $(SHLLIBPRE)octinterp.$(SHLLIB) \
+	    $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB_VER); \
+	  rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB); \
+	  (cd $(DESTDIR)$(octlibdir) ; $(LN_S) $(SHLLIBPRE)octinterp.$(SHLLIB_VER) $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB)); \
+	  if  test x$(SHLBIN) != x ; then \
+	    rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)octinterp.$(SHLBIN); \
+	    $(INSTALL_PROGRAM) \
+	      $(SHLBINPRE)octinterp.$(SHLBIN) $(DESTDIR)$(bindir)/$(SHLBINPRE)octinterp.$(SHLBIN); \
+	  fi; \
+	fi
+.PHONY: install-lib
+
+install-inc:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(octincludedir)/octave
+	for f in $(INCLUDES_FOR_INSTALL); do \
+	  rm -f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  if [ -f $$f ]; then \
+	    $(INSTALL_DATA) $$f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  else \
+	    $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  fi ; \
+	done
+	for f in defaults.h oct-conf.h oct-gperf.h; do \
+	  rm -f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	  if [ -f $$f ]; then \
+	    $(INSTALL_DATA) $$f $(DESTDIR)$(octincludedir)/octave/$$f ; \
+	  else \
+	    $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(octincludedir)/octave/$$f ; \
+	  fi ; \
+	done
+.PHONY: install-inc
+
+uninstall:
+	rm -f $(DESTDIR)$(bindir)/octave$(EXEEXT)
+	rm -f $(DESTDIR)$(bindir)/octave-$(version)$(EXEEXT)
+	rm -f $(DESTDIR)$(octlibdir)/$(LIBPRE)octinterp.$(LIBEXT)
+	rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB)
+	rm -f $(DESTDIR)$(octlibdir)/$(SHLLIBPRE)octinterp.$(SHLLIB_VER)
+	if test x$(SHLBIN) != x ; then \
+	  rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)octinterp.$(SHLBIN); \
+	  rm -f $(DESTDIR)$(bindir)/$(SHLBINPRE)octinterp.$(SHLBIN_VER); \
+	fi
+	for f in $(INCLUDES_FOR_INSTALL) defaults.h oct-conf.h oct-gperf.h; do \
+	  rm -f $(DESTDIR)$(octincludedir)/octave/$$f; \
+	done
+	if [ -n "$(OCT_FILES)" ]; then \
+	  xfiles="$(OCT_FILES)"; \
+	  for f in $$xfiles; do \
+	    rm -f $(DESTDIR)$(octfiledir)/$$f; \
+	  done; \
+	fi
+	rm -f $(DESTDIR)$(octfiledir)/PKG_ADD
+	-rmdir $(DESTDIR)$(octincludedir)/octave
+	-rmdir $(DESTDIR)$(octincludedir)
+	-rmdir $(DESTDIR)$(octlibdir)
+	-rmdir $(DESTDIR)$(octfiledir)
+.PHONY: uninstall
+
+tags: $(SOURCES) $(DLD_SRC)
+	ctags $(SOURCES) $(DLD_SRC)
+
+TAGS: $(SOURCES) $(DLD_SRC)
+	etags $(SOURCES) $(DLD_SRC)
+
+clean:
+	rm -f $(LIBPRE)octinterp.$(LIBEXT)
+	rm -f $(SHLPRE)octinterp.$(SHLEXT_VER) $(SHLPRE)octinterp.$(SHLEXT)
+	rm -f $(SHLBINPRE)octinterp.$(SHLBIN_VER) $(SHLBINPRE)octinterp.$(SHLBIN)
+	rm -f $(OBJECTS) $(DLD_OBJ) $(MAKEDEPS) $(DOC_FILES) $(OCT_FILES)
+	rm -f $(PICOBJ) $(DLD_PICOBJ) stmp-pic gendoc$(EXEEXT)
+	rm -f builtins.cc ops.cc defaults.h oct-conf.h def-files
+	rm -f PKG_ADD
+	-rmdir pic
+.PHONY: clean
+
+mostlyclean: clean
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile octave$(EXEEXT) .fname so_locations oct-errno.cc
+	rm -f tags TAGS y.output yy.lex.c parse.output
+	rm -f stamp-liboctave-prereq
+	rm -f doc-files gendoc.cc graphics.h graphics-props.cc mxarray.h DOCSTRINGS
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f lex.cc parse.cc y.tab.h
+	rm -f oct-gperf.h $(OPT_HANDLERS)
+.PHONY: maintainer-clean
+
+dist: parse.cc lex.cc oct-gperf.h
+	ln $(addprefix $(srcdir)/, $(DISTFILES)) ../`cat ../.fname`/src
+	ln $(BUILT_DISTFILES) ../`cat ../.fname`/src
+	for f in DLD-FUNCTIONS OPERATORS TEMPLATE-INST; do \
+	  if [ -d ../`cat ../.fname`/src/$$f ]; then \
+	    true; \
+	  else \
+	    mkdir ../`cat ../.fname`/src/$$f; \
+	  fi; \
+	done
+	ln $(addprefix $(srcdir)/, $(DLD_SRC)) ../`cat ../.fname`/src/DLD-FUNCTIONS
+	ln $(addprefix $(srcdir)/, $(OP_SRC)) ../`cat ../.fname`/src/OPERATORS
+	ln $(addprefix $(srcdir)/, $(OP_INCLUDES)) ../`cat ../.fname`/src/OPERATORS
+	ln $(addprefix $(srcdir)/, $(TI_SRC)) ../`cat ../.fname`/src/TEMPLATE-INST
+	rm -f parse.cc lex.cc y.tab.h y.output yy.lex.c
+	rm -f oct-gperf.h defaults.h oct-conf.h *.d *.df builtins.cc
+.PHONY: dist
+
+conf-dist:
+	ln $(addprefix $(srcdir)/, octave.cc Makefile.in) ../`cat ../.fname`/src
+.PHONY: conf-dist
+
+# Special rules -- these files need special things to be defined.
+
+$(OPT_HANDLERS) : %.cc : $(top_srcdir)/liboctave/%.in $(top_srcdir)/mk-opts.pl
+	@echo making $@ from $<
+	@$(PERL) $(top_srcdir)/mk-opts.pl --opt-handler-fcns $< > $@-t
+	@mv $@-t $@
+
+## We require Bison.
+parse.cc : parse.y
+	@echo "expect 14 shift/reduce conflicts"
+	$(YACC) $(YFLAGS) --output=$@ --defines=y.tab.h $<
+
+lex.cc : lex.l
+	$(LEX) $(LFLAGS) $< > $(@F)-t
+	@mv $(@F)-t $@
+
+
+$(OPT_INC) : %.h : %.in
+	$(MAKE) -C $(@D) $@
+
+## We want to force an update of defaults.h and oct-conf.h every
+## time make is run because some values may come from the command
+## line or the environment.  The substitution rules use move-if-change,
+## so this should not cause trouble if the file already exists and the
+## newly generated file is not different.
+
+defaults.h: defaults.h.in ../Makeconf Makefile FORCE
+	@$(do-subst-default-vals)
+
+oct-conf.h: oct-conf.h.in ../Makeconf Makefile FORCE
+	@$(do-subst-config-vals)
+
+FORCE:
+.PHONY: FORCE
+
+oct-errno.cc: oct-errno.cc.in ../Makeconf Makefile
+	@echo "making $@ from $<"
+	@if test -n "$(PERL)"; then \
+	  $(srcdir)/mk-errno-list --perl "$(PERL)" < $< > $@-t; \
+	elif test -n "$(PYTHON)"; then \
+	  $(srcdir)/mk-errno-list --python "$(PYTHON)" < $< > $@-t; \
+	else \
+	  $(SED) '/@SYSDEP_ERRNO_LIST@/D' $< > $@-t; \
+	fi
+	@mv $@-t $@
+
+## Don't use a pipeline to process gperf output since if gperf
+## is missing but sed is not, the exit status of the pipeline
+## will still be success and we will end up creating an empty
+## oct-gperf.h file.
+oct-gperf.h: octave.gperf
+	$(GPERF) -t -C -D -G -L C++ -Z octave_kw_hash $< > $@-t1
+	$(SED) 's,lookup\[,gperf_lookup[,' < $@-t1 > $@-t2
+	mv $@-t2 $@
+	rm -f $@-t1
+
+display.o: CPPFLAGS += $(X11_FLAGS)
+
+__magick_read__.d: CPPFLAGS += $(MAGICK_INCFLAGS)
+__magick_read__.df: CPPFLAGS += $(MAGICK_INCFLAGS)
+__magick_read__.o pic/__magick_read__.o: CPPFLAGS += $(MAGICK_INCFLAGS)
+__magick_read__.oct: OCT_LINK_DEPS += $(MAGICK_LIBS)
+
+convhulln.oct: OCT_LINK_DEPS += $(QHULL_LIBS)
+__delaunayn__.oct: OCT_LINK_DEPS += $(QHULL_LIBS)
+__voronoi__.oct: OCT_LINK_DEPS += $(QHULL_LIBS)
+eigs.oct: OCT_LINK_DEPS += $(ARPACK_LIBS)
+qr.oct: OCT_LINK_DEPS += $(QRUPDATE_LIBS)
+chol.oct: OCT_LINK_DEPS += $(QRUPDATE_LIBS)
+regexp.oct: OCT_LINK_DEPS += $(REGEX_LIBS)
+urlwrite.oct: OCT_LINK_DEPS += $(CURL_LIBS)
+__glpk__.oct: OCT_LINK_DEPS += $(GLPK_LIBS)
+fltk_backend.oct: OCT_LINK_DEPS += $(GRAPHICS_LIBS) $(FT2_LIBS)
+
+check: all
+.PHONY: check
+
+ifdef omit_deps
+.PHONY: $(MAKEDEPS)
+endif
+
+-include $(MAKEDEPS)
diff --git a/src/OPERATORS/op-b-b.cc b/src/OPERATORS/op-b-b.cc
new file mode 100644
index 0000000..f6e54cc
--- /dev/null
+++ b/src/OPERATORS/op-b-b.cc
@@ -0,0 +1,102 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// bool unary ops.
+
+// scalar unary ops.
+
+DEFUNOP_OP (not, bool, !)
+
+UNOPDECL (uplus, a)
+{
+  CAST_UNOP_ARG (const octave_bool&);
+  return octave_value (v.double_value ());
+}
+
+UNOPDECL (uminus, a)
+{
+  CAST_UNOP_ARG (const octave_bool&);
+  return octave_value (- v.double_value ());
+}
+
+DEFUNOP_OP (transpose, bool, /* no-op */)
+DEFUNOP_OP (hermitian, bool, /* no-op */)
+
+// bool by bool ops.
+
+DEFBINOP_OP (eq, bool, bool, ==)
+DEFBINOP_OP (ne, bool, bool, !=)
+DEFBINOP_OP (el_and, bool, bool, &&)
+DEFBINOP_OP (el_or, bool, bool, ||)
+
+DEFNDCATOP_FN (b_b, bool, bool, bool_array, bool_array, concat)
+DEFNDCATOP_FN (b_s, bool, scalar, array, array, concat)
+DEFNDCATOP_FN (s_b, scalar, bool, array, array, concat)
+DEFNDCATOP_FN (b_f, bool, float_scalar, float_array, float_array, concat)
+DEFNDCATOP_FN (f_b, float_scalar, bool, float_array, float_array, concat)
+
+void
+install_b_b_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_bool, not);
+  INSTALL_UNOP (op_uplus, octave_bool, uplus);
+  INSTALL_UNOP (op_uminus, octave_bool, uminus);
+  INSTALL_UNOP (op_transpose, octave_bool, transpose);
+  INSTALL_UNOP (op_hermitian, octave_bool, hermitian);
+
+  INSTALL_BINOP (op_eq, octave_bool, octave_bool, eq);
+  INSTALL_BINOP (op_ne, octave_bool, octave_bool, ne);
+  INSTALL_BINOP (op_el_and, octave_bool, octave_bool, el_and);
+  INSTALL_BINOP (op_el_or, octave_bool, octave_bool, el_or);
+
+  INSTALL_CATOP (octave_bool, octave_bool, b_b);
+  INSTALL_CATOP (octave_bool, octave_scalar, b_s);
+  INSTALL_CATOP (octave_scalar, octave_bool, s_b);
+  INSTALL_CATOP (octave_bool, octave_float_scalar, b_f);
+  INSTALL_CATOP (octave_float_scalar, octave_bool, f_b);
+
+  INSTALL_ASSIGNCONV (octave_bool, octave_bool, octave_bool_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-b-bm.cc b/src/OPERATORS/op-b-bm.cc
new file mode 100644
index 0000000..8263410
--- /dev/null
+++ b/src/OPERATORS/op-b-bm.cc
@@ -0,0 +1,86 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// bool matrix by bool ops.
+
+DEFNDBINOP_FN (el_and, bool, bool_matrix, bool, bool_array, mx_el_and)
+DEFNDBINOP_FN (el_or, bool, bool_matrix, bool, bool_array, mx_el_or)
+
+DEFNDBINOP_FN (el_and_not, bool, bool_matrix, bool, bool_array, mx_el_and_not)
+DEFNDBINOP_FN (el_or_not, bool, bool_matrix, bool, bool_array, mx_el_or_not)
+
+DEFNDCATOP_FN (b_bm, bool, bool_matrix, bool_array, bool_array, concat)
+DEFNDCATOP_FN (b_m, bool, matrix, array, array, concat)
+DEFNDCATOP_FN (s_bm, scalar, bool_matrix, array, array, concat)
+
+DEFNDCATOP_FN (b_fm, bool, float_matrix, float_array, float_array, concat)
+DEFNDCATOP_FN (f_bm, float_scalar, bool_matrix, float_array, float_array, concat)
+
+DEFCONV (bool_matrix_conv, bool, bool_matrix)
+{
+  CAST_CONV_ARG (const octave_bool&);
+
+  return new octave_bool_matrix (v.bool_matrix_value ());
+}
+
+void
+install_b_bm_ops (void)
+{
+  INSTALL_BINOP (op_el_and, octave_bool, octave_bool_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_bool, octave_bool_matrix, el_or);
+  INSTALL_BINOP (op_el_and_not, octave_bool, octave_bool_matrix, el_and_not);
+  INSTALL_BINOP (op_el_or_not, octave_bool, octave_bool_matrix, el_or_not);
+
+  INSTALL_CATOP (octave_bool, octave_bool_matrix, b_bm);
+  INSTALL_CATOP (octave_bool, octave_matrix, b_m);
+  INSTALL_CATOP (octave_scalar, octave_bool_matrix, s_bm);
+  INSTALL_CATOP (octave_bool, octave_float_matrix, b_fm);
+  INSTALL_CATOP (octave_float_scalar, octave_bool_matrix, f_bm);
+
+  INSTALL_ASSIGNCONV (octave_bool, octave_bool_matrix, octave_bool_matrix);
+
+  INSTALL_WIDENOP (octave_bool, octave_bool_matrix, bool_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-b-sbm.cc b/src/OPERATORS/op-b-sbm.cc
new file mode 100644
index 0000000..9072c2e
--- /dev/null
+++ b/src/OPERATORS/op-b-sbm.cc
@@ -0,0 +1,101 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ops.h"
+
+#include "ov-re-sparse.h"
+#include "ov-bool-sparse.h"
+
+// bool by sparse bool matrix ops.
+
+DEFBINOP_FN (ne, bool, sparse_bool_matrix, mx_el_ne)
+DEFBINOP_FN (eq, bool, sparse_bool_matrix, mx_el_eq)
+
+DEFBINOP_FN (el_and, bool, sparse_bool_matrix, mx_el_and)
+DEFBINOP_FN (el_or, bool, sparse_bool_matrix, mx_el_or)
+
+DEFCATOP (b_sbm, bool, sparse_bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_bool&, const octave_sparse_bool_matrix&);
+  SparseBoolMatrix tmp (1, 1, v1.bool_value ());
+  return octave_value (tmp. concat (v2.sparse_bool_matrix_value (), 
+				    ra_idx));
+}
+
+DEFCATOP (b_sm, bool, sparse_matrix)
+{
+  CAST_BINOP_ARGS (octave_bool&, const octave_sparse_matrix&);
+  SparseMatrix tmp (1, 1, v1.scalar_value ());
+  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCATOP (s_sbm, scalar, sparse_bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_bool_matrix&);
+  SparseMatrix tmp (1, 1, v1.scalar_value ());
+  return octave_value(tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCONV (sparse_bool_matrix_conv, bool, sparse_bool_matrix)
+{
+  CAST_CONV_ARG (const octave_bool&);
+
+  return new octave_sparse_bool_matrix 
+    (SparseBoolMatrix (1, 1, v.bool_value ()));
+}
+
+void
+install_b_sbm_ops (void)
+{
+  INSTALL_BINOP (op_eq, octave_bool, octave_sparse_bool_matrix, eq);
+  INSTALL_BINOP (op_ne, octave_bool, octave_sparse_bool_matrix, ne);
+
+  INSTALL_BINOP (op_el_and, octave_bool, octave_sparse_bool_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_bool, octave_sparse_bool_matrix, el_or);
+
+  INSTALL_CATOP (octave_bool, octave_sparse_bool_matrix, b_sbm);
+  INSTALL_CATOP (octave_bool, octave_sparse_matrix, b_sm);
+  INSTALL_CATOP (octave_scalar, octave_sparse_bool_matrix, s_sbm);
+
+  INSTALL_ASSIGNCONV (octave_bool, octave_sparse_bool_matrix, 
+		      octave_bool_matrix);
+
+  INSTALL_WIDENOP (octave_bool, octave_sparse_bool_matrix, sparse_bool_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-bm-b.cc b/src/OPERATORS/op-bm-b.cc
new file mode 100644
index 0000000..73fbb36
--- /dev/null
+++ b/src/OPERATORS/op-bm-b.cc
@@ -0,0 +1,117 @@
+/*
+
+Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Cai Jianming
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-str-mat.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// bool matrix by bool ops.
+
+DEFNDBINOP_FN (el_and, bool_matrix, bool, bool_array, bool, mx_el_and)
+DEFNDBINOP_FN (el_or, bool_matrix, bool, bool_array, bool, mx_el_or)
+
+DEFNDBINOP_FN (el_not_and, bool_matrix, bool, bool_array, bool, mx_el_not_and)
+DEFNDBINOP_FN (el_not_or, bool_matrix, bool, bool_array, bool, mx_el_not_or)
+
+DEFNDCATOP_FN (bm_b, bool_matrix, bool, bool_array, bool_array, concat)
+DEFNDCATOP_FN (bm_s, bool_matrix, scalar, array, array, concat)
+DEFNDCATOP_FN (m_b, matrix, bool, array, array, concat)
+DEFNDCATOP_FN (bm_f, bool_matrix, float_scalar, float_array, float_array, concat)
+DEFNDCATOP_FN (fm_b, float_matrix, bool, float_array, float_array, concat)
+
+DEFNDASSIGNOP_FN (assign, bool_matrix, bool, bool_array, assign)
+
+static octave_value
+oct_assignop_conv_and_assign (octave_base_value& a1,
+			      const octave_value_list& idx,
+			      const octave_base_value& a2)
+{
+  octave_bool_matrix& v1 = dynamic_cast<octave_bool_matrix&> (a1);
+
+  // FIXME -- perhaps add a warning for this conversion if the values
+  // are not all 0 or 1?
+
+  boolNDArray v2 = a2.bool_array_value (true);
+
+  if (! error_state)
+    v1.assign (idx, v2);
+
+  return octave_value ();
+}
+
+void
+install_bm_b_ops (void)
+{
+  INSTALL_BINOP (op_el_and, octave_bool_matrix, octave_bool, el_and);
+  INSTALL_BINOP (op_el_or, octave_bool_matrix, octave_bool, el_or);
+  INSTALL_BINOP (op_el_not_and, octave_bool_matrix, octave_bool, el_not_and);
+  INSTALL_BINOP (op_el_not_or, octave_bool_matrix, octave_bool, el_not_or);
+
+  INSTALL_CATOP (octave_bool_matrix, octave_bool, bm_b);
+  INSTALL_CATOP (octave_bool_matrix, octave_scalar, bm_s);
+  INSTALL_CATOP (octave_matrix, octave_bool, m_b);
+  INSTALL_CATOP (octave_bool_matrix, octave_float_scalar, bm_f);
+  INSTALL_CATOP (octave_float_matrix, octave_bool, fm_b);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_bool, assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_scalar, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int8_scalar, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int16_scalar, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int32_scalar, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int64_scalar, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint8_scalar, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint16_scalar, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint32_scalar, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint64_scalar, conv_and_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-bm-bm.cc b/src/OPERATORS/op-bm-bm.cc
new file mode 100644
index 0000000..08d3277
--- /dev/null
+++ b/src/OPERATORS/op-bm-bm.cc
@@ -0,0 +1,182 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ov-range.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-str-mat.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// unary bool matrix ops.
+
+DEFNDUNOP_OP (not, bool_matrix, bool_array, !)
+DEFNDUNOP_OP (uplus, bool_matrix, array, +)
+DEFNDUNOP_OP (uminus, bool_matrix, array, -)
+
+DEFUNOP (transpose, bool_matrix)
+{
+  CAST_UNOP_ARG (const octave_bool_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.bool_matrix_value().transpose ());
+}
+
+// bool matrix by bool matrix ops.
+
+DEFNDBINOP_FN (eq, bool_matrix, bool_matrix, bool_array, bool_array, mx_el_eq)
+DEFNDBINOP_FN (ne, bool_matrix, bool_matrix, bool_array, bool_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_and, bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_and)
+
+DEFNDBINOP_FN (el_or,  bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_or)
+
+DEFNDBINOP_FN (el_not_and, bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_not_and)
+
+DEFNDBINOP_FN (el_not_or,  bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_not_or)
+
+DEFNDBINOP_FN (el_and_not, bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_and_not)
+
+DEFNDBINOP_FN (el_or_not,  bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_or_not)
+
+DEFNDCATOP_FN (bm_bm, bool_matrix, bool_matrix, bool_array, bool_array, concat)
+DEFNDCATOP_FN (bm_m, bool_matrix, matrix, array, array, concat)
+DEFNDCATOP_FN (m_bm, matrix, bool_matrix, array, array, concat)
+DEFNDCATOP_FN (bm_fm, bool_matrix, float_matrix, float_array, float_array, concat)
+DEFNDCATOP_FN (fm_bm, float_matrix, bool_matrix, float_array, float_array, concat)
+
+DEFNDASSIGNOP_FN (assign, bool_matrix, bool_matrix, bool_array, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, bool_matrix, delete_elements)
+
+static octave_value
+oct_assignop_conv_and_assign (octave_base_value& a1,
+			      const octave_value_list& idx,
+			      const octave_base_value& a2)
+{
+  octave_bool_matrix& v1 = dynamic_cast<octave_bool_matrix&> (a1);
+
+  // FIXME -- perhaps add a warning for this conversion if the values
+  // are not all 0 or 1?
+
+  boolNDArray v2 = a2.bool_array_value (true);
+
+  if (! error_state)
+    v1.assign (idx, v2);
+
+  return octave_value ();
+}
+
+DEFCONVFN (matrix_to_bool_matrix, matrix, bool)
+DEFCONVFN (scalar_to_bool_matrix, scalar, bool)
+
+void
+install_bm_bm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_bool_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_bool_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_bool_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_bool_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_bool_matrix, transpose);
+
+  INSTALL_BINOP (op_eq, octave_bool_matrix, octave_bool_matrix, eq);
+  INSTALL_BINOP (op_ne, octave_bool_matrix, octave_bool_matrix, ne);
+
+  INSTALL_BINOP (op_el_and, octave_bool_matrix, octave_bool_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_bool_matrix, octave_bool_matrix, el_or);
+  INSTALL_BINOP (op_el_not_and, octave_bool_matrix, octave_bool_matrix, el_not_and);
+  INSTALL_BINOP (op_el_not_or, octave_bool_matrix, octave_bool_matrix, el_not_or);
+  INSTALL_BINOP (op_el_and_not, octave_bool_matrix, octave_bool_matrix, el_and_not);
+  INSTALL_BINOP (op_el_or_not, octave_bool_matrix, octave_bool_matrix, el_or_not);
+
+  INSTALL_CATOP (octave_bool_matrix, octave_bool_matrix, bm_bm);
+  INSTALL_CATOP (octave_bool_matrix, octave_matrix, bm_m);
+  INSTALL_CATOP (octave_matrix, octave_bool_matrix, m_bm);
+  INSTALL_CATOP (octave_bool_matrix, octave_float_matrix, bm_fm);
+  INSTALL_CATOP (octave_float_matrix, octave_bool_matrix, fm_bm);
+
+  INSTALL_CONVOP (octave_matrix, octave_bool_matrix, matrix_to_bool_matrix);
+  INSTALL_CONVOP (octave_scalar, octave_bool_matrix, scalar_to_bool_matrix);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_bool_matrix, assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_char_matrix_str, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_char_matrix_sq_str, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_range, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_sparse_matrix, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int8_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int16_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int32_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_int64_matrix, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint8_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint16_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint32_matrix, conv_and_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_uint64_matrix, conv_and_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_null_sq_str, null_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-bm-sbm.cc b/src/OPERATORS/op-bm-sbm.cc
new file mode 100644
index 0000000..8e4611a
--- /dev/null
+++ b/src/OPERATORS/op-bm-sbm.cc
@@ -0,0 +1,109 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-bool-mat.h"
+#include "boolMatrix.h"
+#include "ov-scalar.h"
+#include "ops.h"
+
+#include "ov-re-sparse.h"
+#include "ov-bool-sparse.h"
+#include "smx-bm-sbm.h"
+#include "smx-sbm-bm.h"
+
+// bool matrix by sparse bool matrix ops.
+
+DEFBINOP_FN (eq, bool_matrix, sparse_bool_matrix, mx_el_eq)
+DEFBINOP_FN (ne, bool_matrix, sparse_bool_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_and, bool_matrix, sparse_bool_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  bool_matrix, sparse_bool_matrix, mx_el_or)
+
+DEFCATOP (bm_sbm, bool_matrix, sparse_bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_bool_matrix&, const octave_sparse_bool_matrix&);
+  SparseBoolMatrix tmp (v1.bool_matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_bool_matrix_value (), 
+				    ra_idx));
+}
+
+DEFCATOP (m_sbm, matrix, sparse_bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_matrix&, const octave_sparse_bool_matrix&);
+  SparseMatrix tmp (v1.matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCATOP (bm_sm, bool_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (octave_bool_matrix&, const octave_sparse_matrix&); 
+  SparseMatrix tmp (v1.matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCONV (sparse_bool_matrix_conv, bool_matrix, sparse_bool_matrix)
+{
+  CAST_CONV_ARG (const octave_bool_matrix&);
+  return new octave_sparse_bool_matrix 
+    (SparseBoolMatrix (v.bool_matrix_value ()));
+}
+
+DEFNDASSIGNOP_FN (assign, bool_matrix, sparse_bool_matrix, bool_array, assign)
+
+void
+install_bm_sbm_ops (void)
+{
+  INSTALL_BINOP (op_eq, octave_bool_matrix, octave_sparse_bool_matrix, eq);
+  INSTALL_BINOP (op_ne, octave_bool_matrix, octave_sparse_bool_matrix, ne);
+
+  INSTALL_BINOP (op_el_and, octave_bool_matrix, octave_sparse_bool_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_bool_matrix, octave_sparse_bool_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_bool_matrix, octave_sparse_bool_matrix, bm_sbm);
+  INSTALL_CATOP (octave_bool_matrix, octave_sparse_matrix, bm_sm);
+  INSTALL_CATOP (octave_matrix, octave_sparse_bool_matrix, m_sbm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_sparse_bool_matrix, 
+		    assign)
+  INSTALL_ASSIGNCONV (octave_bool_matrix, octave_sparse_bool_matrix, 
+		      octave_bool_matrix);
+
+  INSTALL_WIDENOP (octave_bool_matrix, octave_sparse_bool_matrix, 
+		   sparse_bool_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cdm-cdm.cc b/src/OPERATORS/op-cdm-cdm.cc
new file mode 100644
index 0000000..1349d56
--- /dev/null
+++ b/src/OPERATORS/op-cdm-cdm.cc
@@ -0,0 +1,110 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-cx-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix unary ops.
+
+DEFUNOP_OP (uplus, complex_diag_matrix, /* no-op */)
+DEFUNOP_OP (uminus, complex_diag_matrix, -)
+
+DEFUNOP (transpose, complex_diag_matrix)
+{
+  CAST_UNOP_ARG (const octave_complex_diag_matrix&);
+  return octave_value (v.complex_diag_matrix_value().transpose ());
+}
+
+DEFUNOP (hermitian, complex_diag_matrix)
+{
+  CAST_UNOP_ARG (const octave_complex_diag_matrix&);
+  return octave_value (v.complex_diag_matrix_value().hermitian ());
+}
+
+// matrix by matrix ops.
+
+DEFBINOP_OP (add, complex_diag_matrix, complex_diag_matrix, +)
+DEFBINOP_OP (sub, complex_diag_matrix, complex_diag_matrix, -)
+DEFBINOP_OP (mul, complex_diag_matrix, complex_diag_matrix, *)
+
+DEFBINOP (div, complex_diag_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_complex_diag_matrix&);
+  
+  return xdiv (v1.complex_diag_matrix_value (), 
+               v2.complex_diag_matrix_value ());
+}
+
+DEFBINOP (ldiv, complex_diag_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_complex_diag_matrix&);
+  
+  return xleftdiv (v1.complex_diag_matrix_value (),
+                   v2.complex_diag_matrix_value ());
+}
+
+CONVDECL (complex_diag_matrix_to_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+
+  return new octave_complex_matrix (v.complex_matrix_value ());
+}
+
+CONVDECL (complex_diag_matrix_to_float_complex_diag_matrix)
+{
+  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+
+  return new octave_float_complex_diag_matrix (v.float_complex_diag_matrix_value ());
+}
+
+void
+install_cdm_cdm_ops (void)
+{
+  INSTALL_UNOP (op_uplus, octave_complex_diag_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_complex_diag_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_complex_diag_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_complex_diag_matrix, hermitian);
+
+  INSTALL_BINOP (op_add, octave_complex_diag_matrix, octave_complex_diag_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex_diag_matrix, octave_complex_diag_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex_diag_matrix, octave_complex_diag_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex_diag_matrix, octave_complex_diag_matrix, div);
+  INSTALL_BINOP (op_ldiv, octave_complex_diag_matrix, octave_complex_diag_matrix, ldiv);
+
+  INSTALL_CONVOP (octave_complex_diag_matrix, octave_complex_matrix, complex_diag_matrix_to_complex_matrix);
+  INSTALL_CONVOP (octave_complex_diag_matrix, octave_float_complex_diag_matrix, 
+                  complex_diag_matrix_to_float_complex_diag_matrix);
+  INSTALL_ASSIGNCONV (octave_complex_diag_matrix, octave_complex_matrix, octave_complex_matrix);
+  INSTALL_WIDENOP (octave_complex_diag_matrix, octave_complex_matrix, complex_diag_matrix_to_complex_matrix);
+}
diff --git a/src/OPERATORS/op-cdm-cm.cc b/src/OPERATORS/op-cdm-cm.cc
new file mode 100644
index 0000000..20f5ad2
--- /dev/null
+++ b/src/OPERATORS/op-cdm-cm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-cx-diag.h"
+#define RINCLUDE "ov-cx-mat.h"
+
+#define LMATRIX complex_diag_matrix
+#define RMATRIX complex_matrix
+
+#define LSHORT cdm
+#define RSHORT cm
+
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-cdm-cs.cc b/src/OPERATORS/op-cdm-cs.cc
new file mode 100644
index 0000000..0e1ccbf
--- /dev/null
+++ b/src/OPERATORS/op-cdm-cs.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-complex.h"
+#define MINCLUDE "ov-cx-diag.h"
+
+#define SCALAR complex
+#define MATRIX complex_diag_matrix
+
+#define SSHORT cs
+#define MSHORT cdm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-cdm-dm.cc b/src/OPERATORS/op-cdm-dm.cc
new file mode 100644
index 0000000..9a3c640
--- /dev/null
+++ b/src/OPERATORS/op-cdm-dm.cc
@@ -0,0 +1,37 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-cx-diag.h"
+#define RINCLUDE "ov-re-diag.h"
+
+#define LMATRIX complex_diag_matrix
+#define RMATRIX diag_matrix
+#define RDMATRIX LMATRIX
+
+#define LSHORT cdm
+#define RSHORT dm
+
+#define DEFINEDIV
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-cdm-m.cc b/src/OPERATORS/op-cdm-m.cc
new file mode 100644
index 0000000..dd9aa37
--- /dev/null
+++ b/src/OPERATORS/op-cdm-m.cc
@@ -0,0 +1,38 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-cx-diag.h"
+#define RINCLUDE "ov-re-mat.h"
+
+#define LMATRIX complex_diag_matrix
+#define LDMATRIX complex_matrix
+#define RMATRIX matrix
+#define RDMATRIX complex_matrix
+
+#define LSHORT cdm
+#define RSHORT m
+
+#define DEFINELDIV
+#define DEFINENULLASSIGNCONV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-cdm-s.cc b/src/OPERATORS/op-cdm-s.cc
new file mode 100644
index 0000000..b7dd5d6
--- /dev/null
+++ b/src/OPERATORS/op-cdm-s.cc
@@ -0,0 +1,34 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-scalar.h"
+#define MINCLUDE "ov-cx-diag.h"
+
+#define SCALAR scalar
+#define SCALARV complex
+#define MATRIX complex_diag_matrix
+
+#define SSHORT s
+#define MSHORT cdm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-cell.cc b/src/OPERATORS/op-cell.cc
new file mode 100644
index 0000000..2d879f5
--- /dev/null
+++ b/src/OPERATORS/op-cell.cc
@@ -0,0 +1,110 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cell.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+
+// cell ops.
+
+DEFUNOP (transpose, cell)
+{
+  CAST_UNOP_ARG (const octave_cell&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (Cell (v.cell_value().transpose ()));
+}
+
+DEFCATOP_FN (c_c, cell, cell, concat)
+
+static octave_value
+oct_catop_cell_matrix (octave_base_value& a1, const octave_base_value& a2,
+			 const Array<octave_idx_type>&)
+{
+  octave_value retval;
+  CAST_BINOP_ARGS (const octave_cell&, const octave_matrix&);
+  NDArray tmp = v2.array_value ();
+  dim_vector dv = tmp.dims ();
+  if (dv.all_zero ())
+    retval = octave_value (v1.cell_value ());
+  else
+    error ("invalid concatenation of cell array with matrix");
+  return retval;
+}
+
+static octave_value
+oct_catop_matrix_cell (octave_base_value& a1, const octave_base_value& a2,
+			 const Array<octave_idx_type>&)
+{
+  octave_value retval;
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_cell&);
+  NDArray tmp = v1.array_value ();
+  dim_vector dv = tmp.dims ();
+  if (dv.all_zero ())
+    retval = octave_value (v2.cell_value ());
+  else
+    error ("invalid concatenation of cell array with matrix");
+  return retval;
+}
+
+DEFASSIGNANYOP_FN (assign, cell, assign);
+
+DEFNULLASSIGNOP_FN (null_assign, cell, delete_elements)
+
+void
+install_cell_ops (void)
+{
+  INSTALL_UNOP (op_transpose, octave_cell, transpose);
+  INSTALL_UNOP (op_hermitian, octave_cell, transpose);
+
+  INSTALL_CATOP (octave_cell, octave_cell, c_c);
+
+  INSTALL_CATOP (octave_cell, octave_matrix, cell_matrix);
+  INSTALL_CATOP (octave_matrix, octave_cell, matrix_cell);
+
+  INSTALL_ASSIGNANYOP (op_asn_eq, octave_cell, assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_cell, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_cell, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_cell, octave_null_sq_str, null_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-chm.cc b/src/OPERATORS/op-chm.cc
new file mode 100644
index 0000000..9fff616
--- /dev/null
+++ b/src/OPERATORS/op-chm.cc
@@ -0,0 +1,112 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-ch-mat.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+// char matrix unary ops.
+
+DEFUNOP (transpose, char_matrix)
+{
+  CAST_UNOP_ARG (const octave_char_matrix&);
+
+  return octave_value (v.matrix_value().transpose ());
+}
+
+DEFNDCATOP_FN (chm_chm, char_matrix, char_matrix, char_array, char_array, 
+	       concat)
+
+DEFCATOP (chm_s, char_matrix, scalar)
+{
+  CAST_BINOP_ARGS (octave_char_matrix&, const octave_scalar&);
+
+  gripe_implicit_conversion ("Octave:num-to-str",
+			     v2.type_name (), v1.type_name ());
+
+  return octave_value (v1.char_array_value (). concat(v2.array_value (),
+			       ra_idx));
+}
+
+DEFCATOP (chm_m, char_matrix, matrix)
+{
+  CAST_BINOP_ARGS (octave_char_matrix&, const octave_matrix&);
+
+  gripe_implicit_conversion ("Octave:num-to-str",
+			     v2.type_name (), v1.type_name ());
+
+  return octave_value (v1.char_array_value (). concat (v2.array_value (),
+			       ra_idx));
+}
+
+DEFCATOP (s_chm, scalar, char_matrix)
+{
+  CAST_BINOP_ARGS (octave_scalar&, const octave_char_matrix&);
+
+  gripe_implicit_conversion ("Octave:num-to-str",
+			     v1.type_name (), v2.type_name ());
+
+  return octave_value (v1.array_value (). concat (v2.char_array_value (),
+			       ra_idx));
+}
+
+DEFCATOP (m_chm, matrix, char_matrix)
+{
+  CAST_BINOP_ARGS (octave_matrix&, const octave_char_matrix&);
+
+  gripe_implicit_conversion ("Octave:num-to-str",
+			     v1.type_name (), v2.type_name ());
+
+  return octave_value (v1.array_value (). concat (v2.char_array_value (),
+			       ra_idx));
+}
+
+void
+install_chm_ops (void)
+{
+  INSTALL_UNOP (op_transpose, octave_char_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_char_matrix, transpose);
+
+  INSTALL_CATOP (octave_char_matrix, octave_char_matrix, chm_chm);
+  INSTALL_CATOP (octave_char_matrix, octave_scalar, chm_s);
+  INSTALL_CATOP (octave_char_matrix, octave_matrix, chm_m);
+  INSTALL_CATOP (octave_scalar, octave_char_matrix, s_chm);
+  INSTALL_CATOP (octave_matrix, octave_char_matrix, m_chm);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-class.cc b/src/OPERATORS/op-class.cc
new file mode 100644
index 0000000..5747fc2
--- /dev/null
+++ b/src/OPERATORS/op-class.cc
@@ -0,0 +1,167 @@
+/*
+
+Copyright (C) 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-time.h"
+
+#include "gripes.h"
+#include "load-path.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-class.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "symtab.h"
+#include "parse.h"
+
+// class ops.
+
+#define DEF_CLASS_UNOP(name) \
+  static octave_value \
+  oct_unop_ ## name (const octave_value& a) \
+  { \
+    octave_value retval; \
+ \
+    std::string class_name = a.class_name (); \
+ \
+    octave_value meth = symbol_table::find_method (#name, class_name); \
+ \
+    if (meth.is_defined ()) \
+      { \
+	octave_value_list args; \
+ \
+	args(0) = a; \
+ \
+	octave_value_list tmp = feval (meth.function_value (), args, 1); \
+ \
+	if (tmp.length () > 0) \
+	  retval = tmp(0); \
+      } \
+    else \
+      error ("%s method not defined for %s class", \
+             #name, class_name.c_str ()); \
+ \
+    return retval; \
+  }
+
+DEF_CLASS_UNOP (not)
+DEF_CLASS_UNOP (uplus)
+DEF_CLASS_UNOP (uminus)
+DEF_CLASS_UNOP (transpose)
+DEF_CLASS_UNOP (ctranspose)
+
+// FIXME -- we need to handle precedence in the binop function.
+
+#define DEF_CLASS_BINOP(name) \
+  static octave_value \
+  oct_binop_ ## name (const octave_value& a1, const octave_value& a2) \
+  { \
+    octave_value retval; \
+ \
+    std::string dispatch_type \
+      = a1.is_object () ? a1.class_name () : a2.class_name (); \
+ \
+    octave_value meth = symbol_table::find_method (#name, dispatch_type); \
+ \
+    if (meth.is_defined ()) \
+      { \
+	octave_value_list args; \
+ \
+	args(1) = a2; \
+	args(0) = a1; \
+ \
+	octave_value_list tmp = feval (meth.function_value (), args, 1); \
+ \
+	if (tmp.length () > 0) \
+	  retval = tmp(0); \
+      } \
+    else \
+      error ("%s method not defined for %s class", \
+             #name, dispatch_type.c_str ()); \
+ \
+    return retval; \
+  }
+
+DEF_CLASS_BINOP (plus)
+DEF_CLASS_BINOP (minus)
+DEF_CLASS_BINOP (mtimes)
+DEF_CLASS_BINOP (mrdivide)
+DEF_CLASS_BINOP (mpower)
+DEF_CLASS_BINOP (mldivide)
+DEF_CLASS_BINOP (lt)
+DEF_CLASS_BINOP (le)
+DEF_CLASS_BINOP (eq)
+DEF_CLASS_BINOP (ge)
+DEF_CLASS_BINOP (gt)
+DEF_CLASS_BINOP (ne)
+DEF_CLASS_BINOP (times)
+DEF_CLASS_BINOP (rdivide)
+DEF_CLASS_BINOP (power)
+DEF_CLASS_BINOP (ldivide)
+DEF_CLASS_BINOP (and)
+DEF_CLASS_BINOP (or)
+
+#define INSTALL_CLASS_UNOP(op, f) \
+  octave_value_typeinfo::register_unary_class_op \
+    (octave_value::op, oct_unop_ ## f)
+
+#define INSTALL_CLASS_BINOP(op, f) \
+  octave_value_typeinfo::register_binary_class_op \
+    (octave_value::op, oct_binop_ ## f)
+
+void
+install_class_ops (void)
+{
+  INSTALL_CLASS_UNOP (op_not, not);
+  INSTALL_CLASS_UNOP (op_uplus, uplus);
+  INSTALL_CLASS_UNOP (op_uminus, uminus);
+  INSTALL_CLASS_UNOP (op_transpose, transpose);
+  INSTALL_CLASS_UNOP (op_hermitian, ctranspose);
+
+  INSTALL_CLASS_BINOP (op_add, plus);
+  INSTALL_CLASS_BINOP (op_sub, minus);
+  INSTALL_CLASS_BINOP (op_mul, mtimes);
+  INSTALL_CLASS_BINOP (op_div, mrdivide);
+  INSTALL_CLASS_BINOP (op_pow, mpower);
+  INSTALL_CLASS_BINOP (op_ldiv, mldivide);
+  INSTALL_CLASS_BINOP (op_lt, lt);
+  INSTALL_CLASS_BINOP (op_le, le);
+  INSTALL_CLASS_BINOP (op_eq, eq);
+  INSTALL_CLASS_BINOP (op_ge, ge);
+  INSTALL_CLASS_BINOP (op_gt, gt);
+  INSTALL_CLASS_BINOP (op_ne, ne);
+  INSTALL_CLASS_BINOP (op_el_mul, times);
+  INSTALL_CLASS_BINOP (op_el_div, rdivide);
+  INSTALL_CLASS_BINOP (op_el_pow, power);
+  INSTALL_CLASS_BINOP (op_el_ldiv, ldivide);
+  INSTALL_CLASS_BINOP (op_el_and, and);
+  INSTALL_CLASS_BINOP (op_el_or, or);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cm-cdm.cc b/src/OPERATORS/op-cm-cdm.cc
new file mode 100644
index 0000000..dfb0fa2
--- /dev/null
+++ b/src/OPERATORS/op-cm-cdm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-cx-mat.h"
+#define RINCLUDE "ov-cx-diag.h"
+
+#define LMATRIX complex_matrix
+#define RMATRIX complex_diag_matrix
+
+#define LSHORT cm
+#define RSHORT cdm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-cm-cm.cc b/src/OPERATORS/op-cm-cm.cc
new file mode 100644
index 0000000..84846e6
--- /dev/null
+++ b/src/OPERATORS/op-cm-cm.cc
@@ -0,0 +1,224 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// unary complex matrix ops.
+
+DEFNDUNOP_OP (not, complex_matrix, complex_array, !)
+DEFNDUNOP_OP (uplus, complex_matrix, complex_array, /* no-op */)
+DEFNDUNOP_OP (uminus, complex_matrix, complex_array, -)
+
+DEFUNOP (transpose, complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_complex_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.complex_matrix_value().transpose ());
+}
+
+DEFUNOP (hermitian, complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_complex_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("complex-conjugate transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.complex_matrix_value().hermitian ());
+}
+
+DEFNCUNOP_METHOD (incr, complex_matrix, increment)
+DEFNCUNOP_METHOD (decr, complex_matrix, decrement)
+
+// complex matrix by complex matrix ops.
+
+DEFNDBINOP_OP (add, complex_matrix, complex_matrix, complex_array, complex_array, +)
+DEFNDBINOP_OP (sub, complex_matrix, complex_matrix, complex_array, complex_array, -)
+
+DEFBINOP_OP (mul, complex_matrix, complex_matrix, *)
+
+DEFBINOP (div, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+			    v2.complex_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, complex_matrix, complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (), 
+				v2.complex_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP (trans_mul, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  return octave_value(xgemm (true, false, v1.complex_matrix_value (), 
+                             false, false, v2.complex_matrix_value ()));
+}
+
+DEFBINOP (mul_trans, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  return octave_value(xgemm (false, false, v1.complex_matrix_value (), 
+                             true, false, v2.complex_matrix_value ()));
+}
+
+DEFBINOP (herm_mul, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  return octave_value(xgemm (true, true, v1.complex_matrix_value (), 
+                             false, false, v2.complex_matrix_value ()));
+}
+
+DEFBINOP (mul_herm, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  return octave_value(xgemm (false, false, v1.complex_matrix_value (), 
+                             true, true, v2.complex_matrix_value ()));
+}
+
+DEFNDBINOP_FN (lt, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, complex_matrix, complex_matrix, complex_array, complex_array, product)
+DEFNDBINOP_FN (el_div, complex_matrix, complex_matrix, complex_array, complex_array, quotient)
+DEFNDBINOP_FN (el_pow, complex_matrix, complex_matrix, complex_array, complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+
+  return octave_value (quotient (v2.complex_array_value (), v1.complex_array_value ()));
+}
+
+DEFNDBINOP_FN (el_and, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, complex_matrix, complex_array, complex_array, mx_el_or)
+
+DEFNDCATOP_FN (cm_cm, complex_matrix, complex_matrix, complex_array, complex_array, concat)
+
+DEFNDASSIGNOP_FN (assign, complex_matrix, complex_matrix, complex_array, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, complex_matrix, delete_elements)
+
+CONVDECL (complex_matrix_to_float_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_complex_matrix&);
+
+  return new octave_float_complex_matrix (FloatComplexNDArray (v.complex_array_value ()));
+}
+
+void
+install_cm_cm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_complex_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_complex_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_complex_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_complex_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_complex_matrix, hermitian);
+
+  INSTALL_NCUNOP (op_incr, octave_complex_matrix, incr);
+  INSTALL_NCUNOP (op_decr, octave_complex_matrix, decr);
+
+  INSTALL_BINOP (op_add, octave_complex_matrix, octave_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex_matrix, octave_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex_matrix, octave_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex_matrix, octave_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex_matrix, octave_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex_matrix, octave_complex_matrix, ldiv);
+  INSTALL_BINOP (op_trans_mul, octave_complex_matrix, octave_complex_matrix, trans_mul);
+  INSTALL_BINOP (op_mul_trans, octave_complex_matrix, octave_complex_matrix, mul_trans);
+  INSTALL_BINOP (op_herm_mul, octave_complex_matrix, octave_complex_matrix, herm_mul);
+  INSTALL_BINOP (op_mul_herm, octave_complex_matrix, octave_complex_matrix, mul_herm);
+  INSTALL_BINOP (op_lt, octave_complex_matrix, octave_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex_matrix, octave_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex_matrix, octave_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex_matrix, octave_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex_matrix, octave_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex_matrix, octave_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex_matrix, octave_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex_matrix, octave_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex_matrix, octave_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex_matrix, octave_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_complex_matrix, octave_complex_matrix, cm_cm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_complex_matrix, assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_null_sq_str, null_assign);
+
+  INSTALL_CONVOP (octave_complex_matrix, octave_float_complex_matrix, 
+		  complex_matrix_to_float_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cm-cs.cc b/src/OPERATORS/op-cm-cs.cc
new file mode 100644
index 0000000..5b9e481
--- /dev/null
+++ b/src/OPERATORS/op-cm-cs.cc
@@ -0,0 +1,142 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-complex.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex matrix by complex scalar ops.
+
+DEFNDBINOP_OP (add, complex_matrix, complex, complex_array, complex, +)
+DEFNDBINOP_OP (sub, complex_matrix, complex, complex_array, complex, -)
+DEFNDBINOP_OP (mul, complex_matrix, complex, complex_array, complex, *)
+
+DEFBINOP (div, complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_array_value () / d);
+}
+
+DEFBINOP_FN (pow, complex_matrix, complex, xpow)
+
+DEFBINOP (ldiv, complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+
+  ComplexMatrix m1 = v1.complex_matrix_value ();
+  ComplexMatrix m2 = v2.complex_matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  ComplexMatrix ret = xleftdiv (m1, m2, typ);
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, complex_matrix, complex, complex_array, complex, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, complex, complex_array, complex, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, complex, complex_array, complex, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, complex, complex_array, complex, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, complex, complex_array, complex, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, complex, complex_array, complex, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, complex_matrix, complex, complex_array, complex, *)
+
+DEFBINOP (el_div, complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, complex_matrix, complex, complex_array, complex, elem_xpow)
+
+DEFBINOP (el_ldiv, complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+
+  return x_el_div (v2.complex_value (), v1.complex_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, complex_matrix, complex, complex_array, complex, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, complex, complex_array, complex, mx_el_or)
+
+DEFNDCATOP_FN (cm_cs, complex_matrix, complex, complex_array, complex_array, concat)
+
+DEFNDASSIGNOP_FN (assign, complex_matrix, complex, complex, assign)
+DEFNDASSIGNOP_FN (sgl_assign, float_complex_matrix, complex, float_complex, assign)
+
+void
+install_cm_cs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex_matrix, octave_complex, add);
+  INSTALL_BINOP (op_sub, octave_complex_matrix, octave_complex, sub);
+  INSTALL_BINOP (op_mul, octave_complex_matrix, octave_complex, mul);
+  INSTALL_BINOP (op_div, octave_complex_matrix, octave_complex, div);
+  INSTALL_BINOP (op_pow, octave_complex_matrix, octave_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex_matrix, octave_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex_matrix, octave_complex, lt);
+  INSTALL_BINOP (op_le, octave_complex_matrix, octave_complex, le);
+  INSTALL_BINOP (op_eq, octave_complex_matrix, octave_complex, eq);
+  INSTALL_BINOP (op_ge, octave_complex_matrix, octave_complex, ge);
+  INSTALL_BINOP (op_gt, octave_complex_matrix, octave_complex, gt);
+  INSTALL_BINOP (op_ne, octave_complex_matrix, octave_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex_matrix, octave_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex_matrix, octave_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex_matrix, octave_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex_matrix, octave_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_complex, el_or);
+
+  INSTALL_CATOP (octave_complex_matrix, octave_complex, cm_cs);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_complex, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, octave_complex, sgl_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cm-dm.cc b/src/OPERATORS/op-cm-dm.cc
new file mode 100644
index 0000000..0da2994
--- /dev/null
+++ b/src/OPERATORS/op-cm-dm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-cx-mat.h"
+#define RINCLUDE "ov-re-diag.h"
+
+#define LMATRIX complex_matrix
+#define RMATRIX diag_matrix
+
+#define LSHORT cm
+#define RSHORT dm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-cm-m.cc b/src/OPERATORS/op-cm-m.cc
new file mode 100644
index 0000000..64be593
--- /dev/null
+++ b/src/OPERATORS/op-cm-m.cc
@@ -0,0 +1,137 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-cm-m.h"
+#include "mx-m-cm.h"
+#include "mx-cnda-nda.h"
+#include "mx-nda-cnda.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex matrix by matrix ops.
+
+DEFNDBINOP_OP (add, complex_matrix, matrix, complex_array, array, +)
+DEFNDBINOP_OP (sub, complex_matrix, matrix, complex_array, array, -)
+
+DEFBINOP_OP (mul, complex_matrix, matrix, *)
+
+DEFBINOP (div, complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+			    v2.matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+
+DEFBINOPX (pow, complex_matrix, matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (), 
+				v2.matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, complex_matrix, matrix, complex_array, array, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, matrix, complex_array, array, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, matrix, complex_array, array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, matrix, complex_array, array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, matrix, complex_array, array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, matrix, complex_array, array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, complex_matrix, matrix, complex_array, array, product)
+DEFNDBINOP_FN (el_div, complex_matrix, matrix, complex_array, array, quotient)
+DEFNDBINOP_FN (el_pow, complex_matrix, matrix, complex_array, array, elem_xpow)
+
+DEFBINOP (el_ldiv, complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+
+  return quotient (v2.array_value (), v1.complex_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, complex_matrix, matrix, complex_array, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, matrix, complex_array, array, mx_el_or)
+
+DEFNDCATOP_FN (cm_m, complex_matrix, matrix, complex_array, array, concat)
+
+DEFNDASSIGNOP_FN (assign, complex_matrix, matrix, complex_array, assign)
+
+void
+install_cm_m_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex_matrix, octave_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex_matrix, octave_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex_matrix, octave_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex_matrix, octave_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex_matrix, octave_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex_matrix, octave_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex_matrix, octave_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex_matrix, octave_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex_matrix, octave_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex_matrix, octave_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex_matrix, octave_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex_matrix, octave_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex_matrix, octave_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex_matrix, octave_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex_matrix, octave_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex_matrix, octave_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_matrix, el_or);
+
+  INSTALL_CATOP (octave_complex_matrix, octave_matrix, cm_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_matrix, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cm-pm.cc b/src/OPERATORS/op-cm-pm.cc
new file mode 100644
index 0000000..e1cbe2d
--- /dev/null
+++ b/src/OPERATORS/op-cm-pm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-cx-mat.h"
+
+#define LMATRIX complex_matrix
+#define RMATRIX perm_matrix
+
+#define LSHORT cm
+#define RSHORT pm
+
+#define RIGHT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-cm-s.cc b/src/OPERATORS/op-cm-s.cc
new file mode 100644
index 0000000..b0333d2
--- /dev/null
+++ b/src/OPERATORS/op-cm-s.cc
@@ -0,0 +1,144 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-cm-s.h"
+#include "mx-cnda-s.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex matrix by scalar ops.
+
+DEFNDBINOP_OP (add, complex_matrix, scalar, complex_array, scalar, +)
+DEFNDBINOP_OP (sub, complex_matrix, scalar, complex_array, scalar, -)
+DEFNDBINOP_OP (mul, complex_matrix, scalar, complex_array, scalar, *)
+
+DEFBINOP (div, complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_array_value () / d);
+}
+
+DEFBINOP_FN (pow, complex_matrix, scalar, xpow)
+
+DEFBINOP (ldiv, complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+
+  ComplexMatrix m1 = v1.complex_matrix_value ();
+  Matrix m2 = v2.matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  ComplexMatrix ret = xleftdiv (m1, m2, typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, complex_matrix, scalar, complex_array, scalar, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, scalar, complex_array, scalar, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, scalar, complex_array, scalar, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, scalar, complex_array, scalar, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, scalar, complex_array, scalar, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, scalar, complex_array, scalar, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, complex_matrix, scalar, complex_array, scalar, *)
+
+DEFBINOP (el_div, complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, complex_matrix, scalar, complex_array, scalar, elem_xpow)
+
+DEFBINOP (el_ldiv, complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+
+  return x_el_div (v2.double_value (), v1.complex_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, complex_matrix, scalar, complex_array, scalar, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, scalar, complex_array, scalar, mx_el_or)
+
+DEFNDCATOP_FN (cm_s, complex_matrix, scalar, complex_array, array, concat)
+
+DEFNDASSIGNOP_FN (assign, complex_matrix, scalar, complex_array, assign)
+
+void
+install_cm_s_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex_matrix, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_complex_matrix, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_complex_matrix, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_complex_matrix, octave_scalar, div);
+  INSTALL_BINOP (op_pow, octave_complex_matrix, octave_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex_matrix, octave_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex_matrix, octave_scalar, lt);
+  INSTALL_BINOP (op_le, octave_complex_matrix, octave_scalar, le);
+  INSTALL_BINOP (op_eq, octave_complex_matrix, octave_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_complex_matrix, octave_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_complex_matrix, octave_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_complex_matrix, octave_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex_matrix, octave_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex_matrix, octave_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex_matrix, octave_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex_matrix, octave_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_scalar, el_or);
+
+  INSTALL_CATOP (octave_complex_matrix, octave_scalar, cm_s);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_scalar, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cm-scm.cc b/src/OPERATORS/op-cm-scm.cc
new file mode 100644
index 0000000..25e43d8
--- /dev/null
+++ b/src/OPERATORS/op-cm-scm.cc
@@ -0,0 +1,209 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-scm-cm.h"
+#include "smx-cm-scm.h"
+#include "ov-cx-sparse.h"
+
+// complex matrix by sparse complex matrix ops.
+
+DEFBINOP_OP (add, complex_matrix, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, complex_matrix, sparse_complex_matrix, -)
+
+DEFBINOP_OP (mul, complex_matrix, sparse_complex_matrix, *)
+
+DEFBINOP (div, complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&,
+		   const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+
+      ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+				v2.sparse_complex_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, complex_matrix, sparse_complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (), 
+				v2.complex_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (mul_trans, complex_matrix, sparse_complex_matrix, mul_trans);
+DEFBINOP_FN (mul_herm, complex_matrix, sparse_complex_matrix, mul_herm);
+
+DEFBINOP_FN (lt, complex_matrix, sparse_complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, complex_matrix, sparse_complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, complex_matrix, sparse_complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, complex_matrix, sparse_complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, complex_matrix, sparse_complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, complex_matrix, sparse_complex_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, complex_matrix, sparse_complex_matrix, product)
+DEFBINOP_FN (el_div, complex_matrix, sparse_complex_matrix, quotient)
+
+DEFBINOP (el_pow, complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+  
+  return octave_value 
+    (elem_xpow (SparseComplexMatrix (v1.complex_matrix_value ()),
+		v2.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+
+  return octave_value (quotient (v2.sparse_complex_matrix_value (), 
+				 v1.complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, complex_matrix, sparse_complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  complex_matrix, sparse_complex_matrix, mx_el_or)
+
+DEFCATOP (cm_scm, complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (octave_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+  SparseComplexMatrix tmp (v1.complex_matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_complex_matrix_value (), 
+				    ra_idx));
+}
+
+DEFCONV (sparse_complex_matrix_conv, complex_matrix, 
+	 sparse_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_complex_matrix&);
+  return new octave_sparse_complex_matrix 
+    (SparseComplexMatrix (v.complex_matrix_value ()));
+}
+
+DEFNDASSIGNOP_FN (assign, complex_matrix, sparse_complex_matrix, 
+		  complex_array, assign)
+
+void
+install_cm_scm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, ldiv);
+  INSTALL_BINOP (op_mul_trans, octave_complex_matrix, 
+                 octave_sparse_complex_matrix, mul_trans);
+  INSTALL_BINOP (op_mul_herm, octave_complex_matrix, 
+                 octave_sparse_complex_matrix, mul_herm);
+  INSTALL_BINOP (op_lt, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex_matrix, 
+		 octave_sparse_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_complex_matrix, 
+		 octave_sparse_complex_matrix, cm_scm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, 
+		    octave_sparse_complex_matrix, assign)
+  INSTALL_ASSIGNCONV (octave_complex_matrix, octave_sparse_complex_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_complex_matrix, octave_sparse_complex_matrix, 
+		   sparse_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cm-sm.cc b/src/OPERATORS/op-cm-sm.cc
new file mode 100644
index 0000000..89b6be6
--- /dev/null
+++ b/src/OPERATORS/op-cm-sm.cc
@@ -0,0 +1,174 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-sm-cm.h"
+#include "smx-cm-sm.h"
+#include "ov-re-sparse.h"
+
+// complex matrix by sparse matrix ops.
+
+DEFBINOP_OP (add, complex_matrix, sparse_matrix, +)
+DEFBINOP_OP (sub, complex_matrix, sparse_matrix, -)
+
+DEFBINOP_OP (mul, complex_matrix, sparse_matrix, *)
+
+DEFBINOP (div, complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_sparse_matrix&);
+  
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+
+      ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+				v2.sparse_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, complex_matrix, sparse_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, 
+		   const octave_sparse_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (), 
+				v2.matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (lt, complex_matrix, sparse_matrix, mx_el_lt)
+DEFBINOP_FN (le, complex_matrix, sparse_matrix, mx_el_le)
+DEFBINOP_FN (eq, complex_matrix, sparse_matrix, mx_el_eq)
+DEFBINOP_FN (ge, complex_matrix, sparse_matrix, mx_el_ge)
+DEFBINOP_FN (gt, complex_matrix, sparse_matrix, mx_el_gt)
+DEFBINOP_FN (ne, complex_matrix, sparse_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, complex_matrix, sparse_matrix, product)
+DEFBINOP_FN (el_div, complex_matrix, sparse_matrix, quotient)
+
+DEFBINOP (el_pow, complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, 
+		   const octave_sparse_matrix&);
+  
+  return octave_value 
+    (elem_xpow ( SparseComplexMatrix (v1.complex_matrix_value ()),
+		 v2.sparse_matrix_value ()));
+}
+
+DEFBINOP (el_ldiv, complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_matrix&, 
+		   const octave_sparse_matrix&);
+  return octave_value
+    (quotient (v2.sparse_matrix_value (), v1.complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, complex_matrix, sparse_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  complex_matrix, sparse_matrix, mx_el_or)
+
+DEFCATOP (cm_sm, complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (octave_complex_matrix&, const octave_sparse_matrix&);
+  SparseComplexMatrix tmp (v1.complex_matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFNDASSIGNOP_FN (assign, complex_matrix, sparse_matrix, complex_array, assign)
+
+void
+install_cm_sm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex_matrix, octave_sparse_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex_matrix, octave_sparse_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex_matrix, octave_sparse_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex_matrix, octave_sparse_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex_matrix, octave_sparse_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex_matrix, octave_sparse_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex_matrix, octave_sparse_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex_matrix, octave_sparse_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex_matrix, octave_sparse_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex_matrix, octave_sparse_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex_matrix, octave_sparse_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex_matrix, octave_sparse_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex_matrix, octave_sparse_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex_matrix, octave_sparse_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex_matrix, octave_sparse_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex_matrix, octave_sparse_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_sparse_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_sparse_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_complex_matrix, octave_sparse_matrix, cm_sm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_sparse_matrix, 
+		    assign);
+  INSTALL_ASSIGNCONV (octave_complex_matrix, octave_sparse_matrix, 
+		      octave_complex_matrix)
+
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cs-cm.cc b/src/OPERATORS/op-cs-cm.cc
new file mode 100644
index 0000000..8ca11c6
--- /dev/null
+++ b/src/OPERATORS/op-cs-cm.cc
@@ -0,0 +1,140 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex scalar by complex matrix ops.
+
+DEFNDBINOP_OP (add, complex, complex_matrix, complex, complex_array, +)
+DEFNDBINOP_OP (sub, complex, complex_matrix, complex, complex_array, -)
+DEFNDBINOP_OP (mul, complex, complex_matrix, complex, complex_array, *)
+
+DEFBINOP (div, complex, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex_matrix&);
+
+  ComplexMatrix m1 = v1.complex_matrix_value ();
+  ComplexMatrix m2 = v2.complex_matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  ComplexMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, complex, complex_matrix, xpow)
+
+DEFBINOP (ldiv, complex, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex_matrix&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, complex, complex_matrix, complex, complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, complex, complex_matrix, complex, complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, complex, complex_matrix, complex, complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex, complex_matrix, complex, complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex, complex_matrix, complex, complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex, complex_matrix, complex, complex_array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, complex, complex_matrix, complex, complex_array, *)
+DEFNDBINOP_FN (el_div, complex, complex_matrix, complex, complex_array, x_el_div)
+DEFNDBINOP_FN (el_pow, complex, complex_matrix, complex, complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, complex, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex_matrix&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, complex, complex_matrix, complex, complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex, complex_matrix, complex, complex_array, mx_el_or)
+
+DEFNDCATOP_FN (cs_cm, complex, complex_matrix, complex_array, complex_array, concat)
+
+DEFCONV (complex_matrix_conv, complex, complex_matrix)
+{
+  CAST_CONV_ARG (const octave_complex&);
+
+  return new octave_complex_matrix (v.complex_matrix_value ());
+}
+
+void
+install_cs_cm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex, octave_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex, octave_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex, octave_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex, octave_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex, octave_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex, octave_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex, octave_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex, octave_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex, octave_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex, octave_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex, octave_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex, octave_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex, octave_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex, octave_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex, octave_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex, octave_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex, octave_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_complex, octave_complex_matrix, cs_cm);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_complex_matrix, octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_complex, octave_complex_matrix, complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cs-cs.cc b/src/OPERATORS/op-cs-cs.cc
new file mode 100644
index 0000000..fcfa6c2
--- /dev/null
+++ b/src/OPERATORS/op-cs-cs.cc
@@ -0,0 +1,235 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// unary complex scalar ops.
+
+DEFUNOP (not, complex)
+{
+  CAST_UNOP_ARG (const octave_complex&);
+
+  return octave_value (v.complex_value () == 0.0);
+}
+
+DEFUNOP_OP (uplus, complex, /* no-op */)
+DEFUNOP_OP (uminus, complex, -)
+DEFUNOP_OP (transpose, complex, /* no-op */)
+
+DEFUNOP (hermitian, complex)
+{
+  CAST_UNOP_ARG (const octave_complex&);
+
+  return octave_value (conj (v.complex_value ()));
+}
+
+DEFNCUNOP_METHOD (incr, complex, increment)
+DEFNCUNOP_METHOD (decr, complex, decrement)
+
+// complex scalar by complex scalar ops.
+
+DEFBINOP_OP (add, complex, complex, +)
+DEFBINOP_OP (sub, complex, complex, -)
+DEFBINOP_OP (mul, complex, complex, *)
+
+DEFBINOP (div, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_value () / d);
+}
+
+DEFBINOP_FN (pow, complex, complex, xpow)
+
+DEFBINOP (ldiv, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_value () / d);
+}
+
+DEFBINOP (lt, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return real (v1.complex_value ()) < real (v2.complex_value ());
+}
+
+DEFBINOP (le, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return real (v1.complex_value ()) <= real (v2.complex_value ());
+}
+
+DEFBINOP (eq, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return v1.complex_value () == v2.complex_value ();
+}
+
+DEFBINOP (ge, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return real (v1.complex_value ()) >= real (v2.complex_value ());
+}
+
+DEFBINOP (gt, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return real (v1.complex_value ()) > real (v2.complex_value ());
+}
+
+DEFBINOP (ne, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return v1.complex_value () != v2.complex_value ();
+}
+
+DEFBINOP_OP (el_mul, complex, complex, *)
+
+DEFBINOP (el_div, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_value () / d);
+}
+
+DEFBINOP_FN (el_pow, complex, complex, xpow)
+
+DEFBINOP (el_ldiv, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_value () / d);
+}
+
+DEFBINOP (el_and, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return v1.complex_value () != 0.0 && v2.complex_value () != 0.0;
+}
+
+DEFBINOP (el_or, complex, complex)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+
+  return v1.complex_value () != 0.0 || v2.complex_value () != 0.0;
+}
+
+DEFNDCATOP_FN (cs_cs, complex, complex, complex_array, complex_array, concat)
+
+CONVDECL (complex_to_float_complex)
+{
+  CAST_CONV_ARG (const octave_complex&);
+
+  return new octave_float_complex_matrix (FloatComplexMatrix (1, 1, static_cast<FloatComplex>(v.complex_value ())));
+}
+
+void
+install_cs_cs_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_complex, not);
+  INSTALL_UNOP (op_uplus, octave_complex, uplus);
+  INSTALL_UNOP (op_uminus, octave_complex, uminus);
+  INSTALL_UNOP (op_transpose, octave_complex, transpose);
+  INSTALL_UNOP (op_hermitian, octave_complex, hermitian);
+
+  INSTALL_NCUNOP (op_incr, octave_complex, incr);
+  INSTALL_NCUNOP (op_decr, octave_complex, decr);
+
+  INSTALL_BINOP (op_add, octave_complex, octave_complex, add);
+  INSTALL_BINOP (op_sub, octave_complex, octave_complex, sub);
+  INSTALL_BINOP (op_mul, octave_complex, octave_complex, mul);
+  INSTALL_BINOP (op_div, octave_complex, octave_complex, div);
+  INSTALL_BINOP (op_pow, octave_complex, octave_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex, octave_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex, octave_complex, lt);
+  INSTALL_BINOP (op_le, octave_complex, octave_complex, le);
+  INSTALL_BINOP (op_eq, octave_complex, octave_complex, eq);
+  INSTALL_BINOP (op_ge, octave_complex, octave_complex, ge);
+  INSTALL_BINOP (op_gt, octave_complex, octave_complex, gt);
+  INSTALL_BINOP (op_ne, octave_complex, octave_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex, octave_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex, octave_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex, octave_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex, octave_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex, octave_complex, el_or);
+
+  INSTALL_CATOP (octave_complex, octave_complex, cs_cs);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_complex, octave_complex_matrix);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_null_matrix, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_complex, octave_null_str, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_complex, octave_null_sq_str, octave_complex_matrix);
+
+  INSTALL_CONVOP (octave_complex, octave_float_complex_matrix, 
+		  complex_to_float_complex);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cs-m.cc b/src/OPERATORS/op-cs-m.cc
new file mode 100644
index 0000000..41580e2
--- /dev/null
+++ b/src/OPERATORS/op-cs-m.cc
@@ -0,0 +1,137 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-cs-nda.h"
+#include "mx-nda-cs.h"
+#include "mx-cs-nda.h"
+#include "mx-nda-cs.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex scalar by matrix ops.
+
+DEFNDBINOP_OP (add, complex, matrix, complex, array, +)
+DEFNDBINOP_OP (sub, complex, matrix, complex, array, -)
+DEFNDBINOP_OP (mul, complex, matrix, complex, array, *)
+
+DEFBINOP (div, complex, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_matrix&);
+
+  ComplexMatrix m1 = v1.complex_matrix_value ();
+  Matrix m2 = v2.matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  ComplexMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, complex, matrix, xpow)
+
+DEFBINOP (ldiv, complex, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_matrix&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, complex, matrix, complex, array, mx_el_lt)
+DEFNDBINOP_FN (le, complex, matrix, complex, array, mx_el_le)
+DEFNDBINOP_FN (eq, complex, matrix, complex, array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex, matrix, complex, array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex, matrix, complex, array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex, matrix, complex, array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, complex, matrix, complex, array, *)
+DEFNDBINOP_FN (el_div, complex, matrix, complex, array, x_el_div)
+DEFNDBINOP_FN (el_pow, complex, matrix, complex, array, elem_xpow)
+
+DEFBINOP (el_ldiv, complex, matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_matrix&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, complex, matrix, complex, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex, matrix, complex, array, mx_el_or)
+
+DEFNDCATOP_FN (cs_m, complex, matrix, complex_array, array, concat)
+
+void
+install_cs_m_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex, octave_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex, octave_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex, octave_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex, octave_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex, octave_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex, octave_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex, octave_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex, octave_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex, octave_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex, octave_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex, octave_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex, octave_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex, octave_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex, octave_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex, octave_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex, octave_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex, octave_matrix, el_or);
+
+  INSTALL_CATOP (octave_complex, octave_matrix, cs_m);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_matrix, octave_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cs-s.cc b/src/OPERATORS/op-cs-s.cc
new file mode 100644
index 0000000..2e670fd
--- /dev/null
+++ b/src/OPERATORS/op-cs-s.cc
@@ -0,0 +1,188 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex scalar by scalar ops.
+
+DEFBINOP_OP (add, complex, scalar, +)
+DEFBINOP_OP (sub, complex, scalar, -)
+DEFBINOP_OP (mul, complex, scalar, *)
+
+DEFBINOP (div, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_value () / d);
+}
+
+DEFBINOP_FN (pow, complex, scalar, xpow)
+
+DEFBINOP (ldiv, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.double_value () / d);
+}
+
+DEFBINOP (lt, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return real (v1.complex_value ()) < v2.double_value ();
+}
+
+DEFBINOP (le, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return real (v1.complex_value ()) <= v2.double_value ();
+}
+
+DEFBINOP (eq, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return v1.complex_value () == v2.double_value ();
+}
+
+DEFBINOP (ge, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return real (v1.complex_value ()) >= v2.double_value ();
+}
+
+DEFBINOP (gt, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return real (v1.complex_value ()) > v2.double_value ();
+}
+
+DEFBINOP (ne, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return v1.complex_value () != v2.double_value ();
+}
+
+DEFBINOP_OP (el_mul, complex, scalar, *)
+
+DEFBINOP (el_div, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.complex_value () / d);
+}
+
+DEFBINOP_FN (el_pow, complex, scalar, xpow)
+
+DEFBINOP (el_ldiv, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.double_value () / d);
+}
+
+DEFBINOP (el_and, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return v1.complex_value () != 0.0 && v2.double_value ();
+}
+
+DEFBINOP (el_or, complex, scalar)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+
+  return v1.complex_value () != 0.0 || v2.double_value ();
+}
+
+DEFNDCATOP_FN (cs_s, complex, scalar, complex_array, array, concat)
+
+void
+install_cs_s_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_complex, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_complex, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_complex, octave_scalar, div);
+  INSTALL_BINOP (op_pow, octave_complex, octave_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex, octave_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex, octave_scalar, lt);
+  INSTALL_BINOP (op_le, octave_complex, octave_scalar, le);
+  INSTALL_BINOP (op_eq, octave_complex, octave_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_complex, octave_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_complex, octave_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_complex, octave_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex, octave_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex, octave_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex, octave_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex, octave_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex, octave_scalar, el_or);
+
+  INSTALL_CATOP (octave_complex, octave_scalar, cs_s);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_scalar, octave_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cs-scm.cc b/src/OPERATORS/op-cs-scm.cc
new file mode 100644
index 0000000..9eedd3f
--- /dev/null
+++ b/src/OPERATORS/op-cs-scm.cc
@@ -0,0 +1,178 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ov-complex.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-cx-sparse.h"
+
+// complex scalar by sparse complex matrix ops.
+
+DEFBINOP_OP (add, complex, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, complex, sparse_complex_matrix, -)
+DEFBINOP_OP (mul, complex, sparse_complex_matrix, *)
+
+DEFBINOP (div, complex, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseComplexMatrix (1, 1, v1.complex_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      ComplexMatrix m1 = ComplexMatrix (1, 1, v1.complex_value ());
+      SparseComplexMatrix m2 = v2.sparse_complex_matrix_value ();
+      ComplexMatrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP (pow, complex, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, 
+		   const octave_sparse_complex_matrix&);
+  return xpow (v1.complex_value (), v2.complex_matrix_value ());
+}
+
+DEFBINOP (ldiv, complex, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
+
+  Complex d = v1.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.sparse_complex_matrix_value () / d);
+}
+
+DEFBINOP_FN (lt, complex, sparse_complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, complex, sparse_complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, complex, sparse_complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, complex, sparse_complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, complex, sparse_complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, complex, sparse_complex_matrix, mx_el_ne)
+
+DEFBINOP_OP (el_mul, complex, sparse_complex_matrix, *)
+DEFBINOP_FN (el_div, complex, sparse_complex_matrix, x_el_div)
+
+DEFBINOP_FN (el_pow, complex, sparse_complex_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, complex, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
+
+  Complex d = v1.complex_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_and, complex, sparse_complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  complex, sparse_complex_matrix, mx_el_or)
+
+DEFCATOP (cs_scm, complex, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (octave_complex&, const octave_sparse_complex_matrix&);
+  SparseComplexMatrix tmp (1, 1, v1.complex_value ());
+  return octave_value (tmp. concat (v2.sparse_complex_matrix_value (), 
+				    ra_idx));
+}
+
+DEFCONV (sparse_complex_matrix_conv, complex, sparse_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_complex&);
+
+  return new octave_sparse_complex_matrix 
+    (SparseComplexMatrix (v.complex_matrix_value ()));
+}
+
+void
+install_cs_scm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex, octave_sparse_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex, octave_sparse_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex, octave_sparse_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex, octave_sparse_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex, octave_sparse_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex, octave_sparse_complex_matrix, 
+		 ldiv);
+  INSTALL_BINOP (op_lt, octave_complex, octave_sparse_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex, octave_sparse_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex, octave_sparse_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex, octave_sparse_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex, octave_sparse_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex, octave_sparse_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex, octave_sparse_complex_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex, octave_sparse_complex_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_sparse_complex_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex, octave_sparse_complex_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex, octave_sparse_complex_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_complex, octave_sparse_complex_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_complex, octave_sparse_complex_matrix, cs_scm);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_sparse_complex_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_complex, octave_sparse_complex_matrix, 
+		   sparse_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-cs-sm.cc b/src/OPERATORS/op-cs-sm.cc
new file mode 100644
index 0000000..7c51e74
--- /dev/null
+++ b/src/OPERATORS/op-cs-sm.cc
@@ -0,0 +1,172 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-complex.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "smx-cs-sm.h"
+#include "smx-sm-cs.h"
+
+// complex by sparse matrix ops.
+
+DEFBINOP_OP (add, complex, sparse_matrix, +)
+DEFBINOP_OP (sub, complex, sparse_matrix, -)
+DEFBINOP_OP (mul, complex, sparse_matrix, *)
+
+DEFBINOP (div, complex, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseComplexMatrix (1, 1, v1.complex_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      ComplexMatrix m1 = ComplexMatrix (1, 1, v1.complex_value ());
+      SparseMatrix m2 = v2.sparse_matrix_value ();
+      ComplexMatrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP (pow, complex, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+  return xpow (v1.complex_value (), v2.matrix_value ());
+}
+
+DEFBINOP (ldiv, complex, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+
+  Complex d = v1.complex_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (lt, complex, sparse_matrix, mx_el_lt)
+DEFBINOP_FN (le, complex, sparse_matrix, mx_el_le)
+DEFBINOP_FN (eq, complex, sparse_matrix, mx_el_eq)
+DEFBINOP_FN (ge, complex, sparse_matrix, mx_el_ge)
+DEFBINOP_FN (gt, complex, sparse_matrix, mx_el_gt)
+DEFBINOP_FN (ne, complex, sparse_matrix, mx_el_ne)
+
+DEFBINOP_OP (el_mul, complex, sparse_matrix, *)
+DEFBINOP_FN (el_div, complex, sparse_matrix, x_el_div)
+DEFBINOP_FN (el_pow, complex, sparse_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, complex, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+
+  Complex d = v1.complex_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_and, complex, sparse_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  complex, sparse_matrix, mx_el_or)
+
+DEFCATOP (cs_sm, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (octave_complex&, const octave_sparse_matrix&);
+  SparseComplexMatrix tmp (1, 1, v1.complex_value ());
+  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCONV (sparse_matrix_conv, complex, sparse_matrix)
+{
+  CAST_CONV_ARG (const octave_complex&);
+
+  return new octave_sparse_matrix 
+    (SparseMatrix (v.matrix_value ()));
+}
+
+void
+install_cs_sm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_complex, octave_sparse_matrix, add);
+  INSTALL_BINOP (op_sub, octave_complex, octave_sparse_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_complex, octave_sparse_matrix, mul);
+  INSTALL_BINOP (op_div, octave_complex, octave_sparse_matrix, div);
+  INSTALL_BINOP (op_pow, octave_complex, octave_sparse_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_complex, octave_sparse_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_complex, octave_sparse_matrix, lt);
+  INSTALL_BINOP (op_le, octave_complex, octave_sparse_matrix, le);
+  INSTALL_BINOP (op_eq, octave_complex, octave_sparse_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_complex, octave_sparse_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_complex, octave_sparse_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_complex, octave_sparse_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_complex, octave_sparse_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_complex, octave_sparse_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_sparse_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_complex, octave_sparse_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_complex, octave_sparse_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_complex, octave_sparse_matrix, el_or);
+
+  INSTALL_CATOP (octave_complex, octave_sparse_matrix, cs_sm);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_sparse_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_complex, octave_sparse_matrix, sparse_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-dm-cdm.cc b/src/OPERATORS/op-dm-cdm.cc
new file mode 100644
index 0000000..f19b36a
--- /dev/null
+++ b/src/OPERATORS/op-dm-cdm.cc
@@ -0,0 +1,37 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-re-diag.h"
+#define RINCLUDE "ov-cx-diag.h"
+
+#define LMATRIX diag_matrix
+#define RMATRIX complex_diag_matrix
+#define LDMATRIX RMATRIX
+
+#define LSHORT dm
+#define RSHORT cdm
+
+#define DEFINEDIV
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-dm-cm.cc b/src/OPERATORS/op-dm-cm.cc
new file mode 100644
index 0000000..d6a7f5c
--- /dev/null
+++ b/src/OPERATORS/op-dm-cm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-re-diag.h"
+#define RINCLUDE "ov-cx-mat.h"
+
+#define LMATRIX diag_matrix
+#define RMATRIX complex_matrix
+
+#define LSHORT dm
+#define RSHORT cm
+
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-dm-cs.cc b/src/OPERATORS/op-dm-cs.cc
new file mode 100644
index 0000000..4c7febf
--- /dev/null
+++ b/src/OPERATORS/op-dm-cs.cc
@@ -0,0 +1,34 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-complex.h"
+#define MINCLUDE "ov-re-diag.h"
+
+#define SCALAR complex
+#define MATRIX diag_matrix
+#define MATRIXV complex_diag_matrix
+
+#define SSHORT cs
+#define MSHORT dm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-dm-dm.cc b/src/OPERATORS/op-dm-dm.cc
new file mode 100644
index 0000000..cc22544
--- /dev/null
+++ b/src/OPERATORS/op-dm-dm.cc
@@ -0,0 +1,103 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-re-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix unary ops.
+
+DEFUNOP_OP (uplus, diag_matrix, /* no-op */)
+DEFUNOP_OP (uminus, diag_matrix, -)
+
+DEFUNOP (transpose, diag_matrix)
+{
+  CAST_UNOP_ARG (const octave_diag_matrix&);
+  return octave_value (v.diag_matrix_value().transpose ());
+}
+
+// matrix by matrix ops.
+
+DEFBINOP_OP (add, diag_matrix, diag_matrix, +)
+DEFBINOP_OP (sub, diag_matrix, diag_matrix, -)
+DEFBINOP_OP (mul, diag_matrix, diag_matrix, *)
+
+DEFBINOP (div, diag_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_diag_matrix&);
+  
+  return xdiv (v1.diag_matrix_value (), 
+               v2.diag_matrix_value ());
+}
+
+DEFBINOP (ldiv, diag_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_diag_matrix&);
+  
+  return xleftdiv (v1.diag_matrix_value (),
+                   v2.diag_matrix_value ());
+}
+
+CONVDECL (diag_matrix_to_matrix)
+{
+  CAST_CONV_ARG (const octave_diag_matrix&);
+
+  return new octave_matrix (v.matrix_value ());
+}
+
+CONVDECL (diag_matrix_to_float_diag_matrix)
+{
+  CAST_CONV_ARG (const octave_diag_matrix&);
+
+  return new octave_float_diag_matrix (v.float_diag_matrix_value ());
+}
+
+void
+install_dm_dm_ops (void)
+{
+  INSTALL_UNOP (op_uplus, octave_diag_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_diag_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_diag_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_diag_matrix, transpose);
+
+  INSTALL_BINOP (op_add, octave_diag_matrix, octave_diag_matrix, add);
+  INSTALL_BINOP (op_sub, octave_diag_matrix, octave_diag_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_diag_matrix, octave_diag_matrix, mul);
+  INSTALL_BINOP (op_div, octave_diag_matrix, octave_diag_matrix, div);
+  INSTALL_BINOP (op_ldiv, octave_diag_matrix, octave_diag_matrix, ldiv);
+
+  INSTALL_CONVOP (octave_diag_matrix, octave_matrix, diag_matrix_to_matrix);
+  INSTALL_CONVOP (octave_diag_matrix, octave_float_diag_matrix, diag_matrix_to_float_diag_matrix);
+  INSTALL_ASSIGNCONV (octave_diag_matrix, octave_matrix, octave_matrix);
+  INSTALL_WIDENOP (octave_diag_matrix, octave_matrix, diag_matrix_to_matrix);
+}
diff --git a/src/OPERATORS/op-dm-m.cc b/src/OPERATORS/op-dm-m.cc
new file mode 100644
index 0000000..355ce90
--- /dev/null
+++ b/src/OPERATORS/op-dm-m.cc
@@ -0,0 +1,37 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-re-diag.h"
+#define RINCLUDE "ov-re-mat.h"
+
+#define LMATRIX diag_matrix
+#define LDMATRIX matrix
+#define RMATRIX matrix
+
+#define LSHORT dm
+#define RSHORT m
+
+#define DEFINELDIV
+#define DEFINENULLASSIGNCONV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-dm-s.cc b/src/OPERATORS/op-dm-s.cc
new file mode 100644
index 0000000..b21feb7
--- /dev/null
+++ b/src/OPERATORS/op-dm-s.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-scalar.h"
+#define MINCLUDE "ov-re-diag.h"
+
+#define SCALAR scalar
+#define MATRIX diag_matrix
+
+#define SSHORT s
+#define MSHORT dm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-dm-scm.cc b/src/OPERATORS/op-dm-scm.cc
new file mode 100644
index 0000000..e585838
--- /dev/null
+++ b/src/OPERATORS/op-dm-scm.cc
@@ -0,0 +1,511 @@
+/*
+
+Copyright (C) 2009 Jason Riedy, Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#include "ov-re-diag.h"
+#include "ov-cx-diag.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#include "sparse-xdiv.h"
+
+// diagonal matrix by sparse matrix ops
+
+DEFBINOP (mul_dm_scm, diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.diag_matrix_value () * d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = v1.diag_matrix_value () * v2.sparse_complex_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (mul_cdm_sm, complex_diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.scalar_value ();
+
+      return octave_value (v1.complex_diag_matrix_value () * d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = v1.complex_diag_matrix_value () * v2.sparse_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (mul_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.complex_diag_matrix_value () * d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = v1.complex_diag_matrix_value () * v2.sparse_complex_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (ldiv_dm_scm, diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&,
+		   const octave_sparse_complex_matrix&);
+
+  MatrixType typ = v2.matrix_type ();
+  return xleftdiv (v1.diag_matrix_value (), v2.sparse_complex_matrix_value (),
+		   typ);
+}
+
+DEFBINOP (ldiv_cdm_sm, complex_diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
+		   const octave_sparse_matrix&);
+
+  MatrixType typ = v2.matrix_type ();
+  return xleftdiv (v1.complex_diag_matrix_value (), v2.sparse_matrix_value (),
+		   typ);
+}
+
+DEFBINOP (ldiv_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
+		   const octave_sparse_complex_matrix&);
+
+  MatrixType typ = v2.matrix_type ();
+  return xleftdiv (v1.complex_diag_matrix_value (), v2.sparse_complex_matrix_value (),
+		   typ);
+}
+
+DEFBINOP (add_dm_scm, diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.diag_matrix_value () + d);
+    }
+  else
+    return v1.diag_matrix_value () + v2.sparse_complex_matrix_value ();
+}
+
+DEFBINOP (add_cdm_sm, complex_diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.complex_diag_matrix_value () + d);
+    }
+  else
+    return v1.complex_diag_matrix_value () + v2.sparse_matrix_value ();
+}
+
+DEFBINOP (add_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.complex_diag_matrix_value () + d);
+    }
+  else
+    return v1.complex_diag_matrix_value () + v2.sparse_complex_matrix_value ();
+}
+
+DEFBINOP (sub_dm_scm, diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.diag_matrix_value () + (-d));
+    }
+  else
+    return v1.diag_matrix_value () - v2.sparse_complex_matrix_value ();
+}
+
+DEFBINOP (sub_cdm_sm, complex_diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.complex_diag_matrix_value () + (-d));
+    }
+  else
+    return v1.complex_diag_matrix_value () - v2.sparse_matrix_value ();
+}
+
+DEFBINOP (sub_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_complex_diag_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.complex_diag_matrix_value () + (-d));
+    }
+  else
+    return v1.complex_diag_matrix_value () - v2.sparse_complex_matrix_value ();
+}
+
+// sparse matrix by diagonal matrix ops
+
+DEFBINOP (mul_scm_dm, sparse_complex_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_diag_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    // If v1 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v1.complex_value ();
+
+      return octave_value (d * v2.diag_matrix_value ());
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix ret = v1.sparse_complex_matrix_value () * v2.diag_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (mul_sm_cdm, sparse_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_diag_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    // If v1 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v1.complex_value ();
+
+      return octave_value (d * v2.complex_diag_matrix_value ());
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix ret = v1.sparse_matrix_value () * v2.complex_diag_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (mul_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex_diag_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    // If v1 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v1.complex_value ();
+
+      return octave_value (d * v2.complex_diag_matrix_value ());
+    }
+  else if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, don't bother with further dispatching.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.sparse_complex_matrix_value () * d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix ret = v1.sparse_complex_matrix_value () * v2.complex_diag_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (div_scm_dm, sparse_complex_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      return xdiv (v1.sparse_complex_matrix_value (), v2.diag_matrix_value (), typ);
+    }
+}
+
+DEFBINOP (div_sm_cdm, sparse_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      return xdiv (v1.sparse_matrix_value (), v2.complex_diag_matrix_value (), typ);
+    }
+}
+
+DEFBINOP (div_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      return xdiv (v1.sparse_complex_matrix_value (), v2.complex_diag_matrix_value (), typ);
+    }
+}
+
+DEFBINOP (add_sm_cdm, sparse_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.sparse_matrix_value () + d);
+    }
+  else
+    return v1.sparse_matrix_value () + v2.complex_diag_matrix_value ();
+}
+
+DEFBINOP (add_scm_dm, sparse_complex_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.sparse_complex_matrix_value () + d);
+    }
+  else
+    return v1.sparse_complex_matrix_value () + v2.diag_matrix_value ();
+}
+
+DEFBINOP (add_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.sparse_complex_matrix_value () + d);
+    }
+  else
+    return v1.sparse_complex_matrix_value () + v2.complex_diag_matrix_value ();
+}
+
+DEFBINOP (sub_sm_cdm, sparse_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.sparse_matrix_value () + (-d));
+    }
+  else
+    return v1.sparse_matrix_value () - v2.complex_diag_matrix_value ();
+}
+
+DEFBINOP (sub_scm_dm, sparse_complex_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.sparse_complex_matrix_value () + (-d));
+    }
+  else
+    return v1.sparse_complex_matrix_value () - v2.diag_matrix_value ();
+}
+
+DEFBINOP (sub_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.sparse_complex_matrix_value () + (-d));
+    }
+  else
+    return v1.sparse_complex_matrix_value () - v2.complex_diag_matrix_value ();
+}
+
+void
+install_dm_scm_ops (void)
+{
+  INSTALL_BINOP (op_mul, octave_diag_matrix, octave_sparse_complex_matrix,
+		 mul_dm_scm);
+  INSTALL_BINOP (op_mul, octave_complex_diag_matrix, octave_sparse_matrix,
+		 mul_cdm_sm);
+  INSTALL_BINOP (op_mul, octave_complex_diag_matrix, octave_sparse_complex_matrix,
+		 mul_cdm_scm);
+  INSTALL_BINOP (op_ldiv, octave_diag_matrix, octave_sparse_complex_matrix, ldiv_dm_scm);
+  INSTALL_BINOP (op_ldiv, octave_complex_diag_matrix, octave_sparse_matrix, ldiv_cdm_sm);
+  INSTALL_BINOP (op_ldiv, octave_complex_diag_matrix, octave_sparse_complex_matrix,
+		 ldiv_cdm_scm);
+
+  INSTALL_BINOP (op_add, octave_diag_matrix, octave_sparse_complex_matrix, add_dm_scm);
+  INSTALL_BINOP (op_add, octave_complex_diag_matrix, octave_sparse_matrix, add_cdm_sm);
+  INSTALL_BINOP (op_add, octave_complex_diag_matrix, octave_sparse_complex_matrix,
+		 add_cdm_scm);
+  INSTALL_BINOP (op_sub, octave_diag_matrix, octave_sparse_complex_matrix, sub_dm_scm);
+  INSTALL_BINOP (op_sub, octave_complex_diag_matrix, octave_sparse_matrix, sub_cdm_sm);
+  INSTALL_BINOP (op_sub, octave_complex_diag_matrix, octave_sparse_complex_matrix,
+		 sub_cdm_scm);
+
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_diag_matrix,
+		 mul_scm_dm);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_complex_diag_matrix,
+		 mul_sm_cdm);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_complex_diag_matrix,
+		 mul_scm_cdm);
+
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_diag_matrix, div_scm_dm);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_complex_diag_matrix, div_sm_cdm);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_complex_diag_matrix, div_scm_cdm);
+
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, octave_diag_matrix, add_scm_dm);
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_complex_diag_matrix, add_sm_cdm);
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, octave_complex_diag_matrix, add_scm_cdm);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, octave_diag_matrix, sub_scm_dm);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_complex_diag_matrix, sub_sm_cdm);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, octave_complex_diag_matrix, sub_scm_cdm);
+}
diff --git a/src/OPERATORS/op-dm-sm.cc b/src/OPERATORS/op-dm-sm.cc
new file mode 100644
index 0000000..6b174d7
--- /dev/null
+++ b/src/OPERATORS/op-dm-sm.cc
@@ -0,0 +1,196 @@
+/*
+
+Copyright (C) 2009 Jason Riedy, Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#include "ov-re-diag.h"
+#include "ov-re-sparse.h"
+
+#include "sparse-xdiv.h"
+
+// diagonal matrix by sparse matrix ops
+
+DEFBINOP (mul_dm_sm, diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.diag_matrix_value () * d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseMatrix ret = v1.diag_matrix_value () * v2.sparse_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (ldiv_dm_sm, diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+
+  MatrixType typ = v2.matrix_type ();
+  return xleftdiv (v1.diag_matrix_value (), v2.sparse_matrix_value (), typ);
+}
+
+DEFBINOP (add_dm_sm, diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.diag_matrix_value () + d);
+    }
+  else
+    return v1.diag_matrix_value () + v2.sparse_matrix_value ();
+}
+
+DEFBINOP (sub_dm_sm, diag_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    // If v2 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.diag_matrix_value () - d);
+    }
+  else
+    return v1.diag_matrix_value () - v2.sparse_matrix_value ();
+}
+
+// sparse matrix by diagonal matrix ops
+
+DEFBINOP (mul_sm_dm, sparse_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    // If v1 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v1.scalar_value ();
+
+      return octave_value (d * v2.diag_matrix_value ());
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseMatrix ret = v1.sparse_matrix_value () * v2.diag_matrix_value ();
+      octave_value out = octave_value (ret);
+      typ.mark_as_unsymmetric ();
+      out.matrix_type (typ);
+      return out;
+    }
+}
+
+DEFBINOP (div_sm_dm, sparse_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      return xdiv (v1.sparse_matrix_value (), v2.diag_matrix_value (), typ);
+    }
+}
+
+DEFBINOP (add_sm_dm, sparse_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    // If v1 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v1.scalar_value ();
+
+      return octave_value (d + v2.diag_matrix_value ());
+    }
+  else
+    return v1.sparse_matrix_value () + v2.diag_matrix_value ();
+}
+
+DEFBINOP (sub_sm_dm, sparse_matrix, diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    // If v1 is a scalar in disguise, return a diagonal matrix rather than
+    // a sparse matrix.
+    {
+      double d = v1.scalar_value ();
+
+      return octave_value (d - v2.diag_matrix_value ());
+    }
+  else
+    return v1.sparse_matrix_value () - v2.diag_matrix_value ();
+}
+
+void
+install_dm_sm_ops (void)
+{
+  INSTALL_BINOP (op_mul, octave_diag_matrix, octave_sparse_matrix,
+		 mul_dm_sm);
+
+  INSTALL_BINOP (op_add, octave_diag_matrix, octave_sparse_matrix, add_dm_sm);
+  INSTALL_BINOP (op_sub, octave_diag_matrix, octave_sparse_matrix, sub_dm_sm);
+  INSTALL_BINOP (op_ldiv, octave_diag_matrix, octave_sparse_matrix, ldiv_dm_sm);
+
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_diag_matrix,
+		 mul_sm_dm);
+
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_diag_matrix, add_sm_dm);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_diag_matrix, sub_sm_dm);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_diag_matrix, div_sm_dm);
+}
diff --git a/src/OPERATORS/op-dm-template.cc b/src/OPERATORS/op-dm-template.cc
new file mode 100644
index 0000000..1d4916f
--- /dev/null
+++ b/src/OPERATORS/op-dm-template.cc
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ops.h"
+#include "xdiv.h"
+#include LINCLUDE
+#include RINCLUDE
+#ifdef DEFINENULLASSIGNCONV
+#include "ov-null-mat.h"
+#endif
+
+// matrix by diag matrix ops.
+
+DEFBINOP_OP (add, LMATRIX, RMATRIX, +)
+DEFBINOP_OP (sub, LMATRIX, RMATRIX, -)
+DEFBINOP_OP (mul, LMATRIX, RMATRIX, *)
+
+#ifndef LDMATRIX
+#define LDMATRIX LMATRIX
+#endif
+
+#ifndef RDMATRIX
+#define RDMATRIX RMATRIX
+#endif
+
+#define OCTAVE_LMATRIX CONCAT2(octave_, LMATRIX)
+#define OCTAVE_LDMATRIX CONCAT2(octave_, LDMATRIX)
+#define OCTAVE_RMATRIX CONCAT2(octave_, RMATRIX)
+#define LMATRIX_VALUE CONCAT2(LMATRIX, _value)
+#define RMATRIX_VALUE CONCAT2(RMATRIX, _value)
+#define LDMATRIX_VALUE CONCAT2(LDMATRIX, _value)
+#define RDMATRIX_VALUE CONCAT2(RDMATRIX, _value)
+
+#ifdef DEFINEDIV
+DEFBINOP (div, LMATRIX, RMATRIX)
+{
+  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+
+  return xdiv (v1.LDMATRIX_VALUE (), v2.RMATRIX_VALUE ());
+}
+#endif
+
+#ifdef DEFINELDIV
+DEFBINOP (ldiv, LMATRIX, RMATRIX)
+{
+  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+
+  return xleftdiv (v1.LMATRIX_VALUE (), v2.RDMATRIX_VALUE ());
+}
+#endif
+
+#define SHORT_NAME CONCAT3(LSHORT, _, RSHORT)
+#define INST_NAME CONCAT3(install_, SHORT_NAME, _ops)
+
+void
+INST_NAME (void)
+{
+  INSTALL_BINOP (op_add, OCTAVE_LMATRIX, OCTAVE_RMATRIX, add);
+  INSTALL_BINOP (op_sub, OCTAVE_LMATRIX, OCTAVE_RMATRIX, sub);
+  INSTALL_BINOP (op_mul, OCTAVE_LMATRIX, OCTAVE_RMATRIX, mul);
+#ifdef DEFINEDIV
+  INSTALL_BINOP (op_div, OCTAVE_LMATRIX, OCTAVE_RMATRIX, div);
+#endif
+#ifdef DEFINELDIV
+  INSTALL_BINOP (op_ldiv, OCTAVE_LMATRIX, OCTAVE_RMATRIX, ldiv);
+#endif
+#ifdef DEFINENULLASSIGNCONV
+  INSTALL_ASSIGNCONV (OCTAVE_LMATRIX, octave_null_matrix, OCTAVE_LDMATRIX);
+  INSTALL_ASSIGNCONV (OCTAVE_LMATRIX, octave_null_str, OCTAVE_LDMATRIX);
+  INSTALL_ASSIGNCONV (OCTAVE_LMATRIX, octave_null_sq_str, OCTAVE_LDMATRIX);
+#endif
+}
diff --git a/src/OPERATORS/op-dms-template.cc b/src/OPERATORS/op-dms-template.cc
new file mode 100644
index 0000000..b723cec
--- /dev/null
+++ b/src/OPERATORS/op-dms-template.cc
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ops.h"
+#include "gripes.h"
+#include "xpow.h"
+#include SINCLUDE
+#include MINCLUDE
+
+// matrix by diag matrix ops.
+
+#ifndef SCALARV
+#define SCALARV SCALAR
+#endif
+
+#ifndef MATRIXV
+#define MATRIXV MATRIX
+#endif
+
+DEFNDBINOP_OP (sdmadd, SCALAR, MATRIX, SCALARV, MATRIXV, +)
+DEFNDBINOP_OP (sdmsub, SCALAR, MATRIX, SCALARV, MATRIXV, -)
+DEFNDBINOP_OP (sdmmul, SCALAR, MATRIX, SCALARV, MATRIXV, *)
+DEFNDBINOP_OP (dmsadd, MATRIX, SCALAR, MATRIXV, SCALARV, +)
+DEFNDBINOP_OP (dmssub, MATRIX, SCALAR, MATRIXV, SCALARV, -)
+DEFNDBINOP_OP (dmsmul, MATRIX, SCALAR, MATRIXV, SCALARV, *)
+
+#define OCTAVE_MATRIX CONCAT2(octave_, MATRIX)
+#define OCTAVE_SCALAR CONCAT2(octave_, SCALAR)
+#define MATRIX_VALUE CONCAT2(MATRIXV, _value)
+#define SCALAR_VALUE CONCAT2(SCALARV, _value)
+
+template <class T>
+static T 
+gripe_if_zero (T x)
+{
+  if (x == T ())
+    gripe_divide_by_zero ();
+  return x;
+}
+
+DEFBINOP (dmsdiv, MATRIX, SCALAR)
+{
+  CAST_BINOP_ARGS (const OCTAVE_MATRIX&, const OCTAVE_SCALAR&);
+
+  return v1.MATRIX_VALUE () / gripe_if_zero (v2.SCALAR_VALUE ());
+}
+
+DEFBINOP (sdmldiv, SCALAR, MATRIX)
+{
+  CAST_BINOP_ARGS (const OCTAVE_SCALAR&, const OCTAVE_MATRIX&);
+
+  return v2.MATRIX_VALUE () / gripe_if_zero (v1.SCALAR_VALUE ());
+}
+
+DEFBINOP (dmspow, MATRIX, SCALAR)
+{
+  CAST_BINOP_ARGS (const OCTAVE_MATRIX&, const OCTAVE_SCALAR&);
+
+  return xpow (v1.MATRIX_VALUE (), v2.SCALAR_VALUE ());
+}
+
+#define SHORT_NAME CONCAT3(MSHORT, _, SSHORT)
+#define INST_NAME CONCAT3(install_, SHORT_NAME, _ops)
+
+void
+INST_NAME (void)
+{
+  INSTALL_BINOP (op_add, OCTAVE_MATRIX, OCTAVE_SCALAR, dmsadd);
+  INSTALL_BINOP (op_sub, OCTAVE_MATRIX, OCTAVE_SCALAR, dmssub);
+  INSTALL_BINOP (op_mul, OCTAVE_MATRIX, OCTAVE_SCALAR, dmsmul);
+  INSTALL_BINOP (op_div, OCTAVE_MATRIX, OCTAVE_SCALAR, dmsdiv);
+  INSTALL_BINOP (op_add, OCTAVE_SCALAR, OCTAVE_MATRIX, sdmadd);
+  INSTALL_BINOP (op_sub, OCTAVE_SCALAR, OCTAVE_MATRIX, sdmsub);
+  INSTALL_BINOP (op_mul, OCTAVE_SCALAR, OCTAVE_MATRIX, sdmmul);
+  INSTALL_BINOP (op_ldiv, OCTAVE_SCALAR, OCTAVE_MATRIX, sdmldiv);
+  INSTALL_BINOP (op_pow, OCTAVE_MATRIX, OCTAVE_SCALAR, dmspow);
+}
diff --git a/src/OPERATORS/op-double-conv.cc b/src/OPERATORS/op-double-conv.cc
new file mode 100644
index 0000000..72dd49c
--- /dev/null
+++ b/src/OPERATORS/op-double-conv.cc
@@ -0,0 +1,125 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-bool-sparse.h"
+#include "ov-range.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+// conversion ops
+
+DEFDBLCONVFN (int8_matrix_to_double_matrix, int8_matrix, int8_array)
+DEFDBLCONVFN (int16_matrix_to_double_matrix, int16_matrix, int16_array)
+DEFDBLCONVFN (int32_matrix_to_double_matrix, int32_matrix, int32_array)
+DEFDBLCONVFN (int64_matrix_to_double_matrix, int64_matrix, int64_array)
+
+DEFDBLCONVFN (uint8_matrix_to_double_matrix, uint8_matrix, uint8_array)
+DEFDBLCONVFN (uint16_matrix_to_double_matrix, uint16_matrix, uint16_array)
+DEFDBLCONVFN (uint32_matrix_to_double_matrix, uint32_matrix, uint32_array)
+DEFDBLCONVFN (uint64_matrix_to_double_matrix, uint64_matrix, uint64_array)
+
+DEFDBLCONVFN (int8_scalar_to_double_matrix, int8_scalar, int8_array)
+DEFDBLCONVFN (int16_scalar_to_double_matrix, int16_scalar, int16_array)
+DEFDBLCONVFN (int32_scalar_to_double_matrix, int32_scalar, int32_array)
+DEFDBLCONVFN (int64_scalar_to_double_matrix, int64_scalar, int64_array)
+
+DEFDBLCONVFN (uint8_scalar_to_double_matrix, uint8_scalar, uint8_array)
+DEFDBLCONVFN (uint16_scalar_to_double_matrix, uint16_scalar, uint16_array)
+DEFDBLCONVFN (uint32_scalar_to_double_matrix, uint32_scalar, uint32_array)
+DEFDBLCONVFN (uint64_scalar_to_double_matrix, uint64_scalar, uint64_array)
+
+DEFDBLCONVFN (bool_matrix_to_double_matrix, bool_matrix, bool_array)
+DEFDBLCONVFN (bool_scalar_to_double_matrix, bool, bool_array)
+
+DEFDBLCONVFN (sparse_matrix_to_double_matrix, sparse_matrix, array)
+DEFDBLCONVFN (sparse_bool_matrix_to_double_matrix, sparse_bool_matrix, array)
+
+DEFDBLCONVFN (range_to_double_matrix, range, array)
+
+DEFSTRDBLCONVFN(char_matrix_str_to_double_matrix, char_matrix_str)
+DEFSTRDBLCONVFN(char_matrix_sq_str_to_double_matrix, char_matrix_sq_str)
+
+DEFDBLCONVFN (double_scalar_to_double_matrix, scalar, array)
+
+void
+install_double_conv_ops (void)
+{
+  INSTALL_CONVOP (octave_int8_matrix, octave_matrix, int8_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_int16_matrix, octave_matrix, int16_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_int32_matrix, octave_matrix, int32_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_int64_matrix, octave_matrix, int64_matrix_to_double_matrix);
+
+  INSTALL_CONVOP (octave_uint8_matrix, octave_matrix, uint8_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_uint16_matrix, octave_matrix, uint16_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_uint32_matrix, octave_matrix, uint32_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_uint64_matrix, octave_matrix, uint64_matrix_to_double_matrix);
+
+  INSTALL_CONVOP (octave_int8_scalar, octave_matrix, int8_scalar_to_double_matrix);
+  INSTALL_CONVOP (octave_int16_scalar, octave_matrix, int16_scalar_to_double_matrix);
+  INSTALL_CONVOP (octave_int32_scalar, octave_matrix, int32_scalar_to_double_matrix);
+  INSTALL_CONVOP (octave_int64_scalar, octave_matrix, int64_scalar_to_double_matrix);
+
+  INSTALL_CONVOP (octave_uint8_scalar, octave_matrix, uint8_scalar_to_double_matrix);
+  INSTALL_CONVOP (octave_uint16_scalar, octave_matrix, uint16_scalar_to_double_matrix);
+  INSTALL_CONVOP (octave_uint32_scalar, octave_matrix, uint32_scalar_to_double_matrix);
+  INSTALL_CONVOP (octave_uint64_scalar, octave_matrix, uint64_scalar_to_double_matrix);
+
+  INSTALL_CONVOP (octave_bool_matrix, octave_matrix, bool_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_bool, octave_matrix, bool_scalar_to_double_matrix);
+
+  INSTALL_CONVOP (octave_sparse_matrix, octave_matrix, sparse_matrix_to_double_matrix);
+  INSTALL_CONVOP (octave_sparse_bool_matrix, octave_matrix, sparse_bool_matrix_to_double_matrix);
+
+  INSTALL_CONVOP (octave_range, octave_matrix, range_to_double_matrix);
+
+  INSTALL_CONVOP (octave_char_matrix_str, octave_matrix, char_matrix_str_to_double_matrix);
+  INSTALL_CONVOP (octave_char_matrix_sq_str, octave_matrix, char_matrix_sq_str_to_double_matrix);
+
+  INSTALL_CONVOP (octave_scalar, octave_matrix, double_scalar_to_double_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+p*/
diff --git a/src/OPERATORS/op-fcdm-fcdm.cc b/src/OPERATORS/op-fcdm-fcdm.cc
new file mode 100644
index 0000000..e100210
--- /dev/null
+++ b/src/OPERATORS/op-fcdm-fcdm.cc
@@ -0,0 +1,112 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-cx-diag.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix unary ops.
+
+DEFUNOP_OP (uplus, float_complex_diag_matrix, /* no-op */)
+DEFUNOP_OP (uminus, float_complex_diag_matrix, -)
+
+DEFUNOP (transpose, float_complex_diag_matrix)
+{
+  CAST_UNOP_ARG (const octave_float_complex_diag_matrix&);
+  return octave_value (v.float_complex_diag_matrix_value().transpose ());
+}
+
+DEFUNOP (hermitian, float_complex_diag_matrix)
+{
+  CAST_UNOP_ARG (const octave_float_complex_diag_matrix&);
+  return octave_value (v.float_complex_diag_matrix_value().hermitian ());
+}
+
+// matrix by matrix ops.
+
+DEFBINOP_OP (add, float_complex_diag_matrix, float_complex_diag_matrix, +)
+DEFBINOP_OP (sub, float_complex_diag_matrix, float_complex_diag_matrix, -)
+DEFBINOP_OP (mul, float_complex_diag_matrix, float_complex_diag_matrix, *)
+
+DEFBINOP (div, float_complex_diag_matrix, float_complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_diag_matrix&, const octave_float_complex_diag_matrix&);
+  
+  return xdiv (v1.float_complex_diag_matrix_value (), 
+               v2.float_complex_diag_matrix_value ());
+}
+
+DEFBINOP (ldiv, float_complex_diag_matrix, float_complex_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_diag_matrix&, const octave_float_complex_diag_matrix&);
+  
+  return xleftdiv (v1.float_complex_diag_matrix_value (),
+                   v2.float_complex_diag_matrix_value ());
+}
+
+CONVDECL (float_complex_diag_matrix_to_float_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_float_complex_diag_matrix&);
+
+  return new octave_float_complex_matrix (v.float_complex_matrix_value ());
+}
+
+CONVDECL (float_complex_diag_matrix_to_complex_diag_matrix)
+{
+  CAST_CONV_ARG (const octave_float_complex_diag_matrix&);
+
+  return new octave_complex_diag_matrix (v.complex_diag_matrix_value ());
+}
+
+void
+install_fcdm_fcdm_ops (void)
+{
+  INSTALL_UNOP (op_uplus, octave_float_complex_diag_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_float_complex_diag_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_float_complex_diag_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_float_complex_diag_matrix, hermitian);
+
+  INSTALL_BINOP (op_add, octave_float_complex_diag_matrix, octave_float_complex_diag_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_complex_diag_matrix, octave_float_complex_diag_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex_diag_matrix, octave_float_complex_diag_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_complex_diag_matrix, octave_float_complex_diag_matrix, div);
+  INSTALL_BINOP (op_ldiv, octave_float_complex_diag_matrix, octave_float_complex_diag_matrix, ldiv);
+
+  INSTALL_CONVOP (octave_float_complex_diag_matrix, octave_complex_diag_matrix, 
+                  float_complex_diag_matrix_to_complex_diag_matrix);
+  INSTALL_CONVOP (octave_float_complex_diag_matrix, octave_float_complex_matrix, 
+                  float_complex_diag_matrix_to_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_complex_diag_matrix, octave_float_complex_matrix, octave_float_complex_matrix);
+  INSTALL_WIDENOP (octave_float_complex_diag_matrix, octave_complex_diag_matrix, 
+                   float_complex_diag_matrix_to_complex_diag_matrix);
+}
diff --git a/src/OPERATORS/op-fcdm-fcm.cc b/src/OPERATORS/op-fcdm-fcm.cc
new file mode 100644
index 0000000..2465e74
--- /dev/null
+++ b/src/OPERATORS/op-fcdm-fcm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-cx-diag.h"
+#define RINCLUDE "ov-flt-cx-mat.h"
+
+#define LMATRIX float_complex_diag_matrix
+#define RMATRIX float_complex_matrix
+
+#define LSHORT fcdm
+#define RSHORT fcm
+
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fcdm-fcs.cc b/src/OPERATORS/op-fcdm-fcs.cc
new file mode 100644
index 0000000..f84c7b7
--- /dev/null
+++ b/src/OPERATORS/op-fcdm-fcs.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-flt-complex.h"
+#define MINCLUDE "ov-flt-cx-diag.h"
+
+#define SCALAR float_complex
+#define MATRIX float_complex_diag_matrix
+
+#define SSHORT fcs
+#define MSHORT fcdm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-fcdm-fdm.cc b/src/OPERATORS/op-fcdm-fdm.cc
new file mode 100644
index 0000000..5c75404
--- /dev/null
+++ b/src/OPERATORS/op-fcdm-fdm.cc
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#define LINCLUDE "ov-flt-cx-diag.h"
+#define RINCLUDE "ov-flt-re-diag.h"
+
+#define LMATRIX float_complex_diag_matrix
+#define RMATRIX float_diag_matrix
+#define RDMATRIX LMATRIX
+
+#define LSHORT fcdm
+#define RSHORT fdm
+
+#define DEFINEDIV
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fcdm-fm.cc b/src/OPERATORS/op-fcdm-fm.cc
new file mode 100644
index 0000000..8175e57
--- /dev/null
+++ b/src/OPERATORS/op-fcdm-fm.cc
@@ -0,0 +1,36 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-cx-diag.h"
+#define RINCLUDE "ov-flt-re-mat.h"
+
+#define LMATRIX float_complex_diag_matrix
+#define RMATRIX float_matrix
+#define RDMATRIX float_complex_matrix
+
+#define LSHORT fcdm
+#define RSHORT fm
+
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fcdm-fs.cc b/src/OPERATORS/op-fcdm-fs.cc
new file mode 100644
index 0000000..fd86f93
--- /dev/null
+++ b/src/OPERATORS/op-fcdm-fs.cc
@@ -0,0 +1,34 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-float.h"
+#define MINCLUDE "ov-flt-cx-diag.h"
+
+#define SCALAR float_scalar
+#define SCALARV float_complex
+#define MATRIX float_complex_diag_matrix
+
+#define SSHORT fs
+#define MSHORT fcdm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-fcm-fcdm.cc b/src/OPERATORS/op-fcm-fcdm.cc
new file mode 100644
index 0000000..9ecea86
--- /dev/null
+++ b/src/OPERATORS/op-fcm-fcdm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-cx-mat.h"
+#define RINCLUDE "ov-flt-cx-diag.h"
+
+#define LMATRIX float_complex_matrix
+#define RMATRIX float_complex_diag_matrix
+
+#define LSHORT fcm
+#define RSHORT fcdm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fcm-fcm.cc b/src/OPERATORS/op-fcm-fcm.cc
new file mode 100644
index 0000000..0efdd3d
--- /dev/null
+++ b/src/OPERATORS/op-fcm-fcm.cc
@@ -0,0 +1,283 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// unary complex matrix ops.
+
+DEFNDUNOP_OP (not, float_complex_matrix, float_complex_array, !)
+DEFNDUNOP_OP (uplus, float_complex_matrix, float_complex_array, /* no-op */)
+DEFNDUNOP_OP (uminus, float_complex_matrix, float_complex_array, -)
+
+DEFUNOP (transpose, float_complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_float_complex_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.float_complex_matrix_value().transpose ());
+}
+
+DEFUNOP (hermitian, float_complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_float_complex_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("complex-conjugate transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.float_complex_matrix_value().hermitian ());
+}
+
+DEFNCUNOP_METHOD (incr, float_complex_matrix, increment)
+DEFNCUNOP_METHOD (decr, float_complex_matrix, decrement)
+
+// complex matrix by complex matrix ops.
+
+DEFNDBINOP_OP (add, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, +)
+DEFNDBINOP_OP (sub, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, -)
+
+DEFBINOP_OP (mul, float_complex_matrix, float_complex_matrix, *)
+
+DEFBINOP (div, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_complex_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (), 
+			    v2.float_complex_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, float_complex_matrix, float_complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_complex_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (), 
+				     v2.float_complex_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP (trans_mul, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_complex_matrix&);
+  return octave_value(xgemm (true, false, v1.float_complex_matrix_value (), 
+                             false, false, v2.float_complex_matrix_value ()));
+}
+
+DEFBINOP (mul_trans, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_complex_matrix&);
+  return octave_value(xgemm (false, false, v1.float_complex_matrix_value (), 
+                             true, false, v2.float_complex_matrix_value ()));
+}
+
+DEFBINOP (herm_mul, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_complex_matrix&);
+  return octave_value(xgemm (true, true, v1.float_complex_matrix_value (), 
+                             false, false, v2.float_complex_matrix_value ()));
+}
+
+DEFBINOP (mul_herm, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_complex_matrix&);
+  return octave_value(xgemm (false, false, v1.float_complex_matrix_value (), 
+                             true, true, v2.float_complex_matrix_value ()));
+}
+
+DEFNDBINOP_FN (lt, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, product)
+DEFNDBINOP_FN (el_div, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, quotient)
+DEFNDBINOP_FN (el_pow, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_complex_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
+		   const octave_float_complex_matrix&);
+
+  return octave_value (quotient (v2.float_complex_array_value (), v1.float_complex_array_value ()));
+}
+
+DEFNDBINOP_FN (el_and, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, mx_el_or)
+
+DEFNDCATOP_FN (fcm_fcm, float_complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, concat)
+
+DEFNDCATOP_FN (cm_fcm, complex_matrix, float_complex_matrix, 
+	       float_complex_array, float_complex_array, concat)
+
+DEFNDCATOP_FN (fcm_cm, float_complex_matrix, complex_matrix, 
+	       float_complex_array, float_complex_array, concat)
+
+DEFNDASSIGNOP_FN (assign, float_complex_matrix, float_complex_matrix, 
+		  float_complex_array, assign)
+DEFNDASSIGNOP_FN (dbl_assign, float_complex_matrix, complex_matrix, 
+		  float_complex_array, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, float_complex_matrix, delete_elements)
+
+CONVDECL (float_complex_matrix_to_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_float_complex_matrix&);
+
+  return new octave_complex_matrix (ComplexNDArray (v.float_complex_array_value ()));
+}
+
+void
+install_fcm_fcm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_float_complex_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_float_complex_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_float_complex_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_float_complex_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_float_complex_matrix, hermitian);
+
+  INSTALL_NCUNOP (op_incr, octave_float_complex_matrix, incr);
+  INSTALL_NCUNOP (op_decr, octave_float_complex_matrix, decr);
+
+  INSTALL_BINOP (op_add, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, ldiv);
+  INSTALL_BINOP (op_trans_mul, octave_float_complex_matrix, 
+                 octave_float_complex_matrix, trans_mul);
+  INSTALL_BINOP (op_mul_trans, octave_float_complex_matrix, 
+                 octave_float_complex_matrix, mul_trans);
+  INSTALL_BINOP (op_herm_mul, octave_float_complex_matrix, 
+                 octave_float_complex_matrix, herm_mul);
+  INSTALL_BINOP (op_mul_herm, octave_float_complex_matrix, 
+                 octave_float_complex_matrix, mul_herm);
+  INSTALL_BINOP (op_lt, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex_matrix, 
+		 octave_float_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_complex_matrix, 
+		 octave_float_complex_matrix, fcm_fcm);
+  INSTALL_CATOP (octave_complex_matrix, 
+		 octave_float_complex_matrix, cm_fcm);
+  INSTALL_CATOP (octave_float_complex_matrix, 
+		 octave_complex_matrix, fcm_cm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+		    octave_float_complex_matrix, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+		    octave_complex_matrix, dbl_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+                    octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+                    octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+                    octave_null_sq_str, null_assign);
+
+  INSTALL_CONVOP (octave_float_complex_matrix, octave_complex_matrix, 
+		  float_complex_matrix_to_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcm-fcs.cc b/src/OPERATORS/op-fcm-fcs.cc
new file mode 100644
index 0000000..0f0a9ee
--- /dev/null
+++ b/src/OPERATORS/op-fcm-fcs.cc
@@ -0,0 +1,185 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-complex.h"
+#include "ov-complex.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex matrix by complex scalar ops.
+
+DEFNDBINOP_OP (add, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, +)
+DEFNDBINOP_OP (sub, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, -)
+DEFNDBINOP_OP (mul, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, *)
+
+DEFBINOP (div, float_complex_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_array_value () / d);
+}
+
+DEFBINOP_FN (pow, float_complex_matrix, float_complex, xpow)
+
+DEFBINOP (ldiv, float_complex_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_complex&);
+
+  FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
+  FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  FloatComplexMatrix ret = xleftdiv (m1, m2, typ);
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_lt)
+DEFNDBINOP_FN (le, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_le)
+DEFNDBINOP_FN (eq, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_eq)
+DEFNDBINOP_FN (ge, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_ge)
+DEFNDBINOP_FN (gt, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_gt)
+DEFNDBINOP_FN (ne, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, *)
+
+DEFBINOP (el_div, float_complex_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, elem_xpow)
+
+DEFBINOP (el_ldiv, float_complex_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_complex&);
+
+  return x_el_div (v2.float_complex_value (), v1.float_complex_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex, mx_el_or)
+
+DEFNDCATOP_FN (fcm_fcs, float_complex_matrix, float_complex, 
+	       float_complex_array, float_complex_array, concat)
+
+DEFNDCATOP_FN (cm_fcs, complex_matrix, float_complex, 
+	       float_complex_array, float_complex_array, concat)
+
+DEFNDCATOP_FN (fcm_cs, float_complex_matrix, complex, 
+	       float_complex_array, float_complex_array, concat)
+
+DEFNDASSIGNOP_FN (assign, float_complex_matrix, float_complex, 
+		  float_complex, assign)
+DEFNDASSIGNOP_FN (dbl_assign, complex_matrix, float_complex, 
+		  complex, assign)
+
+void
+install_fcm_fcs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_complex_matrix, 
+		 octave_float_complex, add);
+  INSTALL_BINOP (op_sub, octave_float_complex_matrix, 
+		 octave_float_complex, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex_matrix, 
+		 octave_float_complex, mul);
+  INSTALL_BINOP (op_div, octave_float_complex_matrix, 
+		 octave_float_complex, div);
+  INSTALL_BINOP (op_pow, octave_float_complex_matrix, 
+		 octave_float_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex_matrix, 
+		 octave_float_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex_matrix, octave_float_complex, lt);
+  INSTALL_BINOP (op_le, octave_float_complex_matrix, octave_float_complex, le);
+  INSTALL_BINOP (op_eq, octave_float_complex_matrix, octave_float_complex, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex_matrix, octave_float_complex, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex_matrix, octave_float_complex, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex_matrix, octave_float_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex_matrix, 
+		 octave_float_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex_matrix, 
+		 octave_float_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex_matrix, 
+		 octave_float_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex_matrix, 
+		 octave_float_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex_matrix, 
+		 octave_float_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex_matrix, 
+		 octave_float_complex, el_or);
+
+  INSTALL_CATOP (octave_float_complex_matrix, octave_float_complex, fcm_fcs);
+  INSTALL_CATOP (octave_complex_matrix, octave_float_complex, cm_fcs);
+  INSTALL_CATOP (octave_float_complex_matrix, octave_complex, fcm_cs);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+		    octave_float_complex, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, 
+		    octave_float_complex, dbl_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcm-fdm.cc b/src/OPERATORS/op-fcm-fdm.cc
new file mode 100644
index 0000000..2472b1d
--- /dev/null
+++ b/src/OPERATORS/op-fcm-fdm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-cx-mat.h"
+#define RINCLUDE "ov-flt-re-diag.h"
+
+#define LMATRIX float_complex_matrix
+#define RMATRIX float_diag_matrix
+
+#define LSHORT fcm
+#define RSHORT fdm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fcm-fm.cc b/src/OPERATORS/op-fcm-fm.cc
new file mode 100644
index 0000000..119c7f9
--- /dev/null
+++ b/src/OPERATORS/op-fcm-fm.cc
@@ -0,0 +1,175 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-fcm-fm.h"
+#include "mx-fm-fcm.h"
+#include "mx-fcnda-fnda.h"
+#include "mx-fnda-fcnda.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex matrix by matrix ops.
+
+DEFNDBINOP_OP (add, float_complex_matrix, float_matrix, float_complex_array, float_array, +)
+DEFNDBINOP_OP (sub, float_complex_matrix, float_matrix, float_complex_array, float_array, -)
+
+DEFBINOP_OP (mul, float_complex_matrix, float_matrix, *)
+
+DEFBINOP (div, float_complex_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (), 
+				 v2.float_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+
+DEFBINOPX (pow, float_complex_matrix, float_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, float_complex_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (), 
+				     v2.float_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, product)
+DEFNDBINOP_FN (el_div, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, quotient)
+DEFNDBINOP_FN (el_pow, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_complex_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, 
+		   const octave_float_matrix&);
+
+  return quotient (v2.float_array_value (), v1.float_complex_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, mx_el_or)
+
+DEFNDCATOP_FN (fcm_fm, float_complex_matrix, float_matrix, 
+	       float_complex_array, float_array, concat)
+
+DEFNDCATOP_FN (cm_fm, complex_matrix, float_matrix, 
+	       float_complex_array, float_array, concat)
+
+DEFNDCATOP_FN (fcm_m, float_complex_matrix, matrix, 
+	       float_complex_array, float_array, concat)
+
+DEFNDASSIGNOP_FN (assign, float_complex_matrix, float_matrix, 
+		  float_complex_array, assign)
+DEFNDASSIGNOP_FN (dbl_assign, complex_matrix, float_matrix, 
+		  complex_array, assign)
+
+void
+install_fcm_fm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_complex_matrix, octave_float_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_complex_matrix, octave_float_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex_matrix, octave_float_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_complex_matrix, octave_float_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_complex_matrix, octave_float_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex_matrix, 
+		 octave_float_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex_matrix, octave_float_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_complex_matrix, octave_float_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_complex_matrix, octave_float_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex_matrix, octave_float_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex_matrix, octave_float_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex_matrix, octave_float_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex_matrix, 
+		 octave_float_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex_matrix, 
+		 octave_float_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex_matrix, 
+		 octave_float_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex_matrix, 
+		 octave_float_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex_matrix, 
+		 octave_float_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex_matrix, 
+		 octave_float_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_complex_matrix, octave_float_matrix, fcm_fm);
+  INSTALL_CATOP (octave_complex_matrix, octave_float_matrix, cm_fm);
+  INSTALL_CATOP (octave_float_complex_matrix, octave_matrix, fcm_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+		    octave_float_matrix, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, 
+		    octave_float_matrix, dbl_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcm-fs.cc b/src/OPERATORS/op-fcm-fs.cc
new file mode 100644
index 0000000..e7c07c5
--- /dev/null
+++ b/src/OPERATORS/op-fcm-fs.cc
@@ -0,0 +1,169 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-cm-s.h"
+#include "mx-cnda-s.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-float.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex matrix by scalar ops.
+
+DEFNDBINOP_OP (add, float_complex_matrix, float_scalar, float_complex_array, float_scalar, +)
+DEFNDBINOP_OP (sub, float_complex_matrix, float_scalar, float_complex_array, float_scalar, -)
+DEFNDBINOP_OP (mul, float_complex_matrix, float_scalar, float_complex_array, float_scalar, *)
+
+DEFBINOP (div, float_complex_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_array_value () / d);
+}
+
+DEFBINOP_FN (pow, float_complex_matrix, float_scalar, xpow)
+
+DEFBINOP (ldiv, float_complex_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_scalar&);
+
+  FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
+  FloatMatrix m2 = v2.float_matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  FloatComplexMatrix ret = xleftdiv (m1, m2, typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_lt)
+DEFNDBINOP_FN (le, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_le)
+DEFNDBINOP_FN (eq, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_eq)
+DEFNDBINOP_FN (ge, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_ge)
+DEFNDBINOP_FN (gt, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_gt)
+DEFNDBINOP_FN (ne, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, *)
+
+DEFBINOP (el_div, float_complex_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, elem_xpow)
+
+DEFBINOP (el_ldiv, float_complex_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex_matrix&, const octave_float_scalar&);
+
+  return x_el_div (v2.float_value (), v1.float_complex_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_complex_matrix, float_scalar, float_complex_array, 
+	       float_scalar, mx_el_or)
+
+DEFNDCATOP_FN (fcm_fs, float_complex_matrix, float_scalar, float_complex_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (cm_fs, complex_matrix, float_scalar, float_complex_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (fcm_s, float_complex_matrix, scalar, float_complex_array, 
+	       float_array, concat)
+
+DEFNDASSIGNOP_FN (assign, float_complex_matrix, float_scalar, float_complex_array, assign)
+DEFNDASSIGNOP_FN (dbl_assign, complex_matrix, float_scalar, complex_array, assign)
+
+void
+install_fcm_fs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_complex_matrix, octave_float_scalar, add);
+  INSTALL_BINOP (op_sub, octave_float_complex_matrix, octave_float_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex_matrix, octave_float_scalar, mul);
+  INSTALL_BINOP (op_div, octave_float_complex_matrix, octave_float_scalar, div);
+  INSTALL_BINOP (op_pow, octave_float_complex_matrix, octave_float_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex_matrix, octave_float_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex_matrix, octave_float_scalar, lt);
+  INSTALL_BINOP (op_le, octave_float_complex_matrix, octave_float_scalar, le);
+  INSTALL_BINOP (op_eq, octave_float_complex_matrix, octave_float_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex_matrix, octave_float_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex_matrix, octave_float_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex_matrix, octave_float_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex_matrix, octave_float_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex_matrix, octave_float_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex_matrix, octave_float_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex_matrix, octave_float_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex_matrix, octave_float_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex_matrix, octave_float_scalar, el_or);
+
+  INSTALL_CATOP (octave_float_complex_matrix, octave_float_scalar, fcm_fs);
+  INSTALL_CATOP (octave_complex_matrix, octave_float_scalar, cm_fs);
+  INSTALL_CATOP (octave_float_complex_matrix, octave_scalar, fcm_s);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, 
+		    octave_float_scalar, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, 
+		    octave_float_scalar, dbl_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcm-pm.cc b/src/OPERATORS/op-fcm-pm.cc
new file mode 100644
index 0000000..cdfc70a
--- /dev/null
+++ b/src/OPERATORS/op-fcm-pm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-flt-cx-mat.h"
+
+#define LMATRIX float_complex_matrix
+#define RMATRIX perm_matrix
+
+#define LSHORT fcm
+#define RSHORT pm
+
+#define RIGHT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-fcs-fcm.cc b/src/OPERATORS/op-fcs-fcm.cc
new file mode 100644
index 0000000..f081cac
--- /dev/null
+++ b/src/OPERATORS/op-fcs-fcm.cc
@@ -0,0 +1,159 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex scalar by complex matrix ops.
+
+DEFNDBINOP_OP (add, float_complex, float_complex_matrix, float_complex, float_complex_array, +)
+DEFNDBINOP_OP (sub, float_complex, float_complex_matrix, float_complex, float_complex_array, -)
+DEFNDBINOP_OP (mul, float_complex, float_complex_matrix, float_complex, float_complex_array, *)
+
+DEFBINOP (div, float_complex, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex_matrix&);
+
+  FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
+  FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  FloatComplexMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, float_complex, float_complex_matrix, xpow)
+
+DEFBINOP (ldiv, float_complex, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex_matrix&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, *)
+DEFNDBINOP_FN (el_div, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, x_el_div)
+DEFNDBINOP_FN (el_pow, float_complex, float_complex_matrix, float_complex, 
+	       float_complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_complex, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex_matrix&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, float_complex, float_complex_matrix, float_complex, float_complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_complex, float_complex_matrix, float_complex, float_complex_array, mx_el_or)
+
+DEFNDCATOP_FN (fcs_fcm, float_complex, float_complex_matrix, float_complex_array, float_complex_array, concat)
+
+DEFNDCATOP_FN (cs_fcm, complex, float_complex_matrix, float_complex_array, float_complex_array, concat)
+
+DEFNDCATOP_FN (fcs_cm, float_complex, complex_matrix, float_complex_array, float_complex_array, concat)
+
+DEFCONV (float_complex_matrix_conv, float_complex, float_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_float_complex&);
+
+  return new octave_float_complex_matrix (v.float_complex_matrix_value ());
+}
+
+void
+install_fcs_fcm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_complex, octave_float_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_complex, octave_float_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex, octave_float_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_complex, octave_float_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_complex, octave_float_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex, octave_float_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex, octave_float_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_complex, octave_float_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_complex, octave_float_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex, octave_float_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex, octave_float_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex, octave_float_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex, octave_float_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex, octave_float_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex, octave_float_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex, octave_float_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex, octave_float_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex, octave_float_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_complex, octave_float_complex_matrix, fcs_fcm);
+  INSTALL_CATOP (octave_complex, octave_float_complex_matrix, cs_fcm);
+  INSTALL_CATOP (octave_float_complex, octave_complex_matrix, fcs_cm);
+
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_float_complex_matrix, octave_float_complex_matrix);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_float_complex_matrix, octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_float_complex, octave_float_complex_matrix, float_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcs-fcs.cc b/src/OPERATORS/op-fcs-fcs.cc
new file mode 100644
index 0000000..021b6fc
--- /dev/null
+++ b/src/OPERATORS/op-fcs-fcs.cc
@@ -0,0 +1,248 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// unary complex scalar ops.
+
+DEFUNOP (not, float_complex)
+{
+  CAST_UNOP_ARG (const octave_float_complex&);
+
+  return octave_value (v.float_complex_value () == 0.0);
+}
+
+DEFUNOP_OP (uplus, float_complex, /* no-op */)
+DEFUNOP_OP (uminus, float_complex, -)
+DEFUNOP_OP (transpose, float_complex, /* no-op */)
+
+DEFUNOP (hermitian, float_complex)
+{
+  CAST_UNOP_ARG (const octave_float_complex&);
+
+  return octave_value (conj (v.float_complex_value ()));
+}
+
+DEFNCUNOP_METHOD (incr, float_complex, increment)
+DEFNCUNOP_METHOD (decr, float_complex, decrement)
+
+// complex scalar by complex scalar ops.
+
+DEFBINOP_OP (add, float_complex, float_complex, +)
+DEFBINOP_OP (sub, float_complex, float_complex, -)
+DEFBINOP_OP (mul, float_complex, float_complex, *)
+
+DEFBINOP (div, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_value () / d);
+}
+
+DEFBINOP_FN (pow, float_complex, float_complex, xpow)
+
+DEFBINOP (ldiv, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_value () / d);
+}
+
+DEFBINOP (lt, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return real (v1.float_complex_value ()) < real (v2.float_complex_value ());
+}
+
+DEFBINOP (le, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return real (v1.float_complex_value ()) <= real (v2.float_complex_value ());
+}
+
+DEFBINOP (eq, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return v1.float_complex_value () == v2.float_complex_value ();
+}
+
+DEFBINOP (ge, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return real (v1.float_complex_value ()) >= real (v2.float_complex_value ());
+}
+
+DEFBINOP (gt, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return real (v1.float_complex_value ()) > real (v2.float_complex_value ());
+}
+
+DEFBINOP (ne, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return v1.float_complex_value () != v2.float_complex_value ();
+}
+
+DEFBINOP_OP (el_mul, float_complex, float_complex, *)
+
+DEFBINOP (el_div, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_value () / d);
+}
+
+DEFBINOP_FN (el_pow, float_complex, float_complex, xpow)
+
+DEFBINOP (el_ldiv, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_value () / d);
+}
+
+DEFBINOP (el_and, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return (v1.float_complex_value () != static_cast<float>(0.0) && 
+	  v2.float_complex_value () != static_cast<float>(0.0));
+}
+
+DEFBINOP (el_or, float_complex, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+
+  return (v1.float_complex_value () != static_cast<float>(0.0) || 
+	  v2.float_complex_value () != static_cast<float>(0.0));
+}
+
+DEFNDCATOP_FN (fcs_fcs, float_complex, float_complex, float_complex_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (cs_fcs, complex, float_complex, float_complex_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (fcs_cs, float_complex, complex, float_complex_array, 
+	       float_complex_array, concat)
+
+CONVDECL (float_complex_to_complex)
+{
+  CAST_CONV_ARG (const octave_float_complex&);
+
+  return new octave_complex_matrix (ComplexMatrix (1, 1, static_cast<Complex>(v.float_complex_value ())));
+}
+
+void
+install_fcs_fcs_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_float_complex, not);
+  INSTALL_UNOP (op_uplus, octave_float_complex, uplus);
+  INSTALL_UNOP (op_uminus, octave_float_complex, uminus);
+  INSTALL_UNOP (op_transpose, octave_float_complex, transpose);
+  INSTALL_UNOP (op_hermitian, octave_float_complex, hermitian);
+
+  INSTALL_NCUNOP (op_incr, octave_float_complex, incr);
+  INSTALL_NCUNOP (op_decr, octave_float_complex, decr);
+
+  INSTALL_BINOP (op_add, octave_float_complex, octave_float_complex, add);
+  INSTALL_BINOP (op_sub, octave_float_complex, octave_float_complex, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex, octave_float_complex, mul);
+  INSTALL_BINOP (op_div, octave_float_complex, octave_float_complex, div);
+  INSTALL_BINOP (op_pow, octave_float_complex, octave_float_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex, octave_float_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex, octave_float_complex, lt);
+  INSTALL_BINOP (op_le, octave_float_complex, octave_float_complex, le);
+  INSTALL_BINOP (op_eq, octave_float_complex, octave_float_complex, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex, octave_float_complex, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex, octave_float_complex, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex, octave_float_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex, octave_float_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex, octave_float_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex, octave_float_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex, octave_float_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex, octave_float_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex, octave_float_complex, el_or);
+
+  INSTALL_CATOP (octave_float_complex, octave_float_complex, fcs_fcs);
+  INSTALL_CATOP (octave_complex, octave_float_complex, cs_fcs);
+  INSTALL_CATOP (octave_float_complex, octave_complex, fcs_cs);
+
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_float_complex, octave_float_complex_matrix);
+
+  INSTALL_ASSIGNCONV (octave_complex, octave_float_complex, octave_complex_matrix);
+
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_null_matrix, octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_null_str, octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_null_sq_str, octave_float_complex_matrix);
+
+  INSTALL_CONVOP (octave_float_complex, octave_complex_matrix, 
+		  float_complex_to_complex);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcs-fm.cc b/src/OPERATORS/op-fcs-fm.cc
new file mode 100644
index 0000000..181842b
--- /dev/null
+++ b/src/OPERATORS/op-fcs-fm.cc
@@ -0,0 +1,163 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-cs-nda.h"
+#include "mx-nda-cs.h"
+#include "mx-cs-nda.h"
+#include "mx-nda-cs.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex scalar by matrix ops.
+
+DEFNDBINOP_OP (add, float_complex, float_matrix, float_complex, float_array, +)
+DEFNDBINOP_OP (sub, float_complex, float_matrix, float_complex, float_array, -)
+DEFNDBINOP_OP (mul, float_complex, float_matrix, float_complex, float_array, *)
+
+DEFBINOP (div, float_complex, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_matrix&);
+
+  FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
+  FloatMatrix m2 = v2.float_matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  FloatComplexMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, float_complex, float_matrix, xpow)
+
+DEFBINOP (ldiv, float_complex, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_matrix&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_complex, float_matrix, float_complex, 
+	       float_array, *)
+DEFNDBINOP_FN (el_div, float_complex, float_matrix, float_complex, 
+	       float_array, x_el_div)
+DEFNDBINOP_FN (el_pow, float_complex, float_matrix, float_complex, 
+	       float_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_complex, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_matrix&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_complex, float_matrix, float_complex, 
+	       float_array, mx_el_or)
+
+DEFNDCATOP_FN (fcs_fm, float_complex, float_matrix, float_complex_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (cs_fm, complex, float_matrix, float_complex_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (fcs_m, float_complex, matrix, float_complex_array, 
+	       float_array, concat)
+
+void
+install_fcs_fm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_complex, octave_float_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_complex, octave_float_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex, octave_float_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_complex, octave_float_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_complex, octave_float_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex, octave_float_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex, octave_float_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_complex, octave_float_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_complex, octave_float_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex, octave_float_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex, octave_float_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex, octave_float_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex, octave_float_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex, octave_float_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex, octave_float_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex, octave_float_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex, octave_float_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex, octave_float_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_complex, octave_float_matrix, fcs_fm);
+  INSTALL_CATOP (octave_complex, octave_float_matrix, cs_fm);
+  INSTALL_CATOP (octave_float_complex, octave_matrix, fcs_m);
+
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_float_matrix, 
+		      octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_complex, octave_float_matrix, 
+		      octave_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fcs-fs.cc b/src/OPERATORS/op-fcs-fs.cc
new file mode 100644
index 0000000..ce82fd9
--- /dev/null
+++ b/src/OPERATORS/op-fcs-fs.cc
@@ -0,0 +1,205 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-float.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// complex scalar by scalar ops.
+
+DEFBINOP_OP (add, float_complex, float_scalar, +)
+DEFBINOP_OP (sub, float_complex, float_scalar, -)
+DEFBINOP_OP (mul, float_complex, float_scalar, *)
+
+DEFBINOP (div, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_value () / d);
+}
+
+DEFBINOP_FN (pow, float_complex, float_scalar, xpow)
+
+DEFBINOP (ldiv, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_value () / d);
+}
+
+DEFBINOP (lt, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return real (v1.float_complex_value ()) < v2.float_value ();
+}
+
+DEFBINOP (le, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return real (v1.float_complex_value ()) <= v2.float_value ();
+}
+
+DEFBINOP (eq, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return v1.float_complex_value () == v2.float_value ();
+}
+
+DEFBINOP (ge, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return real (v1.float_complex_value ()) >= v2.float_value ();
+}
+
+DEFBINOP (gt, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return real (v1.float_complex_value ()) > v2.float_value ();
+}
+
+DEFBINOP (ne, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return v1.float_complex_value () != v2.float_value ();
+}
+
+DEFBINOP_OP (el_mul, float_complex, float_scalar, *)
+
+DEFBINOP (el_div, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_complex_value () / d);
+}
+
+DEFBINOP_FN (el_pow, float_complex, float_scalar, xpow)
+
+DEFBINOP (el_ldiv, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  FloatComplex d = v1.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_value () / d);
+}
+
+DEFBINOP (el_and, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return (v1.float_complex_value () != static_cast<float>(0.0) && 
+	  v2.float_value ());
+}
+
+DEFBINOP (el_or, float_complex, float)
+{
+  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+
+  return (v1.float_complex_value () != static_cast<float>(0.0) || 
+	  v2.float_value ());
+}
+
+DEFNDCATOP_FN (fcs_fs, float_complex, float_scalar, float_complex_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (cs_fs, complex, float_scalar, float_complex_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (fcs_s, float_complex, scalar, float_complex_array, 
+	       float_array, concat)
+
+void
+install_fcs_fs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_complex, octave_float_scalar, add);
+  INSTALL_BINOP (op_sub, octave_float_complex, octave_float_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_float_complex, octave_float_scalar, mul);
+  INSTALL_BINOP (op_div, octave_float_complex, octave_float_scalar, div);
+  INSTALL_BINOP (op_pow, octave_float_complex, octave_float_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_complex, octave_float_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_complex, octave_float_scalar, lt);
+  INSTALL_BINOP (op_le, octave_float_complex, octave_float_scalar, le);
+  INSTALL_BINOP (op_eq, octave_float_complex, octave_float_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_float_complex, octave_float_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_float_complex, octave_float_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_float_complex, octave_float_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_complex, octave_float_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_complex, octave_float_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_complex, octave_float_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_complex, octave_float_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_complex, octave_float_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_complex, octave_float_scalar, el_or);
+
+  INSTALL_CATOP (octave_float_complex, octave_float_scalar, fcs_fs);
+  INSTALL_CATOP (octave_complex, octave_float_scalar, cs_fs);
+  INSTALL_CATOP (octave_float_complex, octave_scalar, fcs_s);
+
+  INSTALL_ASSIGNCONV (octave_float_complex, octave_float_scalar, 
+		      octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_complex, octave_float_scalar, 
+		      octave_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fdm-fcdm.cc b/src/OPERATORS/op-fdm-fcdm.cc
new file mode 100644
index 0000000..ea57d32
--- /dev/null
+++ b/src/OPERATORS/op-fdm-fcdm.cc
@@ -0,0 +1,37 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-re-diag.h"
+#define RINCLUDE "ov-flt-cx-diag.h"
+
+#define LMATRIX float_diag_matrix
+#define RMATRIX float_complex_diag_matrix
+#define LDMATRIX RMATRIX
+
+#define LSHORT fdm
+#define RSHORT fcdm
+
+#define DEFINEDIV
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fdm-fcm.cc b/src/OPERATORS/op-fdm-fcm.cc
new file mode 100644
index 0000000..ad63bba
--- /dev/null
+++ b/src/OPERATORS/op-fdm-fcm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-re-diag.h"
+#define RINCLUDE "ov-flt-cx-mat.h"
+
+#define LMATRIX float_diag_matrix
+#define RMATRIX float_complex_matrix
+
+#define LSHORT fdm
+#define RSHORT fcm
+
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fdm-fcs.cc b/src/OPERATORS/op-fdm-fcs.cc
new file mode 100644
index 0000000..8311bc2
--- /dev/null
+++ b/src/OPERATORS/op-fdm-fcs.cc
@@ -0,0 +1,34 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-flt-complex.h"
+#define MINCLUDE "ov-flt-re-diag.h"
+
+#define SCALAR float_complex
+#define MATRIX float_diag_matrix
+#define MATRIXV float_complex_diag_matrix
+
+#define SSHORT fcs
+#define MSHORT fdm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-fdm-fdm.cc b/src/OPERATORS/op-fdm-fdm.cc
new file mode 100644
index 0000000..8df6525
--- /dev/null
+++ b/src/OPERATORS/op-fdm-fdm.cc
@@ -0,0 +1,103 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-flt-re-mat.h"
+#include "ov-flt-re-diag.h"
+#include "ov-re-diag.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix unary ops.
+
+DEFUNOP_OP (uplus, float_diag_matrix, /* no-op */)
+DEFUNOP_OP (uminus, float_diag_matrix, -)
+
+DEFUNOP (transpose, float_diag_matrix)
+{
+  CAST_UNOP_ARG (const octave_float_diag_matrix&);
+  return octave_value (v.float_diag_matrix_value().transpose ());
+}
+
+// matrix by matrix ops.
+
+DEFBINOP_OP (add, float_diag_matrix, float_diag_matrix, +)
+DEFBINOP_OP (sub, float_diag_matrix, float_diag_matrix, -)
+DEFBINOP_OP (mul, float_diag_matrix, float_diag_matrix, *)
+
+DEFBINOP (div, float_diag_matrix, float_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_diag_matrix&, const octave_float_diag_matrix&);
+  
+  return xdiv (v1.float_diag_matrix_value (), 
+               v2.float_diag_matrix_value ());
+}
+
+DEFBINOP (ldiv, float_diag_matrix, float_diag_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_diag_matrix&, const octave_float_diag_matrix&);
+  
+  return xleftdiv (v1.float_diag_matrix_value (),
+                   v2.float_diag_matrix_value ());
+}
+
+CONVDECL (float_diag_matrix_to_diag_matrix)
+{
+  CAST_CONV_ARG (const octave_float_diag_matrix&);
+
+  return new octave_diag_matrix (v.diag_matrix_value ());
+}
+
+CONVDECL (float_diag_matrix_to_float_matrix)
+{
+  CAST_CONV_ARG (const octave_float_diag_matrix&);
+
+  return new octave_float_matrix (v.float_matrix_value ());
+}
+
+void
+install_fdm_fdm_ops (void)
+{
+  INSTALL_UNOP (op_uplus, octave_float_diag_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_float_diag_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_float_diag_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_float_diag_matrix, transpose);
+
+  INSTALL_BINOP (op_add, octave_float_diag_matrix, octave_float_diag_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_diag_matrix, octave_float_diag_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_diag_matrix, octave_float_diag_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_diag_matrix, octave_float_diag_matrix, div);
+  INSTALL_BINOP (op_ldiv, octave_float_diag_matrix, octave_float_diag_matrix, ldiv);
+
+  INSTALL_CONVOP (octave_float_diag_matrix, octave_float_matrix, float_diag_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_float_diag_matrix, octave_diag_matrix, float_diag_matrix_to_diag_matrix);
+  INSTALL_ASSIGNCONV (octave_float_diag_matrix, octave_float_matrix, octave_float_matrix);
+  INSTALL_WIDENOP (octave_float_diag_matrix, octave_float_matrix, float_diag_matrix_to_float_matrix);
+}
diff --git a/src/OPERATORS/op-fdm-fm.cc b/src/OPERATORS/op-fdm-fm.cc
new file mode 100644
index 0000000..8ceeafa
--- /dev/null
+++ b/src/OPERATORS/op-fdm-fm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-re-diag.h"
+#define RINCLUDE "ov-flt-re-mat.h"
+
+#define LMATRIX float_diag_matrix
+#define RMATRIX float_matrix
+
+#define LSHORT fdm
+#define RSHORT fm
+
+#define DEFINELDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fdm-fs.cc b/src/OPERATORS/op-fdm-fs.cc
new file mode 100644
index 0000000..214425a
--- /dev/null
+++ b/src/OPERATORS/op-fdm-fs.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define SINCLUDE "ov-float.h"
+#define MINCLUDE "ov-flt-re-diag.h"
+
+#define SCALAR float_scalar
+#define MATRIX float_diag_matrix
+
+#define SSHORT fs
+#define MSHORT fdm
+
+#include "op-dms-template.cc"
+
diff --git a/src/OPERATORS/op-float-conv.cc b/src/OPERATORS/op-float-conv.cc
new file mode 100644
index 0000000..69b7803
--- /dev/null
+++ b/src/OPERATORS/op-float-conv.cc
@@ -0,0 +1,117 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-range.h"
+#include "ov-float.h"
+#include "ov-flt-re-mat.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+// conversion ops
+
+DEFFLTCONVFN (int8_matrix_to_float_matrix, int8_matrix, int8_array)
+DEFFLTCONVFN (int16_matrix_to_float_matrix, int16_matrix, int16_array)
+DEFFLTCONVFN (int32_matrix_to_float_matrix, int32_matrix, int32_array)
+DEFFLTCONVFN (int64_matrix_to_float_matrix, int64_matrix, int64_array)
+
+DEFFLTCONVFN (uint8_matrix_to_float_matrix, uint8_matrix, uint8_array)
+DEFFLTCONVFN (uint16_matrix_to_float_matrix, uint16_matrix, uint16_array)
+DEFFLTCONVFN (uint32_matrix_to_float_matrix, uint32_matrix, uint32_array)
+DEFFLTCONVFN (uint64_matrix_to_float_matrix, uint64_matrix, uint64_array)
+
+DEFFLTCONVFN (int8_scalar_to_float_matrix, int8_scalar, int8_array)
+DEFFLTCONVFN (int16_scalar_to_float_matrix, int16_scalar, int16_array)
+DEFFLTCONVFN (int32_scalar_to_float_matrix, int32_scalar, int32_array)
+DEFFLTCONVFN (int64_scalar_to_float_matrix, int64_scalar, int64_array)
+
+DEFFLTCONVFN (uint8_scalar_to_float_matrix, uint8_scalar, uint8_array)
+DEFFLTCONVFN (uint16_scalar_to_float_matrix, uint16_scalar, uint16_array)
+DEFFLTCONVFN (uint32_scalar_to_float_matrix, uint32_scalar, uint32_array)
+DEFFLTCONVFN (uint64_scalar_to_float_matrix, uint64_scalar, uint64_array)
+
+DEFFLTCONVFN (bool_matrix_to_float_matrix, bool_matrix, bool_array)
+DEFFLTCONVFN (bool_scalar_to_float_matrix, bool, bool_array)
+
+DEFFLTCONVFN (range_to_float_matrix, range, array)
+
+DEFSTRFLTCONVFN(char_matrix_str_to_float_matrix, char_matrix_str)
+DEFSTRFLTCONVFN(char_matrix_sq_str_to_float_matrix, char_matrix_sq_str)
+
+DEFFLTCONVFN (float_scalar_to_float_matrix, scalar, array)
+
+void
+install_float_conv_ops (void)
+{
+  INSTALL_CONVOP (octave_int8_matrix, octave_float_matrix, int8_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_int16_matrix, octave_float_matrix, int16_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_int32_matrix, octave_float_matrix, int32_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_int64_matrix, octave_float_matrix, int64_matrix_to_float_matrix);
+
+  INSTALL_CONVOP (octave_uint8_matrix, octave_float_matrix, uint8_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_uint16_matrix, octave_float_matrix, uint16_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_uint32_matrix, octave_float_matrix, uint32_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_uint64_matrix, octave_float_matrix, uint64_matrix_to_float_matrix);
+
+  INSTALL_CONVOP (octave_int8_scalar, octave_float_matrix, int8_scalar_to_float_matrix);
+  INSTALL_CONVOP (octave_int16_scalar, octave_float_matrix, int16_scalar_to_float_matrix);
+  INSTALL_CONVOP (octave_int32_scalar, octave_float_matrix, int32_scalar_to_float_matrix);
+  INSTALL_CONVOP (octave_int64_scalar, octave_float_matrix, int64_scalar_to_float_matrix);
+
+  INSTALL_CONVOP (octave_uint8_scalar, octave_float_matrix, uint8_scalar_to_float_matrix);
+  INSTALL_CONVOP (octave_uint16_scalar, octave_float_matrix, uint16_scalar_to_float_matrix);
+  INSTALL_CONVOP (octave_uint32_scalar, octave_float_matrix, uint32_scalar_to_float_matrix);
+  INSTALL_CONVOP (octave_uint64_scalar, octave_float_matrix, uint64_scalar_to_float_matrix);
+
+  INSTALL_CONVOP (octave_bool_matrix, octave_float_matrix, bool_matrix_to_float_matrix);
+  INSTALL_CONVOP (octave_bool, octave_float_matrix, bool_scalar_to_float_matrix);
+
+  INSTALL_CONVOP (octave_range, octave_float_matrix, range_to_float_matrix);
+
+  INSTALL_CONVOP (octave_char_matrix_str, octave_float_matrix, char_matrix_str_to_float_matrix);
+  INSTALL_CONVOP (octave_char_matrix_sq_str, octave_float_matrix, char_matrix_sq_str_to_float_matrix);
+
+  INSTALL_CONVOP (octave_scalar, octave_float_matrix, float_scalar_to_float_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+p*/
diff --git a/src/OPERATORS/op-fm-fcdm.cc b/src/OPERATORS/op-fm-fcdm.cc
new file mode 100644
index 0000000..dd67723
--- /dev/null
+++ b/src/OPERATORS/op-fm-fcdm.cc
@@ -0,0 +1,36 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-re-mat.h"
+#define RINCLUDE "ov-flt-cx-diag.h"
+
+#define LMATRIX float_matrix
+#define RMATRIX float_complex_diag_matrix
+#define LDMATRIX float_complex_matrix
+
+#define LSHORT fm
+#define RSHORT fcdm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fm-fcm.cc b/src/OPERATORS/op-fm-fcm.cc
new file mode 100644
index 0000000..f7ac208
--- /dev/null
+++ b/src/OPERATORS/op-fm-fcm.cc
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-fm-fcm.h"
+#include "mx-fcm-fm.h"
+#include "mx-fnda-fcnda.h"
+#include "mx-fcnda-fnda.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix by complex matrix ops.
+
+DEFNDBINOP_OP (add, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, +)
+DEFNDBINOP_OP (sub, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, -)
+
+DEFBINOP_OP (mul, float_matrix, float_complex_matrix, *)
+
+DEFBINOP (div, float_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, 
+		   const octave_float_complex_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  FloatComplexMatrix ret = xdiv (v1.float_matrix_value (), 
+				 v2.float_complex_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, float_matrix, float_complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, float_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, 
+		   const octave_float_complex_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  FloatComplexMatrix ret = xleftdiv (v1.float_matrix_value (), 
+				v2.float_complex_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, product)
+DEFNDBINOP_FN (el_div, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, quotient)
+DEFNDBINOP_FN (el_pow, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_matrix, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, 
+		   const octave_float_complex_matrix&);
+
+  return quotient (v2.float_complex_array_value (), v1.float_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, mx_el_or)
+
+DEFNDCATOP_FN (fm_fcm, float_matrix, float_complex_matrix, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (m_fcm, matrix, float_complex_matrix, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (fm_cm, float_matrix, complex_matrix, float_array, 
+	       float_complex_array, concat)
+
+DEFCONV (float_complex_matrix_conv, float_matrix, float_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_float_matrix&);
+
+  return new octave_float_complex_matrix (FloatComplexNDArray (v.float_array_value ()));
+}
+
+void
+install_fm_fcm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_matrix, octave_float_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_matrix, octave_float_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_matrix, octave_float_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_matrix, octave_float_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_matrix, octave_float_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_matrix, 
+		 octave_float_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_matrix, octave_float_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_matrix, octave_float_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_matrix, octave_float_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_matrix, octave_float_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_matrix, octave_float_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_matrix, octave_float_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_matrix, 
+		 octave_float_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_matrix, 
+		 octave_float_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_matrix, 
+		 octave_float_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_matrix, 
+		 octave_float_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_matrix, 
+		 octave_float_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_matrix, 
+		 octave_float_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_matrix, octave_float_complex_matrix, fm_fcm);
+  INSTALL_CATOP (octave_matrix, octave_float_complex_matrix, m_fcm);
+  INSTALL_CATOP (octave_float_matrix, octave_complex_matrix, fm_cm);
+
+  INSTALL_ASSIGNCONV (octave_float_matrix, octave_float_complex_matrix, 
+		      octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_matrix, octave_float_complex_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_float_matrix, octave_float_complex_matrix, 
+		   float_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fm-fcs.cc b/src/OPERATORS/op-fm-fcs.cc
new file mode 100644
index 0000000..960b588
--- /dev/null
+++ b/src/OPERATORS/op-fm-fcs.cc
@@ -0,0 +1,169 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-fm-fcs.h"
+#include "mx-fcs-fm.h"
+#include "mx-fnda-fcs.h"
+#include "mx-fcs-fnda.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-complex.h"
+#include "ov-complex.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix by complex scalar ops.
+
+DEFNDBINOP_OP (add, float_matrix, float_complex, float_array, float_complex, +)
+DEFNDBINOP_OP (sub, float_matrix, float_complex, float_array, float_complex, -)
+DEFNDBINOP_OP (mul, float_matrix, float_complex, float_array, float_complex, *)
+
+DEFBINOP (div, float_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_array_value () / d);
+}
+
+DEFBINOP_FN (pow, float_matrix, float_complex, xpow)
+
+DEFBINOP (ldiv, float_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+
+  FloatMatrix m1 = v1.float_matrix_value ();
+  FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  FloatComplexMatrix ret = xleftdiv (m1, m2, typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_lt)
+DEFNDBINOP_FN (le, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_le)
+DEFNDBINOP_FN (eq, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_eq)
+DEFNDBINOP_FN (ge, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_ge)
+DEFNDBINOP_FN (gt, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_gt)
+DEFNDBINOP_FN (ne, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_matrix, float_complex, float_array, 
+	       float_complex, *)
+
+DEFBINOP (el_div, float_matrix, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, float_matrix, float_complex, float_array, 
+	       float_complex, elem_xpow)
+
+DEFBINOP (el_ldiv, float_matrix, flaot_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+
+  return x_el_div (v2.float_complex_value (), v1.float_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_and)
+DEFNDBINOP_FN (el_or, float_matrix, float_complex, float_array, 
+	       float_complex, mx_el_or)
+
+DEFNDCATOP_FN (fm_fcs, float_matrix, float_complex, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (m_fcs, matrix, float_complex, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (fm_cs, float_matrix, complex, float_array, 
+	       float_complex_array, concat)
+
+void
+install_fm_fcs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_matrix, octave_float_complex, add);
+  INSTALL_BINOP (op_sub, octave_float_matrix, octave_float_complex, sub);
+  INSTALL_BINOP (op_mul, octave_float_matrix, octave_float_complex, mul);
+  INSTALL_BINOP (op_div, octave_float_matrix, octave_float_complex, div);
+  INSTALL_BINOP (op_pow, octave_float_matrix, octave_float_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_matrix, octave_float_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_matrix, octave_float_complex, lt);
+  INSTALL_BINOP (op_le, octave_float_matrix, octave_float_complex, le);
+  INSTALL_BINOP (op_eq, octave_float_matrix, octave_float_complex, eq);
+  INSTALL_BINOP (op_ge, octave_float_matrix, octave_float_complex, ge);
+  INSTALL_BINOP (op_gt, octave_float_matrix, octave_float_complex, gt);
+  INSTALL_BINOP (op_ne, octave_float_matrix, octave_float_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_matrix, octave_float_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_matrix, octave_float_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_matrix, octave_float_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_matrix, octave_float_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_matrix, octave_float_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_matrix, octave_float_complex, el_or);
+
+  INSTALL_CATOP (octave_float_matrix, octave_float_complex, fm_fcs);
+  INSTALL_CATOP (octave_matrix, octave_float_complex, m_fcs);
+  INSTALL_CATOP (octave_float_matrix, octave_complex, fm_cs);
+
+  INSTALL_ASSIGNCONV (octave_float_matrix, octave_float_complex, 
+		      octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_matrix, octave_float_complex, 
+		      octave_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fm-fdm.cc b/src/OPERATORS/op-fm-fdm.cc
new file mode 100644
index 0000000..766ca4e
--- /dev/null
+++ b/src/OPERATORS/op-fm-fdm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-flt-re-mat.h"
+#define RINCLUDE "ov-flt-re-diag.h"
+
+#define LMATRIX float_matrix
+#define RMATRIX float_diag_matrix
+
+#define LSHORT fm
+#define RSHORT fdm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-fm-fm.cc b/src/OPERATORS/op-fm-fm.cc
new file mode 100644
index 0000000..b212fea
--- /dev/null
+++ b/src/OPERATORS/op-fm-fm.cc
@@ -0,0 +1,234 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix unary ops.
+
+DEFNDUNOP_OP (not, float_matrix, float_array, !)
+DEFNDUNOP_OP (uplus, float_matrix, float_array, /* no-op */)
+DEFNDUNOP_OP (uminus, float_matrix, float_array, -)
+
+DEFUNOP (transpose, float_matrix)
+{
+  CAST_UNOP_ARG (const octave_float_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.float_matrix_value().transpose ());
+}
+
+DEFNCUNOP_METHOD (incr, float_matrix, increment)
+DEFNCUNOP_METHOD (decr, float_matrix, decrement)
+
+// matrix by matrix ops.
+
+DEFNDBINOP_OP (add, float_matrix, float_matrix, float_array, float_array, +)
+DEFNDBINOP_OP (sub, float_matrix, float_matrix, float_array, float_array, -)
+
+DEFBINOP_OP (mul, float_matrix, float_matrix, *)
+
+DEFBINOP (div, float_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  FloatMatrix ret = xdiv (v1.float_matrix_value (), 
+			  v2.float_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, float_matrix, float_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, float_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  FloatMatrix ret = xleftdiv (v1.float_matrix_value (), 
+			      v2.float_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP (trans_mul, float_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  return octave_value(xgemm (true, v1.float_matrix_value (), 
+                             false, v2.float_matrix_value ()));
+}
+
+DEFBINOP (mul_trans, float_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  return octave_value(xgemm (false, v1.float_matrix_value (), 
+                             true, v2.float_matrix_value ()));
+}
+
+DEFNDBINOP_FN (lt, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, float_matrix, float_matrix, float_array, 
+	       float_array, product)
+DEFNDBINOP_FN (el_div, float_matrix, float_matrix, float_array, 
+	       float_array, quotient)
+DEFNDBINOP_FN (el_pow, float_matrix, float_matrix, float_array, 
+	       float_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_matrix, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+
+  return octave_value (quotient (v2.float_array_value (), 
+				 v1.float_array_value ()));
+}
+
+DEFNDBINOP_FN (el_and, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_or)
+DEFNDBINOP_FN (el_not_and, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_not_and)
+DEFNDBINOP_FN (el_not_or,  float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_not_or)
+DEFNDBINOP_FN (el_and_not, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_and_not)
+DEFNDBINOP_FN (el_or_not,  float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_or_not)
+
+
+
+DEFNDCATOP_FN (fm_fm, float_matrix, float_matrix, float_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (m_fm, matrix, float_matrix, float_array, float_array, concat)
+
+DEFNDCATOP_FN (fm_m, float_matrix, matrix, float_array, float_array, concat)
+
+DEFNDASSIGNOP_FN (assign, float_matrix, float_matrix, float_array, assign)
+
+DEFNDASSIGNOP_FN (dbl_assign, matrix, float_matrix, array, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, float_matrix, delete_elements)
+
+CONVDECL (float_matrix_to_matrix)
+{
+  CAST_CONV_ARG (const octave_float_matrix&);
+
+  return new octave_matrix (v.array_value ());
+}
+
+void
+install_fm_fm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_float_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_float_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_float_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_float_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_float_matrix, transpose);
+
+  INSTALL_NCUNOP (op_incr, octave_float_matrix, incr);
+  INSTALL_NCUNOP (op_decr, octave_float_matrix, decr);
+
+  INSTALL_BINOP (op_add, octave_float_matrix, octave_float_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_matrix, octave_float_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_matrix, octave_float_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_matrix, octave_float_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_matrix, octave_float_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_matrix, octave_float_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_matrix, octave_float_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_matrix, octave_float_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_matrix, octave_float_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_matrix, octave_float_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_matrix, octave_float_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_matrix, octave_float_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_matrix, octave_float_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_matrix, octave_float_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_matrix, octave_float_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_matrix, octave_float_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_matrix, octave_float_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_matrix, octave_float_matrix, el_or);
+  INSTALL_BINOP (op_el_and_not, octave_float_matrix, octave_float_matrix, el_and_not);
+  INSTALL_BINOP (op_el_or_not, octave_float_matrix, octave_float_matrix, el_or_not);
+  INSTALL_BINOP (op_el_not_and, octave_float_matrix, octave_float_matrix, el_not_and);
+  INSTALL_BINOP (op_el_not_or, octave_float_matrix, octave_float_matrix, el_not_or);
+  INSTALL_BINOP (op_trans_mul, octave_float_matrix, octave_float_matrix, trans_mul);
+  INSTALL_BINOP (op_mul_trans, octave_float_matrix, octave_float_matrix, mul_trans);
+  INSTALL_BINOP (op_herm_mul, octave_float_matrix, octave_float_matrix, trans_mul);
+  INSTALL_BINOP (op_mul_herm, octave_float_matrix, octave_float_matrix, mul_trans);
+
+  INSTALL_CATOP (octave_float_matrix, octave_float_matrix, fm_fm);
+  INSTALL_CATOP (octave_matrix, octave_float_matrix, m_fm);
+  INSTALL_CATOP (octave_float_matrix, octave_matrix, fm_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, 
+		    octave_float_matrix, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, 
+		    octave_float_matrix, dbl_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_null_sq_str, null_assign);
+
+  INSTALL_CONVOP (octave_float_matrix, octave_matrix, float_matrix_to_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fm-fs.cc b/src/OPERATORS/op-fm-fs.cc
new file mode 100644
index 0000000..05991bd
--- /dev/null
+++ b/src/OPERATORS/op-fm-fs.cc
@@ -0,0 +1,159 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-flt-re-mat.h"
+#include "ov-float.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix by scalar ops.
+
+DEFNDBINOP_OP (add, float_matrix, float_scalar, float_array, float_scalar, +)
+DEFNDBINOP_OP (sub, float_matrix, float_scalar, float_array, float_scalar, -)
+DEFNDBINOP_OP (mul, float_matrix, float_scalar, float_array, float_scalar, *)
+
+DEFBINOP (div, float_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_array_value () / d);
+}
+
+DEFBINOP_FN (pow, float_matrix, float_scalar, xpow)
+
+DEFBINOP (ldiv, float_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+
+  FloatMatrix m1 = v1.float_matrix_value ();
+  FloatMatrix m2 = v2.float_matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  FloatMatrix ret = xleftdiv (m1, m2, typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_lt)
+DEFNDBINOP_FN (le, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_le)
+DEFNDBINOP_FN (eq, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_eq)
+DEFNDBINOP_FN (ge, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_ge)
+DEFNDBINOP_FN (gt, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_gt)
+DEFNDBINOP_FN (ne, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_matrix, float_scalar, float_array, float_scalar, *)
+
+DEFBINOP (el_div, float_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, float_matrix, float_scalar, float_array, 
+	       float_scalar, elem_xpow)
+
+DEFBINOP (el_ldiv, float_matrix, float)
+{
+  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+
+  return x_el_div (v2.float_value (), v1.float_array_value ());
+}
+
+DEFNDBINOP_FN (el_and, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_and)
+DEFNDBINOP_FN (el_or, float_matrix, float_scalar, float_array, 
+	       float_scalar, mx_el_or)
+
+DEFNDCATOP_FN (fm_fs, float_matrix, float_scalar, float_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (m_fs, matrix, float_scalar, float_array, float_array, concat)
+
+DEFNDCATOP_FN (fm_s, float_matrix, scalar, float_array, float_array, concat)
+
+DEFNDASSIGNOP_FN (assign, float_matrix, float_scalar, float_scalar, assign)
+DEFNDASSIGNOP_FN (dbl_assign, matrix, float_scalar, scalar, assign)
+
+void
+install_fm_fs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_matrix, octave_float_scalar, add);
+  INSTALL_BINOP (op_sub, octave_float_matrix, octave_float_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_float_matrix, octave_float_scalar, mul);
+  INSTALL_BINOP (op_div, octave_float_matrix, octave_float_scalar, div);
+  INSTALL_BINOP (op_pow, octave_float_matrix, octave_float_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_matrix, octave_float_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_matrix, octave_float_scalar, lt);
+  INSTALL_BINOP (op_le, octave_float_matrix, octave_float_scalar, le);
+  INSTALL_BINOP (op_eq, octave_float_matrix, octave_float_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_float_matrix, octave_float_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_float_matrix, octave_float_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_float_matrix, octave_float_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_matrix, octave_float_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_matrix, octave_float_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_matrix, octave_float_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_matrix, octave_float_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_matrix, octave_float_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_matrix, octave_float_scalar, el_or);
+
+  INSTALL_CATOP (octave_float_matrix, octave_float_scalar, fm_fs);
+  INSTALL_CATOP (octave_matrix, octave_float_scalar, m_fs);
+  INSTALL_CATOP (octave_float_matrix, octave_scalar, fm_s);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_float_scalar, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_float_scalar, dbl_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fm-pm.cc b/src/OPERATORS/op-fm-pm.cc
new file mode 100644
index 0000000..77ed3f3
--- /dev/null
+++ b/src/OPERATORS/op-fm-pm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-flt-re-mat.h"
+
+#define LMATRIX float_matrix
+#define RMATRIX perm_matrix
+
+#define LSHORT fm
+#define RSHORT pm
+
+#define RIGHT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-fs-fcm.cc b/src/OPERATORS/op-fs-fcm.cc
new file mode 100644
index 0000000..9e5bf0a
--- /dev/null
+++ b/src/OPERATORS/op-fs-fcm.cc
@@ -0,0 +1,185 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-fs-fcm.h"
+#include "mx-fcm-fs.h"
+#include "mx-fs-fcnda.h"
+#include "mx-fcnda-fs.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by complex matrix ops.
+
+DEFNDBINOP_OP (add, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, +)
+DEFNDBINOP_OP (sub, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, -)
+DEFNDBINOP_OP (mul, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, *)
+
+DEFBINOP (div, float_scalar, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, 
+		   const octave_float_complex_matrix&);
+
+  FloatMatrix m1 = v1.float_matrix_value ();
+  FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  FloatComplexMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, float_scalar, float_complex_matrix, xpow)
+
+DEFBINOP (ldiv, float_scalar, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, 
+		   const octave_float_complex_matrix&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, *)
+DEFNDBINOP_FN (el_div, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, x_el_div)
+DEFNDBINOP_FN (el_pow, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_scalar, float_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, 
+		   const octave_float_complex_matrix&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_scalar, float_complex_matrix, float_scalar, 
+	       float_complex_array, mx_el_or)
+
+DEFNDCATOP_FN (fs_fcm, float_scalar, float_complex_matrix, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (s_fcm, scalar, float_complex_matrix, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (fs_cm, float_scalar, complex_matrix, float_array, 
+	       float_complex_array, concat)
+
+DEFCONV (float_complex_matrix_conv, float_scalar, float_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_float_scalar&);
+
+  return new octave_float_complex_matrix (FloatComplexMatrix (v.float_matrix_value ()));
+}
+
+void
+install_fs_fcm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_scalar, octave_float_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_scalar, octave_float_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_scalar, octave_float_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_scalar, octave_float_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_scalar, octave_float_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_scalar, 
+		 octave_float_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_scalar, octave_float_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_scalar, octave_float_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_scalar, octave_float_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_scalar, octave_float_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_scalar, octave_float_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_scalar, octave_float_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_scalar, 
+		 octave_float_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_scalar, 
+		 octave_float_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_scalar, 
+		 octave_float_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_scalar, 
+		 octave_float_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_scalar, 
+		 octave_float_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_scalar, 
+		 octave_float_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_scalar, octave_float_complex_matrix, fs_fcm);
+  INSTALL_CATOP (octave_scalar, octave_float_complex_matrix, s_fcm);
+  INSTALL_CATOP (octave_float_scalar, octave_complex_matrix, fs_cm);
+
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_float_complex_matrix, 
+		      octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_scalar, octave_float_complex_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_float_scalar, octave_float_complex_matrix, 
+		   float_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fs-fcs.cc b/src/OPERATORS/op-fs-fcs.cc
new file mode 100644
index 0000000..992c852
--- /dev/null
+++ b/src/OPERATORS/op-fs-fcs.cc
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-flt-complex.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by complex scalar ops.
+
+DEFBINOP_OP (add, float_scalar, float_complex, +)
+DEFBINOP_OP (sub, float_scalar, float_complex, -)
+DEFBINOP_OP (mul, float_scalar, float_complex, *)
+
+DEFBINOP (div, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_value () / d);
+}
+
+DEFBINOP_FN (pow, float_scalar, float_complex, xpow)
+
+DEFBINOP (ldiv, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_value () / d);
+}
+
+DEFBINOP (lt, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return v1.float_value () < real (v2.float_complex_value ());
+}
+
+DEFBINOP (le, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return v1.float_value () <= real (v2.float_complex_value ());
+}
+
+DEFBINOP (eq, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return v1.float_value () == v2.float_complex_value ();
+}
+
+DEFBINOP (ge, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return v1.float_value () >= real (v2.float_complex_value ());
+}
+
+DEFBINOP (gt, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return v1.float_value () > real (v2.float_complex_value ());
+}
+
+DEFBINOP (ne, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return v1.float_value () != v2.float_complex_value ();
+}
+
+DEFBINOP_OP (el_mul, float_scalar, float_complex, *)
+
+DEFBINOP (el_div, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  FloatComplex d = v2.float_complex_value ();
+
+  if (d == static_cast<float>(0.0))
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_value () / d);
+}
+
+DEFBINOP_FN (el_pow, float_scalar, float_complex, xpow)
+
+DEFBINOP (el_ldiv, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_complex_value () / d);
+}
+
+DEFBINOP (el_and, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return octave_value (v1.float_scalar_value () && (v2.float_complex_value () != static_cast<float>(0.0)));
+}
+
+DEFBINOP (el_or, float_scalar, float_complex)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+
+  return octave_value (v1.float_scalar_value () || (v2.float_complex_value () != static_cast<float>(0.0)));
+}
+
+DEFNDCATOP_FN (fs_fcs, float_scalar, float_complex, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (s_fcs, scalar, float_complex, float_array, 
+	       float_complex_array, concat)
+
+DEFNDCATOP_FN (fs_cs, float_scalar, complex, float_array, 
+	       float_complex_array, concat)
+
+void
+install_fs_fcs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_scalar, octave_float_complex, add);
+  INSTALL_BINOP (op_sub, octave_float_scalar, octave_float_complex, sub);
+  INSTALL_BINOP (op_mul, octave_float_scalar, octave_float_complex, mul);
+  INSTALL_BINOP (op_div, octave_float_scalar, octave_float_complex, div);
+  INSTALL_BINOP (op_pow, octave_float_scalar, octave_float_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_scalar, octave_float_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_scalar, octave_float_complex, lt);
+  INSTALL_BINOP (op_le, octave_float_scalar, octave_float_complex, le);
+  INSTALL_BINOP (op_eq, octave_float_scalar, octave_float_complex, eq);
+  INSTALL_BINOP (op_ge, octave_float_scalar, octave_float_complex, ge);
+  INSTALL_BINOP (op_gt, octave_float_scalar, octave_float_complex, gt);
+  INSTALL_BINOP (op_ne, octave_float_scalar, octave_float_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_scalar, octave_float_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_scalar, octave_float_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_scalar, octave_float_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_scalar, octave_float_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_scalar, octave_float_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_scalar, octave_float_complex, el_or);
+
+  INSTALL_CATOP (octave_float_scalar, octave_float_complex, fs_fcs);
+  INSTALL_CATOP (octave_scalar, octave_float_complex, s_fcs);
+  INSTALL_CATOP (octave_float_scalar, octave_complex, fs_cs);
+
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_float_complex, 
+		      octave_float_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_scalar, octave_float_complex, 
+		      octave_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fs-fm.cc b/src/OPERATORS/op-fs-fm.cc
new file mode 100644
index 0000000..c122bf6
--- /dev/null
+++ b/src/OPERATORS/op-fs-fm.cc
@@ -0,0 +1,161 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by matrix ops.
+
+DEFNDBINOP_OP (add, float_scalar, float_matrix, float_scalar, float_array, +)
+DEFNDBINOP_OP (sub, float_scalar, float_matrix, float_scalar, float_array, -)
+DEFNDBINOP_OP (mul, float_scalar, float_matrix, float_scalar, float_array, *)
+
+DEFBINOP (div, float_scalar, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_matrix&);
+
+  FloatMatrix m1 = v1.float_matrix_value ();
+  FloatMatrix m2 = v2.float_matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  FloatMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, float_scalar, float_matrix, xpow)
+
+DEFBINOP (ldiv, float_scalar, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_matrix&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_lt)
+DEFNDBINOP_FN (le, float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_le)
+DEFNDBINOP_FN (eq, float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_eq)
+DEFNDBINOP_FN (ge, float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_ge)
+DEFNDBINOP_FN (gt, float_scalar, float_matrix, float_scalar, 
+float_array, mx_el_gt)
+DEFNDBINOP_FN (ne, float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, float_scalar, float_matrix, float_scalar, 
+	       float_array, *)
+DEFNDBINOP_FN (el_div, float_scalar, float_matrix, float_scalar, 
+	       float_array, x_el_div)
+DEFNDBINOP_FN (el_pow, float_scalar, float_matrix, float_scalar, 
+	       float_array, elem_xpow)
+
+DEFBINOP (el_ldiv, float_scalar, float_matrix)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_matrix&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  float_scalar, float_matrix, float_scalar, 
+	       float_array, mx_el_or)
+
+DEFNDCATOP_FN (fs_fm, float_scalar, float_matrix, float_array, 
+	       float_array, concat)
+
+DEFNDCATOP_FN (s_fm, scalar, float_matrix, float_array, float_array, concat)
+
+DEFNDCATOP_FN (fs_m, float_scalar, matrix, float_array, float_array, concat)
+
+DEFCONV (matrix_conv, float_scalar, float_matrix)
+{
+  CAST_CONV_ARG (const octave_float_scalar&);
+
+  return new octave_float_matrix (v.float_matrix_value ());
+}
+
+void
+install_fs_fm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_float_scalar, octave_float_matrix, add);
+  INSTALL_BINOP (op_sub, octave_float_scalar, octave_float_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_float_scalar, octave_float_matrix, mul);
+  INSTALL_BINOP (op_div, octave_float_scalar, octave_float_matrix, div);
+  INSTALL_BINOP (op_pow, octave_float_scalar, octave_float_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_scalar, octave_float_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_scalar, octave_float_matrix, lt);
+  INSTALL_BINOP (op_le, octave_float_scalar, octave_float_matrix, le);
+  INSTALL_BINOP (op_eq, octave_float_scalar, octave_float_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_float_scalar, octave_float_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_float_scalar, octave_float_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_float_scalar, octave_float_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_scalar, octave_float_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_scalar, octave_float_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_scalar, octave_float_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_scalar, octave_float_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_scalar, octave_float_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_scalar, octave_float_matrix, el_or);
+
+  INSTALL_CATOP (octave_float_scalar, octave_float_matrix, fs_fm);
+  INSTALL_CATOP (octave_scalar, octave_float_matrix, s_fm);
+  INSTALL_CATOP (octave_float_scalar, octave_matrix, fs_m);
+
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_float_matrix, octave_float_matrix);
+  INSTALL_ASSIGNCONV (octave_scalar, octave_float_matrix, octave_matrix);
+
+  INSTALL_WIDENOP (octave_float_scalar, octave_float_matrix, matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-fs-fs.cc b/src/OPERATORS/op-fs-fs.cc
new file mode 100644
index 0000000..81b9549
--- /dev/null
+++ b/src/OPERATORS/op-fs-fs.cc
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar unary ops.
+
+DEFUNOP_OP (not, float_scalar, !)
+DEFUNOP_OP (uplus, float_scalar, /* no-op */)
+DEFUNOP_OP (uminus, float_scalar, -)
+DEFUNOP_OP (transpose, float_scalar, /* no-op */)
+DEFUNOP_OP (hermitian, float_scalar, /* no-op */)
+
+DEFNCUNOP_METHOD (incr, float_scalar, increment)
+DEFNCUNOP_METHOD (decr, float_scalar, decrement)
+
+// float by float ops.
+
+DEFBINOP_OP (add, float_scalar, float_scalar, +)
+DEFBINOP_OP (sub, float_scalar, float_scalar, -)
+DEFBINOP_OP (mul, float_scalar, float_scalar, *)
+
+DEFBINOP (div, float_scalar, float_scalar)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_value () / d);
+}
+
+DEFBINOP_FN (pow, float_scalar, float_scalar, xpow)
+
+DEFBINOP (ldiv, float_scalar, float_scalar)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_value () / d);
+}
+
+DEFBINOP_OP (lt, float_scalar, float_scalar, <)
+DEFBINOP_OP (le, float_scalar, float_scalar, <=)
+DEFBINOP_OP (eq, float_scalar, float_scalar, ==)
+DEFBINOP_OP (ge, float_scalar, float_scalar, >=)
+DEFBINOP_OP (gt, float_scalar, float_scalar, >)
+DEFBINOP_OP (ne, float_scalar, float_scalar, !=)
+
+DEFBINOP_OP (el_mul, float_scalar, float_scalar, *)
+
+DEFBINOP (el_div, float_scalar, float_scalar)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+
+  float d = v2.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.float_value () / d);
+}
+
+DEFBINOP_FN (el_pow, float_scalar, float_scalar, xpow)
+
+DEFBINOP (el_ldiv, float_scalar, float_scalar)
+{
+  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+
+  float d = v1.float_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.float_value () / d);
+}
+
+DEFSCALARBOOLOP_OP (el_and, float_scalar, float_scalar, &&)
+DEFSCALARBOOLOP_OP (el_or, float_scalar, float_scalar, ||)
+
+DEFNDCATOP_FN (fs_fs, float_scalar, float_scalar, float_array, float_array, concat)
+DEFNDCATOP_FN (s_fs, scalar, float_scalar, float_array, float_array, concat)
+DEFNDCATOP_FN (fs_s, float_scalar, scalar, float_array, float_array, concat)
+
+CONVDECL (float_to_scalar)
+{
+  CAST_CONV_ARG (const octave_float_scalar&);
+
+  return new octave_matrix (Matrix (1, 1, static_cast<double>(v.float_value ())));
+}
+
+void
+install_fs_fs_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_float_scalar, not);
+  INSTALL_UNOP (op_uplus, octave_float_scalar, uplus);
+  INSTALL_UNOP (op_uminus, octave_float_scalar, uminus);
+  INSTALL_UNOP (op_transpose, octave_float_scalar, transpose);
+  INSTALL_UNOP (op_hermitian, octave_float_scalar, hermitian);
+
+  INSTALL_NCUNOP (op_incr, octave_float_scalar, incr);
+  INSTALL_NCUNOP (op_decr, octave_float_scalar, decr);
+
+  INSTALL_BINOP (op_add, octave_float_scalar, octave_float_scalar, add);
+  INSTALL_BINOP (op_sub, octave_float_scalar, octave_float_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_float_scalar, octave_float_scalar, mul);
+  INSTALL_BINOP (op_div, octave_float_scalar, octave_float_scalar, div);
+  INSTALL_BINOP (op_pow, octave_float_scalar, octave_float_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_float_scalar, octave_float_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_float_scalar, octave_float_scalar, lt);
+  INSTALL_BINOP (op_le, octave_float_scalar, octave_float_scalar, le);
+  INSTALL_BINOP (op_eq, octave_float_scalar, octave_float_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_float_scalar, octave_float_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_float_scalar, octave_float_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_float_scalar, octave_float_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_float_scalar, octave_float_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_float_scalar, octave_float_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_float_scalar, octave_float_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_float_scalar, octave_float_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_float_scalar, octave_float_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_float_scalar, octave_float_scalar, el_or);
+
+  INSTALL_CATOP (octave_float_scalar, octave_float_scalar, fs_fs);
+  INSTALL_CATOP (octave_scalar, octave_float_scalar, s_fs);
+  INSTALL_CATOP (octave_float_scalar, octave_scalar, fs_s);
+
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_float_scalar, octave_float_matrix);
+  INSTALL_ASSIGNCONV (octave_scalar, octave_float_scalar, octave_matrix);
+
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_null_matrix, octave_float_matrix);
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_null_str, octave_float_matrix);
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_null_sq_str, octave_float_matrix);
+
+  INSTALL_CONVOP (octave_float_scalar, octave_matrix, float_to_scalar);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-i16-i16.cc b/src/OPERATORS/op-i16-i16.cc
new file mode 100644
index 0000000..1b2fe46
--- /dev/null
+++ b/src/OPERATORS/op-i16-i16.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-i16nda-i8.h"
+#include "mx-i16nda-ui8.h"
+#include "mx-i16nda-ui16.h"
+#include "mx-i16nda-i32.h"
+#include "mx-i16nda-ui32.h"
+#include "mx-i16nda-i64.h"
+#include "mx-i16nda-ui64.h"
+
+#include "mx-i16nda-i8nda.h"
+#include "mx-i16nda-ui8nda.h"
+#include "mx-i16nda-ui16nda.h"
+#include "mx-i16nda-i32nda.h"
+#include "mx-i16nda-ui32nda.h"
+#include "mx-i16nda-i64nda.h"
+#include "mx-i16nda-ui64nda.h"
+
+#include "mx-i16-i8nda.h"
+#include "mx-i16-ui8nda.h"
+#include "mx-i16-ui16nda.h"
+#include "mx-i16-i32nda.h"
+#include "mx-i16-ui32nda.h"
+#include "mx-i16-i64nda.h"
+#include "mx-i16-ui64nda.h"
+
+#include "mx-i16nda-s.h"
+#include "mx-s-i16nda.h"
+
+#include "mx-i16nda-nda.h"
+#include "mx-nda-i16nda.h"
+
+#include "mx-i16-nda.h"
+#include "mx-nda-i16.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (int16)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, int16_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, int16_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, int16_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, int16_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, int16_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, int16_, int64_, int64_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, int16_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, int16_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, int16_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, int16_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, int16_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, int16_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, int16_, int64_, int64_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, int16_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (int16, int8)
+OCTAVE_MIXED_INT_CMP_OPS (int16, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (int16, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (int16, int32)
+OCTAVE_MIXED_INT_CMP_OPS (int16, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (int16, int64)
+OCTAVE_MIXED_INT_CMP_OPS (int16, uint64)
+
+void
+install_i16_i16_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (int16);
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, int16_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, int16_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, int16_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, int16_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, int16_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, int16_, int64_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, int16_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, int16_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, int16_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, int16_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, int16_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, int16_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, int16_, int64_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, int16_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, int64);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int16, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, int64);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int16, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-i32-i32.cc b/src/OPERATORS/op-i32-i32.cc
new file mode 100644
index 0000000..69c8c8b
--- /dev/null
+++ b/src/OPERATORS/op-i32-i32.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-i32nda-i8.h"
+#include "mx-i32nda-ui8.h"
+#include "mx-i32nda-i16.h"
+#include "mx-i32nda-ui16.h"
+#include "mx-i32nda-ui32.h"
+#include "mx-i32nda-i64.h"
+#include "mx-i32nda-ui64.h"
+
+#include "mx-i32nda-i8nda.h"
+#include "mx-i32nda-ui8nda.h"
+#include "mx-i32nda-i16nda.h"
+#include "mx-i32nda-ui16nda.h"
+#include "mx-i32nda-ui32nda.h"
+#include "mx-i32nda-i64nda.h"
+#include "mx-i32nda-ui64nda.h"
+
+#include "mx-i32-i8nda.h"
+#include "mx-i32-ui8nda.h"
+#include "mx-i32-i16nda.h"
+#include "mx-i32-ui16nda.h"
+#include "mx-i32-ui32nda.h"
+#include "mx-i32-i64nda.h"
+#include "mx-i32-ui64nda.h"
+
+#include "mx-i32nda-s.h"
+#include "mx-s-i32nda.h"
+
+#include "mx-i32nda-nda.h"
+#include "mx-nda-i32nda.h"
+
+#include "mx-i32-nda.h"
+#include "mx-nda-i32.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (int32)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, int32_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, int32_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, int32_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, int32_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, int32_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, int32_, int64_, int64_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, int32_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, int32_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, int32_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, int32_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, int32_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, int32_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, int32_, int64_, int64_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, int32_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (int32, int8)
+OCTAVE_MIXED_INT_CMP_OPS (int32, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (int32, int16)
+OCTAVE_MIXED_INT_CMP_OPS (int32, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (int32, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (int32, int64)
+OCTAVE_MIXED_INT_CMP_OPS (int32, uint64)
+
+void
+install_i32_i32_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (int32);
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, int32_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, int32_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, int32_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, int32_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, int32_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, int32_, int64_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, int32_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, int32_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, int32_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, int32_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, int32_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, int32_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, int32_, int64_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, int32_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, int64);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int32, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, int64);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int32, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-i64-i64.cc b/src/OPERATORS/op-i64-i64.cc
new file mode 100644
index 0000000..97936a7
--- /dev/null
+++ b/src/OPERATORS/op-i64-i64.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-i64nda-i8.h"
+#include "mx-i64nda-ui8.h"
+#include "mx-i64nda-i16.h"
+#include "mx-i64nda-ui16.h"
+#include "mx-i64nda-i32.h"
+#include "mx-i64nda-ui32.h"
+#include "mx-i64nda-ui64.h"
+
+#include "mx-i64nda-i8nda.h"
+#include "mx-i64nda-ui8nda.h"
+#include "mx-i64nda-i16nda.h"
+#include "mx-i64nda-ui16nda.h"
+#include "mx-i64nda-i32nda.h"
+#include "mx-i64nda-ui32nda.h"
+#include "mx-i64nda-ui64nda.h"
+
+#include "mx-i64-i8nda.h"
+#include "mx-i64-ui8nda.h"
+#include "mx-i64-i16nda.h"
+#include "mx-i64-ui16nda.h"
+#include "mx-i64-i32nda.h"
+#include "mx-i64-ui32nda.h"
+#include "mx-i64-ui64nda.h"
+
+#include "mx-i64nda-s.h"
+#include "mx-s-i64nda.h"
+
+#include "mx-i64nda-nda.h"
+#include "mx-nda-i64nda.h"
+
+#include "mx-i64-nda.h"
+#include "mx-nda-i64.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (int64)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, int64_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, int64_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, int64_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, int64_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, int64_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, int64_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, int64_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, int64_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, int64_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, int64_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, int64_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, int64_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, int64_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, int64_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (int64, int8)
+OCTAVE_MIXED_INT_CMP_OPS (int64, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (int64, int16)
+OCTAVE_MIXED_INT_CMP_OPS (int64, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (int64, int32)
+OCTAVE_MIXED_INT_CMP_OPS (int64, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (int64, uint64)
+
+void
+install_i64_i64_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (int64);
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, int64_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, int64_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, int64_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, int64_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, int64_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, int64_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, int64_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, int64_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, int64_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, int64_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, int64_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, int64_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, int64_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, int64_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int64, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int64, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-i8-i8.cc b/src/OPERATORS/op-i8-i8.cc
new file mode 100644
index 0000000..bcc5fce
--- /dev/null
+++ b/src/OPERATORS/op-i8-i8.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-i8nda-ui8.h"
+#include "mx-i8nda-i16.h"
+#include "mx-i8nda-ui16.h"
+#include "mx-i8nda-i32.h"
+#include "mx-i8nda-ui32.h"
+#include "mx-i8nda-i64.h"
+#include "mx-i8nda-ui64.h"
+
+#include "mx-i8nda-ui8nda.h"
+#include "mx-i8nda-i16nda.h"
+#include "mx-i8nda-ui16nda.h"
+#include "mx-i8nda-i32nda.h"
+#include "mx-i8nda-ui32nda.h"
+#include "mx-i8nda-i64nda.h"
+#include "mx-i8nda-ui64nda.h"
+
+#include "mx-i8-ui8nda.h"
+#include "mx-i8-i16nda.h"
+#include "mx-i8-ui16nda.h"
+#include "mx-i8-i32nda.h"
+#include "mx-i8-ui32nda.h"
+#include "mx-i8-i64nda.h"
+#include "mx-i8-ui64nda.h"
+
+#include "mx-i8nda-s.h"
+#include "mx-s-i8nda.h"
+
+#include "mx-i8nda-nda.h"
+#include "mx-nda-i8nda.h"
+
+#include "mx-i8-nda.h"
+#include "mx-nda-i8.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (int8)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, int8_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, int8_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, int8_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, int8_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, int8_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, int8_, int64_, int64_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, int8_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, int8_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, int8_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, int8_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, int8_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, int8_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, int8_, int64_, int64_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, int8_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (int8, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (int8, int16)
+OCTAVE_MIXED_INT_CMP_OPS (int8, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (int8, int32)
+OCTAVE_MIXED_INT_CMP_OPS (int8, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (int8, int64)
+OCTAVE_MIXED_INT_CMP_OPS (int8, uint64)
+
+void
+install_i8_i8_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (int8);
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, int8_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, int8_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, int8_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, int8_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, int8_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, int8_, int64_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, int8_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, int8_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, int8_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, int8_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, int8_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, int8_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, int8_, int64_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, int8_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, int64);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (int8, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, int64);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (int8, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-int-concat.cc b/src/OPERATORS/op-int-concat.cc
new file mode 100644
index 0000000..61a2208
--- /dev/null
+++ b/src/OPERATORS/op-int-concat.cc
@@ -0,0 +1,324 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-range.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "op-int.h"
+#include "ops.h"
+
+// Concatentation of mixed integer types:
+
+OCTAVE_CONCAT_FN2 (int8, int16)
+OCTAVE_CONCAT_FN2 (int8, int32)
+OCTAVE_CONCAT_FN2 (int8, int64)
+
+OCTAVE_CONCAT_FN2 (int8, uint8)
+OCTAVE_CONCAT_FN2 (int8, uint16)
+OCTAVE_CONCAT_FN2 (int8, uint32)
+OCTAVE_CONCAT_FN2 (int8, uint64)
+
+OCTAVE_CONCAT_FN2 (int16, int8)
+OCTAVE_CONCAT_FN2 (int16, int32)
+OCTAVE_CONCAT_FN2 (int16, int64)
+
+OCTAVE_CONCAT_FN2 (int16, uint8)
+OCTAVE_CONCAT_FN2 (int16, uint16)
+OCTAVE_CONCAT_FN2 (int16, uint32)
+OCTAVE_CONCAT_FN2 (int16, uint64)
+
+OCTAVE_CONCAT_FN2 (int32, int8)
+OCTAVE_CONCAT_FN2 (int32, int16)
+OCTAVE_CONCAT_FN2 (int32, int64)
+
+OCTAVE_CONCAT_FN2 (int32, uint8)
+OCTAVE_CONCAT_FN2 (int32, uint16)
+OCTAVE_CONCAT_FN2 (int32, uint32)
+OCTAVE_CONCAT_FN2 (int32, uint64)
+
+OCTAVE_CONCAT_FN2 (int64, int8)
+OCTAVE_CONCAT_FN2 (int64, int16)
+OCTAVE_CONCAT_FN2 (int64, int32)
+
+OCTAVE_CONCAT_FN2 (int64, uint8)
+OCTAVE_CONCAT_FN2 (int64, uint16)
+OCTAVE_CONCAT_FN2 (int64, uint32)
+OCTAVE_CONCAT_FN2 (int64, uint64)
+
+OCTAVE_CONCAT_FN2 (uint8, int8)
+OCTAVE_CONCAT_FN2 (uint8, int16)
+OCTAVE_CONCAT_FN2 (uint8, int32)
+OCTAVE_CONCAT_FN2 (uint8, int64)
+
+OCTAVE_CONCAT_FN2 (uint8, uint16)
+OCTAVE_CONCAT_FN2 (uint8, uint32)
+OCTAVE_CONCAT_FN2 (uint8, uint64)
+
+OCTAVE_CONCAT_FN2 (uint16, int8)
+OCTAVE_CONCAT_FN2 (uint16, int16)
+OCTAVE_CONCAT_FN2 (uint16, int32)
+OCTAVE_CONCAT_FN2 (uint16, int64)
+
+OCTAVE_CONCAT_FN2 (uint16, uint8)
+OCTAVE_CONCAT_FN2 (uint16, uint32)
+OCTAVE_CONCAT_FN2 (uint16, uint64)
+
+OCTAVE_CONCAT_FN2 (uint32, int8)
+OCTAVE_CONCAT_FN2 (uint32, int16)
+OCTAVE_CONCAT_FN2 (uint32, int32)
+OCTAVE_CONCAT_FN2 (uint32, int64)
+
+OCTAVE_CONCAT_FN2 (uint32, uint8)
+OCTAVE_CONCAT_FN2 (uint32, uint16)
+OCTAVE_CONCAT_FN2 (uint32, uint64)
+
+OCTAVE_CONCAT_FN2 (uint64, int8)
+OCTAVE_CONCAT_FN2 (uint64, int16)
+OCTAVE_CONCAT_FN2 (uint64, int32)
+OCTAVE_CONCAT_FN2 (uint64, int64)
+
+OCTAVE_CONCAT_FN2 (uint64, uint8)
+OCTAVE_CONCAT_FN2 (uint64, uint16)
+OCTAVE_CONCAT_FN2 (uint64, uint32)
+
+OCTAVE_INT_DOUBLE_CONCAT_FN (int8)
+OCTAVE_INT_DOUBLE_CONCAT_FN (int16)
+OCTAVE_INT_DOUBLE_CONCAT_FN (int32)
+OCTAVE_INT_DOUBLE_CONCAT_FN (int64)
+
+OCTAVE_INT_DOUBLE_CONCAT_FN (uint8)
+OCTAVE_INT_DOUBLE_CONCAT_FN (uint16)
+OCTAVE_INT_DOUBLE_CONCAT_FN (uint32)
+OCTAVE_INT_DOUBLE_CONCAT_FN (uint64)
+
+OCTAVE_DOUBLE_INT_CONCAT_FN (int8)
+OCTAVE_DOUBLE_INT_CONCAT_FN (int16)
+OCTAVE_DOUBLE_INT_CONCAT_FN (int32)
+OCTAVE_DOUBLE_INT_CONCAT_FN (int64)
+	      	   
+OCTAVE_DOUBLE_INT_CONCAT_FN (uint8)
+OCTAVE_DOUBLE_INT_CONCAT_FN (uint16)
+OCTAVE_DOUBLE_INT_CONCAT_FN (uint32)
+OCTAVE_DOUBLE_INT_CONCAT_FN (uint64)
+
+OCTAVE_INT_FLOAT_CONCAT_FN (int8)
+OCTAVE_INT_FLOAT_CONCAT_FN (int16)
+OCTAVE_INT_FLOAT_CONCAT_FN (int32)
+OCTAVE_INT_FLOAT_CONCAT_FN (int64)
+
+OCTAVE_INT_FLOAT_CONCAT_FN (uint8)
+OCTAVE_INT_FLOAT_CONCAT_FN (uint16)
+OCTAVE_INT_FLOAT_CONCAT_FN (uint32)
+OCTAVE_INT_FLOAT_CONCAT_FN (uint64)
+
+OCTAVE_FLOAT_INT_CONCAT_FN (int8)
+OCTAVE_FLOAT_INT_CONCAT_FN (int16)
+OCTAVE_FLOAT_INT_CONCAT_FN (int32)
+OCTAVE_FLOAT_INT_CONCAT_FN (int64)
+	      	   
+OCTAVE_FLOAT_INT_CONCAT_FN (uint8)
+OCTAVE_FLOAT_INT_CONCAT_FN (uint16)
+OCTAVE_FLOAT_INT_CONCAT_FN (uint32)
+OCTAVE_FLOAT_INT_CONCAT_FN (uint64)
+
+OCTAVE_INT_CHAR_CONCAT_FN (int8)
+OCTAVE_INT_CHAR_CONCAT_FN (int16)
+OCTAVE_INT_CHAR_CONCAT_FN (int32)
+OCTAVE_INT_CHAR_CONCAT_FN (int64)
+
+OCTAVE_INT_CHAR_CONCAT_FN (uint8)
+OCTAVE_INT_CHAR_CONCAT_FN (uint16)
+OCTAVE_INT_CHAR_CONCAT_FN (uint32)
+OCTAVE_INT_CHAR_CONCAT_FN (uint64)
+
+OCTAVE_CHAR_INT_CONCAT_FN (int8)
+OCTAVE_CHAR_INT_CONCAT_FN (int16)
+OCTAVE_CHAR_INT_CONCAT_FN (int32)
+OCTAVE_CHAR_INT_CONCAT_FN (int64)
+	      	   
+OCTAVE_CHAR_INT_CONCAT_FN (uint8)
+OCTAVE_CHAR_INT_CONCAT_FN (uint16)
+OCTAVE_CHAR_INT_CONCAT_FN (uint32)
+OCTAVE_CHAR_INT_CONCAT_FN (uint64)
+
+void
+install_int_concat_ops (void)
+{
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, int32);
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, uint32);
+  OCTAVE_INSTALL_CONCAT_FN2 (int8, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, int32);
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, uint32);
+  OCTAVE_INSTALL_CONCAT_FN2 (int16, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, uint32);
+  OCTAVE_INSTALL_CONCAT_FN2 (int32, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, int32);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, uint32);
+  OCTAVE_INSTALL_CONCAT_FN2 (int64, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, int32);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, uint32);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint8, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, int32);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, uint32);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint16, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, int32);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint32, uint64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, int8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, int16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, int32);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, int64);
+
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, uint8);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, uint16);
+  OCTAVE_INSTALL_CONCAT_FN2 (uint64, uint32);
+
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (int8);
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (int16);
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (int32);
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (int8);
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (int16);
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (int32);
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (int8);
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (int16);
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (int32);
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (int8);
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (int16);
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (int32);
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int8);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int16);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int32);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int8);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int16);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int32);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-int-conv.cc b/src/OPERATORS/op-int-conv.cc
new file mode 100644
index 0000000..3706191
--- /dev/null
+++ b/src/OPERATORS/op-int-conv.cc
@@ -0,0 +1,252 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-range.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#define DEFINTCONVFN(name, tfrom, tto) \
+  CONVDECL (name) \
+  { \
+    CAST_CONV_ARG (const octave_ ## tfrom&); \
+ \
+    octave_ ## tto ::clear_conv_flag (); \
+    octave_ ## tto ## _matrix v2 = v.tto ## _array_value (); \
+    if (octave_ ## tto ::get_trunc_flag ()) \
+      gripe_truncated_conversion (v.type_name (). c_str (), \
+				  v2.type_name (). c_str ()); \
+    if (octave_ ## tto ::get_nan_flag ()) \
+      gripe_nan_conversion (v.type_name (). c_str (), \
+			    v2.type_name (). c_str ()); \
+    if (octave_ ## tto ::get_non_int_flag ()) \
+      gripe_non_integer_conversion (v.type_name (). c_str (), \
+			            v2.type_name (). c_str ()); \
+    octave_ ## tto ::clear_conv_flag (); \
+    return new octave_ ## tto ## _matrix (v2); \
+  }
+
+// conversion ops
+
+DEFINTCONVFN (scalar_to_int8, scalar, int8)
+DEFINTCONVFN (scalar_to_int16, scalar, int16)
+DEFINTCONVFN (scalar_to_int32, scalar, int32)
+DEFINTCONVFN (scalar_to_int64, scalar, int64)
+
+DEFINTCONVFN (scalar_to_uint8, scalar, uint8)
+DEFINTCONVFN (scalar_to_uint16, scalar, uint16)
+DEFINTCONVFN (scalar_to_uint32, scalar, uint32)
+DEFINTCONVFN (scalar_to_uint64, scalar, uint64)
+
+DEFINTCONVFN (matrix_to_int8, matrix, int8)
+DEFINTCONVFN (matrix_to_int16, matrix, int16)
+DEFINTCONVFN (matrix_to_int32, matrix, int32)
+DEFINTCONVFN (matrix_to_int64, matrix, int64)
+
+DEFINTCONVFN (matrix_to_uint8, matrix, uint8)
+DEFINTCONVFN (matrix_to_uint16, matrix, uint16)
+DEFINTCONVFN (matrix_to_uint32, matrix, uint32)
+DEFINTCONVFN (matrix_to_uint64, matrix, uint64)
+
+DEFINTCONVFN (float_scalar_to_int8, float_scalar, int8)
+DEFINTCONVFN (float_scalar_to_int16, float_scalar, int16)
+DEFINTCONVFN (float_scalar_to_int32, float_scalar, int32)
+DEFINTCONVFN (float_scalar_to_int64, float_scalar, int64)
+
+DEFINTCONVFN (float_scalar_to_uint8, float_scalar, uint8)
+DEFINTCONVFN (float_scalar_to_uint16, float_scalar, uint16)
+DEFINTCONVFN (float_scalar_to_uint32, float_scalar, uint32)
+DEFINTCONVFN (float_scalar_to_uint64, float_scalar, uint64)
+
+DEFINTCONVFN (float_matrix_to_int8, float_matrix, int8)
+DEFINTCONVFN (float_matrix_to_int16, float_matrix, int16)
+DEFINTCONVFN (float_matrix_to_int32, float_matrix, int32)
+DEFINTCONVFN (float_matrix_to_int64, float_matrix, int64)
+
+DEFINTCONVFN (float_matrix_to_uint8, float_matrix, uint8)
+DEFINTCONVFN (float_matrix_to_uint16, float_matrix, uint16)
+DEFINTCONVFN (float_matrix_to_uint32, float_matrix, uint32)
+DEFINTCONVFN (float_matrix_to_uint64, float_matrix, uint64)
+
+DEFCONVFN (bool_to_int8, bool, int8)
+DEFCONVFN (bool_to_int16, bool, int16)
+DEFCONVFN (bool_to_int32, bool, int32)
+DEFCONVFN (bool_to_int64, bool, int64)
+
+DEFCONVFN (bool_to_uint8, bool, uint8)
+DEFCONVFN (bool_to_uint16, bool, uint16)
+DEFCONVFN (bool_to_uint32, bool, uint32)
+DEFCONVFN (bool_to_uint64, bool, uint64)
+
+DEFCONVFN (bool_matrix_to_int8, bool_matrix, int8)
+DEFCONVFN (bool_matrix_to_int16, bool_matrix, int16)
+DEFCONVFN (bool_matrix_to_int32, bool_matrix, int32)
+DEFCONVFN (bool_matrix_to_int64, bool_matrix, int64)
+
+DEFCONVFN (bool_matrix_to_uint8, bool_matrix, uint8)
+DEFCONVFN (bool_matrix_to_uint16, bool_matrix, uint16)
+DEFCONVFN (bool_matrix_to_uint32, bool_matrix, uint32)
+DEFCONVFN (bool_matrix_to_uint64, bool_matrix, uint64)
+
+DEFSTRINTCONVFN (char_matrix_sq_str_to_int8, int8)
+DEFSTRINTCONVFN (char_matrix_sq_str_to_int16, int16)
+DEFSTRINTCONVFN (char_matrix_sq_str_to_int32, int32)
+DEFSTRINTCONVFN (char_matrix_sq_str_to_int64, int64)
+
+DEFSTRINTCONVFN (char_matrix_sq_str_to_uint8, uint8)
+DEFSTRINTCONVFN (char_matrix_sq_str_to_uint16, uint16)
+DEFSTRINTCONVFN (char_matrix_sq_str_to_uint32, uint32)
+DEFSTRINTCONVFN (char_matrix_sq_str_to_uint64, uint64)
+
+DEFSTRINTCONVFN (char_matrix_dq_str_to_int8, int8)
+DEFSTRINTCONVFN (char_matrix_dq_str_to_int16, int16)
+DEFSTRINTCONVFN (char_matrix_dq_str_to_int32, int32)
+DEFSTRINTCONVFN (char_matrix_dq_str_to_int64, int64)
+
+DEFSTRINTCONVFN (char_matrix_dq_str_to_uint8, uint8)
+DEFSTRINTCONVFN (char_matrix_dq_str_to_uint16, uint16)
+DEFSTRINTCONVFN (char_matrix_dq_str_to_uint32, uint32)
+DEFSTRINTCONVFN (char_matrix_dq_str_to_uint64, uint64)
+
+DEFINTCONVFN (range_to_int8, range, int8)
+DEFINTCONVFN (range_to_int16, range, int16)
+DEFINTCONVFN (range_to_int32, range, int32)
+DEFINTCONVFN (range_to_int64, range, int64)
+
+DEFINTCONVFN (range_to_uint8, range, uint8)
+DEFINTCONVFN (range_to_uint16, range, uint16)
+DEFINTCONVFN (range_to_uint32, range, uint32)
+DEFINTCONVFN (range_to_uint64, range, uint64)
+
+#define INT_CONV_FUNCTIONS(tfrom) \
+  DEFCONVFN2 (tfrom ## _scalar_to_int8, tfrom, scalar, int8) \
+  DEFCONVFN2 (tfrom ## _scalar_to_int16, tfrom, scalar, int16) \
+  DEFCONVFN2 (tfrom ## _scalar_to_int32, tfrom, scalar, int32) \
+  DEFCONVFN2 (tfrom ## _scalar_to_int64, tfrom, scalar, int64) \
+ \
+  DEFCONVFN2 (tfrom ## _scalar_to_uint8, tfrom, scalar, uint8) \
+  DEFCONVFN2 (tfrom ## _scalar_to_uint16, tfrom, scalar, uint16) \
+  DEFCONVFN2 (tfrom ## _scalar_to_uint32, tfrom, scalar, uint32) \
+  DEFCONVFN2 (tfrom ## _scalar_to_uint64, tfrom, scalar, uint64) \
+ \
+  DEFCONVFN2 (tfrom ## _matrix_to_int8, tfrom, matrix, int8) \
+  DEFCONVFN2 (tfrom ## _matrix_to_int16, tfrom, matrix, int16) \
+  DEFCONVFN2 (tfrom ## _matrix_to_int32, tfrom, matrix, int32) \
+  DEFCONVFN2 (tfrom ## _matrix_to_int64, tfrom, matrix, int64) \
+ \
+  DEFCONVFN2 (tfrom ## _matrix_to_uint8, tfrom, matrix, uint8) \
+  DEFCONVFN2 (tfrom ## _matrix_to_uint16, tfrom, matrix, uint16) \
+  DEFCONVFN2 (tfrom ## _matrix_to_uint32, tfrom, matrix, uint32) \
+  DEFCONVFN2 (tfrom ## _matrix_to_uint64, tfrom, matrix, uint64)
+
+INT_CONV_FUNCTIONS (int8)
+INT_CONV_FUNCTIONS (int16)
+INT_CONV_FUNCTIONS (int32)
+INT_CONV_FUNCTIONS (int64)
+
+INT_CONV_FUNCTIONS (uint8)
+INT_CONV_FUNCTIONS (uint16)
+INT_CONV_FUNCTIONS (uint32)
+INT_CONV_FUNCTIONS (uint64)
+
+#define INSTALL_INT_CONV_FUNCTIONS(tfrom) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_int8_matrix, tfrom ## _scalar_to_int8) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_int16_matrix, tfrom ## _scalar_to_int16) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_int32_matrix, tfrom ## _scalar_to_int32) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_int64_matrix, tfrom ## _scalar_to_int64) \
+ \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_uint8_matrix, tfrom ## _scalar_to_uint8) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_uint16_matrix, tfrom ## _scalar_to_uint16) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_uint32_matrix, tfrom ## _scalar_to_uint32) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _scalar, octave_uint64_matrix, tfrom ## _scalar_to_uint64) \
+ \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_int8_matrix, tfrom ## _matrix_to_int8) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_int16_matrix, tfrom ## _matrix_to_int16) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_int32_matrix, tfrom ## _matrix_to_int32) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_int64_matrix, tfrom ## _matrix_to_int64) \
+ \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_uint8_matrix, tfrom ## _matrix_to_uint8) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_uint16_matrix, tfrom ## _matrix_to_uint16) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_uint32_matrix, tfrom ## _matrix_to_uint32) \
+  INSTALL_CONVOP (octave_ ## tfrom ## _matrix, octave_uint64_matrix, tfrom ## _matrix_to_uint64)
+
+#define INSTALL_CONVOPS(tfrom) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_int8_matrix, tfrom ## _to_int8) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_int16_matrix, tfrom ## _to_int16) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_int32_matrix, tfrom ## _to_int32) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_int64_matrix, tfrom ## _to_int64) \
+ \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_uint8_matrix, tfrom ## _to_uint8) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_uint16_matrix, tfrom ## _to_uint16) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_uint32_matrix, tfrom ## _to_uint32) \
+  INSTALL_CONVOP (octave_ ## tfrom, octave_uint64_matrix, tfrom ## _to_uint64)
+
+void
+install_int_conv_ops (void)
+{
+  INSTALL_CONVOPS (scalar)
+  INSTALL_CONVOPS (matrix)
+  INSTALL_CONVOPS (float_scalar)
+  INSTALL_CONVOPS (float_matrix)
+  INSTALL_CONVOPS (bool)
+  INSTALL_CONVOPS (bool_matrix)
+  INSTALL_CONVOPS (range)
+  INSTALL_CONVOPS (char_matrix_sq_str)
+  INSTALL_CONVOPS (char_matrix_dq_str)
+
+  INSTALL_INT_CONV_FUNCTIONS (int8)
+  INSTALL_INT_CONV_FUNCTIONS (int16)
+  INSTALL_INT_CONV_FUNCTIONS (int32)
+  INSTALL_INT_CONV_FUNCTIONS (int64)
+
+  INSTALL_INT_CONV_FUNCTIONS (uint8)
+  INSTALL_INT_CONV_FUNCTIONS (uint16)
+  INSTALL_INT_CONV_FUNCTIONS (uint32)
+  INSTALL_INT_CONV_FUNCTIONS (uint64)
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-int.h b/src/OPERATORS/op-int.h
new file mode 100644
index 0000000..d662faa
--- /dev/null
+++ b/src/OPERATORS/op-int.h
@@ -0,0 +1,1197 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include "quit.h"
+
+#define DEFINTBINOP_OP(name, t1, t2, op, t3) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value \
+      (v1.t1 ## _value () op v2.t2 ## _value ()); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define DEFINTNDBINOP_OP(name, t1, t2, e1, e2, op, t3) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value \
+      (v1.e1 ## _value () op v2.e2 ## _value ()); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define DEFINTBINOP_FN(name, t1, t2, f, t3, op)	\
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value (f (v1.t1 ## _value (), v2.t2 ## _value ())); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define DEFINTNDBINOP_FN(name, t1, t2, e1, e2, f, t3, op)	\
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define OCTAVE_CONCAT_FN2(T1, T2) \
+  DEFNDCATOP_FN2 (T1 ## _ ## T2 ## _s_s, T1 ## _scalar, T2 ## _scalar, , T1 ## NDArray, T1 ## _array, T2 ## _array, concat) \
+  DEFNDCATOP_FN2 (T1 ## _ ## T2 ## _s_m, T1 ## _scalar, T2 ## _matrix, , T1 ## NDArray, T1 ## _array, T2 ## _array, concat) \
+  DEFNDCATOP_FN2 (T1 ## _ ## T2 ## _m_s, T1 ## _matrix, T2 ## _scalar, , T1 ## NDArray, T1 ## _array, T2 ## _array, concat) \
+  DEFNDCATOP_FN2 (T1 ## _ ## T2 ## _m_m, T1 ## _matrix, T2 ## _matrix, , T1 ## NDArray, T1 ## _array, T2 ## _array, concat)
+
+#define OCTAVE_INSTALL_CONCAT_FN2(T1, T2) \
+  INSTALL_CATOP (octave_ ## T1 ## _scalar, octave_ ## T2 ## _scalar, T1 ## _ ## T2 ## _s_s) \
+  INSTALL_CATOP (octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, T1 ## _ ## T2 ## _s_m) \
+  INSTALL_CATOP (octave_ ## T1 ## _matrix, octave_ ## T2 ## _scalar, T1 ## _ ## T2 ## _m_s) \
+  INSTALL_CATOP (octave_ ## T1 ## _matrix, octave_ ## T2 ## _matrix, T1 ## _ ## T2 ## _m_m)
+
+#define OCTAVE_DOUBLE_INT_CONCAT_FN(TYPE) \
+  DEFNDCATOP_FN2 (double ## _ ## TYPE ## _s_s, scalar, TYPE ## _scalar, TYPE ## NDArray, , array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN2 (double ## _ ## TYPE ## _s_m, scalar, TYPE ## _matrix, TYPE ## NDArray, , array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN2 (double ## _ ## TYPE ## _m_s, matrix, TYPE ## _scalar, TYPE ## NDArray, , array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN2 (double ## _ ## TYPE ## _m_m, matrix, TYPE ## _matrix, TYPE ## NDArray, , array, TYPE ## _array, concat)
+
+#define OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_scalar, octave_ ## TYPE ## _scalar, double ## _ ## TYPE ## _s_s) \
+  INSTALL_CATOP (octave_scalar, octave_ ## TYPE ## _matrix, double ## _ ## TYPE ## _s_m) \
+  INSTALL_CATOP (octave_matrix, octave_ ## TYPE ## _scalar, double ## _ ## TYPE ## _m_s) \
+  INSTALL_CATOP (octave_matrix, octave_ ## TYPE ## _matrix, double ## _ ## TYPE ## _m_m)
+
+#define OCTAVE_INT_DOUBLE_CONCAT_FN(TYPE) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## double ## _s_s, TYPE ## _scalar, scalar, , TYPE ## NDArray, TYPE ## _array, array, concat) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## double ## _s_m, TYPE ## _scalar, matrix, , TYPE ## NDArray, TYPE ## _array, array, concat) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## double ## _m_s, TYPE ## _matrix, scalar, , TYPE ## NDArray, TYPE ## _array, array, concat) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## double ## _m_m, TYPE ## _matrix, matrix, , TYPE ## NDArray, TYPE ## _array, array, concat)
+
+#define OCTAVE_INSTALL_INT_DOUBLE_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_scalar, TYPE ## _ ## double ## _s_s) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_matrix, TYPE ## _ ## double ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_scalar, TYPE ## _ ## double ## _m_s) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_matrix, TYPE ## _ ## double ## _m_m)
+
+#define OCTAVE_FLOAT_INT_CONCAT_FN(TYPE) \
+  DEFNDCATOP_FN2 (float ## _ ## TYPE ## _s_s, float_scalar, TYPE ## _scalar, TYPE ## NDArray, , float_array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN2 (float ## _ ## TYPE ## _s_m, float_scalar, TYPE ## _matrix, TYPE ## NDArray, , float_array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN2 (float ## _ ## TYPE ## _m_s, float_matrix, TYPE ## _scalar, TYPE ## NDArray, , float_array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN2 (float ## _ ## TYPE ## _m_m, float_matrix, TYPE ## _matrix, TYPE ## NDArray, , float_array, TYPE ## _array, concat)
+
+#define OCTAVE_INSTALL_FLOAT_INT_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_float_scalar, octave_ ## TYPE ## _scalar, float ## _ ## TYPE ## _s_s) \
+  INSTALL_CATOP (octave_float_scalar, octave_ ## TYPE ## _matrix, float ## _ ## TYPE ## _s_m) \
+  INSTALL_CATOP (octave_float_matrix, octave_ ## TYPE ## _scalar, float ## _ ## TYPE ## _m_s) \
+  INSTALL_CATOP (octave_float_matrix, octave_ ## TYPE ## _matrix, float ## _ ## TYPE ## _m_m)
+
+#define OCTAVE_INT_FLOAT_CONCAT_FN(TYPE) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## float ## _s_s, TYPE ## _scalar, float_scalar, , TYPE ## NDArray, TYPE ## _array, float_array, concat) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## float ## _s_m, TYPE ## _scalar, float_matrix, , TYPE ## NDArray, TYPE ## _array, float_array, concat) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## float ## _m_s, TYPE ## _matrix, float_scalar, , TYPE ## NDArray, TYPE ## _array, float_array, concat) \
+  DEFNDCATOP_FN2 (TYPE ## _ ## float ## _m_m, TYPE ## _matrix, float_matrix, , TYPE ## NDArray, TYPE ## _array, float_array, concat)
+
+#define OCTAVE_INSTALL_INT_FLOAT_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_float_scalar, TYPE ## _ ## float ## _s_s) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_float_matrix, TYPE ## _ ## float ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_float_scalar, TYPE ## _ ## float ## _m_s) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_float_matrix, TYPE ## _ ## float ## _m_m)
+
+// For compatibility, concatenation with a character always returns a
+// character.
+
+#define OCTAVE_CHAR_INT_CONCAT_FN(TYPE) \
+  DEFNDCHARCATOP_FN (char ## _ ## TYPE ## _m_s, char_matrix, TYPE ## _scalar, concat) \
+  DEFNDCHARCATOP_FN (char ## _ ## TYPE ## _m_m, char_matrix, TYPE ## _matrix, concat)
+
+#define OCTAVE_INSTALL_CHAR_INT_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_char_matrix_str, octave_ ## TYPE ## _scalar, char ## _ ## TYPE ## _m_s) \
+  INSTALL_CATOP (octave_char_matrix_str, octave_ ## TYPE ## _matrix, char ## _ ## TYPE ## _m_m) \
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_ ## TYPE ## _scalar, char ## _ ## TYPE ## _m_s) \
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_ ## TYPE ## _matrix, char ## _ ## TYPE ## _m_m)
+
+#define OCTAVE_INT_CHAR_CONCAT_FN(TYPE) \
+  DEFNDCHARCATOP_FN (TYPE ## _ ## char ## _s_m, TYPE ## _scalar, char_matrix, concat) \
+  DEFNDCHARCATOP_FN (TYPE ## _ ## char ## _m_m, TYPE ## _matrix, char_matrix, concat)
+
+#define OCTAVE_INSTALL_INT_CHAR_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_char_matrix_str, TYPE ## _ ## char ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_char_matrix_str, TYPE ## _ ## char ## _m_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_char_matrix_sq_str, TYPE ## _ ## char ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_char_matrix_sq_str, TYPE ## _ ## char ## _m_m)
+
+#define OCTAVE_CONCAT_FN(TYPE) \
+  DEFNDCATOP_FN (TYPE ## _s_s, TYPE ## _scalar, TYPE ## _scalar, TYPE ## _array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN (TYPE ## _s_m, TYPE ## _scalar, TYPE ## _matrix, TYPE ## _array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN (TYPE ## _m_s, TYPE ## _matrix, TYPE ## _scalar, TYPE ## _array, TYPE ## _array, concat) \
+  DEFNDCATOP_FN (TYPE ## _m_m, TYPE ## _matrix, TYPE ## _matrix, TYPE ## _array, TYPE ## _array, concat)
+
+#define OCTAVE_INSTALL_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _scalar, TYPE ## _s_s) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _matrix, TYPE ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_ ## TYPE ## _scalar, TYPE ## _m_s) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_ ## TYPE ## _matrix, TYPE ## _m_m)
+
+#define OCTAVE_S_INT_UNOPS(TYPE) \
+  /* scalar unary ops. */  \
+ \
+  DEFUNOP_OP (s_not, TYPE ## _scalar, !) \
+  DEFUNOP_OP (s_uplus, TYPE ## _scalar, /* no-op */) \
+  DEFUNOP (s_uminus, TYPE ## _scalar) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## TYPE ## _scalar &); \
+    octave_value retval = octave_value (- v. TYPE ## _scalar_value ()); \
+    if (octave_ ## TYPE ::get_math_trunc_flag ()) \
+      gripe_unop_integer_math_truncated ("-", v.type_name (). c_str ()); \
+    octave_ ## TYPE ::clear_conv_flag (); \
+    return retval; \
+  } \
+  DEFUNOP_OP (s_transpose, TYPE ## _scalar, /* no-op */) \
+  DEFUNOP_OP (s_hermitian, TYPE ## _scalar, /* no-op */) \
+ \
+  DEFNCUNOP_METHOD (s_incr, TYPE ## _scalar, increment) \
+  DEFNCUNOP_METHOD (s_decr, TYPE ## _scalar, decrement)
+
+#define OCTAVE_SS_INT_ARITH_OPS(PFX, T1, T2, T3)	\
+  /* scalar by scalar ops. */ \
+ \
+  DEFINTBINOP_OP (PFX ## _add, T1 ## scalar, T2 ## scalar, +, T3) \
+  DEFINTBINOP_OP (PFX ## _sub, T1 ## scalar, T2 ## scalar, -, T3) \
+  DEFINTBINOP_OP (PFX ## _mul, T1 ## scalar, T2 ## scalar, *, T3) \
+ \
+  DEFBINOP (PFX ## _div, T1 ## scalar, T2 ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+ \
+    if (! v2.T2 ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v1.T1 ## scalar_value () / v2.T2 ## scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("/", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTBINOP_FN (PFX ## _pow, T1 ## scalar, T2 ## scalar, xpow, T3, ^)	\
+ \
+  DEFBINOP (PFX ## _ldiv, T1 ## scalar, T2 ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+ \
+    if (! v1.T1 ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v2.T2 ## scalar_value () / v1.T1 ## scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+          gripe_binop_integer_math_truncated ("\\", v1.type_name (). c_str (), \
+					      v2.type_name (). c_str ()); \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTBINOP_OP (PFX ## _el_mul, T1 ## scalar, T2 ## scalar, *, T3)	\
+ \
+  DEFBINOP (PFX ## _el_div, T1 ## scalar, T2 ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+ \
+    if (! v2.T2 ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v1.T1 ## scalar_value () / v2.T2 ## scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ()); \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTBINOP_FN (PFX ## _el_pow, T1 ## scalar, T2 ## scalar, xpow, T3, .^) \
+ \
+  DEFBINOP (PFX ## _el_ldiv, T1 ## scalar, T2 ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+ \
+    if (! v1.T1 ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v2.T2 ## scalar_value () / v1.T1 ## scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+
+#define OCTAVE_SS_INT_BOOL_OPS(PFX, T1, T2, Z1, Z2) \
+  DEFBINOP (PFX ## _el_and, T2, T2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+ \
+    return v1.T1 ## scalar_value () != Z1 && v2.T2 ## scalar_value () != Z2; \
+  } \
+ \
+  DEFBINOP (PFX ## _el_or, T1, T2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+ \
+    return v1.T1 ## scalar_value () != Z1 || v2.T2 ## scalar_value () != Z2; \
+  }
+
+#define OCTAVE_SS_INT_CMP_OPS(PFX, T1, T2) \
+  DEFBINOP_OP (PFX ## _lt, T1 ## scalar, T2 ## scalar, <) \
+  DEFBINOP_OP (PFX ## _le, T1 ## scalar, T2 ## scalar, <=) \
+  DEFBINOP_OP (PFX ## _eq, T1 ## scalar, T2 ## scalar, ==) \
+  DEFBINOP_OP (PFX ## _ge, T1 ## scalar, T2 ## scalar, >=) \
+  DEFBINOP_OP (PFX ## _gt, T1 ## scalar, T2 ## scalar, >) \
+  DEFBINOP_OP (PFX ## _ne, T1 ## scalar, T2 ## scalar, !=)
+
+#define OCTAVE_SS_POW_OPS(T1, T2) \
+  octave_value \
+  xpow (const octave_ ## T1& a, const octave_ ## T2& b) \
+  { \
+    return pow (a, b); \
+  } \
+ \
+  octave_value \
+  xpow (const octave_ ## T1& a, double b) \
+  { \
+    return pow (a, b); \
+  } \
+ \
+  octave_value \
+  xpow (double a, const octave_ ## T1& b) \
+  { \
+    return pow (a, b); \
+  } \
+ \
+  octave_value \
+  xpow (const octave_ ## T1& a, float b) \
+  { \
+    return powf (a, b); \
+  } \
+ \
+  octave_value \
+  xpow (float a, const octave_ ## T1& b) \
+  { \
+    return powf (a, b); \
+  }
+
+#define OCTAVE_SS_INT_OPS(TYPE) \
+  OCTAVE_S_INT_UNOPS (TYPE) \
+  OCTAVE_SS_POW_OPS (TYPE, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (ss, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (ssx, TYPE ## _, , TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (sxs, , TYPE ## _, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (ssfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (sfxs, float_, TYPE ## _, TYPE) \
+  OCTAVE_SS_INT_CMP_OPS (ss, TYPE ## _, TYPE ## _) \
+  OCTAVE_SS_INT_CMP_OPS (sx, TYPE ## _, ) \
+  OCTAVE_SS_INT_CMP_OPS (xs, , TYPE ## _) \
+  OCTAVE_SS_INT_CMP_OPS (sfx, TYPE ## _, float_) \
+  OCTAVE_SS_INT_CMP_OPS (fxs, float_, TYPE ## _) \
+  OCTAVE_SS_INT_BOOL_OPS (ss, TYPE ## _, TYPE ## _, octave_ ## TYPE (0), octave_ ## TYPE (0)) \
+  OCTAVE_SS_INT_BOOL_OPS (sx, TYPE ## _, , octave_ ## TYPE (0), 0) \
+  OCTAVE_SS_INT_BOOL_OPS (xs, , TYPE ## _, 0, octave_ ## TYPE (0)) \
+  OCTAVE_SS_INT_BOOL_OPS (sfx, TYPE ## _, float_, octave_ ## TYPE (0), 0) \
+  OCTAVE_SS_INT_BOOL_OPS (fxs, float_, TYPE ## _, 0, octave_ ## TYPE (0))
+
+#define OCTAVE_SM_INT_ARITH_OPS(PFX, TS, TM, TI) \
+  /* scalar by matrix ops. */ \
+ \
+  DEFINTNDBINOP_OP (PFX ## _add, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, +, TI) \
+  DEFINTNDBINOP_OP (PFX ## _sub, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, -, TI) \
+  DEFINTNDBINOP_OP (PFX ## _mul, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, *, TI) \
+ \
+  /* DEFBINOP (PFX ## _div, TS ## scalar, TM ## matrix) */ \
+  /* { */ \
+  /* CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); */ \
+  /* */ \
+  /* Matrix m1 = v1.TM ## matrix_value (); */ \
+  /* Matrix m2 = v2.TM ## matrix_value (); */ \
+  /* */ \
+  /* return octave_value (xdiv (m1, m2)); */ \
+  /* } */ \
+ \
+  /* DEFBINOP_FN (PFX ## _pow, TS ## scalar, TM ## matrix, xpow) */ \
+ \
+  DEFBINOP (PFX ## _ldiv, TS ## scalar, TM ## matrix) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); \
+ \
+    if (! v1.TS ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v2.TS ## scalar_value () / v1.TS ## scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("\\", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTNDBINOP_OP (PFX ## _el_mul, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, *, TI) \
+  DEFBINOP (PFX ## _el_div, TS ## scalar, TM ## matrix) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); \
+ \
+    octave_value retval = octave_value (v1.TS ## scalar_value () / v2.TM ## array_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_pow, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, elem_xpow, TI, .^) \
+ \
+  DEFBINOP (PFX ## _el_ldiv, TS ## scalar, TM ## matrix) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); \
+ \
+    if (! v1.TS ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v2.TM ## array_value () / v1.TS ## scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define OCTAVE_SM_INT_CMP_OPS(PFX, TS, TM) \
+  DEFNDBINOP_FN (PFX ## _lt, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_lt) \
+  DEFNDBINOP_FN (PFX ## _le, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_le) \
+  DEFNDBINOP_FN (PFX ## _eq, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_eq) \
+  DEFNDBINOP_FN (PFX ## _ge, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_ge) \
+  DEFNDBINOP_FN (PFX ## _gt, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_gt) \
+  DEFNDBINOP_FN (PFX ## _ne, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_ne)
+
+#define OCTAVE_SM_INT_BOOL_OPS(PFX, TS, TM) \
+  DEFNDBINOP_FN (PFX ## _el_and, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_and) \
+  DEFNDBINOP_FN (PFX ## _el_or,  TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_or) \
+  DEFNDBINOP_FN (PFX ## _el_and_not, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_and_not) \
+  DEFNDBINOP_FN (PFX ## _el_or_not,  TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_or_not)
+
+#define OCTAVE_SM_POW_OPS(T1, T2) \
+  octave_value \
+  elem_xpow (const octave_ ## T1& a, const T2 ## NDArray& b) \
+  { \
+    T2 ## NDArray result (b.dims ()); \
+    for (int i = 0; i < b.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = pow (a, b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+\
+  octave_value \
+  elem_xpow (const octave_ ## T1& a, const NDArray& b) \
+  { \
+    T1 ## NDArray result (b.dims ()); \
+    for (int i = 0; i < b.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = pow (a, b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+ \
+  octave_value \
+  elem_xpow (double a, const T2 ## NDArray& b) \
+  { \
+    T2 ## NDArray result (b.dims ()); \
+    for (int i = 0; i < b.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = pow (a, b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+\
+  octave_value \
+  elem_xpow (const octave_ ## T1& a, const FloatNDArray& b) \
+  { \
+    T1 ## NDArray result (b.dims ()); \
+    for (int i = 0; i < b.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = powf (a, b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+ \
+  octave_value \
+  elem_xpow (float a, const T2 ## NDArray& b) \
+  { \
+    T2 ## NDArray result (b.dims ()); \
+    for (int i = 0; i < b.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = powf (a, b(i)); \
+      } \
+    return octave_value (result); \
+  }
+
+
+#define OCTAVE_SM_CONV(TS, TM) \
+  DEFCONV (TS ## s_ ## TM ## m_conv, TM ## scalar, TM ## matrix) \
+  { \
+    CAST_CONV_ARG (const octave_ ## TS ## scalar&); \
+ \
+    return new octave_ ## TM ## matrix (v.TM ## array_value ()); \
+  }
+
+#define OCTAVE_SM_INT_OPS(TYPE) \
+  OCTAVE_SM_POW_OPS (TYPE, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (sm, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (smx, TYPE ## _, , TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (sxm, , TYPE ## _, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (smfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (sfxm, float_, TYPE ## _, TYPE) \
+  OCTAVE_SM_INT_CMP_OPS (sm, TYPE ## _, TYPE ## _) \
+  OCTAVE_SM_INT_CMP_OPS (xm, , TYPE ## _) \
+  OCTAVE_SM_INT_CMP_OPS (smx, TYPE ## _, ) \
+  OCTAVE_SM_INT_CMP_OPS (fxm, float_, TYPE ## _) \
+  OCTAVE_SM_INT_CMP_OPS (smfx, TYPE ## _, float_) \
+  OCTAVE_SM_INT_BOOL_OPS (sm, TYPE ## _, TYPE ## _) \
+  OCTAVE_SM_INT_BOOL_OPS (xm, , TYPE ## _) \
+  OCTAVE_SM_INT_BOOL_OPS (smx, TYPE ## _, ) \
+  OCTAVE_SM_INT_BOOL_OPS (fxm, float_, TYPE ## _) \
+  OCTAVE_SM_INT_BOOL_OPS (smfx, TYPE ## _, float_) \
+  OCTAVE_SM_CONV (TYPE ## _, TYPE ## _) \
+  OCTAVE_SM_CONV (TYPE ## _, complex_) \
+  OCTAVE_SM_CONV (TYPE ## _, float_complex_)
+
+#define OCTAVE_MS_INT_ARITH_OPS(PFX, TM, TS, TI) \
+  /* matrix by scalar ops. */ \
+ \
+  DEFINTNDBINOP_OP (PFX ## _add, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, +, TI) \
+  DEFINTNDBINOP_OP (PFX ## _sub, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, -, TI) \
+  DEFINTNDBINOP_OP (PFX ## _mul, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, *, TI) \
+ \
+  DEFBINOP (PFX ## _div, TM ## matrix, TS ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); \
+ \
+    if (! v2.TS ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v1.TM ## array_value () / v2.TS ## scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("/", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  /* DEFBINOP_FN (PFX ## _pow, TM ## matrix, TS ## scalar, xpow) */ \
+ \
+  /* DEFBINOP (PFX ## _ldiv, TM ## matrix, TS ## scalar) */ \
+  /* { */ \
+  /* CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); */ \
+  /* */ \
+  /* Matrix m1 = v1.TM ## matrix_value (); */ \
+  /* Matrix m2 = v2.TM ## matrix_value (); */ \
+  /* */ \
+  /* return octave_value (xleftdiv (m1, m2)); */ \
+  /* } */ \
+ \
+  DEFINTNDBINOP_OP (PFX ## _el_mul, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, *, TI) \
+ \
+  DEFBINOP (PFX ## _el_div, TM ## matrix, TS ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); \
+ \
+    if (! v2.TS ## scalar_value ()) \
+      gripe_divide_by_zero (); \
+ \
+    octave_value retval = octave_value (v1.TM ## array_value () / v2.TS ## scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("./", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_pow, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, elem_xpow, TI, .^) \
+ \
+  DEFBINOP (PFX ## _el_ldiv, TM ## matrix, TS ## scalar) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); \
+    \
+    octave_value retval = v2.TS ## scalar_value () / v1.TM ## array_value (); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".^", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define OCTAVE_MS_INT_CMP_OPS(PFX, TM, TS) \
+  DEFNDBINOP_FN (PFX ## _lt, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_lt) \
+  DEFNDBINOP_FN (PFX ## _le, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_le) \
+  DEFNDBINOP_FN (PFX ## _eq, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_eq) \
+  DEFNDBINOP_FN (PFX ## _ge, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_ge) \
+  DEFNDBINOP_FN (PFX ## _gt, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_gt) \
+  DEFNDBINOP_FN (PFX ## _ne, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_ne)
+
+#define OCTAVE_MS_INT_BOOL_OPS(PFX, TM, TS) \
+  DEFNDBINOP_FN (PFX ## _el_and, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_and) \
+  DEFNDBINOP_FN (PFX ## _el_or, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_or) \
+  DEFNDBINOP_FN (PFX ## _el_not_and, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_not_and) \
+  DEFNDBINOP_FN (PFX ## _el_not_or,  TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_not_or)
+
+#define OCTAVE_MS_INT_ASSIGN_OPS(PFX, TM, TS, TE) \
+  DEFNDASSIGNOP_FN (PFX ## _assign, TM ## matrix, TS ## scalar, TM ## scalar, assign)
+
+#define OCTAVE_MS_POW_OPS(T1, T2) \
+octave_value elem_xpow (T1 ## NDArray a, octave_ ## T2  b) \
+{ \
+  T1 ## NDArray result (a.dims ()); \
+  for (int i = 0; i < a.length (); i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = pow (a(i), b);		\
+    } \
+  return octave_value (result); \
+} \
+\
+octave_value elem_xpow (T1 ## NDArray a, double  b) \
+{ \
+  T1 ## NDArray result (a.dims ()); \
+  for (int i = 0; i < a.length (); i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = pow (a(i), b);		\
+    } \
+  return octave_value (result); \
+} \
+\
+octave_value elem_xpow (NDArray a, octave_ ## T2  b) \
+{ \
+  T2 ## NDArray result (a.dims ()); \
+  for (int i = 0; i < a.length (); i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = pow (a(i), b);		\
+    } \
+  return octave_value (result); \
+} \
+\
+octave_value elem_xpow (T1 ## NDArray a, float  b) \
+{ \
+  T1 ## NDArray result (a.dims ()); \
+  for (int i = 0; i < a.length (); i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = powf (a(i), b);		\
+    } \
+  return octave_value (result); \
+} \
+\
+octave_value elem_xpow (FloatNDArray a, octave_ ## T2  b) \
+{ \
+  T2 ## NDArray result (a.dims ()); \
+  for (int i = 0; i < a.length (); i++) \
+    { \
+      OCTAVE_QUIT; \
+      result (i) = powf (a(i), b);		\
+    } \
+  return octave_value (result); \
+}
+
+
+#define OCTAVE_MS_INT_OPS(TYPE) \
+  OCTAVE_MS_POW_OPS (TYPE, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (ms, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (msx, TYPE ## _, , TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (mxs, , TYPE ## _, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (msfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (mfxs, float_, TYPE ## _, TYPE) \
+  OCTAVE_MS_INT_CMP_OPS (ms, TYPE ## _, TYPE ## _) \
+  OCTAVE_MS_INT_CMP_OPS (mx, TYPE ## _, ) \
+  OCTAVE_MS_INT_CMP_OPS (mxs, , TYPE ## _) \
+  OCTAVE_MS_INT_CMP_OPS (mfx, TYPE ## _, float_) \
+  OCTAVE_MS_INT_CMP_OPS (mfxs, float_, TYPE ## _) \
+  OCTAVE_MS_INT_BOOL_OPS (ms, TYPE ## _, TYPE ## _) \
+  OCTAVE_MS_INT_BOOL_OPS (mx, TYPE ## _, ) \
+  OCTAVE_MS_INT_BOOL_OPS (mxs, , TYPE ## _) \
+  OCTAVE_MS_INT_BOOL_OPS (mfx, TYPE ## _, float_) \
+  OCTAVE_MS_INT_BOOL_OPS (mfxs, float_, TYPE ## _) \
+  OCTAVE_MS_INT_ASSIGN_OPS (ms, TYPE ## _, TYPE ## _, TYPE ## _) \
+  OCTAVE_MS_INT_ASSIGN_OPS (mx, TYPE ## _, , ) \
+  OCTAVE_MS_INT_ASSIGN_OPS (mfx, TYPE ## _, float_, float_)
+
+#define OCTAVE_M_INT_UNOPS(TYPE) \
+  /* matrix unary ops. */ \
+ \
+  DEFNDUNOP_OP (m_not, TYPE ## _matrix, TYPE ## _array, !) \
+  DEFNDUNOP_OP (m_uplus, TYPE ## _matrix, TYPE ## _array, /* no-op */) \
+  DEFUNOP (m_uminus, TYPE ## _matrix) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## TYPE ## _matrix &); \
+    octave_value retval = octave_value (- v. TYPE ## _array_value ()); \
+    if (octave_ ## TYPE ::get_math_trunc_flag ()) \
+      gripe_unop_integer_math_truncated ("-", v.type_name (). c_str ()); \
+    octave_ ## TYPE ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFUNOP (m_transpose, TYPE ## _matrix) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## TYPE ## _matrix&); \
+ \
+    if (v.ndims () > 2) \
+      { \
+	error ("transpose not defined for N-d objects"); \
+	return octave_value (); \
+      } \
+    else \
+      return octave_value (v.TYPE ## _array_value().transpose ()); \
+  } \
+ \
+  DEFNCUNOP_METHOD (m_incr, TYPE ## _matrix, increment) \
+  DEFNCUNOP_METHOD (m_decr, TYPE ## _matrix, decrement)
+
+#define OCTAVE_MM_INT_ARITH_OPS(PFX, T1, T2, T3)	\
+  /* matrix by matrix ops. */ \
+ \
+  DEFINTNDBINOP_OP (PFX ## _add, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, +, T3) \
+  DEFINTNDBINOP_OP (PFX ## _sub, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, -, T3) \
+ \
+  /* DEFBINOP_OP (PFX ## _mul, T1 ## matrix, T2 ## matrix, *) */ \
+  /* DEFBINOP_FN (PFX ## _div, T1 ## matrix, T2 ## matrix, xdiv) */ \
+ \
+  DEFBINOPX (PFX ## _pow, T1 ## matrix, T2 ## matrix) \
+  { \
+    error ("can't do A ^ B for A and B both matrices"); \
+    return octave_value (); \
+  } \
+ \
+  /* DEFBINOP_FN (PFX ## _ldiv, T1 ## matrix, T2 ## matrix, xleftdiv) */ \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_mul, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, product, T3, .*) \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_div, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, quotient, T3, ./) \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_pow, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, elem_xpow, T3, .^) \
+ \
+  DEFBINOP (PFX ## _el_ldiv, T1 ## matrix, T2 ## matrix) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## T1 ## matrix&, const octave_ ## T2 ## matrix&); \
+    \
+    octave_value retval = octave_value (quotient (v2.T2 ## array_value (), v1.T1 ## array_value ())); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+					  v2.type_name (). c_str ());	\
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define OCTAVE_MM_INT_CMP_OPS(PFX, T1, T2) \
+  DEFNDBINOP_FN (PFX ## _lt, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_lt) \
+  DEFNDBINOP_FN (PFX ## _le, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_le) \
+  DEFNDBINOP_FN (PFX ## _eq, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_eq) \
+  DEFNDBINOP_FN (PFX ## _ge, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_ge) \
+  DEFNDBINOP_FN (PFX ## _gt, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_gt) \
+  DEFNDBINOP_FN (PFX ## _ne, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_ne)
+
+#define OCTAVE_MM_INT_BOOL_OPS(PFX, T1, T2) \
+  DEFNDBINOP_FN (PFX ## _el_and, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_and) \
+  DEFNDBINOP_FN (PFX ## _el_or,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_or) \
+  DEFNDBINOP_FN (PFX ## _el_not_and, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_not_and) \
+  DEFNDBINOP_FN (PFX ## _el_not_or,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_not_or) \
+  DEFNDBINOP_FN (PFX ## _el_and_not, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_and_not) \
+  DEFNDBINOP_FN (PFX ## _el_or_not,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_or_not)
+
+#define OCTAVE_MM_INT_ASSIGN_OPS(PFX, TLHS, TRHS, TE) \
+  DEFNDASSIGNOP_FN (PFX ## _assign, TLHS ## matrix, TRHS ## matrix, TLHS ## array, assign)
+
+#define OCTAVE_MM_POW_OPS(T1, T2) \
+  octave_value \
+  elem_xpow (const T1 ## NDArray& a, const T2 ## NDArray& b) \
+  { \
+    dim_vector a_dims = a.dims (); \
+    dim_vector b_dims = b.dims (); \
+    if (a_dims != b_dims) \
+      { \
+	gripe_nonconformant ("operator .^", a_dims, b_dims); \
+	return octave_value (); \
+      } \
+    T1 ## NDArray result (a_dims); \
+    for (int i = 0; i < a.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = pow (a(i), b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+\
+  octave_value \
+  elem_xpow (const T1 ## NDArray& a, const NDArray& b) \
+  { \
+    dim_vector a_dims = a.dims (); \
+    dim_vector b_dims = b.dims (); \
+    if (a_dims != b_dims) \
+      { \
+	gripe_nonconformant ("operator .^", a_dims, b_dims); \
+	return octave_value (); \
+      } \
+    T1 ## NDArray result (a_dims); \
+    for (int i = 0; i < a.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = pow (a(i), b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+\
+  octave_value \
+  elem_xpow (const NDArray& a, const T2 ## NDArray& b) \
+  { \
+    dim_vector a_dims = a.dims (); \
+    dim_vector b_dims = b.dims (); \
+    if (a_dims != b_dims) \
+      { \
+	gripe_nonconformant ("operator .^", a_dims, b_dims); \
+	return octave_value (); \
+      } \
+    T2 ## NDArray result (a_dims); \
+    for (int i = 0; i < a.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = pow (a(i), b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+\
+  octave_value \
+  elem_xpow (const T1 ## NDArray& a, const FloatNDArray& b) \
+  { \
+    dim_vector a_dims = a.dims (); \
+    dim_vector b_dims = b.dims (); \
+    if (a_dims != b_dims) \
+      { \
+	gripe_nonconformant ("operator .^", a_dims, b_dims); \
+	return octave_value (); \
+      } \
+    T1 ## NDArray result (a_dims); \
+    for (int i = 0; i < a.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = powf (a(i), b(i)); \
+      } \
+    return octave_value (result); \
+  } \
+\
+  octave_value \
+  elem_xpow (const FloatNDArray& a, const T2 ## NDArray& b) \
+  { \
+    dim_vector a_dims = a.dims (); \
+    dim_vector b_dims = b.dims (); \
+    if (a_dims != b_dims) \
+      { \
+	gripe_nonconformant ("operator .^", a_dims, b_dims); \
+	return octave_value (); \
+      } \
+    T2 ## NDArray result (a_dims); \
+    for (int i = 0; i < a.length (); i++) \
+      { \
+	OCTAVE_QUIT; \
+	result (i) = powf (a(i), b(i)); \
+      } \
+    return octave_value (result); \
+  }
+
+
+#define OCTAVE_MM_CONV(T1, T2) \
+  DEFCONV (T1 ## m_ ## T2 ## m_conv, T1 ## matrix, T2 ## matrix) \
+  { \
+    CAST_CONV_ARG (const octave_ ## T1 ## matrix&); \
+ \
+    return new octave_ ## T2 ## matrix (v.T2 ## array_value ()); \
+  }
+
+#define OCTAVE_MM_INT_OPS(TYPE) \
+  OCTAVE_M_INT_UNOPS (TYPE) \
+  OCTAVE_MM_POW_OPS (TYPE, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mm, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mmx, TYPE ## _, , TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mxm, , TYPE ## _, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mmfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mfxm, float_, TYPE ## _, TYPE) \
+  OCTAVE_MM_INT_CMP_OPS (mm, TYPE ## _, TYPE ## _) \
+  OCTAVE_MM_INT_CMP_OPS (mmx, TYPE ## _, ) \
+  OCTAVE_MM_INT_CMP_OPS (mfxm, float_, TYPE ## _) \
+  OCTAVE_MM_INT_CMP_OPS (mmfx, TYPE ## _, float_) \
+  OCTAVE_MM_INT_CMP_OPS (mxm, , TYPE ## _) \
+  OCTAVE_MM_INT_BOOL_OPS (mm, TYPE ## _, TYPE ## _) \
+  OCTAVE_MM_INT_BOOL_OPS (mmx, TYPE ## _, ) \
+  OCTAVE_MM_INT_BOOL_OPS (mxm, , TYPE ## _) \
+  OCTAVE_MM_INT_BOOL_OPS (mmfx, TYPE ## _, float_) \
+  OCTAVE_MM_INT_BOOL_OPS (mfxm, float_, TYPE ## _) \
+  OCTAVE_MM_INT_ASSIGN_OPS (mm, TYPE ## _, TYPE ## _, TYPE ## _) \
+  OCTAVE_MM_INT_ASSIGN_OPS (mmx, TYPE ## _, , ) \
+  OCTAVE_MM_INT_ASSIGN_OPS (mmfx, TYPE ## _, float_, float_) \
+  OCTAVE_MM_CONV(TYPE ## _, complex_) \
+  OCTAVE_MM_CONV(TYPE ## _, float_complex_)
+
+#define OCTAVE_RE_INT_ASSIGN_OPS(TYPE) \
+  DEFNDASSIGNOP_FN (TYPE ## ms_assign, matrix, TYPE ## _scalar, array, assign) \
+  DEFNDASSIGNOP_FN (TYPE ## mm_assign, matrix, TYPE ## _matrix, array, assign)
+
+#define OCTAVE_FLT_RE_INT_ASSIGN_OPS(TYPE) \
+  DEFNDASSIGNOP_FN (TYPE ## fms_assign, float_matrix, TYPE ## _scalar, float_array, assign) \
+  DEFNDASSIGNOP_FN (TYPE ## fmm_assign, float_matrix, TYPE ## _matrix, float_array, assign)
+
+#define OCTAVE_CX_INT_ASSIGN_OPS(TYPE) \
+  DEFNDASSIGNOP_FN (TYPE ## cms_assign, complex_matrix, TYPE ## _scalar, complex_array, assign) \
+  DEFNDASSIGNOP_FN (TYPE ## cmm_assign, complex_matrix, TYPE ## _matrix, complex_array, assign)
+
+#define OCTAVE_FLT_CX_INT_ASSIGN_OPS(TYPE) \
+  DEFNDASSIGNOP_FN (TYPE ## fcms_assign, float_complex_matrix, TYPE ## _scalar, float_complex_array, assign) \
+  DEFNDASSIGNOP_FN (TYPE ## fcmm_assign, float_complex_matrix, TYPE ## _matrix, float_complex_array, assign)
+
+#define OCTAVE_INT_NULL_ASSIGN_OPS(TYPE) \
+  DEFNULLASSIGNOP_FN (TYPE ## null_assign, TYPE ## _matrix, delete_elements)
+
+#define OCTAVE_INT_OPS(TYPE) \
+  OCTAVE_SS_INT_OPS (TYPE) \
+  OCTAVE_SM_INT_OPS (TYPE) \
+  OCTAVE_MS_INT_OPS (TYPE) \
+  OCTAVE_MM_INT_OPS (TYPE) \
+  OCTAVE_CONCAT_FN (TYPE) \
+  OCTAVE_RE_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_FLT_RE_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_CX_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_FLT_CX_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_INT_NULL_ASSIGN_OPS(TYPE)
+
+#define OCTAVE_INSTALL_S_INT_UNOPS(TYPE) \
+  INSTALL_UNOP (op_not, octave_ ## TYPE ## _scalar, s_not); \
+  INSTALL_UNOP (op_uplus, octave_ ## TYPE ## _scalar, s_uplus); \
+  INSTALL_UNOP (op_uminus, octave_ ## TYPE ## _scalar, s_uminus); \
+  INSTALL_UNOP (op_transpose, octave_ ## TYPE ## _scalar, s_transpose); \
+  INSTALL_UNOP (op_hermitian, octave_ ## TYPE ## _scalar, s_hermitian); \
+ \
+  INSTALL_NCUNOP (op_incr, octave_ ## TYPE ## _scalar, s_incr); \
+  INSTALL_NCUNOP (op_decr, octave_ ## TYPE ## _scalar, s_decr);
+
+#define OCTAVE_INSTALL_SS_INT_ARITH_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_add, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _add); \
+  INSTALL_BINOP (op_sub, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _sub); \
+  INSTALL_BINOP (op_mul, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _mul); \
+  INSTALL_BINOP (op_div, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _div); \
+  INSTALL_BINOP (op_pow, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _pow); \
+  INSTALL_BINOP (op_ldiv, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _ldiv); \
+  INSTALL_BINOP (op_el_mul, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _el_mul); \
+  INSTALL_BINOP (op_el_div, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _el_div); \
+  INSTALL_BINOP (op_el_pow, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _el_pow); \
+  INSTALL_BINOP (op_el_ldiv, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _el_ldiv);
+
+#define OCTAVE_INSTALL_SS_INT_CMP_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_lt, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _lt); \
+  INSTALL_BINOP (op_le, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _le); \
+  INSTALL_BINOP (op_eq, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _eq); \
+  INSTALL_BINOP (op_ge, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _ge); \
+  INSTALL_BINOP (op_gt, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _gt); \
+  INSTALL_BINOP (op_ne, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _ne);
+
+#define OCTAVE_INSTALL_SS_INT_BOOL_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_el_and, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _el_and); \
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## scalar, octave_ ## T2 ## scalar, PFX ## _el_or);
+
+#define OCTAVE_INSTALL_SS_INT_OPS(TYPE) \
+  OCTAVE_INSTALL_S_INT_UNOPS (TYPE) \
+  OCTAVE_INSTALL_SS_INT_ARITH_OPS (ss, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_SS_INT_ARITH_OPS (ssx, TYPE ## _, )	     \
+  OCTAVE_INSTALL_SS_INT_ARITH_OPS (sxs,  , TYPE ## _)	     \
+  OCTAVE_INSTALL_SS_INT_ARITH_OPS (ssfx, TYPE ## _, float_)	     \
+  OCTAVE_INSTALL_SS_INT_ARITH_OPS (sfxs,  float_, TYPE ## _)	     \
+  OCTAVE_INSTALL_SS_INT_CMP_OPS (ss, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_SS_INT_CMP_OPS (sx, TYPE ## _, ) \
+  OCTAVE_INSTALL_SS_INT_CMP_OPS (xs, , TYPE ## _) \
+  OCTAVE_INSTALL_SS_INT_CMP_OPS (sfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_SS_INT_CMP_OPS (fxs, float_, TYPE ## _) \
+  OCTAVE_INSTALL_SS_INT_BOOL_OPS (ss, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_SS_INT_BOOL_OPS (sx, TYPE ## _, ) \
+  OCTAVE_INSTALL_SS_INT_BOOL_OPS (xs, , TYPE ## _) \
+  OCTAVE_INSTALL_SS_INT_BOOL_OPS (sfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_SS_INT_BOOL_OPS (fxs, float_, TYPE ## _) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_scalar, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_float_scalar, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_complex_scalar, octave_complex_matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_float_complex_scalar, octave_float_complex_matrix)
+
+#define OCTAVE_INSTALL_SM_INT_ARITH_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_add, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _add); \
+  INSTALL_BINOP (op_sub, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _sub); \
+  INSTALL_BINOP (op_mul, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _mul); \
+  /* INSTALL_BINOP (op_div, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _div); */ \
+  /* INSTALL_BINOP (op_pow, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _pow); */ \
+  INSTALL_BINOP (op_ldiv, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _ldiv); \
+  INSTALL_BINOP (op_el_mul, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_mul); \
+  INSTALL_BINOP (op_el_div, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_div); \
+  INSTALL_BINOP (op_el_pow, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_pow); \
+  INSTALL_BINOP (op_el_ldiv, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_ldiv);
+
+#define OCTAVE_INSTALL_SM_INT_CMP_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_lt, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _lt); \
+  INSTALL_BINOP (op_le, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _le); \
+  INSTALL_BINOP (op_eq, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _eq); \
+  INSTALL_BINOP (op_ge, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _ge); \
+  INSTALL_BINOP (op_gt, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _gt); \
+  INSTALL_BINOP (op_ne, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _ne);
+
+#define OCTAVE_INSTALL_SM_INT_BOOL_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_el_and, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_and); \
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_or); \
+  INSTALL_BINOP (op_el_and_not, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_and_not); \
+  INSTALL_BINOP (op_el_or_not, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_or_not);
+
+#define OCTAVE_INSTALL_SM_INT_OPS(TYPE) \
+  OCTAVE_INSTALL_SM_INT_ARITH_OPS (sm, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_ARITH_OPS (smx, TYPE ## _, )	     \
+  OCTAVE_INSTALL_SM_INT_ARITH_OPS (sxm, , TYPE ## _)	     \
+  OCTAVE_INSTALL_SM_INT_ARITH_OPS (smfx, TYPE ## _, float_)	     \
+  OCTAVE_INSTALL_SM_INT_ARITH_OPS (sfxm, float_, TYPE ## _)	     \
+  OCTAVE_INSTALL_SM_INT_CMP_OPS (sm, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_CMP_OPS (xm, , TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_CMP_OPS (smx, TYPE ## _, ) \
+  OCTAVE_INSTALL_SM_INT_CMP_OPS (fxm, float_, TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_CMP_OPS (smfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_SM_INT_BOOL_OPS (sm, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_BOOL_OPS (xm, , TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_BOOL_OPS (smx, TYPE ## _, ) \
+  OCTAVE_INSTALL_SM_INT_BOOL_OPS (fxm, float_, TYPE ## _) \
+  OCTAVE_INSTALL_SM_INT_BOOL_OPS (smfx, TYPE ## _, float_) \
+  INSTALL_WIDENOP (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _matrix, TYPE ## _s_ ## TYPE ## _m_conv) \
+  INSTALL_WIDENOP (octave_ ## TYPE ## _scalar, octave_complex_matrix, TYPE ## _s_complex_m_conv) \
+  INSTALL_WIDENOP (octave_ ## TYPE ## _scalar, octave_float_complex_matrix, TYPE ## _s_float_complex_m_conv) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _matrix, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_matrix, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_float_matrix, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_complex_matrix, octave_complex_matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_float_complex_matrix, octave_float_complex_matrix)
+
+#define OCTAVE_INSTALL_MS_INT_ARITH_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_add, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _add); \
+  INSTALL_BINOP (op_sub, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _sub); \
+  INSTALL_BINOP (op_mul, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _mul); \
+  INSTALL_BINOP (op_div, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _div); \
+  /* INSTALL_BINOP (op_pow, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _pow); */ \
+  /* INSTALL_BINOP (op_ldiv, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _ldiv); */ \
+ \
+  INSTALL_BINOP (op_el_mul, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_mul); \
+  INSTALL_BINOP (op_el_div, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_div); \
+  INSTALL_BINOP (op_el_pow, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_pow); \
+  INSTALL_BINOP (op_el_ldiv, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_ldiv);
+
+#define OCTAVE_INSTALL_MS_INT_CMP_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_lt, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _lt); \
+  INSTALL_BINOP (op_le, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _le); \
+  INSTALL_BINOP (op_eq, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _eq); \
+  INSTALL_BINOP (op_ge, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _ge); \
+  INSTALL_BINOP (op_gt, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _gt); \
+  INSTALL_BINOP (op_ne, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _ne);
+
+#define OCTAVE_INSTALL_MS_INT_BOOL_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_el_and, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_and); \
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_or); \
+  INSTALL_BINOP (op_el_not_and, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_not_and); \
+  INSTALL_BINOP (op_el_not_or, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_not_or);
+
+#define OCTAVE_INSTALL_MS_INT_ASSIGN_OPS(PFX, TLHS, TRHS) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign)
+
+#define OCTAVE_INSTALL_MS_INT_OPS(TYPE) \
+  OCTAVE_INSTALL_MS_INT_ARITH_OPS (ms, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_ARITH_OPS (msx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MS_INT_ARITH_OPS (mxs, , TYPE ## _)	   \
+  OCTAVE_INSTALL_MS_INT_ARITH_OPS (msfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_MS_INT_ARITH_OPS (mfxs, float_, TYPE ## _)	   \
+  OCTAVE_INSTALL_MS_INT_CMP_OPS (ms, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_CMP_OPS (mx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MS_INT_CMP_OPS (mxs, , TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_CMP_OPS (mfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_MS_INT_CMP_OPS (mfxs, float_, TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_BOOL_OPS (ms, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_BOOL_OPS (mx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MS_INT_BOOL_OPS (mxs, , TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_BOOL_OPS (mfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_MS_INT_BOOL_OPS (mfxs, float_, TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (ms, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mfx, TYPE ## _, float_) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _matrix, octave_complex_scalar, octave_complex_matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _matrix, octave_float_complex_scalar, octave_float_complex_matrix)
+
+#define OCTAVE_INSTALL_M_INT_UNOPS(TYPE) \
+  INSTALL_UNOP (op_not, octave_ ## TYPE ## _matrix, m_not); \
+  INSTALL_UNOP (op_uplus, octave_ ## TYPE ## _matrix, m_uplus); \
+  INSTALL_UNOP (op_uminus, octave_ ## TYPE ## _matrix, m_uminus); \
+  INSTALL_UNOP (op_transpose, octave_ ## TYPE ## _matrix, m_transpose); \
+  INSTALL_UNOP (op_hermitian, octave_ ## TYPE ## _matrix, m_transpose); \
+ \
+  INSTALL_NCUNOP (op_incr, octave_ ## TYPE ## _matrix, m_incr); \
+  INSTALL_NCUNOP (op_decr, octave_ ## TYPE ## _matrix, m_decr);
+
+#define OCTAVE_INSTALL_MM_INT_ARITH_OPS(PFX, T1, T2)			\
+  INSTALL_BINOP (op_add, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _add); \
+  INSTALL_BINOP (op_sub, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _sub); \
+  /* INSTALL_BINOP (op_mul, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _mul); */ \
+  /* INSTALL_BINOP (op_div, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _div); */ \
+  INSTALL_BINOP (op_pow, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _pow); \
+  /* INSTALL_BINOP (op_ldiv, octave_ ## T1 ## _matrix, octave_ ## T2 ## _matrix, mm_ldiv); */ \
+  INSTALL_BINOP (op_el_mul, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_mul); \
+  INSTALL_BINOP (op_el_div, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_div); \
+  INSTALL_BINOP (op_el_pow, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_pow); \
+  INSTALL_BINOP (op_el_ldiv, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_ldiv);
+
+#define OCTAVE_INSTALL_MM_INT_CMP_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_lt, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _lt); \
+  INSTALL_BINOP (op_le, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _le); \
+  INSTALL_BINOP (op_eq, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _eq); \
+  INSTALL_BINOP (op_ge, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _ge); \
+  INSTALL_BINOP (op_gt, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _gt); \
+  INSTALL_BINOP (op_ne, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _ne);
+
+#define OCTAVE_INSTALL_MM_INT_BOOL_OPS(PFX, T1, T2) \
+  INSTALL_BINOP (op_el_and, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_and); \
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_or); \
+  INSTALL_BINOP (op_el_not_and, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_not_and); \
+  INSTALL_BINOP (op_el_not_or, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_not_or); \
+  INSTALL_BINOP (op_el_and_not, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_and_not); \
+  INSTALL_BINOP (op_el_or_not, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_or_not);
+
+#define OCTAVE_INSTALL_MM_INT_ASSIGN_OPS(PFX, TLHS, TRHS) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## matrix, PFX ## _assign)
+
+#define OCTAVE_INSTALL_MM_INT_OPS(TYPE) \
+  OCTAVE_INSTALL_M_INT_UNOPS (TYPE) \
+  OCTAVE_INSTALL_MM_INT_ARITH_OPS (mm, TYPE ##_, TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_ARITH_OPS (mmx, TYPE ##_, ) \
+  OCTAVE_INSTALL_MM_INT_ARITH_OPS (mxm, , TYPE ##_)	   \
+  OCTAVE_INSTALL_MM_INT_ARITH_OPS (mmfx, TYPE ##_, float_) \
+  OCTAVE_INSTALL_MM_INT_ARITH_OPS (mfxm, float_, TYPE ##_)	   \
+  OCTAVE_INSTALL_MM_INT_CMP_OPS (mm, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_CMP_OPS (mmx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MM_INT_CMP_OPS (mxm, , TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_CMP_OPS (mmfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_MM_INT_CMP_OPS (mfxm, float_, TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_BOOL_OPS (mm, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_BOOL_OPS (mmx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MM_INT_BOOL_OPS (mxm, , TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_BOOL_OPS (mmfx, TYPE ## _, float_) \
+  OCTAVE_INSTALL_MM_INT_BOOL_OPS (mfxm, float_, TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mm, TYPE ## _, TYPE ## _) \
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmx, TYPE ## _, ) \
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmfx, TYPE ## _, float_) \
+  INSTALL_WIDENOP (octave_ ## TYPE ## _matrix, octave_complex_matrix, TYPE ## _m_complex_m_conv) \
+  INSTALL_WIDENOP (octave_ ## TYPE ## _matrix, octave_float_complex_matrix, TYPE ## _m_float_complex_m_conv) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _matrix, octave_complex_matrix, octave_complex_matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _matrix, octave_float_complex_matrix, octave_float_complex_matrix)
+
+#define OCTAVE_INSTALL_RE_INT_ASSIGN_OPS(TYPE) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_ ## TYPE ## _scalar, TYPE ## ms_assign) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_ ## TYPE ## _matrix, TYPE ## mm_assign) \
+  INSTALL_ASSIGNCONV (octave_scalar, octave_ ## TYPE ## _scalar, octave_matrix) \
+  INSTALL_ASSIGNCONV (octave_matrix, octave_ ## TYPE ## _matrix, octave_matrix)
+
+#define OCTAVE_INSTALL_FLT_RE_INT_ASSIGN_OPS(TYPE) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_ ## TYPE ## _scalar, TYPE ## fms_assign) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_ ## TYPE ## _matrix, TYPE ## fmm_assign) \
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_ ## TYPE ## _scalar, octave_float_matrix) \
+  INSTALL_ASSIGNCONV (octave_float_matrix, octave_ ## TYPE ## _matrix, octave_float_matrix)
+
+#define OCTAVE_INSTALL_CX_INT_ASSIGN_OPS(TYPE) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_ ## TYPE ## _scalar, TYPE ## cms_assign) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_ ## TYPE ## _matrix, TYPE ## cmm_assign) \
+  INSTALL_ASSIGNCONV (octave_complex_scalar, octave_ ## TYPE ## _scalar, octave_complex_matrix) \
+  INSTALL_ASSIGNCONV (octave_complex_matrix, octave_ ## TYPE ## _matrix, octave_complex_matrix)
+
+#define OCTAVE_INSTALL_FLT_CX_INT_ASSIGN_OPS(TYPE) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, octave_ ## TYPE ## _scalar, TYPE ## fcms_assign) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, octave_ ## TYPE ## _matrix, TYPE ## fcmm_assign) \
+  INSTALL_ASSIGNCONV (octave_float_complex_scalar, octave_ ## TYPE ## _scalar, octave_complex_matrix) \
+  INSTALL_ASSIGNCONV (octave_float_complex_matrix, octave_ ## TYPE ## _matrix, octave_complex_matrix)
+
+#define OCTAVE_INSTALL_INT_NULL_ASSIGN_OPS(TYPE) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_matrix, TYPE ## null_assign) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_str, TYPE ## null_assign) \
+  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_sq_str, TYPE ## null_assign)
+
+#define OCTAVE_INSTALL_INT_OPS(TYPE) \
+  OCTAVE_INSTALL_SS_INT_OPS (TYPE) \
+  OCTAVE_INSTALL_SM_INT_OPS (TYPE) \
+  OCTAVE_INSTALL_MS_INT_OPS (TYPE) \
+  OCTAVE_INSTALL_MM_INT_OPS (TYPE) \
+  OCTAVE_INSTALL_CONCAT_FN (TYPE) \
+  OCTAVE_INSTALL_RE_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_INSTALL_FLT_RE_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_INSTALL_CX_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_INSTALL_FLT_CX_INT_ASSIGN_OPS (TYPE) \
+  OCTAVE_INSTALL_INT_NULL_ASSIGN_OPS(TYPE)
+
+#define OCTAVE_INSTALL_SM_INT_ASSIGNCONV(TLHS, TRHS) \
+  INSTALL_ASSIGNCONV (octave_ ## TLHS ## _scalar, octave_ ## TRHS ## _scalar, octave_ ## TLHS ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_ ## TLHS ## _scalar, octave_ ## TRHS ## _matrix, octave_ ## TLHS ## _matrix)
+
+#define OCTAVE_MIXED_INT_CMP_OPS(T1, T2) \
+  OCTAVE_SS_INT_CMP_OPS (T1 ## _ ## T2 ## _ss, T1 ## _, T2 ## _) \
+  OCTAVE_SM_INT_CMP_OPS (T1 ## _ ## T2 ## _sm, T1 ## _, T2 ## _) \
+  OCTAVE_MS_INT_CMP_OPS (T1 ## _ ## T2 ## _ms, T1 ## _, T2 ## _) \
+  OCTAVE_MM_INT_CMP_OPS (T1 ## _ ## T2 ## _mm, T1 ## _, T2 ## _)
+
+#define OCTAVE_INSTALL_MIXED_INT_CMP_OPS(T1, T2) \
+  OCTAVE_INSTALL_SS_INT_CMP_OPS (T1 ## _ ## T2 ## _ss, T1 ## _, T2 ## _) \
+  OCTAVE_INSTALL_SM_INT_CMP_OPS (T1 ## _ ## T2 ## _sm, T1 ## _, T2 ## _) \
+  OCTAVE_INSTALL_MS_INT_CMP_OPS (T1 ## _ ## T2 ## _ms, T1 ## _, T2 ## _) \
+  OCTAVE_INSTALL_MM_INT_CMP_OPS (T1 ## _ ## T2 ## _mm, T1 ## _, T2 ## _)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-list.cc b/src/OPERATORS/op-list.cc
new file mode 100644
index 0000000..2a3043a
--- /dev/null
+++ b/src/OPERATORS/op-list.cc
@@ -0,0 +1,49 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-list.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+// list ops.
+
+DEFASSIGNANYOP_FN (assign, list, assign);
+
+void
+install_list_ops (void)
+{
+  INSTALL_ASSIGNANYOP (op_asn_eq, octave_list, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-m-cdm.cc b/src/OPERATORS/op-m-cdm.cc
new file mode 100644
index 0000000..2fabeaa
--- /dev/null
+++ b/src/OPERATORS/op-m-cdm.cc
@@ -0,0 +1,36 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-re-mat.h"
+#define RINCLUDE "ov-cx-diag.h"
+
+#define LMATRIX matrix
+#define RMATRIX complex_diag_matrix
+#define LDMATRIX complex_matrix
+
+#define LSHORT m
+#define RSHORT cdm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-m-cm.cc b/src/OPERATORS/op-m-cm.cc
new file mode 100644
index 0000000..89779e5
--- /dev/null
+++ b/src/OPERATORS/op-m-cm.cc
@@ -0,0 +1,146 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-m-cm.h"
+#include "mx-cm-m.h"
+#include "mx-nda-cnda.h"
+#include "mx-cnda-nda.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix by complex matrix ops.
+
+DEFNDBINOP_OP (add, matrix, complex_matrix, array, complex_array, +)
+DEFNDBINOP_OP (sub, matrix, complex_matrix, array, complex_array, -)
+
+DEFBINOP_OP (mul, matrix, complex_matrix, *)
+
+DEFBINOP (div, matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  ComplexMatrix ret = xdiv (v1.matrix_value (), 
+			    v2.complex_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, matrix, complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  ComplexMatrix ret = xleftdiv (v1.matrix_value (), 
+				v2.complex_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, matrix, complex_matrix, array, complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, complex_matrix, array, complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, complex_matrix, array, complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, complex_matrix, array, complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, complex_matrix, array, complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, complex_matrix, array, complex_array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, matrix, complex_matrix, array, complex_array, product)
+DEFNDBINOP_FN (el_div, matrix, complex_matrix, array, complex_array, quotient)
+DEFNDBINOP_FN (el_pow, matrix, complex_matrix, array, complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+
+  return quotient (v2.complex_array_value (), v1.array_value ());
+}
+
+DEFNDBINOP_FN (el_and, matrix, complex_matrix, array, complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  matrix, complex_matrix, array, complex_array, mx_el_or)
+
+DEFNDCATOP_FN (m_cm, matrix, complex_matrix, array, complex_array, concat)
+
+DEFCONV (complex_matrix_conv, matrix, complex_matrix)
+{
+  CAST_CONV_ARG (const octave_matrix&);
+
+  return new octave_complex_matrix (ComplexNDArray (v.array_value ()));
+}
+
+void
+install_m_cm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_matrix, octave_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_matrix, octave_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_matrix, octave_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_matrix, octave_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_matrix, octave_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_matrix, octave_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_matrix, octave_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_matrix, octave_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_matrix, octave_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_matrix, octave_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_matrix, octave_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_matrix, octave_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_matrix, octave_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_matrix, octave_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_matrix, octave_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_matrix, octave_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_matrix, octave_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_matrix, octave_complex_matrix, m_cm);
+
+  INSTALL_ASSIGNCONV (octave_matrix, octave_complex_matrix, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_matrix, octave_complex_matrix, octave_float_complex_matrix);
+
+  INSTALL_WIDENOP (octave_matrix, octave_complex_matrix, complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-m-cs.cc b/src/OPERATORS/op-m-cs.cc
new file mode 100644
index 0000000..d506df8
--- /dev/null
+++ b/src/OPERATORS/op-m-cs.cc
@@ -0,0 +1,147 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-m-cs.h"
+#include "mx-cs-m.h"
+#include "mx-nda-cs.h"
+#include "mx-cs-nda.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-complex.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix by complex scalar ops.
+
+DEFNDBINOP_OP (add, matrix, complex, array, complex, +)
+DEFNDBINOP_OP (sub, matrix, complex, array, complex, -)
+DEFNDBINOP_OP (mul, matrix, complex, array, complex, *)
+
+DEFBINOP (div, matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.array_value () / d);
+}
+
+DEFBINOP_FN (pow, matrix, complex, xpow)
+
+DEFBINOP (ldiv, matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+
+  Matrix m1 = v1.matrix_value ();
+  ComplexMatrix m2 = v2.complex_matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  ComplexMatrix ret = xleftdiv (m1, m2, typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, matrix, complex, array, complex, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, complex, array, complex, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, complex, array, complex, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, complex, array, complex, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, complex, array, complex, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, complex, array, complex, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, matrix, complex, array, complex, *)
+
+DEFBINOP (el_div, matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, matrix, complex, array, complex, elem_xpow)
+
+DEFBINOP (el_ldiv, matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+
+  return x_el_div (v2.complex_value (), v1.array_value ());
+}
+
+DEFNDBINOP_FN (el_and, matrix, complex, array, complex, mx_el_and)
+DEFNDBINOP_FN (el_or, matrix, complex, array, complex, mx_el_or)
+
+DEFNDCATOP_FN (m_cs, matrix, complex, array, complex_array, concat)
+
+void
+install_m_cs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_matrix, octave_complex, add);
+  INSTALL_BINOP (op_sub, octave_matrix, octave_complex, sub);
+  INSTALL_BINOP (op_mul, octave_matrix, octave_complex, mul);
+  INSTALL_BINOP (op_div, octave_matrix, octave_complex, div);
+  INSTALL_BINOP (op_pow, octave_matrix, octave_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_matrix, octave_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_matrix, octave_complex, lt);
+  INSTALL_BINOP (op_le, octave_matrix, octave_complex, le);
+  INSTALL_BINOP (op_eq, octave_matrix, octave_complex, eq);
+  INSTALL_BINOP (op_ge, octave_matrix, octave_complex, ge);
+  INSTALL_BINOP (op_gt, octave_matrix, octave_complex, gt);
+  INSTALL_BINOP (op_ne, octave_matrix, octave_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_matrix, octave_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_matrix, octave_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_matrix, octave_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_matrix, octave_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_matrix, octave_complex, el_or);
+
+  INSTALL_CATOP (octave_matrix, octave_complex, m_cs);
+
+  INSTALL_ASSIGNCONV (octave_matrix, octave_complex, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_matrix, octave_complex, octave_float_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-m-dm.cc b/src/OPERATORS/op-m-dm.cc
new file mode 100644
index 0000000..c0b1ed9
--- /dev/null
+++ b/src/OPERATORS/op-m-dm.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define LINCLUDE "ov-re-mat.h"
+#define RINCLUDE "ov-re-diag.h"
+
+#define LMATRIX matrix
+#define RMATRIX diag_matrix
+
+#define LSHORT m
+#define RSHORT dm
+
+#define DEFINEDIV
+
+#include "op-dm-template.cc"
+
diff --git a/src/OPERATORS/op-m-m.cc b/src/OPERATORS/op-m-m.cc
new file mode 100644
index 0000000..322eed4
--- /dev/null
+++ b/src/OPERATORS/op-m-m.cc
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix unary ops.
+
+DEFNDUNOP_OP (not, matrix, array, !)
+DEFNDUNOP_OP (uplus, matrix, array, /* no-op */)
+DEFNDUNOP_OP (uminus, matrix, array, -)
+
+DEFUNOP (transpose, matrix)
+{
+  CAST_UNOP_ARG (const octave_matrix&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.matrix_value().transpose ());
+}
+
+DEFNCUNOP_METHOD (incr, matrix, increment)
+DEFNCUNOP_METHOD (decr, matrix, decrement)
+
+// matrix by matrix ops.
+
+DEFNDBINOP_OP (add, matrix, matrix, array, array, +)
+DEFNDBINOP_OP (sub, matrix, matrix, array, array, -)
+
+DEFBINOP_OP (mul, matrix, matrix, *)
+
+DEFBINOP (div, matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  Matrix ret = xdiv (v1.matrix_value (), v2.matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, matrix, matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP (trans_mul, matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  return octave_value(xgemm (true, v1.matrix_value (), false, v2.matrix_value ()));
+}
+
+DEFBINOP (mul_trans, matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  return octave_value(xgemm (false, v1.matrix_value (), true, v2.matrix_value ()));
+}
+
+DEFNDBINOP_FN (lt, matrix, matrix, array, array, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, matrix, array, array, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, matrix, array, array, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, matrix, array, array, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, matrix, array, array, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, matrix, array, array, mx_el_ne)
+
+DEFNDBINOP_FN (el_mul, matrix, matrix, array, array, product)
+DEFNDBINOP_FN (el_div, matrix, matrix, array, array, quotient)
+DEFNDBINOP_FN (el_pow, matrix, matrix, array, array, elem_xpow)
+
+DEFBINOP (el_ldiv, matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+
+  return octave_value (quotient (v2.array_value (), v1.array_value ()));
+}
+
+DEFNDBINOP_FN (el_and, matrix, matrix, array, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  matrix, matrix, array, array, mx_el_or)
+DEFNDBINOP_FN (el_not_and, matrix, matrix, array, array, mx_el_not_and)
+DEFNDBINOP_FN (el_not_or,  matrix, matrix, array, array, mx_el_not_or)
+DEFNDBINOP_FN (el_and_not, matrix, matrix, array, array, mx_el_and_not)
+DEFNDBINOP_FN (el_or_not,  matrix, matrix, array, array, mx_el_or_not)
+
+
+DEFNDCATOP_FN (m_m, matrix, matrix, array, array, concat)
+
+DEFNDASSIGNOP_FN (assign, matrix, matrix, array, assign)
+DEFNDASSIGNOP_FN (sgl_assign, float_matrix, matrix, float_array, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, matrix, delete_elements)
+
+CONVDECL (matrix_to_float_matrix)
+{
+  CAST_CONV_ARG (const octave_matrix&);
+
+  return new octave_float_matrix (FloatNDArray (v.array_value ()));
+}
+
+void
+install_m_m_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_matrix, transpose);
+
+  INSTALL_NCUNOP (op_incr, octave_matrix, incr);
+  INSTALL_NCUNOP (op_decr, octave_matrix, decr);
+
+  INSTALL_BINOP (op_add, octave_matrix, octave_matrix, add);
+  INSTALL_BINOP (op_sub, octave_matrix, octave_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_matrix, octave_matrix, mul);
+  INSTALL_BINOP (op_div, octave_matrix, octave_matrix, div);
+  INSTALL_BINOP (op_pow, octave_matrix, octave_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_matrix, octave_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_matrix, octave_matrix, lt);
+  INSTALL_BINOP (op_le, octave_matrix, octave_matrix, le);
+  INSTALL_BINOP (op_eq, octave_matrix, octave_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_matrix, octave_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_matrix, octave_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_matrix, octave_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_matrix, octave_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_matrix, octave_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_matrix, octave_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_matrix, octave_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_matrix, octave_matrix, el_or);
+  INSTALL_BINOP (op_el_and_not, octave_matrix, octave_matrix, el_and_not);
+  INSTALL_BINOP (op_el_or_not, octave_matrix, octave_matrix, el_or_not);
+  INSTALL_BINOP (op_el_not_and, octave_matrix, octave_matrix, el_not_and);
+  INSTALL_BINOP (op_el_not_or, octave_matrix, octave_matrix, el_not_or);
+  INSTALL_BINOP (op_trans_mul, octave_matrix, octave_matrix, trans_mul);
+  INSTALL_BINOP (op_mul_trans, octave_matrix, octave_matrix, mul_trans);
+  INSTALL_BINOP (op_herm_mul, octave_matrix, octave_matrix, trans_mul);
+  INSTALL_BINOP (op_mul_herm, octave_matrix, octave_matrix, mul_trans);
+
+  INSTALL_CATOP (octave_matrix, octave_matrix, m_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_matrix, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_matrix, sgl_assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_null_sq_str, null_assign);
+
+  INSTALL_CONVOP (octave_matrix, octave_float_matrix, matrix_to_float_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-m-pm.cc b/src/OPERATORS/op-m-pm.cc
new file mode 100644
index 0000000..d3ab834
--- /dev/null
+++ b/src/OPERATORS/op-m-pm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-re-mat.h"
+
+#define LMATRIX matrix
+#define RMATRIX perm_matrix
+
+#define LSHORT m
+#define RSHORT pm
+
+#define RIGHT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-m-s.cc b/src/OPERATORS/op-m-s.cc
new file mode 100644
index 0000000..3275417
--- /dev/null
+++ b/src/OPERATORS/op-m-s.cc
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// matrix by scalar ops.
+
+DEFNDBINOP_OP (add, matrix, scalar, array, scalar, +)
+DEFNDBINOP_OP (sub, matrix, scalar, array, scalar, -)
+DEFNDBINOP_OP (mul, matrix, scalar, array, scalar, *)
+
+DEFBINOP (div, matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.array_value () / d);
+}
+
+DEFBINOP_FN (pow, matrix, scalar, xpow)
+
+DEFBINOP (ldiv, matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+
+  Matrix m1 = v1.matrix_value ();
+  Matrix m2 = v2.matrix_value ();
+  MatrixType typ = v1.matrix_type ();
+
+  Matrix ret = xleftdiv (m1, m2, typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFNDBINOP_FN (lt, matrix, scalar, array, scalar, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, scalar, array, scalar, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, scalar, array, scalar, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, scalar, array, scalar, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, scalar, array, scalar, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, scalar, array, scalar, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, matrix, scalar, array, scalar, *)
+
+DEFBINOP (el_div, matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.array_value () / d);
+}
+
+DEFNDBINOP_FN (el_pow, matrix, scalar, array, scalar, elem_xpow)
+
+DEFBINOP (el_ldiv, matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+
+  return x_el_div (v2.double_value (), v1.array_value ());
+}
+
+DEFNDBINOP_FN (el_and, matrix, scalar, array, scalar, mx_el_and)
+DEFNDBINOP_FN (el_or, matrix, scalar, array, scalar, mx_el_or)
+
+DEFNDCATOP_FN (m_s, matrix, scalar, array, array, concat)
+
+DEFNDASSIGNOP_FN (assign, matrix, scalar, scalar, assign)
+DEFNDASSIGNOP_FN (sgl_assign, float_matrix, scalar, float_scalar, assign)
+
+void
+install_m_s_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_matrix, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_matrix, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_matrix, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_matrix, octave_scalar, div);
+  INSTALL_BINOP (op_pow, octave_matrix, octave_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_matrix, octave_scalar, ldiv);
+
+  //  INSTALL_BINOP (op_lt, octave_matrix, octave_scalar, lt);
+
+  octave_value_typeinfo::register_binary_op
+    (octave_value::op_lt, octave_matrix::static_type_id (),
+     octave_scalar::static_type_id (), oct_binop_lt);
+
+  INSTALL_BINOP (op_le, octave_matrix, octave_scalar, le);
+  INSTALL_BINOP (op_eq, octave_matrix, octave_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_matrix, octave_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_matrix, octave_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_matrix, octave_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_matrix, octave_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_matrix, octave_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_matrix, octave_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_matrix, octave_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_matrix, octave_scalar, el_or);
+
+  INSTALL_CATOP (octave_matrix, octave_scalar, m_s);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_scalar, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_scalar, sgl_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-m-scm.cc b/src/OPERATORS/op-m-scm.cc
new file mode 100644
index 0000000..f1853ca
--- /dev/null
+++ b/src/OPERATORS/op-m-scm.cc
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-scm-m.h"
+#include "smx-m-scm.h"
+#include "ov-cx-sparse.h"
+
+// matrix by sparse complex matrix ops.
+
+DEFBINOP_OP (add, matrix, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, matrix, sparse_complex_matrix, -)
+
+DEFBINOP_OP (mul, matrix, sparse_complex_matrix, *)
+
+DEFBINOP (div, matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+
+      ComplexMatrix ret = xdiv (v1.matrix_value (), 
+				v2.sparse_complex_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, matrix, sparse_complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, 
+		   const octave_sparse_complex_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  ComplexMatrix ret = xleftdiv (v1.matrix_value (), 
+				v2.complex_matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (lt, matrix, sparse_complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, matrix, sparse_complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, matrix, sparse_complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, matrix, sparse_complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, matrix, sparse_complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, matrix, sparse_complex_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, matrix, sparse_complex_matrix, product)
+DEFBINOP_FN (el_div, matrix, sparse_complex_matrix, quotient)
+
+DEFBINOP (el_pow, matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, 
+		   const octave_sparse_complex_matrix&);
+  
+  return octave_value 
+    (elem_xpow (SparseMatrix (v1.matrix_value ()),
+		v2.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP (el_ldiv, matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, 
+		   const octave_sparse_complex_matrix&);
+  return octave_value 
+    (quotient (v2.sparse_complex_matrix_value (), v1.matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, matrix, sparse_complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  matrix, sparse_complex_matrix, mx_el_or)
+
+DEFCATOP (m_scm, matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (octave_matrix&, const octave_sparse_complex_matrix&);
+  SparseMatrix tmp (v1.matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_complex_matrix_value (), 
+				    ra_idx));
+}
+
+DEFCONV (sparse_complex_matrix_conv, matrix, sparse_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_matrix&);
+  return new octave_sparse_complex_matrix 
+    (SparseComplexMatrix (v.complex_matrix_value ()));
+}
+
+void
+install_m_scm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_matrix, octave_sparse_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_matrix, octave_sparse_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_matrix, octave_sparse_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_matrix, octave_sparse_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_matrix, octave_sparse_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_matrix, octave_sparse_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_matrix, octave_sparse_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_matrix, octave_sparse_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_matrix, octave_sparse_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_matrix, octave_sparse_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_matrix, octave_sparse_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_matrix, octave_sparse_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_matrix, octave_sparse_complex_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_matrix, octave_sparse_complex_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_matrix, octave_sparse_complex_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_sparse_complex_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_matrix, octave_sparse_complex_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_matrix, octave_sparse_complex_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_matrix, octave_sparse_complex_matrix, m_scm);
+
+  INSTALL_ASSIGNCONV (octave_matrix, octave_sparse_complex_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_matrix, octave_sparse_complex_matrix, 
+		   sparse_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-m-sm.cc b/src/OPERATORS/op-m-sm.cc
new file mode 100644
index 0000000..9d187dd
--- /dev/null
+++ b/src/OPERATORS/op-m-sm.cc
@@ -0,0 +1,173 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-re-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-sm-m.h"
+#include "smx-m-sm.h"
+#include "ov-re-sparse.h"
+
+// matrix by sparse matrix ops.
+
+DEFBINOP_OP (add, matrix, sparse_matrix, +)
+DEFBINOP_OP (sub, matrix, sparse_matrix, -)
+
+DEFBINOP_OP (mul, matrix, sparse_matrix, *)
+
+DEFBINOP (div, matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+
+      Matrix ret = xdiv (v1.matrix_value (), v2.sparse_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, matrix, sparse_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  MatrixType typ = v1.matrix_type ();
+  
+  Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (), typ);
+
+  v1.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (mul_trans, matrix, sparse_matrix, mul_trans);
+
+DEFBINOP_FN (lt, matrix, sparse_matrix, mx_el_lt)
+DEFBINOP_FN (le, matrix, sparse_matrix, mx_el_le)
+DEFBINOP_FN (eq, matrix, sparse_matrix, mx_el_eq)
+DEFBINOP_FN (ge, matrix, sparse_matrix, mx_el_ge)
+DEFBINOP_FN (gt, matrix, sparse_matrix, mx_el_gt)
+DEFBINOP_FN (ne, matrix, sparse_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, matrix, sparse_matrix, product)
+DEFBINOP_FN (el_div, matrix, sparse_matrix, quotient)
+
+DEFBINOP (el_pow, matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  
+  return octave_value (elem_xpow (SparseMatrix (v1.matrix_value ()), 
+				  v2.sparse_matrix_value ()));
+}
+
+DEFBINOP (el_ldiv, matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  
+  return octave_value 
+    (quotient (v2.sparse_matrix_value (), v1.matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, matrix, sparse_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  matrix, sparse_matrix, mx_el_or)
+
+DEFCATOP (m_sm, matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (octave_matrix&, const octave_sparse_matrix&);
+  SparseMatrix tmp (v1.matrix_value ());
+  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCONV (sparse_matrix_conv, matrix, sparse_matrix)
+{
+  CAST_CONV_ARG (const octave_matrix&);
+  return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
+}
+
+DEFNDASSIGNOP_FN (assign, matrix, sparse_matrix, array, assign)
+
+void
+install_m_sm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_matrix, octave_sparse_matrix, add);
+  INSTALL_BINOP (op_sub, octave_matrix, octave_sparse_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_matrix, octave_sparse_matrix, mul);
+  INSTALL_BINOP (op_div, octave_matrix, octave_sparse_matrix, div);
+  INSTALL_BINOP (op_pow, octave_matrix, octave_sparse_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_matrix, octave_sparse_matrix, ldiv);
+  INSTALL_BINOP (op_mul_trans, octave_matrix, octave_sparse_matrix, mul_trans);
+  INSTALL_BINOP (op_mul_herm, octave_matrix, octave_sparse_matrix, mul_trans);
+  INSTALL_BINOP (op_lt, octave_matrix, octave_sparse_matrix, lt);
+  INSTALL_BINOP (op_le, octave_matrix, octave_sparse_matrix, le);
+  INSTALL_BINOP (op_eq, octave_matrix, octave_sparse_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_matrix, octave_sparse_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_matrix, octave_sparse_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_matrix, octave_sparse_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_matrix, octave_sparse_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_matrix, octave_sparse_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_matrix, octave_sparse_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_sparse_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_matrix, octave_sparse_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_matrix, octave_sparse_matrix,  el_or);
+
+  INSTALL_CATOP (octave_matrix, octave_sparse_matrix, m_sm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_sparse_matrix, assign)
+  INSTALL_ASSIGNCONV (octave_matrix, octave_sparse_matrix, octave_matrix)
+
+  INSTALL_WIDENOP (octave_matrix, octave_sparse_matrix, 
+		   sparse_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-pm-cm.cc b/src/OPERATORS/op-pm-cm.cc
new file mode 100644
index 0000000..14ef9f8
--- /dev/null
+++ b/src/OPERATORS/op-pm-cm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-cx-mat.h"
+
+#define LMATRIX perm_matrix
+#define RMATRIX complex_matrix
+
+#define LSHORT pm
+#define RSHORT cm
+
+#define LEFT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-pm-fcm.cc b/src/OPERATORS/op-pm-fcm.cc
new file mode 100644
index 0000000..698d9f7
--- /dev/null
+++ b/src/OPERATORS/op-pm-fcm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-flt-cx-mat.h"
+
+#define LMATRIX perm_matrix
+#define RMATRIX float_complex_matrix
+
+#define LSHORT pm
+#define RSHORT fcm
+
+#define LEFT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-pm-fm.cc b/src/OPERATORS/op-pm-fm.cc
new file mode 100644
index 0000000..9fd59c6
--- /dev/null
+++ b/src/OPERATORS/op-pm-fm.cc
@@ -0,0 +1,33 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-flt-re-mat.h"
+
+#define LMATRIX perm_matrix
+#define RMATRIX float_matrix
+
+#define LSHORT pm
+#define RSHORT fm
+
+#define LEFT
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-pm-m.cc b/src/OPERATORS/op-pm-m.cc
new file mode 100644
index 0000000..7e70fb7
--- /dev/null
+++ b/src/OPERATORS/op-pm-m.cc
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#define MINCLUDE "ov-re-mat.h"
+
+#define LMATRIX perm_matrix
+#define LDMATRIX matrix
+#define RMATRIX matrix
+
+#define LSHORT pm
+#define RSHORT m
+
+#define LEFT
+#define DEFINENULLASSIGNCONV
+
+#include "op-pm-template.cc"
diff --git a/src/OPERATORS/op-pm-pm.cc b/src/OPERATORS/op-pm-pm.cc
new file mode 100644
index 0000000..d346a35
--- /dev/null
+++ b/src/OPERATORS/op-pm-pm.cc
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-perm.h"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xpow.h"
+
+DEFUNOP (transpose, perm_matrix)
+{
+  CAST_UNOP_ARG (const octave_perm_matrix&);
+  return octave_value (v.perm_matrix_value().transpose ());
+}
+
+DEFBINOP_OP (mul, perm_matrix, perm_matrix, *)
+
+DEFBINOP (div, perm_matrix, perm_matrix)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&);
+  
+  return (v1.perm_matrix_value () * v2.perm_matrix_value ().inverse ());
+}
+
+DEFBINOP (ldiv, perm_matrix, perm_matrix)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&);
+  
+  return (v1.perm_matrix_value ().inverse () * v2.perm_matrix_value ());
+}
+
+DEFBINOP (pow, perm_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_scalar&);
+
+  return xpow (v1.perm_matrix_value (), v2.scalar_value ());
+}
+
+CONVDECL (perm_matrix_to_matrix)
+{
+  CAST_CONV_ARG (const octave_perm_matrix&);
+
+  return new octave_matrix (v.matrix_value ());
+}
+
+void
+install_pm_pm_ops (void)
+{
+  INSTALL_UNOP (op_transpose, octave_perm_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_perm_matrix, transpose);
+
+  INSTALL_BINOP (op_mul, octave_perm_matrix, octave_perm_matrix, mul);
+  INSTALL_BINOP (op_div, octave_perm_matrix, octave_perm_matrix, div);
+  INSTALL_BINOP (op_ldiv, octave_perm_matrix, octave_perm_matrix, ldiv);
+  INSTALL_BINOP (op_pow, octave_perm_matrix, octave_scalar, pow);
+
+  INSTALL_CONVOP (octave_perm_matrix, octave_matrix, perm_matrix_to_matrix);
+  INSTALL_ASSIGNCONV (octave_perm_matrix, octave_matrix, octave_matrix);
+  INSTALL_WIDENOP (octave_perm_matrix, octave_matrix, perm_matrix_to_matrix);
+}
diff --git a/src/OPERATORS/op-pm-scm.cc b/src/OPERATORS/op-pm-scm.cc
new file mode 100644
index 0000000..58c42ce
--- /dev/null
+++ b/src/OPERATORS/op-pm-scm.cc
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 2009 Jason Riedy
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#include "ov-perm.h"
+#include "ov-cx-sparse.h"
+
+// permutation matrix by sparse matrix ops
+
+DEFBINOP (mul_pm_scm, perm_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      std::complex<double> d = v2.complex_value ();
+
+      return octave_value (v1.sparse_matrix_value () * d);
+    }
+  else if (v1.rows() == 1 && v1.columns() == 1)
+    return octave_value (v2.sparse_complex_matrix_value ());
+  else
+    return v1.perm_matrix_value  () * v2.sparse_complex_matrix_value ();
+}
+
+DEFBINOP (ldiv_pm_scm, perm_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_sparse_complex_matrix&);
+
+  return v1.perm_matrix_value ().inverse () * v2.sparse_complex_matrix_value (); 
+}
+
+// sparse matrix by diagonal matrix ops
+
+DEFBINOP (mul_scm_pm, sparse_complex_matrix, perm_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_perm_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      std::complex<double> d = v1.scalar_value ();
+
+      return octave_value (d * v2.sparse_matrix_value ());
+    }
+  else if (v2.rows() == 1 && v2.columns() == 1)
+    return octave_value (v1.sparse_complex_matrix_value ());
+  else
+    return v1.sparse_complex_matrix_value  () * v2.perm_matrix_value ();
+}
+
+DEFBINOP (div_scm_pm, sparse_complex_matrix, perm_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_perm_matrix&);
+
+  return v1.sparse_complex_matrix_value () * v2.perm_matrix_value ().inverse ();
+}
+
+void
+install_pm_scm_ops (void)
+{
+  INSTALL_BINOP (op_mul, octave_perm_matrix, octave_sparse_complex_matrix,
+		 mul_pm_scm);
+  INSTALL_BINOP (op_ldiv, octave_perm_matrix, octave_sparse_complex_matrix,
+		 ldiv_pm_scm);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_perm_matrix,
+		 mul_scm_pm);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_perm_matrix,
+		 div_scm_pm);
+}
diff --git a/src/OPERATORS/op-pm-sm.cc b/src/OPERATORS/op-pm-sm.cc
new file mode 100644
index 0000000..3a6fb2d
--- /dev/null
+++ b/src/OPERATORS/op-pm-sm.cc
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 2009 Jason Riedy
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#include "ov-perm.h"
+#include "ov-re-sparse.h"
+
+// permutation matrix by sparse matrix ops
+
+DEFBINOP (mul_pm_sm, perm_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      return octave_value (v1.sparse_matrix_value () * d);
+    }
+  else if (v1.rows() == 1 && v1.columns() == 1)
+    return octave_value (v2.sparse_matrix_value ());
+  else
+    return v1.perm_matrix_value  () * v2.sparse_matrix_value ();
+}
+
+DEFBINOP (ldiv_pm_sm, perm_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_sparse_matrix&);
+
+  return v1.perm_matrix_value ().inverse () * v2.sparse_matrix_value (); 
+}
+
+// sparse matrix by diagonal matrix ops
+
+DEFBINOP (mul_sm_pm, sparse_matrix, perm_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_perm_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      return octave_value (d * v2.sparse_matrix_value ());
+    }
+  else if (v2.rows() == 1 && v2.columns() == 1)
+    return octave_value (v1.sparse_matrix_value ());
+  else
+    return v1.sparse_matrix_value  () * v2.perm_matrix_value ();
+}
+
+DEFBINOP (div_sm_pm, sparse_matrix, perm_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_perm_matrix&);
+
+  return v1.sparse_matrix_value () * v2.perm_matrix_value ().inverse ();
+}
+
+void
+install_pm_sm_ops (void)
+{
+  INSTALL_BINOP (op_mul, octave_perm_matrix, octave_sparse_matrix,
+		 mul_pm_sm);
+  INSTALL_BINOP (op_ldiv, octave_perm_matrix, octave_sparse_matrix,
+		 ldiv_pm_sm);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_perm_matrix,
+		 mul_sm_pm);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_perm_matrix,
+		 div_sm_pm);
+}
diff --git a/src/OPERATORS/op-pm-template.cc b/src/OPERATORS/op-pm-template.cc
new file mode 100644
index 0000000..33e3ad2
--- /dev/null
+++ b/src/OPERATORS/op-pm-template.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov-perm.h"
+#include MINCLUDE
+#include "ops.h"
+#ifdef DEFINENULLASSIGNCONV
+#include "ov-null-mat.h"
+#endif
+
+#ifndef LDMATRIX
+#define LDMATRIX LMATRIX
+#endif
+
+#define OCTAVE_LMATRIX CONCAT2(octave_, LMATRIX)
+#define OCTAVE_LDMATRIX CONCAT2(octave_, LDMATRIX)
+#define OCTAVE_RMATRIX CONCAT2(octave_, RMATRIX)
+#ifdef LEFT
+#define LMATRIX_VALUE perm_matrix_value
+#define RMATRIX_VALUE CONCAT2(RMATRIX, _value)
+#else
+#define LMATRIX_VALUE CONCAT2(LMATRIX, _value)
+#define RMATRIX_VALUE perm_matrix_value
+#endif
+
+DEFBINOP (mul, LMATRIX, RMATRIX)
+{
+  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+
+  return v1.LMATRIX_VALUE () * v2.RMATRIX_VALUE ();
+}
+
+#ifdef LEFT
+DEFBINOP (ldiv, LMATRIX, RMATRIX)
+{
+  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+
+  return v1.perm_matrix_value ().inverse () * v2.RMATRIX_VALUE (); 
+}
+#else
+DEFBINOP (div, LMATRIX, RMATRIX)
+{
+  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+
+  return v1.LMATRIX_VALUE () * v2.perm_matrix_value ().inverse ();
+}
+#endif
+
+
+#define SHORT_NAME CONCAT3(LSHORT, _, RSHORT)
+#define INST_NAME CONCAT3(install_, SHORT_NAME, _ops)
+
+void
+INST_NAME (void)
+{
+  INSTALL_BINOP (op_mul, OCTAVE_LMATRIX, OCTAVE_RMATRIX, mul);
+#ifdef LEFT
+  INSTALL_BINOP (op_ldiv, OCTAVE_LMATRIX, OCTAVE_RMATRIX, ldiv);
+#else
+  INSTALL_BINOP (op_div, OCTAVE_LMATRIX, OCTAVE_RMATRIX, div);
+#endif
+#ifdef DEFINENULLASSIGNCONV
+  INSTALL_ASSIGNCONV (OCTAVE_LMATRIX, octave_null_matrix, OCTAVE_LDMATRIX);
+  INSTALL_ASSIGNCONV (OCTAVE_LMATRIX, octave_null_str, OCTAVE_LDMATRIX);
+  INSTALL_ASSIGNCONV (OCTAVE_LMATRIX, octave_null_sq_str, OCTAVE_LDMATRIX);
+#endif
+}
diff --git a/src/OPERATORS/op-range.cc b/src/OPERATORS/op-range.cc
new file mode 100644
index 0000000..c26ce8d
--- /dev/null
+++ b/src/OPERATORS/op-range.cc
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-range.h"
+#include "ov-ch-mat.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xpow.h"
+
+// range unary ops.
+
+DEFUNOP (not, range)
+{
+  CAST_UNOP_ARG (const octave_range&);
+
+  return octave_value (! v.matrix_value());
+}
+
+DEFUNOP_OP (uplus, range, /* no-op */)
+DEFUNOP_OP (uminus, range, -)
+
+DEFUNOP (transpose, range)
+{
+  CAST_UNOP_ARG (const octave_range&);
+
+  return octave_value (v.matrix_value().transpose ());
+}
+
+DEFBINOP_OP (addrs, range, scalar, +)
+DEFBINOP_OP (addsr, scalar, range, +)
+DEFBINOP_OP (subrs, range, scalar, -)
+DEFBINOP_OP (subsr, scalar, range, -)
+DEFBINOP_OP (mulrs, range, scalar, *)
+DEFBINOP_OP (mulsr, scalar, range, *)
+
+DEFBINOP_FN (el_powsr, scalar, range, elem_xpow)
+DEFBINOP_FN (el_powcsr, complex, range, elem_xpow)
+
+DEFNDCATOP_FN (r_r, range, range, array, array, concat)
+DEFNDCATOP_FN (r_s, range, scalar, array, array, concat)
+DEFNDCATOP_FN (r_m, range, matrix, array, array, concat)
+DEFNDCATOP_FN (r_cs, range, complex, array, complex_array, concat)
+DEFNDCATOP_FN (r_cm, range, complex_matrix, array, complex_array, concat)
+DEFNDCATOP_FN (r_b, range, bool, array, array, concat)
+DEFNDCATOP_FN (r_bm, range, bool_matrix, array, array, concat)
+DEFNDCATOP_FN (r_chm, range, char_matrix, array, char_array, concat)
+DEFNDCATOP_FN (s_r, scalar, range, array, array, concat)
+DEFNDCATOP_FN (m_r, matrix, range, array, array, concat)
+DEFNDCATOP_FN (cs_r, complex, range, complex_array, array, concat)
+DEFNDCATOP_FN (cm_r, complex_matrix, range, complex_array, array, concat)
+DEFNDCATOP_FN (b_r, bool, range, array, array, concat)
+DEFNDCATOP_FN (bm_r, bool_matrix, range, array, array, concat)
+DEFNDCATOP_FN (chm_r, char_matrix, range, char_array, array, concat)
+
+CONVDECL (range_to_matrix)
+{
+  CAST_CONV_ARG (const octave_range&);
+
+  return new octave_matrix (v.array_value ());
+}
+
+void
+install_range_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_range, not);
+  INSTALL_UNOP (op_uplus, octave_range, uplus);
+  INSTALL_UNOP (op_uminus, octave_range, uminus);
+  INSTALL_UNOP (op_transpose, octave_range, transpose);
+  INSTALL_UNOP (op_hermitian, octave_range, transpose);
+
+  INSTALL_BINOP (op_add, octave_range, octave_scalar, addrs);
+  INSTALL_BINOP (op_add, octave_scalar, octave_range, addsr);
+  INSTALL_BINOP (op_sub, octave_range, octave_scalar, subrs);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_range, subsr);
+  INSTALL_BINOP (op_mul, octave_range, octave_scalar, mulrs);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_range, mulsr);
+
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_range, el_powsr);
+  INSTALL_BINOP (op_el_pow, octave_complex, octave_range, el_powcsr);
+
+  INSTALL_CATOP (octave_range, octave_range, r_r);
+  INSTALL_CATOP (octave_range, octave_scalar, r_s);
+  INSTALL_CATOP (octave_range, octave_matrix, r_m);
+  INSTALL_CATOP (octave_range, octave_complex, r_cs);
+  INSTALL_CATOP (octave_range, octave_complex_matrix, r_cm);
+  INSTALL_CATOP (octave_range, octave_bool, r_b);
+  INSTALL_CATOP (octave_range, octave_bool_matrix, r_bm);
+  INSTALL_CATOP (octave_range, octave_char_matrix, r_chm);
+  INSTALL_CATOP (octave_scalar, octave_range, s_r);
+  INSTALL_CATOP (octave_matrix, octave_range, m_r);
+  INSTALL_CATOP (octave_complex, octave_range, cs_r);
+  INSTALL_CATOP (octave_complex_matrix, octave_range, cm_r);
+  INSTALL_CATOP (octave_bool, octave_range, b_r);
+  INSTALL_CATOP (octave_bool_matrix, octave_range, bm_r);
+  INSTALL_CATOP (octave_char_matrix, octave_range, chm_r);
+
+  // FIXME -- this would be unneccessary if
+  // octave_base_value::numeric_assign always tried converting lhs
+  // before rhs.
+  
+  INSTALL_ASSIGNCONV (octave_range, octave_null_matrix, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_range, octave_null_str, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_range, octave_null_sq_str, octave_matrix);
+
+  // However, this should probably be here just in case we need it.
+  
+  INSTALL_WIDENOP (octave_range, octave_matrix, range_to_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-s-cm.cc b/src/OPERATORS/op-s-cm.cc
new file mode 100644
index 0000000..33339a9
--- /dev/null
+++ b/src/OPERATORS/op-s-cm.cc
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-s-cm.h"
+#include "mx-cm-s.h"
+#include "mx-s-cnda.h"
+#include "mx-cnda-s.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by complex matrix ops.
+
+DEFNDBINOP_OP (add, scalar, complex_matrix, scalar, complex_array, +)
+DEFNDBINOP_OP (sub, scalar, complex_matrix, scalar, complex_array, -)
+DEFNDBINOP_OP (mul, scalar, complex_matrix, scalar, complex_array, *)
+
+DEFBINOP (div, scalar, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
+
+  Matrix m1 = v1.matrix_value ();
+  ComplexMatrix m2 = v2.complex_matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  ComplexMatrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, scalar, complex_matrix, xpow)
+
+DEFBINOP (ldiv, scalar, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, scalar, complex_matrix, scalar, complex_array, mx_el_lt)
+DEFNDBINOP_FN (le, scalar, complex_matrix, scalar, complex_array, mx_el_le)
+DEFNDBINOP_FN (eq, scalar, complex_matrix, scalar, complex_array, mx_el_eq)
+DEFNDBINOP_FN (ge, scalar, complex_matrix, scalar, complex_array, mx_el_ge)
+DEFNDBINOP_FN (gt, scalar, complex_matrix, scalar, complex_array, mx_el_gt)
+DEFNDBINOP_FN (ne, scalar, complex_matrix, scalar, complex_array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, scalar, complex_matrix, scalar, complex_array, *)
+DEFNDBINOP_FN (el_div, scalar, complex_matrix, scalar, complex_array, x_el_div)
+DEFNDBINOP_FN (el_pow, scalar, complex_matrix, scalar, complex_array, elem_xpow)
+
+DEFBINOP (el_ldiv, scalar, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, scalar, complex_matrix, scalar, complex_array, mx_el_and)
+DEFNDBINOP_FN (el_or,  scalar, complex_matrix, scalar, complex_array, mx_el_or)
+
+DEFNDCATOP_FN (s_cm, scalar, complex_matrix, array, complex_array, concat)
+
+DEFCONV (complex_matrix_conv, scalar, complex_matrix)
+{
+  CAST_CONV_ARG (const octave_scalar&);
+
+  return new octave_complex_matrix (ComplexMatrix (v.matrix_value ()));
+}
+
+void
+install_s_cm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_scalar, octave_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_scalar, octave_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_scalar, octave_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_scalar, octave_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_scalar, octave_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_scalar, octave_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_scalar, octave_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_scalar, octave_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_scalar, octave_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_scalar, octave_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_scalar, octave_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_scalar, octave_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_scalar, octave_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_scalar, octave_complex_matrix, s_cm);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_complex_matrix, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_complex_matrix, octave_float_complex_matrix);
+
+  INSTALL_WIDENOP (octave_scalar, octave_complex_matrix, complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-s-cs.cc b/src/OPERATORS/op-s-cs.cc
new file mode 100644
index 0000000..cd1bf17
--- /dev/null
+++ b/src/OPERATORS/op-s-cs.cc
@@ -0,0 +1,191 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by complex scalar ops.
+
+DEFBINOP_OP (add, scalar, complex, +)
+DEFBINOP_OP (sub, scalar, complex, -)
+DEFBINOP_OP (mul, scalar, complex, *)
+
+DEFBINOP (div, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.double_value () / d);
+}
+
+DEFBINOP_FN (pow, scalar, complex, xpow)
+
+DEFBINOP (ldiv, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_value () / d);
+}
+
+DEFBINOP (lt, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return v1.double_value () < real (v2.complex_value ());
+}
+
+DEFBINOP (le, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return v1.double_value () <= real (v2.complex_value ());
+}
+
+DEFBINOP (eq, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return v1.double_value () == v2.complex_value ();
+}
+
+DEFBINOP (ge, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return v1.double_value () >= real (v2.complex_value ());
+}
+
+DEFBINOP (gt, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return v1.double_value () > real (v2.complex_value ());
+}
+
+DEFBINOP (ne, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return v1.double_value () != v2.complex_value ();
+}
+
+DEFBINOP_OP (el_mul, scalar, complex, *)
+
+DEFBINOP (el_div, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.double_value () / d);
+}
+
+DEFBINOP_FN (el_pow, scalar, complex, xpow)
+
+DEFBINOP (el_ldiv, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.complex_value () / d);
+}
+
+DEFBINOP (el_and, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return octave_value (v1.double_value () && (v2.complex_value () != 0.0));
+}
+
+DEFBINOP (el_or, scalar, complex)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+
+  return octave_value (v1.double_value () || (v2.complex_value () != 0.0));
+}
+
+DEFNDCATOP_FN (s_cs, scalar, complex, array, complex_array, concat)
+
+void
+install_s_cs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_scalar, octave_complex, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_complex, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_complex, mul);
+  INSTALL_BINOP (op_div, octave_scalar, octave_complex, div);
+  INSTALL_BINOP (op_pow, octave_scalar, octave_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_scalar, octave_complex, ldiv);
+  INSTALL_BINOP (op_lt, octave_scalar, octave_complex, lt);
+  INSTALL_BINOP (op_le, octave_scalar, octave_complex, le);
+  INSTALL_BINOP (op_eq, octave_scalar, octave_complex, eq);
+  INSTALL_BINOP (op_ge, octave_scalar, octave_complex, ge);
+  INSTALL_BINOP (op_gt, octave_scalar, octave_complex, gt);
+  INSTALL_BINOP (op_ne, octave_scalar, octave_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_scalar, octave_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_scalar, octave_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_scalar, octave_complex, el_or);
+
+  INSTALL_CATOP (octave_scalar, octave_complex, s_cs);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_complex, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_complex, octave_float_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-s-m.cc b/src/OPERATORS/op-s-m.cc
new file mode 100644
index 0000000..5d21c34
--- /dev/null
+++ b/src/OPERATORS/op-s-m.cc
@@ -0,0 +1,143 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by matrix ops.
+
+DEFNDBINOP_OP (add, scalar, matrix, scalar, array, +)
+DEFNDBINOP_OP (sub, scalar, matrix, scalar, array, -)
+DEFNDBINOP_OP (mul, scalar, matrix, scalar, array, *)
+
+DEFBINOP (div, scalar, matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_matrix&);
+
+  Matrix m1 = v1.matrix_value ();
+  Matrix m2 = v2.matrix_value ();
+  MatrixType typ = v2.matrix_type ();
+
+  Matrix ret = xdiv (m1, m2, typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOP_FN (pow, scalar, matrix, xpow)
+
+DEFBINOP (ldiv, scalar, matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_matrix&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.array_value () / d);
+}
+
+DEFNDBINOP_FN (lt, scalar, matrix, scalar, array, mx_el_lt)
+DEFNDBINOP_FN (le, scalar, matrix, scalar, array, mx_el_le)
+DEFNDBINOP_FN (eq, scalar, matrix, scalar, array, mx_el_eq)
+DEFNDBINOP_FN (ge, scalar, matrix, scalar, array, mx_el_ge)
+DEFNDBINOP_FN (gt, scalar, matrix, scalar, array, mx_el_gt)
+DEFNDBINOP_FN (ne, scalar, matrix, scalar, array, mx_el_ne)
+
+DEFNDBINOP_OP (el_mul, scalar, matrix, scalar, array, *)
+DEFNDBINOP_FN (el_div, scalar, matrix, scalar, array, x_el_div)
+DEFNDBINOP_FN (el_pow, scalar, matrix, scalar, array, elem_xpow)
+
+DEFBINOP (el_ldiv, scalar, matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_matrix&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.array_value () / d);
+}
+
+DEFNDBINOP_FN (el_and, scalar, matrix, scalar, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  scalar, matrix, scalar, array, mx_el_or)
+
+DEFNDCATOP_FN (s_m, scalar, matrix, array, array, concat)
+
+DEFCONV (matrix_conv, scalar, matrix)
+{
+  CAST_CONV_ARG (const octave_scalar&);
+
+  return new octave_matrix (v.matrix_value ());
+}
+
+void
+install_s_m_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_scalar, octave_matrix, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_matrix, mul);
+  INSTALL_BINOP (op_div, octave_scalar, octave_matrix, div);
+  INSTALL_BINOP (op_pow, octave_scalar, octave_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_scalar, octave_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_scalar, octave_matrix, lt);
+  INSTALL_BINOP (op_le, octave_scalar, octave_matrix, le);
+  INSTALL_BINOP (op_eq, octave_scalar, octave_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_scalar, octave_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_scalar, octave_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_scalar, octave_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_scalar, octave_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_scalar, octave_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_scalar, octave_matrix, el_or);
+
+  INSTALL_CATOP (octave_scalar, octave_matrix, s_m);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_matrix, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_matrix, octave_float_matrix);
+
+  INSTALL_WIDENOP (octave_scalar, octave_matrix, matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-s-s.cc b/src/OPERATORS/op-s-s.cc
new file mode 100644
index 0000000..7530eba
--- /dev/null
+++ b/src/OPERATORS/op-s-s.cc
@@ -0,0 +1,169 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar unary ops.
+
+DEFUNOP_OP (not, scalar, !)
+DEFUNOP_OP (uplus, scalar, /* no-op */)
+DEFUNOP_OP (uminus, scalar, -)
+DEFUNOP_OP (transpose, scalar, /* no-op */)
+DEFUNOP_OP (hermitian, scalar, /* no-op */)
+
+DEFNCUNOP_METHOD (incr, scalar, increment)
+DEFNCUNOP_METHOD (decr, scalar, decrement)
+
+// scalar by scalar ops.
+
+DEFBINOP_OP (add, scalar, scalar, +)
+DEFBINOP_OP (sub, scalar, scalar, -)
+DEFBINOP_OP (mul, scalar, scalar, *)
+
+DEFBINOP (div, scalar, scalar)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.double_value () / d);
+}
+
+DEFBINOP_FN (pow, scalar, scalar, xpow)
+
+DEFBINOP (ldiv, scalar, scalar)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.double_value () / d);
+}
+
+DEFBINOP_OP (lt, scalar, scalar, <)
+DEFBINOP_OP (le, scalar, scalar, <=)
+DEFBINOP_OP (eq, scalar, scalar, ==)
+DEFBINOP_OP (ge, scalar, scalar, >=)
+DEFBINOP_OP (gt, scalar, scalar, >)
+DEFBINOP_OP (ne, scalar, scalar, !=)
+
+DEFBINOP_OP (el_mul, scalar, scalar, *)
+
+DEFBINOP (el_div, scalar, scalar)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.double_value () / d);
+}
+
+DEFBINOP_FN (el_pow, scalar, scalar, xpow)
+
+DEFBINOP (el_ldiv, scalar, scalar)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+
+  double d = v1.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v2.double_value () / d);
+}
+
+DEFSCALARBOOLOP_OP (el_and, scalar, scalar, &&)
+DEFSCALARBOOLOP_OP (el_or, scalar, scalar, ||)
+
+DEFNDCATOP_FN (s_s, scalar, scalar, array, array, concat)
+
+void
+install_s_s_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_scalar, not);
+  INSTALL_UNOP (op_uplus, octave_scalar, uplus);
+  INSTALL_UNOP (op_uminus, octave_scalar, uminus);
+  INSTALL_UNOP (op_transpose, octave_scalar, transpose);
+  INSTALL_UNOP (op_hermitian, octave_scalar, hermitian);
+
+  INSTALL_NCUNOP (op_incr, octave_scalar, incr);
+  INSTALL_NCUNOP (op_decr, octave_scalar, decr);
+
+  INSTALL_BINOP (op_add, octave_scalar, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_scalar, octave_scalar, div);
+  INSTALL_BINOP (op_pow, octave_scalar, octave_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_scalar, octave_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_scalar, octave_scalar, lt);
+  INSTALL_BINOP (op_le, octave_scalar, octave_scalar, le);
+  INSTALL_BINOP (op_eq, octave_scalar, octave_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_scalar, octave_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_scalar, octave_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_scalar, octave_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_scalar, octave_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_scalar, octave_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_scalar, octave_scalar, el_or);
+
+  INSTALL_CATOP (octave_scalar, octave_scalar, s_s);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_scalar, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_float_scalar, octave_scalar, octave_float_matrix);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_null_matrix, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_scalar, octave_null_str, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_scalar, octave_null_sq_str, octave_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-s-scm.cc b/src/OPERATORS/op-s-scm.cc
new file mode 100644
index 0000000..6a4fc04
--- /dev/null
+++ b/src/OPERATORS/op-s-scm.cc
@@ -0,0 +1,184 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ov-scalar.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-s-scm.h"
+#include "smx-scm-s.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// scalar by sparse complex matrix ops.
+
+DEFBINOP_OP (add, scalar, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, scalar, sparse_complex_matrix, -)
+DEFBINOP_OP (mul, scalar, sparse_complex_matrix, *)
+
+DEFBINOP (div, scalar, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseComplexMatrix (1, 1, v1.scalar_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      Matrix m1 = Matrix (1, 1, v1.scalar_value ());
+      SparseComplexMatrix m2 = v2.sparse_complex_matrix_value ();
+      ComplexMatrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP (pow, scalar, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, 
+		   const octave_sparse_complex_matrix&);
+  return xpow (v1.scalar_value (), v2.complex_matrix_value ());
+}
+
+DEFBINOP (ldiv, scalar, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, 
+		   const octave_sparse_complex_matrix&);
+
+  double d = v1.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (lt, scalar, sparse_complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, scalar, sparse_complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, scalar, sparse_complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, scalar, sparse_complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, scalar, sparse_complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, scalar, sparse_complex_matrix, mx_el_ne)
+
+DEFBINOP_OP (el_mul, scalar, sparse_complex_matrix, *)
+DEFBINOP_FN (el_div, scalar, sparse_complex_matrix, x_el_div)
+DEFBINOP_FN (el_pow, scalar, sparse_complex_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, scalar, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, 
+		   const octave_sparse_complex_matrix&);
+
+  double d = v1.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_and, scalar, sparse_complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or, scalar, sparse_complex_matrix, mx_el_or)
+
+DEFCATOP (s_scm, scalar, sparse_compelx_matrix)
+{
+  CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_complex_matrix&);
+  SparseMatrix tmp (1, 1, v1.scalar_value ());
+  return octave_value
+    (tmp.concat (v2.sparse_complex_matrix_value (), ra_idx));
+}
+
+DEFCONV (sparse_complex_matrix_conv, scalar, sparse_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_scalar&);
+
+  return new octave_sparse_complex_matrix 
+    (SparseComplexMatrix (v.complex_matrix_value ()));
+}
+
+void
+install_s_scm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_scalar, octave_sparse_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_sparse_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_sparse_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_scalar, octave_sparse_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_scalar, octave_sparse_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_scalar, octave_sparse_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_scalar, octave_sparse_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_scalar, octave_sparse_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_scalar, octave_sparse_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_scalar, octave_sparse_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_scalar, octave_sparse_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_scalar, octave_sparse_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_sparse_complex_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_scalar, octave_sparse_complex_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_sparse_complex_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_sparse_complex_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_scalar, octave_sparse_complex_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_scalar, octave_sparse_complex_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_scalar, octave_sparse_complex_matrix, s_scm);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_sparse_complex_matrix, 
+		      octave_complex_matrix);
+
+  INSTALL_WIDENOP (octave_scalar, octave_sparse_complex_matrix, 
+		   sparse_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-s-sm.cc b/src/OPERATORS/op-s-sm.cc
new file mode 100644
index 0000000..46399c9
--- /dev/null
+++ b/src/OPERATORS/op-s-sm.cc
@@ -0,0 +1,167 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-scalar.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-re-sparse.h"
+
+// scalar by sparse matrix ops.
+
+DEFBINOP_OP (add, scalar, sparse_matrix, +)
+DEFBINOP_OP (sub, scalar, sparse_matrix, -)
+DEFBINOP_OP (mul, scalar, sparse_matrix, *)
+
+DEFBINOP (div, scalar, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseMatrix (1, 1, v1.scalar_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      Matrix m1 = Matrix (1, 1, v1.double_value ());
+      SparseMatrix m2 = v2.sparse_matrix_value ();
+      Matrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP (pow, scalar, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+  return xpow (v1.scalar_value (), v2.matrix_value ());
+}
+
+DEFBINOP (ldiv, scalar, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+
+  double d = v1.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (lt, scalar, sparse_matrix, mx_el_lt)
+DEFBINOP_FN (le, scalar, sparse_matrix, mx_el_le)
+DEFBINOP_FN (eq, scalar, sparse_matrix, mx_el_eq)
+DEFBINOP_FN (ge, scalar, sparse_matrix, mx_el_ge)
+DEFBINOP_FN (gt, scalar, sparse_matrix, mx_el_gt)
+DEFBINOP_FN (ne, scalar, sparse_matrix, mx_el_ne)
+
+DEFBINOP_OP (el_mul, scalar, sparse_matrix, *)
+DEFBINOP_FN (el_div, scalar, sparse_matrix, x_el_div)
+DEFBINOP_FN (el_pow, scalar, sparse_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, scalar, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+
+  double d = v1.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v2.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_and, scalar, sparse_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  scalar, sparse_matrix, mx_el_or)
+
+DEFCATOP (s_sm, scalar, sparse_matrix)
+{
+  CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_matrix&);
+  SparseMatrix tmp (1, 1, v1.scalar_value ());
+  return octave_value (tmp.concat (v2.sparse_matrix_value (), ra_idx));
+}
+
+DEFCONV (sparse_matrix_conv, scalar, sparse_matrix)
+{
+  CAST_CONV_ARG (const octave_scalar&);
+
+  return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
+}
+
+void
+install_s_sm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_scalar, octave_sparse_matrix, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_sparse_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_sparse_matrix, mul);
+  INSTALL_BINOP (op_div, octave_scalar, octave_sparse_matrix, div);
+  INSTALL_BINOP (op_pow, octave_scalar, octave_sparse_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_scalar, octave_sparse_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_scalar, octave_sparse_matrix, lt);
+  INSTALL_BINOP (op_le, octave_scalar, octave_sparse_matrix, le);
+  INSTALL_BINOP (op_eq, octave_scalar, octave_sparse_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_scalar, octave_sparse_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_scalar, octave_sparse_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_scalar, octave_sparse_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_sparse_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_scalar, octave_sparse_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_scalar, octave_sparse_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_sparse_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_scalar, octave_sparse_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_scalar, octave_sparse_matrix, el_or);
+
+  INSTALL_CATOP (octave_scalar, octave_sparse_matrix, s_sm);
+
+  INSTALL_ASSIGNCONV (octave_scalar, octave_sparse_matrix, octave_matrix);
+
+  INSTALL_WIDENOP (octave_scalar, octave_sparse_matrix, sparse_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sbm-b.cc b/src/OPERATORS/op-sbm-b.cc
new file mode 100644
index 0000000..bec6200
--- /dev/null
+++ b/src/OPERATORS/op-sbm-b.cc
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-bool.h"
+#include "ov-scalar.h"
+#include "ops.h"
+
+#include "ov-re-sparse.h"
+#include "ov-bool-sparse.h"
+
+// sparse bool matrix by bool ops.
+
+DEFBINOP_FN (ne, sparse_bool_matrix, bool, mx_el_ne)
+DEFBINOP_FN (eq, sparse_bool_matrix, bool, mx_el_eq)
+
+DEFBINOP_FN (el_and, sparse_bool_matrix, bool, mx_el_and)
+DEFBINOP_FN (el_or, sparse_bool_matrix, bool, mx_el_or)
+
+DEFCATOP (sbm_b, sparse_bool_matrix, bool)
+{
+  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool&); 
+		   
+  SparseBoolMatrix tmp (1, 1, v2.bool_value ());
+  return octave_value (v1.sparse_bool_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFCATOP (sm_b, sparse_matrix, bool)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_bool&);
+		   
+  SparseMatrix tmp (1, 1, v2.scalar_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFCATOP (sbm_s, sparse_bool_matrix, scalar)
+{
+  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_scalar&); 
+		   
+  SparseMatrix tmp (1, 1, v2.scalar_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_bool_matrix, bool)
+{
+  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool&);
+
+  SparseBoolMatrix tmp (1, 1, v2.bool_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_sbm_b_ops (void)
+{
+  INSTALL_BINOP (op_eq, octave_sparse_bool_matrix, octave_bool, eq);
+  INSTALL_BINOP (op_ne, octave_sparse_bool_matrix, octave_bool, ne);
+
+  INSTALL_BINOP (op_el_and, octave_sparse_bool_matrix, octave_bool, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_bool_matrix, octave_bool, el_or);
+
+  INSTALL_CATOP (octave_sparse_bool_matrix, octave_bool, sbm_b);
+  INSTALL_CATOP (octave_sparse_bool_matrix, octave_scalar, sbm_s);
+  INSTALL_CATOP (octave_sparse_matrix, octave_bool, sm_b);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_bool_matrix, octave_bool, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sbm-bm.cc b/src/OPERATORS/op-sbm-bm.cc
new file mode 100644
index 0000000..dcedbcc
--- /dev/null
+++ b/src/OPERATORS/op-sbm-bm.cc
@@ -0,0 +1,105 @@
+/*
+
+Copyright (C) 2004, 2005, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-bool-mat.h"
+#include "boolMatrix.h"
+#include "ov-scalar.h"
+#include "ops.h"
+
+#include "ov-re-sparse.h"
+#include "ov-bool-sparse.h"
+#include "smx-bm-sbm.h"
+#include "smx-sbm-bm.h"
+
+// sparse bool matrix by bool matrix ops.
+
+DEFBINOP_FN (eq, sparse_bool_matrix, bool_matrix, mx_el_eq)
+DEFBINOP_FN (ne, sparse_bool_matrix, bool_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_and, sparse_bool_matrix, bool_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_bool_matrix, bool_matrix, mx_el_or)
+
+DEFCATOP (sbm_bm, sparse_bool_matrix, bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool_matrix&); 
+		   
+  SparseBoolMatrix tmp (v2.bool_matrix_value ());
+  return octave_value (v1.sparse_bool_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFCATOP (sbm_m, sparse_bool_matrix, matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_matrix&);
+		   
+  SparseMatrix tmp (v2.matrix_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFCATOP (sm_bm, sparse_matrix, bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_bool_matrix&); 
+		   
+  SparseMatrix tmp (v2.matrix_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_bool_matrix, bool_matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool_matrix&);
+
+  v1.assign (idx, SparseBoolMatrix (v2.bool_matrix_value ()));
+  return octave_value ();
+}
+
+void
+install_sbm_bm_ops (void)
+{
+  INSTALL_BINOP (op_eq, octave_sparse_bool_matrix, octave_bool_matrix, eq);
+  INSTALL_BINOP (op_ne, octave_sparse_bool_matrix, octave_bool_matrix, ne);
+
+  INSTALL_BINOP (op_el_and, octave_sparse_bool_matrix, octave_bool_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_bool_matrix, octave_bool_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_sparse_bool_matrix, octave_bool_matrix, sbm_bm);
+  INSTALL_CATOP (octave_sparse_matrix, octave_bool_matrix, sm_bm);
+  INSTALL_CATOP (octave_sparse_bool_matrix, octave_matrix, sbm_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_bool_matrix, 
+		    octave_bool_matrix, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sbm-sbm.cc b/src/OPERATORS/op-sbm-sbm.cc
new file mode 100644
index 0000000..37ecfc8
--- /dev/null
+++ b/src/OPERATORS/op-sbm-sbm.cc
@@ -0,0 +1,120 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-bool-mat.h"
+#include "ov-scalar.h"
+#include "ops.h"
+
+#include "ov-re-sparse.h"
+#include "ov-bool-sparse.h"
+
+// unary sparse bool matrix ops.
+
+DEFUNOP_OP (not, sparse_bool_matrix, !)
+
+DEFUNOP (uplus, sparse_bool_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
+  return octave_value (v.sparse_matrix_value ());
+}
+
+DEFUNOP (uminus, sparse_bool_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
+  return octave_value ( - v.sparse_matrix_value ());
+}
+
+DEFUNOP (transpose, sparse_bool_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
+  return octave_value (v.sparse_bool_matrix_value().transpose ());
+}
+
+// sparse bool matrix by sparse bool matrix ops.
+
+DEFBINOP_FN (eq, sparse_bool_matrix, sparse_bool_matrix, mx_el_eq)
+DEFBINOP_FN (ne, sparse_bool_matrix, sparse_bool_matrix, mx_el_ne)
+DEFBINOP_FN (el_and, sparse_bool_matrix, sparse_bool_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_bool_matrix, sparse_bool_matrix, mx_el_or)
+
+DEFNDCATOP_FN (sbm_sbm, sparse_bool_matrix, sparse_bool_matrix, 
+	       sparse_bool_matrix, sparse_bool_matrix, concat)
+DEFNDCATOP_FN (sbm_sm, sparse_bool_matrix, sparse_matrix, sparse_matrix, 
+	       sparse_matrix, concat)
+DEFNDCATOP_FN (sm_sbm, sparse_matrix, sparse_bool_matrix, sparse_matrix, 
+	       sparse_matrix, concat)
+
+DEFASSIGNOP_FN (assign, sparse_bool_matrix, sparse_bool_matrix, 
+		assign)
+
+CONVDECL (bool_matrix_to_double_matrix)
+{
+  CAST_CONV_ARG (const octave_sparse_bool_matrix&);
+
+  return new octave_sparse_matrix (SparseMatrix (v.sparse_bool_matrix_value ()));
+}
+
+void
+install_sbm_sbm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_sparse_bool_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_sparse_bool_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_sparse_bool_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_sparse_bool_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_sparse_bool_matrix, transpose);
+
+  INSTALL_BINOP (op_eq, octave_sparse_bool_matrix, 
+		 octave_sparse_bool_matrix, eq);
+  INSTALL_BINOP (op_ne, octave_sparse_bool_matrix, 
+		 octave_sparse_bool_matrix, ne);
+
+  INSTALL_BINOP (op_el_and, octave_sparse_bool_matrix, 
+		 octave_sparse_bool_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_bool_matrix, 
+		 octave_sparse_bool_matrix, el_or);
+
+  INSTALL_CATOP (octave_sparse_bool_matrix, octave_sparse_bool_matrix, 
+		 sbm_sbm);
+  INSTALL_CATOP (octave_sparse_bool_matrix, octave_sparse_matrix, sbm_sm);
+  INSTALL_CATOP (octave_sparse_matrix, octave_sparse_bool_matrix, sm_sbm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_bool_matrix, 
+		    octave_sparse_bool_matrix, assign); 
+
+  INSTALL_CONVOP (octave_sparse_bool_matrix, octave_sparse_matrix, 
+		  bool_matrix_to_double_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-scm-cm.cc b/src/OPERATORS/op-scm-cm.cc
new file mode 100644
index 0000000..90e0728
--- /dev/null
+++ b/src/OPERATORS/op-scm-cm.cc
@@ -0,0 +1,202 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-scm-cm.h"
+#include "smx-cm-scm.h"
+#include "ov-cx-sparse.h"
+
+// sparse complex matrix by complex matrix ops.
+
+DEFBINOP_OP (add, sparse_complex_matrix, complex_matrix, +)
+DEFBINOP_OP (sub, sparse_complex_matrix, complex_matrix, -)
+
+DEFBINOP_OP (mul, sparse_complex_matrix, complex_matrix, *)
+
+DEFBINOP (div, sparse_complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+			    v2.complex_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, sparse_complex_matrix, complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      ComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
+		      v2.complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (trans_mul, sparse_complex_matrix, complex_matrix, trans_mul);
+DEFBINOP_FN (herm_mul, sparse_complex_matrix, complex_matrix, herm_mul);
+
+DEFBINOP_FN (lt, sparse_complex_matrix, complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_complex_matrix, complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_complex_matrix, complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_complex_matrix, complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_complex_matrix, complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_complex_matrix, complex_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_complex_matrix, complex_matrix, product)
+DEFBINOP_FN (el_div, sparse_complex_matrix, complex_matrix, quotient)
+
+DEFBINOP (el_pow, sparse_complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex_matrix&);
+  
+  return octave_value 
+    (elem_xpow (v1.sparse_complex_matrix_value (), SparseComplexMatrix 
+		(v2.complex_matrix_value ())));
+}
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex_matrix&);
+
+  return octave_value (quotient (v2.complex_matrix_value (), 
+				 v1.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_complex_matrix, complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_complex_matrix, complex_matrix, mx_el_or)
+
+DEFCATOP (scm_cm, sparse_complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, 
+		   const octave_complex_matrix&);
+  SparseComplexMatrix tmp (v2.complex_matrix_value ());
+  return octave_value
+    (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_complex_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&,
+		   const octave_complex_matrix&);
+
+  SparseComplexMatrix tmp (v2.complex_matrix_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_scm_cm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, ldiv);
+  INSTALL_BINOP (op_trans_mul, octave_sparse_complex_matrix, 
+                 octave_complex_matrix, trans_mul);
+  INSTALL_BINOP (op_herm_mul, octave_sparse_complex_matrix, 
+                 octave_complex_matrix, herm_mul);
+  INSTALL_BINOP (op_lt, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_complex_matrix, 
+		 octave_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_sparse_complex_matrix, 
+		 octave_complex_matrix, scm_cm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix,
+		    octave_complex_matrix, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-scm-cs.cc b/src/OPERATORS/op-scm-cs.cc
new file mode 100644
index 0000000..d14fc7e
--- /dev/null
+++ b/src/OPERATORS/op-scm-cs.cc
@@ -0,0 +1,190 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ov-complex.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-cx-sparse.h"
+
+// sparse complex matrix by complex scalar ops.
+
+DEFBINOP_OP (add, sparse_complex_matrix, complex, +)
+DEFBINOP_OP (sub, sparse_complex_matrix, complex, -)
+DEFBINOP_OP (mul, sparse_complex_matrix, complex, *)
+
+DEFBINOP (div, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex&);
+
+  Complex d = v2.complex_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP (pow, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex&);
+  return xpow (v1.complex_matrix_value (), v2.complex_value ());
+}
+
+DEFBINOP (ldiv, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseComplexMatrix (1, 1, v2.complex_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix m1 = v1.sparse_complex_matrix_value ();
+      ComplexMatrix m2 = ComplexMatrix (1, 1, v2.complex_value ());
+      ComplexMatrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_complex_matrix, complex, mx_el_lt)
+DEFBINOP_FN (le, sparse_complex_matrix, complex, mx_el_le)
+DEFBINOP_FN (eq, sparse_complex_matrix, complex, mx_el_eq)
+DEFBINOP_FN (ge, sparse_complex_matrix, complex, mx_el_ge)
+DEFBINOP_FN (gt, sparse_complex_matrix, complex, mx_el_gt)
+DEFBINOP_FN (ne, sparse_complex_matrix, complex, mx_el_ne)
+
+DEFBINOP_OP (el_mul, sparse_complex_matrix, complex, *)
+
+DEFBINOP (el_div, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex&);
+
+  octave_value retval;
+
+  Complex d = v2.complex_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval =  octave_value (v1.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_pow, sparse_complex_matrix, complex, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_complex&);
+
+  return octave_value
+    (x_el_div (v2.complex_value (), v1.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_complex_matrix, complex, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_complex_matrix, complex, mx_el_or)
+
+DEFCATOP (scm_cs, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_complex&);
+  SparseComplexMatrix tmp (1, 1, v2.complex_value ());
+  return octave_value
+    (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_complex_matrix, complex)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_complex&);
+
+  SparseComplexMatrix tmp (1, 1, v2.complex_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_scm_cs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, octave_complex, add);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, octave_complex, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_complex, mul);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_complex, div);
+  INSTALL_BINOP (op_pow, octave_sparse_complex_matrix, octave_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_complex_matrix, octave_complex, 
+		 ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_complex_matrix, octave_complex, lt);
+  INSTALL_BINOP (op_le, octave_sparse_complex_matrix, octave_complex, le);
+  INSTALL_BINOP (op_eq, octave_sparse_complex_matrix, octave_complex, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_complex_matrix, octave_complex, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_complex_matrix, octave_complex, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_complex_matrix, octave_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_complex_matrix, octave_complex, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_complex_matrix, octave_complex, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_complex_matrix, octave_complex, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_complex_matrix, octave_complex, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_complex_matrix, octave_complex, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_complex_matrix, octave_complex, 
+		 el_or);
+
+  INSTALL_CATOP (octave_sparse_complex_matrix, octave_complex, scm_cs);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, octave_complex,
+		    assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-scm-m.cc b/src/OPERATORS/op-scm-m.cc
new file mode 100644
index 0000000..4b59aad
--- /dev/null
+++ b/src/OPERATORS/op-scm-m.cc
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-scm-m.h"
+#include "smx-m-scm.h"
+#include "ov-cx-sparse.h"
+
+// sparse complex matrix by matrix ops.
+
+DEFBINOP_OP (add, sparse_complex_matrix, matrix, +)
+DEFBINOP_OP (sub, sparse_complex_matrix, matrix, -)
+
+DEFBINOP_OP (mul, sparse_complex_matrix, matrix, *)
+
+DEFBINOP (div, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+                   const octave_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+			    v2.matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, sparse_complex_matrix, matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_matrix&);
+  
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      ComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
+				    v2.matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_complex_matrix, matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_complex_matrix, matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_complex_matrix, matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_complex_matrix, matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_complex_matrix, matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_complex_matrix, matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_complex_matrix, matrix, product)
+DEFBINOP_FN (el_div, sparse_complex_matrix, matrix, quotient)
+
+DEFBINOP (el_pow, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_matrix&);
+  
+  return octave_value 
+    (elem_xpow (v1.sparse_complex_matrix_value (), SparseMatrix 
+		(v2.matrix_value ())));
+}
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_matrix&);
+
+  return octave_value
+    (quotient (v2.matrix_value (), v1.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_complex_matrix, matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_complex_matrix, matrix, mx_el_or)
+
+DEFCATOP (scm_m, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_matrix&);
+  SparseMatrix tmp (v2.matrix_value ());
+  return octave_value
+    (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_complex_matrix, matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_matrix&);
+
+  SparseComplexMatrix tmp (v2.complex_matrix_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_scm_m_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, octave_matrix, add);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, octave_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_matrix, mul);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_matrix, div);
+  INSTALL_BINOP (op_pow, octave_sparse_complex_matrix, octave_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_complex_matrix, octave_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_complex_matrix, octave_matrix, lt);
+  INSTALL_BINOP (op_le, octave_sparse_complex_matrix, octave_matrix, le);
+  INSTALL_BINOP (op_eq, octave_sparse_complex_matrix, octave_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_complex_matrix, octave_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_complex_matrix, octave_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_complex_matrix, octave_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_complex_matrix, octave_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_complex_matrix, octave_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_complex_matrix, octave_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_complex_matrix, octave_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_complex_matrix, octave_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_complex_matrix, octave_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_sparse_complex_matrix, octave_matrix, scm_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, octave_matrix, 
+		    assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-scm-s.cc b/src/OPERATORS/op-scm-s.cc
new file mode 100644
index 0000000..7459ec8
--- /dev/null
+++ b/src/OPERATORS/op-scm-s.cc
@@ -0,0 +1,195 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ov-scalar.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-scm-s.h"
+#include "smx-s-scm.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// sparse complex matrix by scalar ops.
+
+DEFBINOP_OP (add, sparse_complex_matrix, scalar, +)
+DEFBINOP_OP (sub, sparse_complex_matrix, scalar, -)
+DEFBINOP_OP (mul, sparse_complex_matrix, scalar, *)
+
+DEFBINOP (div, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_scalar&);
+
+  double d = v2.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP (pow, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_scalar&);
+
+  double tmp = v2.scalar_value ();
+  if (static_cast<int> (tmp) == tmp)
+    return xpow (v1.sparse_complex_matrix_value (), tmp);
+  else
+    return xpow (v1.complex_matrix_value (), tmp);
+}
+
+DEFBINOP (ldiv, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_scalar&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseComplexMatrix (1, 1, v2.scalar_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix m1 = v1.sparse_complex_matrix_value ();
+      Matrix m2 = Matrix (1, 1, v2.scalar_value ());
+      ComplexMatrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_complex_matrix, scalar, mx_el_lt)
+DEFBINOP_FN (le, sparse_complex_matrix, scalar, mx_el_le)
+DEFBINOP_FN (eq, sparse_complex_matrix, scalar, mx_el_eq)
+DEFBINOP_FN (ge, sparse_complex_matrix, scalar, mx_el_ge)
+DEFBINOP_FN (gt, sparse_complex_matrix, scalar, mx_el_gt)
+DEFBINOP_FN (ne, sparse_complex_matrix, scalar, mx_el_ne)
+
+DEFBINOP_OP (el_mul, sparse_complex_matrix, scalar, *)
+
+DEFBINOP (el_div, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_scalar&);
+
+  double d = v2.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_complex_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_pow, sparse_complex_matrix, scalar, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_scalar&);
+
+  return octave_value
+    (x_el_div (v2.double_value (), v1.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_complex_matrix, scalar, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_complex_matrix, scalar, mx_el_or)
+
+DEFCATOP (scm_s, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_scalar&);
+  SparseComplexMatrix tmp (1, 1, v2.complex_value ());
+  return octave_value
+    (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_complex_matrix, scalar)
+{
+  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_scalar&);
+
+  SparseComplexMatrix tmp (1, 1, v2.complex_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_scm_s_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_scalar, div);
+  INSTALL_BINOP (op_pow, octave_sparse_complex_matrix, octave_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_complex_matrix, octave_scalar, ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_complex_matrix, octave_scalar, lt);
+  INSTALL_BINOP (op_le, octave_sparse_complex_matrix, octave_scalar, le);
+  INSTALL_BINOP (op_eq, octave_sparse_complex_matrix, octave_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_complex_matrix, octave_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_complex_matrix, octave_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_complex_matrix, octave_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_complex_matrix, octave_scalar, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_complex_matrix, octave_scalar, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_complex_matrix, octave_scalar, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_complex_matrix, octave_scalar, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_complex_matrix, octave_scalar, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_complex_matrix, octave_scalar, 
+		 el_or);
+
+  INSTALL_CATOP (octave_sparse_complex_matrix, octave_scalar, scm_s);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, octave_scalar, 
+		    assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-scm-scm.cc b/src/OPERATORS/op-scm-scm.cc
new file mode 100644
index 0000000..414f5e7
--- /dev/null
+++ b/src/OPERATORS/op-scm-scm.cc
@@ -0,0 +1,254 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+
+#include "sparse-xdiv.h"
+#include "sparse-xpow.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// unary sparse complex matrix ops.
+
+DEFUNOP_OP (not, sparse_complex_matrix, !)
+DEFUNOP_OP (uplus, sparse_complex_matrix, /* no-op */)
+DEFUNOP_OP (uminus, sparse_complex_matrix, -)
+
+DEFUNOP (transpose, sparse_complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+  return octave_value 
+    (v.sparse_complex_matrix_value().transpose (),
+     v.matrix_type ().transpose ());
+}
+
+DEFUNOP (hermitian, sparse_complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+  return octave_value 
+    (v.sparse_complex_matrix_value().hermitian (),
+     v.matrix_type ().transpose ());
+}
+
+#if 0
+DEFUNOP (incr, sparse_complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+
+  return octave_value (v.complex_matrix_value () .increment ());
+}
+
+DEFUNOP (decr, sparse_complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+
+  return octave_value (v.complex_matrix_value () .decrement ());
+}
+#endif
+
+// complex matrix by complex matrix ops.
+
+DEFBINOP_OP (add, sparse_complex_matrix, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, sparse_complex_matrix, sparse_complex_matrix, -)
+
+DEFBINOP_OP (mul, sparse_complex_matrix, sparse_complex_matrix, *)
+
+DEFBINOP (div, sparse_complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+ 
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = xdiv (v1.sparse_complex_matrix_value (), 
+				      v2.sparse_complex_matrix_value (), typ);
+  
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, sparse_complex_matrix, sparse_complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      SparseComplexMatrix ret = 
+	xleftdiv (v1.sparse_complex_matrix_value (), 
+		  v2.sparse_complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_complex_matrix, sparse_complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_complex_matrix, sparse_complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_complex_matrix, sparse_complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_complex_matrix, sparse_complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_complex_matrix, sparse_complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_complex_matrix, sparse_complex_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_complex_matrix, sparse_complex_matrix, product)
+DEFBINOP_FN (el_div, sparse_complex_matrix, sparse_complex_matrix, quotient)
+DEFBINOP_FN (el_pow, sparse_complex_matrix, sparse_complex_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_sparse_complex_matrix&);
+
+  return octave_value (quotient (v2.sparse_complex_matrix_value (), 
+				 v1.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_complex_matrix, sparse_complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_complex_matrix, sparse_complex_matrix, mx_el_or)
+
+DEFCATOP_FN (scm_scm, sparse_complex_matrix, sparse_complex_matrix, concat)
+
+DEFASSIGNOP_FN (assign, sparse_complex_matrix, sparse_complex_matrix, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, sparse_complex_matrix, delete_elements)
+
+void
+install_scm_scm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_sparse_complex_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_sparse_complex_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_sparse_complex_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_sparse_complex_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_sparse_complex_matrix, hermitian);
+
+#if 0
+  INSTALL_NCUNOP (op_incr, octave_sparse_complex_matrix, incr);
+  INSTALL_NCUNOP (op_decr, octave_sparse_complex_matrix, decr);
+#endif
+
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_sparse_complex_matrix, 
+		 octave_sparse_complex_matrix, scm_scm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, 
+		    octave_sparse_complex_matrix, assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, 
+                    octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, 
+                    octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, 
+                    octave_null_sq_str, null_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-scm-sm.cc b/src/OPERATORS/op-scm-sm.cc
new file mode 100644
index 0000000..c2ac174
--- /dev/null
+++ b/src/OPERATORS/op-scm-sm.cc
@@ -0,0 +1,180 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#include "sparse-xdiv.h"
+#include "sparse-xpow.h"
+#include "smx-sm-scm.h"
+#include "smx-scm-sm.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// sparse complex matrix by sparse matrix ops.
+
+DEFBINOP_OP (add, sparse_complex_matrix, sparse_matrix, +)
+DEFBINOP_OP (sub, sparse_complex_matrix, sparse_matrix, -)
+
+DEFBINOP_OP (mul, sparse_complex_matrix, sparse_matrix, *)
+
+DEFBINOP (div, sparse_complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = xdiv (v1.sparse_complex_matrix_value (), 
+				      v2.sparse_matrix_value (), typ);
+  
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, sparse_complex_matrix, sparse_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_sparse_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      SparseComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
+					  v2.sparse_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_complex_matrix, sparse_matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_complex_matrix, sparse_matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_complex_matrix, sparse_matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_complex_matrix, sparse_matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_complex_matrix, sparse_matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_complex_matrix, sparse_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_complex_matrix, sparse_matrix, product)
+DEFBINOP_FN (el_div, sparse_complex_matrix, sparse_matrix, quotient)
+DEFBINOP_FN (el_pow, sparse_complex_matrix, sparse_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_complex_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
+		   const octave_sparse_matrix&);
+
+  return octave_value
+    (quotient (v2.sparse_matrix_value (), v1.sparse_complex_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_complex_matrix, sparse_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_complex_matrix, sparse_matrix, mx_el_or)
+
+DEFCATOP_FN (scm_sm, sparse_complex_matrix, sparse_matrix, concat)
+
+DEFASSIGNOP_FN (assign, sparse_complex_matrix, sparse_matrix, assign)
+
+void
+install_scm_sm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_complex_matrix, octave_sparse_matrix,
+		 add);
+  INSTALL_BINOP (op_sub, octave_sparse_complex_matrix, octave_sparse_matrix,
+		 sub);
+  INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_sparse_matrix,
+		 mul);
+  INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_sparse_matrix,
+		 div);
+  INSTALL_BINOP (op_pow, octave_sparse_complex_matrix, octave_sparse_matrix,
+		 pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_complex_matrix, octave_sparse_matrix,
+		 ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_complex_matrix, octave_sparse_matrix, 
+		 lt);
+  INSTALL_BINOP (op_le, octave_sparse_complex_matrix, octave_sparse_matrix, 
+		 le);
+  INSTALL_BINOP (op_eq, octave_sparse_complex_matrix, octave_sparse_matrix, 
+		 eq);
+  INSTALL_BINOP (op_ge, octave_sparse_complex_matrix, octave_sparse_matrix, 
+		 ge);
+  INSTALL_BINOP (op_gt, octave_sparse_complex_matrix, octave_sparse_matrix, 
+		 gt);
+  INSTALL_BINOP (op_ne, octave_sparse_complex_matrix, octave_sparse_matrix, 
+		 ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_complex_matrix, 
+		 octave_sparse_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_complex_matrix, 
+		 octave_sparse_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_complex_matrix,
+		 octave_sparse_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_complex_matrix, 
+		 octave_sparse_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_complex_matrix, 
+		 octave_sparse_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_complex_matrix, 
+		 octave_sparse_matrix, el_or);
+
+  INSTALL_CATOP (octave_sparse_complex_matrix, octave_sparse_matrix, scm_sm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_complex_matrix, 
+		    octave_sparse_matrix, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sm-cm.cc b/src/OPERATORS/op-sm-cm.cc
new file mode 100644
index 0000000..674c8a9
--- /dev/null
+++ b/src/OPERATORS/op-sm-cm.cc
@@ -0,0 +1,179 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-cx-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-sm-cm.h"
+#include "smx-cm-sm.h"
+#include "ov-re-sparse.h"
+
+// sparse matrix by complex matrix ops.
+
+DEFBINOP_OP (add, sparse_matrix, complex_matrix, +)
+DEFBINOP_OP (sub, sparse_matrix, complex_matrix, -)
+
+DEFBINOP_OP (mul, sparse_matrix, complex_matrix, *)
+
+DEFBINOP (div, sparse_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, 
+		   const octave_complex_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  ComplexMatrix ret = xdiv (v1.matrix_value (), 
+			    v2.complex_matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, sparse_matrix, complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      ComplexMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
+				    v2.complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_matrix, complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_matrix, complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_matrix, complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_matrix, complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_matrix, complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_matrix, complex_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_matrix, complex_matrix, product)
+DEFBINOP_FN (el_div, sparse_matrix, complex_matrix, quotient)
+
+DEFBINOP (el_pow, sparse_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, 
+		   const octave_complex_matrix&);
+  
+  return octave_value 
+    (elem_xpow (v1.sparse_matrix_value (), SparseComplexMatrix 
+		(v2.complex_matrix_value ())));
+}
+
+DEFBINOP (el_ldiv, sparse_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, 
+		   const octave_complex_matrix&);
+
+  return octave_value 
+    (quotient (v2.complex_matrix_value (), v1.sparse_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_matrix, complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_matrix, complex_matrix, mx_el_or)
+
+DEFCATOP (sm_cm, sparse_matrix, complex_matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_complex_matrix&);
+  SparseComplexMatrix tmp (v2.complex_matrix_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFCONV (sparse_complex_matrix_conv, sparse_matrix, sparse_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_sparse_matrix&);
+  return new octave_complex_matrix (v.complex_matrix_value ());
+}
+
+void
+install_sm_cm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_complex_matrix, add);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_complex_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_complex_matrix, mul);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_complex_matrix, div);
+  INSTALL_BINOP (op_pow, octave_sparse_matrix, octave_complex_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_matrix, octave_complex_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_matrix, octave_complex_matrix, lt);
+  INSTALL_BINOP (op_le, octave_sparse_matrix, octave_complex_matrix, le);
+  INSTALL_BINOP (op_eq, octave_sparse_matrix, octave_complex_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_matrix, octave_complex_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_matrix, octave_complex_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_matrix, octave_complex_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_matrix, octave_complex_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_matrix, octave_complex_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_matrix, octave_complex_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_matrix, octave_complex_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_matrix, octave_complex_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_matrix, octave_complex_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_sparse_matrix, octave_complex_matrix, sm_cm);
+
+  INSTALL_ASSIGNCONV (octave_sparse_matrix, octave_complex_matrix, 
+		      octave_sparse_complex_matrix);
+
+  INSTALL_WIDENOP (octave_sparse_matrix, octave_complex_matrix, 
+		   sparse_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sm-cs.cc b/src/OPERATORS/op-sm-cs.cc
new file mode 100644
index 0000000..6c81f1f
--- /dev/null
+++ b/src/OPERATORS/op-sm-cs.cc
@@ -0,0 +1,171 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-complex.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "smx-sm-cs.h"
+#include "smx-cs-sm.h"
+
+// sparse matrix by scalar ops.
+
+DEFBINOP_OP (add, sparse_matrix, complex, +)
+DEFBINOP_OP (sub, sparse_matrix, complex, -)
+DEFBINOP_OP (mul, sparse_matrix, complex, *)
+
+DEFBINOP (div, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP (pow, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+  return xpow (v1.matrix_value (), v2.complex_value ());
+}
+
+DEFBINOP (ldiv, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseComplexMatrix (1, 1, v2.complex_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseMatrix m1 = v1.sparse_matrix_value ();
+      ComplexMatrix m2 = ComplexMatrix (1, 1, v2.complex_value ());
+      ComplexMatrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_matrix, complex, mx_el_lt)
+DEFBINOP_FN (le, sparse_matrix, complex, mx_el_le)
+DEFBINOP_FN (eq, sparse_matrix, complex, mx_el_eq)
+DEFBINOP_FN (ge, sparse_matrix, complex, mx_el_ge)
+DEFBINOP_FN (gt, sparse_matrix, complex, mx_el_gt)
+DEFBINOP_FN (ne, sparse_matrix, complex, mx_el_ne)
+
+DEFBINOP_OP (el_mul, sparse_matrix, complex, *)
+
+DEFBINOP (el_div, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+
+  Complex d = v2.complex_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_pow, sparse_matrix, complex, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+
+  return octave_value (x_el_div (v2.complex_value (), 
+				 v1.sparse_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_matrix, complex, mx_el_and)
+DEFBINOP_FN (el_or, sparse_matrix, complex, mx_el_or)
+
+DEFCATOP (sm_cs, sparse_matrix, complex)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_complex&);
+  SparseComplexMatrix tmp (1, 1, v2.complex_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+void
+install_sm_cs_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_complex, add);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_complex, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_complex, mul);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_complex, div);
+  INSTALL_BINOP (op_pow, octave_sparse_matrix, octave_complex, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_matrix, octave_complex, ldiv);
+
+  INSTALL_BINOP (op_lt, octave_sparse_matrix, octave_complex, lt);
+  INSTALL_BINOP (op_le, octave_sparse_matrix, octave_complex, le);
+  INSTALL_BINOP (op_eq, octave_sparse_matrix, octave_complex, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_matrix, octave_complex, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_matrix, octave_complex, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_matrix, octave_complex, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_matrix, octave_complex, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_matrix, octave_complex, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_matrix, octave_complex, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_matrix, octave_complex, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_matrix, octave_complex, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_matrix, octave_complex, el_or);
+
+  INSTALL_CATOP (octave_sparse_matrix, octave_complex, sm_cs);
+
+  INSTALL_ASSIGNCONV (octave_sparse_matrix, octave_complex,
+		      octave_sparse_complex_matrix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sm-m.cc b/src/OPERATORS/op-sm-m.cc
new file mode 100644
index 0000000..f907fed
--- /dev/null
+++ b/src/OPERATORS/op-sm-m.cc
@@ -0,0 +1,171 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-re-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "smx-sm-m.h"
+#include "smx-m-sm.h"
+#include "ov-re-sparse.h"
+
+// sparse matrix by matrix ops.
+
+DEFBINOP_OP (add, sparse_matrix, matrix, +)
+DEFBINOP_OP (sub, sparse_matrix, matrix, -)
+
+DEFBINOP_OP (mul, sparse_matrix, matrix, *)
+
+DEFBINOP (div, sparse_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  MatrixType typ = v2.matrix_type ();
+  
+  Matrix ret = xdiv (v1.matrix_value (), v2.matrix_value (), typ);
+
+  v2.matrix_type (typ);
+  return ret;
+}
+
+DEFBINOPX (pow, sparse_matrix, matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      Matrix ret = xleftdiv (v1.sparse_matrix_value (), 
+			     v2.matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (trans_mul, sparse_matrix, matrix, trans_mul);
+
+DEFBINOP_FN (lt, sparse_matrix, matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_matrix, matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_matrix, matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_matrix, matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_matrix, matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_matrix, matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_matrix, matrix, product)
+DEFBINOP_FN (el_div, sparse_matrix, matrix, quotient)
+
+DEFBINOP (el_pow, sparse_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  
+  return octave_value (elem_xpow (v1.sparse_matrix_value (), 
+				  SparseMatrix (v2.matrix_value ())));
+}
+
+DEFBINOP (el_ldiv, sparse_matrix, matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  
+  return octave_value
+    (quotient (v2.matrix_value (), v1.sparse_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_matrix, matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_matrix, matrix, mx_el_or)
+
+DEFCATOP (sm_m, sparse_matrix, matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_matrix&);
+  SparseMatrix tmp (v2.matrix_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_matrix, matrix)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_matrix&);
+
+  SparseMatrix tmp (v2.matrix_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_sm_m_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_matrix, add);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_matrix, mul);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_matrix, div);
+  INSTALL_BINOP (op_pow, octave_sparse_matrix, octave_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_matrix, octave_matrix, ldiv);
+  INSTALL_BINOP (op_trans_mul, octave_sparse_matrix, octave_matrix, trans_mul);
+  INSTALL_BINOP (op_herm_mul, octave_sparse_matrix, octave_matrix, trans_mul);
+  INSTALL_BINOP (op_lt, octave_sparse_matrix, octave_matrix, lt);
+  INSTALL_BINOP (op_le, octave_sparse_matrix, octave_matrix, le);
+  INSTALL_BINOP (op_eq, octave_sparse_matrix, octave_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_matrix, octave_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_matrix, octave_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_matrix, octave_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_matrix, octave_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_matrix, octave_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_matrix, octave_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_matrix, octave_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_matrix, octave_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_matrix, octave_matrix,  el_or);
+
+  INSTALL_CATOP (octave_sparse_matrix, octave_matrix, sm_m);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_matrix, octave_matrix, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sm-s.cc b/src/OPERATORS/op-sm-s.cc
new file mode 100644
index 0000000..338173a
--- /dev/null
+++ b/src/OPERATORS/op-sm-s.cc
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-scalar.h"
+#include "ops.h"
+#include "xpow.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-re-sparse.h"
+
+// sparse matrix by scalar ops.
+
+DEFBINOP_OP (add, sparse_matrix, scalar, +)
+DEFBINOP_OP (sub, sparse_matrix, scalar, -)
+DEFBINOP_OP (mul, sparse_matrix, scalar, *)
+
+DEFBINOP (div, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+
+  double d = v2.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP (pow, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+
+  double tmp = v2.scalar_value ();
+  if (static_cast<int> (tmp) == tmp)
+    return xpow (v1.sparse_matrix_value (), tmp);
+  else
+    return xpow (v1.matrix_value (), tmp);
+}
+
+DEFBINOP (ldiv, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (SparseMatrix(1, 1, v2.scalar_value () / d));
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseMatrix m1 = v1.sparse_matrix_value ();
+      Matrix m2 = Matrix (1, 1, v2.scalar_value ());
+      Matrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_matrix, scalar, mx_el_lt)
+DEFBINOP_FN (le, sparse_matrix, scalar, mx_el_le)
+DEFBINOP_FN (eq, sparse_matrix, scalar, mx_el_eq)
+DEFBINOP_FN (ge, sparse_matrix, scalar, mx_el_ge)
+DEFBINOP_FN (gt, sparse_matrix, scalar, mx_el_gt)
+DEFBINOP_FN (ne, sparse_matrix, scalar, mx_el_ne)
+
+DEFBINOP_OP (el_mul, sparse_matrix, scalar, *)
+
+DEFBINOP (el_div, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+
+  double d = v2.double_value ();
+  octave_value retval;
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  retval = octave_value (v1.sparse_matrix_value () / d);
+
+  return retval;
+}
+
+DEFBINOP_FN (el_pow, sparse_matrix, scalar, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+
+  return octave_value 
+    (x_el_div (v2.complex_value (), v1.sparse_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_matrix, scalar, mx_el_and)
+DEFBINOP_FN (el_or, sparse_matrix, scalar, mx_el_or)
+
+DEFCATOP (sm_s, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_scalar&);
+  SparseMatrix tmp (1, 1, v2.scalar_value ());
+  return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
+}
+
+DEFASSIGNOP (assign, sparse_matrix, scalar)
+{
+  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_scalar&);
+
+  SparseMatrix tmp (1, 1, v2.scalar_value ());
+  v1.assign (idx, tmp);
+  return octave_value ();
+}
+
+void
+install_sm_s_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_scalar, div);
+  INSTALL_BINOP (op_pow, octave_sparse_matrix, octave_scalar, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_matrix, octave_scalar, ldiv);
+
+  INSTALL_BINOP (op_lt, octave_sparse_matrix, octave_scalar, lt);
+  INSTALL_BINOP (op_le, octave_sparse_matrix, octave_scalar, le);
+  INSTALL_BINOP (op_eq, octave_sparse_matrix, octave_scalar, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_matrix, octave_scalar, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_matrix, octave_scalar, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_matrix, octave_scalar, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_matrix, octave_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_matrix, octave_scalar, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_matrix, octave_scalar, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_matrix, octave_scalar, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_matrix, octave_scalar, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_matrix, octave_scalar, el_or);
+
+  INSTALL_CATOP (octave_sparse_matrix, octave_scalar, sm_s);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_matrix, octave_scalar, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sm-scm.cc b/src/OPERATORS/op-sm-scm.cc
new file mode 100644
index 0000000..80af1ce
--- /dev/null
+++ b/src/OPERATORS/op-sm-scm.cc
@@ -0,0 +1,188 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+#include "sparse-xdiv.h"
+#include "sparse-xpow.h"
+#include "smx-sm-scm.h"
+#include "smx-scm-sm.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// sparse matrix by sparse complex matrix ops.
+
+DEFBINOP_OP (add, sparse_matrix, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, sparse_matrix, sparse_complex_matrix, -)
+
+DEFBINOP_OP (mul, sparse_matrix, sparse_complex_matrix, *)
+
+DEFBINOP (div, sparse_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = xdiv (v1.sparse_matrix_value (), 
+				  v2.sparse_complex_matrix_value (), typ);
+  
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, sparse_matrix, sparse_complex_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_complex_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      SparseComplexMatrix ret = 
+	xleftdiv (v1.sparse_matrix_value (), 
+		  v2.sparse_complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_matrix, sparse_complex_matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_matrix, sparse_complex_matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_matrix, sparse_complex_matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_matrix, sparse_complex_matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_matrix, sparse_complex_matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_matrix, sparse_complex_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_matrix, sparse_complex_matrix, product)
+DEFBINOP_FN (el_div, sparse_matrix, sparse_complex_matrix, quotient)
+DEFBINOP_FN (el_pow, sparse_matrix, sparse_complex_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_matrix, sparse_complex_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, 
+		   const octave_sparse_complex_matrix&);
+
+  return octave_value
+    (quotient (v2.sparse_complex_matrix_value (), v1.sparse_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_matrix, sparse_complex_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_matrix, sparse_complex_matrix, mx_el_or)
+
+DEFCATOP_FN (sm_scm, sparse_matrix, sparse_complex_matrix, concat)
+
+DEFCONV (sparse_complex_matrix_conv, sparse_matrix, sparse_complex_matrix)
+{
+  CAST_CONV_ARG (const octave_sparse_matrix&);
+  return new octave_sparse_complex_matrix (v.sparse_complex_matrix_value ());
+}
+
+void
+install_sm_scm_ops (void)
+{
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_sparse_complex_matrix,
+		 add);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_sparse_complex_matrix,
+		 sub);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_sparse_complex_matrix,
+		 mul);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_sparse_complex_matrix,
+		 div);
+  INSTALL_BINOP (op_pow, octave_sparse_matrix, octave_sparse_complex_matrix,
+		 pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_matrix, octave_sparse_complex_matrix,
+		 ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_matrix, octave_sparse_complex_matrix, 
+		 lt);
+  INSTALL_BINOP (op_le, octave_sparse_matrix, octave_sparse_complex_matrix, 
+		 le);
+  INSTALL_BINOP (op_eq, octave_sparse_matrix, octave_sparse_complex_matrix, 
+		 eq);
+  INSTALL_BINOP (op_ge, octave_sparse_matrix, octave_sparse_complex_matrix, 
+		 ge);
+  INSTALL_BINOP (op_gt, octave_sparse_matrix, octave_sparse_complex_matrix, 
+		 gt);
+  INSTALL_BINOP (op_ne, octave_sparse_matrix, octave_sparse_complex_matrix, 
+		 ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_matrix, 
+		 octave_sparse_complex_matrix, el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_matrix, 
+		 octave_sparse_complex_matrix, el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_matrix, 
+		 octave_sparse_complex_matrix, el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_matrix, 
+		 octave_sparse_complex_matrix, el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_matrix, 
+		 octave_sparse_complex_matrix, el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_matrix, 
+		 octave_sparse_complex_matrix, el_or);
+
+  INSTALL_CATOP (octave_sparse_matrix, octave_sparse_complex_matrix, sm_scm);
+
+  INSTALL_ASSIGNCONV (octave_sparse_matrix, octave_sparse_complex_matrix, 
+		      octave_sparse_complex_matrix);
+
+  INSTALL_WIDENOP (octave_sparse_matrix, octave_sparse_complex_matrix, 
+		   sparse_complex_matrix_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-sm-sm.cc b/src/OPERATORS/op-sm-sm.cc
new file mode 100644
index 0000000..b7feaa1
--- /dev/null
+++ b/src/OPERATORS/op-sm-sm.cc
@@ -0,0 +1,202 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-typeinfo.h"
+#include "ov-re-mat.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+
+#include "sparse-xpow.h"
+#include "sparse-xdiv.h"
+#include "ov-re-sparse.h"
+
+// sparse matrix unary ops.
+
+DEFUNOP_OP (not, sparse_matrix, !)
+DEFUNOP_OP (uplus, sparse_matrix, /* no-op */)
+DEFUNOP_OP (uminus, sparse_matrix, -)
+
+DEFUNOP (transpose, sparse_matrix)
+{
+  CAST_UNOP_ARG (const octave_sparse_matrix&);
+  return octave_value (v.sparse_matrix_value().transpose (),
+		       v.matrix_type ().transpose ());
+}
+
+// sparse matrix by sparse matrix ops.
+
+DEFBINOP_OP (add, sparse_matrix, sparse_matrix, +)
+
+// DEFBINOP_OP (sub, sparse_matrix, sparse_matrix, -)
+
+  static octave_value
+  oct_binop_sub (const octave_base_value& a1, const octave_base_value& a2)
+  {
+    const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+    const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+    SparseMatrix m = v1.sparse_matrix_value () - v2.sparse_matrix_value ();
+
+    return octave_value (m);
+  }
+
+DEFBINOP_OP (mul, sparse_matrix, sparse_matrix, *)
+
+DEFBINOP (div, sparse_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseMatrix ret = xdiv (v1.sparse_matrix_value (), 
+			       v2.sparse_matrix_value (), typ);
+  
+      v2.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOPX (pow, sparse_matrix, sparse_matrix)
+{
+  error ("can't do A ^ B for A and B both matrices");
+  return octave_value ();
+}
+
+DEFBINOP (ldiv, sparse_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.double_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v2.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+
+      SparseMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
+				   v2.sparse_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
+}
+
+DEFBINOP_FN (lt, sparse_matrix, sparse_matrix, mx_el_lt)
+DEFBINOP_FN (le, sparse_matrix, sparse_matrix, mx_el_le)
+DEFBINOP_FN (eq, sparse_matrix, sparse_matrix, mx_el_eq)
+DEFBINOP_FN (ge, sparse_matrix, sparse_matrix, mx_el_ge)
+DEFBINOP_FN (gt, sparse_matrix, sparse_matrix, mx_el_gt)
+DEFBINOP_FN (ne, sparse_matrix, sparse_matrix, mx_el_ne)
+
+DEFBINOP_FN (el_mul, sparse_matrix, sparse_matrix, product)
+DEFBINOP_FN (el_div, sparse_matrix, sparse_matrix, quotient)
+
+DEFBINOP_FN (el_pow, sparse_matrix, sparse_matrix, elem_xpow)
+
+DEFBINOP (el_ldiv, sparse_matrix, sparse_matrix)
+{
+  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
+  return octave_value
+    (quotient (v2.sparse_matrix_value (), v1.sparse_matrix_value ()));
+}
+
+DEFBINOP_FN (el_and, sparse_matrix, sparse_matrix, mx_el_and)
+DEFBINOP_FN (el_or,  sparse_matrix, sparse_matrix, mx_el_or)
+
+DEFCATOP_FN (sm_sm, sparse_matrix, sparse_matrix, concat)
+
+DEFASSIGNOP_FN (assign, sparse_matrix, sparse_matrix, assign)
+
+DEFNULLASSIGNOP_FN (null_assign, sparse_matrix, delete_elements)
+
+void
+install_sm_sm_ops (void)
+{
+  INSTALL_UNOP (op_not, octave_sparse_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_sparse_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_sparse_matrix, uminus);
+  INSTALL_UNOP (op_transpose, octave_sparse_matrix, transpose);
+  INSTALL_UNOP (op_hermitian, octave_sparse_matrix, transpose);
+
+  INSTALL_BINOP (op_add, octave_sparse_matrix, octave_sparse_matrix, add);
+  INSTALL_BINOP (op_sub, octave_sparse_matrix, octave_sparse_matrix, sub);
+  INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_sparse_matrix, mul);
+  INSTALL_BINOP (op_div, octave_sparse_matrix, octave_sparse_matrix, div);
+  INSTALL_BINOP (op_pow, octave_sparse_matrix, octave_sparse_matrix, pow);
+  INSTALL_BINOP (op_ldiv, octave_sparse_matrix, octave_sparse_matrix, ldiv);
+  INSTALL_BINOP (op_lt, octave_sparse_matrix, octave_sparse_matrix, lt);
+  INSTALL_BINOP (op_le, octave_sparse_matrix, octave_sparse_matrix, le);
+  INSTALL_BINOP (op_eq, octave_sparse_matrix, octave_sparse_matrix, eq);
+  INSTALL_BINOP (op_ge, octave_sparse_matrix, octave_sparse_matrix, ge);
+  INSTALL_BINOP (op_gt, octave_sparse_matrix, octave_sparse_matrix, gt);
+  INSTALL_BINOP (op_ne, octave_sparse_matrix, octave_sparse_matrix, ne);
+  INSTALL_BINOP (op_el_mul, octave_sparse_matrix, octave_sparse_matrix, 
+		 el_mul);
+  INSTALL_BINOP (op_el_div, octave_sparse_matrix, octave_sparse_matrix, 
+		 el_div);
+  INSTALL_BINOP (op_el_pow, octave_sparse_matrix, octave_sparse_matrix, 
+		 el_pow);
+  INSTALL_BINOP (op_el_ldiv, octave_sparse_matrix, octave_sparse_matrix, 
+		 el_ldiv);
+  INSTALL_BINOP (op_el_and, octave_sparse_matrix, octave_sparse_matrix, 
+		 el_and);
+  INSTALL_BINOP (op_el_or, octave_sparse_matrix, octave_sparse_matrix, 
+		 el_or);
+
+  INSTALL_CATOP (octave_sparse_matrix, octave_sparse_matrix, sm_sm);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_matrix, octave_sparse_matrix, 
+		    assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_matrix, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_matrix, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_sparse_matrix, octave_null_sq_str, null_assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-str-m.cc b/src/OPERATORS/op-str-m.cc
new file mode 100644
index 0000000..c6be695
--- /dev/null
+++ b/src/OPERATORS/op-str-m.cc
@@ -0,0 +1,70 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+DEFASSIGNOP (assign, char_matrix_str, octave_matrix)
+{
+  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_matrix&);
+
+  octave_value tmp
+    = v2.convert_to_str_internal (false, false,
+				  a1.is_sq_string () ? '\'' : '"');
+
+  if (! error_state)
+    v1.assign (idx, tmp.char_matrix_value ());
+
+  return octave_value ();
+}
+
+DEFNDCHARCATOP_FN (str_m, char_matrix_str, matrix, concat)
+
+DEFNDCHARCATOP_FN (m_str, matrix, char_matrix_str, concat)
+
+void
+install_str_m_ops (void)
+{
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_matrix, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_matrix, assign);
+
+  INSTALL_CATOP (octave_char_matrix_str, octave_matrix, str_m);
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_matrix, str_m);
+
+  INSTALL_CATOP (octave_matrix, octave_char_matrix_str, m_str);
+  INSTALL_CATOP (octave_matrix, octave_char_matrix_sq_str, m_str);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-str-s.cc b/src/OPERATORS/op-str-s.cc
new file mode 100644
index 0000000..1114b08
--- /dev/null
+++ b/src/OPERATORS/op-str-s.cc
@@ -0,0 +1,70 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+DEFASSIGNOP (assign, char_matrix_str, octave_scalar)
+{
+  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_scalar&);
+
+  octave_value tmp
+    = v2.convert_to_str_internal (false, false,
+ 				  a1.is_sq_string () ? '\'' : '"');
+
+  if (! error_state)
+    v1.assign (idx, tmp.char_matrix_value ());
+
+  return octave_value ();
+}
+
+DEFNDCHARCATOP_FN (str_s, char_matrix_str, scalar, concat)
+
+DEFNDCHARCATOP_FN (s_str, scalar, char_matrix_str, concat)
+
+void
+install_str_s_ops (void)
+{
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_scalar, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_scalar, assign);
+
+  INSTALL_CATOP (octave_char_matrix_str, octave_scalar, str_s);
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_scalar, str_s);
+
+  INSTALL_CATOP (octave_scalar, octave_char_matrix_str, s_str);
+  INSTALL_CATOP (octave_scalar, octave_char_matrix_sq_str, s_str);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-str-str.cc b/src/OPERATORS/op-str-str.cc
new file mode 100644
index 0000000..c03006f
--- /dev/null
+++ b/src/OPERATORS/op-str-str.cc
@@ -0,0 +1,162 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-str-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+
+// string unary ops.
+
+DEFUNOP (transpose, char_matrix_str)
+{
+  CAST_UNOP_ARG (const octave_char_matrix_str&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.char_matrix_value().transpose (), true,
+			 a.is_sq_string () ? '\'' : '"');
+}
+
+// string by string ops.
+
+#define DEFCHARNDBINOP_FN(name, op, t1, t2, e1, e2, f)	\
+  BINOPDECL (name, a1, a2) \
+  { \
+    dim_vector a1_dims = a1.dims (); \
+    dim_vector a2_dims = a2.dims (); \
+ \
+    bool a1_is_scalar = a1_dims.all_ones (); \
+    bool a2_is_scalar = a2_dims.all_ones (); \
+ \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+ \
+    if (a1_is_scalar) \
+      { \
+	if (a2_is_scalar) \
+	  return octave_value ((v1.e1 ## _value ())(0) op (v2.e2 ## _value ())(0)); \
+	else \
+	  return octave_value (f ((v1.e1 ## _value ())(0), v2.e2 ## _value ())); \
+      } \
+    else \
+      { \
+	if (a2_is_scalar) \
+	  return octave_value (f (v1.e1 ## _value (), (v2.e2 ## _value ())(0))); \
+	else \
+	  return octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \
+      } \
+  }
+
+DEFCHARNDBINOP_FN (lt, <, char_matrix_str, char_matrix_str, char_array, char_array, mx_el_lt)
+DEFCHARNDBINOP_FN (le, <=, char_matrix_str, char_matrix_str, char_array, char_array, mx_el_le)
+DEFCHARNDBINOP_FN (eq, ==, char_matrix_str, char_matrix_str, char_array, char_array, mx_el_eq)
+DEFCHARNDBINOP_FN (ge, >=, char_matrix_str, char_matrix_str, char_array, char_array, mx_el_ge)
+DEFCHARNDBINOP_FN (gt, >, char_matrix_str, char_matrix_str, char_array, char_array, mx_el_gt)
+DEFCHARNDBINOP_FN (ne, !=, char_matrix_str, char_matrix_str, char_array, char_array, mx_el_ne)
+
+DEFASSIGNOP (assign, char_matrix_str, char_matrix_str)
+{
+  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_char_matrix_str&);
+
+  v1.assign (idx, v2.char_matrix_value ());
+  return octave_value ();
+}
+
+DEFNULLASSIGNOP_FN (null_assign, char_matrix_str, delete_elements)
+
+DEFNDCHARCATOP_FN (str_str, char_matrix_str, char_matrix_str, concat)
+
+void
+install_str_str_ops (void)
+{
+  INSTALL_UNOP (op_transpose, octave_char_matrix_str, transpose);
+  INSTALL_UNOP (op_transpose, octave_char_matrix_sq_str, transpose);
+
+  INSTALL_UNOP (op_hermitian, octave_char_matrix_str, transpose);
+  INSTALL_UNOP (op_hermitian, octave_char_matrix_sq_str, transpose);
+
+  INSTALL_BINOP (op_lt, octave_char_matrix_str, octave_char_matrix_str, lt);
+  INSTALL_BINOP (op_lt, octave_char_matrix_str, octave_char_matrix_sq_str, lt);
+  INSTALL_BINOP (op_lt, octave_char_matrix_sq_str, octave_char_matrix_str, lt);
+  INSTALL_BINOP (op_lt, octave_char_matrix_sq_str, octave_char_matrix_sq_str, lt);
+  
+  INSTALL_BINOP (op_le, octave_char_matrix_str, octave_char_matrix_str, le);
+  INSTALL_BINOP (op_le, octave_char_matrix_str, octave_char_matrix_sq_str, le);
+  INSTALL_BINOP (op_le, octave_char_matrix_sq_str, octave_char_matrix_str, le);
+  INSTALL_BINOP (op_le, octave_char_matrix_sq_str, octave_char_matrix_sq_str, le);
+  
+  INSTALL_BINOP (op_eq, octave_char_matrix_str, octave_char_matrix_str, eq);
+  INSTALL_BINOP (op_eq, octave_char_matrix_str, octave_char_matrix_sq_str, eq);
+  INSTALL_BINOP (op_eq, octave_char_matrix_sq_str, octave_char_matrix_str, eq);
+  INSTALL_BINOP (op_eq, octave_char_matrix_sq_str, octave_char_matrix_sq_str, eq);
+  
+  INSTALL_BINOP (op_ge, octave_char_matrix_str, octave_char_matrix_str, ge);
+  INSTALL_BINOP (op_ge, octave_char_matrix_str, octave_char_matrix_sq_str, ge);
+  INSTALL_BINOP (op_ge, octave_char_matrix_sq_str, octave_char_matrix_str, ge);
+  INSTALL_BINOP (op_ge, octave_char_matrix_sq_str, octave_char_matrix_sq_str, ge);
+  
+  INSTALL_BINOP (op_gt, octave_char_matrix_str, octave_char_matrix_str, gt);
+  INSTALL_BINOP (op_gt, octave_char_matrix_str, octave_char_matrix_sq_str, gt);
+  INSTALL_BINOP (op_gt, octave_char_matrix_sq_str, octave_char_matrix_str, gt);
+  INSTALL_BINOP (op_gt, octave_char_matrix_sq_str, octave_char_matrix_sq_str, gt);
+  
+  INSTALL_BINOP (op_ne, octave_char_matrix_str, octave_char_matrix_str, ne);
+  INSTALL_BINOP (op_ne, octave_char_matrix_str, octave_char_matrix_sq_str, ne);
+  INSTALL_BINOP (op_ne, octave_char_matrix_sq_str, octave_char_matrix_str, ne);
+  INSTALL_BINOP (op_ne, octave_char_matrix_sq_str, octave_char_matrix_sq_str, ne);
+
+  INSTALL_CATOP (octave_char_matrix_str, octave_char_matrix_str, str_str);
+  INSTALL_CATOP (octave_char_matrix_str, octave_char_matrix_sq_str, str_str);
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_char_matrix_str, str_str);
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_char_matrix_sq_str, str_str);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_char_matrix_str, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_char_matrix_sq_str, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_char_matrix_str, assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_char_matrix_sq_str, assign);
+
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_null_sq_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_null_matrix, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_null_str, null_assign);
+  INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_sq_str, octave_null_sq_str, null_assign);
+
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-struct.cc b/src/OPERATORS/op-struct.cc
new file mode 100644
index 0000000..db899f8
--- /dev/null
+++ b/src/OPERATORS/op-struct.cc
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-struct.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+
+// struct ops.
+
+DEFUNOP (transpose, cell)
+{
+  CAST_UNOP_ARG (const octave_struct&);
+
+  if (v.ndims () > 2)
+    {
+      error ("transpose not defined for N-d objects");
+      return octave_value ();
+    }
+  else
+    return octave_value (v.map_value().transpose ());
+}
+
+DEFNDCATOP_FN (struct_struct, struct, struct, map, map, concat)
+
+static octave_value
+oct_catop_struct_matrix (octave_base_value& a1, const octave_base_value& a2,
+			 const Array<octave_idx_type>&)
+{
+  octave_value retval;
+  CAST_BINOP_ARGS (const octave_struct&, const octave_matrix&);
+  NDArray tmp = v2.array_value ();
+  dim_vector dv = tmp.dims ();
+  if (dv.all_zero ())
+    retval = octave_value (v1.map_value ());
+  else
+    error ("invalid concatenation of structure with matrix");
+  return retval;
+}
+
+static octave_value
+oct_catop_matrix_struct (octave_base_value& a1, const octave_base_value& a2,
+			 const Array<octave_idx_type>&)
+{
+  octave_value retval;
+  CAST_BINOP_ARGS (const octave_matrix&, const octave_struct&);
+  NDArray tmp = v1.array_value ();
+  dim_vector dv = tmp.dims ();
+  if (dv.all_zero ())
+    retval = octave_value (v2.map_value ());
+  else
+    error ("invalid concatenation of structure with matrix");
+  return retval;
+}
+
+void
+install_struct_ops (void)
+{
+  INSTALL_UNOP (op_transpose, octave_struct, transpose);
+  INSTALL_UNOP (op_hermitian, octave_struct, transpose);
+
+  INSTALL_CATOP (octave_struct, octave_struct, struct_struct);
+  INSTALL_CATOP (octave_struct, octave_matrix, struct_matrix);
+  INSTALL_CATOP (octave_matrix, octave_struct, matrix_struct);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-ui16-ui16.cc b/src/OPERATORS/op-ui16-ui16.cc
new file mode 100644
index 0000000..6358f49
--- /dev/null
+++ b/src/OPERATORS/op-ui16-ui16.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-ui16nda-i8.h"
+#include "mx-ui16nda-ui8.h"
+#include "mx-ui16nda-i16.h"
+#include "mx-ui16nda-i32.h"
+#include "mx-ui16nda-ui32.h"
+#include "mx-ui16nda-i64.h"
+#include "mx-ui16nda-ui64.h"
+
+#include "mx-ui16nda-i8nda.h"
+#include "mx-ui16nda-ui8nda.h"
+#include "mx-ui16nda-i16nda.h"
+#include "mx-ui16nda-i32nda.h"
+#include "mx-ui16nda-ui32nda.h"
+#include "mx-ui16nda-i64nda.h"
+#include "mx-ui16nda-ui64nda.h"
+
+#include "mx-ui16-i8nda.h"
+#include "mx-ui16-ui8nda.h"
+#include "mx-ui16-i16nda.h"
+#include "mx-ui16-i32nda.h"
+#include "mx-ui16-ui32nda.h"
+#include "mx-ui16-i64nda.h"
+#include "mx-ui16-ui64nda.h"
+
+#include "mx-ui16nda-s.h"
+#include "mx-s-ui16nda.h"
+
+#include "mx-ui16nda-nda.h"
+#include "mx-nda-ui16nda.h"
+
+#include "mx-ui16-nda.h"
+#include "mx-nda-ui16.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (uint16)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, uint16_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, uint16_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, uint16_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, uint16_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, uint16_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, uint16_, int64_, int64_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, uint16_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, uint16_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, uint16_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, uint16_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, uint16_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, uint16_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, uint16_, int64_, int64_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, uint16_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (uint16, int8)
+OCTAVE_MIXED_INT_CMP_OPS (uint16, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (uint16, int16)
+OCTAVE_MIXED_INT_CMP_OPS (uint16, int32)
+OCTAVE_MIXED_INT_CMP_OPS (uint16, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (uint16, int64)
+OCTAVE_MIXED_INT_CMP_OPS (uint16, uint64)
+
+void
+install_ui16_ui16_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (uint16);
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, uint16_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, uint16_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, uint16_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, uint16_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, uint16_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, uint16_, int64_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, uint16_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, uint16_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, uint16_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, uint16_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, uint16_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, uint16_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, uint16_, int64_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, uint16_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, int64);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint16, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, int64);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint16, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-ui32-ui32.cc b/src/OPERATORS/op-ui32-ui32.cc
new file mode 100644
index 0000000..f1e217e
--- /dev/null
+++ b/src/OPERATORS/op-ui32-ui32.cc
@@ -0,0 +1,154 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-ui32nda-i8.h"
+#include "mx-ui32nda-ui8.h"
+#include "mx-ui32nda-i16.h"
+#include "mx-ui32nda-ui16.h"
+#include "mx-ui32nda-i32.h"
+#include "mx-ui32nda-i64.h"
+#include "mx-ui32nda-ui64.h"
+
+#include "mx-ui32nda-i8nda.h"
+#include "mx-ui32nda-ui8nda.h"
+#include "mx-ui32nda-i16nda.h"
+#include "mx-ui32nda-ui16nda.h"
+#include "mx-ui32nda-i32nda.h"
+#include "mx-ui32nda-i64nda.h"
+#include "mx-ui32nda-ui64nda.h"
+
+#include "mx-ui32-i8nda.h"
+#include "mx-ui32-ui8nda.h"
+#include "mx-ui32-i16nda.h"
+#include "mx-ui32-ui16nda.h"
+#include "mx-ui32-i32nda.h"
+#include "mx-ui32-i64nda.h"
+#include "mx-ui32-ui64nda.h"
+
+#include "mx-ui32nda-s.h"
+#include "mx-s-ui32nda.h"
+
+#include "mx-ui32nda-nda.h"
+#include "mx-nda-ui32nda.h"
+
+#include "mx-ui32-nda.h"
+#include "mx-nda-ui32.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (uint32)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, uint32_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, uint32_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, uint32_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, uint32_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, uint32_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, uint32_, int64_, int64_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, uint32_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, uint32_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, uint32_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, uint32_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, uint32_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, uint32_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, uint32_, int64_, int64_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, uint32_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (uint32, int8)
+OCTAVE_MIXED_INT_CMP_OPS (uint32, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (uint32, int16)
+OCTAVE_MIXED_INT_CMP_OPS (uint32, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (uint32, int32)
+OCTAVE_MIXED_INT_CMP_OPS (uint32, int64)
+OCTAVE_MIXED_INT_CMP_OPS (uint32, uint64)
+void
+install_ui32_ui32_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (uint32);
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, uint32_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, uint32_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, uint32_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, uint32_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, uint32_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, uint32_, int64_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, uint32_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, uint32_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, uint32_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, uint32_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, uint32_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, uint32_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, uint32_, int64_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, uint32_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, int64);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint32, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, int64);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint32, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-ui64-ui64.cc b/src/OPERATORS/op-ui64-ui64.cc
new file mode 100644
index 0000000..187efad
--- /dev/null
+++ b/src/OPERATORS/op-ui64-ui64.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-ui64nda-i8.h"
+#include "mx-ui64nda-ui8.h"
+#include "mx-ui64nda-i16.h"
+#include "mx-ui64nda-ui16.h"
+#include "mx-ui64nda-i32.h"
+#include "mx-ui64nda-ui32.h"
+#include "mx-ui64nda-i64.h"
+
+#include "mx-ui64nda-i8nda.h"
+#include "mx-ui64nda-ui8nda.h"
+#include "mx-ui64nda-i16nda.h"
+#include "mx-ui64nda-ui16nda.h"
+#include "mx-ui64nda-i32nda.h"
+#include "mx-ui64nda-ui32nda.h"
+#include "mx-ui64nda-i64nda.h"
+
+#include "mx-ui64-i8nda.h"
+#include "mx-ui64-ui8nda.h"
+#include "mx-ui64-i16nda.h"
+#include "mx-ui64-ui16nda.h"
+#include "mx-ui64-i32nda.h"
+#include "mx-ui64-ui32nda.h"
+#include "mx-ui64-i64nda.h"
+
+#include "mx-ui64nda-s.h"
+#include "mx-s-ui64nda.h"
+
+#include "mx-ui64nda-nda.h"
+#include "mx-nda-ui64nda.h"
+
+#include "mx-ui64-nda.h"
+#include "mx-nda-ui64.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (uint64)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, uint64_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui8, uint64_, uint8_, uint8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, uint64_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, uint64_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, uint64_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, uint64_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, uint64_, int64_, int64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, uint64_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui8, uint64_, uint8_, uint8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, uint64_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, uint64_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, uint64_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, uint64_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, uint64_, int64_, int64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (uint64, int8)
+OCTAVE_MIXED_INT_CMP_OPS (uint64, uint8)
+OCTAVE_MIXED_INT_CMP_OPS (uint64, int16)
+OCTAVE_MIXED_INT_CMP_OPS (uint64, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (uint64, int32)
+OCTAVE_MIXED_INT_CMP_OPS (uint64, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (uint64, int64)
+
+void
+install_ui64_ui64_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (uint64);
+  
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, uint64_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui8, uint64_, uint8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, uint64_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, uint64_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, uint64_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, uint64_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, uint64_, int64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, uint64_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui8, uint64_, uint8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, uint64_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, uint64_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, uint64_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, uint64_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, uint64_, int64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, uint8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint64, int64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, uint8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint64, int64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/OPERATORS/op-ui8-ui8.cc b/src/OPERATORS/op-ui8-ui8.cc
new file mode 100644
index 0000000..97aa560
--- /dev/null
+++ b/src/OPERATORS/op-ui8-ui8.cc
@@ -0,0 +1,155 @@
+/*
+
+Copyright (C) 1996, 1997, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mx-ui8nda-i8.h"
+#include "mx-ui8nda-i16.h"
+#include "mx-ui8nda-ui16.h"
+#include "mx-ui8nda-i32.h"
+#include "mx-ui8nda-ui32.h"
+#include "mx-ui8nda-i64.h"
+#include "mx-ui8nda-ui64.h"
+
+#include "mx-ui8nda-i8nda.h"
+#include "mx-ui8nda-i16nda.h"
+#include "mx-ui8nda-ui16nda.h"
+#include "mx-ui8nda-i32nda.h"
+#include "mx-ui8nda-ui32nda.h"
+#include "mx-ui8nda-i64nda.h"
+#include "mx-ui8nda-ui64nda.h"
+
+#include "mx-ui8-i8nda.h"
+#include "mx-ui8-i16nda.h"
+#include "mx-ui8-ui16nda.h"
+#include "mx-ui8-i32nda.h"
+#include "mx-ui8-ui32nda.h"
+#include "mx-ui8-i64nda.h"
+#include "mx-ui8-ui64nda.h"
+
+#include "mx-ui8nda-s.h"
+#include "mx-s-ui8nda.h"
+
+#include "mx-ui8nda-nda.h"
+#include "mx-nda-ui8nda.h"
+
+#include "mx-ui8-nda.h"
+#include "mx-nda-ui8.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-int8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-uint8.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+#include "op-int.h"
+
+OCTAVE_INT_OPS (uint8)
+
+OCTAVE_MS_INT_ASSIGN_OPS (mi8, uint8_, int8_, int8_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi16, uint8_, int16_, int16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui16, uint8_, uint16_, uint16_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi32, uint8_, int32_, int32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui32, uint8_, uint32_, uint32_)
+OCTAVE_MS_INT_ASSIGN_OPS (mi64, uint8_, int64_, int64_)
+OCTAVE_MS_INT_ASSIGN_OPS (mui64, uint8_, uint64_, uint64_)
+
+OCTAVE_MM_INT_ASSIGN_OPS (mmi8, uint8_, int8_, int8_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi16, uint8_, int16_, int16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui16, uint8_, uint16_, uint16_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi32, uint8_, int32_, int32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui32, uint8_, uint32_, uint32_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmi64, uint8_, int64_, int64_)
+OCTAVE_MM_INT_ASSIGN_OPS (mmui64, uint8_, uint64_, uint64_)
+
+OCTAVE_MIXED_INT_CMP_OPS (uint8, int8)
+OCTAVE_MIXED_INT_CMP_OPS (uint8, int16)
+OCTAVE_MIXED_INT_CMP_OPS (uint8, uint16)
+OCTAVE_MIXED_INT_CMP_OPS (uint8, int32)
+OCTAVE_MIXED_INT_CMP_OPS (uint8, uint32)
+OCTAVE_MIXED_INT_CMP_OPS (uint8, int64)
+OCTAVE_MIXED_INT_CMP_OPS (uint8, uint64)
+
+void
+install_ui8_ui8_ops (void)
+{
+  OCTAVE_INSTALL_INT_OPS (uint8)
+
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi8, uint8_, int8_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi16, uint8_, int16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui16, uint8_, uint16_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi32, uint8_, int32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui32, uint8_, uint32_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mi64, uint8_, int64_);
+  OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mui64, uint8_, uint64_);
+
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi8, uint8_, int8_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi16, uint8_, int16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui16, uint8_, uint16_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi32, uint8_, int32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui32, uint8_, uint32_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmi64, uint8_, int64_);
+  OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmui64, uint8_, uint64_);
+
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, int8);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, int16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, uint16);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, int32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, uint32);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, int64);
+  OCTAVE_INSTALL_SM_INT_ASSIGNCONV (uint8, uint64);
+
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, int8);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, int16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, uint16);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, int32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, uint32);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, int64);
+  OCTAVE_INSTALL_MIXED_INT_CMP_OPS (uint8, uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/Quad-opts.cc b/src/Quad-opts.cc
new file mode 100644
index 0000000..5a7ec14
--- /dev/null
+++ b/src/Quad-opts.cc
@@ -0,0 +1,256 @@
+// DO NOT EDIT!
+// Generated automatically from ../liboctave/Quad-opts.in.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include "Quad-opts.h"
+
+#include "defun-dld.h"
+#include "pr-output.h"
+
+#include "oct-obj.h"
+#include "utils.h"
+#include "pager.h"
+
+static Quad_options quad_opts;
+
+#define MAX_TOKENS 4
+
+struct Quad_options_struct
+{
+  const char *keyword;
+  const char *kw_tok[MAX_TOKENS + 1];
+  int min_len[MAX_TOKENS + 1];
+  int min_toks_to_match;
+};
+
+#define NUM_OPTIONS 4
+
+static Quad_options_struct Quad_options_table [] =
+{
+  { "absolute tolerance",
+    { "absolute", "tolerance", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "relative tolerance",
+    { "relative", "tolerance", 0, 0, 0, },
+    { 1, 0, 0, 0, 0, }, 1, },
+
+  { "single precision absolute tolerance",
+    { "single", "precision", "absolute", "tolerance", 0, },
+    { 1, 1, 1, 0, 0, }, 3, },
+
+  { "single precision relative tolerance",
+    { "single", "precision", "relative", "tolerance", 0, },
+    { 1, 1, 1, 0, 0, }, 3, },
+};
+
+static void
+print_Quad_options (std::ostream& os)
+{
+  std::ostringstream buf;
+
+  os << "\n"
+     << "Options for Quad include:\n\n"
+     << "  keyword                                             value\n"
+     << "  -------                                             -----\n";
+
+  Quad_options_struct *list = Quad_options_table;
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[0].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = quad_opts.absolute_tolerance ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[1].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    double val = quad_opts.relative_tolerance ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[2].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    float val = quad_opts.single_precision_absolute_tolerance ();
+
+    os << val << "\n";
+  }
+
+  {
+    os << "  "
+        << std::setiosflags (std::ios::left) << std::setw (50)
+        << list[3].keyword
+        << std::resetiosflags (std::ios::left)
+        << "  ";
+
+    float val = quad_opts.single_precision_relative_tolerance ();
+
+    os << val << "\n";
+  }
+
+  os << "\n";
+}
+
+static void
+set_Quad_options (const std::string& keyword, const octave_value& val)
+{
+  Quad_options_struct *list = Quad_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        quad_opts.set_absolute_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      double tmp = val.double_value ();
+
+      if (! error_state)
+        quad_opts.set_relative_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      float tmp = val.float_value ();
+
+      if (! error_state)
+        quad_opts.set_single_precision_absolute_tolerance (tmp);
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      float tmp = val.float_value ();
+
+      if (! error_state)
+        quad_opts.set_single_precision_relative_tolerance (tmp);
+    }
+  else
+    {
+      warning ("quad_options: no match for `%s'", keyword.c_str ());
+    }
+}
+
+static octave_value_list
+show_Quad_options (const std::string& keyword)
+{
+  octave_value retval;
+
+  Quad_options_struct *list = Quad_options_table;
+
+  if (keyword_almost_match (list[0].kw_tok, list[0].min_len,
+           keyword, list[0].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = quad_opts.absolute_tolerance ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[1].kw_tok, list[1].min_len,
+           keyword, list[1].min_toks_to_match, MAX_TOKENS))
+    {
+      double val = quad_opts.relative_tolerance ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[2].kw_tok, list[2].min_len,
+           keyword, list[2].min_toks_to_match, MAX_TOKENS))
+    {
+      float val = quad_opts.single_precision_absolute_tolerance ();
+
+      retval = val;
+    }
+  else if (keyword_almost_match (list[3].kw_tok, list[3].min_len,
+           keyword, list[3].min_toks_to_match, MAX_TOKENS))
+    {
+      float val = quad_opts.single_precision_relative_tolerance ();
+
+      retval = val;
+    }
+  else
+    {
+      warning ("quad_options: no match for `%s'", keyword.c_str ());
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (quad_options, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} quad_options (@var{opt}, @var{val})\n\
+When called with two arguments, this function\n\
+allows you set options parameters for the function @code{quad}.\n\
+Given one argument, @code{quad_options} returns the value of the\n\
+corresponding option.  If no arguments are supplied, the names of all\n\
+the available options and their current values are displayed.\n\
+\n\
+Options include\n\
+\n\
+ at table @code\n\
+ at item \"absolute tolerance\"\n\
+Absolute tolerance; may be zero for pure relative error test.\n\
+ at item \"relative tolerance\"\n\
+Nonnegative relative tolerance.  If the absolute tolerance is zero,\n\
+the relative tolerance must be greater than or equal to \n\
+ at code{max (50*eps, 0.5e-28)}.\n\
+ at item \"single precision absolute tolerance\"\n\
+Absolute tolerance for single precision; may be zero for pure relative \n\
+error test.\n\
+ at item \"single precision relative tolerance\"\n\
+Nonnegative relative tolerance for single precision.  If the absolute\n\
+tolerance is zero, the relative tolerance must be greater than or equal to \n\
+ at code{max (50*eps, 0.5e-28)}.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      print_Quad_options (octave_stdout);
+    }
+  else if (nargin == 1 || nargin == 2)
+    {
+      std::string keyword = args(0).string_value ();
+
+      if (! error_state)
+        {
+          if (nargin == 1)
+            retval = show_Quad_options (keyword);
+          else
+            set_Quad_options (keyword, args(1));
+        }
+      else
+        error ("quad_options: expecting keyword as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
diff --git a/src/TEMPLATE-INST/Array-os.cc b/src/TEMPLATE-INST/Array-os.cc
new file mode 100644
index 0000000..0b4fd95
--- /dev/null
+++ b/src/TEMPLATE-INST/Array-os.cc
@@ -0,0 +1,53 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2003, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Instantiate Arrays of octave_stream objects.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array.h"
+#include "Array.cc"
+
+extern template class OCTAVE_API Array<bool>;
+extern template class OCTAVE_API Array<octave_idx_type>;
+
+#include "oct-stream.h"
+
+typedef scanf_format_elt* scanf_format_elt_ptr;
+typedef printf_format_elt* printf_format_elt_ptr;
+
+NO_INSTANTIATE_ARRAY_SORT (scanf_format_elt_ptr);
+INSTANTIATE_ARRAY (scanf_format_elt_ptr, OCTINTERP_API);
+
+NO_INSTANTIATE_ARRAY_SORT (printf_format_elt_ptr);
+INSTANTIATE_ARRAY (printf_format_elt_ptr, OCTINTERP_API);
+
+NO_INSTANTIATE_ARRAY_SORT (octave_stream);
+INSTANTIATE_ARRAY (octave_stream, OCTINTERP_API);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/TEMPLATE-INST/Array-tc.cc b/src/TEMPLATE-INST/Array-tc.cc
new file mode 100644
index 0000000..3a62aca
--- /dev/null
+++ b/src/TEMPLATE-INST/Array-tc.cc
@@ -0,0 +1,54 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Instantiate Arrays of octave_values.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array.h"
+#include "Array.cc"
+
+#include "Array2.h"
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+#include "ov.h"
+
+#include "oct-sort.cc"
+
+NO_INSTANTIATE_ARRAY_SORT (octave_value);
+
+INSTANTIATE_ARRAY (octave_value, OCTINTERP_API);
+
+template class OCTINTERP_API Array2<octave_value>;
+
+template class OCTINTERP_API ArrayN<octave_value>;
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/base-list.h b/src/base-list.h
new file mode 100644
index 0000000..b387226
--- /dev/null
+++ b/src/base-list.h
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 2002, 2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_list_h)
+#define octave_base_list_h 1
+
+#include <list>
+
+template <typename elt_type>
+class
+octave_base_list
+{
+public:
+
+  typedef typename std::list<elt_type>::iterator iterator;
+  typedef typename std::list<elt_type>::const_iterator const_iterator;
+
+  bool empty (void) const { return lst.empty (); }
+
+  size_t length (void) const { return lst.size (); }
+
+  iterator erase (iterator pos) { return lst.erase (pos); }
+
+  template <class P>
+  void remove_if (P pred)
+  {
+    // We would like to simply call
+    //
+    //   lst.remove_if (pred);
+    //
+    // but the Sun Studio compiler chokes on that.
+    //
+    // FIXME -- this kluge should be removed at some point.
+
+    iterator b = lst.begin ();
+    iterator e = lst.end ();
+    while (b != e)
+      {
+	iterator n = b;
+	n++;
+	if (pred (*b))
+	  lst.erase (b);
+	b = n;
+      }
+  }
+
+  void clear (void) { lst.clear (); }
+
+  iterator begin (void) { return iterator (lst.begin ()); }
+  const_iterator begin (void) const { return const_iterator (lst.begin ()); }
+
+  iterator end (void) { return iterator (lst.end ()); }
+  const_iterator end (void) const { return const_iterator (lst.end ()); }
+
+  elt_type& front (void) { return lst.front (); }
+  elt_type& back (void) { return lst.back (); }
+
+  const elt_type& front (void) const { return lst.front (); }
+  const elt_type& back (void) const { return lst.back (); }
+
+  void push_front (const elt_type& s) { lst.push_front (s); }
+  void push_back (const elt_type& s) { lst.push_back (s); }
+
+  void pop_front (void) { lst.pop_front (); }
+  void pop_back (void) { lst.pop_back (); }
+
+  // For backward compatibility.
+  void append (const elt_type& s) { lst.push_back (s); }
+
+private:
+
+  std::list<elt_type> lst;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/bitfcns.cc b/src/bitfcns.cc
new file mode 100644
index 0000000..0a341d6
--- /dev/null
+++ b/src/bitfcns.cc
@@ -0,0 +1,660 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "str-vec.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "error.h"
+#include "ov.h"
+#include "ov-uint64.h"
+#include "ov-uint32.h"
+#include "ov-uint16.h"
+#include "ov-uint8.h"
+#include "ov-int64.h"
+#include "ov-int32.h"
+#include "ov-int16.h"
+#include "ov-int8.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-bool.h"
+
+// FIXME -- could probably eliminate some code duplication by
+// clever use of templates.
+
+#define BITOPX(OP, FNAME, RET) \
+      { \
+	int nelx = x.numel (); \
+	int nely = y.numel (); \
+ \
+	bool is_scalar_op = (nelx == 1 || nely == 1); \
+ \
+	dim_vector dvx = x.dims (); \
+	dim_vector dvy = y.dims (); \
+ \
+	bool is_array_op = (dvx == dvy); \
+ \
+	if (is_array_op || is_scalar_op) \
+	  { \
+	    RET result; \
+ \
+	    if (nelx != 1) \
+	      result.resize (dvx); \
+	    else \
+	      result.resize (dvy); \
+ \
+	    for (int i = 0; i < nelx; i++) \
+	      if (is_scalar_op) \
+		for (int k = 0; k < nely; k++) \
+		  result(i+k) = x(i) OP y(k); \
+	      else \
+		result(i) = x(i) OP y(i); \
+ \
+	      retval = result; \
+	  } \
+	else \
+	  error ("%s: size of x and y must match, or one operand must be a scalar", FNAME); \
+      }
+
+#define BITOP(OP, FNAME) \
+ \
+  octave_value retval; \
+ \
+  int nargin = args.length (); \
+ \
+  if (nargin == 2) \
+    { \
+      if ((args(0).class_name () == octave_scalar::static_class_name ()) \
+	  || (args(0).class_name () == octave_bool::static_class_name ()) \
+	  || (args(1).class_name () == octave_scalar::static_class_name ()) \
+	  || (args(1).class_name () == octave_bool::static_class_name ())) \
+	{ \
+	  bool arg0_is_int = (args(0).class_name () !=	\
+			      octave_scalar::static_class_name () && \
+			      args(0).class_name () != \
+			      octave_bool::static_class_name ()); \
+	  bool arg1_is_int = (args(1).class_name () !=	\
+			      octave_scalar::static_class_name () && \
+			      args(1).class_name () != \
+			      octave_bool::static_class_name ()); \
+	  \
+	  if (! (arg0_is_int || arg1_is_int))	\
+	    { \
+	      uint64NDArray x (args(0).array_value ()); \
+	      uint64NDArray y (args(1).array_value ());	\
+	      if (! error_state) \
+		BITOPX (OP, FNAME, uint64NDArray); \
+	      retval = retval.array_value (); \
+	    } \
+	  else \
+	    { \
+	      int p = (arg0_is_int ? 1 : 0); \
+	      int q = (arg0_is_int ? 0 : 1); \
+ \
+	      NDArray dx = args(p).array_value (); \
+ \
+	      if (args(q).type_id () == octave_uint64_matrix::static_type_id () \
+		  || args(q).type_id () == octave_uint64_scalar::static_type_id ()) \
+		{ \
+		  uint64NDArray x (dx); \
+		  uint64NDArray y = args(q).uint64_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, uint64NDArray); \
+		 } \
+	      else if (args(q).type_id () == octave_uint32_matrix::static_type_id () \
+		       || args(q).type_id () == octave_uint32_scalar::static_type_id ()) \
+		{ \
+		  uint32NDArray x (dx); \
+		  uint32NDArray y = args(q).uint32_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, uint32NDArray); \
+		} \
+	      else if (args(q).type_id () == octave_uint16_matrix::static_type_id () \
+		       || args(q).type_id () == octave_uint16_scalar::static_type_id ()) \
+		{ \
+		  uint16NDArray x (dx); \
+		  uint16NDArray y = args(q).uint16_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, uint16NDArray); \
+		} \
+	      else if (args(q).type_id () == octave_uint8_matrix::static_type_id () \
+		       || args(q).type_id () == octave_uint8_scalar::static_type_id ()) \
+		{ \
+		  uint8NDArray x (dx); \
+		  uint8NDArray y = args(q).uint8_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, uint8NDArray); \
+		} \
+	      else if (args(q).type_id () == octave_int64_matrix::static_type_id () \
+		       || args(q).type_id () == octave_int64_scalar::static_type_id ()) \
+		{ \
+		  int64NDArray x (dx); \
+		  int64NDArray y = args(q).int64_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, int64NDArray); \
+		} \
+	      else if (args(q).type_id () == octave_int32_matrix::static_type_id () \
+		       || args(q).type_id () == octave_int32_scalar::static_type_id ()) \
+		{ \
+		  int32NDArray x (dx); \
+		  int32NDArray y = args(q).int32_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, int32NDArray); \
+		} \
+	      else if (args(q).type_id () == octave_int16_matrix::static_type_id () \
+		       || args(q).type_id () == octave_int16_scalar::static_type_id ()) \
+		{ \
+		  int16NDArray x (dx); \
+		  int16NDArray y = args(q).int16_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, int16NDArray); \
+		} \
+	      else if (args(q).type_id () == octave_int8_matrix::static_type_id () \
+		       || args(q).type_id () == octave_int8_scalar::static_type_id ()) \
+		{ \
+		  int8NDArray x (dx); \
+		  int8NDArray y = args(q).int8_array_value (); \
+		  if (! error_state) \
+		    BITOPX (OP, FNAME, int8NDArray); \
+		} \
+	      else \
+		error ("%s: invalid operand type", FNAME); \
+	    } \
+	} \
+      else if (args(0).class_name () == args(1).class_name ()) \
+	{ \
+	  if (args(0).type_id () == octave_uint64_matrix::static_type_id () \
+	      || args(0).type_id () == octave_uint64_scalar::static_type_id ()) \
+	    { \
+	      uint64NDArray x = args(0).uint64_array_value (); \
+	      uint64NDArray y = args(1).uint64_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, uint64NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_uint32_matrix::static_type_id () \
+		   || args(0).type_id () == octave_uint32_scalar::static_type_id ()) \
+	    { \
+	      uint32NDArray x = args(0).uint32_array_value (); \
+	      uint32NDArray y = args(1).uint32_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, uint32NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_uint16_matrix::static_type_id () \
+		   || args(0).type_id () == octave_uint16_scalar::static_type_id ()) \
+	    { \
+	      uint16NDArray x = args(0).uint16_array_value (); \
+	      uint16NDArray y = args(1).uint16_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, uint16NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_uint8_matrix::static_type_id () \
+		   || args(0).type_id () == octave_uint8_scalar::static_type_id ()) \
+	    { \
+	      uint8NDArray x = args(0).uint8_array_value (); \
+	      uint8NDArray y = args(1).uint8_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, uint8NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_int64_matrix::static_type_id () \
+		   || args(0).type_id () == octave_int64_scalar::static_type_id ()) \
+	    { \
+	      int64NDArray x = args(0).int64_array_value (); \
+	      int64NDArray y = args(1).int64_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, int64NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_int32_matrix::static_type_id () \
+		   || args(0).type_id () == octave_int32_scalar::static_type_id ()) \
+	    { \
+	      int32NDArray x = args(0).int32_array_value (); \
+	      int32NDArray y = args(1).int32_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, int32NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_int16_matrix::static_type_id () \
+		   || args(0).type_id () == octave_int16_scalar::static_type_id ()) \
+	    { \
+	      int16NDArray x = args(0).int16_array_value (); \
+	      int16NDArray y = args(1).int16_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, int16NDArray); \
+	    } \
+	  else if (args(0).type_id () == octave_int8_matrix::static_type_id () \
+		   || args(0).type_id () == octave_int8_scalar::static_type_id ()) \
+	    { \
+	      int8NDArray x = args(0).int8_array_value (); \
+	      int8NDArray y = args(1).int8_array_value (); \
+	      if (! error_state) \
+		BITOPX (OP, FNAME, int8NDArray); \
+	    } \
+	  else \
+	    error ("%s: invalid operand type", FNAME); \
+	} \
+      else \
+	error ("%s: must have matching operand types", FNAME); \
+    } \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+DEFUN (bitand, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})\n\
+Return the bitwise AND of non-negative integers.\n\
+ at var{x}, @var{y} must be in the range [0,bitmax]\n\
+ at seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\
+ at end deftypefn")
+{
+  BITOP (&, "bitand");
+}
+
+DEFUN (bitor, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})\n\
+Return the bitwise OR of non-negative integers.\n\
+ at var{x}, @var{y} must be in the range [0,bitmax]\n\
+ at seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\
+ at end deftypefn")
+{
+  BITOP (|, "bitor");
+}
+
+DEFUN (bitxor, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})\n\
+Return the bitwise XOR of non-negative integers.\n\
+ at var{x}, @var{y} must be in the range [0,bitmax]\n\
+ at seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}\n\
+ at end deftypefn")
+{
+  BITOP (^, "bitxor");
+}
+
+static int64_t
+bitshift (double a, int n, int64_t mask)
+{
+  // In the name of bug-for-bug compatibility.
+  if (a < 0)
+    return -bitshift (-a, n, mask);
+
+  if (n > 0)
+    return (static_cast<int64_t> (a) << n) & mask;
+  else if (n < 0)
+    return (static_cast<int64_t> (a) >> -n) & mask;
+  else
+    return static_cast<int64_t> (a) & mask;
+}
+
+static int64_t
+bitshift (float a, int n, int64_t mask)
+{
+  // In the name of bug-for-bug compatibility.
+  if (a < 0)
+    return -bitshift (-a, n, mask);
+
+  if (n > 0)
+    return (static_cast<int64_t> (a) << n) & mask;
+  else if (n < 0)
+    return (static_cast<int64_t> (a) >> -n) & mask;
+  else
+    return static_cast<int64_t> (a) & mask;
+}
+
+// Note that the bitshift operators are undefined if shifted by more
+// bits than in the type, so we need to test for the size of the
+// shift.
+
+#define DO_BITSHIFT(T) \
+  if (! error_state) \
+    { \
+      double d1, d2; \
+ \
+      if (n.all_integers (d1, d2)) \
+	{ \
+	  int m_nel = m.numel (); \
+	  int n_nel = n.numel (); \
+ \
+	  bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
+ \
+	  dim_vector m_dv = m.dims (); \
+	  dim_vector n_dv = n.dims (); \
+ \
+	  bool is_array_op = (m_dv == n_dv); \
+ \
+	  if (is_array_op || is_scalar_op) \
+	    { \
+	      T ## NDArray result; \
+ \
+	      if (m_nel != 1) \
+		result.resize (m_dv); \
+	      else \
+		result.resize (n_dv); \
+ \
+	      for (int i = 0; i < m_nel; i++) \
+		if (is_scalar_op) \
+		  for (int k = 0; k < n_nel; k++) \
+		    if (static_cast<int> (n(k)) >= bits_in_type) \
+		      result(i+k) = 0; \
+		    else \
+		      result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
+		else \
+		  if (static_cast<int> (n(i)) >= bits_in_type) \
+		    result(i) = 0;					\
+		  else 						\
+		    result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
+ \
+	      retval = result; \
+	    } \
+	  else \
+	    error ("bitshift: size of A and N must match, or one operand must be a scalar"); \
+	} \
+      else \
+	error ("bitshift: expecting second argument to be integer"); \
+    }
+
+#define DO_UBITSHIFT(T, N) \
+  do \
+    { \
+      int bits_in_type = octave_ ## T :: nbits (); \
+      T ## NDArray m = m_arg.T ## _array_value (); \
+	octave_ ## T mask = octave_ ## T::max (); \
+      if ((N) < bits_in_type) \
+	mask = bitshift (mask, (N) - bits_in_type); \
+      else if ((N) < 1) \
+	mask = 0; \
+      DO_BITSHIFT (T); \
+    } \
+  while (0)
+
+#define DO_SBITSHIFT(T, N) \
+  do \
+    { \
+      int bits_in_type = octave_ ## T :: nbits (); \
+      T ## NDArray m = m_arg.T ## _array_value (); \
+	octave_ ## T mask = octave_ ## T::max (); \
+      if ((N) < bits_in_type) \
+	mask = bitshift (mask, (N) - bits_in_type); \
+      else if ((N) < 1) \
+	mask = 0; \
+      mask = mask | octave_ ## T :: min (); /* FIXME: 2's complement only? */ \
+      DO_BITSHIFT (T); \
+    } \
+  while (0)
+
+DEFUN (bitshift, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})\n\
+ at deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})\n\
+Return a @var{k} bit shift of @var{n}-digit unsigned\n\
+integers in @var{a}.  A positive @var{k} leads to a left shift.\n\
+A negative value to a right shift.  If @var{n} is omitted it defaults\n\
+to log2(bitmax)+1.\n\
+ at var{n} must be in the range [1,log2(bitmax)+1] usually [1,33]\n\
+\n\
+ at example\n\
+ at group\n\
+bitshift (eye (3), 1)\n\
+ at result{}\n\
+ at group\n\
+2 0 0\n\
+0 2 0\n\
+0 0 2\n\
+ at end group\n\
+\n\
+bitshift (10, [-2, -1, 0, 1, 2])\n\
+ at result{} 2   5  10  20  40\n\
+ at c FIXME -- restore this example when third arg is allowed to be an array.\n\
+ at c \n\
+ at c \n\
+ at c bitshift ([1, 10], 2, [3,4])\n\
+ at c @result{} 4  8\n\
+ at end group\n\
+ at end example\n\
+ at seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 || nargin == 3)
+    {
+      int nbits = 64;
+      
+      NDArray n = args(1).array_value ();
+
+      if (error_state)
+	error ("bitshift: expecting integer as second argument");
+      else
+	{
+	  if (nargin == 3)
+	    {
+	      // FIXME -- for compatibility, we should accept an array
+	      // or a scalar as the third argument.
+	      if (args(2).numel () > 1)
+		error ("bitshift: expecting scalar integer as third argument");
+	      else
+		{
+		  nbits = args(2).int_value ();
+	  
+		  if (error_state)
+		    error ("bitshift: expecting integer as third argument");
+		  else if (nbits < 0)
+		    error ("bitshift: number of bits to mask must be positive");
+		}
+	    }
+	}
+
+      if (error_state)
+	return retval;
+
+      octave_value m_arg = args(0);
+      std::string cname = m_arg.class_name ();
+
+      if (cname == "uint8")
+	DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8);
+      else if (cname == "uint16")
+	DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16);
+      else if (cname == "uint32")
+	DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32);
+      else if (cname == "uint64")
+	DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64);
+      else if (cname == "int8")
+	DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8);
+      else if (cname == "int16")
+	DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16);
+      else if (cname == "int32")
+	DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32);
+      else if (cname == "int64")
+	DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64);
+      else if (cname == "double")
+	{
+	  nbits = (nbits < 53 ? nbits : 53);
+	  int64_t mask = 0x1FFFFFFFFFFFFFLL;
+	  if (nbits < 53)
+	    mask = mask >> (53 - nbits);
+	  else if (nbits < 1)
+	    mask = 0;
+	  int bits_in_type = 64;
+	  NDArray m = m_arg.array_value ();
+	  DO_BITSHIFT ( );
+	}
+      else
+	error ("bitshift: not defined for %s objects", cname.c_str ());
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (bitmax, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} bitmax ()\n\
+Return the largest integer that can be represented as a floating point\n\
+value.  On IEEE-754 compatible systems, @code{bitmax} is @code{2^53 - 1}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () != 0)
+    print_usage ();
+  else
+    retval = (static_cast<double> (0x1FFFFFFFFFFFFFLL));
+  return retval;
+}
+
+DEFUN (intmax, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} intmax (@var{type})\n\
+Return the largest integer that can be represented in an integer type.\n\
+The variable @var{type} can be\n\
+\n\
+ at table @code\n\
+ at item int8\n\
+signed 8-bit integer.\n\
+ at item int16\n\
+signed 16-bit integer.\n\
+ at item int32\n\
+signed 32-bit integer.\n\
+ at item int64\n\
+signed 64-bit integer.\n\
+ at item uint8\n\
+unsigned 8-bit integer.\n\
+ at item uint16\n\
+unsigned 16-bit integer.\n\
+ at item uint32\n\
+unsigned 32-bit integer.\n\
+ at item uint64\n\
+unsigned 64-bit integer.\n\
+ at end table\n\
+\n\
+The default for @var{type} is @code{uint32}.\n\
+ at seealso{intmin, bitmax}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  std::string cname = "int32";
+  int nargin = args.length ();
+
+  if (nargin == 1 && args(0).is_string ())
+    cname = args(0).string_value ();
+  else if (nargin != 0)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (cname == "uint8")
+    retval = octave_uint8 (std::numeric_limits<uint8_t>::max ());
+  else if (cname == "uint16")
+    retval = octave_uint16 (std::numeric_limits<uint16_t>::max ());
+  else if (cname == "uint32")
+    retval = octave_uint32 (std::numeric_limits<uint32_t>::max ());
+  else if (cname == "uint64")
+    retval = octave_uint64 (std::numeric_limits<uint64_t>::max ());
+  else if (cname == "int8")
+    retval = octave_int8 (std::numeric_limits<int8_t>::max ());
+  else if (cname == "int16")
+    retval = octave_int16 (std::numeric_limits<int16_t>::max ());
+  else if (cname == "int32")
+    retval = octave_int32 (std::numeric_limits<int32_t>::max ());
+  else if (cname == "int64")
+    retval = octave_int64 (std::numeric_limits<int64_t>::max ());
+  else
+    error ("intmax: not defined for '%s' objects", cname.c_str ());
+
+  return retval;
+}
+
+DEFUN (intmin, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} intmin (@var{type})\n\
+Return the smallest integer that can be represented in an integer type.\n\
+The variable @var{type} can be\n\
+\n\
+ at table @code\n\
+ at item int8\n\
+signed 8-bit integer.\n\
+ at item int16\n\
+signed 16-bit integer.\n\
+ at item int32\n\
+signed 32-bit integer.\n\
+ at item int64\n\
+signed 64-bit integer.\n\
+ at item uint8\n\
+unsigned 8-bit integer.\n\
+ at item uint16\n\
+unsigned 16-bit integer.\n\
+ at item uint32\n\
+unsigned 32-bit integer.\n\
+ at item uint64\n\
+unsigned 64-bit integer.\n\
+ at end table\n\
+\n\
+The default for @var{type} is @code{uint32}.\n\
+ at seealso{intmax, bitmax}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  std::string cname = "int32";
+  int nargin = args.length ();
+
+  if (nargin == 1 && args(0).is_string ())
+    cname = args(0).string_value ();
+  else if (nargin != 0)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (cname == "uint8")
+    retval = octave_uint8 (std::numeric_limits<uint8_t>::min ());
+  else if (cname == "uint16")
+    retval = octave_uint16 (std::numeric_limits<uint16_t>::min());
+  else if (cname == "uint32")
+    retval = octave_uint32 (std::numeric_limits<uint32_t>::min ());
+  else if (cname == "uint64")
+    retval = octave_uint64 (std::numeric_limits<uint64_t>::min ());
+  else if (cname == "int8")
+    retval = octave_int8 (std::numeric_limits<int8_t>::min ());
+  else if (cname == "int16")
+    retval = octave_int16 (std::numeric_limits<int16_t>::min ());
+  else if (cname == "int32")
+    retval = octave_int32 (std::numeric_limits<int32_t>::min ());
+  else if (cname == "int64")
+    retval = octave_int64 (std::numeric_limits<int64_t>::min ());
+  else
+    error ("intmin: not defined for '%s' objects", cname.c_str ());
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/builtins.h b/src/builtins.h
new file mode 100644
index 0000000..4823436
--- /dev/null
+++ b/src/builtins.h
@@ -0,0 +1,34 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_builtins_h)
+#define octave_builtins_h 1
+
+extern OCTINTERP_API void install_builtins (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/c-file-ptr-stream.cc b/src/c-file-ptr-stream.cc
new file mode 100644
index 0000000..56c4890
--- /dev/null
+++ b/src/c-file-ptr-stream.cc
@@ -0,0 +1,351 @@
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "c-file-ptr-stream.h"
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+c_file_ptr_buf::~c_file_ptr_buf (void)
+{
+  close ();
+}
+
+// FIXME -- I'm sure there is room for improvement here...
+
+c_file_ptr_buf::int_type
+c_file_ptr_buf::overflow (int_type c)
+{
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+  if (f)
+    return (c != traits_type::eof ()) ? fputc (c, f) : flush ();
+  else
+    return traits_type::not_eof (c);
+#else
+  if (f)
+    return (c != EOF) ? fputc (c, f) : flush ();
+  else
+    return EOF;
+#endif
+}
+
+c_file_ptr_buf::int_type
+c_file_ptr_buf::underflow_common (bool bump)
+{
+  if (f)
+    {
+      int_type c = fgetc (f);
+
+      if (! bump
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+	  && c != traits_type::eof ())
+#else
+	  && c != EOF)
+#endif
+	ungetc (c, f);
+
+      return c;
+    }
+  else
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+    return traits_type::eof ();
+#else
+    return EOF;
+#endif
+}
+
+c_file_ptr_buf::int_type
+c_file_ptr_buf::pbackfail (int_type c)
+{
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+  return (c != traits_type::eof () && f) ? ungetc (c, f) : 
+    traits_type::not_eof (c);
+#else
+  return (c != EOF && f) ? ungetc (c, f) : EOF;
+#endif
+}
+
+std::streamsize
+c_file_ptr_buf::xsputn (const char* s, std::streamsize n)
+{
+  if (f)
+    return fwrite (s, 1, n, f);
+  else
+    return 0;
+}
+
+std::streamsize
+c_file_ptr_buf::xsgetn (char *s, std::streamsize n)
+{
+  if (f)
+    return fread (s, 1, n, f);
+  else
+    return 0;
+}
+
+static inline int
+seekdir_to_whence (std::ios::seekdir dir)
+{
+  return ((dir == std::ios::beg) ? SEEK_SET :
+	  (dir == std::ios::cur) ? SEEK_CUR :
+	  (dir == std::ios::end) ? SEEK_END :
+	  dir);
+}
+
+std::streampos
+c_file_ptr_buf::seekoff (std::streamoff /* offset */,
+			 std::ios::seekdir /* dir */,
+			 std::ios::openmode)
+{
+  // FIXME
+#if 0
+  if (f)
+    {
+      fseek (f, offset, seekdir_to_whence (dir));
+
+      return ftell (f);
+    }
+  else
+    return 0;
+#endif
+  return -1;
+}
+
+std::streampos
+c_file_ptr_buf::seekpos (std::streampos /* offset */, std::ios::openmode)
+{
+  // FIXME
+#if 0  
+  if (f)
+    {
+      fseek (f, offset, SEEK_SET);
+
+      return ftell (f);
+    }
+  else
+    return 0;
+#endif
+  return -1;
+}
+
+int
+c_file_ptr_buf::sync (void)
+{
+  flush ();
+
+  return 0;
+}
+
+int
+c_file_ptr_buf::flush (void)
+{
+  return f ? fflush (f) : EOF;
+}
+
+int
+c_file_ptr_buf::close (void)
+{
+  int retval = -1;
+
+  flush ();
+
+  if (f)
+    {
+      retval = cf (f);
+      f = 0;
+    }
+
+  return retval;
+}
+
+#ifdef HAVE_ZLIB
+
+c_zfile_ptr_buf::~c_zfile_ptr_buf (void)
+{
+  close ();
+}
+
+// FIXME -- I'm sure there is room for improvement here...
+
+c_zfile_ptr_buf::int_type
+c_zfile_ptr_buf::overflow (int_type c)
+{
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+  if (f)
+    return (c != traits_type::eof ()) ? gzputc (f, c) : flush ();
+  else
+    return traits_type::not_eof (c);
+#else
+  if (f)
+    return (c != EOF) ? gzputc (f, c) : flush ();
+  else
+    return EOF;
+#endif
+}
+
+c_zfile_ptr_buf::int_type
+c_zfile_ptr_buf::underflow_common (bool bump)
+{
+  if (f)
+    {
+      int_type c = gzgetc (f);
+
+      if (! bump
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+	  && c != traits_type::eof ())
+#else
+	  && c != EOF)
+#endif
+	gzungetc (c, f);
+
+      return c;
+    }
+  else
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+    return traits_type::eof ();
+#else
+    return EOF;
+#endif
+}
+
+c_zfile_ptr_buf::int_type
+c_zfile_ptr_buf::pbackfail (int_type c)
+{
+#if defined (CXX_ISO_COMPLIANT_LIBRARY)
+  return (c != traits_type::eof () && f) ? gzungetc (c, f) : 
+    traits_type::not_eof (c);
+#else
+  return (c != EOF && f) ? gzungetc (c, f) : EOF;
+#endif
+}
+
+std::streamsize
+c_zfile_ptr_buf::xsputn (const char* s, std::streamsize n)
+{
+  if (f)
+    return gzwrite (f, s, n);
+  else
+    return 0;
+}
+
+std::streamsize
+c_zfile_ptr_buf::xsgetn (char *s, std::streamsize n)
+{
+  if (f)
+    return gzread (f, s, n);
+  else
+    return 0;
+}
+
+std::streampos
+c_zfile_ptr_buf::seekoff (std::streamoff /* offset */,
+			  std::ios::seekdir /* dir */,
+			  std::ios::openmode)
+{
+  // FIXME
+#if 0
+  if (f)
+    {
+      gzseek (f, offset, seekdir_to_whence (dir));
+
+      return gztell (f);
+    }
+  else
+    return 0;
+#endif
+  return -1;
+}
+
+std::streampos
+c_zfile_ptr_buf::seekpos (std::streampos /* offset */, std::ios::openmode)
+{
+  // FIXME
+#if 0  
+  if (f)
+    {
+      gzseek (f, offset, SEEK_SET);
+
+      return gztell (f);
+    }
+  else
+    return 0;
+#endif
+  return -1;
+}
+
+int
+c_zfile_ptr_buf::sync (void)
+{
+  flush ();
+
+  return 0;
+}
+
+int
+c_zfile_ptr_buf::flush (void)
+{
+  // FIXME -- do we need something more complex here, passing
+  // something other than 0 for the second argument to gzflush and
+  // checking the return value, etc.?
+
+  return f ? gzflush (f, 0) : EOF;
+}
+
+int
+c_zfile_ptr_buf::close (void)
+{
+  int retval = -1;
+
+  flush ();
+
+  if (f)
+    {
+      retval = cf (f);
+      f = 0;
+    }
+
+  return retval;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/c-file-ptr-stream.h b/src/c-file-ptr-stream.h
new file mode 100644
index 0000000..8c0b4f3
--- /dev/null
+++ b/src/c-file-ptr-stream.h
@@ -0,0 +1,217 @@
+/*
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_c_file_ptr_stream_h)
+#define octave_c_file_ptr_stream_h 1
+
+#include <cstdio>
+
+#include <iosfwd>
+
+class
+c_file_ptr_buf : public std::streambuf
+{
+public:
+
+#if !defined (CXX_ISO_COMPLIANT_LIBRARY)
+  typedef int int_type;
+#else
+  typedef std::streambuf::int_type int_type;
+#endif
+
+  typedef int (*close_fcn) (FILE *);
+
+  FILE* stdiofile (void) { return f; }
+
+  c_file_ptr_buf (FILE *f_arg, close_fcn cf_arg = fclose)
+    : std::streambuf (), f (f_arg), cf (cf_arg)
+    { }
+
+  ~c_file_ptr_buf (void);
+
+  int_type overflow (int_type);
+
+  int_type underflow (void) { return underflow_common (false); }
+
+  int_type uflow (void) { return underflow_common (true); }
+
+  int_type pbackfail (int_type);
+
+  std::streamsize xsputn (const char*, std::streamsize);
+
+  std::streamsize xsgetn (char *, std::streamsize);
+
+  std::streampos seekoff (std::streamoff, std::ios::seekdir,
+			  std::ios::openmode = std::ios::in | std::ios::out);
+  
+  std::streampos seekpos (std::streampos,
+			  std::ios::openmode = std::ios::in | std::ios::out);
+
+  int sync (void);
+
+  int flush (void);
+
+  int close (void);
+
+  int file_number () const { return f ? fileno (f) : -1; }
+
+  int seek (long offset, int origin)
+    { return f ? fseek (f, offset, origin) : -1; }
+
+  long tell (void) { return f ? ftell (f) : -1; }
+
+  void clear (void) { if (f) clearerr (f); }
+
+  static int fclose (FILE *f) { return ::fclose (f); }
+
+protected:
+
+  FILE *f;
+
+  close_fcn cf;
+
+private:
+
+  int_type underflow_common (bool);
+};
+
+// FIXME -- the following three classes could probably share
+// some code...
+
+template <typename STREAM_T, typename FILE_T, typename BUF_T>
+class
+c_file_ptr_stream : public STREAM_T
+{
+public:
+
+  c_file_ptr_stream (FILE_T f, typename BUF_T::close_fcn cf = BUF_T::fclose)
+    : STREAM_T (0), buf (new BUF_T (f, cf)) { STREAM_T::init (buf); }
+
+  ~c_file_ptr_stream (void) { delete buf; buf = 0; }
+
+  BUF_T *rdbuf (void) { return buf; }
+
+  void close (void) { if (buf) buf->close (); }
+
+  int seek (long offset, int origin)
+    { return buf ? buf->seek (offset, origin) : -1; }
+
+  long tell (void) { return buf ? buf->tell () : -1; }
+
+  void clear (void) { if (buf) buf->clear (); STREAM_T::clear (); }
+
+private:
+
+  BUF_T *buf;
+};
+
+typedef c_file_ptr_stream<std::istream, FILE *, c_file_ptr_buf> i_c_file_ptr_stream;
+typedef c_file_ptr_stream<std::ostream, FILE *, c_file_ptr_buf> o_c_file_ptr_stream;
+typedef c_file_ptr_stream<std::iostream, FILE *, c_file_ptr_buf> io_c_file_ptr_stream;
+
+#ifdef HAVE_ZLIB
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+class
+c_zfile_ptr_buf : public std::streambuf
+{
+public:
+
+#if !defined (CXX_ISO_COMPLIANT_LIBRARY)
+  typedef int int_type;
+#else
+  typedef std::streambuf::int_type int_type;
+#endif
+
+  typedef int (*close_fcn) (gzFile);
+
+  gzFile stdiofile (void) { return f; }
+
+  c_zfile_ptr_buf (gzFile f_arg, close_fcn cf_arg = fclose)
+    : std::streambuf (), f (f_arg), cf (cf_arg)
+    { }
+
+  ~c_zfile_ptr_buf (void);
+
+  int_type overflow (int_type);
+
+  int_type underflow (void) { return underflow_common (false); }
+
+  int_type uflow (void) { return underflow_common (true); }
+
+  int_type pbackfail (int_type);
+
+  std::streamsize xsputn (const char*, std::streamsize);
+
+  std::streamsize xsgetn (char *, std::streamsize);
+
+  std::streampos seekoff (std::streamoff, std::ios::seekdir,
+			  std::ios::openmode = std::ios::in | std::ios::out);
+  
+  std::streampos seekpos (std::streampos,
+			  std::ios::openmode = std::ios::in | std::ios::out);
+
+  int sync (void);
+
+  int flush (void);
+
+  int close (void);
+
+  int file_number () const { return -1; }
+
+  int seek (long offset, int origin)
+    { return f ? gzseek (f, offset, origin) : -1; }
+
+  long tell (void) { return f ? gztell (f) : -1; }
+
+  void clear (void) { if (f) gzclearerr (f); }
+
+  static int fclose (gzFile f) { return ::gzclose (f); }
+
+protected:
+
+  gzFile f;
+
+  close_fcn cf;
+
+private:
+
+  int_type underflow_common (bool);
+};
+
+typedef c_file_ptr_stream<std::istream, gzFile, c_zfile_ptr_buf> i_c_zfile_ptr_stream;
+typedef c_file_ptr_stream<std::ostream, gzFile, c_zfile_ptr_buf> o_c_zfile_ptr_stream;
+typedef c_file_ptr_stream<std::iostream, gzFile, c_zfile_ptr_buf> io_c_zfile_ptr_stream;
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/comment-list.cc b/src/comment-list.cc
new file mode 100644
index 0000000..8457b60
--- /dev/null
+++ b/src/comment-list.cc
@@ -0,0 +1,106 @@
+/*
+
+Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-utils.h"
+
+#include "comment-list.h"
+#include "error.h"
+
+octave_comment_buffer *octave_comment_buffer::instance = 0;
+
+octave_comment_list *
+octave_comment_list::dup (void) const
+{
+  octave_comment_list *new_cl = new octave_comment_list ();
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const octave_comment_elt elt = *p;
+
+      new_cl->append (elt);
+    }
+
+  return new_cl;
+}
+
+bool
+octave_comment_buffer::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_comment_buffer ();
+
+  if (! instance)
+    {
+      ::error ("unable to create comment buffer object");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+octave_comment_buffer::append (const std::string& s,
+			       octave_comment_elt::comment_type t)
+{
+  if (instance_ok ())
+    instance->do_append (s, t);
+}
+
+octave_comment_list *
+octave_comment_buffer::get_comment (void)
+{
+  return (instance_ok ()) ? instance->do_get_comment () : 0;
+}
+
+void
+octave_comment_buffer::do_append (const std::string& s,
+				  octave_comment_elt::comment_type t)
+{
+  comment_list->append(s, t);
+}
+
+octave_comment_list *
+octave_comment_buffer::do_get_comment (void)
+{
+  octave_comment_list *retval = 0;
+
+  if (comment_list && comment_list->length () > 0)
+    {
+      retval = comment_list;
+      comment_list = new octave_comment_list ();
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/comment-list.h b/src/comment-list.h
new file mode 100644
index 0000000..63097e1
--- /dev/null
+++ b/src/comment-list.h
@@ -0,0 +1,133 @@
+/*
+
+Copyright (C) 2000, 2002, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_comment_list_h)
+#define octave_comment_list_h 1
+
+#include <string>
+
+#include <base-list.h>
+
+extern std::string get_comment_text (void);
+
+extern char *get_comment_text_c_str (void);
+
+extern void save_comment_text (const std::string& text);
+
+class
+octave_comment_elt
+{
+public:
+
+  enum comment_type
+  {
+    unknown,
+    block,
+    end_of_line,
+    doc_string,
+    copyright
+  };
+
+  octave_comment_elt (const std::string& s = std::string (),
+		      comment_type t = unknown)
+    : txt (s), typ (t) { }
+
+  octave_comment_elt (const octave_comment_elt& oc)
+    : txt (oc.txt), typ (oc.typ) { }
+
+  octave_comment_elt& operator = (const octave_comment_elt& oc)
+    {
+      if (this != &oc)
+	{
+	  txt = oc.txt;
+	  typ = oc.typ;
+	}
+
+      return *this;
+    }
+
+  std::string text (void) const { return txt; }
+
+  comment_type type (void) const { return typ; }
+
+  ~octave_comment_elt (void) { }
+
+private:
+
+  // The text of the comment.
+  std::string txt;
+
+  // The type of comment.
+  comment_type typ;
+};
+
+class
+octave_comment_list : public octave_base_list<octave_comment_elt>
+{
+public:
+
+  octave_comment_list (void) { }
+
+  void append (const octave_comment_elt& elt)
+    { octave_base_list<octave_comment_elt>::append (elt); }
+
+  void append (const std::string& s,
+	       octave_comment_elt::comment_type t = octave_comment_elt::unknown)
+    { append (octave_comment_elt (s, t)); }
+
+  octave_comment_list *dup (void) const;
+};
+
+class
+octave_comment_buffer
+{
+public:
+
+  octave_comment_buffer (void)
+    : comment_list (new octave_comment_list ()) { }
+  
+  static bool instance_ok (void);
+
+  static void append
+    (const std::string& s,
+     octave_comment_elt::comment_type t = octave_comment_elt::unknown);
+
+  static octave_comment_list *get_comment (void);
+
+private:
+
+  void do_append (const std::string& s, octave_comment_elt::comment_type t);
+
+  octave_comment_list *do_get_comment (void);
+
+  octave_comment_list *comment_list;
+
+  static octave_comment_buffer *instance;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/cutils.c b/src/cutils.c
new file mode 100644
index 0000000..aed2f5f
--- /dev/null
+++ b/src/cutils.c
@@ -0,0 +1,125 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2003, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+
+#include <windows.h>
+
+#else
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "systime.h"
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#elif HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
+
+#endif
+
+void
+octave_sleep (unsigned int seconds)
+{
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  Sleep (1000 * seconds);
+#else
+  sleep (seconds);
+#endif
+}
+
+void
+octave_usleep (unsigned int useconds)
+{
+  unsigned int sec = useconds / 1000000;
+  unsigned int usec = useconds % 1000000;
+
+  if (sec > 0)
+    octave_sleep (sec);
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+
+  /* Round to the nearest millisecond, with a minimum of 1 millisecond
+     if usleep was called with a a non-zero value.  */
+
+  if (usec > 500)
+    Sleep ((usec+500)/1000);
+  else if (usec > 0)
+    Sleep (1);
+  else
+    Sleep (0);
+
+#elif defined (HAVE_USLEEP)
+
+  usleep (usec);
+
+#elif defined (HAVE_SELECT)
+
+  {
+    struct timeval delay;
+
+    delay.tv_sec = 0;
+    delay.tv_usec = usec;
+
+    select (0, 0, 0, 0, &delay);
+  }
+
+#elif defined (HAVE_POLL)
+
+  {
+    struct pollfd pfd;
+
+    int delay = usec / 1000;
+
+    if (delay > 0)
+      poll (&pfd, 0, delay);
+  }
+
+#endif
+}
+
+int
+octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, va_list args)
+{
+  return vsnprintf (buf, n, fmt, args);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/data.cc b/src/data.cc
new file mode 100644
index 0000000..a7825b2
--- /dev/null
+++ b/src/data.cc
@@ -0,0 +1,5943 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+Copyright (C) 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "systime.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include <cfloat>
+
+#include <string>
+
+#include "lo-ieee.h"
+#include "lo-math.h"
+#include "str-vec.h"
+#include "quit.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-float.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-cx-sparse.h"
+#include "parse.h"
+#include "pt-mat.h"
+#include "utils.h"
+#include "variables.h"
+#include "pager.h"
+#include "xnorm.h"
+
+#if ! defined (HAVE_HYPOTF) && defined (HAVE__HYPOTF)
+#define hypotf _hypotf
+#define HAVE_HYPOTF 1
+#endif
+
+#define ANY_ALL(FCN) \
+ \
+  octave_value retval; \
+ \
+  int nargin = args.length (); \
+ \
+  if (nargin == 1 || nargin == 2) \
+    { \
+      int dim = (nargin == 1 ? -1 : args(1).int_value (true) - 1); \
+ \
+      if (! error_state) \
+        { \
+          if (dim >= -1) \
+	    retval = args(0).FCN (dim); \
+          else \
+	    error (#FCN ": invalid dimension argument = %d", dim + 1); \
+        } \
+      else \
+        error (#FCN ": expecting dimension argument to be an integer"); \
+    } \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+DEFUN (all, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} all (@var{x}, @var{dim})\n\
+The function @code{all} behaves like the function @code{any}, except\n\
+that it returns true only if all the elements of a vector, or all the\n\
+elements along dimension @var{dim} of a matrix, are nonzero.\n\
+ at end deftypefn")
+{
+  ANY_ALL (all);
+}
+
+/*
+
+%!test
+%! x = ones (3);
+%! x(1,1) = 0;
+%! assert((all (all (rand (3) + 1) == [1, 1, 1]) == 1
+%! && all (all (x) == [0, 1, 1]) == 1
+%! && all (x, 1) == [0, 1, 1]
+%! && all (x, 2) == [0; 1; 1]));
+
+%!test
+%! x = ones (3, 'single');
+%! x(1,1) = 0;
+%! assert((all (all (single (rand (3) + 1)) == [1, 1, 1]) == 1
+%! && all (all (x) == [0, 1, 1]) == 1
+%! && all (x, 1) == [0, 1, 1]
+%! && all (x, 2) == [0; 1; 1]));
+
+%!error <Invalid call to all.*> all ();
+%!error <Invalid call to all.*> all (1, 2, 3);
+
+ */
+
+DEFUN (any, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} any (@var{x}, @var{dim})\n\
+For a vector argument, return 1 if any element of the vector is\n\
+nonzero.\n\
+\n\
+For a matrix argument, return a row vector of ones and\n\
+zeros with each element indicating whether any of the elements of the\n\
+corresponding column of the matrix are nonzero.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+any (eye (2, 4))\n\
+     @result{} [ 1, 1, 0, 0 ]\n\
+ at end group\n\
+ at end example\n\
+\n\
+If the optional argument @var{dim} is supplied, work along dimension\n\
+ at var{dim}.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+any (eye (2, 4), 2)\n\
+     @result{} [ 1; 1 ]\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  ANY_ALL (any);
+}
+
+/*
+
+%!test
+%! x = zeros (3);
+%! x(3,3) = 1;
+%! assert((all (any (x) == [0, 0, 1]) == 1
+%! && all (any (ones (3)) == [1, 1, 1]) == 1
+%! && any (x, 1) == [0, 0, 1]
+%! && any (x, 2) == [0; 0; 1]));
+
+%!test
+%! x = zeros (3,'single');
+%! x(3,3) = 1;
+%! assert((all (any (x) == [0, 0, 1]) == 1
+%! && all (any (ones (3, 'single')) == [1, 1, 1]) == 1
+%! && any (x, 1) == [0, 0, 1]
+%! && any (x, 2) == [0; 0; 1]));
+
+%!error <Invalid call to any.*> any ();
+%!error <Invalid call to any.*> any (1, 2, 3);
+
+ */
+
+// These mapping functions may also be useful in other places, eh?
+
+typedef double (*d_dd_fcn) (double, double);
+typedef float (*f_ff_fcn) (float, float);
+
+static NDArray
+map_d_m (d_dd_fcn f, double x, const NDArray& y)
+{
+  NDArray retval (y.dims ());
+  double *r_data = retval.fortran_vec ();
+
+  const double *y_data = y.data ();
+
+  octave_idx_type nel = y.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x, y_data[i]);
+    }
+
+  return retval;
+}
+
+static FloatNDArray
+map_f_fm (f_ff_fcn f, float x, const FloatNDArray& y)
+{
+  FloatNDArray retval (y.dims ());
+  float *r_data = retval.fortran_vec ();
+
+  const float *y_data = y.data ();
+
+  octave_idx_type nel = y.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x, y_data[i]);
+    }
+
+  return retval;
+}
+
+static NDArray
+map_m_d (d_dd_fcn f, const NDArray& x, double y)
+{
+  NDArray retval (x.dims ());
+  double *r_data = retval.fortran_vec ();
+
+  const double *x_data = x.data ();
+
+  octave_idx_type nel = x.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x_data[i], y);
+    }
+
+  return retval;
+}
+
+static FloatNDArray
+map_fm_f (f_ff_fcn f, const FloatNDArray& x, float y)
+{
+  FloatNDArray retval (x.dims ());
+  float *r_data = retval.fortran_vec ();
+
+  const float *x_data = x.data ();
+
+  octave_idx_type nel = x.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x_data[i], y);
+    }
+
+  return retval;
+}
+
+static NDArray
+map_m_m (d_dd_fcn f, const NDArray& x, const NDArray& y)
+{
+  assert (x.dims () == y.dims ());
+
+  NDArray retval (x.dims ());
+  double *r_data = retval.fortran_vec ();
+
+  const double *x_data = x.data ();
+  const double *y_data = y.data ();
+
+  octave_idx_type nel = x.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x_data[i], y_data[i]);
+    }
+
+  return retval;
+}
+
+static FloatNDArray
+map_fm_fm (f_ff_fcn f, const FloatNDArray& x, const FloatNDArray& y)
+{
+  assert (x.dims () == y.dims ());
+
+  FloatNDArray retval (x.dims ());
+  float *r_data = retval.fortran_vec ();
+
+  const float *x_data = x.data ();
+  const float *y_data = y.data ();
+
+  octave_idx_type nel = x.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x_data[i], y_data[i]);
+    }
+
+  return retval;
+}
+
+static SparseMatrix
+map_d_s (d_dd_fcn f, double x, const SparseMatrix& y)
+{
+  octave_idx_type nr = y.rows ();
+  octave_idx_type nc = y.columns ();
+  SparseMatrix retval;
+  double f_zero = f (x, 0.);
+
+  if (f_zero != 0)
+    {
+      retval = SparseMatrix (nr, nc, f_zero);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = y.cidx (j); i < y.cidx (j+1); i++)
+	  {
+	    OCTAVE_QUIT;
+	    retval.data (y.ridx(i) + j * nr) = f (x, y.data (i));
+	  } 
+
+      retval.maybe_compress (true);
+    }
+  else
+    {
+      octave_idx_type nz = y.nnz ();
+      retval = SparseMatrix (nr, nc, nz);
+      octave_idx_type ii = 0;
+      retval.cidx (ii) = 0;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = y.cidx (j); i < y.cidx (j+1); i++)
+	    {
+	      OCTAVE_QUIT;
+	      double val = f (x, y.data (i));
+
+	      if (val != 0.0)
+		{
+		  retval.data (ii) = val;
+		  retval.ridx (ii++) = y.ridx (i);
+		}
+	    } 
+	  retval.cidx (j + 1) = ii;
+	}
+
+      retval.maybe_compress (false);
+    }
+
+  return retval;
+}
+
+static SparseMatrix
+map_s_d (d_dd_fcn f, const SparseMatrix& x, double y)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.columns ();
+  SparseMatrix retval;
+  double f_zero = f (0., y);
+
+  if (f_zero != 0)
+    {
+      retval = SparseMatrix (nr, nc, f_zero);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = x.cidx (j); i < x.cidx (j+1); i++)
+	  {
+	    OCTAVE_QUIT;
+	    retval.data (x.ridx(i) + j * nr) = f (x.data (i), y);
+	  } 
+
+      retval.maybe_compress (true);
+    }
+  else
+    {
+      octave_idx_type nz = x.nnz ();
+      retval = SparseMatrix (nr, nc, nz);
+      octave_idx_type ii = 0;
+      retval.cidx (ii) = 0;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = x.cidx (j); i < x.cidx (j+1); i++)
+	    {
+	      OCTAVE_QUIT;
+	      double val = f (x.data (i), y);
+
+	      if (val != 0.0)
+		{
+		  retval.data (ii) = val;
+		  retval.ridx (ii++) = x.ridx (i);
+		}
+	    } 
+	  retval.cidx (j + 1) = ii;
+	}
+
+      retval.maybe_compress (false);
+    }
+
+  return retval;
+}
+
+static SparseMatrix
+map_s_s (d_dd_fcn f, const SparseMatrix& x, const SparseMatrix& y)
+{
+  octave_idx_type nr = x.rows ();
+  octave_idx_type nc = x.columns ();
+
+  octave_idx_type y_nr = y.rows ();
+  octave_idx_type y_nc = y.columns ();
+
+  assert (nr == y_nr && nc == y_nc);
+
+  SparseMatrix retval;
+  double f_zero = f (0., 0.);
+
+  if (f_zero != 0)
+    {
+      retval = SparseMatrix (nr, nc, f_zero);
+      octave_idx_type k1 = 0, k2 = 0;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  while (k1 < x.cidx(j+1) && k2 < y.cidx(j+1))
+	    {
+	      OCTAVE_QUIT;
+	      if (k1 >= x.cidx(j+1))
+		{
+		  retval.data (y.ridx(k2) + j * nr) = f (0.0, y.data (k2));
+		  k2++;
+		}
+	      else if (k2 >= y.cidx(j+1))
+		{
+		  retval.data (x.ridx(k1) + j * nr) = f (x.data (k1), 0.0);
+		  k1++;
+		}
+	      else
+		{
+		  octave_idx_type rx = x.ridx(k1);
+		  octave_idx_type ry = y.ridx(k2);
+
+		  if (rx < ry)
+		    {
+		      retval.data (rx + j * nr) = f (x.data (k1), 0.0);
+		      k1++;
+		    }
+		  else if (rx > ry)
+		    {
+		      retval.data (ry + j * nr) = f (0.0, y.data (k2));
+		      k2++;
+		    }
+		  else
+		    {
+		      retval.data (ry + j * nr) = f (x.data (k1), y.data (k2));
+		      k1++;
+		      k2++;
+		    }
+		}
+	    }
+	}
+
+      retval.maybe_compress (true);
+    }
+  else
+    {
+      octave_idx_type nz = x.nnz () + y.nnz ();
+      retval = SparseMatrix (nr, nc, nz);
+      octave_idx_type ii = 0;
+      retval.cidx (ii) = 0;
+      octave_idx_type k1 = 0, k2 = 0;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  while (k1 < x.cidx(j+1) && k2 < y.cidx(j+1))
+	    {
+	      OCTAVE_QUIT;
+	      double val;
+	      octave_idx_type r;
+	      if (k1 >= x.cidx(j+1))
+		{
+		  r = y.ridx (k2);
+		  val = f (0.0, y.data (k2++));
+		}
+	      else if (k2 >= y.cidx(j+1))
+		{
+		  r = x.ridx (k1);
+		  val = f (x.data (k1++), 0.0);
+		}
+	      else
+		{
+		  octave_idx_type rx = x.ridx(k1);
+		  octave_idx_type ry = y.ridx(k2);
+
+		  if (rx < ry)
+		    {
+		      r = x.ridx (k1);
+		      val = f (x.data (k1++), 0.0);
+		    }
+		  else if (rx > ry)
+		    {
+		      r = y.ridx (k2);
+		      val = f (0.0, y.data (k2++));
+		    }
+		  else
+		    {
+		      r = y.ridx (k2);
+		      val = f (x.data (k1++), y.data (k2++));
+		    }
+		}
+	      if (val != 0.0)
+		{
+		  retval.data (ii) = val;
+		  retval.ridx (ii++) = r;
+		}
+	    }
+	  retval.cidx (j + 1) = ii;
+	}
+
+      retval.maybe_compress (false);
+    }
+
+  return retval;
+}
+
+DEFUN (atan2, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} atan2 (@var{y}, @var{x})\n\
+Compute atan (@var{y} / @var{x}) for corresponding elements of @var{y}\n\
+and @var{x}.  Signal an error if @var{y} and @var{x} do not match in size\n\
+and orientation.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
+    {
+      if (args(0).is_integer_type () || args(1).is_integer_type ())
+	error ("atan2: not defined for integer types");
+      else
+	{
+	  octave_value arg_y = args(0);
+	  octave_value arg_x = args(1);
+
+	  dim_vector y_dims = arg_y.dims ();
+	  dim_vector x_dims = arg_x.dims ();
+
+	  bool y_is_scalar = y_dims.all_ones ();
+	  bool x_is_scalar = x_dims.all_ones ();
+
+	  bool is_float = arg_y.is_single_type () || arg_x.is_single_type ();
+
+	  if (y_is_scalar && x_is_scalar)
+	    {
+	      if (is_float)
+		{
+		  float y = arg_y.float_value ();
+
+		  if (! error_state)
+		    {
+		      float x = arg_x.float_value ();
+
+		      if (! error_state)
+			retval = atan2f (y, x);
+		    }
+		}
+	      else
+		{
+		  double y = arg_y.double_value ();
+
+		  if (! error_state)
+		    {
+		      double x = arg_x.double_value ();
+
+		      if (! error_state)
+			retval = atan2 (y, x);
+		    }
+		}
+	    }
+	  else if (y_is_scalar)
+	    {
+	      if (is_float)
+		{
+		  float y = arg_y.float_value ();
+
+		  if (! error_state)
+		    {
+		      // Even if x is sparse return a full matrix here
+		      FloatNDArray x = arg_x.float_array_value ();
+
+		      if (! error_state)
+			retval = map_f_fm (atan2f, y, x);
+		    }
+		}
+	      else
+		{
+		  double y = arg_y.double_value ();
+
+		  if (! error_state)
+		    {
+		      // Even if x is sparse return a full matrix here
+		      NDArray x = arg_x.array_value ();
+
+		      if (! error_state)
+			retval = map_d_m (atan2, y, x);
+		    }
+		}
+	    }
+	  else if (x_is_scalar)
+	    {
+	      if (arg_y.is_sparse_type ())
+		{
+		  SparseMatrix y = arg_y.sparse_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      double x = arg_x.double_value ();
+		      
+		      if (! error_state)
+			retval = map_s_d (atan2, y, x);
+		    }
+		}
+	      else if (is_float)
+		{
+		  FloatNDArray y = arg_y.float_array_value ();
+		  
+		  if (! error_state)
+		    {
+		      float x = arg_x.float_value ();
+
+		      if (! error_state)
+			retval = map_fm_f (atan2f, y, x);
+		    }
+		}
+	      else
+		{
+		  NDArray y = arg_y.array_value ();
+
+		  if (! error_state)
+		    {
+		      double x = arg_x.double_value ();
+
+		      if (! error_state)
+			retval = map_m_d (atan2, y, x);
+		    }
+		}
+	    }
+	  else if (y_dims == x_dims)
+	    {
+	      // Even if y is sparse return a full matrix here
+	      if (arg_x.is_sparse_type ())
+		{
+		  SparseMatrix y = arg_y.sparse_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      SparseMatrix x = arg_x.sparse_matrix_value ();
+
+		      if (! error_state)
+			retval = map_s_s (atan2, y, x);
+		    }
+		}
+	      else if (is_float)
+		{
+		  FloatNDArray y = arg_y.array_value ();
+
+		  if (! error_state)
+		    {
+		      FloatNDArray x = arg_x.array_value ();
+
+		      if (! error_state)
+			retval = map_fm_fm (atan2f, y, x);
+		    }
+		}
+	      else
+		{
+		  NDArray y = arg_y.array_value ();
+
+		  if (! error_state)
+		    {
+		      NDArray x = arg_x.array_value ();
+
+		      if (! error_state)
+			retval = map_m_m (atan2, y, x);
+		    }
+		}
+	    }
+	  else
+	    error ("atan2: nonconformant matrices");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (size (atan2 (zeros (0, 2), zeros (0, 2))), [0, 2])
+%!assert (size (atan2 (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
+%!assert (size (atan2 (rand (2, 3, 4), 1)), [2, 3, 4])
+%!assert (size (atan2 (1, rand (2, 3, 4))), [2, 3, 4])
+%!assert (size (atan2 (1, 2)), [1, 1])
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = [0, pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6, 0];
+%! y = [0, rt3, 1, rt3, -rt3, -1, -rt3, 0];
+%! x = [1, 3, 1, 1, 1, 1, 3, 1];
+%! assert(atan2 (y, x), v, sqrt (eps));
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = single([0, pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6, 0]);
+%! y = single([0, rt3, 1, rt3, -rt3, -1, -rt3, 0]);
+%! x = single([1, 3, 1, 1, 1, 1, 3, 1]);
+%! assert(atan2 (y, x), v, sqrt (eps('single')));
+
+%!error <Invalid call to atan2.*> atan2 ();
+%!error <Invalid call to atan2.*> atan2 (1, 2, 3);
+
+*/
+
+
+
+DEFUN (hypot, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} hypot (@var{x}, @var{y})\n\
+Compute the element-by-element square root of the sum of the squares of\n\
+ at var{x} and @var{y}.  This is equivalent to\n\
+ at code{sqrt (@var{x}.^2 + @var{y}.^2)}, but calculated in a manner that\n\
+avoids overflows for large values of @var{x} or @var{y}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
+    {
+      if (args(0).is_integer_type () || args(1).is_integer_type ())
+	error ("hypot: not defined for integer types");
+      else
+	{
+	  octave_value arg_x = args(0);
+	  octave_value arg_y = args(1);
+
+	  dim_vector x_dims = arg_x.dims ();
+	  dim_vector y_dims = arg_y.dims ();
+
+	  bool x_is_scalar = x_dims.all_ones ();
+	  bool y_is_scalar = y_dims.all_ones ();
+
+	  bool is_float = arg_y.is_single_type () || arg_x.is_single_type ();
+
+	  if (y_is_scalar && x_is_scalar)
+	    {
+	      if (is_float)
+		{
+		  float x;
+		  if (arg_x.is_complex_type ())
+		    x = abs (arg_x.float_complex_value ());
+		  else
+		    x = arg_x.float_value ();
+
+		  if (! error_state)
+		    {
+		      float y;
+		      if (arg_y.is_complex_type ())
+			y = abs (arg_y.float_complex_value ());
+		      else
+			y = arg_y.float_value ();
+
+		      if (! error_state)
+			retval = hypotf (x, y);
+		    }
+		}
+	      else
+		{
+		  double x;
+		  if (arg_x.is_complex_type ())
+		    x = abs (arg_x.complex_value ());
+		  else
+		    x = arg_x.double_value ();
+
+		  if (! error_state)
+		    {
+		      double y;
+		      if (arg_y.is_complex_type ())
+			y = abs (arg_y.complex_value ());
+		      else
+			y = arg_y.double_value ();
+
+		      if (! error_state)
+			retval = hypot (x, y);
+		    }
+		}
+	    }
+	  else if (y_is_scalar)
+	    {
+	      if (is_float)
+		{
+		  FloatNDArray x;
+		  if (arg_x.is_complex_type ())
+		    x = arg_x.float_complex_array_value ().abs ();
+		  else
+		    x = arg_x.float_array_value ();
+
+		  if (! error_state)
+		    {
+		      float y;
+		      if (arg_y.is_complex_type ())
+			y = abs (arg_y.float_complex_value ());
+		      else
+			y = arg_y.float_value ();
+
+		      if (! error_state)
+			retval = map_fm_f (hypotf, x, y);
+		    }
+		}
+	      else
+		{
+		  NDArray x;
+		  if (arg_x.is_complex_type ())
+		    x = arg_x.complex_array_value ().abs ();
+		  else
+		    x = arg_x.array_value ();
+
+		  if (! error_state)
+		    {
+		      double y;
+		      if (arg_y.is_complex_type ())
+			y = abs (arg_y.complex_value ());
+		      else
+			y = arg_y.double_value ();
+
+		      if (! error_state)
+			retval = map_m_d (hypot, x, y);
+		    }
+		}
+	    }
+	  else if (x_is_scalar)
+	    {
+	      if (is_float)
+		{
+		  float x;
+		  if (arg_x.is_complex_type ())
+		    x = abs (arg_x.float_complex_value ());
+		  else
+		    x = arg_x.float_value ();
+
+		  if (! error_state)
+		    {
+		      FloatNDArray y;
+		      if (arg_y.is_complex_type ())
+			y = arg_y.float_complex_array_value ().abs ();
+		      else
+			y = arg_y.float_array_value ();
+
+		      if (! error_state)
+			retval = map_f_fm (hypotf, x, y);
+		    }
+		}
+	      else
+		{
+		  double x;
+		  if (arg_x.is_complex_type ())
+		    x = abs (arg_x.complex_value ());
+		  else
+		    x = arg_x.double_value ();
+
+		  if (! error_state)
+		    {
+		      NDArray y;
+		      if (arg_y.is_complex_type ())
+			y = arg_y.complex_array_value ().abs ();
+		      else
+			y = arg_y.array_value ();
+
+		      if (! error_state)
+			retval = map_d_m (hypot, x, y);
+		    }
+		}
+	    }
+	  else if (y_dims == x_dims)
+	    {
+	      if (arg_x.is_sparse_type () && arg_y.is_sparse_type ())
+		{
+		  SparseMatrix x;
+		  if (arg_x.is_complex_type ())
+		    x = arg_x.sparse_complex_matrix_value ().abs ();
+		  else
+		    x = arg_x.sparse_matrix_value ();
+
+		  if (! error_state)
+		    {
+		      SparseMatrix y;
+		      if (arg_y.is_complex_type ())
+			y = arg_y.sparse_complex_matrix_value ().abs ();
+		      else
+			y = arg_y.sparse_matrix_value ();
+
+		      if (! error_state)
+			retval = map_s_s (hypot, x, y);
+		    }
+		}
+	      else if (is_float)
+		{
+		  FloatNDArray x;
+		  if (arg_x.is_complex_type ())
+		    x = arg_x.float_complex_array_value ().abs ();
+		  else
+		    x = arg_x.float_array_value ();
+
+		  if (! error_state)
+		    {
+		      FloatNDArray y;
+		      if (arg_y.is_complex_type ())
+			y = arg_y.float_complex_array_value ().abs ();
+		      else
+			y = arg_y.float_array_value ();
+
+		      if (! error_state)
+			retval = map_fm_fm (hypotf, x, y);
+		    }
+		}
+	      else
+		{
+		  NDArray x;
+		  if (arg_x.is_complex_type ())
+		    x = arg_x.complex_array_value ().abs ();
+		  else
+		    x = arg_x.array_value ();
+
+		  if (! error_state)
+		    {
+		      NDArray y;
+		      if (arg_y.is_complex_type ())
+			y = arg_y.complex_array_value ().abs ();
+		      else
+			y = arg_y.array_value ();
+
+		      if (! error_state)
+			retval = map_m_m (hypot, x, y);
+		    }
+		}
+	    }
+	  else
+	    error ("hypot: nonconformant matrices");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (size (hypot (zeros (0, 2), zeros (0, 2))), [0, 2])
+%!assert (size (hypot (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
+%!assert (size (hypot (rand (2, 3, 4), 1)), [2, 3, 4])
+%!assert (size (hypot (1, rand (2, 3, 4))), [2, 3, 4])
+%!assert (size (hypot (1, 2)), [1, 1])
+%!assert (hypot (1:10, 1:10), sqrt(2) * [1:10], 16*eps)
+%!assert (hypot (single(1:10), single(1:10)), single(sqrt(2) * [1:10]));
+*/
+
+template<typename T, typename ET>
+void 
+map_2_xlog2 (const Array<T>& x, Array<T>& f, Array<ET>& e)
+{
+  f = Array<T>(x.dims ());
+  e = Array<ET>(x.dims ());
+  for (octave_idx_type i = 0; i < x.numel (); i++)
+    {
+      int exp;
+      f.xelem (i) = xlog2 (x(i), exp);
+      e.xelem (i) = exp;
+    }
+}
+
+DEFUN (log2, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} log2 (@var{x})\n\
+ at deftypefnx {Mapping Function} {[@var{f}, @var{e}] =} log2 (@var{x})\n\
+Compute the base-2 logarithm of each element of @var{x}.\n\
+\n\
+If called with two output arguments, split @var{x} into\n\
+binary mantissa and exponent so that\n\
+ at tex\n\
+${1 \\over 2} \\le \\left| f \\right| < 1$\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{1/2 <= abs(f) < 1}\n\
+ at end ifnottex\n\
+and @var{e} is an integer.  If\n\
+ at tex\n\
+$x = 0$, $f = e = 0$.\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{x = 0}, @code{f = e = 0}.\n\
+ at end ifnottex\n\
+ at seealso{pow2, log, log10, exp}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      if (nargout < 2)
+        retval(0) = args(0).log2 ();
+      else if (args(0).is_single_type ())
+	{
+	  if (args(0).is_real_type ())
+	    {
+	      FloatNDArray f;
+	      FloatNDArray x = args(0).float_array_value ();
+	      // FIXME -- should E be an int value?
+	      FloatMatrix e;
+	      map_2_xlog2 (x, f, e);
+	      retval (1) = e;
+	      retval (0) = f;
+	    }
+	  else if (args(0).is_complex_type ())
+	    {
+	      FloatComplexNDArray f;
+	      FloatComplexNDArray x = args(0).float_complex_array_value ();
+	      // FIXME -- should E be an int value?
+	      FloatNDArray e;
+	      map_2_xlog2 (x, f, e);
+	      retval (1) = e;
+	      retval (0) = f;
+	    }
+	}
+      else if (args(0).is_real_type ())
+        {
+          NDArray f;
+          NDArray x = args(0).array_value ();
+          // FIXME -- should E be an int value?
+          Matrix e;
+          map_2_xlog2 (x, f, e);
+          retval (1) = e;
+          retval (0) = f;
+        }
+      else if (args(0).is_complex_type ())
+        {
+          ComplexNDArray f;
+          ComplexNDArray x = args(0).complex_array_value ();
+          // FIXME -- should E be an int value?
+          NDArray e;
+          map_2_xlog2 (x, f, e);
+          retval (1) = e;
+          retval (0) = f;
+        }
+      else
+        gripe_wrong_type_arg ("log2", args(0));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert(log2 ([1/4, 1/2, 1, 2, 4]), [-2, -1, 0, 1, 2]);
+%!assert(log2(Inf), Inf);
+%!assert(isnan(log2(NaN)));
+%!assert(log2(4*i), 2 + log2(1*i));
+%!assert(log2(complex(0,Inf)), Inf + log2(i));
+
+%!test
+%! [f, e] = log2 ([0,-1; 2,-4; Inf,-Inf]);
+%! assert (f, [0,-0.5; 0.5,-0.5; Inf,-Inf]);
+%! assert (e(1:2,:), [0,1;2,3])
+
+%!test
+%! [f, e] = log2 (complex (zeros (3, 2), [0,-1; 2,-4; Inf,-Inf]));
+%! assert (f, complex (zeros (3, 2), [0,-0.5; 0.5,-0.5; Inf,-Inf]));
+%! assert (e(1:2,:), [0,1; 2,3]);
+*/
+
+DEFUN (fmod, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})\n\
+Compute the floating point remainder of dividing @var{x} by @var{y}\n\
+using the C library function @code{fmod}.  The result has the same\n\
+sign as @var{x}.  If @var{y} is zero, the result is implementation-dependent.\n\
+ at seealso{mod, rem}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
+    {
+      octave_value arg_x = args(0);
+      octave_value arg_y = args(1);
+
+      dim_vector y_dims = arg_y.dims ();
+      dim_vector x_dims = arg_x.dims ();
+
+      bool y_is_scalar = y_dims.all_ones ();
+      bool x_is_scalar = x_dims.all_ones ();
+
+      bool is_float = arg_y.is_single_type () || arg_x.is_single_type ();
+
+      if (y_is_scalar && x_is_scalar)
+	{
+	  if (is_float)
+	    {
+	      float y = arg_y.float_value ();
+
+	      if (! error_state)
+		{
+		  float x = arg_x.float_value ();
+
+		  if (! error_state)
+		    retval = fmod (x, y);
+		}
+	    }
+	  else
+	    {
+	      double y = arg_y.double_value ();
+
+	      if (! error_state)
+		{
+		  double x = arg_x.double_value ();
+
+		  if (! error_state)
+		    retval = fmod (x, y);
+		}
+	    }
+	}
+      else if (y_is_scalar)
+	{
+	  if (is_float)
+	    {
+	      float y = arg_y.float_value ();
+
+	      if (! error_state)
+		{
+		  FloatNDArray x = arg_x.float_array_value ();
+
+		  if (! error_state)
+		    retval = map_fm_f (fmodf, x, y);
+		}
+	    }
+	  else
+	    {
+	      double y = arg_y.double_value ();
+
+	      if (! error_state)
+		{
+		  if (arg_x.is_sparse_type ())
+		    {
+		      SparseMatrix x = arg_x.sparse_matrix_value ();
+
+		      if (! error_state)
+			retval = map_s_d (fmod, x, y);
+		    }
+		  else
+		    {
+		      NDArray x = arg_x.array_value ();
+
+		      if (! error_state)
+			retval = map_m_d (fmod, x, y);
+		    }
+		}
+	    }
+	}
+      else if (x_is_scalar)
+	{
+	  if (arg_y.is_sparse_type ())
+	    {
+	      SparseMatrix y = arg_y.sparse_matrix_value ();
+
+	      if (! error_state)
+		{
+		  double x = arg_x.double_value ();
+
+		  if (! error_state)
+		    retval = map_d_s (fmod, x, y);
+		}
+	    }
+	  else if (is_float)
+	    {
+	      FloatNDArray y = arg_y.float_array_value ();
+
+	      if (! error_state)
+		{
+		  float x = arg_x.float_value ();
+
+		  if (! error_state)
+		    retval = map_f_fm (fmodf, x, y);
+		}
+	    }
+	  else
+	    {
+	      NDArray y = arg_y.array_value ();
+
+	      if (! error_state)
+		{
+		  double x = arg_x.double_value ();
+
+		  if (! error_state)
+		    retval = map_d_m (fmod, x, y);
+		}
+	    }
+	}
+      else if (y_dims == x_dims)
+	{
+	  if (arg_y.is_sparse_type () || arg_x.is_sparse_type ())
+	    {
+	      SparseMatrix y = arg_y.sparse_matrix_value ();
+
+	      if (! error_state)
+		{
+		  SparseMatrix x = arg_x.sparse_matrix_value ();
+
+		  if (! error_state)
+		    retval = map_s_s (fmod, x, y);
+		}
+	    }
+	  else if (is_float)
+	    {
+	      FloatNDArray y = arg_y.float_array_value ();
+
+	      if (! error_state)
+		{
+		  FloatNDArray x = arg_x.float_array_value ();
+
+		  if (! error_state)
+		    retval = map_fm_fm (fmodf, x, y);
+		}
+	    }
+	  else
+	    {
+	      NDArray y = arg_y.array_value ();
+
+	      if (! error_state)
+		{
+		  NDArray x = arg_x.array_value ();
+
+		  if (! error_state)
+		    retval = map_m_m (fmod, x, y);
+		}
+	    }
+	}
+      else
+	error ("fmod: nonconformant matrices");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (size (fmod (zeros (0, 2), zeros (0, 2))), [0, 2])
+%!assert (size (fmod (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
+%!assert (size (fmod (rand (2, 3, 4), 1)), [2, 3, 4])
+%!assert (size (fmod (1, rand (2, 3, 4))), [2, 3, 4])
+%!assert (size (fmod (1, 2)), [1, 1])
+*/
+
+// FIXME Need to convert the reduction functions of this file for single precision
+
+#define NATIVE_REDUCTION_1(FCN, TYPE, DIM) \
+  (arg.is_ ## TYPE ## _type ()) \
+    { \
+      TYPE ## NDArray tmp = arg. TYPE ##_array_value (); \
+      \
+      if (! error_state) \
+        { \
+          octave_ ## TYPE::clear_conv_flags (); \
+          retval = tmp.FCN (DIM); \
+          if (octave_ ## TYPE::get_trunc_flag ()) \
+            { \
+              gripe_native_integer_math_truncated (#FCN, \
+                                                   octave_ ## TYPE::type_name ()); \
+              octave_ ## TYPE::clear_conv_flags (); \
+            } \
+        } \
+    }
+
+#define NATIVE_REDUCTION(FCN, BOOL_FCN) \
+ \
+  octave_value retval; \
+ \
+  int nargin = args.length (); \
+ \
+  bool isnative = false; \
+  bool isdouble = false; \
+  \
+  if (nargin > 1 && args(nargin - 1).is_string ()) \
+    { \
+      std::string str = args(nargin - 1).string_value (); \
+      \
+      if (! error_state) \
+	{ \
+	  if (str == "native") \
+	    isnative = true; \
+	  else if (str == "double") \
+            isdouble = true; \
+          else \
+	    error ("sum: unrecognized string argument"); \
+          nargin --; \
+	} \
+    } \
+  \
+  if (nargin == 1 || nargin == 2) \
+    { \
+      octave_value arg = args(0); \
+ \
+      int dim = (nargin == 1 ? -1 : args(1).int_value (true) - 1); \
+ \
+      if (! error_state) \
+	{ \
+	  if (dim >= -1) \
+	    { \
+	      if (arg.is_sparse_type ()) \
+		{ \
+		  if (arg.is_real_type ()) \
+		    { \
+		      SparseMatrix tmp = arg.sparse_matrix_value (); \
+		      \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		  else \
+		    { \
+		      SparseComplexMatrix tmp = arg.sparse_complex_matrix_value (); \
+                      \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		} \
+	      else \
+		{ \
+		  if (isnative)	\
+		    { \
+		      if NATIVE_REDUCTION_1 (FCN, uint8, dim) \
+		      else if NATIVE_REDUCTION_1 (FCN, uint16, dim) \
+                      else if NATIVE_REDUCTION_1 (FCN, uint32, dim) \
+                      else if NATIVE_REDUCTION_1 (FCN, uint64, dim) \
+                      else if NATIVE_REDUCTION_1 (FCN, int8, dim) \
+                      else if NATIVE_REDUCTION_1 (FCN, int16, dim) \
+                      else if NATIVE_REDUCTION_1 (FCN, int32, dim) \
+                      else if NATIVE_REDUCTION_1 (FCN, int64, dim) \
+                      else if (arg.is_bool_type ()) \
+                        { \
+                          boolNDArray tmp = arg.bool_array_value (); \
+                          if (! error_state) \
+                            retval = boolNDArray (tmp.BOOL_FCN (dim)); \
+                        } \
+                      else if (arg.is_char_matrix ()) \
+                        { \
+			  error (#FCN, ": invalid char type"); \
+			} \
+		      else if (!isdouble && arg.is_single_type ()) \
+                        { \
+	                  if (arg.is_complex_type ()) \
+		            { \
+		              FloatComplexNDArray tmp = \
+				arg.float_complex_array_value (); \
+                              \
+		              if (! error_state) \
+		                retval = tmp.FCN (dim); \
+		            } \
+	                  else if (arg.is_real_type ()) \
+		            { \
+		              FloatNDArray tmp = arg.float_array_value (); \
+                              \
+		              if (! error_state) \
+		                retval = tmp.FCN (dim); \
+		            } \
+			} \
+	              else if (arg.is_complex_type ()) \
+		        { \
+		          ComplexNDArray tmp = arg.complex_array_value (); \
+                          \
+		          if (! error_state) \
+		            retval = tmp.FCN (dim); \
+		        } \
+	              else if (arg.is_real_type ()) \
+		        { \
+		          NDArray tmp = arg.array_value (); \
+                          \
+		          if (! error_state) \
+		            retval = tmp.FCN (dim); \
+		        } \
+                      else \
+		        { \
+		          gripe_wrong_type_arg (#FCN, arg); \
+		          return retval; \
+		        } \
+                    } \
+                  else if (arg.is_bool_type ()) \
+                    { \
+                      boolNDArray tmp = arg.bool_array_value (); \
+                      if (! error_state) \
+                        retval = tmp.FCN (dim); \
+                    } \
+		  else if (!isdouble && arg.is_single_type ()) \
+		    { \
+	              if (arg.is_real_type ()) \
+		        { \
+		          FloatNDArray tmp = arg.float_array_value (); \
+                          \
+		          if (! error_state) \
+		            retval = tmp.FCN (dim); \
+		        } \
+	              else if (arg.is_complex_type ()) \
+		        { \
+		          FloatComplexNDArray tmp = \
+			    arg.float_complex_array_value (); \
+                          \
+		          if (! error_state) \
+		            retval = tmp.FCN (dim); \
+		        } \
+		    } \
+	          else if (arg.is_real_type ()) \
+		    { \
+		      NDArray tmp = arg.array_value (); \
+                      \
+		      if (! error_state) \
+		        retval = tmp.FCN (dim); \
+		    } \
+	          else if (arg.is_complex_type ()) \
+		    { \
+		      ComplexNDArray tmp = arg.complex_array_value (); \
+                      \
+		      if (! error_state) \
+		        retval = tmp.FCN (dim); \
+		    } \
+	          else \
+		    { \
+		      gripe_wrong_type_arg (#FCN, arg); \
+		      return retval; \
+		    } \
+		} \
+	    } \
+	  else \
+	    error (#FCN ": invalid dimension argument = %d", dim + 1); \
+	} \
+      \
+    } \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+#define DATA_REDUCTION(FCN) \
+ \
+  octave_value retval; \
+ \
+  int nargin = args.length (); \
+ \
+  if (nargin == 1 || nargin == 2) \
+    { \
+      octave_value arg = args(0); \
+ \
+      int dim = (nargin == 1 ? -1 : args(1).int_value (true) - 1); \
+ \
+      if (! error_state) \
+	{ \
+	  if (dim >= -1) \
+	    { \
+	      if (arg.is_real_type ()) \
+		{ \
+		  if (arg.is_sparse_type ()) \
+		    { \
+		      SparseMatrix tmp = arg.sparse_matrix_value (); \
+ \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		  else if (arg.is_single_type ()) \
+		    { \
+		      FloatNDArray tmp = arg.float_array_value (); \
+ \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		  else \
+		    { \
+		      NDArray tmp = arg.array_value (); \
+ \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		} \
+	      else if (arg.is_complex_type ()) \
+		{ \
+		  if (arg.is_sparse_type ()) \
+		    { \
+		      SparseComplexMatrix tmp = arg.sparse_complex_matrix_value (); \
+ \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		  else if (arg.is_single_type ()) \
+		    { \
+		      FloatComplexNDArray tmp = arg.float_complex_array_value (); \
+ \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		  else \
+		    { \
+		      ComplexNDArray tmp = arg.complex_array_value (); \
+ \
+		      if (! error_state) \
+			retval = tmp.FCN (dim); \
+		    } \
+		} \
+	      else \
+		{ \
+		  gripe_wrong_type_arg (#FCN, arg); \
+		  return retval; \
+		} \
+	    } \
+	  else \
+	    error (#FCN ": invalid dimension argument = %d", dim + 1); \
+	} \
+    } \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+DEFUN (cumprod, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} cumprod (@var{x})\n\
+ at deftypefnx {Built-in Function} {} cumprod (@var{x}, @var{dim})\n\
+Cumulative product of elements along dimension @var{dim}.  If\n\
+ at var{dim} is omitted, it defaults to 1 (column-wise cumulative\n\
+products).\n\
+\n\
+As a special case, if @var{x} is a vector and @var{dim} is omitted,\n\
+return the cumulative product of the elements as a vector with the\n\
+same orientation as @var{x}.\n\
+ at seealso{prod, cumsum}\n\
+ at end deftypefn")
+{
+  DATA_REDUCTION (cumprod);
+}
+
+/*
+
+%!assert (cumprod ([1, 2, 3]), [1, 2, 6]);
+%!assert (cumprod ([-1; -2; -3]), [-1; 2; -6]);
+%!assert (cumprod ([i, 2+i, -3+2i, 4]), [i, -1+2i, -1-8i, -4-32i]);
+%!assert (cumprod ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), [1, 2, 3; i, 4i, 9i; -1+i, -8+8i, -27+27i]);
+
+%!assert (cumprod (single([1, 2, 3])), single([1, 2, 6]));
+%!assert (cumprod (single([-1; -2; -3])), single([-1; 2; -6]));
+%!assert (cumprod (single([i, 2+i, -3+2i, 4])), single([i, -1+2i, -1-8i, -4-32i]));
+%!assert (cumprod (single([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])), single([1, 2, 3; i, 4i, 9i; -1+i, -8+8i, -27+27i]));
+
+%!error <Invalid call to cumprod.*> cumprod ();
+
+%!assert (cumprod ([2, 3; 4, 5], 1), [2, 3; 8, 15]);
+%!assert (cumprod ([2, 3; 4, 5], 2), [2, 6; 4, 20]);
+
+%!assert (cumprod (single([2, 3; 4, 5]), 1), single([2, 3; 8, 15]));
+%!assert (cumprod (single([2, 3; 4, 5]), 2), single([2, 6; 4, 20]));
+
+ */
+
+DEFUN (cumsum, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} cumsum (@var{x})\n\
+ at deftypefnx {Built-in Function} {} cumsum (@var{x}, @var{dim})\n\
+ at deftypefnx {Built-in Function} {} cumsum (@dots{}, 'native')\n\
+Cumulative sum of elements along dimension @var{dim}.  If @var{dim}\n\
+is omitted, it defaults to 1 (column-wise cumulative sums).\n\
+\n\
+As a special case, if @var{x} is a vector and @var{dim} is omitted,\n\
+return the cumulative sum of the elements as a vector with the\n\
+same orientation as @var{x}.\n\
+\n\
+The \"native\" argument implies the summation is performed in native type.\n\
+ See @code{sum} for a complete description and example of the use of\n\
+\"native\".\n\
+ at seealso{sum, cumprod}\n\
+ at end deftypefn")
+{
+  NATIVE_REDUCTION (cumsum, cumsum);
+}
+
+/*
+
+%!assert (cumsum ([1, 2, 3]), [1, 3, 6]);
+%!assert (cumsum ([-1; -2; -3]), [-1; -3; -6]);
+%!assert (cumsum ([i, 2+i, -3+2i, 4]), [i, 2+2i, -1+4i, 3+4i]);
+%!assert (cumsum ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), [1, 2, 3; 1+i, 2+2i, 3+3i; 2+2i, 4+4i, 6+6i]);
+
+%!assert (cumsum (single([1, 2, 3])), single([1, 3, 6]));
+%!assert (cumsum (single([-1; -2; -3])), single([-1; -3; -6]));
+%!assert (cumsum (single([i, 2+i, -3+2i, 4])), single([i, 2+2i, -1+4i, 3+4i]));
+%!assert (cumsum (single([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])), single([1, 2, 3; 1+i, 2+2i, 3+3i; 2+2i, 4+4i, 6+6i]));
+
+%!error <Invalid call to cumsum.*> cumsum ();
+
+%!assert (cumsum ([1, 2; 3, 4], 1), [1, 2; 4, 6]);
+%!assert (cumsum ([1, 2; 3, 4], 2), [1, 3; 3, 7]);
+
+%!assert (cumsum (single([1, 2; 3, 4]), 1), single([1, 2; 4, 6]));
+%!assert (cumsum (single([1, 2; 3, 4]), 2), single([1, 3; 3, 7]));
+
+ */
+
+DEFUN (diag, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} diag (@var{v}, @var{k})\n\
+Return a diagonal matrix with vector @var{v} on diagonal @var{k}.  The\n\
+second argument is optional.  If it is positive, the vector is placed on\n\
+the @var{k}-th super-diagonal.  If it is negative, it is placed on the\n\
+ at var{-k}-th sub-diagonal.  The default value of @var{k} is 0, and the\n\
+vector is placed on the main diagonal.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+diag ([1, 2, 3], 1)\n\
+     @result{}  0  1  0  0\n\
+         0  0  2  0\n\
+         0  0  0  3\n\
+         0  0  0  0\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Given a matrix argument, instead of a vector, @code{diag} extracts the\n\
+ at var{k}-th diagonal of the matrix.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 && args(0).is_defined ())
+    retval = args(0).diag();
+  else if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
+    {
+      octave_idx_type k = args(1).int_value ();
+
+      if (error_state)
+	error ("diag: invalid second argument");      
+      else
+	retval = args(0).diag(k);
+    }
+  else if (nargin == 3)
+    {
+      octave_value arg0 = args(0);
+      if (arg0.ndims () == 2 && (args(0).rows () == 1 || args(0).columns () == 1))
+        {
+          octave_idx_type m = args(1).int_value (), n = args(2).int_value ();
+          if (! error_state)
+            retval = arg0.diag ().resize (dim_vector (m, n));
+          else
+            error ("diag: invalid dimensions");
+        }
+      else
+        error ("diag: first argument must be a vector");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(full (diag ([1; 2; 3])), [1, 0, 0; 0, 2, 0; 0, 0, 3]);
+%!assert(diag ([1; 2; 3], 1), [0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]);
+%!assert(diag ([1; 2; 3], 2), [0, 0, 1, 0, 0; 0, 0, 0, 2, 0; 0, 0, 0, 0, 3; 0, 0, 0, 0, 0; 0, 0, 0, 0, 0]);
+%!assert(diag ([1; 2; 3],-1), [0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]);
+%!assert(diag ([1; 2; 3],-2), [0, 0, 0, 0, 0; 0, 0, 0, 0, 0; 1, 0, 0, 0, 0; 0, 2, 0, 0, 0; 0, 0, 3, 0, 0]);
+
+%!assert(diag ([1, 0, 0; 0, 2, 0; 0, 0, 3]), [1; 2; 3]);
+%!assert(diag ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0], 1), [1; 2; 3]);
+%!assert(diag ([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0], -1), [1; 2; 3]);
+
+%!assert(full (diag (single([1; 2; 3]))), single([1, 0, 0; 0, 2, 0; 0, 0, 3]));
+%!assert(diag (single([1; 2; 3]), 1), single([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]));
+%!assert(diag (single([1; 2; 3]), 2), single([0, 0, 1, 0, 0; 0, 0, 0, 2, 0; 0, 0, 0, 0, 3; 0, 0, 0, 0, 0; 0, 0, 0, 0, 0]));
+%!assert(diag (single([1; 2; 3]),-1), single([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]));
+%!assert(diag (single([1; 2; 3]),-2), single([0, 0, 0, 0, 0; 0, 0, 0, 0, 0; 1, 0, 0, 0, 0; 0, 2, 0, 0, 0; 0, 0, 3, 0, 0]));
+
+%!assert(diag (single([1, 0, 0; 0, 2, 0; 0, 0, 3])), single([1; 2; 3]));
+%!assert(diag (single([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]), 1), single([1; 2; 3]));
+%!assert(diag (single([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]), -1), single([1; 2; 3]));
+
+%!assert(diag (int8([1; 2; 3])), int8([1, 0, 0; 0, 2, 0; 0, 0, 3]));
+%!assert(diag (int8([1; 2; 3]), 1), int8([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]));
+%!assert(diag (int8([1; 2; 3]), 2), int8([0, 0, 1, 0, 0; 0, 0, 0, 2, 0; 0, 0, 0, 0, 3; 0, 0, 0, 0, 0; 0, 0, 0, 0, 0]));
+%!assert(diag (int8([1; 2; 3]),-1), int8([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]));
+%!assert(diag (int8([1; 2; 3]),-2), int8([0, 0, 0, 0, 0; 0, 0, 0, 0, 0; 1, 0, 0, 0, 0; 0, 2, 0, 0, 0; 0, 0, 3, 0, 0]));
+
+%!assert(diag (int8([1, 0, 0; 0, 2, 0; 0, 0, 3])), int8([1; 2; 3]));
+%!assert(diag (int8([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]), 1), int8([1; 2; 3]));
+%!assert(diag (int8([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]), -1), int8([1; 2; 3]));
+
+%!error <Invalid call to diag.*> diag ();
+
+ */
+
+DEFUN (prod, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} prod (@var{x})\n\
+ at deftypefnx {Built-in Function} {} prod (@var{x}, @var{dim})\n\
+Product of elements along dimension @var{dim}.  If @var{dim} is\n\
+omitted, it defaults to 1 (column-wise products).\n\
+\n\
+As a special case, if @var{x} is a vector and @var{dim} is omitted,\n\
+return the product of the elements.\n\
+ at seealso{cumprod, sum}\n\
+ at end deftypefn")
+{
+  DATA_REDUCTION (prod);
+}
+
+/*
+
+%!assert (prod ([1, 2, 3]), 6);
+%!assert (prod ([-1; -2; -3]), -6);
+%!assert (prod ([i, 2+i, -3+2i, 4]), -4 - 32i);
+%!assert (prod ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), [-1+i, -8+8i, -27+27i]);
+
+%!assert (prod (single([1, 2, 3])), single(6));
+%!assert (prod (single([-1; -2; -3])), single(-6));
+%!assert (prod (single([i, 2+i, -3+2i, 4])), single(-4 - 32i));
+%!assert (prod (single([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])), single([-1+i, -8+8i, -27+27i]));
+
+%!error <Invalid call to prod.*> prod ();
+
+%!assert (prod ([1, 2; 3, 4], 1), [3, 8]);
+%!assert (prod ([1, 2; 3, 4], 2), [2; 12]);
+%!assert (prod (zeros (1, 0)), 1);
+%!assert (prod (zeros (1, 0), 1), zeros (1, 0));
+%!assert (prod (zeros (1, 0), 2), 1);
+%!assert (prod (zeros (0, 1)), 1);
+%!assert (prod (zeros (0, 1), 1), 1);
+%!assert (prod (zeros (0, 1), 2), zeros (0, 1));
+%!assert (prod (zeros (2, 0)), zeros (1, 0));
+%!assert (prod (zeros (2, 0), 1), zeros (1, 0));
+%!assert (prod (zeros (2, 0), 2), [1; 1]);
+%!assert (prod (zeros (0, 2)), [1, 1]);
+%!assert (prod (zeros (0, 2), 1), [1, 1]);
+%!assert (prod (zeros (0, 2), 2), zeros(0, 1));
+
+%!assert (prod (single([1, 2; 3, 4]), 1), single([3, 8]));
+%!assert (prod (single([1, 2; 3, 4]), 2), single([2; 12]));
+%!assert (prod (zeros (1, 0, 'single')), single(1));
+%!assert (prod (zeros (1, 0, 'single'), 1), zeros (1, 0, 'single'));
+%!assert (prod (zeros (1, 0, 'single'), 2), single(1));
+%!assert (prod (zeros (0, 1, 'single')), single(1));
+%!assert (prod (zeros (0, 1, 'single'), 1), single(1));
+%!assert (prod (zeros (0, 1, 'single'), 2), zeros (0, 1, 'single'));
+%!assert (prod (zeros (2, 0, 'single')), zeros (1, 0, 'single'));
+%!assert (prod (zeros (2, 0, 'single'), 1), zeros (1, 0, 'single'));
+%!assert (prod (zeros (2, 0, 'single'), 2), single([1; 1]));
+%!assert (prod (zeros (0, 2, 'single')), single([1, 1]));
+%!assert (prod (zeros (0, 2, 'single'), 1), single([1, 1]));
+%!assert (prod (zeros (0, 2, 'single'), 2), zeros(0, 1, 'single'));
+
+ */
+
+#define SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
+  do \
+    { \
+      int dv_len = dv.length (); \
+      Array<octave_idx_type> ra_idx (dv_len > 1 ? dv_len : 2, 0); \
+      \
+      for (int j = 1; j < n_args; j++) \
+	{ \
+	  OCTAVE_QUIT; \
+	  \
+	  TYPE ra = args(j).EXTRACTOR ();	\
+	  \
+	  if (! error_state) \
+	    { \
+	      result.insert (ra, ra_idx); \
+	      \
+	      if (error_state) \
+	        return retval; \
+	      \
+	      dim_vector dv_tmp = args (j).dims (); \
+	      \
+	      if (dim >= dv_len) \
+	        { \
+		  if (j > 1) \
+		    error ("%s: indexing error", fname.c_str ()); \
+		  break; \
+		} \
+	      else \
+		ra_idx (dim) += (dim < dv_tmp.length () ? dv_tmp (dim) : 1); \
+	    } \
+	} \
+    } \
+ while (0)
+
+#define DO_SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
+  do \
+    { \
+      TYPE result (dv); \
+      \
+      SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR); \
+      \
+      retval = result; \
+    } \
+ while (0)
+
+static octave_value
+do_cat (const octave_value_list& args, std::string fname)
+{
+  octave_value retval;
+
+  int n_args = args.length (); 
+
+  if (n_args == 1)
+    retval = Matrix ();
+  else if (n_args == 2)
+    retval = args(1);
+  else if (n_args > 2)
+    {
+      octave_idx_type dim = args(0).int_value () - 1;
+
+      if (error_state)
+	{
+	  error ("cat: expecting first argument to be a integer");
+	  return retval;
+	}
+  
+      if (dim >= 0)
+	{
+ 	  
+ 	  dim_vector  dv = args(1).dims ();
+	  std::string result_type = args(1).class_name ();
+	  
+	  bool all_sq_strings_p = args(1).is_sq_string ();
+	  bool all_dq_strings_p = args(1).is_dq_string ();
+	  bool all_real_p = args(1).is_real_type ();
+	  bool any_sparse_p = args(1).is_sparse_type();
+
+ 	  for (int i = 2; i < args.length (); i++)
+  	    {
+ 	      // add_dims constructs a dimension vector which holds the
+	      // dimensions of the final array after concatenation.
+
+	      if (! dv.concat (args(i).dims (), dim))
+		{
+		  // Dimensions do not match. 
+		  error ("cat: dimension mismatch");
+		  return retval;
+		}
+	      
+	      result_type = 
+		get_concat_class (result_type, args(i).class_name ());
+
+	      if (all_sq_strings_p && ! args(i).is_sq_string ())
+		all_sq_strings_p = false;
+	      if (all_dq_strings_p && ! args(i).is_dq_string ())
+		all_dq_strings_p = false;
+	      if (all_real_p && ! args(i).is_real_type ())
+		all_real_p = false;
+	      if (!any_sparse_p && args(i).is_sparse_type ())
+		any_sparse_p = true;
+	    }
+
+	  if (result_type == "double")
+	    {
+	      if (any_sparse_p)
+		{	    
+		  if (all_real_p)
+		    DO_SINGLE_TYPE_CONCAT (SparseMatrix, sparse_matrix_value);
+		  else
+		    DO_SINGLE_TYPE_CONCAT (SparseComplexMatrix, sparse_complex_matrix_value);
+		}
+	      else
+		{
+		  if (all_real_p)
+		    DO_SINGLE_TYPE_CONCAT (NDArray, array_value);
+		  else
+		    DO_SINGLE_TYPE_CONCAT (ComplexNDArray, complex_array_value);
+		}
+	    }
+	  else if (result_type == "single")
+	    {
+	      if (all_real_p)
+		DO_SINGLE_TYPE_CONCAT (FloatNDArray, float_array_value);
+	      else
+		DO_SINGLE_TYPE_CONCAT (FloatComplexNDArray, 
+				       float_complex_array_value);
+	    }
+	  else if (result_type == "char")
+	    {
+	      char type = all_dq_strings_p ? '"' : '\'';
+
+	      maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p);
+
+	      charNDArray result (dv, Vstring_fill_char);
+
+	      SINGLE_TYPE_CONCAT (charNDArray, char_array_value);
+
+	      retval = octave_value (result, true, type);
+	    }
+	  else if (result_type == "logical")
+	    {
+	      if (any_sparse_p)
+		DO_SINGLE_TYPE_CONCAT (SparseBoolMatrix, sparse_bool_matrix_value);
+	      else
+		DO_SINGLE_TYPE_CONCAT (boolNDArray, bool_array_value);
+	    }
+	  else if (result_type == "int8")
+	    DO_SINGLE_TYPE_CONCAT (int8NDArray, int8_array_value);
+	  else if (result_type == "int16")
+	    DO_SINGLE_TYPE_CONCAT (int16NDArray, int16_array_value);
+	  else if (result_type == "int32")
+	    DO_SINGLE_TYPE_CONCAT (int32NDArray, int32_array_value);
+	  else if (result_type == "int64")
+	    DO_SINGLE_TYPE_CONCAT (int64NDArray, int64_array_value);
+	  else if (result_type == "uint8")
+	    DO_SINGLE_TYPE_CONCAT (uint8NDArray, uint8_array_value);
+	  else if (result_type == "uint16")
+	    DO_SINGLE_TYPE_CONCAT (uint16NDArray, uint16_array_value);
+	  else if (result_type == "uint32")
+	    DO_SINGLE_TYPE_CONCAT (uint32NDArray, uint32_array_value);
+	  else if (result_type == "uint64")
+	    DO_SINGLE_TYPE_CONCAT (uint64NDArray, uint64_array_value);
+	  else
+	    {
+	      // The lines below might seem crazy, since we take a copy
+	      // of the first argument, resize it to be empty and then resize
+	      // it to be full. This is done since it means that there is no
+	      // recopying of data, as would happen if we used a single resize.
+	      // It should be noted that resize operation is also significantly 
+	      // slower than the do_cat_op function, so it makes sense to have
+	      // an empty matrix and copy all data.
+	      //
+	      // We might also start with a empty octave_value using
+	      //   tmp = octave_value_typeinfo::lookup_type 
+	      //                                (args(1).type_name());
+	      // and then directly resize. However, for some types there might
+	      // be some additional setup needed, and so this should be avoided.
+
+	      octave_value tmp = args (1);
+	      tmp = tmp.resize (dim_vector (0,0)).resize (dv);
+
+	      if (error_state)
+		return retval;
+
+	      int dv_len = dv.length ();
+	      Array<octave_idx_type> ra_idx (dv_len, 0);
+
+	      for (int j = 1; j < n_args; j++)
+		{
+		  // Can't fast return here to skip empty matrices as something
+		  // like cat(1,[],single([])) must return an empty matrix of
+		  // the right type.
+		  tmp = do_cat_op (tmp, args (j), ra_idx);
+
+		  if (error_state)
+		    return retval;
+
+		  dim_vector dv_tmp = args (j).dims ();
+
+		  if (dim >= dv_len)
+		    {
+		      if (j > 1)
+			error ("%s: indexing error", fname.c_str ());
+		      break;
+		    }
+		  else
+		    ra_idx (dim) += (dim < dv_tmp.length () ? 
+				     dv_tmp (dim) : 1);
+		}
+	      retval = tmp;
+	    }
+
+	  if (! error_state)
+	    {
+	      // Reshape, chopping trailing singleton dimensions
+	      dv.chop_trailing_singletons ();
+	      retval = retval.reshape (dv);
+	    }
+	}
+      else
+	error ("%s: invalid dimension argument", fname.c_str ());
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (horzcat, args, ,
+       "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} horzcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})\n\
+Return the horizontal concatenation of N-d array objects, @var{array1},\n\
+ at var{array2}, @dots{}, @var{arrayN} along dimension 2.\n\
+ at seealso{cat, vertcat}\n\
+ at end deftypefn")
+{
+  octave_value_list args_tmp = args;
+  
+  int dim = 2;
+  
+  octave_value d (dim);
+  
+  args_tmp.prepend (d);
+  
+  return do_cat (args_tmp, "horzcat");
+}
+
+DEFUN (vertcat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} vertcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})\n\
+Return the vertical concatenation of N-d array objects, @var{array1},\n\
+ at var{array2}, @dots{}, @var{arrayN} along dimension 1.\n\
+ at seealso{cat, horzcat}\n\
+ at end deftypefn")
+{
+  octave_value_list args_tmp = args;
+  
+  int dim = 1;
+  
+  octave_value d (dim);
+  
+  args_tmp.prepend (d);
+  
+  return do_cat (args_tmp, "vertcat");
+}
+
+DEFUN (cat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} cat (@var{dim}, @var{array1}, @var{array2}, @dots{}, @var{arrayN})\n\
+Return the concatenation of N-d array objects, @var{array1},\n\
+ at var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.\n\
+\n\
+ at example\n\
+ at group\n\
+A = ones (2, 2);\n\
+B = zeros (2, 2);\n\
+cat (2, A, B)\n\
+ at result{} ans =\n\
+\n\
+     1 1 0 0\n\
+     1 1 0 0\n\
+ at end group\n\
+ at end example\n\
+\n\
+Alternatively, we can concatenate @var{A} and @var{B} along the\n\
+second dimension the following way:\n\
+\n\
+ at example\n\
+ at group\n\
+[A, B].\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at var{dim} can be larger than the dimensions of the N-d array objects\n\
+and the result will thus have @var{dim} dimensions as the\n\
+following example shows:\n\
+ at example\n\
+ at group\n\
+cat (4, ones(2, 2), zeros (2, 2))\n\
+ at result{} ans =\n\
+\n\
+   ans(:,:,1,1) =\n\
+\n\
+     1 1\n\
+     1 1\n\
+\n\
+   ans(:,:,1,2) =\n\
+     0 0\n\
+     0 0\n\
+ at end group\n\
+ at end example\n\
+ at seealso{horzcat, vertcat}\n\
+ at end deftypefn")
+{
+  return do_cat (args, "cat");
+}
+
+/*
+
+%!function ret = testcat (t1, t2, tr, cmplx)
+%! assert (cat (1, cast ([], t1), cast([], t2)), cast ([], tr));
+%!
+%! assert (cat (1, cast (1, t1), cast (2, t2)), cast ([1; 2], tr));
+%! assert (cat (1, cast (1, t1), cast ([2; 3], t2)), cast ([1; 2; 3], tr));
+%! assert (cat (1, cast ([1; 2], t1), cast (3, t2)), cast ([1; 2; 3], tr));
+%! assert (cat (1, cast ([1; 2], t1), cast ([3; 4], t2)), cast ([1; 2; 3; 4], tr));
+%! assert (cat (2, cast (1, t1), cast (2, t2)), cast ([1, 2], tr));
+%! assert (cat (2, cast (1, t1), cast ([2, 3], t2)), cast ([1, 2, 3], tr));
+%! assert (cat (2, cast ([1, 2], t1), cast (3, t2)), cast ([1, 2, 3], tr));
+%! assert (cat (2, cast ([1, 2], t1), cast ([3, 4], t2)), cast ([1, 2, 3, 4], tr));
+%! 
+%! assert ([cast(1, t1); cast(2, t2)], cast ([1; 2], tr));
+%! assert ([cast(1, t1); cast([2; 3], t2)], cast ([1; 2; 3], tr));
+%! assert ([cast([1; 2], t1); cast(3, t2)], cast ([1; 2; 3], tr));
+%! assert ([cast([1; 2], t1); cast([3; 4], t2)], cast ([1; 2; 3; 4], tr));
+%! assert ([cast(1, t1), cast(2, t2)], cast ([1, 2], tr));
+%! assert ([cast(1, t1), cast([2, 3], t2)], cast ([1, 2, 3], tr));
+%! assert ([cast([1, 2], t1), cast(3, t2)], cast ([1, 2, 3], tr));
+%! assert ([cast([1, 2], t1), cast([3, 4], t2)], cast ([1, 2, 3, 4], tr));
+%!
+%! if (nargin == 3 || cmplx)
+%!   assert (cat (1, cast (1i, t1), cast (2, t2)), cast ([1i; 2], tr));
+%!   assert (cat (1, cast (1i, t1), cast ([2; 3], t2)), cast ([1i; 2; 3], tr));
+%!   assert (cat (1, cast ([1i; 2], t1), cast (3, t2)), cast ([1i; 2; 3], tr));
+%!   assert (cat (1, cast ([1i; 2], t1), cast ([3; 4], t2)), cast ([1i; 2; 3; 4], tr));
+%!   assert (cat (2, cast (1i, t1), cast (2, t2)), cast ([1i, 2], tr));
+%!   assert (cat (2, cast (1i, t1), cast ([2, 3], t2)), cast ([1i, 2, 3], tr));
+%!   assert (cat (2, cast ([1i, 2], t1), cast (3, t2)), cast ([1i, 2, 3], tr));
+%!   assert (cat (2, cast ([1i, 2], t1), cast ([3, 4], t2)), cast ([1i, 2, 3, 4], tr));
+%! 
+%!   assert ([cast(1i, t1); cast(2, t2)], cast ([1i; 2], tr));
+%!   assert ([cast(1i, t1); cast([2; 3], t2)], cast ([1i; 2; 3], tr));
+%!   assert ([cast([1i; 2], t1); cast(3, t2)], cast ([1i; 2; 3], tr));
+%!   assert ([cast([1i; 2], t1); cast([3; 4], t2)], cast ([1i; 2; 3; 4], tr));
+%!   assert ([cast(1i, t1), cast(2, t2)], cast ([1i, 2], tr));
+%!   assert ([cast(1i, t1), cast([2, 3], t2)], cast ([1i, 2, 3], tr));
+%!   assert ([cast([1i, 2], t1), cast(3, t2)], cast ([1i, 2, 3], tr));
+%!   assert ([cast([1i, 2], t1), cast([3, 4], t2)], cast ([1i, 2, 3, 4], tr));
+%!
+%!   assert (cat (1, cast (1, t1), cast (2i, t2)), cast ([1; 2i], tr));
+%!   assert (cat (1, cast (1, t1), cast ([2i; 3], t2)), cast ([1; 2i; 3], tr));
+%!   assert (cat (1, cast ([1; 2], t1), cast (3i, t2)), cast ([1; 2; 3i], tr));
+%!   assert (cat (1, cast ([1; 2], t1), cast ([3i; 4], t2)), cast ([1; 2; 3i; 4], tr));
+%!   assert (cat (2, cast (1, t1), cast (2i, t2)), cast ([1, 2i], tr));
+%!   assert (cat (2, cast (1, t1), cast ([2i, 3], t2)), cast ([1, 2i, 3], tr));
+%!   assert (cat (2, cast ([1, 2], t1), cast (3i, t2)), cast ([1, 2, 3i], tr));
+%!   assert (cat (2, cast ([1, 2], t1), cast ([3i, 4], t2)), cast ([1, 2, 3i, 4], tr));
+%! 
+%!   assert ([cast(1, t1); cast(2i, t2)], cast ([1; 2i], tr));
+%!   assert ([cast(1, t1); cast([2i; 3], t2)], cast ([1; 2i; 3], tr));
+%!   assert ([cast([1; 2], t1); cast(3i, t2)], cast ([1; 2; 3i], tr));
+%!   assert ([cast([1; 2], t1); cast([3i; 4], t2)], cast ([1; 2; 3i; 4], tr));
+%!   assert ([cast(1, t1), cast(2i, t2)], cast ([1, 2i], tr));
+%!   assert ([cast(1, t1), cast([2i, 3], t2)], cast ([1, 2i, 3], tr));
+%!   assert ([cast([1, 2], t1), cast(3i, t2)], cast ([1, 2, 3i], tr));
+%!   assert ([cast([1, 2], t1), cast([3i, 4], t2)], cast ([1, 2, 3i, 4], tr));
+%!
+%!   assert (cat (1, cast (1i, t1), cast (2i, t2)), cast ([1i; 2i], tr));
+%!   assert (cat (1, cast (1i, t1), cast ([2i; 3], t2)), cast ([1i; 2i; 3], tr));
+%!   assert (cat (1, cast ([1i; 2], t1), cast (3i, t2)), cast ([1i; 2; 3i], tr));
+%!   assert (cat (1, cast ([1i; 2], t1), cast ([3i; 4], t2)), cast ([1i; 2; 3i; 4], tr));
+%!   assert (cat (2, cast (1i, t1), cast (2i, t2)), cast ([1i, 2i], tr));
+%!   assert (cat (2, cast (1i, t1), cast ([2i, 3], t2)), cast ([1i, 2i, 3], tr));
+%!   assert (cat (2, cast ([1i, 2], t1), cast (3i, t2)), cast ([1i, 2, 3i], tr));
+%!   assert (cat (2, cast ([1i, 2], t1), cast ([3i, 4], t2)), cast ([1i, 2, 3i, 4], tr));
+%! 
+%!   assert ([cast(1i, t1); cast(2i, t2)], cast ([1i; 2i], tr));
+%!   assert ([cast(1i, t1); cast([2i; 3], t2)], cast ([1i; 2i; 3], tr));
+%!   assert ([cast([1i; 2], t1); cast(3i, t2)], cast ([1i; 2; 3i], tr));
+%!   assert ([cast([1i; 2], t1); cast([3i; 4], t2)], cast ([1i; 2; 3i; 4], tr));
+%!   assert ([cast(1i, t1), cast(2i, t2)], cast ([1i, 2i], tr));
+%!   assert ([cast(1i, t1), cast([2i, 3], t2)], cast ([1i, 2i, 3], tr));
+%!   assert ([cast([1i, 2], t1), cast(3i, t2)], cast ([1i, 2, 3i], tr));
+%!   assert ([cast([1i, 2], t1), cast([3i, 4], t2)], cast ([1i, 2, 3i, 4], tr));
+%! endif
+%! ret = true;
+
+%!assert (testcat('double', 'double', 'double'));
+%!assert (testcat('single', 'double', 'single'));
+%!assert (testcat('double', 'single', 'single'));
+%!assert (testcat('single', 'single', 'single'));
+
+%!assert (testcat('double', 'int8', 'int8', false));
+%!assert (testcat('int8', 'double', 'int8', false));
+%!assert (testcat('single', 'int8', 'int8', false));
+%!assert (testcat('int8', 'single', 'int8', false));
+%!assert (testcat('int8', 'int8', 'int8', false));
+%!assert (testcat('double', 'int16', 'int16', false));
+%!assert (testcat('int16', 'double', 'int16', false));
+%!assert (testcat('single', 'int16', 'int16', false));
+%!assert (testcat('int16', 'single', 'int16', false));
+%!assert (testcat('int16', 'int16', 'int16', false));
+%!assert (testcat('double', 'int32', 'int32', false));
+%!assert (testcat('int32', 'double', 'int32', false));
+%!assert (testcat('single', 'int32', 'int32', false));
+%!assert (testcat('int32', 'single', 'int32', false));
+%!assert (testcat('int32', 'int32', 'int32', false));
+%!assert (testcat('double', 'int64', 'int64', false));
+%!assert (testcat('int64', 'double', 'int64', false));
+%!assert (testcat('single', 'int64', 'int64', false));
+%!assert (testcat('int64', 'single', 'int64', false));
+%!assert (testcat('int64', 'int64', 'int64', false));
+
+%!assert (testcat('double', 'uint8', 'uint8', false));
+%!assert (testcat('uint8', 'double', 'uint8', false));
+%!assert (testcat('single', 'uint8', 'uint8', false));
+%!assert (testcat('uint8', 'single', 'uint8', false));
+%!assert (testcat('uint8', 'uint8', 'uint8', false));
+%!assert (testcat('double', 'uint16', 'uint16', false));
+%!assert (testcat('uint16', 'double', 'uint16', false));
+%!assert (testcat('single', 'uint16', 'uint16', false));
+%!assert (testcat('uint16', 'single', 'uint16', false));
+%!assert (testcat('uint16', 'uint16', 'uint16', false));
+%!assert (testcat('double', 'uint32', 'uint32', false));
+%!assert (testcat('uint32', 'double', 'uint32', false));
+%!assert (testcat('single', 'uint32', 'uint32', false));
+%!assert (testcat('uint32', 'single', 'uint32', false));
+%!assert (testcat('uint32', 'uint32', 'uint32', false));
+%!assert (testcat('double', 'uint64', 'uint64', false));
+%!assert (testcat('uint64', 'double', 'uint64', false));
+%!assert (testcat('single', 'uint64', 'uint64', false));
+%!assert (testcat('uint64', 'single', 'uint64', false));
+%!assert (testcat('uint64', 'uint64', 'uint64', false));
+
+*/
+
+static octave_value
+do_permute (const octave_value_list& args, bool inv)
+{
+  octave_value retval;
+
+  if (args.length () == 2 && args(1).length () >= args(1).ndims ())
+    {
+      Array<int> vec = args(1).int_vector_value ();
+
+      // FIXME -- maybe we should create an idx_vector object
+      // here and pass that to permute?
+
+      int n = vec.length ();
+
+      for (int i = 0; i < n; i++)
+	vec(i)--;
+
+      octave_value ret = args(0).permute (vec, inv);
+
+      if (! error_state)
+	retval = ret;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (permute, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} permute (@var{a}, @var{perm})\n\
+Return the generalized transpose for an N-d array object @var{a}.\n\
+The permutation vector @var{perm} must contain the elements\n\
+ at code{1:ndims(a)} (in any order, but each element must appear just once).\n\
+ at seealso{ipermute}\n\
+ at end deftypefn")
+{
+  return do_permute (args, false);
+}
+
+DEFUN (ipermute, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ipermute (@var{a}, @var{iperm})\n\
+The inverse of the @code{permute} function.  The expression\n\
+\n\
+ at example\n\
+ipermute (permute (a, perm), perm)\n\
+ at end example\n\
+returns the original array @var{a}.\n\
+ at seealso{permute}\n\
+ at end deftypefn")
+{
+  return do_permute (args, true);
+}
+
+DEFUN (length, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} length (@var{a})\n\
+Return the `length' of the object @var{a}.  For matrix objects, the\n\
+length is the number of rows or columns, whichever is greater (this\n\
+odd definition is used for compatibility with @sc{matlab}).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      int len = args(0).length ();
+
+      if (! error_state)
+	retval = len;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (ndims, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ndims (@var{a})\n\
+Returns the number of dimensions of array @var{a}.\n\
+For any array, the result will always be larger than or equal to 2.\n\
+Trailing singleton dimensions are not counted.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      int n_dims = args(0).ndims ();
+
+      if (! error_state)
+	retval = n_dims;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (numel, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} numel (@var{a})\n\
+Returns the number of elements in the object @var{a}.\n\
+ at seealso{size}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      int numel = args(0).numel ();
+
+      if (! error_state)
+	{
+	  if (numel < 0)
+	    numel = 0;
+
+	  retval = numel;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (size, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} size (@var{a}, @var{n})\n\
+Return the number rows and columns of @var{a}.\n\
+\n\
+With one input argument and one output argument, the result is returned\n\
+in a row vector.  If there are multiple output arguments, the number of\n\
+rows is assigned to the first, and the number of columns to the second,\n\
+etc.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+size ([1, 2; 3, 4; 5, 6])\n\
+     @result{} [ 3, 2 ]\n\
+\n\
+[nr, nc] = size ([1, 2; 3, 4; 5, 6])\n\
+     @result{} nr = 3\n\
+     @result{} nc = 2\n\
+ at end group\n\
+ at end example\n\
+\n\
+If given a second argument, @code{size} will return the size of the\n\
+corresponding dimension.  For example\n\
+\n\
+ at example\n\
+ at group\n\
+size ([1, 2; 3, 4; 5, 6], 2)\n\
+     @result{} 2\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns the number of columns in the given matrix.\n\
+ at seealso{numel}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      dim_vector dimensions = args(0).dims ();
+
+      int ndims = dimensions.length ();
+
+      Matrix m (1, ndims);
+
+      if (nargout > 1)
+	{
+	  for (int i = nargout-1; i >= ndims; i--)
+	    retval(i) = 1;
+
+	  if (ndims > nargout)
+	    {
+	      octave_idx_type d = 1;
+
+	      while (ndims >= nargout)
+		d *= dimensions(--ndims);
+	      
+	      retval(ndims) = d;
+	    }
+
+	  while (ndims--)
+	    retval(ndims) = dimensions(ndims);
+	}
+      else
+	{
+	  for (int i = 0; i < ndims; i++)
+	    m(0, i) = dimensions(i);
+
+	  retval(0) = m;
+	}
+    }
+  else if (nargin == 2 && nargout < 2)
+    {
+      octave_idx_type nd = args(1).int_value (true);
+
+      if (error_state)
+	error ("size: expecting scalar as second argument");
+      else
+	{
+	  dim_vector dv = args(0).dims ();
+
+	  if (nd > 0)
+	    {
+	      if (nd <= dv.length ())
+		retval(0) = dv(nd-1);
+	      else 
+		retval(0) = 1;
+	    }
+	  else
+	    error ("size: requested dimension (= %d) out of range", nd);
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (size_equal, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} size_equal (@var{a}, @var{b}, @dots{})\n\
+Return true if the dimensions of all arguments agree.\n\
+Trailing singleton dimensions are ignored.\n\
+Called with a single argument, size_equal returns true.\n\
+ at seealso{size, numel}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin >= 1)
+    {
+      retval = true;
+
+      dim_vector a_dims = args(0).dims ();
+      a_dims.chop_trailing_singletons ();
+
+      for (int i = 1; i < nargin; ++i)
+        {
+          dim_vector b_dims = args(i).dims ();
+          b_dims.chop_trailing_singletons ();
+
+          if (a_dims != b_dims)
+	    {
+	      retval = false;
+	      break;
+	    }
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (nnz, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{scalar} =} nnz (@var{a})\n\
+Returns the number of non zero elements in @var{a}.\n\
+ at seealso{sparse}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).nnz ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (nzmax, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{scalar} =} nzmax (@var{SM})\n\
+Return the amount of storage allocated to the sparse matrix @var{SM}.\n\
+Note that Octave tends to crop unused memory at the first opportunity\n\
+for sparse objects.  There are some cases of user created sparse objects\n\
+where the value returned by @dfn{nzmax} will not be the same as @dfn{nnz},\n\
+but in general they will give the same result.\n\
+ at seealso{sparse, spalloc}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length() == 1)
+    retval = args(0).nzmax ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (rows, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rows (@var{a})\n\
+Return the number of rows of @var{a}.\n\
+ at seealso{size, numel, columns, length, isscalar, isvector, ismatrix}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).rows ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (columns, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} columns (@var{a})\n\
+Return the number of columns of @var{a}.\n\
+ at seealso{size, numel, rows, length, isscalar, isvector, ismatrix}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).columns ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (sum, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} sum (@var{x})\n\
+ at deftypefnx {Built-in Function} {} sum (@var{x}, @var{dim})\n\
+ at deftypefnx {Built-in Function} {} sum (@dots{}, 'native')\n\
+Sum of elements along dimension @var{dim}.  If @var{dim} is\n\
+omitted, it defaults to 1 (column-wise sum).\n\
+\n\
+As a special case, if @var{x} is a vector and @var{dim} is omitted,\n\
+return the sum of the elements.\n\
+\n\
+If the optional argument 'native' is given, then the sum is performed\n\
+in the same type as the original argument, rather than in the default\n\
+double type.  For example\n\
+\n\
+ at example\n\
+ at group\n\
+sum ([true, true])\n\
+  @result{} 2\n\
+sum ([true, true], 'native')\n\
+  @result{} true\n\
+ at end group\n\
+ at end example\n\
+ at seealso{cumsum, sumsq, prod}\n\
+ at end deftypefn")
+{
+  NATIVE_REDUCTION (sum, any);
+}
+
+/*
+
+%!assert (sum([true,true]), 2)
+%!assert (sum([true,true],'native'), true)
+%!assert (sum(int8([127,10,-20])), 117);
+%!assert (sum(int8([127,10,-20]),'native'), int8(107));
+
+%!assert(sum ([1, 2, 3]), 6)
+%!assert(sum ([-1; -2; -3]), -6);
+%!assert(sum ([i, 2+i, -3+2i, 4]), 3+4i);
+%!assert(sum ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), [2+2i, 4+4i, 6+6i]);
+
+%!assert(sum (single([1, 2, 3])), single(6))
+%!assert(sum (single([-1; -2; -3])), single(-6));
+%!assert(sum (single([i, 2+i, -3+2i, 4])), single(3+4i));
+%!assert(sum (single([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])), single([2+2i, 4+4i, 6+6i]));
+
+%!error <Invalid call to sum.*> sum ();
+
+%!assert (sum ([1, 2; 3, 4], 1), [4, 6]);
+%!assert (sum ([1, 2; 3, 4], 2), [3; 7]);
+%!assert (sum (zeros (1, 0)), 0);
+%!assert (sum (zeros (1, 0), 1), zeros(1, 0));
+%!assert (sum (zeros (1, 0), 2), 0);
+%!assert (sum (zeros (0, 1)), 0);
+%!assert (sum (zeros (0, 1), 1), 0);
+%!assert (sum (zeros (0, 1), 2), zeros(0, 1));
+%!assert (sum (zeros (2, 0)),  zeros(1, 0));
+%!assert (sum (zeros (2, 0), 1), zeros(1, 0));
+%!assert (sum (zeros (2, 0), 2),  [0; 0]);
+%!assert (sum (zeros (0, 2)), [0, 0]);
+%!assert (sum (zeros (0, 2), 1), [0, 0]);
+%!assert (sum (zeros (0, 2), 2), zeros(0, 1));
+%!assert (sum (zeros (2, 2, 0, 3)), zeros(1, 2, 0, 3));
+%!assert (sum (zeros (2, 2, 0, 3), 2), zeros(2, 1, 0, 3));
+%!assert (sum (zeros (2, 2, 0, 3), 3), zeros(2, 2, 1, 3));
+%!assert (sum (zeros (2, 2, 0, 3), 4), zeros(2, 2, 0));
+%!assert (sum (zeros (2, 2, 0, 3), 7), zeros(2, 2, 0, 3));
+
+%!assert (sum (single([1, 2; 3, 4]), 1), single([4, 6]));
+%!assert (sum (single([1, 2; 3, 4]), 2), single([3; 7]));
+%!assert (sum (zeros (1, 0, 'single')), single(0));
+%!assert (sum (zeros (1, 0, 'single'), 1), zeros(1, 0, 'single'));
+%!assert (sum (zeros (1, 0, 'single'), 2), single(0));
+%!assert (sum (zeros (0, 1, 'single')), single(0));
+%!assert (sum (zeros (0, 1, 'single'), 1), single(0));
+%!assert (sum (zeros (0, 1, 'single'), 2), zeros(0, 1, 'single'));
+%!assert (sum (zeros (2, 0, 'single')),  zeros(1, 0, 'single'));
+%!assert (sum (zeros (2, 0, 'single'), 1), zeros(1, 0, 'single'));
+%!assert (sum (zeros (2, 0, 'single'), 2),  single([0; 0]));
+%!assert (sum (zeros (0, 2, 'single')), single([0, 0]));
+%!assert (sum (zeros (0, 2, 'single'), 1), single([0, 0]));
+%!assert (sum (zeros (0, 2, 'single'), 2), zeros(0, 1, 'single'));
+%!assert (sum (zeros (2, 2, 0, 3, 'single')), zeros(1, 2, 0, 3, 'single'));
+%!assert (sum (zeros (2, 2, 0, 3, 'single'), 2), zeros(2, 1, 0, 3, 'single'));
+%!assert (sum (zeros (2, 2, 0, 3, 'single'), 3), zeros(2, 2, 1, 3, 'single'));
+%!assert (sum (zeros (2, 2, 0, 3, 'single'), 4), zeros(2, 2, 0, 'single'));
+%!assert (sum (zeros (2, 2, 0, 3, 'single'), 7), zeros(2, 2, 0, 3, 'single'));
+
+*/
+
+DEFUN (sumsq, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} sumsq (@var{x})\n\
+ at deftypefnx {Built-in Function} {} sumsq (@var{x}, @var{dim})\n\
+Sum of squares of elements along dimension @var{dim}.  If @var{dim}\n\
+is omitted, it defaults to 1 (column-wise sum of squares).\n\
+\n\
+As a special case, if @var{x} is a vector and @var{dim} is omitted,\n\
+return the sum of squares of the elements.\n\
+\n\
+This function is conceptually equivalent to computing\n\
+ at example\n\
+sum (x .* conj (x), dim)\n\
+ at end example\n\
+but it uses less memory and avoids calling @code{conj} if @var{x} is real.\n\
+ at seealso{sum}\n\
+ at end deftypefn")
+{
+  DATA_REDUCTION (sumsq);
+}
+
+/*
+
+%!assert(sumsq ([1, 2, 3]), 14)
+%!assert(sumsq ([-1; -2; 4i]), 21);
+%!assert(sumsq ([1, 2, 3; 2, 3, 4; 4i, 6i, 2]), [21, 49, 29]);
+
+%!assert(sumsq (single([1, 2, 3])), single(14))
+%!assert(sumsq (single([-1; -2; 4i])), single(21));
+%!assert(sumsq (single([1, 2, 3; 2, 3, 4; 4i, 6i, 2])), single([21, 49, 29]));
+
+%!error <Invalid call to sumsq.*> sumsq ();
+
+%!assert (sumsq ([1, 2; 3, 4], 1), [10, 20]);
+%!assert (sumsq ([1, 2; 3, 4], 2), [5; 25]);
+
+%!assert (sumsq (single([1, 2; 3, 4]), 1), single([10, 20]));
+%!assert (sumsq (single([1, 2; 3, 4]), 2), single([5; 25]));
+
+ */
+
+DEFUN (islogical, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} islogical (@var{x})\n\
+Return true if @var{x} is a logical object.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_bool_type ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFALIAS (isbool, islogical);
+
+/*
+
+%!assert (islogical(true), true)
+%!assert (islogical(false), true)
+%!assert (islogical([true, false]), true)
+%!assert (islogical(1), false)
+%!assert (islogical(1i), false)
+%!assert (islogical([1,1]), false)
+%!assert (islogical(single(1)), false)
+%!assert (islogical(single(1i)), false)
+%!assert (islogical(single([1,1])), false)
+
+ */
+
+DEFUN (isinteger, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isinteger (@var{x})\n\
+Return true if @var{x} is an integer object (int8, uint8, int16, etc.).\n\
+Note that @code{isinteger (14)} is false because numeric constants in\n\
+Octave are double precision floating point values.\n\
+ at seealso{isreal, isnumeric, class, isa}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_integer_type ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (iscomplex, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} iscomplex (@var{x})\n\
+Return true if @var{x} is a complex-valued numeric object.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_complex_type ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isfloat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isfloat (@var{x})\n\
+Return true if @var{x} is a floating-point numeric object.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_float_type ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// FIXME -- perhaps this should be implemented with an
+// octave_value member function?
+
+DEFUN (complex, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} complex (@var{x})\n\
+ at deftypefnx {Built-in Function} {} complex (@var{re}, @var{im})\n\
+Return a complex result from real arguments.  With 1 real argument @var{x},\n\
+return the complex result @code{@var{x} + 0i}.  With 2 real arguments,\n\
+return the complex result @code{@var{re} + @var{im}}.  @code{complex} can\n\
+often be more convenient than expressions such as @code{a + i*b}.\n\
+For example:\n\
+\n\
+ at example\n\
+complex ([1, 2], [3, 4])\n\
+ at result{}\n\
+   1 + 3i   2 + 4i\n\
+ at end example\n\
+ at seealso{real, imag, iscomplex}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+
+      if (arg.is_complex_type ())
+	retval = arg;
+      else
+	{
+	  if (arg.is_sparse_type ())
+	    {
+	      SparseComplexMatrix val = arg.sparse_complex_matrix_value ();
+
+	      if (! error_state)
+		retval = octave_value (new octave_sparse_complex_matrix (val));
+	    }
+	  else if (arg.is_single_type ())
+	    {
+	      if (arg.numel () == 1)
+		{
+		  FloatComplex val = arg.float_complex_value ();
+
+		  if (! error_state)
+		    retval = octave_value (new octave_float_complex (val));
+		}
+	      else
+		{
+		  FloatComplexNDArray val = arg.float_complex_array_value ();
+
+		  if (! error_state)
+		    retval = octave_value (new octave_float_complex_matrix (val));
+		}
+	    }
+	  else
+	    {
+	      if (arg.numel () == 1)
+		{
+		  Complex val = arg.complex_value ();
+
+		  if (! error_state)
+		    retval = octave_value (new octave_complex (val));
+		}
+	      else
+		{
+		  ComplexNDArray val = arg.complex_array_value ();
+
+		  if (! error_state)
+		    retval = octave_value (new octave_complex_matrix (val));
+		}
+	    }
+
+	  if (error_state)
+	    error ("complex: invalid conversion");
+	}
+    }
+  else if (nargin == 2)
+    {
+      octave_value re = args(0);
+      octave_value im = args(1);
+
+      if (re.is_sparse_type () && im.is_sparse_type ())
+	{
+	  const SparseMatrix re_val = re.sparse_matrix_value ();
+	  const SparseMatrix im_val = im.sparse_matrix_value ();
+
+	  if (!error_state)
+	    {
+	      if (re.numel () == 1)
+		{
+		  SparseComplexMatrix result;
+		  if (re_val.nnz () == 0)
+		    result = Complex(0, 1) * SparseComplexMatrix (im_val);
+		  else
+		    {
+		      result = SparseComplexMatrix (im_val.dims (), re_val (0));
+		      octave_idx_type nr = im_val.rows ();
+		      octave_idx_type nc = im_val.cols ();
+
+		      for (octave_idx_type j = 0; j < nc; j++)
+			{
+			  octave_idx_type off = j * nr;
+			  for (octave_idx_type i = im_val.cidx(j); 
+			       i < im_val.cidx(j + 1); i++)
+			    result.data (im_val.ridx(i) + off) =  
+			      result.data (im_val.ridx(i) + off) + 
+			      Complex (0, im_val.data (i));
+			}
+		    }
+		  retval = octave_value (new octave_sparse_complex_matrix (result));
+		}
+	      else if (im.numel () == 1)
+		{
+		  SparseComplexMatrix result;
+		  if (im_val.nnz () == 0)
+		    result = SparseComplexMatrix (re_val);
+		  else
+		    {
+		      result = SparseComplexMatrix (re_val.rows(), re_val.cols(), Complex(0, im_val (0)));
+		      octave_idx_type nr = re_val.rows ();
+		      octave_idx_type nc = re_val.cols ();
+
+		      for (octave_idx_type j = 0; j < nc; j++)
+			{
+			  octave_idx_type off = j * nr;
+			  for (octave_idx_type i = re_val.cidx(j); 
+			       i < re_val.cidx(j + 1); i++)
+			    result.data (re_val.ridx(i) + off) =  
+			      result.data (re_val.ridx(i) + off) + 
+			      re_val.data (i);
+			}
+		    }
+		  retval = octave_value (new octave_sparse_complex_matrix (result));
+		}
+	      else
+		{
+		  if (re_val.dims () == im_val.dims ())
+		    {
+		      SparseComplexMatrix result = SparseComplexMatrix(re_val) 
+			+ Complex(0, 1) * SparseComplexMatrix (im_val);
+		      retval = octave_value (new octave_sparse_complex_matrix (result));
+		    }
+		  else
+		    error ("complex: dimension mismatch");
+		}
+	    }
+	}
+      else if (re.is_single_type () || im.is_single_type ())
+	{
+	  if (re.numel () == 1)
+	    {
+	      float re_val = re.float_value ();
+
+	      if (im.numel () == 1)
+		{
+		  float im_val = im.double_value ();
+
+		  if (! error_state)
+		    retval = octave_value (new octave_float_complex (FloatComplex (re_val, im_val)));
+		}
+	      else
+		{
+		  const FloatNDArray im_val = im.float_array_value ();
+
+		  if (! error_state)
+		    {
+		      FloatComplexNDArray result (im_val.dims (), FloatComplex ());
+
+		      for (octave_idx_type i = 0; i < im_val.numel (); i++)
+			result.xelem (i) = FloatComplex (re_val, im_val(i));
+
+		      retval = octave_value (new octave_float_complex_matrix (result));
+		    }
+		}
+	    }
+	  else
+	    {
+	      const FloatNDArray re_val = re.float_array_value ();
+
+	      if (im.numel () == 1)
+		{
+		  float im_val = im.float_value ();
+
+		  if (! error_state)
+		    {
+		      FloatComplexNDArray result (re_val.dims (), FloatComplex ());
+
+		      for (octave_idx_type i = 0; i < re_val.numel (); i++)
+			result.xelem (i) = FloatComplex (re_val(i), im_val);
+
+		      retval = octave_value (new octave_float_complex_matrix (result));
+		    }
+		}
+	      else
+		{
+		  const FloatNDArray im_val = im.float_array_value ();
+
+		  if (! error_state)
+		    {
+		      if (re_val.dims () == im_val.dims ())
+			{
+			  FloatComplexNDArray result (re_val.dims (), FloatComplex ());
+
+			  for (octave_idx_type i = 0; i < re_val.numel (); i++)
+			    result.xelem (i) = FloatComplex (re_val(i), im_val(i));
+
+			  retval = octave_value (new octave_float_complex_matrix (result));
+			}
+		      else
+			error ("complex: dimension mismatch");
+		    }
+		}
+	    }
+	}
+      else if (re.numel () == 1)
+	{
+	  double re_val = re.double_value ();
+
+	  if (im.numel () == 1)
+	    {
+	      double im_val = im.double_value ();
+
+	      if (! error_state)
+		retval = octave_value (new octave_complex (Complex (re_val, im_val)));
+	    }
+	  else
+	    {
+	      const NDArray im_val = im.array_value ();
+
+	      if (! error_state)
+		{
+		  ComplexNDArray result (im_val.dims (), Complex ());
+
+		  for (octave_idx_type i = 0; i < im_val.numel (); i++)
+		    result.xelem (i) = Complex (re_val, im_val(i));
+
+		  retval = octave_value (new octave_complex_matrix (result));
+		}
+	    }
+	}
+      else
+	{
+	  const NDArray re_val = re.array_value ();
+
+	  if (im.numel () == 1)
+	    {
+	      double im_val = im.double_value ();
+
+	      if (! error_state)
+		{
+		  ComplexNDArray result (re_val.dims (), Complex ());
+
+		  for (octave_idx_type i = 0; i < re_val.numel (); i++)
+		    result.xelem (i) = Complex (re_val(i), im_val);
+
+		  retval = octave_value (new octave_complex_matrix (result));
+		}
+	    }
+	  else
+	    {
+	      const NDArray im_val = im.array_value ();
+
+	      if (! error_state)
+		{
+		  if (re_val.dims () == im_val.dims ())
+		    {
+		      ComplexNDArray result (re_val.dims (), Complex ());
+
+		      for (octave_idx_type i = 0; i < re_val.numel (); i++)
+			result.xelem (i) = Complex (re_val(i), im_val(i));
+
+		      retval = octave_value (new octave_complex_matrix (result));
+		    }
+		  else
+		    error ("complex: dimension mismatch");
+		}
+	    }
+	}
+
+      if (error_state)
+	error ("complex: invalid conversion");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isreal, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isreal (@var{x})\n\
+Return true if @var{x} is a real-valued numeric object.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_real_type ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isempty, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isempty (@var{a})\n\
+Return 1 if @var{a} is an empty matrix (either the number of rows, or\n\
+the number of columns, or both are zero).  Otherwise, return 0.\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    retval = args(0).is_empty ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isnumeric, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isnumeric (@var{x})\n\
+Return nonzero if @var{x} is a numeric object.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_numeric_type ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (islist, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} islist (@var{x})\n\
+Return nonzero if @var{x} is a list.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_list ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (ismatrix, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ismatrix (@var{a})\n\
+Return 1 if @var{a} is a matrix.  Otherwise, return 0.\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      octave_value arg = args(0);
+
+      if (arg.is_scalar_type () || arg.is_range ())
+	retval = true;
+      else if (arg.is_matrix_type ())
+	retval = (arg.rows () >= 1 && arg.columns () >= 1);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(ismatrix (1));
+%!assert(ismatrix ([1, 2, 3]));
+%!assert(ismatrix ([1, 2; 3, 4]));
+
+%% Yes, this is right, ismatrix() checks for non-empty matrices.
+%!assert(ismatrix ([]), false);
+
+%!assert(ismatrix (single(1)));
+%!assert(ismatrix (single([1, 2, 3])));
+%!assert(ismatrix (single([1, 2; 3, 4])));
+
+%% Yes, this is right, ismatrix() checks for non-empty matrices.
+%!assert(ismatrix (single([])), false);
+
+%!assert(ismatrix ("t"), false);
+%!assert(ismatrix ("test"), false);
+%!assert(ismatrix (["test"; "ing"]), false);
+
+%!test
+%! s.a = 1;
+%! assert(ismatrix (s), false);
+
+%!error <Invalid call to ismatrix.*> ismatrix ();
+%!error <Invalid call to ismatrix.*> ismatrix ([1, 2; 3, 4], 2);
+
+ */
+
+static octave_value
+fill_matrix (const octave_value_list& args, int val, const char *fcn)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  oct_data_conv::data_type dt = oct_data_conv::dt_double;
+
+  dim_vector dims (1, 1);
+  
+  if (nargin > 0 && args(nargin-1).is_string ())
+    {
+      std::string nm = args(nargin-1).string_value ();
+      nargin--;
+
+      dt = oct_data_conv::string_to_data_type (nm);
+
+      if (error_state)
+	return retval;
+    }
+
+  switch (nargin)
+    {
+    case 0:
+      break;
+
+    case 1:
+      get_dimensions (args(0), fcn, dims);
+      break;
+
+    default:
+      {
+	dims.resize (nargin);
+
+	for (int i = 0; i < nargin; i++)
+	  {
+	    dims(i) = args(i).is_empty () ? 0 : args(i).idx_type_value ();
+
+	    if (error_state)
+	      {
+		error ("%s: expecting scalar integer arguments", fcn);
+		break;
+	      }
+	  }
+      }
+      break;
+    }
+
+  if (! error_state)
+    {
+      dims.chop_trailing_singletons ();
+
+      check_dimensions (dims, fcn);
+
+      // FIXME -- perhaps this should be made extensible by
+      // using the class name to lookup a function to call to create
+      // the new value.
+
+      // Note that automatic narrowing will handle conversion from
+      // NDArray to scalar.
+
+      if (! error_state)
+	{
+	  switch (dt)
+	    {
+	    case oct_data_conv::dt_int8:
+	      retval = int8NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_uint8:
+	      retval = uint8NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_int16:
+	      retval = int16NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_uint16:
+	      retval = uint16NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_int32:
+	      retval = int32NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_uint32:
+	      retval = uint32NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_int64:
+	      retval = int64NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_uint64:
+	      retval = uint64NDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_single:
+	      retval = FloatNDArray (dims, val);
+	      break;
+
+	    case oct_data_conv::dt_double:
+              {
+                if (val == 1 && dims.length () == 2 && dims (0) == 1)
+                  retval = Range (1.0, 0.0, dims (1)); // packed form
+                else
+                  retval = NDArray (dims, val);
+              }
+	      break;
+
+	    case oct_data_conv::dt_logical:
+	      retval = boolNDArray (dims, val);
+	      break;
+
+	    default:
+	      error ("%s: invalid class name", fcn);
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_value
+fill_matrix (const octave_value_list& args, double val, float fval, 
+	     const char *fcn)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  oct_data_conv::data_type dt = oct_data_conv::dt_double;
+
+  dim_vector dims (1, 1);
+  
+  if (nargin > 0 && args(nargin-1).is_string ())
+    {
+      std::string nm = args(nargin-1).string_value ();
+      nargin--;
+
+      dt = oct_data_conv::string_to_data_type (nm);
+
+      if (error_state)
+	return retval;
+    }
+
+  switch (nargin)
+    {
+    case 0:
+      break;
+
+    case 1:
+      get_dimensions (args(0), fcn, dims);
+      break;
+
+    default:
+      {
+	dims.resize (nargin);
+
+	for (int i = 0; i < nargin; i++)
+	  {
+	    dims(i) = args(i).is_empty () ? 0 : args(i).idx_type_value ();
+
+	    if (error_state)
+	      {
+		error ("%s: expecting scalar integer arguments", fcn);
+		break;
+	      }
+	  }
+      }
+      break;
+    }
+
+  if (! error_state)
+    {
+      dims.chop_trailing_singletons ();
+
+      check_dimensions (dims, fcn);
+
+      // Note that automatic narrowing will handle conversion from
+      // NDArray to scalar.
+
+      if (! error_state)
+	{
+	  switch (dt)
+	    {
+	    case oct_data_conv::dt_single:
+	      retval = FloatNDArray (dims, fval);
+	      break;
+
+	    case oct_data_conv::dt_double:
+	      retval = NDArray (dims, val);
+	      break;
+
+	    default:
+	      error ("%s: invalid class name", fcn);
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_value
+fill_matrix (const octave_value_list& args, double val, const char *fcn)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  oct_data_conv::data_type dt = oct_data_conv::dt_double;
+
+  dim_vector dims (1, 1);
+  
+  if (nargin > 0 && args(nargin-1).is_string ())
+    {
+      std::string nm = args(nargin-1).string_value ();
+      nargin--;
+
+      dt = oct_data_conv::string_to_data_type (nm);
+
+      if (error_state)
+	return retval;
+    }
+
+  switch (nargin)
+    {
+    case 0:
+      break;
+
+    case 1:
+      get_dimensions (args(0), fcn, dims);
+      break;
+
+    default:
+      {
+	dims.resize (nargin);
+
+	for (int i = 0; i < nargin; i++)
+	  {
+	    dims(i) = args(i).is_empty () ? 0 : args(i).idx_type_value ();
+
+	    if (error_state)
+	      {
+		error ("%s: expecting scalar integer arguments", fcn);
+		break;
+	      }
+	  }
+      }
+      break;
+    }
+
+  if (! error_state)
+    {
+      dims.chop_trailing_singletons ();
+
+      check_dimensions (dims, fcn);
+
+      // Note that automatic narrowing will handle conversion from
+      // NDArray to scalar.
+
+      if (! error_state)
+	{
+	  switch (dt)
+	    {
+	    case oct_data_conv::dt_single:
+	      retval = FloatNDArray (dims, static_cast <float> (val));
+	      break;
+
+	    case oct_data_conv::dt_double:
+	      retval = NDArray (dims, val);
+	      break;
+
+	    default:
+	      error ("%s: invalid class name", fcn);
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_value
+fill_matrix (const octave_value_list& args, const Complex& val,
+	     const char *fcn)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  oct_data_conv::data_type dt = oct_data_conv::dt_double;
+
+  dim_vector dims (1, 1);
+  
+  if (nargin > 0 && args(nargin-1).is_string ())
+    {
+      std::string nm = args(nargin-1).string_value ();
+      nargin--;
+
+      dt = oct_data_conv::string_to_data_type (nm);
+
+      if (error_state)
+	return retval;
+    }
+
+  switch (nargin)
+    {
+    case 0:
+      break;
+
+    case 1:
+      get_dimensions (args(0), fcn, dims);
+      break;
+
+    default:
+      {
+	dims.resize (nargin);
+
+	for (int i = 0; i < nargin; i++)
+	  {
+	    dims(i) = args(i).is_empty () ? 0 : args(i).idx_type_value ();
+
+	    if (error_state)
+	      {
+		error ("%s: expecting scalar integer arguments", fcn);
+		break;
+	      }
+	  }
+      }
+      break;
+    }
+
+  if (! error_state)
+    {
+      dims.chop_trailing_singletons ();
+
+      check_dimensions (dims, fcn);
+
+      // Note that automatic narrowing will handle conversion from
+      // NDArray to scalar.
+
+      if (! error_state)
+	{
+	  switch (dt)
+	    {
+	    case oct_data_conv::dt_single:
+	      retval = FloatComplexNDArray (dims, static_cast<FloatComplex> (val));
+	      break;
+
+	    case oct_data_conv::dt_double:
+	      retval = ComplexNDArray (dims, val);
+	      break;
+
+	    default:
+	      error ("%s: invalid class name", fcn);
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_value
+fill_matrix (const octave_value_list& args, bool val, const char *fcn)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  dim_vector dims (1, 1);
+  
+  switch (nargin)
+    {
+    case 0:
+      break;
+
+    case 1:
+      get_dimensions (args(0), fcn, dims);
+      break;
+
+    default:
+      {
+	dims.resize (nargin);
+
+	for (int i = 0; i < nargin; i++)
+	  {
+	    dims(i) = args(i).is_empty () ? 0 : args(i).idx_type_value ();
+
+	    if (error_state)
+	      {
+		error ("%s: expecting scalar integer arguments", fcn);
+		break;
+	      }
+	  }
+      }
+      break;
+    }
+
+  if (! error_state)
+    {
+      dims.chop_trailing_singletons ();
+
+      check_dimensions (dims, fcn);
+
+      // Note that automatic narrowing will handle conversion from
+      // NDArray to scalar.
+
+      if (! error_state)
+	retval = boolNDArray (dims, val);
+    }
+
+  return retval;
+}
+
+DEFUN (ones, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ones (@var{x})\n\
+ at deftypefnx {Built-in Function} {} ones (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} ones (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} ones (@dots{}, @var{class})\n\
+Return a matrix or N-dimensional array whose elements are all 1.\n\
+The arguments are handled the same as the arguments for @code{eye}.\n\
+\n\
+If you need to create a matrix whose values are all the same, you should\n\
+use an expression like\n\
+\n\
+ at example\n\
+val_matrix = val * ones (n, m)\n\
+ at end example\n\
+\n\
+The optional argument @var{class}, allows @code{ones} to return an array of\n\
+the specified type, for example\n\
+\n\
+ at example\n\
+val = ones (n,m, \"uint8\")\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, 1, "ones");
+}
+
+/*
+
+%!assert(ones (3), [1, 1, 1; 1, 1, 1; 1, 1, 1]);
+%!assert(ones (2, 3), [1, 1, 1; 1, 1, 1]);
+%!assert(ones (3, 2), [1, 1; 1, 1; 1, 1]);
+%!assert(size (ones (3, 4, 5)),  [3, 4, 5]);
+
+%!assert(ones (3,'single'), single([1, 1, 1; 1, 1, 1; 1, 1, 1]));
+%!assert(ones (2, 3,'single'), single([1, 1, 1; 1, 1, 1]));
+%!assert(ones (3, 2,'single'), single([1, 1; 1, 1; 1, 1]));
+%!assert(size (ones (3, 4, 5, 'single')),  [3, 4, 5]);
+
+%!assert(ones (3,'int8'), int8([1, 1, 1; 1, 1, 1; 1, 1, 1]));
+%!assert(ones (2, 3,'int8'), int8([1, 1, 1; 1, 1, 1]));
+%!assert(ones (3, 2,'int8'), int8([1, 1; 1, 1; 1, 1]));
+%!assert(size (ones (3, 4, 5, 'int8')),  [3, 4, 5]);
+
+ */
+
+DEFUN (zeros, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} zeros (@var{x})\n\
+ at deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} zeros (@dots{}, @var{class})\n\
+Return a matrix or N-dimensional array whose elements are all 0.\n\
+The arguments are handled the same as the arguments for @code{eye}.\n\
+\n\
+The optional argument @var{class}, allows @code{zeros} to return an array of\n\
+the specified type, for example\n\
+\n\
+ at example\n\
+val = zeros (n,m, \"uint8\")\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, 0, "zeros");
+}
+
+/*
+
+%!assert(zeros (3), [0, 0, 0; 0, 0, 0; 0, 0, 0]);
+%!assert(zeros (2, 3), [0, 0, 0; 0, 0, 0]);
+%!assert(zeros (3, 2), [0, 0; 0, 0; 0, 0]);
+%!assert(size (zeros (3, 4, 5)),  [3, 4, 5]);
+
+%!assert(zeros (3,'single'), single([0, 0, 0; 0, 0, 0; 0, 0, 0]));
+%!assert(zeros (2, 3,'single'), single([0, 0, 0; 0, 0, 0]));
+%!assert(zeros (3, 2,'single'), single([0, 0; 0, 0; 0, 0]));
+%!assert(size (zeros (3, 4, 5, 'single')),  [3, 4, 5]);
+
+%!assert(zeros (3,'int8'), int8([0, 0, 0; 0, 0, 0; 0, 0, 0]));
+%!assert(zeros (2, 3,'int8'), int8([0, 0, 0; 0, 0, 0]));
+%!assert(zeros (3, 2,'int8'), int8([0, 0; 0, 0; 0, 0]));
+%!assert(size (zeros (3, 4, 5, 'int8')),  [3, 4, 5]);
+
+ */
+
+DEFUN (Inf, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} Inf\n\
+ at deftypefnx {Built-in Function} {} Inf (@var{n})\n\
+ at deftypefnx {Built-in Function} {} Inf (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} Inf (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} Inf (@dots{}, @var{class})\n\
+Return a scalar, matrix or N-dimensional array whose elements are all equal\n\
+to the IEEE representation for positive infinity.\n\
+\n\
+Infinity is produced when results are too large to be represented using the\n\
+the IEEE floating point format for numbers.  Two common examples which\n\
+produce infinity are division by zero and overflow.\n\
+ at example\n\
+ at group\n\
+[1/0 e^800]\n\
+ at result{}\n\
+Inf   Inf\n\
+ at end group\n\
+ at end example\n\
+\n\
+When called with no arguments, return a scalar with the value @samp{Inf}.\n\
+When called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at seealso{isinf}\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, lo_ieee_inf_value (), 
+		      lo_ieee_float_inf_value (), "Inf");
+}
+
+DEFALIAS (inf, Inf);
+
+/*
+
+%!assert(inf (3), [Inf, Inf, Inf; Inf, Inf, Inf; Inf, Inf, Inf]);
+%!assert(inf (2, 3), [Inf, Inf, Inf; Inf, Inf, Inf]);
+%!assert(inf (3, 2), [Inf, Inf; Inf, Inf; Inf, Inf]);
+%!assert(size (inf (3, 4, 5)),  [3, 4, 5]);
+
+%!assert(inf (3,'single'), single([Inf, Inf, Inf; Inf, Inf, Inf; Inf, Inf, Inf]));
+%!assert(inf (2, 3,'single'), single([Inf, Inf, Inf; Inf, Inf, Inf]));
+%!assert(inf (3, 2,'single'), single([Inf, Inf; Inf, Inf; Inf, Inf]));
+%!assert(size (inf (3, 4, 5, 'single')),  [3, 4, 5]);
+
+%!error(inf (3,'int8'));
+%!error(inf (2, 3,'int8'));
+%!error(inf (3, 2,'int8'));
+%!error(inf (3, 4, 5, 'int8'));
+
+ */
+
+DEFUN (NaN, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} NaN\n\
+ at deftypefnx {Built-in Function} {} NaN (@var{n})\n\
+ at deftypefnx {Built-in Function} {} NaN (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} NaN (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} NaN (@dots{}, @var{class})\n\
+Return a scalar, matrix, or N-dimensional array whose elements are all equal\n\
+to the IEEE symbol NaN (Not a Number).\n\
+NaN is the result of operations which do not produce a well defined numerical\n\
+result.  Common operations which produce a NaN are arithmetic with infinity\n\
+ at tex\n\
+($\\infty - \\infty$), zero divided by zero ($0/0$),\n\
+ at end tex\n\
+ at ifnottex\n\
+(Inf - Inf), zero divided by zero (0/0),\n\
+ at end ifnottex\n\
+and any operation involving another NaN value (5 + NaN).\n\
+\n\
+Note that NaN always compares not equal to NaN (NaN != NaN).  This behavior\n\
+is specified by the IEEE standard for floating point arithmetic.  To\n\
+find NaN values, use the @code{isnan} function.\n\
+\n\
+When called with no arguments, return a scalar with the value @samp{NaN}.\n\
+When called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at seealso{isnan}\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, lo_ieee_nan_value (), 
+		      lo_ieee_float_nan_value (), "NaN");
+}
+
+DEFALIAS (nan, NaN);
+
+/* 
+%!assert(NaN (3), [NaN, NaN, NaN; NaN, NaN, NaN; NaN, NaN, NaN]);
+%!assert(NaN (2, 3), [NaN, NaN, NaN; NaN, NaN, NaN]);
+%!assert(NaN (3, 2), [NaN, NaN; NaN, NaN; NaN, NaN]);
+%!assert(size (NaN (3, 4, 5)),  [3, 4, 5]);
+
+%!assert(NaN (3,'single'), single([NaN, NaN, NaN; NaN, NaN, NaN; NaN, NaN, NaN]));
+%!assert(NaN (2, 3,'single'), single([NaN, NaN, NaN; NaN, NaN, NaN]));
+%!assert(NaN (3, 2,'single'), single([NaN, NaN; NaN, NaN; NaN, NaN]));
+%!assert(size (NaN (3, 4, 5, 'single')),  [3, 4, 5]);
+
+%!error(NaN (3,'int8'));
+%!error(NaN (2, 3,'int8'));
+%!error(NaN (3, 2,'int8'));
+%!error(NaN (3, 4, 5, 'int8'));
+
+ */
+
+DEFUN (e, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} e\n\
+ at deftypefnx {Built-in Function} {} e (@var{n})\n\
+ at deftypefnx {Built-in Function} {} e (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} e (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} e (@dots{}, @var{class})\n\
+Return a scalar, matrix, or N-dimensional array whose elements are all equal\n\
+to the base of natural logarithms.  The constant\n\
+ at tex\n\
+$e$ satisfies the equation $\\log (e) = 1$.\n\
+ at end tex\n\
+ at ifnottex\n\
+ at samp{e} satisfies the equation @code{log} (e) = 1.\n\
+ at end ifnottex\n\
+\n\
+When called with no arguments, return a scalar with the value @math{e}.  When\n\
+called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at end deftypefn")
+{
+#if defined (M_E)
+  double e_val = M_E;
+#else
+  double e_val = exp (1.0);
+#endif
+
+  return fill_matrix (args, e_val, "e");
+}
+
+DEFUN (eps, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} eps\n\
+ at deftypefnx {Built-in Function} {} eps (@var{x})\n\
+ at deftypefnx {Built-in Function} {} eps (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} eps (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} eps (@dots{}, @var{class})\n\
+Return a scalar, matrix or N-dimensional array whose elements are all eps,\n\
+the machine precision.  More precisely, @code{eps} is the relative spacing\n\
+between any two adjacent numbers in the machine's floating point system.\n\
+This number is obviously system dependent.  On machines that support IEEE\n\
+floating point arithmetic, @code{eps} is approximately\n\
+ at tex\n\
+$2.2204\\times10^{-16}$ for double precision and $1.1921\\times10^{-7}$\n\
+ at end tex\n\
+ at ifnottex\n\
+2.2204e-16 for double precision and 1.1921e-07\n\
+ at end ifnottex\n\
+for single precision.\n\
+\n\
+When called with no arguments, return a scalar with the value\n\
+ at code{eps(1.0)}.\n\
+Given a single argument @var{x}, return the distance between @var{x} and\n\
+the next largest value.\n\
+When called with more than one argument the first two arguments are taken as\n\
+the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  if (nargin == 1 && ! args(0).is_string ())
+    {
+      if (args(0).is_single_type ())
+	{
+	  float val = args(0).float_value ();
+
+	  if (! error_state)
+	    {
+	      val  = ::fabsf(val);
+	      if (xisnan (val) || xisinf (val))
+		retval = fill_matrix (octave_value ("single"), 
+				      lo_ieee_nan_value (), 
+				      lo_ieee_float_nan_value (), "eps");
+	      else if (val < FLT_MIN)
+		retval = fill_matrix (octave_value ("single"), 0e0, 
+				      powf (2.0, -149e0), "eps");
+	      else
+		{
+		  int expon;
+		  frexpf (val, &expon);
+		  val = std::pow (static_cast <float> (2.0), 
+				  static_cast <float> (expon - 24));
+		  retval = fill_matrix (octave_value ("single"), DBL_EPSILON, 
+					val, "eps");
+		}
+	    }
+	}
+      else
+	{
+	  double val = args(0).double_value ();
+
+	  if (! error_state)
+	    {
+	      val  = ::fabs(val);
+	      if (xisnan (val) || xisinf (val))
+		retval = fill_matrix (octave_value_list (), 
+				      lo_ieee_nan_value (), 
+				      lo_ieee_float_nan_value (), "eps");
+	      else if (val < DBL_MIN)
+		retval = fill_matrix (octave_value_list (),
+				      pow (2.0, -1074e0), 0e0, "eps");
+	      else
+		{
+		  int expon;
+		  frexp (val, &expon);
+		  val = std::pow (static_cast <double> (2.0), 
+				  static_cast <double> (expon - 53));
+		  retval = fill_matrix (octave_value_list (), val, 
+					FLT_EPSILON, "eps");
+		}
+	    }
+	}
+    }
+  else
+    retval = fill_matrix (args, DBL_EPSILON, FLT_EPSILON, "eps");
+
+  return retval;
+}
+
+/*
+
+%!assert(eps(1/2),2^(-53))
+%!assert(eps(1),2^(-52))
+%!assert(eps(2),2^(-51))
+%!assert(eps(realmax),2^971)
+%!assert(eps(0),2^(-1074))
+%!assert(eps(realmin/2),2^(-1074))
+%!assert(eps(realmin/16),2^(-1074))
+%!assert(eps(Inf),NaN)
+%!assert(eps(NaN),NaN)
+%!assert(eps(single(1/2)),single(2^(-24)))
+%!assert(eps(single(1)),single(2^(-23)))
+%!assert(eps(single(2)),single(2^(-22)))
+%!assert(eps(realmax('single')),single(2^104))
+%!assert(eps(single(0)),single(2^(-149)))
+%!assert(eps(realmin('single')/2),single(2^(-149)))
+%!assert(eps(realmin('single')/16),single(2^(-149)))
+%!assert(eps(single(Inf)),single(NaN))
+%!assert(eps(single(NaN)),single(NaN))
+
+*/
+
+
+DEFUN (pi, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} pi\n\
+ at deftypefnx {Built-in Function} {} pi (@var{n})\n\
+ at deftypefnx {Built-in Function} {} pi (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} pi (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} pi (@dots{}, @var{class})\n\
+Return a scalar, matrix, or N-dimensional array whose elements are all equal\n\
+to the ratio of the circumference of a circle to its\n\
+ at tex\n\
+diameter($\\pi$).\n\
+ at end tex\n\
+ at ifnottex\n\
+diameter.\n\
+ at end ifnottex\n\
+Internally, @code{pi} is computed as @samp{4.0 * atan (1.0)}.\n\
+\n\
+When called with no arguments, return a scalar with the value of\n\
+ at tex\n\
+$\\pi$.\n\
+ at end tex\n\
+ at ifnottex\n\
+pi.\n\
+ at end ifnottex\n\
+When called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at end deftypefn")
+{
+#if defined (M_PI)
+  double pi_val = M_PI;
+#else
+  double pi_val = 4.0 * atan (1.0);
+#endif
+
+  return fill_matrix (args, pi_val, "pi");
+}
+
+DEFUN (realmax, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} realmax\n\
+ at deftypefnx {Built-in Function} {} realmax (@var{n})\n\
+ at deftypefnx {Built-in Function} {} realmax (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} realmax (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} realmax (@dots{}, @var{class})\n\
+Return a scalar, matrix or N-dimensional array whose elements are all equal\n\
+to the largest floating point number that is representable.  The actual\n\
+value is system dependent.  On machines that support IEEE\n\
+floating point arithmetic, @code{realmax} is approximately\n\
+ at tex\n\
+$1.7977\\times10^{308}$ for double precision and $3.4028\\times10^{38}$\n\
+ at end tex\n\
+ at ifnottex\n\
+1.7977e+308 for double precision and 3.4028e+38\n\
+ at end ifnottex\n\
+for single precision.\n\
+\n\
+When called with no arguments, return a scalar with the value\n\
+ at code{realmax(\"double\")}.\n\
+When called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at seealso{realmin, intmax, bitmax}\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, DBL_MAX, FLT_MAX, "realmax");
+}
+
+DEFUN (realmin, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} realmin\n\
+ at deftypefnx {Built-in Function} {} realmin (@var{n})\n\
+ at deftypefnx {Built-in Function} {} realmin (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} realmin (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} realmin (@dots{}, @var{class})\n\
+Return a scalar, matrix or N-dimensional array whose elements are all equal\n\
+to the smallest normalized floating point number that is representable.\n\
+The actual value is system dependent.  On machines that support\n\
+IEEE floating point arithmetic, @code{realmin} is approximately\n\
+ at tex\n\
+$2.2251\\times10^{-308}$ for double precision and $1.1755\\times10^{-38}$\n\
+ at end tex\n\
+ at ifnottex\n\
+2.2251e-308 for double precision and 1.1755e-38\n\
+ at end ifnottex\n\
+for single precision.\n\
+\n\
+When called with no arguments, return a scalar with the value\n\
+ at code{realmin(\"double\")}.\n\
+When called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at seealso{realmax, intmin}\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, DBL_MIN, FLT_MIN, "realmin");
+}
+
+DEFUN (I, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} I\n\
+ at deftypefnx {Built-in Function} {} I (@var{n})\n\
+ at deftypefnx {Built-in Function} {} I (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} I (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} I (@dots{}, @var{class})\n\
+Return a scalar, matrix, or N-dimensional array whose elements are all equal\n\
+to the pure imaginary unit, defined as\n\
+ at tex\n\
+$\\sqrt{-1}$.\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{sqrt (-1)}.\n\
+ at end ifnottex\n\
+ I, and its equivalents i, J, and j, are functions so any of the names may\n\
+be reused for other purposes (such as i for a counter variable).\n\
+\n\
+When called with no arguments, return a scalar with the value @math{i}.  When\n\
+called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, Complex (0.0, 1.0), "I");
+}
+
+DEFALIAS (i, I);
+DEFALIAS (J, I);
+DEFALIAS (j, I);
+
+DEFUN (NA, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} NA\n\
+ at deftypefnx {Built-in Function} {} NA (@var{n})\n\
+ at deftypefnx {Built-in Function} {} NA (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} NA (@var{n}, @var{m}, @var{k}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} NA (@dots{}, @var{class})\n\
+Return a scalar, matrix, or N-dimensional array whose elements are all equal\n\
+to the special constant used to designate missing values.\n\
+\n\
+Note that NA always compares not equal to NA (NA != NA).\n\
+To find NA values, use the @code{isna} function.\n\
+\n\
+When called with no arguments, return a scalar with the value @samp{NA}.\n\
+When called with a single argument, return a square matrix with the dimension\n\
+specified.  When called with more than one scalar argument the first two\n\
+arguments are taken as the number of rows and columns and any further\n\
+arguments specify additional matrix dimensions.\n\
+The optional argument @var{class} specifies the return type and may be\n\
+either \"double\" or \"single\".\n\
+ at seealso{isna}\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, lo_ieee_na_value (), 
+		      lo_ieee_float_na_value (), "NA");
+}
+
+/*
+
+%!assert(single(NA('double')),NA('single'))
+%!assert(double(NA('single')),NA('double'))
+
+ */
+
+DEFUN (false, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} false (@var{x})\n\
+ at deftypefnx {Built-in Function} {} false (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} false (@var{n}, @var{m}, @var{k}, @dots{})\n\
+Return a matrix or N-dimensional array whose elements are all logical 0.\n\
+The arguments are handled the same as the arguments for @code{eye}.\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, false, "false");
+}
+
+DEFUN (true, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} true (@var{x})\n\
+ at deftypefnx {Built-in Function} {} true (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} true (@var{n}, @var{m}, @var{k}, @dots{})\n\
+Return a matrix or N-dimensional array whose elements are all logical 1.\n\
+The arguments are handled the same as the arguments for @code{eye}.\n\
+ at end deftypefn")
+{
+  return fill_matrix (args, true, "true");
+}
+
+template <class MT>
+octave_value
+identity_matrix (int nr, int nc)
+{
+  octave_value retval;
+
+  typename octave_array_type_traits<MT>::element_type one (1);
+
+  if (nr == 1 && nc == 1)
+    retval = one;
+  else
+    {
+      dim_vector dims (nr, nc);
+
+      typename octave_array_type_traits<MT>::element_type zero (0);
+
+      MT m (dims, zero);
+
+      if (nr > 0 && nc > 0)
+	{
+	  int n = std::min (nr, nc);
+
+	  for (int i = 0; i < n; i++)
+	    m(i,i) = one;
+	}
+
+      retval = m;
+    }
+
+  return retval;
+}
+
+#define INSTANTIATE_EYE(T) \
+  template octave_value identity_matrix<T> (int, int)
+
+INSTANTIATE_EYE (int8NDArray);
+INSTANTIATE_EYE (uint8NDArray);
+INSTANTIATE_EYE (int16NDArray);
+INSTANTIATE_EYE (uint16NDArray);
+INSTANTIATE_EYE (int32NDArray);
+INSTANTIATE_EYE (uint32NDArray);
+INSTANTIATE_EYE (int64NDArray);
+INSTANTIATE_EYE (uint64NDArray);
+INSTANTIATE_EYE (FloatNDArray);
+INSTANTIATE_EYE (NDArray);
+INSTANTIATE_EYE (boolNDArray);
+
+static octave_value
+identity_matrix (int nr, int nc, oct_data_conv::data_type dt)
+{
+  octave_value retval;
+
+  // FIXME -- perhaps this should be made extensible by using
+  // the class name to lookup a function to call to create the new
+  // value.
+
+  if (! error_state)
+    {
+      switch (dt)
+	{
+	case oct_data_conv::dt_int8:
+	  retval = identity_matrix<int8NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_uint8:
+	  retval = identity_matrix<uint8NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_int16:
+	  retval = identity_matrix<int16NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_uint16:
+	  retval = identity_matrix<uint16NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_int32:
+	  retval = identity_matrix<int32NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_uint32:
+	  retval = identity_matrix<uint32NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_int64:
+	  retval = identity_matrix<int64NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_uint64:
+	  retval = identity_matrix<uint64NDArray> (nr, nc);
+	  break;
+
+	case oct_data_conv::dt_single:
+	  retval = FloatDiagMatrix (nr, nc, 1.0f);
+	  break;
+
+	case oct_data_conv::dt_double:
+	  retval = DiagMatrix (nr, nc, 1.0);
+	  break;
+
+	case oct_data_conv::dt_logical:
+	  retval = identity_matrix<boolNDArray> (nr, nc);
+	  break;
+
+	default:
+	  error ("eye: invalid class name");
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+#undef INT_EYE_MATRIX
+
+DEFUN (eye, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} eye (@var{x})\n\
+ at deftypefnx {Built-in Function} {} eye (@var{n}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} eye (@dots{}, @var{class})\n\
+Return an identity matrix.  If invoked with a single scalar argument,\n\
+ at code{eye} returns a square matrix with the dimension specified.  If you\n\
+supply two scalar arguments, @code{eye} takes them to be the number of\n\
+rows and columns.  If given a vector with two elements, @code{eye} uses\n\
+the values of the elements as the number of rows and columns,\n\
+respectively.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+eye (3)\n\
+     @result{}  1  0  0\n\
+         0  1  0\n\
+         0  0  1\n\
+ at end group\n\
+ at end example\n\
+\n\
+The following expressions all produce the same result:\n\
+\n\
+ at example\n\
+ at group\n\
+eye (2)\n\
+ at equiv{}\n\
+eye (2, 2)\n\
+ at equiv{}\n\
+eye (size ([1, 2; 3, 4])\n\
+ at end group\n\
+ at end example\n\
+\n\
+The optional argument @var{class}, allows @code{eye} to return an array of\n\
+the specified type, like\n\
+\n\
+ at example\n\
+val = zeros (n,m, \"uint8\")\n\
+ at end example\n\
+\n\
+Calling @code{eye} with no arguments is equivalent to calling it\n\
+with an argument of 1.  This odd definition is for compatibility\n\
+with @sc{matlab}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  oct_data_conv::data_type dt = oct_data_conv::dt_double;
+
+  // Check for type information.
+
+  if (nargin > 0 && args(nargin-1).is_string ())
+    {
+      std::string nm = args(nargin-1).string_value ();
+      nargin--;
+
+      dt = oct_data_conv::string_to_data_type (nm);
+
+      if (error_state)
+	return retval;
+    }
+
+  switch (nargin)
+    {
+    case 0:
+      retval = identity_matrix (1, 1, dt);
+      break;
+
+    case 1:
+      {
+	octave_idx_type nr, nc;
+	get_dimensions (args(0), "eye", nr, nc);
+
+	if (! error_state)
+	  retval = identity_matrix (nr, nc, dt);
+      }
+      break;
+
+    case 2:
+      {
+	octave_idx_type nr, nc;
+	get_dimensions (args(0), args(1), "eye", nr, nc);
+
+	if (! error_state)
+	  retval = identity_matrix (nr, nc, dt);
+      }
+      break;
+
+    default:
+      print_usage ();
+      break;
+    }
+
+  return retval;
+}
+
+
+/*
+
+%!assert (full (eye(3)), [1, 0, 0; 0, 1, 0; 0, 0, 1]);
+%!assert (full (eye(2, 3)), [1, 0, 0; 0, 1, 0]);
+
+%!assert (full (eye(3,'single')), single([1, 0, 0; 0, 1, 0; 0, 0, 1]));
+%!assert (full (eye(2, 3,'single')), single([1, 0, 0; 0, 1, 0]));
+
+%!assert (eye(3,'int8'), int8([1, 0, 0; 0, 1, 0; 0, 0, 1]));
+%!assert (eye(2, 3,'int8'), int8([1, 0, 0; 0, 1, 0]));
+
+%!error <Invalid call to eye.*> eye (1, 2, 3);
+
+ */
+
+DEFUN (linspace, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} linspace (@var{base}, @var{limit}, @var{n})\n\
+Return a row vector with @var{n} linearly spaced elements between\n\
+ at var{base} and @var{limit}.  If the number of elements is greater than one,\n\
+then the @var{base} and @var{limit} are always included in\n\
+the range.  If @var{base} is greater than @var{limit}, the elements are\n\
+stored in decreasing order.  If the number of points is not specified, a\n\
+value of 100 is used.\n\
+\n\
+The @code{linspace} function always returns a row vector.\n\
+\n\
+For compatibility with @sc{matlab}, return the second argument if\n\
+fewer than two values are requested.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  octave_idx_type npoints = 100;
+
+  if (nargin != 2 && nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (nargin == 3)
+    npoints = args(2).idx_type_value ();
+
+  if (! error_state)
+    {
+      octave_value arg_1 = args(0);
+      octave_value arg_2 = args(1);
+
+      if (arg_1.is_single_type () || arg_2.is_single_type ())
+	{
+	  if (arg_1.is_complex_type () || arg_2.is_complex_type ())
+	    {
+	      FloatComplex x1 = arg_1.float_complex_value ();
+	      FloatComplex x2 = arg_2.float_complex_value ();
+
+	      if (! error_state)
+		{
+		  FloatComplexRowVector rv = linspace (x1, x2, npoints);
+
+		  if (! error_state)
+		    retval = rv;
+		}
+	    }
+	  else
+	    {
+	      float x1 = arg_1.float_value ();
+	      float x2 = arg_2.float_value ();
+
+	      if (! error_state)
+		{
+		  FloatRowVector rv = linspace (x1, x2, npoints);
+
+		  if (! error_state)
+		    retval = rv;
+		}
+	    }
+	}
+      else
+	{
+	  if (arg_1.is_complex_type () || arg_2.is_complex_type ())
+	    {
+	      Complex x1 = arg_1.complex_value ();
+	      Complex x2 = arg_2.complex_value ();
+
+	      if (! error_state)
+		{
+		  ComplexRowVector rv = linspace (x1, x2, npoints);
+
+		  if (! error_state)
+		    retval = rv;
+		}
+	    }
+	  else
+	    {
+	      double x1 = arg_1.double_value ();
+	      double x2 = arg_2.double_value ();
+
+	      if (! error_state)
+		{
+		  RowVector rv = linspace (x1, x2, npoints);
+
+		  if (! error_state)
+		    retval = rv;
+		}
+	    }
+	}
+    }
+  else
+    error ("linspace: expecting third argument to be an integer");
+
+  return retval;
+}
+
+
+/*
+
+%!test
+%! x1 = linspace (1, 2);
+%! x2 = linspace (1, 2, 10);
+%! x3 = linspace (1, -2, 10);
+%! assert((size (x1) == [1, 100] && x1(1) == 1 && x1(100) == 2
+%! && size (x2) == [1, 10] && x2(1) == 1 && x2(10) == 2
+%! && size (x3) == [1, 10] && x3(1) == 1 && x3(10) == -2));
+
+
+% assert(linspace ([1, 2; 3, 4], 5, 6), linspace (1, 5, 6));
+
+%!error <Invalid call to linspace.*> linspace ();
+%!error <Invalid call to linspace.*> linspace (1, 2, 3, 4);
+
+%!test
+%! fail("linspace ([1, 2; 3, 4], 5, 6)","warning");
+
+*/
+
+// FIXME -- should accept dimensions as separate args for N-d
+// arrays as well as 1-d and 2-d arrays.
+
+DEFUN (resize, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} resize (@var{x}, @var{m})\n\
+ at deftypefnx {Built-in Function} {} resize (@var{x}, @var{m}, @var{n})\n\
+ at deftypefnx {Built-in Function} {} resize (@var{x}, @var{m}, @var{n}, @dots{})\n\
+Resize @var{x} cutting off elements as necessary.\n\
+\n\
+In the result, element with certain indices is equal to the corresponding\n\
+element of @var{x} if the indices are within the bounds of @var{x};\n\
+otherwise, the element is set to zero.\n\
+\n\
+In other words, the statement\n\
+\n\
+ at example\n\
+  y = resize (x, dv);\n\
+ at end example\n\
+\n\
+ at noindent\n\
+is equivalent to the following code:\n\
+\n\
+ at example\n\
+ at group\n\
+  y = zeros (dv, class (x));\n\
+  sz = min (dv, size (x));\n\
+  for i = 1:length (sz), idx@{i@} = 1:sz(i); endfor\n\
+  y(idx@{:@}) = x(idx@{:@});\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+but is performed more efficiently.\n\
+\n\
+If only @var{m} is supplied and it is a scalar, the dimension of the\n\
+result is @var{m}-by- at var{m}.  If @var{m} is a vector, then the\n\
+dimensions of the result are given by the elements of @var{m}.\n\
+If both @var{m} and @var{n} are scalars, then the dimensions of\n\
+the result are @var{m}-by- at var{n}.\n\
+\n\
+An object can be resized to more dimensions than it has;\n\
+in such case the missing dimensions are assumed to be 1.\n\
+Resizing an object to fewer dimensions is not possible.\n\
+ at seealso{reshape, postpad}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      Array<double> vec = args(1).vector_value ();
+      int ndim = vec.length ();
+      if (ndim == 1)
+	{
+	  octave_idx_type m = static_cast<octave_idx_type> (vec(0));
+	  retval = args(0);
+	  retval = retval.resize (dim_vector (m, m), true);
+	}
+      else
+	{
+	  dim_vector dv;
+	  dv.resize (ndim);
+	  for (int i = 0; i < ndim; i++)
+	    dv(i) = static_cast<octave_idx_type> (vec(i));
+	  retval = args(0);
+	  retval = retval.resize (dv, true);
+	}
+    }
+  else if (nargin > 2)
+    {
+      dim_vector dv;
+      dv.resize (nargin - 1);
+      for (octave_idx_type i = 1; i < nargin; i++)
+        dv(i-1) = static_cast<octave_idx_type> (args(i).scalar_value ());
+      if (!error_state)
+	{
+	  retval = args(0);
+	  retval = retval.resize (dv, true);
+	}
+
+    }
+  else
+    print_usage ();
+  return retval;
+}
+
+// FIXME -- should use octave_idx_type for dimensions.
+
+DEFUN (reshape, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} reshape (@var{a}, @var{m}, @var{n}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} reshape (@var{a}, @var{size})\n\
+Return a matrix with the given dimensions whose elements are taken\n\
+from the matrix @var{a}.  The elements of the matrix are accessed in\n\
+column-major order (like Fortran arrays are stored).\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+reshape ([1, 2, 3, 4], 2, 2)\n\
+     @result{}  1  3\n\
+         2  4\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Note that the total number of elements in the original\n\
+matrix must match the total number of elements in the new matrix.\n\
+\n\
+A single dimension of the return matrix can be unknown and is flagged\n\
+by an empty argument.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  Array<int> new_size;
+
+  if (nargin == 2)
+    new_size = args(1).int_vector_value ();
+  else if (nargin > 2)
+    {
+      new_size.resize (nargin-1);
+      int empty_dim = -1;
+      
+      for (int i = 1; i < nargin; i++)
+	{
+	  if (args(i).is_empty ())
+	    if (empty_dim > 0)
+	      {
+		error ("reshape: only a single dimension can be unknown");
+		break;
+	      }
+	    else
+	      {
+		empty_dim = i;
+		new_size(i-1) = 1;
+	      }
+	  else
+	    {
+	      new_size(i-1) = args(i).idx_type_value ();
+
+	      if (error_state)
+		break;
+	    }
+	}
+
+      if (! error_state && (empty_dim > 0))
+	{
+	  int nel = 1;
+	  for (int i = 0; i < nargin - 1; i++)
+	    nel *= new_size(i);
+
+	  if (nel == 0)
+	    new_size(empty_dim-1) = 0;
+	  else
+	    {
+	      int size_empty_dim = args(0).numel () / nel;
+	      
+	      if (args(0).numel () != size_empty_dim * nel)
+		error ("reshape: size is not divisble by the product of known dimensions (= %d)", nel);
+	      else
+		new_size(empty_dim-1) = size_empty_dim;
+	    }
+	}
+    }
+  else
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (error_state)
+    {
+      error ("reshape: invalid arguments");
+      return retval;
+    }
+
+  // Remove trailing singletons in new_size, but leave at least 2
+  // elements.
+
+  int n = new_size.length ();
+
+  while (n > 2)
+    {
+      if (new_size(n-1) == 1)
+	n--;
+      else
+	break;
+    }
+
+  new_size.resize (n);
+
+  if (n < 2)
+    {
+      error ("reshape: expecting size to be vector with at least 2 elements");
+      return retval;
+    }
+
+  dim_vector new_dims;
+
+  new_dims.resize (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    new_dims(i) = new_size(i);
+
+  octave_value arg = args(0);
+
+  dim_vector dims = arg.dims ();
+
+  if (new_dims.numel () == dims.numel ())
+    retval = (new_dims == dims) ? arg : arg.reshape (new_dims);
+  else
+    {
+      std::string dims_str = dims.str ();
+      std::string new_dims_str = new_dims.str ();
+
+      error ("reshape: can't reshape %s array to %s array",
+	     dims_str.c_str (), new_dims_str.c_str ());
+    }
+
+  return retval;
+}
+
+/*
+
+%!assert(size (reshape (ones (4, 4), 2, 8)), [2, 8])
+%!assert(size (reshape (ones (4, 4), 8, 2)), [8, 2])
+%!assert(size (reshape (ones (15, 4), 1, 60)), [1, 60])
+%!assert(size (reshape (ones (15, 4), 60, 1)), [60, 1])
+
+%!assert(size (reshape (ones (4, 4, 'single'), 2, 8)), [2, 8])
+%!assert(size (reshape (ones (4, 4, 'single'), 8, 2)), [8, 2])
+%!assert(size (reshape (ones (15, 4, 'single'), 1, 60)), [1, 60])
+%!assert(size (reshape (ones (15, 4, 'single'), 60, 1)), [60, 1])
+
+%!test
+%! s.a = 1;
+%! fail("reshape (s, 2, 3)");
+
+%!error <Invalid call to reshape.*> reshape ();
+%!error reshape (1, 2, 3, 4);
+
+ */
+
+DEFUN (squeeze, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} squeeze (@var{x})\n\
+Remove singleton dimensions from @var{x} and return the result.\n\
+Note that for compatibility with @sc{matlab}, all objects have\n\
+a minimum of two dimensions and row vectors are left unchanged.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).squeeze ();
+  else
+    print_usage ();    
+
+  return retval;
+}
+
+DEFUN (full, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{FM} =} full (@var{SM})\n\
+ returns a full storage matrix from a sparse, diagonal, permutation matrix or a range.\n\
+ at seealso{sparse}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).full_value ();
+  else
+    print_usage ();    
+
+  return retval;
+}
+
+// Compute various norms of the vector X.
+
+DEFUN (norm, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} norm (@var{a}, @var{p}, @var{opt})\n\
+Compute the p-norm of the matrix @var{a}.  If the second argument is\n\
+missing, @code{p = 2} is assumed.\n\
+\n\
+If @var{a} is a matrix (or sparse matrix):\n\
+\n\
+ at table @asis\n\
+ at item @var{p} = @code{1}\n\
+1-norm, the largest column sum of the absolute values of @var{a}.\n\
+\n\
+ at item @var{p} = @code{2}\n\
+Largest singular value of @var{a}.\n\
+\n\
+ at item @var{p} = @code{Inf} or @code{\"inf\"}\n\
+ at cindex infinity norm\n\
+Infinity norm, the largest row sum of the absolute values of @var{a}.\n\
+\n\
+ at item @var{p} = @code{\"fro\"}\n\
+ at cindex Frobenius norm\n\
+Frobenius norm of @var{a}, @code{sqrt (sum (diag (@var{a}' * @var{a})))}.\n\
+\n\
+ at item other @var{p}, @code{@var{p} > 1}\n\
+ at cindex general p-norm \n\
+maximum @code{norm (A*x, p)} such that @code{norm (x, p) == 1}\n\
+ at end table\n\
+\n\
+If @var{a} is a vector or a scalar:\n\
+\n\
+ at table @asis\n\
+ at item @var{p} = @code{Inf} or @code{\"inf\"}\n\
+ at code{max (abs (@var{a}))}.\n\
+\n\
+ at item @var{p} = @code{-Inf}\n\
+ at code{min (abs (@var{a}))}.\n\
+\n\
+ at item @var{p} = @code{\"fro\"}\n\
+Frobenius norm of @var{a}, @code{sqrt (sumsq (abs (a)))}.\n\
+\n\
+ at item @var{p} = 0\n\
+Hamming norm - the number of nonzero elements.\n\
+\n\
+ at item other @var{p}, @code{@var{p} > 1}\n\
+p-norm of @var{a}, @code{(sum (abs (@var{a}) .^ @var{p})) ^ (1/@var{p})}.\n\
+\n\
+ at item other @var{p} @code{@var{p} < 1}\n\
+the p-pseudonorm defined as above.\n\
+ at end table\n\
+\n\
+If @code{\"rows\"} is given as @var{opt}, the norms of all rows of the matrix @var{a} are\n\
+returned as a column vector.  Similarly, if @code{\"columns\"} or @code{\"cols\"} is passed\n\
+column norms are computed.\n\
+ at seealso{cond, svd}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin >= 1 && nargin <= 3)
+    {
+      octave_value x_arg = args(0);
+
+      if (x_arg.is_empty ())
+	{
+	  if (x_arg.is_single_type ())
+	    retval(0) = static_cast<float>(0.0);
+	  else
+	    retval(0) = 0.0;
+	}
+      else if (x_arg.ndims () == 2)
+	{
+          enum { sfmatrix, sfcols, sfrows, sffrob, sfinf } strflag = sfmatrix;
+          if (nargin > 1 && args(nargin-1).is_string ())
+            {
+              std::string str = args(nargin-1).string_value ();
+              if (str == "cols" || str == "columns")
+                strflag = sfcols;
+              else if (str == "rows")
+                strflag = sfrows;
+              else if (str == "fro")
+                strflag = sffrob;
+              else if (str == "inf")
+                strflag = sfinf;
+              else
+                error ("norm: unrecognized option: %s", str.c_str ());
+              // we've handled the last parameter, so act as if it was removed
+              nargin --;
+            }
+          else if (nargin > 1 && ! args(1).is_scalar_type ())
+            gripe_wrong_type_arg ("norm", args(1), true);
+
+          if (! error_state)
+            {
+              octave_value p_arg = (nargin > 1) ? args(1) : octave_value (2);
+              switch (strflag)
+                {
+                case sfmatrix:
+                  retval(0) = xnorm (x_arg, p_arg);
+                  break;
+                case sfcols:
+                  retval(0) = xcolnorms (x_arg, p_arg);
+                  break;
+                case sfrows:
+                  retval(0) = xrownorms (x_arg, p_arg);
+                  break;
+                case sffrob:
+                  retval(0) = xfrobnorm (x_arg);
+                  break;
+                case sfinf:
+                  retval(0) = xnorm (x_arg, octave_Inf);
+                  break;
+                }
+            }
+	}
+      else
+	error ("norm: only valid for 2-D objects");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!shared x
+%! x = [1, -3, 4, 5, -7];
+%!assert(norm(x,1), 20);
+%!assert(norm(x,2), 10);
+%!assert(norm(x,3), 8.24257059961711, -4*eps);
+%!assert(norm(x,Inf), 7);
+%!assert(norm(x,-Inf), 1);
+%!assert(norm(x,"inf"), 7);
+%!assert(norm(x,"fro"), 10, -eps);
+%!assert(norm(x), 10);
+%!assert(norm([1e200, 1]), 1e200);
+%!assert(norm([3+4i, 3-4i, sqrt(31)]), 9, -4*eps);
+%!shared m
+%! m = magic (4);
+%!assert(norm(m,1), 34);
+%!assert(norm(m,2), 34, -eps);
+%!assert(norm(m,Inf), 34);
+%!assert(norm(m,"inf"), 34);
+%!shared m2, flo, fhi
+%! m2 = [1,2;3,4];
+%! flo = 1e-300;
+%! fhi = 1e+300;
+%!assert (norm(flo*m2,"fro"), sqrt(30)*flo, -eps)
+%!assert (norm(fhi*m2,"fro"), sqrt(30)*fhi, -eps)
+
+%!shared x
+%! x = single([1, -3, 4, 5, -7]);
+%!assert(norm(x,1), single(20));
+%!assert(norm(x,2), single(10));
+%!assert(norm(x,3), single(8.24257059961711), -4*eps('single'));
+%!assert(norm(x,Inf), single(7));
+%!assert(norm(x,-Inf), single(1));
+%!assert(norm(x,"inf"), single(7));
+%!assert(norm(x,"fro"), single(10), -eps('single'));
+%!assert(norm(x), single(10));
+%!assert(norm(single([1e200, 1])), single(1e200));
+%!assert(norm(single([3+4i, 3-4i, sqrt(31)])), single(9), -4*eps('single'));
+%!shared m
+%! m = single(magic (4));
+%!assert(norm(m,1), single(34));
+%!assert(norm(m,2), single(34), -eps('single'));
+%!assert(norm(m,Inf), single(34));
+%!assert(norm(m,"inf"), single(34));
+%!shared m2, flo, fhi
+%! m2 = single([1,2;3,4]);
+%! flo = single(1e-300);
+%! fhi = single(1e+300);
+%!assert (norm(flo*m2,"fro"), single(sqrt(30)*flo), -eps('single'))
+%!assert (norm(fhi*m2,"fro"), single(sqrt(30)*fhi), -eps('single'))
+*/
+
+#define UNARY_OP_DEFUN_BODY(F) \
+ \
+  octave_value retval; \
+ \
+  if (args.length () == 1) \
+    retval = F (args(0)); \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+DEFUN (not, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} not (@var{x})\n\
+This function is equivalent to @code{! x}.\n\
+ at end deftypefn")
+{
+  UNARY_OP_DEFUN_BODY (op_not);
+}
+
+DEFUN (uplus, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} uplus (@var{x})\n\
+This function is equivalent to @code{+ x}.\n\
+ at end deftypefn")
+{
+  UNARY_OP_DEFUN_BODY (op_uplus);
+}
+
+DEFUN (uminus, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} uminus (@var{x})\n\
+This function is equivalent to @code{- x}.\n\
+ at end deftypefn")
+{
+  UNARY_OP_DEFUN_BODY (op_uminus);
+}
+
+DEFUN (transpose, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} transpose (@var{x})\n\
+This function is equivalent to @code{x.'}.\n\
+ at end deftypefn")
+{
+  UNARY_OP_DEFUN_BODY (op_transpose);
+}
+
+/*
+
+%!assert (2.', 2);
+%!assert (2i.',2i);
+%!assert ([1:4].',[1;2;3;4]);
+%!assert ([1;2;3;4].',[1:4]);
+%!assert ([1,2;3,4].',[1,3;2,4]);
+%!assert ([1,2i;3,4].',[1,3;2i,4]);
+
+%!assert (transpose ([1,2;3,4]),[1,3;2,4]);
+
+%!assert (single(2).', single(2));
+%!assert (single(2i).',single(2i));
+%!assert (single([1:4]).',single([1;2;3;4]));
+%!assert (single([1;2;3;4]).',single([1:4]));
+%!assert (single([1,2;3,4]).',single([1,3;2,4]));
+%!assert (single([1,2i;3,4]).',single([1,3;2i,4]));
+
+%!assert (transpose (single([1,2;3,4])),single([1,3;2,4]));
+
+*/
+
+DEFUN (ctranspose, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ctranspose (@var{x})\n\
+This function is equivalent to @code{x'}.\n\
+ at end deftypefn")
+{
+  UNARY_OP_DEFUN_BODY (op_hermitian);
+}
+
+/*
+
+%!assert (2', 2);
+%!assert (2i',-2i);
+%!assert ([1:4]',[1;2;3;4]);
+%!assert ([1;2;3;4]',[1:4]);
+%!assert ([1,2;3,4]',[1,3;2,4]);
+%!assert ([1,2i;3,4]',[1,3;-2i,4]);
+
+%!assert (ctranspose ([1,2i;3,4]),[1,3;-2i,4]);
+
+%!assert (single(2)', single(2));
+%!assert (single(2i)',single(-2i));
+%!assert (single([1:4])',single([1;2;3;4]));
+%!assert (single([1;2;3;4])',single([1:4]));
+%!assert (single([1,2;3,4])',single([1,3;2,4]));
+%!assert (single([1,2i;3,4])',single([1,3;-2i,4]));
+
+%!assert (ctranspose (single([1,2i;3,4])),single([1,3;-2i,4]));
+
+*/
+
+#define BINARY_OP_DEFUN_BODY(F) \
+ \
+  octave_value retval; \
+ \
+  if (args.length () == 2) \
+    retval = F (args(0), args(1)); \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+DEFUN (plus, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} plus (@var{x}, @var{y})\n\
+This function is equivalent to @code{x + y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_add);
+}
+
+DEFUN (minus, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} minus (@var{x}, @var{y})\n\
+This function is equivalent to @code{x - y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_sub);
+}
+
+DEFUN (mtimes, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mtimes (@var{x}, @var{y})\n\
+This function is equivalent to @code{x * y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_mul);
+}
+
+DEFUN (mrdivide, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mrdivide (@var{x}, @var{y})\n\
+This function is equivalent to @code{x / y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_div);
+}
+
+DEFUN (mpower, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mpower (@var{x}, @var{y})\n\
+This function is equivalent to @code{x ^ y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_pow);
+}
+
+DEFUN (mldivide, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mldivide (@var{x}, @var{y})\n\
+This function is equivalent to @code{x \\ y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_ldiv);
+}
+
+DEFUN (lt, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} lt (@var{x}, @var{y})\n\
+This function is equivalent to @code{x < y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_lt);
+}
+
+DEFUN (le, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} le (@var{x}, @var{y})\n\
+This function is equivalent to @code{x <= y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_le);
+}
+
+DEFUN (eq, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} eq (@var{x}, @var{y})\n\
+This function is equivalent to @code{x == y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_eq);
+}
+
+DEFUN (ge, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ge (@var{x}, @var{y})\n\
+This function is equivalent to @code{x >= y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_ge);
+}
+
+DEFUN (gt, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} gt (@var{x}, @var{y})\n\
+This function is equivalent to @code{x > y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_gt);
+}
+
+DEFUN (ne, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ne (@var{x}, @var{y})\n\
+This function is equivalent to @code{x != y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_ne);
+}
+
+DEFUN (times, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} times (@var{x}, @var{y})\n\
+This function is equivalent to @code{x .* y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_el_mul);
+}
+
+DEFUN (rdivide, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rdivide (@var{x}, @var{y})\n\
+This function is equivalent to @code{x ./ y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_el_div);
+}
+
+DEFUN (power, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} power (@var{x}, @var{y})\n\
+This function is equivalent to @code{x .^ y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_el_pow);
+}
+
+DEFUN (ldivide, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ldivide (@var{x}, @var{y})\n\
+This function is equivalent to @code{x .\\ y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_el_ldiv);
+}
+
+DEFUN (and, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} and (@var{x}, @var{y})\n\
+This function is equivalent to @code{x & y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_el_and);
+}
+
+DEFUN (or, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} or (@var{x}, @var{y})\n\
+This function is equivalent to @code{x | y}.\n\
+ at end deftypefn")
+{
+  BINARY_OP_DEFUN_BODY (op_el_or);
+}
+
+static double tic_toc_timestamp = -1.0;
+
+DEFUN (tic, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} tic ()\n\
+ at deftypefnx {Built-in Function} {} toc ()\n\
+Set or check a wall-clock timer.  Calling @code{tic} without an\n\
+output argument sets the timer.  Subsequent calls to @code{toc}\n\
+return the number of seconds since the timer was set.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+tic ();\n\
+# many computations later at dots{}\n\
+elapsed_time = toc ();\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will set the variable @code{elapsed_time} to the number of seconds since\n\
+the most recent call to the function @code{tic}.\n\
+\n\
+If called with one output argument then this function returns a scalar\n\
+of type @code{uint64} and the wall-clock timer is not started.\n\
+\n\
+ at example\n\
+ at group\n\
+t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6\n\
+     @result{} 5\n\
+ at end group\n\
+ at end example\n\
+\n\
+Nested timing with @code{tic} and @code{toc} is not supported.\n\
+Therefore @code{toc} will always return the elapsed time from the most\n\
+recent call to @code{tic}.\n\
+\n\
+If you are more interested in the CPU time that your process used, you\n\
+should use the @code{cputime} function instead.  The @code{tic} and\n\
+ at code{toc} functions report the actual wall clock time that elapsed\n\
+between the calls.  This may include time spent processing other jobs or\n\
+doing nothing at all.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+tic (); sleep (5); toc ()\n\
+     @result{} 5\n\
+t = cputime (); sleep (5); cputime () - t\n\
+     @result{} 0\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+(This example also illustrates that the CPU timer may have a fairly\n\
+coarse resolution.)\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 0)
+    warning ("tic: ignoring extra arguments");
+
+  octave_time now;
+
+  double tmp = now.double_value ();
+
+  if (nargout > 0)
+    retval = static_cast<octave_uint64> (1e6 * tmp);
+  else
+    tic_toc_timestamp = tmp;
+      
+  return retval;
+}
+
+DEFUN (toc, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} toc ()\n\
+See tic.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 0)
+    warning ("tic: ignoring extra arguments");
+
+  if (tic_toc_timestamp < 0)
+    {
+      warning ("toc called before timer set");
+      if (nargout > 0)
+	retval = Matrix ();
+    }
+  else
+    {
+      octave_time now;
+
+      double tmp = now.double_value () - tic_toc_timestamp;
+
+      if (nargout > 0)
+	retval = tmp;
+      else
+	octave_stdout << "Elapsed time is " << tmp << " seconds.\n";
+    }
+    
+  return retval;
+}
+
+DEFUN (cputime, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{total}, @var{user}, @var{system}] =} cputime ();\n\
+Return the CPU time used by your Octave session.  The first output is\n\
+the total time spent executing your process and is equal to the sum of\n\
+second and third outputs, which are the number of CPU seconds spent\n\
+executing in user mode and the number of CPU seconds spent executing in\n\
+system mode, respectively.  If your system does not have a way to report\n\
+CPU time usage, @code{cputime} returns 0 for each of its output values.\n\
+Note that because Octave used some CPU time to start, it is reasonable\n\
+to check to see if @code{cputime} works by checking to see if the total\n\
+CPU time used is nonzero.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  double usr = 0.0;
+  double sys = 0.0;
+
+  if (nargin != 0)
+    warning ("tic: ignoring extra arguments");
+
+#if defined (HAVE_GETRUSAGE)
+
+  struct rusage ru;
+
+  getrusage (RUSAGE_SELF, &ru);
+
+  usr = static_cast<double> (ru.ru_utime.tv_sec) +
+    static_cast<double> (ru.ru_utime.tv_usec) * 1e-6;
+
+  sys = static_cast<double> (ru.ru_stime.tv_sec) +
+    static_cast<double> (ru.ru_stime.tv_usec) * 1e-6;
+
+#elif defined (HAVE_TIMES) && defined (HAVE_SYS_TIMES_H)
+
+  struct tms t;
+
+  times (&t);
+
+  unsigned long ticks;
+  unsigned long seconds;
+  unsigned long fraction;
+
+  ticks = t.tms_utime + t.tms_cutime;
+  fraction = ticks % HZ;
+  seconds = ticks / HZ;
+
+  usr = static_cast<double> (seconds) + static_cast<double>(fraction) /
+    static_cast<double>(HZ);
+
+  ticks = t.tms_stime + t.tms_cstime;
+  fraction = ticks % HZ;
+  seconds = ticks / HZ;
+
+  sys = static_cast<double> (seconds) + static_cast<double>(fraction) /
+    static_cast<double>(HZ);
+
+#elif defined (__WIN32__)
+
+  HANDLE hProcess = GetCurrentProcess ();
+  FILETIME ftCreation, ftExit, ftUser, ftKernel;
+  GetProcessTimes (hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
+
+  int64_t itmp = *(reinterpret_cast<int64_t *> (&ftUser));
+  usr = static_cast<double> (itmp) * 1e-7;
+
+  itmp = *(reinterpret_cast<int64_t *> (&ftKernel));
+  sys = static_cast<double> (itmp) * 1e-7;
+
+#endif
+
+  retval (2) = sys;
+  retval (1) = usr;
+  retval (0) = sys + usr;
+
+  return retval;
+}
+
+DEFUN (sort, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x})\n\
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim})\n\
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{mode})\n\
+ at deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim}, @var{mode})\n\
+Return a copy of @var{x} with the elements arranged in increasing\n\
+order.  For matrices, @code{sort} orders the elements in each column.\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+sort ([1, 2; 2, 3; 3, 1])\n\
+     @result{}  1  1\n\
+         2  2\n\
+         3  3\n\
+ at end group\n\
+ at end example\n\
+\n\
+The @code{sort} function may also be used to produce a matrix\n\
+containing the original row indices of the elements in the sorted\n\
+matrix.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+[s, i] = sort ([1, 2; 2, 3; 3, 1])\n\
+     @result{} s = 1  1\n\
+            2  2\n\
+            3  3\n\
+     @result{} i = 1  3\n\
+            2  1\n\
+            3  2\n\
+ at end group\n\
+ at end example\n\
+\n\
+If the optional argument @var{dim} is given, then the matrix is sorted\n\
+along the dimension defined by @var{dim}.  The optional argument @code{mode}\n\
+defines the order in which the values will be sorted.  Valid values of\n\
+ at code{mode} are `ascend' or `descend'.\n\
+\n\
+For equal elements, the indices are such that the equal elements are listed\n\
+in the order that appeared in the original list.\n\
+\n\
+The @code{sort} function may also be used to sort strings and cell arrays\n\
+of strings, in which case the dictionary order of the strings is used.\n\
+\n\
+The algorithm used in @code{sort} is optimized for the sorting of partially\n\
+ordered lists.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+  sortmode smode = ASCENDING;
+
+  if (nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  bool return_idx = nargout > 1;
+
+  octave_value arg = args(0);
+
+  int dim = 0;
+  if (nargin > 1)
+    {
+      if (args(1).is_string ())
+	{
+	  std::string mode = args(1).string_value();
+	  if (mode == "ascend")
+	    smode = ASCENDING;
+	  else if (mode == "descend")
+	    smode = DESCENDING;
+	  else
+	    {
+	      error ("sort: mode must be either \"ascend\" or \"descend\"");
+	      return retval;
+	    }
+	}
+      else
+	dim = args(1).nint_value () - 1;
+    }
+
+  if (nargin > 2)
+    {
+      if (args(1).is_string ())
+	{
+	  print_usage ();
+	  return retval;
+	}
+
+      if (! args(2).is_string ())
+	{
+	  error ("sort: mode must be a string");
+	  return retval;
+	}
+      std::string mode = args(2).string_value();
+      if (mode == "ascend")
+	smode = ASCENDING;
+      else if (mode == "descend")
+	smode = DESCENDING;
+      else
+	{
+	  error ("sort: mode must be either \"ascend\" or \"descend\"");
+	  return retval;
+	}
+    }
+
+  dim_vector dv = arg.dims ();
+  if (error_state)
+    {
+      gripe_wrong_type_arg ("sort", arg);
+      return retval;
+    }
+  if (nargin == 1 || args(1).is_string ())
+    {
+      // Find first non singleton dimension
+      for (int i = 0; i < dv.length (); i++)
+	if (dv(i) > 1)
+	  {
+	    dim = i;
+	    break;
+	  }
+    }
+  else
+    {
+      if (dim < 0 || dim > dv.length () - 1)
+	{
+	  error ("sort: dim must be a valid dimension");
+	  return retval;
+	}
+    }
+
+  if (return_idx)
+    {
+      Array<octave_idx_type> sidx;
+
+      retval (0) = arg.sort (sidx, dim, smode);
+      retval (1) = NDArray (sidx, true);
+    }
+  else
+    retval(0) = arg.sort (dim, smode);
+
+  return retval;
+}
+
+/*
+
+%% Double
+%!assert (sort ([NaN, 1, -1, 2, Inf]), [-1, 1, 2, Inf, NaN])
+%!assert (sort ([NaN, 1, -1, 2, Inf], 1), [NaN, 1, -1, 2, Inf])
+%!assert (sort ([NaN, 1, -1, 2, Inf], 2), [-1, 1, 2, Inf, NaN])
+%!error (sort ([NaN, 1, -1, 2, Inf], 3))
+%!assert (sort ([NaN, 1, -1, 2, Inf], "ascend"), [-1, 1, 2, Inf, NaN])
+%!assert (sort ([NaN, 1, -1, 2, Inf], 2, "ascend"), [-1, 1, 2, Inf, NaN])
+%!assert (sort ([NaN, 1, -1, 2, Inf], "descend"), [NaN, Inf, 2, 1, -1])
+%!assert (sort ([NaN, 1, -1, 2, Inf], 2, "descend"), [NaN, Inf, 2, 1, -1])
+%!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4]), [3, 1, 6, 4; 8, 2, 7, 5])
+%!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4], 1), [3, 1, 6, 4; 8, 2, 7, 5])
+%!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4], 2), [1, 3, 5, 7; 2, 4, 6, 8])
+%!assert (sort (1), 1)
+
+%!test
+%! [v, i] = sort ([NaN, 1, -1, Inf, 1]);
+%! assert (v, [-1, 1, 1, Inf, NaN])
+%! assert (i, [3, 2, 5, 4, 1])
+
+%% Complex
+%!assert (sort ([NaN, 1i, -1, 2, Inf]), [1i, -1, 2, Inf, NaN])
+%!assert (sort ([NaN, 1i, -1, 2, Inf], 1), [NaN, 1i, -1, 2, Inf])
+%!assert (sort ([NaN, 1i, -1, 2, Inf], 2), [1i, -1, 2, Inf, NaN])
+%!error (sort ([NaN, 1i, -1, 2, Inf], 3))
+%!assert (sort ([NaN, 1i, -1, 2, Inf], "ascend"), [1i, -1, 2, Inf, NaN])
+%!assert (sort ([NaN, 1i, -1, 2, Inf], 2, "ascend"), [1i, -1, 2, Inf, NaN])
+%!assert (sort ([NaN, 1i, -1, 2, Inf], "descend"), [NaN, Inf, 2, -1, 1i])
+%!assert (sort ([NaN, 1i, -1, 2, Inf], 2, "descend"), [NaN, Inf, 2, -1, 1i])
+%!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4]), [3, 1i, 6, 4; 8, 2, 7, 5])
+%!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4], 1), [3, 1i, 6, 4; 8, 2, 7, 5])
+%!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4], 2), [1i, 3, 5, 7; 2, 4, 6, 8])
+%!assert (sort (1i), 1i)
+
+%!test
+%! [v, i] = sort ([NaN, 1i, -1, Inf, 1, 1i]);
+%! assert (v, [1, 1i, 1i, -1, Inf, NaN])
+%! assert (i, [5, 2, 6, 3, 4, 1])
+
+%% Single
+%!assert (sort (single([NaN, 1, -1, 2, Inf])), single([-1, 1, 2, Inf, NaN]))
+%!assert (sort (single([NaN, 1, -1, 2, Inf]), 1), single([NaN, 1, -1, 2, Inf]))
+%!assert (sort (single([NaN, 1, -1, 2, Inf]), 2), single([-1, 1, 2, Inf, NaN]))
+%!error (sort (single([NaN, 1, -1, 2, Inf]), 3))
+%!assert (sort (single([NaN, 1, -1, 2, Inf]), "ascend"), single([-1, 1, 2, Inf, NaN]))
+%!assert (sort (single([NaN, 1, -1, 2, Inf]), 2, "ascend"), single([-1, 1, 2, Inf, NaN]))
+%!assert (sort (single([NaN, 1, -1, 2, Inf]), "descend"), single([NaN, Inf, 2, 1, -1]))
+%!assert (sort (single([NaN, 1, -1, 2, Inf]), 2, "descend"), single([NaN, Inf, 2, 1, -1]))
+%!assert (sort (single([3, 1, 7, 5; 8, 2, 6, 4])), single([3, 1, 6, 4; 8, 2, 7, 5]))
+%!assert (sort (single([3, 1, 7, 5; 8, 2, 6, 4]), 1), single([3, 1, 6, 4; 8, 2, 7, 5]))
+%!assert (sort (single([3, 1, 7, 5; 8, 2, 6, 4]), 2), single([1, 3, 5, 7; 2, 4, 6, 8]))
+%!assert (sort (single(1)), single(1))
+
+%!test
+%! [v, i] = sort (single([NaN, 1, -1, Inf, 1]));
+%! assert (v, single([-1, 1, 1, Inf, NaN]))
+%! assert (i, [3, 2, 5, 4, 1])
+
+%% Single Complex
+%!assert (sort (single([NaN, 1i, -1, 2, Inf])), single([1i, -1, 2, Inf, NaN]))
+%!assert (sort (single([NaN, 1i, -1, 2, Inf]), 1), single([NaN, 1i, -1, 2, Inf]))
+%!assert (sort (single([NaN, 1i, -1, 2, Inf]), 2), single([1i, -1, 2, Inf, NaN]))
+%!error (sort (single([NaN, 1i, -1, 2, Inf]), 3))
+%!assert (sort (single([NaN, 1i, -1, 2, Inf]), "ascend"), single([1i, -1, 2, Inf, NaN]))
+%!assert (sort (single([NaN, 1i, -1, 2, Inf]), 2, "ascend"), single([1i, -1, 2, Inf, NaN]))
+%!assert (sort (single([NaN, 1i, -1, 2, Inf]), "descend"), single([NaN, Inf, 2, -1, 1i]))
+%!assert (sort (single([NaN, 1i, -1, 2, Inf]), 2, "descend"), single([NaN, Inf, 2, -1, 1i]))
+%!assert (sort (single([3, 1i, 7, 5; 8, 2, 6, 4])), single([3, 1i, 6, 4; 8, 2, 7, 5]))
+%!assert (sort (single([3, 1i, 7, 5; 8, 2, 6, 4]), 1), single([3, 1i, 6, 4; 8, 2, 7, 5]))
+%!assert (sort (single([3, 1i, 7, 5; 8, 2, 6, 4]), 2), single([1i, 3, 5, 7; 2, 4, 6, 8]))
+%!assert (sort (single(1i)),single( 1i))
+
+%!test
+%! [v, i] = sort (single([NaN, 1i, -1, Inf, 1, 1i]));
+%! assert (v, single([1, 1i, 1i, -1, Inf, NaN]))
+%! assert (i, [5, 2, 6, 3, 4, 1])
+
+%% Bool
+%!assert (sort ([true, false, true, false]), [false, false, true, true])
+%!assert (sort ([true, false, true, false], 1), [true, false, true, false])
+%!assert (sort ([true, false, true, false], 2), [false, false, true, true])
+%!error (sort ([true, false, true, false], 3))
+%!assert (sort ([true, false, true, false], "ascend"), [false, false, true, true])
+%!assert (sort ([true, false, true, false], 2, "ascend"), [false, false, true, true])
+%!assert (sort ([true, false, true, false], "descend"), [true, true, false, false])
+%!assert (sort ([true, false, true, false], 2, "descend"), [true, true, false, false])
+%!assert (sort (true), true)
+
+%!test
+%! [v, i] = sort ([true, false, true, false]);
+%! assert (v, [false, false, true, true])
+%! assert (i, [2, 4, 1, 3])
+
+%% Sparse Double
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf])), sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 1), sparse ([0, NaN, 1, 0, -1, 2, Inf]))
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2), sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
+%!error (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 3))
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), "ascend"), sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2, "ascend"), sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), "descend"), sparse ([NaN, Inf, 2, 1, 0, 0, -1]))
+%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2, "descend"), sparse ([NaN, Inf, 2, 1, 0, 0, -1]))
+
+%!shared a
+%! a = randn (10, 10);
+%! a (a < 0) = 0;
+%!assert (sort (sparse (a)), sparse (sort (a)))
+%!assert (sort (sparse (a), 1), sparse (sort (a, 1)))
+%!assert (sort (sparse (a), 2), sparse (sort (a, 2)))
+%!test
+%! [v, i] = sort (a);
+%! [vs, is] = sort (sparse (a));
+%! assert (vs, sparse (v))
+%! assert (is, i)
+
+%% Sparse Complex
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf])), sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 1), sparse ([0, NaN, 1i, 0, -1, 2, Inf]))
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2), sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
+%!error (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 3))
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), "ascend"), sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2, "ascend"), sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), "descend"), sparse ([NaN, Inf, 2, -1, 1i, 0, 0]))
+%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2, "descend"), sparse ([NaN, Inf, 2, -1, 1i, 0, 0]))
+
+%!shared a
+%! a = randn (10, 10); 
+%! a (a < 0) = 0;
+%! a = 1i * a;
+%!assert (sort (sparse (a)), sparse (sort (a)))
+%!assert (sort (sparse (a), 1), sparse (sort (a, 1)))
+%!assert (sort (sparse (a), 2), sparse (sort (a, 2)))
+%!test
+%! [v, i] = sort (a);
+%! [vs, is] = sort (sparse (a));
+%! assert (vs, sparse (v))
+%! assert (is, i)
+
+%% Sparse Bool
+%!assert (sort (sparse ([true, false, true, false])), sparse ([false, false, true, true]))
+%!assert (sort (sparse([true, false, true, false]), 1), sparse ([true, false, true, false]))
+%!assert (sort (sparse ([true, false, true, false]), 2), sparse ([false, false, true, true]))
+%!error (sort (sparse ([true, false, true, false], 3)))
+%!assert (sort (sparse ([true, false, true, false]), "ascend"), sparse([false, false, true, true]))
+%!assert (sort (sparse ([true, false, true, false]), 2, "ascend"), sparse([false, false, true, true]))
+%!assert (sort (sparse ([true, false, true, false]), "descend"), sparse ([true, true, false, false]))
+%!assert (sort (sparse ([true, false, true, false]), 2, "descend"), sparse([true, true, false, false]))
+
+%!test
+%! [v, i] = sort (sparse([true, false, true, false]));
+%! assert (v, sparse([false, false, true, true]))
+%! assert (i, [2, 4, 1, 3])
+
+%% Cell string array
+%!shared a, b, c
+%! a = {"Alice", "Cecile", "Eric", "Barry", "David"};
+%! b = {"Alice", "Barry", "Cecile", "David", "Eric"};
+%! c = {"Eric", "David", "Cecile", "Barry", "Alice"};
+%!assert (sort (a), b);
+%!assert (sort (a, 1), a)
+%!assert (sort (a, 2), b)
+%!error (sort (a, 3))
+%!assert (sort (a, "ascend"), b)
+%!assert (sort (a, 2, "ascend"), b)
+%!assert (sort (a, "descend"), c)
+%!assert (sort (a, 2, "descend"), c)
+
+%!test
+%! [v, i] = sort (a);
+%! assert (i, [1, 4, 2, 5, 3])
+
+%!error <Invalid call to sort.*> sort ();
+%!error <Invalid call to sort.*> sort (1, 2, 3, 4);
+
+*/
+
+// Sort the rows of the matrix @var{a} according to the order
+// specified by @var{mode}, which can either be `ascend' or `descend'
+// and return the index vector corresponding to the sort order.
+//
+// This function does not yet support sparse matrices.
+
+DEFUN (__sort_rows_idx__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __sort_rows_idx__ (@var{a}, @var{mode})\n\
+Undocumented internal function.\n\
+ at end deftypefn\n")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+  sortmode smode = ASCENDING;
+
+  if (nargin < 1 || nargin > 2 || (nargin == 2 && ! args(1).is_string ()))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (nargin > 1)
+    {
+      std::string mode = args(1).string_value();
+      if (mode == "ascend")
+        smode = ASCENDING;
+      else if (mode == "descend")
+        smode = DESCENDING;
+      else
+        {
+          error ("__sort_rows_idx__: mode must be either \"ascend\" or \"descend\"");
+          return retval;
+        }
+    }
+
+  octave_value arg = args(0);
+
+  if (arg.is_sparse_type ())
+    error ("__sort_rows_idx__: sparse matrices not yet supported");
+  if (arg.ndims () == 2)
+    {
+      Array<octave_idx_type> idx = arg.sort_rows_idx (smode);
+
+      retval = NDArray (idx, true);
+    }
+  else
+    error ("__sort_rows_idx__: needs a 2-dimensional object");
+
+  return retval;
+}
+
+DEFUN (issorted, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} issorted (@var{a}, @var{rows})\n\
+Returns true if the array is sorted, ascending or descending.\n\
+NaNs are treated as by @code{sort}.  If @var{rows} is supplied and\n\
+has the value \"rows\", checks whether the array is sorted by rows\n\
+as if output by @code{sortrows} (with no options).\n\
+\n\
+This function does not yet support sparse matrices.\n\
+ at seealso{sortrows, sort}\n\
+ at end deftypefn\n")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+      if (arg.dims ().is_vector ())
+        retval = args(0).is_sorted () != UNSORTED;
+      else
+        error ("issorted: needs a vector");
+    }
+  else if (nargin == 2)
+    {
+      if (args(1).is_string () && args(1).string_value () == "rows")
+        {
+          octave_value arg = args(0);
+          sortmode smode = ASCENDING;
+
+          if (arg.is_sparse_type ())
+            error ("issorted: sparse matrices not yet supported");
+          if (arg.ndims () == 2)
+            retval = arg.is_sorted_rows (smode) != UNSORTED;
+          else
+            error ("issorted: needs a 2-dimensional object");
+        }
+      else
+        error ("issorted: second argument must be \"rows\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+template <class NDT>
+static NDT 
+do_accumarray_sum (const idx_vector& idx, const NDT& vals,
+                   octave_idx_type n = -1)
+{
+  typedef typename NDT::element_type T;
+  if (n < 0)
+    n = idx.extent (0);
+  else if (idx.extent (n) > n)
+    error ("accumarray: index out of range");
+
+  // FIXME: the class tree in liboctave is overly complicated, hence the
+  // following type gymnastics.
+  MArray<T> array;
+
+  if (vals.numel () == 1)
+    {
+      array = MArray<T> (n, T ());
+      array.idx_add (idx, vals (0));
+    }
+  else if (vals.length () == idx.length (n))
+    {
+      array = MArray<T> (n, T ());
+      array.idx_add (idx, MArray<T> (vals));
+    }
+  else
+    error ("accumarray: dimensions mismatch");
+
+  return NDT (MArrayN<T> (ArrayN<T> (array)));
+}
+
+DEFUN (__accumarray_sum__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __accumarray_sum__ (@var{idx}, @var{vals}, @var{n})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length ();
+  if (nargin >= 2 && nargin <= 3 && args(0).is_numeric_type ())
+    {
+      idx_vector idx = args(0).index_vector ();
+      octave_idx_type n = -1;
+      if (nargin == 3)
+        n = args(2).idx_type_value (true);
+
+      if (! error_state)
+        {
+          octave_value vals = args(1);
+          if (vals.is_range ())
+            {
+              Range r = vals.range_value ();
+              if (r.inc () == 0)
+                vals = r.base ();
+            }
+
+          if (vals.is_single_type ())
+            {
+              if (vals.is_complex_type ())
+                retval = do_accumarray_sum (idx, vals.float_complex_array_value (), n);
+              else
+                retval = do_accumarray_sum (idx, vals.float_array_value (), n);
+            }
+          else if (vals.is_numeric_type ())
+            {
+              if (vals.is_complex_type ())
+                retval = do_accumarray_sum (idx, vals.complex_array_value (), n);
+              else
+                retval = do_accumarray_sum (idx, vals.array_value (), n);
+            }
+          else
+            gripe_wrong_type_arg ("accumarray", vals);
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;  
+}
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/debug.cc b/src/debug.cc
new file mode 100644
index 0000000..281df6f
--- /dev/null
+++ b/src/debug.cc
@@ -0,0 +1,1124 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 John Swensen
+Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ben Sapp
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <deque>
+#include <fstream>
+#include <iostream>
+#include <set>
+#include <string>
+
+#include "file-stat.h"
+
+#include "defun.h"
+#include "error.h"
+#include "help.h"
+#include "input.h"
+#include "pager.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "parse.h"
+#include "symtab.h"
+#include "gripes.h"
+#include "ov.h"
+#include "ov-usr-fcn.h"
+#include "ov-fcn.h"
+#include "ov-list.h"
+#include "ov-struct.h"
+#include "pt-pr-code.h"
+#include "pt-bp.h"
+#include "pt-eval.h"
+#include "pt-stmt.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "variables.h"
+
+#include "debug.h"
+
+// Initialize the singleton object
+bp_table *bp_table::instance = 0;
+
+static std::string
+snarf_file (const std::string& fname)
+{
+  std::string retval;
+
+  file_stat fs (fname);
+
+  if (fs)
+    {
+      size_t sz = fs.size ();
+
+      std::ifstream file (fname.c_str (), std::ios::in|std::ios::binary);
+
+      if (file)
+	{
+	  std::string buf (sz+1, 0);
+
+	  file.read (&buf[0], sz+1);
+
+	  if (file.eof ())
+	    {
+	      // Expected to read the entire file.
+
+	      retval = buf;
+	    }
+	  else
+	    error ("error reading file %s", fname.c_str ());
+	}
+    }
+
+  return retval;
+}
+
+static std::deque<size_t>
+get_line_offsets (const std::string& buf)
+{
+  // This could maybe be smarter.  Is deque the right thing to use
+  // here?
+
+  std::deque<size_t> offsets;
+
+  offsets.push_back (0);
+
+  size_t len = buf.length ();
+
+  for (size_t i = 0; i < len; i++)
+    {
+      char c = buf[i];
+
+      if (c == '\r' && ++i < len)
+	{
+	  c = buf[i];
+
+	  if (c == '\n')
+	    offsets.push_back (i+1);
+	  else
+	    offsets.push_back (i);
+	}
+      else if (c == '\n')
+	offsets.push_back (i+1);
+    }
+
+  offsets.push_back (len);
+
+  return offsets;
+}
+
+std::string
+get_file_line (const std::string& fname, size_t line)
+{
+  std::string retval;
+
+  static std::string last_fname;
+
+  static std::string buf;
+
+  static std::deque<size_t> offsets;
+
+  if (fname != last_fname)
+    {
+      buf = snarf_file (fname);
+
+      offsets = get_line_offsets (buf);
+    }
+
+  if (line > 0)
+    line--;
+
+  if (line < offsets.size () - 1)
+    {
+      size_t bol = offsets[line];
+      size_t eol = offsets[line+1];
+
+      while (eol > 0 && (buf[eol-1] == '\n' || buf[eol-1] == '\r'))
+	eol--;
+
+      retval = buf.substr (bol, eol - bol);
+    }
+
+  return retval;
+}
+
+// Return a pointer to the user-defined function FNAME.  If FNAME is
+// empty, search backward for the first user-defined function in the
+// current call stack.
+
+static octave_user_code *
+get_user_code (const std::string& fname = std::string ())
+{
+  octave_user_code *dbg_fcn = 0;
+
+  if (fname.empty ())
+    dbg_fcn = octave_call_stack::caller_user_code ();
+  else
+    {
+      octave_value fcn = symbol_table::find_function (fname);
+
+      if (fcn.is_defined () && fcn.is_user_code ())
+	dbg_fcn = fcn.user_code_value ();
+    }
+
+  return dbg_fcn;
+}
+
+static void
+parse_dbfunction_params (const char *who, const octave_value_list& args, 
+			 std::string& symbol_name, bp_table::intmap& lines)
+{
+  int nargin = args.length ();
+  int idx = 0;
+  int list_idx = 0;
+  symbol_name = std::string ();
+  lines = bp_table::intmap ();
+
+  if (args.length () == 0)
+    return;
+
+  // If we are already in a debugging function.
+  if (octave_call_stack::caller_user_code ())
+    {
+      idx = 0;
+      symbol_name = get_user_code ()->name ();
+    }
+  else if (args(0).is_map ())
+    {
+      // Problem because parse_dbfunction_params() can only pass out a
+      // single function
+    }
+  else if (args(0).is_string())
+    {
+      symbol_name = args(0).string_value ();
+      if (error_state)
+	return;
+      idx = 1;
+    }
+  else
+    error ("%s: invalid parameter specified", who);
+
+  for (int i = idx; i < nargin; i++ )
+    {
+      if (args(i).is_string ())
+	{
+	  int line = atoi (args(i).string_value().c_str ());
+	  if (error_state)
+	    break;
+	  lines[list_idx++] = line;
+	}
+      else if (args(i).is_map ())
+	octave_stdout << who << ": accepting a struct" << std::endl;
+      else
+	{
+	  const NDArray arg = args(i).array_value ();
+	  
+	  if (error_state)
+	    break;
+	  
+	  for (octave_idx_type j = 0; j < arg.nelem (); j++)
+	    {
+	      int line = static_cast<int> (arg.elem (j));
+	      if (error_state)
+		break;
+	      lines[list_idx++] = line;
+	    }
+	  
+	  if (error_state)
+	    break;
+	}
+    } 
+}
+
+bp_table::intmap
+bp_table::do_add_breakpoint (const std::string& fname, 
+			     const bp_table::intmap& line)
+{
+  intmap retval;
+
+  octave_idx_type len = line.size ();
+
+  octave_user_code *dbg_fcn = get_user_code (fname);
+
+  if (dbg_fcn)
+    {
+      tree_statement_list *cmds = dbg_fcn->body ();
+
+      if (cmds)
+	{
+	  for (int i = 0; i < len; i++)
+	    {
+	      const_intmap_iterator p = line.find (i);
+
+	      if (p != line.end ())
+		{
+		  int lineno = p->second;
+
+		  retval[i] = cmds->set_breakpoint (lineno);
+
+		  if (retval[i] != 0)
+		    {
+		      bp_set.insert (fname);
+		    }
+		}
+	    }
+	}
+    }
+  else
+    error ("add_breakpoint: unable to find the function requested\n");
+
+  tree_evaluator::debug_mode = bp_table::have_breakpoints ();
+
+  return retval;
+}
+
+
+int 
+bp_table::do_remove_breakpoint (const std::string& fname, 
+				const bp_table::intmap& line)
+{
+  int retval = 0;
+
+  octave_idx_type len = line.size ();
+
+  if (len == 0)
+    {
+      intmap results = remove_all_breakpoints_in_file (fname);
+      retval = results.size ();
+    }
+  else
+    {
+      octave_user_code *dbg_fcn = get_user_code (fname);
+
+      if (dbg_fcn)
+	{
+	  tree_statement_list *cmds = dbg_fcn->body ();
+
+	  if (cmds)
+	    {
+	      octave_value_list results = cmds->list_breakpoints ();
+
+	      if (results.length () > 0)
+		{
+		  for (int i = 0; i < len; i++)
+		    {
+		      const_intmap_iterator p = line.find (i);
+
+		      if (p != line.end ())
+			cmds->delete_breakpoint (p->second);
+		    }
+
+		  results = cmds->list_breakpoints ();
+
+		  bp_set_iterator it = bp_set.find (fname);
+		  if (results.length () == 0 && it != bp_set.end ())
+		    bp_set.erase (it);
+
+		}
+
+	      retval = results.length ();
+	    }
+	}
+      else
+	error ("remove_breakpoint: unable to find the function requested\n");
+    }
+
+  tree_evaluator::debug_mode = bp_table::have_breakpoints ();
+
+  return retval;
+}
+
+
+bp_table::intmap
+bp_table::do_remove_all_breakpoints_in_file (const std::string& fname, 
+					     bool silent)
+{
+  intmap retval;
+
+  octave_user_code *dbg_fcn = get_user_code (fname);
+  
+  if (dbg_fcn)
+    {
+      tree_statement_list *cmds = dbg_fcn->body ();
+
+      if (cmds)
+	{
+	  octave_value_list bkpts = cmds->list_breakpoints ();
+
+	  for (int i = 0; i < bkpts.length (); i++)
+	    {
+	      int lineno = static_cast<int> (bkpts(i).int_value ());
+	      cmds->delete_breakpoint (lineno);
+	      retval[i] = lineno;
+	    }
+
+	  bp_set_iterator it = bp_set.find (fname);
+	  if (it != bp_set.end ())
+	    bp_set.erase (it);
+
+	}
+    }
+  else if (! silent)
+    error ("remove_all_breakpoint_in_file: "
+	   "unable to find the function requested\n");
+
+  tree_evaluator::debug_mode = bp_table::have_breakpoints ();
+
+  return retval;
+}
+
+void 
+bp_table::do_remove_all_breakpoints (void)
+{
+  for (const_bp_set_iterator it = bp_set.begin (); it != bp_set.end (); it++)
+    remove_all_breakpoints_in_file (*it);
+
+
+  tree_evaluator::debug_mode = bp_table::have_breakpoints ();
+}
+
+std::string 
+do_find_bkpt_list (octave_value_list slist, 
+		   std::string match)
+{
+  std::string retval;
+
+  for (int i = 0; i < slist.length (); i++)
+    {
+      if (slist (i).string_value () == match)
+	{
+	  retval = slist(i).string_value ();
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+
+bp_table::fname_line_map
+bp_table::do_get_breakpoint_list (const octave_value_list& fname_list)
+{
+  fname_line_map retval;
+
+  for (bp_set_iterator it = bp_set.begin (); it != bp_set.end (); it++)
+    {
+      if (fname_list.length () == 0
+	  || do_find_bkpt_list (fname_list, *it) != "")
+	{
+	  octave_user_code *f = get_user_code (*it);
+
+	  if (f)
+	    {
+	      tree_statement_list *cmds = f->body ();
+
+	      if (cmds)
+		{
+		  octave_value_list bkpts = cmds->list_breakpoints ();
+		  octave_idx_type len = bkpts.length (); 
+
+		  if (len > 0)
+		    {
+		      bp_table::intmap bkpts_vec;
+		      
+		      for (int i = 0; i < len; i++)
+			bkpts_vec[i] = bkpts (i).double_value ();
+		      
+		      std::string symbol_name = f->name ();
+
+		      retval[symbol_name] = bkpts_vec;
+		    }
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_value
+intmap_to_ov (const bp_table::intmap& line) 
+{
+  int idx = 0;
+
+  NDArray retval (dim_vector (1, line.size ()));
+
+  for (size_t i = 0; i < line.size (); i++)
+    {
+      bp_table::const_intmap_iterator p = line.find (i);
+
+      if (p != line.end ())
+	{
+	  int lineno = p->second;
+	  retval(idx++) = lineno;
+	}
+    }
+
+  retval.resize (dim_vector (1, idx));
+
+  return retval;
+}
+
+DEFUN (dbstop, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {@var{rline} =} dbstop (@var{func}, @var{line}, @dots{})\n\
+Set a breakpoint in a function\n\
+ at table @code\n\
+ at item func\n\
+String representing the function name.  When already in debug\n\
+mode this should be left out and only the line should be given.\n\
+ at item line\n\
+Line number you would like the breakpoint to be set on.  Multiple\n\
+lines might be given as separate arguments or as a vector.\n\
+ at end table\n\
+\n\
+The rline returned is the real line that the breakpoint was set at.\n\
+ at seealso{dbclear, dbstatus, dbstep}\n\
+ at end deftypefn")
+{
+  bp_table::intmap retval;
+  std::string symbol_name;
+  bp_table::intmap lines;
+
+  parse_dbfunction_params ("dbstop", args, symbol_name, lines);
+
+  if (lines.size () == 0)
+    lines[0] = 1;
+
+  if (! error_state)
+    retval = bp_table::add_breakpoint (symbol_name, lines);
+
+  return intmap_to_ov (retval);
+}
+
+DEFUN (dbclear, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dbclear (@var{func}, @var{line}, @dots{})\n\
+Delete a breakpoint in a function\n\
+ at table @code\n\
+ at item func\n\
+String representing the function name.  When already in debug\n\
+mode this should be left out and only the line should be given.\n\
+ at item line\n\
+Line number where you would like to remove the breakpoint.  Multiple\n\
+lines might be given as separate arguments or as a vector.\n\
+ at end table\n\
+No checking is done to make sure that the line you requested is really\n\
+a breakpoint.  If you get the wrong line nothing will happen.\n\
+ at seealso{dbstop, dbstatus, dbwhere}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  std::string symbol_name = "";
+  bp_table::intmap lines;
+
+  parse_dbfunction_params ("dbclear", args, symbol_name, lines);
+      
+  if (! error_state)
+    bp_table::remove_breakpoint (symbol_name, lines);
+
+  return retval;
+}
+
+DEFUN (dbstatus, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {lst =} dbstatus (@var{func})\n\
+Return a vector containing the lines on which a function has \n\
+breakpoints set.\n\
+ at table @code\n\
+ at item func\n\
+String representing the function name.  When already in debug\n\
+mode this should be left out.\n\
+ at end table\n\
+ at seealso{dbclear, dbwhere}\n\
+ at end deftypefn")
+{
+  Octave_map retval;
+  int nargin = args.length ();
+  octave_value_list fcn_list;
+  bp_table::fname_line_map bp_list;
+  std::string symbol_name;
+
+  if (nargin != 0 && nargin != 1)
+    {
+      error ("dbstatus: only zero or one arguements accepted\n");
+      return octave_value ();
+    }
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	{
+	  symbol_name = args(0).string_value ();
+	  fcn_list(0) = symbol_name;
+	  bp_list = bp_table::get_breakpoint_list (fcn_list);
+	}
+      else
+	gripe_wrong_type_arg ("dbstatus", args(0));
+    }
+  else
+    {
+       octave_user_code *dbg_fcn = get_user_code ();
+       if (dbg_fcn)
+	 {
+	   symbol_name = dbg_fcn->name ();
+	   fcn_list(0) = symbol_name;
+	 }
+
+       bp_list = bp_table::get_breakpoint_list (fcn_list);
+    }
+
+  if (nargout == 0)
+    {
+      // Print out the breakpoint information.
+
+      for (bp_table::fname_line_map_iterator it = bp_list.begin ();
+	   it != bp_list.end (); it++)
+	{	  
+	  octave_stdout << "Breakpoint in " << it->first << " at line(s) ";
+
+	  bp_table::intmap m = it->second;
+
+	  size_t nel = m.size ();
+
+	  for (size_t j = 0; j < nel; j++)
+	    octave_stdout << m[j] << ((j < nel - 1) ? ", " : ".");
+
+	  if (nel > 0)
+	    octave_stdout << std::endl;
+	}
+      return octave_value ();
+    }
+  else
+    {
+      // Fill in an array for return.
+
+      int i = 0;
+      Cell names (dim_vector (bp_list.size (), 1));
+      Cell file (dim_vector (bp_list.size (), 1));
+      Cell line (dim_vector (bp_list.size (), 1));
+
+      for (bp_table::const_fname_line_map_iterator it = bp_list.begin ();
+	   it != bp_list.end (); it++)
+	{
+	  names(i) = it->first;
+	  line(i) = intmap_to_ov (it->second);
+	  file(i) = do_which (it->first);
+	  i++;
+	}
+
+      retval.assign ("name", names);
+      retval.assign ("file", file);
+      retval.assign ("line", line);
+
+      return octave_value (retval);
+    }
+}
+
+DEFUN (dbwhere, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dbwhere ()\n\
+Show where we are in the code\n\
+ at seealso{dbclear, dbstatus, dbstop}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  octave_user_code *dbg_fcn = get_user_code ();
+
+  if (dbg_fcn)
+    {
+      bool have_file = true;
+
+      std::string name = dbg_fcn->fcn_file_name ();
+
+      if (name.empty ())
+	{
+	  have_file = false;
+
+	  name = dbg_fcn->name ();
+	}
+
+      octave_stdout << name << ":";
+
+      int l = tree_evaluator::debug_line ();
+
+      if (l > 0)
+	{
+	  octave_stdout << " line " << l;
+
+	  int c = tree_evaluator::debug_column ();
+
+	  if (c > 0)
+	    octave_stdout << ", column " << c;
+
+	  octave_stdout << std::endl;
+
+	  if (have_file)
+	    {
+	      std::string line = get_file_line (name, l);
+
+	      if (! line.empty ())
+		octave_stdout << l << ": " << line << std::endl;
+	    }
+	}
+      else
+	octave_stdout << " (unknown line)\n";
+    }
+  else
+    error ("dbwhere: must be inside of a user function to use dbwhere\n");
+
+  return retval;
+}
+
+// Copied and modified from the do_type command in help.cc
+// Maybe we could share some code?
+void
+do_dbtype (std::ostream& os, const std::string& name, int start, int end)
+{
+  std::string ff = fcn_file_in_path (name);
+
+  if (! ff.empty ())
+    {
+      std::ifstream fs (ff.c_str (), std::ios::in);
+
+      if (fs)
+	{
+	  char ch;
+	  int line = 1;
+	
+	  if (line >= start && line <= end)
+	    os << line << "\t";
+ 	
+	  while (fs.get (ch))
+	    {
+	      if (line >= start && line <= end)
+		{
+		  os << ch;
+		}
+
+	      if (ch == '\n')
+		{
+		  line++;
+		  if (line >= start && line <= end)
+		    os << line << "\t";
+		}
+	    }
+	}
+      else
+	os << "dbtype: unable to open `" << ff << "' for reading!\n";
+    }
+  else
+    os << "dbtype: unknown function " << name << "\n";
+
+  os.flush ();
+}
+
+DEFUN (dbtype, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dbtype ()\n\
+List script file with line numbers.\n\
+ at seealso{dbclear, dbstatus, dbstop}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  octave_user_code *dbg_fcn;
+
+  int nargin = args.length ();
+  string_vector argv = args.make_argv ("dbtype");
+
+  if (! error_state)
+    {
+      switch (nargin)
+	{
+	case 0: // dbtype
+	  dbg_fcn = get_user_code ();
+
+	  if (dbg_fcn)
+	    do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX);
+	  else
+	    error ("dbtype: must be in a user function to give no arguments to dbtype\n");
+	  break;
+
+	case 1: // (dbtype func) || (dbtype start:end)
+	  dbg_fcn = get_user_code (argv[1]);
+
+	  if (dbg_fcn)
+	    do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX);
+	  else
+	    {
+	      dbg_fcn = get_user_code ();
+
+	      if (dbg_fcn)
+		{
+		  std::string arg = argv[1];
+
+		  size_t ind = arg.find (':');
+
+		  if (ind != std::string::npos)
+		    {
+		      std::string start_str = arg.substr (0, ind);
+		      std::string end_str = arg.substr (ind + 1);
+
+		      int start = atoi (start_str.c_str ());
+		      int end = atoi (end_str.c_str ());
+		
+		      if (std::min (start, end) <= 0)
+ 			error ("dbtype: start and end lines must be >= 1\n");
+
+		      if (start <= end)
+			do_dbtype (octave_stdout, dbg_fcn->name (), start, end);
+		      else
+			error ("dbtype: start line must be less than end line\n");
+		    }
+		  else
+		    error ("dbtype: line specification must be `start:end'");
+		}
+	    }
+	  break;
+
+	case 2: // (dbtype func start:end) , (dbtype func start)
+	  dbg_fcn = get_user_code (argv[1]);
+
+	  if (dbg_fcn)
+	    {
+	      std::string arg = argv[2];
+	      int start = 0;
+	      int end = 0;
+	      size_t ind = arg.find (':');
+
+	      if (ind != std::string::npos)
+		{
+		  std::string start_str = arg.substr (0, ind);
+		  std::string end_str = arg.substr (ind + 1);
+
+		  start = atoi (start_str.c_str ());
+		  end = atoi (end_str.c_str ());
+		  
+		}
+	      else
+		{
+		  start = atoi (arg.c_str ());
+		  end = start;
+		}
+
+	      if (std::min (start, end) <= 0)
+		error ("dbtype: start and end lines must be >= 1\n");
+	      
+	      if (start <= end)
+		do_dbtype (octave_stdout, dbg_fcn->name (), start, end);
+	      else
+		error ("dbtype: start line must be less than end line\n");
+	    }
+	  break;
+
+	default:
+	  error ("dbtype: expecting zero, one, or two arguments\n");
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (dbstack, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{stack}, @var{idx}]} dbstack (@var{n})\n\
+Print or return current stack information.  With optional argument\n\
+ at var{n}, omit the @var{n} innermost stack frames.\n\
+ at seealso{dbclear, dbstatus, dbstop}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  unwind_protect::begin_frame ("Fdbstack");
+
+  octave_idx_type curr_frame = -1;
+
+  size_t nskip = 0;
+
+  if (args.length () == 1)
+    {
+      int n = 0;
+
+      octave_value arg = args(0);
+
+      if (arg.is_string ())
+	{
+	  std::string s_arg = arg.string_value ();
+
+	  n = atoi (s_arg.c_str ());
+	}
+      else
+	n = args(0).int_value ();
+
+      if (n > 0)
+	nskip = n;
+      else
+	error ("dbstack: expecting N to be a nonnegative integer");
+    }
+
+  if (! error_state)
+    {
+      Octave_map stk = octave_call_stack::backtrace (nskip, curr_frame);
+
+      if (nargout == 0)
+	{
+	  octave_idx_type nframes_to_display = stk.numel ();
+
+	  if (nframes_to_display > 0)
+	    {
+	      octave_stdout << "Stopped in:\n\n";
+
+	      Cell names = stk.contents ("name");
+	      Cell lines = stk.contents ("line");
+	      Cell columns = stk.contents ("column");
+
+	      for (octave_idx_type i = 0; i < nframes_to_display; i++)
+		{
+		  octave_value name = names(i);
+		  octave_value line = lines(i);
+		  octave_value column = columns(i);
+
+		  octave_stdout << (i == curr_frame ? "--> " : "    ")
+				<< name.string_value ()
+				<< " at line " << line.int_value ()
+				<< " column " << column.int_value ()
+				<< std::endl;
+		}
+	    }
+	}
+      else
+	{
+	  retval(1) = curr_frame < 0 ? 1 : curr_frame + 1;
+	  retval(0) = stk;
+	}
+    }
+
+  unwind_protect::run_frame ("Fdbstack");
+
+  return retval;
+}
+
+static void
+do_dbupdown (const octave_value_list& args, const std::string& who)
+{
+  int n = 1;
+
+  if (args.length () == 1)
+    {
+      octave_value arg = args(0);
+
+      if (arg.is_string ())
+	{
+	  std::string s_arg = arg.string_value ();
+
+	  n = atoi (s_arg.c_str ());
+	}
+      else
+	n = args(0).int_value ();
+    }
+
+  if (! error_state)
+    {
+      if (who == "dbup")
+	n = -n;
+
+      if (! octave_call_stack::goto_frame_relative (n, true))
+	error ("%s: invalid stack frame", who.c_str ());
+    }
+}
+
+DEFUN (dbup, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dbup (@var{n})\n\
+In debugging mode, move up the execution stack @var{n} frames.\n\
+If @var{n} is omitted, move up one frame.\n\
+ at seealso{dbstack}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  do_dbupdown (args, "dbup");
+
+  return retval;
+}
+
+DEFUN (dbdown, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {} dbdown (@var{n})\n\
+In debugging mode, move down the execution stack @var{n} frames.\n\
+If @var{n} is omitted, move down one frame.\n\
+ at seealso{dbstack}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  do_dbupdown (args, "dbdown");
+
+  return retval;
+}
+
+DEFUN (dbstep, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Command} {} dbstep @var{n}\n\
+ at deftypefnx {Command} {} dbstep in\n\
+ at deftypefnx {Command} {} dbstep out\n\
+In debugging mode, execute the next @var{n} lines of code.  If @var{n} is\n\
+omitted execute the next line of code.  If the next line of code is itself\n\
+defined in terms of an m-file remain in the existing function.\n\
+\n\
+Using @code{dbstep in} will cause execution of the next line to step into\n\
+any m-files defined on the next line.  Using @code{dbstep out} with cause\n\
+execution to continue until the current function returns.\n\
+ at seealso{dbcont, dbquit}\n\
+ at end deftypefn")
+{
+  if (Vdebugging)
+    {
+      int nargin = args.length ();
+      
+      if (nargin > 1)
+	print_usage ();
+      else if (nargin == 1)
+	{
+	  if (args(0).is_string ())
+	    {
+	      std::string arg = args(0).string_value ();
+
+	      if (! error_state)
+		{
+		  if (arg == "in")
+		    {
+		      Vdebugging = false;
+
+		      tree_evaluator::dbstep_flag = -1;
+		    }
+		  else if (arg == "out")
+		    {
+		      Vdebugging = false;
+
+		      tree_evaluator::dbstep_flag = -2;
+		    }
+		  else
+		    {
+		      int n = atoi (arg.c_str ());
+
+		      if (n > 0)
+			{
+			  Vdebugging = false;
+
+			  tree_evaluator::dbstep_flag = n;
+			}
+		      else
+			error ("dbstep: invalid argument");
+		    }
+		}
+	    }
+	  else
+	    error ("dbstep: expecting character string as argument");
+	}
+      else
+	{
+	  Vdebugging = false;
+
+	  tree_evaluator::dbstep_flag = 1;
+	}
+    }
+  else
+    error ("dbstep: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+DEFALIAS (dbnext, dbstep);
+
+DEFUN (dbcont, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Command} {} dbcont ()\n\
+In debugging mode, quit debugging mode and continue execution.\n\
+ at seealso{dbstep, dbstep}\n\
+ at end deftypefn")
+{
+  if (Vdebugging)
+    {
+      if (args.length () == 0)
+	{
+	  Vdebugging = false;
+
+	  tree_evaluator::dbstep_flag = 0;
+	}
+      else
+	print_usage ();
+    }
+  else
+    error ("dbcont: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+DEFUN (dbquit, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Command} {} dbquit ()\n\
+In debugging mode, quit debugging mode and return to the top level.\n\
+ at seealso{dbstep, dbcont}\n\
+ at end deftypefn")
+{
+  if (Vdebugging)
+    {
+      if (args.length () == 0)
+	{
+	  tree_evaluator::dbstep_flag = 0;
+
+	  octave_throw_interrupt_exception ();
+	}
+      else
+	print_usage ();
+    }
+  else
+    error ("dbquit: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+DEFUN (isdebugmode, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Command} {} isdebugmode ()\n\
+Return true if debug mode is on, otherwise false.\n\
+ at seealso{dbstack, dbclear, dbstop, dbstatus}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = Vdebugging;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/debug.h b/src/debug.h
new file mode 100644
index 0000000..97fb243
--- /dev/null
+++ b/src/debug.h
@@ -0,0 +1,152 @@
+/*
+
+Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Ben Sapp
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_debug_h)
+#define octave_debug_h 1
+
+#include <map>
+#include <set>
+#include "ov.h"
+#include "dRowVector.h"
+
+class octave_value_list;
+class octave_user_code;
+
+// Interface to breakpoints,.
+
+class
+OCTINTERP_API
+bp_table
+{
+private:
+
+  bp_table (void) { }
+
+  ~bp_table (void) { }
+
+public:
+
+  typedef std::map<int, int> intmap;
+
+  typedef intmap::const_iterator const_intmap_iterator;
+  typedef intmap::iterator intmap_iterator;
+
+  typedef std::map <std::string, intmap> fname_line_map;
+
+  typedef fname_line_map::const_iterator const_fname_line_map_iterator;
+  typedef fname_line_map::iterator fname_line_map_iterator;
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new bp_table ();
+
+    if (! instance)
+      {
+        ::error ("unable to create breakpoint table!");
+        retval = false;
+      }
+    
+    return retval;
+  }
+
+  // Add a breakpoint at the nearest executable line.
+  static intmap add_breakpoint (const std::string& fname = "", 
+				const intmap& lines = intmap ())
+  {
+    return instance_ok ()
+      ? instance->do_add_breakpoint (fname, lines) : intmap ();
+  }
+
+  // Remove a breakpoint from a line in file.
+  static int remove_breakpoint (const std::string& fname = "", 
+				const intmap& lines = intmap ())
+  {
+    return instance_ok ()
+      ? instance->do_remove_breakpoint (fname, lines) : 0;
+  }
+
+  // Remove all the breakpoints in a specified file.
+  static intmap remove_all_breakpoints_in_file (const std::string& fname,
+						bool silent = false)
+  {
+    return instance_ok ()
+      ? instance->do_remove_all_breakpoints_in_file (fname, silent) : intmap ();
+  }
+  
+  // Remove all the breakpoints registered with octave.
+  static void remove_all_breakpoints (void)
+  {
+    if (instance_ok ())
+      instance->do_remove_all_breakpoints ();
+  }
+  
+  // Return all breakpoints.  Each element of the map is a vector
+  // containing the breakpoints corresponding to a given function name.
+  static fname_line_map
+  get_breakpoint_list (const octave_value_list& fname_list)
+  {
+    return instance_ok ()
+      ? instance->do_get_breakpoint_list (fname_list) : fname_line_map ();
+  }
+
+  static bool
+  have_breakpoints (void)
+  {
+    return instance_ok () ? instance->do_have_breakpoints () : 0;
+  }
+
+private:
+
+  typedef std::set<std::string>::const_iterator const_bp_set_iterator;
+  typedef std::set<std::string>::iterator bp_set_iterator;
+
+  // Set of function names containing at least one breakpoint.
+  std::set<std::string> bp_set;
+
+  static bp_table *instance;
+
+  intmap do_add_breakpoint (const std::string& fname, const intmap& lines);
+
+  int do_remove_breakpoint (const std::string&, const intmap& lines);
+
+  intmap do_remove_all_breakpoints_in_file (const std::string& fname, 
+					    bool silent);
+
+  void do_remove_all_breakpoints (void);
+
+  fname_line_map do_get_breakpoint_list (const octave_value_list& fname_list);
+
+  bool do_have_breakpoints (void) { return (! bp_set.empty ()); }
+};
+
+std::string get_file_line (const std::string& fname, size_t line);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/defaults.cc b/src/defaults.cc
new file mode 100644
index 0000000..58ee2a4
--- /dev/null
+++ b/src/defaults.cc
@@ -0,0 +1,491 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "dir-ops.h"
+#include "oct-env.h"
+#include "file-stat.h"
+#include "pathsearch.h"
+#include "str-vec.h"
+
+#include <defaults.h>
+#include "defun.h"
+#include "error.h"
+#include "file-ops.h"
+#include "gripes.h"
+#include "help.h"
+#include "input.h"
+#include "load-path.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "parse.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "variables.h"
+#include <version.h>
+
+std::string Voctave_home;
+
+std::string Vbin_dir;
+std::string Vinfo_dir;
+std::string Vdata_dir;
+std::string Vlibexec_dir;
+std::string Varch_lib_dir;
+std::string Vlocal_arch_lib_dir;
+std::string Vlocal_api_arch_lib_dir;
+std::string Vlocal_ver_arch_lib_dir;
+
+std::string Vlocal_ver_oct_file_dir;
+std::string Vlocal_api_oct_file_dir;
+std::string Vlocal_oct_file_dir;
+
+std::string Vlocal_ver_fcn_file_dir;
+std::string Vlocal_api_fcn_file_dir;
+std::string Vlocal_fcn_file_dir;
+
+std::string Voct_file_dir;
+std::string Vfcn_file_dir;
+
+std::string Vimage_dir;
+
+// The path that will be searched for programs that we execute.
+// (--exec-path path)
+static std::string VEXEC_PATH;
+
+// Name of the editor to be invoked by the edit_history command.
+std::string VEDITOR;
+
+static std::string VIMAGE_PATH;
+
+std::string Vlocal_site_defaults_file;
+std::string Vsite_defaults_file;
+
+std::string
+subst_octave_home (const std::string& s)
+{
+  std::string retval;
+
+  std::string prefix = OCTAVE_PREFIX;
+
+  retval = s;
+
+  if (Voctave_home != prefix)
+    {
+      octave_idx_type len = prefix.length ();
+
+      if (s.substr (0, len) == prefix)
+	retval.replace (0, len, Voctave_home);
+    }
+
+  if (file_ops::dir_sep_char () != '/')
+    std::replace (retval.begin (), retval.end (), '/',
+		  file_ops::dir_sep_char ());
+
+  return retval;
+}
+
+static void
+set_octave_home (void)
+{
+  std::string oh = octave_env::getenv ("OCTAVE_HOME");
+
+  Voctave_home = oh.empty () ? std::string (OCTAVE_PREFIX) : oh;
+}
+
+static void
+set_default_info_dir (void)
+{
+  Vinfo_dir = subst_octave_home (OCTAVE_INFODIR);
+}
+
+static void
+set_default_data_dir (void)
+{
+  Vdata_dir = subst_octave_home (OCTAVE_DATADIR);
+}
+
+static void
+set_default_libexec_dir (void)
+{
+  Vlibexec_dir = subst_octave_home (OCTAVE_LIBEXECDIR);
+}
+
+static void
+set_default_arch_lib_dir (void)
+{
+  Varch_lib_dir = subst_octave_home (OCTAVE_ARCHLIBDIR);
+}
+
+static void
+set_default_local_arch_lib_dir (void)
+{
+  Vlocal_arch_lib_dir = subst_octave_home (OCTAVE_LOCALARCHLIBDIR);
+}
+
+static void
+set_default_local_api_arch_lib_dir (void)
+{
+  Vlocal_api_arch_lib_dir = subst_octave_home (OCTAVE_LOCALAPIARCHLIBDIR);
+}
+
+static void
+set_default_local_ver_arch_lib_dir (void)
+{
+  Vlocal_ver_arch_lib_dir = subst_octave_home (OCTAVE_LOCALVERARCHLIBDIR);
+}
+
+static void
+set_default_local_ver_oct_file_dir (void)
+{
+  Vlocal_ver_oct_file_dir = subst_octave_home (OCTAVE_LOCALVEROCTFILEDIR);
+}
+
+static void
+set_default_local_api_oct_file_dir (void)
+{
+  Vlocal_api_oct_file_dir = subst_octave_home (OCTAVE_LOCALAPIOCTFILEDIR);
+}
+
+static void
+set_default_local_oct_file_dir (void)
+{
+  Vlocal_oct_file_dir = subst_octave_home (OCTAVE_LOCALOCTFILEDIR);
+}
+
+static void
+set_default_local_ver_fcn_file_dir (void)
+{
+  Vlocal_ver_fcn_file_dir = subst_octave_home (OCTAVE_LOCALVERFCNFILEDIR);
+}
+
+static void
+set_default_local_api_fcn_file_dir (void)
+{
+  Vlocal_api_fcn_file_dir = subst_octave_home (OCTAVE_LOCALAPIFCNFILEDIR);
+}
+
+static void
+set_default_local_fcn_file_dir (void)
+{
+  Vlocal_fcn_file_dir = subst_octave_home (OCTAVE_LOCALFCNFILEDIR);
+}
+
+static void
+set_default_fcn_file_dir (void)
+{
+  Vfcn_file_dir = subst_octave_home (OCTAVE_FCNFILEDIR);
+}
+
+static void
+set_default_image_dir (void)
+{
+  Vimage_dir = subst_octave_home (OCTAVE_IMAGEDIR);
+}
+
+static void
+set_default_oct_file_dir (void)
+{
+  Voct_file_dir = subst_octave_home (OCTAVE_OCTFILEDIR);
+}
+
+static void
+set_default_bin_dir (void)
+{
+  Vbin_dir = subst_octave_home (OCTAVE_BINDIR);
+}
+
+void
+set_exec_path (const std::string& path)
+{
+  VEXEC_PATH = Vlocal_ver_arch_lib_dir + dir_path::path_sep_str ()
+    + Vlocal_api_arch_lib_dir + dir_path::path_sep_str ()
+    + Vlocal_arch_lib_dir + dir_path::path_sep_str ()
+    + Varch_lib_dir + dir_path::path_sep_str ()
+    + Vbin_dir;
+  
+  // This is static so that even if set_exec_path is called more than
+  // once, shell_path is the original PATH from the environment,
+  // before we start modifying it.
+  static std::string shell_path = octave_env::getenv ("PATH");
+
+  if (! shell_path.empty ())
+    VEXEC_PATH += dir_path::path_sep_str () + shell_path;
+
+  std::string tpath = path;
+
+  if (tpath.empty ())
+    tpath = octave_env::getenv ("OCTAVE_EXEC_PATH");
+
+  if (! tpath.empty ())
+    VEXEC_PATH = tpath + dir_path::path_sep_str () + VEXEC_PATH;
+
+  octave_env::putenv ("PATH", VEXEC_PATH);
+}
+
+void
+set_image_path (const std::string& path)
+{
+  VIMAGE_PATH = ".";
+
+  std::string tpath = path;
+
+  if (tpath.empty ())
+    tpath = octave_env::getenv ("OCTAVE_IMAGE_PATH");
+
+  if (! tpath.empty ())
+    VIMAGE_PATH += dir_path::path_sep_str () + tpath;
+
+  tpath = genpath (Vimage_dir, "");
+
+  if (! tpath.empty ())
+    VIMAGE_PATH += dir_path::path_sep_str () + tpath;
+}
+
+static void
+set_default_doc_cache_file (void)
+{
+  std::string def_file = subst_octave_home (OCTAVE_DOC_CACHE_FILE);
+
+  std::string env_file = octave_env::getenv ("OCTAVE_DOC_CACHE_FILE");
+
+  Vdoc_cache_file = env_file.empty () ? def_file : env_file;
+}
+
+static void
+set_default_info_file (void)
+{
+  std::string std_info_file = subst_octave_home (OCTAVE_INFOFILE);
+
+  std::string oct_info_file = octave_env::getenv ("OCTAVE_INFO_FILE");
+
+  Vinfo_file = oct_info_file.empty () ? std_info_file : oct_info_file;
+}
+
+static void
+set_default_info_prog (void)
+{
+  std::string oct_info_prog = octave_env::getenv ("OCTAVE_INFO_PROGRAM");
+
+  if (oct_info_prog.empty ())
+    Vinfo_program = "info";
+  else
+    Vinfo_program = std::string (oct_info_prog);
+}
+
+static void
+set_default_editor (void)
+{
+  VEDITOR = "emacs";
+
+  std::string env_editor = octave_env::getenv ("EDITOR");
+
+  if (! env_editor.empty ())
+    VEDITOR = env_editor;
+}
+
+static void
+set_local_site_defaults_file (void)
+{
+  std::string lsf = octave_env::getenv ("OCTAVE_SITE_INITFILE");
+
+  if (lsf.empty ())
+    {
+      Vlocal_site_defaults_file = subst_octave_home (OCTAVE_LOCALSTARTUPFILEDIR);
+      Vlocal_site_defaults_file.append ("/octaverc");
+    }
+  else
+    Vlocal_site_defaults_file = lsf;
+}
+
+static void
+set_site_defaults_file (void)
+{
+  std::string sf = octave_env::getenv ("OCTAVE_VERSION_INITFILE");
+
+  if (sf.empty ())
+    {
+      Vsite_defaults_file = subst_octave_home (OCTAVE_STARTUPFILEDIR);
+      Vsite_defaults_file.append ("/octaverc");
+    }
+  else
+    Vsite_defaults_file = sf;
+}
+
+void
+install_defaults (void)
+{
+  // OCTAVE_HOME must be set first!
+
+  set_octave_home ();
+
+  set_default_info_dir ();
+
+  set_default_data_dir ();
+
+  set_default_libexec_dir ();
+
+  set_default_arch_lib_dir ();
+
+  set_default_local_ver_arch_lib_dir ();
+  set_default_local_api_arch_lib_dir ();
+  set_default_local_arch_lib_dir ();
+
+  set_default_local_ver_oct_file_dir ();
+  set_default_local_api_oct_file_dir ();
+  set_default_local_oct_file_dir ();
+
+  set_default_local_ver_fcn_file_dir ();
+  set_default_local_api_fcn_file_dir ();
+  set_default_local_fcn_file_dir ();
+
+  set_default_fcn_file_dir ();
+  set_default_oct_file_dir ();
+
+  set_default_image_dir ();
+
+  set_default_bin_dir ();
+
+  set_exec_path ();
+
+  set_image_path ();
+
+  set_default_doc_cache_file ();
+
+  set_default_info_file ();
+
+  set_default_info_prog ();
+
+  set_default_editor ();
+
+  set_local_site_defaults_file ();
+
+  set_site_defaults_file ();
+}
+
+DEFUN (EDITOR, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} EDITOR ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} EDITOR (@var{new_val})\n\
+Query or set the internal variable that specifies the editor to\n\
+use with the @code{edit_history} command.  The default value is taken from\n\
+the environment variable @w{@code{EDITOR}} when Octave starts.  If the\n\
+environment variable is not initialized, @w{@code{EDITOR}} will be set to\n\
+ at code{\"emacs\"}.\n\
+ at seealso{edit_history}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (EDITOR);
+}
+
+DEFUN (EXEC_PATH, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} EXEC_PATH ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} EXEC_PATH (@var{new_val})\n\
+Query or set the internal variable that specifies a colon separated\n\
+list of directories to search when executing external programs.\n\
+Its initial value is taken from the environment variable\n\
+ at w{@code{OCTAVE_EXEC_PATH}} (if it exists) or @code{PATH}, but that\n\
+value can be overridden by the command line argument\n\
+ at code{--exec-path PATH}.  At startup, an additional set of\n\
+directories (including the shell PATH) is appended to the path\n\
+specified in the environment or on the command line.  If you use\n\
+the @w{@code{EXEC_PATH}} function to modify the path, you should take\n\
+care to preserve these additional directories.\n\
+ at end deftypefn")
+{
+  std::string saved_exec_path = VEXEC_PATH;
+
+  octave_value retval = SET_NONEMPTY_INTERNAL_STRING_VARIABLE (EXEC_PATH);
+
+  if (VEXEC_PATH != saved_exec_path)
+    octave_env::putenv ("PATH", VEXEC_PATH);
+
+  return retval;
+}
+
+DEFUN (IMAGE_PATH, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} IMAGE_PATH ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} IMAGE_PATH (@var{new_val})\n\
+Query or set the internal variable that specifies a colon separated\n\
+list of directories in which to search for image files.\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (IMAGE_PATH);
+}
+
+DEFUN (OCTAVE_HOME, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} OCTAVE_HOME ()\n\
+Return the name of the top-level Octave installation directory.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = Voctave_home;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("OCTAVE_VERSION", FOCTAVE_VERSION, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} OCTAVE_VERSION ()\n\
+Return the version number of Octave, as a string.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = OCTAVE_VERSION;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/defaults.h.in b/src/defaults.h.in
new file mode 100644
index 0000000..7c218c3
--- /dev/null
+++ b/src/defaults.h.in
@@ -0,0 +1,222 @@
+// defaults.h.in
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_defaults_h)
+#define octave_defaults_h 1
+
+#include <string>
+
+#include "pathsearch.h"
+
+#ifndef OCTAVE_CANONICAL_HOST_TYPE
+#define OCTAVE_CANONICAL_HOST_TYPE %OCTAVE_CANONICAL_HOST_TYPE%
+#endif
+
+#ifndef OCTAVE_DEFAULT_PAGER
+#define OCTAVE_DEFAULT_PAGER %OCTAVE_DEFAULT_PAGER%
+#endif
+
+#ifndef OCTAVE_ARCHLIBDIR
+#define OCTAVE_ARCHLIBDIR %OCTAVE_ARCHLIBDIR%
+#endif
+
+#ifndef OCTAVE_BINDIR
+#define OCTAVE_BINDIR %OCTAVE_BINDIR%
+#endif
+
+#ifndef OCTAVE_DATADIR
+#define OCTAVE_DATADIR %OCTAVE_DATADIR%
+#endif
+
+#ifndef OCTAVE_DATAROOTDIR
+#define OCTAVE_DATAROOTDIR %OCTAVE_DATAROOTDIR%
+#endif
+
+#ifndef OCTAVE_DOC_CACHE_FILE
+#define OCTAVE_DOC_CACHE_FILE %OCTAVE_DOC_CACHE_FILE%
+#endif
+
+#ifndef OCTAVE_EXEC_PREFIX
+#define OCTAVE_EXEC_PREFIX %OCTAVE_EXEC_PREFIX%
+#endif
+
+#ifndef OCTAVE_FCNFILEDIR
+#define OCTAVE_FCNFILEDIR %OCTAVE_FCNFILEDIR%
+#endif
+
+#ifndef OCTAVE_IMAGEDIR
+#define OCTAVE_IMAGEDIR %OCTAVE_IMAGEDIR%
+#endif
+
+#ifndef OCTAVE_INCLUDEDIR
+#define OCTAVE_INCLUDEDIR %OCTAVE_INCLUDEDIR%
+#endif
+
+#ifndef OCTAVE_INFODIR
+#define OCTAVE_INFODIR %OCTAVE_INFODIR%
+#endif
+
+#ifndef OCTAVE_INFOFILE
+#define OCTAVE_INFOFILE %OCTAVE_INFOFILE%
+#endif
+
+#ifndef OCTAVE_LIBDIR
+#define OCTAVE_LIBDIR %OCTAVE_LIBDIR%
+#endif
+
+#ifndef OCTAVE_LIBEXECDIR
+#define OCTAVE_LIBEXECDIR %OCTAVE_LIBEXECDIR%
+#endif
+
+#ifndef OCTAVE_LIBEXECDIR
+#define OCTAVE_LIBEXECDIR %OCTAVE_LIBEXECDIR%
+#endif
+
+#ifndef OCTAVE_LOCALAPIFCNFILEDIR
+#define OCTAVE_LOCALAPIFCNFILEDIR %OCTAVE_LOCALAPIFCNFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALAPIOCTFILEDIR
+#define OCTAVE_LOCALAPIOCTFILEDIR %OCTAVE_LOCALAPIOCTFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALARCHLIBDIR
+#define OCTAVE_LOCALARCHLIBDIR %OCTAVE_LOCALARCHLIBDIR%
+#endif
+
+#ifndef OCTAVE_LOCALFCNFILEDIR
+#define OCTAVE_LOCALFCNFILEDIR %OCTAVE_LOCALFCNFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALOCTFILEDIR
+#define OCTAVE_LOCALOCTFILEDIR %OCTAVE_LOCALOCTFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALSTARTUPFILEDIR
+#define OCTAVE_LOCALSTARTUPFILEDIR %OCTAVE_LOCALSTARTUPFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALAPIARCHLIBDIR
+#define OCTAVE_LOCALAPIARCHLIBDIR %OCTAVE_LOCALAPIARCHLIBDIR%
+#endif
+
+#ifndef OCTAVE_LOCALVERARCHLIBDIR
+#define OCTAVE_LOCALVERARCHLIBDIR %OCTAVE_LOCALVERARCHLIBDIR%
+#endif
+
+#ifndef OCTAVE_LOCALVERFCNFILEDIR
+#define OCTAVE_LOCALVERFCNFILEDIR %OCTAVE_LOCALVERFCNFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALVEROCTFILEDIR
+#define OCTAVE_LOCALVEROCTFILEDIR %OCTAVE_LOCALVEROCTFILEDIR%
+#endif
+
+#ifndef OCTAVE_MAN1DIR
+#define OCTAVE_MAN1DIR %OCTAVE_MAN1DIR%
+#endif
+
+#ifndef OCTAVE_MAN1EXT
+#define OCTAVE_MAN1EXT %OCTAVE_MAN1EXT%
+#endif
+
+#ifndef OCTAVE_MANDIR
+#define OCTAVE_MANDIR %OCTAVE_MANDIR%
+#endif
+
+#ifndef OCTAVE_OCTFILEDIR
+#define OCTAVE_OCTFILEDIR %OCTAVE_OCTFILEDIR%
+#endif
+
+#ifndef OCTAVE_OCTETCDIR
+#define OCTAVE_OCTETCDIR %OCTAVE_OCTETCDIR%
+#endif
+
+#ifndef OCTAVE_OCTINCLUDEDIR
+#define OCTAVE_OCTINCLUDEDIR %OCTAVE_OCTINCLUDEDIR%
+#endif
+
+#ifndef OCTAVE_OCTLIBDIR
+#define OCTAVE_OCTLIBDIR %OCTAVE_OCTLIBDIR%
+#endif
+
+#ifndef OCTAVE_PREFIX
+#define OCTAVE_PREFIX %OCTAVE_PREFIX%
+#endif
+
+#ifndef OCTAVE_STARTUPFILEDIR
+#define OCTAVE_STARTUPFILEDIR %OCTAVE_STARTUPFILEDIR%
+#endif
+
+#ifndef OCTAVE_RELEASE
+#define OCTAVE_RELEASE %OCTAVE_RELEASE%
+#endif
+
+extern std::string Voctave_home;
+
+extern std::string Vbin_dir;
+extern std::string Vinfo_dir;
+extern std::string Vdata_dir;
+extern std::string Vlibexec_dir;
+extern std::string Varch_lib_dir;
+extern std::string Vlocal_arch_lib_dir;
+extern std::string Vlocal_ver_arch_lib_dir;
+
+extern std::string Vlocal_ver_oct_file_dir;
+extern std::string Vlocal_api_oct_file_dir;
+extern std::string Vlocal_oct_file_dir;
+
+extern std::string Vlocal_ver_fcn_file_dir;
+extern std::string Vlocal_api_fcn_file_dir;
+extern std::string Vlocal_fcn_file_dir;
+
+extern std::string Voct_file_dir;
+extern std::string Vfcn_file_dir;
+
+extern std::string Vimage_dir;
+
+// Name of the editor to be invoked by the edit_history command.
+extern std::string VEDITOR;
+
+extern std::string Vlocal_site_defaults_file;
+extern std::string Vsite_defaults_file;
+
+// Name of the FFTW wisdom program.
+extern OCTINTERP_API std::string Vfftw_wisdom_program;
+
+extern std::string subst_octave_home (const std::string&);
+
+extern void install_defaults (void);
+
+extern void set_exec_path (const std::string& path = std::string ());
+extern void set_image_path (const std::string& path = std::string ());
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/src/defun-dld.h b/src/defun-dld.h
new file mode 100644
index 0000000..a3898fa
--- /dev/null
+++ b/src/defun-dld.h
@@ -0,0 +1,78 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_defun_dld_h)
+#define octave_defun_dld_h 1
+
+#if defined (octave_defun_h)
+#error defun.h and defun-dld.h both included in same file!
+#endif
+
+#include "defun-int.h"
+
+// Define a builtin function that may be loaded dynamically at run
+// time.
+//
+// If Octave is not configured for dynamic linking of builtin
+// functions, this is the same as DEFUN, except that it will generate
+// an extra externally visible function.
+//
+// The first DECLARE_FUN is for the benefit of the installer function
+// and the second is for the definition of the function.
+
+#if defined (MAKE_BUILTINS)
+
+#define DEFUN_DLD(name, args_name, nargout_name, doc) \
+  DEFUN_DLD_INTERNAL (name, args_name, nargout_name, doc)
+
+// This one can be used when `name' cannot be used directly (if it is
+// already defined as a macro).  In that case, name is already a
+// quoted string, and the internal name of the function must be passed
+// too (the convention is to use a prefix of "F", so "foo" becomes
+// "Ffoo") as well as the name of the generated installer function
+// (the convention is to use a prefix of "G", so "foo" becomes "Gfoo").
+
+#define DEFUNX_DLD(name, fname, gname, args_name, nargout_name, doc) \
+  DEFUNX_DLD_INTERNAL (name, fname, args_name, nargout_name, doc)
+
+#else
+
+#define DEFUN_DLD(name, args_name, nargout_name, doc) \
+  DECLARE_FUN (name, args_name, nargout_name); \
+  DEFINE_FUN_INSTALLER_FUN (name, doc) \
+  DECLARE_FUN (name, args_name, nargout_name)
+
+#define DEFUNX_DLD(name, fname, gname, args_name, nargout_name, doc) \
+  DECLARE_FUNX (fname, args_name, nargout_name); \
+  DEFINE_FUNX_INSTALLER_FUN (name, fname, gname, doc) \
+  DECLARE_FUNX (fname, args_name, nargout_name)
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/defun-int.h b/src/defun-int.h
new file mode 100644
index 0000000..700ebe4
--- /dev/null
+++ b/src/defun-int.h
@@ -0,0 +1,171 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_defun_int_h)
+#define octave_defun_int_h 1
+
+#include <string>
+
+#include "ov-builtin.h"
+#include "ov-dld-fcn.h"
+#include "symtab.h"
+#include "version.h"
+
+class octave_value;
+
+extern OCTINTERP_API void print_usage (void);
+extern OCTINTERP_API void print_usage (const std::string&);
+
+extern OCTINTERP_API void check_version (const std::string& version, const std::string& fcn);
+
+extern OCTINTERP_API void
+install_builtin_function (octave_builtin::fcn f, const std::string& name,
+			  const std::string& doc,
+			  bool can_hide_function = true);
+
+extern OCTINTERP_API void
+install_dld_function (octave_dld_function::fcn f, const std::string& name,
+		      const octave_shlib& shl, const std::string& doc, 
+		      bool relative = false);
+
+extern OCTINTERP_API void
+install_mex_function (void *fptr, bool fmex, const std::string& name,
+		      const octave_shlib& shl, bool relative = false);
+
+extern OCTINTERP_API void
+alias_builtin (const std::string& alias, const std::string& name);
+
+#define DECLARE_FUNX(name, args_name, nargout_name) \
+  OCTAVE_EXPORT octave_value_list \
+  name (const octave_value_list& args_name, int nargout_name)
+
+#define DECLARE_FUN(name, args_name, nargout_name) \
+  DECLARE_FUNX (F ## name, args_name, nargout_name)
+
+// Define the code that will be used to insert the new function into
+// the symbol table.  We look for this name instead of the actual
+// function so that we can easily install the doc std::string too.
+
+typedef bool (*octave_dld_fcn_installer) (const octave_shlib&, bool relative);
+
+typedef octave_function * (*octave_dld_fcn_getter) (const octave_shlib&, bool relative);
+
+#define DEFINE_FUN_INSTALLER_FUN(name, doc) \
+  DEFINE_FUNX_INSTALLER_FUN(#name, F ## name, G ## name, doc)
+
+#define DEFINE_FUNX_INSTALLER_FUN(name, fname, gname, doc) \
+  extern "C" \
+  OCTAVE_EXPORT \
+  octave_function * \
+  gname (const octave_shlib& shl, bool relative) \
+  { \
+    octave_function *retval = 0; \
+ \
+    check_version (OCTAVE_API_VERSION, name); \
+ \
+    if (! error_state) \
+      { \
+	octave_dld_function *fcn = octave_dld_function::create (fname, shl, name, doc); \
+ \
+        if (relative) \
+          fcn->mark_relative (); \
+ \
+        retval = fcn; \
+      } \
+ \
+    return retval; \
+  }
+
+// MAKE_BUILTINS is defined to extract function names and related
+// information and create the *.df files that are eventually used to
+// create the builtins.cc file.
+
+#if defined (MAKE_BUILTINS)
+
+// Generate code to install name in the symbol table.  The script
+// mkdefs will create a .def file for every .cc file that uses DEFUN,
+// or DEFCMD.
+
+#define DEFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFUN_INTERNAL (name, args_name, nargout_name, doc) \
+  END_INSTALL_BUILTIN
+
+#define DEFCONSTFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFCONSTFUN_INTERNAL (name, args_name, nargout_name, doc) \
+  END_INSTALL_BUILTIN
+
+#define DEFUNX_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFUNX_INTERNAL (name, fname, args_name, nargout_name, doc) \
+  END_INSTALL_BUILTIN
+
+// Generate code to install name in the symbol table.  The script
+// mkdefs will create a .def file for every .cc file that uses
+// DEFUN_DLD.
+
+#define DEFUN_DLD_INTERNAL(name, args_name, nargout_name, doc) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFUN_DLD_INTERNAL (name, args_name, nargout_name, doc) \
+  END_INSTALL_BUILTIN
+
+#define DEFUNX_DLD_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFUNX_DLD_INTERNAL (name, fname, args_name, nargout_name, doc) \
+  END_INSTALL_BUILTIN
+
+// Generate code for making another name for an existing function.
+
+#define DEFALIAS_INTERNAL(alias, name) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFALIAS_INTERNAL(alias, name) \
+  END_INSTALL_BUILTIN
+
+#else /* ! MAKE_BUILTINS */
+
+// Generate the first line of the function definition.  This ensures
+// that the internal functions all have the same signature.
+
+#define DEFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  DECLARE_FUN (name, args_name, nargout_name)
+
+#define DEFCONSTFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  DECLARE_FUN (name, args_name, nargout_name)
+
+#define DEFUNX_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  DECLARE_FUNX (fname, args_name, nargout_name)
+
+// No definition is required for an alias.
+
+#define DEFALIAS_INTERNAL(alias, name)
+
+#endif /* ! MAKE_BUILTINS */
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/defun.cc b/src/defun.cc
new file mode 100644
index 0000000..297c389
--- /dev/null
+++ b/src/defun.cc
@@ -0,0 +1,130 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sstream>
+#include <iostream>
+#include <string>
+
+#include "defun.h"
+#include "dynamic-ld.h"
+#include "error.h"
+#include "help.h"
+#include "ov.h"
+#include "ov-builtin.h"
+#include "ov-dld-fcn.h"
+#include "ov-fcn.h"
+#include "ov-mex-fcn.h"
+#include "ov-usr-fcn.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "symtab.h"
+#include "toplev.h"
+#include "variables.h"
+#include "parse.h"
+
+// Print the usage part of the doc string of FCN (user-defined or DEFUN).
+void
+print_usage (void)
+{
+  const octave_function *cur = octave_call_stack::current ();
+  if (cur)
+    print_usage (cur->name ());
+  else
+    error ("print_usage: invalid function");
+}
+
+void
+print_usage (const std::string& name)
+{
+  feval ("print_usage", octave_value (name), 0);
+}
+
+void
+check_version (const std::string& version, const std::string& fcn)
+{
+  if (version != OCTAVE_API_VERSION)
+    {
+      error ("API version %s found in .oct file function `%s'\n"
+	     "       does not match the running Octave (API version %s)\n"
+	     "       this can lead to incorrect results or other failures\n"
+	     "       you can fix this problem by recompiling this .oct file",
+	     version.c_str (), fcn.c_str (), OCTAVE_API_VERSION);
+    }
+}
+
+// Install variables and functions in the symbol tables.
+
+void
+install_builtin_function (octave_builtin::fcn f, const std::string& name,
+			  const std::string& doc,
+			  bool /* can_hide_function -- not yet implemented */)
+{
+  octave_value fcn (new octave_builtin (f, name, doc));
+
+  symbol_table::install_built_in_function (name, fcn);
+}
+
+void
+install_dld_function (octave_dld_function::fcn f, const std::string& name,
+		      const octave_shlib& shl, const std::string& doc,
+		      bool relative)
+{
+  octave_dld_function *fcn = new octave_dld_function (f, shl, name, doc);
+
+  if (relative)
+    fcn->mark_relative ();
+
+  octave_value fval (fcn);
+
+  symbol_table::install_built_in_function (name, fval);
+}
+
+void
+install_mex_function (void *fptr, bool fmex, const std::string& name,
+		      const octave_shlib& shl, bool relative)
+{
+  octave_mex_function *fcn = new octave_mex_function (fptr, fmex, shl, name);
+
+  if (relative)
+    fcn->mark_relative ();
+
+  octave_value fval (fcn);
+
+  symbol_table::install_built_in_function (name, fval);
+}
+
+void
+alias_builtin (const std::string& alias, const std::string& name)
+{
+  symbol_table::alias_built_in_function (alias, name);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/defun.h b/src/defun.h
new file mode 100644
index 0000000..e122434
--- /dev/null
+++ b/src/defun.h
@@ -0,0 +1,73 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_defun_h)
+#define octave_defun_h 1
+
+#if defined (octave_defun_dld_h)
+#error defun.h and defun-dld.h both included in same file!
+#endif
+
+#include "defun-int.h"
+
+// Define a builtin function.
+//
+//   name is the name of the function, unqouted.
+//
+//   args_name is the name of the octave_value_list variable used to pass
+//     the argument list to this function.
+//
+//   nargout_name is the name of the int variable used to pass the
+//     number of output arguments this function is expected to produce.
+//
+//   doc is the simple help text for the function.
+
+#define DEFUN(name, args_name, nargout_name, doc) \
+  DEFUN_INTERNAL (name, args_name, nargout_name, doc)
+
+// This one can be used when `name' cannot be used directly (if it is
+// already defined as a macro).  In that case, name is already a
+// quoted string, and the internal name of the function must be passed
+// too (the convention is to use a prefix of "F", so "foo" becomes "Ffoo").
+
+#define DEFUNX(name, fname, args_name, nargout_name, doc) \
+  DEFUNX_INTERNAL (name, fname, args_name, nargout_name, doc)
+
+// This is a function with a name that can't be hidden by a variable.
+#define DEFCONSTFUN(name, args_name, nargout_name, doc) \
+  DEFCONSTFUN_INTERNAL (name, args_name, nargout_name, doc)
+
+// Make alias another name for the existing function name.  This macro
+// must be used in the same file where name is defined, after the
+// definition for name.
+
+#define DEFALIAS(alias, name) \
+  DEFALIAS_INTERNAL (alias, name)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/dirfns.cc b/src/dirfns.cc
new file mode 100644
index 0000000..a4b3853
--- /dev/null
+++ b/src/dirfns.cc
@@ -0,0 +1,735 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstdio>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+
+#include <sstream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "file-ops.h"
+#include "file-stat.h"
+#include "glob-match.h"
+#include "oct-env.h"
+#include "pathsearch.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "dir-ops.h"
+#include "dirfns.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "load-path.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "procstream.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// TRUE means we ask for confirmation before recursively removing a
+// directory tree.
+static bool Vconfirm_recursive_rmdir = true;
+
+// The time we last time we changed directories.
+octave_time Vlast_chdir_time = 0.0;
+
+static int
+octave_change_to_directory (const std::string& newdir)
+{
+  int cd_ok = octave_env::chdir (file_ops::tilde_expand (newdir));
+
+  if (cd_ok)
+    {
+      Vlast_chdir_time.stamp ();
+
+      // FIXME -- should this be handled as a list of functions
+      // to call so users can add their own chdir handlers?
+
+      load_path::update ();
+    }
+  else
+    {
+      using namespace std;
+
+      error ("%s: %s", newdir.c_str (), strerror (errno));
+    }
+
+  return cd_ok;
+}
+
+DEFUN (cd, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} cd dir\n\
+ at deffnx {Command} chdir dir\n\
+Change the current working directory to @var{dir}.  If @var{dir} is\n\
+omitted, the current directory is changed to the user's home\n\
+directory.  For example,\n\
+\n\
+ at example\n\
+cd ~/octave\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Changes the current working directory to @file{~/octave}.  If the\n\
+directory does not exist, an error message is printed and the working\n\
+directory is not changed.\n\
+ at seealso{mkdir, rmdir, dir}\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("cd");
+
+  if (error_state)
+    return retval;
+
+  if (argc > 1)
+    {
+      std::string dirname = argv[1];
+
+      if (dirname.length () > 0
+	  && ! octave_change_to_directory (dirname))
+	{
+	  return retval;
+	}
+    }
+  else
+    {
+      std::string home_dir = octave_env::get_home_directory ();
+
+      if (home_dir.empty () || ! octave_change_to_directory (home_dir))
+	return retval;
+    }
+
+  return retval;
+}
+
+DEFALIAS (chdir, cd);
+
+DEFUN (pwd, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} pwd ()\n\
+Return the current working directory.\n\
+ at seealso{dir, ls}\n\
+ at end deftypefn")
+{
+  return octave_value (octave_env::getcwd ());
+}
+
+DEFUN (readdir, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})\n\
+Return names of the files in the directory @var{dir} as a cell array of\n\
+strings.  If an error occurs, return an empty cell array in @var{files}.\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at seealso{dir, glob}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = -1.0;
+  retval(0) = Cell ();
+
+  if (args.length () == 1)
+    {
+      std::string dirname = args(0).string_value ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("readdir", args(0));
+      else
+	{
+	  dir_entry dir (dirname);
+
+	  if (dir)
+	    {
+	      string_vector dirlist = dir.read ();
+	      retval(0) = Cell (dirlist.sort ());
+	      retval(1) = 0.0;
+	    }
+	  else
+	    {
+	      retval(2) = dir.error ();
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// FIXME -- should maybe also allow second arg to specify
+// mode?  OTOH, that might cause trouble with compatibility later...
+
+DEFUN (mkdir, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{dir})\n\
+ at deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{parent}, @var{dir})\n\
+Create a directory named @var{dir} in the directory @var{parent}.\n\
+\n\
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique\n\
+message identifier.\n\
+ at seealso{rmdir}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = std::string ();
+  retval(0) = false;
+
+  int nargin = args.length ();
+
+  std::string dirname;
+
+  if (nargin == 2)
+    {
+      std::string parent = args(0).string_value ();
+      std::string dir = args(1).string_value ();
+
+      if (error_state)
+	{
+	  gripe_wrong_type_arg ("mkdir", args(0));
+	  return retval;
+	}
+      else
+	dirname = file_ops::concat (parent, dir);
+    }
+  else if (nargin == 1)
+    {
+      dirname = args(0).string_value ();
+
+      if (error_state)
+	{
+	  gripe_wrong_type_arg ("mkdir", args(0));
+	  return retval;
+	}
+    }
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string msg;
+
+      dirname = file_ops::tilde_expand (dirname);
+
+      file_stat fs (dirname);
+
+      if (fs && fs.is_dir ())
+	{
+	  // For compatibility with Matlab, we return true when the
+	  // directory already exists.
+
+	  retval(2) = "mkdir";
+	  retval(1) = "directory exists";
+	  retval(0) = true;
+	}
+      else
+	{
+	  int status = file_ops::mkdir (dirname, 0777, msg);
+
+	  if (status < 0)
+	    {
+	      retval(2) = "mkdir";
+	      retval(1) = msg;
+	    }
+	  else
+	    retval(0) = true;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (rmdir, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir})\n\
+ at deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir}, @code{\"s\"})\n\
+Remove the directory named @var{dir}.\n\
+\n\
+If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
+character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique\n\
+message identifier.\n\
+\n\
+If the optional second parameter is supplied with value @code{\"s\"},\n\
+recursively remove all subdirectories as well.\n\
+ at seealso{mkdir, confirm_recursive_rmdir}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = std::string ();
+  retval(0) = false;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string dirname = args(0).string_value ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("rmdir", args(0));
+      else
+	{
+	  std::string fulldir = file_ops::tilde_expand (dirname);
+	  int status = -1;
+	  std::string msg;
+
+	  if (nargin == 2)
+	    {
+	      if (args(1).string_value () == "s")
+		{
+		  bool doit = true;
+
+		  if (interactive && Vconfirm_recursive_rmdir)
+		    {
+		      std::string prompt
+			= "remove entire contents of " + fulldir + "? ";
+
+		      doit = octave_yes_or_no (prompt);
+		    }
+
+		  if (doit)
+		    status = file_ops::recursive_rmdir (fulldir, msg);
+		}
+	      else
+		error ("rmdir: expecting second argument to be \"s\"");
+	    }
+	  else
+	    status = file_ops::rmdir (fulldir, msg);
+
+	  if (status < 0)
+	    {
+	      retval(2) = "rmdir";
+	      retval(1) = msg;
+	    }
+	  else
+	    retval(0) = true;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (link, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})\n\
+Create a new link (also known as a hard link) to an existing file.\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at seealso{symlink}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  if (args.length () == 2)
+    {
+      std::string from = args(0).string_value ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("link", args(0));
+      else
+	{
+	  std::string to = args(1).string_value ();
+
+	  if (error_state)
+	    gripe_wrong_type_arg ("link", args(1));
+	  else
+	    {
+	      std::string msg;
+
+	      int status = file_ops::link (from, to, msg);
+
+	      retval(0) = status;
+
+	      if (status < 0)
+		retval(1) = msg;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (symlink, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})\n\
+Create a symbolic link @var{new} which contains the string @var{old}.\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at seealso{link, readlink}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  if (args.length () == 2)
+    {
+      std::string from = args(0).string_value ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("symlink", args(0));
+      else
+	{
+	  std::string to = args(1).string_value ();
+
+	  if (error_state)
+	    gripe_wrong_type_arg ("symlink", args(1));
+	  else
+	    {
+	      std::string msg;
+
+	      int status = file_ops::symlink (from, to, msg);
+
+	      retval(0) = status;
+
+	      if (status < 0)
+		retval(1) = msg;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (readlink, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})\n\
+Read the value of the symbolic link @var{symlink}.\n\
+\n\
+If successful, @var{result} contains the contents of the symbolic link\n\
+ at var{symlink}, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at seealso{link, symlink}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = -1.0;
+  retval(0) = std::string ();
+
+  if (args.length () == 1)
+    {
+      std::string symlink = args(0).string_value ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("readlink", args(0));
+      else
+	{
+	  std::string result;
+	  std::string msg;
+
+	  int status = file_ops::readlink (symlink, result, msg);
+
+	  retval(0) = result;
+
+	  retval(1) = status;
+
+	  if (status < 0)
+	    retval(2) = msg;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (rename, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})\n\
+Change the name of file @var{old} to @var{new}.\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at seealso{ls, dir}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1.0;
+
+  if (args.length () == 2)
+    {
+      std::string from = args(0).string_value ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("rename", args(0));
+      else
+	{
+	  std::string to = args(1).string_value ();
+
+	  if (error_state)
+	    gripe_wrong_type_arg ("rename", args(1));
+	  else
+	    {
+	      std::string msg;
+
+	      int status = file_ops::rename (from, to, msg);
+
+	      retval(0) = status;
+
+	      if (status < 0)
+		retval(1) = msg;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (glob, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} glob (@var{pattern})\n\
+Given an array of strings (as a char array or a cell array) in\n\
+ at var{pattern}, return a cell array of file names that match any of\n\
+them, or an empty cell array if no patterns match.  Tilde expansion\n\
+is performed on each of the patterns before looking for matching file\n\
+names.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+glob (\"/vm*\")\n\
+     @result{} \"/vmlinuz\"\n\
+ at end group\n\
+ at end example\n\
+ at seealso{dir, ls, stat, readdir}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      string_vector pat = args(0).all_strings ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("glob", args(0));
+      else
+	{
+	  glob_match pattern (file_ops::tilde_expand (pat));
+
+	  retval = Cell (pattern.glob ());
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fnmatch, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})\n\
+Return 1 or zero for each element of @var{string} that matches any of\n\
+the elements of the string array @var{pattern}, using the rules of\n\
+filename pattern matching.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+fnmatch (\"a*b\", @{\"ab\"; \"axyzb\"; \"xyzab\"@})\n\
+     @result{} [ 1; 1; 0 ]\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      string_vector pat = args(0).all_strings ();
+      string_vector str = args(1).all_strings ();
+
+      if (error_state)
+	gripe_wrong_type_arg ("fnmatch", args(0));
+      else
+	{
+	  glob_match pattern (file_ops::tilde_expand (pat));
+
+	  Array<bool> tmp = pattern.match (str);
+
+	  octave_idx_type n = tmp.length ();
+
+	  ColumnVector result (n);
+
+	  for (octave_idx_type i = 0; i < n; i++)
+	    result(i) = tmp(i);
+
+	  retval = result;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (filesep, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} filesep ()\n\
+ at deftypefnx {Built-in Function} {} filesep ('all')\n\
+Return the system-dependent character used to separate directory names.\n\
+\n\
+If 'all' is given, the function return all valid file separators in\n\
+the form of a string.  The list of file separators is system-dependent.\n\
+It is / (forward slash) under UNIX or Mac OS X, / and \\ (forward and\n\
+backward slashes) under Windows.\n\
+ at seealso{pathsep, dir, ls}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = file_ops::dir_sep_str ();
+  else if (args.length () == 1)
+    {
+      std::string s = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  if (s == "all")
+	    retval = file_ops::dir_sep_chars ();
+	  else
+	    gripe_wrong_type_arg ("filesep", args(0));
+	}
+      else
+	gripe_wrong_type_arg ("filesep", args(0));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (pathsep, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} pathsep ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} pathsep (@var{new_val})\n\
+Query or set the character used to separate directories in\n\
+a path.\n\
+ at seealso{filesep, dir, ls}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 0 || nargin == 0)
+    retval = dir_path::path_sep_str ();
+
+  if (nargin == 1)
+    {
+      std::string sval = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  switch (sval.length ())
+	    {
+	    case 1:
+	      dir_path::path_sep_char (sval[0]);
+	      break;
+
+	    case 0:
+	      dir_path::path_sep_char ('\0');
+	      break;
+
+	    default:
+	      error ("pathsep: argument must be a single character");
+	      break;
+	    }
+	}
+      else
+	error ("pathsep: argument must be a single character");
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (confirm_recursive_rmdir, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} confirm_recursive_rmdir ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} confirm_recursive_rmdir (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave\n\
+will ask for confirmation before recursively removing a directory tree.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (confirm_recursive_rmdir);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/dirfns.h b/src/dirfns.h
new file mode 100644
index 0000000..6bed5a7
--- /dev/null
+++ b/src/dirfns.h
@@ -0,0 +1,46 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dirfns_h)
+#define octave_dirfns_h 1
+
+#include <ctime>
+
+#include <string>
+
+#include "oct-time.h"
+
+extern std::string polite_directory_format (const std::string&);
+extern std::string base_pathname (const std::string&);
+extern std::string make_absolute (const std::string&, const std::string&);
+extern std::string get_working_directory (const std::string&);
+
+// The time we last time we changed directories.
+extern octave_time Vlast_chdir_time;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/display.cc b/src/display.cc
new file mode 100644
index 0000000..b7e31ed
--- /dev/null
+++ b/src/display.cc
@@ -0,0 +1,157 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#if defined (OCTAVE_USE_WINDOWS_API)
+#include <Windows.h>
+#elif defined (HAVE_FRAMEWORK_CARBON)
+#include <Carbon/Carbon.h>
+#elif defined (HAVE_X_WINDOWS)
+#include <X11/Xlib.h>
+#endif
+
+#include "display.h"
+#include "error.h"
+
+display_info *display_info::instance = 0;
+
+void
+display_info::init (bool query)
+{
+  if (query)
+    {
+#if defined (OCTAVE_USE_WINDOWS_API)
+
+      HDC hdc = GetDC (0);
+
+      if (hdc)
+	{
+	  dp = GetDeviceCaps (hdc, BITSPIXEL);
+
+	  ht = GetDeviceCaps (hdc, VERTRES);
+	  wd = GetDeviceCaps (hdc, HORZRES);
+
+	  double ht_mm = GetDeviceCaps (hdc, VERTSIZE);
+	  double wd_mm = GetDeviceCaps (hdc, HORZSIZE);
+
+	  rx = wd * 25.4 / wd_mm;
+	  ry = ht * 25.4 / ht_mm;
+	}
+      else
+	warning ("no graphical display found");
+
+#elif defined (HAVE_FRAMEWORK_CARBON)
+
+      CGDirectDisplayID display = CGMainDisplayID ();
+
+      if (display)
+	{
+	  dp = CGDisplayBitsPerPixel (display);
+
+	  ht = CGDisplayPixelsHigh (display);
+	  wd = CGDisplayPixelsWide (display);
+
+	  CGSize sz_mm = CGDisplayScreenSize (display);
+
+	  // On modern Mac systems (>= 10.5) CGSize is a struct keeping 2
+	  // CGFloat values, but the CGFloat typedef is not present on
+	  // older systems, so use double instead.
+	  double ht_mm = sz_mm.height;
+	  double wd_mm = sz_mm.width;
+
+	  rx = wd * 25.4 / wd_mm;
+	  ry = ht * 25.4 / ht_mm;
+	}
+      else
+	warning ("no graphical display found");
+
+#elif defined (HAVE_X_WINDOWS)
+
+      const char *display_name = getenv ("DISPLAY");
+
+      if (display_name && *display_name)
+	{
+	  Display *display = XOpenDisplay (display_name);
+
+	  if (display)
+	    {
+	      Screen *screen = DefaultScreenOfDisplay (display);
+
+	      if (screen)
+		{
+		  dp = DefaultDepthOfScreen (screen);
+
+		  ht = HeightOfScreen (screen);
+		  wd = WidthOfScreen (screen);
+
+		  int screen_number = XScreenNumberOfScreen (screen);
+
+		  double ht_mm = DisplayHeightMM (display, screen_number);
+		  double wd_mm = DisplayWidthMM (display, screen_number);
+
+		  rx = wd * 25.4 / wd_mm;
+		  ry = ht * 25.4 / ht_mm;
+		}
+	      else
+		warning ("X11 display has no default screen");
+	    }
+	  else
+	    warning ("unable to open X11 DISPLAY");
+	}
+      else
+	warning ("X11 DISPLAY environment variable not set");
+#else
+
+      warning ("no graphical display found");
+
+#endif
+    }
+}
+
+bool
+display_info::instance_ok (bool query)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new display_info (query);
+
+  if (! instance)
+    {
+      ::error ("unable to create display_info object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/display.h b/src/display.h
new file mode 100644
index 0000000..8910183
--- /dev/null
+++ b/src/display.h
@@ -0,0 +1,103 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_display_h)
+#define octave_display_h 1
+
+class Matrix;
+
+class display_info
+{
+protected:
+
+  display_info (bool query = true)
+    : ht (1), wd (1), dp (0), rx (72), ry (72)
+  {
+    init (query);
+  }
+
+public:
+
+  static int height (void)
+  {
+    return instance_ok () ? instance->do_height () : 0;
+  }
+
+  static int width (void)
+  {
+    return instance_ok () ? instance->do_width () : 0;
+  }
+
+  static int depth (void)
+  {
+    return instance_ok () ? instance->do_depth () : 0;
+  }
+
+  static double x_dpi (void)
+  {
+    return instance_ok () ? instance->do_x_dpi () : 0;
+  }
+
+  static double y_dpi (void)
+  {
+    return instance_ok () ? instance->do_y_dpi () : 0;
+  }
+
+  // To disable querying the window system for defaults, this function
+  // must be called before any other display_info function.
+  static void no_window_system (void)
+  {
+    instance_ok (false);
+  }
+
+private:
+
+  static display_info *instance;
+
+  // Height, width, and depth of the display.
+  int ht;
+  int wd;
+  int dp;
+
+  // X- and Y- Resolution of the display in dots (pixels) per inch.
+  double rx;
+  double ry;
+
+  int do_height (void) const { return ht; }
+  int do_width (void) const { return wd; }
+  int do_depth (void) const { return dp; }
+
+  double do_x_dpi (void) const { return rx; }
+  double do_y_dpi (void) const { return ry; }
+
+  void init (bool query = true);
+
+  static bool instance_ok (bool query = true);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/dynamic-ld.cc b/src/dynamic-ld.cc
new file mode 100644
index 0000000..8795386
--- /dev/null
+++ b/src/dynamic-ld.cc
@@ -0,0 +1,575 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <list>
+
+#include "oct-env.h"
+#include "oct-time.h"
+#include "file-stat.h"
+
+#include <defaults.h>
+
+#include "defun.h"
+#include "dynamic-ld.h"
+#include "ov-fcn.h"
+#include "ov-dld-fcn.h"
+#include "ov-mex-fcn.h"
+#include "parse.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#define STRINGIFY(s) STRINGIFY1(s)
+#define STRINGIFY1(s) #s
+
+class
+octave_shlib_list
+{
+public:
+
+  typedef std::list<octave_shlib>::iterator iterator;
+  typedef std::list<octave_shlib>::const_iterator const_iterator;
+
+  static void append (const octave_shlib& shl);
+
+  static void remove (octave_shlib& shl, octave_shlib::close_hook cl_hook = 0);
+
+  static octave_shlib find_file (const std::string& file_name);
+
+  static void display (void);
+
+private:
+
+  octave_shlib_list (void) { }
+
+  ~octave_shlib_list (void) { }
+
+  void do_append (const octave_shlib& shl);
+
+  void do_remove (octave_shlib& shl, octave_shlib::close_hook cl_hook = 0);
+
+  octave_shlib do_find_file (const std::string& file_name) const;
+
+  void do_display (void) const;
+
+  static octave_shlib_list *instance;
+
+  static bool instance_ok (void);
+
+  // List of libraries we have loaded.
+  std::list<octave_shlib> lib_list;
+
+  // No copying!
+
+  octave_shlib_list (const octave_shlib_list&);
+
+  octave_shlib_list& operator = (const octave_shlib_list&);
+};
+
+octave_shlib_list *octave_shlib_list::instance = 0;
+
+void
+octave_shlib_list::do_append (const octave_shlib& shl)
+{
+  lib_list.push_back (shl);
+}
+
+void
+octave_shlib_list::do_remove (octave_shlib& shl,
+			      octave_shlib::close_hook cl_hook)
+{
+  for (iterator p = lib_list.begin (); p != lib_list.end (); p++)
+    {
+      if (*p == shl)
+	{
+	  shl.close (cl_hook);
+
+	  lib_list.erase (p);
+
+	  break;
+	}
+    }
+}
+
+octave_shlib
+octave_shlib_list::do_find_file (const std::string& file_name) const
+{
+  octave_shlib retval;
+
+  for (const_iterator p = lib_list.begin (); p != lib_list.end (); p++)
+    {
+      if (p->file_name () == file_name)
+	{
+	  retval = *p;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+void
+octave_shlib_list::do_display (void) const
+{
+  std::cerr << "current shared libraries:" << std::endl;
+  for (const_iterator p = lib_list.begin (); p != lib_list.end (); p++)
+    std::cerr << "  " << p->file_name () << std::endl;
+}
+
+bool
+octave_shlib_list::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_shlib_list ();
+
+  if (! instance)
+    {
+      ::error ("unable to create shared library list object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+octave_shlib_list::append (const octave_shlib& shl)
+{
+  if (instance_ok ())
+    instance->do_append (shl);
+}
+
+void
+octave_shlib_list::remove (octave_shlib& shl,
+			   octave_shlib::close_hook cl_hook)
+{
+  if (instance_ok ())
+    instance->do_remove (shl, cl_hook);
+}
+
+octave_shlib
+octave_shlib_list::find_file (const std::string& file_name)
+{
+  return (instance_ok ())
+    ? instance->do_find_file (file_name) : octave_shlib ();
+}
+
+void
+octave_shlib_list::display (void)
+{
+  if (instance_ok ())
+    instance->do_display ();
+}
+
+class
+octave_mex_file_list
+{
+public:
+
+  typedef std::list<octave_shlib>::iterator iterator;
+  typedef std::list<octave_shlib>::const_iterator const_iterator;
+
+  static void append (const octave_shlib& shl);
+
+  static void remove (octave_shlib& shl, octave_shlib::close_hook cl_hook = 0);
+
+private:
+
+  octave_mex_file_list (void) { }
+
+  ~octave_mex_file_list (void) { }
+
+  void do_append (const octave_shlib& shl);
+
+  void do_remove (octave_shlib& shl, octave_shlib::close_hook cl_hook = 0);
+
+  static octave_mex_file_list *instance;
+
+  static bool instance_ok (void);
+
+  // List of libraries we have loaded.
+  std::list<octave_shlib> file_list;
+
+  // No copying!
+
+  octave_mex_file_list (const octave_mex_file_list&);
+
+  octave_mex_file_list& operator = (const octave_mex_file_list&);
+};
+
+octave_mex_file_list *octave_mex_file_list::instance = 0;
+
+void
+octave_mex_file_list::do_append (const octave_shlib& shl)
+{
+  file_list.push_back (shl);
+}
+
+void
+octave_mex_file_list::do_remove (octave_shlib& shl,
+				 octave_shlib::close_hook cl_hook)
+{
+  for (iterator p = file_list.begin (); p != file_list.end (); p++)
+    {
+      if (*p == shl)
+	{
+	  shl.close (cl_hook);
+
+	  file_list.erase (p);
+
+	  break;
+	}
+    }
+}
+
+bool
+octave_mex_file_list::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_mex_file_list ();
+
+  if (! instance)
+    {
+      ::error ("unable to create shared library list object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+octave_mex_file_list::append (const octave_shlib& shl)
+{
+  if (instance_ok ())
+    instance->do_append (shl);
+}
+
+void
+octave_mex_file_list::remove (octave_shlib& shl,
+			      octave_shlib::close_hook cl_hook)
+{
+  if (instance_ok ())
+    instance->do_remove (shl, cl_hook);
+}
+
+octave_dynamic_loader *octave_dynamic_loader::instance = 0;
+
+bool octave_dynamic_loader::doing_load = false;
+
+bool
+octave_dynamic_loader::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_dynamic_loader ();
+
+  if (! instance)
+    {
+      ::error ("unable to create dynamic loader object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+static
+void do_clear_function (const std::string& fcn_name)
+{
+  warning_with_id ("Octave:reload-forces-clear", "  %s", fcn_name.c_str ());
+
+  symbol_table::clear_user_function (fcn_name);
+}
+
+static void
+clear (octave_shlib& oct_file)
+{
+  if (oct_file.number_of_functions_loaded () > 1)
+    warning_with_id ("Octave:reload-forces-clear",
+		     "reloading %s clears the following functions:",
+		     oct_file.file_name().c_str ());
+
+  octave_shlib_list::remove (oct_file, do_clear_function);
+}
+
+octave_function *
+octave_dynamic_loader::do_load_oct (const std::string& fcn_name,
+				    const std::string& file_name,
+				    bool relative)
+{
+  octave_function *retval = 0;
+
+  unwind_protect::begin_frame ("octave_dynamic_loader::do_load");
+
+  unwind_protect_bool (octave_dynamic_loader::doing_load);
+
+  doing_load = true;
+
+  octave_shlib oct_file = octave_shlib_list::find_file (file_name);
+
+  if (oct_file && oct_file.is_out_of_date ())
+    clear (oct_file);
+
+  if (! oct_file)
+    {
+      oct_file.open (file_name);
+
+      if (! error_state && oct_file)
+	{
+	  octave_shlib_list::append (oct_file);
+
+	  if (relative)
+	    oct_file.mark_relative ();
+	}
+    }
+
+  if (! error_state)
+    {
+      if (oct_file)
+	{
+	  void *function = oct_file.search (fcn_name, name_mangler);
+
+	  if (! function)
+	    {
+	      // FIXME -- can we determine this C mangling scheme
+	      // automatically at run time or configure time?
+
+	      function = oct_file.search (fcn_name, name_uscore_mangler);
+	    }
+
+	  if (function)
+	    {
+	      octave_dld_fcn_getter f
+		= FCN_PTR_CAST (octave_dld_fcn_getter, function);
+
+	      retval = f (oct_file, relative);
+
+	      if (! retval)
+		::error ("failed to install .oct file function `%s'",
+			 fcn_name.c_str ());
+	    }
+	}
+      else
+	::error ("%s is not a valid shared library",
+		 file_name.c_str ());
+    }
+  
+  unwind_protect::run_frame ("octave_dynamic_loader::do_load");
+
+  return retval;
+}
+
+octave_function *
+octave_dynamic_loader::do_load_mex (const std::string& fcn_name,
+				    const std::string& file_name,
+				    bool relative)
+{
+  octave_function *retval = 0;
+
+  unwind_protect::begin_frame ("octave_dynamic_loader::do_load");
+
+  unwind_protect_bool (octave_dynamic_loader::doing_load);
+
+  doing_load = true;
+
+  octave_shlib mex_file = octave_shlib_list::find_file (file_name);
+
+  if (mex_file && mex_file.is_out_of_date ())
+    clear (mex_file);
+
+  if (! mex_file)
+    {
+      mex_file.open (file_name);
+
+      if (! error_state && mex_file)
+	{
+	  octave_shlib_list::append (mex_file);
+
+	  if (relative)
+	    mex_file.mark_relative ();
+	}
+    }
+
+  if (! error_state)
+    {
+      if (mex_file)
+	{
+	  void *function = 0;
+
+	  bool have_fmex = false;
+
+	  octave_mex_file_list::append (mex_file);
+
+	  function = mex_file.search (fcn_name, mex_mangler);
+
+	  if (! function)
+	    {
+	      // FIXME -- can we determine this C mangling scheme
+	      // automatically at run time or configure time?
+
+	      function = mex_file.search (fcn_name, mex_uscore_mangler);
+
+	      if (! function)
+		{
+		  function = mex_file.search (fcn_name, mex_f77_mangler);
+
+		  if (function)
+		    have_fmex = true;
+		}
+	    }
+
+	  if (function)
+	    retval = new octave_mex_function (function, have_fmex,
+					      mex_file, fcn_name);
+	  else
+	    ::error ("failed to install .mex file function `%s'",
+		     fcn_name.c_str ());
+  	}
+      else
+	::error ("%s is not a valid shared library",
+		 file_name.c_str ());
+    }
+
+  unwind_protect::run_frame ("octave_dynamic_loader::do_load");
+
+  return retval;
+}
+
+bool
+octave_dynamic_loader::do_remove_oct (const std::string& fcn_name,
+				      octave_shlib& shl)
+{
+  bool retval = false;
+
+  // We don't need to do anything if this is called because we are in
+  // the process of reloading a .oct file that has changed.
+
+  if (! doing_load)
+    {
+      retval = shl.remove (fcn_name);
+
+      if (shl.number_of_functions_loaded () == 0)
+	octave_shlib_list::remove (shl);
+    }
+
+  return retval;
+}
+
+bool
+octave_dynamic_loader::do_remove_mex (const std::string& fcn_name,
+				      octave_shlib& shl)
+{
+  bool retval = false;
+
+  // We don't need to do anything if this is called because we are in
+  // the process of reloading a .oct file that has changed.
+
+  if (! doing_load)
+    {
+      retval = shl.remove (fcn_name);
+
+      if (shl.number_of_functions_loaded () == 0)
+	octave_mex_file_list::remove (shl);
+    }
+
+  return retval;
+}
+
+octave_function *
+octave_dynamic_loader::load_oct (const std::string& fcn_name,
+				  const std::string& file_name,
+				  bool relative)
+{
+  return (instance_ok ())
+    ? instance->do_load_oct (fcn_name, file_name, relative) : 0;
+}
+
+octave_function *
+octave_dynamic_loader::load_mex (const std::string& fcn_name,
+				  const std::string& file_name,
+				  bool relative)
+{
+  return (instance_ok ())
+    ? instance->do_load_mex (fcn_name, file_name, relative) : 0;
+}
+
+bool
+octave_dynamic_loader::remove_oct (const std::string& fcn_name,
+				   octave_shlib& shl)
+{
+  return (instance_ok ()) ? instance->do_remove_oct (fcn_name, shl) : false;
+}
+
+bool
+octave_dynamic_loader::remove_mex (const std::string& fcn_name,
+				   octave_shlib& shl)
+{
+  return (instance_ok ()) ? instance->do_remove_mex (fcn_name, shl) : false;
+}
+
+std::string
+octave_dynamic_loader::name_mangler (const std::string& name)
+{
+  return "G" + name;
+}
+
+std::string
+octave_dynamic_loader::name_uscore_mangler (const std::string& name)
+{
+  return "_G" + name;
+}
+
+std::string
+octave_dynamic_loader::mex_mangler (const std::string&)
+{
+  return "mexFunction";
+}
+
+std::string
+octave_dynamic_loader::mex_uscore_mangler (const std::string&)
+{
+  return "_mexFunction";
+}
+
+std::string
+octave_dynamic_loader::mex_f77_mangler (const std::string&)
+{
+  return STRINGIFY (F77_FUNC (mexfunction, MEXFUNCTION));
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/dynamic-ld.h b/src/dynamic-ld.h
new file mode 100644
index 0000000..8e61a28
--- /dev/null
+++ b/src/dynamic-ld.h
@@ -0,0 +1,105 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dynamic_ld_h)
+#define octave_dynamic_ld_h 1
+
+#include <string>
+
+#include "oct-shlib.h"
+
+class octave_function;
+
+class
+octave_dynamic_loader
+{
+protected:
+
+  octave_dynamic_loader (void) { }
+
+public:
+
+  virtual ~octave_dynamic_loader (void) { }
+
+  static octave_function *
+  load_oct (const std::string& fcn_name,
+	     const std::string& file_name = std::string (),
+	     bool relative = false);
+
+  static octave_function *
+  load_mex (const std::string& fcn_name,
+	     const std::string& file_name = std::string (),
+	     bool relative = false);
+
+  static bool remove_oct (const std::string& fcn_name, octave_shlib& shl);
+
+  static bool remove_mex (const std::string& fcn_name, octave_shlib& shl);
+
+private:
+
+  // No copying!
+
+  octave_dynamic_loader (const octave_dynamic_loader&);
+
+  octave_dynamic_loader& operator = (const octave_dynamic_loader&);
+
+  static octave_dynamic_loader *instance;
+
+  static bool instance_ok (void);
+
+  octave_function *
+  do_load_oct (const std::string& fcn_name,
+		const std::string& file_name = std::string (),
+		bool relative = false);
+
+  octave_function *
+  do_load_mex (const std::string& fcn_name,
+		const std::string& file_name = std::string (),
+		bool relative = false);
+
+  bool do_remove_oct (const std::string& fcn_name, octave_shlib& shl);
+
+  bool do_remove_mex (const std::string& fcn_name, octave_shlib& shl);
+
+  static bool doing_load;
+
+protected:
+
+  static std::string name_mangler (const std::string& name);
+
+  static std::string name_uscore_mangler (const std::string& name);
+
+  static std::string mex_mangler (const std::string& name);
+
+  static std::string mex_uscore_mangler (const std::string& name);
+
+  static std::string mex_f77_mangler (const std::string& name);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/error.cc b/src/error.cc
new file mode 100644
index 0000000..ba05033
--- /dev/null
+++ b/src/error.cc
@@ -0,0 +1,1778 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdarg>
+#include <cstring>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "defun.h"
+#include "error.h"
+#include "input.h"
+#include "pager.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "utils.h"
+#include "ov.h"
+#include "ov-usr-fcn.h"
+#include "pt-pr-code.h"
+#include "pt-stmt.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "variables.h"
+
+// TRUE means that Octave will try to beep obnoxiously before printing
+// error messages.
+static bool Vbeep_on_error = false;
+
+// TRUE means that Octave will try to enter the debugger when an error
+// is encountered.  This will also inhibit printing of the normal
+// traceback message (you will only see the top-level error message).
+bool Vdebug_on_error = false;
+
+// TRUE means that Octave will try to enter the debugger when a warning
+// is encountered.
+bool Vdebug_on_warning = false;
+
+// TRUE means that Octave will try to display a stack trace when a
+// warning is encountered.
+static bool Vbacktrace_on_warning = false;
+
+// TRUE means that Octave will print a verbose warning.  Currently unused.
+static bool Vverbose_warning;
+
+// TRUE means that Octave will print no warnings, but lastwarn will be 
+//updated
+static bool Vquiet_warning = false;
+
+// A structure containing (most of) the current state of warnings.
+static Octave_map warning_options;
+
+// The text of the last error message.
+static std::string Vlast_error_message;
+
+// The text of the last warning message.
+static std::string Vlast_warning_message;
+
+// The last warning message id.
+static std::string Vlast_warning_id;
+
+// The last error message id.
+static std::string Vlast_error_id;
+
+// The last file in which an error occured
+static Octave_map Vlast_error_stack;
+
+// Current error state.
+//
+// Valid values:
+//
+//   -2: an error has occurred, but don't print any messages.
+//   -1: an error has occurred, we are printing a traceback
+//    0: no error
+//    1: an error has occurred
+//
+int error_state = 0;
+
+// Current warning state.
+//
+//  Valid values:
+//
+//    0: no warning
+//    1: a warning has occurred
+//
+int warning_state = 0;
+
+// Tell the error handler whether to print messages, or just store
+// them for later.  Used for handling errors in eval() and
+// the `unwind_protect' statement.
+int buffer_error_messages = 0;
+
+// TRUE means error messages are turned off.
+bool discard_error_messages = false;
+
+// TRUE means warning messages are turned off.
+bool discard_warning_messages = false;
+
+// The message buffer.
+static std::ostringstream *error_message_buffer = 0;
+
+void
+reset_error_handler (void)
+{
+  error_state = 0;
+  warning_state = 0;
+  buffer_error_messages = 0;
+  discard_error_messages = false;
+}
+
+static void
+initialize_warning_options (const std::string& state)
+{
+  warning_options.clear ();
+
+  warning_options.assign ("identifier", "all");
+  warning_options.assign ("state", state);
+}
+
+static Octave_map
+initialize_last_error_stack (void)
+{
+  static bool initialized = false;
+
+  static string_vector sv (4);
+
+  if (! initialized)
+    {
+      sv[0] = "file";
+      sv[1] = "name";
+      sv[2] = "line";
+      sv[3] = "column";
+
+      initialized = true;
+    }
+
+  return Octave_map (dim_vector (0, 1), sv);
+}
+
+// Warning messages are never buffered.
+
+static void
+vwarning (const char *name, const char *id, const char *fmt, va_list args)
+{
+  if (discard_warning_messages)
+    return;
+
+  flush_octave_stdout ();
+
+  std::ostringstream output_buf;
+
+  if (name)
+    output_buf << name << ": ";
+
+  octave_vformat (output_buf, fmt, args);
+
+  output_buf << std::endl;
+
+  // FIXME -- we really want to capture the message before it
+  // has all the formatting goop attached to it.  We probably also
+  // want just the message, not the traceback information.
+
+  std::string msg_string = output_buf.str ();
+
+  if (! warning_state)
+    {
+      // This is the first warning in a possible series.
+
+      Vlast_warning_id = id;
+      Vlast_warning_message = msg_string;
+    }
+
+  if (! Vquiet_warning)
+    {
+      octave_diary << msg_string;
+
+      std::cerr << msg_string;
+    }
+}
+
+static void
+verror (bool save_last_error, std::ostream& os,
+	const char *name, const char *id, const char *fmt, va_list args)
+{
+  if (discard_error_messages)
+    return;
+
+  if (! buffer_error_messages)
+    flush_octave_stdout ();
+
+  // FIXME -- we really want to capture the message before it
+  // has all the formatting goop attached to it.  We probably also
+  // want just the message, not the traceback information.
+
+  std::ostringstream output_buf;
+
+  octave_vformat (output_buf, fmt, args);
+
+  std::string base_msg = output_buf.str ();
+
+  bool to_beep_or_not_to_beep_p = Vbeep_on_error && ! error_state;
+
+  std::string msg_string;
+
+  if (to_beep_or_not_to_beep_p)
+    msg_string = "\a";
+
+  if (name)
+    msg_string += std::string (name) + ": ";
+
+  msg_string += base_msg + "\n";
+
+  if (! error_state && save_last_error)
+    {
+      // This is the first error in a possible series.
+
+      Vlast_error_id = id;
+      Vlast_error_message = base_msg;
+
+      octave_user_code *fcn = octave_call_stack::caller_user_code ();
+
+      if (fcn)
+	{
+	  octave_idx_type curr_frame = -1;
+
+	  Vlast_error_stack = octave_call_stack::backtrace (0, curr_frame);
+	}
+      else
+	Vlast_error_stack = initialize_last_error_stack ();
+    }
+
+  if (buffer_error_messages)
+    {
+      if (error_message_buffer)
+	msg_string = "error: " + msg_string;
+      else
+	error_message_buffer = new std::ostringstream ();
+
+      *error_message_buffer << msg_string;
+    }
+  else
+    {
+      octave_diary << msg_string;
+      os << msg_string;
+    }
+}
+
+// Note that we don't actually print any message if the error string
+// is just "" or "\n".  This allows error ("") and error ("\n") to
+// just set the error state.
+
+static void
+error_1 (std::ostream& os, const char *name, const char *id,
+	 const char *fmt, va_list args)
+{
+  if (error_state != -2)
+    {
+      if (fmt)
+	{
+	  if (*fmt)
+	    {
+	      size_t len = strlen (fmt);
+
+	      if (len > 0)
+		{
+		  if (fmt[len - 1] == '\n')
+		    {
+		      if (len > 1)
+			{
+			  char *tmp_fmt = strsave (fmt);
+			  tmp_fmt[len - 1] = '\0';
+			  verror (true, os, name, id, tmp_fmt, args);
+			  delete [] tmp_fmt;
+			}
+
+		      error_state = -2;
+		    }
+		  else
+		    {
+		      verror (true, os, name, id, fmt, args);
+
+		      if (! error_state)
+			error_state = 1;
+		    }
+		}
+	    }
+	}
+      else
+	panic ("error_1: invalid format");
+    }
+}
+
+void
+vmessage (const char *name, const char *fmt, va_list args)
+{
+  verror (false, std::cerr, name, "", fmt, args);
+}
+
+void
+message (const char *name, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vmessage (name, fmt, args);
+  va_end (args);
+}
+
+void
+vmessage_with_id (const char *name, const char *id, const char *fmt,
+		  va_list args)
+{
+  verror (false, std::cerr, name, id, fmt, args);
+}
+
+void
+message_with_id (const char *name, const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vmessage_with_id (name, id, fmt, args);
+  va_end (args);
+}
+
+void
+usage_1 (const char *id, const char *fmt, va_list args)
+{
+  verror (true, std::cerr, "usage", id, fmt, args);
+  error_state = -1;
+}
+
+void
+vusage (const char *fmt, va_list args)
+{
+  usage_1 ("", fmt, args);
+}
+
+void
+usage (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vusage (fmt, args);
+  va_end (args);
+}
+
+void
+vusage_with_id (const char *id, const char *fmt, va_list args)
+{
+  usage_1 (id, fmt, args);
+}
+
+void
+usage_with_id (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vusage_with_id (id, fmt, args);
+  va_end (args);
+}
+
+static void
+pr_where_2 (const char *fmt, va_list args)
+{
+  if (fmt)
+    {
+      if (*fmt)
+	{
+	  size_t len = strlen (fmt);
+
+	  if (len > 0)
+	    {
+	      if (fmt[len - 1] == '\n')
+		{
+		  if (len > 1)
+		    {
+		      char *tmp_fmt = strsave (fmt);
+		      tmp_fmt[len - 1] = '\0';
+		      verror (false, std::cerr, 0, "", tmp_fmt, args);
+		      delete [] tmp_fmt;
+		    }
+		}
+	      else
+		verror (false, std::cerr, 0, "", fmt, args);
+	    }
+	}
+    }
+  else
+    panic ("pr_where_2: invalid format");
+}
+
+static void
+pr_where_1 (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  pr_where_2 (fmt, args);
+  va_end (args);
+}
+
+static void
+pr_where (const char *who)
+{
+  octave_idx_type curr_frame = -1;
+
+  Octave_map stk = octave_call_stack::backtrace (0, curr_frame);
+
+  octave_idx_type nframes_to_display = stk.numel ();
+
+  if (nframes_to_display > 0)
+    {
+      pr_where_1 ("%s: called from\n", who);
+
+      Cell names = stk.contents ("name");
+      Cell lines = stk.contents ("line");
+      Cell columns = stk.contents ("column");
+
+      for (octave_idx_type i = 0; i < nframes_to_display; i++)
+	{
+	  octave_value name = names(i);
+	  octave_value line = lines(i);
+	  octave_value column = columns(i);
+
+	  std::string nm = name.string_value ();
+
+	  pr_where_1 ("    %s at line %d column %d\n", nm.c_str (),
+		      line.int_value (), column.int_value ());
+	}
+    }
+}
+
+static void
+error_2 (const char *id, const char *fmt, va_list args)
+{
+  int init_state = error_state;
+
+  error_1 (std::cerr, "error", id, fmt, args);
+
+  if ((interactive || forced_interactive)
+      && Vdebug_on_error && init_state == 0
+      && octave_call_stack::caller_user_code ())
+    {
+      unwind_protect_bool (Vdebug_on_error);
+      Vdebug_on_error = false;
+
+      error_state = 0;
+
+      pr_where ("error");
+
+      do_keyboard (octave_value_list ());
+
+      unwind_protect::run ();
+    }
+}
+
+void
+verror (const char *fmt, va_list args)
+{
+  error_2 ("", fmt, args);
+}
+
+void
+error (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror (fmt, args);
+  va_end (args);
+}
+
+void
+verror_with_id (const char *id, const char *fmt, va_list args)
+{
+  error_2 (id, fmt, args);
+}
+
+void
+error_with_id (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror_with_id (id, fmt, args);
+  va_end (args);
+}
+
+static int
+check_state (const std::string& state)
+{
+  // -1: not found
+  //  0: found, "off"
+  //  1: found, "on"
+  //  2: found, "error"
+
+  if (state == "off")
+    return 0;
+  else if (state == "on")
+    return 1;
+  else if (state == "error")
+    return 2;
+  else
+    return -1;
+}
+
+// For given warning ID, return 0 if warnings are disabled, 1 if
+// enabled, and 2 if this ID should be an error instead of a warning.
+
+int
+warning_enabled (const std::string& id)
+{
+  int retval = 0;
+
+  int all_state = -1;
+  int id_state = -1;
+
+  octave_idx_type nel = warning_options.numel ();
+
+  if (nel > 0)
+    {
+      Cell identifier = warning_options.contents ("identifier");
+      Cell state = warning_options.contents ("state");
+
+      bool all_found = false;
+      bool id_found = false;
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  octave_value ov = identifier(i);
+	  std::string ovs = ov.string_value ();
+
+	  if (! all_found && ovs == "all")
+	    {
+	      all_state = check_state (state(i).string_value ());
+
+	      if (all_state >= 0)
+		all_found = true;
+	    }
+
+	  if (! id_found && ovs == id)
+	    {
+	      id_state = check_state (state(i).string_value ());
+
+	      if (id_state >= 0)
+		id_found = true;
+	    }
+
+	  if (all_found && id_found)
+	    break;
+	}
+    }
+
+  if (all_state == -1)
+    panic_impossible ();
+
+  if (all_state == 0)
+    {
+      if (id_state >= 0)
+	retval = id_state;
+    }
+  else if (all_state == 1)
+    {
+      if (id_state == 0 || id_state == 2)
+	retval = id_state;
+      else
+	retval = all_state;
+    }
+  else if (all_state == 2)
+    {
+      if (id_state == 0)
+	retval= id_state;
+      else
+	retval = all_state;
+    }
+
+  return retval;
+}
+
+static void
+warning_1 (const char *id, const char *fmt, va_list args)
+{
+  int warn_opt = warning_enabled (id);
+
+  if (warn_opt == 2)
+    {
+      // Handle this warning as an error.
+
+      error_2 (id, fmt, args);
+    }
+  else if (warn_opt == 1)
+    {
+      vwarning ("warning", id, fmt, args);
+
+      if (! symbol_table::at_top_level ()
+	  && Vbacktrace_on_warning
+	  && ! warning_state
+	  && ! discard_warning_messages)
+	pr_where ("warning");
+
+      warning_state = 1;
+
+      if ((interactive || forced_interactive)
+	  && Vdebug_on_warning
+	  && octave_call_stack::caller_user_code ())
+	{
+	  unwind_protect_bool (Vdebug_on_warning);
+	  Vdebug_on_warning = false;
+
+	  do_keyboard (octave_value_list ());
+
+	  unwind_protect::run ();
+	}
+    }
+}
+
+void
+vwarning (const char *fmt, va_list args)
+{
+  warning_1 ("", fmt, args);
+}
+
+void
+warning (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vwarning (fmt, args);
+  va_end (args);
+}
+
+void
+vwarning_with_id (const char *id, const char *fmt, va_list args)
+{
+  warning_1 (id, fmt, args);
+}
+
+void
+warning_with_id (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vwarning_with_id (id, fmt, args);
+  va_end (args);
+}
+
+void
+vparse_error (const char *fmt, va_list args)
+{
+  error_1 (std::cerr, 0, "", fmt, args);
+}
+
+void
+parse_error (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vparse_error (fmt, args);
+  va_end (args);
+}
+
+void
+vparse_error_with_id (const char *id, const char *fmt, va_list args)
+{
+  error_1 (std::cerr, 0, id, fmt, args);
+}
+
+void
+parse_error_with_id (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  vparse_error_with_id (id, fmt, args);
+  va_end (args);
+}
+
+void
+rethrow_error (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  error_1 (std::cerr, 0, id, fmt, args);
+  va_end (args);
+}
+
+void
+panic (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  buffer_error_messages = 0;
+  discard_error_messages = false;
+  verror (false, std::cerr, "panic", "", fmt, args);
+  va_end (args);
+  abort ();
+}
+
+static void
+defun_usage_message_1 (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  error_1 (octave_stdout, 0, "", fmt, args);
+  va_end (args);
+}
+
+void
+defun_usage_message (const std::string& msg)
+{
+  defun_usage_message_1 ("%s", msg.c_str ());
+}
+
+typedef void (*error_fun)(const char *, const char *, ...);
+
+extern octave_value_list Fsprintf (const octave_value_list&, int);
+
+static std::string
+handle_message (error_fun f, const char *id, const char *msg,
+		const octave_value_list& args)
+{
+  std::string retval;
+
+  std::string tstr;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      octave_value arg;
+
+      if (nargin > 1)
+	{
+	  octave_value_list tmp = Fsprintf (args, 1);
+	  arg = tmp(0);
+	}
+      else
+	arg = args(0);
+
+      if (arg.is_defined ())
+	{
+	  if (arg.is_string ())
+	    {
+	      tstr = arg.string_value ();
+	      msg = tstr.c_str ();
+	      
+	      if (! msg)
+		return retval;
+	    }
+	  else if (arg.is_empty ())
+	    return retval;
+	}
+    }
+
+// Ugh.
+
+  size_t len = strlen (msg);
+
+  if (len > 0)
+    {
+      if (msg[len - 1] == '\n')
+	{
+	  if (len > 1)
+	    {
+	      char *tmp_msg = strsave (msg);
+	      tmp_msg[len - 1] = '\0';
+	      f (id, "%s\n", tmp_msg);
+	      retval = tmp_msg;
+	      delete [] tmp_msg;
+	    }
+	}
+      else
+	{
+	  f (id, "%s", msg);
+	  retval = msg;
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (rethrow, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rethrow (@var{err})\n\
+Reissues a previous error as defined by @var{err}.  @var{err} is a structure\n\
+that must contain at least the 'message' and 'identifier' fields.  @var{err}\n\
+can also contain a field 'stack' that gives information on the assumed\n\
+location of the error.  Typically @var{err} is returned from\n\
+ at code{lasterror}.\n\
+ at seealso{lasterror, lasterr, error}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length();
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      Octave_map err = args(0).map_value ();
+
+      if (! error_state)
+	{
+	  if (err.contains ("message") && err.contains ("identifier"))
+	    {
+	      std::string msg = err.contents("message")(0).string_value ();
+	      std::string id = err.contents("identifier")(0).string_value ();
+	      int len = msg.length();
+
+	      std::string file;
+	      std::string nm;
+	      int l = -1;
+	      int c = -1;
+
+	      Octave_map err_stack = initialize_last_error_stack ();
+
+	      if (err.contains ("stack"))
+		{
+		  err_stack = err.contents("stack")(0).map_value ();
+
+		  if (err_stack.numel () > 0)
+		    {
+		      if (err_stack.contains ("file"))
+			file = err_stack.contents("file")(0).string_value ();
+
+		      if (err_stack.contains ("name"))
+			nm = err_stack.contents("name")(0).string_value ();
+
+		      if (err_stack.contains ("line"))
+			l = err_stack.contents("line")(0).nint_value ();
+
+		      if (err_stack.contains ("column"))
+			c = err_stack.contents("column")(0).nint_value ();
+		    }
+		}
+
+	      // Ugh.
+	      char *tmp_msg = strsave (msg.c_str ());
+	      if (tmp_msg[len-1] == '\n')
+		{
+		  if (len > 1)
+		    {
+		      tmp_msg[len - 1] = '\0';
+		      rethrow_error (id.c_str (), "%s\n", tmp_msg);
+		    }
+		}
+	      else
+		rethrow_error (id.c_str (), "%s", tmp_msg);
+	      delete [] tmp_msg;
+
+	      // FIXME -- is this the right thing to do for
+	      // Vlast_error_stack?  Should it be saved and restored
+	      // with unwind_protect?
+
+	      Vlast_error_stack = err_stack;
+
+	      if (err.contains ("stack"))
+		{
+		  if (file.empty ())
+		    {
+		      if (nm.empty ())
+			{
+			  if (l > 0)
+			    {
+			      if (c > 0)
+				pr_where_1 ("error: near line %d, column %d", 
+					    l, c);
+			      else
+				pr_where_1 ("error: near line %d", l);
+			    }
+			}
+		      else
+			{
+			  if (l > 0)
+			    {
+			      if (c > 0)
+				pr_where_1 ("error: called from `%s' near line %d, column %d", 
+					    nm.c_str (), l, c);
+			      else
+				pr_where_1 ("error: called from `%d' near line %d", nm.c_str (), l);
+			    }
+			}
+		    }
+		  else
+		    {
+		      if (nm.empty ())
+			{
+			  if (l > 0)
+			    {
+			      if (c > 0)
+				pr_where_1 ("error: in file %s near line %d, column %d", 
+					    file.c_str (), l, c);
+			      else
+				pr_where_1 ("error: in file %s near line %d", file.c_str (), l);
+			    }
+			}
+		      else
+			{
+			  if (l > 0)
+			    {
+			      if (c > 0)
+				pr_where_1 ("error: called from `%s' in file %s near line %d, column %d", 
+					    nm.c_str (), file.c_str (), l, c);
+			      else
+				pr_where_1 ("error: called from `%d' in file %s near line %d", nm.c_str (), file.c_str (), l);
+			    }
+			}
+		    }
+		}
+	    }
+	  else
+	    error ("rethrow: structure must contain the fields 'message and 'identifier'");
+	}
+    }
+  return retval;
+}
+
+DEFUN (error, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} error (@var{template}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} error (@var{id}, @var{template}, @dots{})\n\
+Format the optional arguments under the control of the template string\n\
+ at var{template} using the same rules as the @code{printf} family of\n\
+functions (@pxref{Formatted Output}) and print the resulting message\n\
+on the @code{stderr} stream.  The message is prefixed by the character\n\
+string @samp{error: }.\n\
+\n\
+Calling @code{error} also sets Octave's internal error state such that\n\
+control will return to the top level without evaluating any more\n\
+commands.  This is useful for aborting from functions or scripts.\n\
+\n\
+If the error message does not end with a new line character, Octave will\n\
+print a traceback of all the function calls leading to the error.  For\n\
+example, given the following function definitions:\n\
+\n\
+ at example\n\
+ at group\n\
+function f () g (); end\n\
+function g () h (); end\n\
+function h () nargin == 1 || error (\"nargin != 1\"); end\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+calling the function @code{f} will result in a list of messages that\n\
+can help you to quickly locate the exact location of the error:\n\
+\n\
+ at example\n\
+ at group\n\
+f ()\n\
+error: nargin != 1\n\
+error: called from:\n\
+error:   error at line -1, column -1\n\
+error:   h at line 1, column 27\n\
+error:   g at line 1, column 15\n\
+error:   f at line 1, column 15\n\
+ at end group\n\
+ at end example\n\
+\n\
+If the error message ends in a new line character, Octave will print the\n\
+message but will not display any traceback messages as it returns\n\
+control to the top level.  For example, modifying the error message\n\
+in the previous example to end in a new line causes Octave to only print\n\
+a single message:\n\
+\n\
+ at example\n\
+ at group\n\
+function h () nargin == 1 || error (\"nargin != 1\\n\"); end\n\
+f ()\n\
+error: nargin != 1\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  octave_value_list nargs = args;
+
+  std::string id;
+
+  if (nargin == 0)
+    print_usage ();
+  else
+    {
+      if (nargin > 1)
+	{
+	  std::string arg1 = args(0).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (arg1.find ('%') == std::string::npos)
+		{
+		  id = arg1;
+
+		  nargs.resize (nargin-1);
+
+		  for (int i = 1; i < nargin; i++)
+		    nargs(i-1) = args(i);
+		}
+	    }
+	  else
+	    return retval;
+	}
+      else if (nargin == 1 && args(0).is_map ())
+	{
+	  octave_value_list tmp;
+
+	  Octave_map m = args(0).map_value ();
+
+	  if (m.numel () == 1)
+	    {
+	      if (m.contains ("message"))
+		{
+		  Cell c = m.contents ("message");
+
+		  if (! c.is_empty () && c(0).is_string ())
+		    nargs(0) = c(0).string_value ();
+		}
+
+	      if (m.contains ("identifier"))
+		{
+		  Cell c = m.contents ("identifier");
+
+		  if (! c.is_empty () && c(0).is_string ())
+		    id = c(0).string_value ();
+		}
+
+	      // FIXME -- also need to handle "stack" field in error
+	      // structure, but that will require some more significant
+	      // surgery on handle_message, error_with_id, etc.
+	    }
+	}
+
+      handle_message (error_with_id, id.c_str (), "unspecified error", nargs);
+    }
+
+  return retval;
+}
+
+DEFUN (warning, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} warning (@var{template}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} warning (@var{id}, @var{template}, @dots{})\n\
+Format the optional arguments under the control of the template string\n\
+ at var{template} using the same rules as the @code{printf} family of\n\
+functions (@pxref{Formatted Output}) and print the resulting message\n\
+on the @code{stderr} stream.  The message is prefixed by the character\n\
+string @samp{warning: }.\n\
+You should use this function when you want to notify the user\n\
+of an unusual condition, but only when it makes sense for your program\n\
+to go on.\n\
+\n\
+The optional message identifier allows users to enable or disable\n\
+warnings tagged by @var{id}.  The special identifier @samp{\"all\"} may\n\
+be used to set the state of all warnings.\n\
+\n\
+ at deftypefnx {Built-in Function} {} warning (\"on\", @var{id})\n\
+ at deftypefnx {Built-in Function} {} warning (\"off\", @var{id})\n\
+ at deftypefnx {Built-in Function} {} warning (\"error\", @var{id})\n\
+ at deftypefnx {Built-in Function} {} warning (\"query\", @var{id})\n\
+Set or query the state of a particular warning using the identifier\n\
+ at var{id}.  If the identifier is omitted, a value of @samp{\"all\"} is\n\
+assumed.  If you set the state of a warning to @samp{\"error\"}, the\n\
+warning named by @var{id} is handled as if it were an error instead.\n\
+ at seealso{warning_ids}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+  int argc = nargin + 1;
+
+  bool done = false;
+
+  if (argc > 1 && args.all_strings_p ())
+    {
+      string_vector argv = args.make_argv ("warning");
+
+      if (! error_state)
+	{
+	  std::string arg1 = argv(1);
+	  std::string arg2 = "all";
+
+	  if (argc == 3)
+	    arg2 = argv(2);
+
+	  if (arg1 == "on" || arg1 == "off" || arg1 == "error")
+	    {
+	      Octave_map old_warning_options = warning_options;
+
+	      if (arg2 == "all")
+		{
+		  Octave_map tmp;
+
+		  Cell id (1, 1);
+		  Cell st (1, 1);
+
+		  id(0) = arg2;
+		  st(0) = arg1;
+
+		  // Since internal Octave functions are not
+		  // compatible, turning all warnings into errors
+		  // should leave the state of
+		  // Octave:matlab-incompatible alone.
+
+		  if (arg1 == "error"
+		      && warning_options.contains ("identifier"))
+		    {
+		      octave_idx_type n = 1;
+
+		      Cell tid = warning_options.contents ("identifier");
+		      Cell tst = warning_options.contents ("state");
+
+		      for (octave_idx_type i = 0; i < tid.numel (); i++)
+			{
+			  octave_value vid = tid(i);
+
+			  if (vid.is_string ())
+			    {
+			      std::string key = vid.string_value ();
+
+			      if (key == "Octave:matlab-incompatible"
+				  || key == "Octave:single-quote-string")
+				{
+				  id.resize (dim_vector (1, n+1));
+				  st.resize (dim_vector (1, n+1));
+
+				  id(n) = tid(i);
+				  st(n) = tst(i);
+
+				  n++;
+				}
+			    }
+			}
+		    }
+
+		  tmp.assign ("identifier", id);
+		  tmp.assign ("state", st);
+
+		  warning_options = tmp;
+
+		  done = true;
+		}
+	      else if (arg2 == "backtrace")
+		{
+		  if (arg1 != "error")
+		    {
+		      Vbacktrace_on_warning = (arg1 == "on");
+		      done = true;
+		    }
+		}
+	      else if (arg2 == "debug")
+		{
+		  if (arg1 != "error")
+		    {
+		      Vdebug_on_warning = (arg1 == "on");
+		      done = true;
+		    }
+		}
+	      else if (arg2 == "verbose")
+		{
+		  if (arg1 != "error")
+		    {
+		      Vverbose_warning = (arg1 == "on");
+		      done = true;
+		    }
+		}
+	      else if (arg2 == "quiet")
+		{
+		  if (arg1 != "error")
+		    {
+		      Vquiet_warning = (arg1 == "on");
+		      done = true;
+		    }
+		}
+	      else
+		{
+		  if (arg2 == "last")
+		    arg2 = Vlast_warning_id;
+
+		  if (arg2 == "all")
+		    initialize_warning_options (arg1);
+		  else
+		    {
+		      Cell ident = warning_options.contents ("identifier");
+		      Cell state = warning_options.contents ("state");
+
+		      octave_idx_type nel = ident.numel ();
+
+		      bool found = false;
+
+		      for (octave_idx_type i = 0; i < nel; i++)
+			{
+			  if (ident(i).string_value () == arg2)
+			    {
+			      // FIXME -- if state for "all" is
+			      // same as arg1, we can simply remove the
+			      // item from the list.
+
+			      state(i) = arg1;
+			      warning_options.assign ("state", state);
+			      found = true;
+			      break;
+			    }
+			}
+
+		      if (! found)
+			{
+			  // FIXME -- if state for "all" is
+			  // same as arg1, we don't need to do anything.
+
+			  ident.resize (dim_vector (1, nel+1));
+			  state.resize (dim_vector (1, nel+1));
+
+			  ident(nel) = arg2;
+			  state(nel) = arg1;
+
+			  warning_options.clear ();
+
+			  warning_options.assign ("identifier", ident);
+			  warning_options.assign ("state", state);
+			}
+		    }
+
+		  done = true;
+		}
+
+	      if (done && nargout > 0)
+		retval = old_warning_options;
+	    }
+	  else if (arg1 == "query")
+	    {
+	      if (arg2 == "all")
+		retval = warning_options;
+	      else if (arg2 == "backtrace" || arg2 == "debug"
+		       || arg2 == "verbose" || arg2 == "quiet")
+		{
+		  Octave_map tmp;
+		  tmp.assign ("identifier", arg2);
+		  if (arg2 == "backtrace")
+		    tmp.assign ("state", Vbacktrace_on_warning ? "on" : "off");
+		  else if (arg2 == "debug")
+		    tmp.assign ("state", Vdebug_on_warning ? "on" : "off");
+		  else if (arg2 == "verbose")
+		    tmp.assign ("state", Vverbose_warning ? "on" : "off");
+		  else
+		    tmp.assign ("state", Vquiet_warning ? "on" : "off");
+
+		  retval = tmp;
+		}
+	      else
+		{
+		  if (arg2 == "last")
+		    arg2 = Vlast_warning_id;
+
+		  Cell ident = warning_options.contents ("identifier");
+		  Cell state = warning_options.contents ("state");
+
+		  octave_idx_type nel = ident.numel ();
+
+		  bool found = false;
+		  
+		  std::string val;
+
+		  for (octave_idx_type i = 0; i < nel; i++)
+		    {
+		      if (ident(i).string_value () == arg2)
+			{
+			  val = state(i).string_value ();
+			  found = true;
+			  break;
+			}
+		    }
+
+		  if (! found)
+		    {
+		      for (octave_idx_type i = 0; i < nel; i++)
+			{
+			  if (ident(i).string_value () == "all")
+			    {
+			      val = state(i).string_value ();
+			      found = true;
+			      break;
+			    }
+			}
+		    }
+
+		  if (found)
+		    {
+		      Octave_map tmp;
+
+		      tmp.assign ("identifier", arg2);
+		      tmp.assign ("state", val);
+
+		      retval = tmp;
+		    }
+		  else
+		    error ("warning: unable to find default warning state!");
+		}
+
+	      done = true;
+	    }
+	}
+    }
+  else if (argc == 1)
+    {
+      retval = warning_options;
+
+      done = true;
+    }
+  else if (argc == 2)
+    {
+      octave_value arg = args(0);
+
+      Octave_map old_warning_options = warning_options;
+
+      if (arg.is_map ())
+	{
+	  Octave_map m = arg.map_value ();
+
+	  if (m.contains ("identifier") && m.contains ("state"))
+	    warning_options = m;
+	  else
+	    error ("warning: expecting structure with fields `identifier' and `state'");
+
+	  done = true;
+
+	  if (nargout > 0)
+	    retval = old_warning_options;
+	}
+    }
+
+  if (! (error_state || done))
+    {
+      octave_value_list nargs = args;
+
+      std::string id;
+
+      if (nargin > 1)
+	{
+	  std::string arg1 = args(0).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (arg1.find ('%') == std::string::npos)
+		{
+		  id = arg1;
+
+		  nargs.resize (nargin-1);
+
+		  for (int i = 1; i < nargin; i++)
+		    nargs(i-1) = args(i);
+		}
+	    }
+	  else
+	    return retval;
+	}
+
+      std::string prev_msg = Vlast_warning_message;
+
+      std::string curr_msg = handle_message (warning_with_id, id.c_str (),
+					     "unspecified warning", nargs);
+
+      if (nargout > 0)
+	retval = prev_msg;
+    }
+
+  return retval;
+}
+
+void
+disable_warning (const std::string& id)
+{
+  octave_value_list args;
+
+  args(1) = id;
+  args(0) = "off";
+
+  Fwarning (args, 0);
+}
+
+void
+initialize_default_warning_state (void)
+{
+  initialize_warning_options ("on");
+
+  // Most people will want to have the following disabled.
+
+  disable_warning ("Octave:array-to-scalar");
+  disable_warning ("Octave:array-to-vector");
+  disable_warning ("Octave:empty-list-elements");
+  disable_warning ("Octave:fortran-indexing");
+  disable_warning ("Octave:imag-to-real");
+  disable_warning ("Octave:matlab-incompatible");
+  disable_warning ("Octave:missing-semicolon");
+  disable_warning ("Octave:neg-dim-as-zero");
+  disable_warning ("Octave:resize-on-range-error");
+  disable_warning ("Octave:separator-insert");
+  disable_warning ("Octave:single-quote-string");
+  disable_warning ("Octave:str-to-num");
+  disable_warning ("Octave:string-concat");
+  disable_warning ("Octave:variable-switch-label");
+  disable_warning ("Octave:int-convert-nan");
+  disable_warning ("Octave:int-convert-non-int-val");
+  disable_warning ("Octave:int-convert-overflow");
+  disable_warning ("Octave:int-math-overflow");
+}
+
+DEFUN (lasterror, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{err} =} lasterror (@var{err})\n\
+ at deftypefnx {Built-in Function} {} lasterror ('reset')\n\
+Returns or sets the last error message.  Called without any arguments\n\
+returns a structure containing the last error message, as well as other\n\
+information related to this error.  The elements of this structure are:\n\
+\n\
+ at table @asis\n\
+ at item 'message'\n\
+The text of the last error message\n\
+ at item 'identifier'\n\
+The message identifier of this error message\n\
+ at item 'stack'\n\
+A structure containing information on where the message occurred.  This might\n\
+be an empty structure if this in the case where this information cannot\n\
+be obtained.  The fields of this structure are:\n\
+\n\
+ at table @asis\n\
+ at item 'file'\n\
+The name of the file where the error occurred\n\
+ at item 'name'\n\
+The name of function in which the error occurred\n\
+ at item 'line'\n\
+The line number at which the error occurred\n\
+ at item 'column'\n\
+An optional field with the column number at which the error occurred\n\
+ at end table\n\
+ at end table\n\
+\n\
+The @var{err} structure may also be passed to @code{lasterror} to set the\n\
+information about the last error.  The only constraint on @var{err} in that\n\
+case is that it is a scalar structure.  Any fields of @var{err} that match\n\
+the above are set to the value passed in @var{err}, while other fields are\n\
+set to their default values.\n\
+\n\
+If @code{lasterror} is called with the argument 'reset', all values take\n\
+their default values.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length();
+
+  unwind_protect::begin_frame ("Flasterror");
+
+  unwind_protect_int (error_state);
+  error_state = 0;
+
+  if (nargin < 2)
+    {
+      Octave_map err;
+
+      err.assign ("message", Vlast_error_message);
+      err.assign ("identifier", Vlast_error_id);
+
+      err.assign ("stack", octave_value (Vlast_error_stack));
+
+      if (nargin == 1)
+	{
+	  if (args(0).is_string())
+	    {
+	      if (args(0).string_value () == "reset")
+		{
+		  Vlast_error_message = std::string();
+		  Vlast_error_id = std::string();
+
+		  Vlast_error_stack = initialize_last_error_stack ();
+		}
+	      else
+		error("lasterror: unrecognized string argument");
+	    }
+	  else if (args(0).is_map ())
+	    {
+	      Octave_map new_err = args(0).map_value ();
+	      std::string new_error_message;
+	      std::string new_error_id;
+	      std::string new_error_file;
+	      std::string new_error_name;
+	      int new_error_line = -1;
+	      int new_error_column = -1;
+
+	      if (! error_state && new_err.contains ("message"))
+		{
+		  const std::string tmp = 
+		    new_err.contents("message")(0).string_value ();
+		  new_error_message = tmp;
+		}
+
+	      if (! error_state && new_err.contains ("identifier"))
+		{
+		  const std::string tmp = 
+		    new_err.contents("identifier")(0).string_value ();
+		  new_error_id = tmp;
+		}
+
+	      if (! error_state && new_err.contains ("stack"))
+		{
+		  Octave_map new_err_stack = 
+		    new_err.contents("identifier")(0).map_value ();
+
+		  if (! error_state && new_err_stack.contains ("file"))
+		    {
+		      const std::string tmp = 
+			new_err_stack.contents("file")(0).string_value ();
+		      new_error_file = tmp;
+		    }
+
+		  if (! error_state && new_err_stack.contains ("name"))
+		    {
+		      const std::string tmp = 
+			new_err_stack.contents("name")(0).string_value ();
+		      new_error_name = tmp;
+		    }
+
+		  if (! error_state && new_err_stack.contains ("line"))
+		    {
+		      const int tmp = 
+			new_err_stack.contents("line")(0).nint_value ();
+		      new_error_line = tmp;
+		    }
+		  
+		  if (! error_state && new_err_stack.contains ("column"))
+		    {
+		      const int tmp = 
+			new_err_stack.contents("column")(0).nint_value ();
+		      new_error_column = tmp;
+		    }
+		}
+
+	      if (! error_state)
+		{
+		  Vlast_error_message = new_error_message;
+		  Vlast_error_id = new_error_id;
+
+		  octave_idx_type curr_frame = -1;
+
+		  Vlast_error_stack
+		    = octave_call_stack::backtrace (0, curr_frame);
+		}
+	    }
+	  else
+	    error ("lasterror: argument must be a structure or a string");
+	}
+
+      if (! error_state)
+	retval = err;
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Flasterror");
+
+  return retval;  
+}
+
+DEFUN (lasterr, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lasterr (@var{msg}, @var{msgid})\n\
+Without any arguments, return the last error message.  With one\n\
+argument, set the last error message to @var{msg}.  With two arguments,\n\
+also set the last message identifier.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  unwind_protect::begin_frame ("Flasterr");
+
+  unwind_protect_int (error_state);
+  error_state = 0;
+
+  int argc = args.length () + 1;
+
+  if (argc < 4)
+    {
+      string_vector argv = args.make_argv ("lasterr");
+
+      if (! error_state)
+	{
+	  std::string prev_error_id = Vlast_error_id;
+	  std::string prev_error_message = Vlast_error_message;
+
+	  if (argc > 2)
+	    Vlast_error_id = argv(2);
+
+	  if (argc > 1)
+	    Vlast_error_message = argv(1);
+
+	  if (argc == 1 || nargout > 0)
+	    {
+	      retval(1) = prev_error_id;
+	      retval(0) = prev_error_message;
+	    }
+	}
+      else
+	error ("lasterr: expecting arguments to be character strings");
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Flasterr");
+
+  return retval;  
+}
+
+// For backward compatibility.
+DEFALIAS (error_text, lasterr);
+DEFALIAS (__error_text__, lasterr);
+
+DEFUN (lastwarn, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lastwarn (@var{msg}, @var{msgid})\n\
+Without any arguments, return the last warning message.  With one\n\
+argument, set the last warning message to @var{msg}.  With two arguments,\n\
+also set the last message identifier.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  if (argc < 4)
+    {
+      string_vector argv = args.make_argv ("lastwarn");
+
+      if (! error_state)
+	{
+	  std::string prev_warning_id = Vlast_warning_id;
+	  std::string prev_warning_message = Vlast_warning_message;
+
+	  if (argc > 2)
+	    Vlast_warning_id = argv(2);
+
+	  if (argc > 1)
+	    Vlast_warning_message = argv(1);
+
+	  if (argc == 1 || nargout > 0)
+	    {
+	      warning_state = 0;
+	      retval(1) = prev_warning_id;
+	      retval(0) = prev_warning_message;
+	    }
+	}
+      else
+	error ("lastwarn: expecting arguments to be character strings");
+    }
+  else
+    print_usage ();
+
+  return retval;  
+}
+
+DEFUN (usage, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} usage (@var{msg})\n\
+Print the message @var{msg}, prefixed by the string @samp{usage: }, and\n\
+set Octave's internal error state such that control will return to the\n\
+top level without evaluating any more commands.  This is useful for\n\
+aborting from functions.\n\
+\n\
+After @code{usage} is evaluated, Octave will print a traceback of all\n\
+the function calls leading to the usage message.\n\
+\n\
+You should use this function for reporting problems errors that result\n\
+from an improper call to a function, such as calling a function with an\n\
+incorrect number of arguments, or with arguments of the wrong type.  For\n\
+example, most functions distributed with Octave begin with code like\n\
+this\n\
+\n\
+ at example\n\
+ at group\n\
+if (nargin != 2)\n\
+  usage (\"foo (a, b)\");\n\
+endif\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+to check for the proper number of arguments.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+  handle_message (usage_with_id, "", "unknown", args);
+  return retval;
+}
+
+DEFUN (beep_on_error, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} beep_on_error ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} beep_on_error (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave will try\n\
+to ring the terminal bell before printing an error message.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (beep_on_error);
+}
+
+DEFUN (debug_on_error, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_error ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_error (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave will try\n\
+to enter the debugger when an error is encountered.  This will also\n\
+inhibit printing of the normal traceback message (you will only see\n\
+the top-level error message).\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (debug_on_error);
+}
+
+DEFUN (debug_on_warning, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_warning ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_warning (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave will try\n\
+to enter the debugger when a warning is encountered.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (debug_on_warning);
+}
+
+std::string
+last_error_message (void)
+{
+  return Vlast_error_message;
+}
+
+std::string
+last_error_id (void)
+{
+  return Vlast_error_id;
+}
+
+std::string
+last_warning_message (void)
+{
+  return Vlast_warning_message;
+}
+
+std::string
+last_warning_id (void)
+{
+  return Vlast_warning_id;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/error.h b/src/error.h
new file mode 100644
index 0000000..2775251
--- /dev/null
+++ b/src/error.h
@@ -0,0 +1,129 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_error_h)
+#define octave_error_h 1
+
+#include <cstdarg>
+#include <string>
+
+#define panic_impossible() \
+  panic ("impossible state reached in file `%s' at line %d", \
+	 __FILE__, __LINE__)
+
+extern OCTINTERP_API void reset_error_handler (void);
+
+extern OCTINTERP_API int warning_enabled (const std::string& id);
+
+extern OCTINTERP_API void vmessage (const char *name, const char *fmt, va_list args);
+extern OCTINTERP_API void message (const char *name, const char *fmt, ...);
+
+extern OCTINTERP_API void vusage (const char *fmt, va_list args);
+extern OCTINTERP_API void usage (const char *fmt, ...);
+
+extern OCTINTERP_API void vwarning (const char *fmt, va_list args);
+extern OCTINTERP_API void warning (const char *fmt, ...);
+
+extern OCTINTERP_API void verror (const char *fmt, va_list args);
+extern OCTINTERP_API void error (const char *fmt, ...);
+
+extern OCTINTERP_API void vparse_error (const char *fmt, va_list args);
+extern OCTINTERP_API void parse_error (const char *fmt, ...);
+
+extern OCTINTERP_API void
+vmessage_with_id (const char *id, const char *name, const char *fmt, va_list args);
+
+extern OCTINTERP_API void
+message_with_id (const char *id, const char *name, const char *fmt, ...);
+
+extern OCTINTERP_API void
+vusage_with_id (const char *id, const char *fmt, va_list args);
+
+extern OCTINTERP_API void
+usage_with_id (const char *id, const char *fmt, ...);
+
+extern OCTINTERP_API void
+vwarning_with_id (const char *id, const char *fmt, va_list args);
+
+extern OCTINTERP_API void
+warning_with_id (const char *id, const char *fmt, ...);
+
+extern OCTINTERP_API void
+verror_with_id (const char *id, const char *fmt, va_list args);
+
+extern OCTINTERP_API void
+error_with_id (const char *id, const char *fmt, ...);
+
+extern OCTINTERP_API void
+vparse_error_with_id (const char *id, const char *fmt, va_list args);
+
+extern OCTINTERP_API void
+parse_error_with_id (const char *id, const char *fmt, ...);
+
+extern OCTINTERP_API void panic (const char *fmt, ...) GCC_ATTR_NORETURN;
+
+// Helper function for print_usage defined in defun.cc.
+extern OCTINTERP_API void defun_usage_message (const std::string& msg);
+
+extern OCTINTERP_API void disable_warning (const std::string& id);
+extern OCTINTERP_API void initialize_default_warning_state (void);
+
+// TRUE means that Octave will try to enter the debugger when an error
+// is encountered.  This will also inhibit printing of the normal
+// traceback message (you will only see the top-level error message).
+extern OCTINTERP_API bool Vdebug_on_error;
+
+// TRUE means that Octave will try to enter the debugger when a warning
+// is encountered.
+extern OCTINTERP_API bool Vdebug_on_warning;
+
+// Current error state.
+extern OCTINTERP_API int error_state;
+
+// Current warning state.
+extern OCTINTERP_API int warning_state;
+
+// Tell the error handler whether to print messages, or just store
+// them for later.  Used for handling errors in eval() and
+// the `unwind_protect' statement.
+extern OCTINTERP_API int buffer_error_messages;
+
+// TRUE means error messages are turned off.
+extern OCTINTERP_API bool discard_error_messages;
+
+// TRUE means warning messages are turned off.
+extern OCTINTERP_API bool discard_warning_messages;
+
+// Helper functions to pass last error and warning messages and ids
+extern OCTINTERP_API std::string last_error_message (void);
+extern OCTINTERP_API std::string last_error_id (void);
+extern OCTINTERP_API std::string last_warning_message (void);
+extern OCTINTERP_API std::string last_warning_id (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/file-io.cc b/src/file-io.cc
new file mode 100644
index 0000000..60f31f4
--- /dev/null
+++ b/src/file-io.cc
@@ -0,0 +1,2244 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Originally written by John C. Campbell <jcc at bevo.che.wisc.edu>
+//
+// Thomas Baier <baier at ci.tuwien.ac.at> added the original versions of
+// the following functions:
+//
+//   popen
+//   pclose
+//   execute       (now popen2.m)
+//   sync_system   (now merged with system)
+//   async_system  (now merged with system)
+
+// Extensively revised by John W. Eaton <jwe at octave.org>,
+// April 1996.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <climits>
+#include <cstdio>
+
+#include <iostream>
+#include <stack>
+#include <vector>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "error.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "lo-ieee.h"
+#include "oct-env.h"
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "file-io.h"
+#include "load-path.h"
+#include "oct-fstrm.h"
+#include "oct-iostrm.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "oct-prcstrm.h"
+#include "oct-stream.h"
+#include "oct-strstrm.h"
+#include "pager.h"
+#include "sysdep.h"
+#include "utils.h"
+#include "variables.h"
+
+static octave_value stdin_file;
+static octave_value stdout_file;
+static octave_value stderr_file;
+
+static octave_stream stdin_stream;
+static octave_stream stdout_stream;
+static octave_stream stderr_stream;
+
+void
+initialize_file_io (void)
+{
+  stdin_stream = octave_istream::create (&std::cin, "stdin");
+
+  // This uses octave_stdout (see pager.h), not std::cout so that Octave's
+  // standard output stream will pass through the pager.
+
+  stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
+
+  stderr_stream = octave_ostream::create (&std::cerr, "stderr");
+
+  stdin_file = octave_stream_list::insert (stdin_stream);
+  stdout_file = octave_stream_list::insert (stdout_stream);
+  stderr_file = octave_stream_list::insert (stderr_stream);
+}
+
+void
+close_files (void)
+{
+  octave_stream_list::clear ();
+}
+
+// List of files to delete when we exit or crash.
+//
+// FIXME -- this should really be static, but that causes
+// problems on some systems.
+std::stack <std::string> tmp_files;
+
+void
+mark_for_deletion (const std::string& file)
+{
+  tmp_files.push (file);
+}
+
+void
+cleanup_tmp_files (void)
+{
+  while (! tmp_files.empty ())
+    {
+      std::string filename = tmp_files.top ();
+      tmp_files.pop ();
+      unlink (filename.c_str ());
+    }
+}
+
+static std::ios::openmode
+fopen_mode_to_ios_mode (const std::string& mode_arg)
+{
+  std::ios::openmode retval = std::ios::in;
+
+  if (! mode_arg.empty ())
+    {
+      // Could probably be faster, but does it really matter?
+
+      std::string mode = mode_arg;
+
+      // 'W' and 'R' are accepted as 'w' and 'r', but we warn about
+      // them because Matlab says they perform "automatic flushing"
+      // but we don't know precisely what action that implies.
+
+      size_t pos = mode.find ('W');
+
+      if (pos != std::string::npos)
+	{
+	  warning ("fopen: treating mode \"W\" as equivalent to \"w\"");
+	  mode[pos] = 'w';
+	}
+
+      pos = mode.find ('R');
+
+      if (pos != std::string::npos)
+	{
+	  warning ("fopen: treating mode \"R\" as equivalent to \"r\"");
+	  mode[pos] = 'r';
+	}
+
+      pos = mode.find ('z');
+
+      if (pos != std::string::npos)
+	{
+#if defined (HAVE_ZLIB)
+	  mode.erase (pos, 1);
+#else
+	  error ("this version of Octave does not support gzipped files");
+#endif
+	}
+
+      if (! error_state)
+	{
+	  if (mode == "rt")
+	    retval = std::ios::in;
+	  else if (mode == "wt")
+	    retval = std::ios::out | std::ios::trunc;
+	  else if (mode == "at")
+	    retval = std::ios::out | std::ios::app;
+	  else if (mode == "r+t")
+	    retval = std::ios::in | std::ios::out;
+	  else if (mode == "w+t")
+	    retval = std::ios::in | std::ios::out | std::ios::trunc;
+	  else if (mode == "a+t")
+	    retval = std::ios::in | std::ios::out | std::ios::app;
+	  else if (mode == "rb" || mode == "r")
+	    retval = std::ios::in | std::ios::binary;
+	  else if (mode == "wb" || mode == "w")
+	    retval = std::ios::out | std::ios::trunc | std::ios::binary;
+	  else if (mode == "ab" || mode == "a")
+	    retval = std::ios::out | std::ios::app | std::ios::binary;
+	  else if (mode == "r+b" || mode == "r+")
+	    retval = std::ios::in | std::ios::out | std::ios::binary;
+	  else if (mode == "w+b" || mode == "w+")
+	    retval = (std::ios::in | std::ios::out | std::ios::trunc
+		      | std::ios::binary);
+	  else if (mode == "a+b" || mode == "a+")
+	    retval = (std::ios::in | std::ios::out | std::ios::app
+		      | std::ios::binary);
+	  else
+	    ::error ("invalid mode specified");
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (fclose, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fclose (@var{fid})\n\
+Closes the specified file.  If successful, @code{fclose} returns 0,\n\
+otherwise, it returns -1.\n\
+ at seealso{fopen, fseek, ftell}\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    retval = octave_stream_list::remove (args(0), "fclose");
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fclear, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fclear (@var{fid})\n\
+Clear the stream state for the specified file.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      int fid = octave_stream_list::get_file_number (args (0));
+
+      octave_stream os = octave_stream_list::lookup (fid, "fclear");
+
+      if (! error_state)
+	os.clearerr ();
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fflush, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fflush (@var{fid})\n\
+Flush output to @var{fid}.  This is useful for ensuring that all\n\
+pending output makes it to the screen before some other event occurs.\n\
+For example, it is always a good idea to flush the standard output\n\
+stream before calling @code{input}.\n\
+\n\
+ at code{fflush} returns 0 on success and an OS dependent error value\n\
+(@minus{}1 on unix) on error.\n\
+ at seealso{fopen, fclose}\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      // FIXME -- any way to avoid special case for stdout?
+
+      int fid = octave_stream_list::get_file_number (args (0));
+
+      if (fid == 1)
+	{
+	  flush_octave_stdout ();
+
+	  retval = 0;
+	}
+      else
+	{
+	  octave_stream os = octave_stream_list::lookup (fid, "fflush");
+
+	  if (! error_state)
+	    retval = os.flush ();
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fgetl, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fgetl (@var{fid}, @var{len})\n\
+Read characters from a file, stopping after a newline, or EOF,\n\
+or @var{len} characters have been read.  The characters read, excluding\n\
+the possible trailing newline, are returned as a string.\n\
+\n\
+If @var{len} is omitted, @code{fgetl} reads until the next newline\n\
+character.\n\
+\n\
+If there are no more characters to read, @code{fgetl} returns @minus{}1.\n\
+ at seealso{fread, fscanf}\n\
+ at end deftypefn")
+{
+  static std::string who = "fgetl";
+
+  octave_value_list retval;
+
+  retval(1) = 0;
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), who);
+
+      if (! error_state)
+	{
+	  octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
+
+	  bool err = false;
+
+	  std::string tmp = os.getl (len_arg, err, who);
+
+	  if (! (error_state || err))
+	    {
+	      retval(1) = tmp.length ();
+	      retval(0) = tmp;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fgets, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fgets (@var{fid}, @var{len})\n\
+Read characters from a file, stopping after a newline, or EOF,\n\
+or @var{len} characters have been read.  The characters read, including\n\
+the possible trailing newline, are returned as a string.\n\
+\n\
+If @var{len} is omitted, @code{fgets} reads until the next newline\n\
+character.\n\
+\n\
+If there are no more characters to read, @code{fgets} returns @minus{}1.\n\
+ at seealso{fputs, fopen, fread, fscanf}\n\
+ at end deftypefn")
+{
+  static std::string who = "fgets";
+
+  octave_value_list retval;
+
+  retval(1) = 0.0;
+  retval(0) = -1.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), who);
+
+      if (! error_state)
+	{
+	  octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
+
+	  bool err = false;
+
+	  std::string tmp = os.gets (len_arg, err, who);
+
+	  if (! (error_state || err))
+	    {
+	      retval(1) = tmp.length ();
+	      retval(0) = tmp;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static octave_stream
+do_stream_open (const std::string& name, const std::string& mode,
+		const std::string& arch, int& fid)
+{
+  octave_stream retval;
+
+  fid = -1;
+
+  std::ios::openmode md = fopen_mode_to_ios_mode (mode);
+
+  if (! error_state)
+    {
+      oct_mach_info::float_format flt_fmt =
+	oct_mach_info::string_to_float_format (arch);
+
+      if (! error_state)
+	{
+	  std::string fname = file_ops::tilde_expand (name);
+
+	  file_stat fs (fname);
+
+	  if (! (md & std::ios::out
+		 || octave_env::absolute_pathname (fname)
+		 || octave_env::rooted_relative_pathname (fname)))
+	    {
+	      if (! fs.exists ())
+		{
+		  std::string tmp = octave_env::make_absolute
+		    (load_path::find_file (fname), octave_env::getcwd ());
+
+		  if (! tmp.empty ())
+		    {
+		      warning_with_id ("Octave:fopen-file-in-path",
+				       "fopen: file found in load path");
+		      fname = tmp;
+		    }
+		}
+	    }
+	  
+	  if (! fs.is_dir ())
+	    {
+	      std::string tmode = mode;
+
+	      // Use binary mode if 't' is not specified, but don't add
+	      // 'b' if it is already present.
+
+	      size_t bpos = tmode.find ('b');
+	      size_t tpos = tmode.find ('t');
+
+	      if (bpos == std::string::npos && tpos == std::string::npos)
+		tmode += 'b';
+
+#if defined (HAVE_ZLIB)
+	      size_t pos = tmode.find ('z');
+
+	      if (pos != std::string::npos)
+		{
+		  tmode.erase (pos, 1);
+
+		  gzFile fptr = ::gzopen (fname.c_str (), tmode.c_str ());
+
+		  if (fptr)
+		    retval = octave_zstdiostream::create (fname, fptr, md, flt_fmt);
+		  else
+		    {
+		      using namespace std;
+		      retval.error (::strerror (errno));
+		    }
+		}
+	      else
+#endif
+		{
+		  FILE *fptr = ::fopen (fname.c_str (), tmode.c_str ());
+
+		  retval = octave_stdiostream::create (fname, fptr, md, flt_fmt);
+
+		  if (! fptr)
+		    {
+		      using namespace std;
+		      retval.error (::strerror (errno));
+		    }
+		}
+
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_stream
+do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
+		const octave_value& tc_arch, const char *fcn, int& fid)
+{
+  octave_stream retval;
+
+  fid = -1;
+
+  std::string name = tc_name.string_value ();
+
+  if (! error_state)
+    {
+      std::string mode = tc_mode.string_value ();
+
+      if (! error_state)
+	{
+	  std::string arch = tc_arch.string_value ();
+
+	  if (! error_state)
+	    retval = do_stream_open (name, mode, arch, fid);
+	  else
+	    ::error ("%s: architecture type must be a string", fcn);
+	}
+      else
+	::error ("%s: file mode must be a string", fcn);
+    }
+  else
+    ::error ("%s: file name must be a string", fcn);
+
+  return retval;
+}
+
+DEFUN (fopen, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})\n\
+ at deftypefnx {Built-in Function} {@var{fid_list} =} fopen (\"all\")\n\
+ at deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})\n\
+The first form of the @code{fopen} function opens the named file with\n\
+the specified mode (read-write, read-only, etc.) and architecture\n\
+interpretation (IEEE big endian, IEEE little endian, etc.), and returns\n\
+an integer value that may be used to refer to the file later.  If an\n\
+error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the\n\
+corresponding system error message.  The @var{mode} is a one or two\n\
+character string that specifies whether the file is to be opened for\n\
+reading, writing, or both.\n\
+\n\
+The second form of the @code{fopen} function returns a vector of file ids\n\
+corresponding to all the currently open files, excluding the\n\
+ at code{stdin}, @code{stdout}, and @code{stderr} streams.\n\
+\n\
+The third form of the @code{fopen} function returns information about the\n\
+open file given its file id.\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+myfile = fopen (\"splat.dat\", \"r\", \"ieee-le\");\n\
+ at end example\n\
+\n\
+ at noindent\n\
+opens the file @file{splat.dat} for reading.  If necessary, binary\n\
+numeric values will be read assuming they are stored in IEEE format with\n\
+the least significant bit first, and then converted to the native\n\
+representation.\n\
+\n\
+Opening a file that is already open simply opens it again and returns a\n\
+separate file id.  It is not an error to open a file several times,\n\
+though writing to the same file through several different file ids may\n\
+produce unexpected results.\n\
+\n\
+The possible values @samp{mode} may have are\n\
+\n\
+ at table @asis\n\
+ at item @samp{r}\n\
+Open a file for reading.\n\
+\n\
+ at item @samp{w}\n\
+Open a file for writing.  The previous contents are discarded.\n\
+\n\
+ at item @samp{a}\n\
+Open or create a file for writing at the end of the file.\n\
+\n\
+ at item @samp{r+}\n\
+Open an existing file for reading and writing.\n\
+\n\
+ at item @samp{w+}\n\
+Open a file for reading or writing.  The previous contents are\n\
+discarded.\n\
+\n\
+ at item @samp{a+}\n\
+Open or create a file for reading or writing at the end of the\n\
+file.\n\
+ at end table\n\
+\n\
+Append a \"t\" to the mode string to open the file in text mode or a\n\
+\"b\" to open in binary mode.  On Windows and Macintosh systems, text\n\
+mode reading and writing automatically converts linefeeds to the\n\
+appropriate line end character for the system (carriage-return linefeed\n\
+on Windows, carriage-return on Macintosh).  The default if no mode is\n\
+specified is binary mode.\n\
+\n\
+Additionally, you may append a \"z\" to the mode string to open a\n\
+gzipped file for reading or writing.  For this to be successful, you\n\
+must also open the file in binary mode.\n\
+\n\
+The parameter @var{arch} is a string specifying the default data format\n\
+for the file.  Valid values for @var{arch} are:\n\
+\n\
+ at table @asis\n\
+ at samp{native}\n\
+The format of the current machine (this is the default).\n\
+\n\
+ at samp{ieee-be}\n\
+IEEE big endian format.\n\
+\n\
+ at samp{ieee-le}\n\
+IEEE little endian format.\n\
+\n\
+ at samp{vaxd}\n\
+VAX D floating format.\n\
+\n\
+ at samp{vaxg}\n\
+VAX G floating format.\n\
+\n\
+ at samp{cray}\n\
+Cray floating format.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+however, conversions are currently only supported for @samp{native}\n\
+ at samp{ieee-be}, and @samp{ieee-le} formats.\n\
+ at seealso{fclose, fgets, fputs, fread, fseek, ferror, fprintf, fscanf, ftell, fwrite}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(0) = -1.0;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	{
+	  // If there is only one argument and it is a string but it
+	  // is not the string "all", we assume it is a file to open
+	  // with MODE = "r".  To open a file called "all", you have
+	  // to supply more than one argument.
+
+	  if (args(0).string_value () == "all")
+	    return octave_stream_list::open_file_numbers ();
+	}
+      else
+	{
+	  string_vector tmp = octave_stream_list::get_info (args(0));
+
+	  if (! error_state)
+	    {
+	      retval(2) = tmp(2);
+	      retval(1) = tmp(1);
+	      retval(0) = tmp(0);
+	    }
+
+	  return retval;
+	}
+    }
+
+  if (nargin > 0 && nargin < 4)
+    {
+      octave_value mode = (nargin == 2 || nargin == 3)
+	? args(1) : octave_value ("r");
+
+      octave_value arch = (nargin == 3)
+	? args(2) : octave_value ("native");
+
+      int fid = -1;
+
+      octave_stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
+
+      if (os && ! error_state)
+	{
+	  retval(1) = "";
+	  retval(0) = octave_stream_list::insert (os);
+	}
+      else
+	{
+	  int error_number = 0;
+
+	  retval(1) = os.error (false, error_number);
+	  retval(0) = -1.0;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (freport, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} freport ()\n\
+Print a list of which files have been opened, and whether they are open\n\
+for reading, writing, or both.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+freport ()\n\
+\n\
+     @print{}  number  mode  name\n\
+     @print{} \n\
+     @print{}       0     r  stdin\n\
+     @print{}       1     w  stdout\n\
+     @print{}       2     w  stderr\n\
+     @print{}       3     r  myfile\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    warning ("freport: ignoring extra arguments");
+
+  octave_stdout << octave_stream_list::list_open_files ();
+
+  return retval;
+}
+
+DEFUN (frewind, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} frewind (@var{fid})\n\
+Move the file pointer to the beginning of the file @var{fid}, returning\n\
+0 for success, and -1 if an error was encountered.  It is equivalent to\n\
+ at code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int result = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), "frewind");
+
+      if (! error_state)
+	result = os.rewind ();
+    }
+  else
+    print_usage ();
+
+  if (nargout > 0)
+    retval = result;
+
+  return retval;
+}
+
+DEFUN (fseek, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})\n\
+Set the file pointer to any location within the file @var{fid}.\n\
+\n\
+The pointer is positioned @var{offset} characters from the @var{origin},\n\
+which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
+position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\
+file) or strings \"cof\", \"bof\" or \"eof\".  If @var{origin} is omitted,\n\
+ at w{@code{SEEK_SET}} is assumed.  The offset must be zero, or a value returned\n\
+by @code{ftell} (in which case @var{origin} must be @w{@code{SEEK_SET}}).\n\
+\n\
+Return 0 on success and -1 on error.\n\
+ at seealso{ftell, fopen, fclose}\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 || nargin == 3)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), "fseek");
+
+      if (! error_state)
+	{
+	  octave_value origin_arg = (nargin == 3)
+	    ? args(2) : octave_value (-1.0);
+
+	  retval = os.seek (args(1), origin_arg);
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (ftell, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ftell (@var{fid})\n\
+Return the position of the file pointer as the number of characters\n\
+from the beginning of the file @var{fid}.\n\
+ at seealso{fseek, fopen, fclose}\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), "ftell");
+
+      if (! error_state)
+	retval = os.tell ();
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fprintf, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
+This function is just like @code{printf}, except that the output is\n\
+written to the stream @var{fid} instead of @code{stdout}.\n\
+If @var{fid} is omitted, the output is written to @code{stdout}.\n\
+ at seealso{printf, sprintf, fread, fscanf, fopen, fclose}\n\
+ at end deftypefn")
+{
+  static std::string who = "fprintf";
+
+  octave_value retval;
+
+  int result = -1;
+
+  int nargin = args.length ();
+
+  if (nargin > 1 || (nargin > 0 && args(0).is_string ()))
+    {
+      octave_stream os;
+      int fmt_n = 0;
+
+      if (args(0).is_string ()) 
+	{
+	  os = octave_stream_list::lookup (1, who);
+	}
+      else
+	{
+	  fmt_n = 1;
+	  os = octave_stream_list::lookup (args(0), who);
+	}
+
+      if (! error_state)
+	{
+	  if (args(fmt_n).is_string ())
+	    {
+	      octave_value_list tmp_args;
+
+	      if (nargin > 1 + fmt_n)
+		{
+		  tmp_args.resize (nargin-fmt_n-1, octave_value ());
+
+		  for (int i = fmt_n + 1; i < nargin; i++)
+		    tmp_args(i-fmt_n-1) = args(i);
+		}
+
+	      result = os.printf (args(fmt_n), tmp_args, who);
+	    }
+	  else
+	    ::error ("%s: format must be a string", who.c_str ());
+	}
+    }
+  else
+    print_usage ();
+
+  if (nargout > 0)
+    retval = result;
+
+  return retval;
+}
+
+DEFUN (printf, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} printf (@var{template}, @dots{})\n\
+Print optional arguments under the control of the template string\n\
+ at var{template} to the stream @code{stdout} and return the number of\n\
+characters printed.\n\
+ at ifclear OCTAVE_MANUAL\n\
+\n\
+See the Formatted Output section of the GNU Octave manual for a\n\
+complete description of the syntax of the template string.\n\
+ at end ifclear\n\
+ at seealso{fprintf, sprintf, scanf}\n\
+ at end deftypefn")
+{
+  static std::string who = "printf";
+
+  octave_value retval;
+
+  int result = -1;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      if (args(0).is_string ())
+	{
+	  octave_value_list tmp_args;
+
+	  if (nargin > 1)
+	    {
+	      tmp_args.resize (nargin-1, octave_value ());
+
+	      for (int i = 1; i < nargin; i++)
+		tmp_args(i-1) = args(i);
+	    }
+
+	  result = stdout_stream.printf (args(0), tmp_args, who);
+	}
+      else
+	::error ("%s: format must be a string", who.c_str ());
+    }
+  else
+    print_usage ();
+
+  if (nargout > 0)
+    retval = result;
+
+  return retval;
+}
+
+DEFUN (fputs, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
+Write a string to a file with no formatting.\n\
+\n\
+Return a non-negative number on success and EOF on error.\n\
+ at seealso{scanf, sscanf, fread, fprintf, fgets, fscanf}\n\
+ at end deftypefn")
+{
+  static std::string who = "fputs";
+
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), who);
+
+      if (! error_state)
+	retval = os.puts (args(1), who);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (puts, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} puts (@var{string})\n\
+Write a string to the standard output with no formatting.\n\
+\n\
+Return a non-negative number on success and EOF on error.\n\
+ at end deftypefn")
+{
+  static std::string who = "puts";
+
+  octave_value retval = -1;
+
+  if (args.length () == 1)
+    retval = stdout_stream.puts (args(0), who);
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (sprintf, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})\n\
+This is like @code{printf}, except that the output is returned as a\n\
+string.  Unlike the C library function, which requires you to provide a\n\
+suitably sized string as an argument, Octave's @code{sprintf} function\n\
+returns the string, automatically sized to hold all of the items\n\
+converted.\n\
+ at seealso{printf, fprintf, sscanf}\n\
+ at end deftypefn")
+{
+  static std::string who = "sprintf";
+
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      retval(2) = -1.0;
+      retval(1) = "unknown error";
+      retval(0) = "";
+
+      octave_ostrstream *ostr = new octave_ostrstream ();
+
+      octave_stream os (ostr);
+
+      if (os.is_valid ())
+	{
+	  octave_value fmt_arg = args(0);
+
+	  if (fmt_arg.is_string ())
+	    {
+	      octave_value_list tmp_args;
+
+	      if (nargin > 1)
+		{
+		  tmp_args.resize (nargin-1, octave_value ());
+
+		  for (int i = 1; i < nargin; i++)
+		    tmp_args(i-1) = args(i);
+		}
+
+	      retval(2) = os.printf (fmt_arg, tmp_args, who);
+	      retval(1) = os.error ();
+	      retval(0) = octave_value (ostr->str (),
+					fmt_arg.is_sq_string () ? '\'' : '"');
+	    }
+	  else
+	    ::error ("%s: format must be a string", who.c_str ());
+	}
+      else
+	::error ("%s: unable to create output buffer", who.c_str ());
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fscanf, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} fscanf (@var{fid}, @var{template}, \"C\")\n\
+In the first form, read from @var{fid} according to @var{template},\n\
+returning the result in the matrix @var{val}.\n\
+\n\
+The optional argument @var{size} specifies the amount of data to read\n\
+and may be one of\n\
+\n\
+ at table @code\n\
+ at item Inf\n\
+Read as much as possible, returning a column vector.\n\
+\n\
+ at item @var{nr}\n\
+Read up to @var{nr} elements, returning a column vector.\n\
+\n\
+ at item [@var{nr}, Inf]\n\
+Read as much as possible, returning a matrix with @var{nr} rows.  If the\n\
+number of elements read is not an exact multiple of @var{nr}, the last\n\
+column is padded with zeros.\n\
+\n\
+ at item [@var{nr}, @var{nc}]\n\
+Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
+ at var{nr} rows.  If the number of elements read is not an exact multiple\n\
+of @var{nr}, the last column is padded with zeros.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
+\n\
+A string is returned if @var{template} specifies only character\n\
+conversions.\n\
+\n\
+The number of items successfully read is returned in @var{count}.\n\
+\n\
+In the second form, read from @var{fid} according to @var{template},\n\
+with each conversion specifier in @var{template} corresponding to a\n\
+single scalar return value.  This form is more `C-like', and also\n\
+compatible with previous versions of Octave.  The number of successful\n\
+conversions is returned in @var{count}\n\
+ at ifclear OCTAVE_MANUAL\n\
+\n\
+See the Formatted Input section of the GNU Octave manual for a\n\
+complete description of the syntax of the template string.\n\
+ at end ifclear\n\
+ at seealso{scanf, sscanf, fread, fprintf, fgets, fputs}\n\
+ at end deftypefn")
+{
+  static std::string who = "fscanf";
+
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 3 && args(2).is_string ())
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), who);
+
+      if (! error_state)
+	{
+	  if (args(1).is_string ())
+	    retval = os.oscanf (args(1), who);
+	  else
+	    ::error ("%s: format must be a string", who.c_str ());
+	}
+    }
+  else
+    {
+      retval (1) = 0.0;
+      retval (0) = Matrix ();
+
+      if (nargin == 2 || nargin == 3)
+	{
+	  octave_stream os = octave_stream_list::lookup (args(0), who);
+
+	  if (! error_state)
+	    {
+	      if (args(1).is_string ())
+		{
+		  octave_idx_type count = 0;
+
+		  Array<double> size = (nargin == 3)
+		    ? args(2).vector_value ()
+		    : Array<double> (1, lo_ieee_inf_value ());
+
+		  if (! error_state)
+		    {
+		      octave_value tmp = os.scanf (args(1), size, count, who);
+
+		      if (! error_state)
+			{
+			  retval(1) = count;
+			  retval(0) = tmp;
+			}
+		    }
+		}
+	      else
+		::error ("%s: format must be a string", who.c_str ());
+	    }
+	}
+      else
+	print_usage ();
+    }
+
+  return retval;
+}
+
+DEFUN (sscanf, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{size})\n\
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} sscanf (@var{string}, @var{template}, \"C\")\n\
+This is like @code{fscanf}, except that the characters are taken from the\n\
+string @var{string} instead of from a stream.  Reaching the end of the\n\
+string is treated as an end-of-file condition.\n\
+ at seealso{fscanf, scanf, sprintf}\n\
+ at end deftypefn")
+{
+  static std::string who = "sscanf";
+
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 3 && args(2).is_string ())
+    {
+      if (args(0).is_string ())
+	{
+	  std::string data = args(0).string_value ();
+
+	  octave_stream os = octave_istrstream::create (data);
+
+	  if (os.is_valid ())
+	    {
+	      if (args(1).is_string ())
+		retval = os.oscanf (args(1), who);
+	      else
+		::error ("%s: format must be a string", who.c_str ());
+	    }
+	  else
+	    ::error ("%s: unable to create temporary input buffer",
+		     who.c_str ());
+	}
+      else
+	::error ("%s: first argument must be a string", who.c_str ());
+    }
+  else
+    {
+      if (nargin == 2 || nargin == 3)
+	{
+	  retval(3) = -1.0;
+	  retval(2) = "unknown error";
+	  retval(1) = 0.0;
+	  retval(0) = Matrix ();
+
+	  if (args(0).is_string ())
+	    {
+	      std::string data = args(0).string_value ();
+
+	      octave_stream os = octave_istrstream::create (data);
+
+	      if (os.is_valid ())
+		{
+		  if (args(1).is_string ())
+		    {
+		      octave_idx_type count = 0;
+
+		      Array<double> size = (nargin == 3)
+			? args(2).vector_value ()
+			: Array<double> (1, lo_ieee_inf_value ());
+
+		      octave_value tmp = os.scanf (args(1), size, count, who);
+
+		      if (! error_state)
+			{
+			  // FIXME -- is this the right thing to do?
+			  // Extract error message first, because getting
+			  // position will clear it.
+			  std::string errmsg = os.error ();
+
+			  retval(3) = os.tell () + 1;
+			  retval(2) = errmsg;
+			  retval(1) = count;
+			  retval(0) = tmp;
+			}
+		    }
+		  else
+		    ::error ("%s: format must be a string", who.c_str ());
+		}
+	      else
+		::error ("%s: unable to create temporary input buffer",
+			 who.c_str  ());
+	    }
+	  else
+	    ::error ("%s: first argument must be a string", who.c_str ());
+	}
+      else
+	print_usage ();
+    }
+
+  return retval;
+}
+
+DEFUN (scanf, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} scanf (@var{template}, @var{size})\n\
+ at deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] =} scanf (@var{template}, \"C\")\n\
+This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\
+\n\
+It is currently not useful to call @code{scanf} in interactive\n\
+programs.\n\
+ at seealso{fscanf, sscanf, printf}\n\
+ at end deftypefn")
+{
+  int nargin = args.length ();
+
+  octave_value_list tmp_args (nargin+1, octave_value ());
+
+  tmp_args (0) = 0.0;
+  for (int i = 0; i < nargin; i++)
+    tmp_args (i+1) = args (i);
+
+  return Ffscanf (tmp_args, nargout);
+}
+
+static octave_value
+do_fread (octave_stream& os, const octave_value& size_arg,
+	  const octave_value& prec_arg, const octave_value& skip_arg,
+	  const octave_value& arch_arg, octave_idx_type& count)
+{
+  octave_value retval;
+
+  count = -1;
+
+  Array<double> size = size_arg.vector_value ();
+
+  if (! error_state)
+    {
+      std::string prec = prec_arg.string_value ();
+
+      if (! error_state)
+	{
+	  int block_size = 1;
+	  oct_data_conv::data_type input_type;
+	  oct_data_conv::data_type output_type;
+
+	  oct_data_conv::string_to_data_type (prec, block_size,
+					      input_type, output_type);
+
+	  if (! error_state)
+	    {
+	      int skip = skip_arg.int_value (true);
+
+	      if (! error_state)
+		{
+		  std::string arch = arch_arg.string_value ();
+
+		  if (! error_state)
+		    {
+		      oct_mach_info::float_format flt_fmt
+			= oct_mach_info::string_to_float_format (arch);
+
+		      if (! error_state)
+			retval = os.read (size, block_size, input_type,
+					  output_type, skip, flt_fmt, count);
+		    }
+		  else
+		    ::error ("fread: architecture type must be a string");
+		}
+	      else
+		::error ("fread: skip must be an integer");
+	    }
+	  else
+	    ::error ("fread: invalid data type specified");
+	}
+      else
+	::error ("fread: precision must be a string");
+    }
+  else
+    ::error ("fread: invalid size specified");
+
+  return retval;
+}
+
+DEFUN (fread, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
+Read binary data of type @var{precision} from the specified file ID\n\
+ at var{fid}.\n\
+\n\
+The optional argument @var{size} specifies the amount of data to read\n\
+and may be one of\n\
+\n\
+ at table @code\n\
+ at item Inf\n\
+Read as much as possible, returning a column vector.\n\
+\n\
+ at item @var{nr}\n\
+Read up to @var{nr} elements, returning a column vector.\n\
+\n\
+ at item [@var{nr}, Inf]\n\
+Read as much as possible, returning a matrix with @var{nr} rows.  If the\n\
+number of elements read is not an exact multiple of @var{nr}, the last\n\
+column is padded with zeros.\n\
+\n\
+ at item [@var{nr}, @var{nc}]\n\
+Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
+ at var{nr} rows.  If the number of elements read is not an exact multiple\n\
+of @var{nr}, the last column is padded with zeros.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
+\n\
+The optional argument @var{precision} is a string specifying the type of\n\
+data to read and may be one of\n\
+\n\
+ at table @code\n\
+ at item \"schar\"\n\
+ at itemx \"signed char\"\n\
+Signed character.\n\
+\n\
+ at item \"uchar\"\n\
+ at itemx \"unsigned char\"\n\
+Unsigned character.\n\
+\n\
+ at item \"int8\"\n\
+ at itemx \"integer*1\"\n\
+\n\
+8-bit signed integer.\n\
+\n\
+ at item \"int16\"\n\
+ at itemx \"integer*2\"\n\
+16-bit signed integer.\n\
+\n\
+ at item \"int32\"\n\
+ at itemx \"integer*4\"\n\
+32-bit signed integer.\n\
+\n\
+ at item \"int64\"\n\
+ at itemx \"integer*8\"\n\
+64-bit signed integer.\n\
+\n\
+ at item \"uint8\"\n\
+8-bit unsigned integer.\n\
+\n\
+ at item \"uint16\"\n\
+16-bit unsigned integer.\n\
+\n\
+ at item \"uint32\"\n\
+32-bit unsigned integer.\n\
+\n\
+ at item \"uint64\"\n\
+64-bit unsigned integer.\n\
+\n\
+ at item \"single\"\n\
+ at itemx \"float32\"\n\
+ at itemx \"real*4\"\n\
+32-bit floating point number.\n\
+\n\
+ at item \"double\"\n\
+ at itemx \"float64\"\n\
+ at itemx \"real*8\"\n\
+64-bit floating point number.\n\
+\n\
+ at item \"char\"\n\
+ at itemx \"char*1\"\n\
+Single character.\n\
+\n\
+ at item \"short\"\n\
+Short integer (size is platform dependent).\n\
+\n\
+ at item \"int\"\n\
+Integer (size is platform dependent).\n\
+\n\
+ at item \"long\"\n\
+Long integer (size is platform dependent).\n\
+\n\
+ at item \"ushort\"\n\
+ at itemx \"unsigned short\"\n\
+Unsigned short integer (size is platform dependent).\n\
+\n\
+ at item \"uint\"\n\
+ at itemx \"unsigned int\"\n\
+Unsigned integer (size is platform dependent).\n\
+\n\
+ at item \"ulong\"\n\
+ at itemx \"unsigned long\"\n\
+Unsigned long integer (size is platform dependent).\n\
+\n\
+ at item \"float\"\n\
+Single precision floating point number (size is platform dependent).\n\
+ at end table\n\
+\n\
+ at noindent\n\
+The default precision is @code{\"uchar\"}.\n\
+\n\
+The @var{precision} argument may also specify an optional repeat\n\
+count.  For example, @samp{32*single} causes @code{fread} to read\n\
+a block of 32 single precision floating point numbers.  Reading in\n\
+blocks is useful in combination with the @var{skip} argument.\n\
+\n\
+The @var{precision} argument may also specify a type conversion.\n\
+For example, @samp{int16=>int32} causes @code{fread} to read 16-bit\n\
+integer values and return an array of 32-bit integer values.  By\n\
+default, @code{fread} returns a double precision array.  The special\n\
+form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.\n\
+\n\
+The conversion and repeat counts may be combined.  For example, the\n\
+specification @samp{32*single=>single} causes @code{fread} to read\n\
+blocks of single precision floating point values and return an array\n\
+of single precision values instead of the default array of double\n\
+precision values.\n\
+\n\
+The optional argument @var{skip} specifies the number of bytes to skip\n\
+after each element (or block of elements) is read.  If it is not\n\
+specified, a value of 0 is assumed.  If the final block read is not\n\
+complete, the final skip is omitted.  For example,\n\
+\n\
+ at example\n\
+fread (f, 10, \"3*single=>single\", 8)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will omit the final 8-byte skip because the last read will not be\n\
+a complete block of 3 values.\n\
+\n\
+The optional argument @var{arch} is a string specifying the data format\n\
+for the file.  Valid values are\n\
+\n\
+ at table @code\n\
+ at item \"native\"\n\
+The format of the current machine.\n\
+\n\
+ at item \"ieee-be\"\n\
+IEEE big endian.\n\
+\n\
+ at item \"ieee-le\"\n\
+IEEE little endian.\n\
+\n\
+ at item \"vaxd\"\n\
+VAX D floating format.\n\
+\n\
+ at item \"vaxg\"\n\
+VAX G floating format.\n\
+\n\
+ at item \"cray\"\n\
+Cray floating format.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+Conversions are currently only supported for @code{\"ieee-be\"} and\n\
+ at code{\"ieee-le\"} formats.\n\
+\n\
+The data read from the file is returned in @var{val}, and the number of\n\
+values read is returned in @code{count}\n\
+ at seealso{fwrite, fopen, fclose}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0 && nargin < 6)
+    {
+      retval(1) = -1.0;
+      retval(0) = Matrix ();
+
+      octave_stream os = octave_stream_list::lookup (args(0), "fread");
+
+      if (! error_state)
+	{
+	  octave_value size = lo_ieee_inf_value ();
+	  octave_value prec = "uchar";
+	  octave_value skip = 0;
+	  octave_value arch = "unknown";
+
+	  int idx = 1;
+
+	  if (nargin > idx && ! args(idx).is_string ())
+	    size = args(idx++);
+
+	  if (nargin > idx)
+	    prec = args(idx++);
+
+	  if (nargin > idx)
+	    skip = args(idx++);
+
+	  if (nargin > idx)
+	    arch = args(idx++);
+	  else if (skip.is_string ())
+	    {
+	      arch = skip;
+	      skip = 0;
+	    }
+
+	  octave_idx_type count = -1;
+
+	  octave_value tmp = do_fread (os, size, prec, skip, arch, count);
+
+	  retval(1) = count;
+	  retval(0) = tmp;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static int
+do_fwrite (octave_stream& os, const octave_value& data,
+	   const octave_value& prec_arg, const octave_value& skip_arg,
+	   const octave_value& arch_arg)
+{
+  int retval = -1;
+
+  std::string prec = prec_arg.string_value ();
+
+  if (! error_state)
+    {
+      int block_size = 1;
+      oct_data_conv::data_type output_type;
+
+      oct_data_conv::string_to_data_type (prec, block_size, output_type);
+
+      if (! error_state)
+	{
+	  int skip = skip_arg.int_value (true);
+
+	  if (! error_state)
+	    {
+	      std::string arch = arch_arg.string_value ();
+
+	      if (! error_state)
+		{
+		  oct_mach_info::float_format flt_fmt
+		    = oct_mach_info::string_to_float_format (arch);
+
+		  if (! error_state)
+		    retval = os.write (data, block_size, output_type,
+				       skip, flt_fmt);
+		}
+	      else
+		::error ("fwrite: architecture type must be a string");
+	    }
+	  else
+	    ::error ("fwrite: skip must be an integer");
+	}
+      else
+	::error ("fwrite: invalid precision specified");
+    }
+  else
+    ::error ("fwrite: precision must be a string");
+
+  return retval;
+}
+
+DEFUN (fwrite, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
+Write data in binary form of type @var{precision} to the specified file\n\
+ID @var{fid}, returning the number of values successfully written to the\n\
+file.\n\
+\n\
+The argument @var{data} is a matrix of values that are to be written to\n\
+the file.  The values are extracted in column-major order.\n\
+\n\
+The remaining arguments @var{precision}, @var{skip}, and @var{arch} are\n\
+optional, and are interpreted as described for @code{fread}.\n\
+\n\
+The behavior of @code{fwrite} is undefined if the values in @var{data}\n\
+are too large to fit in the specified precision.\n\
+ at seealso{fread, fopen, fclose}\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin > 1 && nargin < 6)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), "fwrite");
+
+      if (! error_state)
+	{
+	  octave_value prec = "uchar";
+	  octave_value skip = 0;
+	  octave_value arch = "unknown";
+
+	  int idx = 1;
+
+	  octave_value data = args(idx++);
+
+	  if (nargin > idx)
+	    prec = args(idx++);
+
+	  if (nargin > idx)
+	    skip = args(idx++);
+
+	  if (nargin > idx)
+	    arch = args(idx++);
+	  else if (skip.is_string ())
+	    {
+	      arch = skip;
+	      skip = 0;
+	    }
+
+	  double status = do_fwrite (os, data, prec, skip, arch);
+
+	  retval = status;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("feof", Ffeof, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} feof (@var{fid})\n\
+Return 1 if an end-of-file condition has been encountered for a given\n\
+file and 0 otherwise.  Note that it will only return 1 if the end of the\n\
+file has already been encountered, not if the next read operation will\n\
+result in an end-of-file condition.\n\
+ at seealso{fread, fopen, fclose}\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), "feof");
+
+      if (! error_state)
+	retval = os.eof () ? 1.0 : 0.0;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("ferror", Fferror, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ferror (@var{fid})\n\
+Return 1 if an error condition has been encountered for a given file\n\
+and 0 otherwise.  Note that it will only return 1 if an error has\n\
+already been encountered, not if the next operation will result in an\n\
+error condition.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      octave_stream os = octave_stream_list::lookup (args(0), "ferror");
+
+      if (! error_state)
+	{
+	  bool clear = false;
+
+	  if (nargin == 2)
+	    {
+	      std::string opt = args(1).string_value ();
+
+	      if (! error_state)
+		clear = (opt == "clear");
+	      else
+		return retval;
+	    }
+
+	  int error_number = 0;
+
+	  std::string error_message = os.error (clear, error_number);
+
+	  retval(1) = error_number;
+	  retval(0) = error_message;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (popen, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})\n\
+Start a process and create a pipe.  The name of the command to run is\n\
+given by @var{command}.  The file identifier corresponding to the input\n\
+or output stream of the process is returned in @var{fid}.  The argument\n\
+ at var{mode} may be\n\
+\n\
+ at table @code\n\
+ at item \"r\"\n\
+The pipe will be connected to the standard output of the process, and\n\
+open for reading.\n\
+\n\
+ at item \"w\"\n\
+The pipe will be connected to the standard input of the process, and\n\
+open for writing.\n\
+ at end table\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+fid = popen (\"ls -ltr / | tail -3\", \"r\");\n\
+while (ischar (s = fgets (fid)))\n\
+  fputs (stdout, s);\n\
+endwhile\n\
+     @print{} drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc\n\
+     @print{} drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib\n\
+     @print{} drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string mode = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (mode == "r")
+		{
+		  octave_stream ips = octave_iprocstream::create (name);
+
+		  retval = octave_stream_list::insert (ips);
+		}
+	      else if (mode == "w")
+		{
+		  octave_stream ops = octave_oprocstream::create (name);
+
+		  retval = octave_stream_list::insert (ops);
+		}
+	      else
+		::error ("popen: invalid mode specified");
+	    }
+	  else
+	    ::error ("popen: mode must be a string");
+	}
+      else
+	::error ("popen: name must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (pclose, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} pclose (@var{fid})\n\
+Close a file identifier that was opened by @code{popen}.  You may also\n\
+use @code{fclose} for the same purpose.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    retval = octave_stream_list::remove (args(0), "pclose");
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (tmpnam, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
+Return a unique temporary file name as a string.\n\
+\n\
+If @var{prefix} is omitted, a value of @code{\"oct-\"} is used.\n\
+If @var{dir} is also omitted, the default directory for temporary files\n\
+is used.  If @var{dir} is provided, it must exist, otherwise the default\n\
+directory for temporary files is used.  Since the named file is not\n\
+opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
+that it will not be available by the time your program attempts to open it.\n\
+ at seealso{tmpfile, mkstemp, P_tmpdir}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int len = args.length ();
+
+  if (len < 3)
+    {
+      std::string dir = len > 0 ? args(0).string_value () : std::string ();
+
+      if (! error_state)
+	{
+	  std::string pfx
+	    = len > 1 ? args(1).string_value () : std::string ("oct-");
+
+	  if (! error_state)
+	    retval = file_ops::tempnam (dir, pfx);
+	  else
+	    ::error ("expecting second argument to be a string");
+	}
+      else
+	::error ("expecting first argument to be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFALIAS (octave_tmp_file_name, tmpnam);
+
+DEFUN (tmpfile, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
+Return the file ID corresponding to a new temporary file with a unique\n\
+name.  The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\
+The file will be deleted automatically when it is closed or when Octave\n\
+exits.\n\
+\n\
+If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
+string.  Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at seealso{tmpnam, mkstemp, P_tmpdir}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      FILE *fid = tmpfile ();
+
+      if (fid)
+	{
+	  std::string nm;
+
+	  std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
+
+	  octave_stream s = octave_stdiostream::create (nm, fid, md);
+
+	  if (s)
+	    retval(0) = octave_stream_list::insert (s);
+	  else
+	    error ("tmpfile: failed to create octave_stdiostream object");
+
+	}
+      else
+	{
+	  using namespace std;
+	  retval(1) = ::strerror (errno);
+	  retval(0) = -1;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#if defined (HAVE_MKSTEMPS)
+// Prototype for mkstemps in libiberty
+extern "C" int mkstemps (char *pattern, int suffix_len);
+#endif
+
+#if ! defined (HAVE_MKSTEMP) && ! defined (HAVE_MKSTEMPS) && defined (_MSC_VER)
+# if defined (HAVE_FCNTL_H)
+#  include <fcntl.h>
+# endif
+# if defined (HAVE_SYS_STAT_H)
+#  include <sys/stat.h>
+# endif
+int mkstemp (char *tmpl)
+{
+  int ret=-1;
+  mktemp (tmpl);
+  ret = open (tmpl, O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED,
+	      _S_IREAD | _S_IWRITE);
+  return ret;
+}
+#define HAVE_MKSTEMP 1
+#endif
+
+DEFUN (mkstemp, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})\n\
+Return the file ID corresponding to a new temporary file with a unique\n\
+name created from @var{template}.  The last six characters of @var{template}\n\
+must be @code{XXXXXX} and these are replaced with a string that makes the\n\
+filename unique.  The file is then created with mode read/write and\n\
+permissions that are system dependent (on GNU/Linux systems, the permissions\n\
+will be 0600 for versions of glibc 2.0.7 and later).  The file is opened\n\
+with the @w{@code{O_EXCL}} flag.\n\
+\n\
+If the optional argument @var{delete} is supplied and is true,\n\
+the file will be deleted automatically when Octave exits, or when\n\
+the function @code{purge_tmp_files} is called.\n\
+\n\
+If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
+the file, and @var{msg} is an empty string.  Otherwise, @var{fid}\n\
+is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
+error message.\n\
+ at seealso{tmpfile, tmpnam, P_tmpdir}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+#if defined (HAVE_MKSTEMP) || defined (HAVE_MKSTEMPS)
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string tmpl8 = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
+	  strcpy (tmp, tmpl8.c_str ());
+
+#if defined (HAVE_MKSTEMP)
+	  int fd = mkstemp (tmp);
+#else
+	  int fd = mkstemps (tmp, 0);
+#endif
+
+	  if (fd < 0)
+	    {
+	      using namespace std;
+	      retval(2) = ::strerror (errno);
+	      retval(0) = fd;
+	    }
+	  else
+	    {
+	      const char *fopen_mode = "w+";
+
+	      FILE *fid = fdopen (fd, fopen_mode);
+
+	      if (fid)
+		{
+		  std::string nm = tmp;
+
+		  std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
+
+		  octave_stream s = octave_stdiostream::create (nm, fid, md);
+
+		  if (s)
+		    {
+		      retval(1) = nm;
+		      retval(0) = octave_stream_list::insert (s);
+
+		      if (nargin == 2 && args(1).is_true ())
+			mark_for_deletion (nm);
+		    }
+		  else
+		    error ("mkstemp: failed to create octave_stdiostream object");
+		}
+	      else
+		{
+		  using namespace std;
+		  retval(2) = ::strerror (errno);
+		  retval(0) = -1;
+		}
+	    }
+	}
+      else
+	error ("mkstemp: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+#else
+  retval(2) = "mkstemp: not supported on this sytem";
+#endif
+
+  return retval;
+}
+
+static int
+convert (int x, int ibase, int obase)
+{
+  int retval = 0;
+
+  int tmp = x % obase;
+
+  if (tmp > ibase - 1)
+    ::error ("umask: invalid digit");
+  else
+    {
+      retval = tmp;
+      int mult = ibase;
+      while ((x = (x - tmp) / obase))
+	{
+	  tmp = x % obase;
+	  if (tmp > ibase - 1)
+	    {
+	      ::error ("umask: invalid digit");
+	      break;
+	    }
+	  retval += mult * tmp;
+	  mult *= ibase;
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (umask, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} umask (@var{mask})\n\
+Set the permission mask for file creation.  The parameter @var{mask}\n\
+is an integer, interpreted as an octal number.  If successful,\n\
+returns the previous value of the mask (as an integer to be\n\
+interpreted as an octal number); otherwise an error message is printed.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int status = 0;
+
+  if (args.length () == 1)
+    {
+      int mask = args(0).int_value (true);
+
+      if (! error_state)
+	{
+	  if (mask < 0)
+	    {
+	      status = -1;
+	      ::error ("umask: MASK must be a positive integer value");
+	    }
+	  else
+	    {
+	      int oct_mask = convert (mask, 8, 10);
+
+	      if (! error_state)
+		status = convert (file_ops::umask (oct_mask), 10, 8);
+	    }
+	}
+      else
+	{
+	  status = -1;
+	  ::error ("umask: expecting integer argument");
+	}
+    }
+  else
+    print_usage ();
+
+  if (status >= 0)
+    retval(0) = status;
+
+  return retval;
+}
+
+static octave_value
+const_value (const char *, const octave_value_list& args, int val)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = val;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#if ! defined (P_tmpdir)
+#define P_tmpdir "/tmp"
+#endif
+
+DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} P_tmpdir ()\n\
+Return the default name of the directory for temporary files on\n\
+this system.  The name of this directory is system dependent.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = P_tmpdir;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// NOTE: the values of SEEK_SET, SEEK_CUR, and SEEK_END have to be
+// this way for Matlab compatibility.
+
+DEFUNX ("SEEK_SET", FSEEK_SET, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} SEEK_SET ()\n\
+ at deftypefnx {Built-in Function} {} SEEK_CUR ()\n\
+ at deftypefnx {Built-in Function} {} SEEK_END ()\n\
+Return the value required to request that @code{fseek} perform\n\
+one of the following actions:\n\
+ at table @code\n\
+ at item SEEK_SET\n\
+Position file relative to the beginning.\n\
+\n\
+ at item SEEK_CUR\n\
+Position file relative to the current position.\n\
+\n\
+ at item SEEK_END\n\
+Position file relative to the end.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  return const_value ("SEEK_SET", args, -1);
+}
+
+DEFUNX ("SEEK_CUR", FSEEK_CUR, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} SEEK_CUR ()\n\
+See SEEK_SET.\n\
+ at end deftypefn")
+{
+  return const_value ("SEEK_CUR", args, 0);
+}
+
+DEFUNX ("SEEK_END", FSEEK_END, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} SEEK_END ()\n\
+See SEEK_SET.\n\
+ at end deftypefn")
+{
+  return const_value ("SEEK_END", args, 1);
+}
+
+static octave_value
+const_value (const char *, const octave_value_list& args,
+	     const octave_value& val)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = val;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("stdin", Fstdin, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} stdin ()\n\
+Return the numeric value corresponding to the standard input stream.\n\
+When Octave is used interactively, this is filtered through the command\n\
+line editing functions.\n\
+ at seealso{stdout, stderr}\n\
+ at end deftypefn")
+{
+  return const_value ("stdin", args, stdin_file);
+}
+
+DEFUNX ("stdout", Fstdout, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} stdout ()\n\
+Return the numeric value corresponding to the standard output stream.\n\
+Data written to the standard output is normally filtered through the pager.\n\
+ at seealso{stdin, stderr}\n\
+ at end deftypefn")
+{
+  return const_value ("stdout", args, stdout_file);
+}
+
+DEFUNX ("stderr", Fstderr, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} stderr ()\n\
+Return the numeric value corresponding to the standard error stream.\n\
+Even if paging is turned on, the standard error is not sent to the\n\
+pager.  It is useful for error messages and prompts.\n\
+ at seealso{stdin, stdout}\n\
+ at end deftypefn")
+{
+  return const_value ("stderr", args, stderr_file);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/file-io.h b/src/file-io.h
new file mode 100644
index 0000000..cfd4496
--- /dev/null
+++ b/src/file-io.h
@@ -0,0 +1,43 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Written by John C. Campbell <jcc at bevo.che.wisc.edu>
+
+#if !defined (octave_file_io_h)
+#define octave_file_io_h 1
+
+extern OCTINTERP_API void initialize_file_io (void);
+
+extern OCTINTERP_API void close_files (void);
+
+extern OCTINTERP_API void mark_for_deletion (const std::string&);
+
+extern OCTINTERP_API void cleanup_tmp_files (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/genprops.awk b/src/genprops.awk
new file mode 100644
index 0000000..8eb042b
--- /dev/null
+++ b/src/genprops.awk
@@ -0,0 +1,760 @@
+## Copyright (C) 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+## 
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+## 
+## Octave is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+##
+## This script is used to generate the graphics.h file from graphics.h.in.
+##
+## Lines between the BEGIN_PROPERTIES and END_PROPERTIES markers have
+## one of the following formats:
+##
+##   TYPE NAME
+##   TYPE NAME QUALIFIERS
+##   mutable TYPE NAME
+##   mutable TYPE NAME QUALIFIERS
+##
+## For each property, we generate a declaration for the property.
+##
+## If QUALIFIERS is omitted, we generate the following functions directly
+## in the class declaration:
+##
+##   TYPE
+##   get_NAME (void) const
+##   {
+##     return NAME;
+##   }
+##
+##   void
+##   set_NAME (const TYPE& val)
+##   {
+##     if (! error_state)
+##       NAME = val;
+##   }
+##
+##   void
+##   set_NAME (const octave_value& val)
+##   {
+##     set_NAME (TYPE (val));
+##   }
+##
+## If present, the QUALIFIERS string may include any of the characters
+## g, G, m, s, S, o, O, h, which have the following meanings:
+##
+##   g:  There is a custom inline definition for the get function,
+##       so we don't emit one.
+##
+##   G:  There is a custom extern definition for the get function,
+##       so we emit only the declaration.
+##
+##   s:  There is a custom inline definition for the type-specific set
+##       function, so we don't emit one.
+##
+##   S:  There is a custom extern definition for the type-specific set
+##       function, so we emit only the declaration.
+##
+##   o:  There is a custom inline definition for the octave_value version
+##       of the set function, so we don't emit one.
+##
+##   O:  There is a custom extern definition for the octave_value version
+##       of the set function, so we emit only the declaration.
+##
+##   a:  The octave_value version of the set function will use assignment:
+##
+##         void
+##         set_NAME (const octave_value& val)
+##         {
+##           TYPE tmp (NAME);
+##           tmp = val;
+##           set_NAME (tmp);
+##         }
+##
+##       This is useful for things like the radio_value classes which
+##       use an overloaded assignment operator of the form
+##
+##         radio_property& operator = (const octave_value& val);
+##
+##       that preserves the list of possible values, which is different
+##       from what would happen if we simply used the
+##
+##         TYPE (const octave_value&)
+##
+##       constructor, which creates a new radio_property and so cannot
+##       preserve the old list of possible values.
+##
+##   l:  Add the line
+##
+##         update_axis_limits ("NAME");
+##
+##       to the type-specific set function.
+##
+##   m:  Add the line
+##
+##         set_NAMEmode ("manual");
+##
+##       to the type-specific set function.
+##
+##   h:  Make the property hidden
+##
+##   r:  Make the property read-only. A read-only property is not
+##       settable from the global set (caseless_str, octave_value)
+##       method, but still has set_X accessor.
+##
+##   u:  The property has an inline updater method. This effectively
+##       add the line
+##
+##         update_NAME ();
+##
+##       to the type-specific set function. This line is added before
+##       any other update call (like those added by the 'l' or 'm'
+##       modifiers.
+##
+##   U:  Like 'u' modifier except that the updater is not inline.
+##       A declaration for the updater function will be emitted.
+##
+##   f:  The property does not have any factory default value.
+##
+## The 'o' and 'O' qualifiers are only useful when the the property type
+## is something other than octave_value.
+
+## simple accessor
+
+function emit_get_accessor (i, rtype, faccess)
+{
+  printf ("  %s get_%s (void) const", rtype, name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return %s.%s (); }\n", name[i], faccess);
+  else
+    printf (";\n");
+}
+
+## bool_property
+
+function emit_get_bool (i)
+{
+  printf ("  bool is_%s (void) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return %s.is_on (); }\n", name[i]);
+  else
+    printf (";\n");
+
+  emit_get_accessor(i, "std::string", "current_value");
+}
+
+## radio_property
+
+function emit_get_radio (i)
+{
+  printf ("  bool %s_is (const std::string& v) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return %s.is (v); }\n", name[i]);
+  else
+    printf (";\n");
+
+  emit_get_accessor(i, "std::string", "current_value");
+}
+
+## color_property
+
+function emit_get_color (i)
+{
+  printf ("  bool %s_is_rgb (void) const { return %s.is_rgb (); }\n", name[i], name[i]);
+
+  printf ("  bool %s_is (const std::string& v) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return %s.is (v); }\n", name[i]);
+  else
+    printf (";\n");
+  
+  printf ("  Matrix get_%s_rgb (void) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return (%s.is_rgb () ? %s.rgb () : Matrix ()); }\n", name[i], name[i]);
+  else
+    printf (";\n");
+
+  emit_get_accessor(i, "octave_value", "get");
+}
+
+## double_radio_property
+
+function emit_get_double_radio (i)
+{
+  printf ("  bool %s_is_double (void) const { return %s.is_double (); }\n", name[i], name[i]);
+
+  printf ("  bool %s_is (const std::string& v) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return %s.is (v); }\n", name[i]);
+  else
+    printf (";\n");
+  
+  printf ("  double get_%s_double (void) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { return (%s.is_double () ? %s.double_value () : 0); }\n", name[i], name[i]);
+  else
+    printf (";\n");
+
+  emit_get_accessor(i, "octave_value", "get");
+}
+
+## callback_property
+
+function emit_get_callback (i)
+{
+  printf ("  void execute_%s (const octave_value& data = octave_value ()) const", name[i]);
+  
+  if (emit_get[i] == "definition")
+    printf (" { %s.execute (data); }\n", name[i]);
+  else
+    printf (";\n");
+
+  emit_get_accessor(i, "octave_value", "get");
+}
+
+## array_property
+
+function emit_get_array (i)
+{
+  emit_get_accessor(i, "octave_value", "get");
+}
+
+## common section
+
+function emit_common_declarations ()
+{
+  printf ("public:\n");
+  printf ("  properties (const graphics_handle& mh, const graphics_handle& p);\n\n");
+  printf ("  ~properties (void) { }\n\n");
+  printf ("  void set (const caseless_str& pname, const octave_value& val);\n\n");
+  printf ("  octave_value get (bool all = false) const;\n\n");
+  printf ("  octave_value get (const caseless_str& pname) const;\n\n");
+  printf ("  property get_property (const caseless_str& pname);\n\n");
+  printf ("  std::string graphics_object_name (void) const { return go_name; }\n\n");
+  printf ("  static property_list::pval_map_type factory_defaults (void);\n\n");
+  printf ("private:\n  static std::string go_name;\n\n");
+}
+
+function emit_declarations ()
+{
+  if (class_name && ! base)
+    emit_common_declarations();
+
+  printf ("public:\n\n");
+  if (base)
+    printf ("\n  static bool has_property (const std::string& pname, const std::string& cname);\n\n");
+  else
+    printf ("\n  static bool has_property (const std::string& pname);\n\n");
+
+  if (idx > 0)
+    print (base ? "protected:\n" : "private:\n");
+
+  for (i = 1; i <= idx; i++)
+    printf ("  %s%s %s;\n", mutable[i] ? "mutable " : "", type[i], name[i]);
+
+  if (idx > 0)
+    print "\npublic:\n";
+  
+  if (idx > 0)
+  {
+    printf ("  enum\n  {");
+    for (i = 1; i <= idx; i++)
+    {
+      printf ("%s\n    %s = %d", (i == 1 ? "" : ","), toupper(name[i]), pcount);
+      pcount++;
+    }
+    printf ("\n  };\n\n");
+    pcount = (int(pcount/1000)+1)*1000;
+  }
+
+  for (i = 1; i <= idx; i++)
+  {
+    if (emit_get[i])
+    {
+      if (type[i] == "any_property")
+        emit_get_accessor(i, "octave_value", "get");
+      else if (type[i] == "handle_property")
+        emit_get_accessor(i, "graphics_handle", "handle_value");
+      else if (type[i] == "string_property")
+        emit_get_accessor(i, "std::string", "string_value");
+      else if (type[i] == "double_property")
+        emit_get_accessor(i, "double", "double_value");
+      else if (type[i] == "double_radio_property")
+        emit_get_double_radio(i);
+      else if (type[i] == "array_property" \
+	       || type[i] == "row_vector_property")
+        emit_get_array(i);
+      else if (type[i] == "bool_property")
+        emit_get_bool(i);
+      else if (type[i] == "radio_property")
+        emit_get_radio(i);
+      else if (type[i] == "color_property")
+        emit_get_color(i);
+      else if (type[i] == "callback_property")
+        emit_get_callback(i);
+      else
+      {
+        printf ("  %s get_%s (void) const", type[i], name[i]);
+
+        if (emit_get[i] == "definition")
+          printf (" { return %s; }\n", name[i]);
+        else
+          printf (";\n");
+      }
+      printf ("\n");
+    }
+  }
+
+  if (idx > 0)
+    printf ("\n");
+
+  for (i = 1; i <= idx; i++)
+  {
+    if (emit_set[i])
+    {
+      printf ("  void set_%s (const octave_value& val)", name[i], type[i]);
+
+      if (emit_set[i] == "definition")
+      {
+	if (updaters[i] || limits[i] || mode[i])
+	  has_builtin_listeners = 1;
+	else
+	  has_builtin_listeners = 0;
+
+        printf ("\n  {\n    if (! error_state)\n      {\n        if (%s.set (val, %s))\n          {\n",
+          name[i], (has_builtin_listeners ? "false" : "true"));
+        if (mode[i])
+          printf ("            set_%smode (\"manual\");\n", name[i]);
+        if (updater[i])
+          printf ("            update_%s ();\n", name[i]);
+        if (limits[i])
+          printf ("            update_axis_limits (\"%s\");\n", name[i]);
+	if (has_builtin_listeners)
+	  printf ("            %s.run_listeners (POSTSET);\n", name[i]);
+        printf ("            mark_modified ();\n");
+	printf ("          }\n");
+	if (mode[i])
+	  printf ("        else\n          set_%smode (\"manual\");\n", name[i]);
+        printf ("      }\n  }\n\n");
+      }
+      else
+        printf (";\n\n");
+    }
+
+    if (updater[i] == "extern")
+    {
+      printf ("  void update_%s (void);\n\n", name[i]);
+    }
+
+##    if (emit_ov_set[i])
+##    {
+##      printf ("  void set_%s (const octave_value& val)", name[i]);
+##
+##      if (emit_ov_set[i] == "definition")
+##        printf (" { set_%s (%s (val)); }\n\n", name[i], type[i]);
+##      else if (emit_ov_set[i] == "assignment")
+##      {
+##        printf ("\n  {\n    %s tmp (%s);\n    tmp = val;\n    set_%s (tmp);\n  };\n\n",
+##                type[i], name[i], name[i], name[i]);
+##      }
+##      else
+##        printf (";\n");
+##    }
+  }
+
+##  if (idx > 0)
+##    print "\nprivate:";
+}
+
+function emit_source ()
+{
+  if (class_name)
+  {
+    printf ("// ******** %s ********\n\n", class_name) >> filename;
+
+    ## constructor
+
+    if (base)
+      printf ("base_properties::base_properties (const std::string& ty, const graphics_handle& mh, const graphics_handle& p)\n  : ") >> filename;
+    else
+    {
+      printf ("%s::properties::properties (const graphics_handle& mh, const graphics_handle& p)\n", class_name) >> filename;
+      printf ("  : base_properties (go_name, mh, p),\n") >> filename;
+    }
+
+    for (i = 1; i <= idx; i++)
+    {
+      if (ptype[i])
+        printf ("    %s (\"%s\", mh, %s)", name[i], name[i], defval[i]) >> filename;
+      else
+        printf ("    %s (%s)", name[i], defval[i]) >> filename;
+      if (i < idx)
+        printf (",") >> filename;
+      printf ("\n") >> filename;
+    }
+
+    printf ("{\n") >> filename;
+
+    for (i = 1; i <= idx; i++)
+    {
+##    printf ("  insert_static_property (\"%s\", %s);\n", name[i], name[i]) >> filename;
+      if (ptype[i])
+      {
+        printf ("  %s.set_id (%s);\n", name[i], toupper(name[i])) >> filename;
+        if (hidden[i])
+          printf ("  %s.set_hidden (true);\n", name[i]) >> filename;
+      }
+    }
+
+    printf ("  init ();\n}\n\n") >> filename;
+
+    ## set method
+
+    if (base)
+      printf ("void\nbase_properties::set (const caseless_str& pname, const std::string& cname, const octave_value& val)\n{\n") >> filename;
+    else
+      printf ("void\n%s::properties::set (const caseless_str& pname, const octave_value& val)\n{\n",
+              class_name) >> filename;
+
+    first = 1;
+
+    for (i = 1; i <= idx; i++)
+    {
+      if (! readonly[i])
+      {
+        printf ("  %sif (pname.compare (\"%s\"))\n    set_%s (val);\n",
+                (first == 0 ? "else " : ""), name[i], name[i]) >> filename;
+        first = 0;
+      }
+    }
+
+    if (base)
+      printf ("  else\n    set_dynamic (pname, cname, val);\n}\n\n") >> filename;
+    else
+      printf ("  else\n    base_properties::set (pname, \"%s\", val);\n}\n\n", class_name) >> filename;
+
+    ## get "all" method
+
+    if (base)
+    {
+      printf ("octave_value\nbase_properties::get (bool all) const\n{\n") >> filename;
+      printf ("  Octave_map m = get_dynamic (all).map_value ();\n\n") >> filename;
+    }
+    else
+    {
+      printf ("octave_value\n%s::properties::get (bool all) const\n{\n", class_name) >> filename;
+      printf ("  Octave_map m = base_properties::get (all).map_value ();\n\n") >> filename;
+    }
+
+    for (i = 1; i <= idx; i++)
+    {
+      if (hidden[i])
+        printf ("  if (all)\n    m.assign (\"%s\", get_%s ()%s);\n", name[i], name[i],
+                (type[i] == "handle_property" || type[i] == "graphics_handle" ? ".as_octave_value ()" : "")) >> filename;
+      else
+        printf ("  m.assign (\"%s\", get_%s ()%s);\n", name[i], name[i],
+                (type[i] == "handle_property" || type[i] == "graphics_handle" ? ".as_octave_value ()" : "")) >> filename;
+    }
+
+    printf ("\n  return m;\n}\n\n") >> filename;
+    
+    ## get "one" method
+
+    if (base)
+      printf ("octave_value\nbase_properties::get (const caseless_str& pname) const\n{\n") >> filename;
+    else
+      printf ("octave_value\n%s::properties::get (const caseless_str& pname) const\n{\n",
+              class_name) >> filename;
+    printf ("  octave_value retval;\n\n") >> filename;
+
+    for (i = 1; i<= idx; i++)
+    {
+      printf ("  %sif (pname.compare (\"%s\"))\n",
+              (i > 1 ? "else " : ""), name[i]) >> filename;
+      printf ("    retval = get_%s ()%s;\n", name[i],
+              (type[i] == "handle_property" || type[i] == "graphics_handle" ? ".as_octave_value ()" : "")) >> filename;
+    }
+
+    if (base)
+      printf ("  else\n    retval = get_dynamic (pname);\n\n") >> filename;
+    else
+      printf ("  else\n    retval = base_properties::get (pname);\n\n") >> filename;
+    printf ("  return retval;\n}\n\n") >> filename;
+
+    ## get_property method
+
+    if (base)
+      printf ("property\nbase_properties::get_property (const caseless_str& pname)\n{\n") >> filename;
+    else
+      printf ("property\n%s::properties::get_property (const caseless_str& pname)\n{\n",
+              class_name) >> filename;
+
+    for (i = 1; i<= idx; i++)
+    {
+      if (ptype[i])
+      {
+        printf ("  %sif (pname.compare (\"%s\"))\n",
+                (i > 1 ? "else " : ""), name[i]) >> filename;
+        printf ("    return property (&%s, true);\n", name[i]) >> filename;
+      }
+    }
+
+    if (base)
+      printf ("  else\n    return get_property_dynamic (pname);\n") >> filename;
+    else
+      printf ("  else\n    return base_properties::get_property (pname);\n") >> filename;
+    printf ("}\n\n") >> filename;
+
+
+    ## factory defaults method
+
+    if (base)
+    {
+      printf ("property_list::pval_map_type\nbase_properties::factory_defaults (void)\n{\n") >> filename;
+      printf ("  property_list::pval_map_type m;\n\n") >> filename;
+    }
+    else
+    {
+      printf ("property_list::pval_map_type\n%s::properties::factory_defaults (void)\n{\n",
+              class_name) >> filename;
+      printf ("  property_list::pval_map_type m = base_properties::factory_defaults ();\n\n") >> filename;
+    }
+
+    for (i = 1; i <= idx; i++)
+    {
+      if (factory[i])
+      {
+        dval = defval[i];
+        if (type[i] == "radio_property" || type[i] == "color_property")
+      	{
+      	  k = index (dval, "{");
+	  dval = substr (dval, k+1);
+	  l = index (dval, "}");
+      	  if (k > 0 && l > 0)
+	    dval = "\"" substr (dval, 1, l-1) "\"";
+	  else
+	    dval = "octave_value ()";
+      	}
+
+        printf ("  m[\"%s\"] = %s%s;\n", name[i], dval,
+                (type[i] == "handle_property" || type[i] == "graphics_handle" ? ".as_octave_value ()" : "")) >> filename;
+      }
+    }
+
+    printf ("\n  return m;\n}\n\n") >> filename;
+
+    ## go_name static field
+
+    if (! base)
+      printf ("std::string %s::properties::go_name (\"%s\");\n\n",
+              class_name, object_name) >> filename;
+
+    if (base)
+      printf ("bool base_properties::has_property (const std::string& pname, const std::string& cname") >> filename;
+    else
+    printf ("bool %s::properties::has_property (const std::string& pname", class_name) >> filename;
+    printf (")\n{\n  static std::set<std::string> all_properties;\n\n  static bool initialized = false;\n\n  if (! initialized)\n    {\n") >> filename;
+    for (i = 1; i <= idx; i++)
+      printf ("      all_properties.insert (\"%s\");\n", name[i]) >> filename;
+    printf ("\n      initialized = true;\n    }\n\n") >> filename;
+    if (base)
+	printf ("  return all_properties.find (pname) != all_properties.end () || has_dynamic_property (pname, cname);\n}\n\n") >> filename;
+    else
+      printf ("  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, \"%s\");\n}\n\n", class_name) >> filename;
+  }
+}
+
+BEGIN {
+  filename = "graphics-props.cc";
+  printf ("// DO NOT EDIT!  Generated automatically by genprops.awk.\n\n");
+  printf ("// DO NOT EDIT!  Generated automatically by genprops.awk.\n\n") > filename;
+  pcount = 0;
+}
+
+/BEGIN_PROPERTIES *\(.*\)/ {
+  gather = 1;
+  idx = 0;
+  str = $0;
+  beg = index (str, "(") + 1;
+  len = index (str, ")") - beg;
+  args = substr (str, beg, len);
+  n = split (args, arg_list, ",");
+  if (n > 0)
+      class_name = arg_list[1];
+  if (n > 1)
+      object_name = arg_list[2];
+  else
+      object_name = class_name;
+  gsub (/ /, "", class_name);
+  gsub (/ /, "", object_name);
+  base = 0;
+  next;
+}
+
+/BEGIN_PROPERTIES/ {
+  gather = 1;
+  idx = 0;
+  class_name = "";
+  base = 0;
+  next;
+}
+
+/BEGIN_BASE_PROPERTIES/ {
+  gather = 1;
+  idx = 0;
+  class_name = "base";
+  base = 1;
+  next;
+}
+
+/END_PROPERTIES/ {
+  emit_declarations();
+  emit_source();
+  gather = 0;
+  next;
+}
+
+{
+  if (gather)
+  {
+    if (NF < 2 || /^[ \t]*\/\//)
+      next;
+
+    idx++;
+
+    field = 1;
+
+    if ($field == "mutable")
+    {
+      mutable[idx] = 1;
+      field++;
+    }
+    else
+      mutable[idx] = 0;
+
+    type[idx] = $(field++);
+    ptype[idx] = (type[idx] ~ /^.*_property$/);
+    name[idx] = $(field++);
+
+    limits[idx] = 0;
+    mode[idx] = 0;
+    hidden[idx] = 0;
+    readonly[idx] = 0;
+    emit_get[idx] = "definition";
+    emit_set[idx] = "definition";
+    defval[idx] = "";
+    updater[idx] = "";
+    factory[idx] = 1;
+##    if (type[idx] == "octave_value")
+##      emit_ov_set[idx] = "";
+##    else
+##      emit_ov_set[idx] = "definition";
+
+    if (NF >= field)
+    {
+      if ($field != ",")
+      {
+        quals = $(field++);
+
+        if (index (quals, "l"))
+          limits[idx] = 1;
+
+        if (index (quals, "m"))
+          mode[idx] = 1;
+
+        ## There is a custom inline definition for the get function,
+        ## so we don't emit anything.
+        if (index (quals, "g"))
+          emit_get[idx] = "";
+
+        ## There is a custom extern definition for the get function,
+        ## but we still emit the declaration.
+        if (index (quals, "G"))
+          emit_get[idx] = "declaration";
+
+        ## There is a custom inline definition for the set function,
+        ## so we don't emit anything.
+        if (index (quals, "s"))
+          emit_set[idx] = "";
+
+        ## There is a custom extern definition for the set function,
+        ## but we still emit the declaration.
+        if (index (quals, "S"))
+          emit_set[idx] = "declaration";
+        
+	## The property is hidden
+	if (index (quals, "h"))
+	  hidden[idx] = 1;
+
+	## The property is read-only
+	if (index (quals, "r"))
+	  readonly[idx] = 1;
+
+        ## There is an inline updater method that should be called
+        ## from the set method
+        if (index (quals, "u"))
+          updater[idx] = "inline";
+        
+	## There is an extern updater method that should be called
+        ## from the set method
+        if (index (quals, "U"))
+          updater[idx] = "extern";
+
+	## There is not factory default value
+        if (index (quals, "f"))
+          factory[idx] = 0;
+
+##        ## emmit an asignment set function
+##        if (index (quals, "a"))
+##          emit_ov_set[idx] = "assignment";
+##
+##        if (type[idx] != "octave_value")
+##        {
+##          ## The 'o' and 'O' qualifiers are only useful when the
+##          ## the property type is something other than an
+##          ## octave_value.
+##
+##          ## There is a custom inline definition for the
+##          ## octave_value version of the set function, so we
+##          ## don't emit anything.
+##          if (index (quals, "o"))
+##            emit_ov_set[idx] = "";
+##
+##          ## There is a custom extern definition for the
+##          ## octave_value version of the set function, but we
+##          ## still emit the declaration.
+##          if (index (quals, "O"))
+##            emit_ov_set[idx] = "declaration";
+##        }
+      }
+
+      if (NF > field && $field == ",")
+      {
+        field++;
+
+        for (i = field; i <= NF; i++)
+          defval[idx] = (defval[idx] (i > field ? " " : "") $i);
+      }
+    }
+
+  }
+  else
+    print $0;
+}
diff --git a/src/gl-render.cc b/src/gl-render.cc
new file mode 100644
index 0000000..f0f51f3
--- /dev/null
+++ b/src/gl-render.cc
@@ -0,0 +1,2878 @@
+/*
+
+Copyright (C) 2008, 2009 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (HAVE_OPENGL)
+
+#include <lo-mappers.h>
+#include "oct-locbuf.h"
+#include "gl-render.h"
+
+#define LIGHT_MODE GL_FRONT_AND_BACK
+
+// Win32 API requires the CALLBACK attributes for
+// GLU callback functions. Define it to empty on
+// other platforms.
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+enum {
+  AXE_ANY_DIR   = 0,
+  AXE_DEPTH_DIR = 1,
+  AXE_HORZ_DIR  = 2,
+  AXE_VERT_DIR  = 3
+};
+
+static octave_idx_type
+xmin (octave_idx_type x, octave_idx_type y)
+{
+  return x < y ? x : y;
+}
+
+class
+opengl_texture
+{
+protected:
+  class texture_rep
+  {
+  public:
+    texture_rep (void) : valid (false), count (1) { }
+
+    texture_rep (GLuint _id, int _w, int _h, int _tw, int _th)
+	: id (_id), w (_w), h (_h), tw (_tw), th (_th),
+	  tx (double(w)/tw), ty (double(h)/th), valid (true),
+	  count (1) { }
+
+    ~texture_rep (void)
+      {
+	if (valid)
+	  glDeleteTextures (1, &id);
+      }
+
+    void bind (int mode) const
+      { if (valid) glBindTexture (mode, id); }
+
+    void tex_coord (double q, double r) const
+      { if (valid) glTexCoord2d (q*tx, r*ty); }
+
+    GLuint id;
+    int w, h;
+    int tw, th;
+    double tx, ty;
+    bool valid;
+    int count;
+  };
+
+  texture_rep *rep;
+
+private:
+  opengl_texture (texture_rep *_rep) : rep (_rep) { }
+
+public:
+  opengl_texture (void) : rep (new texture_rep ()) { }
+
+  opengl_texture (const opengl_texture& tx)
+      : rep (tx.rep)
+    {
+      rep->count++;
+    }
+
+  ~opengl_texture (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+  opengl_texture& operator = (const opengl_texture& tx)
+    {
+      if (--rep->count == 0)
+	delete rep;
+
+      rep = tx.rep;
+      rep->count++;
+
+      return *this;
+    }
+
+  static opengl_texture create (const octave_value& data);
+
+  void bind (int mode = GL_TEXTURE_2D) const
+    { rep->bind (mode); }
+
+  void tex_coord (double q, double r) const
+    { rep->tex_coord (q, r); }
+  
+  bool is_valid (void) const
+    { return rep->valid; }
+};
+
+static int
+next_power_of_2 (int n)
+{
+  int m = 1;
+
+  while (m < n && m < INT_MAX)
+    m <<= 1;
+
+  return m;
+}
+
+opengl_texture
+opengl_texture::create (const octave_value& data)
+{
+  opengl_texture retval;
+
+  dim_vector dv (data.dims ());
+
+  // Expect RGB data
+  if (dv.length () == 3 && dv(2) == 3)
+    {
+      int h = dv(0), w = dv(1), tw, th;
+      GLuint id;
+      bool ok = true;
+
+      tw = next_power_of_2 (w);
+      th = next_power_of_2 (w);
+
+      glGenTextures (1, &id);
+      glBindTexture (GL_TEXTURE_2D, id);
+
+      if (data.is_double_type ())
+	{
+	  NDArray _a = data.array_value ();
+
+	  OCTAVE_LOCAL_BUFFER (float, a, (3*tw*th));
+
+	  for (int i = 0; i < h; i++)
+	    for (int j = 0, idx = i*tw*3; j < w; j++, idx += 3)
+	      {
+		a[idx]   = _a(i,j,0);
+		a[idx+1] = _a(i,j,1);
+		a[idx+2] = _a(i,j,2);
+	      }
+
+	  glTexImage2D (GL_TEXTURE_2D, 0, 3, tw, th, 0,
+			GL_RGB, GL_FLOAT, a);
+	}
+      else if (data.is_uint8_type ())
+	{
+	  uint8NDArray _a = data.uint8_array_value ();
+
+	  OCTAVE_LOCAL_BUFFER (octave_uint8, a, (3*tw*th));
+
+	  for (int i = 0; i < h; i++)
+	    for (int j = 0, idx = i*tw*3; j < w; j++, idx += 3)
+	      {
+		a[idx]   = _a(i,j,0);
+		a[idx+1] = _a(i,j,1);
+		a[idx+2] = _a(i,j,2);
+	      }
+
+	  glTexImage2D (GL_TEXTURE_2D, 0, 3, tw, th, 0,
+			GL_RGB, GL_UNSIGNED_BYTE, a);
+	}
+      else
+	{
+	  ok = false;
+	  warning ("opengl_texture::create: invalid texture data type (expected double or uint8)");
+	}
+
+      if (ok)
+	{
+	  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	  if (glGetError () != GL_NO_ERROR)
+	    warning ("opengl_texture::create: OpenGL error while generating texture data");
+	  else
+	    retval = opengl_texture (new texture_rep (id, w, h, tw, th));
+	}
+    }
+  else
+    warning ("opengl_texture::create: invalid texture data size");
+
+  return retval;
+}
+
+class
+opengl_tesselator
+{
+public:
+#if defined (HAVE_FRAMEWORK_OPENGL) && defined (HAVE_GLUTESSCALLBACK_THREEDOTS)
+  typedef GLvoid (CALLBACK *fcn) (...);
+#else
+  typedef void (CALLBACK *fcn) (void);
+#endif
+
+public:
+
+  opengl_tesselator (void) : glu_tess (0) { init (); }
+
+  virtual ~opengl_tesselator (void)
+    { if (glu_tess) gluDeleteTess (glu_tess); }
+
+  void begin_polygon (bool filled = true)
+    {
+      gluTessProperty (glu_tess, GLU_TESS_BOUNDARY_ONLY,
+		       (filled ? GL_FALSE : GL_TRUE));
+      fill = filled;
+      gluTessBeginPolygon (glu_tess, this);
+    }
+
+  void end_polygon (void) const
+    { gluTessEndPolygon (glu_tess); }
+
+  void begin_contour (void) const
+    { gluTessBeginContour (glu_tess); }
+
+  void end_contour (void) const
+    { gluTessEndContour (glu_tess); }
+
+  void add_vertex (double *loc, void *data) const
+    { gluTessVertex (glu_tess, loc, data); }
+
+protected:
+  virtual void begin (GLenum /*type*/) { }
+
+  virtual void end (void) { }
+
+  virtual void vertex (void */*data*/) { }
+
+  virtual void combine (GLdouble /*c*/[3], void */*data*/[4],
+			GLfloat /*w*/[4], void **/*out_data*/) { }
+
+  virtual void edge_flag (GLboolean /*flag*/) { }
+
+  virtual void error (GLenum err)
+    { ::error ("OpenGL tesselation error (%d)", err); }
+
+  virtual void init (void)
+    {
+      glu_tess = gluNewTess ();
+
+      gluTessCallback (glu_tess, GLU_TESS_BEGIN_DATA,
+		       reinterpret_cast<fcn> (tess_begin));
+      gluTessCallback (glu_tess, GLU_TESS_END_DATA,
+		       reinterpret_cast<fcn> (tess_end));
+      gluTessCallback (glu_tess, GLU_TESS_VERTEX_DATA,
+		       reinterpret_cast<fcn> (tess_vertex));
+      gluTessCallback (glu_tess, GLU_TESS_COMBINE_DATA,
+		       reinterpret_cast<fcn> (tess_combine));
+      gluTessCallback (glu_tess, GLU_TESS_EDGE_FLAG_DATA,
+		       reinterpret_cast<fcn> (tess_edge_flag));
+      gluTessCallback (glu_tess, GLU_TESS_ERROR_DATA,
+		       reinterpret_cast<fcn> (tess_error));
+    }
+
+  bool is_filled (void) const { return fill; }
+
+private:
+  static void CALLBACK tess_begin (GLenum type, void *t)
+    { reinterpret_cast<opengl_tesselator *> (t)->begin (type); }
+  
+  static void CALLBACK tess_end (void *t)
+    { reinterpret_cast<opengl_tesselator *> (t)->end (); }
+  
+  static void CALLBACK tess_vertex (void *v, void *t)
+    { reinterpret_cast<opengl_tesselator *> (t)->vertex (v); }
+  
+  static void CALLBACK tess_combine (GLdouble c[3], void *v[4], GLfloat w[4],
+				     void **out,  void *t)
+    { reinterpret_cast<opengl_tesselator *> (t)->combine (c, v, w, out); }
+  
+  static void CALLBACK tess_edge_flag (GLboolean flag, void *t)
+    { reinterpret_cast<opengl_tesselator *> (t)->edge_flag (flag); }
+  
+  static void CALLBACK tess_error (GLenum err, void *t)
+    { reinterpret_cast<opengl_tesselator *> (t)->error (err); }
+
+private:
+  GLUtesselator *glu_tess;
+  bool fill;
+};
+
+class
+vertex_data
+{
+public:
+  class vertex_data_rep
+  {
+  public:
+    Matrix coords;
+    Matrix color;
+    Matrix normal;
+    double alpha;
+    float ambient;
+    float diffuse;
+    float specular;
+    float specular_exp;
+
+    // reference counter
+    int count;
+
+    vertex_data_rep (void) : count (1) { }
+
+    vertex_data_rep (const Matrix& c, const Matrix& col, const Matrix& n,
+		     double a, float as, float ds, float ss, float se)
+	: coords (c), color (col), normal (n), alpha (a),
+	  ambient (as), diffuse (ds), specular (ss), specular_exp (se),
+	  count (1) { }
+  };
+
+private:
+  vertex_data_rep *rep;
+
+  vertex_data_rep *nil_rep (void) const
+    {
+      static vertex_data_rep *nr = new vertex_data_rep ();
+
+      return nr;
+    }
+
+public:
+  vertex_data (void) : rep (nil_rep ())
+    { rep->count++; }
+
+  vertex_data (const vertex_data& v) : rep (v.rep)
+    { rep->count++; }
+
+  vertex_data (const Matrix& c, const Matrix& col, const Matrix& n,
+	       double a, float as, float ds, float ss, float se)
+      : rep (new vertex_data_rep (c, col, n, a, as, ds, ss, se))
+    { }
+
+  vertex_data (vertex_data_rep *new_rep)
+      : rep (new_rep) { }
+
+  ~vertex_data (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+  vertex_data& operator = (const vertex_data& v)
+    {
+      if (--rep->count == 0)
+	delete rep;
+
+      rep = v.rep;
+      rep->count++;
+
+      return *this;
+    }
+
+  vertex_data_rep *get_rep (void) const { return rep; }
+};
+
+class
+opengl_renderer::patch_tesselator : public opengl_tesselator
+{
+public:
+  patch_tesselator (opengl_renderer *r, int cmode, int lmode, int idx = 0)
+      : opengl_tesselator (), renderer (r),
+        color_mode (cmode), light_mode (lmode), index (idx),
+        first (true) { }
+
+protected:
+  void begin (GLenum type)
+    {
+      //printf("patch_tesselator::begin (%d)\n", type);
+      first = true;
+
+      if (color_mode == 2 || light_mode == 2)
+	glShadeModel (GL_SMOOTH);
+      else
+	glShadeModel (GL_FLAT);
+
+      if (is_filled ())
+	renderer->set_polygon_offset (true, 1+index);
+
+      glBegin (type);
+    }
+
+  void end (void)
+    {
+      //printf("patch_tesselator::end\n");
+      glEnd ();
+      renderer->set_polygon_offset (false);
+    }
+
+  void vertex (void *data)
+    {
+      vertex_data::vertex_data_rep *v
+	  = reinterpret_cast<vertex_data::vertex_data_rep *> (data);
+      //printf("patch_tesselator::vertex (%g, %g, %g)\n", v->coords(0), v->coords(1), v->coords(2));
+
+      // FIXME: why did I need to keep the first vertex of the face
+      // in JHandles? I think it's related to the fact that the 
+      // tessellation process might re-order the vertices, such that
+      // the first one you get here might not be the first one of the face;
+      // but I can't figure out the actual reason.
+      if (color_mode > 0 && (first || color_mode == 2))
+	{
+	  Matrix col = v->color;
+
+	  if (col.numel () == 3)
+	    {
+	      glColor3dv (col.data ());
+	      if (light_mode > 0)
+		{
+		  float buf[4] = { 0, 0, 0, 1 };
+
+		  for (int k = 0; k < 3; k++)
+		    buf[k] = (v->ambient * col(k));
+		  glMaterialfv (LIGHT_MODE, GL_AMBIENT, buf);
+
+		  for (int k = 0; k < 3; k++)
+		    buf[k] = (v->diffuse * col(k));
+		  glMaterialfv (LIGHT_MODE, GL_AMBIENT, buf);
+		}
+	    }
+	}
+
+      if (light_mode > 0 && (first || light_mode == 2))
+	glNormal3dv (v->normal.data ());
+
+      glVertex3dv (v->coords.data ());
+
+      first = false;
+    }
+
+  void combine (GLdouble xyz[3], void *data[4], GLfloat w[4],
+		void **out_data)
+    {
+      //printf("patch_tesselator::combine\n");
+
+      vertex_data::vertex_data_rep *v[4];
+      int vmax = 4;
+
+      for (int i = 0; i < 4; i++)
+	{
+	  v[i] = reinterpret_cast<vertex_data::vertex_data_rep *> (data[i]);
+
+	  if (vmax == 4 && ! v[i])
+	    vmax = i;
+	}
+
+      Matrix vv (1, 3, 0.0);
+      Matrix cc;
+      Matrix nn (1, 3, 0.0);
+      double aa = 0.0;
+
+      vv(0) = xyz[0];
+      vv(1) = xyz[1];
+      vv(2) = xyz[2];
+
+      if (v[0]->color.numel ())
+	{
+	  cc.resize (1, 3, 0.0);
+	  for (int ic = 0; ic < 3; ic++)
+	    for (int iv = 0; iv < vmax; iv++)
+	      cc(ic) += (w[iv] * v[iv]->color(ic));
+	}
+
+      if (v[0]->normal.numel () > 0)
+	{
+	  for (int in = 0; in < 3; in++)
+	    for (int iv = 0; iv < vmax; iv++)
+	      nn(in) += (w[iv] * v[iv]->normal(in));
+	}
+
+      for (int iv = 0; iv < vmax; iv++)
+	aa += (w[iv] * v[iv]->alpha);
+
+      vertex_data new_v (vv, cc, nn, aa, v[0]->ambient, v[0]->diffuse,
+			 v[0]->specular, v[0]->specular_exp);
+      tmp_vdata.push_back (new_v);
+
+      *out_data = new_v.get_rep ();
+    }
+
+private:
+  opengl_renderer *renderer;
+  int color_mode;	// 0: uni,  1: flat, 2: interp
+  int light_mode;	// 0: none, 1: flat, 2: gouraud
+  int index;
+  bool first;
+  std::list<vertex_data> tmp_vdata;
+};
+
+void
+opengl_renderer::draw (const graphics_object& go)
+{
+  if (! go.valid_object ())
+    return;
+
+  const base_properties& props = go.get_properties ();
+
+  if (go.isa ("figure"))
+    draw (dynamic_cast<const figure::properties&> (props));
+  else if (go.isa ("axes"))
+    draw (dynamic_cast<const axes::properties&> (props));
+  else if (go.isa ("line"))
+    draw (dynamic_cast<const line::properties&> (props));
+  else if (go.isa ("surface"))
+    draw (dynamic_cast<const surface::properties&> (props));
+  else if (go.isa ("patch"))
+    draw (dynamic_cast<const patch::properties&> (props));
+  else if (go.isa ("hggroup"))
+    draw (dynamic_cast<const hggroup::properties&> (props));
+  else
+    warning ("opengl_renderer: cannot render object of type `%s'",
+	     props.graphics_object_name ().c_str ());
+}
+
+void
+opengl_renderer::draw (const figure::properties& props)
+{
+  backend = props.get_backend ();
+
+  // Initialize OpenGL context
+
+  glEnable (GL_DEPTH_TEST);
+  glDepthFunc (GL_LEQUAL);
+  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glEnable (GL_NORMALIZE);
+
+  if (props.is___enhanced__ ())
+    {
+      glEnable (GL_BLEND);
+      glEnable (GL_LINE_SMOOTH);
+    }
+  else
+    {
+      glDisable (GL_BLEND);
+      glDisable (GL_LINE_SMOOTH);
+    }
+
+  // Clear background
+
+  Matrix c = props.get_color_rgb ();
+
+  if (c.length() >= 3)
+    {
+      glClearColor (c(0), c(1), c(2), 1);
+      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    }
+
+  // Draw children
+
+  draw (props.get_all_children ());
+}
+
+void
+opengl_renderer::draw (const axes::properties& props)
+{
+  // setup OpenGL transformation
+
+  Matrix x_zlim = props.get_transform_zlim ();
+  Matrix x_mat1 = props.get_opengl_matrix_1 ();
+  Matrix x_mat2 = props.get_opengl_matrix_2 ();
+  
+  xZ1 = x_zlim(0)-(x_zlim(1)-x_zlim(0))/2;
+  xZ2 = x_zlim(1)+(x_zlim(1)-x_zlim(0))/2;
+
+#if defined (HAVE_FRAMEWORK_OPENGL)
+  GLint vw[4];
+#else
+  int vw[4];
+#endif
+
+  glGetIntegerv (GL_VIEWPORT, vw);
+
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+  glScaled(1, 1, -1);
+  glMultMatrixd (x_mat1.data ());
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
+  glMultMatrixd (x_mat2.data ());
+  glMatrixMode (GL_MODELVIEW);
+
+  glClear (GL_DEPTH_BUFFER_BIT);
+
+  // store axes transformation data
+
+  xform = props.get_transform ();
+  
+  // draw axes object
+
+  GLboolean antialias;
+  glGetBooleanv (GL_LINE_SMOOTH, &antialias);
+  glDisable (GL_LINE_SMOOTH);
+  
+  Matrix xlim = xform.xscale (props.get_xlim ().matrix_value ());
+  Matrix ylim = xform.yscale (props.get_ylim ().matrix_value ());
+  Matrix zlim = xform.zscale (props.get_zlim ().matrix_value ());
+  double x_min = xlim(0), x_max = xlim(1);
+  double y_min = ylim(0), y_max = ylim(1);
+  double z_min = zlim(0), z_max = zlim(1);
+  
+  double xd = (props.xdir_is ("normal") ? 1 : -1);
+  double yd = (props.ydir_is ("normal") ? 1 : -1);
+  double zd = (props.zdir_is ("normal") ? 1 : -1);
+
+  ColumnVector p1, p2, xv (3), yv (3), zv (3);
+  int xstate, ystate, zstate;
+
+  xstate = ystate = zstate = AXE_ANY_DIR;
+
+  p1 = xform.transform (x_min, (y_min+y_max)/2, (z_min+z_max)/2, false);
+  p2 = xform.transform (x_max, (y_min+y_max)/2, (z_min+z_max)/2, false);
+  xv(0) = xround (p2(0)-p1(0));
+  xv(1) = xround (p2(1)-p1(1));
+  xv(2) = (p2(2)-p1(2));
+  if (xv(0) == 0 && xv(1) == 0)
+    xstate = AXE_DEPTH_DIR;
+  else if (xv(2) == 0)
+    {
+      if (xv(0) == 0)
+        xstate = AXE_VERT_DIR;
+      else if (xv(1) == 0)
+        xstate = AXE_HORZ_DIR;
+    }
+  double xPlane;
+  if (xv(2) == 0)
+    if (xv(1) == 0)
+      xPlane = (xv(0) > 0 ? x_max : x_min);
+    else
+      xPlane = (xv(1) < 0 ? x_max : x_min);
+  else
+    xPlane = (xv(2) < 0 ? x_min : x_max);
+  double xPlaneN = (xPlane == x_min ? x_max : x_min);
+  double fx = (x_max-x_min)/sqrt(xv(0)*xv(0)+xv(1)*xv(1));
+
+  p1 = xform.transform ((x_min+x_max)/2, y_min, (z_min+z_max)/2, false);
+  p2 = xform.transform ((x_min+x_max)/2, y_max, (z_min+z_max)/2, false);
+  yv(0) = xround (p2(0)-p1(0));
+  yv(1) = xround (p2(1)-p1(1));
+  yv(2) = (p2(2)-p1(2));
+  if (yv(0) == 0 && yv(1) == 0)
+    ystate = AXE_DEPTH_DIR;
+  else if (yv(2) == 0)
+    {
+      if (yv(0) == 0)
+        ystate = AXE_VERT_DIR;
+      else if (yv(1) == 0)
+        ystate = AXE_HORZ_DIR;
+    }
+  double yPlane;
+  if (yv(2) == 0)
+    if (yv(1) == 0)
+      yPlane = (yv(0) > 0 ? y_max : y_min);
+    else
+      yPlane = (yv(1) < 0 ? y_max : y_min);
+  else
+    yPlane = (yv(2) < 0 ? y_min : y_max);
+  double yPlaneN = (yPlane == y_min ? y_max : y_min);
+  double fy = (y_max-y_min)/sqrt(yv(0)*yv(0)+yv(1)*yv(1));
+
+  p1 = xform.transform((x_min+x_max)/2, (y_min+y_max)/2, z_min, false);
+  p2 = xform.transform((x_min+x_max)/2, (y_min+y_max)/2, z_max, false);
+  zv(0) = xround(p2(0)-p1(0));
+  zv(1) = xround (p2(1)-p1(1));
+  zv(2) = (p2(2)-p1(2));
+  if (zv(0) == 0 && zv(1) == 0)
+    zstate = AXE_DEPTH_DIR;
+  else if (zv(2) == 0)
+  {
+    if (zv(0) == 0)
+      zstate = AXE_VERT_DIR;
+    else if (zv(1) == 0)
+      zstate = AXE_HORZ_DIR;
+  }
+  double zPlane;
+  if (zv(2) == 0)
+    if (zv(1) == 0)
+      zPlane = (zv(0) > 0 ? z_min : z_max);
+    else
+      zPlane = (zv(1) < 0 ? z_min : z_max);
+  else
+    zPlane = (zv(2) < 0 ? z_min : z_max);
+  double zPlaneN = (zPlane == z_min ? z_max : z_min);
+  double fz = (z_max-z_min)/sqrt(zv(0)*zv(0)+zv(1)*zv(1));
+
+  bool mode2d = (((xstate > AXE_DEPTH_DIR ? 1 : 0) +
+        (ystate > AXE_DEPTH_DIR ? 1 : 0) +
+        (zstate > AXE_DEPTH_DIR ? 1 : 0)) == 2);
+  if (props.tickdirmode_is ("auto"))
+  {
+    // FIXME: tickdir should be updated (code below comes
+    //        from JHandles)
+    //autoMode++;
+    //TickDir.set(mode2d ? "in" : "out", true);
+    //autoMode--;
+  }
+
+  // FIXME: use ticklength property
+  double xticklen = 7, yticklen = 7, zticklen = 7;
+
+  //double tickdir = (props.tickdir_is ("in") ? -1 : 1);
+  double tickdir = (props.tickdirmode_is ("auto") ?
+		    (mode2d ? -1 : 1) :
+		    (props.tickdir_is ("in") ? -1 : 1));
+  double xtickoffset = (mode2d && tickdir < 0 ? 0 : xticklen) + 5;
+  double ytickoffset = (mode2d && tickdir < 0 ? 0 : yticklen) + 5;
+  double ztickoffset = (mode2d && tickdir < 0 ? 0 : zticklen) + 5;
+
+  bool xySym = (xd*yd*(xPlane-xPlaneN)*(yPlane-yPlaneN) > 0);
+  bool x2Dtop = false;
+  bool y2Dright = false;
+  double zpTick = zPlane;
+
+  /* 2D mode */
+  if (xstate == AXE_HORZ_DIR && ystate == AXE_VERT_DIR)
+  {
+    if (props.xaxislocation_is ("top"))
+    {
+      double tmp = yPlane;
+      yPlane = yPlaneN;
+      yPlaneN = tmp;
+      x2Dtop = true;
+    }
+    if (props.yaxislocation_is ("right"))
+    {
+      double tmp = xPlane;
+      xPlane = xPlaneN;
+      xPlaneN = tmp;
+      y2Dright = true;
+    }
+    if (props.layer_is ("top"))
+      zpTick = zPlaneN;
+  }
+
+  Matrix axe_color = props.get_color_rgb ();
+  bool visible = props.is_visible ();
+  bool box = props.is_box ();
+
+  // Axes planes
+
+  if (axe_color.numel () > 0 && visible)
+    {
+      set_color (axe_color);
+      set_polygon_offset (true, 2.5);
+
+      glBegin (GL_QUADS);
+
+      // X plane
+      glVertex3d (xPlane, y_min, z_min);
+      glVertex3d (xPlane, y_max, z_min);
+      glVertex3d (xPlane, y_max, z_max);
+      glVertex3d (xPlane, y_min, z_max);
+
+      // Y plane
+      glVertex3d (x_min, yPlane, z_min);
+      glVertex3d (x_max, yPlane, z_min);
+      glVertex3d (x_max, yPlane, z_max);
+      glVertex3d (x_min, yPlane, z_max);
+
+      // Z plane
+      glVertex3d (x_min, y_min, zPlane);
+      glVertex3d (x_max, y_min, zPlane);
+      glVertex3d (x_max, y_max, zPlane);
+      glVertex3d (x_min, y_max, zPlane);
+
+      glEnd ();
+
+      set_polygon_offset (false);
+    }
+
+  // Axes box
+
+  set_linestyle ("-", true);
+  set_linewidth (props.get_linewidth ());
+
+  if (visible)
+    {
+      glBegin (GL_LINES);
+
+      // X box
+      set_color (props.get_xcolor_rgb ());
+      glVertex3d (xPlaneN, yPlaneN, zPlane);
+      glVertex3d (xPlane, yPlaneN, zPlane);
+      if (box)
+        {
+          glVertex3d (xPlaneN, yPlane, zPlane);
+          glVertex3d (xPlane, yPlane, zPlane);
+          glVertex3d (xPlaneN, yPlane, zPlaneN);
+          glVertex3d (xPlane, yPlane, zPlaneN);
+          glVertex3d (xPlaneN, yPlaneN, zPlaneN);
+          glVertex3d (xPlane, yPlaneN, zPlaneN);
+        }
+
+      // Y box
+      set_color (props.get_ycolor_rgb ());
+      glVertex3d (xPlaneN, yPlaneN, zPlane);
+      glVertex3d (xPlaneN, yPlane, zPlane);
+      if (box)
+        {
+          glVertex3d (xPlane, yPlaneN, zPlane);
+          glVertex3d (xPlane, yPlane, zPlane);
+          glVertex3d (xPlane, yPlaneN, zPlaneN);
+          glVertex3d (xPlane, yPlane, zPlaneN);
+          glVertex3d (xPlaneN, yPlaneN, zPlaneN);
+          glVertex3d (xPlaneN, yPlane, zPlaneN);
+        }
+
+      // Z box
+      set_color (props.get_zcolor_rgb ());
+      if (xySym)
+        {
+          glVertex3d (xPlaneN, yPlane, zPlaneN);
+          glVertex3d (xPlaneN, yPlane, zPlane);
+        }
+      else
+        {
+          glVertex3d (xPlane, yPlaneN, zPlaneN);
+          glVertex3d (xPlane, yPlaneN, zPlane);
+        }
+      if (box)
+        {
+          glVertex3d (xPlane, yPlane, zPlaneN);
+          glVertex3d (xPlane, yPlane, zPlane);
+          if (xySym)
+            {
+              glVertex3d (xPlane, yPlaneN, zPlaneN);
+              glVertex3d (xPlane, yPlaneN, zPlane);
+            }
+          else
+            {
+              glVertex3d (xPlaneN, yPlane, zPlaneN);
+              glVertex3d (xPlaneN, yPlane, zPlane);
+            }
+          glVertex3d (xPlaneN, yPlaneN, zPlaneN);
+          glVertex3d (xPlaneN, yPlaneN, zPlane);
+        }
+
+      glEnd ();
+    }
+
+  std::string gridstyle = props.get_gridlinestyle ();
+  std::string minorgridstyle = props.get_minorgridlinestyle ();
+
+  // X grid
+
+  if (visible && xstate != AXE_DEPTH_DIR)
+    {
+      bool do_xgrid = (props.is_xgrid () && (gridstyle != "none"));
+      bool do_xminorgrid = (props.is_xminorgrid () && (minorgridstyle != "none"));
+      bool do_xminortick = props.is_xminortick ();
+      Matrix xticks = xform.xscale (props.get_xtick ().matrix_value ());
+      // FIXME: use pre-computed minor ticks
+      Matrix xmticks;
+      // FIXME: use xticklabels property
+      string_vector xticklabels;
+      int wmax = 0, hmax = 0;
+      bool tick_along_z = xisinf (fy);
+      Matrix tickpos (xticks.numel (), 3);
+
+      set_color (props.get_xcolor_rgb ());
+
+      // grid lines
+      if (do_xgrid)
+        {
+          set_linestyle (gridstyle, true);
+          glBegin (GL_LINES);
+          for (int i = 0; i < xticks.numel (); i++)
+            {
+              double xval = xticks(i);
+
+              glVertex3d (xval, yPlaneN, zpTick);
+              glVertex3d (xval, yPlane, zpTick);
+              if (zstate != AXE_DEPTH_DIR)
+                {
+                  glVertex3d (xval, yPlane, zPlaneN);
+                  glVertex3d (xval, yPlane, zPlane);
+                }
+            }
+          glEnd ();
+          set_linestyle ("-", true);
+        }
+
+      // tick marks
+      if (tick_along_z)
+        {
+          glBegin (GL_LINES);
+          for (int i = 0; i < xticks.numel (); i++)
+            {
+              double xval = xticks(i);
+
+              glVertex3d (xval, yPlaneN, zPlane);
+              glVertex3d (xval, yPlaneN, zPlane+signum(zPlane-zPlaneN)*fz*xticklen*tickdir);
+              if (box && xstate != AXE_ANY_DIR)
+                {
+                  glVertex3d (xval, yPlaneN, zPlaneN);
+                  glVertex3d (xval, yPlaneN,
+                        zPlaneN+signum(zPlaneN-zPlane)*fz*xticklen*tickdir);
+                }
+              tickpos(i,0) = xval;
+              tickpos(i,1) = yPlaneN;
+              tickpos(i,2) = zPlane+signum(zPlane-zPlaneN)*fz*xtickoffset;
+            }
+          glEnd ();
+        }
+      else
+        {
+          glBegin (GL_LINES);
+          for (int i = 0; i < xticks.numel (); i++)
+            {
+              double xval = xticks(i);
+
+              glVertex3d (xval, yPlaneN, zpTick);
+              glVertex3d (xval, yPlaneN+signum(yPlaneN-yPlane)*fy*xticklen*tickdir, zpTick);
+              if (box && xstate != AXE_ANY_DIR)
+                {
+                  glVertex3d (xval, yPlane, zpTick);
+                  glVertex3d (xval,
+                        yPlane+signum(yPlane-yPlaneN)*fy*xticklen*tickdir, zpTick);
+                }
+              tickpos(i,0) = xval;
+              tickpos(i,1) = yPlaneN+signum(yPlaneN-yPlane)*fy*xtickoffset;
+              tickpos(i,2) = zPlane;
+            }
+          glEnd ();
+        }
+
+      // FIXME: tick texts
+
+      // minor grid lines
+      if (do_xminorgrid)
+        {
+          set_linestyle (minorgridstyle, true);
+          glBegin (GL_LINES);
+          for (int i = 0; i < xmticks.numel (); i++)
+            {
+              double xval = xmticks(i);
+
+              glVertex3d (xval, yPlaneN, zpTick);
+              glVertex3d (xval, yPlane, zpTick);
+              if (zstate != AXE_DEPTH_DIR)
+                {
+                  glVertex3d (xval, yPlane, zPlaneN);
+                  glVertex3d (xval, yPlane, zPlane);
+                }
+            }
+          glEnd ();
+          set_linestyle ("-", true);
+        }
+			
+      // minor tick marks
+      if (do_xminortick)
+        {
+          if (tick_along_z)
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < xmticks.numel (); i++)
+                {
+                  double xval = xmticks(i);
+
+                  glVertex3d (xval, yPlaneN, zPlane);
+                  glVertex3d (xval, yPlaneN,
+                      zPlane+signum(zPlane-zPlaneN)*fz*xticklen/2*tickdir);
+                  if (box && xstate != AXE_ANY_DIR)
+                    {
+                      glVertex3d (xval, yPlaneN, zPlaneN);
+                      glVertex3d (xval, yPlaneN,
+                          zPlaneN+signum(zPlaneN-zPlane)*fz*xticklen/2*tickdir);
+                    }
+                }
+              glEnd ();
+            }
+          else
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < xmticks.numel (); i++)
+                {
+                  double xval = xmticks(i);
+
+                  glVertex3d (xval, yPlaneN, zpTick);
+                  glVertex3d (xval,
+                        yPlaneN+signum(yPlaneN-yPlane)*fy*xticklen/2*tickdir, zpTick);
+                  if (box && xstate != AXE_ANY_DIR)
+                    {
+                      glVertex3d (xval, yPlane, zpTick);
+                      glVertex3d (xval,
+                            yPlane+signum(yPlane-yPlaneN)*fy*xticklen/2*tickdir, zpTick);
+                    }
+                }
+              glEnd ();
+            }
+        }
+
+      text::properties& xlabel_props =
+        reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_xlabel ()).get_properties ());
+
+      // FIXME: auto-positioning should be disabled if the 
+      //        label has been positioned manually
+      if (! xlabel_props.get_string ().empty ())
+        {
+          xlabel_props.set_horizontalalignment (xstate > AXE_DEPTH_DIR ? "center" : (xySym ? "left" : "right"));
+	  xlabel_props.set_verticalalignment (xstate == AXE_VERT_DIR ? "bottom" : (zd*zv(2) <= 0 ? "top" : "bottom"));
+
+          double angle = 0;
+          ColumnVector p = graphics_xform::xform_vector ((x_min+x_max)/2, yPlaneN, zPlane);
+
+          if (tick_along_z)
+            p(2) += (signum(zPlane-zPlaneN)*fz*xtickoffset);
+          else
+            p(1) += (signum(yPlaneN-yPlane)*fy*xtickoffset);
+          p = xform.transform (p(0), p(1), p(2), false);
+          switch (xstate)
+            {
+              case AXE_ANY_DIR:
+                p(0) += (xySym ? wmax : -wmax);
+                p(1) += (zd*zv(2) <= 0 ? hmax : -hmax);
+                break;
+              case AXE_VERT_DIR:
+                p(0) -= wmax;
+                angle = 90;
+                break;
+              case AXE_HORZ_DIR:
+                p(1) += hmax;
+                break;
+            }
+          p = xform.untransform (p(0), p(1), p(2), true);
+          xlabel_props.set_position (p.extract_n (0, 3).transpose ());
+          xlabel_props.set_rotation (angle);
+        }
+    }
+
+  // Y grid
+		
+  if (ystate != AXE_DEPTH_DIR && visible)
+    {
+      bool do_ygrid = (props.is_ygrid () && (gridstyle != "none"));
+      bool do_yminorgrid = (props.is_yminorgrid () && (minorgridstyle != "none"));
+      bool do_yminortick = props.is_yminortick ();
+      Matrix yticks = xform.yscale (props.get_ytick ().matrix_value ());
+      // FIXME: use pre-computed minor ticks
+      Matrix ymticks;
+      // FIXME: use yticklabels property
+      string_vector yticklabels;
+      int wmax = 0, hmax = 0;
+      bool tick_along_z = xisinf (fx);
+      Matrix tickpos (yticks.numel (), 3);
+
+      set_color (props.get_ycolor_rgb ());
+
+      // grid lines
+      if (do_ygrid)
+        {
+          set_linestyle (gridstyle, true);
+          glBegin (GL_LINES);
+          for (int i = 0; i < yticks.numel (); i++)
+            {
+              double yval = yticks(i);
+
+              glVertex3d (xPlaneN, yval, zpTick);
+              glVertex3d (xPlane, yval, zpTick);
+              if (zstate != AXE_DEPTH_DIR)
+                {
+                  glVertex3d (xPlane, yval, zPlaneN);
+                  glVertex3d (xPlane, yval, zPlane);
+                }
+            }
+          glEnd ();
+          set_linestyle ("-", true);
+        }
+
+      // tick marks
+      if (tick_along_z)
+        {
+          glBegin (GL_LINES);
+          for (int i = 0; i < yticks.numel (); i++)
+            {
+              double yval = yticks(i);
+
+              glVertex3d (xPlaneN, yval, zPlane);
+              glVertex3d (xPlaneN, yval, zPlane+signum(zPlane-zPlaneN)*fz*yticklen*tickdir);
+              if (box && ystate != AXE_ANY_DIR)
+                {
+                  glVertex3d (xPlaneN, yval, zPlaneN);
+                  glVertex3d (xPlaneN, yval,
+                        zPlaneN+signum(zPlaneN-zPlane)*fz*yticklen*tickdir);
+                }
+              tickpos(i,0) = xPlaneN;
+              tickpos(i,1) = yval;
+              tickpos(i,2) = zPlane+signum(zPlane-zPlaneN)*fz*ytickoffset;
+            }
+          glEnd ();
+        }
+      else
+        {
+          glBegin (GL_LINES);
+          for (int i = 0; i < yticks.numel (); i++)
+            {
+              double yval = yticks(i);
+
+              glVertex3d (xPlaneN, yval, zpTick);
+              glVertex3d (xPlaneN+signum(xPlaneN-xPlane)*fx*yticklen*tickdir, yval, zpTick);
+              if (box && ystate != AXE_ANY_DIR)
+                {
+                  glVertex3d (xPlane, yval, zpTick);
+                  glVertex3d (xPlane+signum(xPlane-xPlaneN)*fx*yticklen*tickdir,
+                        yval, zpTick);
+                }
+              tickpos(i,0) = xPlaneN+signum(xPlaneN-xPlane)*fx*ytickoffset;
+              tickpos(i,1) = yval;
+              tickpos(i,2) = zPlane;
+            }
+          glEnd ();
+        }
+
+      // FIXME: tick texts
+
+      // minor grid lines
+      if (do_yminorgrid)
+        {
+          set_linestyle (minorgridstyle, true);
+          glBegin (GL_LINES);
+          for (int i = 0; i < ymticks.numel (); i++)
+            {
+              double yval = ymticks(i);
+
+              glVertex3d (xPlaneN, yval, zpTick);
+              glVertex3d (xPlane, yval, zpTick);
+              if (zstate != AXE_DEPTH_DIR)
+                {
+                  glVertex3d (xPlane, yval, zPlaneN);
+                  glVertex3d (xPlane, yval, zPlane);
+                }
+            }
+          glEnd ();
+          set_linestyle ("-", true);
+        }
+
+      // minor tick marks
+      if (do_yminortick)
+        {
+          if (tick_along_z)
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < ymticks.numel (); i++)
+                {
+                  double yval = ymticks(i);
+
+                  glVertex3d (xPlaneN, yval, zPlane);
+                  glVertex3d (xPlaneN, yval,
+                        zPlane+signum(zPlane-zPlaneN)*fz*yticklen/2*tickdir);
+                  if (box && ystate != AXE_ANY_DIR)
+                    {
+                      glVertex3d (xPlaneN, yval, zPlaneN);
+                      glVertex3d (xPlaneN, yval,
+                            zPlaneN+signum(zPlaneN-zPlane)*fz*yticklen/2*tickdir);
+                    }
+                }
+              glEnd ();
+            }
+          else
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < ymticks.numel (); i++)
+                {
+                  double yval = ymticks(i);
+
+                  glVertex3d (xPlaneN, yval, zpTick);
+                  glVertex3d (xPlaneN+signum(xPlaneN-xPlane)*fx*yticklen/2*tickdir,
+                        yval, zpTick);
+                  if (box && ystate != AXE_ANY_DIR)
+                    {
+                      glVertex3d (xPlane, yval, zpTick);
+                      glVertex3d (xPlane+signum(xPlane-xPlaneN)*fx*yticklen/2*tickdir,
+                            yval, zpTick);
+                    }
+                }
+              glEnd ();
+            }
+        }
+
+      text::properties& ylabel_props =
+        reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_ylabel ()).get_properties ());
+
+      // FIXME: auto-positioning should be disabled if the 
+      //        label has been positioned manually
+      if (! ylabel_props.get_string ().empty ())
+        {
+          ylabel_props.set_horizontalalignment (ystate > AXE_DEPTH_DIR ? "center" : (!xySym ? "left" : "right"));
+	  ylabel_props.set_verticalalignment (ystate == AXE_VERT_DIR ? "bottom" : (zd*zv(2) <= 0 ? "top" : "bottom"));
+
+          double angle = 0;
+          ColumnVector p = graphics_xform::xform_vector (xPlaneN, (y_min+y_max)/2, zPlane);
+
+          if (tick_along_z)
+            p(2) += (signum(zPlane-zPlaneN)*fz*ytickoffset);
+          else
+            p(0) += (signum(xPlaneN-xPlane)*fx*ytickoffset);
+          p = xform.transform (p(0), p(1), p(2), false);
+          switch (ystate)
+            {
+              case AXE_ANY_DIR:
+                p(0) += (!xySym ? wmax : -wmax);
+                p(1) += (zd*zv(2) <= 0 ? hmax : -hmax);
+                break;
+              case AXE_VERT_DIR:
+                p(0) -= wmax;
+                angle = 90;
+                break;
+              case AXE_HORZ_DIR:
+                p(1) += hmax;
+                break;
+            }
+          p = xform.untransform(p(0), p(1), p(2), true);
+          ylabel_props.set_position (p.extract_n (0, 3).transpose ());
+          ylabel_props.set_rotation (angle);
+        }
+    }
+		
+  // Z Grid
+
+  if (zstate != AXE_DEPTH_DIR && visible)
+    {
+      bool do_zgrid = (props.is_zgrid () && (gridstyle != "none"));
+      bool do_zminorgrid = (props.is_zminorgrid () && (minorgridstyle != "none"));
+      bool do_zminortick = props.is_zminortick ();
+      Matrix zticks = xform.zscale (props.get_ztick ().matrix_value ());
+      // FIXME: use pre-computed minor ticks
+      Matrix zmticks;
+      // FIXME: use zticklabels property
+      string_vector zticklabels;
+      int wmax = 0, hmax = 0;
+      Matrix tickpos (zticks.numel (), 3);
+
+      set_color (props.get_zcolor_rgb ());
+
+      // grid lines
+      if (do_zgrid)
+        {
+          set_linestyle (gridstyle, true);
+          glBegin (GL_LINES);
+          for (int i = 0; i < zticks.numel (); i++)
+            {
+              double zval = zticks(i);
+
+              glVertex3d (xPlaneN, yPlane, zval);
+              glVertex3d (xPlane, yPlane, zval);
+              glVertex3d (xPlane, yPlaneN, zval);
+              glVertex3d (xPlane, yPlane, zval);
+            }
+          glEnd ();
+          set_linestyle ("-", true);
+        }
+
+      // tick marks
+      if (xySym)
+        {
+          if (xisinf (fy))
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < zticks.numel (); i++)
+                {
+                  double zval = zticks(i);
+
+                  glVertex3d (xPlaneN, yPlane, zval);
+                  glVertex3d (xPlaneN+signum(xPlaneN-xPlane)*fx*zticklen*tickdir,
+                        yPlane, zval);
+                  if (box && zstate != AXE_ANY_DIR)
+                    {
+                      glVertex3d (xPlane, yPlane, zval);
+                      glVertex3d (xPlane+signum(xPlane-xPlaneN)*fx*zticklen*tickdir,
+                            yPlane, zval);
+                    }
+                  tickpos(i,0) = xPlaneN+signum(xPlaneN-xPlane)*fx*ztickoffset;
+                  tickpos(i,1) = yPlane;
+                  tickpos(i,2) = zval;
+                }
+              glEnd ();
+            }
+          else
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < zticks.numel (); i++)
+                {
+                  double zval = zticks(i);
+
+                  glVertex3d (xPlaneN, yPlane, zval);
+                  glVertex3d (xPlaneN, yPlane+signum(yPlane-yPlaneN)*fy*zticklen*tickdir, zval);
+                  tickpos(i,0) = xPlaneN;
+                  tickpos(i,1) = yPlane+signum(yPlane-yPlaneN)*fy*ztickoffset;
+                  tickpos(i,2) = zval;
+                }
+              glEnd ();
+            }
+        }
+      else
+        {
+          if (xisinf (fx))
+            {
+              glBegin (GL_LINES);
+              for (int i = 0; i < zticks.numel (); i++)
+                {
+                  double zval = zticks(i);
+
+                  glVertex3d (xPlane, yPlaneN, zval);
+                  glVertex3d (xPlane, yPlaneN+signum(yPlaneN-yPlane)*fy*zticklen*tickdir, zval);
+                  if (box && zstate != AXE_ANY_DIR)
+                    {
+                      glVertex3d (xPlane, yPlane, zval);
+                      glVertex3d (xPlane, yPlane+signum(yPlane-yPlaneN)*fy*zticklen*tickdir, zval);
+                    }
+                  tickpos(i,0) = xPlane;
+                  tickpos(i,1) = yPlaneN+signum(yPlaneN-yPlane)*fy*ztickoffset;
+                  tickpos(i,2) = zval;
+                }
+              glEnd ();
+            }
+          else
+          {
+            glBegin (GL_LINES);
+            for (int i = 0; i < zticks.numel (); i++)
+              {
+                double zval = zticks(i);
+
+                glVertex3d (xPlane, yPlaneN, zval);
+                glVertex3d (xPlane+signum(xPlane-xPlaneN)*fx*zticklen*tickdir, yPlaneN, zval);
+                tickpos(i,0) = xPlane+signum(xPlane-xPlaneN)*fx*ztickoffset;
+                tickpos(i,1) = yPlaneN;
+                tickpos(i,2) = zval;
+              }
+            glEnd ();
+          }
+        }
+
+      // FIXME: tick texts
+
+      // minor grid lines
+      if (do_zminorgrid)
+        {
+          set_linestyle (minorgridstyle, true);
+          glBegin (GL_LINES);
+          for (int i = 0; i < zmticks.numel (); i++)
+            {
+              double zval = zmticks(i);
+
+              glVertex3d (xPlaneN, yPlane, zval);
+              glVertex3d (xPlane, yPlane, zval);
+              glVertex3d (xPlane, yPlaneN, zval);
+              glVertex3d (xPlane, yPlane, zval);
+            }
+          glEnd ();
+          set_linestyle ("-", true);
+        }
+
+      // minor tick marks
+      if (do_zminortick)
+        {
+          if (xySym)
+            {
+              if (xisinf (fy))
+                {
+                  glBegin (GL_LINES);
+                  for (int i = 0; i < zmticks.numel (); i++)
+                    {
+                      double zval = zmticks(i);
+
+                      glVertex3d (xPlaneN, yPlane, zval);
+                      glVertex3d (xPlaneN+signum(xPlaneN-xPlane)*fx*zticklen/2*tickdir,
+                            yPlane, zval);
+                      if (box && zstate != AXE_ANY_DIR)
+                        {
+                          glVertex3d (xPlane, yPlane, zval);
+                          glVertex3d (xPlane+signum(xPlane-xPlaneN)*fx*zticklen/2*tickdir,
+                                yPlane, zval);
+                        }
+                    }
+                  glEnd ();
+                }
+              else
+                {
+                  glBegin (GL_LINES);
+                  for (int i = 0; i < zmticks.numel (); i++)
+                    {
+                      double zval = zmticks(i);
+
+                      glVertex3d (xPlaneN, yPlane, zval);
+                      glVertex3d (xPlaneN, yPlane+signum(yPlane-yPlaneN)*fy*zticklen/2*tickdir, zval);
+                    }
+                  glEnd ();
+                }
+            }
+          else
+            {
+              if (xisinf (fx))
+                {
+                  glBegin (GL_LINES);
+                  for (int i = 0; i < zmticks.numel (); i++)
+                    {
+                      double zval = zmticks(i);
+
+                      glVertex3d (xPlane, yPlaneN, zval);
+                      glVertex3d (xPlane, yPlaneN+signum(yPlaneN-yPlane)*fy*zticklen/2*tickdir, zval);
+                      if (box && zstate != AXE_ANY_DIR)
+                        {
+                          glVertex3d (xPlane, yPlane, zval);
+                          glVertex3d (xPlane, yPlane+signum(yPlane-yPlaneN)*fy*zticklen/2*tickdir, zval);
+                        }
+                    }
+                  glEnd ();
+                }
+              else
+                {
+                  glBegin (GL_LINES);
+                  for (int i = 0; i < zmticks.numel (); i++)
+                    {
+                      double zval = zmticks(i);
+
+                      glVertex3d (xPlane, yPlaneN, zval);
+                      glVertex3d (xPlane+signum(xPlane-xPlaneN)*fx*zticklen/2*tickdir, yPlaneN, zval);
+                    }
+                  glEnd ();
+                }
+            }
+        }
+
+      text::properties& zlabel_props =
+        reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_zlabel ()).get_properties ());
+
+      // FIXME: auto-positioning should be disabled if the 
+      //        label has been positioned manually
+      if (! zlabel_props.get_string ().empty ())
+        {
+          bool camAuto = props.cameraupvectormode_is ("auto");
+
+          zlabel_props.set_horizontalalignment ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right");
+	  zlabel_props.set_verticalalignment(zstate == AXE_VERT_DIR ? "bottom" : ((zd*zv(2) < 0 || camAuto) ? "bottom" : "top"));
+
+          double angle = 0;
+          ColumnVector p;
+
+          if (xySym)
+            {
+              p = graphics_xform::xform_vector (xPlaneN, yPlane, (z_min+z_max)/2);
+              if (xisinf (fy))
+                p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset);
+              else
+                p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset);
+            }
+          else
+            {
+              p = graphics_xform::xform_vector (xPlane, yPlaneN, (z_min+z_max)/2);
+              if (xisinf (fx))
+                p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset);
+              else
+                p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset);
+            }
+          p = xform.transform (p(0), p(1), p(2), false);
+          switch (zstate)
+            {
+              case AXE_ANY_DIR:
+                if (camAuto)
+                  {
+                    p(0) -= wmax;
+                    angle = 90;
+                  }
+                /* FIXME: what's the correct offset?
+                   p[0] += (!xySym ? wmax : -wmax);
+                   p[1] += (zd*zv[2] <= 0 ? hmax : -hmax);
+                   */
+                break;
+              case AXE_VERT_DIR:
+                p(0) -= wmax;
+                angle = 90;
+                break;
+              case AXE_HORZ_DIR:
+                p(1) += hmax;
+                break;
+            }
+          p = xform.untransform (p(0), p(1), p(2), true);
+          zlabel_props.set_position (p.extract_n (0, 3).transpose ());
+          zlabel_props.set_rotation (angle);
+        }
+    }
+
+  set_linestyle ("-");
+
+  // Title
+
+  text::properties& title_props =
+    reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_title ()).get_properties ());
+      
+  // FIXME: auto-positioning should be disabled if the 
+  //        title has been positioned manually
+  if (! title_props.get_string ().empty ())
+    {
+      Matrix bb = props.get_boundingbox (true);
+      ColumnVector p = xform.untransform (bb(0)+bb(2)/2, (bb(1)-10),
+          (x_zlim(0)+x_zlim(1))/2, true);
+      title_props.set_position (p.extract_n(0, 3).transpose ());
+    }
+
+  set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max);
+
+  // Children
+
+  if (antialias == GL_TRUE)
+    glEnable (GL_LINE_SMOOTH);
+
+  Matrix children = props.get_children ();
+  std::list<graphics_object> obj_list;
+  std::list<graphics_object>::iterator it;
+
+  // 1st pass: draw light objects
+
+  for (int i = 0; i < children.numel (); i++)
+    {
+      graphics_object go = gh_manager::get_object (children (i));
+
+      if (go.get_properties ().is_visible ())
+        {
+          if (go.isa ("light"))
+	    draw (go);
+          else
+            obj_list.push_back (go);
+        }
+    }
+
+  // 2nd pass: draw other objects (with units set to "data")
+
+  it = obj_list.begin ();
+  while (it != obj_list.end ())
+    {
+      graphics_object go = (*it);
+
+      // FIXME: check whether object has "units" property and it is set to "data"
+      if (! go.isa ("text") || go.get ("units").string_value () == "data")
+        {
+          set_clipping (go.get_properties ().is_clipping ());
+          draw (go);
+
+          it = obj_list.erase (it);
+        }
+      else
+        it++;
+    }
+
+  // 3rd pass: draw remaining objects
+
+  for (it = obj_list.begin (); it != obj_list.end (); it++)
+    {
+      graphics_object go = (*it);
+
+      set_clipping (go.get_properties ().is_clipping ());
+      draw (go);
+    }
+
+  set_clipping (false);
+  // FIXME: finalize rendering (transparency processing)
+  // FIXME: draw zoom box, if needed
+}
+
+void
+opengl_renderer::draw (const line::properties& props)
+{
+  Matrix x = xform.xscale (props.get_xdata ().matrix_value ());
+  Matrix y = xform.yscale (props.get_ydata ().matrix_value ());
+  Matrix z = xform.zscale (props.get_zdata ().matrix_value ());
+
+  bool has_z = (z.numel () > 0);
+  int n = static_cast<int> (::xmin (::xmin (x.numel (), y.numel ()), (has_z ? z.numel () : INT_MAX)));
+  octave_uint8 clip_mask = (props.is_clipping () ? 0x7F : 0x40), clip_ok (0x40);
+
+  std::vector<octave_uint8> clip (n);
+
+  if (has_z)
+    for (int i = 0; i < n; i++)
+      clip[i] = (clip_code (x(i), y(i), z(i)) & clip_mask);
+  else
+    {
+      double z_mid = (zmin+zmax)/2;
+
+      for (int i = 0; i < n; i++)
+	clip[i] = (clip_code (x(i), y(i), z_mid) & clip_mask);
+    }
+
+  if (! props.linestyle_is ("none"))
+    {
+      set_color (props.get_color_rgb ());
+      set_linestyle (props.get_linestyle (), false);
+      set_linewidth (props.get_linewidth ());
+
+      if (has_z)
+	{
+	  bool flag = false;
+
+	  for (int i = 1; i < n; i++)
+	    {
+	      if ((clip[i-1] & clip[i]) == clip_ok)
+		{
+		  if (! flag)
+		    {
+		      flag = true;
+		      glBegin (GL_LINE_STRIP);
+		      glVertex3d (x(i-1), y(i-1), z(i-1));
+		    }
+		  glVertex3d (x(i), y(i), z(i));
+		}
+	      else if (flag)
+		{
+		  flag = false;
+		  glEnd ();
+		}
+	    }
+
+	  if (flag)
+	    glEnd ();
+	}
+      else
+	{
+	  bool flag = false;
+
+	  for (int i = 1; i < n; i++)
+	    {
+	      if ((clip[i-1] & clip[i]) == clip_ok)
+		{
+		  if (! flag)
+		    {
+		      flag = true;
+		      glBegin (GL_LINE_STRIP);
+		      glVertex2d (x(i-1), y(i-1));
+		    }
+		  glVertex2d (x(i), y(i));
+		}
+	      else if (flag)
+		{
+		  flag = false;
+		  glEnd ();
+		}
+	    }
+
+	  if (flag)
+	    glEnd ();
+	}
+	  
+      set_linewidth (0.5);
+      set_linestyle ("-");
+    }
+
+  set_clipping (false);
+
+  if (! props.marker_is ("none") &&
+      ! (props.markeredgecolor_is ("none")
+	 && props.markerfacecolor_is ("none")))
+    {
+      Matrix lc, fc;
+
+      if (props.markeredgecolor_is ("auto"))
+	lc = props.get_color_rgb ();
+      else if (! props.markeredgecolor_is ("none"))
+	lc = props.get_markeredgecolor_rgb ();
+
+      if (props.markerfacecolor_is ("auto"))
+	fc = props.get_color_rgb ();
+      else if (! props.markerfacecolor_is ("none"))
+	fc = props.get_markerfacecolor_rgb ();
+
+      init_marker (props.get_marker (), props.get_markersize (),
+		   props.get_linewidth ());
+
+      for (int i = 0; i < n; i++)
+        {
+          if (clip[i] == clip_ok)
+            draw_marker (x(i), y(i), (has_z ? z(i) : 0), lc, fc);
+        }
+
+      end_marker ();
+    }
+  
+  set_clipping (props.is_clipping ());
+}
+
+void
+opengl_renderer::draw (const surface::properties& props)
+{
+  Matrix x = xform.xscale (props.get_xdata ().matrix_value ());
+  Matrix y = xform.yscale (props.get_ydata ().matrix_value ());
+  Matrix z = xform.zscale (props.get_zdata ().matrix_value ());
+
+  int zr = z.rows (), zc = z.columns ();
+
+  NDArray c;
+  NDArray n = props.get_vertexnormals ().array_value ();
+
+  // FIXME: handle transparency
+  Matrix a;
+
+  if (props.facelighting_is ("phong") || props.edgelighting_is ("phong"))
+    warning ("opengl_renderer::draw: phong light model not supported");
+
+  int fc_mode = (props.facecolor_is_rgb () ? 0 :
+		 (props.facecolor_is ("flat") ? 1 :
+		  (props.facecolor_is ("interp") ? 2 :
+		   (props.facecolor_is ("texturemap") ? 3 : -1))));
+  int fl_mode = (props.facelighting_is ("none") ? 0 :
+		 (props.facelighting_is ("flat") ? 1 : 2));
+  int fa_mode = (props.facealpha_is_double () ? 0 :
+		 (props.facealpha_is ("flat") ? 1 : 2));
+  int ec_mode = (props.edgecolor_is_rgb () ? 0 :
+		 (props.edgecolor_is ("flat") ? 1 :
+		  (props.edgecolor_is ("interp") ? 2 : -1)));
+  int el_mode = (props.edgelighting_is ("none") ? 0 :
+		 (props.edgelighting_is ("flat") ? 1 : 2));
+  int ea_mode = (props.edgealpha_is_double () ? 0 :
+		 (props.edgealpha_is ("flat") ? 1 : 2));
+
+  Matrix fcolor = (fc_mode == 3 ? Matrix (1, 3, 1.0) : props.get_facecolor_rgb ());
+  Matrix ecolor = props.get_edgecolor_rgb ();
+
+  float as = props.get_ambientstrength ();
+  float ds = props.get_diffusestrength ();
+  float ss = props.get_specularstrength ();
+  float se = props.get_specularexponent ();
+  float cb[4] = { 0.0, 0.0, 0.0, 1.0 };
+  double d = 1.0;
+
+  opengl_texture tex;
+
+  int i1, i2, j1, j2;
+  bool x_mat = (x.rows () == z.rows ());
+  bool y_mat = (y.columns () == z.columns ());
+
+  i1 = i2 = j1 = j2 = 0;
+
+  boolMatrix clip (z.dims (), false);
+
+  for (int i = 0; i < zr; i++)
+    {
+      if (x_mat)
+	i1 = i;
+
+      for (int j = 0; j < zc; j++)
+	{
+	  if (y_mat)
+	    j1 = j;
+
+	  clip(i,j) = is_nan_or_inf (x(i1,j), y(i,j1), z(i,j));
+	}
+    }
+
+  if ((fc_mode > 0 && fc_mode < 3) || ec_mode > 0)
+    c = props.get_color_data ().array_value ();
+
+  if (fa_mode > 0 || ea_mode > 0)
+    {
+      // FIXME: implement alphadata conversion
+      //a = props.get_alpha_data ();
+    }
+
+  if (fl_mode > 0 || el_mode > 0)
+    {
+      float buf[4] = { ss, ss, ss, 1 };
+
+      glMaterialfv (LIGHT_MODE, GL_SPECULAR, buf);
+      glMaterialf (LIGHT_MODE, GL_SHININESS, se);
+    }
+
+  // FIXME: good candidate for caching, transfering pixel
+  // data to OpenGL is time consuming.
+  if (fc_mode == 3)
+    tex = opengl_texture::create (props.get_color_data ());
+
+  if (! props.facecolor_is ("none"))
+    {
+      if (props.get_facealpha_double () == 1)
+	{
+	  if (fc_mode == 0 || fc_mode == 3)
+	    {
+	      glColor3dv (fcolor.data ());
+	      if (fl_mode > 0)
+		{
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = as * fcolor(i);
+		  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = ds * fcolor(i);
+		  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+		}
+	    }
+
+	  if (fl_mode > 0)
+	    glEnable (GL_LIGHTING);
+	  glShadeModel ((fc_mode == 2 || fl_mode == 2) ? GL_SMOOTH : GL_FLAT);
+	  set_polygon_offset (true, 1);
+	  if (fc_mode == 3)
+	    glEnable (GL_TEXTURE_2D);
+
+	  for (int i = 1; i < zc; i++)
+	    {
+	      if (y_mat)
+		{
+		  i1 = i-1;
+		  i2 = i;
+		}
+
+	      for (int j = 1; j < zr; j++)
+		{
+		  if (clip(j-1, i-1) || clip (j, i-1)
+		      || clip (j-1, i) || clip (j, i))
+		    continue;
+
+		  if (x_mat)
+		    {
+		      j1 = j-1;
+		      j2 = j;
+		    }
+
+		  glBegin (GL_QUADS);
+
+		  // Vertex 1
+		  if (fc_mode == 3)
+		    tex.tex_coord (double (i-1) / (zc-1), double (j-1) / (zr-1));
+		  else if (fc_mode > 0)
+		    {
+		      // FIXME: is there a smarter way to do this?
+		      for (int k = 0; k < 3; k++)
+			cb[k] = c(j-1, i-1, k);
+		      glColor3fv (cb);
+
+		      if (fl_mode > 0)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] *= as;
+			  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+			  
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = ds * c(j-1, i-1, k);
+			  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			}
+		    }
+                  if (fl_mode > 0)
+		    {
+		      d = sqrt (n(j-1,i-1,0) * n(j-1,i-1,0)
+				+ n(j-1,i-1,1) * n(j-1,i-1,1)
+				+ n(j-1,i-1,2) * n(j-1,i-1,2));
+		      glNormal3d (n(j-1,i-1,0)/d, n(j-1,i-1,1)/d, n(j-1,i-1,2)/d);
+		    }
+		  glVertex3d (x(j1,i-1), y(j-1,i1), z(j-1,i-1));
+
+		  // Vertex 2
+		  if (fc_mode == 3)
+		    tex.tex_coord (double (i) / (zc-1), double (j-1) / (zr-1));
+		  else if (fc_mode == 2)
+		    {
+		      for (int k = 0; k < 3; k++)
+			cb[k] = c(j-1, i, k);
+		      glColor3fv (cb);
+
+		      if (fl_mode > 0)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] *= as;
+			  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+			  
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = ds * c(j-1, i, k);
+			  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			}
+		    }
+
+                  if (fl_mode == 2)
+		    {
+		      d = sqrt (n(j-1,i,0) * n(j-1,i,0)
+				+ n(j-1,i,1) * n(j-1,i,1)
+				+ n(j-1,i,2) * n(j-1,i,2));
+		      glNormal3d (n(j-1,i,0)/d, n(j-1,i,1)/d, n(j-1,i,2)/d);
+		    }
+
+		  glVertex3d (x(j1,i), y(j-1,i2), z(j-1,i));
+		  
+		  // Vertex 3
+		  if (fc_mode == 3)
+		    tex.tex_coord (double (i) / (zc-1), double (j) / (zr-1));
+		  else if (fc_mode == 2)
+		    {
+		      for (int k = 0; k < 3; k++)
+			cb[k] = c(j, i, k);
+		      glColor3fv (cb);
+
+		      if (fl_mode > 0)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] *= as;
+			  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+			  
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = ds * c(j, i, k);
+			  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			}
+		    }
+		  if (fl_mode == 2)
+		    {
+		      d = sqrt (n(j,i,0) * n(j,i,0)
+				+ n(j,i,1) * n(j,i,1)
+				+ n(j,i,2) * n(j,i,2));
+		      glNormal3d (n(j,i,0)/d, n(j,i,1)/d, n(j,i,2)/d);
+		    }
+		  glVertex3d (x(j2,i), y(j,i2), z(j,i));
+
+		  // Vertex 4
+		  if (fc_mode == 3)
+		    tex.tex_coord (double (i-1) / (zc-1), double (j) / (zr-1));
+		  else if (fc_mode == 2)
+		    {
+		      for (int k = 0; k < 3; k++)
+			cb[k] = c(j, i-1, k);
+		      glColor3fv (cb);
+
+		      if (fl_mode > 0)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] *= as;
+			  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+			  
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = ds * c(j, i-1, k);
+			  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			}
+		    }
+                  if (fl_mode == 2)
+		    {
+		      d = sqrt (n(j,i-1,0) * n(j,i-1,0)
+				+ n(j,i-1,1) * n(j,i-1,1)
+				+ n(j,i-1,2) * n(j,i-1,2));
+		      glNormal3d (n(j,i-1,0)/d, n(j,i-1,1)/d, n(j,i-1,2)/d);
+		    }
+		  glVertex3d (x(j2,i-1), y(j,i1), z(j,i-1));
+
+		  glEnd ();
+		}
+	    }
+
+	  set_polygon_offset (false);
+	  if (fc_mode == 3)
+	    glDisable (GL_TEXTURE_2D);
+
+	  if (fl_mode > 0)
+	    glDisable (GL_LIGHTING);
+	}
+      else
+	{
+	  // FIXME: implement transparency
+	}
+    }
+
+  if (! props.edgecolor_is ("none"))
+    {
+      if (props.get_edgealpha_double () == 1)
+	{
+	  if (ec_mode == 0)
+	    {
+	      glColor3dv (ecolor.data ());
+	      if (fl_mode > 0)
+		{
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = as * ecolor(i);
+		  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = ds * ecolor(i);
+		  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+		}
+	    }
+
+	  if (el_mode > 0)
+	    glEnable (GL_LIGHTING);
+	  glShadeModel ((ec_mode == 2 || el_mode == 2) ? GL_SMOOTH : GL_FLAT);
+
+	  set_linestyle (props.get_linestyle (), false);
+	  set_linewidth (props.get_linewidth ());
+
+	  // Mesh along Y-axis
+
+	  if (props.meshstyle_is ("both") || props.meshstyle_is ("column"))
+	    {
+	      for (int i = 0; i < zc; i++)
+		{
+		  if (y_mat)
+		    {
+		      i1 = i-1;
+		      i2 = i;
+		    }
+
+		  for (int j = 1; j < zr; j++)
+		    {
+		      if (clip(j-1,i) || clip(j,i))
+			continue;
+
+		      if (x_mat)
+			{
+			  j1 = j-1;
+			  j2 = j;
+			}
+
+		      glBegin (GL_LINES);
+
+		      // Vertex 1
+		      if (ec_mode > 0)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = c(j-1, i, k);
+			  glColor3fv (cb);
+
+			  if (fl_mode > 0)
+			    {
+			      for (int k = 0; k < 3; k++)
+				cb[k] *= as;
+			      glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+			      for (int k = 0; k < 3; k++)
+				cb[k] = ds * c(j-1, i, k);
+			      glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			    }
+			}
+		      if (el_mode > 0)
+			{
+			  d = sqrt (n(j-1,i,0) * n(j-1,i,0)
+				    + n(j-1,i,1) * n(j-1,i,1)
+				    + n(j-1,i,2) * n(j-1,i,2));
+			  glNormal3d (n(j-1,i,0)/d, n(j-1,i,1)/d, n(j-1,i,2)/d);
+			}
+		      glVertex3d (x(j1,i), y(j-1,i2), z(j-1,i));
+
+		      // Vertex 2
+		      if (ec_mode == 2)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = c(j, i, k);
+			  glColor3fv (cb);
+
+			  if (fl_mode > 0)
+			    {
+			      for (int k = 0; k < 3; k++)
+				cb[k] *= as;
+			      glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+			      for (int k = 0; k < 3; k++)
+				cb[k] = ds * c(j, i, k);
+			      glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			    }
+			}
+		      if (el_mode == 2)
+		        {
+			  d = sqrt (n(j,i,0) * n(j,i,0)
+				    + n(j,i,1) * n(j,i,1)
+				    + n(j,i,2) * n(j,i,2));
+			  glNormal3d (n(j,i,0)/d, n(j,i,1)/d, n(j,i,2)/d);
+			}
+		      glVertex3d (x(j2,i), y(j,i2), z(j,i));
+
+		      glEnd ();
+		    }
+		}
+	    }
+
+	  // Mesh along X-axis
+
+	  if (props.meshstyle_is ("both") || props.meshstyle_is ("row"))
+	    {
+	      for (int j = 0; j < zr; j++)
+		{
+		  if (x_mat)
+		    {
+		      j1 = j-1;
+		      j2 = j;
+		    }
+
+		  for (int i = 1; i < zc; i++)
+		    {
+		      if (clip(j,i-1) || clip(j,i))
+			continue;
+
+		      if (y_mat)
+			{
+			  i1 = i-1;
+			  i2 = i;
+			}
+
+		      glBegin (GL_LINES);
+
+		      // Vertex 1
+		      if (ec_mode > 0)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = c(j, i-1, k);
+			  glColor3fv (cb);
+
+			  if (fl_mode > 0)
+			    {
+			      for (int k = 0; k < 3; k++)
+				cb[k] *= as;
+			      glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+			      for (int k = 0; k < 3; k++)
+				cb[k] = ds * c(j, i-1, k);
+			      glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			    }
+			}
+		      if (el_mode > 0)
+                        {
+			  d = sqrt (n(j,i-1,0) * n(j,i-1,0)
+				    + n(j,i-1,1) * n(j,i-1,1)
+				    + n(j,i-1,2) * n(j,i-1,2));
+			  glNormal3d (n(j,i-1,0)/d, n(j,i-1,1)/d, n(j,i-1,2)/d);
+			}
+		      glVertex3d (x(j2,i-1), y(j,i1), z(j,i-1));
+		      
+		      // Vertex 2
+		      if (ec_mode == 2)
+			{
+			  for (int k = 0; k < 3; k++)
+			    cb[k] = c(j, i, k);
+			  glColor3fv (cb);
+
+			  if (fl_mode > 0)
+			    {
+			      for (int k = 0; k < 3; k++)
+				cb[k] *= as;
+			      glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+			      for (int k = 0; k < 3; k++)
+				cb[k] = ds * c(j, i, k);
+			      glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+			    }
+			}
+		      if (el_mode == 2)
+		        {
+			  d = sqrt (n(j,i,0) * n(j,i,0)
+				    + n(j,i,1) * n(j,i,1)
+				    + n(j,i,2) * n(j,i,2));
+			  glNormal3d (n(j,i,0)/d, n(j,i,1)/d, n(j,i,2)/d);
+			}
+		      glVertex3d (x(j2,i), y(j,i2), z(j,i));
+		      
+		      glEnd ();
+		    }
+		}
+	    }
+
+	  set_linestyle ("-");
+	  set_linewidth (0.5);
+
+	  if (el_mode > 0)
+	    glDisable (GL_LIGHTING);
+	}
+      else
+	{
+	  // FIXME: implement transparency
+	}
+    }
+
+  if (! props.marker_is ("none") &&
+      ! (props.markeredgecolor_is ("none")
+	 && props.markerfacecolor_is ("none")))
+    {
+      // FIXME: check how transparency should be handled in markers
+      // FIXME: check what to do with marker facecolor set to auto
+      //        and facecolor set to none.
+
+      bool do_edge = ! props.markeredgecolor_is ("none");
+      bool do_face = ! props.markerfacecolor_is ("none");
+
+      Matrix mecolor = props.get_markeredgecolor_rgb ();
+      Matrix mfcolor = props.get_markerfacecolor_rgb ();
+      Matrix cc (1, 3, 0.0);
+
+      if (mecolor.numel () == 0 && props.markeredgecolor_is ("auto"))
+	{
+	  mecolor = props.get_edgecolor_rgb ();
+	  do_edge = ! props.edgecolor_is ("none");
+	}
+
+      if (mfcolor.numel () == 0 && props.markerfacecolor_is ("auto"))
+	{
+	  mfcolor = props.get_facecolor_rgb ();
+	  do_face = ! props.facecolor_is ("none");
+	}
+
+      if ((mecolor.numel () == 0 || mfcolor.numel () == 0)
+	  && c.numel () == 0)
+	c = props.get_color_data ().array_value ();
+
+      init_marker (props.get_marker (), props.get_markersize (),
+		   props.get_linewidth ());
+
+      for (int i = 0; i < zc; i++)
+	{
+	  if (y_mat)
+	    i1 = i;
+	  
+	  for (int j = 0; j < zr; j++)
+	    {
+	      if (clip(j,i))
+		continue;
+
+	      if (x_mat)
+		j1 = j;
+
+	      if ((do_edge && mecolor.numel () == 0)
+		  || (do_face && mfcolor.numel () == 0))
+		{
+		  for (int k = 0; k < 3; k++)
+		    cc(k) = c(j,i,k);
+		}
+
+	      Matrix lc = (do_edge ? (mecolor.numel () == 0 ? cc : mecolor) : Matrix ());
+	      Matrix fc = (do_face ? (mfcolor.numel () == 0 ? cc : mfcolor) : Matrix ());
+
+	      draw_marker (x(j1,i), y(j,i1), z(j,i), lc, fc);
+	    }
+	}
+
+      end_marker ();
+    }
+}
+
+// FIXME: global optimization (rendering, data structures...), there
+// is probably a smarter/faster/less-memory-consuming way to do this.
+void
+opengl_renderer::draw (const patch::properties &props)
+{
+  Matrix f = props.get_faces ().matrix_value ();
+  Matrix v = xform.scale (props.get_vertices ().matrix_value ());
+  Matrix c;
+  Matrix n = props.get_vertexnormals ().matrix_value ();
+  Matrix a;
+
+  int nv = v.rows ();
+  // int vmax = v.columns ();
+  int nf = f.rows ();
+  int fcmax = f.columns ();
+
+  bool has_z = (v.columns () > 2);
+  bool has_facecolor = false;
+  bool has_facealpha = false;
+
+  int fc_mode = (props.facecolor_is_rgb () ? 0 :
+		 (props.facecolor_is("flat") ? 1 : 2));
+  int fl_mode = (props.facelighting_is ("none") ? 0 :
+		 (props.facelighting_is ("flat") ? 1 : 2));
+  int fa_mode = (props.facealpha_is_double () ? 0 :
+		 (props.facealpha_is ("flat") ? 1 : 2));
+  int ec_mode = (props.edgecolor_is_rgb () ? 0 :
+		 (props.edgecolor_is("flat") ? 1 : 2));
+  int el_mode = (props.edgelighting_is ("none") ? 0 :
+		 (props.edgelighting_is ("flat") ? 1 : 2));
+  int ea_mode = (props.edgealpha_is_double () ? 0 :
+		 (props.edgealpha_is ("flat") ? 1 : 2));
+
+  Matrix fcolor = props.get_facecolor_rgb ();
+  Matrix ecolor = props.get_edgecolor_rgb ();
+  
+  float as = props.get_ambientstrength ();
+  float ds = props.get_diffusestrength ();
+  float ss = props.get_specularstrength ();
+  float se = props.get_specularexponent ();
+
+  boolMatrix clip (1, nv, false);
+
+  if (has_z)
+    for (int i = 0; i < nv; i++)
+      clip(i) = is_nan_or_inf (v(i,0), v(i,1), v(i,2));
+  else
+    for (int i = 0; i < nv; i++)
+      clip(i) = is_nan_or_inf (v(i,0), v(i,1), 0);
+
+  boolMatrix clip_f (1, nf, false);
+  Array<int> count_f (nf, 0);
+
+  for (int i = 0; i < nf; i++)
+    {
+      bool fclip = false;
+      int count = 0;
+
+      for (int j = 0; j < fcmax && ! xisnan (f(i,j)); j++, count++)
+	fclip = (fclip || clip(int (f(i,j) - 1)));
+
+      clip_f(i) = fclip;
+      count_f(i) = count;
+    }
+
+  if (fc_mode > 0 || ec_mode > 0)
+    {
+      c = props.get_color_data ().matrix_value ();
+
+      if (c.rows () == 1)
+	{
+	  // Single color specifications, we can simplify a little bit
+	  
+	  if (fc_mode > 0)
+	    {
+	      fcolor = c;
+	      fc_mode = 0;
+	    }
+
+	  if (ec_mode > 0)
+	    {
+	      ecolor = c;
+	      ec_mode = 0;
+	    }
+
+	  c = Matrix ();
+	}
+      else
+	has_facecolor = ((c.numel () > 0) && (c.rows () == f.rows ()));
+    }
+
+  if (fa_mode > 0 || ea_mode > 0)
+    {
+      // FIXME: retrieve alpha data from patch object
+      //a = props.get_alpha_data ();
+      has_facealpha = ((a.numel () > 0) && (a.rows () == f.rows ()));
+    }
+
+  octave_idx_type fr = f.rows ();
+  std::vector<vertex_data> vdata (f.numel ());
+
+  for (int i = 0; i < nf; i++)
+    for (int j = 0; j < count_f(i); j++)
+      {
+	int idx = int (f(i,j) - 1);
+
+	Matrix vv (1, 3, 0.0);
+	Matrix cc;
+	Matrix nn(1, 3, 0.0);
+	double aa = 1.0;
+
+	vv(0) = v(idx,0); vv(1) = v(idx,1);
+	if (has_z)
+	  vv(2) = v(idx,2);
+	// FIXME: uncomment when patch object has normal computation
+	//nn(0) = n(idx,0); nn(1) = n(idx,1); nn(2) = n(idx,2);
+	if (c.numel () > 0)
+	  {
+	    cc.resize (1, 3);
+	    if (has_facecolor)
+	      cc(0) = c(i,0), cc(1) = c(i,1), cc(2) = c(i,2);
+	    else
+	      cc(0) = c(idx,0), cc(1) = c(idx,1), cc(2) = c(idx,2);
+	  }
+	if (a.numel () > 0)
+	  {
+	    if (has_facealpha)
+	      aa = a(i);
+	    else
+	      aa = a(idx);
+	  }
+
+	vdata[i+j*fr] =
+	    vertex_data (vv, cc, nn, aa, as, ds, ss, se);
+      }
+
+  if (fl_mode > 0 || el_mode > 0)
+    {
+      float buf[4] = { ss, ss, ss, 1 };
+
+      glMaterialfv (LIGHT_MODE, GL_SPECULAR, buf);
+      glMaterialf (LIGHT_MODE, GL_SHININESS, se);
+    }
+
+  if (! props.facecolor_is ("none"))
+    {
+      // FIXME: adapt to double-radio property
+      if (props.get_facealpha_double () == 1)
+	{
+	  if (fc_mode == 0)
+	    {
+	      glColor3dv (fcolor.data ());
+	      if (fl_mode > 0)
+		{
+		  float cb[4] = { 0, 0, 0, 1 };
+
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = (as * fcolor(i));
+		  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = ds * fcolor(i);
+		  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+		}
+	    }
+
+	  if (fl_mode > 0)
+	    glEnable (GL_LIGHTING);
+
+	  // FIXME: use __index__ property from patch object
+	  patch_tesselator tess (this, fc_mode, fl_mode, 0);
+
+	  for (int i = 0; i < nf; i++)
+	    {
+	      if (clip_f(i))
+		continue;
+
+	      tess.begin_polygon (true);
+	      tess.begin_contour ();
+
+	      for (int j = 0; j < count_f(i); j++)
+		{
+		  vertex_data::vertex_data_rep *vv = vdata[i+j*fr].get_rep ();
+	
+		  tess.add_vertex (vv->coords.fortran_vec (), vv);
+		}
+
+	      tess.end_contour ();
+	      tess.end_polygon ();
+	    }
+
+	  if (fl_mode > 0)
+	    glDisable (GL_LIGHTING);
+	}
+      else
+	{
+	  // FIXME: implement transparency
+	}
+    }
+
+  if (! props.edgecolor_is ("none"))
+    {
+      // FIXME: adapt to double-radio property
+      if (props.get_edgealpha_double () == 1)
+	{
+	  if (ec_mode == 0)
+	    {
+	      glColor3dv (ecolor.data ());
+	      if (el_mode > 0)
+		{
+		  float cb[4] = { 0, 0, 0, 1 };
+
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = (as * ecolor(i));
+		  glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+		  for (int i = 0; i < 3; i++)
+		    cb[i] = ds * ecolor(i);
+		  glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+		}
+	    }
+
+	  if (el_mode > 0)
+	    glEnable (GL_LIGHTING);
+
+	  set_linestyle (props.get_linestyle (), false);
+	  set_linewidth (props.get_linewidth ());
+
+	  // FIXME: use __index__ property from patch object; should we
+	  // offset patch contour as well?
+	  patch_tesselator tess (this, ec_mode, el_mode);
+
+	  for (int i = 0; i < nf; i++)
+	    {
+	      if (clip_f(i))
+		continue;
+
+	      tess.begin_polygon (false);
+	      tess.begin_contour ();
+
+	      for (int j = 0; j < count_f(i); j++)
+		{
+		  vertex_data::vertex_data_rep *vv = vdata[i+j*fr].get_rep ();
+	
+		  tess.add_vertex (vv->coords.fortran_vec (), vv);
+		}
+
+	      tess.end_contour ();
+	      tess.end_polygon ();
+	    }
+
+	  set_linestyle ("-");
+	  set_linewidth (0.5);
+
+	  if (el_mode > 0)
+	    glDisable (GL_LIGHTING);
+	}
+      else
+	{
+	  // FIXME: implement transparency
+	}
+    }
+
+  if (! props.marker_is ("none") &&
+      ! (props.markeredgecolor_is ("none") && props.markerfacecolor_is ("none")))
+    {
+      bool do_edge = ! props.markeredgecolor_is ("none");
+      bool do_face = ! props.markerfacecolor_is ("none");
+
+      Matrix mecolor = props.get_markeredgecolor_rgb ();
+      Matrix mfcolor = props.get_markerfacecolor_rgb ();
+      Matrix cc (1, 3, 0.0);
+
+      if (mecolor.numel () == 0 && props.markeredgecolor_is ("auto"))
+	{
+	  mecolor = props.get_edgecolor_rgb ();
+	  do_edge = ! props.edgecolor_is ("none");
+	}
+
+      if (mfcolor.numel () == 0 && props.markerfacecolor_is ("auto"))
+	{
+	  mfcolor = props.get_facecolor_rgb ();
+	  do_face = ! props.facecolor_is ("none");
+	}
+
+      init_marker (props.get_marker (), props.get_markersize (),
+		   props.get_linewidth ());
+
+      for (int i = 0; i < nf; i++)
+	for (int j = 0; j < count_f(i); j++)
+	  {
+	    int idx = int (f(i,j) - 1);
+
+	    if (clip(idx))
+	      continue;
+
+	    Matrix lc = (do_edge ? (mecolor.numel () == 0 ?
+				    vdata[i+j*fr].get_rep ()->color : mecolor)
+			 : Matrix ());
+	    Matrix fc = (do_face ? (mfcolor.numel () == 0 ?
+				    vdata[i+j*fr].get_rep ()->color : mfcolor)
+			 : Matrix ());
+
+	    draw_marker (v(idx,0), v(idx,1), (has_z ? v(idx,2) : 0), lc, fc);
+	  }
+
+      end_marker ();
+    }
+}
+
+void
+opengl_renderer::draw (const hggroup::properties &props)
+{
+  draw (props.get_children ());
+}
+
+void
+opengl_renderer::set_viewport (int w, int h)
+{
+  glViewport (0, 0, w, h);
+}
+
+void
+opengl_renderer::set_color (const Matrix& c)
+{
+  glColor3dv (c.data ());
+}
+
+void
+opengl_renderer::set_polygon_offset (bool on, double offset)
+{
+  if (on)
+    {
+      glPolygonOffset (offset, offset);
+      glEnable (GL_POLYGON_OFFSET_FILL);
+      glEnable (GL_POLYGON_OFFSET_LINE);
+    }
+  else
+    {
+      glDisable (GL_POLYGON_OFFSET_FILL);
+      glDisable (GL_POLYGON_OFFSET_LINE);
+    }
+}
+
+void
+opengl_renderer::set_linewidth (float w)
+{
+  glLineWidth (w);
+}
+
+void
+opengl_renderer::set_linestyle (const std::string& s, bool use_stipple)
+{
+  bool solid = false;
+
+  if (s == "-")
+    {
+      glLineStipple (1, static_cast<unsigned short> (0xFFFF));
+      solid = true;
+    }
+  else if (s == ":")
+    glLineStipple (1, static_cast<unsigned short> (0x8888));
+  else if (s == "--")
+    glLineStipple (1, static_cast<unsigned short> (0x0FFF));
+  else if (s == "-.")
+    glLineStipple (1, static_cast<unsigned short> (0x020F));
+  else
+    glLineStipple (1, static_cast<unsigned short> (0x0000));
+
+  if (solid && ! use_stipple)
+    glDisable (GL_LINE_STIPPLE);
+  else
+    glEnable (GL_LINE_STIPPLE);
+}
+
+void
+opengl_renderer::set_clipbox (double x1, double x2, double y1, double y2,
+			      double z1, double z2)
+{
+  double dx = (x2-x1);
+  double dy = (y2-y1);
+  double dz = (z2-z1);
+
+  x1 -= 0.001*dx; x2 += 0.001*dx;
+  y1 -= 0.001*dy; y2 += 0.001*dy;
+  z1 -= 0.001*dz; z2 += 0.001*dz;
+
+  ColumnVector p (4, 0.0);
+
+  p(0) = -1; p(3) = x2;
+  glClipPlane (GL_CLIP_PLANE0, p.data ());
+  p(0) = 1; p(3) = -x1;
+  glClipPlane (GL_CLIP_PLANE1, p.data ());
+  p(0) = 0; p(1) = -1; p(3) = y2;
+  glClipPlane (GL_CLIP_PLANE2, p.data ());
+  p(1) = 1; p(3) = -y1;
+  glClipPlane (GL_CLIP_PLANE3, p.data ());
+  p(1) = 0; p(2) = -1; p(3) = z2;
+  glClipPlane (GL_CLIP_PLANE4, p.data ());
+  p(2) = 1; p(3) = -z1;
+  glClipPlane (GL_CLIP_PLANE5, p.data ());
+
+  xmin = x1; xmax = x2;
+  ymin = y1; ymax = y2;
+  zmin = z1; zmax = z2;
+}
+
+void
+opengl_renderer::set_clipping (bool enable)
+{
+  bool has_clipping = (glIsEnabled (GL_CLIP_PLANE0) == GL_TRUE);
+
+  if (enable != has_clipping)
+    {
+      if (enable)
+        for (int i = 0; i < 6; i++)
+          glEnable (GL_CLIP_PLANE0+i);
+      else
+        for (int i = 0; i < 6; i++)
+          glDisable (GL_CLIP_PLANE0+i);
+    }
+}
+
+void
+opengl_renderer::init_marker (const std::string& m, double size, float width)
+{
+#if defined (HAVE_FRAMEWORK_OPENGL)
+  GLint vw[4];
+#else
+  int vw[4];
+#endif
+
+  glGetIntegerv (GL_VIEWPORT, vw);
+
+  glMatrixMode (GL_PROJECTION);
+  glPushMatrix ();
+  glLoadIdentity ();
+  glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
+  glMatrixMode (GL_MODELVIEW);
+  glPushMatrix ();
+
+  set_clipping (false);
+  set_linewidth (width);
+
+  marker_id = make_marker_list (m, size, false);
+  filled_marker_id = make_marker_list (m, size, true);
+}
+
+void
+opengl_renderer::end_marker (void)
+{
+  glDeleteLists (marker_id, 1);
+  glDeleteLists (filled_marker_id, 1);
+
+  glMatrixMode (GL_MODELVIEW);
+  glPopMatrix ();
+  glMatrixMode (GL_PROJECTION);
+  glPopMatrix ();
+  set_linewidth (0.5f);
+}
+
+void
+opengl_renderer::draw_marker (double x, double y, double z,
+			      const Matrix& lc, const Matrix& fc)
+{
+  ColumnVector tmp = xform.transform (x, y, z, false);
+  
+  glLoadIdentity ();
+  glTranslated (tmp(0), tmp(1), -tmp(2));
+
+  if (filled_marker_id > 0 && fc.numel () > 0)
+    {
+      glColor3dv (fc.data ());
+      set_polygon_offset (true, -1.0);
+      glCallList (filled_marker_id);
+      if (lc.numel () > 0)
+	{
+	  glColor3dv (lc.data ());
+	  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
+	  glEdgeFlag (GL_TRUE);
+	  set_polygon_offset (true, -2.0);
+	  glCallList (filled_marker_id);
+	  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+	}
+      set_polygon_offset (false);
+    }
+  else if (marker_id > 0 && lc.numel () > 0)
+    {
+      glColor3dv (lc.data ());
+      glCallList (marker_id);
+    }
+}
+
+unsigned int
+opengl_renderer::make_marker_list (const std::string& marker, double size,
+				   bool filled) const
+{
+  char c = marker[0];
+
+  if (filled && (c == '+' || c == 'x' || c == '*' || c == '.'))
+    return 0;
+
+  unsigned int ID = glGenLists (1);
+  double sz = size * backend.get_screen_resolution () / 72.0;
+
+  // constants for the * marker
+  const double sqrt2d4 = 0.35355339059327;
+  double tt = sz*sqrt2d4;
+
+  glNewList (ID, GL_COMPILE);
+
+  switch (marker[0])
+    {
+    case '+':
+      glBegin (GL_LINES);
+      glVertex2f (-sz/2 ,0     );
+      glVertex2f (sz/2  ,0     );
+      glVertex2f (0     ,-sz/2 );
+      glVertex2f (0     ,sz/2  );
+      glEnd ();
+      break;
+    case 'x':
+      glBegin(GL_LINES);
+      glVertex2f (-sz/2 ,-sz/2);
+      glVertex2f (sz/2  ,sz/2 );
+      glVertex2f (-sz/2 ,sz/2 );
+      glVertex2f (sz/2 ,-sz/2 );
+      glEnd ();
+      break;
+    case '*':
+      glBegin (GL_LINES);
+      glVertex2f (-sz/2 ,0     );
+      glVertex2f (sz/2  ,0     );
+      glVertex2f (0     ,-sz/2 );
+      glVertex2f (0     ,sz/2  );
+      glVertex2f (-tt   ,-tt   );
+      glVertex2f (+tt   ,+tt   );
+      glVertex2f (-tt   ,+tt   );
+      glVertex2f (+tt   ,-tt   );
+      glEnd ();
+      break;
+    case '.':
+      glBegin (GL_POLYGON);
+      glVertex2f (-sz/10, -sz/10);
+      glVertex2f (-sz/10, sz/10 );
+      glVertex2f (sz/10 , sz/10 );
+      glVertex2f (sz/10 , -sz/10);
+      glEnd ();
+      break;
+    case 's':
+      glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+      glVertex2d (-sz/2, -sz/2);
+      glVertex2d (-sz/2,  sz/2);
+      glVertex2d ( sz/2,  sz/2);
+      glVertex2d ( sz/2, -sz/2);
+      glEnd();
+      break;
+    case 'o':
+      {
+	double ang_step = M_PI / 5;
+
+	glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+	for (double ang = 0; ang < (2*M_PI); ang += ang_step)
+	  glVertex2d (sz*cos(ang)/2, sz*sin(ang)/2);
+	glEnd ();
+      }
+      break;
+    case 'd':
+      glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+      glVertex2d (    0, -sz/2);
+      glVertex2d ( sz/2,     0);
+      glVertex2d (    0,  sz/2);
+      glVertex2d (-sz/2,     0);
+      glEnd();
+      break;
+    case '^':
+      glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+      glVertex2f (0     ,  sz/2);
+      glVertex2f (sz/2  , -sz/2);
+      glVertex2f (-sz/2 , -sz/2);
+      glEnd ();
+      break;
+    case 'v':
+      glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+      glVertex2f (0     ,-sz/2);
+      glVertex2f (-sz/2 ,sz/2 );
+      glVertex2f (sz/2  ,sz/2 );
+      glEnd ();
+      break;
+    case '>':
+      glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+      glVertex2f (sz/2  ,0    );
+      glVertex2f (-sz/2 ,sz/2 );
+      glVertex2f (-sz/2 ,-sz/2);
+      glEnd ();
+      break;
+    case '<':
+      glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
+      glVertex2f (-sz/2 ,0    );
+      glVertex2f (sz/2  ,-sz/2);
+      glVertex2f (sz/2  ,sz/2 );
+      glEnd ();
+      break;
+    default:
+      warning ("opengl_renderer: unsupported marker `%s'",
+	       marker.c_str ());
+      break;
+    }
+
+  glEndList ();
+
+  return ID;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/gl-render.h b/src/gl-render.h
new file mode 100644
index 0000000..f65a9d8
--- /dev/null
+++ b/src/gl-render.h
@@ -0,0 +1,145 @@
+/*
+
+Copyright (C) 2008, 2009 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (gl_render_h)
+#define gl_render_h 1
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#ifdef HAVE_GL_GL_H
+#include <GL/gl.h>
+#elif defined HAVE_OPENGL_GL_H || defined HAVE_FRAMEWORK_OPENGL
+#include <OpenGL/gl.h>
+#endif
+
+#ifdef HAVE_GL_GLU_H
+#include <GL/glu.h>
+#elif defined HAVE_OPENGL_GLU_H || defined HAVE_FRAMEWORK_OPENGL
+#include <OpenGL/glu.h>
+#endif
+
+#include "graphics.h"
+
+class
+OCTINTERP_API
+opengl_renderer
+{
+public:
+  opengl_renderer (void) { }
+
+  virtual ~opengl_renderer (void) { }
+
+  virtual void draw (const graphics_handle& h)
+    { draw (gh_manager::get_object (h)); }
+
+  virtual void draw (const graphics_object& go);
+
+  virtual void draw (const Matrix& hlist)
+    {
+      int len = hlist.length ();
+
+      for (int i = 0; i < len; i++)
+	{
+	  graphics_handle h = gh_manager::lookup (hlist(i));
+
+	  if (h.ok ())
+	    draw (h);
+	}
+    }
+
+  virtual void set_viewport (int w, int h);
+
+protected:
+  virtual void draw (const figure::properties& props);
+  virtual void draw (const axes::properties& props);
+  virtual void draw (const line::properties& props);
+  virtual void draw (const surface::properties& props);
+  virtual void draw (const patch::properties& props);
+  virtual void draw (const hggroup::properties& props);
+
+  virtual void set_color (const Matrix& c);
+  virtual void set_polygon_offset (bool on, double offset = 0.0);
+  virtual void set_linewidth (float w);
+  virtual void set_linestyle (const std::string& s, bool stipple = false);
+  virtual void set_clipbox (double x1, double x2, double y1, double y2,
+			    double z1, double z2);
+  virtual void set_clipping (bool on);
+
+  virtual void init_marker (const std::string& m, double size, float width);
+  virtual void end_marker (void);
+  virtual void draw_marker (double x, double y, double z,
+			    const Matrix& lc, const Matrix& fc);
+
+private:
+  opengl_renderer (const opengl_renderer&) { }
+
+  opengl_renderer& operator = (const opengl_renderer&)
+    { return *this; }
+
+  bool is_nan_or_inf (double x, double y, double z) const
+    {
+      return (xisnan (x) || xisnan (y) || xisnan (z)
+	      || xisinf (x) || xisinf (y) || xisinf (z));
+    }
+
+  octave_uint8 clip_code (double x, double y, double z) const
+    {
+      return ((x < xmin ? 1 : 0)
+	      | (x > xmax ? 1 : 0) << 1
+	      | (y < ymin ? 1 : 0) << 2
+	      | (y > ymax ? 1 : 0) << 3
+	      | (z < zmin ? 1 : 0) << 4
+	      | (z > zmax ? 1 : 0) << 5
+	      | (is_nan_or_inf (x, y, z) ? 0 : 1) << 6);
+    }
+
+  unsigned int make_marker_list (const std::string& m, double size,
+				 bool filled) const;
+
+private:
+  // the backend associated with the figure being rendered
+  graphics_backend backend;
+
+  // axes transformation data
+  graphics_xform xform;
+
+  // axis limits in model scaled coordinate
+  double xmin, xmax;
+  double ymin, ymax;
+  double zmin, zmax;
+
+  // Z projection limits in windows coordinate
+  double xZ1, xZ2;
+
+  // call lists identifiers for markers
+  unsigned int marker_id, filled_marker_id;
+
+  // camera information for primitive sorting
+  ColumnVector camera_pos, camera_dir;
+
+private:
+  class patch_tesselator;
+};
+
+#endif
diff --git a/src/graphics-props.cc b/src/graphics-props.cc
new file mode 100644
index 0000000..c81c30d
--- /dev/null
+++ b/src/graphics-props.cc
@@ -0,0 +1,4391 @@
+// DO NOT EDIT!  Generated automatically by genprops.awk.
+
+// ******** base ********
+
+base_properties::base_properties (const std::string& ty, const graphics_handle& mh, const graphics_handle& p)
+  :     beingdeleted ("beingdeleted", mh, "off"),
+    busyaction ("busyaction", mh, "{queue}|cancel"),
+    buttondownfcn ("buttondownfcn", mh, Matrix ()),
+    children (Matrix ()),
+    clipping ("clipping", mh, "on"),
+    createfcn ("createfcn", mh, Matrix ()),
+    deletefcn ("deletefcn", mh, Matrix ()),
+    handlevisibility ("handlevisibility", mh, "{on}|callback|off"),
+    hittest ("hittest", mh, "on"),
+    interruptible ("interruptible", mh, "on"),
+    parent ("parent", mh, p),
+    selected ("selected", mh, "off"),
+    selectionhighlight ("selectionhighlight", mh, "on"),
+    tag ("tag", mh, ""),
+    type ("type", mh, ty),
+    userdata ("userdata", mh, Matrix ()),
+    visible ("visible", mh, "on"),
+    __modified__ ("__modified__", mh, "on"),
+    __myhandle__ (mh),
+    uicontextmenu ("uicontextmenu", mh, graphics_handle ())
+{
+  beingdeleted.set_id (BEINGDELETED);
+  busyaction.set_id (BUSYACTION);
+  buttondownfcn.set_id (BUTTONDOWNFCN);
+  clipping.set_id (CLIPPING);
+  createfcn.set_id (CREATEFCN);
+  deletefcn.set_id (DELETEFCN);
+  handlevisibility.set_id (HANDLEVISIBILITY);
+  hittest.set_id (HITTEST);
+  interruptible.set_id (INTERRUPTIBLE);
+  parent.set_id (PARENT);
+  selected.set_id (SELECTED);
+  selectionhighlight.set_id (SELECTIONHIGHLIGHT);
+  tag.set_id (TAG);
+  type.set_id (TYPE);
+  userdata.set_id (USERDATA);
+  visible.set_id (VISIBLE);
+  __modified__.set_id (__MODIFIED__);
+  uicontextmenu.set_id (UICONTEXTMENU);
+  init ();
+}
+
+void
+base_properties::set (const caseless_str& pname, const std::string& cname, const octave_value& val)
+{
+  if (pname.compare ("beingdeleted"))
+    set_beingdeleted (val);
+  else if (pname.compare ("busyaction"))
+    set_busyaction (val);
+  else if (pname.compare ("buttondownfcn"))
+    set_buttondownfcn (val);
+  else if (pname.compare ("children"))
+    set_children (val);
+  else if (pname.compare ("clipping"))
+    set_clipping (val);
+  else if (pname.compare ("createfcn"))
+    set_createfcn (val);
+  else if (pname.compare ("deletefcn"))
+    set_deletefcn (val);
+  else if (pname.compare ("handlevisibility"))
+    set_handlevisibility (val);
+  else if (pname.compare ("hittest"))
+    set_hittest (val);
+  else if (pname.compare ("interruptible"))
+    set_interruptible (val);
+  else if (pname.compare ("parent"))
+    set_parent (val);
+  else if (pname.compare ("selected"))
+    set_selected (val);
+  else if (pname.compare ("selectionhighlight"))
+    set_selectionhighlight (val);
+  else if (pname.compare ("tag"))
+    set_tag (val);
+  else if (pname.compare ("userdata"))
+    set_userdata (val);
+  else if (pname.compare ("visible"))
+    set_visible (val);
+  else if (pname.compare ("__modified__"))
+    set___modified__ (val);
+  else if (pname.compare ("uicontextmenu"))
+    set_uicontextmenu (val);
+  else
+    set_dynamic (pname, cname, val);
+}
+
+octave_value
+base_properties::get (bool all) const
+{
+  Octave_map m = get_dynamic (all).map_value ();
+
+  m.assign ("beingdeleted", get_beingdeleted ());
+  m.assign ("busyaction", get_busyaction ());
+  m.assign ("buttondownfcn", get_buttondownfcn ());
+  m.assign ("children", get_children ());
+  m.assign ("clipping", get_clipping ());
+  m.assign ("createfcn", get_createfcn ());
+  m.assign ("deletefcn", get_deletefcn ());
+  m.assign ("handlevisibility", get_handlevisibility ());
+  m.assign ("hittest", get_hittest ());
+  m.assign ("interruptible", get_interruptible ());
+  m.assign ("parent", get_parent ().as_octave_value ());
+  m.assign ("selected", get_selected ());
+  m.assign ("selectionhighlight", get_selectionhighlight ());
+  m.assign ("tag", get_tag ());
+  m.assign ("type", get_type ());
+  m.assign ("userdata", get_userdata ());
+  m.assign ("visible", get_visible ());
+  m.assign ("__modified__", get___modified__ ());
+  if (all)
+    m.assign ("__myhandle__", get___myhandle__ ().as_octave_value ());
+  m.assign ("uicontextmenu", get_uicontextmenu ().as_octave_value ());
+
+  return m;
+}
+
+octave_value
+base_properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("beingdeleted"))
+    retval = get_beingdeleted ();
+  else if (pname.compare ("busyaction"))
+    retval = get_busyaction ();
+  else if (pname.compare ("buttondownfcn"))
+    retval = get_buttondownfcn ();
+  else if (pname.compare ("children"))
+    retval = get_children ();
+  else if (pname.compare ("clipping"))
+    retval = get_clipping ();
+  else if (pname.compare ("createfcn"))
+    retval = get_createfcn ();
+  else if (pname.compare ("deletefcn"))
+    retval = get_deletefcn ();
+  else if (pname.compare ("handlevisibility"))
+    retval = get_handlevisibility ();
+  else if (pname.compare ("hittest"))
+    retval = get_hittest ();
+  else if (pname.compare ("interruptible"))
+    retval = get_interruptible ();
+  else if (pname.compare ("parent"))
+    retval = get_parent ().as_octave_value ();
+  else if (pname.compare ("selected"))
+    retval = get_selected ();
+  else if (pname.compare ("selectionhighlight"))
+    retval = get_selectionhighlight ();
+  else if (pname.compare ("tag"))
+    retval = get_tag ();
+  else if (pname.compare ("type"))
+    retval = get_type ();
+  else if (pname.compare ("userdata"))
+    retval = get_userdata ();
+  else if (pname.compare ("visible"))
+    retval = get_visible ();
+  else if (pname.compare ("__modified__"))
+    retval = get___modified__ ();
+  else if (pname.compare ("__myhandle__"))
+    retval = get___myhandle__ ().as_octave_value ();
+  else if (pname.compare ("uicontextmenu"))
+    retval = get_uicontextmenu ().as_octave_value ();
+  else
+    retval = get_dynamic (pname);
+
+  return retval;
+}
+
+property
+base_properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("beingdeleted"))
+    return property (&beingdeleted, true);
+  else if (pname.compare ("busyaction"))
+    return property (&busyaction, true);
+  else if (pname.compare ("buttondownfcn"))
+    return property (&buttondownfcn, true);
+  else if (pname.compare ("clipping"))
+    return property (&clipping, true);
+  else if (pname.compare ("createfcn"))
+    return property (&createfcn, true);
+  else if (pname.compare ("deletefcn"))
+    return property (&deletefcn, true);
+  else if (pname.compare ("handlevisibility"))
+    return property (&handlevisibility, true);
+  else if (pname.compare ("hittest"))
+    return property (&hittest, true);
+  else if (pname.compare ("interruptible"))
+    return property (&interruptible, true);
+  else if (pname.compare ("parent"))
+    return property (&parent, true);
+  else if (pname.compare ("selected"))
+    return property (&selected, true);
+  else if (pname.compare ("selectionhighlight"))
+    return property (&selectionhighlight, true);
+  else if (pname.compare ("tag"))
+    return property (&tag, true);
+  else if (pname.compare ("type"))
+    return property (&type, true);
+  else if (pname.compare ("userdata"))
+    return property (&userdata, true);
+  else if (pname.compare ("visible"))
+    return property (&visible, true);
+  else if (pname.compare ("__modified__"))
+    return property (&__modified__, true);
+  else if (pname.compare ("uicontextmenu"))
+    return property (&uicontextmenu, true);
+  else
+    return get_property_dynamic (pname);
+}
+
+property_list::pval_map_type
+base_properties::factory_defaults (void)
+{
+  property_list::pval_map_type m;
+
+  m["beingdeleted"] = "off";
+  m["busyaction"] = "queue";
+  m["buttondownfcn"] = Matrix ();
+  m["clipping"] = "on";
+  m["createfcn"] = Matrix ();
+  m["deletefcn"] = Matrix ();
+  m["handlevisibility"] = "on";
+  m["hittest"] = "on";
+  m["interruptible"] = "on";
+  m["selected"] = "off";
+  m["selectionhighlight"] = "on";
+  m["tag"] = "";
+  m["userdata"] = Matrix ();
+  m["visible"] = "on";
+  m["__modified__"] = "on";
+  m["uicontextmenu"] = graphics_handle ().as_octave_value ();
+
+  return m;
+}
+
+bool base_properties::has_property (const std::string& pname, const std::string& cname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("beingdeleted");
+      all_properties.insert ("busyaction");
+      all_properties.insert ("buttondownfcn");
+      all_properties.insert ("children");
+      all_properties.insert ("clipping");
+      all_properties.insert ("createfcn");
+      all_properties.insert ("deletefcn");
+      all_properties.insert ("handlevisibility");
+      all_properties.insert ("hittest");
+      all_properties.insert ("interruptible");
+      all_properties.insert ("parent");
+      all_properties.insert ("selected");
+      all_properties.insert ("selectionhighlight");
+      all_properties.insert ("tag");
+      all_properties.insert ("type");
+      all_properties.insert ("userdata");
+      all_properties.insert ("visible");
+      all_properties.insert ("__modified__");
+      all_properties.insert ("__myhandle__");
+      all_properties.insert ("uicontextmenu");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || has_dynamic_property (pname, cname);
+}
+
+// ******** root_figure ********
+
+root_figure::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    currentfigure ("currentfigure", mh, graphics_handle ()),
+    callbackobject ("callbackobject", mh, graphics_handle ()),
+    screendepth ("screendepth", mh, default_screendepth ()),
+    screensize ("screensize", mh, default_screensize ()),
+    screenpixelsperinch ("screenpixelsperinch", mh, default_screenpixelsperinch ()),
+    units ("units", mh, "inches|centimeters|normalized|points|{pixels}"),
+    showhiddenhandles ("showhiddenhandles", mh, "off")
+{
+  currentfigure.set_id (CURRENTFIGURE);
+  callbackobject.set_id (CALLBACKOBJECT);
+  screendepth.set_id (SCREENDEPTH);
+  screensize.set_id (SCREENSIZE);
+  screenpixelsperinch.set_id (SCREENPIXELSPERINCH);
+  units.set_id (UNITS);
+  showhiddenhandles.set_id (SHOWHIDDENHANDLES);
+  init ();
+}
+
+void
+root_figure::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("currentfigure"))
+    set_currentfigure (val);
+  else if (pname.compare ("units"))
+    set_units (val);
+  else if (pname.compare ("showhiddenhandles"))
+    set_showhiddenhandles (val);
+  else
+    base_properties::set (pname, "root_figure", val);
+}
+
+octave_value
+root_figure::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("currentfigure", get_currentfigure ().as_octave_value ());
+  m.assign ("callbackobject", get_callbackobject ().as_octave_value ());
+  m.assign ("screendepth", get_screendepth ());
+  m.assign ("screensize", get_screensize ());
+  m.assign ("screenpixelsperinch", get_screenpixelsperinch ());
+  m.assign ("units", get_units ());
+  m.assign ("showhiddenhandles", get_showhiddenhandles ());
+
+  return m;
+}
+
+octave_value
+root_figure::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("currentfigure"))
+    retval = get_currentfigure ().as_octave_value ();
+  else if (pname.compare ("callbackobject"))
+    retval = get_callbackobject ().as_octave_value ();
+  else if (pname.compare ("screendepth"))
+    retval = get_screendepth ();
+  else if (pname.compare ("screensize"))
+    retval = get_screensize ();
+  else if (pname.compare ("screenpixelsperinch"))
+    retval = get_screenpixelsperinch ();
+  else if (pname.compare ("units"))
+    retval = get_units ();
+  else if (pname.compare ("showhiddenhandles"))
+    retval = get_showhiddenhandles ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+root_figure::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("currentfigure"))
+    return property (&currentfigure, true);
+  else if (pname.compare ("callbackobject"))
+    return property (&callbackobject, true);
+  else if (pname.compare ("screendepth"))
+    return property (&screendepth, true);
+  else if (pname.compare ("screensize"))
+    return property (&screensize, true);
+  else if (pname.compare ("screenpixelsperinch"))
+    return property (&screenpixelsperinch, true);
+  else if (pname.compare ("units"))
+    return property (&units, true);
+  else if (pname.compare ("showhiddenhandles"))
+    return property (&showhiddenhandles, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+root_figure::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["currentfigure"] = graphics_handle ().as_octave_value ();
+  m["callbackobject"] = graphics_handle ().as_octave_value ();
+  m["screendepth"] = default_screendepth ();
+  m["screensize"] = default_screensize ();
+  m["screenpixelsperinch"] = default_screenpixelsperinch ();
+  m["units"] = "pixels";
+  m["showhiddenhandles"] = "off";
+
+  return m;
+}
+
+std::string root_figure::properties::go_name ("root");
+
+bool root_figure::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("currentfigure");
+      all_properties.insert ("callbackobject");
+      all_properties.insert ("screendepth");
+      all_properties.insert ("screensize");
+      all_properties.insert ("screenpixelsperinch");
+      all_properties.insert ("units");
+      all_properties.insert ("showhiddenhandles");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "root_figure");
+}
+
+// ******** figure ********
+
+figure::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    __plot_stream__ ("__plot_stream__", mh, Matrix ()),
+    __enhanced__ ("__enhanced__", mh, "on"),
+    nextplot ("nextplot", mh, "new|{add}|replace_children|replace"),
+    closerequestfcn ("closerequestfcn", mh, "closereq"),
+    currentaxes ("currentaxes", mh, graphics_handle ()),
+    colormap ("colormap", mh, jet_colormap ()),
+    paperorientation ("paperorientation", mh, "{portrait}|landscape|rotated"),
+    color ("color", mh, color_values (1, 1, 1)),
+    alphamap ("alphamap", mh, Matrix (64, 1, 1)),
+    currentcharacter ("currentcharacter", mh, ""),
+    currentobject ("currentobject", mh, graphics_handle ()),
+    current_point ("current_point", mh, Matrix (2, 1, 0)),
+    dockcontrols ("dockcontrols", mh, "off"),
+    doublebuffer ("doublebuffer", mh, "on"),
+    filename ("filename", mh, ""),
+    integerhandle ("integerhandle", mh, "on"),
+    inverthardcopy ("inverthardcopy", mh, "off"),
+    keypressfcn ("keypressfcn", mh, Matrix ()),
+    keyreleasefcn ("keyreleasefcn", mh, Matrix ()),
+    menubar ("menubar", mh, "none|{figure}"),
+    mincolormap ("mincolormap", mh, 64),
+    name ("name", mh, ""),
+    numbertitle ("numbertitle", mh, "on"),
+    paperunits ("paperunits", mh, "{inches}|centimeters|normalized|points"),
+    paperposition ("paperposition", mh, default_figure_paperposition ()),
+    paperpositionmode ("paperpositionmode", mh, "auto|{manual}"),
+    papersize ("papersize", mh, default_figure_papersize ()),
+    papertype ("papertype", mh, "{usletter}|uslegal|a0|a1|a2|a3|a4|a5|b0|b1|b2|b3|b4|b5|arch-a|arch-b|arch-c|arch-d|arch-e|a|b|c|d|e|tabloid|<custom>"),
+    pointer ("pointer", mh, "crosshair|fullcrosshair|{arrow}|ibeam|watch|topl|topr|botl|botr|left|top|right|bottom|circle|cross|fleur|custom|hand"),
+    pointershapecdata ("pointershapecdata", mh, Matrix (16, 16, 0)),
+    pointershapehotspot ("pointershapehotspot", mh, Matrix (1, 2, 0)),
+    position ("position", mh, default_figure_position ()),
+    renderer ("renderer", mh, "{painters}|zbuffer|opengl|none"),
+    renderermode ("renderermode", mh, "{auto}|manual"),
+    resize ("resize", mh, "on"),
+    resizefcn ("resizefcn", mh, Matrix ()),
+    selectiontype ("selectiontype", mh, "{normal}|open|alt|extend"),
+    toolbar ("toolbar", mh, "none|{auto}|figure"),
+    units ("units", mh, "inches|centimeters|normalized|points|{pixels}|characters"),
+    windowbuttondownfcn ("windowbuttondownfcn", mh, Matrix ()),
+    windowbuttonmotionfcn ("windowbuttonmotionfcn", mh, Matrix ()),
+    windowbuttonupfcn ("windowbuttonupfcn", mh, Matrix ()),
+    windowbuttonwheelfcn ("windowbuttonwheelfcn", mh, Matrix ()),
+    windowstyle ("windowstyle", mh, "{normal}|modal|docked"),
+    wvisual ("wvisual", mh, ""),
+    wvisualmode ("wvisualmode", mh, "{auto}|manual"),
+    xdisplay ("xdisplay", mh, ""),
+    xvisual ("xvisual", mh, ""),
+    xvisualmode ("xvisualmode", mh, "{auto}|manual"),
+    buttondownfcn ("buttondownfcn", mh, Matrix ()),
+    __backend__ ("__backend__", mh, "gnuplot")
+{
+  __plot_stream__.set_id (__PLOT_STREAM__);
+  __plot_stream__.set_hidden (true);
+  __enhanced__.set_id (__ENHANCED__);
+  __enhanced__.set_hidden (true);
+  nextplot.set_id (NEXTPLOT);
+  closerequestfcn.set_id (CLOSEREQUESTFCN);
+  currentaxes.set_id (CURRENTAXES);
+  colormap.set_id (COLORMAP);
+  paperorientation.set_id (PAPERORIENTATION);
+  color.set_id (COLOR);
+  alphamap.set_id (ALPHAMAP);
+  currentcharacter.set_id (CURRENTCHARACTER);
+  currentobject.set_id (CURRENTOBJECT);
+  current_point.set_id (CURRENT_POINT);
+  dockcontrols.set_id (DOCKCONTROLS);
+  doublebuffer.set_id (DOUBLEBUFFER);
+  filename.set_id (FILENAME);
+  integerhandle.set_id (INTEGERHANDLE);
+  inverthardcopy.set_id (INVERTHARDCOPY);
+  keypressfcn.set_id (KEYPRESSFCN);
+  keyreleasefcn.set_id (KEYRELEASEFCN);
+  menubar.set_id (MENUBAR);
+  mincolormap.set_id (MINCOLORMAP);
+  name.set_id (NAME);
+  numbertitle.set_id (NUMBERTITLE);
+  paperunits.set_id (PAPERUNITS);
+  paperposition.set_id (PAPERPOSITION);
+  paperpositionmode.set_id (PAPERPOSITIONMODE);
+  papersize.set_id (PAPERSIZE);
+  papertype.set_id (PAPERTYPE);
+  pointer.set_id (POINTER);
+  pointershapecdata.set_id (POINTERSHAPECDATA);
+  pointershapehotspot.set_id (POINTERSHAPEHOTSPOT);
+  position.set_id (POSITION);
+  renderer.set_id (RENDERER);
+  renderermode.set_id (RENDERERMODE);
+  resize.set_id (RESIZE);
+  resizefcn.set_id (RESIZEFCN);
+  selectiontype.set_id (SELECTIONTYPE);
+  toolbar.set_id (TOOLBAR);
+  units.set_id (UNITS);
+  windowbuttondownfcn.set_id (WINDOWBUTTONDOWNFCN);
+  windowbuttonmotionfcn.set_id (WINDOWBUTTONMOTIONFCN);
+  windowbuttonupfcn.set_id (WINDOWBUTTONUPFCN);
+  windowbuttonwheelfcn.set_id (WINDOWBUTTONWHEELFCN);
+  windowstyle.set_id (WINDOWSTYLE);
+  wvisual.set_id (WVISUAL);
+  wvisualmode.set_id (WVISUALMODE);
+  xdisplay.set_id (XDISPLAY);
+  xvisual.set_id (XVISUAL);
+  xvisualmode.set_id (XVISUALMODE);
+  buttondownfcn.set_id (BUTTONDOWNFCN);
+  __backend__.set_id (__BACKEND__);
+  init ();
+}
+
+void
+figure::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("__plot_stream__"))
+    set___plot_stream__ (val);
+  else if (pname.compare ("__enhanced__"))
+    set___enhanced__ (val);
+  else if (pname.compare ("nextplot"))
+    set_nextplot (val);
+  else if (pname.compare ("closerequestfcn"))
+    set_closerequestfcn (val);
+  else if (pname.compare ("currentaxes"))
+    set_currentaxes (val);
+  else if (pname.compare ("colormap"))
+    set_colormap (val);
+  else if (pname.compare ("paperorientation"))
+    set_paperorientation (val);
+  else if (pname.compare ("color"))
+    set_color (val);
+  else if (pname.compare ("alphamap"))
+    set_alphamap (val);
+  else if (pname.compare ("dockcontrols"))
+    set_dockcontrols (val);
+  else if (pname.compare ("doublebuffer"))
+    set_doublebuffer (val);
+  else if (pname.compare ("integerhandle"))
+    set_integerhandle (val);
+  else if (pname.compare ("inverthardcopy"))
+    set_inverthardcopy (val);
+  else if (pname.compare ("keypressfcn"))
+    set_keypressfcn (val);
+  else if (pname.compare ("keyreleasefcn"))
+    set_keyreleasefcn (val);
+  else if (pname.compare ("menubar"))
+    set_menubar (val);
+  else if (pname.compare ("mincolormap"))
+    set_mincolormap (val);
+  else if (pname.compare ("name"))
+    set_name (val);
+  else if (pname.compare ("numbertitle"))
+    set_numbertitle (val);
+  else if (pname.compare ("paperunits"))
+    set_paperunits (val);
+  else if (pname.compare ("paperposition"))
+    set_paperposition (val);
+  else if (pname.compare ("paperpositionmode"))
+    set_paperpositionmode (val);
+  else if (pname.compare ("papersize"))
+    set_papersize (val);
+  else if (pname.compare ("papertype"))
+    set_papertype (val);
+  else if (pname.compare ("pointer"))
+    set_pointer (val);
+  else if (pname.compare ("pointershapecdata"))
+    set_pointershapecdata (val);
+  else if (pname.compare ("pointershapehotspot"))
+    set_pointershapehotspot (val);
+  else if (pname.compare ("position"))
+    set_position (val);
+  else if (pname.compare ("renderer"))
+    set_renderer (val);
+  else if (pname.compare ("renderermode"))
+    set_renderermode (val);
+  else if (pname.compare ("resize"))
+    set_resize (val);
+  else if (pname.compare ("resizefcn"))
+    set_resizefcn (val);
+  else if (pname.compare ("selectiontype"))
+    set_selectiontype (val);
+  else if (pname.compare ("toolbar"))
+    set_toolbar (val);
+  else if (pname.compare ("units"))
+    set_units (val);
+  else if (pname.compare ("windowbuttondownfcn"))
+    set_windowbuttondownfcn (val);
+  else if (pname.compare ("windowbuttonmotionfcn"))
+    set_windowbuttonmotionfcn (val);
+  else if (pname.compare ("windowbuttonupfcn"))
+    set_windowbuttonupfcn (val);
+  else if (pname.compare ("windowbuttonwheelfcn"))
+    set_windowbuttonwheelfcn (val);
+  else if (pname.compare ("windowstyle"))
+    set_windowstyle (val);
+  else if (pname.compare ("wvisual"))
+    set_wvisual (val);
+  else if (pname.compare ("wvisualmode"))
+    set_wvisualmode (val);
+  else if (pname.compare ("xdisplay"))
+    set_xdisplay (val);
+  else if (pname.compare ("xvisual"))
+    set_xvisual (val);
+  else if (pname.compare ("xvisualmode"))
+    set_xvisualmode (val);
+  else if (pname.compare ("buttondownfcn"))
+    set_buttondownfcn (val);
+  else if (pname.compare ("__backend__"))
+    set___backend__ (val);
+  else
+    base_properties::set (pname, "figure", val);
+}
+
+octave_value
+figure::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  if (all)
+    m.assign ("__plot_stream__", get___plot_stream__ ());
+  if (all)
+    m.assign ("__enhanced__", get___enhanced__ ());
+  m.assign ("nextplot", get_nextplot ());
+  m.assign ("closerequestfcn", get_closerequestfcn ());
+  m.assign ("currentaxes", get_currentaxes ().as_octave_value ());
+  m.assign ("colormap", get_colormap ());
+  m.assign ("paperorientation", get_paperorientation ());
+  m.assign ("color", get_color ());
+  m.assign ("alphamap", get_alphamap ());
+  m.assign ("currentcharacter", get_currentcharacter ());
+  m.assign ("currentobject", get_currentobject ().as_octave_value ());
+  m.assign ("current_point", get_current_point ());
+  m.assign ("dockcontrols", get_dockcontrols ());
+  m.assign ("doublebuffer", get_doublebuffer ());
+  m.assign ("filename", get_filename ());
+  m.assign ("integerhandle", get_integerhandle ());
+  m.assign ("inverthardcopy", get_inverthardcopy ());
+  m.assign ("keypressfcn", get_keypressfcn ());
+  m.assign ("keyreleasefcn", get_keyreleasefcn ());
+  m.assign ("menubar", get_menubar ());
+  m.assign ("mincolormap", get_mincolormap ());
+  m.assign ("name", get_name ());
+  m.assign ("numbertitle", get_numbertitle ());
+  m.assign ("paperunits", get_paperunits ());
+  m.assign ("paperposition", get_paperposition ());
+  m.assign ("paperpositionmode", get_paperpositionmode ());
+  m.assign ("papersize", get_papersize ());
+  m.assign ("papertype", get_papertype ());
+  m.assign ("pointer", get_pointer ());
+  m.assign ("pointershapecdata", get_pointershapecdata ());
+  m.assign ("pointershapehotspot", get_pointershapehotspot ());
+  m.assign ("position", get_position ());
+  m.assign ("renderer", get_renderer ());
+  m.assign ("renderermode", get_renderermode ());
+  m.assign ("resize", get_resize ());
+  m.assign ("resizefcn", get_resizefcn ());
+  m.assign ("selectiontype", get_selectiontype ());
+  m.assign ("toolbar", get_toolbar ());
+  m.assign ("units", get_units ());
+  m.assign ("windowbuttondownfcn", get_windowbuttondownfcn ());
+  m.assign ("windowbuttonmotionfcn", get_windowbuttonmotionfcn ());
+  m.assign ("windowbuttonupfcn", get_windowbuttonupfcn ());
+  m.assign ("windowbuttonwheelfcn", get_windowbuttonwheelfcn ());
+  m.assign ("windowstyle", get_windowstyle ());
+  m.assign ("wvisual", get_wvisual ());
+  m.assign ("wvisualmode", get_wvisualmode ());
+  m.assign ("xdisplay", get_xdisplay ());
+  m.assign ("xvisual", get_xvisual ());
+  m.assign ("xvisualmode", get_xvisualmode ());
+  m.assign ("buttondownfcn", get_buttondownfcn ());
+  m.assign ("__backend__", get___backend__ ());
+
+  return m;
+}
+
+octave_value
+figure::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("__plot_stream__"))
+    retval = get___plot_stream__ ();
+  else if (pname.compare ("__enhanced__"))
+    retval = get___enhanced__ ();
+  else if (pname.compare ("nextplot"))
+    retval = get_nextplot ();
+  else if (pname.compare ("closerequestfcn"))
+    retval = get_closerequestfcn ();
+  else if (pname.compare ("currentaxes"))
+    retval = get_currentaxes ().as_octave_value ();
+  else if (pname.compare ("colormap"))
+    retval = get_colormap ();
+  else if (pname.compare ("paperorientation"))
+    retval = get_paperorientation ();
+  else if (pname.compare ("color"))
+    retval = get_color ();
+  else if (pname.compare ("alphamap"))
+    retval = get_alphamap ();
+  else if (pname.compare ("currentcharacter"))
+    retval = get_currentcharacter ();
+  else if (pname.compare ("currentobject"))
+    retval = get_currentobject ().as_octave_value ();
+  else if (pname.compare ("current_point"))
+    retval = get_current_point ();
+  else if (pname.compare ("dockcontrols"))
+    retval = get_dockcontrols ();
+  else if (pname.compare ("doublebuffer"))
+    retval = get_doublebuffer ();
+  else if (pname.compare ("filename"))
+    retval = get_filename ();
+  else if (pname.compare ("integerhandle"))
+    retval = get_integerhandle ();
+  else if (pname.compare ("inverthardcopy"))
+    retval = get_inverthardcopy ();
+  else if (pname.compare ("keypressfcn"))
+    retval = get_keypressfcn ();
+  else if (pname.compare ("keyreleasefcn"))
+    retval = get_keyreleasefcn ();
+  else if (pname.compare ("menubar"))
+    retval = get_menubar ();
+  else if (pname.compare ("mincolormap"))
+    retval = get_mincolormap ();
+  else if (pname.compare ("name"))
+    retval = get_name ();
+  else if (pname.compare ("numbertitle"))
+    retval = get_numbertitle ();
+  else if (pname.compare ("paperunits"))
+    retval = get_paperunits ();
+  else if (pname.compare ("paperposition"))
+    retval = get_paperposition ();
+  else if (pname.compare ("paperpositionmode"))
+    retval = get_paperpositionmode ();
+  else if (pname.compare ("papersize"))
+    retval = get_papersize ();
+  else if (pname.compare ("papertype"))
+    retval = get_papertype ();
+  else if (pname.compare ("pointer"))
+    retval = get_pointer ();
+  else if (pname.compare ("pointershapecdata"))
+    retval = get_pointershapecdata ();
+  else if (pname.compare ("pointershapehotspot"))
+    retval = get_pointershapehotspot ();
+  else if (pname.compare ("position"))
+    retval = get_position ();
+  else if (pname.compare ("renderer"))
+    retval = get_renderer ();
+  else if (pname.compare ("renderermode"))
+    retval = get_renderermode ();
+  else if (pname.compare ("resize"))
+    retval = get_resize ();
+  else if (pname.compare ("resizefcn"))
+    retval = get_resizefcn ();
+  else if (pname.compare ("selectiontype"))
+    retval = get_selectiontype ();
+  else if (pname.compare ("toolbar"))
+    retval = get_toolbar ();
+  else if (pname.compare ("units"))
+    retval = get_units ();
+  else if (pname.compare ("windowbuttondownfcn"))
+    retval = get_windowbuttondownfcn ();
+  else if (pname.compare ("windowbuttonmotionfcn"))
+    retval = get_windowbuttonmotionfcn ();
+  else if (pname.compare ("windowbuttonupfcn"))
+    retval = get_windowbuttonupfcn ();
+  else if (pname.compare ("windowbuttonwheelfcn"))
+    retval = get_windowbuttonwheelfcn ();
+  else if (pname.compare ("windowstyle"))
+    retval = get_windowstyle ();
+  else if (pname.compare ("wvisual"))
+    retval = get_wvisual ();
+  else if (pname.compare ("wvisualmode"))
+    retval = get_wvisualmode ();
+  else if (pname.compare ("xdisplay"))
+    retval = get_xdisplay ();
+  else if (pname.compare ("xvisual"))
+    retval = get_xvisual ();
+  else if (pname.compare ("xvisualmode"))
+    retval = get_xvisualmode ();
+  else if (pname.compare ("buttondownfcn"))
+    retval = get_buttondownfcn ();
+  else if (pname.compare ("__backend__"))
+    retval = get___backend__ ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+figure::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("__plot_stream__"))
+    return property (&__plot_stream__, true);
+  else if (pname.compare ("__enhanced__"))
+    return property (&__enhanced__, true);
+  else if (pname.compare ("nextplot"))
+    return property (&nextplot, true);
+  else if (pname.compare ("closerequestfcn"))
+    return property (&closerequestfcn, true);
+  else if (pname.compare ("currentaxes"))
+    return property (&currentaxes, true);
+  else if (pname.compare ("colormap"))
+    return property (&colormap, true);
+  else if (pname.compare ("paperorientation"))
+    return property (&paperorientation, true);
+  else if (pname.compare ("color"))
+    return property (&color, true);
+  else if (pname.compare ("alphamap"))
+    return property (&alphamap, true);
+  else if (pname.compare ("currentcharacter"))
+    return property (&currentcharacter, true);
+  else if (pname.compare ("currentobject"))
+    return property (&currentobject, true);
+  else if (pname.compare ("current_point"))
+    return property (&current_point, true);
+  else if (pname.compare ("dockcontrols"))
+    return property (&dockcontrols, true);
+  else if (pname.compare ("doublebuffer"))
+    return property (&doublebuffer, true);
+  else if (pname.compare ("filename"))
+    return property (&filename, true);
+  else if (pname.compare ("integerhandle"))
+    return property (&integerhandle, true);
+  else if (pname.compare ("inverthardcopy"))
+    return property (&inverthardcopy, true);
+  else if (pname.compare ("keypressfcn"))
+    return property (&keypressfcn, true);
+  else if (pname.compare ("keyreleasefcn"))
+    return property (&keyreleasefcn, true);
+  else if (pname.compare ("menubar"))
+    return property (&menubar, true);
+  else if (pname.compare ("mincolormap"))
+    return property (&mincolormap, true);
+  else if (pname.compare ("name"))
+    return property (&name, true);
+  else if (pname.compare ("numbertitle"))
+    return property (&numbertitle, true);
+  else if (pname.compare ("paperunits"))
+    return property (&paperunits, true);
+  else if (pname.compare ("paperposition"))
+    return property (&paperposition, true);
+  else if (pname.compare ("paperpositionmode"))
+    return property (&paperpositionmode, true);
+  else if (pname.compare ("papersize"))
+    return property (&papersize, true);
+  else if (pname.compare ("papertype"))
+    return property (&papertype, true);
+  else if (pname.compare ("pointer"))
+    return property (&pointer, true);
+  else if (pname.compare ("pointershapecdata"))
+    return property (&pointershapecdata, true);
+  else if (pname.compare ("pointershapehotspot"))
+    return property (&pointershapehotspot, true);
+  else if (pname.compare ("position"))
+    return property (&position, true);
+  else if (pname.compare ("renderer"))
+    return property (&renderer, true);
+  else if (pname.compare ("renderermode"))
+    return property (&renderermode, true);
+  else if (pname.compare ("resize"))
+    return property (&resize, true);
+  else if (pname.compare ("resizefcn"))
+    return property (&resizefcn, true);
+  else if (pname.compare ("selectiontype"))
+    return property (&selectiontype, true);
+  else if (pname.compare ("toolbar"))
+    return property (&toolbar, true);
+  else if (pname.compare ("units"))
+    return property (&units, true);
+  else if (pname.compare ("windowbuttondownfcn"))
+    return property (&windowbuttondownfcn, true);
+  else if (pname.compare ("windowbuttonmotionfcn"))
+    return property (&windowbuttonmotionfcn, true);
+  else if (pname.compare ("windowbuttonupfcn"))
+    return property (&windowbuttonupfcn, true);
+  else if (pname.compare ("windowbuttonwheelfcn"))
+    return property (&windowbuttonwheelfcn, true);
+  else if (pname.compare ("windowstyle"))
+    return property (&windowstyle, true);
+  else if (pname.compare ("wvisual"))
+    return property (&wvisual, true);
+  else if (pname.compare ("wvisualmode"))
+    return property (&wvisualmode, true);
+  else if (pname.compare ("xdisplay"))
+    return property (&xdisplay, true);
+  else if (pname.compare ("xvisual"))
+    return property (&xvisual, true);
+  else if (pname.compare ("xvisualmode"))
+    return property (&xvisualmode, true);
+  else if (pname.compare ("buttondownfcn"))
+    return property (&buttondownfcn, true);
+  else if (pname.compare ("__backend__"))
+    return property (&__backend__, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+figure::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["__plot_stream__"] = Matrix ();
+  m["__enhanced__"] = "on";
+  m["nextplot"] = "add";
+  m["closerequestfcn"] = "closereq";
+  m["currentaxes"] = graphics_handle ().as_octave_value ();
+  m["colormap"] = jet_colormap ();
+  m["paperorientation"] = "portrait";
+  m["color"] = octave_value ();
+  m["alphamap"] = Matrix (64, 1, 1);
+  m["currentcharacter"] = "";
+  m["currentobject"] = graphics_handle ().as_octave_value ();
+  m["current_point"] = Matrix (2, 1, 0);
+  m["dockcontrols"] = "off";
+  m["doublebuffer"] = "on";
+  m["filename"] = "";
+  m["integerhandle"] = "on";
+  m["inverthardcopy"] = "off";
+  m["keypressfcn"] = Matrix ();
+  m["keyreleasefcn"] = Matrix ();
+  m["menubar"] = "figure";
+  m["mincolormap"] = 64;
+  m["name"] = "";
+  m["numbertitle"] = "on";
+  m["paperunits"] = "inches";
+  m["paperposition"] = default_figure_paperposition ();
+  m["paperpositionmode"] = "manual";
+  m["papersize"] = default_figure_papersize ();
+  m["papertype"] = "usletter";
+  m["pointer"] = "arrow";
+  m["pointershapecdata"] = Matrix (16, 16, 0);
+  m["pointershapehotspot"] = Matrix (1, 2, 0);
+  m["position"] = default_figure_position ();
+  m["renderer"] = "painters";
+  m["renderermode"] = "auto";
+  m["resize"] = "on";
+  m["resizefcn"] = Matrix ();
+  m["selectiontype"] = "normal";
+  m["toolbar"] = "auto";
+  m["units"] = "pixels";
+  m["windowbuttondownfcn"] = Matrix ();
+  m["windowbuttonmotionfcn"] = Matrix ();
+  m["windowbuttonupfcn"] = Matrix ();
+  m["windowbuttonwheelfcn"] = Matrix ();
+  m["windowstyle"] = "normal";
+  m["wvisual"] = "";
+  m["wvisualmode"] = "auto";
+  m["xdisplay"] = "";
+  m["xvisual"] = "";
+  m["xvisualmode"] = "auto";
+  m["buttondownfcn"] = Matrix ();
+  m["__backend__"] = "gnuplot";
+
+  return m;
+}
+
+std::string figure::properties::go_name ("figure");
+
+bool figure::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("__plot_stream__");
+      all_properties.insert ("__enhanced__");
+      all_properties.insert ("nextplot");
+      all_properties.insert ("closerequestfcn");
+      all_properties.insert ("currentaxes");
+      all_properties.insert ("colormap");
+      all_properties.insert ("paperorientation");
+      all_properties.insert ("color");
+      all_properties.insert ("alphamap");
+      all_properties.insert ("currentcharacter");
+      all_properties.insert ("currentobject");
+      all_properties.insert ("current_point");
+      all_properties.insert ("dockcontrols");
+      all_properties.insert ("doublebuffer");
+      all_properties.insert ("filename");
+      all_properties.insert ("integerhandle");
+      all_properties.insert ("inverthardcopy");
+      all_properties.insert ("keypressfcn");
+      all_properties.insert ("keyreleasefcn");
+      all_properties.insert ("menubar");
+      all_properties.insert ("mincolormap");
+      all_properties.insert ("name");
+      all_properties.insert ("numbertitle");
+      all_properties.insert ("paperunits");
+      all_properties.insert ("paperposition");
+      all_properties.insert ("paperpositionmode");
+      all_properties.insert ("papersize");
+      all_properties.insert ("papertype");
+      all_properties.insert ("pointer");
+      all_properties.insert ("pointershapecdata");
+      all_properties.insert ("pointershapehotspot");
+      all_properties.insert ("position");
+      all_properties.insert ("renderer");
+      all_properties.insert ("renderermode");
+      all_properties.insert ("resize");
+      all_properties.insert ("resizefcn");
+      all_properties.insert ("selectiontype");
+      all_properties.insert ("toolbar");
+      all_properties.insert ("units");
+      all_properties.insert ("windowbuttondownfcn");
+      all_properties.insert ("windowbuttonmotionfcn");
+      all_properties.insert ("windowbuttonupfcn");
+      all_properties.insert ("windowbuttonwheelfcn");
+      all_properties.insert ("windowstyle");
+      all_properties.insert ("wvisual");
+      all_properties.insert ("wvisualmode");
+      all_properties.insert ("xdisplay");
+      all_properties.insert ("xvisual");
+      all_properties.insert ("xvisualmode");
+      all_properties.insert ("buttondownfcn");
+      all_properties.insert ("__backend__");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "figure");
+}
+
+// ******** axes ********
+
+axes::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    position ("position", mh, default_axes_position ()),
+    box ("box", mh, "on"),
+    key ("key", mh, "off"),
+    keybox ("keybox", mh, "off"),
+    keyreverse ("keyreverse", mh, "off"),
+    keypos ("keypos", mh, 1),
+    colororder ("colororder", mh, default_colororder ()),
+    dataaspectratio ("dataaspectratio", mh, Matrix (1, 3, 1.0)),
+    dataaspectratiomode ("dataaspectratiomode", mh, "{auto}|manual"),
+    layer ("layer", mh, "{bottom}|top"),
+    xlim ("xlim", mh, default_lim ()),
+    ylim ("ylim", mh, default_lim ()),
+    zlim ("zlim", mh, default_lim ()),
+    clim ("clim", mh, default_lim ()),
+    alim ("alim", mh, default_lim ()),
+    xlimmode ("xlimmode", mh, "{auto}|manual"),
+    ylimmode ("ylimmode", mh, "{auto}|manual"),
+    zlimmode ("zlimmode", mh, "{auto}|manual"),
+    climmode ("climmode", mh, "{auto}|manual"),
+    alimmode ("alimmode", mh, "{auto}|manual"),
+    xlabel ("xlabel", mh, gh_manager::make_graphics_handle ("text", __myhandle__, false)),
+    ylabel ("ylabel", mh, gh_manager::make_graphics_handle ("text", __myhandle__, false)),
+    zlabel ("zlabel", mh, gh_manager::make_graphics_handle ("text", __myhandle__, false)),
+    title ("title", mh, gh_manager::make_graphics_handle ("text", __myhandle__, false)),
+    xgrid ("xgrid", mh, "off"),
+    ygrid ("ygrid", mh, "off"),
+    zgrid ("zgrid", mh, "off"),
+    xminorgrid ("xminorgrid", mh, "off"),
+    yminorgrid ("yminorgrid", mh, "off"),
+    zminorgrid ("zminorgrid", mh, "off"),
+    xtick ("xtick", mh, default_axes_tick ()),
+    ytick ("ytick", mh, default_axes_tick ()),
+    ztick ("ztick", mh, default_axes_tick ()),
+    xtickmode ("xtickmode", mh, "{auto}|manual"),
+    ytickmode ("ytickmode", mh, "{auto}|manual"),
+    ztickmode ("ztickmode", mh, "{auto}|manual"),
+    xminortick ("xminortick", mh, "off"),
+    yminortick ("yminortick", mh, "off"),
+    zminortick ("zminortick", mh, "off"),
+    xticklabel ("xticklabel", mh, ""),
+    yticklabel ("yticklabel", mh, ""),
+    zticklabel ("zticklabel", mh, ""),
+    xticklabelmode ("xticklabelmode", mh, "{auto}|manual"),
+    yticklabelmode ("yticklabelmode", mh, "{auto}|manual"),
+    zticklabelmode ("zticklabelmode", mh, "{auto}|manual"),
+    interpreter ("interpreter", mh, "tex|{none}|latex"),
+    color ("color", mh, color_property (color_values (1, 1, 1), radio_values ("none"))),
+    xcolor ("xcolor", mh, color_values (0, 0, 0)),
+    ycolor ("ycolor", mh, color_values (0, 0, 0)),
+    zcolor ("zcolor", mh, color_values (0, 0, 0)),
+    xscale ("xscale", mh, "{linear}|log"),
+    yscale ("yscale", mh, "{linear}|log"),
+    zscale ("zscale", mh, "{linear}|log"),
+    xdir ("xdir", mh, "{normal}|reverse"),
+    ydir ("ydir", mh, "{normal}|reverse"),
+    zdir ("zdir", mh, "{normal}|reverse"),
+    yaxislocation ("yaxislocation", mh, "{left}|right|zero"),
+    xaxislocation ("xaxislocation", mh, "{bottom}|top|zero"),
+    view ("view", mh, Matrix ()),
+    nextplot ("nextplot", mh, "add|replace_children|{replace}"),
+    outerposition ("outerposition", mh, default_axes_outerposition ()),
+    activepositionproperty ("activepositionproperty", mh, "{outerposition}|position"),
+    ambientlightcolor ("ambientlightcolor", mh, color_values (1, 1, 1)),
+    cameraposition ("cameraposition", mh, Matrix (1, 3, 0.0)),
+    cameratarget ("cameratarget", mh, Matrix (1, 3, 0.0)),
+    cameraupvector ("cameraupvector", mh, Matrix ()),
+    cameraviewangle ("cameraviewangle", mh, 10.0),
+    camerapositionmode ("camerapositionmode", mh, "{auto}|manual"),
+    cameratargetmode ("cameratargetmode", mh, "{auto}|manual"),
+    cameraupvectormode ("cameraupvectormode", mh, "{auto}|manual"),
+    cameraviewanglemode ("cameraviewanglemode", mh, "{auto}|manual"),
+    currentpoint ("currentpoint", mh, Matrix (2, 3, 0.0)),
+    drawmode ("drawmode", mh, "{normal}|fast"),
+    fontangle ("fontangle", mh, "{normal}|italic|oblique"),
+    fontname ("fontname", mh, OCTAVE_DEFAULT_FONTNAME),
+    fontsize ("fontsize", mh, 12),
+    fontunits ("fontunits", mh, "{points}|normalized|inches|centimeters|pixels"),
+    fontweight ("fontweight", mh, "{normal}|light|demi|bold"),
+    gridlinestyle ("gridlinestyle", mh, "-|--|{:}|-.|none"),
+    linestyleorder ("linestyleorder", mh, "-"),
+    linewidth ("linewidth", mh, 0.5),
+    minorgridlinestyle ("minorgridlinestyle", mh, "-|--|{:}|-.|none"),
+    plotboxaspectratio ("plotboxaspectratio", mh, Matrix (1, 3, 1.0)),
+    plotboxaspectratiomode ("plotboxaspectratiomode", mh, "{auto}|manual"),
+    projection ("projection", mh, "{orthographic}|perpective"),
+    tickdir ("tickdir", mh, "{in}|out"),
+    tickdirmode ("tickdirmode", mh, "{auto}|manual"),
+    ticklength ("ticklength", mh, default_axes_ticklength ()),
+    tightinset ("tightinset", mh, Matrix (1, 4, 0.0)),
+    units ("units", mh, "{normalized}|inches|centimeters|points|pixels|characters"),
+    x_viewtransform ("x_viewtransform", mh, Matrix (4, 4, 0.0)),
+    x_projectiontransform ("x_projectiontransform", mh, Matrix (4, 4, 0.0)),
+    x_viewporttransform ("x_viewporttransform", mh, Matrix (4, 4, 0.0)),
+    x_normrendertransform ("x_normrendertransform", mh, Matrix (4, 4, 0.0)),
+    x_rendertransform ("x_rendertransform", mh, Matrix (4, 4, 0.0))
+{
+  position.set_id (POSITION);
+  box.set_id (BOX);
+  key.set_id (KEY);
+  keybox.set_id (KEYBOX);
+  keyreverse.set_id (KEYREVERSE);
+  keypos.set_id (KEYPOS);
+  colororder.set_id (COLORORDER);
+  dataaspectratio.set_id (DATAASPECTRATIO);
+  dataaspectratiomode.set_id (DATAASPECTRATIOMODE);
+  layer.set_id (LAYER);
+  xlim.set_id (XLIM);
+  ylim.set_id (YLIM);
+  zlim.set_id (ZLIM);
+  clim.set_id (CLIM);
+  alim.set_id (ALIM);
+  xlimmode.set_id (XLIMMODE);
+  ylimmode.set_id (YLIMMODE);
+  zlimmode.set_id (ZLIMMODE);
+  climmode.set_id (CLIMMODE);
+  alimmode.set_id (ALIMMODE);
+  xlabel.set_id (XLABEL);
+  ylabel.set_id (YLABEL);
+  zlabel.set_id (ZLABEL);
+  title.set_id (TITLE);
+  xgrid.set_id (XGRID);
+  ygrid.set_id (YGRID);
+  zgrid.set_id (ZGRID);
+  xminorgrid.set_id (XMINORGRID);
+  yminorgrid.set_id (YMINORGRID);
+  zminorgrid.set_id (ZMINORGRID);
+  xtick.set_id (XTICK);
+  ytick.set_id (YTICK);
+  ztick.set_id (ZTICK);
+  xtickmode.set_id (XTICKMODE);
+  ytickmode.set_id (YTICKMODE);
+  ztickmode.set_id (ZTICKMODE);
+  xminortick.set_id (XMINORTICK);
+  yminortick.set_id (YMINORTICK);
+  zminortick.set_id (ZMINORTICK);
+  xticklabel.set_id (XTICKLABEL);
+  yticklabel.set_id (YTICKLABEL);
+  zticklabel.set_id (ZTICKLABEL);
+  xticklabelmode.set_id (XTICKLABELMODE);
+  yticklabelmode.set_id (YTICKLABELMODE);
+  zticklabelmode.set_id (ZTICKLABELMODE);
+  interpreter.set_id (INTERPRETER);
+  color.set_id (COLOR);
+  xcolor.set_id (XCOLOR);
+  ycolor.set_id (YCOLOR);
+  zcolor.set_id (ZCOLOR);
+  xscale.set_id (XSCALE);
+  yscale.set_id (YSCALE);
+  zscale.set_id (ZSCALE);
+  xdir.set_id (XDIR);
+  ydir.set_id (YDIR);
+  zdir.set_id (ZDIR);
+  yaxislocation.set_id (YAXISLOCATION);
+  xaxislocation.set_id (XAXISLOCATION);
+  view.set_id (VIEW);
+  nextplot.set_id (NEXTPLOT);
+  outerposition.set_id (OUTERPOSITION);
+  activepositionproperty.set_id (ACTIVEPOSITIONPROPERTY);
+  ambientlightcolor.set_id (AMBIENTLIGHTCOLOR);
+  cameraposition.set_id (CAMERAPOSITION);
+  cameratarget.set_id (CAMERATARGET);
+  cameraupvector.set_id (CAMERAUPVECTOR);
+  cameraviewangle.set_id (CAMERAVIEWANGLE);
+  camerapositionmode.set_id (CAMERAPOSITIONMODE);
+  cameratargetmode.set_id (CAMERATARGETMODE);
+  cameraupvectormode.set_id (CAMERAUPVECTORMODE);
+  cameraviewanglemode.set_id (CAMERAVIEWANGLEMODE);
+  currentpoint.set_id (CURRENTPOINT);
+  drawmode.set_id (DRAWMODE);
+  fontangle.set_id (FONTANGLE);
+  fontname.set_id (FONTNAME);
+  fontsize.set_id (FONTSIZE);
+  fontunits.set_id (FONTUNITS);
+  fontweight.set_id (FONTWEIGHT);
+  gridlinestyle.set_id (GRIDLINESTYLE);
+  linestyleorder.set_id (LINESTYLEORDER);
+  linewidth.set_id (LINEWIDTH);
+  minorgridlinestyle.set_id (MINORGRIDLINESTYLE);
+  plotboxaspectratio.set_id (PLOTBOXASPECTRATIO);
+  plotboxaspectratiomode.set_id (PLOTBOXASPECTRATIOMODE);
+  projection.set_id (PROJECTION);
+  tickdir.set_id (TICKDIR);
+  tickdirmode.set_id (TICKDIRMODE);
+  ticklength.set_id (TICKLENGTH);
+  tightinset.set_id (TIGHTINSET);
+  units.set_id (UNITS);
+  x_viewtransform.set_id (X_VIEWTRANSFORM);
+  x_viewtransform.set_hidden (true);
+  x_projectiontransform.set_id (X_PROJECTIONTRANSFORM);
+  x_projectiontransform.set_hidden (true);
+  x_viewporttransform.set_id (X_VIEWPORTTRANSFORM);
+  x_viewporttransform.set_hidden (true);
+  x_normrendertransform.set_id (X_NORMRENDERTRANSFORM);
+  x_normrendertransform.set_hidden (true);
+  x_rendertransform.set_id (X_RENDERTRANSFORM);
+  x_rendertransform.set_hidden (true);
+  init ();
+}
+
+void
+axes::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("position"))
+    set_position (val);
+  else if (pname.compare ("box"))
+    set_box (val);
+  else if (pname.compare ("key"))
+    set_key (val);
+  else if (pname.compare ("keybox"))
+    set_keybox (val);
+  else if (pname.compare ("keyreverse"))
+    set_keyreverse (val);
+  else if (pname.compare ("keypos"))
+    set_keypos (val);
+  else if (pname.compare ("colororder"))
+    set_colororder (val);
+  else if (pname.compare ("dataaspectratio"))
+    set_dataaspectratio (val);
+  else if (pname.compare ("dataaspectratiomode"))
+    set_dataaspectratiomode (val);
+  else if (pname.compare ("layer"))
+    set_layer (val);
+  else if (pname.compare ("xlim"))
+    set_xlim (val);
+  else if (pname.compare ("ylim"))
+    set_ylim (val);
+  else if (pname.compare ("zlim"))
+    set_zlim (val);
+  else if (pname.compare ("clim"))
+    set_clim (val);
+  else if (pname.compare ("alim"))
+    set_alim (val);
+  else if (pname.compare ("xlimmode"))
+    set_xlimmode (val);
+  else if (pname.compare ("ylimmode"))
+    set_ylimmode (val);
+  else if (pname.compare ("zlimmode"))
+    set_zlimmode (val);
+  else if (pname.compare ("climmode"))
+    set_climmode (val);
+  else if (pname.compare ("alimmode"))
+    set_alimmode (val);
+  else if (pname.compare ("xlabel"))
+    set_xlabel (val);
+  else if (pname.compare ("ylabel"))
+    set_ylabel (val);
+  else if (pname.compare ("zlabel"))
+    set_zlabel (val);
+  else if (pname.compare ("title"))
+    set_title (val);
+  else if (pname.compare ("xgrid"))
+    set_xgrid (val);
+  else if (pname.compare ("ygrid"))
+    set_ygrid (val);
+  else if (pname.compare ("zgrid"))
+    set_zgrid (val);
+  else if (pname.compare ("xminorgrid"))
+    set_xminorgrid (val);
+  else if (pname.compare ("yminorgrid"))
+    set_yminorgrid (val);
+  else if (pname.compare ("zminorgrid"))
+    set_zminorgrid (val);
+  else if (pname.compare ("xtick"))
+    set_xtick (val);
+  else if (pname.compare ("ytick"))
+    set_ytick (val);
+  else if (pname.compare ("ztick"))
+    set_ztick (val);
+  else if (pname.compare ("xtickmode"))
+    set_xtickmode (val);
+  else if (pname.compare ("ytickmode"))
+    set_ytickmode (val);
+  else if (pname.compare ("ztickmode"))
+    set_ztickmode (val);
+  else if (pname.compare ("xminortick"))
+    set_xminortick (val);
+  else if (pname.compare ("yminortick"))
+    set_yminortick (val);
+  else if (pname.compare ("zminortick"))
+    set_zminortick (val);
+  else if (pname.compare ("xticklabel"))
+    set_xticklabel (val);
+  else if (pname.compare ("yticklabel"))
+    set_yticklabel (val);
+  else if (pname.compare ("zticklabel"))
+    set_zticklabel (val);
+  else if (pname.compare ("xticklabelmode"))
+    set_xticklabelmode (val);
+  else if (pname.compare ("yticklabelmode"))
+    set_yticklabelmode (val);
+  else if (pname.compare ("zticklabelmode"))
+    set_zticklabelmode (val);
+  else if (pname.compare ("interpreter"))
+    set_interpreter (val);
+  else if (pname.compare ("color"))
+    set_color (val);
+  else if (pname.compare ("xcolor"))
+    set_xcolor (val);
+  else if (pname.compare ("ycolor"))
+    set_ycolor (val);
+  else if (pname.compare ("zcolor"))
+    set_zcolor (val);
+  else if (pname.compare ("xscale"))
+    set_xscale (val);
+  else if (pname.compare ("yscale"))
+    set_yscale (val);
+  else if (pname.compare ("zscale"))
+    set_zscale (val);
+  else if (pname.compare ("xdir"))
+    set_xdir (val);
+  else if (pname.compare ("ydir"))
+    set_ydir (val);
+  else if (pname.compare ("zdir"))
+    set_zdir (val);
+  else if (pname.compare ("yaxislocation"))
+    set_yaxislocation (val);
+  else if (pname.compare ("xaxislocation"))
+    set_xaxislocation (val);
+  else if (pname.compare ("view"))
+    set_view (val);
+  else if (pname.compare ("nextplot"))
+    set_nextplot (val);
+  else if (pname.compare ("outerposition"))
+    set_outerposition (val);
+  else if (pname.compare ("activepositionproperty"))
+    set_activepositionproperty (val);
+  else if (pname.compare ("ambientlightcolor"))
+    set_ambientlightcolor (val);
+  else if (pname.compare ("cameraposition"))
+    set_cameraposition (val);
+  else if (pname.compare ("cameratarget"))
+    set_cameratarget (val);
+  else if (pname.compare ("cameraupvector"))
+    set_cameraupvector (val);
+  else if (pname.compare ("cameraviewangle"))
+    set_cameraviewangle (val);
+  else if (pname.compare ("camerapositionmode"))
+    set_camerapositionmode (val);
+  else if (pname.compare ("cameratargetmode"))
+    set_cameratargetmode (val);
+  else if (pname.compare ("cameraupvectormode"))
+    set_cameraupvectormode (val);
+  else if (pname.compare ("cameraviewanglemode"))
+    set_cameraviewanglemode (val);
+  else if (pname.compare ("currentpoint"))
+    set_currentpoint (val);
+  else if (pname.compare ("drawmode"))
+    set_drawmode (val);
+  else if (pname.compare ("fontangle"))
+    set_fontangle (val);
+  else if (pname.compare ("fontname"))
+    set_fontname (val);
+  else if (pname.compare ("fontsize"))
+    set_fontsize (val);
+  else if (pname.compare ("fontunits"))
+    set_fontunits (val);
+  else if (pname.compare ("fontweight"))
+    set_fontweight (val);
+  else if (pname.compare ("gridlinestyle"))
+    set_gridlinestyle (val);
+  else if (pname.compare ("linestyleorder"))
+    set_linestyleorder (val);
+  else if (pname.compare ("linewidth"))
+    set_linewidth (val);
+  else if (pname.compare ("minorgridlinestyle"))
+    set_minorgridlinestyle (val);
+  else if (pname.compare ("plotboxaspectratio"))
+    set_plotboxaspectratio (val);
+  else if (pname.compare ("plotboxaspectratiomode"))
+    set_plotboxaspectratiomode (val);
+  else if (pname.compare ("projection"))
+    set_projection (val);
+  else if (pname.compare ("tickdir"))
+    set_tickdir (val);
+  else if (pname.compare ("tickdirmode"))
+    set_tickdirmode (val);
+  else if (pname.compare ("ticklength"))
+    set_ticklength (val);
+  else if (pname.compare ("units"))
+    set_units (val);
+  else if (pname.compare ("x_viewtransform"))
+    set_x_viewtransform (val);
+  else if (pname.compare ("x_projectiontransform"))
+    set_x_projectiontransform (val);
+  else if (pname.compare ("x_viewporttransform"))
+    set_x_viewporttransform (val);
+  else if (pname.compare ("x_normrendertransform"))
+    set_x_normrendertransform (val);
+  else if (pname.compare ("x_rendertransform"))
+    set_x_rendertransform (val);
+  else
+    base_properties::set (pname, "axes", val);
+}
+
+octave_value
+axes::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("position", get_position ());
+  m.assign ("box", get_box ());
+  m.assign ("key", get_key ());
+  m.assign ("keybox", get_keybox ());
+  m.assign ("keyreverse", get_keyreverse ());
+  m.assign ("keypos", get_keypos ());
+  m.assign ("colororder", get_colororder ());
+  m.assign ("dataaspectratio", get_dataaspectratio ());
+  m.assign ("dataaspectratiomode", get_dataaspectratiomode ());
+  m.assign ("layer", get_layer ());
+  m.assign ("xlim", get_xlim ());
+  m.assign ("ylim", get_ylim ());
+  m.assign ("zlim", get_zlim ());
+  m.assign ("clim", get_clim ());
+  m.assign ("alim", get_alim ());
+  m.assign ("xlimmode", get_xlimmode ());
+  m.assign ("ylimmode", get_ylimmode ());
+  m.assign ("zlimmode", get_zlimmode ());
+  m.assign ("climmode", get_climmode ());
+  m.assign ("alimmode", get_alimmode ());
+  m.assign ("xlabel", get_xlabel ().as_octave_value ());
+  m.assign ("ylabel", get_ylabel ().as_octave_value ());
+  m.assign ("zlabel", get_zlabel ().as_octave_value ());
+  m.assign ("title", get_title ().as_octave_value ());
+  m.assign ("xgrid", get_xgrid ());
+  m.assign ("ygrid", get_ygrid ());
+  m.assign ("zgrid", get_zgrid ());
+  m.assign ("xminorgrid", get_xminorgrid ());
+  m.assign ("yminorgrid", get_yminorgrid ());
+  m.assign ("zminorgrid", get_zminorgrid ());
+  m.assign ("xtick", get_xtick ());
+  m.assign ("ytick", get_ytick ());
+  m.assign ("ztick", get_ztick ());
+  m.assign ("xtickmode", get_xtickmode ());
+  m.assign ("ytickmode", get_ytickmode ());
+  m.assign ("ztickmode", get_ztickmode ());
+  m.assign ("xminortick", get_xminortick ());
+  m.assign ("yminortick", get_yminortick ());
+  m.assign ("zminortick", get_zminortick ());
+  m.assign ("xticklabel", get_xticklabel ());
+  m.assign ("yticklabel", get_yticklabel ());
+  m.assign ("zticklabel", get_zticklabel ());
+  m.assign ("xticklabelmode", get_xticklabelmode ());
+  m.assign ("yticklabelmode", get_yticklabelmode ());
+  m.assign ("zticklabelmode", get_zticklabelmode ());
+  m.assign ("interpreter", get_interpreter ());
+  m.assign ("color", get_color ());
+  m.assign ("xcolor", get_xcolor ());
+  m.assign ("ycolor", get_ycolor ());
+  m.assign ("zcolor", get_zcolor ());
+  m.assign ("xscale", get_xscale ());
+  m.assign ("yscale", get_yscale ());
+  m.assign ("zscale", get_zscale ());
+  m.assign ("xdir", get_xdir ());
+  m.assign ("ydir", get_ydir ());
+  m.assign ("zdir", get_zdir ());
+  m.assign ("yaxislocation", get_yaxislocation ());
+  m.assign ("xaxislocation", get_xaxislocation ());
+  m.assign ("view", get_view ());
+  m.assign ("nextplot", get_nextplot ());
+  m.assign ("outerposition", get_outerposition ());
+  m.assign ("activepositionproperty", get_activepositionproperty ());
+  m.assign ("ambientlightcolor", get_ambientlightcolor ());
+  m.assign ("cameraposition", get_cameraposition ());
+  m.assign ("cameratarget", get_cameratarget ());
+  m.assign ("cameraupvector", get_cameraupvector ());
+  m.assign ("cameraviewangle", get_cameraviewangle ());
+  m.assign ("camerapositionmode", get_camerapositionmode ());
+  m.assign ("cameratargetmode", get_cameratargetmode ());
+  m.assign ("cameraupvectormode", get_cameraupvectormode ());
+  m.assign ("cameraviewanglemode", get_cameraviewanglemode ());
+  m.assign ("currentpoint", get_currentpoint ());
+  m.assign ("drawmode", get_drawmode ());
+  m.assign ("fontangle", get_fontangle ());
+  m.assign ("fontname", get_fontname ());
+  m.assign ("fontsize", get_fontsize ());
+  m.assign ("fontunits", get_fontunits ());
+  m.assign ("fontweight", get_fontweight ());
+  m.assign ("gridlinestyle", get_gridlinestyle ());
+  m.assign ("linestyleorder", get_linestyleorder ());
+  m.assign ("linewidth", get_linewidth ());
+  m.assign ("minorgridlinestyle", get_minorgridlinestyle ());
+  m.assign ("plotboxaspectratio", get_plotboxaspectratio ());
+  m.assign ("plotboxaspectratiomode", get_plotboxaspectratiomode ());
+  m.assign ("projection", get_projection ());
+  m.assign ("tickdir", get_tickdir ());
+  m.assign ("tickdirmode", get_tickdirmode ());
+  m.assign ("ticklength", get_ticklength ());
+  m.assign ("tightinset", get_tightinset ());
+  m.assign ("units", get_units ());
+  if (all)
+    m.assign ("x_viewtransform", get_x_viewtransform ());
+  if (all)
+    m.assign ("x_projectiontransform", get_x_projectiontransform ());
+  if (all)
+    m.assign ("x_viewporttransform", get_x_viewporttransform ());
+  if (all)
+    m.assign ("x_normrendertransform", get_x_normrendertransform ());
+  if (all)
+    m.assign ("x_rendertransform", get_x_rendertransform ());
+
+  return m;
+}
+
+octave_value
+axes::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("position"))
+    retval = get_position ();
+  else if (pname.compare ("box"))
+    retval = get_box ();
+  else if (pname.compare ("key"))
+    retval = get_key ();
+  else if (pname.compare ("keybox"))
+    retval = get_keybox ();
+  else if (pname.compare ("keyreverse"))
+    retval = get_keyreverse ();
+  else if (pname.compare ("keypos"))
+    retval = get_keypos ();
+  else if (pname.compare ("colororder"))
+    retval = get_colororder ();
+  else if (pname.compare ("dataaspectratio"))
+    retval = get_dataaspectratio ();
+  else if (pname.compare ("dataaspectratiomode"))
+    retval = get_dataaspectratiomode ();
+  else if (pname.compare ("layer"))
+    retval = get_layer ();
+  else if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("zlim"))
+    retval = get_zlim ();
+  else if (pname.compare ("clim"))
+    retval = get_clim ();
+  else if (pname.compare ("alim"))
+    retval = get_alim ();
+  else if (pname.compare ("xlimmode"))
+    retval = get_xlimmode ();
+  else if (pname.compare ("ylimmode"))
+    retval = get_ylimmode ();
+  else if (pname.compare ("zlimmode"))
+    retval = get_zlimmode ();
+  else if (pname.compare ("climmode"))
+    retval = get_climmode ();
+  else if (pname.compare ("alimmode"))
+    retval = get_alimmode ();
+  else if (pname.compare ("xlabel"))
+    retval = get_xlabel ().as_octave_value ();
+  else if (pname.compare ("ylabel"))
+    retval = get_ylabel ().as_octave_value ();
+  else if (pname.compare ("zlabel"))
+    retval = get_zlabel ().as_octave_value ();
+  else if (pname.compare ("title"))
+    retval = get_title ().as_octave_value ();
+  else if (pname.compare ("xgrid"))
+    retval = get_xgrid ();
+  else if (pname.compare ("ygrid"))
+    retval = get_ygrid ();
+  else if (pname.compare ("zgrid"))
+    retval = get_zgrid ();
+  else if (pname.compare ("xminorgrid"))
+    retval = get_xminorgrid ();
+  else if (pname.compare ("yminorgrid"))
+    retval = get_yminorgrid ();
+  else if (pname.compare ("zminorgrid"))
+    retval = get_zminorgrid ();
+  else if (pname.compare ("xtick"))
+    retval = get_xtick ();
+  else if (pname.compare ("ytick"))
+    retval = get_ytick ();
+  else if (pname.compare ("ztick"))
+    retval = get_ztick ();
+  else if (pname.compare ("xtickmode"))
+    retval = get_xtickmode ();
+  else if (pname.compare ("ytickmode"))
+    retval = get_ytickmode ();
+  else if (pname.compare ("ztickmode"))
+    retval = get_ztickmode ();
+  else if (pname.compare ("xminortick"))
+    retval = get_xminortick ();
+  else if (pname.compare ("yminortick"))
+    retval = get_yminortick ();
+  else if (pname.compare ("zminortick"))
+    retval = get_zminortick ();
+  else if (pname.compare ("xticklabel"))
+    retval = get_xticklabel ();
+  else if (pname.compare ("yticklabel"))
+    retval = get_yticklabel ();
+  else if (pname.compare ("zticklabel"))
+    retval = get_zticklabel ();
+  else if (pname.compare ("xticklabelmode"))
+    retval = get_xticklabelmode ();
+  else if (pname.compare ("yticklabelmode"))
+    retval = get_yticklabelmode ();
+  else if (pname.compare ("zticklabelmode"))
+    retval = get_zticklabelmode ();
+  else if (pname.compare ("interpreter"))
+    retval = get_interpreter ();
+  else if (pname.compare ("color"))
+    retval = get_color ();
+  else if (pname.compare ("xcolor"))
+    retval = get_xcolor ();
+  else if (pname.compare ("ycolor"))
+    retval = get_ycolor ();
+  else if (pname.compare ("zcolor"))
+    retval = get_zcolor ();
+  else if (pname.compare ("xscale"))
+    retval = get_xscale ();
+  else if (pname.compare ("yscale"))
+    retval = get_yscale ();
+  else if (pname.compare ("zscale"))
+    retval = get_zscale ();
+  else if (pname.compare ("xdir"))
+    retval = get_xdir ();
+  else if (pname.compare ("ydir"))
+    retval = get_ydir ();
+  else if (pname.compare ("zdir"))
+    retval = get_zdir ();
+  else if (pname.compare ("yaxislocation"))
+    retval = get_yaxislocation ();
+  else if (pname.compare ("xaxislocation"))
+    retval = get_xaxislocation ();
+  else if (pname.compare ("view"))
+    retval = get_view ();
+  else if (pname.compare ("nextplot"))
+    retval = get_nextplot ();
+  else if (pname.compare ("outerposition"))
+    retval = get_outerposition ();
+  else if (pname.compare ("activepositionproperty"))
+    retval = get_activepositionproperty ();
+  else if (pname.compare ("ambientlightcolor"))
+    retval = get_ambientlightcolor ();
+  else if (pname.compare ("cameraposition"))
+    retval = get_cameraposition ();
+  else if (pname.compare ("cameratarget"))
+    retval = get_cameratarget ();
+  else if (pname.compare ("cameraupvector"))
+    retval = get_cameraupvector ();
+  else if (pname.compare ("cameraviewangle"))
+    retval = get_cameraviewangle ();
+  else if (pname.compare ("camerapositionmode"))
+    retval = get_camerapositionmode ();
+  else if (pname.compare ("cameratargetmode"))
+    retval = get_cameratargetmode ();
+  else if (pname.compare ("cameraupvectormode"))
+    retval = get_cameraupvectormode ();
+  else if (pname.compare ("cameraviewanglemode"))
+    retval = get_cameraviewanglemode ();
+  else if (pname.compare ("currentpoint"))
+    retval = get_currentpoint ();
+  else if (pname.compare ("drawmode"))
+    retval = get_drawmode ();
+  else if (pname.compare ("fontangle"))
+    retval = get_fontangle ();
+  else if (pname.compare ("fontname"))
+    retval = get_fontname ();
+  else if (pname.compare ("fontsize"))
+    retval = get_fontsize ();
+  else if (pname.compare ("fontunits"))
+    retval = get_fontunits ();
+  else if (pname.compare ("fontweight"))
+    retval = get_fontweight ();
+  else if (pname.compare ("gridlinestyle"))
+    retval = get_gridlinestyle ();
+  else if (pname.compare ("linestyleorder"))
+    retval = get_linestyleorder ();
+  else if (pname.compare ("linewidth"))
+    retval = get_linewidth ();
+  else if (pname.compare ("minorgridlinestyle"))
+    retval = get_minorgridlinestyle ();
+  else if (pname.compare ("plotboxaspectratio"))
+    retval = get_plotboxaspectratio ();
+  else if (pname.compare ("plotboxaspectratiomode"))
+    retval = get_plotboxaspectratiomode ();
+  else if (pname.compare ("projection"))
+    retval = get_projection ();
+  else if (pname.compare ("tickdir"))
+    retval = get_tickdir ();
+  else if (pname.compare ("tickdirmode"))
+    retval = get_tickdirmode ();
+  else if (pname.compare ("ticklength"))
+    retval = get_ticklength ();
+  else if (pname.compare ("tightinset"))
+    retval = get_tightinset ();
+  else if (pname.compare ("units"))
+    retval = get_units ();
+  else if (pname.compare ("x_viewtransform"))
+    retval = get_x_viewtransform ();
+  else if (pname.compare ("x_projectiontransform"))
+    retval = get_x_projectiontransform ();
+  else if (pname.compare ("x_viewporttransform"))
+    retval = get_x_viewporttransform ();
+  else if (pname.compare ("x_normrendertransform"))
+    retval = get_x_normrendertransform ();
+  else if (pname.compare ("x_rendertransform"))
+    retval = get_x_rendertransform ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+axes::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("position"))
+    return property (&position, true);
+  else if (pname.compare ("box"))
+    return property (&box, true);
+  else if (pname.compare ("key"))
+    return property (&key, true);
+  else if (pname.compare ("keybox"))
+    return property (&keybox, true);
+  else if (pname.compare ("keyreverse"))
+    return property (&keyreverse, true);
+  else if (pname.compare ("keypos"))
+    return property (&keypos, true);
+  else if (pname.compare ("colororder"))
+    return property (&colororder, true);
+  else if (pname.compare ("dataaspectratio"))
+    return property (&dataaspectratio, true);
+  else if (pname.compare ("dataaspectratiomode"))
+    return property (&dataaspectratiomode, true);
+  else if (pname.compare ("layer"))
+    return property (&layer, true);
+  else if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("zlim"))
+    return property (&zlim, true);
+  else if (pname.compare ("clim"))
+    return property (&clim, true);
+  else if (pname.compare ("alim"))
+    return property (&alim, true);
+  else if (pname.compare ("xlimmode"))
+    return property (&xlimmode, true);
+  else if (pname.compare ("ylimmode"))
+    return property (&ylimmode, true);
+  else if (pname.compare ("zlimmode"))
+    return property (&zlimmode, true);
+  else if (pname.compare ("climmode"))
+    return property (&climmode, true);
+  else if (pname.compare ("alimmode"))
+    return property (&alimmode, true);
+  else if (pname.compare ("xlabel"))
+    return property (&xlabel, true);
+  else if (pname.compare ("ylabel"))
+    return property (&ylabel, true);
+  else if (pname.compare ("zlabel"))
+    return property (&zlabel, true);
+  else if (pname.compare ("title"))
+    return property (&title, true);
+  else if (pname.compare ("xgrid"))
+    return property (&xgrid, true);
+  else if (pname.compare ("ygrid"))
+    return property (&ygrid, true);
+  else if (pname.compare ("zgrid"))
+    return property (&zgrid, true);
+  else if (pname.compare ("xminorgrid"))
+    return property (&xminorgrid, true);
+  else if (pname.compare ("yminorgrid"))
+    return property (&yminorgrid, true);
+  else if (pname.compare ("zminorgrid"))
+    return property (&zminorgrid, true);
+  else if (pname.compare ("xtick"))
+    return property (&xtick, true);
+  else if (pname.compare ("ytick"))
+    return property (&ytick, true);
+  else if (pname.compare ("ztick"))
+    return property (&ztick, true);
+  else if (pname.compare ("xtickmode"))
+    return property (&xtickmode, true);
+  else if (pname.compare ("ytickmode"))
+    return property (&ytickmode, true);
+  else if (pname.compare ("ztickmode"))
+    return property (&ztickmode, true);
+  else if (pname.compare ("xminortick"))
+    return property (&xminortick, true);
+  else if (pname.compare ("yminortick"))
+    return property (&yminortick, true);
+  else if (pname.compare ("zminortick"))
+    return property (&zminortick, true);
+  else if (pname.compare ("xticklabel"))
+    return property (&xticklabel, true);
+  else if (pname.compare ("yticklabel"))
+    return property (&yticklabel, true);
+  else if (pname.compare ("zticklabel"))
+    return property (&zticklabel, true);
+  else if (pname.compare ("xticklabelmode"))
+    return property (&xticklabelmode, true);
+  else if (pname.compare ("yticklabelmode"))
+    return property (&yticklabelmode, true);
+  else if (pname.compare ("zticklabelmode"))
+    return property (&zticklabelmode, true);
+  else if (pname.compare ("interpreter"))
+    return property (&interpreter, true);
+  else if (pname.compare ("color"))
+    return property (&color, true);
+  else if (pname.compare ("xcolor"))
+    return property (&xcolor, true);
+  else if (pname.compare ("ycolor"))
+    return property (&ycolor, true);
+  else if (pname.compare ("zcolor"))
+    return property (&zcolor, true);
+  else if (pname.compare ("xscale"))
+    return property (&xscale, true);
+  else if (pname.compare ("yscale"))
+    return property (&yscale, true);
+  else if (pname.compare ("zscale"))
+    return property (&zscale, true);
+  else if (pname.compare ("xdir"))
+    return property (&xdir, true);
+  else if (pname.compare ("ydir"))
+    return property (&ydir, true);
+  else if (pname.compare ("zdir"))
+    return property (&zdir, true);
+  else if (pname.compare ("yaxislocation"))
+    return property (&yaxislocation, true);
+  else if (pname.compare ("xaxislocation"))
+    return property (&xaxislocation, true);
+  else if (pname.compare ("view"))
+    return property (&view, true);
+  else if (pname.compare ("nextplot"))
+    return property (&nextplot, true);
+  else if (pname.compare ("outerposition"))
+    return property (&outerposition, true);
+  else if (pname.compare ("activepositionproperty"))
+    return property (&activepositionproperty, true);
+  else if (pname.compare ("ambientlightcolor"))
+    return property (&ambientlightcolor, true);
+  else if (pname.compare ("cameraposition"))
+    return property (&cameraposition, true);
+  else if (pname.compare ("cameratarget"))
+    return property (&cameratarget, true);
+  else if (pname.compare ("cameraupvector"))
+    return property (&cameraupvector, true);
+  else if (pname.compare ("cameraviewangle"))
+    return property (&cameraviewangle, true);
+  else if (pname.compare ("camerapositionmode"))
+    return property (&camerapositionmode, true);
+  else if (pname.compare ("cameratargetmode"))
+    return property (&cameratargetmode, true);
+  else if (pname.compare ("cameraupvectormode"))
+    return property (&cameraupvectormode, true);
+  else if (pname.compare ("cameraviewanglemode"))
+    return property (&cameraviewanglemode, true);
+  else if (pname.compare ("currentpoint"))
+    return property (&currentpoint, true);
+  else if (pname.compare ("drawmode"))
+    return property (&drawmode, true);
+  else if (pname.compare ("fontangle"))
+    return property (&fontangle, true);
+  else if (pname.compare ("fontname"))
+    return property (&fontname, true);
+  else if (pname.compare ("fontsize"))
+    return property (&fontsize, true);
+  else if (pname.compare ("fontunits"))
+    return property (&fontunits, true);
+  else if (pname.compare ("fontweight"))
+    return property (&fontweight, true);
+  else if (pname.compare ("gridlinestyle"))
+    return property (&gridlinestyle, true);
+  else if (pname.compare ("linestyleorder"))
+    return property (&linestyleorder, true);
+  else if (pname.compare ("linewidth"))
+    return property (&linewidth, true);
+  else if (pname.compare ("minorgridlinestyle"))
+    return property (&minorgridlinestyle, true);
+  else if (pname.compare ("plotboxaspectratio"))
+    return property (&plotboxaspectratio, true);
+  else if (pname.compare ("plotboxaspectratiomode"))
+    return property (&plotboxaspectratiomode, true);
+  else if (pname.compare ("projection"))
+    return property (&projection, true);
+  else if (pname.compare ("tickdir"))
+    return property (&tickdir, true);
+  else if (pname.compare ("tickdirmode"))
+    return property (&tickdirmode, true);
+  else if (pname.compare ("ticklength"))
+    return property (&ticklength, true);
+  else if (pname.compare ("tightinset"))
+    return property (&tightinset, true);
+  else if (pname.compare ("units"))
+    return property (&units, true);
+  else if (pname.compare ("x_viewtransform"))
+    return property (&x_viewtransform, true);
+  else if (pname.compare ("x_projectiontransform"))
+    return property (&x_projectiontransform, true);
+  else if (pname.compare ("x_viewporttransform"))
+    return property (&x_viewporttransform, true);
+  else if (pname.compare ("x_normrendertransform"))
+    return property (&x_normrendertransform, true);
+  else if (pname.compare ("x_rendertransform"))
+    return property (&x_rendertransform, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+axes::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["position"] = default_axes_position ();
+  m["box"] = "on";
+  m["key"] = "off";
+  m["keybox"] = "off";
+  m["keyreverse"] = "off";
+  m["keypos"] = 1;
+  m["colororder"] = default_colororder ();
+  m["dataaspectratio"] = Matrix (1, 3, 1.0);
+  m["dataaspectratiomode"] = "auto";
+  m["layer"] = "bottom";
+  m["xlim"] = default_lim ();
+  m["ylim"] = default_lim ();
+  m["zlim"] = default_lim ();
+  m["clim"] = default_lim ();
+  m["alim"] = default_lim ();
+  m["xlimmode"] = "auto";
+  m["ylimmode"] = "auto";
+  m["zlimmode"] = "auto";
+  m["climmode"] = "auto";
+  m["alimmode"] = "auto";
+  m["xgrid"] = "off";
+  m["ygrid"] = "off";
+  m["zgrid"] = "off";
+  m["xminorgrid"] = "off";
+  m["yminorgrid"] = "off";
+  m["zminorgrid"] = "off";
+  m["xtick"] = default_axes_tick ();
+  m["ytick"] = default_axes_tick ();
+  m["ztick"] = default_axes_tick ();
+  m["xtickmode"] = "auto";
+  m["ytickmode"] = "auto";
+  m["ztickmode"] = "auto";
+  m["xminortick"] = "off";
+  m["yminortick"] = "off";
+  m["zminortick"] = "off";
+  m["xticklabel"] = "";
+  m["yticklabel"] = "";
+  m["zticklabel"] = "";
+  m["xticklabelmode"] = "auto";
+  m["yticklabelmode"] = "auto";
+  m["zticklabelmode"] = "auto";
+  m["interpreter"] = "none";
+  m["color"] = octave_value ();
+  m["xcolor"] = octave_value ();
+  m["ycolor"] = octave_value ();
+  m["zcolor"] = octave_value ();
+  m["xscale"] = "linear";
+  m["yscale"] = "linear";
+  m["zscale"] = "linear";
+  m["xdir"] = "normal";
+  m["ydir"] = "normal";
+  m["zdir"] = "normal";
+  m["yaxislocation"] = "left";
+  m["xaxislocation"] = "bottom";
+  m["view"] = Matrix ();
+  m["nextplot"] = "replace";
+  m["outerposition"] = default_axes_outerposition ();
+  m["activepositionproperty"] = "outerposition";
+  m["ambientlightcolor"] = octave_value ();
+  m["cameraposition"] = Matrix (1, 3, 0.0);
+  m["cameratarget"] = Matrix (1, 3, 0.0);
+  m["cameraupvector"] = Matrix ();
+  m["cameraviewangle"] = 10.0;
+  m["camerapositionmode"] = "auto";
+  m["cameratargetmode"] = "auto";
+  m["cameraupvectormode"] = "auto";
+  m["cameraviewanglemode"] = "auto";
+  m["currentpoint"] = Matrix (2, 3, 0.0);
+  m["drawmode"] = "normal";
+  m["fontangle"] = "normal";
+  m["fontname"] = OCTAVE_DEFAULT_FONTNAME;
+  m["fontsize"] = 12;
+  m["fontunits"] = "points";
+  m["fontweight"] = "normal";
+  m["gridlinestyle"] = ":";
+  m["linestyleorder"] = "-";
+  m["linewidth"] = 0.5;
+  m["minorgridlinestyle"] = ":";
+  m["plotboxaspectratio"] = Matrix (1, 3, 1.0);
+  m["plotboxaspectratiomode"] = "auto";
+  m["projection"] = "orthographic";
+  m["tickdir"] = "in";
+  m["tickdirmode"] = "auto";
+  m["ticklength"] = default_axes_ticklength ();
+  m["tightinset"] = Matrix (1, 4, 0.0);
+  m["units"] = "normalized";
+  m["x_viewtransform"] = Matrix (4, 4, 0.0);
+  m["x_projectiontransform"] = Matrix (4, 4, 0.0);
+  m["x_viewporttransform"] = Matrix (4, 4, 0.0);
+  m["x_normrendertransform"] = Matrix (4, 4, 0.0);
+  m["x_rendertransform"] = Matrix (4, 4, 0.0);
+
+  return m;
+}
+
+std::string axes::properties::go_name ("axes");
+
+bool axes::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("position");
+      all_properties.insert ("box");
+      all_properties.insert ("key");
+      all_properties.insert ("keybox");
+      all_properties.insert ("keyreverse");
+      all_properties.insert ("keypos");
+      all_properties.insert ("colororder");
+      all_properties.insert ("dataaspectratio");
+      all_properties.insert ("dataaspectratiomode");
+      all_properties.insert ("layer");
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("zlim");
+      all_properties.insert ("clim");
+      all_properties.insert ("alim");
+      all_properties.insert ("xlimmode");
+      all_properties.insert ("ylimmode");
+      all_properties.insert ("zlimmode");
+      all_properties.insert ("climmode");
+      all_properties.insert ("alimmode");
+      all_properties.insert ("xlabel");
+      all_properties.insert ("ylabel");
+      all_properties.insert ("zlabel");
+      all_properties.insert ("title");
+      all_properties.insert ("xgrid");
+      all_properties.insert ("ygrid");
+      all_properties.insert ("zgrid");
+      all_properties.insert ("xminorgrid");
+      all_properties.insert ("yminorgrid");
+      all_properties.insert ("zminorgrid");
+      all_properties.insert ("xtick");
+      all_properties.insert ("ytick");
+      all_properties.insert ("ztick");
+      all_properties.insert ("xtickmode");
+      all_properties.insert ("ytickmode");
+      all_properties.insert ("ztickmode");
+      all_properties.insert ("xminortick");
+      all_properties.insert ("yminortick");
+      all_properties.insert ("zminortick");
+      all_properties.insert ("xticklabel");
+      all_properties.insert ("yticklabel");
+      all_properties.insert ("zticklabel");
+      all_properties.insert ("xticklabelmode");
+      all_properties.insert ("yticklabelmode");
+      all_properties.insert ("zticklabelmode");
+      all_properties.insert ("interpreter");
+      all_properties.insert ("color");
+      all_properties.insert ("xcolor");
+      all_properties.insert ("ycolor");
+      all_properties.insert ("zcolor");
+      all_properties.insert ("xscale");
+      all_properties.insert ("yscale");
+      all_properties.insert ("zscale");
+      all_properties.insert ("xdir");
+      all_properties.insert ("ydir");
+      all_properties.insert ("zdir");
+      all_properties.insert ("yaxislocation");
+      all_properties.insert ("xaxislocation");
+      all_properties.insert ("view");
+      all_properties.insert ("nextplot");
+      all_properties.insert ("outerposition");
+      all_properties.insert ("activepositionproperty");
+      all_properties.insert ("ambientlightcolor");
+      all_properties.insert ("cameraposition");
+      all_properties.insert ("cameratarget");
+      all_properties.insert ("cameraupvector");
+      all_properties.insert ("cameraviewangle");
+      all_properties.insert ("camerapositionmode");
+      all_properties.insert ("cameratargetmode");
+      all_properties.insert ("cameraupvectormode");
+      all_properties.insert ("cameraviewanglemode");
+      all_properties.insert ("currentpoint");
+      all_properties.insert ("drawmode");
+      all_properties.insert ("fontangle");
+      all_properties.insert ("fontname");
+      all_properties.insert ("fontsize");
+      all_properties.insert ("fontunits");
+      all_properties.insert ("fontweight");
+      all_properties.insert ("gridlinestyle");
+      all_properties.insert ("linestyleorder");
+      all_properties.insert ("linewidth");
+      all_properties.insert ("minorgridlinestyle");
+      all_properties.insert ("plotboxaspectratio");
+      all_properties.insert ("plotboxaspectratiomode");
+      all_properties.insert ("projection");
+      all_properties.insert ("tickdir");
+      all_properties.insert ("tickdirmode");
+      all_properties.insert ("ticklength");
+      all_properties.insert ("tightinset");
+      all_properties.insert ("units");
+      all_properties.insert ("x_viewtransform");
+      all_properties.insert ("x_projectiontransform");
+      all_properties.insert ("x_viewporttransform");
+      all_properties.insert ("x_normrendertransform");
+      all_properties.insert ("x_rendertransform");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "axes");
+}
+
+// ******** line ********
+
+line::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    xdata ("xdata", mh, default_data ()),
+    ydata ("ydata", mh, default_data ()),
+    zdata ("zdata", mh, Matrix ()),
+    ldata ("ldata", mh, Matrix ()),
+    udata ("udata", mh, Matrix ()),
+    xldata ("xldata", mh, Matrix ()),
+    xudata ("xudata", mh, Matrix ()),
+    xdatasource ("xdatasource", mh, ""),
+    ydatasource ("ydatasource", mh, ""),
+    zdatasource ("zdatasource", mh, ""),
+    color ("color", mh, color_values (0, 0, 0)),
+    linestyle ("linestyle", mh, "{-}|--|:|-.|none"),
+    linewidth ("linewidth", mh, 0.5),
+    marker ("marker", mh, "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h"),
+    markeredgecolor ("markeredgecolor", mh, "{auto}|none"),
+    markerfacecolor ("markerfacecolor", mh, "auto|{none}"),
+    markersize ("markersize", mh, 6),
+    keylabel ("keylabel", mh, ""),
+    interpreter ("interpreter", mh, "{tex}|none|latex"),
+    displayname ("displayname", mh, ""),
+    erasemode ("erasemode", mh, "{normal}|none|xor|background"),
+    xlim ("xlim", mh, Matrix ()),
+    ylim ("ylim", mh, Matrix ()),
+    zlim ("zlim", mh, Matrix ()),
+    xliminclude ("xliminclude", mh, "on"),
+    yliminclude ("yliminclude", mh, "on"),
+    zliminclude ("zliminclude", mh, "off")
+{
+  xdata.set_id (XDATA);
+  ydata.set_id (YDATA);
+  zdata.set_id (ZDATA);
+  ldata.set_id (LDATA);
+  udata.set_id (UDATA);
+  xldata.set_id (XLDATA);
+  xudata.set_id (XUDATA);
+  xdatasource.set_id (XDATASOURCE);
+  ydatasource.set_id (YDATASOURCE);
+  zdatasource.set_id (ZDATASOURCE);
+  color.set_id (COLOR);
+  linestyle.set_id (LINESTYLE);
+  linewidth.set_id (LINEWIDTH);
+  marker.set_id (MARKER);
+  markeredgecolor.set_id (MARKEREDGECOLOR);
+  markerfacecolor.set_id (MARKERFACECOLOR);
+  markersize.set_id (MARKERSIZE);
+  keylabel.set_id (KEYLABEL);
+  interpreter.set_id (INTERPRETER);
+  displayname.set_id (DISPLAYNAME);
+  erasemode.set_id (ERASEMODE);
+  xlim.set_id (XLIM);
+  xlim.set_hidden (true);
+  ylim.set_id (YLIM);
+  ylim.set_hidden (true);
+  zlim.set_id (ZLIM);
+  zlim.set_hidden (true);
+  xliminclude.set_id (XLIMINCLUDE);
+  xliminclude.set_hidden (true);
+  yliminclude.set_id (YLIMINCLUDE);
+  yliminclude.set_hidden (true);
+  zliminclude.set_id (ZLIMINCLUDE);
+  zliminclude.set_hidden (true);
+  init ();
+}
+
+void
+line::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("xdata"))
+    set_xdata (val);
+  else if (pname.compare ("ydata"))
+    set_ydata (val);
+  else if (pname.compare ("zdata"))
+    set_zdata (val);
+  else if (pname.compare ("ldata"))
+    set_ldata (val);
+  else if (pname.compare ("udata"))
+    set_udata (val);
+  else if (pname.compare ("xldata"))
+    set_xldata (val);
+  else if (pname.compare ("xudata"))
+    set_xudata (val);
+  else if (pname.compare ("xdatasource"))
+    set_xdatasource (val);
+  else if (pname.compare ("ydatasource"))
+    set_ydatasource (val);
+  else if (pname.compare ("zdatasource"))
+    set_zdatasource (val);
+  else if (pname.compare ("color"))
+    set_color (val);
+  else if (pname.compare ("linestyle"))
+    set_linestyle (val);
+  else if (pname.compare ("linewidth"))
+    set_linewidth (val);
+  else if (pname.compare ("marker"))
+    set_marker (val);
+  else if (pname.compare ("markeredgecolor"))
+    set_markeredgecolor (val);
+  else if (pname.compare ("markerfacecolor"))
+    set_markerfacecolor (val);
+  else if (pname.compare ("markersize"))
+    set_markersize (val);
+  else if (pname.compare ("keylabel"))
+    set_keylabel (val);
+  else if (pname.compare ("interpreter"))
+    set_interpreter (val);
+  else if (pname.compare ("displayname"))
+    set_displayname (val);
+  else if (pname.compare ("erasemode"))
+    set_erasemode (val);
+  else if (pname.compare ("xliminclude"))
+    set_xliminclude (val);
+  else if (pname.compare ("yliminclude"))
+    set_yliminclude (val);
+  else if (pname.compare ("zliminclude"))
+    set_zliminclude (val);
+  else
+    base_properties::set (pname, "line", val);
+}
+
+octave_value
+line::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("xdata", get_xdata ());
+  m.assign ("ydata", get_ydata ());
+  m.assign ("zdata", get_zdata ());
+  m.assign ("ldata", get_ldata ());
+  m.assign ("udata", get_udata ());
+  m.assign ("xldata", get_xldata ());
+  m.assign ("xudata", get_xudata ());
+  m.assign ("xdatasource", get_xdatasource ());
+  m.assign ("ydatasource", get_ydatasource ());
+  m.assign ("zdatasource", get_zdatasource ());
+  m.assign ("color", get_color ());
+  m.assign ("linestyle", get_linestyle ());
+  m.assign ("linewidth", get_linewidth ());
+  m.assign ("marker", get_marker ());
+  m.assign ("markeredgecolor", get_markeredgecolor ());
+  m.assign ("markerfacecolor", get_markerfacecolor ());
+  m.assign ("markersize", get_markersize ());
+  m.assign ("keylabel", get_keylabel ());
+  m.assign ("interpreter", get_interpreter ());
+  m.assign ("displayname", get_displayname ());
+  m.assign ("erasemode", get_erasemode ());
+  if (all)
+    m.assign ("xlim", get_xlim ());
+  if (all)
+    m.assign ("ylim", get_ylim ());
+  if (all)
+    m.assign ("zlim", get_zlim ());
+  if (all)
+    m.assign ("xliminclude", get_xliminclude ());
+  if (all)
+    m.assign ("yliminclude", get_yliminclude ());
+  if (all)
+    m.assign ("zliminclude", get_zliminclude ());
+
+  return m;
+}
+
+octave_value
+line::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("xdata"))
+    retval = get_xdata ();
+  else if (pname.compare ("ydata"))
+    retval = get_ydata ();
+  else if (pname.compare ("zdata"))
+    retval = get_zdata ();
+  else if (pname.compare ("ldata"))
+    retval = get_ldata ();
+  else if (pname.compare ("udata"))
+    retval = get_udata ();
+  else if (pname.compare ("xldata"))
+    retval = get_xldata ();
+  else if (pname.compare ("xudata"))
+    retval = get_xudata ();
+  else if (pname.compare ("xdatasource"))
+    retval = get_xdatasource ();
+  else if (pname.compare ("ydatasource"))
+    retval = get_ydatasource ();
+  else if (pname.compare ("zdatasource"))
+    retval = get_zdatasource ();
+  else if (pname.compare ("color"))
+    retval = get_color ();
+  else if (pname.compare ("linestyle"))
+    retval = get_linestyle ();
+  else if (pname.compare ("linewidth"))
+    retval = get_linewidth ();
+  else if (pname.compare ("marker"))
+    retval = get_marker ();
+  else if (pname.compare ("markeredgecolor"))
+    retval = get_markeredgecolor ();
+  else if (pname.compare ("markerfacecolor"))
+    retval = get_markerfacecolor ();
+  else if (pname.compare ("markersize"))
+    retval = get_markersize ();
+  else if (pname.compare ("keylabel"))
+    retval = get_keylabel ();
+  else if (pname.compare ("interpreter"))
+    retval = get_interpreter ();
+  else if (pname.compare ("displayname"))
+    retval = get_displayname ();
+  else if (pname.compare ("erasemode"))
+    retval = get_erasemode ();
+  else if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("zlim"))
+    retval = get_zlim ();
+  else if (pname.compare ("xliminclude"))
+    retval = get_xliminclude ();
+  else if (pname.compare ("yliminclude"))
+    retval = get_yliminclude ();
+  else if (pname.compare ("zliminclude"))
+    retval = get_zliminclude ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+line::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("xdata"))
+    return property (&xdata, true);
+  else if (pname.compare ("ydata"))
+    return property (&ydata, true);
+  else if (pname.compare ("zdata"))
+    return property (&zdata, true);
+  else if (pname.compare ("ldata"))
+    return property (&ldata, true);
+  else if (pname.compare ("udata"))
+    return property (&udata, true);
+  else if (pname.compare ("xldata"))
+    return property (&xldata, true);
+  else if (pname.compare ("xudata"))
+    return property (&xudata, true);
+  else if (pname.compare ("xdatasource"))
+    return property (&xdatasource, true);
+  else if (pname.compare ("ydatasource"))
+    return property (&ydatasource, true);
+  else if (pname.compare ("zdatasource"))
+    return property (&zdatasource, true);
+  else if (pname.compare ("color"))
+    return property (&color, true);
+  else if (pname.compare ("linestyle"))
+    return property (&linestyle, true);
+  else if (pname.compare ("linewidth"))
+    return property (&linewidth, true);
+  else if (pname.compare ("marker"))
+    return property (&marker, true);
+  else if (pname.compare ("markeredgecolor"))
+    return property (&markeredgecolor, true);
+  else if (pname.compare ("markerfacecolor"))
+    return property (&markerfacecolor, true);
+  else if (pname.compare ("markersize"))
+    return property (&markersize, true);
+  else if (pname.compare ("keylabel"))
+    return property (&keylabel, true);
+  else if (pname.compare ("interpreter"))
+    return property (&interpreter, true);
+  else if (pname.compare ("displayname"))
+    return property (&displayname, true);
+  else if (pname.compare ("erasemode"))
+    return property (&erasemode, true);
+  else if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("zlim"))
+    return property (&zlim, true);
+  else if (pname.compare ("xliminclude"))
+    return property (&xliminclude, true);
+  else if (pname.compare ("yliminclude"))
+    return property (&yliminclude, true);
+  else if (pname.compare ("zliminclude"))
+    return property (&zliminclude, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+line::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["xdata"] = default_data ();
+  m["ydata"] = default_data ();
+  m["zdata"] = Matrix ();
+  m["ldata"] = Matrix ();
+  m["udata"] = Matrix ();
+  m["xldata"] = Matrix ();
+  m["xudata"] = Matrix ();
+  m["xdatasource"] = "";
+  m["ydatasource"] = "";
+  m["zdatasource"] = "";
+  m["color"] = octave_value ();
+  m["linestyle"] = "-";
+  m["linewidth"] = 0.5;
+  m["marker"] = "none";
+  m["markeredgecolor"] = "auto";
+  m["markerfacecolor"] = "none";
+  m["markersize"] = 6;
+  m["keylabel"] = "";
+  m["interpreter"] = "tex";
+  m["displayname"] = "";
+  m["erasemode"] = "normal";
+  m["xlim"] = Matrix ();
+  m["ylim"] = Matrix ();
+  m["zlim"] = Matrix ();
+  m["xliminclude"] = "on";
+  m["yliminclude"] = "on";
+  m["zliminclude"] = "off";
+
+  return m;
+}
+
+std::string line::properties::go_name ("line");
+
+bool line::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("xdata");
+      all_properties.insert ("ydata");
+      all_properties.insert ("zdata");
+      all_properties.insert ("ldata");
+      all_properties.insert ("udata");
+      all_properties.insert ("xldata");
+      all_properties.insert ("xudata");
+      all_properties.insert ("xdatasource");
+      all_properties.insert ("ydatasource");
+      all_properties.insert ("zdatasource");
+      all_properties.insert ("color");
+      all_properties.insert ("linestyle");
+      all_properties.insert ("linewidth");
+      all_properties.insert ("marker");
+      all_properties.insert ("markeredgecolor");
+      all_properties.insert ("markerfacecolor");
+      all_properties.insert ("markersize");
+      all_properties.insert ("keylabel");
+      all_properties.insert ("interpreter");
+      all_properties.insert ("displayname");
+      all_properties.insert ("erasemode");
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("zlim");
+      all_properties.insert ("xliminclude");
+      all_properties.insert ("yliminclude");
+      all_properties.insert ("zliminclude");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "line");
+}
+
+// ******** text ********
+
+text::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    string ("string", mh, ""),
+    units ("units", mh, "{data}|pixels|normalized|inches|centimeters|points"),
+    position ("position", mh, Matrix (1, 3, 0.0)),
+    rotation ("rotation", mh, 0),
+    horizontalalignment ("horizontalalignment", mh, "{left}|center|right"),
+    color ("color", mh, color_values (0, 0, 0)),
+    fontname ("fontname", mh, OCTAVE_DEFAULT_FONTNAME),
+    fontsize ("fontsize", mh, 10),
+    fontangle ("fontangle", mh, "{normal}|italic|oblique"),
+    fontweight ("fontweight", mh, "light|{normal}|demi|bold"),
+    interpreter ("interpreter", mh, "{tex}|none|latex"),
+    backgroundcolor ("backgroundcolor", mh, "{none}"),
+    displayname ("displayname", mh, ""),
+    edgecolor ("edgecolor", mh, "{none}"),
+    erasemode ("erasemode", mh, "{normal}|none|xor|background"),
+    editing ("editing", mh, "off"),
+    fontunits ("fontunits", mh, "inches|centimeters|normalized|{points}|pixels"),
+    linestyle ("linestyle", mh, "{-}|--|:|-.|none"),
+    linewidth ("linewidth", mh, 0.5),
+    margin ("margin", mh, 1),
+    verticalalignment ("verticalalignment", mh, "top|cap|{middle}|baseline|bottom"),
+    xlim ("xlim", mh, Matrix ()),
+    ylim ("ylim", mh, Matrix ()),
+    zlim ("zlim", mh, Matrix ()),
+    xliminclude ("xliminclude", mh, "on"),
+    yliminclude ("yliminclude", mh, "on"),
+    zliminclude ("zliminclude", mh, "off")
+{
+  string.set_id (STRING);
+  units.set_id (UNITS);
+  position.set_id (POSITION);
+  rotation.set_id (ROTATION);
+  horizontalalignment.set_id (HORIZONTALALIGNMENT);
+  color.set_id (COLOR);
+  fontname.set_id (FONTNAME);
+  fontsize.set_id (FONTSIZE);
+  fontangle.set_id (FONTANGLE);
+  fontweight.set_id (FONTWEIGHT);
+  interpreter.set_id (INTERPRETER);
+  backgroundcolor.set_id (BACKGROUNDCOLOR);
+  displayname.set_id (DISPLAYNAME);
+  edgecolor.set_id (EDGECOLOR);
+  erasemode.set_id (ERASEMODE);
+  editing.set_id (EDITING);
+  fontunits.set_id (FONTUNITS);
+  linestyle.set_id (LINESTYLE);
+  linewidth.set_id (LINEWIDTH);
+  margin.set_id (MARGIN);
+  verticalalignment.set_id (VERTICALALIGNMENT);
+  xlim.set_id (XLIM);
+  xlim.set_hidden (true);
+  ylim.set_id (YLIM);
+  ylim.set_hidden (true);
+  zlim.set_id (ZLIM);
+  zlim.set_hidden (true);
+  xliminclude.set_id (XLIMINCLUDE);
+  xliminclude.set_hidden (true);
+  yliminclude.set_id (YLIMINCLUDE);
+  yliminclude.set_hidden (true);
+  zliminclude.set_id (ZLIMINCLUDE);
+  zliminclude.set_hidden (true);
+  init ();
+}
+
+void
+text::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("string"))
+    set_string (val);
+  else if (pname.compare ("units"))
+    set_units (val);
+  else if (pname.compare ("position"))
+    set_position (val);
+  else if (pname.compare ("rotation"))
+    set_rotation (val);
+  else if (pname.compare ("horizontalalignment"))
+    set_horizontalalignment (val);
+  else if (pname.compare ("color"))
+    set_color (val);
+  else if (pname.compare ("fontname"))
+    set_fontname (val);
+  else if (pname.compare ("fontsize"))
+    set_fontsize (val);
+  else if (pname.compare ("fontangle"))
+    set_fontangle (val);
+  else if (pname.compare ("fontweight"))
+    set_fontweight (val);
+  else if (pname.compare ("interpreter"))
+    set_interpreter (val);
+  else if (pname.compare ("backgroundcolor"))
+    set_backgroundcolor (val);
+  else if (pname.compare ("displayname"))
+    set_displayname (val);
+  else if (pname.compare ("edgecolor"))
+    set_edgecolor (val);
+  else if (pname.compare ("erasemode"))
+    set_erasemode (val);
+  else if (pname.compare ("editing"))
+    set_editing (val);
+  else if (pname.compare ("fontunits"))
+    set_fontunits (val);
+  else if (pname.compare ("linestyle"))
+    set_linestyle (val);
+  else if (pname.compare ("linewidth"))
+    set_linewidth (val);
+  else if (pname.compare ("margin"))
+    set_margin (val);
+  else if (pname.compare ("verticalalignment"))
+    set_verticalalignment (val);
+  else if (pname.compare ("xliminclude"))
+    set_xliminclude (val);
+  else if (pname.compare ("yliminclude"))
+    set_yliminclude (val);
+  else if (pname.compare ("zliminclude"))
+    set_zliminclude (val);
+  else
+    base_properties::set (pname, "text", val);
+}
+
+octave_value
+text::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("string", get_string ());
+  m.assign ("units", get_units ());
+  m.assign ("position", get_position ());
+  m.assign ("rotation", get_rotation ());
+  m.assign ("horizontalalignment", get_horizontalalignment ());
+  m.assign ("color", get_color ());
+  m.assign ("fontname", get_fontname ());
+  m.assign ("fontsize", get_fontsize ());
+  m.assign ("fontangle", get_fontangle ());
+  m.assign ("fontweight", get_fontweight ());
+  m.assign ("interpreter", get_interpreter ());
+  m.assign ("backgroundcolor", get_backgroundcolor ());
+  m.assign ("displayname", get_displayname ());
+  m.assign ("edgecolor", get_edgecolor ());
+  m.assign ("erasemode", get_erasemode ());
+  m.assign ("editing", get_editing ());
+  m.assign ("fontunits", get_fontunits ());
+  m.assign ("linestyle", get_linestyle ());
+  m.assign ("linewidth", get_linewidth ());
+  m.assign ("margin", get_margin ());
+  m.assign ("verticalalignment", get_verticalalignment ());
+  if (all)
+    m.assign ("xlim", get_xlim ());
+  if (all)
+    m.assign ("ylim", get_ylim ());
+  if (all)
+    m.assign ("zlim", get_zlim ());
+  if (all)
+    m.assign ("xliminclude", get_xliminclude ());
+  if (all)
+    m.assign ("yliminclude", get_yliminclude ());
+  if (all)
+    m.assign ("zliminclude", get_zliminclude ());
+
+  return m;
+}
+
+octave_value
+text::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("string"))
+    retval = get_string ();
+  else if (pname.compare ("units"))
+    retval = get_units ();
+  else if (pname.compare ("position"))
+    retval = get_position ();
+  else if (pname.compare ("rotation"))
+    retval = get_rotation ();
+  else if (pname.compare ("horizontalalignment"))
+    retval = get_horizontalalignment ();
+  else if (pname.compare ("color"))
+    retval = get_color ();
+  else if (pname.compare ("fontname"))
+    retval = get_fontname ();
+  else if (pname.compare ("fontsize"))
+    retval = get_fontsize ();
+  else if (pname.compare ("fontangle"))
+    retval = get_fontangle ();
+  else if (pname.compare ("fontweight"))
+    retval = get_fontweight ();
+  else if (pname.compare ("interpreter"))
+    retval = get_interpreter ();
+  else if (pname.compare ("backgroundcolor"))
+    retval = get_backgroundcolor ();
+  else if (pname.compare ("displayname"))
+    retval = get_displayname ();
+  else if (pname.compare ("edgecolor"))
+    retval = get_edgecolor ();
+  else if (pname.compare ("erasemode"))
+    retval = get_erasemode ();
+  else if (pname.compare ("editing"))
+    retval = get_editing ();
+  else if (pname.compare ("fontunits"))
+    retval = get_fontunits ();
+  else if (pname.compare ("linestyle"))
+    retval = get_linestyle ();
+  else if (pname.compare ("linewidth"))
+    retval = get_linewidth ();
+  else if (pname.compare ("margin"))
+    retval = get_margin ();
+  else if (pname.compare ("verticalalignment"))
+    retval = get_verticalalignment ();
+  else if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("zlim"))
+    retval = get_zlim ();
+  else if (pname.compare ("xliminclude"))
+    retval = get_xliminclude ();
+  else if (pname.compare ("yliminclude"))
+    retval = get_yliminclude ();
+  else if (pname.compare ("zliminclude"))
+    retval = get_zliminclude ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+text::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("string"))
+    return property (&string, true);
+  else if (pname.compare ("units"))
+    return property (&units, true);
+  else if (pname.compare ("position"))
+    return property (&position, true);
+  else if (pname.compare ("rotation"))
+    return property (&rotation, true);
+  else if (pname.compare ("horizontalalignment"))
+    return property (&horizontalalignment, true);
+  else if (pname.compare ("color"))
+    return property (&color, true);
+  else if (pname.compare ("fontname"))
+    return property (&fontname, true);
+  else if (pname.compare ("fontsize"))
+    return property (&fontsize, true);
+  else if (pname.compare ("fontangle"))
+    return property (&fontangle, true);
+  else if (pname.compare ("fontweight"))
+    return property (&fontweight, true);
+  else if (pname.compare ("interpreter"))
+    return property (&interpreter, true);
+  else if (pname.compare ("backgroundcolor"))
+    return property (&backgroundcolor, true);
+  else if (pname.compare ("displayname"))
+    return property (&displayname, true);
+  else if (pname.compare ("edgecolor"))
+    return property (&edgecolor, true);
+  else if (pname.compare ("erasemode"))
+    return property (&erasemode, true);
+  else if (pname.compare ("editing"))
+    return property (&editing, true);
+  else if (pname.compare ("fontunits"))
+    return property (&fontunits, true);
+  else if (pname.compare ("linestyle"))
+    return property (&linestyle, true);
+  else if (pname.compare ("linewidth"))
+    return property (&linewidth, true);
+  else if (pname.compare ("margin"))
+    return property (&margin, true);
+  else if (pname.compare ("verticalalignment"))
+    return property (&verticalalignment, true);
+  else if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("zlim"))
+    return property (&zlim, true);
+  else if (pname.compare ("xliminclude"))
+    return property (&xliminclude, true);
+  else if (pname.compare ("yliminclude"))
+    return property (&yliminclude, true);
+  else if (pname.compare ("zliminclude"))
+    return property (&zliminclude, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+text::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["string"] = "";
+  m["units"] = "data";
+  m["position"] = Matrix (1, 3, 0.0);
+  m["rotation"] = 0;
+  m["horizontalalignment"] = "left";
+  m["color"] = octave_value ();
+  m["fontname"] = OCTAVE_DEFAULT_FONTNAME;
+  m["fontsize"] = 10;
+  m["fontangle"] = "normal";
+  m["fontweight"] = "normal";
+  m["interpreter"] = "tex";
+  m["backgroundcolor"] = "none";
+  m["displayname"] = "";
+  m["edgecolor"] = "none";
+  m["erasemode"] = "normal";
+  m["editing"] = "off";
+  m["fontunits"] = "points";
+  m["linestyle"] = "-";
+  m["linewidth"] = 0.5;
+  m["margin"] = 1;
+  m["verticalalignment"] = "middle";
+  m["xlim"] = Matrix ();
+  m["ylim"] = Matrix ();
+  m["zlim"] = Matrix ();
+  m["xliminclude"] = "on";
+  m["yliminclude"] = "on";
+  m["zliminclude"] = "off";
+
+  return m;
+}
+
+std::string text::properties::go_name ("text");
+
+bool text::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("string");
+      all_properties.insert ("units");
+      all_properties.insert ("position");
+      all_properties.insert ("rotation");
+      all_properties.insert ("horizontalalignment");
+      all_properties.insert ("color");
+      all_properties.insert ("fontname");
+      all_properties.insert ("fontsize");
+      all_properties.insert ("fontangle");
+      all_properties.insert ("fontweight");
+      all_properties.insert ("interpreter");
+      all_properties.insert ("backgroundcolor");
+      all_properties.insert ("displayname");
+      all_properties.insert ("edgecolor");
+      all_properties.insert ("erasemode");
+      all_properties.insert ("editing");
+      all_properties.insert ("fontunits");
+      all_properties.insert ("linestyle");
+      all_properties.insert ("linewidth");
+      all_properties.insert ("margin");
+      all_properties.insert ("verticalalignment");
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("zlim");
+      all_properties.insert ("xliminclude");
+      all_properties.insert ("yliminclude");
+      all_properties.insert ("zliminclude");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "text");
+}
+
+// ******** image ********
+
+image::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    xdata ("xdata", mh, Matrix ()),
+    ydata ("ydata", mh, Matrix ()),
+    cdata ("cdata", mh, Matrix ()),
+    cdatamapping ("cdatamapping", mh, "{scaled}|direct"),
+    xlim ("xlim", mh, Matrix()),
+    ylim ("ylim", mh, Matrix()),
+    clim ("clim", mh, Matrix()),
+    xliminclude ("xliminclude", mh, "on"),
+    yliminclude ("yliminclude", mh, "on"),
+    climinclude ("climinclude", mh, "on")
+{
+  xdata.set_id (XDATA);
+  ydata.set_id (YDATA);
+  cdata.set_id (CDATA);
+  cdatamapping.set_id (CDATAMAPPING);
+  xlim.set_id (XLIM);
+  xlim.set_hidden (true);
+  ylim.set_id (YLIM);
+  ylim.set_hidden (true);
+  clim.set_id (CLIM);
+  clim.set_hidden (true);
+  xliminclude.set_id (XLIMINCLUDE);
+  xliminclude.set_hidden (true);
+  yliminclude.set_id (YLIMINCLUDE);
+  yliminclude.set_hidden (true);
+  climinclude.set_id (CLIMINCLUDE);
+  climinclude.set_hidden (true);
+  init ();
+}
+
+void
+image::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("xdata"))
+    set_xdata (val);
+  else if (pname.compare ("ydata"))
+    set_ydata (val);
+  else if (pname.compare ("cdata"))
+    set_cdata (val);
+  else if (pname.compare ("cdatamapping"))
+    set_cdatamapping (val);
+  else if (pname.compare ("xliminclude"))
+    set_xliminclude (val);
+  else if (pname.compare ("yliminclude"))
+    set_yliminclude (val);
+  else if (pname.compare ("climinclude"))
+    set_climinclude (val);
+  else
+    base_properties::set (pname, "image", val);
+}
+
+octave_value
+image::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("xdata", get_xdata ());
+  m.assign ("ydata", get_ydata ());
+  m.assign ("cdata", get_cdata ());
+  m.assign ("cdatamapping", get_cdatamapping ());
+  if (all)
+    m.assign ("xlim", get_xlim ());
+  if (all)
+    m.assign ("ylim", get_ylim ());
+  if (all)
+    m.assign ("clim", get_clim ());
+  if (all)
+    m.assign ("xliminclude", get_xliminclude ());
+  if (all)
+    m.assign ("yliminclude", get_yliminclude ());
+  if (all)
+    m.assign ("climinclude", get_climinclude ());
+
+  return m;
+}
+
+octave_value
+image::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("xdata"))
+    retval = get_xdata ();
+  else if (pname.compare ("ydata"))
+    retval = get_ydata ();
+  else if (pname.compare ("cdata"))
+    retval = get_cdata ();
+  else if (pname.compare ("cdatamapping"))
+    retval = get_cdatamapping ();
+  else if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("clim"))
+    retval = get_clim ();
+  else if (pname.compare ("xliminclude"))
+    retval = get_xliminclude ();
+  else if (pname.compare ("yliminclude"))
+    retval = get_yliminclude ();
+  else if (pname.compare ("climinclude"))
+    retval = get_climinclude ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+image::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("xdata"))
+    return property (&xdata, true);
+  else if (pname.compare ("ydata"))
+    return property (&ydata, true);
+  else if (pname.compare ("cdata"))
+    return property (&cdata, true);
+  else if (pname.compare ("cdatamapping"))
+    return property (&cdatamapping, true);
+  else if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("clim"))
+    return property (&clim, true);
+  else if (pname.compare ("xliminclude"))
+    return property (&xliminclude, true);
+  else if (pname.compare ("yliminclude"))
+    return property (&yliminclude, true);
+  else if (pname.compare ("climinclude"))
+    return property (&climinclude, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+image::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["xdata"] = Matrix ();
+  m["ydata"] = Matrix ();
+  m["cdata"] = Matrix ();
+  m["cdatamapping"] = "scaled";
+  m["xlim"] = Matrix();
+  m["ylim"] = Matrix();
+  m["clim"] = Matrix();
+  m["xliminclude"] = "on";
+  m["yliminclude"] = "on";
+  m["climinclude"] = "on";
+
+  return m;
+}
+
+std::string image::properties::go_name ("image");
+
+bool image::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("xdata");
+      all_properties.insert ("ydata");
+      all_properties.insert ("cdata");
+      all_properties.insert ("cdatamapping");
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("clim");
+      all_properties.insert ("xliminclude");
+      all_properties.insert ("yliminclude");
+      all_properties.insert ("climinclude");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "image");
+}
+
+// ******** patch ********
+
+patch::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    xdata ("xdata", mh, Matrix ()),
+    ydata ("ydata", mh, Matrix ()),
+    zdata ("zdata", mh, Matrix ()),
+    cdata ("cdata", mh, Matrix ()),
+    cdatamapping ("cdatamapping", mh, "{scaled}|direct"),
+    faces ("faces", mh, Matrix ()),
+    facevertexalphadata ("facevertexalphadata", mh, Matrix ()),
+    facevertexcdata ("facevertexcdata", mh, Matrix ()),
+    vertices ("vertices", mh, Matrix ()),
+    vertexnormals ("vertexnormals", mh, Matrix ()),
+    normalmode ("normalmode", mh, "{auto}|manual"),
+    facecolor ("facecolor", mh, "{flat}|none|interp"),
+    facealpha ("facealpha", mh, double_radio_property (1.0, radio_values ("flat|interp"))),
+    facelighting ("facelighting", mh, "flat|{none}|gouraud|phong"),
+    edgecolor ("edgecolor", mh, color_property (color_values (0, 0, 0), radio_values ("flat|none|interp"))),
+    edgealpha ("edgealpha", mh, double_radio_property (1.0, radio_values ("flat|interp"))),
+    edgelighting ("edgelighting", mh, "{none}|flat|gouraud|phong"),
+    backfacelighting ("backfacelighting", mh, "{reverselit}|unlit|lit"),
+    ambientstrength ("ambientstrength", mh, 0.3),
+    diffusestrength ("diffusestrength", mh, 0.6),
+    specularstrength ("specularstrength", mh, 0.6),
+    specularexponent ("specularexponent", mh, 10.0),
+    specularcolorreflectance ("specularcolorreflectance", mh, 1.0),
+    erasemode ("erasemode", mh, "{normal}|background|xor|none"),
+    linestyle ("linestyle", mh, "{-}|--|:|-.|none"),
+    linewidth ("linewidth", mh, 0.5),
+    marker ("marker", mh, "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h"),
+    markeredgecolor ("markeredgecolor", mh, "{auto}|none"),
+    markerfacecolor ("markerfacecolor", mh, "auto|{none}"),
+    markersize ("markersize", mh, 6),
+    keylabel ("keylabel", mh, ""),
+    interpreter ("interpreter", mh, "{tex}|none|latex"),
+    alphadatamapping ("alphadatamapping", mh, "none|{scaled}|direct"),
+    xlim ("xlim", mh, Matrix ()),
+    ylim ("ylim", mh, Matrix ()),
+    zlim ("zlim", mh, Matrix ()),
+    clim ("clim", mh, Matrix ()),
+    alim ("alim", mh, Matrix ()),
+    xliminclude ("xliminclude", mh, "on"),
+    yliminclude ("yliminclude", mh, "on"),
+    zliminclude ("zliminclude", mh, "on"),
+    climinclude ("climinclude", mh, "on"),
+    aliminclude ("aliminclude", mh, "on")
+{
+  xdata.set_id (XDATA);
+  ydata.set_id (YDATA);
+  zdata.set_id (ZDATA);
+  cdata.set_id (CDATA);
+  cdatamapping.set_id (CDATAMAPPING);
+  faces.set_id (FACES);
+  facevertexalphadata.set_id (FACEVERTEXALPHADATA);
+  facevertexcdata.set_id (FACEVERTEXCDATA);
+  vertices.set_id (VERTICES);
+  vertexnormals.set_id (VERTEXNORMALS);
+  normalmode.set_id (NORMALMODE);
+  facecolor.set_id (FACECOLOR);
+  facealpha.set_id (FACEALPHA);
+  facelighting.set_id (FACELIGHTING);
+  edgecolor.set_id (EDGECOLOR);
+  edgealpha.set_id (EDGEALPHA);
+  edgelighting.set_id (EDGELIGHTING);
+  backfacelighting.set_id (BACKFACELIGHTING);
+  ambientstrength.set_id (AMBIENTSTRENGTH);
+  diffusestrength.set_id (DIFFUSESTRENGTH);
+  specularstrength.set_id (SPECULARSTRENGTH);
+  specularexponent.set_id (SPECULAREXPONENT);
+  specularcolorreflectance.set_id (SPECULARCOLORREFLECTANCE);
+  erasemode.set_id (ERASEMODE);
+  linestyle.set_id (LINESTYLE);
+  linewidth.set_id (LINEWIDTH);
+  marker.set_id (MARKER);
+  markeredgecolor.set_id (MARKEREDGECOLOR);
+  markerfacecolor.set_id (MARKERFACECOLOR);
+  markersize.set_id (MARKERSIZE);
+  keylabel.set_id (KEYLABEL);
+  interpreter.set_id (INTERPRETER);
+  alphadatamapping.set_id (ALPHADATAMAPPING);
+  xlim.set_id (XLIM);
+  xlim.set_hidden (true);
+  ylim.set_id (YLIM);
+  ylim.set_hidden (true);
+  zlim.set_id (ZLIM);
+  zlim.set_hidden (true);
+  clim.set_id (CLIM);
+  clim.set_hidden (true);
+  alim.set_id (ALIM);
+  alim.set_hidden (true);
+  xliminclude.set_id (XLIMINCLUDE);
+  xliminclude.set_hidden (true);
+  yliminclude.set_id (YLIMINCLUDE);
+  yliminclude.set_hidden (true);
+  zliminclude.set_id (ZLIMINCLUDE);
+  zliminclude.set_hidden (true);
+  climinclude.set_id (CLIMINCLUDE);
+  climinclude.set_hidden (true);
+  aliminclude.set_id (ALIMINCLUDE);
+  aliminclude.set_hidden (true);
+  init ();
+}
+
+void
+patch::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("xdata"))
+    set_xdata (val);
+  else if (pname.compare ("ydata"))
+    set_ydata (val);
+  else if (pname.compare ("zdata"))
+    set_zdata (val);
+  else if (pname.compare ("cdata"))
+    set_cdata (val);
+  else if (pname.compare ("cdatamapping"))
+    set_cdatamapping (val);
+  else if (pname.compare ("faces"))
+    set_faces (val);
+  else if (pname.compare ("facevertexalphadata"))
+    set_facevertexalphadata (val);
+  else if (pname.compare ("facevertexcdata"))
+    set_facevertexcdata (val);
+  else if (pname.compare ("vertices"))
+    set_vertices (val);
+  else if (pname.compare ("vertexnormals"))
+    set_vertexnormals (val);
+  else if (pname.compare ("normalmode"))
+    set_normalmode (val);
+  else if (pname.compare ("facecolor"))
+    set_facecolor (val);
+  else if (pname.compare ("facealpha"))
+    set_facealpha (val);
+  else if (pname.compare ("facelighting"))
+    set_facelighting (val);
+  else if (pname.compare ("edgecolor"))
+    set_edgecolor (val);
+  else if (pname.compare ("edgealpha"))
+    set_edgealpha (val);
+  else if (pname.compare ("edgelighting"))
+    set_edgelighting (val);
+  else if (pname.compare ("backfacelighting"))
+    set_backfacelighting (val);
+  else if (pname.compare ("ambientstrength"))
+    set_ambientstrength (val);
+  else if (pname.compare ("diffusestrength"))
+    set_diffusestrength (val);
+  else if (pname.compare ("specularstrength"))
+    set_specularstrength (val);
+  else if (pname.compare ("specularexponent"))
+    set_specularexponent (val);
+  else if (pname.compare ("specularcolorreflectance"))
+    set_specularcolorreflectance (val);
+  else if (pname.compare ("erasemode"))
+    set_erasemode (val);
+  else if (pname.compare ("linestyle"))
+    set_linestyle (val);
+  else if (pname.compare ("linewidth"))
+    set_linewidth (val);
+  else if (pname.compare ("marker"))
+    set_marker (val);
+  else if (pname.compare ("markeredgecolor"))
+    set_markeredgecolor (val);
+  else if (pname.compare ("markerfacecolor"))
+    set_markerfacecolor (val);
+  else if (pname.compare ("markersize"))
+    set_markersize (val);
+  else if (pname.compare ("keylabel"))
+    set_keylabel (val);
+  else if (pname.compare ("interpreter"))
+    set_interpreter (val);
+  else if (pname.compare ("alphadatamapping"))
+    set_alphadatamapping (val);
+  else if (pname.compare ("xliminclude"))
+    set_xliminclude (val);
+  else if (pname.compare ("yliminclude"))
+    set_yliminclude (val);
+  else if (pname.compare ("zliminclude"))
+    set_zliminclude (val);
+  else if (pname.compare ("climinclude"))
+    set_climinclude (val);
+  else if (pname.compare ("aliminclude"))
+    set_aliminclude (val);
+  else
+    base_properties::set (pname, "patch", val);
+}
+
+octave_value
+patch::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("xdata", get_xdata ());
+  m.assign ("ydata", get_ydata ());
+  m.assign ("zdata", get_zdata ());
+  m.assign ("cdata", get_cdata ());
+  m.assign ("cdatamapping", get_cdatamapping ());
+  m.assign ("faces", get_faces ());
+  m.assign ("facevertexalphadata", get_facevertexalphadata ());
+  m.assign ("facevertexcdata", get_facevertexcdata ());
+  m.assign ("vertices", get_vertices ());
+  m.assign ("vertexnormals", get_vertexnormals ());
+  m.assign ("normalmode", get_normalmode ());
+  m.assign ("facecolor", get_facecolor ());
+  m.assign ("facealpha", get_facealpha ());
+  m.assign ("facelighting", get_facelighting ());
+  m.assign ("edgecolor", get_edgecolor ());
+  m.assign ("edgealpha", get_edgealpha ());
+  m.assign ("edgelighting", get_edgelighting ());
+  m.assign ("backfacelighting", get_backfacelighting ());
+  m.assign ("ambientstrength", get_ambientstrength ());
+  m.assign ("diffusestrength", get_diffusestrength ());
+  m.assign ("specularstrength", get_specularstrength ());
+  m.assign ("specularexponent", get_specularexponent ());
+  m.assign ("specularcolorreflectance", get_specularcolorreflectance ());
+  m.assign ("erasemode", get_erasemode ());
+  m.assign ("linestyle", get_linestyle ());
+  m.assign ("linewidth", get_linewidth ());
+  m.assign ("marker", get_marker ());
+  m.assign ("markeredgecolor", get_markeredgecolor ());
+  m.assign ("markerfacecolor", get_markerfacecolor ());
+  m.assign ("markersize", get_markersize ());
+  m.assign ("keylabel", get_keylabel ());
+  m.assign ("interpreter", get_interpreter ());
+  m.assign ("alphadatamapping", get_alphadatamapping ());
+  if (all)
+    m.assign ("xlim", get_xlim ());
+  if (all)
+    m.assign ("ylim", get_ylim ());
+  if (all)
+    m.assign ("zlim", get_zlim ());
+  if (all)
+    m.assign ("clim", get_clim ());
+  if (all)
+    m.assign ("alim", get_alim ());
+  if (all)
+    m.assign ("xliminclude", get_xliminclude ());
+  if (all)
+    m.assign ("yliminclude", get_yliminclude ());
+  if (all)
+    m.assign ("zliminclude", get_zliminclude ());
+  if (all)
+    m.assign ("climinclude", get_climinclude ());
+  if (all)
+    m.assign ("aliminclude", get_aliminclude ());
+
+  return m;
+}
+
+octave_value
+patch::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("xdata"))
+    retval = get_xdata ();
+  else if (pname.compare ("ydata"))
+    retval = get_ydata ();
+  else if (pname.compare ("zdata"))
+    retval = get_zdata ();
+  else if (pname.compare ("cdata"))
+    retval = get_cdata ();
+  else if (pname.compare ("cdatamapping"))
+    retval = get_cdatamapping ();
+  else if (pname.compare ("faces"))
+    retval = get_faces ();
+  else if (pname.compare ("facevertexalphadata"))
+    retval = get_facevertexalphadata ();
+  else if (pname.compare ("facevertexcdata"))
+    retval = get_facevertexcdata ();
+  else if (pname.compare ("vertices"))
+    retval = get_vertices ();
+  else if (pname.compare ("vertexnormals"))
+    retval = get_vertexnormals ();
+  else if (pname.compare ("normalmode"))
+    retval = get_normalmode ();
+  else if (pname.compare ("facecolor"))
+    retval = get_facecolor ();
+  else if (pname.compare ("facealpha"))
+    retval = get_facealpha ();
+  else if (pname.compare ("facelighting"))
+    retval = get_facelighting ();
+  else if (pname.compare ("edgecolor"))
+    retval = get_edgecolor ();
+  else if (pname.compare ("edgealpha"))
+    retval = get_edgealpha ();
+  else if (pname.compare ("edgelighting"))
+    retval = get_edgelighting ();
+  else if (pname.compare ("backfacelighting"))
+    retval = get_backfacelighting ();
+  else if (pname.compare ("ambientstrength"))
+    retval = get_ambientstrength ();
+  else if (pname.compare ("diffusestrength"))
+    retval = get_diffusestrength ();
+  else if (pname.compare ("specularstrength"))
+    retval = get_specularstrength ();
+  else if (pname.compare ("specularexponent"))
+    retval = get_specularexponent ();
+  else if (pname.compare ("specularcolorreflectance"))
+    retval = get_specularcolorreflectance ();
+  else if (pname.compare ("erasemode"))
+    retval = get_erasemode ();
+  else if (pname.compare ("linestyle"))
+    retval = get_linestyle ();
+  else if (pname.compare ("linewidth"))
+    retval = get_linewidth ();
+  else if (pname.compare ("marker"))
+    retval = get_marker ();
+  else if (pname.compare ("markeredgecolor"))
+    retval = get_markeredgecolor ();
+  else if (pname.compare ("markerfacecolor"))
+    retval = get_markerfacecolor ();
+  else if (pname.compare ("markersize"))
+    retval = get_markersize ();
+  else if (pname.compare ("keylabel"))
+    retval = get_keylabel ();
+  else if (pname.compare ("interpreter"))
+    retval = get_interpreter ();
+  else if (pname.compare ("alphadatamapping"))
+    retval = get_alphadatamapping ();
+  else if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("zlim"))
+    retval = get_zlim ();
+  else if (pname.compare ("clim"))
+    retval = get_clim ();
+  else if (pname.compare ("alim"))
+    retval = get_alim ();
+  else if (pname.compare ("xliminclude"))
+    retval = get_xliminclude ();
+  else if (pname.compare ("yliminclude"))
+    retval = get_yliminclude ();
+  else if (pname.compare ("zliminclude"))
+    retval = get_zliminclude ();
+  else if (pname.compare ("climinclude"))
+    retval = get_climinclude ();
+  else if (pname.compare ("aliminclude"))
+    retval = get_aliminclude ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+patch::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("xdata"))
+    return property (&xdata, true);
+  else if (pname.compare ("ydata"))
+    return property (&ydata, true);
+  else if (pname.compare ("zdata"))
+    return property (&zdata, true);
+  else if (pname.compare ("cdata"))
+    return property (&cdata, true);
+  else if (pname.compare ("cdatamapping"))
+    return property (&cdatamapping, true);
+  else if (pname.compare ("faces"))
+    return property (&faces, true);
+  else if (pname.compare ("facevertexalphadata"))
+    return property (&facevertexalphadata, true);
+  else if (pname.compare ("facevertexcdata"))
+    return property (&facevertexcdata, true);
+  else if (pname.compare ("vertices"))
+    return property (&vertices, true);
+  else if (pname.compare ("vertexnormals"))
+    return property (&vertexnormals, true);
+  else if (pname.compare ("normalmode"))
+    return property (&normalmode, true);
+  else if (pname.compare ("facecolor"))
+    return property (&facecolor, true);
+  else if (pname.compare ("facealpha"))
+    return property (&facealpha, true);
+  else if (pname.compare ("facelighting"))
+    return property (&facelighting, true);
+  else if (pname.compare ("edgecolor"))
+    return property (&edgecolor, true);
+  else if (pname.compare ("edgealpha"))
+    return property (&edgealpha, true);
+  else if (pname.compare ("edgelighting"))
+    return property (&edgelighting, true);
+  else if (pname.compare ("backfacelighting"))
+    return property (&backfacelighting, true);
+  else if (pname.compare ("ambientstrength"))
+    return property (&ambientstrength, true);
+  else if (pname.compare ("diffusestrength"))
+    return property (&diffusestrength, true);
+  else if (pname.compare ("specularstrength"))
+    return property (&specularstrength, true);
+  else if (pname.compare ("specularexponent"))
+    return property (&specularexponent, true);
+  else if (pname.compare ("specularcolorreflectance"))
+    return property (&specularcolorreflectance, true);
+  else if (pname.compare ("erasemode"))
+    return property (&erasemode, true);
+  else if (pname.compare ("linestyle"))
+    return property (&linestyle, true);
+  else if (pname.compare ("linewidth"))
+    return property (&linewidth, true);
+  else if (pname.compare ("marker"))
+    return property (&marker, true);
+  else if (pname.compare ("markeredgecolor"))
+    return property (&markeredgecolor, true);
+  else if (pname.compare ("markerfacecolor"))
+    return property (&markerfacecolor, true);
+  else if (pname.compare ("markersize"))
+    return property (&markersize, true);
+  else if (pname.compare ("keylabel"))
+    return property (&keylabel, true);
+  else if (pname.compare ("interpreter"))
+    return property (&interpreter, true);
+  else if (pname.compare ("alphadatamapping"))
+    return property (&alphadatamapping, true);
+  else if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("zlim"))
+    return property (&zlim, true);
+  else if (pname.compare ("clim"))
+    return property (&clim, true);
+  else if (pname.compare ("alim"))
+    return property (&alim, true);
+  else if (pname.compare ("xliminclude"))
+    return property (&xliminclude, true);
+  else if (pname.compare ("yliminclude"))
+    return property (&yliminclude, true);
+  else if (pname.compare ("zliminclude"))
+    return property (&zliminclude, true);
+  else if (pname.compare ("climinclude"))
+    return property (&climinclude, true);
+  else if (pname.compare ("aliminclude"))
+    return property (&aliminclude, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+patch::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["xdata"] = Matrix ();
+  m["ydata"] = Matrix ();
+  m["zdata"] = Matrix ();
+  m["cdata"] = Matrix ();
+  m["cdatamapping"] = "scaled";
+  m["faces"] = Matrix ();
+  m["facevertexalphadata"] = Matrix ();
+  m["facevertexcdata"] = Matrix ();
+  m["vertices"] = Matrix ();
+  m["vertexnormals"] = Matrix ();
+  m["normalmode"] = "auto";
+  m["facecolor"] = "flat";
+  m["facealpha"] = double_radio_property (1.0, radio_values ("flat|interp"));
+  m["facelighting"] = "none";
+  m["edgecolor"] = octave_value ();
+  m["edgealpha"] = double_radio_property (1.0, radio_values ("flat|interp"));
+  m["edgelighting"] = "none";
+  m["backfacelighting"] = "reverselit";
+  m["ambientstrength"] = 0.3;
+  m["diffusestrength"] = 0.6;
+  m["specularstrength"] = 0.6;
+  m["specularexponent"] = 10.0;
+  m["specularcolorreflectance"] = 1.0;
+  m["erasemode"] = "normal";
+  m["linestyle"] = "-";
+  m["linewidth"] = 0.5;
+  m["marker"] = "none";
+  m["markeredgecolor"] = "auto";
+  m["markerfacecolor"] = "none";
+  m["markersize"] = 6;
+  m["keylabel"] = "";
+  m["interpreter"] = "tex";
+  m["alphadatamapping"] = "scaled";
+  m["xlim"] = Matrix ();
+  m["ylim"] = Matrix ();
+  m["zlim"] = Matrix ();
+  m["clim"] = Matrix ();
+  m["alim"] = Matrix ();
+  m["xliminclude"] = "on";
+  m["yliminclude"] = "on";
+  m["zliminclude"] = "on";
+  m["climinclude"] = "on";
+  m["aliminclude"] = "on";
+
+  return m;
+}
+
+std::string patch::properties::go_name ("patch");
+
+bool patch::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("xdata");
+      all_properties.insert ("ydata");
+      all_properties.insert ("zdata");
+      all_properties.insert ("cdata");
+      all_properties.insert ("cdatamapping");
+      all_properties.insert ("faces");
+      all_properties.insert ("facevertexalphadata");
+      all_properties.insert ("facevertexcdata");
+      all_properties.insert ("vertices");
+      all_properties.insert ("vertexnormals");
+      all_properties.insert ("normalmode");
+      all_properties.insert ("facecolor");
+      all_properties.insert ("facealpha");
+      all_properties.insert ("facelighting");
+      all_properties.insert ("edgecolor");
+      all_properties.insert ("edgealpha");
+      all_properties.insert ("edgelighting");
+      all_properties.insert ("backfacelighting");
+      all_properties.insert ("ambientstrength");
+      all_properties.insert ("diffusestrength");
+      all_properties.insert ("specularstrength");
+      all_properties.insert ("specularexponent");
+      all_properties.insert ("specularcolorreflectance");
+      all_properties.insert ("erasemode");
+      all_properties.insert ("linestyle");
+      all_properties.insert ("linewidth");
+      all_properties.insert ("marker");
+      all_properties.insert ("markeredgecolor");
+      all_properties.insert ("markerfacecolor");
+      all_properties.insert ("markersize");
+      all_properties.insert ("keylabel");
+      all_properties.insert ("interpreter");
+      all_properties.insert ("alphadatamapping");
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("zlim");
+      all_properties.insert ("clim");
+      all_properties.insert ("alim");
+      all_properties.insert ("xliminclude");
+      all_properties.insert ("yliminclude");
+      all_properties.insert ("zliminclude");
+      all_properties.insert ("climinclude");
+      all_properties.insert ("aliminclude");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "patch");
+}
+
+// ******** surface ********
+
+surface::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    xdata ("xdata", mh, Matrix ()),
+    ydata ("ydata", mh, Matrix ()),
+    zdata ("zdata", mh, Matrix ()),
+    cdata ("cdata", mh, Matrix ()),
+    cdatamapping ("cdatamapping", mh, "{scaled}|direct"),
+    xdatasource ("xdatasource", mh, ""),
+    ydatasource ("ydatasource", mh, ""),
+    zdatasource ("zdatasource", mh, ""),
+    cdatasource ("cdatasource", mh, ""),
+    facecolor ("facecolor", mh, "{flat}|none|interp|texturemap"),
+    facealpha ("facealpha", mh, double_radio_property (1.0, radio_values ("flat|interp"))),
+    edgecolor ("edgecolor", mh, color_property (color_values (0, 0, 0), radio_values ("flat|none|interp"))),
+    linestyle ("linestyle", mh, "{-}|--|:|-.|none"),
+    linewidth ("linewidth", mh, 0.5),
+    marker ("marker", mh, "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h"),
+    markeredgecolor ("markeredgecolor", mh, "{auto}|none"),
+    markerfacecolor ("markerfacecolor", mh, "auto|{none}"),
+    markersize ("markersize", mh, 6),
+    keylabel ("keylabel", mh, ""),
+    interpreter ("interpreter", mh, "{tex}|none|latex"),
+    alphadata ("alphadata", mh, Matrix ()),
+    alphadatamapping ("alphadatamapping", mh, "none|direct|{scaled}"),
+    ambientstrength ("ambientstrength", mh, 0.3),
+    backfacelighting ("backfacelighting", mh, "unlit|lit|{reverselit}"),
+    diffusestrength ("diffusestrength", mh, 0.6),
+    edgealpha ("edgealpha", mh, double_radio_property (1.0, radio_values ("flat|interp"))),
+    edgelighting ("edgelighting", mh, "{none}|flat|gouraud|phong"),
+    erasemode ("erasemode", mh, "{normal}|none|xor|background"),
+    facelighting ("facelighting", mh, "{none}|flat|gouraud|phong"),
+    meshstyle ("meshstyle", mh, "{both}|row|column"),
+    normalmode ("normalmode", mh, "{auto}|manual"),
+    specularcolorreflectance ("specularcolorreflectance", mh, 1),
+    specularexponent ("specularexponent", mh, 10),
+    specularstrength ("specularstrength", mh, 0.9),
+    vertexnormals ("vertexnormals", mh, Matrix ()),
+    xlim ("xlim", mh, Matrix ()),
+    ylim ("ylim", mh, Matrix ()),
+    zlim ("zlim", mh, Matrix ()),
+    clim ("clim", mh, Matrix ()),
+    alim ("alim", mh, Matrix ()),
+    xliminclude ("xliminclude", mh, "on"),
+    yliminclude ("yliminclude", mh, "on"),
+    zliminclude ("zliminclude", mh, "on"),
+    climinclude ("climinclude", mh, "on"),
+    aliminclude ("aliminclude", mh, "on")
+{
+  xdata.set_id (XDATA);
+  ydata.set_id (YDATA);
+  zdata.set_id (ZDATA);
+  cdata.set_id (CDATA);
+  cdatamapping.set_id (CDATAMAPPING);
+  xdatasource.set_id (XDATASOURCE);
+  ydatasource.set_id (YDATASOURCE);
+  zdatasource.set_id (ZDATASOURCE);
+  cdatasource.set_id (CDATASOURCE);
+  facecolor.set_id (FACECOLOR);
+  facealpha.set_id (FACEALPHA);
+  edgecolor.set_id (EDGECOLOR);
+  linestyle.set_id (LINESTYLE);
+  linewidth.set_id (LINEWIDTH);
+  marker.set_id (MARKER);
+  markeredgecolor.set_id (MARKEREDGECOLOR);
+  markerfacecolor.set_id (MARKERFACECOLOR);
+  markersize.set_id (MARKERSIZE);
+  keylabel.set_id (KEYLABEL);
+  interpreter.set_id (INTERPRETER);
+  alphadata.set_id (ALPHADATA);
+  alphadatamapping.set_id (ALPHADATAMAPPING);
+  ambientstrength.set_id (AMBIENTSTRENGTH);
+  backfacelighting.set_id (BACKFACELIGHTING);
+  diffusestrength.set_id (DIFFUSESTRENGTH);
+  edgealpha.set_id (EDGEALPHA);
+  edgelighting.set_id (EDGELIGHTING);
+  erasemode.set_id (ERASEMODE);
+  facelighting.set_id (FACELIGHTING);
+  meshstyle.set_id (MESHSTYLE);
+  normalmode.set_id (NORMALMODE);
+  specularcolorreflectance.set_id (SPECULARCOLORREFLECTANCE);
+  specularexponent.set_id (SPECULAREXPONENT);
+  specularstrength.set_id (SPECULARSTRENGTH);
+  vertexnormals.set_id (VERTEXNORMALS);
+  xlim.set_id (XLIM);
+  xlim.set_hidden (true);
+  ylim.set_id (YLIM);
+  ylim.set_hidden (true);
+  zlim.set_id (ZLIM);
+  zlim.set_hidden (true);
+  clim.set_id (CLIM);
+  clim.set_hidden (true);
+  alim.set_id (ALIM);
+  alim.set_hidden (true);
+  xliminclude.set_id (XLIMINCLUDE);
+  xliminclude.set_hidden (true);
+  yliminclude.set_id (YLIMINCLUDE);
+  yliminclude.set_hidden (true);
+  zliminclude.set_id (ZLIMINCLUDE);
+  zliminclude.set_hidden (true);
+  climinclude.set_id (CLIMINCLUDE);
+  climinclude.set_hidden (true);
+  aliminclude.set_id (ALIMINCLUDE);
+  aliminclude.set_hidden (true);
+  init ();
+}
+
+void
+surface::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("xdata"))
+    set_xdata (val);
+  else if (pname.compare ("ydata"))
+    set_ydata (val);
+  else if (pname.compare ("zdata"))
+    set_zdata (val);
+  else if (pname.compare ("cdata"))
+    set_cdata (val);
+  else if (pname.compare ("cdatamapping"))
+    set_cdatamapping (val);
+  else if (pname.compare ("xdatasource"))
+    set_xdatasource (val);
+  else if (pname.compare ("ydatasource"))
+    set_ydatasource (val);
+  else if (pname.compare ("zdatasource"))
+    set_zdatasource (val);
+  else if (pname.compare ("cdatasource"))
+    set_cdatasource (val);
+  else if (pname.compare ("facecolor"))
+    set_facecolor (val);
+  else if (pname.compare ("facealpha"))
+    set_facealpha (val);
+  else if (pname.compare ("edgecolor"))
+    set_edgecolor (val);
+  else if (pname.compare ("linestyle"))
+    set_linestyle (val);
+  else if (pname.compare ("linewidth"))
+    set_linewidth (val);
+  else if (pname.compare ("marker"))
+    set_marker (val);
+  else if (pname.compare ("markeredgecolor"))
+    set_markeredgecolor (val);
+  else if (pname.compare ("markerfacecolor"))
+    set_markerfacecolor (val);
+  else if (pname.compare ("markersize"))
+    set_markersize (val);
+  else if (pname.compare ("keylabel"))
+    set_keylabel (val);
+  else if (pname.compare ("interpreter"))
+    set_interpreter (val);
+  else if (pname.compare ("alphadata"))
+    set_alphadata (val);
+  else if (pname.compare ("alphadatamapping"))
+    set_alphadatamapping (val);
+  else if (pname.compare ("ambientstrength"))
+    set_ambientstrength (val);
+  else if (pname.compare ("backfacelighting"))
+    set_backfacelighting (val);
+  else if (pname.compare ("diffusestrength"))
+    set_diffusestrength (val);
+  else if (pname.compare ("edgealpha"))
+    set_edgealpha (val);
+  else if (pname.compare ("edgelighting"))
+    set_edgelighting (val);
+  else if (pname.compare ("erasemode"))
+    set_erasemode (val);
+  else if (pname.compare ("facelighting"))
+    set_facelighting (val);
+  else if (pname.compare ("meshstyle"))
+    set_meshstyle (val);
+  else if (pname.compare ("normalmode"))
+    set_normalmode (val);
+  else if (pname.compare ("specularcolorreflectance"))
+    set_specularcolorreflectance (val);
+  else if (pname.compare ("specularexponent"))
+    set_specularexponent (val);
+  else if (pname.compare ("specularstrength"))
+    set_specularstrength (val);
+  else if (pname.compare ("vertexnormals"))
+    set_vertexnormals (val);
+  else if (pname.compare ("xliminclude"))
+    set_xliminclude (val);
+  else if (pname.compare ("yliminclude"))
+    set_yliminclude (val);
+  else if (pname.compare ("zliminclude"))
+    set_zliminclude (val);
+  else if (pname.compare ("climinclude"))
+    set_climinclude (val);
+  else if (pname.compare ("aliminclude"))
+    set_aliminclude (val);
+  else
+    base_properties::set (pname, "surface", val);
+}
+
+octave_value
+surface::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  m.assign ("xdata", get_xdata ());
+  m.assign ("ydata", get_ydata ());
+  m.assign ("zdata", get_zdata ());
+  m.assign ("cdata", get_cdata ());
+  m.assign ("cdatamapping", get_cdatamapping ());
+  m.assign ("xdatasource", get_xdatasource ());
+  m.assign ("ydatasource", get_ydatasource ());
+  m.assign ("zdatasource", get_zdatasource ());
+  m.assign ("cdatasource", get_cdatasource ());
+  m.assign ("facecolor", get_facecolor ());
+  m.assign ("facealpha", get_facealpha ());
+  m.assign ("edgecolor", get_edgecolor ());
+  m.assign ("linestyle", get_linestyle ());
+  m.assign ("linewidth", get_linewidth ());
+  m.assign ("marker", get_marker ());
+  m.assign ("markeredgecolor", get_markeredgecolor ());
+  m.assign ("markerfacecolor", get_markerfacecolor ());
+  m.assign ("markersize", get_markersize ());
+  m.assign ("keylabel", get_keylabel ());
+  m.assign ("interpreter", get_interpreter ());
+  m.assign ("alphadata", get_alphadata ());
+  m.assign ("alphadatamapping", get_alphadatamapping ());
+  m.assign ("ambientstrength", get_ambientstrength ());
+  m.assign ("backfacelighting", get_backfacelighting ());
+  m.assign ("diffusestrength", get_diffusestrength ());
+  m.assign ("edgealpha", get_edgealpha ());
+  m.assign ("edgelighting", get_edgelighting ());
+  m.assign ("erasemode", get_erasemode ());
+  m.assign ("facelighting", get_facelighting ());
+  m.assign ("meshstyle", get_meshstyle ());
+  m.assign ("normalmode", get_normalmode ());
+  m.assign ("specularcolorreflectance", get_specularcolorreflectance ());
+  m.assign ("specularexponent", get_specularexponent ());
+  m.assign ("specularstrength", get_specularstrength ());
+  m.assign ("vertexnormals", get_vertexnormals ());
+  if (all)
+    m.assign ("xlim", get_xlim ());
+  if (all)
+    m.assign ("ylim", get_ylim ());
+  if (all)
+    m.assign ("zlim", get_zlim ());
+  if (all)
+    m.assign ("clim", get_clim ());
+  if (all)
+    m.assign ("alim", get_alim ());
+  if (all)
+    m.assign ("xliminclude", get_xliminclude ());
+  if (all)
+    m.assign ("yliminclude", get_yliminclude ());
+  if (all)
+    m.assign ("zliminclude", get_zliminclude ());
+  if (all)
+    m.assign ("climinclude", get_climinclude ());
+  if (all)
+    m.assign ("aliminclude", get_aliminclude ());
+
+  return m;
+}
+
+octave_value
+surface::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("xdata"))
+    retval = get_xdata ();
+  else if (pname.compare ("ydata"))
+    retval = get_ydata ();
+  else if (pname.compare ("zdata"))
+    retval = get_zdata ();
+  else if (pname.compare ("cdata"))
+    retval = get_cdata ();
+  else if (pname.compare ("cdatamapping"))
+    retval = get_cdatamapping ();
+  else if (pname.compare ("xdatasource"))
+    retval = get_xdatasource ();
+  else if (pname.compare ("ydatasource"))
+    retval = get_ydatasource ();
+  else if (pname.compare ("zdatasource"))
+    retval = get_zdatasource ();
+  else if (pname.compare ("cdatasource"))
+    retval = get_cdatasource ();
+  else if (pname.compare ("facecolor"))
+    retval = get_facecolor ();
+  else if (pname.compare ("facealpha"))
+    retval = get_facealpha ();
+  else if (pname.compare ("edgecolor"))
+    retval = get_edgecolor ();
+  else if (pname.compare ("linestyle"))
+    retval = get_linestyle ();
+  else if (pname.compare ("linewidth"))
+    retval = get_linewidth ();
+  else if (pname.compare ("marker"))
+    retval = get_marker ();
+  else if (pname.compare ("markeredgecolor"))
+    retval = get_markeredgecolor ();
+  else if (pname.compare ("markerfacecolor"))
+    retval = get_markerfacecolor ();
+  else if (pname.compare ("markersize"))
+    retval = get_markersize ();
+  else if (pname.compare ("keylabel"))
+    retval = get_keylabel ();
+  else if (pname.compare ("interpreter"))
+    retval = get_interpreter ();
+  else if (pname.compare ("alphadata"))
+    retval = get_alphadata ();
+  else if (pname.compare ("alphadatamapping"))
+    retval = get_alphadatamapping ();
+  else if (pname.compare ("ambientstrength"))
+    retval = get_ambientstrength ();
+  else if (pname.compare ("backfacelighting"))
+    retval = get_backfacelighting ();
+  else if (pname.compare ("diffusestrength"))
+    retval = get_diffusestrength ();
+  else if (pname.compare ("edgealpha"))
+    retval = get_edgealpha ();
+  else if (pname.compare ("edgelighting"))
+    retval = get_edgelighting ();
+  else if (pname.compare ("erasemode"))
+    retval = get_erasemode ();
+  else if (pname.compare ("facelighting"))
+    retval = get_facelighting ();
+  else if (pname.compare ("meshstyle"))
+    retval = get_meshstyle ();
+  else if (pname.compare ("normalmode"))
+    retval = get_normalmode ();
+  else if (pname.compare ("specularcolorreflectance"))
+    retval = get_specularcolorreflectance ();
+  else if (pname.compare ("specularexponent"))
+    retval = get_specularexponent ();
+  else if (pname.compare ("specularstrength"))
+    retval = get_specularstrength ();
+  else if (pname.compare ("vertexnormals"))
+    retval = get_vertexnormals ();
+  else if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("zlim"))
+    retval = get_zlim ();
+  else if (pname.compare ("clim"))
+    retval = get_clim ();
+  else if (pname.compare ("alim"))
+    retval = get_alim ();
+  else if (pname.compare ("xliminclude"))
+    retval = get_xliminclude ();
+  else if (pname.compare ("yliminclude"))
+    retval = get_yliminclude ();
+  else if (pname.compare ("zliminclude"))
+    retval = get_zliminclude ();
+  else if (pname.compare ("climinclude"))
+    retval = get_climinclude ();
+  else if (pname.compare ("aliminclude"))
+    retval = get_aliminclude ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+surface::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("xdata"))
+    return property (&xdata, true);
+  else if (pname.compare ("ydata"))
+    return property (&ydata, true);
+  else if (pname.compare ("zdata"))
+    return property (&zdata, true);
+  else if (pname.compare ("cdata"))
+    return property (&cdata, true);
+  else if (pname.compare ("cdatamapping"))
+    return property (&cdatamapping, true);
+  else if (pname.compare ("xdatasource"))
+    return property (&xdatasource, true);
+  else if (pname.compare ("ydatasource"))
+    return property (&ydatasource, true);
+  else if (pname.compare ("zdatasource"))
+    return property (&zdatasource, true);
+  else if (pname.compare ("cdatasource"))
+    return property (&cdatasource, true);
+  else if (pname.compare ("facecolor"))
+    return property (&facecolor, true);
+  else if (pname.compare ("facealpha"))
+    return property (&facealpha, true);
+  else if (pname.compare ("edgecolor"))
+    return property (&edgecolor, true);
+  else if (pname.compare ("linestyle"))
+    return property (&linestyle, true);
+  else if (pname.compare ("linewidth"))
+    return property (&linewidth, true);
+  else if (pname.compare ("marker"))
+    return property (&marker, true);
+  else if (pname.compare ("markeredgecolor"))
+    return property (&markeredgecolor, true);
+  else if (pname.compare ("markerfacecolor"))
+    return property (&markerfacecolor, true);
+  else if (pname.compare ("markersize"))
+    return property (&markersize, true);
+  else if (pname.compare ("keylabel"))
+    return property (&keylabel, true);
+  else if (pname.compare ("interpreter"))
+    return property (&interpreter, true);
+  else if (pname.compare ("alphadata"))
+    return property (&alphadata, true);
+  else if (pname.compare ("alphadatamapping"))
+    return property (&alphadatamapping, true);
+  else if (pname.compare ("ambientstrength"))
+    return property (&ambientstrength, true);
+  else if (pname.compare ("backfacelighting"))
+    return property (&backfacelighting, true);
+  else if (pname.compare ("diffusestrength"))
+    return property (&diffusestrength, true);
+  else if (pname.compare ("edgealpha"))
+    return property (&edgealpha, true);
+  else if (pname.compare ("edgelighting"))
+    return property (&edgelighting, true);
+  else if (pname.compare ("erasemode"))
+    return property (&erasemode, true);
+  else if (pname.compare ("facelighting"))
+    return property (&facelighting, true);
+  else if (pname.compare ("meshstyle"))
+    return property (&meshstyle, true);
+  else if (pname.compare ("normalmode"))
+    return property (&normalmode, true);
+  else if (pname.compare ("specularcolorreflectance"))
+    return property (&specularcolorreflectance, true);
+  else if (pname.compare ("specularexponent"))
+    return property (&specularexponent, true);
+  else if (pname.compare ("specularstrength"))
+    return property (&specularstrength, true);
+  else if (pname.compare ("vertexnormals"))
+    return property (&vertexnormals, true);
+  else if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("zlim"))
+    return property (&zlim, true);
+  else if (pname.compare ("clim"))
+    return property (&clim, true);
+  else if (pname.compare ("alim"))
+    return property (&alim, true);
+  else if (pname.compare ("xliminclude"))
+    return property (&xliminclude, true);
+  else if (pname.compare ("yliminclude"))
+    return property (&yliminclude, true);
+  else if (pname.compare ("zliminclude"))
+    return property (&zliminclude, true);
+  else if (pname.compare ("climinclude"))
+    return property (&climinclude, true);
+  else if (pname.compare ("aliminclude"))
+    return property (&aliminclude, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+surface::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["xdata"] = Matrix ();
+  m["ydata"] = Matrix ();
+  m["zdata"] = Matrix ();
+  m["cdata"] = Matrix ();
+  m["cdatamapping"] = "scaled";
+  m["xdatasource"] = "";
+  m["ydatasource"] = "";
+  m["zdatasource"] = "";
+  m["cdatasource"] = "";
+  m["facecolor"] = "flat";
+  m["facealpha"] = double_radio_property (1.0, radio_values ("flat|interp"));
+  m["edgecolor"] = octave_value ();
+  m["linestyle"] = "-";
+  m["linewidth"] = 0.5;
+  m["marker"] = "none";
+  m["markeredgecolor"] = "auto";
+  m["markerfacecolor"] = "none";
+  m["markersize"] = 6;
+  m["keylabel"] = "";
+  m["interpreter"] = "tex";
+  m["alphadata"] = Matrix ();
+  m["alphadatamapping"] = "scaled";
+  m["ambientstrength"] = 0.3;
+  m["backfacelighting"] = "reverselit";
+  m["diffusestrength"] = 0.6;
+  m["edgealpha"] = double_radio_property (1.0, radio_values ("flat|interp"));
+  m["edgelighting"] = "none";
+  m["erasemode"] = "normal";
+  m["facelighting"] = "none";
+  m["meshstyle"] = "both";
+  m["normalmode"] = "auto";
+  m["specularcolorreflectance"] = 1;
+  m["specularexponent"] = 10;
+  m["specularstrength"] = 0.9;
+  m["vertexnormals"] = Matrix ();
+  m["xlim"] = Matrix ();
+  m["ylim"] = Matrix ();
+  m["zlim"] = Matrix ();
+  m["clim"] = Matrix ();
+  m["alim"] = Matrix ();
+  m["xliminclude"] = "on";
+  m["yliminclude"] = "on";
+  m["zliminclude"] = "on";
+  m["climinclude"] = "on";
+  m["aliminclude"] = "on";
+
+  return m;
+}
+
+std::string surface::properties::go_name ("surface");
+
+bool surface::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("xdata");
+      all_properties.insert ("ydata");
+      all_properties.insert ("zdata");
+      all_properties.insert ("cdata");
+      all_properties.insert ("cdatamapping");
+      all_properties.insert ("xdatasource");
+      all_properties.insert ("ydatasource");
+      all_properties.insert ("zdatasource");
+      all_properties.insert ("cdatasource");
+      all_properties.insert ("facecolor");
+      all_properties.insert ("facealpha");
+      all_properties.insert ("edgecolor");
+      all_properties.insert ("linestyle");
+      all_properties.insert ("linewidth");
+      all_properties.insert ("marker");
+      all_properties.insert ("markeredgecolor");
+      all_properties.insert ("markerfacecolor");
+      all_properties.insert ("markersize");
+      all_properties.insert ("keylabel");
+      all_properties.insert ("interpreter");
+      all_properties.insert ("alphadata");
+      all_properties.insert ("alphadatamapping");
+      all_properties.insert ("ambientstrength");
+      all_properties.insert ("backfacelighting");
+      all_properties.insert ("diffusestrength");
+      all_properties.insert ("edgealpha");
+      all_properties.insert ("edgelighting");
+      all_properties.insert ("erasemode");
+      all_properties.insert ("facelighting");
+      all_properties.insert ("meshstyle");
+      all_properties.insert ("normalmode");
+      all_properties.insert ("specularcolorreflectance");
+      all_properties.insert ("specularexponent");
+      all_properties.insert ("specularstrength");
+      all_properties.insert ("vertexnormals");
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("zlim");
+      all_properties.insert ("clim");
+      all_properties.insert ("alim");
+      all_properties.insert ("xliminclude");
+      all_properties.insert ("yliminclude");
+      all_properties.insert ("zliminclude");
+      all_properties.insert ("climinclude");
+      all_properties.insert ("aliminclude");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "surface");
+}
+
+// ******** hggroup ********
+
+hggroup::properties::properties (const graphics_handle& mh, const graphics_handle& p)
+  : base_properties (go_name, mh, p),
+    xlim ("xlim", mh, Matrix()),
+    ylim ("ylim", mh, Matrix()),
+    zlim ("zlim", mh, Matrix()),
+    clim ("clim", mh, Matrix()),
+    alim ("alim", mh, Matrix()),
+    xliminclude ("xliminclude", mh, "on"),
+    yliminclude ("yliminclude", mh, "on"),
+    zliminclude ("zliminclude", mh, "on"),
+    climinclude ("climinclude", mh, "on"),
+    aliminclude ("aliminclude", mh, "on")
+{
+  xlim.set_id (XLIM);
+  xlim.set_hidden (true);
+  ylim.set_id (YLIM);
+  ylim.set_hidden (true);
+  zlim.set_id (ZLIM);
+  zlim.set_hidden (true);
+  clim.set_id (CLIM);
+  clim.set_hidden (true);
+  alim.set_id (ALIM);
+  alim.set_hidden (true);
+  xliminclude.set_id (XLIMINCLUDE);
+  xliminclude.set_hidden (true);
+  yliminclude.set_id (YLIMINCLUDE);
+  yliminclude.set_hidden (true);
+  zliminclude.set_id (ZLIMINCLUDE);
+  zliminclude.set_hidden (true);
+  climinclude.set_id (CLIMINCLUDE);
+  climinclude.set_hidden (true);
+  aliminclude.set_id (ALIMINCLUDE);
+  aliminclude.set_hidden (true);
+  init ();
+}
+
+void
+hggroup::properties::set (const caseless_str& pname, const octave_value& val)
+{
+  if (pname.compare ("xliminclude"))
+    set_xliminclude (val);
+  else if (pname.compare ("yliminclude"))
+    set_yliminclude (val);
+  else if (pname.compare ("zliminclude"))
+    set_zliminclude (val);
+  else if (pname.compare ("climinclude"))
+    set_climinclude (val);
+  else if (pname.compare ("aliminclude"))
+    set_aliminclude (val);
+  else
+    base_properties::set (pname, "hggroup", val);
+}
+
+octave_value
+hggroup::properties::get (bool all) const
+{
+  Octave_map m = base_properties::get (all).map_value ();
+
+  if (all)
+    m.assign ("xlim", get_xlim ());
+  if (all)
+    m.assign ("ylim", get_ylim ());
+  if (all)
+    m.assign ("zlim", get_zlim ());
+  if (all)
+    m.assign ("clim", get_clim ());
+  if (all)
+    m.assign ("alim", get_alim ());
+  if (all)
+    m.assign ("xliminclude", get_xliminclude ());
+  if (all)
+    m.assign ("yliminclude", get_yliminclude ());
+  if (all)
+    m.assign ("zliminclude", get_zliminclude ());
+  if (all)
+    m.assign ("climinclude", get_climinclude ());
+  if (all)
+    m.assign ("aliminclude", get_aliminclude ());
+
+  return m;
+}
+
+octave_value
+hggroup::properties::get (const caseless_str& pname) const
+{
+  octave_value retval;
+
+  if (pname.compare ("xlim"))
+    retval = get_xlim ();
+  else if (pname.compare ("ylim"))
+    retval = get_ylim ();
+  else if (pname.compare ("zlim"))
+    retval = get_zlim ();
+  else if (pname.compare ("clim"))
+    retval = get_clim ();
+  else if (pname.compare ("alim"))
+    retval = get_alim ();
+  else if (pname.compare ("xliminclude"))
+    retval = get_xliminclude ();
+  else if (pname.compare ("yliminclude"))
+    retval = get_yliminclude ();
+  else if (pname.compare ("zliminclude"))
+    retval = get_zliminclude ();
+  else if (pname.compare ("climinclude"))
+    retval = get_climinclude ();
+  else if (pname.compare ("aliminclude"))
+    retval = get_aliminclude ();
+  else
+    retval = base_properties::get (pname);
+
+  return retval;
+}
+
+property
+hggroup::properties::get_property (const caseless_str& pname)
+{
+  if (pname.compare ("xlim"))
+    return property (&xlim, true);
+  else if (pname.compare ("ylim"))
+    return property (&ylim, true);
+  else if (pname.compare ("zlim"))
+    return property (&zlim, true);
+  else if (pname.compare ("clim"))
+    return property (&clim, true);
+  else if (pname.compare ("alim"))
+    return property (&alim, true);
+  else if (pname.compare ("xliminclude"))
+    return property (&xliminclude, true);
+  else if (pname.compare ("yliminclude"))
+    return property (&yliminclude, true);
+  else if (pname.compare ("zliminclude"))
+    return property (&zliminclude, true);
+  else if (pname.compare ("climinclude"))
+    return property (&climinclude, true);
+  else if (pname.compare ("aliminclude"))
+    return property (&aliminclude, true);
+  else
+    return base_properties::get_property (pname);
+}
+
+property_list::pval_map_type
+hggroup::properties::factory_defaults (void)
+{
+  property_list::pval_map_type m = base_properties::factory_defaults ();
+
+  m["xlim"] = Matrix();
+  m["ylim"] = Matrix();
+  m["zlim"] = Matrix();
+  m["clim"] = Matrix();
+  m["alim"] = Matrix();
+  m["xliminclude"] = "on";
+  m["yliminclude"] = "on";
+  m["zliminclude"] = "on";
+  m["climinclude"] = "on";
+  m["aliminclude"] = "on";
+
+  return m;
+}
+
+std::string hggroup::properties::go_name ("hggroup");
+
+bool hggroup::properties::has_property (const std::string& pname)
+{
+  static std::set<std::string> all_properties;
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      all_properties.insert ("xlim");
+      all_properties.insert ("ylim");
+      all_properties.insert ("zlim");
+      all_properties.insert ("clim");
+      all_properties.insert ("alim");
+      all_properties.insert ("xliminclude");
+      all_properties.insert ("yliminclude");
+      all_properties.insert ("zliminclude");
+      all_properties.insert ("climinclude");
+      all_properties.insert ("aliminclude");
+
+      initialized = true;
+    }
+
+  return all_properties.find (pname) != all_properties.end () || base_properties::has_property (pname, "hggroup");
+}
+
diff --git a/src/graphics.cc b/src/graphics.cc
new file mode 100644
index 0000000..fa19379
--- /dev/null
+++ b/src/graphics.cc
@@ -0,0 +1,5453 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cfloat>
+#include <cstdlib>
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <sstream>
+
+#include "file-ops.h"
+#include "file-stat.h"
+
+#include "cmd-edit.h"
+#include "defun.h"
+#include "display.h"
+#include "error.h"
+#include "graphics.h"
+#include "input.h"
+#include "ov.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-fcn-handle.h"
+#include "parse.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+
+// forward declaration
+static octave_value xget (const graphics_handle& h, const caseless_str& name);
+
+static void
+gripe_set_invalid (const std::string& pname)
+{
+  error ("set: invalid value for %s property", pname.c_str ());
+}
+
+static Matrix
+jet_colormap (void)
+{
+  Matrix cmap (64, 3, 0.0);
+
+  for (octave_idx_type i = 0; i < 64; i++)
+    {
+      // This is the jet colormap.  It would be nice to be able
+      // to feval the jet function but since there is a static
+      // property object that includes a colormap_property
+      // object, we need to initialize this before main is even
+      // called, so calling an interpreted function is not
+      // possible.
+
+      double x = i / 63.0;
+
+      if (x >= 3.0/8.0 && x < 5.0/8.0)
+        cmap(i,0) = 4.0 * x - 3.0/2.0;
+      else if (x >= 5.0/8.0 && x < 7.0/8.0)
+        cmap(i,0) = 1.0;
+      else if (x >= 7.0/8.0)
+        cmap(i,0) = -4.0 * x + 9.0/2.0;
+
+      if (x >= 1.0/8.0 && x < 3.0/8.0)
+        cmap(i,1) = 4.0 * x - 1.0/2.0;
+      else if (x >= 3.0/8.0 && x < 5.0/8.0)
+        cmap(i,1) = 1.0;
+      else if (x >= 5.0/8.0 && x < 7.0/8.0)
+        cmap(i,1) = -4.0 * x + 7.0/2.0;
+
+      if (x < 1.0/8.0)
+        cmap(i,2) = 4.0 * x + 1.0/2.0;
+      else if (x >= 1.0/8.0 && x < 3.0/8.0)
+        cmap(i,2) = 1.0;
+      else if (x >= 3.0/8.0 && x < 5.0/8.0)
+        cmap(i,2) = -4.0 * x + 5.0/2.0;
+    }
+
+  return cmap;
+}
+
+static double
+default_screendepth (void)
+{
+  return display_info::depth ();
+}
+
+static Matrix
+default_screensize (void)
+{
+  Matrix retval (1, 4, 1.0);
+
+  retval(2) = display_info::width ();
+  retval(3) = display_info::height ();
+
+  return retval;
+}
+
+static double
+default_screenpixelsperinch (void)
+{
+  return (display_info::x_dpi () + display_info::y_dpi ()) / 2;
+}
+
+static Matrix
+default_colororder (void)
+{
+  Matrix retval (7, 3, 0.0);
+
+  retval(0,2) = 1.0;
+
+  retval(1,1) = 0.5;
+
+  retval(2,0) = 1.0;
+
+  retval(3,1) = 0.75;
+  retval(3,2) = 0.75;
+
+  retval(4,0) = 0.75;
+  retval(4,2) = 0.75;
+
+  retval(5,0) = 0.75;
+  retval(5,1) = 0.75;
+
+  retval(6,0) = 0.25;
+  retval(6,1) = 0.25;
+  retval(6,2) = 0.25;
+
+  return retval;
+}
+
+static Matrix
+default_lim (void)
+{
+  Matrix m (1, 2, 0);
+  m(1) = 1;
+  return m;
+}
+
+static Matrix
+default_data (void)
+{
+  Matrix retval (1, 2);
+
+  retval(0) = 0;
+  retval(1) = 1;
+
+  return retval;
+}
+
+static Matrix
+default_axes_position (void)
+{
+  Matrix m (1, 4, 0.0);
+  m(0) = 0.13;
+  m(1) = 0.11;
+  m(2) = 0.775;
+  m(3) = 0.815;
+  return m;
+}
+
+static Matrix
+default_axes_outerposition (void)
+{
+  Matrix m (1, 4, 0.0);
+  m(2) = m(3) = 1.0;
+  return m;
+}
+
+static Matrix
+default_axes_tick (void)
+{
+  Matrix m (1, 6, 0.0);
+  m(0) = 0.0;
+  m(1) = 0.2;
+  m(2) = 0.4;
+  m(3) = 0.6;
+  m(4) = 0.8;
+  m(5) = 1.0;
+  return m;
+}
+
+static Matrix
+default_axes_ticklength (void)
+{
+  Matrix m (1, 2, 0.01);
+  m(1) = 0.025;
+  return m;
+}
+
+static Matrix
+default_figure_position (void)
+{
+  Matrix m (1, 4, 0.0);
+  m(0) = 300;
+  m(1) = 200;
+  m(2) = 560;
+  m(3) = 420;
+  return m;
+}
+
+static Matrix
+default_figure_papersize (void)
+{
+  Matrix m (1, 2, 0.0);
+  m(0) = 8.5;
+  m(1) = 11.0;
+  return m;
+}
+
+static Matrix
+default_figure_paperposition (void)
+{
+  Matrix m (1, 4, 0.0);
+  m(0) = 0.25;
+  m(1) = 2.50;
+  m(2) = 8.00;
+  m(3) = 6.00;
+  return m;
+}
+
+static Matrix
+convert_position (const Matrix& pos, const caseless_str& from_units,
+		  const caseless_str& to_units,
+		  const Matrix& parent_dim = Matrix (1, 2, 0.0))
+{
+  Matrix retval (1, 4);
+  double res = 0;
+
+  if (from_units.compare ("pixels"))
+    retval = pos;
+  else if (from_units.compare ("normalized"))
+    {
+      retval(0) = pos(0) * parent_dim(0) + 1;
+      retval(1) = pos(1) * parent_dim(1) + 1;
+      retval(2) = pos(2) * parent_dim(0);
+      retval(3) = pos(3) * parent_dim(1);
+    }
+  else if (from_units.compare ("characters"))
+    {
+      if (res <= 0)
+	res = xget (0, "screenpixelsperinch").double_value ();
+
+      double f = 0.0;
+
+      // FIXME -- this assumes the system font is Helvetica 10pt 
+      //          (for which "x" requires 6x12 pixels at 74.951 pixels/inch)
+      f = 12.0 * res / 74.951;
+
+      if (f > 0)
+	{
+	  retval(0) = 0.5 * pos(0) * f;
+	  retval(1) = pos(1) * f;
+	  retval(2) = 0.5 * pos(2) * f;
+	  retval(3) = pos(3) * f;
+	}
+    }
+  else
+    {
+      if (res <= 0)
+	res = xget (0, "screenpixelsperinch").double_value ();
+
+      double f = 0.0;
+
+      if (from_units.compare ("points"))
+	f = res / 72.0;
+      else if (from_units.compare ("inches"))
+	f = res;
+      else if (from_units.compare ("centimeters"))
+	f = res / 2.54;
+
+      if (f > 0)
+	{
+	  retval(0) = pos(0) * f + 1;
+	  retval(1) = pos(1) * f + 1;
+	  retval(2) = pos(2) * f;
+	  retval(3) = pos(3) * f;
+	}
+    }
+
+  if (! to_units.compare ("pixels"))
+    {
+      if (to_units.compare ("normalized"))
+	{
+	  retval(0) = (retval(0) - 1) / parent_dim(0);
+	  retval(1) = (retval(1) - 1) / parent_dim(1);
+	  retval(2) /= parent_dim(0);
+	  retval(3) /= parent_dim(1);
+	}
+      else if (to_units.compare ("characters"))
+	{
+	  if (res <= 0)
+	    res = xget (0, "screenpixelsperinch").double_value ();
+
+	  double f = 0.0;
+
+	  f = 12.0 * res / 74.951;
+
+	  if (f > 0)
+	    {
+	      retval(0) = 2 * retval(0) / f;
+	      retval(1) = retval(1) / f;
+	      retval(2) = 2 * retval(2) / f;
+	      retval(3) = retval(3) / f;
+	    }
+	}
+      else
+	{
+	  if (res <= 0)
+	    res = xget (0, "screenpixelsperinch").double_value ();
+
+	  double f = 0.0;
+
+	  if (to_units.compare ("points"))
+	    f = res / 72.0;
+	  else if (to_units.compare ("inches"))
+	    f = res;
+	  else if (to_units.compare ("centimeters"))
+	    f = res / 2.54;
+
+	  if (f > 0)
+	    {
+	      retval(0) = (retval(0) - 1) / f;
+	      retval(1) = (retval(1) - 1) / f;
+	      retval(2) /= f;
+	      retval(3) /= f;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static graphics_object
+xget_ancestor (const graphics_object& go_arg, const std::string& type)
+{
+  graphics_object go = go_arg;
+
+  do
+    {
+      if (go.valid_object ())
+	{
+	  if (go.isa (type))
+	    return go;
+	  else
+	    go = gh_manager::get_object (go.get_parent ());
+	}
+      else
+	return graphics_object ();
+    }
+ while (true);
+}
+
+static octave_value
+convert_cdata (const base_properties& props, const octave_value& cdata,
+	       bool is_scaled, int cdim)
+{
+  dim_vector dv (cdata.dims ());
+
+  if (dv.length () == cdim && dv(cdim-1) == 3)
+    return cdata;
+
+  Matrix cmap (1, 3, 0.0);
+  Matrix clim (1, 2, 0.0);
+
+  graphics_object go = gh_manager::get_object (props.get___myhandle__ ());
+  graphics_object fig = xget_ancestor (go, "figure");
+
+  if (fig.valid_object ())
+    {
+      Matrix _cmap = fig.get (caseless_str ("colormap")).matrix_value ();
+
+      if (! error_state)
+	cmap = _cmap;
+    }
+
+  if (is_scaled)
+    {
+      graphics_object ax = xget_ancestor (go, "axes");
+
+      if (ax.valid_object ())
+	{
+	  Matrix _clim = ax.get (caseless_str ("clim")).matrix_value ();
+
+	  if (! error_state)
+	    clim = _clim;
+	}
+    }
+
+  dv.resize (cdim);
+  dv(cdim-1) = 3;
+
+  NDArray a (dv);
+
+  octave_idx_type lda = a.numel () / static_cast<octave_idx_type> (3);
+  octave_idx_type nc = cmap.rows ();
+
+  double *av = a.fortran_vec ();
+  const double *cmapv = cmap.data ();
+  const double *cv = 0;
+  const octave_uint8 *icv = 0;
+
+  if (cdata.is_integer_type ())
+    icv = cdata.uint8_array_value ().data ();
+  else
+    cv = cdata.array_value ().data ();
+
+  for (octave_idx_type i = 0; i < lda; i++)
+    {
+      double x = (cv ? cv[i] : double (icv[i]));
+
+      if (is_scaled)
+	x = xround ((nc - 1) * (x - clim(0)) / (clim(1) - clim(0)));
+      else
+	x = xround (x - 1);
+
+      if (x < 0)
+	x = 0;
+      else if (x >= nc)
+	x = (nc - 1);
+
+      octave_idx_type idx = static_cast<octave_idx_type> (x);
+
+      av[i]       = cmapv[idx];
+      av[i+lda]   = cmapv[idx+nc];
+      av[i+2*lda] = cmapv[idx+2*nc];
+    }
+
+  return octave_value (a);
+}
+
+template<class T>
+static void
+get_array_limits (const Array<T>& m, double& emin, double& emax,
+		  double& eminp)
+{
+  const T *data = m.data ();
+  octave_idx_type n = m.numel ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      double e = double (data[i]);
+
+      if (! (xisinf (e) || xisnan (e)))
+	{
+	  if (e < emin)
+	    emin = e;
+
+	  if (e > emax)
+	    emax = e;
+
+	  if (e > 0 && e < eminp)
+	    eminp = e;
+	}
+    }
+}
+
+static bool
+lookup_object_name (const caseless_str& name, caseless_str& go_name,
+		    caseless_str& rest)
+{
+  int len = name.length ();
+  int offset = 0;
+  bool result = false;
+
+  if (len >= 4)
+    {
+      caseless_str pfx = name.substr (0, 4);
+
+      if (pfx.compare ("axes") || pfx.compare ("line")
+	  || pfx.compare ("text"))
+	offset = 4;
+      else if (len >= 5)
+	{
+	  pfx = name.substr (0, 5);
+
+	  if (pfx.compare ("image") || pfx.compare ("patch"))
+	    offset = 5;
+	  else if (len >= 6)
+	    {
+	      pfx = name.substr (0, 6);
+
+	      if (pfx.compare ("figure"))
+		offset = 6;
+	      else if (len >= 7)
+		{
+		  pfx = name.substr (0, 7);
+
+		  if (pfx.compare ("surface") || pfx.compare ("hggroup"))
+		    offset = 7;
+		}
+	    }
+	}
+
+      if (offset > 0)
+	{
+	  go_name = pfx;
+	  rest = name.substr (offset);
+	  result = true;
+	}
+    }
+
+  return result;
+}
+
+static base_graphics_object*
+make_graphics_object_from_type (const caseless_str& type,
+				const graphics_handle& h = graphics_handle (),
+				const graphics_handle& p = graphics_handle ())
+{
+  base_graphics_object *go = 0;
+
+  if (type.compare ("figure"))
+    go = new figure (h, p);
+  else if (type.compare ("axes"))
+    go = new axes (h, p);
+  else if (type.compare ("line"))
+    go = new line (h, p);
+  else if (type.compare ("text"))
+    go = new text (h, p);
+  else if (type.compare ("image"))
+    go = new image (h, p);
+  else if (type.compare ("patch"))
+    go = new patch (h, p);
+  else if (type.compare ("surface"))
+    go = new surface (h, p);
+  else if (type.compare ("hggroup"))
+    go = new hggroup (h, p);
+
+  return go;
+}
+
+// ---------------------------------------------------------------------
+
+bool
+base_property::set (const octave_value& v, bool do_run )
+{
+  if (do_set (v))
+    {
+
+      // notify backend
+      if (id >= 0)
+	{
+	  graphics_object go = gh_manager::get_object (parent);
+	  if (go)
+	    {
+	      graphics_backend backend = go.get_backend();
+	      if (backend)
+		backend.property_changed (go, id);
+	    }
+	}
+
+      // run listeners
+      if (do_run && ! error_state)
+	run_listeners (POSTSET);
+
+      return true;
+    }
+
+  return false;
+}
+
+
+void
+base_property::run_listeners (listener_mode mode)
+{
+  const octave_value_list& l = listeners[mode];
+
+  for (int i = 0; i < l.length (); i++)
+    {
+      gh_manager::execute_callback (parent, l(i), octave_value ());
+
+      if (error_state)
+	break;
+    }
+}
+
+radio_values::radio_values (const std::string& opt_string)
+{
+  size_t beg = 0;
+  size_t len = opt_string.length ();
+  bool done = len == 0;
+
+  while (! done)
+    {
+      size_t end = opt_string.find ('|', beg);
+
+      if (end == std::string::npos)
+	{
+	  end = len;
+	  done = true;
+	}
+
+      std::string t = opt_string.substr (beg, end-beg);
+
+      // Might want more error checking here...
+      if (t[0] == '{')
+	{
+	  t = t.substr (1, t.length () - 2);
+	  default_val = t;
+	}
+      else if (beg == 0) // ensure default value
+	default_val = t;
+
+      possible_vals.insert (t);
+
+      beg = end + 1;
+    }
+}
+
+bool
+color_values::str2rgb (std::string str)
+{
+  double tmp_rgb[3] = {0, 0, 0};
+  bool retval = true;
+  unsigned int len = str.length();
+
+  std::transform (str.begin (), str.end (), str.begin (), tolower);
+
+  if (str.compare(0, len, "blue", 0, len) == 0)
+    tmp_rgb[2] = 1;
+  else if (str.compare(0, len, "black", 0, len) == 0
+	   || str.compare(0, len, "k", 0, len) == 0)
+    tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 0;
+  else if (str.compare(0, len, "red", 0, len) == 0)
+    tmp_rgb[0] = 1;
+  else if (str.compare(0, len, "green", 0, len) == 0)
+    tmp_rgb[1] = 1;
+  else if (str.compare(0, len, "yellow", 0, len) == 0)
+    tmp_rgb[0] = tmp_rgb[1] = 1;
+  else if (str.compare(0, len, "magenta", 0, len) == 0)
+    tmp_rgb[0] = tmp_rgb[2] = 1;
+  else if (str.compare(0, len, "cyan", 0, len) == 0)
+    tmp_rgb[1] = tmp_rgb[2] = 1;
+  else if (str.compare(0, len, "white", 0, len) == 0
+	   || str.compare(0, len, "w", 0, len) == 0)
+    tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 1;
+  else	
+    retval = false;
+
+  if (retval)
+    {
+      for (int i = 0; i < 3; i++)
+	xrgb(i) = tmp_rgb[i];
+    }
+
+  return retval;
+}
+
+bool
+color_property::do_set (const octave_value& val)
+{
+  if (val.is_string ())
+    {
+      std::string s = val.string_value ();
+
+      if (! s.empty ())
+	{
+	  if (radio_val.contains (s))
+	    {
+	      if (current_type != radio_t || current_val != s)
+		{
+		  current_val = s;
+		  current_type = radio_t;
+		  return true;
+		}
+	    }
+          else
+	    {
+	      color_values col (s);
+	      if (! error_state)
+		{
+		  if (current_type != color_t || col != color_val)
+		    {
+		      color_val = col;
+		      current_type = color_t;
+		      return true;
+		    }
+		}
+	      else
+		error ("invalid value for color property \"%s\" (value = %s)",
+		       get_name ().c_str (), s.c_str ());
+	    }	
+	}
+      else
+	error ("invalid value for color property \"%s\"",
+           get_name ().c_str ());
+    }
+  else if (val.is_numeric_type ())
+    {
+      Matrix m = val.matrix_value ();
+
+      if (m.numel () == 3)
+	{
+	  color_values col (m (0), m (1), m(2));
+	  if (! error_state)
+	    {
+	      if (current_type != color_t || col != color_val)
+		{
+		  color_val = col;
+		  current_type = color_t;
+		  return true;
+		}
+	    }
+	}
+      else
+	error ("invalid value for color property \"%s\"",
+           get_name ().c_str ());
+    }
+  else 
+    error ("invalid value for color property \"%s\"",
+           get_name ().c_str ());
+
+  return false;
+}
+
+bool
+double_radio_property::do_set (const octave_value& val)
+{
+  if (val.is_string ())
+    {
+      std::string s = val.string_value ();
+
+      if (! s.empty () && radio_val.contains (s))
+	{
+	  if (current_type != radio_t || s != current_val)
+	    {
+	      current_val = s;
+	      current_type = radio_t;
+	      return true;
+	    }
+	}
+      else
+	error ("invalid value for double_radio property \"%s\"",
+	       get_name ().c_str ());
+    }
+  else if (val.is_scalar_type () && val.is_real_type ())
+    {
+      double new_dval = val.double_value ();
+
+      if (current_type != double_t || new_dval != dval)
+	{
+	  dval = new_dval;
+	  current_type = double_t;
+	  return true;
+	}
+    }
+  else 
+    error ("invalid value for double_radio property \"%s\"",
+	   get_name ().c_str ());
+
+  return false;
+}
+
+bool
+array_property::validate (const octave_value& v)
+{
+  bool xok = false;
+
+  // FIXME -- should we always support []?
+  if (v.is_empty () && v.is_numeric_type ())
+    return true;
+
+  // check value type
+  if (type_constraints.size () > 0)
+    {
+      for (std::list<std::string>::const_iterator it = type_constraints.begin ();
+           ! xok && it != type_constraints.end (); ++it)
+        if ((*it) == v.class_name ())
+          xok = true;
+    }
+  else
+    xok = v.is_numeric_type ();
+
+  if (xok)
+    {
+      dim_vector vdims = v.dims ();
+      int vlen = vdims.length ();
+
+      xok = false;
+
+      // check value size
+      if (size_constraints.size () > 0)
+        for (std::list<dim_vector>::const_iterator it = size_constraints.begin ();
+             ! xok && it != size_constraints.end (); ++it)
+          {
+            dim_vector itdims = (*it);
+
+            if (itdims.length () == vlen)
+              {
+                xok = true;
+
+                for (int i = 0; xok && i < vlen; i++)
+                  if (itdims(i) >= 0 && itdims(i) != vdims(i))
+                    xok = false;
+              }
+          }
+      else
+        return true;
+    }
+
+  return xok;
+}
+
+bool
+array_property::is_equal (const octave_value& v) const
+{
+  if (data.type_name () == v.type_name ())
+    {
+      if (data.dims () == v.dims ())
+	{
+
+#define CHECK_ARRAY_EQUAL(T,F,A) \
+	    { \
+	      if (data.numel () == 1) \
+		return data.F ## scalar_value () == \
+		  v.F ## scalar_value (); \
+	      else  \
+		{ \
+                  /* Keep copy of array_value to allow sparse/bool arrays */ \
+		  /* that are converted, to not be deallocated early */ \
+		  const A m1 = data.F ## array_value (); \
+		  const T* d1 = m1.data (); \
+		  const A m2 = v.F ## array_value (); \
+		  const T* d2 = m2.data ();\
+		  \
+		  bool flag = true; \
+		  \
+		  for (int i = 0; flag && i < data.numel (); i++) \
+		    if (d1[i] != d2[i]) \
+		      flag = false; \
+		  \
+		  return flag; \
+		} \
+	    }
+
+	  if (data.is_double_type() || data.is_bool_type ())
+	    CHECK_ARRAY_EQUAL (double, , NDArray)
+	  else if (data.is_single_type ())
+	    CHECK_ARRAY_EQUAL (float, float_, FloatNDArray)
+	  else if (data.is_int8_type ())
+	    CHECK_ARRAY_EQUAL (octave_int8, int8_, int8NDArray)
+	  else if (data.is_int16_type ())
+	    CHECK_ARRAY_EQUAL (octave_int16, int16_, int16NDArray)
+	  else if (data.is_int32_type ())
+	    CHECK_ARRAY_EQUAL (octave_int32, int32_, int32NDArray)
+	  else if (data.is_int64_type ())
+	    CHECK_ARRAY_EQUAL (octave_int64, int64_, int64NDArray)
+	  else if (data.is_uint8_type ())
+	    CHECK_ARRAY_EQUAL (octave_uint8, uint8_, uint8NDArray)
+	  else if (data.is_uint16_type ())
+	    CHECK_ARRAY_EQUAL (octave_uint16, uint16_, uint16NDArray)
+	  else if (data.is_uint32_type ())
+	    CHECK_ARRAY_EQUAL (octave_uint32, uint32_, uint32NDArray)
+	  else if (data.is_uint64_type ())
+	    CHECK_ARRAY_EQUAL (octave_uint64, uint64_, uint64NDArray)
+	}
+    }
+
+  return false;
+}
+
+void
+array_property::get_data_limits (void)
+{
+  xmin = xminp = octave_Inf;
+  xmax = -octave_Inf;
+
+  if (! data.is_empty ())
+    {
+      if (data.is_integer_type ())
+	{
+	  if (data.is_int8_type ())
+	    get_array_limits (data.int8_array_value (), xmin, xmax, xminp);
+	  else if (data.is_uint8_type ())
+	    get_array_limits (data.uint8_array_value (), xmin, xmax, xminp);
+	  else if (data.is_int16_type ())
+	    get_array_limits (data.int16_array_value (), xmin, xmax, xminp);
+	  else if (data.is_uint16_type ())
+	    get_array_limits (data.uint16_array_value (), xmin, xmax, xminp);
+	  else if (data.is_int32_type ())
+	    get_array_limits (data.int32_array_value (), xmin, xmax, xminp);
+	  else if (data.is_uint32_type ())
+	    get_array_limits (data.uint32_array_value (), xmin, xmax, xminp);
+	  else if (data.is_int64_type ())
+	    get_array_limits (data.int64_array_value (), xmin, xmax, xminp);
+	  else if (data.is_uint64_type ())
+	    get_array_limits (data.uint64_array_value (), xmin, xmax, xminp);
+	}
+      else
+	get_array_limits (data.array_value (), xmin, xmax, xminp);
+    }
+}
+
+bool
+handle_property::do_set (const octave_value& v)
+{
+  double dv = v.double_value ();
+
+  if (! error_state)
+    {
+      graphics_handle gh = gh_manager::lookup (dv);
+
+      if (xisnan (gh.value ()) || gh.ok ())
+	{
+	  if (current_val != gh)
+	    {
+	      current_val = gh;
+	      return true;
+	    }
+	}
+      else
+        error ("set: invalid graphics handle (= %g) for property \"%s\"",
+	       dv, get_name ().c_str ());
+    }
+  else
+    error ("set: invalid graphics handle for property \"%s\"",
+	   get_name ().c_str ());
+
+  return false;
+}
+
+bool
+callback_property::validate (const octave_value& v) const
+{
+  // case 1: function handle
+  // case 2: cell array with first element being a function handle
+  // case 3: string corresponding to known function name
+  // case 4: evaluatable string
+  // case 5: empty matrix
+
+  if (v.is_function_handle ())
+    return true;
+  else if (v.is_string ())
+    // complete validation will be done at execution-time
+    return true;
+  else if (v.is_cell () && v.length () > 0
+           && (v.rows() == 1 || v.columns () == 1)
+           && v.cell_value ()(0).is_function_handle ())
+    return true;
+  else if (v.is_empty ())
+    return true;
+
+  return false;
+}
+
+void
+callback_property::execute (const octave_value& data) const
+{
+  if (callback.is_defined () && ! callback.is_empty ())
+    gh_manager::execute_callback (get_parent (), callback, data);
+}
+
+// Used to cache dummy graphics objects from which dynamic
+// properties can be cloned.
+static std::map<caseless_str, graphics_object> dprop_obj_map;
+
+property
+property::create (const std::string& name, const graphics_handle& h,
+		  const caseless_str& type, const octave_value_list& args)
+{
+  property retval;
+
+  if (type.compare ("string"))
+    {
+      std::string val = (args.length () > 0 ? args(0).string_value () : "");
+
+      if (! error_state)
+	retval = property (new string_property (name, h, val));
+    }
+  else if (type.compare ("any"))
+    {
+      octave_value val =
+	  (args.length () > 0 ? args(0) : octave_value (Matrix ()));
+
+      retval = property (new any_property (name, h, val));
+    }
+  else if (type.compare ("radio"))
+    {
+      if (args.length () > 0)
+	{
+	  std::string vals = args(0).string_value ();
+
+	  if (! error_state)
+	    {
+	      retval = property (new radio_property (name, h, vals));
+
+	      if (args.length () > 1)
+		retval.set (args(1));
+	    }
+	  else
+	    error ("addproperty: invalid argument for radio property, expected a string value");
+	}
+      else
+	error ("addproperty: missing possible values for radio property");
+    }
+  else if (type.compare ("double"))
+    {
+      double d = (args.length () > 0 ? args(0).double_value () : 0);
+
+      if (! error_state)
+	retval = property (new double_property (name, h, d));
+    }
+  else if (type.compare ("handle"))
+    {
+      double hh = (args.length () > 0 ? args(0).double_value () : octave_NaN);
+
+      if (! error_state)
+	{
+	  graphics_handle gh (hh);
+
+	  retval = property (new handle_property (name, h, gh));
+	}
+    }
+  else if (type.compare ("boolean"))
+    {
+      retval = property (new bool_property (name, h, false));
+
+      if (args.length () > 0)
+	retval.set (args(0));
+    }
+  else if (type.compare ("data"))
+    {
+      retval = property (new array_property (name, h, Matrix ()));
+
+      if (args.length () > 0)
+	{
+	  retval.set (args(0));
+
+	  // FIXME -- additional argument could define constraints,
+	  // but is this really useful?
+	}
+    }
+  else if (type.compare ("color"))
+    {
+      color_values cv (0, 0, 0);
+      radio_values rv;
+
+      if (args.length () > 1)
+	rv = radio_values (args(1).string_value ());
+
+      if (! error_state)
+	{
+	  retval = property (new color_property (name, h, cv, rv));
+
+	  if (! error_state)
+	    {
+	      if (args.length () > 0 && ! args(0).is_empty ())
+		retval.set (args(0));
+	      else
+		retval.set (rv.default_value ());
+	    }
+	}
+    }
+  else
+    {
+      caseless_str go_name, go_rest;
+
+      if (lookup_object_name (type, go_name, go_rest))
+	{
+	  graphics_object go;
+
+	  std::map<caseless_str, graphics_object>::const_iterator it =
+	      dprop_obj_map.find (go_name);
+
+	  if (it == dprop_obj_map.end ())
+	    {
+	      base_graphics_object *bgo =
+		  make_graphics_object_from_type (go_name);
+
+	      if (bgo)
+		{
+		  go = graphics_object (bgo);
+
+		  dprop_obj_map[go_name] = go;
+		}
+	    }
+	  else
+	    go = it->second;
+
+	  if (go.valid_object ())
+	    {
+	      property prop = go.get_properties ().get_property (go_rest);
+
+	      if (! error_state)
+		{
+		  retval = prop.clone ();
+
+		  retval.set_parent (h);
+		  retval.set_name (name);
+
+		  if (args.length () > 0)
+		    retval.set (args(0));
+		}
+	    }
+	  else
+	    error ("addproperty: invalid object type (= %s)",
+		   go_name.c_str ());
+	}
+      else
+	error ("addproperty: unsupported type for dynamic property (= %s)",
+	       type.c_str ());
+    }
+  
+  return retval;
+}
+
+// ---------------------------------------------------------------------
+
+void
+property_list::set (const caseless_str& name, const octave_value& val)
+{
+  size_t offset = 0;
+
+  size_t len = name.length ();
+
+  if (len > 4)
+    {
+      caseless_str pfx = name.substr (0, 4);
+
+      if (pfx.compare ("axes") || pfx.compare ("line")
+	  || pfx.compare ("text"))
+	offset = 4;
+      else if (len > 5)
+	{
+	  pfx = name.substr (0, 5);
+
+	  if (pfx.compare ("image") || pfx.compare ("patch"))
+	    offset = 5;
+	  else if (len > 6)
+	    {
+	      pfx = name.substr (0, 6);
+
+	      if (pfx.compare ("figure"))
+		offset = 6;
+	      else if (len > 7)
+		{
+		  pfx = name.substr (0, 7);
+
+		  if (pfx.compare ("surface") || pfx.compare ("hggroup"))
+		    offset = 7;
+		}
+	    }
+	}
+
+      if (offset > 0)
+	{
+	  // FIXME -- should we validate property names and values here?
+
+	  std::string pname = name.substr (offset);
+
+	  std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
+	  std::transform (pname.begin (), pname.end (), pname.begin (), tolower);
+
+	  bool has_property = false;
+	  if (pfx == "axes")
+	    has_property = axes::properties::has_property (pname);
+	  else if (pfx == "line")
+	    has_property = line::properties::has_property (pname);
+	  else if (pfx == "text")
+	    has_property = text::properties::has_property (pname);
+	  else if (pfx == "image")
+	    has_property = image::properties::has_property (pname);
+	  else if (pfx == "patch")
+	    has_property = patch::properties::has_property (pname);
+	  else if (pfx == "figure")
+	    has_property = figure::properties::has_property (pname);
+	  else if (pfx == "surface")
+	    has_property = surface::properties::has_property (pname);
+	  else if (pfx == "hggroup")
+	    has_property = hggroup::properties::has_property (pname);
+
+	  if (has_property)
+	    {
+	      bool remove = false;
+	      if (val.is_string ())
+		{
+		  caseless_str tval = val.string_value ();
+
+		  remove = tval.compare ("remove");
+		}
+
+	      pval_map_type& pval_map = plist_map[pfx];
+
+	      if (remove)
+		{
+		  pval_map_iterator p = pval_map.find (pname);
+
+		  if (p != pval_map.end ())
+		    pval_map.erase (p);
+		}
+	      else
+		pval_map[pname] = val;
+	    }
+	  else
+	    error ("invalid %s property `%s'", pfx.c_str (), pname.c_str ());
+	}
+    }
+
+  if (! error_state && offset == 0)
+    error ("invalid default property specification");
+}
+
+octave_value
+property_list::lookup (const caseless_str& name) const
+{
+  octave_value retval;
+
+  size_t offset = 0;
+
+  size_t len = name.length ();
+
+  if (len > 4)
+    {
+      caseless_str pfx = name.substr (0, 4);
+
+      if (pfx.compare ("axes") || pfx.compare ("line")
+	  || pfx.compare ("text"))
+	offset = 4;
+      else if (len > 5)
+	{
+	  pfx = name.substr (0, 5);
+
+	  if (pfx.compare ("image") || pfx.compare ("patch"))
+	    offset = 5;
+	  else if (len > 6)
+	    {
+	      pfx = name.substr (0, 6);
+
+	      if (pfx.compare ("figure"))
+		offset = 6;
+	      else if (len > 7)
+		{
+		  pfx = name.substr (0, 7);
+
+		  if (pfx.compare ("surface") || pfx.compare ("hggroup"))
+		    offset = 7;
+		}
+	    }
+	}
+
+      if (offset > 0)
+	{
+	  std::string pname = name.substr (offset);
+
+	  std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
+	  std::transform (pname.begin (), pname.end (), pname.begin (), tolower);
+
+	  plist_map_const_iterator p = find (pfx);
+
+	  if (p != end ())
+	    {
+	      const pval_map_type& pval_map = p->second;
+
+	      pval_map_const_iterator q = pval_map.find (pname);
+
+	      if (q != pval_map.end ())
+		retval = q->second;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+Octave_map
+property_list::as_struct (const std::string& prefix_arg) const
+{
+  Octave_map m;
+
+  for (plist_map_const_iterator p = begin (); p != end (); p++)
+    {
+      std::string prefix = prefix_arg + p->first;
+
+      const pval_map_type pval_map = p->second;
+
+      for (pval_map_const_iterator q = pval_map.begin ();
+	   q != pval_map.end ();
+	   q++)
+	m.assign (prefix + q->first, q->second);
+    }
+
+  return m;    
+}
+
+graphics_handle::graphics_handle (const octave_value& a)
+  : val (octave_NaN)
+{
+  if (a.is_empty ())
+    /* do nothing */;
+  else
+    {
+      double tval = a.double_value ();
+
+      if (! error_state)
+	val = tval;
+      else
+	error ("invalid graphics handle");
+    }
+}
+
+void
+graphics_object::set (const octave_value_list& args)
+{
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    rep->defaults ();
+  else if (nargin % 2 == 0)
+    {
+      for (int i = 0; i < nargin; i += 2)
+	{
+	  caseless_str name = args(i).string_value ();
+
+	  if (! error_state)
+	    {
+	      octave_value val = args(i+1);
+
+	      if (val.is_string ())
+		{
+		  caseless_str tval = val.string_value ();
+
+		  if (tval.compare ("default"))
+		    val = get_default (name);
+		  else if (tval.compare ("factory"))
+		    val = get_factory_default (name);
+		}
+
+	      if (error_state)
+		break;
+
+	      rep->set (name, val);
+	    }
+	  else
+	    error ("set: expecting argument %d to be a property name", i);
+	}
+    }
+  else
+    error ("set: invalid number of arguments");
+}
+
+static double
+make_handle_fraction (void)
+{
+  static double maxrand = RAND_MAX + 2.0;
+
+  return (rand () + 1.0) / maxrand;
+}
+
+graphics_handle
+gh_manager::get_handle (const std::string& go_name)
+{
+  graphics_handle retval;
+
+  if (go_name == "figure")
+    {
+      // Figure handles are positive integers corresponding to the
+      // figure number.
+
+      // We always want the lowest unused figure number.
+
+      retval = 1;
+
+      while (handle_map.find (retval) != handle_map.end ())
+	retval++;
+    }
+  else
+    {
+      // Other graphics handles are negative integers plus some random
+      // fractional part.  To avoid running out of integers, we
+      // recycle the integer part but tack on a new random part each
+      // time.
+
+      free_list_iterator p = handle_free_list.begin ();
+
+      if (p != handle_free_list.end ())
+	{
+	  retval = *p;
+	  handle_free_list.erase (p);
+	}
+      else
+	{
+	  retval = graphics_handle (next_handle);
+
+	  next_handle = ceil (next_handle) - 1.0 - make_handle_fraction ();
+	}
+    }
+
+  return retval;
+}
+
+void
+gh_manager::do_free (const graphics_handle& h)
+{
+  if (h.ok ())
+    {
+      if (h.value () != 0)
+	{
+	  iterator p = handle_map.find (h);
+
+	  if (p != handle_map.end ())
+	    {
+	      base_properties& bp = p->second.get_properties ();
+	      
+	      bp.set_beingdeleted (true);
+
+	      bp.delete_children ();
+
+	      octave_value val = bp.get_deletefcn ();
+
+	      bp.execute_deletefcn ();
+
+	      // notify backend
+	      graphics_backend backend = p->second.get_backend ();
+	      if (backend)
+                backend.object_destroyed (p->second);
+
+	      // Note: this will be valid only for first explicitly 
+	      // deleted object.  All its children will then have an
+	      // unknown backend.
+
+	      // Graphics handles for non-figure objects are negative
+	      // integers plus some random fractional part.  To avoid
+	      // running out of integers, we recycle the integer part
+	      // but tack on a new random part each time.
+
+	      handle_map.erase (p);
+
+	      if (h.value () < 0)
+		handle_free_list.insert (ceil (h.value ()) - make_handle_fraction ());
+	    }
+	  else
+	    error ("graphics_handle::free: invalid object %g", h.value ());
+	}
+      else
+	error ("graphics_handle::free: can't delete root figure");
+    }
+}
+
+gh_manager *gh_manager::instance = 0;
+
+static void
+xset (const graphics_handle& h, const caseless_str& name,
+      const octave_value& val)
+{
+  graphics_object obj = gh_manager::get_object (h);
+  obj.set (name, val);
+}
+
+static void
+xset (const graphics_handle& h, const octave_value_list& args)
+{
+  if (args.length () > 0)
+    {
+      graphics_object obj = gh_manager::get_object (h);
+      obj.set (args);
+    }
+}
+
+
+static octave_value
+xget (const graphics_handle& h, const caseless_str& name)
+{
+  graphics_object obj = gh_manager::get_object (h);
+  return obj.get (name);
+}
+
+static graphics_handle
+reparent (const octave_value& ov, const std::string& who,
+	  const std::string& property, const graphics_handle& new_parent,
+	  bool adopt = true)
+{
+  graphics_handle h = octave_NaN;
+
+  double val = ov.double_value ();
+
+  if (! error_state)
+    {
+      h = gh_manager::lookup (val);
+
+      if (h.ok ())
+	{
+	  graphics_object obj = gh_manager::get_object (h);
+	  
+	  graphics_handle parent_h = obj.get_parent ();
+
+	  graphics_object parent_obj = gh_manager::get_object (parent_h);
+
+	  parent_obj.remove_child (h);
+
+	  if (adopt)
+	    obj.set ("parent", new_parent.value ());
+	  else
+	    obj.reparent (new_parent);
+	}
+      else
+	error ("%s: invalid graphics handle (= %g) for %s",
+	       who.c_str (), val, property.c_str ());
+    }
+  else
+    error ("%s: expecting %s to be a graphics handle",
+	   who.c_str (), property.c_str ());
+
+  return h;
+}
+
+// This function is NOT equivalent to the scripting language function gcf.
+graphics_handle
+gcf (void)
+{
+  octave_value val = xget (0, "currentfigure");
+
+  return val.is_empty () ? octave_NaN : val.double_value ();
+}
+
+// This function is NOT equivalent to the scripting language function gca.
+graphics_handle
+gca (void)
+{
+  octave_value val = xget (gcf (), "currentaxes");
+
+  return val.is_empty () ? octave_NaN : val.double_value ();
+}
+
+static void
+adopt (const graphics_handle& p, const graphics_handle& h)
+{
+  graphics_object parent_obj = gh_manager::get_object (p);
+
+  parent_obj.adopt (h);
+}
+
+static bool
+is_handle (const graphics_handle& h)
+{
+  return h.ok ();
+}
+
+static bool
+is_handle (double val)
+{
+  graphics_handle h = gh_manager::lookup (val);
+
+  return h.ok ();
+}
+
+static octave_value
+is_handle (const octave_value& val)
+{
+  octave_value retval = false;
+
+  if (val.is_real_scalar () && is_handle (val.double_value ()))
+    retval = true;
+  else if (val.is_real_matrix ())
+    {
+      if (val.is_string ())
+	retval = boolNDArray (val.dims (), false);
+      else
+	{
+	  const NDArray handles = val.array_value ();
+
+	  if (! error_state)
+	    {
+	      boolNDArray result (handles.dims ());
+
+	      for (octave_idx_type i = 0; i < handles.numel (); i++)
+		result.xelem (i) = is_handle (handles (i));
+
+	      retval = result;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static bool
+is_figure (double val)
+{
+  graphics_object obj = gh_manager::get_object (val);
+
+  return obj && obj.isa ("figure");
+}
+
+static void
+xcreatefcn (const graphics_handle& h)
+{
+  graphics_object obj = gh_manager::get_object (h);
+  obj.get_properties ().execute_createfcn  ();
+}
+
+// ---------------------------------------------------------------------
+
+void
+base_graphics_backend::property_changed (const graphics_handle& h, int id)
+{
+  graphics_object go = gh_manager::get_object (h);
+
+  property_changed (go, id);
+}
+
+void
+base_graphics_backend::object_created (const graphics_handle& h)
+{
+  graphics_object go = gh_manager::get_object (h);
+
+  object_created (go);
+}
+
+void
+base_graphics_backend::object_destroyed (const graphics_handle& h)
+{
+  graphics_object go = gh_manager::get_object (h);
+
+  object_destroyed (go);
+}
+// ---------------------------------------------------------------------
+
+static Matrix
+maybe_set_children (const Matrix& kids, const octave_value& val)
+{
+  const Matrix new_kids = val.matrix_value ();
+
+  bool ok = true;
+
+  if (! error_state)
+    {
+      if (kids.numel () == new_kids.numel ())
+	{
+	  Matrix t1 = kids;
+	  Matrix t2 = new_kids;
+
+	  t1.sort ();
+	  t2.sort ();
+
+	  if (t1 != t2)
+	    ok = false;
+	}
+      else
+	ok = false;
+
+      if (! ok)
+	error ("set: new children must be a permutation of existing children");
+    }
+  else
+    {
+      ok = false;
+      error ("set: expecting children to be array of graphics handles");
+    }
+
+  return ok ? new_kids : kids;
+}
+
+void
+base_properties::set_from_list (base_graphics_object& obj,
+				property_list& defaults)
+{
+  std::string go_name = graphics_object_name ();
+
+  property_list::plist_map_const_iterator p = defaults.find (go_name);
+
+  if (p != defaults.end ())
+    {
+      const property_list::pval_map_type pval_map = p->second;
+
+      for (property_list::pval_map_const_iterator q = pval_map.begin ();
+	   q != pval_map.end ();
+	   q++)
+	{
+	  std::string pname = q->first;
+
+	  obj.set (pname, q->second);
+
+	  if (error_state)
+	    {
+	      error ("error setting default property %s", pname.c_str ());
+	      break;
+	    }
+	}
+    }
+}
+
+octave_value
+base_properties::get_dynamic (const caseless_str& name) const
+{
+  octave_value retval;
+
+  std::map<caseless_str, property, cmp_caseless_str>::const_iterator it = all_props.find (name);
+
+  if (it != all_props.end ())
+    retval = it->second.get ();
+  else
+    error ("get: unknown property \"%s\"", name.c_str ());
+
+  return retval;
+}
+
+octave_value
+base_properties::get_dynamic (bool all) const
+{
+  Octave_map m;
+
+  for (std::map<caseless_str, property, cmp_caseless_str>::const_iterator it = all_props.begin ();
+       it != all_props.end (); ++it)
+    if (all || ! it->second.is_hidden ())
+      m.assign (it->second.get_name (), it->second.get ());
+
+  return m;
+}
+
+std::map<std::string, std::set<std::string> > base_properties::all_dynamic_properties;
+
+bool
+base_properties::has_dynamic_property (const std::string& pname,
+				       const std::string& cname)
+{
+  // FIXME -- we need to maintain a static map of class names to sets
+  // of dynamic property names, then look up the set for the given
+  // cname, then see if the set contains the given pname.  Doing that
+  // implies changes to set_dynamic, I think.  Where is set_dynamic
+  // ever used?
+
+  std::set<std::string>& dynprops = all_dynamic_properties[cname];
+
+  return dynprops.find (pname) != dynprops.end ();
+}
+
+void
+base_properties::set_dynamic (const caseless_str& pname,
+			      const std::string& cname,
+			      const octave_value& val)
+{
+  std::map<caseless_str, property, cmp_caseless_str>::iterator it = all_props.find (pname);
+
+  if (it != all_props.end ())
+    it->second.set (val);
+  else
+    error ("set: unknown property \"%s\"", pname.c_str ());
+
+  if (! error_state)
+    {
+      all_dynamic_properties[cname].insert (pname);
+
+      mark_modified ();
+    }
+}
+
+property
+base_properties::get_property_dynamic (const caseless_str& name)
+{
+  std::map<caseless_str, property, cmp_caseless_str>::const_iterator it = all_props.find (name);
+
+  if (it == all_props.end ())
+    {
+      error ("get_property: unknown property \"%s\"", name.c_str ());
+      return property ();
+    }
+  else
+    return it->second;
+}
+
+bool
+base_properties::has_property (const caseless_str& name)
+{
+  property p;
+
+  unwind_protect::begin_frame("base_properties::has_property");
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_int (error_state);
+
+  discard_error_messages = true;
+
+  p = get_property (name);
+
+  unwind_protect::run_frame ("base_properties::has_property");
+
+  return (p.ok ());
+}
+
+void
+base_properties::remove_child (const graphics_handle& h)
+{
+  octave_idx_type k = -1;
+  octave_idx_type n = children.numel ();
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      if (h.value () == children(i))
+	{
+	  k = i;
+	  break;
+	}
+    }
+
+  if (k >= 0)
+    {
+      Matrix new_kids (n-1, 1);
+      octave_idx_type j = 0;
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  if (i != k)
+	    new_kids(j++) = children(i);
+	}
+      children = new_kids;
+      mark_modified ();
+    }
+}
+
+void
+base_properties::set_parent (const octave_value& val)
+{
+  double tmp = val.double_value ();
+
+  graphics_handle new_parent = octave_NaN;
+
+  if (! error_state)
+    {
+      new_parent = gh_manager::lookup (tmp);
+
+      if (new_parent.ok ())
+	{
+	  graphics_object parent_obj = gh_manager::get_object (get_parent ());
+
+	  parent_obj.remove_child (__myhandle__);
+
+	  parent = new_parent.as_octave_value ();
+
+	  ::adopt (parent.handle_value (), __myhandle__);
+	}
+      else
+	error ("set: invalid graphics handle (= %g) for parent", tmp);
+    }
+  else
+    error ("set: expecting parent to be a graphics handle");
+}
+
+void
+base_properties::set_children (const octave_value& val)
+{
+  children = maybe_set_children (children, val);
+}
+
+void
+base_properties::mark_modified (void)
+{
+  __modified__ = "on";
+  graphics_object parent_obj = gh_manager::get_object (get_parent ());
+  if (parent_obj)
+    parent_obj.mark_modified ();
+}
+
+void
+base_properties::override_defaults (base_graphics_object& obj)
+{
+  graphics_object parent_obj = gh_manager::get_object (get_parent ());
+
+  if (parent_obj)
+    parent_obj.override_defaults (obj);
+}
+
+void
+base_properties::update_axis_limits (const std::string& axis_type) const
+{
+  graphics_object obj = gh_manager::get_object (__myhandle__);
+
+  if (obj)
+    obj.update_axis_limits (axis_type);
+}
+
+void
+base_properties::delete_children (void)
+{
+  octave_idx_type n = children.numel ();
+
+  // A callback function might have already deleted the child,
+  // so check before deleting
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      graphics_object go = gh_manager::get_object (children(i));
+
+      if (go.valid_object ())
+	gh_manager::free (children(i));
+    }
+}
+
+graphics_backend
+base_properties::get_backend (void) const
+{
+  graphics_object go = gh_manager::get_object (get_parent ());
+
+  if (go)
+    return go.get_backend ();
+  else
+    return graphics_backend ();
+}
+
+void
+base_properties::update_boundingbox (void)
+{
+  Matrix kids = get_children ();
+
+  for (int i = 0; i < kids.numel (); i++)
+    {
+      graphics_object go = gh_manager::get_object (kids(i));
+
+      if (go.valid_object ())
+	go.get_properties ().update_boundingbox ();
+    }
+}
+
+void
+base_properties::add_listener (const caseless_str& nm, const octave_value& v,
+			       listener_mode mode)
+{
+  property p = get_property (nm);
+
+  if (! error_state && p.ok ())
+    p.add_listener (v, mode);
+}
+
+void
+base_properties::delete_listener (const caseless_str& nm, 
+				  const octave_value& v, listener_mode mode)
+{
+  property p = get_property (nm);
+
+  if (! error_state && p.ok ())
+    p.delete_listener (v, mode);
+}
+
+// ---------------------------------------------------------------------
+
+class gnuplot_backend : public base_graphics_backend
+{
+public:
+  gnuplot_backend (void)
+      : base_graphics_backend ("gnuplot") { }
+
+  ~gnuplot_backend (void) { }
+
+  bool is_valid (void) const { return true; }
+
+  void object_destroyed (const graphics_object& go)
+    {
+      if (go.isa ("figure"))
+	{
+	  const figure::properties& props =
+	      dynamic_cast<const figure::properties&> (go.get_properties ());
+
+	  send_quit (props.get___plot_stream__ ());
+	}
+    }
+
+  void property_changed (const graphics_object& go, int id)
+    {
+      if (go.isa ("figure"))
+	{
+	  graphics_object obj (go);
+
+	  figure::properties& props =
+	      dynamic_cast<figure::properties&> (obj.get_properties ());
+
+	  switch (id)
+	    {
+	    case base_properties::VISIBLE:
+	      if (! props.is_visible ())
+		{
+		  send_quit (props.get___plot_stream__ ());
+		  props.set___plot_stream__ (Matrix ());
+		  props.set___enhanced__ (false);
+		}
+	      break;
+	    }
+	}
+    }
+
+  void redraw_figure (const graphics_object& go) const
+    {
+      octave_value_list args;
+      args(0) = go.get_handle ().as_octave_value ();
+      feval ("gnuplot_drawnow", args);
+    }
+
+  void print_figure (const graphics_object& go, const std::string& term,
+		     const std::string& file, bool mono,
+		     const std::string& debug_file) const
+    {
+      octave_value_list args;
+      if (! debug_file.empty ())
+	args(4) = debug_file;
+      args(3) = mono;
+      args(2) = file;
+      args(1) = term;
+      args(0) = go.get_handle ().as_octave_value ();
+      feval ("gnuplot_drawnow", args);
+    }
+
+  Matrix get_canvas_size (const graphics_handle&) const
+    {
+      Matrix sz (1, 2, 0.0);
+      return sz;
+    }
+
+  double get_screen_resolution (void) const
+    { return 72.0; }
+
+  Matrix get_screen_size (void) const
+    { return Matrix (1, 2, 0.0); }
+
+private:
+  void send_quit (const octave_value& pstream) const
+    {
+      if (! pstream.is_empty ())
+	{
+	  octave_value_list args;
+	  Matrix fids = pstream.matrix_value ();
+
+	  if (! error_state)
+	    {
+	      args(1) = "\nquit;\n";
+	      args(0) = fids(0);
+	      feval ("fputs", args);
+
+	      args.resize (1);
+	      feval ("fflush", args);
+	      feval ("pclose", args);
+
+	      if (fids.numel () > 1)
+		{
+		  args(0) = fids(1);
+		  feval ("pclose", args);
+
+		  if (fids.numel () > 2)
+		    {
+		      args(0) = fids(2);
+		      feval ("waitpid", args);
+		    }
+		}
+	    }
+	}
+    }
+};
+
+graphics_backend
+graphics_backend::default_backend (void)
+{
+  if (available_backends.size () == 0)
+    register_backend (new gnuplot_backend ());
+
+  return available_backends["gnuplot"];
+}
+
+std::map<std::string, graphics_backend> graphics_backend::available_backends;
+
+// ---------------------------------------------------------------------
+
+void
+base_graphics_object::update_axis_limits (const std::string& axis_type)
+{
+  if (valid_object ())
+    {
+      graphics_object parent_obj = gh_manager::get_object (get_parent ());
+
+      if (parent_obj)
+	parent_obj.update_axis_limits (axis_type);
+    }
+  else
+    error ("base_graphics_object::update_axis_limits: invalid graphics object");
+}
+
+void
+base_graphics_object::remove_all_listeners (void)
+{
+  Octave_map m = get (true).map_value ();
+
+  for (Octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++)
+    {
+      if (get_properties().has_property (pa->first))
+	{
+	  property p = get_properties ().get_property (pa->first);
+
+	  if (! error_state && p.ok ())
+	    p.delete_listener ();
+	}
+    }
+}
+
+// ---------------------------------------------------------------------
+
+#include "graphics-props.cc"
+
+// ---------------------------------------------------------------------
+
+void
+root_figure::properties::set_currentfigure (const octave_value& v)
+{
+  graphics_handle val (v);
+
+  if (error_state)
+    return;
+
+  if (xisnan (val.value ()) || is_handle (val))
+    {
+      currentfigure = val;
+
+      gh_manager::push_figure (val);
+    }
+  else
+    gripe_set_invalid ("currentfigure");
+}
+
+void
+root_figure::properties::set_callbackobject (const octave_value& v)
+{
+  graphics_handle val (v);
+
+  if (error_state)
+    return;
+
+  if (xisnan (val.value ()))
+    {
+      if (! cbo_stack.empty ())
+	{
+	  val = cbo_stack.front ();
+
+	  cbo_stack.pop_front ();
+	}
+
+      callbackobject = val;
+    }
+  else if (is_handle (val))
+    {
+      if (get_callbackobject ().ok ())
+	cbo_stack.push_front (get_callbackobject ());
+
+      callbackobject = val;
+    }
+  else
+    gripe_set_invalid ("callbackobject");
+}
+
+void
+root_figure::properties::update_units (void)
+{
+  caseless_str xunits = get_units ();
+
+  Matrix ss = default_screensize ();
+
+  double dpi = get_screenpixelsperinch ();
+
+  if (xunits.compare ("inches"))
+    {
+      ss(0) = 0;
+      ss(1) = 0;
+      ss(2) /= dpi;
+      ss(3) /= dpi;
+    }
+  else if (xunits.compare ("centimeters"))
+    {
+      ss(0) = 0;
+      ss(1) = 0;
+      ss(2) *= 2.54 / dpi;
+      ss(3) *= 2.54 / dpi;
+    }
+  else if (xunits.compare ("normalized"))
+    {
+      ss = Matrix (1, 4, 1.0);
+    }
+  else if (xunits.compare ("points"))
+    {
+      ss(0) = 0;
+      ss(1) = 0;
+      ss(2) *= 72 / dpi;
+      ss(3) *= 72 / dpi;
+    }
+
+  set_screensize (ss);
+}
+
+void
+root_figure::properties::remove_child (const graphics_handle& gh)
+{
+  gh_manager::pop_figure (gh);
+
+  graphics_handle cf = gh_manager::current_figure ();
+
+  xset (0, "currentfigure", cf.value ());
+  
+  base_properties::remove_child (gh);
+}
+
+property_list
+root_figure::factory_properties = root_figure::init_factory_properties ();
+
+// ---------------------------------------------------------------------
+
+void
+figure::properties::set_currentaxes (const octave_value& v)
+{
+  graphics_handle val (v);
+
+  if (error_state)
+    return;
+
+  if (xisnan (val.value ()) || is_handle (val))
+    currentaxes = val;
+  else
+    gripe_set_invalid ("currentaxes");
+}
+
+void
+figure::properties::remove_child (const graphics_handle& gh)
+{
+  base_properties::remove_child (gh);
+
+  if (gh == currentaxes.handle_value ())
+    {
+      graphics_handle new_currentaxes;
+
+      for (octave_idx_type i = 0; i < children.numel (); i++)
+	{
+	  graphics_handle kid = children(i);
+
+	  graphics_object go = gh_manager::get_object (kid);
+
+	  if (go.isa ("axes"))
+	    {
+	      new_currentaxes = kid;
+	      break;
+	    }
+	}
+
+      currentaxes = new_currentaxes;
+    }
+}
+
+void
+figure::properties::set_visible (const octave_value& val)
+{
+  std::string s = val.string_value ();
+
+  if (! error_state)
+    {
+      if (s == "on")
+	xset (0, "currentfigure", __myhandle__.value ());
+
+      visible = val;
+    }
+}
+
+Matrix
+figure::properties::get_boundingbox (bool) const
+{
+  Matrix screen_size = xget (0, "screensize").matrix_value ().extract_n (0, 2, 1, 2);
+  Matrix pos;
+
+  pos = convert_position (get_position ().matrix_value (), get_units (),
+			  "pixels", screen_size);
+
+  pos(0)--;
+  pos(1)--;
+  pos(1) = screen_size(1) - pos(1) - pos(3);
+
+  return pos;
+}
+
+void
+figure::properties::set_boundingbox (const Matrix& bb)
+{
+  Matrix screen_size = xget (0, "screensize").matrix_value ().extract_n (0, 2, 1, 2);
+  Matrix pos = bb;
+
+  pos(1) = screen_size(1) - pos(1) - pos(3);
+  pos(1)++;
+  pos(0)++;
+  pos = convert_position (pos, "pixels", get_units (), screen_size);
+
+  set_position (pos);
+}
+
+void
+figure::properties::set_position (const octave_value& v)
+{
+  if (! error_state)
+    {
+      Matrix old_bb, new_bb;
+
+      old_bb = get_boundingbox ();
+      position = v;
+      new_bb = get_boundingbox ();
+
+      if (old_bb != new_bb)
+	{
+	  if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3))
+	    {
+	      execute_resizefcn ();
+	      update_boundingbox ();
+	    }
+	}
+
+      mark_modified ();
+    }
+}
+
+std::string
+figure::properties::get_title (void) const
+{
+  if (is_numbertitle ())
+    {
+      std::ostringstream os;
+      std::string nm = get_name ();
+
+      os << "Figure " << __myhandle__.value ();
+      if (! nm.empty ())
+	os << ": " << get_name ();
+
+      return os.str ();
+    }
+  else
+    return get_name ();
+}
+
+octave_value
+figure::get_default (const caseless_str& name) const
+{
+  octave_value retval = default_properties.lookup (name);
+
+  if (retval.is_undefined ())
+    {
+      graphics_handle parent = get_parent ();
+      graphics_object parent_obj = gh_manager::get_object (parent);
+
+      retval = parent_obj.get_default (name);
+    }
+
+  return retval;
+}
+
+// ---------------------------------------------------------------------
+
+void
+axes::properties::init (void)
+{
+  position.add_constraint (dim_vector (1, 4));
+  position.add_constraint (dim_vector (0, 0));
+  outerposition.add_constraint (dim_vector (1, 4));
+  colororder.add_constraint (dim_vector (-1, 3));
+  dataaspectratio.add_constraint (dim_vector (1, 3));
+  plotboxaspectratio.add_constraint (dim_vector (1, 3));
+  xlim.add_constraint (2);
+  ylim.add_constraint (2);
+  zlim.add_constraint (2);
+  clim.add_constraint (2);
+  alim.add_constraint (2);
+  xtick.add_constraint (dim_vector (1, -1));
+  ytick.add_constraint (dim_vector (1, -1));
+  ztick.add_constraint (dim_vector (1, -1));
+  Matrix vw (1, 2, 0);
+  vw(1) = 90;
+  view = vw;
+  view.add_constraint (dim_vector (1, 2));
+  cameraposition.add_constraint (dim_vector (1, 3));
+  Matrix upv (1, 3, 0.0);
+  upv(2) = 1.0;
+  cameraupvector = upv;
+  cameraupvector.add_constraint (dim_vector (1, 3));
+  currentpoint.add_constraint (dim_vector (2, 3));
+  ticklength.add_constraint (dim_vector (1, 2));
+  tightinset.add_constraint (dim_vector (1, 4));
+
+  x_zlim.resize (1, 2);
+
+  sx = "linear";
+  sy = "linear";
+  sz = "linear";
+
+  xset (xlabel.handle_value (), "handlevisibility", "off");
+  xset (ylabel.handle_value (), "handlevisibility", "off");
+  xset (zlabel.handle_value (), "handlevisibility", "off");
+  xset (title.handle_value (), "handlevisibility", "off");
+
+  xset (xlabel.handle_value (), "horizontalalignment", "center");
+  xset (ylabel.handle_value (), "horizontalalignment", "center");
+  xset (zlabel.handle_value (), "horizontalalignment", "right");
+  xset (title.handle_value (), "horizontalalignment", "center");
+
+  xset (xlabel.handle_value (), "verticalalignment", "cap");
+  xset (ylabel.handle_value (), "verticalalignment", "bottom");
+  xset (title.handle_value (), "verticalalignment", "bottom");
+
+  xset (ylabel.handle_value (), "rotation", 90.0);
+
+  adopt (xlabel.handle_value ());
+  adopt (ylabel.handle_value ());
+  adopt (zlabel.handle_value ());
+  adopt (title.handle_value ());
+}
+
+void 
+axes::properties::sync_positions (void)
+{
+#if 0
+  // FIXME -- this should take font metrics into consideration,
+  // and also the fact that the colorbox leaves the outerposition
+  // alone but alters the position. For now just don't adjust the
+  // positions relative to each other.
+
+  if (activepositionproperty.is ("outerposition"))
+    {
+      Matrix outpos = outerposition.get ().matrix_value ();
+      Matrix defpos = default_axes_position ();
+      Matrix pos(outpos);
+      pos(0) = outpos(0) + defpos(0) * outpos(2);
+      pos(1) = outpos(1) + defpos(1) * outpos(3);
+      pos(2) = outpos(2) * defpos(2);
+      pos(3) = outpos(3) * defpos(3);
+      position = pos;
+    }
+  else
+    {
+      Matrix pos = position.get ().matrix_value ();
+      pos(0) -= pos(2)*0.05;
+      pos(1) -= pos(3)*0.05;
+      pos(2) *= 1.1;
+      pos(3) *= 1.1;
+      outerposition = pos;
+    }
+#endif
+
+  update_transform ();
+}
+
+void
+axes::properties::set_text_child (handle_property& hp,
+				  const std::string& who,
+				  const octave_value& v)
+{
+  graphics_handle val = ::reparent (v, "set", who, __myhandle__, false);
+
+  if (! error_state)
+    {
+      xset (val, "handlevisibility", "off");
+
+      gh_manager::free (hp.handle_value ());
+
+      base_properties::remove_child (hp.handle_value ());
+
+      hp = val;
+
+      adopt (hp.handle_value ());
+    }
+}
+
+void
+axes::properties::set_xlabel (const octave_value& v)
+{
+  set_text_child (xlabel, "xlabel", v);
+}
+
+void
+axes::properties::set_ylabel (const octave_value& v)
+{
+  set_text_child (ylabel, "ylabel", v);
+}
+
+void
+axes::properties::set_zlabel (const octave_value& v)
+{
+  set_text_child (zlabel, "zlabel", v);
+}
+
+void
+axes::properties::set_title (const octave_value& v)
+{
+  set_text_child (title, "title", v);
+}
+
+void
+axes::properties::set_defaults (base_graphics_object& obj,
+				const std::string& mode)
+{
+  box = "on";
+  key = "off";
+  keybox = "off";
+  keyreverse = "off";
+  keypos = 1.0;
+  colororder = default_colororder ();
+  dataaspectratio = Matrix (1, 3, 1.0);
+  dataaspectratiomode = "auto";
+  layer = "bottom";
+
+  Matrix tlim (1, 2, 0.0);
+  tlim(1) = 1;
+  xlim = tlim;
+  ylim = tlim;
+  zlim = tlim;
+  
+  Matrix cl (1, 2, 0);
+  cl(1) = 1;
+  clim = cl;
+  
+  xlimmode = "auto";
+  ylimmode = "auto";
+  zlimmode = "auto";
+  climmode = "auto";
+
+  xgrid = "off";
+  ygrid = "off";
+  zgrid = "off";
+  xminorgrid = "off";
+  yminorgrid = "off";
+  zminorgrid = "off";
+  xtick = Matrix ();
+  ytick = Matrix ();
+  ztick = Matrix ();
+  xtickmode = "auto";
+  ytickmode = "auto";
+  ztickmode = "auto";
+  xticklabel = "";
+  yticklabel = "";
+  zticklabel = "";
+  xticklabelmode = "auto";
+  yticklabelmode = "auto";
+  zticklabelmode = "auto";
+  color = color_values (1, 1, 1);
+  xcolor = color_values ("black");
+  ycolor = color_values ("black");
+  zcolor = color_values ("black");
+  xscale = "linear";
+  yscale = "linear";
+  zscale = "linear";
+  xdir = "normal";
+  ydir = "normal";
+  zdir = "normal";
+  yaxislocation = "left";
+  xaxislocation = "bottom";
+
+  // Note: camera properties will be set through update_transform
+  camerapositionmode = "auto";
+  cameratargetmode = "auto";
+  cameraupvectormode = "auto";
+  cameraviewanglemode = "auto";
+  plotboxaspectratio = Matrix (1, 3, 1.0);
+  drawmode = "normal";
+  gridlinestyle = ":";
+  linestyleorder = "-";
+  linewidth = 0.5;
+  minorgridlinestyle = ":";
+  // Note: plotboxaspectratio will be set through update_aspectratiors
+  plotboxaspectratiomode = "auto";
+  projection = "orthographic";
+  tickdir = "in";
+  tickdirmode = "auto";
+  ticklength = default_axes_ticklength ();
+  tightinset = Matrix (1, 4, 0.0);
+
+  sx = "linear";
+  sy = "linear";
+  sz = "linear";
+
+  Matrix tview (1, 2, 0.0);
+  tview(1) = 90;
+  view = tview;
+
+  visible = "on";
+  nextplot = "replace";
+
+  if (mode != "replace")
+    {
+      fontangle = "normal";
+      fontname = OCTAVE_DEFAULT_FONTNAME;
+      fontsize = 12;
+      fontunits = "points";
+      fontweight = "normal";
+
+      Matrix touterposition (1, 4, 0.0);
+      touterposition(2) = 1;
+      touterposition(3) = 1;
+      outerposition = touterposition;
+
+      position = default_axes_position ();
+
+      activepositionproperty = "outerposition";
+    }
+
+  delete_children ();
+
+  children = Matrix ();
+
+  xlabel = gh_manager::make_graphics_handle ("text", __myhandle__, false);
+  ylabel = gh_manager::make_graphics_handle ("text", __myhandle__, false);
+  zlabel = gh_manager::make_graphics_handle ("text", __myhandle__, false);
+  title = gh_manager::make_graphics_handle ("text", __myhandle__, false);
+
+  xset (xlabel.handle_value (), "handlevisibility", "off");
+  xset (ylabel.handle_value (), "handlevisibility", "off");
+  xset (zlabel.handle_value (), "handlevisibility", "off");
+  xset (title.handle_value (), "handlevisibility", "off");
+
+  xset (xlabel.handle_value (), "horizontalalignment", "center");
+  xset (ylabel.handle_value (), "horizontalalignment", "center");
+  xset (zlabel.handle_value (), "horizontalalignment", "right");
+  xset (title.handle_value (), "horizontalalignment", "center");
+
+  xset (xlabel.handle_value (), "verticalalignment", "cap");
+  xset (ylabel.handle_value (), "verticalalignment", "bottom");
+  xset (title.handle_value (), "verticalalignment", "bottom");
+
+  xset (ylabel.handle_value (), "rotation", 90.0);
+
+  adopt (xlabel.handle_value ());
+  adopt (ylabel.handle_value ());
+  adopt (zlabel.handle_value ());
+  adopt (title.handle_value ());
+
+  update_transform ();
+
+  override_defaults (obj);
+}
+
+void
+axes::properties::delete_text_child (handle_property& hp)
+{
+  graphics_handle h = hp.handle_value ();
+
+  if (h.ok ())
+    {
+      graphics_object go = gh_manager::get_object (h);
+
+      if (go.valid_object ())
+	gh_manager::free (h);
+
+      base_properties::remove_child (h);
+    }
+
+  // FIXME -- is it necessary to check whether the axes object is
+  // being deleted now?  I think this function is only called when an
+  // individual child object is delete and not when the parent axes
+  // object is deleted.
+
+  if (! is_beingdeleted ())
+    {
+      hp = gh_manager::make_graphics_handle ("text", __myhandle__, false);
+
+      xset (hp.handle_value (), "handlevisibility", "off");
+
+      adopt (hp.handle_value ());
+    }
+}
+
+void
+axes::properties::remove_child (const graphics_handle& h)
+{
+  if (xlabel.handle_value ().ok () && h == xlabel.handle_value ())
+    delete_text_child (xlabel);
+  else if (ylabel.handle_value ().ok () && h == ylabel.handle_value ())
+    delete_text_child (ylabel);
+  else if (zlabel.handle_value ().ok () && h == zlabel.handle_value ())
+    delete_text_child (zlabel);
+  else if (title.handle_value ().ok () && h == title.handle_value ())
+    delete_text_child (title);
+  else
+    base_properties::remove_child (h);
+}
+
+Matrix
+base_properties::get_children (void) const
+{
+  Matrix retval = children;
+  
+  graphics_object go = gh_manager::get_object (0);
+
+  root_figure::properties& props =
+      dynamic_cast<root_figure::properties&> (go.get_properties ());
+
+  if (! props.is_showhiddenhandles ())
+    {
+      octave_idx_type k = 0;
+
+      for (octave_idx_type i = 0; i < children.numel (); i++)
+	{
+	  graphics_handle kid = children (i);
+
+	  if (gh_manager::is_handle_visible (kid))
+	    retval(k++) = children(i);
+	}
+
+      retval.resize (k, 1);
+    }
+
+  return retval;;
+}
+
+inline Matrix
+xform_matrix (void)
+{
+  Matrix m (4, 4, 0.0);
+  for (int i = 0; i < 4; i++)
+    m(i,i) = 1;
+  return m;
+}
+
+inline ColumnVector
+xform_vector (void)
+{
+  ColumnVector v (4, 0.0);
+  v(3) = 1;
+  return v;
+}
+
+inline ColumnVector
+xform_vector (double x, double y, double z)
+{
+  ColumnVector v (4, 1.0);
+  v(0) = x; v(1) = y; v(2) = z;
+  return v;
+}
+
+inline ColumnVector
+transform (const Matrix& m, double x, double y, double z)
+{
+  return (m * xform_vector (x, y, z));
+}
+
+inline Matrix
+xform_scale (double x, double y, double z)
+{
+  Matrix m (4, 4, 0.0);
+  m(0,0) = x; m(1,1) = y; m(2,2) = z; m(3,3) = 1;
+  return m;
+}
+
+inline Matrix
+xform_translate (double x, double y, double z)
+{
+  Matrix m = xform_matrix ();
+  m(0,3) = x; m(1,3) = y; m(2,3) = z; m(3,3) = 1;
+  return m;
+}
+
+inline void
+scale (Matrix& m, double x, double y, double z)
+{
+  m = m * xform_scale (x, y, z);
+}
+
+inline void
+translate (Matrix& m, double x, double y, double z)
+{
+  m = m * xform_translate (x, y, z);
+}
+
+inline void
+xform (ColumnVector& v, const Matrix& m)
+{
+  v = m*v;
+}
+
+inline void
+scale (ColumnVector& v, double x, double y, double z)
+{
+  v(0) *= x;
+  v(1) *= y;
+  v(2) *= z;
+}
+
+inline void
+translate (ColumnVector& v, double x, double y, double z)
+{
+  v(0) += x;
+  v(1) += y;
+  v(2) += z;
+}
+
+inline void
+normalize (ColumnVector& v)
+{
+  double fact = 1.0/sqrt(v(0)*v(0)+v(1)*v(1)+v(2)*v(2));
+  scale (v, fact, fact, fact);
+}
+
+inline double
+dot (const ColumnVector& v1, const ColumnVector& v2)
+{
+  return (v1(0)*v2(0)+v1(1)*v2(1)+v1(2)*v2(2));
+}
+
+inline double
+norm (const ColumnVector& v)
+{
+  return sqrt (dot (v, v));
+}
+
+inline ColumnVector
+cross (const ColumnVector& v1, const ColumnVector& v2)
+{
+  ColumnVector r = xform_vector ();
+  r(0) = v1(1)*v2(2)-v1(2)*v2(1);
+  r(1) = v1(2)*v2(0)-v1(0)*v2(2);
+  r(2) = v1(0)*v2(1)-v1(1)*v2(0);
+  return r;
+}
+
+inline Matrix
+unit_cube (void)
+{
+  static double data[32] = {
+      0,0,0,1,
+      1,0,0,1,
+      0,1,0,1,
+      0,0,1,1,
+      1,1,0,1,
+      1,0,1,1,
+      0,1,1,1,
+      1,1,1,1};
+  Matrix m (4, 8);
+  memcpy (m.fortran_vec (), data, sizeof(double)*32);
+  return m;
+}
+
+inline ColumnVector
+cam2xform (const Array<double>& m)
+{
+  ColumnVector retval (4, 1.0);
+  memcpy (retval.fortran_vec (), m.fortran_vec (), sizeof(double)*3);
+  return retval;
+}
+
+inline RowVector
+xform2cam (const ColumnVector& v)
+{
+  return v.extract_n (0, 3).transpose ();
+}
+
+void
+axes::properties::update_camera (void)
+{
+  double xd = (xdir_is ("normal") ? 1 : -1);
+  double yd = (ydir_is ("normal") ? 1 : -1);
+  double zd = (zdir_is ("normal") ? 1 : -1);
+
+  Matrix xlimits = sx.scale (get_xlim ().matrix_value ());
+  Matrix ylimits = sy.scale (get_ylim ().matrix_value ());
+  Matrix zlimits = sz.scale (get_zlim ().matrix_value ());
+
+  double xo = xlimits(xd > 0 ? 0 : 1);
+  double yo = ylimits(yd > 0 ? 0 : 1);
+  double zo = zlimits(zd > 0 ? 0 : 1);
+  
+  Matrix pb  = get_plotboxaspectratio ().matrix_value ();
+  
+  bool autocam = (camerapositionmode_is ("auto")
+		  && cameratargetmode_is ("auto")
+	    	  && cameraupvectormode_is ("auto")
+		  && cameraviewanglemode_is ("auto"));
+  bool dowarp = (autocam && dataaspectratiomode_is("auto")
+		 && plotboxaspectratiomode_is ("auto"));
+
+  ColumnVector c_eye (xform_vector ());
+  ColumnVector c_center (xform_vector ());
+  ColumnVector c_upv (xform_vector ());
+  
+  if (cameratargetmode_is ("auto"))
+    {
+      c_center(0) = (xlimits(0)+xlimits(1))/2;
+      c_center(1) = (ylimits(0)+ylimits(1))/2;
+      c_center(2) = (zlimits(0)+zlimits(1))/2;
+
+      cameratarget = xform2cam (c_center);
+    }
+  else
+    c_center = cam2xform (get_cameratarget ().matrix_value ());
+  
+  if (camerapositionmode_is ("auto"))
+    {
+      Matrix tview = get_view ().matrix_value ();
+      double az = tview(0), el = tview(1);
+      double d = 5*sqrt(pb(0)*pb(0)+pb(1)*pb(1)+pb(2)*pb(2));
+
+      if (el == 90 || el == -90)
+	c_eye(2) = d*signum(el);
+      else
+	{
+	  az *= M_PI/180.0;
+	  el *= M_PI/180.0;
+	  c_eye(0) = d*cos(el)*sin(az);
+	  c_eye(1) = -d*cos(el)*cos(az);
+	  c_eye(2) = d*sin(el);
+	}
+      c_eye(0) = c_eye(0)*(xlimits(1)-xlimits(0))/(xd*pb(0))+c_center(0);
+      c_eye(1) = c_eye(1)*(ylimits(1)-ylimits(0))/(yd*pb(1))+c_center(1);
+      c_eye(2) = c_eye(2)*(zlimits(1)-zlimits(0))/(zd*pb(2))+c_center(2);
+
+      cameraposition = xform2cam (c_eye);
+    }
+  else
+    c_eye = cam2xform (get_cameraposition ().matrix_value ());
+
+  if (cameraupvectormode_is ("auto"))
+    {
+      Matrix tview = get_view ().matrix_value ();
+      double az = tview(0), el = tview(1);
+
+      if (el == 90 || el == -90)
+	{
+	  c_upv(0) = -sin(az*M_PI/180.0)*(xlimits(1)-xlimits(0))/pb(0);
+	  c_upv(1) = cos(az*M_PI/180.0)*(ylimits(1)-ylimits(0))/pb(1);
+	}
+      else
+	c_upv(2) = 1;
+
+      cameraupvector = xform2cam (c_upv);
+    }
+  else
+    c_upv = cam2xform (get_cameraupvector ().matrix_value ());
+
+  Matrix x_view = xform_matrix ();
+  Matrix x_projection = xform_matrix ();
+  Matrix x_viewport = xform_matrix ();
+  Matrix x_normrender = xform_matrix ();
+  Matrix x_pre = xform_matrix ();
+  
+  x_render = xform_matrix ();
+  x_render_inv = xform_matrix ();
+
+  scale (x_pre, pb(0), pb(1), pb(2));
+  translate (x_pre, -0.5, -0.5, -0.5);
+  scale (x_pre, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
+	 zd/(zlimits(1)-zlimits(0)));
+  translate (x_pre, -xo, -yo, -zo);
+
+  xform (c_eye, x_pre);
+  xform (c_center, x_pre);
+  scale (c_upv, pb(0)/(xlimits(1)-xlimits(0)), pb(1)/(ylimits(1)-ylimits(0)), 
+	 pb(2)/(zlimits(1)-zlimits(0)));
+  translate (c_center, -c_eye(0), -c_eye(1), -c_eye(2));
+
+  ColumnVector F (c_center), f (F), UP (c_upv);
+  normalize (f);
+  normalize (UP);
+
+  if (std::abs (dot (f, UP)) > 1e-15)
+    {
+      double fa = 1/sqrt(1-f(2)*f(2));
+      scale (UP, fa, fa, fa);
+    }
+
+  ColumnVector s = cross (f, UP);
+  ColumnVector u = cross (s, f);
+
+  scale (x_view, 1, 1, -1);
+  Matrix l = xform_matrix ();
+  l(0,0) = s(0); l(0,1) = s(1); l(0,2) = s(2);
+  l(1,0) = u(0); l(1,1) = u(1); l(1,2) = u(2);
+  l(2,0) = -f(0); l(2,1) = -f(1); l(2,2) = -f(2);
+  x_view = x_view * l;
+  translate (x_view, -c_eye(0), -c_eye(1), -c_eye(2));
+  scale (x_view, pb(0), pb(1), pb(2));
+  translate (x_view, -0.5, -0.5, -0.5);
+
+  Matrix x_cube = x_view * unit_cube ();
+  ColumnVector cmin = x_cube.row_min (), cmax = x_cube.row_max ();
+  double xM = cmax(0)-cmin(0);
+  double yM = cmax(1)-cmin(1);
+
+  Matrix bb = get_boundingbox (true);
+
+  double v_angle;
+
+  if (cameraviewanglemode_is ("auto"))
+    {
+      double af;
+
+      // FIXME -- was this really needed?  When compared to Matlab, it
+      // does not seem to be required. Need investigation with concrete
+      // backend to see results visually.
+      if (false && dowarp)
+        af = 1.0 / (xM > yM ? xM : yM);
+      else
+        {
+          if ((bb(2)/bb(3)) > (xM/yM))
+            af = 1.0 / yM;
+          else
+            af = 1.0 / xM;
+        }
+      v_angle = 2 * (180.0 / M_PI) * atan (1 / (2 * af * norm (F)));
+
+      cameraviewangle = v_angle;
+    }
+  else
+    v_angle = get_cameraviewangle ();
+
+  double pf = 1 / (2 * tan ((v_angle / 2) * M_PI / 180.0) * norm (F));
+  scale (x_projection, pf, pf, 1);
+
+  if (dowarp)
+    {
+      xM *= pf;
+      yM *= pf;
+      translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
+      scale (x_viewport, bb(2)/xM, -bb(3)/yM, 1);
+    }
+  else
+    {
+      double pix = 1;
+      if (autocam)
+	{
+	  if ((bb(2)/bb(3)) > (xM/yM))
+	    pix = bb(3);
+	  else
+	    pix = bb(2);
+	}
+      else
+	pix = (bb(2) < bb(3) ? bb(2) : bb(3));
+      translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
+      scale (x_viewport, pix, -pix, 1);
+    }
+
+  x_normrender = x_viewport * x_projection * x_view;
+
+  x_cube = x_normrender * unit_cube ();
+  cmin = x_cube.row_min ();
+  cmax = x_cube.row_max ();
+  x_zlim.resize (1, 2);
+  x_zlim(0) = cmin(2);
+  x_zlim(1) = cmax(2);
+
+  x_render = x_normrender;
+  scale (x_render, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
+	 zd/(zlimits(1)-zlimits(0)));
+  translate (x_render, -xo, -yo, -zo);
+
+  x_viewtransform = x_view;
+  x_projectiontransform = x_projection;
+  x_viewporttransform = x_viewport;
+  x_normrendertransform = x_normrender;
+  x_rendertransform = x_render;
+
+  x_render_inv = x_render.inverse ();
+
+  // Note: these matrices are a slight modified version of the regular
+  // matrices, more suited for OpenGL rendering (x_gl_mat1 => light
+  // => x_gl_mat2)
+  x_gl_mat1 = x_view;
+  scale (x_gl_mat1, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
+	 zd/(zlimits(1)-zlimits(0)));
+  translate (x_gl_mat1, -xo, -yo, -zo);
+  x_gl_mat2 = x_viewport * x_projection;
+}
+
+void
+axes::properties::update_aspectratios (void)
+{
+  Matrix xlimits = get_xlim ().matrix_value ();
+  Matrix ylimits = get_ylim ().matrix_value ();
+  Matrix zlimits = get_zlim ().matrix_value ();
+
+  double dx = (xlimits(1)-xlimits(0));
+  double dy = (ylimits(1)-ylimits(0));
+  double dz = (zlimits(1)-zlimits(0));
+
+  if (dataaspectratiomode_is ("auto"))
+    {
+      double dmin = xmin (xmin (dx, dy), dz);
+      Matrix da (1, 3, 0.0);
+
+      da(0) = dx/dmin;
+      da(1) = dy/dmin;
+      da(2) = dz/dmin;
+
+      dataaspectratio = da;
+    }
+
+  if (plotboxaspectratiomode_is ("auto"))
+    {
+      if (dataaspectratiomode_is ("auto"))
+	plotboxaspectratio = Matrix (1, 3, 1.0);
+      else
+	{
+	  Matrix da = get_dataaspectratio ().matrix_value ();
+	  Matrix pba (1, 3, 0.0);
+
+	  pba(0) = dx/da(0);
+	  pba(1) = dy/da(1);
+	  pba(2) = dz/da(2);
+	}
+    }
+  
+  // FIXME -- if plotboxaspectratiomode is "manual", limits
+  // and/or dataaspectratio might be adapted.
+}
+
+// The INTERNAL flag defines whether position or outerposition is used.
+
+Matrix
+axes::properties::get_boundingbox (bool internal) const
+{
+  graphics_object obj = gh_manager::get_object (get_parent ());
+  Matrix parent_bb = obj.get_properties ().get_boundingbox (true);
+  Matrix pos = (internal ?
+		  get_position ().matrix_value ()
+		  : get_outerposition ().matrix_value ());
+
+
+  pos = convert_position (pos, get_units (), "pixels",
+			  parent_bb.extract_n (0, 2, 1, 2));
+  pos(0)--;
+  pos(1)--;
+  pos(1) = parent_bb(3) - pos(1) - pos(3);
+
+  return pos;
+}
+
+ColumnVector
+graphics_xform::xform_vector (double x, double y, double z)
+{
+  return ::xform_vector (x, y, z);
+}
+
+Matrix
+graphics_xform::xform_eye (void)
+{
+  return ::xform_matrix ();
+}
+
+ColumnVector
+graphics_xform::transform (double x, double y, double z,
+			   bool use_scale) const
+{
+  if (use_scale)
+    {
+      x = sx.scale (x);
+      y = sy.scale (y);
+      z = sz.scale (z);
+    }
+
+  return ::transform (xform, x, y, z);
+}
+
+ColumnVector
+graphics_xform::untransform (double x, double y, double z,
+			     bool use_scale) const
+{
+  ColumnVector v = ::transform (xform_inv, x, y, z);
+
+  if (use_scale)
+    {
+      v(0) = sx.unscale (v(0));
+      v(1) = sy.unscale (v(1));
+      v(2) = sz.unscale (v(2));
+    }
+
+  return v;
+}
+
+octave_value
+axes::get_default (const caseless_str& name) const
+{
+  octave_value retval = default_properties.lookup (name);
+
+  if (retval.is_undefined ())
+    {
+      graphics_handle parent = get_parent ();
+      graphics_object parent_obj = gh_manager::get_object (parent);
+
+      retval = parent_obj.get_default (name);
+    }
+
+  return retval;
+}
+
+// FIXME -- remove.
+// FIXME -- maybe this should go into array_property class?
+/*
+static void
+check_limit_vals (double& min_val, double& max_val, double& min_pos,
+		  const array_property& data)
+{
+  double val = data.min_val ();
+  if (! (xisinf (val) || xisnan (val)) && val < min_val)
+    min_val = val;
+  val = data.max_val ();
+  if (! (xisinf (val) || xisnan (val)) && val > max_val)
+    max_val = val;
+  val = data.min_pos ();
+  if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos)
+    min_pos = val;
+}
+*/
+
+static void
+check_limit_vals (double& min_val, double& max_val, double& min_pos,
+		  const octave_value& data)
+{
+  if (data.is_matrix_type ())
+    {
+      Matrix m = data.matrix_value ();
+
+      if (! error_state && m.numel () == 3)
+	{
+	  double val;
+
+	  val = m(0);
+	  if (! (xisinf (val) || xisnan (val)) && val < min_val)
+	    min_val = val;
+
+	  val = m(1);
+	  if (! (xisinf (val) || xisnan (val)) && val > max_val)
+	    max_val = val;
+
+	  val = m(2);
+	  if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos)
+	    min_pos = val;
+	}
+    }
+}
+
+// magform(x) Returns (a, b), where x = a * 10^b, a >= 1., and b is
+// integral.
+
+static void
+magform (double x, double& a, int& b)
+{
+  if (x == 0)
+    {
+      a = 0;
+      b = 0;
+    }
+  else
+    {
+      double l = std::log10 (std::abs (x));
+      double r = std::fmod (l, 1.);
+      a = std::pow (10.0, r);
+      b = static_cast<int> (l-r);
+      if (a < 1)
+	{
+	  a *= 10;
+	  b -= 1;
+	}
+
+      if (x < 0)
+	a = -a;
+    }
+}
+
+// A translation from Tom Holoryd's python code at
+// http://kurage.nimh.nih.gov/tomh/tics.py
+// FIXME -- add log ticks
+
+double
+axes::properties::calc_tick_sep (double lo, double hi)
+{
+  int ticint = 5;
+
+  // Reference: Lewart, C. R., "Algorithms SCALE1, SCALE2, and
+  // SCALE3 for Determination of Scales on Computer Generated
+  // Plots", Communications of the ACM, 10 (1973), 639-640.
+  // Also cited as ACM Algorithm 463.
+
+  double a;
+  int b, x;
+
+  magform ((hi-lo)/ticint, a, b);
+
+  static const double sqrt_2 = sqrt (2.0);
+  static const double sqrt_10 = sqrt (10.0);
+  static const double sqrt_50 = sqrt (50.0);
+
+  if (a < sqrt_2)
+    x = 1;
+  else if (a < sqrt_10)
+    x = 2;
+  else if (a < sqrt_50)
+    x = 5;
+  else
+    x = 10;
+
+  return x * std::pow (10., b);
+
+}
+
+// Attempt to make "nice" limits from the actual max and min of the
+// data.  For log plots, we will also use the smallest strictly positive
+// value.
+
+Matrix
+axes::properties::get_axis_limits (double xmin, double xmax,
+				   double min_pos, bool logscale)
+{
+  Matrix retval;
+
+  double min_val = xmin;
+  double max_val = xmax;
+
+  if (! (xisinf (min_val) || xisinf (max_val)))
+    {
+      if (logscale)
+	{
+	  if (xisinf (min_pos))
+	    {
+	      // warning ("axis: logscale with no positive values to plot");
+	      return retval;
+	    }
+
+	  if (min_val <= 0)
+	    {
+	      warning ("axis: omitting nonpositive data in log plot");
+	      min_val = min_pos;
+	    }
+	  // FIXME -- maybe this test should also be relative?
+	  if (std::abs (min_val - max_val) < sqrt (DBL_EPSILON))
+	    {
+	      min_val *= 0.9;
+	      max_val *= 1.1;
+	    }
+	  min_val = pow (10, floor (log10 (min_val)));
+	  max_val = pow (10, ceil (log10 (max_val)));
+	}
+      else
+	{
+	  if (min_val == 0 && max_val == 0)
+	    {
+	      min_val = -1;
+	      max_val = 1;
+	    }
+	  // FIXME -- maybe this test should also be relative?
+	  else if (std::abs (min_val - max_val) < sqrt (DBL_EPSILON))
+	    {
+	      min_val -= 0.1 * std::abs (min_val);
+	      max_val += 0.1 * std::abs (max_val);
+	    }
+
+	  double tick_sep = calc_tick_sep (min_val , max_val);
+	  min_val = tick_sep * std::floor (min_val / tick_sep);
+	  max_val = tick_sep * ceil (max_val / tick_sep);
+	}
+    }
+
+  retval.resize (1, 2);
+
+  retval(0) = min_val;
+  retval(1) = max_val;
+
+  return retval;
+}
+
+void 
+axes::properties::calc_ticks_and_lims (array_property& lims,
+				       array_property& ticks,
+				       bool limmode_is_auto, bool is_logscale)
+{
+  // FIXME -- add log ticks and lims
+
+  if (lims.get ().is_empty ())
+    return;
+
+  double lo = (lims.get ().matrix_value ()) (0);
+  double hi = (lims.get ().matrix_value ()) (1);
+  // FIXME should this be checked for somewhere else? (i.e. set{x,y,z}lim)
+  if (hi < lo) 
+    {
+      double tmp = hi;
+      hi = lo;
+      lo = tmp;
+    }
+
+  if (is_logscale)
+    {
+      // FIXME we should check for negtives here
+      hi = std::log10 (hi);
+      lo = std::log10 (lo);
+    }
+
+  double tick_sep = calc_tick_sep (lo , hi);
+
+  int i1 = static_cast<int> (std::floor (lo / tick_sep));
+  int i2 = static_cast<int> (std::ceil (hi / tick_sep));
+
+  if (limmode_is_auto)
+    {
+      // adjust limits to include min and max tics
+      Matrix tmp_lims (1,2);
+      tmp_lims(0) = tick_sep * i1;
+      tmp_lims(1) = tick_sep * i2;
+
+      if (is_logscale) 
+	{
+	  tmp_lims(0) = std::pow (10.,tmp_lims(0));
+	  tmp_lims(1) = std::pow (10.,tmp_lims(1));
+	}
+      lims = tmp_lims;
+    }
+  else
+    {
+      // adjust min and max tics if they are out of limits
+      i1 = static_cast<int> (std::ceil (lo / tick_sep));
+      i2 = static_cast<int> (std::floor (hi / tick_sep));
+    }
+      
+  Matrix tmp_ticks (1, i2-i1+1);
+  for (int i = 0; i <= i2-i1; i++) 
+    {
+      tmp_ticks (i) = tick_sep * (i+i1);
+      if (is_logscale)
+	tmp_ticks (i) = std::pow (10., tmp_ticks (i));
+    }
+
+  ticks = tmp_ticks;
+}
+
+static void
+get_children_limits (double& min_val, double& max_val, double& min_pos,
+		     const Matrix& kids, char limit_type)
+{
+  octave_idx_type n = kids.numel ();
+
+  switch (limit_type)
+    {
+    case 'x':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_xliminclude ())
+	    {
+	      octave_value lim = obj.get_xlim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+
+    case 'y':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_yliminclude ())
+	    {
+	      octave_value lim = obj.get_ylim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+    
+    case 'z':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_zliminclude ())
+	    {
+	      octave_value lim = obj.get_zlim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+    
+    case 'c':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_climinclude ())
+	    {
+	      octave_value lim = obj.get_clim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+    
+    case 'a':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_aliminclude ())
+	    {
+	      octave_value lim = obj.get_alim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+
+    default:
+      break;
+    }
+}
+
+static bool updating_axis_limits = false;
+
+void
+axes::update_axis_limits (const std::string& axis_type)
+{
+  if (updating_axis_limits)
+    return;
+
+  Matrix kids = xproperties.get_children ();
+
+  double min_val = octave_Inf;
+  double max_val = -octave_Inf;
+  double min_pos = octave_Inf;
+
+  char update_type = 0;
+
+  Matrix limits;
+
+  if (axis_type == "xdata" || axis_type == "xscale"
+      || axis_type == "xldata" || axis_type == "xudata"
+      || axis_type == "xlimmode" || axis_type == "xliminclude"
+      || axis_type == "xlim")
+    {
+      if (xproperties.xlimmode_is ("auto"))
+	{
+	  get_children_limits (min_val, max_val, min_pos, kids, 'x');
+	  
+	  limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
+						xproperties.xscale_is ("log"));
+
+	  update_type = 'x';
+	}
+    }
+  else if (axis_type == "ydata" || axis_type == "yscale"
+	   || axis_type == "ldata" || axis_type == "udata"
+	   || axis_type == "ylimmode" || axis_type == "yliminclude"
+	   || axis_type == "ylim")
+    {
+      if (xproperties.ylimmode_is ("auto"))
+	{
+	  get_children_limits (min_val, max_val, min_pos, kids, 'y');
+
+	  limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
+						xproperties.yscale_is ("log"));
+
+	  update_type = 'y';
+	}
+    }
+  else if (axis_type == "zdata" || axis_type == "zscale"
+	   || axis_type == "zlimmode" || axis_type == "zliminclude"
+	   || axis_type == "zlim")
+    {
+      if (xproperties.zlimmode_is ("auto"))
+	{
+	  get_children_limits (min_val, max_val, min_pos, kids, 'z');
+
+	  limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
+						xproperties.zscale_is ("log"));
+
+	  update_type = 'z';
+	}
+    }
+  else if (axis_type == "cdata" || axis_type == "climmode"
+	   || axis_type == "cdatamapping" || axis_type == "climinclude"
+	   || axis_type == "clim")
+    {
+      if (xproperties.climmode_is ("auto"))
+	{
+	  get_children_limits (min_val, max_val, min_pos, kids, 'c');
+
+	  if (min_val > max_val)
+	    {
+	      min_val = min_pos = 0;
+	      max_val = 1;
+	    }
+	  else if (min_val == max_val)
+	    max_val = min_val + 1;
+
+	  limits.resize (1, 2);
+
+	  limits(0) = min_val;
+	  limits(1) = max_val;
+
+	  update_type = 'c';
+	}
+
+    }
+  else if (axis_type == "alphadata" || axis_type == "alimmode"
+	   || axis_type == "alphadatamapping" || axis_type == "aliminclude"
+	   || axis_type == "alim")
+    {
+      if (xproperties.alimmode_is ("auto"))
+	{
+	  get_children_limits (min_val, max_val, min_pos, kids, 'a');
+
+	  if (min_val > max_val)
+	    {
+	      min_val = min_pos = 0;
+	      max_val = 1;
+	    }
+	  else if (min_val == max_val)
+	    max_val = min_val + 1;
+
+	  limits.resize (1, 2);
+
+	  limits(0) = min_val;
+	  limits(1) = max_val;
+
+	  update_type = 'a';
+	}
+
+    }
+
+  unwind_protect_bool (updating_axis_limits);
+  updating_axis_limits = true;
+
+  switch (update_type)
+    {
+    case 'x':
+      xproperties.set_xlim (limits);
+      xproperties.set_xlimmode ("auto");
+      xproperties.update_xlim ();
+      break;
+
+    case 'y':
+      xproperties.set_ylim (limits);
+      xproperties.set_ylimmode ("auto");
+      xproperties.update_ylim ();
+      break;
+
+    case 'z':
+      xproperties.set_zlim (limits);
+      xproperties.set_zlimmode ("auto");
+      xproperties.update_zlim ();
+      break;
+
+    case 'c':
+      xproperties.set_clim (limits);
+      xproperties.set_climmode ("auto");
+      break;
+
+    case 'a':
+      xproperties.set_alim (limits);
+      xproperties.set_alimmode ("auto");
+      break;
+
+    default:
+      break;
+    }
+
+  xproperties.update_transform ();
+
+  unwind_protect::run ();
+}
+
+void
+axes::properties::zoom (const Matrix& xl, const Matrix& yl)
+{
+  zoom_stack.push_front (xlimmode.get ());
+  zoom_stack.push_front (xlim.get ());
+  zoom_stack.push_front (ylimmode.get ());
+  zoom_stack.push_front (ylim.get ());
+
+  xlim = xl;
+  xlimmode = "manual";
+  ylim = yl;
+  ylimmode = "manual";
+
+  update_transform ();
+  update_xlim (false);
+  update_ylim (false);
+}
+
+void
+axes::properties::unzoom (void)
+{
+  if (zoom_stack.size () >= 4)
+    {
+      ylim = zoom_stack.front ();
+      zoom_stack.pop_front ();
+      ylimmode = zoom_stack.front ();
+      zoom_stack.pop_front ();
+      xlim = zoom_stack.front ();
+      zoom_stack.pop_front ();
+      xlimmode = zoom_stack.front ();
+      zoom_stack.pop_front ();
+
+      update_transform ();
+      update_xlim (false);
+      update_ylim (false);
+    }
+}
+
+void
+axes::properties::clear_zoom_stack (void)
+{
+  while (zoom_stack.size () > 4)
+    zoom_stack.pop_front ();
+
+  unzoom ();
+}
+
+// ---------------------------------------------------------------------
+
+Matrix
+line::properties::compute_xlim (void) const
+{
+  Matrix m (1, 3);
+
+  m(0) = xmin (xdata.min_val (), xmin (xldata.min_val (), xudata.min_val ()));
+  m(1) = xmax (xdata.max_val (), xmax (xldata.max_val (), xudata.max_val ()));
+  m(2) = xmin (xdata.min_pos (), xmin (xldata.min_pos (), xudata.min_pos ()));
+
+  return m;
+}
+
+Matrix
+line::properties::compute_ylim (void) const
+{
+  Matrix m (1, 3);
+
+  m(0) = xmin (ydata.min_val (), xmin (ldata.min_val (), udata.min_val ()));
+  m(1) = xmax (ydata.max_val (), xmax (ldata.max_val (), udata.max_val ()));
+  m(2) = xmin (ydata.min_pos (), xmin (ldata.min_pos (), udata.min_pos ()));
+
+  return m;
+}
+
+// ---------------------------------------------------------------------
+
+// Note: "text" code is entirely auto-generated
+
+// ---------------------------------------------------------------------
+
+// Note: "image" code is entirely auto-generated
+
+// ---------------------------------------------------------------------
+
+octave_value
+patch::properties::get_color_data (void) const
+{
+  return convert_cdata (*this, get_facevertexcdata (),
+			cdatamapping_is ("scaled"), 2);
+}
+
+// ---------------------------------------------------------------------
+
+octave_value
+surface::properties::get_color_data (void) const
+{
+  return convert_cdata (*this, get_cdata (), cdatamapping_is ("scaled"), 3);
+}
+
+inline void
+cross_product (double x1, double y1, double z1,
+	       double x2, double y2, double z2,
+	       double& x, double& y, double& z)
+{
+  x += (y1 * z2 - z1 * y2);
+  y += (z1 * x2 - x1 * z2);
+  z += (x1 * y2 - y1 * x2);
+}
+
+void
+surface::properties::update_normals (void)
+{
+  if (normalmode_is ("auto"))
+    {
+      Matrix x = get_xdata ().matrix_value ();
+      Matrix y = get_ydata ().matrix_value ();
+      Matrix z = get_zdata ().matrix_value ();
+
+
+      int p = z.columns (), q = z.rows ();
+      int i1 = 0, i2 = 0, i3 = 0;
+      int j1 = 0, j2 = 0, j3 = 0;
+
+      bool x_mat = (x.rows () == q);
+      bool y_mat = (y.columns () == p);
+
+      NDArray n (dim_vector (q, p, 3), 0.0);
+
+      for (int i = 0; i < p; i++)
+	{
+	  if (y_mat)
+	    {
+	      i1 = i - 1;
+	      i2 = i;
+	      i3 = i + 1;
+	    }
+
+	  for (int j = 0; j < q; j++)
+	    {
+	      if (x_mat)
+		{
+		  j1 = j - 1;
+		  j2 = j;
+		  j3 = j + 1;
+		}
+
+	      double& nx = n(j, i, 0);
+	      double& ny = n(j, i, 1);
+	      double& nz = n(j, i, 2);
+
+              if ((j > 0) && (i > 0))
+                  // upper left quadrangle
+	          cross_product (x(j1,i-1)-x(j2,i), y(j-1,i1)-y(j,i2), z(j-1,i-1)-z(j,i),
+		                 x(j2,i-1)-x(j1,i), y(j,i1)-y(j-1,i2), z(j,i-1)-z(j-1,i),
+			         nx, ny, nz);
+
+              if ((j > 0) && (i < (p -1)))
+                  // upper right quadrangle
+                  cross_product (x(j1,i+1)-x(j2,i), y(j-1,i3)-y(j,i2), z(j-1,i+1)-z(j,i),
+		                 x(j1,i)-x(j2,i+1), y(j-1,i2)-y(j,i3), z(j-1,i)-z(j,i+1),
+			         nx, ny, nz);
+
+              if ((j < (q - 1)) && (i > 0))
+                  // lower left quadrangle
+                  cross_product (x(j2,i-1)-x(j3,i), y(j,i1)-y(j+1,i2), z(j,i-1)-z(j+1,i),
+		                 x(j3,i-1)-x(j2,i), y(j+1,i1)-y(j,i2), z(j+1,i-1)-z(j,i),
+			         nx, ny, nz);
+
+              if ((j < (q - 1)) && (i < (p -1)))
+                  // lower right quadrangle
+	          cross_product (x(j3,i)-x(j2,i+1), y(j+1,i2)-y(j,i3), z(j+1,i)-z(j,i+1),
+                                 x(j3,i+1)-x(j2,i), y(j+1,i3)-y(j,i2), z(j+1,i+1)-z(j,i),
+			         nx, ny, nz);
+
+              double d = - std::max(std::max(fabs(nx), fabs(ny)), fabs(nz));
+
+	      nx /= d;
+	      ny /= d;
+	      nz /= d;
+	    }
+	}
+      vertexnormals = n;
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void
+hggroup::update_axis_limits (const std::string& axis_type)
+{
+  Matrix kids = xproperties.get_children ();
+
+  double min_val = octave_Inf;
+  double max_val = -octave_Inf;
+  double min_pos = octave_Inf;
+
+  char update_type = 0;
+
+  if (axis_type == "xlim" || axis_type == "xliminclude")
+    {
+      get_children_limits (min_val, max_val, min_pos, kids, 'x');
+      
+      update_type = 'x';
+    }
+  else if (axis_type == "ylim" || axis_type == "yliminclude")
+    {
+      get_children_limits (min_val, max_val, min_pos, kids, 'y');
+
+      update_type = 'y';
+    }
+  else if (axis_type == "zlim" || axis_type == "zliminclude")
+    {
+      get_children_limits (min_val, max_val, min_pos, kids, 'z');
+
+      update_type = 'z';
+    }
+  else if (axis_type == "clim" || axis_type == "climinclude")
+    {
+      get_children_limits (min_val, max_val, min_pos, kids, 'c');
+
+      update_type = 'c';
+
+    }
+  else if (axis_type == "alim" || axis_type == "aliminclude")
+    {
+      get_children_limits (min_val, max_val, min_pos, kids, 'a');
+
+      update_type = 'a';
+    }
+
+  Matrix limits (1, 3, 0.0);
+
+  limits(0) = min_val;
+  limits(1) = max_val;
+  limits(2) = min_pos;
+
+  switch (update_type)
+    {
+    case 'x':
+      xproperties.set_xlim (limits);
+      break;
+
+    case 'y':
+      xproperties.set_ylim (limits);
+      break;
+
+    case 'z':
+      xproperties.set_zlim (limits);
+      break;
+
+    case 'c':
+      xproperties.set_clim (limits);
+      break;
+
+    case 'a':
+      xproperties.set_alim (limits);
+      break;
+
+    default:
+      break;
+    }
+
+  base_graphics_object::update_axis_limits (axis_type);
+}
+
+// ---------------------------------------------------------------------
+
+octave_value
+base_graphics_object::get_default (const caseless_str& name) const
+{
+  graphics_handle parent = get_parent ();
+  graphics_object parent_obj = gh_manager::get_object (parent);
+
+  return parent_obj.get_default (type () + name);
+}
+
+octave_value
+base_graphics_object::get_factory_default (const caseless_str& name) const
+{
+  graphics_object parent_obj = gh_manager::get_object (0);
+
+  return parent_obj.get_factory_default (type () + name);
+}
+
+// We use a random value for the handle to avoid issues with plots and
+// scalar values for the first argument.
+gh_manager::gh_manager (void)
+  : handle_map (), handle_free_list (),
+    next_handle (-1.0 - (rand () + 1.0) / (RAND_MAX + 2.0))
+{
+  handle_map[0] = graphics_object (new root_figure ());
+
+  // Make sure the default backend is registered.
+  graphics_backend::default_backend ();
+}
+
+graphics_handle
+gh_manager::do_make_graphics_handle (const std::string& go_name,
+				     const graphics_handle& p, bool do_createfcn)
+{
+  graphics_handle h = get_handle (go_name);
+
+  base_graphics_object *go = 0;
+
+  go = make_graphics_object_from_type (go_name, h, p);
+  
+  if (go)
+    {
+      graphics_object obj (go);
+
+      handle_map[h] = obj;
+      if (do_createfcn)
+        go->get_properties ().execute_createfcn ();
+
+      // notify backend
+      graphics_backend backend = go->get_backend ();
+      if (backend)
+        backend.object_created (obj);
+    }
+  else
+    error ("gh_manager::do_make_graphics_handle: invalid object type `%s'",
+	   go_name.c_str ());
+
+  return h;
+}
+
+graphics_handle
+gh_manager::do_make_figure_handle (double val)
+{
+  graphics_handle h = val;
+
+  base_graphics_object* go = new figure (h, 0);
+  graphics_object obj (go);
+
+  handle_map[h] = obj;
+
+  // notify backend
+  graphics_backend backend = go->get_backend ();
+  if (backend)
+    backend.object_created (obj);
+  
+  return h;
+}
+
+void
+gh_manager::do_push_figure (const graphics_handle& h)
+{
+  do_pop_figure (h);
+
+  figure_list.push_front (h);
+}
+
+void
+gh_manager::do_pop_figure (const graphics_handle& h)
+{
+  for (figure_list_iterator p = figure_list.begin ();
+       p != figure_list.end ();
+       p++)
+    {
+      if (*p == h)
+	{
+	  figure_list.erase (p);
+	  break;
+	}
+    }
+}
+
+class
+callback_event : public base_graphics_event
+{
+public:
+  callback_event (const graphics_handle& h, const std::string& name,
+		  const octave_value& data = Matrix ())
+      : base_graphics_event (), handle (h), callback_name (name),
+        callback_data (data) { }
+
+  void execute (void)
+    {
+      gh_manager::execute_callback (handle, callback_name, callback_data);
+    }
+
+private:
+  callback_event (void)
+      : base_graphics_event () { }
+
+private:
+  graphics_handle handle;
+  std::string callback_name;
+  octave_value callback_data;
+};
+
+class
+function_event : public base_graphics_event
+{
+public:
+  function_event (graphics_event::event_fcn fcn, void* data = 0)
+      : base_graphics_event (), function (fcn),
+        function_data (data) { }
+
+  void execute (void)
+    {
+      function (function_data);
+    }
+
+private:
+  function_event (void)
+      : base_graphics_event () { }
+
+private:
+  graphics_event::event_fcn function;
+  void* function_data;
+};
+
+class
+set_event : public base_graphics_event
+{
+public:
+  set_event (const graphics_handle& h, const std::string& name,
+	     const octave_value& value)
+      : base_graphics_event (), handle (h), property_name (name),
+        property_value (value) { }
+
+  void execute (void)
+    {
+      gh_manager::autolock guard;
+
+      xset (handle, property_name, property_value);
+    }
+
+private:
+  set_event (void)
+      : base_graphics_event () { }
+
+private:
+  graphics_handle handle;
+  std::string property_name;
+  octave_value property_value;
+};
+
+graphics_event
+graphics_event::create_callback_event (const graphics_handle& h,
+				       const std::string& name,
+				       const octave_value& data)
+{
+  graphics_event e;
+
+  e.rep = new callback_event (h, name, data);
+
+  return e;
+}
+
+graphics_event
+graphics_event::create_function_event (graphics_event::event_fcn fcn,
+				       void *data)
+{
+  graphics_event e;
+
+  e.rep = new function_event (fcn, data);
+
+  return e;
+}
+
+graphics_event
+graphics_event::create_set_event (const graphics_handle& h,
+				  const std::string& name,
+				  const octave_value& data)
+{
+  graphics_event e;
+
+  e.rep = new set_event (h, name, data);
+
+  return e;
+}
+
+static void
+xset_gcbo (const graphics_handle& h)
+{
+  graphics_object go = gh_manager::get_object (0);
+  root_figure::properties& props =
+      dynamic_cast<root_figure::properties&> (go.get_properties ());
+
+  props.set_callbackobject (h.as_octave_value ());
+}
+
+void
+gh_manager::do_restore_gcbo (void)
+{
+  gh_manager::autolock guard;
+
+  callback_objects.pop_front ();
+
+  xset_gcbo (callback_objects.empty ()
+	     ? graphics_handle ()
+	     : callback_objects.front ().get_handle ());
+}
+
+void
+gh_manager::do_execute_callback (const graphics_handle& h,
+				 const octave_value& cb_arg,
+				 const octave_value& data)
+{
+  octave_value_list args;
+  octave_function *fcn = 0;
+
+  args(0) = h.as_octave_value ();
+  if (data.is_defined ())
+    args(1) = data;
+  else
+    args(1) = Matrix ();
+
+  unwind_protect::begin_frame ("execute_callback");
+  unwind_protect::add (gh_manager::restore_gcbo);
+
+  if (true)
+    {
+      gh_manager::autolock guard;
+  
+      callback_objects.push_front (get_object (h));
+      xset_gcbo (h);
+    }
+
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  // Copy CB because "function_value" method is non-const.
+
+  octave_value cb = cb_arg;
+
+  if (cb.is_function_handle ())
+    fcn = cb.function_value ();
+  else if (cb.is_string ())
+    {
+      int status;
+      std::string s = cb.string_value ();
+
+      eval_string (s, false, status);
+    }
+  else if (cb.is_cell () && cb.length () > 0
+           && (cb.rows () == 1 || cb.columns () == 1)
+           && cb.cell_value ()(0).is_function_handle ())
+    {
+      Cell c = cb.cell_value ();
+
+      fcn = c(0).function_value ();
+      if (! error_state)
+        {
+          for (int i = 1; i < c.length () ; i++)
+            args(1+i) = c(i);
+        }
+    }
+  else
+    {
+      std::string nm = cb.class_name ();
+      error ("trying to execute non-executable object (class = %s)",
+	     nm.c_str ());
+    }
+
+  if (fcn && ! error_state)
+    feval (fcn, args);
+  
+  END_INTERRUPT_WITH_EXCEPTIONS;
+
+  unwind_protect::run_frame ("execute_callback");
+}
+
+void
+gh_manager::do_post_event (const graphics_event& e)
+{
+  event_queue.push_back (e);
+
+  command_editor::add_event_hook (gh_manager::process_events);
+}
+
+void
+gh_manager::do_post_callback (const graphics_handle& h, const std::string name,
+			      const octave_value& data)
+{
+  gh_manager::autolock guard;
+
+  graphics_object go = get_object (h);
+
+  if (go.valid_object ())
+    {
+      if (callback_objects.empty ())
+	do_post_event (graphics_event::create_callback_event (h, name, data));
+      else
+	{
+	  const graphics_object& current = callback_objects.front ();
+
+	  if (current.get_properties ().is_interruptible ())
+	    do_post_event (graphics_event::create_callback_event (h, name, data));
+	  else
+	    {
+	      caseless_str busy_action (go.get_properties ().get_busyaction ());
+
+	      if (busy_action.compare ("queue"))
+		do_post_event (graphics_event::create_callback_event (h, name, data));
+	      else
+		{
+		  caseless_str cname (name);
+
+		  if (cname.compare ("deletefcn")
+		      || cname.compare ("createfcn")
+		      || (go.isa ("figure")
+			  && (cname.compare ("closerequestfcn")
+			      || cname.compare ("resizefcn"))))
+		    do_post_event (graphics_event::create_callback_event (h, name, data));
+		}
+	    }
+	}
+    }
+}
+
+void
+gh_manager::do_post_function (graphics_event::event_fcn fcn, void* fcn_data)
+{
+  gh_manager::autolock guard;
+
+  do_post_event (graphics_event::create_function_event (fcn, fcn_data));
+}
+
+void
+gh_manager::do_post_set (const graphics_handle& h, const std::string name,
+			 const octave_value& value)
+{
+  gh_manager::autolock guard;
+
+  do_post_event (graphics_event::create_set_event (h, name, value));
+}
+
+int
+gh_manager::do_process_events (bool force)
+{
+  graphics_event e;
+
+  do
+    {
+      e = graphics_event ();
+
+      gh_manager::lock ();
+
+      if (! event_queue.empty ())
+	{
+	  if (callback_objects.empty () || force)
+	    {
+	      e = event_queue.front ();
+	      
+	      event_queue.pop_front ();
+	    }
+	  else
+	    {
+	      const graphics_object& go = callback_objects.front ();
+
+	      if (go.get_properties ().is_interruptible ())
+		{
+		  e = event_queue.front ();
+
+		  event_queue.pop_front ();
+		}
+	    }
+	}
+
+      gh_manager::unlock ();
+
+      if (e.ok ())
+	e.execute ();
+    }
+  while (e.ok ());
+
+  gh_manager::lock ();
+
+  if (event_queue.empty ())
+    command_editor::remove_event_hook (gh_manager::process_events);
+
+  gh_manager::unlock ();
+
+  return 0;
+}
+
+property_list::plist_map_type
+root_figure::init_factory_properties (void)
+{
+  property_list::plist_map_type plist_map;
+
+  plist_map["figure"] = figure::properties::factory_defaults ();
+  plist_map["axes"] = axes::properties::factory_defaults ();
+  plist_map["line"] = line::properties::factory_defaults ();
+  plist_map["text"] = text::properties::factory_defaults ();
+  plist_map["image"] = image::properties::factory_defaults ();
+  plist_map["patch"] = patch::properties::factory_defaults ();
+  plist_map["surface"] = surface::properties::factory_defaults ();
+  plist_map["hggroup"] = hggroup::properties::factory_defaults ();
+
+  return plist_map;
+}
+
+// ---------------------------------------------------------------------
+
+DEFUN (ishandle, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ishandle (@var{h})\n\
+Return true if @var{h} is a graphics handle and false otherwise.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = is_handle (args(0));
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (set, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} set (@var{h}, @var{p}, @var{v}, @dots{})\n\
+Set the named property value or vector @var{p} to the value @var{v}\n\
+for the graphics handle @var{h}.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      ColumnVector hcv (args(0).vector_value ());
+
+      if (! error_state)
+        {
+	  bool request_drawnow = false;
+
+          for (octave_idx_type n = 0; n < hcv.length (); n++) 
+            {
+              graphics_object obj = gh_manager::get_object (hcv(n));
+
+              if (obj)
+                {
+                  obj.set (args.splice (0, 1));
+
+                  request_drawnow = true;
+                }
+              else
+		{
+		  error ("set: invalid handle (= %g)", hcv(n));
+		  break;
+		}
+            }
+
+	  if (! error_state && request_drawnow)
+	    Vdrawnow_requested = true;
+        }
+      else
+        error ("set: expecting graphics handle as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (get, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} get (@var{h}, @var{p})\n\
+Return the named property @var{p} from the graphics handle @var{h}.\n\
+If @var{p} is omitted, return the complete property list for @var{h}.\n\
+If @var{h} is a vector, return a cell array including the property\n\
+values or lists respectively.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  Cell vals;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      ColumnVector hcv (args(0).vector_value ());
+
+      if (! error_state)
+        {
+	  octave_idx_type len = hcv.length ();
+
+	  vals.resize (dim_vector (len, 1));
+
+          for (octave_idx_type n = 0; n < len; n++)
+            {
+              graphics_object obj = gh_manager::get_object (hcv(n));
+
+              if (obj)
+                {
+                  if (nargin == 1)
+                    vals(n) = obj.get ();
+                  else
+                    {
+                      caseless_str property = args(1).string_value ();
+
+                      if (! error_state)
+                        vals(n) = obj.get (property);
+                      else
+			{
+			  error ("get: expecting property name as second argument");
+			  break;
+			}
+                    }
+                }
+              else
+		{
+		  error ("get: invalid handle (= %g)", hcv(n));
+		  break;
+		}
+            }
+        }
+      else
+        error ("get: expecting graphics handle as first argument");
+    }
+  else
+    print_usage ();
+
+  if (! error_state)
+    {
+      octave_idx_type len = vals.numel ();
+
+      if (len > 1)
+	retval = vals;
+      else if (len == 1)
+	retval = vals(0);
+    }
+
+  return retval;
+}
+
+// Return all properties from the graphics handle @var{h}.
+// If @var{h} is a vector, return a cell array including the
+// property values or lists respectively.
+
+DEFUN (__get__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __get__ (@var{h})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  Cell vals;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      ColumnVector hcv (args(0).vector_value ());
+
+      if (! error_state)
+        {
+          octave_idx_type len = hcv.length ();
+
+          vals.resize (dim_vector (len, 1));
+
+          for (octave_idx_type n = 0; n < len; n++)
+            {
+              graphics_object obj = gh_manager::get_object (hcv(n));
+
+              if (obj)
+                vals(n) = obj.get (true);
+              else
+                {
+                  error ("get: invalid handle (= %g)", hcv(n));
+                  break;
+                }
+            }
+        }
+      else
+        error ("get: expecting graphics handle as first argument");
+    }
+  else
+    print_usage ();
+
+  if (! error_state)
+    {
+      octave_idx_type len = vals.numel ();
+
+      if (len > 1)
+        retval = vals;
+      else if (len == 1)
+        retval = vals(0);
+    }
+
+  return retval;
+}
+
+static octave_value
+make_graphics_object (const std::string& go_name,
+		      const octave_value_list& args)
+{
+  octave_value retval;
+
+  double val = octave_NaN;
+
+  octave_value_list xargs = args.splice (0, 1);
+
+  caseless_str p ("parent");
+
+  for (int i = 0; i < xargs.length (); i++)
+    if (xargs(i).is_string ()
+	&& p.compare (xargs(i).string_value ()))
+      {
+	if (i < (xargs.length () - 1))
+	  {
+	    val = xargs(i+1).double_value ();
+
+	    if (! error_state)
+	      {
+		xargs = xargs.splice (i, 2);
+		break;
+	      }
+	  }
+	else
+	  error ("__go_%s__: missing value for parent property",
+		 go_name.c_str ());
+      }
+
+  if (! error_state && xisnan (val))
+    val = args(0).double_value ();
+
+  if (! error_state)
+    {
+      graphics_handle parent = gh_manager::lookup (val);
+
+      if (parent.ok ())
+	{
+	  graphics_handle h
+	    = gh_manager::make_graphics_handle (go_name, parent, false);
+
+	  if (! error_state)
+	    {
+	      adopt (parent, h);
+
+	      xset (h, xargs);
+	      xcreatefcn (h);
+
+	      retval = h.value ();
+
+	      if (! error_state)
+		Vdrawnow_requested = true;
+	    }
+	  else
+	    error ("__go%s__: unable to create graphics handle",
+		   go_name.c_str ());
+	}
+      else
+	error ("__go_%s__: invalid parent", go_name.c_str ());
+    }
+  else
+    error ("__go_%s__: invalid parent", go_name.c_str ());
+
+  return retval;
+}
+
+DEFUN (__go_figure__, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_figure__ (@var{fignum})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  if (args.length () > 0)
+    {
+      double val = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  if (is_figure (val))
+	    {
+	      graphics_handle h = gh_manager::lookup (val);
+
+	      xset (h, args.splice (0, 1));
+
+	      retval = h.value ();
+	    }
+	  else
+	    {
+	      graphics_handle h = octave_NaN;
+
+	      if (xisnan (val))
+		h = gh_manager::make_graphics_handle ("figure", 0, false);
+	      else if (val > 0 && D_NINT (val) == val)
+		h = gh_manager::make_figure_handle (val);
+	      else
+		error ("__go_figure__: invalid figure number");
+
+	      if (! error_state && h.ok ())
+		{
+		  adopt (0, h);
+
+		  xset (h, args.splice (0, 1));
+		  xcreatefcn (h);
+
+		  retval = h.value ();
+		}
+	      else
+		error ("__go_figure__: failed to create figure handle");
+	    }
+	}
+      else
+	error ("__go_figure__: expecting figure number to be double value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#define GO_BODY(TYPE) \
+  gh_manager::autolock guard; \
+ \
+  octave_value retval; \
+ \
+  if (args.length () > 0) \
+    retval = make_graphics_object (#TYPE, args); \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+DEFUN (__go_axes__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_axes__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (axes);
+}
+
+DEFUN (__go_line__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_line__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (line);
+}
+
+DEFUN (__go_text__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_text__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (text);
+}
+
+DEFUN (__go_image__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_image__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (image);
+}
+
+DEFUN (__go_surface__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_surface__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (surface);
+}
+
+DEFUN (__go_patch__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_patch__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (patch);
+}
+
+DEFUN (__go_hggroup__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_hggroup__ (@var{parent})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  GO_BODY (hggroup);
+}
+
+DEFUN (__go_delete__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_delete__ (@var{h})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      graphics_handle h = octave_NaN;
+
+      const NDArray vals = args (0).array_value ();
+
+      if (! error_state)
+	{
+	  // Check is all the handles to delete are valid first
+	  // as callbacks might delete one of the handles we
+	  // later want to delete
+	  for (octave_idx_type i = 0; i < vals.numel (); i++)
+	    {
+	      h = gh_manager::lookup (vals.elem (i));
+
+	      if (! h.ok ())
+		{
+		  error ("delete: invalid graphics object (= %g)", 
+			 vals.elem (i));
+		  break;
+		}
+	    }
+
+	  if (! error_state)
+	    {
+	      for (octave_idx_type i = 0; i < vals.numel (); i++)
+		{
+		  h = gh_manager::lookup (vals.elem (i));
+
+		  if (h.ok ())
+		    {
+		      graphics_object obj = gh_manager::get_object (h);
+
+		      // Don't do recursive deleting, due to callbacks
+		      if (! obj.get_properties ().is_beingdeleted ())
+			{
+			  graphics_handle parent_h = obj.get_parent ();
+
+			  graphics_object parent_obj = 
+			    gh_manager::get_object (parent_h);
+
+			  // NOTE: free the handle before removing it from its
+			  //       parent's children, such that the object's 
+			  //       state is correct when the deletefcn callback
+			  //       is executed
+
+			  gh_manager::free (h);
+
+			  // A callback function might have already deleted 
+			  // the parent
+			  if (parent_obj.valid_object ())
+			    parent_obj.remove_child (h);
+
+			  Vdrawnow_requested = true;
+			}
+		    }
+		}
+	    }
+	}
+      else
+	error ("delete: invalid graphics object");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__go_axes_init__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_axes_init__ (@var{h}, @var{mode})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  std::string mode = "";
+
+  if (nargin == 2)
+    {
+      mode = args(1).string_value ();
+
+      if (error_state)
+	return retval;
+    }
+
+  if (nargin == 1 || nargin == 2)
+    {
+      graphics_handle h = octave_NaN;
+
+      double val = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  h = gh_manager::lookup (val);
+
+	  if (h.ok ())
+	    {
+	      graphics_object obj = gh_manager::get_object (h);
+
+	      obj.set_defaults (mode);
+
+	      h = gh_manager::lookup (val);
+	      if (! h.ok ())
+		error ("__go_axes_init__: axis deleted during initialization (= %g)", val);
+	    }
+	  else
+	    error ("__go_axes_init__: invalid graphics object (= %g)", val);
+	}
+      else
+	error ("__go_axes_init__: invalid graphics object");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__go_handles__, , ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_handles__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  return octave_value (gh_manager::handle_list ());
+}
+
+DEFUN (__go_figure_handles__, , ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_figure_handles__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  return octave_value (gh_manager::figure_handle_list ());
+}
+
+DEFUN (__go_execute_callback__, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __go_execute_callback__ (@var{h}, @var{name})\n\
+ at deftypefnx {Built-in Function} {} __go_execute_callback__ (@var{h}, @var{name}, @var{param})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 || nargin == 3)
+    {
+      double val = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  graphics_handle h = gh_manager::lookup (val);
+
+	  if (h.ok ())
+	    {
+	      std::string name = args(1).string_value ();
+
+	      if (! error_state)
+		{
+		  if (nargin == 2)
+		    gh_manager::execute_callback (h, name);
+		  else
+		    gh_manager::execute_callback (h, name, args(2));
+		}
+	      else
+		error ("__go_execute_callback__: invalid callback name");
+	    }
+	  else
+	    error ("__go_execute_callback__: invalid graphics object (= %g)",
+		   val);
+	}
+      else
+	error ("__go_execute_callback__: invalid graphics object");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (available_backends, , ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} available_backends ()\n\
+Return a cell array of registered graphics backends.\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  return octave_value (graphics_backend::available_backends_list ());
+}
+
+static void
+clear_drawnow_request (void *)
+{
+  Vdrawnow_requested = false;
+}
+
+DEFUN (drawnow, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} drawnow ()\n\
+ at deftypefnx {Built-in Function} {} drawnow (\"expose\")\n\
+ at deftypefnx {Built-in Function} {} drawnow (@var{term}, @var{file}, @var{mono}, @var{debug_file})\n\
+Update figure windows and their children.  The event queue is flushed and\n\
+any callbacks generated are executed.  With the optional argument\n\
+ at code{\"expose\"}, only graphic objects are updated and no other events or\n\
+callbacks are processed.\n\
+The third calling form of @code{drawnow} is for debugging and is\n\
+undocumented.\n\
+ at end deftypefn")
+{
+  static int drawnow_executing = 0;
+  static bool __go_close_all_registered__ = false;
+
+  octave_value retval;
+
+  gh_manager::lock ();
+
+  unwind_protect::begin_frame ("Fdrawnow");
+  unwind_protect::add (clear_drawnow_request);
+
+  unwind_protect_int (drawnow_executing);
+
+  if (++drawnow_executing <= 1)
+    {
+      if (! __go_close_all_registered__)
+	{
+	  octave_add_atexit_function ("__go_close_all__");
+
+	  __go_close_all_registered__ = true;
+	}
+
+      if (args.length () == 0 || args.length () == 1)
+	{
+	  Matrix hlist = gh_manager::figure_handle_list ();
+
+	  for (int i = 0; ! error_state && i < hlist.length (); i++)
+	    {
+	      graphics_handle h = gh_manager::lookup (hlist(i));
+
+	      if (h.ok () && h != 0)
+		{
+		  graphics_object go = gh_manager::get_object (h);
+		  figure::properties& fprops = dynamic_cast <figure::properties&> (go.get_properties ());
+
+		  if (fprops.is_modified ())
+		    {
+		      if (fprops.is_visible ())
+			{
+			  gh_manager::unlock ();
+
+			  fprops.get_backend ().redraw_figure (go);
+
+			  gh_manager::lock ();
+			}
+
+		      fprops.set_modified (false);
+		    }
+		}
+	    }
+
+	  bool do_events = true;
+
+	  if (args.length () == 1)
+	    {
+	      caseless_str val (args(0).string_value ());
+
+	      if (! error_state && val.compare ("expose"))
+		do_events = false;
+	      else
+		{
+		  error ("drawnow: invalid argument, expected `expose' as argument");
+		  return retval;
+		}
+	    }
+
+	  if (do_events)
+	    {
+	      gh_manager::unlock ();
+
+	      gh_manager::process_events ();
+
+	      gh_manager::lock ();
+	    }
+	}
+      else if (args.length () >= 2 && args.length () <= 4)
+	{
+	  std::string term, file, debug_file;
+	  bool mono;
+
+	  term = args(0).string_value ();
+
+	  if (! error_state)
+	    {
+	      file = args(1).string_value ();
+
+	      if (! error_state)
+		{
+		  size_t pos = file.find_last_of (file_ops::dir_sep_chars ());
+
+		  if (pos != std::string::npos)
+		    {
+		      std::string dirname = file.substr (0, pos+1);
+
+		      file_stat fs (dirname);
+
+		      if (! (fs && fs.is_dir ()))
+			{
+			  error ("drawnow: nonexistent directory `%s'",
+				 dirname.c_str ());
+
+			  return retval;
+			}
+		    }
+
+		  mono = (args.length () >= 3 ? args(2).bool_value () : false);
+
+		  if (! error_state)
+		    {
+		      debug_file = (args.length () > 3 ? args(3).string_value ()
+				    : "");
+
+		      if (! error_state)
+			{
+			  graphics_handle h = gcf ();
+
+			  if (h.ok ())
+			    {
+			      graphics_object go = gh_manager::get_object (h);
+
+			      gh_manager::unlock ();
+
+			      go.get_backend ()
+				.print_figure (go, term, file, mono, debug_file);
+
+			      gh_manager::lock ();
+			    }
+			  else
+			    error ("drawnow: nothing to draw");
+			}
+		      else
+			error ("drawnow: invalid debug_file, expected a string value");
+		    }
+		  else
+		    error ("drawnow: invalid colormode, expected a boolean value");
+		}
+	      else
+		error ("drawnow: invalid file, expected a string value");
+	    }
+	  else
+	    error ("drawnow: invalid terminal, expected a string value");
+	}
+      else
+	print_usage ();
+    }
+
+  unwind_protect::run_frame ("Fdrawnow");
+
+  gh_manager::unlock ();
+
+  return retval;
+}
+
+DEFUN (addlistener, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} addlistener (@var{h}, @var{prop}, @var{fcn})\n\
+Register @var{fcn} as listener for the property @var{prop} of the graphics\n\
+object @var{h}.  Property listeners are executed (in order of registration)\n\
+when the property is set.  The new value is already available when the\n\
+listeners are executed.\n\
+\n\
+ at var{prop} must be a string naming a valid property in @var{h}.\n\
+\n\
+ at var{fcn} can be a function handle, a string or a cell array whose first\n\
+element is a function handle.  If @var{fcn} is a function handle, the\n\
+corresponding function should accept at least 2 arguments, that will be\n\
+set to the object handle and the empty matrix respectively.  If @var{fcn}\n\
+is a string, it must be any valid octave expression.  If @var{fcn} is a cell\n\
+array, the first element must be a function handle with the same signature\n\
+as described above.  The next elements of the cell array are passed\n\
+as additional arguments to the function.\n\
+\n\
+Example:\n\
+\n\
+ at example\n\
+ at group\n\
+function my_listener (h, dummy, p1)\n\
+  fprintf (\"my_listener called with p1=%s\\n\", p1);\n\
+endfunction\n\
+\n\
+addlistener (gcf, \"position\", @{@@my_listener, \"my string\"@})\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  if (args.length () == 3)
+    {
+      double h = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  std::string pname = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      graphics_handle gh = gh_manager::lookup (h);
+
+	      if (gh.ok ())
+		{
+		  graphics_object go = gh_manager::get_object (gh);
+
+		  go.add_property_listener (pname, args(2), POSTSET);
+		}
+	      else
+		error ("addlistener: invalid graphics object (= %g)",
+		       h);
+	    }
+	  else
+	    error ("addlistener: invalid property name, expected a string value");
+	}
+      else
+	error ("addlistener: invalid handle");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (dellistener, args, ,
+   "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} dellistener (@var{h}, @var{prop}, @var{fcn})\n\
+Remove the registration of @var{fcn} as a listener for the property\n\
+ at var{prop} of the graphics object @var{h}.  The function @var{fcn} must\n\
+be the same variable (not just the same value), as was passed to the\n\
+original call to @code{addlistener}.\n\
+\n\
+If @var{fcn} is not defined then all listener functions of @var{prop}\n\
+are removed.\n\
+\n\
+Example:\n\
+\n\
+ at example\n\
+ at group\n\
+function my_listener (h, dummy, p1)\n\
+  fprintf (\"my_listener called with p1=%s\\n\", p1);\n\
+endfunction\n\
+\n\
+c = @{@@my_listener, \"my string\"@};\n\
+addlistener (gcf, \"position\", c);\n\
+dellistener (gcf, \"position\", c);\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  if (args.length () == 3 || args.length () == 2)
+    {
+      double h = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  std::string pname = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      graphics_handle gh = gh_manager::lookup (h);
+
+	      if (gh.ok ())
+		{
+		  graphics_object go = gh_manager::get_object (gh);
+
+		  if (args.length () == 2)
+		    go.delete_property_listener (pname, octave_value (), POSTSET);
+		  else
+		    go.delete_property_listener (pname, args(2), POSTSET);
+		}
+	      else
+		error ("dellistener: invalid graphics object (= %g)",
+		       h);
+	    }
+	  else
+	    error ("dellistener: invalid property name, expected a string value");
+	}
+      else
+	error ("dellistener: invalid handle");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (addproperty, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} addproperty (@var{name}, @var{h}, @var{type}, [@var{arg}, @dots{}])\n\
+Create a new property named @var{name} in graphics object @var{h}.\n\
+ at var{type} determines the type of the property to create.  @var{args}\n\
+usually contains the default value of the property, but additional\n\
+arguments might be given, depending on the type of the property.\n\
+\n\
+The supported property types are:\n\
+\n\
+ at table @code\n\
+ at item string\n\
+A string property.  @var{arg} contains the default string value.\n\
+ at item any\n\
+An un-typed property.  This kind of property can hold any octave\n\
+value.  @var{args} contains the default value.\n\
+ at item radio\n\
+A string property with a limited set of accepted values.  The first\n\
+argument must be a string with all accepted values separated by\n\
+a vertical bar ('|').  The default value can be marked by enclosing\n\
+it with a '@{' '@}' pair.  The default value may also be given as\n\
+an optional second string argument.\n\
+ at item boolean\n\
+A boolean property.  This property type is equivalent to a radio\n\
+property with \"on|off\" as accepted values.  @var{arg} contains\n\
+the default property value.\n\
+ at item double\n\
+A scalar double property.  @var{arg} contains the default value.\n\
+ at item handle\n\
+A handle property.  This kind of property holds the handle of a\n\
+graphics object.  @var{arg} contains the default handle value.\n\
+When no default value is given, the property is initialized to\n\
+the empty matrix.\n\
+ at item data\n\
+A data (matrix) property.  @var{arg} contains the default data\n\
+value.  When no default value is given, the data is initialized to\n\
+the empty matrix.\n\
+ at item color\n\
+A color property.  @var{arg} contains the default color value.\n\
+When no default color is given, the property is set to black.\n\
+An optional second string argument may be given to specify an\n\
+additional set of accepted string values (like a radio property).\n\
+ at end table\n\
+\n\
+ at var{type} may also be the concatenation of a core object type and\n\
+a valid property name for that object type.  The property created\n\
+then has the same characteristics as the referenced property (type,\n\
+possible values, hidden state at dots{}).  This allows to clone an existing\n\
+property into the graphics object @var{h}.\n\
+\n\
+Examples:\n\
+\n\
+ at example\n\
+ at group\n\
+addproperty (\"my_property\", gcf, \"string\", \"a string value\");\n\
+addproperty (\"my_radio\", gcf, \"radio\", \"val_1|val_2|@{val_3@}\");\n\
+addproperty (\"my_style\", gcf, \"linelinestyle\", \"--\");\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  if (args.length () >= 3)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  double h = args(1).double_value ();
+
+	  if (! error_state)
+	    {
+	      graphics_handle gh = gh_manager::lookup (h);
+
+	      if (gh.ok ())
+		{
+		  graphics_object go = gh_manager::get_object (gh);
+
+		  std::string type = args(2).string_value ();
+
+		  if (! error_state)
+		    {
+		      if (! go.get_properties ().has_property (name))
+			{
+			  property p = property::create (name, gh, type,
+							 args.splice (0, 3));
+
+			  if (! error_state)
+			    go.get_properties ().insert_property (name, p);
+			}
+		      else
+			error ("addproperty: a `%s' property already exists in the graphics object",
+			       name.c_str ());
+		    }
+		  else
+		    error ("addproperty: invalid property type, expected a string value");
+		}
+	      else
+		error ("addproperty: invalid graphics object (= %g)", h);
+	    }
+	  else
+	    error ("addproperty: invalid handle value");
+	}
+      else
+	error ("addproperty: invalid property name, expected a string value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+octave_value
+get_property_from_handle (double handle, const std::string& property,
+			  const std::string& func)
+{
+  gh_manager::autolock guard;
+
+  graphics_object obj = gh_manager::get_object (handle);
+  octave_value retval;
+
+  if (obj)
+    {
+      caseless_str p = std::string (property);
+      retval = obj.get (p);
+    }
+  else
+    error ("%s: invalid handle (= %g)", func.c_str(), handle);
+
+  return retval;
+}
+
+bool
+set_property_in_handle (double handle, const std::string& property,
+			const octave_value& arg, const std::string& func)
+{
+  gh_manager::autolock guard;
+
+  graphics_object obj = gh_manager::get_object (handle);
+  int ret = false;
+
+  if (obj)
+    {
+      caseless_str p = std::string (property);
+      obj.set (p, arg);
+      if (!error_state)
+	ret = true;
+    }
+  else
+    error ("%s: invalid handle (= %g)", func.c_str(), handle);
+
+  return ret;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/graphics.h b/src/graphics.h
new file mode 100644
index 0000000..56466f8
--- /dev/null
+++ b/src/graphics.h
@@ -0,0 +1,9147 @@
+// DO NOT EDIT!  Generated automatically by genprops.awk.
+
+/*
+
+Copyright (C) 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (graphics_h)
+#define graphics_h 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include "lo-ieee.h"
+
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-mutex.h"
+#include "ov.h"
+
+// FIXME -- maybe this should be a configure option?
+// Matlab defaults to "Helvetica", but that causes problems for many
+// gnuplot users.
+#if !defined (OCTAVE_DEFAULT_FONTNAME)
+#define OCTAVE_DEFAULT_FONTNAME "*"
+#endif
+
+class caseless_str : public std::string
+{
+public:
+  typedef std::string::iterator iterator;
+  typedef std::string::const_iterator const_iterator;
+
+  caseless_str (void) : std::string () { }
+  caseless_str (const std::string& s) : std::string (s) { }
+  caseless_str (const char *s) : std::string (s) { }
+
+  caseless_str (const caseless_str& name) : std::string (name) { }
+
+  caseless_str& operator = (const caseless_str& pname)
+  {
+    std::string::operator = (pname);
+    return *this;
+  }
+
+  operator std::string (void) const { return *this; }
+
+  // Case-insensitive comparison.
+  bool compare (const std::string& s, size_t limit = std::string::npos) const
+  {
+    const_iterator p1 = begin ();
+    const_iterator p2 = s.begin ();
+
+    size_t k = 0;
+
+    while (p1 != end () && p2 != s.end () && k++ < limit)
+      {
+	if (std::tolower (*p1) != std::tolower (*p2))
+	  return false;
+
+	*p1++;
+	*p2++;
+      }
+
+    return (limit == std::string::npos) ? size () == s.size () : k == limit;
+  }
+};
+
+// ---------------------------------------------------------------------
+
+class graphics_handle
+{
+public:
+  graphics_handle (void) : val (octave_NaN) { }
+
+  graphics_handle (const octave_value& a);
+
+  graphics_handle (int a) : val (a) { }
+
+  graphics_handle (double a) : val (a) { }
+
+  graphics_handle (const graphics_handle& a) : val (a.val) { }
+
+  graphics_handle& operator = (const graphics_handle& a)
+  {
+    if (&a != this)
+      val = a.val;
+
+    return *this;
+  }
+
+  ~graphics_handle (void) { }
+
+  double value (void) const { return val; }
+
+  octave_value as_octave_value (void) const
+  {
+    return ok () ? octave_value (val) : octave_value (Matrix ());
+  }
+
+  graphics_handle operator ++ (void)
+  {
+    ++val;
+    return *this;
+  }
+
+  graphics_handle operator ++ (int)
+  {
+    graphics_handle h = *this;
+    ++val;
+    return h;
+  }
+
+  graphics_handle operator -- (void)
+  {
+    --val;
+    return *this;
+  }
+
+  graphics_handle operator -- (int)
+  {
+    graphics_handle h = *this;
+    --val;
+    return h;
+  }
+
+  bool ok (void) const { return ! xisnan (val); }
+
+private:
+  double val;
+};
+
+inline bool
+operator == (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () == b.value ();
+}
+
+inline bool
+operator != (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () != b.value ();
+}
+
+inline bool
+operator < (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () < b.value ();
+}
+
+inline bool
+operator <= (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () <= b.value ();
+}
+
+inline bool
+operator >= (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () >= b.value ();
+}
+
+inline bool
+operator > (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () > b.value ();
+}
+
+// ---------------------------------------------------------------------
+
+class base_scaler
+{
+public:
+  base_scaler (void) { }
+
+  virtual ~base_scaler (void) { }
+
+  virtual Matrix scale (const Matrix& m) const
+    {
+      error ("invalid axis scale");
+      return m;
+    }
+
+  virtual NDArray scale (const NDArray& m) const
+    {
+      error ("invalid axis scale");
+      return m;
+    }
+
+  virtual double scale (double d) const
+    {
+      error ("invalid axis scale");
+      return d;
+    }
+  
+  virtual double unscale (double d) const
+    {
+      error ("invalid axis scale");
+      return d;
+    }
+
+  virtual base_scaler* clone () const
+    { return new base_scaler (); }
+
+  virtual bool is_linear (void) const
+    { return false; }
+};
+
+class lin_scaler : public base_scaler
+{
+public:
+  lin_scaler (void) { }
+
+  Matrix scale (const Matrix& m) const { return m; }
+
+  NDArray scale (const NDArray& m) const { return m; }
+
+  double scale (double d) const { return d; }
+
+  double unscale (double d) const { return d; }
+
+  base_scaler* clone (void) const { return new lin_scaler (); }
+
+  bool is_linear (void) const { return true; }
+};
+
+class log_scaler : public base_scaler
+{
+public:
+  log_scaler (void) { }
+
+  Matrix scale (const Matrix& m) const
+    {
+      Matrix retval (m.rows (), m.cols ());
+
+      do_scale (m.data (), retval.fortran_vec (), m.numel ());
+      return retval;
+    }
+
+  NDArray scale (const NDArray& m) const
+    {
+      NDArray retval (m.dims ());
+
+      do_scale (m.data (), retval.fortran_vec (), m.numel ());
+      return retval;
+    }
+
+  double scale (double d) const
+    { return log10 (d); }
+
+  double unscale (double d) const
+    { return pow (10.0, d); }
+
+  base_scaler* clone (void) const
+    { return new log_scaler (); }
+
+private:
+  void do_scale (const double *src, double *dest, int n) const
+    {
+      for (int i = 0; i < n; i++)
+	dest[i] = log10(src[i]);
+    }
+};
+
+class scaler
+{
+public:
+  scaler (void) : rep (new base_scaler ()) { }
+
+  scaler (const scaler& s) : rep (s.rep->clone()) { }
+
+  ~scaler (void) { delete rep; }
+
+  Matrix scale (const Matrix& m) const
+    { return rep->scale (m); }
+
+  NDArray scale (const NDArray& m) const
+    { return rep->scale (m); }
+
+  double scale (double d) const
+    { return rep->scale (d); }
+
+  double unscale (double d) const
+    { return rep->unscale (d); }
+
+  bool is_linear (void) const
+    { return rep->is_linear (); }
+
+  scaler& operator = (const scaler& s)
+    {
+      if (rep)
+	{
+	  delete rep;
+	  rep = 0;
+	}
+
+      rep = s.rep->clone ();
+
+      return *this;
+    }
+
+  scaler& operator = (const std::string& s)
+    {
+      if (rep)
+	{
+	  delete rep;
+	  rep = 0;
+	}
+
+      if (s == "log")
+	rep = new log_scaler ();
+      else if (s == "linear")
+	rep = new lin_scaler ();
+      else
+	rep = new base_scaler ();
+
+      return *this;
+    }
+
+private:
+  base_scaler *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class property;
+
+enum listener_mode { POSTSET };
+
+class base_property
+{
+public:
+  friend class property;
+
+public:
+  base_property (void) : id (-1), count (1) { }
+
+  base_property (const std::string& s, const graphics_handle& h)
+    : id (-1), count (1), name (s), parent (h), hidden (false) { }
+
+  base_property (const base_property& p)
+    : id (-1), count (1), name (p.name), parent (p.parent), hidden (p.hidden) { }
+
+  virtual ~base_property (void) { }
+
+  bool ok (void) const { return parent.ok (); }
+
+  std::string get_name (void) const { return name; }
+
+  void set_name (const std::string& s) { name = s; }
+
+  graphics_handle get_parent (void) const { return parent; }
+
+  void set_parent (const graphics_handle &h) { parent = h; }
+
+  bool is_hidden (void) const { return hidden; }
+
+  void set_hidden (bool flag) { hidden = flag; }
+
+  int get_id (void) const { return id; }
+
+  void set_id (int d) { id = d; }
+
+  // Sets property value, notifies backend.
+  // If do_run is true, runs associated listeners.
+  bool set (const octave_value& v, bool do_run = true);
+  
+  virtual octave_value get (void) const
+    {
+      error ("get: invalid property \"%s\"", name.c_str ());
+      return octave_value ();
+    }
+
+  base_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  void add_listener (const octave_value& v, listener_mode mode = POSTSET)
+    {
+      octave_value_list& l = listeners[mode];
+      l.resize (l.length () + 1, v);
+    }
+
+  void delete_listener (const octave_value& v = octave_value (), 
+			listener_mode mode = POSTSET)
+    {
+      octave_value_list& l = listeners[mode];
+
+      if (v.is_defined ())
+	{
+	  bool found = false;
+	  int i;
+
+	  for (i = 0; i < l.length (); i++)
+	    {
+	      if (v.internal_rep () == l(i).internal_rep ())
+		{
+		  found = true;
+		  break;
+		}
+	    }
+	  if (found)
+	    {
+	      for (int j = i; j < l.length() - 1; j++)
+		l(j) = l (j + 1);
+
+	      l.resize (l.length () - 1);
+	    }
+	}
+      else
+	l.resize (0);
+
+    }
+
+  OCTINTERP_API void run_listeners (listener_mode mode = POSTSET);
+
+  virtual base_property* clone (void) const
+    { return new base_property (*this); }
+
+protected:
+  virtual bool do_set (const octave_value&)
+    {
+      error ("set: invalid property \"%s\"", name.c_str ());
+      return false;
+    }
+
+private:
+  typedef std::map<listener_mode, octave_value_list> listener_map;
+  typedef std::map<listener_mode, octave_value_list>::iterator listener_map_iterator;
+  typedef std::map<listener_mode, octave_value_list>::const_iterator listener_map_const_iterator;
+
+private:
+  int id;
+  int count;
+  std::string name;
+  graphics_handle parent;
+  bool hidden;
+  listener_map listeners;
+};
+
+// ---------------------------------------------------------------------
+
+class string_property : public base_property
+{
+public:
+  string_property (const std::string& s, const graphics_handle& h,
+                   const std::string& val = "")
+    : base_property (s, h), str (val) { }
+
+  string_property (const string_property& p)
+    : base_property (p), str (p.str) { }
+
+  octave_value get (void) const
+    { return octave_value (str); }
+
+  std::string string_value (void) const { return str; }
+
+  string_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new string_property (*this); }
+
+protected:
+  bool do_set (const octave_value& val)
+    {
+      if (val.is_string ())
+	{
+	  std::string new_str = val.string_value ();
+
+	  if (new_str != str)
+	    {
+	      str = new_str;
+	      return true;
+	    }
+	}
+      else
+        error ("set: invalid string property value for \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  std::string str;
+};
+
+// ---------------------------------------------------------------------
+
+class radio_values
+{
+public:
+  OCTINTERP_API radio_values (const std::string& opt_string = std::string ());
+
+  radio_values (const radio_values& a)
+    : default_val (a.default_val), possible_vals (a.possible_vals) { }
+
+  radio_values& operator = (const radio_values& a)
+  {
+    if (&a != this)
+      {
+	default_val = a.default_val;
+	possible_vals = a.possible_vals;
+      }
+
+    return *this;
+  }
+
+  std::string default_value (void) const { return default_val; }
+
+  bool validate (const std::string& val)
+  {
+    bool retval = true;
+
+    if (! contains (val))
+      {
+	error ("invalid value = %s", val.c_str ());
+	retval = false;
+      }
+
+    return retval;
+  }
+  
+  bool contains (const std::string& val)
+  {
+    return (possible_vals.find (val) != possible_vals.end ());
+  }
+
+private:
+  // Might also want to cache
+  std::string default_val;
+  std::set<caseless_str> possible_vals;
+};
+
+class radio_property : public base_property
+{
+public:
+  radio_property (const std::string& nm, const graphics_handle& h,
+                  const radio_values& v = radio_values ())
+    : base_property (nm, h),
+      vals (v), current_val (v.default_value ()) { }
+
+  radio_property (const std::string& nm, const graphics_handle& h,
+                  const std::string& v)
+    : base_property (nm, h),
+      vals (v), current_val (vals.default_value ()) { }
+
+  radio_property (const std::string& nm, const graphics_handle& h,
+                  const radio_values& v, const std::string& def)
+    : base_property (nm, h),
+      vals (v), current_val (def) { }
+
+  radio_property (const radio_property& p)
+    : base_property (p), vals (p.vals), current_val (p.current_val) { }
+
+  octave_value get (void) const { return octave_value (current_val); }
+
+  const std::string& current_value (void) const { return current_val; }
+
+  bool is (const caseless_str& v) const
+    { return v.compare (current_val); }
+
+  radio_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new radio_property (*this); }
+
+protected:
+  bool do_set (const octave_value& newval) 
+  {
+    if (newval.is_string ())
+      {
+        std::string s = newval.string_value ();
+        if (vals.validate (s))
+	  {
+	    if (s != current_val)
+	      {
+		current_val = s;
+		return true;
+	      }
+	  }
+        else
+          error ("set: invalid value for radio property \"%s\" (value = %s)",
+              get_name ().c_str (), s.c_str ());
+      }
+    else	
+      error ("set: invalid value for radio property \"%s\"",
+          get_name ().c_str ());
+    return false;
+  }
+
+private:
+  radio_values vals;
+  std::string current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class color_values
+{
+public:
+  color_values (double r = 0, double g = 0, double b = 1)
+    : xrgb (1, 3)
+  {
+    xrgb(0) = r;
+    xrgb(1) = g;
+    xrgb(2) = b;
+
+    validate ();
+  }
+
+  color_values (std::string str)
+    : xrgb (1, 3)
+  {
+    if (! str2rgb (str))
+      error ("invalid color specification: %s", str.c_str ());
+  }
+
+  color_values (const color_values& c)
+    : xrgb (c.xrgb)
+  { }
+
+  color_values& operator = (const color_values& c)
+  {
+    if (&c != this)
+      xrgb = c.xrgb;
+
+    return *this;
+  }
+
+  bool operator == (const color_values& c) const
+    {
+      return (xrgb(0) == c.xrgb(0)
+	      && xrgb(1) == c.xrgb(1)
+	      && xrgb(2) == c.xrgb(2));
+    }
+
+  bool operator != (const color_values& c) const
+    { return ! (*this == c); }
+
+  Matrix rgb (void) const { return xrgb; }
+
+  operator octave_value (void) const { return xrgb; }
+
+  void validate (void) const
+  {
+    for (int i = 0; i < 3; i++)
+      {
+	if (xrgb(i) < 0 ||  xrgb(i) > 1)
+	  {
+	    error ("invalid RGB color specification");
+	    break;
+	  }
+      }
+  }
+
+private:
+  Matrix xrgb;
+
+  OCTINTERP_API bool str2rgb (std::string str);
+};
+
+class color_property : public base_property
+{
+public:
+  color_property (const color_values& c, const radio_values& v)
+    : base_property ("", graphics_handle ()),
+      current_type (color_t), color_val (c), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const color_values& c = color_values (),
+                  const radio_values& v = radio_values ())
+    : base_property (nm, h),
+      current_type (color_t), color_val (c), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const radio_values& v)
+    : base_property (nm, h),
+      current_type (radio_t), color_val (color_values ()), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const std::string& v)
+    : base_property (nm, h),
+      current_type (radio_t), color_val (color_values ()), radio_val (v),
+      current_val (radio_val.default_value ())
+  { }
+  
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const color_property& v)
+    : base_property (nm, h),
+      current_type (v.current_type), color_val (v.color_val),
+      radio_val (v.radio_val), current_val (v.current_val)
+  { }
+
+  color_property (const color_property& p)
+    : base_property (p), current_type (p.current_type),
+      color_val (p.color_val), radio_val (p.radio_val),
+      current_val (p.current_val) { }
+
+  octave_value get (void) const
+  {
+    if (current_type == color_t)
+      return color_val.rgb ();
+
+    return current_val;
+  }
+
+  bool is_rgb (void) const { return (current_type == color_t); }
+
+  bool is_radio (void) const { return (current_type == radio_t); }
+
+  bool is (const std::string& v) const
+    { return (is_radio () && current_val == v); }
+
+  Matrix rgb (void) const
+  {
+    if (current_type != color_t)
+      error ("color has no rgb value");
+
+    return color_val.rgb ();
+  }
+
+  const std::string& current_value (void) const
+  {
+    if (current_type != radio_t)
+      error ("color has no radio value");
+
+    return current_val;
+  }
+
+  color_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  operator octave_value (void) const { return get (); }
+
+  base_property* clone (void) const { return new color_property (*this); }
+
+protected:
+  OCTINTERP_API bool do_set (const octave_value& newval);
+
+private:
+  enum current_enum { color_t, radio_t } current_type;
+  color_values color_val;
+  radio_values radio_val;
+  std::string current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class double_property : public base_property
+{
+public:
+  double_property (const std::string& nm, const graphics_handle& h,
+                   double d = 0)
+    : base_property (nm, h),
+      current_val (d) { }
+
+  double_property (const double_property& p)
+    : base_property (p), current_val (p.current_val) { }
+
+  octave_value get (void) const { return octave_value (current_val); }
+
+  double double_value (void) const { return current_val; }
+
+  double_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new double_property (*this); }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      if (v.is_scalar_type () && v.is_real_type ())
+	{
+	  double new_val = v.double_value ();
+
+	  if (new_val != current_val)
+	    {
+	      current_val = new_val;
+	      return true;
+	    }
+	}
+      else
+        error ("set: invalid value for double property \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  double current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class double_radio_property : public base_property
+{
+public:
+  double_radio_property (double d, const radio_values& v)
+      : base_property ("", graphics_handle ()),
+        current_type (double_t), dval (d), radio_val (v),
+	current_val (v.default_value ())
+  { }
+
+  double_radio_property (const std::string& nm, const graphics_handle& h,
+			 const std::string& v)
+      : base_property (nm, h),
+        current_type (radio_t), dval (0), radio_val (v),
+	current_val (radio_val.default_value ())
+  { }
+
+  double_radio_property (const std::string& nm, const graphics_handle& h,
+			 const double_radio_property& v)
+      : base_property (nm, h),
+        current_type (v.current_type), dval (v.dval),
+	radio_val (v.radio_val), current_val (v.current_val)
+  { }
+
+  double_radio_property (const double_radio_property& p)
+    : base_property (p), current_type (p.current_type),
+      dval (p.dval), radio_val (p.radio_val),
+      current_val (p.current_val) { }
+
+  octave_value get (void) const
+  {
+    if (current_type == double_t)
+      return dval;
+
+    return current_val;
+  }
+
+  bool is_double (void) const { return (current_type == double_t); }
+
+  bool is_radio (void) const { return (current_type == radio_t); }
+
+  bool is (const std::string& v) const
+    { return (is_radio () && current_val == v); }
+
+  double double_value (void) const
+  {
+    if (current_type != double_t)
+      error ("%s: property has no double", get_name ().c_str ());
+
+    return dval;
+  }
+
+  const std::string& current_value (void) const
+  {
+    if (current_type != radio_t)
+      error ("%s: property has no radio value");
+
+    return current_val;
+  }
+
+  double_radio_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  operator octave_value (void) const { return get (); }
+
+  base_property* clone (void) const
+    { return new double_radio_property (*this); }
+
+protected:
+  OCTINTERP_API bool do_set (const octave_value& v);
+
+private:
+  enum current_enum { double_t, radio_t } current_type;
+  double dval;
+  radio_values radio_val;
+  std::string current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class array_property : public base_property
+{
+public:
+  array_property (void)
+      : base_property ("", graphics_handle ()), data (Matrix ())
+    {
+      get_data_limits ();
+    }
+
+  array_property (const std::string& nm, const graphics_handle& h,
+                  const octave_value& m)
+      : base_property (nm, h), data (m)
+    {
+      get_data_limits ();
+    }
+
+  // This copy constructor is only intended to be used
+  // internally to access min/max values; no need to
+  // copy constraints.
+  array_property (const array_property& p)
+    : base_property (p), data (p.data),
+      xmin (p.xmin), xmax (p.xmax), xminp (p.xminp) { }
+
+  octave_value get (void) const { return data; }
+
+  void add_constraint (const std::string& type)
+    { type_constraints.push_back (type); }
+
+  void add_constraint (const dim_vector& dims)
+    { size_constraints.push_back (dims); }
+
+  double min_val (void) const { return xmin; }
+  double max_val (void) const { return xmax; }
+  double min_pos (void) const { return xminp; }
+
+  Matrix get_limits (void) const
+    {
+      Matrix m (1, 3);
+      
+      m(0) = min_val ();
+      m(1) = max_val ();
+      m(2) = min_pos ();
+
+      return m;
+    }
+
+  array_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const
+    {
+      array_property *p = new array_property (*this);
+
+      p->type_constraints = type_constraints;
+      p->size_constraints = size_constraints;
+      
+      return p;
+    }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      if (validate (v))
+	{
+	  // FIXME -- should we check for actual data change?
+	  if (! is_equal (v))
+	    {
+	      data = v;
+
+	      get_data_limits ();
+
+	      return true;
+	    }
+	}
+      else
+        error ("invalid value for array property \"%s\"",
+               get_name ().c_str ());
+      
+      return false;
+    }
+
+private:
+  OCTINTERP_API bool validate (const octave_value& v);
+
+  OCTINTERP_API bool is_equal (const octave_value& v) const;
+
+  OCTINTERP_API void get_data_limits (void);
+
+protected:
+  octave_value data;
+  double xmin;
+  double xmax;
+  double xminp;
+  std::list<std::string> type_constraints;
+  std::list<dim_vector> size_constraints;
+};
+
+class row_vector_property : public array_property
+{
+public:
+  row_vector_property (const std::string& nm, const graphics_handle& h,
+		       const octave_value& m)
+    : array_property (nm, h, m)
+  {
+    add_constraint (dim_vector (-1, 1));
+    add_constraint (dim_vector (1, -1));
+  }
+
+  row_vector_property (const row_vector_property& p)
+    : array_property (p)
+  {
+    add_constraint (dim_vector (-1, 1));
+    add_constraint (dim_vector (1, -1));
+  }
+
+  void add_constraint (const std::string& type)
+  {
+    array_property::add_constraint (type);
+  }
+
+  void add_constraint (const dim_vector& dims)
+  {
+    array_property::add_constraint (dims);
+  }
+
+  void add_constraint (octave_idx_type len)
+  {
+    size_constraints.remove (dim_vector (1, -1));
+    size_constraints.remove (dim_vector (-1, 1));
+
+    add_constraint (dim_vector (1, len));
+    add_constraint (dim_vector (len, 1));
+  }
+
+  row_vector_property& operator = (const octave_value& val)
+  {
+    set (val);
+    return *this;
+  }
+
+  base_property* clone (void) const
+    {
+      row_vector_property *p = new row_vector_property (*this);
+
+      p->type_constraints = type_constraints;
+      p->size_constraints = size_constraints;
+
+      return p;
+    }
+
+protected:
+  bool do_set (const octave_value& v)
+  {
+    bool retval = array_property::do_set (v);
+
+    if (! error_state)
+      {
+	dim_vector dv = data.dims ();
+
+	if (dv(0) > 1 && dv(1) == 1)
+	  {
+	    int tmp = dv(0);
+	    dv(0) = dv(1);
+	    dv(1) = tmp;
+
+	    data = data.reshape (dv);
+	  }
+
+	return retval;
+      }
+
+    return false;
+  }
+
+private:
+  OCTINTERP_API bool validate (const octave_value& v);
+};
+
+// ---------------------------------------------------------------------
+
+class bool_property : public radio_property
+{
+public:
+  bool_property (const std::string& nm, const graphics_handle& h,
+                 bool val)
+    : radio_property (nm, h, radio_values (val ? "{on}|off" : "on|{off}"))
+    { }
+
+  bool_property (const std::string& nm, const graphics_handle& h,
+                 const char* val)
+    : radio_property (nm, h, radio_values ("on|off"), val)
+    { }
+
+  bool_property (const bool_property& p)
+    : radio_property (p) { }
+
+  bool is_on (void) const { return is ("on"); }
+  
+  bool_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new bool_property (*this); }
+
+protected:
+  bool do_set (const octave_value& val)
+    {
+      if (val.is_bool_scalar ())
+        return radio_property::do_set (val.bool_value () ? "on" : "off");
+      else
+        return radio_property::do_set (val);
+    }
+};
+
+// ---------------------------------------------------------------------
+
+class handle_property : public base_property
+{
+public:
+  handle_property (const std::string& nm, const graphics_handle& h,
+                   const graphics_handle& val = graphics_handle ())
+    : base_property (nm, h),
+      current_val (val) { }
+
+  handle_property (const handle_property& p)
+    : base_property (p), current_val (p.current_val) { }
+
+  octave_value get (void) const { return current_val.as_octave_value (); }
+
+  graphics_handle handle_value (void) const { return current_val; }
+
+  handle_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  handle_property& operator = (const graphics_handle& h)
+    {
+      set (octave_value (h.value ()));
+      return *this;
+    }
+
+  base_property* clone (void) const { return new handle_property (*this); }
+
+protected:
+  OCTINTERP_API bool do_set (const octave_value& v);
+
+private:
+  graphics_handle current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class any_property : public base_property
+{
+public:
+  any_property (const std::string& nm, const graphics_handle& h,
+                  const octave_value& m = Matrix ())
+    : base_property (nm, h), data (m) { }
+
+  any_property (const any_property& p)
+    : base_property (p), data (p.data) { }
+
+  octave_value get (void) const { return data; }
+
+  any_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new any_property (*this); }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      data = v;
+      return true;
+    }
+
+private:
+  octave_value data;
+};
+
+// ---------------------------------------------------------------------
+
+class callback_property : public base_property
+{
+public:
+  callback_property (const std::string& nm, const graphics_handle& h,
+                     const octave_value& m)
+    : base_property (nm, h), callback (m) { }
+
+  callback_property (const callback_property& p)
+    : base_property (p), callback (p.callback) { }
+
+  octave_value get (void) const { return callback; }
+
+  OCTINTERP_API void execute (const octave_value& data = octave_value ()) const;
+
+  callback_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new callback_property (*this); }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      if (validate (v))
+	{
+	  callback = v;
+	  return true;
+	}
+      else
+        error ("invalid value for callback property \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  OCTINTERP_API bool validate (const octave_value& v) const;
+
+private:
+  octave_value callback;
+};
+
+// ---------------------------------------------------------------------
+
+class property
+{
+public:
+  property (void) : rep (new base_property ("", graphics_handle ()))
+    { }
+
+  property (base_property *bp, bool persist = false) : rep (bp)
+    { if (persist) rep->count++; }
+
+  property (const property& p)
+    {
+      rep = p.rep;
+      rep->count++;
+    }
+
+  ~property (void)
+    {
+      if (--rep->count <= 0)
+        delete rep;
+    }
+
+  bool ok (void) const
+    { return rep->ok (); }
+
+  std::string get_name (void) const
+    { return rep->get_name (); }
+
+  void set_name (const std::string& name)
+    { rep->set_name (name); }
+
+  graphics_handle get_parent (void) const
+    { return rep->get_parent (); }
+
+  void set_parent (const graphics_handle& h)
+    { rep->set_parent (h); }
+
+  bool is_hidden (void) const
+    { return rep->is_hidden (); }
+
+  void set_hidden (bool flag)
+    { rep->set_hidden (flag); }
+
+  int get_id (void) const
+    { return rep->get_id (); }
+
+  void set_id (int d)
+    { rep->set_id (d); }
+
+  octave_value get (void) const
+    { return rep->get (); }
+
+  bool set (const octave_value& val)
+    { return rep->set (val); }
+
+  property& operator = (const octave_value& val)
+    {
+      *rep = val;
+      return *this;
+    }
+
+  property& operator = (const property& p)
+    {
+      if (rep && --rep->count <= 0)
+        delete rep;
+      
+      rep = p.rep;
+      rep->count++;
+
+      return *this;
+    }
+
+  void add_listener (const octave_value& v, listener_mode mode = POSTSET)
+    { rep->add_listener (v, mode); }
+
+  void delete_listener (const octave_value& v = octave_value (), 
+			listener_mode mode = POSTSET)
+  { rep->delete_listener (v, mode); }
+
+  void run_listeners (listener_mode mode = POSTSET)
+    { rep->run_listeners (mode); }
+
+  OCTINTERP_API static
+      property create (const std::string& name, const graphics_handle& parent,
+		       const caseless_str& type,
+		       const octave_value_list& args);
+
+  property clone (void) const
+    { return property (rep->clone ()); }
+
+  /*
+  const string_property& as_string_property (void) const
+    { return *(dynamic_cast<string_property*> (rep)); }
+
+  const radio_property& as_radio_property (void) const
+    { return *(dynamic_cast<radio_property*> (rep)); }
+
+  const color_property& as_color_property (void) const
+    { return *(dynamic_cast<color_property*> (rep)); }
+
+  const double_property& as_double_property (void) const
+    { return *(dynamic_cast<double_property*> (rep)); }
+
+  const bool_property& as_bool_property (void) const
+    { return *(dynamic_cast<bool_property*> (rep)); }
+  
+  const handle_property& as_handle_property (void) const
+    { return *(dynamic_cast<handle_property*> (rep)); }
+    */
+
+private:
+  base_property *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class property_list
+{
+public:
+  typedef std::map<std::string, octave_value> pval_map_type;
+  typedef std::map<std::string, pval_map_type> plist_map_type;
+  
+  typedef pval_map_type::iterator pval_map_iterator;
+  typedef pval_map_type::const_iterator pval_map_const_iterator;
+
+  typedef plist_map_type::iterator plist_map_iterator;
+  typedef plist_map_type::const_iterator plist_map_const_iterator;
+
+  property_list (const plist_map_type& m = plist_map_type ())
+    : plist_map (m) { }
+
+  ~property_list (void) { }
+
+  void set (const caseless_str& name, const octave_value& val);
+
+  octave_value lookup (const caseless_str& name) const;
+
+  plist_map_iterator begin (void) { return plist_map.begin (); }
+  plist_map_const_iterator begin (void) const { return plist_map.begin (); }
+
+  plist_map_iterator end (void) { return plist_map.end (); }
+  plist_map_const_iterator end (void) const { return plist_map.end (); }
+
+  plist_map_iterator find (const std::string& go_name)
+  {
+    return plist_map.find (go_name);
+  }
+
+  plist_map_const_iterator find (const std::string& go_name) const
+  {
+    return plist_map.find (go_name);
+  }
+
+  Octave_map as_struct (const std::string& prefix_arg) const;
+
+private:
+  plist_map_type plist_map;
+};
+
+// ---------------------------------------------------------------------
+
+class graphics_backend;
+class graphics_object;
+
+class base_graphics_backend
+{
+public:
+  friend class graphics_backend;
+
+public:
+  base_graphics_backend (const std::string& nm)
+      : name (nm), count (0) { }
+
+  virtual ~base_graphics_backend (void) { }
+
+  std::string get_name (void) const { return name; }
+
+  virtual bool is_valid (void) const { return false; }
+
+  virtual void redraw_figure (const graphics_object&) const
+    { gripe_invalid ("redraw_figure"); }
+
+  virtual void print_figure (const graphics_object&, const std::string&,
+			     const std::string&, bool,
+			     const std::string& = "") const
+    { gripe_invalid ("print_figure"); }
+
+  virtual Matrix get_canvas_size (const graphics_handle&) const
+    {
+      gripe_invalid ("get_canvas_size");
+      return Matrix (1, 2, 0.0);
+    }
+
+  virtual double get_screen_resolution (void) const
+    {
+      gripe_invalid ("get_screen_resolution");
+      return 72.0;
+    }
+  
+  virtual Matrix get_screen_size (void) const
+    {
+      gripe_invalid ("get_screen_size");
+      return Matrix (1, 2, 0.0);
+    }
+
+  // Called when graphics object using this backend changes it's property.
+  virtual void property_changed (const graphics_object&, int)
+    { gripe_invalid ("property_changed"); }
+
+  void property_changed (const graphics_handle&, int);
+  
+  // Called when new object using this backend is created.
+  virtual void object_created (const graphics_object&)
+    { gripe_invalid ("object_created"); }
+
+  void object_created (const graphics_handle&);
+
+  // Called when object using this backend is destroyed.
+  virtual void object_destroyed (const graphics_object&)
+    { gripe_invalid ("object_destroyed"); }
+
+  void object_destroyed (const graphics_handle&);
+
+private:
+  std::string name;
+  int count;
+
+private:
+  void gripe_invalid (const std::string& fname) const
+    {
+      if (! is_valid ())
+	error ("%s: invalid graphics backend", fname.c_str ());
+    }
+};
+
+class graphics_backend
+{
+public:
+  graphics_backend (void)
+      : rep (new base_graphics_backend ("unknown"))
+    {
+      rep->count++;
+    }
+
+  graphics_backend (base_graphics_backend* b)
+      : rep (b)
+    {
+      rep->count++;
+    }
+
+  graphics_backend (const graphics_backend& b)
+      : rep (b.rep)
+    {
+      rep->count++;
+    }
+
+  ~graphics_backend (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+  graphics_backend& operator = (const graphics_backend& b)
+    {
+      if (rep != b.rep)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = b.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+  operator bool (void) const { return rep->is_valid (); }
+
+  std::string get_name (void) const { return rep->get_name (); }
+
+  void redraw_figure (const graphics_object& go) const
+    { rep->redraw_figure (go); }
+  
+  void print_figure (const graphics_object& go, const std::string& term,
+		     const std::string& file, bool mono,
+		     const std::string& debug_file = "") const
+    { rep->print_figure (go, term, file, mono, debug_file); }
+
+  Matrix get_canvas_size (const graphics_handle& fh) const
+    { return rep->get_canvas_size (fh); }
+
+  double get_screen_resolution (void) const
+    { return rep->get_screen_resolution (); }
+
+  Matrix get_screen_size (void) const
+    { return rep->get_screen_size (); }
+
+  // Notifies backend that object't property has changed.
+  void property_changed (const graphics_object& go, int id)
+    { rep->property_changed (go, id); }
+  
+  void property_changed (const graphics_handle& h, int id)
+    { rep->property_changed (h, id); }
+
+  // Notifies backend that new object was created.
+  void object_created (const graphics_object& go)
+    { rep->object_created (go); }
+  
+  void object_created (const graphics_handle& h)
+    { rep->object_created (h); }
+  
+  // Notifies backend that object was destroyed.
+  // This is called only for explicitly deleted object. Children are
+  // deleted implicitly and backend isn't notified.
+  void object_destroyed (const graphics_object& go)
+    { rep->object_destroyed (go); }
+  
+  void object_destroyed (const graphics_handle& h)
+    { rep->object_destroyed (h); }
+  
+  OCTINTERP_API static graphics_backend default_backend (void);
+
+  static void register_backend (const graphics_backend& b)
+    { available_backends[b.get_name ()] = b; }
+
+  static void unregister_backend (const std::string& name)
+    { available_backends.erase (name); }
+
+  static graphics_backend find_backend (const std::string& name)
+  {
+    const_available_backends_iterator p = available_backends.find (name);
+
+    if (p != available_backends.end ())
+      return p->second;
+    else
+      return default_backend ();
+  }
+
+  static Cell available_backends_list (void)
+  {
+    Cell m (1 , available_backends.size ());
+    const_available_backends_iterator p;
+    int i;
+    
+    for (i = 0,p = available_backends.begin (); p !=  available_backends.end (); p++,i++)
+      m(i) = p->first;
+
+    return m;
+  }
+
+private:
+  base_graphics_backend *rep;
+
+  static OCTINTERP_API std::map<std::string, graphics_backend> available_backends;
+
+  typedef std::map<std::string, graphics_backend>::iterator available_backends_iterator;
+  typedef std::map<std::string, graphics_backend>::const_iterator const_available_backends_iterator;
+};
+
+// ---------------------------------------------------------------------
+
+class base_graphics_object;
+
+class OCTINTERP_API base_properties
+{
+public:
+  base_properties (const std::string& ty = "unknown",
+                   const graphics_handle& mh = graphics_handle (),
+                   const graphics_handle& p = graphics_handle ());
+
+  virtual ~base_properties (void) { }
+
+  virtual std::string graphics_object_name (void) const { return "unknonwn"; }
+
+  void mark_modified (void);
+
+  void override_defaults (base_graphics_object& obj);
+
+  // Look through DEFAULTS for properties with given CLASS_NAME, and
+  // apply them to the current object with set (virtual method).
+
+  void set_from_list (base_graphics_object& obj, property_list& defaults);
+
+  void insert_property (const std::string& name, property p)
+    {
+      p.set_name (name);
+      p.set_parent (__myhandle__);
+      all_props[name] = p;
+    }
+
+  virtual void set (const caseless_str&, const octave_value&)
+  {
+    panic_impossible ();
+  }
+
+  void set (const caseless_str& pname, const std::string& cname,
+	    const octave_value& val);
+
+  virtual octave_value get (const caseless_str& pname) const;
+
+  virtual octave_value get (bool all = false) const;
+
+  virtual property get_property (const caseless_str& pname);
+
+  bool has_property (const caseless_str& pname);
+
+  bool is_modified (void) const { return is___modified__ (); }
+ 
+  virtual void remove_child (const graphics_handle& h);
+
+  virtual void adopt (const graphics_handle& h)
+  {
+    octave_idx_type n = children.numel ();
+    children.resize (n+1, 1);
+    for (octave_idx_type i = n; i > 0; i--)
+      children(i) = children(i-1);
+    children(0) = h.value ();
+    mark_modified ();
+  }
+
+  virtual graphics_backend get_backend (void) const;
+
+  virtual Matrix get_boundingbox (bool /*internal*/ = false) const
+    { return Matrix (1, 4, 0.0); }
+
+  virtual void update_boundingbox (void);
+
+  virtual void add_listener (const caseless_str&, const octave_value&,
+			     listener_mode = POSTSET);
+
+  virtual void delete_listener (const caseless_str&, const octave_value&,
+				listener_mode = POSTSET);
+
+  void set_tag (const octave_value& val) { tag = val; }
+
+  void set_parent (const octave_value& val);
+
+  Matrix get_all_children (void) const { return children; }
+
+  void set_children (const octave_value& val);
+
+  void set_modified (const octave_value& val) { set___modified__ (val); }
+
+  void set___modified__ (const octave_value& val) { __modified__ = val; }
+
+  void reparent (const graphics_handle& new_parent) { parent = new_parent; }
+
+  // Update data limits for AXIS_TYPE (xdata, ydata, etc.) in the parent
+  // axes object.
+
+  virtual void update_axis_limits (const std::string& axis_type) const;
+
+  virtual void delete_children (void);
+
+  static property_list::pval_map_type factory_defaults (void);
+
+  // FIXME -- these functions should be generated automatically by the
+  // genprops.awk script.
+  //
+  // EMIT_BASE_PROPERTIES_GET_FUNCTIONS
+
+  virtual octave_value get_xlim (void) const { return octave_value (); }
+  virtual octave_value get_ylim (void) const { return octave_value (); }
+  virtual octave_value get_zlim (void) const { return octave_value (); }
+  virtual octave_value get_clim (void) const { return octave_value (); }
+  virtual octave_value get_alim (void) const { return octave_value (); }
+
+  virtual bool is_xliminclude (void) const { return false; }
+  virtual bool is_yliminclude (void) const { return false; }
+  virtual bool is_zliminclude (void) const { return false; }
+  virtual bool is_climinclude (void) const { return false; }
+  virtual bool is_aliminclude (void) const { return false; }
+
+  bool is_handle_visible (void) const
+  {
+    return ! handlevisibility.is ("off");
+  }
+
+  static std::map<std::string, std::set<std::string> > all_dynamic_properties;
+ 
+  static bool has_dynamic_property (const std::string& pname,
+				    const std::string& cname);
+
+protected:
+  void set_dynamic (const caseless_str& pname, const std::string& cname,
+		    const octave_value& val);
+
+  octave_value get_dynamic (const caseless_str& pname) const;
+
+  octave_value get_dynamic (bool all = false) const;
+
+  property get_property_dynamic (const caseless_str& pname);
+
+public:
+
+
+  static bool has_property (const std::string& pname, const std::string& cname);
+
+protected:
+
+  bool_property beingdeleted;
+  radio_property busyaction;
+  callback_property buttondownfcn;
+  Matrix children;
+  bool_property clipping;
+  callback_property createfcn;
+  callback_property deletefcn;
+  radio_property handlevisibility;
+  bool_property hittest;
+  bool_property interruptible;
+  handle_property parent;
+  bool_property selected;
+  bool_property selectionhighlight;
+  string_property tag;
+  string_property type;
+  any_property userdata;
+  bool_property visible;
+  bool_property __modified__;
+  graphics_handle __myhandle__;
+  handle_property uicontextmenu;
+
+public:
+
+  enum
+  {
+    BEINGDELETED = 0,
+    BUSYACTION = 1,
+    BUTTONDOWNFCN = 2,
+    CHILDREN = 3,
+    CLIPPING = 4,
+    CREATEFCN = 5,
+    DELETEFCN = 6,
+    HANDLEVISIBILITY = 7,
+    HITTEST = 8,
+    INTERRUPTIBLE = 9,
+    PARENT = 10,
+    SELECTED = 11,
+    SELECTIONHIGHLIGHT = 12,
+    TAG = 13,
+    TYPE = 14,
+    USERDATA = 15,
+    VISIBLE = 16,
+    __MODIFIED__ = 17,
+    __MYHANDLE__ = 18,
+    UICONTEXTMENU = 19
+  };
+
+  bool is_beingdeleted (void) const { return beingdeleted.is_on (); }
+  std::string get_beingdeleted (void) const { return beingdeleted.current_value (); }
+
+  bool busyaction_is (const std::string& v) const { return busyaction.is (v); }
+  std::string get_busyaction (void) const { return busyaction.current_value (); }
+
+  void execute_buttondownfcn (const octave_value& data = octave_value ()) const { buttondownfcn.execute (data); }
+  octave_value get_buttondownfcn (void) const { return buttondownfcn.get (); }
+
+  Matrix get_children (void) const;
+
+  bool is_clipping (void) const { return clipping.is_on (); }
+  std::string get_clipping (void) const { return clipping.current_value (); }
+
+  void execute_createfcn (const octave_value& data = octave_value ()) const { createfcn.execute (data); }
+  octave_value get_createfcn (void) const { return createfcn.get (); }
+
+  void execute_deletefcn (const octave_value& data = octave_value ()) const { deletefcn.execute (data); }
+  octave_value get_deletefcn (void) const { return deletefcn.get (); }
+
+  bool handlevisibility_is (const std::string& v) const { return handlevisibility.is (v); }
+  std::string get_handlevisibility (void) const { return handlevisibility.current_value (); }
+
+  bool is_hittest (void) const { return hittest.is_on (); }
+  std::string get_hittest (void) const { return hittest.current_value (); }
+
+  bool is_interruptible (void) const { return interruptible.is_on (); }
+  std::string get_interruptible (void) const { return interruptible.current_value (); }
+
+  graphics_handle get_parent (void) const { return parent.handle_value (); }
+
+  bool is_selected (void) const { return selected.is_on (); }
+  std::string get_selected (void) const { return selected.current_value (); }
+
+  bool is_selectionhighlight (void) const { return selectionhighlight.is_on (); }
+  std::string get_selectionhighlight (void) const { return selectionhighlight.current_value (); }
+
+  std::string get_tag (void) const { return tag.string_value (); }
+
+  std::string get_type (void) const { return type.string_value (); }
+
+  octave_value get_userdata (void) const { return userdata.get (); }
+
+  bool is_visible (void) const { return visible.is_on (); }
+  std::string get_visible (void) const { return visible.current_value (); }
+
+  bool is___modified__ (void) const { return __modified__.is_on (); }
+  std::string get___modified__ (void) const { return __modified__.current_value (); }
+
+  graphics_handle get___myhandle__ (void) const { return __myhandle__; }
+
+  graphics_handle get_uicontextmenu (void) const { return uicontextmenu.handle_value (); }
+
+
+  void set_beingdeleted (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (beingdeleted.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_busyaction (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (busyaction.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_buttondownfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (buttondownfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_clipping (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (clipping.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_createfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (createfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_deletefcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (deletefcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_handlevisibility (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (handlevisibility.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_hittest (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (hittest.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_interruptible (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (interruptible.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_selected (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (selected.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_selectionhighlight (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (selectionhighlight.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_userdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (userdata.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_visible (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (visible.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_uicontextmenu (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (uicontextmenu.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+
+protected:
+  struct cmp_caseless_str 
+    {
+      bool operator () (const caseless_str &a, const caseless_str &b) const
+        {
+	  std::string a1 = a;
+	  std::transform (a1.begin (), a1.end (), a1.begin (), tolower);
+	  std::string b1 = b;
+	  std::transform (b1.begin (), b1.end (), b1.begin (), tolower);
+
+          return a1 < b1;
+        }
+    };
+
+  std::map<caseless_str, property, cmp_caseless_str> all_props;
+
+protected:
+  void insert_static_property (const std::string& name, base_property& p)
+    { insert_property (name, property (&p, true)); }
+  
+  virtual void init (void) { }
+};
+
+class OCTINTERP_API base_graphics_object
+{
+public:
+  friend class graphics_object;
+
+  base_graphics_object (void) : count (1) { }
+
+  base_graphics_object (const base_graphics_object&) { }
+
+  virtual ~base_graphics_object (void) { }
+
+  virtual void mark_modified (void)
+  {
+    if (valid_object ())
+      get_properties ().mark_modified ();
+    else
+      error ("base_graphics_object::mark_modified: invalid graphics object");
+  }
+
+  virtual void override_defaults (base_graphics_object& obj)
+  {
+    if (valid_object ())
+      get_properties ().override_defaults (obj);
+    else
+      error ("base_graphics_object::override_defaults: invalid graphics object");
+  }
+
+  virtual void set_from_list (property_list& plist)
+  {
+    if (valid_object ())
+      get_properties ().set_from_list (*this, plist);
+    else
+      error ("base_graphics_object::set_from_list: invalid graphics object");
+  }
+
+  virtual void set (const caseless_str& pname, const octave_value& pval)
+  {
+    if (valid_object ())
+      get_properties ().set (pname, pval);
+    else
+      error ("base_graphics_object::set: invalid graphics object");
+  }
+
+  virtual void set_defaults (const std::string&)
+  {
+    error ("base_graphics_object::set_defaults: invalid graphics object");
+  }
+
+  virtual octave_value get (bool all = false) const
+  {
+    if (valid_object ())
+      return get_properties ().get (all);
+    else
+      {
+        error ("base_graphics_object::get: invalid graphics object");
+        return octave_value ();
+      }
+  }
+
+  virtual octave_value get (const caseless_str& pname) const
+  {
+    if (valid_object ())
+      return get_properties ().get (pname);
+    else
+      {
+        error ("base_graphics_object::get: invalid graphics object");
+        return octave_value ();
+      }
+  }
+
+  virtual octave_value get_default (const caseless_str&) const;
+
+  virtual octave_value get_factory_default (const caseless_str&) const;
+
+  virtual octave_value get_defaults (void) const
+  {
+    error ("base_graphics_object::get_defaults: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual octave_value get_factory_defaults (void) const
+  {
+    error ("base_graphics_object::get_factory_defaults: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual graphics_handle get_parent (void) const
+  {
+    if (valid_object ())
+      return get_properties ().get_parent ();
+    else
+      {
+        error ("base_graphics_object::get_parent: invalid graphics object");
+        return graphics_handle ();
+      }
+  }
+
+  graphics_handle get_handle (void) const
+  {
+    if (valid_object ())
+      return get_properties ().get___myhandle__ ();
+    else
+      {
+        error ("base_graphics_object::get_handle: invalid graphics object");
+        return graphics_handle ();
+      }
+  }
+
+  virtual void remove_child (const graphics_handle& h)
+  {
+    if (valid_object ())
+      get_properties ().remove_child (h);
+    else
+      error ("base_graphics_object::remove_child: invalid graphics object");
+  }
+
+  virtual void adopt (const graphics_handle& h)
+  {
+    if (valid_object ())
+      get_properties ().adopt (h);
+    else
+      error ("base_graphics_object::adopt: invalid graphics object");
+  }
+
+  virtual void reparent (const graphics_handle& np)
+  {
+    if (valid_object ())
+      get_properties ().reparent (np);
+    else
+      error ("base_graphics_object::reparent: invalid graphics object");
+  }
+
+  virtual void defaults (void) const
+  {
+    if (valid_object ())
+      {
+        std::string msg = (type () + "::defaults");
+        gripe_not_implemented (msg.c_str ());
+      }
+    else
+      error ("base_graphics_object::default: invalid graphics object");
+  }
+
+  virtual base_properties& get_properties (void)
+  {
+    static base_properties properties;
+    error ("base_graphics_object::get_properties: invalid graphics object");
+    return properties;
+  }
+
+  virtual const base_properties& get_properties (void) const
+  {
+    static base_properties properties;
+    error ("base_graphics_object::get_properties: invalid graphics object");
+    return properties;
+  }
+
+  virtual void update_axis_limits (const std::string& axis_type);
+
+  virtual bool valid_object (void) const { return false; }
+
+  virtual std::string type (void) const
+  {
+    return (valid_object () ? get_properties ().graphics_object_name ()
+        : "unknown");
+  }
+
+  bool isa (const std::string& go_name) const
+  {
+    return type () == go_name;
+  }
+
+  virtual graphics_backend get_backend (void) const
+  {
+    if (valid_object ())
+      return get_properties ().get_backend ();
+    else
+      {
+	error ("base_graphics_object::get_backend: invalid graphics object");
+	return graphics_backend ();
+      }
+  }
+
+  virtual void add_property_listener (const std::string& nm,
+				      const octave_value& v,
+				      listener_mode mode = POSTSET)
+    {
+      if (valid_object ())
+	get_properties ().add_listener (nm, v, mode);
+    }
+
+  virtual void delete_property_listener (const std::string& nm,
+					 const octave_value& v,
+					 listener_mode mode = POSTSET)
+    {
+      if (valid_object ())
+	get_properties ().delete_listener (nm, v, mode);
+    }
+
+  virtual void remove_all_listeners (void);
+
+protected:
+  // A reference count.
+  int count;
+};
+
+class OCTINTERP_API graphics_object
+{
+public:
+  graphics_object (void) : rep (new base_graphics_object ()) { }
+
+  graphics_object (base_graphics_object *new_rep)
+    : rep (new_rep) { }
+
+  graphics_object (const graphics_object& obj)
+  {
+    rep = obj.rep;
+    rep->count++;
+  }
+
+  graphics_object& operator = (const graphics_object& obj)
+  {
+    if (rep != obj.rep)
+      {
+	if (--rep->count == 0)
+	  delete rep;
+
+	rep = obj.rep;
+	rep->count++;
+      }
+
+    return *this;
+  }
+
+  ~graphics_object (void)
+  {
+    if (--rep->count == 0)
+      delete rep;
+  }
+
+  void mark_modified (void) { rep->mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    rep->override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist) { rep->set_from_list (plist); }
+
+  void set (const caseless_str& name, const octave_value& val)
+  {
+    rep->set (name, val);
+  }
+
+  void set (const octave_value_list& args);
+
+  void set_defaults (const std::string& mode) { rep->set_defaults (mode); }
+
+  octave_value get (bool all = false) const { return rep->get (all); }
+
+  octave_value get (const caseless_str& name) const
+  {
+    return name.compare ("default")
+      ? get_defaults ()
+      : (name.compare ("factory")
+	 ? get_factory_defaults () : rep->get (name));
+  }
+
+  octave_value get_default (const caseless_str& name) const
+  {
+    return rep->get_default (name);
+  }
+
+  octave_value get_factory_default (const caseless_str& name) const
+  {
+    return rep->get_factory_default (name);
+  }
+
+  octave_value get_defaults (void) const { return rep->get_defaults (); }
+
+  octave_value get_factory_defaults (void) const
+  {
+    return rep->get_factory_defaults ();
+  }
+
+  graphics_handle get_parent (void) const { return rep->get_parent (); }
+
+  graphics_handle get_handle (void) const { return rep->get_handle (); }
+
+  void remove_child (const graphics_handle& h) { rep->remove_child (h); }
+
+  void adopt (const graphics_handle& h) { rep->adopt (h); }
+
+  void reparent (const graphics_handle& h) { rep->reparent (h); }
+
+  void defaults (void) const { rep->defaults (); }
+
+  bool isa (const std::string& go_name) const { return rep->isa (go_name); }
+
+  base_properties& get_properties (void) { return rep->get_properties (); }
+
+  const base_properties& get_properties (void) const
+  {
+    return rep->get_properties ();
+  }
+
+  void update_axis_limits (const std::string& axis_type)
+  {
+    rep->update_axis_limits (axis_type);
+  }
+
+  bool valid_object (void) const { return rep->valid_object (); }
+
+  std::string type (void) const { return rep->type (); }
+
+  operator bool (void) const { return rep->valid_object (); }
+
+  // FIXME -- these functions should be generated automatically by the
+  // genprops.awk script.
+  //
+  // EMIT_GRAPHICS_OBJECT_GET_FUNCTIONS
+
+  octave_value get_xlim (void) const
+  { return get_properties ().get_xlim (); }
+
+  octave_value get_ylim (void) const
+  { return get_properties ().get_ylim (); }
+  
+  octave_value get_zlim (void) const
+  { return get_properties ().get_zlim (); }
+  
+  octave_value get_clim (void) const
+  { return get_properties ().get_clim (); }
+  
+  octave_value get_alim (void) const
+  { return get_properties ().get_alim (); }
+
+  bool is_xliminclude (void) const
+  { return get_properties ().is_xliminclude (); }
+  
+  bool is_yliminclude (void) const
+  { return get_properties ().is_yliminclude (); }
+  
+  bool is_zliminclude (void) const
+  { return get_properties ().is_zliminclude (); }
+  
+  bool is_climinclude (void) const
+  { return get_properties ().is_climinclude (); }
+  
+  bool is_aliminclude (void) const
+  { return get_properties ().is_aliminclude (); }
+
+  bool is_handle_visible (void) const
+  { return get_properties ().is_handle_visible (); }
+  
+  graphics_backend get_backend (void) const { return rep->get_backend (); }
+
+  void add_property_listener (const std::string& nm, const octave_value& v,
+			      listener_mode mode = POSTSET)
+    { rep->add_property_listener (nm, v, mode); }
+
+  void delete_property_listener (const std::string& nm, const octave_value& v,
+				 listener_mode mode = POSTSET)
+    { rep->delete_property_listener (nm, v, mode); }
+
+private:
+  base_graphics_object *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API root_figure : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void remove_child (const graphics_handle& h);
+    
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  handle_property currentfigure;
+  handle_property callbackobject;
+  double_property screendepth;
+  array_property screensize;
+  double_property screenpixelsperinch;
+  radio_property units;
+  bool_property showhiddenhandles;
+
+public:
+
+  enum
+  {
+    CURRENTFIGURE = 1000,
+    CALLBACKOBJECT = 1001,
+    SCREENDEPTH = 1002,
+    SCREENSIZE = 1003,
+    SCREENPIXELSPERINCH = 1004,
+    UNITS = 1005,
+    SHOWHIDDENHANDLES = 1006
+  };
+
+  graphics_handle get_currentfigure (void) const { return currentfigure.handle_value (); }
+
+  graphics_handle get_callbackobject (void) const { return callbackobject.handle_value (); }
+
+  double get_screendepth (void) const { return screendepth.double_value (); }
+
+  octave_value get_screensize (void) const { return screensize.get (); }
+
+  double get_screenpixelsperinch (void) const { return screenpixelsperinch.double_value (); }
+
+  bool units_is (const std::string& v) const { return units.is (v); }
+  std::string get_units (void) const { return units.current_value (); }
+
+  bool is_showhiddenhandles (void) const { return showhiddenhandles.is_on (); }
+  std::string get_showhiddenhandles (void) const { return showhiddenhandles.current_value (); }
+
+
+  void set_currentfigure (const octave_value& val);
+
+  void set_callbackobject (const octave_value& val);
+
+  void set_screendepth (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (screendepth.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_screensize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (screensize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_screenpixelsperinch (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (screenpixelsperinch.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_units (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (units.set (val, true))
+          {
+            update_units ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void update_units (void);
+
+  void set_showhiddenhandles (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (showhiddenhandles.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+
+  private:
+    std::list<graphics_handle> cbo_stack;
+  };
+
+private:
+  properties xproperties;
+
+public:
+
+  root_figure (void) : xproperties (0, graphics_handle ()), default_properties () { }
+
+  ~root_figure (void) { xproperties.delete_children (); }
+
+  void mark_modified (void) { }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set (const caseless_str& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  octave_value get (const caseless_str& name) const
+  {
+    octave_value retval;
+
+    if (name.compare ("default", 7))
+      return get_default (name.substr (7));
+    else if (name.compare ("factory", 7))
+      return get_factory_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const caseless_str& name) const
+  {
+    octave_value retval = default_properties.lookup (name);
+
+    if (retval.is_undefined ())
+      {
+	// no default property found, use factory default
+	retval = factory_properties.lookup (name);
+
+	if (retval.is_undefined ())
+	  error ("get: invalid default property `%s'", name.c_str ());
+      }
+
+    return retval;
+  }
+
+  octave_value get_factory_default (const caseless_str& name) const
+  {
+    octave_value retval = factory_properties.lookup (name);
+
+    if (retval.is_undefined ())
+      error ("get: invalid factory default property `%s'", name.c_str ());
+
+    return retval;
+  }
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  octave_value get_factory_defaults (void) const
+  {
+    return factory_properties.as_struct ("factory");
+  }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+
+  static property_list factory_properties;
+
+  static property_list::plist_map_type init_factory_properties (void);
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API figure : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void remove_child (const graphics_handle& h);
+
+    void set_visible (const octave_value& val);
+
+    graphics_backend get_backend (void) const
+      {
+	if (! backend)
+	  backend = graphics_backend::default_backend ();
+
+	return backend;
+      }
+
+    void set_backend (const graphics_backend& b) 
+    { 
+      if (backend)
+	backend.object_destroyed (__myhandle__);
+      backend = b; 
+      __backend__ = b.get_name ();
+      __plot_stream__ = Matrix ();
+      mark_modified ();
+    }
+
+    void set___backend__ (const octave_value& val)
+    {
+      if (! error_state)
+	{
+	  if (val.is_string ())
+	    {
+	      std::string nm = val.string_value ();
+	      graphics_backend b = graphics_backend::find_backend (nm);
+	      if (b.get_name () != nm)
+		{
+		  error ("set___backend__: invalid backend");
+		}
+	      else
+		{
+		  set_backend (b);
+		  mark_modified ();
+		}
+	    }
+	  else
+	    error ("set___backend__ must be a string");
+	}
+    }
+
+    Matrix get_boundingbox (bool internal = false) const;
+
+    void set_boundingbox (const Matrix& bb);
+
+    std::string get_title (void) const;
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  any_property __plot_stream__;
+  bool_property __enhanced__;
+  radio_property nextplot;
+  callback_property closerequestfcn;
+  handle_property currentaxes;
+  array_property colormap;
+  radio_property paperorientation;
+  color_property color;
+  array_property alphamap;
+  string_property currentcharacter;
+  handle_property currentobject;
+  array_property current_point;
+  bool_property dockcontrols;
+  bool_property doublebuffer;
+  string_property filename;
+  bool_property integerhandle;
+  bool_property inverthardcopy;
+  callback_property keypressfcn;
+  callback_property keyreleasefcn;
+  radio_property menubar;
+  double_property mincolormap;
+  string_property name;
+  bool_property numbertitle;
+  radio_property paperunits;
+  array_property paperposition;
+  radio_property paperpositionmode;
+  array_property papersize;
+  radio_property papertype;
+  radio_property pointer;
+  array_property pointershapecdata;
+  array_property pointershapehotspot;
+  array_property position;
+  radio_property renderer;
+  radio_property renderermode;
+  bool_property resize;
+  callback_property resizefcn;
+  radio_property selectiontype;
+  radio_property toolbar;
+  radio_property units;
+  callback_property windowbuttondownfcn;
+  callback_property windowbuttonmotionfcn;
+  callback_property windowbuttonupfcn;
+  callback_property windowbuttonwheelfcn;
+  radio_property windowstyle;
+  string_property wvisual;
+  radio_property wvisualmode;
+  string_property xdisplay;
+  string_property xvisual;
+  radio_property xvisualmode;
+  callback_property buttondownfcn;
+  string_property __backend__;
+
+public:
+
+  enum
+  {
+    __PLOT_STREAM__ = 2000,
+    __ENHANCED__ = 2001,
+    NEXTPLOT = 2002,
+    CLOSEREQUESTFCN = 2003,
+    CURRENTAXES = 2004,
+    COLORMAP = 2005,
+    PAPERORIENTATION = 2006,
+    COLOR = 2007,
+    ALPHAMAP = 2008,
+    CURRENTCHARACTER = 2009,
+    CURRENTOBJECT = 2010,
+    CURRENT_POINT = 2011,
+    DOCKCONTROLS = 2012,
+    DOUBLEBUFFER = 2013,
+    FILENAME = 2014,
+    INTEGERHANDLE = 2015,
+    INVERTHARDCOPY = 2016,
+    KEYPRESSFCN = 2017,
+    KEYRELEASEFCN = 2018,
+    MENUBAR = 2019,
+    MINCOLORMAP = 2020,
+    NAME = 2021,
+    NUMBERTITLE = 2022,
+    PAPERUNITS = 2023,
+    PAPERPOSITION = 2024,
+    PAPERPOSITIONMODE = 2025,
+    PAPERSIZE = 2026,
+    PAPERTYPE = 2027,
+    POINTER = 2028,
+    POINTERSHAPECDATA = 2029,
+    POINTERSHAPEHOTSPOT = 2030,
+    POSITION = 2031,
+    RENDERER = 2032,
+    RENDERERMODE = 2033,
+    RESIZE = 2034,
+    RESIZEFCN = 2035,
+    SELECTIONTYPE = 2036,
+    TOOLBAR = 2037,
+    UNITS = 2038,
+    WINDOWBUTTONDOWNFCN = 2039,
+    WINDOWBUTTONMOTIONFCN = 2040,
+    WINDOWBUTTONUPFCN = 2041,
+    WINDOWBUTTONWHEELFCN = 2042,
+    WINDOWSTYLE = 2043,
+    WVISUAL = 2044,
+    WVISUALMODE = 2045,
+    XDISPLAY = 2046,
+    XVISUAL = 2047,
+    XVISUALMODE = 2048,
+    BUTTONDOWNFCN = 2049,
+    __BACKEND__ = 2050
+  };
+
+  octave_value get___plot_stream__ (void) const { return __plot_stream__.get (); }
+
+  bool is___enhanced__ (void) const { return __enhanced__.is_on (); }
+  std::string get___enhanced__ (void) const { return __enhanced__.current_value (); }
+
+  bool nextplot_is (const std::string& v) const { return nextplot.is (v); }
+  std::string get_nextplot (void) const { return nextplot.current_value (); }
+
+  void execute_closerequestfcn (const octave_value& data = octave_value ()) const { closerequestfcn.execute (data); }
+  octave_value get_closerequestfcn (void) const { return closerequestfcn.get (); }
+
+  graphics_handle get_currentaxes (void) const { return currentaxes.handle_value (); }
+
+  octave_value get_colormap (void) const { return colormap.get (); }
+
+  bool paperorientation_is (const std::string& v) const { return paperorientation.is (v); }
+  std::string get_paperorientation (void) const { return paperorientation.current_value (); }
+
+  bool color_is_rgb (void) const { return color.is_rgb (); }
+  bool color_is (const std::string& v) const { return color.is (v); }
+  Matrix get_color_rgb (void) const { return (color.is_rgb () ? color.rgb () : Matrix ()); }
+  octave_value get_color (void) const { return color.get (); }
+
+  octave_value get_alphamap (void) const { return alphamap.get (); }
+
+  std::string get_currentcharacter (void) const { return currentcharacter.string_value (); }
+
+  graphics_handle get_currentobject (void) const { return currentobject.handle_value (); }
+
+  octave_value get_current_point (void) const { return current_point.get (); }
+
+  bool is_dockcontrols (void) const { return dockcontrols.is_on (); }
+  std::string get_dockcontrols (void) const { return dockcontrols.current_value (); }
+
+  bool is_doublebuffer (void) const { return doublebuffer.is_on (); }
+  std::string get_doublebuffer (void) const { return doublebuffer.current_value (); }
+
+  std::string get_filename (void) const { return filename.string_value (); }
+
+  bool is_integerhandle (void) const { return integerhandle.is_on (); }
+  std::string get_integerhandle (void) const { return integerhandle.current_value (); }
+
+  bool is_inverthardcopy (void) const { return inverthardcopy.is_on (); }
+  std::string get_inverthardcopy (void) const { return inverthardcopy.current_value (); }
+
+  void execute_keypressfcn (const octave_value& data = octave_value ()) const { keypressfcn.execute (data); }
+  octave_value get_keypressfcn (void) const { return keypressfcn.get (); }
+
+  void execute_keyreleasefcn (const octave_value& data = octave_value ()) const { keyreleasefcn.execute (data); }
+  octave_value get_keyreleasefcn (void) const { return keyreleasefcn.get (); }
+
+  bool menubar_is (const std::string& v) const { return menubar.is (v); }
+  std::string get_menubar (void) const { return menubar.current_value (); }
+
+  double get_mincolormap (void) const { return mincolormap.double_value (); }
+
+  std::string get_name (void) const { return name.string_value (); }
+
+  bool is_numbertitle (void) const { return numbertitle.is_on (); }
+  std::string get_numbertitle (void) const { return numbertitle.current_value (); }
+
+  bool paperunits_is (const std::string& v) const { return paperunits.is (v); }
+  std::string get_paperunits (void) const { return paperunits.current_value (); }
+
+  octave_value get_paperposition (void) const { return paperposition.get (); }
+
+  bool paperpositionmode_is (const std::string& v) const { return paperpositionmode.is (v); }
+  std::string get_paperpositionmode (void) const { return paperpositionmode.current_value (); }
+
+  octave_value get_papersize (void) const { return papersize.get (); }
+
+  bool papertype_is (const std::string& v) const { return papertype.is (v); }
+  std::string get_papertype (void) const { return papertype.current_value (); }
+
+  bool pointer_is (const std::string& v) const { return pointer.is (v); }
+  std::string get_pointer (void) const { return pointer.current_value (); }
+
+  octave_value get_pointershapecdata (void) const { return pointershapecdata.get (); }
+
+  octave_value get_pointershapehotspot (void) const { return pointershapehotspot.get (); }
+
+  octave_value get_position (void) const { return position.get (); }
+
+  bool renderer_is (const std::string& v) const { return renderer.is (v); }
+  std::string get_renderer (void) const { return renderer.current_value (); }
+
+  bool renderermode_is (const std::string& v) const { return renderermode.is (v); }
+  std::string get_renderermode (void) const { return renderermode.current_value (); }
+
+  bool is_resize (void) const { return resize.is_on (); }
+  std::string get_resize (void) const { return resize.current_value (); }
+
+  void execute_resizefcn (const octave_value& data = octave_value ()) const { resizefcn.execute (data); }
+  octave_value get_resizefcn (void) const { return resizefcn.get (); }
+
+  bool selectiontype_is (const std::string& v) const { return selectiontype.is (v); }
+  std::string get_selectiontype (void) const { return selectiontype.current_value (); }
+
+  bool toolbar_is (const std::string& v) const { return toolbar.is (v); }
+  std::string get_toolbar (void) const { return toolbar.current_value (); }
+
+  bool units_is (const std::string& v) const { return units.is (v); }
+  std::string get_units (void) const { return units.current_value (); }
+
+  void execute_windowbuttondownfcn (const octave_value& data = octave_value ()) const { windowbuttondownfcn.execute (data); }
+  octave_value get_windowbuttondownfcn (void) const { return windowbuttondownfcn.get (); }
+
+  void execute_windowbuttonmotionfcn (const octave_value& data = octave_value ()) const { windowbuttonmotionfcn.execute (data); }
+  octave_value get_windowbuttonmotionfcn (void) const { return windowbuttonmotionfcn.get (); }
+
+  void execute_windowbuttonupfcn (const octave_value& data = octave_value ()) const { windowbuttonupfcn.execute (data); }
+  octave_value get_windowbuttonupfcn (void) const { return windowbuttonupfcn.get (); }
+
+  void execute_windowbuttonwheelfcn (const octave_value& data = octave_value ()) const { windowbuttonwheelfcn.execute (data); }
+  octave_value get_windowbuttonwheelfcn (void) const { return windowbuttonwheelfcn.get (); }
+
+  bool windowstyle_is (const std::string& v) const { return windowstyle.is (v); }
+  std::string get_windowstyle (void) const { return windowstyle.current_value (); }
+
+  std::string get_wvisual (void) const { return wvisual.string_value (); }
+
+  bool wvisualmode_is (const std::string& v) const { return wvisualmode.is (v); }
+  std::string get_wvisualmode (void) const { return wvisualmode.current_value (); }
+
+  std::string get_xdisplay (void) const { return xdisplay.string_value (); }
+
+  std::string get_xvisual (void) const { return xvisual.string_value (); }
+
+  bool xvisualmode_is (const std::string& v) const { return xvisualmode.is (v); }
+  std::string get_xvisualmode (void) const { return xvisualmode.current_value (); }
+
+  void execute_buttondownfcn (const octave_value& data = octave_value ()) const { buttondownfcn.execute (data); }
+  octave_value get_buttondownfcn (void) const { return buttondownfcn.get (); }
+
+  std::string get___backend__ (void) const { return __backend__.string_value (); }
+
+
+  void set___plot_stream__ (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (__plot_stream__.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set___enhanced__ (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (__enhanced__.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_nextplot (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (nextplot.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_closerequestfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (closerequestfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_currentaxes (const octave_value& val);
+
+  void set_colormap (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (colormap.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_paperorientation (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (paperorientation.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_color (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (color.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alphamap (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alphamap.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_currentcharacter (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (currentcharacter.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_currentobject (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (currentobject.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_current_point (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (current_point.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_dockcontrols (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (dockcontrols.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_doublebuffer (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (doublebuffer.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_filename (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (filename.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_integerhandle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (integerhandle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_inverthardcopy (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (inverthardcopy.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keypressfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keypressfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keyreleasefcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keyreleasefcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_menubar (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (menubar.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_mincolormap (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (mincolormap.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_name (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (name.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_numbertitle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (numbertitle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_paperunits (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (paperunits.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_paperposition (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (paperposition.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_paperpositionmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (paperpositionmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_papersize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (papersize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_papertype (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (papertype.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_pointer (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (pointer.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_pointershapecdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (pointershapecdata.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_pointershapehotspot (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (pointershapehotspot.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_position (const octave_value& val);
+
+  void set_renderer (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (renderer.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_renderermode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (renderermode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_resize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (resize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_resizefcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (resizefcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_selectiontype (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (selectiontype.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_toolbar (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (toolbar.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_units (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (units.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_windowbuttondownfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (windowbuttondownfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_windowbuttonmotionfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (windowbuttonmotionfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_windowbuttonupfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (windowbuttonupfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_windowbuttonwheelfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (windowbuttonwheelfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_windowstyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (windowstyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_wvisual (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (wvisual.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_wvisualmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (wvisualmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xdisplay (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdisplay.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xvisual (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xvisual.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xvisualmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xvisualmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_buttondownfcn (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (buttondownfcn.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+    
+  protected:
+    void init (void)
+      {
+        colormap.add_constraint (dim_vector (-1, 3));
+	alphamap.add_constraint (dim_vector (-1, 1));
+	paperposition.add_constraint (dim_vector (1, 4));
+	pointershapecdata.add_constraint (dim_vector (16, 16));
+	pointershapehotspot.add_constraint (dim_vector (1, 2));
+	position.add_constraint (dim_vector (1, 4));
+      }
+
+  private:
+    mutable graphics_backend backend;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  figure (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p), default_properties ()
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~figure (void)
+  {
+    xproperties.delete_children (); 
+  }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (root figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set (const caseless_str& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  octave_value get (const caseless_str& name) const
+  {
+    octave_value retval;
+
+    if (name.compare ("default", 7))
+      retval = get_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const caseless_str& name) const;
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API graphics_xform
+{
+public:
+  graphics_xform (void)
+      : xform (xform_eye ()), xform_inv (xform_eye ())
+    {
+      sx = sy = sz = "linear";
+    }
+
+  graphics_xform (const Matrix& xm, const Matrix& xim,
+		  const scaler& x, const scaler& y, const scaler& z)
+      : xform (xm), xform_inv (xim), sx (x), sy (y), sz (z) { }
+
+  graphics_xform (const graphics_xform& g)
+      : xform (g.xform), xform_inv (g.xform_inv), sx (g.sx),
+        sy (g.sy), sz (g.sz) { }
+
+  ~graphics_xform (void) { }
+
+  graphics_xform& operator = (const graphics_xform& g)
+    {
+      xform = g.xform;
+      xform_inv = g.xform_inv;
+      sx = g.sx;
+      sy = g.sy;
+      sz = g.sz;
+
+      return *this;
+    }
+
+  static ColumnVector xform_vector (double x, double y, double z);
+
+  static Matrix xform_eye (void);
+
+  ColumnVector transform (double x, double y, double z,
+			  bool scale = true) const;
+  
+  ColumnVector untransform (double x, double y, double z,
+			    bool scale = true) const;
+
+  Matrix xscale (const Matrix& m) const { return sx.scale (m); }
+  Matrix yscale (const Matrix& m) const { return sy.scale (m); }
+  Matrix zscale (const Matrix& m) const { return sz.scale (m); }
+
+  Matrix scale (const Matrix& m) const
+    {
+      bool has_z = (m.columns () > 2);
+
+      if (sx.is_linear () && sy.is_linear ()
+	  && (! has_z || sz.is_linear ()))
+	return m;
+
+      Matrix retval (m.dims ());
+
+      int r = m.rows ();
+
+      for (int i = 0; i < r; i++)
+	{
+	  retval(i,0) = sx.scale (m(i,0));
+	  retval(i,1) = sy.scale (m(i,1));
+	  if (has_z)
+	    retval(i,2) = sz.scale (m(i,2));
+	}
+
+      return retval;
+    }
+
+private:
+  Matrix xform;
+  Matrix xform_inv;
+  scaler sx, sy, sz;
+};
+
+class OCTINTERP_API axes : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void set_defaults (base_graphics_object& obj, const std::string& mode);
+
+    void remove_child (const graphics_handle& h);
+
+    const scaler& get_x_scaler (void) const { return sx; }
+    const scaler& get_y_scaler (void) const { return sy; }
+    const scaler& get_z_scaler (void) const { return sz; }
+
+    Matrix get_boundingbox (bool internal = false) const;
+
+    void update_boundingbox (void)
+      {
+	if (units_is ("normalized"))
+	  {
+	    update_transform ();
+	    base_properties::update_boundingbox ();
+	  }
+      }
+
+    void update_camera (void);
+    void update_aspectratios (void);
+    void update_transform (void)
+      {
+	update_aspectratios ();
+	update_camera ();
+      }
+
+    graphics_xform get_transform (void) const
+      { return graphics_xform (x_render, x_render_inv, sx, sy, sz); }
+
+    Matrix get_transform_matrix (void) const { return x_render; }
+    Matrix get_inverse_transform_matrix (void) const { return x_render_inv; }
+    Matrix get_opengl_matrix_1 (void) const { return x_gl_mat1; }
+    Matrix get_opengl_matrix_2 (void) const { return x_gl_mat2; }
+    Matrix get_transform_zlim (void) const { return x_zlim; }
+
+    ColumnVector pixel2coord (double px, double py) const
+    { return get_transform ().untransform (px, py, (x_zlim(0)+x_zlim(1))/2); }
+
+    ColumnVector coord2pixel (double x, double y, double z) const
+    { return get_transform ().transform (x, y, z); }
+
+    void zoom (const Matrix& xl, const Matrix& yl);
+    void unzoom (void);
+    void clear_zoom_stack (void);
+
+  private:
+    scaler sx, sy, sz;
+    Matrix x_render, x_render_inv;
+    Matrix x_gl_mat1, x_gl_mat2;
+    Matrix x_zlim;
+    std::list<octave_value> zoom_stack;
+
+    void set_text_child (handle_property& h, const std::string& who,
+			 const octave_value& v);
+
+    void delete_text_child (handle_property& h);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    // properties which are not in matlab: interpreter
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  array_property position;
+  bool_property box;
+  bool_property key;
+  bool_property keybox;
+  bool_property keyreverse;
+  any_property keypos;
+  array_property colororder;
+  array_property dataaspectratio;
+  radio_property dataaspectratiomode;
+  radio_property layer;
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property zlim;
+  row_vector_property clim;
+  row_vector_property alim;
+  radio_property xlimmode;
+  radio_property ylimmode;
+  radio_property zlimmode;
+  radio_property climmode;
+  radio_property alimmode;
+  handle_property xlabel;
+  handle_property ylabel;
+  handle_property zlabel;
+  handle_property title;
+  bool_property xgrid;
+  bool_property ygrid;
+  bool_property zgrid;
+  bool_property xminorgrid;
+  bool_property yminorgrid;
+  bool_property zminorgrid;
+  row_vector_property xtick;
+  row_vector_property ytick;
+  row_vector_property ztick;
+  radio_property xtickmode;
+  radio_property ytickmode;
+  radio_property ztickmode;
+  bool_property xminortick;
+  bool_property yminortick;
+  bool_property zminortick;
+  any_property xticklabel;
+  any_property yticklabel;
+  any_property zticklabel;
+  radio_property xticklabelmode;
+  radio_property yticklabelmode;
+  radio_property zticklabelmode;
+  radio_property interpreter;
+  color_property color;
+  color_property xcolor;
+  color_property ycolor;
+  color_property zcolor;
+  radio_property xscale;
+  radio_property yscale;
+  radio_property zscale;
+  radio_property xdir;
+  radio_property ydir;
+  radio_property zdir;
+  radio_property yaxislocation;
+  radio_property xaxislocation;
+  array_property view;
+  radio_property nextplot;
+  array_property outerposition;
+  radio_property activepositionproperty;
+  color_property ambientlightcolor;
+  array_property cameraposition;
+  array_property cameratarget;
+  array_property cameraupvector;
+  double_property cameraviewangle;
+  radio_property camerapositionmode;
+  radio_property cameratargetmode;
+  radio_property cameraupvectormode;
+  radio_property cameraviewanglemode;
+  array_property currentpoint;
+  radio_property drawmode;
+  radio_property fontangle;
+  string_property fontname;
+  double_property fontsize;
+  radio_property fontunits;
+  radio_property fontweight;
+  radio_property gridlinestyle;
+  string_property linestyleorder;
+  double_property linewidth;
+  radio_property minorgridlinestyle;
+  array_property plotboxaspectratio;
+  radio_property plotboxaspectratiomode;
+  radio_property projection;
+  radio_property tickdir;
+  radio_property tickdirmode;
+  array_property ticklength;
+  array_property tightinset;
+  radio_property units;
+  array_property x_viewtransform;
+  array_property x_projectiontransform;
+  array_property x_viewporttransform;
+  array_property x_normrendertransform;
+  array_property x_rendertransform;
+
+public:
+
+  enum
+  {
+    POSITION = 3000,
+    BOX = 3001,
+    KEY = 3002,
+    KEYBOX = 3003,
+    KEYREVERSE = 3004,
+    KEYPOS = 3005,
+    COLORORDER = 3006,
+    DATAASPECTRATIO = 3007,
+    DATAASPECTRATIOMODE = 3008,
+    LAYER = 3009,
+    XLIM = 3010,
+    YLIM = 3011,
+    ZLIM = 3012,
+    CLIM = 3013,
+    ALIM = 3014,
+    XLIMMODE = 3015,
+    YLIMMODE = 3016,
+    ZLIMMODE = 3017,
+    CLIMMODE = 3018,
+    ALIMMODE = 3019,
+    XLABEL = 3020,
+    YLABEL = 3021,
+    ZLABEL = 3022,
+    TITLE = 3023,
+    XGRID = 3024,
+    YGRID = 3025,
+    ZGRID = 3026,
+    XMINORGRID = 3027,
+    YMINORGRID = 3028,
+    ZMINORGRID = 3029,
+    XTICK = 3030,
+    YTICK = 3031,
+    ZTICK = 3032,
+    XTICKMODE = 3033,
+    YTICKMODE = 3034,
+    ZTICKMODE = 3035,
+    XMINORTICK = 3036,
+    YMINORTICK = 3037,
+    ZMINORTICK = 3038,
+    XTICKLABEL = 3039,
+    YTICKLABEL = 3040,
+    ZTICKLABEL = 3041,
+    XTICKLABELMODE = 3042,
+    YTICKLABELMODE = 3043,
+    ZTICKLABELMODE = 3044,
+    INTERPRETER = 3045,
+    COLOR = 3046,
+    XCOLOR = 3047,
+    YCOLOR = 3048,
+    ZCOLOR = 3049,
+    XSCALE = 3050,
+    YSCALE = 3051,
+    ZSCALE = 3052,
+    XDIR = 3053,
+    YDIR = 3054,
+    ZDIR = 3055,
+    YAXISLOCATION = 3056,
+    XAXISLOCATION = 3057,
+    VIEW = 3058,
+    NEXTPLOT = 3059,
+    OUTERPOSITION = 3060,
+    ACTIVEPOSITIONPROPERTY = 3061,
+    AMBIENTLIGHTCOLOR = 3062,
+    CAMERAPOSITION = 3063,
+    CAMERATARGET = 3064,
+    CAMERAUPVECTOR = 3065,
+    CAMERAVIEWANGLE = 3066,
+    CAMERAPOSITIONMODE = 3067,
+    CAMERATARGETMODE = 3068,
+    CAMERAUPVECTORMODE = 3069,
+    CAMERAVIEWANGLEMODE = 3070,
+    CURRENTPOINT = 3071,
+    DRAWMODE = 3072,
+    FONTANGLE = 3073,
+    FONTNAME = 3074,
+    FONTSIZE = 3075,
+    FONTUNITS = 3076,
+    FONTWEIGHT = 3077,
+    GRIDLINESTYLE = 3078,
+    LINESTYLEORDER = 3079,
+    LINEWIDTH = 3080,
+    MINORGRIDLINESTYLE = 3081,
+    PLOTBOXASPECTRATIO = 3082,
+    PLOTBOXASPECTRATIOMODE = 3083,
+    PROJECTION = 3084,
+    TICKDIR = 3085,
+    TICKDIRMODE = 3086,
+    TICKLENGTH = 3087,
+    TIGHTINSET = 3088,
+    UNITS = 3089,
+    X_VIEWTRANSFORM = 3090,
+    X_PROJECTIONTRANSFORM = 3091,
+    X_VIEWPORTTRANSFORM = 3092,
+    X_NORMRENDERTRANSFORM = 3093,
+    X_RENDERTRANSFORM = 3094
+  };
+
+  octave_value get_position (void) const { return position.get (); }
+
+  bool is_box (void) const { return box.is_on (); }
+  std::string get_box (void) const { return box.current_value (); }
+
+  bool is_key (void) const { return key.is_on (); }
+  std::string get_key (void) const { return key.current_value (); }
+
+  bool is_keybox (void) const { return keybox.is_on (); }
+  std::string get_keybox (void) const { return keybox.current_value (); }
+
+  bool is_keyreverse (void) const { return keyreverse.is_on (); }
+  std::string get_keyreverse (void) const { return keyreverse.current_value (); }
+
+  octave_value get_keypos (void) const { return keypos.get (); }
+
+  octave_value get_colororder (void) const { return colororder.get (); }
+
+  octave_value get_dataaspectratio (void) const { return dataaspectratio.get (); }
+
+  bool dataaspectratiomode_is (const std::string& v) const { return dataaspectratiomode.is (v); }
+  std::string get_dataaspectratiomode (void) const { return dataaspectratiomode.current_value (); }
+
+  bool layer_is (const std::string& v) const { return layer.is (v); }
+  std::string get_layer (void) const { return layer.current_value (); }
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_zlim (void) const { return zlim.get (); }
+
+  octave_value get_clim (void) const { return clim.get (); }
+
+  octave_value get_alim (void) const { return alim.get (); }
+
+  bool xlimmode_is (const std::string& v) const { return xlimmode.is (v); }
+  std::string get_xlimmode (void) const { return xlimmode.current_value (); }
+
+  bool ylimmode_is (const std::string& v) const { return ylimmode.is (v); }
+  std::string get_ylimmode (void) const { return ylimmode.current_value (); }
+
+  bool zlimmode_is (const std::string& v) const { return zlimmode.is (v); }
+  std::string get_zlimmode (void) const { return zlimmode.current_value (); }
+
+  bool climmode_is (const std::string& v) const { return climmode.is (v); }
+  std::string get_climmode (void) const { return climmode.current_value (); }
+
+  bool alimmode_is (const std::string& v) const { return alimmode.is (v); }
+  std::string get_alimmode (void) const { return alimmode.current_value (); }
+
+  graphics_handle get_xlabel (void) const { return xlabel.handle_value (); }
+
+  graphics_handle get_ylabel (void) const { return ylabel.handle_value (); }
+
+  graphics_handle get_zlabel (void) const { return zlabel.handle_value (); }
+
+  graphics_handle get_title (void) const { return title.handle_value (); }
+
+  bool is_xgrid (void) const { return xgrid.is_on (); }
+  std::string get_xgrid (void) const { return xgrid.current_value (); }
+
+  bool is_ygrid (void) const { return ygrid.is_on (); }
+  std::string get_ygrid (void) const { return ygrid.current_value (); }
+
+  bool is_zgrid (void) const { return zgrid.is_on (); }
+  std::string get_zgrid (void) const { return zgrid.current_value (); }
+
+  bool is_xminorgrid (void) const { return xminorgrid.is_on (); }
+  std::string get_xminorgrid (void) const { return xminorgrid.current_value (); }
+
+  bool is_yminorgrid (void) const { return yminorgrid.is_on (); }
+  std::string get_yminorgrid (void) const { return yminorgrid.current_value (); }
+
+  bool is_zminorgrid (void) const { return zminorgrid.is_on (); }
+  std::string get_zminorgrid (void) const { return zminorgrid.current_value (); }
+
+  octave_value get_xtick (void) const { return xtick.get (); }
+
+  octave_value get_ytick (void) const { return ytick.get (); }
+
+  octave_value get_ztick (void) const { return ztick.get (); }
+
+  bool xtickmode_is (const std::string& v) const { return xtickmode.is (v); }
+  std::string get_xtickmode (void) const { return xtickmode.current_value (); }
+
+  bool ytickmode_is (const std::string& v) const { return ytickmode.is (v); }
+  std::string get_ytickmode (void) const { return ytickmode.current_value (); }
+
+  bool ztickmode_is (const std::string& v) const { return ztickmode.is (v); }
+  std::string get_ztickmode (void) const { return ztickmode.current_value (); }
+
+  bool is_xminortick (void) const { return xminortick.is_on (); }
+  std::string get_xminortick (void) const { return xminortick.current_value (); }
+
+  bool is_yminortick (void) const { return yminortick.is_on (); }
+  std::string get_yminortick (void) const { return yminortick.current_value (); }
+
+  bool is_zminortick (void) const { return zminortick.is_on (); }
+  std::string get_zminortick (void) const { return zminortick.current_value (); }
+
+  octave_value get_xticklabel (void) const { return xticklabel.get (); }
+
+  octave_value get_yticklabel (void) const { return yticklabel.get (); }
+
+  octave_value get_zticklabel (void) const { return zticklabel.get (); }
+
+  bool xticklabelmode_is (const std::string& v) const { return xticklabelmode.is (v); }
+  std::string get_xticklabelmode (void) const { return xticklabelmode.current_value (); }
+
+  bool yticklabelmode_is (const std::string& v) const { return yticklabelmode.is (v); }
+  std::string get_yticklabelmode (void) const { return yticklabelmode.current_value (); }
+
+  bool zticklabelmode_is (const std::string& v) const { return zticklabelmode.is (v); }
+  std::string get_zticklabelmode (void) const { return zticklabelmode.current_value (); }
+
+  bool interpreter_is (const std::string& v) const { return interpreter.is (v); }
+  std::string get_interpreter (void) const { return interpreter.current_value (); }
+
+  bool color_is_rgb (void) const { return color.is_rgb (); }
+  bool color_is (const std::string& v) const { return color.is (v); }
+  Matrix get_color_rgb (void) const { return (color.is_rgb () ? color.rgb () : Matrix ()); }
+  octave_value get_color (void) const { return color.get (); }
+
+  bool xcolor_is_rgb (void) const { return xcolor.is_rgb (); }
+  bool xcolor_is (const std::string& v) const { return xcolor.is (v); }
+  Matrix get_xcolor_rgb (void) const { return (xcolor.is_rgb () ? xcolor.rgb () : Matrix ()); }
+  octave_value get_xcolor (void) const { return xcolor.get (); }
+
+  bool ycolor_is_rgb (void) const { return ycolor.is_rgb (); }
+  bool ycolor_is (const std::string& v) const { return ycolor.is (v); }
+  Matrix get_ycolor_rgb (void) const { return (ycolor.is_rgb () ? ycolor.rgb () : Matrix ()); }
+  octave_value get_ycolor (void) const { return ycolor.get (); }
+
+  bool zcolor_is_rgb (void) const { return zcolor.is_rgb (); }
+  bool zcolor_is (const std::string& v) const { return zcolor.is (v); }
+  Matrix get_zcolor_rgb (void) const { return (zcolor.is_rgb () ? zcolor.rgb () : Matrix ()); }
+  octave_value get_zcolor (void) const { return zcolor.get (); }
+
+  bool xscale_is (const std::string& v) const { return xscale.is (v); }
+  std::string get_xscale (void) const { return xscale.current_value (); }
+
+  bool yscale_is (const std::string& v) const { return yscale.is (v); }
+  std::string get_yscale (void) const { return yscale.current_value (); }
+
+  bool zscale_is (const std::string& v) const { return zscale.is (v); }
+  std::string get_zscale (void) const { return zscale.current_value (); }
+
+  bool xdir_is (const std::string& v) const { return xdir.is (v); }
+  std::string get_xdir (void) const { return xdir.current_value (); }
+
+  bool ydir_is (const std::string& v) const { return ydir.is (v); }
+  std::string get_ydir (void) const { return ydir.current_value (); }
+
+  bool zdir_is (const std::string& v) const { return zdir.is (v); }
+  std::string get_zdir (void) const { return zdir.current_value (); }
+
+  bool yaxislocation_is (const std::string& v) const { return yaxislocation.is (v); }
+  std::string get_yaxislocation (void) const { return yaxislocation.current_value (); }
+
+  bool xaxislocation_is (const std::string& v) const { return xaxislocation.is (v); }
+  std::string get_xaxislocation (void) const { return xaxislocation.current_value (); }
+
+  octave_value get_view (void) const { return view.get (); }
+
+  bool nextplot_is (const std::string& v) const { return nextplot.is (v); }
+  std::string get_nextplot (void) const { return nextplot.current_value (); }
+
+  octave_value get_outerposition (void) const { return outerposition.get (); }
+
+  bool activepositionproperty_is (const std::string& v) const { return activepositionproperty.is (v); }
+  std::string get_activepositionproperty (void) const { return activepositionproperty.current_value (); }
+
+  bool ambientlightcolor_is_rgb (void) const { return ambientlightcolor.is_rgb (); }
+  bool ambientlightcolor_is (const std::string& v) const { return ambientlightcolor.is (v); }
+  Matrix get_ambientlightcolor_rgb (void) const { return (ambientlightcolor.is_rgb () ? ambientlightcolor.rgb () : Matrix ()); }
+  octave_value get_ambientlightcolor (void) const { return ambientlightcolor.get (); }
+
+  octave_value get_cameraposition (void) const { return cameraposition.get (); }
+
+  octave_value get_cameratarget (void) const { return cameratarget.get (); }
+
+  octave_value get_cameraupvector (void) const { return cameraupvector.get (); }
+
+  double get_cameraviewangle (void) const { return cameraviewangle.double_value (); }
+
+  bool camerapositionmode_is (const std::string& v) const { return camerapositionmode.is (v); }
+  std::string get_camerapositionmode (void) const { return camerapositionmode.current_value (); }
+
+  bool cameratargetmode_is (const std::string& v) const { return cameratargetmode.is (v); }
+  std::string get_cameratargetmode (void) const { return cameratargetmode.current_value (); }
+
+  bool cameraupvectormode_is (const std::string& v) const { return cameraupvectormode.is (v); }
+  std::string get_cameraupvectormode (void) const { return cameraupvectormode.current_value (); }
+
+  bool cameraviewanglemode_is (const std::string& v) const { return cameraviewanglemode.is (v); }
+  std::string get_cameraviewanglemode (void) const { return cameraviewanglemode.current_value (); }
+
+  octave_value get_currentpoint (void) const { return currentpoint.get (); }
+
+  bool drawmode_is (const std::string& v) const { return drawmode.is (v); }
+  std::string get_drawmode (void) const { return drawmode.current_value (); }
+
+  bool fontangle_is (const std::string& v) const { return fontangle.is (v); }
+  std::string get_fontangle (void) const { return fontangle.current_value (); }
+
+  std::string get_fontname (void) const { return fontname.string_value (); }
+
+  double get_fontsize (void) const { return fontsize.double_value (); }
+
+  bool fontunits_is (const std::string& v) const { return fontunits.is (v); }
+  std::string get_fontunits (void) const { return fontunits.current_value (); }
+
+  bool fontweight_is (const std::string& v) const { return fontweight.is (v); }
+  std::string get_fontweight (void) const { return fontweight.current_value (); }
+
+  bool gridlinestyle_is (const std::string& v) const { return gridlinestyle.is (v); }
+  std::string get_gridlinestyle (void) const { return gridlinestyle.current_value (); }
+
+  std::string get_linestyleorder (void) const { return linestyleorder.string_value (); }
+
+  double get_linewidth (void) const { return linewidth.double_value (); }
+
+  bool minorgridlinestyle_is (const std::string& v) const { return minorgridlinestyle.is (v); }
+  std::string get_minorgridlinestyle (void) const { return minorgridlinestyle.current_value (); }
+
+  octave_value get_plotboxaspectratio (void) const { return plotboxaspectratio.get (); }
+
+  bool plotboxaspectratiomode_is (const std::string& v) const { return plotboxaspectratiomode.is (v); }
+  std::string get_plotboxaspectratiomode (void) const { return plotboxaspectratiomode.current_value (); }
+
+  bool projection_is (const std::string& v) const { return projection.is (v); }
+  std::string get_projection (void) const { return projection.current_value (); }
+
+  bool tickdir_is (const std::string& v) const { return tickdir.is (v); }
+  std::string get_tickdir (void) const { return tickdir.current_value (); }
+
+  bool tickdirmode_is (const std::string& v) const { return tickdirmode.is (v); }
+  std::string get_tickdirmode (void) const { return tickdirmode.current_value (); }
+
+  octave_value get_ticklength (void) const { return ticklength.get (); }
+
+  octave_value get_tightinset (void) const { return tightinset.get (); }
+
+  bool units_is (const std::string& v) const { return units.is (v); }
+  std::string get_units (void) const { return units.current_value (); }
+
+  octave_value get_x_viewtransform (void) const { return x_viewtransform.get (); }
+
+  octave_value get_x_projectiontransform (void) const { return x_projectiontransform.get (); }
+
+  octave_value get_x_viewporttransform (void) const { return x_viewporttransform.get (); }
+
+  octave_value get_x_normrendertransform (void) const { return x_normrendertransform.get (); }
+
+  octave_value get_x_rendertransform (void) const { return x_rendertransform.get (); }
+
+
+  void set_position (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (position.set (val, true))
+          {
+            update_position ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_box (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (box.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_key (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (key.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keybox (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keybox.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keyreverse (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keyreverse.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keypos (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keypos.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_colororder (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (colororder.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_dataaspectratio (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (dataaspectratio.set (val, false))
+          {
+            set_dataaspectratiomode ("manual");
+            dataaspectratio.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_dataaspectratiomode ("manual");
+      }
+  }
+
+  void set_dataaspectratiomode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (dataaspectratiomode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_layer (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (layer.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, false))
+          {
+            set_xlimmode ("manual");
+            update_xlim ();
+            xlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_xlimmode ("manual");
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, false))
+          {
+            set_ylimmode ("manual");
+            update_ylim ();
+            ylim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_ylimmode ("manual");
+      }
+  }
+
+  void set_zlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlim.set (val, false))
+          {
+            set_zlimmode ("manual");
+            update_zlim ();
+            zlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_zlimmode ("manual");
+      }
+  }
+
+  void set_clim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (clim.set (val, false))
+          {
+            set_climmode ("manual");
+            clim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_climmode ("manual");
+      }
+  }
+
+  void set_alim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alim.set (val, false))
+          {
+            set_alimmode ("manual");
+            alim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_alimmode ("manual");
+      }
+  }
+
+  void set_xlimmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlimmode.set (val, false))
+          {
+            update_axis_limits ("xlimmode");
+            xlimmode.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylimmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylimmode.set (val, false))
+          {
+            update_axis_limits ("ylimmode");
+            ylimmode.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zlimmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlimmode.set (val, false))
+          {
+            update_axis_limits ("zlimmode");
+            zlimmode.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_climmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (climmode.set (val, false))
+          {
+            update_axis_limits ("climmode");
+            climmode.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alimmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alimmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlabel (const octave_value& val);
+
+  void set_ylabel (const octave_value& val);
+
+  void set_zlabel (const octave_value& val);
+
+  void set_title (const octave_value& val);
+
+  void set_xgrid (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xgrid.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ygrid (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ygrid.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zgrid (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zgrid.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xminorgrid (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xminorgrid.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yminorgrid (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yminorgrid.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zminorgrid (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zminorgrid.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xtick (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xtick.set (val, false))
+          {
+            set_xtickmode ("manual");
+            xtick.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_xtickmode ("manual");
+      }
+  }
+
+  void set_ytick (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ytick.set (val, false))
+          {
+            set_ytickmode ("manual");
+            ytick.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_ytickmode ("manual");
+      }
+  }
+
+  void set_ztick (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ztick.set (val, false))
+          {
+            set_ztickmode ("manual");
+            ztick.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_ztickmode ("manual");
+      }
+  }
+
+  void set_xtickmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xtickmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ytickmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ytickmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ztickmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ztickmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xminortick (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xminortick.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yminortick (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yminortick.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zminortick (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zminortick.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xticklabel (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xticklabel.set (val, false))
+          {
+            set_xticklabelmode ("manual");
+            xticklabel.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_xticklabelmode ("manual");
+      }
+  }
+
+  void set_yticklabel (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yticklabel.set (val, false))
+          {
+            set_yticklabelmode ("manual");
+            yticklabel.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_yticklabelmode ("manual");
+      }
+  }
+
+  void set_zticklabel (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zticklabel.set (val, false))
+          {
+            set_zticklabelmode ("manual");
+            zticklabel.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_zticklabelmode ("manual");
+      }
+  }
+
+  void set_xticklabelmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xticklabelmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yticklabelmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yticklabelmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zticklabelmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zticklabelmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_interpreter (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (interpreter.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_color (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (color.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xcolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xcolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ycolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ycolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zcolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zcolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xscale (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xscale.set (val, false))
+          {
+            update_xscale ();
+            update_axis_limits ("xscale");
+            xscale.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yscale (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yscale.set (val, false))
+          {
+            update_yscale ();
+            update_axis_limits ("yscale");
+            yscale.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zscale (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zscale.set (val, false))
+          {
+            update_zscale ();
+            update_axis_limits ("zscale");
+            zscale.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xdir (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdir.set (val, true))
+          {
+            update_xdir ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydir (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydir.set (val, true))
+          {
+            update_ydir ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zdir (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zdir.set (val, true))
+          {
+            update_zdir ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yaxislocation (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yaxislocation.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xaxislocation (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xaxislocation.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_view (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (view.set (val, true))
+          {
+            update_view ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_nextplot (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (nextplot.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_outerposition (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (outerposition.set (val, true))
+          {
+            update_outerposition ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_activepositionproperty (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (activepositionproperty.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ambientlightcolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ambientlightcolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cameraposition (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameraposition.set (val, false))
+          {
+            set_camerapositionmode ("manual");
+            cameraposition.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_camerapositionmode ("manual");
+      }
+  }
+
+  void set_cameratarget (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameratarget.set (val, false))
+          {
+            set_cameratargetmode ("manual");
+            cameratarget.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_cameratargetmode ("manual");
+      }
+  }
+
+  void set_cameraupvector (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameraupvector.set (val, false))
+          {
+            set_cameraupvectormode ("manual");
+            cameraupvector.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_cameraupvectormode ("manual");
+      }
+  }
+
+  void set_cameraviewangle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameraviewangle.set (val, false))
+          {
+            set_cameraviewanglemode ("manual");
+            cameraviewangle.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_cameraviewanglemode ("manual");
+      }
+  }
+
+  void set_camerapositionmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (camerapositionmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cameratargetmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameratargetmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cameraupvectormode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameraupvectormode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cameraviewanglemode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cameraviewanglemode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_currentpoint (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (currentpoint.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_drawmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (drawmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontangle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontangle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontname (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontname.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontsize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontsize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontunits (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontunits.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontweight (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontweight.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_gridlinestyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (gridlinestyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linestyleorder (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linestyleorder.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linewidth (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linewidth.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_minorgridlinestyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (minorgridlinestyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_plotboxaspectratio (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (plotboxaspectratio.set (val, false))
+          {
+            set_plotboxaspectratiomode ("manual");
+            plotboxaspectratio.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_plotboxaspectratiomode ("manual");
+      }
+  }
+
+  void set_plotboxaspectratiomode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (plotboxaspectratiomode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_projection (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (projection.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_tickdir (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (tickdir.set (val, false))
+          {
+            set_tickdirmode ("manual");
+            tickdir.run_listeners (POSTSET);
+            mark_modified ();
+          }
+        else
+          set_tickdirmode ("manual");
+      }
+  }
+
+  void set_tickdirmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (tickdirmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ticklength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ticklength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_tightinset (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (tightinset.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_units (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (units.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_x_viewtransform (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (x_viewtransform.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_x_projectiontransform (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (x_projectiontransform.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_x_viewporttransform (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (x_viewporttransform.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_x_normrendertransform (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (x_normrendertransform.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_x_rendertransform (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (x_rendertransform.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+
+  protected:
+    void init (void);
+
+  private:
+    void update_xscale (void) { sx = get_xscale (); }
+    void update_yscale (void) { sy = get_yscale (); }
+    void update_zscale (void) { sz = get_zscale (); }
+
+    void update_view (void) { update_camera (); }
+
+    void update_xdir (void) { update_camera (); }
+    void update_ydir (void) { update_camera (); }
+    void update_zdir (void) { update_camera (); }
+
+    void sync_positions (void);
+    void update_outerposition (void) { sync_positions ();}
+    void update_position (void) { sync_positions (); }
+
+    double calc_tick_sep (double minval, double maxval);
+    void calc_ticks_and_lims (array_property& lims, array_property& ticks, bool limmode_is_auto, bool is_logscale);
+    void fix_limits (array_property& lims)
+    {
+      if (lims.get ().is_empty ()) 
+	return;
+
+      Matrix l = lims.get ().matrix_value ();
+      if (l(0) > l(1))
+	{
+	  l(0) = 0;
+	  l(1) = 1;
+	  lims = l;
+	}
+      else if (l(0) == l(1))
+	{
+	  l(0) -= 0.5;
+	  l(1) += 0.5;
+	  lims = l;
+	}
+    }      
+
+  public:
+    Matrix get_axis_limits (double xmin, double xmax, double min_pos, bool logscale);
+    
+    void update_xlim (bool do_clr_zoom = true)
+    {
+      if (xtickmode.is ("auto"))
+	calc_ticks_and_lims (xlim, xtick, xlimmode.is ("auto"), xscale.is ("log"));
+
+      fix_limits (xlim);
+
+      if (do_clr_zoom)
+	zoom_stack.clear ();
+    }
+
+    void update_ylim (bool do_clr_zoom = true)
+    {
+      if (ytickmode.is ("auto"))
+	calc_ticks_and_lims (ylim, ytick, ylimmode.is ("auto"), yscale.is ("log"));
+
+      fix_limits (ylim);
+
+      if (do_clr_zoom)
+	zoom_stack.clear ();
+    }
+
+    void update_zlim (void)
+    {
+      if (ztickmode.is ("auto"))
+	calc_ticks_and_lims (zlim, ztick, zlimmode.is ("auto"), zscale.is ("log"));
+
+      fix_limits (zlim);
+
+      zoom_stack.clear ();
+    }
+    
+  };
+
+private:
+  properties xproperties;
+
+public:
+  axes (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p), default_properties ()
+  {
+    xproperties.override_defaults (*this);
+    xproperties.update_transform ();
+  }
+
+  ~axes (void) { xproperties.delete_children (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set (const caseless_str& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  void set_defaults (const std::string& mode)
+  {
+    remove_all_listeners ();
+    xproperties.set_defaults (*this, mode);
+  }
+
+  octave_value get (const caseless_str& name) const
+  {
+    octave_value retval;
+
+    // FIXME -- finish this.
+    if (name.compare ("default", 7))
+      retval = get_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const caseless_str& name) const;
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  void update_axis_limits (const std::string& axis_type);
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API line : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    // properties which are not in matlab:
+    // ldata, udata, xldata, xudata, keylabel, interpreter
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  row_vector_property xdata;
+  row_vector_property ydata;
+  row_vector_property zdata;
+  row_vector_property ldata;
+  row_vector_property udata;
+  row_vector_property xldata;
+  row_vector_property xudata;
+  string_property xdatasource;
+  string_property ydatasource;
+  string_property zdatasource;
+  color_property color;
+  radio_property linestyle;
+  double_property linewidth;
+  radio_property marker;
+  color_property markeredgecolor;
+  color_property markerfacecolor;
+  double_property markersize;
+  string_property keylabel;
+  radio_property interpreter;
+  string_property displayname;
+  radio_property erasemode;
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property zlim;
+  bool_property xliminclude;
+  bool_property yliminclude;
+  bool_property zliminclude;
+
+public:
+
+  enum
+  {
+    XDATA = 4000,
+    YDATA = 4001,
+    ZDATA = 4002,
+    LDATA = 4003,
+    UDATA = 4004,
+    XLDATA = 4005,
+    XUDATA = 4006,
+    XDATASOURCE = 4007,
+    YDATASOURCE = 4008,
+    ZDATASOURCE = 4009,
+    COLOR = 4010,
+    LINESTYLE = 4011,
+    LINEWIDTH = 4012,
+    MARKER = 4013,
+    MARKEREDGECOLOR = 4014,
+    MARKERFACECOLOR = 4015,
+    MARKERSIZE = 4016,
+    KEYLABEL = 4017,
+    INTERPRETER = 4018,
+    DISPLAYNAME = 4019,
+    ERASEMODE = 4020,
+    XLIM = 4021,
+    YLIM = 4022,
+    ZLIM = 4023,
+    XLIMINCLUDE = 4024,
+    YLIMINCLUDE = 4025,
+    ZLIMINCLUDE = 4026
+  };
+
+  octave_value get_xdata (void) const { return xdata.get (); }
+
+  octave_value get_ydata (void) const { return ydata.get (); }
+
+  octave_value get_zdata (void) const { return zdata.get (); }
+
+  octave_value get_ldata (void) const { return ldata.get (); }
+
+  octave_value get_udata (void) const { return udata.get (); }
+
+  octave_value get_xldata (void) const { return xldata.get (); }
+
+  octave_value get_xudata (void) const { return xudata.get (); }
+
+  std::string get_xdatasource (void) const { return xdatasource.string_value (); }
+
+  std::string get_ydatasource (void) const { return ydatasource.string_value (); }
+
+  std::string get_zdatasource (void) const { return zdatasource.string_value (); }
+
+  bool color_is_rgb (void) const { return color.is_rgb (); }
+  bool color_is (const std::string& v) const { return color.is (v); }
+  Matrix get_color_rgb (void) const { return (color.is_rgb () ? color.rgb () : Matrix ()); }
+  octave_value get_color (void) const { return color.get (); }
+
+  bool linestyle_is (const std::string& v) const { return linestyle.is (v); }
+  std::string get_linestyle (void) const { return linestyle.current_value (); }
+
+  double get_linewidth (void) const { return linewidth.double_value (); }
+
+  bool marker_is (const std::string& v) const { return marker.is (v); }
+  std::string get_marker (void) const { return marker.current_value (); }
+
+  bool markeredgecolor_is_rgb (void) const { return markeredgecolor.is_rgb (); }
+  bool markeredgecolor_is (const std::string& v) const { return markeredgecolor.is (v); }
+  Matrix get_markeredgecolor_rgb (void) const { return (markeredgecolor.is_rgb () ? markeredgecolor.rgb () : Matrix ()); }
+  octave_value get_markeredgecolor (void) const { return markeredgecolor.get (); }
+
+  bool markerfacecolor_is_rgb (void) const { return markerfacecolor.is_rgb (); }
+  bool markerfacecolor_is (const std::string& v) const { return markerfacecolor.is (v); }
+  Matrix get_markerfacecolor_rgb (void) const { return (markerfacecolor.is_rgb () ? markerfacecolor.rgb () : Matrix ()); }
+  octave_value get_markerfacecolor (void) const { return markerfacecolor.get (); }
+
+  double get_markersize (void) const { return markersize.double_value (); }
+
+  std::string get_keylabel (void) const { return keylabel.string_value (); }
+
+  bool interpreter_is (const std::string& v) const { return interpreter.is (v); }
+  std::string get_interpreter (void) const { return interpreter.current_value (); }
+
+  std::string get_displayname (void) const { return displayname.string_value (); }
+
+  bool erasemode_is (const std::string& v) const { return erasemode.is (v); }
+  std::string get_erasemode (void) const { return erasemode.current_value (); }
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_zlim (void) const { return zlim.get (); }
+
+  bool is_xliminclude (void) const { return xliminclude.is_on (); }
+  std::string get_xliminclude (void) const { return xliminclude.current_value (); }
+
+  bool is_yliminclude (void) const { return yliminclude.is_on (); }
+  std::string get_yliminclude (void) const { return yliminclude.current_value (); }
+
+  bool is_zliminclude (void) const { return zliminclude.is_on (); }
+  std::string get_zliminclude (void) const { return zliminclude.current_value (); }
+
+
+  void set_xdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdata.set (val, true))
+          {
+            update_xdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydata.set (val, true))
+          {
+            update_ydata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zdata.set (val, true))
+          {
+            update_zdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ldata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ldata.set (val, true))
+          {
+            update_ldata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_udata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (udata.set (val, true))
+          {
+            update_udata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xldata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xldata.set (val, true))
+          {
+            update_xldata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xudata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xudata.set (val, true))
+          {
+            update_xudata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xdatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zdatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zdatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_color (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (color.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linestyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linestyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linewidth (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linewidth.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_marker (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (marker.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markeredgecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markeredgecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markerfacecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markerfacecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markersize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markersize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keylabel (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keylabel.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_interpreter (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (interpreter.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_displayname (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (displayname.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_erasemode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (erasemode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, false))
+          {
+            update_axis_limits ("xlim");
+            xlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, false))
+          {
+            update_axis_limits ("ylim");
+            ylim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlim.set (val, false))
+          {
+            update_axis_limits ("zlim");
+            zlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xliminclude.set (val, false))
+          {
+            update_axis_limits ("xliminclude");
+            xliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yliminclude.set (val, false))
+          {
+            update_axis_limits ("yliminclude");
+            yliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zliminclude.set (val, false))
+          {
+            update_axis_limits ("zliminclude");
+            zliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+
+  private:
+    Matrix compute_xlim (void) const;
+    Matrix compute_ylim (void) const;
+
+    void update_xdata (void) { set_xlim (compute_xlim ()); }
+    void update_xldata (void) { set_xlim (compute_xlim ()); }
+    void update_xudata (void) { set_xlim (compute_xlim ()); }
+    
+    void update_ydata (void) { set_ylim (compute_ylim ()); }
+    void update_ldata (void) { set_ylim (compute_ylim ()); }
+    void update_udata (void) { set_ylim (compute_ylim ()); }
+
+    void update_zdata (void)
+      {
+	set_zlim (zdata.get_limits ());
+	set_zliminclude (get_zdata ().numel () > 0);
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  line (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~line (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API text : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  string_property string;
+  radio_property units;
+  array_property position;
+  double_property rotation;
+  radio_property horizontalalignment;
+  color_property color;
+  string_property fontname;
+  double_property fontsize;
+  radio_property fontangle;
+  radio_property fontweight;
+  radio_property interpreter;
+  color_property backgroundcolor;
+  string_property displayname;
+  color_property edgecolor;
+  radio_property erasemode;
+  bool_property editing;
+  radio_property fontunits;
+  radio_property linestyle;
+  double_property linewidth;
+  double_property margin;
+  radio_property verticalalignment;
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property zlim;
+  bool_property xliminclude;
+  bool_property yliminclude;
+  bool_property zliminclude;
+
+public:
+
+  enum
+  {
+    STRING = 5000,
+    UNITS = 5001,
+    POSITION = 5002,
+    ROTATION = 5003,
+    HORIZONTALALIGNMENT = 5004,
+    COLOR = 5005,
+    FONTNAME = 5006,
+    FONTSIZE = 5007,
+    FONTANGLE = 5008,
+    FONTWEIGHT = 5009,
+    INTERPRETER = 5010,
+    BACKGROUNDCOLOR = 5011,
+    DISPLAYNAME = 5012,
+    EDGECOLOR = 5013,
+    ERASEMODE = 5014,
+    EDITING = 5015,
+    FONTUNITS = 5016,
+    LINESTYLE = 5017,
+    LINEWIDTH = 5018,
+    MARGIN = 5019,
+    VERTICALALIGNMENT = 5020,
+    XLIM = 5021,
+    YLIM = 5022,
+    ZLIM = 5023,
+    XLIMINCLUDE = 5024,
+    YLIMINCLUDE = 5025,
+    ZLIMINCLUDE = 5026
+  };
+
+  std::string get_string (void) const { return string.string_value (); }
+
+  bool units_is (const std::string& v) const { return units.is (v); }
+  std::string get_units (void) const { return units.current_value (); }
+
+  octave_value get_position (void) const { return position.get (); }
+
+  double get_rotation (void) const { return rotation.double_value (); }
+
+  bool horizontalalignment_is (const std::string& v) const { return horizontalalignment.is (v); }
+  std::string get_horizontalalignment (void) const { return horizontalalignment.current_value (); }
+
+  bool color_is_rgb (void) const { return color.is_rgb (); }
+  bool color_is (const std::string& v) const { return color.is (v); }
+  Matrix get_color_rgb (void) const { return (color.is_rgb () ? color.rgb () : Matrix ()); }
+  octave_value get_color (void) const { return color.get (); }
+
+  std::string get_fontname (void) const { return fontname.string_value (); }
+
+  double get_fontsize (void) const { return fontsize.double_value (); }
+
+  bool fontangle_is (const std::string& v) const { return fontangle.is (v); }
+  std::string get_fontangle (void) const { return fontangle.current_value (); }
+
+  bool fontweight_is (const std::string& v) const { return fontweight.is (v); }
+  std::string get_fontweight (void) const { return fontweight.current_value (); }
+
+  bool interpreter_is (const std::string& v) const { return interpreter.is (v); }
+  std::string get_interpreter (void) const { return interpreter.current_value (); }
+
+  bool backgroundcolor_is_rgb (void) const { return backgroundcolor.is_rgb (); }
+  bool backgroundcolor_is (const std::string& v) const { return backgroundcolor.is (v); }
+  Matrix get_backgroundcolor_rgb (void) const { return (backgroundcolor.is_rgb () ? backgroundcolor.rgb () : Matrix ()); }
+  octave_value get_backgroundcolor (void) const { return backgroundcolor.get (); }
+
+  std::string get_displayname (void) const { return displayname.string_value (); }
+
+  bool edgecolor_is_rgb (void) const { return edgecolor.is_rgb (); }
+  bool edgecolor_is (const std::string& v) const { return edgecolor.is (v); }
+  Matrix get_edgecolor_rgb (void) const { return (edgecolor.is_rgb () ? edgecolor.rgb () : Matrix ()); }
+  octave_value get_edgecolor (void) const { return edgecolor.get (); }
+
+  bool erasemode_is (const std::string& v) const { return erasemode.is (v); }
+  std::string get_erasemode (void) const { return erasemode.current_value (); }
+
+  bool is_editing (void) const { return editing.is_on (); }
+  std::string get_editing (void) const { return editing.current_value (); }
+
+  bool fontunits_is (const std::string& v) const { return fontunits.is (v); }
+  std::string get_fontunits (void) const { return fontunits.current_value (); }
+
+  bool linestyle_is (const std::string& v) const { return linestyle.is (v); }
+  std::string get_linestyle (void) const { return linestyle.current_value (); }
+
+  double get_linewidth (void) const { return linewidth.double_value (); }
+
+  double get_margin (void) const { return margin.double_value (); }
+
+  bool verticalalignment_is (const std::string& v) const { return verticalalignment.is (v); }
+  std::string get_verticalalignment (void) const { return verticalalignment.current_value (); }
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_zlim (void) const { return zlim.get (); }
+
+  bool is_xliminclude (void) const { return xliminclude.is_on (); }
+  std::string get_xliminclude (void) const { return xliminclude.current_value (); }
+
+  bool is_yliminclude (void) const { return yliminclude.is_on (); }
+  std::string get_yliminclude (void) const { return yliminclude.current_value (); }
+
+  bool is_zliminclude (void) const { return zliminclude.is_on (); }
+  std::string get_zliminclude (void) const { return zliminclude.current_value (); }
+
+
+  void set_string (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (string.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_units (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (units.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_position (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (position.set (val, true))
+          {
+            update_position ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_rotation (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (rotation.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_horizontalalignment (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (horizontalalignment.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_color (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (color.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontname (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontname.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontsize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontsize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontangle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontangle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontweight (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontweight.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_interpreter (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (interpreter.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_backgroundcolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (backgroundcolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_displayname (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (displayname.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_erasemode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (erasemode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_editing (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (editing.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_fontunits (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (fontunits.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linestyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linestyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linewidth (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linewidth.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_margin (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (margin.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_verticalalignment (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (verticalalignment.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, false))
+          {
+            update_axis_limits ("xlim");
+            xlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, false))
+          {
+            update_axis_limits ("ylim");
+            ylim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlim.set (val, false))
+          {
+            update_axis_limits ("zlim");
+            zlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xliminclude.set (val, false))
+          {
+            update_axis_limits ("xliminclude");
+            xliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yliminclude.set (val, false))
+          {
+            update_axis_limits ("yliminclude");
+            yliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zliminclude.set (val, false))
+          {
+            update_axis_limits ("zliminclude");
+            zliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+
+  protected:
+    void init (void)
+      {
+        position.add_constraint (dim_vector (1, 3));
+      }
+
+  private:
+    void update_position (void)
+      {
+	Matrix pos = get_position ().matrix_value ();
+	Matrix lim;
+
+	lim = Matrix (1, 3, pos(0));
+	lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	set_xlim (lim);
+
+	lim = Matrix (1, 3, pos(1));
+	lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	set_ylim (lim);
+
+	if (pos.numel () == 3)
+	  {
+	    lim = Matrix (1, 3, pos(2));
+	    lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	    set_zliminclude ("on");
+	    set_zlim (lim);
+	  }
+	else
+	  set_zliminclude ("off");
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  text (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~text (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API image : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  row_vector_property xdata;
+  row_vector_property ydata;
+  array_property cdata;
+  radio_property cdatamapping;
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property clim;
+  bool_property xliminclude;
+  bool_property yliminclude;
+  bool_property climinclude;
+
+public:
+
+  enum
+  {
+    XDATA = 6000,
+    YDATA = 6001,
+    CDATA = 6002,
+    CDATAMAPPING = 6003,
+    XLIM = 6004,
+    YLIM = 6005,
+    CLIM = 6006,
+    XLIMINCLUDE = 6007,
+    YLIMINCLUDE = 6008,
+    CLIMINCLUDE = 6009
+  };
+
+  octave_value get_xdata (void) const { return xdata.get (); }
+
+  octave_value get_ydata (void) const { return ydata.get (); }
+
+  octave_value get_cdata (void) const { return cdata.get (); }
+
+  bool cdatamapping_is (const std::string& v) const { return cdatamapping.is (v); }
+  std::string get_cdatamapping (void) const { return cdatamapping.current_value (); }
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_clim (void) const { return clim.get (); }
+
+  bool is_xliminclude (void) const { return xliminclude.is_on (); }
+  std::string get_xliminclude (void) const { return xliminclude.current_value (); }
+
+  bool is_yliminclude (void) const { return yliminclude.is_on (); }
+  std::string get_yliminclude (void) const { return yliminclude.current_value (); }
+
+
+  void set_xdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdata.set (val, true))
+          {
+            update_xdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydata.set (val, true))
+          {
+            update_ydata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdata.set (val, true))
+          {
+            update_cdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdatamapping (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdatamapping.set (val, false))
+          {
+            update_axis_limits ("cdatamapping");
+            cdatamapping.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, false))
+          {
+            update_axis_limits ("xlim");
+            xlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, false))
+          {
+            update_axis_limits ("ylim");
+            ylim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_clim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (clim.set (val, false))
+          {
+            update_axis_limits ("clim");
+            clim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xliminclude.set (val, false))
+          {
+            update_axis_limits ("xliminclude");
+            xliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yliminclude.set (val, false))
+          {
+            update_axis_limits ("yliminclude");
+            yliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_climinclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (climinclude.set (val, false))
+          {
+            update_axis_limits ("climinclude");
+            climinclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+
+  protected:
+    void init (void)
+      {
+	xdata.add_constraint (2);
+	ydata.add_constraint (2);
+	cdata.add_constraint ("double");
+	cdata.add_constraint ("logical");
+	cdata.add_constraint ("uint8");
+	cdata.add_constraint (dim_vector (-1, -1));
+	cdata.add_constraint (dim_vector (-1, -1, 3));
+      }
+
+  private:
+    // FIXME -- limits should take pixel width into account.
+    void update_xdata (void)
+      { set_xlim (xdata.get_limits ()); }
+
+    // FIXME -- idem.
+    void update_ydata (void)
+      { set_ylim (ydata.get_limits ()); }
+
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  image (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~image (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API patch : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    octave_value get_color_data (void) const;
+    
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    bool is_aliminclude (void) const
+      { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
+    std::string get_aliminclude (void) const
+      { return aliminclude.current_value (); }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  array_property xdata;
+  array_property ydata;
+  array_property zdata;
+  array_property cdata;
+  radio_property cdatamapping;
+  array_property faces;
+  array_property facevertexalphadata;
+  array_property facevertexcdata;
+  array_property vertices;
+  array_property vertexnormals;
+  radio_property normalmode;
+  color_property facecolor;
+  double_radio_property facealpha;
+  radio_property facelighting;
+  color_property edgecolor;
+  double_radio_property edgealpha;
+  radio_property edgelighting;
+  radio_property backfacelighting;
+  double_property ambientstrength;
+  double_property diffusestrength;
+  double_property specularstrength;
+  double_property specularexponent;
+  double_property specularcolorreflectance;
+  radio_property erasemode;
+  radio_property linestyle;
+  double_property linewidth;
+  radio_property marker;
+  color_property markeredgecolor;
+  color_property markerfacecolor;
+  double_property markersize;
+  string_property keylabel;
+  radio_property interpreter;
+  radio_property alphadatamapping;
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property zlim;
+  row_vector_property clim;
+  row_vector_property alim;
+  bool_property xliminclude;
+  bool_property yliminclude;
+  bool_property zliminclude;
+  bool_property climinclude;
+  bool_property aliminclude;
+
+public:
+
+  enum
+  {
+    XDATA = 7000,
+    YDATA = 7001,
+    ZDATA = 7002,
+    CDATA = 7003,
+    CDATAMAPPING = 7004,
+    FACES = 7005,
+    FACEVERTEXALPHADATA = 7006,
+    FACEVERTEXCDATA = 7007,
+    VERTICES = 7008,
+    VERTEXNORMALS = 7009,
+    NORMALMODE = 7010,
+    FACECOLOR = 7011,
+    FACEALPHA = 7012,
+    FACELIGHTING = 7013,
+    EDGECOLOR = 7014,
+    EDGEALPHA = 7015,
+    EDGELIGHTING = 7016,
+    BACKFACELIGHTING = 7017,
+    AMBIENTSTRENGTH = 7018,
+    DIFFUSESTRENGTH = 7019,
+    SPECULARSTRENGTH = 7020,
+    SPECULAREXPONENT = 7021,
+    SPECULARCOLORREFLECTANCE = 7022,
+    ERASEMODE = 7023,
+    LINESTYLE = 7024,
+    LINEWIDTH = 7025,
+    MARKER = 7026,
+    MARKEREDGECOLOR = 7027,
+    MARKERFACECOLOR = 7028,
+    MARKERSIZE = 7029,
+    KEYLABEL = 7030,
+    INTERPRETER = 7031,
+    ALPHADATAMAPPING = 7032,
+    XLIM = 7033,
+    YLIM = 7034,
+    ZLIM = 7035,
+    CLIM = 7036,
+    ALIM = 7037,
+    XLIMINCLUDE = 7038,
+    YLIMINCLUDE = 7039,
+    ZLIMINCLUDE = 7040,
+    CLIMINCLUDE = 7041,
+    ALIMINCLUDE = 7042
+  };
+
+  octave_value get_xdata (void) const { return xdata.get (); }
+
+  octave_value get_ydata (void) const { return ydata.get (); }
+
+  octave_value get_zdata (void) const { return zdata.get (); }
+
+  octave_value get_cdata (void) const { return cdata.get (); }
+
+  bool cdatamapping_is (const std::string& v) const { return cdatamapping.is (v); }
+  std::string get_cdatamapping (void) const { return cdatamapping.current_value (); }
+
+  octave_value get_faces (void) const { return faces.get (); }
+
+  octave_value get_facevertexalphadata (void) const { return facevertexalphadata.get (); }
+
+  octave_value get_facevertexcdata (void) const { return facevertexcdata.get (); }
+
+  octave_value get_vertices (void) const { return vertices.get (); }
+
+  octave_value get_vertexnormals (void) const { return vertexnormals.get (); }
+
+  bool normalmode_is (const std::string& v) const { return normalmode.is (v); }
+  std::string get_normalmode (void) const { return normalmode.current_value (); }
+
+  bool facecolor_is_rgb (void) const { return facecolor.is_rgb (); }
+  bool facecolor_is (const std::string& v) const { return facecolor.is (v); }
+  Matrix get_facecolor_rgb (void) const { return (facecolor.is_rgb () ? facecolor.rgb () : Matrix ()); }
+  octave_value get_facecolor (void) const { return facecolor.get (); }
+
+  bool facealpha_is_double (void) const { return facealpha.is_double (); }
+  bool facealpha_is (const std::string& v) const { return facealpha.is (v); }
+  double get_facealpha_double (void) const { return (facealpha.is_double () ? facealpha.double_value () : 0); }
+  octave_value get_facealpha (void) const { return facealpha.get (); }
+
+  bool facelighting_is (const std::string& v) const { return facelighting.is (v); }
+  std::string get_facelighting (void) const { return facelighting.current_value (); }
+
+  bool edgecolor_is_rgb (void) const { return edgecolor.is_rgb (); }
+  bool edgecolor_is (const std::string& v) const { return edgecolor.is (v); }
+  Matrix get_edgecolor_rgb (void) const { return (edgecolor.is_rgb () ? edgecolor.rgb () : Matrix ()); }
+  octave_value get_edgecolor (void) const { return edgecolor.get (); }
+
+  bool edgealpha_is_double (void) const { return edgealpha.is_double (); }
+  bool edgealpha_is (const std::string& v) const { return edgealpha.is (v); }
+  double get_edgealpha_double (void) const { return (edgealpha.is_double () ? edgealpha.double_value () : 0); }
+  octave_value get_edgealpha (void) const { return edgealpha.get (); }
+
+  bool edgelighting_is (const std::string& v) const { return edgelighting.is (v); }
+  std::string get_edgelighting (void) const { return edgelighting.current_value (); }
+
+  bool backfacelighting_is (const std::string& v) const { return backfacelighting.is (v); }
+  std::string get_backfacelighting (void) const { return backfacelighting.current_value (); }
+
+  double get_ambientstrength (void) const { return ambientstrength.double_value (); }
+
+  double get_diffusestrength (void) const { return diffusestrength.double_value (); }
+
+  double get_specularstrength (void) const { return specularstrength.double_value (); }
+
+  double get_specularexponent (void) const { return specularexponent.double_value (); }
+
+  double get_specularcolorreflectance (void) const { return specularcolorreflectance.double_value (); }
+
+  bool erasemode_is (const std::string& v) const { return erasemode.is (v); }
+  std::string get_erasemode (void) const { return erasemode.current_value (); }
+
+  bool linestyle_is (const std::string& v) const { return linestyle.is (v); }
+  std::string get_linestyle (void) const { return linestyle.current_value (); }
+
+  double get_linewidth (void) const { return linewidth.double_value (); }
+
+  bool marker_is (const std::string& v) const { return marker.is (v); }
+  std::string get_marker (void) const { return marker.current_value (); }
+
+  bool markeredgecolor_is_rgb (void) const { return markeredgecolor.is_rgb (); }
+  bool markeredgecolor_is (const std::string& v) const { return markeredgecolor.is (v); }
+  Matrix get_markeredgecolor_rgb (void) const { return (markeredgecolor.is_rgb () ? markeredgecolor.rgb () : Matrix ()); }
+  octave_value get_markeredgecolor (void) const { return markeredgecolor.get (); }
+
+  bool markerfacecolor_is_rgb (void) const { return markerfacecolor.is_rgb (); }
+  bool markerfacecolor_is (const std::string& v) const { return markerfacecolor.is (v); }
+  Matrix get_markerfacecolor_rgb (void) const { return (markerfacecolor.is_rgb () ? markerfacecolor.rgb () : Matrix ()); }
+  octave_value get_markerfacecolor (void) const { return markerfacecolor.get (); }
+
+  double get_markersize (void) const { return markersize.double_value (); }
+
+  std::string get_keylabel (void) const { return keylabel.string_value (); }
+
+  bool interpreter_is (const std::string& v) const { return interpreter.is (v); }
+  std::string get_interpreter (void) const { return interpreter.current_value (); }
+
+  bool alphadatamapping_is (const std::string& v) const { return alphadatamapping.is (v); }
+  std::string get_alphadatamapping (void) const { return alphadatamapping.current_value (); }
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_zlim (void) const { return zlim.get (); }
+
+  octave_value get_clim (void) const { return clim.get (); }
+
+  octave_value get_alim (void) const { return alim.get (); }
+
+  bool is_xliminclude (void) const { return xliminclude.is_on (); }
+  std::string get_xliminclude (void) const { return xliminclude.current_value (); }
+
+  bool is_yliminclude (void) const { return yliminclude.is_on (); }
+  std::string get_yliminclude (void) const { return yliminclude.current_value (); }
+
+  bool is_zliminclude (void) const { return zliminclude.is_on (); }
+  std::string get_zliminclude (void) const { return zliminclude.current_value (); }
+
+
+  void set_xdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdata.set (val, true))
+          {
+            update_xdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydata.set (val, true))
+          {
+            update_ydata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zdata.set (val, true))
+          {
+            update_zdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdata.set (val, true))
+          {
+            update_cdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdatamapping (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdatamapping.set (val, false))
+          {
+            update_axis_limits ("cdatamapping");
+            cdatamapping.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_faces (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (faces.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facevertexalphadata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facevertexalphadata.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facevertexcdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facevertexcdata.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_vertices (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (vertices.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_vertexnormals (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (vertexnormals.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_normalmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (normalmode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facealpha (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facealpha.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facelighting (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facelighting.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgealpha (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgealpha.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgelighting (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgelighting.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_backfacelighting (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (backfacelighting.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ambientstrength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ambientstrength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_diffusestrength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (diffusestrength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_specularstrength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (specularstrength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_specularexponent (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (specularexponent.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_specularcolorreflectance (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (specularcolorreflectance.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_erasemode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (erasemode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linestyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linestyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linewidth (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linewidth.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_marker (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (marker.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markeredgecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markeredgecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markerfacecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markerfacecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markersize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markersize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keylabel (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keylabel.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_interpreter (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (interpreter.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alphadatamapping (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alphadatamapping.set (val, false))
+          {
+            update_axis_limits ("alphadatamapping");
+            alphadatamapping.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, false))
+          {
+            update_axis_limits ("xlim");
+            xlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, false))
+          {
+            update_axis_limits ("ylim");
+            ylim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlim.set (val, false))
+          {
+            update_axis_limits ("zlim");
+            zlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_clim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (clim.set (val, false))
+          {
+            update_axis_limits ("clim");
+            clim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alim.set (val, false))
+          {
+            update_axis_limits ("alim");
+            alim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xliminclude.set (val, false))
+          {
+            update_axis_limits ("xliminclude");
+            xliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yliminclude.set (val, false))
+          {
+            update_axis_limits ("yliminclude");
+            yliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zliminclude.set (val, false))
+          {
+            update_axis_limits ("zliminclude");
+            zliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_climinclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (climinclude.set (val, false))
+          {
+            update_axis_limits ("climinclude");
+            climinclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_aliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (aliminclude.set (val, false))
+          {
+            update_axis_limits ("aliminclude");
+            aliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+
+  protected:
+    void init (void)
+      {
+	xdata.add_constraint (dim_vector (-1, -1));
+	ydata.add_constraint (dim_vector (-1, -1));
+	zdata.add_constraint (dim_vector (-1, -1));
+        vertices.add_constraint (dim_vector (-1, 2));
+        vertices.add_constraint (dim_vector (-1, 3));
+	cdata.add_constraint (dim_vector (-1, -1));
+	cdata.add_constraint (dim_vector (-1, -1, 3));
+	facevertexcdata.add_constraint (dim_vector (-1, 1));
+	facevertexcdata.add_constraint (dim_vector (-1, 3));
+	facevertexalphadata.add_constraint (dim_vector (-1, 1));
+      }
+
+  private:
+    void update_xdata (void) { set_xlim (xdata.get_limits ()); }
+    void update_ydata (void) { set_ylim (ydata.get_limits ()); }
+    void update_zdata (void) { set_zlim (zdata.get_limits ()); }
+    
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  patch (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~patch (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API surface : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    octave_value get_color_data (void) const;
+
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    bool is_aliminclude (void) const
+      { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
+    std::string get_aliminclude (void) const
+      { return aliminclude.current_value (); }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  array_property xdata;
+  array_property ydata;
+  array_property zdata;
+  array_property cdata;
+  radio_property cdatamapping;
+  string_property xdatasource;
+  string_property ydatasource;
+  string_property zdatasource;
+  string_property cdatasource;
+  color_property facecolor;
+  double_radio_property facealpha;
+  color_property edgecolor;
+  radio_property linestyle;
+  double_property linewidth;
+  radio_property marker;
+  color_property markeredgecolor;
+  color_property markerfacecolor;
+  double_property markersize;
+  string_property keylabel;
+  radio_property interpreter;
+  array_property alphadata;
+  radio_property alphadatamapping;
+  double_property ambientstrength;
+  radio_property backfacelighting;
+  double_property diffusestrength;
+  double_radio_property edgealpha;
+  radio_property edgelighting;
+  radio_property erasemode;
+  radio_property facelighting;
+  radio_property meshstyle;
+  radio_property normalmode;
+  double_property specularcolorreflectance;
+  double_property specularexponent;
+  double_property specularstrength;
+  array_property vertexnormals;
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property zlim;
+  row_vector_property clim;
+  row_vector_property alim;
+  bool_property xliminclude;
+  bool_property yliminclude;
+  bool_property zliminclude;
+  bool_property climinclude;
+  bool_property aliminclude;
+
+public:
+
+  enum
+  {
+    XDATA = 8000,
+    YDATA = 8001,
+    ZDATA = 8002,
+    CDATA = 8003,
+    CDATAMAPPING = 8004,
+    XDATASOURCE = 8005,
+    YDATASOURCE = 8006,
+    ZDATASOURCE = 8007,
+    CDATASOURCE = 8008,
+    FACECOLOR = 8009,
+    FACEALPHA = 8010,
+    EDGECOLOR = 8011,
+    LINESTYLE = 8012,
+    LINEWIDTH = 8013,
+    MARKER = 8014,
+    MARKEREDGECOLOR = 8015,
+    MARKERFACECOLOR = 8016,
+    MARKERSIZE = 8017,
+    KEYLABEL = 8018,
+    INTERPRETER = 8019,
+    ALPHADATA = 8020,
+    ALPHADATAMAPPING = 8021,
+    AMBIENTSTRENGTH = 8022,
+    BACKFACELIGHTING = 8023,
+    DIFFUSESTRENGTH = 8024,
+    EDGEALPHA = 8025,
+    EDGELIGHTING = 8026,
+    ERASEMODE = 8027,
+    FACELIGHTING = 8028,
+    MESHSTYLE = 8029,
+    NORMALMODE = 8030,
+    SPECULARCOLORREFLECTANCE = 8031,
+    SPECULAREXPONENT = 8032,
+    SPECULARSTRENGTH = 8033,
+    VERTEXNORMALS = 8034,
+    XLIM = 8035,
+    YLIM = 8036,
+    ZLIM = 8037,
+    CLIM = 8038,
+    ALIM = 8039,
+    XLIMINCLUDE = 8040,
+    YLIMINCLUDE = 8041,
+    ZLIMINCLUDE = 8042,
+    CLIMINCLUDE = 8043,
+    ALIMINCLUDE = 8044
+  };
+
+  octave_value get_xdata (void) const { return xdata.get (); }
+
+  octave_value get_ydata (void) const { return ydata.get (); }
+
+  octave_value get_zdata (void) const { return zdata.get (); }
+
+  octave_value get_cdata (void) const { return cdata.get (); }
+
+  bool cdatamapping_is (const std::string& v) const { return cdatamapping.is (v); }
+  std::string get_cdatamapping (void) const { return cdatamapping.current_value (); }
+
+  std::string get_xdatasource (void) const { return xdatasource.string_value (); }
+
+  std::string get_ydatasource (void) const { return ydatasource.string_value (); }
+
+  std::string get_zdatasource (void) const { return zdatasource.string_value (); }
+
+  std::string get_cdatasource (void) const { return cdatasource.string_value (); }
+
+  bool facecolor_is_rgb (void) const { return facecolor.is_rgb (); }
+  bool facecolor_is (const std::string& v) const { return facecolor.is (v); }
+  Matrix get_facecolor_rgb (void) const { return (facecolor.is_rgb () ? facecolor.rgb () : Matrix ()); }
+  octave_value get_facecolor (void) const { return facecolor.get (); }
+
+  bool facealpha_is_double (void) const { return facealpha.is_double (); }
+  bool facealpha_is (const std::string& v) const { return facealpha.is (v); }
+  double get_facealpha_double (void) const { return (facealpha.is_double () ? facealpha.double_value () : 0); }
+  octave_value get_facealpha (void) const { return facealpha.get (); }
+
+  bool edgecolor_is_rgb (void) const { return edgecolor.is_rgb (); }
+  bool edgecolor_is (const std::string& v) const { return edgecolor.is (v); }
+  Matrix get_edgecolor_rgb (void) const { return (edgecolor.is_rgb () ? edgecolor.rgb () : Matrix ()); }
+  octave_value get_edgecolor (void) const { return edgecolor.get (); }
+
+  bool linestyle_is (const std::string& v) const { return linestyle.is (v); }
+  std::string get_linestyle (void) const { return linestyle.current_value (); }
+
+  double get_linewidth (void) const { return linewidth.double_value (); }
+
+  bool marker_is (const std::string& v) const { return marker.is (v); }
+  std::string get_marker (void) const { return marker.current_value (); }
+
+  bool markeredgecolor_is_rgb (void) const { return markeredgecolor.is_rgb (); }
+  bool markeredgecolor_is (const std::string& v) const { return markeredgecolor.is (v); }
+  Matrix get_markeredgecolor_rgb (void) const { return (markeredgecolor.is_rgb () ? markeredgecolor.rgb () : Matrix ()); }
+  octave_value get_markeredgecolor (void) const { return markeredgecolor.get (); }
+
+  bool markerfacecolor_is_rgb (void) const { return markerfacecolor.is_rgb (); }
+  bool markerfacecolor_is (const std::string& v) const { return markerfacecolor.is (v); }
+  Matrix get_markerfacecolor_rgb (void) const { return (markerfacecolor.is_rgb () ? markerfacecolor.rgb () : Matrix ()); }
+  octave_value get_markerfacecolor (void) const { return markerfacecolor.get (); }
+
+  double get_markersize (void) const { return markersize.double_value (); }
+
+  std::string get_keylabel (void) const { return keylabel.string_value (); }
+
+  bool interpreter_is (const std::string& v) const { return interpreter.is (v); }
+  std::string get_interpreter (void) const { return interpreter.current_value (); }
+
+  octave_value get_alphadata (void) const { return alphadata.get (); }
+
+  bool alphadatamapping_is (const std::string& v) const { return alphadatamapping.is (v); }
+  std::string get_alphadatamapping (void) const { return alphadatamapping.current_value (); }
+
+  double get_ambientstrength (void) const { return ambientstrength.double_value (); }
+
+  bool backfacelighting_is (const std::string& v) const { return backfacelighting.is (v); }
+  std::string get_backfacelighting (void) const { return backfacelighting.current_value (); }
+
+  double get_diffusestrength (void) const { return diffusestrength.double_value (); }
+
+  bool edgealpha_is_double (void) const { return edgealpha.is_double (); }
+  bool edgealpha_is (const std::string& v) const { return edgealpha.is (v); }
+  double get_edgealpha_double (void) const { return (edgealpha.is_double () ? edgealpha.double_value () : 0); }
+  octave_value get_edgealpha (void) const { return edgealpha.get (); }
+
+  bool edgelighting_is (const std::string& v) const { return edgelighting.is (v); }
+  std::string get_edgelighting (void) const { return edgelighting.current_value (); }
+
+  bool erasemode_is (const std::string& v) const { return erasemode.is (v); }
+  std::string get_erasemode (void) const { return erasemode.current_value (); }
+
+  bool facelighting_is (const std::string& v) const { return facelighting.is (v); }
+  std::string get_facelighting (void) const { return facelighting.current_value (); }
+
+  bool meshstyle_is (const std::string& v) const { return meshstyle.is (v); }
+  std::string get_meshstyle (void) const { return meshstyle.current_value (); }
+
+  bool normalmode_is (const std::string& v) const { return normalmode.is (v); }
+  std::string get_normalmode (void) const { return normalmode.current_value (); }
+
+  double get_specularcolorreflectance (void) const { return specularcolorreflectance.double_value (); }
+
+  double get_specularexponent (void) const { return specularexponent.double_value (); }
+
+  double get_specularstrength (void) const { return specularstrength.double_value (); }
+
+  octave_value get_vertexnormals (void) const { return vertexnormals.get (); }
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_zlim (void) const { return zlim.get (); }
+
+  octave_value get_clim (void) const { return clim.get (); }
+
+  octave_value get_alim (void) const { return alim.get (); }
+
+  bool is_xliminclude (void) const { return xliminclude.is_on (); }
+  std::string get_xliminclude (void) const { return xliminclude.current_value (); }
+
+  bool is_yliminclude (void) const { return yliminclude.is_on (); }
+  std::string get_yliminclude (void) const { return yliminclude.current_value (); }
+
+  bool is_zliminclude (void) const { return zliminclude.is_on (); }
+  std::string get_zliminclude (void) const { return zliminclude.current_value (); }
+
+
+  void set_xdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdata.set (val, true))
+          {
+            update_xdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydata.set (val, true))
+          {
+            update_ydata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zdata.set (val, true))
+          {
+            update_zdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdata.set (val, true))
+          {
+            update_cdata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdatamapping (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdatamapping.set (val, false))
+          {
+            update_axis_limits ("cdatamapping");
+            cdatamapping.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xdatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xdatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ydatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ydatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zdatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zdatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_cdatasource (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (cdatasource.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facealpha (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facealpha.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linestyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linestyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_linewidth (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (linewidth.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_marker (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (marker.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markeredgecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markeredgecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markerfacecolor (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markerfacecolor.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_markersize (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (markersize.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_keylabel (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (keylabel.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_interpreter (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (interpreter.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alphadata (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alphadata.set (val, true))
+          {
+            update_alphadata ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alphadatamapping (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alphadatamapping.set (val, false))
+          {
+            update_axis_limits ("alphadatamapping");
+            alphadatamapping.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ambientstrength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ambientstrength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_backfacelighting (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (backfacelighting.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_diffusestrength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (diffusestrength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgealpha (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgealpha.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_edgelighting (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (edgelighting.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_erasemode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (erasemode.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_facelighting (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (facelighting.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_meshstyle (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (meshstyle.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_normalmode (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (normalmode.set (val, true))
+          {
+            update_normalmode ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_specularcolorreflectance (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (specularcolorreflectance.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_specularexponent (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (specularexponent.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_specularstrength (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (specularstrength.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_vertexnormals (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (vertexnormals.set (val, true))
+          {
+            update_vertexnormals ();
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, false))
+          {
+            update_axis_limits ("xlim");
+            xlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, false))
+          {
+            update_axis_limits ("ylim");
+            ylim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlim.set (val, false))
+          {
+            update_axis_limits ("zlim");
+            zlim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_clim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (clim.set (val, false))
+          {
+            update_axis_limits ("clim");
+            clim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alim.set (val, false))
+          {
+            update_axis_limits ("alim");
+            alim.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xliminclude.set (val, false))
+          {
+            update_axis_limits ("xliminclude");
+            xliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yliminclude.set (val, false))
+          {
+            update_axis_limits ("yliminclude");
+            yliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zliminclude.set (val, false))
+          {
+            update_axis_limits ("zliminclude");
+            zliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_climinclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (climinclude.set (val, false))
+          {
+            update_axis_limits ("climinclude");
+            climinclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_aliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (aliminclude.set (val, false))
+          {
+            update_axis_limits ("aliminclude");
+            aliminclude.run_listeners (POSTSET);
+            mark_modified ();
+          }
+      }
+  }
+
+
+  protected:
+    void init (void)
+      {
+	xdata.add_constraint (dim_vector (-1, -1));
+	ydata.add_constraint (dim_vector (-1, -1));
+	zdata.add_constraint (dim_vector (-1, -1));
+	alphadata.add_constraint ("double");
+	alphadata.add_constraint ("uint8");
+	alphadata.add_constraint (dim_vector (-1, -1));
+	vertexnormals.add_constraint (dim_vector (-1, -1, 3));
+	cdata.add_constraint ("double");
+	cdata.add_constraint ("uint8");
+	cdata.add_constraint (dim_vector (-1, -1));
+	cdata.add_constraint (dim_vector (-1, -1, 3));
+      }
+
+  private:
+    void update_normals (void);
+
+    void update_xdata (void)
+      {
+	update_normals ();
+	set_xlim (xdata.get_limits ());
+      }
+ 
+    void update_ydata (void)
+      {
+	update_normals ();
+	set_ylim (ydata.get_limits ());
+      }
+
+    void update_zdata (void)
+      {
+	update_normals ();
+	set_zlim (zdata.get_limits ());
+      }
+
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+
+    void update_alphadata (void)
+      {
+	if (alphadatamapping_is ("scaled"))
+	  set_alim (alphadata.get_limits ());
+	else
+	  alim = alphadata.get_limits ();
+      }
+
+    void update_normalmode (void)
+      { update_normals (); }
+
+    void update_vertexnormals (void)
+      { set_normalmode ("manual"); }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  surface (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~surface (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API hggroup : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void remove_child (const graphics_handle& h)
+      {
+	base_properties::remove_child (h);
+	update_limits ();
+      }
+
+    void adopt (const graphics_handle& h)
+      {
+	base_properties::adopt (h);
+	update_limits ();
+      }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+public:
+  properties (const graphics_handle& mh, const graphics_handle& p);
+
+  ~properties (void) { }
+
+  void set (const caseless_str& pname, const octave_value& val);
+
+  octave_value get (bool all = false) const;
+
+  octave_value get (const caseless_str& pname) const;
+
+  property get_property (const caseless_str& pname);
+
+  std::string graphics_object_name (void) const { return go_name; }
+
+  static property_list::pval_map_type factory_defaults (void);
+
+private:
+  static std::string go_name;
+
+public:
+
+
+  static bool has_property (const std::string& pname);
+
+private:
+
+  row_vector_property xlim;
+  row_vector_property ylim;
+  row_vector_property zlim;
+  row_vector_property clim;
+  row_vector_property alim;
+  bool_property xliminclude;
+  bool_property yliminclude;
+  bool_property zliminclude;
+  bool_property climinclude;
+  bool_property aliminclude;
+
+public:
+
+  enum
+  {
+    XLIM = 9000,
+    YLIM = 9001,
+    ZLIM = 9002,
+    CLIM = 9003,
+    ALIM = 9004,
+    XLIMINCLUDE = 9005,
+    YLIMINCLUDE = 9006,
+    ZLIMINCLUDE = 9007,
+    CLIMINCLUDE = 9008,
+    ALIMINCLUDE = 9009
+  };
+
+  octave_value get_xlim (void) const { return xlim.get (); }
+
+  octave_value get_ylim (void) const { return ylim.get (); }
+
+  octave_value get_zlim (void) const { return zlim.get (); }
+
+  octave_value get_clim (void) const { return clim.get (); }
+
+  octave_value get_alim (void) const { return alim.get (); }
+
+  bool is_xliminclude (void) const { return xliminclude.is_on (); }
+  std::string get_xliminclude (void) const { return xliminclude.current_value (); }
+
+  bool is_yliminclude (void) const { return yliminclude.is_on (); }
+  std::string get_yliminclude (void) const { return yliminclude.current_value (); }
+
+  bool is_zliminclude (void) const { return zliminclude.is_on (); }
+  std::string get_zliminclude (void) const { return zliminclude.current_value (); }
+
+  bool is_climinclude (void) const { return climinclude.is_on (); }
+  std::string get_climinclude (void) const { return climinclude.current_value (); }
+
+  bool is_aliminclude (void) const { return aliminclude.is_on (); }
+  std::string get_aliminclude (void) const { return aliminclude.current_value (); }
+
+
+  void set_xlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xlim.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_ylim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (ylim.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zlim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zlim.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_clim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (clim.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_alim (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (alim.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_xliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (xliminclude.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_yliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (yliminclude.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_zliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (zliminclude.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_climinclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (climinclude.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+  void set_aliminclude (const octave_value& val)
+  {
+    if (! error_state)
+      {
+        if (aliminclude.set (val, true))
+          {
+            mark_modified ();
+          }
+      }
+  }
+
+
+  private:
+    void update_limits (void)
+      {
+	update_axis_limits ("xlim");
+	update_axis_limits ("ylim");
+	update_axis_limits ("zlim");
+	update_axis_limits ("clim");
+	update_axis_limits ("alim");
+      }
+
+  protected:
+    void init (void)
+      { }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  hggroup (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~hggroup (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+  
+  void update_axis_limits (const std::string& axis_type);
+};
+
+// ---------------------------------------------------------------------
+
+octave_value
+get_property_from_handle (double handle, const std::string &property,
+			  const std::string &func);
+bool
+set_property_in_handle (double handle, const std::string &property,
+			const octave_value &arg, const std::string &func);
+
+// ---------------------------------------------------------------------
+
+class graphics_event;
+
+class
+base_graphics_event
+{
+public:
+  friend class graphics_event;
+
+  base_graphics_event (void) : count (1) { }
+
+  virtual ~base_graphics_event (void) { }
+
+  virtual void execute (void) = 0;
+
+private:
+  int count;
+};
+
+class
+graphics_event
+{
+public:
+  typedef void (*event_fcn) (void*);
+
+  graphics_event (void) : rep (0) { }
+
+  graphics_event (const graphics_event& e)
+    {
+      rep = e.rep;
+      rep->count++;
+    }
+
+  ~graphics_event (void)
+    {
+      if (rep && --rep->count == 0)
+	delete rep;
+    }
+
+  graphics_event& operator = (const graphics_event& e)
+    {
+      if (rep != e.rep)
+	{
+	  if (rep && --rep->count == 0)
+	    delete rep;
+
+	  rep = e.rep;
+	  if (rep)
+	    rep->count++;
+	}
+
+      return *this;
+    }
+
+  void execute (void)
+    { if (rep) rep->execute (); }
+
+  bool ok (void) const
+    { return (rep != 0); }
+
+  static graphics_event
+      create_callback_event (const graphics_handle& h,
+			     const std::string& name,
+			     const octave_value& data = Matrix ());
+
+  static graphics_event
+      create_function_event (event_fcn fcn, void *data = 0);
+
+  static graphics_event
+      create_set_event (const graphics_handle& h,
+			const std::string& name,
+			const octave_value& value);
+private:
+  base_graphics_event *rep;
+};
+
+class OCTINTERP_API gh_manager
+{
+protected:
+
+  gh_manager (void);
+
+public:
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new gh_manager ();
+
+    if (! instance)
+      {
+	::error ("unable to create gh_manager!");
+
+	retval = false;
+      }
+
+    return retval;
+  }
+
+  static void free (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_free (h);
+  }
+
+  static graphics_handle lookup (double val)
+  {
+    return instance_ok () ? instance->do_lookup (val) : graphics_handle ();
+  }
+
+  static graphics_object get_object (const graphics_handle& h)
+  {
+    return instance_ok () ? instance->do_get_object (h) : graphics_object ();
+  }
+
+  static graphics_handle
+  make_graphics_handle (const std::string& go_name,
+			const graphics_handle& parent, bool do_createfcn = true)
+  {
+    return instance_ok ()
+      ? instance->do_make_graphics_handle (go_name, parent, do_createfcn)
+      : graphics_handle ();
+  }
+
+  static graphics_handle make_figure_handle (double val)
+  {
+    return instance_ok ()
+      ? instance->do_make_figure_handle (val) : graphics_handle ();
+  }
+
+  static void push_figure (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_push_figure (h);
+  }
+
+  static void pop_figure (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_pop_figure (h);
+  }
+
+  static graphics_handle current_figure (void)
+  {
+    return instance_ok ()
+      ? instance->do_current_figure () : graphics_handle ();
+  }
+
+  static Matrix handle_list (void)
+  {
+    return instance_ok () ? instance->do_handle_list () : Matrix ();
+  }
+
+  static void lock (void)
+  {
+    if (instance_ok ())
+      instance->do_lock ();
+  }
+
+  static void unlock (void)
+  {
+    if (instance_ok ())
+      instance->do_unlock ();
+  }
+
+  static Matrix figure_handle_list (void)
+  {
+    return instance_ok () ? instance->do_figure_handle_list () : Matrix ();
+  }
+
+  static void execute_callback (const graphics_handle& h,
+				const std::string& name,
+				const octave_value& data = Matrix ())
+  {
+    graphics_object go = get_object (h);
+
+    if (go.valid_object ())
+      {
+	octave_value cb = go.get (name);
+
+	if (! error_state)
+	  execute_callback (h, cb, data);
+      }
+  }
+
+  static void execute_callback (const graphics_handle& h,
+				const octave_value& cb,
+				const octave_value& data = Matrix ())
+  {
+    if (instance_ok ())
+      instance->do_execute_callback (h, cb, data);
+  }
+
+  static void post_callback (const graphics_handle& h,
+			     const std::string& name,
+			     const octave_value& data = Matrix ())
+  {
+    if (instance_ok ())
+      instance->do_post_callback (h, name, data);
+  }
+
+  static void post_function (graphics_event::event_fcn fcn, void* data = 0)
+  {
+    if (instance_ok ())
+      instance->do_post_function (fcn, data);
+  }
+
+  static void post_set (const graphics_handle& h,
+			const std::string& name,
+			const octave_value& value)
+  {
+    if (instance_ok ())
+      instance->do_post_set (h, name, value);
+  }
+
+  static int process_events (void)
+  {
+    return (instance_ok () ?  instance->do_process_events () : 0);
+  }
+
+  static int flush_events (void)
+  {
+    return (instance_ok () ?  instance->do_process_events (true) : 0);
+  }
+
+  static bool is_handle_visible (const graphics_handle& h)
+  {
+    bool retval = false;
+
+    graphics_object go = get_object (h);
+
+    if (go.valid_object ())
+      retval = go.is_handle_visible ();
+
+    return retval;
+  }
+
+public:
+  class autolock
+  {
+  public:
+    autolock (void) { lock (); }
+
+    ~autolock (void) { unlock (); }
+
+  private:
+
+    // No copying!
+    autolock (const autolock&);
+    autolock& operator = (const autolock&);
+  };
+
+private:
+
+  static gh_manager *instance;
+
+  typedef std::map<graphics_handle, graphics_object>::iterator iterator;
+  typedef std::map<graphics_handle, graphics_object>::const_iterator const_iterator;
+
+  typedef std::set<graphics_handle>::iterator free_list_iterator;
+  typedef std::set<graphics_handle>::const_iterator const_free_list_iterator;
+
+  typedef std::list<graphics_handle>::iterator figure_list_iterator;
+  typedef std::list<graphics_handle>::const_iterator const_figure_list_iterator;
+
+  // A map of handles to graphics objects.
+  std::map<graphics_handle, graphics_object> handle_map;
+
+  // The available graphics handles.
+  std::set<graphics_handle> handle_free_list;
+
+  // The next handle available if handle_free_list is empty.
+  double next_handle;
+
+  // The allocated figure handles.  Top of the stack is most recently
+  // created.
+  std::list<graphics_handle> figure_list;
+
+  // The lock for accessing the graphics sytsem
+  octave_mutex graphics_lock;
+
+  // The list of event queued by backends
+  std::list<graphics_event> event_queue;
+
+  // The stack of callback objects
+  std::list<graphics_object> callback_objects;
+
+  graphics_handle get_handle (const std::string& go_name);
+
+  void do_free (const graphics_handle& h);
+
+  graphics_handle do_lookup (double val)
+  {
+    iterator p = (xisnan (val) ? handle_map.end () : handle_map.find (val));
+
+    return (p != handle_map.end ()) ? p->first : graphics_handle ();
+  }
+
+  graphics_object do_get_object (const graphics_handle& h)
+  {
+    iterator p = (h.ok () ? handle_map.find (h) : handle_map.end ());
+
+    return (p != handle_map.end ()) ? p->second : graphics_object ();
+  }
+
+  graphics_handle do_make_graphics_handle (const std::string& go_name,
+					   const graphics_handle& p, bool do_createfcn);
+
+  graphics_handle do_make_figure_handle (double val);
+
+  Matrix do_handle_list (void)
+  {
+    Matrix retval (1, handle_map.size ());
+    octave_idx_type i = 0;
+    for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++)
+      {
+	graphics_handle h = p->first;
+	retval(i++) = h.value ();
+      }
+    return retval;
+  }
+
+  Matrix do_figure_handle_list (void)
+  {
+    Matrix retval (1, figure_list.size ());
+    octave_idx_type i = 0;
+    for (const_figure_list_iterator p = figure_list.begin ();
+	 p != figure_list.end ();
+	 p++)
+      {
+	graphics_handle h = *p;
+	retval(i++) = h.value ();
+      }
+    return retval;
+  }
+
+  void do_push_figure (const graphics_handle& h);
+
+  void do_pop_figure (const graphics_handle& h);
+
+  graphics_handle do_current_figure (void) const
+  {
+    return figure_list.empty () ? graphics_handle () : figure_list.front ();
+  }
+
+  void do_lock (void) { graphics_lock.lock (); }
+  
+  void do_unlock (void) { graphics_lock.unlock (); }
+
+  void do_execute_callback (const graphics_handle& h, const octave_value& cb,
+			    const octave_value& data);
+
+  void do_post_callback (const graphics_handle& h, const std::string name,
+			 const octave_value& data);
+
+  void do_post_function (graphics_event::event_fcn fcn, void* fcn_data);
+
+  void do_post_set (const graphics_handle& h, const std::string name,
+		    const octave_value& value);
+
+  int do_process_events (bool force = false);
+
+  static void restore_gcbo (void*)
+  {
+    if (instance_ok ())
+      instance->do_restore_gcbo ();
+  }
+
+  void do_restore_gcbo (void);
+
+  void do_post_event (const graphics_event& e);
+};
+
+
+// This function is NOT equivalent to the scripting language function gcf.
+OCTINTERP_API graphics_handle gcf (void);
+
+// This function is NOT equivalent to the scripting language function gca.
+OCTINTERP_API graphics_handle gca (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/graphics.h.in b/src/graphics.h.in
new file mode 100644
index 0000000..e6cbb44
--- /dev/null
+++ b/src/graphics.h.in
@@ -0,0 +1,3884 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (graphics_h)
+#define graphics_h 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include "lo-ieee.h"
+
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-mutex.h"
+#include "ov.h"
+
+// FIXME -- maybe this should be a configure option?
+// Matlab defaults to "Helvetica", but that causes problems for many
+// gnuplot users.
+#if !defined (OCTAVE_DEFAULT_FONTNAME)
+#define OCTAVE_DEFAULT_FONTNAME "*"
+#endif
+
+class caseless_str : public std::string
+{
+public:
+  typedef std::string::iterator iterator;
+  typedef std::string::const_iterator const_iterator;
+
+  caseless_str (void) : std::string () { }
+  caseless_str (const std::string& s) : std::string (s) { }
+  caseless_str (const char *s) : std::string (s) { }
+
+  caseless_str (const caseless_str& name) : std::string (name) { }
+
+  caseless_str& operator = (const caseless_str& pname)
+  {
+    std::string::operator = (pname);
+    return *this;
+  }
+
+  operator std::string (void) const { return *this; }
+
+  // Case-insensitive comparison.
+  bool compare (const std::string& s, size_t limit = std::string::npos) const
+  {
+    const_iterator p1 = begin ();
+    const_iterator p2 = s.begin ();
+
+    size_t k = 0;
+
+    while (p1 != end () && p2 != s.end () && k++ < limit)
+      {
+	if (std::tolower (*p1) != std::tolower (*p2))
+	  return false;
+
+	*p1++;
+	*p2++;
+      }
+
+    return (limit == std::string::npos) ? size () == s.size () : k == limit;
+  }
+};
+
+// ---------------------------------------------------------------------
+
+class graphics_handle
+{
+public:
+  graphics_handle (void) : val (octave_NaN) { }
+
+  graphics_handle (const octave_value& a);
+
+  graphics_handle (int a) : val (a) { }
+
+  graphics_handle (double a) : val (a) { }
+
+  graphics_handle (const graphics_handle& a) : val (a.val) { }
+
+  graphics_handle& operator = (const graphics_handle& a)
+  {
+    if (&a != this)
+      val = a.val;
+
+    return *this;
+  }
+
+  ~graphics_handle (void) { }
+
+  double value (void) const { return val; }
+
+  octave_value as_octave_value (void) const
+  {
+    return ok () ? octave_value (val) : octave_value (Matrix ());
+  }
+
+  graphics_handle operator ++ (void)
+  {
+    ++val;
+    return *this;
+  }
+
+  graphics_handle operator ++ (int)
+  {
+    graphics_handle h = *this;
+    ++val;
+    return h;
+  }
+
+  graphics_handle operator -- (void)
+  {
+    --val;
+    return *this;
+  }
+
+  graphics_handle operator -- (int)
+  {
+    graphics_handle h = *this;
+    --val;
+    return h;
+  }
+
+  bool ok (void) const { return ! xisnan (val); }
+
+private:
+  double val;
+};
+
+inline bool
+operator == (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () == b.value ();
+}
+
+inline bool
+operator != (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () != b.value ();
+}
+
+inline bool
+operator < (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () < b.value ();
+}
+
+inline bool
+operator <= (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () <= b.value ();
+}
+
+inline bool
+operator >= (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () >= b.value ();
+}
+
+inline bool
+operator > (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () > b.value ();
+}
+
+// ---------------------------------------------------------------------
+
+class base_scaler
+{
+public:
+  base_scaler (void) { }
+
+  virtual ~base_scaler (void) { }
+
+  virtual Matrix scale (const Matrix& m) const
+    {
+      error ("invalid axis scale");
+      return m;
+    }
+
+  virtual NDArray scale (const NDArray& m) const
+    {
+      error ("invalid axis scale");
+      return m;
+    }
+
+  virtual double scale (double d) const
+    {
+      error ("invalid axis scale");
+      return d;
+    }
+  
+  virtual double unscale (double d) const
+    {
+      error ("invalid axis scale");
+      return d;
+    }
+
+  virtual base_scaler* clone () const
+    { return new base_scaler (); }
+
+  virtual bool is_linear (void) const
+    { return false; }
+};
+
+class lin_scaler : public base_scaler
+{
+public:
+  lin_scaler (void) { }
+
+  Matrix scale (const Matrix& m) const { return m; }
+
+  NDArray scale (const NDArray& m) const { return m; }
+
+  double scale (double d) const { return d; }
+
+  double unscale (double d) const { return d; }
+
+  base_scaler* clone (void) const { return new lin_scaler (); }
+
+  bool is_linear (void) const { return true; }
+};
+
+class log_scaler : public base_scaler
+{
+public:
+  log_scaler (void) { }
+
+  Matrix scale (const Matrix& m) const
+    {
+      Matrix retval (m.rows (), m.cols ());
+
+      do_scale (m.data (), retval.fortran_vec (), m.numel ());
+      return retval;
+    }
+
+  NDArray scale (const NDArray& m) const
+    {
+      NDArray retval (m.dims ());
+
+      do_scale (m.data (), retval.fortran_vec (), m.numel ());
+      return retval;
+    }
+
+  double scale (double d) const
+    { return log10 (d); }
+
+  double unscale (double d) const
+    { return pow (10.0, d); }
+
+  base_scaler* clone (void) const
+    { return new log_scaler (); }
+
+private:
+  void do_scale (const double *src, double *dest, int n) const
+    {
+      for (int i = 0; i < n; i++)
+	dest[i] = log10(src[i]);
+    }
+};
+
+class scaler
+{
+public:
+  scaler (void) : rep (new base_scaler ()) { }
+
+  scaler (const scaler& s) : rep (s.rep->clone()) { }
+
+  ~scaler (void) { delete rep; }
+
+  Matrix scale (const Matrix& m) const
+    { return rep->scale (m); }
+
+  NDArray scale (const NDArray& m) const
+    { return rep->scale (m); }
+
+  double scale (double d) const
+    { return rep->scale (d); }
+
+  double unscale (double d) const
+    { return rep->unscale (d); }
+
+  bool is_linear (void) const
+    { return rep->is_linear (); }
+
+  scaler& operator = (const scaler& s)
+    {
+      if (rep)
+	{
+	  delete rep;
+	  rep = 0;
+	}
+
+      rep = s.rep->clone ();
+
+      return *this;
+    }
+
+  scaler& operator = (const std::string& s)
+    {
+      if (rep)
+	{
+	  delete rep;
+	  rep = 0;
+	}
+
+      if (s == "log")
+	rep = new log_scaler ();
+      else if (s == "linear")
+	rep = new lin_scaler ();
+      else
+	rep = new base_scaler ();
+
+      return *this;
+    }
+
+private:
+  base_scaler *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class property;
+
+enum listener_mode { POSTSET };
+
+class base_property
+{
+public:
+  friend class property;
+
+public:
+  base_property (void) : id (-1), count (1) { }
+
+  base_property (const std::string& s, const graphics_handle& h)
+    : id (-1), count (1), name (s), parent (h), hidden (false) { }
+
+  base_property (const base_property& p)
+    : id (-1), count (1), name (p.name), parent (p.parent), hidden (p.hidden) { }
+
+  virtual ~base_property (void) { }
+
+  bool ok (void) const { return parent.ok (); }
+
+  std::string get_name (void) const { return name; }
+
+  void set_name (const std::string& s) { name = s; }
+
+  graphics_handle get_parent (void) const { return parent; }
+
+  void set_parent (const graphics_handle &h) { parent = h; }
+
+  bool is_hidden (void) const { return hidden; }
+
+  void set_hidden (bool flag) { hidden = flag; }
+
+  int get_id (void) const { return id; }
+
+  void set_id (int d) { id = d; }
+
+  // Sets property value, notifies backend.
+  // If do_run is true, runs associated listeners.
+  bool set (const octave_value& v, bool do_run = true);
+  
+  virtual octave_value get (void) const
+    {
+      error ("get: invalid property \"%s\"", name.c_str ());
+      return octave_value ();
+    }
+
+  base_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  void add_listener (const octave_value& v, listener_mode mode = POSTSET)
+    {
+      octave_value_list& l = listeners[mode];
+      l.resize (l.length () + 1, v);
+    }
+
+  void delete_listener (const octave_value& v = octave_value (), 
+			listener_mode mode = POSTSET)
+    {
+      octave_value_list& l = listeners[mode];
+
+      if (v.is_defined ())
+	{
+	  bool found = false;
+	  int i;
+
+	  for (i = 0; i < l.length (); i++)
+	    {
+	      if (v.internal_rep () == l(i).internal_rep ())
+		{
+		  found = true;
+		  break;
+		}
+	    }
+	  if (found)
+	    {
+	      for (int j = i; j < l.length() - 1; j++)
+		l(j) = l (j + 1);
+
+	      l.resize (l.length () - 1);
+	    }
+	}
+      else
+	l.resize (0);
+
+    }
+
+  OCTINTERP_API void run_listeners (listener_mode mode = POSTSET);
+
+  virtual base_property* clone (void) const
+    { return new base_property (*this); }
+
+protected:
+  virtual bool do_set (const octave_value&)
+    {
+      error ("set: invalid property \"%s\"", name.c_str ());
+      return false;
+    }
+
+private:
+  typedef std::map<listener_mode, octave_value_list> listener_map;
+  typedef std::map<listener_mode, octave_value_list>::iterator listener_map_iterator;
+  typedef std::map<listener_mode, octave_value_list>::const_iterator listener_map_const_iterator;
+
+private:
+  int id;
+  int count;
+  std::string name;
+  graphics_handle parent;
+  bool hidden;
+  listener_map listeners;
+};
+
+// ---------------------------------------------------------------------
+
+class string_property : public base_property
+{
+public:
+  string_property (const std::string& s, const graphics_handle& h,
+                   const std::string& val = "")
+    : base_property (s, h), str (val) { }
+
+  string_property (const string_property& p)
+    : base_property (p), str (p.str) { }
+
+  octave_value get (void) const
+    { return octave_value (str); }
+
+  std::string string_value (void) const { return str; }
+
+  string_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new string_property (*this); }
+
+protected:
+  bool do_set (const octave_value& val)
+    {
+      if (val.is_string ())
+	{
+	  std::string new_str = val.string_value ();
+
+	  if (new_str != str)
+	    {
+	      str = new_str;
+	      return true;
+	    }
+	}
+      else
+        error ("set: invalid string property value for \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  std::string str;
+};
+
+// ---------------------------------------------------------------------
+
+class radio_values
+{
+public:
+  OCTINTERP_API radio_values (const std::string& opt_string = std::string ());
+
+  radio_values (const radio_values& a)
+    : default_val (a.default_val), possible_vals (a.possible_vals) { }
+
+  radio_values& operator = (const radio_values& a)
+  {
+    if (&a != this)
+      {
+	default_val = a.default_val;
+	possible_vals = a.possible_vals;
+      }
+
+    return *this;
+  }
+
+  std::string default_value (void) const { return default_val; }
+
+  bool validate (const std::string& val)
+  {
+    bool retval = true;
+
+    if (! contains (val))
+      {
+	error ("invalid value = %s", val.c_str ());
+	retval = false;
+      }
+
+    return retval;
+  }
+  
+  bool contains (const std::string& val)
+  {
+    return (possible_vals.find (val) != possible_vals.end ());
+  }
+
+private:
+  // Might also want to cache
+  std::string default_val;
+  std::set<caseless_str> possible_vals;
+};
+
+class radio_property : public base_property
+{
+public:
+  radio_property (const std::string& nm, const graphics_handle& h,
+                  const radio_values& v = radio_values ())
+    : base_property (nm, h),
+      vals (v), current_val (v.default_value ()) { }
+
+  radio_property (const std::string& nm, const graphics_handle& h,
+                  const std::string& v)
+    : base_property (nm, h),
+      vals (v), current_val (vals.default_value ()) { }
+
+  radio_property (const std::string& nm, const graphics_handle& h,
+                  const radio_values& v, const std::string& def)
+    : base_property (nm, h),
+      vals (v), current_val (def) { }
+
+  radio_property (const radio_property& p)
+    : base_property (p), vals (p.vals), current_val (p.current_val) { }
+
+  octave_value get (void) const { return octave_value (current_val); }
+
+  const std::string& current_value (void) const { return current_val; }
+
+  bool is (const caseless_str& v) const
+    { return v.compare (current_val); }
+
+  radio_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new radio_property (*this); }
+
+protected:
+  bool do_set (const octave_value& newval) 
+  {
+    if (newval.is_string ())
+      {
+        std::string s = newval.string_value ();
+        if (vals.validate (s))
+	  {
+	    if (s != current_val)
+	      {
+		current_val = s;
+		return true;
+	      }
+	  }
+        else
+          error ("set: invalid value for radio property \"%s\" (value = %s)",
+              get_name ().c_str (), s.c_str ());
+      }
+    else	
+      error ("set: invalid value for radio property \"%s\"",
+          get_name ().c_str ());
+    return false;
+  }
+
+private:
+  radio_values vals;
+  std::string current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class color_values
+{
+public:
+  color_values (double r = 0, double g = 0, double b = 1)
+    : xrgb (1, 3)
+  {
+    xrgb(0) = r;
+    xrgb(1) = g;
+    xrgb(2) = b;
+
+    validate ();
+  }
+
+  color_values (std::string str)
+    : xrgb (1, 3)
+  {
+    if (! str2rgb (str))
+      error ("invalid color specification: %s", str.c_str ());
+  }
+
+  color_values (const color_values& c)
+    : xrgb (c.xrgb)
+  { }
+
+  color_values& operator = (const color_values& c)
+  {
+    if (&c != this)
+      xrgb = c.xrgb;
+
+    return *this;
+  }
+
+  bool operator == (const color_values& c) const
+    {
+      return (xrgb(0) == c.xrgb(0)
+	      && xrgb(1) == c.xrgb(1)
+	      && xrgb(2) == c.xrgb(2));
+    }
+
+  bool operator != (const color_values& c) const
+    { return ! (*this == c); }
+
+  Matrix rgb (void) const { return xrgb; }
+
+  operator octave_value (void) const { return xrgb; }
+
+  void validate (void) const
+  {
+    for (int i = 0; i < 3; i++)
+      {
+	if (xrgb(i) < 0 ||  xrgb(i) > 1)
+	  {
+	    error ("invalid RGB color specification");
+	    break;
+	  }
+      }
+  }
+
+private:
+  Matrix xrgb;
+
+  OCTINTERP_API bool str2rgb (std::string str);
+};
+
+class color_property : public base_property
+{
+public:
+  color_property (const color_values& c, const radio_values& v)
+    : base_property ("", graphics_handle ()),
+      current_type (color_t), color_val (c), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const color_values& c = color_values (),
+                  const radio_values& v = radio_values ())
+    : base_property (nm, h),
+      current_type (color_t), color_val (c), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const radio_values& v)
+    : base_property (nm, h),
+      current_type (radio_t), color_val (color_values ()), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const std::string& v)
+    : base_property (nm, h),
+      current_type (radio_t), color_val (color_values ()), radio_val (v),
+      current_val (radio_val.default_value ())
+  { }
+  
+  color_property (const std::string& nm, const graphics_handle& h,
+                  const color_property& v)
+    : base_property (nm, h),
+      current_type (v.current_type), color_val (v.color_val),
+      radio_val (v.radio_val), current_val (v.current_val)
+  { }
+
+  color_property (const color_property& p)
+    : base_property (p), current_type (p.current_type),
+      color_val (p.color_val), radio_val (p.radio_val),
+      current_val (p.current_val) { }
+
+  octave_value get (void) const
+  {
+    if (current_type == color_t)
+      return color_val.rgb ();
+
+    return current_val;
+  }
+
+  bool is_rgb (void) const { return (current_type == color_t); }
+
+  bool is_radio (void) const { return (current_type == radio_t); }
+
+  bool is (const std::string& v) const
+    { return (is_radio () && current_val == v); }
+
+  Matrix rgb (void) const
+  {
+    if (current_type != color_t)
+      error ("color has no rgb value");
+
+    return color_val.rgb ();
+  }
+
+  const std::string& current_value (void) const
+  {
+    if (current_type != radio_t)
+      error ("color has no radio value");
+
+    return current_val;
+  }
+
+  color_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  operator octave_value (void) const { return get (); }
+
+  base_property* clone (void) const { return new color_property (*this); }
+
+protected:
+  OCTINTERP_API bool do_set (const octave_value& newval);
+
+private:
+  enum current_enum { color_t, radio_t } current_type;
+  color_values color_val;
+  radio_values radio_val;
+  std::string current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class double_property : public base_property
+{
+public:
+  double_property (const std::string& nm, const graphics_handle& h,
+                   double d = 0)
+    : base_property (nm, h),
+      current_val (d) { }
+
+  double_property (const double_property& p)
+    : base_property (p), current_val (p.current_val) { }
+
+  octave_value get (void) const { return octave_value (current_val); }
+
+  double double_value (void) const { return current_val; }
+
+  double_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new double_property (*this); }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      if (v.is_scalar_type () && v.is_real_type ())
+	{
+	  double new_val = v.double_value ();
+
+	  if (new_val != current_val)
+	    {
+	      current_val = new_val;
+	      return true;
+	    }
+	}
+      else
+        error ("set: invalid value for double property \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  double current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class double_radio_property : public base_property
+{
+public:
+  double_radio_property (double d, const radio_values& v)
+      : base_property ("", graphics_handle ()),
+        current_type (double_t), dval (d), radio_val (v),
+	current_val (v.default_value ())
+  { }
+
+  double_radio_property (const std::string& nm, const graphics_handle& h,
+			 const std::string& v)
+      : base_property (nm, h),
+        current_type (radio_t), dval (0), radio_val (v),
+	current_val (radio_val.default_value ())
+  { }
+
+  double_radio_property (const std::string& nm, const graphics_handle& h,
+			 const double_radio_property& v)
+      : base_property (nm, h),
+        current_type (v.current_type), dval (v.dval),
+	radio_val (v.radio_val), current_val (v.current_val)
+  { }
+
+  double_radio_property (const double_radio_property& p)
+    : base_property (p), current_type (p.current_type),
+      dval (p.dval), radio_val (p.radio_val),
+      current_val (p.current_val) { }
+
+  octave_value get (void) const
+  {
+    if (current_type == double_t)
+      return dval;
+
+    return current_val;
+  }
+
+  bool is_double (void) const { return (current_type == double_t); }
+
+  bool is_radio (void) const { return (current_type == radio_t); }
+
+  bool is (const std::string& v) const
+    { return (is_radio () && current_val == v); }
+
+  double double_value (void) const
+  {
+    if (current_type != double_t)
+      error ("%s: property has no double", get_name ().c_str ());
+
+    return dval;
+  }
+
+  const std::string& current_value (void) const
+  {
+    if (current_type != radio_t)
+      error ("%s: property has no radio value");
+
+    return current_val;
+  }
+
+  double_radio_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  operator octave_value (void) const { return get (); }
+
+  base_property* clone (void) const
+    { return new double_radio_property (*this); }
+
+protected:
+  OCTINTERP_API bool do_set (const octave_value& v);
+
+private:
+  enum current_enum { double_t, radio_t } current_type;
+  double dval;
+  radio_values radio_val;
+  std::string current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class array_property : public base_property
+{
+public:
+  array_property (void)
+      : base_property ("", graphics_handle ()), data (Matrix ())
+    {
+      get_data_limits ();
+    }
+
+  array_property (const std::string& nm, const graphics_handle& h,
+                  const octave_value& m)
+      : base_property (nm, h), data (m)
+    {
+      get_data_limits ();
+    }
+
+  // This copy constructor is only intended to be used
+  // internally to access min/max values; no need to
+  // copy constraints.
+  array_property (const array_property& p)
+    : base_property (p), data (p.data),
+      xmin (p.xmin), xmax (p.xmax), xminp (p.xminp) { }
+
+  octave_value get (void) const { return data; }
+
+  void add_constraint (const std::string& type)
+    { type_constraints.push_back (type); }
+
+  void add_constraint (const dim_vector& dims)
+    { size_constraints.push_back (dims); }
+
+  double min_val (void) const { return xmin; }
+  double max_val (void) const { return xmax; }
+  double min_pos (void) const { return xminp; }
+
+  Matrix get_limits (void) const
+    {
+      Matrix m (1, 3);
+      
+      m(0) = min_val ();
+      m(1) = max_val ();
+      m(2) = min_pos ();
+
+      return m;
+    }
+
+  array_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const
+    {
+      array_property *p = new array_property (*this);
+
+      p->type_constraints = type_constraints;
+      p->size_constraints = size_constraints;
+      
+      return p;
+    }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      if (validate (v))
+	{
+	  // FIXME -- should we check for actual data change?
+	  if (! is_equal (v))
+	    {
+	      data = v;
+
+	      get_data_limits ();
+
+	      return true;
+	    }
+	}
+      else
+        error ("invalid value for array property \"%s\"",
+               get_name ().c_str ());
+      
+      return false;
+    }
+
+private:
+  OCTINTERP_API bool validate (const octave_value& v);
+
+  OCTINTERP_API bool is_equal (const octave_value& v) const;
+
+  OCTINTERP_API void get_data_limits (void);
+
+protected:
+  octave_value data;
+  double xmin;
+  double xmax;
+  double xminp;
+  std::list<std::string> type_constraints;
+  std::list<dim_vector> size_constraints;
+};
+
+class row_vector_property : public array_property
+{
+public:
+  row_vector_property (const std::string& nm, const graphics_handle& h,
+		       const octave_value& m)
+    : array_property (nm, h, m)
+  {
+    add_constraint (dim_vector (-1, 1));
+    add_constraint (dim_vector (1, -1));
+  }
+
+  row_vector_property (const row_vector_property& p)
+    : array_property (p)
+  {
+    add_constraint (dim_vector (-1, 1));
+    add_constraint (dim_vector (1, -1));
+  }
+
+  void add_constraint (const std::string& type)
+  {
+    array_property::add_constraint (type);
+  }
+
+  void add_constraint (const dim_vector& dims)
+  {
+    array_property::add_constraint (dims);
+  }
+
+  void add_constraint (octave_idx_type len)
+  {
+    size_constraints.remove (dim_vector (1, -1));
+    size_constraints.remove (dim_vector (-1, 1));
+
+    add_constraint (dim_vector (1, len));
+    add_constraint (dim_vector (len, 1));
+  }
+
+  row_vector_property& operator = (const octave_value& val)
+  {
+    set (val);
+    return *this;
+  }
+
+  base_property* clone (void) const
+    {
+      row_vector_property *p = new row_vector_property (*this);
+
+      p->type_constraints = type_constraints;
+      p->size_constraints = size_constraints;
+
+      return p;
+    }
+
+protected:
+  bool do_set (const octave_value& v)
+  {
+    bool retval = array_property::do_set (v);
+
+    if (! error_state)
+      {
+	dim_vector dv = data.dims ();
+
+	if (dv(0) > 1 && dv(1) == 1)
+	  {
+	    int tmp = dv(0);
+	    dv(0) = dv(1);
+	    dv(1) = tmp;
+
+	    data = data.reshape (dv);
+	  }
+
+	return retval;
+      }
+
+    return false;
+  }
+
+private:
+  OCTINTERP_API bool validate (const octave_value& v);
+};
+
+// ---------------------------------------------------------------------
+
+class bool_property : public radio_property
+{
+public:
+  bool_property (const std::string& nm, const graphics_handle& h,
+                 bool val)
+    : radio_property (nm, h, radio_values (val ? "{on}|off" : "on|{off}"))
+    { }
+
+  bool_property (const std::string& nm, const graphics_handle& h,
+                 const char* val)
+    : radio_property (nm, h, radio_values ("on|off"), val)
+    { }
+
+  bool_property (const bool_property& p)
+    : radio_property (p) { }
+
+  bool is_on (void) const { return is ("on"); }
+  
+  bool_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new bool_property (*this); }
+
+protected:
+  bool do_set (const octave_value& val)
+    {
+      if (val.is_bool_scalar ())
+        return radio_property::do_set (val.bool_value () ? "on" : "off");
+      else
+        return radio_property::do_set (val);
+    }
+};
+
+// ---------------------------------------------------------------------
+
+class handle_property : public base_property
+{
+public:
+  handle_property (const std::string& nm, const graphics_handle& h,
+                   const graphics_handle& val = graphics_handle ())
+    : base_property (nm, h),
+      current_val (val) { }
+
+  handle_property (const handle_property& p)
+    : base_property (p), current_val (p.current_val) { }
+
+  octave_value get (void) const { return current_val.as_octave_value (); }
+
+  graphics_handle handle_value (void) const { return current_val; }
+
+  handle_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  handle_property& operator = (const graphics_handle& h)
+    {
+      set (octave_value (h.value ()));
+      return *this;
+    }
+
+  base_property* clone (void) const { return new handle_property (*this); }
+
+protected:
+  OCTINTERP_API bool do_set (const octave_value& v);
+
+private:
+  graphics_handle current_val;
+};
+
+// ---------------------------------------------------------------------
+
+class any_property : public base_property
+{
+public:
+  any_property (const std::string& nm, const graphics_handle& h,
+                  const octave_value& m = Matrix ())
+    : base_property (nm, h), data (m) { }
+
+  any_property (const any_property& p)
+    : base_property (p), data (p.data) { }
+
+  octave_value get (void) const { return data; }
+
+  any_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new any_property (*this); }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      data = v;
+      return true;
+    }
+
+private:
+  octave_value data;
+};
+
+// ---------------------------------------------------------------------
+
+class callback_property : public base_property
+{
+public:
+  callback_property (const std::string& nm, const graphics_handle& h,
+                     const octave_value& m)
+    : base_property (nm, h), callback (m) { }
+
+  callback_property (const callback_property& p)
+    : base_property (p), callback (p.callback) { }
+
+  octave_value get (void) const { return callback; }
+
+  OCTINTERP_API void execute (const octave_value& data = octave_value ()) const;
+
+  callback_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new callback_property (*this); }
+
+protected:
+  bool do_set (const octave_value& v)
+    {
+      if (validate (v))
+	{
+	  callback = v;
+	  return true;
+	}
+      else
+        error ("invalid value for callback property \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  OCTINTERP_API bool validate (const octave_value& v) const;
+
+private:
+  octave_value callback;
+};
+
+// ---------------------------------------------------------------------
+
+class property
+{
+public:
+  property (void) : rep (new base_property ("", graphics_handle ()))
+    { }
+
+  property (base_property *bp, bool persist = false) : rep (bp)
+    { if (persist) rep->count++; }
+
+  property (const property& p)
+    {
+      rep = p.rep;
+      rep->count++;
+    }
+
+  ~property (void)
+    {
+      if (--rep->count <= 0)
+        delete rep;
+    }
+
+  bool ok (void) const
+    { return rep->ok (); }
+
+  std::string get_name (void) const
+    { return rep->get_name (); }
+
+  void set_name (const std::string& name)
+    { rep->set_name (name); }
+
+  graphics_handle get_parent (void) const
+    { return rep->get_parent (); }
+
+  void set_parent (const graphics_handle& h)
+    { rep->set_parent (h); }
+
+  bool is_hidden (void) const
+    { return rep->is_hidden (); }
+
+  void set_hidden (bool flag)
+    { rep->set_hidden (flag); }
+
+  int get_id (void) const
+    { return rep->get_id (); }
+
+  void set_id (int d)
+    { rep->set_id (d); }
+
+  octave_value get (void) const
+    { return rep->get (); }
+
+  bool set (const octave_value& val)
+    { return rep->set (val); }
+
+  property& operator = (const octave_value& val)
+    {
+      *rep = val;
+      return *this;
+    }
+
+  property& operator = (const property& p)
+    {
+      if (rep && --rep->count <= 0)
+        delete rep;
+      
+      rep = p.rep;
+      rep->count++;
+
+      return *this;
+    }
+
+  void add_listener (const octave_value& v, listener_mode mode = POSTSET)
+    { rep->add_listener (v, mode); }
+
+  void delete_listener (const octave_value& v = octave_value (), 
+			listener_mode mode = POSTSET)
+  { rep->delete_listener (v, mode); }
+
+  void run_listeners (listener_mode mode = POSTSET)
+    { rep->run_listeners (mode); }
+
+  OCTINTERP_API static
+      property create (const std::string& name, const graphics_handle& parent,
+		       const caseless_str& type,
+		       const octave_value_list& args);
+
+  property clone (void) const
+    { return property (rep->clone ()); }
+
+  /*
+  const string_property& as_string_property (void) const
+    { return *(dynamic_cast<string_property*> (rep)); }
+
+  const radio_property& as_radio_property (void) const
+    { return *(dynamic_cast<radio_property*> (rep)); }
+
+  const color_property& as_color_property (void) const
+    { return *(dynamic_cast<color_property*> (rep)); }
+
+  const double_property& as_double_property (void) const
+    { return *(dynamic_cast<double_property*> (rep)); }
+
+  const bool_property& as_bool_property (void) const
+    { return *(dynamic_cast<bool_property*> (rep)); }
+  
+  const handle_property& as_handle_property (void) const
+    { return *(dynamic_cast<handle_property*> (rep)); }
+    */
+
+private:
+  base_property *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class property_list
+{
+public:
+  typedef std::map<std::string, octave_value> pval_map_type;
+  typedef std::map<std::string, pval_map_type> plist_map_type;
+  
+  typedef pval_map_type::iterator pval_map_iterator;
+  typedef pval_map_type::const_iterator pval_map_const_iterator;
+
+  typedef plist_map_type::iterator plist_map_iterator;
+  typedef plist_map_type::const_iterator plist_map_const_iterator;
+
+  property_list (const plist_map_type& m = plist_map_type ())
+    : plist_map (m) { }
+
+  ~property_list (void) { }
+
+  void set (const caseless_str& name, const octave_value& val);
+
+  octave_value lookup (const caseless_str& name) const;
+
+  plist_map_iterator begin (void) { return plist_map.begin (); }
+  plist_map_const_iterator begin (void) const { return plist_map.begin (); }
+
+  plist_map_iterator end (void) { return plist_map.end (); }
+  plist_map_const_iterator end (void) const { return plist_map.end (); }
+
+  plist_map_iterator find (const std::string& go_name)
+  {
+    return plist_map.find (go_name);
+  }
+
+  plist_map_const_iterator find (const std::string& go_name) const
+  {
+    return plist_map.find (go_name);
+  }
+
+  Octave_map as_struct (const std::string& prefix_arg) const;
+
+private:
+  plist_map_type plist_map;
+};
+
+// ---------------------------------------------------------------------
+
+class graphics_backend;
+class graphics_object;
+
+class base_graphics_backend
+{
+public:
+  friend class graphics_backend;
+
+public:
+  base_graphics_backend (const std::string& nm)
+      : name (nm), count (0) { }
+
+  virtual ~base_graphics_backend (void) { }
+
+  std::string get_name (void) const { return name; }
+
+  virtual bool is_valid (void) const { return false; }
+
+  virtual void redraw_figure (const graphics_object&) const
+    { gripe_invalid ("redraw_figure"); }
+
+  virtual void print_figure (const graphics_object&, const std::string&,
+			     const std::string&, bool,
+			     const std::string& = "") const
+    { gripe_invalid ("print_figure"); }
+
+  virtual Matrix get_canvas_size (const graphics_handle&) const
+    {
+      gripe_invalid ("get_canvas_size");
+      return Matrix (1, 2, 0.0);
+    }
+
+  virtual double get_screen_resolution (void) const
+    {
+      gripe_invalid ("get_screen_resolution");
+      return 72.0;
+    }
+  
+  virtual Matrix get_screen_size (void) const
+    {
+      gripe_invalid ("get_screen_size");
+      return Matrix (1, 2, 0.0);
+    }
+
+  // Called when graphics object using this backend changes it's property.
+  virtual void property_changed (const graphics_object&, int)
+    { gripe_invalid ("property_changed"); }
+
+  void property_changed (const graphics_handle&, int);
+  
+  // Called when new object using this backend is created.
+  virtual void object_created (const graphics_object&)
+    { gripe_invalid ("object_created"); }
+
+  void object_created (const graphics_handle&);
+
+  // Called when object using this backend is destroyed.
+  virtual void object_destroyed (const graphics_object&)
+    { gripe_invalid ("object_destroyed"); }
+
+  void object_destroyed (const graphics_handle&);
+
+private:
+  std::string name;
+  int count;
+
+private:
+  void gripe_invalid (const std::string& fname) const
+    {
+      if (! is_valid ())
+	error ("%s: invalid graphics backend", fname.c_str ());
+    }
+};
+
+class graphics_backend
+{
+public:
+  graphics_backend (void)
+      : rep (new base_graphics_backend ("unknown"))
+    {
+      rep->count++;
+    }
+
+  graphics_backend (base_graphics_backend* b)
+      : rep (b)
+    {
+      rep->count++;
+    }
+
+  graphics_backend (const graphics_backend& b)
+      : rep (b.rep)
+    {
+      rep->count++;
+    }
+
+  ~graphics_backend (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+  graphics_backend& operator = (const graphics_backend& b)
+    {
+      if (rep != b.rep)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = b.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+  operator bool (void) const { return rep->is_valid (); }
+
+  std::string get_name (void) const { return rep->get_name (); }
+
+  void redraw_figure (const graphics_object& go) const
+    { rep->redraw_figure (go); }
+  
+  void print_figure (const graphics_object& go, const std::string& term,
+		     const std::string& file, bool mono,
+		     const std::string& debug_file = "") const
+    { rep->print_figure (go, term, file, mono, debug_file); }
+
+  Matrix get_canvas_size (const graphics_handle& fh) const
+    { return rep->get_canvas_size (fh); }
+
+  double get_screen_resolution (void) const
+    { return rep->get_screen_resolution (); }
+
+  Matrix get_screen_size (void) const
+    { return rep->get_screen_size (); }
+
+  // Notifies backend that object't property has changed.
+  void property_changed (const graphics_object& go, int id)
+    { rep->property_changed (go, id); }
+  
+  void property_changed (const graphics_handle& h, int id)
+    { rep->property_changed (h, id); }
+
+  // Notifies backend that new object was created.
+  void object_created (const graphics_object& go)
+    { rep->object_created (go); }
+  
+  void object_created (const graphics_handle& h)
+    { rep->object_created (h); }
+  
+  // Notifies backend that object was destroyed.
+  // This is called only for explicitly deleted object. Children are
+  // deleted implicitly and backend isn't notified.
+  void object_destroyed (const graphics_object& go)
+    { rep->object_destroyed (go); }
+  
+  void object_destroyed (const graphics_handle& h)
+    { rep->object_destroyed (h); }
+  
+  OCTINTERP_API static graphics_backend default_backend (void);
+
+  static void register_backend (const graphics_backend& b)
+    { available_backends[b.get_name ()] = b; }
+
+  static void unregister_backend (const std::string& name)
+    { available_backends.erase (name); }
+
+  static graphics_backend find_backend (const std::string& name)
+  {
+    const_available_backends_iterator p = available_backends.find (name);
+
+    if (p != available_backends.end ())
+      return p->second;
+    else
+      return default_backend ();
+  }
+
+  static Cell available_backends_list (void)
+  {
+    Cell m (1 , available_backends.size ());
+    const_available_backends_iterator p;
+    int i;
+    
+    for (i = 0,p = available_backends.begin (); p !=  available_backends.end (); p++,i++)
+      m(i) = p->first;
+
+    return m;
+  }
+
+private:
+  base_graphics_backend *rep;
+
+  static OCTINTERP_API std::map<std::string, graphics_backend> available_backends;
+
+  typedef std::map<std::string, graphics_backend>::iterator available_backends_iterator;
+  typedef std::map<std::string, graphics_backend>::const_iterator const_available_backends_iterator;
+};
+
+// ---------------------------------------------------------------------
+
+class base_graphics_object;
+
+class OCTINTERP_API base_properties
+{
+public:
+  base_properties (const std::string& ty = "unknown",
+                   const graphics_handle& mh = graphics_handle (),
+                   const graphics_handle& p = graphics_handle ());
+
+  virtual ~base_properties (void) { }
+
+  virtual std::string graphics_object_name (void) const { return "unknonwn"; }
+
+  void mark_modified (void);
+
+  void override_defaults (base_graphics_object& obj);
+
+  // Look through DEFAULTS for properties with given CLASS_NAME, and
+  // apply them to the current object with set (virtual method).
+
+  void set_from_list (base_graphics_object& obj, property_list& defaults);
+
+  void insert_property (const std::string& name, property p)
+    {
+      p.set_name (name);
+      p.set_parent (__myhandle__);
+      all_props[name] = p;
+    }
+
+  virtual void set (const caseless_str&, const octave_value&)
+  {
+    panic_impossible ();
+  }
+
+  void set (const caseless_str& pname, const std::string& cname,
+	    const octave_value& val);
+
+  virtual octave_value get (const caseless_str& pname) const;
+
+  virtual octave_value get (bool all = false) const;
+
+  virtual property get_property (const caseless_str& pname);
+
+  bool has_property (const caseless_str& pname);
+
+  bool is_modified (void) const { return is___modified__ (); }
+ 
+  virtual void remove_child (const graphics_handle& h);
+
+  virtual void adopt (const graphics_handle& h)
+  {
+    octave_idx_type n = children.numel ();
+    children.resize (n+1, 1);
+    for (octave_idx_type i = n; i > 0; i--)
+      children(i) = children(i-1);
+    children(0) = h.value ();
+    mark_modified ();
+  }
+
+  virtual graphics_backend get_backend (void) const;
+
+  virtual Matrix get_boundingbox (bool /*internal*/ = false) const
+    { return Matrix (1, 4, 0.0); }
+
+  virtual void update_boundingbox (void);
+
+  virtual void add_listener (const caseless_str&, const octave_value&,
+			     listener_mode = POSTSET);
+
+  virtual void delete_listener (const caseless_str&, const octave_value&,
+				listener_mode = POSTSET);
+
+  void set_tag (const octave_value& val) { tag = val; }
+
+  void set_parent (const octave_value& val);
+
+  Matrix get_all_children (void) const { return children; }
+
+  void set_children (const octave_value& val);
+
+  void set_modified (const octave_value& val) { set___modified__ (val); }
+
+  void set___modified__ (const octave_value& val) { __modified__ = val; }
+
+  void reparent (const graphics_handle& new_parent) { parent = new_parent; }
+
+  // Update data limits for AXIS_TYPE (xdata, ydata, etc.) in the parent
+  // axes object.
+
+  virtual void update_axis_limits (const std::string& axis_type) const;
+
+  virtual void delete_children (void);
+
+  static property_list::pval_map_type factory_defaults (void);
+
+  // FIXME -- these functions should be generated automatically by the
+  // genprops.awk script.
+  //
+  // EMIT_BASE_PROPERTIES_GET_FUNCTIONS
+
+  virtual octave_value get_xlim (void) const { return octave_value (); }
+  virtual octave_value get_ylim (void) const { return octave_value (); }
+  virtual octave_value get_zlim (void) const { return octave_value (); }
+  virtual octave_value get_clim (void) const { return octave_value (); }
+  virtual octave_value get_alim (void) const { return octave_value (); }
+
+  virtual bool is_xliminclude (void) const { return false; }
+  virtual bool is_yliminclude (void) const { return false; }
+  virtual bool is_zliminclude (void) const { return false; }
+  virtual bool is_climinclude (void) const { return false; }
+  virtual bool is_aliminclude (void) const { return false; }
+
+  bool is_handle_visible (void) const
+  {
+    return ! handlevisibility.is ("off");
+  }
+
+  static std::map<std::string, std::set<std::string> > all_dynamic_properties;
+ 
+  static bool has_dynamic_property (const std::string& pname,
+				    const std::string& cname);
+
+protected:
+  void set_dynamic (const caseless_str& pname, const std::string& cname,
+		    const octave_value& val);
+
+  octave_value get_dynamic (const caseless_str& pname) const;
+
+  octave_value get_dynamic (bool all = false) const;
+
+  property get_property_dynamic (const caseless_str& pname);
+
+  BEGIN_BASE_PROPERTIES
+    // properties common to all objects
+    bool_property beingdeleted , "off"
+    radio_property busyaction , "{queue}|cancel"
+    callback_property buttondownfcn , Matrix ()
+    // FIXME -- use a property class for children.
+    Matrix children Gfs , Matrix ()
+    bool_property clipping , "on"
+    callback_property createfcn , Matrix ()
+    callback_property deletefcn , Matrix ()
+    radio_property handlevisibility , "{on}|callback|off"
+    bool_property hittest , "on"
+    bool_property interruptible , "on"
+    handle_property parent fs , p
+    bool_property selected , "off"
+    bool_property selectionhighlight , "on"
+    string_property tag s , ""
+    string_property type frs , ty
+    any_property userdata , Matrix ()
+    bool_property visible , "on"
+    // additional (octave-specific) properties
+    bool_property __modified__ s , "on"
+    graphics_handle __myhandle__ fhrs , mh
+    // FIXME -- should this really be here?
+    handle_property uicontextmenu , graphics_handle ()
+  END_PROPERTIES
+
+protected:
+  struct cmp_caseless_str 
+    {
+      bool operator () (const caseless_str &a, const caseless_str &b) const
+        {
+	  std::string a1 = a;
+	  std::transform (a1.begin (), a1.end (), a1.begin (), tolower);
+	  std::string b1 = b;
+	  std::transform (b1.begin (), b1.end (), b1.begin (), tolower);
+
+          return a1 < b1;
+        }
+    };
+
+  std::map<caseless_str, property, cmp_caseless_str> all_props;
+
+protected:
+  void insert_static_property (const std::string& name, base_property& p)
+    { insert_property (name, property (&p, true)); }
+  
+  virtual void init (void) { }
+};
+
+class OCTINTERP_API base_graphics_object
+{
+public:
+  friend class graphics_object;
+
+  base_graphics_object (void) : count (1) { }
+
+  base_graphics_object (const base_graphics_object&) { }
+
+  virtual ~base_graphics_object (void) { }
+
+  virtual void mark_modified (void)
+  {
+    if (valid_object ())
+      get_properties ().mark_modified ();
+    else
+      error ("base_graphics_object::mark_modified: invalid graphics object");
+  }
+
+  virtual void override_defaults (base_graphics_object& obj)
+  {
+    if (valid_object ())
+      get_properties ().override_defaults (obj);
+    else
+      error ("base_graphics_object::override_defaults: invalid graphics object");
+  }
+
+  virtual void set_from_list (property_list& plist)
+  {
+    if (valid_object ())
+      get_properties ().set_from_list (*this, plist);
+    else
+      error ("base_graphics_object::set_from_list: invalid graphics object");
+  }
+
+  virtual void set (const caseless_str& pname, const octave_value& pval)
+  {
+    if (valid_object ())
+      get_properties ().set (pname, pval);
+    else
+      error ("base_graphics_object::set: invalid graphics object");
+  }
+
+  virtual void set_defaults (const std::string&)
+  {
+    error ("base_graphics_object::set_defaults: invalid graphics object");
+  }
+
+  virtual octave_value get (bool all = false) const
+  {
+    if (valid_object ())
+      return get_properties ().get (all);
+    else
+      {
+        error ("base_graphics_object::get: invalid graphics object");
+        return octave_value ();
+      }
+  }
+
+  virtual octave_value get (const caseless_str& pname) const
+  {
+    if (valid_object ())
+      return get_properties ().get (pname);
+    else
+      {
+        error ("base_graphics_object::get: invalid graphics object");
+        return octave_value ();
+      }
+  }
+
+  virtual octave_value get_default (const caseless_str&) const;
+
+  virtual octave_value get_factory_default (const caseless_str&) const;
+
+  virtual octave_value get_defaults (void) const
+  {
+    error ("base_graphics_object::get_defaults: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual octave_value get_factory_defaults (void) const
+  {
+    error ("base_graphics_object::get_factory_defaults: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual graphics_handle get_parent (void) const
+  {
+    if (valid_object ())
+      return get_properties ().get_parent ();
+    else
+      {
+        error ("base_graphics_object::get_parent: invalid graphics object");
+        return graphics_handle ();
+      }
+  }
+
+  graphics_handle get_handle (void) const
+  {
+    if (valid_object ())
+      return get_properties ().get___myhandle__ ();
+    else
+      {
+        error ("base_graphics_object::get_handle: invalid graphics object");
+        return graphics_handle ();
+      }
+  }
+
+  virtual void remove_child (const graphics_handle& h)
+  {
+    if (valid_object ())
+      get_properties ().remove_child (h);
+    else
+      error ("base_graphics_object::remove_child: invalid graphics object");
+  }
+
+  virtual void adopt (const graphics_handle& h)
+  {
+    if (valid_object ())
+      get_properties ().adopt (h);
+    else
+      error ("base_graphics_object::adopt: invalid graphics object");
+  }
+
+  virtual void reparent (const graphics_handle& np)
+  {
+    if (valid_object ())
+      get_properties ().reparent (np);
+    else
+      error ("base_graphics_object::reparent: invalid graphics object");
+  }
+
+  virtual void defaults (void) const
+  {
+    if (valid_object ())
+      {
+        std::string msg = (type () + "::defaults");
+        gripe_not_implemented (msg.c_str ());
+      }
+    else
+      error ("base_graphics_object::default: invalid graphics object");
+  }
+
+  virtual base_properties& get_properties (void)
+  {
+    static base_properties properties;
+    error ("base_graphics_object::get_properties: invalid graphics object");
+    return properties;
+  }
+
+  virtual const base_properties& get_properties (void) const
+  {
+    static base_properties properties;
+    error ("base_graphics_object::get_properties: invalid graphics object");
+    return properties;
+  }
+
+  virtual void update_axis_limits (const std::string& axis_type);
+
+  virtual bool valid_object (void) const { return false; }
+
+  virtual std::string type (void) const
+  {
+    return (valid_object () ? get_properties ().graphics_object_name ()
+        : "unknown");
+  }
+
+  bool isa (const std::string& go_name) const
+  {
+    return type () == go_name;
+  }
+
+  virtual graphics_backend get_backend (void) const
+  {
+    if (valid_object ())
+      return get_properties ().get_backend ();
+    else
+      {
+	error ("base_graphics_object::get_backend: invalid graphics object");
+	return graphics_backend ();
+      }
+  }
+
+  virtual void add_property_listener (const std::string& nm,
+				      const octave_value& v,
+				      listener_mode mode = POSTSET)
+    {
+      if (valid_object ())
+	get_properties ().add_listener (nm, v, mode);
+    }
+
+  virtual void delete_property_listener (const std::string& nm,
+					 const octave_value& v,
+					 listener_mode mode = POSTSET)
+    {
+      if (valid_object ())
+	get_properties ().delete_listener (nm, v, mode);
+    }
+
+  virtual void remove_all_listeners (void);
+
+protected:
+  // A reference count.
+  int count;
+};
+
+class OCTINTERP_API graphics_object
+{
+public:
+  graphics_object (void) : rep (new base_graphics_object ()) { }
+
+  graphics_object (base_graphics_object *new_rep)
+    : rep (new_rep) { }
+
+  graphics_object (const graphics_object& obj)
+  {
+    rep = obj.rep;
+    rep->count++;
+  }
+
+  graphics_object& operator = (const graphics_object& obj)
+  {
+    if (rep != obj.rep)
+      {
+	if (--rep->count == 0)
+	  delete rep;
+
+	rep = obj.rep;
+	rep->count++;
+      }
+
+    return *this;
+  }
+
+  ~graphics_object (void)
+  {
+    if (--rep->count == 0)
+      delete rep;
+  }
+
+  void mark_modified (void) { rep->mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    rep->override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist) { rep->set_from_list (plist); }
+
+  void set (const caseless_str& name, const octave_value& val)
+  {
+    rep->set (name, val);
+  }
+
+  void set (const octave_value_list& args);
+
+  void set_defaults (const std::string& mode) { rep->set_defaults (mode); }
+
+  octave_value get (bool all = false) const { return rep->get (all); }
+
+  octave_value get (const caseless_str& name) const
+  {
+    return name.compare ("default")
+      ? get_defaults ()
+      : (name.compare ("factory")
+	 ? get_factory_defaults () : rep->get (name));
+  }
+
+  octave_value get_default (const caseless_str& name) const
+  {
+    return rep->get_default (name);
+  }
+
+  octave_value get_factory_default (const caseless_str& name) const
+  {
+    return rep->get_factory_default (name);
+  }
+
+  octave_value get_defaults (void) const { return rep->get_defaults (); }
+
+  octave_value get_factory_defaults (void) const
+  {
+    return rep->get_factory_defaults ();
+  }
+
+  graphics_handle get_parent (void) const { return rep->get_parent (); }
+
+  graphics_handle get_handle (void) const { return rep->get_handle (); }
+
+  void remove_child (const graphics_handle& h) { rep->remove_child (h); }
+
+  void adopt (const graphics_handle& h) { rep->adopt (h); }
+
+  void reparent (const graphics_handle& h) { rep->reparent (h); }
+
+  void defaults (void) const { rep->defaults (); }
+
+  bool isa (const std::string& go_name) const { return rep->isa (go_name); }
+
+  base_properties& get_properties (void) { return rep->get_properties (); }
+
+  const base_properties& get_properties (void) const
+  {
+    return rep->get_properties ();
+  }
+
+  void update_axis_limits (const std::string& axis_type)
+  {
+    rep->update_axis_limits (axis_type);
+  }
+
+  bool valid_object (void) const { return rep->valid_object (); }
+
+  std::string type (void) const { return rep->type (); }
+
+  operator bool (void) const { return rep->valid_object (); }
+
+  // FIXME -- these functions should be generated automatically by the
+  // genprops.awk script.
+  //
+  // EMIT_GRAPHICS_OBJECT_GET_FUNCTIONS
+
+  octave_value get_xlim (void) const
+  { return get_properties ().get_xlim (); }
+
+  octave_value get_ylim (void) const
+  { return get_properties ().get_ylim (); }
+  
+  octave_value get_zlim (void) const
+  { return get_properties ().get_zlim (); }
+  
+  octave_value get_clim (void) const
+  { return get_properties ().get_clim (); }
+  
+  octave_value get_alim (void) const
+  { return get_properties ().get_alim (); }
+
+  bool is_xliminclude (void) const
+  { return get_properties ().is_xliminclude (); }
+  
+  bool is_yliminclude (void) const
+  { return get_properties ().is_yliminclude (); }
+  
+  bool is_zliminclude (void) const
+  { return get_properties ().is_zliminclude (); }
+  
+  bool is_climinclude (void) const
+  { return get_properties ().is_climinclude (); }
+  
+  bool is_aliminclude (void) const
+  { return get_properties ().is_aliminclude (); }
+
+  bool is_handle_visible (void) const
+  { return get_properties ().is_handle_visible (); }
+  
+  graphics_backend get_backend (void) const { return rep->get_backend (); }
+
+  void add_property_listener (const std::string& nm, const octave_value& v,
+			      listener_mode mode = POSTSET)
+    { rep->add_property_listener (nm, v, mode); }
+
+  void delete_property_listener (const std::string& nm, const octave_value& v,
+				 listener_mode mode = POSTSET)
+    { rep->delete_property_listener (nm, v, mode); }
+
+private:
+  base_graphics_object *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API root_figure : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void remove_child (const graphics_handle& h);
+    
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (root_figure, root)
+      handle_property currentfigure S , graphics_handle ()
+      handle_property callbackobject Sr , graphics_handle ()
+      double_property screendepth r , default_screendepth ()
+      array_property screensize r , default_screensize ()
+      double_property screenpixelsperinch r , default_screenpixelsperinch ()
+      radio_property units U , "inches|centimeters|normalized|points|{pixels}"
+      bool_property showhiddenhandles , "off"
+    END_PROPERTIES
+
+  private:
+    std::list<graphics_handle> cbo_stack;
+  };
+
+private:
+  properties xproperties;
+
+public:
+
+  root_figure (void) : xproperties (0, graphics_handle ()), default_properties () { }
+
+  ~root_figure (void) { xproperties.delete_children (); }
+
+  void mark_modified (void) { }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set (const caseless_str& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  octave_value get (const caseless_str& name) const
+  {
+    octave_value retval;
+
+    if (name.compare ("default", 7))
+      return get_default (name.substr (7));
+    else if (name.compare ("factory", 7))
+      return get_factory_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const caseless_str& name) const
+  {
+    octave_value retval = default_properties.lookup (name);
+
+    if (retval.is_undefined ())
+      {
+	// no default property found, use factory default
+	retval = factory_properties.lookup (name);
+
+	if (retval.is_undefined ())
+	  error ("get: invalid default property `%s'", name.c_str ());
+      }
+
+    return retval;
+  }
+
+  octave_value get_factory_default (const caseless_str& name) const
+  {
+    octave_value retval = factory_properties.lookup (name);
+
+    if (retval.is_undefined ())
+      error ("get: invalid factory default property `%s'", name.c_str ());
+
+    return retval;
+  }
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  octave_value get_factory_defaults (void) const
+  {
+    return factory_properties.as_struct ("factory");
+  }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+
+  static property_list factory_properties;
+
+  static property_list::plist_map_type init_factory_properties (void);
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API figure : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void remove_child (const graphics_handle& h);
+
+    void set_visible (const octave_value& val);
+
+    graphics_backend get_backend (void) const
+      {
+	if (! backend)
+	  backend = graphics_backend::default_backend ();
+
+	return backend;
+      }
+
+    void set_backend (const graphics_backend& b) 
+    { 
+      if (backend)
+	backend.object_destroyed (__myhandle__);
+      backend = b; 
+      __backend__ = b.get_name ();
+      __plot_stream__ = Matrix ();
+      mark_modified ();
+    }
+
+    void set___backend__ (const octave_value& val)
+    {
+      if (! error_state)
+	{
+	  if (val.is_string ())
+	    {
+	      std::string nm = val.string_value ();
+	      graphics_backend b = graphics_backend::find_backend (nm);
+	      if (b.get_name () != nm)
+		{
+		  error ("set___backend__: invalid backend");
+		}
+	      else
+		{
+		  set_backend (b);
+		  mark_modified ();
+		}
+	    }
+	  else
+	    error ("set___backend__ must be a string");
+	}
+    }
+
+    Matrix get_boundingbox (bool internal = false) const;
+
+    void set_boundingbox (const Matrix& bb);
+
+    std::string get_title (void) const;
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (figure)
+      any_property __plot_stream__ h , Matrix ()
+      bool_property __enhanced__ h , "on"
+      radio_property nextplot , "new|{add}|replace_children|replace"
+      callback_property closerequestfcn , "closereq"
+      handle_property currentaxes S , graphics_handle ()
+      array_property colormap , jet_colormap ()
+      radio_property paperorientation , "{portrait}|landscape|rotated"
+      color_property color , color_values (1, 1, 1)
+      array_property alphamap , Matrix (64, 1, 1)
+      string_property currentcharacter r , ""
+      handle_property currentobject r , graphics_handle ()
+      array_property current_point r , Matrix (2, 1, 0)
+      bool_property dockcontrols , "off"
+      bool_property doublebuffer , "on"
+      string_property filename r , ""
+      bool_property integerhandle , "on"
+      bool_property inverthardcopy , "off"
+      callback_property keypressfcn , Matrix ()
+      callback_property keyreleasefcn , Matrix ()
+      radio_property menubar , "none|{figure}"
+      double_property mincolormap , 64
+      string_property name , ""
+      bool_property numbertitle , "on"
+      radio_property paperunits , "{inches}|centimeters|normalized|points"
+      array_property paperposition , default_figure_paperposition ()
+      radio_property paperpositionmode , "auto|{manual}"
+      array_property papersize , default_figure_papersize ()
+      radio_property papertype , "{usletter}|uslegal|a0|a1|a2|a3|a4|a5|b0|b1|b2|b3|b4|b5|arch-a|arch-b|arch-c|arch-d|arch-e|a|b|c|d|e|tabloid|<custom>"
+      radio_property pointer , "crosshair|fullcrosshair|{arrow}|ibeam|watch|topl|topr|botl|botr|left|top|right|bottom|circle|cross|fleur|custom|hand"
+      array_property pointershapecdata , Matrix (16, 16, 0)
+      array_property pointershapehotspot , Matrix (1, 2, 0)
+      array_property position S , default_figure_position ()
+      radio_property renderer , "{painters}|zbuffer|opengl|none"
+      radio_property renderermode , "{auto}|manual"
+      bool_property resize , "on"
+      callback_property resizefcn , Matrix ()
+      radio_property selectiontype , "{normal}|open|alt|extend"
+      radio_property toolbar , "none|{auto}|figure"
+      radio_property units , "inches|centimeters|normalized|points|{pixels}|characters"
+      callback_property windowbuttondownfcn , Matrix ()
+      callback_property windowbuttonmotionfcn , Matrix ()
+      callback_property windowbuttonupfcn , Matrix ()
+      callback_property windowbuttonwheelfcn , Matrix ()
+      radio_property windowstyle , "{normal}|modal|docked"
+      string_property wvisual , ""
+      radio_property wvisualmode , "{auto}|manual"
+      string_property xdisplay , ""
+      string_property xvisual , ""
+      radio_property xvisualmode , "{auto}|manual"
+      callback_property buttondownfcn , Matrix ()
+      string_property __backend__ s , "gnuplot"
+    END_PROPERTIES
+    
+  protected:
+    void init (void)
+      {
+        colormap.add_constraint (dim_vector (-1, 3));
+	alphamap.add_constraint (dim_vector (-1, 1));
+	paperposition.add_constraint (dim_vector (1, 4));
+	pointershapecdata.add_constraint (dim_vector (16, 16));
+	pointershapehotspot.add_constraint (dim_vector (1, 2));
+	position.add_constraint (dim_vector (1, 4));
+      }
+
+  private:
+    mutable graphics_backend backend;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  figure (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p), default_properties ()
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~figure (void)
+  {
+    xproperties.delete_children (); 
+  }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (root figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set (const caseless_str& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  octave_value get (const caseless_str& name) const
+  {
+    octave_value retval;
+
+    if (name.compare ("default", 7))
+      retval = get_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const caseless_str& name) const;
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API graphics_xform
+{
+public:
+  graphics_xform (void)
+      : xform (xform_eye ()), xform_inv (xform_eye ())
+    {
+      sx = sy = sz = "linear";
+    }
+
+  graphics_xform (const Matrix& xm, const Matrix& xim,
+		  const scaler& x, const scaler& y, const scaler& z)
+      : xform (xm), xform_inv (xim), sx (x), sy (y), sz (z) { }
+
+  graphics_xform (const graphics_xform& g)
+      : xform (g.xform), xform_inv (g.xform_inv), sx (g.sx),
+        sy (g.sy), sz (g.sz) { }
+
+  ~graphics_xform (void) { }
+
+  graphics_xform& operator = (const graphics_xform& g)
+    {
+      xform = g.xform;
+      xform_inv = g.xform_inv;
+      sx = g.sx;
+      sy = g.sy;
+      sz = g.sz;
+
+      return *this;
+    }
+
+  static ColumnVector xform_vector (double x, double y, double z);
+
+  static Matrix xform_eye (void);
+
+  ColumnVector transform (double x, double y, double z,
+			  bool scale = true) const;
+  
+  ColumnVector untransform (double x, double y, double z,
+			    bool scale = true) const;
+
+  Matrix xscale (const Matrix& m) const { return sx.scale (m); }
+  Matrix yscale (const Matrix& m) const { return sy.scale (m); }
+  Matrix zscale (const Matrix& m) const { return sz.scale (m); }
+
+  Matrix scale (const Matrix& m) const
+    {
+      bool has_z = (m.columns () > 2);
+
+      if (sx.is_linear () && sy.is_linear ()
+	  && (! has_z || sz.is_linear ()))
+	return m;
+
+      Matrix retval (m.dims ());
+
+      int r = m.rows ();
+
+      for (int i = 0; i < r; i++)
+	{
+	  retval(i,0) = sx.scale (m(i,0));
+	  retval(i,1) = sy.scale (m(i,1));
+	  if (has_z)
+	    retval(i,2) = sz.scale (m(i,2));
+	}
+
+      return retval;
+    }
+
+private:
+  Matrix xform;
+  Matrix xform_inv;
+  scaler sx, sy, sz;
+};
+
+class OCTINTERP_API axes : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void set_defaults (base_graphics_object& obj, const std::string& mode);
+
+    void remove_child (const graphics_handle& h);
+
+    const scaler& get_x_scaler (void) const { return sx; }
+    const scaler& get_y_scaler (void) const { return sy; }
+    const scaler& get_z_scaler (void) const { return sz; }
+
+    Matrix get_boundingbox (bool internal = false) const;
+
+    void update_boundingbox (void)
+      {
+	if (units_is ("normalized"))
+	  {
+	    update_transform ();
+	    base_properties::update_boundingbox ();
+	  }
+      }
+
+    void update_camera (void);
+    void update_aspectratios (void);
+    void update_transform (void)
+      {
+	update_aspectratios ();
+	update_camera ();
+      }
+
+    graphics_xform get_transform (void) const
+      { return graphics_xform (x_render, x_render_inv, sx, sy, sz); }
+
+    Matrix get_transform_matrix (void) const { return x_render; }
+    Matrix get_inverse_transform_matrix (void) const { return x_render_inv; }
+    Matrix get_opengl_matrix_1 (void) const { return x_gl_mat1; }
+    Matrix get_opengl_matrix_2 (void) const { return x_gl_mat2; }
+    Matrix get_transform_zlim (void) const { return x_zlim; }
+
+    ColumnVector pixel2coord (double px, double py) const
+    { return get_transform ().untransform (px, py, (x_zlim(0)+x_zlim(1))/2); }
+
+    ColumnVector coord2pixel (double x, double y, double z) const
+    { return get_transform ().transform (x, y, z); }
+
+    void zoom (const Matrix& xl, const Matrix& yl);
+    void unzoom (void);
+    void clear_zoom_stack (void);
+
+  private:
+    scaler sx, sy, sz;
+    Matrix x_render, x_render_inv;
+    Matrix x_gl_mat1, x_gl_mat2;
+    Matrix x_zlim;
+    std::list<octave_value> zoom_stack;
+
+    void set_text_child (handle_property& h, const std::string& who,
+			 const octave_value& v);
+
+    void delete_text_child (handle_property& h);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    // properties which are not in matlab: interpreter
+
+    BEGIN_PROPERTIES (axes)
+      array_property position u , default_axes_position ()
+      bool_property box , "on"
+      bool_property key , "off"
+      bool_property keybox , "off"
+      bool_property keyreverse , "off"
+      any_property keypos , 1
+      array_property colororder , default_colororder ()
+      array_property dataaspectratio m , Matrix (1, 3, 1.0)
+      radio_property dataaspectratiomode , "{auto}|manual"
+      radio_property layer , "{bottom}|top"
+      row_vector_property xlim mu , default_lim ()
+      row_vector_property ylim mu , default_lim ()
+      row_vector_property zlim mu , default_lim ()
+      row_vector_property clim m , default_lim ()
+      row_vector_property alim m , default_lim ()
+      radio_property xlimmode al , "{auto}|manual"
+      radio_property ylimmode al , "{auto}|manual"
+      radio_property zlimmode al , "{auto}|manual"
+      radio_property climmode al , "{auto}|manual"
+      radio_property alimmode    , "{auto}|manual"
+      handle_property xlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
+      handle_property ylabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
+      handle_property zlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
+      handle_property title SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
+      bool_property xgrid , "off"
+      bool_property ygrid , "off"
+      bool_property zgrid , "off"
+      bool_property xminorgrid , "off"
+      bool_property yminorgrid , "off"
+      bool_property zminorgrid , "off"
+      row_vector_property xtick m , default_axes_tick ()
+      row_vector_property ytick m , default_axes_tick ()
+      row_vector_property ztick m , default_axes_tick ()
+      radio_property xtickmode , "{auto}|manual"
+      radio_property ytickmode , "{auto}|manual"
+      radio_property ztickmode , "{auto}|manual"
+      bool_property xminortick , "off"
+      bool_property yminortick , "off"
+      bool_property zminortick , "off"
+      // FIXME -- should be kind of string array.
+      any_property xticklabel m , ""
+      any_property yticklabel m , ""
+      any_property zticklabel m , ""
+      radio_property xticklabelmode , "{auto}|manual"
+      radio_property yticklabelmode , "{auto}|manual"
+      radio_property zticklabelmode , "{auto}|manual"
+      radio_property interpreter , "tex|{none}|latex"
+      color_property color , color_property (color_values (1, 1, 1), radio_values ("none"))
+      color_property xcolor , color_values (0, 0, 0)
+      color_property ycolor , color_values (0, 0, 0)
+      color_property zcolor , color_values (0, 0, 0)
+      radio_property xscale alu , "{linear}|log"
+      radio_property yscale alu , "{linear}|log"
+      radio_property zscale alu , "{linear}|log"
+      radio_property xdir u , "{normal}|reverse"
+      radio_property ydir u , "{normal}|reverse"
+      radio_property zdir u , "{normal}|reverse"
+      radio_property yaxislocation , "{left}|right|zero"
+      radio_property xaxislocation , "{bottom}|top|zero"
+      array_property view u , Matrix ()
+      radio_property nextplot , "add|replace_children|{replace}"
+      array_property outerposition u , default_axes_outerposition ()
+      radio_property activepositionproperty , "{outerposition}|position"
+      color_property ambientlightcolor , color_values (1, 1, 1)
+      array_property cameraposition m , Matrix (1, 3, 0.0)
+      array_property cameratarget m , Matrix (1, 3, 0.0)
+      array_property cameraupvector m , Matrix ()
+      double_property cameraviewangle m , 10.0
+      radio_property camerapositionmode , "{auto}|manual"
+      radio_property cameratargetmode , "{auto}|manual"
+      radio_property cameraupvectormode , "{auto}|manual"
+      radio_property cameraviewanglemode , "{auto}|manual"
+      array_property currentpoint , Matrix (2, 3, 0.0)
+      radio_property drawmode , "{normal}|fast"
+      radio_property fontangle , "{normal}|italic|oblique"
+      string_property fontname , OCTAVE_DEFAULT_FONTNAME
+      double_property fontsize , 12
+      radio_property fontunits , "{points}|normalized|inches|centimeters|pixels"
+      radio_property fontweight , "{normal}|light|demi|bold"
+      radio_property gridlinestyle , "-|--|{:}|-.|none"
+      // FIXME -- should be kind of string array.
+      string_property linestyleorder , "-"
+      double_property linewidth , 0.5
+      radio_property minorgridlinestyle , "-|--|{:}|-.|none"
+      array_property plotboxaspectratio m , Matrix (1, 3, 1.0)
+      radio_property plotboxaspectratiomode , "{auto}|manual"
+      radio_property projection , "{orthographic}|perpective"
+      radio_property tickdir m , "{in}|out"
+      radio_property tickdirmode , "{auto}|manual"
+      array_property ticklength , default_axes_ticklength ()
+      array_property tightinset r , Matrix (1, 4, 0.0)
+      // FIXME -- uicontextmenu should be moved here.
+      radio_property units , "{normalized}|inches|centimeters|points|pixels|characters"
+      // hidden properties for transformation computation
+      array_property x_viewtransform h , Matrix (4, 4, 0.0)
+      array_property x_projectiontransform h , Matrix (4, 4, 0.0)
+      array_property x_viewporttransform h , Matrix (4, 4, 0.0)
+      array_property x_normrendertransform h , Matrix (4, 4, 0.0)
+      array_property x_rendertransform h , Matrix (4, 4, 0.0)
+   END_PROPERTIES
+
+  protected:
+    void init (void);
+
+  private:
+    void update_xscale (void) { sx = get_xscale (); }
+    void update_yscale (void) { sy = get_yscale (); }
+    void update_zscale (void) { sz = get_zscale (); }
+
+    void update_view (void) { update_camera (); }
+
+    void update_xdir (void) { update_camera (); }
+    void update_ydir (void) { update_camera (); }
+    void update_zdir (void) { update_camera (); }
+
+    void sync_positions (void);
+    void update_outerposition (void) { sync_positions ();}
+    void update_position (void) { sync_positions (); }
+
+    double calc_tick_sep (double minval, double maxval);
+    void calc_ticks_and_lims (array_property& lims, array_property& ticks, bool limmode_is_auto, bool is_logscale);
+    void fix_limits (array_property& lims)
+    {
+      if (lims.get ().is_empty ()) 
+	return;
+
+      Matrix l = lims.get ().matrix_value ();
+      if (l(0) > l(1))
+	{
+	  l(0) = 0;
+	  l(1) = 1;
+	  lims = l;
+	}
+      else if (l(0) == l(1))
+	{
+	  l(0) -= 0.5;
+	  l(1) += 0.5;
+	  lims = l;
+	}
+    }      
+
+  public:
+    Matrix get_axis_limits (double xmin, double xmax, double min_pos, bool logscale);
+    
+    void update_xlim (bool do_clr_zoom = true)
+    {
+      if (xtickmode.is ("auto"))
+	calc_ticks_and_lims (xlim, xtick, xlimmode.is ("auto"), xscale.is ("log"));
+
+      fix_limits (xlim);
+
+      if (do_clr_zoom)
+	zoom_stack.clear ();
+    }
+
+    void update_ylim (bool do_clr_zoom = true)
+    {
+      if (ytickmode.is ("auto"))
+	calc_ticks_and_lims (ylim, ytick, ylimmode.is ("auto"), yscale.is ("log"));
+
+      fix_limits (ylim);
+
+      if (do_clr_zoom)
+	zoom_stack.clear ();
+    }
+
+    void update_zlim (void)
+    {
+      if (ztickmode.is ("auto"))
+	calc_ticks_and_lims (zlim, ztick, zlimmode.is ("auto"), zscale.is ("log"));
+
+      fix_limits (zlim);
+
+      zoom_stack.clear ();
+    }
+    
+  };
+
+private:
+  properties xproperties;
+
+public:
+  axes (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p), default_properties ()
+  {
+    xproperties.override_defaults (*this);
+    xproperties.update_transform ();
+  }
+
+  ~axes (void) { xproperties.delete_children (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set (const caseless_str& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  void set_defaults (const std::string& mode)
+  {
+    remove_all_listeners ();
+    xproperties.set_defaults (*this, mode);
+  }
+
+  octave_value get (const caseless_str& name) const
+  {
+    octave_value retval;
+
+    // FIXME -- finish this.
+    if (name.compare ("default", 7))
+      retval = get_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const caseless_str& name) const;
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  void update_axis_limits (const std::string& axis_type);
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API line : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    // properties which are not in matlab:
+    // ldata, udata, xldata, xudata, keylabel, interpreter
+
+    BEGIN_PROPERTIES (line)
+      row_vector_property xdata u , default_data ()
+      row_vector_property ydata u , default_data ()
+      row_vector_property zdata u , Matrix ()
+      row_vector_property ldata u , Matrix ()
+      row_vector_property udata u , Matrix ()
+      row_vector_property xldata u , Matrix ()
+      row_vector_property xudata u , Matrix ()
+      string_property xdatasource , ""
+      string_property ydatasource , ""
+      string_property zdatasource , ""
+      color_property color , color_values (0, 0, 0)
+      radio_property linestyle , "{-}|--|:|-.|none"
+      double_property linewidth , 0.5
+      radio_property marker , "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h"
+      color_property markeredgecolor , "{auto}|none"
+      color_property markerfacecolor , "auto|{none}"
+      double_property markersize , 6
+      string_property keylabel , ""
+      radio_property interpreter , "{tex}|none|latex"
+      string_property displayname , ""
+      radio_property erasemode , "{normal}|none|xor|background"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "off"
+    END_PROPERTIES
+
+  private:
+    Matrix compute_xlim (void) const;
+    Matrix compute_ylim (void) const;
+
+    void update_xdata (void) { set_xlim (compute_xlim ()); }
+    void update_xldata (void) { set_xlim (compute_xlim ()); }
+    void update_xudata (void) { set_xlim (compute_xlim ()); }
+    
+    void update_ydata (void) { set_ylim (compute_ylim ()); }
+    void update_ldata (void) { set_ylim (compute_ylim ()); }
+    void update_udata (void) { set_ylim (compute_ylim ()); }
+
+    void update_zdata (void)
+      {
+	set_zlim (zdata.get_limits ());
+	set_zliminclude (get_zdata ().numel () > 0);
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  line (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~line (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API text : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (text)
+      string_property string , ""
+      radio_property units , "{data}|pixels|normalized|inches|centimeters|points"
+      array_property position u , Matrix (1, 3, 0.0)
+      double_property rotation , 0
+      radio_property horizontalalignment , "{left}|center|right"
+      color_property color , color_values (0, 0, 0)
+      string_property fontname , OCTAVE_DEFAULT_FONTNAME
+      double_property fontsize , 10
+      radio_property fontangle , "{normal}|italic|oblique"
+      radio_property fontweight , "light|{normal}|demi|bold"
+      radio_property interpreter , "{tex}|none|latex"
+      color_property backgroundcolor , "{none}"
+      string_property displayname , ""
+      color_property edgecolor , "{none}"
+      radio_property erasemode , "{normal}|none|xor|background"
+      bool_property editing , "off"
+      radio_property fontunits , "inches|centimeters|normalized|{points}|pixels"
+      radio_property linestyle , "{-}|--|:|-.|none"
+      double_property linewidth , 0.5
+      double_property margin , 1
+      radio_property verticalalignment , "top|cap|{middle}|baseline|bottom"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "off"
+    END_PROPERTIES
+
+  protected:
+    void init (void)
+      {
+        position.add_constraint (dim_vector (1, 3));
+      }
+
+  private:
+    void update_position (void)
+      {
+	Matrix pos = get_position ().matrix_value ();
+	Matrix lim;
+
+	lim = Matrix (1, 3, pos(0));
+	lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	set_xlim (lim);
+
+	lim = Matrix (1, 3, pos(1));
+	lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	set_ylim (lim);
+
+	if (pos.numel () == 3)
+	  {
+	    lim = Matrix (1, 3, pos(2));
+	    lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	    set_zliminclude ("on");
+	    set_zlim (lim);
+	  }
+	else
+	  set_zliminclude ("off");
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  text (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~text (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API image : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (image)
+      row_vector_property xdata u , Matrix ()
+      row_vector_property ydata u , Matrix ()
+      array_property cdata u , Matrix ()
+      radio_property cdatamapping al , "{scaled}|direct"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix()
+      row_vector_property ylim hlr , Matrix()
+      row_vector_property clim hlr , Matrix()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property climinclude hlg , "on"
+    END_PROPERTIES
+
+  protected:
+    void init (void)
+      {
+	xdata.add_constraint (2);
+	ydata.add_constraint (2);
+	cdata.add_constraint ("double");
+	cdata.add_constraint ("logical");
+	cdata.add_constraint ("uint8");
+	cdata.add_constraint (dim_vector (-1, -1));
+	cdata.add_constraint (dim_vector (-1, -1, 3));
+      }
+
+  private:
+    // FIXME -- limits should take pixel width into account.
+    void update_xdata (void)
+      { set_xlim (xdata.get_limits ()); }
+
+    // FIXME -- idem.
+    void update_ydata (void)
+      { set_ylim (ydata.get_limits ()); }
+
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  image (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~image (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API patch : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    octave_value get_color_data (void) const;
+    
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    bool is_aliminclude (void) const
+      { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
+    std::string get_aliminclude (void) const
+      { return aliminclude.current_value (); }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (patch)
+      array_property xdata u , Matrix ()
+      array_property ydata u , Matrix ()
+      array_property zdata u , Matrix ()
+      array_property cdata u , Matrix ()
+      radio_property cdatamapping l , "{scaled}|direct"
+      array_property faces , Matrix ()
+      array_property facevertexalphadata , Matrix ()
+      array_property facevertexcdata , Matrix ()
+      array_property vertices , Matrix ()
+      array_property vertexnormals , Matrix ()
+      radio_property normalmode , "{auto}|manual"
+      color_property facecolor , "{flat}|none|interp"
+      double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp"))
+      radio_property facelighting , "flat|{none}|gouraud|phong"
+      color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("flat|none|interp"))
+      double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp"))
+      radio_property edgelighting , "{none}|flat|gouraud|phong"
+      radio_property backfacelighting , "{reverselit}|unlit|lit"
+      double_property ambientstrength , 0.3
+      double_property diffusestrength , 0.6
+      double_property specularstrength , 0.6
+      double_property specularexponent , 10.0
+      double_property specularcolorreflectance , 1.0
+      radio_property erasemode , "{normal}|background|xor|none"
+      radio_property linestyle , "{-}|--|:|-.|none"
+      double_property linewidth , 0.5
+      radio_property marker , "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h"
+      color_property markeredgecolor , "{auto}|none"
+      color_property markerfacecolor , "auto|{none}"
+      double_property markersize , 6
+      string_property keylabel , ""
+      radio_property interpreter , "{tex}|none|latex"
+      radio_property alphadatamapping l , "none|{scaled}|direct"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      row_vector_property clim hlr , Matrix ()
+      row_vector_property alim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "on"
+      bool_property climinclude hlg , "on"
+      bool_property aliminclude hlg , "on"
+    END_PROPERTIES
+
+  protected:
+    void init (void)
+      {
+	xdata.add_constraint (dim_vector (-1, -1));
+	ydata.add_constraint (dim_vector (-1, -1));
+	zdata.add_constraint (dim_vector (-1, -1));
+        vertices.add_constraint (dim_vector (-1, 2));
+        vertices.add_constraint (dim_vector (-1, 3));
+	cdata.add_constraint (dim_vector (-1, -1));
+	cdata.add_constraint (dim_vector (-1, -1, 3));
+	facevertexcdata.add_constraint (dim_vector (-1, 1));
+	facevertexcdata.add_constraint (dim_vector (-1, 3));
+	facevertexalphadata.add_constraint (dim_vector (-1, 1));
+      }
+
+  private:
+    void update_xdata (void) { set_xlim (xdata.get_limits ()); }
+    void update_ydata (void) { set_ylim (ydata.get_limits ()); }
+    void update_zdata (void) { set_zlim (zdata.get_limits ()); }
+    
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  patch (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~patch (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API surface : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    octave_value get_color_data (void) const;
+
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    bool is_aliminclude (void) const
+      { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
+    std::string get_aliminclude (void) const
+      { return aliminclude.current_value (); }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (surface)
+      array_property xdata u , Matrix ()
+      array_property ydata u , Matrix ()
+      array_property zdata u , Matrix ()
+      array_property cdata u , Matrix ()
+      radio_property cdatamapping al , "{scaled}|direct"
+      string_property xdatasource , ""
+      string_property ydatasource , ""
+      string_property zdatasource , ""
+      string_property cdatasource , ""
+      color_property facecolor , "{flat}|none|interp|texturemap"
+      double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp"))
+      color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("flat|none|interp"))
+      radio_property linestyle , "{-}|--|:|-.|none"
+      double_property linewidth , 0.5
+      radio_property marker , "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h"
+      color_property markeredgecolor , "{auto}|none"
+      color_property markerfacecolor , "auto|{none}"
+      double_property markersize , 6
+      string_property keylabel , ""
+      radio_property interpreter , "{tex}|none|latex"
+      array_property alphadata u , Matrix ()
+      radio_property alphadatamapping l , "none|direct|{scaled}"
+      double_property ambientstrength , 0.3
+      radio_property backfacelighting , "unlit|lit|{reverselit}"
+      double_property diffusestrength , 0.6
+      double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp"))
+      radio_property edgelighting , "{none}|flat|gouraud|phong"
+      radio_property erasemode , "{normal}|none|xor|background"
+      radio_property facelighting , "{none}|flat|gouraud|phong"
+      radio_property meshstyle , "{both}|row|column"
+      radio_property normalmode u , "{auto}|manual"
+      double_property specularcolorreflectance , 1
+      double_property specularexponent , 10
+      double_property specularstrength , 0.9
+      array_property vertexnormals u , Matrix ()
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      row_vector_property clim hlr , Matrix ()
+      row_vector_property alim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "on"
+      bool_property climinclude hlg , "on"
+      bool_property aliminclude hlg , "on"
+    END_PROPERTIES
+
+  protected:
+    void init (void)
+      {
+	xdata.add_constraint (dim_vector (-1, -1));
+	ydata.add_constraint (dim_vector (-1, -1));
+	zdata.add_constraint (dim_vector (-1, -1));
+	alphadata.add_constraint ("double");
+	alphadata.add_constraint ("uint8");
+	alphadata.add_constraint (dim_vector (-1, -1));
+	vertexnormals.add_constraint (dim_vector (-1, -1, 3));
+	cdata.add_constraint ("double");
+	cdata.add_constraint ("uint8");
+	cdata.add_constraint (dim_vector (-1, -1));
+	cdata.add_constraint (dim_vector (-1, -1, 3));
+      }
+
+  private:
+    void update_normals (void);
+
+    void update_xdata (void)
+      {
+	update_normals ();
+	set_xlim (xdata.get_limits ());
+      }
+ 
+    void update_ydata (void)
+      {
+	update_normals ();
+	set_ylim (ydata.get_limits ());
+      }
+
+    void update_zdata (void)
+      {
+	update_normals ();
+	set_zlim (zdata.get_limits ());
+      }
+
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+
+    void update_alphadata (void)
+      {
+	if (alphadatamapping_is ("scaled"))
+	  set_alim (alphadata.get_limits ());
+	else
+	  alim = alphadata.get_limits ();
+      }
+
+    void update_normalmode (void)
+      { update_normals (); }
+
+    void update_vertexnormals (void)
+      { set_normalmode ("manual"); }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  surface (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~surface (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API hggroup : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    void remove_child (const graphics_handle& h)
+      {
+	base_properties::remove_child (h);
+	update_limits ();
+      }
+
+    void adopt (const graphics_handle& h)
+      {
+	base_properties::adopt (h);
+	update_limits ();
+      }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (hggroup)
+      // hidden properties for limit computation
+      row_vector_property xlim hr , Matrix()
+      row_vector_property ylim hr , Matrix()
+      row_vector_property zlim hr , Matrix()
+      row_vector_property clim hr , Matrix()
+      row_vector_property alim hr , Matrix()
+      bool_property xliminclude h , "on"
+      bool_property yliminclude h , "on"
+      bool_property zliminclude h , "on"
+      bool_property climinclude h , "on"
+      bool_property aliminclude h , "on"
+    END_PROPERTIES
+
+  private:
+    void update_limits (void)
+      {
+	update_axis_limits ("xlim");
+	update_axis_limits ("ylim");
+	update_axis_limits ("zlim");
+	update_axis_limits ("clim");
+	update_axis_limits ("alim");
+      }
+
+  protected:
+    void init (void)
+      { }
+  };
+
+private:
+  properties xproperties;
+
+public:
+  hggroup (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~hggroup (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+  
+  void update_axis_limits (const std::string& axis_type);
+};
+
+// ---------------------------------------------------------------------
+
+octave_value
+get_property_from_handle (double handle, const std::string &property,
+			  const std::string &func);
+bool
+set_property_in_handle (double handle, const std::string &property,
+			const octave_value &arg, const std::string &func);
+
+// ---------------------------------------------------------------------
+
+class graphics_event;
+
+class
+base_graphics_event
+{
+public:
+  friend class graphics_event;
+
+  base_graphics_event (void) : count (1) { }
+
+  virtual ~base_graphics_event (void) { }
+
+  virtual void execute (void) = 0;
+
+private:
+  int count;
+};
+
+class
+graphics_event
+{
+public:
+  typedef void (*event_fcn) (void*);
+
+  graphics_event (void) : rep (0) { }
+
+  graphics_event (const graphics_event& e)
+    {
+      rep = e.rep;
+      rep->count++;
+    }
+
+  ~graphics_event (void)
+    {
+      if (rep && --rep->count == 0)
+	delete rep;
+    }
+
+  graphics_event& operator = (const graphics_event& e)
+    {
+      if (rep != e.rep)
+	{
+	  if (rep && --rep->count == 0)
+	    delete rep;
+
+	  rep = e.rep;
+	  if (rep)
+	    rep->count++;
+	}
+
+      return *this;
+    }
+
+  void execute (void)
+    { if (rep) rep->execute (); }
+
+  bool ok (void) const
+    { return (rep != 0); }
+
+  static graphics_event
+      create_callback_event (const graphics_handle& h,
+			     const std::string& name,
+			     const octave_value& data = Matrix ());
+
+  static graphics_event
+      create_function_event (event_fcn fcn, void *data = 0);
+
+  static graphics_event
+      create_set_event (const graphics_handle& h,
+			const std::string& name,
+			const octave_value& value);
+private:
+  base_graphics_event *rep;
+};
+
+class OCTINTERP_API gh_manager
+{
+protected:
+
+  gh_manager (void);
+
+public:
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new gh_manager ();
+
+    if (! instance)
+      {
+	::error ("unable to create gh_manager!");
+
+	retval = false;
+      }
+
+    return retval;
+  }
+
+  static void free (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_free (h);
+  }
+
+  static graphics_handle lookup (double val)
+  {
+    return instance_ok () ? instance->do_lookup (val) : graphics_handle ();
+  }
+
+  static graphics_object get_object (const graphics_handle& h)
+  {
+    return instance_ok () ? instance->do_get_object (h) : graphics_object ();
+  }
+
+  static graphics_handle
+  make_graphics_handle (const std::string& go_name,
+			const graphics_handle& parent, bool do_createfcn = true)
+  {
+    return instance_ok ()
+      ? instance->do_make_graphics_handle (go_name, parent, do_createfcn)
+      : graphics_handle ();
+  }
+
+  static graphics_handle make_figure_handle (double val)
+  {
+    return instance_ok ()
+      ? instance->do_make_figure_handle (val) : graphics_handle ();
+  }
+
+  static void push_figure (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_push_figure (h);
+  }
+
+  static void pop_figure (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_pop_figure (h);
+  }
+
+  static graphics_handle current_figure (void)
+  {
+    return instance_ok ()
+      ? instance->do_current_figure () : graphics_handle ();
+  }
+
+  static Matrix handle_list (void)
+  {
+    return instance_ok () ? instance->do_handle_list () : Matrix ();
+  }
+
+  static void lock (void)
+  {
+    if (instance_ok ())
+      instance->do_lock ();
+  }
+
+  static void unlock (void)
+  {
+    if (instance_ok ())
+      instance->do_unlock ();
+  }
+
+  static Matrix figure_handle_list (void)
+  {
+    return instance_ok () ? instance->do_figure_handle_list () : Matrix ();
+  }
+
+  static void execute_callback (const graphics_handle& h,
+				const std::string& name,
+				const octave_value& data = Matrix ())
+  {
+    graphics_object go = get_object (h);
+
+    if (go.valid_object ())
+      {
+	octave_value cb = go.get (name);
+
+	if (! error_state)
+	  execute_callback (h, cb, data);
+      }
+  }
+
+  static void execute_callback (const graphics_handle& h,
+				const octave_value& cb,
+				const octave_value& data = Matrix ())
+  {
+    if (instance_ok ())
+      instance->do_execute_callback (h, cb, data);
+  }
+
+  static void post_callback (const graphics_handle& h,
+			     const std::string& name,
+			     const octave_value& data = Matrix ())
+  {
+    if (instance_ok ())
+      instance->do_post_callback (h, name, data);
+  }
+
+  static void post_function (graphics_event::event_fcn fcn, void* data = 0)
+  {
+    if (instance_ok ())
+      instance->do_post_function (fcn, data);
+  }
+
+  static void post_set (const graphics_handle& h,
+			const std::string& name,
+			const octave_value& value)
+  {
+    if (instance_ok ())
+      instance->do_post_set (h, name, value);
+  }
+
+  static int process_events (void)
+  {
+    return (instance_ok () ?  instance->do_process_events () : 0);
+  }
+
+  static int flush_events (void)
+  {
+    return (instance_ok () ?  instance->do_process_events (true) : 0);
+  }
+
+  static bool is_handle_visible (const graphics_handle& h)
+  {
+    bool retval = false;
+
+    graphics_object go = get_object (h);
+
+    if (go.valid_object ())
+      retval = go.is_handle_visible ();
+
+    return retval;
+  }
+
+public:
+  class autolock
+  {
+  public:
+    autolock (void) { lock (); }
+
+    ~autolock (void) { unlock (); }
+
+  private:
+
+    // No copying!
+    autolock (const autolock&);
+    autolock& operator = (const autolock&);
+  };
+
+private:
+
+  static gh_manager *instance;
+
+  typedef std::map<graphics_handle, graphics_object>::iterator iterator;
+  typedef std::map<graphics_handle, graphics_object>::const_iterator const_iterator;
+
+  typedef std::set<graphics_handle>::iterator free_list_iterator;
+  typedef std::set<graphics_handle>::const_iterator const_free_list_iterator;
+
+  typedef std::list<graphics_handle>::iterator figure_list_iterator;
+  typedef std::list<graphics_handle>::const_iterator const_figure_list_iterator;
+
+  // A map of handles to graphics objects.
+  std::map<graphics_handle, graphics_object> handle_map;
+
+  // The available graphics handles.
+  std::set<graphics_handle> handle_free_list;
+
+  // The next handle available if handle_free_list is empty.
+  double next_handle;
+
+  // The allocated figure handles.  Top of the stack is most recently
+  // created.
+  std::list<graphics_handle> figure_list;
+
+  // The lock for accessing the graphics sytsem
+  octave_mutex graphics_lock;
+
+  // The list of event queued by backends
+  std::list<graphics_event> event_queue;
+
+  // The stack of callback objects
+  std::list<graphics_object> callback_objects;
+
+  graphics_handle get_handle (const std::string& go_name);
+
+  void do_free (const graphics_handle& h);
+
+  graphics_handle do_lookup (double val)
+  {
+    iterator p = (xisnan (val) ? handle_map.end () : handle_map.find (val));
+
+    return (p != handle_map.end ()) ? p->first : graphics_handle ();
+  }
+
+  graphics_object do_get_object (const graphics_handle& h)
+  {
+    iterator p = (h.ok () ? handle_map.find (h) : handle_map.end ());
+
+    return (p != handle_map.end ()) ? p->second : graphics_object ();
+  }
+
+  graphics_handle do_make_graphics_handle (const std::string& go_name,
+					   const graphics_handle& p, bool do_createfcn);
+
+  graphics_handle do_make_figure_handle (double val);
+
+  Matrix do_handle_list (void)
+  {
+    Matrix retval (1, handle_map.size ());
+    octave_idx_type i = 0;
+    for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++)
+      {
+	graphics_handle h = p->first;
+	retval(i++) = h.value ();
+      }
+    return retval;
+  }
+
+  Matrix do_figure_handle_list (void)
+  {
+    Matrix retval (1, figure_list.size ());
+    octave_idx_type i = 0;
+    for (const_figure_list_iterator p = figure_list.begin ();
+	 p != figure_list.end ();
+	 p++)
+      {
+	graphics_handle h = *p;
+	retval(i++) = h.value ();
+      }
+    return retval;
+  }
+
+  void do_push_figure (const graphics_handle& h);
+
+  void do_pop_figure (const graphics_handle& h);
+
+  graphics_handle do_current_figure (void) const
+  {
+    return figure_list.empty () ? graphics_handle () : figure_list.front ();
+  }
+
+  void do_lock (void) { graphics_lock.lock (); }
+  
+  void do_unlock (void) { graphics_lock.unlock (); }
+
+  void do_execute_callback (const graphics_handle& h, const octave_value& cb,
+			    const octave_value& data);
+
+  void do_post_callback (const graphics_handle& h, const std::string name,
+			 const octave_value& data);
+
+  void do_post_function (graphics_event::event_fcn fcn, void* fcn_data);
+
+  void do_post_set (const graphics_handle& h, const std::string name,
+		    const octave_value& value);
+
+  int do_process_events (bool force = false);
+
+  static void restore_gcbo (void*)
+  {
+    if (instance_ok ())
+      instance->do_restore_gcbo ();
+  }
+
+  void do_restore_gcbo (void);
+
+  void do_post_event (const graphics_event& e);
+};
+
+
+// This function is NOT equivalent to the scripting language function gcf.
+OCTINTERP_API graphics_handle gcf (void);
+
+// This function is NOT equivalent to the scripting language function gca.
+OCTINTERP_API graphics_handle gca (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/gripes.cc b/src/gripes.cc
new file mode 100644
index 0000000..3fd8921
--- /dev/null
+++ b/src/gripes.cc
@@ -0,0 +1,278 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+void
+gripe_not_supported (const char *fcn)
+{
+  error ("%s: not supported on this system", fcn);
+}
+
+void
+gripe_not_implemented (const char *fcn)
+{
+  error ("%s: not implemented", fcn);
+}
+
+void
+gripe_string_invalid (void)
+{
+  error ("std::string constant used in invalid context");
+}
+
+void
+gripe_range_invalid (void)
+{
+  error ("range constant used in invalid context");
+}
+
+void
+gripe_nonconformant (void)
+{
+  error ("nonconformant matrices");
+}
+
+void
+gripe_nonconformant (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2)
+{
+  error ("nonconformant matrices (op1 is %dx%d, op2 is %dx%d)",
+	 r1, c1, r2, c2);
+}
+
+void
+gripe_empty_arg (const char *name, bool is_error)
+{
+  if (is_error)
+    error ("%s: empty matrix is invalid as an argument", name);
+  else
+    warning ("%s: argument is empty matrix", name);
+}
+
+void
+gripe_square_matrix_required (const char *name)
+{
+  error ("%s: argument must be a square matrix", name);
+}
+
+void
+gripe_user_supplied_eval (const char *name)
+{
+  error ("%s: evaluation of user-supplied function failed", name);
+}
+
+void
+gripe_user_returned_invalid (const char *name)
+{
+  error ("%s: user-supplied function returned invalid value", name);
+}
+
+void
+gripe_invalid_conversion (const std::string& from, const std::string& to)
+{
+  error ("invalid conversion from %s to %s", from.c_str (), to.c_str ());
+}
+
+void
+gripe_invalid_value_specified (const char *name)
+{
+  warning ("invalid value specified for `%s'", name);
+}
+
+void
+gripe_2_or_3_dim_plot (void)
+{
+  error ("plot: can only plot in 2 or 3 dimensions");
+}
+
+void
+gripe_unrecognized_float_fmt (void)
+{
+  error ("unrecognized floating point format requested");
+}
+
+void
+gripe_unrecognized_data_fmt (const char *warn_for)
+{
+  error ("%s: unrecognized data format requested", warn_for);
+}
+
+void
+gripe_data_conversion (const char *from, const char *to)
+{
+  error ("unable to convert from %s to %s format", from, to);
+}
+
+void
+gripe_wrong_type_arg (const char *name, const char *s, bool is_error)
+{
+  if (is_error)
+    error ("%s: wrong type argument `%s'", name, s);
+  else
+    warning ("%s: wrong type argument `%s'", name, s);
+}
+
+void
+gripe_wrong_type_arg (const char *name, const std::string& s, bool is_error)
+{
+  gripe_wrong_type_arg (name, s.c_str (), is_error);
+}
+
+void
+gripe_wrong_type_arg (const char *name, const octave_value& tc,
+		      bool is_error)
+{
+  std::string type = tc.type_name ();
+
+  gripe_wrong_type_arg (name, type, is_error);
+}
+
+void
+gripe_wrong_type_arg (const std::string& name, const octave_value& tc,
+		      bool is_error)
+{
+  gripe_wrong_type_arg (name.c_str (), tc, is_error);
+}
+
+void
+gripe_wrong_type_arg_for_unary_op (const octave_value& op)
+{
+  std::string type = op.type_name ();
+  error ("invalid operand `%s' for unary operator", type.c_str ());
+}
+
+void
+gripe_wrong_type_arg_for_binary_op (const octave_value& op)
+{
+  std::string type = op.type_name ();
+  error ("invalid operand `%s' for binary operator", type.c_str ());
+}
+
+void
+gripe_implicit_conversion (const char *id, const char *from, const char *to)
+{
+  warning_with_id (id, "implicit conversion from %s to %s", from, to);
+}
+
+void
+gripe_implicit_conversion (const std::string& id,
+			   const std::string& from, const std::string& to)
+{
+  warning_with_id (id.c_str (),
+		   "implicit conversion from %s to %s",
+		   from.c_str (), to.c_str ());
+}
+
+void
+gripe_divide_by_zero (void)
+{
+  warning_with_id ("Octave:divide-by-zero", "division by zero");
+}
+
+void
+gripe_logical_conversion (void)
+{
+  warning_with_id ("Octave:logical-conversion",
+		   "value not equal to 1 or 0 converted to logical 1");
+}
+
+void
+gripe_truncated_conversion (const char *srctype, const char *desttype)
+{
+  warning_with_id ("Octave:int-convert-overflow", 
+                   "data truncated converting from %s to %s",
+                   srctype, desttype);
+}
+
+void
+gripe_binop_integer_math_truncated (const char *op, const char *type1, const char *type2)
+{
+  warning_with_id ("Octave:int-math-overflow",
+                   "data truncated for %s by %s binary operator %s",
+                   type1, type2, op);
+}
+
+void
+gripe_native_integer_math_truncated (const char *fcn, const char *type)
+{
+  warning_with_id ("Octave:int-math-overflow",
+                   "data truncated for %s native %s operation",
+                   type, fcn);
+}
+
+void
+gripe_unop_integer_math_truncated (const char* op, const char *type)
+{
+  warning_with_id ("Octave:int-math-overflow",
+                   "data truncated for the %s unary operator %s", type, op);
+}
+
+void
+gripe_library_execution_error (void)
+{
+  octave_exception_state = octave_no_exception;
+
+  if (! error_state)
+    error ("caught execution error in library function");
+}
+
+void
+gripe_non_integer_conversion (const char *srctype, const char *desttype)
+{
+  warning_with_id ("Octave:int-convert-non-int-val", 
+                   "Conversion of non-integer value from %s to %s",
+                   srctype, desttype);
+}
+void
+gripe_nan_conversion (const char *srctype, const char *desttype)
+{
+  warning_with_id ("Octave:int-convert-nan", 
+                   "Conversion of NaN from %s to %s",
+                   srctype, desttype);
+}
+
+void
+gripe_invalid_inquiry_subscript (void)
+{
+  error ("invalid dimension inquiry of a non-existent value");
+}
+
+void
+gripe_indexed_cs_list (void)
+{
+  error ("a cs-list cannot be further indexed");
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/gripes.h b/src/gripes.h
new file mode 100644
index 0000000..71e5568
--- /dev/null
+++ b/src/gripes.h
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2003, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_gripes_h)
+#define octave_gripes_h 1
+
+#include <string>
+
+#include "oct-types.h"
+
+class octave_value;
+
+extern OCTINTERP_API void
+gripe_not_supported (const char *);
+
+extern OCTINTERP_API void
+gripe_not_implemented (const char *);
+
+extern OCTINTERP_API void
+gripe_string_invalid (void);
+
+extern OCTINTERP_API void
+gripe_range_invalid (void);
+
+extern OCTINTERP_API void
+gripe_nonconformant (void);
+
+extern OCTINTERP_API void
+gripe_nonconformant (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2);
+
+extern OCTINTERP_API void
+gripe_empty_arg (const char *name, bool is_error);
+
+extern OCTINTERP_API void
+gripe_square_matrix_required (const char *name);
+
+extern OCTINTERP_API void
+gripe_user_supplied_eval (const char *name);
+
+extern OCTINTERP_API void
+gripe_user_returned_invalid (const char *name);
+
+extern OCTINTERP_API void
+gripe_invalid_conversion (const std::string& from, const std::string& to);
+
+extern OCTINTERP_API void
+gripe_invalid_value_specified (const char *name);
+
+extern OCTINTERP_API void
+gripe_2_or_3_dim_plot (void);
+
+extern OCTINTERP_API void
+gripe_unrecognized_float_fmt (void);
+
+extern OCTINTERP_API void
+gripe_unrecognized_data_fmt (const char *warn_for);
+
+extern OCTINTERP_API void
+gripe_data_conversion (const char *from, const char *to);
+
+extern OCTINTERP_API void
+gripe_wrong_type_arg (const char *name, const char *s,
+		      bool is_error = true);
+
+extern OCTINTERP_API void
+gripe_wrong_type_arg (const char *name, const std::string& s,
+		      bool is_error = true);
+
+extern OCTINTERP_API void
+gripe_wrong_type_arg (const char *name, const octave_value& tc,
+		      bool is_error = true);
+
+extern OCTINTERP_API void
+gripe_wrong_type_arg (const std::string& name, const octave_value& tc,
+		      bool is_error = true);
+
+extern OCTINTERP_API void
+gripe_wrong_type_arg_for_unary_op (const octave_value& op);
+
+extern OCTINTERP_API void
+gripe_wrong_type_arg_for_binary_op (const octave_value& op);
+
+extern OCTINTERP_API void
+gripe_implicit_conversion (const char *id, const char *from, const char *to);
+
+extern OCTINTERP_API void
+gripe_implicit_conversion (const std::string& id, const std::string& from,
+			   const std::string& to);
+
+extern OCTINTERP_API void
+gripe_truncated_conversion (const char *srctype, const char *desttype);
+
+extern OCTINTERP_API void
+gripe_binop_integer_math_truncated (const char *op, const char *type1, const char *type2);
+
+extern OCTINTERP_API void
+gripe_native_integer_math_truncated (const char *fcn, const char *type);
+
+extern OCTINTERP_API void
+gripe_unop_integer_math_truncated (const char *op, const char *type);
+
+extern OCTINTERP_API void
+gripe_non_integer_conversion (const char *srctype, const char *desttype);
+
+extern OCTINTERP_API void
+gripe_nan_conversion (const char *srctype, const char *desttype);
+
+extern OCTINTERP_API void
+gripe_divide_by_zero (void);
+
+extern OCTINTERP_API void
+gripe_logical_conversion (void);
+
+extern OCTINTERP_API void
+gripe_library_execution_error (void);
+
+extern OCTINTERP_API void
+gripe_invalid_inquiry_subscript (void);
+
+extern OCTINTERP_API void
+gripe_indexed_cs_list (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/help.cc b/src/help.cc
new file mode 100644
index 0000000..6ee1c47
--- /dev/null
+++ b/src/help.cc
@@ -0,0 +1,1077 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+#include <cstring>
+
+#include <algorithm>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+#include "str-vec.h"
+
+#include <defaults.h>
+#include "defun.h"
+#include "dirfns.h"
+#include "error.h"
+#include "gripes.h"
+#include "help.h"
+#include "input.h"
+#include "load-path.h"
+#include "oct-obj.h"
+#include "ov-usr-fcn.h"
+#include "pager.h"
+#include "parse.h"
+#include "pathsearch.h"
+#include "procstream.h"
+#include "pt-pr-code.h"
+#include "sighandlers.h"
+#include "symtab.h"
+#include "syswait.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "quit.h"
+
+// Name of the doc cache file specified on the command line.
+// (--doc-cache-file file)
+std::string Vdoc_cache_file;
+
+// Name of the info file specified on command line.
+// (--info-file file)
+std::string Vinfo_file;
+
+// Name of the info reader we'd like to use.
+// (--info-program program)
+std::string Vinfo_program;
+
+// Name of the makeinfo program to run.
+static std::string Vmakeinfo_program = "makeinfo";
+
+// If TRUE, don't print additional help message in help and usage
+// functions.
+static bool Vsuppress_verbose_help_message = false;
+
+#include <map>
+
+typedef std::map<std::string, std::string> map_type;
+typedef map_type::value_type pair_type;
+typedef map_type::const_iterator map_iter;
+
+template<typename T, std::size_t z>
+std::size_t
+size (T const (&)[z])
+{
+  return z;
+}
+
+// FIXME -- The descriptions could easily be in texinfo -- should they?
+const static pair_type operators[] =
+{
+  pair_type ("!",
+    "Logical not operator.  See also `~'.\n"),
+
+  pair_type ("!=",
+    "Logical not equals operator.  See also `~='.\n"),
+
+  pair_type ("\"",
+    "String delimiter.\n"),
+
+  pair_type ("#",
+    "Begin comment character.  See also `%'."),
+
+  pair_type ("%",
+    "Begin comment charcter.  See also `#'."),
+
+  pair_type ("&",
+    "Element by element logical and operator.  See also `&&'."),
+
+  pair_type ("&&",
+    "Logical and operator (with short-circuit evaluation).  See also `&'."),
+
+  pair_type ("'",
+    "Matrix transpose operator.  For complex matrices, computes the\n\
+complex conjugate (Hermitian) transpose.  See also `.''\n\
+\n\
+The single quote character may also be used to delimit strings, but\n\
+it is better to use the double quote character, since that is never\n\
+ambiguous"),
+
+  pair_type ("(",
+    "Array index or function argument delimiter."),
+
+  pair_type (")",
+    "Array index or function argument delimiter."),
+
+  pair_type ("*",
+    "Multiplication operator.  See also `.*'"),
+
+  pair_type ("**",
+    "Power operator.  See also `^', `.**', and `.^'"),
+
+  pair_type ("+",
+    "Addition operator."),
+
+  pair_type ("++",
+    "Increment operator.  As in C, may be applied as a prefix or postfix\n\
+operator."),
+
+  pair_type (",",
+    "Array index, function argument, or command separator."),
+
+  pair_type ("-",
+    "Subtraction or unary negation operator."),
+
+  pair_type ("--",
+    "Decrement operator.  As in C, may be applied as a prefix or postfix\n\
+operator."),
+
+  pair_type (".'",
+    "Matrix transpose operator.  For complex matrices, computes the\n\
+transpose, *not* the complex conjugate transpose.  See also `''."),
+
+  pair_type (".*",
+    "Element by element multiplication operator.  See also `*'."),
+
+  pair_type (".**",
+    "Element by element power operator.  See also `**', `^', and `.^'."),
+
+  pair_type ("./",
+    "Element by element division operator.  See also `/' and `\\'."),
+
+  pair_type (".^",
+    "Element by element power operator.  See also `**', `^', and `.^'."),
+
+  pair_type ("/",
+    "Right division.  See also `\\' and `./'."),
+
+  pair_type (":",
+    "Select entire rows or columns of matrices."),
+
+  pair_type (";",
+    "Array row or command separator.  See also `,'."),
+
+  pair_type ("<",
+    "Less than operator."),
+
+  pair_type ("<=",
+    "Less than or equals operator."),
+
+  pair_type ("=",
+    "Assignment operator."),
+
+  pair_type ("==",
+    "Equality test operator."),
+
+  pair_type (">",
+    "Greater than operator."),
+
+  pair_type (">=",
+    "Greater than or equals operator."),
+
+  pair_type ("[",
+    "Return list delimiter.  See also `]'."),
+
+  pair_type ("\\",
+    "Left division operator.  See also `/' and `./'."),
+
+  pair_type ("]",
+    "Return list delimiter.  See also `['."),
+
+  pair_type ("^",
+    "Power operator.  See also `**', `.^', and `.**.'"),
+
+  pair_type ("|",
+    "Element by element logical or operator.  See also `||'."),
+
+  pair_type ("||",
+    "Logical or operator (with short-circuit evaluation).  See also `|'."),
+
+  pair_type ("~",
+    "Logical not operator.  See also `!' and `~'."),
+
+  pair_type ("~=",
+    "Logical not equals operator.  See also `!='."),
+};
+
+const static pair_type keywords[] =
+{
+  pair_type ("break",
+    "-*- texinfo -*-\n\
+ at deffn Keyword break\n\
+Exit the innermost enclosing do, while or for loop.\n\
+ at seealso{do, while, for, continue}\n\
+ at end deffn"),
+
+  pair_type ("case",
+    "-*- texinfo -*-\n\
+ at deffn Keyword case @{@var{value}@}\n\
+A case statement in an switch.  Octave cases are exclusive and do not\n\
+fall-through as do C-language cases.  A switch statement must have at least\n\
+one case.  See @code{switch} for an example.\n\
+ at seealso{switch}\n\
+ at end deffn"),
+
+  pair_type ("catch",
+    "-*- texinfo -*-\n\
+ at deffn Keyword catch\n\
+Begin the cleanup part of a try-catch block.\n\
+ at seealso{try}\n\
+ at end deffn"),
+
+  pair_type ("continue",
+    "-*- texinfo -*-\n\
+ at deffn Keyword continue\n\
+Jump to the end of the innermost enclosing do, while or for loop.\n\
+ at seealso{do, while, for, break}\n\
+ at end deffn"),
+
+  pair_type ("do",
+    "-*- texinfo -*-\n\
+ at deffn Keyword do\n\
+Begin a do-until loop.  This differs from a do-while loop in that the\n\
+body of the loop is executed at least once.\n\
+ at seealso{while}\n\
+ at end deffn"),
+
+  pair_type ("else",
+    "-*- texinfo -*-\n\
+ at deffn Keyword else\n\
+Alternate action for an if block.  See @code{if} for an example.\n\
+ at seealso{if}\n\
+ at end deffn"),
+
+  pair_type ("elseif",
+    "-*- texinfo -*-\n\
+ at deffn Keyword elseif (@var{condition})\n\
+Alternate conditional test for an if block.  See @code{if} for an example.\n\
+ at seealso{if}\n\
+ at end deffn"),
+
+  pair_type ("end",
+    "-*- texinfo -*-\n\
+ at deffn Keyword end\n\
+Mark the end of any @code{for}, @code{if}, @code{do}, @code{while}, or @code{function} block.\n\
+ at seealso{for, if, do, while, function}\n\
+ at end deffn"),
+
+  pair_type ("end_try_catch",
+    "-*- texinfo -*-\n\
+ at deffn Keyword end_try_catch\n\
+Mark the end of an @code{try-catch} block.\n\
+ at seealso{try, catch}\n\
+ at end deffn"), 
+
+  pair_type ("end_unwind_protect",
+    "-*- texinfo -*-\n\
+ at deffn Keyword end_unwind_protect\n\
+Mark the end of an unwind_protect block.\n\
+ at seealso{unwind_protect}\n\
+ at end deffn"), 
+
+  pair_type ("endfor",
+    "-*- texinfo -*-\n\
+ at deffn Keyword endfor\n\
+Mark the end of a for loop.  See @code{for} for an example.\n\
+ at seealso{for}\n\
+ at end deffn"),
+
+  pair_type ("endfunction",
+    "-*- texinfo -*-\n\
+ at deffn Keyword endfunction\n\
+Mark the end of a function.\n\
+ at seealso{function}\n\
+ at end deffn"),
+
+  pair_type ("endif",
+    "-*- texinfo -*-\n\
+ at deffn Keyword endif\n\
+Mark the end of an if block.  See @code{if} for an example.\n\
+ at seealso{if}\n\
+ at end deffn"),
+
+  pair_type ("endswitch",
+    "-*- texinfo -*-\n\
+ at deffn Keyword endswitch\n\
+Mark the end of a switch block.  See @code{switch} for an example.\n\
+ at seealso{switch}\n\
+ at end deffn"),
+
+  pair_type ("endwhile",
+    "-*- texinfo -*-\n\
+ at deffn Keyword endwhile\n\
+Mark the end of a while loop.  See @code{while} for an example.\n\
+ at seealso{do, while}\n\
+ at end deffn"),
+
+  pair_type ("for",
+    "-*- texinfo -*-\n\
+ at deffn Keyword for @var{i} = @var{range}\n\
+Begin a for loop.\n\
+ at example\n\
+ at group\n\
+for i = 1:10\n\
+  i\n\
+endfor\n\
+ at end group\n\
+ at end example\n\
+ at seealso{do, while}\n\
+ at end deffn"),
+
+  pair_type ("function",
+    "-*- texinfo -*-\n\
+ at deffn Keyword function @var{outputs} = function (@var{input}, @dots{})\n\
+ at deffnx Keyword function {} function (@var{input}, @dots{})\n\
+ at deffnx Keyword function @var{outputs} = function\n\
+Begin a function body with @var{outputs} as results and @var{inputs} as\n\
+parameters.\n\
+ at seealso{return}\n\
+ at end deffn"),
+
+  pair_type ("global",
+    "-*- texinfo -*-\n\
+ at deffn Keyword global\n\
+Declare variables to have global scope.\n\
+ at example\n\
+ at group\n\
+global @var{x};\n\
+if isempty (@var{x})\n\
+  x = 1;\n\
+endif\n\
+ at end group\n\
+ at end example\n\
+ at seealso{persistent}\n\
+ at end deffn"),
+
+  pair_type ("if",
+    "-*- texinfo -*-\n\
+ at deffn Keyword if (@var{cond}) @dots{} endif\n\
+ at deffnx Keyword if (@var{cond}) @dots{} else @dots{} endif\n\
+ at deffnx Keyword if (@var{cond}) @dots{} elseif (@var{cond}) @dots{} endif\n\
+ at deffnx Keyword if (@var{cond}) @dots{} elseif (@var{cond}) @dots{} else @dots{} endif\n\
+Begin an if block.\n\
+ at example\n\
+ at group\n\
+x = 1;\n\
+if (x == 1)\n\
+  disp (\"one\");\n\
+elseif (x == 2)\n\
+  disp (\"two\");\n\
+else\n\
+  disp (\"not one or two\");\n\
+endif\n\
+ at end group\n\
+ at end example\n\
+ at seealso{switch}\n\
+ at end deffn"),
+
+  pair_type ("otherwise",
+    "-*- texinfo -*-\n\
+ at deffn Keyword otherwise\n\
+The default statement in a switch block (similar to else in an if block).\n\
+ at seealso{switch}\n\
+ at end deffn"),
+
+  pair_type ("persistent",
+    "-*- texinfo -*-\n\
+ at deffn Keyword persistent @var{var}\n\
+Declare variables as persistent.  A variable that has been declared\n\
+persistent within a function will retain its contents in memory between\n\
+subsequent calls to the same function.  The difference between persistent\n\
+variables and global variables is that persistent variables are local in \n\
+scope to a particular function and are not visible elsewhere.\n\
+ at seealso{global}\n\
+ at end deffn"),
+
+  pair_type ("replot",
+    "-*- texinfo -*-\n\
+ at deffn Keyword replot\n\
+Replot a graphic.\n\
+ at seealso{plot}\n\
+ at end deffn"),
+
+  pair_type ("return",
+    "-*- texinfo -*-\n\
+ at deffn Keyword return\n\
+Return from a function.\n\
+ at seealso{function}\n\
+ at end deffn"),
+
+  pair_type ("static",
+    "-*- texinfo -*-\n\
+ at deffn Keyword static\n\
+This function has been deprecated in favor of persistent.\n\
+ at seealso{persistent}\n\
+ at end deffn"),
+
+  pair_type ("switch",
+    "-*- texinfo -*-\n\
+ at deffn Keyword switch @var{statement}\n\
+Begin a switch block.\n\
+ at example\n\
+ at group\n\
+yesno = \"yes\"\n\
+\n\
+switch yesno\n\
+  case @{\"Yes\" \"yes\" \"YES\" \"y\" \"Y\"@}\n\
+    value = 1;\n\
+  case @{\"No\" \"no\" \"NO\" \"n\" \"N\"@}\n\
+    value = 0;\n\
+  otherwise\n\
+    error (\"invalid value\");\n\
+endswitch\n\
+ at end group\n\
+ at end example\n\
+ at seealso{if, case, otherwise}\n\
+ at end deffn"),
+
+  pair_type ("try",
+    "-*- texinfo -*-\n\
+ at deffn Keyword try\n\
+Begin a try-catch block.\n\
+\n\
+If an error occurs within a try block, then the catch code will be run and\n\
+execution will proceed after the catch block (though it is often\n\
+recommended to use the lasterr function to re-throw the error after cleanup\n\
+is completed).\n\
+ at seealso{catch,unwind_protect}\n\
+ at end deffn"), 
+
+  pair_type ("until",
+    "-*- texinfo -*-\n\
+ at deffn Keyword until\n\
+End a do-until loop.\n\
+ at seealso{do}\n\
+ at end deffn"),
+
+  pair_type ("unwind_protect",
+    "-*- texinfo -*-\n\
+ at deffn Keyword unwind_protect\n\
+Begin an unwind_protect block.\n\
+\n\
+If an error occurs within the first part of an unwind_protect block\n\
+the commands within the unwind_protect_cleanup block are executed before\n\
+the error is thrown.  If an error is not thrown, then the\n\
+unwind_protect_cleanup block is still executed (in other words, the\n\
+unwind_protect_cleanup will be run with or without an error in the\n\
+unwind_protect block).\n\
+ at seealso{unwind_protect_cleanup,try}\n\
+ at end deffn"), 
+
+  pair_type ("unwind_protect_cleanup",
+    "-*- texinfo -*-\n\
+ at deffn Keyword unwind_protect_cleanup\n\
+Begin the cleanup section of an unwind_protect block.\n\
+ at seealso{unwind_protect}\n\
+ at end deffn"), 
+
+  pair_type ("varargin",
+    "-*- texinfo -*-\n\
+ at deffn Keyword varargin\n\
+Pass an arbitrary number of arguments into a function.\n\
+ at seealso{varargout, nargin, nargout}\n\
+ at end deffn"),
+
+  pair_type ("varargout",
+    "-*- texinfo -*-\n\
+ at deffn Keyword varargout\n\
+Pass an arbitrary number of arguments out of a function.\n\
+ at seealso{varargin, nargin, nargout}\n\
+ at end deffn"),
+
+  pair_type ("while",
+    "-*- texinfo -*-\n\
+ at deffn Keyword while\n\
+Begin a while loop.\n\
+ at seealso{do}\n\
+ at end deffn"),
+};
+
+// Return a copy of the operator or keyword names.
+static string_vector
+names (const map_type& lst)
+{
+  string_vector retval (lst.size ());
+  int j = 0;
+  for (map_iter iter = lst.begin (); iter != lst.end (); iter ++)
+    retval [j++] = iter->first;
+  return retval;
+}
+
+const static map_type operators_map (operators, operators + size (operators));
+const static map_type keywords_map (keywords, keywords + size (keywords));
+const static string_vector keyword_names = names (keywords_map);
+
+// FIXME -- It's not likely that this does the right thing now.
+
+string_vector
+make_name_list (void)
+{
+  const int key_len = keyword_names.length ();
+
+  const string_vector bif = symbol_table::built_in_function_names ();
+  const int bif_len = bif.length ();
+
+  // FIXME -- is this really necessary here?
+  const string_vector glb = symbol_table::global_variable_names ();
+  const int glb_len = glb.length ();
+
+  // FIXME -- is this really necessary here?
+  const string_vector top = symbol_table::top_level_variable_names ();
+  const int top_len = top.length ();
+
+  string_vector lcl;
+  if (! symbol_table::at_top_level ())
+    lcl = symbol_table::variable_names ();
+  const int lcl_len = lcl.length ();
+
+  const string_vector ffl = load_path::fcn_names ();
+  const int ffl_len = ffl.length ();
+
+  const string_vector afl = autoloaded_functions ();
+  const int afl_len = afl.length ();
+
+  const int total_len = key_len + bif_len + glb_len + top_len + lcl_len
+    + ffl_len + afl_len;
+
+  string_vector list (total_len);
+
+  // Put all the symbols in one big list.
+
+  int j = 0;
+  int i = 0;
+  for (i = 0; i < key_len; i++)
+    list[j++] = keyword_names[i];
+
+  for (i = 0; i < bif_len; i++)
+    list[j++] = bif[i];
+
+  for (i = 0; i < glb_len; i++)
+    list[j++] = glb[i];
+
+  for (i = 0; i < top_len; i++)
+    list[j++] = top[i];
+
+  for (i = 0; i < lcl_len; i++)
+    list[j++] = lcl[i];
+
+  for (i = 0; i < ffl_len; i++)
+    list[j++] = ffl[i];
+
+  for (i = 0; i < afl_len; i++)
+    list[j++] = afl[i];
+
+  return list;
+}
+
+static bool
+looks_like_html (const std::string& msg)
+{
+  const size_t p1 = msg.find ('\n');
+  std::string t = msg.substr (0, p1);
+  const size_t p2 = t.find ("<html"); // FIXME: this comparison should be case-insensitive
+  
+   return (p2 != std::string::npos);
+}
+
+static bool
+looks_like_texinfo (const std::string& msg, size_t& p1)
+{
+  p1 = msg.find ('\n');
+
+  std::string t = msg.substr (0, p1);
+
+  if (p1 == std::string::npos)
+    p1 = 0;
+
+  size_t p2 = t.find ("-*- texinfo -*-");
+
+  return (p2 != std::string::npos);
+}
+
+static bool
+raw_help_from_symbol_table (const std::string& nm, std::string& h, 
+			    std::string& w, bool& symbol_found)
+{
+  bool retval = false;
+
+  octave_value val = symbol_table::find_function (nm);
+
+  if (val.is_defined ())
+    {
+      octave_function *fcn = val.function_value ();
+
+      if (fcn)
+	{
+	  symbol_found = true;
+
+	  h = fcn->doc_string ();
+
+          retval = true;
+
+	  w = fcn->fcn_file_name ();
+
+	  if (w.empty ())
+            w = fcn->is_user_function ()
+              ? "command-line function" : "built-in function";
+	}
+    }
+
+  return retval;
+}
+
+static bool
+raw_help_from_file (const std::string& nm, std::string& h, 
+		    std::string& file, bool& symbol_found)
+{
+  bool retval = false;
+
+  // FIXME -- this is a bit of a kluge...
+  unwind_protect_bool (reading_script_file);
+  reading_script_file = true;
+
+  h = get_help_from_file (nm, symbol_found, file);
+
+  unwind_protect::run ();
+
+  if (h.length () > 0)
+    retval = true;
+
+  return retval;
+}
+
+static bool
+raw_help_from_map (const std::string& nm, std::string& h, 
+		   const map_type& map, bool& symbol_found)
+{
+  map_iter idx = map.find (nm);
+  symbol_found = (idx != map.end ());
+  h = (symbol_found) ? idx->second : "";
+  return symbol_found;
+}
+
+std::string
+raw_help (const std::string& nm, bool& symbol_found)
+{
+  std::string h;
+  std::string w;
+  std::string f;
+
+  (raw_help_from_symbol_table (nm, h, w, symbol_found)
+   || raw_help_from_file (nm, h, f, symbol_found)
+   || raw_help_from_map (nm, h, operators_map, symbol_found)
+   || raw_help_from_map (nm, h, keywords_map, symbol_found));
+
+  return h;
+}
+
+static void
+do_get_help_text (const std::string name, std::string& text,
+		  std::string& format)
+{
+  bool symbol_found = false;
+  text = raw_help (name, symbol_found);
+  
+  format = "Not found";
+  if (symbol_found)
+    {
+      size_t idx = -1;
+      if (text.empty ())
+        {
+          format = "Not documented";
+        }
+      else if (looks_like_texinfo (text, idx))
+        {
+          format = "texinfo";
+          text.erase (0, idx);
+        }
+      else if (looks_like_html (text))
+        {
+          format = "html";
+        }
+      else
+        {
+          format = "plain text";
+        }
+    }
+}
+
+DEFUN (get_help_text, args, , "-*- texinfo -*-\n\
+ at deftypefn {Loadable Function} {[@var{text}, @var{format}] =} get_help_text (@var{name})\n\
+Returns the help text of a given function.\n\
+\n\
+This function returns the raw help text @var{text} and an indication of\n\
+its format for the function @var{name}.  The format indication @var{format}\n\
+is a string that can be either @t{\"texinfo\"}, @t{\"html\"}, or\n\
+ at t{\"plain text\"}.\n\
+\n\
+To convert the help text to other formats, use the @code{makeinfo} function.\n\
+\n\
+ at seealso{makeinfo}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      const std::string name = args (0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string text;
+	  std::string format;
+
+	  do_get_help_text (name, text, format);
+  
+	  retval(1) = format;
+	  retval(0) = text;
+	}
+      else
+	error ("get_help_text: invalid input");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Return a cell array of strings containing the names of all
+// operators.
+
+DEFUN (__operators__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Function File} __operators__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  return octave_value (Cell (names (operators_map)));
+}
+
+// Return a cell array of strings containing the names of all
+// keywords.
+
+DEFUN (__keywords__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Function File} __keywords__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  return octave_value (Cell (names (keywords_map)));
+}
+
+// Return a cell array of strings containing the names of all builtin
+// functions.
+
+DEFUN (__builtins__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Function File} __builtins__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  const string_vector bif = symbol_table::built_in_function_names ();
+
+  return octave_value (Cell (bif));
+}
+
+static std::string
+do_which (const std::string& name, std::string& type)
+{
+  std::string file;
+
+  type = std::string ();
+
+  octave_value val = symbol_table::find_function (name);
+
+  if (name.find_first_of ('.') == std::string::npos)
+    {
+      if (val.is_defined ())
+        {
+          octave_function *fcn = val.function_value ();
+
+          if (fcn)
+            {
+              file = fcn->fcn_file_name ();
+
+              if (file.empty ())
+                {
+                  if (fcn->is_user_function ())
+                    type = "command-line function";
+                  else
+                    type = "built-in function";
+                }
+              else
+                type = val.is_user_script ()
+                  ? std::string ("script") : std::string ("function");
+            }
+        }
+      else
+        {
+          // We might find a file that contains only a doc string.
+
+          file = load_path::find_fcn_file (name);
+        }
+    }
+  else
+    {
+      // File query.
+
+      // For compatibility: "file." queries "file".
+      if (name.size () > 1 && name[name.size () - 1] == '.')
+        file = load_path::find_file (name.substr (0, name.size () - 1));
+      else
+        file = load_path::find_file (name);
+    }
+
+
+  return file;
+}
+
+std::string
+do_which (const std::string& name)
+{
+  std::string retval;
+
+  std::string type;
+
+  retval = do_which (name, type);
+
+  return retval;
+}
+
+DEFUN (__which__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __which__ (@var{name}, @dots{})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  string_vector argv = args.make_argv ("which");
+
+  if (! error_state)
+    {
+      int argc = argv.length ();
+
+      if (argc > 1)
+	{
+	  Octave_map m (dim_vector (1, argc-1));
+
+	  Cell names (1, argc-1);
+	  Cell files (1, argc-1);
+	  Cell types (1, argc-1);
+
+	  for (int i = 1; i < argc; i++)
+	    {
+	      std::string name = argv[i];
+
+	      std::string type;
+
+	      std::string file = do_which (name, type);
+
+	      names(i-1) = name;
+	      files(i-1) = file;
+	      types(i-1) = type;
+	    }
+
+	  m.assign ("name", names);
+	  m.assign ("file", files);
+	  m.assign ("type", types);
+
+	  retval = m;
+	}
+      else
+	print_usage ();
+    }
+
+  return retval;
+}
+
+// FIXME -- Are we sure this function always does the right thing?
+inline bool
+file_is_in_dir (const std::string filename, const std::string dir)
+{
+  if (filename.find (dir) == 0)
+    {
+      const int dir_len = dir.size ();
+      const int filename_len = filename.size ();
+      const int max_allowed_seps = file_ops::is_dir_sep (dir [dir_len-1]) ? 0 : 1;
+      
+      int num_seps = 0;
+      for (int i = dir_len; i < filename_len; i++)
+        if (file_ops::is_dir_sep (filename [i]))
+          num_seps ++;
+      
+      return (num_seps <= max_allowed_seps);
+    }
+  else
+    return false;
+}
+
+// Return a cell array of strings containing the names of all
+// functions available in DIRECTORY.  If no directory is given, search
+// the current path.
+
+DEFUN (__list_functions__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Function File} {@var{retval} =} __list_functions__ ()\n\
+ at deftypefnx{Function File} {@var{retval} =} __list_functions__ (@var{directory})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  // Get list of functions
+  string_vector ffl = load_path::fcn_names ();
+  string_vector afl = autoloaded_functions ();
+  
+  if (args.length () == 0)
+    retval = Cell (ffl.append (afl));
+  else
+    {
+      std::string dir = args (0).string_value ();
+
+      if (! error_state)
+	{
+	  string_vector fl = load_path::files (dir, true);
+
+	  if (! error_state)
+	    {
+	      // Return a sorted list with unique entries (in case of
+	      // .m and .oct versions of the same function in a given
+	      // directory, for example).
+	      fl.sort (true);
+
+	      retval = Cell (fl);
+	    }
+	}
+      else
+        error ("__list_functions__: input must be a string");
+    }  
+
+  return retval;
+}
+
+DEFUN (doc_cache_file, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} doc_cache_file ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} doc_cache_file (@var{new_val})\n\
+Query or set the internal variable that specifies the name of the\n\
+Octave documentation cache file.  A cache file significantly improves\n\
+the performance of the @code{lookfor} command.  The default value is \n\
+ at file{@var{octave-home}/share/octave/@var{version}/etc/doc-cache},\n\
+in which @var{octave-home} is the root directory of the Octave installation,\n\
+and @var{version} is the Octave version number.\n\
+The default value may be overridden by the environment variable\n\
+ at w{@code{OCTAVE_DOC_CACHE_FILE}}, or the command line argument\n\
+ at samp{--doc-cache-file NAME}.\n\
+ at seealso{lookfor, info_program, doc, help, makeinfo_program}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (doc_cache_file);
+}
+
+DEFUN (info_file, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} info_file ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} info_file (@var{new_val})\n\
+Query or set the internal variable that specifies the name of the\n\
+Octave info file.  The default value is\n\
+ at file{@var{octave-home}/info/octave.info}, in\n\
+which @var{octave-home} is the root directory of the Octave installation.\n\
+The default value may be overridden by the environment variable\n\
+ at w{@code{OCTAVE_INFO_FILE}}, or the command line argument\n\
+ at samp{--info-file NAME}.\n\
+ at seealso{info_program, doc, help, makeinfo_program}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (info_file);
+}
+
+DEFUN (info_program, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} info_program ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} info_program (@var{new_val})\n\
+Query or set the internal variable that specifies the name of the\n\
+info program to run.  The default value is\n\
+ at file{@var{octave-home}/libexec/octave/@var{version}/exec/@var{arch}/info}\n\
+in which @var{octave-home} is the root directory of the Octave installation,\n\
+ at var{version} is the Octave version number, and @var{arch}\n\
+is the system type (for example, @code{i686-pc-linux-gnu}).  The\n\
+default value may be overridden by the environment variable\n\
+ at w{@code{OCTAVE_INFO_PROGRAM}}, or the command line argument\n\
+ at samp{--info-program NAME}.\n\
+ at seealso{info_file, doc, help, makeinfo_program}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (info_program);
+}
+
+DEFUN (makeinfo_program, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} makeinfo_program ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} makeinfo_program (@var{new_val})\n\
+Query or set the internal variable that specifies the name of the\n\
+program that Octave runs to format help text containing\n\
+Texinfo markup commands.  The default value is @code{makeinfo}.\n\
+ at seealso{info_file, info_program, doc, help}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (makeinfo_program);
+}
+
+DEFUN (suppress_verbose_help_message, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} suppress_verbose_help_message ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} suppress_verbose_help_message (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave\n\
+will add additional help information to the end of the output from\n\
+the @code{help} command and usage messages for built-in commands.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (suppress_verbose_help_message);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/help.h b/src/help.h
new file mode 100644
index 0000000..81bab35
--- /dev/null
+++ b/src/help.h
@@ -0,0 +1,56 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_help_h)
+#define octave_help_h 1
+
+#include <iosfwd>
+#include <string>
+
+class string_vector;
+
+extern string_vector make_name_list (void);
+
+extern OCTINTERP_API std::string raw_help (const std::string&, bool&);
+
+// Name of the doc cache file specified on the command line.
+// (--doc-cache-file file)
+extern std::string Vdoc_cache_file;
+
+// Name of the info file specified on command line.
+// (--info-file file)
+extern std::string Vinfo_file;
+
+// Name of the info reader we'd like to use.
+// (--info-program program)
+extern std::string Vinfo_program;
+
+extern std::string do_which (const std::string& name);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/input.cc b/src/input.cc
new file mode 100644
index 0000000..db39548
--- /dev/null
+++ b/src/input.cc
@@ -0,0 +1,1473 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Get command input interactively or from files.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "file-ops.h"
+#include "quit.h"
+#include "str-vec.h"
+
+#include "debug.h"
+#include "defun.h"
+#include "dirfns.h"
+#include "error.h"
+#include "gripes.h"
+#include "help.h"
+#include "input.h"
+#include "load-path.h"
+#include "oct-map.h"
+#include "oct-hist.h"
+#include "toplev.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "parse.h"
+#include "pathlen.h"
+#include "pt.h"
+#include "pt-const.h"
+#include "pt-eval.h"
+#include "pt-stmt.h"
+#include "sighandlers.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// Primary prompt string.
+static std::string VPS1 = "\\s:\\#> ";
+
+// Secondary prompt string.
+static std::string VPS2 = "> ";
+
+// String printed before echoed input (enabled by --echo-input).
+std::string VPS4 = "+ ";
+
+// Echo commands as they are executed?
+//
+//   1  ==>  echo commands read from script files
+//   2  ==>  echo commands from functions
+//   4  ==>  echo commands read from command line
+//
+// more than one state can be active at once.
+int Vecho_executing_commands = ECHO_OFF;
+
+// The time we last printed a prompt.
+octave_time Vlast_prompt_time = 0.0;
+
+// Character to append after successful command-line completion attempts.
+static char Vcompletion_append_char = ' ';
+
+// Global pointer for eval().
+std::string current_eval_string;
+
+// TRUE means get input from current_eval_string.
+bool get_input_from_eval_string = false;
+
+// TRUE means we haven't been asked for the input from
+// current_eval_string yet.
+bool input_from_eval_string_pending = false;
+
+// TRUE means that input is coming from a file that was named on
+// the command line.
+bool input_from_command_line_file = false;
+
+// TRUE means we're parsing a function file.
+bool reading_fcn_file = false;
+
+// Simple name of function file we are reading.
+std::string curr_fcn_file_name;
+
+// Full name of file we are reading.
+std::string curr_fcn_file_full_name;
+
+// TRUE means we're parsing a script file.
+bool reading_script_file = false;
+
+// If we are reading from an M-file, this is it.
+FILE *ff_instream = 0;
+
+// TRUE means this is an interactive shell.
+bool interactive = false;
+
+// TRUE means the user forced this shell to be interactive (-i).
+bool forced_interactive = false;
+
+// Should we issue a prompt?
+int promptflag = 1;
+
+// The current line of input, from wherever.
+std::string current_input_line;
+
+// TRUE after a call to completion_matches.
+bool octave_completion_matches_called = false;
+
+// TRUE if the plotting system has requested a call to drawnow at
+// the next user prompt.
+bool Vdrawnow_requested = false;
+
+// TRUE if we are in debugging mode.
+bool Vdebugging = false;
+
+// If we are in debugging mode, this is the last command entered, so
+// that we can repeat the previous command if the user just types RET.
+static std::string last_debugging_command;
+
+// TRUE if we are running in the Emacs GUD mode.
+static bool Vgud_mode = false;
+
+// The filemarker used to separate filenames from subfunction names
+char Vfilemarker = '>';
+
+static void
+do_input_echo (const std::string& input_string)
+{
+  int do_echo = reading_script_file ?
+    (Vecho_executing_commands & ECHO_SCRIPTS)
+      : (Vecho_executing_commands & ECHO_CMD_LINE) && ! forced_interactive;
+
+  if (do_echo)
+    {
+      if (forced_interactive)
+	{
+	  if (promptflag > 0)
+	    octave_stdout << command_editor::decode_prompt_string (VPS1);
+	  else
+	    octave_stdout << command_editor::decode_prompt_string (VPS2);
+	}
+      else
+	octave_stdout << command_editor::decode_prompt_string (VPS4);
+
+      if (! input_string.empty ())
+	{
+	  octave_stdout << input_string;
+
+	  if (input_string[input_string.length () - 1] != '\n')
+	    octave_stdout << "\n";
+	}
+    }
+}
+
+std::string
+gnu_readline (const std::string& s, bool force_readline)
+{
+  OCTAVE_QUIT;
+
+  std::string retval;
+
+  if (line_editing || force_readline)
+    {
+      bool eof;
+
+      retval = command_editor::readline (s, eof);
+
+      if (! eof && retval.empty ())
+	retval = "\n";
+    }
+  else
+    {
+      if (! s.empty () && (interactive || forced_interactive))
+	{
+	  FILE *stream = command_editor::get_output_stream ();
+
+	  fputs (s.c_str (), stream);
+	  fflush (stream);
+	}
+
+      FILE *curr_stream = command_editor::get_input_stream ();
+
+      if (reading_fcn_file || reading_script_file)
+	curr_stream = ff_instream;
+
+      retval = octave_fgets (curr_stream);
+    }
+
+  return retval;
+}
+
+static inline std::string
+interactive_input (const std::string& s, bool force_readline = false)
+{
+  Vlast_prompt_time.stamp ();
+
+  if (Vdrawnow_requested && (interactive || forced_interactive))
+    {
+      feval ("drawnow");
+
+      flush_octave_stdout ();
+
+      // We set Vdrawnow_requested to false even if there is an error
+      // in drawnow so that the error doesn't reappear at every prompt.
+
+      Vdrawnow_requested = false;
+
+      if (error_state)
+	return "\n";
+    }
+
+  return gnu_readline (s, force_readline);
+}
+
+static std::string
+octave_gets (void)
+{
+  OCTAVE_QUIT;
+
+  std::string retval;
+
+  bool history_skip_auto_repeated_debugging_command = false;
+
+  if ((interactive || forced_interactive)
+      && (! (reading_fcn_file
+	     || reading_script_file
+	     || input_from_startup_file
+	     || input_from_command_line_file)))
+    {
+      std::string ps = (promptflag > 0) ? VPS1 : VPS2;
+
+      std::string prompt = command_editor::decode_prompt_string (ps);
+
+      pipe_handler_error_count = 0;
+
+      flush_octave_stdout ();
+
+      octave_diary << prompt;
+
+      retval = interactive_input (prompt);
+
+      // There is no need to update the load_path cache if there is no
+      // user input.
+      if (! retval.empty ()
+	  && retval.find_first_not_of (" \t\n\r") != std::string::npos)
+	{
+	  load_path::update ();
+
+	  if (Vdebugging)
+	    last_debugging_command = retval;
+	  else
+	    last_debugging_command = std::string ();
+	}
+      else if (Vdebugging)
+	{
+	  retval = last_debugging_command;
+	  history_skip_auto_repeated_debugging_command = true;
+	}
+    }
+  else
+    retval = gnu_readline ("");
+
+  current_input_line = retval;
+
+  if (! current_input_line.empty ())
+    {
+      if (! (input_from_startup_file || input_from_command_line_file
+	     || history_skip_auto_repeated_debugging_command))
+	command_history::add (current_input_line);
+
+      if (! (reading_fcn_file || reading_script_file))
+	{
+	  octave_diary << current_input_line;
+
+	  if (current_input_line[current_input_line.length () - 1] != '\n')
+	    octave_diary << "\n";
+	}
+
+      do_input_echo (current_input_line);
+    }
+  else if (! (reading_fcn_file || reading_script_file))
+    octave_diary << "\n";
+  
+  return retval;
+}
+
+// Read a line from the input stream.
+
+static std::string
+get_user_input (void)
+{
+  OCTAVE_QUIT;
+
+  std::string retval;
+
+  if (get_input_from_eval_string)
+    {
+      if (input_from_eval_string_pending)
+	{
+	  input_from_eval_string_pending = false;
+
+	  retval = current_eval_string;
+
+	  size_t len = retval.length ();
+
+	  if (len > 0 && retval[len-1] != '\n')
+	    retval.append ("\n");
+	}
+    }
+  else
+    retval = octave_gets ();
+
+  current_input_line = retval;
+
+  return retval;
+}
+
+int
+octave_read (char *buf, unsigned max_size)
+{
+  // FIXME -- is this a safe way to buffer the input?
+
+  static const char * const eol = "\n";
+  static std::string input_buf;
+  static const char *pos = 0;
+  static size_t chars_left = 0;
+
+  int status = 0;
+  if (chars_left == 0)
+    {
+      pos = 0;
+
+      input_buf = get_user_input ();
+
+      chars_left = input_buf.length ();
+
+      pos = input_buf.c_str ();
+    }
+
+  if (chars_left > 0)
+    {
+      size_t len = max_size > chars_left ? chars_left : max_size;
+      assert (len > 0);
+
+      memcpy (buf, pos, len);
+
+      chars_left -= len;
+      pos += len;
+
+      // Make sure input ends with a new line character.
+      if (chars_left == 0 && buf[len-1] != '\n')
+	{
+	  if (len < max_size) 
+	    {
+	      // There is enough room to plug the newline character in
+	      // the buffer.
+	      buf[len++] = '\n';
+	    }
+	  else
+	    {
+	      // There isn't enough room to plug the newline character
+	      // in the buffer so make sure it is returned on the next
+	      // octave_read call.
+	      pos = eol;
+	      chars_left = 1;
+	    }
+	}
+
+      status = len;
+
+    }
+  else if (chars_left == 0)
+    {
+      status = 0;
+    }
+  else    
+    status = -1;
+
+  return status;
+}
+
+// Fix things up so that input can come from file `name', printing a
+// warning if the file doesn't exist.
+
+FILE *
+get_input_from_file (const std::string& name, int warn)
+{
+  FILE *instream = 0;
+
+  if (name.length () > 0)
+    instream = fopen (name.c_str (), "rb");
+
+  if (! instream && warn)
+    warning ("%s: no such file or directory", name.c_str ());
+
+  if (reading_fcn_file || reading_script_file)
+    ff_instream = instream;
+  else
+    command_editor::set_input_stream (instream);
+
+  return instream;
+}
+
+// Fix things up so that input can come from the standard input.  This
+// may need to become much more complicated, which is why it's in a
+// separate function.
+
+FILE *
+get_input_from_stdin (void)
+{
+  command_editor::set_input_stream (stdin);
+  return command_editor::get_input_stream ();
+}
+
+// FIXME -- make this generate file names when appropriate.
+
+static string_vector
+generate_possible_completions (const std::string& text, std::string& prefix,
+			       std::string& hint)
+{
+  string_vector names;
+
+  prefix = "";
+
+  if (looks_like_struct (text))
+    names = generate_struct_completions (text, prefix, hint);
+  else
+    names = make_name_list ();
+
+  // Sort and remove duplicates.
+
+  names.sort (true);
+
+  return names;
+}
+
+static std::string
+generate_completion (const std::string& text, int state)
+{
+  std::string retval;
+
+  static std::string prefix;
+  static std::string hint;
+
+  static size_t hint_len = 0;
+
+  static int list_index = 0;
+  static int name_list_len = 0;
+  static int name_list_total_len = 0;
+  static string_vector name_list;
+  static string_vector file_name_list;
+
+  static int matches = 0;
+
+  if (state == 0)
+    {
+      list_index = 0;
+
+      prefix = "";
+
+      hint = text;
+
+      name_list = generate_possible_completions (text, prefix, hint);
+
+      name_list_len = name_list.length ();
+
+      file_name_list = command_editor::generate_filename_completions (text);
+
+      name_list.append (file_name_list);
+
+      name_list_total_len = name_list.length ();
+
+      hint_len = hint.length ();
+
+      matches = 0;
+
+      for (int i = 0; i < name_list_len; i++)
+	if (hint == name_list[i].substr (0, hint_len))
+	  matches++;
+    }
+
+  if (name_list_total_len > 0 && matches > 0)
+    {
+      while (list_index < name_list_total_len)
+	{
+	  std::string name = name_list[list_index];
+
+	  list_index++;
+
+	  if (hint == name.substr (0, hint_len))
+	    {
+	      if (list_index <= name_list_len && ! prefix.empty ())
+		retval = prefix + "." + name;
+	      else
+		retval = name;
+
+	      // FIXME -- looks_like_struct is broken for now,
+	      // so it always returns false.
+
+	      if (matches == 1 && looks_like_struct (retval))
+ 		{
+ 		  // Don't append anything, since we don't know
+ 		  // whether it should be '(' or '.'.
+
+ 		  command_editor::set_completion_append_character ('\0');
+ 		}
+ 	      else
+ 		command_editor::set_completion_append_character
+ 		  (Vcompletion_append_char);
+
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static std::string
+quoting_filename (const std::string &text, int, char quote)
+{
+  if (quote)
+    return text;
+  else
+    return (std::string ("'") + text);
+}
+
+void
+initialize_command_input (void)
+{
+  // If we are using readline, this allows conditional parsing of the
+  // .inputrc file.
+
+  command_editor::set_name ("Octave");
+
+  // FIXME -- this needs to include a comma too, but that
+  // causes trouble for the new struct element completion code.
+
+  static const char *s = "\t\n !\"\'*+-/:;<=>(){}[\\]^`~";
+
+  command_editor::set_basic_word_break_characters (s);
+
+  command_editor::set_completer_word_break_characters (s);
+
+  command_editor::set_basic_quote_characters ("\"");
+
+  command_editor::set_filename_quote_characters (" \t\n\\\"'@<>=;|&()#$`?*[!:{");
+  command_editor::set_completer_quote_characters ("'\"");
+
+  command_editor::set_completion_function (generate_completion);
+
+  command_editor::set_quoting_function (quoting_filename);
+}
+
+static void
+get_debug_input (const std::string& prompt)
+{
+  octave_user_code *caller = octave_call_stack::caller_user_code ();
+  std::string nm;
+
+  int curr_debug_line = tree_evaluator::debug_line ();
+
+  bool have_file = false;
+
+  if (caller)
+    {
+      nm = caller->fcn_file_name ();
+
+      if (nm.empty ())
+	nm = caller->name ();
+      else
+	have_file = true;
+    }
+  else
+    curr_debug_line = -1;
+
+  std::ostringstream buf;
+
+  if (! nm.empty ())
+    {
+      if (Vgud_mode)
+	{
+	  static char ctrl_z = 'Z' & 0x1f;
+
+	  buf << ctrl_z << ctrl_z << nm << ":" << curr_debug_line;
+	}
+      else
+	{
+	  // FIXME -- we should come up with a clean way to detect
+	  // that we are stopped on the no-op command that marks the
+	  // end of a function or script.
+
+	  buf << "stopped in " << nm;
+
+	  if (curr_debug_line > 0)
+	    buf << " at line " << curr_debug_line;
+
+	  if (have_file)
+	    {
+	      std::string line_buf
+		= get_file_line (nm, curr_debug_line);
+
+	      if (! line_buf.empty ())
+		buf << "\n" << curr_debug_line << ": " << line_buf;
+	    }
+	}
+    }
+
+  std::string msg = buf.str ();
+
+  if (! msg.empty ())
+    {
+      if (! Vgud_mode)
+	std::cerr << "keyboard: ";
+
+      std::cerr << msg << std::endl;
+    }
+
+  unwind_protect::begin_frame ("get_debug_input");
+
+  unwind_protect_str (VPS1);
+  VPS1 = prompt;
+
+  while (Vdebugging)
+    {
+      reset_error_handler ();
+
+      reset_parser ();
+
+      // Save current value of global_command.
+      unwind_protect_ptr (global_command);
+
+      // Do this with an unwind-protect cleanup function so that the
+      // forced variables will be unmarked in the event of an interrupt.
+      symbol_table::scope_id scope = symbol_table::top_scope ();
+      unwind_protect::add (symbol_table::unmark_forced_variables, &scope);
+
+      // This is the same as yyparse in parse.y.
+      int retval = octave_parse ();
+
+      if (retval == 0 && global_command)
+	{
+	  global_command->accept (*current_evaluator);
+
+	  // FIXME -- To avoid a memory leak, global_command should be
+	  // deleted, I think.  But doing that here causes trouble if
+	  // an error occurs while executing a debugging command
+	  // (dbstep, for example). It's not clear to me why that
+	  // happens.
+	  //
+	  // delete global_command;
+	  //
+	  // global_command = 0;
+
+	  if (octave_completion_matches_called)
+	    octave_completion_matches_called = false;	    
+	}
+
+      // Unmark forced variables.
+      unwind_protect::run ();
+
+      // Restore previous value of global_command.
+      unwind_protect::run ();
+
+      OCTAVE_QUIT;
+    }
+
+  unwind_protect::run_frame ("get_debug_input");
+}
+
+// If the user simply hits return, this will produce an empty matrix.
+
+static octave_value_list
+get_user_input (const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  int read_as_string = 0;
+
+  if (nargin == 2)
+    read_as_string++;
+
+  std::string prompt = args(0).string_value ();
+
+  if (error_state)
+    {
+      error ("input: unrecognized argument");
+      return retval;
+    }
+
+  flush_octave_stdout ();
+
+  octave_diary << prompt;
+
+  std::string input_buf = interactive_input (prompt.c_str (), true);
+
+  if (! (error_state || input_buf.empty ()))
+    {
+      if (! input_from_startup_file)
+	command_history::add (input_buf);
+
+      size_t len = input_buf.length ();
+
+      octave_diary << input_buf;
+
+      if (input_buf[len - 1] != '\n')
+	octave_diary << "\n";
+
+      if (len < 1)
+	return read_as_string ? octave_value ("") : octave_value (Matrix ());
+
+      if (read_as_string)
+	{
+	  // FIXME -- fix gnu_readline and octave_gets instead!
+	  if (input_buf.length () == 1 && input_buf[0] == '\n')
+	    retval(0) = "";
+	  else
+	    retval(0) = input_buf;
+	}
+      else
+	{
+	  int parse_status = 0;
+
+	  retval = eval_string (input_buf, true, parse_status, nargout);
+
+	  if (! Vdebugging && retval.length () == 0)
+	    retval(0) = Matrix ();
+	}
+    }
+  else
+    error ("input: reading user-input failed!");
+
+  return retval;
+}
+
+DEFUN (input, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} input (@var{prompt})\n\
+ at deftypefnx {Built-in Function} {} input (@var{prompt}, \"s\")\n\
+Print a prompt and wait for user input.  For example,\n\
+\n\
+ at example\n\
+input (\"Pick a number, any number! \")\n\
+ at end example\n\
+\n\
+ at noindent\n\
+prints the prompt\n\
+\n\
+ at example\n\
+Pick a number, any number!\n\
+ at end example\n\
+\n\
+ at noindent\n\
+and waits for the user to enter a value.  The string entered by the user\n\
+is evaluated as an expression, so it may be a literal constant, a\n\
+variable name, or any other valid expression.\n\
+\n\
+Currently, @code{input} only returns one value, regardless of the number\n\
+of values produced by the evaluation of the expression.\n\
+\n\
+If you are only interested in getting a literal string value, you can\n\
+call @code{input} with the character string @code{\"s\"} as the second\n\
+argument.  This tells Octave to return the string entered by the user\n\
+directly, without evaluating it first.\n\
+\n\
+Because there may be output waiting to be displayed by the pager, it is\n\
+a good idea to always call @code{fflush (stdout)} before calling\n\
+ at code{input}.  This will ensure that all pending output is written to\n\
+the screen before your prompt.  @xref{Input and Output}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    retval = get_user_input (args, nargout);
+  else
+    print_usage ();
+
+  return retval;
+}
+
+bool
+octave_yes_or_no (const std::string& prompt)
+{
+  std::string prompt_string = prompt + "(yes or no) ";
+
+  while (1)
+    {
+      std::string input_buf = interactive_input (prompt_string, true);
+
+      if (input_buf == "yes")
+	return true;
+      else if (input_buf == "no")
+	return false;
+      else
+	message (0, "Please answer yes or no.");
+    }
+}
+
+DEFUN (yes_or_no, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} yes_or_no (@var{prompt})\n\
+Ask the user a yes-or-no question.  Return 1 if the answer is yes.\n\
+Takes one argument, which is the string to display to ask the\n\
+question.  It should end in a space; @samp{yes-or-no-p} adds\n\
+ at samp{(yes or no) } to it.  The user must confirm the answer with\n\
+RET and can edit it until it has been confirmed.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0 || nargin == 1)
+    {
+      std::string prompt;
+
+      if (nargin == 1)
+	{
+	  prompt = args(0).string_value ();
+
+	  if (error_state)
+	    {
+	      error ("yes_or_no: expecting argument to be character string");
+	      return retval;
+	    }
+	}
+
+      retval = octave_yes_or_no (prompt);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static void
+restore_command_history (void *)
+{
+  command_history::ignore_entries (! Vsaving_history);
+}
+
+static size_t saved_frame = 0;
+
+static void
+restore_frame (void *)
+{
+  octave_call_stack::goto_frame (saved_frame);
+}
+
+octave_value
+do_keyboard (const octave_value_list& args)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  assert (nargin == 0 || nargin == 1);
+
+  unwind_protect::begin_frame ("do_keyboard");
+
+  // FIXME -- we shouldn't need both the
+  // command_history object and the
+  // Vsaving_history variable...
+  command_history::ignore_entries (false);
+
+  unwind_protect::add (restore_command_history, 0);
+
+  unwind_protect_bool (Vsaving_history);
+  unwind_protect_bool (Vdebugging);
+
+  saved_frame = octave_call_stack::current_frame ();
+  unwind_protect::add (restore_frame);
+  unwind_protect_size_t (saved_frame);
+
+  Vsaving_history = true;
+  Vdebugging = true;
+
+  std::string prompt = "debug> ";
+  if (nargin > 0)
+    prompt = args(0).string_value ();
+
+  if (! error_state)
+    get_debug_input (prompt);
+
+  unwind_protect::run_frame ("do_keyboard");
+
+  return retval;
+}
+
+DEFUN (keyboard, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} keyboard ()\n\
+ at deftypefnx {Built-in Function} {} keyboard (@var{prompt})\n\
+This function is normally used for simple debugging.  When the\n\
+ at code{keyboard} function is executed, Octave prints a prompt and waits\n\
+for user input.  The input strings are then evaluated and the results\n\
+are printed.  This makes it possible to examine the values of variables\n\
+within a function, and to assign new values if necessary.  To leave the\n\
+prompt and return to normal execution type @samp{return} or @samp{dbcont}.\n\
+The @code{keyboard} function does not return an exit status.\n\
+\n\
+If @code{keyboard} is invoked without arguments, a default prompt of\n\
+ at samp{debug> } is used.\n\
+ at seealso{dbcont, dbquit}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0 || nargin == 1)
+    {
+      saved_frame = octave_call_stack::current_frame ();
+      unwind_protect::add (restore_frame);
+      unwind_protect_size_t (saved_frame);
+
+      // Skip the frame assigned to the keyboard function.
+      octave_call_stack::goto_frame_relative (0, true);
+
+      do_keyboard (args);
+
+      unwind_protect::run ();
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (echo, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} echo options\n\
+Control whether commands are displayed as they are executed.  Valid\n\
+options are:\n\
+\n\
+ at table @code\n\
+ at item on\n\
+Enable echoing of commands as they are executed in script files.\n\
+\n\
+ at item off\n\
+Disable echoing of commands as they are executed in script files.\n\
+\n\
+ at item on all\n\
+Enable echoing of commands as they are executed in script files and\n\
+functions.\n\
+\n\
+ at item off all\n\
+Disable echoing of commands as they are executed in script files and\n\
+functions.\n\
+ at end table\n\
+\n\
+ at noindent\n\
+With no arguments, @code{echo} toggles the current echo state.\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("echo");
+
+  if (error_state)
+    return retval;
+
+  switch (argc)
+    {
+    case 1:
+      {
+	if ((Vecho_executing_commands & ECHO_SCRIPTS)
+	    || (Vecho_executing_commands & ECHO_FUNCTIONS))
+	  Vecho_executing_commands = ECHO_OFF;
+	else
+	  Vecho_executing_commands = ECHO_SCRIPTS;
+      }
+      break;
+
+    case 2:
+      {
+	std::string arg = argv[1];
+
+	if (arg == "on")
+	  Vecho_executing_commands = ECHO_SCRIPTS;
+	else if (arg == "off")
+	  Vecho_executing_commands = ECHO_OFF;
+	else
+	  print_usage ();
+      }
+      break;
+
+    case 3:
+      {
+	std::string arg = argv[1];
+
+	if (arg == "on" && argv[2] == "all")
+	  {
+	    int tmp = (ECHO_SCRIPTS | ECHO_FUNCTIONS);
+	    Vecho_executing_commands = tmp;
+	  }
+	else if (arg == "off" && argv[2] == "all")
+	  Vecho_executing_commands = ECHO_OFF;
+	else
+	  print_usage ();
+      }
+      break;
+
+    default:
+      print_usage ();
+      break;
+    }
+
+  return retval;
+}
+
+DEFUN (completion_matches, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} completion_matches (@var{hint})\n\
+Generate possible completions given @var{hint}.\n\
+\n\
+This function is provided for the benefit of programs like Emacs which\n\
+might be controlling Octave and handling user input.  The current\n\
+command number is not incremented when this function is called.  This is\n\
+a feature, not a bug.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string hint = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  int n = 32;
+
+	  string_vector list (n);
+
+	  int k = 0;
+
+	  for (;;)
+	    {
+	      std::string cmd = generate_completion (hint, k);
+
+	      if (! cmd.empty ())
+		{
+		  if (k == n)
+		    {
+		      n *= 2;
+		      list.resize (n);
+		    }
+
+		  list[k++] = cmd;
+		}
+	      else
+		{
+		  list.resize (k);
+		  break;
+		}
+	    }
+
+	  if (nargout > 0)
+	    {
+	      if (! list.empty ())
+		retval = list;
+	      else
+		retval = "";
+	    }
+	  else
+	    {
+	      // We don't use string_vector::list_in_columns here
+	      // because it will be easier for Emacs if the names
+	      // appear in a single column.
+
+	      int len = list.length ();
+
+	      for (int i = 0; i < len; i++)
+		octave_stdout << list[i] << "\n";
+	    }
+
+	  octave_completion_matches_called = true;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (read_readline_init_file, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} read_readline_init_file (@var{file})\n\
+Read the readline library initialization file @var{file}.  If\n\
+ at var{file} is omitted, read the default initialization file (normally\n\
+ at file{~/.inputrc}).\n\
+\n\
+ at xref{Readline Init File, , , readline, GNU Readline Library},\n\
+for details.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    command_editor::read_init_file ();
+  else if (nargin == 1)
+    {
+      std::string file = args(0).string_value ();
+
+      if (! error_state)
+	command_editor::read_init_file (file);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (re_read_readline_init_file, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} re_read_readline_init_file ()\n\
+Re-read the last readline library initialization file that was read.\n\
+ at xref{Readline Init File, , , readline, GNU Readline Library},\n\
+for details.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 0)
+    command_editor::re_read_init_file ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+typedef std::map<std::string, octave_value> hook_fcn_map_type;
+
+static hook_fcn_map_type hook_fcn_map;
+
+static int
+input_event_hook (void)
+{
+  hook_fcn_map_type::iterator p = hook_fcn_map.begin ();
+
+  while (p != hook_fcn_map.end ())
+    {
+      std::string hook_fcn = p->first;
+      octave_value user_data = p->second;
+
+      p++;
+
+      if (is_valid_function (hook_fcn))
+	{
+	  if (user_data.is_defined ())
+	    feval (hook_fcn, user_data, 0);
+	  else
+	    feval (hook_fcn, octave_value_list (), 0);
+	}
+      else
+	hook_fcn_map.erase (p);
+    }
+
+  if (hook_fcn_map.empty ())
+    command_editor::remove_event_hook (input_event_hook);
+
+  return 0;
+}
+
+DEFUN (add_input_event_hook, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} add_input_event_hook (@var{fcn}, @var{data})\n\
+Add the named function @var{fcn} to the list of functions to call\n\
+periodically when Octave is waiting for input.  The function should\n\
+have the form\n\
+ at example\n\
+ at var{fcn} (@var{data})\n\
+ at end example\n\
+\n\
+If @var{data} is omitted, Octave calls the function without any\n\
+arguments.\n\
+ at seealso{remove_input_event_hook}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      octave_value user_data;
+
+      if (nargin == 2)
+	user_data = args(1);
+
+      std::string hook_fcn = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  if (hook_fcn_map.empty ())
+	    command_editor::add_event_hook (input_event_hook);
+
+	  hook_fcn_map[hook_fcn] = user_data;
+	}
+      else
+	error ("add_input_event_hook: expecting string as first arg");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (remove_input_event_hook, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} remove_input_event_hook (@var{fcn})\n\
+Remove the named function @var{fcn} to the list of functions to call\n\
+periodically when Octave is waiting for input.\n\
+ at seealso{add_input_event_hook}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string hook_fcn = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  hook_fcn_map_type::iterator p = hook_fcn_map.find (hook_fcn);
+
+	  if (p != hook_fcn_map.end ())
+	    hook_fcn_map.erase (p);
+	  else
+	    error ("remove_input_event_hook: %s not found in list",
+		   hook_fcn.c_str ());
+
+	  if (hook_fcn_map.empty ())
+	    command_editor::remove_event_hook (input_event_hook);
+	}
+      else
+	error ("remove_input_event_hook: expecting string as first arg");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (PS1, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} PS1 ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS1 (@var{new_val})\n\
+Query or set the primary prompt string.  When executing interactively,\n\
+Octave displays the primary prompt when it is ready to read a command.\n\
+\n\
+The default value of the primary prompt string is @code{\"\\s:\\#> \"}.\n\
+To change it, use a command like\n\
+\n\
+ at example\n\
+octave:13> PS1 (\"\\\\u@@\\\\H> \")\n\
+ at end example\n\
+\n\
+ at noindent\n\
+which will result in the prompt @samp{boris@@kremvax> } for the user\n\
+ at samp{boris} logged in on the host @samp{kremvax.kgb.su}.  Note that two\n\
+backslashes are required to enter a backslash into a double-quoted\n\
+character string.\n\
+ at xref{Strings}.\n\
+ at seealso{PS2, PS4}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (PS1);
+}
+
+DEFUN (PS2, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} PS2 ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS2 (@var{new_val})\n\
+Query or set the secondary prompt string.  The secondary prompt is\n\
+printed when Octave is expecting additional input to complete a\n\
+command.  For example, if you are typing a @code{for} loop that spans several\n\
+lines, Octave will print the secondary prompt at the beginning of\n\
+each line after the first.  The default value of the secondary prompt\n\
+string is @code{\"> \"}.\n\
+ at seealso{PS1, PS4}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (PS2);
+}
+
+DEFUN (PS4, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} PS4 ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} PS4 (@var{new_val})\n\
+Query or set the character string used to prefix output produced\n\
+when echoing commands is enabled.\n\
+The default value is @code{\"+ \"}.\n\
+ at xref{Diary and Echo Commands}, for a description of echoing commands.\n\
+ at seealso{echo, echo_executing_commands, PS1, PS2}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (PS4);
+}
+
+DEFUN (completion_append_char, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} completion_append_char ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} completion_append_char (@var{new_val})\n\
+Query or set the internal character variable that is appended to\n\
+successful command-line completion attempts.  The default\n\
+value is @code{\" \"} (a single space).\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (completion_append_char);
+}
+
+DEFUN (echo_executing_commands, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} echo_executing_commands ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} echo_executing_commands (@var{new_val})\n\
+Query or set the internal variable that controls the echo state.\n\
+It may be the sum of the following values:\n\
+\n\
+ at table @asis\n\
+ at item 1\n\
+Echo commands read from script files.\n\
+\n\
+ at item 2\n\
+Echo commands from functions.\n\
+\n\
+ at item 4\n\
+Echo commands read from command line.\n\
+ at end table\n\
+\n\
+More than one state can be active at once.  For example, a value of 3 is\n\
+equivalent to the command @kbd{echo on all}.\n\
+\n\
+The value of @code{echo_executing_commands} may be set by the @kbd{echo}\n\
+command or the command line option @code{--echo-commands}.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (echo_executing_commands);
+}
+
+DEFUN (__request_drawnow__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __request_drawnow__ ()\n\
+ at deftypefnx {Built-in Function} {} __request_drawnow__ (@var{flag})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    Vdrawnow_requested = true;
+  else if (nargin == 1)
+    Vdrawnow_requested = args(0).bool_value ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__gud_mode__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __gud_mode__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = Vgud_mode;
+  else if (nargin == 1)
+    Vgud_mode = args(0).bool_value ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (filemarker, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} filemarker ()\n\
+Returns or sets the character used to separate filename from the\n\
+the subfunction names contained within the file.  This can be used in\n\
+a generic manner to interact with subfunctions.  For example\n\
+\n\
+ at example\n\
+help ([\"myfunc\", filemarker, \"mysubfunc\"])\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns the help string associated with the sub-function @code{mysubfunc}\n\
+of the function @code{myfunc}.  Another use of @code{filemarker} is when\n\
+debugging it allows easier placement of breakpoints within sub-functions.\n\
+For example\n\
+\n\
+ at example\n\
+dbstop ([\"myfunc\", filemarker, \"mysubfunc\"])\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will set a breakpoint at the first line of the subfunction @code{mysubfunc}.\n\
+ at end deftypefn")
+{
+  char tmp = Vfilemarker;
+  octave_value retval = SET_INTERNAL_VARIABLE (filemarker);
+
+  // The character passed must not be a legal character for a function name
+  if (! error_state && (::isalnum (Vfilemarker) || Vfilemarker == '_'))
+    {
+      Vfilemarker = tmp;
+      error ("filemarker: character can not be a valid character for a function name");
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/input.h b/src/input.h
new file mode 100644
index 0000000..b279996
--- /dev/null
+++ b/src/input.h
@@ -0,0 +1,124 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Use the GNU readline library for command line editing and hisory.
+
+#if !defined (octave_input_h)
+#define octave_input_h 1
+
+#include <cstdio>
+
+#include <string>
+
+#include "oct-time.h"
+#include "oct-obj.h"
+#include "pager.h"
+
+class octave_value;
+
+extern OCTINTERP_API int octave_read (char *buf, unsigned max_size);
+extern OCTINTERP_API FILE *get_input_from_file (const std::string& name, int warn = 1);
+extern OCTINTERP_API FILE *get_input_from_stdin (void);
+
+// Global pointer for eval().
+extern std::string current_eval_string;
+
+// TRUE means get input from current_eval_string.
+extern bool get_input_from_eval_string;
+
+// TRUE means we haven't been asked for the input from
+// current_eval_string yet.
+extern bool input_from_eval_string_pending;
+
+// TRUE means that input is coming from a file that was named on
+// the command line.
+extern bool input_from_command_line_file;
+
+// TRUE means we're parsing a function file.
+extern bool reading_fcn_file;
+
+// Simple name of function file we are reading.
+extern std::string curr_fcn_file_name;
+
+// Full name of file we are reading.
+extern std::string curr_fcn_file_full_name;
+
+// TRUE means we're parsing a script file.
+extern bool reading_script_file;
+
+// If we are reading from an M-file, this is it.
+extern FILE *ff_instream;
+
+// TRUE means this is an interactive shell.
+extern bool interactive;
+
+// TRUE means the user forced this shell to be interactive (-i).
+extern bool forced_interactive;
+
+// Should we issue a prompt?
+extern int promptflag;
+
+// A line of input.
+extern std::string current_input_line;
+
+// TRUE after a call to completion_matches.
+extern bool octave_completion_matches_called;
+
+// TRUE if the plotting system has requested a call to drawnow at
+// the next user prompt.
+extern OCTINTERP_API bool Vdrawnow_requested;
+
+// TRUE if we are in debugging mode.
+extern OCTINTERP_API bool Vdebugging;
+
+extern std::string gnu_readline (const std::string& s, bool force_readline = false);
+
+extern void initialize_command_input (void);
+
+extern bool octave_yes_or_no (const std::string& prompt);
+
+extern octave_value do_keyboard (const octave_value_list& args = octave_value_list ());
+
+extern std::string VPS4;
+
+extern char Vfilemarker;
+
+enum echo_state
+{
+  ECHO_OFF = 0,
+  ECHO_SCRIPTS = 1,
+  ECHO_FUNCTIONS = 2,
+  ECHO_CMD_LINE = 4
+};
+
+extern int Vecho_executing_commands;
+
+extern octave_time Vlast_prompt_time;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/lex.cc b/src/lex.cc
new file mode 100644
index 0000000..49c007a
--- /dev/null
+++ b/src/lex.cc
@@ -0,0 +1,6223 @@
+
+#line 3 "<stdout>"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer octave__create_buffer
+#define yy_delete_buffer octave__delete_buffer
+#define yy_flex_debug octave__flex_debug
+#define yy_init_buffer octave__init_buffer
+#define yy_flush_buffer octave__flush_buffer
+#define yy_load_buffer_state octave__load_buffer_state
+#define yy_switch_to_buffer octave__switch_to_buffer
+#define yyin octave_in
+#define yyleng octave_leng
+#define yylex octave_lex
+#define yylineno octave_lineno
+#define yyout octave_out
+#define yyrestart octave_restart
+#define yytext octave_text
+#define yywrap octave_wrap
+#define yyalloc octave_alloc
+#define yyrealloc octave_realloc
+#define yyfree octave_free
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif	/* defined (__STDC__) */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE octave_restart(octave_in  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int octave_leng;
+
+extern FILE *octave_in, *octave_out;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up octave_text. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up octave_text again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via octave_restart()), so that the user can continue scanning by
+	 * just pointing octave_in at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when octave_text is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int octave_leng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow octave_wrap()'s to do buffer switches
+ * instead of setting up a fresh octave_in.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void octave_restart (FILE *input_file  );
+void octave__switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE octave__create_buffer (FILE *file,int size  );
+void octave__delete_buffer (YY_BUFFER_STATE b  );
+void octave__flush_buffer (YY_BUFFER_STATE b  );
+void octave_push_buffer_state (YY_BUFFER_STATE new_buffer  );
+void octave_pop_buffer_state (void );
+
+static void octave_ensure_buffer_stack (void );
+static void octave__load_buffer_state (void );
+static void octave__init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER octave__flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE octave__scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE octave__scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE octave__scan_bytes (yyconst char *bytes,int len  );
+
+void *octave_alloc (yy_size_t  );
+void *octave_realloc (void *,yy_size_t  );
+void octave_free (void *  );
+
+#define yy_new_buffer octave__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        octave_ensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            octave__create_buffer(octave_in,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        octave_ensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            octave__create_buffer(octave_in,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *octave_in = (FILE *) 0, *octave_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int octave_lineno;
+
+int octave_lineno = 1;
+
+extern char *octave_text;
+#define yytext_ptr octave_text
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up octave_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	octave_leng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 87
+#define YY_END_OF_BUFFER 88
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[453] =
+    {   0,
+       20,   20,   20,   20,   20,   20,    0,    0,    0,    0,
+        0,    0,   88,   86,   20,   25,   25,   64,   27,   28,
+       23,   46,   26,   65,   66,   52,   50,   56,   51,   67,
+       53,   19,   19,   30,   55,   48,   59,   49,   24,   15,
+       54,   16,   57,   84,   47,   85,   64,   20,   28,    7,
+        4,    4,    7,    6,    7,    7,    6,    7,    7,    7,
+        7,    5,    7,    7,    7,    7,    7,    7,    5,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,   11,   14,   14,   28,   10,   12,    8,    9,   11,
+       28,    1,   87,    2,    3,   20,   25,   44,   23,   23,
+
+       60,   80,   58,   70,   39,   68,   40,   69,   38,   33,
+       31,   32,    0,   34,   19,   35,   36,   71,   19,   19,
+        0,   17,    0,   62,   41,   42,   45,   63,   15,    0,
+       21,   21,    0,   72,   78,   84,   81,   61,   43,   20,
+        0,    0,    7,    7,    4,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,   11,   14,   14,    0,   10,
+       12,    8,    9,   14,   14,    0,   14,    0,   13,   13,
+
+       10,   12,   12,    0,    8,    9,   11,    0,    0,   37,
+       75,   73,   74,    0,   76,    0,   77,   79,   18,   19,
+        0,   19,   19,   82,   83,    0,   22,   22,    0,   29,
+       29,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,   14,
+       14,    0,   14,   14,   13,   13,    0,   13,   13,   13,
+        0,   12,    8,    9,   12,    0,   12,   12,    0,   13,
+       13,    0,   19,   22,    7,    7,   14,   14,   14,    0,
+       12,    8,    9,   13,    0,   13,   13,   13,   13,    0,
+       13,   13,   12,   12,   12,    0,    8,    9,   12,   12,
+
+       12,    0,   13,   14,   14,   12,   12,   12,    0,    8,
+        9,   13,   13,   13,    0,   12,    8,    9,   13,   13,
+       13,    0,   12,    8,    9,   12,   12,    0,   12,   12,
+       12,    0,    0,   12,   12,   12,   12,   12,   12,    0,
+       12,   12,   12,    0,    0,   12,   12,   13,   13,   12,
+       12,   12,    0,    8,    9,   13,   13,   12,   12,   12,
+        0,    8,    9,   12,    0,   12,   12,   12,   12,    0,
+       12,   12,   12,   12,   12,    0,   12,    8,    9,   12,
+       12,   12,   12,   12,   12,    0,   12,    8,    9,   12,
+       12,   12,    0,   12,   12,   12,    0,   12,   12,   12,
+
+        0,   12,    8,    9,   12,   12,   12,    0,   12,    8,
+        9,   12,   12,   12,   12,   12,    0,    8,    9,   12,
+       12,   12,   12,   12,    0,    8,    9,   12,   12,   12,
+       12,   12,   12,   12,   12,   12,    0,    8,    9,   12,
+       12,   12,   12,   12,    0,    8,    9,   12,   12,   12,
+       12,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    5,    6,    7,    8,    7,    9,   10,   11,
+       12,   13,   14,   15,   16,   17,   18,   19,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   21,   22,   23,
+       24,   25,    1,   26,   27,   27,   27,   28,   28,   27,
+        8,    8,   29,   29,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,   30,    8,    8,
+       31,   32,   33,   34,    8,    1,   27,   27,   27,   28,
+
+       28,   27,    8,    8,   29,   29,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,   30,
+        8,    8,   35,   36,   37,   38,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[39] =
+    {   0,
+        1,    2,    3,    3,    1,    1,    1,    2,    1,    1,
+        1,    1,    1,    1,    3,    1,    1,    1,    2,    2,
+        1,    3,    1,    1,    1,    1,    2,    2,    2,    2,
+        1,    1,    1,    1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[469] =
+    {   0,
+        0,   37,   44,   81,   87,   85,  858,  856,  855,  854,
+      853,  852,  854, 2036,  851, 2036,  849,  827, 2036, 2036,
+      848,   75, 2036, 2036, 2036,   72,   79, 2036,   81,  115,
+      825,  133,   87, 2036, 2036,   17,  824,   18, 2036,  845,
+      115, 2036,  822,  842,   62, 2036,  819,   93,  803,  835,
+     2036,  833,   99, 2036,  162,  112, 2036,  832,  831,  124,
+      141, 2036,  142,  191,  106,  224,  802,  829, 2036,  136,
+      143,  144,  828,  827,  170,  826,  152,  825,  176,  824,
+      155,  253,  289,  822,  107,  821,  181,  820,  819,  149,
+      183, 2036, 2036, 2036, 2036,  818, 2036, 2036,  817,  816,
+
+     2036, 2036,  793, 2036, 2036, 2036, 2036, 2036, 2036,  182,
+      792,  784,  790,  778,  200,  777,  774, 2036,  317,  217,
+      183, 2036,  194,  763, 2036, 2036, 2036,  762,  782,  228,
+     2036,  780,  109, 2036, 2036,  770, 2036, 2036, 2036,  173,
+      736,  138,  764,  763, 2036,  760,  749,    0,  748,  746,
+      214,  745,  734,  733,  728,  727,  724,  237,  225,  238,
+      231,  240,  269,  245,  249,  713,  342,  684,  263,  688,
+      282,  256,  652,  616,  580,  257,  544,  301,  310,  518,
+      506,  488,  463,  441,  438,    0,    0,  434,  263,  430,
+      313,  419,  414,    0,  403,  291,    0,  296,  375,  411,
+
+      373,  336,  361,  303,  371,  339,    0,  315,  354,  307,
+     2036, 2036, 2036,  381, 2036,  328, 2036, 2036, 2036,  361,
+      304,  367,  372, 2036, 2036,  325, 2036,  330,  367, 2036,
+      318,  261,  285,  276,  274,  391,  272,  403,  270,  268,
+      222,  390,  409,  422,  450,  215,  213,  423,  400,    0,
+        0,  350,    0,  478,    0,  195,  363,  514,    0,  550,
+      427,  432,  451,  454,  457,  443,  464,  484,  470,    0,
+      586,  430,  464, 2036,  487,  490,  622,    0,  658,  459,
+      492,  499,  510,    0,  472,    0,  694,    0,    0,  494,
+        0,  730,  520,  766,  802,  501,  526,  529,  535,  541,
+
+      556,  522,    0,    0,    0,  562,  838,  874,  531,  571,
+      574,  910,    0,  946,  537,  577,  592,  595,  982,    0,
+     1018,  546,  598,  607,  610,    0,  193,  552, 1054,    0,
+     1090,  558,  564,    0, 1126,  613,  628,    0,  168,  567,
+     1162,    0, 1198,  582,  588,    0, 1234,    0,    0,  634,
+        0, 1270,  600,  643,  646,    0,    0,  649,    0, 1306,
+      603,  664,  667,    0,  618,    0, 1342,    0,    0,  624,
+        0, 1378, 1414,    0, 1450,  630,  670,  679,  682,    0,
+        0,    0, 1486,    0, 1522,  636,  685,  700,  703, 1558,
+        0, 1594,  639, 1630,    0, 1666,  654, 1702,    0, 1738,
+
+      660,  706,  715,  718, 1774,    0, 1810,  672,  721,  736,
+      739,    0,    0,  742,    0, 1846,  675,  751,  754,    0,
+        0,  757,    0, 1882,  690,  772,  775,    0,    0,    0,
+        0,    0,    0,  778,    0, 1918,  696,  787,  790,    0,
+        0,  793,    0, 1954,  708,  808,  811,    0,    0,    0,
+        0, 2036, 1991, 1994, 1997,  125, 2000, 2002, 2005, 2008,
+     2011, 2014, 2017, 2020, 2023, 2026, 2029, 2032
+    } ;
+
+static yyconst flex_int16_t yy_def[469] =
+    {   0,
+      452,    1,  452,    3,    1,    5,  453,  453,  454,  454,
+      455,  455,  452,  452,  452,  452,  452,  452,  452,  452,
+      456,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  457,
+      452,  452,  457,  452,  457,  457,  452,  457,  457,  457,
+      457,  452,  457,  457,  457,  457,   66,  457,  452,  457,
+      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
+      457,  452,  452,   83,  458,  452,  452,  452,  452,   82,
+      458,  452,  452,  452,  452,  452,  452,  452,  452,  456,
+
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  459,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  457,  452,  452,  457,  452,   55,  457,  457,
+      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
+      457,  457,  457,  457,  457,  457,   66,   66,  457,  457,
+      457,  457,  457,  457,  457,  457,  452,  452,  460,  457,
+      457,  452,  457,  457,  457,   82,   83,   83,  458,  452,
+      452,  452,  452,   83,   83,  461,   83,  458,  452,  458,
+
+      452,  452,  452,  462,  452,  452,   90,  458,  458,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  459,  452,  459,  452,  452,
+      452,  457,  457,  457,  457,  457,  457,  457,  457,  457,
+      457,   66,  457,  457,  457,  457,  457,  460,  459,   83,
+       83,  461,   83,  461,  199,  199,  463,  458,  199,  458,
+      464,  458,  458,  458,  452,  462,  452,  462,  458,  199,
+      458,  452,  452,  452,  457,  457,  461,   83,  461,  461,
+      461,  461,  461,  199,  463,  199,  463,  199,  199,  464,
+      199,  464,  458,  452,  458,  465,  458,  458,  462,  452,
+
+      462,  462,  199,   83,   83,  461,  452,  461,  466,  461,
+      461,  463,  199,  463,  463,  463,  463,  463,  464,  199,
+      464,  464,  464,  464,  464,  294,  294,  467,  458,  294,
+      458,  468,  465,  294,  465,  452,  452,  307,  307,  466,
+      461,  307,  461,  466,  466,  307,  466,  199,  199,  463,
+      294,  463,  467,  463,  463,  199,  199,  464,  294,  464,
+      468,  464,  464,  294,  467,  294,  467,  294,  294,  468,
+      294,  468,  465,  294,  465,  468,  465,  465,  465,  307,
+      307,  307,  466,  307,  466,  466,  466,  466,  466,  463,
+      294,  463,  467,  464,  294,  464,  468,  467,  294,  467,
+
+      467,  467,  467,  467,  468,  294,  468,  468,  468,  468,
+      468,  294,  294,  465,  294,  465,  465,  465,  465,  307,
+      307,  466,  307,  466,  466,  466,  466,  294,  294,  294,
+      294,  294,  294,  467,  294,  467,  467,  467,  467,  294,
+      294,  468,  294,  468,  468,  468,  468,  294,  307,  294,
+      294,    0,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452
+    } ;
+
+static yyconst flex_int16_t yy_nxt[2075] =
+    {   0,
+       14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
+       24,   25,   26,   27,   28,   29,   30,   31,   32,   33,
+       34,   35,   36,   37,   38,   39,   21,   21,   21,   21,
+       40,   41,   42,   43,   44,   45,   46,   47,   48,  124,
+      125,  127,  128,   49,   50,   15,   51,   52,   53,   54,
+       20,   55,   56,   57,   58,   59,   60,   61,   62,   63,
+       64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
+       55,   55,   55,   55,   74,   75,   76,   77,   78,   79,
+       80,   81,   48,  101,  103,  137,   90,   49,   82,   83,
+       84,   91,  105,   85,  140,  104,  107,  138,  102,  141,
+
+      144,   86,  106,  119,  108,  120,  120,  144,   87,  199,
+      200,  227,  228,  144,  121,  122,  130,  131,  132,   88,
+      149,  133,  146,   89,  109,  144,  100,  110,  111,  166,
+      112,  113,  114,  115,  115,  150,  151,  144,  134,  229,
+      230,  231,  144,  144,  144,  144,  116,  152,  117,  119,
+      207,  120,  120,  144,  153,  208,  144,  155,  172,  173,
+      121,  122,  123,  147,  154,  156,  174,  175,  176,  148,
+      380,  178,  131,  132,  140,  181,  179,  144,  185,  141,
+      148,  148,  202,  202,  203,  199,  200,  204,  148,  148,
+      148,  148,  144,  180,  210,  364,  221,  284,  221,  183,
+
+      157,  222,  222,  158,  159,  211,  160,  161,  162,  163,
+      163,  184,  223,  223,  144,  144,  144,  209,  115,  115,
+      223,  223,  164,  144,  165,  144,  144,  216,  122,  130,
+      131,  132,  144,  119,  133,  120,  120,  181,  144,  144,
+      167,  144,  168,  168,  121,  122,  144,  236,  234,  232,
+      144,  169,  170,  171,  186,  187,  188,  144,  144,  189,
+      233,  235,  144,  237,  144,  199,  200,  190,  239,  144,
+      144,  144,  240,  144,  191,  144,  243,  144,  243,  246,
+      247,  244,  244,  144,  240,  192,  144,  163,  163,  193,
+      194,  194,  195,  253,  254,  196,  238,  170,  199,  200,
+
+      245,  245,  178,  131,  132,  267,  268,  133,  245,  245,
+      191,  249,  227,  228,  202,  202,  203,  199,  200,  204,
+      230,  192,  222,  222,  226,  193,  219,  227,  228,  219,
+      218,  226,  274,  228,  219,  220,  220,  202,  202,  203,
+      206,  272,  204,  272,  121,  122,  273,  273,  219,  209,
+      219,  241,  253,  254,  241,  269,  270,  271,  143,  241,
+      242,  242,  202,  265,  203,  286,  287,  204,  229,  230,
+      231,  143,  205,  241,  201,  241,  255,  255,  256,  220,
+      220,  257,  130,  131,  132,  222,  222,  133,  121,  122,
+      223,  223,  178,  131,  132,  122,  191,  179,  223,  223,
+
+      122,  249,  227,  228,  144,  251,  143,  192,  242,  242,
+      144,  193,  258,  259,  260,  206,  275,  261,  275,  143,
+      205,  276,  276,  144,  249,  227,  228,  244,  244,  291,
+      292,  201,  262,  293,  294,  295,  250,  226,  296,  144,
+      244,  244,  144,  263,  226,  267,  268,  264,  273,  273,
+      170,  144,  297,  199,  200,  298,  199,  200,  202,  202,
+      203,  253,  254,  204,  144,  202,  202,  203,  245,  245,
+      204,  269,  270,  271,  286,  287,  245,  245,  170,  277,
+      278,  279,  273,  273,  280,  299,  300,  301,  144,  182,
+      302,  144,  122,  306,  307,  308,  291,  292,  309,  281,
+
+      310,  253,  254,  334,  335,  276,  276,  144,  276,  276,
+      282,  311,  253,  254,  283,  258,  288,  260,  170,  144,
+      261,  293,  294,  295,  267,  268,  296,  297,  199,  200,
+      298,  199,  200,  346,  347,  262,  299,  336,  301,  286,
+      287,  302,  202,  202,  203,  177,  263,  204,  291,  292,
+      264,  258,  289,  260,  366,  367,  261,  299,  337,  301,
+      371,  372,  302,  306,  307,  308,  334,  335,  309,  346,
+      347,  262,  310,  253,  254,  311,  253,  254,  350,  351,
+      352,  144,  263,  353,  346,  347,  264,  258,  303,  260,
+      346,  347,  261,  354,  286,  287,  355,  286,  287,  358,
+
+      359,  360,  366,  367,  361,  371,  372,  262,  362,  291,
+      292,  363,  291,  292,  202,  202,  203,  144,  263,  204,
+      366,  367,  264,  277,  304,  279,  371,  372,  280,  202,
+      202,  203,  371,  372,  204,  350,  351,  352,  346,  347,
+      353,  366,  367,  281,  354,  286,  287,  355,  286,  287,
+      358,  359,  360,  144,  282,  361,  371,  372,  283,  277,
+      305,  279,  366,  367,  280,  362,  291,  292,  363,  291,
+      292,  414,  415,  416,  371,  372,  417,  334,  335,  281,
+      418,  334,  335,  419,  334,  335,  422,  423,  424,  144,
+      282,  425,  346,  347,  283,  312,  313,  314,  366,  367,
+
+      315,  426,  346,  347,  427,  346,  347,  434,  435,  436,
+      371,  372,  437,  143,  144,  316,  438,  366,  367,  439,
+      366,  367,  442,  443,  444,  144,  317,  445,  144,  144,
+      318,  319,  320,  321,  144,  144,  322,  446,  371,  372,
+      447,  371,  372,  414,  415,  416,  144,  144,  417,  144,
+      147,  323,  418,  334,  335,  419,  334,  335,  422,  423,
+      424,  144,  324,  425,  144,  144,  325,  326,  326,  327,
+      142,  136,  328,  426,  346,  347,  427,  346,  347,  434,
+      435,  436,  131,  129,  437,  225,  224,  191,  438,  366,
+      367,  439,  366,  367,  442,  443,  444,  218,  192,  445,
+
+      217,  215,  193,  329,  330,  331,  214,  213,  332,  446,
+      371,  372,  447,  371,  372,  212,  135,   99,   99,   96,
+      206,  205,  201,  262,  197,  144,  182,  144,  177,  144,
+      144,  143,  144,  144,  263,  145,  144,  142,  264,  338,
+      338,  339,  139,  136,  340,  135,  129,  126,  118,   99,
+       98,   97,   96,  452,   93,   93,   93,   93,   93,  191,
+       93,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      192,  452,  452,  452,  193,  341,  342,  343,  452,  452,
+      344,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  281,  452,  452,  452,  452,
+
+      452,  452,  452,  452,  452,  452,  282,  452,  452,  452,
+      283,  312,  348,  314,  452,  452,  315,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  316,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  317,  452,  452,  452,  318,  312,  349,  314,
+      452,  452,  315,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  316,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  317,  452,
+      452,  452,  318,  319,  356,  321,  452,  452,  322,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+
+      452,  452,  452,  323,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  324,  452,  452,  452,  325,  319,
+      357,  321,  452,  452,  322,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  323,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      324,  452,  452,  452,  325,  329,  368,  331,  452,  452,
+      332,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  262,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  263,  452,  452,  452,
+      264,  329,  369,  331,  452,  452,  332,  452,  452,  452,
+
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  262,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  263,  452,  452,  452,  264,  373,  374,  375,
+      452,  452,  376,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  377,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  378,  452,
+      452,  452,  379,  341,  381,  343,  452,  452,  344,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  281,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  282,  452,  452,  452,  283,  341,
+
+      382,  343,  452,  452,  344,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  281,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      282,  452,  452,  452,  283,  383,  384,  385,  452,  452,
+      386,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  387,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  388,  452,  452,  452,
+      389,  390,  391,  392,  452,  452,  393,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  316,  452,  452,  452,  452,  452,  452,  452,  452,
+
+      452,  452,  317,  452,  452,  452,  318,  394,  395,  396,
+      452,  452,  397,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  323,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  324,  452,
+      452,  452,  325,  398,  399,  400,  452,  452,  401,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  402,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  403,  452,  452,  452,  404,  405,
+      406,  407,  452,  452,  408,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  409,
+
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      410,  452,  452,  452,  411,  373,  412,  375,  452,  452,
+      376,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  377,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  378,  452,  452,  452,
+      379,  373,  413,  375,  452,  452,  376,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  377,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  378,  452,  452,  452,  379,  383,  420,  385,
+      452,  452,  386,  452,  452,  452,  452,  452,  452,  452,
+
+      452,  452,  452,  452,  452,  452,  452,  387,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  388,  452,
+      452,  452,  389,  383,  421,  385,  452,  452,  386,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  387,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  388,  452,  452,  452,  389,  390,
+      428,  392,  452,  452,  393,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  316,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      317,  452,  452,  452,  318,  390,  429,  392,  452,  452,
+
+      393,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  316,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  317,  452,  452,  452,
+      318,  394,  430,  396,  452,  452,  397,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  323,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  324,  452,  452,  452,  325,  394,  431,  396,
+      452,  452,  397,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  323,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  324,  452,
+
+      452,  452,  325,  398,  432,  400,  452,  452,  401,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  402,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  403,  452,  452,  452,  404,  398,
+      433,  400,  452,  452,  401,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  402,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      403,  452,  452,  452,  404,  405,  440,  407,  452,  452,
+      408,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  409,  452,  452,  452,  452,
+
+      452,  452,  452,  452,  452,  452,  410,  452,  452,  452,
+      411,  405,  441,  407,  452,  452,  408,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  409,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  410,  452,  452,  452,  411,  373,  448,  375,
+      452,  452,  376,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  377,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  378,  452,
+      452,  452,  379,  383,  449,  385,  452,  452,  386,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+
+      452,  452,  452,  387,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  388,  452,  452,  452,  389,  398,
+      450,  400,  452,  452,  401,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  402,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      403,  452,  452,  452,  404,  405,  451,  407,  452,  452,
+      408,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  409,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  410,  452,  452,  452,
+      411,   92,   92,   92,   94,   94,   94,   95,   95,   95,
+
+      143,  143,  198,  198,  198,  226,  226,  226,  248,  248,
+      248,  252,  252,  252,  266,  266,  266,  285,  285,  285,
+      290,  290,  290,  333,  333,  333,  345,  345,  345,  365,
+      365,  365,  370,  370,  370,   13,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452
+    } ;
+
+static yyconst flex_int16_t yy_chk[2075] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,   36,
+       36,   38,   38,    2,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    4,   22,   26,   45,    6,    4,    5,    5,
+        5,    6,   27,    5,   48,   26,   29,   45,   22,   48,
+
+       53,    5,   27,   33,   29,   33,   33,   65,    5,   85,
+       85,  133,  133,   56,   33,   33,   41,   41,   41,    5,
+       56,   41,   53,    5,   30,   60,  456,   30,   30,   65,
+       30,   30,   30,   30,   30,   56,   60,   70,   41,  142,
+      142,  142,   61,   63,   71,   72,   30,   60,   30,   32,
+       90,   32,   32,   77,   61,   90,   81,   63,   70,   70,
+       32,   32,   32,   55,   61,   63,   71,   72,   72,   55,
+      339,   75,   75,   75,  140,   77,   75,   79,   81,  140,
+       55,   55,   87,   87,   87,   91,   91,   87,   55,   55,
+       55,   55,   64,   75,  110,  327,  121,  256,  121,   79,
+
+       64,  121,  121,   64,   64,  110,   64,   64,   64,   64,
+       64,   79,  123,  123,  247,  151,  246,   91,  115,  115,
+      123,  123,   64,  241,   64,   66,  159,  115,  115,  130,
+      130,  130,  161,  120,  130,  120,  120,  151,  158,  160,
+       66,  162,   66,   66,  120,  120,  164,  161,  159,  158,
+      165,   66,   66,   66,   82,   82,   82,  172,  176,   82,
+      158,  160,  232,  162,  169,  189,  189,   82,  164,  240,
+      163,  239,  165,  237,   82,  235,  169,  234,  169,  172,
+      176,  169,  169,  171,  232,   82,  233,  163,  163,   82,
+       83,   83,   83,  196,  196,   83,  163,  163,  198,  198,
+
+      171,  171,  178,  178,  178,  204,  204,  178,  171,  171,
+       83,  179,  179,  179,  191,  191,  191,  208,  208,  191,
+      231,   83,  221,  221,  179,   83,  119,  226,  226,  119,
+      210,  179,  228,  228,  119,  119,  119,  202,  202,  202,
+      206,  216,  202,  216,  119,  119,  216,  216,  119,  208,
+      119,  167,  252,  252,  167,  209,  209,  209,  167,  167,
+      167,  167,  203,  203,  203,  257,  257,  203,  229,  229,
+      229,  167,  205,  167,  201,  167,  199,  199,  199,  220,
+      220,  199,  214,  214,  214,  222,  222,  214,  220,  220,
+      223,  223,  236,  236,  236,  222,  199,  236,  223,  223,
+
+      223,  249,  249,  249,  238,  195,  242,  199,  242,  242,
+      243,  199,  200,  200,  200,  193,  238,  200,  238,  242,
+      192,  238,  238,  244,  248,  248,  248,  243,  243,  261,
+      261,  190,  200,  262,  262,  262,  188,  248,  262,  185,
+      244,  244,  184,  200,  248,  266,  266,  200,  272,  272,
+      244,  245,  263,  263,  263,  264,  264,  264,  265,  265,
+      265,  280,  280,  265,  183,  267,  267,  267,  245,  245,
+      267,  269,  269,  269,  285,  285,  245,  245,  245,  254,
+      254,  254,  273,  273,  254,  268,  268,  268,  275,  182,
+      268,  276,  273,  281,  281,  281,  290,  290,  281,  254,
+
+      282,  282,  282,  296,  296,  275,  275,  181,  276,  276,
+      254,  283,  283,  283,  254,  258,  258,  258,  276,  180,
+      258,  293,  293,  293,  302,  302,  293,  297,  297,  297,
+      298,  298,  298,  309,  309,  258,  299,  299,  299,  315,
+      315,  299,  300,  300,  300,  177,  258,  300,  322,  322,
+      258,  260,  260,  260,  328,  328,  260,  301,  301,  301,
+      332,  332,  301,  306,  306,  306,  333,  333,  306,  340,
+      340,  260,  310,  310,  310,  311,  311,  311,  316,  316,
+      316,  175,  260,  316,  344,  344,  260,  271,  271,  271,
+      345,  345,  271,  317,  317,  317,  318,  318,  318,  323,
+
+      323,  323,  353,  353,  323,  361,  361,  271,  324,  324,
+      324,  325,  325,  325,  336,  336,  336,  174,  271,  336,
+      365,  365,  271,  277,  277,  277,  370,  370,  277,  337,
+      337,  337,  376,  376,  337,  350,  350,  350,  386,  386,
+      350,  393,  393,  277,  354,  354,  354,  355,  355,  355,
+      358,  358,  358,  173,  277,  358,  397,  397,  277,  279,
+      279,  279,  401,  401,  279,  362,  362,  362,  363,  363,
+      363,  377,  377,  377,  408,  408,  377,  417,  417,  279,
+      378,  378,  378,  379,  379,  379,  387,  387,  387,  170,
+      279,  387,  425,  425,  279,  287,  287,  287,  437,  437,
+
+      287,  388,  388,  388,  389,  389,  389,  402,  402,  402,
+      445,  445,  402,  168,  166,  287,  403,  403,  403,  404,
+      404,  404,  409,  409,  409,  157,  287,  409,  156,  155,
+      287,  292,  292,  292,  154,  153,  292,  410,  410,  410,
+      411,  411,  411,  414,  414,  414,  152,  150,  414,  149,
+      147,  292,  418,  418,  418,  419,  419,  419,  422,  422,
+      422,  146,  292,  422,  144,  143,  292,  294,  294,  294,
+      141,  136,  294,  426,  426,  426,  427,  427,  427,  434,
+      434,  434,  132,  129,  434,  128,  124,  294,  438,  438,
+      438,  439,  439,  439,  442,  442,  442,  117,  294,  442,
+
+      116,  114,  294,  295,  295,  295,  113,  112,  295,  446,
+      446,  446,  447,  447,  447,  111,  103,  100,   99,   96,
+       89,   88,   86,  295,   84,   80,   78,   76,   74,   73,
+       68,   67,   59,   58,  295,   52,   50,   49,  295,  307,
+      307,  307,   47,   44,  307,   43,   40,   37,   31,   21,
+       18,   17,   15,   13,   12,   11,   10,    9,    8,  307,
+        7,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      307,    0,    0,    0,  307,  308,  308,  308,    0,    0,
+      308,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  308,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,  308,    0,    0,    0,
+      308,  312,  312,  312,    0,    0,  312,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  312,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  312,    0,    0,    0,  312,  314,  314,  314,
+        0,    0,  314,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  314,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  314,    0,
+        0,    0,  314,  319,  319,  319,    0,    0,  319,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,  319,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  319,    0,    0,    0,  319,  321,
+      321,  321,    0,    0,  321,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  321,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      321,    0,    0,    0,  321,  329,  329,  329,    0,    0,
+      329,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  329,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  329,    0,    0,    0,
+      329,  331,  331,  331,    0,    0,  331,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  331,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  331,    0,    0,    0,  331,  335,  335,  335,
+        0,    0,  335,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  335,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  335,    0,
+        0,    0,  335,  341,  341,  341,    0,    0,  341,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  341,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  341,    0,    0,    0,  341,  343,
+
+      343,  343,    0,    0,  343,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  343,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      343,    0,    0,    0,  343,  347,  347,  347,    0,    0,
+      347,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  347,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  347,    0,    0,    0,
+      347,  352,  352,  352,    0,    0,  352,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  352,    0,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,  352,    0,    0,    0,  352,  360,  360,  360,
+        0,    0,  360,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  360,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  360,    0,
+        0,    0,  360,  367,  367,  367,    0,    0,  367,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  367,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  367,    0,    0,    0,  367,  372,
+      372,  372,    0,    0,  372,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  372,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      372,    0,    0,    0,  372,  373,  373,  373,    0,    0,
+      373,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  373,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  373,    0,    0,    0,
+      373,  375,  375,  375,    0,    0,  375,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  375,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  375,    0,    0,    0,  375,  383,  383,  383,
+        0,    0,  383,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,  383,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  383,    0,
+        0,    0,  383,  385,  385,  385,    0,    0,  385,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  385,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  385,    0,    0,    0,  385,  390,
+      390,  390,    0,    0,  390,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  390,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      390,    0,    0,    0,  390,  392,  392,  392,    0,    0,
+
+      392,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  392,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  392,    0,    0,    0,
+      392,  394,  394,  394,    0,    0,  394,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  394,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  394,    0,    0,    0,  394,  396,  396,  396,
+        0,    0,  396,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  396,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  396,    0,
+
+        0,    0,  396,  398,  398,  398,    0,    0,  398,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  398,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  398,    0,    0,    0,  398,  400,
+      400,  400,    0,    0,  400,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  400,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      400,    0,    0,    0,  400,  405,  405,  405,    0,    0,
+      405,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  405,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,  405,    0,    0,    0,
+      405,  407,  407,  407,    0,    0,  407,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  407,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  407,    0,    0,    0,  407,  416,  416,  416,
+        0,    0,  416,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  416,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  416,    0,
+        0,    0,  416,  424,  424,  424,    0,    0,  424,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,  424,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  424,    0,    0,    0,  424,  436,
+      436,  436,    0,    0,  436,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  436,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      436,    0,    0,    0,  436,  444,  444,  444,    0,    0,
+      444,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  444,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  444,    0,    0,    0,
+      444,  453,  453,  453,  454,  454,  454,  455,  455,  455,
+
+      457,  457,  458,  458,  458,  459,  459,  459,  460,  460,
+      460,  461,  461,  461,  462,  462,  462,  463,  463,  463,
+      464,  464,  464,  465,  465,  465,  466,  466,  466,  467,
+      467,  467,  468,  468,  468,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452,  452,  452,  452,  452,  452,  452,
+      452,  452,  452,  452
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int octave__flex_debug;
+int octave__flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *octave_text;
+#line 1 "lex.l"
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+
+
+
+
+#line 36 "lex.l"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cstring>
+
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <string>
+#include <stack>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "quit.h"
+#include "lo-mappers.h"
+
+// These would be alphabetical, but y.tab.h must be included before
+// oct-gperf.h and y.tab.h must be included after token.h and the tree
+// class declarations.  We can't include y.tab.h in oct-gperf.h
+// because it may not be protected to allow it to be included multiple
+// times.
+
+#include "Cell.h"
+#include "comment-list.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "lex.h"
+#include "ov.h"
+#include "parse.h"
+#include "pt-all.h"
+#include "symtab.h"
+#include "token.h"
+#include "toplev.h"
+#include "utils.h"
+#include "variables.h"
+#include <y.tab.h>
+#include <oct-gperf.h>
+
+#if ! (defined (FLEX_SCANNER) \
+       && defined (YY_FLEX_MAJOR_VERSION) && YY_FLEX_MAJOR_VERSION >= 2 \
+       && defined (YY_FLEX_MINOR_VERSION) && YY_FLEX_MINOR_VERSION >= 5)
+#error lex.l requires flex version 2.5.4 or later
+#endif
+
+#define yylval octave_lval
+
+// Arrange to get input via readline.
+
+#ifdef YY_INPUT
+#undef YY_INPUT
+#endif
+#define YY_INPUT(buf, result, max_size) \
+  if ((result = octave_read (buf, max_size)) < 0) \
+    YY_FATAL_ERROR ("octave_read () in flex scanner failed");
+
+// Try to avoid crashing out completely on fatal scanner errors.
+// The call to yy_fatal_error should never happen, but it avoids a
+// `static function defined but not used' warning from gcc.
+
+#ifdef YY_FATAL_ERROR
+#undef YY_FATAL_ERROR
+#endif
+#define YY_FATAL_ERROR(msg) \
+  do \
+    { \
+      error (msg); \
+      OCTAVE_QUIT; \
+      yy_fatal_error (msg); \
+    } \
+  while (0)
+
+#define DISPLAY_TOK_AND_RETURN(tok) \
+  do \
+    { \
+      int tok_val = tok; \
+      if (Vdisplay_tokens) \
+        display_token (tok_val); \
+      if (lexer_debug_flag) \
+        { \
+	  std::cerr << "R: "; \
+          display_token (tok_val); \
+	  std::cerr << std::endl;  \
+	} \
+      return tok_val; \
+    } \
+  while (0)
+
+#define COUNT_TOK_AND_RETURN(tok) \
+  do \
+    { \
+      Vtoken_count++; \
+      DISPLAY_TOK_AND_RETURN (tok); \
+    } \
+  while (0)
+
+#define TOK_RETURN(tok) \
+  do \
+    { \
+      current_input_column += octave_leng; \
+      lexer_flags.quote_is_transpose = false; \
+      lexer_flags.convert_spaces_to_comma = true; \
+      COUNT_TOK_AND_RETURN (tok); \
+    } \
+  while (0)
+
+#define TOK_PUSH_AND_RETURN(name, tok) \
+  do \
+    { \
+      yylval.tok_val = new token (name, input_line_number, \
+				  current_input_column); \
+      token_stack.push (yylval.tok_val); \
+      TOK_RETURN (tok); \
+    } \
+  while (0)
+
+#define BIN_OP_RETURN(tok, convert, bos) \
+  do \
+    { \
+      yylval.tok_val = new token (input_line_number, current_input_column); \
+      token_stack.push (yylval.tok_val); \
+      current_input_column += octave_leng; \
+      lexer_flags.quote_is_transpose = false; \
+      lexer_flags.convert_spaces_to_comma = convert; \
+      lexer_flags.looking_for_object_index = false; \
+      lexer_flags.at_beginning_of_statement = bos; \
+      COUNT_TOK_AND_RETURN (tok); \
+    } \
+  while (0)
+
+#define XBIN_OP_RETURN(tok, convert, bos) \
+  do \
+    { \
+      gripe_matlab_incompatible_operator (octave_text); \
+      BIN_OP_RETURN (tok, convert, bos); \
+    } \
+  while (0)
+
+#define LEXER_DEBUG(pattern) \
+  do \
+    { \
+      if (lexer_debug_flag) \
+        lexer_debug (pattern, octave_text); \
+    } \
+  while (0)
+
+// TRUE means that we have encountered EOF on the input stream.
+bool parser_end_of_input = false;
+
+// Flags that need to be shared between the lexer and parser.
+lexical_feedback lexer_flags;
+
+// Stack to hold tokens so that we can delete them when the parser is
+// reset and avoid growing forever just because we are stashing some
+// information.  This has to appear before lex.h is included, because
+// one of the macros defined there uses token_stack.
+//
+// FIXME -- this should really be static, but that causes
+// problems on some systems.
+std::stack <token*> token_stack;
+
+// Did eat_whitespace() eat a space or tab, or a newline, or both?
+
+typedef int yum_yum;
+
+const yum_yum ATE_NOTHING = 0;
+const yum_yum ATE_SPACE_OR_TAB = 1;
+const yum_yum ATE_NEWLINE = 2;
+
+// Is the closest nesting level a square bracket, squiggly brace or a paren?
+
+class bracket_brace_paren_nesting_level
+{
+public:
+
+  bracket_brace_paren_nesting_level (void) : context () { }
+
+  ~bracket_brace_paren_nesting_level (void) { }
+
+  void bracket (void) { context.push (BRACKET); }
+  bool is_bracket (void)
+    { return ! context.empty () && context.top () == BRACKET; }
+
+  void brace (void) {  context.push (BRACE); }
+  bool is_brace (void)
+    { return ! context.empty () && context.top () == BRACE; }
+
+  void paren (void) {  context.push (PAREN); }
+  bool is_paren (void)
+    { return ! context.empty () && context.top () == PAREN; }
+
+  bool is_bracket_or_brace (void)
+    { return (! context.empty ()
+	      && (context.top () == BRACKET || context.top () == BRACE)); }
+
+  bool none (void) { return context.empty (); }
+
+  void remove (void) { if (! context.empty ()) context.pop (); }
+
+  void clear (void) { while (! context.empty ()) context.pop (); }
+
+private:
+
+  std::stack<int> context;
+
+  static const int BRACKET;
+  static const int BRACE;
+  static const int PAREN;
+
+  bracket_brace_paren_nesting_level (const bracket_brace_paren_nesting_level&);
+
+  bracket_brace_paren_nesting_level&
+  operator = (const bracket_brace_paren_nesting_level&);
+};
+
+const int bracket_brace_paren_nesting_level::BRACKET = 1;
+const int bracket_brace_paren_nesting_level::BRACE = 2;
+const int bracket_brace_paren_nesting_level::PAREN = 3;
+
+static bracket_brace_paren_nesting_level nesting_level;
+
+static bool Vdisplay_tokens = false;
+
+static unsigned int Vtoken_count = 0;
+
+// The start state that was in effect when the beginning of a block
+// comment was noticed.
+static int block_comment_nesting_level = 0;
+
+// Internal variable for lexer debugging state.
+static bool lexer_debug_flag = false;
+
+// Forward declarations for functions defined at the bottom of this
+// file.
+
+static int text_yyinput (void);
+static void xunput (char c, char *buf);
+static void fixup_column_count (char *s);
+static void do_comma_insert_check (void);
+static int is_keyword_token (const std::string& s);
+static void prep_for_function (void);
+static void prep_for_nested_function (void);
+static int process_comment (bool start_in_block, bool& eof);
+static bool match_any (char c, const char *s);
+static bool next_token_is_sep_op (void);
+static bool next_token_is_bin_op (bool spc_prev);
+static bool next_token_is_postfix_unary_op (bool spc_prev);
+static std::string strip_trailing_whitespace (char *s);
+static void handle_number (void);
+static int handle_string (char delim);
+static int handle_close_bracket (bool spc_gobbled, int bracket_type);
+static int handle_identifier (void);
+static bool have_continuation (bool trailing_comments_ok = true);
+static bool have_ellipsis_continuation (bool trailing_comments_ok = true);
+static void scan_for_comments (const char *);
+static yum_yum eat_whitespace (void);
+static yum_yum eat_continuation (void);
+static void maybe_warn_separator_insert (char sep);
+static void gripe_single_quote_string (void);
+static void gripe_matlab_incompatible (const std::string& msg);
+static void maybe_gripe_matlab_incompatible_comment (char c);
+static void gripe_matlab_incompatible_continuation (void);
+static void gripe_matlab_incompatible_operator (const std::string& op);
+static void display_token (int tok);
+static void lexer_debug (const char *pattern, const char *text);
+
+#line 1378 "<stdout>"
+
+#define INITIAL 0
+#define COMMAND_START 1
+#define MATRIX_START 2
+#define SCRIPT_FILE_BEGIN 3
+#define NESTED_FUNCTION_END 4
+#define NESTED_FUNCTION_BEGIN 5
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int octave_lex_destroy (void );
+
+int octave_get_debug (void );
+
+void octave_set_debug (int debug_flag  );
+
+YY_EXTRA_TYPE octave_get_extra (void );
+
+void octave_set_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *octave_get_in (void );
+
+void octave_set_in  (FILE * in_str  );
+
+FILE *octave_get_out (void );
+
+void octave_set_out  (FILE * out_str  );
+
+int octave_get_leng (void );
+
+char *octave_get_text (void );
+
+int octave_get_lineno (void );
+
+void octave_set_lineno (int line_number  );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int octave_wrap (void );
+#else
+extern int octave_wrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( octave_text, octave_leng, 1, octave_out )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		int n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( octave_in )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( octave_in ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, octave_in))==0 && ferror(octave_in)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(octave_in); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int octave_lex (void);
+
+#define YY_DECL int octave_lex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after octave_text and octave_leng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( octave_leng > 0 ) \
+		YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+				(octave_text[octave_leng - 1] == '\n'); \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 330 "lex.l"
+
+
+#line 1571 "<stdout>"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! octave_in )
+			octave_in = stdin;
+
+		if ( ! octave_out )
+			octave_out = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			octave_ensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				octave__create_buffer(octave_in,YY_BUF_SIZE );
+		}
+
+		octave__load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of octave_text. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 453 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 2036 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 332 "lex.l"
+{
+    LEXER_DEBUG ("<SCRIPT_FILE_BEGIN>.");
+
+    BEGIN (INITIAL);
+    xunput (octave_text[0], octave_text);
+    COUNT_TOK_AND_RETURN (SCRIPT);
+  }
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 340 "lex.l"
+{
+    LEXER_DEBUG ("<NESTED_FUNCTION_END>.");
+
+    BEGIN (NESTED_FUNCTION_BEGIN);
+    xunput (octave_text[0], octave_text);
+
+    lexer_flags.at_beginning_of_statement = true;
+
+    COUNT_TOK_AND_RETURN (';');
+  }
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 351 "lex.l"
+{
+    LEXER_DEBUG ("<NESTED_FUNCTION_BEGIN>.");
+
+    BEGIN (INITIAL);
+    xunput (octave_text[0], octave_text);
+
+    prep_for_nested_function ();
+
+    COUNT_TOK_AND_RETURN (FCN);
+  }
+	YY_BREAK
+
+// Help and other command-style functions.
+
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+#line 366 "lex.l"
+{
+    LEXER_DEBUG ("<COMMAND_START>{NL}");
+
+    BEGIN (INITIAL);
+    input_line_number++;
+    current_input_column = 1;
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = true;
+
+    COUNT_TOK_AND_RETURN ('\n');
+  }
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 381 "lex.l"
+{
+    LEXER_DEBUG ("<COMMAND_START>[\\;\\,]");
+
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = true;
+
+    BEGIN (INITIAL);
+
+    if (strcmp (octave_text, ",") == 0)
+      TOK_RETURN (',');
+    else
+      TOK_RETURN (';');
+  }
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 395 "lex.l"
+{
+    LEXER_DEBUG ("<COMMAND_START>[\\\"\\']");
+
+    lexer_flags.at_beginning_of_statement = false;
+
+    current_input_column++;
+    int tok = handle_string (octave_text[0]);
+
+    COUNT_TOK_AND_RETURN (tok);
+  }
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 406 "lex.l"
+{
+    LEXER_DEBUG ("<COMMAND_START>[^#% \\t\\r\\n\\;\\,\\\"\\'][^ \\t\\r\\n\\;\\,]*{S}*");
+
+    std::string tok = strip_trailing_whitespace (octave_text);
+
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    TOK_PUSH_AND_RETURN (tok, SQ_STRING);
+  }
+	YY_BREAK
+
+// For this and the next two rules, we're looking at ']', and we
+// need to know if the next token is `=' or `=='.
+//
+// It would have been so much easier if the delimiters were simply
+// different for the expression on the left hand side of the equals
+// operator.
+//
+// It's also a pain in the ass to decide whether to insert a comma
+// after seeing a ']' character...
+
+// FIXME -- we need to handle block comments here.
+
+case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+#line 431 "lex.l"
+{
+    LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*\\]{S}*");
+
+    scan_for_comments (octave_text);
+    fixup_column_count (octave_text);
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    int c = octave_text[octave_leng-1];
+    int cont_is_spc = eat_continuation ();
+    bool spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
+    int tok_to_return = handle_close_bracket (spc_gobbled, ']');
+
+    if (spc_gobbled)
+      xunput (' ', octave_text);
+
+    COUNT_TOK_AND_RETURN (tok_to_return);
+  }
+	YY_BREAK
+
+// FIXME -- we need to handle block comments here.
+
+case 9:
+/* rule 9 can match eol */
+YY_RULE_SETUP
+#line 457 "lex.l"
+{
+    LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*\\}{S}*");
+
+    scan_for_comments (octave_text);
+    fixup_column_count (octave_text);
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    int c = octave_text[octave_leng-1];
+    int cont_is_spc = eat_continuation ();
+    bool spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
+    int tok_to_return = handle_close_bracket (spc_gobbled, '}');
+
+    if (spc_gobbled)
+      xunput (' ', octave_text);
+
+    COUNT_TOK_AND_RETURN (tok_to_return);
+  }
+	YY_BREAK
+
+// Commas are element separators in matrix constants.  If we don't
+// check for continuations here we can end up inserting too many
+// commas.
+
+case 10:
+YY_RULE_SETUP
+#line 485 "lex.l"
+{
+    LEXER_DEBUG ("<MATRIX_START>{S}*\\,{S}*");
+
+    current_input_column += octave_leng;
+
+    int tmp = eat_continuation ();
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    if (! lexer_flags.looking_at_object_index.front ())
+      {
+	if ((tmp & ATE_NEWLINE) == ATE_NEWLINE)
+	  {
+	    maybe_warn_separator_insert (';');
+
+	    xunput (';', octave_text);
+	  }
+      }
+
+    COUNT_TOK_AND_RETURN (',');
+  }
+	YY_BREAK
+
+// In some cases, spaces in matrix constants can turn into commas.
+// If commas are required, spaces are not important in matrix
+// constants so we just eat them.  If we don't check for continuations
+// here we can end up inserting too many commas.
+
+case 11:
+YY_RULE_SETUP
+#line 517 "lex.l"
+{
+    LEXER_DEBUG ("<MATRIX_START>{S}+");
+
+    current_input_column += octave_leng;
+
+    lexer_flags.at_beginning_of_statement = false;
+
+    int tmp = eat_continuation ();
+
+    if (! lexer_flags.looking_at_object_index.front ())
+      {
+	bool bin_op = next_token_is_bin_op (true);
+	bool postfix_un_op = next_token_is_postfix_unary_op (true);
+	bool sep_op = next_token_is_sep_op ();
+
+	if (! (postfix_un_op || bin_op || sep_op)
+	    && nesting_level.is_bracket_or_brace ()
+	    && lexer_flags.convert_spaces_to_comma)
+	  {
+	    if ((tmp & ATE_NEWLINE) == ATE_NEWLINE)
+	      {
+		maybe_warn_separator_insert (';');
+
+		xunput (';', octave_text);
+	      }
+
+	    lexer_flags.quote_is_transpose = false;
+	    lexer_flags.convert_spaces_to_comma = true;
+
+	    maybe_warn_separator_insert (',');
+
+	    COUNT_TOK_AND_RETURN (',');
+	  }
+      }
+  }
+	YY_BREAK
+
+// Semicolons are handled as row seprators in matrix constants.  If we
+// don't eat whitespace here we can end up inserting too many
+// semicolons.
+
+// FIXME -- we need to handle block comments here.
+
+case 12:
+/* rule 12 can match eol */
+YY_RULE_SETUP
+#line 561 "lex.l"
+{
+    LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*;{SNLCMT}*");
+
+    scan_for_comments (octave_text);
+    fixup_column_count (octave_text);
+    eat_whitespace ();
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    COUNT_TOK_AND_RETURN (';');
+  }
+	YY_BREAK
+
+// In some cases, new lines can also become row separators.  If we
+// don't eat whitespace here we can end up inserting too many
+// semicolons.
+
+// FIXME -- we need to handle block comments here.
+
+case 13:
+/* rule 13 can match eol */
+#line 585 "lex.l"
+case 14:
+/* rule 14 can match eol */
+YY_RULE_SETUP
+#line 585 "lex.l"
+{
+    LEXER_DEBUG ("<MATRIX_START>{S}*{COMMENT}{SNLCMT}*|<MATRIX_START>{S}*{NL}{SNLCMT}*");
+
+    scan_for_comments (octave_text);
+    fixup_column_count (octave_text);
+    eat_whitespace ();
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    if (nesting_level.none ())
+      return LEXICAL_ERROR;
+
+    if (! lexer_flags.looking_at_object_index.front ()
+	&& nesting_level.is_bracket_or_brace ())
+      {
+	maybe_warn_separator_insert (';');
+
+	COUNT_TOK_AND_RETURN (';');
+      }
+  }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 608 "lex.l"
+{
+    LEXER_DEBUG ("\\[{S}*");
+
+    nesting_level.bracket ();
+
+    lexer_flags.looking_at_object_index.push_front (false);
+
+    current_input_column += octave_leng;
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    if (lexer_flags.defining_func && ! lexer_flags.parsed_function_name)
+      lexer_flags.looking_at_return_list = true;
+    else
+      lexer_flags.looking_at_matrix_or_assign_lhs = true;
+
+    promptflag--;
+    eat_whitespace ();
+
+    lexer_flags.bracketflag++;
+    BEGIN (MATRIX_START);
+    COUNT_TOK_AND_RETURN ('[');
+  }
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 634 "lex.l"
+{
+    LEXER_DEBUG ("\\]");
+
+    nesting_level.remove ();
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    TOK_RETURN (']');
+  }
+	YY_BREAK
+
+// Imaginary numbers.
+
+case 17:
+YY_RULE_SETUP
+#line 651 "lex.l"
+{
+    LEXER_DEBUG ("{NUMBER}{Im}");
+
+    handle_number ();
+    COUNT_TOK_AND_RETURN (IMAG_NUM);
+  }
+	YY_BREAK
+
+// Real numbers.  Don't grab the `.' part of a dot operator as part of
+// the constant.
+
+case 18:
+*yy_cp = (yy_hold_char); /* undo effects of setting up octave_text */
+(yy_c_buf_p) = yy_cp -= 2;
+YY_DO_BEFORE_ACTION; /* set up octave_text again */
+#line 664 "lex.l"
+case 19:
+YY_RULE_SETUP
+#line 664 "lex.l"
+{
+    LEXER_DEBUG ("{D}+/\\.[\\*/\\^\\']|{NUMBER}");
+    handle_number ();
+    COUNT_TOK_AND_RETURN (NUM);
+  }
+	YY_BREAK
+
+// Eat whitespace.  Whitespace inside matrix constants is handled by
+// the <MATRIX_START> start state code above.
+
+case 20:
+YY_RULE_SETUP
+#line 675 "lex.l"
+{
+    current_input_column += octave_leng;
+  }
+	YY_BREAK
+
+// Continuation lines.  Allow comments after continuations.
+
+case 21:
+/* rule 21 can match eol */
+#line 684 "lex.l"
+case 22:
+/* rule 22 can match eol */
+YY_RULE_SETUP
+#line 684 "lex.l"
+{
+    LEXER_DEBUG ("{CONT}{S}*{NL}|{CONT}{S}*{COMMENT}");
+
+    if (octave_text[0] == '\\')
+      gripe_matlab_incompatible_continuation ();
+    scan_for_comments (octave_text);
+    promptflag--;
+    input_line_number++;
+    current_input_column = 1;
+  }
+	YY_BREAK
+
+// End of file.
+
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(COMMAND_START):
+case YY_STATE_EOF(MATRIX_START):
+case YY_STATE_EOF(SCRIPT_FILE_BEGIN):
+case YY_STATE_EOF(NESTED_FUNCTION_END):
+case YY_STATE_EOF(NESTED_FUNCTION_BEGIN):
+#line 699 "lex.l"
+{
+    LEXER_DEBUG ("<<EOF>>");
+
+    if (block_comment_nesting_level != 0)
+      {
+	warning ("block comment open at end of input");
+
+	if ((reading_fcn_file || reading_script_file)
+	    && ! curr_fcn_file_name.empty ())
+	  warning ("near line %d of file `%s.m'",
+		   input_line_number, curr_fcn_file_name.c_str ());
+      }
+
+    TOK_RETURN (END_OF_INPUT);
+  }
+	YY_BREAK
+
+// Identifiers.  Truncate the token at the first space or tab but
+// don't write directly on octave_text.
+
+case 23:
+YY_RULE_SETUP
+#line 720 "lex.l"
+{
+    LEXER_DEBUG ("{IDENT}{S}*");
+
+    int id_tok = handle_identifier ();
+
+    if (id_tok >= 0)
+      COUNT_TOK_AND_RETURN (id_tok);
+  }
+	YY_BREAK
+
+// Function handles.
+
+case 24:
+YY_RULE_SETUP
+#line 733 "lex.l"
+{
+    LEXER_DEBUG ("@");
+
+    current_input_column++;
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = false;
+    lexer_flags.looking_at_function_handle++;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    COUNT_TOK_AND_RETURN ('@');
+  }
+	YY_BREAK
+
+// A new line character.  New line characters inside matrix constants
+// are handled by the <MATRIX_START> start state code above.  If closest
+// nesting is inside parentheses, don't return a row separator.
+
+case 25:
+/* rule 25 can match eol */
+YY_RULE_SETUP
+#line 753 "lex.l"
+{
+    LEXER_DEBUG ("{NL}");
+
+    input_line_number++;
+    current_input_column = 1;
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+
+    if (nesting_level.none ())
+      {
+	lexer_flags.at_beginning_of_statement = true;
+	COUNT_TOK_AND_RETURN ('\n');
+      }
+    else if (nesting_level.is_paren ())
+      {
+	lexer_flags.at_beginning_of_statement = false;
+	gripe_matlab_incompatible ("bare newline inside parentheses");
+      }
+    else if (nesting_level.is_bracket_or_brace ())
+      return LEXICAL_ERROR;
+  }
+	YY_BREAK
+
+// Single quote can either be the beginning of a string or a transpose
+// operator. 
+
+case 26:
+YY_RULE_SETUP
+#line 781 "lex.l"
+{
+    LEXER_DEBUG ("'");
+
+    current_input_column++;
+    lexer_flags.convert_spaces_to_comma = true;
+
+    if (lexer_flags.quote_is_transpose)
+      {
+	do_comma_insert_check ();
+	COUNT_TOK_AND_RETURN (QUOTE);
+      }
+    else
+      {
+	int tok = handle_string ('\'');
+	COUNT_TOK_AND_RETURN (tok);
+      }
+  }
+	YY_BREAK
+
+// Double quotes always begin strings.
+
+case 27:
+YY_RULE_SETUP
+#line 803 "lex.l"
+{
+    LEXER_DEBUG ("\"");
+
+    current_input_column++;
+    int tok = handle_string ('"');
+
+    COUNT_TOK_AND_RETURN (tok);
+}
+	YY_BREAK
+
+// Gobble comments.
+
+case 28:
+YY_RULE_SETUP
+#line 816 "lex.l"
+{
+    LEXER_DEBUG ("{CCHAR}");
+
+    lexer_flags.looking_for_object_index = false;
+
+    xunput (octave_text[0], octave_text);
+
+    bool eof = false;
+    int tok = process_comment (false, eof);
+
+    if (eof)
+      TOK_RETURN (END_OF_INPUT);
+    else if (tok > 0)
+      COUNT_TOK_AND_RETURN (tok);
+  }
+	YY_BREAK
+
+// Block comments.
+
+case 29:
+/* rule 29 can match eol */
+YY_RULE_SETUP
+#line 836 "lex.l"
+{
+    LEXER_DEBUG ("^{S}*{CCHAR}\\{{S}*{NL}");
+
+    lexer_flags.looking_for_object_index = false;
+
+    input_line_number++;
+    current_input_column = 1;
+    block_comment_nesting_level++;
+    promptflag--;
+
+    bool eof = false;
+    process_comment (true, eof);
+  }
+	YY_BREAK
+
+// Other operators.
+
+case 30:
+YY_RULE_SETUP
+#line 854 "lex.l"
+{ LEXER_DEBUG (":"); BIN_OP_RETURN (':', false, false); }
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 856 "lex.l"
+{ LEXER_DEBUG (".+"); XBIN_OP_RETURN (EPLUS, false, false); }
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 857 "lex.l"
+{ LEXER_DEBUG (".-"); XBIN_OP_RETURN (EMINUS, false, false); }
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 858 "lex.l"
+{ LEXER_DEBUG (".*"); BIN_OP_RETURN (EMUL, false, false); }
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 859 "lex.l"
+{ LEXER_DEBUG ("./"); BIN_OP_RETURN (EDIV, false, false); }
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 860 "lex.l"
+{ LEXER_DEBUG (".\\"); BIN_OP_RETURN (ELEFTDIV, false, false); }
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 861 "lex.l"
+{ LEXER_DEBUG (".^"); BIN_OP_RETURN (EPOW, false, false); }
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 862 "lex.l"
+{ LEXER_DEBUG (".**"); XBIN_OP_RETURN (EPOW, false, false); }
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 863 "lex.l"
+{ LEXER_DEBUG (".'"); do_comma_insert_check (); BIN_OP_RETURN (TRANSPOSE, true, false); }
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 864 "lex.l"
+{ LEXER_DEBUG ("++"); do_comma_insert_check (); XBIN_OP_RETURN (PLUS_PLUS, true, false); }
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 865 "lex.l"
+{ LEXER_DEBUG ("--"); do_comma_insert_check (); XBIN_OP_RETURN (MINUS_MINUS, true, false); }
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 866 "lex.l"
+{ LEXER_DEBUG ("<="); BIN_OP_RETURN (EXPR_LE, false, false); }
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 867 "lex.l"
+{ LEXER_DEBUG ("=="); BIN_OP_RETURN (EXPR_EQ, false, false); }
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 868 "lex.l"
+{ LEXER_DEBUG ("~="); BIN_OP_RETURN (EXPR_NE, false, false); }
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 869 "lex.l"
+{ LEXER_DEBUG ("!="); XBIN_OP_RETURN (EXPR_NE, false, false); }
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 870 "lex.l"
+{ LEXER_DEBUG (">="); BIN_OP_RETURN (EXPR_GE, false, false); }
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 871 "lex.l"
+{ LEXER_DEBUG ("&"); BIN_OP_RETURN (EXPR_AND, false, false); }
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 872 "lex.l"
+{ LEXER_DEBUG ("|"); BIN_OP_RETURN (EXPR_OR, false, false); }
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 873 "lex.l"
+{ LEXER_DEBUG ("<"); BIN_OP_RETURN (EXPR_LT, false, false); }
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 874 "lex.l"
+{ LEXER_DEBUG (">"); BIN_OP_RETURN (EXPR_GT, false, false); }
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 875 "lex.l"
+{ LEXER_DEBUG ("+"); BIN_OP_RETURN ('+', false, false); }
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 876 "lex.l"
+{ LEXER_DEBUG ("-"); BIN_OP_RETURN ('-', false, false); }
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 877 "lex.l"
+{ LEXER_DEBUG ("*"); BIN_OP_RETURN ('*', false, false); }
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 878 "lex.l"
+{ LEXER_DEBUG ("/"); BIN_OP_RETURN ('/', false, false); }
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 879 "lex.l"
+{ LEXER_DEBUG ("\\"); BIN_OP_RETURN (LEFTDIV, false, false); }
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 880 "lex.l"
+{ LEXER_DEBUG (";"); BIN_OP_RETURN (';', true, true); }
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 881 "lex.l"
+{ LEXER_DEBUG (","); BIN_OP_RETURN (',', true, ! lexer_flags.looking_at_object_index.front ()); }
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 882 "lex.l"
+{ LEXER_DEBUG ("^"); BIN_OP_RETURN (POW, false, false); }
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 883 "lex.l"
+{ LEXER_DEBUG ("**"); XBIN_OP_RETURN (POW, false, false); }
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 884 "lex.l"
+{ LEXER_DEBUG ("="); BIN_OP_RETURN ('=', true, false); }
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 885 "lex.l"
+{ LEXER_DEBUG ("&&"); BIN_OP_RETURN (EXPR_AND_AND, false, false); }
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 886 "lex.l"
+{ LEXER_DEBUG ("||"); BIN_OP_RETURN (EXPR_OR_OR, false, false); }
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 887 "lex.l"
+{ LEXER_DEBUG ("<<"); XBIN_OP_RETURN (LSHIFT, false, false); }
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 888 "lex.l"
+{ LEXER_DEBUG (">>"); XBIN_OP_RETURN (RSHIFT, false, false); }
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 891 "lex.l"
+{
+    LEXER_DEBUG ("{NOT}");
+
+    if (octave_text[0] == '~')
+      BIN_OP_RETURN (EXPR_NOT, false, false);
+    else
+      XBIN_OP_RETURN (EXPR_NOT, false, false);
+  }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 900 "lex.l"
+{
+    LEXER_DEBUG ("(");
+
+    // If we are looking for an object index, then push TRUE for
+    // looking_at_object_index.  Otherwise, just push whatever state
+    // is current (so that we can pop it off the stack when we find
+    // the matching close paren).
+
+    lexer_flags.looking_at_object_index.push_front
+      (lexer_flags.looking_for_object_index);
+
+    lexer_flags.looking_at_indirect_ref = false;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    nesting_level.paren ();
+    promptflag--;
+
+    TOK_RETURN ('(');
+  }
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 921 "lex.l"
+{
+    LEXER_DEBUG (")");
+
+    nesting_level.remove ();
+    current_input_column++;
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.quote_is_transpose = true;
+    lexer_flags.convert_spaces_to_comma = nesting_level.is_bracket_or_brace ();
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    do_comma_insert_check ();
+
+    COUNT_TOK_AND_RETURN (')');
+  }
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 939 "lex.l"
+{
+    LEXER_DEBUG (".");
+
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    TOK_RETURN ('.');
+  }
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 948 "lex.l"
+{ LEXER_DEBUG ("+="); XBIN_OP_RETURN (ADD_EQ, false, false); }
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 949 "lex.l"
+{ LEXER_DEBUG ("-="); XBIN_OP_RETURN (SUB_EQ, false, false); }
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 950 "lex.l"
+{ LEXER_DEBUG ("*="); XBIN_OP_RETURN (MUL_EQ, false, false); }
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 951 "lex.l"
+{ LEXER_DEBUG ("/="); XBIN_OP_RETURN (DIV_EQ, false, false); }
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 952 "lex.l"
+{ LEXER_DEBUG ("\\="); XBIN_OP_RETURN (LEFTDIV_EQ, false, false); }
+	YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 953 "lex.l"
+{ LEXER_DEBUG (".+="); XBIN_OP_RETURN (ADD_EQ, false, false); }
+	YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 954 "lex.l"
+{ LEXER_DEBUG (".-="); XBIN_OP_RETURN (SUB_EQ, false, false); }
+	YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 955 "lex.l"
+{ LEXER_DEBUG (".*="); XBIN_OP_RETURN (EMUL_EQ, false, false); }
+	YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 956 "lex.l"
+{ LEXER_DEBUG ("./="); XBIN_OP_RETURN (EDIV_EQ, false, false); }
+	YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 957 "lex.l"
+{ LEXER_DEBUG (".\\="); XBIN_OP_RETURN (ELEFTDIV_EQ, false, false); }
+	YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 958 "lex.l"
+{ LEXER_DEBUG ("{POW}="); XBIN_OP_RETURN (POW_EQ, false, false); }
+	YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 959 "lex.l"
+{ LEXER_DEBUG ("{EPOW}="); XBIN_OP_RETURN (EPOW_EQ, false, false); }
+	YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 960 "lex.l"
+{ LEXER_DEBUG ("&="); XBIN_OP_RETURN (AND_EQ, false, false); }
+	YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 961 "lex.l"
+{ LEXER_DEBUG ("|="); XBIN_OP_RETURN (OR_EQ, false, false); }
+	YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 962 "lex.l"
+{ LEXER_DEBUG ("<<="); XBIN_OP_RETURN (LSHIFT_EQ, false, false); }
+	YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 963 "lex.l"
+{ LEXER_DEBUG (">>="); XBIN_OP_RETURN (RSHIFT_EQ, false, false); }
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 965 "lex.l"
+{
+    LEXER_DEBUG ("\\{{S}*");
+
+    nesting_level.brace ();
+
+    lexer_flags.looking_at_object_index.push_front
+      (lexer_flags.looking_for_object_index);
+
+    current_input_column += octave_leng;
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    promptflag--;
+    eat_whitespace ();
+
+    lexer_flags.braceflag++;
+    BEGIN (MATRIX_START);
+    COUNT_TOK_AND_RETURN ('{');
+  }
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 987 "lex.l"
+{
+    LEXER_DEBUG ("}");
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    nesting_level.remove ();
+
+    TOK_RETURN ('}');
+  }
+	YY_BREAK
+
+// Unrecognized input is a lexical error.
+
+case 86:
+YY_RULE_SETUP
+#line 1004 "lex.l"
+{
+    LEXER_DEBUG (".");
+
+    // EOF happens here if we are parsing nested functions.
+
+    xunput (octave_text[0], octave_text);
+
+    int c = text_yyinput ();
+
+    if (c != EOF)
+      {
+	current_input_column++;
+
+	error ("invalid character `%s' (ASCII %d) near line %d, column %d",
+	       undo_string_escape (static_cast<char> (c)), c,
+	       input_line_number, current_input_column);
+
+	return LEXICAL_ERROR;
+      }
+    else
+      TOK_RETURN (END_OF_INPUT);
+  }
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 1027 "lex.l"
+ECHO;
+	YY_BREAK
+#line 2652 "<stdout>"
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed octave_in at a new source and called
+			 * octave_lex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = octave_in;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( octave_wrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * octave_text, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of octave_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					octave_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), (size_t) num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			octave_restart(octave_in  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) octave_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 453 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 453 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 452);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up octave_text */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					octave_restart(octave_in );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( octave_wrap( ) )
+						return EOF;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve octave_text */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void octave_restart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        octave_ensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            octave__create_buffer(octave_in,YY_BUF_SIZE );
+	}
+
+	octave__init_buffer(YY_CURRENT_BUFFER,input_file );
+	octave__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void octave__switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		octave_pop_buffer_state();
+	 *		octave_push_buffer_state(new_buffer);
+     */
+	octave_ensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	octave__load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (octave_wrap()) processing, but the only time this flag
+	 * is looked at is after octave_wrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void octave__load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	octave_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE octave__create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) octave_alloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in octave__create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) octave_alloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in octave__create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	octave__init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with octave__create_buffer()
+ * 
+ */
+    void octave__delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		octave_free((void *) b->yy_ch_buf  );
+
+	octave_free((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a octave_restart() or at EOF.
+ */
+    static void octave__init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	octave__flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then octave__init_buffer was _probably_
+     * called from octave_restart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void octave__flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		octave__load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void octave_push_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	octave_ensure_buffer_stack();
+
+	/* This block is copied from octave__switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from octave__switch_to_buffer. */
+	octave__load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void octave_pop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	octave__delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		octave__load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void octave_ensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)octave_alloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in octave_ensure_buffer_stack()" );
+								  
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)octave_realloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in octave_ensure_buffer_stack()" );
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE octave__scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) octave_alloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in octave__scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	octave__switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to octave_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       octave__scan_bytes() instead.
+ */
+YY_BUFFER_STATE octave__scan_string (yyconst char * yystr )
+{
+    
+	return octave__scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to octave_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE octave__scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) octave_alloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in octave__scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = octave__scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in octave__scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up octave_text. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		octave_text[octave_leng] = (yy_hold_char); \
+		(yy_c_buf_p) = octave_text + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		octave_leng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int octave_get_lineno  (void)
+{
+        
+    return octave_lineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *octave_get_in  (void)
+{
+        return octave_in;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *octave_get_out  (void)
+{
+        return octave_out;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int octave_get_leng  (void)
+{
+        return octave_leng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *octave_get_text  (void)
+{
+        return octave_text;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void octave_set_lineno (int  line_number )
+{
+    
+    octave_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see octave__switch_to_buffer
+ */
+void octave_set_in (FILE *  in_str )
+{
+        octave_in = in_str ;
+}
+
+void octave_set_out (FILE *  out_str )
+{
+        octave_out = out_str ;
+}
+
+int octave_get_debug  (void)
+{
+        return octave__flex_debug;
+}
+
+void octave_set_debug (int  bdebug )
+{
+        octave__flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from octave_lex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    octave_in = stdin;
+    octave_out = stdout;
+#else
+    octave_in = (FILE *) 0;
+    octave_out = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * octave_lex_init()
+     */
+    return 0;
+}
+
+/* octave_lex_destroy is for both reentrant and non-reentrant scanners. */
+int octave_lex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		octave__delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		octave_pop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	octave_free((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * octave_lex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *octave_alloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *octave_realloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void octave_free (void * ptr )
+{
+	free( (char *) ptr );	/* see octave_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 1027 "lex.l"
+
+
+
+// GAG.
+//
+// If we're reading a matrix and the next character is '[', make sure
+// that we insert a comma ahead of it.
+
+void
+do_comma_insert_check (void)
+{
+  int spc_gobbled = eat_continuation ();
+
+  int c = text_yyinput ();
+
+  xunput (c, octave_text);
+
+  if (spc_gobbled)
+    xunput (' ', octave_text);
+
+  lexer_flags.do_comma_insert = (! lexer_flags.looking_at_object_index.front ()
+				 && lexer_flags.bracketflag && c == '[');
+}
+
+// Fix things up for errors or interrupts.  The parser is never called
+// recursively, so it is always safe to reinitialize its state before
+// doing any parsing.
+
+void
+reset_parser (void)
+{
+  // Start off on the right foot.
+  BEGIN (INITIAL);
+
+  parser_end_of_input = false;
+  end_tokens_expected = 0;
+
+  while (! symtab_context.empty ())
+    symtab_context.pop ();
+
+  symbol_table::reset_parent_scope ();
+
+  // We do want a prompt by default.
+  promptflag = 1;
+
+  // We are not in a block comment.
+  block_comment_nesting_level = 0;
+
+  // Error may have occurred inside some brackets, braces, or parentheses.
+  nesting_level.clear ();
+
+  // Clear out the stack of token info used to track line and column
+  // numbers.
+  while (! token_stack.empty ())
+    {
+      delete token_stack.top ();
+      token_stack.pop ();
+    }
+
+  // Can be reset by defining a function.
+  if (! (reading_script_file || reading_fcn_file))
+    {
+      current_input_column = 1;
+      input_line_number = command_editor::current_command_number ();
+    }
+
+  // Only ask for input from stdin if we are expecting interactive
+  // input.
+  if ((interactive || forced_interactive)
+      && ! (reading_fcn_file
+	    || reading_script_file
+	    || get_input_from_eval_string
+	    || input_from_startup_file))
+    octave_restart (stdin);
+
+  // Clear the buffer for help text.
+  while (! help_buf.empty ())
+    help_buf.pop ();
+
+  // Reset other flags.
+  lexer_flags.init ();
+}
+
+static void
+display_character (char c)
+{
+  if (isgraph (c))
+    std::cerr << c;
+  else
+    switch (c)
+      {
+      case 0:
+	std::cerr << "NUL";
+	break;
+
+      case 1:
+	std::cerr << "SOH";
+	break;
+
+      case 2:
+	std::cerr << "STX";
+	break;
+
+      case 3:
+	std::cerr << "ETX";
+	break;
+
+      case 4:
+	std::cerr << "EOT";
+	break;
+
+      case 5:
+	std::cerr << "ENQ";
+	break;
+
+      case 6:
+	std::cerr << "ACK";
+	break;
+
+      case 7:
+	std::cerr << "\\a";
+	break;
+
+      case 8:
+	std::cerr << "\\b";
+	break;
+
+      case 9:
+	std::cerr << "\\t";
+	break;
+
+      case 10:
+	std::cerr << "\\n";
+	break;
+
+      case 11:
+	std::cerr << "\\v";
+	break;
+
+      case 12:
+	std::cerr << "\\f";
+	break;
+
+      case 13:
+	std::cerr << "\\r";
+	break;
+
+      case 14:
+	std::cerr << "SO";
+	break;
+
+      case 15:
+	std::cerr << "SI";
+	break;
+
+      case 16:
+	std::cerr << "DLE";
+	break;
+
+      case 17:
+	std::cerr << "DC1";
+	break;
+
+      case 18:
+	std::cerr << "DC2";
+	break;
+
+      case 19:
+	std::cerr << "DC3";
+	break;
+
+      case 20:
+	std::cerr << "DC4";
+	break;
+
+      case 21:
+	std::cerr << "NAK";
+	break;
+
+      case 22:
+	std::cerr << "SYN";
+	break;
+
+      case 23:
+	std::cerr << "ETB";
+	break;
+
+      case 24:
+	std::cerr << "CAN";
+	break;
+
+      case 25:
+	std::cerr << "EM";
+	break;
+
+      case 26:
+	std::cerr << "SUB";
+	break;
+
+      case 27:
+	std::cerr << "ESC";
+	break;
+
+      case 28:
+	std::cerr << "FS";
+	break;
+
+      case 29:
+	std::cerr << "GS";
+	break;
+
+      case 30:
+	std::cerr << "RS";
+	break;
+
+      case 31:
+	std::cerr << "US";
+	break;
+
+      case 32:
+	std::cerr << "SPACE";
+	break;
+
+      case 127:
+	std::cerr << "DEL";
+	break;
+      }
+}
+
+static int
+text_yyinput (void)
+{
+  int c = yyinput ();
+
+  if (lexer_debug_flag)
+    {
+      std::cerr << "I: ";
+      display_character (c);
+      std::cerr << std::endl;
+    }
+
+  // Convert CRLF into just LF and single CR into LF.
+
+  if (c == '\r')
+    {
+      c = yyinput ();
+
+      if (lexer_debug_flag)
+	{
+	  std::cerr << "I: ";
+	  display_character (c);
+	  std::cerr << std::endl;
+	}
+
+      if (c != '\n')
+	{
+	  xunput (c, octave_text);
+	  c = '\n';
+	}
+    }
+
+  if (c == '\n')
+    input_line_number++;
+
+  return c;
+}
+
+static void
+xunput (char c, char *buf)
+{
+  if (lexer_debug_flag)
+    {
+      std::cerr << "U: ";
+      display_character (c);
+      std::cerr << std::endl;
+    }
+
+  if (c == '\n')
+    input_line_number--;
+
+  yyunput (c, buf);
+}
+
+// If we read some newlines, we need figure out what column we're
+// really looking at.
+
+static void
+fixup_column_count (char *s)
+{
+  char c;
+  while ((c = *s++) != '\0')
+    {
+      if (c == '\n')
+        {
+          input_line_number++;
+          current_input_column = 1;
+        }
+      else
+	current_input_column++;
+    }
+}
+
+// Include these so that we don't have to link to libfl.a.
+
+int
+octave_wrap (void)
+{
+  return 1;
+}
+
+// Tell us all what the current buffer is.
+
+YY_BUFFER_STATE
+current_buffer (void)
+{
+  return YY_CURRENT_BUFFER;
+}
+
+// Create a new buffer.
+
+YY_BUFFER_STATE
+create_buffer (FILE *f)
+{
+  return octave__create_buffer (f, YY_BUF_SIZE);
+}
+
+// Start reading a new buffer.
+
+void
+switch_to_buffer (YY_BUFFER_STATE buf)
+{
+  octave__switch_to_buffer (buf);
+}
+
+// Delete a buffer.
+
+void
+delete_buffer (YY_BUFFER_STATE buf)
+{
+  octave__delete_buffer (buf);
+}
+
+// Restore a buffer (for unwind-prot).
+
+void
+restore_input_buffer (void *buf)
+{
+  switch_to_buffer (static_cast<YY_BUFFER_STATE> (buf));
+}
+
+// Delete a buffer (for unwind-prot).
+
+void
+delete_input_buffer (void *buf)
+{
+  delete_buffer (static_cast<YY_BUFFER_STATE> (buf));
+}
+
+static void
+prep_for_function (void)
+{
+  end_tokens_expected++;
+
+  promptflag--;
+
+  lexer_flags.defining_func = true;
+  lexer_flags.parsed_function_name = false;
+
+  if (! (reading_fcn_file || reading_script_file))
+    input_line_number = 1;
+}
+
+static void
+prep_for_nested_function (void)
+{
+  lexer_flags.parsing_nested_function = 1;
+  help_buf.push (std::string ());
+  prep_for_function ();
+  // We're still only expecting one end token for this set of functions.
+  end_tokens_expected--;
+  yylval.tok_val = new token (input_line_number, current_input_column);
+  token_stack.push (yylval.tok_val);
+}
+
+static bool
+inside_any_object_index (void)
+{
+  bool retval = false;
+
+  for (std::list<bool>::const_iterator i = lexer_flags.looking_at_object_index.begin ();
+       i != lexer_flags.looking_at_object_index.end (); i++)
+    {
+      if (*i)
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+// Handle keywords.  Return -1 if the keyword should be ignored.
+
+static int
+is_keyword_token (const std::string& s)
+{
+  int l = input_line_number;
+  int c = current_input_column;
+
+  int len = s.length ();
+
+  const octave_kw *kw = octave_kw_hash::in_word_set (s.c_str (), len);
+
+  if (kw)
+    {
+      yylval.tok_val = 0;
+
+      switch (kw->kw_id)
+	{
+	case break_kw:
+	case catch_kw:
+	case continue_kw:
+	case else_kw:
+	case otherwise_kw:
+	case return_kw:
+	case unwind_protect_cleanup_kw:
+	  lexer_flags.at_beginning_of_statement = true;
+	  break;
+
+	case case_kw:
+	case elseif_kw:
+	case global_kw:
+	case static_kw:
+	case until_kw:
+	  break;
+
+	case end_kw:
+	  if (inside_any_object_index ()
+	      || (lexer_flags.defining_func
+		  && ! (lexer_flags.looking_at_return_list
+			|| lexer_flags.parsed_function_name)))
+	    return 0;
+	  else
+	    {
+	      if (reading_fcn_file && end_tokens_expected == 1)
+		return -1;
+	      else
+		{
+		  yylval.tok_val = new token (token::simple_end, l, c);
+		  lexer_flags.at_beginning_of_statement = true;
+		  end_tokens_expected--;
+		}
+	    }
+	  break;
+
+	case end_try_catch_kw:
+	  yylval.tok_val = new token (token::try_catch_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case end_unwind_protect_kw:
+	  yylval.tok_val = new token (token::unwind_protect_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endfor_kw:
+	  yylval.tok_val = new token (token::for_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endfunction_kw:
+	  {
+	    if (reading_fcn_file && end_tokens_expected == 1)
+	      return -1;
+	    else
+	      {
+		yylval.tok_val = new token (token::function_end, l, c);
+		lexer_flags.at_beginning_of_statement = true;
+		end_tokens_expected--;
+	      }
+	  }
+	  break;
+
+	case endif_kw:
+	  yylval.tok_val = new token (token::if_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endswitch_kw:
+	  yylval.tok_val = new token (token::switch_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endwhile_kw:
+	  yylval.tok_val = new token (token::while_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case for_kw:
+	case while_kw:
+	  end_tokens_expected++;
+	  promptflag--;
+	  lexer_flags.looping++;
+	  break;
+
+	case do_kw:
+	  lexer_flags.at_beginning_of_statement = true;
+	  promptflag--;
+	  lexer_flags.looping++;
+	  break;
+
+	case try_kw:
+	case unwind_protect_kw:
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected++;
+	  promptflag--;
+	  break;
+
+	case if_kw:
+	case switch_kw:
+	  end_tokens_expected++;
+	  promptflag--;
+	  break;
+
+	case function_kw:
+	  {
+	    if (lexer_flags.defining_func)
+	      {
+		if (reading_fcn_file)
+		  {
+		    if (lexer_flags.parsing_nested_function)
+		      {
+			BEGIN (NESTED_FUNCTION_END);
+
+			yylval.tok_val = new token (token::function_end, l, c);
+			token_stack.push (yylval.tok_val);
+
+			lexer_flags.at_beginning_of_statement = true;
+
+			return END;
+		      }
+		    else
+		      {
+			prep_for_nested_function ();
+
+			return FCN;
+		      }
+		  }
+		else
+		  {
+		    error ("nested functions not implemented in this context");
+
+		    if ((reading_fcn_file || reading_script_file)
+			&& ! curr_fcn_file_name.empty ())
+		      error ("near line %d of file `%s.m'",
+			     input_line_number, curr_fcn_file_name.c_str ());
+		    else
+		      error ("near line %d", input_line_number);
+
+		    return LEXICAL_ERROR;
+		  }
+	      }
+	    else
+	      prep_for_function ();
+	  }
+	  break;
+
+        case magic_file_kw:
+	  {
+	    if ((reading_fcn_file || reading_script_file)
+		&& ! curr_fcn_file_full_name.empty ())
+	      yylval.tok_val = new token (curr_fcn_file_full_name, l, c);
+	    else
+	      yylval.tok_val = new token ("stdin", l, c);
+	  }
+	  break;
+
+        case magic_line_kw:
+	  yylval.tok_val = new token (static_cast<double> (l), "", l, c);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+
+      if (! yylval.tok_val)
+	yylval.tok_val = new token (l, c);
+
+      token_stack.push (yylval.tok_val);
+
+      return kw->tok;
+    }
+
+  return 0;
+}
+
+static bool
+is_variable (const std::string& name)
+{
+  return (symbol_table::is_variable (name)
+	  || (lexer_flags.pending_local_variables.find (name)
+	      != lexer_flags.pending_local_variables.end ()));
+}
+
+static std::string
+grab_block_comment (stream_reader& reader, bool& eof)
+{
+  std::string buf;
+
+  bool at_bol = true;
+  bool look_for_marker = false;
+
+  bool warned_incompatible = false;
+
+  int c = 0;
+
+  while ((c = reader.getc ()) != EOF)
+    {
+      current_input_column++;
+
+      if (look_for_marker)
+	{
+	  at_bol = false;
+	  look_for_marker = false;
+
+	  if (c == '{' || c == '}')
+	    {
+	      std::string tmp_buf (1, static_cast<char> (c));
+
+	      int type = c;
+
+	      bool done = false;
+
+	      while ((c = reader.getc ()) != EOF && ! done)
+		{
+		  current_input_column++;
+
+		  switch (c)
+		    {
+		    case ' ':
+		    case '\t':
+		      tmp_buf += static_cast<char> (c);
+		      break;
+
+		    case '\n':
+		      {
+			current_input_column = 0;
+			at_bol = true;
+			done = true;
+
+			if (type == '{')
+			  {
+			    block_comment_nesting_level++;
+			    promptflag--;
+			  }
+			else
+			  {
+			    block_comment_nesting_level--;
+			    promptflag++;
+
+			    if (block_comment_nesting_level == 0)
+			      {
+				buf += grab_comment_block (reader, true, eof);
+
+				return buf;
+			      }
+			  }
+		      }
+		      break;
+
+		    default:
+		      at_bol = false;
+		      tmp_buf += static_cast<char> (c);
+		      buf += tmp_buf;
+		      done = true;
+		      break;
+		    }
+		}
+	    }
+	}
+
+      if (at_bol && (c == '%' || c == '#'))
+        {
+          if (c == '#' && ! warned_incompatible)
+	    {
+	      warned_incompatible = true;
+	      maybe_gripe_matlab_incompatible_comment (c);
+	    }
+
+	  at_bol = false;
+	  look_for_marker = true;
+	}
+      else
+	{
+	  buf += static_cast<char> (c);
+
+	  if (c == '\n')
+	    {
+	      current_input_column = 0;
+	      at_bol = true;
+	    }
+	}
+    }
+
+  if (c == EOF)
+    eof = true;
+
+  return buf;
+}
+
+std::string
+grab_comment_block (stream_reader& reader, bool at_bol,
+		    bool& eof)
+{
+  std::string buf;
+
+  // TRUE means we are at the beginning of a comment block.
+  bool begin_comment = false;
+
+  // TRUE means we are currently reading a comment block.
+  bool in_comment = false;
+
+  bool warned_incompatible = false;
+
+  int c = 0;
+
+  while ((c = reader.getc ()) != EOF)
+    {
+      current_input_column++;
+
+      if (begin_comment)
+	{
+	  if (c == '%' || c == '#')
+	    {
+	      at_bol = false;
+	      continue;
+	    }
+	  else if (at_bol && c == '{')
+	    {
+	      std::string tmp_buf (1, static_cast<char> (c));
+
+	      bool done = false;
+
+	      while ((c = reader.getc ()) != EOF && ! done)
+		{
+		  current_input_column++;
+
+		  switch (c)
+		    {
+		    case ' ':
+		    case '\t':
+		      tmp_buf += static_cast<char> (c);
+		      break;
+
+		    case '\n':
+		      {
+			current_input_column = 0;
+			at_bol = true;
+			done = true;
+
+			block_comment_nesting_level++;
+			promptflag--;
+
+			buf += grab_block_comment (reader, eof);
+
+			in_comment = false;
+
+			if (eof)
+			  goto done;
+		      }
+		      break;
+
+		    default:
+		      at_bol = false;
+		      tmp_buf += static_cast<char> (c);
+		      buf += tmp_buf;
+		      done = true;
+		      break;
+		    }
+		}
+	    }
+	  else
+	    {
+	      at_bol = false;
+	      begin_comment = false;
+	    }
+	}	
+
+      if (in_comment)
+	{
+	  buf += static_cast<char> (c);
+
+	  if (c == '\n')
+	    {
+	      at_bol = true;
+	      current_input_column = 0;
+	      in_comment = false;
+
+	      // FIXME -- bailing out here prevents things like
+	      //
+	      //    octave> # comment
+	      //    octave> x = 1
+	      //
+	      // from failing at the command line, while still
+	      // allowing blocks of comments to be grabbed properly
+	      // for function doc strings.  But only the first line of
+	      // a mult-line doc string will be picked up for
+	      // functions defined on the command line.  We need a
+	      // better way of collecting these comments...
+	      if (! (reading_fcn_file || reading_script_file))
+		goto done;
+	    }
+	}
+      else
+	{
+	  switch (c)
+	    {
+	    case ' ':
+	    case '\t':
+	      break;
+
+	    case '#':
+	      if (! warned_incompatible)
+		{
+		  warned_incompatible = true;
+		  maybe_gripe_matlab_incompatible_comment (c);
+		}
+	      // fall through...
+
+	    case '%':
+	      in_comment = true;
+	      begin_comment = true;
+	      break;
+
+	    default:
+	      current_input_column--;
+	      reader.ungetc (c);
+	      goto done;
+	    }
+	}
+    }
+
+ done:
+
+  if (c == EOF)
+    eof = true;
+
+  return buf;
+}
+
+class
+flex_stream_reader : public stream_reader
+{
+public:
+  flex_stream_reader (char *buf_arg) : stream_reader (), buf (buf_arg) { }
+
+  int getc (void) { return ::text_yyinput (); }
+  int ungetc (int c) { ::xunput (c, buf); return 0; }
+  
+private:
+  char *buf;
+};
+
+static int
+process_comment (bool start_in_block, bool& eof)
+{
+  eof = false;
+
+  std::string help_txt;
+
+  if (! help_buf.empty ())
+    help_txt = help_buf.top ();
+
+  flex_stream_reader flex_reader (octave_text);
+
+  // process_comment is only supposed to be called when we are not
+  // initially looking at a block comment.
+
+  std::string txt = start_in_block
+    ? grab_block_comment (flex_reader, eof)
+    : grab_comment_block (flex_reader, false, eof);
+
+  if (lexer_debug_flag)
+    std::cerr << "C: " << txt << std::endl;
+
+  if (help_txt.empty () && nesting_level.none ())
+    {
+      if (! help_buf.empty ())
+	help_buf.pop ();
+
+      help_buf.push (txt);
+    }
+
+  octave_comment_buffer::append (txt);
+
+  current_input_column = 1;
+  lexer_flags.quote_is_transpose = false;
+  lexer_flags.convert_spaces_to_comma = true;
+  lexer_flags.at_beginning_of_statement = true;
+
+  if (YY_START == COMMAND_START)
+    BEGIN (INITIAL);
+
+  if (nesting_level.none ())
+    return '\n';
+  else if (nesting_level.is_bracket_or_brace ())
+    return ';';
+  else
+    return 0;
+}
+
+// Return 1 if the given character matches any character in the given
+// string.
+
+static bool
+match_any (char c, const char *s)
+{
+  char tmp;
+  while ((tmp = *s++) != '\0')
+    {
+      if (c == tmp)
+	return true;
+    }
+  return false;
+}
+
+// Given information about the spacing surrounding an operator,
+// return 1 if it looks like it should be treated as a binary
+// operator.  For example,
+//
+//   [ 1 + 2 ]  or  [ 1+ 2]  or  [ 1+2 ]  ==>  binary
+//
+//   [ 1 +2 ]  ==>  unary
+
+static bool
+looks_like_bin_op (bool spc_prev, int next_char)
+{
+  bool spc_next = (next_char == ' ' || next_char == '\t');
+
+  return ((spc_prev && spc_next) || ! spc_prev);
+}
+
+// Recognize separators.  If the separator is a CRLF pair, it is
+// replaced by a single LF.
+
+static bool
+next_token_is_sep_op (void)
+{
+  bool retval = false;
+
+  int c = text_yyinput ();
+
+  retval = match_any (c, ",;\n]");
+
+  xunput (c, octave_text);
+
+  return retval;
+}
+
+// Try to determine if the next token should be treated as a postfix
+// unary operator.  This is ugly, but it seems to do the right thing.
+
+static bool
+next_token_is_postfix_unary_op (bool spc_prev)
+{
+  bool un_op = false;
+
+  int c0 = text_yyinput ();
+
+  if (c0 == '\'' && ! spc_prev)
+    {
+      un_op = true;
+    }
+  else if (c0 == '.')
+    {
+      int c1 = text_yyinput ();
+      un_op = (c1 == '\'');
+      xunput (c1, octave_text);
+    }
+  else if (c0 == '+')
+    {
+      int c1 = text_yyinput ();
+      un_op = (c1 == '+');
+      xunput (c1, octave_text);
+    }
+  else if (c0 == '-')
+    {
+      int c1 = text_yyinput ();
+      un_op = (c1 == '-');
+      xunput (c1, octave_text);
+    }
+
+  xunput (c0, octave_text);
+
+  return un_op;
+}
+
+// Try to determine if the next token should be treated as a binary
+// operator.
+//
+// This kluge exists because whitespace is not always ignored inside
+// the square brackets that are used to create matrix objects (though
+// spacing only really matters in the cases that can be interpreted
+// either as binary ops or prefix unary ops: currently just +, -).
+//
+// Note that a line continuation directly following a + or - operator
+// (e.g., the characters '[' 'a' ' ' '+' '\' LFD 'b' ']') will be
+// parsed as a binary operator.
+
+static bool
+next_token_is_bin_op (bool spc_prev)
+{
+  bool bin_op = false;
+
+  int c0 = text_yyinput ();
+
+  switch (c0)
+    {
+    case '+':
+    case '-':
+      {
+	int c1 = text_yyinput ();
+
+	switch (c1)
+	  {
+	  case '+':
+	  case '-':
+	    // Unary ops, spacing doesn't matter.
+	    break;
+
+	  case '=':
+	    // Binary ops, spacing doesn't matter.
+	    bin_op = true;
+	    break;
+
+	  default:
+	    // Could be either, spacing matters.
+	    bin_op = looks_like_bin_op (spc_prev, c1);
+	    break;
+	  }
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    case ':':
+    case '/':
+    case '\\':
+    case '^':
+      // Always a binary op (may also include /=, \=, and ^=).
+      bin_op = true;
+      break;
+
+    // .+ .- ./ .\ .^ .* .**
+    case '.':
+      {
+	int c1 = text_yyinput ();
+
+	if (match_any (c1, "+-/\\^*"))
+	  // Always a binary op (may also include .+=, .-=, ./=, ...).
+	  bin_op = true;
+	else if (! isdigit (c1) && c1 != ' ' && c1 != '\t' && c1 != '.')
+	  // A structure element reference is a binary op.
+	  bin_op = true;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    // = == & && | || * **
+    case '=':
+    case '&':
+    case '|':
+    case '*':
+      // Always a binary op (may also include ==, &&, ||, **).
+      bin_op = true;
+      break;
+
+    // < <= <> > >=
+    case '<':
+    case '>':
+      // Always a binary op (may also include <=, <>, >=).
+      bin_op = true;
+      break;
+
+    // ~= !=
+    case '~':
+    case '!':
+      {
+	int c1 = text_yyinput ();
+
+	// ~ and ! can be unary ops, so require following =.
+	if (c1 == '=')
+	  bin_op = true;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  xunput (c0, octave_text);
+
+  return bin_op;
+}
+
+// Used to delete trailing white space from tokens.
+
+static std::string
+strip_trailing_whitespace (char *s)
+{
+  std::string retval = s;
+
+  size_t pos = retval.find_first_of (" \t");
+
+  if (pos != std::string::npos)
+    retval.resize (pos);
+
+  return retval;
+}
+
+// FIXME -- we need to handle block comments here.
+
+static void
+scan_for_comments (const char *text)
+{
+  std::string comment_buf;
+
+  bool in_comment = false;
+  bool beginning_of_comment = false;
+
+  int len = strlen (text);
+  int i = 0;
+
+  while (i < len)
+    {
+      char c = text[i++];
+
+      switch (c)
+	{
+	case '%':
+	case '#':
+	  if (in_comment)
+	    {
+	      if (! beginning_of_comment)
+		comment_buf += static_cast<char> (c);
+	    }
+	  else
+	    {
+	      maybe_gripe_matlab_incompatible_comment (c);
+	      in_comment = true;
+	      beginning_of_comment = true;
+	    }
+	  break;
+
+	case '\n':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      octave_comment_buffer::append (comment_buf);
+	      comment_buf.resize (0);
+	      in_comment = false;
+	      beginning_of_comment = false;
+	    }
+	  break;
+
+	default:
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  break;
+	}
+    }
+
+  if (! comment_buf.empty ())
+    octave_comment_buffer::append (comment_buf);
+}
+
+// Discard whitespace, including comments and continuations.
+//
+// Return value is logical OR of the following values:
+//
+//  ATE_NOTHING      : no spaces to eat
+//  ATE_SPACE_OR_TAB : space or tab in input
+//  ATE_NEWLINE      : bare new line in input
+
+// FIXME -- we need to handle block comments here.
+
+static yum_yum
+eat_whitespace (void)
+{
+  yum_yum retval = ATE_NOTHING;
+
+  std::string comment_buf;
+
+  bool in_comment = false;
+  bool beginning_of_comment = false;
+
+  int c = 0;
+
+  while ((c = text_yyinput ()) != EOF)
+    {
+      current_input_column++;
+
+      switch (c)
+	{
+	case ' ':
+	case '\t':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  retval |= ATE_SPACE_OR_TAB;
+	  break;
+
+	case '\n':
+	  retval |= ATE_NEWLINE;
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      octave_comment_buffer::append (comment_buf);
+	      comment_buf.resize (0);
+	      in_comment = false;
+	      beginning_of_comment = false;
+	    }
+	  current_input_column = 0;
+	  break;
+
+	case '#':
+	case '%':
+	  if (in_comment)
+	    {
+	      if (! beginning_of_comment)
+		comment_buf += static_cast<char> (c);
+	    }
+	  else
+	    {
+	      maybe_gripe_matlab_incompatible_comment (c);
+	      in_comment = true;
+	      beginning_of_comment = true;
+	    }
+	  break;
+
+	case '.':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	      break;
+	    }
+	  else
+	    {
+	      if (have_ellipsis_continuation ())
+		break;
+	      else
+		goto done;
+	    }
+
+	case '\\':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	      break;
+	    }
+	  else
+	    {
+	      if (have_continuation ())
+		break;
+	      else
+		goto done;
+	    }
+
+	default:
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	      break;
+	    }
+	  else
+	    goto done;
+	}
+    }
+
+  if (! comment_buf.empty ())
+    octave_comment_buffer::append (comment_buf);
+
+ done:
+  xunput (c, octave_text);
+  current_input_column--;
+  return retval;
+}
+
+static inline bool
+looks_like_hex (const char *s, int len)
+{
+  return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
+}
+
+static void
+handle_number (void)
+{
+  double value = 0.0;
+  int nread = 0;
+
+  if (looks_like_hex (octave_text, strlen (octave_text)))
+    {
+      unsigned long ival;
+
+      nread = sscanf (octave_text, "%lx", &ival);
+
+      value = static_cast<double> (ival);
+    }
+  else
+    {
+      char *tmp = strsave (octave_text);
+
+      char *idx = strpbrk (tmp, "Dd");
+
+      if (idx)
+	*idx = 'e';
+
+      nread = sscanf (tmp, "%lf", &value);
+
+      delete [] tmp;
+    }
+
+  // If octave_text doesn't contain a valid number, we are in deep doo doo.
+
+  assert (nread == 1);
+
+  lexer_flags.quote_is_transpose = true;
+  lexer_flags.convert_spaces_to_comma = true;
+  lexer_flags.looking_for_object_index = true;
+  lexer_flags.at_beginning_of_statement = false;
+
+  yylval.tok_val = new token (value, octave_text, input_line_number,
+			      current_input_column);
+
+  token_stack.push (yylval.tok_val);
+
+  current_input_column += octave_leng;
+
+  do_comma_insert_check ();
+}
+
+// We have seen a backslash and need to find out if it should be
+// treated as a continuation character.  If so, this eats it, up to
+// and including the new line character.
+//
+// Match whitespace only, followed by a comment character or newline.
+// Once a comment character is found, discard all input until newline.
+// If non-whitespace characters are found before comment
+// characters, return 0.  Otherwise, return 1.
+
+// FIXME -- we need to handle block comments here.
+
+static bool
+have_continuation (bool trailing_comments_ok)
+{
+  std::ostringstream buf;
+
+  std::string comment_buf;
+
+  bool in_comment = false;
+  bool beginning_of_comment = false;
+
+  int c = 0;
+
+  while ((c = text_yyinput ()) != EOF)
+    {
+      buf << static_cast<char> (c);
+
+      switch (c)
+	{
+	case ' ':
+	case '\t':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  break;
+
+	case '%':
+	case '#':
+	  if (trailing_comments_ok)
+	    {
+	      if (in_comment)
+		{
+		  if (! beginning_of_comment)
+		    comment_buf += static_cast<char> (c);
+		}
+	      else
+		{
+		  maybe_gripe_matlab_incompatible_comment (c);
+		  in_comment = true;
+		  beginning_of_comment = true;
+		}
+	    }
+	  else
+	    goto cleanup;
+	  break;
+
+	case '\n':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      octave_comment_buffer::append (comment_buf);
+	    }
+	  current_input_column = 0;
+	  promptflag--;
+	  gripe_matlab_incompatible_continuation ();
+	  return true;
+
+	default:
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  else
+	    goto cleanup;
+	  break;
+	}
+    }
+
+  xunput (c, octave_text);
+  return false;
+
+cleanup:
+
+  std::string s = buf.str ();
+
+  int len = s.length ();
+  while (len--)
+    xunput (s[len], octave_text);
+
+  return false;
+}
+
+// We have seen a `.' and need to see if it is the start of a
+// continuation.  If so, this eats it, up to and including the new
+// line character.
+
+static bool
+have_ellipsis_continuation (bool trailing_comments_ok)
+{
+  char c1 = text_yyinput ();
+  if (c1 == '.')
+    {
+      char c2 = text_yyinput ();
+      if (c2 == '.' && have_continuation (trailing_comments_ok))
+	return true;
+      else
+	{
+	  xunput (c2, octave_text);
+	  xunput (c1, octave_text);
+	}
+    }
+  else
+    xunput (c1, octave_text);
+
+  return false;
+}
+
+// See if we have a continuation line.  If so, eat it and the leading
+// whitespace on the next line.
+//
+// Return value is the same as described for eat_whitespace().
+
+static yum_yum
+eat_continuation (void)
+{
+  int retval = ATE_NOTHING;
+
+  int c = text_yyinput ();
+
+  if ((c == '.' && have_ellipsis_continuation ())
+      || (c == '\\' && have_continuation ()))
+    retval = eat_whitespace ();
+  else
+    xunput (c, octave_text);
+
+  return retval;
+}
+
+static int
+handle_string (char delim)
+{
+  std::ostringstream buf;
+
+  int bos_line = input_line_number;
+  int bos_col = current_input_column;
+
+  int c;
+  int escape_pending = 0;
+
+  while ((c = text_yyinput ()) != EOF)
+    {
+      current_input_column++;
+
+      if (c == '\\')
+	{
+	  if (delim == '\'' || escape_pending)
+	    {
+	      buf << static_cast<char> (c);
+	      escape_pending = 0;
+	    }
+	  else
+	    {
+	      if (have_continuation (false))
+		escape_pending = 0;
+	      else
+		{
+		  buf << static_cast<char> (c);
+		  escape_pending = 1;
+		}
+	    }
+	  continue;
+	}
+      else if (c == '.')
+	{
+	  if (delim == '\'' || ! have_ellipsis_continuation (false))
+	    buf << static_cast<char> (c);
+	}
+      else if (c == '\n')
+	{
+	  error ("unterminated string constant");
+	  break;
+	}
+      else if (c == delim)
+	{
+	  if (escape_pending)
+	    buf << static_cast<char> (c);
+	  else
+	    {
+	      c = text_yyinput ();
+	      if (c == delim)
+		{
+		  buf << static_cast<char> (c);		    
+		}
+	      else
+		{
+		  std::string s;  
+		  xunput (c, octave_text);
+
+		  if (delim == '\'')
+		    s = buf.str ();
+		  else
+		    s = do_string_escapes (buf.str ());
+
+		  lexer_flags.quote_is_transpose = true;
+		  lexer_flags.convert_spaces_to_comma = true;
+
+		  yylval.tok_val = new token (s, bos_line, bos_col);
+		  token_stack.push (yylval.tok_val);
+
+		  if (delim == '"')
+		    gripe_matlab_incompatible ("\" used as string delimiter");
+		  else if (delim == '\'')
+		    gripe_single_quote_string ();
+
+                  lexer_flags.looking_for_object_index = true;
+		  lexer_flags.at_beginning_of_statement = false;
+
+		  return delim == '"' ? DQ_STRING : SQ_STRING;
+		}
+	    }
+	}
+      else
+	{
+	  buf << static_cast<char> (c);
+	}
+
+      escape_pending = 0;
+    }
+
+  return LEXICAL_ERROR;
+}
+
+static bool
+next_token_is_assign_op (void)
+{
+  bool retval = false;
+
+  int c0 = text_yyinput ();
+
+  switch (c0)
+    {
+    case '=':
+      {
+	int c1 = text_yyinput ();
+	xunput (c1, octave_text);
+	if (c1 != '=')
+	  retval = true;
+      }
+      break;
+
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '\\':
+    case '&':
+    case '|':
+      {
+	int c1 = text_yyinput ();
+	xunput (c1, octave_text);
+	if (c1 == '=')
+	  retval = true;
+      }
+      break;
+
+    case '.':
+      {
+	int c1 = text_yyinput ();
+	if (match_any (c1, "+-*/\\"))
+	  {
+	    int c2 = text_yyinput ();
+	    xunput (c2, octave_text);
+	    if (c2 == '=')
+	      retval = true;
+	  }
+	xunput (c1, octave_text);
+      }
+      break;
+
+    case '>':
+      {
+	int c1 = text_yyinput ();
+	if (c1 == '>')
+	  {
+	    int c2 = text_yyinput ();
+	    xunput (c2, octave_text);
+	    if (c2 == '=')
+	      retval = true;
+	  }
+	xunput (c1, octave_text);
+      }
+      break;
+
+    case '<':
+      {
+	int c1 = text_yyinput ();
+	if (c1 == '<')
+	  {
+	    int c2 = text_yyinput ();
+	    xunput (c2, octave_text);
+	    if (c2 == '=')
+	      retval = true;
+	  }
+	xunput (c1, octave_text);
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  xunput (c0, octave_text);
+
+  return retval;
+}
+
+static bool
+next_token_is_index_op (void)
+{
+  int c = text_yyinput ();
+  xunput (c, octave_text);
+  return c == '(' || c == '{';
+}
+
+static int
+handle_close_bracket (bool spc_gobbled, int bracket_type)
+{
+  int retval = bracket_type;
+
+  if (! nesting_level.none ())
+    {
+      nesting_level.remove ();
+
+      if (bracket_type == ']')
+	lexer_flags.bracketflag--;
+      else if (bracket_type == '}')
+	lexer_flags.braceflag--;
+      else
+	panic_impossible ();
+    }
+
+  if (lexer_flags.bracketflag == 0 && lexer_flags.braceflag == 0)
+    BEGIN (INITIAL);
+
+  if (bracket_type == ']'
+      && next_token_is_assign_op ()
+      && ! lexer_flags.looking_at_return_list)
+    {
+      retval = CLOSE_BRACE;
+    }
+  else if ((lexer_flags.bracketflag || lexer_flags.braceflag)
+	   && lexer_flags.convert_spaces_to_comma
+	   && (nesting_level.is_bracket ()
+	       || (nesting_level.is_brace ()
+		   && ! lexer_flags.looking_at_object_index.front ())))
+    {
+      bool index_op = next_token_is_index_op ();
+
+      // Don't insert comma if we are looking at something like
+      //
+      //   [x{i}{j}] or [x{i}(j)]
+      //
+      // but do if we are looking at
+      //
+      //   [x{i} {j}] or [x{i} (j)]
+
+      if (spc_gobbled || ! (bracket_type == '}' && index_op))
+	{
+	  bool bin_op = next_token_is_bin_op (spc_gobbled);
+
+	  bool postfix_un_op = next_token_is_postfix_unary_op (spc_gobbled);
+
+	  bool sep_op = next_token_is_sep_op ();
+
+	  if (! (postfix_un_op || bin_op || sep_op))
+	    {
+	      maybe_warn_separator_insert (',');
+
+	      xunput (',', octave_text);
+	      return retval;
+	    }
+	}
+    }
+
+  lexer_flags.quote_is_transpose = true;
+  lexer_flags.convert_spaces_to_comma = true;
+
+  return retval;
+}
+
+static void
+maybe_unput_comma (int spc_gobbled)
+{
+  if (nesting_level.is_bracket ()
+      || (nesting_level.is_brace ()
+	  && ! lexer_flags.looking_at_object_index.front ()))
+    {
+      int bin_op = next_token_is_bin_op (spc_gobbled);
+
+      int postfix_un_op = next_token_is_postfix_unary_op (spc_gobbled);
+
+      int c1 = text_yyinput ();
+      int c2 = text_yyinput ();
+
+      xunput (c2, octave_text);
+      xunput (c1, octave_text);
+
+      int sep_op = next_token_is_sep_op ();
+
+      int dot_op = (c1 == '.'
+		    && (isalpha (c2) || isspace (c2) || c2 == '_'));
+
+      if (postfix_un_op || bin_op || sep_op || dot_op)
+	return;
+
+      int index_op = (c1 == '(' || c1 == '{');
+
+      // If there is no space before the indexing op, we don't insert
+      // a comma.
+
+      if (index_op && ! spc_gobbled)
+	return;
+
+      maybe_warn_separator_insert (',');
+
+      xunput (',', octave_text);
+    }
+}
+
+static bool
+next_token_can_follow_bin_op (void)
+{
+  std::stack<char> buf;
+
+  int c = EOF;
+
+  // Skip whitespace in current statement on current line
+  while (true)
+    {
+      c = text_yyinput ();
+
+      buf.push (c);
+
+      if (match_any (c, ",;\n") || (c != ' ' && c != '\t'))
+	break;
+    }
+
+  // Restore input.
+  while (! buf.empty ())
+    {
+      xunput (buf.top (), octave_text);
+
+      buf.pop ();
+    }
+
+  return (isalnum (c) || match_any (c, "!\"'(-[_{~"));
+}
+
+static bool
+looks_like_command_arg (void)
+{
+  bool retval = true;
+
+  int c0 = text_yyinput ();
+
+  switch (c0)
+    {
+    // = ==
+    case '=':
+      {
+	int c1 = text_yyinput ();
+
+	if (c1 == '=')
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, octave_text);
+	  }
+	else
+	  retval = false;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    case '(':
+    case '{':
+      // Indexing.
+      retval = false;
+      break;
+
+    case '\n':
+      // EOL.
+      break;
+
+    case '\'':
+    case '"':
+      // Beginning of a character string.
+      break;
+
+    // + - ++ -- += -=
+    case '+':
+    case '-':
+      {
+	int c1 = text_yyinput ();
+
+	switch (c1)
+	  {
+	  case '\n':
+	    // EOL.
+	  case '+':
+	  case '-':
+	    // Unary ops, spacing doesn't matter.
+	    break;
+
+	  case '\t':
+	  case ' ':
+	    {
+	      if (next_token_can_follow_bin_op ())
+		retval = false;
+	    }
+	    break;
+
+	  case '=':
+	    {
+	      int c2 = text_yyinput ();
+
+	      if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		  && next_token_can_follow_bin_op ())
+		retval = false;
+
+	      xunput (c2, octave_text);
+	    }
+	    break;
+	  }
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    case ':':
+    case '/':
+    case '\\':
+    case '^':
+      {
+	int c1 = text_yyinput ();
+
+	if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+	    && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    // .+ .- ./ .\ .^ .* .**
+    case '.':
+      {
+	int c1 = text_yyinput ();
+
+	if (match_any (c1, "+-/\\^*"))
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (c2 == '=')
+	      {
+		int c3 = text_yyinput ();
+
+		if (! match_any (c3, ",;\n") && (c3 == ' ' || c3 == '\t')
+		    && next_token_can_follow_bin_op ())
+		  retval = false;
+
+		xunput (c3, octave_text);
+	      }
+	    else if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		     && next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, octave_text);
+	  }
+	else if (! match_any (c1, ",;\n")
+		 && (! isdigit (c1) && c1 != ' ' && c1 != '\t'
+		     && c1 != '.'))
+	  {
+	    // Structure reference.  FIXME -- is this a complete check?
+
+	    retval = false;
+	  }
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    // & && | || * **
+    case '&':
+    case '|':
+    case '*':
+      {
+	int c1 = text_yyinput ();
+
+	if (c1 == c0)
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, octave_text);
+	  }
+	else if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+		 && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    // < <= > >=
+    case '<':
+    case '>':
+      {
+	int c1 = text_yyinput ();
+
+	if (c1 == '=')
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, octave_text);
+	  }
+	else if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+		 && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    // ~= !=
+    case '~':
+    case '!':
+      {
+	int c1 = text_yyinput ();
+
+	// ~ and ! can be unary ops, so require following =.
+	if (c1 == '=')
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, octave_text);
+	  }
+	else if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+		 && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, octave_text);
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  xunput (c0, octave_text);
+
+  return retval;
+}
+
+// Figure out exactly what kind of token to return when we have seen
+// an identifier.  Handles keywords.  Return -1 if the identifier
+// should be ignored.
+
+static int
+handle_identifier (void)
+{
+  bool at_bos = lexer_flags.at_beginning_of_statement;
+
+  std::string tok = strip_trailing_whitespace (octave_text);
+
+  int c = octave_text[octave_leng-1];
+
+  int cont_is_spc = eat_continuation ();
+
+  int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
+
+  // If we are expecting a structure element, avoid recognizing
+  // keywords and other special names and return STRUCT_ELT, which is
+  // a string that is also a valid identifier.  But first, we have to
+  // decide whether to insert a comma.
+
+  if (lexer_flags.looking_at_indirect_ref)
+    {
+      do_comma_insert_check ();
+
+      maybe_unput_comma (spc_gobbled);
+
+      yylval.tok_val = new token (tok, input_line_number,
+				  current_input_column);
+
+      token_stack.push (yylval.tok_val);
+
+      lexer_flags.quote_is_transpose = true;
+      lexer_flags.convert_spaces_to_comma = true;
+      lexer_flags.looking_for_object_index = true;
+
+      current_input_column += octave_leng;
+
+      return STRUCT_ELT;
+    }
+
+  lexer_flags.at_beginning_of_statement = false;
+
+  // The is_keyword_token may reset
+  // lexer_flags.at_beginning_of_statement.  For example, if it sees
+  // an else token, then the next token is at the beginning of a
+  // statement.
+
+  int kw_token = is_keyword_token (tok);
+
+  // If we found a keyword token, then the beginning_of_statement flag
+  // is already set.  Otherwise, we won't be at the beginning of a
+  // statement.
+
+  if (lexer_flags.looking_at_function_handle)
+    {
+      if (kw_token)
+	{
+	  error ("function handles may not refer to keywords");
+
+	  return LEXICAL_ERROR;
+	}
+      else
+	{
+	  yylval.tok_val = new token (tok, input_line_number,
+				      current_input_column);
+
+	  token_stack.push (yylval.tok_val);
+
+	  current_input_column += octave_leng;
+	  lexer_flags.quote_is_transpose = false;
+	  lexer_flags.convert_spaces_to_comma = true;
+	  lexer_flags.looking_for_object_index = true;
+
+	  return FCN_HANDLE;
+	}
+    }
+
+  // If we have a regular keyword, return it.
+  // Keywords can be followed by identifiers.
+
+  if (kw_token)
+    {
+      if (kw_token >= 0)
+	{
+	  current_input_column += octave_leng;
+	  lexer_flags.quote_is_transpose = false;
+	  lexer_flags.convert_spaces_to_comma = true;
+	  lexer_flags.looking_for_object_index = false;
+	}
+
+      return kw_token;
+    }
+
+  // See if we have a plot keyword (title, using, with, or clear).
+
+  int c1 = text_yyinput ();
+
+  bool next_tok_is_eq = false;
+  if (c1 == '=')
+    {
+      int c2 = text_yyinput ();
+      xunput (c2, octave_text);
+
+      if (c2 != '=')
+	next_tok_is_eq = true;
+    }
+
+  xunput (c1, octave_text);
+
+  // Kluge alert.
+  //
+  // If we are looking at a text style function, set up to gobble its
+  // arguments.
+  //
+  // If the following token is `=', or if we are parsing a function
+  // return list or function parameter list, or if we are looking at
+  // something like [ab,cd] = foo (), force the symbol to be inserted
+  // as a variable in the current symbol table.
+
+  if (! is_variable (tok))
+    {
+      if (at_bos && spc_gobbled && looks_like_command_arg ())
+	{
+	  BEGIN (COMMAND_START);
+	}
+      else if (next_tok_is_eq
+	       || lexer_flags.looking_at_decl_list
+	       || lexer_flags.looking_at_return_list
+	       || (lexer_flags.looking_at_parameter_list
+		   && ! lexer_flags.looking_at_initializer_expression))
+	{
+	  symbol_table::force_variable (tok);
+	}
+      else if (lexer_flags.looking_at_matrix_or_assign_lhs)
+	{
+	  lexer_flags.pending_local_variables.insert (tok);
+	}
+    }
+
+  // Find the token in the symbol table.  Beware the magic
+  // transformation of the end keyword...
+
+  if (tok == "end")
+    tok = "__end__";    
+
+  yylval.tok_val = new token (&(symbol_table::insert (tok)),
+			      input_line_number, current_input_column);
+
+  token_stack.push (yylval.tok_val);
+
+  // After seeing an identifer, it is ok to convert spaces to a comma
+  // (if needed).
+
+  lexer_flags.convert_spaces_to_comma = true;
+
+  if (! (next_tok_is_eq || YY_START == COMMAND_START))
+    {
+      lexer_flags.quote_is_transpose = true;
+
+      do_comma_insert_check ();
+
+      maybe_unput_comma (spc_gobbled);
+    }
+
+  current_input_column += octave_leng;
+
+  if (tok != "__end__")
+    lexer_flags.looking_for_object_index = true;
+
+  return NAME;
+}
+
+void
+lexical_feedback::init (void)
+{
+  // Not initially defining a matrix list.
+  bracketflag = 0;
+
+  // Not initially defining a cell array list.
+  braceflag = 0;
+
+  // Not initially inside a loop or if statement.
+  looping = 0;
+
+  // Not initially defining a function.
+  defining_func = false;
+  parsed_function_name = false;
+  parsing_nested_function = 0;
+  parsing_class_method = false;
+
+  // Not initiallly looking at a function handle.
+  looking_at_function_handle = 0;
+
+  // Not parsing a function return, parameter, or declaration list.
+  looking_at_return_list = false;
+  looking_at_parameter_list = false;
+  looking_at_decl_list = false;
+
+  // Not looking at an argument list initializer expression.
+  looking_at_initializer_expression = false;
+
+  // Not parsing a matrix or the left hand side of multi-value
+  // assignment statement.
+  looking_at_matrix_or_assign_lhs = false;
+
+  // Not parsing an object index.
+  while (! looking_at_object_index.empty ())
+    looking_at_object_index.pop_front ();
+
+  looking_at_object_index.push_front (false);
+
+  // Object index not possible until we've seen something.
+  looking_for_object_index = false;
+
+  // Yes, we are at the beginning of a statement.
+  at_beginning_of_statement = true;
+
+  // No need to do comma insert or convert spaces to comma at
+  // beginning of input. 
+  convert_spaces_to_comma = true;
+  do_comma_insert = false;
+
+  // Not initially looking at indirect references.
+  looking_at_indirect_ref = false;
+
+  // Quote marks strings intially.
+  quote_is_transpose = false;
+
+  // Set of identifiers that might be local variable names is empty.
+  pending_local_variables.clear ();
+}
+
+bool
+is_keyword (const std::string& s)
+{
+  return octave_kw_hash::in_word_set (s.c_str (), s.length ()) != 0;
+}
+
+DEFUN (iskeyword, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} iskeyword (@var{name})\n\
+Return true if @var{name} is an Octave keyword.  If @var{name}\n\
+is omitted, return a list of keywords.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("iskeyword");
+
+  if (error_state)
+    return retval;
+
+  if (argc == 1)
+    {
+      string_vector lst (TOTAL_KEYWORDS);
+
+      for (int i = 0; i < TOTAL_KEYWORDS; i++)
+	lst[i] = wordlist[i].name;
+
+      retval = Cell (lst.sort ());
+    }
+  else if (argc == 2)
+    {
+      retval = is_keyword (argv[1]);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+void
+prep_lexer_for_script (void)
+{
+  BEGIN (SCRIPT_FILE_BEGIN);
+}
+
+static void
+maybe_warn_separator_insert (char sep)
+{
+  std::string nm = curr_fcn_file_full_name;
+
+  if (nm.empty ())
+    warning_with_id ("Octave:separator-insert",
+		     "potential auto-insertion of `%c' near line %d",
+		     sep, input_line_number);
+  else
+    warning_with_id ("Octave:separator-insert",
+		     "potential auto-insertion of `%c' near line %d of file %s",
+		     sep, input_line_number, nm.c_str ());
+}
+
+static void
+gripe_single_quote_string (void)
+{
+  std::string nm = curr_fcn_file_full_name;
+
+  if (nm.empty ())
+    warning_with_id ("Octave:single-quote-string",
+		     "single quote delimited string near line %d",
+		     input_line_number);
+  else
+    warning_with_id ("Octave:single-quote-string",
+		     "single quote delimited string near line %d of file %s",
+		     input_line_number, nm.c_str ());
+}
+
+static void
+gripe_matlab_incompatible (const std::string& msg)
+{
+  std::string nm = curr_fcn_file_full_name;
+
+  if (nm.empty ())
+    warning_with_id ("Octave:matlab-incompatible",
+		     "potential Matlab compatibility problem: %s",
+		     msg.c_str ());
+  else
+    warning_with_id ("Octave:matlab-incompatible",
+		     "potential Matlab compatibility problem: %s near line %d offile %s",
+		     msg.c_str (), input_line_number, nm.c_str ());
+}
+
+static void
+maybe_gripe_matlab_incompatible_comment (char c)
+{
+  if (c == '#')
+    gripe_matlab_incompatible ("# used as comment character");
+}
+
+static void
+gripe_matlab_incompatible_continuation (void)
+{
+  gripe_matlab_incompatible ("\\ used as line continuation marker");
+}
+
+static void
+gripe_matlab_incompatible_operator (const std::string& op)
+{
+  std::string t = op;
+  int n = t.length ();
+  if (t[n-1] == '\n')
+    t.resize (n-1);
+  gripe_matlab_incompatible (t + " used as operator");
+}
+
+static void
+display_token (int tok)
+{
+  switch (tok)
+    {
+    case '=': std::cerr << "'='\n"; break;
+    case ':': std::cerr << "':'\n"; break;
+    case '-': std::cerr << "'-'\n"; break;
+    case '+': std::cerr << "'+'\n"; break;
+    case '*': std::cerr << "'*'\n"; break;
+    case '/': std::cerr << "'/'\n"; break;
+    case ADD_EQ: std::cerr << "ADD_EQ\n"; break;
+    case SUB_EQ: std::cerr << "SUB_EQ\n"; break;
+    case MUL_EQ: std::cerr << "MUL_EQ\n"; break;
+    case DIV_EQ: std::cerr << "DIV_EQ\n"; break;
+    case LEFTDIV_EQ: std::cerr << "LEFTDIV_EQ\n"; break;
+    case POW_EQ: std::cerr << "POW_EQ\n"; break;
+    case EMUL_EQ: std::cerr << "EMUL_EQ\n"; break;
+    case EDIV_EQ: std::cerr << "EDIV_EQ\n"; break;
+    case ELEFTDIV_EQ: std::cerr << "ELEFTDIV_EQ\n"; break;
+    case EPOW_EQ: std::cerr << "EPOW_EQ\n"; break;
+    case AND_EQ: std::cerr << "AND_EQ\n"; break;
+    case OR_EQ: std::cerr << "OR_EQ\n"; break;
+    case LSHIFT_EQ: std::cerr << "LSHIFT_EQ\n"; break;
+    case RSHIFT_EQ: std::cerr << "RSHIFT_EQ\n"; break;
+    case LSHIFT: std::cerr << "LSHIFT\n"; break;
+    case RSHIFT: std::cerr << "RSHIFT\n"; break;
+    case EXPR_AND_AND: std::cerr << "EXPR_AND_AND\n"; break;
+    case EXPR_OR_OR: std::cerr << "EXPR_OR_OR\n"; break;
+    case EXPR_AND: std::cerr << "EXPR_AND\n"; break;
+    case EXPR_OR: std::cerr << "EXPR_OR\n"; break;
+    case EXPR_NOT: std::cerr << "EXPR_NOT\n"; break;
+    case EXPR_LT: std::cerr << "EXPR_LT\n"; break;
+    case EXPR_LE: std::cerr << "EXPR_LE\n"; break;
+    case EXPR_EQ: std::cerr << "EXPR_EQ\n"; break;
+    case EXPR_NE: std::cerr << "EXPR_NE\n"; break;
+    case EXPR_GE: std::cerr << "EXPR_GE\n"; break;
+    case EXPR_GT: std::cerr << "EXPR_GT\n"; break;
+    case LEFTDIV: std::cerr << "LEFTDIV\n"; break;
+    case EMUL: std::cerr << "EMUL\n"; break;
+    case EDIV: std::cerr << "EDIV\n"; break;
+    case ELEFTDIV: std::cerr << "ELEFTDIV\n"; break;
+    case EPLUS: std::cerr << "EPLUS\n"; break;
+    case EMINUS: std::cerr << "EMINUS\n"; break;
+    case QUOTE: std::cerr << "QUOTE\n"; break;
+    case TRANSPOSE: std::cerr << "TRANSPOSE\n"; break;
+    case PLUS_PLUS: std::cerr << "PLUS_PLUS\n"; break;
+    case MINUS_MINUS: std::cerr << "MINUS_MINUS\n"; break;
+    case POW: std::cerr << "POW\n"; break;
+    case EPOW: std::cerr << "EPOW\n"; break;
+    case NUM: std::cerr << "NUM\n"; break;
+    case IMAG_NUM: std::cerr << "IMAG_NUM\n"; break;
+    case STRUCT_ELT: std::cerr << "STRUCT_ELT\n"; break;
+    case NAME: std::cerr << "NAME\n"; break;
+    case END: std::cerr << "END\n"; break;
+    case DQ_STRING: std::cerr << "DQ_STRING\n"; break;
+    case SQ_STRING: std::cerr << "SQ_STRING\n"; break;
+    case FOR: std::cerr << "FOR\n"; break;
+    case WHILE: std::cerr << "WHILE\n"; break;
+    case DO: std::cerr << "DO\n"; break;
+    case UNTIL: std::cerr << "UNTIL\n"; break;
+    case IF: std::cerr << "IF\n"; break;
+    case ELSEIF: std::cerr << "ELSEIF\n"; break;
+    case ELSE: std::cerr << "ELSE\n"; break;
+    case SWITCH: std::cerr << "SWITCH\n"; break;
+    case CASE: std::cerr << "CASE\n"; break;
+    case OTHERWISE: std::cerr << "OTHERWISE\n"; break;
+    case BREAK: std::cerr << "BREAK\n"; break;
+    case CONTINUE: std::cerr << "CONTINUE\n"; break;
+    case FUNC_RET: std::cerr << "FUNC_RET\n"; break;
+    case UNWIND: std::cerr << "UNWIND\n"; break;
+    case CLEANUP: std::cerr << "CLEANUP\n"; break;
+    case TRY: std::cerr << "TRY\n"; break;
+    case CATCH: std::cerr << "CATCH\n"; break;
+    case GLOBAL: std::cerr << "GLOBAL\n"; break;
+    case STATIC: std::cerr << "STATIC\n"; break;
+    case FCN_HANDLE: std::cerr << "FCN_HANDLE\n"; break;
+    case END_OF_INPUT: std::cerr << "END_OF_INPUT\n\n"; break;
+    case LEXICAL_ERROR: std::cerr << "LEXICAL_ERROR\n\n"; break;
+    case FCN: std::cerr << "FCN\n"; break;
+    case CLOSE_BRACE: std::cerr << "CLOSE_BRACE\n"; break;
+    case '\n': std::cerr << "\\n\n"; break;
+    case '\r': std::cerr << "\\r\n"; break;
+    case '\t': std::cerr << "TAB\n"; break;
+    default:
+      {
+        if (tok < 256)
+	  std::cerr << static_cast<char> (tok) << "\n";
+	else
+	  std::cerr << "UNKNOWN(" << tok << ")\n";
+      }
+      break;
+    }
+}
+
+static void
+display_state (void)
+{
+  std::cerr << "S: ";
+
+  switch (YY_START)
+    {
+    case INITIAL:
+      std::cerr << "INITIAL" << std::endl;
+      break;
+
+    case COMMAND_START:
+      std::cerr << "COMMAND_START" << std::endl;
+      break;
+
+    case MATRIX_START:
+      std::cerr << "MATRIX_START" << std::endl;
+      break;
+
+    case SCRIPT_FILE_BEGIN:
+      std::cerr << "SCRIPT_FILE_BEGIN" << std::endl;
+      break;
+
+    case NESTED_FUNCTION_END:
+      std::cerr << "NESTED_FUNCTION_END" << std::endl;
+      break;
+
+    case NESTED_FUNCTION_BEGIN:
+      std::cerr << "NESTED_FUNCTION_BEGIN" << std::endl;
+      break;
+
+    default:
+      std::cerr << "UNKNOWN START STATE!" << std::endl;
+      break;
+    }
+}
+
+static void
+lexer_debug (const char *pattern, const char *text)
+{
+  std::cerr << std::endl;
+
+  display_state ();
+
+  std::cerr << "P: " << pattern << std::endl;
+  std::cerr << "T: " << text << std::endl;
+}
+
+DEFUN (__display_tokens__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __display_tokens__ ()\n\
+Query or set the internal variable that determines whether Octave's\n\
+lexer displays tokens as they are read.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (display_tokens);
+}
+
+DEFUN (__token_count__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __token_count__ ()\n\
+Number of language tokens processed since Octave startup.\n\
+ at end deftypefn")
+{
+  return octave_value (Vtoken_count);
+}
+
+DEFUN (__lexer_debug_flag__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{old_val} =} __lexer_debug_flag__ (@var{new_val}))\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  retval = set_internal_variable (lexer_debug_flag, args, nargout,
+           			  "__lexer_debug_flag__");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/lex.h b/src/lex.h
new file mode 100644
index 0000000..a875a08
--- /dev/null
+++ b/src/lex.h
@@ -0,0 +1,184 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_lex_h)
+#define octave_lex_h 1
+
+#include <list>
+
+// FIXME -- these input buffer things should be members of a
+// parser input stream class.
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+// Associate a buffer with a new file to read.
+extern OCTINTERP_API YY_BUFFER_STATE create_buffer (FILE *f);
+
+// Report the current buffer.
+extern OCTINTERP_API YY_BUFFER_STATE current_buffer (void);
+
+// Connect to new buffer buffer.
+extern OCTINTERP_API void switch_to_buffer (YY_BUFFER_STATE buf);
+
+// Delete a buffer.
+extern OCTINTERP_API void delete_buffer (YY_BUFFER_STATE buf);
+
+// Restore a buffer (for unwind-prot).
+extern OCTINTERP_API void restore_input_buffer (void *buf);
+
+// Delete a buffer (for unwind-prot).
+extern OCTINTERP_API void delete_input_buffer (void *buf);
+
+// Is the given string a keyword?
+extern bool is_keyword (const std::string& s);
+
+extern void prep_lexer_for_script (void);
+
+// For communication between the lexer and parser.
+
+class
+lexical_feedback
+{
+public:
+
+  lexical_feedback (void) { init (); }
+
+  ~lexical_feedback (void) { }
+
+  void init (void);
+
+  // Square bracket level count.
+  int bracketflag;
+
+  // Curly brace level count.
+  int braceflag;
+
+  // TRUE means we're in the middle of defining a loop.
+  int looping;
+
+  // TRUE means that we should convert spaces to a comma inside a
+  // matrix definition.
+  bool convert_spaces_to_comma;
+
+  // TRUE means we are at the beginning of a statement, where a
+  // command name is possible.
+  bool at_beginning_of_statement;
+
+  // TRUE means we're in the middle of defining a function.
+  bool defining_func;
+
+  // Nonzero means we are parsing a function handle.
+  int looking_at_function_handle;
+
+  // TRUE means we're parsing the return list for a function.
+  bool looking_at_return_list;
+
+  // TRUE means we're parsing the parameter list for a function.
+  bool looking_at_parameter_list;
+
+  // TRUE means we're parsing a declaration list (global or
+  // persistent).
+  bool looking_at_decl_list;
+
+  // TRUE means we are looking at the initializer expression for a
+  // parameter list element.
+  bool looking_at_initializer_expression;
+
+  // TRUE means we're parsing a matrix or the left hand side of
+  // multi-value assignment statement.
+  bool looking_at_matrix_or_assign_lhs;
+
+  // If the front of the list is TRUE, the closest paren, brace, or
+  // bracket nesting is an index for an object.
+  std::list<bool> looking_at_object_index;
+
+  // Object index not possible until we've seen something.
+  bool looking_for_object_index;
+
+  // GAG.  Stupid kludge so that [[1,2][3,4]] will work.
+  bool do_comma_insert;
+
+  // TRUE means we're looking at an indirect reference to a
+  // structure element.
+  bool looking_at_indirect_ref;
+
+  // TRUE means that we've already seen the name of this function.
+  // Should only matter if defining_func is also TRUE.
+  bool parsed_function_name;
+
+  // Are we parsing a nested function?
+  //   1 ==> Yes.
+  //   0 ==> No.
+  //  -1 ==> Yes, but it is the last one because we have seen EOF.
+  int parsing_nested_function;
+
+  // TRUE means we are parsing a class method.
+  bool parsing_class_method;
+
+  // Return transpose or start a string?
+  bool quote_is_transpose;
+
+  // Set of identifiers that might be local variable names.
+  std::set<std::string> pending_local_variables;
+
+private:
+
+  lexical_feedback (const lexical_feedback&);
+
+  lexical_feedback& operator = (const lexical_feedback&);
+};
+
+class
+stream_reader
+{
+public:
+  virtual int getc (void) = 0;
+  virtual int ungetc (int c) = 0;
+
+protected:
+  stream_reader (void) { }
+  ~stream_reader (void) { }
+
+private:
+
+  // No copying!
+  stream_reader (const stream_reader&);
+  stream_reader& operator = (const stream_reader&);
+};
+
+extern std::string
+grab_comment_block (stream_reader& reader, bool at_bol, bool& eof);
+
+// TRUE means that we have encountered EOF on the input stream.
+extern bool parser_end_of_input;
+
+// Flags that need to be shared between the lexer and parser.
+extern lexical_feedback lexer_flags;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/lex.l b/src/lex.l
new file mode 100644
index 0000000..e325219
--- /dev/null
+++ b/src/lex.l
@@ -0,0 +1,3597 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+%option prefix = "octave_"
+
+%s COMMAND_START
+%s MATRIX_START
+
+%x SCRIPT_FILE_BEGIN
+
+%x NESTED_FUNCTION_END
+%x NESTED_FUNCTION_BEGIN
+
+%{
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cstring>
+
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <string>
+#include <stack>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "quit.h"
+#include "lo-mappers.h"
+
+// These would be alphabetical, but y.tab.h must be included before
+// oct-gperf.h and y.tab.h must be included after token.h and the tree
+// class declarations.  We can't include y.tab.h in oct-gperf.h
+// because it may not be protected to allow it to be included multiple
+// times.
+
+#include "Cell.h"
+#include "comment-list.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "lex.h"
+#include "ov.h"
+#include "parse.h"
+#include "pt-all.h"
+#include "symtab.h"
+#include "token.h"
+#include "toplev.h"
+#include "utils.h"
+#include "variables.h"
+#include <y.tab.h>
+#include <oct-gperf.h>
+
+#if ! (defined (FLEX_SCANNER) \
+       && defined (YY_FLEX_MAJOR_VERSION) && YY_FLEX_MAJOR_VERSION >= 2 \
+       && defined (YY_FLEX_MINOR_VERSION) && YY_FLEX_MINOR_VERSION >= 5)
+#error lex.l requires flex version 2.5.4 or later
+#endif
+
+#define yylval octave_lval
+
+// Arrange to get input via readline.
+
+#ifdef YY_INPUT
+#undef YY_INPUT
+#endif
+#define YY_INPUT(buf, result, max_size) \
+  if ((result = octave_read (buf, max_size)) < 0) \
+    YY_FATAL_ERROR ("octave_read () in flex scanner failed");
+
+// Try to avoid crashing out completely on fatal scanner errors.
+// The call to yy_fatal_error should never happen, but it avoids a
+// `static function defined but not used' warning from gcc.
+
+#ifdef YY_FATAL_ERROR
+#undef YY_FATAL_ERROR
+#endif
+#define YY_FATAL_ERROR(msg) \
+  do \
+    { \
+      error (msg); \
+      OCTAVE_QUIT; \
+      yy_fatal_error (msg); \
+    } \
+  while (0)
+
+#define DISPLAY_TOK_AND_RETURN(tok) \
+  do \
+    { \
+      int tok_val = tok; \
+      if (Vdisplay_tokens) \
+        display_token (tok_val); \
+      if (lexer_debug_flag) \
+        { \
+	  std::cerr << "R: "; \
+          display_token (tok_val); \
+	  std::cerr << std::endl;  \
+	} \
+      return tok_val; \
+    } \
+  while (0)
+
+#define COUNT_TOK_AND_RETURN(tok) \
+  do \
+    { \
+      Vtoken_count++; \
+      DISPLAY_TOK_AND_RETURN (tok); \
+    } \
+  while (0)
+
+#define TOK_RETURN(tok) \
+  do \
+    { \
+      current_input_column += yyleng; \
+      lexer_flags.quote_is_transpose = false; \
+      lexer_flags.convert_spaces_to_comma = true; \
+      COUNT_TOK_AND_RETURN (tok); \
+    } \
+  while (0)
+
+#define TOK_PUSH_AND_RETURN(name, tok) \
+  do \
+    { \
+      yylval.tok_val = new token (name, input_line_number, \
+				  current_input_column); \
+      token_stack.push (yylval.tok_val); \
+      TOK_RETURN (tok); \
+    } \
+  while (0)
+
+#define BIN_OP_RETURN(tok, convert, bos) \
+  do \
+    { \
+      yylval.tok_val = new token (input_line_number, current_input_column); \
+      token_stack.push (yylval.tok_val); \
+      current_input_column += yyleng; \
+      lexer_flags.quote_is_transpose = false; \
+      lexer_flags.convert_spaces_to_comma = convert; \
+      lexer_flags.looking_for_object_index = false; \
+      lexer_flags.at_beginning_of_statement = bos; \
+      COUNT_TOK_AND_RETURN (tok); \
+    } \
+  while (0)
+
+#define XBIN_OP_RETURN(tok, convert, bos) \
+  do \
+    { \
+      gripe_matlab_incompatible_operator (yytext); \
+      BIN_OP_RETURN (tok, convert, bos); \
+    } \
+  while (0)
+
+#define LEXER_DEBUG(pattern) \
+  do \
+    { \
+      if (lexer_debug_flag) \
+        lexer_debug (pattern, yytext); \
+    } \
+  while (0)
+
+// TRUE means that we have encountered EOF on the input stream.
+bool parser_end_of_input = false;
+
+// Flags that need to be shared between the lexer and parser.
+lexical_feedback lexer_flags;
+
+// Stack to hold tokens so that we can delete them when the parser is
+// reset and avoid growing forever just because we are stashing some
+// information.  This has to appear before lex.h is included, because
+// one of the macros defined there uses token_stack.
+//
+// FIXME -- this should really be static, but that causes
+// problems on some systems.
+std::stack <token*> token_stack;
+
+// Did eat_whitespace() eat a space or tab, or a newline, or both?
+
+typedef int yum_yum;
+
+const yum_yum ATE_NOTHING = 0;
+const yum_yum ATE_SPACE_OR_TAB = 1;
+const yum_yum ATE_NEWLINE = 2;
+
+// Is the closest nesting level a square bracket, squiggly brace or a paren?
+
+class bracket_brace_paren_nesting_level
+{
+public:
+
+  bracket_brace_paren_nesting_level (void) : context () { }
+
+  ~bracket_brace_paren_nesting_level (void) { }
+
+  void bracket (void) { context.push (BRACKET); }
+  bool is_bracket (void)
+    { return ! context.empty () && context.top () == BRACKET; }
+
+  void brace (void) {  context.push (BRACE); }
+  bool is_brace (void)
+    { return ! context.empty () && context.top () == BRACE; }
+
+  void paren (void) {  context.push (PAREN); }
+  bool is_paren (void)
+    { return ! context.empty () && context.top () == PAREN; }
+
+  bool is_bracket_or_brace (void)
+    { return (! context.empty ()
+	      && (context.top () == BRACKET || context.top () == BRACE)); }
+
+  bool none (void) { return context.empty (); }
+
+  void remove (void) { if (! context.empty ()) context.pop (); }
+
+  void clear (void) { while (! context.empty ()) context.pop (); }
+
+private:
+
+  std::stack<int> context;
+
+  static const int BRACKET;
+  static const int BRACE;
+  static const int PAREN;
+
+  bracket_brace_paren_nesting_level (const bracket_brace_paren_nesting_level&);
+
+  bracket_brace_paren_nesting_level&
+  operator = (const bracket_brace_paren_nesting_level&);
+};
+
+const int bracket_brace_paren_nesting_level::BRACKET = 1;
+const int bracket_brace_paren_nesting_level::BRACE = 2;
+const int bracket_brace_paren_nesting_level::PAREN = 3;
+
+static bracket_brace_paren_nesting_level nesting_level;
+
+static bool Vdisplay_tokens = false;
+
+static unsigned int Vtoken_count = 0;
+
+// The start state that was in effect when the beginning of a block
+// comment was noticed.
+static int block_comment_nesting_level = 0;
+
+// Internal variable for lexer debugging state.
+static bool lexer_debug_flag = false;
+
+// Forward declarations for functions defined at the bottom of this
+// file.
+
+static int text_yyinput (void);
+static void xunput (char c, char *buf);
+static void fixup_column_count (char *s);
+static void do_comma_insert_check (void);
+static int is_keyword_token (const std::string& s);
+static void prep_for_function (void);
+static void prep_for_nested_function (void);
+static int process_comment (bool start_in_block, bool& eof);
+static bool match_any (char c, const char *s);
+static bool next_token_is_sep_op (void);
+static bool next_token_is_bin_op (bool spc_prev);
+static bool next_token_is_postfix_unary_op (bool spc_prev);
+static std::string strip_trailing_whitespace (char *s);
+static void handle_number (void);
+static int handle_string (char delim);
+static int handle_close_bracket (bool spc_gobbled, int bracket_type);
+static int handle_identifier (void);
+static bool have_continuation (bool trailing_comments_ok = true);
+static bool have_ellipsis_continuation (bool trailing_comments_ok = true);
+static void scan_for_comments (const char *);
+static yum_yum eat_whitespace (void);
+static yum_yum eat_continuation (void);
+static void maybe_warn_separator_insert (char sep);
+static void gripe_single_quote_string (void);
+static void gripe_matlab_incompatible (const std::string& msg);
+static void maybe_gripe_matlab_incompatible_comment (char c);
+static void gripe_matlab_incompatible_continuation (void);
+static void gripe_matlab_incompatible_operator (const std::string& op);
+static void display_token (int tok);
+static void lexer_debug (const char *pattern, const char *text);
+
+%}
+
+D	[0-9]
+S	[ \t]
+NL	((\n)|(\r)|(\r\n))
+SNL	({S}|{NL})
+EL	(\.\.\.)
+BS	(\\)
+CONT	({EL}|{BS})
+Im	[iIjJ]
+CCHAR	[#%]
+COMMENT	({CCHAR}.*{NL})
+SNLCMT	({SNL}|{COMMENT})
+NOT	((\~)|(\!))
+POW     ((\*\*)|(\^))
+EPOW    (\.{POW})
+IDENT	([_$a-zA-Z][_$a-zA-Z0-9]*)
+EXPON	([DdEe][+-]?{D}+)
+NUMBER	(({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+))
+%%
+
+<SCRIPT_FILE_BEGIN>. {
+    LEXER_DEBUG ("<SCRIPT_FILE_BEGIN>.");
+
+    BEGIN (INITIAL);
+    xunput (yytext[0], yytext);
+    COUNT_TOK_AND_RETURN (SCRIPT);
+  }
+
+<NESTED_FUNCTION_END>. {
+    LEXER_DEBUG ("<NESTED_FUNCTION_END>.");
+
+    BEGIN (NESTED_FUNCTION_BEGIN);
+    xunput (yytext[0], yytext);
+
+    lexer_flags.at_beginning_of_statement = true;
+
+    COUNT_TOK_AND_RETURN (';');
+  }
+
+<NESTED_FUNCTION_BEGIN>. {
+    LEXER_DEBUG ("<NESTED_FUNCTION_BEGIN>.");
+
+    BEGIN (INITIAL);
+    xunput (yytext[0], yytext);
+
+    prep_for_nested_function ();
+
+    COUNT_TOK_AND_RETURN (FCN);
+  }
+
+%{
+// Help and other command-style functions.
+%}
+
+<COMMAND_START>{NL} {
+    LEXER_DEBUG ("<COMMAND_START>{NL}");
+
+    BEGIN (INITIAL);
+    input_line_number++;
+    current_input_column = 1;
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = true;
+
+    COUNT_TOK_AND_RETURN ('\n');
+  }
+
+<COMMAND_START>[\;\,] {
+    LEXER_DEBUG ("<COMMAND_START>[\\;\\,]");
+
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = true;
+
+    BEGIN (INITIAL);
+
+    if (strcmp (yytext, ",") == 0)
+      TOK_RETURN (',');
+    else
+      TOK_RETURN (';');
+  }
+
+<COMMAND_START>[\"\'] {
+    LEXER_DEBUG ("<COMMAND_START>[\\\"\\']");
+
+    lexer_flags.at_beginning_of_statement = false;
+
+    current_input_column++;
+    int tok = handle_string (yytext[0]);
+
+    COUNT_TOK_AND_RETURN (tok);
+  }
+
+<COMMAND_START>[^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}* {
+    LEXER_DEBUG ("<COMMAND_START>[^#% \\t\\r\\n\\;\\,\\\"\\'][^ \\t\\r\\n\\;\\,]*{S}*");
+
+    std::string tok = strip_trailing_whitespace (yytext);
+
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    TOK_PUSH_AND_RETURN (tok, SQ_STRING);
+  }
+
+%{
+// For this and the next two rules, we're looking at ']', and we
+// need to know if the next token is `=' or `=='.
+//
+// It would have been so much easier if the delimiters were simply
+// different for the expression on the left hand side of the equals
+// operator.
+//
+// It's also a pain in the ass to decide whether to insert a comma
+// after seeing a ']' character...
+
+// FIXME -- we need to handle block comments here.
+%}
+
+<MATRIX_START>{SNLCMT}*\]{S}* {
+    LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*\\]{S}*");
+
+    scan_for_comments (yytext);
+    fixup_column_count (yytext);
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    int c = yytext[yyleng-1];
+    int cont_is_spc = eat_continuation ();
+    bool spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
+    int tok_to_return = handle_close_bracket (spc_gobbled, ']');
+
+    if (spc_gobbled)
+      xunput (' ', yytext);
+
+    COUNT_TOK_AND_RETURN (tok_to_return);
+  }
+
+%{
+// FIXME -- we need to handle block comments here.
+%}
+
+<MATRIX_START>{SNLCMT}*\}{S}* {
+    LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*\\}{S}*");
+
+    scan_for_comments (yytext);
+    fixup_column_count (yytext);
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    int c = yytext[yyleng-1];
+    int cont_is_spc = eat_continuation ();
+    bool spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
+    int tok_to_return = handle_close_bracket (spc_gobbled, '}');
+
+    if (spc_gobbled)
+      xunput (' ', yytext);
+
+    COUNT_TOK_AND_RETURN (tok_to_return);
+  }
+
+%{
+// Commas are element separators in matrix constants.  If we don't
+// check for continuations here we can end up inserting too many
+// commas.
+%}
+
+<MATRIX_START>{S}*\,{S}* {
+    LEXER_DEBUG ("<MATRIX_START>{S}*\\,{S}*");
+
+    current_input_column += yyleng;
+
+    int tmp = eat_continuation ();
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    if (! lexer_flags.looking_at_object_index.front ())
+      {
+	if ((tmp & ATE_NEWLINE) == ATE_NEWLINE)
+	  {
+	    maybe_warn_separator_insert (';');
+
+	    xunput (';', yytext);
+	  }
+      }
+
+    COUNT_TOK_AND_RETURN (',');
+  }
+
+%{
+// In some cases, spaces in matrix constants can turn into commas.
+// If commas are required, spaces are not important in matrix
+// constants so we just eat them.  If we don't check for continuations
+// here we can end up inserting too many commas.
+%}
+
+<MATRIX_START>{S}+ {
+    LEXER_DEBUG ("<MATRIX_START>{S}+");
+
+    current_input_column += yyleng;
+
+    lexer_flags.at_beginning_of_statement = false;
+
+    int tmp = eat_continuation ();
+
+    if (! lexer_flags.looking_at_object_index.front ())
+      {
+	bool bin_op = next_token_is_bin_op (true);
+	bool postfix_un_op = next_token_is_postfix_unary_op (true);
+	bool sep_op = next_token_is_sep_op ();
+
+	if (! (postfix_un_op || bin_op || sep_op)
+	    && nesting_level.is_bracket_or_brace ()
+	    && lexer_flags.convert_spaces_to_comma)
+	  {
+	    if ((tmp & ATE_NEWLINE) == ATE_NEWLINE)
+	      {
+		maybe_warn_separator_insert (';');
+
+		xunput (';', yytext);
+	      }
+
+	    lexer_flags.quote_is_transpose = false;
+	    lexer_flags.convert_spaces_to_comma = true;
+
+	    maybe_warn_separator_insert (',');
+
+	    COUNT_TOK_AND_RETURN (',');
+	  }
+      }
+  }
+
+%{
+// Semicolons are handled as row seprators in matrix constants.  If we
+// don't eat whitespace here we can end up inserting too many
+// semicolons.
+
+// FIXME -- we need to handle block comments here.
+%}
+
+<MATRIX_START>{SNLCMT}*;{SNLCMT}* {
+    LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*;{SNLCMT}*");
+
+    scan_for_comments (yytext);
+    fixup_column_count (yytext);
+    eat_whitespace ();
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    COUNT_TOK_AND_RETURN (';');
+  }
+
+%{
+// In some cases, new lines can also become row separators.  If we
+// don't eat whitespace here we can end up inserting too many
+// semicolons.
+
+// FIXME -- we need to handle block comments here.
+%}
+
+<MATRIX_START>{S}*{COMMENT}{SNLCMT}* |
+<MATRIX_START>{S}*{NL}{SNLCMT}* {
+    LEXER_DEBUG ("<MATRIX_START>{S}*{COMMENT}{SNLCMT}*|<MATRIX_START>{S}*{NL}{SNLCMT}*");
+
+    scan_for_comments (yytext);
+    fixup_column_count (yytext);
+    eat_whitespace ();
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    if (nesting_level.none ())
+      return LEXICAL_ERROR;
+
+    if (! lexer_flags.looking_at_object_index.front ()
+	&& nesting_level.is_bracket_or_brace ())
+      {
+	maybe_warn_separator_insert (';');
+
+	COUNT_TOK_AND_RETURN (';');
+      }
+  }
+
+\[{S}* {
+    LEXER_DEBUG ("\\[{S}*");
+
+    nesting_level.bracket ();
+
+    lexer_flags.looking_at_object_index.push_front (false);
+
+    current_input_column += yyleng;
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    if (lexer_flags.defining_func && ! lexer_flags.parsed_function_name)
+      lexer_flags.looking_at_return_list = true;
+    else
+      lexer_flags.looking_at_matrix_or_assign_lhs = true;
+
+    promptflag--;
+    eat_whitespace ();
+
+    lexer_flags.bracketflag++;
+    BEGIN (MATRIX_START);
+    COUNT_TOK_AND_RETURN ('[');
+  }
+
+\] {
+    LEXER_DEBUG ("\\]");
+
+    nesting_level.remove ();
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    TOK_RETURN (']');
+  }
+
+%{
+// Imaginary numbers.
+%}
+
+{NUMBER}{Im} {
+    LEXER_DEBUG ("{NUMBER}{Im}");
+
+    handle_number ();
+    COUNT_TOK_AND_RETURN (IMAG_NUM);
+  }
+
+%{
+// Real numbers.  Don't grab the `.' part of a dot operator as part of
+// the constant.
+%}
+
+{D}+/\.[\*/\\^\'] |
+{NUMBER} {
+    LEXER_DEBUG ("{D}+/\\.[\\*/\\^\\']|{NUMBER}");
+    handle_number ();
+    COUNT_TOK_AND_RETURN (NUM);
+  }
+
+%{
+// Eat whitespace.  Whitespace inside matrix constants is handled by
+// the <MATRIX_START> start state code above.
+%}
+
+{S}* {
+    current_input_column += yyleng;
+  }
+
+%{
+// Continuation lines.  Allow comments after continuations.
+%}
+
+{CONT}{S}*{NL} |
+{CONT}{S}*{COMMENT} {
+    LEXER_DEBUG ("{CONT}{S}*{NL}|{CONT}{S}*{COMMENT}");
+
+    if (yytext[0] == '\\')
+      gripe_matlab_incompatible_continuation ();
+    scan_for_comments (yytext);
+    promptflag--;
+    input_line_number++;
+    current_input_column = 1;
+  }
+
+%{
+// End of file.
+%}
+
+<<EOF>> {
+    LEXER_DEBUG ("<<EOF>>");
+
+    if (block_comment_nesting_level != 0)
+      {
+	warning ("block comment open at end of input");
+
+	if ((reading_fcn_file || reading_script_file)
+	    && ! curr_fcn_file_name.empty ())
+	  warning ("near line %d of file `%s.m'",
+		   input_line_number, curr_fcn_file_name.c_str ());
+      }
+
+    TOK_RETURN (END_OF_INPUT);
+  }
+
+%{
+// Identifiers.  Truncate the token at the first space or tab but
+// don't write directly on yytext.
+%}
+
+{IDENT}{S}* {
+    LEXER_DEBUG ("{IDENT}{S}*");
+
+    int id_tok = handle_identifier ();
+
+    if (id_tok >= 0)
+      COUNT_TOK_AND_RETURN (id_tok);
+  }
+
+%{
+// Function handles.
+%}
+
+"@" {
+    LEXER_DEBUG ("@");
+
+    current_input_column++;
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = false;
+    lexer_flags.looking_at_function_handle++;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    COUNT_TOK_AND_RETURN ('@');
+  }
+
+%{
+// A new line character.  New line characters inside matrix constants
+// are handled by the <MATRIX_START> start state code above.  If closest
+// nesting is inside parentheses, don't return a row separator.
+%}
+
+{NL} {
+    LEXER_DEBUG ("{NL}");
+
+    input_line_number++;
+    current_input_column = 1;
+
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+
+    if (nesting_level.none ())
+      {
+	lexer_flags.at_beginning_of_statement = true;
+	COUNT_TOK_AND_RETURN ('\n');
+      }
+    else if (nesting_level.is_paren ())
+      {
+	lexer_flags.at_beginning_of_statement = false;
+	gripe_matlab_incompatible ("bare newline inside parentheses");
+      }
+    else if (nesting_level.is_bracket_or_brace ())
+      return LEXICAL_ERROR;
+  }
+
+%{
+// Single quote can either be the beginning of a string or a transpose
+// operator. 
+%}
+
+"'" {
+    LEXER_DEBUG ("'");
+
+    current_input_column++;
+    lexer_flags.convert_spaces_to_comma = true;
+
+    if (lexer_flags.quote_is_transpose)
+      {
+	do_comma_insert_check ();
+	COUNT_TOK_AND_RETURN (QUOTE);
+      }
+    else
+      {
+	int tok = handle_string ('\'');
+	COUNT_TOK_AND_RETURN (tok);
+      }
+  }
+
+%{
+// Double quotes always begin strings.
+%}
+
+\" {
+    LEXER_DEBUG ("\"");
+
+    current_input_column++;
+    int tok = handle_string ('"');
+
+    COUNT_TOK_AND_RETURN (tok);
+}
+
+%{
+// Gobble comments.
+%} 
+
+{CCHAR} {
+    LEXER_DEBUG ("{CCHAR}");
+
+    lexer_flags.looking_for_object_index = false;
+
+    xunput (yytext[0], yytext);
+
+    bool eof = false;
+    int tok = process_comment (false, eof);
+
+    if (eof)
+      TOK_RETURN (END_OF_INPUT);
+    else if (tok > 0)
+      COUNT_TOK_AND_RETURN (tok);
+  }
+
+%{
+// Block comments.
+%}
+
+^{S}*{CCHAR}\{{S}*{NL} {
+    LEXER_DEBUG ("^{S}*{CCHAR}\\{{S}*{NL}");
+
+    lexer_flags.looking_for_object_index = false;
+
+    input_line_number++;
+    current_input_column = 1;
+    block_comment_nesting_level++;
+    promptflag--;
+
+    bool eof = false;
+    process_comment (true, eof);
+  }
+
+%{
+// Other operators.
+%}
+
+":"     { LEXER_DEBUG (":"); BIN_OP_RETURN (':', false, false); }
+
+".+"	{ LEXER_DEBUG (".+"); XBIN_OP_RETURN (EPLUS, false, false); }
+".-"	{ LEXER_DEBUG (".-"); XBIN_OP_RETURN (EMINUS, false, false); }
+".*"	{ LEXER_DEBUG (".*"); BIN_OP_RETURN (EMUL, false, false); }
+"./"	{ LEXER_DEBUG ("./"); BIN_OP_RETURN (EDIV, false, false); }
+".\\"	{ LEXER_DEBUG (".\\"); BIN_OP_RETURN (ELEFTDIV, false, false); }
+".^"	{ LEXER_DEBUG (".^"); BIN_OP_RETURN (EPOW, false, false); }
+".**"	{ LEXER_DEBUG (".**"); XBIN_OP_RETURN (EPOW, false, false); }
+".'"	{ LEXER_DEBUG (".'"); do_comma_insert_check (); BIN_OP_RETURN (TRANSPOSE, true, false); }
+"++"	{ LEXER_DEBUG ("++"); do_comma_insert_check (); XBIN_OP_RETURN (PLUS_PLUS, true, false); }
+"--"	{ LEXER_DEBUG ("--"); do_comma_insert_check (); XBIN_OP_RETURN (MINUS_MINUS, true, false); }
+"<="	{ LEXER_DEBUG ("<="); BIN_OP_RETURN (EXPR_LE, false, false); }
+"=="	{ LEXER_DEBUG ("=="); BIN_OP_RETURN (EXPR_EQ, false, false); }
+"~="	{ LEXER_DEBUG ("~="); BIN_OP_RETURN (EXPR_NE, false, false); }
+"!="	{ LEXER_DEBUG ("!="); XBIN_OP_RETURN (EXPR_NE, false, false); }
+">="	{ LEXER_DEBUG (">="); BIN_OP_RETURN (EXPR_GE, false, false); }
+"&"	{ LEXER_DEBUG ("&"); BIN_OP_RETURN (EXPR_AND, false, false); }
+"|"	{ LEXER_DEBUG ("|"); BIN_OP_RETURN (EXPR_OR, false, false); }
+"<"	{ LEXER_DEBUG ("<"); BIN_OP_RETURN (EXPR_LT, false, false); }
+">"	{ LEXER_DEBUG (">"); BIN_OP_RETURN (EXPR_GT, false, false); }
+"+"     { LEXER_DEBUG ("+"); BIN_OP_RETURN ('+', false, false); }
+"-"     { LEXER_DEBUG ("-"); BIN_OP_RETURN ('-', false, false); }
+"*"	{ LEXER_DEBUG ("*"); BIN_OP_RETURN ('*', false, false); }
+"/"	{ LEXER_DEBUG ("/"); BIN_OP_RETURN ('/', false, false); }
+"\\"	{ LEXER_DEBUG ("\\"); BIN_OP_RETURN (LEFTDIV, false, false); }
+";"     { LEXER_DEBUG (";"); BIN_OP_RETURN (';', true, true); }
+","     { LEXER_DEBUG (","); BIN_OP_RETURN (',', true, ! lexer_flags.looking_at_object_index.front ()); }
+"^"	{ LEXER_DEBUG ("^"); BIN_OP_RETURN (POW, false, false); }
+"**"	{ LEXER_DEBUG ("**"); XBIN_OP_RETURN (POW, false, false); }
+"="	{ LEXER_DEBUG ("="); BIN_OP_RETURN ('=', true, false); }
+"&&"	{ LEXER_DEBUG ("&&"); BIN_OP_RETURN (EXPR_AND_AND, false, false); }
+"||"	{ LEXER_DEBUG ("||"); BIN_OP_RETURN (EXPR_OR_OR, false, false); }
+"<<"	{ LEXER_DEBUG ("<<"); XBIN_OP_RETURN (LSHIFT, false, false); }
+">>"	{ LEXER_DEBUG (">>"); XBIN_OP_RETURN (RSHIFT, false, false); }
+
+
+{NOT} {
+    LEXER_DEBUG ("{NOT}");
+
+    if (yytext[0] == '~')
+      BIN_OP_RETURN (EXPR_NOT, false, false);
+    else
+      XBIN_OP_RETURN (EXPR_NOT, false, false);
+  }
+
+"(" {
+    LEXER_DEBUG ("(");
+
+    // If we are looking for an object index, then push TRUE for
+    // looking_at_object_index.  Otherwise, just push whatever state
+    // is current (so that we can pop it off the stack when we find
+    // the matching close paren).
+
+    lexer_flags.looking_at_object_index.push_front
+      (lexer_flags.looking_for_object_index);
+
+    lexer_flags.looking_at_indirect_ref = false;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    nesting_level.paren ();
+    promptflag--;
+
+    TOK_RETURN ('(');
+  }
+
+")" {
+    LEXER_DEBUG (")");
+
+    nesting_level.remove ();
+    current_input_column++;
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.quote_is_transpose = true;
+    lexer_flags.convert_spaces_to_comma = nesting_level.is_bracket_or_brace ();
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    do_comma_insert_check ();
+
+    COUNT_TOK_AND_RETURN (')');
+  }
+
+"." {
+    LEXER_DEBUG (".");
+
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    TOK_RETURN ('.');
+  }
+
+"+="	{ LEXER_DEBUG ("+="); XBIN_OP_RETURN (ADD_EQ, false, false); }
+"-="	{ LEXER_DEBUG ("-="); XBIN_OP_RETURN (SUB_EQ, false, false); }
+"*="	{ LEXER_DEBUG ("*="); XBIN_OP_RETURN (MUL_EQ, false, false); }
+"/="	{ LEXER_DEBUG ("/="); XBIN_OP_RETURN (DIV_EQ, false, false); }
+"\\="	{ LEXER_DEBUG ("\\="); XBIN_OP_RETURN (LEFTDIV_EQ, false, false); }
+".+="	{ LEXER_DEBUG (".+="); XBIN_OP_RETURN (ADD_EQ, false, false); }
+".-="	{ LEXER_DEBUG (".-="); XBIN_OP_RETURN (SUB_EQ, false, false); }
+".*="	{ LEXER_DEBUG (".*="); XBIN_OP_RETURN (EMUL_EQ, false, false); }
+"./="	{ LEXER_DEBUG ("./="); XBIN_OP_RETURN (EDIV_EQ, false, false); }
+".\\="	{ LEXER_DEBUG (".\\="); XBIN_OP_RETURN (ELEFTDIV_EQ, false, false); }
+{POW}=  { LEXER_DEBUG ("{POW}="); XBIN_OP_RETURN (POW_EQ, false, false); }
+{EPOW}= { LEXER_DEBUG ("{EPOW}="); XBIN_OP_RETURN (EPOW_EQ, false, false); }
+"&="	{ LEXER_DEBUG ("&="); XBIN_OP_RETURN (AND_EQ, false, false); }
+"|="	{ LEXER_DEBUG ("|="); XBIN_OP_RETURN (OR_EQ, false, false); }
+"<<="	{ LEXER_DEBUG ("<<="); XBIN_OP_RETURN (LSHIFT_EQ, false, false); }
+">>="	{ LEXER_DEBUG (">>="); XBIN_OP_RETURN (RSHIFT_EQ, false, false); }
+
+\{{S}* {
+    LEXER_DEBUG ("\\{{S}*");
+
+    nesting_level.brace ();
+
+    lexer_flags.looking_at_object_index.push_front
+      (lexer_flags.looking_for_object_index);
+
+    current_input_column += yyleng;
+    lexer_flags.quote_is_transpose = false;
+    lexer_flags.convert_spaces_to_comma = true;
+    lexer_flags.looking_for_object_index = false;
+    lexer_flags.at_beginning_of_statement = false;
+
+    promptflag--;
+    eat_whitespace ();
+
+    lexer_flags.braceflag++;
+    BEGIN (MATRIX_START);
+    COUNT_TOK_AND_RETURN ('{');
+  }
+
+"}" {
+    LEXER_DEBUG ("}");
+
+    lexer_flags.looking_at_object_index.pop_front ();
+
+    lexer_flags.looking_for_object_index = true;
+    lexer_flags.at_beginning_of_statement = false;
+
+    nesting_level.remove ();
+
+    TOK_RETURN ('}');
+  }
+
+%{
+// Unrecognized input is a lexical error.
+%}
+
+. {
+    LEXER_DEBUG (".");
+
+    // EOF happens here if we are parsing nested functions.
+
+    xunput (yytext[0], yytext);
+
+    int c = text_yyinput ();
+
+    if (c != EOF)
+      {
+	current_input_column++;
+
+	error ("invalid character `%s' (ASCII %d) near line %d, column %d",
+	       undo_string_escape (static_cast<char> (c)), c,
+	       input_line_number, current_input_column);
+
+	return LEXICAL_ERROR;
+      }
+    else
+      TOK_RETURN (END_OF_INPUT);
+  }
+
+%%
+
+// GAG.
+//
+// If we're reading a matrix and the next character is '[', make sure
+// that we insert a comma ahead of it.
+
+void
+do_comma_insert_check (void)
+{
+  int spc_gobbled = eat_continuation ();
+
+  int c = text_yyinput ();
+
+  xunput (c, yytext);
+
+  if (spc_gobbled)
+    xunput (' ', yytext);
+
+  lexer_flags.do_comma_insert = (! lexer_flags.looking_at_object_index.front ()
+				 && lexer_flags.bracketflag && c == '[');
+}
+
+// Fix things up for errors or interrupts.  The parser is never called
+// recursively, so it is always safe to reinitialize its state before
+// doing any parsing.
+
+void
+reset_parser (void)
+{
+  // Start off on the right foot.
+  BEGIN (INITIAL);
+
+  parser_end_of_input = false;
+  end_tokens_expected = 0;
+
+  while (! symtab_context.empty ())
+    symtab_context.pop ();
+
+  symbol_table::reset_parent_scope ();
+
+  // We do want a prompt by default.
+  promptflag = 1;
+
+  // We are not in a block comment.
+  block_comment_nesting_level = 0;
+
+  // Error may have occurred inside some brackets, braces, or parentheses.
+  nesting_level.clear ();
+
+  // Clear out the stack of token info used to track line and column
+  // numbers.
+  while (! token_stack.empty ())
+    {
+      delete token_stack.top ();
+      token_stack.pop ();
+    }
+
+  // Can be reset by defining a function.
+  if (! (reading_script_file || reading_fcn_file))
+    {
+      current_input_column = 1;
+      input_line_number = command_editor::current_command_number ();
+    }
+
+  // Only ask for input from stdin if we are expecting interactive
+  // input.
+  if ((interactive || forced_interactive)
+      && ! (reading_fcn_file
+	    || reading_script_file
+	    || get_input_from_eval_string
+	    || input_from_startup_file))
+    yyrestart (stdin);
+
+  // Clear the buffer for help text.
+  while (! help_buf.empty ())
+    help_buf.pop ();
+
+  // Reset other flags.
+  lexer_flags.init ();
+}
+
+static void
+display_character (char c)
+{
+  if (isgraph (c))
+    std::cerr << c;
+  else
+    switch (c)
+      {
+      case 0:
+	std::cerr << "NUL";
+	break;
+
+      case 1:
+	std::cerr << "SOH";
+	break;
+
+      case 2:
+	std::cerr << "STX";
+	break;
+
+      case 3:
+	std::cerr << "ETX";
+	break;
+
+      case 4:
+	std::cerr << "EOT";
+	break;
+
+      case 5:
+	std::cerr << "ENQ";
+	break;
+
+      case 6:
+	std::cerr << "ACK";
+	break;
+
+      case 7:
+	std::cerr << "\\a";
+	break;
+
+      case 8:
+	std::cerr << "\\b";
+	break;
+
+      case 9:
+	std::cerr << "\\t";
+	break;
+
+      case 10:
+	std::cerr << "\\n";
+	break;
+
+      case 11:
+	std::cerr << "\\v";
+	break;
+
+      case 12:
+	std::cerr << "\\f";
+	break;
+
+      case 13:
+	std::cerr << "\\r";
+	break;
+
+      case 14:
+	std::cerr << "SO";
+	break;
+
+      case 15:
+	std::cerr << "SI";
+	break;
+
+      case 16:
+	std::cerr << "DLE";
+	break;
+
+      case 17:
+	std::cerr << "DC1";
+	break;
+
+      case 18:
+	std::cerr << "DC2";
+	break;
+
+      case 19:
+	std::cerr << "DC3";
+	break;
+
+      case 20:
+	std::cerr << "DC4";
+	break;
+
+      case 21:
+	std::cerr << "NAK";
+	break;
+
+      case 22:
+	std::cerr << "SYN";
+	break;
+
+      case 23:
+	std::cerr << "ETB";
+	break;
+
+      case 24:
+	std::cerr << "CAN";
+	break;
+
+      case 25:
+	std::cerr << "EM";
+	break;
+
+      case 26:
+	std::cerr << "SUB";
+	break;
+
+      case 27:
+	std::cerr << "ESC";
+	break;
+
+      case 28:
+	std::cerr << "FS";
+	break;
+
+      case 29:
+	std::cerr << "GS";
+	break;
+
+      case 30:
+	std::cerr << "RS";
+	break;
+
+      case 31:
+	std::cerr << "US";
+	break;
+
+      case 32:
+	std::cerr << "SPACE";
+	break;
+
+      case 127:
+	std::cerr << "DEL";
+	break;
+      }
+}
+
+static int
+text_yyinput (void)
+{
+  int c = yyinput ();
+
+  if (lexer_debug_flag)
+    {
+      std::cerr << "I: ";
+      display_character (c);
+      std::cerr << std::endl;
+    }
+
+  // Convert CRLF into just LF and single CR into LF.
+
+  if (c == '\r')
+    {
+      c = yyinput ();
+
+      if (lexer_debug_flag)
+	{
+	  std::cerr << "I: ";
+	  display_character (c);
+	  std::cerr << std::endl;
+	}
+
+      if (c != '\n')
+	{
+	  xunput (c, yytext);
+	  c = '\n';
+	}
+    }
+
+  if (c == '\n')
+    input_line_number++;
+
+  return c;
+}
+
+static void
+xunput (char c, char *buf)
+{
+  if (lexer_debug_flag)
+    {
+      std::cerr << "U: ";
+      display_character (c);
+      std::cerr << std::endl;
+    }
+
+  if (c == '\n')
+    input_line_number--;
+
+  yyunput (c, buf);
+}
+
+// If we read some newlines, we need figure out what column we're
+// really looking at.
+
+static void
+fixup_column_count (char *s)
+{
+  char c;
+  while ((c = *s++) != '\0')
+    {
+      if (c == '\n')
+        {
+          input_line_number++;
+          current_input_column = 1;
+        }
+      else
+	current_input_column++;
+    }
+}
+
+// Include these so that we don't have to link to libfl.a.
+
+int
+yywrap (void)
+{
+  return 1;
+}
+
+// Tell us all what the current buffer is.
+
+YY_BUFFER_STATE
+current_buffer (void)
+{
+  return YY_CURRENT_BUFFER;
+}
+
+// Create a new buffer.
+
+YY_BUFFER_STATE
+create_buffer (FILE *f)
+{
+  return yy_create_buffer (f, YY_BUF_SIZE);
+}
+
+// Start reading a new buffer.
+
+void
+switch_to_buffer (YY_BUFFER_STATE buf)
+{
+  yy_switch_to_buffer (buf);
+}
+
+// Delete a buffer.
+
+void
+delete_buffer (YY_BUFFER_STATE buf)
+{
+  yy_delete_buffer (buf);
+}
+
+// Restore a buffer (for unwind-prot).
+
+void
+restore_input_buffer (void *buf)
+{
+  switch_to_buffer (static_cast<YY_BUFFER_STATE> (buf));
+}
+
+// Delete a buffer (for unwind-prot).
+
+void
+delete_input_buffer (void *buf)
+{
+  delete_buffer (static_cast<YY_BUFFER_STATE> (buf));
+}
+
+static void
+prep_for_function (void)
+{
+  end_tokens_expected++;
+
+  promptflag--;
+
+  lexer_flags.defining_func = true;
+  lexer_flags.parsed_function_name = false;
+
+  if (! (reading_fcn_file || reading_script_file))
+    input_line_number = 1;
+}
+
+static void
+prep_for_nested_function (void)
+{
+  lexer_flags.parsing_nested_function = 1;
+  help_buf.push (std::string ());
+  prep_for_function ();
+  // We're still only expecting one end token for this set of functions.
+  end_tokens_expected--;
+  yylval.tok_val = new token (input_line_number, current_input_column);
+  token_stack.push (yylval.tok_val);
+}
+
+static bool
+inside_any_object_index (void)
+{
+  bool retval = false;
+
+  for (std::list<bool>::const_iterator i = lexer_flags.looking_at_object_index.begin ();
+       i != lexer_flags.looking_at_object_index.end (); i++)
+    {
+      if (*i)
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+// Handle keywords.  Return -1 if the keyword should be ignored.
+
+static int
+is_keyword_token (const std::string& s)
+{
+  int l = input_line_number;
+  int c = current_input_column;
+
+  int len = s.length ();
+
+  const octave_kw *kw = octave_kw_hash::in_word_set (s.c_str (), len);
+
+  if (kw)
+    {
+      yylval.tok_val = 0;
+
+      switch (kw->kw_id)
+	{
+	case break_kw:
+	case catch_kw:
+	case continue_kw:
+	case else_kw:
+	case otherwise_kw:
+	case return_kw:
+	case unwind_protect_cleanup_kw:
+	  lexer_flags.at_beginning_of_statement = true;
+	  break;
+
+	case case_kw:
+	case elseif_kw:
+	case global_kw:
+	case static_kw:
+	case until_kw:
+	  break;
+
+	case end_kw:
+	  if (inside_any_object_index ()
+	      || (lexer_flags.defining_func
+		  && ! (lexer_flags.looking_at_return_list
+			|| lexer_flags.parsed_function_name)))
+	    return 0;
+	  else
+	    {
+	      if (reading_fcn_file && end_tokens_expected == 1)
+		return -1;
+	      else
+		{
+		  yylval.tok_val = new token (token::simple_end, l, c);
+		  lexer_flags.at_beginning_of_statement = true;
+		  end_tokens_expected--;
+		}
+	    }
+	  break;
+
+	case end_try_catch_kw:
+	  yylval.tok_val = new token (token::try_catch_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case end_unwind_protect_kw:
+	  yylval.tok_val = new token (token::unwind_protect_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endfor_kw:
+	  yylval.tok_val = new token (token::for_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endfunction_kw:
+	  {
+	    if (reading_fcn_file && end_tokens_expected == 1)
+	      return -1;
+	    else
+	      {
+		yylval.tok_val = new token (token::function_end, l, c);
+		lexer_flags.at_beginning_of_statement = true;
+		end_tokens_expected--;
+	      }
+	  }
+	  break;
+
+	case endif_kw:
+	  yylval.tok_val = new token (token::if_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endswitch_kw:
+	  yylval.tok_val = new token (token::switch_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case endwhile_kw:
+	  yylval.tok_val = new token (token::while_end, l, c);
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected--;
+	  break;
+
+	case for_kw:
+	case while_kw:
+	  end_tokens_expected++;
+	  promptflag--;
+	  lexer_flags.looping++;
+	  break;
+
+	case do_kw:
+	  lexer_flags.at_beginning_of_statement = true;
+	  promptflag--;
+	  lexer_flags.looping++;
+	  break;
+
+	case try_kw:
+	case unwind_protect_kw:
+	  lexer_flags.at_beginning_of_statement = true;
+	  end_tokens_expected++;
+	  promptflag--;
+	  break;
+
+	case if_kw:
+	case switch_kw:
+	  end_tokens_expected++;
+	  promptflag--;
+	  break;
+
+	case function_kw:
+	  {
+	    if (lexer_flags.defining_func)
+	      {
+		if (reading_fcn_file)
+		  {
+		    if (lexer_flags.parsing_nested_function)
+		      {
+			BEGIN (NESTED_FUNCTION_END);
+
+			yylval.tok_val = new token (token::function_end, l, c);
+			token_stack.push (yylval.tok_val);
+
+			lexer_flags.at_beginning_of_statement = true;
+
+			return END;
+		      }
+		    else
+		      {
+			prep_for_nested_function ();
+
+			return FCN;
+		      }
+		  }
+		else
+		  {
+		    error ("nested functions not implemented in this context");
+
+		    if ((reading_fcn_file || reading_script_file)
+			&& ! curr_fcn_file_name.empty ())
+		      error ("near line %d of file `%s.m'",
+			     input_line_number, curr_fcn_file_name.c_str ());
+		    else
+		      error ("near line %d", input_line_number);
+
+		    return LEXICAL_ERROR;
+		  }
+	      }
+	    else
+	      prep_for_function ();
+	  }
+	  break;
+
+        case magic_file_kw:
+	  {
+	    if ((reading_fcn_file || reading_script_file)
+		&& ! curr_fcn_file_full_name.empty ())
+	      yylval.tok_val = new token (curr_fcn_file_full_name, l, c);
+	    else
+	      yylval.tok_val = new token ("stdin", l, c);
+	  }
+	  break;
+
+        case magic_line_kw:
+	  yylval.tok_val = new token (static_cast<double> (l), "", l, c);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+
+      if (! yylval.tok_val)
+	yylval.tok_val = new token (l, c);
+
+      token_stack.push (yylval.tok_val);
+
+      return kw->tok;
+    }
+
+  return 0;
+}
+
+static bool
+is_variable (const std::string& name)
+{
+  return (symbol_table::is_variable (name)
+	  || (lexer_flags.pending_local_variables.find (name)
+	      != lexer_flags.pending_local_variables.end ()));
+}
+
+static std::string
+grab_block_comment (stream_reader& reader, bool& eof)
+{
+  std::string buf;
+
+  bool at_bol = true;
+  bool look_for_marker = false;
+
+  bool warned_incompatible = false;
+
+  int c = 0;
+
+  while ((c = reader.getc ()) != EOF)
+    {
+      current_input_column++;
+
+      if (look_for_marker)
+	{
+	  at_bol = false;
+	  look_for_marker = false;
+
+	  if (c == '{' || c == '}')
+	    {
+	      std::string tmp_buf (1, static_cast<char> (c));
+
+	      int type = c;
+
+	      bool done = false;
+
+	      while ((c = reader.getc ()) != EOF && ! done)
+		{
+		  current_input_column++;
+
+		  switch (c)
+		    {
+		    case ' ':
+		    case '\t':
+		      tmp_buf += static_cast<char> (c);
+		      break;
+
+		    case '\n':
+		      {
+			current_input_column = 0;
+			at_bol = true;
+			done = true;
+
+			if (type == '{')
+			  {
+			    block_comment_nesting_level++;
+			    promptflag--;
+			  }
+			else
+			  {
+			    block_comment_nesting_level--;
+			    promptflag++;
+
+			    if (block_comment_nesting_level == 0)
+			      {
+				buf += grab_comment_block (reader, true, eof);
+
+				return buf;
+			      }
+			  }
+		      }
+		      break;
+
+		    default:
+		      at_bol = false;
+		      tmp_buf += static_cast<char> (c);
+		      buf += tmp_buf;
+		      done = true;
+		      break;
+		    }
+		}
+	    }
+	}
+
+      if (at_bol && (c == '%' || c == '#'))
+        {
+          if (c == '#' && ! warned_incompatible)
+	    {
+	      warned_incompatible = true;
+	      maybe_gripe_matlab_incompatible_comment (c);
+	    }
+
+	  at_bol = false;
+	  look_for_marker = true;
+	}
+      else
+	{
+	  buf += static_cast<char> (c);
+
+	  if (c == '\n')
+	    {
+	      current_input_column = 0;
+	      at_bol = true;
+	    }
+	}
+    }
+
+  if (c == EOF)
+    eof = true;
+
+  return buf;
+}
+
+std::string
+grab_comment_block (stream_reader& reader, bool at_bol,
+		    bool& eof)
+{
+  std::string buf;
+
+  // TRUE means we are at the beginning of a comment block.
+  bool begin_comment = false;
+
+  // TRUE means we are currently reading a comment block.
+  bool in_comment = false;
+
+  bool warned_incompatible = false;
+
+  int c = 0;
+
+  while ((c = reader.getc ()) != EOF)
+    {
+      current_input_column++;
+
+      if (begin_comment)
+	{
+	  if (c == '%' || c == '#')
+	    {
+	      at_bol = false;
+	      continue;
+	    }
+	  else if (at_bol && c == '{')
+	    {
+	      std::string tmp_buf (1, static_cast<char> (c));
+
+	      bool done = false;
+
+	      while ((c = reader.getc ()) != EOF && ! done)
+		{
+		  current_input_column++;
+
+		  switch (c)
+		    {
+		    case ' ':
+		    case '\t':
+		      tmp_buf += static_cast<char> (c);
+		      break;
+
+		    case '\n':
+		      {
+			current_input_column = 0;
+			at_bol = true;
+			done = true;
+
+			block_comment_nesting_level++;
+			promptflag--;
+
+			buf += grab_block_comment (reader, eof);
+
+			in_comment = false;
+
+			if (eof)
+			  goto done;
+		      }
+		      break;
+
+		    default:
+		      at_bol = false;
+		      tmp_buf += static_cast<char> (c);
+		      buf += tmp_buf;
+		      done = true;
+		      break;
+		    }
+		}
+	    }
+	  else
+	    {
+	      at_bol = false;
+	      begin_comment = false;
+	    }
+	}	
+
+      if (in_comment)
+	{
+	  buf += static_cast<char> (c);
+
+	  if (c == '\n')
+	    {
+	      at_bol = true;
+	      current_input_column = 0;
+	      in_comment = false;
+
+	      // FIXME -- bailing out here prevents things like
+	      //
+	      //    octave> # comment
+	      //    octave> x = 1
+	      //
+	      // from failing at the command line, while still
+	      // allowing blocks of comments to be grabbed properly
+	      // for function doc strings.  But only the first line of
+	      // a mult-line doc string will be picked up for
+	      // functions defined on the command line.  We need a
+	      // better way of collecting these comments...
+	      if (! (reading_fcn_file || reading_script_file))
+		goto done;
+	    }
+	}
+      else
+	{
+	  switch (c)
+	    {
+	    case ' ':
+	    case '\t':
+	      break;
+
+	    case '#':
+	      if (! warned_incompatible)
+		{
+		  warned_incompatible = true;
+		  maybe_gripe_matlab_incompatible_comment (c);
+		}
+	      // fall through...
+
+	    case '%':
+	      in_comment = true;
+	      begin_comment = true;
+	      break;
+
+	    default:
+	      current_input_column--;
+	      reader.ungetc (c);
+	      goto done;
+	    }
+	}
+    }
+
+ done:
+
+  if (c == EOF)
+    eof = true;
+
+  return buf;
+}
+
+class
+flex_stream_reader : public stream_reader
+{
+public:
+  flex_stream_reader (char *buf_arg) : stream_reader (), buf (buf_arg) { }
+
+  int getc (void) { return ::text_yyinput (); }
+  int ungetc (int c) { ::xunput (c, buf); return 0; }
+  
+private:
+  char *buf;
+};
+
+static int
+process_comment (bool start_in_block, bool& eof)
+{
+  eof = false;
+
+  std::string help_txt;
+
+  if (! help_buf.empty ())
+    help_txt = help_buf.top ();
+
+  flex_stream_reader flex_reader (yytext);
+
+  // process_comment is only supposed to be called when we are not
+  // initially looking at a block comment.
+
+  std::string txt = start_in_block
+    ? grab_block_comment (flex_reader, eof)
+    : grab_comment_block (flex_reader, false, eof);
+
+  if (lexer_debug_flag)
+    std::cerr << "C: " << txt << std::endl;
+
+  if (help_txt.empty () && nesting_level.none ())
+    {
+      if (! help_buf.empty ())
+	help_buf.pop ();
+
+      help_buf.push (txt);
+    }
+
+  octave_comment_buffer::append (txt);
+
+  current_input_column = 1;
+  lexer_flags.quote_is_transpose = false;
+  lexer_flags.convert_spaces_to_comma = true;
+  lexer_flags.at_beginning_of_statement = true;
+
+  if (YY_START == COMMAND_START)
+    BEGIN (INITIAL);
+
+  if (nesting_level.none ())
+    return '\n';
+  else if (nesting_level.is_bracket_or_brace ())
+    return ';';
+  else
+    return 0;
+}
+
+// Return 1 if the given character matches any character in the given
+// string.
+
+static bool
+match_any (char c, const char *s)
+{
+  char tmp;
+  while ((tmp = *s++) != '\0')
+    {
+      if (c == tmp)
+	return true;
+    }
+  return false;
+}
+
+// Given information about the spacing surrounding an operator,
+// return 1 if it looks like it should be treated as a binary
+// operator.  For example,
+//
+//   [ 1 + 2 ]  or  [ 1+ 2]  or  [ 1+2 ]  ==>  binary
+//
+//   [ 1 +2 ]  ==>  unary
+
+static bool
+looks_like_bin_op (bool spc_prev, int next_char)
+{
+  bool spc_next = (next_char == ' ' || next_char == '\t');
+
+  return ((spc_prev && spc_next) || ! spc_prev);
+}
+
+// Recognize separators.  If the separator is a CRLF pair, it is
+// replaced by a single LF.
+
+static bool
+next_token_is_sep_op (void)
+{
+  bool retval = false;
+
+  int c = text_yyinput ();
+
+  retval = match_any (c, ",;\n]");
+
+  xunput (c, yytext);
+
+  return retval;
+}
+
+// Try to determine if the next token should be treated as a postfix
+// unary operator.  This is ugly, but it seems to do the right thing.
+
+static bool
+next_token_is_postfix_unary_op (bool spc_prev)
+{
+  bool un_op = false;
+
+  int c0 = text_yyinput ();
+
+  if (c0 == '\'' && ! spc_prev)
+    {
+      un_op = true;
+    }
+  else if (c0 == '.')
+    {
+      int c1 = text_yyinput ();
+      un_op = (c1 == '\'');
+      xunput (c1, yytext);
+    }
+  else if (c0 == '+')
+    {
+      int c1 = text_yyinput ();
+      un_op = (c1 == '+');
+      xunput (c1, yytext);
+    }
+  else if (c0 == '-')
+    {
+      int c1 = text_yyinput ();
+      un_op = (c1 == '-');
+      xunput (c1, yytext);
+    }
+
+  xunput (c0, yytext);
+
+  return un_op;
+}
+
+// Try to determine if the next token should be treated as a binary
+// operator.
+//
+// This kluge exists because whitespace is not always ignored inside
+// the square brackets that are used to create matrix objects (though
+// spacing only really matters in the cases that can be interpreted
+// either as binary ops or prefix unary ops: currently just +, -).
+//
+// Note that a line continuation directly following a + or - operator
+// (e.g., the characters '[' 'a' ' ' '+' '\' LFD 'b' ']') will be
+// parsed as a binary operator.
+
+static bool
+next_token_is_bin_op (bool spc_prev)
+{
+  bool bin_op = false;
+
+  int c0 = text_yyinput ();
+
+  switch (c0)
+    {
+    case '+':
+    case '-':
+      {
+	int c1 = text_yyinput ();
+
+	switch (c1)
+	  {
+	  case '+':
+	  case '-':
+	    // Unary ops, spacing doesn't matter.
+	    break;
+
+	  case '=':
+	    // Binary ops, spacing doesn't matter.
+	    bin_op = true;
+	    break;
+
+	  default:
+	    // Could be either, spacing matters.
+	    bin_op = looks_like_bin_op (spc_prev, c1);
+	    break;
+	  }
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    case ':':
+    case '/':
+    case '\\':
+    case '^':
+      // Always a binary op (may also include /=, \=, and ^=).
+      bin_op = true;
+      break;
+
+    // .+ .- ./ .\ .^ .* .**
+    case '.':
+      {
+	int c1 = text_yyinput ();
+
+	if (match_any (c1, "+-/\\^*"))
+	  // Always a binary op (may also include .+=, .-=, ./=, ...).
+	  bin_op = true;
+	else if (! isdigit (c1) && c1 != ' ' && c1 != '\t' && c1 != '.')
+	  // A structure element reference is a binary op.
+	  bin_op = true;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    // = == & && | || * **
+    case '=':
+    case '&':
+    case '|':
+    case '*':
+      // Always a binary op (may also include ==, &&, ||, **).
+      bin_op = true;
+      break;
+
+    // < <= <> > >=
+    case '<':
+    case '>':
+      // Always a binary op (may also include <=, <>, >=).
+      bin_op = true;
+      break;
+
+    // ~= !=
+    case '~':
+    case '!':
+      {
+	int c1 = text_yyinput ();
+
+	// ~ and ! can be unary ops, so require following =.
+	if (c1 == '=')
+	  bin_op = true;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  xunput (c0, yytext);
+
+  return bin_op;
+}
+
+// Used to delete trailing white space from tokens.
+
+static std::string
+strip_trailing_whitespace (char *s)
+{
+  std::string retval = s;
+
+  size_t pos = retval.find_first_of (" \t");
+
+  if (pos != std::string::npos)
+    retval.resize (pos);
+
+  return retval;
+}
+
+// FIXME -- we need to handle block comments here.
+
+static void
+scan_for_comments (const char *text)
+{
+  std::string comment_buf;
+
+  bool in_comment = false;
+  bool beginning_of_comment = false;
+
+  int len = strlen (text);
+  int i = 0;
+
+  while (i < len)
+    {
+      char c = text[i++];
+
+      switch (c)
+	{
+	case '%':
+	case '#':
+	  if (in_comment)
+	    {
+	      if (! beginning_of_comment)
+		comment_buf += static_cast<char> (c);
+	    }
+	  else
+	    {
+	      maybe_gripe_matlab_incompatible_comment (c);
+	      in_comment = true;
+	      beginning_of_comment = true;
+	    }
+	  break;
+
+	case '\n':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      octave_comment_buffer::append (comment_buf);
+	      comment_buf.resize (0);
+	      in_comment = false;
+	      beginning_of_comment = false;
+	    }
+	  break;
+
+	default:
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  break;
+	}
+    }
+
+  if (! comment_buf.empty ())
+    octave_comment_buffer::append (comment_buf);
+}
+
+// Discard whitespace, including comments and continuations.
+//
+// Return value is logical OR of the following values:
+//
+//  ATE_NOTHING      : no spaces to eat
+//  ATE_SPACE_OR_TAB : space or tab in input
+//  ATE_NEWLINE      : bare new line in input
+
+// FIXME -- we need to handle block comments here.
+
+static yum_yum
+eat_whitespace (void)
+{
+  yum_yum retval = ATE_NOTHING;
+
+  std::string comment_buf;
+
+  bool in_comment = false;
+  bool beginning_of_comment = false;
+
+  int c = 0;
+
+  while ((c = text_yyinput ()) != EOF)
+    {
+      current_input_column++;
+
+      switch (c)
+	{
+	case ' ':
+	case '\t':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  retval |= ATE_SPACE_OR_TAB;
+	  break;
+
+	case '\n':
+	  retval |= ATE_NEWLINE;
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      octave_comment_buffer::append (comment_buf);
+	      comment_buf.resize (0);
+	      in_comment = false;
+	      beginning_of_comment = false;
+	    }
+	  current_input_column = 0;
+	  break;
+
+	case '#':
+	case '%':
+	  if (in_comment)
+	    {
+	      if (! beginning_of_comment)
+		comment_buf += static_cast<char> (c);
+	    }
+	  else
+	    {
+	      maybe_gripe_matlab_incompatible_comment (c);
+	      in_comment = true;
+	      beginning_of_comment = true;
+	    }
+	  break;
+
+	case '.':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	      break;
+	    }
+	  else
+	    {
+	      if (have_ellipsis_continuation ())
+		break;
+	      else
+		goto done;
+	    }
+
+	case '\\':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	      break;
+	    }
+	  else
+	    {
+	      if (have_continuation ())
+		break;
+	      else
+		goto done;
+	    }
+
+	default:
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	      break;
+	    }
+	  else
+	    goto done;
+	}
+    }
+
+  if (! comment_buf.empty ())
+    octave_comment_buffer::append (comment_buf);
+
+ done:
+  xunput (c, yytext);
+  current_input_column--;
+  return retval;
+}
+
+static inline bool
+looks_like_hex (const char *s, int len)
+{
+  return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
+}
+
+static void
+handle_number (void)
+{
+  double value = 0.0;
+  int nread = 0;
+
+  if (looks_like_hex (yytext, strlen (yytext)))
+    {
+      unsigned long ival;
+
+      nread = sscanf (yytext, "%lx", &ival);
+
+      value = static_cast<double> (ival);
+    }
+  else
+    {
+      char *tmp = strsave (yytext);
+
+      char *idx = strpbrk (tmp, "Dd");
+
+      if (idx)
+	*idx = 'e';
+
+      nread = sscanf (tmp, "%lf", &value);
+
+      delete [] tmp;
+    }
+
+  // If yytext doesn't contain a valid number, we are in deep doo doo.
+
+  assert (nread == 1);
+
+  lexer_flags.quote_is_transpose = true;
+  lexer_flags.convert_spaces_to_comma = true;
+  lexer_flags.looking_for_object_index = true;
+  lexer_flags.at_beginning_of_statement = false;
+
+  yylval.tok_val = new token (value, yytext, input_line_number,
+			      current_input_column);
+
+  token_stack.push (yylval.tok_val);
+
+  current_input_column += yyleng;
+
+  do_comma_insert_check ();
+}
+
+// We have seen a backslash and need to find out if it should be
+// treated as a continuation character.  If so, this eats it, up to
+// and including the new line character.
+//
+// Match whitespace only, followed by a comment character or newline.
+// Once a comment character is found, discard all input until newline.
+// If non-whitespace characters are found before comment
+// characters, return 0.  Otherwise, return 1.
+
+// FIXME -- we need to handle block comments here.
+
+static bool
+have_continuation (bool trailing_comments_ok)
+{
+  std::ostringstream buf;
+
+  std::string comment_buf;
+
+  bool in_comment = false;
+  bool beginning_of_comment = false;
+
+  int c = 0;
+
+  while ((c = text_yyinput ()) != EOF)
+    {
+      buf << static_cast<char> (c);
+
+      switch (c)
+	{
+	case ' ':
+	case '\t':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  break;
+
+	case '%':
+	case '#':
+	  if (trailing_comments_ok)
+	    {
+	      if (in_comment)
+		{
+		  if (! beginning_of_comment)
+		    comment_buf += static_cast<char> (c);
+		}
+	      else
+		{
+		  maybe_gripe_matlab_incompatible_comment (c);
+		  in_comment = true;
+		  beginning_of_comment = true;
+		}
+	    }
+	  else
+	    goto cleanup;
+	  break;
+
+	case '\n':
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      octave_comment_buffer::append (comment_buf);
+	    }
+	  current_input_column = 0;
+	  promptflag--;
+	  gripe_matlab_incompatible_continuation ();
+	  return true;
+
+	default:
+	  if (in_comment)
+	    {
+	      comment_buf += static_cast<char> (c);
+	      beginning_of_comment = false;
+	    }
+	  else
+	    goto cleanup;
+	  break;
+	}
+    }
+
+  xunput (c, yytext);
+  return false;
+
+cleanup:
+
+  std::string s = buf.str ();
+
+  int len = s.length ();
+  while (len--)
+    xunput (s[len], yytext);
+
+  return false;
+}
+
+// We have seen a `.' and need to see if it is the start of a
+// continuation.  If so, this eats it, up to and including the new
+// line character.
+
+static bool
+have_ellipsis_continuation (bool trailing_comments_ok)
+{
+  char c1 = text_yyinput ();
+  if (c1 == '.')
+    {
+      char c2 = text_yyinput ();
+      if (c2 == '.' && have_continuation (trailing_comments_ok))
+	return true;
+      else
+	{
+	  xunput (c2, yytext);
+	  xunput (c1, yytext);
+	}
+    }
+  else
+    xunput (c1, yytext);
+
+  return false;
+}
+
+// See if we have a continuation line.  If so, eat it and the leading
+// whitespace on the next line.
+//
+// Return value is the same as described for eat_whitespace().
+
+static yum_yum
+eat_continuation (void)
+{
+  int retval = ATE_NOTHING;
+
+  int c = text_yyinput ();
+
+  if ((c == '.' && have_ellipsis_continuation ())
+      || (c == '\\' && have_continuation ()))
+    retval = eat_whitespace ();
+  else
+    xunput (c, yytext);
+
+  return retval;
+}
+
+static int
+handle_string (char delim)
+{
+  std::ostringstream buf;
+
+  int bos_line = input_line_number;
+  int bos_col = current_input_column;
+
+  int c;
+  int escape_pending = 0;
+
+  while ((c = text_yyinput ()) != EOF)
+    {
+      current_input_column++;
+
+      if (c == '\\')
+	{
+	  if (delim == '\'' || escape_pending)
+	    {
+	      buf << static_cast<char> (c);
+	      escape_pending = 0;
+	    }
+	  else
+	    {
+	      if (have_continuation (false))
+		escape_pending = 0;
+	      else
+		{
+		  buf << static_cast<char> (c);
+		  escape_pending = 1;
+		}
+	    }
+	  continue;
+	}
+      else if (c == '.')
+	{
+	  if (delim == '\'' || ! have_ellipsis_continuation (false))
+	    buf << static_cast<char> (c);
+	}
+      else if (c == '\n')
+	{
+	  error ("unterminated string constant");
+	  break;
+	}
+      else if (c == delim)
+	{
+	  if (escape_pending)
+	    buf << static_cast<char> (c);
+	  else
+	    {
+	      c = text_yyinput ();
+	      if (c == delim)
+		{
+		  buf << static_cast<char> (c);		    
+		}
+	      else
+		{
+		  std::string s;  
+		  xunput (c, yytext);
+
+		  if (delim == '\'')
+		    s = buf.str ();
+		  else
+		    s = do_string_escapes (buf.str ());
+
+		  lexer_flags.quote_is_transpose = true;
+		  lexer_flags.convert_spaces_to_comma = true;
+
+		  yylval.tok_val = new token (s, bos_line, bos_col);
+		  token_stack.push (yylval.tok_val);
+
+		  if (delim == '"')
+		    gripe_matlab_incompatible ("\" used as string delimiter");
+		  else if (delim == '\'')
+		    gripe_single_quote_string ();
+
+                  lexer_flags.looking_for_object_index = true;
+		  lexer_flags.at_beginning_of_statement = false;
+
+		  return delim == '"' ? DQ_STRING : SQ_STRING;
+		}
+	    }
+	}
+      else
+	{
+	  buf << static_cast<char> (c);
+	}
+
+      escape_pending = 0;
+    }
+
+  return LEXICAL_ERROR;
+}
+
+static bool
+next_token_is_assign_op (void)
+{
+  bool retval = false;
+
+  int c0 = text_yyinput ();
+
+  switch (c0)
+    {
+    case '=':
+      {
+	int c1 = text_yyinput ();
+	xunput (c1, yytext);
+	if (c1 != '=')
+	  retval = true;
+      }
+      break;
+
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '\\':
+    case '&':
+    case '|':
+      {
+	int c1 = text_yyinput ();
+	xunput (c1, yytext);
+	if (c1 == '=')
+	  retval = true;
+      }
+      break;
+
+    case '.':
+      {
+	int c1 = text_yyinput ();
+	if (match_any (c1, "+-*/\\"))
+	  {
+	    int c2 = text_yyinput ();
+	    xunput (c2, yytext);
+	    if (c2 == '=')
+	      retval = true;
+	  }
+	xunput (c1, yytext);
+      }
+      break;
+
+    case '>':
+      {
+	int c1 = text_yyinput ();
+	if (c1 == '>')
+	  {
+	    int c2 = text_yyinput ();
+	    xunput (c2, yytext);
+	    if (c2 == '=')
+	      retval = true;
+	  }
+	xunput (c1, yytext);
+      }
+      break;
+
+    case '<':
+      {
+	int c1 = text_yyinput ();
+	if (c1 == '<')
+	  {
+	    int c2 = text_yyinput ();
+	    xunput (c2, yytext);
+	    if (c2 == '=')
+	      retval = true;
+	  }
+	xunput (c1, yytext);
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  xunput (c0, yytext);
+
+  return retval;
+}
+
+static bool
+next_token_is_index_op (void)
+{
+  int c = text_yyinput ();
+  xunput (c, yytext);
+  return c == '(' || c == '{';
+}
+
+static int
+handle_close_bracket (bool spc_gobbled, int bracket_type)
+{
+  int retval = bracket_type;
+
+  if (! nesting_level.none ())
+    {
+      nesting_level.remove ();
+
+      if (bracket_type == ']')
+	lexer_flags.bracketflag--;
+      else if (bracket_type == '}')
+	lexer_flags.braceflag--;
+      else
+	panic_impossible ();
+    }
+
+  if (lexer_flags.bracketflag == 0 && lexer_flags.braceflag == 0)
+    BEGIN (INITIAL);
+
+  if (bracket_type == ']'
+      && next_token_is_assign_op ()
+      && ! lexer_flags.looking_at_return_list)
+    {
+      retval = CLOSE_BRACE;
+    }
+  else if ((lexer_flags.bracketflag || lexer_flags.braceflag)
+	   && lexer_flags.convert_spaces_to_comma
+	   && (nesting_level.is_bracket ()
+	       || (nesting_level.is_brace ()
+		   && ! lexer_flags.looking_at_object_index.front ())))
+    {
+      bool index_op = next_token_is_index_op ();
+
+      // Don't insert comma if we are looking at something like
+      //
+      //   [x{i}{j}] or [x{i}(j)]
+      //
+      // but do if we are looking at
+      //
+      //   [x{i} {j}] or [x{i} (j)]
+
+      if (spc_gobbled || ! (bracket_type == '}' && index_op))
+	{
+	  bool bin_op = next_token_is_bin_op (spc_gobbled);
+
+	  bool postfix_un_op = next_token_is_postfix_unary_op (spc_gobbled);
+
+	  bool sep_op = next_token_is_sep_op ();
+
+	  if (! (postfix_un_op || bin_op || sep_op))
+	    {
+	      maybe_warn_separator_insert (',');
+
+	      xunput (',', yytext);
+	      return retval;
+	    }
+	}
+    }
+
+  lexer_flags.quote_is_transpose = true;
+  lexer_flags.convert_spaces_to_comma = true;
+
+  return retval;
+}
+
+static void
+maybe_unput_comma (int spc_gobbled)
+{
+  if (nesting_level.is_bracket ()
+      || (nesting_level.is_brace ()
+	  && ! lexer_flags.looking_at_object_index.front ()))
+    {
+      int bin_op = next_token_is_bin_op (spc_gobbled);
+
+      int postfix_un_op = next_token_is_postfix_unary_op (spc_gobbled);
+
+      int c1 = text_yyinput ();
+      int c2 = text_yyinput ();
+
+      xunput (c2, yytext);
+      xunput (c1, yytext);
+
+      int sep_op = next_token_is_sep_op ();
+
+      int dot_op = (c1 == '.'
+		    && (isalpha (c2) || isspace (c2) || c2 == '_'));
+
+      if (postfix_un_op || bin_op || sep_op || dot_op)
+	return;
+
+      int index_op = (c1 == '(' || c1 == '{');
+
+      // If there is no space before the indexing op, we don't insert
+      // a comma.
+
+      if (index_op && ! spc_gobbled)
+	return;
+
+      maybe_warn_separator_insert (',');
+
+      xunput (',', yytext);
+    }
+}
+
+static bool
+next_token_can_follow_bin_op (void)
+{
+  std::stack<char> buf;
+
+  int c = EOF;
+
+  // Skip whitespace in current statement on current line
+  while (true)
+    {
+      c = text_yyinput ();
+
+      buf.push (c);
+
+      if (match_any (c, ",;\n") || (c != ' ' && c != '\t'))
+	break;
+    }
+
+  // Restore input.
+  while (! buf.empty ())
+    {
+      xunput (buf.top (), yytext);
+
+      buf.pop ();
+    }
+
+  return (isalnum (c) || match_any (c, "!\"'(-[_{~"));
+}
+
+static bool
+looks_like_command_arg (void)
+{
+  bool retval = true;
+
+  int c0 = text_yyinput ();
+
+  switch (c0)
+    {
+    // = ==
+    case '=':
+      {
+	int c1 = text_yyinput ();
+
+	if (c1 == '=')
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, yytext);
+	  }
+	else
+	  retval = false;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    case '(':
+    case '{':
+      // Indexing.
+      retval = false;
+      break;
+
+    case '\n':
+      // EOL.
+      break;
+
+    case '\'':
+    case '"':
+      // Beginning of a character string.
+      break;
+
+    // + - ++ -- += -=
+    case '+':
+    case '-':
+      {
+	int c1 = text_yyinput ();
+
+	switch (c1)
+	  {
+	  case '\n':
+	    // EOL.
+	  case '+':
+	  case '-':
+	    // Unary ops, spacing doesn't matter.
+	    break;
+
+	  case '\t':
+	  case ' ':
+	    {
+	      if (next_token_can_follow_bin_op ())
+		retval = false;
+	    }
+	    break;
+
+	  case '=':
+	    {
+	      int c2 = text_yyinput ();
+
+	      if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		  && next_token_can_follow_bin_op ())
+		retval = false;
+
+	      xunput (c2, yytext);
+	    }
+	    break;
+	  }
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    case ':':
+    case '/':
+    case '\\':
+    case '^':
+      {
+	int c1 = text_yyinput ();
+
+	if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+	    && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    // .+ .- ./ .\ .^ .* .**
+    case '.':
+      {
+	int c1 = text_yyinput ();
+
+	if (match_any (c1, "+-/\\^*"))
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (c2 == '=')
+	      {
+		int c3 = text_yyinput ();
+
+		if (! match_any (c3, ",;\n") && (c3 == ' ' || c3 == '\t')
+		    && next_token_can_follow_bin_op ())
+		  retval = false;
+
+		xunput (c3, yytext);
+	      }
+	    else if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		     && next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, yytext);
+	  }
+	else if (! match_any (c1, ",;\n")
+		 && (! isdigit (c1) && c1 != ' ' && c1 != '\t'
+		     && c1 != '.'))
+	  {
+	    // Structure reference.  FIXME -- is this a complete check?
+
+	    retval = false;
+	  }
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    // & && | || * **
+    case '&':
+    case '|':
+    case '*':
+      {
+	int c1 = text_yyinput ();
+
+	if (c1 == c0)
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, yytext);
+	  }
+	else if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+		 && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    // < <= > >=
+    case '<':
+    case '>':
+      {
+	int c1 = text_yyinput ();
+
+	if (c1 == '=')
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, yytext);
+	  }
+	else if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+		 && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    // ~= !=
+    case '~':
+    case '!':
+      {
+	int c1 = text_yyinput ();
+
+	// ~ and ! can be unary ops, so require following =.
+	if (c1 == '=')
+	  {
+	    int c2 = text_yyinput ();
+
+	    if (! match_any (c2, ",;\n") && (c2 == ' ' || c2 == '\t')
+		&& next_token_can_follow_bin_op ())
+	      retval = false;
+
+	    xunput (c2, yytext);
+	  }
+	else if (! match_any (c1, ",;\n") && (c1 == ' ' || c1 == '\t')
+		 && next_token_can_follow_bin_op ())
+	  retval = false;
+
+	xunput (c1, yytext);
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  xunput (c0, yytext);
+
+  return retval;
+}
+
+// Figure out exactly what kind of token to return when we have seen
+// an identifier.  Handles keywords.  Return -1 if the identifier
+// should be ignored.
+
+static int
+handle_identifier (void)
+{
+  bool at_bos = lexer_flags.at_beginning_of_statement;
+
+  std::string tok = strip_trailing_whitespace (yytext);
+
+  int c = yytext[yyleng-1];
+
+  int cont_is_spc = eat_continuation ();
+
+  int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
+
+  // If we are expecting a structure element, avoid recognizing
+  // keywords and other special names and return STRUCT_ELT, which is
+  // a string that is also a valid identifier.  But first, we have to
+  // decide whether to insert a comma.
+
+  if (lexer_flags.looking_at_indirect_ref)
+    {
+      do_comma_insert_check ();
+
+      maybe_unput_comma (spc_gobbled);
+
+      yylval.tok_val = new token (tok, input_line_number,
+				  current_input_column);
+
+      token_stack.push (yylval.tok_val);
+
+      lexer_flags.quote_is_transpose = true;
+      lexer_flags.convert_spaces_to_comma = true;
+      lexer_flags.looking_for_object_index = true;
+
+      current_input_column += yyleng;
+
+      return STRUCT_ELT;
+    }
+
+  lexer_flags.at_beginning_of_statement = false;
+
+  // The is_keyword_token may reset
+  // lexer_flags.at_beginning_of_statement.  For example, if it sees
+  // an else token, then the next token is at the beginning of a
+  // statement.
+
+  int kw_token = is_keyword_token (tok);
+
+  // If we found a keyword token, then the beginning_of_statement flag
+  // is already set.  Otherwise, we won't be at the beginning of a
+  // statement.
+
+  if (lexer_flags.looking_at_function_handle)
+    {
+      if (kw_token)
+	{
+	  error ("function handles may not refer to keywords");
+
+	  return LEXICAL_ERROR;
+	}
+      else
+	{
+	  yylval.tok_val = new token (tok, input_line_number,
+				      current_input_column);
+
+	  token_stack.push (yylval.tok_val);
+
+	  current_input_column += yyleng;
+	  lexer_flags.quote_is_transpose = false;
+	  lexer_flags.convert_spaces_to_comma = true;
+	  lexer_flags.looking_for_object_index = true;
+
+	  return FCN_HANDLE;
+	}
+    }
+
+  // If we have a regular keyword, return it.
+  // Keywords can be followed by identifiers.
+
+  if (kw_token)
+    {
+      if (kw_token >= 0)
+	{
+	  current_input_column += yyleng;
+	  lexer_flags.quote_is_transpose = false;
+	  lexer_flags.convert_spaces_to_comma = true;
+	  lexer_flags.looking_for_object_index = false;
+	}
+
+      return kw_token;
+    }
+
+  // See if we have a plot keyword (title, using, with, or clear).
+
+  int c1 = text_yyinput ();
+
+  bool next_tok_is_eq = false;
+  if (c1 == '=')
+    {
+      int c2 = text_yyinput ();
+      xunput (c2, yytext);
+
+      if (c2 != '=')
+	next_tok_is_eq = true;
+    }
+
+  xunput (c1, yytext);
+
+  // Kluge alert.
+  //
+  // If we are looking at a text style function, set up to gobble its
+  // arguments.
+  //
+  // If the following token is `=', or if we are parsing a function
+  // return list or function parameter list, or if we are looking at
+  // something like [ab,cd] = foo (), force the symbol to be inserted
+  // as a variable in the current symbol table.
+
+  if (! is_variable (tok))
+    {
+      if (at_bos && spc_gobbled && looks_like_command_arg ())
+	{
+	  BEGIN (COMMAND_START);
+	}
+      else if (next_tok_is_eq
+	       || lexer_flags.looking_at_decl_list
+	       || lexer_flags.looking_at_return_list
+	       || (lexer_flags.looking_at_parameter_list
+		   && ! lexer_flags.looking_at_initializer_expression))
+	{
+	  symbol_table::force_variable (tok);
+	}
+      else if (lexer_flags.looking_at_matrix_or_assign_lhs)
+	{
+	  lexer_flags.pending_local_variables.insert (tok);
+	}
+    }
+
+  // Find the token in the symbol table.  Beware the magic
+  // transformation of the end keyword...
+
+  if (tok == "end")
+    tok = "__end__";    
+
+  yylval.tok_val = new token (&(symbol_table::insert (tok)),
+			      input_line_number, current_input_column);
+
+  token_stack.push (yylval.tok_val);
+
+  // After seeing an identifer, it is ok to convert spaces to a comma
+  // (if needed).
+
+  lexer_flags.convert_spaces_to_comma = true;
+
+  if (! (next_tok_is_eq || YY_START == COMMAND_START))
+    {
+      lexer_flags.quote_is_transpose = true;
+
+      do_comma_insert_check ();
+
+      maybe_unput_comma (spc_gobbled);
+    }
+
+  current_input_column += yyleng;
+
+  if (tok != "__end__")
+    lexer_flags.looking_for_object_index = true;
+
+  return NAME;
+}
+
+void
+lexical_feedback::init (void)
+{
+  // Not initially defining a matrix list.
+  bracketflag = 0;
+
+  // Not initially defining a cell array list.
+  braceflag = 0;
+
+  // Not initially inside a loop or if statement.
+  looping = 0;
+
+  // Not initially defining a function.
+  defining_func = false;
+  parsed_function_name = false;
+  parsing_nested_function = 0;
+  parsing_class_method = false;
+
+  // Not initiallly looking at a function handle.
+  looking_at_function_handle = 0;
+
+  // Not parsing a function return, parameter, or declaration list.
+  looking_at_return_list = false;
+  looking_at_parameter_list = false;
+  looking_at_decl_list = false;
+
+  // Not looking at an argument list initializer expression.
+  looking_at_initializer_expression = false;
+
+  // Not parsing a matrix or the left hand side of multi-value
+  // assignment statement.
+  looking_at_matrix_or_assign_lhs = false;
+
+  // Not parsing an object index.
+  while (! looking_at_object_index.empty ())
+    looking_at_object_index.pop_front ();
+
+  looking_at_object_index.push_front (false);
+
+  // Object index not possible until we've seen something.
+  looking_for_object_index = false;
+
+  // Yes, we are at the beginning of a statement.
+  at_beginning_of_statement = true;
+
+  // No need to do comma insert or convert spaces to comma at
+  // beginning of input. 
+  convert_spaces_to_comma = true;
+  do_comma_insert = false;
+
+  // Not initially looking at indirect references.
+  looking_at_indirect_ref = false;
+
+  // Quote marks strings intially.
+  quote_is_transpose = false;
+
+  // Set of identifiers that might be local variable names is empty.
+  pending_local_variables.clear ();
+}
+
+bool
+is_keyword (const std::string& s)
+{
+  return octave_kw_hash::in_word_set (s.c_str (), s.length ()) != 0;
+}
+
+DEFUN (iskeyword, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} iskeyword (@var{name})\n\
+Return true if @var{name} is an Octave keyword.  If @var{name}\n\
+is omitted, return a list of keywords.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("iskeyword");
+
+  if (error_state)
+    return retval;
+
+  if (argc == 1)
+    {
+      string_vector lst (TOTAL_KEYWORDS);
+
+      for (int i = 0; i < TOTAL_KEYWORDS; i++)
+	lst[i] = wordlist[i].name;
+
+      retval = Cell (lst.sort ());
+    }
+  else if (argc == 2)
+    {
+      retval = is_keyword (argv[1]);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+void
+prep_lexer_for_script (void)
+{
+  BEGIN (SCRIPT_FILE_BEGIN);
+}
+
+static void
+maybe_warn_separator_insert (char sep)
+{
+  std::string nm = curr_fcn_file_full_name;
+
+  if (nm.empty ())
+    warning_with_id ("Octave:separator-insert",
+		     "potential auto-insertion of `%c' near line %d",
+		     sep, input_line_number);
+  else
+    warning_with_id ("Octave:separator-insert",
+		     "potential auto-insertion of `%c' near line %d of file %s",
+		     sep, input_line_number, nm.c_str ());
+}
+
+static void
+gripe_single_quote_string (void)
+{
+  std::string nm = curr_fcn_file_full_name;
+
+  if (nm.empty ())
+    warning_with_id ("Octave:single-quote-string",
+		     "single quote delimited string near line %d",
+		     input_line_number);
+  else
+    warning_with_id ("Octave:single-quote-string",
+		     "single quote delimited string near line %d of file %s",
+		     input_line_number, nm.c_str ());
+}
+
+static void
+gripe_matlab_incompatible (const std::string& msg)
+{
+  std::string nm = curr_fcn_file_full_name;
+
+  if (nm.empty ())
+    warning_with_id ("Octave:matlab-incompatible",
+		     "potential Matlab compatibility problem: %s",
+		     msg.c_str ());
+  else
+    warning_with_id ("Octave:matlab-incompatible",
+		     "potential Matlab compatibility problem: %s near line %d offile %s",
+		     msg.c_str (), input_line_number, nm.c_str ());
+}
+
+static void
+maybe_gripe_matlab_incompatible_comment (char c)
+{
+  if (c == '#')
+    gripe_matlab_incompatible ("# used as comment character");
+}
+
+static void
+gripe_matlab_incompatible_continuation (void)
+{
+  gripe_matlab_incompatible ("\\ used as line continuation marker");
+}
+
+static void
+gripe_matlab_incompatible_operator (const std::string& op)
+{
+  std::string t = op;
+  int n = t.length ();
+  if (t[n-1] == '\n')
+    t.resize (n-1);
+  gripe_matlab_incompatible (t + " used as operator");
+}
+
+static void
+display_token (int tok)
+{
+  switch (tok)
+    {
+    case '=': std::cerr << "'='\n"; break;
+    case ':': std::cerr << "':'\n"; break;
+    case '-': std::cerr << "'-'\n"; break;
+    case '+': std::cerr << "'+'\n"; break;
+    case '*': std::cerr << "'*'\n"; break;
+    case '/': std::cerr << "'/'\n"; break;
+    case ADD_EQ: std::cerr << "ADD_EQ\n"; break;
+    case SUB_EQ: std::cerr << "SUB_EQ\n"; break;
+    case MUL_EQ: std::cerr << "MUL_EQ\n"; break;
+    case DIV_EQ: std::cerr << "DIV_EQ\n"; break;
+    case LEFTDIV_EQ: std::cerr << "LEFTDIV_EQ\n"; break;
+    case POW_EQ: std::cerr << "POW_EQ\n"; break;
+    case EMUL_EQ: std::cerr << "EMUL_EQ\n"; break;
+    case EDIV_EQ: std::cerr << "EDIV_EQ\n"; break;
+    case ELEFTDIV_EQ: std::cerr << "ELEFTDIV_EQ\n"; break;
+    case EPOW_EQ: std::cerr << "EPOW_EQ\n"; break;
+    case AND_EQ: std::cerr << "AND_EQ\n"; break;
+    case OR_EQ: std::cerr << "OR_EQ\n"; break;
+    case LSHIFT_EQ: std::cerr << "LSHIFT_EQ\n"; break;
+    case RSHIFT_EQ: std::cerr << "RSHIFT_EQ\n"; break;
+    case LSHIFT: std::cerr << "LSHIFT\n"; break;
+    case RSHIFT: std::cerr << "RSHIFT\n"; break;
+    case EXPR_AND_AND: std::cerr << "EXPR_AND_AND\n"; break;
+    case EXPR_OR_OR: std::cerr << "EXPR_OR_OR\n"; break;
+    case EXPR_AND: std::cerr << "EXPR_AND\n"; break;
+    case EXPR_OR: std::cerr << "EXPR_OR\n"; break;
+    case EXPR_NOT: std::cerr << "EXPR_NOT\n"; break;
+    case EXPR_LT: std::cerr << "EXPR_LT\n"; break;
+    case EXPR_LE: std::cerr << "EXPR_LE\n"; break;
+    case EXPR_EQ: std::cerr << "EXPR_EQ\n"; break;
+    case EXPR_NE: std::cerr << "EXPR_NE\n"; break;
+    case EXPR_GE: std::cerr << "EXPR_GE\n"; break;
+    case EXPR_GT: std::cerr << "EXPR_GT\n"; break;
+    case LEFTDIV: std::cerr << "LEFTDIV\n"; break;
+    case EMUL: std::cerr << "EMUL\n"; break;
+    case EDIV: std::cerr << "EDIV\n"; break;
+    case ELEFTDIV: std::cerr << "ELEFTDIV\n"; break;
+    case EPLUS: std::cerr << "EPLUS\n"; break;
+    case EMINUS: std::cerr << "EMINUS\n"; break;
+    case QUOTE: std::cerr << "QUOTE\n"; break;
+    case TRANSPOSE: std::cerr << "TRANSPOSE\n"; break;
+    case PLUS_PLUS: std::cerr << "PLUS_PLUS\n"; break;
+    case MINUS_MINUS: std::cerr << "MINUS_MINUS\n"; break;
+    case POW: std::cerr << "POW\n"; break;
+    case EPOW: std::cerr << "EPOW\n"; break;
+    case NUM: std::cerr << "NUM\n"; break;
+    case IMAG_NUM: std::cerr << "IMAG_NUM\n"; break;
+    case STRUCT_ELT: std::cerr << "STRUCT_ELT\n"; break;
+    case NAME: std::cerr << "NAME\n"; break;
+    case END: std::cerr << "END\n"; break;
+    case DQ_STRING: std::cerr << "DQ_STRING\n"; break;
+    case SQ_STRING: std::cerr << "SQ_STRING\n"; break;
+    case FOR: std::cerr << "FOR\n"; break;
+    case WHILE: std::cerr << "WHILE\n"; break;
+    case DO: std::cerr << "DO\n"; break;
+    case UNTIL: std::cerr << "UNTIL\n"; break;
+    case IF: std::cerr << "IF\n"; break;
+    case ELSEIF: std::cerr << "ELSEIF\n"; break;
+    case ELSE: std::cerr << "ELSE\n"; break;
+    case SWITCH: std::cerr << "SWITCH\n"; break;
+    case CASE: std::cerr << "CASE\n"; break;
+    case OTHERWISE: std::cerr << "OTHERWISE\n"; break;
+    case BREAK: std::cerr << "BREAK\n"; break;
+    case CONTINUE: std::cerr << "CONTINUE\n"; break;
+    case FUNC_RET: std::cerr << "FUNC_RET\n"; break;
+    case UNWIND: std::cerr << "UNWIND\n"; break;
+    case CLEANUP: std::cerr << "CLEANUP\n"; break;
+    case TRY: std::cerr << "TRY\n"; break;
+    case CATCH: std::cerr << "CATCH\n"; break;
+    case GLOBAL: std::cerr << "GLOBAL\n"; break;
+    case STATIC: std::cerr << "STATIC\n"; break;
+    case FCN_HANDLE: std::cerr << "FCN_HANDLE\n"; break;
+    case END_OF_INPUT: std::cerr << "END_OF_INPUT\n\n"; break;
+    case LEXICAL_ERROR: std::cerr << "LEXICAL_ERROR\n\n"; break;
+    case FCN: std::cerr << "FCN\n"; break;
+    case CLOSE_BRACE: std::cerr << "CLOSE_BRACE\n"; break;
+    case '\n': std::cerr << "\\n\n"; break;
+    case '\r': std::cerr << "\\r\n"; break;
+    case '\t': std::cerr << "TAB\n"; break;
+    default:
+      {
+        if (tok < 256)
+	  std::cerr << static_cast<char> (tok) << "\n";
+	else
+	  std::cerr << "UNKNOWN(" << tok << ")\n";
+      }
+      break;
+    }
+}
+
+static void
+display_state (void)
+{
+  std::cerr << "S: ";
+
+  switch (YY_START)
+    {
+    case INITIAL:
+      std::cerr << "INITIAL" << std::endl;
+      break;
+
+    case COMMAND_START:
+      std::cerr << "COMMAND_START" << std::endl;
+      break;
+
+    case MATRIX_START:
+      std::cerr << "MATRIX_START" << std::endl;
+      break;
+
+    case SCRIPT_FILE_BEGIN:
+      std::cerr << "SCRIPT_FILE_BEGIN" << std::endl;
+      break;
+
+    case NESTED_FUNCTION_END:
+      std::cerr << "NESTED_FUNCTION_END" << std::endl;
+      break;
+
+    case NESTED_FUNCTION_BEGIN:
+      std::cerr << "NESTED_FUNCTION_BEGIN" << std::endl;
+      break;
+
+    default:
+      std::cerr << "UNKNOWN START STATE!" << std::endl;
+      break;
+    }
+}
+
+static void
+lexer_debug (const char *pattern, const char *text)
+{
+  std::cerr << std::endl;
+
+  display_state ();
+
+  std::cerr << "P: " << pattern << std::endl;
+  std::cerr << "T: " << text << std::endl;
+}
+
+DEFUN (__display_tokens__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __display_tokens__ ()\n\
+Query or set the internal variable that determines whether Octave's\n\
+lexer displays tokens as they are read.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (display_tokens);
+}
+
+DEFUN (__token_count__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __token_count__ ()\n\
+Number of language tokens processed since Octave startup.\n\
+ at end deftypefn")
+{
+  return octave_value (Vtoken_count);
+}
+
+DEFUN (__lexer_debug_flag__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{old_val} =} __lexer_debug_flag__ (@var{new_val}))\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  retval = set_internal_variable (lexer_debug_flag, args, nargout,
+           			  "__lexer_debug_flag__");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/load-path.cc b/src/load-path.cc
new file mode 100644
index 0000000..86b0738
--- /dev/null
+++ b/src/load-path.cc
@@ -0,0 +1,2122 @@
+/*
+
+Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+
+#include "dir-ops.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+#include "pathsearch.h"
+
+#include "defaults.h"
+#include "defun.h"
+#include "input.h"
+#include "load-path.h"
+#include "pager.h"
+#include "parse.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+
+load_path *load_path::instance = 0;
+load_path::hook_fcn_ptr load_path::add_hook = execute_pkg_add;
+load_path::hook_fcn_ptr load_path::remove_hook = execute_pkg_del;
+std::string load_path::command_line_path;
+std::string load_path::sys_path;
+load_path::abs_dir_cache_type load_path::abs_dir_cache;
+
+void
+load_path::dir_info::update (void)
+{
+  file_stat fs (dir_name);
+
+  if (fs)
+    {
+      if (is_relative)
+	{
+	  try
+	    {
+	      std::string abs_name
+		= octave_env::make_absolute (dir_name, octave_env::getcwd ());
+
+	      abs_dir_cache_iterator p = abs_dir_cache.find (abs_name);
+
+	      if (p != abs_dir_cache.end ())
+		{
+		  // The directory is in the cache of all directories
+		  // we have visited (indexed by its absolute name).
+		  // If it is out of date, initialize it.  Otherwise,
+		  // copy the info from the cache.  By doing that, we
+		  // avoid unnecessary calls to stat that can slow
+		  // things down tremendously for large directories.
+
+		  const dir_info& di = p->second;
+
+		  if (fs.mtime () != di.dir_mtime)
+		    initialize ();
+		  else
+		    *this = di;
+
+		  return;
+		}
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      // Skip updating if we don't know where we are, but
+	      // don't treat it as an error.
+
+	      error_state = 0;
+	    }
+	}
+
+      if (fs.mtime () != dir_mtime)
+	initialize ();
+    }
+  else
+    {
+      std::string msg = fs.error ();
+      warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ());
+    }
+}
+
+void
+load_path::dir_info::initialize (void)
+{
+  is_relative = ! octave_env::absolute_pathname (dir_name);
+
+  file_stat fs (dir_name);
+
+  if (fs)
+    {
+      dir_mtime = fs.mtime ();
+
+      get_file_list (dir_name);
+
+      try
+	{
+	  std::string abs_name
+	    = octave_env::make_absolute (dir_name, octave_env::getcwd ());
+
+	  // FIXME -- nothing is ever removed from this cache of
+	  // directory information, so there could be some resource
+	  // problems.  Perhaps it should be pruned from time to time.
+
+	  abs_dir_cache[abs_name] = *this;
+	}
+      catch (octave_execution_exception)
+	{
+	  // Skip updating if we don't know where we are.
+	}
+    }
+  else
+    {
+      std::string msg = fs.error ();
+      warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ());
+    }
+}
+
+void
+load_path::dir_info::get_file_list (const std::string& d)
+{
+  dir_entry dir (d);
+
+  if (dir)
+    {
+      string_vector flist = dir.read ();
+
+      octave_idx_type len = flist.length ();
+
+      all_files.resize (len);
+      fcn_files.resize (len);
+
+      octave_idx_type all_files_count = 0;
+      octave_idx_type fcn_files_count = 0;
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  std::string fname = flist[i];
+
+	  std::string full_name = file_ops::concat (d, fname);
+
+	  file_stat fs (full_name);
+
+	  if (fs)
+	    {
+	      if (fs.is_dir ())
+		{
+		  if (fname == "private")
+		    get_private_file_map (full_name);
+		  else if (fname[0] == '@')
+		    get_method_file_map (full_name, fname.substr (1));
+		}
+	      else
+		{
+		  all_files[all_files_count++] = fname;
+
+		  size_t pos = fname.rfind ('.');
+
+		  if (pos != std::string::npos)
+		    {
+		      std::string ext = fname.substr (pos);
+
+		      if (ext == ".m" || ext == ".oct" || ext == ".mex")
+			{
+			  std::string base = fname.substr (0, pos);
+
+			  if (valid_identifier (base))
+			    fcn_files[fcn_files_count++] = fname;
+			}
+		    }
+		}
+	    }
+	}
+
+      all_files.resize (all_files_count);
+      fcn_files.resize (fcn_files_count);
+    }
+  else
+    {
+      std::string msg = dir.error ();
+      warning ("load_path: %s: %s", d.c_str (), msg.c_str ());
+    }
+}
+
+load_path::dir_info::fcn_file_map_type
+get_fcn_files (const std::string& d)
+{
+  load_path::dir_info::fcn_file_map_type retval;
+
+  dir_entry dir (d);
+
+  if (dir)
+    {
+      string_vector flist = dir.read ();
+
+      octave_idx_type len = flist.length ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  std::string fname = flist[i];
+
+	  std::string ext;
+	  std::string base = fname;
+
+	  size_t pos = fname.rfind ('.');
+
+	  if (pos != std::string::npos)
+	    {
+	      base = fname.substr (0, pos);
+	      ext = fname.substr (pos);
+
+	      if (valid_identifier (base))
+		{
+		  int t = 0;
+
+		  if (ext == ".m")
+		    t = load_path::M_FILE;
+		  else if (ext == ".oct")
+		    t = load_path::OCT_FILE;
+		  else if (ext == ".mex")
+		    t = load_path::MEX_FILE;
+
+		  retval[base] |= t;
+		}
+	    }
+	}
+    }
+  else
+    {
+      std::string msg = dir.error ();
+      warning ("load_path: %s: %s", d.c_str (), msg.c_str ());
+    }
+
+  return retval;
+}
+
+void
+load_path::dir_info::get_private_file_map (const std::string& d)
+{
+  private_file_map = get_fcn_files (d);
+}
+
+void
+load_path::dir_info::get_method_file_map (const std::string& d,
+					  const std::string& class_name)
+{
+  method_file_map[class_name].method_file_map = get_fcn_files (d);
+
+  std::string pd = file_ops::concat (d, "private");
+
+  file_stat fs (pd);
+
+  if (fs && fs.is_dir ())
+    method_file_map[class_name].private_file_map = get_fcn_files (pd);
+}
+
+bool
+load_path::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new load_path ();
+
+  if (! instance)
+    {
+      ::error ("unable to create load path object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+// FIXME -- maybe we should also maintain a map to speed up this
+// method of access.
+
+load_path::const_dir_info_list_iterator
+load_path::find_dir_info (const std::string& dir_arg) const
+{
+  std::string dir = file_ops::tilde_expand (dir_arg);
+
+  const_dir_info_list_iterator retval = dir_info_list.begin ();
+
+  while (retval != dir_info_list.end ())
+    {
+      if (retval->dir_name == dir)
+	break;
+
+      retval++;
+    }
+
+  return retval;
+}
+
+load_path::dir_info_list_iterator
+load_path::find_dir_info (const std::string& dir_arg)
+{
+  std::string dir = file_ops::tilde_expand (dir_arg);
+
+  dir_info_list_iterator retval = dir_info_list.begin ();
+
+  while (retval != dir_info_list.end ())
+    {
+      if (retval->dir_name == dir)
+	break;
+
+      retval++;
+    }
+
+  return retval;
+}
+
+bool
+load_path::contains (const std::string& dir) const
+{
+  return find_dir_info (dir) != dir_info_list.end ();
+}
+
+void
+load_path::move_fcn_map (const std::string& dir_name,
+			 const string_vector& fcn_files, bool at_end)
+{
+  octave_idx_type len = fcn_files.length ();
+
+  for (octave_idx_type k = 0; k < len; k++)
+    {
+      std::string fname = fcn_files[k];
+
+      std::string ext;
+      std::string base = fname;
+
+      size_t pos = fname.rfind ('.');
+
+      if (pos != std::string::npos)
+	{
+	  base = fname.substr (0, pos);
+	  ext = fname.substr (pos);
+	}
+
+      file_info_list_type& file_info_list = fcn_map[base];
+
+      if (file_info_list.size () == 1)
+	continue;
+      else
+	{
+	  for (file_info_list_iterator p = file_info_list.begin ();
+	       p != file_info_list.end ();
+	       p++)
+	    {
+	      if (p->dir_name == dir_name)
+		{
+		  file_info fi = *p;
+
+		  file_info_list.erase (p);
+
+		  if (at_end)
+		    file_info_list.push_back (fi);
+		  else
+		    file_info_list.push_front (fi);
+
+		  break;
+		}
+	    }
+	}
+    }
+}
+
+void
+load_path::move_method_map (const std::string& dir_name, bool at_end)
+{
+  for (method_map_iterator i = method_map.begin ();
+       i != method_map.end ();
+       i++)
+    {
+      std::string class_name = i->first;
+
+      fcn_map_type& fm = i->second;
+
+      std::string full_dir_name
+	= file_ops::concat (dir_name, "@" + class_name);
+
+      for (fcn_map_iterator q = fm.begin (); q != fm.end (); q++)
+	{
+	  file_info_list_type& file_info_list = q->second;
+
+	  if (file_info_list.size () == 1)
+	    continue;
+	  else
+	    {
+	      for (file_info_list_iterator p = file_info_list.begin ();
+	       p != file_info_list.end ();
+	       p++)
+		{
+		  if (p->dir_name == full_dir_name)
+		    {
+		      file_info fi = *p;
+
+		      file_info_list.erase (p);
+
+		      if (at_end)
+			file_info_list.push_back (fi);
+		      else
+			file_info_list.push_front (fi);
+
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+}
+
+void
+load_path::move (dir_info_list_iterator i, bool at_end)
+{
+  if (dir_info_list.size () > 1)
+    {
+      dir_info di = *i;
+
+      dir_info_list.erase (i);
+
+      if (at_end)
+	dir_info_list.push_back (di);
+      else
+	dir_info_list.push_front (di);
+
+      std::string dir_name = di.dir_name;
+
+      move_fcn_map (dir_name, di.fcn_files, at_end);
+
+      // No need to move elements of private function map.
+
+      move_method_map (dir_name, at_end);
+    }
+}
+
+static void
+maybe_add_path_elts (std::string& path, const std::string& dir)
+{
+  std::string tpath = genpath (dir);
+
+  if (! tpath.empty ())
+    {
+      if (path.empty ())
+	path = tpath;
+      else
+	path += dir_path::path_sep_str () + tpath;
+    }
+}
+
+void
+load_path::do_initialize (bool set_initial_path)
+{
+  sys_path = "";
+
+  if (set_initial_path)
+    {
+      maybe_add_path_elts (sys_path, Vlocal_ver_oct_file_dir);
+      maybe_add_path_elts (sys_path, Vlocal_api_oct_file_dir);
+      maybe_add_path_elts (sys_path, Vlocal_oct_file_dir);
+      maybe_add_path_elts (sys_path, Vlocal_ver_fcn_file_dir);
+      maybe_add_path_elts (sys_path, Vlocal_api_fcn_file_dir);
+      maybe_add_path_elts (sys_path, Vlocal_fcn_file_dir);
+      maybe_add_path_elts (sys_path, Voct_file_dir);
+      maybe_add_path_elts (sys_path, Vfcn_file_dir);
+    }
+
+  std::string tpath = load_path::command_line_path;
+
+  if (tpath.empty ())
+    tpath = octave_env::getenv ("OCTAVE_PATH");
+
+  std::string xpath = ".";
+
+  if (! tpath.empty ())
+    xpath += dir_path::path_sep_str () + tpath;
+
+  if (! sys_path.empty ())
+    xpath += dir_path::path_sep_str () + sys_path;
+
+  do_set (xpath, false);
+}
+
+void
+load_path::do_clear (void)
+{
+  dir_info_list.clear ();
+  fcn_map.clear ();
+  private_fcn_map.clear ();
+  method_map.clear ();
+  parent_map.clear ();
+
+  do_append (".", false);
+}
+
+static std::list<std::string>
+split_path (const std::string& p)
+{
+  std::list<std::string> retval;
+
+  size_t beg = 0;
+  size_t end = p.find (dir_path::path_sep_char ());
+
+  size_t len = p.length ();
+
+  while (end != std::string::npos)
+    {
+      std::string elt = p.substr (beg, end-beg);
+
+      if (! elt.empty ())
+	retval.push_back (elt);
+
+      beg = end + 1;
+
+      if (beg == len)
+	break;
+
+      end = p.find (dir_path::path_sep_char (), beg);
+    }
+
+  std::string elt = p.substr (beg);
+
+  if (! elt.empty ())
+    retval.push_back (elt);
+
+  return retval;
+}
+
+void
+load_path::do_set (const std::string& p, bool warn)
+{
+  std::list<std::string> elts = split_path (p);
+
+  // Temporarily disable add hook.
+
+  unwind_protect_fptr (add_hook);
+
+  add_hook = 0;
+
+  do_clear ();
+
+  for (std::list<std::string>::const_iterator i = elts.begin ();
+       i != elts.end ();
+       i++)
+    do_append (*i, warn);
+
+  // Restore add hook and execute for all newly added directories.
+
+  unwind_protect::run ();
+
+  for (dir_info_list_iterator i = dir_info_list.begin ();
+       i != dir_info_list.end ();
+       i++)
+    {
+      if (add_hook)
+	add_hook (i->dir_name);
+    }
+}
+
+void
+load_path::do_append (const std::string& dir, bool warn)
+{
+  if (! dir.empty ())
+    do_add (dir, true, warn);
+}
+
+void
+load_path::do_prepend (const std::string& dir, bool warn)
+{
+  if (! dir.empty ())
+    do_add (dir, false, warn);
+}
+
+void
+load_path::do_add (const std::string& dir_arg, bool at_end, bool warn)
+{
+  size_t len = dir_arg.length ();
+
+  if (len > 1 && dir_arg.substr (len-2) == "//")
+    warning_with_id ("Octave:recursive-path-search",
+		     "trailing `//' is no longer special in search path elements");
+
+  std::string dir = file_ops::tilde_expand (dir_arg);
+
+  dir_info_list_iterator i = find_dir_info (dir);
+
+  if (i != dir_info_list.end ())
+    move (i, at_end);
+  else
+    {
+      file_stat fs (dir);
+
+      if (fs)
+	{
+	  if (fs.is_dir ())
+	    {
+	      dir_info di (dir);
+
+	      if (! error_state)
+		{
+		  if (at_end)
+		    dir_info_list.push_back (di);
+		  else
+		    dir_info_list.push_front (di);
+
+		  add_to_fcn_map (di, true);
+
+		  add_to_private_fcn_map (di);
+
+		  add_to_method_map (di, true);
+
+		  if (add_hook)
+		    add_hook (dir);
+		}
+	    }
+	  else if (warn)
+	    warning ("addpath: %s: not a directory", dir_arg.c_str ());
+	}
+      else if (warn)
+	{
+	  std::string msg = fs.error ();
+	  warning ("addpath: %s: %s", dir_arg.c_str (), msg.c_str ());
+	}
+    }
+
+  // FIXME -- is there a better way to do this?
+
+  i = find_dir_info (".");
+
+  if (i != dir_info_list.end ())
+    move (i, false);
+  else
+    panic_impossible ();
+}
+
+void
+load_path::remove_fcn_map (const std::string& dir,
+			   const string_vector& fcn_files)
+{
+  octave_idx_type len = fcn_files.length ();
+
+  for (octave_idx_type k = 0; k < len; k++)
+    {
+      std::string fname = fcn_files[k];
+
+      std::string ext;
+      std::string base = fname;
+
+      size_t pos = fname.rfind ('.');
+
+      if (pos != std::string::npos)
+	{
+	  base = fname.substr (0, pos);
+	  ext = fname.substr (pos);
+	}
+
+      file_info_list_type& file_info_list = fcn_map[base];
+
+      for (file_info_list_iterator p = file_info_list.begin ();
+	   p != file_info_list.end ();
+	   p++)
+	{
+	  if (p->dir_name == dir)
+	    {
+	      file_info_list.erase (p);
+
+	      if (file_info_list.empty ())
+		fcn_map.erase (fname);
+
+	      break;
+	    }
+	}
+    }
+}
+
+void
+load_path::remove_private_fcn_map (const std::string& dir)
+{
+  private_fcn_map_iterator p = private_fcn_map.find (dir);
+
+  if (p != private_fcn_map.end ())
+    private_fcn_map.erase (p);
+}
+
+void
+load_path::remove_method_map (const std::string& dir)
+{
+  for (method_map_iterator i = method_map.begin ();
+       i != method_map.end ();
+       i++)
+    {
+      std::string class_name = i->first;
+
+      fcn_map_type& fm = i->second;
+
+      std::string full_dir_name = file_ops::concat (dir, "@" + class_name);
+
+      for (fcn_map_iterator q = fm.begin (); q != fm.end (); q++)
+	{
+	  file_info_list_type& file_info_list = q->second;
+
+	  if (file_info_list.size () == 1)
+	    continue;
+	  else
+	    {
+	      for (file_info_list_iterator p = file_info_list.begin ();
+	       p != file_info_list.end ();
+	       p++)
+		{
+		  if (p->dir_name == full_dir_name)
+		    {
+		      file_info_list.erase (p);
+
+		      // FIXME -- if there are no other elements, we
+		      // should remove this element of fm but calling
+		      // erase here would invalidate the iterator q.
+
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+}
+
+bool
+load_path::do_remove (const std::string& dir_arg)
+{
+  bool retval = false;
+
+  if (! dir_arg.empty ())
+    {
+      if (dir_arg == ".")
+	{
+	  warning ("rmpath: can't remove \".\" from path");
+
+	  // Avoid additional warnings.
+	  retval = true;
+	}
+      else
+	{
+	  std::string dir = file_ops::tilde_expand (dir_arg);
+
+	  dir_info_list_iterator i = find_dir_info (dir);
+
+	  if (i != dir_info_list.end ())
+	    {
+	      retval = true;
+
+	      if (remove_hook)
+		remove_hook (dir);
+
+	      string_vector fcn_files = i->fcn_files;
+
+	      dir_info_list.erase (i);
+
+	      remove_fcn_map (dir, fcn_files);
+
+	      remove_private_fcn_map (dir);
+
+	      remove_method_map (dir);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+void
+load_path::do_update (void) const
+{
+  // I don't see a better way to do this because we need to
+  // preserve the correct directory ordering for new files that
+  // have appeared.
+
+  fcn_map.clear ();
+
+  private_fcn_map.clear ();
+
+  method_map.clear ();
+
+  for (dir_info_list_iterator p = dir_info_list.begin ();
+       p != dir_info_list.end ();
+       p++)
+    {
+      dir_info& di = *p;
+
+      di.update ();
+
+      add_to_fcn_map (di, true);
+
+      add_to_private_fcn_map (di);
+
+      add_to_method_map (di, true);
+    }
+}
+
+bool
+load_path::check_file_type (std::string& fname, int type, int possible_types,
+			    const std::string& fcn, const char *who)
+{
+  bool retval = false;
+
+  if (type == load_path::OCT_FILE)
+    {
+      if ((type & possible_types) == load_path::OCT_FILE)
+	{
+	  fname += ".oct";
+	  retval = true;
+	}
+    }
+  else if (type == load_path::M_FILE)
+    {
+      if ((type & possible_types) == load_path::M_FILE)
+	{
+	  fname += ".m";
+	  retval = true;
+	}
+    }
+  else if (type == load_path::MEX_FILE)
+    {
+      if ((type & possible_types) == load_path::MEX_FILE)
+	{
+	  fname += ".mex";
+	  retval = true;
+	}
+    }
+  else if (type == (load_path::M_FILE | load_path::OCT_FILE))
+    {
+      if (possible_types & load_path::OCT_FILE)
+	{
+	  fname += ".oct";
+	  retval = true;
+	}
+      else if (possible_types & load_path::M_FILE)
+	{
+	  fname += ".m";
+	  retval = true;
+	}
+    }
+  else if (type == (load_path::M_FILE | load_path::MEX_FILE))
+    {
+      if (possible_types & load_path::MEX_FILE)
+	{
+	  fname += ".mex";
+	  retval = true;
+	}
+      else if (possible_types & load_path::M_FILE)
+	{
+	  fname += ".m";
+	  retval = true;
+	}
+    }
+  else if (type == (load_path::OCT_FILE | load_path::MEX_FILE))
+    {
+      if (possible_types & load_path::OCT_FILE)
+	{
+	  fname += ".oct";
+	  retval = true;
+	}
+      else if (possible_types & load_path::MEX_FILE)
+	{
+	  fname += ".mex";
+	  retval = true;
+	}
+    }
+  else if (type == (load_path::M_FILE | load_path::OCT_FILE
+		    | load_path::MEX_FILE))
+    {
+      if (possible_types & load_path::OCT_FILE)
+	{
+	  fname += ".oct";
+	  retval = true;
+	}
+      else if (possible_types & load_path::MEX_FILE)
+	{
+	  fname += ".mex";
+	  retval = true;
+	}
+      else if (possible_types & load_path::M_FILE)
+	{
+	  fname += ".m";
+	  retval = true;
+	}
+    }
+  else
+    error ("%s: %s: invalid type code = %d", who, fcn.c_str (), type);
+
+  return retval;
+} 
+
+std::string
+load_path::do_find_fcn (const std::string& fcn, std::string& dir_name,
+			int type) const
+{
+  std::string retval;
+  
+  //  update ();
+
+  if (fcn.length () > 0 && fcn[0] == '@')
+    {
+      size_t pos = fcn.find ('/');
+
+      if (pos != std::string::npos)
+	{
+	  std::string class_name = fcn.substr (1, pos-1);
+	  std::string meth = fcn.substr (pos+1);
+
+	  retval = do_find_method (class_name, meth, dir_name);
+	}
+      else
+	retval = std::string ();
+    }
+  else
+    {
+      dir_name = std::string ();
+
+      const_fcn_map_iterator p = fcn_map.find (fcn);
+
+      if (p != fcn_map.end ())
+	{
+	  const file_info_list_type& file_info_list = p->second;
+
+	  for (const_file_info_list_iterator i = file_info_list.begin ();
+	       i != file_info_list.end ();
+	       i++)
+	    {
+	      const file_info& fi = *i;
+
+	      retval = file_ops::concat (fi.dir_name, fcn);
+
+	      if (check_file_type (retval, type, fi.types,
+				   fcn, "load_path::do_find_fcn"))
+		{
+		  dir_name = fi.dir_name;
+		  break;
+		}
+	      else
+		retval = std::string ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+std::string
+load_path::do_find_private_fcn (const std::string& dir,
+				const std::string& fcn, int type) const
+{
+  std::string retval;
+
+  //  update ();
+
+  const_private_fcn_map_iterator q = private_fcn_map.find (dir);
+
+  if (q != private_fcn_map.end ())
+    {
+      const dir_info::fcn_file_map_type& m = q->second;
+
+      dir_info::const_fcn_file_map_iterator p = m.find (fcn);
+
+      if (p != m.end ())
+	{
+	  std::string fname
+	    = file_ops::concat (file_ops::concat (dir, "private"), fcn);
+
+	  if (check_file_type (fname, type, p->second, fcn,
+			       "load_path::find_private_fcn"))
+	    retval = fname;
+	}
+    }
+
+  return retval;
+}
+
+std::string
+load_path::do_find_method (const std::string& class_name,
+			   const std::string& meth,
+			   std::string& dir_name, int type) const
+{
+  std::string retval;
+
+  //  update ();
+
+  dir_name = std::string ();
+
+  const_method_map_iterator q = method_map.find (class_name);
+
+  if (q != method_map.end ())
+    {
+      const fcn_map_type& m = q->second;
+
+      const_fcn_map_iterator p = m.find (meth);
+
+      if (p == m.end ())
+	{
+	  // Look in parent classes.
+
+	  const_parent_map_iterator r = parent_map.find (class_name);
+
+	  if (r != parent_map.end ())
+	    {
+	      const std::list<std::string>& plist = r->second;
+	      std::list<std::string>::const_iterator it = plist.begin ();
+
+	      while (it != plist.end ())
+		{
+		  retval = do_find_method (*it, meth, dir_name, type);
+
+		  if (retval != "")
+		    break;
+
+		  it++;
+		}
+	    }
+	}
+      else
+	{
+	  const file_info_list_type& file_info_list = p->second;
+
+	  for (const_file_info_list_iterator i = file_info_list.begin ();
+	       i != file_info_list.end ();
+	       i++)
+	    {
+	      const file_info& fi = *i;
+
+	      retval = file_ops::concat (fi.dir_name, meth);
+
+	      bool found = check_file_type (retval, type, fi.types,
+					    meth, "load_path::do_find_method");
+
+	      if (found)
+		{
+		  dir_name = fi.dir_name;
+		  break;
+		}
+	      else
+		retval = std::string ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+std::list<std::string>
+load_path::do_methods (const std::string& class_name) const
+{
+  std::list<std::string> retval;
+
+  //  update ();
+
+  const_method_map_iterator q = method_map.find (class_name);
+
+  if (q != method_map.end ())
+    {
+      const fcn_map_type& m = q->second;
+
+      for (const_fcn_map_iterator p = m.begin (); p != m.end (); p++)
+	retval.push_back (p->first);
+    }
+
+  if (! retval.empty ())
+    retval.sort ();
+
+  return retval;
+}
+
+std::string
+load_path::do_find_file (const std::string& file) const
+{
+  std::string retval;
+
+  if (file.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos)
+    {
+      if (octave_env::absolute_pathname (file)
+	  || octave_env::rooted_relative_pathname (file))
+	{
+	  file_stat fs (file);
+
+	  if (fs.exists ())
+	    return file;
+	}
+      else
+	{
+	  for (const_dir_info_list_iterator p = dir_info_list.begin ();
+	       p != dir_info_list.end ();
+	       p++)
+	    {
+	      std::string tfile = file_ops::concat (p->dir_name, file);
+
+	      file_stat fs (tfile);
+
+	      if (fs.exists ())
+		return tfile;
+	    }
+	}
+    }
+  else
+    {
+      for (const_dir_info_list_iterator p = dir_info_list.begin ();
+	   p != dir_info_list.end ();
+	   p++)
+	{
+	  string_vector all_files = p->all_files;
+
+	  octave_idx_type len = all_files.length ();
+
+	  for (octave_idx_type i = 0; i < len; i++)
+	    {
+	      if (all_files[i] == file)
+		return file_ops::concat (p->dir_name, file);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+std::string
+load_path::do_find_dir (const std::string& dir) const
+{
+  std::string retval;
+
+  if (dir.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos
+      && (octave_env::absolute_pathname (dir)
+	  || octave_env::rooted_relative_pathname (dir)))
+    {
+      file_stat fs (dir);
+
+      if (fs.exists () && fs.is_dir ())
+	return dir;
+    }
+  else
+    {
+      for (const_dir_info_list_iterator p = dir_info_list.begin ();
+	   p != dir_info_list.end ();
+	   p++)
+	{
+	  std::string dname = p->dir_name;
+
+	  size_t dname_len = dname.length ();
+
+	  if (dname.substr (dname_len - 1) == file_ops::dir_sep_str ())
+	    dname = dname.substr (0, dname_len - 1);
+
+	  size_t dir_len = dir.length ();
+
+	  if (dname_len >= dir_len
+	      && file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
+	      && dir.compare (dname.substr (dname_len - dir_len)) == 0)
+	    {
+	      file_stat fs (p->dir_name);
+
+	      if (fs.exists () && fs.is_dir ())
+		return p->dir_name;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+std::string
+load_path::do_find_first_of (const string_vector& flist) const
+{
+  std::string retval;
+
+  std::string dir_name;
+  std::string file_name;
+
+  octave_idx_type flen = flist.length ();
+  octave_idx_type rel_flen = 0;
+
+  string_vector rel_flist (flen);
+
+  for (octave_idx_type i = 0; i < flen; i++)
+    {
+      if (octave_env::absolute_pathname (flist[i]))
+	{
+	  file_stat fs (flist[i]);
+
+	  if (fs.exists ())
+	    return flist[i];
+	}
+      else
+	rel_flist[rel_flen++] = flist[i];
+    }
+
+  rel_flist.resize (rel_flen);
+
+  for (const_dir_info_list_iterator p = dir_info_list.begin ();
+       p != dir_info_list.end ();
+       p++)
+    {
+      string_vector all_files = p->all_files;
+
+      octave_idx_type len = all_files.length ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  for (octave_idx_type j = 0; j < rel_flen; j++)
+	    {
+	      if (all_files[i] == rel_flist[j])
+		{
+		  dir_name = p->dir_name;
+		  file_name = rel_flist[j];
+
+		  goto done;
+		}
+	    }
+	}
+    }
+
+ done:
+
+  if (! dir_name.empty ())
+    retval = file_ops::concat (dir_name, file_name);
+
+  return retval;
+}
+
+string_vector
+load_path::do_find_all_first_of (const string_vector& flist) const
+{
+  std::list<std::string> retlist;
+
+  std::string dir_name;
+  std::string file_name;
+
+  octave_idx_type flen = flist.length ();
+  octave_idx_type rel_flen = 0;
+
+  string_vector rel_flist (flen);
+
+  for (octave_idx_type i = 0; i < flen; i++)
+    {
+      if (octave_env::absolute_pathname (flist[i]))
+	{
+	  file_stat fs (flist[i]);
+
+	  if (fs.exists ())
+	    retlist.push_back (flist[i]);
+	}
+      else
+	rel_flist[rel_flen++] = flist[i];
+    }
+
+  rel_flist.resize (rel_flen);
+
+  for (const_dir_info_list_iterator p = dir_info_list.begin ();
+       p != dir_info_list.end ();
+       p++)
+    {
+      string_vector all_files = p->all_files;
+
+      octave_idx_type len = all_files.length ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  for (octave_idx_type j = 0; j < rel_flen; j++)
+	    {
+	      if (all_files[i] == rel_flist[j])
+		retlist.push_back
+		  (file_ops::concat (p->dir_name, rel_flist[j]));
+	    }
+	}
+    }
+
+  size_t retsize = retlist.size ();
+
+  string_vector retval (retsize);
+
+  for (size_t i = 0; i < retsize; i++)
+    {
+      retval[i] = retlist.front ();
+
+      retlist.pop_front ();
+    }
+
+  return retval;
+}
+
+string_vector
+load_path::do_dirs (void) const
+{
+  size_t len = dir_info_list.size ();
+
+  string_vector retval (len);
+
+  octave_idx_type k = 0;
+
+  for (const_dir_info_list_iterator i = dir_info_list.begin ();
+       i != dir_info_list.end ();
+       i++)
+    retval[k++] = i->dir_name;
+
+  return retval;
+}
+
+std::list<std::string>
+load_path::do_dir_list (void) const
+{
+  std::list<std::string> retval;
+
+  for (const_dir_info_list_iterator i = dir_info_list.begin ();
+       i != dir_info_list.end ();
+       i++)
+    retval.push_back (i->dir_name);
+
+  return retval;
+}
+
+string_vector
+load_path::do_files (const std::string& dir, bool omit_exts) const
+{
+  string_vector retval;
+
+  const_dir_info_list_iterator p = find_dir_info (dir);
+
+  if (p != dir_info_list.end ())
+    retval = p->fcn_files;
+
+  if (omit_exts)
+    {
+      octave_idx_type len = retval.length ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  std::string fname = retval[i];
+
+	  size_t pos = fname.rfind ('.');
+
+	  if (pos != std::string::npos)
+	    retval[i] = fname.substr (0, pos);
+	}
+    }
+
+  return retval;
+}
+
+string_vector
+load_path::do_fcn_names (void) const
+{
+  size_t len = fcn_map.size ();
+
+  string_vector retval (len);
+
+  octave_idx_type count = 0;
+
+  for (const_fcn_map_iterator p = fcn_map.begin ();
+       p != fcn_map.end ();
+       p++)
+    retval[count++] = p->first;
+
+  return retval;
+}
+
+std::string
+load_path::do_path (void) const
+{
+  std::string xpath;
+
+  string_vector xdirs = load_path::dirs ();
+
+  octave_idx_type len = xdirs.length ();
+
+  if (len > 0)
+    xpath = xdirs[0];
+
+  for (octave_idx_type i = 1; i < len; i++)
+    xpath += dir_path::path_sep_str () + xdirs[i];
+
+  return xpath;
+}
+
+void
+print_types (std::ostream& os, int types)
+{
+  bool printed_type = false;
+
+  if (types & load_path::OCT_FILE)
+    {
+      os << "oct";
+      printed_type = true;
+    }
+
+  if (types & load_path::MEX_FILE)
+    {
+      if (printed_type)
+	os << "|";
+      os << "mex";
+      printed_type = true;
+    }
+
+  if (types & load_path::M_FILE)
+    {
+      if (printed_type)
+	os << "|";
+      os << "m";
+      printed_type = true;
+    }
+}
+
+void
+print_fcn_list (std::ostream& os,
+		const load_path::dir_info::fcn_file_map_type& lst)
+{
+  for (load_path::dir_info::const_fcn_file_map_iterator p = lst.begin ();
+       p != lst.end ();
+       p++)
+    {
+      os << "  " << p->first << " (";
+
+      print_types (os, p->second);
+
+      os << ")\n";
+    }
+}
+
+string_vector
+get_file_list (const load_path::dir_info::fcn_file_map_type& lst)
+{
+  octave_idx_type n = lst.size ();
+
+  string_vector retval (n);
+
+  octave_idx_type count = 0;
+
+  for (load_path::dir_info::const_fcn_file_map_iterator p = lst.begin ();
+       p != lst.end ();
+       p++)
+    {
+      std::string nm = p->first;
+
+      int types = p->second;
+
+      if (types & load_path::OCT_FILE)
+	nm += ".oct";
+      else if (types & load_path::MEX_FILE)
+	nm += ".mex";
+      else
+	nm += ".m";
+
+      retval[count++] = nm;
+    }
+
+  return retval;
+}
+
+void
+load_path::do_display (std::ostream& os) const
+{
+  for (const_dir_info_list_iterator i = dir_info_list.begin ();
+       i != dir_info_list.end ();
+       i++)
+    {
+      string_vector fcn_files = i->fcn_files;
+
+      if (! fcn_files.empty ())
+	{
+	  os << "\n*** function files in " << i->dir_name << ":\n\n";
+
+	  fcn_files.list_in_columns (os);
+	}
+
+      const dir_info::method_file_map_type& method_file_map
+	= i->method_file_map;
+
+      if (! method_file_map.empty ())
+	{
+	  for (dir_info::const_method_file_map_iterator p = method_file_map.begin ();
+	       p != method_file_map.end ();
+	       p++)
+	    {
+	      os << "\n*** methods in " << i->dir_name
+		 << "/@" << p->first << ":\n\n";
+
+	      const dir_info::class_info& ci = p->second;
+
+	      string_vector method_files = get_file_list (ci.method_file_map);
+
+	      method_files.list_in_columns (os);
+	    }
+	}
+    }
+
+  for (const_private_fcn_map_iterator i = private_fcn_map.begin ();
+       i != private_fcn_map.end (); i++)
+    {
+      os << "\n*** private functions in "
+	 << file_ops::concat (i->first, "private") << ":\n\n";
+
+      print_fcn_list (os, i->second);
+    }
+
+#if defined (DEBUG_LOAD_PATH)
+
+  for (const_fcn_map_iterator i = fcn_map.begin ();
+       i != fcn_map.end ();
+       i++)
+    {
+      os << i->first << ":\n";
+
+      const file_info_list_type& file_info_list = i->second;
+
+      for (const_file_info_list_iterator p = file_info_list.begin ();
+	   p != file_info_list.end ();
+	   p++)
+	{
+	  os << "  " << p->dir_name << " (";
+
+	  print_types (os, p->types);
+
+	  os << ")\n";
+	}
+    }
+
+  for (const_method_map_iterator i = method_map.begin ();
+       i != method_map.end ();
+       i++)
+    {
+      os << "CLASS " << i->first << ":\n";
+
+      const fcn_map_type& fm = i->second;
+
+      for (const_fcn_map_iterator q = fm.begin ();
+	   q != fm.end ();
+	   q++)
+	{
+	  os << "  " << q->first << ":\n";
+
+	  const file_info_list_type& file_info_list = q->second;
+
+	  for (const_file_info_list_iterator p = file_info_list.begin ();
+	       p != file_info_list.end ();
+	       p++)
+	    {
+	      os << "  " << p->dir_name << " (";
+
+	      print_types (os, p->types);
+
+	      os << ")\n";
+	    }
+	}
+    }
+
+  os << "\n";
+
+#endif
+}
+
+void
+load_path::do_add_to_parent_map (const std::string& classname,
+				 const std::list<std::string>& parent_list) const
+{
+  parent_map[classname] = parent_list;
+}
+
+void
+load_path::add_to_fcn_map (const dir_info& di, bool at_end) const
+{
+  std::string dir_name = di.dir_name;
+
+  string_vector fcn_files = di.fcn_files;
+
+  octave_idx_type len = fcn_files.length ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      std::string fname = fcn_files[i];
+
+      std::string ext;
+      std::string base = fname;
+
+      size_t pos = fname.rfind ('.');
+
+      if (pos != std::string::npos)
+	{
+	  base = fname.substr (0, pos);
+	  ext = fname.substr (pos);
+	}
+
+      file_info_list_type& file_info_list = fcn_map[base];
+
+      file_info_list_iterator p = file_info_list.begin ();
+
+      while (p != file_info_list.end ())
+	{
+	  if (p->dir_name == dir_name)
+	    break;
+
+	  p++;
+	}
+
+      int t = 0;
+      if (ext == ".m")
+	t = load_path::M_FILE;
+      else if (ext == ".oct")
+	t = load_path::OCT_FILE;
+      else if (ext == ".mex")
+	t = load_path::MEX_FILE;
+
+      if (p == file_info_list.end ())
+	{
+	  file_info fi (dir_name, t);
+
+	  if (at_end)
+	    file_info_list.push_back (fi);
+	  else
+	    file_info_list.push_front (fi);
+	}
+      else
+	{
+	  file_info& fi = *p;
+
+	  fi.types |= t;
+	}
+    }
+}
+
+void
+load_path::add_to_private_fcn_map (const dir_info& di) const
+{
+  dir_info::fcn_file_map_type private_file_map = di.private_file_map;
+
+  if (! private_file_map.empty ())
+    private_fcn_map[di.dir_name] = private_file_map;
+}
+
+void
+load_path::add_to_method_map (const dir_info& di, bool at_end) const
+{
+  std::string dir_name = di.dir_name;
+
+  // <CLASS_NAME, CLASS_INFO>
+  dir_info::method_file_map_type method_file_map = di.method_file_map;
+
+  for (dir_info::const_method_file_map_iterator q = method_file_map.begin ();
+       q != method_file_map.end ();
+       q++)
+    {
+      std::string class_name = q->first;
+
+      fcn_map_type& fm = method_map[class_name];
+
+      std::string full_dir_name
+	= file_ops::concat (dir_name, "@" + class_name);
+
+      const dir_info::class_info& ci = q->second;
+
+      // <FCN_NAME, TYPES>
+      const dir_info::fcn_file_map_type& m = ci.method_file_map;
+
+      for (dir_info::const_fcn_file_map_iterator p = m.begin ();
+	   p != m.end ();
+	   p++)
+	{
+	  std::string base = p->first;
+
+	  int types = p->second;
+
+	  file_info_list_type& file_info_list = fm[base];
+
+	  file_info_list_iterator p2 = file_info_list.begin ();
+
+	  while (p2 != file_info_list.end ())
+	    {
+	      if (p2->dir_name == full_dir_name)
+		break;
+
+	      p2++;
+	    }
+
+	  if (p2 == file_info_list.end ())
+	    {
+	      file_info fi (full_dir_name, types);
+
+	      if (at_end)
+		file_info_list.push_back (fi);
+	      else
+		file_info_list.push_front (fi);
+	    }
+	  else
+	    {
+	      // FIXME -- is this possible?
+
+	      file_info& fi = *p2;
+
+	      fi.types = types;
+	    }
+	}
+
+      // <FCN_NAME, TYPES>
+      dir_info::fcn_file_map_type private_file_map = ci.private_file_map;
+
+      if (! private_file_map.empty ())
+	private_fcn_map[full_dir_name] = private_file_map;
+    }
+}
+
+std::string
+genpath (const std::string& dirname, const string_vector& skip)
+{
+  std::string retval;
+
+  dir_entry dir (dirname);
+
+  if (dir)
+    {
+      retval = dirname;
+
+      string_vector dirlist = dir.read ();
+      
+      octave_idx_type len = dirlist.length ();
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  std::string elt = dirlist[i];
+
+	  // FIXME -- the caller should be able to specify the list of
+	  // directories to skip in addition to ".", "..", and
+	  // directories beginning with "@".
+
+	  bool skip_p = (elt == "." || elt == ".." || elt[0] == '@');
+
+	  if (! skip_p)
+	    {
+	      for (octave_idx_type j = 0; j < skip.length (); j++)
+		{
+		  skip_p = (elt == skip[j]);
+		  if (skip_p)
+		    break;
+		}
+
+	      if (! skip_p)
+		{
+		  std::string nm = file_ops::concat (dirname, elt);
+
+		  file_stat fs (nm);
+
+		  if (fs && fs.is_dir ())
+		    retval += dir_path::path_sep_str () + genpath (nm);
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static void
+execute_pkg_add_or_del (const std::string& dir,
+			const std::string& script_file)
+{
+  if (! octave_interpreter_ready)
+    return;
+
+  unwind_protect::begin_frame ("execute_pkg_add_or_del");
+
+  unwind_protect_bool (input_from_startup_file);
+
+  input_from_startup_file = true;
+
+  std::string file = file_ops::concat (dir, script_file);
+
+  file_stat fs (file);
+
+  if (fs.exists ())
+    source_file (file, "base");
+
+  unwind_protect::run_frame ("execute_pkg_add_or_del");
+}
+
+void
+execute_pkg_add (const std::string& dir)
+{
+  execute_pkg_add_or_del (dir, "PKG_ADD");
+}
+
+void
+execute_pkg_del (const std::string& dir)
+{
+  execute_pkg_add_or_del (dir, "PKG_DEL");
+}
+
+DEFUN (genpath, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} genpath (@var{dir})\n\
+Return a path constructed from @var{dir} and all its subdirectories.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      std::string dirname = args(0).string_value ();
+
+      if (! error_state)
+	retval = genpath (dirname);
+      else
+	error ("genpath: expecting argument to be a character string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static void
+rehash_internal (void)
+{
+  load_path::update ();
+
+  // FIXME -- maybe we should rename this variable since it is being
+  // used for more than keeping track of the prompt time.
+
+  // This will force updated functions to be found.
+  Vlast_prompt_time.stamp ();
+}
+
+DEFUN (rehash, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rehash ()\n\
+Reinitialize Octave's load path directory cache.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  rehash_internal ();
+
+  return retval;
+}
+
+DEFUN (command_line_path, , ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} command_line_path (@dots{})\n\
+Return the command line path variable.\n\
+\n\
+ at seealso{path, addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\
+ at end deftypefn")
+{
+  return octave_value (load_path::get_command_line_path ());
+}
+
+DEFUN (restoredefaultpath, , ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} restoredefaultpath (@dots{})\n\
+Restore Octave's path to it's initial state at startup.\n\
+\n\
+ at seealso{path, addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\
+ at end deftypefn")
+{
+  load_path::initialize (true);
+
+  return octave_value (load_path::system_path ());
+}
+
+// Return Octave's original default list of directories in which to
+// search for function files.  This corresponds to the path that
+// exists prior to running the system's octaverc file or the user's
+// ~/.octaverc file
+
+DEFUN (__pathorig__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} __pathorig__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  return octave_value (load_path::system_path ());
+}
+
+DEFUN (path, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} path (@dots{})\n\
+Modify or display Octave's load path.\n\
+\n\
+If @var{nargin} and @var{nargout} are zero, display the elements of\n\
+Octave's load path in an easy to read format.\n\
+\n\
+If @var{nargin} is zero and nargout is greater than zero, return the\n\
+current load path.\n\
+\n\
+If @var{nargin} is greater than zero, concatenate the arguments,\n\
+separating them with @code{pathsep()}.  Set the internal search path\n\
+to the result and return it.\n\
+\n\
+No checks are made for duplicate elements.\n\
+ at seealso{addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("path");
+
+  if (! error_state)
+    {
+      if (argc > 1)
+	{
+	  std::string path = argv[1];
+
+	  for (int i = 2; i < argc; i++)
+	    path += dir_path::path_sep_str () + argv[i];
+
+	  load_path::set (path, true);
+
+	  rehash_internal ();
+	}
+
+      if (nargout > 0)
+	retval = load_path::path ();
+      else if (argc == 1 && nargout == 0)
+	{
+	  octave_stdout << "\nOctave's search path contains the following directories:\n\n";
+
+	  string_vector dirs = load_path::dirs ();
+
+	  dirs.list_in_columns (octave_stdout);
+
+	  octave_stdout << "\n";
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (addpath, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})\n\
+Add @var{dir1}, @dots{} to the current function search path.  If\n\
+ at var{option} is @samp{\"-begin\"} or 0 (the default), prepend the\n\
+directory name to the current path.  If @var{option} is @samp{\"-end\"}\n\
+or 1, append the directory name to the current path.\n\
+Directories added to the path must exist.\n\
+ at seealso{path, rmpath, genpath, pathdef, savepath, pathsep}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  // Originally written by Bill Denney and Etienne Grossman.  Heavily
+  // modified and translated to C++ by jwe.
+
+  if (nargout > 0)
+    retval = load_path::path ();
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      bool append = false;
+
+      octave_value option_arg = args(nargin-1);
+
+      if (option_arg.is_string ())
+	{
+	  std::string option = option_arg.string_value ();
+
+	  if (option == "-end")
+	    {
+	      append = true;
+	      nargin--;
+	    }
+	  else if (option == "-begin")
+	    nargin--;
+	}
+      else if (option_arg.is_numeric_type ())
+	{
+	  int val = option_arg.int_value ();
+
+	  if (! error_state)
+	    {
+	      if (val == 0)
+		append = false;
+	      else if (val == 1)
+		append = true;
+	      else
+		{
+		  error ("addpath: expecting final argument to be 1 or 0");
+		  return retval;
+		}
+	    }
+	  else
+	    {
+	      error ("addpath: expecting final argument to be 1 or 0");
+	      return retval;
+	    }
+	}
+
+      bool need_to_update = false;
+
+      for (int i = 0; i < nargin; i++)
+	{
+	  std::string arg = args(i).string_value ();
+
+	  if (! error_state)
+	    {
+	      std::list<std::string> dir_elts = split_path (arg);
+
+	      if (! append)
+		std::reverse (dir_elts.begin (), dir_elts.end ());
+
+	      for (std::list<std::string>::const_iterator p = dir_elts.begin ();
+		   p != dir_elts.end ();
+		   p++)
+		{
+		  std::string dir = *p;
+
+		  //dir = regexprep (dir_elts{j}, "//+", "/");
+		  //dir = regexprep (dir, "/$", "");
+
+		  if (append)
+		    load_path::append (dir, true);
+		  else
+		    load_path::prepend (dir, true);
+
+		  need_to_update = true;
+		}
+	    }
+	  else
+	    error ("addpath: expecting all args to be character strings");
+	}
+
+      if (need_to_update)
+	rehash_internal ();
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (rmpath, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rmpath (@var{dir1}, @dots{})\n\
+Remove @var{dir1}, @dots{} from the current function search path.\n\
+\n\
+ at seealso{path, addpath, genpath, pathdef, savepath, pathsep}\n\
+ at end deftypefn")
+{
+  // Originally by Etienne Grossmann. Heavily modified and translated
+  // to C++ by jwe.
+
+  octave_value retval;
+
+  if (nargout > 0)
+    retval = load_path::path ();
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      bool need_to_update = false;
+
+      for (int i = 0; i < nargin; i++)
+	{
+	  std::string arg = args(i).string_value ();
+
+	  if (! error_state)
+	    {
+	      std::list<std::string> dir_elts = split_path (arg);
+
+	      for (std::list<std::string>::const_iterator p = dir_elts.begin ();
+		   p != dir_elts.end ();
+		   p++)
+		{
+		  std::string dir = *p;
+
+		  //dir = regexprep (dir_elts{j}, "//+", "/");
+		  //dir = regexprep (dir, "/$", "");
+
+		  if (! load_path::remove (dir))
+		    warning ("rmpath: %s: not found", dir.c_str ());
+		  else
+		    need_to_update = true;
+		}
+	    }
+	  else
+	    error ("addpath: expecting all args to be character strings");
+	}
+
+      if (need_to_update)
+	rehash_internal ();
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/load-path.h b/src/load-path.h
new file mode 100644
index 0000000..620c381
--- /dev/null
+++ b/src/load-path.h
@@ -0,0 +1,538 @@
+/*
+
+Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_load_path_h)
+#define octave_load_path_h 1
+
+#include <iosfwd>
+#include <list>
+#include <map>
+#include <string>
+
+#include "pathsearch.h"
+#include "str-vec.h"
+
+class
+OCTINTERP_API
+load_path
+{
+protected:
+
+  load_path (void)
+    : dir_info_list (), fcn_map (), method_map (), parent_map () { }
+
+public:
+
+  typedef void (*hook_fcn_ptr) (const std::string& dir);
+
+  ~load_path (void) { }
+
+  static void initialize (bool set_initial_path = false)
+  {
+    if (instance_ok ())
+      instance->do_initialize (set_initial_path);
+  }
+
+  static void clear (void)
+  {
+    if (instance_ok ())
+      instance->do_clear ();
+  }
+
+  static void set (const std::string& p, bool warn = false)
+  {
+    if (instance_ok ())
+      instance->do_set (p, warn);
+  }
+
+  static void append (const std::string& dir, bool warn = false)
+  {
+    if (instance_ok ())
+      instance->do_append (dir, warn);
+  }
+
+  static void prepend (const std::string& dir, bool warn = false)
+  {
+    if (instance_ok ())
+      instance->do_prepend (dir, warn);
+  }
+
+  static bool remove (const std::string& dir)
+  {
+    return instance_ok () ? instance->do_remove (dir) : false;
+  }
+
+  static void update (void)
+  {
+    if (instance_ok ())
+      instance->do_update ();
+  }
+
+  static std::string find_method (const std::string& class_name,
+				  const std::string& meth,
+				  std::string& dir_name)
+  {
+    return instance_ok ()
+      ? instance->do_find_method (class_name, meth, dir_name) : std::string ();
+  }
+
+  static std::string find_method (const std::string& class_name,
+				  const std::string& meth)
+  {
+    std::string dir_name;
+    return find_method (class_name, meth, dir_name);
+  }
+
+  static std::list<std::string> methods (const std::string& class_name)
+  {
+    return instance_ok ()
+      ? instance->do_methods (class_name) : std::list<std::string> ();
+  }
+
+  static std::string find_fcn (const std::string& fcn, std::string& dir_name)
+  {
+    return instance_ok ()
+      ? instance->do_find_fcn (fcn, dir_name) : std::string ();
+  }
+
+  static std::string find_fcn (const std::string& fcn)
+  {
+    std::string dir_name;
+    return find_fcn (fcn, dir_name);
+  }
+
+  static std::string find_private_fcn (const std::string& dir,
+				       const std::string& fcn)
+  {
+    return instance_ok ()
+      ? instance->do_find_private_fcn (dir, fcn) : std::string ();
+  }
+
+  static std::string find_fcn_file (const std::string& fcn)
+  {
+    std::string dir_name;
+
+    return instance_ok () ?
+      instance->do_find_fcn (fcn, dir_name, M_FILE) : std::string ();
+  }
+
+  static std::string find_oct_file (const std::string& fcn)
+  {
+    std::string dir_name;
+
+    return instance_ok () ?
+      instance->do_find_fcn (fcn, dir_name, OCT_FILE) : std::string ();
+  }
+
+  static std::string find_mex_file (const std::string& fcn)
+  {
+    std::string dir_name;
+
+    return instance_ok () ?
+      instance->do_find_fcn (fcn, dir_name, MEX_FILE) : std::string ();
+  }
+
+  static std::string find_file (const std::string& file)
+  {
+    return instance_ok ()
+      ? instance->do_find_file (file) : std::string ();
+  }
+
+  static std::string find_dir (const std::string& dir)
+  {
+    return instance_ok ()
+      ? instance->do_find_dir (dir) : std::string ();
+  }
+
+  static std::string find_first_of (const string_vector& files)
+  {
+    return instance_ok () ?
+      instance->do_find_first_of (files) : std::string ();
+  }
+
+  static string_vector find_all_first_of (const string_vector& files)
+  {
+    return instance_ok () ?
+      instance->do_find_all_first_of (files) : string_vector ();
+  }
+
+  static string_vector dirs (void)
+  {
+    return instance_ok () ? instance->do_dirs () : string_vector ();
+  }
+
+  static std::list<std::string> dir_list (void)
+  {
+    return instance_ok ()
+      ? instance->do_dir_list () : std::list<std::string> ();
+  }
+
+  static string_vector files (const std::string& dir, bool omit_exts = false)
+  {
+    return instance_ok ()
+      ? instance->do_files (dir, omit_exts) : string_vector ();
+  }
+
+  static string_vector fcn_names (void)
+  {
+    return instance_ok () ? instance->do_fcn_names () : string_vector ();
+  }
+
+  static std::string path (void)
+  {
+    return instance_ok () ? instance->do_path () : std::string ();
+  }
+
+  static void display (std::ostream& os)
+  {
+    if (instance_ok ())
+      instance->do_display (os);
+  }
+
+  static void set_add_hook (hook_fcn_ptr f) { add_hook = f; }
+
+  static void set_remove_hook (hook_fcn_ptr f) { remove_hook = f; }
+
+  static void set_command_line_path (const std::string& p)
+  {
+    if (command_line_path.empty ())
+      command_line_path = p;
+    else
+      command_line_path += dir_path::path_sep_str () + p;
+  }
+
+  static std::string get_command_line_path (void)
+  {
+    return instance_ok () ? instance->do_get_command_line_path () : std::string ();
+  }
+
+  static std::string system_path (void)
+  {
+    return instance_ok () ? instance->do_system_path () : std::string ();
+  }
+
+  static void add_to_parent_map (const std::string& classname,
+				 const std::list<std::string>& parent_list)
+  {
+    if (instance_ok ())
+      instance->do_add_to_parent_map (classname, parent_list);
+  }
+
+private:
+
+  static const int M_FILE = 1;
+  static const int OCT_FILE = 2;
+  static const int MEX_FILE = 4;
+
+  class dir_info
+  {
+  public:
+
+    // <FCN_NAME, TYPE>
+    typedef std::map<std::string, int> fcn_file_map_type;
+
+    typedef fcn_file_map_type::const_iterator const_fcn_file_map_iterator;
+    typedef fcn_file_map_type::iterator fcn_file_map_iterator;
+
+    struct class_info
+    {
+      fcn_file_map_type method_file_map;
+      fcn_file_map_type private_file_map;
+    };
+
+    // <CLASS_NAME, CLASS_INFO>
+    typedef std::map<std::string, class_info> method_file_map_type;
+
+    typedef method_file_map_type::const_iterator const_method_file_map_iterator;
+    typedef method_file_map_type::iterator method_file_map_iterator;
+
+    // This default constructor is only provided so we can create a
+    // std::map of dir_info objects.  You should not use this
+    // constructor for any other purpose.
+    dir_info (void) { }
+
+    dir_info (const std::string& d) : dir_name (d) { initialize (); }
+
+    dir_info (const dir_info& di)
+      : dir_name (di.dir_name), abs_dir_name (di.abs_dir_name),
+	is_relative (di.is_relative),
+	dir_mtime (di.dir_mtime), all_files (di.all_files),
+	fcn_files (di.fcn_files),
+	private_file_map (di.private_file_map),
+	method_file_map (di.method_file_map) { }
+
+    ~dir_info (void) { }
+
+    dir_info& operator = (const dir_info& di)
+    {
+      if (&di != this)
+	{
+	  dir_name = di.dir_name;
+	  abs_dir_name = di.abs_dir_name;
+	  is_relative = di.is_relative;
+	  dir_mtime = di.dir_mtime;
+	  all_files = di.all_files;
+	  fcn_files = di.fcn_files;
+	  private_file_map = di.private_file_map;
+	  method_file_map = di.method_file_map;
+	}
+
+      return *this;
+    }
+
+    void update (void);
+
+    std::string dir_name;
+    std::string abs_dir_name;
+    bool is_relative;
+    octave_time dir_mtime;
+    string_vector all_files;
+    string_vector fcn_files;
+    fcn_file_map_type private_file_map;
+    method_file_map_type method_file_map;
+
+  private:
+
+    void initialize (void);
+
+    void get_file_list (const std::string& d);
+
+    void get_private_file_map (const std::string& d);
+
+    void get_method_file_map (const std::string& d,
+			      const std::string& class_name);
+
+    friend fcn_file_map_type get_fcn_files (const std::string& d);
+  };
+
+  class file_info
+  {
+  public:
+
+    file_info (const std::string& d, int t) : dir_name (d), types (t) { }
+
+    file_info (const file_info& fi)
+      : dir_name (fi.dir_name), types (fi.types) { }
+
+    ~file_info (void) { }
+
+    file_info& operator = (const file_info& fi)
+    {
+      if (&fi != this)
+	{
+	  dir_name = fi.dir_name;
+	  types = fi.types;
+	}
+
+      return *this;
+    }
+
+    std::string dir_name;
+    int types;
+  };
+
+  // We maintain two ways of looking at the same information.
+  //
+  // First, a list of directories and the set of "public" files and
+  // private files (those found in the special "private" subdirectory)
+  // in each directory.
+  //
+  // Second, a map from file names (the union of all "public" files for all
+  // directories, but without filename extensions) to a list of
+  // corresponding information (directory name and file types).  This
+  // way, we can quickly find shadowed file names and look up all
+  // overloaded functions (in the "@" directories used to implement
+  // classes).
+
+  typedef std::list<dir_info> dir_info_list_type;
+
+  typedef dir_info_list_type::const_iterator const_dir_info_list_iterator;
+  typedef dir_info_list_type::iterator dir_info_list_iterator;
+
+  typedef std::map<std::string, dir_info> abs_dir_cache_type;
+
+  typedef abs_dir_cache_type::const_iterator const_abs_dir_cache_iterator;
+  typedef abs_dir_cache_type::iterator abs_dir_cache_iterator;
+
+  typedef std::list<file_info> file_info_list_type;
+
+  typedef file_info_list_type::const_iterator const_file_info_list_iterator;
+  typedef file_info_list_type::iterator file_info_list_iterator;
+
+  // <FCN_NAME, FILE_INFO_LIST>
+  typedef std::map<std::string, file_info_list_type> fcn_map_type;
+
+  typedef fcn_map_type::const_iterator const_fcn_map_iterator;
+  typedef fcn_map_type::iterator fcn_map_iterator;
+
+  // <DIR_NAME, <FCN_NAME, TYPE>>
+  typedef std::map<std::string, dir_info::fcn_file_map_type> private_fcn_map_type;
+
+  typedef private_fcn_map_type::const_iterator const_private_fcn_map_iterator;
+  typedef private_fcn_map_type::iterator private_fcn_map_iterator;
+
+  // <CLASS_NAME, <FCN_NAME, FILE_INFO_LIST>>
+  typedef std::map<std::string, fcn_map_type> method_map_type;
+
+  typedef method_map_type::const_iterator const_method_map_iterator;
+  typedef method_map_type::iterator method_map_iterator;
+ 
+  // <CLASS_NAME, PARENT_LIST>>
+  typedef std::map<std::string, std::list<std::string> > parent_map_type;
+
+  typedef parent_map_type::const_iterator const_parent_map_iterator;
+  typedef parent_map_type::iterator parent_map_iterator;
+
+  mutable dir_info_list_type dir_info_list;
+
+  mutable fcn_map_type fcn_map;
+
+  mutable private_fcn_map_type private_fcn_map;
+
+  mutable method_map_type method_map;
+
+  mutable parent_map_type parent_map;
+
+  static load_path *instance;
+
+  static hook_fcn_ptr add_hook;
+
+  static hook_fcn_ptr remove_hook;
+
+  static std::string command_line_path;
+
+  static std::string sys_path;
+
+  static abs_dir_cache_type abs_dir_cache;
+
+  static bool instance_ok (void);
+
+  const_dir_info_list_iterator find_dir_info (const std::string& dir) const;
+  dir_info_list_iterator find_dir_info (const std::string& dir);
+
+  bool contains (const std::string& dir) const;
+
+  void move_fcn_map (const std::string& dir,
+		     const string_vector& fcn_files, bool at_end);
+
+  void move_method_map (const std::string& dir, bool at_end);
+
+  void move (std::list<dir_info>::iterator i, bool at_end);
+
+  void do_initialize (bool set_initial_path);
+
+  void do_clear (void);
+
+  void do_set (const std::string& p, bool warn);
+
+  void do_append (const std::string& dir, bool warn);
+
+  void do_prepend (const std::string& dir, bool warn);
+
+  void do_add (const std::string& dir, bool at_end, bool warn);
+
+  void remove_fcn_map (const std::string& dir, const string_vector& fcn_files);
+
+  void remove_private_fcn_map (const std::string& dir);
+
+  void remove_method_map (const std::string& dir);
+
+  bool do_remove (const std::string& dir);
+
+  void do_update (void) const;
+
+  static bool
+  check_file_type (std::string& fname, int type, int possible_types,
+		   const std::string& fcn, const char *who);
+
+  std::string do_find_fcn (const std::string& fcn,
+			   std::string& dir_name,
+			   int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+  std::string do_find_private_fcn (const std::string& dir,
+				   const std::string& fcn,
+				   int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+  std::string do_find_method (const std::string& class_name,
+			      const std::string& meth,
+			      std::string& dir_name,
+			      int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+  std::list<std::string> do_methods (const std::string& class_name) const;
+
+  std::string do_find_file (const std::string& file) const;
+
+  std::string do_find_dir (const std::string& dir) const;
+
+  std::string do_find_first_of (const string_vector& files) const;
+
+  string_vector do_find_all_first_of (const string_vector& files) const;
+
+  string_vector do_dirs (void) const;
+
+  std::list<std::string> do_dir_list (void) const;
+
+  string_vector do_files (const std::string& dir, bool omit_exts) const;
+
+  string_vector do_fcn_names (void) const;
+
+  std::string do_path (void) const;
+
+  friend void print_types (std::ostream& os, int types);
+
+  friend string_vector get_file_list (const dir_info::fcn_file_map_type& lst);
+
+  friend void
+  print_fcn_list (std::ostream& os, const dir_info::fcn_file_map_type& lst);
+
+  void do_display (std::ostream& os) const;
+
+  std::string do_system_path (void) const { return sys_path; }
+
+  std::string do_get_command_line_path (void) const { return command_line_path; }
+
+  void do_add_to_parent_map (const std::string& classname,
+			     const std::list<std::string>& parent_list) const;
+
+  void add_to_fcn_map (const dir_info& di, bool at_end) const;
+
+  void add_to_private_fcn_map (const dir_info& di) const;
+
+  void add_to_method_map (const dir_info& di, bool at_end) const;
+
+  friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d);
+};
+
+extern std::string
+genpath (const std::string& dir, const string_vector& skip = "private");
+
+extern void execute_pkg_add (const std::string& dir);
+extern void execute_pkg_del (const std::string& dir);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/src/load-save.cc b/src/load-save.cc
new file mode 100644
index 0000000..a5e4330
--- /dev/null
+++ b/src/load-save.cc
@@ -0,0 +1,1843 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: John W. Eaton.
+// HDF5 support by Steven G. Johnson <stevenj at alum.mit.edu>
+// Matlab v5 support by James R. Van Zandt <jrv at vanzandt.mv.com>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-path.h"
+#include "load-save.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "symtab.h"
+#include "sysdep.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+#include "ls-hdf5.h"
+#include "ls-mat-ascii.h"
+#include "ls-mat4.h"
+#include "ls-mat5.h"
+#include "ls-oct-ascii.h"
+#include "ls-oct-binary.h"
+
+#ifdef HAVE_ZLIB
+#include "zfstream.h"
+#endif
+
+// Write octave-core file if Octave crashes or is killed by a signal.
+static bool Vcrash_dumps_octave_core = true;
+
+// The maximum amount of memory (in kilobytes) that we will attempt to
+// write to the Octave core file.
+static double Voctave_core_file_limit = -1.0;
+
+// The name of the Octave core file.
+static std::string Voctave_core_file_name = "octave-core";
+
+// The default output format.  May be one of "binary", "text",
+// "mat-binary", or "hdf5".
+static std::string Vdefault_save_options = "-text";
+
+// The output format for Octave core files.
+static std::string Voctave_core_file_options = "-binary";
+
+static std::string
+default_save_header_format (void)
+{
+  return
+    std::string ("# Created by Octave " OCTAVE_VERSION
+		 ", %a %b %d %H:%M:%S %Y %Z <")
+    + octave_env::get_user_name ()
+    + std::string ("@")
+    + octave_env::get_host_name ()
+    + std::string (">");
+}
+
+// The format string for the comment line at the top of text-format
+// save files.  Passed to strftime.  Should begin with `#' and contain
+// no newline characters.
+static std::string Vsave_header_format_string = default_save_header_format ();
+
+static void
+gripe_file_open (const std::string& fcn, const std::string& file)
+{
+  if (fcn == "load")
+    error ("%s: unable to open input file `%s'", fcn.c_str (), file.c_str ());
+  else if (fcn == "save")
+    error ("%s: unable to open output file `%s'", fcn.c_str (), file.c_str ());
+  else
+    error ("%s: unable to open file `%s'", fcn.c_str (), file.c_str ());
+}
+
+// Install a variable with name NAME and the value VAL in the
+// symbol table.  If GLOBAL is TRUE, make the variable global.
+
+static void
+install_loaded_variable (const std::string& name,
+			 const octave_value& val,
+			 bool global, const std::string& /*doc*/)
+{
+  if (global)
+    {
+      symbol_table::clear (name);
+      symbol_table::mark_global (name);
+      symbol_table::global_varref (name) = val;
+    }
+  else
+    symbol_table::varref (name) = val;
+}
+
+// Return TRUE if NAME matches one of the given globbing PATTERNS.
+
+static bool
+matches_patterns (const string_vector& patterns, int pat_idx,
+		  int num_pat, const std::string& name)
+{
+  for (int i = pat_idx; i < num_pat; i++)
+    {
+      glob_match pattern (patterns[i]);
+
+      if (pattern.match (name))
+	return true;
+    }
+
+  return false;
+}
+
+int
+read_binary_file_header (std::istream& is, bool& swap,
+			 oct_mach_info::float_format& flt_fmt, bool quiet)
+{
+  const int magic_len = 10;
+  char magic[magic_len+1];
+  is.read (magic, magic_len);
+  magic[magic_len] = '\0';
+
+  if (strncmp (magic, "Octave-1-L", magic_len) == 0)
+    swap = oct_mach_info::words_big_endian ();
+  else if (strncmp (magic, "Octave-1-B", magic_len) == 0)
+    swap = ! oct_mach_info::words_big_endian ();
+  else
+    {
+      if (! quiet)
+	error ("load: unable to read read binary file");
+      return -1;
+    }
+	
+  char tmp = 0;
+  is.read (&tmp, 1);
+
+  flt_fmt = mopt_digit_to_float_format (tmp);
+
+  if (flt_fmt == oct_mach_info::flt_fmt_unknown)
+    {
+      if (! quiet)
+        error ("load: unrecognized binary format!");
+
+      return -1;
+    }
+
+  return 0;
+}
+
+#ifdef HAVE_ZLIB
+static bool
+check_gzip_magic (const std::string& fname)
+{
+  bool retval = false;
+  std::ifstream file (fname.c_str ());
+  OCTAVE_LOCAL_BUFFER (unsigned char, magic, 2);
+
+  if (file.read (reinterpret_cast<char *> (magic), 2) && magic[0] == 0x1f && 
+      magic[1] == 0x8b)
+    retval = true;
+
+  file.close ();
+  return retval;
+} 
+#endif
+
+static load_save_format
+get_file_format (std::istream& file, const std::string& filename)
+{
+  load_save_format retval = LS_UNKNOWN;
+
+  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
+
+  bool swap = false;
+
+  if (read_binary_file_header (file, swap, flt_fmt, true) == 0)
+    retval = LS_BINARY;
+  else
+    {
+      file.clear ();
+      file.seekg (0, std::ios::beg);
+
+      int32_t mopt, nr, nc, imag, len;
+
+      int err = read_mat_file_header (file, swap, mopt, nr, nc, imag, len, 1);
+
+      if (! err)
+	retval = LS_MAT_BINARY;
+      else
+	{
+	  file.clear ();
+	  file.seekg (0, std::ios::beg);
+
+	  err = read_mat5_binary_file_header (file, swap, true, filename);
+
+	  if (! err)
+  	    {
+	      file.clear ();
+	      file.seekg (0, std::ios::beg);
+	      retval = LS_MAT5_BINARY;
+  	    }
+  	  else
+  	    {
+	      file.clear ();
+	      file.seekg (0, std::ios::beg);
+
+	      std::string tmp = extract_keyword (file, "name");
+
+	      if (! tmp.empty ())
+		retval = LS_ASCII;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static load_save_format
+get_file_format (const std::string& fname, const std::string& orig_fname, 
+		 bool &use_zlib)
+{
+  load_save_format retval = LS_UNKNOWN;
+
+#ifdef HAVE_HDF5
+  // check this before we open the file
+  if (H5Fis_hdf5 (fname.c_str ()) > 0)
+    return LS_HDF5;
+#endif /* HAVE_HDF5 */
+
+  std::ifstream file (fname.c_str ());
+  use_zlib = false;
+      
+  if (file)
+    {
+      retval = get_file_format (file, orig_fname);
+      file.close ();
+
+#ifdef HAVE_ZLIB
+      if (retval == LS_UNKNOWN && check_gzip_magic (fname))	
+	{
+	  gzifstream gzfile (fname.c_str ());
+	  use_zlib = true;
+
+	  if (gzfile)
+	    {
+	      retval = get_file_format (gzfile, orig_fname);
+	      gzfile.close ();
+	    }
+	}
+#endif
+
+      if (retval == LS_UNKNOWN)
+	{
+	  // Try reading the file as numbers only, determining the
+	  // number of rows and columns from the data.  We don't
+	  // even bother to check to see if the first item in the
+	  // file is a number, so that get_complete_line() can
+	  // skip any comments that might appear at the top of the
+	  // file.
+
+	  retval = LS_MAT_ASCII;
+	}
+    }
+  else
+    gripe_file_open ("load", orig_fname);
+
+  return retval;
+}
+
+octave_value
+do_load (std::istream& stream, const std::string& orig_fname,
+	 load_save_format format, oct_mach_info::float_format flt_fmt,
+	 bool list_only, bool swap, bool verbose,
+	 const string_vector& argv, int argv_idx, int argc, int nargout)
+{
+  octave_value retval;
+
+  Octave_map retstruct;
+
+  std::ostringstream output_buf;
+  std::list<std::string> symbol_names;
+
+  octave_idx_type count = 0;
+
+  for (;;)
+    {
+      bool global = false;
+      octave_value tc;
+
+      std::string name;
+      std::string doc;
+
+      switch (format.type)
+	{
+	case LS_ASCII:
+	  name = read_ascii_data (stream, orig_fname, global, tc, count);
+	  break;
+
+	case LS_BINARY:
+	  name = read_binary_data (stream, swap, flt_fmt, orig_fname,
+				   global, tc, doc);
+	  break;
+
+	case LS_MAT_ASCII:
+	  name = read_mat_ascii_data (stream, orig_fname, tc);
+	  break;
+
+	case LS_MAT_BINARY:
+	  name = read_mat_binary_data (stream, orig_fname, tc);
+	  break;
+
+#ifdef HAVE_HDF5
+	case LS_HDF5:
+	  name = read_hdf5_data (stream, orig_fname, global, tc, doc);
+	  break;
+#endif /* HAVE_HDF5 */
+
+	case LS_MAT5_BINARY:
+	case LS_MAT7_BINARY:
+	  name = read_mat5_binary_element (stream, orig_fname, swap,
+					   global, tc);
+	  break;
+
+	default:
+	  gripe_unrecognized_data_fmt ("load");
+	  break;
+	}
+
+      if (error_state || stream.eof () || name.empty ())
+	break;
+      else if (! error_state && ! name.empty ())
+	{
+	  if (tc.is_defined ())
+	    {
+	      if (format == LS_MAT_ASCII && argv_idx < argc)
+		warning ("load: loaded ASCII file `%s' -- ignoring extra args",
+			 orig_fname.c_str ());
+
+	      if (format == LS_MAT_ASCII
+		  || argv_idx == argc
+		  || matches_patterns (argv, argv_idx, argc, name))
+		{
+		  count++;
+		  if (list_only)
+		    {
+		      if (verbose)
+			{
+			  if (count == 1)
+			    output_buf
+			      << "type               rows   cols   name\n"
+			      << "====               ====   ====   ====\n";
+
+			  output_buf
+			    << std::setiosflags (std::ios::left)
+			    << std::setw (16) << tc.type_name () . c_str ()
+			    << std::setiosflags (std::ios::right)
+			    << std::setw (7) << tc.rows ()
+			    << std::setw (7) << tc.columns ()
+			    << "   " << name << "\n";
+			}
+		      else
+			symbol_names.push_back (name);
+		    }
+		  else
+		    {
+		      if (nargout == 1)
+			{
+			  if (format == LS_MAT_ASCII)
+			    retval = tc;
+			  else
+			    retstruct.assign (name, tc);
+			}
+		      else
+			install_loaded_variable (name, tc, global, doc);
+		    }
+		}
+
+	      // Only attempt to read one item from a headless text file.
+
+	      if (format == LS_MAT_ASCII)
+		break;
+	    }
+	  else
+	    error ("load: unable to load variable `%s'", name.c_str ());
+	}
+      else
+	{
+	  if (count == 0)
+	    error ("load: are you sure `%s' is an Octave data file?",
+		   orig_fname.c_str ());
+
+	  break;
+	}
+    }
+
+  if (list_only && count)
+    {
+      if (verbose)
+	{
+	  std::string msg = output_buf.str ();
+
+	  if (nargout > 0)
+	    retval = msg;
+	  else
+	    octave_stdout << msg;
+	}
+      else
+	{
+	  if (nargout  > 0)
+	    retval = Cell (string_vector (symbol_names));
+	  else
+	    {
+	      string_vector names (symbol_names);
+
+	      names.list_in_columns (octave_stdout);
+
+	      octave_stdout << "\n";
+	    }
+	}
+    }
+  else if (retstruct.nfields () != 0)
+    retval = retstruct;
+
+  return retval;
+}
+
+std::string
+find_file_to_load (const std::string& name, const std::string& orig_name)
+{
+  std::string fname = name;
+
+  if (! (octave_env::absolute_pathname (fname)
+	 || octave_env::rooted_relative_pathname (fname)))
+    {
+      file_stat fs (fname);
+
+      if (! (fs.exists () && fs.is_reg ()))
+	{
+	  std::string tmp = octave_env::make_absolute
+	    (load_path::find_file (fname), octave_env::getcwd ());
+
+	  if (! tmp.empty ())
+	    {
+	      warning_with_id ("Octave:load-file-in-path",
+			       "load: file found in load path");
+	      fname = tmp;
+	    }
+	}
+    }
+
+  size_t dot_pos = fname.rfind (".");
+  size_t sep_pos = fname.find_last_of (file_ops::dir_sep_chars ());
+    
+  if (dot_pos == std::string::npos
+      || (sep_pos != std::string::npos && dot_pos < sep_pos))
+    {
+      // Either no '.' in name or no '.' appears after last directory
+      // separator.
+
+      file_stat fs (fname);
+
+      if (! (fs.exists () && fs.is_reg ()))
+	fname = find_file_to_load (fname + ".mat", orig_name);
+    }
+  else
+    {
+      file_stat fs (fname);
+  
+      if (! (fs.exists () && fs.is_reg ()))
+	{
+	  fname = "";
+
+	  error ("load: unable to find file %s", orig_name.c_str ());
+	}
+    }
+
+  return fname;
+}
+
+
+// HDF5 load/save documentation is included in the Octave manual
+// regardless, but if HDF5 is not linked in we also include a
+// sentence noting this, so the user understands that the features
+// aren't available.  Define a macro for this sentence:
+
+#ifdef HAVE_HDF5
+#define HAVE_HDF5_HELP_STRING ""
+#else /* ! HAVE_HDF5 */
+#define HAVE_HDF5_HELP_STRING "\n\
+HDF5 load and save are not available, as this Octave executable was\n\
+not linked with the HDF5 library."
+#endif /* ! HAVE HDF5 */
+
+DEFUN (load, args, nargout,
+  "-*- texinfo -*-\n\
+ at deffn  {Command} load file\n\
+ at deffnx {Command} load options file\n\
+ at deffnx {Command} load options file v1 v2 @dots{}\n\
+ at deffnx {Command} S = load(\"options\", \"file\", \"v1\", \"v2\", @dots{})\n\
+Load the named variables @var{v1}, @var{v2}, @dots{}, from the file\n\
+ at var{file}.  If no variables are specified then all variables found in the\n\
+file will be loaded.  As with @code{save}, the list of variables to extract\n\
+can be full names or use a pattern syntax.  The format of the file is\n\
+automatically detected but may be overridden by supplying the appropriate\n\
+option.\n\
+\n\
+If load is invoked using the functional form\n\
+\n\
+ at example\n\
+load (\"-option1\", @dots{}, \"file\", \"v1\", @dots{})\n\
+ at end example\n\
+\n\
+ at noindent\n\
+then the @var{options}, @var{file}, and variable name arguments\n\
+(@var{v1}, @dots{}) must be specified as character strings.\n\
+\n\
+If a variable that is not marked as global is loaded from a file when a\n\
+global symbol with the same name already exists, it is loaded in the\n\
+global symbol table.  Also, if a variable is marked as global in a file\n\
+and a local symbol exists, the local symbol is moved to the global\n\
+symbol table and given the value from the file.\n\
+\n\
+If invoked with a single output argument, Octave returns data instead\n\
+of inserting variables in the symbol table.  If the data file contains\n\
+only numbers (TAB- or space-delimited columns), a matrix of values is\n\
+returned.  Otherwise, @code{load} returns a structure with members\n\
+ corresponding to the names of the variables in the file.\n\
+\n\
+The @code{load} command can read data stored in Octave's text and\n\
+binary formats, and @sc{matlab}'s binary format.  If compiled with zlib\n\
+support, it can also load gzip-compressed files.  It will automatically\n\
+detect the type of file and do conversion from different floating point\n\
+formats (currently only IEEE big and little endian, though other formats\n\
+may be added in the future).\n\
+\n\
+Valid options for @code{load} are listed in the following table.\n\
+\n\
+ at table @code\n\
+ at item -force\n\
+This option is accepted for backward compatibility but is ignored.\n\
+Octave now overwrites variables currently in memory with\n\
+those of the same name found in the file.\n\
+\n\
+ at item -ascii\n\
+Force Octave to assume the file contains columns of numbers in text format\n\
+without any header or other information.  Data in the file will be loaded\n\
+as a single numeric matrix with the name of the variable derived from the\n\
+name of the file.\n\
+\n\
+ at item -binary\n\
+Force Octave to assume the file is in Octave's binary format.\n\
+\n\
+ at item -hdf5\n\
+Force Octave to assume the file is in HDF5 format.\n\
+(HDF5 is a free, portable binary format developed by the National\n\
+Center for Supercomputing Applications at the University of Illinois.)\n\
+Note that Octave can read HDF5 files not created by itself, but may\n\
+skip some datasets in formats that it cannot support.\n"
+
+HAVE_HDF5_HELP_STRING
+
+"\n\
+ at item -import\n\
+This option is accepted for backward compatibility but is ignored.\n\
+Octave can now support multi-dimensional HDF data and automatically\n\
+modifies variable names if they are invalid Octave identifiers.\n\
+\n\
+ at item -mat\n\
+ at itemx -mat-binary\n\
+ at itemx -6\n\
+ at itemx -v6\n\
+ at itemx -7\n\
+ at itemx -v7\n\
+Force Octave to assume the file is in @sc{matlab}'s version 6 or 7 binary\n\
+format.\n\
+\n\
+ at item  -mat4-binary\n\
+ at itemx -4\n\
+ at itemx -v4\n\
+ at itemx -V4\n\
+Force Octave to assume the file is in the binary format written by\n\
+ at sc{matlab} version 4.\n\
+\n\
+ at item -text\n\
+Force Octave to assume the file is in Octave's text format.\n\
+ at end table\n\
+ at seealso{save, dlmwrite, csvwrite, fwrite}\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("load");
+
+  if (error_state)
+    return retval;
+
+  // It isn't necessary to have the default load format stored in a
+  // user preference variable since we can determine the type of file
+  // as we are reading.
+
+  load_save_format format = LS_UNKNOWN;
+
+  bool list_only = false;
+  bool verbose = false;
+
+  int i;
+  for (i = 1; i < argc; i++)
+    {
+      if (argv[i] == "-force" || argv[i] == "-f")
+	{
+	  // Silently ignore this
+	  // warning ("load: -force ignored");
+	}
+      else if (argv[i] == "-list" || argv[i] == "-l")
+	{
+	  list_only = true;
+	}
+      else if (argv[i] == "-verbose" || argv[i] == "-v")
+	{
+	  verbose = true;
+	}
+      else if (argv[i] == "-ascii" || argv[i] == "-a")
+	{
+	  format = LS_MAT_ASCII;
+	}
+      else if (argv[i] == "-binary" || argv[i] == "-b")
+	{
+	  format = LS_BINARY;
+	}
+      else if (argv[i] == "-mat-binary" || argv[i] == "-mat" || argv[i] == "-m"
+	       || argv[i] == "-6" || argv[i] == "-v6")
+	{
+	  format = LS_MAT5_BINARY;
+	}
+      else if (argv[i] == "-7" || argv[i] == "-v7")
+	{
+	  format = LS_MAT7_BINARY;
+	}
+      else if (argv[i] == "-mat4-binary" || argv[i] == "-V4"
+	       || argv[i] == "-v4" || argv[i] == "-4")
+	{
+	  format = LS_MAT_BINARY;
+	}
+      else if (argv[i] == "-hdf5" || argv[i] == "-h")
+	{
+#ifdef HAVE_HDF5
+	  format = LS_HDF5;
+#else /* ! HAVE_HDF5 */
+	  error ("load: octave executable was not linked with HDF5 library");
+	  return retval;
+#endif /* ! HAVE_HDF5 */
+	}
+      else if (argv[i] == "-import" || argv[i] == "-i")
+	{
+	  warning ("load: -import ignored");
+	}
+      else if (argv[i] == "-text" || argv[i] == "-t")
+	{
+	  format = LS_ASCII;
+	}
+      else
+	break;
+    }
+
+  if (i == argc)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string orig_fname = argv[i];
+
+  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
+
+  bool swap = false;
+
+  if (argv[i] == "-")
+    {
+      i++;
+
+#ifdef HAVE_HDF5
+      if (format == LS_HDF5)
+	error ("load: cannot read HDF5 format from stdin");
+      else
+#endif /* HAVE_HDF5 */
+      if (format != LS_UNKNOWN)
+	{
+	  // FIXME -- if we have already seen EOF on a
+	  // previous call, how do we fix up the state of std::cin so
+	  // that we can get additional input?  I'm afraid that we
+	  // can't fix this using std::cin only.
+
+	  retval = do_load (std::cin, orig_fname, format, flt_fmt,
+			    list_only, swap, verbose, argv, i, argc,
+			    nargout);
+	}
+      else
+	error ("load: must specify file format if reading from stdin");
+    }
+  else
+    {
+      std::string fname = file_ops::tilde_expand (argv[i]);
+
+      fname = find_file_to_load (fname, orig_fname);
+
+      if (error_state)
+	return retval;
+
+      bool use_zlib = false;
+
+      if (format == LS_UNKNOWN)
+	format = get_file_format (fname, orig_fname, use_zlib);
+
+#ifdef HAVE_HDF5
+      if (format == LS_HDF5)
+	{
+	  i++;
+
+	  hdf5_ifstream hdf5_file (fname.c_str ());
+
+	  if (hdf5_file.file_id >= 0)
+	    {
+	      retval = do_load (hdf5_file, orig_fname, format,
+				flt_fmt, list_only, swap, verbose,
+				argv, i, argc, nargout);
+
+	      hdf5_file.close ();
+	    }
+	  else
+	    gripe_file_open ("load", orig_fname);
+	}
+      else
+#endif /* HAVE_HDF5 */
+	// don't insert any statements here; the "else" above has to
+	// go with the "if" below!!!!!
+      if (format != LS_UNKNOWN)
+	{
+	  i++;
+
+	  // Always open in binary mode and handle various
+	  // line-endings explicitly.
+	  std::ios::openmode mode = std::ios::in | std::ios::binary;
+
+#ifdef HAVE_ZLIB
+	  if (use_zlib)
+	    {
+	      gzifstream file (fname.c_str (), mode);
+
+	      if (file)
+		{
+		  if (format == LS_BINARY)
+		    {
+		      if (read_binary_file_header (file, swap, flt_fmt) < 0)
+			{
+			  if (file) file.close ();
+			  return retval;
+			}
+		    }
+		  else if (format == LS_MAT5_BINARY 
+			   || format == LS_MAT7_BINARY)
+		    {
+		      if (read_mat5_binary_file_header (file, swap, false, orig_fname) < 0)
+			{
+			  if (file) file.close ();
+			  return retval;
+			}
+		    }
+
+		  retval = do_load (file, orig_fname, format,
+				    flt_fmt, list_only, swap, verbose,
+				argv, i, argc, nargout);
+
+		  file.close ();
+		}
+	      else
+		gripe_file_open ("load", orig_fname);
+	    }
+	  else
+#endif
+	    {
+	      std::ifstream file (fname.c_str (), mode);
+
+	      if (file)
+		{
+		  if (format == LS_BINARY)
+		    {
+		      if (read_binary_file_header (file, swap, flt_fmt) < 0)
+			{
+			  if (file) file.close ();
+			  return retval;
+			}
+		    }
+		  else if (format == LS_MAT5_BINARY 
+			   || format == LS_MAT7_BINARY)
+		    {
+		      if (read_mat5_binary_file_header (file, swap, false, orig_fname) < 0)
+			{
+			  if (file) file.close ();
+			  return retval;
+			}
+		    }
+
+		  retval = do_load (file, orig_fname, format,
+				    flt_fmt, list_only, swap, verbose,
+				    argv, i, argc, nargout);
+
+		  file.close ();
+		}
+	      else
+		error ("load: unable open input file `%s'",
+		       orig_fname.c_str ());
+	    }
+	}
+    }
+    
+  return retval;
+}
+
+// Return TRUE if PATTERN has any special globbing chars in it.
+
+static bool
+glob_pattern_p (const std::string& pattern)
+{
+  int open = 0;
+
+  int len = pattern.length ();
+
+  for (int i = 0; i < len; i++)
+    {
+      char c = pattern[i];
+
+      switch (c)
+	{
+	case '?':
+	case '*':
+	  return true;
+
+	case '[':	// Only accept an open brace if there is a close
+	  open++;	// brace to match it.  Bracket expressions must be
+	  continue;	// complete, according to Posix.2
+
+	case ']':
+	  if (open)
+	    return true;
+	  continue;
+
+	case '\\':
+	  if (i == len - 1)
+	    return false;
+
+	default:
+	  continue;
+	}
+    }
+
+  return false;
+}
+
+static void
+do_save (std::ostream& os, const octave_value& tc,
+	 const std::string& name, const std::string& help,
+	 bool global, load_save_format fmt, bool save_as_floats)
+{
+  switch (fmt.type)
+    {
+    case LS_ASCII:
+      save_ascii_data (os, tc, name, global, 0);
+      break;
+
+    case LS_BINARY:
+      save_binary_data (os, tc, name, help, global, save_as_floats);
+      break;
+
+    case LS_MAT_ASCII:
+      if (! save_mat_ascii_data (os, tc, fmt.opts & LS_MAT_ASCII_LONG ? 16 : 8, 
+                                 fmt.opts & LS_MAT_ASCII_TABS))
+	warning ("save: unable to save %s in ASCII format", name.c_str ());
+      break;
+
+    case LS_MAT_BINARY:
+      save_mat_binary_data (os, tc, name);
+      break;
+
+#ifdef HAVE_HDF5
+    case LS_HDF5:
+      save_hdf5_data (os, tc, name, help, global, save_as_floats);
+      break;
+#endif /* HAVE_HDF5 */
+
+    case LS_MAT5_BINARY:
+      save_mat5_binary_element (os, tc, name, global, false, save_as_floats);
+      break;
+
+    case LS_MAT7_BINARY:
+      save_mat5_binary_element (os, tc, name, global, true, save_as_floats);
+      break;
+
+    default:
+      gripe_unrecognized_data_fmt ("save");
+      break;
+    }
+}
+
+// Save the info from SR on stream OS in the format specified by FMT.
+
+void
+do_save (std::ostream& os, const symbol_table::symbol_record& sr,
+	 load_save_format fmt, bool save_as_floats)
+{
+  octave_value val = sr.varval ();
+
+  if (val.is_defined ())
+    {
+      std::string name = sr.name ();
+      std::string help;
+      bool global = sr.is_global ();
+
+      do_save (os, val, name, help, global, fmt, save_as_floats);
+    }
+}
+
+// save fields of a scalar structure STR matching PATTERN on stream OS
+// in the format specified by FMT.
+
+static size_t
+save_fields (std::ostream& os, const Octave_map& m,
+	     const std::string& pattern,
+	     load_save_format fmt, bool save_as_floats)
+{
+  glob_match pat (pattern);
+  
+  size_t saved = 0;
+
+  for (Octave_map::const_iterator p = m.begin (); p != m.end (); p++)
+    {
+      std::string empty_str;
+
+      if (pat.match(p->first))
+        {
+          do_save (os, p->second(0), p->first, empty_str,
+		   0, fmt, save_as_floats);
+
+          saved++;
+        }
+    }
+
+  return saved;
+}
+
+// Save variables with names matching PATTERN on stream OS in the
+// format specified by FMT.
+
+static size_t
+save_vars (std::ostream& os, const std::string& pattern,
+	   load_save_format fmt, bool save_as_floats)
+{
+  std::list<symbol_table::symbol_record> vars = symbol_table::glob (pattern);
+
+  size_t saved = 0;
+
+  typedef std::list<symbol_table::symbol_record>::const_iterator const_vars_iterator;
+
+  for (const_vars_iterator p = vars.begin (); p != vars.end (); p++)
+    {
+      do_save (os, *p, fmt, save_as_floats);
+
+      if (error_state)
+	break;
+
+      saved++;
+    }
+
+  return saved;
+}
+
+static string_vector
+parse_save_options (const string_vector &argv,
+		    load_save_format &format, bool &append,
+		    bool &save_as_floats, bool &use_zlib)
+{
+  string_vector retval;
+  int argc = argv.length ();
+
+  bool do_double = false, do_tabs = false;
+
+  for (int i = 0; i < argc; i++)
+    {
+      if (argv[i] == "-append")
+	{
+	  append = true;
+	}
+      else if (argv[i] == "-ascii" || argv[i] == "-a")
+	{
+	  format = LS_MAT_ASCII;
+	}
+      else if (argv[i] == "-double")
+	{
+	  do_double = true;
+	}
+      else if (argv[i] == "-tabs")
+	{
+	  do_tabs = true;
+	}
+      else if (argv[i] == "-text" || argv[i] == "-t")
+	{
+	  format = LS_ASCII;
+	}
+      else if (argv[i] == "-binary" || argv[i] == "-b")
+	{
+	  format = LS_BINARY;
+	}
+      else if (argv[i] == "-hdf5" || argv[i] == "-h")
+	{
+#ifdef HAVE_HDF5
+	  format = LS_HDF5;
+#else /* ! HAVE_HDF5 */
+	  error ("save: octave executable was not linked with HDF5 library");
+#endif /* ! HAVE_HDF5 */
+	}
+      else if (argv[i] == "-mat-binary" || argv[i] == "-mat" 
+	       || argv[i] == "-m" || argv[i] == "-6" || argv[i] == "-v6"
+	       || argv[i] == "-V6")
+	{
+	  format = LS_MAT5_BINARY;
+	}
+#ifdef HAVE_ZLIB
+      else if (argv[i] == "-mat7-binary" || argv[i] == "-7" 
+	       || argv[i] == "-v7" || argv[i] == "-V7")
+	{
+	  format = LS_MAT7_BINARY;
+	}
+#endif
+      else if (argv[i] == "-mat4-binary" || argv[i] == "-V4"
+	       || argv[i] == "-v4" || argv[i] == "-4")
+	{
+	  format = LS_MAT_BINARY;
+	}
+      else if (argv[i] == "-float-binary" || argv[i] == "-f")
+	{
+	  format = LS_BINARY;
+	  save_as_floats = true;
+	}
+      else if (argv[i] == "-float-hdf5")
+	{
+#ifdef HAVE_HDF5
+	  format = LS_HDF5;
+	  save_as_floats = true;
+#else /* ! HAVE_HDF5 */
+	  error ("save: octave executable was not linked with HDF5 library");
+#endif /* ! HAVE_HDF5 */
+	}
+#ifdef HAVE_ZLIB
+      else if (argv[i] == "-zip" || argv[i] == "-z")
+	{
+	  use_zlib  = true;
+	}
+#endif
+      else
+        retval.append (argv[i]);
+    }
+
+  if (do_double)
+    {
+      if (format == LS_MAT_ASCII)
+	format.opts |= LS_MAT_ASCII_LONG;
+      else
+	warning ("save: \"-double\" option only has an effect with \"-ascii\"");
+    }
+
+  if (do_tabs)
+    {
+      if (format == LS_MAT_ASCII)
+	format.opts |= LS_MAT_ASCII_TABS;
+      else
+	warning ("save: \"-tabs\" option only has an effect with \"-ascii\"");
+    }
+
+  return retval;
+}
+
+static string_vector
+parse_save_options (const std::string &arg, load_save_format &format, 
+		    bool &append, bool &save_as_floats, 
+		    bool &use_zlib)
+{
+  std::istringstream is (arg);
+  std::string str;
+  string_vector argv;
+  
+  while (! is.eof ())
+    {
+      is >> str;
+      argv.append (str);
+    }
+
+  return parse_save_options (argv, format, append, save_as_floats, 
+			     use_zlib);
+}
+
+void
+write_header (std::ostream& os, load_save_format format)
+{
+  switch (format.type)
+    {
+    case LS_BINARY:
+      {
+	os << (oct_mach_info::words_big_endian ()
+	       ? "Octave-1-B" : "Octave-1-L");
+
+	oct_mach_info::float_format flt_fmt =
+	  oct_mach_info::native_float_format ();
+
+	char tmp = static_cast<char> (float_format_to_mopt_digit (flt_fmt));
+
+	os.write (&tmp, 1);
+      }
+      break;
+
+    case LS_MAT5_BINARY:
+    case LS_MAT7_BINARY:
+      {
+	char const * versionmagic;
+	int16_t number = *(reinterpret_cast<const int16_t *>("\x00\x01"));
+	struct tm bdt;
+	time_t now;
+	char headertext[128];
+
+	time (&now);
+	bdt = *gmtime (&now);
+	memset (headertext, ' ', 124);
+	// ISO 8601 format date
+	strftime (headertext, 124, "MATLAB 5.0 MAT-file, written by Octave "
+		  OCTAVE_VERSION ", %Y-%m-%d %T UTC", &bdt);
+
+	// The first pair of bytes give the version of the MAT file
+	// format.  The second pair of bytes form a magic number which
+	// signals a MAT file.  MAT file data are always written in
+	// native byte order.  The order of the bytes in the second
+	// pair indicates whether the file was written by a big- or
+	// little-endian machine.  However, the version number is
+	// written in the *opposite* byte order from everything else!
+	if (number == 1)
+	  versionmagic = "\x01\x00\x4d\x49"; // this machine is big endian
+	else
+	  versionmagic = "\x00\x01\x49\x4d"; // this machine is little endian
+
+	memcpy (headertext+124, versionmagic, 4);
+	os.write (headertext, 128);
+      }
+
+      break;
+
+#ifdef HAVE_HDF5
+    case LS_HDF5:
+#endif /* HAVE_HDF5 */
+    case LS_ASCII:
+      {
+	octave_localtime now;
+
+	std::string comment_string = now.strftime (Vsave_header_format_string);
+
+	if (! comment_string.empty ())
+	  {
+#ifdef HAVE_HDF5
+	    if (format == LS_HDF5)
+	      {
+		hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
+		H5Gset_comment (hs.file_id, "/", comment_string.c_str ());
+	      }
+	    else
+#endif /* HAVE_HDF5 */
+	      os << comment_string << "\n";
+	  }
+      }
+    break;
+
+    default:
+      break;
+    }
+}
+
+static void
+save_vars (const string_vector& argv, int argv_idx, int argc,
+	   std::ostream& os, load_save_format fmt,
+	   bool save_as_floats, bool write_header_info)
+{
+  if (write_header_info)
+    write_header (os, fmt);
+
+  if (argv_idx == argc)
+    {
+      save_vars (os, "*", fmt, save_as_floats);
+    }
+  else if (argv[argv_idx] == "-struct")
+    {
+      if (++argv_idx >= argc) 
+        {
+          error ("save: missing struct name");
+          return;
+        }
+
+      std::string struct_name = argv[argv_idx];
+
+      if (! symbol_table::is_variable (struct_name))
+        {
+          error ("save: no such variable: `%s'", struct_name.c_str ());
+          return;
+        }
+
+      octave_value struct_var = symbol_table::varref (struct_name);
+
+      if (! struct_var.is_map () || struct_var.numel () != 1) 
+        {
+          error ("save: `%s' is not a scalar structure",
+		 struct_name.c_str ());
+          return;
+        }
+      Octave_map struct_var_map = struct_var.map_value ();
+
+      ++argv_idx;
+
+      if (argv_idx < argc) 
+        {
+          for (int i = argv_idx; i < argc; i++)
+            {
+              if (! save_fields (os, struct_var_map, argv[i], fmt,
+				 save_as_floats))
+                {
+                  warning ("save: no such field `%s.%s'", 
+			   struct_name.c_str (), argv[i].c_str ());
+                }
+            }
+        }
+      else
+	save_fields (os, struct_var_map, "*", fmt, save_as_floats);
+    }
+  else
+    {
+      for (int i = argv_idx; i < argc; i++)
+	{
+	  if (! save_vars (os, argv[i], fmt, save_as_floats))
+	    warning ("save: no such variable `%s'", argv[i].c_str ());
+	}
+    }
+}
+
+static void
+dump_octave_core (std::ostream& os, const char *fname, load_save_format fmt,
+		  bool save_as_floats)
+{
+  write_header (os, fmt);
+
+  std::list<symbol_table::symbol_record> vars
+    = symbol_table::all_variables (symbol_table::top_scope (), 0);
+
+  double save_mem_size = 0;
+
+  typedef std::list<symbol_table::symbol_record>::const_iterator const_vars_iterator;
+
+  for (const_vars_iterator p = vars.begin (); p != vars.end (); p++)
+    {
+      octave_value val = p->varval ();
+
+      if (val.is_defined ())
+	{
+	  std::string name = p->name ();
+	  std::string help;
+	  bool global = p->is_global ();
+
+	  double val_size = val.byte_size () / 1024;
+
+	  // FIXME -- maybe we should try to throw out the largest first...
+
+	  if (Voctave_core_file_limit < 0
+	      || save_mem_size + val_size < Voctave_core_file_limit)
+	    {
+	      save_mem_size += val_size;
+
+	      do_save (os, val, name, help, global, fmt, save_as_floats);
+
+	      if (error_state)
+		break;
+	    }
+	}
+    }
+
+  message (0, "save to `%s' complete", fname);
+}
+
+void
+dump_octave_core (void)
+{
+  if (Vcrash_dumps_octave_core)
+    {
+      // FIXME -- should choose better file name?
+
+      const char *fname = Voctave_core_file_name.c_str ();
+
+      message (0, "attempting to save variables to `%s'...", fname);
+
+      load_save_format format = LS_BINARY;
+
+      bool save_as_floats = false;
+
+      bool append = false;
+
+      bool use_zlib = false;
+
+      parse_save_options (Voctave_core_file_options, format, append, 
+			  save_as_floats, use_zlib);
+  
+      std::ios::openmode mode = std::ios::out;
+
+      // Matlab v7 files are always compressed
+      if (format == LS_MAT7_BINARY)
+	use_zlib = false;
+
+      if (format == LS_BINARY
+#ifdef HAVE_HDF5
+	  || format == LS_HDF5
+#endif
+	  || format == LS_MAT_BINARY
+	  || format == LS_MAT5_BINARY
+	  || format == LS_MAT7_BINARY)
+	mode |= std::ios::binary;
+
+      mode |= append ? std::ios::ate : std::ios::trunc;
+
+#ifdef HAVE_HDF5
+      if (format == LS_HDF5)
+	{
+	  hdf5_ofstream file (fname, mode);
+
+	  if (file.file_id >= 0)
+	    {
+	      dump_octave_core (file, fname, format, save_as_floats);
+
+	      file.close ();
+	    }
+	  else
+	    warning ("unable to open `%s' for writing...", fname);
+	}
+      else
+#endif /* HAVE_HDF5 */
+	// don't insert any commands here!  The open brace below must
+	// go with the else above!
+	{
+#ifdef HAVE_ZLIB
+	  if (use_zlib)
+	    {
+	      gzofstream file (fname, mode);
+
+	      if (file)
+		{
+		  dump_octave_core (file, fname, format, save_as_floats);
+
+		  file.close ();
+		}
+	      else
+		warning ("unable to open `%s' for writing...", fname);
+	    }
+	  else
+#endif
+	    {
+	      std::ofstream file (fname, mode);
+	  
+	      if (file)
+		{
+		  dump_octave_core (file, fname, format, save_as_floats);
+
+		  file.close ();
+		}
+	      else
+		warning ("unable to open `%s' for writing...", fname);
+	    }
+	}
+    }
+}
+
+#ifdef HAVE_ZLIB
+#define HAVE_ZLIB_HELP_STRING ""
+#else /* ! HAVE_ZLIB */
+#define HAVE_ZLIB_HELP_STRING "\n\
+This option is not available, as this Octave executable was not linked with\n\
+the zlib library."
+#endif /* ! HAVE ZLIB */
+
+DEFUN (save, args, ,
+  "-*- texinfo -*-\n\
+ at deffn  {Command} save file\n\
+ at deffnx {Command} save options file\n\
+ at deffnx {Command} save options file @var{v1} @var{v2} @dots{}\n\
+ at deffnx {Command} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}\n\
+Save the named variables @var{v1}, @var{v2}, @dots{}, in the file\n\
+ at var{file}.  The special filename @samp{-} may be used to write\n\
+output to the terminal.  If no variable names are listed, Octave saves\n\
+all the variables in the current scope.  Otherwise, full variable names or\n\
+pattern syntax can be used to specify the variables to save.\n\
+If the @code{-struct} modifier is used, fields @var{f1} @var{f2} @dots{}\n\
+of the scalar structure @var{STRUCT} are saved as if they were variables\n\
+with corresponding names.\n\
+Valid options for the @code{save} command are listed in the following table.\n\
+Options that modify the output format override the format specified by \n\
+ at code{default_save_options}.\n\
+\n\
+If save is invoked using the functional form\n\
+\n\
+ at example\n\
+save (\"-option1\", @dots{}, \"file\", \"v1\", @dots{})\n\
+ at end example\n\
+\n\
+ at noindent\n\
+then the @var{options}, @var{file}, and variable name arguments\n\
+(@var{v1}, @dots{}) must be specified as character strings.\n\
+\n\
+ at table @code\n\
+ at item -ascii\n\
+Save a single matrix in a text file without header or any other information.\n\
+\n\
+ at item -binary\n\
+Save the data in Octave's binary data format.\n\
+\n\
+ at item -float-binary\n\
+Save the data in Octave's binary data format but only using single\n\
+precision.  Only use this format if you know that all the\n\
+values to be saved can be represented in single precision.\n\
+\n\
+ at item -hdf5\n\
+Save the data in HDF5 format.\n\
+(HDF5 is a free, portable binary format developed by the National\n\
+Center for Supercomputing Applications at the University of Illinois.)\n"
+
+HAVE_HDF5_HELP_STRING
+
+"\n\
+ at item -float-hdf5\n\
+Save the data in HDF5 format but only using single precision.\n\
+Only use this format if you know that all the\n\
+values to be saved can be represented in single precision.\n\
+\n\
+ at item -V7\n\
+ at itemx -v7\n\
+ at itemx -7\n\
+ at itemx -mat7-binary\n\
+Save the data in @sc{matlab}'s v7 binary data format.\n"
+
+HAVE_ZLIB_HELP_STRING
+
+"\n\
+ at item -V6\n\
+ at itemx -v6\n\
+ at itemx -6\n\
+ at itemx -mat\n\
+ at itemx -mat-binary\n\
+Save the data in @sc{matlab}'s v6 binary data format.\n\
+\n\
+ at item -V4\n\
+ at itemx -v4\n\
+ at itemx -4\n\
+ at itemx -mat4-binary\n\
+Save the data in the binary format written by @sc{matlab} version 4.\n\
+\n\
+ at item -text\n\
+Save the data in Octave's text data format.  (default).\n\
+\n\
+ at item -zip\n\
+ at itemx -z\n\
+Use the gzip algorithm to compress the file.  This works equally on files that\n\
+are compressed with gzip outside of octave, and gzip can equally be used to\n\
+convert the files for backward compatibility.\n"
+
+HAVE_ZLIB_HELP_STRING
+
+"@end table\n\
+\n\
+The list of variables to save may use wildcard patterns containing\n\
+the following special characters:\n\
+ at table @code\n\
+ at item ?\n\
+Match any single character.\n\
+\n\
+ at item *\n\
+Match zero or more characters.\n\
+\n\
+ at item [ @var{list} ]\n\
+Match the list of characters specified by @var{list}.  If the first\n\
+character is @code{!} or @code{^}, match all characters except those\n\
+specified by @var{list}.  For example, the pattern @code{[a-zA-Z]} will\n\
+match all lower and upper case alphabetic characters.  \n\
+\n\
+Wildcards may also be used in the field name specifications when using\n\
+the @code{-struct} modifier (but not in the struct name itself).\n\
+\n\
+ at end table\n\
+\n\
+Except when using the @sc{matlab} binary data file format or the\n\
+ at samp{-ascii} format, saving global\n\
+variables also saves the global status of the variable.  If the variable\n\
+is restored at a later time using @samp{load}, it will be restored as a\n\
+global variable.\n\
+\n\
+The command\n\
+\n\
+ at example\n\
+save -binary data a b*\n\
+ at end example\n\
+\n\
+ at noindent\n\
+saves the variable @samp{a} and all variables beginning with @samp{b} to\n\
+the file @file{data} in Octave's binary format.\n\
+ at seealso{load, default_save_options, dlmread, csvread, fread}\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length ();
+
+  string_vector argv = args.make_argv ();
+
+  if (error_state)
+    return retval;
+
+  // Here is where we would get the default save format if it were
+  // stored in a user preference variable.
+
+  bool save_as_floats = false;
+
+  load_save_format format = LS_ASCII;
+
+  bool append = false;
+
+  bool use_zlib = false;
+
+  // get default options
+  parse_save_options (Vdefault_save_options, format, append, save_as_floats, 
+                      use_zlib);
+
+  // override from command line
+  argv = parse_save_options (argv, format, append, save_as_floats, 
+                             use_zlib);
+  argc = argv.length ();
+  int i = 0;
+
+  if (error_state)
+    return retval;
+
+  if (i == argc)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (save_as_floats && format == LS_ASCII)
+    {
+      error ("save: cannot specify both -ascii and -float-binary");
+      return retval;
+    }
+
+  if (argv[i] == "-")
+    {
+      i++;
+
+#ifdef HAVE_HDF5
+      if (format == LS_HDF5)
+        error ("save: cannot write HDF5 format to stdout");
+      else
+#endif /* HAVE_HDF5 */
+	// don't insert any commands here!  the brace below must go
+	// with the "else" above!
+	{
+	  if (append)
+	    warning ("save: ignoring -append option for output to stdout");
+
+	  // FIXME -- should things intended for the screen end up
+	  // in a octave_value (string)?
+	  
+	  save_vars (argv, i, argc, octave_stdout, format,
+		     save_as_floats, true);
+	}
+    }
+
+  // Guard against things like `save a*', which are probably mistakes...
+
+  else if (i == argc - 1 && glob_pattern_p (argv[i]))
+    {
+      print_usage ();
+      return retval;
+    }
+  else
+    {
+      std::string fname = file_ops::tilde_expand (argv[i]);
+
+      i++;
+
+      // Matlab v7 files are always compressed
+      if (format == LS_MAT7_BINARY)
+	use_zlib = false;
+
+      std::ios::openmode mode
+	= append ? (std::ios::app | std::ios::ate) : std::ios::out;
+
+      if (format == LS_BINARY
+#ifdef HAVE_HDF5
+	  || format == LS_HDF5
+#endif
+	  || format == LS_MAT_BINARY
+	  || format == LS_MAT5_BINARY
+	  || format == LS_MAT7_BINARY)
+	mode |= std::ios::binary;
+
+#ifdef HAVE_HDF5
+      if (format == LS_HDF5)
+	{
+	  // FIXME. It should be possible to append to HDF5 files.
+	  if (append)
+	    {
+	      error ("save: appending to HDF5 files is not implemented");
+	      return retval;
+	    }
+
+	  bool write_header_info = ! (append && 
+				      H5Fis_hdf5 (fname.c_str ()) > 0);
+
+	  hdf5_ofstream hdf5_file (fname.c_str (), mode);
+
+	  if (hdf5_file.file_id != -1)
+	    {
+	      save_vars (argv, i, argc, hdf5_file, format,
+			 save_as_floats, write_header_info);
+
+	      hdf5_file.close ();
+	  }
+	else
+	  {
+	    gripe_file_open ("save", fname);
+	    return retval;
+	  }
+	}
+      else
+#endif /* HAVE_HDF5 */
+	// don't insert any statements here!  The brace below must go
+	// with the "else" above!
+	{
+#ifdef HAVE_ZLIB
+	  if (use_zlib)
+	    {
+	      gzofstream file (fname.c_str (), mode);
+
+	      if (file)
+		{
+		  bool write_header_info = ! file.tellp ();
+
+		  save_vars (argv, i, argc, file, format,
+			     save_as_floats, write_header_info);
+
+		  file.close ();
+		}
+	      else
+		{
+		  gripe_file_open ("save", fname);
+		  return retval;
+		}
+	    }
+	  else
+#endif
+	    {
+	      std::ofstream file (fname.c_str (), mode);
+	  
+	      if (file)
+		{
+		  bool write_header_info = ! file.tellp ();
+
+		  save_vars (argv, i, argc, file, format,
+			     save_as_floats, write_header_info);
+
+		  file.close ();
+		}
+	      else
+		{
+		  gripe_file_open ("save", fname);
+		  return retval;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (crash_dumps_octave_core, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} crash_dumps_octave_core ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave tries\n\
+to save all current variables to the file \"octave-core\" if it\n\
+crashes or receives a hangup, terminate or similar signal.\n\
+ at seealso{octave_core_file_limit, octave_core_file_name, octave_core_file_options}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (crash_dumps_octave_core);
+}
+
+DEFUN (default_save_options, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {@var{val} =} default_save_options ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} default_save_options (@var{new_val})\n\
+Query or set the internal variable that specifies the default options\n\
+for the @code{save} command, and defines the default format.\n\
+Typical values include @code{\"-ascii\"}, @code{\"-text -zip\"}.\n\
+The default value is @code{-text}.\n\
+ at seealso{save}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (default_save_options);
+}
+
+DEFUN (octave_core_file_limit, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_limit ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_limit (@var{new_val})\n\
+Query or set the internal variable that specifies the maximum amount\n\
+of memory (in kilobytes) of the top-level workspace that Octave will\n\
+attempt to save when writing data to the crash dump file (the name of\n\
+the file is specified by @var{octave_core_file_name}).  If\n\
+ at var{octave_core_file_options} flags specify a binary format,\n\
+then @var{octave_core_file_limit} will be approximately the maximum\n\
+size of the file.  If a text file format is used, then the file could\n\
+be much larger than the limit.  The default value is -1 (unlimited)\n\
+ at seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (octave_core_file_limit);
+}
+
+DEFUN (octave_core_file_name, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_name ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_name (@var{new_val})\n\
+Query or set the internal variable that specifies the name of the file\n\
+used for saving data from the top-level workspace if Octave aborts.\n\
+The default value is @code{\"octave-core\"}\n\
+ at seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (octave_core_file_name);
+}
+
+DEFUN (octave_core_file_options, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} octave_core_file_options ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_options (@var{new_val})\n\
+Query or set the internal variable that specifies the options used for\n\
+saving the workspace data if Octave aborts.  The value of\n\
+ at code{octave_core_file_options} should follow the same format as the\n\
+options for the @code{save} function.  The default value is Octave's binary\n\
+format.\n\
+ at seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (octave_core_file_options);
+}
+
+DEFUN (save_header_format_string, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {@var{val} =} save_header_format_string ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} save_header_format_string (@var{new_val})\n\
+Query or set the internal variable that specifies the format\n\
+string used for the comment line written at the beginning of\n\
+text-format data files saved by Octave.  The format string is\n\
+passed to @code{strftime} and should begin with the character\n\
+ at samp{#} and contain no newline characters.  If the value of\n\
+ at code{save_header_format_string} is the empty string,\n\
+the header comment is omitted from text-format data files.  The\n\
+default value is\n\
+\n\
+ at c Set example in small font to prevent overfull line\n\
+ at smallexample\n\
+\"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>\"\n\
+ at end smallexample\n\
+ at seealso{strftime, save}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (save_header_format_string);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/load-save.h b/src/load-save.h
new file mode 100644
index 0000000..c4fbc84
--- /dev/null
+++ b/src/load-save.h
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_load_save_h)
+#define octave_load_save_h 1
+
+#include <iosfwd>
+#include <string>
+
+class octave_value;
+
+// FIXME: maybe MAT5 and MAT7 should be options to MAT_BINARY.
+// Similarly, save_as_floats may be an option for LS_BINARY, LS_HDF5 etc.
+enum load_save_format_type
+  {
+    LS_ASCII,
+    LS_BINARY,
+    LS_MAT_ASCII,
+    LS_MAT_BINARY,
+    LS_MAT5_BINARY,
+    LS_MAT7_BINARY,
+#ifdef HAVE_HDF5
+    LS_HDF5,
+#endif /* HAVE_HDF5 */
+    LS_UNKNOWN
+  };
+
+enum load_save_format_options
+{
+  // LS_MAT_ASCII options (not exclusive)
+  LS_MAT_ASCII_LONG = 1,
+  LS_MAT_ASCII_TABS = 2,
+  // LS_MAT_BINARY options
+  LS_MAT_BINARY_V5 = 1,
+  LS_MAT_BINARY_V7,
+  // zero means no option.
+  LS_NO_OPTION = 0  
+};
+
+class load_save_format
+{
+public:
+  load_save_format (load_save_format_type t,
+                    load_save_format_options o = LS_NO_OPTION)
+    : type (t), opts (o) { }
+  operator int (void) const
+    { return type; }
+  int type, opts;
+};
+
+extern void dump_octave_core (void);
+
+extern int
+read_binary_file_header (std::istream& is, bool& swap,
+			 oct_mach_info::float_format& flt_fmt,
+			 bool quiet = false);
+
+extern octave_value
+do_load (std::istream& stream, const std::string& orig_fname, bool force,
+	 load_save_format format, oct_mach_info::float_format flt_fmt,
+	 bool list_only, bool swap, bool verbose,
+	 const string_vector& argv, int argv_idx, int argc, int nargout);
+
+extern void
+do_save (std::ostream& os, const symbol_table::symbol_record& sr,
+	 load_save_format fmt, bool save_as_floats);
+
+extern void
+write_header (std::ostream& os, load_save_format format);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-ascii-helper.cc b/src/ls-ascii-helper.cc
new file mode 100644
index 0000000..90a0273
--- /dev/null
+++ b/src/ls-ascii-helper.cc
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 2009 Benjamin Lindner
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ls-ascii-helper.h"
+
+#include <iostream>
+#include <sstream>
+
+// Helper functions when reading from ascii files.
+
+// These function take care of CR/LF issues when files are opened in
+// text-mode for reading.
+
+// Skip characters from stream IS until a newline is reached.
+// Depending on KEEP_NEWLINE, either eat newline from stream or
+// keep it unread.
+
+void
+skip_until_newline (std::istream& is, bool keep_newline)
+{
+  if (! is)
+    return;
+  
+  while (is)
+    {
+      char c = is.peek ();
+
+      if (c == '\n' || c == '\r')
+	{
+	  // Reached newline.
+	  if (! keep_newline)
+	    {
+	      // Eat the CR or LF character.
+	      char d;
+	      is.get (d);
+	      
+	      // Make sure that for binary-mode opened ascii files
+	      // containing CRLF line endings we skip the LF after CR.
+	      if (c == '\r' && is.peek () == '\n')
+		{
+		  // Yes, LF following CR, eat it.
+		  is.get (d);
+		}
+	    }
+	  
+	  // Newline was found, and read from stream if
+	  // keep_newline == true, so exit loop.
+	  break;
+	}
+      else
+	{
+	  // No newline charater peeked, so read it and proceed to next
+	  // character.
+	  char d;
+	  is.get (d);
+	}
+    }
+}
+
+
+// If stream IS currently points to a newline (a leftover from a
+// previous read) then eat newline(s) until a non-newline character is
+// found.
+
+void
+skip_preceeding_newline (std::istream& is)
+{
+  if (! is)
+    return;
+  
+  // Check whether IS currently points to newline character.
+  char c = is.peek ();
+
+  if (c == '\n' || c == '\r')
+    {
+      // Yes, at newline.
+      do
+	{
+	  // Eat the CR or LF character.
+	  char d;
+	  is.get (d);
+	  
+	  // Make sure that for binary-mode opened ascii files
+	  // containing CRLF line endings we skip the LF after CR.
+	  if (c == '\r' && is.peek () == '\n')
+	    {
+	      // Yes, LF following CR, eat it.
+	      is.get (d);
+	  }
+	  
+	  // Peek into next character.
+	  c = is.peek ();
+
+	  // Loop while still a newline ahead.
+	}
+      while (c == '\n' || c == '\r');
+    }
+}
+
+// Read charaters from stream IS until a newline is reached.
+// Depending on KEEP_NEWLINE, either eat newline from stream or keep
+// it unread.  Characters read are stored and returned as
+// std::string.
+
+std::string
+read_until_newline (std::istream& is, bool keep_newline)
+{
+  if (! is)
+    return std::string ();
+  
+  std::ostringstream buf;
+  
+  while (is)
+    {
+      char c = is.peek ();
+
+      if (c == '\n' || c == '\r')
+	{
+	  // Reached newline.
+	  if (! keep_newline)
+	    {
+	      // Eat the CR or LF character.
+	      char d;
+	      is.get (d);
+	      
+	      // Make sure that for binary-mode opened ascii files
+	      // containing CRLF line endings we skip the LF after
+	      // CR.
+
+	      if (c == '\r' && is.peek () == '\n')
+		{
+		  // Yes, LF following CR, eat it.
+		  is.get (d);
+		}
+	    }
+	  
+	  // Newline was found, and read from stream if
+	  // keep_newline == true, so exit loop.
+	  break;
+	}
+      else
+	{
+	  // No newline charater peeked, so read it, store it, and
+	  // proceed to next.
+	  char d;
+	  is.get (d);
+	  buf << d;
+	}
+    }
+  
+  return buf.str ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-ascii-helper.h b/src/ls-ascii-helper.h
new file mode 100644
index 0000000..abfaa22
--- /dev/null
+++ b/src/ls-ascii-helper.h
@@ -0,0 +1,44 @@
+/*
+
+Copyright (C) 2009 Benjamin Lindner
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_ascii_helper_h)
+#define octave_ls_ascii_helper_h 1
+
+#include <iosfwd>
+#include <string>
+
+extern OCTINTERP_API void
+skip_until_newline (std::istream& is, bool keep_newline = false);
+
+extern OCTINTERP_API void
+skip_preceeding_newline (std::istream& is);
+
+extern OCTINTERP_API std::string
+read_until_newline (std::istream& is, bool keep_newline = false);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-hdf5.cc b/src/ls-hdf5.cc
new file mode 100644
index 0000000..84065e3
--- /dev/null
+++ b/src/ls-hdf5.cc
@@ -0,0 +1,832 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Steven G. Johnson <stevenj at alum.mit.edu>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (HAVE_HDF5)
+
+#include <cfloat>
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "sysdep.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+static std::string
+make_valid_identifier (const std::string& nm)
+{
+  std::string retval;
+
+  size_t nm_len = nm.length ();
+
+  if (nm_len > 0)
+    {
+      if (! isalpha (nm[0]))
+	retval += '_';
+
+      for (size_t i = 0; i < nm_len; i++)
+	{
+	  char c = nm[i];
+	  retval += (isalnum (c) || c == '_') ? c : '_';
+	}
+    }
+
+  return retval;
+}
+
+// Define this to 1 if/when HDF5 supports automatic conversion between
+// integer and floating-point binary data:
+#define HAVE_HDF5_INT2FLOAT_CONVERSIONS 0
+
+// Given two compound types t1 and t2, determine whether they 
+// are compatible for reading/writing.  This function only
+// works for non-nested types composed of simple elements (ints, floats...),
+// which is all we need it for
+
+bool
+hdf5_types_compatible (hid_t t1, hid_t t2)
+{
+  int n;
+  if ((n = H5Tget_nmembers (t1)) != H5Tget_nmembers (t2))
+    return false;
+
+  for (int i = 0; i < n; ++i)
+    {
+      hid_t mt1 = H5Tget_member_type (t1, i);
+      hid_t mt2 = H5Tget_member_type (t2, i);
+
+      if (H5Tget_class (mt1) != H5Tget_class (mt2))
+	return false;
+
+      H5Tclose (mt2);
+      H5Tclose (mt1);
+    }
+
+  return true;
+}
+
+// Return true if loc_id has the attribute named attr_name, and false
+// otherwise.
+
+bool
+hdf5_check_attr (hid_t loc_id, const char *attr_name)
+{
+  bool retval = false;
+
+  // we have to pull some shenanigans here to make sure
+  // HDF5 doesn't print out all sorts of error messages if we
+  // call H5Aopen for a non-existing attribute
+
+  H5E_auto_t err_func;
+  void *err_func_data;
+
+  // turn off error reporting temporarily, but save the error
+  // reporting function:
+
+  H5Eget_auto (&err_func, &err_func_data);
+  H5Eset_auto (0, 0);
+
+  hid_t attr_id = H5Aopen_name (loc_id, attr_name);
+
+  if (attr_id >= 0)
+    {
+      // successful
+      retval = 1;
+      H5Aclose (attr_id);
+    }
+
+  // restore error reporting:
+  H5Eset_auto (err_func, err_func_data);
+
+  return retval;
+}
+
+// The following subroutines creates an HDF5 representations of the way
+// we will store Octave complex types (pairs of floating-point numbers).
+// NUM_TYPE is the HDF5 numeric type to use for storage (e.g. 
+// H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary 
+// conversions are handled automatically by HDF5.
+
+hid_t
+hdf5_make_complex_type (hid_t num_type)
+{
+  hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 2);
+
+  H5Tinsert (type_id, "real", 0 * sizeof (double), num_type);
+  H5Tinsert (type_id, "imag", 1 * sizeof (double), num_type);
+
+  return type_id;
+}
+
+// This variable, set in read_hdf5_data(), tells whether we are using
+// a version of HDF5 with a buggy H5Giterate (i.e. which neglects to
+// increment the index parameter to the next unread item).
+static bool have_h5giterate_bug = false;
+
+// This function is designed to be passed to H5Giterate, which calls it
+// on each data item in an HDF5 file.  For the item whose name is NAME in
+// the group GROUP_ID, this function sets dv->tc to an Octave representation
+// of that item.  (dv must be a pointer to hdf5_callback_data.)  (It also
+// sets the other fields of dv).
+//
+// It returns 1 on success (in which case H5Giterate stops and returns),
+// -1 on error, and 0 to tell H5Giterate to continue on to the next item
+// (e.g. if NAME was a data type we don't recognize).
+
+herr_t
+hdf5_read_next_data (hid_t group_id, const char *name, void *dv)
+{
+  hdf5_callback_data *d = static_cast <hdf5_callback_data *> (dv);
+  hid_t type_id = -1, type_class_id = -1, data_id = -1, subgroup_id = -1,
+    space_id = -1;
+
+  H5G_stat_t info;
+  herr_t retval = 0;
+  bool ident_valid = valid_identifier (name);
+
+  std::string vname = name;
+
+  // Allow identifiers as all digits so we can load lists saved by
+  // earlier versions of Octave.
+
+  if (! ident_valid )
+    {
+      // fix the identifier, replacing invalid chars with underscores
+      vname = make_valid_identifier (vname);
+
+      // check again (in case vname was null, empty, or some such thing):
+      ident_valid = valid_identifier (vname); 
+    }
+
+  H5Gget_objinfo (group_id, name, 1, &info);
+
+  if (info.type == H5G_GROUP && ident_valid)
+    {
+      subgroup_id = H5Gopen (group_id, name);
+
+      if (subgroup_id < 0)
+	{
+	  retval = subgroup_id;
+	  goto done;
+	}
+
+      if (hdf5_check_attr (subgroup_id, "OCTAVE_NEW_FORMAT"))
+	{
+	  data_id = H5Dopen (subgroup_id, "type");
+
+	  if (data_id < 0)
+	    {
+	      retval = data_id;
+	      goto done;
+	    }
+
+	  type_id = H5Dget_type (data_id);
+
+	  type_class_id = H5Tget_class (type_id);
+
+	  if (type_class_id != H5T_STRING)
+	    goto done;
+	  
+	  space_id = H5Dget_space (data_id);
+	  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+	  if (rank != 0)
+	    goto done;
+
+	  int slen = H5Tget_size (type_id);
+	  if (slen < 0)
+	    goto done;
+
+	  OCTAVE_LOCAL_BUFFER (char, typ, slen);
+
+	  // create datatype for (null-terminated) string to read into:
+	  hid_t st_id = H5Tcopy (H5T_C_S1);
+	  H5Tset_size (st_id, slen);
+
+	  if (H5Dread (data_id, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
+		       typ) < 0)
+	    goto done;
+
+	  H5Tclose (st_id);
+	  H5Dclose (data_id);
+
+	  d->tc = octave_value_typeinfo::lookup_type (typ);
+
+	  retval = (d->tc.load_hdf5 (subgroup_id, "value", 
+		have_h5giterate_bug) ? 1 : -1);
+
+	  // check for OCTAVE_GLOBAL attribute:
+	  d->global = hdf5_check_attr (subgroup_id, "OCTAVE_GLOBAL");
+
+	  H5Gclose (subgroup_id);
+	}
+      else
+	{
+	  // an HDF5 group is treated as an octave structure by
+	  // default (since that preserves name information), and an
+	  // octave list otherwise.
+
+	  if (hdf5_check_attr (subgroup_id, "OCTAVE_LIST"))
+	    d->tc = octave_value_typeinfo::lookup_type ("list");
+	  else
+	    d->tc = octave_value_typeinfo::lookup_type ("struct");
+	  
+	  // check for OCTAVE_GLOBAL attribute:
+	  d->global = hdf5_check_attr (subgroup_id, "OCTAVE_GLOBAL");
+
+	  H5Gclose (subgroup_id);
+
+	  retval = (d->tc.load_hdf5 (group_id, name, have_h5giterate_bug) 
+		    ? 1 : -1);
+	}
+
+    }
+  else if (info.type == H5G_DATASET && ident_valid)
+    {
+      // For backwards compatiability.
+      data_id = H5Dopen (group_id, name);
+
+      if (data_id < 0)
+	{
+	  retval = data_id;
+	  goto done;
+	}
+
+      type_id = H5Dget_type (data_id);
+      
+      type_class_id = H5Tget_class (type_id);
+
+      if (type_class_id == H5T_FLOAT)
+	{
+	  space_id = H5Dget_space (data_id);
+
+	  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+	  
+	  if (rank == 0)
+	    d->tc = octave_value_typeinfo::lookup_type ("scalar");
+	  else
+	    d->tc = octave_value_typeinfo::lookup_type ("matrix");
+
+	  H5Sclose (space_id);
+	}
+      else if (type_class_id == H5T_INTEGER)
+	{
+	  // What integer type do we really have..
+	  std::string int_typ;
+#ifdef HAVE_H5T_GET_NATIVE_TYPE
+	  // FIXME test this code and activated with an autoconf 
+	  // test!! It is also incorrect for 64-bit indexing!!
+	  
+	  switch (H5Tget_native_type (type_id, H5T_DIR_ASCEND))
+	    {
+	    case H5T_NATIVE_CHAR:
+	      int_typ = "int8 ";
+	      break;
+ 
+	    case H5T_NATIVE_SHORT:
+	      int_typ = "int16 ";
+	      break;
+
+	    case H5T_NATIVE_INT:
+	    case H5T_NATIVE_LONG:
+	      int_typ = "int32 ";
+	      break;
+
+	    case H5T_NATIVE_LLONG:
+	      int_typ = "int64 ";
+	      break;
+
+	    case H5T_NATIVE_UCHAR:
+	      int_typ = "uint8 ";
+	      break;
+
+	    case H5T_NATIVE_USHORT:
+	      int_typ = "uint16 ";
+	      break;
+
+	    case H5T_NATIVE_UINT:
+	    case H5T_NATIVE_ULONG:
+	      int_typ = "uint32 ";
+	      break;
+
+	    case H5T_NATIVE_ULLONG:
+	      int_typ = "uint64 ";
+	      break;
+	    }   
+#else
+	  hid_t int_sign = H5Tget_sign (type_id);
+
+	  if (int_sign == H5T_SGN_ERROR)
+	    warning ("load: can't read `%s' (unknown datatype)", name);
+	  else
+	    {
+	      if (int_sign == H5T_SGN_NONE)
+		int_typ.append ("u");
+	      int_typ.append ("int");
+
+	      int slen = H5Tget_size (type_id);
+	      if (slen < 0)
+		warning ("load: can't read `%s' (unknown datatype)", name);
+	      else
+		{
+		  switch (slen)
+		    {
+		    case 1:
+		      int_typ.append ("8 ");
+		      break;
+
+		    case 2:
+		      int_typ.append ("16 ");
+		      break;
+
+		    case 4:
+		      int_typ.append ("32 ");
+		      break;
+
+		    case 8:
+		      int_typ.append ("64 ");
+		      break;
+
+		    default:
+		      warning ("load: can't read `%s' (unknown datatype)", 
+			       name);
+		      int_typ = "";
+		      break;
+		    }
+		}
+	    }
+#endif
+	  if (int_typ == "")
+	    warning ("load: can't read `%s' (unknown datatype)", name);
+	  else
+	    {
+	      // Matrix or scalar?
+	      space_id = H5Dget_space (data_id);
+
+	      hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+	      
+	      if (rank == 0)
+		int_typ.append ("scalar");
+	      else
+		int_typ.append ("matrix");
+
+	      d->tc = octave_value_typeinfo::lookup_type (int_typ);
+	      H5Sclose (space_id);
+	    }
+	}
+      else if (type_class_id == H5T_STRING)
+	d->tc = octave_value_typeinfo::lookup_type ("string");
+      else if (type_class_id == H5T_COMPOUND)
+	{
+	  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+
+	  if (hdf5_types_compatible (type_id, complex_type))
+	    {
+	      // read complex matrix or scalar variable
+	      space_id = H5Dget_space (data_id);
+	      hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+		  
+	      if (rank == 0)
+		d->tc = octave_value_typeinfo::lookup_type ("complex scalar");
+	      else
+		d->tc = octave_value_typeinfo::lookup_type ("complex matrix");
+
+	      H5Sclose (space_id);
+	    }
+	  else
+	    // Assume that if its not complex its a range. If its not
+	    // it'll be rejected later in the range code
+	    d->tc = octave_value_typeinfo::lookup_type ("range");
+
+	  H5Tclose (complex_type);
+	}
+      else
+	{
+	  warning ("load: can't read `%s' (unknown datatype)", name);
+	  retval = 0; // unknown datatype; skip
+	}
+      
+      // check for OCTAVE_GLOBAL attribute:
+      d->global = hdf5_check_attr (data_id, "OCTAVE_GLOBAL");
+
+      H5Tclose (type_id);
+      H5Dclose (data_id);
+
+      retval = (d->tc.load_hdf5 (group_id, name, have_h5giterate_bug) 
+		? 1 : -1);
+    }
+
+  if (!ident_valid)
+    {
+      // should we attempt to handle invalid identifiers by converting
+      // bad characters to '_', say?
+      warning ("load: skipping invalid identifier `%s' in hdf5 file",
+	       name);
+    }
+
+ done:
+  if (retval < 0)
+    error ("load: error while reading hdf5 item %s", name);
+  
+  if (retval > 0)
+    {
+      // get documentation string, if any:
+      int comment_length = H5Gget_comment (group_id, name, 0, 0);
+
+      if (comment_length > 1)
+	{
+	  OCTAVE_LOCAL_BUFFER (char, tdoc, comment_length);
+	  H5Gget_comment (group_id, name, comment_length, tdoc);
+	  d->doc = tdoc;
+	}
+      else if (vname != name)
+	{
+	  // the name was changed; store the original name
+	  // as the documentation string:
+	  d->doc = name;
+	}
+
+      // copy name (actually, vname):
+      d->name = vname;
+    }
+
+  return retval;
+}
+
+// Read the next Octave variable from the stream IS, which must really be
+// an hdf5_ifstream.  Return the variable value in tc, its doc string
+// in doc, and whether it is global in global.  The return value is
+// the name of the variable, or NULL if none were found or there was
+// and error.
+std::string
+read_hdf5_data (std::istream& is, const std::string& /* filename */, 
+		bool& global, octave_value& tc, std::string& doc)
+{
+  std::string retval;
+
+  doc.resize (0);
+
+  hdf5_ifstream& hs = dynamic_cast<hdf5_ifstream&> (is);
+  hdf5_callback_data d;
+
+  // Versions of HDF5 prior to 1.2.2 had a bug in H5Giterate where it
+  // would return the index of the last item processed instead of the
+  // next item to be processed, forcing us to increment the index manually.
+
+  unsigned int vers_major, vers_minor, vers_release;
+
+  H5get_libversion (&vers_major, &vers_minor, &vers_release);
+
+  // FIXME -- this test looks wrong.
+  have_h5giterate_bug
+    = (vers_major < 1
+       || (vers_major == 1 && (vers_minor < 2
+			       || (vers_minor == 2 && vers_release < 2))));
+
+  herr_t H5Giterate_retval = -1;
+
+#ifdef HAVE_H5GGET_NUM_OBJS
+  hsize_t num_obj = 0;
+  hid_t group_id = H5Gopen (hs.file_id, "/"); 
+  H5Gget_num_objs (group_id, &num_obj);
+  H5Gclose (group_id);
+  if (hs.current_item < static_cast<int> (num_obj))
+#endif
+    H5Giterate_retval = H5Giterate (hs.file_id, "/", &hs.current_item,
+				    hdf5_read_next_data, &d);
+
+  if (have_h5giterate_bug)
+    {
+      // H5Giterate sets current_item to the last item processed; we want
+      // the index of the next item (for the next call to read_hdf5_data)
+
+      hs.current_item++;
+    }
+
+  if (H5Giterate_retval > 0)
+    {
+      global = d.global;
+      tc = d.tc;
+      doc = d.doc;
+    }
+  else
+    {
+      // an error occurred (H5Giterate_retval < 0) or there are no
+      // more datasets print an error message if retval < 0?
+      // hdf5_read_next_data already printed one, probably.
+    }
+
+  if (! d.name.empty ())
+    retval = d.name;
+
+  return retval;
+}
+
+// Add an attribute named attr_name to loc_id (a simple scalar
+// attribute with value 1).  Return value is >= 0 on success.
+static herr_t
+hdf5_add_attr (hid_t loc_id, const char *attr_name)
+{
+  herr_t retval = 0;
+
+  hid_t as_id = H5Screate (H5S_SCALAR);
+
+  if (as_id >= 0)
+    {
+      hid_t a_id = H5Acreate (loc_id, attr_name,
+			      H5T_NATIVE_UCHAR, as_id, H5P_DEFAULT);
+
+      if (a_id >= 0)
+	{
+	  unsigned char attr_val = 1;
+
+	  retval = H5Awrite (a_id, H5T_NATIVE_UCHAR, &attr_val);
+
+	  H5Aclose (a_id);
+	}
+      else
+	retval = a_id;
+
+      H5Sclose (as_id);
+    }
+  else
+    retval = as_id;
+
+  return retval;
+}
+
+// Save an empty matrix, if needed. Returns
+//    > 0  Saved empty matrix
+//    = 0  Not an empty matrix; did nothing
+//    < 0  Error condition
+int
+save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d)
+{
+  hsize_t sz = d.length ();
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, dims, sz);
+  bool empty = false;
+  hid_t space_hid = -1, data_hid = -1;
+  int retval;
+  for (hsize_t i = 0; i < sz; i++)
+    {
+      dims[i] = d(i);
+      if (dims[i] < 1)
+	empty = true;
+    }
+
+  if (!empty)
+    return 0;
+
+  space_hid = H5Screate_simple (1, &sz, 0);
+  if (space_hid < 0) return space_hid;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return data_hid;
+    }
+  
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, dims) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  if (retval >= 0)
+    retval = hdf5_add_attr (loc_id, "OCTAVE_EMPTY_MATRIX");
+  
+  return (retval == 0 ? 1 : retval);
+}
+
+// Load an empty matrix, if needed. Returns
+//    > 0  loaded empty matrix, dimensions returned
+//    = 0  Not an empty matrix; did nothing
+//    < 0  Error condition
+int
+load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d)
+{
+  if (!hdf5_check_attr(loc_id, "OCTAVE_EMPTY_MATRIX"))
+    return 0;
+
+  hsize_t hdims, maxdims;
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+  H5Sget_simple_extent_dims (space_id, &hdims, &maxdims);
+  int retval;
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, dims, hdims);
+
+  retval = H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+		    H5P_DEFAULT, dims);
+  if (retval >= 0)
+    {
+      d.resize (hdims);
+      for (hsize_t i = 0; i < hdims; i++)
+	d(i) = dims[i];
+    }
+
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return (retval == 0 ? hdims : retval);
+}
+
+// save_type_to_hdf5 is not currently used, since hdf5 doesn't yet support
+// automatic float<->integer conversions:
+
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+
+// return the HDF5 type id corresponding to the Octave save_type
+
+hid_t
+save_type_to_hdf5 (save_type st)
+{
+  switch (st)
+    {
+    case LS_U_CHAR:
+      return H5T_NATIVE_UCHAR;
+
+    case LS_U_SHORT:
+      return H5T_NATIVE_USHORT;
+
+    case LS_U_INT:
+      return H5T_NATIVE_UINT;
+
+    case LS_CHAR:
+      return H5T_NATIVE_CHAR;
+
+    case LS_SHORT:
+      return H5T_NATIVE_SHORT;
+
+    case LS_INT:
+      return H5T_NATIVE_INT;
+
+    case LS_FLOAT:
+      return H5T_NATIVE_FLOAT;
+
+    case LS_DOUBLE:
+    default:
+      return H5T_NATIVE_DOUBLE;
+    }
+}
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+
+// Add the data from TC to the HDF5 location loc_id, which could
+// be either a file or a group within a file.  Return true if
+// successful.  This function calls itself recursively for lists
+// (stored as HDF5 groups).
+
+bool
+add_hdf5_data (hid_t loc_id, const octave_value& tc,
+	       const std::string& name, const std::string& doc,
+	       bool mark_as_global, bool save_as_floats)
+{
+  hsize_t dims[3];
+  hid_t type_id = -1, space_id = -1, data_id = -1, data_type_id = -1;
+  bool retval = false;
+  octave_value val = tc;
+  // FIXME: diagonal & permutation matrices currently don't know how to save
+  // themselves, so we convert them first to normal matrices using A = A(:,:).
+  // This is a temporary hack.
+  if (val.is_diag_matrix () || val.is_perm_matrix ())
+    val = val.full_value ();
+
+  std::string t = val.type_name();
+
+  data_id = H5Gcreate (loc_id, name.c_str (), 0);
+  if (data_id < 0)
+    goto error_cleanup;
+
+  // attach the type of the variable
+  type_id = H5Tcopy (H5T_C_S1); H5Tset_size (type_id, t.length () + 1);
+  if (type_id < 0)
+    goto error_cleanup;
+
+  dims[0] = 0;
+  space_id = H5Screate_simple (0 , dims, 0);
+  if (space_id < 0)
+    goto error_cleanup;
+
+  data_type_id = H5Dcreate (data_id, "type",  type_id, space_id, H5P_DEFAULT);
+  if (data_type_id < 0 || H5Dwrite (data_type_id, type_id, H5S_ALL, H5S_ALL, 
+				    H5P_DEFAULT, t.c_str ()) < 0)
+    goto error_cleanup;
+
+  // Now call the real function to save the variable
+  retval = val.save_hdf5 (data_id, "value", save_as_floats);
+
+  // attach doc string as comment:
+  if (retval && doc.length () > 0
+      && H5Gset_comment (loc_id, name.c_str (), doc.c_str ()) < 0)
+    retval = false;
+
+  // if it's global, add an attribute "OCTAVE_GLOBAL" with value 1
+  if (retval && mark_as_global)
+    retval = hdf5_add_attr (data_id, "OCTAVE_GLOBAL") >= 0;
+
+  // We are saving in the new variable format, so mark it
+  if (retval)
+    retval = hdf5_add_attr (data_id, "OCTAVE_NEW_FORMAT") >= 0;
+
+ error_cleanup:
+
+  if (data_type_id >= 0)
+    H5Dclose (data_type_id);
+
+  if (type_id >= 0)
+    H5Tclose (type_id);
+
+  if (space_id >= 0)
+    H5Sclose (space_id);
+
+  if (data_id >= 0)
+    H5Gclose (data_id);
+
+  if (! retval)
+    error ("save: error while writing `%s' to hdf5 file", name.c_str ());
+
+  return retval;
+}
+
+// Write data from TC in HDF5 (binary) format to the stream OS,
+// which must be an hdf5_ofstream, returning true on success.
+
+bool
+save_hdf5_data (std::ostream& os, const octave_value& tc,
+		const std::string& name, const std::string& doc,
+		bool mark_as_global, bool save_as_floats)
+{
+  hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
+
+  return add_hdf5_data (hs.file_id, tc, name, doc,
+			mark_as_global, save_as_floats);
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-hdf5.h b/src/ls-hdf5.h
new file mode 100644
index 0000000..ffa3d4a
--- /dev/null
+++ b/src/ls-hdf5.h
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_hdf5_h)
+#define octave_ls_hdf5_h 1
+
+#if defined (HAVE_HDF5)
+
+#include "oct-hdf5.h"
+
+// first, we need to define our own dummy stream subclass, since
+// HDF5 needs to do its own file i/o
+
+// hdf5_fstreambase is used for both input and output streams, modeled
+// on the fstreambase class in <fstream.h>
+
+class hdf5_fstreambase : virtual public std::ios
+{
+public:
+
+  // HDF5 uses an "id" to refer to an open file
+  hid_t file_id;
+
+  // keep track of current item index in the file
+  int current_item;
+
+  hdf5_fstreambase () { file_id = -1; }
+
+  ~hdf5_fstreambase () { close (); }
+
+  hdf5_fstreambase (const char *name, int mode, int /* prot */ = 0)
+    {
+      if (mode & std::ios::in)
+	file_id = H5Fopen (name, H5F_ACC_RDONLY, H5P_DEFAULT);
+      else if (mode & std::ios::out)
+	{
+	  if (mode & std::ios::app && H5Fis_hdf5 (name) > 0)
+	    file_id = H5Fopen (name, H5F_ACC_RDWR, H5P_DEFAULT);
+	  else
+	    file_id = H5Fcreate (name, H5F_ACC_TRUNC, H5P_DEFAULT, 
+				 H5P_DEFAULT);
+	}
+      if (file_id < 0)
+	std::ios::setstate (std::ios::badbit);
+
+      current_item = 0;
+    }
+
+  void close ()
+    { 
+      if (file_id >= 0)
+	{
+	  if (H5Fclose (file_id) < 0)
+	    std::ios::setstate (std::ios::badbit);
+	  file_id = -1;
+	}
+    }
+
+  void open (const char *name, int mode, int)
+    {
+      clear ();
+
+      if (mode & std::ios::in)
+	file_id = H5Fopen (name, H5F_ACC_RDONLY, H5P_DEFAULT);
+      else if (mode & std::ios::out)
+	{
+	  if (mode & std::ios::app && H5Fis_hdf5 (name) > 0)
+	    file_id = H5Fopen (name, H5F_ACC_RDWR, H5P_DEFAULT);
+	  else
+	    file_id = H5Fcreate (name, H5F_ACC_TRUNC, H5P_DEFAULT, 
+				 H5P_DEFAULT);
+	}
+      if (file_id < 0)
+	std::ios::setstate (std::ios::badbit);
+
+      current_item = 0;
+    }
+};
+
+// input and output streams, subclassing istream and ostream
+// so that we can pass them for stream parameters in the functions below.
+
+class hdf5_ifstream : public hdf5_fstreambase, public std::istream
+{
+public:
+
+  hdf5_ifstream () : hdf5_fstreambase (), std::istream (0) { }
+
+  hdf5_ifstream (const char *name, int mode = std::ios::in|std::ios::binary,
+		 int prot = 0)
+    : hdf5_fstreambase (name, mode, prot), std::istream (0) { }
+
+  void open (const char *name, int mode = std::ios::in|std::ios::binary,
+	     int prot = 0)
+    { hdf5_fstreambase::open (name, mode, prot); }
+};
+
+class hdf5_ofstream : public hdf5_fstreambase, public std::ostream
+{
+public:
+
+  hdf5_ofstream () : hdf5_fstreambase (), std::ostream (0) { }
+
+  hdf5_ofstream (const char *name, int mode = std::ios::out|std::ios::binary,
+		 int prot = 0)
+    : hdf5_fstreambase (name, mode, prot), std::ostream (0) { }
+
+  void open (const char *name, int mode = std::ios::out|std::ios::binary,
+	     int prot = 0)
+    { hdf5_fstreambase::open (name, mode, prot); }
+};
+
+// Callback data structure for passing data to hdf5_read_next_data, below.
+
+struct
+hdf5_callback_data
+{
+  hdf5_callback_data (void)
+    : name (), global (false), tc (), doc () { }
+
+  // the following fields are set by hdf5_read_data on successful return:
+
+  // the name of the variable
+  std::string name;
+
+  // whether it is global
+  bool global;
+
+  // the value of the variable, in Octave form
+  octave_value tc;
+
+  // a documentation string (NULL if none)
+  std::string doc;
+};
+
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+extern OCTINTERP_API hid_t
+save_type_to_hdf5 (save_type st)
+#endif
+
+extern OCTINTERP_API hid_t
+hdf5_make_complex_type (hid_t num_type);
+
+extern OCTINTERP_API bool
+hdf5_types_compatible (hid_t t1, hid_t t2);
+
+extern OCTINTERP_API herr_t
+hdf5_read_next_data (hid_t group_id, const char *name, void *dv);
+
+extern OCTINTERP_API bool
+add_hdf5_data (hid_t loc_id, const octave_value& tc,
+	       const std::string& name, const std::string& doc,
+	       bool mark_as_global, bool save_as_floats);
+
+extern OCTINTERP_API int
+save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d);
+
+extern OCTINTERP_API int
+load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d);
+
+extern OCTINTERP_API std::string
+read_hdf5_data (std::istream& is,  const std::string& filename, bool& global,
+		octave_value& tc, std::string& doc);
+
+extern OCTINTERP_API bool
+save_hdf5_data (std::ostream& os, const octave_value& tc,
+		const std::string& name, const std::string& doc,
+		bool mark_as_global, bool save_as_floats);
+
+#ifdef IDX_TYPE_LONG
+#define H5T_NATIVE_IDX H5T_NATIVE_LONG
+#else
+#define H5T_NATIVE_IDX H5T_NATIVE_INT
+#endif
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-mat-ascii.cc b/src/ls-mat-ascii.cc
new file mode 100644
index 0000000..0aaebfd
--- /dev/null
+++ b/src/ls-mat-ascii.cc
@@ -0,0 +1,385 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "lex.h"
+#include "load-save.h"
+#include "ls-ascii-helper.h"
+#include "ls-mat-ascii.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "sysdep.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+static std::string
+get_mat_data_input_line (std::istream& is)
+{
+  std::string retval;
+
+  bool have_data = false;
+
+  do
+    {
+      retval = "";
+
+      char c;
+      while (is.get (c))
+	{
+	  if (c == '\n' || c == '\r')
+	    {
+	      is.putback (c);
+	      skip_preceeding_newline (is);
+	      break;
+	    }
+
+	  if (c == '%' || c == '#')
+	    {
+	      skip_until_newline (is, false);
+	      break;
+	    }
+
+	  if (! is.eof ())
+	    {
+	      if (! have_data && c != ' ' && c != '\t')
+		have_data = true;
+
+	      retval += c;
+	    }
+	}
+    }
+  while (! (have_data || is.eof ()));
+
+  return retval;
+}
+
+static void
+get_lines_and_columns (std::istream& is, const std::string& filename, octave_idx_type& nr, octave_idx_type& nc)
+{
+  std::streampos pos = is.tellg ();
+
+  int file_line_number = 0;
+
+  nr = 0;
+  nc = 0;
+
+  while (is && ! error_state)
+    {
+      OCTAVE_QUIT;
+
+      std::string buf = get_mat_data_input_line (is);
+
+      file_line_number++;
+
+      size_t beg = buf.find_first_not_of (", \t");
+
+      // If we see a CR as the last character in the buffer, we had a
+      // CRLF pair as the line separator.  Any other CR in the text
+      // will not be considered as whitespace.
+
+      if (beg != std::string::npos && buf[beg] == '\r' && beg == buf.length () - 1)
+	{
+	  // We had a blank line ending with a CRLF.  Handle it the
+	  // same as an empty line.
+	  beg = std::string::npos;
+	}
+
+      octave_idx_type tmp_nc = 0;
+
+      while (beg != std::string::npos)
+	{
+	  tmp_nc++;
+
+	  size_t end = buf.find_first_of (", \t", beg);
+
+	  if (end != std::string::npos)
+	    {
+	      beg = buf.find_first_not_of (", \t", end);
+
+	      if (beg == std::string::npos || (buf[beg] == '\r' && 
+				  beg == buf.length () - 1))
+		{
+		  // We had a line with trailing spaces and
+		  // ending with a CRLF, so this should look like EOL,
+		  // not a new colum.
+		  break;
+		}
+	    }
+	  else
+	    break;
+	}
+
+      if (tmp_nc > 0)
+	{
+	  if (nc == 0)
+	    {
+	      nc = tmp_nc;
+	      nr++;
+	    }
+	  else if (nc == tmp_nc)
+	    nr++;
+	  else
+	    error ("load: %s: inconsistent number of columns near line %d",
+		   filename.c_str (), file_line_number);
+	}
+    }
+
+  if (nr == 0 || nc == 0)
+    error ("load: file `%s' seems to be empty!", filename.c_str ());
+
+  is.clear ();
+  is.seekg (pos);
+}
+
+// Extract a matrix from a file of numbers only.
+//
+// Comments are not allowed.  The file should only have numeric values.
+//
+// Reads the file twice.  Once to find the number of rows and columns,
+// and once to extract the matrix.
+//
+// FILENAME is used for error messages.
+//
+// This format provides no way to tag the data as global.
+
+std::string
+read_mat_ascii_data (std::istream& is, const std::string& filename,
+		     octave_value& tc)
+{
+  std::string retval;
+
+  std::string varname;
+
+  size_t pos = filename.rfind ('/');
+
+  if (pos != std::string::npos)
+    varname = filename.substr (pos+1);
+  else
+    varname = filename;
+
+  pos = varname.rfind ('.');
+
+  if (pos != std::string::npos)
+    varname = varname.substr (0, pos);
+
+  size_t len = varname.length ();
+  for (size_t i = 0; i < len; i++)
+    {
+      char c = varname[i];
+      if (! (isalnum (c) || c == '_'))
+	varname[i] = '_';
+    }
+
+  if (is_keyword (varname) || ! isalpha (varname[0]))
+    varname.insert (0, "X");
+
+  if (valid_identifier (varname))
+    {
+      octave_idx_type nr = 0;
+      octave_idx_type nc = 0;
+
+      int total_count = 0;
+
+      get_lines_and_columns (is, filename, nr, nc);
+
+      OCTAVE_QUIT;
+
+      if (! error_state && nr > 0 && nc > 0)
+	{
+	  Matrix tmp (nr, nc);
+
+	  if (nr < 1 || nc < 1)
+	    is.clear (std::ios::badbit);
+	  else
+	    {
+	      double d;
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  std::string buf = get_mat_data_input_line (is);
+
+		  std::istringstream tmp_stream (buf);
+
+		  for (octave_idx_type j = 0; j < nc; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      d = octave_read_double (tmp_stream);
+
+		      if (tmp_stream || tmp_stream.eof ())
+			{
+			  tmp.elem (i, j) = d;
+			  total_count++;
+
+			  // Skip whitespace and commas.
+			  char c;
+			  while (1)
+			    {
+			      tmp_stream >> c;
+
+			      if (! tmp_stream)
+				break;
+
+			      if (! (c == ' ' || c == '\t' || c == ','))
+				{
+				  tmp_stream.putback (c);
+				  break;
+				}
+			    }
+
+			  if (tmp_stream.eof ())
+			    break;
+			}
+		      else
+			{
+			  error ("load: failed to read matrix from file `%s'",
+				 filename.c_str ());
+
+			  return retval;
+			}
+
+		    }
+		}
+	    }
+
+	  if (is || is.eof ())
+	    {
+	      // FIXME -- not sure this is best, but it works.
+
+	      if (is.eof ())
+		is.clear ();
+
+	      octave_idx_type expected = nr * nc;
+
+	      if (expected == total_count)
+		{
+		  tc = tmp;
+		  retval = varname;
+		}
+	      else
+		error ("load: expected %d elements, found %d",
+		       expected, total_count);
+	    }
+	  else
+	    error ("load: failed to read matrix from file `%s'",
+		   filename.c_str ());
+	}
+      else
+	error ("load: unable to extract matrix size from file `%s'",
+	       filename.c_str ());
+    }
+  else
+    error ("load: unable to convert filename `%s' to valid identifier",
+	   filename.c_str ());
+
+  return retval;
+}
+
+bool
+save_mat_ascii_data (std::ostream& os, const octave_value& val,
+		     int precision, bool tabs)
+{
+  bool success = true;
+
+  if (val.is_complex_type ())
+    warning ("save: omitting imaginary part for ASCII file");
+
+  Matrix m = val.matrix_value (true);
+
+  if (error_state)
+    {
+      success = false;
+
+      error_state = 0;
+    }
+  else
+    {
+      long old_precision = os.precision ();
+
+      os.precision (precision);
+
+      std::ios::fmtflags oflags
+	= os.flags (static_cast<std::ios::fmtflags> (std::ios::scientific));
+
+      if (tabs)
+        {
+          for (octave_idx_type i = 0; i < m.rows (); i++)
+            {
+              for (octave_idx_type j = 0; j < m.cols (); j++)
+                {
+                  // Omit leading tabs.
+                  if (j != 0) os << '\t'; 
+                  octave_write_double (os, m (i, j));
+                }
+              os << "\n";
+            }
+        }
+      else
+        os << m;
+
+      os.flags (oflags);
+
+      os.precision (old_precision);
+    }
+
+  return (os && success);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-mat-ascii.h b/src/ls-mat-ascii.h
new file mode 100644
index 0000000..d00b522
--- /dev/null
+++ b/src/ls-mat-ascii.h
@@ -0,0 +1,41 @@
+/*
+
+Copyright (C) 2003, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_mat_ascii_h)
+#define octave_ls_mat_ascii_h 1
+
+extern std::string
+read_mat_ascii_data (std::istream& is, const std::string& filename,
+		     octave_value& tc);
+
+extern bool
+save_mat_ascii_data (std::ostream& os, const octave_value& val_arg,
+		     int precision, bool tabs = false);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-mat4.cc b/src/ls-mat4.cc
new file mode 100644
index 0000000..6352311
--- /dev/null
+++ b/src/ls-mat4.cc
@@ -0,0 +1,617 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "sysdep.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+#include "dSparse.h"
+
+#include "ls-mat4.h"
+
+// Read LEN elements of data from IS in the format specified by
+// PRECISION, placing the result in DATA.  If SWAP is TRUE, swap
+// the bytes of each element before copying to DATA.  FLT_FMT
+// specifies the format of the data if we are reading floating point
+// numbers.
+
+static void
+read_mat_binary_data (std::istream& is, double *data, int precision,
+		      int len, bool swap,
+		      oct_mach_info::float_format flt_fmt)
+{
+  switch (precision)
+    {
+    case 0:
+      read_doubles (is, data, LS_DOUBLE, len, swap, flt_fmt);
+      break;
+
+    case 1:
+      read_doubles (is, data, LS_FLOAT, len, swap, flt_fmt);
+      break;
+
+    case 2:
+      read_doubles (is, data, LS_INT, len, swap, flt_fmt);
+      break;
+
+    case 3:
+      read_doubles (is, data, LS_SHORT, len, swap, flt_fmt);
+      break;
+
+    case 4:
+      read_doubles (is, data, LS_U_SHORT, len, swap, flt_fmt);
+      break;
+
+    case 5:
+      read_doubles (is, data, LS_U_CHAR, len, swap, flt_fmt);
+      break;
+
+    default:
+      break;
+    }
+}
+
+int
+read_mat_file_header (std::istream& is, bool& swap, int32_t& mopt, 
+		      int32_t& nr, int32_t& nc,
+		      int32_t& imag, int32_t& len,
+		      int quiet)
+{
+  swap = false;
+
+  // We expect to fail here, at the beginning of a record, so not
+  // being able to read another mopt value should not result in an
+  // error.
+
+  is.read (reinterpret_cast<char *> (&mopt), 4);
+  if (! is)
+    return 1;
+
+  if (! is.read (reinterpret_cast<char *> (&nr), 4))
+    goto data_read_error;
+
+  if (! is.read (reinterpret_cast<char *> (&nc), 4))
+    goto data_read_error;
+
+  if (! is.read (reinterpret_cast<char *> (&imag), 4))
+    goto data_read_error;
+
+  if (! is.read (reinterpret_cast<char *> (&len), 4))
+    goto data_read_error;
+
+// If mopt is nonzero and the byte order is swapped, mopt will be
+// bigger than we expect, so we swap bytes.
+//
+// If mopt is zero, it means the file was written on a little endian
+// machine, and we only need to swap if we are running on a big endian
+// machine.
+//
+// Gag me.
+
+  if (oct_mach_info::words_big_endian () && mopt == 0)
+    swap = true;
+
+  // mopt is signed, therefore byte swap may result in negative value.
+
+  if (mopt > 9999 || mopt < 0)
+    swap = true;
+
+  if (swap)
+    {
+      swap_bytes<4> (&mopt);
+      swap_bytes<4> (&nr);
+      swap_bytes<4> (&nc);
+      swap_bytes<4> (&imag);
+      swap_bytes<4> (&len);
+    }
+
+  if (mopt > 9999 || mopt < 0 || imag > 1 || imag < 0)
+    {
+      if (! quiet)
+	error ("load: can't read binary file");
+      return -1;
+    }
+
+  return 0;
+
+ data_read_error:
+  return -1;
+}
+
+// We don't just use a cast here, because we need to be able to detect
+// possible errors.
+
+oct_mach_info::float_format
+mopt_digit_to_float_format (int mach)
+{
+  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
+
+  switch (mach)
+    {
+    case 0:
+      flt_fmt = oct_mach_info::flt_fmt_ieee_little_endian;
+      break;
+
+    case 1:
+      flt_fmt = oct_mach_info::flt_fmt_ieee_big_endian;
+      break;
+
+    case 2:
+      flt_fmt = oct_mach_info::flt_fmt_vax_d;
+      break;
+
+    case 3:
+      flt_fmt = oct_mach_info::flt_fmt_vax_g;
+      break;
+
+    case 4:
+      flt_fmt = oct_mach_info::flt_fmt_cray;
+      break;
+
+    default:
+      flt_fmt = oct_mach_info::flt_fmt_unknown;
+      break;
+    }
+
+  return flt_fmt;
+}
+
+int
+float_format_to_mopt_digit (oct_mach_info::float_format flt_fmt)
+{
+  int retval = -1;
+
+  switch (flt_fmt)
+    {
+    case oct_mach_info::flt_fmt_ieee_little_endian:
+      retval = 0;
+      break;
+
+    case oct_mach_info::flt_fmt_ieee_big_endian:
+      retval = 1;
+      break;
+
+    case oct_mach_info::flt_fmt_vax_d:
+      retval = 2;
+      break;
+
+    case oct_mach_info::flt_fmt_vax_g:
+      retval = 3;
+      break;
+
+    case oct_mach_info::flt_fmt_cray:
+      retval = 4;
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+// Extract one value (scalar, matrix, string, etc.) from stream IS and
+// place it in TC, returning the name of the variable.
+//
+// The data is expected to be in Matlab version 4 .mat format, though
+// not all the features of that format are supported.
+//
+// FILENAME is used for error messages.
+//
+// This format provides no way to tag the data as global.
+
+std::string
+read_mat_binary_data (std::istream& is, const std::string& filename,
+		      octave_value& tc)
+{
+  std::string retval;
+
+  // These are initialized here instead of closer to where they are
+  // first used to avoid errors from gcc about goto crossing
+  // initialization of variable.
+
+  Matrix re;
+  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
+  bool swap = false;
+  int type = 0;
+  int prec = 0;
+  int order = 0;
+  int mach = 0;
+  int dlen = 0;
+
+  int32_t mopt, nr, nc, imag, len;
+
+  int err = read_mat_file_header (is, swap, mopt, nr, nc, imag, len);
+  if (err)
+    {
+      if (err < 0)
+	goto data_read_error;
+      else
+	return retval;
+    }
+
+  type = mopt % 10;  // Full, sparse, etc.
+  mopt /= 10;        // Eliminate first digit.
+  prec = mopt % 10;  // double, float, int, etc.
+  mopt /= 10;        // Eliminate second digit.
+  order = mopt % 10; // Row or column major ordering.
+  mopt /= 10;        // Eliminate third digit.
+  mach = mopt % 10;  // IEEE, VAX, etc.
+
+  flt_fmt = mopt_digit_to_float_format (mach);
+
+  if (flt_fmt == oct_mach_info::flt_fmt_unknown)
+    {
+      error ("load: unrecognized binary format!");
+      return retval;
+    }
+
+  if (imag && type == 1)
+    {
+      error ("load: encountered complex matrix with string flag set!");
+      return retval;
+    }
+
+  // LEN includes the terminating character, and the file is also
+  // supposed to include it, but apparently not all files do.  Either
+  // way, I think this should work.
+
+  {
+    OCTAVE_LOCAL_BUFFER (char, name, len+1);
+    name[len] = '\0';
+    if (! is.read (name, len))
+      goto data_read_error;
+    retval = name;
+
+    dlen = nr * nc;
+    if (dlen < 0)
+      goto data_read_error;
+
+    if (order)
+      {
+	octave_idx_type tmp = nr;
+	nr = nc;
+	nc = tmp;
+      }
+
+    if (type == 2)
+      {
+	if (nc == 4)
+	  {
+	    octave_idx_type nr_new, nc_new;
+	    Array<Complex> data (dim_vector (1, nr - 1));
+	    Array<octave_idx_type> c (dim_vector (1, nr - 1));
+	    Array<octave_idx_type> r (dim_vector (1, nr - 1));
+	    OCTAVE_LOCAL_BUFFER (double, dtmp, nr);
+	    OCTAVE_LOCAL_BUFFER (double, ctmp, nr);
+
+	    read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt);
+	    for (octave_idx_type i = 0; i < nr - 1; i++)
+	      r.xelem(i) = dtmp[i] - 1;
+	    nr_new = dtmp[nr - 1];
+	    read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt);
+	    for (octave_idx_type i = 0; i < nr - 1; i++)
+	      c.xelem(i) = dtmp[i] - 1;
+	    nc_new = dtmp[nr - 1];
+	    read_mat_binary_data (is, dtmp, prec, nr - 1, swap, flt_fmt);
+	    read_mat_binary_data (is, ctmp, prec, 1, swap, flt_fmt);
+	    read_mat_binary_data (is, ctmp, prec, nr - 1, swap, flt_fmt);
+
+	    for (octave_idx_type i = 0; i < nr - 1; i++)
+	      data.xelem(i) = Complex (dtmp[i], ctmp[i]);
+	    read_mat_binary_data (is, ctmp, prec, 1, swap, flt_fmt);
+
+	    SparseComplexMatrix smc = SparseComplexMatrix (data, r, c, 
+							   nr_new, nc_new);
+
+	    tc = order ? smc.transpose () : smc;
+	  }
+	else
+	  {
+	    octave_idx_type nr_new, nc_new;
+	    Array<double> data (dim_vector (1, nr - 1));
+	    Array<octave_idx_type> c (dim_vector (1, nr - 1));
+	    Array<octave_idx_type> r (dim_vector (1, nr - 1));
+	    OCTAVE_LOCAL_BUFFER (double, dtmp, nr);
+
+	    read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt);
+	    for (octave_idx_type i = 0; i < nr - 1; i++)
+	      r.xelem(i) = dtmp[i] - 1;
+	    nr_new = dtmp[nr - 1];
+	    read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt);
+	    for (octave_idx_type i = 0; i < nr - 1; i++)
+	      c.xelem(i) = dtmp[i] - 1;
+	    nc_new = dtmp[nr - 1];
+	    read_mat_binary_data (is, data.fortran_vec (), prec, nr - 1, swap, flt_fmt);
+	    read_mat_binary_data (is, dtmp, prec, 1, swap, flt_fmt);
+
+	    SparseMatrix sm = SparseMatrix (data, r, c, nr_new, nc_new);
+
+	    tc = order ? sm.transpose () : sm;
+	  }
+      }
+    else
+      {
+	re.resize (nr, nc);
+
+	read_mat_binary_data (is, re.fortran_vec (), prec, dlen, swap, flt_fmt);
+
+	if (! is || error_state)
+	  {
+	    error ("load: reading matrix data for `%s'", name);
+	    goto data_read_error;
+	  }
+
+	if (imag)
+	  {
+	    Matrix im (nr, nc);
+
+	    read_mat_binary_data (is, im.fortran_vec (), prec, dlen, swap,
+				  flt_fmt);
+
+	    if (! is || error_state)
+	      {
+		error ("load: reading imaginary matrix data for `%s'", name);
+		goto data_read_error;
+	      }
+
+	    ComplexMatrix ctmp (nr, nc);
+
+	    for (octave_idx_type j = 0; j < nc; j++)
+	      for (octave_idx_type i = 0; i < nr; i++)
+		ctmp (i, j) = Complex (re (i, j), im (i, j));
+
+	    tc = order ? ctmp.transpose () : ctmp;
+	  }
+	else
+	  tc = order ? re.transpose () : re;
+
+	if (type == 1)
+	  tc = tc.convert_to_str (false, true, '\'');
+      }
+
+      return retval;
+    }
+
+ data_read_error:
+  error ("load: trouble reading binary file `%s'", filename.c_str ());
+  return retval;
+}
+
+// Save the data from TC along with the corresponding NAME on stream OS 
+// in the MatLab version 4 binary format.
+
+bool
+save_mat_binary_data (std::ostream& os, const octave_value& tc,
+		      const std::string& name) 
+{
+  int32_t mopt = 0;
+
+  mopt += tc.is_sparse_type () ? 2 : tc.is_string () ? 1 : 0;
+
+  oct_mach_info::float_format flt_fmt =
+    oct_mach_info::native_float_format ();;
+
+  mopt += 1000 * float_format_to_mopt_digit (flt_fmt);
+
+  os.write (reinterpret_cast<char *> (&mopt), 4);
+  
+  octave_idx_type len;
+  int32_t nr = tc.rows ();
+
+  int32_t nc = tc.columns ();
+
+  if (tc.is_sparse_type ())
+    {
+      len = tc.nnz ();
+      uint32_t nnz = len + 1;
+      os.write (reinterpret_cast<char *> (&nnz), 4);
+
+      uint32_t iscmplx = tc.is_complex_type () ? 4 : 3;
+      os.write (reinterpret_cast<char *> (&iscmplx), 4);
+
+      uint32_t tmp = 0;
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+  else
+    {
+      os.write (reinterpret_cast<char *> (&nr), 4);
+      os.write (reinterpret_cast<char *> (&nc), 4);
+
+      int32_t imag = tc.is_complex_type () ? 1 : 0;
+      os.write (reinterpret_cast<char *> (&imag), 4);
+
+      len = nr * nc;
+    }
+
+
+  // LEN includes the terminating character, and the file is also
+  // supposed to include it.
+
+  int32_t name_len = name.length () + 1;
+
+  os.write (reinterpret_cast<char *> (&name_len), 4);
+  os << name << '\0';
+
+  if (tc.is_string ())
+    {
+      unwind_protect::begin_frame ("save_mat_binary_data");
+
+      charMatrix chm = tc.char_matrix_value ();
+
+      octave_idx_type nrow = chm.rows ();
+      octave_idx_type ncol = chm.cols ();
+	
+      OCTAVE_LOCAL_BUFFER (double, buf, ncol*nrow);
+	
+      for (octave_idx_type i = 0; i < nrow; i++)
+      	{
+	  std::string tstr = chm.row_as_string (i);
+	  const char *s = tstr.data ();
+	  
+	  for (octave_idx_type j = 0; j < ncol; j++)
+	    buf[j*nrow+i] = static_cast<double> (*s++ & 0x00FF);
+       	}
+      os.write (reinterpret_cast<char *> (buf), nrow*ncol*sizeof(double));
+      
+      unwind_protect::run_frame ("save_mat_binary_data");
+    }
+  else if (tc.is_range ())
+    {
+      Range r = tc.range_value ();
+      double base = r.base ();
+      double inc = r.inc ();
+      octave_idx_type nel = r.nelem ();
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  double x = base + i * inc;
+	  os.write (reinterpret_cast<char *> (&x), 8);
+	}
+    }
+  else if (tc.is_real_scalar ())
+    {
+      double tmp = tc.double_value ();
+      os.write (reinterpret_cast<char *> (&tmp), 8);
+    }
+  else if (tc.is_sparse_type ())
+    {
+      double ds;
+      OCTAVE_LOCAL_BUFFER (double, dtmp, len);
+      if (tc.is_complex_matrix ())
+	{
+	  SparseComplexMatrix m = tc.sparse_complex_matrix_value ();
+
+	  for (octave_idx_type i = 0; i < len; i++)
+	    dtmp [i] = m.ridx(i) + 1;
+	  os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+	  ds = nr;
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+
+	  octave_idx_type ii = 0;
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	      dtmp[ii++] = j + 1;
+	  os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+	  ds = nc;
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+
+	  for (octave_idx_type i = 0; i < len; i++)
+	    dtmp [i] = std::real (m.data(i));
+	  os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+	  ds = 0.;
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+
+	  for (octave_idx_type i = 0; i < len; i++)
+	    dtmp [i] = std::imag (m.data(i));
+	  os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+	}
+      else
+	{
+	  SparseMatrix m = tc.sparse_matrix_value ();
+
+	  for (octave_idx_type i = 0; i < len; i++)
+	    dtmp [i] = m.ridx(i) + 1;
+	  os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+	  ds = nr;
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+
+	  octave_idx_type ii = 0;
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++)
+	      dtmp[ii++] = j + 1;
+	  os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+	  ds = nc;
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+
+	  os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+	  ds = 0.;
+	  os.write (reinterpret_cast<const char *> (&ds), 8);
+	}
+    }
+  else if (tc.is_real_matrix ())
+    {
+      Matrix m = tc.matrix_value ();
+      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+    }
+  else if (tc.is_complex_scalar ())
+    {
+      Complex tmp = tc.complex_value ();
+      os.write (reinterpret_cast<char *> (&tmp), 16);
+    }
+  else if (tc.is_complex_matrix ())
+    {
+      ComplexMatrix m_cmplx = tc.complex_matrix_value ();
+      Matrix m = ::real (m_cmplx);
+      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      m = ::imag (m_cmplx);
+      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+    }
+  else
+    gripe_wrong_type_arg ("save", tc, false);
+
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-mat4.h b/src/ls-mat4.h
new file mode 100644
index 0000000..0d2b7b8
--- /dev/null
+++ b/src/ls-mat4.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2003, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_mat4_h)
+#define octave_ls_mat4_h 1
+
+extern oct_mach_info::float_format
+mopt_digit_to_float_format (int mach);
+
+extern int
+float_format_to_mopt_digit (oct_mach_info::float_format flt_fmt);
+
+extern int
+read_mat_file_header (std::istream& is, bool& swap, int32_t& mopt, 
+		      int32_t& nr, int32_t& nc, int32_t& imag,
+		      int32_t& len, int quiet = 0);
+
+extern std::string
+read_mat_binary_data (std::istream& is, const std::string& filename,
+		      octave_value& tc);
+
+extern bool
+save_mat_binary_data (std::ostream& os, const octave_value& tc,
+		      const std::string& name) ;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-mat5.cc b/src/ls-mat5.cc
new file mode 100644
index 0000000..0ad608f
--- /dev/null
+++ b/src/ls-mat5.cc
@@ -0,0 +1,2268 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: James R. Van Zandt <jrv at vanzandt.mv.com>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+#include "file-stat.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "load-path.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "ov-class.h"
+#include "ov-fcn-inline.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+#include "ls-utils.h"
+#include "ls-mat5.h"
+
+#include "parse.h"
+#include "defaults.h"
+
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif
+
+#define PAD(l) (((l) > 0 && (l) <= 4) ? 4 : (((l)+7)/8)*8)
+
+
+// The subsystem data block
+static octave_value subsys_ov;
+
+// FIXME -- the following enum values should be the same as the
+// mxClassID values in mexproto.h, but it seems they have also changed
+// over time.  What is the correct way to handle this and maintain
+// backward compatibility with old MAT files?  For now, use
+// "MAT_FILE_" instead of "mx" as the prefix for these names to avoid
+// conflict with the mxClassID enum in mexproto.h.
+
+enum arrayclasstype
+  {
+    MAT_FILE_CELL_CLASS=1,		// cell array
+    MAT_FILE_STRUCT_CLASS,		// structure
+    MAT_FILE_OBJECT_CLASS,		// object
+    MAT_FILE_CHAR_CLASS,		// character array
+    MAT_FILE_SPARSE_CLASS,		// sparse array
+    MAT_FILE_DOUBLE_CLASS,		// double precision array
+    MAT_FILE_SINGLE_CLASS,		// single precision floating point
+    MAT_FILE_INT8_CLASS,		// 8 bit signed integer
+    MAT_FILE_UINT8_CLASS,		// 8 bit unsigned integer
+    MAT_FILE_INT16_CLASS,		// 16 bit signed integer
+    MAT_FILE_UINT16_CLASS,		// 16 bit unsigned integer
+    MAT_FILE_INT32_CLASS,		// 32 bit signed integer
+    MAT_FILE_UINT32_CLASS,		// 32 bit unsigned integer
+    MAT_FILE_INT64_CLASS,		// 64 bit signed integer
+    MAT_FILE_UINT64_CLASS,		// 64 bit unsigned integer
+    MAT_FILE_FUNCTION_CLASS,            // Function handle
+    MAT_FILE_WORKSPACE_CLASS		// Workspace (undocumented)
+  };
+
+// Read COUNT elements of data from IS in the format specified by TYPE,
+// placing the result in DATA.  If SWAP is TRUE, swap the bytes of
+// each element before copying to DATA.  FLT_FMT specifies the format
+// of the data if we are reading floating point numbers.
+
+static void
+read_mat5_binary_data (std::istream& is, double *data,
+		       int count, bool swap, mat5_data_type type,
+		       oct_mach_info::float_format flt_fmt)
+{
+  
+  switch (type)
+    {
+    case miINT8:
+      read_doubles (is, data, LS_CHAR, count, swap, flt_fmt);
+      break;
+
+    case miUTF8:
+    case miUINT8:
+      read_doubles (is, data, LS_U_CHAR, count, swap, flt_fmt);
+      break;
+
+    case miINT16:
+      read_doubles (is, data, LS_SHORT, count, swap, flt_fmt);
+      break;
+
+    case miUTF16:
+    case miUINT16:
+      read_doubles (is, data, LS_U_SHORT, count, swap, flt_fmt);
+      break;
+
+    case miINT32:
+      read_doubles (is, data, LS_INT, count, swap, flt_fmt);
+      break;
+
+    case miUTF32:
+    case miUINT32:
+      read_doubles (is, data, LS_U_INT, count, swap, flt_fmt);
+      break;
+
+    case miSINGLE:
+      read_doubles (is, data, LS_FLOAT, count, swap, flt_fmt);
+      break;
+
+    case miRESERVE1:
+      break;
+
+    case miDOUBLE:
+      read_doubles (is, data, LS_DOUBLE, count, swap, flt_fmt);
+      break;
+
+    case miRESERVE2:
+    case miRESERVE3:
+      break;
+
+    // FIXME -- how are the 64-bit cases supposed to work here?
+    case miINT64:
+      read_doubles (is, data, LS_LONG, count, swap, flt_fmt);
+      break;
+
+    case miUINT64:
+      read_doubles (is, data, LS_U_LONG, count, swap, flt_fmt);
+      break;
+
+    case miMATRIX:
+    default:
+      break;
+    }
+}
+
+template <class T>
+void
+read_mat5_integer_data (std::istream& is, T *m, int count, bool swap,
+			mat5_data_type type)
+{
+
+#define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream)	\
+  do \
+    { \
+      if (len > 0) \
+	{ \
+	  OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
+	  stream.read (reinterpret_cast<char *> (ptr), size * len); \
+	  if (swap) \
+	    swap_bytes< size > (ptr, len); \
+	  for (int i = 0; i < len; i++) \
+	    data[i] = ptr[i]; \
+	} \
+    } \
+  while (0)
+
+  switch (type)
+    {
+    case miINT8:
+      READ_INTEGER_DATA (int8_t, swap, m, 1, count, is);
+      break;
+
+    case miUINT8:
+      READ_INTEGER_DATA (uint8_t, swap, m, 1, count, is);
+      break;
+
+    case miINT16:
+      READ_INTEGER_DATA (int16_t, swap, m, 2, count, is);
+      break;
+
+    case miUINT16:
+      READ_INTEGER_DATA (uint16_t, swap, m, 2, count, is);
+      break;
+
+    case miINT32:
+      READ_INTEGER_DATA (int32_t, swap, m, 4, count, is);
+      break;
+
+    case miUINT32:
+      READ_INTEGER_DATA (uint32_t, swap, m, 4, count, is);
+      break;
+
+    case miSINGLE:
+    case miRESERVE1:
+    case miDOUBLE:
+    case miRESERVE2:
+    case miRESERVE3:
+      break;
+
+    case miINT64:
+      READ_INTEGER_DATA (int64_t, swap, m, 8, count, is);
+      break;
+
+    case miUINT64:
+      READ_INTEGER_DATA (uint64_t, swap, m, 8, count, is);
+      break;
+
+    case miMATRIX:
+    default:
+      break;
+    }
+
+#undef READ_INTEGER_DATA
+
+}
+
+template void read_mat5_integer_data (std::istream& is, octave_int8 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_int16 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_int32 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_int64 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_uint8 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_uint16 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_uint32 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+template void read_mat5_integer_data (std::istream& is, octave_uint64 *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+
+template void read_mat5_integer_data (std::istream& is, int *m,
+				      int count, bool swap,
+				      mat5_data_type type);
+
+#define OCTAVE_MAT5_INTEGER_READ(TYP) \
+  { \
+	TYP re (dims); \
+  \
+	std::streampos tmp_pos; \
+  \
+	if (read_mat5_tag (is, swap, type, len)) \
+	  { \
+	    error ("load: reading matrix data for `%s'", retval.c_str ()); \
+	    goto data_read_error; \
+	  } \
+  \
+	int n = re.length (); \
+	tmp_pos = is.tellg (); \
+	read_mat5_integer_data (is, re.fortran_vec (), n, swap,	\
+				static_cast<enum mat5_data_type> (type)); \
+  \
+	if (! is || error_state) \
+	  { \
+	    error ("load: reading matrix data for `%s'", retval.c_str ()); \
+	    goto data_read_error; \
+	  } \
+  \
+	is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len))); \
+  \
+	if (imag) \
+	  { \
+	    /* We don't handle imag integer types, convert to an array */ \
+	    NDArray im (dims); \
+  \
+	    if (read_mat5_tag (is, swap, type, len)) \
+	      { \
+		error ("load: reading matrix data for `%s'", \
+		       retval.c_str ()); \
+		goto data_read_error; \
+	      } \
+  \
+	    n = im.length (); \
+	    read_mat5_binary_data (is, im.fortran_vec (), n, swap, \
+				   static_cast<enum mat5_data_type> (type), flt_fmt); \
+  \
+	    if (! is || error_state) \
+	      { \
+		error ("load: reading imaginary matrix data for `%s'", \
+		       retval.c_str ()); \
+		goto data_read_error; \
+	      } \
+  \
+	    ComplexNDArray ctmp (dims); \
+  \
+	    for (int i = 0; i < n; i++) \
+	      ctmp(i) = Complex (re(i).double_value (), im(i)); \
+  \
+            tc = ctmp;  \
+	  } \
+	else \
+	  tc = re; \
+  }
+  
+// Read one element tag from stream IS, 
+// place the type code in TYPE and the byte count in BYTES
+// return nonzero on error
+static int
+read_mat5_tag (std::istream& is, bool swap, int32_t& type, int32_t& bytes)
+{
+  unsigned int upper;
+  int32_t temp;
+
+  if (! is.read (reinterpret_cast<char *> (&temp), 4 ))
+    goto data_read_error;
+
+  if (swap)
+    swap_bytes<4> (&temp);
+
+  upper = (temp >> 16) & 0xffff;
+  type = temp & 0xffff;
+
+  if (upper)
+    {
+      // "compressed" format
+      bytes = upper;
+    }
+  else
+    {
+      if (! is.read (reinterpret_cast<char *> (&temp), 4 ))
+	goto data_read_error;
+      if (swap)
+	swap_bytes<4> (&temp);
+      bytes = temp;
+    }
+
+  return 0;
+
+ data_read_error:
+  return 1;
+}
+
+static void
+read_int (std::istream& is, bool swap, int32_t& val)
+{
+  is.read (reinterpret_cast<char *> (&val), 4);
+
+  if (swap)
+    swap_bytes<4> (&val);
+}
+
+// Extract one data element (scalar, matrix, string, etc.) from stream
+// IS and place it in TC, returning the name of the variable.
+//
+// The data is expected to be in Matlab's "Version 5" .mat format,
+// though not all the features of that format are supported.
+//
+// FILENAME is used for error messages.
+
+std::string
+read_mat5_binary_element (std::istream& is, const std::string& filename,
+			  bool swap, bool& global, octave_value& tc)
+{
+  std::string retval;
+
+  // These are initialized here instead of closer to where they are
+  // first used to avoid errors from gcc about goto crossing
+  // initialization of variable.
+
+  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
+  int32_t type = 0;
+  std::string classname;
+  bool isclass = false;
+  bool imag;
+  bool logicalvar;
+  enum arrayclasstype arrayclass;
+  int32_t nzmax;
+  int32_t flags;
+  dim_vector dims;
+  int32_t len;
+  int32_t element_length;
+  std::streampos pos;
+  int16_t number;
+  number = *(reinterpret_cast<const int16_t *>("\x00\x01"));
+
+  global = false;
+
+  // MAT files always use IEEE floating point
+  if ((number == 1) ^ swap)
+    flt_fmt = oct_mach_info::flt_fmt_ieee_big_endian;
+  else
+    flt_fmt = oct_mach_info::flt_fmt_ieee_little_endian;
+
+  // element type and length
+  if (read_mat5_tag (is, swap, type, element_length))
+    return retval;			// EOF
+
+#ifdef HAVE_ZLIB
+  if (type == miCOMPRESSED)
+    {
+      // If C++ allowed us direct access to the file descriptor of an ifstream 
+      // in a uniform way, the code below could be vastly simplified, and 
+      // additional copies of the data in memory wouldn't be needed!!
+
+      OCTAVE_LOCAL_BUFFER (char, inbuf, element_length);
+      is.read (inbuf, element_length);
+
+      // We uncompress the first 8 bytes of the header to get the buffer length
+      // This will fail with an error Z_MEM_ERROR
+      uLongf destLen = 8;
+      OCTAVE_LOCAL_BUFFER (unsigned int, tmp, 2);
+      if (uncompress (reinterpret_cast<Bytef *> (tmp), &destLen, 
+		      reinterpret_cast<Bytef *> (inbuf), element_length)
+	  !=  Z_MEM_ERROR)
+	{
+	  // Why should I have to initialize outbuf as I'll just overwrite!!
+	  if (swap)
+	    swap_bytes<4> (tmp, 2);
+
+	  destLen = tmp[1] + 8;
+	  std::string outbuf (destLen, ' '); 
+
+	  // FIXME -- find a way to avoid casting away const here!
+
+	  int err = uncompress (reinterpret_cast<Bytef *> (const_cast<char *> (outbuf.c_str ())), &destLen, 
+				reinterpret_cast<Bytef *> (inbuf), element_length);
+
+	  if (err != Z_OK)
+	    error ("load: error uncompressing data element");
+	  else
+	    {
+	      std::istringstream gz_is (outbuf);
+	      retval = read_mat5_binary_element (gz_is, filename, 
+						 swap, global, tc);
+	    }
+	}
+      else
+	error ("load: error probing size of compressed data element");
+
+      return retval;
+    }
+#endif
+
+  if (type != miMATRIX)
+    {
+      pos = is.tellg ();
+      error ("load: invalid element type = %d", type);
+      goto early_read_error;
+    }
+
+  if (element_length == 0)
+    {
+      tc = Matrix ();
+      return retval;
+    }
+
+  pos = is.tellg ();
+
+  // array flags subelement
+  if (read_mat5_tag (is, swap, type, len) || type != miUINT32 || len != 8)
+    {
+      error ("load: invalid array flags subelement");
+      goto early_read_error;
+    }
+
+  read_int (is, swap, flags);
+  imag = (flags & 0x0800) != 0;	// has an imaginary part?
+  global = (flags & 0x0400) != 0; // global variable?
+  logicalvar = (flags & 0x0200) != 0; // boolean ?
+  arrayclass = static_cast<arrayclasstype> (flags & 0xff);
+  read_int (is, swap, nzmax);	// max number of non-zero in sparse
+  
+  // dimensions array subelement
+  if (arrayclass != MAT_FILE_WORKSPACE_CLASS)
+    {
+      int32_t dim_len;
+
+      if (read_mat5_tag (is, swap, type, dim_len) || type != miINT32)
+	{
+	  error ("load: invalid dimensions array subelement");
+	  goto early_read_error;
+	}
+
+      int ndims = dim_len / 4;
+      dims.resize (ndims);
+      for (int i = 0; i < ndims; i++)
+	{
+	  int32_t n;
+	  read_int (is, swap, n);
+	  dims(i) = n;
+	}
+
+      std::streampos tmp_pos = is.tellg ();
+      is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (dim_len) - dim_len));
+    }
+  else
+    {
+      // Why did mathworks decide to not have dims for a workspace!!!
+      dims.resize(2);
+      dims(0) = 1;
+      dims(1) = 1;
+    }
+
+  if (read_mat5_tag (is, swap, type, len) || type != miINT8)
+    {
+      error ("load: invalid array name subelement");
+      goto early_read_error;
+    }
+
+  {
+    OCTAVE_LOCAL_BUFFER (char, name, len+1);
+
+    // Structure field subelements have zero-length array name subelements.
+
+    std::streampos tmp_pos = is.tellg ();
+
+    if (len)
+      {
+	if (! is.read (name, len ))
+	  goto data_read_error;
+	
+	is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
+      }
+
+    name[len] = '\0';
+    retval = name;
+  }
+
+  switch (arrayclass)
+    {
+    case MAT_FILE_CELL_CLASS:
+      {
+	Cell cell_array (dims);
+
+	int n = cell_array.length ();
+
+	for (int i = 0; i < n; i++)
+	  {
+	    octave_value tc2;
+
+	    std::string nm
+	      = read_mat5_binary_element (is, filename, swap, global, tc2);
+
+	    if (! is || error_state)
+	      {
+		error ("load: reading cell data for `%s'", nm.c_str ());
+		goto data_read_error;
+	      }
+
+	    cell_array(i) = tc2;
+	  }
+
+	tc = cell_array;
+      }
+      break;
+
+    case MAT_FILE_SPARSE_CLASS:
+#if SIZEOF_INT != SIZEOF_OCTAVE_IDX_TYPE
+      warning ("load: sparse objects are not implemented");
+      goto skip_ahead;
+#else
+      {
+	int nr = dims(0);
+	int nc = dims(1);
+	SparseMatrix sm;
+	SparseComplexMatrix scm;
+	int *ridx;
+	int *cidx;
+	double *data;
+
+	// Setup return value
+	if (imag)
+	  {
+	    scm = SparseComplexMatrix (static_cast<octave_idx_type> (nr),
+				       static_cast<octave_idx_type> (nc),
+				       static_cast<octave_idx_type> (nzmax));
+	    ridx = scm.ridx ();
+	    cidx = scm.cidx ();
+	    data = 0;
+	  }
+	else
+	  {
+	    sm = SparseMatrix (static_cast<octave_idx_type> (nr),
+			       static_cast<octave_idx_type> (nc),
+			       static_cast<octave_idx_type> (nzmax));
+	    ridx = sm.ridx ();
+	    cidx = sm.cidx ();
+	    data = sm.data ();
+	  }
+
+	// row indices
+	std::streampos tmp_pos;
+	  
+	if (read_mat5_tag (is, swap, type, len))
+	  {
+	    error ("load: reading sparse row data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	tmp_pos = is.tellg ();
+
+	read_mat5_integer_data (is, ridx, nzmax, swap,
+				static_cast<enum mat5_data_type> (type));
+
+	if (! is || error_state)
+	  {
+	    error ("load: reading sparse row data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
+
+	// col indices
+	if (read_mat5_tag (is, swap, type, len))
+	  {
+	    error ("load: reading sparse column data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	tmp_pos = is.tellg ();
+
+	read_mat5_integer_data (is, cidx, nc + 1, swap,
+				static_cast<enum mat5_data_type> (type));
+
+	if (! is || error_state)
+	  {
+	    error ("load: reading sparse column data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
+
+	// real data subelement
+	if (read_mat5_tag (is, swap, type, len))
+	  {
+	    error ("load: reading sparse matrix data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	int32_t nnz = cidx[nc];
+	NDArray re;
+	if (imag)
+	  {
+	    re = NDArray (dim_vector (static_cast<int> (nnz)));
+	    data = re.fortran_vec ();
+	  }
+
+	tmp_pos = is.tellg ();
+	read_mat5_binary_data (is, data, nnz, swap,
+			       static_cast<enum mat5_data_type> (type), flt_fmt);
+
+	if (! is || error_state)
+	  {
+	    error ("load: reading sparse matrix data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
+
+	// imaginary data subelement
+	if (imag)
+	  {
+	    NDArray im (dim_vector (static_cast<int> (nnz)));
+	  
+	    if (read_mat5_tag (is, swap, type, len))
+	      {
+		error ("load: reading sparse matrix data for `%s'", retval.c_str ());
+		goto data_read_error;
+	      }
+
+	    read_mat5_binary_data (is, im.fortran_vec (), nnz, swap,
+				   static_cast<enum mat5_data_type> (type), flt_fmt);
+
+	    if (! is || error_state)
+	      {
+		error ("load: reading imaginary sparse matrix data for `%s'",
+		       retval.c_str ());
+		goto data_read_error;
+	      }
+
+	    for (int i = 0; i < nnz; i++)
+	      scm.xdata (i) = Complex (re (i), im (i));
+
+	    tc = scm;
+	  }
+	else
+	  tc = sm;
+      }
+#endif
+      break;
+
+    case MAT_FILE_FUNCTION_CLASS:
+      {
+	octave_value tc2;
+	std::string nm
+	  = read_mat5_binary_element (is, filename, swap, global, tc2);
+
+	if (! is || error_state)
+	  goto data_read_error;
+
+	// Octave can handle both "/" and "\" as a directry seperator
+	// and so can ignore the seperator field of m0. I think the
+	// sentinel field is also save to ignore.
+	Octave_map m0 = tc2.map_value();
+	Octave_map m1 = m0.contents("function_handle")(0).map_value();
+	std::string ftype = m1.contents("type")(0).string_value();
+	std::string fname = m1.contents("function")(0).string_value();
+	std::string fpath = m1.contents("file")(0).string_value();
+
+	if (ftype == "simple" || ftype == "scopedfunction")
+	  {
+	    if (fpath.length() == 0)
+	      // We have a builtin function
+	      tc = make_fcn_handle (fname);
+	    else
+	      {
+		std::string mroot = 
+		  m0.contents("matlabroot")(0).string_value();
+
+		if ((fpath.length () >= mroot.length ()) &&
+		    fpath.substr(0, mroot.length()) == mroot &&
+		    OCTAVE_EXEC_PREFIX != mroot)
+		  {
+		    // If fpath starts with matlabroot, and matlabroot
+		    // doesn't equal octave_config_info ("exec_prefix")
+		    // then the function points to a version of Octave
+		    // or Matlab other than the running version. In that
+		    // case we replace with the same function in the
+		    // running version of Octave?
+		    
+		    // First check if just replacing matlabroot is enough
+		    std::string str = OCTAVE_EXEC_PREFIX + 
+		      fpath.substr (mroot.length ());		    
+		    file_stat fs (str);
+
+		    if (fs.exists ())
+		      {
+			size_t xpos
+			  = str.find_last_of (file_ops::dir_sep_chars ());
+
+			std::string dir_name = str.substr (0, xpos);
+
+			octave_function *fcn
+			  = load_fcn_from_file (str, dir_name, "", fname);
+		    
+			if (fcn)
+			  {
+			    octave_value tmp (fcn);
+
+			    tc = octave_value (new octave_fcn_handle (tmp, fname));
+			  }
+		      }
+		    else
+		      {
+			// Next just search for it anywhere in the
+			// system path
+			string_vector names(3);
+			names(0) = fname + ".oct";
+			names(1) = fname + ".mex";
+			names(2) = fname + ".m";
+
+			dir_path p (load_path::system_path ());
+
+			str = octave_env::make_absolute 
+			  (p.find_first_of (names), octave_env::getcwd ());
+
+			size_t xpos
+			  = str.find_last_of (file_ops::dir_sep_chars ());
+
+			std::string dir_name = str.substr (0, xpos);
+
+			octave_function *fcn
+			  = load_fcn_from_file (str, dir_name, "", fname);
+
+			if (fcn)
+			  {
+			    octave_value tmp (fcn);
+
+			    tc = octave_value (new octave_fcn_handle (tmp, fname));
+			  }
+			else
+			  {
+			    warning ("load: can't find the file %s", 
+				     fpath.c_str());
+			    goto skip_ahead;
+			  }
+		      }
+		  }
+		else
+		  {
+		    size_t xpos
+		      = fpath.find_last_of (file_ops::dir_sep_chars ());
+
+		    std::string dir_name = fpath.substr (0, xpos);
+
+		    octave_function *fcn
+		      = load_fcn_from_file (fpath, dir_name, "", fname);
+
+		    if (fcn)
+		      {
+			octave_value tmp (fcn);
+
+			tc = octave_value (new octave_fcn_handle (tmp, fname));
+		      }
+		    else
+		      {
+			warning ("load: can't find the file %s", 
+				 fpath.c_str());
+			goto skip_ahead;
+		      }
+		  }
+	      }
+	  }
+	else if (ftype == "nested")
+	  {
+	    warning ("load: can't load nested function");
+	    goto skip_ahead;
+	  }
+	else if (ftype == "anonymous")
+	  {
+	    Octave_map m2 = m1.contents("workspace")(0).map_value();
+	    uint32NDArray MCOS = m2.contents("MCOS")(0).uint32_array_value();
+	    octave_idx_type off = static_cast<octave_idx_type>(MCOS(4).double_value ());
+	    m2 = subsys_ov.map_value();
+	    m2 = m2.contents("MCOS")(0).map_value();
+	    tc2 = m2.contents("MCOS")(0).cell_value()(1 + off).cell_value()(1);
+	    m2 = tc2.map_value();
+
+	    unwind_protect::begin_frame ("anon_mat5_load");
+
+	    // Set up temporary scope to use for evaluating the text
+	    // that defines the anonymous function.
+
+	    symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
+	    unwind_protect::add (symbol_table::erase_scope, &local_scope);
+
+	    symbol_table::set_scope (local_scope);
+
+	    octave_call_stack::push (local_scope, 0);
+	    unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+	    if (m2.nfields() > 0)
+	      {
+		octave_value tmp;
+      
+		for (Octave_map::iterator p0 = m2.begin() ; 
+		     p0 != m2.end(); p0++)
+		  {
+		    std::string key = m2.key(p0);
+		    octave_value val = m2.contents(p0)(0);
+
+		    symbol_table::varref (key, local_scope, 0) = val;
+                  }
+	      }
+	    
+	    int parse_status;
+	    octave_value anon_fcn_handle = 
+	      eval_string (fname.substr (4), true, parse_status);
+
+	    if (parse_status == 0)
+	      {
+		octave_fcn_handle *fh = 
+		  anon_fcn_handle.fcn_handle_value ();
+
+		if (fh)
+		  tc = new octave_fcn_handle (fh->fcn_val (), "@<anonymous>");
+		else
+		  {
+		    error ("load: failed to load anonymous function handle");
+		    goto skip_ahead;
+		  }
+	      }
+	    else
+	      {
+		error ("load: failed to load anonymous function handle");
+		goto skip_ahead;
+	      }
+
+	    unwind_protect::run_frame ("anon_mat5_load");
+	  }
+	else
+	  {
+	    error ("load: invalid function handle type");
+	    goto skip_ahead;
+	  }
+      }
+      break;
+
+    case MAT_FILE_WORKSPACE_CLASS:
+      {
+	Octave_map m (dim_vector (1, 1));
+	int n_fields = 2;
+	string_vector field (n_fields);
+
+	for (int i = 0; i < n_fields; i++)
+	  {
+	    int32_t fn_type;
+	    int32_t fn_len;
+	    if (read_mat5_tag (is, swap, fn_type, fn_len) || fn_type != miINT8)
+	      {
+		error ("load: invalid field name subelement");
+		goto data_read_error;
+	      }
+
+	    OCTAVE_LOCAL_BUFFER (char, elname, fn_len + 1);
+
+	    std::streampos tmp_pos = is.tellg ();
+
+	    if (fn_len)
+	      {
+		if (! is.read (elname, fn_len))
+		  goto data_read_error;
+
+		is.seekg (tmp_pos + 
+			  static_cast<std::streamoff> (PAD (fn_len)));
+	      }
+
+	    elname[fn_len] = '\0';
+
+	    field(i) = elname;
+	  }
+
+	std::vector<Cell> elt (n_fields);
+
+	for (octave_idx_type i = 0; i < n_fields; i++)
+	  elt[i] = Cell (dims);
+
+	octave_idx_type n = dims.numel ();
+
+	// fields subelements
+	for (octave_idx_type j = 0; j < n; j++)
+	  {
+	    for (octave_idx_type i = 0; i < n_fields; i++)
+	      {
+		if (field(i) == "MCOS")
+		  {
+		    octave_value fieldtc;
+		    read_mat5_binary_element (is, filename, swap, global,
+					      fieldtc); 
+		    if (! is || error_state)
+		      goto data_read_error;
+
+		    elt[i](j) = fieldtc;
+		  }
+		else
+		  elt[i](j) = octave_value ();
+	      }
+	  }
+
+	for (octave_idx_type i = 0; i < n_fields; i++)
+	  m.assign (field (i), elt[i]);
+	tc = m;
+      }
+      break;
+
+    case MAT_FILE_OBJECT_CLASS:
+      {
+	isclass = true;
+
+	if (read_mat5_tag (is, swap, type, len) || type != miINT8)
+	  {
+	    error ("load: invalid class name");
+	    goto skip_ahead;
+	  }
+
+	{
+	  OCTAVE_LOCAL_BUFFER (char, name, len+1);
+
+	  std::streampos tmp_pos = is.tellg ();
+
+	  if (len)
+	    {
+	      if (! is.read (name, len ))
+		goto data_read_error;
+	
+	      is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
+	    }
+
+	  name[len] = '\0';
+	  classname = name;
+	}
+      }
+      // Fall-through
+    case MAT_FILE_STRUCT_CLASS:
+      {
+	Octave_map m (dim_vector (1, 1));
+	int32_t fn_type;
+	int32_t fn_len;
+	int32_t field_name_length;
+
+	// field name length subelement -- actually the maximum length
+	// of a field name.  The Matlab docs promise this will always
+	// be 32.  We read and use the actual value, on the theory
+	// that eventually someone will recognize that's a waste of
+	// space.
+	if (read_mat5_tag (is, swap, fn_type, fn_len) || fn_type != miINT32)
+	  {
+	    error ("load: invalid field name length subelement");
+	    goto data_read_error;
+	  }
+
+	if (! is.read (reinterpret_cast<char *> (&field_name_length), fn_len ))
+	  goto data_read_error;
+
+	if (swap)
+	  swap_bytes<4> (&field_name_length);
+
+	// field name subelement.  The length of this subelement tells
+	// us how many fields there are.
+	if (read_mat5_tag (is, swap, fn_type, fn_len) || fn_type != miINT8)
+	  {
+	    error ("load: invalid field name subelement");
+	    goto data_read_error;
+	  }
+
+	octave_idx_type n_fields = fn_len/field_name_length;
+
+	if (n_fields > 0)
+	  {
+	    fn_len = PAD (fn_len);
+
+	    OCTAVE_LOCAL_BUFFER (char, elname, fn_len);
+
+	    if (! is.read (elname, fn_len))
+	      goto data_read_error;
+
+	    std::vector<Cell> elt (n_fields);
+
+	    for (octave_idx_type i = 0; i < n_fields; i++)
+	      elt[i] = Cell (dims);
+
+	    octave_idx_type n = dims.numel ();
+
+	    // fields subelements
+	    for (octave_idx_type j = 0; j < n; j++)
+	      {
+		for (octave_idx_type i = 0; i < n_fields; i++)
+		  {
+		    octave_value fieldtc;
+		    read_mat5_binary_element (is, filename, swap, global,
+					      fieldtc); 
+		    elt[i](j) = fieldtc;
+		  }
+	      }
+
+	    for (octave_idx_type i = 0; i < n_fields; i++)
+	      {
+		const char *key = elname + i*field_name_length;
+
+		m.assign (key, elt[i]);
+	      }
+	  }
+
+	if (isclass)
+	  {
+	    if (classname == "inline")
+	      {
+		// inline is not an object in Octave but rather an
+		// overload of a function handle. Special case.
+		tc =  
+		  new octave_fcn_inline (m.contents("expr")(0).string_value(),
+					 m.contents("args")(0).string_value());
+	      }
+	    else
+	      {
+		octave_class* cls = new octave_class (m, classname);
+		cls->reconstruct_exemplar ();
+
+		if (! cls->reconstruct_parents ())
+		  warning ("load: unable to reconstruct object inheritance");
+
+		tc = cls; 
+		if (load_path::find_method (classname, "loadobj") != 
+		    std::string())
+		  {
+		    octave_value_list tmp = feval ("loadobj", tc, 1);
+
+		    if (! error_state)
+		      tc = tmp(0);
+		    else
+		      goto data_read_error;
+		  }
+	      }
+	  }
+	else
+	  tc = m;
+      }
+      break;
+
+    case MAT_FILE_INT8_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (int8NDArray);
+      break;
+
+    case MAT_FILE_UINT8_CLASS:
+      {
+	OCTAVE_MAT5_INTEGER_READ (uint8NDArray);
+
+	// Logical variables can either be MAT_FILE_UINT8_CLASS or
+	// MAT_FILE_DOUBLE_CLASS, so check if we have a logical
+	// variable and convert it.
+
+	if (logicalvar)
+	  {
+	    uint8NDArray in = tc.uint8_array_value ();
+	    int nel = in.nelem ();
+	    boolNDArray out (dims);
+	    
+	    for (int i = 0; i < nel; i++)
+	      out (i) = in(i).bool_value ();
+
+	    tc = out;
+	  }
+      }
+      break;
+
+    case MAT_FILE_INT16_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (int16NDArray);
+      break;
+
+    case MAT_FILE_UINT16_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (uint16NDArray);
+      break;
+
+    case MAT_FILE_INT32_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (int32NDArray);
+      break;
+
+    case MAT_FILE_UINT32_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (uint32NDArray);
+      break;
+
+    case MAT_FILE_INT64_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (int64NDArray);
+      break;
+
+    case MAT_FILE_UINT64_CLASS:
+      OCTAVE_MAT5_INTEGER_READ (uint64NDArray);
+      break;
+
+    case MAT_FILE_CHAR_CLASS:
+      // handle as a numerical array to start with
+
+    case MAT_FILE_DOUBLE_CLASS:
+    case MAT_FILE_SINGLE_CLASS:
+    default:
+      {
+	NDArray re (dims);
+      
+	// real data subelement
+
+	std::streampos tmp_pos;
+	  
+	if (read_mat5_tag (is, swap, type, len))
+	  {
+	    error ("load: reading matrix data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	int n = re.length ();
+	tmp_pos = is.tellg ();
+	read_mat5_binary_data (is, re.fortran_vec (), n, swap,
+			       static_cast<enum mat5_data_type> (type), flt_fmt);
+
+	if (! is || error_state)
+	  {
+	    error ("load: reading matrix data for `%s'", retval.c_str ());
+	    goto data_read_error;
+	  }
+
+	is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
+
+	if (logicalvar)
+	  {
+	    // Logical variables can either be MAT_FILE_UINT8_CLASS or
+	    // MAT_FILE_DOUBLE_CLASS, so check if we have a logical
+	    // variable and convert it.
+
+	    boolNDArray out (dims);
+	    
+	    for (int i = 0; i < n; i++)
+	      out (i) = static_cast<bool> (re (i));
+
+	    tc = out;
+	  }
+	else if (imag)
+	  {
+	    // imaginary data subelement
+
+	    NDArray im (dims);
+	  
+	    if (read_mat5_tag (is, swap, type, len))
+	      {
+		error ("load: reading matrix data for `%s'", retval.c_str ());
+		goto data_read_error;
+	      }
+
+	    n = im.length ();
+	    read_mat5_binary_data (is, im.fortran_vec (), n, swap,
+				   static_cast<enum mat5_data_type> (type), flt_fmt);
+
+	    if (! is || error_state)
+	      {
+		error ("load: reading imaginary matrix data for `%s'",
+		       retval.c_str ());
+		goto data_read_error;
+	      }
+
+	    ComplexNDArray ctmp (dims);
+
+	    for (int i = 0; i < n; i++)
+	      ctmp(i) = Complex (re(i), im(i));
+
+	    tc = ctmp;
+	  }
+	else
+	  {
+	    if (arrayclass == MAT_FILE_CHAR_CLASS)
+	      {
+		if (type == miUTF16 || type == miUTF32)
+		  {
+		    bool found_big_char = false;
+		    for (int i = 0; i < n; i++)
+		      {
+			if (re(i) > 127) {
+			  re(i) = '?';
+			  found_big_char = true;
+			}
+		      }
+
+		    if (found_big_char)
+		      {
+			warning ("load: can not read non-ASCII portions of UTF characters.");
+			warning ("      Replacing unreadable characters with '?'.");
+		      }
+		  }
+		else if (type == miUTF8)
+		  {
+		    // Search for multi-byte encoded UTF8 characters and
+		    // replace with 0x3F for '?'... Give the user a warning
+
+		    bool utf8_multi_byte = false;
+		    for (int i = 0; i < n; i++)
+		      {
+			unsigned char a = static_cast<unsigned char> (re(i));
+			if (a > 0x7f)
+			  utf8_multi_byte = true;
+		      }
+		    
+		    if (utf8_multi_byte)
+		      {
+			warning ("load: can not read multi-byte encoded UTF8 characters.");
+			warning ("      Replacing unreadable characters with '?'.");
+			for (int i = 0; i < n; i++)
+			  {
+			    unsigned char a = static_cast<unsigned char> (re(i));
+			    if (a > 0x7f)
+			      re(i) = '?';
+			  }
+		      }
+		  }
+		tc = re;
+		tc = tc.convert_to_str (false, true, '\'');
+	      }
+	    else
+	      tc = re;
+	  }
+      }
+    }
+
+  is.seekg (pos + static_cast<std::streamoff> (element_length));
+
+  if (is.eof ())
+    is.clear ();
+
+  return retval;
+
+ data_read_error:
+ early_read_error:
+  error ("load: trouble reading binary file `%s'", filename.c_str ());
+  return std::string ();
+
+ skip_ahead:
+  warning ("skipping over `%s'", retval.c_str ());
+  is.seekg (pos + static_cast<std::streamoff> (element_length));
+  return read_mat5_binary_element (is, filename, swap, global, tc);
+}
+
+int
+read_mat5_binary_file_header (std::istream& is, bool& swap, bool quiet, 
+			      const std::string& filename)
+{
+  int16_t version=0, magic=0;
+  uint64_t subsys_offset;
+
+  is.seekg (116, std::ios::beg);
+  is.read (reinterpret_cast<char *> (&subsys_offset), 8);
+
+  is.seekg (124, std::ios::beg);
+  is.read (reinterpret_cast<char *> (&version), 2);
+  is.read (reinterpret_cast<char *> (&magic), 2);
+
+  if (magic == 0x4d49)
+    swap = 0;
+  else if (magic == 0x494d)
+    swap = 1;
+  else
+    {
+      if (! quiet)
+	error ("load: can't read binary file");
+      return -1;
+    }
+
+  if (! swap)			// version number is inverse swapped!
+    version = ((version >> 8) & 0xff) + ((version & 0xff) << 8);
+
+  if (version != 1 && !quiet)
+    warning ("load: found version %d binary MAT file, "
+	     "but only prepared for version 1", version);
+
+  if (swap)
+    swap_bytes<8> (&subsys_offset, 1);
+
+  if (subsys_offset != 0x2020202020202020ULL && subsys_offset != 0ULL)
+    {
+      // Read the subsystem data block
+      is.seekg (subsys_offset, std::ios::beg);
+
+      octave_value tc;
+      bool global;
+      read_mat5_binary_element (is, filename, swap, global, tc);
+
+      if (!is || error_state)
+	return -1;
+
+      if (tc.is_uint8_type ())
+	{
+	  const uint8NDArray itmp = tc.uint8_array_value();
+	  octave_idx_type ilen = itmp.nelem ();
+
+	  // Why should I have to initialize outbuf as just overwrite
+	  std::string outbuf (ilen - 7, ' ');
+
+	  // FIXME -- find a way to avoid casting away const here
+	  char *ctmp = const_cast<char *> (outbuf.c_str ());
+	  for (octave_idx_type j = 8; j < ilen; j++)
+	    ctmp[j-8] = itmp(j).char_value ();
+
+	  std::istringstream fh_ws (outbuf);
+
+	  read_mat5_binary_element (fh_ws, filename, swap, global, subsys_ov);
+
+	  if (error_state)
+	    return -1;
+	}
+      else
+	return -1;
+
+      // Reposition to just after the header
+      is.seekg (128, std::ios::beg);
+    }
+
+  return 0;
+}
+
+static int 
+write_mat5_tag (std::ostream& is, int type, int bytes)
+{
+  int32_t temp;
+
+  if (bytes > 0 && bytes <= 4)
+    temp = (bytes << 16) + type;
+  else
+    {
+      temp = type;
+      if (! is.write (reinterpret_cast<char *> (&temp), 4))
+	goto data_write_error;
+      temp = bytes;
+    }
+
+  if (! is.write (reinterpret_cast<char *> (&temp), 4))
+    goto data_write_error;
+
+  return 0;
+
+ data_write_error:
+  return 1;
+}
+
+// write out the numeric values in M to OS,
+// preceded by the appropriate tag.
+static void 
+write_mat5_array (std::ostream& os, const NDArray& m, bool save_as_floats)
+{
+  int nel = m.nelem ();
+  double max_val, min_val;
+  save_type st = LS_DOUBLE;
+  mat5_data_type mst;
+  int size;
+  unsigned len;
+  const double *data = m.data ();
+
+// Have to use copy here to avoid writing over data accessed via
+// Matrix::data().
+
+#define MAT5_DO_WRITE(TYPE, data, count, stream) \
+  do \
+    { \
+      OCTAVE_LOCAL_BUFFER (TYPE, ptr, count); \
+      for (int i = 0; i < count; i++) \
+        ptr[i] = static_cast<TYPE> (data[i]); \
+      stream.write (reinterpret_cast<char *> (ptr), count * sizeof (TYPE)); \
+    } \
+  while (0)
+
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+
+  if (m.all_integers (max_val, min_val))
+    st = get_save_type (max_val, min_val);
+
+  switch (st)
+    {
+    default:
+    case LS_DOUBLE:  mst = miDOUBLE; size = 8; break;
+    case LS_FLOAT:   mst = miSINGLE; size = 4; break;
+    case LS_U_CHAR:  mst = miUINT8;  size = 1; break;
+    case LS_U_SHORT: mst = miUINT16; size = 2; break;
+    case LS_U_INT:   mst = miUINT32; size = 4; break;
+    case LS_CHAR:    mst = miINT8;   size = 1; break;
+    case LS_SHORT:   mst = miINT16;  size = 2; break;
+    case LS_INT:     mst = miINT32;  size = 4; break;
+    }
+
+  len = nel*size;
+  write_mat5_tag (os, mst, len);
+
+  {
+    switch (st)
+      {
+      case LS_U_CHAR:
+	MAT5_DO_WRITE (uint8_t, data, nel, os);
+	break;
+	
+      case LS_U_SHORT:
+	MAT5_DO_WRITE (uint16_t, data, nel, os);
+	break;
+	
+      case LS_U_INT:
+	MAT5_DO_WRITE (uint32_t, data, nel, os);
+	break;
+	
+      case LS_U_LONG:
+	MAT5_DO_WRITE (uint64_t, data, nel, os);
+	break;
+
+      case LS_CHAR:
+	MAT5_DO_WRITE (int8_t, data, nel, os);
+	break;
+	
+      case LS_SHORT:
+	MAT5_DO_WRITE (int16_t, data, nel, os);
+	break;
+
+      case LS_INT:
+	MAT5_DO_WRITE (int32_t, data, nel, os);
+	break;
+
+      case LS_LONG:
+	MAT5_DO_WRITE (int64_t, data, nel, os);
+	break;
+
+      case LS_FLOAT:
+	MAT5_DO_WRITE (float, data, nel, os);
+	break;
+
+      case LS_DOUBLE: // No conversion necessary.
+	os.write (reinterpret_cast<const char *> (data), len);
+	break;
+
+      default:
+	(*current_liboctave_error_handler)
+	  ("unrecognized data format requested");
+	break;
+      }
+  }
+  if (PAD (len) > len)
+    {
+      static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
+      os.write (buf, PAD (len) - len);
+    }
+}
+
+template <class T>
+void 
+write_mat5_integer_data (std::ostream& os, const T *m, int size, int nel)
+{
+  mat5_data_type mst;
+  unsigned len;
+
+  switch (size)
+    {
+    case 1:
+      mst = miUINT8;
+      break;
+    case 2:
+      mst = miUINT16;
+      break;
+    case 4:
+      mst = miUINT32;
+      break;
+    case 8:
+      mst = miUINT64;
+      break;
+    case -1:
+      mst = miINT8;
+      size = - size;
+      break;
+    case -2:
+      mst = miINT16;
+      size = - size;
+      break;
+    case -4:
+      mst = miINT32;
+      size = - size;
+      break;
+    case -8:
+    default:
+      mst = miINT64;
+      size = - size;
+      break;
+    }
+
+  len = nel*size;
+  write_mat5_tag (os, mst, len);
+
+  os.write (reinterpret_cast<const char *> (m), len);
+
+  if (PAD (len) > len)
+    {
+      static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
+      os.write (buf, PAD (len) - len);
+    }
+}
+
+template void write_mat5_integer_data (std::ostream& os, const octave_int8 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_int16 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_int32 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_int64 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_uint8 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_uint16 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_uint32 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const octave_uint64 *m,
+				       int size, int nel);
+template void write_mat5_integer_data (std::ostream& os, const int *m, 
+				       int size, int nel);
+
+// Write out cell element values in the cell array to OS, preceded by
+// the appropriate tag.
+
+static bool 
+write_mat5_cell_array (std::ostream& os, const Cell& cell,
+		       bool mark_as_global, bool save_as_floats)
+{
+  int nel = cell.nelem ();
+
+  for (int i = 0; i < nel; i++)
+    {
+      octave_value ov = cell(i);
+
+      if (! save_mat5_binary_element (os, ov, "", mark_as_global,
+				      false, save_as_floats))
+	return false;
+    }
+
+  return true;
+}
+
+int
+save_mat5_array_length (const double* val, int nel, bool save_as_floats)
+{
+  if (nel > 0)
+    {
+      int size = 8;
+
+      if (save_as_floats)
+	{
+	  bool too_large_for_float = false;
+	  for (int i = 0; i < nel; i++)
+	    {
+	      double tmp = val [i];
+
+	      if (! (xisnan (tmp) || xisinf (tmp))
+		  && fabs (tmp) > FLT_MAX)
+		{
+		  too_large_for_float = true;
+		  break;
+		}
+	    }
+
+	  if (!too_large_for_float)
+	    size = 4;
+	}
+
+      // The code below is disabled since get_save_type currently doesn't
+      // deal with integer types. This will need to be activated if get_save_type
+      // is changed.
+
+      // double max_val = val[0];
+      // double min_val = val[0];
+      // bool all_integers =  true;
+      //
+      // for (int i = 0; i < nel; i++)
+      //   {
+      //     double val = val[i];
+      //
+      //     if (val > max_val)
+      //       max_val = val;
+      //
+      //     if (val < min_val)
+      //       min_val = val;
+      //
+      //     if (D_NINT (val) != val)
+      //       {
+      //         all_integers = false;
+      //         break;
+      //       }
+      //   }
+      //
+      // if (all_integers)
+      //   {
+      //     if (max_val < 256 && min_val > -1)
+      //       size = 1;
+      //     else if (max_val < 65536 && min_val > -1)
+      //       size = 2;
+      //     else if (max_val < 4294967295UL && min_val > -1)
+      //       size = 4;
+      //     else if (max_val < 128 && min_val >= -128)
+      //       size = 1;
+      //     else if (max_val < 32768 && min_val >= -32768)
+      //       size = 2;
+      //     else if (max_val <= 2147483647L && min_val >= -2147483647L)
+      //       size = 4;
+      //   }
+
+      return 8 + nel * size;
+    }
+  else
+    return 8;
+}
+
+int
+save_mat5_array_length (const Complex* val, int nel, bool save_as_floats)
+{
+  int ret;
+
+  OCTAVE_LOCAL_BUFFER (double, tmp, nel);
+
+  for (int i = 1; i < nel; i++)
+    tmp[i] = std::real (val[i]);
+
+  ret = save_mat5_array_length (tmp, nel, save_as_floats);
+
+  for (int i = 1; i < nel; i++)
+    tmp[i] = std::imag (val[i]);
+
+  ret += save_mat5_array_length (tmp, nel, save_as_floats);
+
+  return ret;
+}
+
+int
+save_mat5_element_length (const octave_value& tc, const std::string& name, 
+			  bool save_as_floats, bool mat7_format)
+{
+  int max_namelen = (mat7_format ? 63 : 31);
+  int len = name.length ();
+  std::string cname = tc.class_name ();
+  int ret = 32;
+
+  if (len > 4)
+    ret += PAD (len > max_namelen ? max_namelen : len);
+
+  ret += PAD (4 * tc.ndims ());
+  
+  if (tc.is_string ())
+    {
+      charNDArray chm = tc.char_array_value ();
+      ret += 8;
+      if (chm.nelem () > 2)
+	ret += PAD (2 * chm.nelem ());
+    }
+  else if (tc.is_sparse_type ())
+    {
+      if (tc.is_complex_type ())
+	{
+	  SparseComplexMatrix m = tc.sparse_complex_matrix_value ();
+	  int nc = m.cols ();
+	  int nnz = m.nzmax ();
+
+	  ret += 16 + PAD (nnz * sizeof (int)) + PAD ((nc + 1) * sizeof (int)) +
+	    save_mat5_array_length (m.data (), m.nelem (), save_as_floats);
+	}
+      else
+	{
+	  SparseMatrix m = tc.sparse_matrix_value ();
+	  int nc = m.cols ();
+	  int nnz = m.nzmax ();
+
+	  ret += 16 + PAD (nnz * sizeof (int)) + PAD ((nc + 1) * sizeof (int)) +
+	    save_mat5_array_length (m.data (), m.nelem (), save_as_floats);
+	}
+    }
+
+#define INT_LEN(nel, size) \
+  { \
+    ret += 8; \
+    int sz = nel * size; \
+    if (sz > 4) \
+      ret += PAD (sz);	\
+  }
+
+  else if (cname == "int8")
+    INT_LEN (tc.int8_array_value ().nelem (), 1)
+  else if (cname == "int16")
+    INT_LEN (tc.int16_array_value ().nelem (), 2)
+  else if (cname == "int32")
+    INT_LEN (tc.int32_array_value ().nelem (), 4)
+  else if (cname == "int64")
+    INT_LEN (tc.int64_array_value ().nelem (), 8)
+  else if (cname == "uint8")
+    INT_LEN (tc.uint8_array_value ().nelem (), 1)
+  else if (cname == "uint16")
+    INT_LEN (tc.uint16_array_value ().nelem (), 2)
+  else if (cname == "uint32")
+    INT_LEN (tc.uint32_array_value ().nelem (), 4)
+  else if (cname == "uint64")
+    INT_LEN (tc.uint64_array_value ().nelem (), 8)
+  else if (tc.is_bool_type ())
+    INT_LEN (tc.bool_array_value ().nelem (), 1)
+  else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ())
+    {
+      NDArray m = tc.array_value ();
+      ret += save_mat5_array_length (m.fortran_vec (), m.nelem (),
+				     save_as_floats);
+    }
+  else if (tc.is_cell ())
+    {
+      Cell cell = tc.cell_value ();
+      int nel = cell.nelem ();
+
+      for (int i = 0; i < nel; i++)
+	ret += 8 + 
+	  save_mat5_element_length (cell (i), "", save_as_floats, mat7_format);
+    }
+  else if (tc.is_complex_scalar () || tc.is_complex_matrix ()) 
+    {
+      ComplexNDArray m = tc.complex_array_value ();
+      ret += save_mat5_array_length (m.fortran_vec (), m.nelem (),
+				     save_as_floats);
+    }
+  else if (tc.is_map () || tc.is_inline_function () || tc.is_object ()) 
+    {
+      int fieldcnt = 0;
+      const Octave_map m = tc.map_value ();
+      int nel = m.numel ();
+
+      if (tc.is_inline_function ())
+	// length of "inline" is 6
+	ret += 8 + PAD (6 > max_namelen ? max_namelen : 6);
+      else if (tc.is_object ())
+	{
+	  int classlen = tc.class_name (). length ();
+
+	  ret += 8 + PAD (classlen > max_namelen ? max_namelen : classlen);
+	}
+
+      for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
+	fieldcnt++;
+
+      ret += 16 + fieldcnt * (max_namelen + 1);
+
+
+      for (int j = 0; j < nel; j++)
+	{
+
+	  for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
+	    {
+	      const Cell elts = m.contents (i);
+
+	      ret += 8 + save_mat5_element_length (elts(j), "", 
+					       save_as_floats, mat7_format);
+	    }
+	}
+    }
+  else
+    ret = -1;
+
+  return ret;
+}
+
+// save the data from TC along with the corresponding NAME on stream
+// OS in the MatLab version 5 binary format.  Return true on success.
+
+bool
+save_mat5_binary_element (std::ostream& os,
+			  const octave_value& tc, const std::string& name,
+			  bool mark_as_global, bool mat7_format,
+			  bool save_as_floats, bool compressing) 
+{
+  int32_t flags=0;
+  int32_t nnz=0;
+  std::streampos fixup, contin;
+  std::string cname = tc.class_name ();
+  int max_namelen = (mat7_format ? 63 : 31);
+
+#ifdef HAVE_ZLIB
+  if (mat7_format && !compressing)
+    {
+      bool ret = false;
+
+      std::ostringstream buf;
+
+      // The code seeks backwards in the stream to fix the header. Can't
+      // do this with zlib, so use a stringstream.
+      ret = save_mat5_binary_element (buf, tc, name, mark_as_global, true,
+				      save_as_floats, true);
+
+      if (ret)
+	{
+	  // destLen must be at least 0.1% larger than source buffer 
+	  // + 12 bytes. Reality is it must be larger again than that.
+	  std::string buf_str = buf.str ();
+	  uLongf srcLen = buf_str.length ();
+	  uLongf destLen = srcLen * 101 / 100 + 12; 
+	  OCTAVE_LOCAL_BUFFER (char, out_buf, destLen);
+
+	  if (compress (reinterpret_cast<Bytef *> (out_buf), &destLen, 
+			reinterpret_cast<const Bytef *> (buf_str.c_str ()), srcLen) == Z_OK)
+	    {
+	      write_mat5_tag (os, miCOMPRESSED, static_cast<int> (destLen)); 
+	      os.write (out_buf, destLen);
+	    }
+	  else
+	    {
+	      error ("save: error compressing data element");
+	      ret = false;
+	    }
+	}
+
+      return ret;
+    }
+#endif
+
+  // element type and length
+  fixup = os.tellp ();
+  write_mat5_tag (os, miMATRIX, save_mat5_element_length 
+		  (tc, name, save_as_floats, mat7_format));
+  
+  // array flags subelement
+  write_mat5_tag (os, miUINT32, 8);
+
+  if (tc.is_bool_type ())
+    flags |= 0x0200;
+
+  if (mark_as_global)
+    flags |= 0x0400;
+
+  if (tc.is_complex_scalar () || tc.is_complex_matrix ())
+    flags |= 0x0800;
+
+  if (tc.is_string ())
+    flags |= MAT_FILE_CHAR_CLASS;
+  else if (cname == "int8")
+    flags |= MAT_FILE_INT8_CLASS;
+  else if (cname == "int16")
+    flags |= MAT_FILE_INT16_CLASS;
+  else if (cname == "int32")
+    flags |= MAT_FILE_INT32_CLASS;
+  else if (cname == "int64")
+    flags |= MAT_FILE_INT64_CLASS;
+  else if (cname == "uint8" || tc.is_bool_type ())
+    flags |= MAT_FILE_UINT8_CLASS;
+  else if (cname == "uint16")
+    flags |= MAT_FILE_UINT16_CLASS;
+  else if (cname == "uint32")
+    flags |= MAT_FILE_UINT32_CLASS;
+  else if (cname == "uint64")
+    flags |= MAT_FILE_UINT64_CLASS;
+  else if (tc.is_sparse_type ())
+    {
+      flags |= MAT_FILE_SPARSE_CLASS;
+      if (tc.is_complex_type ())
+	{
+	  SparseComplexMatrix scm = tc.sparse_complex_matrix_value ();
+	  nnz = scm.nzmax ();
+	}
+      else
+	{
+	  SparseMatrix sm = tc.sparse_matrix_value ();
+	  nnz = sm.nzmax ();
+	}
+    }
+  else if (tc.is_real_scalar ())
+    flags |= MAT_FILE_DOUBLE_CLASS;
+  else if (tc.is_real_matrix () || tc.is_range ())
+    flags |= MAT_FILE_DOUBLE_CLASS;
+  else if (tc.is_complex_scalar ())
+    flags |= MAT_FILE_DOUBLE_CLASS;
+  else if (tc.is_complex_matrix ())
+    flags |= MAT_FILE_DOUBLE_CLASS;
+  else if (tc.is_map ()) 
+    flags |= MAT_FILE_STRUCT_CLASS;
+  else if (tc.is_cell ())
+    flags |= MAT_FILE_CELL_CLASS;
+  else if (tc.is_inline_function () || tc.is_object ())
+    flags |= MAT_FILE_OBJECT_CLASS;
+  else
+    {
+      gripe_wrong_type_arg ("save", tc, false);
+      goto error_cleanup;
+    }
+
+  os.write (reinterpret_cast<char *> (&flags), 4);
+  os.write (reinterpret_cast<char *> (&nnz), 4);
+
+  {
+    dim_vector dv = tc.dims ();
+    int nd = tc.ndims ();
+    int dim_len = 4*nd;
+
+    write_mat5_tag (os, miINT32, dim_len);
+
+    for (int i = 0; i < nd; i++)
+      {
+	int32_t n = dv(i);
+	os.write (reinterpret_cast<char *> (&n), 4);
+      }
+
+    if (PAD (dim_len) > dim_len)
+      {
+	static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
+	os.write (buf, PAD (dim_len) - dim_len);
+      }
+  }
+
+  // array name subelement
+  {
+    int namelen = name.length ();
+
+    if (namelen > max_namelen)
+      namelen = max_namelen; // only 31 or 63 char names permitted in mat file
+
+    int paddedlength = PAD (namelen);
+
+    write_mat5_tag (os, miINT8, namelen);
+    OCTAVE_LOCAL_BUFFER (char, paddedname, paddedlength);
+    memset (paddedname, 0, paddedlength);
+    strncpy (paddedname, name.c_str (), namelen);
+    os.write (paddedname, paddedlength);
+  }
+
+  // data element
+  if (tc.is_string ())
+    {
+      charNDArray chm = tc.char_array_value ();
+      int nel = chm.nelem ();
+      int len = nel*2;
+      int paddedlength = PAD (len);
+
+      OCTAVE_LOCAL_BUFFER (int16_t, buf, nel+3);
+      write_mat5_tag (os, miUINT16, len);
+
+      const char *s = chm.data ();
+
+      for (int i = 0; i < nel; i++)
+	buf[i] = *s++ & 0x00FF;
+
+      os.write (reinterpret_cast<char *> (buf), len);
+      
+      if (paddedlength > len)
+	{
+	  static char padbuf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
+	  os.write (padbuf, paddedlength - len);
+	}
+    }
+  else if (tc.is_sparse_type ())
+    {
+      if (tc.is_complex_type ())
+	{
+	  SparseComplexMatrix m = tc.sparse_complex_matrix_value ();
+	  int nc = m.cols ();
+
+	  int tmp = sizeof (int);
+
+	  write_mat5_integer_data (os, m.ridx (), -tmp, nnz);
+	  write_mat5_integer_data (os, m.cidx (), -tmp, nc + 1);
+
+	  NDArray buf (dim_vector (nnz, 1));
+
+	  for (int i = 0; i < nnz; i++)
+	    buf (i) = std::real (m.data (i));
+
+	  write_mat5_array (os, buf, save_as_floats);
+
+	  for (int i = 0; i < nnz; i++)
+	    buf (i) = std::imag (m.data (i));
+
+	  write_mat5_array (os, buf, save_as_floats);
+	}
+      else
+	{
+	  SparseMatrix m = tc.sparse_matrix_value ();
+	  int nc = m.cols ();
+
+	  int tmp = sizeof (int);
+
+	  write_mat5_integer_data (os, m.ridx (), -tmp, nnz);
+	  write_mat5_integer_data (os, m.cidx (), -tmp, nc + 1);
+
+	  // FIXME
+	  // Is there a way to easily do without this buffer
+	  NDArray buf (dim_vector (nnz, 1));
+
+	  for (int i = 0; i < nnz; i++)
+	    buf (i) = m.data (i);
+
+	  write_mat5_array (os, buf, save_as_floats);
+	}
+    }
+  else if (cname == "int8")
+    {
+      int8NDArray m = tc.int8_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), -1, m.nelem ());
+    }
+  else if (cname == "int16")
+    {
+      int16NDArray m = tc.int16_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), -2, m.nelem ());
+    }
+  else if (cname == "int32")
+    {
+      int32NDArray m = tc.int32_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), -4, m.nelem ());
+    }
+  else if (cname == "int64")
+    {
+      int64NDArray m = tc.int64_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), -8, m.nelem ());
+    }
+  else if (cname == "uint8")
+    {
+      uint8NDArray m = tc.uint8_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), 1, m.nelem ());
+    }
+  else if (cname == "uint16")
+    {
+      uint16NDArray m = tc.uint16_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), 2, m.nelem ());
+    }
+  else if (cname == "uint32")
+    {
+      uint32NDArray m = tc.uint32_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), 4, m.nelem ());
+    }
+  else if (cname == "uint64")
+    {
+      uint64NDArray m = tc.uint64_array_value ();
+
+      write_mat5_integer_data (os, m.fortran_vec (), 8, m.nelem ());
+    }
+  else if (tc.is_bool_type ())
+    {
+      uint8NDArray m (tc.bool_array_value ());
+
+      write_mat5_integer_data (os, m.fortran_vec (), 1, m.nelem ());
+    }
+  else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ())
+    {
+      NDArray m = tc.array_value ();
+
+      write_mat5_array (os, m, save_as_floats);
+    }
+  else if (tc.is_cell ())
+    {
+      Cell cell = tc.cell_value ();
+
+      if (! write_mat5_cell_array (os, cell, mark_as_global, save_as_floats))
+	goto error_cleanup;
+    }
+  else if (tc.is_complex_scalar () || tc.is_complex_matrix ()) 
+    {
+      ComplexNDArray m_cmplx = tc.complex_array_value ();
+
+      write_mat5_array (os, ::real (m_cmplx), save_as_floats);
+      write_mat5_array (os, ::imag (m_cmplx), save_as_floats);
+    }
+  else if (tc.is_map () || tc.is_inline_function() || tc.is_object ()) 
+    {
+      if (tc.is_inline_function () || tc.is_object ())
+	{
+	  std::string classname = tc.is_object() ? tc.class_name () : "inline";
+	  int namelen = classname.length ();
+
+	  if (namelen > max_namelen)
+	    namelen = max_namelen; // only 31 or 63 char names permitted
+
+	  int paddedlength = PAD (namelen);
+
+	  write_mat5_tag (os, miINT8, namelen);
+	  OCTAVE_LOCAL_BUFFER (char, paddedname, paddedlength);
+	  memset (paddedname, 0, paddedlength);
+	  strncpy (paddedname, classname.c_str (), namelen);
+	  os.write (paddedname, paddedlength);
+	}
+
+      Octave_map m;
+
+      if (tc.is_object () &&
+	  load_path::find_method (tc.class_name (), "saveobj") != std::string())
+	{
+	  octave_value_list tmp = feval ("saveobj", tc, 1);
+	  if (! error_state)
+	    m = tmp(0).map_value ();
+	  else
+	    goto error_cleanup;
+	}
+      else
+	m = tc.map_value ();
+
+      // an Octave structure */
+      // recursively write each element of the structure
+      {
+	char buf[64];
+	int32_t maxfieldnamelength = max_namelen + 1;
+
+	octave_idx_type nf = m.nfields ();
+
+	int fieldcnt = nf;
+
+	write_mat5_tag (os, miINT32, 4);
+	os.write (reinterpret_cast<char *> (&maxfieldnamelength), 4);
+	write_mat5_tag (os, miINT8, fieldcnt*maxfieldnamelength);
+
+	// Iterating over the list of keys will preserve the order of
+	// the fields.
+	string_vector keys = m.keys ();
+
+	for (octave_idx_type i = 0; i < nf; i++)
+	  {
+	    std::string key = keys(i);
+
+	    // write the name of each element
+	    memset (buf, 0, max_namelen + 1);
+	    // only 31 or 63 char names permitted
+	    strncpy (buf, key.c_str (), max_namelen);
+	    os.write (buf, max_namelen + 1);
+	  }
+
+	int len = m.numel ();
+
+	// Create temporary copy of structure contents to avoid
+	// multiple calls of the contents method.
+	std::vector<const octave_value *> elts (nf);
+	for (octave_idx_type i = 0; i < nf; i++)
+	  elts[i] = m.contents (keys(i)).data ();
+
+	for (int j = 0; j < len; j++)
+	  {
+	    // write the data of each element
+
+	    // Iterating over the list of keys will preserve the order
+	    // of the fields.
+	    for (octave_idx_type i = 0; i < nf; i++)
+	      {
+		bool retval2 = save_mat5_binary_element (os, elts[i][j], "",
+							 mark_as_global,
+							 false, 
+							 save_as_floats);
+		if (! retval2)
+		  goto error_cleanup;
+	      }
+	  }
+      }
+    }
+  else
+    gripe_wrong_type_arg ("save", tc, false);
+
+  contin = os.tellp ();
+
+  return true;
+
+ error_cleanup:
+  error ("save: error while writing `%s' to MAT file", name.c_str ());
+
+  return false;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-mat5.h b/src/ls-mat5.h
new file mode 100644
index 0000000..158757f
--- /dev/null
+++ b/src/ls-mat5.h
@@ -0,0 +1,68 @@
+/*
+
+Copyright (C) 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_mat5_h)
+#define octave_ls_mat5_h 1
+
+enum mat5_data_type
+  {
+    miINT8 = 1,			// 8 bit signed
+    miUINT8,			// 8 bit unsigned
+    miINT16,			// 16 bit signed
+    miUINT16,			// 16 bit unsigned
+    miINT32,			// 32 bit signed
+    miUINT32,			// 32 bit unsigned
+    miSINGLE,			// IEEE 754 single precision float
+    miRESERVE1,
+    miDOUBLE,			// IEEE 754 double precision float
+    miRESERVE2,
+    miRESERVE3,
+    miINT64,			// 64 bit signed
+    miUINT64,			// 64 bit unsigned
+    miMATRIX,			// MATLAB array
+    miCOMPRESSED,		// Compressed data
+    miUTF8,			// Unicode UTF-8 Encoded Character Data
+    miUTF16,			// Unicode UTF-16 Encoded Character Data
+    miUTF32			// Unicode UTF-32 Encoded Character Data
+  };
+
+extern int
+read_mat5_binary_file_header (std::istream& is, bool& swap,
+			      bool quiet = false,
+			      const std::string& filename = std::string());
+extern std::string
+read_mat5_binary_element (std::istream& is, const std::string& filename,
+			  bool swap, bool& global, octave_value& tc);
+extern bool
+save_mat5_binary_element (std::ostream& os,
+			  const octave_value& tc, const std::string& name,
+			  bool mark_as_global, bool mat7_format,
+			  bool save_as_floats, bool compressing = false);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-oct-ascii.cc b/src/ls-oct-ascii.cc
new file mode 100644
index 0000000..8d49beb
--- /dev/null
+++ b/src/ls-oct-ascii.cc
@@ -0,0 +1,428 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: John W. Eaton.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "ls-ascii-helper.h"
+#include "ls-oct-ascii.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+// The number of decimal digits to use when writing ascii data.
+static int Vsave_precision = 16;
+
+// Functions for reading ascii data.
+
+// Extract a KEYWORD and its value from stream IS, returning the
+// associated value in a new string.
+//
+// Input should look something like:
+//
+//  [%#][ \t]*keyword[ \t]*:[ \t]*string-value[ \t]*\n
+
+std::string
+extract_keyword (std::istream& is, const char *keyword, const bool next_only)
+{
+  std::string retval;
+
+  int ch = is.peek ();
+  if (next_only && ch != '%' && ch != '#')
+    return retval;
+
+  char c;
+  while (is.get (c))
+    {
+      if (c == '%' || c == '#')
+	{
+	  std::ostringstream buf;
+	
+	  while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
+	    ; // Skip whitespace and comment characters.
+
+	  if (isalpha (c))
+	    buf << c;
+
+	  while (is.get (c) && isalpha (c))
+	    buf << c;
+
+	  std::string tmp = buf.str ();
+	  bool match = (tmp.compare (0, strlen (keyword), keyword) == 0);
+
+	  if (match)
+	    {
+	      std::ostringstream value;
+	      while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
+		; // Skip whitespace and the colon.
+
+	      is.putback(c);
+	      retval = read_until_newline (is, false);
+	      break;
+	    }
+	  else if (next_only)
+	    break;
+	  else
+	    skip_until_newline (is, false);
+	}
+    }
+
+  int len = retval.length ();
+
+  if (len > 0)
+    {
+      while (len)
+	{
+	  c = retval[len-1];
+
+	  if (c == ' ' || c == '\t')
+	    len--;
+	  else
+	    {
+	      retval.resize (len);
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+// Extract one value (scalar, matrix, string, etc.) from stream IS and
+// place it in TC, returning the name of the variable.  If the value
+// is tagged as global in the file, return TRUE in GLOBAL.
+//
+// Each type supplies its own function to load the data, and so this
+// function is extensible.
+//
+// FILENAME is used for error messages.
+//
+// The data is expected to be in the following format:
+//
+// The input file must have a header followed by some data.
+//
+// All lines in the header must begin with a `#' character.
+//
+// The header must contain a list of keyword and value pairs with the
+// keyword and value separated by a colon.
+//
+// Keywords must appear in the following order:
+//
+// # name: <name>
+// # type: <type>
+// # <info>
+//
+// Where, for the built in types are:
+//
+//  <name> : a valid identifier
+//
+//  <type> : <typename>
+//         | global <typename>
+//
+//  <typename> : scalar
+//             | complex scalar
+//             | matrix
+//             | complex matrix
+//             | bool
+//             | bool matrix
+//             | string
+//             | range
+//
+//  <info> : <matrix info>
+//         | <string info>
+//
+//  <matrix info> : # rows: <integer>
+//                : # columns: <integer>
+//
+//  <string info> : # elements: <integer>
+//                : # length: <integer> (once before each string)
+//
+//  For backward compatibility the type "string array" is treated as a
+// "string" type. Also "string" can have a single element with no elements
+// line such that
+//
+//  <string info> : # length: <integer>
+//
+// Formatted ASCII data follows the header.
+//
+// Example:
+//
+//  # name: foo
+//  # type: matrix
+//  # rows: 2
+//  # columns: 2
+//    2  4
+//    1  3
+//
+// Example:
+//
+//  # name: foo
+//  # type: string
+//  # elements: 5
+//  # length: 4
+//  this
+//  # length: 2
+//  is
+//  # length: 1
+//  a
+//  # length: 6
+//  string
+//  # length: 5
+//  array
+//
+// FIXME -- this format is fairly rigid, and doesn't allow for
+// arbitrary comments.  Someone should fix that. It does allow arbitrary
+// types however.
+
+// Ugh.  The signature of the compare method is not standard in older
+// versions of the GNU libstdc++.  Do this instead:
+
+#define SUBSTRING_COMPARE_EQ(s, pos, n, t) (s.substr (pos, n) == t)
+
+std::string
+read_ascii_data (std::istream& is, const std::string& filename, bool& global,
+		 octave_value& tc, octave_idx_type count)
+{
+  // Read name for this entry or break on EOF.
+
+  std::string name = extract_keyword (is, "name");
+
+  if (name.empty ())
+    {
+      if (count == 0)
+	error ("load: empty name keyword or no data found in file `%s'",
+	       filename.c_str ());
+
+      return std::string ();
+    }
+
+  if (! (name == ".nargin." || name == ".nargout."
+	 || name == CELL_ELT_TAG || valid_identifier (name)))
+    {
+      error ("load: bogus identifier `%s' found in file `%s'",
+	     name.c_str (), filename.c_str ());
+      return std::string ();
+    }
+
+  // Look for type keyword.
+
+  std::string tag = extract_keyword (is, "type");
+
+  if (! tag.empty ())
+    {
+      std::string typ;
+      size_t pos = tag.rfind (' ');
+
+      if (pos != std::string::npos)
+	{
+	  global = SUBSTRING_COMPARE_EQ (tag, 0, 6, "global");
+
+	  typ = global ? tag.substr (7) : tag;
+	}
+      else
+	typ = tag;
+
+      // Special case for backward compatiablity. A small bit of cruft
+      if (SUBSTRING_COMPARE_EQ (typ, 0, 12, "string array"))
+	tc = octave_value (charMatrix (), true);
+      else
+	tc = octave_value_typeinfo::lookup_type (typ);
+
+      if (! tc.load_ascii (is))
+	error ("load: trouble reading ascii file `%s'", filename.c_str ());
+    }
+  else
+    error ("load: failed to extract keyword specifying value type");
+
+  if (error_state)
+    {
+      error ("load: reading file %s", filename.c_str ());
+      return std::string ();
+    }
+
+  return name;
+}
+
+// Save the data from TC along with the corresponding NAME, and global
+// flag MARK_AS_GLOBAL on stream OS in the plain text format described
+// above for load_ascii_data.  If NAME is empty, the name: line is not
+// generated.  PRECISION specifies the number of decimal digits to print. 
+//
+// Assumes ranges and strings cannot contain Inf or NaN values.
+//
+// Returns 1 for success and 0 for failure.
+
+// FIXME -- should probably write the help string here too.
+
+bool
+save_ascii_data (std::ostream& os, const octave_value& val_arg,
+		 const std::string& name, bool mark_as_global,
+		 int precision)
+{
+  bool success = true;
+
+  if (! name.empty ())
+    os << "# name: " << name << "\n";
+
+  octave_value val = val_arg;
+
+  if (mark_as_global)
+    os << "# type: global " << val.type_name () << "\n";
+  else
+    os << "# type: " << val.type_name() << "\n";
+
+  if (! precision)
+    precision = Vsave_precision;
+
+  long old_precision = os.precision ();
+  os.precision (precision);
+
+  success = val.save_ascii (os);
+
+  os.precision (old_precision);
+
+  return (os && success);
+}
+
+bool
+save_ascii_data_for_plotting (std::ostream& os, const octave_value& t,
+			      const std::string& name)
+{
+  return save_ascii_data (os, t, name, false, 6);
+}
+
+// Maybe this should be a static function in tree-plot.cc?
+
+// If TC is matrix, save it on stream OS in a format useful for
+// making a 3-dimensional plot with gnuplot.  If PARAMETRIC is
+// TRUE, assume a parametric 3-dimensional plot will be generated.
+
+bool
+save_three_d (std::ostream& os, const octave_value& tc, bool parametric)
+{
+  bool fail = false;
+
+  octave_idx_type nr = tc.rows ();
+  octave_idx_type nc = tc.columns ();
+
+  if (tc.is_real_matrix ())
+    {
+      os << "# 3D data...\n"
+	 << "# type: matrix\n"
+	 << "# total rows: " << nr << "\n"
+	 << "# total columns: " << nc << "\n";
+
+      long old_precision = os.precision ();
+      os.precision (6);
+
+      if (parametric)
+	{
+	  octave_idx_type extras = nc % 3;
+	  if (extras)
+	    warning ("ignoring last %d columns", extras);
+
+	  Matrix tmp = tc.matrix_value ();
+	  nr = tmp.rows ();
+
+	  for (octave_idx_type i = 0; i < nc-extras; i += 3)
+	    {
+	      os << tmp.extract (0, i, nr-1, i+2);
+	      if (i+3 < nc-extras)
+		os << "\n";
+	    }
+	}
+      else
+	{
+	  Matrix tmp = tc.matrix_value ();
+	  nr = tmp.rows ();
+
+	  for (octave_idx_type i = 0; i < nc; i++)
+	    {
+	      os << tmp.extract (0, i, nr-1, i);
+	      if (i+1 < nc)
+		os << "\n";
+	    }
+	}
+
+      os.precision (old_precision);
+    }
+  else
+    {
+      ::error ("for now, I can only save real matrices in 3D format");
+      fail = true;
+    }
+
+  return (os && ! fail);
+}
+
+DEFUN (save_precision, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} save_precision ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} save_precision (@var{new_val})\n\
+Query or set the internal variable that specifies the number of\n\
+digits to keep when saving data in text format.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE_WITH_LIMITS (save_precision, -1, INT_MAX);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-oct-ascii.h b/src/ls-oct-ascii.h
new file mode 100644
index 0000000..3a20cda
--- /dev/null
+++ b/src/ls-oct-ascii.h
@@ -0,0 +1,188 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_oct_ascii_h)
+#define octave_ls_oct_ascii_h 1
+
+#include <cfloat>
+
+#include <sstream>
+#include <string>
+
+#include "str-vec.h"
+
+#include "ls-ascii-helper.h"
+
+// Flag for cell elements
+#define CELL_ELT_TAG "<cell-element>"
+
+// Used when converting Inf to something that gnuplot can read.
+
+#ifndef OCT_RBV
+#define OCT_RBV DBL_MAX / 100.0
+#endif
+
+extern OCTINTERP_API std::string
+extract_keyword (std::istream& is, const char *keyword, 
+		 const bool next_only = false);
+
+extern OCTINTERP_API std::string
+read_ascii_data (std::istream& is, const std::string& filename, bool& global,
+		 octave_value& tc, octave_idx_type count);
+
+extern OCTINTERP_API bool
+save_ascii_data (std::ostream& os, const octave_value& val_arg,
+		 const std::string& name, bool mark_as_global, int precision);
+
+extern OCTINTERP_API bool
+save_ascii_data_for_plotting (std::ostream& os, const octave_value& t,
+			      const std::string& name);
+
+extern OCTINTERP_API bool
+save_three_d (std::ostream& os, const octave_value& t,
+	      bool parametric = false);
+
+// Match KEYWORD on stream IS, placing the associated value in VALUE,
+// returning TRUE if successful and FALSE otherwise.
+//
+// Input should look something like:
+//
+//  [%#][ \t]*keyword[ \t]*int-value.*\n
+
+template <class T>
+bool
+extract_keyword (std::istream& is, const char *keyword, T& value, 
+		 const bool next_only = false)
+{
+  bool status = false;
+  value = T();
+
+  char c;
+  while (is.get (c))
+    {
+      if (c == '%' || c == '#')
+	{
+	  std::ostringstream buf;
+
+	  while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
+	    ; // Skip whitespace and comment characters.
+
+	  if (isalpha (c))
+	    buf << c;
+
+	  while (is.get (c) && isalpha (c))
+	    buf << c;
+
+	  std::string tmp = buf.str ();
+	  bool match = (tmp.compare (0, strlen (keyword), keyword) == 0);
+
+	  if (match)
+	    {
+	      while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
+		; // Skip whitespace and the colon.
+
+	      is.putback (c);
+	      if (c != '\n' && c != '\r')
+		is >> value;
+	      if (is)
+		status = true;
+	      skip_until_newline (is, false);
+	      break;
+	    }
+	  else if (next_only)
+	    break;
+	}
+    }
+  return status;
+}
+
+// Match one of the elements in KEYWORDS on stream IS, placing the
+// matched keyword in KW and the associated value in VALUE,
+// returning TRUE if successful and FALSE otherwise.
+//
+// Input should look something like:
+//
+//  [%#][ \t]*keyword[ \t]*int-value.*\n
+
+template <class T>
+bool
+extract_keyword (std::istream& is, const string_vector& keywords,
+		 std::string& kw, T& value, const bool next_only = false)
+{
+  bool status = false;
+  kw = "";
+  value = 0;
+
+  char c;
+  while (is.get (c))
+    {
+      if (c == '%' || c == '#')
+	{
+	  std::ostringstream buf;
+
+	  while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
+	    ; // Skip whitespace and comment characters.
+
+	  if (isalpha (c))
+	    buf << c;
+
+	  while (is.get (c) && isalpha (c))
+	    buf << c;
+
+	  std::string tmp = buf.str ();
+
+	  for (int i = 0; i < keywords.length (); i++)
+	    {
+	      int match = (tmp == keywords[i]);
+
+	      if (match)
+		{
+		  kw = keywords[i];
+
+		  while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
+		    ; // Skip whitespace and the colon.
+
+		  is.putback (c);
+		  if (c != '\n' && c != '\r')
+		    is >> value;
+		  if (is)
+		    status = true;
+		  skip_until_newline (is, false);
+		  return status;
+		}
+	    }
+
+	  if (next_only)
+	    break;
+	}
+    }
+  return status;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-oct-binary.cc b/src/ls-oct-binary.cc
new file mode 100644
index 0000000..a0b70f6
--- /dev/null
+++ b/src/ls-oct-binary.cc
@@ -0,0 +1,314 @@
+/*
+
+Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "sysdep.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+#include "ls-utils.h"
+#include "ls-oct-binary.h"
+
+// Extract one value (scalar, matrix, string, etc.) from stream IS and
+// place it in TC, returning the name of the variable.  If the value
+// is tagged as global in the file, return TRUE in GLOBAL.  If SWAP
+// is TRUE, swap bytes after reading.
+//
+// The data is expected to be in the following format:
+//
+// Header (one per file):
+// =====================
+//
+//   object               type            bytes
+//   ------               ----            -----
+//   magic number         string             10
+//
+//   float format         integer             1  
+//
+//
+// Data (one set for each item):
+// ============================
+//
+//   object               type            bytes
+//   ------               ----            -----
+//   name_length          integer             4
+//
+//   name                 string    name_length
+//
+//   doc_length           integer             4
+//
+//   doc                  string     doc_length
+//
+//   global flag          integer             1
+//
+//   data type            char                1
+//
+// In general "data type" is 255, and in that case the next arguments
+// in the data set are
+//
+//   object               type            bytes
+//   ------               ----            -----
+//   type_length          integer             4
+//
+//   type                 string    type_length
+//
+// The string "type" is then used with octave_value_typeinfo::lookup_type
+// to create an octave_value of the correct type. The specific load/save
+// function is then called.
+//
+// For backward compatiablity "data type" can also be a value between 1
+// and 7, where this defines a hardcoded octave_value of the type
+//
+//   data type                  octave_value
+//   ---------                  ------------
+//   1                          scalar
+//   2                          matrix
+//   3                          complex scalar
+//   4                          complex matrix
+//   5                          string   (old style storage)
+//   6                          range
+//   7                          string
+//
+// Except for "data type" equal 5 that requires special treatment, these
+// old style "data type" value also cause the specific load/save functions
+// to be called. FILENAME is used for error messages.
+
+std::string
+read_binary_data (std::istream& is, bool swap,
+		  oct_mach_info::float_format fmt,
+		  const std::string& filename, bool& global,
+		  octave_value& tc, std::string& doc)
+{
+  std::string retval;
+
+  unsigned char tmp = 0;
+
+  int32_t name_len = 0;
+  int32_t doc_len = 0;
+
+  doc.resize (0);
+
+  // We expect to fail here, at the beginning of a record, so not
+  // being able to read another name should not result in an error.
+
+  is.read (reinterpret_cast<char *> (&name_len), 4);
+  if (! is)
+    return retval;
+  if (swap)
+    swap_bytes<4> (&name_len);
+
+  {
+    OCTAVE_LOCAL_BUFFER (char, name, name_len+1);
+    name[name_len] = '\0';
+    if (! is.read (reinterpret_cast<char *> (name), name_len))
+      goto data_read_error;
+    retval = name;
+  }
+
+  is.read (reinterpret_cast<char *> (&doc_len), 4);
+  if (! is)
+    goto data_read_error;
+  if (swap)
+    swap_bytes<4> (&doc_len);
+
+  {
+    OCTAVE_LOCAL_BUFFER (char, tdoc, doc_len+1);
+    tdoc[doc_len] = '\0';
+    if (! is.read (reinterpret_cast<char *> (tdoc), doc_len))
+      goto data_read_error;
+    doc = tdoc;
+  }
+
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    goto data_read_error;
+  global = tmp ? 1 : 0;
+
+  tmp = 0;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    goto data_read_error;
+
+  // All cases except 255 kept for backwards compatibility
+  switch (tmp)
+    {
+    case 1:
+      tc = octave_value_typeinfo::lookup_type ("scalar");
+      break;
+
+    case 2:
+      tc = octave_value_typeinfo::lookup_type ("matrix");
+      break;
+
+    case 3:
+      tc = octave_value_typeinfo::lookup_type ("complex scalar");
+      break;
+
+    case 4:
+      tc = octave_value_typeinfo::lookup_type ("complex matrix");
+      break;
+
+    case 5:
+      {
+	// FIXMEX
+	// This is cruft, since its for a save type that is old. Maybe
+	// this is taking backward compatability too far!!
+	int32_t len;
+	if (! is.read (reinterpret_cast<char *> (&len), 4))
+	  goto data_read_error;
+	if (swap)
+	  swap_bytes<4> (&len);
+	OCTAVE_LOCAL_BUFFER (char, s, len+1);
+	if (! is.read (reinterpret_cast<char *> (s), len))
+	  goto data_read_error;
+	s[len] = '\0';
+	tc = s;
+
+	// Early return, since don't want rest of this function
+	return retval;
+      }
+      break;
+
+    case 6:
+      tc = octave_value_typeinfo::lookup_type ("range");
+      break;
+
+    case 7:
+      tc = octave_value_typeinfo::lookup_type ("string");
+      break;
+
+    case 255:
+      {
+	// Read the saved variable type
+	int32_t len;
+	if (! is.read (reinterpret_cast<char *> (&len), 4))
+	  goto data_read_error;
+	if (swap)
+	  swap_bytes<4> (&len);
+	OCTAVE_LOCAL_BUFFER (char, s, len+1);
+	if (! is.read (s, len))
+	  goto data_read_error;
+	s[len] = '\0';
+	std::string typ = s;
+	tc = octave_value_typeinfo::lookup_type (typ);
+      }
+      break;
+    default:
+      goto data_read_error;
+      break;
+    }
+  
+  if (!tc.load_binary (is, swap, fmt))
+    {
+    data_read_error:
+      error ("load: trouble reading binary file `%s'", filename.c_str ());
+    }
+
+  return retval;
+}
+
+// Save the data from TC along with the corresponding NAME, help
+// string DOC, and global flag MARK_AS_GLOBAL on stream OS in the
+// binary format described above for read_binary_data.
+
+bool
+save_binary_data (std::ostream& os, const octave_value& tc,
+		  const std::string& name, const std::string& doc,
+		  bool mark_as_global, bool save_as_floats) 
+{
+  int32_t name_len = name.length ();
+
+  os.write (reinterpret_cast<char *> (&name_len), 4);
+  os << name;
+
+  int32_t doc_len = doc.length ();
+
+  os.write (reinterpret_cast<char *> (&doc_len), 4);
+  os << doc;
+
+  unsigned char tmp;
+
+  tmp = mark_as_global;
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+
+  // 255 flags the new binary format
+  tmp = 255;
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+
+  // Write the string corresponding to the octave_value type
+  std::string typ = tc.type_name ();
+  int32_t len = typ.length ();
+  os.write (reinterpret_cast<char *> (&len), 4);
+  const char *btmp = typ.data ();
+  os.write (btmp, len);
+      
+  // The octave_value of tc is const. Make a copy...
+  octave_value val = tc;
+
+  // Call specific save function
+  bool success = val.save_binary (os, save_as_floats);
+
+  return (os && success);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-oct-binary.h b/src/ls-oct-binary.h
new file mode 100644
index 0000000..451ca87
--- /dev/null
+++ b/src/ls-oct-binary.h
@@ -0,0 +1,44 @@
+/*
+
+Copyright (C) 2003, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_oct_binary_h)
+#define octave_ls_oct_binary_h 1
+
+extern OCTINTERP_API bool
+save_binary_data (std::ostream& os, const octave_value& tc,
+		  const std::string& name, const std::string& doc,
+		  bool mark_as_global, bool save_as_floats);
+
+extern OCTINTERP_API std::string
+read_binary_data (std::istream& is, bool swap,
+		  oct_mach_info::float_format fmt,
+		  const std::string& filename, bool& global,
+		  octave_value& tc, std::string& doc);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ls-utils.cc b/src/ls-utils.cc
new file mode 100644
index 0000000..0ac30c3
--- /dev/null
+++ b/src/ls-utils.cc
@@ -0,0 +1,66 @@
+/*
+
+Copyright (C) 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "data-conv.h"
+
+#include "ls-utils.h"
+
+// MAX_VAL and MIN_VAL are assumed to have integral values even though
+// they are stored in doubles.
+
+save_type
+get_save_type (double /* max_val */, double /* min_val */)
+{
+  save_type st = LS_DOUBLE;
+
+  // Matlab doesn't seem to load the UINT32 type correctly, so let's
+  // avoid it (and the other unsigned types, even though they may not
+  // have the same problem.  And apparently, there are problems with
+  // other smaller types as well.  If we avoid them all, then maybe we
+  // will avoid problems.  Unfortunately, we won't be able to save
+  // space...
+
+  //  if (max_val < 256 && min_val > -1)
+  //    st = LS_U_CHAR;
+  //  else if (max_val < 65536 && min_val > -1)
+  //    st = LS_U_SHORT;
+  //  else if (max_val < 4294967295UL && min_val > -1)
+  //    st = LS_U_INT;
+  //  else if (max_val < 128 && min_val >= -128)
+  //    st = LS_CHAR;
+  //  else if (max_val < 32768 && min_val >= -32768)
+  //    st = LS_SHORT;
+  //  else if (max_val <= 2147483647L && min_val >= -2147483647L)
+  //    st = LS_INT;
+
+  return st;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ls-utils.h b/src/ls-utils.h
new file mode 100644
index 0000000..04e61de
--- /dev/null
+++ b/src/ls-utils.h
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ls_utils_h)
+#define octave_ls_utils 1
+
+extern save_type
+get_save_type (double max_val, double min_val);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..3cb1f91
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,42 @@
+/*
+
+Copyright (C) 2002, 2003, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "f77-fcn.h"
+#include "lo-ieee.h"
+
+#include "octave.h"
+
+int
+main (int argc, char **argv)
+{
+  return octave_main (argc, argv, 0);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/mappers.cc b/src/mappers.cc
new file mode 100644
index 0000000..a1e59d6
--- /dev/null
+++ b/src/mappers.cc
@@ -0,0 +1,1742 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+#include <cfloat>
+
+#include "lo-ieee.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+
+#include "defun.h"
+#include "error.h"
+#include "variables.h"
+
+DEFUN (abs, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} abs (@var{z})\n\
+Compute the magnitude of @var{z}, defined as\n\
+ at tex\n\
+$|z| = \\sqrt{x^2 + y^2}$.\n\
+ at end tex\n\
+ at ifnottex\n\
+|@var{z}| = @code{sqrt (x^2 + y^2)}.\n\
+ at end ifnottex\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+abs (3 + 4i)\n\
+     @result{} 5\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).abs ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(abs (1), 1);
+%!assert(abs (-3.5), 3.5);
+%!assert(abs (3+4i), 5);
+%!assert(abs (3-4i), 5);
+%!assert(abs ([1.1, 3i; 3+4i, -3-4i]), [1.1, 3; 5, 5]);
+
+%!assert(abs (single(1)), single(1));
+%!assert(abs (single(-3.5)), single(3.5));
+%!assert(abs (single(3+4i)), single(5));
+%!assert(abs (single(3-4i)), single(5));
+%!assert(abs (single([1.1, 3i; 3+4i, -3-4i])), single([1.1, 3; 5, 5]));
+
+%!error abs ();
+%!error abs (1, 2);
+
+ */
+
+DEFUN (acos, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} acos (@var{x})\n\
+Compute the inverse cosine in radians for each element of @var{x}.\n\
+ at seealso{cos, acosd}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).acos ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = [0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi];
+%! x = [1, rt3/2, rt2/2, 1/2, 0, -1/2, -rt2/2, -rt3/2, -1];
+%! assert(acos (x), v, sqrt(eps));
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = single ([0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi]);
+%! x = single ([1, rt3/2, rt2/2, 1/2, 0, -1/2, -rt2/2, -rt3/2, -1]);
+%! assert(acos (x), v, sqrt(eps('single')));
+
+%!error acos ();
+%!error acos (1, 2);
+
+*/
+
+DEFUN (acosh, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} acosh (@var{x})\n\
+Compute the inverse hyperbolic cosine for each element of @var{x}.\n\
+ at seealso{cosh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).acosh ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! v = [0, pi/2*i, pi*i, pi/2*i];
+%! x = [1, 0, -1, 0];
+%! assert(acosh (x), v, sqrt(eps));
+
+%!test
+%! v = single([0, pi/2*i, pi*i, pi/2*i]);
+%! x = single([1, 0, -1, 0]);
+%! assert(acosh (x), v, sqrt (eps('single')));
+
+%!error acosh ();
+%!error acosh (1, 2);
+
+*/
+
+DEFUN (angle, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} angle (@var{z})\n\
+See arg.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).arg ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (arg, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} arg (@var{z})\n\
+ at deftypefnx {Mapping Function} {} angle (@var{z})\n\
+Compute the argument of @var{z}, defined as,\n\
+ at tex\n\
+$\\theta = atan2 (y, x),$\n\
+ at end tex\n\
+ at ifnottex\n\
+ at var{theta} = @code{atan2 (@var{y}, @var{x})},\n\
+ at end ifnottex\n\
+in radians.\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+arg (3 + 4i)\n\
+     @result{} 0.92730\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).arg ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(arg (1), 0);
+%!assert(arg (i), pi/2);
+%!assert(arg (-1), pi);
+%!assert(arg (-i), -pi/2);
+%!assert(arg ([1, i; -1, -i]), [0, pi/2; pi, -pi/2]);
+
+%!assert(arg (single(1)), single(0));
+%!assert(arg (single(i)), single(pi/2));
+%!assert(arg (single(-1)), single(pi));
+%!assert(arg (single(-i)), single(-pi/2));
+%!assert(arg (single([1, i; -1, -i])), single([0, pi/2; pi, -pi/2]), 2e1*eps('single'));
+
+%!error arg ();
+%!error arg (1, 2);
+
+*/
+
+DEFUN (asin, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} asin (@var{x})\n\
+Compute the inverse sine in radians for each element of @var{x}.\n\
+ at seealso{sin, asind}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).asin ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = [0, pi/6, pi/4, pi/3, pi/2, pi/3, pi/4, pi/6, 0];
+%! x = [0, 1/2, rt2/2, rt3/2, 1, rt3/2, rt2/2, 1/2, 0];
+%! assert(all (abs (asin (x) - v) < sqrt (eps)));
+%!error asin ();
+%!error asin (1, 2);
+*/
+
+DEFUN (asinh, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} asinh (@var{x})\n\
+Compute the inverse hyperbolic sine for each element of @var{x}.\n\
+ at seealso{sinh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).asinh ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! v = [0, pi/2*i, 0, -pi/2*i];
+%! x = [0, i, 0, -i];
+%! assert(asinh (x), v,  sqrt (eps));
+
+%!test
+%! v = single([0, pi/2*i, 0, -pi/2*i]);
+%! x = single([0, i, 0, -i]);
+%! assert(asinh (x), v,  sqrt (eps('single')));
+
+%!error asinh ();
+%!error asinh (1, 2);
+
+*/
+
+DEFUN (atan, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} atan (@var{x})\n\
+Compute the inverse tangent in radians for each element of @var{x}.\n\
+ at seealso{tan, atand}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).atan ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = [0, pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6, 0];
+%! x = [0, rt3/3, 1, rt3, -rt3, -1, -rt3/3, 0];
+%! assert(atan (x), v, sqrt (eps));
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! v = single([0, pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6, 0]);
+%! x = single([0, rt3/3, 1, rt3, -rt3, -1, -rt3/3, 0]);
+%! assert(atan (x), v, sqrt (eps('single')));
+
+%!error atan ();
+%!error atan (1, 2);
+
+ */
+
+DEFUN (atanh, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} atanh (@var{x})\n\
+Compute the inverse hyperbolic tangent for each element of @var{x}.\n\
+ at seealso{tanh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).atanh ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! v = [0, 0];
+%! x = [0, 0];
+%! assert(atanh (x), v, sqrt (eps));
+
+%!test
+%! v = single([0, 0]);
+%! x = single([0, 0]);
+%! assert(atanh (x), v, sqrt (eps('single')));
+
+%!error atanh ();
+%!error atanh (1, 2);
+
+*/
+
+DEFUN (ceil, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} ceil (@var{x})\n\
+Return the smallest integer not less than @var{x}.  This is equivalent to\n\
+rounding towards positive infinity.  If @var{x} is\n\
+complex, return @code{ceil (real (@var{x})) + ceil (imag (@var{x})) * I}.\n\
+ at example\n\
+ at group\n\
+ceil ([-2.7, 2.7])\n\
+   @result{}  -2   3\n\
+ at end group\n\
+ at end example\n\
+ at seealso{floor, round, fix}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).ceil ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%% double precision
+%!assert(ceil ([2, 1.1, -1.1, -1]), [2, 2, -1, -1]);
+
+%% compelx double precison 
+%!assert(ceil ([2+2i, 1.1+1.1i, -1.1-1.1i, -1-i]), [2+2i, 2+2i, -1-i, -1-i]);
+
+%% single precision
+%!assert(ceil (single([2, 1.1, -1.1, -1])), single([2, 2, -1, -1]));
+
+%% compelx single preci
+%!assert(ceil (single ([2+2i, 1.1+1.1i, -1.1-1.1i, -1-i])), single([2+2i, 2+2i, -1-i, -1-i]));
+
+%!error ceil ();
+%!error ceil (1, 2);
+
+*/
+
+DEFUN (conj, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} conj (@var{z})\n\
+Return the complex conjugate of @var{z}, defined as\n\
+ at tex\n\
+$\\bar{z} = x - iy$.\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{conj (@var{z})} = @var{x} - @var{i}@var{y}.\n\
+ at end ifnottex\n\
+ at seealso{real, imag}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).conj ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(conj (1), 1);
+%!assert(conj (i), -i)
+%!assert(conj (1+i), 1-i)
+%!assert(conj (1-i), 1+i)
+%!assert(conj ([-1, -i; -1+i, -1-i]), [-1, i; -1-i, -1+i]);
+
+%!assert(conj (single(1)), single(1));
+%!assert(conj (single(i)), single(-i))
+%!assert(conj (single(1+i)), single(1-i))
+%!assert(conj (single(1-i)), single(1+i))
+%!assert(conj (single([-1, -i; -1+i, -1-i])), single([-1, i; -1-i, -1+i]));
+
+%!error conj ();
+%!error conj (1, 2);
+
+*/
+
+DEFUN (cos, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} cos (@var{x})\n\
+Compute the cosine for each element of @var{x} in radians.\n\
+ at seealso{acos, cosd, cosh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).cos ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi];
+%! v = [1, rt3/2, rt2/2, 1/2, 0, -1/2, -rt2/2, -rt3/2, -1];
+%! assert(cos (x), v, sqrt (eps));
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = single([0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi]);
+%! v = single([1, rt3/2, rt2/2, 1/2, 0, -1/2, -rt2/2, -rt3/2, -1]);
+%! assert(cos (x), v, sqrt (eps('single')));
+
+%!error cos ();
+%!error cos (1, 2);
+
+ */
+
+DEFUN (cosh, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} cosh (@var{x})\n\
+Compute the hyperbolic cosine for each element of @var{x}.\n\
+ at seealso{acosh, sinh, tanh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).cosh ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! x = [0, pi/2*i, pi*i, 3*pi/2*i];
+%! v = [1, 0, -1, 0];
+%! assert(cosh (x), v, sqrt (eps));
+
+%!test
+%! x = single([0, pi/2*i, pi*i, 3*pi/2*i]);
+%! v = single([1, 0, -1, 0]);
+%! assert(cosh (x), v, sqrt (eps ('single')));
+
+%!error cosh ();
+%!error cosh (1, 2);
+
+*/
+
+DEFUN (erf, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} erf (@var{z})\n\
+Computes the error function,\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+ {\\rm erf} (z) = {2 \\over \\sqrt{\\pi}}\\int_0^z e^{-t^2} dt\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+                         z\n\
+                        /\n\
+erf (z) = (2/sqrt (pi)) | e^(-t^2) dt\n\
+                        /\n\
+                     t=0\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+ at seealso{erfc, erfinv}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).erf ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = -1i*sqrt(-1/(6.4187*6.4187));
+%! assert (erf(a), erf(real(a)));
+
+%!test
+%! x=[0,.5,1];
+%! v=[0, .520499877813047, .842700792949715];
+%! assert(all(abs(erf(x)-v)<1.e-10) &&  all(abs(erf(-x)+v)<1.e-10) && all(abs(erfc(x)+v-1)<1.e-10) && all(abs(erfinv(v)-x)<1.e-10));
+
+%!test
+%! a = -1i*sqrt(single (-1/(6.4187*6.4187)));
+%! assert (erf(a), erf(real(a)));
+
+%!test
+%! x=single ([0,.5,1]);
+%! v=single ([0, .520499877813047, .842700792949715]);
+%! assert(all(abs(erf(x)-v)<1.e-6) &&  all(abs(erf(-x)+v)<1.e-6) && all(abs(erfc(x)+v-1)<1.e-6) && all(abs(erfinv(v)-x)<1.e-6));
+
+%% test/octave.test/arith/erf-2.m
+%!error erf();
+
+%% test/octave.test/arith/erf-3.m
+%!error erf(1,2);
+
+
+
+*/
+
+DEFUN (erfc, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} erfc (@var{z})\n\
+Computes the complementary error function,\n\
+ at iftex\n\
+ at tex\n\
+$1 - {\\rm erf} (z)$.\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+ at code{1 - erf (@var{z})}.\n\
+ at end ifnottex\n\
+ at seealso{erf, erfinv}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).erfc ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = -1i*sqrt(-1/(6.4187*6.4187));
+%! assert (erfc(a), erfc(real(a)));
+
+*/
+
+DEFUN (exp, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} exp (@var{x})\n\
+Compute\n\
+ at tex\n\
+$e^{x}$\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{e^x}\n\
+ at end ifnottex\n\
+for each element of @var{x}.  To compute the matrix\n\
+exponential, see @ref{Linear Algebra}.\n\
+ at seealso{log}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).exp ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(exp ([0, 1, -1, -1000]), [1, e, 1/e, 0], sqrt (eps));
+%!assert(exp (1+i), e * (cos (1) + sin (1) * i), sqrt (eps));
+%!assert(exp (single([0, 1, -1, -1000])), single([1, e, 1/e, 0]), sqrt (eps('single')));
+%!assert(exp (single(1+i)), single (e * (cos (1) + sin (1) * i)), sqrt (eps('single')));
+
+%!error exp ();
+%!error exp (1, 2);
+
+%!assert(exp (Inf) == Inf && exp (-Inf) == 0 && isnan (exp (NaN)));
+%!assert(exp (Inf ('single')) == Inf('single') && exp (-Inf('single')) == 0 && isnan (exp (NaN('single'))));
+
+*/
+
+DEFUN (expm1, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} expm1 (@var{x})\n\
+Compute\n\
+ at tex\n\
+$ e^{x} - 1 $\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{exp (@var{x}) - 1}\n\
+ at end ifnottex\n\
+accurately in the neighborhood of zero.\n\
+ at seealso{exp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).expm1 ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (finite, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} finite (@var{x})\n\
+Return 1 for elements of @var{x} that are finite values and zero\n\
+otherwise.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+finite ([13, Inf, NA, NaN])\n\
+     @result{} [ 1, 0, 0, 0 ]\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).finite ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(!(finite (Inf)));
+%!assert(!(finite (NaN)));
+%!assert(finite (rand(1,10)));
+
+%!assert(!(finite (single(Inf))));
+%!assert(!(finite (single(NaN))));
+%!assert(finite (single(rand(1,10))));
+
+ */
+
+DEFUN (fix, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} fix (@var{x})\n\
+Truncate fractional portion of @var{x} and return the integer portion.  This\n\
+is equivalent to rounding towards zero.  If @var{x} is complex, return\n\
+ at code{fix (real (@var{x})) + fix (imag (@var{x})) * I}.\n\
+ at example\n\
+ at group\n\
+fix ([-2.7, 2.7])\n\
+   @result{} -2   2\n\
+ at end group\n\
+ at end example\n\
+ at seealso{ceil, floor, round}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).fix ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(fix ([1.1, 1, -1.1, -1]), [1, 1, -1, -1]);
+%!assert(fix ([1.1+1.1i, 1+i, -1.1-1.1i, -1-i]), [1+i, 1+i, -1-i, -1-i]);
+%!assert(fix (single([1.1, 1, -1.1, -1])), single([1, 1, -1, -1]));
+%!assert(fix (single([1.1+1.1i, 1+i, -1.1-1.1i, -1-i])), single([1+i, 1+i, -1-i, -1-i]));
+
+%!error fix ();
+%!error fix (1, 2);
+
+*/
+
+DEFUN (floor, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} floor (@var{x})\n\
+Return the largest integer not greater than @var{x}.  This is equivalent to\n\
+rounding towards negative infinity.  If @var{x} is\n\
+complex, return @code{floor (real (@var{x})) + floor (imag (@var{x})) * I}.\n\
+ at example\n\
+ at group\n\
+floor ([-2.7, 2.7])\n\
+     @result{} -3   2\n\
+ at end group\n\
+ at end example\n\
+ at seealso{ceil, round, fix}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).floor ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(floor ([2, 1.1, -1.1, -1]), [2, 1, -2, -1]);
+%!assert(floor ([2+2i, 1.1+1.1i, -1.1-1.1i, -1-i]), [2+2i, 1+i, -2-2i, -1-i]);
+%!assert(floor (single ([2, 1.1, -1.1, -1])), single ([2, 1, -2, -1]));
+%!assert(floor (single([2+2i, 1.1+1.1i, -1.1-1.1i, -1-i])), single([2+2i, 1+i, -2-2i, -1-i]));
+
+%!error floor ();
+%!error floor (1, 2);
+
+*/
+
+DEFUN (gamma, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} gamma (@var{z})\n\
+Computes the Gamma function,\n\
+ at iftex\n\
+ at tex\n\
+$$\n\
+ \\Gamma (z) = \\int_0^\\infty t^{z-1} e^{-t} dt.\n\
+$$\n\
+ at end tex\n\
+ at end iftex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+            infinity\n\
+            /\n\
+gamma (z) = | t^(z-1) exp (-t) dt.\n\
+            /\n\
+         t=0\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+ at seealso{gammainc, lgamma}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).gamma ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = -1i*sqrt(-1/(6.4187*6.4187));
+%! assert (gamma(a), gamma(real(a)));
+
+%!test
+%! x = [.5, 1, 1.5, 2, 3, 4, 5];
+%! v = [sqrt(pi), 1, .5*sqrt(pi), 1, 2, 6, 24];
+%! assert(gamma(x), v, sqrt(eps))
+
+%!test
+%! a = single(-1i*sqrt(-1/(6.4187*6.4187)));
+%! assert (gamma(a), gamma(real(a)));
+
+%!test
+%! x = single([.5, 1, 1.5, 2, 3, 4, 5]);
+%! v = single([sqrt(pi), 1, .5*sqrt(pi), 1, 2, 6, 24]);
+%! assert(gamma(x), v, sqrt(eps('single')))
+
+%!error gamma();
+%!error gamma(1,2);
+
+*/
+
+DEFUN (imag, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} imag (@var{z})\n\
+Return the imaginary part of @var{z} as a real number.\n\
+ at seealso{real, conj}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).imag ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(imag (1), 0);
+%!assert(imag (i), 1);
+%!assert(imag (1+i), 1);
+%!assert(imag ([i, 1; 1, i]), full (eye (2)));
+
+%!assert(imag (single(1)), single(0));
+%!assert(imag (single(i)), single(1));
+%!assert(imag (single(1+i)), single(1));
+%!assert(imag (single([i, 1; 1, i])), full (eye (2,'single')));
+
+%!error imag ();
+%!error imag (1, 2);
+
+ */
+
+DEFUNX ("isalnum", Fisalnum, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isalnum (@var{s})\n\
+Return 1 for characters that are letters or digits (@code{isalpha\n\
+(@var{s})} or @code{isdigit (@var{s})} is true).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisalnum ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("isalpha", Fisalpha, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isalpha (@var{s})\n\
+ at deftypefnx {Mapping Function} {} isletter (@var{s})\n\
+Return true for characters that are letters (@code{isupper (@var{s})}\n\
+or @code{islower (@var{s})} is true).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisalpha ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("isascii", Fisascii, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isascii (@var{s})\n\
+Return 1 for characters that are ASCII (in the range 0 to 127 decimal).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisascii ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("iscntrl", Fiscntrl, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} iscntrl (@var{s})\n\
+Return 1 for control characters.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xiscntrl ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("isdigit", Fisdigit, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isdigit (@var{s})\n\
+Return 1 for characters that are decimal digits.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisdigit ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isinf, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isinf (@var{x})\n\
+Return 1 for elements of @var{x} that are infinite and zero\n\
+otherwise.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+isinf ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 1, 0, 0 ]\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).isinf ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(isinf (Inf));
+%!assert(!isinf (NaN));
+%!assert(!(isinf (NA)));
+%!assert(isinf (rand(1,10)), false(1,10));
+%!assert(isinf([NaN -Inf -1 0 1 Inf NA]), [false, true, false, false, false, true, false]);
+
+%!assert(isinf (single(Inf)));
+%!assert(!(isinf (single(NaN))));
+%!assert(!(isinf (single(NA))));
+%!assert(isinf (single(rand(1,10))), false(1,10));
+%!assert(isinf(single([NaN -Inf -1 0 1 Inf NA])), [false, true, false, false, false, true, false]);
+
+ */
+
+DEFUNX ("isgraph", Fisgraph, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isgraph (@var{s})\n\
+Return 1 for printable characters (but not the space character).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisgraph ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("islower", Fislower, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} islower (@var{s})\n\
+Return 1 for characters that are lower case letters.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xislower ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isna, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isna (@var{x})\n\
+Return 1 for elements of @var{x} that are NA (missing) values and zero\n\
+otherwise.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+isna ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 0, 1, 0 ]\n\
+ at end group\n\
+ at end example\n\
+ at seealso{isnan}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).isna ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(!(isna (Inf)));
+%!assert(!isna (NaN));
+%!assert(isna (NA));
+%!assert(isna (rand(1,10)), false(1,10));
+%!assert(isna([NaN -Inf -1 0 1 Inf NA]), [false, false, false, false, false, false, true]);
+
+%!assert(!(isna (single(Inf))));
+%!assert(!isna (single(NaN)));
+%!assert(isna (single(NA)));
+%!assert(isna (single(rand(1,10))), false(1,10));
+%!assert(isna(single([NaN -Inf -1 0 1 Inf NA])), [false, false, false, false, false, false, true]);
+
+ */
+
+DEFUN (isnan, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isnan (@var{x})\n\
+Return 1 for elements of @var{x} that are NaN values and zero\n\
+otherwise.  NA values are also considered NaN values.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+isnan ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 0, 1, 1 ]\n\
+ at end group\n\
+ at end example\n\
+ at seealso{isna}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).isnan ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(!(isnan (Inf)));
+%!assert(isnan (NaN));
+%!assert(isnan (NA));
+%!assert(isnan (rand(1,10)), false(1,10));
+%!assert(isnan([NaN -Inf -1 0 1 Inf NA]), [true, false, false, false, false, false, true]);
+
+%!assert(!(isnan (single(Inf))));
+%!assert(isnan (single(NaN)));
+%!assert(isnan (single(NA)));
+%!assert(isnan (single(rand(1,10))), false(1,10));
+%!assert(isnan(single([NaN -Inf -1 0 1 Inf NA])), [true, false, false, false, false, false, true]);
+
+ */
+
+DEFUNX ("isprint", Fisprint, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isprint (@var{s})\n\
+Return 1 for printable characters (including the space character).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisprint ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("ispunct", Fispunct, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} ispunct (@var{s})\n\
+Return 1 for punctuation characters.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xispunct ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("isspace", Fisspace, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isspace (@var{s})\n\
+Return 1 for whitespace characters (space, formfeed, newline,\n\
+carriage return, tab, and vertical tab).\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisspace ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("isupper", Fisupper, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isupper (@var{s})\n\
+Return 1 for upper case letters.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisupper ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("isxdigit", Fisxdigit, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} isxdigit (@var{s})\n\
+Return 1 for characters that are hexadecimal digits.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xisxdigit ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (lgamma, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} lgamma (@var{x})\n\
+ at deftypefnx {Mapping Function} {} gammaln (@var{x})\n\
+Return the natural logarithm of the gamma function of @var{x}.\n\
+ at seealso{gamma, gammainc}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).lgamma ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! a = -1i*sqrt(-1/(6.4187*6.4187));
+%! assert (lgamma(a), lgamma(real(a)));
+
+%!test
+%! x = [.5, 1, 1.5, 2, 3, 4, 5];
+%! v = [sqrt(pi), 1, .5*sqrt(pi), 1, 2, 6, 24];
+%! assert(lgamma(x), log(v), sqrt(eps))
+
+%!test
+%! a = single(-1i*sqrt(-1/(6.4187*6.4187)));
+%! assert (lgamma(a), lgamma(real(a)));
+
+%!test
+%! x = single([.5, 1, 1.5, 2, 3, 4, 5]);
+%! v = single([sqrt(pi), 1, .5*sqrt(pi), 1, 2, 6, 24]);
+%! assert(lgamma(x), log(v), sqrt(eps ('single')))
+
+%!error lgamma();
+%!error lgamma(1,2);
+
+*/
+
+DEFUN (log, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} log (@var{x})\n\
+Compute the natural logarithm,\n\
+ at tex\n\
+$\\ln{(x)},$\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{ln (@var{x})},\n\
+ at end ifnottex\n\
+for each element of @var{x}.  To compute the\n\
+matrix logarithm, see @ref{Linear Algebra}.\n\
+ at seealso{exp, log1p, log2, log10, logspace}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).log ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(log ([1, e, e^2]), [0, 1, 2], sqrt (eps));
+%!assert(log ([-0.5, -1.5, -2.5]), log([0.5, 1.5, 2.5]) + pi*1i, sqrt (eps));
+
+%!assert(log (single([1, e, e^2])), single([0, 1, 2]), sqrt (eps('single')));
+%!assert(log (single([-0.5, -1.5, -2.5])), single(log([0.5, 1.5, 2.5]) + pi*1i), 4*eps('single'));
+
+%!error log ();
+%!error log (1, 2);
+
+ */
+
+DEFUN (log10, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} log10 (@var{x})\n\
+Compute the base-10 logarithm of each element of @var{x}.\n\
+ at seealso{log, log2, logspace, exp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).log10 ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(log10 ([0.01, 0.1, 1, 10, 100]), [-2, -1, 0, 1, 2], sqrt (eps));
+%!assert(log10 (single([0.01, 0.1, 1, 10, 100])), single([-2, -1, 0, 1, 2]), sqrt (eps ('single')));
+
+%!error log10 ();
+%!error log10 (1, 2);
+
+*/
+
+DEFUN (log1p, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} log1p (@var{x})\n\
+Compute\n\
+ at tex\n\
+$\\ln{(1 + x)}$\n\
+ at end tex\n\
+ at ifnottex\n\
+ at code{log (1 + @var{x})}\n\
+ at end ifnottex\n\
+accurately in the neighborhood of zero.\n\
+ at seealso{log, exp, expm1}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).log1p ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (real, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} real (@var{z})\n\
+Return the real part of @var{z}.\n\
+ at seealso{imag, conj}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).real ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(real (1), 1);
+%!assert(real (i), 0);
+%!assert(real (1+i), 1);
+%!assert(real ([1, i; i, 1]), full (eye (2)));
+
+%!assert(real (single(1)), single(1));
+%!assert(real (single(i)), single(0));
+%!assert(real (single(1+i)), single(1));
+%!assert(real (single([1, i; i, 1])), full (eye (2,'single')));
+
+%!error real ();
+%!error real (1, 2);
+
+*/
+
+DEFUN (round, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} round (@var{x})\n\
+Return the integer nearest to @var{x}.  If @var{x} is complex, return\n\
+ at code{round (real (@var{x})) + round (imag (@var{x})) * I}.\n\
+ at example\n\
+ at group\n\
+round ([-2.7, 2.7])\n\
+     @result{} -3   3\n\
+ at end group\n\
+ at end example\n\
+ at seealso{ceil, floor, fix}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).round ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(round (1), 1);
+%!assert(round (1.1), 1);
+%!assert(round (5.5), 6);
+%!assert(round (i), i);
+%!assert(round (2.5+3.5i), 3+4i);
+%!assert(round (-2.6), -3);
+%!assert(round ([1.1, -2.4; -3.7, 7.1]), [1, -2; -4, 7]);
+
+%!assert(round (single(1)), single(1));
+%!assert(round (single(1.1)), single(1));
+%!assert(round (single(5.5)), single(6));
+%!assert(round (single(i)), single(i));
+%!assert(round (single(2.5+3.5i)), single(3+4i));
+%!assert(round (single(-2.6)), single(-3));
+%!assert(round (single([1.1, -2.4; -3.7, 7.1])), single([1, -2; -4, 7]));
+
+%!error round ();
+%!error round (1, 2);
+
+*/
+
+DEFUN (roundb, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} roundb (@var{x})\n\
+Return the integer nearest to @var{x}.  If there are two nearest\n\
+integers, return the even one (banker's rounding).  If @var{x} is complex,\n\
+return @code{roundb (real (@var{x})) + roundb (imag (@var{x})) * I}.\n\
+ at seealso{round}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).roundb ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (sign, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} sign (@var{x})\n\
+Compute the @dfn{signum} function, which is defined as\n\
+ at tex\n\
+$$\n\
+{\\rm sign} (@var{x}) = \\cases{1,&$x>0$;\\cr 0,&$x=0$;\\cr -1,&$x<0$.\\cr}\n\
+$$\n\
+ at end tex\n\
+ at ifnottex\n\
+\n\
+ at example\n\
+ at group\n\
+           -1, x < 0;\n\
+sign (x) =  0, x = 0;\n\
+            1, x > 0.\n\
+ at end group\n\
+ at end example\n\
+ at end ifnottex\n\
+\n\
+For complex arguments, @code{sign} returns @code{x ./ abs (@var{x})}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).signum ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(sign (-2) , -1);
+%!assert(sign (3), 1);
+%!assert(sign (0), 0);
+%!assert(sign ([1, -pi; e, 0]), [1, -1; 1, 0]);
+
+%!assert(sign (single(-2)) , single(-1));
+%!assert(sign (single(3)), single(1));
+%!assert(sign (single(0)), single(0));
+%!assert(sign (single([1, -pi; e, 0])), single([1, -1; 1, 0]));
+
+%!error sign ();
+%!error sign (1, 2);
+
+*/
+
+DEFUN (sin, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} sin (@var{x})\n\
+Compute the sine for each element of @var{x} in radians.\n\
+ at seealso{asin, sind, sinh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).sin ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi];
+%! v = [0, 1/2, rt2/2, rt3/2, 1, rt3/2, rt2/2, 1/2, 0];
+%! assert(sin (x), v, sqrt (eps));
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = single([0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi]);
+%! v = single([0, 1/2, rt2/2, rt3/2, 1, rt3/2, rt2/2, 1/2, 0]);
+%! assert(sin (x), v, sqrt (eps('single')));
+
+%!error sin ();
+%!error sin (1, 2);
+
+*/
+
+DEFUN (sinh, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} sinh (@var{x})\n\
+Compute the hyperbolic sine for each element of @var{x}.\n\
+ at seealso{asinh, cosh, tanh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).sinh ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! x = [0, pi/2*i, pi*i, 3*pi/2*i];
+%! v = [0, i, 0, -i];
+%! assert(sinh (x), v, sqrt (eps));
+
+%!test
+%! x = single([0, pi/2*i, pi*i, 3*pi/2*i]);
+%! v = single([0, i, 0, -i]);
+%! assert(sinh (x), v, sqrt (eps('single')));
+
+%!error sinh ();
+%!error sinh (1, 2);
+
+ */
+
+DEFUN (sqrt, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} sqrt (@var{x})\n\
+Compute the square root of each element of @var{x}.  If @var{x} is negative,\n\
+a complex result is returned.  To compute the matrix square root, see\n\
+ at ref{Linear Algebra}.\n\
+ at seealso{realsqrt}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).sqrt ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert(sqrt (4), 2)
+%!assert(sqrt (-1), i)
+%!assert(sqrt (1+i), exp (0.5 * log (1+i)), sqrt (eps));
+%!assert(sqrt([4, -4; i, 1-i]), [2, 2i; exp(0.5 * log (i)), exp(0.5 * log (1-i))], sqrt(eps));
+
+%!assert(sqrt (single(4)), single(2))
+%!assert(sqrt (single(-1)), single(i))
+%!assert(sqrt (single(1+i)), single(exp (0.5 * log (1+i))), sqrt (eps('single')));
+%!assert(sqrt(single([4, -4; i, 1-i])), single([2, 2i; exp(0.5 * log (i)), exp(0.5 * log (1-i))]), sqrt(eps('single')));
+
+%!error sqrt ();
+%!error sqrt (1, 2);
+
+*/
+
+DEFUN (tan, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} tan (@var{z})\n\
+Compute the tangent for each element of @var{x} in radians.\n\
+ at seealso{atan, tand, tanh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).tan ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = [0, pi/6, pi/4, pi/3, 2*pi/3, 3*pi/4, 5*pi/6, pi];
+%! v = [0, rt3/3, 1, rt3, -rt3, -1, -rt3/3, 0];
+%! assert(tan (x), v,  sqrt (eps));
+
+%!test
+%! rt2 = sqrt (2);
+%! rt3 = sqrt (3);
+%! x = single([0, pi/6, pi/4, pi/3, 2*pi/3, 3*pi/4, 5*pi/6, pi]);
+%! v = single([0, rt3/3, 1, rt3, -rt3, -1, -rt3/3, 0]);
+%! assert(tan (x), v,  sqrt (eps('single')));
+
+%!error tan ();
+%!error tan (1, 2);
+
+*/
+
+DEFUN (tanh, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} tanh (@var{x})\n\
+Compute hyperbolic tangent for each element of @var{x}.\n\
+ at seealso{atanh, sinh, cosh}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).tanh ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! x = [0, pi*i];
+%! v = [0, 0];
+%! assert(tanh (x), v, sqrt (eps));
+
+%!test
+%! x = single([0, pi*i]);
+%! v = single([0, 0]);
+%! assert(tanh (x), v, sqrt (eps('single')));
+
+%!error tanh ();
+%!error tanh (1, 2);
+
+*/
+
+DEFUNX ("toascii", Ftoascii, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} toascii (@var{s})\n\
+Return ASCII representation of @var{s} in a matrix.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+toascii (\"ASCII\")\n\
+     @result{} [ 65, 83, 67, 73, 73 ]\n\
+ at end group\n\
+\n\
+ at end example\n\
+ at seealso{char}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xtoascii ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("tolower", Ftolower, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Mapping Function} {} tolower (@var{s})\n\
+ at deftypefnx {Mapping Function} {} lower (@var{s})\n\
+Return a copy of the string or cell string @var{s}, with each upper-case\n\
+character replaced by the corresponding lower-case one; non-alphabetic\n\
+characters are left unchanged.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+tolower (\"MiXeD cAsE 123\")\n\
+     @result{} \"mixed case 123\"\n\
+ at end group\n\
+ at end example\n\
+ at seealso{toupper}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xtolower ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFALIAS (lower, tolower);
+
+/*
+ 
+%!error <Invalid call to tolower.*> tolower();
+%!error <Invalid call to tolower.*> lower();
+%!assert(tolower("OCTAVE"), "octave");
+%!assert(tolower("123OCTave!_&"), "123octave!_&");
+%!assert(tolower({"ABC", "DEF", {"GHI", {"JKL"}}}), {"abc", "def", {"ghi", {"jkl"}}});
+%!assert(tolower(["ABC"; "DEF"]), ["abc"; "def"]);
+%!assert(tolower({["ABC"; "DEF"]}), {["abc";"def"]});
+%!assert(tolower(68), "d");
+%!assert(tolower({[68, 68; 68, 68]}), {["dd";"dd"]});
+%!test
+%!  a(3,3,3,3) = "D";
+%!  assert(tolower(a)(3,3,3,3), "d");
+
+*/
+
+
+DEFUNX ("toupper", Ftoupper, args, ,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} toupper (@var{s})\n\
+ at deftypefnx {Built-in Function} {} upper (@var{s})\n\
+Return a copy of the string or cell string @var{s}, with each lower-case\n\
+character replaced by the corresponding upper-case one; non-alphabetic\n\
+characters are left unchanged.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+toupper (\"MiXeD cAsE 123\")\n\
+     @result{} \"MIXED CASE 123\"\n\
+ at end group\n\
+ at end example\n\
+ at seealso{tolower}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).xtoupper ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFALIAS (upper, toupper);
+
+/*
+ 
+%!error <Invalid call to toupper.*> toupper();
+%!error <Invalid call to toupper.*> upper();
+%!assert(toupper("octave"), "OCTAVE");
+%!assert(toupper("123OCTave!_&"), "123OCTAVE!_&");
+%!assert(toupper({"abc", "def", {"ghi", {"jkl"}}}), {"ABC", "DEF", {"GHI", {"JKL"}}});
+%!assert(toupper(["abc"; "def"]), ["ABC"; "DEF"]);
+%!assert(toupper({["abc"; "def"]}), {["ABC";"DEF"]});
+%!assert(toupper(100), "D");
+%!assert(toupper({[100, 100; 100, 100]}), {["DD";"DD"]});
+%!test
+%!  a(3,3,3,3) = "d";
+%!  assert(toupper(a)(3,3,3,3), "D");
+
+*/
+
+DEFALIAS (gammaln, lgamma);
+
+DEFALIAS (isfinite, finite);
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/matherr.c b/src/matherr.c
new file mode 100644
index 0000000..568db44
--- /dev/null
+++ b/src/matherr.c
@@ -0,0 +1,59 @@
+/*
+
+Copyright (C) 1997, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (EXCEPTION_IN_MATH)
+
+#include "lo-math.h"
+
+int
+matherr (struct exception *x)
+{
+  /* Possibly print our own message someday.  Should probably be
+     user-switchable. */
+
+  switch (x->type)
+    {
+    case DOMAIN:
+    case SING:
+    case OVERFLOW:
+    case UNDERFLOW:
+    case TLOSS:
+    case PLOSS:
+    default:
+      break;
+    }
+
+  /* But don't print the system message. */
+
+  return 1;
+}
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/src/mex.cc b/src/mex.cc
new file mode 100644
index 0000000..a721510
--- /dev/null
+++ b/src/mex.cc
@@ -0,0 +1,3466 @@
+/*
+
+Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <config.h>
+
+#include <cfloat>
+#include <csetjmp>
+#include <cstdarg>
+#include <cstdlib>
+#include <cstring>
+#include <cctype>
+
+#include <set>
+
+#include "f77-fcn.h"
+#include "lo-ieee.h"
+#include "oct-locbuf.h"
+
+// mxArray must be declared as a class before including mexproto.h.
+class mxArray;
+#include "Cell.h"
+#include "mexproto.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-mex-fcn.h"
+#include "ov-usr-fcn.h"
+#include "pager.h"
+#include "parse.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "graphics.h"
+
+// #define DEBUG 1
+
+static void
+xfree (void *ptr)
+{
+  ::free (ptr);
+}
+
+static mwSize
+max_str_len (mwSize m, const char **str)
+{
+  int max_len = 0;
+
+  for (mwSize i = 0; i < m; i++)
+    {
+      mwSize tmp = strlen (str[i]);
+
+      if (tmp > max_len)
+	max_len = tmp;
+    }
+
+  return max_len;
+}
+
+static int
+valid_key (const char *key)
+{
+  int retval = 0;
+
+  int nel = strlen (key);
+
+  if (nel > 0)
+    {
+      if (isalpha (key[0]))
+	{
+	  for (int i = 1; i < nel; i++)
+	    {
+	      if (! (isalnum (key[i]) || key[i] == '_'))
+		goto done;
+	    }
+
+	  retval = 1;
+	}
+    }
+
+ done:
+
+  return retval;
+}
+
+// ------------------------------------------------------------------
+
+// A class to provide the default implemenation of some of the virtual
+// functions declared in the mxArray class.
+
+class mxArray_base : public mxArray
+{
+protected:
+
+  mxArray_base (void) : mxArray (xmxArray ()) { }
+
+public:
+
+  mxArray *clone (void) const = 0;
+
+  ~mxArray_base (void) { }
+
+  bool is_octave_value (void) const { return false; }
+
+  int is_cell (void) const = 0;
+
+  int is_char (void) const = 0;
+
+  int is_class (const char *name_arg) const
+  {
+    int retval = 0;
+
+    const char *cname = get_class_name ();
+
+    if (cname && name_arg)
+      retval = ! strcmp (cname, name_arg);
+
+    return retval;
+  }
+
+  int is_complex (void) const = 0;
+
+  int is_double (void) const = 0;
+
+  int is_int16 (void) const = 0;
+
+  int is_int32 (void) const = 0;
+
+  int is_int64 (void) const = 0;
+
+  int is_int8 (void) const = 0;
+
+  int is_logical (void) const = 0;
+
+  int is_numeric (void) const = 0;
+
+  int is_single (void) const = 0;
+
+  int is_sparse (void) const = 0;
+
+  int is_struct (void) const = 0;
+
+  int is_uint16 (void) const = 0;
+
+  int is_uint32 (void) const = 0;
+
+  int is_uint64 (void) const = 0;
+
+  int is_uint8 (void) const = 0;
+
+  int is_logical_scalar (void) const
+  {
+    return is_logical () && get_number_of_elements () == 1;
+  }
+
+  int is_logical_scalar_true (void) const = 0;
+
+  mwSize get_m (void) const = 0;
+
+  mwSize get_n (void) const = 0;
+
+  mwSize *get_dimensions (void) const = 0;
+
+  mwSize get_number_of_dimensions (void) const = 0;
+
+  void set_m (mwSize m) = 0;
+
+  void set_n (mwSize n) = 0;
+
+  void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0;
+
+  mwSize get_number_of_elements (void) const = 0;
+
+  int is_empty (void) const = 0;
+
+  mxClassID get_class_id (void) const = 0;
+
+  const char *get_class_name (void) const = 0;
+
+  void set_class_name (const char *name_arg) = 0;
+
+  mxArray *get_cell (mwIndex /*idx*/) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void set_cell (mwIndex idx, mxArray *val) = 0;
+
+  double get_scalar (void) const = 0;
+
+  void *get_data (void) const = 0;
+
+  void *get_imag_data (void) const = 0;
+
+  void set_data (void *pr) = 0;
+
+  void set_imag_data (void *pi) = 0;
+
+  mwIndex *get_ir (void) const = 0;
+
+  mwIndex *get_jc (void) const = 0;
+
+  mwSize get_nzmax (void) const = 0;
+
+  void set_ir (mwIndex *ir) = 0;
+
+  void set_jc (mwIndex *jc) = 0;
+
+  void set_nzmax (mwSize nzmax) = 0;
+
+  int add_field (const char *key) = 0;
+
+  void remove_field (int key_num) = 0;
+
+  mxArray *get_field_by_number (mwIndex index, int key_num) const = 0;
+
+  void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0;
+
+  int get_number_of_fields (void) const = 0;
+
+  const char *get_field_name_by_number (int key_num) const = 0;
+
+  int get_field_number (const char *key) const = 0;
+
+  int get_string (char *buf, mwSize buflen) const = 0;
+
+  char *array_to_string (void) const = 0;
+
+  mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0;
+
+  size_t get_element_size (void) const = 0;
+
+  bool mutation_needed (void) const { return false; }
+
+  mxArray *mutate (void) const { return 0; }
+
+protected:
+
+  octave_value as_octave_value (void) const = 0;
+
+  mxArray_base (const mxArray_base&) : mxArray (xmxArray ()) { }
+
+  void invalid_type_error (void) const
+  {
+    error ("invalid type for operation");
+  }
+
+  void error (const char *msg) const
+  {
+    // FIXME
+    ::error ("%s", msg);
+  }
+};
+
+static mwIndex
+calc_single_subscript_internal (mwSize ndims, const mwSize *dims,
+				mwSize nsubs, const mwIndex *subs)
+{
+  mwIndex retval = 0;
+
+  switch (nsubs)
+    {
+    case 0:
+      break;
+
+    case 1:
+      retval = subs[0];
+      break;
+
+    default:
+      {
+	// Both nsubs and ndims should be at least 2 here.
+
+	mwSize n = nsubs <= ndims ? nsubs : ndims;
+
+	retval = subs[--n];
+
+	while (--n >= 0)
+	  retval = dims[n] * retval + subs[n];
+      }
+      break;
+    }
+
+  return retval;
+}
+
+// The object that handles values pass to MEX files from Octave.  Some
+// methods in this class may set mutate_flag to TRUE to tell the
+// mxArray class to convert to the Matlab-style representation and
+// then invoke the method on that object instead (for example, getting
+// a pointer to real or imaginary data from a complex object requires
+// a mutation but getting a pointer to real data from a real object
+// does not).  Changing the representation causes a copy so we try to
+// avoid it unless it is really necessary.  Once the conversion
+// happens, we delete this representation, so the conversion can only
+// happen once per call to a MEX file.
+
+static inline void *maybe_mark_foreign (void *ptr);
+
+class mxArray_octave_value : public mxArray_base
+{
+public:
+
+  mxArray_octave_value (const octave_value& ov)
+    : mxArray_base (), val (ov), mutate_flag (false),
+      id (mxUNKNOWN_CLASS), class_name (0), ndims (-1), dims (0) { }
+
+  mxArray *clone (void) const { return new mxArray_octave_value (*this); }
+
+  ~mxArray_octave_value (void)
+  {
+    mxFree (class_name);
+    mxFree (dims);
+  }
+
+  bool is_octave_value (void) const { return true; }
+
+  int is_cell (void) const { return val.is_cell (); }
+
+  int is_char (void) const { return val.is_string (); }
+
+  int is_complex (void) const { return val.is_complex_type (); }
+
+  int is_double (void) const { return val.is_double_type (); }
+
+  int is_int16 (void) const { return val.is_int16_type (); }
+
+  int is_int32 (void) const { return val.is_int32_type (); }
+
+  int is_int64 (void) const { return val.is_int64_type (); }
+
+  int is_int8 (void) const { return val.is_int8_type (); }
+
+  int is_logical (void) const { return val.is_bool_type (); }
+
+  int is_numeric (void) const { return val.is_numeric_type (); }
+
+  int is_single (void) const { return val.is_single_type (); }
+
+  int is_sparse (void) const { return val.is_sparse_type (); }
+
+  int is_struct (void) const { return val.is_map (); }
+
+  int is_uint16 (void) const { return val.is_uint16_type (); }
+
+  int is_uint32 (void) const { return val.is_uint32_type (); }
+
+  int is_uint64 (void) const { return val.is_uint64_type (); }
+
+  int is_uint8 (void) const { return val.is_uint8_type (); }
+
+  int is_range (void) const { return val.is_range (); }
+
+  int is_real_type (void) const { return val.is_real_type (); }
+
+  int is_logical_scalar_true (void) const
+  {
+    return (is_logical_scalar () && val.is_true ());
+  }
+
+  mwSize get_m (void) const { return val.rows (); }
+
+  mwSize get_n (void) const 
+  {
+    mwSize n = 1;
+
+    // Force dims and ndims to be cached.
+    get_dimensions();
+
+    for (mwIndex i = ndims - 1; i > 0; i--)
+      n *= dims[i];
+
+    return n;
+  }
+
+  mwSize *get_dimensions (void) const
+  {
+    if (! dims)
+      {
+	ndims = val.ndims ();
+
+	dims = static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)));
+
+	dim_vector dv = val.dims ();
+
+	for (mwIndex i = 0; i < ndims; i++)
+	  dims[i] = dv(i);
+      }
+
+    return dims;
+  }
+
+  mwSize get_number_of_dimensions (void) const
+  {
+    // Force dims and ndims to be cached.
+    get_dimensions ();
+
+    return ndims;
+  }
+
+  void set_m (mwSize /*m*/) { request_mutation (); }
+
+  void set_n (mwSize /*n*/) { request_mutation (); }
+
+  void set_dimensions (mwSize */*dims_arg*/, mwSize /*ndims_arg*/)
+  {
+    request_mutation ();
+  }
+
+  mwSize get_number_of_elements (void) const { return val.numel (); }
+
+  int is_empty (void) const { return val.is_empty (); }
+
+  mxClassID get_class_id (void) const
+  {
+    id = mxUNKNOWN_CLASS;
+
+    std::string cn = val.class_name ();
+
+    if (cn == "cell")
+      id = mxCELL_CLASS;
+    else if (cn == "struct")
+      id = mxSTRUCT_CLASS;
+    else if (cn == "logical")
+      id = mxLOGICAL_CLASS;
+    else if (cn == "char")
+      id = mxCHAR_CLASS;
+    else if (cn == "double")
+      id = mxDOUBLE_CLASS;
+    else if (cn == "single")
+      id = mxSINGLE_CLASS;
+    else if (cn == "int8")
+      id = mxINT8_CLASS;
+    else if (cn == "uint8")
+      id = mxUINT8_CLASS;
+    else if (cn == "int16")
+      id = mxINT16_CLASS;
+    else if (cn == "uint16")
+      id = mxUINT16_CLASS;
+    else if (cn == "int32")
+      id = mxINT32_CLASS;
+    else if (cn == "uint32")
+      id = mxUINT32_CLASS;
+    else if (cn == "int64")
+      id = mxINT64_CLASS;
+    else if (cn == "uint64")
+      id = mxUINT64_CLASS;
+    else if (cn == "function_handle")
+      id = mxFUNCTION_CLASS;
+
+    return id;
+  }
+
+  const char *get_class_name (void) const
+  {
+    if (! class_name)
+      {
+	std::string s = val.class_name ();
+	class_name = strsave (s.c_str ());
+      }
+
+    return class_name;
+  }
+
+  // Not allowed.
+  void set_class_name (const char */*name_arg*/) { request_mutation (); }
+
+  mxArray *get_cell (mwIndex /*idx*/) const
+  {
+    request_mutation ();
+    return 0;
+  }
+
+  // Not allowed.
+  void set_cell (mwIndex /*idx*/, mxArray */*val*/) { request_mutation (); }
+
+  double get_scalar (void) const { return val.scalar_value (true); }
+
+  void *get_data (void) const
+  {
+    void *retval = val.mex_get_data ();
+
+    if (retval)
+      maybe_mark_foreign (retval);
+    else
+      request_mutation ();
+
+    return retval;
+  }
+
+  void *get_imag_data (void) const
+  {
+    void *retval = 0;
+
+    if (is_numeric () && is_real_type ())
+      retval = 0;
+    else
+      request_mutation ();
+
+    return retval;
+  }
+
+  // Not allowed.
+  void set_data (void */*pr*/) { request_mutation (); }
+
+  // Not allowed.
+  void set_imag_data (void */*pi*/) { request_mutation (); }
+
+  mwIndex *get_ir (void) const
+  {
+    return static_cast<mwIndex *> (maybe_mark_foreign (val.mex_get_ir ()));
+  }
+
+  mwIndex *get_jc (void) const
+  {
+    return static_cast<mwIndex *> (maybe_mark_foreign (val.mex_get_jc ()));
+  }
+
+  mwSize get_nzmax (void) const { return val.nzmax (); }
+
+  // Not allowed.
+  void set_ir (mwIndex */*ir*/) { request_mutation (); }
+
+  // Not allowed.
+  void set_jc (mwIndex */*jc*/) { request_mutation (); }
+
+  // Not allowed.
+  void set_nzmax (mwSize /*nzmax*/) { request_mutation (); }
+
+  // Not allowed.
+  int add_field (const char */*key*/)
+  {
+    request_mutation ();
+    return 0;
+  }
+
+  // Not allowed.
+  void remove_field (int /*key_num*/) { request_mutation (); }
+
+  mxArray *get_field_by_number (mwIndex /*index*/, int /*key_num*/) const
+  {
+    request_mutation ();
+    return 0;
+  }
+
+  // Not allowed.
+  void set_field_by_number (mwIndex /*index*/, int /*key_num*/, mxArray */*val*/)
+  {
+    request_mutation ();
+  }
+
+  int get_number_of_fields (void) const { return val.nfields (); }
+
+  const char *get_field_name_by_number (int /*key_num*/) const
+  {
+    request_mutation ();
+    return 0;
+  }
+
+  int get_field_number (const char */*key*/) const
+  {
+    request_mutation ();
+    return 0;
+  }
+
+  int get_string (char *buf, mwSize buflen) const
+  {
+    int retval = 1;
+
+    mwSize nel = get_number_of_elements ();
+
+    if (val.is_string () && nel < buflen)
+      {
+	charNDArray tmp = val.char_array_value ();
+
+	const char *p = tmp.data ();
+
+	for (mwIndex i = 0; i < nel; i++)
+	  buf[i] = p[i];
+
+	buf[nel] = 0;
+
+	retval = 0;
+      }
+
+    return retval;
+  }
+
+  char *array_to_string (void) const
+  {
+    // FIXME -- this is suposed to handle multi-byte character
+    // strings.
+
+    char *buf = 0;
+
+    if (val.is_string ())
+      {
+	mwSize nel = get_number_of_elements ();
+
+	buf = static_cast<char *> (malloc (nel + 1));
+
+	if (buf)
+	  {
+	    charNDArray tmp = val.char_array_value ();
+
+	    const char *p = tmp.data ();
+
+	    for (mwIndex i = 0; i < nel; i++)
+	      buf[i] = p[i];
+
+	    buf[nel] = '\0';
+	  }
+      }
+
+    return buf;
+  }
+
+  mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const
+  {
+    // Force ndims, dims to be cached.
+    get_dimensions ();
+
+    return calc_single_subscript_internal (ndims, dims, nsubs, subs);
+  }
+
+  size_t get_element_size (void) const
+  {
+    // Force id to be cached.
+    get_class_id ();
+
+    switch (id)
+      {
+      case mxCELL_CLASS: return sizeof (mxArray *);
+      case mxSTRUCT_CLASS: return sizeof (mxArray *);
+      case mxLOGICAL_CLASS: return sizeof (mxLogical);
+      case mxCHAR_CLASS: return sizeof (mxChar);
+      case mxDOUBLE_CLASS: return sizeof (double);
+      case mxSINGLE_CLASS: return sizeof (float);
+      case mxINT8_CLASS: return 1;
+      case mxUINT8_CLASS: return 1;
+      case mxINT16_CLASS: return 2;
+      case mxUINT16_CLASS: return 2;
+      case mxINT32_CLASS: return 4;
+      case mxUINT32_CLASS: return 4;
+      case mxINT64_CLASS: return 8;
+      case mxUINT64_CLASS: return 8;
+      case mxFUNCTION_CLASS: return 0;
+      default: return 0;
+      }    
+  }
+
+  bool mutation_needed (void) const { return mutate_flag; }
+
+  void request_mutation (void) const
+  {
+    if (mutate_flag)
+      panic_impossible ();
+
+    mutate_flag = true;
+  }
+
+  mxArray *mutate (void) const { return val.as_mxArray (); }
+
+protected:
+
+  octave_value as_octave_value (void) const { return val; }
+
+  mxArray_octave_value (const mxArray_octave_value& arg)
+    : mxArray_base (arg), val (arg.val), mutate_flag (arg.mutate_flag),
+      id (arg.id), class_name (strsave (arg.class_name)), ndims (arg.ndims),
+      dims (ndims > 0 ? static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))) : 0)
+  {
+    if (dims)
+      {
+	for (mwIndex i = 0; i < ndims; i++)
+	  dims[i] = arg.dims[i];
+      }
+  }
+
+private:
+
+  octave_value val;
+
+  mutable bool mutate_flag;
+
+  // Caching these does not cost much or lead to much duplicated
+  // code.  For other things, we just request mutation to a
+  // Matlab-style mxArray object.
+
+  mutable mxClassID id;
+  mutable char *class_name;
+  mutable mwSize ndims;
+  mutable mwSize *dims;
+};
+
+// The base class for the Matlab-style representation, used to handle
+// things that are common to all Matlab-style objects.
+
+class mxArray_matlab : public mxArray_base
+{
+protected:
+
+  mxArray_matlab (mxClassID id_arg = mxUNKNOWN_CLASS)
+    : mxArray_base (), class_name (0), id (id_arg), ndims (0), dims (0) { }
+
+  mxArray_matlab (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg)
+    : mxArray_base (), class_name (0), id (id_arg),
+      ndims (ndims_arg < 2 ? 2 : ndims_arg),
+      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+  {
+    if (ndims_arg < 2)
+      {
+	dims[0] = 1;
+	dims[1] = 1;
+      }
+
+    for (mwIndex i = 0; i < ndims_arg; i++)
+      dims[i] = dims_arg[i];
+
+    for (mwIndex i = ndims - 1; i > 1; i--)
+      {
+	if (dims[i] == 1)
+	  ndims--;
+	else
+	  break;
+      }
+  }
+
+  mxArray_matlab (mxClassID id_arg, const dim_vector& dv)
+    : mxArray_base (), class_name (0), id (id_arg),
+      ndims (dv.length ()),
+      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+  {
+    for (mwIndex i = 0; i < ndims; i++)
+      dims[i] = dv(i);
+
+    for (mwIndex i = ndims - 1; i > 1; i--)
+      {
+	if (dims[i] == 1)
+	  ndims--;
+	else
+	  break;
+      }
+  }
+
+  mxArray_matlab (mxClassID id_arg, mwSize m, mwSize n)
+    : mxArray_base (), class_name (0), id (id_arg), ndims (2),
+      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+  {
+    dims[0] = m;
+    dims[1] = n;
+  }
+
+public:
+
+  ~mxArray_matlab (void)
+  {
+    mxFree (class_name);
+    mxFree (dims);
+  }
+
+  int is_cell (void) const { return id == mxCELL_CLASS; }
+
+  int is_char (void) const { return id == mxCHAR_CLASS; }
+
+  int is_complex (void) const { return 0; }
+
+  int is_double (void) const { return id == mxDOUBLE_CLASS; }
+
+  int is_int16 (void) const { return id == mxINT16_CLASS; }
+
+  int is_int32 (void) const { return id == mxINT32_CLASS; }
+
+  int is_int64 (void) const { return id == mxINT64_CLASS; }
+
+  int is_int8 (void) const { return id == mxINT8_CLASS; }
+
+  int is_logical (void) const { return id == mxLOGICAL_CLASS; }
+
+  int is_numeric (void) const
+  {
+    return (id == mxDOUBLE_CLASS || id == mxSINGLE_CLASS
+	    || id == mxINT8_CLASS || id == mxUINT8_CLASS
+	    || id == mxINT16_CLASS || id == mxUINT16_CLASS
+	    || id == mxINT32_CLASS || id == mxUINT32_CLASS
+	    || id == mxINT64_CLASS || id == mxUINT64_CLASS);
+  }
+
+  int is_single (void) const { return id == mxSINGLE_CLASS; }
+
+  int is_sparse (void) const { return 0; }
+
+  int is_struct (void) const { return id == mxSTRUCT_CLASS; }
+
+  int is_uint16 (void) const { return id == mxUINT16_CLASS; }
+
+  int is_uint32 (void) const { return id == mxUINT32_CLASS; }
+
+  int is_uint64 (void) const { return id == mxUINT64_CLASS; }
+
+  int is_uint8 (void) const { return id == mxUINT8_CLASS; }
+
+  int is_logical_scalar_true (void) const
+  {
+    return (is_logical_scalar ()
+	    && static_cast<mxLogical *> (get_data ())[0] != 0);
+  }
+
+  mwSize get_m (void) const { return dims[0]; }
+
+  mwSize get_n (void) const
+  {
+    mwSize n = 1;
+
+    for (mwSize i = ndims - 1 ; i > 0 ; i--)
+      n *= dims[i];
+
+    return n;
+  }
+
+  mwSize *get_dimensions (void) const { return dims; }
+
+  mwSize get_number_of_dimensions (void) const { return ndims; }
+
+  void set_m (mwSize m) { dims[0] = m; }
+
+  void set_n (mwSize n) { dims[1] = n; }
+
+  void set_dimensions (mwSize *dims_arg, mwSize ndims_arg)
+  {
+    dims = dims_arg;
+    ndims = ndims_arg;
+  }
+
+  mwSize get_number_of_elements (void) const
+  {
+    mwSize retval = dims[0];
+
+    for (mwIndex i = 1; i < ndims; i++)
+      retval *= dims[i];
+
+    return retval;
+  }
+
+  int is_empty (void) const { return get_number_of_elements () == 0; }
+
+  mxClassID get_class_id (void) const { return id; }
+
+  const char *get_class_name (void) const
+  {
+    switch (id)
+      {
+      case mxCELL_CLASS: return "cell";
+      case mxSTRUCT_CLASS: return "struct";
+      case mxLOGICAL_CLASS: return "logical";
+      case mxCHAR_CLASS: return "char";
+      case mxDOUBLE_CLASS: return "double";
+      case mxSINGLE_CLASS: return "single";
+      case mxINT8_CLASS: return "int8";
+      case mxUINT8_CLASS: return "uint8";
+      case mxINT16_CLASS: return "int16";
+      case mxUINT16_CLASS: return "uint16";
+      case mxINT32_CLASS: return "int32";
+      case mxUINT32_CLASS: return "uint32";
+      case mxINT64_CLASS: return "int64";
+      case mxUINT64_CLASS: return "uint64";
+      case mxFUNCTION_CLASS: return "function_handle";
+      default: return "unknown";
+      }
+  }
+
+  void set_class_name (const char *name_arg)
+  {
+    mxFree (class_name);
+    class_name = static_cast<char *> (malloc (strlen (name_arg) + 1));
+    strcpy (class_name, name_arg);
+  }
+
+  mxArray *get_cell (mwIndex /*idx*/) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void set_cell (mwIndex /*idx*/, mxArray */*val*/)
+  {
+    invalid_type_error ();
+  }
+
+  double get_scalar (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void *get_data (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void *get_imag_data (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void set_data (void */*pr*/)
+  {
+    invalid_type_error ();
+  }
+
+  void set_imag_data (void */*pi*/)
+  {
+    invalid_type_error ();
+  }
+
+  mwIndex *get_ir (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  mwIndex *get_jc (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  mwSize get_nzmax (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void set_ir (mwIndex */*ir*/)
+  {
+    invalid_type_error ();
+  }
+
+  void set_jc (mwIndex */*jc*/)
+  {
+    invalid_type_error ();
+  }
+
+  void set_nzmax (mwSize /*nzmax*/)
+  {
+    invalid_type_error ();
+  }
+
+  int add_field (const char */*key*/)
+  {
+    invalid_type_error ();
+    return -1;
+  }
+
+  void remove_field (int /*key_num*/)
+  {
+    invalid_type_error ();
+  }
+
+  mxArray *get_field_by_number (mwIndex /*index*/, int /*key_num*/) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  void set_field_by_number (mwIndex /*index*/, int /*key_num*/, mxArray */*val*/)
+  {
+    invalid_type_error ();
+  }
+
+  int get_number_of_fields (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  const char *get_field_name_by_number (int /*key_num*/) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  int get_field_number (const char */*key*/) const
+  {
+    return -1;
+  }
+
+  int get_string (char */*buf*/, mwSize /*buflen*/) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  char *array_to_string (void) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const
+  {
+    return calc_single_subscript_internal (ndims, dims, nsubs, subs);
+  }
+
+  size_t get_element_size (void) const
+  {
+    switch (id)
+      {
+      case mxCELL_CLASS: return sizeof (mxArray *);
+      case mxSTRUCT_CLASS: return sizeof (mxArray *);
+      case mxLOGICAL_CLASS: return sizeof (mxLogical);
+      case mxCHAR_CLASS: return sizeof (mxChar);
+      case mxDOUBLE_CLASS: return sizeof (double);
+      case mxSINGLE_CLASS: return sizeof (float);
+      case mxINT8_CLASS: return 1;
+      case mxUINT8_CLASS: return 1;
+      case mxINT16_CLASS: return 2;
+      case mxUINT16_CLASS: return 2;
+      case mxINT32_CLASS: return 4;
+      case mxUINT32_CLASS: return 4;
+      case mxINT64_CLASS: return 8;
+      case mxUINT64_CLASS: return 8;
+      case mxFUNCTION_CLASS: return 0;
+      default: return 0;
+      }    
+  }
+
+protected:
+
+  mxArray_matlab (const mxArray_matlab& val)
+    : mxArray_base (val), class_name (strsave (val.class_name)),
+      id (val.id), ndims (val.ndims),
+      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+  {
+    for (mwIndex i = 0; i < ndims; i++)
+      dims[i] = val.dims[i];
+  }
+
+  dim_vector
+  dims_to_dim_vector (void) const
+  {
+    mwSize nd = get_number_of_dimensions ();
+
+    mwSize *d = get_dimensions ();
+
+    dim_vector dv;
+    dv.resize (nd);
+
+    for (mwIndex i = 0; i < nd; i++)
+      dv(i) = d[i];
+
+    return dv;
+  }
+
+private:
+
+  char *class_name;
+
+  mxClassID id;
+
+  mwSize ndims;
+  mwSize *dims;
+
+  void invalid_type_error (void) const
+  {
+    error ("invalid type for operation");
+  }
+};
+
+// Matlab-style numeric, character, and logical data.
+
+class mxArray_number : public mxArray_matlab
+{
+public:
+
+  mxArray_number (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg,
+		  mxComplexity flag = mxREAL)
+    : mxArray_matlab (id_arg, ndims_arg, dims_arg),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { }
+
+  mxArray_number (mxClassID id_arg, const dim_vector& dv,
+		  mxComplexity flag = mxREAL)
+    : mxArray_matlab (id_arg, dv),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { }
+
+  mxArray_number (mxClassID id_arg, mwSize m, mwSize n, mxComplexity flag = mxREAL)
+    : mxArray_matlab (id_arg, m, n),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { }
+
+  mxArray_number (mxClassID id_arg, double val)
+    : mxArray_matlab (id_arg, 1, 1),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (0)
+  {
+    double *dpr = static_cast<double *> (pr);
+    dpr[0] = val;
+  }
+
+  mxArray_number (mxClassID id_arg, mxLogical val)
+    : mxArray_matlab (id_arg, 1, 1),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (0)
+  {
+    mxLogical *lpr = static_cast<mxLogical *> (pr);
+    lpr[0] = val;
+  }
+
+  mxArray_number (const char *str)
+    : mxArray_matlab (mxCHAR_CLASS, 1, strlen (str)),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (0)
+  {
+    mxChar *cpr = static_cast<mxChar *> (pr);
+    mwSize nel = get_number_of_elements ();
+    for (mwIndex i = 0; i < nel; i++)
+      cpr[i] = str[i];
+  }
+
+  // FIXME??
+  mxArray_number (mwSize m, const char **str)
+    : mxArray_matlab (mxCHAR_CLASS, m, max_str_len (m, str)),
+      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pi (0)
+  {
+    mxChar *cpr = static_cast<mxChar *> (pr);
+    
+    mwSize *dv = get_dimensions ();
+
+    mwSize nc = dv[1];
+
+    for (mwIndex j = 0; j < m; j++)
+      {
+	const char *ptr = str[j];
+
+	size_t tmp_len = strlen (ptr);
+
+	for (size_t i = 0; i < tmp_len; i++)
+	  cpr[m*i+j] = static_cast<mxChar> (ptr[i]);
+
+	for (size_t i = tmp_len; i < nc; i++)
+	  cpr[m*i+j] = static_cast<mxChar> (' ');
+      }	
+  }
+
+  mxArray_number *clone (void) const { return new mxArray_number (*this); }
+
+  ~mxArray_number (void)
+  {
+    mxFree (pr);
+    mxFree (pi);
+  }
+
+  int is_complex (void) const { return pi != 0; }
+
+  double get_scalar (void) const
+  {
+    double retval = 0;
+
+    switch (get_class_id ())
+      {
+      case mxLOGICAL_CLASS:
+	retval = *(static_cast<bool *> (pr));
+	break;
+
+      case mxCHAR_CLASS:
+	retval = *(static_cast<mxChar *> (pr));
+	break;
+
+      case mxSINGLE_CLASS:
+	retval = *(static_cast<float *> (pr));
+	break;
+
+      case mxDOUBLE_CLASS:
+	retval = *(static_cast<double *> (pr));
+	break;
+
+      case mxINT8_CLASS:
+	retval = *(static_cast<int8_t *> (pr));
+	break;
+
+      case mxUINT8_CLASS:
+	retval = *(static_cast<uint8_t *> (pr));
+	break;
+
+      case mxINT16_CLASS:
+	retval = *(static_cast<int16_t *> (pr));
+	break;
+
+      case mxUINT16_CLASS:
+	retval = *(static_cast<uint16_t *> (pr));
+	break;
+
+      case mxINT32_CLASS:
+	retval = *(static_cast<int32_t *> (pr));
+	break;
+
+      case mxUINT32_CLASS:
+	retval = *(static_cast<uint32_t *> (pr));
+	break;
+
+      case mxINT64_CLASS:
+	retval = *(static_cast<int64_t *> (pr));
+	break;
+
+      case mxUINT64_CLASS:
+	retval = *(static_cast<uint64_t *> (pr));
+	break;
+
+      default:
+	panic_impossible ();
+      }
+
+    return retval;
+  }
+
+  void *get_data (void) const { return pr; }
+
+  void *get_imag_data (void) const { return pi; }
+
+  void set_data (void *pr_arg) { pr = pr_arg; }
+
+  void set_imag_data (void *pi_arg) { pi = pi_arg; }
+
+  int get_string (char *buf, mwSize buflen) const
+  {
+    int retval = 1;
+
+    mwSize nel = get_number_of_elements ();
+
+    if (nel < buflen)
+      {
+	mxChar *ptr = static_cast<mxChar *> (pr);
+
+	for (mwIndex i = 0; i < nel; i++)
+	  buf[i] = static_cast<char> (ptr[i]);
+
+	buf[nel] = 0;
+      }
+
+    return retval;
+  }
+
+  char *array_to_string (void) const
+  {
+    // FIXME -- this is suposed to handle multi-byte character
+    // strings.
+
+    mwSize nel = get_number_of_elements ();
+
+    char *buf = static_cast<char *> (malloc (nel + 1));
+
+    if (buf)
+      {
+	mxChar *ptr = static_cast<mxChar *> (pr);
+
+	for (mwIndex i = 0; i < nel; i++)
+	  buf[i] = static_cast<char> (ptr[i]);
+
+	buf[nel] = '\0';
+      }
+
+    return buf;
+  }
+
+protected:
+
+  template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T>
+  octave_value
+  int_to_ov (const dim_vector& dv) const
+  {
+    octave_value retval;
+
+    mwSize nel = get_number_of_elements ();
+
+    ELT_T *ppr = static_cast<ELT_T *> (pr);
+
+    if (pi)
+      error ("complex integer types are not supported");
+    else
+      {
+	ARRAY_T val (dv);
+
+	ARRAY_ELT_T *ptr = val.fortran_vec ();
+
+	for (mwIndex i = 0; i < nel; i++)
+	  ptr[i] = ppr[i];
+
+	retval = val;
+      }
+
+    return retval;
+  }
+
+  octave_value as_octave_value (void) const
+  {
+    octave_value retval;
+
+    dim_vector dv = dims_to_dim_vector ();
+
+    switch (get_class_id ())
+      {
+      case mxLOGICAL_CLASS:
+	retval = int_to_ov<bool, boolNDArray, bool> (dv);
+	break;
+
+      case mxCHAR_CLASS:
+	{
+	  mwSize nel = get_number_of_elements ();
+
+	  mxChar *ppr = static_cast<mxChar *> (pr);
+
+	  charNDArray val (dv);
+
+	  char *ptr = val.fortran_vec ();
+
+	  for (mwIndex i = 0; i < nel; i++)
+	    ptr[i] = static_cast<char> (ppr[i]);
+
+	  retval = octave_value (val, true, '\'');
+	}
+	break;
+
+      case mxSINGLE_CLASS:
+	{
+	  mwSize nel = get_number_of_elements ();
+
+	  float *ppr = static_cast<float *> (pr);
+
+	  if (pi)
+	    {
+	      ComplexNDArray val (dv);
+
+	      Complex *ptr = val.fortran_vec ();
+
+	      float *ppi = static_cast<float *> (pi);
+
+	      for (mwIndex i = 0; i < nel; i++)
+		ptr[i] = Complex (ppr[i], ppi[i]);
+
+	      retval = val;
+	    }
+	  else
+	    {
+	      NDArray val (dv);
+
+	      double *ptr = val.fortran_vec ();
+
+	      for (mwIndex i = 0; i < nel; i++)
+		ptr[i] = ppr[i];
+
+	      retval = val;
+	    }
+	}
+	break;
+
+      case mxDOUBLE_CLASS:
+	{
+	  mwSize nel = get_number_of_elements ();
+
+	  double *ppr = static_cast<double *> (pr);
+
+	  if (pi)
+	    {
+	      ComplexNDArray val (dv);
+
+	      Complex *ptr = val.fortran_vec ();
+
+	      double *ppi = static_cast<double *> (pi);
+
+	      for (mwIndex i = 0; i < nel; i++)
+		ptr[i] = Complex (ppr[i], ppi[i]);
+
+	      retval = val;
+	    }
+	  else
+	    {
+	      NDArray val (dv);
+
+	      double *ptr = val.fortran_vec ();
+
+	      for (mwIndex i = 0; i < nel; i++)
+		ptr[i] = ppr[i];
+
+	      retval = val;
+	    }
+	}
+	break;
+
+      case mxINT8_CLASS:
+	retval = int_to_ov<int8_t, int8NDArray, octave_int8> (dv);
+	break;
+
+      case mxUINT8_CLASS:
+	retval = int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv);
+	break;
+
+      case mxINT16_CLASS:
+	retval = int_to_ov<int16_t, int16NDArray, octave_int16> (dv);
+	break;
+
+      case mxUINT16_CLASS:
+	retval = int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv);
+	break;
+
+      case mxINT32_CLASS:
+	retval = int_to_ov<int32_t, int32NDArray, octave_int32> (dv);
+	break;
+
+      case mxUINT32_CLASS:
+	retval = int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv);
+	break;
+
+      case mxINT64_CLASS:
+	retval = int_to_ov<int64_t, int64NDArray, octave_int64> (dv);
+	break;
+
+      case mxUINT64_CLASS:
+	retval = int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv);
+	break;
+
+      default:
+	panic_impossible ();
+      }    
+
+    return retval;
+  }
+
+  mxArray_number (const mxArray_number& val)
+    : mxArray_matlab (val),
+      pr (malloc (get_number_of_elements () * get_element_size ())),
+      pi (val.pi ? malloc (get_number_of_elements () * get_element_size ()) : 0)
+  {
+    size_t nbytes = get_number_of_elements () * get_element_size ();
+
+    if (pr)
+      memcpy (pr, val.pr, nbytes);
+
+    if (pi)
+      memcpy (pi, val.pi, nbytes);
+  }
+
+private:
+
+  void *pr;
+  void *pi;
+};
+
+// Matlab-style sparse arrays.
+
+class mxArray_sparse : public mxArray_matlab
+{
+public:
+
+  mxArray_sparse (mxClassID id_arg, int m, int n, int nzmax_arg,
+		  mxComplexity flag = mxREAL)
+    : mxArray_matlab (id_arg, m, n), nzmax (nzmax_arg)
+  {
+    pr = (calloc (nzmax, get_element_size ()));
+    pi = (flag == mxCOMPLEX ? calloc (nzmax, get_element_size ()) : 0);
+    ir = static_cast<mwIndex *> (calloc (nzmax, sizeof (mwIndex)));
+    jc = static_cast<mwIndex *> (calloc (n + 1, sizeof (mwIndex)));
+  }
+
+  mxArray_sparse *clone (void) const { return new mxArray_sparse (*this); }
+
+  ~mxArray_sparse (void)
+  {
+    mxFree (pr);
+    mxFree (pi);
+    mxFree (ir);
+    mxFree (jc);
+  }
+
+  int is_complex (void) const { return pi != 0; }
+
+  int is_sparse (void) const { return 1; }
+
+  void *get_data (void) const { return pr; }
+
+  void *get_imag_data (void) const { return pi; }
+
+  void set_data (void *pr_arg) { pr = pr_arg; }
+
+  void set_imag_data (void *pi_arg) { pi = pi_arg; }
+
+  mwIndex *get_ir (void) const { return ir; }
+
+  mwIndex *get_jc (void) const { return jc; }
+
+  mwSize get_nzmax (void) const { return nzmax; }
+
+  void set_ir (mwIndex *ir_arg) { ir = ir_arg; }
+
+  void set_jc (mwIndex *jc_arg) { jc = jc_arg; }
+
+  void set_nzmax (mwSize nzmax_arg) { nzmax = nzmax_arg; }
+
+protected:
+
+  octave_value as_octave_value (void) const
+  {
+    octave_value retval;
+
+    dim_vector dv = dims_to_dim_vector ();
+
+    switch (get_class_id ())
+      {
+      case mxLOGICAL_CLASS:
+	{
+	  bool *ppr = static_cast<bool *> (pr);
+
+	  SparseBoolMatrix val (get_m (), get_n (),
+				static_cast<octave_idx_type> (nzmax));
+
+	  for (mwIndex i = 0; i < nzmax; i++)
+	    {
+	      val.xdata(i) = ppr[i];
+	      val.xridx(i) = ir[i];
+	    }
+
+	  for (mwIndex i = 0; i < get_n () + 1; i++)
+	    val.xcidx(i) = jc[i];
+
+	  retval = val;
+	}
+	break;
+
+      case mxSINGLE_CLASS:
+	error ("single precision sparse data type not supported");
+	break;
+
+      case mxDOUBLE_CLASS:
+	{
+	  if (pi)
+	    {
+	      double *ppr = static_cast<double *> (pr);
+	      double *ppi = static_cast<double *> (pi);
+
+	      SparseComplexMatrix val (get_m (), get_n (),
+				       static_cast<octave_idx_type> (nzmax));
+
+	      for (mwIndex i = 0; i < nzmax; i++)
+		{
+		  val.xdata(i) = Complex (ppr[i], ppi[i]);
+		  val.xridx(i) = ir[i];
+		}
+
+	      for (mwIndex i = 0; i < get_n () + 1; i++)
+		val.xcidx(i) = jc[i];
+
+	      retval = val;
+	    }
+	  else
+	    {
+	      double *ppr = static_cast<double *> (pr);
+
+	      SparseMatrix val (get_m (), get_n (),
+				static_cast<octave_idx_type> (nzmax));
+
+	      for (mwIndex i = 0; i < nzmax; i++)
+		{
+		  val.xdata(i) = ppr[i];
+		  val.xridx(i) = ir[i];
+		}
+
+	      for (mwIndex i = 0; i < get_n () + 1; i++)
+		val.xcidx(i) = jc[i];
+
+	      retval = val;
+	    }
+	}
+	break;
+
+      default:
+	panic_impossible ();
+      }
+
+    return retval;
+  }
+
+private:
+
+  mwSize nzmax;
+
+  void *pr;
+  void *pi;
+  mwIndex *ir;
+  mwIndex *jc;
+
+  mxArray_sparse (const mxArray_sparse& val)
+    : mxArray_matlab (val), nzmax (val.nzmax),
+      pr (malloc (nzmax * get_element_size ())),
+      pi (val.pi ? malloc (nzmax * get_element_size ()) : 0),
+      ir (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex)))),
+      jc (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex))))
+  {
+    size_t nbytes = nzmax * get_element_size ();
+
+    if (pr)
+      memcpy (pr, val.pr, nbytes);
+
+    if (pi)
+      memcpy (pi, val.pi, nbytes);
+
+    if (ir)
+      memcpy (ir, val.ir, nzmax * sizeof (mwIndex));
+
+    if (jc)
+      memcpy (jc, val.jc, (val.get_n () + 1) * sizeof (mwIndex));
+  }
+};
+
+// Matlab-style struct arrays.
+
+class mxArray_struct : public mxArray_matlab
+{
+public:
+
+  mxArray_struct (mwSize ndims_arg, const mwSize *dims_arg, int num_keys_arg,
+		  const char **keys)
+    : mxArray_matlab (mxSTRUCT_CLASS, ndims_arg, dims_arg), nfields (num_keys_arg),
+      fields (static_cast<char **> (calloc (nfields, sizeof (char *)))),
+      data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
+  {
+    init (keys);
+  }
+
+  mxArray_struct (const dim_vector& dv, int num_keys_arg, const char **keys)
+    : mxArray_matlab (mxSTRUCT_CLASS, dv), nfields (num_keys_arg),
+      fields (static_cast<char **> (calloc (nfields, sizeof (char *)))),
+      data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
+  {
+    init (keys);
+  }
+
+  mxArray_struct (mwSize m, mwSize n, int num_keys_arg, const char **keys)
+    : mxArray_matlab (mxSTRUCT_CLASS, m, n), nfields (num_keys_arg),
+      fields (static_cast<char **> (calloc (nfields, sizeof (char *)))),
+      data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
+  {
+    init (keys);
+  }
+
+  void init (const char **keys)
+  {
+    for (int i = 0; i < nfields; i++)
+      fields[i] = strsave (keys[i]);
+  }
+
+  mxArray_struct *clone (void) const { return new mxArray_struct (*this); }
+
+  ~mxArray_struct (void)
+  {
+    for (int i = 0; i < nfields; i++)
+      mxFree (fields[i]);
+
+    mxFree (fields);
+
+    mwSize ntot = nfields * get_number_of_elements ();
+
+    for  (mwIndex i = 0; i < ntot; i++)
+      delete data[i];
+
+    mxFree (data);
+  }
+
+  int add_field (const char *key)
+  {
+    int retval = -1;
+
+    if (valid_key (key))
+      {
+	nfields++;
+
+	fields = static_cast<char **> (mxRealloc (fields, nfields * sizeof (char *)));
+
+	if (fields)
+	  {
+	    fields[nfields-1] = strsave (key);
+
+	    mwSize nel = get_number_of_elements ();
+
+	    mwSize ntot = nfields * nel;
+
+	    mxArray **new_data = static_cast<mxArray **> (malloc (ntot * sizeof (mxArray *)));
+
+	    if (new_data)
+	      {
+		mwIndex j = 0;
+		mwIndex k = 0;
+		mwIndex n = 0;
+
+		for (mwIndex i = 0; i < ntot; i++)
+		  {
+		    if (++n == nfields)
+		      {
+			new_data[j++] = 0;
+			n = 0;
+		      }
+		    else
+		      new_data[j++] = data[k++];
+		  }
+
+		mxFree (data);
+
+		data = new_data;
+
+		retval = nfields - 1;
+	      }
+	  }
+      }
+
+    return retval;
+  }
+
+  void remove_field (int key_num)
+  {
+    if (key_num >= 0 && key_num < nfields)
+      {
+	mwSize nel = get_number_of_elements ();
+
+	mwSize ntot = nfields * nel;
+
+	int new_nfields = nfields - 1;
+
+	char **new_fields = static_cast<char **> (malloc (new_nfields * sizeof (char *)));
+
+	mxArray **new_data = static_cast<mxArray **> (malloc (new_nfields * nel * sizeof (mxArray *)));
+
+	for (int i = 0; i < key_num; i++)
+	  new_fields[i] = fields[i];
+
+	for (int i = key_num + 1; i < nfields; i++)
+	  new_fields[i-1] = fields[i];
+
+	if (new_nfields > 0)
+	  {
+	    mwIndex j = 0;
+	    mwIndex k = 0;
+	    mwIndex n = 0;
+
+	    for (mwIndex i = 0; i < ntot; i++)
+	      {
+		if (n == key_num)
+		  k++;
+		else
+		  new_data[j++] = data[k++];
+
+		if (++n == nfields)
+		  n = 0;
+	      }
+	  }
+
+	nfields = new_nfields;
+
+	mxFree (fields);
+	mxFree (data);
+
+	fields = new_fields;
+	data = new_data;
+      }
+  }
+
+  mxArray *get_field_by_number (mwIndex index, int key_num) const
+  {
+    return key_num >= 0 && key_num < nfields
+      ? data[nfields * index + key_num] : 0;
+  }
+
+  void set_field_by_number (mwIndex index, int key_num, mxArray *val);
+
+  int get_number_of_fields (void) const { return nfields; }
+
+  const char *get_field_name_by_number (int key_num) const
+  {
+    return key_num >= 0 && key_num < nfields ? fields[key_num] : 0;
+  }
+
+  int get_field_number (const char *key) const
+  {
+    int retval = -1;
+
+    for (int i = 0; i < nfields; i++)
+      {
+	if (! strcmp (key, fields[i]))
+	  {
+	    retval = i;
+	    break;
+	  }
+      }
+
+    return retval;
+  }
+
+  void *get_data (void) const { return data; }
+
+  void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); }
+
+protected:
+
+  octave_value as_octave_value (void) const
+  {
+    dim_vector dv = dims_to_dim_vector ();
+
+    string_vector keys (fields, nfields);
+
+    Octave_map m;
+
+    mwSize ntot = nfields * get_number_of_elements ();
+
+    for (int i = 0; i < nfields; i++)
+      {
+	Cell c (dv);
+
+	octave_value *p = c.fortran_vec ();
+
+	mwIndex k = 0;
+	for (mwIndex j = i; j < ntot; j += nfields)
+	  p[k++] = mxArray::as_octave_value (data[j]);
+
+	m.assign (keys[i], c);
+      }
+
+    return m;
+  }
+
+private:
+
+  int nfields;
+
+  char **fields;
+
+  mxArray **data;
+
+  mxArray_struct (const mxArray_struct& val)
+    : mxArray_matlab (val), nfields (val.nfields),
+      fields (static_cast<char **> (malloc (nfields * sizeof (char *)))),
+      data (static_cast<mxArray **> (malloc (nfields * get_number_of_elements () * sizeof (mxArray *))))
+  {
+    for (int i = 0; i < nfields; i++)
+      fields[i] = strsave (val.fields[i]);
+
+    mwSize nel = get_number_of_elements ();
+
+    for (mwIndex i = 0; i < nel * nfields; i++)
+      {
+	mxArray *ptr = val.data[i];
+	data[i] = ptr ? ptr->clone () : 0;
+      }
+  }
+};
+
+// Matlab-style cell arrays.
+
+class mxArray_cell : public mxArray_matlab
+{
+public:
+
+  mxArray_cell (mwSize ndims_arg, const mwSize *dims_arg)
+    : mxArray_matlab (mxCELL_CLASS, ndims_arg, dims_arg),
+      data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
+
+  mxArray_cell (const dim_vector& dv)
+    : mxArray_matlab (mxCELL_CLASS, dv),
+      data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
+
+  mxArray_cell (mwSize m, mwSize n)
+    : mxArray_matlab (mxCELL_CLASS, m, n),
+      data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
+
+  mxArray_cell *clone (void) const { return new mxArray_cell (*this); }
+
+  ~mxArray_cell (void)
+  {
+    mwSize nel = get_number_of_elements ();
+
+    for  (mwIndex i = 0; i < nel; i++)
+      delete data[i];
+
+    mxFree (data);
+  }
+
+  mxArray *get_cell (mwIndex idx) const
+  {
+    return idx >= 0 && idx < get_number_of_elements () ? data[idx] : 0;
+  }
+
+  void set_cell (mwIndex idx, mxArray *val);
+
+  void *get_data (void) const { return data; }
+
+  void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); }
+
+protected:
+
+  octave_value as_octave_value (void) const
+  {
+    dim_vector dv = dims_to_dim_vector ();
+
+    Cell c (dv);
+
+    mwSize nel = get_number_of_elements ();
+
+    octave_value *p = c.fortran_vec ();
+
+    for (mwIndex i = 0; i < nel; i++)
+      p[i] = mxArray::as_octave_value (data[i]);
+
+    return c;
+  }
+
+private:
+
+  mxArray **data;
+
+  mxArray_cell (const mxArray_cell& val)
+    : mxArray_matlab (val),
+      data (static_cast<mxArray **> (malloc (get_number_of_elements () * sizeof (mxArray *))))
+  {
+    mwSize nel = get_number_of_elements ();
+
+    for (mwIndex i = 0; i < nel; i++)
+      {
+	mxArray *ptr = val.data[i];
+	data[i] = ptr ? ptr->clone () : 0;
+      }
+  }
+};
+
+// ------------------------------------------------------------------
+
+mxArray::mxArray (const octave_value& ov)
+  : rep (new mxArray_octave_value (ov)), name (0) { }
+
+mxArray::mxArray (mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag)
+  : rep (new mxArray_number (id, ndims, dims, flag)), name (0) { }
+
+mxArray::mxArray (mxClassID id, const dim_vector& dv, mxComplexity flag)
+  : rep (new mxArray_number (id, dv, flag)), name (0) { }
+
+mxArray::mxArray (mxClassID id, mwSize m, mwSize n, mxComplexity flag)
+  : rep (new mxArray_number (id, m, n, flag)), name (0) { }
+
+mxArray::mxArray (mxClassID id, double val)
+  : rep (new mxArray_number (id, val)), name (0) { }
+
+mxArray::mxArray (mxClassID id, mxLogical val)
+  : rep (new mxArray_number (id, val)), name (0) { }
+
+mxArray::mxArray (const char *str)
+  : rep (new mxArray_number (str)), name (0) { }
+
+mxArray::mxArray (mwSize m, const char **str)
+  : rep (new mxArray_number (m, str)), name (0) { }
+
+mxArray::mxArray (mxClassID id, mwSize m, mwSize n, mwSize nzmax, mxComplexity flag)
+  : rep (new mxArray_sparse (id, m, n, nzmax, flag)), name (0) { }
+
+mxArray::mxArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys)
+  : rep (new mxArray_struct (ndims, dims, num_keys, keys)), name (0) { }
+
+mxArray::mxArray (const dim_vector& dv, int num_keys, const char **keys)
+  : rep (new mxArray_struct (dv, num_keys, keys)), name (0) { }
+
+mxArray::mxArray (mwSize m, mwSize n, int num_keys, const char **keys)
+  : rep (new mxArray_struct (m, n, num_keys, keys)), name (0) { }
+
+mxArray::mxArray (mwSize ndims, const mwSize *dims)
+  : rep (new mxArray_cell (ndims, dims)), name (0) { }
+
+mxArray::mxArray (const dim_vector& dv)
+  : rep (new mxArray_cell (dv)), name (0) { }
+
+mxArray::mxArray (mwSize m, mwSize n)
+  : rep (new mxArray_cell (m, n)), name (0) { }
+
+mxArray::~mxArray (void)
+{
+  mxFree (name);
+
+  delete rep;
+}
+
+void
+mxArray::set_name (const char *name_arg)
+{
+  mxFree (name);
+  name = strsave (name_arg);
+}
+
+octave_value
+mxArray::as_octave_value (mxArray *ptr)
+{
+  return ptr ? ptr->as_octave_value () : octave_value (Matrix ());
+}
+
+octave_value
+mxArray::as_octave_value (void) const
+{
+  return rep->as_octave_value ();
+}
+
+void
+mxArray::maybe_mutate (void) const
+{
+  if (rep->is_octave_value ())
+    {
+      // The mutate function returns a pointer to a complete new
+      // mxArray object (or 0, if no mutation happened).  We just want
+      // to replace the existing rep with the rep from the new object.
+
+      mxArray *new_val = rep->mutate ();
+
+      if (new_val)
+	{
+	  delete rep;
+	  rep = new_val->rep;
+	  new_val->rep = 0;
+	  delete new_val;
+	}
+    }
+}
+
+// ------------------------------------------------------------------
+
+// A class to manage calls to MEX functions.  Mostly deals with memory
+// management.
+
+class mex
+{
+public:
+
+  mex (octave_mex_function *f)
+    : curr_mex_fcn (f), memlist (), arraylist (), fname (0) { }
+
+  ~mex (void)
+  {
+    if (! memlist.empty ())
+      error ("mex: %s: cleanup failed", function_name ());
+
+    mxFree (fname);
+  }
+
+  const char *function_name (void) const
+  {
+    if (! fname)
+      {
+	octave_function *fcn = octave_call_stack::current ();
+
+	if (fcn)
+	  {
+	    std::string nm = fcn->name ();
+	    fname = mxArray::strsave (nm.c_str ());
+	  }
+	else
+	  fname = mxArray::strsave ("unknown");
+      }
+
+    return fname;
+  }
+
+  // Free all unmarked pointers obtained from malloc and calloc.
+  static void cleanup (void *ptr)
+  {
+    mex *context = static_cast<mex *> (ptr);
+
+    // We can't use mex::free here because it modifies memlist.
+    for (std::set<void *>::iterator p = context->memlist.begin ();
+	 p != context->memlist.end (); p++)
+      xfree (*p);
+
+    context->memlist.clear ();
+
+    // We can't use mex::free_value here because it modifies arraylist.
+    for (std::set<mxArray *>::iterator p = context->arraylist.begin ();
+	 p != context->arraylist.end (); p++)
+      delete *p;
+
+    context->arraylist.clear ();
+  }
+
+  // Allocate memory.
+  void *malloc_unmarked (size_t n)
+  {
+    void *ptr = ::malloc (n);
+
+    if (! ptr)
+      {
+	// FIXME -- could use "octave_new_handler();" instead
+
+	error ("%s: failed to allocate %d bytes of memory",
+	       function_name (), n);
+
+	abort ();
+      }
+
+    global_mark (ptr);
+
+    return ptr;
+  }
+
+  // Allocate memory to be freed on exit.
+  void *malloc (size_t n)
+  {
+    void *ptr = malloc_unmarked (n);
+
+    mark (ptr);
+
+    return ptr;
+  }
+
+  // Allocate memory and initialize to 0.
+  void *calloc_unmarked (size_t n, size_t t)
+  {
+    void *ptr = malloc_unmarked (n*t);
+
+    memset (ptr, 0, n*t);
+
+    return ptr;
+  }
+
+  // Allocate memory to be freed on exit and initialize to 0.
+  void *calloc (size_t n, size_t t)
+  {
+    void *ptr = calloc_unmarked (n, t);
+
+    mark (ptr);
+
+    return ptr;
+  }
+
+  // Reallocate a pointer obtained from malloc or calloc.  We don't
+  // need an "unmarked" version of this.
+  void *realloc (void *ptr, size_t n)
+  {
+    void *v = ::realloc (ptr, n);
+
+    std::set<void *>::iterator p = memlist.find (ptr);
+
+    if (v && p != memlist.end ())
+      {
+	memlist.erase (p);
+	memlist.insert (v);
+      }
+
+    p = global_memlist.find (ptr);
+
+    if (v && p != global_memlist.end ())
+      {
+	global_memlist.erase (p);
+	global_memlist.insert (v);
+      }
+
+    return v;
+  }
+
+  // Free a pointer obtained from malloc or calloc.
+  void free (void *ptr)
+  {
+    if (ptr)
+      {
+	unmark (ptr);
+
+	std::set<void *>::iterator p = global_memlist.find (ptr);
+
+	if (p != global_memlist.end ())
+	  {
+	    global_memlist.erase (p);
+
+	    xfree (ptr);
+	  }
+	else
+	  {
+	    p = foreign_memlist.find (ptr);
+
+	    if (p != foreign_memlist.end ())
+	      foreign_memlist.erase (p);
+	    else
+	      warning ("mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc");
+	  }
+      }
+  }
+
+  // Mark a pointer to be freed on exit.
+  void mark (void *ptr)
+  {
+#ifdef DEBUG
+    if (memlist.find (ptr) != memlist.end ())
+      warning ("%s: double registration ignored", function_name ());
+#endif
+
+    memlist.insert (ptr);
+  }
+
+  // Unmark a pointer to be freed on exit, either because it was
+  // made persistent, or because it was already freed.
+  void unmark (void *ptr)
+  {
+    std::set<void *>::iterator p = memlist.find (ptr);
+
+    if (p != memlist.end ())
+      memlist.erase (p);
+#ifdef DEBUG
+    else
+      warning ("%s: value not marked", function_name ());
+#endif
+  }
+
+  mxArray *mark_array (mxArray *ptr)
+  {
+    arraylist.insert (ptr);
+    return ptr;
+  }
+
+  void unmark_array (mxArray *ptr)
+  {
+    std::set<mxArray *>::iterator p = arraylist.find (ptr);
+
+    if (p != arraylist.end ())
+      arraylist.erase (p);
+  }
+
+  // Mark a pointer as one we allocated.
+  void mark_foreign (void *ptr)
+  {
+#ifdef DEBUG
+    if (foreign_memlist.find (ptr) != foreign_memlist.end ())
+      warning ("%s: double registration ignored", function_name ());
+#endif
+
+    foreign_memlist.insert (ptr);
+  }
+
+  // Unmark a pointer as one we allocated.
+  void unmark_foreign (void *ptr)
+  {
+    std::set<void *>::iterator p = foreign_memlist.find (ptr);
+
+    if (p != foreign_memlist.end ())
+      foreign_memlist.erase (p);
+#ifdef DEBUG
+    else
+      warning ("%s: value not marked", function_name ());
+#endif
+
+  }
+
+  // Make a new array value and initialize from an octave value; it will be
+  // freed on exit unless marked as persistent.
+  mxArray *make_value (const octave_value& ov)
+  {
+    return mark_array (new mxArray (ov));
+  }
+
+  // Free an array and its contents.
+  bool free_value (mxArray *ptr)
+  {
+    bool inlist = false;
+
+    std::set<mxArray *>::iterator p = arraylist.find (ptr);
+
+    if (p != arraylist.end ())
+      {
+	inlist = true;
+	arraylist.erase (p);
+	delete ptr;
+      }
+#ifdef DEBUG
+    else
+      warning ("mex::free_value: skipping memory not allocated by mex::make_value");
+#endif
+
+    return inlist;
+  }
+
+  octave_mex_function *current_mex_function (void) const
+  {
+    return curr_mex_fcn;
+  }
+
+  // 1 if error should be returned to MEX file, 0 if abort.
+  int trap_feval_error;
+
+  // longjmp return point if mexErrMsgTxt or error.
+  jmp_buf jump;
+
+  // Trigger a long jump back to the mex calling function.
+  void abort (void) { longjmp (jump, 1); }
+
+private:
+
+  // Pointer to the mex function that corresponds to this mex context.
+  octave_mex_function *curr_mex_fcn;
+
+  // List of memory resources that need to be freed upon exit.
+  std::set<void *> memlist;
+
+  // List of mxArray objects that need to be freed upon exit.
+  std::set<mxArray *> arraylist;
+
+  // List of memory resources we know about, but that were allocated
+  // elsewhere.
+  std::set<void *> foreign_memlist;
+
+  // The name of the currently executing function.
+  mutable char *fname;
+
+  // List of memory resources we allocated.
+  static std::set<void *> global_memlist;
+
+  // Mark a pointer as one we allocated.
+  void global_mark (void *ptr)
+  {
+#ifdef DEBUG
+    if (global_memlist.find (ptr) != global_memlist.end ())
+      warning ("%s: double registration ignored", function_name ());
+#endif
+
+    global_memlist.insert (ptr);
+  }
+
+  // Unmark a pointer as one we allocated.
+  void global_unmark (void *ptr)
+  {
+    std::set<void *>::iterator p = global_memlist.find (ptr);
+
+    if (p != global_memlist.end ())
+      global_memlist.erase (p);
+#ifdef DEBUG
+    else
+      warning ("%s: value not marked", function_name ());
+#endif
+
+  }
+};
+
+// List of memory resources we allocated.
+std::set<void *> mex::global_memlist;
+
+// Current context.
+mex *mex_context = 0;
+
+void *
+mxArray::malloc (size_t n)
+{
+  return mex_context ? mex_context->malloc_unmarked (n) : ::malloc (n);
+}
+
+void *
+mxArray::calloc (size_t n, size_t t)
+{
+  return mex_context ? mex_context->calloc_unmarked (n, t) : ::calloc (n, t);
+}
+
+static inline void *
+maybe_mark_foreign (void *ptr)
+{
+  if (mex_context)
+    mex_context->mark_foreign (ptr);
+
+  return ptr;
+}
+
+static inline mxArray *
+maybe_unmark_array (mxArray *ptr)
+{
+  if (mex_context)
+    mex_context->unmark_array (ptr);
+
+  return ptr;
+}
+
+static inline void *
+maybe_unmark (void *ptr)
+{
+  if (mex_context)
+    mex_context->unmark (ptr);
+
+  return ptr;
+}
+
+void
+mxArray_struct::set_field_by_number (mwIndex index, int key_num, mxArray *val)
+{
+  if (key_num >= 0 && key_num < nfields)
+    data[nfields * index + key_num] = maybe_unmark_array (val);
+}
+
+void
+mxArray_cell::set_cell (mwIndex idx, mxArray *val)
+{
+  if (idx >= 0 && idx < get_number_of_elements ())
+    data[idx] = maybe_unmark_array (val);
+}
+
+// ------------------------------------------------------------------
+
+// C interface to mxArray objects:
+
+// Floating point predicates.
+
+int
+mxIsFinite (const double v)
+{
+  return lo_ieee_finite (v) != 0;
+}
+
+int
+mxIsInf (const double v)
+{
+  return lo_ieee_isinf (v) != 0;
+}
+
+int
+mxIsNaN (const double v)
+{
+  return lo_ieee_isnan (v) != 0;
+}
+
+double
+mxGetEps (void)
+{
+  return DBL_EPSILON;
+}
+
+double
+mxGetInf (void)
+{
+  return lo_ieee_inf_value ();
+}
+
+double
+mxGetNaN (void)
+{
+  return lo_ieee_nan_value ();
+}
+
+// Memory management.
+void *
+mxCalloc (size_t n, size_t size)
+{
+  return mex_context ? mex_context->calloc (n, size) : calloc (n, size);
+}
+
+void *
+mxMalloc (size_t n)
+{
+  return mex_context ? mex_context->malloc (n) : malloc (n);
+}
+
+void *
+mxRealloc (void *ptr, size_t size)
+{
+  return mex_context ? mex_context->realloc (ptr, size) : realloc (ptr, size);
+}
+
+void
+mxFree (void *ptr)
+{
+  if (mex_context)
+    mex_context->free (ptr);
+  else
+    xfree (ptr);
+}
+
+static inline mxArray *
+maybe_mark_array (mxArray *ptr)
+{
+  return mex_context ? mex_context->mark_array (ptr) : ptr;
+}
+  
+// Constructors.
+mxArray *
+mxCreateCellArray (mwSize ndims, const mwSize *dims)
+{
+  return maybe_mark_array (new mxArray (ndims, dims));
+}
+
+mxArray *
+mxCreateCellMatrix (mwSize m, mwSize n)
+{
+  return maybe_mark_array (new mxArray (m, n));
+}
+
+mxArray *
+mxCreateCharArray (mwSize ndims, const mwSize *dims)
+{
+  return maybe_mark_array (new mxArray (mxCHAR_CLASS, ndims, dims));
+}
+
+mxArray *
+mxCreateCharMatrixFromStrings (mwSize m, const char **str)
+{
+  return maybe_mark_array (new mxArray (m, str));
+}
+
+mxArray *
+mxCreateDoubleMatrix (mwSize m, mwSize n, mxComplexity flag)
+{
+  return maybe_mark_array (new mxArray (mxDOUBLE_CLASS, m, n, flag));
+}
+
+mxArray *
+mxCreateDoubleScalar (double val)
+{
+  return maybe_mark_array (new mxArray (mxDOUBLE_CLASS, val));
+}
+
+mxArray *
+mxCreateLogicalArray (mwSize ndims, const mwSize *dims)
+{
+  return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, ndims, dims));
+}
+
+mxArray *
+mxCreateLogicalMatrix (mwSize m, mwSize n)
+{
+  return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, m, n));
+}
+
+mxArray *
+mxCreateLogicalScalar (mxLogical val)
+{
+  return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, val));
+}
+
+mxArray *
+mxCreateNumericArray (mwSize ndims, const mwSize *dims, mxClassID class_id,
+		      mxComplexity flag)
+{
+  return maybe_mark_array (new mxArray (class_id, ndims, dims, flag));
+}
+
+mxArray *
+mxCreateNumericMatrix (mwSize m, mwSize n, mxClassID class_id, mxComplexity flag)
+{
+  return maybe_mark_array (new mxArray (class_id, m, n, flag));
+}
+
+mxArray *
+mxCreateSparse (mwSize m, mwSize n, mwSize nzmax, mxComplexity flag)
+{
+  return maybe_mark_array (new mxArray (mxDOUBLE_CLASS, m, n, nzmax, flag));
+}
+
+mxArray *
+mxCreateSparseLogicalMatrix (mwSize m, mwSize n, mwSize nzmax)
+{
+  return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, m, n, nzmax));
+}
+
+mxArray *
+mxCreateString (const char *str)
+{
+  return maybe_mark_array (new mxArray (str));
+}
+
+mxArray *
+mxCreateStructArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys)
+{
+  return maybe_mark_array (new mxArray (ndims, dims, num_keys, keys));
+}
+
+mxArray *
+mxCreateStructMatrix (mwSize m, mwSize n, int num_keys, const char **keys)
+{
+  return maybe_mark_array (new mxArray (m, n, num_keys, keys));
+}
+
+// Copy constructor.
+mxArray *
+mxDuplicateArray (const mxArray *ptr)
+{
+  return maybe_mark_array (ptr->clone ());
+}
+
+// Destructor.
+void
+mxDestroyArray (mxArray *ptr)
+{
+  if (! (mex_context && mex_context->free_value (ptr)))
+    delete ptr;
+}
+
+// Type Predicates.
+int
+mxIsCell (const mxArray *ptr)
+{
+  return ptr->is_cell ();
+}
+
+int
+mxIsChar (const mxArray *ptr)
+{
+  return ptr->is_char ();
+}
+
+int
+mxIsClass (const mxArray *ptr, const char *name)
+{
+  return ptr->is_class (name);
+}
+
+int
+mxIsComplex (const mxArray *ptr)
+{
+  return ptr->is_complex ();
+}
+
+int
+mxIsDouble (const mxArray *ptr)
+{
+  return ptr->is_double ();
+}
+
+int
+mxIsInt16 (const mxArray *ptr)
+{
+  return ptr->is_int16 ();
+}
+
+int
+mxIsInt32 (const mxArray *ptr)
+{
+  return ptr->is_int32 ();
+}
+
+int
+mxIsInt64 (const mxArray *ptr)
+{
+  return ptr->is_int64 ();
+}
+
+int
+mxIsInt8 (const mxArray *ptr)
+{
+  return ptr->is_int8 ();
+}
+
+int
+mxIsLogical (const mxArray *ptr)
+{
+  return ptr->is_logical ();
+}
+
+int
+mxIsNumeric (const mxArray *ptr)
+{
+  return ptr->is_numeric ();
+}
+
+int
+mxIsSingle (const mxArray *ptr)
+{
+  return ptr->is_single ();
+}
+
+int
+mxIsSparse (const mxArray *ptr)
+{
+  return ptr->is_sparse ();
+}
+
+int
+mxIsStruct (const mxArray *ptr)
+{
+  return ptr->is_struct ();
+}
+
+int
+mxIsUint16 (const mxArray *ptr)
+{
+  return ptr->is_uint16 ();
+}
+
+int
+mxIsUint32 (const mxArray *ptr)
+{
+  return ptr->is_uint32 ();
+}
+
+int
+mxIsUint64 (const mxArray *ptr)
+{
+  return ptr->is_uint64 ();
+}
+
+int
+mxIsUint8 (const mxArray *ptr)
+{
+  return ptr->is_uint8 ();
+}
+
+// Odd type+size predicate.
+int
+mxIsLogicalScalar (const mxArray *ptr)
+{
+  return ptr->is_logical_scalar ();
+}
+
+// Odd type+size+value predicate.
+int
+mxIsLogicalScalarTrue (const mxArray *ptr)
+{
+  return ptr->is_logical_scalar_true ();
+}
+
+// Size predicate.
+int
+mxIsEmpty (const mxArray *ptr)
+{
+  return ptr->is_empty ();
+}
+
+// Just plain odd thing to ask of a value.
+int
+mxIsFromGlobalWS (const mxArray */*ptr*/)
+{
+  // FIXME
+  abort ();
+  return 0;
+}
+
+// Dimension extractors.
+size_t
+mxGetM (const mxArray *ptr)
+{
+  return ptr->get_m ();
+}
+
+size_t
+mxGetN (const mxArray *ptr)
+{
+  return ptr->get_n ();
+}
+
+mwSize *
+mxGetDimensions (const mxArray *ptr)
+{
+  return ptr->get_dimensions ();
+}
+
+mwSize
+mxGetNumberOfDimensions (const mxArray *ptr)
+{
+  return ptr->get_number_of_dimensions ();
+}
+
+size_t
+mxGetNumberOfElements (const mxArray *ptr)
+{
+  return ptr->get_number_of_elements ();
+}
+
+// Dimension setters.
+void
+mxSetM (mxArray *ptr, mwSize m)
+{
+  ptr->set_m (m);
+}
+
+void
+mxSetN (mxArray *ptr, mwSize n)
+{
+  ptr->set_n (n);
+}
+
+void
+mxSetDimensions (mxArray *ptr, mwSize *dims, mwSize ndims)
+{
+  ptr->set_dimensions (static_cast<mwSize *> (maybe_unmark (dims)), ndims);
+}
+  
+// Data extractors.
+double *
+mxGetPr (const mxArray *ptr)
+{
+  return static_cast<double *> (ptr->get_data ());
+}
+
+double *
+mxGetPi (const mxArray *ptr)
+{
+  return static_cast<double *> (ptr->get_imag_data ());
+}
+
+double
+mxGetScalar (const mxArray *ptr)
+{
+  return ptr->get_scalar ();
+}
+
+mxChar *
+mxGetChars (const mxArray *ptr)
+{
+  return static_cast<mxChar *> (ptr->get_data ());
+}
+
+mxLogical *
+mxGetLogicals (const mxArray *ptr)
+{
+  return static_cast<mxLogical *> (ptr->get_data ());
+}
+
+void *
+mxGetData (const mxArray *ptr)
+{
+  return ptr->get_data ();
+}
+
+void *
+mxGetImagData (const mxArray *ptr)
+{
+  return ptr->get_imag_data ();
+}
+
+// Data setters.
+void
+mxSetPr (mxArray *ptr, double *pr)
+{
+  ptr->set_data (maybe_unmark (pr));
+}
+
+void
+mxSetPi (mxArray *ptr, double *pi)
+{
+  ptr->set_imag_data (maybe_unmark (pi));
+}
+
+void
+mxSetData (mxArray *ptr, void *pr)
+{
+  ptr->set_data (maybe_unmark (pr));
+}
+
+void
+mxSetImagData (mxArray *ptr, void *pi)
+{
+  ptr->set_imag_data (maybe_unmark (pi));
+}
+
+// Classes.
+mxClassID
+mxGetClassID (const mxArray *ptr)
+{
+  return ptr->get_class_id ();
+}
+
+const char *
+mxGetClassName (const mxArray *ptr)
+{
+  return ptr->get_class_name ();
+}
+
+void
+mxSetClassName (mxArray *ptr, const char *name)
+{
+  ptr->set_class_name (name);
+}
+
+// Cell support.
+mxArray *
+mxGetCell (const mxArray *ptr, mwIndex idx)
+{
+  return ptr->get_cell (idx);
+}
+
+void
+mxSetCell (mxArray *ptr, mwIndex idx, mxArray *val)
+{
+  ptr->set_cell (idx, val);
+}
+
+// Sparse support.
+mwIndex *
+mxGetIr (const mxArray *ptr)
+{
+  return ptr->get_ir ();
+}
+
+mwIndex *
+mxGetJc (const mxArray *ptr)
+{
+  return ptr->get_jc ();
+}
+
+mwSize
+mxGetNzmax (const mxArray *ptr)
+{
+  return ptr->get_nzmax ();
+}
+
+void
+mxSetIr (mxArray *ptr, mwIndex *ir)
+{
+  ptr->set_ir (static_cast <mwIndex *> (maybe_unmark (ir)));
+}
+
+void
+mxSetJc (mxArray *ptr, mwIndex *jc)
+{
+  ptr->set_jc (static_cast<mwIndex *> (maybe_unmark (jc)));
+}
+
+void
+mxSetNzmax (mxArray *ptr, mwSize nzmax)
+{
+  ptr->set_nzmax (nzmax);
+}
+
+// Structure support.
+int
+mxAddField (mxArray *ptr, const char *key)
+{
+  return ptr->add_field (key);
+}
+
+void
+mxRemoveField (mxArray *ptr, int key_num)
+{
+  ptr->remove_field (key_num);
+}
+
+mxArray *
+mxGetField (const mxArray *ptr, mwIndex index, const char *key)
+{
+  int key_num = mxGetFieldNumber (ptr, key);
+  return mxGetFieldByNumber (ptr, index, key_num);
+}
+
+mxArray *
+mxGetFieldByNumber (const mxArray *ptr, mwIndex index, int key_num)
+{
+  return ptr->get_field_by_number (index, key_num);
+}
+
+void
+mxSetField (mxArray *ptr, mwIndex index, const char *key, mxArray *val)
+{
+  int key_num = mxGetFieldNumber (ptr, key);
+  mxSetFieldByNumber (ptr, index, key_num, val);
+}
+
+void
+mxSetFieldByNumber (mxArray *ptr, mwIndex index, int key_num, mxArray *val)
+{
+  ptr->set_field_by_number (index, key_num, val);
+}
+
+int
+mxGetNumberOfFields (const mxArray *ptr)
+{
+  return ptr->get_number_of_fields ();
+}
+
+const char *
+mxGetFieldNameByNumber (const mxArray *ptr, int key_num)
+{
+  return ptr->get_field_name_by_number (key_num);
+}
+
+int
+mxGetFieldNumber (const mxArray *ptr, const char *key)
+{
+  return ptr->get_field_number (key);
+}
+
+int
+mxGetString (const mxArray *ptr, char *buf, mwSize buflen)
+{
+  return ptr->get_string (buf, buflen);
+}
+
+char *
+mxArrayToString (const mxArray *ptr)
+{
+  return ptr->array_to_string ();
+}
+  
+mwIndex
+mxCalcSingleSubscript (const mxArray *ptr, mwSize nsubs, mwIndex *subs)
+{
+  return ptr->calc_single_subscript (nsubs, subs);
+}
+
+size_t
+mxGetElementSize (const mxArray *ptr)
+{
+  return ptr->get_element_size ();
+}
+
+// ------------------------------------------------------------------
+
+typedef void (*cmex_fptr) (int nlhs, mxArray **plhs, int nrhs, mxArray **prhs);
+typedef F77_RET_T (*fmex_fptr) (int& nlhs, mxArray **plhs, int& nrhs, mxArray **prhs);
+
+octave_value_list
+call_mex (bool have_fmex, void *f, const octave_value_list& args,
+	  int nargout_arg, octave_mex_function *curr_mex_fcn)
+{
+  // Use at least 1 for nargout since even for zero specified args,
+  // still want to be able to return an ans.
+
+  volatile int nargout = nargout_arg;
+
+  int nargin = args.length ();
+  OCTAVE_LOCAL_BUFFER (mxArray *, argin, nargin);
+  for (int i = 0; i < nargin; i++)
+    argin[i] = 0;
+
+  int nout = nargout == 0 ? 1 : nargout;
+  OCTAVE_LOCAL_BUFFER (mxArray *, argout, nout);
+  for (int i = 0; i < nout; i++)
+    argout[i] = 0;
+
+  unwind_protect::begin_frame ("call_mex");
+
+  // Save old mex pointer.
+  unwind_protect_ptr (mex_context);
+
+  mex context (curr_mex_fcn);
+
+  unwind_protect::add (mex::cleanup, static_cast<void *> (&context));
+
+  for (int i = 0; i < nargin; i++)
+    argin[i] = context.make_value (args(i));
+
+  if (setjmp (context.jump) == 0)
+    {
+      mex_context = &context;
+
+      if (have_fmex)
+	{
+	  fmex_fptr fcn = FCN_PTR_CAST (fmex_fptr, f);
+
+	  int tmp_nargout = nargout;
+	  int tmp_nargin = nargin;
+
+	  fcn (tmp_nargout, argout, tmp_nargin, argin);
+	}
+      else
+	{
+	  cmex_fptr fcn = FCN_PTR_CAST (cmex_fptr, f);
+
+	  fcn (nargout, argout, nargin, argin);
+	}
+    }
+
+  // Convert returned array entries back into octave values.
+
+  octave_value_list retval;
+
+  if (! error_state)
+    {
+      if (nargout == 0 && argout[0])
+	{
+	  // We have something for ans.
+	  nargout = 1;
+	}
+
+      retval.resize (nargout);
+
+      for (int i = 0; i < nargout; i++)
+	retval(i) = mxArray::as_octave_value (argout[i]);
+    }
+
+  // Clean up mex resources.
+  unwind_protect::run_frame ("call_mex");
+
+  return retval;
+}
+
+// C interface to mex functions:
+
+const char *
+mexFunctionName (void)
+{
+  return mex_context ? mex_context->function_name () : "unknown";
+}
+
+int
+mexCallMATLAB (int nargout, mxArray *argout[], int nargin, mxArray *argin[],
+	       const char *fname)
+{
+  octave_value_list args;
+
+  // FIXME -- do we need unwind protect to clean up args?  Off hand, I
+  // would say that this problem is endemic to Octave and we will
+  // continue to have memory leaks after Ctrl-C until proper exception
+  // handling is implemented.  longjmp() only clears the stack, so any
+  // class which allocates data on the heap is going to leak.
+
+  args.resize (nargin);
+
+  for (int i = 0; i < nargin; i++)
+    args(i) = mxArray::as_octave_value (argin[i]);
+
+  octave_value_list retval = feval (fname, args, nargout);
+
+  if (error_state && mex_context->trap_feval_error == 0)
+    {
+      // FIXME -- is this the correct way to clean up?  abort() is
+      // going to trigger a long jump, so the normal class destructors
+      // will not be called.  Hopefully this will reduce things to a
+      // tiny leak.  Maybe create a new octave memory tracer type
+      // which prints a friendly message every time it is
+      // created/copied/deleted to check this.
+
+      args.resize (0);
+      retval.resize (0);
+      mex_context->abort ();
+    }
+
+  int num_to_copy = retval.length ();
+
+  if (nargout < retval.length ())
+    num_to_copy = nargout;
+
+  for (int i = 0; i < num_to_copy; i++)
+    {
+      // FIXME -- it would be nice to avoid copying the value here,
+      // but there is no way to steal memory from a matrix, never mind
+      // that matrix memory is allocated by new[] and mxArray memory
+      // is allocated by malloc().
+      argout[i] = mex_context->make_value (retval (i));
+    }
+
+  while (num_to_copy < nargout)
+    argout[num_to_copy++] = 0;
+
+  if (error_state)
+    {
+      error_state = 0;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+void
+mexSetTrapFlag (int flag)
+{
+  if (mex_context)
+    mex_context->trap_feval_error = flag;
+}
+
+int
+mexEvalString (const char *s)
+{
+  int retval = 0;
+
+  int parse_status;
+
+  octave_value_list ret;
+
+  ret = eval_string (s, false, parse_status, 0);
+
+  if (parse_status || error_state)
+    {
+      error_state = 0;
+
+      retval = 1;
+    }
+
+  return retval;
+}
+
+void
+mexErrMsgTxt (const char *s)
+{
+  if (s && strlen (s) > 0)
+    error ("%s: %s", mexFunctionName (), s);
+  else
+    // Just set the error state; don't print msg.
+    error ("");
+
+  mex_context->abort ();
+}
+
+void
+mexErrMsgIdAndTxt (const char *id, const char *fmt, ...)
+{
+  if (fmt && strlen (fmt) > 0)
+    {
+      const char *fname = mexFunctionName ();
+      size_t len = strlen (fname) + 2 + strlen (fmt) + 1;
+      OCTAVE_LOCAL_BUFFER (char, tmpfmt, len);
+      sprintf (tmpfmt, "%s: %s", fname, fmt);
+      va_list args;
+      va_start (args, fmt);
+      verror_with_id (id, tmpfmt, args);
+      va_end (args);
+    }
+  else
+    // Just set the error state; don't print msg.
+    error ("");
+
+  mex_context->abort ();
+}
+
+void
+mexWarnMsgTxt (const char *s)
+{
+  warning ("%s", s);
+}
+
+void
+mexWarnMsgIdAndTxt (const char *id, const char *fmt, ...)
+{
+  // FIXME -- is this right?  What does Matlab do if fmt is NULL or
+  // an empty string?
+
+  if (fmt && strlen (fmt) > 0)
+    {
+      const char *fname = mexFunctionName ();
+      size_t len = strlen (fname) + 2 + strlen (fmt) + 1;
+      OCTAVE_LOCAL_BUFFER (char, tmpfmt, len);
+      sprintf (tmpfmt, "%s: %s", fname, fmt);
+      va_list args;
+      va_start (args, fmt);
+      vwarning_with_id (id, tmpfmt, args);
+      va_end (args);
+    }
+}
+
+void
+mexPrintf (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  octave_vformat (octave_stdout, fmt, args);
+  va_end (args);
+}
+
+mxArray *
+mexGetVariable (const char *space, const char *name)
+{
+  mxArray *retval = 0;
+
+  octave_value val;
+
+  if (! strcmp (space, "global"))
+    val = get_global_value (name);
+  else
+    {
+      // FIXME -- should this be in variables.cc?
+
+      unwind_protect::begin_frame ("mexGetVariable");
+
+      bool caller = ! strcmp (space, "caller");
+      bool base = ! strcmp (space, "base");
+
+      if (caller || base)
+	{
+	  if (caller)
+	    octave_call_stack::goto_caller_frame ();
+	  else
+	    octave_call_stack::goto_base_frame ();
+
+	  if (! error_state)
+	    unwind_protect::add (octave_call_stack::unwind_pop);
+
+	  val = symbol_table::varval (name);
+	}
+      else
+	mexErrMsgTxt ("mexGetVariable: symbol table does not exist");
+
+      unwind_protect::run_frame ("mexGetVariable");
+    }
+
+  if (val.is_defined ())
+    {
+      retval = mex_context->make_value (val);
+
+      retval->set_name (name);
+    }
+
+  return retval;
+}
+
+const mxArray *
+mexGetVariablePtr (const char *space, const char *name)
+{
+  return mexGetVariable (space, name);
+}
+
+int
+mexPutVariable (const char *space, const char *name, mxArray *ptr)
+{
+  if (! ptr)
+    return 1;
+
+  if (! name)
+    return 1;
+
+  if (name[0] == '\0')
+    name = ptr->get_name ();
+
+  if (! name || name[0] == '\0')
+    return 1;
+
+  if (! strcmp (space, "global"))
+    set_global_value (name, mxArray::as_octave_value (ptr));
+  else
+    {
+      // FIXME -- should this be in variables.cc?
+
+      unwind_protect::begin_frame ("mexPutVariable");
+
+      bool caller = ! strcmp (space, "caller");
+      bool base = ! strcmp (space, "base");
+
+      if (caller || base)
+	{
+	  if (caller)
+	    octave_call_stack::goto_caller_frame ();
+	  else
+	    octave_call_stack::goto_base_frame ();
+
+	  if (! error_state)
+	    unwind_protect::add (octave_call_stack::unwind_pop);
+
+	  symbol_table::varref (name) = mxArray::as_octave_value (ptr);
+	}
+      else
+	mexErrMsgTxt ("mexPutVariable: symbol table does not exist");
+
+      unwind_protect::run_frame ("mexPutVariable");
+    }
+
+  return 0;
+}
+
+void
+mexMakeArrayPersistent (mxArray *ptr)
+{
+  maybe_unmark_array (ptr);
+}
+
+void
+mexMakeMemoryPersistent (void *ptr)
+{
+  maybe_unmark (ptr);
+}
+
+int
+mexAtExit (void (*f) (void))
+{
+  if (mex_context)
+    {
+      octave_mex_function *curr_mex_fcn = mex_context->current_mex_function ();
+
+      assert (curr_mex_fcn);
+
+      curr_mex_fcn->atexit (f);
+    }
+
+  return 0;
+}
+
+const mxArray *
+mexGet (double handle, const char *property)
+{
+  mxArray *m = 0;
+  octave_value ret = get_property_from_handle (handle, property, "mexGet");
+
+  if (!error_state && ret.is_defined())
+    m = ret.as_mxArray ();
+  return m;
+}
+
+int
+mexIsGlobal (const mxArray *ptr)
+{
+  return mxIsFromGlobalWS (ptr);
+}
+
+int
+mexIsLocked (void)
+{
+  int retval = 0;
+
+  if (mex_context)
+    {
+      const char *fname = mexFunctionName ();
+
+      retval = mislocked (fname);
+    }
+
+  return retval;
+}
+
+std::map<std::string,int> mex_lock_count;
+
+void
+mexLock (void)
+{
+  if (mex_context)
+    {
+      const char *fname = mexFunctionName ();
+
+      if (mex_lock_count.find (fname) == mex_lock_count.end ())
+	mex_lock_count[fname] = 1;
+      else
+	mex_lock_count[fname]++;
+
+      mlock ();
+    }
+}
+
+int
+mexSet (double handle, const char *property, mxArray *val)
+{
+  bool ret = 
+    set_property_in_handle (handle, property, mxArray::as_octave_value (val),
+			    "mexSet");
+  return (ret ? 0 : 1);
+}
+
+void
+mexUnlock (void)
+{
+  if (mex_context)
+    {
+      const char *fname = mexFunctionName ();
+
+      std::map<std::string,int>::iterator p = mex_lock_count.find (fname);
+
+      if (p != mex_lock_count.end ())
+	{
+	  int count = --mex_lock_count[fname];
+
+	  if (count == 0)
+	    {
+	      munlock (fname);
+
+	      mex_lock_count.erase (p);
+	    }
+	}
+    }
+}
diff --git a/src/mex.h b/src/mex.h
new file mode 100644
index 0000000..03bdc39
--- /dev/null
+++ b/src/mex.h
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 2001, 2006, 2007 Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+This code was originally distributed as part of Octave Forge under
+the following terms:
+
+Author: Paul Kienzle
+I grant this code to the public domain.
+2001-03-22
+
+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.
+
+*/
+
+/* mex.h is for use in C-programs only; do NOT include it in mex.cc */
+
+#if ! defined (MEX_H)
+#define MEX_H
+
+#define HAVE_OCTAVE
+
+typedef void mxArray;
+
+#if ! defined (__cplusplus)
+typedef int bool;
+#endif
+
+/* -V4 stuff */
+#if defined (V4)
+#define Matrix mxArray
+#define REAL mxREAL
+#endif
+
+#define mxMAXNAME 64
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined (V4)
+void mexFunction (int nlhs, mxArray* plhs[], int nrhs, mxArray *prhs[]);
+#else
+void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray *prhs[]);
+#endif
+  
+#include "mexproto.h"
+
+/* V4 floating point routines renamed in V5.  */
+#define mexIsNaN mxIsNaN
+#define mexIsFinite mxIsFinite
+#define mexIsInf mxIsInf
+#define mexGetEps mxGetEps
+#define mexGetInf mxGetInf
+#define mexGetNaN mxGetNan
+  
+#define mexGetGlobal(nm) mexGetArray (nm, "global")
+#define mexGetMatrix(nm) mexGetArray (nm, "caller")
+#define mexGetMatrixPtr(nm) mexGetArrayPtr (nm, "caller")
+
+#define mexGetArray(nm, space) mexGetVariable (space, nm)
+#define mexGetArrayPtr(nm, space) mexGetVariablePtr (space, nm)
+
+#define mexPutMatrix(ptr) mexPutVariable ("caller", "", ptr)
+#define mexPutArray(ptr, space) mexPutVariable (space, "", ptr)
+  
+#define mxCreateFull mxCreateDoubleMatrix
+
+#define mxCreateScalarDouble mxCreateDoubleScalar
+
+#define mxFreeMatrix mxDestroyArray
+
+#define mxIsString mxIsChar
+
+/* Apparently these are also defined.  */
+
+#ifndef UINT64_T
+#define UINT64_T uint64_t
+#endif
+
+#ifndef uint64_T
+#define uint64_T uint64_t
+#endif
+
+#ifndef INT64_T
+#define INT64_T int64_t
+#endif
+
+#ifndef int64_T
+#define int64_T int64_t
+#endif
+
+#ifndef UINT32_T
+#define UINT32_T uint32_t
+#endif
+
+#ifndef uint32_T
+#define uint32_T uint32_t
+#endif
+
+#ifndef INT32_T
+#define INT32_T int32_t
+#endif
+
+#ifndef int32_T
+#define int32_T int32_t
+#endif
+
+#ifndef UINT16_T
+#define UINT16_T uint16_t
+#endif
+
+#ifndef uint16_T
+#define uint16_T uint16_t
+#endif
+
+#ifndef INT16_T
+#define INT16_T int16_t
+#endif
+
+#ifndef int16_T
+#define int16_T int16_t
+#endif
+
+#ifndef UINT8_T
+#define UINT8_T uint8_t
+#endif
+
+#ifndef uint8_T
+#define uint8_T uint8_t
+#endif
+
+#ifndef INT8_T
+#define INT8_T int8_t
+#endif
+
+#ifndef int8_T
+#define int8_T int8_t
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/src/mexproto.h b/src/mexproto.h
new file mode 100644
index 0000000..9da4ac9
--- /dev/null
+++ b/src/mexproto.h
@@ -0,0 +1,275 @@
+/*
+
+Copyright (C) 2006, 2007, 2008 Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+This code was originally distributed as part of Octave Forge under
+the following terms:
+
+Author: Paul Kienzle
+I grant this code to the public domain.
+2001-03-22
+
+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.
+
+*/
+
+/* mex.h is for use in C-programs only; do NOT include it in mex.cc */
+
+#if ! defined (MEXPROTO_H)
+#define MEXPROTO_H
+
+#if defined (__cplusplus)
+#include <cstdlib>
+extern "C" {
+#else
+#include <stdlib.h>
+#endif
+
+#include "oct-dlldefs.h"
+
+#define MXARRAY_TYPEDEFS_ONLY
+#include "mxarray.h"
+#undef MXARRAY_TYPEDEFS_ONLY
+
+// Interface to the interpreter.
+extern OCTINTERP_API const char *mexFunctionName (void);
+
+extern OCTINTERP_API int mexCallMATLAB (int nargout, mxArray *argout[], int nargin,
+			  mxArray *argin[], const char *fname);
+
+extern OCTINTERP_API void mexSetTrapFlag (int flag);
+extern OCTINTERP_API int mexEvalString (const char *s);
+extern OCTINTERP_API void mexErrMsgTxt (const char *s);
+extern OCTINTERP_API void mexErrMsgIdAndTxt (const char *id, const char *s, ...);
+extern OCTINTERP_API void mexWarnMsgTxt (const char *s);
+extern OCTINTERP_API void mexWarnMsgIdAndTxt (const char *id, const char *s, ...);
+extern OCTINTERP_API void mexPrintf (const char *fmt, ...);
+  
+extern OCTINTERP_API mxArray *mexGetVariable (const char *space, const char *name);
+extern OCTINTERP_API const mxArray *mexGetVariablePtr (const char *space, const char *name);
+
+extern OCTINTERP_API int mexPutVariable (const char *space, const char *name, mxArray *ptr);
+
+extern OCTINTERP_API void mexMakeArrayPersistent (mxArray *ptr);
+extern OCTINTERP_API void mexMakeMemoryPersistent (void *ptr);
+
+extern OCTINTERP_API int mexAtExit (void (*f) (void));
+extern OCTINTERP_API const mxArray *mexGet (double handle, const char *property);
+extern OCTINTERP_API int mexIsGlobal (const mxArray *ptr);
+extern OCTINTERP_API int mexIsLocked (void);
+extern OCTINTERP_API void mexLock (void);
+extern OCTINTERP_API int mexSet (double handle, const char *property, mxArray *val);
+extern OCTINTERP_API void mexUnlock (void);
+
+// Floating point predicates.
+extern OCTINTERP_API int mxIsFinite (double v);
+extern OCTINTERP_API int mxIsInf (double v);
+extern OCTINTERP_API int mxIsNaN (double v);
+
+// Floating point values.
+extern OCTINTERP_API double mxGetEps (void);
+extern OCTINTERP_API double mxGetInf (void);
+extern OCTINTERP_API double mxGetNaN (void);
+  
+// Memory management.
+extern OCTINTERP_API void *mxCalloc (size_t n, size_t size);
+extern OCTINTERP_API void *mxMalloc (size_t n);
+extern OCTINTERP_API void *mxRealloc (void *ptr, size_t size);
+extern OCTINTERP_API void mxFree (void *ptr);
+  
+// Constructors.
+extern OCTINTERP_API mxArray *mxCreateCellArray (mwSize ndims, const mwSize *dims);
+extern OCTINTERP_API mxArray *mxCreateCellMatrix (mwSize m, mwSize n);
+extern OCTINTERP_API mxArray *mxCreateCharArray (mwSize ndims, const mwSize *dims);
+extern OCTINTERP_API mxArray *mxCreateCharMatrixFromStrings (mwSize m, const char **str);
+extern OCTINTERP_API mxArray *mxCreateDoubleMatrix (mwSize nr, mwSize nc, mxComplexity flag);
+extern OCTINTERP_API mxArray *mxCreateDoubleScalar (double val);
+extern OCTINTERP_API mxArray *mxCreateLogicalArray (mwSize ndims, const mwSize *dims);
+extern OCTINTERP_API mxArray *mxCreateLogicalMatrix (mwSize m, mwSize n);
+extern OCTINTERP_API mxArray *mxCreateLogicalScalar (mxLogical val);
+extern OCTINTERP_API mxArray *mxCreateNumericArray (mwSize ndims, const mwSize *dims, mxClassID class_id, mxComplexity flag);
+extern OCTINTERP_API mxArray *mxCreateNumericMatrix (mwSize m, mwSize n, mxClassID class_id, mxComplexity flag);
+extern OCTINTERP_API mxArray *mxCreateSparse (mwSize m, mwSize n, mwSize nzmax, mxComplexity flag);
+extern OCTINTERP_API mxArray *mxCreateSparseLogicalMatrix (mwSize m, mwSize n, mwSize nzmax);
+extern OCTINTERP_API mxArray *mxCreateString (const char *str);
+extern OCTINTERP_API mxArray *mxCreateStructArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys);
+extern OCTINTERP_API mxArray *mxCreateStructMatrix (mwSize rows, mwSize cols, int num_keys, const char **keys);
+
+// Copy constructor.
+extern OCTINTERP_API mxArray *mxDuplicateArray (const mxArray *v);
+
+// Destructor.
+extern OCTINTERP_API void mxDestroyArray (mxArray *v);
+
+// Type Predicates.
+extern OCTINTERP_API int mxIsCell (const mxArray *ptr);
+extern OCTINTERP_API int mxIsChar (const mxArray *ptr);
+extern OCTINTERP_API int mxIsClass (const mxArray *ptr, const char *name);
+extern OCTINTERP_API int mxIsComplex (const mxArray *ptr);
+extern OCTINTERP_API int mxIsDouble (const mxArray *ptr);
+extern OCTINTERP_API int mxIsInt16 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsInt32 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsInt64 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsInt8 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsLogical (const mxArray *ptr);
+extern OCTINTERP_API int mxIsNumeric (const mxArray *ptr);
+extern OCTINTERP_API int mxIsSingle (const mxArray *ptr);
+extern OCTINTERP_API int mxIsSparse (const mxArray *ptr);
+extern OCTINTERP_API int mxIsStruct (const mxArray *ptr);
+extern OCTINTERP_API int mxIsUint16 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsUint32 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsUint64 (const mxArray *ptr);
+extern OCTINTERP_API int mxIsUint8 (const mxArray *ptr);
+
+// Odd type+size predicate.
+extern OCTINTERP_API int mxIsLogicalScalar (const mxArray *ptr);
+
+// Odd type+size+value predicate.
+extern OCTINTERP_API int mxIsLogicalScalarTrue (const mxArray *ptr);
+
+// Size predicate.
+extern OCTINTERP_API int mxIsEmpty (const mxArray *ptr);
+
+// Just plain odd thing to ask of a value.
+extern OCTINTERP_API int mxIsFromGlobalWS (const mxArray *ptr);
+
+// Dimension extractors.
+extern OCTINTERP_API size_t mxGetM (const mxArray *ptr);
+extern OCTINTERP_API size_t mxGetN (const mxArray *ptr);
+extern OCTINTERP_API mwSize *mxGetDimensions (const mxArray *ptr);
+extern OCTINTERP_API mwSize mxGetNumberOfDimensions (const mxArray *ptr);
+extern OCTINTERP_API size_t mxGetNumberOfElements (const mxArray *ptr);
+
+// Dimension setters.
+extern OCTINTERP_API void mxSetM (mxArray *ptr, mwSize M);
+extern OCTINTERP_API void mxSetN (mxArray *ptr, mwSize N);
+extern OCTINTERP_API void mxSetDimensions (mxArray *ptr, mwSize *dims, mwSize ndims);
+  
+// Data extractors.
+extern OCTINTERP_API double *mxGetPi (const mxArray *ptr);
+extern OCTINTERP_API double *mxGetPr (const mxArray *ptr);
+extern OCTINTERP_API double mxGetScalar (const mxArray *ptr);
+extern OCTINTERP_API mxChar *mxGetChars (const mxArray *ptr);
+extern OCTINTERP_API mxLogical *mxGetLogicals (const mxArray *ptr);
+extern OCTINTERP_API void *mxGetData (const mxArray *ptr);
+extern OCTINTERP_API void *mxGetImagData (const mxArray *ptr);
+
+// Data setters./
+extern OCTINTERP_API void mxSetPr (mxArray *ptr, double *pr);
+extern OCTINTERP_API void mxSetPi (mxArray *ptr, double *pi);
+extern OCTINTERP_API void mxSetData (mxArray *ptr, void *data);
+extern OCTINTERP_API void mxSetImagData (mxArray *ptr, void *pi);
+
+// Classes.
+extern OCTINTERP_API mxClassID mxGetClassID (const mxArray *ptr);
+extern OCTINTERP_API const char *mxGetClassName (const mxArray *ptr);
+
+extern OCTINTERP_API void mxSetClassName (mxArray *ptr, const char *name);
+
+// Cell support.
+extern OCTINTERP_API mxArray *mxGetCell (const mxArray *ptr, mwIndex idx);
+
+extern OCTINTERP_API void mxSetCell (mxArray *ptr, mwIndex idx, mxArray *val);
+
+// Sparse support.
+extern OCTINTERP_API mwIndex *mxGetIr (const mxArray *ptr);
+extern OCTINTERP_API mwIndex *mxGetJc (const mxArray *ptr);
+extern OCTINTERP_API mwSize mxGetNzmax (const mxArray *ptr);
+
+extern OCTINTERP_API void mxSetIr (mxArray *ptr, mwIndex *ir);
+extern OCTINTERP_API void mxSetJc (mxArray *ptr, mwIndex *jc);
+extern OCTINTERP_API void mxSetNzmax (mxArray *ptr, mwSize nzmax);
+
+// Structure support.
+extern OCTINTERP_API int mxAddField (mxArray *ptr, const char *key);
+
+extern OCTINTERP_API void mxRemoveField (mxArray *ptr, int key_num);
+
+extern OCTINTERP_API mxArray *mxGetField (const mxArray *ptr, mwIndex index, const char *key);
+extern OCTINTERP_API mxArray *mxGetFieldByNumber (const mxArray *ptr, mwIndex index, int key_num);
+
+extern OCTINTERP_API void mxSetField (mxArray *ptr, mwIndex index, const char *key, mxArray *val);
+extern OCTINTERP_API void mxSetFieldByNumber (mxArray *ptr, mwIndex index, int key_num, mxArray *val);
+
+extern OCTINTERP_API int mxGetNumberOfFields (const mxArray *ptr);
+
+extern OCTINTERP_API const char *mxGetFieldNameByNumber (const mxArray *ptr, int key_num);
+extern OCTINTERP_API int mxGetFieldNumber (const mxArray *ptr, const char *key);
+
+extern OCTINTERP_API int mxGetString (const mxArray *ptr, char *buf, mwSize buflen);
+extern OCTINTERP_API char *mxArrayToString (const mxArray *ptr);
+  
+// Miscellaneous.
+#ifdef NDEBUG
+#define mxAssert(expr, msg) \
+  do \
+    { \
+      if (! expr) \
+        { \
+          mexPrintf ("Assertion failed: %s, at line %d of file \"%s\".\n%s\n", \
+                     #expr, __LINE__, __FILE__, msg); \
+        } \
+    } \
+  while (0)
+
+#define mxAssertS(expr, msg) \
+  do \
+    { \
+      if (! expr) \
+        { \
+          mexPrintf ("Assertion failed at line %d of file \"%s\".\n%s\n", \
+                     __LINE__, __FILE__, msg); \
+          abort (); \
+        } \
+    } \
+  while (0)
+#else
+#define mxAssert(expr, msg)
+#define mxAssertS(expr, msg)
+#endif
+
+extern OCTINTERP_API mwIndex mxCalcSingleSubscript (const mxArray *ptr, mwSize nsubs, mwIndex *subs);
+
+extern OCTINTERP_API size_t mxGetElementSize (const mxArray *ptr);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/src/mk-errno-list b/src/mk-errno-list
new file mode 100755
index 0000000..865d459
--- /dev/null
+++ b/src/mk-errno-list
@@ -0,0 +1,52 @@
+#! /bin/sh
+#
+# Copyright (C) 2005, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+if [ $# -ne 2 ]; then
+  echo "usage: get-errno-list [--perl PERL|--python PYTHON]" 1>&2
+  exit 1
+fi
+
+if [ $1 = "--perl" ]; then
+  PERL="$2";
+  $PERL -e 'foreach $key (keys(%!)) {
+    $x .= "#if defined ($key)\n    { \"$key\", $key, },\n#endif\n";
+  }
+  while (<>) {
+    s/^ *\@SYSDEP_ERRNO_LIST\@/$ x/;
+    print;
+  }'
+
+elif [ $1 = "--python" ]; then
+  PYTHON="$2";
+  $PYTHON -c '
+from errno import errorcode
+from sys import stdin
+
+t = "#if defined (%s)\n    { \"%s\", %s, },\n#endif\n"
+errstr = ""
+for k in errorcode.keys():
+    errstr += t % tuple(3*[errorcode[k]])
+
+for l in stdin:
+    print l.replace("@SYSDEP_ERRNO_LIST@", errstr),
+'
+fi
+
+exit $?
diff --git a/src/mk-pkg-add b/src/mk-pkg-add
new file mode 100755
index 0000000..306d976
--- /dev/null
+++ b/src/mk-pkg-add
@@ -0,0 +1,51 @@
+#! /bin/sh -e
+#
+# Copyright (C) 2005, 2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+SED=${SED:-'sed'}
+
+for f in "$@"; do
+  if [ -f $f ]; then
+
+    ## Compute and print the autoloads.
+  
+    base=`basename $f | $SED 's/\.df$//'`
+    fcns=`$SED -n -e 's/^ *XDEFUN_DLD_INTERNAL *( *\([^, ]*\)[, ].*$/\1/p' \
+                  -e 's/^ *XDEFUNX_DLD_INTERNAL *( *"\([^"]*\)".*$/\1/p' $f | \
+	  sort -u`
+    if [ -n "$fcns" ]; then
+      for n in $fcns; do
+	if [ "$n" = "$base" ]; then
+	  true
+	else
+          echo "autoload (\"$n\", \"$base.oct\");"
+	fi
+      done
+    fi
+
+    ## Process PKG_ADD directives after autoloads so that all
+    ## necessary functions can be found before they are used.
+
+    $SED -n -e 's,^//* *PKG_ADD: *,,p' \
+            -e 's,^/\* *PKG_ADD: *\(.*\) *\*/ *$,\1,p' $f
+
+  fi
+done
+
+exit $?
diff --git a/src/mkbuiltins b/src/mkbuiltins
new file mode 100755
index 0000000..150eea1
--- /dev/null
+++ b/src/mkbuiltins
@@ -0,0 +1,116 @@
+#! /bin/sh
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005,
+#               2006, 2007, 2008, 2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+if test $# -ne 1; then
+  echo "usage: mkbuiltins f1" 1>&2
+  exit 1
+fi
+
+SED=${SED:-'sed'}
+
+DEF_FILES=`cat $1`
+
+if test -z "$DEF_FILES"; then
+  echo "mkbuiltins: DEF_FILES is empty!" 1>&2
+  exit 1
+fi
+
+cat << \EOF
+// DO NOT EDIT!  Generated automatically by mkbuiltins.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "defun.h"
+#include "oct-obj.h"
+#include "variables.h"
+#include "builtins.h"
+
+#if defined (quad)
+#undef quad
+#endif
+
+#if defined (ENABLE_DYNAMIC_LINKING)
+
+#define XDEFUN_DLD_INTERNAL(name, args_name, nargout_name, doc)
+
+#define XDEFUNX_DLD_INTERNAL(name, fname, args_name, nargout_name, doc)
+
+#else
+
+#define XDEFUN_DLD_INTERNAL(name, args_name, nargout_name, doc) \
+  XDEFUN_INTERNAL(name, args_name, nargout_name, doc)
+
+#define XDEFUNX_DLD_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, doc)
+
+#endif
+
+#define XDEFUN_FILE_NAME(name)
+
+#define XDEFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  extern DECLARE_FUN (name, args_name, nargout_name); \
+  install_builtin_function (F ## name, #name, doc); \
+
+#define XDEFCONSTFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  extern DECLARE_FUN (name, args_name, nargout_name); \
+  install_builtin_function (F ## name, #name, doc, false); \
+
+#define XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  extern DECLARE_FUNX (fname, args_name, nargout_name); \
+  install_builtin_function (fname, name, doc); \
+
+#define XDEFALIAS_INTERNAL(alias, name) \
+  alias_builtin (#alias, #name);
+
+#define XDEFCONST_INTERNAL(name, defn, doc)
+
+EOF
+
+for file in $DEF_FILES; do
+  fcn=`echo $file | $SED 's,^\./,,; s/\.df//; s/-/_/g'`
+  echo "static void"
+  echo "install_${fcn}_fcns (void)"
+  echo "{"
+  cat $file
+  echo "}"
+  echo ""
+done
+
+cat << \EOF
+
+void
+install_builtins (void)
+{
+EOF
+
+for file in $DEF_FILES; do
+  fcn=`echo $file | $SED 's,^\./,,; s/\.df//; s/-/_/g'`
+  echo "  install_${fcn}_fcns ();"
+done
+
+cat << \EOF
+}
+
+EOF
+
+exit 0
diff --git a/src/mkdefs b/src/mkdefs
new file mode 100755
index 0000000..95d7536
--- /dev/null
+++ b/src/mkdefs
@@ -0,0 +1,34 @@
+#! /bin/sh
+#
+# Copyright (C) 1996, 1999, 2000, 2003, 2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+SED=${SED:-'sed'}
+
+$SED -n -e '/^ *BEGIN_INSTALL_BUILTIN/{
+  : loop
+  s/BEGIN_INSTALL_BUILTIN//
+  s/^#[ \t][ \t]*[0-9][0-9]*.*$//
+  /END_INSTALL_BUILTIN/b done
+  p
+  n
+  b loop
+  : done
+  s/END_INSTALL_BUILTIN//
+  p
+}'
diff --git a/src/mkgendoc b/src/mkgendoc
new file mode 100755
index 0000000..9b0863b
--- /dev/null
+++ b/src/mkgendoc
@@ -0,0 +1,126 @@
+#! /bin/sh
+#
+# Copyright (C) 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2008,
+#               2009 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+SED=${SED:-'sed'}
+
+if test $# -ne 1; then
+  echo "usage: mkgendoc f1" 1>&2
+  exit 1
+fi
+
+DOC_FILES=`cat $1`
+
+if test -z "$DOC_FILES"; then
+  echo "mkgendoc: DOC_FILES is empty!" 1>&2
+  exit 1
+fi
+
+cat << \EOF
+// DO NOT EDIT!  Generated automatically by mkgendoc
+
+#if defined (__DECCXX)
+#define __USE_STD_IOSTREAM
+#endif
+
+#include <iostream>
+#include <string>
+
+#define XDEFUN_FILE_NAME(name) \
+  std::string file_name = name;
+
+#define XDEFUN_DLD_INTERNAL(name, args_name, nargout_name, doc) \
+  print_doc_string (#name, file_name, doc);
+
+#define XDEFUNX_DLD_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  print_doc_string (name, file_name, doc);
+
+#define XDEFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  print_doc_string (#name, file_name, doc);
+
+#define XDEFCONSTFUN_INTERNAL(name, args_name, nargout_name, doc) \
+  print_doc_string (#name, file_name, doc);
+
+#define XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, doc) \
+  print_doc_string (name, file_name, doc);
+
+#define XDEFALIAS_INTERNAL(alias, name)
+
+#define XDEFVAR_INTERNAL(name, sname, defn, protect, chg_fcn, doc) \
+  print_doc_string (#name, file_name, doc);
+
+#define XDEFCONST_INTERNAL(name, defn, doc) \
+  print_doc_string (#name, file_name, doc);
+
+static void
+print_doc_string (const std::string& name, const std::string& file_name,
+		  const std::string& doc)
+{
+  std::cout << "";
+
+  size_t len = name.length ();
+
+  if (name[0] == '"' && name[len-1] == '"')
+    std::cout << name.substr (1, len-2) << "\n";
+  else
+    std::cout << name << "\n";
+
+  std::cout << "@c " << file_name << "\n"
+	    << doc << "\n";
+}
+
+EOF
+
+for file in $DOC_FILES; do
+  fcn=`echo $file | $SED 's,^\./,,; s/\.df//; s/-/_/g'`
+  echo "static void"
+  echo "print_${fcn}_doc_strings (void)"
+  echo "{"
+  cat $file
+  echo "}"
+  echo ""
+done
+
+cat << \EOF
+
+int
+main (void)
+{
+  std::cout
+    << "### DO NOT EDIT!\n"
+    << "###\n"
+    << "### This file is generated automatically from the Octave sources.\n"
+    << "### Edit those files instead and run make to update this file.\n"
+    << std::endl;
+
+EOF
+
+for file in $DOC_FILES; do
+  fcn=`echo $file | $SED 's,^\./,,; s/\.df//; s/-/_/g'`
+  echo "  print_${fcn}_doc_strings ();"
+done
+
+cat << \EOF
+
+  return 0;
+}
+EOF
+
+exit 0
diff --git a/src/mkops b/src/mkops
new file mode 100755
index 0000000..2d88d94
--- /dev/null
+++ b/src/mkops
@@ -0,0 +1,57 @@
+#! /bin/sh
+#
+# Copyright (C) 1997, 1998, 2003, 2006, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+SED=${SED:-'sed'}
+
+cat << \EOF
+// DO NOT EDIT!  Generated automatically by mkbuiltins.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+extern void install_base_type_conversions (void);
+
+EOF
+
+for file in "$@"; do
+  f=`echo $file | $SED 's,^\./,,; s%^OPERATORS/op-%%; s%\.cc%%; s%-%_%g'`
+  echo "extern void install_${f}_ops (void);"
+done
+
+cat << \EOF
+
+void
+install_ops (void)
+{
+  install_base_type_conversions ();
+
+EOF
+
+for file in "$@"; do
+  f=`echo $file | $SED 's,^\./,,; s%^OPERATORS/op-%%; s%\.cc%%; s%-%_%g'`
+  echo "  install_${f}_ops ();"
+done
+
+cat << \EOF
+}
+EOF
+
+exit 0
diff --git a/src/mxarray.h b/src/mxarray.h
new file mode 100644
index 0000000..d8961ad
--- /dev/null
+++ b/src/mxarray.h
@@ -0,0 +1,345 @@
+/*
+
+Copyright (C) 2001, 2006, 2007, 2008 Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+Part of this code was originally distributed as part of Octave Forge under
+the following terms:
+
+Author: Paul Kienzle
+I grant this code to the public domain.
+2001-03-22
+
+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.
+
+*/
+
+#if ! defined (MXARRAY_H)
+#define MXARRAY_H
+
+typedef enum
+  {
+    mxREAL = 0,
+    mxCOMPLEX = 1
+  }
+  mxComplexity;
+
+typedef enum
+  {
+    mxUNKNOWN_CLASS = 0,
+    mxCELL_CLASS,
+    mxSTRUCT_CLASS,
+    mxLOGICAL_CLASS,
+    mxCHAR_CLASS,
+    mxUNUSED_CLASS,
+    mxDOUBLE_CLASS,
+    mxSINGLE_CLASS,
+    mxINT8_CLASS,
+    mxUINT8_CLASS,
+    mxINT16_CLASS,
+    mxUINT16_CLASS,
+    mxINT32_CLASS,
+    mxUINT32_CLASS,
+    mxINT64_CLASS,
+    mxUINT64_CLASS,
+    mxFUNCTION_CLASS
+  }
+  mxClassID;
+
+typedef unsigned char mxLogical;
+
+/* typedef Uint16 mxChar; */
+typedef char mxChar;
+
+/* 
+ * FIXME? Mathworks says these should be size_t on 64-bit system and when
+ * mex is used with the -largearraydims flag, but why do that? Its better
+ * to conform to the same indexing as the rest of Octave
+ */
+typedef int mwSize;
+typedef int mwIndex;
+
+#if ! defined (MXARRAY_TYPEDEFS_ONLY)
+
+#include <cstring>
+
+class octave_value;
+
+#define DO_MUTABLE_METHOD(RET_T, METHOD_CALL) \
+  RET_T retval = rep->METHOD_CALL; \
+ \
+  if (rep->mutation_needed ()) \
+    { \
+      maybe_mutate (); \
+      retval = rep->METHOD_CALL; \
+    } \
+ \
+  return retval
+
+#define DO_VOID_MUTABLE_METHOD(METHOD_CALL) \
+  rep->METHOD_CALL; \
+ \
+  if (rep->mutation_needed ()) \
+    { \
+      maybe_mutate (); \
+      rep->METHOD_CALL; \
+    }
+
+// This just provides a way to avoid infinite recursion when building
+// mxArray objects.
+
+struct
+xmxArray
+{
+  xmxArray (void) { }
+};
+
+// The main interface class.  The representation can be based on an
+// octave_value object or a separate object that tries to reproduce
+// the semantics of mxArray objects in Matlab more directly.
+
+class mxArray
+{
+public:
+
+  mxArray (const octave_value& ov);
+
+  mxArray (mxClassID id, mwSize ndims, const mwSize *dims,
+	   mxComplexity flag = mxREAL);
+
+  mxArray (mxClassID id, const dim_vector& dv, mxComplexity flag = mxREAL);
+
+  mxArray (mxClassID id, mwSize m, mwSize n, mxComplexity flag = mxREAL);
+
+  mxArray (mxClassID id, double val);
+
+  mxArray (mxClassID id, mxLogical val);
+
+  mxArray (const char *str);
+
+  mxArray (mwSize m, const char **str);
+
+  mxArray (mxClassID id, mwSize m, mwSize n, mwSize nzmax,
+	   mxComplexity flag = mxREAL);
+
+  mxArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys);
+
+  mxArray (const dim_vector& dv, int num_keys, const char **keys);
+
+  mxArray (mwSize m, mwSize n, int num_keys, const char **keys);
+
+  mxArray (mwSize ndims, const mwSize *dims);
+
+  mxArray (const dim_vector& dv);
+
+  mxArray (mwSize m, mwSize n);
+
+  virtual mxArray *clone (void) const
+  {
+    mxArray *new_rep = rep->clone ();
+
+    return new mxArray (new_rep, name);
+  }
+
+  virtual ~mxArray (void);
+
+  virtual bool is_octave_value (void) const { return rep->is_octave_value (); }
+
+  virtual int is_cell (void) const { return rep->is_cell (); }
+
+  virtual int is_char (void) const { return rep->is_char (); }
+
+  virtual int is_class (const char *name_arg) const { return rep->is_class (name_arg); }
+
+  virtual int is_complex (void) const { return rep->is_complex (); }
+
+  virtual int is_double (void) const { return rep->is_double (); }
+
+  virtual int is_int16 (void) const { return rep->is_int16 (); }
+
+  virtual int is_int32 (void) const { return rep->is_int32 (); }
+
+  virtual int is_int64 (void) const { return rep->is_int64 (); }
+
+  virtual int is_int8 (void) const { return rep->is_int8 (); }
+
+  virtual int is_logical (void) const { return rep->is_logical (); }
+
+  virtual int is_numeric (void) const { return rep->is_numeric (); }
+
+  virtual int is_single (void) const { return rep->is_single (); }
+
+  virtual int is_sparse (void) const { return rep->is_sparse (); }
+
+  virtual int is_struct (void) const { return rep->is_struct (); }
+
+  virtual int is_uint16 (void) const { return rep->is_uint16 (); }
+
+  virtual int is_uint32 (void) const { return rep->is_uint32 (); }
+
+  virtual int is_uint64 (void) const { return rep->is_uint64 (); }
+
+  virtual int is_uint8 (void) const { return rep->is_uint8 (); }
+
+  virtual int is_logical_scalar (void) const { return rep->is_logical_scalar (); }
+
+  virtual int is_logical_scalar_true (void) const { return rep->is_logical_scalar_true (); }
+
+  virtual mwSize get_m (void) const { return rep->get_m (); }
+
+  virtual mwSize get_n (void) const { return rep->get_n (); }
+
+  virtual mwSize *get_dimensions (void) const { return rep->get_dimensions (); }
+
+  virtual mwSize get_number_of_dimensions (void) const { return rep->get_number_of_dimensions (); }
+
+  virtual void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); }
+
+  virtual void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); }
+
+  virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); }
+
+  virtual mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); }
+
+  virtual int is_empty (void) const { return get_number_of_elements () == 0; }
+
+  const char *get_name (void) const { return name; }
+
+  void set_name (const char *name_arg);
+
+  virtual mxClassID get_class_id (void) const { return rep->get_class_id (); }
+
+  virtual const char *get_class_name (void) const { return rep->get_class_name (); }
+
+  virtual void set_class_name (const char *name_arg) { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); }
+
+  virtual mxArray *get_cell (mwIndex idx) const { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); }
+
+  virtual void set_cell (mwIndex idx, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); }
+
+  virtual double get_scalar (void) const { return rep->get_scalar (); }
+
+  virtual void *get_data (void) const { DO_MUTABLE_METHOD (void *, get_data ()); }
+
+  virtual void *get_imag_data (void) const { DO_MUTABLE_METHOD (void *, get_imag_data ()); }
+
+  virtual void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); }
+
+  virtual void set_imag_data (void *pi) { DO_VOID_MUTABLE_METHOD (set_imag_data (pi)); }
+
+  virtual mwIndex *get_ir (void) const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); }
+
+  virtual mwIndex *get_jc (void) const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); }
+
+  virtual mwSize get_nzmax (void) const { return rep->get_nzmax (); }
+
+  virtual void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); }
+
+  virtual void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); }
+
+  virtual void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); }
+
+  virtual int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); }
+
+  virtual void remove_field (int key_num) { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); }
+
+  virtual mxArray *get_field_by_number (mwIndex index, int key_num) const { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); }
+
+  virtual void set_field_by_number (mwIndex index, int key_num, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); }
+
+  virtual int get_number_of_fields (void) const { return rep->get_number_of_fields (); }
+
+  virtual const char *get_field_name_by_number (int key_num) const { DO_MUTABLE_METHOD (const char*, get_field_name_by_number (key_num)); }
+
+  virtual int get_field_number (const char *key) const { DO_MUTABLE_METHOD (int, get_field_number (key)); }
+
+  virtual int get_string (char *buf, mwSize buflen) const { return rep->get_string (buf, buflen); }
+
+  virtual char *array_to_string (void) const { return rep->array_to_string (); }
+
+  virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const { return rep->calc_single_subscript (nsubs, subs); }
+
+  virtual size_t get_element_size (void) const { return rep->get_element_size (); }
+
+  virtual bool mutation_needed (void) const { return rep->mutation_needed (); }
+
+  virtual mxArray *mutate (void) const { return rep->mutate (); }
+
+  static void *malloc (size_t n);
+
+  static void *calloc (size_t n, size_t t);
+
+  static char *strsave (const char *str)
+  {
+    char *retval = 0;
+
+    if (str)
+      {
+	mwSize sz =  sizeof (mxChar) * (strlen (str) + 1);
+	retval = static_cast<char *> (mxArray::malloc (sz));
+	strcpy (retval, str);
+      }
+
+    return retval;
+  }
+
+  static octave_value as_octave_value (mxArray *ptr);
+
+protected:
+
+  virtual octave_value as_octave_value (void) const;
+
+  mxArray (const xmxArray&) : rep (0), name (0) { }
+
+private:
+
+  mutable mxArray *rep;
+
+  char *name;
+
+  mxArray (mxArray *r, const char *n)
+    : rep (r), name (strsave (n)) { }
+
+  void maybe_mutate (void) const;
+
+  // No copying!
+
+  mxArray (const mxArray&);
+
+  mxArray& operator = (const mxArray&);
+};
+
+#undef DO_MUTABLE_METHOD
+#undef DO_VOID_MUTABLE_METHOD
+
+#endif
+#endif
diff --git a/src/mxarray.h.in b/src/mxarray.h.in
new file mode 100644
index 0000000..e391cb4
--- /dev/null
+++ b/src/mxarray.h.in
@@ -0,0 +1,345 @@
+/*
+
+Copyright (C) 2001, 2006, 2007, 2008 Paul Kienzle
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+Part of this code was originally distributed as part of Octave Forge under
+the following terms:
+
+Author: Paul Kienzle
+I grant this code to the public domain.
+2001-03-22
+
+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.
+
+*/
+
+#if ! defined (MXARRAY_H)
+#define MXARRAY_H
+
+typedef enum
+  {
+    mxREAL = 0,
+    mxCOMPLEX = 1
+  }
+  mxComplexity;
+
+typedef enum
+  {
+    mxUNKNOWN_CLASS = 0,
+    mxCELL_CLASS,
+    mxSTRUCT_CLASS,
+    mxLOGICAL_CLASS,
+    mxCHAR_CLASS,
+    mxUNUSED_CLASS,
+    mxDOUBLE_CLASS,
+    mxSINGLE_CLASS,
+    mxINT8_CLASS,
+    mxUINT8_CLASS,
+    mxINT16_CLASS,
+    mxUINT16_CLASS,
+    mxINT32_CLASS,
+    mxUINT32_CLASS,
+    mxINT64_CLASS,
+    mxUINT64_CLASS,
+    mxFUNCTION_CLASS
+  }
+  mxClassID;
+
+typedef unsigned char mxLogical;
+
+/* typedef Uint16 mxChar; */
+typedef char mxChar;
+
+/* 
+ * FIXME? Mathworks says these should be size_t on 64-bit system and when
+ * mex is used with the -largearraydims flag, but why do that? Its better
+ * to conform to the same indexing as the rest of Octave
+ */
+typedef @OCTAVE_IDX_TYPE@ mwSize;
+typedef @OCTAVE_IDX_TYPE@ mwIndex;
+
+#if ! defined (MXARRAY_TYPEDEFS_ONLY)
+
+#include <cstring>
+
+class octave_value;
+
+#define DO_MUTABLE_METHOD(RET_T, METHOD_CALL) \
+  RET_T retval = rep->METHOD_CALL; \
+ \
+  if (rep->mutation_needed ()) \
+    { \
+      maybe_mutate (); \
+      retval = rep->METHOD_CALL; \
+    } \
+ \
+  return retval
+
+#define DO_VOID_MUTABLE_METHOD(METHOD_CALL) \
+  rep->METHOD_CALL; \
+ \
+  if (rep->mutation_needed ()) \
+    { \
+      maybe_mutate (); \
+      rep->METHOD_CALL; \
+    }
+
+// This just provides a way to avoid infinite recursion when building
+// mxArray objects.
+
+struct
+xmxArray
+{
+  xmxArray (void) { }
+};
+
+// The main interface class.  The representation can be based on an
+// octave_value object or a separate object that tries to reproduce
+// the semantics of mxArray objects in Matlab more directly.
+
+class mxArray
+{
+public:
+
+  mxArray (const octave_value& ov);
+
+  mxArray (mxClassID id, mwSize ndims, const mwSize *dims,
+	   mxComplexity flag = mxREAL);
+
+  mxArray (mxClassID id, const dim_vector& dv, mxComplexity flag = mxREAL);
+
+  mxArray (mxClassID id, mwSize m, mwSize n, mxComplexity flag = mxREAL);
+
+  mxArray (mxClassID id, double val);
+
+  mxArray (mxClassID id, mxLogical val);
+
+  mxArray (const char *str);
+
+  mxArray (mwSize m, const char **str);
+
+  mxArray (mxClassID id, mwSize m, mwSize n, mwSize nzmax,
+	   mxComplexity flag = mxREAL);
+
+  mxArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys);
+
+  mxArray (const dim_vector& dv, int num_keys, const char **keys);
+
+  mxArray (mwSize m, mwSize n, int num_keys, const char **keys);
+
+  mxArray (mwSize ndims, const mwSize *dims);
+
+  mxArray (const dim_vector& dv);
+
+  mxArray (mwSize m, mwSize n);
+
+  virtual mxArray *clone (void) const
+  {
+    mxArray *new_rep = rep->clone ();
+
+    return new mxArray (new_rep, name);
+  }
+
+  virtual ~mxArray (void);
+
+  virtual bool is_octave_value (void) const { return rep->is_octave_value (); }
+
+  virtual int is_cell (void) const { return rep->is_cell (); }
+
+  virtual int is_char (void) const { return rep->is_char (); }
+
+  virtual int is_class (const char *name_arg) const { return rep->is_class (name_arg); }
+
+  virtual int is_complex (void) const { return rep->is_complex (); }
+
+  virtual int is_double (void) const { return rep->is_double (); }
+
+  virtual int is_int16 (void) const { return rep->is_int16 (); }
+
+  virtual int is_int32 (void) const { return rep->is_int32 (); }
+
+  virtual int is_int64 (void) const { return rep->is_int64 (); }
+
+  virtual int is_int8 (void) const { return rep->is_int8 (); }
+
+  virtual int is_logical (void) const { return rep->is_logical (); }
+
+  virtual int is_numeric (void) const { return rep->is_numeric (); }
+
+  virtual int is_single (void) const { return rep->is_single (); }
+
+  virtual int is_sparse (void) const { return rep->is_sparse (); }
+
+  virtual int is_struct (void) const { return rep->is_struct (); }
+
+  virtual int is_uint16 (void) const { return rep->is_uint16 (); }
+
+  virtual int is_uint32 (void) const { return rep->is_uint32 (); }
+
+  virtual int is_uint64 (void) const { return rep->is_uint64 (); }
+
+  virtual int is_uint8 (void) const { return rep->is_uint8 (); }
+
+  virtual int is_logical_scalar (void) const { return rep->is_logical_scalar (); }
+
+  virtual int is_logical_scalar_true (void) const { return rep->is_logical_scalar_true (); }
+
+  virtual mwSize get_m (void) const { return rep->get_m (); }
+
+  virtual mwSize get_n (void) const { return rep->get_n (); }
+
+  virtual mwSize *get_dimensions (void) const { return rep->get_dimensions (); }
+
+  virtual mwSize get_number_of_dimensions (void) const { return rep->get_number_of_dimensions (); }
+
+  virtual void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); }
+
+  virtual void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); }
+
+  virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); }
+
+  virtual mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); }
+
+  virtual int is_empty (void) const { return get_number_of_elements () == 0; }
+
+  const char *get_name (void) const { return name; }
+
+  void set_name (const char *name_arg);
+
+  virtual mxClassID get_class_id (void) const { return rep->get_class_id (); }
+
+  virtual const char *get_class_name (void) const { return rep->get_class_name (); }
+
+  virtual void set_class_name (const char *name_arg) { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); }
+
+  virtual mxArray *get_cell (mwIndex idx) const { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); }
+
+  virtual void set_cell (mwIndex idx, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); }
+
+  virtual double get_scalar (void) const { return rep->get_scalar (); }
+
+  virtual void *get_data (void) const { DO_MUTABLE_METHOD (void *, get_data ()); }
+
+  virtual void *get_imag_data (void) const { DO_MUTABLE_METHOD (void *, get_imag_data ()); }
+
+  virtual void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); }
+
+  virtual void set_imag_data (void *pi) { DO_VOID_MUTABLE_METHOD (set_imag_data (pi)); }
+
+  virtual mwIndex *get_ir (void) const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); }
+
+  virtual mwIndex *get_jc (void) const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); }
+
+  virtual mwSize get_nzmax (void) const { return rep->get_nzmax (); }
+
+  virtual void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); }
+
+  virtual void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); }
+
+  virtual void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); }
+
+  virtual int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); }
+
+  virtual void remove_field (int key_num) { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); }
+
+  virtual mxArray *get_field_by_number (mwIndex index, int key_num) const { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); }
+
+  virtual void set_field_by_number (mwIndex index, int key_num, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); }
+
+  virtual int get_number_of_fields (void) const { return rep->get_number_of_fields (); }
+
+  virtual const char *get_field_name_by_number (int key_num) const { DO_MUTABLE_METHOD (const char*, get_field_name_by_number (key_num)); }
+
+  virtual int get_field_number (const char *key) const { DO_MUTABLE_METHOD (int, get_field_number (key)); }
+
+  virtual int get_string (char *buf, mwSize buflen) const { return rep->get_string (buf, buflen); }
+
+  virtual char *array_to_string (void) const { return rep->array_to_string (); }
+
+  virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const { return rep->calc_single_subscript (nsubs, subs); }
+
+  virtual size_t get_element_size (void) const { return rep->get_element_size (); }
+
+  virtual bool mutation_needed (void) const { return rep->mutation_needed (); }
+
+  virtual mxArray *mutate (void) const { return rep->mutate (); }
+
+  static void *malloc (size_t n);
+
+  static void *calloc (size_t n, size_t t);
+
+  static char *strsave (const char *str)
+  {
+    char *retval = 0;
+
+    if (str)
+      {
+	mwSize sz =  sizeof (mxChar) * (strlen (str) + 1);
+	retval = static_cast<char *> (mxArray::malloc (sz));
+	strcpy (retval, str);
+      }
+
+    return retval;
+  }
+
+  static octave_value as_octave_value (mxArray *ptr);
+
+protected:
+
+  virtual octave_value as_octave_value (void) const;
+
+  mxArray (const xmxArray&) : rep (0), name (0) { }
+
+private:
+
+  mutable mxArray *rep;
+
+  char *name;
+
+  mxArray (mxArray *r, const char *n)
+    : rep (r), name (strsave (n)) { }
+
+  void maybe_mutate (void) const;
+
+  // No copying!
+
+  mxArray (const mxArray&);
+
+  mxArray& operator = (const mxArray&);
+};
+
+#undef DO_MUTABLE_METHOD
+#undef DO_VOID_MUTABLE_METHOD
+
+#endif
+#endif
diff --git a/src/oct-conf.h.in b/src/oct-conf.h.in
new file mode 100644
index 0000000..8d85b52
--- /dev/null
+++ b/src/oct-conf.h.in
@@ -0,0 +1,343 @@
+// oct-conf.h.in
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_conf_h)
+#define octave_conf_h 1
+
+#ifndef OCTAVE_CONF_ALL_CFLAGS
+#define OCTAVE_CONF_ALL_CFLAGS %OCTAVE_CONF_ALL_CFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_ALL_CXXFLAGS
+#define OCTAVE_CONF_ALL_CXXFLAGS %OCTAVE_CONF_ALL_CXXFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_ALL_FFLAGS
+#define OCTAVE_CONF_ALL_FFLAGS %OCTAVE_CONF_ALL_FFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_ALL_LDFLAGS
+#define OCTAVE_CONF_ALL_LDFLAGS %OCTAVE_CONF_ALL_LDFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_ARFLAGS
+#define OCTAVE_CONF_ARFLAGS %OCTAVE_CONF_ARFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_AR
+#define OCTAVE_CONF_AR %OCTAVE_CONF_AR%
+#endif
+
+#ifndef OCTAVE_CONF_BLAS_LIBS
+#define OCTAVE_CONF_BLAS_LIBS %OCTAVE_CONF_BLAS_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_CARBON_LIBS
+#define OCTAVE_CONF_CARBON_LIBS %OCTAVE_CONF_CARBON_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_CC
+#define OCTAVE_CONF_CC %OCTAVE_CONF_CC%
+#endif
+
+#ifndef OCTAVE_CONF_CC_VERSION
+#define OCTAVE_CONF_CC_VERSION %OCTAVE_CONF_CC_VERSION%
+#endif
+
+#ifndef OCTAVE_CONF_CFLAGS
+#define OCTAVE_CONF_CFLAGS %OCTAVE_CONF_CFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_CPICFLAG
+#define OCTAVE_CONF_CPICFLAG %OCTAVE_CONF_CPICFLAG%
+#endif
+
+#ifndef OCTAVE_CONF_CPPFLAGS
+#define OCTAVE_CONF_CPPFLAGS %OCTAVE_CONF_CPPFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_CURL_LIBS
+#define OCTAVE_CONF_CURL_LIBS %OCTAVE_CONF_CURL_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_CXXCPP
+#define OCTAVE_CONF_CXXCPP %OCTAVE_CONF_CXXCPP%
+#endif
+
+#ifndef OCTAVE_CONF_CXXFLAGS
+#define OCTAVE_CONF_CXXFLAGS %OCTAVE_CONF_CXXFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_CXXPICFLAG
+#define OCTAVE_CONF_CXXPICFLAG %OCTAVE_CONF_CXXPICFLAG%
+#endif
+
+#ifndef OCTAVE_CONF_CXX
+#define OCTAVE_CONF_CXX %OCTAVE_CONF_CXX%
+#endif
+
+#ifndef OCTAVE_CONF_CXX_VERSION
+#define OCTAVE_CONF_CXX_VERSION %OCTAVE_CONF_CXX_VERSION%
+#endif
+
+#ifndef OCTAVE_CONF_DEFAULT_PAGER
+#define OCTAVE_CONF_DEFAULT_PAGER %OCTAVE_CONF_DEFAULT_PAGER%
+#endif
+
+#ifndef OCTAVE_CONF_DEFS
+#define OCTAVE_CONF_DEFS %OCTAVE_CONF_DEFS%
+#endif
+
+#ifndef OCTAVE_CONF_DL_LD
+#define OCTAVE_CONF_DL_LD %OCTAVE_CONF_DL_LD%
+#endif
+
+#ifndef OCTAVE_CONF_DL_LDFLAGS
+#define OCTAVE_CONF_DL_LDFLAGS %OCTAVE_CONF_DL_LDFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_EXEEXT
+#define OCTAVE_CONF_EXEEXT %OCTAVE_CONF_EXEEXT%
+#endif
+
+#ifndef OCTAVE_CONF_F77
+#define OCTAVE_CONF_F77 %OCTAVE_CONF_F77%
+#endif
+
+#ifndef OCTAVE_CONF_F77_FLOAT_STORE_FLAG
+#define OCTAVE_CONF_F77_FLOAT_STORE_FLAG %OCTAVE_CONF_F77_FLOAT_STORE_FLAG%
+#endif
+
+#ifndef OCTAVE_CONF_FC
+#define OCTAVE_CONF_FC %OCTAVE_CONF_FC%
+#endif
+
+#ifndef OCTAVE_CONF_FFLAGS
+#define OCTAVE_CONF_FFLAGS %OCTAVE_CONF_FFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_FFTW_LIBS
+#define OCTAVE_CONF_FFTW_LIBS %OCTAVE_CONF_FFTW_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_FLIBS
+#define OCTAVE_CONF_FLIBS %OCTAVE_CONF_FLIBS%
+#endif
+
+#ifndef OCTAVE_CONF_FPICFLAG
+#define OCTAVE_CONF_FPICFLAG %OCTAVE_CONF_FPICFLAG%
+#endif
+
+#ifndef OCTAVE_CONF_GLPK_LIBS
+#define OCTAVE_CONF_GLPK_LIBS %OCTAVE_CONF_GLPK_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_GNUPLOT
+#define OCTAVE_CONF_GNUPLOT %OCTAVE_CONF_GNUPLOT%
+#endif
+
+#ifndef OCTAVE_CONF_INCFLAGS
+#define OCTAVE_CONF_INCFLAGS %OCTAVE_CONF_INCFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_INCLUDEDIR
+#define OCTAVE_CONF_INCLUDEDIR %OCTAVE_CONF_INCLUDEDIR%
+#endif
+
+#ifndef OCTAVE_CONF_LDFLAGS
+#define OCTAVE_CONF_LDFLAGS %OCTAVE_CONF_LDFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_LD_CXX
+#define OCTAVE_CONF_LD_CXX %OCTAVE_CONF_LD_CXX%
+#endif
+
+#ifndef OCTAVE_CONF_LD_STATIC_FLAG
+#define OCTAVE_CONF_LD_STATIC_FLAG %OCTAVE_CONF_LD_STATIC_FLAG%
+#endif
+
+#ifndef OCTAVE_CONF_LEXLIB
+#define OCTAVE_CONF_LEXLIB %OCTAVE_CONF_LEXLIB%
+#endif
+
+#ifndef OCTAVE_CONF_LEX
+#define OCTAVE_CONF_LEX %OCTAVE_CONF_LEX%
+#endif
+
+#ifndef OCTAVE_CONF_LFLAGS
+#define OCTAVE_CONF_LFLAGS %OCTAVE_CONF_LFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_LIBCRUFT
+#define OCTAVE_CONF_LIBCRUFT %OCTAVE_CONF_LIBCRUFT%
+#endif
+
+#ifndef OCTAVE_CONF_LIBEXT
+#define OCTAVE_CONF_LIBEXT %OCTAVE_CONF_LIBEXT%
+#endif
+
+#ifndef OCTAVE_CONF_LIBFLAGS
+#define OCTAVE_CONF_LIBFLAGS %OCTAVE_CONF_LIBFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_LIBOCTAVE
+#define OCTAVE_CONF_LIBOCTAVE %OCTAVE_CONF_LIBOCTAVE%
+#endif
+
+#ifndef OCTAVE_CONF_LIBOCTINTERP
+#define OCTAVE_CONF_LIBOCTINTERP %OCTAVE_CONF_LIBOCTINTERP%
+#endif
+
+#ifndef OCTAVE_CONF_LIBPLPLOT
+#define OCTAVE_CONF_LIBPLPLOT %OCTAVE_CONF_LIBPLPLOT%
+#endif
+
+#ifndef OCTAVE_CONF_LIBREADLINE
+#define OCTAVE_CONF_LIBREADLINE %OCTAVE_CONF_LIBREADLINE%
+#endif
+
+#ifndef OCTAVE_CONF_LIBS
+#define OCTAVE_CONF_LIBS %OCTAVE_CONF_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_LN_S
+#define OCTAVE_CONF_LN_S %OCTAVE_CONF_LN_S%
+#endif
+
+#ifndef OCTAVE_CONF_MAGICK_INCFLAGS
+#define OCTAVE_CONF_MAGICK_INCFLAGS %OCTAVE_CONF_MAGICK_INCFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_MAGICK_LIBS
+#define OCTAVE_CONF_MAGICK_LIBS %OCTAVE_CONF_MAGICK_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS
+#define OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_OCTINCLUDEDIR
+#define OCTAVE_CONF_OCTINCLUDEDIR %OCTAVE_CONF_OCTINCLUDEDIR%
+#endif
+
+#ifndef OCTAVE_CONF_OCTLIBDIR
+#define OCTAVE_CONF_OCTLIBDIR %OCTAVE_CONF_OCTLIBDIR%
+#endif
+
+#ifndef OCTAVE_CONF_PREFIX
+#define OCTAVE_CONF_PREFIX %OCTAVE_CONF_PREFIX%
+#endif
+
+#ifndef OCTAVE_CONF_RANLIB
+#define OCTAVE_CONF_RANLIB %OCTAVE_CONF_RANLIB%
+#endif
+
+#ifndef OCTAVE_CONF_RDYNAMIC_FLAG
+#define OCTAVE_CONF_RDYNAMIC_FLAG %OCTAVE_CONF_RDYNAMIC_FLAG%
+#endif
+
+#ifndef OCTAVE_CONF_RLD_FLAG
+#define OCTAVE_CONF_RLD_FLAG %OCTAVE_CONF_RLD_FLAG%
+#endif
+
+#ifndef OCTAVE_CONF_SED
+#define OCTAVE_CONF_SED %OCTAVE_CONF_SED%
+#endif
+
+#ifndef OCTAVE_CONF_SHARED_LIBS
+#define OCTAVE_CONF_SHARED_LIBS %OCTAVE_CONF_SHARED_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_SHLEXT
+#define OCTAVE_CONF_SHLEXT %OCTAVE_CONF_SHLEXT%
+#endif
+
+#ifndef OCTAVE_CONF_SHLEXT_VER
+#define OCTAVE_CONF_SHLEXT_VER %OCTAVE_CONF_SHLEXT_VER%
+#endif
+
+#ifndef OCTAVE_CONF_SH_LD
+#define OCTAVE_CONF_SH_LD %OCTAVE_CONF_SH_LD%
+#endif
+
+#ifndef OCTAVE_CONF_SH_LDFLAGS
+#define OCTAVE_CONF_SH_LDFLAGS %OCTAVE_CONF_SH_LDFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_SONAME_FLAGS
+#define OCTAVE_CONF_SONAME_FLAGS %OCTAVE_CONF_SONAME_FLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_STATIC_LIBS
+#define OCTAVE_CONF_STATIC_LIBS %OCTAVE_CONF_STATIC_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_UGLY_DEFS
+#define OCTAVE_CONF_UGLY_DEFS %OCTAVE_CONF_UGLY_DEFS%
+#endif
+
+#ifndef OCTAVE_CONF_USE_64_BIT_IDX_T
+#define OCTAVE_CONF_USE_64_BIT_IDX_T %OCTAVE_CONF_USE_64_BIT_IDX_T%
+#endif
+
+#ifndef OCTAVE_CONF_ENABLE_DYNAMIC_LINKING
+#define OCTAVE_CONF_ENABLE_DYNAMIC_LINKING %OCTAVE_CONF_ENABLE_DYNAMIC_LINKING%
+#endif
+
+#ifndef OCTAVE_CONF_X11_INCFLAGS
+#define OCTAVE_CONF_X11_INCFLAGS %OCTAVE_CONF_X11_INCFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_X11_LIBS
+#define OCTAVE_CONF_X11_LIBS %OCTAVE_CONF_X11_LIBS%
+#endif
+
+#ifndef OCTAVE_CONF_XTRA_CFLAGS
+#define OCTAVE_CONF_XTRA_CFLAGS %OCTAVE_CONF_XTRA_CFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_XTRA_CXXFLAGS
+#define OCTAVE_CONF_XTRA_CXXFLAGS %OCTAVE_CONF_XTRA_CXXFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_YACC
+#define OCTAVE_CONF_YACC %OCTAVE_CONF_YACC%
+#endif
+
+#ifndef OCTAVE_CONF_YFLAGS
+#define OCTAVE_CONF_YFLAGS %OCTAVE_CONF_YFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_config_opts
+#define OCTAVE_CONF_config_opts %OCTAVE_CONF_config_opts%
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/src/oct-errno.cc.in b/src/oct-errno.cc.in
new file mode 100644
index 0000000..f297a39
--- /dev/null
+++ b/src/oct-errno.cc.in
@@ -0,0 +1,345 @@
+// oct-errno.cc.in
+/*
+
+Copyright (C) 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+
+#include "oct-errno.h"
+#include "oct-map.h"
+#include "error.h"
+
+octave_errno *octave_errno::instance = 0;
+
+octave_errno::octave_errno (void)
+{
+  struct errno_struct
+  {
+    const char *name;
+    int value;
+  };
+
+  static errno_struct errno_codes[] =
+  {
+    // POSIX.
+
+#if defined (E2BIG)
+    { "E2BIG", E2BIG, },
+#endif
+#if defined (EACCES)
+    { "EACCES", EACCES, },
+#endif
+#if defined (EADDRINUSE)
+    { "EADDRINUSE", EADDRINUSE, },
+#endif
+#if defined (EADDRNOTAVAIL)
+    { "EADDRNOTAVAIL", EADDRNOTAVAIL, },
+#endif
+#if defined (EAFNOSUPPORT)
+    { "EAFNOSUPPORT", EAFNOSUPPORT, },
+#endif
+#if defined (EAGAIN)
+    { "EAGAIN", EAGAIN, },
+#endif
+#if defined (EALREADY)
+    { "EALREADY", EALREADY, },
+#endif
+#if defined (EBADF)
+    { "EBADF", EBADF, },
+#endif
+#if defined (EBUSY)
+    { "EBUSY", EBUSY, },
+#endif
+#if defined (ECHILD)
+    { "ECHILD", ECHILD, },
+#endif
+#if defined (ECONNABORTED)
+    { "ECONNABORTED", ECONNABORTED, },
+#endif
+#if defined (ECONNREFUSED)
+    { "ECONNREFUSED", ECONNREFUSED, },
+#endif
+#if defined (ECONNRESET)
+    { "ECONNRESET", ECONNRESET, },
+#endif
+#if defined (EDEADLK)
+    { "EDEADLK", EDEADLK, },
+#endif
+#if defined (EDESTADDRREQ)
+    { "EDESTADDRREQ", EDESTADDRREQ, },
+#endif
+#if defined (EDOM)
+    { "EDOM", EDOM, },
+#endif
+#if defined (EDQUOT)
+    { "EDQUOT", EDQUOT, },
+#endif
+#if defined (EEXIST)
+    { "EEXIST", EEXIST, },
+#endif
+#if defined (EFAULT)
+    { "EFAULT", EFAULT, },
+#endif
+#if defined (EFBIG)
+    { "EFBIG", EFBIG, },
+#endif
+#if defined (EHOSTDOWN)
+    { "EHOSTDOWN", EHOSTDOWN, },
+#endif
+#if defined (EHOSTUNREACH)
+    { "EHOSTUNREACH", EHOSTUNREACH, },
+#endif
+#if defined (EINPROGRESS)
+    { "EINPROGRESS", EINPROGRESS, },
+#endif
+#if defined (EINTR)
+    { "EINTR", EINTR, },
+#endif
+#if defined (EINVAL)
+    { "EINVAL", EINVAL, },
+#endif
+#if defined (EIO)
+    { "EIO", EIO, },
+#endif
+#if defined (EISCONN)
+    { "EISCONN", EISCONN, },
+#endif
+#if defined (EISDIR)
+    { "EISDIR", EISDIR, },
+#endif
+#if defined (ELOOP)
+    { "ELOOP", ELOOP, },
+#endif
+#if defined (EMFILE)
+    { "EMFILE", EMFILE, },
+#endif
+#if defined (EMLINK)
+    { "EMLINK", EMLINK, },
+#endif
+#if defined (EMSGSIZE)
+    { "EMSGSIZE", EMSGSIZE, },
+#endif
+#if defined (ENAMETOOLONG)
+    { "ENAMETOOLONG", ENAMETOOLONG, },
+#endif
+#if defined (ENETDOWN)
+    { "ENETDOWN", ENETDOWN, },
+#endif
+#if defined (ENETRESET)
+    { "ENETRESET", ENETRESET, },
+#endif
+#if defined (ENETUNREACH)
+    { "ENETUNREACH", ENETUNREACH, },
+#endif
+#if defined (ENFILE)
+    { "ENFILE", ENFILE, },
+#endif
+#if defined (ENOBUFS)
+    { "ENOBUFS", ENOBUFS, },
+#endif
+#if defined (ENODEV)
+    { "ENODEV", ENODEV, },
+#endif
+#if defined (ENOENT)
+    { "ENOENT", ENOENT, },
+#endif
+#if defined (ENOEXEC)
+    { "ENOEXEC", ENOEXEC, },
+#endif
+#if defined (ENOLCK)
+    { "ENOLCK", ENOLCK, },
+#endif
+#if defined (ENOMEM)
+    { "ENOMEM", ENOMEM, },
+#endif
+#if defined (ENOPROTOOPT)
+    { "ENOPROTOOPT", ENOPROTOOPT, },
+#endif
+#if defined (ENOSPC)
+    { "ENOSPC", ENOSPC, },
+#endif
+#if defined (ENOSYS)
+    { "ENOSYS", ENOSYS, },
+#endif
+#if defined (ENOTBLK)
+    { "ENOTBLK", ENOTBLK, },
+#endif
+#if defined (ENOTCONN)
+    { "ENOTCONN", ENOTCONN, },
+#endif
+#if defined (ENOTDIR)
+    { "ENOTDIR", ENOTDIR, },
+#endif
+#if defined (ENOTEMPTY)
+    { "ENOTEMPTY", ENOTEMPTY, },
+#endif
+#if defined (ENOTSOCK)
+    { "ENOTSOCK", ENOTSOCK, },
+#endif
+#if defined (ENOTTY)
+    { "ENOTTY", ENOTTY, },
+#endif
+#if defined (ENXIO)
+    { "ENXIO", ENXIO, },
+#endif
+#if defined (EOPNOTSUPP)
+    { "EOPNOTSUPP", EOPNOTSUPP, },
+#endif
+#if defined (EPERM)
+    { "EPERM", EPERM, },
+#endif
+#if defined (EPFNOSUPPORT)
+    { "EPFNOSUPPORT", EPFNOSUPPORT, },
+#endif
+#if defined (EPIPE)
+    { "EPIPE", EPIPE, },
+#endif
+#if defined (EPROTONOSUPPORT)
+    { "EPROTONOSUPPORT", EPROTONOSUPPORT, },
+#endif
+#if defined (EPROTOTYPE)
+    { "EPROTOTYPE", EPROTOTYPE, },
+#endif
+#if defined (ERANGE)
+    { "ERANGE", ERANGE, },
+#endif
+#if defined (EREMOTE)
+    { "EREMOTE", EREMOTE, },
+#endif
+#if defined (ERESTART)
+    { "ERESTART", ERESTART, },
+#endif
+#if defined (EROFS)
+    { "EROFS", EROFS, },
+#endif
+#if defined (ESHUTDOWN)
+    { "ESHUTDOWN", ESHUTDOWN, },
+#endif
+#if defined (ESOCKTNOSUPPORT)
+    { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, },
+#endif
+#if defined (ESPIPE)
+    { "ESPIPE", ESPIPE, },
+#endif
+#if defined (ESRCH)
+    { "ESRCH", ESRCH, },
+#endif
+#if defined (ESTALE)
+    { "ESTALE", ESTALE, },
+#endif
+#if defined (ETIMEDOUT)
+    { "ETIMEDOUT", ETIMEDOUT, },
+#endif
+#if defined (ETOOMANYREFS)
+    { "ETOOMANYREFS", ETOOMANYREFS, },
+#endif
+#if defined (ETXTBSY)
+    { "ETXTBSY", ETXTBSY, },
+#endif
+#if defined (EUSERS)
+    { "EUSERS", EUSERS, },
+#endif
+#if defined (EWOULDBLOCK)
+    { "EWOULDBLOCK", EWOULDBLOCK, },
+#endif
+#if defined (EXDEV)
+    { "EXDEV", EXDEV, },
+#endif
+
+    // Others (duplicates are OK).
+
+ at SYSDEP_ERRNO_LIST@
+
+    { 0, 0, },
+  };
+
+  // Stuff them all in a map for fast access.
+
+  errno_struct *ptr = errno_codes;
+
+  while (ptr->name)
+    {
+      errno_tbl[ptr->name] = ptr->value;
+      ptr++;
+    }
+}
+
+bool
+octave_errno::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_errno ();
+
+  if (! instance)
+    {
+      ::error ("unable to create errno object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+int
+octave_errno::lookup (const std::string& name)
+{
+  return (instance_ok ()) ? instance->do_lookup (name) : -1;
+}
+
+Octave_map
+octave_errno::list (void)
+{
+  return (instance_ok ()) ? instance->do_list () : Octave_map ();
+}
+
+int
+octave_errno::do_lookup (const std::string& name)
+{
+  return (errno_tbl.find (name) != errno_tbl.end ()) ? errno_tbl[name] : -1;
+}
+
+Octave_map
+octave_errno::do_list (void)
+{
+  Octave_map retval;
+
+  for (std::map<std::string, int>::const_iterator p = errno_tbl.begin ();
+       p != errno_tbl.end ();
+       p++)
+    {
+      retval.assign (p->first, p->second);
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/src/oct-errno.h b/src/oct-errno.h
new file mode 100644
index 0000000..a158eae
--- /dev/null
+++ b/src/oct-errno.h
@@ -0,0 +1,77 @@
+// oct-errno.h.in
+/*
+
+Copyright (C) 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_errno_h)
+#define octave_errno_h 1
+
+#include <cerrno>
+#include <map>
+#include <string>
+
+#include "oct-map.h"
+
+class
+octave_errno
+{
+protected:
+
+  octave_errno (void);
+
+public:
+
+  ~octave_errno (void) { }
+
+  static bool instance_ok (void);
+
+  static int lookup (const std::string& name);
+
+  static Octave_map list (void);
+
+  static int get (void) { return errno; }
+
+  static int set (int val)
+  {
+    int retval = errno;
+    errno = val;
+    return retval;
+  }
+
+private:
+
+  std::map<std::string, int> errno_tbl;
+
+  static octave_errno *instance;
+
+  int do_lookup (const std::string& name);
+
+  Octave_map do_list (void);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
diff --git a/src/oct-fstrm.cc b/src/oct-fstrm.cc
new file mode 100644
index 0000000..8457c6d
--- /dev/null
+++ b/src/oct-fstrm.cc
@@ -0,0 +1,125 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <cstring>
+
+#include "error.h"
+#include "oct-fstrm.h"
+
+octave_stream
+octave_fstream::create (const std::string& nm_arg, std::ios::openmode arg_md,
+			oct_mach_info::float_format ff)
+{
+  return octave_stream (new octave_fstream (nm_arg, arg_md, ff));
+}
+
+octave_fstream::octave_fstream (const std::string& nm_arg,
+				std::ios::openmode arg_md,
+				oct_mach_info::float_format ff)
+  : octave_base_stream (arg_md, ff), nm (nm_arg)
+{
+
+#if CXX_ISO_COMPLIANT_LIBRARY
+
+  fs.open (nm.c_str (), arg_md);
+
+#else
+  // Override default protection of 0664 so that umask will appear to
+  // do the right thing.
+
+  fs.open (nm.c_str (), arg_md, 0666);
+
+#endif
+
+  if (! fs)
+    {
+      using namespace std;
+
+      error (strerror (errno));
+    }
+}
+
+// Position a stream at OFFSET relative to ORIGIN.
+
+int
+octave_fstream::seek (long, int)
+{
+  error ("fseek: invalid_operation");
+  return -1;
+}
+
+// Return current stream position.
+
+long
+octave_fstream::tell (void)
+{
+  error ("ftell: invalid_operation");
+  return -1;
+}
+
+// Return non-zero if EOF has been reached on this stream.
+
+bool
+octave_fstream::eof (void) const
+{
+  return fs.eof ();
+}
+
+void
+octave_fstream::do_close (void)
+{
+  fs.close ();
+}
+
+std::istream *
+octave_fstream::input_stream (void)
+{
+  std::istream *retval = 0;
+
+  if (mode () & std::ios::in)
+    retval = &fs;
+
+  return retval;
+}
+
+std::ostream *
+octave_fstream::output_stream (void)
+{
+  std::ostream *retval = 0;
+
+  if (mode () & std::ios::out)
+    retval = &fs;
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-fstrm.h b/src/oct-fstrm.h
new file mode 100644
index 0000000..b2a18f8
--- /dev/null
+++ b/src/oct-fstrm.h
@@ -0,0 +1,93 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_fstream_h)
+#define octave_octave_fstream_h 1
+
+#include <fstream>
+#include <string>
+
+#include "oct-stream.h"
+
+class
+octave_fstream : public octave_base_stream
+{
+public:
+
+  octave_fstream (const std::string& nm_arg,
+		  std::ios::openmode arg_md = std::ios::in|std::ios::out,
+		  oct_mach_info::float_format flt_fmt
+		    = oct_mach_info::native_float_format ());
+
+  static octave_stream
+  create (const std::string& nm_arg,
+	  std::ios::openmode arg_md = std::ios::in|std::ios::out,
+	  oct_mach_info::float_format flt_fmt
+	    = oct_mach_info::native_float_format ());
+
+  // Position a stream at OFFSET relative to ORIGIN.
+
+  int seek (long offset, int origin);
+
+  // Return current stream position.
+
+  long tell (void);
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const;
+
+  void do_close (void);
+
+  // The name of the file.
+
+  std::string name (void) const { return nm; }
+
+  std::istream *input_stream (void);
+
+  std::ostream *output_stream (void);
+
+protected:
+
+  ~octave_fstream (void) { }
+
+private:
+
+  std::string nm;
+
+  std::fstream fs;
+
+  // No copying!
+
+  octave_fstream (const octave_fstream&);
+
+  octave_fstream& operator = (const octave_fstream&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-gperf.h b/src/oct-gperf.h
new file mode 100644
index 0000000..64a2160
--- /dev/null
+++ b/src/oct-gperf.h
@@ -0,0 +1,253 @@
+/* C++ code produced by gperf version 3.0.2 */
+/* Command-line: gperf -t -C -D -G -L C++ -Z octave_kw_hash octave.gperf  */
+/* Computed positions: -k'1,3' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf at gnu.org>."
+#endif
+
+#line 1 "octave.gperf"
+
+/*
+
+Copyright (C) 1995, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+NOTE: gperf 2.7.2 will silently generate bad code if there are blank
+lines following the "%{" marker above.  This comment block seems to be
+handled correctly.
+
+*/
+enum octave_kw_id
+{
+  break_kw,
+  case_kw,
+  catch_kw,
+  continue_kw,
+  do_kw,
+  else_kw,
+  elseif_kw,
+  end_kw,
+  end_try_catch_kw,
+  end_unwind_protect_kw,
+  endfor_kw,
+  endfunction_kw,
+  endif_kw,
+  endswitch_kw,
+  endwhile_kw,
+  for_kw,
+  function_kw,
+  global_kw,
+  if_kw,
+  magic_file_kw,
+  magic_line_kw,
+  otherwise_kw,
+  return_kw,
+  static_kw,
+  switch_kw,
+  try_kw,
+  until_kw,
+  unwind_protect_kw,
+  unwind_protect_cleanup_kw,
+  while_kw
+};
+#line 62 "octave.gperf"
+struct octave_kw { const char *name; int tok; octave_kw_id kw_id; };
+
+#define TOTAL_KEYWORDS 31
+#define MIN_WORD_LENGTH 2
+#define MAX_WORD_LENGTH 22
+#define MIN_HASH_VALUE 4
+#define MAX_HASH_VALUE 53
+/* maximum key range = 50, duplicates = 0 */
+
+class octave_kw_hash
+{
+private:
+  static inline unsigned int hash (const char *str, unsigned int len);
+public:
+  static const struct octave_kw *in_word_set (const char *str, unsigned int len);
+};
+
+inline unsigned int
+octave_kw_hash::hash (register const char *str, register unsigned int len)
+{
+  static const unsigned char asso_values[] =
+    {
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      25, 54, 54, 54, 54, 54, 20, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 20, 54, 30,  0, 20,
+       5,  0, 25, 25,  0, 15, 54, 54, 54, 54,
+       0,  0,  0, 54, 15,  0,  5,  5, 54,  0,
+      54, 30, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+      54, 54, 54, 54, 54, 54
+    };
+  register int hval = len;
+
+  switch (hval)
+    {
+      default:
+        hval += asso_values[(unsigned char)str[2]];
+      /*FALLTHROUGH*/
+      case 2:
+      case 1:
+        hval += asso_values[(unsigned char)str[0]];
+        break;
+    }
+  return hval;
+}
+
+static const struct octave_kw wordlist[] =
+  {
+#line 69 "octave.gperf"
+    {"else", ELSE, else_kw},
+#line 64 "octave.gperf"
+    {"break", BREAK, break_kw},
+#line 70 "octave.gperf"
+    {"elseif", ELSEIF, elseif_kw},
+#line 68 "octave.gperf"
+    {"do", DO, do_kw},
+#line 71 "octave.gperf"
+    {"end", END, end_kw},
+#line 83 "octave.gperf"
+    {"otherwise", OTHERWISE, otherwise_kw},
+#line 76 "octave.gperf"
+    {"endif", END, endif_kw},
+#line 74 "octave.gperf"
+    {"endfor", END, endfor_kw},
+#line 78 "octave.gperf"
+    {"endwhile", END, endwhile_kw},
+#line 77 "octave.gperf"
+    {"endswitch", END, endswitch_kw},
+#line 89 "octave.gperf"
+    {"until", UNTIL, until_kw},
+#line 75 "octave.gperf"
+    {"endfunction", END, endfunction_kw},
+#line 82 "octave.gperf"
+    {"if", IF, if_kw},
+#line 72 "octave.gperf"
+    {"end_try_catch", END, end_try_catch_kw},
+#line 90 "octave.gperf"
+    {"unwind_protect", UNWIND, unwind_protect_kw},
+#line 92 "octave.gperf"
+    {"while", WHILE, while_kw},
+#line 87 "octave.gperf"
+    {"switch", SWITCH, switch_kw},
+#line 73 "octave.gperf"
+    {"end_unwind_protect", END, end_unwind_protect_kw},
+#line 65 "octave.gperf"
+    {"case", CASE, case_kw},
+#line 84 "octave.gperf"
+    {"persistent", STATIC, static_kw},
+#line 85 "octave.gperf"
+    {"return", FUNC_RET, return_kw},
+#line 91 "octave.gperf"
+    {"unwind_protect_cleanup", CLEANUP, unwind_protect_cleanup_kw},
+#line 67 "octave.gperf"
+    {"continue", CONTINUE, continue_kw},
+#line 66 "octave.gperf"
+    {"catch", CATCH, catch_kw},
+#line 81 "octave.gperf"
+    {"global", GLOBAL, global_kw},
+#line 80 "octave.gperf"
+    {"function", FCN, function_kw},
+#line 86 "octave.gperf"
+    {"static", STATIC, static_kw},
+#line 88 "octave.gperf"
+    {"try", TRY, try_kw},
+#line 79 "octave.gperf"
+    {"for", FOR, for_kw},
+#line 94 "octave.gperf"
+    {"__LINE__", NUM, magic_line_kw},
+#line 93 "octave.gperf"
+    {"__FILE__", DQ_STRING, magic_file_kw}
+  };
+
+static const signed char gperf_lookup[] =
+  {
+    -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7, -1,  8,
+     9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19, 20, 21,
+    22, -1, 23, 24, -1, 25, -1, -1, 26, -1, 27, -1, -1, -1,
+    -1, 28, -1, -1, -1, -1, 29, -1, -1, -1, -1, 30
+  };
+
+const struct octave_kw *
+octave_kw_hash::in_word_set (register const char *str, register unsigned int len)
+{
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register int index = gperf_lookup[key];
+
+          if (index >= 0)
+            {
+              register const char *s = wordlist[index].name;
+
+              if (*str == *s && !strcmp (str + 1, s + 1))
+                return &wordlist[index];
+            }
+        }
+    }
+  return 0;
+}
diff --git a/src/oct-hdf5.h b/src/oct-hdf5.h
new file mode 100644
index 0000000..7e64553
--- /dev/null
+++ b/src/oct-hdf5.h
@@ -0,0 +1,42 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave__hdf5_h)
+#define octave_hdf5_h 1
+
+#if defined (HAVE_HDF5)
+
+#if !defined (H5_USE_16_API)
+#define H5_USE_16_API 1
+#endif
+
+#include <hdf5.h>
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-hist.cc b/src/oct-hist.cc
new file mode 100644
index 0000000..d2b7934
--- /dev/null
+++ b/src/oct-hist.cc
@@ -0,0 +1,748 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+The functions listed below were adapted from similar functions from
+GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free
+Software Foundation, Inc.
+
+  do_history         edit_history_readline
+  do_edit_history    edit_history_add_hist
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+#include <cstring>
+
+#include <string>
+
+#include <fstream>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-hist.h"
+#include "file-ops.h"
+#include "lo-mappers.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "str-vec.h"
+
+#include <defaults.h>
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "oct-hist.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "parse.h"
+#include "sighandlers.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// TRUE means input is coming from temporary history file.
+bool input_from_tmp_history_file = false;
+
+static std::string
+default_history_file (void)
+{
+  std::string file;
+
+  std::string env_file = octave_env::getenv ("OCTAVE_HISTFILE");
+
+  if (! env_file.empty ())
+    file = env_file;
+
+  if (file.empty ())
+    file = file_ops::concat (octave_env::get_home_directory (),
+			     ".octave_hist");
+
+  return file;
+}
+
+// Where history is saved.
+static std::string Vhistory_file = default_history_file ();
+
+static int
+default_history_size (void)
+{
+  int size = 1024;
+
+  std::string env_size = octave_env::getenv ("OCTAVE_HISTSIZE");
+
+  if (! env_size.empty ())
+    {
+      int val;
+
+      if (sscanf (env_size.c_str (), "%d", &val) == 1)
+	size = val > 0 ? val : 0;
+    }
+
+  return size;
+}
+
+// The number of lines to keep in the history file.
+static int Vhistory_size = default_history_size ();
+
+static std::string
+default_history_timestamp_format (void)
+{
+  return
+    std::string ("# Octave " OCTAVE_VERSION ", %a %b %d %H:%M:%S %Y %Z <")
+    + octave_env::get_user_name ()
+    + std::string ("@")
+    + octave_env::get_host_name ()
+    + std::string (">");
+}
+
+// The format of the timestamp marker written to the history file when
+// Octave exits.
+static std::string Vhistory_timestamp_format_string
+  = default_history_timestamp_format ();
+
+// TRUE if we are saving history.
+bool Vsaving_history = true;
+
+// Display, save, or load history.  Stolen and modified from bash.
+//
+// Arg of -w FILENAME means write file, arg of -r FILENAME
+// means read file, arg of -q means don't number lines.  Arg of N
+// means only display that many items. 
+
+static void
+do_history (int argc, const string_vector& argv)
+{
+  int numbered_output = 1;
+
+  int i;
+  for (i = 1; i < argc; i++)
+    {
+      std::string option = argv[i];
+
+      if (option == "-r" || option == "-w" || option == "-a"
+	  || option == "-n")
+	{
+	  if (i < argc - 1)
+	    command_history::set_file (argv[i+1]);
+
+	  if (option == "-a")
+	    // Append `new' lines to file.
+	    command_history::append ();
+
+	  else if (option == "-w")
+	    // Write entire history.
+	    command_history::write ();
+
+	  else if (option == "-r")
+	    // Read entire file.
+	    command_history::read ();
+
+	  else if (option == "-n")
+	    // Read `new' history from file.
+	    command_history::read_range ();
+
+	  else
+	    panic_impossible ();
+
+	  return;
+	}
+      else if (argv[i] == "-q")
+	numbered_output = 0;
+      else if (argv[i] == "--")
+	{
+	  i++;
+	  break;
+	}
+      else
+	break;
+    }
+
+  int limit = -1;
+
+  if (i < argc)
+    {
+      if (sscanf (argv[i].c_str (), "%d", &limit) != 1)
+        {
+	  if (argv[i][0] == '-')
+	    error ("history: unrecognized option `%s'", argv[i].c_str ());
+	  else
+	    error ("history: bad non-numeric arg `%s'", argv[i].c_str ());
+
+	  return;
+        }
+
+      if (limit < 0)
+	limit = -limit;
+    }
+
+  string_vector hlist = command_history::list (limit, numbered_output);
+
+  int len = hlist.length ();
+
+  for (i = 0; i < len; i++)
+    octave_stdout << hlist[i] << "\n";
+}
+
+// Read the edited history lines from STREAM and return them
+// one at a time.  This can read unlimited length lines.  The
+// caller should free the storage.
+
+static char *
+edit_history_readline (std::fstream& stream)
+{
+  char c;
+  int line_len = 128;
+  int lindex = 0;
+  char *line = new char [line_len];
+  line[0] = '\0';
+
+  while (stream.get (c))
+    {
+      if (lindex + 2 >= line_len)
+	{
+	  char *tmp_line = new char [line_len += 128];
+	  strcpy (tmp_line, line);
+	  delete [] line;
+	  line = tmp_line;
+	}
+
+      if (c == '\n')
+	{
+	  line[lindex++] = '\n';
+	  line[lindex++] = '\0';
+	  return line;
+	}
+      else
+	line[lindex++] = c;
+    }
+
+  if (! lindex)
+    {
+      delete [] line;
+      return 0;
+    }
+
+  if (lindex + 2 >= line_len)
+    {
+      char *tmp_line = new char [lindex+3];
+      strcpy (tmp_line, line);
+      delete [] line;
+      line = tmp_line;
+    }
+
+  // Finish with newline if none in file.
+
+  line[lindex++] = '\n';
+  line[lindex++] = '\0';
+  return line;
+}
+
+// Use `command' to replace the last entry in the history list, which,
+// by this time, is `run_history blah...'.  The intent is that the
+// new command becomes the history entry, and that `fc' should never
+// appear in the history list.  This way you can do `run_history' to
+// your heart's content.
+
+static void
+edit_history_repl_hist (const std::string& command)
+{
+  if (! command.empty ())
+    {
+      string_vector hlist = command_history::list ();
+
+      int len = hlist.length ();
+
+      if (len > 0)
+	{
+	  int i = len - 1;
+
+	  std::string histent = command_history::get_entry (i);
+
+	  if (! histent.empty ())
+	    {
+	      std::string cmd = command;
+
+	      int cmd_len = cmd.length ();
+
+	      if (cmd[cmd_len - 1] == '\n')
+		cmd.resize (cmd_len - 1);
+
+	      if (! cmd.empty ())
+		command_history::replace_entry (i, cmd);
+	    }
+	}
+    }
+}
+
+static void
+edit_history_add_hist (const std::string& line)
+{
+  if (! line.empty ())
+    {
+      std::string tmp = line;
+
+      int len = tmp.length ();
+	
+      if (len > 0 && tmp[len-1] == '\n')
+	tmp.resize (len - 1);
+
+      if (! tmp.empty ())
+	command_history::add (tmp);
+    }
+}
+
+static std::string
+mk_tmp_hist_file (int argc, const string_vector& argv,
+		  int insert_curr, const char *warn_for) 
+{
+  std::string retval;
+
+  string_vector hlist = command_history::list ();
+
+  int hist_count = hlist.length ();
+
+  // The current command line is already part of the history list by
+  // the time we get to this point.  Delete it from the list.
+
+  hist_count -= 2;
+
+  if (! insert_curr)
+    command_history::remove (hist_count);
+
+  hist_count--;
+
+  // If no numbers have been specified, the default is to edit the
+  // last command in the history list.
+
+  int hist_end = hist_count;
+  int hist_beg = hist_count;
+  int reverse = 0;
+
+  // Process options.
+
+  int usage_error = 0;
+  if (argc == 3)
+    {
+      if (sscanf (argv[1].c_str (), "%d", &hist_beg) != 1
+	  || sscanf (argv[2].c_str (), "%d", &hist_end) != 1)
+	usage_error = 1;
+      else
+	{
+	  hist_beg--;
+	  hist_end--;
+	}
+    }
+  else if (argc == 2)
+    {
+      if (sscanf (argv[1].c_str (), "%d", &hist_beg) != 1)
+	usage_error = 1;
+      else
+	{
+	  hist_beg--;
+	  hist_end = hist_beg;
+	}
+    }
+
+  if (hist_beg < 0 || hist_end < 0 || hist_beg > hist_count
+      || hist_end > hist_count)
+    {
+      error ("%s: history specification out of range", warn_for);
+      return retval;
+    }
+
+  if (usage_error)
+    {
+      usage ("%s [first] [last]", warn_for);
+      return retval;
+    }
+
+  if (hist_end < hist_beg)
+    {
+      int t = hist_end;
+      hist_end = hist_beg;
+      hist_beg = t;
+      reverse = 1;
+    }
+
+  std::string name = file_ops::tempnam ("", "oct-");
+
+  std::fstream file (name.c_str (), std::ios::out);
+
+  if (! file)
+    {
+      error ("%s: couldn't open temporary file `%s'", warn_for,
+	     name.c_str ());
+      return retval;
+    }
+
+  if (reverse)
+    {
+      for (int i = hist_end; i >= hist_beg; i--)
+	file << hlist[i] << "\n";
+    }
+  else
+    {
+      for (int i = hist_beg; i <= hist_end; i++)
+	file << hlist[i] << "\n";
+    }
+
+  file.close ();
+
+  return name;
+}
+
+static void
+do_edit_history (int argc, const string_vector& argv)
+{
+  std::string name = mk_tmp_hist_file (argc, argv, 0, "edit_history");
+
+  if (name.empty ())
+    return;
+
+  // Call up our favorite editor on the file of commands.
+
+  std::string cmd = VEDITOR;
+  cmd.append (" \"");
+  cmd.append (name);
+  cmd.append ("\"");
+
+  // Ignore interrupts while we are off editing commands.  Should we
+  // maybe avoid using system()?
+
+  volatile octave_interrupt_handler old_interrupt_handler
+    = octave_ignore_interrupts ();
+
+  system (cmd.c_str ());
+
+  octave_set_interrupt_handler (old_interrupt_handler);
+
+  // Write the commands to the history file since source_file
+  // disables command line history while it executes.
+
+  std::fstream file (name.c_str (), std::ios::in);
+
+  char *line;
+  int first = 1;
+  while ((line = edit_history_readline (file)) != 0)
+    {
+      // Skip blank lines.
+
+      if (line[0] == '\n')
+	{
+	  delete [] line;
+	  continue;
+	}
+
+      if (first)
+	{
+	  first = 0;
+	  edit_history_repl_hist (line);
+	}
+      else
+	edit_history_add_hist (line);
+    }
+
+  file.close ();
+
+  // Turn on command echo, so the output from this will make better
+  // sense.
+
+  unwind_protect::begin_frame ("do_edit_history");
+
+  unwind_protect_int (Vecho_executing_commands);
+  unwind_protect_bool (input_from_tmp_history_file);
+
+  Vecho_executing_commands = ECHO_CMD_LINE;
+  input_from_tmp_history_file = true;
+
+  source_file (name);
+
+  unwind_protect::run_frame ("do_edit_history");
+
+  // Delete the temporary file.  Should probably be done with an
+  // unwind_protect.
+
+  unlink (name.c_str ());
+}
+
+static void
+do_run_history (int argc, const string_vector& argv)
+{
+  std::string name = mk_tmp_hist_file (argc, argv, 1, "run_history");
+
+  if (name.empty ())
+    return;
+
+  // Turn on command echo so the output from this will make better
+  // sense.
+
+  unwind_protect::begin_frame ("do_run_history");
+
+  unwind_protect_int (Vecho_executing_commands);
+  unwind_protect_bool (input_from_tmp_history_file);
+
+  Vecho_executing_commands = ECHO_CMD_LINE;
+  input_from_tmp_history_file = true;
+
+  source_file (name);
+
+  unwind_protect::run_frame ("do_run_history");
+
+  // Delete the temporary file.
+
+  // FIXME -- should probably be done using an unwind_protect.
+
+  unlink (name.c_str ());
+}
+
+void
+initialize_history (bool read_history_file)
+{
+  command_history::set_file (Vhistory_file);
+  command_history::set_size (Vhistory_size);
+
+  if (read_history_file)
+    command_history::read (false);
+}
+
+void
+octave_history_write_timestamp (void)
+{
+  octave_localtime now;
+
+  std::string timestamp = now.strftime (Vhistory_timestamp_format_string);
+
+  if (! timestamp.empty ())
+    command_history::add (timestamp);
+}
+
+DEFUN (edit_history, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} edit_history [@var{first}] [@var{last}]\n\
+If invoked with no arguments, @code{edit_history} allows you to edit the\n\
+history list using the editor named by the variable @w{@code{EDITOR}}.  The\n\
+commands to be edited are first copied to a temporary file.  When you\n\
+exit the editor, Octave executes the commands that remain in the file.\n\
+It is often more convenient to use @code{edit_history} to define functions \n\
+rather than attempting to enter them directly on the command line.\n\
+By default, the block of commands is executed as soon as you exit the\n\
+editor.  To avoid executing any commands, simply delete all the lines\n\
+from the buffer before exiting the editor.\n\
+\n\
+The @code{edit_history} command takes two optional arguments specifying\n\
+the history numbers of first and last commands to edit.  For example,\n\
+the command\n\
+\n\
+ at example\n\
+edit_history 13\n\
+ at end example\n\
+\n\
+ at noindent\n\
+extracts all the commands from the 13th through the last in the history\n\
+list.  The command\n\
+\n\
+ at example\n\
+edit_history 13 169\n\
+ at end example\n\
+\n\
+ at noindent\n\
+only extracts commands 13 through 169.  Specifying a larger number for\n\
+the first command than the last command reverses the list of commands\n\
+before placing them in the buffer to be edited.  If both arguments are\n\
+omitted, the previous command in the history list is used.\n\
+ at seealso{run_history}\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("edit_history");
+
+  if (error_state)
+    return retval;
+
+  do_edit_history (argc, argv);
+
+  return retval;
+}
+
+DEFUN (history, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} history options\n\
+If invoked with no arguments, @code{history} displays a list of commands\n\
+that you have executed.  Valid options are:\n\
+\n\
+ at table @code\n\
+ at item -w @var{file}\n\
+Write the current history to the file @var{file}.  If the name is\n\
+omitted, use the default history file (normally @file{~/.octave_hist}).\n\
+\n\
+ at item -r @var{file}\n\
+Read the file @var{file}, replacing the current history list with its\n\
+contents.  If the name is omitted, use the default history file\n\
+(normally @file{~/.octave_hist}).\n\
+\n\
+ at item @var{n}\n\
+Display only the most recent @var{n} lines of history.\n\
+\n\
+ at item -q\n\
+Don't number the displayed lines of history.  This is useful for cutting\n\
+and pasting commands using the X Window System.\n\
+ at end table\n\
+\n\
+For example, to display the five most recent commands that you have\n\
+typed without displaying line numbers, use the command\n\
+ at kbd{history -q 5}.\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("history");
+
+  if (error_state)
+    return retval;
+
+  do_history (argc, argv);
+
+  return retval;
+}
+
+DEFUN (run_history, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} run_history [@var{first}] [@var{last}]\n\
+Similar to @code{edit_history}, except that the editor is not invoked,\n\
+and the commands are simply executed as they appear in the history list.\n\
+ at seealso{edit_history}\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("run_history");
+
+  if (error_state)
+    return retval;
+
+  do_run_history (argc, argv);
+
+  return retval;
+}
+
+DEFUN (history_size, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} history_size ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_size (@var{new_val})\n\
+Query or set the internal variable that specifies how many entries\n\
+to store in the history file.  The default value is @code{1024},\n\
+but may be overridden by the environment variable @w{@code{OCTAVE_HISTSIZE}}.\n\
+ at seealso{history_file, history_timestamp_format_string, saving_history}\n\
+ at end deftypefn")
+{
+  int saved_history_size = Vhistory_size;
+
+  octave_value retval
+    = SET_INTERNAL_VARIABLE_WITH_LIMITS (history_size, -1, INT_MAX);
+
+  if (Vhistory_size != saved_history_size)
+    command_history::set_size (Vhistory_size);
+
+  return retval;
+}
+
+DEFUN (history_file, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} history_file ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_file (@var{new_val})\n\
+Query or set the internal variable that specifies the name of the\n\
+file used to store command history.  The default value is\n\
+ at file{~/.octave_hist}, but may be overridden by the environment\n\
+variable @w{@code{OCTAVE_HISTFILE}}.\n\
+ at seealso{history_size, saving_history, history_timestamp_format_string}\n\
+ at end deftypefn")
+{
+  std::string saved_history_file = Vhistory_file;
+
+  octave_value retval = SET_INTERNAL_VARIABLE (history_file);
+
+  if (Vhistory_file != saved_history_file)
+    command_history::set_file (Vhistory_file);
+
+  return retval;
+}
+
+DEFUN (history_timestamp_format_string, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} history_timestamp_format_string ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} history_timestamp_format_string (@var{new_val})\n\
+Query or set the internal variable that specifies the format string\n\
+for the comment line that is written to the history file when Octave\n\
+exits.  The format string is passed to @code{strftime}.  The default\n\
+value is\n\
+\n\
+ at example\n\
+\"# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>\"\n\
+ at end example\n\
+ at seealso{strftime, history_file, history_size, saving_history}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (history_timestamp_format_string);
+}
+
+DEFUN (saving_history, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} saving_history ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} saving_history (@var{new_val})\n\
+Query or set the internal variable that controls whether commands entered\n\
+on the command line are saved in the history file.\n\
+ at seealso{history_file, history_size, history_timestamp_format_string}\n\
+ at end deftypefn")
+{
+  octave_value retval = SET_INTERNAL_VARIABLE (saving_history);
+
+  command_history::ignore_entries (! Vsaving_history);
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-hist.h b/src/oct-hist.h
new file mode 100644
index 0000000..a15ea41
--- /dev/null
+++ b/src/oct-hist.h
@@ -0,0 +1,48 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_hist_h)
+#define octave_octave_hist_h 1
+
+#include <string>
+
+#include "cmd-hist.h"
+
+extern void initialize_history (bool read_history_file = false);
+
+// Write timestamp to history file.
+extern void octave_history_write_timestamp (void);
+
+// TRUE means input is coming from temporary history file.
+extern bool input_from_tmp_history_file;
+
+// TRUE if we are saving history.
+extern bool Vsaving_history;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-iostrm.cc b/src/oct-iostrm.cc
new file mode 100644
index 0000000..35d09c8
--- /dev/null
+++ b/src/oct-iostrm.cc
@@ -0,0 +1,96 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-iostrm.h"
+
+// Position a stream at OFFSET relative to ORIGIN.
+
+int
+octave_base_iostream::seek (long, int)
+{
+  invalid_operation ();
+  return -1;
+}
+
+// Return current stream position.
+
+long
+octave_base_iostream::tell (void)
+{
+  invalid_operation ();
+  return -1;
+}
+
+// Return non-zero if EOF has been reached on this stream.
+
+bool
+octave_base_iostream::eof (void) const
+{
+  invalid_operation ();
+  return false;
+}
+
+void
+octave_base_iostream::invalid_operation (void) const
+{
+  ::error ("%s: invalid operation", stream_type ());
+}
+
+// Return non-zero if EOF has been reached on this stream.
+
+bool
+octave_istream::eof (void) const
+{
+  return is && is->eof ();
+}
+
+octave_stream
+octave_istream::create (std::istream *arg, const std::string& n)
+{
+  return octave_stream (new octave_istream (arg, n));
+}
+
+// Return non-zero if EOF has been reached on this stream.
+
+bool
+octave_ostream::eof (void) const
+{
+  return os && os->eof ();
+}
+
+octave_stream
+octave_ostream::create (std::ostream *arg, const std::string& n)
+{
+  return octave_stream (new octave_ostream (arg, n));
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-iostrm.h b/src/oct-iostrm.h
new file mode 100644
index 0000000..c62dd92
--- /dev/null
+++ b/src/oct-iostrm.h
@@ -0,0 +1,161 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2007,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_iostream_h)
+#define octave_octave_iostream_h 1
+
+#include <iosfwd>
+
+#include "oct-stream.h"
+
+class
+octave_base_iostream : public octave_base_stream
+{
+public:
+
+  octave_base_iostream (const std::string& n = std::string (),
+			std::ios::openmode m = std::ios::in|std::ios::out,
+			oct_mach_info::float_format ff
+			  = oct_mach_info::native_float_format ())
+    : octave_base_stream (m, ff), nm (n) { }
+
+  // Position a stream at OFFSET relative to ORIGIN.
+
+  int seek (long offset, int origin);
+
+  // Return current stream position.
+
+  long tell (void);
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const;
+
+  // The name of the file.
+
+  std::string name (void) const { return nm; }
+
+protected:
+
+  ~octave_base_iostream (void) { }
+
+  void invalid_operation (void) const;
+
+private:
+
+  std::string nm;
+
+  virtual const char *stream_type (void) const = 0;
+
+  // No copying!
+
+  octave_base_iostream (const octave_base_iostream&);
+
+  octave_base_iostream& operator = (const octave_base_iostream&);
+};
+
+class
+octave_istream : public octave_base_iostream
+{
+public:
+
+  octave_istream (std::istream *arg = 0, const std::string& n = std::string ())
+    : octave_base_iostream (n, std::ios::in,
+			    oct_mach_info::native_float_format ()),
+      is (arg)
+  { }
+
+  static octave_stream
+  create (std::istream *arg = 0, const std::string& n = std::string ());
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const;
+
+  std::istream *input_stream (void) { return is; }
+
+  std::ostream *output_stream (void) { return 0; }
+
+protected:
+
+  ~octave_istream (void) { }
+
+private:
+
+  std::istream *is;
+
+  const char *stream_type (void) const { return "octave_istream"; }
+
+  // No copying!
+
+  octave_istream (const octave_istream&);
+
+  octave_istream& operator = (const octave_istream&);
+};
+
+class
+octave_ostream : public octave_base_iostream
+{
+public:
+
+  octave_ostream (std::ostream *arg, const std::string& n = std::string ())
+    : octave_base_iostream (n, std::ios::out,
+			    oct_mach_info::native_float_format ()),
+      os (arg)
+  { }
+
+  static octave_stream
+  create (std::ostream *arg, const std::string& n = std::string ());
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const;
+
+  std::istream *input_stream (void) { return 0; }
+
+  std::ostream *output_stream (void) { return os; }
+
+protected:
+
+  ~octave_ostream (void) { }
+
+private:
+
+  std::ostream *os;
+
+  const char *stream_type (void) const { return "octave_ostream"; }
+
+  // No copying!
+
+  octave_ostream (const octave_ostream&);
+
+  octave_ostream& operator = (const octave_ostream&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-lvalue.cc b/src/oct-lvalue.cc
new file mode 100644
index 0000000..6294b17
--- /dev/null
+++ b/src/oct-lvalue.cc
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+
+void
+octave_lvalue::assign (octave_value::assign_op op, const octave_value& rhs)
+{
+  octave_value tmp (idx.empty ()
+		    ? val->assign (op, rhs)
+		    : val->assign (op, type, idx, rhs));
+
+  if (! error_state)
+    *val = tmp;
+}
+
+void
+octave_lvalue::set_index (const std::string& t,
+			  const std::list<octave_value_list>& i)
+{
+  if (! index_set)
+    {
+      type = t;
+      idx = i;
+      index_set = true;
+    }
+  else
+    error ("invalid index expression in assignment");
+}
+
+void
+octave_lvalue::do_unary_op (octave_value::unary_op op)
+{
+  octave_value tmp (idx.empty ()
+		    ? val->do_non_const_unary_op (op)
+		    : val->do_non_const_unary_op (op, type, idx));
+
+  if (! error_state)
+    *val = tmp;
+}
+
+octave_value
+octave_lvalue::value (void)
+{
+  octave_value retval;
+
+  if (idx.empty ())
+    retval = *val;
+  else
+    {
+      if (val->is_constant ())
+	retval = val->subsref (type, idx);
+      else
+	{
+	  octave_value_list t = val->subsref (type, idx, 1);
+	  if (t.length () > 0)
+	    retval = t(0);	      
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-lvalue.h b/src/oct-lvalue.h
new file mode 100644
index 0000000..24be943
--- /dev/null
+++ b/src/oct-lvalue.h
@@ -0,0 +1,111 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_lvalue_h)
+#define octave_lvalue_h 1
+
+class octave_value;
+class octave_value_list;
+
+#include <string>
+
+#include "oct-obj.h"
+#include "pt-idx.h"
+
+// FIXME -- eliminate the following kluge?
+
+// This variable is used when creating dummy octave_lvalue objects.
+static octave_value dummy_val;
+
+class
+octave_lvalue
+{
+public:
+
+  octave_lvalue (octave_value *v = &dummy_val)
+    : val (v), type (), idx (), nel (1), index_set (false) { }
+
+  octave_lvalue (const octave_lvalue& vr)
+    : val (vr.val), type (vr.type), idx (vr.idx), nel (vr.nel),
+      index_set (vr.index_set) { }
+
+  octave_lvalue& operator = (const octave_lvalue& vr)
+    {
+      if (this != &vr)
+	{
+	  val = vr.val;
+	  type = vr.type;
+	  idx = vr.idx;
+	  nel = vr.nel;
+	  index_set = vr.index_set;
+	}
+
+      return *this;
+    }
+
+  ~octave_lvalue (void) { }
+
+  bool is_defined (void) { return val->is_defined (); }
+
+  bool is_undefined (void) { return val->is_undefined (); }
+
+  bool is_map (void) { return val->is_map (); }
+
+  void define (const octave_value& v) { *val = v; }
+
+  void assign (octave_value::assign_op, const octave_value&);
+
+  void numel (octave_idx_type n) { nel = n; }
+
+  octave_idx_type numel (void) const { return nel; }
+
+  void set_index (const std::string& t, const std::list<octave_value_list>& i);
+
+  void clear_index (void) { type = std::string (); idx.clear (); }
+
+  void do_unary_op (octave_value::unary_op op);
+
+  octave_value value (void);
+
+  const octave_value *object (void) const { return val; }
+
+private:
+
+  octave_value *val;
+
+  std::string type;
+
+  std::list<octave_value_list> idx;
+
+  octave_idx_type nel;
+
+  bool index_set;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-map.cc b/src/oct-map.cc
new file mode 100644
index 0000000..4f73fcf
--- /dev/null
+++ b/src/oct-map.cc
@@ -0,0 +1,541 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "str-vec.h"
+
+#include "oct-map.h"
+#include "utils.h"
+
+Octave_map::Octave_map (const dim_vector& dv, const Cell& key_vals)
+  : map (), key_list (), dimensions (dv)
+{
+  Cell c (dv);
+
+  if (key_vals.is_cellstr ())
+    {
+      for (octave_idx_type i = 0; i < key_vals.numel (); i++)
+	{
+	  std::string k = key_vals(i).string_value ();
+	  map[k] = c;
+	  key_list.push_back (k);
+	}
+    }
+  else
+    error ("Octave_map: expecting keys to be cellstr");
+}
+
+Octave_map
+Octave_map::squeeze (void) const
+{
+  Octave_map retval (dims ().squeeze ());
+
+  for (const_iterator pa = begin (); pa != end (); pa++)
+    {
+      Cell tmp = contents (pa).squeeze ();
+
+      if (error_state)
+	break;
+
+      retval.assign (key (pa), tmp);
+    }
+
+  // Preserve order of keys.
+  retval.key_list = key_list;
+
+  return retval;
+}
+
+/*
+%!# test preservation of keys by squeeze
+%!test
+%!  x(1,1,1,1).d = 10; x(3,5,1,7).a = "b"; x(2,4,1,7).f = 27;
+%!  assert (fieldnames (squeeze (x)), {"d"; "a"; "f"});
+*/
+
+Octave_map
+Octave_map::permute (const Array<int>& vec, bool inv) const
+{
+  Octave_map retval (dims ());
+
+  for (const_iterator pa = begin (); pa != end (); pa++)
+    {
+      Cell tmp = contents (pa).permute (vec, inv);
+
+      if (error_state)
+	break;
+
+      retval.assign (key (pa), tmp);
+    }
+
+  // Preserve order of keys.
+  retval.key_list = key_list;
+
+  return retval;
+}
+
+/*
+%!# test preservation of key order by permute
+%!test
+%!  x(1,1,1,1).d = 10; x(3,5,1,7).a = "b"; x(2,4,1,7).f = 27;
+%!  assert (fieldnames (permute (x, [3, 4, 1, 2])), {"d"; "a"; "f"});
+*/
+
+Cell&
+Octave_map::contents (const std::string& k)
+{
+  maybe_add_to_key_list (k);
+
+  return map[k];
+}
+
+Cell
+Octave_map::contents (const std::string& k) const
+{
+  const_iterator p = seek (k);
+
+  return p != end () ? p->second : Cell ();
+}
+
+int
+Octave_map::intfield (const std::string& k, int def_val) const
+{
+  int retval = def_val;
+
+  Cell c = contents (k);
+
+  if (! c.is_empty ())
+    retval = c(0).int_value ();
+
+  return retval;
+}
+
+std::string
+Octave_map::stringfield (const std::string& k,
+			 const std::string& def_val) const
+{
+  std::string retval = def_val;
+
+  Cell c = contents (k);
+
+  if (! c.is_empty ())
+    retval = c(0).string_value ();
+
+  return retval;
+}
+
+string_vector
+Octave_map::keys (void) const
+{
+  assert (nfields () == key_list.size ());
+
+  return string_vector (key_list);
+}
+
+Octave_map
+Octave_map::transpose (void) const
+{
+  assert (ndims () == 2);
+
+  dim_vector dv = dims ();
+
+  octave_idx_type nr = dv(0);
+  octave_idx_type nc = dv(1);
+
+  dim_vector new_dims (nc, nr);
+
+  Octave_map retval (new_dims);
+
+  for (const_iterator p = begin (); p != end (); p++)
+    retval.assign (key(p), Cell (contents(p).transpose ()));
+
+  // Preserve order of keys.
+  retval.key_list = key_list;
+
+  return retval;
+}
+
+/*
+%!# test preservation of key order by transpose
+%!test
+%!  x(1,1).d = 10; x(3,5).a = "b"; x(2,4).f = 27;
+%!  assert (fieldnames (transpose (x)), {"d"; "a"; "f"});
+%!  assert (fieldnames (x'), {"d"; "a"; "f"});
+%!  assert (fieldnames (x.'), {"d"; "a"; "f"});
+*/
+
+Octave_map
+Octave_map::reshape (const dim_vector& new_dims) const
+{
+  Octave_map retval;
+
+  if (new_dims != dims ())
+    {
+      for (const_iterator p = begin (); p != end (); p++)
+	retval.assign (key(p), contents(p).reshape (new_dims));
+
+      retval.dimensions = new_dims;
+
+      // Preserve order of keys.
+      retval.key_list = key_list;
+    }
+  else
+    retval = *this;
+
+  return retval;
+}
+
+/*
+%!# test preservation of key order by reshape
+%!test
+%!  x(1,1).d = 10; x(4,6).a = "b"; x(2,4).f = 27;
+%!  assert (fieldnames (reshape (x, 3, 8)), {"d"; "a"; "f"});
+*/
+
+void
+Octave_map::resize (const dim_vector& dv, bool fill)
+{
+  if (dv != dims ())
+    {
+      if (nfields () == 0)
+	dimensions = dv;
+      else
+	{
+	  for (const_iterator p = begin (); p != end (); p++)
+	    {
+	      Cell tmp = contents(p);
+
+	      if (fill)
+		tmp.resize (dv, Cell::resize_fill_value ());
+	      else
+		tmp.resize (dv);
+
+	      dimensions = dv;
+
+	      assign (key(p), tmp);
+	    }
+	}
+    }
+}
+
+Octave_map
+Octave_map::concat (const Octave_map& rb, const Array<octave_idx_type>& ra_idx)
+{
+  Octave_map retval;
+
+  if (nfields () == rb.nfields ())
+    {
+      for (const_iterator pa = begin (); pa != end (); pa++)
+	{
+	  const_iterator pb = rb.seek (key(pa));
+
+	  if (pb == rb.end ())
+	    {
+	      error ("field name mismatch in structure concatenation");
+	      break;
+	    }
+	
+	  retval.assign (key(pa),
+			 contents(pa).insert (rb.contents(pb), ra_idx));
+	}
+
+      // Preserve order of keys.
+      retval.key_list = key_list;
+    }
+  else
+    {
+      dim_vector dv = dims ();
+
+      if (dv.all_zero ())
+	retval = rb;
+      else
+	{
+	  dv = rb.dims ();
+
+	  if (dv.all_zero ())
+	    retval = *this;
+	  else
+	    error ("invalid structure concatenation");
+	}
+    }
+
+  return retval;
+}
+
+/*
+%!# test preservation of key order by concatenation
+%!test
+%!  x(1, 1).d = 10; x(4, 6).a = "b"; x(2, 4).f = 27;
+%!  y(1, 6).f = 11; y(1, 6).a = "c"; y(1, 6).d = 33;
+%!  assert (fieldnames ([x; y]), {"d"; "a"; "f"});
+*/
+
+static bool
+keys_ok (const Octave_map& a, const Octave_map& b, string_vector& keys)
+{
+  bool retval = false;
+
+  keys = string_vector ();
+
+  if (a.nfields () == 0)
+    {
+      keys = b.keys ();
+      retval = true;
+    }
+  else
+    {
+      string_vector a_keys = a.keys().sort ();
+      string_vector b_keys = b.keys().sort ();
+
+      octave_idx_type a_len = a_keys.length ();
+      octave_idx_type b_len = b_keys.length ();
+
+      if (a_len == b_len)
+	{
+	  for (octave_idx_type i = 0; i < a_len; i++)
+	    {
+	      if (a_keys[i] != b_keys[i])
+		goto done;
+	    }
+
+	  keys = a_keys;
+	  retval = true;
+	}
+    }
+
+ done:
+  return retval;
+}
+
+Octave_map&
+Octave_map::maybe_delete_elements (const octave_value_list& idx)
+{
+  string_vector t_keys = keys();
+  octave_idx_type len = t_keys.length ();
+
+  if (len > 0)
+    {
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  std::string k = t_keys[i];
+
+	  map[k] = contents(k).delete_elements (idx);
+
+	  if (error_state)
+	    break;
+	}
+
+      if (!error_state)
+	dimensions = contents(t_keys[0]).dims();
+    }
+
+  return *this;
+}
+
+Octave_map&
+Octave_map::assign (const octave_value_list& idx, const Octave_map& rhs)
+{
+  string_vector t_keys;
+
+  if (keys_ok (*this, rhs, t_keys))
+    {
+      octave_idx_type len = t_keys.length ();
+
+      if (len == 0)
+	{
+	  Cell tmp_lhs (dims ());
+	  Cell tmp_rhs (rhs.dims ());
+
+	  tmp_lhs.assign (idx, tmp_rhs, Matrix ());
+
+	  if (! error_state)
+	    resize (tmp_lhs.dims ());
+	  else
+	    error ("size mismatch in structure assignment");
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < len; i++)
+	    {
+	      std::string k = t_keys[i];
+
+	      Cell t_rhs = rhs.contents (k);
+
+	      assign (idx, k, t_rhs);
+
+	      if (error_state)
+		break;
+	    }
+	}
+    }
+  else
+    error ("field name mismatch in structure assignment");
+
+  return *this;
+}
+
+Octave_map&
+Octave_map::assign (const octave_value_list& idx, const std::string& k,
+		    const Cell& rhs)
+{
+  Cell tmp;
+
+  if (contains (k))
+    tmp = map[k];
+  else
+    tmp = Cell (dimensions);
+
+  tmp.assign (idx, rhs);
+
+  if (! error_state)
+    {
+      dim_vector tmp_dims = tmp.dims ();
+
+      if (tmp_dims != dimensions)
+	{
+	  for (iterator p = begin (); p != end (); p++)
+	    contents(p).resize (tmp_dims, Cell::resize_fill_value ());
+
+          dimensions = tmp_dims;
+	}
+
+      maybe_add_to_key_list (k);
+
+      map[k] = tmp;
+    }
+
+  return *this;
+}
+
+Octave_map&
+Octave_map::assign (const std::string& k, const octave_value& rhs)
+{
+  if (nfields () == 0)
+    {
+      maybe_add_to_key_list (k);
+
+      map[k] = Cell (rhs);
+
+      dimensions = dim_vector (1, 1);
+    }
+  else
+    {
+      dim_vector dv = dims ();
+
+      if (dv.all_ones ())
+	{
+	  maybe_add_to_key_list (k);
+
+	  map[k] = Cell (rhs);
+	}
+      else
+	error ("invalid structure assignment");
+    }
+
+  return *this;
+}
+
+Octave_map&
+Octave_map::assign (const std::string& k, const Cell& rhs)
+{
+  if (nfields () == 0)
+    {
+      maybe_add_to_key_list (k);
+
+      map[k] = rhs;
+
+      dimensions = rhs.dims ();
+    }
+  else
+    {
+      if (dims () == rhs.dims ())
+	{
+	  maybe_add_to_key_list (k);
+
+	  map[k] = rhs;
+	}
+      else
+	error ("invalid structure assignment");
+    }
+
+  return *this;
+}
+
+Octave_map
+Octave_map::index (const octave_value_list& idx, bool resize_ok) const
+{
+  Octave_map retval;
+
+  octave_idx_type n_idx = idx.length ();
+
+  if (n_idx > 0)
+    {
+      Array<idx_vector> ra_idx (n_idx);
+
+      for (octave_idx_type i = 0; i < n_idx; i++)
+        {
+          ra_idx(i) = idx(i).index_vector ();
+          if (error_state)
+            break;
+        }
+
+      if (! error_state)
+        {
+          for (const_iterator p = begin (); p != end (); p++)
+            {
+              Cell tmp = contents (p);
+
+              tmp = tmp.ArrayN<octave_value>::index (ra_idx, resize_ok);
+
+              if (error_state)
+                break;
+
+              retval.assign (key(p), tmp);
+            }
+
+          // Preserve order of keys.
+          retval.key_list = key_list;
+        }
+    }
+  else
+    retval = *this;
+
+  return retval;
+}
+
+/*
+%!# test preservation of key order by indexing
+%!test
+%!  x(1, 1).d = 10; x(4, 6).a = "b"; x(2, 4).f = 27;
+%!  assert (fieldnames (x([1, 2], [2:5])), {"d"; "a"; "f"});
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-map.h b/src/oct-map.h
new file mode 100644
index 0000000..8ca6714
--- /dev/null
+++ b/src/oct-map.h
@@ -0,0 +1,218 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_map_h)
+#define octave_oct_map_h 1
+
+#include <algorithm>
+#include <map>
+
+#include "Cell.h"
+#include "oct-obj.h"
+
+class string_vector;
+
+class
+OCTINTERP_API
+Octave_map
+{
+ public:
+
+  typedef std::map<std::string, Cell>::iterator iterator;
+  typedef std::map<std::string, Cell>::const_iterator const_iterator;
+
+  typedef std::list<std::string>::iterator key_list_iterator;
+  typedef std::list<std::string>::const_iterator const_key_list_iterator;
+
+  // Warning!  You should always use at least two dimensions.
+
+  Octave_map (const dim_vector& dv = dim_vector (0, 0),
+	      const Cell& key_vals = Cell ());
+
+  Octave_map (const std::string& k, const octave_value& value)
+    : map (), key_list (), dimensions (1, 1)
+  {
+    map[k] = value;
+    key_list.push_back (k);
+  }
+
+  Octave_map (const string_vector& sv)
+    : map (), key_list (), dimensions (0, 0)
+  {
+    for (octave_idx_type i = 0; i < sv.length (); i++)
+      {
+	std::string k = sv[i];
+	map[k] = Cell ();
+	key_list.push_back (k);
+      }
+  }
+
+  Octave_map (const std::string& k, const Cell& vals)
+    : map (), key_list (), dimensions (vals.dims ())
+  {
+    map[k] = vals;
+    key_list.push_back (k);
+  }
+
+  Octave_map (const std::string& k, const octave_value_list& val_list)
+    : map (), key_list (), dimensions (1, val_list.length ())
+  {
+    map[k] = val_list;
+    key_list.push_back (k);
+  }
+
+  Octave_map (const Octave_map& m)
+    : map (m.map), key_list (m.key_list), dimensions (m.dimensions) { }
+
+  Octave_map& operator = (const Octave_map& m)
+    {
+      if (this != &m)
+	{
+	  map = m.map;
+	  key_list = m.key_list;
+	  dimensions = m.dimensions;
+	}
+
+      return *this;
+    }
+
+  ~Octave_map (void) { }
+
+  Octave_map squeeze (void) const; 
+
+  Octave_map permute (const Array<int>& vec, bool inv = false) const; 
+
+  // This is the number of keys.
+  octave_idx_type nfields (void) const { return map.size (); }
+
+  void del (const std::string& k)
+    {
+      iterator p = map.find (k);
+
+      if (p != map.end ())
+	{
+	  map.erase (p);
+
+	  key_list_iterator q
+	    = std::find (key_list.begin (), key_list.end (), k);
+
+	  assert (q != key_list.end ());
+
+	  key_list.erase (q);
+	}
+    }
+
+  iterator begin (void) { return iterator (map.begin ()); }
+  const_iterator begin (void) const { return const_iterator (map.begin ()); }
+
+  iterator end (void) { return iterator (map.end ()); }
+  const_iterator end (void) const { return const_iterator (map.end ()); }
+
+  std::string key (const_iterator p) const { return p->first; }
+
+  Cell& contents (const std::string& k);
+  Cell contents (const std::string& k) const;
+
+  Cell& contents (iterator p)
+    { return p->second; }
+
+  Cell contents (const_iterator p) const
+    { return p->second; }
+
+  int intfield (const std::string& k, int def_val = 0) const;
+
+  std::string stringfield (const std::string& k,
+			   const std::string& def_val = std::string ()) const;
+
+  iterator seek (const std::string& k) { return map.find (k); }
+  const_iterator seek (const std::string& k) const { return map.find (k); }
+
+  bool contains (const std::string& k) const
+    { return (seek (k) != map.end ()); }
+
+  void clear (void)
+    {
+      map.clear ();
+      key_list.clear ();
+    }
+
+  string_vector keys (void) const;
+
+  octave_idx_type rows (void) const { return dimensions(0); }
+
+  octave_idx_type columns (void) const { return dimensions(1); }
+
+  dim_vector dims (void) const { return dimensions; }
+
+  int ndims (void) const { return dimensions.length (); }
+
+  Octave_map transpose (void) const;
+
+  Octave_map reshape (const dim_vector& new_dims) const;
+
+  void resize (const dim_vector& dv, bool fill = false);
+
+  octave_idx_type numel (void) const { return dimensions.numel (); }
+
+  Octave_map concat (const Octave_map& rb, const Array<octave_idx_type>& ra_idx);
+
+  Octave_map& maybe_delete_elements (const octave_value_list& idx);
+
+  Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
+
+  Octave_map& assign (const octave_value_list& idx, const std::string& k,
+		      const Cell& rhs);
+
+  Octave_map& assign (const std::string& k, const octave_value& rhs);
+
+  Octave_map& assign (const std::string& k, const Cell& rhs);
+
+  Octave_map index (const octave_value_list& idx, 
+		    bool resize_ok = false) const;
+
+private:
+
+  // The map of names to values.
+  std::map<std::string, Cell> map;
+
+  // An extra list of keys, so we can keep track of the order the keys
+  // are added for compatibility with you know what.
+  std::list<std::string> key_list;
+
+  // The current size.
+  mutable dim_vector dimensions;
+
+  void maybe_add_to_key_list (const std::string& k)
+    {
+      if (! contains (k))
+	key_list.push_back (k);
+    }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-obj.cc b/src/oct-obj.cc
new file mode 100644
index 0000000..432967c
--- /dev/null
+++ b/src/oct-obj.cc
@@ -0,0 +1,273 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "Cell.h"
+
+octave_value_list::octave_value_list (const std::list<octave_value_list>& lst)
+{
+  octave_idx_type n = 0, nel = 0;
+
+  // Determine number.
+  for (std::list<octave_value_list>::const_iterator p = lst.begin ();
+       p != lst.end (); p++)
+    {
+      n++;
+      nel += p->length ();
+    }
+
+  // Optimize single-element case
+  if (n == 1)
+    data = lst.front ().data;
+  else if (nel > 0)
+    {
+      data.resize (nel);
+      octave_idx_type k = 0;
+      for (std::list<octave_value_list>::const_iterator p = lst.begin ();
+           p != lst.end (); p++)
+        {
+          data.assign (idx_vector (k, k + p->length ()), p->data);
+          k += p->length ();
+        }
+      assert (k == nel);
+    }
+
+}
+
+octave_allocator
+octave_value_list::allocator (sizeof (octave_value_list));
+
+octave_value_list&
+octave_value_list::prepend (const octave_value& val)
+{
+  octave_idx_type n = length ();
+
+  resize (n + 1);
+
+  while (n > 0)
+    {
+      elem (n) = elem (n - 1);
+      n--;
+    }
+
+  elem (0) = val;
+  
+  return *this;
+}
+
+octave_value_list&
+octave_value_list::append (const octave_value& val)
+{
+  octave_idx_type n = length ();
+
+  resize (n + 1);
+
+  elem (n) = val;
+
+  return *this;
+}
+
+octave_value_list&
+octave_value_list::append (const octave_value_list& lst)
+{
+  octave_idx_type len = length ();
+  octave_idx_type lst_len = lst.length ();
+
+  resize (len + lst_len);
+
+  for (octave_idx_type i = 0; i < lst_len; i++)
+    elem (len + i) = lst (i);
+
+  return *this;
+}
+
+octave_value_list&
+octave_value_list::reverse (void)
+{
+  octave_idx_type n = length ();
+
+  for (octave_idx_type i = 0; i < n / 2; i++)
+    {
+      octave_value tmp = elem (i);
+      elem (i) = elem (n - i - 1);
+      elem (n - i - 1) = tmp;
+    }
+
+  return *this;
+}
+
+octave_value_list
+octave_value_list::splice (octave_idx_type offset, octave_idx_type rep_length,
+			   const octave_value_list& lst) const
+{ 
+  octave_value_list retval;
+
+  octave_idx_type len = length ();
+
+  if (offset < 0 || offset >= len)
+    {
+      if (! (rep_length == 0 && offset == len))
+	{
+	  error ("octave_value_list::splice: invalid OFFSET");
+	  return retval;
+	}
+    }
+
+  if (rep_length < 0 || rep_length + offset > len)
+    {
+      error ("octave_value_list::splice: invalid LENGTH");
+      return retval;
+    }
+
+  octave_idx_type lst_len = lst.length ();
+
+  octave_idx_type new_len = len - rep_length + lst_len;
+
+  retval.resize (new_len);
+
+  octave_idx_type k = 0;
+
+  for (octave_idx_type i = 0; i < offset; i++)
+    retval(k++) = elem (i);
+
+  for (octave_idx_type i = 0; i < lst_len; i++)
+    retval(k++) = lst(i);
+
+  for (octave_idx_type i = offset + rep_length; i < len; i++)
+    retval(k++) = elem (i);
+
+  return retval;
+}
+
+bool
+octave_value_list::all_strings_p (void) const
+{
+  octave_idx_type n = length ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    if (! elem(i).is_string ())
+      return false;
+
+  return true;
+}
+
+bool
+octave_value_list::all_scalars (void) const
+{
+  octave_idx_type n = length (), i;
+
+  for (i = 0; i < n && elem (i).is_string (); i++) ;
+  
+  return i == n;
+}
+
+bool
+octave_value_list::has_magic_colon (void) const
+{
+  octave_idx_type n = length ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    if (elem(i).is_magic_colon ())
+      return true;
+
+  return false;
+}
+
+string_vector
+octave_value_list::make_argv (const std::string& fcn_name) const
+{
+  string_vector argv;
+
+  if (all_strings_p ())
+    {
+      octave_idx_type len = length ();
+
+      octave_idx_type total_nr = 0;
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  // An empty std::string ("") has zero columns and zero rows (a
+	  // change that was made for Matlab contemptibility.
+
+	  octave_idx_type n = elem(i).rows ();
+
+	  total_nr += n ? n : 1;
+	}
+
+      octave_idx_type k = 0;
+      if (! fcn_name.empty ())
+        {
+          argv.resize (total_nr+1);
+          argv[0] = fcn_name;
+          k = 1;
+        }
+      else
+        argv.resize (total_nr);
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  octave_idx_type nr = elem(i).rows ();
+
+	  if (nr < 2)
+	    argv[k++] = elem(i).string_value ();
+	  else
+	    {
+	      string_vector tmp = elem(i).all_strings ();
+
+	      for (octave_idx_type j = 0; j < nr; j++)
+		argv[k++] = tmp[j];
+	    }
+	}
+    }
+  else
+    error ("%s: expecting all arguments to be strings", fcn_name.c_str ());
+
+  return argv;
+}
+
+void
+octave_value_list::make_storable_values (void)
+{
+  octave_idx_type len = length ();
+  const Array<octave_value>& cdata = data;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      // This is optimized so that we don't force a copy unless necessary.
+      octave_value tmp = cdata(i).storable_value ();
+      if (! tmp.is_copy_of (cdata (i)))
+        data(i) = tmp;
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-obj.h b/src/oct-obj.h
new file mode 100644
index 0000000..9fd12c0
--- /dev/null
+++ b/src/oct-obj.h
@@ -0,0 +1,191 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008 John W. Eaton
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_obj_h)
+#define octave_oct_obj_h 1
+
+#include <string>
+#include <vector>
+
+#include "oct-alloc.h"
+#include "str-vec.h"
+#include "Array.h"
+
+#include "ov.h"
+#include "Cell.h"
+
+class
+OCTINTERP_API
+octave_value_list
+{
+public:
+
+  octave_value_list (void)
+    : data () { }
+
+  octave_value_list (octave_idx_type n, const octave_value& val)
+    : data (dim_vector (1, n), val) { }
+
+  octave_value_list (const octave_value& tc)
+    : data (1, tc) { }
+
+  octave_value_list (const Array<octave_value>& d)
+    : data (d.reshape (dim_vector (1, d.numel ()))) { }
+
+  octave_value_list (const Cell& tc)
+    : data (tc.reshape (dim_vector (1, tc.numel ()))) { }
+
+  octave_value_list (const octave_value_list& obj)
+    : data (obj.data), names (obj.names) { }
+
+  // Concatenation constructor.
+  octave_value_list (const std::list<octave_value_list>&);
+
+  ~octave_value_list (void) { }
+
+  void *operator new (size_t size)
+    { return allocator.alloc (size); }
+
+  void operator delete (void *p, size_t size)
+    { allocator.free (p, size); }
+
+  // FIXME -- without this, I have errors with the stack of
+  // octave_value_list objects in ov-usr-fcn.h.  Why?
+  void *operator new (size_t size, void *p)
+    { return ::operator new (size, p); }
+
+  void operator delete (void *p, void *)
+    {
+#if defined (HAVE_PLACEMENT_DELETE)
+      ::operator delete (p, static_cast<void *> (0));
+#else
+      ::operator delete (p);
+#endif
+    }
+
+  octave_value_list& operator = (const octave_value_list& obj)
+    {
+      if (this != &obj)
+	{
+	  data = obj.data;
+	  names = obj.names;
+	}
+
+      return *this;
+    }
+
+  Array<octave_value> array_value (void) const { return data; }
+
+  Cell cell_value (void) const { return array_value (); }
+
+  // Assignment will resize on range errors.
+
+  octave_value& operator () (octave_idx_type n) { return elem (n); }
+
+  octave_value operator () (octave_idx_type n) const { return elem (n); }
+
+  octave_idx_type length (void) const { return data.length (); }
+
+  bool empty (void) const { return length () == 0; }
+
+  void resize (octave_idx_type n) { data.resize (n); }
+
+  void resize (octave_idx_type n, const octave_value& val)
+    { data.resize (n, val); }
+
+  octave_value_list& prepend (const octave_value& val);
+
+  octave_value_list& append (const octave_value& val);
+
+  octave_value_list& append (const octave_value_list& lst);
+
+  octave_value_list& reverse (void);
+
+  octave_value_list
+  slice (octave_idx_type offset, octave_idx_type len) const
+    { return data.index (idx_vector (offset, offset + len)); }
+
+  octave_value_list
+  splice (octave_idx_type offset, octave_idx_type len,
+	  const octave_value_list& lst = octave_value_list ()) const;
+
+  bool all_strings_p (void) const;
+
+  bool all_scalars (void) const;
+
+  bool has_magic_colon (void) const;
+
+  string_vector make_argv (const std::string& = std::string()) const;
+
+  void stash_name_tags (const string_vector& nm) { names = nm; }
+
+  string_vector name_tags (void) const { return names; }
+
+  void make_storable_values (void);
+
+private:
+
+  static octave_allocator allocator;
+
+  Array<octave_value> data;
+
+  // This list of strings can be used to tag each element of data with
+  // a name.  By default, it is empty.
+  string_vector names;
+
+  // This constructor is private with no definition to keep statements
+  // like
+  //
+  //   octave_value_list foo = 5;
+  //   octave_value_list foo = 5.0;
+  //
+  // from doing different things.  Instead, you have to use the
+  // constructor
+  //
+  //   octave_value_list (n, val);
+  //
+  // and supply a default value to create a vector-valued
+  // octave_value_list.
+
+  octave_value_list (octave_idx_type n);
+
+  octave_value& elem (octave_idx_type n)
+    {
+      if (n >= length ())
+	resize (n + 1);
+
+      return data(n);
+    }
+
+  octave_value elem (octave_idx_type n) const
+    { return data(n); }
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-prcstrm.cc b/src/oct-prcstrm.cc
new file mode 100644
index 0000000..ccc0d81
--- /dev/null
+++ b/src/oct-prcstrm.cc
@@ -0,0 +1,77 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdio>
+
+#include "oct-prcstrm.h"
+#include "sysdep.h"
+
+octave_stream
+octave_iprocstream::create (const std::string& n, std::ios::openmode arg_md,
+			    oct_mach_info::float_format ff)
+{
+  return octave_stream (new octave_iprocstream (n, arg_md, ff));
+}
+
+octave_iprocstream::octave_iprocstream (const std::string& n,
+					std::ios::openmode arg_md,
+					oct_mach_info::float_format ff)
+  : octave_stdiostream (n, octave_popen (n.c_str (), "r"),
+			arg_md, ff, octave_pclose)
+{
+}
+
+octave_iprocstream::~octave_iprocstream (void)
+{
+  do_close ();
+}
+
+octave_stream
+octave_oprocstream::create (const std::string& n, std::ios::openmode arg_md,
+			    oct_mach_info::float_format ff)
+{
+  return octave_stream (new octave_oprocstream (n, arg_md, ff));
+}
+
+octave_oprocstream::octave_oprocstream (const std::string& n,
+					std::ios::openmode arg_md,
+					oct_mach_info::float_format ff)
+  : octave_stdiostream (n, octave_popen (n.c_str (), "w"),
+			arg_md, ff, octave_pclose)
+{
+}
+
+octave_oprocstream::~octave_oprocstream (void)
+{
+  do_close ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-prcstrm.h b/src/oct-prcstrm.h
new file mode 100644
index 0000000..9b16bab
--- /dev/null
+++ b/src/oct-prcstrm.h
@@ -0,0 +1,94 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2003, 2004, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_procstream_h)
+#define octave_octave_procstream_h 1
+
+#include "oct-stdstrm.h"
+
+// FIXME -- why don't these classes use iprocstream and
+// oprocstream, which in turn use the octave_procbuf class?
+
+class
+octave_iprocstream : public octave_stdiostream
+{
+public:
+
+  octave_iprocstream (const std::string& n,
+		      std::ios::openmode arg_md = std::ios::in,
+		      oct_mach_info::float_format flt_fmt
+		        = oct_mach_info::native_float_format ());
+
+  static octave_stream
+  create (const std::string& n, std::ios::openmode arg_md = std::ios::in,
+	  oct_mach_info::float_format flt_fmt
+	    = oct_mach_info::native_float_format ());
+
+protected:
+
+  ~octave_iprocstream (void);
+
+private:
+
+  // No copying!
+
+  octave_iprocstream (const octave_iprocstream&);
+
+  octave_iprocstream& operator = (const octave_iprocstream&);
+};
+
+class
+octave_oprocstream : public octave_stdiostream
+{
+public:
+
+  octave_oprocstream (const std::string& n,
+		      std::ios::openmode arg_md = std::ios::out,
+		      oct_mach_info::float_format flt_fmt
+		        = oct_mach_info::native_float_format ());
+
+  static octave_stream
+  create (const std::string& n, std::ios::openmode arg_md = std::ios::out,
+	  oct_mach_info::float_format flt_fmt
+	    = oct_mach_info::native_float_format ());
+
+protected:
+
+  ~octave_oprocstream (void);
+
+private:
+
+  // No copying!
+
+  octave_oprocstream (const octave_oprocstream&);
+
+  octave_oprocstream& operator = (const octave_oprocstream&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-procbuf.cc b/src/oct-procbuf.cc
new file mode 100644
index 0000000..7981a9d
--- /dev/null
+++ b/src/oct-procbuf.cc
@@ -0,0 +1,229 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2006
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+
+#include <iostream>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "oct-procbuf.h"
+#include "oct-syscalls.h"
+#include "sysdep.h"
+#include "variables.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "utils.h"
+
+// This class is based on the procbuf class from libg++, written by
+// Per Bothner, Copyright (C) 1993 Free Software Foundation.
+
+static octave_procbuf *octave_procbuf_list = 0;
+
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+octave_procbuf *
+octave_procbuf::open (const char *command, int mode)
+{
+#if defined (__CYGWIN__) || defined (__MINGW32__) || defined (_MSC_VER)
+
+  if (is_open ()) 
+    return 0;
+
+  f = octave_popen (command, (mode & std::ios::in) ? "r" : "w");
+
+  if (! f)
+    return 0;
+
+  // Oops... popen doesn't return the associated pid, so fake it for now
+
+  proc_pid = 1;
+
+  open_p = true;
+
+  if (mode & std::ios::out)
+    ::setvbuf (f, 0, _IOLBF, BUFSIZ);
+
+  return this;
+  
+#elif defined (HAVE_SYS_WAIT_H)
+
+  int pipe_fds[2];
+
+  volatile int child_std_end = (mode & std::ios::in) ? 1 : 0;
+
+  volatile int parent_end, child_end;
+
+  if (is_open ())
+    return 0;
+
+  if (pipe (pipe_fds) < 0)
+    return 0;
+
+  if (mode & std::ios::in)
+    {
+      parent_end = pipe_fds[0];
+      child_end = pipe_fds[1];
+    }
+  else
+    {
+      parent_end = pipe_fds[1];
+      child_end = pipe_fds[0];
+    }
+
+  proc_pid = ::fork ();
+
+  if (proc_pid == 0)
+    {
+      ::close (parent_end);
+
+      if (child_end != child_std_end)
+	{
+	  ::dup2 (child_end, child_std_end);
+	  ::close (child_end);
+	}
+
+      while (octave_procbuf_list)
+	{
+	  FILE *fp = octave_procbuf_list->f;
+
+	  if (fp)
+	    {
+	      ::fclose (fp);
+	      fp = 0;
+	    }
+
+	  octave_procbuf_list = octave_procbuf_list->next;
+	}
+
+      execl ("/bin/sh", "sh", "-c", command, static_cast<void *> (0));
+
+      exit (127);
+    }
+
+  ::close (child_end);
+
+  if (proc_pid < 0)
+    {
+      ::close (parent_end);
+      return 0;
+    }
+
+  f = ::fdopen (parent_end, (mode & std::ios::in) ? "r" : "w");
+
+  if (mode & std::ios::out)
+    ::setvbuf (f, 0, _IOLBF, BUFSIZ);
+
+  open_p = true;
+
+  next = octave_procbuf_list;
+  octave_procbuf_list = this;
+
+  return this;
+
+#else
+
+  return 0;
+
+#endif
+}
+
+octave_procbuf *
+octave_procbuf::close (void)
+{
+#if defined (__CYGWIN__) || defined (__MINGW32__) || defined (_MSC_VER)
+
+  if (f)
+    {
+      wstatus = octave_pclose (f);
+      f = 0;
+    }
+
+  open_p = false;
+
+  return this;
+  
+#elif defined (HAVE_SYS_WAIT_H)
+
+  if (f)
+    {
+      pid_t wait_pid;
+
+      int status = -1;
+
+      for (octave_procbuf **ptr = &octave_procbuf_list;
+	   *ptr != 0;
+	   ptr = &(*ptr)->next)
+	{
+	  if (*ptr == this)
+	    {
+	      *ptr = (*ptr)->next;
+	      status = 0;
+	      break;
+	    }
+	}
+
+      if (status == 0 && ::fclose (f) == 0)
+	{
+	  using namespace std;
+
+	  do
+	    {
+	      wait_pid = octave_syscalls::waitpid (proc_pid, &wstatus, 0);
+	    }
+	  while (wait_pid == -1 && errno == EINTR);
+	}
+
+      f = 0;
+    }
+
+  open_p = false;
+
+  return this;
+
+#else
+
+  return 0;
+
+#endif
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-procbuf.h b/src/oct-procbuf.h
new file mode 100644
index 0000000..04355d6
--- /dev/null
+++ b/src/oct-procbuf.h
@@ -0,0 +1,79 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This class is based on the procbuf class from libg++, written by
+// Per Bothner, Copyright (C) 1993 Free Software Foundation.
+
+#if !defined (octave_octave_procbuf_h)
+#define octave_octave_procbuf_h 1
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "c-file-ptr-stream.h"
+
+class
+octave_procbuf : public c_file_ptr_buf
+{
+public:
+
+  octave_procbuf (void)
+    : c_file_ptr_buf (0), wstatus (-1), open_p (false), proc_pid (-1),
+      next (0) { }
+
+  octave_procbuf (const char *command, int mode)
+    : c_file_ptr_buf (0), wstatus (-1), open_p (false), proc_pid (-1),
+      next (0) { open (command, mode); }
+
+  ~octave_procbuf (void) { close (); }
+
+  octave_procbuf *open (const char *command, int mode);
+
+  octave_procbuf *close (void);
+
+  int wait_status (void) const { return wstatus; }
+
+  bool is_open (void) const { return open_p; }
+
+  pid_t pid (void) const { return proc_pid; }
+
+protected:
+
+  int wstatus;
+
+  bool open_p;
+
+  pid_t proc_pid;
+
+  octave_procbuf *next;
+};
+
+extern void symbols_of_oct_procbuf (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-stdstrm.h b/src/oct-stdstrm.h
new file mode 100644
index 0000000..8f77218
--- /dev/null
+++ b/src/oct-stdstrm.h
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_stdiostream_h)
+#define octave_octave_stdiostream_h 1
+
+#include "oct-stream.h"
+#include "c-file-ptr-stream.h"
+
+template <typename BUF_T, typename STREAM_T, typename FILE_T>
+class
+octave_tstdiostream : public octave_base_stream
+{
+public:
+
+  octave_tstdiostream (const std::string& n, FILE_T f = 0,
+		       std::ios::openmode m = std::ios::in|std::ios::out,
+		       oct_mach_info::float_format ff
+		         = oct_mach_info::native_float_format (),
+		       typename BUF_T::close_fcn cf = BUF_T::fclose)
+    : octave_base_stream (m, ff), nm (n), md (m),
+      s (f ? new STREAM_T (f, cf) : 0)
+  { }
+
+  static octave_stream
+  create (const std::string& n, FILE_T f = 0,
+	  std::ios::openmode m = std::ios::in|std::ios::out,
+	  oct_mach_info::float_format ff
+	    = oct_mach_info::native_float_format (),
+	  typename BUF_T::close_fcn cf = BUF_T::fclose)
+  {
+    return octave_stream (new octave_tstdiostream (n, f, m, ff, cf));
+  }
+
+  // Position a stream at OFFSET relative to ORIGIN.
+
+  int seek (long offset, int origin)
+    { return s ? s->seek (offset, origin) : -1; }
+
+  // Return current stream position.
+
+  long tell (void) { return s ? s->tell () : -1; }
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const { return s ? s->eof () : true; }
+
+  // The name of the file.
+
+  std::string name (void) const { return nm; }
+
+  std::istream *input_stream (void) { return (md & std::ios::in) ? s : 0; }
+
+  std::ostream *output_stream (void) { return (md & std::ios::out) ? s : 0; }
+
+  // FIXME -- should not have to cast away const here.
+  BUF_T *rdbuf (void) const
+    { return s ? (const_cast<STREAM_T *> (s))->rdbuf () : 0; }
+
+  bool bad (void) const { return s ? s->bad () : true; }
+
+  void clear (void) { if (s) s->clear (); }
+
+  void do_close (void) { if (s) s->close (); }
+
+protected:
+
+  std::string nm;
+
+  std::ios::openmode md;
+
+  STREAM_T *s;
+
+  ~octave_tstdiostream (void) { delete s; }
+
+private:
+
+  // No copying!
+
+  octave_tstdiostream (const octave_tstdiostream&);
+
+  octave_tstdiostream& operator = (const octave_tstdiostream&);
+};
+
+typedef octave_tstdiostream<c_file_ptr_buf, io_c_file_ptr_stream, FILE *> octave_stdiostream;
+
+#ifdef HAVE_ZLIB
+
+typedef octave_tstdiostream<c_zfile_ptr_buf, io_c_zfile_ptr_stream, gzFile> octave_zstdiostream;
+
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-stream.cc b/src/oct-stream.cc
new file mode 100644
index 0000000..198b539
--- /dev/null
+++ b/src/oct-stream.cc
@@ -0,0 +1,4345 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cctype>
+#include <cstring>
+
+#include <iomanip>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+
+#include <Array.h>
+
+#include "byte-swap.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "str-vec.h"
+#include "quit.h"
+
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "oct-stdstrm.h"
+#include "oct-stream.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+// Possible values for conv_err:
+//
+//   1 : not a real scalar
+//   2 : value is NaN
+//   3 : value is not an integer
+
+static int
+convert_to_valid_int (const octave_value& tc, int& conv_err)
+{
+  int retval = 0;
+
+  conv_err = 0;
+
+  double dval = tc.double_value ();
+
+  if (! error_state)
+    {
+      if (! lo_ieee_isnan (dval))
+	{
+	  int ival = NINT (dval);
+
+	  if (ival == dval)
+	    retval = ival;
+	  else
+	    conv_err = 3;
+	}
+      else
+	conv_err = 2;
+    }
+  else
+    conv_err = 1;
+
+  return retval;
+}
+
+static int
+get_size (double d, const std::string& who)
+{
+  int retval = -1;
+
+  if (! lo_ieee_isnan (d))
+    {
+      if (! xisinf (d))
+	{
+	  if (d >= 0.0)
+	    retval = NINT (d);
+	  else
+	    ::error ("%s: negative value invalid as size specification",
+		     who.c_str ());
+	}
+      else
+	retval = -1;
+    }
+  else
+    ::error ("%s: NaN is invalid as size specification", who.c_str ());
+
+  return retval;
+}
+
+static void
+get_size (const Array<double>& size, octave_idx_type& nr, octave_idx_type& nc, bool& one_elt_size_spec,
+	  const std::string& who)
+{
+  nr = -1;
+  nc = -1;
+
+  one_elt_size_spec = false;
+
+  double dnr = -1.0;
+  double dnc = -1.0;
+
+  octave_idx_type sz_len = size.length ();
+
+  if (sz_len == 1)
+    {
+      one_elt_size_spec = true;
+
+      dnr = size (0);
+
+      dnc = (dnr == 0.0) ? 0.0 : 1.0;
+    }
+  else if (sz_len == 2)
+    {
+      dnr = size (0);
+
+      if (! xisinf (dnr))
+	dnc = size (1);
+      else
+	::error ("%s: invalid size specification", who.c_str ());
+    }
+  else
+    ::error ("%s: invalid size specification", who.c_str ());
+
+  if (! error_state)
+    {
+      nr = get_size (dnr, who);
+
+      if (! error_state && dnc >= 0.0)
+	nc = get_size (dnc, who);
+    }
+}
+
+scanf_format_list::scanf_format_list (const std::string& s)
+  : nconv (0), curr_idx (0), list (16), buf (0)
+{
+  int num_elts = 0;
+
+  int n = s.length ();
+
+  int i = 0;
+
+  int width = 0;
+  bool discard = false;
+  char modifier = '\0';
+  char type = '\0';
+
+  bool have_more = true;
+
+  while (i < n)
+    {
+      have_more = true;
+
+      if (! buf)
+	buf = new std::ostringstream ();
+
+      if (s[i] == '%')
+	{
+	  // Process percent-escape conversion type.
+
+	  process_conversion (s, i, n, width, discard, type, modifier,
+			      num_elts);
+	  have_more = (buf != 0);
+	}
+      else if (isspace (s[i]))
+	{
+	  type = scanf_format_elt::whitespace_conversion;
+
+	  width = 0;
+	  discard = false;
+	  modifier = '\0';
+	  *buf << " ";
+
+	  while (++i < n && isspace (s[i]))
+	    /* skip whitespace */;
+
+	  add_elt_to_list (width, discard, type, modifier, num_elts);
+
+	  have_more = false;
+	}
+      else
+	{
+	  type = scanf_format_elt::literal_conversion;
+
+	  width = 0;
+	  discard = false;
+	  modifier = '\0';
+
+	  while (i < n && ! isspace (s[i]) && s[i] != '%')
+	    *buf << s[i++];
+
+	  add_elt_to_list (width, discard, type, modifier, num_elts);
+
+	  have_more = false;
+	}
+
+      if (nconv < 0)
+	{
+	  have_more = false;
+	  break;
+	}
+    }
+
+  if (have_more)
+    add_elt_to_list (width, discard, type, modifier, num_elts);
+
+  list.resize (num_elts);
+
+  delete buf;
+}
+
+scanf_format_list::~scanf_format_list (void)
+{
+  octave_idx_type n = list.length ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      scanf_format_elt *elt = list(i);
+      delete elt;
+    }	
+}
+
+void
+scanf_format_list::add_elt_to_list (int width, bool discard, char type,
+				    char modifier, int& num_elts,
+				    const std::string& char_class)
+{
+  if (buf)
+    {
+      std::string text = buf->str ();
+
+      if (! text.empty ())
+	{
+	  scanf_format_elt *elt
+	    = new scanf_format_elt (text.c_str (), width, discard, type,
+				    modifier, char_class);
+
+	  if (num_elts == list.length ())
+	    list.resize (2 * num_elts);
+
+	  list(num_elts++) = elt;
+	}
+
+      delete buf;
+      buf = 0;
+    }
+}
+
+static std::string
+expand_char_class (const std::string& s)
+{
+  std::string retval;
+
+  size_t len = s.length ();
+
+  size_t i = 0;
+
+  while (i < len)
+    {
+      unsigned char c = s[i++];
+
+      if (c == '-' && i > 1 && i < len
+	  && static_cast<unsigned char> (s[i-2]) <= static_cast<unsigned char> (s[i]))
+	{
+	  // Add all characters from the range except the first (we
+	  // already added it below).
+
+	  for (c = s[i-2]+1; c < s[i]; c++)
+	    retval += c;
+	}
+      else
+	{
+	  // Add the character to the class.  Only add '-' if it is
+	  // the last character in the class.
+
+	  if (c != '-' || i == len)
+	    retval += c;
+	}
+    }
+
+  return retval;
+}
+
+void
+scanf_format_list::process_conversion (const std::string& s, int& i, int n,
+				       int& width, bool& discard, char& type,
+				       char& modifier, int& num_elts)
+{
+  width = 0;
+  discard = false;
+  modifier = '\0';
+  type = '\0';
+
+  *buf << s[i++];
+
+  bool have_width = false;
+
+  while (i < n)
+    {
+      switch (s[i])
+	{
+	case '*':
+	  if (discard)
+	    nconv = -1;
+	  else
+	    {
+	      discard = true;
+	      *buf << s[i++];
+	    }
+	  break;
+
+	case '0': case '1': case '2': case '3': case '4':
+	case '5': case '6': case '7': case '8': case '9':
+	  if (have_width)
+	    nconv = -1;
+	  else
+	    {
+	      char c = s[i++];
+	      width = width * 10 + c - '0';
+	      have_width = true;
+	      *buf << c;
+	      while (i < n && isdigit (s[i]))
+		{
+		  c = s[i++];
+		  width = width * 10 + c - '0';
+		  *buf << c;
+		}
+	    }
+	  break;
+
+	case 'h': case 'l': case 'L':
+	  if (modifier != '\0')
+	    nconv = -1;
+	  else
+	    modifier = s[i++];
+	  break;
+
+	case 'd': case 'i': case 'o': case 'u': case 'x':
+	  if (modifier == 'L')
+	    {
+	      nconv = -1;
+	      break;
+	    }
+	  goto fini;
+
+	case 'e': case 'f': case 'g':
+	  if (modifier == 'h')
+	    {
+	      nconv = -1;
+	      break;
+	    }
+
+	  // No float or long double conversions, thanks.
+	  *buf << 'l';
+
+	  goto fini;
+
+	case 'c': case 's': case 'p': case '%': case '[':
+	  if (modifier != '\0')
+	    {
+	      nconv = -1;
+	      break;
+	    }
+	  goto fini;
+
+	fini:
+	  {
+	    if (finish_conversion (s, i, n, width, discard, type,
+				   modifier, num_elts) == 0)
+	      return;
+	  }
+	  break;
+
+	default:
+	  nconv = -1;
+	  break;
+	}
+
+      if (nconv < 0)
+	break;
+    }
+
+  nconv = -1;
+}
+
+int
+scanf_format_list::finish_conversion (const std::string& s, int& i, int n,
+				      int& width, bool discard, char& type,
+				      char modifier, int& num_elts)
+{
+  int retval = 0;
+
+  std::string char_class;
+
+  int beg_idx = -1;
+  int end_idx = -1;
+
+  if (s[i] == '%')
+    {
+      type = '%';
+      *buf << s[i++];
+    }
+  else
+    {
+      type = s[i];
+
+      if (s[i] == '[')
+	{
+	  *buf << s[i++];
+
+	  if (i < n)
+	    {
+	      beg_idx = i;
+
+	      if (s[i] == '^')
+		{
+		  type = '^';
+		  *buf << s[i++];
+
+		  if (i < n)
+		    {
+		      beg_idx = i;
+
+		      if (s[i] == ']')
+			*buf << s[i++];
+		    }
+		}
+	      else if (s[i] == ']')
+		*buf << s[i++];
+	    }
+
+	  while (i < n && s[i] != ']')
+	    *buf << s[i++];
+
+	  if (i < n && s[i] == ']')
+	    {
+	      end_idx = i-1;
+	      *buf << s[i++];
+	    }
+
+	  if (s[i-1] != ']')
+	    retval = nconv = -1;
+	}
+      else
+	*buf << s[i++];
+    }
+
+  nconv++;
+
+  if (nconv > 0)
+    {
+      if (beg_idx >= 0 && end_idx >= 0)
+	char_class = expand_char_class (s.substr (beg_idx,
+						  end_idx - beg_idx + 1));
+
+      add_elt_to_list (width, discard, type, modifier, num_elts, char_class);
+    }
+
+  return retval;
+}
+
+void
+scanf_format_list::printme (void) const
+{
+  int n = list.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      scanf_format_elt *elt = list(i);
+
+      std::cerr
+	<< "width:      " << elt->width << "\n"
+	<< "discard:    " << elt->discard << "\n"
+	<< "type:       ";
+
+      if (elt->type == scanf_format_elt::literal_conversion)
+	std::cerr << "literal text\n";
+      else if (elt->type == scanf_format_elt::whitespace_conversion)
+	std::cerr << "whitespace\n";
+      else
+	std::cerr << elt->type << "\n";
+
+      std::cerr
+	<< "modifier:   " << elt->modifier << "\n"
+	<< "char_class: `" << undo_string_escapes (elt->char_class) << "'\n"
+	<< "text:       `" << undo_string_escapes (elt->text) << "'\n\n";
+    }
+}
+
+bool
+scanf_format_list::all_character_conversions (void)
+{
+  int n = list.length ();
+
+  if (n > 0)
+    {
+      for (int i = 0; i < n; i++)
+	{
+	  scanf_format_elt *elt = list(i);
+
+	  switch (elt->type)
+	    {
+	    case 'c': case 's': case '%': case '[': case '^':
+	    case scanf_format_elt::literal_conversion:
+	    case scanf_format_elt::whitespace_conversion:
+	      break;
+
+	    default:
+	      return false;
+	      break;
+	    }
+	}
+
+      return true;
+    }
+  else
+    return false;
+}
+
+bool
+scanf_format_list::all_numeric_conversions (void)
+{
+  int n = list.length ();
+
+  if (n > 0)
+    {
+      for (int i = 0; i < n; i++)
+	{
+	  scanf_format_elt *elt = list(i);
+
+	  switch (elt->type)
+	    {
+	    case 'd': case 'i': case 'o': case 'u': case 'x':
+	    case 'e': case 'f': case 'g':
+	      break;
+
+	    default:
+	      return false;
+	      break;
+	    }
+	}
+
+      return true;
+    }
+  else
+    return false;
+}
+
+// Ugh again.
+
+printf_format_list::printf_format_list (const std::string& s)
+  : nconv (0), curr_idx (0), list (16), buf (0)
+{
+  int num_elts = 0;
+
+  int n = s.length ();
+
+  int i = 0;
+
+  int args = 0;
+  std::string flags;
+  int fw = 0;
+  int prec = 0;
+  char modifier = '\0';
+  char type = '\0';
+
+  bool have_more = true;
+  bool empty_buf = true;
+
+  if (n == 0)
+    {
+      printf_format_elt *elt
+	= new printf_format_elt ("", args, fw, prec, flags, type, modifier);
+
+      list(num_elts++) = elt;
+
+      list.resize (num_elts);
+    }
+  else
+    {
+      while (i < n)
+	{
+	  have_more = true;
+
+	  if (! buf)
+	    {
+	      buf = new std::ostringstream ();
+	      empty_buf = true;
+	    }
+
+	  switch (s[i])
+	    {
+	    case '%':
+	      {
+		if (empty_buf)
+		  {
+		    process_conversion (s, i, n, args, flags, fw, prec,
+					type, modifier, num_elts);
+
+		    have_more = (buf != 0);
+		  }
+		else
+		  add_elt_to_list (args, flags, fw, prec, type, modifier,
+				   num_elts);
+	      }
+	      break;
+
+	    default:
+	      {
+		args = 0;
+		flags = "";
+		fw = 0;
+		prec = 0;
+		modifier = '\0';
+		type = '\0';
+		*buf << s[i++];
+		empty_buf = false;
+	      }
+	      break;
+	    }
+
+	  if (nconv < 0)
+	    {
+	      have_more = false;
+	      break;
+	    }
+	}
+
+      if (have_more)
+	add_elt_to_list (args, flags, fw, prec, type, modifier, num_elts);
+
+      list.resize (num_elts);
+
+      delete buf;
+    }
+}
+
+printf_format_list::~printf_format_list (void)
+{
+  int n = list.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      printf_format_elt *elt = list(i);
+      delete elt;
+    }	
+}
+
+void
+printf_format_list::add_elt_to_list (int args, const std::string& flags,
+				     int fw, int prec, char type,
+				     char modifier, int& num_elts)
+{
+  if (buf)
+    {
+      std::string text = buf->str ();
+
+      if (! text.empty ())
+	{
+	  printf_format_elt *elt
+	    = new printf_format_elt (text.c_str (), args, fw, prec, flags,
+				     type, modifier);
+
+	  if (num_elts == list.length ())
+	    list.resize (2 * num_elts);
+
+	  list(num_elts++) = elt;
+	}
+
+      delete buf;
+      buf = 0;
+    }
+}
+
+void
+printf_format_list::process_conversion
+  (const std::string& s, int& i, int n, int& args, std::string& flags,
+   int& fw, int& prec, char& modifier, char& type, int& num_elts)
+{
+  args = 0;
+  flags = "";
+  fw = 0;
+  prec = 0;
+  modifier = '\0';
+  type = '\0';
+
+  *buf << s[i++];
+
+  bool nxt = false;
+
+  while (i < n)
+    {
+      switch (s[i])
+	{
+	case '-': case '+': case ' ': case '0': case '#':
+	  flags += s[i];
+	  *buf << s[i++];
+	  break;
+
+	default:
+	  nxt = true;
+	  break;
+	}
+
+      if (nxt)
+	break;
+    }
+
+  if (i < n)
+    {
+      if (s[i] == '*')
+	{
+	  fw = -1;
+	  args++;
+	  *buf << s[i++];
+	}
+      else
+	{
+	  if (isdigit (s[i]))
+	    {
+	      int nn = 0;
+	      std::string tmp = s.substr (i);
+	      sscanf (tmp.c_str (), "%d%n", &fw, &nn);
+	    }
+
+	  while (i < n && isdigit (s[i]))
+	    *buf << s[i++];
+	}
+    }
+
+  if (i < n && s[i] == '.')
+    {
+      *buf << s[i++];
+
+      if (i < n)
+	{
+	  if (s[i] == '*')
+	    {
+	      prec = -1;
+	      args++;
+	      *buf << s[i++];
+	    }
+	  else
+	    {
+	      if (isdigit (s[i]))
+		{
+		  int nn = 0;
+		  std::string tmp = s.substr (i);
+		  sscanf (tmp.c_str (), "%d%n", &prec, &nn);
+		}
+
+	      while (i < n && isdigit (s[i]))
+		*buf << s[i++];
+	    }
+	}
+    }
+
+  if (i < n)
+    {
+      switch (s[i])
+	{
+	case 'h': case 'l': case 'L':
+	  modifier = s[i];
+	  *buf << s[i++];
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  if (i < n)
+    finish_conversion (s, i, args, flags, fw, prec, modifier, type, num_elts);
+  else
+    nconv = -1;
+}
+
+void
+printf_format_list::finish_conversion
+  (const std::string& s, int& i, int args, const std::string& flags,
+   int fw, int prec, char modifier, char& type, int& num_elts)
+
+{
+  switch (s[i])
+    {
+    case 'd': case 'i': case 'o': case 'x': case 'X':
+    case 'u': case 'c':
+      if (modifier == 'L')
+	{
+	  nconv = -1;
+	  break;
+	}
+      goto fini;
+
+    case 'f': case 'e': case 'E': case 'g': case 'G':
+      if (modifier == 'h' || modifier == 'l')
+	{
+	  nconv = -1;
+	  break;
+	}
+      goto fini;
+
+    case 's': case 'p': case '%':
+      if (modifier != '\0')
+	{
+	  nconv = -1;
+	  break;
+	}
+      goto fini;
+
+    fini:
+
+      type = s[i];
+
+      *buf << s[i++];
+
+      if (type != '%' || args != 0)
+	nconv++;
+
+      if (type != '%')
+	args++;
+
+      add_elt_to_list (args, flags, fw, prec, type, modifier, num_elts);
+
+      break;
+
+    default:
+      nconv = -1;
+      break;
+    }
+}
+
+void
+printf_format_list::printme (void) const
+{
+  int n = list.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      printf_format_elt *elt = list(i);
+
+      std::cerr
+	<< "args:     " << elt->args << "\n"
+	<< "flags:    `" << elt->flags << "'\n"
+	<< "width:    " << elt->fw << "\n"
+	<< "prec:     " << elt->prec << "\n"
+	<< "type:     `" << elt->type << "'\n"
+	<< "modifier: `" << elt->modifier << "'\n"
+	<< "text:     `" << undo_string_escapes (elt->text) << "'\n\n";
+    }
+}
+
+int
+octave_base_stream::file_number (void)
+{
+  // Kluge alert!
+
+  if (name () == "stdin")
+    return 0;
+
+  if (name () == "stdout")
+    return 1;
+
+  if (name () == "stderr")
+    return 2;
+
+  int retval = -1;
+
+  std::istream *is = input_stream ();
+  std::ostream *os = output_stream ();
+
+  // There is no standard way to get the underlying file descriptor from 
+  // std::filebuf (nor in the GNU libstdc++-v3 implementation). We cache
+  // the descriptor in c_file_ptr_buf, and then extract it here.
+
+  c_file_ptr_buf *ibuf
+    = is ? dynamic_cast<c_file_ptr_buf *> (is->rdbuf ()) : 0;
+
+  c_file_ptr_buf *obuf
+    = os ? dynamic_cast<c_file_ptr_buf *> (os->rdbuf ()) : 0;
+
+  int i_fid = ibuf ? ibuf->file_number () : -1;
+  int o_fid = obuf ? obuf->file_number () : -1;
+
+  if (i_fid >= 0)
+    {
+      if (o_fid >= 0)
+	retval = (i_fid == o_fid) ? i_fid : -1;
+      else
+	retval = i_fid;
+    }
+  else if (o_fid >= 0)
+    retval = o_fid;
+
+  return retval;
+}
+
+void
+octave_base_stream::error (const std::string& msg)
+{
+  fail = true;
+  errmsg = msg;
+}
+
+void
+octave_base_stream::error (const std::string& who, const std::string& msg)
+{
+  fail = true;
+  errmsg = who + ": " + msg;
+}
+
+void
+octave_base_stream::clear (void)
+{
+  fail = false;
+  errmsg = "";
+}
+
+void
+octave_base_stream::clearerr (void)
+{
+  std::istream *is = input_stream ();
+  std::ostream *os = output_stream ();
+
+  if (is)
+    is->clear ();
+
+  if (os)
+    os->clear ();
+}
+
+// Functions that are defined for all input streams (input streams
+// are those that define is).
+
+std::string
+octave_base_stream::do_gets (octave_idx_type max_len, bool& err,
+			     bool strip_newline, const std::string& who)
+{
+  std::string retval;
+
+  if ((interactive || forced_interactive) && file_number () == 0)
+    {
+      ::error ("%s: unable to read from stdin while running interactively",
+	       who.c_str ());
+	     
+      return retval;
+    }
+
+  err = false;
+
+  std::istream *isp = input_stream ();
+
+  if (isp)
+    {
+      std::istream& is = *isp;
+
+      std::ostringstream buf;
+
+      int c = 0;
+      int char_count = 0;
+
+      if (max_len != 0)
+	{
+	  while (is && (c = is.get ()) != EOF)
+	    {
+	      char_count++;
+
+	      // Handle CRLF, CR, or LF as line ending.
+
+	      if (c == '\r')
+		{
+		  if (! strip_newline)
+		    buf << static_cast<char> (c);
+
+		  c = is.get ();
+
+		  if (c != EOF)
+		    {
+		      if (c == '\n')
+			{
+			  char_count++;
+
+			  if (! strip_newline)
+			    buf << static_cast<char> (c);
+			}
+		      else
+			is.putback (c);
+		    }
+
+		  break;
+		}
+	      else if (c == '\n')
+		{
+		  if (! strip_newline)
+		    buf << static_cast<char> (c);
+
+		  break;
+		}
+	      else
+		buf << static_cast<char> (c);
+
+	      if (max_len > 0 && char_count == max_len)
+		break;
+	    }
+	}
+
+      if (! is.eof () && char_count > 0)
+	{
+	  // GAGME.  Matlab seems to check for EOF even if the last
+	  // character in a file is a newline character.  This is NOT
+	  // what the corresponding C-library functions do.
+	  int disgusting_compatibility_hack = is.get ();
+	  if (! is.eof ())
+	    is.putback (disgusting_compatibility_hack);
+	}
+
+      if (is.good () || (is.eof () && char_count > 0))
+	retval = buf.str ();
+      else
+	{
+	  err = true;
+
+	  if (is.eof () && char_count == 0)
+	    error (who, "at end of file");
+	  else
+	    error (who, "read error");
+	}
+    }
+  else
+    {
+      err = true;
+      invalid_operation (who, "reading");
+    }
+
+  return retval;
+}
+
+std::string
+octave_base_stream::getl (octave_idx_type max_len, bool& err, const std::string& who)
+{
+  return do_gets (max_len, err, true, who);
+}
+
+std::string
+octave_base_stream::gets (octave_idx_type max_len, bool& err, const std::string& who)
+{
+  return do_gets (max_len, err, false, who);
+}
+
+#define OCTAVE_SCAN(is, fmt, arg) octave_scan (is, fmt, arg)
+
+template <class T>
+std::istream&
+octave_scan_1 (std::istream& is, const scanf_format_elt& fmt, T* valptr)
+{
+  T& ref = *valptr;
+
+  switch (fmt.type)
+    {
+    case 'o':
+      is >> std::oct >> ref >> std::dec;
+      break;
+
+    case 'x':
+      is >> std::hex >> ref >> std::dec;
+      break;
+
+    case 'i':
+      {
+	int c1 = is.get ();
+
+	if (! is.eof ())
+	  {
+	    if (c1 == '0')
+	      {
+		int c2 = is.peek ();
+
+		if (c2 == 'x' || c2 == 'X')
+                  {
+                    is.ignore ();
+                    if (std::isxdigit (is.peek ()))
+                      is >> std::hex >> ref >> std::dec;
+                    else
+                      ref = 0;
+                  }
+		else
+		  {
+		    if (c2 == '0' || c2 == '1' || c2 == '2'
+			|| c2 == '3' || c2 == '4' || c2 == '5'
+			|| c2 == '6' || c2 == '7')
+		      is >> std::oct >> ref >> std::dec;
+		    else
+		      ref = 0;
+		  }
+	      }
+	    else
+	      {
+		is.putback (c1);
+
+		is >> ref;
+	      }
+	  }
+      }
+      break;
+
+    default:
+      is >> ref;
+      break;
+    }
+
+  return is;
+}
+
+template <class T>
+std::istream&
+octave_scan (std::istream& is, const scanf_format_elt& fmt, T* valptr)
+{
+  if (fmt.width)
+    {
+      // Limit input to fmt.width characters by reading into a
+      // temporary stringstream buffer.
+
+      std::string tmp;
+
+      is.width (fmt.width);
+      is >> tmp;
+
+      std::istringstream ss (tmp);
+
+      octave_scan_1 (ss, fmt, valptr);
+    }
+  else
+    octave_scan_1 (is, fmt, valptr);
+
+  return is;
+}
+
+// Note that this specialization is only used for reading characters, not 
+// character strings. See BEGIN_S_CONVERSION for details.
+
+template<>
+std::istream&
+octave_scan<> (std::istream& is, const scanf_format_elt& /* fmt */,
+	       char* valptr)
+{
+  return is >> valptr;
+}
+
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, int*);
+
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, long int*);
+
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, short int*);
+
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, unsigned int*);
+
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, unsigned long int*);
+
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, unsigned short int*);
+
+#if 0
+template std::istream&
+octave_scan (std::istream&, const scanf_format_elt&, float*);
+#endif
+
+template<>
+std::istream&
+octave_scan<> (std::istream& is, const scanf_format_elt& fmt, double* valptr)
+{
+  double& ref = *valptr;
+
+  switch (fmt.type)
+    {
+    case 'e':
+    case 'f':
+    case 'g':
+      {
+	int c1 = EOF;
+
+	while (is && (c1 = is.get ()) != EOF && isspace (c1))
+	  /* skip whitespace */;
+
+	if (c1 != EOF)
+	  {
+	    if (c1 == 'N')
+	      {
+		int c2 = is.get ();
+
+		if (c2 != EOF)
+		  {
+		    if (c2 == 'A')
+		      {
+			int c3 = is.get ();
+
+			if (c3 != EOF)
+			  {
+			    is.putback (c3);
+
+			    if (isspace (c3) || ispunct (c3))
+			      ref = octave_NA;
+			    else
+			      {
+				is.putback (c2);
+				is.putback (c1);
+
+				is >> ref;
+			      }
+			  }
+			else
+			  {
+			    is.clear ();
+
+			    ref = octave_NA;
+			  }
+		      }
+		    else if (c2 == 'a')
+		      {
+			int c3 = is.get ();
+
+			if (c3 != EOF)
+			  {
+			    if (c3 == 'N')
+			      {
+				int c4 = is.get ();
+
+				if (c4 != EOF)
+				  {
+				    is.putback (c4);
+
+				    if (isspace (c4) || ispunct (c4))
+				      ref = octave_NaN;
+				    else
+				      {
+					is.putback (c3);
+					is.putback (c2);
+					is.putback (c1);
+
+					is >> ref;
+				      }
+				  }
+				else
+				  {
+				    is.clear ();
+
+				    ref = octave_NaN;
+				  }
+			      }
+			    else
+			      {
+				is.putback (c3);
+				is.putback (c2);
+				is.putback (c1);
+
+				is >> ref;
+			      }
+			  }
+		      }
+		    else
+		      {
+			is.putback (c2);
+			is.putback (c1);
+
+			is >> ref;
+		      }
+		  }
+	      }
+	    else if (c1 == 'I')
+	      {
+		int c2 = is.get ();
+
+		if (c2 != EOF)
+		  {
+		    if (c2 == 'n')
+		      {
+			int c3 = is.get ();
+
+			if (c3 != EOF)
+			  {
+			    if (c3 == 'f')
+			      {
+				int c4 = is.get ();
+
+				if (c4 != EOF)
+				  {
+				    is.putback (c4);
+
+				    if (isspace (c4) || ispunct (c4))
+				      ref = octave_Inf;
+				    else
+				      {
+					is.putback (c3);
+					is.putback (c2);
+					is.putback (c1);
+
+					is >> ref;
+				      }
+				  }
+				else
+				  {
+				    is.clear ();
+
+				    ref = octave_Inf;
+				  }
+			      }
+			    else
+			      {
+				is.putback (c3);
+				is.putback (c2);
+				is.putback (c1);
+
+				is >> ref;
+			      }
+			}
+		      else
+			{
+			  is.putback (c2);
+			  is.putback (c1);
+
+			  is >> ref;
+			}
+		      }
+		  }
+	      }
+	    else
+	      {
+		is.putback (c1);
+
+		is >> ref;
+	      }
+	  }
+      }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return is;
+}
+
+template <class T>
+void
+do_scanf_conv (std::istream& is, const scanf_format_elt& fmt,
+	       T valptr, Matrix& mval, double *data, octave_idx_type& idx,
+	       octave_idx_type& conversion_count, octave_idx_type nr, octave_idx_type max_size,
+	       bool discard) 
+{
+  OCTAVE_SCAN (is, fmt, valptr);
+
+  if (is)
+    {
+      if (idx == max_size && ! discard)
+	{
+	  max_size *= 2;
+
+	  if (nr > 0)
+	    mval.resize (nr, max_size / nr, 0.0);
+	  else
+	    mval.resize (max_size, 1, 0.0);
+
+	  data = mval.fortran_vec ();
+	}
+
+      if (! discard)
+	{
+	  conversion_count++;
+	  data[idx++] = *(valptr);
+	}
+    }
+}
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, int*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, long int*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, short int*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned int*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned long int*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned short int*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+#if 0
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, float*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+#endif
+
+template void
+do_scanf_conv (std::istream&, const scanf_format_elt&, double*,
+	       Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
+
+#define DO_WHITESPACE_CONVERSION() \
+  do \
+    { \
+      int c = EOF; \
+ \
+      while (is && (c = is.get ()) != EOF && isspace (c)) \
+	/* skip whitespace */; \
+ \
+      if (c != EOF) \
+	is.putback (c); \
+    } \
+  while (0)
+
+#define DO_LITERAL_CONVERSION() \
+  do \
+    { \
+      int c = EOF; \
+ \
+      int n = strlen (fmt); \
+      int i = 0; \
+ \
+      while (i < n && is && (c = is.get ()) != EOF) \
+	{ \
+	  if (c == static_cast<unsigned char> (fmt[i])) \
+	    { \
+	      i++; \
+	      continue; \
+	    } \
+	  else \
+	    { \
+	      is.putback (c); \
+	      break; \
+	    } \
+	} \
+ \
+      if (i != n) \
+	is.setstate (std::ios::failbit); \
+    } \
+  while (0)
+
+#define DO_PCT_CONVERSION() \
+  do \
+    { \
+      int c = is.get (); \
+ \
+      if (c != EOF) \
+	{ \
+	  if (c != '%') \
+	    { \
+	      is.putback (c); \
+	      is.setstate (std::ios::failbit); \
+	    } \
+	} \
+      else \
+	is.setstate (std::ios::failbit); \
+    } \
+  while (0)
+
+#define BEGIN_C_CONVERSION() \
+  is.unsetf (std::ios::skipws); \
+ \
+  int width = elt->width ? elt->width : 1; \
+ \
+  char *tbuf = new char[width + 1]; \
+ \
+  int c = EOF; \
+  int n = 0; \
+ \
+  while (is && n < width && (c = is.get ()) != EOF) \
+    tbuf[n++] = static_cast<char> (c);		    \
+ \
+  tbuf[n] = '\0'; \
+ \
+  if (n > 0 && c == EOF) \
+    is.clear (); \
+ \
+  std::string tmp = tbuf; \
+ \
+  delete [] tbuf
+
+// For a `%s' format, skip initial whitespace and then read until the
+// next whitespace character or until WIDTH characters have been read.
+#define BEGIN_S_CONVERSION() \
+  int width = elt->width; \
+ \
+  std::string tmp; \
+ \
+  do \
+    { \
+      if (width) \
+        { \
+          char *tbuf = new char [width+1]; \
+ \
+          int c = EOF; \
+ \
+          int n = 0; \
+ \
+          while (is && (c = is.get ()) != EOF) \
+            { \
+              if (! isspace (c)) \
+                { \
+                  tbuf[n++] = static_cast<char> (c); \
+                  break; \
+                } \
+            } \
+ \
+          while (is && n < width && (c = is.get ()) != EOF) \
+            { \
+              if (isspace (c)) \
+                { \
+                  is.putback (c); \
+                  break; \
+                } \
+              else \
+                tbuf[n++] = static_cast<char> (c); \
+            } \
+ \
+          tbuf[n] = '\0'; \
+ \
+          if (n > 0 && c == EOF) \
+            is.clear (); \
+ \
+          tmp = tbuf; \
+ \
+          delete [] tbuf; \
+        } \
+      else \
+        { \
+          is >> std::ws >> tmp; \
+        } \
+    } \
+  while (0)
+
+// This format must match a nonempty sequence of characters.
+#define BEGIN_CHAR_CLASS_CONVERSION() \
+  int width = elt->width; \
+ \
+  std::string tmp; \
+ \
+  do \
+    { \
+      if (! width) \
+	width = INT_MAX; \
+ \
+      std::ostringstream buf; \
+ \
+      std::string char_class = elt->char_class; \
+ \
+      int c = EOF; \
+ \
+      if (elt->type == '[') \
+        { \
+	  int chars_read = 0; \
+	  while (is && chars_read++ < width && (c = is.get ()) != EOF \
+	         && char_class.find (c) != std::string::npos) \
+	    buf << static_cast<char> (c); \
+	} \
+      else \
+	{ \
+	  int chars_read = 0; \
+	  while (is && chars_read++ < width && (c = is.get ()) != EOF \
+	         && char_class.find (c) == std::string::npos) \
+	    buf << static_cast<char> (c); \
+	} \
+ \
+      if (width == INT_MAX && c != EOF) \
+	is.putback (c); \
+ \
+      tmp = buf.str (); \
+ \
+      if (tmp.empty ()) \
+        is.setstate (std::ios::failbit); \
+    } \
+  while (0)
+
+#define FINISH_CHARACTER_CONVERSION() \
+  do \
+    { \
+      width = tmp.length (); \
+ \
+      if (is) \
+	{ \
+	  int i = 0; \
+ \
+	  if (! discard) \
+	    { \
+	      conversion_count++; \
+ \
+	      while (i < width && tmp[i] != '\0') \
+		{ \
+		  if (data_index == max_size) \
+		    { \
+		      max_size *= 2; \
+ \
+		      if (all_char_conv) \
+			{ \
+			  if (one_elt_size_spec) \
+			    mval.resize (1, max_size, 0.0); \
+			  else if (nr > 0) \
+			    mval.resize (nr, max_size / nr, 0.0); \
+			  else \
+			    panic_impossible (); \
+			} \
+		      else if (nr > 0) \
+			mval.resize (nr, max_size / nr, 0.0); \
+		      else \
+			mval.resize (max_size, 1, 0.0); \
+ \
+		      data = mval.fortran_vec (); \
+		    } \
+ \
+		  data[data_index++] = tmp[i++]; \
+		} \
+	    } \
+	} \
+    } \
+  while (0)
+
+octave_value
+octave_base_stream::do_scanf (scanf_format_list& fmt_list,
+			      octave_idx_type nr, octave_idx_type nc, bool one_elt_size_spec,
+			      octave_idx_type& conversion_count, const std::string& who)
+{
+  octave_value retval = Matrix ();
+
+  if ((interactive || forced_interactive) && file_number () == 0)
+    {
+      ::error ("%s: unable to read from stdin while running interactively",
+	       who.c_str ());
+	     
+      return retval;
+    }
+
+  conversion_count = 0;
+
+  int nconv = fmt_list.num_conversions ();
+
+  octave_idx_type data_index = 0;
+
+  if (nr == 0 || nc == 0)
+    {
+      if (one_elt_size_spec)
+	nc = 0;
+
+      return Matrix (nr, nc, 0.0);
+    }
+
+  std::istream *isp = input_stream ();
+
+  bool all_char_conv = fmt_list.all_character_conversions ();
+
+  Matrix mval;
+  double *data = 0;
+  octave_idx_type max_size = 0;
+  octave_idx_type max_conv = 0;
+
+  octave_idx_type final_nr = 0;
+  octave_idx_type final_nc = 0;
+
+  if (all_char_conv)
+    {
+      // Any of these could be resized later (if we have %s
+      // conversions, we may read more than one element for each
+      // conversion).
+
+      if (one_elt_size_spec)
+	{
+	  max_size = 512;
+	  mval.resize (1, max_size, 0.0);
+
+	  if (nr > 0)
+	    max_conv = nr;
+	}
+      else if (nr > 0)
+	{
+	  if (nc > 0)
+	    {
+	      mval.resize (nr, nc, 0.0);
+	      max_size = max_conv = nr * nc;
+	    }
+	  else
+	    {
+	      mval.resize (nr, 32, 0.0);
+	      max_size = nr * 32;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else if (nr > 0)
+    {
+      if (nc > 0)
+	{
+	  // Will not resize later.
+	  mval.resize (nr, nc, 0.0);
+	  max_size = nr * nc;
+	  max_conv = max_size;
+	}
+      else
+	{
+	  // Maybe resize later.
+	  mval.resize (nr, 32, 0.0);
+	  max_size = nr * 32;
+	}
+    }
+  else
+    {
+      // Maybe resize later.
+      mval.resize (32, 1, 0.0);
+      max_size = 32;
+    }
+
+  data = mval.fortran_vec ();
+
+  if (isp)
+    {
+      std::istream& is = *isp;
+
+      const scanf_format_elt *elt = fmt_list.first ();
+
+      std::ios::fmtflags flags = is.flags ();
+
+      for (;;)
+	{
+	  OCTAVE_QUIT;
+
+	  if (elt)
+	    {
+	      if (max_conv > 0 && conversion_count == max_conv)
+		{
+		  if (all_char_conv && one_elt_size_spec)
+		    {
+		      final_nr = 1;
+		      final_nc = data_index;
+		    }
+		  else
+		    {
+		      final_nr = nr;
+		      final_nc = (data_index - 1) / nr + 1;
+		    }
+
+		  break;
+		}
+	      else if (data_index == max_size)
+		{
+		  max_size *= 2;
+
+		  if (all_char_conv)
+		    {
+		      if (one_elt_size_spec)
+			mval.resize (1, max_size, 0.0);
+		      else if (nr > 0)
+			mval.resize (nr, max_size / nr, 0.0);
+		      else
+			panic_impossible ();
+		    }
+		  else if (nr > 0)
+		    mval.resize (nr, max_size / nr, 0.0);
+		  else
+		    mval.resize (max_size, 1, 0.0);
+
+		  data = mval.fortran_vec ();
+		}
+
+	      const char *fmt = elt->text;
+
+	      bool discard = elt->discard;
+
+	      switch (elt->type)
+		{
+		case scanf_format_elt::whitespace_conversion:
+		  DO_WHITESPACE_CONVERSION ();
+		  break;
+
+		case scanf_format_elt::literal_conversion:
+		  DO_LITERAL_CONVERSION ();
+		  break;
+
+		case '%':
+		  DO_PCT_CONVERSION ();
+		  break;
+
+		case 'd': case 'i':
+		  {
+		    switch (elt->modifier)
+		      {
+		      case 'h':
+			{
+			  short int tmp;
+			  do_scanf_conv (is, *elt, &tmp, mval, data,
+					 data_index, conversion_count,
+					 nr, max_size, discard);
+			}
+			break;
+
+		      case 'l':
+			{
+			  long int tmp;
+			  do_scanf_conv (is, *elt, &tmp, mval, data,
+					 data_index, conversion_count,
+					 nr, max_size, discard);
+			}
+			break;
+
+		      default:
+			{
+			  int tmp;
+			  do_scanf_conv (is, *elt, &tmp, mval, data,
+					 data_index, conversion_count,
+					 nr, max_size, discard);
+			}
+			break;
+		      }
+		  }
+		  break;
+
+		case 'o': case 'u': case 'x':
+		  {
+		    switch (elt->modifier)
+		      {
+		      case 'h':
+			{
+			  unsigned short int tmp;
+			  do_scanf_conv (is, *elt, &tmp, mval, data,
+					 data_index, conversion_count,
+					 nr, max_size, discard);
+			}
+			break;
+
+		      case 'l':
+			{
+			  unsigned long int tmp;
+			  do_scanf_conv (is, *elt, &tmp, mval, data,
+					 data_index, conversion_count,
+					 nr, max_size, discard);
+			}
+			break;
+
+		      default:
+			{
+			  unsigned int tmp;
+			  do_scanf_conv (is, *elt, &tmp, mval, data,
+					 data_index, conversion_count,
+					 nr, max_size, discard);
+			}
+			break;
+		      }
+		  }
+		  break;
+
+		case 'e': case 'f': case 'g':
+		  {
+		    double tmp;
+
+		    do_scanf_conv (is, *elt, &tmp, mval, data,
+				   data_index, conversion_count,
+				   nr, max_size, discard);
+		  }
+		  break;
+
+		case 'c':
+		  {
+		    BEGIN_C_CONVERSION ();
+
+		    FINISH_CHARACTER_CONVERSION ();
+
+		    is.setf (flags);
+		  }
+		  break;
+
+		case 's':
+		  {
+		    BEGIN_S_CONVERSION ();
+
+		    FINISH_CHARACTER_CONVERSION ();
+		  }
+		  break;
+
+		case '[': case '^':
+		  {
+		    BEGIN_CHAR_CLASS_CONVERSION ();
+
+		    FINISH_CHARACTER_CONVERSION ();
+		  }
+		  break;
+
+		case 'p':
+		  error ("%s: unsupported format specifier", who.c_str ());
+		  break;
+
+		default:
+		  error ("%s: internal format error", who.c_str ());
+		  break;
+		}
+
+	      if (! ok ())
+		{
+		  break;
+		}
+	      else if (! is)
+		{
+		  if (all_char_conv)
+		    {
+		      if (one_elt_size_spec)
+			{
+			  final_nr = 1;
+			  final_nc = data_index;
+			}
+		      else if (data_index > nr)
+			{
+			  final_nr = nr;
+			  final_nc = (data_index - 1) / nr + 1;
+			}
+		      else
+			{
+			  final_nr = data_index;
+			  final_nc = 1;
+			}
+		    }
+		  else if (nr > 0)
+		    {
+		      if (data_index > nr)
+			{
+			  final_nr = nr;
+			  final_nc = (data_index - 1) / nr + 1;
+			}
+		      else
+			{
+			  final_nr = data_index;
+			  final_nc = 1;
+			}
+		    }
+		  else
+		    {
+		      final_nr = data_index;
+		      final_nc = 1;
+		    }
+
+		  // If it looks like we have a matching failure, then
+		  // reset the failbit in the stream state.
+
+		  if (is.rdstate () & std::ios::failbit)
+		    is.clear (is.rdstate () & (~std::ios::failbit));
+
+		  // FIXME -- is this the right thing to do?
+
+		  if (interactive && name () == "stdin")
+		    {
+		      is.clear ();
+
+		      // Skip to end of line.
+
+		      bool err;
+		      do_gets (-1, err, false, who);
+		    }
+
+		  break;
+		}
+	    }
+	  else
+	    {
+	      error ("%s: internal format error", who.c_str ());
+	      break;
+	    }
+
+	  elt = fmt_list.next (nconv > 0);
+	}
+    }
+
+  if (ok ())
+    {
+      mval.resize (final_nr, final_nc, 0.0);
+
+      retval = mval;
+
+      if (all_char_conv)
+	retval = retval.convert_to_str (false, true);
+    }
+
+  return retval;
+}
+
+octave_value
+octave_base_stream::scanf (const std::string& fmt, const Array<double>& size,
+			   octave_idx_type& conversion_count, const std::string& who)
+{
+  octave_value retval = Matrix ();
+
+  conversion_count = 0;
+
+  std::istream *isp = input_stream ();
+
+  if (isp)
+    {
+      scanf_format_list fmt_list (fmt);
+
+      if (fmt_list.num_conversions () == -1)
+	::error ("%s: invalid format specified", who.c_str ());
+      else
+	{
+	octave_idx_type nr = -1;
+	octave_idx_type nc = -1;
+
+	bool one_elt_size_spec;
+
+	get_size (size, nr, nc, one_elt_size_spec, who);
+
+	if (! error_state)
+	  retval = do_scanf (fmt_list, nr, nc, one_elt_size_spec,
+			     conversion_count, who);
+	}
+    }
+  else
+    invalid_operation (who, "reading");
+
+  return retval;
+}
+
+bool
+octave_base_stream::do_oscanf (const scanf_format_elt *elt,
+			       octave_value& retval, const std::string& who)
+{
+  bool quit = false;
+
+  std::istream *isp = input_stream ();
+
+  if (isp)
+    {
+      std::istream& is = *isp;
+
+      std::ios::fmtflags flags = is.flags ();
+
+      if (elt)
+	{
+	  const char *fmt = elt->text;
+
+	  bool discard = elt->discard;
+
+	  switch (elt->type)
+	    {
+	    case scanf_format_elt::whitespace_conversion:
+	      DO_WHITESPACE_CONVERSION ();
+	      break;
+
+	    case scanf_format_elt::literal_conversion:
+	      DO_LITERAL_CONVERSION ();
+	      break;
+
+	    case '%':
+	      {
+		DO_PCT_CONVERSION ();
+
+		if (! is)
+		  quit = true;
+
+	      }
+	      break;
+
+	    case 'd': case 'i':
+	      {
+		int tmp;
+
+		if (OCTAVE_SCAN (is, *elt, &tmp))
+		  {
+		    if (! discard)
+		      retval = tmp;
+		  }
+		else
+		  quit = true;
+	      }
+	      break;
+
+	    case 'o': case 'u': case 'x':
+	      {
+		long int tmp;
+
+		if (OCTAVE_SCAN (is, *elt, &tmp))
+		  {
+		    if (! discard)
+		      retval = tmp;
+		  }
+		else
+		  quit = true;
+	      }
+	      break;
+
+	    case 'e': case 'f': case 'g':
+	      {
+		double tmp;
+
+		if (OCTAVE_SCAN (is, *elt, &tmp))
+		  {
+		    if (! discard)
+		      retval = tmp;
+		  }
+		else
+		  quit = true;
+	      }
+	      break;
+
+	    case 'c':
+	      {
+		BEGIN_C_CONVERSION ();
+
+		if (! discard)
+		  retval = tmp;
+
+		if (! is)
+		  quit = true;
+
+		is.setf (flags);
+	      }
+	      break;
+
+	    case 's':
+	      {
+		BEGIN_S_CONVERSION ();
+
+		if (! discard)
+		  retval = tmp;
+
+		if (! is)
+		  quit = true;
+	      }
+	      break;
+
+	    case '[': case '^':
+	      {
+		BEGIN_CHAR_CLASS_CONVERSION ();
+
+		if (! discard)
+		  retval = tmp;
+
+		if (! is)
+		  quit = true;
+	      }
+	      break;
+
+	    case 'p':
+	      error ("%s: unsupported format specifier", who.c_str ());
+	      break;
+
+	    default:
+	      error ("%s: internal format error", who.c_str ());
+	      break;
+	    }
+	}
+
+      if (ok () && is.fail ())
+	{
+	  error ("%s: read error", who.c_str ());
+
+	  // FIXME -- is this the right thing to do?
+
+	  if (interactive && name () == "stdin")
+	    {
+	      // Skip to end of line.
+
+	      bool err;
+	      do_gets (-1, err, false, who);
+	    }
+	}
+    }
+
+  return quit;
+}
+
+octave_value_list
+octave_base_stream::oscanf (const std::string& fmt, const std::string& who)
+{
+  octave_value_list retval;
+
+  std::istream *isp = input_stream ();
+
+  if (isp)
+    {
+      std::istream& is = *isp;
+
+      scanf_format_list fmt_list (fmt);
+
+      int nconv = fmt_list.num_conversions ();
+
+      if (nconv == -1)
+	::error ("%s: invalid format specified", who.c_str ());
+      else
+	{
+	  is.clear ();
+
+	  int len = fmt_list.length ();
+
+	  retval.resize (nconv+1, Matrix ());
+
+	  const scanf_format_elt *elt = fmt_list.first ();
+
+	  int num_values = 0;
+
+	  bool quit = false;
+
+	  for (octave_idx_type i = 0; i < len; i++)
+	    {
+	      octave_value tmp;
+
+	      quit = do_oscanf (elt, tmp, who);
+
+	      if (quit)
+		break;
+	      else
+		{
+		  if (tmp.is_defined ())
+		    retval (num_values++) = tmp;
+
+		  if (! ok ())
+		    break;
+
+		  elt = fmt_list.next (nconv > 0);
+		}
+	    }
+
+	  retval(nconv) = num_values;
+
+	  if (! quit)
+	    {
+	      // Pick up any trailing stuff.
+	      if (ok () && len > nconv)
+		{
+		  octave_value tmp;
+
+		  elt = fmt_list.next ();
+
+		  do_oscanf (elt, tmp, who);
+		}
+	    }
+	}
+    }
+  else
+    invalid_operation (who, "reading");
+
+  return retval;
+}
+
+// Functions that are defined for all output streams (output streams
+// are those that define os).
+
+int
+octave_base_stream::flush (void)
+{
+  int retval = -1;
+
+  std::ostream *os = output_stream ();
+
+  if (os)
+    {
+      os->flush ();
+
+      if (os->good ())
+	retval = 0;
+    }
+  else
+    invalid_operation ("fflush", "writing");
+
+  return retval;
+}
+
+class
+printf_value_cache
+{
+public:
+
+  enum state { ok, conversion_error };
+
+  printf_value_cache (const octave_value_list& args, const std::string& who)
+    : values (args), val_idx (0), elt_idx (0),
+      n_vals (values.length ()), n_elts (0), data (0),
+      curr_state (ok)
+  {
+    for (octave_idx_type i = 0; i < values.length (); i++)
+      {
+	octave_value val = values(i);
+
+	if (val.is_map () || val.is_cell () || val.is_object ()
+	    || val.is_list ())
+	  {
+	    gripe_wrong_type_arg (who, val);
+	    break;
+	  }
+      }
+  }
+
+  ~printf_value_cache (void) { }
+
+  // Get the current value as a double and advance the internal pointer.
+  double double_value (void);
+
+  // Get the current value as an int and advance the internal pointer.
+  int int_value (void);
+
+  // Get the current value as a string and advance the internal pointer.
+  std::string string_value (void);
+
+  operator bool () const { return (curr_state == ok); }
+
+  bool exhausted (void) { return (val_idx >= n_vals); }
+
+private:
+
+  const octave_value_list values;
+  int val_idx;
+  int elt_idx;
+  int n_vals;
+  int n_elts;
+  const double *data;
+  NDArray curr_val;
+  state curr_state;
+
+  // Must create value cache with values!
+
+  printf_value_cache (void);
+
+  // No copying!
+
+  printf_value_cache (const printf_value_cache&);
+
+  printf_value_cache& operator = (const printf_value_cache&);
+};
+
+double
+printf_value_cache::double_value (void)
+{
+  double retval = 0.0;
+
+  if (exhausted ())
+    curr_state = conversion_error;
+
+  while (! exhausted ())
+    {
+      if (! data)
+	{
+	  octave_value tmp_val = values (val_idx);
+
+	  // Force string conversion here for compatibility.
+
+	  curr_val = tmp_val.array_value (true);
+
+	  if (! error_state)
+	    {
+	      elt_idx = 0;
+	      n_elts = curr_val.length ();
+	      data = curr_val.data ();
+	    }
+	  else
+	    {
+	      curr_state = conversion_error;
+	      break;
+	    }
+	}
+
+      if (elt_idx < n_elts)
+	{
+	  retval = data[elt_idx++];
+
+	  if (elt_idx >= n_elts)
+	    {
+	      elt_idx = 0;
+	      val_idx++;
+	      data = 0;
+	    }
+
+	  break;
+	}
+      else
+	{
+	  val_idx++;
+	  data = 0;
+
+	  if (n_elts == 0 && exhausted ())
+	    curr_state = conversion_error;
+
+	  continue;
+	}
+    }
+
+  return retval;
+}
+
+int
+printf_value_cache::int_value (void)
+{
+  int retval = 0;
+
+  double dval = double_value ();
+
+  if (! error_state)
+    {
+      if (D_NINT (dval) == dval)
+	retval = NINT (dval);
+      else
+	curr_state = conversion_error;
+    }
+
+  return retval;
+}
+
+std::string
+printf_value_cache::string_value (void)
+{
+  std::string retval;
+
+  if (exhausted ())
+    curr_state = conversion_error;
+  else
+    {
+      octave_value tval = values (val_idx++);
+
+      if (tval.rows () == 1)
+	retval = tval.string_value ();
+      else
+	{
+	  // In the name of Matlab compatibility.
+
+	  charMatrix chm = tval.char_matrix_value ();
+
+	  octave_idx_type nr = chm.rows ();
+	  octave_idx_type nc = chm.columns ();
+
+	  int k = 0;
+
+	  retval.resize (nr * nc, '\0');
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = 0; i < nr; i++)
+	      retval[k++] = chm(i,j);
+	}
+
+      if (error_state)
+	curr_state = conversion_error;
+    }
+
+  return retval;
+}
+
+// Ugh again and again.
+
+template <class T>
+int
+do_printf_conv (std::ostream& os, const char *fmt, int nsa, int sa_1,
+		int sa_2, T arg, const std::string& who)
+{
+  int retval = 0;
+
+  switch (nsa)
+    {
+    case 2:
+      retval = octave_format (os, fmt, sa_1, sa_2, arg);
+      break;
+
+    case 1:
+      retval = octave_format (os, fmt, sa_1, arg);
+      break;
+
+    case 0:
+      retval = octave_format (os, fmt, arg);
+      break;
+
+    default:
+      ::error ("%s: internal error handling format", who.c_str ());
+      break;
+    }
+
+  return retval;
+}
+
+template int
+do_printf_conv (std::ostream&, const char*, int, int, int, int,
+		const std::string&);
+
+template int
+do_printf_conv (std::ostream&, const char*, int, int, int, long,
+		const std::string&);
+
+template int
+do_printf_conv (std::ostream&, const char*, int, int, int, unsigned int,
+		const std::string&);
+
+template int
+do_printf_conv (std::ostream&, const char*, int, int, int, unsigned long,
+		const std::string&);
+
+template int
+do_printf_conv (std::ostream&, const char*, int, int, int, double,
+		const std::string&);
+
+template int
+do_printf_conv (std::ostream&, const char*, int, int, int, const char*,
+		const std::string&);
+
+#define DO_DOUBLE_CONV(TQUAL) \
+  do \
+    { \
+      if (val > std::numeric_limits<TQUAL long>::max () \
+	  || val < std::numeric_limits<TQUAL long>::min ()) \
+	{ \
+	  std::string tfmt = fmt; \
+ \
+	  tfmt.replace (tfmt.rfind (elt->type), 1, ".f"); \
+ \
+	  if (elt->modifier == 'l') \
+	    tfmt.replace (tfmt.rfind (elt->modifier), 1, ""); \
+ \
+	  retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, \
+				    val, who); \
+	} \
+      else \
+	retval += do_printf_conv (os, fmt, nsa, sa_1, sa_2, \
+				  static_cast<TQUAL long> (val), who); \
+    } \
+  while (0)
+
+int
+octave_base_stream::do_printf (printf_format_list& fmt_list,
+			       const octave_value_list& args,
+			       const std::string& who)
+{
+  int retval = 0;
+
+  int nconv = fmt_list.num_conversions ();
+
+  std::ostream *osp = output_stream ();
+
+  if (osp)
+    {
+      std::ostream& os = *osp;
+
+      const printf_format_elt *elt = fmt_list.first ();
+
+      printf_value_cache val_cache (args, who);
+
+      if (error_state)
+	return retval;
+
+      for (;;)
+	{
+	  OCTAVE_QUIT;
+
+	  if (elt)
+	    {
+	      // NSA is the number of `star' args to convert.
+
+	      int nsa = (elt->fw < 0) + (elt->prec < 0);
+
+	      int sa_1 = 0;
+	      int sa_2 = 0; 
+
+	      if (nsa > 0)
+		{
+		  sa_1 = val_cache.int_value ();
+
+		  if (! val_cache)
+		    break;
+		  else
+		    {
+		      if (nsa > 1)
+			{
+			  sa_2 = val_cache.int_value ();
+
+			  if (! val_cache)
+			    break;
+			}
+		    }
+		}
+
+	      const char *fmt = elt->text;
+
+	      if (elt->type == '%')
+		{
+		  os << "%";
+		  retval++;
+		}
+	      else if (elt->args == 0 && elt->text)
+		{
+		  os << elt->text;
+		  retval += strlen (elt->text);
+		}	      
+	      else if (elt->type == 's')
+		{
+		  std::string val = val_cache.string_value ();
+
+		  if (val_cache)
+		    retval += do_printf_conv (os, fmt, nsa, sa_1,
+					      sa_2, val.c_str (), who);
+		  else
+		    break;
+		}
+	      else
+		{
+		  double val = val_cache.double_value ();
+
+		  if (val_cache)
+		    {
+		      if (lo_ieee_isnan (val) || xisinf (val))
+			{
+			  std::string tfmt = fmt;
+			  std::string::size_type i1, i2;
+
+			  tfmt.replace ((i1 = tfmt.rfind (elt->type)),
+					1, 1, 's');
+
+			  if ((i2 = tfmt.rfind ('.')) != std::string::npos && i2 < i1)
+			    {
+			      tfmt.erase (i2, i1-i2);
+			      if (elt->prec < 0)
+				nsa--;
+			    }
+
+			  const char *tval = xisinf (val)
+			    ? (val < 0 ? "-Inf" : "Inf")
+			    : (lo_ieee_is_NA (val) ? "NA" : "NaN");
+
+			  retval += do_printf_conv (os, tfmt.c_str (),
+						    nsa, sa_1, sa_2,
+						    tval, who);
+			}
+		      else
+			{
+			  char type = elt->type;
+
+			  switch (type)
+			    {
+			    case 'd': case 'i': case 'c':
+			      DO_DOUBLE_CONV (OCTAVE_EMPTY_CPP_ARG);
+			      break;
+
+			    case 'o': case 'x': case 'X': case 'u':
+			      DO_DOUBLE_CONV (unsigned);
+			      break;
+
+			    case 'f': case 'e': case 'E':
+			    case 'g': case 'G':
+			      retval
+				+= do_printf_conv (os, fmt, nsa, sa_1, sa_2,
+						   val, who);
+			      break;
+
+			    default:
+			      error ("%s: invalid format specifier",
+				     who.c_str ());
+			      return -1;
+			      break;
+			    }
+			}
+		    }
+		  else
+		    break;
+		}
+
+	      if (! os)
+		{
+		  error ("%s: write error", who.c_str ());
+		  break;
+		}
+	    }
+	  else
+	    {
+	      ::error ("%s: internal error handling format", who.c_str ());
+	      retval = -1;
+	      break;
+	    }
+
+	  elt = fmt_list.next (nconv > 0 && ! val_cache.exhausted ());
+
+	  if (! elt || (val_cache.exhausted () && elt->args > 0))
+	    break;
+	}	      
+    }
+  else
+    invalid_operation (who, "writing");
+
+  return retval;
+}
+
+int
+octave_base_stream::printf (const std::string& fmt,
+			    const octave_value_list& args,
+			    const std::string& who)
+{
+  int retval = 0;
+
+  printf_format_list fmt_list (fmt);
+
+  if (fmt_list.num_conversions () == -1)
+    ::error ("%s: invalid format specified", who.c_str ());
+  else
+    retval = do_printf (fmt_list, args, who);
+
+  return retval;
+}
+
+int
+octave_base_stream::puts (const std::string& s, const std::string& who)
+{
+  int retval = -1;
+
+  std::ostream *osp = output_stream ();
+
+  if (osp)
+    {
+      std::ostream& os = *osp;
+
+      os << s;
+
+      if (os)
+	{
+	  // FIXME -- why does this seem to be necessary?
+	  // Without it, output from a loop like
+	  //
+	  //   for i = 1:100, fputs (stdout, "foo\n"); endfor
+	  //
+	  // doesn't seem to go to the pager immediately.
+
+	  os.flush ();
+
+	  if (os)
+	    retval = 0;
+	  else
+	    error ("%s: write error", who.c_str ());
+	}
+      else
+	error ("%s: write error", who.c_str ());
+    }
+  else
+    invalid_operation (who, "writing");
+
+  return retval;
+}
+
+// Return current error message for this stream.
+
+std::string
+octave_base_stream::error (bool clear_err, int& err_num)
+{
+  err_num = fail ? -1 : 0;
+
+  std::string tmp = errmsg;
+
+  if (clear_err)
+    clear ();
+
+  return tmp;
+}
+
+void
+octave_base_stream::invalid_operation (const std::string& who, const char *rw)
+{
+  // Note that this is not ::error () !
+
+  error (who, std::string ("stream not open for ") + rw);
+}
+
+octave_stream::octave_stream (octave_base_stream *bs)
+  : rep (bs)
+{
+  if (rep)
+    rep->count = 1;
+}
+
+octave_stream::~octave_stream (void)
+{
+  if (rep && --rep->count == 0)
+    delete rep;
+}
+
+octave_stream::octave_stream (const octave_stream& s)
+  : rep (s.rep)
+{
+  if (rep)
+    rep->count++;
+}
+
+octave_stream&
+octave_stream::operator = (const octave_stream& s)
+{
+  if (rep != s.rep)
+    {
+      if (rep && --rep->count == 0)
+	delete rep;
+
+      rep = s.rep;
+
+      if (rep)
+	rep->count++;
+    }
+
+  return *this;
+}
+
+int
+octave_stream::flush (void)
+{
+  int retval = -1;
+
+  if (stream_ok ())
+    retval = rep->flush ();
+
+  return retval;
+}
+
+std::string
+octave_stream::getl (octave_idx_type max_len, bool& err, const std::string& who)
+{
+  std::string retval;
+
+  if (stream_ok ())
+    retval = rep->getl (max_len, err, who);
+
+  return retval;
+}
+
+std::string
+octave_stream::getl (const octave_value& tc_max_len, bool& err,
+		     const std::string& who)
+{
+  std::string retval;
+
+  err = false;
+
+  int conv_err = 0;
+
+  int max_len = -1;
+
+  if (tc_max_len.is_defined ())
+    {
+      max_len = convert_to_valid_int (tc_max_len, conv_err);
+
+      if (conv_err || max_len < 0)
+	{
+	  err = true;
+	  ::error ("%s: invalid maximum length specified", who.c_str ());
+	}
+    }
+
+  if (! error_state)
+    retval = getl (max_len, err, who);
+
+  return retval;
+}
+
+std::string
+octave_stream::gets (octave_idx_type max_len, bool& err, const std::string& who)
+{
+  std::string retval;
+
+  if (stream_ok ())
+    retval = rep->gets (max_len, err, who);
+
+  return retval;
+}
+
+std::string
+octave_stream::gets (const octave_value& tc_max_len, bool& err,
+		     const std::string& who)
+{
+  std::string retval;
+
+  err = false;
+
+  int conv_err = 0;
+
+  int max_len = -1;
+
+  if (tc_max_len.is_defined ())
+    {
+      max_len = convert_to_valid_int (tc_max_len, conv_err);
+
+      if (conv_err || max_len < 0)
+	{
+	  err = true;
+	  ::error ("%s: invalid maximum length specified", who.c_str ());
+	}
+    }
+
+  if (! error_state)
+    retval = gets (max_len, err, who);
+
+  return retval;
+}
+
+int
+octave_stream::seek (long offset, int origin)
+{
+  int status = -1;
+
+  if (stream_ok ())
+    {
+      clearerr ();
+
+      long orig_pos = rep->tell ();
+
+      status = rep->seek (offset, origin);
+
+      if (status == 0)
+	{
+	  long save_pos = rep->tell ();
+
+	  rep->seek (0, SEEK_END);
+
+	  long pos_eof = rep->tell ();
+
+	  // I don't think save_pos can be less than zero, but we'll
+	  // check anyway...
+
+	  if (save_pos > pos_eof || save_pos < 0)
+	    {
+	      // Seek outside bounds of file.  Failure should leave
+	      // position unchanged.
+
+	      rep->seek (orig_pos, SEEK_SET);
+
+	      status = -1;
+	    }
+	  else
+	    {
+	      // Is it possible for this to fail?  We are just
+	      // returning to a position after the first successful
+	      // seek.
+
+	      rep->seek (save_pos, SEEK_SET);
+	    }
+	}
+    }
+
+  return status;
+}
+
+int
+octave_stream::seek (const octave_value& tc_offset,
+		     const octave_value& tc_origin)
+{
+  int retval = -1;
+
+  long xoffset = tc_offset.long_value (true);
+
+  if (! error_state)
+    {
+      int conv_err = 0;
+
+      int origin = SEEK_SET;
+
+      if (tc_origin.is_string ())
+	{
+	  std::string xorigin = tc_origin.string_value ();
+
+	  if (xorigin == "bof")
+	    origin = SEEK_SET;
+	  else if (xorigin == "cof")
+	    origin = SEEK_CUR;
+	  else if (xorigin == "eof")
+	    origin = SEEK_END;
+	  else
+	    conv_err = -1;
+	}
+      else
+	{
+	  int xorigin = convert_to_valid_int (tc_origin, conv_err);
+
+	  if (! conv_err)
+	    {
+	      if (xorigin == -1)
+		origin = SEEK_SET;
+	      else if (xorigin == 0)
+		origin = SEEK_CUR;
+	      else if (xorigin == 1)
+		origin = SEEK_END;
+	      else
+		conv_err = -1;
+	    }
+	}
+
+      if (! conv_err)
+	{
+	  retval = seek (xoffset, origin);
+
+	  if (retval != 0)
+	    error ("fseek: failed to seek to requested position");
+	}
+      else
+	error ("fseek: invalid value for origin");
+    }
+  else
+    error ("fseek: invalid value for offset");
+
+  return retval;
+}
+
+long
+octave_stream::tell (void)
+{
+  long retval = -1;
+
+  if (stream_ok ())
+    retval = rep->tell ();
+
+  return retval;
+}
+
+int
+octave_stream::rewind (void)
+{
+  return seek (0, SEEK_SET);
+}
+
+bool
+octave_stream::is_open (void) const
+{
+  bool retval = false;
+
+  if (stream_ok ())
+    retval = rep->is_open ();
+
+  return retval;
+}
+
+void
+octave_stream::close (void)
+{
+  if (stream_ok ())
+    rep->close ();
+}
+
+template <class RET_T, class READ_T>
+octave_value
+do_read (octave_stream& strm, octave_idx_type nr, octave_idx_type nc, octave_idx_type block_size,
+	 octave_idx_type skip, bool do_float_fmt_conv, bool do_NA_conv,
+	 oct_mach_info::float_format from_flt_fmt, octave_idx_type& count)
+{
+  octave_value retval;
+
+  RET_T nda;
+
+  count = 0;
+
+  typename octave_array_type_traits<RET_T>::element_type elt_zero
+    = typename octave_array_type_traits<RET_T>::element_type ();
+
+  typename octave_array_type_traits<RET_T>::element_type *dat = 0;
+
+  octave_idx_type max_size = 0;
+
+  octave_idx_type final_nr = 0;
+  octave_idx_type final_nc = 1;
+
+  if (nr > 0)
+    {
+      if (nc > 0)
+	{
+	  nda.resize (dim_vector (nr, nc), elt_zero);
+	  dat = nda.fortran_vec ();
+	  max_size = nr * nc;
+	}
+      else
+	{
+	  nda.resize (dim_vector (nr, 32), elt_zero);
+	  dat = nda.fortran_vec ();
+	  max_size = nr * 32;
+	}
+    }
+  else
+    {
+      nda.resize (dim_vector (32, 1), elt_zero);
+      dat = nda.fortran_vec ();
+      max_size = 32;
+    }
+
+  // FIXME -- byte order for Cray?
+
+  bool swap = false;
+
+  if (oct_mach_info::words_big_endian ())
+    swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
+	    || from_flt_fmt == oct_mach_info::flt_fmt_vax_g
+	    || from_flt_fmt == oct_mach_info::flt_fmt_vax_g);
+  else
+    swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
+
+  union
+  {
+    char buf[sizeof (typename octave_type_traits<READ_T>::val_type)];
+    typename octave_type_traits<READ_T>::val_type val;
+  } u;
+
+  std::istream *isp = strm.input_stream ();
+
+  if (isp)
+    {
+      std::istream& is = *isp;
+
+      octave_idx_type elts_read = 0;
+
+      for (;;)
+	{
+	  // FIXME -- maybe there should be a special case for
+	  // skip == 0.
+
+	  if (is)
+	    {
+	      if (nr > 0 && nc > 0 && count == max_size)
+		{
+		  final_nr = nr;
+		  final_nc = nc;
+
+		  break;
+		}
+
+	      is.read (u.buf, sizeof (typename octave_type_traits<READ_T>::val_type));
+
+	      // We only swap bytes for integer types.  For float
+	      // types, the format conversion will also handle byte
+	      // swapping.
+
+	      if (swap)
+		swap_bytes<sizeof (typename octave_type_traits<READ_T>::val_type)> (u.buf);
+	      else if (do_float_fmt_conv)
+		do_float_format_conversion
+		  (u.buf,
+		   sizeof (typename octave_type_traits<READ_T>::val_type),
+		   1, from_flt_fmt, oct_mach_info::float_format ());
+
+	      typename octave_array_type_traits<RET_T>::element_type tmp
+		= static_cast <typename octave_array_type_traits<RET_T>::element_type> (u.val);
+
+	      if (is)
+		{
+		  if (count == max_size)
+		    {
+		      max_size *= 2;
+
+		      if (nr > 0)
+			nda.resize (dim_vector (nr, max_size / nr),
+				    elt_zero);
+		      else
+			nda.resize (dim_vector (max_size, 1), elt_zero);
+
+		      dat = nda.fortran_vec ();
+		    }
+
+		  if (do_NA_conv && __lo_ieee_is_old_NA (tmp))
+		    tmp = __lo_ieee_replace_old_NA (tmp);
+
+		  dat[count++] = tmp;
+
+		  elts_read++;
+		}
+
+	      int seek_status = 0;
+
+	      if (skip != 0 && elts_read == block_size)
+		{
+		  seek_status = strm.seek (skip, SEEK_CUR);
+		  elts_read = 0;
+		}
+
+	      if (is.eof () || seek_status < 0)
+		{
+		  if (nr > 0)
+		    {
+		      if (count > nr)
+			{
+			  final_nr = nr;
+			  final_nc = (count - 1) / nr + 1;
+			}
+		      else
+			{
+			  final_nr = count;
+			  final_nc = 1;
+			}
+		    }
+		  else
+		    {
+		      final_nr = count;
+		      final_nc = 1;
+		    }
+
+		  break;
+		}
+	    }
+	  else if (is.eof ())
+	    break;
+	}
+    }
+
+  nda.resize (dim_vector (final_nr, final_nc), elt_zero);
+
+  retval = nda;
+
+  return retval;
+}
+
+#define DO_READ_VAL_TEMPLATE(RET_T, READ_T) \
+  template octave_value \
+  do_read<RET_T, READ_T> (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool, \
+			  oct_mach_info::float_format, octave_idx_type&)
+
+// FIXME -- should we only have float if it is a different
+// size from double?
+
+#define INSTANTIATE_DO_READ(VAL_T) \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_int8); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint8); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_int16); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint16); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_int32); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint32); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_int64); \
+  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint64); \
+  DO_READ_VAL_TEMPLATE (VAL_T, float); \
+  DO_READ_VAL_TEMPLATE (VAL_T, double); \
+  DO_READ_VAL_TEMPLATE (VAL_T, char); \
+  DO_READ_VAL_TEMPLATE (VAL_T, signed char); \
+  DO_READ_VAL_TEMPLATE (VAL_T, unsigned char)
+
+INSTANTIATE_DO_READ (int8NDArray);
+INSTANTIATE_DO_READ (uint8NDArray);
+INSTANTIATE_DO_READ (int16NDArray);
+INSTANTIATE_DO_READ (uint16NDArray);
+INSTANTIATE_DO_READ (int32NDArray);
+INSTANTIATE_DO_READ (uint32NDArray);
+INSTANTIATE_DO_READ (int64NDArray);
+INSTANTIATE_DO_READ (uint64NDArray);
+INSTANTIATE_DO_READ (FloatNDArray);
+INSTANTIATE_DO_READ (NDArray);
+INSTANTIATE_DO_READ (charNDArray);
+INSTANTIATE_DO_READ (boolNDArray);
+
+typedef octave_value (*read_fptr) (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool,
+				   oct_mach_info::float_format ffmt, octave_idx_type&);
+
+#define FILL_TABLE_ROW(R, VAL_T) \
+  read_fptr_table[R][oct_data_conv::dt_int8] = do_read<VAL_T, octave_int8>; \
+  read_fptr_table[R][oct_data_conv::dt_uint8] = do_read<VAL_T, octave_uint8>; \
+  read_fptr_table[R][oct_data_conv::dt_int16] = do_read<VAL_T, octave_int16>; \
+  read_fptr_table[R][oct_data_conv::dt_uint16] = do_read<VAL_T, octave_uint16>; \
+  read_fptr_table[R][oct_data_conv::dt_int32] = do_read<VAL_T, octave_int32>; \
+  read_fptr_table[R][oct_data_conv::dt_uint32] = do_read<VAL_T, octave_uint32>; \
+  read_fptr_table[R][oct_data_conv::dt_int64] = do_read<VAL_T, octave_int64>; \
+  read_fptr_table[R][oct_data_conv::dt_uint64] = do_read<VAL_T, octave_uint64>; \
+  read_fptr_table[R][oct_data_conv::dt_single] = do_read<VAL_T, float>; \
+  read_fptr_table[R][oct_data_conv::dt_double] = do_read<VAL_T, double>; \
+  read_fptr_table[R][oct_data_conv::dt_char] = do_read<VAL_T, char>; \
+  read_fptr_table[R][oct_data_conv::dt_schar] = do_read<VAL_T, signed char>; \
+  read_fptr_table[R][oct_data_conv::dt_uchar] = do_read<VAL_T, unsigned char>; \
+  read_fptr_table[R][oct_data_conv::dt_logical] = do_read<VAL_T, unsigned char>
+
+octave_value
+octave_stream::read (const Array<double>& size, octave_idx_type block_size,
+		     oct_data_conv::data_type input_type,
+		     oct_data_conv::data_type output_type,
+		     octave_idx_type skip, oct_mach_info::float_format ffmt,
+		     octave_idx_type& char_count)
+{
+  static bool initialized = false;
+
+  // Table function pointers for return types x read types.
+
+  static read_fptr read_fptr_table[oct_data_conv::dt_unknown][14];
+
+  if (! initialized)
+    {
+      for (int i = 0; i < oct_data_conv::dt_unknown; i++)
+        for (int j = 0; j < 14; j++)
+          read_fptr_table[i][j] = 0;
+
+      FILL_TABLE_ROW (oct_data_conv::dt_int8, int8NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_uint8, uint8NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_int16, int16NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_uint16, uint16NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_int32, int32NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_uint32, uint32NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_int64, int64NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_uint64, uint64NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_single, FloatNDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_double, NDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_char, charNDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_schar, charNDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_uchar, charNDArray);
+      FILL_TABLE_ROW (oct_data_conv::dt_logical, boolNDArray);
+
+      initialized = true;
+    }
+
+  octave_value retval;
+
+  if (stream_ok ())
+    {
+      // FIXME -- we may eventually want to make this extensible.
+
+      // FIXME -- we need a better way to ensure that this
+      // numbering stays consistent with the order of the elements in the
+      // data_type enum in the oct_data_conv class.
+
+      char_count = 0;
+
+      octave_idx_type nr = -1;
+      octave_idx_type nc = -1;
+
+      bool ignore;
+
+      get_size (size, nr, nc, ignore, "fread");
+
+      if (! error_state)
+	{
+	  if (nr == 0 || nc == 0)
+	    retval = Matrix (nr, nc);
+	  else
+	    {
+	      if (ffmt == oct_mach_info::flt_fmt_unknown)
+		ffmt = float_format ();
+
+	      read_fptr fcn = read_fptr_table[output_type][input_type];
+
+	      bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double
+					 || input_type == oct_data_conv::dt_single)
+					&& ffmt != float_format ());
+
+	      bool do_NA_conv = (output_type == oct_data_conv::dt_double);
+
+	      if (fcn)
+		{
+		  retval = (*fcn) (*this, nr, nc, block_size, skip,
+				   do_float_fmt_conv, do_NA_conv,
+				   ffmt, char_count);
+
+		  // FIXME -- kluge!
+
+		  if (! error_state
+		      && (output_type == oct_data_conv::dt_char
+			  || output_type == oct_data_conv::dt_schar
+			  || output_type == oct_data_conv::dt_uchar))
+		    retval = octave_value (retval.char_matrix_value (), true);
+		}
+	      else
+		error ("fread: unable to read and convert requested types");
+	    }
+	}
+      else
+	invalid_operation ("fread", "reading");
+    }
+
+  return retval;
+}
+
+octave_idx_type
+octave_stream::write (const octave_value& data, octave_idx_type block_size,
+		      oct_data_conv::data_type output_type, octave_idx_type skip,
+		      oct_mach_info::float_format flt_fmt)
+{
+  octave_idx_type retval = -1;
+
+  if (stream_ok ())
+    {
+      if (! error_state)
+	{
+	  if (flt_fmt == oct_mach_info::flt_fmt_unknown)
+	    flt_fmt = float_format ();
+
+	  octave_idx_type status = data.write (*this, block_size, output_type,
+				   skip, flt_fmt);
+
+	  if (status < 0)
+	    error ("fwrite: write error");
+	  else
+	    retval = status;
+	}
+      else
+	invalid_operation ("fwrite", "writing");
+    }
+
+  return retval;
+}
+
+template <class T>
+void
+write_int (std::ostream& os, bool swap, const T& val)
+{
+  typename octave_type_traits<T>::val_type tmp = val.value ();
+
+  if (swap)
+    swap_bytes<sizeof (typename octave_type_traits<T>::val_type)> (&tmp);
+
+  os.write (reinterpret_cast<const char *> (&tmp),
+	    sizeof (typename octave_type_traits<T>::val_type));
+}
+
+template void write_int (std::ostream&, bool, const octave_int8&);
+template void write_int (std::ostream&, bool, const octave_uint8&);
+template void write_int (std::ostream&, bool, const octave_int16&);
+template void write_int (std::ostream&, bool, const octave_uint16&);
+template void write_int (std::ostream&, bool, const octave_int32&);
+template void write_int (std::ostream&, bool, const octave_uint32&);
+template void write_int (std::ostream&, bool, const octave_int64&);
+template void write_int (std::ostream&, bool, const octave_uint64&);
+
+template <class T>
+static inline bool
+do_write (std::ostream& os, const T& val, oct_data_conv::data_type output_type,
+	  oct_mach_info::float_format flt_fmt, bool swap,
+	  bool do_float_conversion)
+{
+  bool retval = true;
+
+  // For compatibility, Octave converts to the output type, then
+  // writes.  This means that truncation happens on the conversion.
+  // For example, the following program prints 0:
+  //
+  //   x = int8 (-1)
+  //   f = fopen ("foo.dat", "w");
+  //   fwrite (f, x, "unsigned char");
+  //   fclose (f);
+  //   f = fopen ("foo.dat", "r");
+  //   y = fread (f, 1, "unsigned char");
+  //   printf ("%d\n", y);
+
+  switch (output_type)
+    {
+    case oct_data_conv::dt_char:
+    case oct_data_conv::dt_schar:
+    case oct_data_conv::dt_int8:
+      write_int (os, swap, octave_int8 (val));
+      break;
+
+    case oct_data_conv::dt_uchar:
+    case oct_data_conv::dt_uint8:
+      write_int (os, swap, octave_uint8 (val));
+      break;
+
+    case oct_data_conv::dt_int16:
+      write_int (os, swap, octave_int16 (val));
+      break;
+
+    case oct_data_conv::dt_uint16:
+      write_int (os, swap, octave_uint16 (val));
+      break;
+
+    case oct_data_conv::dt_int32:
+      write_int (os, swap, octave_int32 (val));
+      break;
+
+    case oct_data_conv::dt_uint32:
+      write_int (os, swap, octave_uint32 (val));
+      break;
+
+    case oct_data_conv::dt_int64:
+      write_int (os, swap, octave_int64 (val));
+      break;
+
+    case oct_data_conv::dt_uint64:
+      write_int (os, swap, octave_uint64 (val));
+      break;
+
+    case oct_data_conv::dt_single:
+      {
+	float f = static_cast<float> (val);
+
+	if (do_float_conversion)
+	  do_float_format_conversion (&f, 1, flt_fmt);
+
+	os.write (reinterpret_cast<const char *> (&f), sizeof (float));
+      }
+      break;
+
+    case oct_data_conv::dt_double:
+      {
+	double d = static_cast<double> (val);
+	if (do_float_conversion)
+	  do_double_format_conversion (&d, 1, flt_fmt);
+
+	os.write (reinterpret_cast<const char *> (&d), sizeof (double));
+      }
+      break;
+
+    default:
+      retval = false;
+      (*current_liboctave_error_handler)
+	("write: invalid type specification");
+      break;
+    }
+
+  return retval;
+}
+
+template bool
+do_write (std::ostream&, const octave_int8&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_uint8&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_int16&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_uint16&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_int32&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_uint32&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_int64&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template bool
+do_write (std::ostream&, const octave_uint64&, oct_data_conv::data_type,
+	  oct_mach_info::float_format, bool, bool);
+
+template <class T>
+octave_idx_type
+octave_stream::write (const Array<T>& data, octave_idx_type block_size,
+		      oct_data_conv::data_type output_type,
+		      octave_idx_type skip, oct_mach_info::float_format flt_fmt)
+{
+  octave_idx_type retval = -1;
+
+  bool status = true;
+
+  octave_idx_type count = 0;
+
+  const T *d = data.data ();
+
+  octave_idx_type n = data.length ();
+
+  oct_mach_info::float_format native_flt_fmt
+    = oct_mach_info::float_format ();
+
+  bool do_float_conversion = (flt_fmt != native_flt_fmt);
+
+  // FIXME -- byte order for Cray?
+
+  bool swap = false;
+
+  if (oct_mach_info::words_big_endian ())
+    swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
+	    || flt_fmt == oct_mach_info::flt_fmt_vax_g
+	    || flt_fmt == oct_mach_info::flt_fmt_vax_g);
+  else
+    swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    {
+      std::ostream *osp = output_stream ();
+
+      if (osp)
+	{
+	  std::ostream& os = *osp;
+
+	  if (skip != 0 && (i % block_size) == 0)
+	    {
+	      // Seek to skip when inside bounds of existing file.
+	      // Otherwise, write NUL to skip.
+
+	      long orig_pos = tell ();
+
+	      seek (0, SEEK_END);
+
+	      long eof_pos = tell ();
+
+	      // Is it possible for this to fail to return us to the
+	      // original position?
+	      seek (orig_pos, SEEK_SET);
+
+	      long remaining = eof_pos - orig_pos;
+
+	      if (remaining < skip)
+		{
+		  seek (0, SEEK_END);
+
+		  // FIXME -- probably should try to write larger
+		  // blocks...
+
+		  unsigned char zero = 0;
+		  for (octave_idx_type j = 0; j < skip - remaining; j++)
+		    os.write (reinterpret_cast<const char *> (&zero), 1);
+		}
+	      else
+		seek (skip, SEEK_CUR);
+	    }
+
+	  if (os)
+	    {
+	      status = do_write (os, d[i], output_type, flt_fmt, swap,
+				 do_float_conversion);
+
+	      if (os && status)
+		count++;
+	      else
+		break;
+	    }
+	  else
+	    {
+	      status = false;
+	      break;
+	    }
+	}
+      else
+	{
+	  status = false;
+	  break;
+	}
+    }
+
+  if (status)
+    retval = count;
+
+  return retval;
+}
+
+template octave_idx_type
+octave_stream::write (const Array<char>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<bool>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<double>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<float>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_int8>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_uint8>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_int16>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_uint16>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_int32>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_uint32>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_int64>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+template octave_idx_type
+octave_stream::write (const Array<octave_uint64>&, octave_idx_type,
+		      oct_data_conv::data_type,
+		      octave_idx_type, oct_mach_info::float_format);
+
+octave_value
+octave_stream::scanf (const std::string& fmt, const Array<double>& size,
+		      octave_idx_type& count, const std::string& who)
+{
+  octave_value retval;
+
+  if (stream_ok ())
+    retval = rep->scanf (fmt, size, count, who);
+
+  return retval;
+}
+
+octave_value
+octave_stream::scanf (const octave_value& fmt, const Array<double>& size,
+		      octave_idx_type& count, const std::string& who)
+{
+  octave_value retval = Matrix ();
+
+  if (fmt.is_string ())
+    {
+      std::string sfmt = fmt.string_value ();
+
+      if (fmt.is_sq_string ())
+	sfmt = do_string_escapes (sfmt);
+
+      retval = scanf (sfmt, size, count, who);
+    }
+  else
+    {
+      // Note that this is not ::error () !
+
+      error (who + ": format must be a string");
+    }
+
+  return retval;
+}
+
+octave_value_list
+octave_stream::oscanf (const std::string& fmt, const std::string& who)
+{
+  octave_value_list retval;
+
+  if (stream_ok ())
+    retval = rep->oscanf (fmt, who);
+
+  return retval;
+}
+
+octave_value_list
+octave_stream::oscanf (const octave_value& fmt, const std::string& who)
+{
+  octave_value_list retval;
+
+  if (fmt.is_string ())
+    {
+      std::string sfmt = fmt.string_value ();
+
+      if (fmt.is_sq_string ())
+	sfmt = do_string_escapes (sfmt);
+
+      retval = oscanf (sfmt, who);
+    }
+  else
+    {
+      // Note that this is not ::error () !
+
+      error (who + ": format must be a string");
+    }
+
+  return retval;
+}
+
+int
+octave_stream::printf (const std::string& fmt, const octave_value_list& args,
+		       const std::string& who)
+{
+  int retval = -1;
+
+  if (stream_ok ())
+    retval = rep->printf (fmt, args, who);
+
+  return retval;
+}
+
+int
+octave_stream::printf (const octave_value& fmt, const octave_value_list& args,
+		       const std::string& who)
+{
+  int retval = 0;
+
+  if (fmt.is_string ())
+    {
+      std::string sfmt = fmt.string_value ();
+
+      if (fmt.is_sq_string ())
+	sfmt = do_string_escapes (sfmt);
+
+      retval = printf (sfmt, args, who);
+    }
+  else
+    {
+      // Note that this is not ::error () !
+
+      error (who + ": format must be a string");
+    }
+
+  return retval;
+}
+
+int
+octave_stream::puts (const std::string& s, const std::string& who)
+{
+  int retval = -1;
+
+  if (stream_ok ())
+    retval = rep->puts (s, who);
+
+  return retval;
+}
+
+// FIXME -- maybe this should work for string arrays too.
+
+int
+octave_stream::puts (const octave_value& tc_s, const std::string& who)
+{
+  int retval = -1;
+
+  if (tc_s.is_string ())
+    {
+      std::string s = tc_s.string_value ();      
+      retval = puts (s, who);
+    }
+  else
+    {
+      // Note that this is not ::error () !
+
+      error (who + ": argument must be a string");
+    }
+
+  return retval;
+}
+
+bool
+octave_stream::eof (void) const
+{
+  int retval = -1;
+
+  if (stream_ok ())
+    retval = rep->eof ();
+
+  return retval;
+}
+
+std::string
+octave_stream::error (bool clear, int& err_num)
+{
+  std::string retval = "invalid stream object";
+
+  if (stream_ok (false))
+    retval = rep->error (clear, err_num);
+
+  return retval;
+}
+
+std::string
+octave_stream::name (void) const
+{
+  std::string retval;
+
+  if (stream_ok ())
+    retval = rep->name ();
+
+  return retval;
+}
+
+int
+octave_stream::mode (void) const
+{
+  int retval = 0;
+
+  if (stream_ok ())
+    retval = rep->mode ();
+
+  return retval;
+}
+
+oct_mach_info::float_format
+octave_stream::float_format (void) const
+{
+  oct_mach_info::float_format retval = oct_mach_info::flt_fmt_unknown;
+
+  if (stream_ok ())
+    retval = rep->float_format ();
+
+  return retval;
+}
+
+std::string
+octave_stream::mode_as_string (int mode)
+{
+  std::string retval = "???";
+  std::ios::openmode in_mode = static_cast<std::ios::openmode> (mode);
+
+  if (in_mode == std::ios::in)
+    retval = "r";
+  else if (in_mode == std::ios::out 
+           || in_mode == (std::ios::out | std::ios::trunc))
+    retval = "w";
+  else if (in_mode == (std::ios::out | std::ios::app))
+    retval = "a";
+  else if (in_mode == (std::ios::in | std::ios::out))
+    retval = "r+";
+  else if (in_mode == (std::ios::in | std::ios::out | std::ios::trunc))
+    retval = "w+";
+  else if (in_mode == (std::ios::in | std::ios::out | std::ios::ate))
+    retval = "a+";
+  else if (in_mode == (std::ios::in | std::ios::binary))
+    retval = "rb";
+  else if (in_mode == (std::ios::out | std::ios::binary)
+	   || in_mode == (std::ios::out | std::ios::trunc | std::ios::binary))
+    retval = "wb";
+  else if (in_mode == (std::ios::out | std::ios::app | std::ios::binary))
+    retval = "ab";
+  else if (in_mode == (std::ios::in | std::ios::out | std::ios::binary))
+    retval = "r+b";
+  else if (in_mode == (std::ios::in | std::ios::out | std::ios::trunc 
+		       | std::ios::binary))
+    retval = "w+b";
+  else if (in_mode == (std::ios::in | std::ios::out | std::ios::ate
+		       | std::ios::binary))
+    retval = "a+b";
+
+  return retval;
+}
+
+octave_stream_list *octave_stream_list::instance = 0;
+
+bool
+octave_stream_list::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_stream_list ();
+
+  if (! instance)
+    {
+      ::error ("unable to create stream list object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+int
+octave_stream_list::insert (octave_stream& os)
+{
+  return (instance_ok ()) ? instance->do_insert (os) : -1;
+}
+
+octave_stream
+octave_stream_list::lookup (int fid, const std::string& who)
+{
+  return (instance_ok ()) ? instance->do_lookup (fid, who) : octave_stream ();
+}
+
+octave_stream
+octave_stream_list::lookup (const octave_value& fid, const std::string& who)
+{
+  return (instance_ok ()) ? instance->do_lookup (fid, who) : octave_stream ();
+}
+
+int
+octave_stream_list::remove (int fid, const std::string& who)
+{
+  return (instance_ok ()) ? instance->do_remove (fid, who) : -1;
+}
+
+int
+octave_stream_list::remove (const octave_value& fid, const std::string& who)
+{
+  return (instance_ok ()) ? instance->do_remove (fid, who) : -1;
+}
+
+void
+octave_stream_list::clear (bool flush)
+{
+  if (instance)
+    instance->do_clear (flush);
+}
+
+string_vector
+octave_stream_list::get_info (int fid)
+{
+  return (instance_ok ()) ? instance->do_get_info (fid) : string_vector ();
+}
+
+string_vector
+octave_stream_list::get_info (const octave_value& fid)
+{
+  return (instance_ok ()) ? instance->do_get_info (fid) : string_vector ();
+}
+
+std::string
+octave_stream_list::list_open_files (void)
+{
+  return (instance_ok ()) ? instance->do_list_open_files () : std::string ();
+}
+
+octave_value
+octave_stream_list::open_file_numbers (void)
+{
+  return (instance_ok ())
+    ? instance->do_open_file_numbers () : octave_value ();
+}
+
+int
+octave_stream_list::get_file_number (const octave_value& fid)
+{
+  return (instance_ok ()) ? instance->do_get_file_number (fid) : -1;
+}
+
+int
+octave_stream_list::do_insert (octave_stream& os)
+{
+  // Insert item with key corresponding to file-descriptor.
+
+  int stream_number;
+
+  if ((stream_number = os.file_number ()) == -1)
+    return stream_number;
+
+  // Should we test for "(list.find (stream_number) != list.end ()) &&
+  // list[stream_number].is_open ()" and respond with "error
+  // ("internal error: ...")"? It should not happen except for some
+  // bug or if the user has opened a stream with an interpreted
+  // command, but closed it directly with a system call in an
+  // oct-file; then the kernel knows the fd is free, but Octave does
+  // not know. If it happens, it should not do harm here to simply
+  // overwrite this entry, although the wrong entry might have done
+  // harm before.
+
+  if (list.size () < list.max_size ())
+    list[stream_number] = os;
+  else
+    {
+      stream_number = -1;
+      error ("could not create file id");
+    }
+
+  return stream_number;
+
+}
+
+static void
+gripe_invalid_file_id (int fid, const std::string& who)
+{
+  if (who.empty ())
+    ::error ("invalid stream number = %d", fid);
+  else
+    ::error ("%s: invalid stream number = %d", who.c_str (), fid);
+}
+
+octave_stream
+octave_stream_list::do_lookup (int fid, const std::string& who) const
+{
+  octave_stream retval;
+
+  if (fid >= 0)
+    {
+      if (lookup_cache != list.end () && lookup_cache->first == fid)
+        retval = lookup_cache->second;
+      else
+        {
+          ostrl_map::const_iterator iter = list.find (fid);
+
+          if (iter != list.end ())
+            {
+              retval = iter->second;
+              lookup_cache = iter;
+            }
+          else
+            gripe_invalid_file_id (fid, who);
+        }
+    }
+  else
+    gripe_invalid_file_id (fid, who);
+
+  return retval;
+}
+
+octave_stream
+octave_stream_list::do_lookup (const octave_value& fid,
+			       const std::string& who) const
+{
+  octave_stream retval;
+
+  int i = get_file_number (fid);
+
+  if (! error_state)
+    retval = do_lookup (i, who);
+
+  return retval;
+}
+
+int
+octave_stream_list::do_remove (int fid, const std::string& who)
+{
+  int retval = -1;
+
+  // Can't remove stdin (std::cin), stdout (std::cout), or stderr
+  // (std::cerr).
+
+  if (fid > 2)
+    {
+      ostrl_map::iterator iter = list.find (fid);
+
+      if (iter != list.end ())
+	{
+	  octave_stream os = iter->second;
+          list.erase (iter);
+          lookup_cache = list.end ();
+
+          // FIXME: is this check redundant?
+	  if (os.is_valid ())
+	    {
+	      os.close ();
+	      retval = 0;
+	    }
+	  else
+	    gripe_invalid_file_id (fid, who);
+	}
+      else
+	gripe_invalid_file_id (fid, who);
+    }
+  else
+    gripe_invalid_file_id (fid, who);
+
+  return retval;
+}
+
+int
+octave_stream_list::do_remove (const octave_value& fid, const std::string& who)
+{
+  int retval = -1;
+
+  if (fid.is_string () && fid.string_value () == "all")
+    {
+      do_clear (false);
+
+      retval = 0;
+    }
+  else
+    {
+      int i = get_file_number (fid);
+
+      if (! error_state)
+	retval = do_remove (i, who);
+    }
+
+  return retval;
+}
+
+void
+octave_stream_list::do_clear (bool flush)
+{
+  if (flush)
+    {
+      // Do flush stdout and stderr.
+
+      list[0].flush ();
+      list[1].flush ();
+    }
+
+  octave_stream saved_os[3];
+  // But don't delete them or stdin.
+  for (ostrl_map::iterator iter = list.begin (); iter != list.end (); iter++)
+    {
+      int fid = iter->first;
+      octave_stream os = iter->second;
+      if (fid < 3)
+        saved_os[fid] = os;
+      else if (os.is_valid ())
+        os.close ();
+    }
+  list.clear ();
+  for (int fid = 0; fid < 3; fid++) list[fid] = saved_os[fid];
+  lookup_cache = list.end ();
+}
+
+string_vector
+octave_stream_list::do_get_info (int fid) const
+{
+  string_vector retval;
+
+  octave_stream os = do_lookup (fid);
+
+  if (os.is_valid ())
+    {
+      retval.resize (3);
+
+      retval(0) = os.name ();
+      retval(1) = octave_stream::mode_as_string (os.mode ());
+      retval(2) = oct_mach_info::float_format_as_string (os.float_format ());
+    }
+  else
+    ::error ("invalid file id = %d", fid);
+
+  return retval;
+}
+
+string_vector
+octave_stream_list::do_get_info (const octave_value& fid) const
+{
+  string_vector retval;
+
+  int conv_err = 0;
+
+  int int_fid = convert_to_valid_int (fid, conv_err);
+
+  if (! conv_err)
+    retval = do_get_info (int_fid);
+  else
+    ::error ("file id must be a file object or integer value");
+
+  return retval;
+}
+
+std::string
+octave_stream_list::do_list_open_files (void) const
+{
+  std::string retval;
+
+  std::ostringstream buf;
+
+  buf << "\n"
+      << "  number  mode  arch       name\n"
+      << "  ------  ----  ----       ----\n";
+
+  for (ostrl_map::const_iterator p = list.begin (); p != list.end (); p++)
+    {
+      octave_stream os = p->second;
+
+      buf << "  "
+	  << std::setiosflags (std::ios::right)
+	  << std::setw (4) << p->first << "     "
+	  << std::setiosflags (std::ios::left)
+	  << std::setw (3)
+	  << octave_stream::mode_as_string (os.mode ())
+	  << "  "
+	  << std::setw (9)
+	  << oct_mach_info::float_format_as_string (os.float_format ())
+	  << "  "
+	  << os.name () << "\n";
+    }
+
+  buf << "\n";
+
+  retval = buf.str ();
+
+  return retval;
+}
+
+octave_value
+octave_stream_list::do_open_file_numbers (void) const
+{
+  Matrix retval (1, list.size (), 0.0);
+
+  int num_open = 0;
+
+  for (ostrl_map::const_iterator p = list.begin (); p != list.end (); p++)
+    {
+      // Skip stdin, stdout, and stderr.
+
+      if (p->first > 2 && p->second)
+	retval(0,num_open++) = p->first;
+    }
+
+  retval.resize ((num_open > 0), num_open);
+
+  return retval;
+}
+
+int
+octave_stream_list::do_get_file_number (const octave_value& fid) const
+{
+  int retval = -1;
+
+  if (fid.is_string ())
+    {
+      std::string nm = fid.string_value ();
+
+      for (ostrl_map::const_iterator p = list.begin (); p != list.end (); p++)
+	{
+	  // stdin (std::cin), stdout (std::cout), and stderr (std::cerr)
+	  // are unnamed.
+
+	  if (p->first > 2)
+	    {
+	      octave_stream os = p->second;
+
+	      if (os && os.name () == nm)
+		{
+		  retval = p->first;
+		  break;
+		}
+	    }
+	}
+    }
+  else
+    {
+      int conv_err = 0;
+
+      int int_fid = convert_to_valid_int (fid, conv_err);
+
+      if (conv_err)
+	::error ("file id must be a file object, std::string, or integer value");
+      else
+	retval = int_fid;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-stream.h b/src/oct-stream.h
new file mode 100644
index 0000000..794548e
--- /dev/null
+++ b/src/oct-stream.h
@@ -0,0 +1,700 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_stream_h)
+#define octave_octave_stream_h 1
+
+class Matrix;
+class string_vector;
+class octave_value;
+class octave_value_list;
+
+#include <iosfwd>
+#include <sstream>
+#include <string>
+#include <map>
+
+#include "Array.h"
+#include "data-conv.h"
+#include "lo-utils.h"
+#include "mach-info.h"
+
+class
+OCTINTERP_API
+scanf_format_elt
+{
+public:
+
+  enum special_conversion
+    {
+      whitespace_conversion = 1,
+      literal_conversion = 2
+    };
+
+  scanf_format_elt (const char *txt = 0, int w = 0, bool d = false,
+		    char typ = '\0', char mod = '\0',
+		    const std::string& ch_class = std::string ())
+    : text (strsave (txt)), width (w), discard (d), type (typ),
+      modifier (mod), char_class (ch_class) { }
+
+  scanf_format_elt (const scanf_format_elt& e)
+    : text (strsave (e.text)), width (e.width), discard (e.discard),
+      type (e.type), modifier (e.modifier), char_class (e.char_class) { }
+
+  scanf_format_elt& operator = (const scanf_format_elt& e)
+    {
+      if (this != &e)
+	{
+	  text = strsave (e.text);
+	  width = e.width;
+	  discard = e.discard;
+	  type = e.type;
+	  modifier = e.modifier;
+	  char_class = e.char_class;
+	}
+
+      return *this;
+    }
+
+  ~scanf_format_elt (void) { delete [] text; }
+
+  // The C-style format string.
+  const char *text;
+
+  // The maximum field width.
+  int width;
+
+  // TRUE if we are not storing the result of this conversion.
+  bool discard;
+
+  // Type of conversion -- `d', `i', `o', `u', `x', `e', `f', `g',
+  // `c', `s', `p', `%', or `['.
+  char type;
+
+  // A length modifier -- `h', `l', or `L'.
+  char modifier;
+
+  // The class of characters in a `[' format.
+  std::string char_class;
+};
+
+class
+OCTINTERP_API
+scanf_format_list
+{
+public:
+
+  scanf_format_list (const std::string& fmt = std::string ());
+
+  ~scanf_format_list (void);
+
+  int num_conversions (void) { return nconv; }
+
+  // The length can be different than the number of conversions.
+  // For example, "x %d y %d z" has 2 conversions but the length of
+  // the list is 3 because of the characters that appear after the
+  // last conversion.
+
+  int length (void) { return list.length (); }
+
+  const scanf_format_elt *first (void)
+    {
+      curr_idx = 0;
+      return current ();
+    }
+
+  const scanf_format_elt *current (void) const
+    { return list.length () > 0 ? list.elem (curr_idx) : 0; }
+
+  const scanf_format_elt *next (bool cycle = true)
+    {
+      curr_idx++;
+
+      if (curr_idx >= list.length ())
+	{
+	  if (cycle)
+	    curr_idx = 0;
+	  else
+	    return 0;
+	}
+      return current ();
+    }
+
+  void printme (void) const;
+
+  bool ok (void) const { return (nconv >= 0); }
+
+  operator bool () const { return ok (); }
+
+  bool all_character_conversions (void);
+
+  bool all_numeric_conversions (void);
+
+private:
+
+  // Number of conversions specified by this format string, or -1 if
+  // invalid conversions have been found.
+  int nconv;
+
+  // Index to current element;
+  int curr_idx;
+
+  // List of format elements.
+  Array<scanf_format_elt*> list;
+
+  // Temporary buffer.
+  std::ostringstream *buf;
+
+  void add_elt_to_list (int width, bool discard, char type, char modifier,
+			int& num_elts,
+			const std::string& char_class = std::string ()); 
+
+  void process_conversion (const std::string& s, int& i, int n, int& width,
+			   bool& discard, char& type, char& modifier,
+			   int& num_elts);
+
+  int finish_conversion (const std::string& s, int& i, int n, int& width,
+			 bool discard, char& type, char modifier,
+			 int& num_elts);
+  // No copying!
+
+  scanf_format_list (const scanf_format_list&);
+
+  scanf_format_list& operator = (const scanf_format_list&);
+};
+
+class
+printf_format_elt
+{
+public:
+
+  printf_format_elt (const char *txt = 0, int n = 0, int w = 0,
+		     int p = 0, const std::string& f = std::string (),
+		     char typ = '\0', char mod = '\0')
+    : text (strsave (txt)), args (n), fw (w), prec (p), flags (f),
+      type (typ), modifier (mod) { }
+
+  printf_format_elt (const printf_format_elt& e)
+    : text (strsave (e.text)), args (e.args), fw (e.fw), prec (e.prec),
+      flags (e.flags), type (e.type), modifier (e.modifier) { }
+
+  printf_format_elt& operator = (const printf_format_elt& e)
+    {
+      if (this != &e)
+	{
+	  text = strsave (e.text);
+	  args = e.args;
+	  fw = e.fw;
+	  prec = e.prec;
+	  flags = e.flags;
+	  type = e.type;
+	  modifier = e.modifier;
+	}
+
+      return *this;
+    }
+
+  ~printf_format_elt (void) { delete [] text; }
+ 
+  // The C-style format string.
+  const char *text;
+
+  // How many args do we expect to consume?
+  int args;
+
+  // Field width.
+  int fw;
+
+  // Precision.
+  int prec;
+
+  // Flags -- `-', `+', ` ', `0', or `#'.
+  std::string flags;
+
+  // Type of conversion -- `d', `i', `o', `x', `X', `u', `c', `s',
+  // `f', `e', `E', `g', `G', `p', or `%'
+  char type;
+
+  // A length modifier -- `h', `l', or `L'.
+  char modifier;
+};
+
+class
+OCTINTERP_API
+printf_format_list
+{
+public:
+
+  printf_format_list (const std::string& fmt = std::string ());
+
+  ~printf_format_list (void);
+
+  int num_conversions (void) { return nconv; }
+
+  const printf_format_elt *first (void)
+    {
+      curr_idx = 0;
+      return current ();
+    }
+
+  const printf_format_elt *current (void) const
+    { return list.length () > 0 ? list.elem (curr_idx) : 0; }
+
+  const printf_format_elt *next (bool cycle = true)
+    {
+      curr_idx++;
+
+      if (curr_idx >= list.length ())
+	{
+	  if (cycle)
+	    curr_idx = 0;
+	  else
+	    return 0;
+	}
+
+      return current ();
+    }
+
+  bool last_elt_p (void) { return (curr_idx + 1 == list.length ()); }
+
+  void printme (void) const;
+
+  bool ok (void) const { return (nconv >= 0); }
+
+  operator bool () const { return ok (); }
+
+private:
+
+  // Number of conversions specified by this format string, or -1 if
+  // invalid conversions have been found.
+  int nconv;
+
+  // Index to current element;
+  int curr_idx;
+
+  // List of format elements.
+  Array<printf_format_elt*> list;
+
+  // Temporary buffer.
+  std::ostringstream *buf;
+
+  void add_elt_to_list (int args, const std::string& flags, int fw,
+			int prec, char type, char modifier,
+ 			int& num_elts);
+ 
+  void process_conversion (const std::string& s, int& i, int n,
+			   int& args, std::string& flags, int& fw,
+			   int& prec, char& modifier, char& type,
+			   int& num_elts); 
+ 
+  void finish_conversion (const std::string& s, int& i, int args,
+			  const std::string& flags, int fw, int prec,
+			  char modifier, char& type, int& num_elts);
+
+  // No copying!
+
+  printf_format_list (const printf_format_list&);
+
+  printf_format_list& operator = (const printf_format_list&);
+};
+
+// Provide an interface for Octave streams.
+
+class
+OCTINTERP_API
+octave_base_stream
+{
+friend class octave_stream;
+
+public:
+
+  octave_base_stream (std::ios::openmode arg_md = std::ios::in|std::ios::out,
+		      oct_mach_info::float_format ff
+		        = oct_mach_info::native_float_format ())
+    : count (0), md (arg_md), flt_fmt (ff), fail (false), open_state (true)
+  { }
+
+  virtual ~octave_base_stream (void) { }
+
+  // The remaining functions are not specific to input or output only,
+  // and must be provided by the derived classes.
+
+  // Position a stream at OFFSET relative to ORIGIN.
+
+  virtual int seek (long offset, int origin) = 0;
+
+  // Return current stream position.
+
+  virtual long tell (void) = 0;
+
+  // Return TRUE if EOF has been reached on this stream.
+
+  virtual bool eof (void) const = 0;
+
+  // The name of the file.
+
+  virtual std::string name (void) const = 0;
+
+  // If the derived class provides this function and it returns a
+  // pointer to a valid istream, scanf(), read(), getl(), and gets()
+  // will automatically work for this stream.
+
+  virtual std::istream *input_stream (void) { return 0; }
+
+  // If the derived class provides this function and it returns a
+  // pointer to a valid ostream, flush(), write(), and printf() will
+  // automatically work for this stream.
+
+  virtual std::ostream *output_stream (void) { return 0; }
+
+  // Return TRUE if this stream is open.
+
+  bool is_open (void) const { return open_state; }
+
+  virtual void do_close (void) { }
+
+  void close (void)
+    {
+      if (is_open ())
+	{
+	  open_state = false;
+	  do_close ();
+	}
+    }
+
+  int file_number (void);
+
+  bool ok (void) const { return ! fail; }
+
+  // Return current error message for this stream.
+
+  std::string error (bool clear, int& err_num);
+
+protected:
+
+  int mode (void) const { return md; }
+
+  oct_mach_info::float_format float_format (void) const { return flt_fmt; }
+
+  // Set current error state and set fail to TRUE.
+
+  void error (const std::string& msg);
+  void error (const std::string& who, const std::string& msg);
+
+  // Clear any error message and set fail to FALSE.
+
+  void clear (void);
+
+  // Clear stream state.
+
+  void clearerr (void);
+
+private:
+
+  // A reference count.
+  octave_idx_type count;
+
+  // The permission bits for the file.  Should be some combination of
+  // std::ios::open_mode bits.
+  int md;
+
+  // Data format.
+  oct_mach_info::float_format flt_fmt;
+
+  // TRUE if an error has occurred.
+  bool fail;
+
+  // TRUE if this stream is open.
+  bool open_state;
+
+  // Should contain error message if fail is TRUE.
+  std::string errmsg;
+
+  // Functions that are defined for all input streams (input streams
+  // are those that define is).
+
+  std::string do_gets (octave_idx_type max_len, bool& err, bool strip_newline,
+		       const std::string& who /* = "gets" */);
+
+  std::string getl (octave_idx_type max_len, bool& err, const std::string& who /* = "getl" */);
+  std::string gets (octave_idx_type max_len, bool& err, const std::string& who /* = "gets" */);
+
+  octave_value do_scanf (scanf_format_list& fmt_list, octave_idx_type nr, octave_idx_type nc,
+			 bool one_elt_size_spec, octave_idx_type& count,
+			 const std::string& who /* = "scanf" */);
+
+  octave_value scanf (const std::string& fmt, const Array<double>& size,
+		      octave_idx_type& count, const std::string& who /* = "scanf" */);
+
+  bool do_oscanf (const scanf_format_elt *elt, octave_value&,
+		  const std::string& who /* = "scanf" */);
+
+  octave_value_list oscanf (const std::string& fmt,
+			    const std::string& who /* = "scanf" */);
+
+  // Functions that are defined for all output streams (output streams
+  // are those that define os).
+
+  int flush (void);
+
+  int do_printf (printf_format_list& fmt_list, const octave_value_list& args,
+		 const std::string& who /* = "printf" */);
+
+  int printf (const std::string& fmt, const octave_value_list& args,
+	      const std::string& who /* = "printf" */);
+
+  int puts (const std::string& s, const std::string& who /* = "puts" */);
+
+  // We can always do this in terms of seek(), so the derived class
+  // only has to provide that.
+
+  void invalid_operation (const std::string& who, const char *rw);
+
+  // No copying!
+
+  octave_base_stream (const octave_base_stream&);
+
+  octave_base_stream& operator = (const octave_base_stream&);
+};
+
+class
+OCTINTERP_API
+octave_stream
+{
+public:
+
+  octave_stream (octave_base_stream *bs = 0);
+
+  ~octave_stream (void);
+
+  octave_stream (const octave_stream&);
+
+  octave_stream& operator = (const octave_stream&);
+
+  int flush (void);
+
+  std::string getl (octave_idx_type max_len, bool& err, const std::string& who /* = "getl" */);
+  std::string getl (const octave_value& max_len, bool& err,
+		    const std::string& who /* = "getl" */);
+
+  std::string gets (octave_idx_type max_len, bool& err, const std::string& who /* = "gets" */);
+  std::string gets (const octave_value& max_len, bool& err,
+		    const std::string& who /* = "gets" */);
+
+  int seek (long offset, int origin);
+  int seek (const octave_value& offset, const octave_value& origin);
+
+  long tell (void);
+
+  int rewind (void);
+
+  bool is_open (void) const;
+
+  void close (void);
+
+  octave_value read (const Array<double>& size, octave_idx_type block_size,
+		     oct_data_conv::data_type input_type,
+		     oct_data_conv::data_type output_type,
+		     octave_idx_type skip, oct_mach_info::float_format flt_fmt,
+		     octave_idx_type& count);
+
+  octave_idx_type write (const octave_value& data, octave_idx_type block_size,
+	     oct_data_conv::data_type output_type,
+	     octave_idx_type skip, oct_mach_info::float_format flt_fmt);
+
+  template <class T>
+  octave_idx_type write (const Array<T>&, octave_idx_type block_size,
+	     oct_data_conv::data_type output_type,
+	     octave_idx_type skip, oct_mach_info::float_format flt_fmt);
+
+  octave_value scanf (const std::string& fmt, const Array<double>& size,
+		      octave_idx_type& count, const std::string& who /* = "scanf" */);
+
+  octave_value scanf (const octave_value& fmt, const Array<double>& size,
+		      octave_idx_type& count, const std::string& who /* = "scanf" */);
+
+  octave_value_list oscanf (const std::string& fmt,
+			    const std::string& who /* = "scanf" */);
+
+  octave_value_list oscanf (const octave_value& fmt,
+			    const std::string& who /* = "scanf" */);
+
+  int printf (const std::string& fmt, const octave_value_list& args,
+	      const std::string& who /* = "printf" */);
+
+  int printf (const octave_value& fmt, const octave_value_list& args,
+	      const std::string& who /* = "printf" */);
+
+  int puts (const std::string& s, const std::string& who /* = "puts" */);
+  int puts (const octave_value& s, const std::string& who /* = "puts" */);
+
+  bool eof (void) const;
+
+  std::string error (bool clear, int& err_num);
+
+  std::string error (bool clear = false)
+    {
+      int err_num;
+      return error (clear, err_num);
+    }
+
+  // Set the error message and state.
+
+  void error (const std::string& msg)
+    {
+      if (rep)
+	rep->error (msg);
+    }
+
+  void error (const char *msg) { error (std::string (msg)); }
+
+  int file_number (void) { return rep ? rep->file_number () : -1; }
+
+  bool is_valid (void) const { return (rep != 0); }
+
+  bool ok (void) const { return rep && rep->ok (); }
+
+  operator bool () const { return ok (); }
+
+  std::string name (void) const;
+
+  int mode (void) const;
+
+  oct_mach_info::float_format float_format (void) const;
+
+  static std::string mode_as_string (int mode);
+
+  std::istream *input_stream (void)
+  {
+    return rep ? rep->input_stream () : 0;
+  }
+
+  std::ostream *output_stream (void)
+  {
+    return rep ? rep->output_stream () : 0;
+  }
+
+  void clearerr (void) { if (rep) rep->clearerr (); }
+
+private:
+
+  // The actual representation of this stream.
+  octave_base_stream *rep;
+
+  bool stream_ok (bool clear = true) const
+    {
+      bool retval = true;
+
+      if (rep)
+	{
+	  if (clear)
+	    rep->clear ();
+	}
+      else
+	retval = false;
+
+      return retval;
+    }
+
+  void invalid_operation (const std::string& who, const char *rw)
+    {
+      if (rep)
+	rep->invalid_operation (who, rw);
+    }
+};
+
+class
+OCTINTERP_API
+octave_stream_list
+{
+protected:
+
+  octave_stream_list (void) : list (), lookup_cache (list.end ()) { }
+
+public:
+
+  ~octave_stream_list (void) { }
+
+  static bool instance_ok (void);
+
+  static int insert (octave_stream& os);
+
+  static octave_stream
+  lookup (int fid, const std::string& who = std::string ());
+
+  static octave_stream
+  lookup (const octave_value& fid, const std::string& who = std::string ());
+
+  static int remove (int fid, const std::string& who = std::string ());
+  static int remove (const octave_value& fid,
+		     const std::string& who = std::string ());
+
+  static void clear (bool flush = true);
+
+  static string_vector get_info (int fid);
+  static string_vector get_info (const octave_value& fid);
+
+  static std::string list_open_files (void);
+
+  static octave_value open_file_numbers (void);
+
+  static int get_file_number (const octave_value& fid);
+
+private:
+
+  typedef std::map<int, octave_stream> ostrl_map;
+
+  ostrl_map list;
+
+  mutable ostrl_map::const_iterator lookup_cache;
+
+  static octave_stream_list *instance;
+
+  int do_insert (octave_stream& os);
+
+  octave_stream do_lookup (int fid, const std::string& who = std::string ()) const;
+  octave_stream do_lookup (const octave_value& fid,
+			   const std::string& who = std::string ()) const;
+
+  int do_remove (int fid, const std::string& who = std::string ());
+  int do_remove (const octave_value& fid, const std::string& who = std::string ());
+
+  void do_clear (bool flush = true);
+
+  string_vector do_get_info (int fid) const;
+  string_vector do_get_info (const octave_value& fid) const;
+
+  std::string do_list_open_files (void) const;
+
+  octave_value do_open_file_numbers (void) const;
+
+  int do_get_file_number (const octave_value& fid) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-strstrm.cc b/src/oct-strstrm.cc
new file mode 100644
index 0000000..94fda53
--- /dev/null
+++ b/src/oct-strstrm.cc
@@ -0,0 +1,73 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-strstrm.h"
+
+// Position a stream at OFFSET relative to ORIGIN.
+
+int
+octave_base_strstream::seek (long, int)
+{
+  error ("fseek: invalid operation");
+  return -1;
+}
+
+// Return current stream position.
+
+long
+octave_base_strstream::tell (void)
+{
+  error ("ftell: invalid operation");
+  return -1;
+}
+
+octave_stream
+octave_istrstream::create (const char *data, std::ios::openmode arg_md,
+			   oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_istrstream (data, arg_md, flt_fmt));
+}
+
+octave_stream
+octave_istrstream::create (const std::string& data, std::ios::openmode arg_md,
+			   oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_istrstream (data, arg_md, flt_fmt));
+}
+
+octave_stream
+octave_ostrstream::create (std::ios::openmode arg_md,
+			   oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_ostrstream (arg_md, flt_fmt));
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct-strstrm.h b/src/oct-strstrm.h
new file mode 100644
index 0000000..4da49ca
--- /dev/null
+++ b/src/oct-strstrm.h
@@ -0,0 +1,181 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_strstream_h)
+#define octave_octave_strstream_h 1
+
+#include <string>
+#include <sstream>
+
+#include "oct-stream.h"
+
+class
+octave_base_strstream : public octave_base_stream
+{
+public:
+
+  octave_base_strstream (std::ios::openmode m = std::ios::out,
+			 oct_mach_info::float_format ff
+			   = oct_mach_info::native_float_format ())
+    : octave_base_stream (m, ff) { }
+
+  // Position a stream at OFFSET relative to ORIGIN.
+
+  int seek (long, int);
+
+  // Return current stream position.
+
+  long tell (void);
+
+  // The name of the file.
+
+  std::string name (void) const { return std::string (); }
+
+  virtual std::streambuf *rdbuf (void) = 0;
+
+  virtual bool bad (void) const = 0;
+
+  virtual void clear (void) = 0;
+
+protected:
+
+  ~octave_base_strstream (void) { }
+
+private:
+
+  // No copying!
+
+  octave_base_strstream (const octave_base_strstream&);
+
+  octave_base_strstream& operator = (const octave_base_strstream&);
+};
+
+class
+octave_istrstream : public octave_base_strstream
+{
+public:
+
+  octave_istrstream (const char *data,
+		     std::ios::openmode arg_md = std::ios::out,
+		     oct_mach_info::float_format ff
+		       = oct_mach_info::native_float_format ())
+    : octave_base_strstream (arg_md, ff), is (data) { }
+
+  octave_istrstream (const std::string& data,
+		     std::ios::openmode arg_md = std::ios::out,
+		     oct_mach_info::float_format ff
+		       = oct_mach_info::native_float_format ())
+    : octave_base_strstream (arg_md, ff), is (data.c_str ()) { }
+
+  static octave_stream
+  create (const char *data, std::ios::openmode arg_md = std::ios::out,
+	  oct_mach_info::float_format ff
+	    = oct_mach_info::native_float_format ());
+
+  static octave_stream
+  create (const std::string& data, std::ios::openmode arg_md = std::ios::out,
+	  oct_mach_info::float_format ff
+	    = oct_mach_info::native_float_format ());
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const { return is.eof (); }
+
+  std::istream *input_stream (void) { return &is; }
+
+  std::ostream *output_stream (void) { return 0; }
+
+  std::streambuf *rdbuf (void) { return is ? is.rdbuf () : 0; }
+
+  bool bad (void) const { return is.bad (); }
+
+  void clear (void) { is.clear (); }
+
+protected:
+
+  ~octave_istrstream (void) { }
+
+private:
+
+  std::istringstream is;
+
+  // No copying!
+
+  octave_istrstream (const octave_istrstream&);
+
+  octave_istrstream& operator = (const octave_istrstream&);
+};
+
+class
+octave_ostrstream : public octave_base_strstream
+{
+public:
+
+  octave_ostrstream (std::ios::openmode arg_md = std::ios::out,
+		     oct_mach_info::float_format ff
+		       = oct_mach_info::native_float_format ())
+    : octave_base_strstream (arg_md, ff) { }
+
+  static octave_stream
+  create (std::ios::openmode arg_md = std::ios::out,
+	  oct_mach_info::float_format ff
+	    = oct_mach_info::native_float_format ());
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const { return os.eof (); }
+
+  std::istream *input_stream (void) { return 0; }
+
+  std::ostream *output_stream (void) { return &os; }
+
+  std::string str (void) { return os.str (); }
+
+  std::streambuf *rdbuf (void) { return os ? os.rdbuf () : 0; }
+
+  bool bad (void) const { return os.bad (); }
+
+  void clear (void) { os.clear (); }
+
+protected:
+
+  ~octave_ostrstream (void) { }
+
+private:
+
+  std::ostringstream os;
+
+  // No copying!
+
+  octave_ostrstream (const octave_ostrstream&);
+
+  octave_ostrstream& operator = (const octave_ostrstream&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/oct.h b/src/oct.h
new file mode 100644
index 0000000..ab8bcec
--- /dev/null
+++ b/src/oct.h
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2004, 2005, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_h)
+#define octave_oct_h 1
+
+// Things that are often included to create .oct files.
+
+// config.h needs to be first because it includes #defines that can */
+// affect other header files.
+
+#include "config.h"
+
+#include "Matrix.h"
+
+#include "oct-locbuf.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "help.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "utils.h"
+#include "variables.h"
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/octave.cc b/src/octave.cc
new file mode 100644
index 0000000..fc6b588
--- /dev/null
+++ b/src/octave.cc
@@ -0,0 +1,968 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Born February 20, 1992.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+
+#include <fstream>
+#include <iostream>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "f77-fcn.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "lo-error.h"
+#include "oct-env.h"
+#include "pathsearch.h"
+#include "str-vec.h"
+
+#include <defaults.h>
+#include "Cell.h"
+#include "defun.h"
+#include "display.h"
+#include "error.h"
+#include "file-io.h"
+#include "input.h"
+#include "lex.h"
+#include "load-path.h"
+#include "octave.h"
+#include "oct-hist.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "ops.h"
+#include "toplev.h"
+#include "parse.h"
+#include "procstream.h"
+#include "prog-args.h"
+#include "sighandlers.h"
+#include "sysdep.h"
+#include "ov.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include <version.h>
+
+// Kluge.
+extern "C" F77_RET_T
+F77_FUNC (xerbla, XERBLA) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&
+			   F77_CHAR_ARG_LEN_DECL);
+
+extern void install_builtins (void);
+
+#if !defined (HAVE_ATEXIT) && defined (HAVE_ON_EXIT)
+extern "C" int on_exit ();
+#define atexit on_exit
+#endif
+
+// The command-line options.
+static string_vector octave_argv;
+
+// The name used to invoke Octave.
+static std::string
+octave_program_invocation_name;
+
+// The last component of octave_program_invocation_name.
+static std::string octave_program_name;
+
+// TRUE means we read ~/.octaverc and ./.octaverc.
+// (--norc; --no-init-file; -f)
+static bool read_init_files = true;
+
+// TRUE means we read the site-wide octaverc files.
+// (--norc; --no-site-file; -f)
+static bool read_site_files = true;
+
+// TRUE means we set the initial path to configured defaults.
+// (--no-init-path)
+static bool set_initial_path = true;
+
+// TRUE means we don't print the usual startup message.
+// (--quiet; --silent; -q)
+static bool inhibit_startup_message = false;
+
+// TRUE means we turn on compatibility options.
+// (--traditional)
+static bool traditional = false;
+
+// If TRUE, print verbose info in some cases.
+// (--verbose; -V)
+static bool verbose_flag = false;
+
+// Usage message
+static const char *usage_string = 
+  "octave [-?HVdfhiqvx] [--debug] [--echo-commands] [--eval CODE]\n\
+       [--exec-path path] [--help] [--image-path path] [--info-file file]\n\
+       [--info-program prog] [--interactive] [--line-editing] [--no-history] [--no-init-file]\n\
+       [--no-line-editing] [--no-site-file] [--no-init-path] [--no-window-system] [-p path]\n\
+       [--path path] [--silent] [--traditional] [--verbose] [--version] [file]";
+
+// This is here so that it's more likely that the usage message and
+// the real set of options will agree.  Note: the `+' must come first
+// to prevent getopt from permuting arguments!
+static const char *short_opts = "+?HVdfhip:qvx";
+
+// The code to evaluate at startup (--eval CODE)
+static std::string code_to_eval;
+
+// If TRUE, don't exit after evaluating code given by --eval option.
+static bool persist = false;
+
+// Long options.  See the comments in getopt.h for the meanings of the
+// fields in this structure.
+#define DOC_CACHE_FILE_OPTION 1
+#define EVAL_OPTION 2
+#define EXEC_PATH_OPTION 3
+#define IMAGE_PATH_OPTION 4
+#define INFO_FILE_OPTION 5
+#define INFO_PROG_OPTION 6
+#define NO_INIT_FILE_OPTION 7
+#define NO_LINE_EDITING_OPTION 8
+#define NO_SITE_FILE_OPTION 9
+#define NO_INIT_PATH_OPTION 10
+#define PERSIST_OPTION 11
+#define TRADITIONAL_OPTION 12
+#define LINE_EDITING_OPTION 13
+#define NO_WINDOW_SYSTEM_OPTION 14
+long_options long_opts[] =
+  {
+    { "debug",            prog_args::no_arg,       0, 'd' },
+    { "braindead",        prog_args::no_arg,       0, TRADITIONAL_OPTION },
+    { "doc-cache-file",   prog_args::required_arg, 0, DOC_CACHE_FILE_OPTION },
+    { "echo-commands",    prog_args::no_arg,       0, 'x' },
+    { "eval",             prog_args::required_arg, 0, EVAL_OPTION },
+    { "exec-path",        prog_args::required_arg, 0, EXEC_PATH_OPTION },
+    { "help",             prog_args::no_arg,       0, 'h' },
+    { "image-path",       prog_args::required_arg, 0, IMAGE_PATH_OPTION },
+    { "info-file",        prog_args::required_arg, 0, INFO_FILE_OPTION },
+    { "info-program",     prog_args::required_arg, 0, INFO_PROG_OPTION },
+    { "interactive",      prog_args::no_arg,       0, 'i' },
+    { "line-editing",     prog_args::no_arg,       0, LINE_EDITING_OPTION },
+    { "no-history",       prog_args::no_arg,       0, 'H' },
+    { "no-init-file",     prog_args::no_arg,       0, NO_INIT_FILE_OPTION },
+    { "no-line-editing",  prog_args::no_arg,       0, NO_LINE_EDITING_OPTION },
+    { "no-site-file",     prog_args::no_arg,       0, NO_SITE_FILE_OPTION },
+    { "no-init-path",     prog_args::no_arg,       0, NO_INIT_PATH_OPTION },
+    { "no-window-system", prog_args::no_arg,       0, NO_WINDOW_SYSTEM_OPTION },
+    { "norc",             prog_args::no_arg,       0, 'f' },
+    { "path",             prog_args::required_arg, 0, 'p' },
+    { "persist",          prog_args::no_arg,       0, PERSIST_OPTION },
+    { "quiet",            prog_args::no_arg,       0, 'q' },
+    { "silent",           prog_args::no_arg,       0, 'q' },
+    { "traditional",      prog_args::no_arg,       0, TRADITIONAL_OPTION },
+    { "verbose",          prog_args::no_arg,       0, 'V' },
+    { "version",          prog_args::no_arg,       0, 'v' },
+    { 0,                  0,                       0, 0 }
+  };
+
+// Store the command-line options for later use.
+
+static void
+intern_argv (int argc, char **argv)
+{
+  assert (symbol_table::at_top_level ());
+
+  symbol_table::varref (".nargin.") = argc - 1;
+
+  symbol_table::mark_hidden (".nargin.");
+
+  if (argc > 1)
+    {
+      octave_argv.resize (argc - 1);
+
+      // Skip program name in argv.
+      int i = argc;
+      while (--i > 0)
+	octave_argv[i-1] = *(argv+i);
+    }
+}
+
+static void
+initialize_pathsearch (void)
+{
+  // This may seem odd, but doing it this way means that we don't have
+  // to modify the kpathsea library...
+
+  std::string odb = octave_env::getenv ("OCTAVE_DB_PATH");
+
+  // For backward compatibility.
+
+  if (odb.empty ())
+    odb = octave_env::getenv ("OCTAVE_DB_DIR");
+
+  if (odb.empty ())
+    odb = Vdata_dir + file_ops::dir_sep_str () + "octave:"
+      + Vlibexec_dir + file_ops::dir_sep_str () + "octave";
+}
+
+DEFUN (__version_info__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {retval =} __version_info__ (@var{name}, @var{version}, @var{release}, @var{date})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  static Octave_map vinfo;
+
+  int nargin = args.length ();
+
+  if (nargin == 4)
+    {
+      if (vinfo.nfields () == 0)
+	{
+	  vinfo.assign ("Name", args (0));
+	  vinfo.assign ("Version", args (1));
+	  vinfo.assign ("Release", args (2));
+	  vinfo.assign ("Date", args (3));
+	}
+      else
+	{
+	  octave_idx_type n = vinfo.numel () + 1;
+
+	  vinfo.resize (dim_vector (n, 1));
+
+	  octave_value idx (n);
+
+	  vinfo.assign (idx, "Name", Cell (octave_value (args (0))));
+	  vinfo.assign (idx, "Version", Cell (octave_value (args (1))));
+	  vinfo.assign (idx, "Release", Cell (octave_value (args (2))));
+	  vinfo.assign (idx, "Date", Cell (octave_value (args (3))));
+	}
+    }
+  else if (nargin == 0)
+    retval = vinfo;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static void
+initialize_version_info (void)
+{
+  octave_value_list args;
+
+  args(3) = OCTAVE_RELEASE_DATE;
+  args(2) = OCTAVE_RELEASE;
+  args(1) = OCTAVE_VERSION;
+  args(0) = "GNU Octave";
+
+  F__version_info__ (args, 0);
+}
+
+// Initialize by reading startup files.
+
+static void
+execute_startup_files (void)
+{
+  unwind_protect::begin_frame ("execute_startup_files");
+
+  unwind_protect_bool (input_from_startup_file);
+
+  input_from_startup_file = true;
+
+  std::string context;
+
+  bool verbose = (verbose_flag && ! inhibit_startup_message);
+
+  bool require_file = false;
+
+  if (read_site_files)
+    {
+      // Execute commands from the site-wide configuration file.
+      // First from the file $(prefix)/lib/octave/site/m/octaverc
+      // (if it exists), then from the file
+      // $(prefix)/share/octave/$(version)/m/octaverc (if it exists).
+
+      source_file (Vlocal_site_defaults_file, context, verbose, require_file);
+
+      source_file (Vsite_defaults_file, context, verbose, require_file);
+    }
+
+  if (read_init_files)
+    {
+      // Try to execute commands from $HOME/$OCTAVE_INITFILE and
+      // $OCTAVE_INITFILE.  If $OCTAVE_INITFILE is not set, .octaverc
+      // is assumed.
+
+      bool home_rc_already_executed = false;
+
+      std::string initfile = octave_env::getenv ("OCTAVE_INITFILE");
+
+      if (initfile.empty ())
+	initfile = ".octaverc";
+
+      std::string home_dir = octave_env::get_home_directory ();
+
+      std::string home_rc = octave_env::make_absolute (initfile, home_dir);
+
+      std::string local_rc;
+
+      if (! home_rc.empty ())
+	{
+	  source_file (home_rc, context, verbose, require_file);
+
+	  // Names alone are not enough.
+
+	  file_stat fs_home_rc (home_rc);
+
+	  if (fs_home_rc)
+	    {
+	      // We want to check for curr_dir after executing home_rc
+	      // because doing that may change the working directory.
+
+	      std::string curr_dir = octave_env::getcwd ();
+
+	      local_rc = octave_env::make_absolute (initfile, curr_dir);
+
+	      home_rc_already_executed = same_file (home_rc, local_rc);
+	    }
+	}
+
+      if (! home_rc_already_executed)
+	{
+	  if (local_rc.empty ())
+	    {
+	      std::string curr_dir = octave_env::getcwd ();
+
+	      local_rc = octave_env::make_absolute (initfile, curr_dir);
+	    }
+
+	  source_file (local_rc, context, verbose, require_file);
+	}
+    }
+
+  unwind_protect::run_frame ("execute_startup_files");
+}
+
+static int
+execute_eval_option_code (const std::string& code)
+{
+  unwind_protect::begin_frame ("execute_eval_option_code");
+
+  octave_save_signal_mask ();
+
+  can_interrupt = true;
+
+  octave_signal_hook = octave_signal_handler;
+  octave_interrupt_hook = unwind_protect::run_all;
+  octave_bad_alloc_hook = unwind_protect::run_all;
+
+  octave_catch_interrupts ();
+
+  octave_initialized = true;
+
+  unwind_protect_bool (interactive);
+
+  interactive = false;
+
+  int parse_status = 0;
+
+  try
+    {
+      eval_string (code, false, parse_status, 0);
+    }
+  catch (octave_interrupt_exception)
+    {
+      recover_from_exception ();
+      octave_stdout << "\n";
+      if (quitting_gracefully)
+        clean_up_and_exit (exit_status);
+    }
+  catch (std::bad_alloc)
+    {
+      std::cerr << "error: memory exhausted or requested size too large for range of Octave's index type -- eval failed"
+		<< std::endl;
+    }
+
+  unwind_protect::run_frame ("execute_eval_option_code");
+
+  return parse_status;
+}
+
+static void
+execute_command_line_file (const std::string& fname)
+{
+  unwind_protect::begin_frame ("execute_command_line_file");
+
+  octave_save_signal_mask ();
+
+  can_interrupt = true;
+
+  octave_signal_hook = octave_signal_handler;
+  octave_interrupt_hook = unwind_protect::run_all;
+  octave_bad_alloc_hook = unwind_protect::run_all;
+
+  octave_catch_interrupts ();
+
+  octave_initialized = true;
+
+  unwind_protect_bool (interactive);
+  unwind_protect_bool (reading_script_file);
+  unwind_protect_bool (input_from_command_line_file);
+
+  unwind_protect_str (curr_fcn_file_name);
+  unwind_protect_str (curr_fcn_file_full_name);
+
+  unwind_protect_str (octave_program_invocation_name);
+  unwind_protect_str (octave_program_name);
+
+  interactive = false;
+  reading_script_file = true;
+  input_from_command_line_file = true;
+
+  curr_fcn_file_name = fname;
+  curr_fcn_file_full_name = curr_fcn_file_name;
+
+  octave_program_invocation_name = curr_fcn_file_name;
+
+  size_t pos = curr_fcn_file_name.find_last_of (file_ops::dir_sep_chars ());
+  
+  std::string tmp = (pos != std::string::npos)
+    ? curr_fcn_file_name.substr (pos+1) : curr_fcn_file_name;
+
+  octave_program_name = tmp;
+
+  try
+    {
+      std::string context;
+      bool verbose = false;
+      bool require_file = true;
+
+      source_file (fname, context, verbose, require_file, "octave");
+    }
+  catch (octave_interrupt_exception)
+    {
+      recover_from_exception ();
+      octave_stdout << "\n";
+      if (quitting_gracefully)
+        clean_up_and_exit (exit_status);
+    }
+  catch (std::bad_alloc)
+    {
+      std::cerr << "error: memory exhausted or requested size too large for range of Octave's index type -- execution of "
+		<< fname << " failed" << std::endl;
+    }
+ 
+  unwind_protect::run_frame ("execute_command_line_file");
+}
+
+// Usage message with extra help.
+
+static void
+verbose_usage (void)
+{
+  std::cout << OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY "\n\
+\n\
+Usage: octave [options]\n\
+\n\
+Options:\n\
+\n\
+  --debug, -d             Enter parser debugging mode.\n\
+  --doc-cache-file FILE   Use doc cache file FILE.\n\
+  --echo-commands, -x     Echo commands as they are executed.\n\
+  --eval CODE             Evaluate CODE.  Exit when done unless --persist.\n\
+  --exec-path PATH        Set path for executing subprograms.\n\
+  --help, -h, -?          Print short help message and exit.\n\
+  --image-path PATH       Add PATH to head of image search path.\n\
+  --info-file FILE        Use top-level info file FILE.\n\
+  --info-program PROGRAM  Use PROGRAM for reading info files.\n\
+  --interactive, -i       Force interactive behavior.\n\
+  --line-editing          Force readline use for command-line editing.\n\
+  --no-history, -H        Don't save commands to the history list\n\
+  --no-init-file          Don't read the ~/.octaverc or .octaverc files.\n\
+  --no-init-path          Don't initialize function search path.\n\
+  --no-line-editing       Don't use readline for command-line editing.\n\
+  --no-site-file          Don't read the site-wide octaverc file.\n\
+  --no-window-system      Disable window system, including graphics.\n\
+  --norc, -f              Don't read any initialization files.\n\
+  --path PATH, -p PATH    Add PATH to head of function search path.\n\
+  --persist               Go interactive after --eval or reading from FILE.\n\
+  --silent, -q            Don't print message at startup.\n\
+  --traditional           Set variables for closer MATLAB compatibility.\n\
+  --verbose, -V           Enable verbose output in some cases.\n\
+  --version, -v           Print version number and exit.\n\
+\n\
+  FILE                    Execute commands from FILE.  Exit when done\n\
+                          unless --persist is also specified.\n\
+\n"
+OCTAVE_WWW_STATEMENT "\n\
+\n"
+OCTAVE_CONTRIB_STATEMENT "\n\
+\n"
+OCTAVE_BUGS_STATEMENT "\n";
+
+  exit (0);
+}
+
+// Terse usage messsage.
+
+static void
+usage (void)
+{
+  std::cerr << "usage: " << usage_string << "\n";
+  exit (1);
+}
+
+static void
+print_version_and_exit (void)
+{
+  std::cout << OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS "\n";
+  exit (0);
+}
+
+static void
+lo_error_handler (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror (fmt, args);
+  va_end (args);
+
+  octave_throw_execution_exception ();
+}
+
+static void
+initialize_error_handlers ()
+{
+  set_liboctave_error_handler (lo_error_handler);
+  set_liboctave_warning_handler (warning);
+  set_liboctave_warning_with_id_handler (warning_with_id);
+}
+
+// What happens on --traditional.
+
+static void
+maximum_braindamage (void)
+{
+  persist = true;
+
+  bind_internal_variable ("PS1", ">> ");
+  bind_internal_variable ("PS2", "");
+  bind_internal_variable ("beep_on_error", true);
+  bind_internal_variable ("confirm_recursive_rmdir", false);
+  bind_internal_variable ("crash_dumps_octave_core", false);
+  bind_internal_variable ("default_save_options", "-mat-binary");
+  bind_internal_variable ("fixed_point_format", true);
+  bind_internal_variable ("history_timestamp_format_string",
+			 "%%-- %D %I:%M %p --%%");
+  bind_internal_variable ("page_screen_output", false);
+  bind_internal_variable ("print_empty_dimensions", false);
+
+  disable_warning ("Octave:fopen-file-in-path");
+  disable_warning ("Octave:function-name-clash");
+  disable_warning ("Octave:load-file-in-path");
+}
+
+// You guessed it.
+
+int
+octave_main (int argc, char **argv, int embedded)
+{
+  octave_env::set_program_name (argv[0]);
+
+  octave_program_invocation_name = octave_env::get_program_invocation_name ();
+  octave_program_name = octave_env::get_program_name ();
+
+  // The order of these calls is important.  The call to
+  // install_defaults must come before install_builtins because
+  // default variable values must be available for the variables to be
+  // installed, and the call to install_builtins must come before the
+  // options are processed because some command line options override
+  // defaults by calling bind_internal_variable.
+
+  init_signals ();
+
+  sysdep_init ();
+
+  // The idea here is to force xerbla to be referenced so that we will
+  // link to our own version instead of the one provided by the BLAS
+  // library.  But octave_NaN should never be -1, so we should never
+  // actually call xerbla.
+
+  if (octave_NaN == -1)
+    F77_FUNC (xerbla, XERBLA) ("octave", 13, 6L);
+
+  initialize_error_handlers ();
+
+  initialize_default_warning_state ();
+
+  install_defaults ();
+
+  initialize_pathsearch ();
+
+  if (! embedded)
+    install_signal_handlers ();
+  else
+    quit_allowed = false;
+
+  initialize_file_io ();
+
+  install_types ();
+
+  install_ops ();
+
+  install_builtins ();
+
+  prog_args args (argc, argv, short_opts, long_opts);
+
+  bool forced_line_editing = false;
+
+  bool read_history_file = true;
+
+  int optc;
+  while ((optc = args.getopt ()) != EOF)
+    {
+      switch (optc)
+	{
+	case 'H':
+	  read_history_file = false;
+	  bind_internal_variable ("saving_history", false);
+	  break;
+
+	case 'V':
+	  verbose_flag = true;
+	  break;
+
+	case 'd':
+	  // This is the same as yydebug in parse.y.
+	  octave_debug++;
+	  break;
+
+	case 'f':
+	  read_init_files = false;
+	  read_site_files = false;
+	  break;
+
+	case 'h':
+	case '?':
+	  verbose_usage ();
+	  break;
+
+	case 'i':
+	  forced_interactive = true;
+	  break;
+
+	case 'p':
+	  if (args.optarg ())
+	    load_path::set_command_line_path (args.optarg ());
+	  break;
+
+	case 'q':
+	  inhibit_startup_message = true;
+	  break;
+
+	case 'x':
+	  {
+	    double tmp = (ECHO_SCRIPTS | ECHO_FUNCTIONS | ECHO_CMD_LINE);
+	    bind_internal_variable ("echo_executing_commands", tmp);
+	  }
+	  break;
+
+	case 'v':
+	  print_version_and_exit ();
+	  break;
+
+	case DOC_CACHE_FILE_OPTION:
+	  if (args.optarg ())
+	    bind_internal_variable ("doc_cache_file", args.optarg ());
+	  break;
+
+	case EVAL_OPTION:
+	  if (args.optarg ())
+	    {
+	      if (code_to_eval.empty ())
+		code_to_eval = args.optarg ();
+	      else
+		code_to_eval += std::string (" ") + args.optarg ();
+	    }
+	  break;
+
+	case EXEC_PATH_OPTION:
+	  if (args.optarg ())
+	    set_exec_path (args.optarg ());
+	  break;
+
+	case IMAGE_PATH_OPTION:
+	  if (args.optarg ())
+	    set_image_path (args.optarg ());
+	  break;
+
+	case INFO_FILE_OPTION:
+	  if (args.optarg ())
+	    bind_internal_variable ("info_file", args.optarg ());
+	  break;
+
+	case INFO_PROG_OPTION:
+	  if (args.optarg ())
+	    bind_internal_variable ("info_program", args.optarg ());
+	  break;
+
+	case LINE_EDITING_OPTION:
+	  forced_line_editing = true;
+	  break;
+
+	case NO_INIT_FILE_OPTION:
+	  read_init_files = false;
+	  break;
+
+	case NO_LINE_EDITING_OPTION:
+	  line_editing = false;
+	  break;
+
+	case NO_SITE_FILE_OPTION:
+	  read_site_files = 0;
+	  break;
+
+	case NO_INIT_PATH_OPTION:
+	  set_initial_path = false;
+	  break;
+
+	case NO_WINDOW_SYSTEM_OPTION:
+	  display_info::no_window_system ();
+	  break;
+
+	case TRADITIONAL_OPTION:
+	  traditional = true;
+	  break;
+
+	case PERSIST_OPTION:
+	  persist = true;
+	  break;
+
+	default:
+	  usage ();
+	  break;
+	}
+    }
+
+#if defined (HAVE_ATEXIT) || defined (HAVE_ON_EXIT)
+  // Make sure we clean up when we exit.  Also allow users to register
+  // functions.  If we don't have atexit or on_exit, we're going to
+  // leave some junk files around if we exit abnormally.
+
+  atexit (do_octave_atexit);
+#endif
+
+  // Is input coming from a terminal?  If so, we are probably
+  // interactive.
+
+  interactive = (! embedded
+		 && isatty (fileno (stdin)) && isatty (fileno (stdout)));
+
+  if (! interactive && ! forced_line_editing)
+    line_editing = false;
+
+  // Force default line editor if we don't want readline editing.
+  if (! line_editing)
+    command_editor::force_default_editor ();
+
+  // These can come after command line args since none of them set any
+  // defaults that might be changed by command line options.
+
+  if (line_editing)
+    initialize_command_input ();
+
+  if (! inhibit_startup_message)
+    std::cout << OCTAVE_STARTUP_MESSAGE "\n" << std::endl;
+
+  if (traditional)
+    maximum_braindamage ();
+
+  octave_interpreter_ready = true;
+
+  initialize_version_info ();
+
+  // Make all command-line arguments available to startup files,
+  // including PKG_ADD files.
+
+  intern_argv (argc, argv);
+
+  load_path::initialize (set_initial_path);
+
+  execute_startup_files ();
+
+  initialize_history (read_history_file);
+
+  if (! inhibit_startup_message && reading_startup_message_printed)
+    std::cout << std::endl;
+
+  // If there is an extra argument, see if it names a file to read.
+  // Additional arguments are taken as command line options for the
+  // script.
+
+  int last_arg_idx = args.optind ();
+
+  int remaining_args = argc - last_arg_idx;
+
+  if (! code_to_eval.empty ())
+    {
+      int parse_status = execute_eval_option_code (code_to_eval);
+
+      if (! (persist || remaining_args > 0))
+	clean_up_and_exit (parse_status || error_state ? 1 : 0);
+    }
+
+  if (remaining_args > 0)
+    {
+      // If we are running an executable script (#! /bin/octave) then
+      // we should only see the args passed to the script.
+
+      intern_argv (remaining_args, argv+last_arg_idx);
+
+      execute_command_line_file (argv[last_arg_idx]);
+
+      if (! persist)
+	clean_up_and_exit (error_state ? 1 : 0);
+    }
+
+  // Avoid counting commands executed from startup files.
+
+  command_editor::reset_current_command_number (1);
+
+  // Now argv should have the full set of args.
+  intern_argv (argc, argv);
+
+  if (! embedded)
+    switch_to_buffer (create_buffer (get_input_from_stdin ()));
+
+  // Force input to be echoed if not really interactive, but the user
+  // has forced interactive behavior.
+
+  if (! interactive && forced_interactive)
+    {
+      command_editor::blink_matching_paren (false);
+
+      // FIXME -- is this the right thing to do?
+
+      bind_internal_variable ("echo_executing_commands", ECHO_CMD_LINE);
+    }
+
+  if (embedded)
+    {
+      // FIXME -- do we need to do any cleanup here before
+      // returning?  If we don't, what will happen to Octave functions
+      // that have been registered to execute with atexit, for example?
+
+      return 1;
+    }
+
+  int retval = main_loop ();
+
+  if (retval == 1 && ! error_state)
+    retval = 0;
+
+  clean_up_and_exit (retval);
+
+  return 0;
+}
+
+DEFUN (argv, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} argv ()\n\
+Return the command line arguments passed to Octave.  For example,\n\
+if you invoked Octave using the command\n\
+\n\
+ at example\n\
+octave --no-line-editing --silent\n\
+ at end example\n\
+\n\
+ at noindent\n\
+ at code{argv} would return a cell array of strings with the elements\n\
+ at code{--no-line-editing} and @code{--silent}.\n\
+\n\
+If you write an executable Octave script, @code{argv} will return the\n\
+list of arguments passed to the script.  @xref{Executable Octave Programs},\n\
+for an example of how to create an executable Octave script.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = Cell (octave_argv);
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (program_invocation_name, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} program_invocation_name ()\n\
+Return the name that was typed at the shell prompt to run Octave.\n\
+\n\
+If executing a script from the command line (e.g., @code{octave foo.m})\n\
+or using an executable Octave script, the program name is set to the\n\
+name of the script.  @xref{Executable Octave Programs}, for an example of\n\
+how to create an executable Octave script.\n\
+ at seealso{program_name}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = octave_program_invocation_name;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (program_name, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} program_name ()\n\
+Return the last component of the value returned by\n\
+ at code{program_invocation_name}.\n\
+ at seealso{program_invocation_name}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = octave_program_name;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/octave.gperf b/src/octave.gperf
new file mode 100644
index 0000000..8f6f1c2
--- /dev/null
+++ b/src/octave.gperf
@@ -0,0 +1,94 @@
+%{
+/*
+
+Copyright (C) 1995, 1997, 1998, 2000, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+NOTE: gperf 2.7.2 will silently generate bad code if there are blank
+lines following the "%{" marker above.  This comment block seems to be
+handled correctly.
+
+*/
+enum octave_kw_id
+{
+  break_kw,
+  case_kw,
+  catch_kw,
+  continue_kw,
+  do_kw,
+  else_kw,
+  elseif_kw,
+  end_kw,
+  end_try_catch_kw,
+  end_unwind_protect_kw,
+  endfor_kw,
+  endfunction_kw,
+  endif_kw,
+  endswitch_kw,
+  endwhile_kw,
+  for_kw,
+  function_kw,
+  global_kw,
+  if_kw,
+  magic_file_kw,
+  magic_line_kw,
+  otherwise_kw,
+  return_kw,
+  static_kw,
+  switch_kw,
+  try_kw,
+  until_kw,
+  unwind_protect_kw,
+  unwind_protect_cleanup_kw,
+  while_kw
+};
+%}
+struct octave_kw { const char *name; int tok; octave_kw_id kw_id; };
+%%
+break, BREAK, break_kw
+case, CASE, case_kw
+catch, CATCH, catch_kw
+continue, CONTINUE, continue_kw
+do, DO, do_kw
+else, ELSE, else_kw
+elseif, ELSEIF, elseif_kw
+end, END, end_kw
+end_try_catch, END, end_try_catch_kw
+end_unwind_protect, END, end_unwind_protect_kw
+endfor, END, endfor_kw
+endfunction, END, endfunction_kw
+endif, END, endif_kw
+endswitch, END, endswitch_kw
+endwhile, END, endwhile_kw
+for, FOR, for_kw
+function, FCN, function_kw
+global, GLOBAL, global_kw
+if, IF, if_kw
+otherwise, OTHERWISE, otherwise_kw
+persistent, STATIC, static_kw
+return, FUNC_RET, return_kw
+static, STATIC, static_kw
+switch, SWITCH, switch_kw
+try, TRY, try_kw
+until, UNTIL, until_kw
+unwind_protect, UNWIND, unwind_protect_kw
+unwind_protect_cleanup, CLEANUP, unwind_protect_cleanup_kw
+while, WHILE, while_kw
+__FILE__, DQ_STRING, magic_file_kw
+__LINE__, NUM, magic_line_kw
diff --git a/src/octave.h b/src/octave.h
new file mode 100644
index 0000000..617f8eb
--- /dev/null
+++ b/src/octave.h
@@ -0,0 +1,42 @@
+/*
+
+Copyright (C) 2002, 2003, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_octave_h)
+#define octave_octave_h 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern OCTINTERP_API int octave_main (int argc, char **argv, int embedded);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ops.h b/src/ops.h
new file mode 100644
index 0000000..0df01bd
--- /dev/null
+++ b/src/ops.h
@@ -0,0 +1,440 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ops_h)
+#define octave_ops_h 1
+
+#include "Array-util.h"
+
+// Concatenation macros that enforce argument prescan
+#define CONCAT2X(x,y) x ## y
+#define CONCAT2(x,y) CONCAT2X(x,y)
+
+#define CONCAT3X(x,y,z) x ## y ## z
+#define CONCAT3(x,y,z) CONCAT3X(x,y,z)
+
+extern void install_ops (void);
+
+#define INSTALL_UNOP(op, t, f) \
+  octave_value_typeinfo::register_unary_op \
+    (octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
+
+#define INSTALL_NCUNOP(op, t, f) \
+  octave_value_typeinfo::register_non_const_unary_op \
+    (octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
+
+#define INSTALL_BINOP(op, t1, t2, f) \
+  octave_value_typeinfo::register_binary_op \
+    (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
+     CONCAT2(oct_binop_, f));
+
+#define INSTALL_CATOP(t1, t2, f) \
+  octave_value_typeinfo::register_cat_op \
+    (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_catop_, f));
+
+#define INSTALL_ASSIGNOP(op, t1, t2, f) \
+  octave_value_typeinfo::register_assign_op \
+    (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
+     CONCAT2(oct_assignop_, f));
+
+#define INSTALL_ASSIGNANYOP(op, t1, f) \
+  octave_value_typeinfo::register_assignany_op \
+    (octave_value::op, t1::static_type_id (), CONCAT2(oct_assignop_, f));
+
+#define INSTALL_ASSIGNCONV(t1, t2, tr) \
+  octave_value_typeinfo::register_pref_assign_conv \
+    (t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
+
+#define INSTALL_CONVOP(t1, t2, f) \
+  octave_value_typeinfo::register_type_conv_op \
+    (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
+
+#define INSTALL_WIDENOP(t1, t2, f) \
+  octave_value_typeinfo::register_widening_op \
+    (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
+
+#define BOOL_OP1(xt, xn, get_x, yt, yn, get_y) \
+  xt xn = get_x; \
+  yt yn = get_y;
+
+#define BOOL_OP2(x) \
+  octave_idx_type nr = x.rows (); \
+  octave_idx_type nc = x.columns ();
+
+#define BOOL_OP3(test) \
+  boolMatrix retval (nr, nc); \
+  for (octave_idx_type j = 0; j < nc; j++) \
+    for (octave_idx_type i = 0; i < nr; i++) \
+      retval (i, j) = test; \
+  return retval;
+
+#define SC_MX_BOOL_OP(st, sn, get_s, mt, mn, get_m, test, empty_result) \
+  do \
+    { \
+      BOOL_OP1 (st, sn, get_s, mt, mn, get_m) \
+      BOOL_OP2 (mn) \
+      if (nr == 0 || nc == 0) \
+        return empty_result; \
+      BOOL_OP3 (test) \
+    } \
+  while (0)
+
+#define MX_SC_BOOL_OP(mt, mn, get_m, st, sn, get_s, test, empty_result) \
+  do \
+    { \
+      BOOL_OP1 (mt, mn, get_m, st, sn, get_s) \
+      BOOL_OP2 (mn) \
+      if (nr == 0 || nc == 0) \
+        return empty_result; \
+      BOOL_OP3 (test) \
+    } \
+  while (0)
+
+#define MX_MX_BOOL_OP(m1t, m1n, get_m1, m2t, m2n, get_m2, test, op, \
+		      one_empty_result, two_empty_result) \
+  do \
+    { \
+      BOOL_OP1 (m1t, m1n, get_m1, m2t, m2n, get_m2) \
+      octave_idx_type m1_nr = m1n.rows (); \
+      octave_idx_type m1_nc = m1n.cols (); \
+      octave_idx_type m2_nr = m2n.rows (); \
+      octave_idx_type m2_nc = m2n.cols (); \
+      if (m1_nr == m2_nr && m1_nc == m2_nc) \
+	{ \
+	  if (m1_nr == 0 && m1_nc == 0) \
+	    return two_empty_result; \
+	  else \
+	    { \
+	      BOOL_OP2 (m1n) \
+	      BOOL_OP3 (test) \
+	    } \
+	} \
+      else \
+	{ \
+	  if ((m1_nr == 0 && m1_nc == 0) || (m2_nr == 0 && m2_nc == 0)) \
+	    return one_empty_result; \
+	  else \
+	    { \
+	      gripe_nonconformant ("operator " op, m1_nr, m1_nc, \
+				   m2_nr, m2_nc); \
+	      return boolMatrix (); \
+	    } \
+	} \
+    } \
+  while (0)
+
+#define CAST_UNOP_ARG(t) \
+  t v = dynamic_cast<t> (a)
+
+#define CAST_BINOP_ARGS(t1, t2) \
+  t1 v1 = dynamic_cast<t1> (a1);		\
+  t2 v2 = dynamic_cast<t2> (a2)
+
+#define CAST_CONV_ARG(t) \
+  t v = dynamic_cast<t> (a)
+
+#define ASSIGNOPDECL(name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
+			 const octave_value_list& idx, \
+			 const octave_base_value& a2)
+
+#define NULLASSIGNOPDECL(name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a, \
+			 const octave_value_list& idx, \
+			 const octave_base_value&)
+
+#define ASSIGNANYOPDECL(name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
+			 const octave_value_list& idx, \
+			 const octave_value& a2)
+
+#define DEFASSIGNOP(name, t1, t2) \
+  ASSIGNOPDECL (name)
+
+#define DEFASSIGNOP_FN(name, t1, t2, f) \
+  ASSIGNOPDECL (name) \
+  { \
+    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+ \
+    v1.f (idx, v2.CONCAT2(t1, _value) ()); \
+    return octave_value (); \
+  }
+
+#define DEFNULLASSIGNOP_FN(name, t, f) \
+  NULLASSIGNOPDECL (name) \
+  { \
+    CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
+ \
+    v.f (idx); \
+    return octave_value (); \
+  }
+
+#define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
+  ASSIGNOPDECL (name) \
+  { \
+    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+ \
+    v1.f (idx, v2.CONCAT2(e, _value) ()); \
+    return octave_value (); \
+  }
+
+#define DEFASSIGNANYOP_FN(name, t1, f) \
+  ASSIGNANYOPDECL (name) \
+  { \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+ \
+    v1.f (idx, a2); \
+    return octave_value (); \
+  }
+
+#define CONVDECL(name) \
+  static octave_base_value * \
+  CONCAT2(oct_conv_, name) (const octave_base_value& a)
+
+#define CONVDECLX(name) \
+  static octave_base_value * \
+  CONCAT2(oct_conv_, name) (const octave_base_value&)
+
+#define DEFCONV(name, a_dummy, b_dummy) \
+  CONVDECL (name)
+
+#define DEFCONVFNX(name, tfrom, ovtto, tto, e) \
+  CONVDECL (name) \
+  { \
+    CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
+ \
+    return new CONCAT2(octave_, ovtto) (CONCAT2(tto, NDArray) (v.CONCAT2(e, array_value) ())); \
+  }
+
+#define DEFCONVFNX2(name, tfrom, ovtto, e) \
+  CONVDECL (name) \
+  { \
+    CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
+ \
+    return new CONCAT2(octave_, ovtto) (v.CONCAT2(e, array_value) ()); \
+  }
+
+#define DEFDBLCONVFN(name, ovtfrom, e) \
+  CONVDECL (name) \
+  { \
+    CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
+ \
+    return new octave_matrix (NDArray (v.CONCAT2(e, _value) ())); \
+  }
+
+#define DEFFLTCONVFN(name, ovtfrom, e) \
+  CONVDECL (name) \
+  { \
+    CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
+ \
+    return new octave_float_matrix (FloatNDArray (v.CONCAT2(e, _value) ())); \
+  }
+
+#define DEFSTRINTCONVFN(name, tto) \
+  DEFCONVFNX(name, char_matrix_str, CONCAT2(tto, _matrix), tto, char_)
+
+#define DEFSTRDBLCONVFN(name, tfrom) \
+  DEFCONVFNX(name, tfrom, matrix, , char_)
+
+#define DEFSTRFLTCONVFN(name, tfrom) \
+  DEFCONVFNX(name, tfrom, float_matrix, Float, char_)
+
+#define DEFCONVFN(name, tfrom, tto) \
+  DEFCONVFNX2 (name, tfrom, CONCAT2(tto, _matrix), CONCAT2(tto, _))
+
+#define DEFCONVFN2(name, tfrom, sm, tto) \
+  DEFCONVFNX2 (name, CONCAT3(tfrom, _, sm), CONCAT2(tto, _matrix), CONCAT2(tto, _))
+
+#define UNOPDECL(name, a) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value& a)
+
+#define DEFUNOPX(name, t) \
+  UNOPDECL (name, , )
+
+#define DEFUNOP(name, t) \
+  UNOPDECL (name, a)
+
+#define DEFUNOP_OP(name, t, op) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    return octave_value (op v.CONCAT2(t, _value) ()); \
+  }
+
+#define DEFNDUNOP_OP(name, t, e, op) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    return octave_value (op v.CONCAT2(e, _value) ()); \
+  }
+
+// FIXME -- in some cases, the constructor isn't necessary.
+
+#define DEFUNOP_FN(name, t, f) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    return octave_value (f (v.CONCAT2(t, _value) ())); \
+  }
+
+#define DEFNDUNOP_FN(name, t, e, f) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    return octave_value (f (v.CONCAT2(e, _value) ())); \
+  }
+
+#define DEFNCUNOP_METHOD(name, t, method) \
+  static void \
+  CONCAT2(oct_unop_, name) (octave_base_value& a) \
+  { \
+    CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
+    v.method (); \
+  }
+
+#define BINOPDECL(name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2)
+
+#define DEFBINOPX(name, t1, t2) \
+  BINOPDECL (name, , )
+
+#define DEFBINOP(name, t1, t2) \
+  BINOPDECL (name, a1, a2)
+
+#define DEFBINOP_OP(name, t1, t2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value \
+      (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
+  }
+
+#define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    if (xisnan (v1.CONCAT2(t1, _value) ()) || xisnan (v2.CONCAT2(t2, _value) ())) \
+      { \
+        error ("invalid conversion from NaN to logical"); \
+        return octave_value (); \
+      } \
+    else \
+      return octave_value \
+        (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
+  }
+
+#define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value \
+      (v1.CONCAT2(e1, _value) () op v2.CONCAT2(e2, _value) ()); \
+  }
+
+// FIXME -- in some cases, the constructor isn't necessary.
+
+#define DEFBINOP_FN(name, t1, t2, f) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value (f (v1.CONCAT2(t1, _value) (), v2.CONCAT2(t2, _value) ())); \
+  }
+
+#define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
+  }
+
+#define BINOP_NONCONFORMANT(msg) \
+  gripe_nonconformant (msg, \
+		       a1.rows (), a1.columns (), \
+		       a2.rows (), a2.columns ()); \
+  return octave_value ()
+
+#define CATOPDECL(name, a1, a2)	\
+  static octave_value \
+  CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
+		      const Array<octave_idx_type>& ra_idx)
+
+#define DEFCATOPX(name, t1, t2)	\
+  CATOPDECL (name, , )
+
+#define DEFCATOP(name, t1, t2)	\
+  CATOPDECL (name, a1, a2)
+
+// FIXME -- in some cases, the constructor isn't necessary.
+
+#define DEFCATOP_FN(name, t1, t2, f) \
+  CATOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value (v1.CONCAT2(t1, _value) () . f (v2.CONCAT2(t2, _value) (), ra_idx)); \
+  }
+
+#define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
+  CATOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value (v1.CONCAT2(e1, _value) () . f (v2.CONCAT2(e2, _value) (), ra_idx)); \
+  }
+
+#define DEFNDCHARCATOP_FN(name, t1, t2, f) \
+  CATOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+ \
+    return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
+			 true, ((a1.is_sq_string () || a2.is_sq_string ()) \
+				? '\'' : '"')); \
+  }
+
+// For compatibility, the second arg is always converted to the type
+// of the first.  Hmm.
+
+#define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
+  CATOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    return octave_value (tc1 (v1.CONCAT2(e1, _value) ()) . f (tc2 (v2.CONCAT2(e2, _value) ()), ra_idx)); \
+  }
+
+#define CATOP_NONCONFORMANT(msg) \
+  gripe_nonconformant (msg, \
+		       a1.rows (), a1.columns (), \
+		       a2.rows (), a2.columns ()); \
+  return octave_value ()
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-diag.cc b/src/ov-base-diag.cc
new file mode 100644
index 0000000..ddba823
--- /dev/null
+++ b/src/ov-base-diag.cc
@@ -0,0 +1,550 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "mach-info.h"
+#include "lo-ieee.h"
+
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "pr-output.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-stream.h"
+#include "ops.h"
+
+#include "ls-oct-ascii.h"
+
+template <class DMT, class MT>
+octave_value
+octave_base_diag<DMT, MT>::subsref (const std::string& type,
+                                    const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front ());
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval.next_subsref (type, idx);
+}
+
+template <class DMT, class MT>
+octave_value
+octave_base_diag<DMT, MT>::do_index_op (const octave_value_list& idx,
+                                        bool resize_ok)
+{
+  octave_value retval;
+  typedef typename DMT::element_type el_type;
+
+  if (idx.length () == 2 && ! resize_ok)
+    {
+      idx_vector idx0 = idx(0).index_vector ();
+      idx_vector idx1 = idx(1).index_vector ();
+
+      if (idx0.is_scalar () && idx1.is_scalar ())
+        {
+          // FIXME: the proxy mechanism of DiagArray2 causes problems here.
+          retval = el_type (matrix.checkelem (idx0(0), idx1(0)));
+        }
+      else
+        {
+          octave_idx_type m = idx0.length (matrix.rows ());
+          octave_idx_type n = idx1.length (matrix.columns ());
+          if (idx0.is_colon_equiv (m) && idx1.is_colon_equiv (n)
+              && m <= matrix.rows () && n <= matrix.rows ())
+            {
+              DMT rm (matrix);
+              rm.resize (m, n);
+              retval = rm;
+            }
+          else
+            retval = to_dense ().do_index_op (idx, resize_ok);
+        }
+    }
+  else
+    retval = to_dense ().do_index_op (idx, resize_ok);
+
+  return retval;
+}
+
+template <class DMT, class MT>
+octave_value 
+octave_base_diag<DMT, MT>::subsasgn (const std::string& type,
+                                     const std::list<octave_value_list>& idx,
+                                     const octave_value& rhs)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	if (type.length () == 1)
+          {
+            octave_value_list jdx = idx.front ();
+            // Check for a simple element assignment. That means, if D is a diagonal matrix,
+            // `D(i,i) = x' will not destroy its diagonality (provided i is a valid index).
+            if (jdx.length () == 2 && jdx(0).is_scalar_type () && jdx(1).is_scalar_type ())
+              {
+                typename DMT::element_type val;
+                idx_vector i0 = jdx(0).index_vector (), i1 = jdx(1).index_vector ();
+                if (! error_state  && i0(0) == i1(0) 
+                    && i0(0) < matrix.rows () && i1(0) < matrix.cols ()
+                    && chk_valid_scalar (rhs, val))
+                  {
+                    matrix (i0(0), i1(0)) = val;                    
+                    retval = this;
+                    this->count++;
+                    // invalidate cache
+                    dense_cache = octave_value ();
+                  }
+              }
+
+            if (! error_state && ! retval.is_defined ())
+              retval = numeric_assign (type, idx, rhs);
+          }
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("in indexed assignment of %s, last lhs index must be ()",
+		   nm.c_str ());
+	  }
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	if (is_empty ())
+	  {
+	    octave_value tmp = octave_value::empty_conv (type, rhs);
+
+	    retval = tmp.subsasgn (type, idx, rhs);
+	  }
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval;
+}
+
+template <class DMT, class MT>
+octave_value
+octave_base_diag<DMT, MT>::resize (const dim_vector& dv, bool fill) const
+{
+  octave_value retval;
+  if (dv.length () == 2)
+    {
+      DMT rm (matrix);
+      rm.resize (dv(0), dv(1));
+      retval = rm;
+    }
+  else
+    retval = to_dense ().resize (dv, fill);
+  return retval;
+}
+
+template <class DMT, class MT>
+bool
+octave_base_diag<DMT, MT>::is_true (void) const
+{
+  return to_dense ().is_true ();
+}
+
+// FIXME: this should be achieveable using ::real
+template <class T> inline T helper_getreal (T x) { return x; }
+template <class T> inline T helper_getreal (std::complex<T> x) { return x.real (); }
+// FIXME: we really need some traits so that ad hoc hooks like this are not necessary
+template <class T> inline T helper_iscomplex (T) { return false; }
+template <class T> inline T helper_iscomplex (std::complex<T>) { return true; }
+
+template <class DMT, class MT>
+double
+octave_base_diag<DMT, MT>::double_value (bool force_conversion) const
+{
+  double retval = lo_ieee_nan_value ();
+  typedef typename DMT::element_type el_type;
+
+  if (helper_iscomplex (el_type ()) && ! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real scalar");
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "real scalar");
+
+      retval = helper_getreal (el_type (matrix (0, 0)));
+    }
+  else
+    gripe_invalid_conversion (type_name (), "real scalar");
+
+  return retval;
+}
+
+template <class DMT, class MT>
+float
+octave_base_diag<DMT, MT>::float_value (bool force_conversion) const
+{
+  float retval = lo_ieee_float_nan_value ();
+  typedef typename DMT::element_type el_type;
+
+  if (helper_iscomplex (el_type ()) && ! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real scalar");
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "real scalar");
+
+      retval = helper_getreal (el_type (matrix (0, 0)));
+    }
+  else
+    gripe_invalid_conversion (type_name (), "real scalar");
+
+  return retval;
+}
+
+template <class DMT, class MT>
+Complex
+octave_base_diag<DMT, MT>::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion (type_name (), "complex scalar");
+
+  return retval;
+}
+
+template <class DMT, class MT>
+FloatComplex
+octave_base_diag<DMT, MT>::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion (type_name (), "complex scalar");
+
+  return retval;
+}
+
+template <class DMT, class MT>
+Matrix
+octave_base_diag<DMT, MT>::matrix_value (bool) const
+{
+  return Matrix (diag_matrix_value ());
+}
+
+template <class DMT, class MT>
+FloatMatrix
+octave_base_diag<DMT, MT>::float_matrix_value (bool) const
+{
+  return FloatMatrix (float_diag_matrix_value ());
+}
+
+template <class DMT, class MT>
+ComplexMatrix
+octave_base_diag<DMT, MT>::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (complex_diag_matrix_value ());
+}
+
+template <class DMT, class MT>
+FloatComplexMatrix
+octave_base_diag<DMT, MT>::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (float_complex_diag_matrix_value ());
+}
+
+template <class DMT, class MT>
+NDArray
+octave_base_diag<DMT, MT>::array_value (bool) const
+{
+  return NDArray (matrix_value ());
+}
+
+template <class DMT, class MT>
+FloatNDArray
+octave_base_diag<DMT, MT>::float_array_value (bool) const
+{
+  return FloatNDArray (float_matrix_value ());
+}
+
+template <class DMT, class MT>
+ComplexNDArray
+octave_base_diag<DMT, MT>::complex_array_value (bool) const
+{
+  return ComplexNDArray (complex_matrix_value ());
+}
+
+template <class DMT, class MT>
+FloatComplexNDArray
+octave_base_diag<DMT, MT>::float_complex_array_value (bool) const
+{
+  return FloatComplexNDArray (float_complex_matrix_value ());
+}
+
+template <class DMT, class MT>
+boolNDArray
+octave_base_diag<DMT, MT>::bool_array_value (bool warn) const
+{
+  return to_dense ().bool_array_value (warn); 
+}
+  
+template <class DMT, class MT>
+charNDArray
+octave_base_diag<DMT, MT>::char_array_value (bool warn) const
+{
+  return to_dense ().char_array_value (warn); 
+}
+  
+template <class DMT, class MT>
+SparseMatrix 
+octave_base_diag<DMT, MT>::sparse_matrix_value (bool) const
+{
+  return SparseMatrix (diag_matrix_value ());
+}
+
+template <class DMT, class MT>
+SparseComplexMatrix 
+octave_base_diag<DMT, MT>::sparse_complex_matrix_value (bool) const
+{
+  return SparseComplexMatrix (complex_diag_matrix_value ());
+}
+
+template <class DMT, class MT>
+idx_vector
+octave_base_diag<DMT, MT>::index_vector (void) const
+{
+  return to_dense ().index_vector ();
+}
+
+template <class DMT, class MT>
+octave_value
+octave_base_diag<DMT, MT>::convert_to_str_internal (bool pad, bool force, char type) const
+{
+  return to_dense ().convert_to_str_internal (pad, force, type);
+}
+
+template <class DMT, class MT>
+bool 
+octave_base_diag<DMT, MT>::save_ascii (std::ostream& os)
+{
+  os << "# rows: " << matrix.rows () << "\n"
+    << "# columns: " << matrix.columns () << "\n";
+
+  os << matrix.diag ();
+
+  return true;
+}
+
+template <class DMT, class MT>
+bool 
+octave_base_diag<DMT, MT>::load_ascii (std::istream& is)
+{
+  octave_idx_type r = 0, c = 0;
+  bool success = true;
+
+  if (extract_keyword (is, "rows", r, true)
+      && extract_keyword (is, "columns", c, true))
+    {
+      octave_idx_type l = r < c ? r : c;
+      MT tmp (l, 1);
+      is >> tmp;
+
+      if (!is) 
+	{
+	  error ("load: failed to load diagonal matrix constant");
+	  success = false;
+	}
+      else
+        {
+          // This is a little tricky, as we have the Matrix type, but
+          // not ColumnVector type. We need to help the compiler get
+          // through the inheritance tree.
+          typedef typename DMT::element_type el_type;
+          matrix = DMT (MDiagArray2<el_type> (MArray<el_type> (tmp)));
+          matrix.resize (r, c);
+
+          // Invalidate cache. Probably not necessary, but safe.
+          dense_cache = octave_value ();
+        }
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+template <class DMT, class MT>
+void
+octave_base_diag<DMT, MT>::print_raw (std::ostream& os,
+                                      bool pr_as_read_syntax) const
+{
+  return octave_print_internal (os, matrix, pr_as_read_syntax,
+                                current_print_indent_level ());
+}
+
+template <class DMT, class MT>
+mxArray *
+octave_base_diag<DMT, MT>::as_mxArray (void) const
+{
+  return to_dense ().as_mxArray ();
+}
+
+template <class DMT, class MT>
+bool
+octave_base_diag<DMT, MT>::print_as_scalar (void) const
+{
+  dim_vector dv = dims ();
+
+  return (dv.all_ones () || dv.any_zero ());
+}
+
+template <class DMT, class MT>
+void
+octave_base_diag<DMT, MT>::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+template <class DMT, class MT>
+int
+octave_base_diag<DMT, MT>::write (octave_stream& os, int block_size,
+                                  oct_data_conv::data_type output_type, int skip,
+                                  oct_mach_info::float_format flt_fmt) const
+{ 
+  return to_dense ().write (os, block_size, output_type, skip, flt_fmt); 
+}
+
+template <class DMT, class MT>
+void
+octave_base_diag<DMT, MT>::print_info (std::ostream& os,
+                                       const std::string& prefix) const
+{
+  matrix.print_info (os, prefix);
+}
+
+template <class DMT, class MT>
+octave_value
+octave_base_diag<DMT, MT>::to_dense (void) const
+{
+  if (! dense_cache.is_defined ())
+    dense_cache = MT (matrix);
+
+  return dense_cache;
+}
+
+#define FORWARD_MAPPER(MAP) \
+  template <class DMT, class MT> \
+  octave_value \
+  octave_base_diag<DMT, MT>::MAP (void) const \
+  { \
+    return to_dense ().MAP (); \
+  }
+
+FORWARD_MAPPER (erf)
+FORWARD_MAPPER (erfc)
+FORWARD_MAPPER (gamma)
+FORWARD_MAPPER (lgamma)
+FORWARD_MAPPER (acos)
+FORWARD_MAPPER (acosh)
+FORWARD_MAPPER (angle)
+FORWARD_MAPPER (arg)
+FORWARD_MAPPER (asin)
+FORWARD_MAPPER (asinh)
+FORWARD_MAPPER (atan)
+FORWARD_MAPPER (atanh)
+FORWARD_MAPPER (ceil)
+FORWARD_MAPPER (cos)
+FORWARD_MAPPER (cosh)
+FORWARD_MAPPER (exp)
+FORWARD_MAPPER (expm1)
+FORWARD_MAPPER (fix)
+FORWARD_MAPPER (floor)
+FORWARD_MAPPER (log)
+FORWARD_MAPPER (log2)
+FORWARD_MAPPER (log10)
+FORWARD_MAPPER (log1p)
+FORWARD_MAPPER (round)
+FORWARD_MAPPER (roundb)
+FORWARD_MAPPER (signum)
+FORWARD_MAPPER (sin)
+FORWARD_MAPPER (sinh)
+FORWARD_MAPPER (tan)
+FORWARD_MAPPER (tanh)
+FORWARD_MAPPER (finite)
+FORWARD_MAPPER (isinf)
+FORWARD_MAPPER (isna)
+FORWARD_MAPPER (isnan)
+
diff --git a/src/ov-base-diag.h b/src/ov-base-diag.h
new file mode 100644
index 0000000..5e97627
--- /dev/null
+++ b/src/ov-base-diag.h
@@ -0,0 +1,262 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_diag_h)
+#define octave_base_diag_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "oct-obj.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+class tree_walker;
+
+// Real matrix values.
+
+template <class DMT, class MT>
+class
+octave_base_diag : public octave_base_value
+{
+
+public:
+
+  octave_base_diag (void)
+    : octave_base_value () { }
+
+  octave_base_diag (const DMT& m)
+    : octave_base_value (), matrix (m)
+  { }
+
+  octave_base_diag (const octave_base_diag& m)
+    : octave_base_value (), matrix (m.matrix) { }
+
+  ~octave_base_diag (void) { }
+
+  size_t byte_size (void) const { return matrix.byte_size (); }
+
+  octave_value squeeze (void) const { return matrix; }
+
+  octave_value full_value (void) const { return to_dense (); }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx);
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int)
+    { return subsref (type, idx); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  dim_vector dims (void) const { return matrix.dims (); }
+
+  octave_idx_type nnz (void) const { return to_dense ().nnz (); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return to_dense ().reshape (new_dims); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return to_dense ().permute (vec, inv); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  octave_value all (int dim = 0) const { return MT (matrix).all (dim); }
+  octave_value any (int dim = 0) const { return MT (matrix).any (dim); }
+
+  MatrixType matrix_type (void) const { return MatrixType::Diagonal; }
+  MatrixType matrix_type (const MatrixType&) const
+    { return matrix_type (); }
+
+  octave_value diag (octave_idx_type k = 0) const
+    { return octave_value (matrix.diag (k)); }
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return to_dense ().sort (dim, mode); }
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return to_dense ().sort (sidx, dim, mode); }
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return to_dense ().is_sorted (mode); }
+
+  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const
+    { return to_dense ().sort_rows_idx (mode); }
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+    { return to_dense ().is_sorted_rows (mode); }
+
+  bool is_matrix_type (void) const { return true; }
+
+  bool is_numeric_type (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_true (void) const;
+
+  bool is_diag_matrix (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  idx_vector index_vector (void) const;
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+   
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+   
+  boolNDArray bool_array_value (bool warn = false) const;
+
+  charNDArray char_array_value (bool = false) const;
+  
+  NDArray array_value (bool = false) const; 
+
+  FloatNDArray float_array_value (bool = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  int8NDArray
+  int8_array_value (void) const { return to_dense ().int8_array_value (); }
+
+  int16NDArray
+  int16_array_value (void) const { return to_dense ().int16_array_value (); }
+
+  int32NDArray
+  int32_array_value (void) const { return to_dense ().int32_array_value (); }
+
+  int64NDArray
+  int64_array_value (void) const { return to_dense ().int64_array_value (); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return to_dense ().uint8_array_value (); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return to_dense ().uint16_array_value (); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return to_dense ().uint32_array_value (); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return to_dense ().uint64_array_value (); }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const;
+
+  mxArray *as_mxArray (void) const;
+
+  bool print_as_scalar (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
+
+  // We forward everything except abs, real, imag, conj, sqrt.
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+protected:
+
+  DMT matrix;
+
+  octave_value to_dense (void) const;
+
+  virtual bool chk_valid_scalar (const octave_value&, 
+                                 typename DMT::element_type&) const = 0;
+
+private:
+
+  mutable octave_value dense_cache;
+
+};
+
+#endif
diff --git a/src/ov-base-int.cc b/src/ov-base-int.cc
new file mode 100644
index 0000000..cd6a07d
--- /dev/null
+++ b/src/ov-base-int.cc
@@ -0,0 +1,599 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+#include <vector>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-base-scalar.h"
+#include "ov-base-scalar.cc"
+#include "ov-base-int.h"
+#include "ov-int-traits.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+// We have all the machinery below (octave_base_int_helper and
+// octave_base_int_helper_traits) to avoid a few warnings from GCC
+// about comparisons always false due to limited range of data types.
+// Ugh.  The cure may be worse than the disease.
+
+template <class T, bool is_signed = true, bool can_be_too_big = true>
+struct octave_base_int_helper
+{
+  static bool
+  char_value_out_of_range (T val) { return val < 0 || val > UCHAR_MAX; }
+};
+
+template <class T>
+struct octave_base_int_helper<T, false, false>
+{
+  static bool char_value_out_of_range (T) { return false; }
+};
+
+template <class T>
+struct octave_base_int_helper<T, false, true>
+{
+  static bool char_value_out_of_range (T val) { return val > UCHAR_MAX; }
+};
+
+template <class T>
+struct octave_base_int_helper<T, true, false>
+{
+  static bool char_value_out_of_range (T val) { return val < 0; }
+};
+
+// For all types other than char, signed char, and unsigned char, we
+// assume that the upper limit for the range of allowable values is
+// larger than the range for unsigned char.  If that's not true, we
+// are still OK, but will see the warnings again for any other types
+// that do not meet this assumption.
+
+template <class T>
+struct octave_base_int_helper_traits
+{
+  static const bool can_be_larger_than_uchar_max = true;
+};
+
+template <>
+struct octave_base_int_helper_traits<char>
+{
+  static const bool can_be_larger_than_uchar_max = false;
+};
+
+template <>
+struct octave_base_int_helper_traits<signed char>
+{
+  static const bool can_be_larger_than_uchar_max = false;
+};
+
+template <>
+struct octave_base_int_helper_traits<unsigned char>
+{
+  static const bool can_be_larger_than_uchar_max = false;
+};
+
+
+template <class T>
+octave_base_value *
+octave_base_int_matrix<T>::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (this->matrix.nelem () == 1)
+    retval = new typename octave_value_int_traits<T>::scalar_type (this->matrix (0));
+
+  return retval;
+}
+
+template <class T>
+octave_value
+octave_base_int_matrix<T>::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+  dim_vector dv = this->dims ();
+  octave_idx_type nel = dv.numel ();
+
+  charNDArray chm (dv);
+
+  bool warned = false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+
+      typename T::element_type tmp = this->matrix(i);
+
+      typedef typename T::element_type::val_type val_type;
+
+      val_type ival = tmp.value ();
+
+      static const bool is_signed = std::numeric_limits<val_type>::is_signed;
+      static const bool can_be_larger_than_uchar_max
+	= octave_base_int_helper_traits<val_type>::can_be_larger_than_uchar_max;
+
+      if (octave_base_int_helper<val_type, is_signed,
+	  can_be_larger_than_uchar_max>::char_value_out_of_range (ival))
+	{
+	  // FIXME -- is there something better we could do?
+
+	  ival = 0;
+
+	  if (! warned)
+	    {
+	      ::warning ("range error for conversion to character value");
+	      warned = true;
+	    }
+	}
+      else
+	chm (i) = static_cast<char> (ival);
+    }
+
+  retval = octave_value (chm, true, type);
+
+  return retval;
+}
+
+template <class T>
+bool
+octave_base_int_matrix<T>::save_ascii (std::ostream& os)
+{
+  dim_vector d = this->dims ();
+
+  os << "# ndims: " << d.length () << "\n";
+
+  for (int i = 0; i < d.length (); i++)
+    os << " " << d (i);
+
+  os << "\n" << this->matrix;
+
+  return true;
+}
+
+template <class T>
+bool 
+octave_base_int_matrix<T>::load_ascii (std::istream& is)
+{
+  int mdims = 0;
+  bool success = true;
+
+  if (extract_keyword (is, "ndims", mdims, true))
+    {
+      if (mdims >= 0)
+	{
+	  dim_vector dv;
+	  dv.resize (mdims);
+
+	  for (int i = 0; i < mdims; i++)
+	    is >> dv(i);
+
+	  T tmp(dv);
+
+	  is >> tmp;
+
+	  if (!is) 
+	    {
+	      error ("load: failed to load matrix constant");
+	      success = false;
+	    }
+
+	  this->matrix = tmp;
+	}
+      else
+	{
+	  error ("load: failed to extract number of rows and columns");
+	  success = false;
+	}
+    }
+  else
+    error ("load: failed to extract number of dimensions");
+
+  return success;
+}
+
+template <class T>
+bool 
+octave_base_int_matrix<T>::save_binary (std::ostream& os, bool&)
+{
+  dim_vector d = this->dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i=0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  os.write (reinterpret_cast<const char *> (this->matrix.data()), this->byte_size());
+
+  return true;
+}
+
+template <class T>
+bool
+octave_base_int_matrix<T>::load_binary (std::istream& is, bool swap,
+					oct_mach_info::float_format )
+{
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims >= 0)
+    return false;
+
+  mdims = - mdims;
+  int32_t di;
+  dim_vector dv;
+  dv.resize (mdims);
+
+  for (int i = 0; i < mdims; i++)
+    {
+      if (! is.read (reinterpret_cast<char *> (&di), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&di);
+      dv(i) = di;
+    }
+
+  // Convert an array with a single dimension to be a row vector.
+  // Octave should never write files like this, other software
+  // might.
+
+  if (mdims == 1)
+    {
+      mdims = 2;
+      dv.resize (mdims);
+      dv(1) = dv(0);
+      dv(0) = 1;
+    }
+
+  T m (dv);
+
+  if (! is.read (reinterpret_cast<char *> (m.fortran_vec ()), m.byte_size ()))
+    return false;
+
+  if (swap)
+    {
+      int nel = dv.numel ();
+      int bytes = nel / m.byte_size();
+      for (int i = 0; i < nel; i++) 
+	switch (bytes)
+	  {
+	  case 8:
+	    swap_bytes<8> (&m(i));
+	    break;
+	  case 4:
+	    swap_bytes<4> (&m(i));
+	    break;
+	  case 2:
+	    swap_bytes<2> (&m(i));
+	    break;
+	  case 1:
+	  default:
+	    break;
+	  }
+    }
+
+  this->matrix = m;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+template <class T>
+bool
+octave_base_int_matrix<T>::save_hdf5 (hid_t loc_id, const char *name, bool)
+{
+  hid_t save_type_hid = HDF5_SAVE_TYPE;
+  bool retval = true;
+  dim_vector dv = this->dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1;
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, 0);
+
+  if (space_hid < 0) return false;
+
+  data_hid = H5Dcreate (loc_id, name, save_type_hid, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  retval = H5Dwrite (data_hid, save_type_hid, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, this->matrix.data()) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+template <class T>
+bool
+octave_base_int_matrix<T>::load_hdf5 (hid_t loc_id, const char *name,
+				      bool /* have_h5giterate_bug */)
+{
+  hid_t save_type_hid = HDF5_SAVE_TYPE;
+  bool retval = false;
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    this->matrix.resize(dv);
+  if (empty)
+      return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+  
+  if (rank < 1)
+    {
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  if (rank == 1)
+    {
+      dv.resize (2);
+      dv(0) = 1;
+      dv(1) = hdims[0];
+    }
+  else
+    {
+      dv.resize (rank);
+      for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	dv(j) = hdims[i];
+    }
+
+  T m (dv);
+  if (H5Dread (data_hid, save_type_hid, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, m.fortran_vec()) >= 0) 
+    {
+      retval = true;
+      this->matrix = m;
+    }
+
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+template <class T>
+void
+octave_base_int_matrix<T>::print_raw (std::ostream& os,
+				      bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, this->matrix, pr_as_read_syntax,
+   			 this->current_print_indent_level ());
+}
+
+template <class T>
+octave_value
+octave_base_int_scalar<T>::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+
+  T tmp = this->scalar;
+
+  typedef typename T::val_type val_type;
+
+  val_type ival = tmp.value ();
+
+  static const bool is_signed = std::numeric_limits<val_type>::is_signed;
+  static const bool can_be_larger_than_uchar_max
+    = octave_base_int_helper_traits<val_type>::can_be_larger_than_uchar_max;
+
+  if (octave_base_int_helper<val_type, is_signed,
+      can_be_larger_than_uchar_max>::char_value_out_of_range (ival))
+    {
+      // FIXME -- is there something better we could do?
+
+      ival = 0;
+
+      ::warning ("range error for conversion to character value");
+    }
+  else
+    retval = octave_value (std::string (1, static_cast<char> (ival)), type);
+
+  return retval;
+}
+
+template <class T>
+bool
+octave_base_int_scalar<T>::save_ascii (std::ostream& os)
+{
+  os << this->scalar << "\n";
+  return true;
+}
+
+template <class T>
+bool 
+octave_base_int_scalar<T>::load_ascii (std::istream& is)
+{
+  is >> this->scalar;
+  if (!is)
+    {
+      error ("load: failed to load scalar constant");
+      return false;
+    }
+  return true;
+}
+
+template <class T>
+bool 
+octave_base_int_scalar<T>::save_binary (std::ostream& os, bool&)
+{
+  os.write (reinterpret_cast<char *> (&(this->scalar)), this->byte_size());
+  return true;
+}
+
+template <class T>
+bool 
+octave_base_int_scalar<T>::load_binary (std::istream& is, bool swap,
+					oct_mach_info::float_format)
+{
+  T tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), this->byte_size()))
+    return false;
+
+  if (swap)
+    switch (this->byte_size())
+      {
+      case 8:
+	swap_bytes<8> (&tmp);
+	break;
+      case 4:
+	swap_bytes<4> (&tmp);
+	break;
+      case 2:
+	swap_bytes<2> (&tmp);
+	break;
+      case 1:
+      default:
+	break;
+      }
+  this->scalar = tmp;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+template <class T>
+bool
+octave_base_int_scalar<T>::save_hdf5 (hid_t loc_id, const char *name, bool)
+{
+  hid_t save_type_hid = HDF5_SAVE_TYPE;
+  bool retval = true;
+  hsize_t dimens[3];
+  hid_t space_hid = -1, data_hid = -1;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0) return false;
+
+  data_hid = H5Dcreate (loc_id, name, save_type_hid, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  retval = H5Dwrite (data_hid, save_type_hid, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &(this->scalar)) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+template <class T>
+bool
+octave_base_int_scalar<T>::load_hdf5 (hid_t loc_id, const char *name,
+				      bool /* have_h5giterate_bug */)
+{
+  hid_t save_type_hid = HDF5_SAVE_TYPE;
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  T tmp;
+  if (H5Dread (data_hid, save_type_hid, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &tmp) < 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  this->scalar = tmp;
+
+  H5Dclose (data_hid);
+
+  return true;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-int.h b/src/ov-base-int.h
new file mode 100644
index 0000000..93a016c
--- /dev/null
+++ b/src/ov-base-int.h
@@ -0,0 +1,135 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_int_matrix_h)
+#define octave_base_int_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-scalar.h"
+#include "ov-typeinfo.h"
+
+// base int matrix values.
+
+template <class T>
+class
+octave_base_int_matrix : public octave_base_matrix<T>
+{
+public:
+
+  octave_base_int_matrix (void) : octave_base_matrix<T> () { }
+
+  octave_base_int_matrix (const T& nda) : octave_base_matrix<T> (nda) { }
+
+  ~octave_base_int_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_base_int_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_int_matrix (); }
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  bool is_real_type (void) const { return true; }
+
+  //  void increment (void) { matrix += 1; }
+
+  //  void decrement (void) { matrix -= 1; }
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  octave_value convert_to_str_internal (bool, bool, char type) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& );
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format );
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+};
+
+// base int scalar values.
+
+template <class T>
+class
+octave_base_int_scalar : public octave_base_scalar<T>
+{
+public:
+
+  octave_base_int_scalar (void) : octave_base_scalar<T> () { }
+
+  octave_base_int_scalar (const T& s) : octave_base_scalar<T> (s) { }
+
+  ~octave_base_int_scalar (void) { }
+
+  octave_base_value *clone (void) const { return new octave_base_int_scalar (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_int_scalar (); }
+
+  octave_base_value *try_narrowing_conversion (void) { return 0; }
+
+  bool is_real_type (void) const { return true; }
+
+  //  void increment (void) { scalar += 1; }
+
+  //  void decrement (void) { scalar -= 1; }
+
+  octave_value convert_to_str_internal (bool, bool, char type) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& );
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format );
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool );
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-mat.cc b/src/ov-base-mat.cc
new file mode 100644
index 0000000..87a3563
--- /dev/null
+++ b/src/ov-base-mat.cc
@@ -0,0 +1,458 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+Copyright (C) 2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Cell.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "pr-output.h"
+
+template <class MT>
+octave_value
+octave_base_matrix<MT>::subsref (const std::string& type,
+				 const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front ());
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval.next_subsref (type, idx);
+}
+
+template <class MT>
+octave_value
+octave_base_matrix<MT>::subsasgn (const std::string& type,
+				  const std::list<octave_value_list>& idx,
+				  const octave_value& rhs)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	if (type.length () == 1)
+	  retval = numeric_assign (type, idx, rhs);
+	else if (is_empty ())
+	  {
+	    // Allow conversion of empty matrix to some other type in
+	    // cases like
+	    //
+	    //  x = []; x(i).f = rhs
+
+	    if (type[1] == '.')
+	      {
+		octave_value tmp = octave_value::empty_conv (type, rhs);
+
+		retval = tmp.subsasgn (type, idx, rhs);
+	      }
+	    else
+	      error ("invalid assignment expression");
+	  }
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("in indexed assignment of %s, last lhs index must be ()",
+		   nm.c_str ());
+	  }
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	if (is_empty ())
+	  {
+	    octave_value tmp = octave_value::empty_conv (type, rhs);
+
+	    retval = tmp.subsasgn (type, idx, rhs);
+	  }
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval;
+}
+
+template <class MT>
+octave_value
+octave_base_matrix<MT>::do_index_op (const octave_value_list& idx,
+				     bool resize_ok)
+{
+  octave_value retval;
+
+  octave_idx_type n_idx = idx.length ();
+
+  int nd = matrix.ndims ();
+
+  switch (n_idx)
+    {
+    case 0:
+      retval = matrix;
+      break;
+
+    case 1:
+      {
+	idx_vector i = idx (0).index_vector ();
+
+	if (! error_state)
+          {
+            // optimize single scalar index.
+            if (i.is_scalar () && i(0) < matrix.numel ())
+              retval = const_cast<const MT&> (matrix)(i(0));
+            else
+              retval = MT (matrix.index (i, resize_ok));
+          }
+      }
+      break;
+
+    case 2:
+      {
+        idx_vector i = idx (0).index_vector ();
+
+        if (! error_state)
+          {
+            idx_vector j = idx (1).index_vector ();
+
+            if (! error_state)
+              {
+                // optimize two scalar indices.
+                if (i.is_scalar () && j.is_scalar () && nd == 2
+                    && i(0) < matrix.rows () && j(0) < matrix.columns ())
+                  retval = const_cast<const MT&> (matrix)(i(0), j(0));
+                else
+                  retval = MT (matrix.index (i, j, resize_ok));
+              }
+          }
+      }
+      break;
+
+    default:
+      {
+        Array<idx_vector> idx_vec (n_idx);
+        bool scalar_opt = n_idx == nd;
+        const dim_vector dv = matrix.dims ();
+
+        for (octave_idx_type i = 0; i < n_idx; i++)
+          {
+            idx_vec(i) = idx(i).index_vector ();
+
+            if (error_state)
+              break;
+
+            scalar_opt = (scalar_opt && idx_vec(i).is_scalar ()
+                          && idx_vec(i)(0) < dv(0));
+          }
+
+        if (! error_state)
+          {
+            if (scalar_opt)
+              {
+                // optimize all scalar indices. Don't construct an index array,
+                // but rather calc a scalar index directly.
+                octave_idx_type k = 1, j = 0;
+                for (octave_idx_type i = 0; i < n_idx; i++)
+                  {
+                    j += idx_vec(i)(0) * k;
+                    k *= dv (i);
+                  }
+                retval = const_cast<const MT&> (matrix)(j);
+              }
+            else
+              retval = MT (matrix.index (idx_vec, resize_ok));
+          }
+      }
+      break;
+    }
+
+  return retval;
+}
+
+template <class MT>
+void
+octave_base_matrix<MT>::assign (const octave_value_list& idx, const MT& rhs)
+{
+  octave_idx_type n_idx = idx.length ();
+
+  switch (n_idx)
+    {
+    case 0:
+      panic_impossible ();
+      break;
+
+    case 1:
+      {
+	idx_vector i = idx (0).index_vector ();
+
+	if (! error_state)
+          matrix.assign (i, rhs);
+      }
+      break;
+
+    case 2:
+      {
+        idx_vector i = idx (0).index_vector ();
+
+        if (! error_state)
+          {
+            idx_vector j = idx (1).index_vector ();
+
+            if (! error_state)
+              matrix.assign (i, j, rhs);
+          }
+      }
+      break;
+
+    default:
+      {
+        Array<idx_vector> idx_vec (n_idx);
+
+        for (octave_idx_type i = 0; i < n_idx; i++)
+          {
+            idx_vec(i) = idx(i).index_vector ();
+
+            if (error_state)
+              break;
+          }
+
+        if (! error_state)
+          matrix.assign (idx_vec, rhs);
+      }
+      break;
+    }
+
+  // Invalidate the matrix type
+  typ.invalidate_type ();
+}
+
+template <class MT>
+void
+octave_base_matrix<MT>::assign (const octave_value_list& idx,
+                                typename MT::element_type rhs)
+{
+  octave_idx_type n_idx = idx.length ();
+
+  int nd = matrix.ndims ();
+
+  MT mrhs (dim_vector (1), rhs);
+
+  switch (n_idx)
+    {
+    case 0:
+      panic_impossible ();
+      break;
+
+    case 1:
+      {
+	idx_vector i = idx (0).index_vector ();
+
+	if (! error_state)
+          {
+            // optimize single scalar index.
+            if (i.is_scalar () && i(0) < matrix.numel ())
+              matrix(i(0)) = rhs;
+            else
+              matrix.assign (i, mrhs);
+          }
+      }
+      break;
+
+    case 2:
+      {
+        idx_vector i = idx (0).index_vector ();
+
+        if (! error_state)
+          {
+            idx_vector j = idx (1).index_vector ();
+
+            if (! error_state)
+              {
+                // optimize two scalar indices.
+                if (i.is_scalar () && j.is_scalar () && nd == 2
+                    && i(0) < matrix.rows () && j(0) < matrix.columns ())
+                  matrix(i(0), j(0)) = rhs;
+                else
+                  matrix.assign (i, j, mrhs);
+              }
+          }
+      }
+      break;
+
+    default:
+      {
+        Array<idx_vector> idx_vec (n_idx);
+        bool scalar_opt = n_idx == nd;
+        const dim_vector dv = matrix.dims ().redim (n_idx);
+
+        for (octave_idx_type i = 0; i < n_idx; i++)
+          {
+            idx_vec(i) = idx(i).index_vector ();
+
+            if (error_state)
+              break;
+
+            scalar_opt = (scalar_opt && idx_vec(i).is_scalar ()
+                          && idx_vec(i)(0) < dv(i));
+          }
+
+        if (! error_state)
+          {
+            if (scalar_opt)
+              {
+                // optimize all scalar indices. Don't construct an index array,
+                // but rather calc a scalar index directly.
+                octave_idx_type k = 1, j = 0;
+                for (octave_idx_type i = 0; i < n_idx; i++)
+                  {
+                    j += idx_vec(i)(0) * k;
+                    k *= dv (i);
+                  }
+                matrix(j) = rhs;
+              }
+            else
+              matrix.assign (idx_vec, mrhs);
+          }
+      }
+      break;
+    }
+
+  // Invalidate the matrix type
+  typ.invalidate_type ();
+}
+
+template <class MT>
+void
+octave_base_matrix<MT>::delete_elements (const octave_value_list& idx)
+{
+  octave_idx_type len = idx.length ();
+
+  Array<idx_vector> ra_idx (len);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    ra_idx(i) = idx(i).index_vector ();
+
+  matrix.delete_elements (ra_idx);
+
+  // Invalidate the matrix type
+  typ.invalidate_type ();
+}
+
+template <class MT>
+octave_value
+octave_base_matrix<MT>::resize (const dim_vector& dv, bool fill) const
+{
+  MT retval (matrix); 
+  if (fill)
+    retval.resize (dv, 0);
+  else
+    retval.resize (dv); 
+  return retval;
+}
+
+template <class MT>
+bool
+octave_base_matrix<MT>::is_true (void) const
+{
+  bool retval = false;
+  dim_vector dv = matrix.dims ();
+  int nel = dv.numel ();
+
+  if (nel > 0)
+    {
+      MT t1 (matrix.reshape (dim_vector (nel, 1)));
+
+      if (t1.any_element_is_nan ())
+	error ("invalid conversion from NaN to logical");
+      else
+	{
+	  boolNDArray t2 = t1.all ();
+
+	  retval = t2(0);
+	}
+    }
+
+  return retval;
+}
+
+template <class MT>
+bool
+octave_base_matrix<MT>::print_as_scalar (void) const
+{
+  dim_vector dv = dims ();
+
+  return (dv.all_ones () || dv.any_zero ());
+}
+
+template <class MT>
+void
+octave_base_matrix<MT>::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+template <class MT>
+void
+octave_base_matrix<MT>::print_info (std::ostream& os,
+				    const std::string& prefix) const
+{
+  matrix.print_info (os, prefix);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-mat.h b/src/ov-base-mat.h
new file mode 100644
index 0000000..c6122c7
--- /dev/null
+++ b/src/ov-base-mat.h
@@ -0,0 +1,167 @@
+/*
+
+Copyright (C) 1998, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_matrix_h)
+#define octave_base_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+#include "MatrixType.h"
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+
+class tree_walker;
+
+// Real matrix values.
+
+template <class MT>
+class
+octave_base_matrix : public octave_base_value
+{
+public:
+
+  octave_base_matrix (void)
+    : octave_base_value (), typ (MatrixType ()) { }
+
+  octave_base_matrix (const MT& m, const MatrixType& t = MatrixType ())
+    : octave_base_value (), matrix (m), typ (t)
+  {
+    if (matrix.ndims () == 0)
+      matrix.resize (dim_vector (0, 0));
+  }
+
+  octave_base_matrix (const octave_base_matrix& m)
+    : octave_base_value (), matrix (m.matrix), typ (m.typ) { }
+
+  ~octave_base_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_base_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_matrix (); }
+
+  size_t byte_size (void) const { return matrix.byte_size (); }
+
+  octave_value squeeze (void) const { return MT (matrix.squeeze ()); }
+
+  octave_value full_value (void) const { return matrix; }
+
+  void maybe_economize (void) { matrix.maybe_economize (); }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx);
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int)
+    { return subsref (type, idx); }
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  void assign (const octave_value_list& idx, const MT& rhs);
+
+  void assign (const octave_value_list& idx, typename MT::element_type rhs);
+
+  void delete_elements (const octave_value_list& idx);
+
+  dim_vector dims (void) const { return matrix.dims (); }
+
+  octave_idx_type numel (void) const { return matrix.numel (); }
+
+  octave_idx_type nnz (void) const { return matrix.nnz (); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return MT (matrix.reshape (new_dims)); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return MT (matrix.permute (vec, inv)); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  octave_value all (int dim = 0) const { return matrix.all (dim); }
+  octave_value any (int dim = 0) const { return matrix.any (dim); }
+
+  MatrixType matrix_type (void) const { return typ; }
+  MatrixType matrix_type (const MatrixType& _typ) const
+    { MatrixType ret = typ; typ = _typ; return ret; }
+
+  octave_value diag (octave_idx_type k = 0) const
+    { return octave_value (matrix.diag (k)); }
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (dim, mode)); }
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (sidx, dim, mode)); }
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return matrix.is_sorted (mode); }
+
+  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const
+    { return matrix.sort_rows_idx (mode); }
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+    { return matrix.is_sorted_rows (mode); }
+
+  bool is_matrix_type (void) const { return true; }
+
+  bool is_numeric_type (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_true (void) const;
+
+  bool print_as_scalar (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
+
+protected:
+
+  MT matrix;
+
+  mutable MatrixType typ;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-scalar.cc b/src/ov-base-scalar.cc
new file mode 100644
index 0000000..bb5937d
--- /dev/null
+++ b/src/ov-base-scalar.cc
@@ -0,0 +1,148 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "oct-obj.h"
+#include "ov-base.h"
+#include "ov-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-base-scalar.h"
+#include "pr-output.h"
+
+template <class ST>
+octave_value
+octave_base_scalar<ST>::subsref (const std::string& type,
+				 const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front ());
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval.next_subsref (type, idx);
+}
+
+template <class ST>
+octave_value
+octave_base_scalar<ST>::subsasgn (const std::string& type,
+				  const std::list<octave_value_list>& idx,
+				  const octave_value& rhs)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	if (type.length () == 1)
+          retval = numeric_assign (type, idx, rhs);
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("in indexed assignment of %s, last rhs index must be ()",
+		   nm.c_str ());
+	  }
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval;
+}
+
+template <class ST>
+bool
+octave_base_scalar<ST>::is_true (void) const
+{
+  bool retval = false;
+
+  if (xisnan (scalar))
+    error ("invalid conversion from NaN to logical");
+  else
+    retval = (scalar != ST ());
+
+  return retval;
+}
+
+template <class ST>
+void
+octave_base_scalar<ST>::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+template <class ST>
+void
+octave_base_scalar<ST>::print_raw (std::ostream& os,
+				   bool pr_as_read_syntax) const
+{
+  indent (os);
+  octave_print_internal (os, scalar, pr_as_read_syntax);
+}
+
+template <class ST>
+bool
+octave_base_scalar<ST>::print_name_tag (std::ostream& os,
+					const std::string& name) const
+{
+  indent (os);
+  os << name << " = ";
+  return false;    
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-scalar.h b/src/ov-base-scalar.h
new file mode 100644
index 0000000..f1b7e74
--- /dev/null
+++ b/src/ov-base-scalar.h
@@ -0,0 +1,154 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_scalar_h)
+#define octave_base_scalar_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+#include "MatrixType.h"
+
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+// Real scalar values.
+
+template <class ST>
+class
+octave_base_scalar : public octave_base_value
+{
+public:
+
+  octave_base_scalar (void)
+    : octave_base_value (), typ (MatrixType ()) { }
+
+  octave_base_scalar (const ST& s, const MatrixType& t = MatrixType ())
+    : octave_base_value (), scalar (s), typ (t) { }
+
+  octave_base_scalar (const octave_base_scalar& s)
+    : octave_base_value (), scalar (s.scalar), typ (s.typ) { }
+
+  ~octave_base_scalar (void) { }
+
+  octave_base_value *clone (void) const { return new octave_base_scalar (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_scalar (); }
+
+  octave_value squeeze (void) const { return scalar; }
+
+  octave_value full_value (void) const { return scalar; }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx);
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int)
+    { return subsref (type, idx); }
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  bool is_constant (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+
+  dim_vector dims (void) const { static dim_vector dv (1, 1); return dv; }
+
+  octave_idx_type nnz (void) const { return (scalar != ST ()) ? 1 : 0; }
+
+  octave_value permute (const Array<int>&, bool = false) const
+    { return scalar; }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return array_value ().reshape (new_dims); }
+
+  size_t byte_size (void) const { return sizeof (ST); }
+
+  octave_value all (int = 0) const { return (scalar != ST ()); }
+
+  octave_value any (int = 0) const { return (scalar != ST ()); }
+
+  octave_value diag (octave_idx_type k = 0) const 
+    { return octave_value (matrix_value (). diag (k)); }
+
+  octave_value sort (octave_idx_type, sortmode) const
+    { return octave_value (scalar); }
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type,
+		     sortmode) const
+    { 
+      sidx.resize (dim_vector (1, 1)); 
+      sidx(0) = 0; 
+      return octave_value (scalar); 
+    }
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return mode ? mode : ASCENDING; }
+
+  Array<octave_idx_type> sort_rows_idx (sortmode) const
+    { return Array<octave_idx_type> (1, 0); }
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+    { return mode ? mode : ASCENDING; }
+
+  MatrixType matrix_type (void) const { return typ; }
+  MatrixType matrix_type (const MatrixType& _typ) const
+    { MatrixType ret = typ; typ = _typ; return ret; }
+
+  bool is_scalar_type (void) const { return true; }
+
+  bool is_numeric_type (void) const { return true; }
+
+  bool is_true (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const;
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return const_cast<ST *> (&scalar); }
+
+protected:
+
+  // The value of this scalar.
+  ST scalar;
+
+  mutable MatrixType typ;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-sparse.cc b/src/ov-base-sparse.cc
new file mode 100644
index 0000000..8e63cf1
--- /dev/null
+++ b/src/ov-base-sparse.cc
@@ -0,0 +1,376 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+
+#include "oct-obj.h"
+#include "ov-base.h"
+#include "quit.h"
+#include "pr-output.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+#include "boolSparse.h"
+#include "ov-base-sparse.h"
+#include "pager.h"
+
+template <class T>
+octave_value
+octave_base_sparse<T>::do_index_op (const octave_value_list& idx, 
+				    bool resize_ok)
+{
+  octave_value retval;
+
+  octave_idx_type n_idx = idx.length ();
+
+  int nd = matrix.ndims ();
+
+  switch (n_idx)
+    {
+    case 0:
+      retval = matrix;
+      break;
+
+    case 1:
+      {
+	idx_vector i = idx (0).index_vector ();
+
+	if (! error_state)
+	  retval = octave_value (matrix.index (i, resize_ok));
+      }
+      break;
+
+    default:
+      {
+	if (n_idx == 2 && nd == 2)
+	  {
+	    idx_vector i = idx (0).index_vector ();
+
+	    if (! error_state)
+	      {
+		idx_vector j = idx (1).index_vector ();
+
+		if (! error_state)
+		  retval = octave_value (matrix.index (i, j, resize_ok));
+	      }
+	  }
+	else
+	  {
+	    Array<idx_vector> idx_vec (n_idx);
+
+	    for (octave_idx_type i = 0; i < n_idx; i++)
+	      {
+		idx_vec(i) = idx(i).index_vector ();
+
+		if (error_state)
+		  break;
+	      }
+
+	    if (! error_state)
+	      retval = octave_value (matrix.index (idx_vec, resize_ok));
+	  }
+      }
+      break;
+    }
+
+  return retval;
+}
+
+template <class T>
+octave_value
+octave_base_sparse<T>::subsref (const std::string& type,
+				const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front ());
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval.next_subsref (type, idx);
+}
+
+template <class T>
+octave_value 
+octave_base_sparse<T>::subsasgn (const std::string& type,
+				 const std::list<octave_value_list>& idx,
+				 const octave_value& rhs)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	if (type.length () == 1)
+	  retval = numeric_assign (type, idx, rhs);
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("in indexed assignment of %s, last lhs index must be ()",
+		   nm.c_str ());
+	  }
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	if (is_empty ())
+	  {
+	    octave_value tmp = octave_value::empty_conv (type, rhs);
+
+	    retval = tmp.subsasgn (type, idx, rhs);
+	  }
+	else
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval;
+}
+
+template <class T>
+void 
+octave_base_sparse<T>::assign (const octave_value_list& idx, const T& rhs)
+{
+  octave_idx_type len = idx.length ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    matrix.set_index (idx(i).index_vector ());
+
+  ::assign (matrix, rhs);
+
+  // Invalidate matrix type.
+  typ.invalidate_type ();
+}
+
+template <class MT>
+void
+octave_base_sparse<MT>::delete_elements (const octave_value_list& idx)
+{
+  octave_idx_type len = idx.length ();
+
+  Array<idx_vector> ra_idx (len);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    ra_idx(i) = idx(i).index_vector ();
+
+  matrix.maybe_delete_elements (ra_idx);
+
+  // Invalidate the matrix type
+  typ.invalidate_type ();
+}
+
+template <class T>
+octave_value 
+octave_base_sparse<T>::resize (const dim_vector& dv, bool) const
+{ 
+  T retval (matrix); 
+  retval.resize (dv); 
+  return retval; 
+}
+
+template <class T>
+bool 
+octave_base_sparse<T>::is_true (void) const
+{
+  bool retval = false;
+  dim_vector dv = matrix.dims ();
+  octave_idx_type nel = dv.numel ();
+  octave_idx_type nz = nzmax ();
+
+  if (nz == nel && nel > 0)
+    {
+      T t1 (matrix.reshape (dim_vector (nel, 1)));
+
+      SparseBoolMatrix t2 = t1.all ();
+
+      retval = t2(0);
+    }
+
+  return retval;
+}
+
+template <class T>
+bool 
+octave_base_sparse<T>::print_as_scalar (void) const
+{
+  dim_vector dv = dims ();
+
+  return (dv.all_ones () || dv.any_zero ());
+}
+
+template <class T>
+void 
+octave_base_sparse<T>::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+template <class T>
+void 
+octave_base_sparse<T>::print_info (std::ostream& os, 
+				   const std::string& prefix) const
+{
+  matrix.print_info (os, prefix);
+}
+
+template <class T>
+void
+octave_base_sparse<T>::print_raw (std::ostream& os,
+				  bool pr_as_read_syntax) const
+{
+  octave_idx_type nr = matrix.rows ();
+  octave_idx_type nc = matrix.cols ();
+  octave_idx_type nz = nnz ();
+
+  // FIXME -- this should probably all be handled by a
+  // separate octave_print_internal function that can handle format
+  // compact, loose, etc.
+
+  os << "Compressed Column Sparse (rows = " << nr
+     << ", cols = " << nc
+     << ", nnz = " << nz;
+
+  double dnel = matrix.numel ();
+
+  if (dnel > 0)
+    os << " [" << std::setprecision (2) << (nz / dnel * 100) << "%]";
+
+  os << ")\n";
+
+  // add one to the printed indices to go from
+  //  zero-based to one-based arrays
+
+  if (nz != 0)
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  OCTAVE_QUIT;
+
+	  // FIXME -- is there an easy way to get the max row
+	  // and column indices so we can set the width appropriately
+	  // and line up the columns here?  Similarly, we should look
+	  // at all the nonzero values and display them with the same
+	  // formatting rules that apply to columns of a matrix.
+
+	  for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++)
+	    {
+	      os << "\n";
+	      os << "  (" << matrix.ridx(i)+1 <<
+		", "  << j+1 << ") -> ";
+
+	      octave_print_internal (os, matrix.data(i), pr_as_read_syntax);
+	    }
+	}
+    }
+}
+
+template <class T>
+bool
+octave_base_sparse<T>::save_ascii (std::ostream& os)
+{
+  dim_vector dv = this->dims ();
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  os << "# nnz: "      << nzmax () << "\n";
+  os << "# rows: "     << dv (0) << "\n";
+  os << "# columns: "  << dv (1) << "\n";
+
+  os << this->matrix;
+
+  return true;
+}
+
+template <class T>
+bool 
+octave_base_sparse<T>::load_ascii (std::istream& is)
+{
+  octave_idx_type nz = 0;
+  octave_idx_type nr = 0;
+  octave_idx_type nc = 0;
+  bool success = true;
+
+  if (extract_keyword (is, "nnz", nz, true) &&
+      extract_keyword (is, "rows", nr, true) &&
+      extract_keyword (is, "columns", nc, true))
+    {
+      T tmp (nr, nc, nz);
+
+      is >> tmp;
+
+      if (!is) 
+	{
+	  error ("load: failed to load matrix constant");
+	  success = false;
+	}
+
+      matrix = tmp;
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base-sparse.h b/src/ov-base-sparse.h
new file mode 100644
index 0000000..d56e0b0
--- /dev/null
+++ b/src/ov-base-sparse.h
@@ -0,0 +1,183 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_sparse_h)
+#define octave_base_sparse_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+#include "boolSparse.h"
+#include "MatrixType.h"
+
+class Octave_map;
+
+class tree_walker;
+
+class octave_sparse_bool_matrix;
+
+template <class T>
+class
+octave_base_sparse : public octave_base_value
+{
+ public:
+ 
+  octave_base_sparse (void) : octave_base_value (), typ (MatrixType ()) { }
+
+  octave_base_sparse (const T& a) : octave_base_value (), matrix (a),
+				    typ (MatrixType ())
+  {
+    if (matrix.ndims () == 0)
+      matrix.resize (dim_vector (0, 0));
+  }
+
+  octave_base_sparse (const T& a, const MatrixType& t) : octave_base_value (), 
+				matrix (a), typ (t)
+  {
+    if (matrix.ndims () == 0)
+      matrix.resize (dim_vector (0, 0));
+  }
+
+  octave_base_sparse (const octave_base_sparse& a) : 
+    octave_base_value (), matrix (a.matrix), typ (a.typ) { }
+
+  ~octave_base_sparse (void) { }
+
+  octave_base_value *clone (void) const { return new octave_base_sparse (*this); }
+  octave_base_value *empty_clone (void) const 
+    { return new octave_base_sparse (); }
+
+  octave_idx_type nnz (void) const { return matrix.nnz (); }
+
+  octave_idx_type nzmax (void) const { return matrix.nzmax (); }
+
+  size_t byte_size (void) const { return matrix.byte_size (); }
+
+  octave_value squeeze (void) const { return matrix.squeeze (); }
+
+  octave_value full_value (void) const { return matrix.matrix_value (); }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx);
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int)
+    { return subsref (type, idx); }
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  void assign (const octave_value_list& idx, const T& rhs);
+
+  void delete_elements (const octave_value_list& idx);
+
+  dim_vector dims (void) const { return matrix.dims (); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return T (matrix.reshape (new_dims)); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return T (matrix.permute (vec, inv)); }
+
+  octave_value resize (const dim_vector& dv, bool = false) const;
+
+  octave_value all (int dim = 0) const { return matrix.all (dim); }
+  octave_value any (int dim = 0) const { return matrix.any (dim); }
+
+  octave_value diag (octave_idx_type k = 0) const
+    { return octave_value (matrix.diag (k)); }
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (dim, mode)); }
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (sidx, dim, mode)); }
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return full_value ().is_sorted (mode); }
+
+  MatrixType matrix_type (void) const { return typ; }
+  MatrixType matrix_type (const MatrixType& _typ) const
+    { MatrixType ret = typ; typ = _typ; return ret; }
+
+  bool is_matrix_type (void) const { return true; }
+
+  bool is_numeric_type (void) const { return true; }
+
+  bool is_sparse_type (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_true (void) const;
+
+  octave_idx_type capacity (void) const { return matrix.capacity (); }
+
+  bool print_as_scalar (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  // Unsafe.  These functions exists to support the MEX interface.
+  // You should not use them anywhere else.
+  void *mex_get_data (void) const { return matrix.mex_get_data (); }
+
+  octave_idx_type *mex_get_ir (void) const { return matrix.mex_get_ir (); }
+
+  octave_idx_type *mex_get_jc (void) const { return matrix.mex_get_jc (); }
+
+protected:
+
+  T matrix;
+
+  mutable MatrixType typ;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base.cc b/src/ov-base.cc
new file mode 100644
index 0000000..dd3bc26
--- /dev/null
+++ b/src/ov-base.cc
@@ -0,0 +1,1453 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-cell.h"
+#include "ov-ch-mat.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-list.h"
+#include "ov-range.h"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "ov-str-mat.h"
+#include "ov-fcn-handle.h"
+#include "parse.h"
+#include "utils.h"
+#include "variables.h"
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value,
+				     "<unknown type>", "unknown");
+
+// TRUE means to perform automatic sparse to real mutation if there
+// is memory to be saved
+bool Vsparse_auto_mutate = false;
+
+octave_value
+octave_base_value::squeeze (void) const
+{
+  std::string nm = type_name ();
+  error ("squeeze: invalid operation for %s type", nm.c_str ());
+  return octave_value ();
+}
+
+octave_value
+octave_base_value::full_value (void) const
+{
+  gripe_wrong_type_arg ("full: invalid operation for %s type", type_name ());
+  return octave_value ();
+}
+
+octave_value
+octave_base_value::subsref (const std::string&,
+			    const std::list<octave_value_list>&)
+{
+  std::string nm = type_name ();
+  error ("can't perform indexing operations for %s type", nm.c_str ());
+  return octave_value ();
+}
+
+octave_value_list
+octave_base_value::subsref (const std::string&,
+			    const std::list<octave_value_list>&, int)
+{
+  std::string nm = type_name ();
+  error ("can't perform indexing operations for %s type", nm.c_str ());
+  return octave_value ();
+}
+
+octave_value
+octave_base_value::subsref (const std::string& type,
+			    const std::list<octave_value_list>& idx,
+                            bool /* auto_add */)
+{
+  // This way we may get a more meaningful error message.
+  return subsref (type, idx);
+}
+
+octave_value
+octave_base_value::do_index_op (const octave_value_list&, bool)
+{
+  std::string nm = type_name ();
+  error ("can't perform indexing operations for %s type", nm.c_str ());
+  return octave_value ();
+}
+
+octave_value_list
+octave_base_value::do_multi_index_op (int, const octave_value_list&)
+{
+  std::string nm = type_name ();
+  error ("can't perform indexing operations for %s type", nm.c_str ());
+  return octave_value ();
+}
+
+idx_vector
+octave_base_value::index_vector (void) const
+{
+  std::string nm = type_name ();
+  error ("%s type invalid as index value", nm.c_str ());
+  return idx_vector ();
+}
+
+int
+octave_base_value::ndims (void) const
+{
+  dim_vector dv = dims ();
+
+  int n_dims = dv.length ();
+     
+   // Remove trailing singleton dimensions.
+
+   for (int i = n_dims; i > 2; i--)
+     {
+       if (dv(i-1) == 1)
+	 n_dims--;
+       else
+	 break;
+     }
+   
+   // The result is always >= 2.
+
+   if (n_dims < 2)
+     n_dims = 2;
+
+   return n_dims;
+}
+
+octave_value
+octave_base_value::subsasgn (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     const octave_value& rhs)
+{
+  octave_value retval;
+
+  if (is_defined ())
+    {
+      if (is_numeric_type ())
+	{
+	  switch (type[0])
+	    {
+	    case '(':
+	      {
+		if (type.length () == 1)
+		  retval = numeric_assign (type, idx, rhs);
+		else if (is_empty ())
+		  {
+		    // Allow conversion of empty matrix to some other
+		    // type in cases like
+		    //
+		    //  x = []; x(i).f = rhs
+
+		    octave_value tmp = octave_value::empty_conv (type, rhs);
+
+		    retval = tmp.subsasgn (type, idx, rhs);
+		  }
+		else
+		  {
+		    std::string nm = type_name ();
+		    error ("in indexed assignment of %s, last rhs index must be ()",
+			   nm.c_str ());
+		  }
+	      }
+	      break;
+
+	    case '{':
+	    case '.':
+	      {
+		std::string nm = type_name ();
+		error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	      }
+	      break;
+
+	    default:
+	      panic_impossible ();
+	    }
+	}
+      else
+	{
+	  std::string nm = type_name ();
+	  error ("can't perform indexed assignment for %s type", nm.c_str ());
+	}
+    }
+  else
+    {
+      // Create new object of appropriate type for given index and rhs
+      // types and then call subsasgn again for that object.
+
+      octave_value tmp = octave_value::empty_conv (type, rhs);
+
+      retval = tmp.subsasgn (type, idx, rhs);
+    }
+
+  return retval;
+}
+
+octave_idx_type
+octave_base_value::nnz (void) const
+{
+  gripe_wrong_type_arg ("octave_base_value::nnz ()", type_name ());
+  return -1;
+}
+
+octave_idx_type
+octave_base_value::nzmax (void) const
+{
+  gripe_wrong_type_arg ("octave_base_value::nzmax ()", type_name ());
+  return -1;
+}
+
+octave_idx_type
+octave_base_value::nfields (void) const
+{
+  gripe_wrong_type_arg ("octave_base_value::nfields ()", type_name ());
+  return -1;
+}
+
+octave_value
+octave_base_value::reshape (const dim_vector&) const
+{
+  gripe_wrong_type_arg ("octave_base_value::reshape ()", type_name ());
+  return octave_value ();
+}
+
+octave_value
+octave_base_value::permute (const Array<int>&, bool) const
+{
+  gripe_wrong_type_arg ("octave_base_value::permute ()", type_name ());
+  return octave_value ();
+}
+
+octave_value
+octave_base_value::resize (const dim_vector&, bool) const
+{
+  gripe_wrong_type_arg ("octave_base_value::resize ()", type_name ());
+  return octave_value ();
+}
+
+MatrixType 
+octave_base_value::matrix_type (void) const
+{
+  gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
+  return MatrixType ();
+}
+
+MatrixType 
+octave_base_value::matrix_type (const MatrixType&) const
+{
+  gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
+  return MatrixType ();
+}
+
+octave_value
+octave_base_value::all (int) const
+{
+  return 0.0;
+}
+
+octave_value
+octave_base_value::any (int) const
+{
+  return 0.0;
+}
+
+octave_value
+octave_base_value::convert_to_str (bool pad, bool force, char type) const
+{
+  octave_value retval = convert_to_str_internal (pad, force, type);
+
+  if (! force && is_numeric_type ())
+    gripe_implicit_conversion ("Octave:num-to-str",
+			       type_name (), retval.type_name ());
+
+  return retval;
+}
+
+octave_value
+octave_base_value::convert_to_str_internal (bool, bool, char) const
+{
+  gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
+			type_name ());
+  return octave_value ();
+}
+
+void
+octave_base_value::convert_to_row_or_column_vector (void)
+{
+  gripe_wrong_type_arg
+    ("octave_base_value::convert_to_row_or_column_vector ()",
+     type_name ());
+}
+
+void
+octave_base_value::print (std::ostream&, bool) const
+{
+  gripe_wrong_type_arg ("octave_base_value::print ()", type_name ());
+}
+
+void
+octave_base_value::print_raw (std::ostream&, bool) const
+{
+  gripe_wrong_type_arg ("octave_base_value::print_raw ()", type_name ());
+}
+
+bool
+octave_base_value::print_name_tag (std::ostream& os, const std::string& name) const
+{
+  bool retval = false;
+
+  indent (os);
+
+  if (print_as_scalar ())
+    os << name << " = ";
+  else
+    {
+      os << name << " =";
+      newline (os);
+      newline (os);
+      retval = true;
+    }
+
+  return retval;
+}
+
+void
+octave_base_value::print_with_name (std::ostream& output_buf,
+				    const std::string& name, 
+				    bool print_padding) const
+{
+  bool pad_after = print_name_tag (output_buf, name);
+
+  print (output_buf);
+
+  if (print_padding && pad_after)
+    newline (output_buf);
+}
+
+void
+octave_base_value::print_info (std::ostream& os,
+			       const std::string& /* prefix */) const
+{
+  os << "no info for type: " << type_name () << "\n";
+}
+
+#define INT_CONV_METHOD(T, F, MIN_LIMIT, MAX_LIMIT) \
+  T \
+  octave_base_value::F ## _value (bool require_int, bool frc_str_conv) const \
+  { \
+    T retval = 0; \
+ \
+    double d = double_value (frc_str_conv); \
+ \
+    if (! error_state) \
+      { \
+	if (require_int && D_NINT (d) != d) \
+	  error ("conversion of %g to " #T " value failed", d); \
+	else if (d < MIN_LIMIT) \
+	  retval = MIN_LIMIT; \
+	else if (d > MAX_LIMIT) \
+	  retval = MAX_LIMIT; \
+	else \
+	  retval = static_cast<T> (::fix (d));	\
+      } \
+    else \
+      gripe_wrong_type_arg ("octave_base_value::" #F "_value ()", \
+			    type_name ()); \
+ \
+    return retval; \
+  }
+
+INT_CONV_METHOD (short int, short, SHRT_MIN, SHRT_MAX)
+INT_CONV_METHOD (unsigned short int, ushort, 0, USHRT_MAX)
+
+INT_CONV_METHOD (int, int, INT_MIN, INT_MAX)
+INT_CONV_METHOD (unsigned int, uint, 0, UINT_MAX)
+
+INT_CONV_METHOD (long int, long, LONG_MIN, LONG_MAX)
+INT_CONV_METHOD (unsigned long int, ulong, 0, ULONG_MAX)
+
+int
+octave_base_value::nint_value (bool frc_str_conv) const
+{
+  int retval = 0;
+
+  double d = double_value (frc_str_conv);
+
+  if (! error_state)
+    {
+      if (xisnan (d))
+	{
+	  error ("conversion of NaN to integer value failed");
+	  return retval;
+	}
+
+      retval = static_cast<int> (::fix (d));
+    }
+  else
+    gripe_wrong_type_arg ("octave_base_value::nint_value ()", type_name ());
+
+  return retval;
+}
+
+double
+octave_base_value::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+  gripe_wrong_type_arg ("octave_base_value::double_value ()", type_name ());
+  return retval;
+}
+
+float
+octave_base_value::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+  gripe_wrong_type_arg ("octave_base_value::float_value ()", type_name ());
+  return retval;
+}
+
+Cell
+octave_base_value::cell_value () const
+{
+  Cell retval;
+  gripe_wrong_type_arg ("octave_base_value::cell_value()", type_name ());
+  return retval;
+}
+
+Matrix
+octave_base_value::matrix_value (bool) const
+{
+  Matrix retval;
+  gripe_wrong_type_arg ("octave_base_value::matrix_value()", type_name ());
+  return retval;
+}
+
+FloatMatrix
+octave_base_value::float_matrix_value (bool) const
+{
+  FloatMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::float_matrix_value()", type_name ());
+  return retval;
+}
+
+NDArray
+octave_base_value::array_value (bool) const
+{
+  FloatNDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::array_value()", type_name ());
+  return retval;
+}
+
+FloatNDArray
+octave_base_value::float_array_value (bool) const
+{
+  FloatNDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::float_array_value()", type_name ());
+  return retval;
+}
+
+Complex
+octave_base_value::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+  Complex retval (tmp, tmp);
+  gripe_wrong_type_arg ("octave_base_value::complex_value()", type_name ());
+  return retval;
+}
+
+FloatComplex
+octave_base_value::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+  FloatComplex retval (tmp, tmp);
+  gripe_wrong_type_arg ("octave_base_value::float_complex_value()", type_name ());
+  return retval;
+}
+
+ComplexMatrix
+octave_base_value::complex_matrix_value (bool) const
+{
+  ComplexMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::complex_matrix_value()",
+			type_name ());
+  return retval;
+}
+
+FloatComplexMatrix
+octave_base_value::float_complex_matrix_value (bool) const
+{
+  FloatComplexMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::float_complex_matrix_value()",
+			type_name ());
+  return retval;
+}
+
+ComplexNDArray
+octave_base_value::complex_array_value (bool) const
+{
+  ComplexNDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::complex_array_value()",
+			type_name ());
+  return retval;
+}
+
+FloatComplexNDArray
+octave_base_value::float_complex_array_value (bool) const
+{
+  FloatComplexNDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::float_complex_array_value()",
+			type_name ());
+  return retval;
+}
+
+bool
+octave_base_value::bool_value (bool) const
+{
+  bool retval = false;
+  gripe_wrong_type_arg ("octave_base_value::bool_value()", type_name ());
+  return retval;
+}
+
+boolMatrix
+octave_base_value::bool_matrix_value (bool) const
+{
+  boolMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::bool_matrix_value()",
+			type_name ());
+  return retval;
+}
+
+boolNDArray
+octave_base_value::bool_array_value (bool) const
+{
+  boolNDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::bool_array_value()",
+			type_name ());
+  return retval;
+}
+
+charMatrix
+octave_base_value::char_matrix_value (bool force) const
+{
+  charMatrix retval;
+
+  octave_value tmp = convert_to_str (false, force);
+
+  if (! error_state)
+    retval = tmp.char_matrix_value ();
+
+  return retval;
+}
+
+charNDArray
+octave_base_value::char_array_value (bool) const
+{
+  charNDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::char_array_value()",
+			type_name ());
+  return retval;
+}
+
+SparseMatrix
+octave_base_value::sparse_matrix_value (bool) const
+{
+  SparseMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::sparse_matrix_value()", type_name ());
+  return retval;
+}
+
+SparseComplexMatrix
+octave_base_value::sparse_complex_matrix_value (bool) const
+{
+  SparseComplexMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::sparse_complex_matrix_value()", type_name ());
+  return retval;
+}
+
+SparseBoolMatrix
+octave_base_value::sparse_bool_matrix_value (bool) const
+{
+  SparseBoolMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::sparse_bool_matrix_value()", type_name ());
+  return retval;
+}
+
+DiagMatrix
+octave_base_value::diag_matrix_value (bool) const
+{
+  DiagMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::diag_matrix_value()", type_name ());
+  return retval;
+}
+
+FloatDiagMatrix
+octave_base_value::float_diag_matrix_value (bool) const
+{
+  FloatDiagMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::float_diag_matrix_value()", type_name ());
+  return retval;
+}
+
+ComplexDiagMatrix
+octave_base_value::complex_diag_matrix_value (bool) const
+{
+  ComplexDiagMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::complex_diag_matrix_value()", type_name ());
+  return retval;
+}
+
+FloatComplexDiagMatrix
+octave_base_value::float_complex_diag_matrix_value (bool) const
+{
+  FloatComplexDiagMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::float_complex_diag_matrix_value()", type_name ());
+  return retval;
+}
+
+PermMatrix
+octave_base_value::perm_matrix_value (void) const
+{
+  PermMatrix retval;
+  gripe_wrong_type_arg ("octave_base_value::perm_matrix_value()", type_name ());
+  return retval;
+}
+
+octave_int8
+octave_base_value::int8_scalar_value (void) const
+{
+  octave_int8 retval;
+  gripe_wrong_type_arg ("octave_base_value::int8_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_int16
+octave_base_value::int16_scalar_value (void) const
+{
+  octave_int16 retval;
+  gripe_wrong_type_arg ("octave_base_value::int16_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_int32
+octave_base_value::int32_scalar_value (void) const
+{
+  octave_int32 retval;
+  gripe_wrong_type_arg ("octave_base_value::int32_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_int64
+octave_base_value::int64_scalar_value (void) const
+{
+  octave_int64 retval;
+  gripe_wrong_type_arg ("octave_base_value::int64_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_uint8
+octave_base_value::uint8_scalar_value (void) const
+{
+  octave_uint8 retval;
+  gripe_wrong_type_arg ("octave_base_value::uint8_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_uint16
+octave_base_value::uint16_scalar_value (void) const
+{
+  octave_uint16 retval;
+  gripe_wrong_type_arg ("octave_base_value::uint16_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_uint32
+octave_base_value::uint32_scalar_value (void) const
+{
+  octave_uint32 retval;
+  gripe_wrong_type_arg ("octave_base_value::uint32_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+octave_uint64
+octave_base_value::uint64_scalar_value (void) const
+{
+  octave_uint64 retval;
+  gripe_wrong_type_arg ("octave_base_value::uint64_scalar_value()",
+			type_name ());
+  return retval;
+}
+
+int8NDArray
+octave_base_value::int8_array_value (void) const
+{
+  int8NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::int8_array_value()",
+			type_name ());
+  return retval;
+}
+
+int16NDArray
+octave_base_value::int16_array_value (void) const
+{
+  int16NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::int16_array_value()",
+			type_name ());
+  return retval;
+}
+
+int32NDArray
+octave_base_value::int32_array_value (void) const
+{
+  int32NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::int32_array_value()",
+			type_name ());
+  return retval;
+}
+
+int64NDArray
+octave_base_value::int64_array_value (void) const
+{
+  int64NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::int64_array_value()",
+			type_name ());
+  return retval;
+}
+
+uint8NDArray
+octave_base_value::uint8_array_value (void) const
+{
+  uint8NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::uint8_array_value()",
+			type_name ());
+  return retval;
+}
+
+uint16NDArray
+octave_base_value::uint16_array_value (void) const
+{
+  uint16NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::uint16_array_value()",
+			type_name ());
+  return retval;
+}
+
+uint32NDArray
+octave_base_value::uint32_array_value (void) const
+{
+  uint32NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::uint32_array_value()",
+			type_name ());
+  return retval;
+}
+
+uint64NDArray
+octave_base_value::uint64_array_value (void) const
+{
+  uint64NDArray retval;
+  gripe_wrong_type_arg ("octave_base_value::uint64_array_value()",
+			type_name ());
+  return retval;
+}
+
+string_vector
+octave_base_value::all_strings (bool pad) const
+{
+  string_vector retval;
+
+  octave_value tmp = convert_to_str (pad, true);
+
+  if (! error_state)
+    retval = tmp.all_strings ();
+
+  return retval;
+}
+
+std::string
+octave_base_value::string_value (bool force) const
+{
+  std::string retval;
+
+  octave_value tmp = convert_to_str (force);
+
+  if (! error_state)
+    retval = tmp.string_value ();
+
+  return retval;
+}
+
+Array<std::string>
+octave_base_value::cellstr_value (void) const
+{
+  Array<std::string> retval;
+  gripe_wrong_type_arg ("octave_base_value::cellstry_value()",
+			type_name ());
+  return retval;
+}
+
+Range
+octave_base_value::range_value (void) const
+{
+  Range retval;
+  gripe_wrong_type_arg ("octave_base_value::range_value()", type_name ());
+  return retval;
+}
+
+Octave_map
+octave_base_value::map_value (void) const
+{
+  Octave_map retval;
+  gripe_wrong_type_arg ("octave_base_value::map_value()", type_name ());
+  return retval;
+}
+
+string_vector
+octave_base_value::map_keys (void) const
+{
+  string_vector retval;
+  gripe_wrong_type_arg ("octave_base_value::map_keys()", type_name ());
+  return retval;
+}
+
+size_t
+octave_base_value::nparents (void) const
+{
+  size_t retval = 0;
+  gripe_wrong_type_arg ("octave_base_value::nparents()", type_name ());
+  return retval;
+}
+
+std::list<std::string>
+octave_base_value::parent_class_name_list (void) const
+{
+  std::list<std::string> retval;
+  gripe_wrong_type_arg ("octave_base_value::parent_class_name_list()",
+			type_name ());
+  return retval;
+}
+
+string_vector
+octave_base_value::parent_class_names (void) const
+{
+  string_vector retval;
+  gripe_wrong_type_arg ("octave_base_value::parent_class_names()",
+			type_name ());
+  return retval;
+}
+
+octave_function *
+octave_base_value::function_value (bool silent)
+{
+  octave_function *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::function_value()",
+			  type_name ());
+  return retval;
+}
+
+const octave_function *
+octave_base_value::function_value (bool silent) const
+{
+  const octave_function *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::function_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_user_function *
+octave_base_value::user_function_value (bool silent)
+{
+  octave_user_function *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::user_function_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_user_script *
+octave_base_value::user_script_value (bool silent)
+{
+  octave_user_script *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::user_script_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_user_code *
+octave_base_value::user_code_value (bool silent)
+{
+  octave_user_code *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::user_code_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_fcn_handle *
+octave_base_value::fcn_handle_value (bool silent)
+{
+  octave_fcn_handle *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::fcn_handle_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_fcn_inline *
+octave_base_value::fcn_inline_value (bool silent)
+{
+  octave_fcn_inline *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::fcn_inline_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_value_list
+octave_base_value::list_value (void) const
+{
+  octave_value_list retval;
+  gripe_wrong_type_arg ("octave_base_value::list_value()", type_name ());
+  return retval;
+}
+
+bool 
+octave_base_value::save_ascii (std::ostream&)
+{
+  gripe_wrong_type_arg ("octave_base_value::save_ascii()", type_name ());
+  return false;
+}
+
+bool 
+octave_base_value::load_ascii (std::istream&)
+{
+  gripe_wrong_type_arg ("octave_base_value::load_ascii()", type_name ());
+  return false;
+}
+
+bool 
+octave_base_value::save_binary (std::ostream&, bool&)
+{
+  gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
+  return false;
+}
+
+bool 
+octave_base_value::load_binary (std::istream&, bool,
+				oct_mach_info::float_format)
+{
+  gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
+  return false;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_base_value::save_hdf5 (hid_t, const char *, bool)
+{
+  gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
+
+  return false;
+}
+
+bool 
+octave_base_value::load_hdf5 (hid_t, const char *, bool)
+{
+  gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
+
+  return false;
+}
+
+#endif
+
+int
+octave_base_value::write (octave_stream&, int, oct_data_conv::data_type,
+			  int, oct_mach_info::float_format) const
+{
+  gripe_wrong_type_arg ("octave_base_value::write()", type_name ());
+
+  return false;
+}
+
+mxArray *
+octave_base_value::as_mxArray (void) const
+{
+  gripe_wrong_type_arg ("octave_base_value::as_mxArray ()", type_name ());
+
+  return 0;
+}
+
+octave_value
+octave_base_value::diag (octave_idx_type) const
+{
+  gripe_wrong_type_arg ("octave_base_value::diag ()", type_name ());
+
+  return octave_value();
+}
+
+octave_value
+octave_base_value::sort (octave_idx_type, sortmode) const
+{
+  gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ());
+
+  return octave_value();
+}
+
+octave_value
+octave_base_value::sort (Array<octave_idx_type> &, 
+			 octave_idx_type, sortmode) const
+{
+  gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ());
+
+  return octave_value();
+}
+
+sortmode
+octave_base_value::is_sorted (sortmode) const
+{
+  gripe_wrong_type_arg ("octave_base_value::is_sorted ()", type_name ());
+
+  return UNSORTED;
+}
+
+Array<octave_idx_type>
+octave_base_value::sort_rows_idx (sortmode) const
+{
+  gripe_wrong_type_arg ("octave_base_value::sort_rows_idx ()", type_name ());
+
+  return Array<octave_idx_type> ();
+}
+
+sortmode
+octave_base_value::is_sorted_rows (sortmode) const
+{
+  gripe_wrong_type_arg ("octave_base_value::is_sorted_rows ()", type_name ());
+
+  return UNSORTED;
+}
+
+#define UNDEFINED_MAPPER(F) \
+  octave_value \
+  octave_base_value::F (void) const \
+  { \
+    gripe_wrong_type_arg ("octave_base_value::" #F " ()", type_name ()); \
+    return octave_value (); \
+  }
+
+UNDEFINED_MAPPER (abs)
+UNDEFINED_MAPPER (acos)
+UNDEFINED_MAPPER (acosh)
+UNDEFINED_MAPPER (angle)
+UNDEFINED_MAPPER (arg)
+UNDEFINED_MAPPER (asin)
+UNDEFINED_MAPPER (asinh)
+UNDEFINED_MAPPER (atan)
+UNDEFINED_MAPPER (atanh)
+UNDEFINED_MAPPER (ceil)
+UNDEFINED_MAPPER (conj)
+UNDEFINED_MAPPER (cos)
+UNDEFINED_MAPPER (cosh)
+UNDEFINED_MAPPER (erf)
+UNDEFINED_MAPPER (erfc)
+UNDEFINED_MAPPER (exp)
+UNDEFINED_MAPPER (expm1)
+UNDEFINED_MAPPER (finite)
+UNDEFINED_MAPPER (fix)
+UNDEFINED_MAPPER (floor)
+UNDEFINED_MAPPER (gamma)
+UNDEFINED_MAPPER (imag)
+UNDEFINED_MAPPER (isinf)
+UNDEFINED_MAPPER (isna)
+UNDEFINED_MAPPER (isnan)
+UNDEFINED_MAPPER (lgamma)
+UNDEFINED_MAPPER (log)
+UNDEFINED_MAPPER (log2)
+UNDEFINED_MAPPER (log10)
+UNDEFINED_MAPPER (log1p)
+UNDEFINED_MAPPER (real)
+UNDEFINED_MAPPER (round)
+UNDEFINED_MAPPER (roundb)
+UNDEFINED_MAPPER (signum)
+UNDEFINED_MAPPER (sin)
+UNDEFINED_MAPPER (sinh)
+UNDEFINED_MAPPER (sqrt)
+UNDEFINED_MAPPER (tan)
+UNDEFINED_MAPPER (tanh)
+
+// String mapper functions, convert to a string
+
+#define STRING_MAPPER(F) \
+  octave_value \
+  octave_base_value::F (void) const \
+  { \
+    octave_value tmp = octave_value (char_array_value (true), true); \
+    return error_state ? octave_value () : octave_value (tmp.F ()); \
+  }
+
+STRING_MAPPER (xisalnum)
+STRING_MAPPER (xisalpha)
+STRING_MAPPER (xisascii)
+STRING_MAPPER (xiscntrl)
+STRING_MAPPER (xisdigit)
+STRING_MAPPER (xisgraph)
+STRING_MAPPER (xislower)
+STRING_MAPPER (xisprint)
+STRING_MAPPER (xispunct)
+STRING_MAPPER (xisspace)
+STRING_MAPPER (xisupper)
+STRING_MAPPER (xisxdigit)
+STRING_MAPPER (xtoascii)
+STRING_MAPPER (xtolower)
+STRING_MAPPER (xtoupper)
+
+void
+octave_base_value::lock (void)
+{
+  gripe_wrong_type_arg ("octave_base_value::lock ()", type_name ());
+}
+
+void
+octave_base_value::unlock (void)
+{
+  gripe_wrong_type_arg ("octave_base_value::unlock ()", type_name ());
+}
+
+void
+octave_base_value::dump (std::ostream& os) const
+{
+  dim_vector dv = this->dims ();
+
+  os << "class: " << this->class_name ()
+     << " type: " << this->type_name ()
+     << " dims: " << dv.str ();
+}
+
+static void
+gripe_indexed_assignment (const std::string& tn1, const std::string& tn2)
+{
+  error ("assignment of `%s' to indexed `%s' not implemented",
+	 tn2.c_str (), tn1.c_str ());
+}
+
+static void
+gripe_assign_conversion_failed (const std::string& tn1,
+				const std::string& tn2)
+{
+  error ("type conversion for assignment of `%s' to indexed `%s' failed",
+	 tn2.c_str (), tn1.c_str ());
+}
+
+static void
+gripe_no_conversion (const std::string& on, const std::string& tn1,
+		     const std::string& tn2)
+{
+  error ("operator %s: no conversion for assignment of `%s' to indexed `%s'",
+	 on.c_str (), tn2.c_str (), tn1.c_str ());
+}
+
+octave_value
+octave_base_value::numeric_assign (const std::string& type,
+				   const std::list<octave_value_list>& idx,
+				   const octave_value& rhs)
+{
+  octave_value retval;
+
+  if (idx.front ().empty ())
+    {
+      error ("missing index in indexed assignment");
+      return retval;
+    }
+
+  int t_lhs = type_id ();
+  int t_rhs = rhs.type_id ();
+
+  octave_value_typeinfo::assign_op_fcn f
+    = octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
+					       t_lhs, t_rhs);
+
+  bool done = false;
+
+  if (f)
+    {
+      f (*this, idx.front (), rhs.get_rep ());
+
+      done = (! error_state);
+    }
+
+  if (done)
+    {
+      count++;
+      retval = octave_value (this);
+    }
+  else
+    {
+      int t_result
+	= octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
+
+      if (t_result >= 0)
+	{
+	  octave_base_value::type_conv_fcn cf
+	    = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
+
+	  if (cf)
+	    {
+	      octave_base_value *tmp = cf (*this);
+
+	      if (tmp)
+		{
+		  octave_value val (tmp);
+
+		  retval = val.subsasgn (type, idx, rhs);
+
+		  done = (! error_state);
+		}
+	      else
+		gripe_assign_conversion_failed (type_name (),
+						rhs.type_name ());
+	    }
+	  else
+	    gripe_indexed_assignment (type_name (), rhs.type_name ());
+	}
+
+      if (! (done || error_state))
+	{
+	  octave_value tmp_rhs;
+
+	  octave_base_value::type_conv_info cf_rhs
+	    = rhs.numeric_conversion_function ();
+
+	  octave_base_value::type_conv_info cf_this
+	    = numeric_conversion_function ();
+
+          // Try biased (one-sided) conversions first.
+          if (cf_rhs.type_id () >= 0
+              && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
+                                                           t_lhs, cf_rhs.type_id ())
+                  || octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, 
+                                                                     cf_rhs.type_id ()) >= 0))
+            cf_this = 0;
+          else if (cf_this.type_id () >= 0
+                   && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
+                                                                cf_this.type_id (), t_rhs)
+                       || octave_value_typeinfo::lookup_pref_assign_conv (cf_this.type_id (),
+                                                                          t_rhs) >= 0))
+            cf_rhs = 0;
+
+	  if (cf_rhs)
+	    {
+	      octave_base_value *tmp = cf_rhs (rhs.get_rep ());
+
+	      if (tmp)
+		tmp_rhs = octave_value (tmp);
+	      else
+		{
+		  gripe_assign_conversion_failed (type_name (),
+						  rhs.type_name ());
+		  return octave_value ();
+		}
+	    }
+	  else
+	    tmp_rhs = rhs;
+
+	  count++;
+	  octave_value tmp_lhs = octave_value (this);
+
+	  if (cf_this)
+	    {
+	      octave_base_value *tmp = cf_this (*this);
+
+	      if (tmp)
+		tmp_lhs = octave_value (tmp);
+	      else
+		{
+		  gripe_assign_conversion_failed (type_name (),
+						  rhs.type_name ());
+		  return octave_value ();
+		}
+	    }
+
+	  if (cf_this || cf_rhs)
+	    {
+	      retval = tmp_lhs.subsasgn (type, idx, tmp_rhs);
+
+	      done = (! error_state);
+	    }
+	  else
+	    gripe_no_conversion (octave_value::assign_op_as_string (octave_value::op_asn_eq),
+				 type_name (), rhs.type_name ());
+	}
+    }
+
+  // The assignment may have converted to a type that is wider than
+  // necessary.
+
+  retval.maybe_mutate ();
+
+  return retval;
+}
+
+// Current indentation.
+int octave_base_value::curr_print_indent_level = 0;
+
+// TRUE means we are at the beginning of a line.
+bool octave_base_value::beginning_of_line = true;
+
+// Each print() function should call this before printing anything.
+//
+// This doesn't need to be fast, but isn't there a better way?
+
+void
+octave_base_value::indent (std::ostream& os) const
+{
+  assert (curr_print_indent_level >= 0);
+ 
+  if (beginning_of_line)
+    {
+      // FIXME -- do we need this?
+      // os << prefix;
+
+      for (int i = 0; i < curr_print_indent_level; i++)
+	os << " ";
+
+      beginning_of_line = false;
+    }
+}
+
+// All print() functions should use this to print new lines.
+
+void
+octave_base_value::newline (std::ostream& os) const
+{
+  os << "\n";
+
+  beginning_of_line = true;
+}
+
+// For ressetting print state.
+
+void
+octave_base_value::reset (void) const
+{
+  beginning_of_line = true;
+  curr_print_indent_level = 0;
+}
+
+CONVDECLX (matrix_conv)
+{
+  return new octave_matrix ();
+}
+
+CONVDECLX (complex_matrix_conv)
+{
+  return new octave_complex_matrix ();
+}
+
+CONVDECLX (string_conv)
+{
+  return new octave_char_matrix_str ();
+}
+
+CONVDECLX (cell_conv)
+{
+  return new octave_cell ();
+}
+
+void
+install_base_type_conversions (void)
+{
+  INSTALL_ASSIGNCONV (octave_base_value, octave_scalar, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_base_value, octave_matrix, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_base_value, octave_complex, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_base_value, octave_complex_matrix, octave_complex_matrix);
+  INSTALL_ASSIGNCONV (octave_base_value, octave_range, octave_matrix);
+  INSTALL_ASSIGNCONV (octave_base_value, octave_char_matrix_str, octave_char_matrix_str);
+  INSTALL_ASSIGNCONV (octave_base_value, octave_cell, octave_cell);
+
+  INSTALL_WIDENOP (octave_base_value, octave_matrix, matrix_conv);
+  INSTALL_WIDENOP (octave_base_value, octave_complex_matrix, complex_matrix_conv);
+  INSTALL_WIDENOP (octave_base_value, octave_char_matrix_str, string_conv);
+  INSTALL_WIDENOP (octave_base_value, octave_cell, cell_conv);
+}
+
+DEFUN (sparse_auto_mutate, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} sparse_auto_mutate ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} sparse_auto_mutate (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave will\n\
+automatically mutate sparse matrices to real matrices to save memory.\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+s = speye(3);\n\
+sparse_auto_mutate (false)\n\
+s (:, 1) = 1;\n\
+typeinfo (s)\n\
+ at result{} sparse matrix\n\
+sparse_auto_mutate (true)\n\
+s (1, :) = 1;\n\
+typeinfo (s)\n\
+ at result{} matrix\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (sparse_auto_mutate);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-base.h b/src/ov-base.h
new file mode 100644
index 0000000..b4b8c64
--- /dev/null
+++ b/src/ov-base.h
@@ -0,0 +1,662 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_base_value_h)
+#define octave_base_value_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <list>
+#include <string>
+
+#include "Range.h"
+#include "data-conv.h"
+#include "mxarray.h"
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-hdf5.h"
+
+class Cell;
+class Octave_map;
+class octave_value;
+class octave_value_list;
+class octave_stream;
+class octave_function;
+class octave_user_function;
+class octave_user_script;
+class octave_user_code;
+class octave_fcn_handle;
+class octave_fcn_inline;
+class octave_value_list;
+class octave_lvalue;
+
+class tree_walker;
+
+// T_ID is the type id of struct objects, set by register_type().
+// T_NAME is the type name of struct objects.
+
+#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA \
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2 (OCTAVE_EMPTY_CPP_ARG)
+
+#define DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA \
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(virtual)
+
+#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(VIRTUAL) \
+  public: \
+    VIRTUAL int type_id (void) const { return t_id; } \
+    VIRTUAL std::string type_name (void) const { return t_name; } \
+    VIRTUAL std::string class_name (void) const { return c_name; } \
+    static int static_type_id (void) { return t_id; } \
+    static std::string static_type_name (void) { return t_name; } \
+    static std::string static_class_name (void) { return c_name; } \
+    static void register_type (void); \
+ \
+  private: \
+    static int t_id; \
+    static const std::string t_name; \
+    static const std::string c_name;
+
+
+#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c) \
+  int t::t_id (-1); \
+  const std::string t::t_name (n); \
+  const std::string t::c_name (c); \
+  void t::register_type (void) \
+    { \
+      t_id = octave_value_typeinfo::register_type (t::t_name, \
+						   t::c_name, \
+						   octave_value (new t ())); \
+    }
+
+// A base value type, so that derived types only have to redefine what
+// they need (if they are derived from octave_base_value instead of
+// octave_value).
+
+class
+OCTINTERP_API
+octave_base_value
+{
+public:
+
+  typedef octave_base_value * (*type_conv_fcn) (const octave_base_value&);
+
+  // type conversion, including result type information
+  class type_conv_info
+  {
+  public:
+    type_conv_info (type_conv_fcn f = 0, int t = -1) : _fcn (f), _type_id (t) { }
+
+    operator type_conv_fcn (void) const { return _fcn; }
+
+    octave_base_value * operator () (const octave_base_value &v) const 
+      { return (*_fcn) (v); }
+
+    int type_id (void) const { return _type_id; }
+
+  private:
+    type_conv_fcn _fcn;
+    int _type_id;
+  };
+
+  friend class octave_value;
+
+  octave_base_value (void) : count (1) { }
+
+  octave_base_value (const octave_base_value&) { }
+
+  virtual ~octave_base_value (void) { }
+
+  virtual octave_base_value *
+  clone (void) const { return new octave_base_value (*this); }
+
+  virtual octave_base_value *
+  empty_clone (void) const { return new octave_base_value (); }
+
+  virtual type_conv_info
+  numeric_conversion_function (void) const
+    { return type_conv_info (); }
+
+  virtual type_conv_info
+  numeric_demotion_function (void) const
+    { return type_conv_info (); }
+
+  virtual octave_value squeeze (void) const;
+
+  virtual octave_value full_value (void) const;
+
+  virtual octave_base_value *try_narrowing_conversion (void) { return 0; }
+
+  virtual void maybe_economize (void) { }
+
+  virtual octave_value
+  subsref (const std::string& type,
+	   const std::list<octave_value_list>& idx);
+
+  virtual octave_value_list
+  subsref (const std::string& type,
+	   const std::list<octave_value_list>& idx,
+	   int nargout);
+
+  virtual octave_value
+  subsref (const std::string& type,
+	   const std::list<octave_value_list>& idx,
+           bool auto_add);
+
+  virtual octave_value
+  do_index_op (const octave_value_list& idx, bool resize_ok = false);
+
+  virtual octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& idx);
+
+  virtual void assign (const std::string&, const octave_value&) { }
+
+  virtual octave_value
+  subsasgn (const std::string& type,
+	    const std::list<octave_value_list>& idx,
+	    const octave_value& rhs);
+
+  virtual idx_vector index_vector (void) const;
+
+  virtual dim_vector dims (void) const { return dim_vector (-1, -1); }
+
+  octave_idx_type rows (void) const
+    {
+      dim_vector dv = dims ();
+
+      return (dv.length () > 0) ? dv(0) : -1;
+    }
+
+  octave_idx_type columns (void) const
+    {
+      dim_vector dv = dims ();
+
+      return (dv.length () > 1) ? dv(1) : -1;
+    }
+
+  virtual int ndims (void) const;
+
+  virtual octave_idx_type numel (void) const { return dims ().numel (); }
+
+  virtual octave_idx_type capacity (void) const { return numel (); }
+
+  virtual size_t byte_size (void) const { return 0; }
+
+  virtual octave_idx_type nnz (void) const;
+
+  virtual octave_idx_type nzmax (void) const;
+
+  virtual octave_idx_type nfields (void) const;
+
+  virtual octave_value reshape (const dim_vector&) const;
+
+  virtual octave_value permute (const Array<int>& vec, bool = false) const;
+
+  virtual octave_value resize (const dim_vector&, bool fill = false) const;
+
+  virtual MatrixType matrix_type (void) const;
+
+  virtual MatrixType matrix_type (const MatrixType& typ) const;
+
+  virtual bool is_defined (void) const { return false; }
+
+  bool is_empty (void) const { return numel () == 0; }
+
+  virtual bool is_cell (void) const { return false; }
+
+  virtual bool is_cellstr (void) const { return false; }
+
+  virtual bool is_real_scalar (void) const { return false; }
+
+  virtual bool is_real_matrix (void) const { return false; }
+
+  virtual bool is_real_nd_array (void) const { return false; }
+
+  virtual bool is_complex_scalar (void) const { return false; }
+
+  virtual bool is_complex_matrix (void) const { return false; }
+
+  virtual bool is_bool_scalar (void) const { return false; }
+
+  virtual bool is_bool_matrix (void) const { return false; }
+
+  virtual bool is_char_matrix (void) const { return false; }
+
+  virtual bool is_diag_matrix (void) const { return false; }
+
+  virtual bool is_perm_matrix (void) const { return false; }
+
+  virtual bool is_string (void) const { return false; }
+
+  virtual bool is_sq_string (void) const { return false; }
+
+  virtual bool is_range (void) const { return false; }
+
+  virtual bool is_map (void) const { return false; }
+
+  virtual bool is_object (void) const { return false; }
+
+  virtual bool is_cs_list (void) const { return false; }
+
+  virtual bool is_list (void) const { return false; }
+
+  virtual bool is_magic_colon (void) const { return false; }
+
+  virtual bool is_all_va_args (void) const { return false; }
+
+  virtual octave_value all (int = 0) const;
+
+  virtual octave_value any (int = 0) const;
+
+  virtual bool is_double_type (void) const { return false; }
+
+  virtual bool is_single_type (void) const { return false; }
+
+  virtual bool is_float_type (void) const { return false; }
+
+  virtual bool is_int8_type (void) const { return false; }
+
+  virtual bool is_int16_type (void) const { return false; }
+
+  virtual bool is_int32_type (void) const { return false; }
+
+  virtual bool is_int64_type (void) const { return false; }
+
+  virtual bool is_uint8_type (void) const { return false; }
+
+  virtual bool is_uint16_type (void) const { return false; }
+
+  virtual bool is_uint32_type (void) const { return false; }
+
+  virtual bool is_uint64_type (void) const { return false; }
+
+  virtual bool is_bool_type (void) const { return false; }
+
+  virtual bool is_integer_type (void) const { return false; }
+
+  virtual bool is_real_type (void) const { return false; }
+
+  virtual bool is_complex_type (void) const { return false; }
+
+  // Would be nice to get rid of the next four functions:
+
+  virtual bool is_scalar_type (void) const { return false; }
+
+  virtual bool is_matrix_type (void) const { return false; }
+
+  virtual bool is_numeric_type (void) const { return false; }
+
+  virtual bool is_sparse_type (void) const { return false; }
+
+  virtual bool is_true (void) const { return false; }
+
+  virtual bool is_null_value (void) const { return false; }
+
+  virtual bool is_constant (void) const { return false; }
+
+  virtual bool is_function_handle (void) const { return false; }
+
+  virtual bool is_inline_function (void) const { return false; }
+
+  virtual bool is_function (void) const { return false; }
+
+  virtual bool is_user_script (void) const { return false; }
+
+  virtual bool is_user_function (void) const { return false; }
+
+  virtual bool is_user_code (void) const { return false; }
+
+  virtual bool is_builtin_function (void) const { return false; }
+
+  virtual bool is_dld_function (void) const { return false; }
+
+  virtual bool is_mex_function (void) const { return false; }
+
+  virtual void erase_subfunctions (void) { }
+
+  virtual short int short_value (bool = false, bool = false) const;
+
+  virtual unsigned short int ushort_value (bool = false, bool = false) const;
+
+  virtual int int_value (bool = false, bool = false) const;
+
+  virtual unsigned int uint_value (bool = false, bool = false) const;
+
+  virtual int nint_value (bool = false) const;
+
+  virtual long int long_value (bool = false, bool = false) const;
+
+  virtual unsigned long int ulong_value (bool = false, bool = false) const;
+
+  virtual double double_value (bool = false) const;
+
+  virtual float float_value (bool = false) const;
+
+  virtual double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  virtual float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  virtual Cell cell_value (void) const;
+
+  virtual Matrix matrix_value (bool = false) const;
+
+  virtual FloatMatrix float_matrix_value (bool = false) const;
+
+  virtual NDArray array_value (bool = false) const;
+
+  virtual FloatNDArray float_array_value (bool = false) const;
+
+  virtual Complex complex_value (bool = false) const;
+
+  virtual FloatComplex float_complex_value (bool = false) const;
+
+  virtual ComplexMatrix complex_matrix_value (bool = false) const;
+
+  virtual FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  virtual ComplexNDArray complex_array_value (bool = false) const;
+
+  virtual FloatComplexNDArray float_complex_array_value (bool = false) const;
+
+  virtual bool bool_value (bool = false) const;
+
+  virtual boolMatrix bool_matrix_value (bool = false) const;
+
+  virtual boolNDArray bool_array_value (bool = false) const;
+
+  virtual charMatrix char_matrix_value (bool force = false) const;
+
+  virtual charNDArray char_array_value (bool = false) const;
+
+  virtual SparseMatrix sparse_matrix_value (bool = false) const;
+
+  virtual SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  virtual SparseBoolMatrix sparse_bool_matrix_value (bool = false) const;
+
+  virtual DiagMatrix diag_matrix_value (bool = false) const;
+
+  virtual FloatDiagMatrix float_diag_matrix_value (bool = false) const;
+  
+  virtual ComplexDiagMatrix complex_diag_matrix_value (bool = false) const;
+  
+  virtual FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
+  
+  virtual PermMatrix perm_matrix_value (void) const;
+
+  virtual octave_int8 int8_scalar_value (void) const;
+
+  virtual octave_int16 int16_scalar_value (void) const;
+
+  virtual octave_int32 int32_scalar_value (void) const;
+
+  virtual octave_int64 int64_scalar_value (void) const;
+
+  virtual octave_uint8 uint8_scalar_value (void) const;
+
+  virtual octave_uint16 uint16_scalar_value (void) const;
+
+  virtual octave_uint32 uint32_scalar_value (void) const;
+
+  virtual octave_uint64 uint64_scalar_value (void) const;
+
+  virtual int8NDArray int8_array_value (void) const;
+
+  virtual int16NDArray int16_array_value (void) const;
+
+  virtual int32NDArray int32_array_value (void) const;
+
+  virtual int64NDArray int64_array_value (void) const;
+
+  virtual uint8NDArray uint8_array_value (void) const;
+
+  virtual uint16NDArray uint16_array_value (void) const;
+
+  virtual uint32NDArray uint32_array_value (void) const;
+
+  virtual uint64NDArray uint64_array_value (void) const;
+
+  virtual string_vector all_strings (bool pad = false) const;
+
+  virtual std::string string_value (bool force = false) const;
+
+  virtual Array<std::string> cellstr_value (void) const;
+
+  virtual Range range_value (void) const;
+
+  virtual Octave_map map_value (void) const;
+
+  virtual string_vector map_keys (void) const;
+
+  virtual size_t nparents (void) const;
+
+  virtual std::list<std::string> parent_class_name_list (void) const;
+
+  virtual string_vector parent_class_names (void) const;
+
+  virtual octave_base_value *find_parent_class (const std::string&)
+    { return 0; }
+
+  virtual octave_function *function_value (bool silent = false);
+
+  virtual const octave_function *function_value (bool silent = false) const;
+
+  virtual octave_user_function *user_function_value (bool silent = false);
+
+  virtual octave_user_script *user_script_value (bool silent = false);
+
+  virtual octave_user_code *user_code_value (bool silent = false);
+
+  virtual octave_fcn_handle *fcn_handle_value (bool silent = false);
+
+  virtual octave_fcn_inline *fcn_inline_value (bool silent = false);
+
+  virtual octave_value_list list_value (void) const;
+
+  virtual octave_value convert_to_str (bool pad = false, bool force = false,
+				       char type = '"') const;
+  virtual octave_value
+  convert_to_str_internal (bool pad, bool force, char type) const;
+
+  virtual void convert_to_row_or_column_vector (void);
+
+  virtual bool print_as_scalar (void) const { return false; }
+
+  virtual void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  virtual void
+  print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  virtual bool
+  print_name_tag (std::ostream& os, const std::string& name) const;
+
+  virtual void
+  print_with_name (std::ostream& output_buf, const std::string& name, 
+		   bool print_padding = true) const;
+
+  virtual void print_info (std::ostream& os, const std::string& prefix) const;
+
+  virtual bool save_ascii (std::ostream& os);
+
+  virtual bool load_ascii (std::istream& is);
+
+  virtual bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  virtual bool load_binary (std::istream& is, bool swap, 
+			    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  virtual bool
+  save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  virtual bool
+  load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  virtual int
+  write (octave_stream& os, int block_size,
+	 oct_data_conv::data_type output_type, int skip,
+	 oct_mach_info::float_format flt_fmt) const;
+
+  virtual void *mex_get_data (void) const { return 0; }
+
+  virtual octave_idx_type *mex_get_ir (void) const { return 0; }
+
+  virtual octave_idx_type *mex_get_jc (void) const { return 0; }
+
+  virtual mxArray *as_mxArray (void) const;
+
+  virtual octave_value diag (octave_idx_type k = 0) const;
+
+  virtual octave_value sort (octave_idx_type dim = 0, 
+			     sortmode mode = ASCENDING) const;
+  virtual octave_value sort (Array<octave_idx_type> &sidx, 
+			     octave_idx_type dim = 0,
+			     sortmode mode = ASCENDING) const;
+
+  virtual sortmode is_sorted (sortmode mode = UNSORTED) const;
+
+  virtual Array<octave_idx_type>
+  sort_rows_idx (sortmode mode = ASCENDING) const;
+
+  virtual sortmode is_sorted_rows (sortmode mode = UNSORTED) const;
+
+  virtual void lock (void);
+
+  virtual void unlock (void);
+
+  virtual bool islocked (void) const { return false; }
+
+  virtual void dump (std::ostream& os) const;
+
+  virtual octave_value abs (void) const;
+  virtual octave_value acos (void) const;
+  virtual octave_value acosh (void) const;
+  virtual octave_value angle (void) const;
+  virtual octave_value arg (void) const;
+  virtual octave_value asin (void) const;
+  virtual octave_value asinh (void) const;
+  virtual octave_value atan (void) const;
+  virtual octave_value atanh (void) const;
+  virtual octave_value ceil (void) const;
+  virtual octave_value conj (void) const;
+  virtual octave_value cos (void) const;
+  virtual octave_value cosh (void) const;
+  virtual octave_value erf (void) const;
+  virtual octave_value erfc (void) const;
+  virtual octave_value exp (void) const;
+  virtual octave_value expm1 (void) const;
+  virtual octave_value finite (void) const;
+  virtual octave_value fix (void) const;
+  virtual octave_value floor (void) const;
+  virtual octave_value gamma (void) const;
+  virtual octave_value imag (void) const;
+  virtual octave_value isinf (void) const;
+  virtual octave_value isna (void) const;
+  virtual octave_value isnan (void) const;
+  virtual octave_value lgamma (void) const;
+  virtual octave_value log (void) const;
+  virtual octave_value log2 (void) const;
+  virtual octave_value log10 (void) const;
+  virtual octave_value log1p (void) const;
+  virtual octave_value real (void) const;
+  virtual octave_value round (void) const;
+  virtual octave_value roundb (void) const;
+  virtual octave_value signum (void) const;
+  virtual octave_value sin (void) const;
+  virtual octave_value sinh (void) const;
+  virtual octave_value sqrt (void) const;
+  virtual octave_value tan (void) const;
+  virtual octave_value tanh (void) const;
+
+  // These functions are prefixed with X to avoid potential macro
+  // conflicts.
+
+  virtual octave_value xisalnum (void) const;
+  virtual octave_value xisalpha (void) const;
+  virtual octave_value xisascii (void) const;
+  virtual octave_value xiscntrl (void) const;
+  virtual octave_value xisdigit (void) const;
+  virtual octave_value xisgraph (void) const;
+  virtual octave_value xislower (void) const;
+  virtual octave_value xisprint (void) const;
+  virtual octave_value xispunct (void) const;
+  virtual octave_value xisspace (void) const;
+  virtual octave_value xisupper (void) const;
+  virtual octave_value xisxdigit (void) const;
+  virtual octave_value xtoascii (void) const;
+  virtual octave_value xtolower (void) const;
+  virtual octave_value xtoupper (void) const;
+
+protected:
+
+  // This should only be called for derived types.
+
+  octave_value numeric_assign (const std::string& type,
+			       const std::list<octave_value_list>& idx,
+			       const octave_value& rhs);
+
+  void reset_indent_level (void) const
+    { curr_print_indent_level = 0; }
+
+  void increment_indent_level (void) const
+    { curr_print_indent_level += 2; }
+
+  void decrement_indent_level (void) const
+    { curr_print_indent_level -= 2; }
+
+  int current_print_indent_level (void) const
+    { return curr_print_indent_level; }
+
+  void indent (std::ostream& os) const;
+
+  void newline (std::ostream& os) const;
+
+  void reset (void) const;
+
+  // A reference count.
+  int count;
+
+private:
+
+  static int curr_print_indent_level;
+  static bool beginning_of_line;
+
+  DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA
+};
+
+// TRUE means to perform automatic sparse to real mutation if there
+// is memory to be saved
+extern bool Vsparse_auto_mutate;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-bool-mat.cc b/src/ov-bool-mat.cc
new file mode 100644
index 0000000..7f54c9b
--- /dev/null
+++ b/src/ov-bool-mat.cc
@@ -0,0 +1,543 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <vector>
+
+#include "lo-ieee.h"
+#include "mx-base.h"
+#include "oct-locbuf.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-re-mat.h"
+#include "pr-output.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+template class octave_base_matrix<boolNDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_bool_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool_matrix,
+				     "bool matrix", "logical");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_bool_matrix&);
+
+  return new octave_matrix (NDArray (v.bool_array_value ()));
+}
+
+octave_base_value::type_conv_info
+octave_bool_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_bool_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.ndims () == 2)
+    {
+      boolMatrix bm = matrix.matrix_value ();
+
+      octave_idx_type nr = bm.rows ();
+      octave_idx_type nc = bm.cols ();
+
+      if (nr == 1 && nc == 1)
+	retval = new octave_bool (bm (0, 0));
+    }
+
+  return retval;
+}
+
+double
+octave_bool_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "bool matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("bool matrix", "real scalar");
+
+  return retval;
+}
+
+float
+octave_bool_matrix::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "bool matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("bool matrix", "real scalar");
+
+  return retval;
+}
+
+Complex
+octave_bool_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "bool matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("bool matrix", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_bool_matrix::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "bool matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("bool matrix", "complex scalar");
+
+  return retval;
+}
+
+octave_value
+octave_bool_matrix::convert_to_str_internal (bool pad, bool force,
+					     char type) const
+{
+  octave_value tmp = octave_value (array_value ());
+  return tmp.convert_to_str (pad, force, type);
+}
+
+void
+octave_bool_matrix::print_raw (std::ostream& os,
+			       bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+bool 
+octave_bool_matrix::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+  if (d.length () > 2)
+    {
+      NDArray tmp = array_value ();
+      os << "# ndims: " << d.length () << "\n";
+
+      for (int i = 0; i < d.length (); i++)
+	os << " " << d (i);
+
+      os << "\n" << tmp;
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for backward 
+      // compatiability. Makes load_ascii much more complex!!
+      os << "# rows: " << rows () << "\n"
+	 << "# columns: " << columns () << "\n";
+
+      Matrix tmp = matrix_value ();
+
+      os << tmp;
+    }
+
+  return true;
+}
+
+bool 
+octave_bool_matrix::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  string_vector keywords (2);
+
+  keywords[0] = "ndims";
+  keywords[1] = "rows";
+
+  std::string kw;
+  octave_idx_type val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = static_cast<int> (val);
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      if (is)
+		{
+		  boolNDArray btmp (dv);
+
+		  if (btmp.is_empty ())
+		    matrix = btmp;
+		  else
+		    {
+		      NDArray tmp(dv);
+		      is >> tmp;
+
+		      if (is)
+			{
+			  for (octave_idx_type i = 0; i < btmp.nelem (); i++)
+			    btmp.elem (i) = (tmp.elem (i) != 0.);
+
+			  matrix = btmp;
+			}
+		      else
+			{
+			  error ("load: failed to load matrix constant");
+			  success = false;
+			}
+		    }
+		}
+	      else
+		{
+		  error ("load: failed to extract dimensions");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of dimensions");
+	      success = false;
+	    }
+	}
+      else if (kw == "rows")
+	{
+	  octave_idx_type nr = val;
+	  octave_idx_type nc = 0;
+
+	  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  Matrix tmp (nr, nc);
+		  is >> tmp;
+		  if (is) 
+		    {
+		      boolMatrix btmp (nr, nc);
+		      for (octave_idx_type j = 0; j < nc; j++)
+			for (octave_idx_type i = 0; i < nr; i++)
+			  btmp.elem (i,j) = (tmp.elem (i, j) != 0.);
+
+		      matrix = btmp;
+		    }
+		  else
+		    {
+		      error ("load: failed to load matrix constant");
+		      success = false;
+		    }
+		}
+	      else if (nr == 0 || nc == 0)
+		matrix = boolMatrix (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of rows and columns");
+	      success = false;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_bool_matrix::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i = 0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  boolNDArray m = bool_array_value ();
+  bool *mtmp = m.fortran_vec ();
+  octave_idx_type nel = m.nelem ();
+  OCTAVE_LOCAL_BUFFER (char, htmp, nel);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    htmp[i] = (mtmp[i] ? 1 : 0);
+
+  os.write (htmp, nel);
+
+  return true;
+}
+
+bool 
+octave_bool_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format /* fmt */)
+{
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims >= 0)
+    return false;
+
+  // mdims is negative for consistency with other matrices, where it is
+  // negative to allow the positive value to be used for rows/cols for
+  // backward compatibility
+  mdims = - mdims;
+  int32_t di;
+  dim_vector dv;
+  dv.resize (mdims);
+
+  for (int i = 0; i < mdims; i++)
+    {
+      if (! is.read (reinterpret_cast<char *> (&di), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&di);
+      dv(i) = di;
+    }
+  
+  // Convert an array with a single dimension to be a row vector.
+  // Octave should never write files like this, other software
+  // might.
+
+  if (mdims == 1)
+    {
+      mdims = 2;
+      dv.resize (mdims);
+      dv(1) = dv(0);
+      dv(0) = 1;
+    }
+
+  octave_idx_type nel = dv.numel ();
+  OCTAVE_LOCAL_BUFFER (char, htmp, nel);
+  if (! is.read (htmp, nel))
+    return false;
+  boolNDArray m(dv);
+  bool *mtmp = m.fortran_vec ();
+  for (octave_idx_type i = 0; i < nel; i++)
+    mtmp[i] = (htmp[i] ? 1 : 0);
+  matrix = m;
+
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_bool_matrix::save_hdf5 (hid_t loc_id, const char *name,
+			       bool /* save_as_floats */)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  boolNDArray m = bool_array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+
+  space_hid = H5Screate_simple (rank, hdims, 0);
+  if (space_hid < 0) return false;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_HBOOL, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  octave_idx_type nel = m.nelem ();
+  bool *mtmp = m.fortran_vec ();
+  OCTAVE_LOCAL_BUFFER (hbool_t, htmp, nel);
+  
+  for (octave_idx_type i = 0; i < nel; i++)
+    htmp[i] = mtmp[i];
+
+  retval = H5Dwrite (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, htmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_bool_matrix::load_hdf5 (hid_t loc_id, const char *name,
+			       bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+    return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+  
+  if (rank < 1)
+    {
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  if (rank == 1)
+    {
+      dv.resize (2);
+      dv(0) = 1;
+      dv(1) = hdims[0];
+    }
+  else
+    {
+      dv.resize (rank);
+      for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	dv(j) = hdims[i];
+    }
+
+  octave_idx_type nel = dv.numel ();
+  OCTAVE_LOCAL_BUFFER (hbool_t, htmp, nel);
+  if (H5Dread (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL, H5P_DEFAULT, htmp) >= 0) 
+    {
+      retval = true;
+
+      boolNDArray btmp (dv);
+      for (octave_idx_type i = 0; i < nel; i++)
+	  btmp.elem (i) = htmp[i];
+
+      matrix = btmp;
+    }
+
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_bool_matrix::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxLOGICAL_CLASS, dims (), mxREAL);
+
+  bool *pr = static_cast<bool *> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  const bool *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    pr[i] = p[i];
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-bool-mat.h b/src/ov-bool-mat.h
new file mode 100644
index 0000000..568eedc
--- /dev/null
+++ b/src/ov-bool-mat.h
@@ -0,0 +1,268 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_bool_matrix_h)
+#define octave_bool_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+
+#include "MatrixType.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Character matrix values.
+
+class
+octave_bool_matrix : public octave_base_matrix<boolNDArray>
+{
+public:
+
+  octave_bool_matrix (void)
+    : octave_base_matrix<boolNDArray> () { }
+
+  octave_bool_matrix (const boolNDArray& bnda)
+    : octave_base_matrix<boolNDArray> (bnda) { }
+
+  octave_bool_matrix (const boolMatrix& bm)
+    : octave_base_matrix<boolNDArray> (bm) { }
+
+  octave_bool_matrix (const boolMatrix& bm, const MatrixType& t)
+    : octave_base_matrix<boolNDArray> (bm, t) { }
+
+  octave_bool_matrix (const octave_bool_matrix& bm)
+    : octave_base_matrix<boolNDArray> (bm) { }
+
+  ~octave_bool_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_bool_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_bool_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  idx_vector index_vector (void) const { return idx_vector (matrix); }
+
+  bool is_bool_matrix (void) const { return true; }
+
+  bool is_bool_type (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (matrix); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (matrix); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (matrix); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (matrix); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (matrix); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (matrix); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (matrix); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (matrix); }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const
+    { return Matrix (matrix.matrix_value ()); }
+
+  FloatMatrix float_matrix_value (bool = false) const
+    { return FloatMatrix (matrix.matrix_value ()); }
+
+  NDArray array_value (bool = false) const
+    { return NDArray (matrix); }
+
+  FloatNDArray float_array_value (bool = false) const
+    { return FloatNDArray (matrix); }
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return ComplexMatrix (matrix.matrix_value ( )); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const
+    { return FloatComplexMatrix (matrix.matrix_value ( )); }
+
+  ComplexNDArray complex_array_value (bool = false) const
+    { return ComplexNDArray (matrix); }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const
+    { return FloatComplexNDArray (matrix); }
+
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dims ());
+
+    octave_idx_type nel = numel ();
+  
+    for (octave_idx_type i = 0; i < nel; i++)
+      retval(i) = static_cast<char>(matrix(i));
+
+    return retval;
+  }
+
+  boolMatrix bool_matrix_value (bool = false) const
+    { return matrix.matrix_value (); }
+
+  boolNDArray bool_array_value (bool = false) const
+    { return matrix; }
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+  { return SparseMatrix (Matrix (matrix.matrix_value ())); }
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+  { return SparseComplexMatrix (ComplexMatrix (matrix.matrix_value ())); }
+
+  SparseBoolMatrix sparse_bool_matrix_value (bool = false) const
+  { return SparseBoolMatrix (matrix.matrix_value ()); }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return matrix.mex_get_data (); }
+
+  mxArray *as_mxArray (void) const;
+
+  // Mapper functions are converted to double for treatment
+#define BOOL_MAT_MAPPER(MAP) \
+  octave_value MAP (void) const \
+    { \
+      octave_matrix m (array_value ()); \
+      return m.MAP (); \
+    }
+
+  BOOL_MAT_MAPPER (abs)
+  BOOL_MAT_MAPPER (acos)
+  BOOL_MAT_MAPPER (acosh)
+  BOOL_MAT_MAPPER (angle)
+  BOOL_MAT_MAPPER (arg)
+  BOOL_MAT_MAPPER (asin)
+  BOOL_MAT_MAPPER (asinh)
+  BOOL_MAT_MAPPER (atan)
+  BOOL_MAT_MAPPER (atanh)
+  BOOL_MAT_MAPPER (ceil)
+  BOOL_MAT_MAPPER (conj)
+  BOOL_MAT_MAPPER (cos)
+  BOOL_MAT_MAPPER (cosh)
+  BOOL_MAT_MAPPER (erf)
+  BOOL_MAT_MAPPER (erfc)
+  BOOL_MAT_MAPPER (exp)
+  BOOL_MAT_MAPPER (expm1)
+  BOOL_MAT_MAPPER (finite)
+  BOOL_MAT_MAPPER (fix)
+  BOOL_MAT_MAPPER (floor)
+  BOOL_MAT_MAPPER (gamma)
+  BOOL_MAT_MAPPER (imag)
+  BOOL_MAT_MAPPER (isinf)
+  BOOL_MAT_MAPPER (isna)
+  BOOL_MAT_MAPPER (isnan)
+  BOOL_MAT_MAPPER (lgamma)
+  BOOL_MAT_MAPPER (log)
+  BOOL_MAT_MAPPER (log2)
+  BOOL_MAT_MAPPER (log10)
+  BOOL_MAT_MAPPER (log1p)
+  BOOL_MAT_MAPPER (real)
+  BOOL_MAT_MAPPER (round)
+  BOOL_MAT_MAPPER (roundb)
+  BOOL_MAT_MAPPER (signum)
+  BOOL_MAT_MAPPER (sin)
+  BOOL_MAT_MAPPER (sinh)
+  BOOL_MAT_MAPPER (sqrt)
+  BOOL_MAT_MAPPER (tan)
+  BOOL_MAT_MAPPER (tanh)
+
+#undef BOOL_MAT_MAPPER
+
+protected:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-bool-sparse.cc b/src/ov-bool-sparse.cc
new file mode 100644
index 0000000..64ae332
--- /dev/null
+++ b/src/ov-bool-sparse.cc
@@ -0,0 +1,734 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+#include <vector>
+
+#include "ov-base.h"
+#include "ov-scalar.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "gripes.h"
+#include "ops.h"
+#include "oct-locbuf.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "ov-bool-sparse.h"
+
+#include "ov-base-sparse.h"
+#include "ov-base-sparse.cc"
+
+template class OCTINTERP_API octave_base_sparse<SparseBoolMatrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_sparse_bool_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_bool_matrix, "sparse bool matrix", "logical");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_sparse_bool_matrix&);
+
+  return new octave_sparse_matrix (SparseMatrix (v.sparse_bool_matrix_value ()));
+}
+
+octave_base_value::type_conv_info
+octave_sparse_bool_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_sparse_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_sparse_bool_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (Vsparse_auto_mutate)
+    {
+      // Don't use numel, since it can overflow for very large matrices
+      // Note that for the second test, this means it becomes approximative
+      // since it involves a cast to double to avoid issues of overflow
+      if (matrix.rows () == 1 && matrix.cols () == 1)
+	{
+	  // Const copy of the matrix, so the right version of () operator used
+	  const SparseBoolMatrix tmp (matrix);
+
+	  retval = new octave_bool (tmp (0));
+	}
+      else if (matrix.cols () > 0 && matrix.rows () > 0 && 
+	       double (matrix.byte_size ()) > double (matrix.rows ()) *
+	       double (matrix.cols ()) * sizeof (bool))
+	retval = new octave_bool_matrix (matrix.matrix_value ());
+    }
+
+  return retval;
+}
+
+double
+octave_sparse_bool_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (numel () > 0)
+    {
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "bool sparse matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("bool sparse matrix", "real scalar");
+
+  return retval;
+}
+
+Complex
+octave_sparse_bool_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "bool sparse matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("bool sparse matrix", "complex scalar");
+
+  return retval;
+}
+
+octave_value
+octave_sparse_bool_matrix::convert_to_str_internal (bool pad, bool force,
+						    char type) const
+{
+  octave_value tmp = octave_value (array_value ());
+  return tmp.convert_to_str (pad, force, type);
+}
+
+// FIXME These are inefficient ways of creating full matrices
+
+Matrix
+octave_sparse_bool_matrix::matrix_value (bool) const
+{
+  return Matrix (matrix.matrix_value ());
+}
+
+ComplexMatrix
+octave_sparse_bool_matrix::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (matrix.matrix_value ());
+}
+
+ComplexNDArray
+octave_sparse_bool_matrix::complex_array_value (bool) const
+{
+  return ComplexNDArray (ComplexMatrix (matrix.matrix_value ()));
+}
+
+NDArray 
+octave_sparse_bool_matrix::array_value (bool) const
+{
+  return NDArray (Matrix(matrix.matrix_value ()));
+}
+
+charNDArray
+octave_sparse_bool_matrix::char_array_value (bool) const
+{
+  charNDArray retval (dims (), 0);
+  octave_idx_type nc = matrix.cols ();
+  octave_idx_type nr = matrix.rows ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++)
+      retval(matrix.ridx(i) + nr * j) = static_cast<char>(matrix.data (i));
+
+  return retval;
+}
+
+boolMatrix 
+octave_sparse_bool_matrix::bool_matrix_value (bool) const
+{ 
+  return matrix.matrix_value (); 
+}
+
+boolNDArray 
+octave_sparse_bool_matrix::bool_array_value (bool) const
+{ 
+  return boolNDArray (matrix.matrix_value ()); 
+}
+
+
+SparseMatrix 
+octave_sparse_bool_matrix::sparse_matrix_value (bool) const
+{
+  return SparseMatrix (this->matrix);
+}
+
+SparseComplexMatrix 
+octave_sparse_bool_matrix::sparse_complex_matrix_value (bool) const
+{
+  return SparseComplexMatrix (this->matrix);
+}
+
+bool 
+octave_sparse_bool_matrix::save_binary (std::ostream& os, bool&)
+{
+  dim_vector d = this->dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  int nr = d(0);
+  int nc = d(1);
+  int nz = nzmax ();
+
+  int32_t itmp;
+  // Use negative value for ndims to be consistent with other formats
+  itmp= -2;        
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nr;    
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nc;
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nz;
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+
+  // add one to the printed indices to go from
+  // zero-based to one-based arrays
+  for (int i = 0; i < nc+1; i++)  
+    {
+      OCTAVE_QUIT;
+      itmp = matrix.cidx(i);
+      os.write (reinterpret_cast<char *> (&itmp), 4);
+    }
+
+  for (int i = 0; i < nz; i++) 
+    {
+      OCTAVE_QUIT;
+      itmp = matrix.ridx(i); 
+      os.write (reinterpret_cast<char *> (&itmp), 4);
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, htmp, nz);
+
+  for (int i = 0; i < nz; i++)
+    htmp[i] = (matrix.data (i) ? 1 : 0);
+   
+  os.write (htmp, nz);
+
+  return true;
+}
+
+bool
+octave_sparse_bool_matrix::load_binary (std::istream& is, bool swap,
+					oct_mach_info::float_format /* fmt */)
+{
+  int32_t nz, nc, nr, tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+    return false;
+
+  if (swap)
+    swap_bytes<4> (&tmp);
+
+  if (tmp != -2) {
+    error("load: only 2D sparse matrices are supported");
+    return false;
+  }
+
+  if (! is.read (reinterpret_cast<char *> (&nr), 4))
+    return false;
+  if (! is.read (reinterpret_cast<char *> (&nc), 4))
+    return false;
+  if (! is.read (reinterpret_cast<char *> (&nz), 4))
+    return false;
+
+  if (swap)
+    {
+      swap_bytes<4> (&nr);
+      swap_bytes<4> (&nc);
+      swap_bytes<4> (&nz);
+    }
+
+  SparseBoolMatrix m (static_cast<octave_idx_type> (nr),
+		      static_cast<octave_idx_type> (nc),
+		      static_cast<octave_idx_type> (nz));
+
+  for (int i = 0; i < nc+1; i++) 
+    {
+      OCTAVE_QUIT;
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+      m.cidx(i) = tmp;
+    }
+
+  for (int i = 0; i < nz; i++) 
+    {
+      OCTAVE_QUIT;
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+      m.ridx(i) = tmp;
+    }
+
+  if (error_state || ! is)
+    return false;
+
+  OCTAVE_LOCAL_BUFFER (char, htmp, nz);
+
+  if (! is.read (htmp, nz))
+    return false;
+
+  for (int i = 0; i < nz; i++)
+    m.data(i) = (htmp[i] ? 1 : 0);
+ 
+  matrix = m;
+
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_sparse_bool_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  hid_t group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0)
+    return false;
+
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  SparseBoolMatrix m = sparse_bool_matrix_value ();
+  octave_idx_type tmp;
+  hsize_t hdims[2];
+
+  space_hid = H5Screate_simple (0, hdims, 0);
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.rows ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.cols ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.nzmax ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+
+  hdims[0] = m.cols() + 1;
+  hdims[1] = 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  octave_idx_type * itmp = m.xcidx ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, itmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  H5Sclose (space_hid);
+
+  hdims[0] = m.nzmax ();
+  hdims[1] = 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  itmp = m.xridx ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, itmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "data", H5T_NATIVE_HBOOL, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hbool_t, htmp, m.nzmax ());  
+  for (int i = 0; i < m.nzmax (); i++)
+    htmp[i] = m.xdata(i);
+
+  retval = H5Dwrite (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, htmp) >= 0;
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+bool
+octave_sparse_bool_matrix::load_hdf5 (hid_t loc_id, const char *name,
+				      bool /* have_h5giterate_bug */)
+{
+  octave_idx_type nr, nc, nz;
+  hid_t group_hid, data_hid, space_hid;
+  hsize_t rank;
+  
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+    return (empty > 0);
+  
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0 ) return false;
+
+  data_hid = H5Dopen (group_hid, "nr");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nr) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "nc");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nc) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+  
+  data_hid = H5Dopen (group_hid, "nz");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nz) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+
+  SparseBoolMatrix m (static_cast<octave_idx_type> (nr),
+		      static_cast<octave_idx_type> (nc),
+		      static_cast<octave_idx_type> (nz));
+
+  data_hid = H5Dopen (group_hid, "cidx");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nc + 1 || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  octave_idx_type *itmp = m.xcidx ();
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "ridx");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nz || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  itmp = m.xridx ();
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "data");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nz || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hbool_t, htmp, nz);
+  bool retval = false;
+  if (H5Dread (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL, H5P_DEFAULT, htmp) >= 0) 
+    {
+      retval = true;
+
+      for (int i = 0; i < nz; i++)
+	m.xdata(i) = htmp[i];
+
+      matrix = m;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_sparse_bool_matrix::as_mxArray (void) const
+{
+  mwSize nz = nzmax ();
+  mxArray *retval = new mxArray (mxLOGICAL_CLASS, rows (), columns (), 
+				 nz, mxREAL);
+  bool *pr = static_cast<bool *> (retval->get_data ());
+  mwIndex *ir = retval->get_ir ();
+  mwIndex *jc = retval->get_jc ();
+
+  for (mwIndex i = 0; i < nz; i++)
+    {
+      pr[i] = matrix.data(i);
+      ir[i] = matrix.ridx(i);
+    }
+
+  for (mwIndex i = 0; i < columns () + 1; i++)
+    jc[i] = matrix.cidx(i);
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-bool-sparse.h b/src/ov-bool-sparse.h
new file mode 100644
index 0000000..8b92821
--- /dev/null
+++ b/src/ov-bool-sparse.h
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_bool_matrix_h)
+#define octave_sparse_bool_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+#include "boolSparse.h"
+#include "ov-base-sparse.h"
+#include "ov-re-sparse.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+class
+OCTINTERP_API
+octave_sparse_bool_matrix : public octave_base_sparse<SparseBoolMatrix>
+{
+public:
+
+  octave_sparse_bool_matrix (void)
+    : octave_base_sparse<SparseBoolMatrix> () { }
+
+  octave_sparse_bool_matrix (const SparseBoolMatrix& bnda)
+    : octave_base_sparse<SparseBoolMatrix> (bnda) { }
+
+  octave_sparse_bool_matrix (const SparseBoolMatrix& bnda,
+			     const MatrixType& t)
+    : octave_base_sparse<SparseBoolMatrix> (bnda, t) { }
+
+  octave_sparse_bool_matrix (const boolNDArray& m)
+    : octave_base_sparse<SparseBoolMatrix> (SparseBoolMatrix (m)) { }
+
+  octave_sparse_bool_matrix (const boolMatrix& m)
+    : octave_base_sparse<SparseBoolMatrix> (SparseBoolMatrix (m)) { }
+
+  octave_sparse_bool_matrix (const Sparse<bool>& a)
+    : octave_base_sparse<SparseBoolMatrix> (a) { }
+
+  octave_sparse_bool_matrix (const octave_sparse_bool_matrix& bm)
+    : octave_base_sparse<SparseBoolMatrix> (bm) { }
+
+  ~octave_sparse_bool_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_sparse_bool_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_sparse_bool_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  // FIXME Adapt idx_vector to allow sparse logical indexing!!
+  idx_vector index_vector (void) const 
+    { return idx_vector (bool_array_value ()); }
+
+  bool is_bool_matrix (void) const { return true; }
+
+  bool is_bool_type (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  NDArray array_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+
+  charNDArray char_array_value (bool = false) const;
+
+  boolMatrix bool_matrix_value (bool = false) const;
+
+  boolNDArray bool_array_value (bool = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  SparseBoolMatrix sparse_bool_matrix_value (bool = false) const
+    { return matrix; }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  mxArray *as_mxArray (void) const;
+
+  // Mapper functions are converted to double for treatment
+#define BOOL_SPARSE_MAPPER(MAP) \
+  octave_value MAP (void) const \
+    { \
+      octave_sparse_matrix m (sparse_matrix_value ()); \
+      return m.MAP (); \
+    }
+
+  BOOL_SPARSE_MAPPER (abs)
+  BOOL_SPARSE_MAPPER (acos)
+  BOOL_SPARSE_MAPPER (acosh)
+  BOOL_SPARSE_MAPPER (angle)
+  BOOL_SPARSE_MAPPER (arg)
+  BOOL_SPARSE_MAPPER (asin)
+  BOOL_SPARSE_MAPPER (asinh)
+  BOOL_SPARSE_MAPPER (atan)
+  BOOL_SPARSE_MAPPER (atanh)
+  BOOL_SPARSE_MAPPER (ceil)
+  BOOL_SPARSE_MAPPER (conj)
+  BOOL_SPARSE_MAPPER (cos)
+  BOOL_SPARSE_MAPPER (cosh)
+  BOOL_SPARSE_MAPPER (erf)
+  BOOL_SPARSE_MAPPER (erfc)
+  BOOL_SPARSE_MAPPER (exp)
+  BOOL_SPARSE_MAPPER (expm1)
+  BOOL_SPARSE_MAPPER (finite)
+  BOOL_SPARSE_MAPPER (fix)
+  BOOL_SPARSE_MAPPER (floor)
+  BOOL_SPARSE_MAPPER (gamma)
+  BOOL_SPARSE_MAPPER (imag)
+  BOOL_SPARSE_MAPPER (isinf)
+  BOOL_SPARSE_MAPPER (isna)
+  BOOL_SPARSE_MAPPER (isnan)
+  BOOL_SPARSE_MAPPER (lgamma)
+  BOOL_SPARSE_MAPPER (log)
+  BOOL_SPARSE_MAPPER (log2)
+  BOOL_SPARSE_MAPPER (log10)
+  BOOL_SPARSE_MAPPER (log1p)
+  BOOL_SPARSE_MAPPER (real)
+  BOOL_SPARSE_MAPPER (round)
+  BOOL_SPARSE_MAPPER (roundb)
+  BOOL_SPARSE_MAPPER (signum)
+  BOOL_SPARSE_MAPPER (sin)
+  BOOL_SPARSE_MAPPER (sinh)
+  BOOL_SPARSE_MAPPER (sqrt)
+  BOOL_SPARSE_MAPPER (tan)
+  BOOL_SPARSE_MAPPER (tanh)
+
+#undef BOOL_SPARSE_MAPPER
+
+protected:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-bool.cc b/src/ov-bool.cc
new file mode 100644
index 0000000..7a57833
--- /dev/null
+++ b/src/ov-bool.cc
@@ -0,0 +1,240 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "mx-base.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ops.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-base.h"
+#include "ov-base-scalar.h"
+#include "ov-base-scalar.cc"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "pr-output.h"
+
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+
+template class octave_base_scalar<bool>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_bool);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool, "bool", "logical");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_bool&);
+
+  return new octave_scalar (v.bool_value ());
+}
+
+octave_base_value::type_conv_info
+octave_bool::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_scalar::static_type_id ());
+
+}
+
+octave_value
+octave_bool::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // FIXME -- this doesn't solve the problem of
+  //
+  //   a = 1; a([1,1], [1,1], [1,1])
+  //
+  // and similar constructions.  Hmm...
+
+  // FIXME -- using this constructor avoids narrowing the
+  // 1x1 matrix back to a scalar value.  Need a better solution
+  // to this problem.
+
+  octave_value tmp (new octave_bool_matrix (bool_matrix_value ()));
+
+  return tmp.do_index_op (idx, resize_ok);
+}
+
+octave_value 
+octave_bool::resize (const dim_vector& dv, bool fill) const
+{ 
+  if (fill)
+    {
+      boolNDArray retval (dv, false); 
+      if (dv.numel()) 
+	retval(0) = scalar; 
+      return retval; 
+    }
+  else
+    {
+      boolNDArray retval (dv); 
+      if (dv.numel()) 
+	retval(0) = scalar; 
+      return retval; 
+    }
+}
+
+octave_value
+octave_bool::convert_to_str_internal (bool, bool, char type) const
+{
+  char s[2];
+  s[0] = static_cast<char> (scalar);
+  s[1] = '\0';
+
+  return octave_value (s, type);
+}
+
+bool 
+octave_bool::save_ascii (std::ostream& os)
+{
+  double d = double_value ();
+
+  octave_write_double (os, d);
+  os << "\n";
+
+  return true;
+}
+
+bool 
+octave_bool::load_ascii (std::istream& is)
+{
+  scalar = (octave_read_double (is) != 0.);
+
+  if (!is)
+    {
+      error ("load: failed to load scalar constant");
+      return false;
+    }
+
+  return true;
+}
+
+bool 
+octave_bool::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+  char tmp = (scalar ? 1 : 0);
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+
+  return true;
+}
+
+bool 
+octave_bool::load_binary (std::istream& is, bool /* swap */,
+			  oct_mach_info::float_format /* fmt */)
+{
+  char tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    return false;
+  scalar = (tmp ? 1 : 0);
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_bool::save_hdf5 (hid_t loc_id, const char *name,
+			bool /* save_as_floats */)
+{
+  hsize_t dimens[3];
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0) return false;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_DOUBLE, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  double tmp = double_value ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_bool::load_hdf5 (hid_t loc_id, const char *name,
+			bool /* have_h5giterate_bug */)
+{
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  double dtmp;
+  if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &dtmp) < 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  scalar = (dtmp != 0.);
+
+  H5Dclose (data_hid);
+
+  return true;
+}
+
+#endif
+
+mxArray *
+octave_bool::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxLOGICAL_CLASS, 1, 1, mxREAL);
+
+  bool *pr = static_cast<bool *> (retval->get_data ());
+
+  pr[0] = scalar;
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-bool.h b/src/ov-bool.h
new file mode 100644
index 0000000..2c42c05
--- /dev/null
+++ b/src/ov-bool.h
@@ -0,0 +1,272 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_bool_h)
+#define octave_bool_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-scalar.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Real scalar values.
+
+class
+octave_bool : public octave_base_scalar<bool>
+{
+public:
+
+  octave_bool (void)
+    : octave_base_scalar<bool> (false) { }
+
+  octave_bool (bool b)
+    : octave_base_scalar<bool> (b) { }
+
+  octave_bool (const octave_bool& s)
+    : octave_base_scalar<bool> (s) { }
+
+  ~octave_bool (void) { }
+
+  octave_base_value *clone (void) const { return new octave_bool (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_bool (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  idx_vector index_vector (void) const { return idx_vector (scalar); }
+
+  bool is_real_scalar (void) const { return true; }
+
+  bool is_bool_scalar (void) const { return true; }
+
+  bool is_bool_type (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_true (void) const { return scalar; }
+
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), scalar); }
+
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), scalar); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), scalar); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), scalar); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), scalar); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), scalar); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), scalar); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), scalar); }
+
+  double double_value (bool = false) const { return scalar; }
+
+  float float_value (bool = false) const { return scalar; }
+
+  double scalar_value (bool = false) const { return scalar; }
+
+  float float_scalar_value (bool = false) const { return scalar; }
+
+  Matrix matrix_value (bool = false) const
+    { return Matrix (1, 1, scalar); }
+
+  FloatMatrix float_matrix_value (bool = false) const
+    { return FloatMatrix (1, 1, scalar); }
+
+  NDArray array_value (bool = false) const
+    { return NDArray (dim_vector (1, 1), static_cast<double> (scalar)); }
+
+  FloatNDArray float_array_value (bool = false) const
+    { return FloatNDArray (dim_vector (1, 1), static_cast<double> (scalar)); }
+
+  Complex complex_value (bool = false) const { return scalar; }
+
+  FloatComplex float_complex_value (bool = false) const { return scalar; }
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return ComplexMatrix (1, 1, Complex (scalar)); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const
+    { return FloatComplexMatrix (1, 1, FloatComplex (scalar)); }
+
+  ComplexNDArray complex_array_value (bool = false) const
+    { return ComplexNDArray (dim_vector (1, 1), Complex (scalar)); }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const
+    { return FloatComplexNDArray (dim_vector (1, 1), FloatComplex (scalar)); }
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return SparseMatrix (Matrix (1, 1, scalar)); }
+
+  // FIXME Need SparseComplexMatrix (Matrix) constructor!!!
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (sparse_matrix_value ()); }
+
+  SparseBoolMatrix sparse_bool_matrix_value (bool = false) const
+    { return SparseBoolMatrix (boolMatrix (1, 1, scalar)); }
+
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = static_cast<char> (scalar);
+    return retval;
+  }
+
+  bool bool_value (bool = false) const { return scalar; }
+
+  boolMatrix bool_matrix_value (bool = false) const
+    { return boolMatrix (1, 1, scalar); }
+
+  boolNDArray bool_array_value (bool = false) const
+    { return boolNDArray (dim_vector (1, 1), scalar); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      return os.write (bool_array_value (), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  mxArray *as_mxArray (void) const;
+
+  // Mapper functions are converted to double for treatment
+#define BOOL_MAPPER(MAP) \
+  octave_value MAP (void) const \
+    { \
+      octave_scalar s (static_cast<double> (scalar)); \
+      return s.MAP (); \
+    }
+
+  BOOL_MAPPER (abs)
+  BOOL_MAPPER (acos)
+  BOOL_MAPPER (acosh)
+  BOOL_MAPPER (angle)
+  BOOL_MAPPER (arg)
+  BOOL_MAPPER (asin)
+  BOOL_MAPPER (asinh)
+  BOOL_MAPPER (atan)
+  BOOL_MAPPER (atanh)
+  BOOL_MAPPER (ceil)
+  BOOL_MAPPER (conj)
+  BOOL_MAPPER (cos)
+  BOOL_MAPPER (cosh)
+  BOOL_MAPPER (erf)
+  BOOL_MAPPER (erfc)
+  BOOL_MAPPER (exp)
+  BOOL_MAPPER (expm1)
+  BOOL_MAPPER (finite)
+  BOOL_MAPPER (fix)
+  BOOL_MAPPER (floor)
+  BOOL_MAPPER (gamma)
+  BOOL_MAPPER (imag)
+  BOOL_MAPPER (isinf)
+  BOOL_MAPPER (isna)
+  BOOL_MAPPER (isnan)
+  BOOL_MAPPER (lgamma)
+  BOOL_MAPPER (log)
+  BOOL_MAPPER (log2)
+  BOOL_MAPPER (log10)
+  BOOL_MAPPER (log1p)
+  BOOL_MAPPER (real)
+  BOOL_MAPPER (round)
+  BOOL_MAPPER (roundb)
+  BOOL_MAPPER (signum)
+  BOOL_MAPPER (sin)
+  BOOL_MAPPER (sinh)
+  BOOL_MAPPER (sqrt)
+  BOOL_MAPPER (tan)
+  BOOL_MAPPER (tanh)
+
+#undef BOOL_MAPPER
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-builtin.cc b/src/ov-builtin.cc
new file mode 100644
index 0000000..1a29592
--- /dev/null
+++ b/src/ov-builtin.cc
@@ -0,0 +1,127 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov-builtin.h"
+#include "ov.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_builtin);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_builtin,
+				     "built-in function",
+				     "built-in function");
+
+octave_value_list
+octave_builtin::subsref (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
+
+	retval = do_multi_index_op (tmp_nargout, idx.front ());
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+  //
+  // FIXME -- Note that if a function call returns multiple
+  // values, and there is further indexing to perform, then we are
+  // ignoring all but the first value.  Is this really what we want to
+  // do?  If it is not, then what should happen for stat("file").size,
+  // for exmaple?
+
+  if (idx.size () > 1)
+    retval = retval(0).next_subsref (nargout, type, idx);
+
+  return retval;
+}
+
+octave_value_list
+octave_builtin::do_multi_index_op (int nargout, const octave_value_list& args)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  if (args.has_magic_colon ())
+    ::error ("invalid use of colon in function argument list");
+  else
+    {
+      unwind_protect::begin_frame ("builtin_func_eval");
+
+      octave_call_stack::push (this);
+
+      unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+      try
+	{
+	  retval = (*f) (args, nargout);
+          // Do not allow null values to be returned from functions.
+          // FIXME -- perhaps true builtins should be allowed?
+          retval.make_storable_values ();
+	}
+      catch (octave_execution_exception)
+	{
+	  gripe_library_execution_error ();
+	}
+
+      unwind_protect::run_frame ("builtin_func_eval");
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-builtin.h b/src/ov-builtin.h
new file mode 100644
index 0000000..3816598
--- /dev/null
+++ b/src/ov-builtin.h
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_builtin_h)
+#define octave_builtin_h 1
+
+#include <string>
+
+#include "ov-fcn.h"
+#include "ov-typeinfo.h"
+
+class octave_value;
+class octave_value_list;
+
+// Builtin functions.
+
+class
+OCTINTERP_API
+octave_builtin : public octave_function
+{
+public:
+
+  octave_builtin (void) { }
+
+  typedef octave_value_list (*fcn) (const octave_value_list&, int);
+
+  octave_builtin (fcn ff, const std::string& nm = std::string (),
+		  const std::string& ds = std::string ())
+    : octave_function (nm, ds), f (ff) { }
+
+  ~octave_builtin (void) { }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  octave_function *function_value (bool = false) { return this; }
+
+  const octave_function *function_value (bool = false) const { return this; }
+
+  bool is_builtin_function (void) const { return true; }
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& args);
+
+protected:
+
+  // A pointer to the actual function.
+  fcn f;
+
+private:
+
+  // No copying!
+
+  octave_builtin (const octave_builtin& ob);
+
+  octave_builtin& operator = (const octave_builtin& ob);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cell.cc b/src/ov-cell.cc
new file mode 100644
index 0000000..b37fb68
--- /dev/null
+++ b/src/ov-cell.cc
@@ -0,0 +1,1432 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+
+#include "Array-util.h"
+#include "byte-swap.h"
+#include "lo-utils.h"
+#include "quit.h"
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "error.h"
+#include "ov-cell.h"
+#include "oct-obj.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "pr-output.h"
+#include "ov-scalar.h"
+#include "gripes.h"
+
+#include "ls-oct-ascii.h"
+#include "ls-oct-binary.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+// Cell is able to handle octave_value indexing by itself, so just forward
+// everything.
+
+template <>
+octave_value
+octave_base_matrix<Cell>::do_index_op (const octave_value_list& idx,
+                                       bool resize_ok)
+{
+  return matrix.index (idx, resize_ok);
+}
+
+template <>
+void
+octave_base_matrix<Cell>::assign (const octave_value_list& idx, const Cell& rhs)
+{
+  matrix.assign (idx, rhs);
+}
+
+template <>
+void
+octave_base_matrix<Cell>::assign (const octave_value_list& idx, octave_value rhs)
+{
+  // FIXME: Really?
+  if (rhs.is_cell ())
+    matrix.assign (idx, rhs.cell_value ());
+  else
+    matrix.assign (idx, Cell (rhs));
+}
+
+template <>
+void
+octave_base_matrix<Cell>::delete_elements (const octave_value_list& idx)
+{
+  matrix.delete_elements (idx);
+}
+
+template class octave_base_matrix<Cell>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_cell);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cell, "cell", "cell");
+
+static void
+gripe_failed_assignment (void)
+{
+  error ("assignment to cell array failed");
+}
+
+octave_value_list
+octave_cell::subsref (const std::string& type,
+		      const std::list<octave_value_list>& idx,
+		      int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval(0) = do_index_op (idx.front ());
+      break;
+
+    case '{':
+      {
+	octave_value tmp = do_index_op (idx.front ());
+
+	if (! error_state)
+	  {
+	    Cell tcell = tmp.cell_value ();
+
+	    if (tcell.length () == 1)
+	      retval(0) = tcell(0,0);
+	    else
+              retval = octave_value (octave_value_list (tcell), true);
+	  }
+      }
+      break;
+
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+
+  if (idx.size () > 1)
+    retval = retval(0).next_subsref (nargout, type, idx);
+
+  return retval;
+}
+
+octave_value
+octave_cell::subsref (const std::string& type,
+		      const std::list<octave_value_list>& idx,
+		      bool auto_add)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front (), auto_add);
+      break;
+
+    case '{':
+      {
+	octave_value tmp = do_index_op (idx.front (), auto_add);
+
+	if (! error_state)
+	  {
+	    const Cell tcell = tmp.cell_value ();
+
+	    if (tcell.length () == 1)
+	      retval = tcell(0,0);
+	    else
+              retval = octave_value (octave_value_list (tcell), true);
+	  }
+      }
+      break;
+
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+
+  if (idx.size () > 1)
+    retval = retval.next_subsref (auto_add, type, idx);
+
+  return retval;
+}
+
+octave_value
+octave_cell::subsasgn (const std::string& type,
+		       const std::list<octave_value_list>& idx,
+		       const octave_value& rhs)
+{
+  octave_value retval;
+
+  int n = type.length ();
+
+  octave_value t_rhs = rhs;
+
+  clear_cellstr_cache ();
+
+  if (idx.front ().empty ())
+    {
+      error ("missing index in indexed assignment");
+      return retval;
+    }
+
+  if (n > 1)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (is_empty () && type[1] == '.')
+	      {
+		// Allow conversion of empty cell array to some other
+		// type in cases like
+		//
+		//  x = []; x(i).f = rhs
+
+		octave_value tmp = octave_value::empty_conv (type, rhs);
+
+		return tmp.subsasgn (type, idx, rhs);
+	      }
+	    else
+	      {
+		octave_value tmp = do_index_op (idx.front (), true);
+
+		if (! tmp.is_defined ())
+		  tmp = octave_value::empty_conv (type.substr (1), rhs);
+
+		if (! error_state)
+		  {
+		    std::list<octave_value_list> next_idx (idx);
+
+		    next_idx.erase (next_idx.begin ());
+
+		    tmp.make_unique ();
+
+		    t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs);
+		  }
+	      }
+	  }
+	  break;
+
+	case '{':
+	  {
+            matrix.make_unique ();
+	    Cell tmpc = matrix.index (idx.front (), true);
+
+	    if (! error_state)
+	      {
+                std::list<octave_value_list> next_idx (idx);
+
+                next_idx.erase (next_idx.begin ());
+
+                std::string next_type = type.substr (1);
+
+                if (tmpc.numel () == 1)
+		  {
+		    octave_value tmp = tmpc(0);
+                    tmpc = Cell ();
+
+		    if (! tmp.is_defined () || tmp.is_zero_by_zero ())
+                      {
+                        tmp = octave_value::empty_conv (type.substr (1), rhs);
+                        tmp.make_unique (); // probably a no-op.
+                      }
+                    else
+                      // optimization: ignore the copy still stored inside our array. 
+                      tmp.make_unique (1);
+
+		    if (! error_state)
+		      t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
+		  }
+                else
+                  gripe_indexed_cs_list ();
+	      }
+	  }
+	  break;
+
+	case '.':
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+
+  if (! error_state)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    octave_value_list i = idx.front ();
+
+	    if (t_rhs.is_cell ())
+	      octave_base_matrix<Cell>::assign (i, t_rhs.cell_value ());
+	    else
+	      if (t_rhs.is_null_value ())
+		octave_base_matrix<Cell>::delete_elements (i);
+	      else
+		octave_base_matrix<Cell>::assign (i, Cell (t_rhs));
+
+	    if (! error_state)
+	      {
+		count++;
+		retval = octave_value (this);
+	      }
+	    else
+	      gripe_failed_assignment ();
+	  }
+	  break;
+
+	case '{':
+	  {
+	    octave_value_list idxf = idx.front ();
+
+	    if (t_rhs.is_cs_list ())
+	      {
+		Cell tmp_cell = Cell (t_rhs.list_value ());
+
+                // Inquire the proper shape of the RHS.
+
+                dim_vector didx = dims ().redim (idxf.length ());
+                for (octave_idx_type k = 0; k < idxf.length (); k++)
+                  if (! idxf(k).is_magic_colon ()) didx(k) = idxf(k).numel ();
+
+                if (didx.numel () == tmp_cell.numel ())
+                  tmp_cell = tmp_cell.reshape (didx);
+
+
+		octave_base_matrix<Cell>::assign (idxf, tmp_cell);
+	      }
+	    else if (idxf.all_scalars () || do_index_op (idxf, true).numel () == 1)
+              // Regularize a null matrix if stored into a cell.
+              octave_base_matrix<Cell>::assign (idxf, Cell (t_rhs.storable_value ()));
+            else if (! error_state)
+              error ("invalid assignment to cs-list outside multiple assignment.");
+
+	    if (! error_state)
+	      {
+		count++;
+		retval = octave_value (this);
+	      }
+	    else
+	      gripe_failed_assignment ();
+	  }
+	  break;
+
+	case '.':
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+
+  return retval;
+}
+
+void 
+octave_cell::clear_cellstr_cache (void) const
+{
+  cellstr_cache = Array<std::string> ();
+}
+
+void 
+octave_cell::make_cellstr_cache (void) const
+{
+  cellstr_cache = Array<std::string> (matrix.dims ());
+
+  octave_idx_type n = numel ();
+
+  std::string *dst = cellstr_cache.fortran_vec ();
+  const octave_value *src = matrix.data ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    dst[i] = src[i].string_value ();
+}
+
+bool 
+octave_cell::is_cellstr (void) const
+{
+  bool retval;
+  if (! cellstr_cache.is_empty ())
+    retval = true;
+  else
+    {
+      retval = matrix.is_cellstr ();
+      // force cache to be created here
+      if (retval)
+        make_cellstr_cache ();
+    }
+
+  return retval;
+}
+
+void 
+octave_cell::assign (const octave_value_list& idx, const Cell& rhs)
+{
+  clear_cellstr_cache ();
+  octave_base_matrix<Cell>::assign (idx, rhs);
+}
+
+void 
+octave_cell::assign (const octave_value_list& idx, const octave_value& rhs)
+{
+  clear_cellstr_cache ();
+  octave_base_matrix<Cell>::assign (idx, rhs);
+}
+
+
+void 
+octave_cell::delete_elements (const octave_value_list& idx)
+{
+  clear_cellstr_cache ();
+  octave_base_matrix<Cell>::delete_elements (idx);
+}
+
+size_t
+octave_cell::byte_size (void) const
+{
+  size_t retval = 0;
+
+  for (octave_idx_type i = 0; i < numel (); i++)
+    retval += matrix(i).byte_size ();
+
+  return retval;
+}
+
+octave_value
+octave_cell::sort (octave_idx_type dim, sortmode mode) const
+{
+  octave_value retval;
+
+  if (is_cellstr ())
+    {
+      Array<std::string> tmp = cellstr_value ();
+
+      tmp = tmp.sort (dim, mode);
+
+      // We already have the cache.
+      retval = new octave_cell (tmp);
+    }
+  else
+    error ("sort: only cell arrays of character strings may be sorted");
+  
+  return retval;
+}
+
+octave_value
+octave_cell::sort (Array<octave_idx_type> &sidx, octave_idx_type dim,
+		   sortmode mode) const
+{
+  octave_value retval;
+
+  if (is_cellstr ())
+    {
+      Array<std::string> tmp = cellstr_value ();
+
+      tmp = tmp.sort (sidx, dim, mode);
+
+      // We already have the cache.
+      retval = new octave_cell (tmp);
+    }
+  else
+    error ("sort: only cell arrays of character strings may be sorted");
+  
+  return retval;
+}
+
+sortmode 
+octave_cell::is_sorted (sortmode mode) const
+{
+  sortmode retval = UNSORTED;
+
+  if (is_cellstr ())
+    {
+      Array<std::string> tmp = cellstr_value ();
+
+      retval = tmp.is_sorted (mode);
+    }
+  else
+    error ("issorted: not a cell array of strings");
+  
+  return retval;
+}
+
+
+Array<octave_idx_type>
+octave_cell::sort_rows_idx (sortmode mode) const
+{
+  Array<octave_idx_type> retval;
+
+  if (is_cellstr ())
+    {
+      Array<std::string> tmp = cellstr_value ();
+
+      retval = tmp.sort_rows_idx (mode);
+    }
+  else
+    error ("sortrows: only cell arrays of character strings may be sorted");
+  
+  return retval;
+}
+
+sortmode 
+octave_cell::is_sorted_rows (sortmode mode) const
+{
+  sortmode retval = UNSORTED;
+
+  if (is_cellstr ())
+    {
+      Array<std::string> tmp = cellstr_value ();
+
+      retval = tmp.is_sorted_rows (mode);
+    }
+  else
+    error ("issorted: not a cell array of strings");
+  
+  return retval;
+}
+
+bool
+octave_cell::is_true (void) const
+{
+  error ("invalid conversion from cell array to logical value");
+  return false;
+}
+
+octave_value_list
+octave_cell::list_value (void) const
+{
+  return octave_value_list (matrix);
+}
+
+string_vector
+octave_cell::all_strings (bool pad) const
+{
+  string_vector retval;
+
+  octave_idx_type nel = numel ();
+
+  int n_elts = 0;
+
+  octave_idx_type max_len = 0;
+
+  std::queue<string_vector> strvec_queue;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      string_vector s = matrix(i).all_strings ();
+
+      if (error_state)
+	return retval;
+
+      octave_idx_type s_len = s.length ();
+
+      n_elts += s_len ? s_len : 1;
+
+      octave_idx_type s_max_len = s.max_length ();
+
+      if (s_max_len > max_len)
+	max_len = s_max_len;
+
+      strvec_queue.push (s);
+    }
+
+  retval = string_vector (n_elts);
+
+  octave_idx_type k = 0;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      const string_vector s = strvec_queue.front ();
+      strvec_queue.pop ();
+
+      octave_idx_type s_len = s.length ();
+
+      if (s_len)
+	{
+	  for (octave_idx_type j = 0; j < s_len; j++)
+	    {
+	      std::string t = s[j];
+	      int t_len = t.length ();
+
+	      if (pad && max_len > t_len)
+		t += std::string (max_len - t_len, ' ');
+
+	      retval[k++] = t;
+	    }
+	}
+      else if (pad)
+	retval[k++] = std::string (max_len, ' ');
+      else
+	retval[k++] = std::string ();
+    }
+
+  return retval;
+}
+
+Array<std::string>
+octave_cell::cellstr_value (void) const
+{
+  Array<std::string> retval;
+
+  if (is_cellstr ())
+    {
+      retval = cellstr_cache;
+    }
+  else
+    error ("invalid conversion from cell array to array of strings");
+
+  return retval;
+}
+
+bool
+octave_cell::print_as_scalar (void) const
+{
+  return (ndims () > 2 || numel () == 0);
+}
+
+void
+octave_cell::print (std::ostream& os, bool) const
+{
+  print_raw (os);
+}
+
+void
+octave_cell::print_raw (std::ostream& os, bool) const
+{
+  int nd = matrix.ndims ();
+
+  if (nd == 2)
+    {
+      octave_idx_type nr = rows ();
+      octave_idx_type nc = columns ();
+
+      if (nr > 0 && nc > 0)
+	{
+	  indent (os);
+	  os << "{";
+	  newline (os);
+
+	  increment_indent_level ();
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  OCTAVE_QUIT;
+
+		  std::ostringstream buf;
+		  buf << "[" << i+1 << "," << j+1 << "]";
+
+		  octave_value val = matrix(i,j);
+
+		  val.print_with_name (os, buf.str ());
+		}
+	    }
+
+	  decrement_indent_level ();
+
+	  indent (os);
+	  os << "}";
+	  newline (os);
+	}
+      else
+	{
+	  os << "{}";
+	  if (Vprint_empty_dimensions)
+	    os << "(" << nr << "x" << nc << ")";
+	  os << "\n";
+	}
+    }
+  else
+    {
+      indent (os);
+      dim_vector dv = matrix.dims ();
+      os << "{" << dv.str () << " Cell Array}";
+      newline (os);
+    }
+}
+
+#define CELL_ELT_TAG "<cell-element>"
+
+bool 
+octave_cell::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+  if (d.length () > 2)
+    {
+      os << "# ndims: " << d.length () << "\n";
+      
+      for (int i = 0; i < d.length (); i++)
+	os << " " << d (i);
+      os << "\n";
+
+      Cell tmp = cell_value ();
+      
+      for (octave_idx_type i = 0; i < d.numel (); i++)
+	{
+	  octave_value o_val = tmp.elem (i);
+
+	  // Recurse to print sub-value.
+	  bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, false, 0);
+	      
+	  if (! b)
+	    return os;
+	}
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for backward 
+      // compatiability. Makes load_ascii much more complex!!
+      os << "# rows: " << rows () << "\n"
+	 << "# columns: " << columns () << "\n";
+
+      Cell tmp = cell_value ();
+      
+      for (octave_idx_type j = 0; j < tmp.cols (); j++)
+	{
+	  for (octave_idx_type i = 0; i < tmp.rows (); i++)
+	    {
+	      octave_value o_val = tmp.elem (i, j);
+
+	      // Recurse to print sub-value.
+	      bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, false, 0);
+	      
+	      if (! b)
+		return os;
+	    }
+	  
+	  os << "\n";
+	}
+    }
+
+  return true;
+}
+
+bool 
+octave_cell::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  clear_cellstr_cache ();
+
+  string_vector keywords(2);
+
+  keywords[0] = "ndims";
+  keywords[1] = "rows";
+
+  std::string kw;
+  octave_idx_type val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = static_cast<int> (val);
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      Cell tmp(dv);
+
+	      for (octave_idx_type i = 0; i < dv.numel (); i++)
+		{
+		  octave_value t2;
+		  bool dummy;
+
+		  // recurse to read cell elements
+		  std::string nm = read_ascii_data (is, std::string (), 
+						    dummy, t2, i);
+
+		  if (nm == CELL_ELT_TAG)
+		    {
+		      if (is)
+			tmp.elem (i) = t2;
+		    }
+		  else
+		    {
+		      error ("load: cell array element had unexpected name");
+		      success = false;
+		      break;
+		    }
+		}
+
+	      if (is)
+		matrix = tmp;
+	      else
+		{
+		  error ("load: failed to load matrix constant");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of rows and columns");
+	      success = false;
+	    }
+	}
+      else if (kw == "rows")
+	{
+	  octave_idx_type nr = val;
+	  octave_idx_type nc = 0;
+
+	  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  Cell tmp (nr, nc);
+
+		  for (octave_idx_type j = 0; j < nc; j++)
+		    {
+		      for (octave_idx_type i = 0; i < nr; i++)
+			{
+			  octave_value t2;
+			  bool dummy;
+
+			  // recurse to read cell elements
+			  std::string nm = read_ascii_data (is, std::string (),
+							    dummy, t2, i);
+
+			  if (nm == CELL_ELT_TAG)
+			    {
+			      if (is)
+				tmp.elem (i, j) = t2;
+			    }
+			  else
+			    {
+			      error ("load: cell array element had unexpected name");
+			      success = false;
+			      goto cell_read_error;
+			    }
+			}
+		    }
+	      
+		cell_read_error:
+
+		  if (is)
+		    matrix = tmp;
+		  else
+		    {
+		      error ("load: failed to load cell element");
+		      success = false;
+		    }
+		}
+	      else if (nr == 0 || nc == 0)
+		matrix = Cell (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of rows and columns for cell array");
+	      success = false;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_cell::save_binary (std::ostream& os, bool& save_as_floats)
+{
+  dim_vector d = dims ();
+  if (d.length () < 1)
+    return false;
+
+  // Use negative value for ndims
+  int32_t di = - d.length();
+  os.write (reinterpret_cast<char *> (&di), 4);
+  for (int i = 0; i < d.length (); i++)
+    {
+      di = d(i);
+      os.write (reinterpret_cast<char *> (&di), 4);
+    }
+  
+  Cell tmp = cell_value ();
+      
+  for (octave_idx_type i = 0; i < d.numel (); i++)
+    {
+      octave_value o_val = tmp.elem (i);
+
+      // Recurse to print sub-value.
+      bool b = save_binary_data (os, o_val, CELL_ELT_TAG, "", 0, 
+				 save_as_floats);
+	      
+      if (! b)
+	return false;
+    }
+  
+  return true;
+}
+
+bool 
+octave_cell::load_binary (std::istream& is, bool swap,
+                          oct_mach_info::float_format fmt)
+{
+  clear_cellstr_cache ();
+
+  bool success = true;
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims >= 0)
+    return false;
+
+  mdims = -mdims;
+  int32_t di;
+  dim_vector dv;
+  dv.resize (mdims);
+
+  for (int i = 0; i < mdims; i++)
+    {
+      if (! is.read (reinterpret_cast<char *> (&di), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&di);
+      dv(i) = di;
+    }
+  
+  // Convert an array with a single dimension to be a row vector.
+  // Octave should never write files like this, other software
+  // might.
+
+  if (mdims == 1)
+    {
+      mdims = 2;
+      dv.resize (mdims);
+      dv(1) = dv(0);
+      dv(0) = 1;
+    }
+
+  octave_idx_type nel = dv.numel ();
+  Cell tmp(dv);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      octave_value t2;
+      bool dummy;
+      std::string doc;
+
+      // recurse to read cell elements
+      std::string nm = read_binary_data (is, swap, fmt, std::string (), 
+					 dummy, t2, doc);
+
+      if (nm == CELL_ELT_TAG)
+	{
+	  if (is)
+	    tmp.elem (i) = t2;
+	}
+      else
+	{
+	  error ("load: cell array element had unexpected name");
+	  success = false;
+	  break;
+	}
+    }
+
+  if (is)
+    matrix = tmp;
+  else
+    {
+      error ("load: failed to load matrix constant");
+      success = false;
+    }
+
+  return success;
+}
+
+void *
+octave_cell::mex_get_data (void) const
+{
+  clear_cellstr_cache ();
+  return matrix.mex_get_data ();
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_cell::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  hsize_t rank = dv.length (); 
+  hid_t space_hid = -1, data_hid = -1, size_hid = -1;
+
+  data_hid = H5Gcreate (loc_id, name, 0);
+
+  if (data_hid < 0)
+    return false;
+
+  // Have to save cell array shape, since can't have a 
+  // dataset of groups....
+
+  space_hid = H5Screate_simple (1, &rank, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (hsize_t i = 0; i < rank; i++)
+    hdims[i] = dv(rank-i-1);
+
+  size_hid = H5Dcreate (data_hid, "dims", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (size_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (data_hid);
+      return false;
+    }
+
+  if (H5Dwrite (size_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		H5P_DEFAULT, hdims) < 0)
+    {
+      H5Dclose (size_hid);
+      H5Sclose (space_hid);
+      H5Gclose (data_hid);
+      return false;
+    }
+
+  H5Dclose (size_hid);
+  H5Sclose (space_hid);
+
+  // Recursively add each element of the cell to this group.
+
+  Cell tmp = cell_value ();
+
+  octave_idx_type nel = dv.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      std::ostringstream buf;
+      int digits = static_cast<int> (::floor (::log10 (static_cast<double> (nel)) + 1.0));
+      buf << "_" << std::setw (digits) << std::setfill ('0') << i;
+      std::string s = buf.str ();
+
+      if (! add_hdf5_data (data_hid, tmp.elem (i), s.c_str (), "", false,
+			   save_as_floats))
+	{
+	  H5Gclose (data_hid);
+	  return false;
+	}
+    }
+
+  H5Gclose (data_hid);
+
+  return true;
+}
+
+bool
+octave_cell::load_hdf5 (hid_t loc_id, const char *name,
+			bool have_h5giterate_bug)
+{
+  clear_cellstr_cache ();
+
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+    return (empty > 0);
+
+  hid_t group_id = H5Gopen (loc_id, name);
+
+  if (group_id < 0)
+    return false;
+
+  hid_t data_hid = H5Dopen (group_id, "dims");
+  hid_t space_hid = H5Dget_space (data_hid);
+  hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
+  if (rank != 1) 
+    {
+      H5Dclose (data_hid);
+      H5Gclose (group_id);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering.
+
+  dv.resize (hdims[0]);
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, tmp, hdims[0]);
+  
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, tmp) < 0)
+    {
+      H5Dclose (data_hid);
+      H5Gclose (group_id);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+  H5Gclose (group_id);
+
+  for (hsize_t i = 0, j = hdims[0] - 1; i < hdims[0]; i++, j--)
+    dv(j) = tmp[i];
+
+  hdf5_callback_data dsub;
+
+  herr_t retval2 = -1;
+
+  Cell m (dv);
+
+  int current_item = 0;
+
+  if (have_h5giterate_bug)
+    current_item = 1;   // Skip dims items in group.
+
+#ifdef HAVE_H5GGET_NUM_OBJS
+  hsize_t num_obj = 0;
+  group_id = H5Gopen (loc_id, name); 
+  H5Gget_num_objs (group_id, &num_obj);
+  H5Gclose (group_id);
+#endif
+
+  for (octave_idx_type i = 0; i < dv.numel (); i++)
+    {
+
+#ifdef HAVE_H5GGET_NUM_OBJS
+      if (current_item >= static_cast<int> (num_obj))
+	retval2 = -1;
+      else
+#endif
+	retval2 = H5Giterate (loc_id, name, &current_item,
+			      hdf5_read_next_data, &dsub);
+      
+      if (retval2 <= 0)
+	break;
+
+      octave_value ov = dsub.tc;
+      m.elem (i) = ov;
+
+      if (have_h5giterate_bug)
+	current_item++;  // H5Giterate returned the last index processed.
+
+    }
+
+  if (retval2 >= 0)
+    {
+      matrix = m;
+      retval = true;
+    }
+  
+  return retval;
+}
+
+#endif
+
+DEFUN (iscell, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} iscell (@var{x})\n\
+Return true if @var{x} is a cell array object.  Otherwise, return\n\
+false.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_cell ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (cell, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} cell (@var{x})\n\
+ at deftypefnx {Built-in Function} {} cell (@var{n}, @var{m})\n\
+Create a new cell array object.  If invoked with a single scalar\n\
+argument, @code{cell} returns a square cell array with the dimension\n\
+specified.  If you supply two scalar arguments, @code{cell} takes\n\
+them to be the number of rows and columns.  If given a vector with two\n\
+elements, @code{cell} uses the values of the elements as the number of\n\
+rows and columns, respectively.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  dim_vector dims;
+
+  switch (nargin)
+    {
+    case 0:
+      dims = dim_vector (0, 0);
+      break;
+
+    case 1:
+      get_dimensions (args(0), "cell", dims);
+      break;
+
+    default:
+      {
+	dims.resize (nargin);
+
+	for (int i = 0; i < nargin; i++)
+	  {
+	    dims(i) = args(i).is_empty () ? 0 : args(i).nint_value ();
+
+	    if (error_state)
+	      {
+		error ("cell: expecting scalar arguments");
+		break;
+	      }
+	  }
+      }
+      break;
+    }
+
+  if (! error_state)
+    {
+      dims.chop_trailing_singletons ();
+
+      check_dimensions (dims, "cell");
+
+      if (! error_state)
+        retval = Cell (dims, Matrix ());
+    }
+
+  return retval;
+}
+
+DEFUN (iscellstr, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} iscellstr (@var{cell})\n\
+Return true if every element of the cell array @var{cell} is a\n\
+character string\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_cellstr ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Note that since Fcellstr calls Fiscellstr, we need to have
+// Fiscellstr defined first (to provide a declaration) and also we
+// should keep it in the same file (so we don't have to provide a
+// declaration) and so we don't have to use feval to call it.
+
+DEFUN (cellstr, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} cellstr (@var{string})\n\
+Create a new cell array object from the elements of the string\n\
+array @var{string}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      octave_value_list tmp = Fiscellstr (args, 1);
+
+      if (tmp(0).is_true ())
+	retval = args(0);
+      else
+	{
+	  string_vector s = args(0).all_strings ();
+
+	  if (! error_state)
+	    retval = (s.is_empty ()
+                      ? Cell (octave_value (std::string ()))
+                      : Cell (s, true));
+	  else
+	    error ("cellstr: expecting argument to be a 2-d character array");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (struct2cell, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} struct2cell (@var{S})\n\
+Create a new cell array from the objects stored in the struct object.\n\
+If @var{f} is the number of fields in the structure, the resulting\n\
+cell array will have a dimension vector corresponding to\n\
+ at code{[@var{F} size(@var{S})]}.\n\
+ at seealso{cell2struct, fieldnames}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      Octave_map m = args(0).map_value ();
+
+      if (! error_state)
+	{
+	  dim_vector m_dv = m.dims ();
+
+	  string_vector keys = m.keys ();
+
+	  octave_idx_type num_fields = keys.length ();
+
+	  // The resulting dim_vector should have dimensions:
+	  // [numel(fields) size(struct)]
+	  // except if the struct is a column vector.
+
+	  dim_vector result_dv;
+	  if (m_dv (m_dv.length () - 1) == 1)
+	      result_dv.resize (m_dv.length ());
+	  else
+	      result_dv.resize (m_dv.length () + 1); // Add 1 for the fields.
+
+	  result_dv(0) = num_fields;
+
+	  for (int i = 1; i < result_dv.length (); i++)
+	    result_dv(i) = m_dv(i-1);
+
+	  Cell c (result_dv);
+
+	  octave_idx_type n_elts = m.numel ();
+
+	  for (octave_idx_type j = 0; j < num_fields; j++)
+	    {
+	      octave_idx_type k = j;
+
+	      const Cell vals = m.contents (keys(j));
+
+	      for (octave_idx_type i = 0; i < n_elts; i++)
+		{
+		  c(k) = vals(i);
+		  k += num_fields;
+		}
+	    }
+
+	  retval = c;
+	}
+      else
+	error ("struct2cell: expecting argument to be a cell array");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+mxArray *
+octave_cell::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (dims ());
+
+  mxArray **elts = static_cast<mxArray **> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  const octave_value *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    elts[i] = new mxArray (p[i]);
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cell.h b/src/ov-cell.h
new file mode 100644
index 0000000..281bf2e
--- /dev/null
+++ b/src/ov-cell.h
@@ -0,0 +1,199 @@
+/*
+
+Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_cell_h)
+#define octave_cell_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "error.h"
+#include "ov-base-mat.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Cells.
+
+class
+octave_cell : public octave_base_matrix<Cell>
+{
+public:
+
+  octave_cell (void)
+    : octave_base_matrix<Cell> () { }
+
+  octave_cell (const Cell& c)
+    : octave_base_matrix<Cell> (c) { }
+
+  octave_cell (const Array<std::string>& str)
+    : octave_base_matrix<Cell> (Cell (str)), cellstr_cache (str) { }
+
+  octave_cell (const octave_cell& c)
+    : octave_base_matrix<Cell> (c) { }
+
+  ~octave_cell (void) { }
+
+  octave_base_value *clone (void) const { return new octave_cell (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_cell (); }
+
+#if 0
+  octave_base_value *try_narrowing_conversion (void);
+#endif
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int);
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx,
+                        bool auto_add);
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  void assign (const octave_value_list& idx, const Cell& rhs);
+
+  void assign (const octave_value_list& idx, const octave_value& rhs);
+
+  void delete_elements (const octave_value_list& idx);
+
+  size_t byte_size (void) const;
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const;
+
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const;
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const;
+
+  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const;
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const;
+
+  bool is_matrix_type (void) const { return false; }
+
+  bool is_numeric_type (void) const { return false; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_cell (void) const { return true; }
+
+  bool is_cellstr (void) const;
+
+  bool is_true (void) const;
+
+  Cell cell_value (void) const { return matrix; }
+
+  octave_value_list list_value (void) const;
+
+  octave_value convert_to_str_internal (bool pad, bool, char type) const
+    { return octave_value (all_strings (pad), type); }
+
+  string_vector all_strings (bool pad = false) const;
+
+  Array<std::string> cellstr_value (void) const;
+
+  bool print_as_scalar (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  octave_value xisalnum (void) const { return matrix.xisalnum (); }
+  octave_value xisalpha (void) const { return matrix.xisalpha (); }
+  octave_value xisascii (void) const { return matrix.xisascii (); }
+  octave_value xiscntrl (void) const { return matrix.xiscntrl (); }
+  octave_value xisdigit (void) const { return matrix.xisdigit (); }
+  octave_value xisgraph (void) const { return matrix.xisgraph (); }
+  octave_value xislower (void) const { return matrix.xislower (); }
+  octave_value xisprint (void) const { return matrix.xisprint (); }
+  octave_value xispunct (void) const { return matrix.xispunct (); }
+  octave_value xisspace (void) const { return matrix.xisspace (); }
+  octave_value xisupper (void) const { return matrix.xisupper (); }
+  octave_value xisxdigit (void) const { return matrix.xisxdigit (); }
+  octave_value xtoascii (void) const { return matrix.xtoascii (); }
+  octave_value xtolower (void) const { return matrix.xtolower (); }
+  octave_value xtoupper (void) const { return matrix.xtoupper (); }
+
+  mxArray *as_mxArray (void) const;
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const; 
+
+private:
+
+  void clear_cellstr_cache (void) const;
+
+  mutable Array<std::string> cellstr_cache;
+
+  void make_cellstr_cache (void) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-ch-mat.cc b/src/ov-ch-mat.cc
new file mode 100644
index 0000000..b37500c
--- /dev/null
+++ b/src/ov-ch-mat.cc
@@ -0,0 +1,162 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "mx-base.h"
+
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-ch-mat.h"
+#include "gripes.h"
+#include "pr-output.h"
+
+template class octave_base_matrix<charNDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix,
+				     "char matrix", "int8");
+
+idx_vector 
+octave_char_matrix::index_vector (void) const
+{ 
+  const char *p = matrix.data ();
+  if (numel () == 1 && *p == ':')
+    return idx_vector (':');
+  else
+    return idx_vector (array_value (true)); 
+}
+
+double
+octave_char_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "character matrix", "real scalar");
+
+      retval = static_cast<unsigned char> (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("character matrix", "real scalar");
+
+  return retval;
+}
+
+float
+octave_char_matrix::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "character matrix", "real scalar");
+
+      retval = static_cast<unsigned char> (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("character matrix", "real scalar");
+
+  return retval;
+}
+
+Complex
+octave_char_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "character matrix", "complex scalar");
+
+      retval = static_cast<unsigned char> (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("character matrix", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_char_matrix::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "character matrix", "complex scalar");
+
+      retval = static_cast<unsigned char> (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("character matrix", "complex scalar");
+
+  return retval;
+}
+
+void
+octave_char_matrix::print_raw (std::ostream& os,
+			       bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+mxArray *
+octave_char_matrix::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxCHAR_CLASS, dims (), mxREAL);
+
+  mxChar *pr = static_cast<mxChar *> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  const char *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    pr[i] = p[i];
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-ch-mat.h b/src/ov-ch-mat.h
new file mode 100644
index 0000000..15bbc06
--- /dev/null
+++ b/src/ov-ch-mat.h
@@ -0,0 +1,154 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_char_matrix_h)
+#define octave_char_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "ov-base.h"
+
+#include "ov-base-mat.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Character matrix values.
+
+class
+octave_char_matrix : public octave_base_matrix<charNDArray>
+{
+public:
+
+  octave_char_matrix (void)
+    : octave_base_matrix<charNDArray> () { }
+
+  octave_char_matrix (const charMatrix& chm, bool = false)
+    : octave_base_matrix<charNDArray> (chm) { }
+
+  octave_char_matrix (const charNDArray& chm, bool = false)
+    : octave_base_matrix<charNDArray> (chm) { }
+
+  octave_char_matrix (char c)
+    : octave_base_matrix<charNDArray> (c) { }
+
+  octave_char_matrix (const char *s)
+    : octave_base_matrix<charNDArray> (s) { }
+
+  octave_char_matrix (const std::string& s)
+    : octave_base_matrix<charNDArray> (s) { }
+
+  octave_char_matrix (const string_vector& s)
+    : octave_base_matrix<charNDArray> (s) { }
+
+  octave_char_matrix (const octave_char_matrix& chm)
+    : octave_base_matrix<charNDArray> (chm) { }
+
+  ~octave_char_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_char_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_char_matrix (); }
+
+  idx_vector index_vector (void) const;
+
+  bool is_char_matrix (void) const { return true; }
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const
+    { return Matrix (matrix.matrix_value ()); }
+
+  FloatMatrix float_matrix_value (bool = false) const
+    { return FloatMatrix (matrix.matrix_value ()); }
+
+  NDArray array_value (bool = false) const
+    { return NDArray (matrix); }
+
+  FloatNDArray float_array_value (bool = false) const
+    { return FloatNDArray (matrix); }
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return ComplexMatrix (matrix.matrix_value ()); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const
+    { return FloatComplexMatrix (matrix.matrix_value ()); }
+
+  ComplexNDArray complex_array_value (bool = false) const
+    { return ComplexNDArray (matrix); }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const
+    { return FloatComplexNDArray (matrix); }
+
+  charMatrix char_matrix_value (bool = false) const
+    { return matrix.matrix_value (); }
+
+  charNDArray char_array_value (bool = false) const
+    { return matrix; }
+
+  octave_value convert_to_str_internal (bool, bool, char type) const
+    { return octave_value (matrix, true, type); }
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  mxArray *as_mxArray (void) const;
+
+protected:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-class.cc b/src/ov-class.cc
new file mode 100644
index 0000000..e0dfba1
--- /dev/null
+++ b/src/ov-class.cc
@@ -0,0 +1,1858 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Array-util.h"
+#include "byte-swap.h"
+#include "oct-locbuf.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "file-ops.h"
+#include "gripes.h"
+#include "load-path.h"
+#include "ls-hdf5.h"
+#include "ls-oct-ascii.h"
+#include "ls-oct-binary.h"
+#include "ls-utils.h"
+#include "oct-lvalue.h"
+#include "ov-class.h"
+#include "ov-fcn.h"
+#include "pager.h"
+#include "parse.h"
+#include "pr-output.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "variables.h"
+
+DEFINE_OCTAVE_ALLOCATOR(octave_class);
+
+int octave_class::t_id (-1);
+
+const std::string octave_class::t_name ("class");
+
+void
+octave_class::register_type (void)
+{
+  t_id = octave_value_typeinfo::register_type
+    (octave_class::t_name, "<unknown>", octave_value (new octave_class ()));
+}
+
+octave_class::octave_class (const Octave_map& m, const std::string& id, 
+			    const octave_value_list& parents)
+  : octave_base_value (), map (m), c_name (id)
+{
+  octave_idx_type n = parents.length ();
+
+  for (octave_idx_type idx = 0; idx < n; idx++)
+    {
+      octave_value parent = parents(idx);
+
+      if (! parent.is_object ())
+	error ("parents must be objects");
+      else
+	{
+	  std::string cnm = parent.class_name ();
+
+	  if (find_parent_class (cnm))
+	    error ("duplicate class in parent tree");
+	  else
+	    {
+	      parent_list.push_back (cnm);
+
+	      map.assign (cnm, parent);
+	    }
+	}
+    }
+
+  if (! error_state)
+    load_path::add_to_parent_map (id, parent_list);
+}
+
+static std::string
+get_current_method_class (void)
+{
+  std::string retval;
+
+  octave_function *fcn = octave_call_stack::current ();
+
+  std::string my_dir = fcn->dir_name ();
+
+  std::string method_class = file_ops::tail (my_dir);
+
+  if (method_class.size () > 0)
+    retval = method_class.substr (1);
+
+  return retval;
+}
+
+static void
+gripe_invalid_index (void)
+{
+  error ("invalid index for class");
+}
+
+static void
+gripe_invalid_index_for_assignment (void)
+{
+  error ("invalid index for class assignment");
+}
+
+static void
+gripe_invalid_index_type (const std::string& nm, char t)
+{
+  error ("%s cannot be indexed with %c", nm.c_str (), t);
+}
+
+static void
+gripe_failed_assignment (void)
+{
+  error ("assignment to class element failed");
+}
+
+static inline octave_value_list
+sanitize (const octave_value_list& ovl)
+{
+  octave_value_list retval = ovl;
+
+  for (octave_idx_type i = 0; i < ovl.length (); i++)
+    {
+      if (retval(i).is_magic_colon ())
+	retval(i) = ":";
+    }
+
+  return retval;
+}
+
+static inline octave_value
+make_idx_args (const std::string& type,
+	       const std::list<octave_value_list>& idx,
+	       const std::string& who)
+{
+  octave_value retval;
+
+  size_t len = type.length ();
+
+  if (len == idx.size ())
+    {
+      Cell type_field (1, len);
+      Cell subs_field (1, len);
+
+      std::list<octave_value_list>::const_iterator p = idx.begin ();
+
+      for (size_t i = 0; i < len; i++)
+	{
+	  char t = type[i];
+
+	  switch (t)
+	    {
+	    case '(':
+	      type_field(i) = "()";
+	      subs_field(i) = Cell (sanitize (*p++));
+	      break;
+
+	    case '{':
+	      type_field(i) = "{}";
+	      subs_field(i) = Cell (sanitize (*p++));
+	      break;
+
+	    case '.':
+	      {
+		type_field(i) = ".";
+
+		octave_value_list vlist = *p++;
+
+		if (vlist.length () == 1)
+		  {
+		    octave_value val = vlist(0);
+
+		    if (val.is_string ())
+		      subs_field(i) = val;
+		    else
+		      {
+			error ("expecting character string argument for `.' index");
+			return retval;
+		      }
+		  }
+		else
+		  {
+		    error ("expecting single argument for `.' index");
+		    return retval;
+		  }
+	      }
+	      break;
+
+	    default:
+	      panic_impossible ();
+	      break;
+	    }
+	}
+
+      Octave_map m;
+
+      m.assign ("type", type_field);
+      m.assign ("subs", subs_field);
+
+      retval = m;
+    }
+  else
+    error ("invalid index for %s", who.c_str ());
+
+  return retval;
+}
+
+Cell
+octave_class::dotref (const octave_value_list& idx)
+{
+  Cell retval;
+
+  assert (idx.length () == 1);
+
+  std::string method_class = get_current_method_class ();
+
+  // Find the class in which this method resides before attempting to access
+  // the requested field.
+
+  octave_base_value *obvp
+    = method_class.empty () ? 0 : find_parent_class (method_class);
+
+  Octave_map my_map;
+
+  my_map = obvp ? obvp->map_value () : map;
+
+  std::string nm = idx(0).string_value ();
+
+  if (! error_state)
+    {
+      Octave_map::const_iterator p = my_map.seek (nm);
+
+      if (p != my_map.end ())
+	retval = my_map.contents (p);
+      else
+	error ("class has no member `%s'", nm.c_str ());
+    }
+  else
+    gripe_invalid_index ();
+
+  return retval;
+}
+
+static bool
+called_from_builtin (void)
+{
+  octave_function *fcn = octave_call_stack::caller ();
+
+  // FIXME -- we probably need a better check here, or some other
+  // mechanism to avoid overloaded functions when builtin is used.
+  // For example, what if someone overloads the builtin function?
+  // Also, are there other places where using builtin is not properly
+  // avoiding dispatch?
+
+  return (fcn && fcn->name () == "builtin");
+}
+
+octave_value_list
+octave_class::subsref (const std::string& type,
+		       const std::list<octave_value_list>& idx,
+		       int nargout)
+{
+  octave_value_list retval;
+
+  if (in_class_method () || called_from_builtin ())
+    {
+      // FIXME -- this block of code is the same as the body of
+      // octave_struct::subsref.  Maybe it could be shared instead of
+      // duplicated.
+
+      int skip = 1;
+
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (type.length () > 1 && type[1] == '.')
+	      {
+		std::list<octave_value_list>::const_iterator p = idx.begin ();
+		octave_value_list key_idx = *++p;
+
+		Cell tmp = dotref (key_idx);
+
+		if (! error_state)
+		  {
+		    Cell t = tmp.index (idx.front ());
+
+		    retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true);
+
+		    // We handled two index elements, so tell
+		    // next_subsref to skip both of them.
+
+		    skip++;
+		  }
+	      }
+	    else
+	      retval(0) = octave_value (map.index (idx.front ()),
+					class_name ());
+	  }
+	  break;
+
+	case '.':
+	  {
+	    if (map.numel() > 0)
+	      {
+		Cell t = dotref (idx.front ());
+
+		retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true);
+	      }
+	  }
+	  break;
+
+	case '{':
+	  gripe_invalid_index_type (type_name (), type[0]);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+
+      // FIXME -- perhaps there should be an
+      // octave_value_list::next_subsref member function?  See also
+      // octave_user_function::subsref.
+
+      if (idx.size () > 1)
+	retval = retval(0).next_subsref (nargout, type, idx, skip);
+    }
+  else
+    {
+      octave_value meth = symbol_table::find_method ("subsref", class_name ());
+
+      if (meth.is_defined ())
+	{
+	  octave_value_list args;
+
+	  args(1) = make_idx_args (type, idx, "subsref");
+
+	  if (error_state)
+	    return octave_value_list ();
+
+	  count++;
+	  args(0) = octave_value (this);
+
+	  return feval (meth.function_value (), args, nargout);
+	}
+      else
+	{
+	  if (type.length () == 1 && type[0] == '(')
+	    retval(0) = octave_value (map.index (idx.front ()), class_name ());
+	  else
+	    gripe_invalid_index ();
+	}
+    }
+
+  return retval;
+}
+
+octave_value
+octave_class::numeric_conv (const Cell& val, const std::string& type)
+{
+  octave_value retval;
+
+  if (val.length () == 1)
+    {
+      retval = val(0);
+
+      if (type.length () > 0 && type[0] == '.' && ! retval.is_map ())
+	retval = Octave_map ();
+    }
+  else
+    gripe_invalid_index_for_assignment ();
+
+  return retval;
+}
+
+octave_value
+octave_class::subsasgn (const std::string& type,
+			const std::list<octave_value_list>& idx,
+			const octave_value& rhs)
+{
+  octave_value retval;
+
+  if (! (in_class_method () || called_from_builtin ()))
+    {
+      octave_value meth = symbol_table::find_method ("subsasgn", class_name ());
+
+      if (meth.is_defined ())
+	{
+	  octave_value_list args;
+
+	  args(2) = rhs;
+
+	  args(1) = make_idx_args (type, idx, "subsasgn");
+
+	  if (error_state)
+	    return octave_value_list ();
+
+	  count++;
+	  args(0) = octave_value (this);
+
+	  octave_value_list tmp = feval (meth.function_value (), args);
+
+	  // FIXME -- should the subsasgn method be able to return
+	  // more than one value?
+
+	  if (tmp.length () > 1)
+	    error ("expecting single return value from @%s/subsasgn",
+		   class_name().c_str ());
+
+	  else
+	    retval = tmp(0);
+
+	  return retval;
+	}
+    }
+
+  // FIXME -- this block of code is the same as the body of
+  // octave_struct::subsasgn.  Maybe it could be shared instead of
+  // duplicated.
+
+  int n = type.length ();
+
+  octave_value t_rhs = rhs;
+
+  if (n > 1 && ! (type.length () == 2 && type[0] == '(' && type[1] == '.'))
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (type.length () > 1 && type[1] == '.')
+	      {
+		std::list<octave_value_list>::const_iterator p = idx.begin ();
+		octave_value_list t_idx = *p;
+
+		octave_value_list key_idx = *++p;
+
+		assert (key_idx.length () == 1);
+
+		std::string key = key_idx(0).string_value ();
+
+		if (! error_state)
+		  {
+		    octave_value u;
+
+		    if (! map.contains (key))
+		      u = octave_value::empty_conv (type.substr (2), rhs);
+		    else
+		      {
+			Cell map_val = map.contents (key);
+
+			Cell map_elt = map_val.index (idx.front (), true);
+
+			u = numeric_conv (map_elt, type.substr (2));
+		      }
+
+		    if (! error_state)
+		      {
+			std::list<octave_value_list> next_idx (idx);
+
+			// We handled two index elements, so subsasgn to
+			// needs to skip both of them.
+
+			next_idx.erase (next_idx.begin ());
+			next_idx.erase (next_idx.begin ());
+
+			u.make_unique ();
+
+			t_rhs = u.subsasgn (type.substr (2), next_idx, rhs);
+		      }
+		  }
+		else
+		  gripe_invalid_index_for_assignment ();
+	      }
+	    else
+	      gripe_invalid_index_for_assignment ();
+	  }
+	  break;
+
+	case '.':
+	  {
+	    octave_value_list key_idx = idx.front ();
+
+	    assert (key_idx.length () == 1);
+
+	    std::string key = key_idx(0).string_value ();
+
+	    if (! error_state)
+	      {
+		octave_value u;
+
+		if (! map.contains (key))
+		  u = octave_value::empty_conv (type.substr (1), rhs);
+		else
+		  {
+		    Cell map_val = map.contents (key);
+
+		    u = numeric_conv (map_val, type.substr (1));
+		  }
+
+		if (! error_state)
+		  {
+		    std::list<octave_value_list> next_idx (idx);
+
+		    next_idx.erase (next_idx.begin ());
+
+		    u.make_unique ();
+
+		    t_rhs = u.subsasgn (type.substr (1), next_idx, rhs);
+		  }
+	      }
+	    else
+	      gripe_invalid_index_for_assignment ();
+	  }
+	  break;
+
+	case '{':
+	  gripe_invalid_index_type (type_name (), type[0]);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+
+  if (! error_state)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (n > 1 && type[1] == '.')
+	      {
+		std::list<octave_value_list>::const_iterator p = idx.begin ();
+		octave_value_list key_idx = *++p;
+
+		assert (key_idx.length () == 1);
+
+		std::string key = key_idx(0).string_value ();
+
+		if (! error_state)
+		  {
+		    map.assign (idx.front (), key, t_rhs);
+
+		    if (! error_state)
+		      {
+			count++;
+			retval = octave_value (this);
+		      }
+		    else
+		      gripe_failed_assignment ();
+		  }
+		else
+		  gripe_failed_assignment ();
+	      }
+	    else
+	      {
+		if (t_rhs.is_object () || t_rhs.is_map ())
+		  {
+		    Octave_map rhs_map = t_rhs.map_value ();
+
+		    if (! error_state)
+		      {
+			map.assign (idx.front (), rhs_map);
+
+			if (! error_state)
+			  {
+			    count++;
+			    retval = octave_value (this);
+			  }
+			else
+			  gripe_failed_assignment ();
+		      }
+		    else
+		      error ("invalid class assignment");
+		  }
+		else
+		  {
+		    if (t_rhs.is_empty ())
+		      {
+			map.maybe_delete_elements (idx.front());
+
+			if (! error_state)
+			  {
+			    count++;
+			    retval = octave_value (this);
+			  }
+			else
+			  gripe_failed_assignment ();
+		      }
+		    else
+		      error ("invalid class assignment");
+		  }
+	      }
+	  }
+	  break;
+
+	case '.':
+	  {
+	    // Find the class in which this method resides before 
+	    // attempting to access the requested field.
+
+	    std::string method_class = get_current_method_class ();
+
+	    octave_base_value *obvp = find_parent_class (method_class);
+
+	    if (obvp)
+	      {
+		octave_value_list key_idx = idx.front ();
+
+		assert (key_idx.length () == 1);
+
+		std::string key = key_idx(0).string_value ();
+
+		if (! error_state)
+		  {
+		    obvp->assign (key, t_rhs);
+
+		    if (! error_state)
+		      {
+			count++;
+			retval = octave_value (this);
+		      }
+		    else
+		      gripe_failed_assignment ();
+		  }
+		else
+		  gripe_failed_assignment ();
+	      }
+	    else
+	      error ("malformed class");
+	  }
+	  break;
+
+	case '{':
+	  gripe_invalid_index_type (type_name (), type[0]);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+  else
+    gripe_failed_assignment ();
+
+  return retval;
+}
+
+idx_vector
+octave_class::index_vector (void) const
+{
+  idx_vector retval;
+
+  octave_value meth = symbol_table::find_method ("subsindex", class_name ());
+
+  if (meth.is_defined ())
+    {
+      octave_value_list args;
+      args(0) = octave_value (new octave_class (map, c_name));
+
+      octave_value_list tmp = feval (meth.function_value (), args, 1);
+
+      if (!error_state && tmp.length () >= 1)
+	{
+	  if (tmp(0).is_object())
+	    error ("subsindex function must return a valid index vector");
+	  else
+	    // Index vector returned by subsindex is zero based 
+	    // (why this inconsistency Mathworks?), and so we must
+	    // add one to the value returned as the index_vector method
+	    // expects it to be one based.
+	    retval = do_binary_op (octave_value::op_add, tmp (0), 
+				   octave_value (1.0)).index_vector ();
+	}
+    }
+  else
+    error ("no subsindex method defined for class %s",
+	   class_name().c_str ());
+
+  return retval;
+}
+
+size_t
+octave_class::byte_size (void) const
+{
+  // Neglect the size of the fieldnames.
+
+  size_t retval = 0;
+
+  for (Octave_map::const_iterator p = map.begin (); p != map.end (); p++)
+    {
+      std::string key = map.key (p);
+
+      octave_value val = octave_value (map.contents (p));
+
+      retval += val.byte_size ();
+    }
+
+  return retval;
+}
+
+string_vector
+octave_class::map_keys (void) const
+{
+  string_vector retval;
+  gripe_wrong_type_arg ("octave_class::map_keys()", type_name ());
+  return retval;
+}
+
+octave_base_value *
+octave_class::find_parent_class (const std::string& parent_class_name)
+{
+  octave_base_value* retval = 0;
+
+  if (parent_class_name == class_name ())
+    retval = this;
+  else
+    {
+      for (std::list<std::string>::iterator pit = parent_list.begin ();
+	   pit != parent_list.end ();
+	   pit++)
+	{
+	  Octave_map::const_iterator smap = map.seek (*pit);
+
+	  const Cell& tmp = smap->second;
+
+	  octave_value vtmp = tmp(0);
+
+	  octave_base_value *obvp = vtmp.internal_rep ();
+
+	  retval = obvp->find_parent_class (parent_class_name);
+
+	  if (retval)
+	    break;
+	}
+    }
+
+  return retval;
+}
+
+void
+octave_class::print (std::ostream& os, bool) const
+{
+  print_raw (os);
+}
+
+void
+octave_class::print_raw (std::ostream& os, bool) const
+{
+  unwind_protect::begin_frame ("octave_class_print");
+
+  unwind_protect_int (Vstruct_levels_to_print);
+
+  indent (os);
+  os << "  <class " << class_name () << ">";
+  newline (os);
+
+  unwind_protect::run_frame ("octave_class_print");
+}
+
+bool
+octave_class::print_name_tag (std::ostream& os, const std::string& name) const
+{
+  bool retval = false;
+
+  indent (os);
+  os << name << " =";
+  newline (os);
+  newline (os);
+
+  return retval;
+}
+
+void
+octave_class::print_with_name (std::ostream&, const std::string& name, 
+			       bool) const
+{
+  octave_value fcn = symbol_table::find_method ("display", class_name ());
+
+  if (fcn.is_defined ())
+    {
+      octave_value_list args;
+
+      args(0) = octave_value (clone (), 1);
+      
+      string_vector arg_names (1);
+
+      arg_names[0] = name;
+
+      args.stash_name_tags (arg_names);
+
+      feval (fcn.function_value (), args);
+    }
+}
+
+// Loading a class properly requires an exemplar map entry for success.
+// If we don't have one, we attempt to create one by calling the constructor 
+// with no arguments.
+bool
+octave_class::reconstruct_exemplar (void)
+{
+  bool retval = false;
+
+  octave_class::exemplar_const_iterator it
+    = octave_class::exemplar_map.find (c_name);
+
+  if (it != octave_class::exemplar_map.end ())
+    retval = true;
+  else
+    {
+      octave_value ctor = symbol_table::find_method (c_name, c_name);
+
+      if (ctor.is_defined ())
+	{
+	  octave_value_list result = feval (ctor, 1);
+
+	  if (result.length () == 1)
+	    retval = true;
+	  else
+	    warning ("call to constructor for class %s failed", c_name.c_str ());
+	}
+      else
+	warning ("no constructor for class %s", c_name.c_str ());
+    }
+
+  return retval;
+}
+
+void
+octave_class::clear_exemplar_map (void)
+{
+  exemplar_map.clear ();
+}
+
+//  Load/save does not provide enough information to reconstruct the
+//  class inheritance structure.  reconstruct_parents () attempts to
+//  do so.  If successful, a "true" value is returned.
+//
+//  Note that we don't check the loaded object structure against the
+//  class structure here so the user's loadobj method has a chance
+//  to do its magic.
+bool
+octave_class::reconstruct_parents (void)
+{
+  bool retval = true, might_have_inheritance = false;
+  std::string dbgstr = "dork";
+
+  // First, check to see if there might be an issue with inheritance.
+  for (Octave_map::const_iterator p = map.begin (); p != map.end (); p++)
+    {
+      std::string  key = map.key (p);
+      Cell         val = map.contents (p);
+      if ( val(0).is_object() )
+	{
+	  dbgstr = "blork";
+	  if( key == val(0).class_name() )
+	    {
+	      might_have_inheritance = true;
+	      dbgstr = "cork";
+	      break;
+	    }
+	}
+    }
+  
+  if (might_have_inheritance)
+    {
+      octave_class::exemplar_const_iterator it
+	= octave_class::exemplar_map.find (c_name);
+
+      if (it == octave_class::exemplar_map.end ())
+	retval = false;
+      else
+	{
+	  octave_class::exemplar_info exmplr = it->second;
+	  parent_list = exmplr.parents ();
+	  for (std::list<std::string>::iterator pit = parent_list.begin ();
+	       pit != parent_list.end ();
+	       pit++)
+	    {
+	      dbgstr = *pit;
+	      bool dbgbool = map.contains (*pit);
+	      if (!dbgbool)
+		{
+		  retval = false;
+		  break;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+bool
+octave_class::save_ascii (std::ostream& os)
+{
+  os << "# classname: " << class_name () << "\n";
+  Octave_map m;
+  if (load_path::find_method (class_name (), "saveobj") != std::string ())
+    {
+      octave_value in = new octave_class (*this);
+      octave_value_list tmp = feval ("saveobj", in, 1);
+      if (! error_state)
+	m = tmp(0).map_value ();
+      else
+	return false;
+    }
+  else
+    m = map_value ();
+
+  os << "# length: " << m.nfields () << "\n";
+
+  Octave_map::iterator i = m.begin ();
+  while (i != m.end ())
+    {
+      octave_value val = map.contents (i);
+
+      bool b = save_ascii_data (os, val, m.key (i), false, 0);
+      
+      if (! b)
+	return os;
+
+      i++;
+    }
+
+  return true;
+}
+
+bool 
+octave_class::load_ascii (std::istream& is)
+{
+  octave_idx_type len = 0;
+  std::string classname;
+  bool success = true;
+
+  if (extract_keyword (is, "classname", classname) && classname != "")
+    {
+      if (extract_keyword (is, "length", len) && len >= 0)
+	{
+	  if (len > 0)
+	    {
+	      Octave_map m (map);
+
+	      for (octave_idx_type j = 0; j < len; j++)
+		{
+		  octave_value t2;
+		  bool dummy;
+
+		  // recurse to read cell elements
+		  std::string nm
+		    = read_ascii_data (is, std::string (), dummy, t2, j);
+
+		  if (! is)
+		    break;
+
+		  Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+
+		  if (error_state)
+		    {
+		      error ("load: internal error loading class elements");
+		      return false;
+		    }
+
+		  m.assign (nm, tcell);
+		}
+
+	      if (is) 
+		{
+		  c_name = classname;
+		  reconstruct_exemplar ();
+
+		  map = m;
+		  
+		  if (! reconstruct_parents ())
+		    warning ("load: unable to reconstruct object inheritance");
+		  else
+		    {
+		      if (load_path::find_method (classname, "loadobj")
+			  != std::string ())
+			{
+			  octave_value in = new octave_class (*this);
+			  octave_value_list tmp = feval ("loadobj", in, 1);
+
+			  if (! error_state)
+			    map = tmp(0).map_value ();
+			  else
+			    success = false;
+			}
+		    }
+		}
+	      else
+		{
+		  error ("load: failed to load class");
+		  success = false;
+		}
+	    }
+	  else if (len == 0 )
+	    {
+	      map = Octave_map (dim_vector (1, 1));
+	      c_name = classname;
+	    }
+	  else
+	    panic_impossible ();
+	}
+      else 
+	{
+	  error ("load: failed to extract number of elements in class");
+	  success = false;
+	}
+    }
+  else
+    {
+      error ("load: failed to extract name of class");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_class::save_binary (std::ostream& os, bool& save_as_floats)
+{
+  int32_t classname_len = class_name().length ();
+
+  os.write (reinterpret_cast<char *> (&classname_len), 4);
+  os << class_name ();
+
+  Octave_map m;
+  if (load_path::find_method (class_name (), "saveobj") != std::string ())
+    {
+      octave_value in = new octave_class (*this);
+      octave_value_list tmp = feval ("saveobj", in, 1);
+      if (! error_state)
+	m = tmp(0).map_value ();
+      else
+	return false;
+    }
+  else
+    m = map_value ();
+
+  int32_t len = m.nfields();
+  os.write (reinterpret_cast<char *> (&len), 4);
+  
+  Octave_map::iterator i = m.begin ();
+  while (i != m.end ())
+    {
+      octave_value val = map.contents (i);
+
+      bool b = save_binary_data (os, val, m.key (i), "", 0, save_as_floats);
+      
+      if (! b)
+	return os;
+
+      i++;
+    }
+
+  return true;
+}
+
+bool 
+octave_class::load_binary (std::istream& is, bool swap,
+			    oct_mach_info::float_format fmt)
+{
+  bool success = true;
+
+  int32_t classname_len;
+
+  is.read (reinterpret_cast<char *> (&classname_len), 4);
+  if (! is)
+    return false;
+  else if (swap)
+    swap_bytes<4> (&classname_len);
+
+  {
+    OCTAVE_LOCAL_BUFFER (char, classname, classname_len+1);
+    classname[classname_len] = '\0';
+    if (! is.read (reinterpret_cast<char *> (classname), classname_len))
+      return false;
+    c_name = classname;
+  }
+  reconstruct_exemplar ();
+
+  int32_t len;
+  if (! is.read (reinterpret_cast<char *> (&len), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&len);
+
+  if (len > 0)
+    {
+      Octave_map m (map);
+
+      for (octave_idx_type j = 0; j < len; j++)
+	{
+	  octave_value t2;
+	  bool dummy;
+	  std::string doc;
+
+	  // recurse to read cell elements
+	  std::string nm = read_binary_data (is, swap, fmt, std::string (), 
+					     dummy, t2, doc);
+
+	  if (! is)
+	    break;
+
+	  Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+ 
+	  if (error_state)
+	    {
+	      error ("load: internal error loading class elements");
+	      return false;
+	    }
+
+	  m.assign (nm, tcell);
+	}
+
+      if (is) 
+	{
+	  map = m;
+
+	  if (! reconstruct_parents ())
+	    warning ("load: unable to reconstruct object inheritance");
+	  else
+	    {
+	      if (load_path::find_method (c_name, "loadobj") != std::string ())
+		{
+		  octave_value in = new octave_class (*this);
+		  octave_value_list tmp = feval ("loadobj", in, 1);
+
+		  if (! error_state)
+		    map = tmp(0).map_value ();
+		  else
+		    success = false;
+		}
+	    }
+	}
+      else
+	{
+	  warning ("load: failed to load class");
+	  success = false;
+	}
+    }
+  else if (len == 0 )
+    map = Octave_map (dim_vector (1, 1));
+  else
+    panic_impossible ();
+
+  return success;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_class::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+{
+  hsize_t hdims[3];
+  hid_t group_hid = -1;
+  hid_t type_hid = -1;
+  hid_t space_hid = -1;
+  hid_t class_hid = -1;
+  hid_t data_hid = -1;
+  Octave_map m;
+  Octave_map::iterator i;
+
+  group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0)
+    goto error_cleanup;
+
+  // Add the class name to the group
+  type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid, c_name.length () + 1);
+  if (type_hid < 0)
+    goto error_cleanup;
+
+  hdims[0] = 0;
+  space_hid = H5Screate_simple (0 , hdims, 0);
+  if (space_hid < 0)
+    goto error_cleanup;
+
+  class_hid = H5Dcreate (group_hid, "classname",  type_hid, space_hid,
+			 H5P_DEFAULT);
+  if (class_hid < 0 || H5Dwrite (class_hid, type_hid, H5S_ALL, H5S_ALL, 
+				    H5P_DEFAULT, c_name.c_str ()) < 0)
+    goto error_cleanup;
+
+  data_hid = H5Gcreate (group_hid, "value", 0);
+  if (data_hid < 0)
+    goto error_cleanup;
+
+  if (load_path::find_method (class_name (), "saveobj") != std::string ())
+    {
+      octave_value in = new octave_class (*this);
+      octave_value_list tmp = feval ("saveobj", in, 1);
+      if (! error_state)
+	m = tmp(0).map_value ();
+      else
+	goto error_cleanup;
+    }
+  else
+    m = map_value ();
+
+  // recursively add each element of the class to this group
+  i = m.begin ();
+  while (i != m.end ())
+    {
+      octave_value val = map.contents (i);
+
+      bool retval2 = add_hdf5_data (data_hid, val, m.key (i), "", false, 
+				    save_as_floats);
+
+      if (! retval2)
+	break;
+
+      i++;
+    }
+
+ error_cleanup:
+
+  if (data_hid > 0)
+    H5Gclose (data_hid);
+
+  if (class_hid > 0)
+    H5Dclose (class_hid);
+
+  if (space_hid > 0)
+    H5Sclose (space_hid);
+
+  if (type_hid > 0)
+    H5Tclose (type_hid);
+
+  if (group_hid > 0)
+    H5Gclose (group_hid);
+
+  return true;
+}
+
+bool 
+octave_class::load_hdf5 (hid_t loc_id, const char *name,
+			  bool have_h5giterate_bug)
+{
+  bool retval = false;
+
+  hid_t group_hid = -1;
+  hid_t data_hid = -1;
+  hid_t type_hid = -1;
+  hid_t type_class_hid = -1;
+  hid_t space_hid = -1;
+  hid_t subgroup_hid = -1; 
+  hid_t st_id = -1;
+
+  hdf5_callback_data dsub;
+
+  herr_t retval2 = 0;
+  Octave_map m (dim_vector (1, 1));
+  int current_item = 0;
+  hsize_t num_obj = 0;
+  int slen = 0;
+  hsize_t rank = 0;
+
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0)
+    goto error_cleanup;
+
+  
+  data_hid = H5Dopen (group_hid, "classname");
+
+  if (data_hid < 0)
+    goto error_cleanup;
+
+  type_hid = H5Dget_type (data_hid);
+
+  type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid != H5T_STRING)
+    goto error_cleanup;
+	  
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    goto error_cleanup;
+
+  slen = H5Tget_size (type_hid);
+  if (slen < 0)
+    goto error_cleanup;
+
+  // do-while loop here to prevent goto crossing initialization of classname
+  do
+    {
+      OCTAVE_LOCAL_BUFFER (char, classname, slen);
+
+      // create datatype for (null-terminated) string to read into:
+      st_id = H5Tcopy (H5T_C_S1);
+      H5Tset_size (st_id, slen);
+
+      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
+		   classname) < 0)
+	{
+	  H5Tclose (st_id);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+     
+      H5Tclose (st_id);
+      H5Dclose (data_hid);
+      data_hid = -1;
+
+      c_name = classname;
+    }
+  while (0);
+  reconstruct_exemplar ();
+
+
+#ifdef HAVE_H5GGET_NUM_OBJS
+  subgroup_hid = H5Gopen (group_hid, name); 
+  H5Gget_num_objs (subgroup_hid, &num_obj);
+  H5Gclose (subgroup_hid);
+
+  while (current_item < static_cast<int> (num_obj)
+	 && (retval2 = H5Giterate (group_hid, name, &current_item,
+				   hdf5_read_next_data, &dsub)) > 0)
+#else
+  while ((retval2 = H5Giterate (group_hid, name, &current_item,
+				hdf5_read_next_data, &dsub)) > 0)
+#endif
+    {
+      octave_value t2 = dsub.tc;
+
+      Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+ 
+      if (error_state)
+	{
+	  error ("load: internal error loading class elements");
+	  return false;
+	}
+
+      m.assign (dsub.name, tcell);
+
+      if (have_h5giterate_bug)
+	current_item++;  // H5Giterate returned the last index processed
+    }
+
+  if (retval2 >= 0)
+    {
+      map = m;
+
+      if (!reconstruct_parents ())
+	warning ("load: unable to reconstruct object inheritance");
+      else
+	{
+	  if (load_path::find_method (c_name, "loadobj") != std::string ())
+	    {
+	      octave_value in = new octave_class (*this);
+	      octave_value_list tmp = feval ("loadobj", in, 1);
+
+	      if (! error_state)
+		{
+		  map = tmp(0).map_value ();
+		  retval = true;
+		}
+	      else
+		retval = false;
+	    }
+	  else
+	    retval = true;
+	}
+    }
+  
+ error_cleanup:
+  if (data_hid > 0)
+    H5Dclose (data_hid);
+
+  if (data_hid > 0)
+    H5Gclose (group_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_class::as_mxArray (void) const
+{
+  gripe_wrong_type_arg ("octave_class::as_mxArray ()", type_name ());
+
+  return 0;
+}
+
+bool
+octave_class::in_class_method (void) const
+{
+  octave_function *fcn = octave_call_stack::current ();
+
+  return (fcn
+	  && (fcn->is_class_method ()
+	      || fcn->is_class_constructor ()
+	      || fcn->is_private_function_of_class (class_name ()))
+	  && fcn->dispatch_class () == class_name ());
+}
+
+octave_class::exemplar_info::exemplar_info (const octave_value& obj)
+  : field_names (), parent_class_names ()
+{
+  if (obj.is_object ())
+    {
+      Octave_map m = obj.map_value ();
+      field_names = m.keys ();
+
+      parent_class_names = obj.parent_class_name_list ();
+    }
+  else
+    error ("invalid call to exmplar_info constructor");
+}
+
+
+// A map from class names to lists of fields.
+std::map<std::string, octave_class::exemplar_info> octave_class::exemplar_map;
+
+bool
+octave_class::exemplar_info::compare (const octave_value& obj) const
+{
+  bool retval = true;
+
+  if (obj.is_object ())
+    {
+      if (nfields () == obj.nfields ())
+	{
+	  Octave_map obj_map = obj.map_value ();
+	  string_vector obj_fnames = obj_map.keys ();
+	  string_vector fnames = fields ();
+
+	  for (octave_idx_type i = 0; i < nfields (); i++)
+	    {
+	      if (obj_fnames[i] != fnames[i])
+		{
+		  retval = false;
+		  error ("mismatch in field names");
+		  break;
+		}
+	    }
+
+	  if (nparents () == obj.nparents ())
+	    {
+	      std::list<std::string> obj_parents
+		= obj.parent_class_name_list ();
+	      std::list<std::string> pnames = parents ();
+
+	      std::list<std::string>::const_iterator p = obj_parents.begin ();
+	      std::list<std::string>::const_iterator q = pnames.begin ();
+
+	      while (p != obj_parents.end ())
+		{
+		  if (*p++ != *q++)
+		    {
+		      retval = false;
+		      error ("mismatch in parent classes");
+		      break;
+		    }
+		}
+	    }
+	  else
+	    {
+	      retval = false;
+	      error ("mismatch in number of parent classes");
+	    }
+	}
+      else
+	{
+	  retval = false;
+	  error ("mismatch in number of fields");
+	}
+    }
+  else
+    {
+      retval = false;
+      error ("invalid comparison of class exemplar to non-class object");
+    }
+
+  return retval;
+}
+
+DEFUN (class, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} class (@var{expr})\n\
+ at deftypefnx {Built-in Function} {} class (@var{s}, @var{id})\n\
+ at deftypefnx {Built-in Function} {} class (@var{s}, @var{id}, @var{p}, @dots{})\n\
+Return the class of the expression @var{expr} or create a class with\n\
+fields from structure @var{s} and name (string) @var{id}.  Additional\n\
+arguments name a list of parent classes from which the new class is\n\
+derived.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    print_usage ();
+  else if (nargin == 1)
+    retval = args(0).class_name ();
+  else
+    {
+      Octave_map m = args(0).map_value ();
+
+      if (! error_state)
+	{
+	  std::string id = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      octave_function *fcn = octave_call_stack::caller ();
+
+	      if (fcn && fcn->is_class_constructor ())
+		{
+		  if (nargin == 2)
+		    retval = octave_value (new octave_class (m, id));
+		  else
+		    {
+		      octave_value_list parents = args.slice (2, nargin-2);
+
+		      retval = octave_value (new octave_class (m, id, parents));
+		    }
+
+		  if (! error_state)
+		    {
+		      octave_class::exemplar_const_iterator it
+			= octave_class::exemplar_map.find (id);
+
+		      if (it == octave_class::exemplar_map.end ())
+			octave_class::exemplar_map[id]
+			  = octave_class::exemplar_info (retval);
+		      else if (! it->second.compare (retval))
+			error ("class: object of class `%s' does not match previously constructed objects", id.c_str ());
+		    }
+		}
+	      else
+		error ("class: invalid call from outside class constructor");
+	    }
+	  else
+	    error ("class: expecting character string as second argument");
+	}
+      else
+	error ("class: expecting structure as first argument");
+    }
+
+  return retval;
+}
+
+DEFUN (__isa_parent__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __isa_parent__ (@var{class}, @var{name})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 2)
+    {
+      octave_value cls = args(0);
+      octave_value nm = args(1);
+
+      if (! error_state)
+	{
+	  if (cls.find_parent_class (nm.string_value ()))
+	    retval = true;
+	}
+      else
+	error ("__isa_parent__: expecting arguments to be character strings");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__parent_classes__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __parent_classes__ (@var{x})\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval = Cell ();
+
+  if (args.length () == 1)
+    {
+      octave_value arg = args(0);
+
+      if (arg.is_object ())
+	retval = Cell (arg.parent_class_names ());
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isobject, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isobject (@var{x})\n\
+Return true if @var{x} is a class object.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_object ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (ismethod, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ismethod (@var{x}, @var{method})\n\
+Return true if @var{x} is a class object and the string @var{method}\n\
+is a method of this class.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      octave_value arg = args(0);
+
+      std::string class_name;
+
+      if (arg.is_object ())
+	class_name = arg.class_name ();
+      else if (arg.is_string ())
+	class_name = arg.string_value ();
+      else
+	error ("ismethod: expecting object or class name as first argument");
+
+      if (! error_state)
+	{
+	  std::string method = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (load_path::find_method (class_name, method) != std::string ())
+		retval = true;
+	      else
+		retval = false;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (methods, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} methods (@var{x})\n\
+ at deftypefnx {Built-in Function} {} methods (\"classname\")\n\
+Return a cell array containing the names of the methods for the\n\
+object @var{x} or the named class.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      octave_value arg = args(0);
+
+      std::string class_name;
+
+      if (arg.is_object ())
+	class_name = arg.class_name ();
+      else if (arg.is_string ())
+	class_name = arg.string_value ();
+      else
+	error ("methods: expecting object or class name as argument");
+
+      if (! error_state)
+	{
+	  string_vector sv = load_path::methods (class_name);
+
+	  if (nargout == 0)
+	    {
+	      octave_stdout << "Methods for class " << class_name << ":\n\n";
+
+	      sv.list_in_columns (octave_stdout);
+
+	      octave_stdout << std::endl;
+	    }
+	  else
+	    retval = Cell (sv);
+	}	  
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static bool
+is_built_in_class (const std::string& cn)
+{
+  static std::set<std::string> built_in_class_names;
+
+  if (built_in_class_names.empty ())
+    {
+      built_in_class_names.insert ("double");
+      built_in_class_names.insert ("single");
+      built_in_class_names.insert ("cell");
+      built_in_class_names.insert ("struct");
+      built_in_class_names.insert ("logical");
+      built_in_class_names.insert ("char");
+      built_in_class_names.insert ("function handle");
+      built_in_class_names.insert ("int8");
+      built_in_class_names.insert ("uint8");
+      built_in_class_names.insert ("int16");
+      built_in_class_names.insert ("uint16");
+      built_in_class_names.insert ("int32");
+      built_in_class_names.insert ("uint32");
+      built_in_class_names.insert ("int64");
+      built_in_class_names.insert ("uint64");
+    }
+
+  return built_in_class_names.find (cn) != built_in_class_names.end ();
+}
+
+DEFUN (superiorto, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} superiorto (@var{class_name}, @dots{})\n\
+When called from a class constructor, mark the object currently\n\
+constructed as having a higher precedence than @var{class_name}.\n\
+More that one such class can be specified in a single call.\n\
+This function may only be called from a class constructor.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  octave_function *fcn = octave_call_stack::caller ();
+
+  if (fcn && fcn->is_class_constructor ())
+    {
+      for (int i = 0; i < args.length(); i++)
+	{
+	  std::string class_name = args(i).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (! is_built_in_class (class_name))
+		{
+		  std::string this_class_name = fcn->name ();
+
+		  if (! symbol_table::set_class_relationship (this_class_name,
+							      class_name))
+		    {
+		      error ("superiorto: precedence already set for %s and %s",
+			     this_class_name.c_str (), class_name.c_str ());
+		      break;
+		    }
+		}
+	      else
+		{
+		  // User defined classes always have higher precedence
+		  // than built-in classes.
+		}
+	    }
+	  else
+	    {
+	      error ("superiorto: expecting argument to be class name");
+	      break;
+	    }
+	}
+    }
+  else
+    error ("superiorto: invalid call from outside class constructor");
+
+  return retval;
+}
+
+DEFUN (inferiorto, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} inferiorto (@var{class_name}, @dots{})\n\
+When called from a class constructor, mark the object currently\n\
+constructed as having a lower precedence than @var{class_name}.\n\
+More that one such class can be specified in a single call.\n\
+This function may only be called from a class constructor.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  octave_function *fcn = octave_call_stack::caller ();
+
+  if (fcn && fcn->is_class_constructor ())
+    {
+      for (int i = 0; i < args.length(); i++)
+	{
+	  std::string class_name = args(i).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (! is_built_in_class (class_name))
+		{
+		  std::string this_class_name = fcn->name ();
+
+		  symbol_table::set_class_relationship (class_name,
+							this_class_name);
+
+		  if (! symbol_table::set_class_relationship (this_class_name,
+							      class_name))
+		    {
+		      error ("inferiorto: precedence already set for %s and %s",
+			     this_class_name.c_str (), class_name.c_str ());
+		      break;
+		    }
+		}
+	      else
+		{
+		  error ("inferiorto: cannot give user-defined class lower precedence than built-in class");
+		  break;
+		}
+	    }
+	  else
+	    {
+	      error ("inferiorto: expecting argument to be class name");
+	      break;
+	    }
+	}
+    }
+  else
+    error ("inferiorto: invalid call from outside class constructor");
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-class.h b/src/ov-class.h
new file mode 100644
index 0000000..bd3100a
--- /dev/null
+++ b/src/ov-class.h
@@ -0,0 +1,249 @@
+/*
+
+Copyright (C) 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_class_h)
+#define octave_class_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-alloc.h"
+#include "oct-map.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+class octave_value_list;
+
+class tree_walker;
+
+// Data structures.
+
+class
+octave_class : public octave_base_value
+{
+public:
+
+  octave_class (void)
+    : octave_base_value () { }
+
+  octave_class (const Octave_map& m, const std::string& id)
+    : octave_base_value (), map (m), c_name (id) { }
+
+  octave_class (const octave_class& s)
+    : octave_base_value (s), map (s.map), c_name (s.c_name),
+      parent_list (s.parent_list) { }
+
+  octave_class (const Octave_map& m, const std::string& id, 
+                const octave_value_list& parents);
+
+  ~octave_class (void) { }
+
+  octave_base_value *clone (void) const { return new octave_class (*this); }
+
+  octave_base_value *empty_clone (void) const
+  {
+    return new octave_class (Octave_map (map.keys ()), class_name ());
+  }
+
+  Cell dotref (const octave_value_list& idx);
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  static octave_value numeric_conv (const Cell& val,
+				    const std::string& type);
+
+  void assign(const std::string& k, const octave_value& rhs)
+  { map.assign (k, rhs); };
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  idx_vector index_vector (void) const;
+
+  dim_vector dims (void) const { return map.dims (); }
+
+  size_t byte_size (void) const;
+
+  // This is the number of elements in each field.  The total number
+  // of elements is numel () * nfields ().
+  octave_idx_type numel (void) const
+  {
+    dim_vector dv = dims ();
+    return dv.numel ();
+  }
+
+  octave_idx_type nfields (void) const { return map.nfields (); }
+
+  size_t nparents (void) const { return parent_list.size (); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return map.reshape (new_dims); }
+
+  octave_value resize (const dim_vector& dv, bool = false) const
+    { Octave_map tmap = map; tmap.resize (dv); return tmap; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_map (void) const { return false; }
+
+  bool is_object (void) const { return true; }
+
+  Octave_map map_value (void) const { return map; }
+
+  string_vector map_keys (void) const;
+
+  std::list<std::string> parent_class_name_list (void) const
+    { return parent_list; }
+
+  string_vector parent_class_names (void) const
+    { return string_vector (parent_list); }
+
+  octave_base_value *find_parent_class (const std::string&);
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const;
+
+  void print_with_name (std::ostream& os, const std::string& name, 
+			bool print_padding = true) const;
+
+  bool reconstruct_exemplar (void);
+
+  static void clear_exemplar_map (void);
+
+  bool reconstruct_parents (void);
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  mxArray *as_mxArray (void) const;
+
+private:
+
+  Octave_map map;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+public:
+  int type_id (void) const { return t_id; }
+  std::string type_name (void) const { return t_name; }
+  std::string class_name (void) const { return c_name; }
+
+  static int static_type_id (void) { return t_id; }
+  static std::string static_type_name (void) { return t_name; }
+  static std::string static_class_name (void) { return "<unknown>"; }
+  static void register_type (void);
+
+private:
+  static int t_id;
+
+  static const std::string t_name;
+  std::string c_name;
+  std::list<std::string> parent_list;
+
+  bool in_class_method (void) const;
+
+public:
+  // The list of field names and parent classes defines a class.  We
+  // keep track of each class that has been created so that we know
+  class exemplar_info
+  {
+  public:
+
+    exemplar_info (void) : field_names (), parent_class_names () { }
+
+    exemplar_info (const octave_value& obj);
+
+    exemplar_info (const exemplar_info& x)
+      : field_names (x.field_names),
+	parent_class_names (x.parent_class_names) { }
+
+    exemplar_info& operator = (const exemplar_info& x)
+    {
+      if (&x != this)
+	{
+	  field_names = x.field_names;
+	  parent_class_names = x.parent_class_names;
+	}
+      return *this;
+    }
+
+    octave_idx_type nfields (void) const { return field_names.length (); }
+
+    size_t nparents (void) const { return parent_class_names.size (); }
+
+    string_vector fields (void) const { return field_names; }
+
+    std::list<std::string> parents (void) const { return parent_class_names; }
+
+    bool compare (const octave_value& obj) const;
+
+  private:
+
+    string_vector field_names;
+    std::list<std::string> parent_class_names;
+  };
+
+  // A map from class names to lists of fields.
+  static std::map<std::string, exemplar_info> exemplar_map;
+
+  typedef std::map<std::string, exemplar_info>::iterator exemplar_iterator;
+  typedef std::map<std::string, exemplar_info>::const_iterator exemplar_const_iterator;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-colon.cc b/src/ov-colon.cc
new file mode 100644
index 0000000..dfc30fa
--- /dev/null
+++ b/src/ov-colon.cc
@@ -0,0 +1,55 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "error.h"
+#include "pr-output.h"
+#include "oct-obj.h"
+#include "ov-colon.h"
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_magic_colon,
+				     "magic-colon", "magic-colon");
+
+void
+octave_magic_colon::print (std::ostream& os, bool) const
+{
+  indent (os);
+  print_raw (os);
+}
+
+void
+octave_magic_colon::print_raw (std::ostream& os, bool) const
+{
+  os << ":";
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-colon.h b/src/ov-colon.h
new file mode 100644
index 0000000..5a16d8a
--- /dev/null
+++ b/src/ov-colon.h
@@ -0,0 +1,85 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2005, 2006, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_magic_colon_h)
+#define octave_magic_colon_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// A type to represent `:' as used for indexing.
+
+class
+octave_magic_colon : public octave_base_value
+{
+public:
+
+  octave_magic_colon (void)
+    : octave_base_value () { }
+
+  octave_magic_colon (const octave_magic_colon&)
+    : octave_base_value () { }
+
+  ~octave_magic_colon (void) { }
+
+  octave_base_value *clone (void) const { return new octave_magic_colon (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_magic_colon (); }
+
+  idx_vector index_vector (void) const { return idx_vector (':'); }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_magic_colon (void) const { return true; }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+private:
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-complex.cc b/src/ov-complex.cc
new file mode 100644
index 0000000..de9181b
--- /dev/null
+++ b/src/ov-complex.cc
@@ -0,0 +1,504 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-base.h"
+#include "ov-base-scalar.h"
+#include "ov-base-scalar.cc"
+#include "ov-cx-mat.h"
+#include "ov-scalar.h"
+#include "gripes.h"
+#include "pr-output.h"
+#include "ops.h"
+
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+
+template class octave_base_scalar<Complex>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_complex);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex,
+				     "complex scalar", "double");
+
+static octave_base_value *
+default_numeric_demotion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_complex&);
+
+  return new octave_float_complex (v.float_complex_value ());
+}
+
+octave_base_value::type_conv_info
+octave_complex::numeric_demotion_function (void) const
+{
+  return octave_base_value::type_conv_info(default_numeric_demotion_function,
+                                           octave_float_complex::static_type_id ());
+}
+
+octave_base_value *
+octave_complex::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  double im = std::imag (scalar);
+
+  if (im == 0.0 && ! lo_ieee_signbit (im))
+    retval = new octave_scalar (std::real (scalar));
+
+  return retval;
+}
+
+octave_value
+octave_complex::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // FIXME -- this doesn't solve the problem of
+  //
+  //   a = i; a([1,1], [1,1], [1,1])
+  //
+  // and similar constructions.  Hmm...
+
+  // FIXME -- using this constructor avoids narrowing the
+  // 1x1 matrix back to a scalar value.  Need a better solution
+  // to this problem.
+
+  octave_value tmp (new octave_complex_matrix (complex_matrix_value ()));
+
+  return tmp.do_index_op (idx, resize_ok);
+}
+
+double
+octave_complex::double_value (bool force_conversion) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real scalar");
+
+  retval = std::real (scalar);
+
+  return retval;
+}
+
+float
+octave_complex::float_value (bool force_conversion) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real scalar");
+
+  retval = std::real (scalar);
+
+  return retval;
+}
+
+Matrix
+octave_complex::matrix_value (bool force_conversion) const
+{
+  Matrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = Matrix (1, 1, std::real (scalar));
+
+  return retval;
+}
+
+FloatMatrix
+octave_complex::float_matrix_value (bool force_conversion) const
+{
+  FloatMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = FloatMatrix (1, 1, std::real (scalar));
+
+  return retval;
+}
+
+NDArray
+octave_complex::array_value (bool force_conversion) const
+{
+  NDArray retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = NDArray (dim_vector (1, 1), std::real (scalar));
+
+  return retval;
+}
+
+FloatNDArray
+octave_complex::float_array_value (bool force_conversion) const
+{
+  FloatNDArray retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = FloatNDArray (dim_vector (1, 1), std::real (scalar));
+
+  return retval;
+}
+
+Complex
+octave_complex::complex_value (bool) const
+{
+  return scalar;
+}
+
+FloatComplex
+octave_complex::float_complex_value (bool) const
+{
+  return static_cast<FloatComplex> (scalar);
+}
+
+ComplexMatrix
+octave_complex::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (1, 1, scalar);
+}
+
+FloatComplexMatrix
+octave_complex::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (1, 1, static_cast<FloatComplex> (scalar));
+}
+
+ComplexNDArray
+octave_complex::complex_array_value (bool /* force_conversion */) const
+{
+  return ComplexNDArray (dim_vector (1, 1), scalar);
+}
+
+FloatComplexNDArray
+octave_complex::float_complex_array_value (bool /* force_conversion */) const
+{
+  return FloatComplexNDArray (dim_vector (1, 1), static_cast<FloatComplex> (scalar));
+}
+
+octave_value 
+octave_complex::resize (const dim_vector& dv, bool fill) const
+{
+  if (fill)
+    {
+      ComplexNDArray retval (dv, ComplexNDArray::resize_fill_value ());
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+  else
+    {
+      ComplexNDArray retval (dv);
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+}
+
+bool 
+octave_complex::save_ascii (std::ostream& os)
+{
+  Complex c = complex_value ();
+
+  octave_write_complex (os, c);
+
+  os << "\n";
+
+  return true;
+}
+
+bool 
+octave_complex::load_ascii (std::istream& is)
+{
+  scalar = octave_read_complex (is);
+
+  if (!is) 
+    {
+      error ("load: failed to load complex scalar constant");
+      return false;
+    }
+
+  return true;
+}
+
+
+bool 
+octave_complex::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+  char tmp = static_cast<char> (LS_DOUBLE);
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+  Complex ctmp = complex_value ();
+  os.write (reinterpret_cast<char *> (&ctmp), 16);
+
+  return true;
+}
+
+bool 
+octave_complex::load_binary (std::istream& is, bool swap,
+			     oct_mach_info::float_format fmt)
+{
+  char tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    return false;
+
+  Complex ctmp;
+  read_doubles (is, reinterpret_cast<double *> (&ctmp),
+		static_cast<save_type> (tmp), 2, swap, fmt);
+  if (error_state || ! is)
+    return false;
+
+  scalar = ctmp;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_complex::save_hdf5 (hid_t loc_id, const char *name,
+			   bool /* save_as_floats */)
+{
+  hsize_t dimens[3];
+  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
+  bool retval = true;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0)
+    return false;
+
+  type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+  if (type_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      return false;
+    }
+
+  Complex tmp = complex_value ();
+  retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
+		     &tmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_complex::load_hdf5 (hid_t loc_id, const char *name,
+			   bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t type_hid = H5Dget_type (data_hid);
+
+  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+
+  if (! hdf5_types_compatible (type_hid, complex_type))
+    {
+      H5Tclose (complex_type);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  hid_t space_id = H5Dget_space (data_hid);
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+  if (rank != 0) 
+    {
+      H5Tclose (complex_type);
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  // complex scalar:
+  Complex ctmp;
+  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+	       &ctmp) >= 0)
+    {
+      retval = true;
+      scalar = ctmp;
+    }
+
+  H5Tclose (complex_type);
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_complex::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, 1, 1, mxCOMPLEX);
+
+  double *pr = static_cast<double *> (retval->get_data ());
+  double *pi = static_cast<double *> (retval->get_imag_data ());
+
+  pr[0] = std::real (scalar);
+  pi[0] = std::imag (scalar);
+
+  return retval;
+}
+
+static double
+xabs (const Complex& x)
+{
+  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
+}
+
+static double
+ximag (const Complex& x)
+{
+  return x.imag ();
+}
+
+static double
+xreal (const Complex& x)
+{
+  return x.real ();
+}
+
+#define COMPLEX_MAPPER(MAP, FCN)	\
+  octave_value \
+  octave_complex::MAP (void) const \
+  { \
+    return octave_value (FCN (scalar)); \
+  }
+
+#define SCALAR_MAPPER(MAP, FCN)	\
+  octave_value \
+  octave_complex::MAP (void) const \
+  { \
+    if (scalar.imag () == 0) \
+      return octave_value (FCN (scalar.real ())); \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_complex::MAP (void) const \
+  { \
+    if (scalar.imag () == 0) \
+      { \
+	double re = scalar.real (); \
+	return (re < L1 || re > L2 \
+            ? octave_value (CFCN (scalar)) \
+	    : octave_value (RFCN (re))); \
+      } \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+SCALAR_MAPPER (erf, ::erf)
+SCALAR_MAPPER (erfc, ::erfc)
+SCALAR_MAPPER (gamma, xgamma)
+CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+
+COMPLEX_MAPPER (abs, xabs)
+COMPLEX_MAPPER (acos, ::acos)
+COMPLEX_MAPPER (acosh, ::acosh)
+COMPLEX_MAPPER (angle, std::arg)
+COMPLEX_MAPPER (arg, std::arg)
+COMPLEX_MAPPER (asin, ::asin)
+COMPLEX_MAPPER (asinh, ::asinh)
+COMPLEX_MAPPER (atan, ::atan)
+COMPLEX_MAPPER (atanh, ::atanh)
+COMPLEX_MAPPER (ceil, ::ceil)
+COMPLEX_MAPPER (conj, std::conj)
+COMPLEX_MAPPER (cos, std::cos)
+COMPLEX_MAPPER (cosh, std::cosh)
+COMPLEX_MAPPER (exp, std::exp)
+COMPLEX_MAPPER (expm1, ::expm1)
+COMPLEX_MAPPER (fix, ::fix)
+COMPLEX_MAPPER (floor, ::floor)
+COMPLEX_MAPPER (imag, ximag)
+COMPLEX_MAPPER (log, std::log)
+COMPLEX_MAPPER (log2, xlog2)
+COMPLEX_MAPPER (log10, std::log10)
+COMPLEX_MAPPER (log1p, ::log1p)
+COMPLEX_MAPPER (real, xreal)
+COMPLEX_MAPPER (round, xround)
+COMPLEX_MAPPER (roundb, xroundb)
+COMPLEX_MAPPER (signum, ::signum)
+COMPLEX_MAPPER (sin, std::sin)
+COMPLEX_MAPPER (sinh, std::sinh)
+COMPLEX_MAPPER (sqrt, std::sqrt)
+COMPLEX_MAPPER (tan, std::tan)
+COMPLEX_MAPPER (tanh, std::tanh)
+COMPLEX_MAPPER (finite, xfinite)
+COMPLEX_MAPPER (isinf, xisinf)
+COMPLEX_MAPPER (isna, octave_is_NA)
+COMPLEX_MAPPER (isnan, xisnan)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-complex.h b/src/ov-complex.h
new file mode 100644
index 0000000..2ffb098
--- /dev/null
+++ b/src/ov-complex.h
@@ -0,0 +1,221 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_complex_h)
+#define octave_complex_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "lo-ieee.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "ov-base.h"
+#include "ov-cx-mat.h"
+#include "ov-base-scalar.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Complex scalar values.
+
+class
+OCTINTERP_API
+octave_complex : public octave_base_scalar<Complex>
+{
+public:
+
+  octave_complex (void)
+    : octave_base_scalar<Complex> () { }
+
+  octave_complex (const Complex& c)
+    : octave_base_scalar<Complex> (c) { }
+
+  octave_complex (const octave_complex& c)
+    : octave_base_scalar<Complex> (c) { }
+
+  ~octave_complex (void) { }
+
+  octave_base_value *clone (void) const { return new octave_complex (*this); }
+
+  // We return an octave_complex_matrix object here instead of an
+  // octave_complex object so that in expressions like A(2,2,2) = 2
+  // (for A previously undefined), A will be empty instead of a 1x1
+  // object.
+  octave_base_value *empty_clone (void) const
+    { return new octave_complex_matrix (); }
+
+  type_conv_info numeric_demotion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  octave_value any (int = 0) const
+    {
+      return (scalar != Complex (0, 0)
+	      && ! (lo_ieee_isnan (std::real (scalar))
+		    || lo_ieee_isnan (std::imag (scalar))));
+    }
+
+  bool is_complex_scalar (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  NDArray array_value (bool = false) const;
+
+  FloatNDArray float_array_value (bool = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return SparseMatrix (matrix_value ()); }
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (complex_matrix_value ()); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+
+  void increment (void) { scalar += 1.0; }
+
+  void decrement (void) { scalar -= 1.0; }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      // Yes, for compatibility, we drop the imaginary part here.
+      return os.write (array_value (true), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+typedef octave_complex octave_complex_scalar;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cs-list.cc b/src/ov-cs-list.cc
new file mode 100644
index 0000000..f425096
--- /dev/null
+++ b/src/ov-cs-list.cc
@@ -0,0 +1,50 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <sstream>
+
+#include "lo-utils.h"
+
+#include "defun.h"
+#include "error.h"
+#include "ov-cs-list.h"
+#include "unwind-prot.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_cs_list);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cs_list, "cs-list", "cs-list");
+
+octave_cs_list::octave_cs_list (const Cell& c)
+  : octave_base_value (), lst (c)
+{
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cs-list.h b/src/ov-cs-list.h
new file mode 100644
index 0000000..e85cbe5
--- /dev/null
+++ b/src/ov-cs-list.h
@@ -0,0 +1,92 @@
+/*
+
+Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_cs_list_h)
+#define octave_cs_list_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "error.h"
+#include "oct-alloc.h"
+#include "oct-obj.h"
+#include "ov-list.h"
+#include "ov-typeinfo.h"
+
+class tree_walker;
+
+// Lists.
+
+class
+octave_cs_list : public octave_base_value
+{
+public:
+
+  octave_cs_list (void)
+    : octave_base_value (), lst () { }
+
+  octave_cs_list (const octave_value_list& l)
+    : octave_base_value (), lst (l) { }
+
+  octave_cs_list (const Cell& c);
+
+  octave_cs_list (const octave_cs_list& l)
+    : octave_base_value (), lst (l.lst) { }
+
+  ~octave_cs_list (void) { }
+
+  octave_base_value *clone (void) const { return new octave_cs_list (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_cs_list (); }
+
+  dim_vector dims (void) const { return dim_vector (1, lst.length ()); }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_cs_list (void) const { return true; }
+
+  octave_value_list list_value (void) const { return lst; }
+
+private:
+
+  // The list of Octave values.
+  octave_value_list lst;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cx-diag.cc b/src/ov-cx-diag.cc
new file mode 100644
index 0000000..ea8dc2a
--- /dev/null
+++ b/src/ov-cx-diag.cc
@@ -0,0 +1,246 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "byte-swap.h"
+
+#include "ov-cx-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-re-diag.h"
+#include "ov-base-diag.cc"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ls-utils.h"
+
+template class octave_base_diag<ComplexDiagMatrix, ComplexMatrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_complex_diag_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_diag_matrix, 
+                                     "complex diagonal matrix", "double");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+
+  return new octave_complex_matrix (v.complex_matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_complex_diag_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_complex_matrix::static_type_id ());
+}
+
+static octave_base_value *
+default_numeric_demotion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+
+  return new octave_float_complex_diag_matrix (v.float_complex_diag_matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_complex_diag_matrix::numeric_demotion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_demotion_function,
+                                            octave_float_complex_diag_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_complex_diag_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.nelem () == 1)
+    {
+      // FIXME: the proxy mechanism of DiagArray2 causes problems here.
+      retval = new octave_complex (Complex (matrix (0, 0)));
+      octave_base_value *rv2 = retval->try_narrowing_conversion ();
+      if (rv2)
+        {
+          delete retval;
+          retval = rv2;
+        }
+    }
+  else if (matrix.all_elements_are_real ())
+    {
+      return new octave_diag_matrix (::real (matrix));
+    }
+
+  return retval;
+}
+
+DiagMatrix
+octave_complex_diag_matrix::diag_matrix_value (bool force_conversion) const
+{
+  DiagMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       type_name (), "real matrix");
+
+  retval = ::real (matrix);
+
+  return retval;
+}
+
+FloatDiagMatrix
+octave_complex_diag_matrix::float_diag_matrix_value (bool force_conversion) const
+{
+  DiagMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       type_name (), "real matrix");
+
+  retval = ::real (matrix);
+
+  return retval;
+}
+
+ComplexDiagMatrix
+octave_complex_diag_matrix::complex_diag_matrix_value (bool) const
+{
+  return matrix;
+}
+
+FloatComplexDiagMatrix
+octave_complex_diag_matrix::float_complex_diag_matrix_value (bool) const
+{
+  return FloatComplexDiagMatrix (matrix);
+}
+
+octave_value
+octave_complex_diag_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_complex_diag_matrix::real (void) const
+{
+  return ::real (matrix);
+}
+
+octave_value
+octave_complex_diag_matrix::conj (void) const
+{
+  return ::conj (matrix);
+}
+
+octave_value
+octave_complex_diag_matrix::imag (void) const
+{
+  return ::imag (matrix);
+}
+
+octave_value
+octave_complex_diag_matrix::sqrt (void) const
+{    
+  octave_value retval;
+
+  static ComplexNDArray::cmapper csqrt = std::sqrt;
+
+  ComplexColumnVector dvec = matrix.diag ();
+  retval = ComplexDiagMatrix (dvec.map (csqrt));
+
+  retval.resize (dims ());
+
+  return retval;
+}
+
+bool 
+octave_complex_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  ComplexMatrix m = ComplexMatrix (matrix.diag ());
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (matrix.length () > 4096) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const Complex *mtmp = m.data ();
+  write_doubles (os, reinterpret_cast<const double *> (mtmp), st, 2 * m.numel ());
+
+  return true;
+}
+
+bool 
+octave_complex_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  ComplexDiagMatrix m (r, c);
+  Complex *im = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_doubles (is, reinterpret_cast<double *> (im),
+                static_cast<save_type> (tmp), 2 * len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
+bool 
+octave_complex_diag_matrix::chk_valid_scalar (const octave_value& val, 
+                                              Complex& x) const
+{
+  bool retval = val.is_complex_scalar () || val.is_real_scalar ();
+  if (retval)
+    x = val.complex_value ();
+  return retval;
+}
diff --git a/src/ov-cx-diag.h b/src/ov-cx-diag.h
new file mode 100644
index 0000000..bcf3901
--- /dev/null
+++ b/src/ov-cx-diag.h
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_complex_diag_matrix_h)
+#define octave_complex_diag_matrix_h 1
+
+#include "ov-base.h"
+#include "ov-base-diag.h"
+#include "ov-cx-mat.h"
+#include "ov-typeinfo.h"
+
+// Real diagonal matrix values.
+
+class
+OCTINTERP_API
+octave_complex_diag_matrix 
+  : public octave_base_diag<ComplexDiagMatrix, ComplexMatrix>
+{
+public:
+
+  octave_complex_diag_matrix (void)
+    : octave_base_diag<ComplexDiagMatrix, ComplexMatrix> () { }
+
+  octave_complex_diag_matrix (const ComplexDiagMatrix& m)
+    : octave_base_diag<ComplexDiagMatrix, ComplexMatrix> (m) { }
+
+  octave_complex_diag_matrix (const octave_complex_diag_matrix& m)
+    : octave_base_diag<ComplexDiagMatrix, ComplexMatrix> (m) { }
+
+  ~octave_complex_diag_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_complex_diag_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_complex_diag_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  type_conv_info numeric_demotion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  bool is_complex_matrix (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  DiagMatrix diag_matrix_value (bool = false) const;
+
+  FloatDiagMatrix float_diag_matrix_value (bool = false) const;
+
+  ComplexDiagMatrix complex_diag_matrix_value (bool = false) const;
+
+  FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+  octave_value abs (void) const;
+  octave_value conj (void) const;
+  octave_value imag (void) const;
+  octave_value real (void) const;
+  octave_value sqrt (void) const;
+
+private:
+
+  bool chk_valid_scalar (const octave_value&, 
+                         Complex&) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
diff --git a/src/ov-cx-mat.cc b/src/ov-cx-mat.cc
new file mode 100644
index 0000000..d33d109
--- /dev/null
+++ b/src/ov-cx-mat.cc
@@ -0,0 +1,910 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <vector>
+
+#include "data-conv.h"
+#include "lo-ieee.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+#include "mx-base.h"
+#include "mach-info.h"
+#include "oct-locbuf.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "pr-output.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+template class octave_base_matrix<ComplexNDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_complex_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_matrix,
+				     "complex matrix", "double");
+
+static octave_base_value *
+default_numeric_demotion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_complex_matrix&);
+
+  return new octave_float_complex_matrix (v.float_complex_matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_complex_matrix::numeric_demotion_function (void) const
+{
+  return octave_base_value::type_conv_info(default_numeric_demotion_function,
+                                           octave_float_complex_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_complex_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.ndims () == 2)
+    {
+      ComplexMatrix cm = matrix.matrix_value ();
+
+      octave_idx_type nr = cm.rows ();
+      octave_idx_type nc = cm.cols ();
+
+      if (nr == 1 && nc == 1)
+	{
+	  Complex c = matrix (0, 0);
+
+	  double im = std::imag (c);
+
+	  if (im == 0.0 && ! lo_ieee_signbit (im))
+	    retval = new octave_scalar (std::real (c));
+	  else
+	    retval = new octave_complex (c);
+	}
+      else if (nr == 0 || nc == 0)
+	retval = new octave_matrix (Matrix (nr, nc));
+      else if (cm.all_elements_are_real ())
+	retval = new octave_matrix (::real (cm));
+    }
+  else if (matrix.all_elements_are_real ())
+    retval = new octave_matrix (::real (matrix));
+
+  return retval;
+}
+
+double
+octave_complex_matrix::double_value (bool force_conversion) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real scalar");
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "real scalar");
+
+      retval = std::real (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "real scalar");
+
+  return retval;
+}
+
+float
+octave_complex_matrix::float_value (bool force_conversion) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real scalar");
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "real scalar");
+
+      retval = std::real (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "real scalar");
+
+  return retval;
+}
+
+Matrix
+octave_complex_matrix::matrix_value (bool force_conversion) const
+{
+  Matrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real matrix");
+
+  retval = ::real (matrix.matrix_value ());
+
+  return retval;
+}
+
+FloatMatrix
+octave_complex_matrix::float_matrix_value (bool force_conversion) const
+{
+  FloatMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real matrix");
+
+  retval = ::real (matrix.matrix_value ());
+
+  return retval;
+}
+
+Complex
+octave_complex_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_complex_matrix::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "complex scalar");
+
+  return retval;
+}
+
+ComplexMatrix
+octave_complex_matrix::complex_matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
+FloatComplexMatrix
+octave_complex_matrix::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (matrix.matrix_value ());
+}
+
+charNDArray
+octave_complex_matrix::char_array_value (bool frc_str_conv) const
+{
+  charNDArray retval;
+
+  if (! frc_str_conv)
+    gripe_implicit_conversion ("Octave:num-to-str",
+			       "complex matrix", "string");
+  else
+    {
+      retval = charNDArray (dims ());
+      octave_idx_type nel = numel ();
+  
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval.elem (i) = static_cast<char>(std::real (matrix.elem (i)));
+    }
+
+  return retval;
+}  
+
+FloatComplexNDArray 
+octave_complex_matrix::float_complex_array_value (bool) const 
+{ 
+  return FloatComplexNDArray (matrix);
+}
+
+SparseMatrix
+octave_complex_matrix::sparse_matrix_value (bool force_conversion) const
+{
+  SparseMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real matrix");
+
+  retval = SparseMatrix (::real (matrix.matrix_value ()));
+
+  return retval;
+}
+
+SparseComplexMatrix
+octave_complex_matrix::sparse_complex_matrix_value (bool) const
+{
+  return SparseComplexMatrix (matrix.matrix_value ());
+}
+
+octave_value
+octave_complex_matrix::diag (octave_idx_type k) const
+{
+  octave_value retval;
+  if (k == 0 && matrix.ndims () == 2 
+      && (matrix.rows () == 1 || matrix.columns () == 1))
+    retval = ComplexDiagMatrix (DiagArray2<Complex> (matrix));
+  else
+    retval = octave_base_matrix<ComplexNDArray>::diag (k);
+
+  return retval;
+}
+
+bool 
+octave_complex_matrix::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+  if (d.length () > 2)
+    {
+      ComplexNDArray tmp = complex_array_value ();
+
+      os << "# ndims: " << d.length () << "\n";
+
+      for (int i = 0; i < d.length (); i++)
+	os << " " << d (i);
+
+      os << "\n" << tmp;
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for backward 
+      // compatiability. Makes load_ascii much more complex!!
+      os << "# rows: " << rows () << "\n"
+	 << "# columns: " << columns () << "\n";
+
+      os << complex_matrix_value ();
+    }
+
+  return true;
+}
+
+bool 
+octave_complex_matrix::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  string_vector keywords(2);
+
+  keywords[0] = "ndims";
+  keywords[1] = "rows";
+
+  std::string kw;
+  octave_idx_type val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = static_cast<int> (val);
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      if (is)
+		{
+		  ComplexNDArray tmp(dv);
+
+                  is >> tmp;
+
+                  if (is)
+                    matrix = tmp;
+                  else
+                    {
+                      error ("load: failed to load matrix constant");
+                      success = false;
+                    }
+		}
+	      else
+		{
+		  error ("load: failed to read dimensions");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of dimensions");
+	      success = false;
+	    }
+	}
+      else if (kw == "rows")
+	{
+	  octave_idx_type nr = val;
+	  octave_idx_type nc = 0;
+
+	  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  ComplexMatrix tmp (nr, nc);
+		  is >> tmp;
+		  if (is)
+		    matrix = tmp;
+		  else
+		    {
+		      error ("load: failed to load matrix constant");
+		      success = false;
+		    }
+		}
+	      else if (nr == 0 || nc == 0)
+		matrix = ComplexMatrix (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of rows and columns");
+	      success = false;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_complex_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i = 0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  ComplexNDArray m = complex_array_value ();
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (d.numel () > 4096) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+
+  const Complex *mtmp = m.data ();
+  write_doubles (os, reinterpret_cast<const double *> (mtmp), st, 2 * d.numel ());
+
+  return true;
+}
+
+bool 
+octave_complex_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  char tmp;
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims < 0)
+    {
+      mdims = - mdims;
+      int32_t di;
+      dim_vector dv;
+      dv.resize (mdims);
+
+      for (int i = 0; i < mdims; i++)
+	{
+	  if (! is.read (reinterpret_cast<char *> (&di), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&di);
+	  dv(i) = di;
+	}
+
+      // Convert an array with a single dimension to be a row vector.
+      // Octave should never write files like this, other software
+      // might.
+
+      if (mdims == 1)
+	{
+	  mdims = 2;
+	  dv.resize (mdims);
+	  dv(1) = dv(0);
+	  dv(0) = 1;
+	}
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+
+      ComplexNDArray m(dv);
+      Complex *im = m.fortran_vec ();
+      read_doubles (is, reinterpret_cast<double *> (im),
+		    static_cast<save_type> (tmp), 2 * dv.numel (), swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  else
+    {
+      int32_t nr, nc;
+      nr = mdims;
+      if (! is.read (reinterpret_cast<char *> (&nc), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&nc);
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+      ComplexMatrix m (nr, nc);
+      Complex *im = m.fortran_vec ();
+      octave_idx_type len = nr * nc;
+      read_doubles (is, reinterpret_cast<double *> (im),
+		    static_cast<save_type> (tmp), 2*len, swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_complex_matrix::save_hdf5 (hid_t loc_id, const char *name,
+				  bool save_as_floats)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1, type_hid = -1;
+  bool retval = true;
+  ComplexNDArray m = complex_array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, 0);
+  if (space_hid < 0) return false;
+
+  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
+
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	save_type_hid = H5T_NATIVE_FLOAT;
+    }
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+  // hdf5 currently doesn't support float/integer conversions
+  else
+    {
+      double max_val, min_val;
+      
+      if (m.all_integers (max_val, min_val))
+	save_type_hid
+	  = save_type_to_hdf5 (get_save_type (max_val, min_val));
+    }
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+
+  type_hid = hdf5_make_complex_type (save_type_hid);
+  if (type_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      return false;
+    }
+
+  hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+  if (complex_type_hid < 0) retval = false;
+
+  if (retval)
+    {
+      Complex *mtmp = m.fortran_vec ();
+      if (H5Dwrite (data_hid, complex_type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		    mtmp) < 0)
+	{
+	  H5Tclose (complex_type_hid);
+	  retval = false;
+	}
+    }
+
+  H5Tclose (complex_type_hid);
+  H5Dclose (data_hid);
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool 
+octave_complex_matrix::load_hdf5 (hid_t loc_id, const char *name,
+				  bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+      return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t type_hid = H5Dget_type (data_hid);
+
+  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+
+  if (! hdf5_types_compatible (type_hid, complex_type))
+    {
+      H5Tclose (complex_type);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+  
+  if (rank < 1)
+    {
+      H5Tclose (complex_type);
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  if (rank == 1)
+    {
+      dv.resize (2);
+      dv(0) = 1;
+      dv(1) = hdims[0];
+    }
+  else
+    {
+      dv.resize (rank);
+      for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	dv(j) = hdims[i];
+    }
+
+  ComplexNDArray m (dv);
+  Complex *reim = m.fortran_vec ();
+  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+	       reim) >= 0) 
+    {
+      retval = true;
+      matrix = m;
+    }
+
+  H5Tclose (complex_type);
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+void
+octave_complex_matrix::print_raw (std::ostream& os,
+				  bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+mxArray *
+octave_complex_matrix::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, dims (), mxCOMPLEX);
+
+  double *pr = static_cast<double *> (retval->get_data ());
+  double *pi = static_cast<double *> (retval->get_imag_data ());
+
+  mwSize nel = numel ();
+
+  const Complex *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    {
+      pr[i] = std::real (p[i]);
+      pi[i] = std::imag (p[i]);
+    }
+
+  return retval;
+}
+
+#if 0
+static double
+xabs (const Complex& x)
+{
+  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
+}
+#endif
+
+static double
+ximag (const Complex& x)
+{
+  return x.imag ();
+}
+
+static double
+xreal (const Complex& x)
+{
+  return x.real ();
+}
+
+static bool
+any_element_less_than (const NDArray& a, double val)
+{
+  octave_idx_type len = a.length ();
+  const double *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] < val)
+	return true;
+    }
+
+  return false;
+}
+
+static bool
+any_element_greater_than (const NDArray& a, double val)
+{
+  octave_idx_type len = a.length ();
+  const double *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] > val)
+	return true;
+    }
+
+  return false;
+}
+
+#define ARRAY_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_complex_matrix::MAP (void) const \
+  { \
+    static AMAP cmap = FCN; \
+    return matrix.map (cmap); \
+  }
+
+#define DARRAY_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_complex_matrix::MAP (void) const \
+  { \
+    static ComplexNDArray::dmapper dmap = ximag; \
+    NDArray m = matrix.map (dmap); \
+    if (m.all_elements_are_zero ()) \
+      { \
+	dmap = xreal; \
+	m = matrix.map (dmap); \
+        static AMAP cmap = FCN; \
+        return m.map (cmap); \
+      } \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_complex_matrix::MAP (void) const \
+  { \
+    static ComplexNDArray::dmapper idmap = ximag; \
+    NDArray m = matrix.map (idmap); \
+    if (m.all_elements_are_zero ()) \
+      { \
+	static ComplexNDArray::dmapper rdmap = xreal; \
+	m = matrix.map (rdmap); \
+        static NDArray::dmapper dmap = RFCN; \
+        static NDArray::cmapper cmap = CFCN; \
+        return (any_element_less_than (m, L1) \
+                ? octave_value (m.map (cmap)) \
+	        : (any_element_greater_than (m, L2) \
+	           ? octave_value (m.map (cmap)) \
+	           : octave_value (m.map (dmap)))); \
+      } \
+    else \
+      { \
+        /*error ("%s: not defined for complex arguments", #MAP); */	\
+        return octave_value (m); \
+      } \
+  }
+
+// The fast mappers.
+octave_value
+octave_complex_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_complex_matrix::real (void) const
+{
+  return ::real (matrix);
+}
+
+octave_value
+octave_complex_matrix::conj (void) const
+{
+  return ::conj (matrix);
+}
+
+octave_value
+octave_complex_matrix::imag (void) const
+{
+  return ::imag (matrix);
+}
+
+octave_value
+octave_complex_matrix::isnan (void) const
+{
+  return matrix.isnan ();
+}
+
+octave_value
+octave_complex_matrix::isinf (void) const
+{
+  return matrix.isinf ();
+}
+
+octave_value
+octave_complex_matrix::finite (void) const
+{
+  return matrix.isfinite ();
+}
+
+DARRAY_MAPPER (erf, NDArray::dmapper, ::erf)
+DARRAY_MAPPER (erfc, NDArray::dmapper, ::erfc)
+DARRAY_MAPPER (gamma, NDArray::dmapper, xgamma)
+CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+
+ARRAY_MAPPER (acos, ComplexNDArray::cmapper, ::acos)
+ARRAY_MAPPER (acosh, ComplexNDArray::cmapper, ::acosh)
+ARRAY_MAPPER (angle, ComplexNDArray::dmapper, std::arg)
+ARRAY_MAPPER (arg, ComplexNDArray::dmapper, std::arg)
+ARRAY_MAPPER (asin, ComplexNDArray::cmapper, ::asin)
+ARRAY_MAPPER (asinh, ComplexNDArray::cmapper, ::asinh)
+ARRAY_MAPPER (atan, ComplexNDArray::cmapper, ::atan)
+ARRAY_MAPPER (atanh, ComplexNDArray::cmapper, ::atanh)
+ARRAY_MAPPER (ceil, ComplexNDArray::cmapper, ::ceil)
+ARRAY_MAPPER (cos, ComplexNDArray::cmapper, std::cos)
+ARRAY_MAPPER (cosh, ComplexNDArray::cmapper, std::cosh)
+ARRAY_MAPPER (exp, ComplexNDArray::cmapper, std::exp)
+ARRAY_MAPPER (expm1, ComplexNDArray::cmapper, ::expm1)
+ARRAY_MAPPER (fix, ComplexNDArray::cmapper, ::fix)
+ARRAY_MAPPER (floor, ComplexNDArray::cmapper, ::floor)
+ARRAY_MAPPER (log, ComplexNDArray::cmapper, std::log)
+ARRAY_MAPPER (log2, ComplexNDArray::cmapper, xlog2)
+ARRAY_MAPPER (log10, ComplexNDArray::cmapper, std::log10)
+ARRAY_MAPPER (log1p, ComplexNDArray::cmapper, ::log1p)
+ARRAY_MAPPER (round, ComplexNDArray::cmapper, xround)
+ARRAY_MAPPER (roundb, ComplexNDArray::cmapper, xroundb)
+ARRAY_MAPPER (signum, ComplexNDArray::cmapper, ::signum)
+ARRAY_MAPPER (sin, ComplexNDArray::cmapper, std::sin)
+ARRAY_MAPPER (sinh, ComplexNDArray::cmapper, std::sinh)
+ARRAY_MAPPER (sqrt, ComplexNDArray::cmapper, std::sqrt)
+ARRAY_MAPPER (tan, ComplexNDArray::cmapper, std::tan)
+ARRAY_MAPPER (tanh, ComplexNDArray::cmapper, std::tanh)
+ARRAY_MAPPER (isna, ComplexNDArray::bmapper, octave_is_NA)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cx-mat.h b/src/ov-cx-mat.h
new file mode 100644
index 0000000..0125693
--- /dev/null
+++ b/src/ov-cx-mat.h
@@ -0,0 +1,220 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_complex_matrix_h)
+#define octave_complex_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-typeinfo.h"
+
+#include "MatrixType.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Complex matrix values.
+
+class
+OCTINTERP_API
+octave_complex_matrix : public octave_base_matrix<ComplexNDArray>
+{
+public:
+
+  octave_complex_matrix (void)
+    : octave_base_matrix<ComplexNDArray> () { }
+
+  octave_complex_matrix (const ComplexNDArray& m)
+    : octave_base_matrix<ComplexNDArray> (m) { }
+
+  octave_complex_matrix (const ComplexMatrix& m)
+    : octave_base_matrix<ComplexNDArray> (m) { }
+
+  octave_complex_matrix (const ComplexMatrix& m, const MatrixType& t)
+    : octave_base_matrix<ComplexNDArray> (m, t) { }
+
+  octave_complex_matrix (const ArrayN<Complex>& m)
+    : octave_base_matrix<ComplexNDArray> (ComplexNDArray (m)) { }
+
+  octave_complex_matrix (const ComplexDiagMatrix& d)
+    : octave_base_matrix<ComplexNDArray> (ComplexMatrix (d)) { }
+
+  octave_complex_matrix (const ComplexRowVector& v)
+    : octave_base_matrix<ComplexNDArray> (ComplexMatrix (v)) { }
+
+  octave_complex_matrix (const ComplexColumnVector& v)
+    : octave_base_matrix<ComplexNDArray> (ComplexMatrix (v)) { }
+
+  octave_complex_matrix (const octave_complex_matrix& cm)
+    : octave_base_matrix<ComplexNDArray> (cm) { }
+
+  ~octave_complex_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_complex_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_complex_matrix (); }
+
+  type_conv_info numeric_demotion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  bool is_complex_matrix (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const { return matrix; }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+
+  charNDArray char_array_value (bool frc_str_conv = false) const;
+  
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  octave_value diag (octave_idx_type k = 0) const;
+
+  void increment (void) { matrix += Complex (1.0); }
+
+  void decrement (void) { matrix -= Complex (1.0); }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      // Yes, for compatibility, we drop the imaginary part here.
+      return os.write (matrix_value (true), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cx-sparse.cc b/src/ov-cx-sparse.cc
new file mode 100644
index 0000000..b8faeed
--- /dev/null
+++ b/src/ov-cx-sparse.cc
@@ -0,0 +1,972 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+#include <vector>
+
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+
+#include "ov-base.h"
+#include "ov-scalar.h"
+#include "ov-complex.h"
+#include "gripes.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#include "ov-base-sparse.h"
+#include "ov-base-sparse.cc"
+
+#include "ov-bool-sparse.h"
+
+template class OCTINTERP_API octave_base_sparse<SparseComplexMatrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_sparse_complex_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_complex_matrix, "sparse complex matrix", "double");
+
+octave_base_value *
+octave_sparse_complex_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (Vsparse_auto_mutate)
+    {
+      int nr = matrix.rows ();
+      int nc = matrix.cols ();
+
+      // Don't use numel, since it can overflow for very large matrices
+      // Note that for the tests on matrix size, they become approximative
+      // since they involves a cast to double to avoid issues of overflow
+      if (matrix.rows () == 1 && matrix.cols () == 1)
+	{
+	  // Const copy of the matrix, so the right version of () operator used
+	  const SparseComplexMatrix tmp (matrix);
+
+	  Complex c = tmp (0, 0);
+
+	  if (std::imag (c) == 0.0)
+	    retval = new octave_scalar (std::real (c));
+	  else
+	    retval = new octave_complex (c);
+	}
+      else if (nr == 0 || nc == 0)
+	retval = new octave_matrix (Matrix (nr, nc));
+      else if (matrix.all_elements_are_real ())
+	if (matrix.cols () > 0 && matrix.rows () > 0 && 
+	    double (matrix.byte_size ()) > double (matrix.rows ()) *
+	    double (matrix.cols ()) * sizeof (double))
+	  retval = new octave_matrix (::real (matrix.matrix_value ()));
+	else
+	  retval = new octave_sparse_matrix (::real (matrix));
+      else if (matrix.cols () > 0 && matrix.rows () > 0 && 
+	       double (matrix.byte_size ()) > double (matrix.rows ()) *
+	       double (matrix.cols ()) * sizeof (Complex))
+	retval = new octave_complex_matrix (matrix.matrix_value ());
+    }
+  else
+    {
+      if (matrix.all_elements_are_real ())
+	retval = new octave_sparse_matrix (::real (matrix));
+    }
+    
+  return retval;
+}
+
+void
+octave_sparse_complex_matrix::assign (const octave_value_list& idx,
+				      const SparseComplexMatrix& rhs)
+{
+  octave_base_sparse<SparseComplexMatrix>::assign (idx, rhs);
+}
+
+void
+octave_sparse_complex_matrix::assign (const octave_value_list& idx,
+				      const SparseMatrix& rhs)
+{
+  int len = idx.length ();
+
+  for (int i = 0; i < len; i++)
+    matrix.set_index (idx(i).index_vector ());
+
+  ::assign (matrix, rhs);
+}
+
+double
+octave_sparse_complex_matrix::double_value (bool force_conversion) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex sparse matrix", "real scalar");
+
+  // FIXME -- maybe this should be a function, valid_as_scalar()
+  if (numel () > 0)
+    {
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "complex sparse matrix", "real scalar");
+
+      retval = std::real (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("complex sparse matrix", "real scalar");
+
+  return retval;
+}
+
+Matrix
+octave_sparse_complex_matrix::matrix_value (bool force_conversion) const
+{
+  Matrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex sparse matrix", "real matrix");
+
+  retval = ::real (matrix.matrix_value ());
+
+  return retval;
+}
+
+Complex
+octave_sparse_complex_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  // FIXME -- maybe this should be a function, valid_as_scalar()
+  if (numel () > 0)
+    {
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "complex sparse matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("complex sparse matrix", "real scalar");
+
+  return retval;
+}
+
+ComplexMatrix
+octave_sparse_complex_matrix::complex_matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
+ComplexNDArray 
+octave_sparse_complex_matrix::complex_array_value (bool) const
+{
+  return ComplexNDArray (matrix.matrix_value ());
+}
+
+charNDArray
+octave_sparse_complex_matrix::char_array_value (bool frc_str_conv) const
+{
+  charNDArray retval;
+
+  if (! frc_str_conv)
+    gripe_implicit_conversion ("Octave:num-to-str",
+			       "sparse complex matrix", "string");
+  else
+    {
+      retval = charNDArray (dims (), 0);
+      octave_idx_type nc = matrix.cols ();
+      octave_idx_type nr = matrix.rows ();
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++)
+	  retval(matrix.ridx(i) + nr * j) = 
+	    static_cast<char>(std::real (matrix.data (i)));
+    }
+
+  return retval;
+}
+
+SparseMatrix
+octave_sparse_complex_matrix::sparse_matrix_value (bool force_conversion) const
+{
+  SparseMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex sparse matrix", 
+			       "real sparse matrix");
+
+  retval = ::real (matrix);
+
+  return retval;
+}
+
+bool 
+octave_sparse_complex_matrix::save_binary (std::ostream& os, 
+					   bool&save_as_floats)
+{
+  dim_vector d = this->dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  int nr = d(0);
+  int nc = d(1);
+  int nz = nzmax ();
+
+  int32_t itmp;
+  // Use negative value for ndims to be consistent with other formats
+  itmp= -2;        
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nr;    
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nc;
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nz;
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (matrix.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (matrix.nzmax () > 8192) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (matrix.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  // add one to the printed indices to go from
+  // zero-based to one-based arrays
+   for (int i = 0; i < nc+1; i++)  
+     {
+       OCTAVE_QUIT;
+       itmp = matrix.cidx(i);
+       os.write (reinterpret_cast<char *> (&itmp), 4);
+     }
+
+   for (int i = 0; i < nz; i++) 
+     {
+       OCTAVE_QUIT;
+       itmp = matrix.ridx(i); 
+       os.write (reinterpret_cast<char *> (&itmp), 4);
+     }
+
+   write_doubles (os, reinterpret_cast<const double *> (matrix.data()), st, 2 * nz);
+
+  return true;
+}
+
+bool
+octave_sparse_complex_matrix::load_binary (std::istream& is, bool swap,
+				   oct_mach_info::float_format fmt)
+{
+  int32_t nz, nc, nr, tmp;
+  char ctmp;
+
+  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+    return false;
+
+  if (swap)
+    swap_bytes<4> (&tmp);
+
+  if (tmp != -2) {
+    error("load: only 2D sparse matrices are supported");
+    return false;
+  }
+
+  if (! is.read (reinterpret_cast<char *> (&nr), 4))
+    return false;
+  if (! is.read (reinterpret_cast<char *> (&nc), 4))
+    return false;
+  if (! is.read (reinterpret_cast<char *> (&nz), 4))
+    return false;
+
+  if (swap)
+    {
+      swap_bytes<4> (&nr);
+      swap_bytes<4> (&nc);
+      swap_bytes<4> (&nz);
+    }
+
+  SparseComplexMatrix m (static_cast<octave_idx_type> (nr),
+			 static_cast<octave_idx_type> (nc),
+			 static_cast<octave_idx_type> (nz));
+
+  for (int i = 0; i < nc+1; i++) 
+    {
+      OCTAVE_QUIT;
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+      m.cidx(i) = tmp;
+    }
+
+  for (int i = 0; i < nz; i++) 
+    {
+      OCTAVE_QUIT;
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+      m.ridx(i) = tmp;
+    }
+
+  if (! is.read (reinterpret_cast<char *> (&ctmp), 1))
+    return false;
+  
+  read_doubles (is, reinterpret_cast<double *> (m.data ()),
+		static_cast<save_type> (ctmp), 2 * nz, swap, fmt);
+
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_sparse_complex_matrix::save_hdf5 (hid_t loc_id, const char *name, 
+					 bool save_as_floats)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  hid_t group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0)
+    return false;
+
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  SparseComplexMatrix m = sparse_complex_matrix_value ();
+  octave_idx_type tmp;
+  hsize_t hdims[2];
+
+  space_hid = H5Screate_simple (0, hdims, 0);
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.rows ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.cols ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.nzmax ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+
+  hdims[0] = m.cols() + 1;
+  hdims[1] = 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  octave_idx_type * itmp = m.xcidx ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, itmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  H5Sclose (space_hid);
+
+  hdims[0] = m.nzmax ();
+  hdims[1] = 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  itmp = m.xridx ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
+
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	save_type_hid = H5T_NATIVE_FLOAT;
+    }
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+  // hdf5 currently doesn't support float/integer conversions
+  else
+    {
+      double max_val, min_val;
+
+      if (m.all_integers (max_val, min_val))
+	save_type_hid
+	  = save_type_to_hdf5 (get_save_type (max_val, min_val));
+    }
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+
+  hid_t type_hid = hdf5_make_complex_type (save_type_hid);
+  if (type_hid < 0)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+  retval = false;
+  if (complex_type_hid >= 0) 
+    {
+      Complex * ctmp = m.xdata ();
+
+      retval = H5Dwrite (data_hid, complex_type_hid, H5S_ALL, H5S_ALL,
+			 H5P_DEFAULT, ctmp) >= 0;
+    }
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+  H5Tclose (type_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+bool
+octave_sparse_complex_matrix::load_hdf5 (hid_t loc_id, const char *name,
+					 bool /* have_h5giterate_bug */)
+{
+  octave_idx_type nr, nc, nz;
+  hid_t group_hid, data_hid, space_hid;
+  hsize_t rank;
+  
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+    return (empty > 0);
+  
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0 ) return false;
+
+  data_hid = H5Dopen (group_hid, "nr");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nr) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "nc");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nc) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+  
+  data_hid = H5Dopen (group_hid, "nz");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nz) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+
+  SparseComplexMatrix m (static_cast<octave_idx_type> (nr),
+			 static_cast<octave_idx_type> (nc),
+			 static_cast<octave_idx_type> (nz));
+
+  data_hid = H5Dopen (group_hid, "cidx");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nc + 1 || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  octave_idx_type *itmp = m.xcidx ();
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "ridx");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nz || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  itmp = m.xridx ();
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "data");
+  hid_t type_hid = H5Dget_type (data_hid);
+
+  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
+
+  if (! hdf5_types_compatible (type_hid, complex_type))
+    {
+      H5Tclose (complex_type);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nz || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  Complex *ctmp = m.xdata ();
+  bool retval = false;
+  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, ctmp) >= 0) 
+    {
+      retval = true;
+      matrix = m;
+    }
+
+  H5Tclose (complex_type);
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_sparse_complex_matrix::as_mxArray (void) const
+{
+  mwSize nz = nzmax ();
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, rows (), columns (),
+				 nz, mxCOMPLEX);
+  double *pr = static_cast<double *> (retval->get_data ());
+  double *pi = static_cast<double *> (retval->get_imag_data ());
+  mwIndex *ir = retval->get_ir ();
+  mwIndex *jc = retval->get_jc ();
+
+  for (mwIndex i = 0; i < nz; i++)
+    {
+      Complex val = matrix.data(i);
+      pr[i] = std::real (val);
+      pi[i] = std::imag (val);
+      ir[i] = matrix.ridx(i);
+    }
+
+  for (mwIndex i = 0; i < columns() + 1; i++)
+    jc[i] = matrix.cidx(i);
+
+  return retval;
+}
+
+static double
+xabs (const Complex& x)
+{
+  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
+}
+
+static double
+ximag (const Complex& x)
+{
+  return x.imag ();
+}
+
+static double
+xreal (const Complex& x)
+{
+  return x.real ();
+}
+
+static bool
+any_element_less_than (const SparseMatrix& a, double val)
+{
+  octave_idx_type len = a.nnz ();
+
+  if (val > 0. && len != a.numel ())
+    return true;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (a.data(i) < val)
+	return true;
+    }
+
+  return false;
+}
+
+static bool
+any_element_greater_than (const SparseMatrix& a, double val)
+{
+  octave_idx_type len = a.nnz ();
+
+  if (val < 0. && len != a.numel ())
+    return true;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (a.data(i) > val)
+	return true;
+    }
+
+  return false;
+}
+
+#define SPARSE_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_sparse_complex_matrix::MAP (void) const \
+  { \
+    static AMAP cmap = FCN; \
+    return matrix.map (cmap); \
+  }
+
+#define DSPARSE_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_sparse_complex_matrix::MAP (void) const \
+  { \
+    static SparseComplexMatrix::dmapper dmap = ximag; \
+    SparseMatrix m = matrix.map (dmap); \
+    if (m.all_elements_are_zero ()) \
+      { \
+	dmap = xreal; \
+	m = matrix.map (dmap); \
+        static AMAP cmap = FCN; \
+        return m.map (cmap); \
+      } \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+#define CD_SPARSE_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_sparse_complex_matrix::MAP (void) const \
+  { \
+    static SparseComplexMatrix::dmapper idmap = ximag; \
+    SparseMatrix m = matrix.map (idmap); \
+    if (m.all_elements_are_zero ()) \
+      { \
+        static SparseComplexMatrix::dmapper rdmap = xreal; \
+	m = matrix.map (rdmap); \
+        static SparseMatrix::dmapper dmap = RFCN; \
+        static SparseMatrix::cmapper cmap = CFCN; \
+        return (any_element_less_than (m, L1) \
+                ? octave_value (m.map (cmap)) \
+	        : (any_element_greater_than (m, L2) \
+	           ? octave_value (m.map (cmap)) \
+	           : octave_value (m.map (dmap)))); \
+      } \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+DSPARSE_MAPPER (erf, SparseMatrix::dmapper, ::erf)
+DSPARSE_MAPPER (erfc, SparseMatrix::dmapper, ::erfc)
+DSPARSE_MAPPER (gamma, SparseMatrix::dmapper, xgamma)
+CD_SPARSE_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+
+SPARSE_MAPPER (abs, SparseComplexMatrix::dmapper, xabs)
+SPARSE_MAPPER (acos, SparseComplexMatrix::cmapper, ::acos)
+SPARSE_MAPPER (acosh, SparseComplexMatrix::cmapper, ::acosh)
+SPARSE_MAPPER (angle, SparseComplexMatrix::dmapper, std::arg)
+SPARSE_MAPPER (arg, SparseComplexMatrix::dmapper, std::arg)
+SPARSE_MAPPER (asin, SparseComplexMatrix::cmapper, ::asin)
+SPARSE_MAPPER (asinh, SparseComplexMatrix::cmapper, ::asinh)
+SPARSE_MAPPER (atan, SparseComplexMatrix::cmapper, ::atan)
+SPARSE_MAPPER (atanh, SparseComplexMatrix::cmapper, ::atanh)
+SPARSE_MAPPER (ceil, SparseComplexMatrix::cmapper, ::ceil)
+SPARSE_MAPPER (conj, SparseComplexMatrix::cmapper, std::conj)
+SPARSE_MAPPER (cos, SparseComplexMatrix::cmapper, std::cos)
+SPARSE_MAPPER (cosh, SparseComplexMatrix::cmapper, std::cosh)
+SPARSE_MAPPER (exp, SparseComplexMatrix::cmapper, std::exp)
+SPARSE_MAPPER (expm1, SparseComplexMatrix::cmapper, ::expm1)
+SPARSE_MAPPER (fix, SparseComplexMatrix::cmapper, ::fix)
+SPARSE_MAPPER (floor, SparseComplexMatrix::cmapper, ::floor)
+SPARSE_MAPPER (imag, SparseComplexMatrix::dmapper, ximag)
+SPARSE_MAPPER (log, SparseComplexMatrix::cmapper, std::log)
+SPARSE_MAPPER (log2, SparseComplexMatrix::cmapper, xlog2)
+SPARSE_MAPPER (log10, SparseComplexMatrix::cmapper, std::log10)
+SPARSE_MAPPER (log1p, SparseComplexMatrix::cmapper, ::log1p)
+SPARSE_MAPPER (real, SparseComplexMatrix::dmapper, xreal)
+SPARSE_MAPPER (round, SparseComplexMatrix::cmapper, xround)
+SPARSE_MAPPER (roundb, SparseComplexMatrix::cmapper, xroundb)
+SPARSE_MAPPER (signum, SparseComplexMatrix::cmapper, ::signum)
+SPARSE_MAPPER (sin, SparseComplexMatrix::cmapper, std::sin)
+SPARSE_MAPPER (sinh, SparseComplexMatrix::cmapper, std::sinh)
+SPARSE_MAPPER (sqrt, SparseComplexMatrix::cmapper, std::sqrt)
+SPARSE_MAPPER (tan, SparseComplexMatrix::cmapper, std::tan)
+SPARSE_MAPPER (tanh, SparseComplexMatrix::cmapper, std::tanh)
+SPARSE_MAPPER (finite, SparseComplexMatrix::bmapper, xfinite)
+SPARSE_MAPPER (isinf, SparseComplexMatrix::bmapper, xisinf)
+SPARSE_MAPPER (isna, SparseComplexMatrix::bmapper, octave_is_NA)
+SPARSE_MAPPER (isnan, SparseComplexMatrix::bmapper, xisnan)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-cx-sparse.h b/src/ov-cx-sparse.h
new file mode 100644
index 0000000..de4bbfe
--- /dev/null
+++ b/src/ov-cx-sparse.h
@@ -0,0 +1,205 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_complex_matrix_h)
+#define octave_sparse_complex_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+#include "CSparse.h"
+#include "ov-base-sparse.h"
+#include "ov-re-sparse.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+class
+OCTINTERP_API
+octave_sparse_complex_matrix : public octave_base_sparse<SparseComplexMatrix>
+{
+public:
+
+  octave_sparse_complex_matrix (void)
+    : octave_base_sparse<SparseComplexMatrix> () { }
+
+  octave_sparse_complex_matrix (const ComplexNDArray& m)
+    : octave_base_sparse<SparseComplexMatrix> (SparseComplexMatrix (m)) { }
+
+  octave_sparse_complex_matrix (const ComplexMatrix& m)
+    : octave_base_sparse<SparseComplexMatrix> (SparseComplexMatrix (m)) { }
+
+  octave_sparse_complex_matrix (const SparseComplexMatrix& m)
+    : octave_base_sparse<SparseComplexMatrix> (m) { }
+
+  octave_sparse_complex_matrix (const SparseComplexMatrix& m, 
+				const MatrixType &t)
+    : octave_base_sparse<SparseComplexMatrix> (m, t) { }
+
+  octave_sparse_complex_matrix (const MSparse<Complex>& m)
+    : octave_base_sparse<SparseComplexMatrix> (m) { }
+
+  octave_sparse_complex_matrix (const MSparse<Complex>& m, 
+				const MatrixType &t)
+    : octave_base_sparse<SparseComplexMatrix> (m, t) { }
+
+  octave_sparse_complex_matrix (const Sparse<Complex>& m, 
+				const MatrixType &t)
+    : octave_base_sparse<SparseComplexMatrix> (SparseComplexMatrix (m), t) { }
+
+  octave_sparse_complex_matrix (const Sparse<Complex>& m)
+    : octave_base_sparse<SparseComplexMatrix> (SparseComplexMatrix (m)) { }
+
+  octave_sparse_complex_matrix (const octave_sparse_complex_matrix& cm)
+    : octave_base_sparse<SparseComplexMatrix> (cm) { }
+
+  ~octave_sparse_complex_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_sparse_complex_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_sparse_complex_matrix (); }
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  void assign (const octave_value_list& idx, const SparseComplexMatrix& rhs);
+
+  void assign (const octave_value_list& idx, const SparseMatrix& rhs);
+
+  bool is_complex_matrix (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+
+  charNDArray char_array_value (bool frc_str_conv = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return matrix; }
+
+#if 0
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      // Yes, for compatibility, we drop the imaginary part here.
+      return os.write (matrix_value (true), block_size, output_type,
+		       skip, flt_fmt);
+    }
+#endif
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-dld-fcn.cc b/src/ov-dld-fcn.cc
new file mode 100644
index 0000000..ad5446a
--- /dev/null
+++ b/src/ov-dld-fcn.cc
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-shlib.h"
+
+#include <defaults.h>
+#include "dynamic-ld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-dld-fcn.h"
+#include "ov.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_dld_function);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_dld_function,
+				     "dynamically-linked function",
+				     "dynamically-linked function");
+
+
+octave_dld_function::octave_dld_function
+  (octave_builtin::fcn ff, const octave_shlib& shl,
+   const std::string& nm, const std::string& ds)
+  : octave_builtin (ff, nm, ds), sh_lib (shl)
+{
+  mark_fcn_file_up_to_date (time_parsed ());
+
+  std::string file_name = fcn_file_name ();
+
+  system_fcn_file
+    = (! file_name.empty ()
+       && Voct_file_dir == file_name.substr (0, Voct_file_dir.length ()));
+}
+
+octave_dld_function::~octave_dld_function (void)
+{
+  octave_dynamic_loader::remove_oct (my_name, sh_lib);
+}
+
+std::string
+octave_dld_function::fcn_file_name (void) const
+{
+  return sh_lib.file_name ();
+}
+
+octave_time
+octave_dld_function::time_parsed (void) const
+{
+  return sh_lib.time_loaded ();
+}
+
+// Note: this wrapper around the octave_dld_function constructor is
+//       necessary to work around a MSVC limitation handling in
+//       virtual destructors that prevents unloading a dynamic module
+//       before *all* objects (of class using a virtual dtor) have
+//       been fully deleted; indeed, MSVC attaches auto-generated code
+//       (scalar deleting destructor) to objects created in a dynamic
+//       module, and this code will be executed in the dynamic module
+//       context at object deletion; unloading the dynamic module
+//       before objects have been deleted will make the "delete" code
+//       of objects to point to an invalid code segment.
+
+octave_dld_function*
+octave_dld_function::create (octave_builtin::fcn ff, const octave_shlib& shl,
+			     const std::string& nm, const std::string& ds)
+{
+  return new octave_dld_function (ff, shl, nm, ds);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-dld-fcn.h b/src/ov-dld-fcn.h
new file mode 100644
index 0000000..1a64612
--- /dev/null
+++ b/src/ov-dld-fcn.h
@@ -0,0 +1,105 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_dld_function_h)
+#define octave_dld_function_h 1
+
+#include <string>
+
+#include "oct-shlib.h"
+
+#include "ov-fcn.h"
+#include "ov-builtin.h"
+#include "ov-typeinfo.h"
+
+class octave_shlib;
+
+class octave_value;
+class octave_value_list;
+
+// Dynamically-linked functions.
+
+class
+OCTINTERP_API
+octave_dld_function : public octave_builtin
+{
+public:
+
+  octave_dld_function (void) { }
+
+  octave_dld_function (octave_builtin::fcn ff, const octave_shlib& shl,
+		       const std::string& nm = std::string (),
+		       const std::string& ds = std::string ());
+
+  ~octave_dld_function (void);
+
+  void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; }
+
+  std::string fcn_file_name (void) const;
+
+  octave_time time_parsed (void) const;
+
+  octave_time time_checked (void) const { return t_checked; }
+
+  bool is_system_fcn_file (void) const { return system_fcn_file; }
+
+  bool is_builtin_function (void) const { return false; }
+
+  bool is_dld_function (void) const { return true; }
+  
+  static octave_dld_function* create (octave_builtin::fcn ff,
+      const octave_shlib& shl,
+      const std::string& nm = std::string (),
+      const std::string& ds = std::string ());
+
+private:
+
+  octave_shlib sh_lib;
+
+  // The time the file was last checked to see if it needs to be
+  // parsed again.
+  mutable octave_time t_checked;
+
+  // True if this function came from a file that is considered to be a
+  // system function.  This affects whether we check the time stamp
+  // on the file to see if it has changed.
+  bool system_fcn_file;
+
+  // No copying!
+
+  octave_dld_function (const octave_dld_function& fn);
+
+  octave_dld_function& operator = (const octave_dld_function& fn);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-fcn-handle.cc b/src/ov-fcn-handle.cc
new file mode 100644
index 0000000..0c97d95
--- /dev/null
+++ b/src/ov-fcn-handle.cc
@@ -0,0 +1,1405 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+#include "file-ops.h"
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "oct-map.h"
+#include "ov-base.h"
+#include "ov-fcn-handle.h"
+#include "ov-usr-fcn.h"
+#include "pr-output.h"
+#include "pt-pr-code.h"
+#include "pt-misc.h"
+#include "pt-stmt.h"
+#include "pt-cmd.h"
+#include "pt-exp.h"
+#include "pt-assign.h"
+#include "variables.h"
+#include "parse.h"
+#include "unwind-prot.h"
+#include "defaults.h"
+#include "file-stat.h"
+#include "load-path.h"
+#include "oct-env.h"
+
+#include "byte-swap.h"
+#include "ls-ascii-helper.h"
+#include "ls-hdf5.h"
+#include "ls-oct-ascii.h"
+#include "ls-oct-binary.h"
+#include "ls-utils.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_fcn_handle);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_handle,
+				     "function handle",
+				     "function_handle");
+
+octave_fcn_handle::octave_fcn_handle (const octave_value& f,
+				      const std::string& n)
+  : warn_reload (true), fcn (f), nm (n)
+{
+  octave_user_function *uf = fcn.user_function_value (true);
+
+  if (uf)
+    symbol_table::cache_name (uf->scope (), nm);
+}
+
+octave_value_list
+octave_fcn_handle::subsref (const std::string& type,
+			    const std::list<octave_value_list>& idx,
+			    int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	out_of_date_check (fcn);
+
+	if (fcn.is_defined ())
+	  {
+	    octave_function *f = function_value ();
+
+	    if (f)
+	      retval = f->subsref (type, idx, nargout);
+	    else
+	      error ("invalid function handle");
+	  }
+	else
+	  error ("invalid function handle");
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string typ_nm = type_name ();
+	error ("%s cannot be indexed with %c", typ_nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // There's no need to call next_subsref here --
+  // octave_function::subsref will handle that for us.
+
+  return retval;
+}
+
+bool
+octave_fcn_handle::set_fcn (const std::string &octaveroot, 
+			    const std::string& fpath)
+{
+  bool success = true;
+
+  if (octaveroot.length () != 0
+      && fpath.length () >= octaveroot.length ()
+      && fpath.substr (0, octaveroot.length ()) == octaveroot
+      && OCTAVE_EXEC_PREFIX != octaveroot)
+    {
+      // First check if just replacing matlabroot is enough
+      std::string str = OCTAVE_EXEC_PREFIX + 
+	fpath.substr (octaveroot.length ());		    
+      file_stat fs (str);
+
+      if (fs.exists ())
+	{
+	  size_t xpos = str.find_last_of (file_ops::dir_sep_chars ());
+
+	  std::string dir_name = str.substr (0, xpos);
+
+	  octave_function *xfcn
+	    = load_fcn_from_file (str, dir_name, "", nm);
+
+	  if (xfcn)
+	    {
+	      octave_value tmp (xfcn);
+
+	      fcn = octave_value (new octave_fcn_handle (tmp, nm));
+	    }
+	  else
+	    {
+	      error ("function handle points to non-existent function");
+	      success = false;
+	    }
+	}
+      else
+	{
+	  // Next just search for it anywhere in the system path
+	  string_vector names(3);
+	  names(0) = nm + ".oct";
+	  names(1) = nm + ".mex";
+	  names(2) = nm + ".m";
+
+	  dir_path p (load_path::system_path ());
+
+	  str = octave_env::make_absolute 
+	    (p.find_first_of (names), octave_env::getcwd ());
+
+	  size_t xpos = str.find_last_of (file_ops::dir_sep_chars ());
+
+	  std::string dir_name = str.substr (0, xpos);
+
+	  octave_function *xfcn = load_fcn_from_file (str, dir_name, "", nm);
+
+	  if (xfcn)
+	    {
+	      octave_value tmp (xfcn);
+
+	      fcn = octave_value (new octave_fcn_handle (tmp, nm));
+	    }
+	  else
+	    {
+	      error ("function handle points to non-existent function");
+	      success = false;
+	    }
+	}
+    }
+  else
+    {
+      if (fpath.length () > 0)
+	{
+	  size_t xpos = fpath.find_last_of (file_ops::dir_sep_chars ());
+
+	  std::string dir_name = fpath.substr (0, xpos);
+
+	  octave_function *xfcn = load_fcn_from_file (fpath, dir_name, "", nm);
+
+	  if (xfcn)
+	    {
+	      octave_value tmp (xfcn);
+
+	      fcn = octave_value (new octave_fcn_handle (tmp, nm));
+	    }
+	  else
+	    {
+	      error ("function handle points to non-existent function");
+	      success = false;
+	    }
+	}
+      else
+	{
+	  fcn = symbol_table::find_function (nm);
+
+	  if (! fcn.is_function ())
+	    {
+	      error ("function handle points to non-existent function");
+	      success = false;
+	    }
+	}
+    }
+
+  return success;
+}
+
+bool
+octave_fcn_handle::save_ascii (std::ostream& os)
+{
+  if (nm == "@<anonymous>")
+    {
+      os << nm << "\n";
+
+      print_raw (os, true);
+      os << "\n";
+
+      if (fcn.is_undefined ())
+	return false;
+
+      octave_user_function *f = fcn.user_function_value ();
+
+      std::list<symbol_table::symbol_record> vars
+	= symbol_table::all_variables (f->scope (), 0);
+
+      size_t varlen = vars.size ();
+
+      if (varlen > 0)
+	{
+	  os << "# length: " << varlen << "\n";
+
+	  for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
+	       p != vars.end (); p++)
+	    {
+	      if (! save_ascii_data (os, p->varval (), p->name (), false, 0))
+		return os;
+	    }
+	}
+    }
+  else
+    {
+      octave_function *f = function_value ();
+      std::string fnm = f ? f->fcn_file_name () : std::string ();
+
+      os << "# octaveroot: " << OCTAVE_EXEC_PREFIX << "\n";
+      if (! fnm.empty ())
+	os << "# path: " << fnm << "\n";
+      os << nm << "\n";
+    }
+
+  return true;
+}
+
+bool
+octave_fcn_handle::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  std::streampos pos = is.tellg ();
+  std::string octaveroot = extract_keyword (is, "octaveroot", true);
+  if (octaveroot.length() == 0)
+    {
+      is.seekg (pos);
+      is.clear ();
+    }
+  pos = is.tellg ();
+  std::string fpath = extract_keyword (is, "path", true);
+  if (fpath.length() == 0)
+    {
+      is.seekg (pos);
+      is.clear ();
+    }
+
+  is >> nm;
+
+  if (nm == "@<anonymous>")
+    {
+      skip_preceeding_newline (is);
+
+      std::string buf;
+
+      if (is)
+	{
+
+	  // Get a line of text whitespace characters included, leaving
+	  // newline in the stream.
+	  buf = read_until_newline (is, true);
+
+	}
+
+      pos = is.tellg ();
+
+      unwind_protect::begin_frame ("anon_ascii_load");
+
+      // Set up temporary scope to use for evaluating the text that
+      // defines the anonymous function.
+
+      symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
+      unwind_protect::add (symbol_table::erase_scope, &local_scope);
+
+      symbol_table::set_scope (local_scope);
+
+      octave_call_stack::push (local_scope, 0);
+      unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+      octave_idx_type len = 0;
+
+      if (extract_keyword (is, "length", len, true) && len >= 0)
+	{
+	  if (len > 0)
+	    {
+	      for (octave_idx_type i = 0; i < len; i++)
+		{
+		  octave_value t2;
+		  bool dummy;
+
+		  std::string name
+		    = read_ascii_data (is, std::string (), dummy, t2, i);
+
+		  if (!is)
+		    {
+		      error ("load: failed to load anonymous function handle");
+		      break;
+		    }
+
+		  symbol_table::varref (name, local_scope, 0) = t2;
+		}
+	    }
+	}
+      else
+	{
+	  is.seekg (pos);
+	  is.clear ();
+	}
+
+      if (is && success)
+	{
+	  int parse_status;
+	  octave_value anon_fcn_handle = 
+	    eval_string (buf, true, parse_status);
+
+	  if (parse_status == 0)
+	    {
+	      octave_fcn_handle *fh = 
+		anon_fcn_handle.fcn_handle_value ();
+
+	      if (fh)
+		{
+		  fcn = fh->fcn;
+
+		  octave_user_function *uf = fcn.user_function_value (true);
+
+		  if (uf)
+		    symbol_table::cache_name (uf->scope (), nm);
+		}
+	      else
+		success = false;
+	    }
+	  else
+	    success = false;
+	}
+      else
+	success = false;
+
+      unwind_protect::run_frame ("anon_ascii_load");
+    }
+  else
+    success = set_fcn (octaveroot, fpath);
+
+  return success;
+}
+
+bool
+octave_fcn_handle::save_binary (std::ostream& os, bool& save_as_floats)
+{
+  if (nm == "@<anonymous>")
+    {
+      std::ostringstream nmbuf;
+
+      if (fcn.is_undefined ())
+	return false;
+
+      octave_user_function *f = fcn.user_function_value ();
+
+      std::list<symbol_table::symbol_record> vars
+	= symbol_table::all_variables (f->scope (), 0);
+
+      size_t varlen = vars.size ();
+
+      if (varlen > 0)
+	nmbuf << nm << " " << varlen;
+      else
+	nmbuf << nm;
+
+      std::string buf_str = nmbuf.str();
+      int32_t tmp = buf_str.length ();
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+      os.write (buf_str.c_str (), buf_str.length ());
+
+      std::ostringstream buf;
+      print_raw (buf, true);
+      std::string stmp = buf.str ();
+      tmp = stmp.length ();
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+      os.write (stmp.c_str (), stmp.length ());
+
+      if (varlen > 0)
+	{
+	  for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
+	       p != vars.end (); p++)
+	    {
+	      if (! save_binary_data (os, p->varval (), p->name (),
+				      "", 0, save_as_floats))
+		return os;
+	    }
+	}
+    }
+  else
+    {
+      std::ostringstream nmbuf;
+
+      octave_function *f = function_value ();
+      std::string fnm = f ? f->fcn_file_name () : std::string ();
+
+      nmbuf << nm << "\n" << OCTAVE_EXEC_PREFIX << "\n" << fnm;
+
+      std::string buf_str = nmbuf.str ();
+      int32_t tmp = buf_str.length ();
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+      os.write (buf_str.c_str (), buf_str.length ());
+    }
+
+  return true;
+}
+
+bool
+octave_fcn_handle::load_binary (std::istream& is, bool swap,
+				oct_mach_info::float_format fmt)
+{
+  bool success = true;
+
+  int32_t tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&tmp);
+
+  OCTAVE_LOCAL_BUFFER (char, ctmp1, tmp+1);
+  is.get (ctmp1, tmp+1, 0);
+  nm = std::string (ctmp1);
+
+  if (! is)
+    return false;
+
+  if (nm.length() >= 12 && nm.substr (0, 12) == "@<anonymous>")
+    {
+      octave_idx_type len = 0;
+
+      if (nm.length() > 12)
+	{
+	  std::istringstream nm_is (nm.substr(12));
+	  nm_is >> len;
+	  nm = nm.substr(0,12);
+	}
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+
+      OCTAVE_LOCAL_BUFFER (char, ctmp2, tmp+1);
+      is.get (ctmp2, tmp+1, 0);
+
+      unwind_protect::begin_frame ("anon_binary_load");
+
+      // Set up temporary scope to use for evaluating the text that
+      // defines the anonymous function.
+
+      symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
+      unwind_protect::add (symbol_table::erase_scope, &local_scope);	      
+
+      symbol_table::set_scope (local_scope);
+
+      octave_call_stack::push (local_scope, 0);
+      unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+      if (len > 0)
+	{
+	  for (octave_idx_type i = 0; i < len; i++)
+	    {
+	      octave_value t2;
+	      bool dummy;
+	      std::string doc;
+
+	      std::string name = 
+		read_binary_data (is, swap, fmt, std::string (), 
+				  dummy, t2, doc);
+
+	      if (!is)
+		{
+		  error ("load: failed to load anonymous function handle");
+		  break;
+		}
+
+	      symbol_table::varref (name, local_scope) = t2;
+	    }
+	}
+
+      if (is && success)
+	{
+	  int parse_status;
+	  octave_value anon_fcn_handle = 
+	    eval_string (ctmp2, true, parse_status);
+
+	  if (parse_status == 0)
+	    {
+	      octave_fcn_handle *fh = anon_fcn_handle.fcn_handle_value ();
+
+	      if (fh)
+		{
+		  fcn = fh->fcn;
+
+		  octave_user_function *uf = fcn.user_function_value (true);
+
+		  if (uf)
+		    symbol_table::cache_name (uf->scope (), nm);
+		}
+	      else
+		success = false;
+	    }
+	  else
+	    success = false;
+	}
+
+      unwind_protect::run_frame ("anon_binary_load");
+    }
+  else
+    {
+      std::string octaveroot;
+      std::string fpath;
+
+      if (nm.find_first_of ("\n") != std::string::npos)
+	{
+	  size_t pos1 = nm.find_first_of ("\n");
+	  size_t pos2 = nm.find_first_of ("\n", pos1 + 1);
+	  octaveroot = nm.substr (pos1 + 1, pos2 - pos1 - 1);
+	  fpath = nm.substr (pos2 + 1);
+	  nm = nm.substr (0, pos1);
+	}
+
+      success = set_fcn (octaveroot, fpath);
+     }
+ 
+ return success;
+}
+
+#if defined (HAVE_HDF5)
+bool
+octave_fcn_handle::save_hdf5 (hid_t loc_id, const char *name,
+			      bool save_as_floats)
+{
+  bool retval = true;
+
+  hid_t group_hid = -1;
+  group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0)
+    return false;
+
+  hid_t space_hid = -1, data_hid = -1, type_hid = -1;;
+
+  // attach the type of the variable
+  type_hid = H5Tcopy (H5T_C_S1);
+  H5Tset_size (type_hid, nm.length () + 1);
+  if (type_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, 2);
+  hdims[0] = 0;
+  hdims[1] = 0;
+  space_hid = H5Screate_simple (0 , hdims, 0);
+  if (space_hid < 0)
+    {
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "nm",  type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL,
+				H5P_DEFAULT, nm.c_str ()) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Dclose (data_hid);
+
+  if (nm == "@<anonymous>")
+    {
+      std::ostringstream buf;
+      print_raw (buf, true);
+      std::string stmp = buf.str ();
+
+      // attach the type of the variable
+      H5Tset_size (type_hid, stmp.length () + 1);
+      if (type_hid < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      data_hid = H5Dcreate (group_hid, "fcn",  type_hid, space_hid,
+			    H5P_DEFAULT);
+      if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL,
+				    H5P_DEFAULT, stmp.c_str ()) < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Dclose (data_hid);
+
+      octave_user_function *f = fcn.user_function_value ();
+
+      std::list<symbol_table::symbol_record> vars
+	= symbol_table::all_variables (f->scope (), 0);
+
+      size_t varlen = vars.size ();
+
+      if (varlen > 0)
+	{
+	  hid_t as_id = H5Screate (H5S_SCALAR);
+
+	  if (as_id >= 0)
+	    {
+	      hid_t a_id = H5Acreate (group_hid, "SYMBOL_TABLE",
+				      H5T_NATIVE_IDX, as_id, H5P_DEFAULT);
+
+	      if (a_id >= 0)
+		{
+		  retval = (H5Awrite (a_id, H5T_NATIVE_IDX, &varlen) >= 0);
+
+		  H5Aclose (a_id);
+		}
+	      else
+		retval = false;
+
+	      H5Sclose (as_id);
+	    }
+	  else
+	    retval = false;
+
+	  data_hid = H5Gcreate (group_hid, "symbol table", 0);
+	  if (data_hid < 0) 
+	    {
+	      H5Sclose (space_hid);
+	      H5Tclose (type_hid);
+	      H5Gclose (group_hid);
+	      return false;
+	    }
+
+	  for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
+	       p != vars.end (); p++)
+	    {
+	      if (! add_hdf5_data (data_hid, p->varval (), p->name (),
+				   "", false, save_as_floats))
+		break;
+	    }
+	  H5Gclose (data_hid);
+	}
+    }
+  else
+    {
+      std::string octaveroot = OCTAVE_EXEC_PREFIX;
+
+      octave_function *f = function_value ();
+      std::string fpath = f ? f->fcn_file_name () : std::string ();
+
+      H5Sclose (space_hid);
+      hdims[0] = 1;
+      hdims[1] = octaveroot.length ();
+      space_hid = H5Screate_simple (0 , hdims, 0);
+      if (space_hid < 0)
+	{
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Tclose (type_hid);
+      type_hid = H5Tcopy (H5T_C_S1);
+      H5Tset_size (type_hid, octaveroot.length () + 1);
+
+      hid_t a_id = H5Acreate (group_hid, "OCTAVEROOT",
+			      type_hid, space_hid, H5P_DEFAULT);
+
+      if (a_id >= 0)
+	{
+	  retval = (H5Awrite (a_id, type_hid, octaveroot.c_str ()) >= 0);
+
+	  H5Aclose (a_id);
+	}
+      else
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Sclose (space_hid);
+      hdims[0] = 1;
+      hdims[1] = fpath.length ();
+      space_hid = H5Screate_simple (0 , hdims, 0);
+      if (space_hid < 0)
+	{
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Tclose (type_hid);
+      type_hid = H5Tcopy (H5T_C_S1);
+      H5Tset_size (type_hid, fpath.length () + 1);
+
+      a_id = H5Acreate (group_hid, "FILE", type_hid, space_hid, H5P_DEFAULT);
+
+      if (a_id >= 0)
+	{
+	  retval = (H5Awrite (a_id, type_hid, fpath.c_str ()) >= 0);
+
+	  H5Aclose (a_id);
+	}
+      else
+	retval = false;
+    }
+
+  H5Sclose (space_hid);
+  H5Tclose (type_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+bool
+octave_fcn_handle::load_hdf5 (hid_t loc_id, const char *name,
+			      bool have_h5giterate_bug)
+{
+  bool success = true;
+
+  hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
+  hsize_t rank;
+  int slen;
+
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0)
+    return false;
+
+  data_hid = H5Dopen (group_hid, "nm");
+
+  if (data_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  type_hid = H5Dget_type (data_hid);
+  type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid != H5T_STRING)
+    {
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  slen = H5Tget_size (type_hid);
+  if (slen < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, nm_tmp, slen);
+
+  // create datatype for (null-terminated) string to read into:
+  st_id = H5Tcopy (H5T_C_S1);
+  H5Tset_size (st_id, slen);
+
+  if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, nm_tmp) < 0)
+    {
+      H5Tclose (st_id);
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Tclose (st_id);
+  H5Dclose (data_hid);
+  nm = nm_tmp;
+
+  if (nm == "@<anonymous>")
+    {
+      data_hid = H5Dopen (group_hid, "fcn");
+
+      if (data_hid < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Tclose (type_hid);
+      type_hid = H5Dget_type (data_hid);
+      type_class_hid = H5Tget_class (type_hid);
+
+      if (type_class_hid != H5T_STRING)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Sclose (space_hid);
+      space_hid = H5Dget_space (data_hid);
+      rank = H5Sget_simple_extent_ndims (space_hid);
+
+      if (rank != 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      slen = H5Tget_size (type_hid);
+      if (slen < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      OCTAVE_LOCAL_BUFFER (char, fcn_tmp, slen);
+
+      // create datatype for (null-terminated) string to read into:
+      st_id = H5Tcopy (H5T_C_S1);
+      H5Tset_size (st_id, slen);
+
+      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, fcn_tmp) < 0)
+	{
+	  H5Tclose (st_id);
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+      H5Tclose (st_id);
+      H5Dclose (data_hid);
+
+      octave_idx_type len = 0;
+
+      // we have to pull some shenanigans here to make sure
+      // HDF5 doesn't print out all sorts of error messages if we
+      // call H5Aopen for a non-existing attribute
+
+      H5E_auto_t err_func;
+      void *err_func_data;
+
+      // turn off error reporting temporarily, but save the error
+      // reporting function:
+      H5Eget_auto (&err_func, &err_func_data);
+      H5Eset_auto (0, 0);
+
+      hid_t attr_id = H5Aopen_name (group_hid, "SYMBOL_TABLE");
+
+      if (attr_id >= 0)
+	{
+	  if (H5Aread (attr_id, H5T_NATIVE_IDX, &len) < 0)
+	    success = false;
+
+	  H5Aclose (attr_id);
+	}
+
+      // restore error reporting:
+      H5Eset_auto (err_func, err_func_data);
+
+      unwind_protect::begin_frame ("anon_hdf5_load");
+
+      // Set up temporary scope to use for evaluating the text that
+      // defines the anonymous function.
+
+      symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
+      unwind_protect::add (symbol_table::erase_scope, &local_scope);
+
+      symbol_table::set_scope (local_scope);
+
+      octave_call_stack::push (local_scope, 0);
+      unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+      if (len > 0 && success)
+	{
+#ifdef HAVE_H5GGET_NUM_OBJS
+	  hsize_t num_obj = 0;
+	  data_hid = H5Gopen (group_hid, "symbol table"); 
+	  H5Gget_num_objs (data_hid, &num_obj);
+	  H5Gclose (data_hid);
+
+	  if (num_obj != static_cast<hsize_t>(len))
+	    {
+	      error ("load: failed to load anonymous function handle");
+	      success = false;
+	    }
+#endif
+
+	  if (! error_state)
+	    {
+	      hdf5_callback_data dsub;
+	      int current_item = 0;
+	      for (octave_idx_type i = 0; i < len; i++)
+		{
+		  if (H5Giterate (group_hid, "symbol table", &current_item,
+				  hdf5_read_next_data, &dsub) <= 0)
+		    {
+		      error ("load: failed to load anonymous function handle");
+		      success = false;
+		      break;
+		    }
+
+		  if (have_h5giterate_bug)
+		    current_item++;  // H5Giterate returns last index processed
+
+		  symbol_table::varref (dsub.name, local_scope) = dsub.tc;
+		}
+	    }
+	}
+
+      if (success)
+	{
+	  int parse_status;
+	  octave_value anon_fcn_handle = 
+	    eval_string (fcn_tmp, true, parse_status);
+
+	  if (parse_status == 0)
+	    {
+	      octave_fcn_handle *fh = anon_fcn_handle.fcn_handle_value ();
+
+	      if (fh)
+		{
+		  fcn = fh->fcn;
+
+		  octave_user_function *uf = fcn.user_function_value (true);
+
+		  if (uf)
+		    symbol_table::cache_name (uf->scope (), nm);
+		}
+	      else
+		success = false;
+	    }
+	  else
+	    success = false;
+	}
+
+      unwind_protect::run_frame ("anon_hdf5_load");
+    }
+  else
+    {
+      std::string octaveroot;
+      std::string fpath;
+
+      // we have to pull some shenanigans here to make sure
+      // HDF5 doesn't print out all sorts of error messages if we
+      // call H5Aopen for a non-existing attribute
+
+      H5E_auto_t err_func;
+      void *err_func_data;
+
+      // turn off error reporting temporarily, but save the error
+      // reporting function:
+      H5Eget_auto (&err_func, &err_func_data);
+      H5Eset_auto (0, 0);
+
+      hid_t attr_id = H5Aopen_name (group_hid, "OCTAVEROOT");
+      if (attr_id >= 0)
+	{
+	  H5Tclose (type_hid);
+	  type_hid = H5Aget_type (attr_id);
+	  type_class_hid = H5Tget_class (type_hid);
+
+	  if (type_class_hid != H5T_STRING)
+	    success = false;
+	  else
+	    {
+	      slen = H5Tget_size (type_hid);
+	      st_id = H5Tcopy (H5T_C_S1);
+	      H5Tset_size (st_id, slen);
+	      OCTAVE_LOCAL_BUFFER (char, root_tmp, slen);
+
+	      if (H5Aread (attr_id, st_id, root_tmp) < 0)
+		success = false;
+	      else
+		octaveroot = root_tmp;
+
+	      H5Tclose (st_id);
+	    }
+
+	  H5Aclose (attr_id);
+	}
+
+      if (success)
+	{
+	  attr_id = H5Aopen_name (group_hid, "FILE");
+	  if (attr_id >= 0)
+	    {
+	      H5Tclose (type_hid);
+	      type_hid = H5Aget_type (attr_id);
+	      type_class_hid = H5Tget_class (type_hid);
+
+	      if (type_class_hid != H5T_STRING)
+		success = false;
+	      else
+		{
+		  slen = H5Tget_size (type_hid);
+		  st_id = H5Tcopy (H5T_C_S1);
+		  H5Tset_size (st_id, slen);
+		  OCTAVE_LOCAL_BUFFER (char, path_tmp, slen);
+
+		  if (H5Aread (attr_id, st_id, path_tmp) < 0)
+		    success = false;
+		  else
+		    fpath = path_tmp;
+
+		  H5Tclose (st_id);
+		}
+
+	      H5Aclose (attr_id);
+	    }
+	}
+
+      // restore error reporting:
+      H5Eset_auto (err_func, err_func_data);
+
+      success = (success ? set_fcn (octaveroot, fpath) : success);
+    }
+
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+  H5Gclose (group_hid);
+
+  return success;
+}
+
+#endif
+
+/* 
+
+%!test
+%! a = 2;
+%! f = @(x) a + x;
+%! g = @(x) 2 * x;
+%! hm = @flops;
+%! hdld = @svd;
+%! hbi = @log2;
+%! f2 = f;
+%! g2 = g;
+%! hm2 = hm;
+%! hdld2 = hdld;
+%! hbi2 = hbi;
+%! modes = {"-text", "-binary"};
+%! if (!isempty(findstr(octave_config_info ("DEFS"),"HAVE_HDF5")))
+%!   modes(end+1) = "-hdf5";
+%! endif
+%! for i = 1:numel (modes)
+%!   mode = modes{i};
+%!   nm = tmpnam();
+%!   unwind_protect
+%!     save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2");
+%!     clear f2 g2 hm2 hdld2 hbi2
+%!     load (nm);
+%!     assert (f(2),f2(2));
+%!     assert (g(2),g2(2));
+%!     assert (g(3),g2(3));
+%!     unlink (nm);
+%!     save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2");
+%!   unwind_protect_cleanup
+%!     unlink (nm);
+%!   end_unwind_protect
+%! endfor
+
+*/
+
+void
+octave_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+void
+octave_fcn_handle::print_raw (std::ostream& os, bool pr_as_read_syntax) const
+{
+  bool printed = false;
+
+  if (nm == "@<anonymous>")
+    {
+      tree_print_code tpc (os);
+
+      // FCN is const because this member function is, so we can't
+      // use it to call user_function_value, so we make a copy first.
+
+      octave_value ftmp = fcn;
+
+      octave_user_function *f = ftmp.user_function_value ();
+
+      if (f)
+	{
+	  tree_parameter_list *p = f->parameter_list ();
+
+	  os << "@(";
+
+	  if (p)
+	    p->accept (tpc);
+
+	  os << ") ";
+
+	  tree_statement_list *b = f->body ();
+
+	  if (b)
+	    {
+	      assert (b->length () == 1);
+
+	      tree_statement *s = b->front ();
+
+	      if (s)
+		{
+		  if (s->is_expression ())
+		    {
+		      tree_expression *e = s->expression ();
+
+		      if (e)
+			e->accept (tpc);
+		    }
+		  else
+		    {
+		      tree_command *c = s->command ();
+
+		      tpc.suspend_newline ();
+		      c->accept (tpc);
+		      tpc.resume_newline ();
+		    }
+		}
+	    }
+
+	  printed = true;
+	}
+    }
+
+  if (! printed)
+    octave_print_internal (os, nm, pr_as_read_syntax,
+			   current_print_indent_level ());
+}
+
+octave_value
+make_fcn_handle (const std::string& nm)
+{
+  octave_value retval;
+
+  octave_value f = symbol_table::find_function (nm);
+
+  if (f.is_defined ())
+    retval = octave_value (new octave_fcn_handle (f, nm));
+  else
+    error ("error creating function handle \"@%s\"", nm.c_str ());
+
+  return retval;
+}
+
+DEFUN (functions, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} functions (@var{fcn_handle})\n\
+Return a struct containing information about the function handle\n\
+ at var{fcn_handle}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      octave_fcn_handle *fh = args(0).fcn_handle_value ();
+
+      if (! error_state)
+	{
+	  octave_function *fcn = fh ? fh->function_value () : 0;
+
+	  if (fcn)
+	    {
+	      Octave_map m;
+
+	      std::string fh_nm = fh->fcn_name ();
+
+	      if (fh_nm == "@<anonymous>")
+		{
+		  std::ostringstream buf;
+		  fh->print_raw (buf);
+		  m.assign ("function", buf.str ());
+
+		  m.assign ("type", "anonymous");
+		}
+	      else
+		{
+		  m.assign ("function", fh_nm);
+
+		  if (fcn->is_nested_function ())
+		    {
+		      m.assign ("type", "subfunction");
+		      Cell parentage (dim_vector (1, 2));
+		      parentage.elem(0) = fh_nm;
+		      parentage.elem(1) = fcn->parent_fcn_name ();
+		      m.assign ("parentage", octave_value (parentage)); 
+		    }
+		  else
+		    m.assign ("type", "simple");
+		}
+
+	      std::string nm = fcn->fcn_file_name ();
+
+	      if (fh_nm == "@<anonymous>")
+		{
+		  m.assign ("file", nm);
+
+		  octave_user_function *fu = fh->user_function_value ();
+
+		  std::list<symbol_table::symbol_record> vars
+		    = symbol_table::all_variables (fu->scope (), 0);
+
+		  size_t varlen = vars.size ();
+
+		  if (varlen > 0)
+		    {
+		      Octave_map ws;
+		      for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
+			   p != vars.end (); p++)
+			{
+			  ws.assign (p->name (), p->varval (0));
+			}
+
+		      m.assign ("workspace", ws);
+		    }
+		}
+	      else if (fcn->is_user_function () || fcn->is_user_script ())
+		{
+		  octave_function *fu = fh->function_value ();
+		  m.assign ("file", fu->fcn_file_name ());
+		}
+	      else
+		m.assign ("file", "");
+
+	      retval = m;
+	    }
+	  else
+	    error ("functions: invalid function handle object");
+	}
+      else
+	error ("functions: argument must be a function handle object");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (func2str, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} func2str (@var{fcn_handle})\n\
+Return a string containing the name of the function referenced by\n\
+the function handle @var{fcn_handle}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      octave_fcn_handle *fh = args(0).fcn_handle_value ();
+
+      if (! error_state && fh)
+	{
+	  std::string fh_nm = fh->fcn_name ();
+
+	  if (fh_nm == "@<anonymous>")
+	    {
+	      std::ostringstream buf;
+
+	      fh->print_raw (buf);
+
+	      retval = buf.str ();
+	    }
+	  else
+	    retval = fh_nm;
+	}
+      else
+	error ("func2str: expecting valid function handle as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (str2func, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} str2func (@var{fcn_name})\n\
+Return a function handle constructed from the string @var{fcn_name}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      std::string nm = args(0).string_value ();
+
+      if (! error_state)
+	retval = make_fcn_handle (nm);
+      else
+	error ("str2func: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!function y = testrecursionfunc (f, x, n)
+%!  if (nargin < 3)
+%!    n = 0;
+%!  endif
+%!  if (n > 2)
+%!    y = f (x);
+%!  else
+%!    n++;
+%!    y = testrecursionfunc (@(x) f(2*x), x, n);
+%!  endif
+%!test
+%! assert (testrecursionfunc (@(x) x, 1), 8);
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-fcn-handle.h b/src/ov-fcn-handle.h
new file mode 100644
index 0000000..cdcde05
--- /dev/null
+++ b/src/ov-fcn-handle.h
@@ -0,0 +1,141 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_fcn_handle_h)
+#define octave_fcn_handle_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "oct-alloc.h"
+
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-fcn.h"
+#include "ov-typeinfo.h"
+
+// Function handles.
+
+class
+OCTINTERP_API
+octave_fcn_handle : public octave_base_value
+{
+public:
+  octave_fcn_handle (void)
+    : warn_reload (true), fcn (), nm () { }
+
+  octave_fcn_handle (const std::string& n)
+    : warn_reload (true), fcn (), nm (n) { }
+
+  octave_fcn_handle (const octave_value& f,  const std::string& n);
+
+  octave_fcn_handle (const octave_fcn_handle& fh)
+    : octave_base_value (fh), warn_reload (fh.warn_reload),
+      fcn (fh.fcn), nm (fh.nm) { }
+
+  ~octave_fcn_handle (void) { }
+
+  octave_base_value *clone (void) const { return new octave_fcn_handle (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_fcn_handle (); }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  bool is_defined (void) const { return true; }
+
+  bool is_function_handle (void) const { return true; }
+
+  dim_vector dims (void) const { static dim_vector dv (1, 1); return dv; }
+
+  octave_function *function_value (bool = false)
+    { return fcn.function_value (); }
+
+  const octave_function *function_value (bool = false) const
+    { return fcn.function_value (); }
+
+  octave_user_function *user_function_value (bool = false)
+    { return fcn.user_function_value (); }
+
+  octave_fcn_handle *fcn_handle_value (bool = false) { return this; }
+
+  octave_value fcn_val (void) const { return fcn; }
+
+  std::string fcn_name (void) const { return nm; }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+private:
+
+  bool set_fcn (const std::string &octaveroot, const std::string& fpath);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+
+  // If TRUE, print a warning if the pointed-to fucntion is out of
+  // date.  This variable may be removed when updating is properly
+  // implemented.
+  mutable bool warn_reload;
+
+protected:
+
+  // The function we are handling.
+  octave_value fcn;
+
+  // The name of the handle, including the "@".
+  std::string nm;
+};
+
+extern octave_value make_fcn_handle (const std::string& nm);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-fcn-inline.cc b/src/ov-fcn-inline.cc
new file mode 100644
index 0000000..e76409c
--- /dev/null
+++ b/src/ov-fcn-inline.cc
@@ -0,0 +1,912 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+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 <istream>
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "ov-base.h"
+#include "ov-fcn-inline.h"
+#include "ov-usr-fcn.h"
+#include "pr-output.h"
+#include "variables.h"
+#include "parse.h"
+#include "toplev.h"
+
+#include "byte-swap.h"
+#include "ls-ascii-helper.h"
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_fcn_inline);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_inline,
+				     "inline function",
+				     "function_handle");
+
+octave_fcn_inline::octave_fcn_inline (const std::string& f,
+				      const string_vector& a,
+				      const std::string& n)
+  : octave_fcn_handle (n), iftext (f), ifargs (a)
+{
+  // Form a string representing the function.
+
+  std::ostringstream buf;
+
+  buf << "@(";
+
+  for (int i = 0; i < ifargs.length (); i++)
+    {
+      if (i > 0)
+	buf << ", ";
+
+      buf << ifargs(i);
+    }
+
+  buf << ") " << iftext;
+
+  int parse_status;
+  octave_value anon_fcn_handle = eval_string (buf.str (), true, parse_status);
+
+  if (parse_status == 0)
+    {
+      octave_fcn_handle *fh = anon_fcn_handle.fcn_handle_value ();
+
+      if (fh)
+	{
+	  fcn = fh->fcn_val ();
+
+	  octave_user_function *uf = fcn.user_function_value ();
+
+	  if (uf)
+	    {
+	      octave_function *curr_fcn = octave_call_stack::current ();
+
+	      if (curr_fcn)
+		{
+		  symbol_table::scope_id parent_scope
+		    = curr_fcn->parent_fcn_scope ();
+
+		  if (parent_scope < 0)
+		    parent_scope = curr_fcn->scope ();
+	
+		  uf->stash_parent_fcn_scope (parent_scope);
+		}
+	    }
+	}
+    }
+
+  if (fcn.is_undefined ())
+    error ("inline: unable to define function");
+}
+
+// This function is supplied to allow a Matlab style class structure
+// to be returned..
+Octave_map
+octave_fcn_inline::map_value (void) const
+{
+  Octave_map m;
+  string_vector args = fcn_arg_names ();
+  m.assign ("version", octave_value (1.0));
+  m.assign ("isEmpty", octave_value (0.0));
+  m.assign ("expr", octave_value (fcn_text ()));
+  m.assign ("numArgs", octave_value (args.length ()));
+  m.assign ("args", octave_value (args));
+  std::ostringstream buf;
+  for (int i = 0; i < args.length (); i++)
+    buf << args(i) << " = INLINE_INPUTS_{" << i + 1 << "}; ";
+  m.assign ("inputExpr", octave_value (buf.str ()));
+
+  return m;
+}
+
+bool
+octave_fcn_inline::save_ascii (std::ostream& os)
+{
+  os << "# nargs: " <<  ifargs.length () << "\n";
+  for (int i = 0; i < ifargs.length (); i++)
+    os << ifargs(i) << "\n";
+  if (nm.length () < 1)
+    // Write an invalid value to flag empty fcn handle name.
+    os << "0\n";
+  else
+    os << nm << "\n";
+  os << iftext << "\n";
+  return true;
+}
+
+bool
+octave_fcn_inline::load_ascii (std::istream& is)
+{
+  int nargs;
+  if (extract_keyword (is, "nargs", nargs, true))
+    {
+      ifargs.resize (nargs);
+      for (int i = 0; i < nargs; i++)
+	is >> ifargs(i);
+      is >> nm;
+      if (nm == "0")
+	nm = "";
+
+      skip_preceeding_newline (is);
+
+      std::string buf;
+
+      if (is)
+	{
+
+	  // Get a line of text whitespace characters included,
+	  // leaving newline in the stream.
+	  buf = read_until_newline (is, true);
+	}
+
+      iftext = buf;
+
+      octave_fcn_inline tmp (iftext, ifargs, nm);
+      fcn = tmp.fcn;
+
+      return true;
+    }
+  else
+    return false;
+}
+
+bool
+octave_fcn_inline::save_binary (std::ostream& os, bool&)
+{
+  int32_t tmp = ifargs.length ();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i = 0; i < ifargs.length (); i++)
+    {
+      tmp = ifargs(i).length ();
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+      os.write (ifargs(i).c_str (), ifargs(i).length ());
+    }
+  tmp = nm.length ();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  os.write (nm.c_str (), nm.length ());
+  tmp = iftext.length ();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  os.write (iftext.c_str (), iftext.length ());
+  return true;
+}
+
+bool
+octave_fcn_inline::load_binary (std::istream& is, bool swap,
+				oct_mach_info::float_format)
+{
+  int32_t nargs;
+  if (! is.read (reinterpret_cast<char *> (&nargs), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&nargs);
+
+  if (nargs < 1)
+    return false;
+  else
+    {
+      int32_t tmp;
+      ifargs.resize (nargs);
+      for (int i = 0; i < nargs; i++)
+	{
+	  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&tmp);
+
+	  OCTAVE_LOCAL_BUFFER (char, ctmp, tmp+1);
+	  is.read (ctmp, tmp);
+	  ifargs(i) = std::string (ctmp);
+
+	  if (! is)
+	    return false;
+	}
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+
+      OCTAVE_LOCAL_BUFFER (char, ctmp1, tmp+1);
+      is.read (ctmp1, tmp);
+      nm = std::string (ctmp1);
+
+      if (! is)
+	return false;
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+
+      OCTAVE_LOCAL_BUFFER (char, ctmp2, tmp+1);
+      is.read (ctmp2, tmp);
+      iftext = std::string (ctmp2);
+
+      if (! is)
+	return false;
+
+      octave_fcn_inline ftmp (iftext, ifargs, nm);
+      fcn = ftmp.fcn;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+bool
+octave_fcn_inline::save_hdf5 (hid_t loc_id, const char *name,
+			      bool /* save_as_floats */)
+{
+  hid_t group_hid = -1;
+  group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0 ) return false;
+
+  size_t len = 0;
+  for (int i = 0; i < ifargs.length (); i++)
+    if (len < ifargs(i).length ())
+      len = ifargs(i).length ();
+
+  hid_t space_hid = -1, data_hid = -1, type_hid = -1;;
+  bool retval = true;
+
+  // FIXME Is there a better way of saving string vectors, than a
+  // null padded matrix?
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, 2);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  hdims[1] = ifargs.length ();
+  hdims[0] = len + 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+  if (space_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "args", H5T_NATIVE_CHAR, space_hid,
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, s, ifargs.length () * (len + 1));
+
+  // Save the args as a null teminated list
+  for (int i = 0; i < ifargs.length (); i++)
+    {
+      const char * cptr = ifargs(i).c_str ();
+      for (size_t j = 0; j < ifargs(i).length (); j++)
+	s[i*(len+1)+j] = *cptr++;
+      s[ifargs(i).length ()] = '\0';
+    }
+
+  retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, s) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  if (!retval)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  // attach the type of the variable
+  type_hid = H5Tcopy (H5T_C_S1);
+  H5Tset_size (type_hid, nm.length () + 1);
+  if (type_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  hdims[0] = 0;
+  space_hid = H5Screate_simple (0 , hdims, 0);
+  if (space_hid < 0)
+    {
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "nm",  type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL,
+				H5P_DEFAULT, nm.c_str ()) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Dclose (data_hid);
+
+  // attach the type of the variable
+  H5Tset_size (type_hid, iftext.length () + 1);
+  if (type_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "iftext",  type_hid, space_hid,
+			H5P_DEFAULT);
+  if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL,
+				H5P_DEFAULT, iftext.c_str ()) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+  H5Tclose (type_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+bool
+octave_fcn_inline::load_hdf5 (hid_t loc_id, const char *name,
+			      bool /* have_h5giterate_bug */)
+{
+  hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
+  hsize_t rank;
+  int slen;
+
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0 ) return false;
+
+  data_hid = H5Dopen (group_hid, "args");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Dclose (data_hid);
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  ifargs.resize (hdims[1]);
+
+  OCTAVE_LOCAL_BUFFER (char, s1, hdims[0] * hdims[1]);
+
+  if (H5Dread (data_hid, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL,
+	       H5P_DEFAULT, s1) < 0)
+    {
+      H5Dclose (data_hid);
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  for (size_t i = 0; i < hdims[1]; i++)
+    ifargs(i) = std::string (s1 + i*hdims[0]);
+
+  data_hid = H5Dopen (group_hid, "nm");
+
+  if (data_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  type_hid = H5Dget_type (data_hid);
+  type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid != H5T_STRING)
+    {
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  slen = H5Tget_size (type_hid);
+  if (slen < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, nm_tmp, slen);
+
+  // create datatype for (null-terminated) string to read into:
+  st_id = H5Tcopy (H5T_C_S1);
+  H5Tset_size (st_id, slen);
+
+  if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, nm_tmp) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Tclose (st_id);
+  H5Dclose (data_hid);
+  nm = nm_tmp;
+
+  data_hid = H5Dopen (group_hid, "iftext");
+
+  if (data_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  type_hid = H5Dget_type (data_hid);
+  type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid != H5T_STRING)
+    {
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  slen = H5Tget_size (type_hid);
+  if (slen < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, iftext_tmp, slen);
+
+  // create datatype for (null-terminated) string to read into:
+  st_id = H5Tcopy (H5T_C_S1);
+  H5Tset_size (st_id, slen);
+
+  if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, iftext_tmp) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Tclose (st_id);
+  H5Dclose (data_hid);
+  iftext = iftext_tmp;
+
+  octave_fcn_inline ftmp (iftext, ifargs, nm);
+  fcn = ftmp.fcn;
+
+  return true;
+}
+#endif
+
+void
+octave_fcn_inline::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+void
+octave_fcn_inline::print_raw (std::ostream& os, bool pr_as_read_syntax) const
+{
+  std::ostringstream buf;
+
+  if (nm.empty ())
+    buf << "f(";
+  else
+    buf << nm << "(";
+
+  for (int i = 0; i < ifargs.length (); i++)
+    {
+      if (i)
+	buf << ", ";
+
+      buf << ifargs(i);
+    }
+
+  buf << ") = " << iftext;
+
+  octave_print_internal (os, buf.str (), pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+octave_value
+octave_fcn_inline::convert_to_str_internal (bool, bool, char type) const
+{
+  return octave_value (fcn_text (), type);
+}
+
+DEFUNX ("inline", Finline, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} inline (@var{str})\n\
+ at deftypefnx {Built-in Function} {} inline (@var{str}, @var{arg1}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} inline (@var{str}, @var{n})\n\
+Create an inline function from the character string @var{str}.\n\
+If called with a single argument, the arguments of the generated\n\
+function are extracted from the function itself.  The generated\n\
+function arguments will then be in alphabetical order.  It should\n\
+be noted that i, and j are ignored as arguments due to the\n\
+ambiguity between their use as a variable or their use as an inbuilt\n\
+constant.  All arguments followed by a parenthesis are considered\n\
+to be functions.\n\
+\n\
+If the second and subsequent arguments are character strings,\n\
+they are the names of the arguments of the function.\n\
+\n\
+If the second argument is an integer @var{n}, the arguments are\n\
+ at code{\"x\"}, @code{\"P1\"}, @dots{}, @code{\"P at var{N}\"}.\n\
+ at seealso{argnames, formula, vectorize}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      std::string fun = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  string_vector fargs;
+
+	  if (nargin == 1)
+	    {
+	      bool is_arg = false;
+	      bool in_string = false;
+	      std::string tmp_arg;
+	      size_t i = 0;
+	      
+	      while (i < fun.length ())
+		{
+		  bool terminate_arg = false;
+		  char c = fun[i++];
+
+		  if (in_string)
+		    {
+		      if (c == '\'' || c == '\"')
+			in_string = false;
+		    }
+		  else if (c == '\'' || c == '\"')
+		    {
+		      in_string = true;
+		      if (is_arg)
+			terminate_arg = true;
+		    }
+		  else if (! isalpha (c) && c != '_')
+		    if (! is_arg)
+		      continue;
+		    else if (isdigit (c))
+		      tmp_arg.append (1, c);
+		    else
+		      {
+			// Before we do anything remove trailing whitespaces.
+			while (i < fun.length () && isspace (c))
+			  c = fun[i++];
+			
+			// Do we have a variable or a function?
+			if (c != '(')
+			  terminate_arg = true;
+			else
+			  {
+			    tmp_arg = std::string ();
+			    is_arg = false;
+			  }
+		      }
+		  else
+		    {
+		      tmp_arg.append (1, c);
+		      is_arg = true;
+		    }
+
+		  if (terminate_arg || (i == fun.length () && is_arg))
+		    {
+		      bool have_arg = false;
+		      
+		      for (int j = 0; j < fargs.length (); j++)
+			if (tmp_arg == fargs (j))
+			  {
+			    have_arg = true;
+			    break;
+			  }
+			  
+		      if (! have_arg && tmp_arg != "i" && tmp_arg != "j" &&
+			  tmp_arg != "NaN" && tmp_arg != "nan" && 
+			  tmp_arg != "Inf" && tmp_arg != "inf" && 
+			  tmp_arg != "NA" && tmp_arg != "pi" &&
+			  tmp_arg != "eps")
+			fargs.append (tmp_arg);
+
+		      tmp_arg = std::string ();
+		      is_arg = false;
+		    }
+		}
+
+	      // Sort the arguments into ascii order.
+	      fargs.sort ();
+	    }
+	  else if (nargin == 2 && args(1).is_numeric_type ())
+	    {
+	      int n = args(1).int_value ();
+
+	      if (! error_state)
+		{
+		  if (n >= 0)
+		    {
+		      fargs.resize (n+1);
+
+		      fargs(0) = "x";
+
+		      for (int i = 1; i < n+1; i++)
+			{
+			  std::ostringstream buf;
+			  buf << "P" << i;
+			  fargs(i) = buf.str ();
+			}
+		    }
+		  else
+		    {
+		      error ("inline: numeric argument must be nonnegative");
+		      return retval;
+		    }
+		}
+	      else
+		{
+		  error ("inline: expecting second argument to be an integer");
+		  return retval;
+		}
+	    }
+	  else
+	    {
+	      fargs.resize (nargin - 1);
+
+	      for (int i = 1; i < nargin; i++)
+		{
+		  std::string s = args(i).string_value ();
+
+		  if (! error_state)
+		    fargs(i-1) = s;
+		  else
+		    {
+		      error ("inline: expecting string arguments");
+		      return retval;
+		    }
+		}
+	    }
+
+	  retval = octave_value (new octave_fcn_inline (fun, fargs));
+	}
+      else
+	error ("inline: first argument must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!shared fn
+%! fn = inline ("x.^2 + 1","x");
+%!assert (feval (fn, 6), 37)
+%!assert (fn (6), 37)
+*/
+
+DEFUN (formula, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} formula (@var{fun})\n\
+Return a character string representing the inline function @var{fun}.\n\
+Note that @code{char (@var{fun})} is equivalent to\n\
+ at code{formula (@var{fun})}.\n\
+ at seealso{argnames, inline, vectorize}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_fcn_inline* fn = args(0).fcn_inline_value (true);
+
+      if (fn)
+	retval = octave_value (fn->fcn_text ());
+      else
+	error ("formula: must be an inline function");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (argnames, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} argnames (@var{fun})\n\
+Return a cell array of character strings containing the names of\n\
+the arguments of the inline function @var{fun}.\n\
+ at seealso{inline, formula, vectorize}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_fcn_inline *fn = args(0).fcn_inline_value (true);
+
+      if (fn)
+	{
+	  string_vector t1 = fn->fcn_arg_names ();
+
+	  Cell t2 (dim_vector (t1.length (), 1));
+
+	  for (int i = 0; i < t1.length (); i++)
+	    t2(i) = t1(i);
+
+	  retval = t2;
+	}
+      else
+	error ("argnames: argument must be an inline function");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (vectorize, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} vectorize (@var{fun})\n\
+Create a vectorized version of the inline function @var{fun}\n\
+by replacing all occurrences of @code{*}, @code{/}, etc., with\n\
+ at code{.*}, @code{./}, etc.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string old_func;
+      octave_fcn_inline* old = 0;
+      bool func_is_string = true;
+
+      if (args(0).is_string ())
+	old_func = args(0).string_value ();
+      else
+	{
+	  old = args(0).fcn_inline_value (true);
+	  func_is_string = false;
+
+	  if (old)
+	    old_func = old->fcn_text ();
+	  else
+	    error ("vectorize: must be a string or inline function");
+	}
+
+      if (! error_state)
+	{
+	  std::string new_func;
+	  size_t i = 0;
+
+	  while (i < old_func.length ())
+	    {
+	      std::string t1 = old_func.substr (i, 1);
+
+	      if (t1 == "*" || t1 == "/" || t1 == "\\" || t1 == "^")
+		{
+		  if (i && old_func.substr (i-1, 1) != ".")
+		    new_func.append (".");
+
+		  // Special case for ** operator.
+		  if (t1 == "*" && i < (old_func.length () - 1)
+		      && old_func.substr (i+1, 1) == "*")
+		    {
+		      new_func.append ("*");
+		      i++;
+		    }
+		}
+	      new_func.append (t1);
+	      i++;
+	    }
+
+	  if (func_is_string)
+	    retval = octave_value (new_func);
+	  else
+	    retval = octave_value (new octave_fcn_inline 
+				   (new_func, old->fcn_arg_names ()));
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-fcn-inline.h b/src/ov-fcn-inline.h
new file mode 100644
index 0000000..107be5f
--- /dev/null
+++ b/src/ov-fcn-inline.h
@@ -0,0 +1,111 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_fcn_inline_h)
+#define octave_fcn_inline_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "oct-alloc.h"
+
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-fcn.h"
+#include "ov-typeinfo.h"
+#include "symtab.h"
+#include "ov-fcn-handle.h"
+
+// Inline functions.
+
+class
+OCTINTERP_API
+octave_fcn_inline : public octave_fcn_handle
+{
+public:
+
+  octave_fcn_inline (void)
+    : octave_fcn_handle (), iftext (), ifargs () { }
+
+  octave_fcn_inline (const std::string& f, const string_vector& a, 
+		     const std::string& n = std::string ());
+
+  octave_fcn_inline (const octave_fcn_inline& fi)
+    : octave_fcn_handle (fi), iftext (fi.iftext), ifargs (fi.ifargs) { }
+
+  ~octave_fcn_inline (void) { }
+
+  octave_base_value *clone (void) const { return new octave_fcn_inline (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_fcn_inline (); }
+
+  bool is_inline_function (void) const { return true; }
+
+  octave_fcn_inline *fcn_inline_value (bool = false) { return this; }
+
+  std::string fcn_text (void) const { return iftext; }
+
+  string_vector fcn_arg_names (void) const { return ifargs; }
+
+  octave_value convert_to_str_internal (bool, bool, char) const;
+
+  Octave_map map_value (void) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+
+  // The expression of an inline function.
+  std::string iftext;
+
+  // The args of an inline function.
+  string_vector ifargs;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/src/ov-fcn.cc b/src/ov-fcn.cc
new file mode 100644
index 0000000..4af1a29
--- /dev/null
+++ b/src/ov-fcn.cc
@@ -0,0 +1,52 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_function);
+
+octave_base_value *
+octave_function::clone (void) const
+{
+  panic_impossible ();
+  return 0;
+}
+
+octave_base_value *
+octave_function::empty_clone (void) const
+{
+  panic_impossible ();
+  return 0;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-fcn.h b/src/ov-fcn.h
new file mode 100644
index 0000000..ffe3ee4
--- /dev/null
+++ b/src/ov-fcn.h
@@ -0,0 +1,187 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_function_h)
+#define octave_function_h 1
+
+#include <string>
+
+#include "oct-time.h"
+#include "str-vec.h"
+
+#include "oct-alloc.h"
+#include "oct-obj.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+#include "symtab.h"
+
+class tree_walker;
+
+// Functions.
+
+class
+OCTINTERP_API
+octave_function : public octave_base_value
+{
+public:
+
+  octave_function (void)
+    : relative (false), locked (false), private_function (false),
+      xdispatch_class (), my_name (), my_dir_name (), doc () { }
+
+  ~octave_function (void) { }
+
+  octave_base_value *clone (void) const;
+  octave_base_value *empty_clone (void) const;
+
+  bool is_defined (void) const { return true; }
+
+  bool is_function (void) const { return true; }
+
+  virtual bool is_system_fcn_file (void) const { return false; }
+
+  virtual std::string fcn_file_name (void) const { return std::string (); }
+
+  virtual std::string parent_fcn_name (void) const { return std::string (); }
+
+  virtual symbol_table::scope_id parent_fcn_scope (void) const { return -1; }
+
+  virtual void mark_fcn_file_up_to_date (const octave_time&) { }
+
+  virtual symbol_table::scope_id scope (void) { return -1; }
+
+  virtual octave_time time_parsed (void) const
+    { return octave_time (static_cast<time_t> (0)); }
+
+  virtual octave_time time_checked (void) const
+    { return octave_time (static_cast<time_t> (0)); }
+
+  virtual bool is_nested_function (void) const { return false; }
+
+  virtual bool is_class_constructor (void) const { return false; }
+
+  virtual bool is_class_method (void) const { return false; }
+
+  virtual bool takes_varargs (void) const { return false; }
+
+  virtual bool takes_var_return (void) const { return false; }
+
+  void stash_dispatch_class (const std::string& nm) { xdispatch_class = nm; }
+
+  std::string dispatch_class (void) const { return xdispatch_class; }
+
+  void mark_as_private_function (const std::string& cname = std::string ())
+  {
+    private_function = true;
+    xdispatch_class = cname;
+  }
+
+  bool is_private_function (void) const { return private_function; }
+
+  bool is_private_function_of_class (const std::string& nm)
+    { return private_function && xdispatch_class == nm; }
+
+  std::string dir_name (void) const { return my_dir_name; }
+
+  void stash_dir_name (const std::string& dir) { my_dir_name = dir; }
+
+  void lock (void)
+  {
+    this->lock_subfunctions ();
+    locked = true;
+  }
+
+  void unlock (void)
+  {
+    this->unlock_subfunctions ();
+    locked = false;
+  }
+
+  bool islocked (void) const { return locked; }
+
+  virtual void lock_subfunctions (void) { }
+
+  virtual void unlock_subfunctions (void) { }
+
+  void mark_relative (void) { relative = true; }
+
+  bool is_relative (void) const { return relative; }
+
+  std::string name (void) const { return my_name; }
+
+  void document (const std::string& ds) { doc = ds; }
+
+  std::string doc_string (void) const { return doc; }
+
+  virtual void unload (void) { }
+
+  virtual void accept (tree_walker&) { }
+
+protected:
+
+  octave_function (const std::string& nm,
+		   const std::string& ds = std::string ())
+    : relative (false), my_name (nm), doc (ds) { }
+
+  // TRUE if this function was found from a relative path element.
+  bool relative;
+
+  // TRUE if this function is tagged so that it can't be cleared.
+  bool locked;
+
+  // TRUE means this is a private function.
+  bool private_function;
+
+  // If this object is a class method or constructor, or a private
+  // function inside a class directory, this is the name of the class
+  // to which the method belongs. 
+  std::string xdispatch_class;
+
+  // The name of this function.
+  std::string my_name;
+
+  // The name of the directory in the path where we found this
+  // function.  May be relative.
+  std::string my_dir_name;
+
+  // The help text for this function.
+  std::string doc;
+
+private:
+
+  // No copying!
+
+  octave_function (const octave_function& f);
+
+  octave_function& operator = (const octave_function& f);
+
+  DECLARE_OCTAVE_ALLOCATOR
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-float.cc b/src/ov-float.cc
new file mode 100644
index 0000000..7e64cf1
--- /dev/null
+++ b/src/ov-float.cc
@@ -0,0 +1,321 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "data-conv.h"
+#include "mach-info.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-base.h"
+#include "ov-base-scalar.h"
+#include "ov-base-scalar.cc"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+#include "pr-output.h"
+#include "xdiv.h"
+#include "xpow.h"
+#include "ops.h"
+
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+
+template class octave_base_scalar<float>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_float_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_scalar, "float scalar", "single");
+
+octave_value
+octave_float_scalar::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // FIXME -- this doesn't solve the problem of
+  //
+  //   a = 1; a([1,1], [1,1], [1,1])
+  //
+  // and similar constructions.  Hmm...
+
+  // FIXME -- using this constructor avoids narrowing the
+  // 1x1 matrix back to a scalar value.  Need a better solution
+  // to this problem.
+
+  octave_value tmp (new octave_matrix (matrix_value ()));
+
+  return tmp.do_index_op (idx, resize_ok);
+}
+
+octave_value 
+octave_float_scalar::resize (const dim_vector& dv, bool fill) const
+{
+  if (fill)
+    {
+      FloatNDArray retval (dv, NDArray::resize_fill_value());
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+  else
+    {
+      FloatNDArray retval (dv);
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+}
+
+octave_value
+octave_float_scalar::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+
+  if (xisnan (scalar))
+    ::error ("invalid conversion from NaN to character");
+  else
+    {
+      int ival = NINT (scalar);
+
+      if (ival < 0 || ival > UCHAR_MAX)
+	{
+	  // FIXME -- is there something better we could do?
+
+	  ival = 0;
+
+	  ::warning ("range error for conversion to character value");
+	}
+
+      retval = octave_value (std::string (1, static_cast<char> (ival)), type);
+    }
+
+  return retval;
+}
+
+bool 
+octave_float_scalar::save_ascii (std::ostream& os)
+{
+  float d = float_value ();
+
+  octave_write_float (os, d);
+
+  os << "\n";
+
+  return true;
+}
+
+bool 
+octave_float_scalar::load_ascii (std::istream& is)
+{
+  scalar = octave_read_float (is);
+  if (!is)
+    {
+      error ("load: failed to load scalar constant");
+      return false;
+    }
+
+  return true;
+}
+
+bool 
+octave_float_scalar::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+  char tmp = LS_FLOAT;
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+  float dtmp = float_value ();
+  os.write (reinterpret_cast<char *> (&dtmp), 4);
+
+  return true;
+}
+
+bool 
+octave_float_scalar::load_binary (std::istream& is, bool swap,
+			    oct_mach_info::float_format fmt)
+{
+  char tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    return false;
+
+  float dtmp;
+  read_floats (is, &dtmp, static_cast<save_type> (tmp), 1, swap, fmt);
+  if (error_state || ! is)
+    return false;
+
+  scalar = dtmp;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_float_scalar::save_hdf5 (hid_t loc_id, const char *name,
+			  bool /* save_as_floats */)
+{
+  hsize_t dimens[3];
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0) return false;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_FLOAT, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  float tmp = float_value ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_float_scalar::load_hdf5 (hid_t loc_id, const char *name,
+			  bool /* have_h5giterate_bug */)
+{
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  float dtmp;
+  if (H5Dread (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &dtmp) < 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  scalar = dtmp;
+
+  H5Dclose (data_hid);
+
+  return true;
+}
+
+#endif
+
+mxArray *
+octave_float_scalar::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxSINGLE_CLASS, 1, 1, mxREAL);
+
+  float *pr = static_cast<float *> (retval->get_data ());
+
+  pr[0] = scalar;
+
+  return retval;
+}
+
+#define SCALAR_MAPPER(MAP, FCN) \
+  octave_value \
+  octave_float_scalar::MAP (void) const \
+  { \
+    return octave_value (FCN (scalar)); \
+  }
+
+#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_float_scalar::MAP (void) const \
+  { \
+    return (scalar < L1 || scalar > L2 \
+            ? octave_value (CFCN (FloatComplex (scalar))) \
+	    : octave_value (RFCN (scalar))); \
+  }
+
+static float
+xconj (float x)
+{
+  return x;
+}
+
+SCALAR_MAPPER (erf, ::erff)
+SCALAR_MAPPER (erfc, ::erfcf)
+SCALAR_MAPPER (gamma, xgamma)
+CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Float_Inf)
+SCALAR_MAPPER (abs, ::fabsf)
+CD_SCALAR_MAPPER (acos, ::acosf, ::acos, -1.0, 1.0)
+CD_SCALAR_MAPPER (acosh, ::acoshf, ::acosh, 1.0, octave_Float_Inf)
+SCALAR_MAPPER (angle, ::arg)
+SCALAR_MAPPER (arg, ::arg)
+CD_SCALAR_MAPPER (asin, ::asinf, ::asin, -1.0, 1.0)
+SCALAR_MAPPER (asinh, ::asinhf)
+SCALAR_MAPPER (atan, ::atanf)
+CD_SCALAR_MAPPER (atanh, ::atanhf, ::atanh, -1.0, 1.0)
+SCALAR_MAPPER (ceil, ::ceilf)
+SCALAR_MAPPER (conj, xconj)
+SCALAR_MAPPER (cos, ::cosf)
+SCALAR_MAPPER (cosh, ::coshf)
+SCALAR_MAPPER (exp, ::expf)
+SCALAR_MAPPER (expm1, ::expm1f)
+SCALAR_MAPPER (fix, ::fix)
+SCALAR_MAPPER (floor, ::floorf)
+SCALAR_MAPPER (imag, ::imag)
+CD_SCALAR_MAPPER (log, ::logf, std::log, 0.0, octave_Float_Inf)
+CD_SCALAR_MAPPER (log2, xlog2, xlog2, 0.0, octave_Float_Inf)
+CD_SCALAR_MAPPER (log10, ::log10f, std::log10, 0.0, octave_Float_Inf)
+CD_SCALAR_MAPPER (log1p, ::log1pf, ::log1p, -1.0, octave_Float_Inf)
+SCALAR_MAPPER (real, ::real)
+SCALAR_MAPPER (round, xround)
+SCALAR_MAPPER (roundb, xroundb)
+SCALAR_MAPPER (signum, ::signum)
+SCALAR_MAPPER (sin, ::sinf)
+SCALAR_MAPPER (sinh, ::sinhf)
+CD_SCALAR_MAPPER (sqrt, ::sqrtf, std::sqrt, 0.0, octave_Float_Inf)
+SCALAR_MAPPER (tan, ::tanf)
+SCALAR_MAPPER (tanh, ::tanhf)
+SCALAR_MAPPER (finite, xfinite)
+SCALAR_MAPPER (isinf, xisinf)
+SCALAR_MAPPER (isna, octave_is_NA)
+SCALAR_MAPPER (isnan, xisnan)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-float.h b/src/ov-float.h
new file mode 100644
index 0000000..cf7a026
--- /dev/null
+++ b/src/ov-float.h
@@ -0,0 +1,299 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_h)
+#define octave_float_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "gripes.h"
+#include "ov-base.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-base-scalar.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Real scalar values.
+
+class
+OCTINTERP_API
+octave_float_scalar : public octave_base_scalar<float>
+{
+public:
+
+  octave_float_scalar (void)
+    : octave_base_scalar<float> (0.0) { }
+
+  octave_float_scalar (float d)
+    : octave_base_scalar<float> (d) { }
+
+  octave_float_scalar (const octave_float_scalar& s)
+    : octave_base_scalar<float> (s) { }
+
+  ~octave_float_scalar (void) { }
+
+  octave_base_value *clone (void) const { return new octave_float_scalar (*this); }
+
+  // We return an octave_matrix here instead of an octave_float_scalar so
+  // that in expressions like A(2,2,2) = 2 (for A previously
+  // undefined), A will be empty instead of a 1x1 object.
+  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  idx_vector index_vector (void) const { return idx_vector (scalar); }
+
+  octave_value any (int = 0) const
+    { return (scalar != 0 && ! lo_ieee_isnan (scalar)); }
+
+  bool is_real_scalar (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_single_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), scalar); }
+
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), scalar); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), scalar); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), scalar); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), scalar); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), scalar); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), scalar); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), scalar); }
+
+#define DEFINE_INT_SCALAR_VALUE(TYPE) \
+  octave_ ## TYPE \
+  TYPE ## _scalar_value (void) const \
+    { return octave_ ## TYPE (scalar); }
+
+  DEFINE_INT_SCALAR_VALUE (int8)
+  DEFINE_INT_SCALAR_VALUE (int16)
+  DEFINE_INT_SCALAR_VALUE (int32)
+  DEFINE_INT_SCALAR_VALUE (int64)
+  DEFINE_INT_SCALAR_VALUE (uint8)
+  DEFINE_INT_SCALAR_VALUE (uint16)
+  DEFINE_INT_SCALAR_VALUE (uint32)
+  DEFINE_INT_SCALAR_VALUE (uint64)
+
+#undef DEFINE_INT_SCALAR_VALUE
+
+  double double_value (bool = false) const { return static_cast<double> (scalar); }
+
+  float float_value (bool = false) const { return scalar; }
+
+  double scalar_value (bool = false) const { return static_cast<double> (scalar); }
+
+  float float_scalar_value (bool = false) const { return scalar; }
+
+  Matrix matrix_value (bool = false) const
+    { return Matrix (1, 1, scalar); }
+
+  FloatMatrix float_matrix_value (bool = false) const
+    { return FloatMatrix (1, 1, scalar); }
+
+  NDArray array_value (bool = false) const
+    { return NDArray (dim_vector (1, 1), scalar); }
+
+  FloatNDArray float_array_value (bool = false) const
+    { return FloatNDArray (dim_vector (1, 1), scalar); }
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return SparseMatrix (Matrix (1, 1, scalar)); }
+
+  // FIXME Need SparseComplexMatrix (Matrix) constructor!!!
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (sparse_matrix_value ()); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  Complex complex_value (bool = false) const { return scalar; }
+
+  FloatComplex float_complex_value (bool = false) const { return scalar; }
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return  ComplexMatrix (1, 1, Complex (scalar)); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const
+    { return  FloatComplexMatrix (1, 1, FloatComplex (scalar)); }
+
+  ComplexNDArray complex_array_value (bool = false) const
+    { return ComplexNDArray (dim_vector (1, 1), Complex (scalar)); }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const
+    { return FloatComplexNDArray (dim_vector (1, 1), FloatComplex (scalar)); }
+
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = static_cast<char> (scalar);
+    return retval;
+  }
+
+  bool bool_value (bool warn = false) const
+  {
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
+      gripe_logical_conversion ();
+
+    return scalar;
+  }
+
+  boolNDArray bool_array_value (bool warn = false) const
+  {
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
+      gripe_logical_conversion ();
+
+    return boolNDArray (dim_vector (1, 1), scalar);
+  }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void increment (void) { ++scalar; }
+
+  void decrement (void) { --scalar; }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      return os.write (array_value (), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+  octave_value map (float (*fcn) (float)) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-complex.cc b/src/ov-flt-complex.cc
new file mode 100644
index 0000000..c64e36f
--- /dev/null
+++ b/src/ov-flt-complex.cc
@@ -0,0 +1,489 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-complex.h"
+#include "ov-base.h"
+#include "ov-base-scalar.h"
+#include "ov-base-scalar.cc"
+#include "ov-flt-cx-mat.h"
+#include "ov-float.h"
+#include "ov-flt-complex.h"
+#include "gripes.h"
+#include "pr-output.h"
+#include "ops.h"
+
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+
+template class octave_base_scalar<FloatComplex>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_float_complex);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex,
+				     "float complex scalar", "single");
+
+octave_base_value *
+octave_float_complex::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  float im = std::imag (scalar);
+
+  if (im == 0.0 && ! lo_ieee_signbit (im))
+    retval = new octave_float_scalar (std::real (scalar));
+
+  return retval;
+}
+
+octave_value
+octave_float_complex::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // FIXME -- this doesn't solve the problem of
+  //
+  //   a = i; a([1,1], [1,1], [1,1])
+  //
+  // and similar constructions.  Hmm...
+
+  // FIXME -- using this constructor avoids narrowing the
+  // 1x1 matrix back to a scalar value.  Need a better solution
+  // to this problem.
+
+  octave_value tmp (new octave_float_complex_matrix (float_complex_matrix_value ()));
+
+  return tmp.do_index_op (idx, resize_ok);
+}
+
+double
+octave_float_complex::double_value (bool force_conversion) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real scalar");
+
+  retval = std::real (scalar);
+
+  return retval;
+}
+
+float
+octave_float_complex::float_value (bool force_conversion) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real scalar");
+
+  retval = std::real (scalar);
+
+  return retval;
+}
+
+Matrix
+octave_float_complex::matrix_value (bool force_conversion) const
+{
+  Matrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = Matrix (1, 1, std::real (scalar));
+
+  return retval;
+}
+
+FloatMatrix
+octave_float_complex::float_matrix_value (bool force_conversion) const
+{
+  FloatMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = FloatMatrix (1, 1, std::real (scalar));
+
+  return retval;
+}
+
+NDArray
+octave_float_complex::array_value (bool force_conversion) const
+{
+  NDArray retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = NDArray (dim_vector (1, 1), std::real (scalar));
+
+  return retval;
+}
+
+FloatNDArray
+octave_float_complex::float_array_value (bool force_conversion) const
+{
+  FloatNDArray retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex scalar", "real matrix");
+
+  retval = FloatNDArray (dim_vector (1, 1), std::real (scalar));
+
+  return retval;
+}
+
+Complex
+octave_float_complex::complex_value (bool) const
+{
+  return scalar;
+}
+
+FloatComplex
+octave_float_complex::float_complex_value (bool) const
+{
+  return static_cast<FloatComplex> (scalar);
+}
+
+ComplexMatrix
+octave_float_complex::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (1, 1, scalar);
+}
+
+FloatComplexMatrix
+octave_float_complex::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (1, 1, scalar);
+}
+
+ComplexNDArray
+octave_float_complex::complex_array_value (bool /* force_conversion */) const
+{
+  return ComplexNDArray (dim_vector (1, 1), scalar);
+}
+
+FloatComplexNDArray
+octave_float_complex::float_complex_array_value (bool /* force_conversion */) const
+{
+  return FloatComplexNDArray (dim_vector (1, 1), scalar);
+}
+
+octave_value 
+octave_float_complex::resize (const dim_vector& dv, bool fill) const
+{
+  if (fill)
+    {
+      FloatComplexNDArray retval (dv, FloatComplexNDArray::resize_fill_value ());
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+  else
+    {
+      FloatComplexNDArray retval (dv);
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+}
+
+bool 
+octave_float_complex::save_ascii (std::ostream& os)
+{
+  FloatComplex c = float_complex_value ();
+
+  octave_write_float_complex (os, c);
+
+  os << "\n";
+
+  return true;
+}
+
+bool 
+octave_float_complex::load_ascii (std::istream& is)
+{
+  scalar = octave_read_float_complex (is);
+
+  if (!is) 
+    {
+      error ("load: failed to load complex scalar constant");
+      return false;
+    }
+
+  return true;
+}
+
+
+bool 
+octave_float_complex::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+  char tmp = static_cast<char> (LS_FLOAT);
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+  FloatComplex ctmp = float_complex_value ();
+  os.write (reinterpret_cast<char *> (&ctmp), 8);
+
+  return true;
+}
+
+bool 
+octave_float_complex::load_binary (std::istream& is, bool swap,
+			     oct_mach_info::float_format fmt)
+{
+  char tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    return false;
+
+  FloatComplex ctmp;
+  read_floats (is, reinterpret_cast<float *> (&ctmp),
+		static_cast<save_type> (tmp), 2, swap, fmt);
+  if (error_state || ! is)
+    return false;
+
+  scalar = ctmp;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_float_complex::save_hdf5 (hid_t loc_id, const char *name,
+			   bool /* save_as_floats */)
+{
+  hsize_t dimens[3];
+  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
+  bool retval = true;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0)
+    return false;
+
+  type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
+  if (type_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      return false;
+    }
+
+  FloatComplex tmp = float_complex_value ();
+  retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
+		     &tmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_float_complex::load_hdf5 (hid_t loc_id, const char *name,
+			   bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t type_hid = H5Dget_type (data_hid);
+
+  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
+
+  if (! hdf5_types_compatible (type_hid, complex_type))
+    {
+      H5Tclose (complex_type);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  hid_t space_id = H5Dget_space (data_hid);
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+  if (rank != 0) 
+    {
+      H5Tclose (complex_type);
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  // complex scalar:
+  FloatComplex ctmp;
+  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+	       &ctmp) >= 0)
+    {
+      retval = true;
+      scalar = ctmp;
+    }
+
+  H5Tclose (complex_type);
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_float_complex::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxSINGLE_CLASS, 1, 1, mxCOMPLEX);
+
+  float *pr = static_cast<float *> (retval->get_data ());
+  float *pi = static_cast<float *> (retval->get_imag_data ());
+
+  pr[0] = std::real (scalar);
+  pi[0] = std::imag (scalar);
+
+  return retval;
+}
+
+static float
+xabs (const FloatComplex& x)
+{
+  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
+}
+
+static float
+ximag (const FloatComplex& x)
+{
+  return x.imag ();
+}
+
+static float
+xreal (const FloatComplex& x)
+{
+  return x.real ();
+}
+
+#define COMPLEX_MAPPER(MAP, FCN)	\
+  octave_value \
+  octave_float_complex::MAP (void) const \
+  { \
+    return octave_value (FCN (scalar)); \
+  }
+
+#define SCALAR_MAPPER(MAP, FCN)	\
+  octave_value \
+  octave_float_complex::MAP (void) const \
+  { \
+    if (scalar.imag () == 0) \
+      return octave_value (FCN (scalar.real ())); \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_float_complex::MAP (void) const \
+  { \
+    if (scalar.imag () == 0) \
+      { \
+	float re = scalar.real (); \
+	return (re < L1 || re > L2 \
+            ? octave_value (CFCN (scalar)) \
+	    : octave_value (RFCN (re))); \
+      } \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+SCALAR_MAPPER (erf, ::erff)
+SCALAR_MAPPER (erfc, ::erfcf)
+SCALAR_MAPPER (gamma, xgamma)
+CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+
+COMPLEX_MAPPER (abs, xabs)
+COMPLEX_MAPPER (acos, ::acos)
+COMPLEX_MAPPER (acosh, ::acosh)
+COMPLEX_MAPPER (angle, std::arg)
+COMPLEX_MAPPER (arg, std::arg)
+COMPLEX_MAPPER (asin, ::asin)
+COMPLEX_MAPPER (asinh, ::asinh)
+COMPLEX_MAPPER (atan, ::atan)
+COMPLEX_MAPPER (atanh, ::atanh)
+COMPLEX_MAPPER (ceil, ::ceil)
+COMPLEX_MAPPER (conj, std::conj)
+COMPLEX_MAPPER (cos, std::cos)
+COMPLEX_MAPPER (cosh, std::cosh)
+COMPLEX_MAPPER (exp, std::exp)
+COMPLEX_MAPPER (expm1, ::expm1f)
+COMPLEX_MAPPER (fix, ::fix)
+COMPLEX_MAPPER (floor, ::floor)
+COMPLEX_MAPPER (imag, ximag)
+COMPLEX_MAPPER (log, std::log)
+COMPLEX_MAPPER (log2, xlog2)
+COMPLEX_MAPPER (log10, std::log10)
+COMPLEX_MAPPER (log1p, ::log1pf)
+COMPLEX_MAPPER (real, xreal)
+COMPLEX_MAPPER (round, xround)
+COMPLEX_MAPPER (roundb, xroundb)
+COMPLEX_MAPPER (signum, ::signum)
+COMPLEX_MAPPER (sin, std::sin)
+COMPLEX_MAPPER (sinh, std::sinh)
+COMPLEX_MAPPER (sqrt, std::sqrt)
+COMPLEX_MAPPER (tan, std::tan)
+COMPLEX_MAPPER (tanh, std::tanh)
+COMPLEX_MAPPER (finite, xfinite)
+COMPLEX_MAPPER (isinf, xisinf)
+COMPLEX_MAPPER (isna, octave_is_NA)
+COMPLEX_MAPPER (isnan, xisnan)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-complex.h b/src/ov-flt-complex.h
new file mode 100644
index 0000000..e174fac
--- /dev/null
+++ b/src/ov-flt-complex.h
@@ -0,0 +1,219 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_complex_h)
+#define octave_float_complex_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "lo-ieee.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "ov-base.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-base-scalar.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Complex scalar values.
+
+class
+OCTINTERP_API
+octave_float_complex : public octave_base_scalar<FloatComplex>
+{
+public:
+
+  octave_float_complex (void)
+    : octave_base_scalar<FloatComplex> () { }
+
+  octave_float_complex (const FloatComplex& c)
+    : octave_base_scalar<FloatComplex> (c) { }
+
+  octave_float_complex (const octave_float_complex& c)
+    : octave_base_scalar<FloatComplex> (c) { }
+
+  ~octave_float_complex (void) { }
+
+  octave_base_value *clone (void) const { return new octave_float_complex (*this); }
+
+  // We return an octave_float_complex_matrix object here instead of an
+  // octave_float_complex object so that in expressions like A(2,2,2) = 2
+  // (for A previously undefined), A will be empty instead of a 1x1
+  // object.
+  octave_base_value *empty_clone (void) const
+    { return new octave_float_complex_matrix (); }
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  octave_value any (int = 0) const
+    {
+      return (scalar != FloatComplex (0, 0)
+	      && ! (lo_ieee_isnan (std::real (scalar))
+		    || lo_ieee_isnan (std::imag (scalar))));
+    }
+
+  bool is_complex_scalar (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_single_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  NDArray array_value (bool = false) const;
+
+  FloatNDArray float_array_value (bool = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return SparseMatrix (matrix_value ()); }
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (complex_matrix_value ()); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+
+  void increment (void) { scalar += 1.0; }
+
+  void decrement (void) { scalar -= 1.0; }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      // Yes, for compatibility, we drop the imaginary part here.
+      return os.write (array_value (true), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+typedef octave_float_complex octave_float_complex_scalar;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-cx-diag.cc b/src/ov-flt-cx-diag.cc
new file mode 100644
index 0000000..e4f80c4
--- /dev/null
+++ b/src/ov-flt-cx-diag.cc
@@ -0,0 +1,221 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "byte-swap.h"
+
+#include "ov-flt-cx-diag.h"
+#include "ov-base-diag.cc"
+#include "ov-flt-re-diag.h"
+#include "ov-flt-complex.h"
+#include "ov-flt-cx-mat.h"
+#include "ls-utils.h"
+
+template class octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_float_complex_diag_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex_diag_matrix, 
+                                     "float complex diagonal matrix", "single");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_float_complex_diag_matrix&);
+
+  return new octave_float_complex_matrix (v.float_complex_matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_float_complex_diag_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_float_complex_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_float_complex_diag_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.nelem () == 1)
+    {
+      // FIXME: the proxy mechanism of DiagArray2 causes problems here.
+      retval = new octave_float_complex (FloatComplex (matrix (0, 0)));
+      octave_base_value *rv2 = retval->try_narrowing_conversion ();
+      if (rv2)
+        {
+          delete retval;
+          retval = rv2;
+        }
+    }
+  else if (matrix.all_elements_are_real ())
+    {
+      return new octave_float_diag_matrix (::real (matrix));
+    }
+
+  return retval;
+}
+
+DiagMatrix
+octave_float_complex_diag_matrix::diag_matrix_value (bool force_conversion) const
+{
+  DiagMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       type_name (), "real matrix");
+
+  retval = ::real (matrix);
+
+  return retval;
+}
+
+FloatDiagMatrix
+octave_float_complex_diag_matrix::float_diag_matrix_value (bool force_conversion) const
+{
+  DiagMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       type_name (), "real matrix");
+
+  retval = ::real (matrix);
+
+  return retval;
+}
+
+ComplexDiagMatrix
+octave_float_complex_diag_matrix::complex_diag_matrix_value (bool) const
+{
+  return ComplexDiagMatrix (matrix);
+}
+
+FloatComplexDiagMatrix
+octave_float_complex_diag_matrix::float_complex_diag_matrix_value (bool) const
+{
+  return matrix;
+}
+
+octave_value
+octave_float_complex_diag_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_float_complex_diag_matrix::real (void) const
+{
+  return ::real (matrix);
+}
+
+octave_value
+octave_float_complex_diag_matrix::conj (void) const
+{
+  return ::conj (matrix);
+}
+
+octave_value
+octave_float_complex_diag_matrix::imag (void) const
+{
+  return ::imag (matrix);
+}
+
+octave_value
+octave_float_complex_diag_matrix::sqrt (void) const
+{    
+  octave_value retval;
+
+  static FloatComplexNDArray::cmapper csqrt = std::sqrt;
+
+  FloatComplexColumnVector dvec = matrix.diag ();
+  retval = FloatComplexDiagMatrix (dvec.map (csqrt));
+
+  retval.resize (dims ());
+
+  return retval;
+}
+
+bool 
+octave_float_complex_diag_matrix::save_binary (std::ostream& os, 
+                                               bool& /* save_as_floats */)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  FloatComplexMatrix m = FloatComplexMatrix (matrix.diag ());
+  save_type st = LS_FLOAT;
+  if (matrix.length () > 4096) // FIXME -- make this configurable.
+    {
+      float max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const FloatComplex *mtmp = m.data ();
+  write_floats (os, reinterpret_cast<const float *> (mtmp), st, 2 * m.numel ());
+
+  return true;
+}
+
+bool 
+octave_float_complex_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  FloatComplexDiagMatrix m (r, c);
+  FloatComplex *re = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_floats (is, reinterpret_cast<float *> (re), 
+               static_cast<save_type> (tmp), 2 * len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
+bool 
+octave_float_complex_diag_matrix::chk_valid_scalar (const octave_value& val, 
+                                                    FloatComplex& x) const
+{
+  bool retval = val.is_complex_scalar () || val.is_real_scalar ();
+  if (retval)
+    x = val.float_complex_value ();
+  return retval;
+}
diff --git a/src/ov-flt-cx-diag.h b/src/ov-flt-cx-diag.h
new file mode 100644
index 0000000..a5eefde
--- /dev/null
+++ b/src/ov-flt-cx-diag.h
@@ -0,0 +1,101 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_complex_diag_matrix_h)
+#define octave_float_complex_diag_matrix_h 1
+
+#include "ov-base.h"
+#include "ov-base-diag.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-typeinfo.h"
+
+// Real diagonal matrix values.
+
+class
+OCTINTERP_API
+octave_float_complex_diag_matrix 
+  : public octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix>
+{
+public:
+
+  octave_float_complex_diag_matrix (void)
+    : octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix> () { }
+
+  octave_float_complex_diag_matrix (const FloatComplexDiagMatrix& m)
+    : octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix> (m) { }
+
+  octave_float_complex_diag_matrix (const octave_float_complex_diag_matrix& m)
+    : octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix> (m) { }
+
+  ~octave_float_complex_diag_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_float_complex_diag_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_float_complex_diag_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  bool is_complex_matrix (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  DiagMatrix diag_matrix_value (bool = false) const;
+
+  FloatDiagMatrix float_diag_matrix_value (bool = false) const;
+
+  ComplexDiagMatrix complex_diag_matrix_value (bool = false) const;
+
+  FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+  octave_value abs (void) const;
+  octave_value conj (void) const;
+  octave_value imag (void) const;
+  octave_value real (void) const;
+  octave_value sqrt (void) const;
+
+private:
+
+  bool chk_valid_scalar (const octave_value&, 
+                         FloatComplex&) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-cx-mat.cc b/src/ov-flt-cx-mat.cc
new file mode 100644
index 0000000..e6dbef6
--- /dev/null
+++ b/src/ov-flt-cx-mat.cc
@@ -0,0 +1,877 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <vector>
+
+#include "data-conv.h"
+#include "lo-ieee.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+#include "mx-base.h"
+#include "mach-info.h"
+#include "oct-locbuf.h"
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "pr-output.h"
+#include "ops.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+template class octave_base_matrix<FloatComplexNDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_float_complex_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex_matrix,
+				     "float complex matrix", "single");
+
+octave_base_value *
+octave_float_complex_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.ndims () == 2)
+    {
+      FloatComplexMatrix cm = matrix.matrix_value ();
+
+      octave_idx_type nr = cm.rows ();
+      octave_idx_type nc = cm.cols ();
+
+      if (nr == 1 && nc == 1)
+	{
+	  FloatComplex c = matrix (0, 0);
+
+	  float im = std::imag (c);
+
+	  if (im == 0.0 && ! lo_ieee_signbit (im))
+	    retval = new octave_float_scalar (std::real (c));
+	  else
+	    retval = new octave_float_complex (c);
+	}
+      else if (nr == 0 || nc == 0)
+	retval = new octave_float_matrix (FloatMatrix (nr, nc));
+      else if (cm.all_elements_are_real ())
+	retval = new octave_float_matrix (::real (cm));
+    }
+  else if (matrix.all_elements_are_real ())
+    retval = new octave_float_matrix (::real (matrix));
+
+  return retval;
+}
+
+double
+octave_float_complex_matrix::double_value (bool force_conversion) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real scalar");
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "real scalar");
+
+      retval = std::real (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "real scalar");
+
+  return retval;
+}
+
+float
+octave_float_complex_matrix::float_value (bool force_conversion) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real scalar");
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "real scalar");
+
+      retval = std::real (matrix (0, 0));
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "real scalar");
+
+  return retval;
+}
+
+Matrix
+octave_float_complex_matrix::matrix_value (bool force_conversion) const
+{
+  Matrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real matrix");
+
+  retval = ::real (matrix.matrix_value ());
+
+  return retval;
+}
+
+FloatMatrix
+octave_float_complex_matrix::float_matrix_value (bool force_conversion) const
+{
+  FloatMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real matrix");
+
+  retval = ::real (matrix.matrix_value ());
+
+  return retval;
+}
+
+Complex
+octave_float_complex_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_float_complex_matrix::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "complex matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("complex matrix", "complex scalar");
+
+  return retval;
+}
+
+ComplexMatrix
+octave_float_complex_matrix::complex_matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
+FloatComplexMatrix
+octave_float_complex_matrix::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (matrix.matrix_value ());
+}
+
+charNDArray
+octave_float_complex_matrix::char_array_value (bool frc_str_conv) const
+{
+  charNDArray retval;
+
+  if (! frc_str_conv)
+    gripe_implicit_conversion ("Octave:num-to-str",
+			       "complex matrix", "string");
+  else
+    {
+      retval = charNDArray (dims ());
+      octave_idx_type nel = numel ();
+  
+      for (octave_idx_type i = 0; i < nel; i++)
+	retval.elem (i) = static_cast<char>(std::real (matrix.elem (i)));
+    }
+
+  return retval;
+}  
+
+FloatComplexNDArray 
+octave_float_complex_matrix::float_complex_array_value (bool) const 
+{ 
+  return FloatComplexNDArray (matrix);
+}
+
+SparseMatrix
+octave_float_complex_matrix::sparse_matrix_value (bool force_conversion) const
+{
+  SparseMatrix retval;
+
+  if (! force_conversion)
+    gripe_implicit_conversion ("Octave:imag-to-real",
+			       "complex matrix", "real matrix");
+
+  retval = SparseMatrix (::real (matrix.matrix_value ()));
+
+  return retval;
+}
+
+SparseComplexMatrix
+octave_float_complex_matrix::sparse_complex_matrix_value (bool) const
+{
+  return SparseComplexMatrix (matrix.matrix_value ());
+}
+
+octave_value
+octave_float_complex_matrix::diag (octave_idx_type k) const
+{
+  octave_value retval;
+  if (k == 0 && matrix.ndims () == 2 
+      && (matrix.rows () == 1 || matrix.columns () == 1))
+    retval = FloatComplexDiagMatrix (DiagArray2<FloatComplex> (matrix));
+  else
+    retval = octave_base_matrix<FloatComplexNDArray>::diag (k);
+
+  return retval;
+}
+
+bool 
+octave_float_complex_matrix::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+  if (d.length () > 2)
+    {
+      FloatComplexNDArray tmp = complex_array_value ();
+
+      os << "# ndims: " << d.length () << "\n";
+
+      for (int i = 0; i < d.length (); i++)
+	os << " " << d (i);
+
+      os << "\n" << tmp;
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for backward 
+      // compatiability. Makes load_ascii much more complex!!
+      os << "# rows: " << rows () << "\n"
+	 << "# columns: " << columns () << "\n";
+
+      os << complex_matrix_value ();
+    }
+
+  return true;
+}
+
+bool 
+octave_float_complex_matrix::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  string_vector keywords(2);
+
+  keywords[0] = "ndims";
+  keywords[1] = "rows";
+
+  std::string kw;
+  octave_idx_type val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = static_cast<int> (val);
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      if (is)
+		{
+		  FloatComplexNDArray tmp(dv);
+
+                  is >> tmp;
+
+                  if (is)
+                    matrix = tmp;
+                  else
+                    {
+                      error ("load: failed to load matrix constant");
+                      success = false;
+                    }
+		}
+	      else
+		{
+		  error ("load: failed to read dimensions");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of dimensions");
+	      success = false;
+	    }
+	}
+      else if (kw == "rows")
+	{
+	  octave_idx_type nr = val;
+	  octave_idx_type nc = 0;
+
+	  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  FloatComplexMatrix tmp (nr, nc);
+		  is >> tmp;
+		  if (is)
+		    matrix = tmp;
+		  else
+		    {
+		      error ("load: failed to load matrix constant");
+		      success = false;
+		    }
+		}
+	      else if (nr == 0 || nc == 0)
+		matrix = FloatComplexMatrix (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of rows and columns");
+	      success = false;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_float_complex_matrix::save_binary (std::ostream& os, bool&)
+{
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i = 0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  FloatComplexNDArray m = complex_array_value ();
+  save_type st = LS_FLOAT;
+  if (d.numel () > 4096) // FIXME -- make this configurable.
+    {
+      float max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const FloatComplex *mtmp = m.data ();
+  write_floats (os, reinterpret_cast<const float *> (mtmp), st, 2 * d.numel ());
+
+  return true;
+}
+
+bool 
+octave_float_complex_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  char tmp;
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims < 0)
+    {
+      mdims = - mdims;
+      int32_t di;
+      dim_vector dv;
+      dv.resize (mdims);
+
+      for (int i = 0; i < mdims; i++)
+	{
+	  if (! is.read (reinterpret_cast<char *> (&di), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&di);
+	  dv(i) = di;
+	}
+
+      // Convert an array with a single dimension to be a row vector.
+      // Octave should never write files like this, other software
+      // might.
+
+      if (mdims == 1)
+	{
+	  mdims = 2;
+	  dv.resize (mdims);
+	  dv(1) = dv(0);
+	  dv(0) = 1;
+	}
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+
+      FloatComplexNDArray m(dv);
+      FloatComplex *im = m.fortran_vec ();
+      read_floats (is, reinterpret_cast<float *> (im),
+		    static_cast<save_type> (tmp), 2 * dv.numel (), swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  else
+    {
+      int32_t nr, nc;
+      nr = mdims;
+      if (! is.read (reinterpret_cast<char *> (&nc), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&nc);
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+      FloatComplexMatrix m (nr, nc);
+      FloatComplex *im = m.fortran_vec ();
+      octave_idx_type len = nr * nc;
+      read_floats (is, reinterpret_cast<float *> (im),
+		    static_cast<save_type> (tmp), 2*len, swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_float_complex_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1, type_hid = -1;
+  bool retval = true;
+  FloatComplexNDArray m = complex_array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, 0);
+  if (space_hid < 0) return false;
+
+  hid_t save_type_hid = H5T_NATIVE_FLOAT;
+
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+  // hdf5 currently doesn't support float/integer conversions
+  else
+    {
+      float max_val, min_val;
+      
+      if (m.all_integers (max_val, min_val))
+	save_type_hid
+	  = save_type_to_hdf5 (get_save_type (max_val, min_val));
+    }
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+
+  type_hid = hdf5_make_complex_type (save_type_hid);
+  if (type_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      return false;
+    }
+
+  hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
+  if (complex_type_hid < 0) retval = false;
+
+  if (retval)
+    {
+      FloatComplex *mtmp = m.fortran_vec ();
+      if (H5Dwrite (data_hid, complex_type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		    mtmp) < 0)
+	{
+	  H5Tclose (complex_type_hid);
+	  retval = false;
+	}
+    }
+
+  H5Tclose (complex_type_hid);
+  H5Dclose (data_hid);
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool 
+octave_float_complex_matrix::load_hdf5 (hid_t loc_id, const char *name,
+				  bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+      return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t type_hid = H5Dget_type (data_hid);
+
+  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
+
+  if (! hdf5_types_compatible (type_hid, complex_type))
+    {
+      H5Tclose (complex_type);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+  
+  if (rank < 1)
+    {
+      H5Tclose (complex_type);
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  if (rank == 1)
+    {
+      dv.resize (2);
+      dv(0) = 1;
+      dv(1) = hdims[0];
+    }
+  else
+    {
+      dv.resize (rank);
+      for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	dv(j) = hdims[i];
+    }
+
+  FloatComplexNDArray m (dv);
+  FloatComplex *reim = m.fortran_vec ();
+  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+	       reim) >= 0) 
+    {
+      retval = true;
+      matrix = m;
+    }
+
+  H5Tclose (complex_type);
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+void
+octave_float_complex_matrix::print_raw (std::ostream& os,
+				  bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+mxArray *
+octave_float_complex_matrix::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxSINGLE_CLASS, dims (), mxCOMPLEX);
+
+  float *pr = static_cast<float *> (retval->get_data ());
+  float *pi = static_cast<float *> (retval->get_imag_data ());
+
+  mwSize nel = numel ();
+
+  const FloatComplex *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    {
+      pr[i] = std::real (p[i]);
+      pi[i] = std::imag (p[i]);
+    }
+
+  return retval;
+}
+
+#if 0
+static float
+xabs (const FloatComplex& x)
+{
+  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
+}
+#endif
+
+static float
+ximag (const FloatComplex& x)
+{
+  return x.imag ();
+}
+
+static float
+xreal (const FloatComplex& x)
+{
+  return x.real ();
+}
+
+static bool
+any_element_less_than (const FloatNDArray& a, float val)
+{
+  octave_idx_type len = a.length ();
+  const float *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] < val)
+	return true;
+    }
+
+  return false;
+}
+
+static bool
+any_element_greater_than (const FloatNDArray& a, float val)
+{
+  octave_idx_type len = a.length ();
+  const float *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] > val)
+	return true;
+    }
+
+  return false;
+}
+
+#define ARRAY_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_float_complex_matrix::MAP (void) const \
+  { \
+    static AMAP cmap = FCN; \
+    return matrix.map (cmap); \
+  }
+
+#define DARRAY_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_float_complex_matrix::MAP (void) const \
+  { \
+    static FloatComplexNDArray::dmapper dmap = ximag; \
+    FloatNDArray m = matrix.map (dmap); \
+    if (m.all_elements_are_zero ()) \
+      { \
+	dmap = xreal; \
+	m = matrix.map (dmap); \
+        static AMAP cmap = FCN; \
+        return m.map (cmap); \
+      } \
+    else \
+      { \
+        error ("%s: not defined for complex arguments", #MAP); \
+        return octave_value (); \
+      } \
+  }
+
+#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_float_complex_matrix::MAP (void) const \
+  { \
+    static FloatComplexNDArray::dmapper idmap = ximag; \
+    NDArray m = matrix.map (idmap); \
+    if (m.all_elements_are_zero ()) \
+      { \
+	static FloatComplexNDArray::dmapper rdmap = xreal; \
+	m = matrix.map (rdmap); \
+        static NDArray::dmapper dmap = RFCN; \
+        static NDArray::cmapper cmap = CFCN; \
+        return (any_element_less_than (m, L1) \
+                ? octave_value (m.map (cmap)) \
+	        : (any_element_greater_than (m, L2) \
+	           ? octave_value (m.map (cmap)) \
+	           : octave_value (m.map (dmap)))); \
+      } \
+    else \
+      { \
+        /*error ("%s: not defined for complex arguments", #MAP); */	\
+        return octave_value (m); \
+      } \
+  }
+
+// The fast mappers.
+octave_value
+octave_float_complex_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_float_complex_matrix::real (void) const
+{
+  return ::real (matrix);
+}
+
+octave_value
+octave_float_complex_matrix::conj (void) const
+{
+  return ::conj (matrix);
+}
+
+octave_value
+octave_float_complex_matrix::imag (void) const
+{
+  return ::imag (matrix);
+}
+
+octave_value
+octave_float_complex_matrix::isnan (void) const
+{
+  return matrix.isnan ();
+}
+
+octave_value
+octave_float_complex_matrix::isinf (void) const
+{
+  return matrix.isinf ();
+}
+
+octave_value
+octave_float_complex_matrix::finite (void) const
+{
+  return matrix.isfinite ();
+}
+
+DARRAY_MAPPER (erf, FloatNDArray::dmapper, ::erff)
+DARRAY_MAPPER (erfc, FloatNDArray::dmapper, ::erfcf)
+DARRAY_MAPPER (gamma, FloatNDArray::dmapper, xgamma)
+CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+
+ARRAY_MAPPER (acos, FloatComplexNDArray::cmapper, ::acos)
+ARRAY_MAPPER (acosh, FloatComplexNDArray::cmapper, ::acosh)
+ARRAY_MAPPER (angle, FloatComplexNDArray::dmapper, std::arg)
+ARRAY_MAPPER (arg, FloatComplexNDArray::dmapper, std::arg)
+ARRAY_MAPPER (asin, FloatComplexNDArray::cmapper, ::asin)
+ARRAY_MAPPER (asinh, FloatComplexNDArray::cmapper, ::asinh)
+ARRAY_MAPPER (atan, FloatComplexNDArray::cmapper, ::atan)
+ARRAY_MAPPER (atanh, FloatComplexNDArray::cmapper, ::atanh)
+ARRAY_MAPPER (ceil, FloatComplexNDArray::cmapper, ::ceil)
+ARRAY_MAPPER (cos, FloatComplexNDArray::cmapper, std::cos)
+ARRAY_MAPPER (cosh, FloatComplexNDArray::cmapper, std::cosh)
+ARRAY_MAPPER (exp, FloatComplexNDArray::cmapper, std::exp)
+ARRAY_MAPPER (expm1, FloatComplexNDArray::cmapper, ::expm1f)
+ARRAY_MAPPER (fix, FloatComplexNDArray::cmapper, ::fix)
+ARRAY_MAPPER (floor, FloatComplexNDArray::cmapper, ::floor)
+ARRAY_MAPPER (log, FloatComplexNDArray::cmapper, std::log)
+ARRAY_MAPPER (log2, FloatComplexNDArray::cmapper, xlog2)
+ARRAY_MAPPER (log10, FloatComplexNDArray::cmapper, std::log10)
+ARRAY_MAPPER (log1p, FloatComplexNDArray::cmapper, ::log1pf)
+ARRAY_MAPPER (round, FloatComplexNDArray::cmapper, xround)
+ARRAY_MAPPER (roundb, FloatComplexNDArray::cmapper, xroundb)
+ARRAY_MAPPER (signum, FloatComplexNDArray::cmapper, ::signum)
+ARRAY_MAPPER (sin, FloatComplexNDArray::cmapper, std::sin)
+ARRAY_MAPPER (sinh, FloatComplexNDArray::cmapper, std::sinh)
+ARRAY_MAPPER (sqrt, FloatComplexNDArray::cmapper, std::sqrt)
+ARRAY_MAPPER (tan, FloatComplexNDArray::cmapper, std::tan)
+ARRAY_MAPPER (tanh, FloatComplexNDArray::cmapper, std::tanh)
+ARRAY_MAPPER (isna, FloatComplexNDArray::bmapper, octave_is_NA)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-cx-mat.h b/src/ov-flt-cx-mat.h
new file mode 100644
index 0000000..1d0d89d
--- /dev/null
+++ b/src/ov-flt-cx-mat.h
@@ -0,0 +1,218 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_complex_matrix_h)
+#define octave_float_complex_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-typeinfo.h"
+
+#include "MatrixType.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Complex matrix values.
+
+class
+OCTINTERP_API
+octave_float_complex_matrix : public octave_base_matrix<FloatComplexNDArray>
+{
+public:
+
+  octave_float_complex_matrix (void)
+    : octave_base_matrix<FloatComplexNDArray> () { }
+
+  octave_float_complex_matrix (const FloatComplexNDArray& m)
+    : octave_base_matrix<FloatComplexNDArray> (m) { }
+
+  octave_float_complex_matrix (const FloatComplexMatrix& m)
+    : octave_base_matrix<FloatComplexNDArray> (m) { }
+
+  octave_float_complex_matrix (const FloatComplexMatrix& m, const MatrixType& t)
+    : octave_base_matrix<FloatComplexNDArray> (m, t) { }
+
+  octave_float_complex_matrix (const ArrayN<FloatComplex>& m)
+    : octave_base_matrix<FloatComplexNDArray> (FloatComplexNDArray (m)) { }
+
+  octave_float_complex_matrix (const FloatComplexDiagMatrix& d)
+    : octave_base_matrix<FloatComplexNDArray> (FloatComplexMatrix (d)) { }
+
+  octave_float_complex_matrix (const FloatComplexRowVector& v)
+    : octave_base_matrix<FloatComplexNDArray> (FloatComplexMatrix (v)) { }
+
+  octave_float_complex_matrix (const FloatComplexColumnVector& v)
+    : octave_base_matrix<FloatComplexNDArray> (FloatComplexMatrix (v)) { }
+
+  octave_float_complex_matrix (const octave_float_complex_matrix& cm)
+    : octave_base_matrix<FloatComplexNDArray> (cm) { }
+
+  ~octave_float_complex_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_float_complex_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_float_complex_matrix (); }
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  bool is_complex_matrix (void) const { return true; }
+
+  bool is_complex_type (void) const { return true; }
+
+  bool is_single_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const { return matrix; }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+
+  charNDArray char_array_value (bool frc_str_conv = false) const;
+  
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  octave_value diag (octave_idx_type k = 0) const;
+
+  void increment (void) { matrix += FloatComplex (1.0); }
+
+  void decrement (void) { matrix -= FloatComplex (1.0); }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      // Yes, for compatibility, we drop the imaginary part here.
+      return os.write (matrix_value (true), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-re-diag.cc b/src/ov-flt-re-diag.cc
new file mode 100644
index 0000000..53ae221
--- /dev/null
+++ b/src/ov-flt-re-diag.cc
@@ -0,0 +1,195 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "byte-swap.h"
+
+#include "ov-flt-re-diag.h"
+#include "ov-base-diag.cc"
+#include "ov-float.h"
+#include "ov-flt-re-mat.h"
+#include "ls-utils.h"
+
+template class octave_base_diag<FloatDiagMatrix, FloatMatrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_float_diag_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_diag_matrix, 
+                                     "float diagonal matrix", "single");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_float_diag_matrix&);
+
+  return new octave_float_matrix (v.float_matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_float_diag_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_float_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_float_diag_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  // FIXME: the proxy mechanism of DiagArray2 causes problems here.
+  if (matrix.nelem () == 1)
+    retval = new octave_float_scalar (float (matrix (0, 0)));
+
+  return retval;
+}
+
+DiagMatrix
+octave_float_diag_matrix::diag_matrix_value (bool) const
+{
+  return DiagMatrix (matrix);
+}
+
+FloatDiagMatrix
+octave_float_diag_matrix::float_diag_matrix_value (bool) const
+{
+  return matrix;
+}
+
+ComplexDiagMatrix
+octave_float_diag_matrix::complex_diag_matrix_value (bool) const
+{
+  return ComplexDiagMatrix (matrix);
+}
+
+FloatComplexDiagMatrix
+octave_float_diag_matrix::float_complex_diag_matrix_value (bool) const
+{
+  return FloatComplexDiagMatrix (matrix);
+}
+
+octave_value
+octave_float_diag_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_float_diag_matrix::real (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_float_diag_matrix::conj (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_float_diag_matrix::imag (void) const
+{
+  return DiagMatrix (matrix.rows (), matrix.cols (), 0.0f);
+}
+
+octave_value
+octave_float_diag_matrix::sqrt (void) const
+{    
+  octave_value retval;
+
+  static FloatNDArray::dmapper dsqrt = ::sqrtf;
+  static FloatNDArray::cmapper csqrt = std::sqrt;
+
+  FloatColumnVector dvec = matrix.diag ();
+  if (FloatMatrix (dvec).any_element_is_negative ())
+    retval = FloatComplexDiagMatrix (dvec.map (csqrt));
+  else
+    retval = FloatDiagMatrix (dvec.map (dsqrt));
+
+  retval.resize (dims ());
+
+  return retval;
+}
+
+bool 
+octave_float_diag_matrix::save_binary (std::ostream& os,
+				       bool& /* save_as_floats*/)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  FloatMatrix m = FloatMatrix (matrix.diag ());
+  save_type st = LS_FLOAT;
+  if (matrix.length () > 8192) // FIXME -- make this configurable.
+    {
+      float max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const float *mtmp = m.data ();
+  write_floats (os, mtmp, st, m.numel ());
+
+  return true;
+}
+
+bool 
+octave_float_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  FloatDiagMatrix m (r, c);
+  float *re = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_floats (is, re, static_cast<save_type> (tmp), len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
+bool 
+octave_float_diag_matrix::chk_valid_scalar (const octave_value& val, 
+                                            float& x) const
+{
+  bool retval = val.is_real_scalar ();
+  if (retval)
+    x = val.float_value ();
+  return retval;
+}
diff --git a/src/ov-flt-re-diag.h b/src/ov-flt-re-diag.h
new file mode 100644
index 0000000..5c4d750
--- /dev/null
+++ b/src/ov-flt-re-diag.h
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_diag_matrix_h)
+#define octave_float_diag_matrix_h 1
+
+#include "ov-base.h"
+#include "ov-base-diag.h"
+#include "ov-flt-re-mat.h"
+#include "ov-typeinfo.h"
+
+// Real diagonal matrix values.
+
+class
+OCTINTERP_API
+octave_float_diag_matrix 
+  : public octave_base_diag<FloatDiagMatrix, FloatMatrix>
+{
+public:
+
+  octave_float_diag_matrix (void)
+    : octave_base_diag<FloatDiagMatrix, FloatMatrix> () { }
+
+  octave_float_diag_matrix (const FloatDiagMatrix& m)
+    : octave_base_diag<FloatDiagMatrix, FloatMatrix> (m) { }
+
+  octave_float_diag_matrix (const octave_float_diag_matrix& m)
+    : octave_base_diag<FloatDiagMatrix, FloatMatrix> (m) { }
+
+  ~octave_float_diag_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_float_diag_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_float_diag_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_single_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  DiagMatrix diag_matrix_value (bool = false) const;
+
+  FloatDiagMatrix float_diag_matrix_value (bool = false) const;
+
+  ComplexDiagMatrix complex_diag_matrix_value (bool = false) const;
+
+  FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+  octave_value abs (void) const;
+  octave_value conj (void) const;
+  octave_value imag (void) const;
+  octave_value real (void) const;
+  octave_value sqrt (void) const;
+
+private:
+
+  bool chk_valid_scalar (const octave_value&, 
+                         float&) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
diff --git a/src/ov-flt-re-mat.cc b/src/ov-flt-re-mat.cc
new file mode 100644
index 0000000..5125ce0
--- /dev/null
+++ b/src/ov-flt-re-mat.cc
@@ -0,0 +1,862 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+#include <vector>
+
+#include "data-conv.h"
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "mx-base.h"
+#include "quit.h"
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-flt-complex.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-flt-re-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+#include "ops.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+#if ! defined (UCHAR_MAX)
+#define UCHAR_MAX 255
+#endif
+
+template class octave_base_matrix<FloatNDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_float_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_matrix, "float matrix", "single");
+
+octave_base_value *
+octave_float_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.nelem () == 1)
+    retval = new octave_float_scalar (matrix (0));
+
+  return retval;
+}
+
+double
+octave_float_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "real scalar");
+
+  return retval;
+}
+
+float
+octave_float_matrix::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "real scalar");
+
+  return retval;
+}
+
+// FIXME
+
+Matrix
+octave_float_matrix::matrix_value (bool) const
+{
+  return Matrix (matrix.matrix_value ());
+}
+
+FloatMatrix
+octave_float_matrix::float_matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
+Complex
+octave_float_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_float_matrix::float_complex_value (bool) const
+{
+  double tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "complex scalar");
+
+  return retval;
+}
+
+// FIXME
+
+ComplexMatrix
+octave_float_matrix::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (matrix.matrix_value ());
+}
+
+FloatComplexMatrix
+octave_float_matrix::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (matrix.matrix_value ());
+}
+
+ComplexNDArray
+octave_float_matrix::complex_array_value (bool) const
+{
+  return ComplexNDArray (matrix);
+}
+
+FloatComplexNDArray
+octave_float_matrix::float_complex_array_value (bool) const
+{
+  return FloatComplexNDArray (matrix);
+}
+
+NDArray 
+octave_float_matrix::array_value (bool) const
+{ 
+  return NDArray (matrix); 
+}
+
+boolNDArray
+octave_float_matrix::bool_array_value (bool warn) const
+{
+  if (matrix.any_element_is_nan ())
+    error ("invalid conversion from NaN to logical");
+  else if (warn && matrix.any_element_not_one_or_zero ())
+    gripe_logical_conversion ();
+
+  return boolNDArray (matrix);
+}
+  
+charNDArray
+octave_float_matrix::char_array_value (bool) const
+{
+  charNDArray retval (dims ());
+
+  octave_idx_type nel = numel ();
+  
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval.elem (i) = static_cast<char>(matrix.elem (i));
+
+  return retval;
+}
+  
+SparseMatrix 
+octave_float_matrix::sparse_matrix_value (bool) const
+{
+  return SparseMatrix (matrix.matrix_value ());
+}
+
+SparseComplexMatrix 
+octave_float_matrix::sparse_complex_matrix_value (bool) const
+{
+  // FIXME Need a SparseComplexMatrix (Matrix) constructor to make
+  // this function more efficient. Then this should become
+  // return SparseComplexMatrix (matrix.matrix_value ());
+  return SparseComplexMatrix (sparse_matrix_value ());
+}
+
+octave_value
+octave_float_matrix::diag (octave_idx_type k) const
+{
+  octave_value retval;
+  if (k == 0 && matrix.ndims () == 2 
+      && (matrix.rows () == 1 || matrix.columns () == 1))
+    retval = FloatDiagMatrix (DiagArray2<float> (matrix));
+  else
+    retval = octave_base_matrix<FloatNDArray>::diag (k);
+
+  return retval;
+}
+
+octave_value
+octave_float_matrix::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+  dim_vector dv = dims ();
+  octave_idx_type nel = dv.numel ();
+
+  charNDArray chm (dv);
+
+  bool warned = false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+
+      float d = matrix (i);
+
+      if (xisnan (d))
+	{
+	  ::error ("invalid conversion from NaN to character");
+	  return retval;
+	}
+      else
+	{
+	  int ival = NINT (d);
+
+	  if (ival < 0 || ival > UCHAR_MAX)
+	    {
+	      // FIXME -- is there something
+	      // better we could do?
+
+	      ival = 0;
+
+	      if (! warned)
+		{
+		  ::warning ("range error for conversion to character value");
+		  warned = true;
+		}
+	    }
+
+	  chm (i) = static_cast<char> (ival);
+	}
+    }
+
+  retval = octave_value (chm, true, type);
+
+  return retval;
+}
+
+bool 
+octave_float_matrix::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+
+  if (d.length () > 2)
+    {
+      FloatNDArray tmp = float_array_value ();
+
+      os << "# ndims: " << d.length () << "\n";
+
+      for (int i=0; i < d.length (); i++)
+	os << " " << d (i);
+
+      os << "\n" << tmp;
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for backward 
+      // compatiability. Makes load_ascii much more complex!!
+      os << "# rows: " << rows () << "\n"
+	 << "# columns: " << columns () << "\n";
+
+      os << float_matrix_value ();
+    }
+
+  return true;
+}
+
+bool 
+octave_float_matrix::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  string_vector keywords(2);
+
+  keywords[0] = "ndims";
+  keywords[1] = "rows";
+
+  std::string kw;
+  octave_idx_type val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = static_cast<int> (val);
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      if (is)
+		{
+		  FloatNDArray tmp(dv);
+
+                  is >> tmp;
+
+                  if (is)
+                    matrix = tmp;
+                  else
+                    {
+                      error ("load: failed to load matrix constant");
+                      success = false;
+                    }
+		}
+	      else
+		{
+		  error ("load: failed to read dimensions");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of dimensions");
+	      success = false;
+	    }
+	}
+      else if (kw == "rows")
+	{
+	  octave_idx_type nr = val;
+	  octave_idx_type nc = 0;
+
+	  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  FloatMatrix tmp (nr, nc);
+		  is >> tmp;
+		  if (is)
+		    matrix = tmp;
+		  else
+		    {
+		      error ("load: failed to load matrix constant");
+		      success = false;
+		    }
+		}
+	      else if (nr == 0 || nc == 0)
+		matrix = FloatMatrix (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else 
+	    {
+	      error ("load: failed to extract number of rows and columns");
+	      success = false;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_float_matrix::save_binary (std::ostream& os, bool&)
+{
+
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i = 0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  FloatNDArray m = float_array_value ();
+  save_type st = LS_FLOAT;
+  if (d.numel () > 8192) // FIXME -- make this configurable.
+    {
+      float max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const float *mtmp = m.data ();
+  write_floats (os, mtmp, st, d.numel ());
+
+  return true;
+}
+
+bool 
+octave_float_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  char tmp;
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims < 0)
+    {
+      mdims = - mdims;
+      int32_t di;
+      dim_vector dv;
+      dv.resize (mdims);
+
+      for (int i = 0; i < mdims; i++)
+	{
+	  if (! is.read (reinterpret_cast<char *> (&di), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&di);
+	  dv(i) = di;
+	}
+
+      // Convert an array with a single dimension to be a row vector.
+      // Octave should never write files like this, other software
+      // might.
+
+      if (mdims == 1)
+	{
+	  mdims = 2;
+	  dv.resize (mdims);
+	  dv(1) = dv(0);
+	  dv(0) = 1;
+	}
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+
+      FloatNDArray m(dv);
+      float *re = m.fortran_vec ();
+      read_floats (is, re, static_cast<save_type> (tmp), dv.numel (), swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  else
+    {
+      int32_t nr, nc;
+      nr = mdims;
+      if (! is.read (reinterpret_cast<char *> (&nc), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&nc);
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+      FloatMatrix m (nr, nc);
+      float *re = m.fortran_vec ();
+      octave_idx_type len = nr * nc;
+      read_floats (is, re, static_cast<save_type> (tmp), len, swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_float_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  FloatNDArray m = array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, 0);
+
+  if (space_hid < 0) return false;
+
+  hid_t save_type_hid = H5T_NATIVE_FLOAT;
+
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+  // hdf5 currently doesn't support float/integer conversions
+  else
+    {
+      float max_val, min_val;
+
+      if (m.all_integers (max_val, min_val))
+	save_type_hid
+	  = save_type_to_hdf5 (get_save_type (max_val, min_val));
+    }
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+  
+  data_hid = H5Dcreate (loc_id, name, save_type_hid, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  float *mtmp = m.fortran_vec ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, mtmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_float_matrix::load_hdf5 (hid_t loc_id, const char *name,
+			  bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+      return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+  
+  if (rank < 1)
+    {
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  if (rank == 1)
+    {
+      dv.resize (2);
+      dv(0) = 1;
+      dv(1) = hdims[0];
+    }
+  else
+    {
+      dv.resize (rank);
+      for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	dv(j) = hdims[i];
+    }
+
+  FloatNDArray m (dv);
+  float *re = m.fortran_vec ();
+  if (H5Dread (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, re) >= 0) 
+    {
+      retval = true;
+      matrix = m;
+    }
+
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+void
+octave_float_matrix::print_raw (std::ostream& os,
+			  bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+mxArray *
+octave_float_matrix::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxSINGLE_CLASS, dims (), mxREAL);
+
+  float *pr = static_cast<float *> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  const float *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    pr[i] = p[i];
+
+  return retval;
+}
+
+static bool
+any_element_less_than (const FloatNDArray& a, float val)
+{
+  octave_idx_type len = a.length ();
+  const float *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] < val)
+	return true;
+    }
+
+  return false;
+}
+
+static bool
+any_element_greater_than (const FloatNDArray& a, float val)
+{
+  octave_idx_type len = a.length ();
+  const float *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] > val)
+	return true;
+    }
+
+  return false;
+}
+
+#define ARRAY_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_float_matrix::MAP (void) const \
+  { \
+    static AMAP dmap = FCN; \
+    return matrix.map (dmap); \
+  }
+
+#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_float_matrix::MAP (void) const \
+  { \
+    static FloatNDArray::dmapper dmap = RFCN; \
+    static FloatNDArray::cmapper cmap = CFCN; \
+ \
+    return (any_element_less_than (matrix, L1) \
+            ? octave_value (matrix.map (cmap)) \
+	    : (any_element_greater_than (matrix, L2) \
+	       ? octave_value (matrix.map (cmap)) \
+	       : octave_value (matrix.map (dmap)))); \
+  }
+
+// The fast mappers.
+octave_value
+octave_float_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_float_matrix::real (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_float_matrix::conj (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_float_matrix::imag (void) const
+{
+  return FloatNDArray (matrix.dims (), 0.0);
+}
+
+octave_value
+octave_float_matrix::isnan (void) const
+{
+  return matrix.isnan ();
+}
+
+octave_value
+octave_float_matrix::isinf (void) const
+{
+  return matrix.isinf ();
+}
+
+octave_value
+octave_float_matrix::finite (void) const
+{
+  return matrix.isfinite ();
+}
+
+ARRAY_MAPPER (erf, FloatNDArray::dmapper, ::erff)
+ARRAY_MAPPER (erfc, FloatNDArray::dmapper, ::erfcf)
+ARRAY_MAPPER (gamma, FloatNDArray::dmapper, xgamma)
+CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Float_Inf)
+CD_ARRAY_MAPPER (acos, ::acosf, ::acos, -1.0, 1.0)
+CD_ARRAY_MAPPER (acosh, ::acoshf, ::acosh, 1.0, octave_Float_Inf)
+ARRAY_MAPPER (angle, FloatNDArray::dmapper, ::arg)
+ARRAY_MAPPER (arg, FloatNDArray::dmapper, ::arg)
+CD_ARRAY_MAPPER (asin, ::asinf, ::asin, -1.0, 1.0)
+ARRAY_MAPPER (asinh, FloatNDArray::dmapper,::asinhf)
+ARRAY_MAPPER (atan, FloatNDArray::dmapper, ::atanf)
+CD_ARRAY_MAPPER (atanh, ::atanhf, ::atanh, -1.0, 1.0)
+ARRAY_MAPPER (ceil, FloatNDArray::dmapper, ::ceilf)
+ARRAY_MAPPER (cos, FloatNDArray::dmapper, ::cosf)
+ARRAY_MAPPER (cosh, FloatNDArray::dmapper, ::coshf)
+ARRAY_MAPPER (exp, FloatNDArray::dmapper, ::expf)
+ARRAY_MAPPER (expm1, FloatNDArray::dmapper, ::expm1f)
+ARRAY_MAPPER (fix, FloatNDArray::dmapper, ::fix)
+ARRAY_MAPPER (floor, FloatNDArray::dmapper, ::floorf)
+CD_ARRAY_MAPPER (log, ::logf, std::log, 0.0, octave_Float_Inf)
+CD_ARRAY_MAPPER (log2, xlog2, xlog2, 0.0, octave_Float_Inf)
+CD_ARRAY_MAPPER (log10, ::log10f, std::log10, 0.0, octave_Float_Inf)
+CD_ARRAY_MAPPER (log1p, ::log1pf, ::log1pf, -1.0, octave_Float_Inf)
+ARRAY_MAPPER (round, FloatNDArray::dmapper, xround)
+ARRAY_MAPPER (roundb, FloatNDArray::dmapper, xroundb)
+ARRAY_MAPPER (signum, FloatNDArray::dmapper, ::signum)
+ARRAY_MAPPER (sin, FloatNDArray::dmapper, ::sinf)
+ARRAY_MAPPER (sinh, FloatNDArray::dmapper, ::sinhf)
+CD_ARRAY_MAPPER (sqrt, ::sqrtf, std::sqrt, 0.0, octave_Float_Inf)
+ARRAY_MAPPER (tan, FloatNDArray::dmapper, ::tanf)
+ARRAY_MAPPER (tanh, FloatNDArray::dmapper, ::tanhf)
+ARRAY_MAPPER (isna, FloatNDArray::bmapper, octave_is_NA)
+
+DEFUN (single, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} single (@var{x})\n\
+Convert @var{x} to single precision type.\n\
+ at seealso{double}\n\
+ at end deftypefn")
+{
+  // The OCTAVE_TYPE_CONV_BODY3 macro declares retval, so they go
+  // inside their own scopes, and we don't declare retval here to
+  // avoid a shadowed declaration warning.
+
+  if (args.length () == 1)
+    {
+      if (args(0).is_diag_matrix ())
+        {
+	  if (args(0).is_complex_type ())
+	    {
+	      OCTAVE_TYPE_CONV_BODY3 (single, octave_float_complex_diag_matrix, octave_float_complex);
+	    }
+	  else
+	    {
+	      OCTAVE_TYPE_CONV_BODY3 (single, octave_float_diag_matrix, octave_float_scalar);
+	    }
+        }
+      else if (args(0).is_sparse_type ())
+	{
+	  error ("single: sparse type do not support single precision");
+	}
+      else if (args(0).is_complex_type ())
+	{
+	  OCTAVE_TYPE_CONV_BODY3 (single, octave_float_complex_matrix, octave_float_complex);
+	}
+      else
+	{
+	  OCTAVE_TYPE_CONV_BODY3 (single, octave_float_matrix, octave_float_scalar);
+	}
+    }
+  else
+    print_usage ();
+
+  return octave_value ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-flt-re-mat.h b/src/ov-flt-re-mat.h
new file mode 100644
index 0000000..930f9ff
--- /dev/null
+++ b/src/ov-flt-re-mat.h
@@ -0,0 +1,251 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_float_matrix_h)
+#define octave_float_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-typeinfo.h"
+
+#include "MatrixType.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Real matrix values.
+
+class
+OCTINTERP_API
+octave_float_matrix : public octave_base_matrix<FloatNDArray>
+{
+public:
+
+  octave_float_matrix (void)
+    : octave_base_matrix<FloatNDArray> () { }
+
+  octave_float_matrix (const FloatMatrix& m)
+    : octave_base_matrix<FloatNDArray> (m) { }
+
+  octave_float_matrix (const FloatMatrix& m, const MatrixType& t)
+    : octave_base_matrix<FloatNDArray> (m, t) { }
+
+  octave_float_matrix (const FloatNDArray& nda)
+    : octave_base_matrix<FloatNDArray> (nda) { }
+
+  octave_float_matrix (const ArrayN<float>& m)
+    : octave_base_matrix<FloatNDArray> (FloatNDArray (m)) { }
+
+  octave_float_matrix (const FloatDiagMatrix& d)
+    : octave_base_matrix<FloatNDArray> (FloatMatrix (d)) { }
+
+  octave_float_matrix (const FloatRowVector& v)
+    : octave_base_matrix<FloatNDArray> (FloatMatrix (v)) { }
+
+  octave_float_matrix (const FloatColumnVector& v)
+    : octave_base_matrix<FloatNDArray> (FloatMatrix (v)) { }
+
+  octave_float_matrix (const octave_float_matrix& m)
+    : octave_base_matrix<FloatNDArray> (m) { }
+
+  ~octave_float_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_float_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_float_matrix (); }
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  idx_vector index_vector (void) const { return idx_vector (matrix); }
+
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_single_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (matrix); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (matrix); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (matrix); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (matrix); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (matrix); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (matrix); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (matrix); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (matrix); }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+   
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+
+  boolNDArray bool_array_value (bool warn = false) const;
+
+  charNDArray char_array_value (bool = false) const;
+  
+  NDArray array_value (bool = false) const;
+  
+  FloatNDArray float_array_value (bool = false) const { return matrix; }
+
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  octave_value diag (octave_idx_type k = 0) const;
+
+  void increment (void) { matrix += 1.0; }
+
+  void decrement (void) { matrix -= 1.0; }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return matrix.mex_get_data (); }
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int-traits.h b/src/ov-int-traits.h
new file mode 100644
index 0000000..755b185
--- /dev/null
+++ b/src/ov-int-traits.h
@@ -0,0 +1,69 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_value_int_traits_h)
+#define octave_value_int_traits_h 1
+
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+
+template <class T>
+class
+octave_value_int_traits
+{
+public:
+  typedef T scalar_type;
+};
+
+#define OCTAVE_VALUE_INT_TRAITS(MT, ST) \
+  template<> \
+  class \
+  octave_value_int_traits<MT> \
+  { \
+  public: \
+    typedef ST scalar_type; \
+  }
+
+OCTAVE_VALUE_INT_TRAITS(int8NDArray, octave_int8_scalar);
+OCTAVE_VALUE_INT_TRAITS(int16NDArray, octave_int16_scalar);
+OCTAVE_VALUE_INT_TRAITS(int32NDArray, octave_int32_scalar);
+OCTAVE_VALUE_INT_TRAITS(int64NDArray, octave_int64_scalar);
+
+OCTAVE_VALUE_INT_TRAITS(uint8NDArray, octave_uint8_scalar);
+OCTAVE_VALUE_INT_TRAITS(uint16NDArray, octave_uint16_scalar);
+OCTAVE_VALUE_INT_TRAITS(uint32NDArray, octave_uint32_scalar);
+OCTAVE_VALUE_INT_TRAITS(uint64NDArray, octave_uint64_scalar);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int16.cc b/src/ov-int16.cc
new file mode 100644
index 0000000..2e5e71c
--- /dev/null
+++ b/src/ov-int16.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_INT16
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-int16.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<int16NDArray>;
+
+template class octave_base_int_matrix<int16NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int16_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int16_matrix,
+				     "int16 matrix", "int16");
+
+template class octave_base_scalar<octave_int16>;
+
+template class octave_base_int_scalar<octave_int16>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int16_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int16_scalar,
+				     "int16 scalar", "int16");
+
+DEFUN (int16, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} int16 (@var{x})\n\
+Convert @var{x} to 16-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (int16);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int16.h b/src/ov-int16.h
new file mode 100644
index 0000000..10f72c9
--- /dev/null
+++ b/src/ov-int16.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int16_h)
+#define octave_int16_h 1
+
+#define OCTAVE_INT_T octave_int16
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_int16_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION int16_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_int16_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION int16_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_int16_type
+
+#define OCTAVE_INT_MX_CLASS mxINT16_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int32.cc b/src/ov-int32.cc
new file mode 100644
index 0000000..c297b86
--- /dev/null
+++ b/src/ov-int32.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_INT32
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-int32.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<int32NDArray>;
+
+template class octave_base_int_matrix<int32NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int32_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int32_matrix,
+				     "int32 matrix", "int32");
+
+template class octave_base_scalar<octave_int32>;
+
+template class octave_base_int_scalar<octave_int32>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int32_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int32_scalar,
+				     "int32 scalar", "int32");
+
+DEFUN (int32, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} int32 (@var{x})\n\
+Convert @var{x} to 32-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (int32);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int32.h b/src/ov-int32.h
new file mode 100644
index 0000000..14832ad
--- /dev/null
+++ b/src/ov-int32.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int32_h)
+#define octave_int32_h 1
+
+#define OCTAVE_INT_T octave_int32
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_int32_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION int32_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_int32_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION int32_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_int32_type
+
+#define OCTAVE_INT_MX_CLASS mxINT32_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int64.cc b/src/ov-int64.cc
new file mode 100644
index 0000000..2849e94
--- /dev/null
+++ b/src/ov-int64.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_INT64
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-int64.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<int64NDArray>;
+
+template class octave_base_int_matrix<int64NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int64_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int64_matrix,
+				     "int64 matrix", "int64");
+
+template class octave_base_scalar<octave_int64>;
+
+template class octave_base_int_scalar<octave_int64>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int64_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int64_scalar,
+				     "int64 scalar", "int64");
+
+DEFUN (int64, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} int64 (@var{x})\n\
+Convert @var{x} to 64-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (int64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int64.h b/src/ov-int64.h
new file mode 100644
index 0000000..0d29ccf
--- /dev/null
+++ b/src/ov-int64.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int64_h)
+#define octave_int64_h 1
+
+#define OCTAVE_INT_T octave_int64
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_int64_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION int64_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_int64_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION int64_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_int64_type
+
+#define OCTAVE_INT_MX_CLASS mxINT64_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int8.cc b/src/ov-int8.cc
new file mode 100644
index 0000000..c3d1083
--- /dev/null
+++ b/src/ov-int8.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_INT8
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-int8.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<int8NDArray>;
+
+template class octave_base_int_matrix<int8NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int8_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int8_matrix,
+				     "int8 matrix", "int8");
+
+template class octave_base_scalar<octave_int8>;
+
+template class octave_base_int_scalar<octave_int8>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_int8_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int8_scalar,
+				     "int8 scalar", "int8");
+
+DEFUN (int8, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} int8 (@var{x})\n\
+Convert @var{x} to 8-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (int8);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-int8.h b/src/ov-int8.h
new file mode 100644
index 0000000..a989841
--- /dev/null
+++ b/src/ov-int8.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_int8_h)
+#define octave_int8_h 1
+
+#define OCTAVE_INT_T octave_int8
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_int8_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION int8_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_int8_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION int8_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_int8_type
+
+#define OCTAVE_INT_MX_CLASS mxINT8_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-intx.h b/src/ov-intx.h
new file mode 100644
index 0000000..1b8d063
--- /dev/null
+++ b/src/ov-intx.h
@@ -0,0 +1,705 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-int.h"
+#include "ov-typeinfo.h"
+#include "gripes.h"
+
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+
+class
+OCTINTERP_API
+OCTAVE_VALUE_INT_MATRIX_T
+  : public octave_base_int_matrix<intNDArray<OCTAVE_INT_T> >
+{
+public:
+
+  OCTAVE_VALUE_INT_MATRIX_T (void)
+    : octave_base_int_matrix<intNDArray<OCTAVE_INT_T> > () { }
+
+  OCTAVE_VALUE_INT_MATRIX_T (const intNDArray<OCTAVE_INT_T>& nda)
+    : octave_base_int_matrix<intNDArray<OCTAVE_INT_T> > (nda) { }
+
+  OCTAVE_VALUE_INT_MATRIX_T (const ArrayN<OCTAVE_INT_T>& nda)
+    : octave_base_int_matrix<intNDArray<OCTAVE_INT_T> >
+        (intNDArray<OCTAVE_INT_T> (nda)) { }
+
+  ~OCTAVE_VALUE_INT_MATRIX_T (void) { }
+
+  octave_base_value *clone (void) const
+    { return new OCTAVE_VALUE_INT_MATRIX_T (*this); }
+
+  octave_base_value *empty_clone (void) const
+    { return new OCTAVE_VALUE_INT_MATRIX_T (); }
+
+  bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
+
+  bool is_integer_type (void) const { return true; }
+
+private:
+
+  template <class IM>
+  IM convert_gripe () const
+    {
+      typedef typename IM::element_type dest_el_type;
+      typedef intNDArray<OCTAVE_INT_T>::element_type src_el_type;
+      dest_el_type::clear_conv_flag ();
+      IM retval (matrix);
+      if (dest_el_type::get_trunc_flag ())
+	gripe_truncated_conversion (src_el_type::type_name (),
+				    dest_el_type::type_name ());
+      dest_el_type::clear_conv_flag ();
+      return retval;
+    }
+
+public:
+
+  int8NDArray
+  int8_array_value (void) const { return convert_gripe<int8NDArray> (); }
+
+  int16NDArray
+  int16_array_value (void) const { return convert_gripe<int16NDArray> (); }
+
+  int32NDArray
+  int32_array_value (void) const { return convert_gripe<int32NDArray> (); }
+
+  int64NDArray
+  int64_array_value (void) const { return convert_gripe<int64NDArray> (); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return convert_gripe<uint8NDArray> (); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return convert_gripe<uint16NDArray> (); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return convert_gripe<uint32NDArray> (); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return convert_gripe<uint64NDArray> (); }
+
+  double
+  double_value (bool = false) const
+    {
+      double retval = lo_ieee_nan_value ();
+
+      if (numel () > 0)
+	{
+	  gripe_implicit_conversion ("Octave:array-as-scalar",
+				     type_name (), "real scalar");
+
+	  retval = matrix(0).double_value ();
+	}
+      else
+	gripe_invalid_conversion (type_name (), "real scalar");
+
+      return retval;
+      
+    }
+
+  float
+  float_value (bool = false) const
+    {
+      float retval = lo_ieee_float_nan_value ();
+
+      if (numel () > 0)
+	{
+	  gripe_implicit_conversion ("Octave:array-as-scalar",
+				     type_name (), "real scalar");
+
+	  retval = matrix(0).float_value ();
+	}
+      else
+	gripe_invalid_conversion (type_name (), "real scalar");
+
+      return retval;
+      
+    }
+
+  double scalar_value (bool = false) const { return double_value (); }
+
+  float float_scalar_value (bool = false) const { return float_value (); }
+
+  Matrix
+  matrix_value (bool = false) const
+    {
+      Matrix retval;
+      dim_vector dv = dims ();
+      if (dv.length () > 2)
+	error ("invalid conversion of %s to Matrix", type_name().c_str ());
+      else
+	{
+	  retval = Matrix (dv(0), dv(1));
+	  double *vec = retval.fortran_vec ();
+	  octave_idx_type nel = matrix.numel ();
+	  for (octave_idx_type i = 0; i < nel; i++)
+	    vec[i] = matrix(i).double_value ();
+	}
+      return retval;
+    }
+
+  FloatMatrix
+  float_matrix_value (bool = false) const
+    {
+      FloatMatrix retval;
+      dim_vector dv = dims ();
+      if (dv.length () > 2)
+	error ("invalid conversion of %s to FloatMatrix", type_name().c_str ());
+      else
+	{
+	  retval = FloatMatrix (dv(0), dv(1));
+	  float *vec = retval.fortran_vec ();
+	  octave_idx_type nel = matrix.numel ();
+	  for (octave_idx_type i = 0; i < nel; i++)
+	    vec[i] = matrix(i).float_value ();
+	}
+      return retval;
+    }
+
+  ComplexMatrix
+  complex_matrix_value (bool = false) const
+    {
+      ComplexMatrix retval;
+      dim_vector dv = dims();
+      if (dv.length () > 2)
+	error ("invalid conversion of %s to Matrix", type_name().c_str ());
+      else
+	{
+	  retval = ComplexMatrix (dv(0), dv(1));
+	  Complex *vec = retval.fortran_vec ();
+	  octave_idx_type nel = matrix.numel ();
+	  for (octave_idx_type i = 0; i < nel; i++)
+	    vec[i] = Complex (matrix(i).double_value ());
+	}
+      return retval;
+    }
+
+  FloatComplexMatrix
+  float_complex_matrix_value (bool = false) const
+    {
+      FloatComplexMatrix retval;
+      dim_vector dv = dims();
+      if (dv.length () > 2)
+	error ("invalid conversion of %s to FloatMatrix", type_name().c_str ());
+      else
+	{
+	  retval = FloatComplexMatrix (dv(0), dv(1));
+	  FloatComplex *vec = retval.fortran_vec ();
+	  octave_idx_type nel = matrix.numel ();
+	  for (octave_idx_type i = 0; i < nel; i++)
+	    vec[i] = FloatComplex (matrix(i).float_value ());
+	}
+      return retval;
+    }
+
+  NDArray
+  array_value (bool = false) const
+    { 
+      NDArray retval (matrix.dims ()); 
+      double *vec = retval.fortran_vec ();
+      octave_idx_type nel = matrix.numel ();
+      for (octave_idx_type i = 0; i < nel; i++)
+        vec[i] = matrix(i).double_value ();
+      return retval;
+    }
+
+  FloatNDArray
+  float_array_value (bool = false) const
+    { 
+      FloatNDArray retval (matrix.dims ()); 
+      float *vec = retval.fortran_vec ();
+      octave_idx_type nel = matrix.numel ();
+      for (octave_idx_type i = 0; i < nel; i++)
+        vec[i] = matrix(i).float_value ();
+      return retval;
+    }
+
+  ComplexNDArray
+  complex_array_value (bool = false) const
+    { 
+      ComplexNDArray retval (matrix.dims ()); 
+      Complex *vec = retval.fortran_vec ();
+      octave_idx_type nel = matrix.numel ();
+      for (octave_idx_type i = 0; i < nel; i++)
+        vec[i] = Complex (matrix(i).double_value ());
+      return retval;
+    }
+
+  FloatComplexNDArray
+  float_complex_array_value (bool = false) const
+    { 
+      FloatComplexNDArray retval (matrix.dims ()); 
+      FloatComplex *vec = retval.fortran_vec ();
+      octave_idx_type nel = matrix.numel ();
+      for (octave_idx_type i = 0; i < nel; i++)
+        vec[i] = FloatComplex (matrix(i).float_value ());
+      return retval;
+    }
+
+  boolNDArray
+  bool_array_value (bool warn = false) const
+  {
+    boolNDArray retval (dims ());
+
+    octave_idx_type nel = numel ();
+
+    if (warn && matrix.any_element_not_one_or_zero ())
+      gripe_logical_conversion ();
+
+    bool *vec = retval.fortran_vec ();
+    for (octave_idx_type i = 0; i < nel; i++)
+      vec[i] = matrix(i).bool_value ();
+
+    return retval;
+  }
+
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dims ());
+
+    octave_idx_type nel = numel ();
+  
+    char *vec = retval.fortran_vec ();
+    for (octave_idx_type i = 0; i < nel; i++)
+      vec[i] = matrix(i).char_value ();
+
+    return retval;
+  }
+
+  void increment (void) 
+   { 
+     matrix += OCTAVE_INT_T (1); 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("++", type_name (). c_str ());
+
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
+
+  void decrement (void)
+   { 
+     matrix -= OCTAVE_INT_T (1); 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("--", type_name (). c_str ());
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
+
+  idx_vector index_vector (void) const { return idx_vector (matrix); }
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return matrix.mex_get_data (); }
+
+  mxArray *as_mxArray (void) const
+  {
+    mxArray *retval = new mxArray (OCTAVE_INT_MX_CLASS, dims (), mxREAL);
+
+    OCTAVE_INT_T::val_type *pr = static_cast<OCTAVE_INT_T::val_type *> (retval->get_data ());
+
+    mwSize nel = numel ();
+
+    const OCTAVE_INT_T *p = matrix.data ();
+
+    for (mwIndex i = 0; i < nel; i++)
+      pr[i] = p[i].value ();
+
+    return retval;
+  }
+
+#define MAT_MAPPER(FCN) \
+  octave_value FCN (void) const { return matrix.FCN (); }
+
+  MAT_MAPPER (abs)
+  MAT_MAPPER (signum)
+
+#undef MAT_MAPPER
+
+  octave_value imag (void) const
+  {
+    return intNDArray<OCTAVE_INT_T> (matrix.dims (),
+				     static_cast<OCTAVE_INT_T>(0));
+  }
+
+#define NO_OP_MAPPER(FCN) \
+  octave_value FCN (void) const { return octave_value (matrix); }
+
+  NO_OP_MAPPER (ceil)
+  NO_OP_MAPPER (conj)
+  NO_OP_MAPPER (fix)
+  NO_OP_MAPPER (floor)
+  NO_OP_MAPPER (real)
+  NO_OP_MAPPER (round)
+  NO_OP_MAPPER (roundb)
+
+#undef NO_OP_MAPPER
+
+#define BOOL_MAPPER(FCN, VAL) \
+  octave_value FCN (void) const { return boolNDArray (matrix.dims (), VAL); }
+
+  BOOL_MAPPER (finite, true)
+  BOOL_MAPPER (isinf, false)
+  BOOL_MAPPER (isna, false)
+  BOOL_MAPPER (isnan, false)
+
+#undef BOOL_MAPPER
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+class
+OCTINTERP_API
+OCTAVE_VALUE_INT_SCALAR_T
+  : public octave_base_int_scalar<OCTAVE_INT_T>
+{
+public:
+
+  OCTAVE_VALUE_INT_SCALAR_T (void)
+    : octave_base_int_scalar<OCTAVE_INT_T> () { }
+
+  OCTAVE_VALUE_INT_SCALAR_T (const OCTAVE_INT_T& nda)
+    : octave_base_int_scalar<OCTAVE_INT_T> (nda) { }
+
+  ~OCTAVE_VALUE_INT_SCALAR_T (void) { }
+
+  octave_base_value *clone (void) const
+    { return new OCTAVE_VALUE_INT_SCALAR_T (*this); }
+
+  octave_base_value *empty_clone (void) const
+    { return new OCTAVE_VALUE_INT_MATRIX_T (); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false)
+    {
+      // FIXME -- this doesn't solve the problem of
+      //
+      //   a = 1; a([1,1], [1,1], [1,1])
+      //
+      // and similar constructions.  Hmm...
+
+      // FIXME -- using this constructor avoids narrowing the
+      // 1x1 matrix back to a scalar value.  Need a better solution
+      // to this problem.
+
+      octave_value tmp
+        (new OCTAVE_VALUE_INT_MATRIX_T
+         (OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION ())); 
+
+      return tmp.do_index_op (idx, resize_ok);
+    }
+
+  bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
+
+  bool is_integer_type (void) const { return true; }
+
+private:
+
+  template <class IS>
+  IS convert_gripe () const
+    {
+      typedef IS dest_el_type;
+      typedef OCTAVE_INT_T src_el_type;
+      dest_el_type::clear_conv_flag ();
+      IS retval (scalar);
+
+      if (dest_el_type::get_trunc_flag ())
+	gripe_truncated_conversion (src_el_type::type_name (),
+				    dest_el_type::type_name ());
+      dest_el_type::clear_conv_flag ();
+      return retval;
+    }
+
+public:
+
+  octave_int8
+  int8_scalar_value (void) const { return convert_gripe<octave_int8> (); }
+
+  octave_int16
+  int16_scalar_value (void) const { return convert_gripe<octave_int16> (); }
+
+  octave_int32
+  int32_scalar_value (void) const { return convert_gripe<octave_int32> (); }
+
+  octave_int64
+  int64_scalar_value (void) const { return convert_gripe<octave_int64> (); }
+
+  octave_uint8
+  uint8_scalar_value (void) const { return convert_gripe<octave_uint8> (); }
+
+  octave_uint16
+  uint16_scalar_value (void) const { return convert_gripe<octave_uint16> (); }
+
+  octave_uint32
+  uint32_scalar_value (void) const { return convert_gripe<octave_uint32> (); }
+
+  octave_uint64
+  uint64_scalar_value (void) const { return convert_gripe<octave_uint64> (); }
+
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), int8_scalar_value ()); }
+
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), int16_scalar_value ()); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), int32_scalar_value ()); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), int64_scalar_value ()); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), uint8_scalar_value ()); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), uint16_scalar_value ()); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), uint32_scalar_value ()); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), uint64_scalar_value ()); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const
+    {
+      if (fill)
+	{
+	  intNDArray<OCTAVE_INT_T> retval (dv, 0);
+	  if (dv.numel())
+	    retval(0) = scalar;
+	  return retval;
+	}
+      else
+	{
+	  intNDArray<OCTAVE_INT_T> retval (dv);
+	  if (dv.numel())
+	    retval(0) = scalar;
+	  return retval;
+	}
+    }
+
+  double double_value (bool = false) const { return scalar.double_value (); }
+
+  float float_value (bool = false) const { return scalar.float_value (); }
+
+  double scalar_value (bool = false) const { return scalar.double_value (); }
+
+  float float_scalar_value (bool = false) const { return scalar.float_value (); }
+
+  Matrix
+  matrix_value (bool = false) const
+    {
+      Matrix retval (1, 1);
+      retval(0,0) = scalar.double_value ();
+      return retval;
+    }
+
+  FloatMatrix
+  float_matrix_value (bool = false) const
+    {
+      FloatMatrix retval (1, 1);
+      retval(0,0) = scalar.float_value ();
+      return retval;
+    }
+
+  ComplexMatrix
+  complex_matrix_value (bool = false) const
+    {
+      ComplexMatrix retval (1, 1);
+      retval(0,0) = Complex (scalar.double_value ());
+      return retval;
+    }
+
+  FloatComplexMatrix
+  float_complex_matrix_value (bool = false) const
+    {
+      FloatComplexMatrix retval (1, 1);
+      retval(0,0) = FloatComplex (scalar.float_value ());
+      return retval;
+    }
+
+  NDArray
+  array_value (bool = false) const
+    { 
+      NDArray retval (dim_vector (1, 1)); 
+      retval(0) = scalar.double_value ();
+      return retval;
+    }
+
+  FloatNDArray
+  float_array_value (bool = false) const
+    { 
+      FloatNDArray retval (dim_vector (1, 1)); 
+      retval(0) = scalar.float_value ();
+      return retval;
+    }
+
+  ComplexNDArray
+  complex_array_value (bool = false) const
+    { 
+      ComplexNDArray retval (dim_vector (1, 1));
+      retval(0) = FloatComplex (scalar.double_value ());
+      return retval;
+    }
+
+  FloatComplexNDArray
+  float_complex_array_value (bool = false) const
+    { 
+      FloatComplexNDArray retval (dim_vector (1, 1));
+      retval(0) = FloatComplex (scalar.float_value ());
+      return retval;
+    }
+
+  boolNDArray
+  bool_array_value (bool warn = false) const
+  {
+    boolNDArray retval (dim_vector (1, 1));
+
+    if (warn && scalar != 0.0 && scalar != 1.0)
+      gripe_logical_conversion ();
+
+    retval(0) = scalar.bool_value ();
+
+    return retval;
+  }
+
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = scalar.char_value ();
+    return retval;
+  }
+
+  void increment (void) 
+   { 
+     scalar += OCTAVE_INT_T (1); 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("++", type_name (). c_str ());
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
+
+  void decrement (void)
+   { 
+     scalar -= OCTAVE_INT_T (1); 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("--", type_name (). c_str ());
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
+
+  idx_vector index_vector (void) const { return idx_vector (scalar); }
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, octave_idx_type skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      return os.write (OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (),
+		       block_size, output_type, skip, flt_fmt);
+    }
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return scalar.mex_get_data (); }
+
+  mxArray *as_mxArray (void) const
+  {
+    mxArray *retval = new mxArray (OCTAVE_INT_MX_CLASS, 1, 1, mxREAL);
+
+    OCTAVE_INT_T::val_type *pr = static_cast<OCTAVE_INT_T::val_type *> (retval->get_data ());
+
+    pr[0] = scalar.value ();
+
+    return retval;
+  }
+
+#define SCALAR_MAPPER(FCN) \
+  octave_value FCN (void) const { return scalar.FCN (); }
+
+  SCALAR_MAPPER (abs)
+  SCALAR_MAPPER (signum)
+
+#undef SCALAR_MAPPER
+
+  octave_value imag (void) const { return static_cast<OCTAVE_INT_T>(0); }
+
+#define NO_OP_MAPPER(FCN) \
+  octave_value FCN (void) const { return octave_value (scalar); }
+
+  NO_OP_MAPPER (ceil)
+  NO_OP_MAPPER (conj)
+  NO_OP_MAPPER (fix)
+  NO_OP_MAPPER (floor)
+  NO_OP_MAPPER (real)
+  NO_OP_MAPPER (round)
+  NO_OP_MAPPER (roundb)
+
+#undef NO_OP_MAPPER
+
+#define BOOL_MAPPER(FCN, VAL) octave_value FCN (void) const { return VAL; }
+
+  BOOL_MAPPER (finite, true)
+  BOOL_MAPPER (isinf, false)
+  BOOL_MAPPER (isna, false)
+  BOOL_MAPPER (isnan, false)
+
+#undef BOOL_MAPPER
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-list.cc b/src/ov-list.cc
new file mode 100644
index 0000000..f9aba59
--- /dev/null
+++ b/src/ov-list.cc
@@ -0,0 +1,760 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <sstream>
+
+#include "lo-utils.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "ov.h"
+#include "ov-list.h"
+#include "unwind-prot.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-oct-binary.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_list);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_list, "list", "list");
+
+octave_list::octave_list (const Cell& c)
+  : octave_base_value (), data ()
+{
+  octave_idx_type n = c.length ();
+
+  data.resize (dim_vector (1, n));
+
+  for (octave_idx_type i = 0; i < n; i++)
+    data(i) = c(i);
+}
+
+octave_value_list
+octave_list::subsref (const std::string& type,
+		      const std::list<octave_value_list>& idx, int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	octave_value_list tmp_idx = idx.front ();
+
+	if (tmp_idx.length () == 1)
+	  {
+	    Cell tmp = data.index (tmp_idx (0));
+
+	    retval(0) = octave_value (new octave_list (tmp));
+	  }
+	else
+	  error ("only one index allowed for lists");
+      }
+      break;
+
+    case '{':
+      {
+	octave_value_list tmp_idx = idx.front ();
+
+	if (tmp_idx.length () == 1)
+	  {
+	    Cell tmp = data.index (tmp_idx (0));
+
+	    if (tmp.length () == 1)
+	      retval(0) = tmp(0);
+	    else
+	      retval(0) = octave_value (tmp, true);
+	  }
+	else
+	  error ("only one index allowed for lists");
+      }
+      break;
+
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+
+  if (idx.size () > 1)
+    retval = retval(0).next_subsref (nargout, type, idx);
+
+  return retval;
+}
+
+octave_value
+octave_list::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  octave_value retval;
+
+  if (idx.length () == 1)
+    {
+      Cell tcell = data.index (idx (0), resize_ok);
+
+      octave_value_list result;
+
+      octave_idx_type n = tcell.numel ();
+
+      result.resize (n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	result(i) = tcell(i);
+
+      retval = result;
+    }
+  else
+    error ("only one index allowed for lists");
+
+  return retval;
+}
+
+octave_value
+octave_list::subsasgn (const std::string& type,
+		       const std::list<octave_value_list>& idx,
+		       const octave_value& rhs)
+{
+  octave_value retval;
+
+  octave_idx_type n = type.length ();
+
+  octave_value t_rhs = rhs;
+
+  if (idx.front ().empty ())
+    {
+      error ("missing index in indexed assignment");
+      return retval;
+    }
+
+  if (n > 1)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    octave_value tmp = do_index_op (idx.front (), true);
+
+	    if (! tmp.is_defined ())
+	      tmp = octave_value::empty_conv (type.substr (1), rhs);
+
+	    if (! error_state)
+	      {
+		std::list<octave_value_list> next_idx (idx);
+
+		next_idx.erase (next_idx.begin ());
+
+		t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs);
+	      }
+	  }
+	  break;
+
+	case '{':
+	case '.':
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+
+  if (! error_state)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    octave_value_list i = idx.front ();
+
+	    data.assign (i, Cell (t_rhs), Cell::resize_fill_value ());
+
+	    count++;
+	    retval = octave_value (this);
+	  }
+	  break;
+
+	case '{':
+	case '.':
+	  {
+	    std::string nm = type_name ();
+	    error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+	  }
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+
+  return retval;
+}
+
+void
+octave_list::assign (const octave_value_list& idx, const octave_value& rhs)
+{
+  if (idx.length () == 1)
+    {
+      int i = idx(0).int_value (true);
+
+      if (! error_state)
+	{
+	  octave_idx_type n = data.length ();
+
+	  if (i > 0)
+	    {
+	      if (i > n)
+		warning_with_id ("Octave:resize-on-range-error",
+				 "list index = %d out of range", i);
+
+	      data(i-1) = rhs;
+	    }
+	  else
+	    error ("list index = %d out of range", i);
+	}
+      else
+	error ("list index must be an integer");
+    }
+  else
+    error ("lists may only be indexed by a single scalar");
+}
+
+size_t
+octave_list::byte_size (void) const
+{
+  size_t retval = 0;
+
+  for (octave_idx_type i = 0; i < numel (); i++)
+    retval += data(i).byte_size ();
+
+  return retval;
+}
+
+octave_value_list
+octave_list::list_value (void) const
+{
+  octave_value_list retval;
+
+  octave_idx_type n = data.length ();
+
+  retval.resize (n);
+  
+  for (octave_idx_type i = 0; i < n; i++)
+    retval(i) = data(i);
+
+  return retval;
+}
+
+void
+octave_list::print (std::ostream& os, bool) const
+{
+  print_raw (os);
+}
+
+void
+octave_list::print_raw (std::ostream& os, bool) const
+{
+  unwind_protect::begin_frame ("octave_list_print");
+
+  octave_idx_type n = data.length ();
+
+  if (n > 0)
+    {
+      indent (os);
+      os << "(";
+      newline (os);
+
+      increment_indent_level ();
+
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  std::ostringstream buf;
+
+	  buf << "[" << i+1 << "]";
+
+	  octave_value val = data(i);
+
+	  val.print_with_name (os, buf.str ());
+	}
+
+      decrement_indent_level ();
+
+      indent (os);
+      os << ")";
+    }
+  else
+    os << "()";
+
+  newline (os);
+
+  unwind_protect::run_frame ("octave_list_print");
+}
+
+bool
+octave_list::print_name_tag (std::ostream& os, const std::string& name) const
+{
+  indent (os);
+  if (data.length () == 0)
+    os << name << " = ";
+  else
+    {
+      os << name << " =";
+      newline (os);
+    }
+  return false;
+}
+
+DEFUN (list, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} list (@var{a1}, @var{a2}, @dots{})\n\
+Create a new list with elements given by the arguments @var{a1},\n\
+ at var{a2}, @dots{}.\n\
+ at end deftypefn")
+{
+  static bool warned = false;
+
+  if (! warned)
+    {
+      warning ("list objects are deprecated; use cell arrays instead");
+      warned = true;
+    }
+
+  return octave_value (args);
+}
+
+DEFUN (nth, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} nth (@var{list}, @var{n})\n\
+Return the @var{n}-th element of @var{list}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      octave_value_list lst = args(0).list_value ();
+
+      if (! error_state)
+	{
+	  int n = args(1).int_value (true);
+
+	  if (! error_state)
+	    {
+	      if (n > 0 && n <= lst.length ())
+		retval = lst(n-1);
+	      else
+		error ("nth: index = %d out of range", n);
+	    }
+	  else
+	    error ("nth: second argument must be an integer");
+	}
+      else
+	error ("nth: first argument must be a list");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (append, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} append (@var{list}, @var{a1}, @var{a2}, @dots{})\n\
+Return a new list created by appending @var{a1}, @var{a2}, @dots{}, to\n\
+ at var{list}.  If any of the arguments to be appended is a list, its\n\
+elements are appended individually.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+x = list (1, 2);\n\
+y = list (3, 4);\n\
+append (x, y);\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+results in the list containing the four elements @samp{(1 2 3 4)}, not\n\
+a list containing the three elements @samp{(1 2 (3 4))}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 1)
+    {
+      octave_value_list tmp = args(0).list_value ();
+
+      if (! error_state)
+	{
+	  for (int i = 1; i < nargin; i++)
+	    {
+	      octave_value ov = args(i);
+
+	      if (ov.is_list ())
+		tmp.append (ov.list_value ());
+	      else
+		tmp.append (ov);
+	    }
+
+	  retval = octave_value (tmp);
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (reverse, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} reverse (@var{list})\n\
+Return a new list created by reversing the elements of @var{list}.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value_list tmp = args(0).list_value ();
+
+      if (! error_state)
+	  retval = octave_value (tmp.reverse ());
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (splice, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} splice (@var{list_1}, @var{offset}, @var{length}, @var{list_2})\n\
+Replace @var{length} elements of @var{list_1} beginning at\n\
+ at var{offset} with the contents of @var{list_2} (if any).  If\n\
+ at var{length} is omitted, all elements from @var{offset} to the end of\n\
+ at var{list_1} are replaced.  As a special case, if @var{offset} is one\n\
+greater than the length of @var{list_1} and @var{length} is 0, splice\n\
+is equivalent to @code{append (@var{list_1}, @var{list_2})}.\n\
+ at end deftypefn") 
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 1 && nargin < 5)
+    {
+      octave_value_list list_1 = args(0).list_value ();
+
+      if (! error_state)
+	{
+	  int offset = args(1).int_value (true);
+
+	  if (! error_state)
+	    {
+	      offset--;
+
+	      int length = 0;
+
+	      octave_value_list list_2;
+
+	      if (nargin < 3)
+		length = list_1.length () - offset;
+	      else
+		{
+		  length = args(2).int_value (true);
+
+		  if (! error_state)
+		    {
+		      if (nargin == 4)
+			{
+			  list_2 = args(3).list_value ();
+
+			  if (error_state)
+			    error ("splice: fourth argument must be a list");
+			}
+		    }
+		  else
+		    error ("splice: LENGTH must be an integer");
+		}
+
+	      if (! error_state)
+		retval = octave_value (list_1.splice (offset, length, list_2));
+	    }
+	  else
+	    error ("splice: OFFSET must be an integer");
+	}
+      else
+	error ("splice: first argument must be a list");      
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+bool 
+octave_list::save_ascii (std::ostream& os)
+{
+  octave_value_list lst = list_value ();
+  os << "# length: " << lst.length () << "\n";
+
+  for (int i = 0; i < lst.length (); ++i)
+    {
+      // should we use lst.name_tags () to label the elements?
+
+      std::ostringstream buf;
+      buf << "_" << i;
+      std::string s = buf.str ();
+
+      bool b = save_ascii_data (os, lst (i), s.c_str (), false, 0);
+      
+      if (! b)
+	return false;
+    }
+
+  return true;
+}
+
+bool 
+octave_list::load_ascii (std::istream& is)
+{
+  int len = 0;
+  bool success = true;
+
+  if (extract_keyword (is, "length", len) && len >= 0)
+    {
+      if (len > 0)
+	{
+	  octave_value_list lst;
+
+	  for (int j = 0; j < len; j++)
+	    {
+	      octave_value t2;
+	      bool dummy;
+
+	      // recurse to read list elements
+	      std::string nm
+		= read_ascii_data (is, std::string (), dummy, t2, j);
+
+	      if (!is)
+		break;
+
+	      lst.append (t2);
+	    }
+
+	  if (is) 
+	    data = lst;
+	  else
+	    {
+	      error ("load: failed to load list");
+	      success = false;
+	    }
+	}
+      else if (len == 0 )
+	data = Cell (0, 0);
+      else
+	panic_impossible ();
+    }
+  else {
+    error ("load: failed to extract number of elements in list");
+    success = false;
+  }
+
+  return success;
+}
+
+bool 
+octave_list::save_binary (std::ostream& os, bool& save_as_floats)
+{
+  octave_value_list lst = list_value ();
+
+  int32_t len = lst.length();
+  os.write (reinterpret_cast<char *> (&len), 4);
+  
+  for (int i = 0; i < lst.length (); i++)
+    {
+      // should we use lst.name_tags () to label the elements?
+
+      std::ostringstream buf;
+      buf << "_" << i;
+      std::string s = buf.str ();
+
+      // Recurse to print sub-value.
+      bool b = save_binary_data (os, lst(i), s.c_str (), "", 0,
+				 save_as_floats);
+	      
+      if (! b)
+	return false;
+    }
+  
+  return true;
+}
+
+bool 
+octave_list::load_binary (std::istream& is, bool swap,
+			  oct_mach_info::float_format fmt)
+{
+  int32_t len;
+  if (! is.read (reinterpret_cast<char *> (&len), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&len);
+
+  if (len > 0)
+    {
+      octave_value_list lst;
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  octave_value t2;
+	  bool dummy;
+	  std::string doc;
+	  
+	  // recurse to read list elements
+	  std::string nm = read_binary_data (is, swap, fmt, std::string (), 
+					     dummy, t2, doc);
+	  
+	  if (!is)
+	    return false;
+	  
+	  lst.append(t2);
+	}
+
+      if (is)
+	data = lst;
+      else
+	{
+	  error ("load: failed to load list");
+	  return false;
+	}
+
+    }
+  else if (len == 0 )
+    data = Cell (0, 0);
+  else
+    return false;
+  
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_list::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+{
+  hid_t data_hid = -1;
+
+  data_hid = H5Gcreate (loc_id, name, 0);
+  if (data_hid < 0) return false;
+
+  // recursively add each element of the list to this group
+  octave_value_list lst = list_value ();
+
+  for (octave_idx_type i = 0; i < lst.length (); ++i)
+    {
+      // should we use lst.name_tags () to label the elements?
+
+      std::ostringstream buf;
+      buf << "_" << i;
+      std::string s = buf.str ();
+
+      bool retval2 = add_hdf5_data (data_hid, lst (i), s.c_str (), "",
+				    false, save_as_floats);
+      if (! retval2)
+	break;
+    }
+
+  H5Gclose (data_hid);
+
+  return true;
+}
+
+bool
+octave_list::load_hdf5 (hid_t loc_id,  const char *name,
+			bool have_h5giterate_bug)
+{
+  bool retval = false;
+
+  hdf5_callback_data dsub;
+
+  herr_t retval2 = -1;
+  octave_value_list lst;
+  int current_item = 0;
+#ifdef HAVE_H5GGET_NUM_OBJS
+  hsize_t num_obj = 0;
+  hid_t group_id = H5Gopen (loc_id, name); 
+  H5Gget_num_objs (group_id, &num_obj);
+  H5Gclose (group_id);
+
+  while (current_item < static_cast<int> (num_obj)
+	 && (retval2 = H5Giterate (loc_id, name, &current_item,
+				   hdf5_read_next_data, &dsub)) > 0)
+#else
+  while ((retval2 = H5Giterate (loc_id, name, &current_item,
+				hdf5_read_next_data, &dsub)) > 0)
+#endif
+    {
+      lst.append (dsub.tc);
+
+      if (have_h5giterate_bug)
+	current_item++;  // H5Giterate returned the last index processed
+    }
+
+  if (retval2 >= 0)
+    {
+      data = lst;
+      retval = true;
+    }
+  
+  return retval;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-list.h b/src/ov-list.h
new file mode 100644
index 0000000..cd1630c
--- /dev/null
+++ b/src/ov-list.h
@@ -0,0 +1,135 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_list_h)
+#define octave_list_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "error.h"
+#include "oct-alloc.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+class tree_walker;
+
+// Lists.
+
+class
+octave_list : public octave_base_value
+{
+public:
+
+  octave_list (void)
+    : octave_base_value () { }
+
+  octave_list (const octave_value_list& l)
+    : octave_base_value (), data (l) { }
+
+  octave_list (const Cell& c);
+
+  octave_list (const octave_list& l)
+    : octave_base_value (), data (l.data) { }
+
+  ~octave_list (void) { }
+
+  octave_base_value *clone (void) const { return new octave_list (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_list (); }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  void assign (const octave_value_list& idx, const octave_value& rhs);
+
+  dim_vector dims (void) const { return dim_vector (1, data.length ()); }
+
+  size_t byte_size (void) const;
+
+  bool is_defined (void) const { return true; }
+
+  bool is_list (void) const { return true; }
+
+  octave_value_list list_value (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+protected:
+
+  // The list of Octave values.
+  Cell data;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-mex-fcn.cc b/src/ov-mex-fcn.cc
new file mode 100644
index 0000000..89ef961
--- /dev/null
+++ b/src/ov-mex-fcn.cc
@@ -0,0 +1,167 @@
+/*
+
+Copyright (C) 1996, 1997, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-shlib.h"
+
+#include <defaults.h>
+#include "dynamic-ld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov-mex-fcn.h"
+#include "ov.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_mex_function);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_mex_function,
+				     "mex function", "mex function");
+
+octave_mex_function::octave_mex_function
+  (void *fptr, bool fmex, const octave_shlib& shl,
+   const std::string& nm)
+  : octave_function (nm), mex_fcn_ptr (fptr), exit_fcn_ptr (0),
+    have_fmex (fmex), sh_lib (shl)
+{
+  mark_fcn_file_up_to_date (time_parsed ());
+
+  std::string file_name = fcn_file_name ();
+
+  system_fcn_file
+    = (! file_name.empty ()
+       && Voct_file_dir == file_name.substr (0, Voct_file_dir.length ()));
+}
+
+octave_mex_function::~octave_mex_function (void)
+{
+  if (exit_fcn_ptr)
+    (*exit_fcn_ptr) ();
+
+  octave_dynamic_loader::remove_mex (my_name, sh_lib);
+}
+
+std::string
+octave_mex_function::fcn_file_name (void) const
+{
+  return sh_lib.file_name ();
+}
+
+octave_time
+octave_mex_function::time_parsed (void) const
+{
+  return sh_lib.time_loaded ();
+}
+
+octave_value_list
+octave_mex_function::subsref (const std::string& type,
+			      const std::list<octave_value_list>& idx,
+			      int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
+
+	retval = do_multi_index_op (tmp_nargout, idx.front ());
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+  //
+  // FIXME -- Note that if a function call returns multiple
+  // values, and there is further indexing to perform, then we are
+  // ignoring all but the first value.  Is this really what we want to
+  // do?  If it is not, then what should happen for stat("file").size,
+  // for exmaple?
+
+  if (idx.size () > 1)
+    retval = retval(0).next_subsref (nargout, type, idx);
+
+  return retval;
+}
+
+// FIXME -- shouldn't this declaration be a header file somewhere?
+extern octave_value_list
+call_mex (bool have_fmex, void *f, const octave_value_list& args,
+	  int nargout, octave_mex_function *curr_mex_fcn);
+
+octave_value_list
+octave_mex_function::do_multi_index_op (int nargout,
+					const octave_value_list& args)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  if (args.has_magic_colon ())
+    ::error ("invalid use of colon in function argument list");
+  else
+    {
+      unwind_protect::begin_frame ("mex_func_eval");
+
+      octave_call_stack::push (this);
+
+      unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+      try
+	{
+	  retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this);
+	}
+      catch (octave_execution_exception)
+	{
+	  gripe_library_execution_error ();
+	}
+
+      unwind_protect::run_frame ("mex_func_eval");
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-mex-fcn.h b/src/ov-mex-fcn.h
new file mode 100644
index 0000000..54d11b2
--- /dev/null
+++ b/src/ov-mex-fcn.h
@@ -0,0 +1,123 @@
+/*
+
+Copyright (C) 1996, 1997, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_mex_function_h)
+#define octave_mex_function_h 1
+
+#include <string>
+
+#include "oct-shlib.h"
+
+#include "ov-fcn.h"
+#include "ov-builtin.h"
+#include "ov-typeinfo.h"
+
+class octave_shlib;
+
+class octave_value;
+class octave_value_list;
+
+// Dynamically-linked functions.
+
+class
+octave_mex_function : public octave_function
+{
+public:
+
+  octave_mex_function (void) { }
+
+  octave_mex_function (void *fptr, bool fmex, const octave_shlib& shl,
+		       const std::string& nm = std::string ());
+
+  ~octave_mex_function (void);
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  octave_function *function_value (bool = false) { return this; }
+
+  const octave_function *function_value (bool = false) const { return this; }
+
+  void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; }
+
+  std::string fcn_file_name (void) const;
+
+  octave_time time_parsed (void) const;
+
+  octave_time time_checked (void) const { return t_checked; }
+
+  bool is_system_fcn_file (void) const { return system_fcn_file; }
+
+  bool is_builtin_function (void) const { return false; }
+
+  bool is_mex_function (void) const { return true; }
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& args);
+
+  void atexit (void (*fcn) (void)) { exit_fcn_ptr = fcn; }
+
+private:
+
+  void *mex_fcn_ptr;
+
+  void (*exit_fcn_ptr) (void);
+
+  bool have_fmex;
+
+  octave_shlib sh_lib;
+
+  // The time the file was last checked to see if it needs to be
+  // parsed again.
+  mutable octave_time t_checked;
+
+  // True if this function came from a file that is considered to be a
+  // system function.  This affects whether we check the time stamp
+  // on the file to see if it has changed.
+  bool system_fcn_file;
+
+  // No copying!
+
+  octave_mex_function (const octave_mex_function& fn);
+
+  octave_mex_function& operator = (const octave_mex_function& fn);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-null-mat.cc b/src/ov-null-mat.cc
new file mode 100644
index 0000000..0d91023
--- /dev/null
+++ b/src/ov-null-mat.cc
@@ -0,0 +1,117 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov-null-mat.h"
+#include "ops.h"
+#include "defun.h"
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_null_matrix, "null_matrix", "double");
+
+const octave_value octave_null_matrix::instance (new octave_null_matrix ());
+
+static octave_base_value *
+default_null_matrix_numeric_conversion_function (const octave_base_value& a)
+{
+  // The cast is not necessary?
+  // CAST_CONV_ARG (const octave_null_matrix&);
+
+  return a.empty_clone ();
+}
+
+octave_base_value::type_conv_info
+octave_null_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_null_matrix_numeric_conversion_function, 
+                                            octave_matrix::static_type_id ());
+}
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_null_str, "null_string", "char");
+
+const octave_value octave_null_str::instance (new octave_null_str ());
+
+static octave_base_value *
+default_null_str_numeric_conversion_function (const octave_base_value& a)
+{
+  // The cast is not necessary?
+  // CAST_CONV_ARG (const octave_null_str&);
+
+  return a.empty_clone ();
+}
+
+octave_base_value::type_conv_info
+octave_null_str::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_null_str_numeric_conversion_function, 
+                                            octave_char_matrix_str::static_type_id ());
+}
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_null_sq_str, "null_sq_string", "char");
+
+const octave_value octave_null_sq_str::instance (new octave_null_sq_str ());
+
+static octave_base_value *
+default_null_sq_str_numeric_conversion_function (const octave_base_value& a)
+{
+  // The cast is not necessary?
+  // CAST_CONV_ARG (const octave_null_sq_str&);
+
+  return a.empty_clone ();
+}
+
+octave_base_value::type_conv_info
+octave_null_sq_str::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_null_sq_str_numeric_conversion_function, 
+                                            octave_char_matrix_sq_str::static_type_id ());
+}
+
+DEFUN (isnull, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isnull (@var{x})\n\
+Return 1 if @var{x} is a special null matrix, string or single quoted string.\n\
+Indexed assignment with such a value as right-hand side should delete array elements.\n\
+This function should be used when overloading indexed assignment for user-defined \n\
+classes instead of @code{isempty}, to distinguish the cases:\n\
+ at table @asis\n\
+ at item @code{A(I) = []}\n\
+This should delete elements if @code{I} is nonempty.\n\
+ at item @code{X = []; A(I) = X}\n\
+This should give an error if @code{I} is nonempty.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 && args(0).is_defined ())
+    retval = args(0).is_null_value ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
diff --git a/src/ov-null-mat.h b/src/ov-null-mat.h
new file mode 100644
index 0000000..ce09995
--- /dev/null
+++ b/src/ov-null-mat.h
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_null_matrix_h)
+#define octave_null_matrix_h 1
+
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-str-mat.h"
+
+// Design rationale:
+// The constructors are hidden. There is only one null matrix (or null string) object,
+// that can have shallow copies. Cloning the object returns just a normal empty matrix,
+// so all the shallow copies are, in fact, read-only. This conveniently ensures that any
+// attempt to fiddle with the null matrix destroys its special status.
+
+// The special [] value.
+
+class
+OCTINTERP_API
+octave_null_matrix : public octave_matrix
+{
+  octave_null_matrix (void) : octave_matrix () { }
+
+public:
+
+  static const octave_value instance;
+
+  bool is_null_value (void) const { return true; }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+private:
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+// The special "" value
+
+class 
+OCTINTERP_API
+octave_null_str : public octave_char_matrix_str
+{
+  octave_null_str (void) : octave_char_matrix_str () { }
+
+public:
+
+  static const octave_value instance;
+
+  bool is_null_value (void) const { return true; }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+
+private:
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+// The special '' value
+
+class 
+OCTINTERP_API
+octave_null_sq_str : public octave_char_matrix_sq_str
+{
+  octave_null_sq_str (void) : octave_char_matrix_sq_str () { }
+
+public:
+
+  static const octave_value instance;
+
+  bool is_null_value (void) const { return true; }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+private:
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
diff --git a/src/ov-perm.cc b/src/ov-perm.cc
new file mode 100644
index 0000000..8bed585
--- /dev/null
+++ b/src/ov-perm.cc
@@ -0,0 +1,491 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "byte-swap.h"
+
+#include "ov-perm.h"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "error.h"
+#include "gripes.h"
+#include "ops.h"
+#include "pr-output.h"
+
+#include "ls-oct-ascii.h"
+
+octave_value
+octave_perm_matrix::subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front ());
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval.next_subsref (type, idx);
+}
+
+octave_value
+octave_perm_matrix::do_index_op (const octave_value_list& idx,
+                                 bool resize_ok)
+{
+  octave_value retval;
+  octave_idx_type nidx = idx.length ();
+  idx_vector idx0, idx1;
+  if (nidx == 2)
+    {
+      idx0 = idx(0).index_vector ();
+      idx1 = idx(1).index_vector ();
+    }
+
+  // This hack is to allow constructing permutation matrices using
+  // eye(n)(p,:), eye(n)(:,q) && eye(n)(p,q) where p & q are permutation
+  // vectors. 
+  // Note that, for better consistency, eye(n)(:,:) still converts to a full
+  // matrix.
+  if (! error_state && nidx == 2)
+    {
+      bool left = idx0.is_permutation (matrix.rows ());
+      bool right = idx1.is_permutation (matrix.cols ());
+
+      if (left && right)
+        {
+          if (idx0.is_colon ()) left = false;
+          if (idx1.is_colon ()) right = false;
+          if (left || right)
+            {
+              PermMatrix p = matrix;
+              if (left)
+                p = PermMatrix (idx0, false) * p;
+              if (right)
+                p = p * PermMatrix (idx1, true);
+              retval = p;
+            }
+          else
+            {
+              retval = this;
+              this->count++;
+            }
+        }
+    }
+
+  // if error_state is set, we've already griped.
+  if (! error_state && ! retval.is_defined ())
+    {
+      if (nidx == 2 && ! resize_ok &&
+          idx0.is_scalar () && idx1.is_scalar ())
+        {
+          retval = matrix.checkelem (idx0(0), idx1(0));
+        }
+      else
+        retval = to_dense ().do_index_op (idx, resize_ok);
+    }
+
+  return retval;
+}
+
+bool
+octave_perm_matrix::is_true (void) const
+{
+  return to_dense ().is_true ();
+}
+
+double
+octave_perm_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion (type_name (), "real scalar");
+
+  return retval;
+}
+
+float
+octave_perm_matrix::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion (type_name (), "real scalar");
+
+  return retval;
+}
+
+Complex
+octave_perm_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion (type_name (), "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_perm_matrix::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 type_name (), "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion (type_name (), "complex scalar");
+
+  return retval;
+}
+
+#define FORWARD_MATRIX_VALUE(TYPE, PREFIX) \
+TYPE \
+octave_perm_matrix::PREFIX ## _value (bool frc_str_conv) const \
+{ \
+  return to_dense ().PREFIX ## _value (frc_str_conv); \
+}
+
+SparseMatrix
+octave_perm_matrix::sparse_matrix_value (bool) const
+{
+  return SparseMatrix (matrix);
+}
+
+SparseComplexMatrix
+octave_perm_matrix::sparse_complex_matrix_value (bool) const
+{
+  return SparseComplexMatrix (sparse_matrix_value ());
+}
+
+FORWARD_MATRIX_VALUE (Matrix, matrix)
+FORWARD_MATRIX_VALUE (FloatMatrix, float_matrix)
+FORWARD_MATRIX_VALUE (ComplexMatrix, complex_matrix)
+FORWARD_MATRIX_VALUE (FloatComplexMatrix, float_complex_matrix)
+
+FORWARD_MATRIX_VALUE (NDArray, array)
+FORWARD_MATRIX_VALUE (FloatNDArray, float_array)
+FORWARD_MATRIX_VALUE (ComplexNDArray, complex_array)
+FORWARD_MATRIX_VALUE (FloatComplexNDArray, float_complex_array)
+
+FORWARD_MATRIX_VALUE (boolNDArray, bool_array)
+FORWARD_MATRIX_VALUE (charNDArray, char_array)
+
+idx_vector
+octave_perm_matrix::index_vector (void) const
+{
+  return to_dense ().index_vector ();
+}
+
+octave_value
+octave_perm_matrix::convert_to_str_internal (bool pad, bool force, char type) const
+{
+  return to_dense ().convert_to_str_internal (pad, force, type);
+}
+
+bool 
+octave_perm_matrix::save_ascii (std::ostream& os)
+{
+  typedef octave_int<octave_idx_type> idx_int_type;
+
+  os << "# size: " << matrix.rows () << "\n";
+  os << "# orient: " << (matrix.is_col_perm () ? 'c' : 'r') << '\n';
+
+  Array<octave_idx_type> pvec = matrix.pvec ();
+  octave_idx_type n = pvec.length ();
+  ColumnVector tmp (n);
+  for (octave_idx_type i = 0; i < n; i++) tmp(i) = pvec(i) + 1;
+  os << tmp;
+
+  return true;
+}
+
+bool 
+octave_perm_matrix::load_ascii (std::istream& is)
+{
+  typedef octave_int<octave_idx_type> idx_int_type;
+  octave_idx_type n;
+  bool success = true;
+  char orient;
+
+  if (extract_keyword (is, "size", n, true)
+      && extract_keyword (is, "orient", orient, true))
+    {
+      bool colp = orient == 'c';
+      dim_vector dv (n);
+      ColumnVector tmp (n);
+      is >> tmp;
+      if (!is) 
+	{
+	  error ("load: failed to load permutation matrix constant");
+	  success = false;
+	}
+      else
+        {
+          Array<octave_idx_type> pvec (n);
+          for (octave_idx_type i = 0; i < n; i++) pvec(i) = tmp(i) - 1;
+          matrix = PermMatrix (pvec, colp);
+
+          // Invalidate cache. Probably not necessary, but safe.
+          dense_cache = octave_value ();
+        }
+    }
+  else
+    {
+      error ("load: failed to extract size & orientation");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_perm_matrix::save_binary (std::ostream& os, bool&)
+{
+
+  int32_t size = matrix.rows ();
+  bool colp = matrix.is_col_perm ();
+  os.write (reinterpret_cast<char *> (&size), 4);
+  os.write (reinterpret_cast<char *> (&colp), 1);
+  os.write (reinterpret_cast<const char *> (matrix.data ()), matrix.byte_size());
+
+  return true;
+}
+
+bool
+octave_perm_matrix::load_binary (std::istream& is, bool swap,
+                                 oct_mach_info::float_format )
+{
+  int32_t size;
+  bool colp;
+  if (! (is.read (reinterpret_cast<char *> (&size), 4)
+         && is.read (reinterpret_cast<char *> (&colp), 1)))
+    return false;
+
+  MArray<octave_idx_type> m (size);
+
+  if (! is.read (reinterpret_cast<char *> (m.fortran_vec ()), m.byte_size ()))
+    return false;
+
+  if (swap)
+    {
+      int nel = m.numel ();
+      for (int i = 0; i < nel; i++) 
+	switch (sizeof (octave_idx_type))
+	  {
+	  case 8:
+	    swap_bytes<8> (&m(i));
+	    break;
+	  case 4:
+	    swap_bytes<4> (&m(i));
+	    break;
+	  case 2:
+	    swap_bytes<2> (&m(i));
+	    break;
+	  case 1:
+	  default:
+	    break;
+	  }
+    }
+
+  matrix = PermMatrix (m, colp);
+  return true;
+}
+
+void
+octave_perm_matrix::print_raw (std::ostream& os,
+                               bool pr_as_read_syntax) const
+{
+  return octave_print_internal (os, matrix, pr_as_read_syntax,
+                                current_print_indent_level ());
+}
+
+mxArray *
+octave_perm_matrix::as_mxArray (void) const
+{
+  return to_dense ().as_mxArray ();
+}
+
+bool
+octave_perm_matrix::print_as_scalar (void) const
+{
+  dim_vector dv = dims ();
+
+  return (dv.all_ones () || dv.any_zero ());
+}
+
+void
+octave_perm_matrix::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+int
+octave_perm_matrix::write (octave_stream& os, int block_size,
+                                oct_data_conv::data_type output_type, int skip,
+                                oct_mach_info::float_format flt_fmt) const
+{ 
+  return to_dense ().write (os, block_size, output_type, skip, flt_fmt); 
+}
+
+void
+octave_perm_matrix::print_info (std::ostream& os,
+				    const std::string& prefix) const
+{
+  matrix.print_info (os, prefix);
+}
+
+
+octave_value
+octave_perm_matrix::to_dense (void) const
+{
+  if (! dense_cache.is_defined ())
+      dense_cache = Matrix (matrix);
+
+  return dense_cache;
+}
+
+#define FORWARD_MAPPER(MAP) \
+  octave_value \
+  octave_perm_matrix::MAP (void) const \
+  { \
+    return to_dense ().MAP (); \
+  }
+
+FORWARD_MAPPER (erf)
+FORWARD_MAPPER (erfc)
+FORWARD_MAPPER (gamma)
+FORWARD_MAPPER (lgamma)
+FORWARD_MAPPER (abs)
+FORWARD_MAPPER (acos)
+FORWARD_MAPPER (acosh)
+FORWARD_MAPPER (angle)
+FORWARD_MAPPER (arg)
+FORWARD_MAPPER (asin)
+FORWARD_MAPPER (asinh)
+FORWARD_MAPPER (atan)
+FORWARD_MAPPER (atanh)
+FORWARD_MAPPER (ceil)
+FORWARD_MAPPER (conj)
+FORWARD_MAPPER (cos)
+FORWARD_MAPPER (cosh)
+FORWARD_MAPPER (exp)
+FORWARD_MAPPER (expm1)
+FORWARD_MAPPER (fix)
+FORWARD_MAPPER (floor)
+FORWARD_MAPPER (imag)
+FORWARD_MAPPER (log)
+FORWARD_MAPPER (log2)
+FORWARD_MAPPER (log10)
+FORWARD_MAPPER (log1p)
+FORWARD_MAPPER (real)
+FORWARD_MAPPER (round)
+FORWARD_MAPPER (roundb)
+FORWARD_MAPPER (signum)
+FORWARD_MAPPER (sin)
+FORWARD_MAPPER (sinh)
+FORWARD_MAPPER (sqrt)
+FORWARD_MAPPER (tan)
+FORWARD_MAPPER (tanh)
+FORWARD_MAPPER (finite)
+FORWARD_MAPPER (isinf)
+FORWARD_MAPPER (isna)
+FORWARD_MAPPER (isnan)
+
+DEFINE_OCTAVE_ALLOCATOR (octave_perm_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_perm_matrix, 
+                                     "permutation matrix", "double");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_perm_matrix&);
+
+  return new octave_matrix (v.matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_perm_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_perm_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.nelem () == 1)
+    retval = new octave_scalar (matrix (0, 0));
+
+  return retval;
+}
+
diff --git a/src/ov-perm.h b/src/ov-perm.h
new file mode 100644
index 0000000..5d7f899
--- /dev/null
+++ b/src/ov-perm.h
@@ -0,0 +1,267 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_perm_matrix_h)
+#define octave_perm_matrix_h 1
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+#include "oct-obj.h"
+
+class 
+OCTINTERP_API
+octave_perm_matrix : public octave_base_value
+{
+public:
+  octave_perm_matrix (void) : matrix () { }
+
+  octave_perm_matrix (const PermMatrix& p) : matrix (p) { }
+
+  octave_base_value *clone (void) const { return new octave_perm_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_perm_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  size_t byte_size (void) const { return matrix.byte_size (); }
+
+  octave_value squeeze (void) const { return matrix; }
+
+  octave_value full_value (void) const { return to_dense (); }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx);
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int)
+    { return subsref (type, idx); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  dim_vector dims (void) const { return matrix.dims (); }
+
+  octave_idx_type nnz (void) const { return matrix.rows (); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return to_dense ().reshape (new_dims); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return to_dense ().permute (vec, inv); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const
+    { return to_dense ().resize (dv, fill); }
+
+  octave_value all (int dim = 0) const { return to_dense ().all (dim); }
+  octave_value any (int dim = 0) const { return to_dense ().any (dim); }
+
+  MatrixType matrix_type (void) const { return MatrixType::Permuted_Diagonal; }
+  MatrixType matrix_type (const MatrixType&) const
+    { return matrix_type (); }
+
+  octave_value diag (octave_idx_type k = 0) const
+    { return to_dense () .diag (k); }
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return to_dense ().sort (dim, mode); }
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return to_dense ().sort (sidx, dim, mode); }
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return to_dense ().is_sorted (mode); }
+
+  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const
+    { return to_dense ().sort_rows_idx (mode); }
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+    { return to_dense ().is_sorted_rows (mode); }
+
+  bool is_perm_matrix (void) const { return true; }
+
+  bool is_matrix_type (void) const { return true; }
+
+  bool is_numeric_type (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  bool is_true (void) const;
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  idx_vector index_vector (void) const;
+
+  PermMatrix perm_matrix_value (void) const
+    { return matrix; }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+   
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+   
+  boolNDArray bool_array_value (bool warn = false) const;
+
+  charNDArray char_array_value (bool = false) const;
+  
+  NDArray array_value (bool = false) const; 
+
+  FloatNDArray float_array_value (bool = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  int8NDArray
+  int8_array_value (void) const { return to_dense ().int8_array_value (); }
+
+  int16NDArray
+  int16_array_value (void) const { return to_dense ().int16_array_value (); }
+
+  int32NDArray
+  int32_array_value (void) const { return to_dense ().int32_array_value (); }
+
+  int64NDArray
+  int64_array_value (void) const { return to_dense ().int64_array_value (); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return to_dense ().uint8_array_value (); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return to_dense ().uint16_array_value (); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return to_dense ().uint32_array_value (); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return to_dense ().uint64_array_value (); }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const;
+
+  mxArray *as_mxArray (void) const;
+
+  bool print_as_scalar (void) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+protected:
+
+  PermMatrix matrix;  
+
+  virtual octave_value to_dense (void) const;
+
+  mutable octave_value dense_cache;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
diff --git a/src/ov-range.cc b/src/ov-range.cc
new file mode 100644
index 0000000..0326901
--- /dev/null
+++ b/src/ov-range.cc
@@ -0,0 +1,560 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+
+#include "gripes.h"
+#include "ops.h"
+#include "oct-obj.h"
+#include "ov-range.h"
+#include "ov-re-mat.h"
+#include "ov-scalar.h"
+#include "pr-output.h"
+
+#include "byte-swap.h"
+#include "ls-ascii-helper.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_range);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_range, "range", "double");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_range&);
+
+  return new octave_matrix (v.matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_range::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_range::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  switch (range.nelem ())
+    {
+    case 1:
+      retval = new octave_scalar (range.base ());
+      break;
+
+    case 0:
+      retval = new octave_matrix (Matrix (1, 0));
+      break;
+
+    case -2:
+      retval = new octave_matrix (range.matrix_value ());
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+octave_value
+octave_range::subsref (const std::string& type,
+		       const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = do_index_op (idx.front ());
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  return retval.next_subsref (type, idx);
+}
+
+octave_value
+octave_range::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // FIXME -- this doesn't solve the problem of
+  //
+  //   a = 1:5; a(1, 1, 1)
+  //
+  // and similar constructions.  Hmm...
+
+  // FIXME -- using this constructor avoids possibly narrowing
+  // the range to a scalar value.  Need a better solution to this
+  // problem.
+
+  octave_value tmp (new octave_matrix (range.matrix_value ()));
+
+  return tmp.do_index_op (idx, resize_ok);
+}
+
+double
+octave_range::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  octave_idx_type nel = range.nelem ();
+
+  if (nel > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "range", "real scalar");
+
+      retval = range.base ();
+    }
+  else
+    gripe_invalid_conversion ("range", "real scalar");
+
+  return retval;
+}
+
+float
+octave_range::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  octave_idx_type nel = range.nelem ();
+
+  if (nel > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "range", "real scalar");
+
+      retval = range.base ();
+    }
+  else
+    gripe_invalid_conversion ("range", "real scalar");
+
+  return retval;
+}
+
+charNDArray
+octave_range::char_array_value (bool) const
+{
+  const Matrix matrix = range.matrix_value ();
+  charNDArray retval (dims ());
+
+  octave_idx_type nel = numel ();
+  
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval.elem (i) = static_cast<char>(matrix.elem (i));
+
+  return retval;
+}
+  
+octave_value
+octave_range::all (int dim) const
+{
+  // FIXME -- this is a potential waste of memory.
+
+  Matrix m = range.matrix_value ();
+
+  return m.all (dim);
+}
+
+octave_value
+octave_range::any (int dim) const
+{
+  // FIXME -- this is a potential waste of memory.
+
+  Matrix m = range.matrix_value ();
+
+  return m.any (dim);
+}
+
+octave_value 
+octave_range::diag (octave_idx_type k) const
+{ 
+  return (k == 0
+          ? octave_value (DiagMatrix (DiagArray2<double> (range.matrix_value ())))
+          : octave_value (range.diag (k))); 
+}
+
+
+bool
+octave_range::is_true (void) const
+{
+  bool retval = false;
+
+  if (range.nelem () != 0)
+    {
+      // FIXME -- this is a potential waste of memory.
+
+      Matrix m ((range.matrix_value () . all ()) . all ());
+
+      retval = (m.rows () == 1 && m.columns () == 1 && m (0, 0) != 0.0);
+    }
+
+  return retval;
+}
+
+Complex
+octave_range::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  octave_idx_type nel = range.nelem ();
+
+  if (nel > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "range", "complex scalar");
+
+      retval = range.base ();
+    }
+  else
+    gripe_invalid_conversion ("range", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_range::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  octave_idx_type nel = range.nelem ();
+
+  if (nel > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "range", "complex scalar");
+
+      retval = range.base ();
+    }
+  else
+    gripe_invalid_conversion ("range", "complex scalar");
+
+  return retval;
+}
+
+octave_value 
+octave_range::resize (const dim_vector& dv, bool fill) const
+{ 
+  NDArray retval = array_value (); 
+  if (fill)
+    retval.resize (dv, NDArray::resize_fill_value());
+  else
+    retval.resize (dv); 
+  return retval; 
+}
+
+octave_value
+octave_range::convert_to_str_internal (bool pad, bool force, char type) const
+{
+  octave_value tmp (range.matrix_value ());
+  return tmp.convert_to_str (pad, force, type);
+}
+
+void
+octave_range::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+void
+octave_range::print_raw (std::ostream& os, bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, range, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+bool
+octave_range::print_name_tag (std::ostream& os, const std::string& name) const
+{
+  bool retval = false;
+
+  octave_idx_type n = range.nelem ();
+
+  indent (os);
+
+  if (n == 0 || n == 1)
+    os << name << " = ";
+  else
+    {
+      os << name << " =";
+      newline (os);
+      newline (os);
+      retval = true;
+    }
+    
+  return retval;
+}
+
+// Skip white space and comments on stream IS.
+
+static void
+skip_comments (std::istream& is)
+{
+  char c = '\0';
+  while (is.get (c))
+    {
+      if (c == ' ' || c == '\t' || c == '\n')
+	; // Skip whitespace on way to beginning of next line.
+      else
+	break;
+    }
+
+  skip_until_newline (is, false);
+}
+
+bool 
+octave_range::save_ascii (std::ostream& os)
+{
+  Range r = range_value ();
+  double base = r.base ();
+  double limit = r.limit ();
+  double inc = r.inc ();
+
+  os << "# base, limit, increment\n";
+  octave_write_double (os, base);
+  os << " ";
+  octave_write_double (os, limit);
+  os << " ";
+  octave_write_double (os, inc);
+  os << "\n";
+
+  return true;
+}
+
+bool 
+octave_range::load_ascii (std::istream& is)
+{
+  // # base, limit, range comment added by save ().
+  skip_comments (is);
+
+  is >> range;
+
+  if (!is)
+    {
+      error ("load: failed to load range constant");
+      return false;
+    }
+
+  return true;
+}
+
+bool 
+octave_range::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+  char tmp = LS_DOUBLE;
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+  Range r = range_value ();
+  double bas = r.base ();
+  double lim = r.limit ();
+  double inc = r.inc ();
+  os.write (reinterpret_cast<char *> (&bas), 8);
+  os.write (reinterpret_cast<char *> (&lim), 8);
+  os.write (reinterpret_cast<char *> (&inc), 8);
+
+  return true;
+}
+
+bool 
+octave_range::load_binary (std::istream& is, bool swap,
+			   oct_mach_info::float_format /* fmt */)
+{
+  char tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    return false;
+  double bas, lim, inc;
+  if (! is.read (reinterpret_cast<char *> (&bas), 8))
+    return false;
+  if (swap)
+    swap_bytes<8> (&bas);
+  if (! is.read (reinterpret_cast<char *> (&lim), 8))
+    return false;
+  if (swap)
+    swap_bytes<8> (&lim);
+  if (! is.read (reinterpret_cast<char *> (&inc), 8))
+    return false;
+  if (swap)
+    swap_bytes<8> (&inc);
+  Range r (bas, lim, inc);
+  range = r;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+// The following subroutines creates an HDF5 representation of the way
+// we will store Octave range types (triplets of floating-point numbers). 
+// NUM_TYPE is the HDF5 numeric type to use for storage (e.g. 
+// H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary 
+// conversions are handled automatically by HDF5.
+
+static hid_t
+hdf5_make_range_type (hid_t num_type)
+{
+  hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3);
+
+  H5Tinsert (type_id, "base", 0 * sizeof (double), num_type);
+  H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type);
+  H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type);
+
+  return type_id;
+}
+
+bool
+octave_range::save_hdf5 (hid_t loc_id, const char *name,
+			 bool /* save_as_floats */)
+{
+  hsize_t dimens[3];
+  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
+  bool retval = true;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0) return false;
+
+  type_hid = hdf5_make_range_type (H5T_NATIVE_DOUBLE);
+  if (type_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      return false;
+    }
+  
+  Range r = range_value ();
+  double range_vals[3];
+  range_vals[0] = r.base ();
+  range_vals[1] = r.limit ();
+  range_vals[2] = r.inc ();
+
+  retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		     range_vals) >= 0;
+
+  H5Dclose (data_hid);
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool 
+octave_range::load_hdf5 (hid_t loc_id, const char *name,
+			 bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t type_hid = H5Dget_type (data_hid);
+
+  hid_t range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE);
+
+  if (! hdf5_types_compatible (type_hid, range_type))
+    {
+      H5Tclose (range_type);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  hid_t space_hid = H5Dget_space (data_hid);
+  hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    {
+      H5Tclose (range_type);
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  double rangevals[3];
+  if (H5Dread (data_hid, range_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
+	       rangevals) >= 0)
+    {
+      retval = true;
+      Range r (rangevals[0], rangevals[1], rangevals[2]);
+      range = r;
+    }
+
+  H5Tclose (range_type);
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_range::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, dims (), mxREAL);
+
+  double *pr = static_cast<double *> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  Matrix m = matrix_value ();
+
+  const double *p = m.data ();
+
+  for (mwSize i = 0; i < nel; i++)
+    pr[i] = p[i];
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-range.h b/src/ov-range.h
new file mode 100644
index 0000000..c5a0127
--- /dev/null
+++ b/src/ov-range.h
@@ -0,0 +1,349 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_range_h)
+#define octave_range_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "Range.h"
+
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Range values.
+
+class
+octave_range : public octave_base_value
+{
+public:
+
+  octave_range (void)
+    : octave_base_value () { }
+
+  octave_range (double base, double limit, double inc)
+    : octave_base_value (), range (base, limit, inc)
+      {
+	if (range.nelem () < 0)
+	  ::error ("invalid range");
+      }
+
+  octave_range (const Range& r)
+    : octave_base_value (), range (r)
+      {
+	if (range.nelem () < 0 && range.nelem () != -2)
+	  ::error ("invalid range");
+      }
+
+  octave_range (const octave_range& r)
+    : octave_base_value (), range (r.range) { }
+
+  ~octave_range (void) { }
+
+  octave_base_value *clone (void) const { return new octave_range (*this); }
+
+  // A range is really just a special kind of real matrix object.  In
+  // the places where we need to call empty_clone, it makes more sense
+  // to create an empty matrix (0x0) instead of an empty range (1x0).
+  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx);
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx, int)
+    { return subsref (type, idx); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  idx_vector index_vector (void) const { return idx_vector (range); }
+
+  dim_vector dims (void) const
+    { 
+      octave_idx_type n = range.nelem ();
+      return dim_vector (n > 0, n);
+    }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+
+  size_t byte_size (void) const { return 3 * sizeof (double); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return NDArray (array_value().reshape (new_dims)); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return NDArray (array_value().permute (vec, inv)); }
+
+  octave_value squeeze (void) const { return range; }
+
+  octave_value full_value (void) const { return range.matrix_value (); }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_range (void) const { return true; }
+
+  octave_value all (int dim = 0) const;
+
+  octave_value any (int dim = 0) const;
+
+  octave_value diag (octave_idx_type k = 0) const;
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return range.sort (dim, mode); }
+
+  octave_value sort (Array<octave_idx_type>& sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return range.sort (sidx, dim, mode); }
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return range.is_sorted (mode); }
+
+  Array<octave_idx_type> sort_rows_idx (sortmode) const
+    { return Array<octave_idx_type> (1, 0); }
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+    { return mode ? mode : ASCENDING; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  bool is_numeric_type (void) const { return true; }
+
+  bool is_true (void) const;
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return float_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const
+    { return range.matrix_value (); }
+
+  FloatMatrix float_matrix_value (bool = false) const
+    { return range.matrix_value (); }
+
+  NDArray array_value (bool = false) const
+    { return range.matrix_value (); }
+
+  FloatNDArray float_array_value (bool = false) const
+    { return FloatMatrix (range.matrix_value ()); }
+
+  charNDArray char_array_value (bool = false) const;
+  
+  // FIXME -- it would be better to have Range::intXNDArray_value
+  // functions to avoid the intermediate conversion to a matrix
+  // object.
+
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (array_value ()); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (array_value ()); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (array_value ()); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (array_value ()); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (array_value ()); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (array_value ()); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (array_value ()); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (array_value ()); }
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return SparseMatrix (range.matrix_value ()); }
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (sparse_matrix_value ()); }
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  boolNDArray bool_array_value (bool warn = false) const
+  {
+    Matrix m = range.matrix_value ();
+
+    if (m.any_element_is_nan ())
+      error ("invalid conversion from NaN to logical");
+    else if (warn && m.any_element_not_one_or_zero ())
+      gripe_logical_conversion ();
+
+    return boolNDArray (m);
+  }
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return ComplexMatrix (range.matrix_value ()); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const
+    { return FloatComplexMatrix (range.matrix_value ()); }
+
+  ComplexNDArray complex_array_value (bool = false) const
+    { return ComplexMatrix (range.matrix_value ()); }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const
+    { return FloatComplexMatrix (range.matrix_value ()); }
+
+  Range range_value (void) const { return range; }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      // FIXME -- could be more memory efficient by having a
+      // special case of the octave_stream::write method for ranges.
+
+      return os.write (matrix_value (), block_size, output_type, skip,
+		       flt_fmt);
+    }
+
+  mxArray *as_mxArray (void) const;
+
+  // Mapper functions are converted to double for treatment
+#define RANGE_MAPPER(MAP) \
+  octave_value MAP (void) const \
+    { \
+      octave_matrix m (array_value ()); \
+      return m.MAP (); \
+    }
+
+  RANGE_MAPPER (abs)
+  RANGE_MAPPER (acos)
+  RANGE_MAPPER (acosh)
+  RANGE_MAPPER (angle)
+  RANGE_MAPPER (arg)
+  RANGE_MAPPER (asin)
+  RANGE_MAPPER (asinh)
+  RANGE_MAPPER (atan)
+  RANGE_MAPPER (atanh)
+  RANGE_MAPPER (ceil)
+  RANGE_MAPPER (conj)
+  RANGE_MAPPER (cos)
+  RANGE_MAPPER (cosh)
+  RANGE_MAPPER (erf)
+  RANGE_MAPPER (erfc)
+  RANGE_MAPPER (exp)
+  RANGE_MAPPER (expm1)
+  RANGE_MAPPER (finite)
+  RANGE_MAPPER (fix)
+  RANGE_MAPPER (floor)
+  RANGE_MAPPER (gamma)
+  RANGE_MAPPER (imag)
+  RANGE_MAPPER (isinf)
+  RANGE_MAPPER (isna)
+  RANGE_MAPPER (isnan)
+  RANGE_MAPPER (lgamma)
+  RANGE_MAPPER (log)
+  RANGE_MAPPER (log2)
+  RANGE_MAPPER (log10)
+  RANGE_MAPPER (log1p)
+  RANGE_MAPPER (real)
+  RANGE_MAPPER (round)
+  RANGE_MAPPER (roundb)
+  RANGE_MAPPER (signum)
+  RANGE_MAPPER (sin)
+  RANGE_MAPPER (sinh)
+  RANGE_MAPPER (sqrt)
+  RANGE_MAPPER (tan)
+  RANGE_MAPPER (tanh)
+
+private:
+
+  Range range;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-re-diag.cc b/src/ov-re-diag.cc
new file mode 100644
index 0000000..5a37b1a
--- /dev/null
+++ b/src/ov-re-diag.cc
@@ -0,0 +1,264 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "byte-swap.h"
+
+#include "ov-re-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-base-diag.cc"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ls-utils.h"
+
+template class octave_base_diag<DiagMatrix, Matrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_diag_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_diag_matrix, "diagonal matrix", "double");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_diag_matrix&);
+
+  return new octave_matrix (v.matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_diag_matrix::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_matrix::static_type_id ());
+}
+
+static octave_base_value *
+default_numeric_demotion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_diag_matrix&);
+
+  return new octave_float_diag_matrix (v.float_diag_matrix_value ());
+}
+
+octave_base_value::type_conv_info
+octave_diag_matrix::numeric_demotion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_demotion_function,
+                                            octave_float_diag_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_diag_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  // FIXME: the proxy mechanism of DiagArray2 causes problems here.
+  if (matrix.nelem () == 1)
+    retval = new octave_scalar (double (matrix (0, 0)));
+
+  return retval;
+}
+
+octave_value
+octave_diag_matrix::do_index_op (const octave_value_list& idx,
+                                 bool resize_ok)
+{
+  octave_value retval;
+
+  // This hack is to allow constructing permutation matrices using
+  // eye(n)(p,:), eye(n)(:,q) && eye(n)(p,q) where p & q are permutation
+  // vectors. 
+  if (! resize_ok && idx.length () == 2 && matrix.is_multiple_of_identity (1))
+    {
+      idx_vector idx0 = idx(0).index_vector ();
+      idx_vector idx1 = idx(1).index_vector ();
+      
+      if (! error_state)
+        {
+          bool left = idx0.is_permutation (matrix.rows ());
+          bool right = idx1.is_permutation (matrix.cols ());
+
+          if (left && right)
+            {
+              if (idx0.is_colon ()) left = false;
+              if (idx1.is_colon ()) right = false;
+              if (left && right)
+                retval = PermMatrix (idx0, false) * PermMatrix (idx1, true);
+              else if (left)
+                retval = PermMatrix (idx0, false);
+              else if (right)
+                retval = PermMatrix (idx1, true);
+              else
+                {
+                  retval = this;
+                  this->count++;
+                }
+            }
+        }
+    }
+
+  // if error_state is set, we've already griped.
+  if (! error_state && retval.is_undefined ())
+    retval = octave_base_diag<DiagMatrix, Matrix>::do_index_op (idx, resize_ok);
+
+  return retval;
+}
+
+DiagMatrix
+octave_diag_matrix::diag_matrix_value (bool) const
+{
+  return matrix;
+}
+
+FloatDiagMatrix
+octave_diag_matrix::float_diag_matrix_value (bool) const
+{
+  return FloatDiagMatrix (matrix);
+}
+
+ComplexDiagMatrix
+octave_diag_matrix::complex_diag_matrix_value (bool) const
+{
+  return ComplexDiagMatrix (matrix);
+}
+
+FloatComplexDiagMatrix
+octave_diag_matrix::float_complex_diag_matrix_value (bool) const
+{
+  return FloatComplexDiagMatrix (matrix);
+}
+
+octave_value
+octave_diag_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_diag_matrix::real (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_diag_matrix::conj (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_diag_matrix::imag (void) const
+{
+  return DiagMatrix (matrix.rows (), matrix.cols (), 0.0);
+}
+
+octave_value
+octave_diag_matrix::sqrt (void) const
+{    
+  octave_value retval;
+
+  static NDArray::dmapper dsqrt = ::sqrt;
+  static NDArray::cmapper csqrt = std::sqrt;
+
+  ColumnVector dvec = matrix.diag ();
+  if (Matrix (dvec).any_element_is_negative ())
+    retval = ComplexDiagMatrix (dvec.map (csqrt));
+  else
+    retval = DiagMatrix (dvec.map (dsqrt));
+
+  retval.resize (dims ());
+
+  return retval;
+}
+
+bool 
+octave_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  Matrix m = Matrix (matrix.diag ());
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (matrix.length () > 8192) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const double *mtmp = m.data ();
+  write_doubles (os, mtmp, st, m.numel ());
+
+  return true;
+}
+
+bool 
+octave_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  DiagMatrix m (r, c);
+  double *re = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_doubles (is, re, static_cast<save_type> (tmp), len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
+bool 
+octave_diag_matrix::chk_valid_scalar (const octave_value& val, 
+                                      double& x) const
+{
+  bool retval = val.is_real_scalar ();
+  if (retval)
+    x = val.double_value ();
+  return retval;
+}
diff --git a/src/ov-re-diag.h b/src/ov-re-diag.h
new file mode 100644
index 0000000..61624ef
--- /dev/null
+++ b/src/ov-re-diag.h
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_diag_matrix_h)
+#define octave_diag_matrix_h 1
+
+#include "ov-base.h"
+#include "ov-base-diag.h"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+
+// Real diagonal matrix values.
+
+class
+OCTINTERP_API
+octave_diag_matrix 
+  : public octave_base_diag<DiagMatrix, Matrix>
+{
+public:
+
+  octave_diag_matrix (void)
+    : octave_base_diag<DiagMatrix, Matrix> () { }
+
+  octave_diag_matrix (const DiagMatrix& m)
+    : octave_base_diag<DiagMatrix, Matrix> (m) { }
+
+  octave_diag_matrix (const octave_diag_matrix& m)
+    : octave_base_diag<DiagMatrix, Matrix> (m) { }
+
+  ~octave_diag_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_diag_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_diag_matrix (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  type_conv_info numeric_demotion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  DiagMatrix diag_matrix_value (bool = false) const;
+
+  FloatDiagMatrix float_diag_matrix_value (bool = false) const;
+
+  ComplexDiagMatrix complex_diag_matrix_value (bool = false) const;
+
+  FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+  octave_value abs (void) const;
+  octave_value conj (void) const;
+  octave_value imag (void) const;
+  octave_value real (void) const;
+  octave_value sqrt (void) const;
+
+private:
+
+  bool chk_valid_scalar (const octave_value&, 
+                         double&) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
diff --git a/src/ov-re-mat.cc b/src/ov-re-mat.cc
new file mode 100644
index 0000000..3ba3cb9
--- /dev/null
+++ b/src/ov-re-mat.cc
@@ -0,0 +1,901 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+#include <vector>
+
+#include "data-conv.h"
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "mx-base.h"
+#include "quit.h"
+#include "oct-locbuf.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-base-mat.cc"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-re-diag.h"
+#include "ov-cx-diag.h"
+#include "ov-perm.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+#if ! defined (UCHAR_MAX)
+#define UCHAR_MAX 255
+#endif
+
+template class octave_base_matrix<NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_matrix, "matrix", "double");
+
+static octave_base_value *
+default_numeric_demotion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_matrix&);
+
+  return new octave_float_matrix (v.float_array_value ());
+}
+
+octave_base_value::type_conv_info
+octave_matrix::numeric_demotion_function (void) const
+{
+  return octave_base_value::type_conv_info(default_numeric_demotion_function,
+                                           octave_float_matrix::static_type_id ());
+}
+
+octave_base_value *
+octave_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (matrix.nelem () == 1)
+    retval = new octave_scalar (matrix (0));
+
+  return retval;
+}
+
+double
+octave_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "real scalar");
+
+  return retval;
+}
+
+float
+octave_matrix::float_value (bool) const
+{
+  float retval = lo_ieee_float_nan_value ();
+
+  if (numel () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "real scalar");
+
+  return retval;
+}
+
+// FIXME
+
+Matrix
+octave_matrix::matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
+FloatMatrix
+octave_matrix::float_matrix_value (bool) const
+{
+  return FloatMatrix (matrix.matrix_value ());
+}
+
+Complex
+octave_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "complex scalar");
+
+  return retval;
+}
+
+FloatComplex
+octave_matrix::float_complex_value (bool) const
+{
+  float tmp = lo_ieee_float_nan_value ();
+
+  FloatComplex retval (tmp, tmp);
+
+  if (rows () > 0 && columns () > 0)
+    {
+      gripe_implicit_conversion ("Octave:array-as-scalar",
+				 "real matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real matrix", "complex scalar");
+
+  return retval;
+}
+
+// FIXME
+
+ComplexMatrix
+octave_matrix::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (matrix.matrix_value ());
+}
+
+FloatComplexMatrix
+octave_matrix::float_complex_matrix_value (bool) const
+{
+  return FloatComplexMatrix (matrix.matrix_value ());
+}
+
+ComplexNDArray
+octave_matrix::complex_array_value (bool) const
+{
+  return ComplexNDArray (matrix);
+}
+
+FloatComplexNDArray
+octave_matrix::float_complex_array_value (bool) const
+{
+  return FloatComplexNDArray (matrix);
+}
+
+boolNDArray
+octave_matrix::bool_array_value (bool warn) const
+{
+  if (matrix.any_element_is_nan ())
+    error ("invalid conversion from NaN to logical");
+  else if (warn && matrix.any_element_not_one_or_zero ())
+    gripe_logical_conversion ();
+
+  return boolNDArray (matrix);
+}
+  
+charNDArray
+octave_matrix::char_array_value (bool) const
+{
+  charNDArray retval (dims ());
+
+  octave_idx_type nel = numel ();
+  
+  for (octave_idx_type i = 0; i < nel; i++)
+    retval.elem (i) = static_cast<char>(matrix.elem (i));
+
+  return retval;
+}
+  
+SparseMatrix 
+octave_matrix::sparse_matrix_value (bool) const
+{
+  return SparseMatrix (matrix.matrix_value ());
+}
+
+SparseComplexMatrix 
+octave_matrix::sparse_complex_matrix_value (bool) const
+{
+  // FIXME Need a SparseComplexMatrix (Matrix) constructor to make
+  // this function more efficient. Then this should become
+  // return SparseComplexMatrix (matrix.matrix_value ());
+  return SparseComplexMatrix (sparse_matrix_value ());
+}
+
+octave_value
+octave_matrix::diag (octave_idx_type k) const
+{
+  octave_value retval;
+  if (k == 0 && matrix.ndims () == 2 
+      && (matrix.rows () == 1 || matrix.columns () == 1))
+    retval = DiagMatrix (DiagArray2<double> (matrix));
+  else
+    retval = octave_base_matrix<NDArray>::diag (k);
+
+  return retval;
+}
+
+octave_value
+octave_matrix::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+  dim_vector dv = dims ();
+  octave_idx_type nel = dv.numel ();
+
+  charNDArray chm (dv);
+
+  bool warned = false;
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+
+      double d = matrix (i);
+
+      if (xisnan (d))
+	{
+	  ::error ("invalid conversion from NaN to character");
+	  return retval;
+	}
+      else
+	{
+	  int ival = NINT (d);
+
+	  if (ival < 0 || ival > UCHAR_MAX)
+	    {
+	      // FIXME -- is there something
+	      // better we could do?
+
+	      ival = 0;
+
+	      if (! warned)
+		{
+		  ::warning ("range error for conversion to character value");
+		  warned = true;
+		}
+	    }
+
+	  chm (i) = static_cast<char> (ival);
+	}
+    }
+
+  retval = octave_value (chm, true, type);
+
+  return retval;
+}
+
+bool 
+octave_matrix::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+
+  if (d.length () > 2)
+    {
+      NDArray tmp = array_value ();
+
+      os << "# ndims: " << d.length () << "\n";
+
+      for (int i=0; i < d.length (); i++)
+	os << " " << d (i);
+
+      os << "\n" << tmp;
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for backward 
+      // compatiability. Makes load_ascii much more complex!!
+      os << "# rows: " << rows () << "\n"
+	 << "# columns: " << columns () << "\n";
+
+      os << matrix_value ();
+    }
+
+  return true;
+}
+
+bool 
+octave_matrix::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  string_vector keywords(2);
+
+  keywords[0] = "ndims";
+  keywords[1] = "rows";
+
+  std::string kw;
+  octave_idx_type val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = static_cast<int> (val);
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      if (is)
+		{
+		  NDArray tmp(dv);
+
+                  is >> tmp;
+
+                  if (is)
+                    matrix = tmp;
+                  else
+                    {
+                      error ("load: failed to load matrix constant");
+                      success = false;
+                    }
+		}
+	      else
+		{
+		  error ("load: failed to read dimensions");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of dimensions");
+	      success = false;
+	    }
+	}
+      else if (kw == "rows")
+	{
+	  octave_idx_type nr = val;
+	  octave_idx_type nc = 0;
+
+	  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  Matrix tmp (nr, nc);
+		  is >> tmp;
+		  if (is)
+		    matrix = tmp;
+		  else
+		    {
+		      error ("load: failed to load matrix constant");
+		      success = false;
+		    }
+		}
+	      else if (nr == 0 || nc == 0)
+		matrix = Matrix (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else 
+	    {
+	      error ("load: failed to extract number of rows and columns");
+	      success = false;
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i = 0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  NDArray m = array_value ();
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (d.numel () > 8192) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const double *mtmp = m.data ();
+  write_doubles (os, mtmp, st, d.numel ());
+
+  return true;
+}
+
+bool 
+octave_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  char tmp;
+  int32_t mdims;
+  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&mdims);
+  if (mdims < 0)
+    {
+      mdims = - mdims;
+      int32_t di;
+      dim_vector dv;
+      dv.resize (mdims);
+
+      for (int i = 0; i < mdims; i++)
+	{
+	  if (! is.read (reinterpret_cast<char *> (&di), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&di);
+	  dv(i) = di;
+	}
+
+      // Convert an array with a single dimension to be a row vector.
+      // Octave should never write files like this, other software
+      // might.
+
+      if (mdims == 1)
+	{
+	  mdims = 2;
+	  dv.resize (mdims);
+	  dv(1) = dv(0);
+	  dv(0) = 1;
+	}
+
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+
+      NDArray m(dv);
+      double *re = m.fortran_vec ();
+      read_doubles (is, re, static_cast<save_type> (tmp), dv.numel (), swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  else
+    {
+      int32_t nr, nc;
+      nr = mdims;
+      if (! is.read (reinterpret_cast<char *> (&nc), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&nc);
+      if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+	return false;
+      Matrix m (nr, nc);
+      double *re = m.fortran_vec ();
+      octave_idx_type len = nr * nc;
+      read_doubles (is, re, static_cast<save_type> (tmp), len, swap, fmt);
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  NDArray m = array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, 0);
+
+  if (space_hid < 0) return false;
+
+  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
+
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	save_type_hid = H5T_NATIVE_FLOAT;
+    }
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+  // hdf5 currently doesn't support float/integer conversions
+  else
+    {
+      double max_val, min_val;
+
+      if (m.all_integers (max_val, min_val))
+	save_type_hid
+	  = save_type_to_hdf5 (get_save_type (max_val, min_val));
+    }
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+  
+  data_hid = H5Dcreate (loc_id, name, save_type_hid, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  double *mtmp = m.fortran_vec ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, mtmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_matrix::load_hdf5 (hid_t loc_id, const char *name,
+			  bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+      return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+  
+  if (rank < 1)
+    {
+      H5Sclose (space_id);
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  if (rank == 1)
+    {
+      dv.resize (2);
+      dv(0) = 1;
+      dv(1) = hdims[0];
+    }
+  else
+    {
+      dv.resize (rank);
+      for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	dv(j) = hdims[i];
+    }
+
+  NDArray m (dv);
+  double *re = m.fortran_vec ();
+  if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, re) >= 0) 
+    {
+      retval = true;
+      matrix = m;
+    }
+
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return retval;
+}
+
+#endif
+
+void
+octave_matrix::print_raw (std::ostream& os,
+			  bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level ());
+}
+
+mxArray *
+octave_matrix::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, dims (), mxREAL);
+
+  double *pr = static_cast<double *> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  const double *p = matrix.data ();
+
+  for (mwIndex i = 0; i < nel; i++)
+    pr[i] = p[i];
+
+  return retval;
+}
+
+static bool
+any_element_less_than (const NDArray& a, double val)
+{
+  octave_idx_type len = a.length ();
+  const double *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] < val)
+	return true;
+    }
+
+  return false;
+}
+
+static bool
+any_element_greater_than (const NDArray& a, double val)
+{
+  octave_idx_type len = a.length ();
+  const double *m = a.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (m[i] > val)
+	return true;
+    }
+
+  return false;
+}
+
+#define ARRAY_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_matrix::MAP (void) const \
+  { \
+    static AMAP dmap = FCN; \
+    return matrix.map (dmap); \
+  }
+
+#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_matrix::MAP (void) const \
+  { \
+    static NDArray::dmapper dmap = RFCN; \
+    static NDArray::cmapper cmap = CFCN; \
+ \
+    return (any_element_less_than (matrix, L1) \
+            ? octave_value (matrix.map (cmap)) \
+	    : (any_element_greater_than (matrix, L2) \
+	       ? octave_value (matrix.map (cmap)) \
+	       : octave_value (matrix.map (dmap)))); \
+  }
+
+// The fast mappers.
+octave_value
+octave_matrix::abs (void) const
+{
+  return matrix.abs ();
+}
+
+octave_value
+octave_matrix::real (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_matrix::conj (void) const
+{
+  return matrix;
+}
+
+octave_value
+octave_matrix::imag (void) const
+{
+  return NDArray (matrix.dims (), 0.0);
+}
+
+octave_value
+octave_matrix::isnan (void) const
+{
+  return matrix.isnan ();
+}
+
+octave_value
+octave_matrix::isinf (void) const
+{
+  return matrix.isinf ();
+}
+
+octave_value
+octave_matrix::finite (void) const
+{
+  return matrix.isfinite ();
+}
+
+ARRAY_MAPPER (erf, NDArray::dmapper, ::erf)
+ARRAY_MAPPER (erfc, NDArray::dmapper, ::erfc)
+ARRAY_MAPPER (gamma, NDArray::dmapper, xgamma)
+CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+CD_ARRAY_MAPPER (acos, ::acos, ::acos, -1.0, 1.0)
+CD_ARRAY_MAPPER (acosh, ::acosh, ::acosh, 1.0, octave_Inf)
+ARRAY_MAPPER (angle, NDArray::dmapper, ::arg)
+ARRAY_MAPPER (arg, NDArray::dmapper, ::arg)
+CD_ARRAY_MAPPER (asin, ::asin, ::asin, -1.0, 1.0)
+ARRAY_MAPPER (asinh, NDArray::dmapper,::asinh)
+ARRAY_MAPPER (atan, NDArray::dmapper, ::atan)
+CD_ARRAY_MAPPER (atanh, ::atanh, ::atanh, -1.0, 1.0)
+ARRAY_MAPPER (ceil, NDArray::dmapper, ::ceil)
+ARRAY_MAPPER (cos, NDArray::dmapper, ::cos)
+ARRAY_MAPPER (cosh, NDArray::dmapper, ::cosh)
+ARRAY_MAPPER (exp, NDArray::dmapper, ::exp)
+ARRAY_MAPPER (expm1, NDArray::dmapper, ::expm1)
+ARRAY_MAPPER (fix, NDArray::dmapper, ::fix)
+ARRAY_MAPPER (floor, NDArray::dmapper, ::floor)
+CD_ARRAY_MAPPER (log, ::log, std::log, 0.0, octave_Inf)
+CD_ARRAY_MAPPER (log2, xlog2, xlog2, 0.0, octave_Inf)
+CD_ARRAY_MAPPER (log10, ::log10, std::log10, 0.0, octave_Inf)
+CD_ARRAY_MAPPER (log1p, ::log1p, ::log1p, -1.0, octave_Inf)
+ARRAY_MAPPER (round, NDArray::dmapper, xround)
+ARRAY_MAPPER (roundb, NDArray::dmapper, xroundb)
+ARRAY_MAPPER (signum, NDArray::dmapper, ::signum)
+ARRAY_MAPPER (sin, NDArray::dmapper, ::sin)
+ARRAY_MAPPER (sinh, NDArray::dmapper, ::sinh)
+CD_ARRAY_MAPPER (sqrt, ::sqrt, std::sqrt, 0.0, octave_Inf)
+ARRAY_MAPPER (tan, NDArray::dmapper, ::tan)
+ARRAY_MAPPER (tanh, NDArray::dmapper, ::tanh)
+ARRAY_MAPPER (isna, NDArray::bmapper, octave_is_NA)
+
+DEFUN (double, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} double (@var{x})\n\
+Convert @var{x} to double precision type.\n\
+ at seealso{single}\n\
+ at end deftypefn")
+{
+  // The OCTAVE_TYPE_CONV_BODY3 macro declares retval, so they go
+  // inside their own scopes, and we don't declare retval here to
+  // avoid a shadowed declaration warning.
+
+  if (args.length () == 1)
+    {
+      if (args(0).is_perm_matrix ())
+        {
+          OCTAVE_TYPE_CONV_BODY3 (double, octave_perm_matrix, octave_scalar);
+        }
+      else if (args(0).is_diag_matrix ())
+        {
+	  if (args(0).is_complex_type ())
+	    {
+	      OCTAVE_TYPE_CONV_BODY3 (double, octave_complex_diag_matrix, octave_complex);
+	    }
+	  else
+	    {
+	      OCTAVE_TYPE_CONV_BODY3 (double, octave_diag_matrix, octave_scalar);
+	    }
+        }
+      else if (args(0).is_sparse_type ())
+	{
+	  if (args(0).is_complex_type ())
+	    {
+	      OCTAVE_TYPE_CONV_BODY3 (double, octave_sparse_complex_matrix, octave_complex);
+	    }
+	  else
+	    {
+	      OCTAVE_TYPE_CONV_BODY3 (double, octave_sparse_matrix, octave_scalar);
+	    }
+	}
+      else if (args(0).is_complex_type ())
+	{
+	  OCTAVE_TYPE_CONV_BODY3 (double, octave_complex_matrix, octave_complex);
+	}
+      else
+	{
+	  OCTAVE_TYPE_CONV_BODY3 (double, octave_matrix, octave_scalar);
+	}
+    }
+  else
+    print_usage ();
+
+  return octave_value ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-re-mat.h b/src/ov-re-mat.h
new file mode 100644
index 0000000..d58e17f
--- /dev/null
+++ b/src/ov-re-mat.h
@@ -0,0 +1,250 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_matrix_h)
+#define octave_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-base-mat.h"
+#include "ov-typeinfo.h"
+
+#include "MatrixType.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Real matrix values.
+
+class
+OCTINTERP_API
+octave_matrix : public octave_base_matrix<NDArray>
+{
+public:
+
+  octave_matrix (void)
+    : octave_base_matrix<NDArray> () { }
+
+  octave_matrix (const Matrix& m)
+    : octave_base_matrix<NDArray> (m) { }
+
+  octave_matrix (const Matrix& m, const MatrixType& t)
+    : octave_base_matrix<NDArray> (m, t) { }
+
+  octave_matrix (const NDArray& nda)
+    : octave_base_matrix<NDArray> (nda) { }
+
+  octave_matrix (const ArrayN<double>& m)
+    : octave_base_matrix<NDArray> (NDArray (m)) { }
+
+  octave_matrix (const DiagMatrix& d)
+    : octave_base_matrix<NDArray> (Matrix (d)) { }
+
+  octave_matrix (const RowVector& v)
+    : octave_base_matrix<NDArray> (Matrix (v)) { }
+
+  octave_matrix (const ColumnVector& v)
+    : octave_base_matrix<NDArray> (Matrix (v)) { }
+
+  octave_matrix (const octave_matrix& m)
+    : octave_base_matrix<NDArray> (m) { }
+
+  ~octave_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
+
+  type_conv_info numeric_demotion_function (void) const;
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  idx_vector index_vector (void) const { return idx_vector (matrix); }
+
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (matrix); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (matrix); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (matrix); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (matrix); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (matrix); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (matrix); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (matrix); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (matrix); }
+
+  double double_value (bool = false) const;
+
+  float float_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  FloatMatrix float_matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  FloatComplex float_complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+   
+  FloatComplexNDArray float_complex_array_value (bool = false) const;
+   
+  boolNDArray bool_array_value (bool warn = false) const;
+
+  charNDArray char_array_value (bool = false) const;
+  
+  NDArray array_value (bool = false) const { return matrix; }
+
+  FloatNDArray float_array_value (bool = false) const { return matrix; }
+
+  SparseMatrix sparse_matrix_value (bool = false) const;
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+
+  octave_value diag (octave_idx_type k = 0) const;
+
+  void increment (void) { matrix += 1.0; }
+
+  void decrement (void) { matrix -= 1.0; }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
+
+  // Unsafe.  This function exists to support the MEX interface.
+  // You should not use it anywhere else.
+  void *mex_get_data (void) const { return matrix.mex_get_data (); }
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-re-sparse.cc b/src/ov-re-sparse.cc
new file mode 100644
index 0000000..16419da
--- /dev/null
+++ b/src/ov-re-sparse.cc
@@ -0,0 +1,918 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+#include <vector>
+
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+#include "oct-locbuf.h"
+
+#include "ov-base.h"
+#include "ov-scalar.h"
+#include "gripes.h"
+
+#include "ls-hdf5.h"
+
+#include "ov-re-sparse.h"
+
+#include "ov-base-sparse.h"
+#include "ov-base-sparse.cc"
+
+#include "ov-bool-sparse.h"
+
+template class OCTINTERP_API octave_base_sparse<SparseMatrix>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_sparse_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_matrix, "sparse matrix", "double");
+
+idx_vector
+octave_sparse_matrix::index_vector (void) const
+{
+  if (matrix.numel () == matrix.nnz ())
+    return idx_vector (array_value ());
+  else
+    {
+      std::string nm = type_name ();
+      error ("%s type invalid as index value", nm.c_str ());
+      return idx_vector ();
+    }
+}
+
+octave_base_value *
+octave_sparse_matrix::try_narrowing_conversion (void)
+{
+  octave_base_value *retval = 0;
+
+  if (Vsparse_auto_mutate)
+    {
+      // Don't use numel, since it can overflow for very large matrices
+      // Note that for the second test, this means it becomes approximative
+      // since it involves a cast to double to avoid issues of overflow
+      if (matrix.rows () == 1 && matrix.cols () == 1)
+	{
+	  // Const copy of the matrix, so the right version of () operator used
+	  const SparseMatrix tmp (matrix);
+
+	  retval = new octave_scalar (tmp (0));
+	}
+      else if (matrix.cols () > 0 && matrix.rows () > 0 && 
+	       double (matrix.byte_size ()) > double (matrix.rows ()) *
+	       double (matrix.cols ()) * sizeof (double))
+	retval = new octave_matrix (matrix.matrix_value ());
+    }
+
+  return retval;
+}
+
+double
+octave_sparse_matrix::double_value (bool) const
+{
+  double retval = lo_ieee_nan_value ();
+
+  if (numel () > 0)
+    {
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "real sparse matrix", "real scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real sparse matrix", "real scalar");
+
+  return retval;
+}
+
+Complex
+octave_sparse_matrix::complex_value (bool) const
+{
+  double tmp = lo_ieee_nan_value ();
+
+  Complex retval (tmp, tmp);
+
+  // FIXME -- maybe this should be a function, valid_as_scalar()
+  if (rows () > 0 && columns () > 0)
+    {
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "real sparse matrix", "complex scalar");
+
+      retval = matrix (0, 0);
+    }
+  else
+    gripe_invalid_conversion ("real sparse matrix", "complex scalar");
+
+  return retval;
+}
+
+Matrix
+octave_sparse_matrix::matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
+boolNDArray
+octave_sparse_matrix::bool_array_value (bool warn) const
+{
+  NDArray m = matrix.matrix_value ();
+
+  if (m.any_element_is_nan ())
+    error ("invalid conversion from NaN to logical");
+  else if (warn && m.any_element_not_one_or_zero ())
+    gripe_logical_conversion ();
+
+  return boolNDArray (m);
+}
+
+charNDArray
+octave_sparse_matrix::char_array_value (bool) const
+{
+  charNDArray retval (dims (), 0);
+  octave_idx_type nc = matrix.cols ();
+  octave_idx_type nr = matrix.rows ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++)
+      retval(matrix.ridx(i) + nr * j) = static_cast<char>(matrix.data (i));
+
+  return retval;
+}
+  
+ComplexMatrix
+octave_sparse_matrix::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (matrix.matrix_value ());
+}
+
+ComplexNDArray
+octave_sparse_matrix::complex_array_value (bool) const
+{
+  return ComplexNDArray (ComplexMatrix (matrix.matrix_value ()));
+}
+
+NDArray 
+octave_sparse_matrix::array_value (bool) const
+{
+  return NDArray (matrix.matrix_value ());
+}
+
+octave_value
+octave_sparse_matrix::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+  dim_vector dv = dims ();
+  octave_idx_type nel = dv.numel ();
+
+  if (nel == 0)
+    {
+      char s = '\0';
+      retval = octave_value (&s, type);
+    }
+  else
+    {
+      octave_idx_type nr = matrix.rows ();
+      octave_idx_type nc = matrix.cols ();
+      charNDArray chm (dv, static_cast<char> (0));
+	  
+      bool warned = false;
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = matrix.cidx(j); 
+	     i < matrix.cidx(j+1); i++)
+	  {
+	    OCTAVE_QUIT;
+
+	    double d = matrix.data (i);
+
+	      if (xisnan (d))
+		{
+		  ::error ("invalid conversion from NaN to character");
+		  return retval;
+		}
+	      else
+		{
+		  int ival = NINT (d);
+
+		  if (ival < 0 || ival > UCHAR_MAX)
+		    {
+		      // FIXME -- is there something
+		      // better we could do?
+
+		      ival = 0;
+
+		      if (! warned)
+			{
+			  ::warning ("range error for conversion to character value");
+			  warned = true;
+			}
+		    }
+
+		  chm (matrix.ridx(i) + j * nr) = 
+		    static_cast<char> (ival);
+		}
+	  }
+      retval = octave_value (chm, true, type);
+    }
+
+  return retval;
+}
+
+bool 
+octave_sparse_matrix::save_binary (std::ostream& os, bool&save_as_floats)
+{
+  dim_vector d = this->dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  int nr = d(0);
+  int nc = d(1);
+  int nz = nzmax ();
+
+  int32_t itmp;
+  // Use negative value for ndims to be consistent with other formats
+  itmp= -2;        
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nr;    
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nc;
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+  
+  itmp= nz;
+  os.write (reinterpret_cast<char *> (&itmp), 4);
+
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (matrix.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (matrix.nzmax () > 8192) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (matrix.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  // add one to the printed indices to go from
+  // zero-based to one-based arrays
+   for (int i = 0; i < nc+1; i++)  
+     {
+       OCTAVE_QUIT;
+       itmp = matrix.cidx(i);
+       os.write (reinterpret_cast<char *> (&itmp), 4);
+     }
+
+   for (int i = 0; i < nz; i++) 
+     {
+       OCTAVE_QUIT;
+       itmp = matrix.ridx(i); 
+       os.write (reinterpret_cast<char *> (&itmp), 4);
+     }
+
+   write_doubles (os, matrix.data(), st, nz);
+
+  return true;
+}
+
+bool
+octave_sparse_matrix::load_binary (std::istream& is, bool swap,
+				   oct_mach_info::float_format fmt)
+{
+  int32_t nz, nc, nr, tmp;
+  char ctmp;
+
+  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+    return false;
+
+  if (swap)
+    swap_bytes<4> (&tmp);
+
+  if (tmp != -2) {
+    error("load: only 2D sparse matrices are supported");
+    return false;
+  }
+
+  if (! is.read (reinterpret_cast<char *> (&nr), 4))
+    return false;
+  if (! is.read (reinterpret_cast<char *> (&nc), 4))
+    return false;
+  if (! is.read (reinterpret_cast<char *> (&nz), 4))
+    return false;
+
+  if (swap)
+    {
+      swap_bytes<4> (&nr);
+      swap_bytes<4> (&nc);
+      swap_bytes<4> (&nz);
+    }
+
+  SparseMatrix m (static_cast<octave_idx_type> (nr),
+		  static_cast<octave_idx_type> (nc),
+		  static_cast<octave_idx_type> (nz));
+
+  for (int i = 0; i < nc+1; i++) 
+    {
+      OCTAVE_QUIT;
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+      m.xcidx(i) = tmp;
+    }
+
+  for (int i = 0; i < nz; i++) 
+    {
+      OCTAVE_QUIT;
+      if (! is.read (reinterpret_cast<char *> (&tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+      m.xridx(i) = tmp;
+    }
+
+  if (! is.read (reinterpret_cast<char *> (&ctmp), 1))
+    return false;
+  
+  read_doubles (is, m.xdata (), static_cast<save_type> (ctmp), nz, swap, fmt);
+
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_sparse_matrix::save_hdf5 (hid_t loc_id, const char *name, 
+				 bool save_as_floats)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  // Ensure that additional memory is deallocated
+  matrix.maybe_compress ();
+
+  hid_t group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0)
+    return false;
+
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  SparseMatrix m = sparse_matrix_value ();
+  octave_idx_type tmp;
+  hsize_t hdims[2];
+
+  space_hid = H5Screate_simple (0, hdims, 0);
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.rows ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		     &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.cols ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		     &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  tmp = m.nzmax ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		     &tmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+
+  hdims[0] = m.cols() + 1;
+  hdims[1] = 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  octave_idx_type * itmp = m.xcidx ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		     itmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }    
+
+  H5Sclose (space_hid);
+
+  hdims[0] = m.nzmax ();
+  hdims[1] = 1;
+
+  space_hid = H5Screate_simple (2, hdims, 0);
+
+  if (space_hid < 0) 
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  itmp = m.xridx ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		     itmp) >= 0;
+  H5Dclose (data_hid);
+  if (!retval)
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
+
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	save_type_hid = H5T_NATIVE_FLOAT;
+    }
+#if HAVE_HDF5_INT2FLOAT_CONVERSIONS
+  // hdf5 currently doesn't support float/integer conversions
+  else
+    {
+      double max_val, min_val;
+
+      if (m.all_integers (max_val, min_val))
+	save_type_hid
+	  = save_type_to_hdf5 (get_save_type (max_val, min_val));
+    }
+#endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
+
+  data_hid = H5Dcreate (group_hid, "data", save_type_hid, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  
+  double * dtmp = m.xdata ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, dtmp) >= 0;
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+bool
+octave_sparse_matrix::load_hdf5 (hid_t loc_id, const char *name,
+				 bool /* have_h5giterate_bug */)
+{
+  octave_idx_type nr, nc, nz;
+  hid_t group_hid, data_hid, space_hid;
+  hsize_t rank;
+  
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+    return (empty > 0);
+  
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0) return false;
+
+  data_hid = H5Dopen (group_hid, "nr");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &nr) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "nc");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &nc) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+  
+  data_hid = H5Dopen (group_hid, "nz");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &nz) < 0)
+    { 
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Dclose (data_hid);
+
+  SparseMatrix m (static_cast<octave_idx_type> (nr),
+		  static_cast<octave_idx_type> (nc),
+		  static_cast<octave_idx_type> (nz));
+
+  data_hid = H5Dopen (group_hid, "cidx");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nc + 1 || 
+      static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  octave_idx_type *itmp = m.xcidx ();
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, itmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "ridx");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  itmp = m.xridx ();
+  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, itmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+
+  data_hid = H5Dopen (group_hid, "data");
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 2)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+  if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1)
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  double *dtmp = m.xdata ();
+  if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, dtmp) < 0) 
+    {
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  H5Sclose (space_hid);
+  H5Dclose (data_hid);
+  H5Gclose (group_hid);
+
+  matrix = m;
+
+  return true;
+}
+
+#endif
+
+mxArray *
+octave_sparse_matrix::as_mxArray (void) const
+{
+  mwSize nz = nzmax();
+  mwSize nr = rows();
+  mwSize nc = columns();
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, nr, nc, nz, mxREAL);
+  double *pr = static_cast<double *> (retval->get_data ());
+  mwIndex *ir = retval->get_ir();
+  mwIndex *jc = retval->get_jc();
+
+  for (mwIndex i = 0; i < nz; i++)
+    {
+      pr[i] = matrix.data(i);
+      ir[i] = matrix.ridx(i);
+    }
+
+  for (mwIndex i = 0; i < nc + 1; i++)
+    jc[i] = matrix.cidx(i);
+
+  return retval;
+}
+
+static bool
+any_element_less_than (const SparseMatrix& a, double val)
+{
+  octave_idx_type len = a.nnz ();
+
+  if (val > 0. && len != a.numel ())
+    return true;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (a.data(i) < val)
+	return true;
+    }
+
+  return false;
+}
+
+static bool
+any_element_greater_than (const SparseMatrix& a, double val)
+{
+  octave_idx_type len = a.nnz ();
+
+  if (val < 0. && len != a.numel ())
+    return true;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+
+      if (a.data(i) > val)
+	return true;
+    }
+
+  return false;
+}
+
+#define SPARSE_MAPPER(MAP, AMAP, FCN) \
+  octave_value \
+  octave_sparse_matrix::MAP (void) const \
+  { \
+    static AMAP dmap = FCN; \
+    return matrix.map (dmap); \
+  }
+
+#define CD_SPARSE_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_sparse_matrix::MAP (void) const \
+  { \
+    static SparseMatrix::dmapper dmap = RFCN; \
+    static SparseMatrix::cmapper cmap = CFCN; \
+ \
+    return (any_element_less_than (matrix, L1) \
+            ? octave_value (matrix.map (cmap)) \
+            : (any_element_greater_than (matrix, L2) \
+               ? octave_value (matrix.map (cmap)) \
+	       : octave_value (matrix.map (dmap)))); \
+  }
+
+static double
+xconj (double x)
+{
+  return x;
+}
+
+SPARSE_MAPPER (erf, SparseMatrix::dmapper, ::erf)
+SPARSE_MAPPER (erfc, SparseMatrix::dmapper, ::erfc)
+SPARSE_MAPPER (gamma, SparseMatrix::dmapper, xgamma)
+CD_SPARSE_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+SPARSE_MAPPER (abs, SparseMatrix::dmapper, ::fabs)
+CD_SPARSE_MAPPER (acos, ::acos, ::acos, -1.0, 1.0)
+CD_SPARSE_MAPPER (acosh, ::acosh, ::acosh, 1.0, octave_Inf)
+SPARSE_MAPPER (angle, SparseMatrix::dmapper, ::arg)
+SPARSE_MAPPER (arg, SparseMatrix::dmapper, ::arg)
+CD_SPARSE_MAPPER (asin, ::asin, ::asin, -1.0, 1.0)
+SPARSE_MAPPER (asinh, SparseMatrix::dmapper, ::asinh)
+SPARSE_MAPPER (atan, SparseMatrix::dmapper, ::atan)
+CD_SPARSE_MAPPER (atanh, ::atanh, ::atanh, -1.0, 1.0)
+SPARSE_MAPPER (ceil, SparseMatrix::dmapper, ::ceil)
+SPARSE_MAPPER (conj, SparseMatrix::dmapper, xconj)
+SPARSE_MAPPER (cos, SparseMatrix::dmapper, ::cos)
+SPARSE_MAPPER (cosh, SparseMatrix::dmapper, ::cosh)
+SPARSE_MAPPER (exp, SparseMatrix::dmapper, ::exp)
+SPARSE_MAPPER (expm1, SparseMatrix::dmapper, ::expm1)
+SPARSE_MAPPER (fix, SparseMatrix::dmapper, ::fix)
+SPARSE_MAPPER (floor, SparseMatrix::dmapper, ::floor)
+SPARSE_MAPPER (imag, SparseMatrix::dmapper, ::imag)
+CD_SPARSE_MAPPER (log, ::log, std::log, 0.0, octave_Inf)
+CD_SPARSE_MAPPER (log2, xlog2, xlog2, 0.0, octave_Inf)
+CD_SPARSE_MAPPER (log10, ::log10, std::log10, 0.0, octave_Inf)
+CD_SPARSE_MAPPER (log1p, ::log1p, ::log1p, 0.0, octave_Inf)
+SPARSE_MAPPER (real, SparseMatrix::dmapper, ::real)
+SPARSE_MAPPER (round, SparseMatrix::dmapper, xround)
+SPARSE_MAPPER (roundb, SparseMatrix::dmapper, xroundb)
+SPARSE_MAPPER (signum, SparseMatrix::dmapper, ::signum)
+SPARSE_MAPPER (sin, SparseMatrix::dmapper, ::sin)
+SPARSE_MAPPER (sinh, SparseMatrix::dmapper, ::sinh)
+CD_SPARSE_MAPPER (sqrt, ::sqrt, std::sqrt, 0.0, octave_Inf)
+SPARSE_MAPPER (tan, SparseMatrix::dmapper, ::tan)
+SPARSE_MAPPER (tanh, SparseMatrix::dmapper, ::tanh)
+SPARSE_MAPPER (finite, SparseMatrix::bmapper, xfinite)
+SPARSE_MAPPER (isinf, SparseMatrix::bmapper, xisinf)
+SPARSE_MAPPER (isna, SparseMatrix::bmapper, octave_is_NA)
+SPARSE_MAPPER (isnan, SparseMatrix::bmapper, xisnan)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-re-sparse.h b/src/ov-re-sparse.h
new file mode 100644
index 0000000..a925c2e
--- /dev/null
+++ b/src/ov-re-sparse.h
@@ -0,0 +1,205 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_matrix_h)
+#define octave_sparse_matrix_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+#include "dSparse.h"
+#include "MatrixType.h"
+#include "ov-base-sparse.h"
+#include "ov-cx-sparse.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+class
+OCTINTERP_API
+octave_sparse_matrix : public octave_base_sparse<SparseMatrix>
+{
+public:
+
+  octave_sparse_matrix (void)
+    : octave_base_sparse<SparseMatrix> () { }
+
+  octave_sparse_matrix (const Matrix& m)
+    : octave_base_sparse<SparseMatrix> (SparseMatrix (m)) { }
+
+  octave_sparse_matrix (const NDArray& m)
+    : octave_base_sparse<SparseMatrix> (SparseMatrix (m)) { }
+
+  octave_sparse_matrix (const SparseMatrix& m)
+    : octave_base_sparse<SparseMatrix> (m) { }
+
+  octave_sparse_matrix (const SparseMatrix& m, const MatrixType& t)
+    : octave_base_sparse<SparseMatrix> (m, t) { }
+
+  octave_sparse_matrix (const MSparse<double>& m)
+    : octave_base_sparse<SparseMatrix> (m) { }
+    
+  octave_sparse_matrix (const MSparse<double>& m, const MatrixType& t)
+    : octave_base_sparse<SparseMatrix> (m, t) { }
+
+  octave_sparse_matrix (const Sparse<double>& m)
+    : octave_base_sparse<SparseMatrix> (SparseMatrix (m)) { }
+    
+  octave_sparse_matrix (const Sparse<double>& m, const MatrixType& t)
+    : octave_base_sparse<SparseMatrix> (SparseMatrix (m), t) { }
+
+  octave_sparse_matrix (const octave_sparse_matrix& m)
+    : octave_base_sparse<SparseMatrix> (m) { }
+
+  ~octave_sparse_matrix (void) { }
+
+  octave_base_value *clone (void) const { return new octave_sparse_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_sparse_matrix (); }
+
+  octave_base_value *try_narrowing_conversion (void);
+
+  idx_vector index_vector (void) const;
+
+  bool is_real_matrix (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  double double_value (bool = false) const;
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return double_value (frc_str_conv); }
+
+  Matrix matrix_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  boolNDArray bool_array_value (bool warn = false) const;
+
+  charNDArray char_array_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+   
+  NDArray array_value (bool = false) const;
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return matrix; }
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (matrix); }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+#if 0
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
+#endif
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+  octave_value map (double (*fcn) (double)) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-scalar.cc b/src/ov-scalar.cc
new file mode 100644
index 0000000..6f7560d
--- /dev/null
+++ b/src/ov-scalar.cc
@@ -0,0 +1,336 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "data-conv.h"
+#include "mach-info.h"
+#include "lo-specfun.h"
+#include "lo-mappers.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-base.h"
+#include "ov-base-scalar.h"
+#include "ov-base-scalar.cc"
+#include "ov-re-mat.h"
+#include "ov-typeinfo.h"
+#include "pr-output.h"
+#include "xdiv.h"
+#include "xpow.h"
+#include "ops.h"
+
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+
+template class octave_base_scalar<double>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_scalar, "scalar", "double");
+
+static octave_base_value *
+default_numeric_demotion_function (const octave_base_value& a)
+{
+  CAST_CONV_ARG (const octave_scalar&);
+
+  return new octave_float_scalar (v.float_value ());
+}
+
+octave_base_value::type_conv_info
+octave_scalar::numeric_demotion_function (void) const
+{
+  return octave_base_value::type_conv_info(default_numeric_demotion_function,
+                                           octave_float_scalar::static_type_id ());
+}
+
+octave_value
+octave_scalar::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // FIXME -- this doesn't solve the problem of
+  //
+  //   a = 1; a([1,1], [1,1], [1,1])
+  //
+  // and similar constructions.  Hmm...
+
+  // FIXME -- using this constructor avoids narrowing the
+  // 1x1 matrix back to a scalar value.  Need a better solution
+  // to this problem.
+
+  octave_value tmp (new octave_matrix (matrix_value ()));
+
+  return tmp.do_index_op (idx, resize_ok);
+}
+
+octave_value 
+octave_scalar::resize (const dim_vector& dv, bool fill) const
+{
+  if (fill)
+    {
+      NDArray retval (dv, NDArray::resize_fill_value());
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+  else
+    {
+      NDArray retval (dv);
+
+      if (dv.numel ())
+	retval(0) = scalar;
+
+      return retval;
+    }
+}
+
+octave_value
+octave_scalar::convert_to_str_internal (bool, bool, char type) const
+{
+  octave_value retval;
+
+  if (xisnan (scalar))
+    ::error ("invalid conversion from NaN to character");
+  else
+    {
+      int ival = NINT (scalar);
+
+      if (ival < 0 || ival > UCHAR_MAX)
+	{
+	  // FIXME -- is there something better we could do?
+
+	  ival = 0;
+
+	  ::warning ("range error for conversion to character value");
+	}
+
+      retval = octave_value (std::string (1, static_cast<char> (ival)), type);
+    }
+
+  return retval;
+}
+
+bool 
+octave_scalar::save_ascii (std::ostream& os)
+{
+  double d = double_value ();
+
+  octave_write_double (os, d);
+
+  os << "\n";
+
+  return true;
+}
+
+bool 
+octave_scalar::load_ascii (std::istream& is)
+{
+  scalar = octave_read_double (is);
+  if (!is)
+    {
+      error ("load: failed to load scalar constant");
+      return false;
+    }
+
+  return true;
+}
+
+bool 
+octave_scalar::save_binary (std::ostream& os, bool& /* save_as_floats */)
+{
+  char tmp = LS_DOUBLE;
+  os.write (reinterpret_cast<char *> (&tmp), 1);
+  double dtmp = double_value ();
+  os.write (reinterpret_cast<char *> (&dtmp), 8);
+
+  return true;
+}
+
+bool 
+octave_scalar::load_binary (std::istream& is, bool swap,
+			    oct_mach_info::float_format fmt)
+{
+  char tmp;
+  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
+    return false;
+
+  double dtmp;
+  read_doubles (is, &dtmp, static_cast<save_type> (tmp), 1, swap, fmt);
+  if (error_state || ! is)
+    return false;
+
+  scalar = dtmp;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_scalar::save_hdf5 (hid_t loc_id, const char *name,
+			  bool /* save_as_floats */)
+{
+  hsize_t dimens[3];
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+
+  space_hid = H5Screate_simple (0, dimens, 0);
+  if (space_hid < 0) return false;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_DOUBLE, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0) 
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  double tmp = double_value ();
+  retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, &tmp) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool
+octave_scalar::load_hdf5 (hid_t loc_id, const char *name,
+			  bool /* have_h5giterate_bug */)
+{
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+
+  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
+
+  if (rank != 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  double dtmp;
+  if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, 
+	       H5P_DEFAULT, &dtmp) < 0)
+    { 
+      H5Dclose (data_hid);
+      return false;
+    }
+
+  scalar = dtmp;
+
+  H5Dclose (data_hid);
+
+  return true;
+}
+
+#endif
+
+mxArray *
+octave_scalar::as_mxArray (void) const
+{
+  mxArray *retval = new mxArray (mxDOUBLE_CLASS, 1, 1, mxREAL);
+
+  double *pr = static_cast<double *> (retval->get_data ());
+
+  pr[0] = scalar;
+
+  return retval;
+}
+
+#define SCALAR_MAPPER(MAP, FCN) \
+  octave_value \
+  octave_scalar::MAP (void) const \
+  { \
+    return octave_value (FCN (scalar)); \
+  }
+
+#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
+  octave_value \
+  octave_scalar::MAP (void) const \
+  { \
+    return (scalar < L1 || scalar > L2 \
+            ? octave_value (CFCN (Complex (scalar))) \
+	    : octave_value (RFCN (scalar))); \
+  }
+
+static double
+xconj (double x)
+{
+  return x;
+}
+
+SCALAR_MAPPER (erf, ::erf)
+SCALAR_MAPPER (erfc, ::erfc)
+SCALAR_MAPPER (gamma, xgamma)
+CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+SCALAR_MAPPER (abs, ::fabs)
+CD_SCALAR_MAPPER (acos, ::acos, ::acos, -1.0, 1.0)
+CD_SCALAR_MAPPER (acosh, ::acosh, ::acosh, 1.0, octave_Inf)
+SCALAR_MAPPER (angle, ::arg)
+SCALAR_MAPPER (arg, ::arg)
+CD_SCALAR_MAPPER (asin, ::asin, ::asin, -1.0, 1.0)
+SCALAR_MAPPER (asinh, ::asinh)
+SCALAR_MAPPER (atan, ::atan)
+CD_SCALAR_MAPPER (atanh, ::atanh, ::atanh, -1.0, 1.0)
+SCALAR_MAPPER (ceil, ::ceil)
+SCALAR_MAPPER (conj, xconj)
+SCALAR_MAPPER (cos, ::cos)
+SCALAR_MAPPER (cosh, ::cosh)
+SCALAR_MAPPER (exp, ::exp)
+SCALAR_MAPPER (expm1, ::expm1)
+SCALAR_MAPPER (fix, ::fix)
+SCALAR_MAPPER (floor, ::floor)
+SCALAR_MAPPER (imag, ::imag)
+CD_SCALAR_MAPPER (log, ::log, std::log, 0.0, octave_Inf)
+CD_SCALAR_MAPPER (log2, xlog2, xlog2, 0.0, octave_Inf)
+CD_SCALAR_MAPPER (log10, ::log10, std::log10, 0.0, octave_Inf)
+CD_SCALAR_MAPPER (log1p, ::log1p, ::log1p, -1.0, octave_Inf)
+SCALAR_MAPPER (real, ::real)
+SCALAR_MAPPER (round, xround)
+SCALAR_MAPPER (roundb, xroundb)
+SCALAR_MAPPER (signum, ::signum)
+SCALAR_MAPPER (sin, ::sin)
+SCALAR_MAPPER (sinh, ::sinh)
+CD_SCALAR_MAPPER (sqrt, ::sqrt, std::sqrt, 0.0, octave_Inf)
+SCALAR_MAPPER (tan, ::tan)
+SCALAR_MAPPER (tanh, ::tanh)
+SCALAR_MAPPER (finite, xfinite)
+SCALAR_MAPPER (isinf, xisinf)
+SCALAR_MAPPER (isna, octave_is_NA)
+SCALAR_MAPPER (isnan, xisnan)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-scalar.h b/src/ov-scalar.h
new file mode 100644
index 0000000..65e1858
--- /dev/null
+++ b/src/ov-scalar.h
@@ -0,0 +1,300 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_scalar_h)
+#define octave_scalar_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "lo-ieee.h"
+#include "lo-mappers.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "str-vec.h"
+
+#include "gripes.h"
+#include "ov-base.h"
+#include "ov-re-mat.h"
+#include "ov-base-scalar.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Real scalar values.
+
+class
+OCTINTERP_API
+octave_scalar : public octave_base_scalar<double>
+{
+public:
+
+  octave_scalar (void)
+    : octave_base_scalar<double> (0.0) { }
+
+  octave_scalar (double d)
+    : octave_base_scalar<double> (d) { }
+
+  octave_scalar (const octave_scalar& s)
+    : octave_base_scalar<double> (s) { }
+
+  ~octave_scalar (void) { }
+
+  octave_base_value *clone (void) const { return new octave_scalar (*this); }
+
+  // We return an octave_matrix here instead of an octave_scalar so
+  // that in expressions like A(2,2,2) = 2 (for A previously
+  // undefined), A will be empty instead of a 1x1 object.
+  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  type_conv_info numeric_demotion_function (void) const;
+
+  idx_vector index_vector (void) const { return idx_vector (scalar); }
+
+  octave_value any (int = 0) const
+    { return (scalar != 0 && ! lo_ieee_isnan (scalar)); }
+
+  bool is_real_scalar (void) const { return true; }
+
+  bool is_real_type (void) const { return true; }
+
+  bool is_double_type (void) const { return true; }
+
+  bool is_float_type (void) const { return true; }
+
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), scalar); }
+
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), scalar); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), scalar); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), scalar); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), scalar); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), scalar); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), scalar); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), scalar); }
+
+#define DEFINE_INT_SCALAR_VALUE(TYPE) \
+  octave_ ## TYPE \
+  TYPE ## _scalar_value (void) const \
+    { return octave_ ## TYPE (scalar); }
+
+  DEFINE_INT_SCALAR_VALUE (int8)
+  DEFINE_INT_SCALAR_VALUE (int16)
+  DEFINE_INT_SCALAR_VALUE (int32)
+  DEFINE_INT_SCALAR_VALUE (int64)
+  DEFINE_INT_SCALAR_VALUE (uint8)
+  DEFINE_INT_SCALAR_VALUE (uint16)
+  DEFINE_INT_SCALAR_VALUE (uint32)
+  DEFINE_INT_SCALAR_VALUE (uint64)
+
+#undef DEFINE_INT_SCALAR_VALUE
+
+  double double_value (bool = false) const { return scalar; }
+
+  float float_value (bool = false) const { return static_cast<float> (scalar); }
+
+  double scalar_value (bool = false) const { return scalar; }
+
+  float float_scalar_value (bool = false) const { return static_cast<float> (scalar); }
+
+  Matrix matrix_value (bool = false) const
+    { return Matrix (1, 1, scalar); }
+
+  FloatMatrix float_matrix_value (bool = false) const
+    { return FloatMatrix (1, 1, scalar); }
+
+  NDArray array_value (bool = false) const
+    { return NDArray (dim_vector (1, 1), scalar); }
+
+  FloatNDArray float_array_value (bool = false) const
+    { return FloatNDArray (dim_vector (1, 1), scalar); }
+
+  SparseMatrix sparse_matrix_value (bool = false) const
+    { return SparseMatrix (Matrix (1, 1, scalar)); }
+
+  // FIXME Need SparseComplexMatrix (Matrix) constructor!!!
+  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
+    { return SparseComplexMatrix (sparse_matrix_value ()); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  Complex complex_value (bool = false) const { return scalar; }
+
+  FloatComplex float_complex_value (bool = false) const { return scalar; }
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+    { return  ComplexMatrix (1, 1, Complex (scalar)); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool = false) const
+    { return  FloatComplexMatrix (1, 1, FloatComplex (scalar)); }
+
+  ComplexNDArray complex_array_value (bool = false) const
+    { return ComplexNDArray (dim_vector (1, 1), Complex (scalar)); }
+
+  FloatComplexNDArray float_complex_array_value (bool = false) const
+    { return FloatComplexNDArray (dim_vector (1, 1), FloatComplex (scalar)); }
+
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = static_cast<char> (scalar);
+    return retval;
+  }
+
+  bool bool_value (bool warn = false) const
+  {
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
+      gripe_logical_conversion ();
+
+    return scalar;
+  }
+
+  boolNDArray bool_array_value (bool warn = false) const
+  {
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
+      gripe_logical_conversion ();
+
+    return boolNDArray (dim_vector (1, 1), scalar);
+  }
+
+  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+
+  void increment (void) { ++scalar; }
+
+  void decrement (void) { --scalar; }
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    {
+      return os.write (array_value (), block_size, output_type,
+		       skip, flt_fmt);
+    }
+
+  mxArray *as_mxArray (void) const;
+
+  octave_value erf (void) const;
+  octave_value erfc (void) const;
+  octave_value gamma (void) const;
+  octave_value lgamma (void) const;
+  octave_value abs (void) const;
+  octave_value acos (void) const;
+  octave_value acosh (void) const;
+  octave_value angle (void) const;
+  octave_value arg (void) const;
+  octave_value asin (void) const;
+  octave_value asinh (void) const;
+  octave_value atan (void) const;
+  octave_value atanh (void) const;
+  octave_value ceil (void) const;
+  octave_value conj (void) const;
+  octave_value cos (void) const;
+  octave_value cosh (void) const;
+  octave_value exp (void) const;
+  octave_value expm1 (void) const;
+  octave_value fix (void) const;
+  octave_value floor (void) const;
+  octave_value imag (void) const;
+  octave_value log (void) const;
+  octave_value log2 (void) const;
+  octave_value log10 (void) const;
+  octave_value log1p (void) const;
+  octave_value real (void) const;
+  octave_value round (void) const;
+  octave_value roundb (void) const;
+  octave_value signum (void) const;
+  octave_value sin (void) const;
+  octave_value sinh (void) const;
+  octave_value sqrt (void) const;
+  octave_value tan (void) const;
+  octave_value tanh (void) const;
+  octave_value finite (void) const;
+  octave_value isinf (void) const;
+  octave_value isna (void) const;
+  octave_value isnan (void) const;
+
+private:
+  octave_value map (double (*fcn) (double)) const;
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-str-mat.cc b/src/ov-str-mat.cc
new file mode 100644
index 0000000..3876aa8
--- /dev/null
+++ b/src/ov-str-mat.cc
@@ -0,0 +1,797 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <iostream>
+#include <vector>
+
+#include "data-conv.h"
+#include "lo-ieee.h"
+#include "mach-info.h"
+#include "mx-base.h"
+#include "oct-locbuf.h"
+
+#include "byte-swap.h"
+#include "defun.h"
+#include "gripes.h"
+#include "ls-ascii-helper.h"
+#include "ls-hdf5.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ops.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
+#include "ov-str-mat.h"
+#include "pr-output.h"
+#include "pt-mat.h"
+#include "utils.h"
+
+DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_str);
+DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_sq_str);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_str, "string", "char");
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_sq_str, "sq_string", "char");
+
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
+{
+  octave_base_value *retval = 0;
+
+  CAST_CONV_ARG (const octave_char_matrix_str&);
+
+  NDArray nda = v.array_value (true);
+
+  if (! error_state)
+    {
+      if (nda.numel () == 1)
+        retval = new octave_scalar (nda(0));
+      else
+        retval = new octave_matrix (nda);
+    }
+
+  return retval;
+}
+
+octave_base_value::type_conv_info
+octave_char_matrix_str::numeric_conversion_function (void) const
+{
+  return octave_base_value::type_conv_info (default_numeric_conversion_function,
+                                            octave_matrix::static_type_id ());
+}
+
+octave_value
+octave_char_matrix_str::do_index_op_internal (const octave_value_list& idx,
+					      bool resize_ok, char type)
+{
+  octave_value retval;
+
+  octave_idx_type len = idx.length ();
+
+  switch (len)
+    {
+    case 0:
+      retval = octave_value (matrix, true, type);
+      break;
+
+    case 1:
+      {
+	idx_vector i = idx (0).index_vector ();
+
+	if (! error_state)
+	  retval = octave_value (charNDArray (matrix.index (i, resize_ok)),
+				 true, type);
+      }
+      break;
+
+    case 2:
+      {
+	idx_vector i = idx (0).index_vector ();
+	idx_vector j = idx (1).index_vector ();
+
+	if (! error_state)
+	  retval = octave_value (charNDArray (matrix.index (i, j, resize_ok)),
+				 true, type);
+      }
+      break;
+
+    default:
+      {
+	Array<idx_vector> idx_vec (len);
+
+	for (octave_idx_type i = 0; i < len; i++)
+	  idx_vec(i) = idx(i).index_vector ();
+
+	if (! error_state)
+	  retval = octave_value (charNDArray (matrix.index (idx_vec, resize_ok)),
+				 true, type);
+      }
+      break;
+    }
+
+  return retval;
+}
+
+octave_value 
+octave_char_matrix_str::resize (const dim_vector& dv, bool fill) const
+{
+  charNDArray retval (matrix);
+  if (fill)
+    retval.resize (dv, charNDArray::resize_fill_value());
+  else
+    retval.resize (dv);
+  return octave_value (retval, true);
+}
+
+#define CHAR_MATRIX_CONV(T, INIT, TNAME, FCN) \
+  T retval INIT; \
+ \
+  if (! force_string_conv) \
+    gripe_invalid_conversion ("string", TNAME); \
+  else \
+    { \
+      warning_with_id ("Octave:str-to-num", \
+		       "implicit conversion from %s to %s", \
+		       "string", TNAME); \
+ \
+      retval = octave_char_matrix::FCN (); \
+    } \
+ \
+  return retval
+
+double
+octave_char_matrix_str::double_value (bool force_string_conv) const
+{
+  CHAR_MATRIX_CONV (double, = 0, "real scalar", double_value);
+}
+
+Complex
+octave_char_matrix_str::complex_value (bool force_string_conv) const
+{
+  CHAR_MATRIX_CONV (Complex, = 0, "complex scalar", complex_value);
+}
+
+Matrix
+octave_char_matrix_str::matrix_value (bool force_string_conv) const
+{
+  CHAR_MATRIX_CONV (Matrix, , "real matrix", matrix_value);
+}
+
+ComplexMatrix
+octave_char_matrix_str::complex_matrix_value (bool force_string_conv) const
+{
+  CHAR_MATRIX_CONV (ComplexMatrix, , "complex matrix", complex_matrix_value);
+}
+
+NDArray
+octave_char_matrix_str::array_value (bool force_string_conv) const
+{
+  CHAR_MATRIX_CONV (NDArray, , "real N-d array", array_value);
+}
+
+ComplexNDArray
+octave_char_matrix_str::complex_array_value (bool force_string_conv) const
+{
+  CHAR_MATRIX_CONV (ComplexNDArray, , "complex N-d array",
+		    complex_array_value);
+}
+
+string_vector
+octave_char_matrix_str::all_strings (bool) const
+{
+  string_vector retval;
+
+  if (matrix.ndims () == 2)
+    {
+      charMatrix chm = matrix.matrix_value ();
+
+      octave_idx_type n = chm.rows ();
+
+      retval.resize (n);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	retval[i] = chm.row_as_string (i);
+    }
+  else
+    error ("invalid conversion of charNDArray to string_vector");
+
+  return retval;
+}
+
+std::string
+octave_char_matrix_str::string_value (bool) const
+{
+  std::string retval;
+
+  if (matrix.ndims () == 2)
+    {
+      charMatrix chm = matrix.matrix_value ();
+
+      retval = chm.row_as_string (0);  // FIXME???
+    }
+  else
+    error ("invalid conversion of charNDArray to string");
+
+  return retval;
+}
+
+void
+octave_char_matrix_str::print_raw (std::ostream& os, bool pr_as_read_syntax) const
+{
+  octave_print_internal (os, matrix, pr_as_read_syntax,
+			 current_print_indent_level (), true);
+}
+
+bool 
+octave_char_matrix_str::save_ascii (std::ostream& os)
+{
+  dim_vector d = dims ();
+  if (d.length () > 2)
+    {
+      charNDArray tmp = char_array_value ();
+      os << "# ndims: " << d.length () << "\n";
+      for (int i=0; i < d.length (); i++)
+	os << " " << d (i);
+      os << "\n";
+      os.write (tmp.fortran_vec (), d.numel ());
+      os << "\n";
+    }
+  else
+    {
+      // Keep this case, rather than use generic code above for
+      // backward compatiability. Makes load_ascii much more complex!!
+      charMatrix chm = char_matrix_value ();
+      octave_idx_type elements = chm.rows ();
+      os << "# elements: " << elements << "\n";
+      for (octave_idx_type i = 0; i < elements; i++)
+	{
+	  unsigned len = chm.cols ();
+	  os << "# length: " << len << "\n";
+	  std::string tstr = chm.row_as_string (i, false, true);
+	  const char *tmp = tstr.data ();
+	  if (tstr.length () > len)
+	    panic_impossible ();
+	  os.write (tmp, len);
+	  os << "\n";
+	}
+    }
+
+  return true;
+}
+
+bool 
+octave_char_matrix_str::load_ascii (std::istream& is)
+{
+  bool success = true;
+
+  string_vector keywords(3);
+
+  keywords[0] = "ndims";
+  keywords[1] = "elements";
+  keywords[2] = "length";
+
+  std::string kw;
+  int val = 0;
+
+  if (extract_keyword (is, keywords, kw, val, true))
+    {
+      if (kw == "ndims")
+	{
+	  int mdims = val;
+
+	  if (mdims >= 0)
+	    {
+	      dim_vector dv;
+	      dv.resize (mdims);
+
+	      for (int i = 0; i < mdims; i++)
+		is >> dv(i);
+
+	      if (is)
+		{
+		  charNDArray tmp(dv);
+
+		  if (tmp.is_empty ())
+		    matrix = tmp;
+		  else
+		    {
+		      char *ftmp = tmp.fortran_vec ();
+
+		      skip_preceeding_newline (is);
+
+		      if (! is.read (ftmp, dv.numel ()) || !is)
+			{
+			  error ("load: failed to load string constant");
+			  success = false;
+			}
+		      else
+			matrix = tmp;
+		    }
+		}
+	      else
+		{
+		  error ("load: failed to read dimensions");
+		  success = false;
+		}
+	    }
+	  else
+	    {
+	      error ("load: failed to extract matrix size");
+	      success = false;
+	    }
+	}
+      else if (kw == "elements")
+	{
+	  int elements = val;
+
+	  if (elements >= 0)
+	    {
+	      // FIXME -- need to be able to get max length
+	      // before doing anything.
+
+	      charMatrix chm (elements, 0);
+	      int max_len = 0;
+	      for (int i = 0; i < elements; i++)
+		{
+		  int len;
+		  if (extract_keyword (is, "length", len) && len >= 0)
+		    {
+		      // Use this instead of a C-style character
+		      // buffer so that we can properly handle
+		      // embedded NUL characters.
+		      charMatrix tmp (1, len);
+		      char *ptmp = tmp.fortran_vec ();
+
+		      if (len > 0 && ! is.read (ptmp, len))
+			{
+			  error ("load: failed to load string constant");
+			  success = false;
+			  break;
+			}
+		      else
+			{
+			  if (len > max_len)
+			    {
+			      max_len = len;
+			      chm.resize (elements, max_len, 0);
+			    }
+
+			  chm.insert (tmp, i, 0);
+			}
+		    }
+		  else
+		    {
+		      error ("load: failed to extract string length for element %d", 
+			     i+1);
+		      success = false;
+		    }
+		}
+	  
+	      if (! error_state)
+		matrix = chm;
+	    }
+	  else
+	    {
+	      error ("load: failed to extract number of string elements");
+	      success = false;
+	    }
+	}
+      else if (kw == "length")
+	{
+	  int len = val;
+      
+	  if (len >= 0)
+	    {
+	      // This is cruft for backward compatiability, 
+	      // but relatively harmless.
+
+	      // Use this instead of a C-style character buffer so
+	      // that we can properly handle embedded NUL characters.
+	      charMatrix tmp (1, len);
+	      char *ptmp = tmp.fortran_vec ();
+
+	      if (len > 0 && ! is.read (ptmp, len))
+		{
+		  error ("load: failed to load string constant");
+		}
+	      else
+		{
+		  if (is)
+		    matrix = tmp;
+		  else
+		    error ("load: failed to load string constant");
+		}
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      error ("load: failed to extract number of rows and columns");
+      success = false;
+    }
+
+  return success;
+}
+
+bool 
+octave_char_matrix_str::save_binary (std::ostream& os,
+				     bool& /* save_as_floats */)
+{
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  int32_t tmp = - d.length();
+  os.write (reinterpret_cast<char *> (&tmp), 4);
+  for (int i=0; i < d.length (); i++)
+    {
+      tmp = d(i);
+      os.write (reinterpret_cast<char *> (&tmp), 4);
+    }
+
+  charNDArray m = char_array_value ();
+  os.write (m.fortran_vec (), d.numel ());
+  return true;
+}
+
+bool 
+octave_char_matrix_str::load_binary (std::istream& is, bool swap,
+				     oct_mach_info::float_format /* fmt */)
+{
+  int32_t elements;
+  if (! is.read (reinterpret_cast<char *> (&elements), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&elements);
+
+  if (elements < 0)
+    {
+      int32_t mdims = - elements;
+      int32_t di;
+      dim_vector dv;
+      dv.resize (mdims);
+
+      for (int i = 0; i < mdims; i++)
+	{
+	  if (! is.read (reinterpret_cast<char *> (&di), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&di);
+	  dv(i) = di;
+	}
+      
+      // Convert an array with a single dimension to be a row vector.
+      // Octave should never write files like this, other software
+      // might.
+
+      if (mdims == 1)
+	{
+	  mdims = 2;
+	  dv.resize (mdims);
+	  dv(1) = dv(0);
+	  dv(0) = 1;
+	}
+
+      charNDArray m(dv);
+      char *tmp = m.fortran_vec ();
+      is.read (tmp, dv.numel ());
+      
+      if (error_state || ! is)
+	return false;
+      matrix = m;
+    }
+  else
+    {
+      charMatrix chm (elements, 0);
+      int max_len = 0;
+      for (int i = 0; i < elements; i++)
+	{
+	  int32_t len;
+	  if (! is.read (reinterpret_cast<char *> (&len), 4))
+	    return false;
+	  if (swap)
+	    swap_bytes<4> (&len);
+	  charMatrix btmp (1, len);
+	  char *pbtmp = btmp.fortran_vec ();
+	  if (! is.read (pbtmp, len))
+	    return false;
+	  if (len > max_len)
+	    {
+	      max_len = len;
+	      chm.resize (elements, max_len, 0);
+	    }
+	  chm.insert (btmp, i, 0);
+	}
+      matrix = chm;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name,
+				   bool /* save_as_floats */)
+{
+  dim_vector dv = dims ();
+  int empty = save_hdf5_empty (loc_id, name, dv);
+  if (empty)
+    return (empty > 0);
+
+  int rank = dv.length ();
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  charNDArray m = char_array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = dv (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, 0);
+  if (space_hid < 0)
+    return false;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, s, dv.numel ());
+
+  for (int i = 0; i < dv.numel (); ++i)
+    s[i] = m(i);
+
+  retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, 
+		     H5P_DEFAULT, s) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  return retval;
+}
+
+bool 
+octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name,
+				   bool /* have_h5giterate_bug */)
+{
+  bool retval = false;
+
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty)
+    return (empty > 0);
+
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_hid = H5Dget_space (data_hid);
+  hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
+  hid_t type_hid = H5Dget_type (data_hid);
+  hid_t type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid == H5T_INTEGER)
+    {
+      if (rank < 1)
+	{
+	  H5Tclose (type_hid);
+	  H5Sclose (space_hid);
+	  H5Dclose (data_hid);
+	  return false;
+	}
+
+      OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+      OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+      H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+      // Octave uses column-major, while HDF5 uses row-major ordering
+      if (rank == 1)
+	{
+	  dv.resize (2);
+	  dv(0) = 1;
+	  dv(1) = hdims[0];
+	}
+      else
+	{
+	  dv.resize (rank);
+	  for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
+	    dv(j) = hdims[i];
+	}
+
+      charNDArray m (dv);
+      char *str = m.fortran_vec ();
+      if (H5Dread (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, 
+		   H5P_DEFAULT, str) >= 0) 
+	{
+	  retval = true;
+	  matrix = m;
+	}
+
+      H5Tclose (type_hid);
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      return true;
+    }
+  else
+    {
+      // This is cruft for backward compatiability and easy data
+      // importation
+      if (rank == 0)
+	{
+	  // a single string:
+	  int slen = H5Tget_size (type_hid);
+	  if (slen < 0)
+	    {
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return false;
+	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (char, s, slen);
+	      // create datatype for (null-terminated) string
+	      // to read into:
+	      hid_t st_id = H5Tcopy (H5T_C_S1);
+	      H5Tset_size (st_id, slen);
+	      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, s) < 0)
+		{
+		  H5Tclose (st_id);
+		  H5Tclose (type_hid);
+		  H5Sclose (space_hid);
+		  H5Dclose (data_hid);
+		  return false;
+		}
+
+	      matrix = charMatrix (s);
+	  
+	      H5Tclose (st_id);
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return true;
+	    }
+	}
+      else if (rank == 1)
+	{
+	  // string vector
+	  hsize_t elements, maxdim;
+	  H5Sget_simple_extent_dims (space_hid, &elements, &maxdim);
+	  int slen = H5Tget_size (type_hid);
+	  if (slen < 0)
+	    {
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return false;
+	    }
+	  else
+	    {
+	      // hdf5 string arrays store strings of all the
+	      // same physical length (I think), which is
+	      // slightly wasteful, but oh well.
+	  
+	      OCTAVE_LOCAL_BUFFER (char, s, elements * slen);
+
+	      // create datatype for (null-terminated) string
+	      // to read into:
+	      hid_t st_id = H5Tcopy (H5T_C_S1);
+	      H5Tset_size (st_id, slen);
+
+	      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, s) < 0)
+		{
+		  H5Tclose (st_id);
+		  H5Tclose (type_hid);
+		  H5Sclose (space_hid);
+		  H5Dclose (data_hid);
+		  return false;
+		}
+
+	      charMatrix chm (elements, slen - 1);
+	      for (hsize_t i = 0; i < elements; ++i)
+		{
+		  chm.insert (s + i*slen, i, 0);
+		}
+
+	      matrix = chm;
+
+	      H5Tclose (st_id);
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return true;
+	    }
+	}
+      else
+	{
+	  H5Tclose (type_hid);
+	  H5Sclose (space_hid);
+	  H5Dclose (data_hid);
+	  return false;
+	}
+    }
+
+  return retval;
+}
+
+#endif
+
+#define MACRO_WRAPPER(FCN, CTYPE_FCN) \
+  static int x ## FCN (int c) { return CTYPE_FCN (c); }
+
+#define STRING_MAPPER(FCN, AMAP, CTYPE_FCN) \
+  MACRO_WRAPPER (FCN, CTYPE_FCN) \
+ \
+  octave_value \
+  octave_char_matrix_str::FCN (void) const \
+  { \
+    static charNDArray::mapper smap = x ## FCN; \
+    return matrix.AMAP (smap);  \
+  }
+
+#define TOSTRING_MAPPER(FCN, AMAP, CTYPE_FCN) \
+  MACRO_WRAPPER (FCN, CTYPE_FCN) \
+ \
+  octave_value \
+  octave_char_matrix_str::FCN (void) const \
+  { \
+    static charNDArray::mapper smap = x ## FCN; \
+    return octave_value (matrix.AMAP (smap), true, \
+			 is_sq_string () ? '\'' : '"'); \
+  }
+
+STRING_MAPPER (xisalnum, bmap, isalnum)
+STRING_MAPPER (xisalpha, bmap, isalpha)
+STRING_MAPPER (xisascii, bmap, isascii)
+STRING_MAPPER (xiscntrl, bmap, iscntrl)
+STRING_MAPPER (xisdigit, bmap, isdigit)
+STRING_MAPPER (xisgraph, bmap, isgraph)
+STRING_MAPPER (xislower, bmap, islower)
+STRING_MAPPER (xisprint, bmap, isprint)
+STRING_MAPPER (xispunct, bmap, ispunct)
+STRING_MAPPER (xisspace, bmap, isspace)
+STRING_MAPPER (xisupper, bmap, isupper)
+STRING_MAPPER (xisxdigit, bmap, isxdigit)
+STRING_MAPPER (xtoascii, dmap, toascii)
+TOSTRING_MAPPER (xtolower, smap, tolower)
+TOSTRING_MAPPER (xtoupper, smap, toupper)
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-str-mat.h b/src/ov-str-mat.h
new file mode 100644
index 0000000..d4179f3
--- /dev/null
+++ b/src/ov-str-mat.h
@@ -0,0 +1,298 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_char_matrix_str_h)
+#define octave_char_matrix_str_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-stream.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-ch-mat.h"
+#include "ov-typeinfo.h"
+
+class Octave_map;
+class octave_value_list;
+
+class tree_walker;
+
+// Character matrix values with special properties for use as
+// strings.
+
+class
+OCTINTERP_API
+octave_char_matrix_str : public octave_char_matrix
+{
+public:
+
+  octave_char_matrix_str (void)
+    : octave_char_matrix () { }
+
+  octave_char_matrix_str (const charMatrix& chm)
+    : octave_char_matrix (chm) { }
+
+  octave_char_matrix_str (const charNDArray& chm)
+    : octave_char_matrix (chm) { }
+
+  octave_char_matrix_str (char c)
+    : octave_char_matrix (c) { }
+
+  octave_char_matrix_str (const char *s)
+    : octave_char_matrix (s) { }
+
+  octave_char_matrix_str (const std::string& s)
+    : octave_char_matrix (s) { }
+
+  octave_char_matrix_str (const string_vector& s)
+    : octave_char_matrix (s) { }
+
+  octave_char_matrix_str (const octave_char_matrix& chm)
+    : octave_char_matrix (chm) { }
+
+  octave_char_matrix_str (const octave_char_matrix_str& chms)
+    : octave_char_matrix (chms) { }
+
+  ~octave_char_matrix_str (void) { }
+
+  octave_base_value *clone (void) const { return new octave_char_matrix_str (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_char_matrix_str (); }
+
+  type_conv_info numeric_conversion_function (void) const;
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false)
+    { return do_index_op_internal (idx, resize_ok); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return octave_value (charNDArray (matrix.reshape (new_dims)), true); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return octave_value (charNDArray (matrix.permute (vec, inv)), true); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const;
+
+  bool is_string (void) const { return true; }
+
+  bool is_real_type (void) const { return false; }
+
+  bool is_matrix_type (void) const { return false; }
+
+  bool is_numeric_type (void) const { return false; }
+
+  double double_value (bool = false) const;
+
+  Matrix matrix_value (bool = false) const;
+
+  NDArray array_value (bool = false) const;
+
+  Complex complex_value (bool = false) const;
+
+  ComplexMatrix complex_matrix_value (bool = false) const;
+
+  ComplexNDArray complex_array_value (bool = false) const;
+
+  string_vector all_strings (bool pad = false) const;
+
+  std::string string_value (bool force = false) const;
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (dim, mode), true); }
+
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (sidx, dim, mode), true); }
+
+  bool print_as_scalar (void) const { return (rows () <= 1); }
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  int write (octave_stream& os, int block_size,
+	     oct_data_conv::data_type output_type, int skip,
+	     oct_mach_info::float_format flt_fmt) const
+    { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
+
+  octave_value xisalnum (void) const;
+  octave_value xisalpha (void) const;
+  octave_value xisascii (void) const;
+  octave_value xiscntrl (void) const;
+  octave_value xisdigit (void) const;
+  octave_value xisgraph (void) const;
+  octave_value xislower (void) const;
+  octave_value xisprint (void) const;
+  octave_value xispunct (void) const;
+  octave_value xisspace (void) const;
+  octave_value xisupper (void) const;
+  octave_value xisxdigit (void) const;
+  octave_value xtoascii (void) const;
+  octave_value xtolower (void) const;
+  octave_value xtoupper (void) const;
+
+#define MAT_MAPPER(MAP) \
+  octave_value MAP (void) const \
+    { \
+      octave_matrix m (array_value (true)); \
+      return m.MAP (); \
+    }
+
+  MAT_MAPPER (abs)
+  MAT_MAPPER (angle)
+  MAT_MAPPER (arg)
+  MAT_MAPPER (ceil)
+  MAT_MAPPER (conj)
+  MAT_MAPPER (fix)
+  MAT_MAPPER (floor)
+  MAT_MAPPER (imag)
+  MAT_MAPPER (real)
+  MAT_MAPPER (round)
+  MAT_MAPPER (signum)
+
+#undef MAT_MAPPER
+
+#define BOOL_MAT_MAPPER(MAP, VAL)	\
+  octave_value MAP (void) const \
+    { \
+      return boolNDArray (matrix.dims (), VAL); \
+    }
+
+  BOOL_MAT_MAPPER (finite, true)
+  BOOL_MAT_MAPPER (isinf, false)
+  BOOL_MAT_MAPPER (isna, false)
+  BOOL_MAT_MAPPER (isnan, false)
+
+#undef BOOL_MAT_MAPPER
+
+protected:
+
+  octave_value do_index_op_internal (const octave_value_list& idx,
+				     bool resize_ok, char type = '"');
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+typedef octave_char_matrix_str octave_char_matrix_dq_str;
+
+class
+octave_char_matrix_sq_str : public octave_char_matrix_str
+{
+public:
+
+  octave_char_matrix_sq_str (void)
+    : octave_char_matrix_str () { }
+
+  octave_char_matrix_sq_str (const charMatrix& chm)
+    : octave_char_matrix_str (chm) { }
+
+  octave_char_matrix_sq_str (const charNDArray& chm)
+    : octave_char_matrix_str (chm) { }
+
+  octave_char_matrix_sq_str (char c)
+    : octave_char_matrix_str (c) { }
+
+  octave_char_matrix_sq_str (const char *s)
+    : octave_char_matrix_str (s) { }
+
+  octave_char_matrix_sq_str (const std::string& s)
+    : octave_char_matrix_str (s) { }
+
+  octave_char_matrix_sq_str (const string_vector& s)
+    : octave_char_matrix_str (s) { }
+
+  octave_char_matrix_sq_str (const octave_char_matrix_str& chm)
+    : octave_char_matrix_str (chm) { }
+
+  octave_char_matrix_sq_str (const octave_char_matrix_sq_str& chms)
+    : octave_char_matrix_str (chms) { }
+
+  ~octave_char_matrix_sq_str (void) { }
+
+  octave_base_value *clone (void) const { return new octave_char_matrix_sq_str (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_char_matrix_sq_str (); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return octave_value (charNDArray (matrix.reshape (new_dims)), true, '\''); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return octave_value (charNDArray (matrix.permute (vec, inv)), true, '\''); }
+
+  octave_value resize (const dim_vector& dv, bool = false) const
+    {
+      charNDArray retval (matrix);
+      retval.resize (dv);
+      return octave_value (retval, true, '\'');
+    }
+
+  bool is_sq_string (void) const { return true; }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false)
+    { return do_index_op_internal (idx, resize_ok, '\''); }
+
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (dim, mode), true, '\''); }
+
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		     sortmode mode = ASCENDING) const
+    { return octave_value (matrix.sort (sidx, dim, mode), true, '\''); }
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-struct.cc b/src/ov-struct.cc
new file mode 100644
index 0000000..b73100a
--- /dev/null
+++ b/src/ov-struct.cc
@@ -0,0 +1,1520 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-lvalue.h"
+#include "ov-list.h"
+#include "ov-struct.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+#include "Array-util.h"
+#include "oct-locbuf.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-oct-binary.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+#include "pr-output.h"
+
+DEFINE_OCTAVE_ALLOCATOR(octave_struct);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct", "struct");
+
+Cell
+octave_struct::dotref (const octave_value_list& idx, bool auto_add)
+{
+  Cell retval;
+
+  assert (idx.length () == 1);
+
+  std::string nm = idx(0).string_value ();
+
+  Octave_map::const_iterator p = map.seek (nm);
+
+  if (p != map.end ())
+    retval = map.contents (p);
+  else if (auto_add)
+    retval = (numel () == 0) ? Cell (dim_vector (1)) : Cell (dims ());
+  else 
+    error ("structure has no member `%s'", nm.c_str ());
+
+  return retval;
+}
+
+#if 0
+static void
+gripe_invalid_index (void)
+{
+  error ("invalid index for structure array");
+}
+#endif
+
+static void
+gripe_invalid_index_for_assignment (void)
+{
+  error ("invalid index for structure array assignment");
+}
+
+static void
+gripe_invalid_index_type (const std::string& nm, char t)
+{
+  error ("%s cannot be indexed with %c", nm.c_str (), t);
+}
+
+static void
+gripe_failed_assignment (void)
+{
+  error ("assignment to structure element failed");
+}
+
+octave_value_list
+octave_struct::subsref (const std::string& type,
+			const std::list<octave_value_list>& idx,
+			int nargout)
+{
+  octave_value_list retval;
+
+  int skip = 1;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	if (type.length () > 1 && type[1] == '.')
+	  {
+	    std::list<octave_value_list>::const_iterator p = idx.begin ();
+	    octave_value_list key_idx = *++p;
+
+	    const Cell tmp = dotref (key_idx);
+
+	    if (! error_state)
+	      {
+		const Cell t = tmp.index (idx.front ());
+
+		retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true);
+
+		// We handled two index elements, so tell
+		// next_subsref to skip both of them.
+
+		skip++;
+	      }
+	  }
+	else
+	  retval(0) = map.index (idx.front ());
+      }
+      break;
+
+    case '.':
+      {
+	if (map.numel() > 0)
+	  {
+	    const Cell t = dotref (idx.front ());
+
+	    retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true);
+	  }
+      }
+      break;
+
+    case '{':
+      gripe_invalid_index_type (type_name (), type[0]);
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+
+  if (idx.size () > 1)
+    retval = retval(0).next_subsref (nargout, type, idx, skip);
+
+  return retval;
+}
+
+octave_value
+octave_struct::subsref (const std::string& type,
+			const std::list<octave_value_list>& idx,
+			bool auto_add)
+{
+  octave_value retval;
+
+  int skip = 1;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	if (type.length () > 1 && type[1] == '.')
+	  {
+	    std::list<octave_value_list>::const_iterator p = idx.begin ();
+	    octave_value_list key_idx = *++p;
+
+	    const Cell tmp = dotref (key_idx, auto_add);
+
+	    if (! error_state)
+	      {
+		const Cell t = tmp.index (idx.front (), auto_add);
+
+		retval = (t.length () == 1) ? t(0) : octave_value (t, true);
+
+		// We handled two index elements, so tell
+		// next_subsref to skip both of them.
+
+		skip++;
+	      }
+	  }
+	else
+	  retval = map.index (idx.front (), auto_add);
+      }
+      break;
+
+    case '.':
+      {
+	if (map.numel() > 0)
+	  {
+	    const Cell t = dotref (idx.front (), auto_add);
+
+	    retval = (t.length () == 1) ? t(0) : octave_value (t, true);
+	  }
+      }
+      break;
+
+    case '{':
+      gripe_invalid_index_type (type_name (), type[0]);
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_user_function::subsref.
+
+  if (idx.size () > 1)
+    retval = retval.next_subsref (auto_add, type, idx, skip);
+
+  return retval;
+}
+
+/*
+%!test
+%! x(1).a.a = 1; x(2).a.a = 2;
+%! assert (size (x), [1, 2]);
+%! assert (x(1).a.a, 1);
+%! assert (x(2).a.a, 2);
+*/
+
+octave_value
+octave_struct::numeric_conv (const octave_value& val,
+			     const std::string& type)
+{
+  octave_value retval;
+
+  if (type.length () > 0 && type[0] == '.' && ! val.is_map ())
+    retval = Octave_map ();
+  else
+    retval = val;
+
+  return retval;
+}
+
+octave_value
+octave_struct::subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs)
+{
+  octave_value retval;
+
+  int n = type.length ();
+
+  octave_value t_rhs = rhs;
+
+  if (idx.front ().empty ())
+    {
+      error ("missing index in indexed assignment");
+      return retval;
+    }
+
+  if (n > 1 && ! (type.length () == 2 && type[0] == '(' && type[1] == '.'))
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (type.length () > 1 && type[1] == '.')
+	      {
+		std::list<octave_value_list>::const_iterator p = idx.begin ();
+		octave_value_list t_idx = *p;
+
+		octave_value_list key_idx = *++p;
+
+		assert (key_idx.length () == 1);
+
+		std::string key = key_idx(0).string_value ();
+
+                std::list<octave_value_list> next_idx (idx);
+
+                // We handled two index elements, so subsasgn to
+                // needs to skip both of them.
+
+                next_idx.erase (next_idx.begin ());
+                next_idx.erase (next_idx.begin ());
+
+                std::string next_type = type.substr (2);
+
+                Cell tmpc (1, 1);
+                Octave_map::iterator pkey = map.seek (key);
+                if (pkey != map.end ())
+                  {
+                    pkey->second.make_unique ();
+                    tmpc = pkey->second.index (idx.front (), true);
+                  }
+
+                // FIXME: better code reuse? cf. octave_cell::subsasgn and the case below.
+		if (! error_state)
+		  {
+                    if (tmpc.numel () == 1)
+                      {
+                        octave_value& tmp = tmpc(0);
+
+                        if (! tmp.is_defined () || tmp.is_zero_by_zero ())
+                          {
+                            tmp = octave_value::empty_conv (next_type, rhs);
+                            tmp.make_unique (); // probably a no-op.
+                          }
+                        else
+                          // optimization: ignore the copy still stored inside our map.
+                          tmp.make_unique (1);
+
+                        if (! error_state)
+                          t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
+                      }
+                    else
+                      gripe_indexed_cs_list ();
+		  }
+	      }
+	    else
+	      gripe_invalid_index_for_assignment ();
+	  }
+	  break;
+
+	case '.':
+	  {
+	    octave_value_list key_idx = idx.front ();
+
+	    assert (key_idx.length () == 1);
+
+	    std::string key = key_idx(0).string_value ();
+
+            std::list<octave_value_list> next_idx (idx);
+
+            next_idx.erase (next_idx.begin ());
+
+            std::string next_type = type.substr (1);
+
+            Cell tmpc (1, 1);
+            Octave_map::iterator pkey = map.seek (key);
+            if (pkey != map.end ())
+              {
+                pkey->second.make_unique ();
+                tmpc = pkey->second;
+              }
+
+            // FIXME: better code reuse?
+            if (! error_state)
+              {
+                if (tmpc.numel () == 1)
+                  {
+                    octave_value& tmp = tmpc(0);
+
+                    if (! tmp.is_defined () || tmp.is_zero_by_zero ())
+                      {
+                        tmp = octave_value::empty_conv (next_type, rhs);
+                        tmp.make_unique (); // probably a no-op.
+                      }
+                    else
+                      // optimization: ignore the copy still stored inside our map.
+                      tmp.make_unique (1);
+
+                    if (! error_state)
+                      t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
+                  }
+                else
+                  gripe_indexed_cs_list ();
+              }
+	  }
+	  break;
+
+	case '{':
+	  gripe_invalid_index_type (type_name (), type[0]);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+
+  if (! error_state)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (n > 1 && type[1] == '.')
+	      {
+		std::list<octave_value_list>::const_iterator p = idx.begin ();
+		octave_value_list key_idx = *++p;
+                octave_value_list idxf = idx.front ();
+
+		assert (key_idx.length () == 1);
+
+		std::string key = key_idx(0).string_value ();
+
+		if (! error_state)
+		  {
+                    if (t_rhs.is_cs_list ())
+                      {
+                        Cell tmp_cell = Cell (t_rhs.list_value ());
+
+                        // Inquire the proper shape of the RHS.
+
+                        dim_vector didx = dims ().redim (idxf.length ());
+                        for (octave_idx_type k = 0; k < idxf.length (); k++)
+                          if (! idxf(k).is_magic_colon ()) didx(k) = idxf(k).numel ();
+
+                        if (didx.numel () == tmp_cell.numel ())
+                          tmp_cell = tmp_cell.reshape (didx);
+
+
+                        map.assign (idxf, key, tmp_cell);
+
+                        if (! error_state)
+                          {
+                            count++;
+                            retval = octave_value (this);
+                          }
+                        else
+                          gripe_failed_assignment ();
+                      }
+                    else 
+                      {
+                        const Octave_map& cmap = const_cast<const Octave_map &> (map);
+                        // cast map to const reference to avoid forced key insertion.
+                        if (idxf.all_scalars () 
+                            || cmap.contents (key).index (idxf, true).numel () == 1)
+                          {
+                            map.assign (idxf, key, t_rhs.storable_value ());
+                            if (! error_state)
+                              {
+                                count++;
+                                retval = octave_value (this);
+                              }
+                            else
+                              gripe_failed_assignment ();
+                          }
+                        else if (! error_state)
+                          error ("invalid assignment to cs-list outside multiple assignment.");
+                      }
+		  }
+		else
+		  gripe_failed_assignment ();
+	      }
+	    else
+	      {
+		if (t_rhs.is_map())
+		  {
+		    Octave_map rhs_map = t_rhs.map_value ();
+
+		    if (! error_state)
+		      {
+			map.assign (idx.front (), rhs_map);
+
+			if (! error_state)
+			  {
+			    count++;
+			    retval = octave_value (this);
+			  }
+			else
+			  gripe_failed_assignment ();
+		      }
+		    else
+		      error ("invalid structure assignment");
+		  }
+		else
+		  {
+		    if (t_rhs.is_null_value()) 
+		      {
+			map.maybe_delete_elements (idx.front());
+
+			if (! error_state)
+			  {
+			    count++;
+			    retval = octave_value (this);
+			  }
+			else
+			  gripe_failed_assignment ();
+		      }
+		    else
+		      error ("invalid structure assignment");
+		  }
+	      }
+	  }
+	  break;
+
+	case '.':
+	  {
+	    octave_value_list key_idx = idx.front ();
+
+	    assert (key_idx.length () == 1);
+
+	    std::string key = key_idx(0).string_value ();
+
+	    if (t_rhs.is_cs_list ())
+	      {
+		Cell tmp_cell = Cell (t_rhs.list_value ());
+
+		// The shape of the RHS is irrelevant, we just want
+		// the number of elements to agree and to preserve the
+		// shape of the left hand side of the assignment.
+
+		if (numel () == tmp_cell.numel ())
+		  tmp_cell = tmp_cell.reshape (dims ());
+
+		map.assign (key, tmp_cell);
+	      }
+	    else
+              // Regularize a null matrix if stored into a struct component.
+	      map.assign (key, t_rhs.storable_value ());
+
+	    if (! error_state)
+	      {
+		count++;
+		retval = octave_value (this);
+	      }
+	    else
+	      gripe_failed_assignment ();
+	  }
+	  break;
+
+	case '{':
+	  gripe_invalid_index_type (type_name (), type[0]);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+  else
+    gripe_failed_assignment ();
+
+  return retval;
+}
+
+octave_value
+octave_struct::do_index_op (const octave_value_list& idx, bool resize_ok)
+{
+  // Octave_map handles indexing itself.
+  return map.index (idx, resize_ok);
+}
+
+size_t
+octave_struct::byte_size (void) const
+{
+  // Neglect the size of the fieldnames.
+
+  size_t retval = 0;
+
+  for (Octave_map::const_iterator p = map.begin (); p != map.end (); p++)
+    {
+      std::string key = map.key (p);
+
+      octave_value val = octave_value (map.contents (p));
+
+      retval += val.byte_size ();
+    }
+
+  return retval;
+}
+
+void
+octave_struct::print (std::ostream& os, bool) const
+{
+  print_raw (os);
+}
+
+void
+octave_struct::print_raw (std::ostream& os, bool) const
+{
+  unwind_protect::begin_frame ("octave_struct_print");
+
+  unwind_protect_int (Vstruct_levels_to_print);
+
+  if (Vstruct_levels_to_print >= 0)
+    {
+      bool print_keys_only = Vstruct_levels_to_print-- == 0;
+
+      indent (os);
+      os << "{";
+      newline (os);
+
+      increment_indent_level ();
+
+      octave_idx_type n = map.numel ();
+
+      if (n != 1 || print_keys_only)
+	{
+	  indent (os);
+	  dim_vector dv = dims ();
+	  os << dv.str () << " struct array containing the fields:";
+	  newline (os);
+	  newline (os);
+
+	  increment_indent_level ();
+	}
+
+      string_vector key_list = map.keys ();
+
+      for (octave_idx_type i = 0; i < key_list.length (); i++)
+	{
+	  std::string key = key_list[i];
+
+	  Cell val = map.contents (key);
+
+	  octave_value tmp = (n == 1) ? val(0) : octave_value (val, true);
+
+	  if (n != 1 || print_keys_only)
+	    {
+	      indent (os);
+	      os << key;
+	      if (n == 1)
+		{
+		  dim_vector dv = tmp.dims ();
+		  os << ": " << dv.str () << " " << tmp.type_name ();
+		}
+	      newline (os);
+	    }
+	  else
+	    tmp.print_with_name (os, key);
+	}
+
+      if (n != 1 || print_keys_only)
+	decrement_indent_level ();
+
+      decrement_indent_level ();
+
+      indent (os);
+      os << "}";
+      newline (os);
+    }
+  else
+    {
+      indent (os);
+      os << "<structure>";
+      newline (os);
+    }
+
+  unwind_protect::run_frame ("octave_struct_print");
+}
+
+bool
+octave_struct::print_name_tag (std::ostream& os, const std::string& name) const
+{
+  bool retval = false;
+
+  indent (os);
+
+  if (Vstruct_levels_to_print < 0)
+    os << name << " = ";
+  else
+    {
+      os << name << " =";
+      newline (os);
+      retval = true;
+    }
+
+  return retval;
+}
+
+static bool 
+scalar (const dim_vector& dims) 
+{
+  return dims.length () == 2 && dims (0) == 1 && dims (1) == 1;
+}
+
+/*
+%!shared x
+%! x(1).a=1; x(2).a=2; x(1).b=3; x(2).b=3;
+%!assert(struct('a',1,'b',3),x(1))
+%!assert(isempty(x([])))
+%!assert(isempty(struct('a',{},'b',{})))
+%!assert(struct('a',{1,2},'b',{3,3}),x)
+%!assert(struct('a',{1,2},'b',3),x)
+%!assert(struct('a',{1,2},'b',{3}),x)
+%!assert(struct('b',3,'a',{1,2}),x)
+%!assert(struct('b',{3},'a',{1,2}),x) 
+%!test x=struct([]);
+%!assert(size(x),[0,0]);
+%!assert(isstruct(x));
+%!assert(isempty(fieldnames(x)));
+%!fail("struct('a',{1,2},'b',{1,2,3})","dimensions of parameter 2 do not match those of parameter 4")
+%!fail("struct(1,2,3,4)","struct expects alternating \"field\", VALUE pairs");
+%!fail("struct('1',2,'3')","struct expects alternating \"field\", VALUE pairs");
+*/
+
+DEFUN (struct, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} struct (\"field\", @var{value}, \"field\", @var{value}, @dots{})\n\
+\n\
+Create a structure and initialize its value.\n\
+\n\
+If the values are cell arrays, create a structure array and initialize\n\
+its values.  The dimensions of each cell array of values must match.\n\
+Singleton cells and non-cell values are repeated so that they fill\n\
+the entire array.  If the cells are empty, create an empty structure\n\
+array with the specified field names.\n\
+\n\
+If the argument is an object, return the underlying struct.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  // struct ([]) returns an empty struct.
+
+  // struct (empty_matrix) returns an empty struct with the same
+  // dimensions as the empty matrix.
+
+  // Note that struct () creates a 1x1 struct with no fields for
+  // compatibility with Matlab.
+
+  if (nargin == 1 && args(0).is_object ())
+    {
+      Octave_map m = args(0).map_value ();
+      retval = octave_value (new octave_struct (m));
+
+      return retval;
+    }
+
+  if ((nargin == 1 || nargin == 2)
+      && args(0).is_empty () && args(0).is_real_matrix ())
+    {
+      Cell fields;
+
+      if (nargin == 2)
+	{
+	  if (args(1).is_cellstr ())
+	    retval = Octave_map (args(0).dims (), args(1).cell_value ());
+	  else
+	    error ("struct: expecting cell array of field names as second argument");
+	}
+      else
+	retval = Octave_map (args(0).dims ());
+
+      return retval;
+    }
+    
+  // Check for "field", VALUE pairs.
+
+  for (int i = 0; i < nargin; i += 2) 
+    {
+      if (! args(i).is_string () || i + 1 >= nargin)
+	{
+	  error ("struct expects alternating \"field\", VALUE pairs");
+	  return retval;
+	}
+    }
+
+  // Check that the dimensions of the values correspond.
+
+  dim_vector dims (1, 1);
+
+  int first_dimensioned_value = 0;
+
+  for (int i = 1; i < nargin; i += 2) 
+    {
+      if (args(i).is_cell ()) 
+	{
+	  dim_vector argdims (args(i).dims ());
+
+	  if (! scalar (argdims))
+	    {
+	      if (! first_dimensioned_value)
+		{
+		  dims = argdims;
+		  first_dimensioned_value = i + 1;
+		}
+	      else if (dims != argdims)
+		{
+		  error ("struct: dimensions of parameter %d do not match those of parameter %d",
+			 first_dimensioned_value, i+1);
+		  return retval;
+		}
+	    }
+	}
+    }
+
+  // Create the return value.
+
+  Octave_map map (dims);
+
+  for (int i = 0; i < nargin; i+= 2) 
+    {
+      // Get key.
+
+      std::string key (args(i).string_value ());
+
+      if (error_state)
+	return retval;
+
+      if (! valid_identifier (key))
+	{
+	  error ("struct: invalid structure field name `%s'", key.c_str ());
+	  return retval;
+	}
+
+      // Value may be v, { v }, or { v1, v2, ... }
+      // In the first two cases, we need to create a cell array of
+      // the appropriate dimensions filled with v.  In the last case, 
+      // the cell array has already been determined to be of the
+      // correct dimensions.
+
+      if (args(i+1).is_cell ()) 
+	{
+	  const Cell c (args(i+1).cell_value ());
+
+	  if (error_state)
+	    return retval;
+
+	  if (scalar (c.dims ())) 
+	    map.assign (key, Cell (dims, c(0)));
+	  else 
+	    map.assign (key, c);
+	}
+      else 
+	map.assign (key, Cell (dims, args(i+1)));
+
+      if (error_state)
+	return retval;
+    }
+
+  return octave_value (map);
+}
+
+DEFUN (isstruct, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isstruct (@var{expr})\n\
+Return 1 if the value of the expression @var{expr} is a structure.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_map ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fieldnames, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fieldnames (@var{struct})\n\
+Return a cell array of strings naming the elements of the structure\n\
+ at var{struct}.  It is an error to call @code{fieldnames} with an\n\
+argument that is not a structure.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+
+      if (arg.is_map () || arg.is_object ())
+	{
+	  Octave_map m = arg.map_value ();
+
+	  string_vector keys = m.keys ();
+
+	  if (keys.length () == 0)
+	    retval = Cell (0, 1);
+	  else
+	    retval = Cell (m.keys ());
+	}
+      else
+	gripe_wrong_type_arg ("fieldnames", args(0));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (isfield, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isfield (@var{expr}, @var{name})\n\
+Return true if the expression @var{expr} is a structure and it includes an\n\
+element named @var{name}.  The first argument must be a structure and\n\
+the second must be a string.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      retval = false;
+
+      // FIXME -- should this work for all types that can do
+      // structure reference operations?
+
+      if (args(0).is_map () && args(1).is_string ())
+	{
+	  std::string key = args(1).string_value ();
+
+	  Octave_map m = args(0).map_value ();
+
+	  retval = m.contains (key) != 0;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Check that the dimensions of the input arguments are correct.
+
+static bool
+cell2struct_check_args (const dim_vector& c_dv, const dim_vector& f_dv,
+			bool is_cell, int dim)
+{
+  bool retval = true;
+
+  if (dim >= 0 && dim < c_dv.length ())
+    {
+      if (is_cell)
+	{
+	  if (f_dv.numel () != c_dv(dim))
+	    {
+	      error ("cell2struct: numel (FIELD) != size (CELL, DIM)");
+
+	      retval = false;
+	    }
+	}
+      else
+	{
+	  if (f_dv.length () > 2)
+	    {
+	      error ("cell2struct: field array must be a 2-d matrix");
+
+	      retval = false;
+	    }
+	  else if (f_dv(0) != c_dv(dim))
+	    {
+	      error ("cell2struct: size (FIELD, 1) != length (C, DIM)");
+
+	      retval = false;
+	    }
+	}
+    }
+  else
+    {
+      error ("cell2struct: DIM out of range");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+static void
+cell2struct_construct_idx (Array<octave_idx_type>& ra_idx1,
+			   const Array<octave_idx_type>& ra_idx2,
+			   octave_idx_type dim, octave_idx_type fill_value)
+{
+  octave_idx_type iidx = 0;
+
+  for (octave_idx_type idx = 0; idx < ra_idx1.length (); idx++)
+    {
+      if (idx == dim)
+	ra_idx1.elem (idx) = fill_value;
+      else
+	ra_idx1.elem (idx) = ra_idx2(iidx++);
+    }
+}
+
+DEFUN (cell2struct, args, ,
+       "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} cell2struct (@var{cell}, @var{fields}, @var{dim})\n\
+Convert @var{cell} to a structure.  The number of fields in @var{fields}\n\
+must match the number of elements in @var{cell} along dimension @var{dim},\n\
+that is @code{numel (@var{fields}) == size (@var{cell}, @var{dim})}.\n\
+\n\
+ at example\n\
+ at group\n\
+A = cell2struct (@{'Peter', 'Hannah', 'Robert';\n\
+                   185, 170, 168@},\n\
+                 @{'Name','Height'@}, 1);\n\
+A(1)\n\
+ at result{} ans =\n\
+      @{\n\
+        Height = 185\n\
+        Name   = Peter\n\
+      @}\n\
+\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 3)
+    {
+      Cell c = args(0).cell_value ();
+
+      if (! error_state)
+	{
+	  octave_value field = args(1);
+
+	  // Field is either cell or character matrix.
+
+	  // FIXME -- this could be simplified if we had
+	  // cellstr and iscellstr functions available.
+
+	  bool field_is_cell = field.is_cell ();
+
+	  Cell field_cell;
+	  charMatrix field_char;
+
+	  if (field_is_cell)
+	    field_cell = field.cell_value ();
+	  else
+	    field_char = field.char_matrix_value ();
+
+	  if (! error_state)
+	    {
+	      // Retrieve the dimension value.
+
+	      // FIXME --  int_value () should print out the
+	      // conversions it does to be Matlab compatible.
+
+	      octave_idx_type dim = args(2).int_value () - 1;
+
+	      if (! error_state)
+		{
+		  dim_vector c_dv = c.dims ();
+		  dim_vector field_dv = field.dims ();
+
+		  if (cell2struct_check_args (c_dv, field_dv, field_is_cell,
+					      dim))
+		    {
+		      octave_idx_type c_dv_length = c_dv.length ();
+
+		      // Dimension vector for the Cell arrays to be
+		      // put into the structure.
+
+		      dim_vector value_dv;
+
+		      // Initialize c_value_dv.
+
+		      if (c_dv_length == 2)
+			value_dv = dim_vector (1, 1);
+		      else
+			value_dv.resize (c_dv_length - 1);
+
+		      octave_idx_type idx_tmp = 0;
+
+		      for (octave_idx_type i = 0; i < c_dv_length; i++)
+			{
+			  if (i != dim)
+			    value_dv.elem (idx_tmp++) = c_dv.elem (i);
+			}
+
+		      // All initializing is done, we can start moving
+		      // values.
+
+		      Octave_map map;
+
+		      // If field is a cell array then we use all
+		      // elements in array, on the other hand when
+		      // field is a character array the number of
+		      // elements is equals the number of rows.
+
+		      octave_idx_type field_numel
+			= field_is_cell ? field_dv.numel (): field_dv(0);
+
+		      // For matlab compatibility.
+
+		      if (field_numel == 0)
+			map.reshape (dim_vector (0, 1));
+
+		      for (octave_idx_type i = 0; i < field_numel; i++)
+			{
+			  // Construct cell array which goes into the
+			  // structure together with the appropriate
+			  // field name.
+
+			  Cell c_value (value_dv);
+
+			  Array<octave_idx_type> value_idx (value_dv.length (), 0);
+			  Array<octave_idx_type> c_idx (c_dv_length, 0);
+
+			  for (octave_idx_type j = 0; j < value_dv.numel (); j++)
+			    {
+			      // Need to do this to construct the
+			      // appropriate idx for getting elements
+			      // from the original cell array.
+
+			      cell2struct_construct_idx (c_idx, value_idx,
+							 dim, i);
+
+			      c_value.elem (value_idx) = c.elem (c_idx);
+
+			      increment_index (value_idx, value_dv);
+			    }
+
+			  std::string field_str;
+
+			  if (field_is_cell)
+			    {
+			      // Matlab retrieves the field values
+			      // column by column.
+
+			      octave_value field_tmp = field_cell.elem (i);
+
+			      field_str = field_tmp.string_value ();
+
+			      if (error_state)
+				{
+				  error ("cell2struct: fields have to be of type string");
+				  break;
+				}
+			    }
+			  else
+			    {
+			      field_str = field_char.row_as_string (i);
+
+			      if (error_state)
+				return retval;
+			    }
+
+			  if (! valid_identifier (field_str))
+			    {
+			      error ("cell2struct: invalid field name `%s'",
+				     field_str.c_str ());
+			      break;
+			    }
+
+			  map.reshape (value_dv);
+
+			  map.assign (field_str, c_value);
+			}
+
+		      if (! error_state)
+			retval = map;
+		    }
+		}
+	      else
+		error ("cell2struct: expecting third argument to be an integer");
+	    }
+	  else
+	    error ("cell2struct: expecting second argument to be a cell or character array");
+	}
+      else
+	error ("cell2struct: expecting first argument to be a cell array");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// So we can call Fcellstr directly.
+extern octave_value_list Fcellstr (const octave_value_list& args, int);
+
+DEFUN (rmfield, args, ,
+       "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rmfield (@var{s}, @var{f})\n\
+Remove field @var{f} from the structure @var{s}.  If @var{f} is a\n\
+cell array of character strings or a character array, remove the\n\
+named fields.\n\
+ at seealso{cellstr, iscellstr, setfield}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      Octave_map m = args(0).map_value ();
+
+      octave_value_list fval = Fcellstr (args(1), 1);
+
+      if (! error_state)
+	{
+	  Cell fcell = fval(0).cell_value ();
+
+	  for (int i = 0; i < fcell.numel (); i++)
+	    {
+	      std::string key = fcell(i).string_value ();
+
+	      if (m.contains (key))
+		m.del (key);
+	      else
+		{
+		  error ("rmfield: structure does not contain field %s",
+			 key.c_str ());
+
+		  break;
+		}
+	    }
+
+	  if (! error_state)
+	    retval = m;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+bool
+octave_struct::save_ascii (std::ostream& os)
+{
+  Octave_map m = map_value ();
+
+  octave_idx_type nf = m.nfields ();
+
+  os << "# length: " << nf << "\n";
+
+  // Iterating over the list of keys will preserve the order of the
+  // fields.
+  string_vector keys = m.keys ();
+
+  for (octave_idx_type i = 0; i < nf; i++)
+    {
+      std::string key = keys(i);
+
+      octave_value val = map.contents (key);
+
+      bool b = save_ascii_data (os, val, key, false, 0);
+      
+      if (! b)
+	return os;
+    }
+
+  return true;
+}
+
+bool 
+octave_struct::load_ascii (std::istream& is)
+{
+  octave_idx_type len = 0;
+  bool success = true;
+
+  if (extract_keyword (is, "length", len) && len >= 0)
+    {
+      if (len > 0)
+	{
+	  Octave_map m (map);
+
+	  for (octave_idx_type j = 0; j < len; j++)
+	    {
+	      octave_value t2;
+	      bool dummy;
+
+	      // recurse to read cell elements
+	      std::string nm
+		= read_ascii_data (is, std::string (), dummy, t2, j);
+
+	      if (!is)
+		break;
+
+	      Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+
+	      if (error_state)
+		{
+		  error ("load: internal error loading struct elements");
+		  return false;
+		}
+
+	      m.assign (nm, tcell);
+	    }
+
+	  if (is) 
+	    map = m;
+	  else
+	    {
+	      error ("load: failed to load structure");
+	      success = false;
+	    }
+	}
+      else if (len == 0 )
+	map = Octave_map (dim_vector (1, 1));
+      else
+	panic_impossible ();
+    }
+  else {
+    error ("load: failed to extract number of elements in structure");
+    success = false;
+  }
+
+  return success;
+}
+
+bool 
+octave_struct::save_binary (std::ostream& os, bool& save_as_floats)
+{
+  Octave_map m = map_value ();
+
+  octave_idx_type nf = m.nfields ();
+
+  int32_t len = nf;
+  os.write (reinterpret_cast<char *> (&len), 4);
+
+  // Iterating over the list of keys will preserve the order of the
+  // fields.
+  string_vector keys = m.keys ();
+
+  for (octave_idx_type i = 0; i < nf; i++)
+    {
+      std::string key = keys(i);
+
+      octave_value val = map.contents (key);
+
+      bool b = save_binary_data (os, val, key, "", 0, save_as_floats);
+      
+      if (! b)
+	return os;
+    }
+
+  return true;
+}
+
+bool 
+octave_struct::load_binary (std::istream& is, bool swap,
+			    oct_mach_info::float_format fmt)
+{
+  bool success = true;
+  int32_t len;
+  if (! is.read (reinterpret_cast<char *> (&len), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&len);
+
+  if (len > 0)
+    {
+      Octave_map m (map);
+
+      for (octave_idx_type j = 0; j < len; j++)
+	{
+	  octave_value t2;
+	  bool dummy;
+	  std::string doc;
+
+	  // recurse to read cell elements
+	  std::string nm = read_binary_data (is, swap, fmt, std::string (), 
+					     dummy, t2, doc);
+
+	  if (!is)
+	    break;
+
+	  Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+ 
+	  if (error_state)
+	    {
+	      error ("load: internal error loading struct elements");
+	      return false;
+	    }
+
+	  m.assign (nm, tcell);
+	}
+
+      if (is) 
+	map = m;
+      else
+	{
+	  error ("load: failed to load structure");
+	  success = false;
+	}
+    }
+  else if (len == 0 )
+    map = Octave_map (dim_vector (1, 1));
+  else
+    panic_impossible ();
+
+  return success;
+}
+
+#if defined (HAVE_HDF5)
+
+bool
+octave_struct::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+{
+  hid_t data_hid = -1;
+
+  data_hid = H5Gcreate (loc_id, name, 0);
+  if (data_hid < 0) return false;
+
+  // recursively add each element of the structure to this group
+  Octave_map m = map_value ();
+
+  octave_idx_type nf = m.nfields ();
+
+  // Iterating over the list of keys will preserve the order of the
+  // fields.
+  string_vector keys = m.keys ();
+
+  for (octave_idx_type i = 0; i < nf; i++)
+    {
+      std::string key = keys(i);
+
+      octave_value val = map.contents (key);
+
+      bool retval2 = add_hdf5_data (data_hid, val, key, "", false, 
+				    save_as_floats);
+
+      if (! retval2)
+	break;
+    }
+
+  H5Gclose (data_hid);
+
+  return true;
+}
+
+bool 
+octave_struct::load_hdf5 (hid_t loc_id, const char *name,
+			  bool have_h5giterate_bug)
+{
+  bool retval = false;
+
+  hdf5_callback_data dsub;
+
+  herr_t retval2 = 0;
+  Octave_map m (dim_vector (1, 1));
+  int current_item = 0;
+#ifdef HAVE_H5GGET_NUM_OBJS
+  hsize_t num_obj = 0;
+  hid_t group_id = H5Gopen (loc_id, name); 
+  H5Gget_num_objs (group_id, &num_obj);
+  H5Gclose (group_id);
+
+  // FIXME -- fields appear to be sorted alphabetically on loading.
+  // Why is that happening?
+
+  while (current_item < static_cast<int> (num_obj)
+	 && (retval2 = H5Giterate (loc_id, name, &current_item,
+				   hdf5_read_next_data, &dsub)) > 0)
+#else
+  while ((retval2 = H5Giterate (loc_id, name, &current_item,
+				hdf5_read_next_data, &dsub)) > 0)
+#endif
+    {
+      octave_value t2 = dsub.tc;
+
+      Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+ 
+      if (error_state)
+	{
+	  error ("load: internal error loading struct elements");
+	  return false;
+	}
+
+      m.assign (dsub.name, tcell);
+
+      if (have_h5giterate_bug)
+	current_item++;  // H5Giterate returned the last index processed
+    }
+
+  if (retval2 >= 0)
+    {
+      map = m;
+      retval = true;
+    }
+  
+  return retval;
+}
+
+#endif
+
+mxArray *
+octave_struct::as_mxArray (void) const
+{
+  int nf = nfields ();
+  string_vector kv = map_keys ();
+
+  OCTAVE_LOCAL_BUFFER (const char *, f, nf);
+
+  for (int i = 0; i < nf; i++)
+    f[i] = kv[i].c_str ();
+
+  mxArray *retval = new mxArray (dims (), nf, f);
+
+  mxArray **elts = static_cast<mxArray **> (retval->get_data ());
+
+  mwSize nel = numel ();
+
+  mwSize ntot = nf * nel;
+
+  for (int i = 0; i < nf; i++)
+    {
+      Cell c = map.contents (kv[i]);
+
+      const octave_value *p = c.data ();
+
+      mwIndex k = 0;
+      for (mwIndex j = i; j < ntot; j += nf)
+	elts[j] = new mxArray (p[k++]);
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-struct.h b/src/ov-struct.h
new file mode 100644
index 0000000..cc8c430
--- /dev/null
+++ b/src/ov-struct.h
@@ -0,0 +1,168 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_struct_h)
+#define octave_struct_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+
+#include "mx-base.h"
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-alloc.h"
+#include "oct-map.h"
+#include "ov-base.h"
+#include "ov-typeinfo.h"
+
+class octave_value_list;
+
+class tree_walker;
+
+// Data structures.
+
+class
+octave_struct : public octave_base_value
+{
+public:
+
+  octave_struct (void)
+    : octave_base_value () { }
+
+  octave_struct (const Octave_map& m)
+    : octave_base_value (), map (m) { }
+
+  octave_struct (const octave_struct& s)
+    : octave_base_value (), map (s.map) { }
+
+  ~octave_struct (void) { }
+
+  octave_base_value *clone (void) const { return new octave_struct (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_struct (); }
+
+  Cell dotref (const octave_value_list& idx, bool auto_add = false);
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string&,
+			     const std::list<octave_value_list>&, int);
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx,
+                        bool auto_add);
+
+  static octave_value numeric_conv (const octave_value& val,
+				    const std::string& type);
+
+  octave_value subsasgn (const std::string& type,
+			 const std::list<octave_value_list>& idx,
+			 const octave_value& rhs);
+
+  octave_value squeeze (void) const { return map.squeeze (); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return map.permute (vec, inv); }
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false);
+
+  dim_vector dims (void) const { return map.dims (); }
+
+  size_t byte_size (void) const;
+
+  // This is the number of elements in each field.  The total number
+  // of elements is numel () * nfields ().
+  octave_idx_type numel (void) const
+  {
+    dim_vector dv = dims ();
+    return dv.numel ();
+  }
+
+  octave_idx_type nfields (void) const { return map.nfields (); }
+
+  octave_value reshape (const dim_vector& new_dims) const
+    { return map.reshape (new_dims); }
+
+  octave_value resize (const dim_vector& dv, bool = false) const
+    { Octave_map tmap = map; tmap.resize (dv); return tmap; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_map (void) const { return true; }
+
+  Octave_map map_value (void) const { return map; }
+
+  string_vector map_keys (void) const { return map.keys (); }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const;
+
+  bool save_ascii (std::ostream& os);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
+  mxArray *as_mxArray (void) const;
+
+protected:
+
+  // The associative array used to manage the structure data.
+  Octave_map map;
+
+private:
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-type-conv.h b/src/ov-type-conv.h
new file mode 100644
index 0000000..4485cfd
--- /dev/null
+++ b/src/ov-type-conv.h
@@ -0,0 +1,115 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_ov_type_conv_h)
+#define octave_ov_type_conv_h 1
+
+static 
+octave_value
+octave_type_conv_body (const octave_value &arg, const std::string& name, int t_result)
+{
+  int t_arg = arg.type_id ();
+  octave_value retval;
+
+  if (t_arg == t_result || arg.class_name () == name)
+    {
+      retval = arg;
+    }
+  else
+    {
+      octave_base_value::type_conv_fcn cf1
+        = octave_value_typeinfo::lookup_type_conv_op (t_arg, t_result);
+       
+      if (cf1)
+        {
+          octave_base_value *tmp (cf1 (*(arg.internal_rep ())));
+
+          if (tmp)
+            {
+              retval = octave_value (tmp);
+
+              retval.maybe_mutate ();
+            }
+        }
+      else
+        {
+          octave_base_value::type_conv_fcn cf2
+            = arg.numeric_conversion_function ();
+
+          if (cf2)
+            {
+              octave_base_value *tmp (cf2 (*(arg.internal_rep ())));
+
+              if (tmp)
+                {
+                  octave_value xarg (tmp);
+
+                  retval = octave_type_conv_body (xarg, name, t_result);
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+                         
+
+#define OCTAVE_TYPE_CONV_BODY3(NAME, MATRIX_RESULT_T, SCALAR_RESULT_T) \
+ \
+  octave_value retval; \
+ \
+  int nargin = args.length (); \
+ \
+  if (nargin == 1) \
+    { \
+      const octave_value arg = args(0); \
+ \
+      int t_result = MATRIX_RESULT_T::static_type_id (); \
+ \
+      retval = octave_type_conv_body (arg, #NAME, t_result); \
+      if (retval.is_undefined ()) \
+        { \
+          std::string arg_tname = arg.type_name (); \
+ \
+          std::string result_tname = arg.numel () == 1 \
+            ? SCALAR_RESULT_T::static_type_name () \
+            : MATRIX_RESULT_T::static_type_name (); \
+ \
+          gripe_invalid_conversion (arg_tname, result_tname); \
+        } \
+    } \
+  else \
+    print_usage (); \
+ \
+  return retval
+
+#define OCTAVE_TYPE_CONV_BODY(NAME) \
+  OCTAVE_TYPE_CONV_BODY3 (NAME, octave_ ## NAME ## _matrix, \
+			  octave_ ## NAME ## _scalar)
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-typeinfo.cc b/src/ov-typeinfo.cc
new file mode 100644
index 0000000..17005c9
--- /dev/null
+++ b/src/ov-typeinfo.cc
@@ -0,0 +1,620 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov-typeinfo.h"
+
+#include "defun.h"
+#include "error.h"
+
+const int
+octave_value_typeinfo::init_tab_sz (16);
+
+octave_value_typeinfo *
+octave_value_typeinfo::instance (0);
+
+#include <Array.h>
+#include <Array2.h>
+#include <Array3.h>
+
+bool
+octave_value_typeinfo::instance_ok (void)
+{
+  bool retval = true;
+  if (! instance)
+    instance = new octave_value_typeinfo ();
+
+  if (! instance)
+    {
+      ::error ("unable to create value type info object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+int
+octave_value_typeinfo::register_type (const std::string& t_name,
+				      const std::string& c_name,
+				      const octave_value& val)
+{
+  return (instance_ok ())
+    ? instance->do_register_type (t_name, c_name, val) : -1;
+}
+
+bool
+octave_value_typeinfo::register_unary_class_op (octave_value::unary_op op,
+					        octave_value_typeinfo::unary_class_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_unary_class_op (op, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_unary_op (octave_value::unary_op op,
+					   int t, octave_value_typeinfo::unary_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_unary_op (op, t, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_non_const_unary_op (octave_value::unary_op op,
+						    int t,
+						    octave_value_typeinfo::non_const_unary_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_non_const_unary_op (op, t, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_binary_class_op (octave_value::binary_op op,
+						 octave_value_typeinfo::binary_class_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_binary_class_op (op, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_binary_op (octave_value::binary_op op,
+					   int t1, int t2,
+					   octave_value_typeinfo::binary_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_binary_op (op, t1, t2, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_binary_class_op (octave_value::compound_binary_op op,
+						 octave_value_typeinfo::binary_class_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_binary_class_op (op, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_binary_op (octave_value::compound_binary_op op,
+					   int t1, int t2,
+					   octave_value_typeinfo::binary_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_binary_op (op, t1, t2, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_cat_op (int t1, int t2, octave_value_typeinfo::cat_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_cat_op (t1, t2, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_assign_op (octave_value::assign_op op,
+					   int t_lhs, int t_rhs,
+					   octave_value_typeinfo::assign_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_assign_op (op, t_lhs, t_rhs, f) : -1;
+}
+
+bool
+octave_value_typeinfo::register_assignany_op (octave_value::assign_op op,
+					      int t_lhs, octave_value_typeinfo::assignany_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_assignany_op (op, t_lhs, f) : -1;
+}
+
+bool
+octave_value_typeinfo::register_pref_assign_conv (int t_lhs, int t_rhs,
+						  int t_result) 
+{
+  return (instance_ok ())
+    ? instance->do_register_pref_assign_conv (t_lhs, t_rhs, t_result) : false;
+}
+
+bool
+octave_value_typeinfo::register_type_conv_op (int t, int t_result,
+					      octave_base_value::type_conv_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_type_conv_op (t, t_result, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_widening_op (int t, int t_result,
+					     octave_base_value::type_conv_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_widening_op (t, t_result, f) : false;
+}
+
+// FIXME -- we should also store all class names and provide a
+// way to list them (calling class with nargin == 0?).
+
+int
+octave_value_typeinfo::do_register_type (const std::string& t_name,
+					 const std::string& /* c_name */,
+					 const octave_value& val)
+{
+  int i = 0;
+
+  for (i = 0; i < num_types; i++)
+    if (t_name == types (i))
+      return i;
+
+  int len = types.length ();
+
+  if (i == len)
+    {
+      len *= 2;
+
+      types.resize (len, std::string ());
+
+      vals.resize (len, octave_value ());
+
+      unary_ops.resize (static_cast<int> (octave_value::num_unary_ops), len, 0);
+
+      non_const_unary_ops.resize
+	(static_cast<int> (octave_value::num_unary_ops), len, 0);
+
+      binary_ops.resize (static_cast<int> (octave_value::num_binary_ops),
+			 len, len, 0);
+
+      compound_binary_ops.resize (static_cast<int> (octave_value::num_compound_binary_ops),
+                                  len, len, 0);
+
+      cat_ops.resize (len, len, 0);
+
+      assign_ops.resize (static_cast<int> (octave_value::num_assign_ops), len, len, 0);
+
+      assignany_ops.resize (static_cast<int> (octave_value::num_assign_ops), len, 0);
+
+      pref_assign_conv.resize (len, len, -1);
+
+      type_conv_ops.resize (len, len, 0);
+
+      widening_ops.resize (len, len, 0);
+    }
+
+  types (i) = t_name;
+
+  vals (i) = val;
+
+  num_types++;
+
+  return i;
+}
+
+bool
+octave_value_typeinfo::do_register_unary_class_op (octave_value::unary_op op,
+					           octave_value_typeinfo::unary_class_op_fcn f)
+{
+  if (lookup_unary_class_op (op))
+    {
+      std::string op_name = octave_value::unary_op_as_string (op);
+
+      warning ("duplicate unary operator `%s' for class dispatch",
+	       op_name.c_str ());
+    }
+
+  unary_class_ops.checkelem (static_cast<int> (op)) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_unary_op (octave_value::unary_op op,
+					     int t, octave_value_typeinfo::unary_op_fcn f)
+{
+  if (lookup_unary_op (op, t))
+    {
+      std::string op_name = octave_value::unary_op_as_string (op);
+      std::string type_name = types(t);
+
+      warning ("duplicate unary operator `%s' for type `%s'",
+	       op_name.c_str (), type_name.c_str ());
+    }
+
+  unary_ops.checkelem (static_cast<int> (op), t) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_non_const_unary_op
+  (octave_value::unary_op op, int t, octave_value_typeinfo::non_const_unary_op_fcn f)
+{
+  if (lookup_non_const_unary_op (op, t))
+    {
+      std::string op_name = octave_value::unary_op_as_string (op);
+      std::string type_name = types(t);
+
+      warning ("duplicate unary operator `%s' for type `%s'",
+	       op_name.c_str (), type_name.c_str ());
+    }
+
+  non_const_unary_ops.checkelem (static_cast<int> (op), t) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_binary_class_op (octave_value::binary_op op,
+						    octave_value_typeinfo::binary_class_op_fcn f)
+{
+  if (lookup_binary_class_op (op))
+    {
+      std::string op_name = octave_value::binary_op_as_string (op);
+
+      warning ("duplicate binary operator `%s' for class dispatch",
+	       op_name.c_str ());
+    }
+
+  binary_class_ops.checkelem (static_cast<int> (op)) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_binary_op (octave_value::binary_op op,
+					      int t1, int t2,
+					      octave_value_typeinfo::binary_op_fcn f)
+{
+  if (lookup_binary_op (op, t1, t2))
+    {
+      std::string op_name = octave_value::binary_op_as_string (op);
+      std::string t1_name = types(t1);
+      std::string t2_name = types(t2);
+
+      warning ("duplicate binary operator `%s' for types `%s' and `%s'",
+	       op_name.c_str (), t1_name.c_str (), t1_name.c_str ());
+    }
+
+  binary_ops.checkelem (static_cast<int> (op), t1, t2) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_binary_class_op (octave_value::compound_binary_op op,
+						    octave_value_typeinfo::binary_class_op_fcn f)
+{
+  if (lookup_binary_class_op (op))
+    {
+      std::string op_name = octave_value::binary_op_fcn_name (op);
+
+      warning ("duplicate compound binary operator `%s' for class dispatch",
+	       op_name.c_str ());
+    }
+
+  compound_binary_class_ops.checkelem (static_cast<int> (op)) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_binary_op (octave_value::compound_binary_op op,
+					      int t1, int t2,
+					      octave_value_typeinfo::binary_op_fcn f)
+{
+  if (lookup_binary_op (op, t1, t2))
+    {
+      std::string op_name = octave_value::binary_op_fcn_name (op);
+      std::string t1_name = types(t1);
+      std::string t2_name = types(t2);
+
+      warning ("duplicate compound binary operator `%s' for types `%s' and `%s'",
+	       op_name.c_str (), t1_name.c_str (), t1_name.c_str ());
+    }
+
+  compound_binary_ops.checkelem (static_cast<int> (op), t1, t2) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_cat_op (int t1, int t2, octave_value_typeinfo::cat_op_fcn f)
+{
+  if (lookup_cat_op (t1, t2))
+    {
+      std::string t1_name = types(t1);
+      std::string t2_name = types(t2);
+
+      warning ("duplicate concatenation operator for types `%s' and `%s'",
+	       t1_name.c_str (), t1_name.c_str ());
+    }
+
+  cat_ops.checkelem (t1, t2) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_assign_op (octave_value::assign_op op,
+					      int t_lhs, int t_rhs,
+					      octave_value_typeinfo::assign_op_fcn f)
+{
+  if (lookup_assign_op (op, t_lhs, t_rhs))
+    {
+      std::string op_name = octave_value::assign_op_as_string (op);
+      std::string t_lhs_name = types(t_lhs);
+      std::string t_rhs_name = types(t_rhs);
+
+      warning ("duplicate assignment operator `%s' for types `%s' and `%s'",
+	       op_name.c_str (), t_lhs_name.c_str (), t_rhs_name.c_str ());
+    }
+
+  assign_ops.checkelem (static_cast<int> (op), t_lhs, t_rhs) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_assignany_op (octave_value::assign_op op,
+						 int t_lhs, octave_value_typeinfo::assignany_op_fcn f)
+{
+  if (lookup_assignany_op (op, t_lhs))
+    {
+      std::string op_name = octave_value::assign_op_as_string (op);
+      std::string t_lhs_name = types(t_lhs);
+
+      warning ("duplicate assignment operator `%s' for types `%s'",
+	       op_name.c_str (), t_lhs_name.c_str ());
+    }
+
+  assignany_ops.checkelem (static_cast<int> (op), t_lhs) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_pref_assign_conv (int t_lhs, int t_rhs,
+						     int t_result) 
+{
+  if (lookup_pref_assign_conv (t_lhs, t_rhs) >= 0)
+    {
+      std::string t_lhs_name = types(t_lhs);
+      std::string t_rhs_name = types(t_rhs);
+
+      warning ("overriding assignment conversion for types `%s' and `%s'",
+	       t_lhs_name.c_str (), t_rhs_name.c_str ());
+    }
+
+  pref_assign_conv.checkelem (t_lhs, t_rhs) = t_result;
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_type_conv_op
+  (int t, int t_result, octave_base_value::type_conv_fcn f)
+{
+  if (lookup_type_conv_op (t, t_result))
+    {
+      std::string t_name = types(t);
+      std::string t_result_name = types(t_result);
+
+      warning ("overriding type conversion op for `%s' to `%s'",
+	       t_name.c_str (), t_result_name.c_str ());
+    }
+
+  type_conv_ops.checkelem (t, t_result) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_widening_op
+  (int t, int t_result, octave_base_value::type_conv_fcn f)
+{
+  if (lookup_widening_op (t, t_result))
+    {
+      std::string t_name = types(t);
+      std::string t_result_name = types(t_result);
+
+      warning ("overriding widening op for `%s' to `%s'",
+	       t_name.c_str (), t_result_name.c_str ());
+    }
+
+  widening_ops.checkelem (t, t_result) = reinterpret_cast<void *> (f);
+
+  return false;
+}
+
+octave_value
+octave_value_typeinfo::do_lookup_type (const std::string& nm)
+{
+  octave_value retval;
+
+  for (int i = 0; i < num_types; i++)
+    {
+      if (nm == types(i))
+	{
+	  retval = vals(i);
+	  retval.make_unique ();
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+octave_value_typeinfo::unary_class_op_fcn
+octave_value_typeinfo::do_lookup_unary_class_op (octave_value::unary_op op)
+{
+  void *f = unary_class_ops.checkelem (static_cast<int> (op));
+  return reinterpret_cast<octave_value_typeinfo::unary_class_op_fcn> (f);
+}
+
+octave_value_typeinfo::unary_op_fcn
+octave_value_typeinfo::do_lookup_unary_op (octave_value::unary_op op, int t)
+{
+  void *f = unary_ops.checkelem (static_cast<int> (op), t);
+  return reinterpret_cast<octave_value_typeinfo::unary_op_fcn> (f);
+}
+
+octave_value_typeinfo::non_const_unary_op_fcn
+octave_value_typeinfo::do_lookup_non_const_unary_op
+  (octave_value::unary_op op, int t)
+{
+  void *f = non_const_unary_ops.checkelem (static_cast<int> (op), t);
+  return reinterpret_cast<octave_value_typeinfo::non_const_unary_op_fcn> (f);
+}
+
+octave_value_typeinfo::binary_class_op_fcn
+octave_value_typeinfo::do_lookup_binary_class_op (octave_value::binary_op op)
+{
+  void *f = binary_class_ops.checkelem (static_cast<int> (op));
+  return reinterpret_cast<octave_value_typeinfo::binary_class_op_fcn> (f);
+}
+
+octave_value_typeinfo::binary_op_fcn
+octave_value_typeinfo::do_lookup_binary_op (octave_value::binary_op op,
+					    int t1, int t2)
+{
+  void *f = binary_ops.checkelem (static_cast<int> (op), t1, t2);
+  return reinterpret_cast<octave_value_typeinfo::binary_op_fcn> (f);
+}
+
+octave_value_typeinfo::binary_class_op_fcn
+octave_value_typeinfo::do_lookup_binary_class_op (octave_value::compound_binary_op op)
+{
+  void *f = compound_binary_class_ops.checkelem (static_cast<int> (op));
+  return reinterpret_cast<octave_value_typeinfo::binary_class_op_fcn> (f);
+}
+
+octave_value_typeinfo::binary_op_fcn
+octave_value_typeinfo::do_lookup_binary_op (octave_value::compound_binary_op op,
+					    int t1, int t2)
+{
+  void *f = compound_binary_ops.checkelem (static_cast<int> (op), t1, t2);
+  return reinterpret_cast<octave_value_typeinfo::binary_op_fcn> (f);
+}
+
+octave_value_typeinfo::cat_op_fcn
+octave_value_typeinfo::do_lookup_cat_op (int t1, int t2)
+{
+  void *f = cat_ops.checkelem (t1, t2);
+  return reinterpret_cast<octave_value_typeinfo::cat_op_fcn> (f);
+}
+
+octave_value_typeinfo::assign_op_fcn
+octave_value_typeinfo::do_lookup_assign_op (octave_value::assign_op op,
+					    int t_lhs, int t_rhs)
+{
+  void *f = assign_ops.checkelem (static_cast<int> (op), t_lhs, t_rhs);
+  return reinterpret_cast<octave_value_typeinfo::assign_op_fcn> (f);
+}
+
+octave_value_typeinfo::assignany_op_fcn
+octave_value_typeinfo::do_lookup_assignany_op (octave_value::assign_op op,
+					       int t_lhs)
+{
+  void *f = assignany_ops.checkelem (static_cast<int> (op), t_lhs);
+  return reinterpret_cast<octave_value_typeinfo::assignany_op_fcn> (f);
+}
+
+int
+octave_value_typeinfo::do_lookup_pref_assign_conv (int t_lhs, int t_rhs)
+{
+  return pref_assign_conv.checkelem (t_lhs, t_rhs);
+}
+
+octave_base_value::type_conv_fcn
+octave_value_typeinfo::do_lookup_type_conv_op (int t, int t_result)
+{
+  void *f = type_conv_ops.checkelem (t, t_result);
+  return reinterpret_cast<octave_base_value::type_conv_fcn> (f);
+}
+
+octave_base_value::type_conv_fcn
+octave_value_typeinfo::do_lookup_widening_op (int t, int t_result)
+{
+  void *f = widening_ops.checkelem (t, t_result);
+  return reinterpret_cast<octave_base_value::type_conv_fcn> (f);
+}
+
+string_vector
+octave_value_typeinfo::do_installed_type_names (void)
+{
+  string_vector retval (num_types);
+
+  for (int i = 0;i < num_types; i++)
+    retval (i) = types (i);
+
+  return retval;
+}
+
+DEFUN (typeinfo, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} typeinfo (@var{expr})\n\
+\n\
+Return the type of the expression @var{expr}, as a string.  If\n\
+ at var{expr} is omitted, return an array of strings containing all the\n\
+currently installed data types.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_value_typeinfo::installed_type_names ();
+  else if (nargin == 1)
+    retval = args(0).type_name ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-typeinfo.h b/src/ov-typeinfo.h
new file mode 100644
index 0000000..56c809f
--- /dev/null
+++ b/src/ov-typeinfo.h
@@ -0,0 +1,329 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_value_typeinfo_h)
+#define octave_value_typeinfo_h 1
+
+#include <string>
+
+#include "Array.h"
+#include "Array2.h"
+#include "Array3.h"
+
+#include "ov.h"
+
+class string_vector;
+
+class
+OCTINTERP_API
+octave_value_typeinfo
+{
+public:
+
+  typedef octave_value (*unary_class_op_fcn) (const octave_value&);
+
+  typedef octave_value (*unary_op_fcn) (const octave_base_value&);
+
+  typedef void (*non_const_unary_op_fcn) (octave_base_value&);
+
+  typedef octave_value (*binary_class_op_fcn)
+    (const octave_value&, const octave_value&);
+
+  typedef octave_value (*binary_op_fcn)
+    (const octave_base_value&, const octave_base_value&);
+
+  typedef octave_value (*cat_op_fcn)
+    (octave_base_value&, const octave_base_value&, const Array<octave_idx_type>& ra_idx);
+
+  typedef octave_value (*assign_op_fcn)
+    (octave_base_value&, const octave_value_list&, const octave_base_value&);
+
+  typedef octave_value (*assignany_op_fcn)
+    (octave_base_value&, const octave_value_list&, const octave_value&);
+
+  static bool instance_ok (void);
+
+  static int register_type (const std::string&, const std::string&,
+			    const octave_value&);
+
+  static bool register_unary_class_op (octave_value::unary_op,
+				       unary_class_op_fcn);
+
+  static bool register_unary_op (octave_value::unary_op, int, unary_op_fcn);
+
+  static bool register_non_const_unary_op (octave_value::unary_op, int,
+					   non_const_unary_op_fcn);
+
+  static bool register_binary_class_op (octave_value::binary_op,
+					binary_class_op_fcn);
+
+  static bool register_binary_op (octave_value::binary_op, int, int,
+				  binary_op_fcn);
+
+  static bool register_binary_class_op (octave_value::compound_binary_op,
+					binary_class_op_fcn);
+
+  static bool register_binary_op (octave_value::compound_binary_op, int, int,
+				  binary_op_fcn);
+
+  static bool register_cat_op (int, int, cat_op_fcn);
+
+  static bool register_assign_op (octave_value::assign_op, int, int,
+				  assign_op_fcn);
+
+  static bool register_assignany_op (octave_value::assign_op, int,
+				     assignany_op_fcn);
+
+  static bool register_pref_assign_conv (int, int, int);
+
+  static bool
+  register_type_conv_op (int, int, octave_base_value::type_conv_fcn);
+
+  static bool
+  register_widening_op (int, int, octave_base_value::type_conv_fcn);
+
+  static octave_value
+  lookup_type (const std::string& nm)
+  {
+    return instance->do_lookup_type (nm);
+  }
+
+  static unary_class_op_fcn
+  lookup_unary_class_op (octave_value::unary_op op)
+  {
+    return instance->do_lookup_unary_class_op (op);
+  }
+
+  static unary_op_fcn
+  lookup_unary_op (octave_value::unary_op op, int t)
+  {
+    return instance->do_lookup_unary_op (op, t);
+  }
+
+  static non_const_unary_op_fcn
+  lookup_non_const_unary_op (octave_value::unary_op op, int t)
+  {
+    return instance->do_lookup_non_const_unary_op (op, t);
+  }
+
+  static binary_class_op_fcn
+  lookup_binary_class_op (octave_value::binary_op op)
+  {
+    return instance->do_lookup_binary_class_op (op);
+  }
+
+  static binary_op_fcn
+  lookup_binary_op (octave_value::binary_op op, int t1, int t2)
+  {
+    return instance->do_lookup_binary_op (op, t1, t2);
+  }
+
+  static binary_class_op_fcn
+  lookup_binary_class_op (octave_value::compound_binary_op op)
+  {
+    return instance->do_lookup_binary_class_op (op);
+  }
+
+  static binary_op_fcn
+  lookup_binary_op (octave_value::compound_binary_op op, int t1, int t2)
+  {
+    return instance->do_lookup_binary_op (op, t1, t2);
+  }
+
+  static cat_op_fcn
+  lookup_cat_op (int t1, int t2)
+  {
+    return instance->do_lookup_cat_op (t1, t2);
+  }
+
+  static assign_op_fcn
+  lookup_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs)
+  {
+    return instance->do_lookup_assign_op (op, t_lhs, t_rhs);
+  }
+
+  static assignany_op_fcn
+  lookup_assignany_op (octave_value::assign_op op, int t_lhs)
+  {
+    return instance->do_lookup_assignany_op (op, t_lhs);
+  }
+
+  static int
+  lookup_pref_assign_conv (int t_lhs, int t_rhs)
+  {
+    return instance->do_lookup_pref_assign_conv (t_lhs, t_rhs);
+  }
+
+  static octave_base_value::type_conv_fcn
+  lookup_type_conv_op (int t, int t_result)
+  {
+    return instance->do_lookup_type_conv_op (t, t_result);
+  }
+
+  static octave_base_value::type_conv_fcn
+  lookup_widening_op (int t, int t_result)
+  {
+    return instance->do_lookup_widening_op (t, t_result);
+  }
+
+  static string_vector installed_type_names (void)
+  {
+    return instance->do_installed_type_names ();
+  }
+
+protected:
+
+  octave_value_typeinfo (void)
+    : num_types (0), types (init_tab_sz, std::string ()),
+      vals (init_tab_sz),
+      unary_class_ops (octave_value::num_unary_ops, 0),
+      unary_ops (octave_value::num_unary_ops, init_tab_sz, 0),
+      non_const_unary_ops (octave_value::num_unary_ops, init_tab_sz, 0),
+      binary_class_ops (octave_value::num_binary_ops, 0),
+      binary_ops (octave_value::num_binary_ops, init_tab_sz, init_tab_sz, 0),
+      cat_ops (init_tab_sz, init_tab_sz, 0),
+      assign_ops (octave_value::num_assign_ops, init_tab_sz, init_tab_sz, 0),
+      assignany_ops (octave_value::num_assign_ops, init_tab_sz, 0),
+      pref_assign_conv (init_tab_sz, init_tab_sz, -1),
+      type_conv_ops (init_tab_sz, init_tab_sz, 0),
+      widening_ops (init_tab_sz, init_tab_sz, 0)  { }
+
+private:
+
+  static const int init_tab_sz;
+
+  static octave_value_typeinfo *instance;
+
+  int num_types;
+
+  Array<std::string> types;
+
+  Array<octave_value> vals;
+
+  Array<void *> unary_class_ops;
+
+  Array2<void *> unary_ops;
+
+  Array2<void *> non_const_unary_ops;
+
+  Array<void *> binary_class_ops;
+
+  Array3<void *> binary_ops;
+
+  Array<void *> compound_binary_class_ops;
+
+  Array3<void *> compound_binary_ops;
+
+  Array2<void *> cat_ops;
+
+  Array3<void *> assign_ops;
+
+  Array2<void *> assignany_ops;
+
+  Array2<int> pref_assign_conv;
+
+  Array2<void *> type_conv_ops;
+
+  Array2<void *> widening_ops;
+
+  int do_register_type (const std::string&, const std::string&,
+			const octave_value&);
+
+  bool do_register_unary_class_op (octave_value::unary_op, unary_class_op_fcn);
+
+  bool do_register_unary_op (octave_value::unary_op, int, unary_op_fcn);
+
+  bool do_register_non_const_unary_op (octave_value::unary_op, int,
+				       non_const_unary_op_fcn);
+
+  bool do_register_binary_class_op (octave_value::binary_op,
+				    binary_class_op_fcn);
+
+  bool do_register_binary_op (octave_value::binary_op, int, int,
+			      binary_op_fcn);
+
+  bool do_register_binary_class_op (octave_value::compound_binary_op,
+				    binary_class_op_fcn);
+
+  bool do_register_binary_op (octave_value::compound_binary_op, int, int,
+			      binary_op_fcn);
+
+  bool do_register_cat_op (int, int, cat_op_fcn);
+
+  bool do_register_assign_op (octave_value::assign_op, int, int,
+			      assign_op_fcn);
+
+  bool do_register_assignany_op (octave_value::assign_op, int,
+				 assignany_op_fcn);
+
+  bool do_register_pref_assign_conv (int, int, int);
+
+  bool do_register_type_conv_op (int, int, octave_base_value::type_conv_fcn);
+
+  bool do_register_widening_op (int, int, octave_base_value::type_conv_fcn);
+
+  octave_value do_lookup_type (const std::string& nm);
+
+  unary_class_op_fcn do_lookup_unary_class_op (octave_value::unary_op);
+
+  unary_op_fcn do_lookup_unary_op (octave_value::unary_op, int);
+
+  non_const_unary_op_fcn do_lookup_non_const_unary_op
+    (octave_value::unary_op, int);
+
+  binary_class_op_fcn do_lookup_binary_class_op (octave_value::binary_op);
+
+  binary_op_fcn do_lookup_binary_op (octave_value::binary_op, int, int);
+
+  binary_class_op_fcn do_lookup_binary_class_op (octave_value::compound_binary_op);
+
+  binary_op_fcn do_lookup_binary_op (octave_value::compound_binary_op, int, int);
+
+  cat_op_fcn do_lookup_cat_op (int, int);
+
+  assign_op_fcn do_lookup_assign_op (octave_value::assign_op, int, int);
+
+  assignany_op_fcn do_lookup_assignany_op (octave_value::assign_op, int);
+
+  int do_lookup_pref_assign_conv (int, int);
+
+  octave_base_value::type_conv_fcn do_lookup_type_conv_op (int, int);
+
+  octave_base_value::type_conv_fcn do_lookup_widening_op (int, int);
+
+  string_vector do_installed_type_names (void);
+
+  // No copying!
+
+  octave_value_typeinfo (const octave_value_typeinfo&);
+
+  octave_value_typeinfo& operator = (const octave_value_typeinfo&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint16.cc b/src/ov-uint16.cc
new file mode 100644
index 0000000..364d9b6
--- /dev/null
+++ b/src/ov-uint16.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_UINT16
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-uint16.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<uint16NDArray>;
+
+template class octave_base_int_matrix<uint16NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint16_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint16_matrix,
+				     "uint16 matrix", "uint16");
+
+template class octave_base_scalar<octave_uint16>;
+
+template class octave_base_int_scalar<octave_uint16>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint16_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint16_scalar,
+				     "uint16 scalar", "uint16");
+
+DEFUN (uint16, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} uint16 (@var{x})\n\
+Convert @var{x} to unsigned 16-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (uint16);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint16.h b/src/ov-uint16.h
new file mode 100644
index 0000000..be1713e
--- /dev/null
+++ b/src/ov-uint16.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint16_h)
+#define octave_uint16_h 1
+
+#define OCTAVE_INT_T octave_uint16
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_uint16_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION uint16_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_uint16_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION uint16_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_uint16_type
+
+#define OCTAVE_INT_MX_CLASS mxUINT16_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint32.cc b/src/ov-uint32.cc
new file mode 100644
index 0000000..ad752cf
--- /dev/null
+++ b/src/ov-uint32.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_UINT32
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-uint32.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<uint32NDArray>;
+
+template class octave_base_int_matrix<uint32NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint32_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint32_matrix,
+				     "uint32 matrix", "uint32");
+
+template class octave_base_scalar<octave_uint32>;
+
+template class octave_base_int_scalar<octave_uint32>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint32_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint32_scalar,
+				     "uint32 scalar", "uint32");
+
+DEFUN (uint32, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} uint32 (@var{x})\n\
+Convert @var{x} to unsigned 32-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (uint32);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint32.h b/src/ov-uint32.h
new file mode 100644
index 0000000..c8d4dcd
--- /dev/null
+++ b/src/ov-uint32.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint32_h)
+#define octave_uint32_h 1
+
+#define OCTAVE_INT_T octave_uint32
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_uint32_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION uint32_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_uint32_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION uint32_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_uint32_type
+
+#define OCTAVE_INT_MX_CLASS mxUINT32_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint64.cc b/src/ov-uint64.cc
new file mode 100644
index 0000000..596d4c2
--- /dev/null
+++ b/src/ov-uint64.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_UINT64
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-uint64.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<uint64NDArray>;
+
+template class octave_base_int_matrix<uint64NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint64_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint64_matrix,
+				     "uint64 matrix", "uint64");
+
+template class octave_base_scalar<octave_uint64>;
+
+template class octave_base_int_scalar<octave_uint64>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint64_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint64_scalar,
+				     "uint64 scalar", "uint64");
+
+DEFUN (uint64, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} uint64 (@var{x})\n\
+Convert @var{x} to unsigned 64-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (uint64);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint64.h b/src/ov-uint64.h
new file mode 100644
index 0000000..659902d
--- /dev/null
+++ b/src/ov-uint64.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint64_h)
+#define octave_uint64_h 1
+
+#define OCTAVE_INT_T octave_uint64
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_uint64_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION uint64_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_uint64_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION uint64_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_uint64_type
+
+#define OCTAVE_INT_MX_CLASS mxUINT64_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint8.cc b/src/ov-uint8.cc
new file mode 100644
index 0000000..3364e7b
--- /dev/null
+++ b/src/ov-uint8.cc
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <climits>
+
+#include <iostream>
+
+#include "lo-ieee.h"
+#include "lo-utils.h"
+#include "mx-base.h"
+#include "quit.h"
+
+#include "defun.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ops.h"
+#include "ov-base.h"
+
+#ifdef HAVE_HDF5
+#define HDF5_SAVE_TYPE H5T_NATIVE_UINT8
+#endif
+
+#include "ov-base-int.h"
+#include "ov-base-int.cc"
+#include "ov-uint8.h"
+#include "ov-type-conv.h"
+#include "pr-output.h"
+#include "variables.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-utils.h"
+#include "ls-hdf5.h"
+
+template class octave_base_matrix<uint8NDArray>;
+
+template class octave_base_int_matrix<uint8NDArray>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint8_matrix);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint8_matrix,
+				     "uint8 matrix", "uint8");
+
+template class octave_base_scalar<octave_uint8>;
+
+template class octave_base_int_scalar<octave_uint8>;
+
+DEFINE_OCTAVE_ALLOCATOR (octave_uint8_scalar);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint8_scalar,
+				     "uint8 scalar", "uint8");
+
+DEFUN (uint8, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} uint8 (@var{x})\n\
+Convert @var{x} to unsigned 8-bit integer type.\n\
+ at end deftypefn")
+{
+  OCTAVE_TYPE_CONV_BODY (uint8);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-uint8.h b/src/ov-uint8.h
new file mode 100644
index 0000000..fa00779
--- /dev/null
+++ b/src/ov-uint8.h
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_uint8_h)
+#define octave_uint8_h 1
+
+#define OCTAVE_INT_T octave_uint8
+
+#define OCTAVE_VALUE_INT_MATRIX_T octave_uint8_matrix
+#define OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION uint8_array_value
+
+#define OCTAVE_VALUE_INT_SCALAR_T octave_uint8_scalar
+#define OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION uint8_scalar_value
+
+#define OCTAVE_TYPE_PREDICATE_FUNCTION is_uint8_type
+
+#define OCTAVE_INT_MX_CLASS mxUINT8_CLASS
+
+#include "ov-intx.h"
+
+#undef OCTAVE_INT_T
+
+#undef OCTAVE_VALUE_INT_MATRIX_T
+#undef OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_VALUE_INT_SCALAR_T
+#undef OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION
+
+#undef OCTAVE_TYPE_PREDICATE_FUNCTION
+
+#undef OCTAVE_INT_MX_CLASS
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-usr-fcn.cc b/src/ov-usr-fcn.cc
new file mode 100644
index 0000000..8889466
--- /dev/null
+++ b/src/ov-usr-fcn.cc
@@ -0,0 +1,702 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "str-vec.h"
+
+#include <defaults.h>
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "input.h"
+#include "oct-obj.h"
+#include "ov-usr-fcn.h"
+#include "ov.h"
+#include "pager.h"
+#include "pt-eval.h"
+#include "pt-jump.h"
+#include "pt-misc.h"
+#include "pt-pr-code.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "symtab.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "parse.h"
+#include "variables.h"
+
+// Maximum nesting level for functions called recursively.
+static int Vmax_recursion_depth = 256;
+
+// User defined scripts.
+
+DEFINE_OCTAVE_ALLOCATOR (octave_user_script);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_user_script,
+				     "user-defined script",
+				     "user-defined script");
+
+octave_user_script::octave_user_script (void)
+  : octave_user_code (), cmd_list (0), file_name (),
+    t_parsed (static_cast<time_t> (0)),
+    t_checked (static_cast<time_t> (0)),
+    call_depth (-1)
+{ }
+
+octave_user_script::octave_user_script (const std::string& fnm,
+					const std::string& nm,
+					tree_statement_list *cmds,
+					const std::string& ds)
+  : octave_user_code (nm, ds), cmd_list (cmds), file_name (fnm),
+    t_parsed (static_cast<time_t> (0)),
+    t_checked (static_cast<time_t> (0)),
+    call_depth (-1)
+{
+  if (cmd_list)
+    cmd_list->mark_as_script_body ();
+}
+
+octave_user_script::octave_user_script (const std::string& fnm,
+					const std::string& nm,
+					const std::string& ds)
+  : octave_user_code (nm, ds), cmd_list (0), file_name (fnm), 
+    t_parsed (static_cast<time_t> (0)),
+    t_checked (static_cast<time_t> (0)),
+    call_depth (-1)
+{ }
+
+octave_user_script::~octave_user_script (void)
+{
+  delete cmd_list;
+}
+
+octave_value_list
+octave_user_script::subsref (const std::string&,
+			     const std::list<octave_value_list>&, int)
+{
+  octave_value_list retval;
+
+  ::error ("invalid use of script in index expression");
+
+  return retval;
+}
+
+octave_value_list
+octave_user_script::do_multi_index_op (int nargout,
+				       const octave_value_list& args)
+{
+  octave_value_list retval;
+
+  unwind_protect::begin_frame ("user_script_eval");
+
+  if (! error_state)
+    {
+      if (args.length () == 0 && nargout == 0)
+	{
+	  if (cmd_list)
+	    {
+	      unwind_protect_int (call_depth);
+	      call_depth++;
+
+	      if (call_depth < Vmax_recursion_depth)
+		{
+		  octave_call_stack::push (this);
+
+		  unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+		  unwind_protect_bool (tree_evaluator::in_fcn_or_script_body);
+		  tree_evaluator::in_fcn_or_script_body = true;
+
+		  cmd_list->accept (*current_evaluator);
+
+		  if (tree_return_command::returning)
+		    tree_return_command::returning = 0;
+
+		  if (tree_break_command::breaking)
+		    tree_break_command::breaking--;
+
+		  if (error_state)
+		    octave_call_stack::backtrace_error_message ();
+		}
+	      else
+		::error ("max_recursion_limit exceeded");
+    	    }
+	}
+      else
+	error ("invalid call to script");
+    }
+
+  unwind_protect::run_frame ("user_script_eval");
+
+  return retval;
+}
+
+void
+octave_user_script::accept (tree_walker& tw)
+{
+  tw.visit_octave_user_script (*this);
+}
+
+// User defined functions.
+
+DEFINE_OCTAVE_ALLOCATOR (octave_user_function);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_user_function,
+				     "user-defined function",
+				     "user-defined function");
+
+// Ugh.  This really needs to be simplified (code/data?
+// extrinsic/intrinsic state?).
+
+octave_user_function::octave_user_function
+  (symbol_table::scope_id sid, tree_parameter_list *pl,
+   tree_parameter_list *rl, tree_statement_list *cl)
+  : octave_user_code (std::string (), std::string ()),
+    param_list (pl), ret_list (rl), cmd_list (cl),
+    lead_comm (), trail_comm (), file_name (),
+    parent_name (), t_parsed (static_cast<time_t> (0)),
+    t_checked (static_cast<time_t> (0)),
+    system_fcn_file (false), call_depth (-1),
+    num_named_args (param_list ? param_list->length () : 0),
+    nested_function (false), inline_function (false),
+    class_constructor (false), class_method (false), args_passed (),
+    num_args_passed (0), parent_scope (-1), local_scope (sid)
+{
+  if (cmd_list)
+    cmd_list->mark_as_function_body ();
+}
+
+octave_user_function::~octave_user_function (void)
+{
+  delete param_list;
+  delete ret_list;
+  delete cmd_list;
+  delete lead_comm;
+  delete trail_comm;
+
+  symbol_table::erase_scope (local_scope);
+}
+
+octave_user_function *
+octave_user_function::define_ret_list (tree_parameter_list *t)
+{
+  ret_list = t;
+
+  return this;
+}
+
+void
+octave_user_function::stash_fcn_file_name (const std::string& nm)
+{
+  file_name = nm;
+}
+
+void
+octave_user_function::mark_as_system_fcn_file (void)
+{
+  if (! file_name.empty ())
+    {
+      // We really should stash the whole path to the file we found,
+      // when we looked it up, to avoid possible race conditions...
+      // FIXME
+      //
+      // We probably also don't need to get the library directory
+      // every time, but since this function is only called when the
+      // function file is parsed, it probably doesn't matter that
+      // much.
+
+      std::string ff_name = fcn_file_in_path (file_name);
+
+      if (Vfcn_file_dir == ff_name.substr (0, Vfcn_file_dir.length ()))
+	system_fcn_file = 1;
+    }
+  else
+    system_fcn_file = 0;
+}
+
+bool
+octave_user_function::takes_varargs (void) const
+{
+  return (param_list && param_list->takes_varargs ());
+}
+
+bool
+octave_user_function::takes_var_return (void) const
+{
+  return (ret_list && ret_list->takes_varargs ());
+}
+
+void
+octave_user_function::lock_subfunctions (void)
+{
+  symbol_table::lock_subfunctions (local_scope);
+}
+
+void
+octave_user_function::unlock_subfunctions (void)
+{
+  symbol_table::unlock_subfunctions (local_scope);
+}
+
+octave_value_list
+octave_user_function::octave_all_va_args (void)
+{
+  octave_value_list retval;
+
+  octave_idx_type n = num_args_passed - num_named_args;
+
+  if (n > 0)
+    retval = args_passed.slice (num_named_args, n);
+
+  return retval;
+}
+
+static void
+clear_param_list (void *lst)
+{
+  tree_parameter_list *tmp = static_cast<tree_parameter_list *> (lst);
+
+  if (tmp)
+    tmp->undefine ();
+}
+
+static void
+restore_args_passed (void *fcn)
+{
+  octave_user_function *tmp = static_cast<octave_user_function *> (fcn);
+
+  if (tmp)
+    tmp->restore_args_passed ();
+}
+
+octave_value_list
+octave_user_function::subsref (const std::string& type,
+			       const std::list<octave_value_list>& idx,
+			       int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      {
+	int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
+
+	retval = do_multi_index_op (tmp_nargout, idx.front ());
+      }
+      break;
+
+    case '{':
+    case '.':
+      {
+	std::string nm = type_name ();
+	error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+    }
+
+  // FIXME -- perhaps there should be an
+  // octave_value_list::next_subsref member function?  See also
+  // octave_builtin::subsref.
+
+  if (idx.size () > 1)
+    retval = retval(0).next_subsref (nargout, type, idx);
+
+  return retval;
+}
+
+octave_value_list
+octave_user_function::do_multi_index_op (int nargout,
+					 const octave_value_list& args)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  if (! cmd_list)
+    return retval;
+
+  int nargin = args.length ();
+
+  unwind_protect::begin_frame ("user_func_eval");
+
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth >= Vmax_recursion_depth)
+    {
+      ::error ("max_recursion_limit exceeded");
+      unwind_protect::run_frame ("user_func_eval");
+      return retval;
+    }
+
+  // Save old and set current symbol table context, for
+  // eval_undefined_error().
+
+  octave_call_stack::push (this, local_scope, call_depth);
+  unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+  if (call_depth > 0)
+    {
+      symbol_table::push_context ();
+
+      unwind_protect::add (symbol_table::pop_context);
+    }
+
+  // Save and restore args passed for recursive calls.
+
+  save_args_passed (args);
+
+  unwind_protect::add (::restore_args_passed, this);
+
+  string_vector arg_names = args.name_tags ();
+
+  unwind_protect_int (num_args_passed);
+  num_args_passed = nargin;
+
+  if (param_list && ! param_list->varargs_only ())
+    {
+      param_list->define_from_arg_vector (args);
+      if (error_state)
+	goto abort;
+    }
+
+  // Force parameter list to be undefined when this function exits.
+  // Doing so decrements the reference counts on the values of local
+  // variables that are also named function parameters.
+
+  unwind_protect::add (clear_param_list, param_list);
+
+  // Force return list to be undefined when this function exits.
+  // Doing so decrements the reference counts on the values of local
+  // variables that are also named values returned by this function.
+
+  unwind_protect::add (clear_param_list, ret_list);
+
+  if (call_depth == 0)
+    {
+      // Force symbols to be undefined again when this function
+      // exits.
+      //
+      // This cleanup function is added to the unwind_protect stack
+      // after the calls to clear the parameter lists so that local
+      // variables will be cleared before the parameter lists are
+      // cleared.  That way, any function parameters that have been
+      // declared global will be unmarked as global before they are
+      // undefined by the clear_param_list cleanup function.
+
+      unwind_protect::add (symbol_table::clear_variables);
+    }
+
+  // The following code is in a separate scope to avoid warnings from
+  // G++ about `goto abort' crossing the initialization of some
+  // variables.
+
+  {
+    bind_automatic_vars (arg_names, nargin, nargout, octave_all_va_args ());
+
+    bool echo_commands = (Vecho_executing_commands & ECHO_FUNCTIONS);
+
+    if (echo_commands)
+      print_code_function_header ();
+
+    // Evaluate the commands that make up the function.
+
+    unwind_protect_bool (tree_evaluator::in_fcn_or_script_body);
+    tree_evaluator::in_fcn_or_script_body = true;
+
+    bool special_expr = (is_inline_function ()
+			 || cmd_list->is_anon_function_body ());
+
+    if (special_expr)
+      {
+	assert (cmd_list->length () == 1);
+
+	tree_statement *stmt = 0;
+
+	if ((stmt = cmd_list->front ())
+	    && stmt->is_expression ())
+	  {
+	    tree_expression *expr = stmt->expression ();
+
+	    retval = expr->rvalue (nargout);
+	  }
+      }
+    else
+      cmd_list->accept (*current_evaluator);
+
+    if (echo_commands)
+      print_code_function_trailer ();
+
+    if (tree_return_command::returning)
+      tree_return_command::returning = 0;
+
+    if (tree_break_command::breaking)
+      tree_break_command::breaking--;
+
+    if (error_state)
+      {
+	octave_call_stack::backtrace_error_message ();
+	goto abort;
+      }
+    
+    // Copy return values out.
+
+    if (ret_list && ! special_expr)
+      {
+	ret_list->initialize_undefined_elements (my_name, nargout, Matrix ());
+
+	Cell varargout;
+
+	if (ret_list->takes_varargs ())
+	  {
+	    octave_value varargout_varval = symbol_table::varval ("varargout");
+
+	    if (varargout_varval.is_defined ())
+	      {
+		varargout = varargout_varval.cell_value ();
+
+		if (error_state)
+		  error ("expecting varargout to be a cell array object");
+	      }
+	  }
+
+	if (! error_state)
+	  retval = ret_list->convert_to_const_vector (varargout);
+      }
+  }
+
+ abort:
+  unwind_protect::run_frame ("user_func_eval");
+
+  return retval;
+}
+
+void
+octave_user_function::accept (tree_walker& tw)
+{
+  tw.visit_octave_user_function (*this);
+}
+
+#if 0
+void
+octave_user_function::print_symtab_info (std::ostream& os) const
+{
+  symbol_table::print_info (os, local_scope);
+}
+#endif
+
+void
+octave_user_function::print_code_function_header (void)
+{
+  tree_print_code tpc (octave_stdout, VPS4);
+
+  tpc.visit_octave_user_function_header (*this);
+}
+
+void
+octave_user_function::print_code_function_trailer (void)
+{
+  tree_print_code tpc (octave_stdout, VPS4);
+
+  tpc.visit_octave_user_function_trailer (*this);
+}
+
+void
+octave_user_function::bind_automatic_vars
+  (const string_vector& arg_names, int nargin, int nargout,
+   const octave_value_list& va_args)
+{
+  if (! arg_names.empty ())
+    symbol_table::varref ("argn") = arg_names;
+
+  symbol_table::varref (".nargin.") = nargin;
+  symbol_table::varref (".nargout.") = nargout;
+
+  symbol_table::mark_hidden (".nargin.");
+  symbol_table::mark_hidden (".nargout.");
+
+  if (takes_varargs ())
+    symbol_table::varref ("varargin") = va_args.cell_value ();
+}
+
+DEFUN (nargin, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} nargin ()\n\
+ at deftypefnx {Built-in Function} {} nargin (@var{fcn_name})\n\
+Within a function, return the number of arguments passed to the function.\n\
+At the top level, return the number of command line arguments passed to\n\
+Octave.  If called with the optional argument @var{fcn_name}, return the\n\
+maximum number of arguments the named function can accept, or -1 if the\n\
+function accepts a variable number of arguments.\n\
+ at seealso{nargout, varargin, varargout}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string fname = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  octave_value fcn_val = symbol_table::find_user_function (fname);
+
+	  octave_user_function *fcn = fcn_val.user_function_value (true);
+
+	  if (fcn)
+	    {
+	      if (fcn->takes_varargs ())
+		retval = -1;
+	      else
+		{
+		  tree_parameter_list *param_list = fcn->parameter_list ();
+
+		  retval = param_list ? param_list->length () : 0;
+		}
+	    }
+	  else
+	    error ("nargin: invalid function");
+	}
+      else
+	error ("nargin: expecting string as first argument");
+    }
+  else if (nargin == 0)
+    {
+      retval = symbol_table::varval (".nargin.");
+
+      if (retval.is_undefined ())
+	retval = 0;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (nargout, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} nargout ()\n\
+ at deftypefnx {Built-in Function} {} nargout (@var{fcn_name})\n\
+Within a function, return the number of values the caller expects to\n\
+receive.  If called with the optional argument @var{fcn_name}, return the\n\
+maximum number of values the named function can produce, or -1 if the\n\
+function can produce a variable number of values.\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+f ()\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will cause @code{nargout} to return 0 inside the function @code{f} and\n\
+\n\
+ at example\n\
+[s, t] = f ()\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will cause @code{nargout} to return 2 inside the function\n\
+ at code{f}.\n\
+\n\
+At the top level, @code{nargout} is undefined.\n\
+ at seealso{nargin, varargin, varargout}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string fname = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  octave_value fcn_val = symbol_table::find_user_function (fname);
+
+	  octave_user_function *fcn = fcn_val.user_function_value (true);
+
+	  if (fcn)
+	    {
+	      if (fcn->takes_var_return ())
+		retval = -1;
+	      else
+		{
+		  tree_parameter_list *ret_list = fcn->return_list ();
+
+		  retval = ret_list ? ret_list->length () : 0;
+		}
+	    }
+	  else
+	    error ("nargout: invalid function");
+	}
+      else
+	error ("nargout: expecting string as first argument");
+    }
+  else if (nargin == 0)
+    {
+      if (! symbol_table::at_top_level ())
+	{
+	  retval = symbol_table::varval (".nargout.");
+
+	  if (retval.is_undefined ())
+	    retval = 0;
+	}
+      else
+	error ("nargout: invalid call at top level");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (max_recursion_depth, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} max_recursion_depth ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} max_recursion_depth (@var{new_val})\n\
+Query or set the internal limit on the number of times a function may\n\
+be called recursively.  If the limit is exceeded, an error message is\n\
+printed and control returns to the top level.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (max_recursion_depth);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov-usr-fcn.h b/src/ov-usr-fcn.h
new file mode 100644
index 0000000..98e2069
--- /dev/null
+++ b/src/ov-usr-fcn.h
@@ -0,0 +1,418 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_user_function_h)
+#define octave_user_function_h 1
+
+#include <ctime>
+
+#include <string>
+#include <stack>
+
+#include "comment-list.h"
+#include "oct-obj.h"
+#include "ov-fcn.h"
+#include "ov-typeinfo.h"
+#include "symtab.h"
+
+class string_vector;
+
+class octave_value;
+class tree_parameter_list;
+class tree_statement_list;
+class tree_va_return_list;
+class tree_walker;
+
+class 
+octave_user_code : public octave_function
+{
+public:
+  octave_user_code (void)
+    : octave_function () { }
+
+  ~octave_user_code (void) { }
+
+  bool is_user_code (void) const { return true; }
+
+  virtual tree_statement_list *body (void) = 0;
+
+protected:
+
+  octave_user_code (const std::string& nm,
+		    const std::string& ds = std::string ())
+    : octave_function (nm, ds) { }
+
+private:
+
+  // No copying!
+
+  octave_user_code (const octave_user_code& f);
+
+  octave_user_code& operator = (const octave_user_code& f);
+};
+
+// Scripts.
+
+class
+octave_user_script : public octave_user_code
+{
+public:
+
+  octave_user_script (void);
+
+  octave_user_script (const std::string& fnm, const std::string& nm,
+		      tree_statement_list *cmds,
+		      const std::string& ds = std::string ());
+
+  octave_user_script (const std::string& fnm, const std::string& nm,
+		      const std::string& ds = std::string ());
+
+  ~octave_user_script (void);
+
+  octave_function *function_value (bool = false) { return this; }
+
+  const octave_function *function_value (bool = false) const { return this; }
+
+  octave_user_script *user_script_value (bool = false) { return this; }
+
+  octave_user_code *user_code_value (bool = false) { return this; }
+
+  // Scripts and user functions are both considered "scripts" because
+  // they are written in Octave's scripting language.
+
+  bool is_user_script (void) const { return true; }
+
+  void stash_fcn_file_name (const std::string& nm) { file_name = nm; }
+
+  void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; }
+
+  void stash_fcn_file_time (const octave_time& t)
+    {
+      t_parsed = t;
+      mark_fcn_file_up_to_date (t);
+    }
+
+  std::string fcn_file_name (void) const { return file_name; }
+
+  octave_time time_parsed (void) const { return t_parsed; }
+
+  octave_time time_checked (void) const { return t_checked; }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& args);
+
+  tree_statement_list *body (void) { return cmd_list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The list of commands that make up the body of this function.
+  tree_statement_list *cmd_list;
+
+  // The name of the file we parsed.
+  std::string file_name;
+
+  // The time the file was parsed.
+  octave_time t_parsed;
+
+  // The time the file was last checked to see if it needs to be
+  // parsed again.
+  octave_time t_checked;
+
+  // Used to keep track of recursion depth.
+  int call_depth;
+
+  // No copying!
+
+  octave_user_script (const octave_user_script& f);
+
+  octave_user_script& operator = (const octave_user_script& f);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+// User-defined functions.
+
+class
+octave_user_function : public octave_user_code
+{
+public:
+
+  octave_user_function (symbol_table::scope_id sid = -1,
+			tree_parameter_list *pl = 0,
+			tree_parameter_list *rl = 0,
+			tree_statement_list *cl = 0);
+
+  ~octave_user_function (void);
+
+  octave_function *function_value (bool = false) { return this; }
+
+  const octave_function *function_value (bool = false) const { return this; }
+
+  octave_user_function *user_function_value (bool = false) { return this; }
+
+  octave_user_code *user_code_value (bool = false) { return this; }
+
+  octave_user_function *define_param_list (tree_parameter_list *t);
+
+  octave_user_function *define_ret_list (tree_parameter_list *t);
+
+  void stash_fcn_file_name (const std::string& nm);
+
+  void stash_parent_fcn_name (const std::string& p) { parent_name = p; }
+
+  void stash_parent_fcn_scope (symbol_table::scope_id ps) { parent_scope = ps; }
+
+  void stash_leading_comment (octave_comment_list *lc) { lead_comm = lc; }
+
+  void stash_trailing_comment (octave_comment_list *tc) { trail_comm = tc; }
+
+  void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; }
+
+  void stash_fcn_file_time (const octave_time& t)
+    {
+      t_parsed = t;
+      mark_fcn_file_up_to_date (t);
+    }
+
+  std::string fcn_file_name (void) const { return file_name; }
+
+  std::string parent_fcn_name (void) const { return parent_name; }
+
+  symbol_table::scope_id parent_fcn_scope (void) const { return parent_scope; }
+
+  symbol_table::scope_id scope (void) { return local_scope; }
+
+  octave_time time_parsed (void) const { return t_parsed; }
+
+  octave_time time_checked (void) const { return t_checked; }
+
+  void mark_as_system_fcn_file (void);
+
+  bool is_system_fcn_file (void) const { return system_fcn_file; }
+
+  bool is_user_function (void) const { return true; }
+
+  void erase_subfunctions (void)
+    {
+      symbol_table::erase_subfunctions_in_scope (local_scope);
+    }
+
+  bool takes_varargs (void) const;
+
+  bool takes_var_return (void) const;
+
+  void lock_subfunctions (void);
+
+  void unlock_subfunctions (void);
+
+  octave_value_list octave_all_va_args (void);
+
+  void stash_function_name (const std::string& s) { my_name = s; }
+
+  void mark_as_nested_function (void) { nested_function = true; }
+
+  bool is_nested_function (void) const { return nested_function; }
+
+  void mark_as_inline_function (void) { inline_function = true; }
+
+  bool is_inline_function (void) const { return inline_function; }
+
+  void mark_as_class_constructor (void) { class_constructor = true; }
+
+  bool is_class_constructor (void) const { return class_constructor; }
+
+  void mark_as_class_method (void) { class_method = true; }
+
+  bool is_class_method (void) const { return class_method; }
+
+  void save_args_passed (const octave_value_list& args)
+    {
+      if (call_depth > 0)
+	saved_args.push (args_passed);
+
+      args_passed = args;
+    }
+
+  void restore_args_passed (void)
+    {
+      if (saved_args.empty ())
+	args_passed = octave_value_list ();
+      else
+	{
+	  args_passed = saved_args.top ();
+	  saved_args.pop ();
+	}
+    }
+
+  octave_value subsref (const std::string& type,
+			const std::list<octave_value_list>& idx)
+    {
+      octave_value_list tmp = subsref (type, idx, 1);
+      return tmp.length () > 0 ? tmp(0) : octave_value ();
+    }
+
+  octave_value_list subsref (const std::string& type,
+			     const std::list<octave_value_list>& idx,
+			     int nargout);
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& args);
+
+  tree_parameter_list *parameter_list (void) { return param_list; }
+
+  tree_parameter_list *return_list (void) { return ret_list; }
+
+  tree_statement_list *body (void) { return cmd_list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  void accept (tree_walker& tw);
+
+#if 0
+  void print_symtab_info (std::ostream& os) const;
+#endif
+
+private:
+
+  // List of arguments for this function.  These are local variables.
+  tree_parameter_list *param_list;
+
+  // List of parameters we return.  These are also local variables in
+  // this function.
+  tree_parameter_list *ret_list;
+
+  // The list of commands that make up the body of this function.
+  tree_statement_list *cmd_list;
+
+  // The comments preceding the FUNCTION token.
+  octave_comment_list *lead_comm;
+
+  // The comments preceding the ENDFUNCTION token.
+  octave_comment_list *trail_comm;
+
+  // The name of the file we parsed.
+  std::string file_name;
+
+  // The name of the parent function, if any.
+  std::string parent_name;
+
+  // The time the file was parsed.
+  octave_time t_parsed;
+
+  // The time the file was last checked to see if it needs to be
+  // parsed again.
+  octave_time t_checked;
+
+  // True if this function came from a file that is considered to be a
+  // system function.  This affects whether we check the time stamp
+  // on the file to see if it has changed.
+  bool system_fcn_file;
+
+  // Used to keep track of recursion depth.
+  int call_depth;
+
+  // The number of arguments that have names.
+  int num_named_args;
+
+  // TRUE means this is a nested function.
+  bool nested_function;
+
+  // TRUE means this is an inline function.
+  bool inline_function;
+
+  // TRUE means this function is the constructor for class object.
+  bool class_constructor;
+
+  // TRUE means this function is a method for a class.
+  bool class_method;
+
+  // The values that were passed as arguments.
+  octave_value_list args_passed;
+
+  // A place to store the passed args for recursive calls.
+  std::stack<octave_value_list> saved_args;
+
+  // The number of arguments passed in.
+  int num_args_passed;
+
+  // The scope of the parent function, if any.
+  symbol_table::scope_id parent_scope;
+
+  symbol_table::scope_id local_scope;
+
+#if 0
+  // The symbol record for argn in the local symbol table.
+  octave_value& argn_varref;
+
+  // The symbol record for nargin in the local symbol table.
+  octave_value& nargin_varref;
+
+  // The symbol record for nargout in the local symbol table.
+  octave_value& nargout_varref;
+
+  // The symbol record for varargin in the local symbol table.
+  octave_value& varargin_varref;
+#endif
+
+  void print_code_function_header (void);
+
+  void print_code_function_trailer (void);
+
+  void bind_automatic_vars (const string_vector& arg_names, int nargin,
+			    int nargout, const octave_value_list& va_args);
+
+  // No copying!
+
+  octave_user_function (const octave_user_function& fn);
+
+  octave_user_function& operator = (const octave_user_function& fn);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov.cc b/src/ov.cc
new file mode 100644
index 0000000..c455f02
--- /dev/null
+++ b/src/ov.cc
@@ -0,0 +1,2732 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "data-conv.h"
+#include "quit.h"
+#include "str-vec.h"
+
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "ov.h"
+#include "ov-base.h"
+#include "ov-bool.h"
+#include "ov-bool-mat.h"
+#include "ov-cell.h"
+#include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-re-mat.h"
+#include "ov-flt-re-mat.h"
+#include "ov-re-diag.h"
+#include "ov-flt-re-diag.h"
+#include "ov-perm.h"
+#include "ov-bool-sparse.h"
+#include "ov-cx-sparse.h"
+#include "ov-re-sparse.h"
+#include "ov-int8.h"
+#include "ov-int16.h"
+#include "ov-int32.h"
+#include "ov-int64.h"
+#include "ov-uint8.h"
+#include "ov-uint16.h"
+#include "ov-uint32.h"
+#include "ov-uint64.h"
+#include "ov-complex.h"
+#include "ov-flt-complex.h"
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-cx-diag.h"
+#include "ov-flt-cx-diag.h"
+#include "ov-ch-mat.h"
+#include "ov-str-mat.h"
+#include "ov-range.h"
+#include "ov-struct.h"
+#include "ov-class.h"
+#include "ov-list.h"
+#include "ov-cs-list.h"
+#include "ov-colon.h"
+#include "ov-builtin.h"
+#include "ov-dld-fcn.h"
+#include "ov-usr-fcn.h"
+#include "ov-fcn-handle.h"
+#include "ov-fcn-inline.h"
+#include "ov-typeinfo.h"
+#include "ov-null-mat.h"
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "pager.h"
+#include "parse.h"
+#include "pr-output.h"
+#include "symtab.h"
+#include "utils.h"
+#include "variables.h"
+
+// We are likely to have a lot of octave_value objects to allocate, so
+// make the grow_size large.
+DEFINE_OCTAVE_ALLOCATOR2(octave_value, 1024);
+
+// FIXME
+
+// Octave's value type.
+
+std::string
+octave_value::unary_op_as_string (unary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case op_not:
+      retval = "!";
+      break;
+
+    case op_uplus:
+      retval = "+";
+      break;
+
+    case op_uminus:
+      retval = "-";
+      break;
+
+    case op_transpose:
+      retval = ".'";
+      break;
+
+    case op_hermitian:
+      retval = "'";
+      break;
+
+    case op_incr:
+      retval = "++";
+      break;
+
+    case op_decr:
+      retval = "--";
+      break;
+
+    default:
+      retval = "<unknown>";
+    }
+
+  return retval;
+}
+
+std::string
+octave_value::unary_op_fcn_name (unary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case op_not:
+      retval = "not";
+      break;
+
+    case op_uplus:
+      retval = "uplus";
+      break;
+
+    case op_uminus:
+      retval = "uminus";
+      break;
+
+    case op_transpose:
+      retval = "transpose";
+      break;
+
+    case op_hermitian:
+      retval = "ctranspose";
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+std::string
+octave_value::binary_op_as_string (binary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case op_add:
+      retval = "+";
+      break;
+
+    case op_sub:
+      retval = "-";
+      break;
+
+    case op_mul:
+      retval = "*";
+      break;
+
+    case op_div:
+      retval = "/";
+      break;
+
+    case op_pow:
+      retval = "^";
+      break;
+
+    case op_ldiv:
+      retval = "\\";
+      break;
+
+    case op_lshift:
+      retval = "<<";
+      break;
+
+    case op_rshift:
+      retval = ">>";
+      break;
+
+    case op_lt:
+      retval = "<";
+      break;
+
+    case op_le:
+      retval = "<=";
+      break;
+
+    case op_eq:
+      retval = "==";
+      break;
+
+    case op_ge:
+      retval = ">=";
+      break;
+
+    case op_gt:
+      retval = ">";
+      break;
+
+    case op_ne:
+      retval = "!=";
+      break;
+
+    case op_el_mul:
+      retval = ".*";
+      break;
+
+    case op_el_div:
+      retval = "./";
+      break;
+
+    case op_el_pow:
+      retval = ".^";
+      break;
+
+    case op_el_ldiv:
+      retval = ".\\";
+      break;
+
+    case op_el_and:
+      retval = "&";
+      break;
+
+    case op_el_or:
+      retval = "|";
+      break;
+
+    case op_struct_ref:
+      retval = ".";
+      break;
+
+    default:
+      retval = "<unknown>";
+    }
+
+  return retval;
+}
+
+std::string
+octave_value::binary_op_fcn_name (binary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case op_add:
+      retval = "plus";
+      break;
+
+    case op_sub:
+      retval = "minus";
+      break;
+
+    case op_mul:
+      retval = "mtimes";
+      break;
+
+    case op_div:
+      retval = "mrdivide";
+      break;
+
+    case op_pow:
+      retval = "mpower";
+      break;
+
+    case op_ldiv:
+      retval = "mldivide";
+      break;
+
+    case op_lt:
+      retval = "lt";
+      break;
+
+    case op_le:
+      retval = "le";
+      break;
+
+    case op_eq:
+      retval = "eq";
+      break;
+
+    case op_ge:
+      retval = "ge";
+      break;
+
+    case op_gt:
+      retval = "gt";
+      break;
+
+    case op_ne:
+      retval = "ne";
+      break;
+
+    case op_el_mul:
+      retval = "times";
+      break;
+
+    case op_el_div:
+      retval = "rdivide";
+      break;
+
+    case op_el_pow:
+      retval = "power";
+      break;
+
+    case op_el_ldiv:
+      retval = "ldivide";
+      break;
+
+    case op_el_and:
+      retval = "and";
+      break;
+
+    case op_el_or:
+      retval = "or";
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+std::string
+octave_value::binary_op_fcn_name (compound_binary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case op_trans_mul:
+      retval = "transtimes";
+      break;
+
+    case op_mul_trans:
+      retval = "timestrans";
+      break;
+
+    case op_herm_mul:
+      retval = "hermtimes";
+      break;
+
+    case op_mul_herm:
+      retval = "timesherm";
+      break;
+
+    case op_el_and_not:
+      retval = "andnot";
+      break;
+
+    case op_el_or_not:
+      retval = "ornot";
+      break;
+
+    case op_el_not_and:
+      retval = "notand";
+      break;
+
+    case op_el_not_or:
+      retval = "notor";
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+std::string
+octave_value::assign_op_as_string (assign_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case op_asn_eq:
+      retval = "=";
+      break;
+
+    case op_add_eq:
+      retval = "+=";
+      break;
+
+    case op_sub_eq:
+      retval = "-=";
+      break;
+
+    case op_mul_eq:
+      retval = "*=";
+      break;
+
+    case op_div_eq:
+      retval = "/=";
+      break;
+
+    case op_ldiv_eq:
+      retval = "\\=";
+      break;
+
+    case op_pow_eq:
+      retval = "^=";
+      break;
+
+    case op_lshift_eq:
+      retval = "<<=";
+      break;
+
+    case op_rshift_eq:
+      retval = ">>=";
+      break;
+
+    case op_el_mul_eq:
+      retval = ".*=";
+      break;
+
+    case op_el_div_eq:
+      retval = "./=";
+      break;
+
+    case op_el_ldiv_eq:
+      retval = ".\\=";
+      break;
+
+    case op_el_pow_eq:
+      retval = ".^=";
+      break;
+
+    case op_el_and_eq:
+      retval = "&=";
+      break;
+
+    case op_el_or_eq:
+      retval = "|=";
+      break;
+
+    default:
+      retval = "<unknown>";
+    }
+
+  return retval;
+}
+
+octave_value::octave_value (short int i)
+  : rep (new octave_scalar (i))
+{
+}
+
+octave_value::octave_value (unsigned short int i)
+  : rep (new octave_scalar (i))
+{
+}
+
+octave_value::octave_value (int i)
+  : rep (new octave_scalar (i))
+{
+}
+
+octave_value::octave_value (unsigned int i)
+  : rep (new octave_scalar (i))
+{
+}
+
+octave_value::octave_value (long int i)
+  : rep (new octave_scalar (i))
+{
+}
+
+octave_value::octave_value (unsigned long int i)
+  : rep (new octave_scalar (i))
+{
+}
+
+#if defined (HAVE_LONG_LONG_INT)
+octave_value::octave_value (long long int i)
+  : rep (new octave_scalar (i))
+{
+}
+#endif
+
+#if defined (HAVE_UNSIGNED_LONG_LONG_INT)
+octave_value::octave_value (unsigned long long int i)
+  : rep (new octave_scalar (i))
+{
+}
+#endif
+
+octave_value::octave_value (octave_time t)
+  : rep (new octave_scalar (t.double_value ()))
+{
+}
+
+octave_value::octave_value (double d)
+  : rep (new octave_scalar (d))
+{
+}
+
+octave_value::octave_value (float d)
+  : rep (new octave_float_scalar (d))
+{
+}
+
+octave_value::octave_value (const Cell& c, bool is_csl)
+  : rep (is_csl
+	 ? dynamic_cast<octave_base_value *> (new octave_cs_list (c))
+	 : dynamic_cast<octave_base_value *> (new octave_cell (c)))
+{
+}
+
+octave_value::octave_value (const ArrayN<octave_value>& a, bool is_csl)
+  : rep (is_csl
+	 ? dynamic_cast<octave_base_value *> (new octave_cs_list (Cell (a)))
+	 : dynamic_cast<octave_base_value *> (new octave_cell (Cell (a))))
+{
+}
+
+octave_value::octave_value (const Matrix& m, const MatrixType& t)
+  : rep (new octave_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatMatrix& m, const MatrixType& t)
+  : rep (new octave_float_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const NDArray& a)
+  : rep (new octave_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatNDArray& a)
+  : rep (new octave_float_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<double>& a)
+  : rep (new octave_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<float>& a)
+  : rep (new octave_float_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const DiagMatrix& d)
+  : rep (new octave_diag_matrix (d))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatDiagMatrix& d)
+  : rep (new octave_float_diag_matrix (d))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const RowVector& v)
+  : rep (new octave_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatRowVector& v)
+  : rep (new octave_float_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ColumnVector& v)
+  : rep (new octave_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatColumnVector& v)
+  : rep (new octave_float_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const Complex& C)
+  : rep (new octave_complex (C))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatComplex& C)
+  : rep (new octave_float_complex (C))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ComplexMatrix& m, const MatrixType& t)
+  : rep (new octave_complex_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatComplexMatrix& m, const MatrixType& t)
+  : rep (new octave_float_complex_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ComplexNDArray& a)
+  : rep (new octave_complex_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatComplexNDArray& a)
+  : rep (new octave_float_complex_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<Complex>& a)
+  : rep (new octave_complex_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<FloatComplex>& a)
+  : rep (new octave_float_complex_matrix (a))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ComplexDiagMatrix& d)
+  : rep (new octave_complex_diag_matrix (d))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatComplexDiagMatrix& d)
+  : rep (new octave_float_complex_diag_matrix (d))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ComplexRowVector& v)
+  : rep (new octave_complex_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatComplexRowVector& v)
+  : rep (new octave_float_complex_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ComplexColumnVector& v)
+  : rep (new octave_complex_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const FloatComplexColumnVector& v)
+  : rep (new octave_float_complex_matrix (v))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const PermMatrix& p)
+  : rep (new octave_perm_matrix (p))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (bool b)
+  : rep (new octave_bool (b))
+{
+}
+
+octave_value::octave_value (const boolMatrix& bm, const MatrixType& t)
+  : rep (new octave_bool_matrix (bm, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const boolNDArray& bnda)
+  : rep (new octave_bool_matrix (bnda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<bool>& bnda)
+  : rep (new octave_bool_matrix (bnda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (char c, char type)
+  : rep (type == '"'
+	 ? new octave_char_matrix_dq_str (c)
+	 : new octave_char_matrix_sq_str (c))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const char *s, char type)
+  : rep (type == '"'
+	 ? new octave_char_matrix_dq_str (s)
+	 : new octave_char_matrix_sq_str (s))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const std::string& s, char type)
+  : rep (type == '"'
+	 ? new octave_char_matrix_dq_str (s)
+	 : new octave_char_matrix_sq_str (s))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const string_vector& s, char type)
+  : rep (type == '"'
+	 ? new octave_char_matrix_dq_str (s)
+	 : new octave_char_matrix_sq_str (s))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const charMatrix& chm, bool is_str, char type)
+  : rep (is_str
+	 ? (type == '"'
+	    ? new octave_char_matrix_dq_str (chm)
+	    : new octave_char_matrix_sq_str (chm))
+	 : new octave_char_matrix (chm))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const charNDArray& chm, bool is_str, char type)
+  : rep (is_str
+	 ? (type == '"'
+	    ? new octave_char_matrix_dq_str (chm)
+	    : new octave_char_matrix_sq_str (chm))
+	 : new octave_char_matrix (chm))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<char>& chm, bool is_str, char type)
+  : rep (is_str
+	 ? (type == '"'
+	    ? new octave_char_matrix_dq_str (chm)
+	    : new octave_char_matrix_sq_str (chm))
+	 : new octave_char_matrix (chm))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const SparseMatrix& m, const MatrixType &t)
+  : rep (new octave_sparse_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const Sparse<double>& m, const MatrixType &t)
+  : rep (new octave_sparse_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const SparseComplexMatrix& m, const MatrixType &t)
+  : rep (new octave_sparse_complex_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const Sparse<Complex>& m, const MatrixType &t)
+  : rep (new octave_sparse_complex_matrix (m, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const SparseBoolMatrix& bm, const MatrixType &t)
+  : rep (new octave_sparse_bool_matrix (bm, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const Sparse<bool>& bm, const MatrixType &t)
+  : rep (new octave_sparse_bool_matrix (bm, t))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_int8& i)
+  : rep (new octave_int8_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_uint8& i)
+  : rep (new octave_uint8_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_int16& i)
+  : rep (new octave_int16_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_uint16& i)
+  : rep (new octave_uint16_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_int32& i)
+  : rep (new octave_int32_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_uint32& i)
+  : rep (new octave_uint32_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_int64& i)
+  : rep (new octave_int64_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave_uint64& i)
+  : rep (new octave_uint64_scalar (i))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const int8NDArray& inda)
+  : rep (new octave_int8_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_int8>& inda)
+  : rep (new octave_int8_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const uint8NDArray& inda)
+  : rep (new octave_uint8_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_uint8>& inda)
+  : rep (new octave_uint8_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const int16NDArray& inda)
+  : rep (new octave_int16_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_int16>& inda)
+  : rep (new octave_int16_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const uint16NDArray& inda)
+  : rep (new octave_uint16_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_uint16>& inda)
+  : rep (new octave_uint16_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const int32NDArray& inda)
+  : rep (new octave_int32_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_int32>& inda)
+  : rep (new octave_int32_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const uint32NDArray& inda)
+  : rep (new octave_uint32_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_uint32>& inda)
+  : rep (new octave_uint32_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const int64NDArray& inda)
+  : rep (new octave_int64_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_int64>& inda)
+  : rep (new octave_int64_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const uint64NDArray& inda)
+  : rep (new octave_uint64_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const ArrayN<octave_uint64>& inda)
+  : rep (new octave_uint64_matrix (inda))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (double base, double limit, double inc)
+  : rep (new octave_range (base, limit, inc))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const Range& r)
+  : rep (new octave_range (r))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const Octave_map& m)
+  : rep (new octave_struct (m))
+{
+}
+
+octave_value::octave_value (const Octave_map& m, const std::string& id)
+  : rep (new octave_class (m, id))
+{
+}
+
+octave_value::octave_value (const octave_value_list& l, bool is_csl)
+  : rep (is_csl
+	 ? dynamic_cast<octave_base_value *> (new octave_cs_list (l))
+	 : dynamic_cast<octave_base_value *> (new octave_list (l)))
+{
+}
+
+octave_value::octave_value (octave_value::magic_colon)
+  : rep (new octave_magic_colon ())
+{
+}
+
+octave_value::octave_value (octave_base_value *new_rep)
+  : rep (new_rep)
+{
+}
+
+octave_value::octave_value (octave_base_value *new_rep, int xcount)
+  : rep (new_rep)
+{
+  rep->count = xcount;
+}
+
+octave_base_value *
+octave_value::clone (void) const
+{
+  panic_impossible ();
+  return 0;
+}
+
+void
+octave_value::maybe_mutate (void)
+{
+  octave_base_value *tmp = rep->try_narrowing_conversion ();
+
+  if (tmp && tmp != rep)
+    {
+      if (--rep->count == 0)
+	delete rep;
+
+      rep = tmp;
+    }    
+}
+
+octave_value
+octave_value::single_subsref (const std::string& type,
+			      const octave_value_list& idx)
+{
+  std::list<octave_value_list> i;
+
+  i.push_back (idx);
+
+  return rep->subsref (type, i);
+}
+
+octave_value_list
+octave_value::subsref (const std::string& type,
+		       const std::list<octave_value_list>& idx, int nargout)
+{
+  if (nargout == 1)
+    return rep->subsref (type, idx);
+  else
+    return rep->subsref (type, idx, nargout);
+}
+
+octave_value
+octave_value::next_subsref (const std::string& type,
+			    const std::list<octave_value_list>& idx,
+			    size_t skip) 
+{
+  if (! error_state && idx.size () > skip)
+    {
+      std::list<octave_value_list> new_idx (idx);
+      for (size_t i = 0; i < skip; i++)
+	new_idx.erase (new_idx.begin ());
+      return subsref (type.substr (skip), new_idx);
+    }
+  else
+    return *this;
+}
+
+octave_value_list
+octave_value::next_subsref (int nargout, const std::string& type,
+			    const std::list<octave_value_list>& idx,
+			    size_t skip) 
+{
+  if (! error_state && idx.size () > skip)
+    {
+      std::list<octave_value_list> new_idx (idx);
+      for (size_t i = 0; i < skip; i++)
+	new_idx.erase (new_idx.begin ());
+      return subsref (type.substr (skip), new_idx, nargout);
+    }
+  else
+    return *this;
+}
+
+octave_value
+octave_value::next_subsref (bool auto_add, const std::string& type,
+			    const std::list<octave_value_list>& idx,
+			    size_t skip) 
+{
+  if (! error_state && idx.size () > skip)
+    {
+      std::list<octave_value_list> new_idx (idx);
+      for (size_t i = 0; i < skip; i++)
+	new_idx.erase (new_idx.begin ());
+      return subsref (type.substr (skip), new_idx, auto_add);
+    }
+  else
+    return *this;
+}
+
+octave_value_list
+octave_value::do_multi_index_op (int nargout, const octave_value_list& idx)
+{
+  return rep->do_multi_index_op (nargout, idx);
+}
+
+#if 0
+static void
+gripe_assign_failed (const std::string& on, const std::string& tn1,
+		     const std::string& tn2)
+{
+  error ("assignment failed for `%s %s %s'",
+	 tn1.c_str (), on.c_str (), tn2.c_str ());
+}
+#endif
+
+static void
+gripe_assign_failed_or_no_method (const std::string& on,
+				  const std::string& tn1,
+				  const std::string& tn2)
+{
+  error ("assignment failed, or no method for `%s %s %s'",
+	 tn1.c_str (), on.c_str (), tn2.c_str ());
+}
+
+octave_value
+octave_value::subsasgn (const std::string& type,
+			const std::list<octave_value_list>& idx,
+			const octave_value& rhs)
+{
+  return rep->subsasgn (type, idx, rhs);
+}
+
+octave_value
+octave_value::assign (assign_op op, const std::string& type,
+		      const std::list<octave_value_list>& idx,
+		      const octave_value& rhs)
+{
+  octave_value retval;
+
+  make_unique ();
+
+  octave_value t_rhs = rhs;
+
+  if (op != op_asn_eq)
+    {
+      // FIXME -- only do the following stuff if we can't find
+      // a specific function to call to handle the op= operation for
+      // the types we have.
+
+      octave_value t = subsref (type, idx);
+
+      if (! error_state)
+	{
+	  binary_op binop = op_eq_to_binary_op (op);
+
+	  if (! error_state)
+	    t_rhs = do_binary_op (binop, t, rhs);
+	}
+    }
+
+  if (! error_state)
+    {
+      if (type[0] == '.' && ! (is_map () || is_object ()))
+	{
+	  octave_value tmp = Octave_map ();
+	  retval = tmp.subsasgn (type, idx, t_rhs);
+	}
+      else
+	retval = subsasgn (type, idx, t_rhs);
+    }
+
+  if (error_state)
+    gripe_assign_failed_or_no_method (assign_op_as_string (op),
+				      type_name (), rhs.type_name ());
+
+  return retval;
+}
+
+const octave_value&
+octave_value::assign (assign_op op, const octave_value& rhs)
+{
+  if (op == op_asn_eq)
+    // Regularize a null matrix if stored into a variable.
+    operator = (rhs.storable_value ());
+  else
+    {
+      // FIXME -- only do the following stuff if we can't find
+      // a specific function to call to handle the op= operation for
+      // the types we have.
+
+      binary_op binop = op_eq_to_binary_op (op);
+
+      if (! error_state)
+	{
+	  octave_value t = do_binary_op (binop, *this, rhs);
+
+	  if (! error_state)
+	    operator = (t);
+	}
+
+      if (error_state)
+	gripe_assign_failed_or_no_method (assign_op_as_string (op),
+					  type_name (), rhs.type_name ());
+    }
+
+  return *this;
+}
+
+octave_idx_type
+octave_value::length (void) const
+{
+  int retval = 0;
+
+  dim_vector dv = dims ();
+
+  for (int i = 0; i < dv.length (); i++)
+    {
+      if (dv(i) < 0)
+	{
+	  retval = -1;
+	  break;
+	}
+
+      if (dv(i) == 0)
+	{
+	  retval = 0;
+	  break;
+	}
+
+      if (dv(i) > retval)
+	retval = dv(i);
+    }
+
+  return retval;
+}
+
+Matrix
+octave_value::size (void) const
+{
+  dim_vector dv = dims ();
+
+  int n_dims = dv.length ();
+
+  Matrix retval (1, n_dims);
+
+  while (n_dims--)
+    retval(n_dims) = dv(n_dims);
+
+  return retval;
+}
+
+bool
+octave_value::is_equal (const octave_value& test) const
+{
+  bool retval = false;
+
+  // If there is no op_eq for these types, we can't compare values.
+
+  if (rows () == test.rows () && columns () == test.columns ())
+    {
+      octave_value tmp = do_binary_op (octave_value::op_eq, *this, test);
+
+      // Empty array also means a match.
+      if (! error_state && tmp.is_defined ())
+	retval = tmp.is_true () || tmp.is_empty ();
+    }
+
+  return retval;
+}
+
+Cell
+octave_value::cell_value (void) const
+{
+  return rep->cell_value ();
+}
+
+// Define the idx_type_value function here instead of in ov.h to avoid
+// needing definitions for the SIZEOF_X macros in ov.h.
+
+octave_idx_type
+octave_value::idx_type_value (bool req_int, bool frc_str_conv) const
+{
+#if SIZEOF_OCTAVE_IDX_TYPE == SIZEOF_LONG
+  return long_value (req_int, frc_str_conv);
+#elif SIZEOF_OCTAVE_IDX_TYPE == SIZEOF_INT
+  return int_value (req_int, frc_str_conv);
+#else
+#error "no octave_value extractor for octave_idx_type"
+#endif
+}
+
+Octave_map
+octave_value::map_value (void) const
+{
+  return rep->map_value ();
+}
+
+octave_function *
+octave_value::function_value (bool silent)
+{
+  return rep->function_value (silent);
+}
+
+const octave_function *
+octave_value::function_value (bool silent) const
+{
+  return rep->function_value (silent);
+}
+
+octave_user_function *
+octave_value::user_function_value (bool silent)
+{
+  return rep->user_function_value (silent);
+}
+
+octave_user_script *
+octave_value::user_script_value (bool silent)
+{
+  return rep->user_script_value (silent);
+}
+
+octave_user_code *
+octave_value::user_code_value (bool silent)
+{
+  return rep->user_code_value (silent);
+}
+
+octave_fcn_handle *
+octave_value::fcn_handle_value (bool silent)
+{
+  return rep->fcn_handle_value (silent);
+}
+
+octave_fcn_inline *
+octave_value::fcn_inline_value (bool silent)
+{
+  return rep->fcn_inline_value (silent);
+}
+
+octave_value_list
+octave_value::list_value (void) const
+{
+  return rep->list_value ();
+}
+
+static dim_vector
+make_vector_dims (const dim_vector& dv, bool force_vector_conversion,
+                  const std::string& my_type, const std::string& wanted_type)
+{
+  dim_vector retval (dv);
+  retval.chop_trailing_singletons ();
+  octave_idx_type nel = dv.numel ();
+
+  if (retval.length () > 2 || (retval(0) != 1 && retval(1) != 1))
+    {
+      if (!force_vector_conversion)
+        gripe_implicit_conversion ("Octave:array-as-vector",
+                                   my_type.c_str (), wanted_type.c_str ());
+      retval = dim_vector (nel);
+    }
+
+  return retval;
+}
+
+ColumnVector
+octave_value::column_vector_value (bool force_string_conv,
+                                   bool frc_vec_conv) const
+{
+  return ColumnVector (vector_value (force_string_conv, 
+                                     frc_vec_conv));
+}
+
+ComplexColumnVector
+octave_value::complex_column_vector_value (bool force_string_conv,
+                                           bool frc_vec_conv) const
+{
+  return ComplexColumnVector (complex_vector_value (force_string_conv, 
+                                                    frc_vec_conv));
+}
+
+RowVector
+octave_value::row_vector_value (bool force_string_conv,
+                                bool frc_vec_conv) const
+{
+  return RowVector (vector_value (force_string_conv, 
+                                  frc_vec_conv));
+}
+
+ComplexRowVector
+octave_value::complex_row_vector_value (bool force_string_conv,
+                                        bool frc_vec_conv) const
+{
+  return ComplexRowVector (complex_vector_value (force_string_conv, 
+                                                 frc_vec_conv));
+}
+
+Array<double>
+octave_value::vector_value (bool force_string_conv,
+			    bool force_vector_conversion) const
+{
+  Array<double> retval = array_value (force_string_conv);
+
+  if (error_state)
+    return retval;
+  else
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "real vector"));
+}
+
+template <class T>
+static Array<int>
+convert_to_int_array (const Array<octave_int<T> >& A)
+{
+  Array<int> retval (A.dims ());
+  octave_idx_type n = A.numel ();
+
+  octave_int<int>::clear_conv_flag ();
+  for (octave_idx_type i = 0; i < n; i++)
+    retval.xelem (i) = octave_int<int> (A.xelem (i));
+
+  if (octave_int<int>::get_trunc_flag ())
+    gripe_truncated_conversion (octave_int<T>::type_name (), "int");
+
+  octave_int<int>::clear_conv_flag ();
+
+  return retval;
+}
+
+Array<int>
+octave_value::int_vector_value (bool force_string_conv, bool require_int,
+				bool force_vector_conversion) const
+{
+  Array<int> retval;
+
+  if (is_integer_type ())
+    {
+      if (is_int32_type ())
+        retval = convert_to_int_array (int32_array_value ());
+      else if (is_int64_type ())
+        retval = convert_to_int_array (int64_array_value ());
+      else if (is_int16_type ())
+        retval = convert_to_int_array (int16_array_value ());
+      else if (is_int8_type ())
+        retval = convert_to_int_array (int8_array_value ());
+      else if (is_uint32_type ())
+        retval = convert_to_int_array (uint32_array_value ());
+      else if (is_uint64_type ())
+        retval = convert_to_int_array (uint64_array_value ());
+      else if (is_uint16_type ())
+        retval = convert_to_int_array (uint16_array_value ());
+      else if (is_uint8_type ())
+        retval = convert_to_int_array (uint8_array_value ());
+      else
+        retval = array_value (force_string_conv);
+    }
+  else 
+    {
+      const NDArray a = array_value (force_string_conv);
+      if (! error_state)
+        {
+          if (require_int)
+            {
+              retval.resize (a.dims ());
+              for (octave_idx_type i = 0; i < a.numel (); i++)
+                {
+                  double ai = a.elem (i);
+                  int v = static_cast<int> (ai);
+                  if (ai == v)
+                    retval.xelem (i) = v;
+                  else
+                    {
+                      error ("conversion to integer value failed");
+                      break;
+                    }
+                }
+            }
+          else
+            retval = Array<int> (a);
+        }
+    }
+
+
+  if (error_state)
+    return retval;
+  else
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "integer vector"));
+}
+
+template <class T>
+static Array<octave_idx_type>
+convert_to_octave_idx_type_array (const Array<octave_int<T> >& A)
+{
+  Array<octave_idx_type> retval (A.dims ());
+  octave_idx_type n = A.numel ();
+
+  octave_int<int>::clear_conv_flag ();
+  for (octave_idx_type i = 0; i < n; i++)
+    retval.xelem (i) = octave_int<octave_idx_type> (A.xelem (i));
+
+  if (octave_int<int>::get_trunc_flag ())
+    gripe_truncated_conversion (octave_int<T>::type_name (), "int");
+
+  octave_int<int>::clear_conv_flag ();
+
+  return retval;
+}
+
+Array<octave_idx_type>
+octave_value::octave_idx_type_vector_value (bool force_string_conv,
+					    bool require_int,
+					    bool force_vector_conversion) const
+{
+  Array<octave_idx_type> retval;
+
+  if (is_integer_type ())
+    {
+      if (is_int32_type ())
+        retval = convert_to_octave_idx_type_array (int32_array_value ());
+      else if (is_int64_type ())
+        retval = convert_to_octave_idx_type_array (int64_array_value ());
+      else if (is_int16_type ())
+        retval = convert_to_octave_idx_type_array (int16_array_value ());
+      else if (is_int8_type ())
+        retval = convert_to_octave_idx_type_array (int8_array_value ());
+      else if (is_uint32_type ())
+        retval = convert_to_octave_idx_type_array (uint32_array_value ());
+      else if (is_uint64_type ())
+        retval = convert_to_octave_idx_type_array (uint64_array_value ());
+      else if (is_uint16_type ())
+        retval = convert_to_octave_idx_type_array (uint16_array_value ());
+      else if (is_uint8_type ())
+        retval = convert_to_octave_idx_type_array (uint8_array_value ());
+      else
+        retval = array_value (force_string_conv);
+    }
+  else 
+    {
+      const NDArray a = array_value (force_string_conv);
+      if (! error_state)
+        {
+          if (require_int)
+            {
+              retval.resize (a.dims ());
+              for (octave_idx_type i = 0; i < a.numel (); i++)
+                {
+                  double ai = a.elem (i);
+                  octave_idx_type v = static_cast<octave_idx_type> (ai);
+                  if (ai == v)
+                    retval.xelem (i) = v;
+                  else
+                    {
+                      error ("conversion to integer value failed");
+                      break;
+                    }
+                }
+            }
+          else
+            retval = Array<octave_idx_type> (a);
+        }
+    }
+
+
+  if (error_state)
+    return retval;
+  else
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "integer vector"));
+}
+
+Array<Complex>
+octave_value::complex_vector_value (bool force_string_conv,
+                                    bool force_vector_conversion) const
+{
+  Array<Complex> retval = complex_array_value (force_string_conv);
+
+  if (error_state)
+    return retval;
+  else
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "complex vector"));
+}
+
+FloatColumnVector
+octave_value::float_column_vector_value (bool force_string_conv,
+                                         bool frc_vec_conv) const
+{
+  return FloatColumnVector (float_vector_value (force_string_conv, 
+                                                frc_vec_conv));
+}
+
+FloatComplexColumnVector
+octave_value::float_complex_column_vector_value (bool force_string_conv,
+                                                 bool frc_vec_conv) const
+{
+  return FloatComplexColumnVector (float_complex_vector_value (force_string_conv, 
+                                                               frc_vec_conv));
+}
+
+FloatRowVector
+octave_value::float_row_vector_value (bool force_string_conv,
+                                      bool frc_vec_conv) const
+{
+  return FloatRowVector (float_vector_value (force_string_conv, 
+                                             frc_vec_conv));
+}
+
+FloatComplexRowVector
+octave_value::float_complex_row_vector_value (bool force_string_conv,
+                                              bool frc_vec_conv) const
+{
+  return FloatComplexRowVector (float_complex_vector_value (force_string_conv, 
+                                                           frc_vec_conv));
+}
+
+Array<float>
+octave_value::float_vector_value (bool force_string_conv,
+                                  bool force_vector_conversion) const
+{
+  Array<float> retval = float_array_value (force_string_conv);
+
+  if (error_state)
+    return retval;
+  else
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "real vector"));
+}
+
+Array<FloatComplex>
+octave_value::float_complex_vector_value (bool force_string_conv,
+                                          bool force_vector_conversion) const
+{
+  Array<FloatComplex> retval = float_complex_array_value (force_string_conv);
+
+  if (error_state)
+    return retval;
+  else
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "complex vector"));
+}
+
+octave_value 
+octave_value::storable_value (void) const
+{
+  octave_value retval = *this;
+  if (is_null_value ())
+    retval = octave_value (rep->empty_clone ());
+  else
+    retval.maybe_economize ();
+
+  return retval;
+}
+
+void 
+octave_value::make_storable_value (void) 
+{
+  if (is_null_value ())
+    {
+      octave_base_value *rc = rep->empty_clone ();
+      if (--rep->count == 0)
+        delete rep;
+      rep = rc;
+    }
+  else
+    maybe_economize ();
+}
+
+int
+octave_value::write (octave_stream& os, int block_size,
+		     oct_data_conv::data_type output_type, int skip,
+		     oct_mach_info::float_format flt_fmt) const
+{
+  return rep->write (os, block_size, output_type, skip, flt_fmt);
+}
+
+static void
+gripe_binary_op (const std::string& on, const std::string& tn1,
+		 const std::string& tn2)
+{
+  error ("binary operator `%s' not implemented for `%s' by `%s' operations",
+	 on.c_str (), tn1.c_str (), tn2.c_str ());
+}
+
+static void
+gripe_binary_op_conv (const std::string& on)
+{
+  error ("type conversion failed for binary operator `%s'", on.c_str ());
+}
+
+octave_value
+do_binary_op (octave_value::binary_op op,
+	      const octave_value& v1, const octave_value& v2)
+{
+  octave_value retval;
+
+  int t1 = v1.type_id ();
+  int t2 = v2.type_id ();
+
+  if (t1 == octave_class::static_type_id ()
+      || t2 == octave_class::static_type_id ())
+    {
+      octave_value_typeinfo::binary_class_op_fcn f
+	= octave_value_typeinfo::lookup_binary_class_op (op);
+
+      if (f)
+	{
+	  try
+	    {
+	      retval = f (v1, v2);
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      gripe_library_execution_error ();
+	    }
+	}	    
+      else
+	gripe_binary_op (octave_value::binary_op_as_string (op),
+			 v1.class_name (), v2.class_name ());
+    }
+  else
+    {
+      // FIXME -- we need to handle overloading operators for built-in
+      // classes (double, char, int8, etc.)
+
+      octave_value_typeinfo::binary_op_fcn f
+	= octave_value_typeinfo::lookup_binary_op (op, t1, t2);
+
+      if (f)
+	{
+	  try
+	    {
+	      retval = f (*v1.rep, *v2.rep);
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      gripe_library_execution_error ();
+	    }
+	}
+      else
+	{
+	  octave_value tv1;
+	  octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
+
+	  octave_value tv2;
+	  octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
+
+          // Try biased (one-sided) conversions first.
+          if (cf2.type_id () >= 0 &&
+              octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
+            cf1 = 0;
+          else if (cf1.type_id () >= 0 &&
+                   octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
+            cf2 = 0;
+
+	  if (cf1)
+	    {
+	      octave_base_value *tmp = cf1 (*v1.rep);
+
+	      if (tmp)
+		{
+		  tv1 = octave_value (tmp);
+		  t1 = tv1.type_id ();
+		}
+	      else
+		{
+		  gripe_binary_op_conv (octave_value::binary_op_as_string (op));
+		  return retval;
+		}
+	    }
+	  else
+	    tv1 = v1;
+
+	  if (cf2)
+	    {
+	      octave_base_value *tmp = cf2 (*v2.rep);
+
+	      if (tmp)
+		{
+		  tv2 = octave_value (tmp);
+		  t2 = tv2.type_id ();
+		}
+	      else
+		{
+		  gripe_binary_op_conv (octave_value::binary_op_as_string (op));
+		  return retval;
+		}
+	    }
+	  else
+	    tv2 = v2;
+
+	  if (cf1 || cf2)
+	    {
+              retval = do_binary_op (op, tv1, tv2);
+	    }
+	  else
+	    {
+	      //demote double -> single and try again
+	      cf1 = tv1.numeric_demotion_function ();
+
+	      cf2 = tv2.numeric_demotion_function ();
+
+              // Try biased (one-sided) conversions first.
+              if (cf2.type_id () >= 0
+                  && octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
+                cf1 = 0;
+              else if (cf1.type_id () >= 0
+                       && octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
+                cf2 = 0;
+
+	      if (cf1)
+		{
+		  octave_base_value *tmp = cf1 (*tv1.rep);
+
+		  if (tmp)
+		    {
+		      tv1 = octave_value (tmp);
+		      t1 = tv1.type_id ();
+		    }
+		  else
+		    {
+		      gripe_binary_op_conv (octave_value::binary_op_as_string (op));
+		      return retval;
+		    }
+		}
+
+	      if (cf2)
+		{
+		  octave_base_value *tmp = cf2 (*tv2.rep);
+
+		  if (tmp)
+		    {
+		      tv2 = octave_value (tmp);
+		      t2 = tv2.type_id ();
+		    }
+		  else
+		    {
+		      gripe_binary_op_conv (octave_value::binary_op_as_string (op));
+		      return retval;
+		    }
+		}
+
+	      if (cf1 || cf2)
+		{
+		  f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
+
+		  if (f)
+		    {
+		      try
+			{
+			  retval = f (*tv1.rep, *tv2.rep);
+			}
+		      catch (octave_execution_exception)
+			{
+			  gripe_library_execution_error ();
+			}
+		    }
+		  else
+		    gripe_binary_op (octave_value::binary_op_as_string (op),
+				     v1.type_name (), v2.type_name ());
+		}
+	      else
+		gripe_binary_op (octave_value::binary_op_as_string (op),
+				 v1.type_name (), v2.type_name ());
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static octave_value
+decompose_binary_op (octave_value::compound_binary_op op,
+                     const octave_value& v1, const octave_value& v2)
+{
+  octave_value retval;
+
+  switch (op)
+    {
+    case octave_value::op_trans_mul:
+      retval = do_binary_op (octave_value::op_mul,
+                             do_unary_op (octave_value::op_transpose, v1),
+                             v2);
+      break;
+    case octave_value::op_mul_trans:
+      retval = do_binary_op (octave_value::op_mul,
+                             v1,
+                             do_unary_op (octave_value::op_transpose, v2));
+      break;
+    case octave_value::op_herm_mul:
+      retval = do_binary_op (octave_value::op_mul,
+                             do_unary_op (octave_value::op_hermitian, v1),
+                             v2);
+      break;
+    case octave_value::op_mul_herm:
+      retval = do_binary_op (octave_value::op_mul,
+                             v1,
+                             do_unary_op (octave_value::op_hermitian, v2));
+      break;
+    case octave_value::op_el_not_and:
+      retval = do_binary_op (octave_value::op_el_and,
+                             do_unary_op (octave_value::op_not, v1),
+                             v2);
+      break;
+    case octave_value::op_el_not_or:
+      retval = do_binary_op (octave_value::op_el_or,
+                             do_unary_op (octave_value::op_not, v1),
+                             v2);
+      break;
+    case octave_value::op_el_and_not:
+      retval = do_binary_op (octave_value::op_el_and,
+                             v1,
+                             do_unary_op (octave_value::op_not, v2));
+      break;
+    case octave_value::op_el_or_not:
+      retval = do_binary_op (octave_value::op_el_or,
+                             v1,
+                             do_unary_op (octave_value::op_not, v2));
+      break;
+    default:
+      error ("invalid compound operator");
+      break;
+    }
+
+  return retval;
+}
+
+octave_value
+do_binary_op (octave_value::compound_binary_op op,
+              const octave_value& v1, const octave_value& v2)
+{
+  octave_value retval;
+
+  int t1 = v1.type_id ();
+  int t2 = v2.type_id ();
+
+  if (t1 == octave_class::static_type_id ()
+      || t2 == octave_class::static_type_id ())
+    {
+      octave_value_typeinfo::binary_class_op_fcn f
+	= octave_value_typeinfo::lookup_binary_class_op (op);
+
+      if (f)
+	{
+	  try
+	    {
+	      retval = f (v1, v2);
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      gripe_library_execution_error ();
+	    }
+	}	    
+      else
+        retval = decompose_binary_op (op, v1, v2);
+    }
+  else
+    {
+      octave_value_typeinfo::binary_op_fcn f
+	= octave_value_typeinfo::lookup_binary_op (op, t1, t2);
+
+      if (f)
+	{
+	  try
+	    {
+	      retval = f (*v1.rep, *v2.rep);
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      gripe_library_execution_error ();
+	    }
+	}
+      else
+        retval = decompose_binary_op (op, v1, v2);
+    }
+
+  return retval;
+}
+
+static void
+gripe_cat_op (const std::string& tn1, const std::string& tn2)
+{
+  error ("concatenation operator not implemented for `%s' by `%s' operations",
+	 tn1.c_str (), tn2.c_str ());
+}
+
+static void
+gripe_cat_op_conv (void)
+{
+  error ("type conversion failed for concatenation operator");
+}
+
+octave_value
+do_cat_op (const octave_value& v1, const octave_value& v2, 
+	   const Array<octave_idx_type>& ra_idx)
+{
+  octave_value retval;
+
+  // Can't rapid return for concatenation with an empty object here as
+  // something like cat(1,[],single([]) must return the correct type.
+
+  int t1 = v1.type_id ();
+  int t2 = v2.type_id ();
+
+  octave_value_typeinfo::cat_op_fcn f
+    = octave_value_typeinfo::lookup_cat_op (t1, t2);
+
+  if (f)
+    {
+      try
+	{
+	  retval = f (*v1.rep, *v2.rep, ra_idx);
+	}
+      catch (octave_execution_exception)
+	{
+	  gripe_library_execution_error ();
+	}
+    }
+  else
+    {
+      octave_value tv1;
+      octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
+
+      octave_value tv2;
+      octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
+
+      // Try biased (one-sided) conversions first.
+      if (cf2.type_id () >= 0
+          && octave_value_typeinfo::lookup_cat_op (t1, cf2.type_id ()))
+        cf1 = 0;
+      else if (cf1.type_id () >= 0
+               && octave_value_typeinfo::lookup_cat_op (cf1.type_id (), t2))
+        cf2 = 0;
+
+      if (cf1)
+	{
+	  octave_base_value *tmp = cf1 (*v1.rep);
+
+	  if (tmp)
+	    {
+	      tv1 = octave_value (tmp);
+	      t1 = tv1.type_id ();
+	    }
+	  else
+	    {
+	      gripe_cat_op_conv ();
+	      return retval;
+	    }
+	}
+      else
+	tv1 = v1;
+
+      if (cf2)
+	{
+	  octave_base_value *tmp = cf2 (*v2.rep);
+
+	  if (tmp)
+	    {
+	      tv2 = octave_value (tmp);
+	      t2 = tv2.type_id ();
+	    }
+	  else
+	    {
+	      gripe_cat_op_conv ();
+	      return retval;
+	    }
+	}
+      else
+	tv2 = v2;
+
+      if (cf1 || cf2)
+	{
+          retval = do_cat_op (tv1, tv2, ra_idx);
+	}
+      else
+	gripe_cat_op (v1.type_name (), v2.type_name ());
+    }
+
+  return retval;
+}
+
+void
+octave_value::print_info (std::ostream& os, const std::string& prefix) const
+{
+  os << prefix << "type_name: " << type_name () << "\n"
+     << prefix << "count:     " << get_count () << "\n"
+     << prefix << "rep info:  ";
+
+  rep->print_info (os, prefix + " ");
+}
+
+static void
+gripe_unary_op (const std::string& on, const std::string& tn)
+{
+  error ("unary operator `%s' not implemented for `%s' operands",
+	 on.c_str (), tn.c_str ());
+}
+
+static void
+gripe_unary_op_conv (const std::string& on)
+{
+  error ("type conversion failed for unary operator `%s'", on.c_str ());
+}
+
+octave_value
+do_unary_op (octave_value::unary_op op, const octave_value& v)
+{
+  octave_value retval;
+
+  int t = v.type_id ();
+
+  if (t == octave_class::static_type_id ())
+    {
+      octave_value_typeinfo::unary_class_op_fcn f
+	= octave_value_typeinfo::lookup_unary_class_op (op);
+
+      if (f)
+	{
+	  try
+	    {
+	      retval = f (v);
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      gripe_library_execution_error ();
+	    }
+	}
+      else
+	gripe_unary_op (octave_value::unary_op_as_string (op),
+			v.class_name ());
+    }
+  else
+    {
+      // FIXME -- we need to handle overloading operators for built-in
+      // classes (double, char, int8, etc.)
+
+      octave_value_typeinfo::unary_op_fcn f
+	= octave_value_typeinfo::lookup_unary_op (op, t);
+
+      if (f)
+	{
+	  try
+	    {
+	      retval = f (*v.rep);
+	    }
+	  catch (octave_execution_exception)
+	    {
+	      gripe_library_execution_error ();
+	    }
+	}
+      else
+	{
+	  octave_value tv;
+	  octave_base_value::type_conv_fcn cf
+	    = v.numeric_conversion_function ();
+
+	  if (cf)
+	    {
+	      octave_base_value *tmp = cf (*v.rep);
+
+	      if (tmp)
+		{
+		  tv = octave_value (tmp);
+                  retval = do_unary_op (op, tv);
+		}
+	      else
+		gripe_unary_op_conv (octave_value::unary_op_as_string (op));
+	    }
+	  else
+	    gripe_unary_op (octave_value::unary_op_as_string (op),
+			    v.type_name ());
+	}
+    }
+
+  return retval;
+}
+
+static void
+gripe_unary_op_conversion_failed (const std::string& op,
+				  const std::string& tn)
+{
+  error ("operator %s: type conversion for `%s' failed",
+	 op.c_str (), tn.c_str ());
+}
+
+const octave_value&
+octave_value::do_non_const_unary_op (unary_op op)
+{
+  octave_value retval;
+
+  int t = type_id ();
+
+  octave_value_typeinfo::non_const_unary_op_fcn f
+    = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
+
+  if (f)
+    {
+      make_unique ();
+
+      try
+	{
+	  f (*rep);
+	}
+      catch (octave_execution_exception)
+	{
+	  gripe_library_execution_error ();
+	}
+    }
+  else
+    {
+      octave_base_value::type_conv_fcn cf = numeric_conversion_function ();
+
+      if (cf)
+	{
+	  octave_base_value *tmp = cf (*rep);
+
+	  if (tmp)
+	    {
+	      octave_base_value *old_rep = rep;
+	      rep = tmp;
+
+	      t = type_id ();
+
+	      f = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
+
+	      if (f)
+		{
+		  try
+		    {
+		      f (*rep);
+		    }
+		  catch (octave_execution_exception)
+		    {
+		      gripe_library_execution_error ();
+		    }
+
+		  if (old_rep && --old_rep->count == 0)
+		    delete old_rep;
+		}
+	      else
+		{
+		  if (old_rep)
+		    {
+		      if (--rep->count == 0)
+			delete rep;
+
+		      rep = old_rep;
+		    }
+
+		  gripe_unary_op (octave_value::unary_op_as_string (op),
+				  type_name ());
+		}
+	    }
+	  else
+	    gripe_unary_op_conversion_failed
+	      (octave_value::unary_op_as_string (op), type_name ());
+	}
+      else
+	gripe_unary_op (octave_value::unary_op_as_string (op), type_name ());
+    }
+
+  return *this;
+}
+
+#if 0
+static void
+gripe_unary_op_failed_or_no_method (const std::string& on,
+				    const std::string& tn) 
+{
+  error ("operator %s: no method, or unable to evaluate for %s operand",
+	 on.c_str (), tn.c_str ());
+}
+#endif
+
+void
+octave_value::do_non_const_unary_op (unary_op, const octave_value_list&)
+{
+  abort ();
+}
+
+octave_value
+octave_value::do_non_const_unary_op (unary_op op, const std::string& type,
+				     const std::list<octave_value_list>& idx)
+{
+  octave_value retval;
+
+  if (idx.empty ())
+    {
+      do_non_const_unary_op (op);
+
+      retval = *this;
+    }
+  else
+    {
+      // FIXME -- only do the following stuff if we can't find a
+      // specific function to call to handle the op= operation for the
+      // types we have.
+
+      assign_op assop = unary_op_to_assign_op (op);
+
+      retval = assign (assop, type, idx, 1.0);
+    }
+
+  return retval;
+}
+
+octave_value::assign_op
+octave_value::unary_op_to_assign_op (unary_op op)
+{
+  assign_op binop = unknown_assign_op;
+
+  switch (op)
+    {
+    case op_incr:
+      binop = op_add_eq;
+      break;
+
+    case op_decr:
+      binop = op_sub_eq;
+      break;
+
+    default:
+      {
+	std::string on = unary_op_as_string (op);
+	error ("operator %s: no assign operator found", on.c_str ());
+      }
+    }
+
+  return binop;
+}
+
+octave_value::binary_op 
+octave_value::op_eq_to_binary_op (assign_op op)
+{
+  binary_op binop = unknown_binary_op;
+
+  switch (op)
+    {
+    case op_add_eq:
+      binop = op_add;
+      break;
+
+    case op_sub_eq:
+      binop = op_sub;
+      break;
+
+    case op_mul_eq:
+      binop = op_mul;
+      break;
+
+    case op_div_eq:
+      binop = op_div;
+      break;
+
+    case op_ldiv_eq:
+      binop = op_ldiv;
+      break;
+
+    case op_pow_eq:
+      binop = op_pow;
+      break;
+
+    case op_lshift_eq:
+      binop = op_lshift;
+      break;
+
+    case op_rshift_eq:
+      binop = op_rshift;
+      break;
+
+    case op_el_mul_eq:
+      binop = op_el_mul;
+      break;
+
+    case op_el_div_eq:
+      binop = op_el_div;
+      break;
+
+    case op_el_ldiv_eq:
+      binop = op_el_ldiv;
+      break;
+
+    case op_el_pow_eq:
+      binop = op_el_pow;
+      break;
+
+    case op_el_and_eq:
+      binop = op_el_and;
+      break;
+
+    case op_el_or_eq:
+      binop = op_el_or;
+      break;
+
+    default:
+      {
+	std::string on = assign_op_as_string (op);
+	error ("operator %s: no binary operator found", on.c_str ());
+      }
+    }
+
+  return binop;
+}
+
+octave_value
+octave_value::empty_conv (const std::string& type, const octave_value& rhs)
+{
+  octave_value retval;
+
+  if (type.length () > 0)
+    {
+      switch (type[0])
+	{
+	case '(':
+	  {
+	    if (type.length () > 1 && type[1] == '.')
+	      retval = Octave_map ();
+	    else
+	      retval = octave_value (rhs.empty_clone ());
+	  }
+	  break;
+
+	case '{':
+	  retval = Cell ();
+	  break;
+
+	case '.':
+	  retval = Octave_map ();
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+    }
+  else
+    retval = octave_value (rhs.empty_clone ());
+
+  return retval;
+}
+
+void
+install_types (void)
+{
+  octave_base_value::register_type ();
+  octave_cell::register_type ();
+  octave_scalar::register_type ();
+  octave_complex::register_type ();
+  octave_matrix::register_type ();
+  octave_diag_matrix::register_type ();
+  octave_complex_matrix::register_type ();
+  octave_complex_diag_matrix::register_type ();
+  octave_range::register_type ();
+  octave_bool::register_type ();
+  octave_bool_matrix::register_type ();
+  octave_char_matrix::register_type ();
+  octave_char_matrix_str::register_type ();
+  octave_char_matrix_sq_str::register_type ();
+  octave_int8_scalar::register_type ();
+  octave_int16_scalar::register_type ();
+  octave_int32_scalar::register_type ();
+  octave_int64_scalar::register_type ();
+  octave_uint8_scalar::register_type ();
+  octave_uint16_scalar::register_type ();
+  octave_uint32_scalar::register_type ();
+  octave_uint64_scalar::register_type ();
+  octave_int8_matrix::register_type ();
+  octave_int16_matrix::register_type ();
+  octave_int32_matrix::register_type ();
+  octave_int64_matrix::register_type ();
+  octave_uint8_matrix::register_type ();
+  octave_uint16_matrix::register_type ();
+  octave_uint32_matrix::register_type ();
+  octave_uint64_matrix::register_type ();
+  octave_sparse_bool_matrix::register_type ();
+  octave_sparse_matrix::register_type ();
+  octave_sparse_complex_matrix::register_type ();
+  octave_struct::register_type ();
+  octave_class::register_type ();
+  octave_list::register_type ();
+  octave_cs_list::register_type ();
+  octave_magic_colon::register_type ();
+  octave_builtin::register_type ();
+  octave_user_function::register_type ();
+  octave_dld_function::register_type ();
+  octave_fcn_handle::register_type ();
+  octave_fcn_inline::register_type ();
+  octave_float_scalar::register_type ();
+  octave_float_complex::register_type ();
+  octave_float_matrix::register_type ();
+  octave_float_diag_matrix::register_type ();
+  octave_float_complex_matrix::register_type ();
+  octave_float_complex_diag_matrix::register_type ();
+  octave_perm_matrix::register_type ();
+  octave_null_matrix::register_type ();
+  octave_null_str::register_type ();
+  octave_null_sq_str::register_type ();
+}
+
+#if 0
+DEFUN (cast, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} cast (@var{val}, @var{type})\n\
+Convert @var{val} to the new data type @var{type}.\n\
+ at seealso{class, typeinfo}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    error ("cast: not implemented");
+  else
+    print_usage ();
+
+  return retval;
+}
+#endif
+
+DEFUN (sizeof, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} sizeof (@var{val})\n\
+Return the size of @var{val} in bytes\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).byte_size ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static void
+decode_subscripts (const char* name, const octave_value& arg,
+		   std::string& type_string,
+		   std::list<octave_value_list>& idx)
+{
+  Octave_map m = arg.map_value ();
+
+  if (! error_state
+      && m.nfields () == 2 && m.contains ("type") && m.contains ("subs"))
+    {
+      Cell& type = m.contents ("type");
+      Cell& subs = m.contents ("subs");
+
+      type_string = std::string (type.length(), '\0');
+
+      for (int k = 0; k < type.length (); k++)
+	{
+	  std::string item = type(k).string_value ();
+
+	  if (! error_state)
+	    {
+	      if (item == "{}")
+		type_string[k] = '{';
+	      else if (item == "()")
+		type_string[k] = '(';
+	      else if (item == ".")
+		type_string[k] = '.';
+	      else
+		{
+		  error("%s: invalid indexing type `%s'", name, item.c_str ());
+		  return;
+		}
+	    }
+	  else
+	    {
+	      error ("%s: expecting type(%d) to be a character string",
+		     name, k+1);
+	      return;
+	    }
+
+	  octave_value_list idx_item;
+
+	  if (subs(k).is_string ())
+	    idx_item(0) = subs(k);
+	  else if (subs(k).is_cell ())
+	    {
+	      Cell subs_cell = subs(k).cell_value ();
+
+	      for (int n = 0; n < subs_cell.length (); n++)
+		{
+		  if (subs_cell(n).is_string ()
+		      && subs_cell(n).string_value () == ":")
+		    idx_item(n) = octave_value(octave_value::magic_colon_t);
+		  else
+		    idx_item(n) = subs_cell(n);
+		}
+	    }
+	  else
+	    {
+	      error ("%s: expecting subs(%d) to be a character string or cell array",
+		     name, k+1);
+	      return;
+	    }
+
+	  idx.push_back (idx_item);
+	}
+    }
+  else
+    error ("%s: second argument must be a structure with fields `type' and `subs'", name);
+}
+
+DEFUN (subsref, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})\n\
+Perform the subscripted element selection operation according to\n\
+the subscript specified by @var{idx}.\n\
+\n\
+The subscript @var{idx} is expected to be a structure array with\n\
+fields @samp{type} and @samp{subs}.  Valid values for @samp{type}\n\
+are @samp{\"()\"}, @samp{\"@{@}\"}, and @samp{\".\"}.\n\
+The @samp{subs} field may be either @samp{\":\"} or a cell array\n\
+of index values.\n\
+\n\
+The following example shows how to extract the two first columns of\n\
+a matrix\n\
+\n\
+ at example\n\
+ at group\n\
+val = magic(3)\n\
+     @result{} val = [ 8   1   6\n\
+                3   5   7\n\
+                4   9   2 ]\n\
+idx.type = \"()\";\n\
+idx.subs = @{\":\", 1:2@};\n\
+subsref(val, idx)\n\
+     @result{} [ 8   1 \n\
+          3   5 \n\
+          4   9 ]\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Note that this is the same as writing @code{val(:,1:2)}.\n\
+ at seealso{subsasgn, substruct}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 2)
+    {
+      std::string type;
+      std::list<octave_value_list> idx;
+
+      decode_subscripts ("subsref", args(1), type, idx);
+
+      if (! error_state)
+	retval = args(0).subsref (type, idx, nargout);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (subsasgn, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} subsasgn (@var{val}, @var{idx}, @var{rhs})\n\
+Perform the subscripted assignment operation according to\n\
+the subscript specified by @var{idx}.\n\
+\n\
+The subscript @var{idx} is expected to be a structure array with\n\
+fields @samp{type} and @samp{subs}.  Valid values for @samp{type}\n\
+are @samp{\"()\"}, @samp{\"@{@}\"}, and @samp{\".\"}.\n\
+The @samp{subs} field may be either @samp{\":\"} or a cell array\n\
+of index values.\n\
+\n\
+The following example shows how to set the two first columns of a\n\
+3-by-3 matrix to zero.\n\
+\n\
+ at example\n\
+ at group\n\
+val = magic(3);\n\
+idx.type = \"()\";\n\
+idx.subs = @{\":\", 1:2@};\n\
+subsasgn (val, idx, 0)\n\
+     @result{} [ 0   0   6\n\
+          0   0   7\n\
+          0   0   2 ]\n\
+ at end group\n\
+ at end example\n\
+\n\
+Note that this is the same as writing @code{val(:,1:2) = 0}.\n\
+ at seealso{subsref, substruct}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 3)
+    {
+      std::string type;
+      std::list<octave_value_list> idx;
+
+      decode_subscripts ("subsasgn", args(1), type, idx);
+
+      octave_value arg0 = args(0);
+
+      arg0.make_unique ();
+
+      if (! error_state)
+	retval = arg0.subsasgn (type, idx, args(2));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ov.h b/src/ov.h
new file mode 100644
index 0000000..aa49bf4
--- /dev/null
+++ b/src/ov.h
@@ -0,0 +1,1310 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_value_h)
+#define octave_value_h 1
+
+#include <cstdlib>
+
+#include <iosfwd>
+#include <string>
+#include <list>
+
+#include "Range.h"
+#include "data-conv.h"
+#include "idx-vector.h"
+#include "mach-info.h"
+#include "mxarray.h"
+#include "mx-base.h"
+#include "oct-alloc.h"
+#include "oct-time.h"
+#include "str-vec.h"
+
+#include "oct-hdf5.h"
+#include "oct-sort.h"
+
+class Cell;
+class Octave_map;
+class octave_stream;
+class octave_function;
+class octave_user_function;
+class octave_fcn_handle;
+class octave_fcn_inline;
+class octave_value_list;
+class octave_lvalue;
+
+#include "ov-base.h"
+
+// Constants.
+
+class octave_value;
+
+class
+OCTINTERP_API
+octave_value
+{
+public:
+
+  enum unary_op
+  {
+    op_not,            // not
+    op_uplus,          // uplus
+    op_uminus,         // uminus
+    op_transpose,      // transpose
+    op_hermitian,      // ctranspose
+    op_incr,
+    op_decr,
+    num_unary_ops,
+    unknown_unary_op
+  };
+
+  enum binary_op
+  {
+    op_add,            // plus
+    op_sub,            // minus
+    op_mul,            // mtimes
+    op_div,            // mrdivide
+    op_pow,            // mpower
+    op_ldiv,           // mldivide
+    op_lshift,
+    op_rshift,
+    op_lt,             // lt
+    op_le,             // le
+    op_eq,             // eq
+    op_ge,             // ge
+    op_gt,             // gt
+    op_ne,             // ne
+    op_el_mul,         // times
+    op_el_div,         // rdivide
+    op_el_pow,         // power
+    op_el_ldiv,        // ldivide
+    op_el_and,         // and
+    op_el_or,          // or
+    op_struct_ref,
+    num_binary_ops,
+    unknown_binary_op
+  };
+
+  enum compound_binary_op
+  {
+    // ** compound operations **
+    op_trans_mul,      
+    op_mul_trans,
+    op_herm_mul,      
+    op_mul_herm,
+    op_el_not_and,
+    op_el_not_or,
+    op_el_and_not,
+    op_el_or_not,
+    num_compound_binary_ops,
+    unknown_compound_binary_op
+  };
+
+  enum assign_op
+  {
+    op_asn_eq,
+    op_add_eq,
+    op_sub_eq,
+    op_mul_eq,
+    op_div_eq,
+    op_ldiv_eq,
+    op_pow_eq,
+    op_lshift_eq,
+    op_rshift_eq,
+    op_el_mul_eq,
+    op_el_div_eq,
+    op_el_ldiv_eq,
+    op_el_pow_eq,
+    op_el_and_eq,
+    op_el_or_eq,
+    num_assign_ops,
+    unknown_assign_op
+  };
+
+  static std::string unary_op_as_string (unary_op);
+  static std::string unary_op_fcn_name (unary_op);
+
+  static std::string binary_op_as_string (binary_op);
+  static std::string binary_op_fcn_name (binary_op);
+
+  static std::string binary_op_fcn_name (compound_binary_op);
+
+  static std::string assign_op_as_string (assign_op);
+
+  static octave_value empty_conv (const std::string& type,
+				  const octave_value& rhs = octave_value ());
+
+  enum magic_colon { magic_colon_t };
+
+  octave_value (void)
+    {
+      static octave_base_value nil_rep;
+      rep = &nil_rep;
+      rep->count++;
+    }
+
+  octave_value (short int i);
+  octave_value (unsigned short int i);
+  octave_value (int i);
+  octave_value (unsigned int i);
+  octave_value (long int i);
+  octave_value (unsigned long int i);
+
+  // FIXME -- these are kluges.  They turn into doubles
+  // internally, which will break for very large values.  We just use
+  // them to store things like 64-bit ino_t, etc, and hope that those
+  // values are never actually larger than can be represented exactly
+  // in a double.
+
+#if defined (HAVE_LONG_LONG_INT)
+  octave_value (long long int i);
+#endif
+#if defined (HAVE_UNSIGNED_LONG_LONG_INT)
+  octave_value (unsigned long long int i);
+#endif
+
+  octave_value (octave_time t);
+  octave_value (double d);
+  octave_value (float d);
+  octave_value (const ArrayN<octave_value>& a, bool is_cs_list = false);
+  octave_value (const Cell& c, bool is_cs_list = false);
+  octave_value (const Matrix& m, const MatrixType& t = MatrixType());
+  octave_value (const FloatMatrix& m, const MatrixType& t = MatrixType());
+  octave_value (const NDArray& nda);
+  octave_value (const FloatNDArray& nda);
+  octave_value (const ArrayN<double>& m);
+  octave_value (const ArrayN<float>& m);
+  octave_value (const DiagMatrix& d);
+  octave_value (const FloatDiagMatrix& d);
+  octave_value (const RowVector& v);
+  octave_value (const FloatRowVector& v);
+  octave_value (const ColumnVector& v);
+  octave_value (const FloatColumnVector& v);
+  octave_value (const Complex& C);
+  octave_value (const FloatComplex& C);
+  octave_value (const ComplexMatrix& m, const MatrixType& t = MatrixType());
+  octave_value (const FloatComplexMatrix& m, const MatrixType& t = MatrixType());
+  octave_value (const ComplexNDArray& cnda);
+  octave_value (const FloatComplexNDArray& cnda);
+  octave_value (const ArrayN<Complex>& m);
+  octave_value (const ArrayN<FloatComplex>& m);
+  octave_value (const ComplexDiagMatrix& d);
+  octave_value (const FloatComplexDiagMatrix& d);
+  octave_value (const ComplexRowVector& v);
+  octave_value (const FloatComplexRowVector& v);
+  octave_value (const ComplexColumnVector& v);
+  octave_value (const FloatComplexColumnVector& v);
+  octave_value (const PermMatrix& p);
+  octave_value (bool b);
+  octave_value (const boolMatrix& bm, const MatrixType& t = MatrixType());
+  octave_value (const boolNDArray& bnda);
+  octave_value (const ArrayN<bool>& bnda);
+  octave_value (char c, char type = '"');
+  octave_value (const char *s, char type = '"');
+  octave_value (const std::string& s, char type = '"');
+  octave_value (const string_vector& s, char type = '"');
+  octave_value (const charMatrix& chm, bool is_string = false,
+		char type = '"');
+  octave_value (const charNDArray& chnda, bool is_string = false,
+		char type = '"');
+  octave_value (const ArrayN<char>& chnda, bool is_string = false,
+		char type = '"');
+  octave_value (const SparseMatrix& m, const MatrixType& t = MatrixType ());
+  octave_value (const Sparse<double>& m, const MatrixType& t = MatrixType ());
+  octave_value (const SparseComplexMatrix& m, 
+		const MatrixType& t = MatrixType ());
+  octave_value (const Sparse<Complex>& m, const MatrixType& t = MatrixType ());
+  octave_value (const SparseBoolMatrix& bm, 
+		const MatrixType& t = MatrixType ());
+  octave_value (const Sparse<bool>& m, const MatrixType& t = MatrixType ());
+  octave_value (const octave_int8& i);
+  octave_value (const octave_int16& i);
+  octave_value (const octave_int32& i);
+  octave_value (const octave_int64& i);
+  octave_value (const octave_uint8& i);
+  octave_value (const octave_uint16& i);
+  octave_value (const octave_uint32& i);
+  octave_value (const octave_uint64& i);
+  octave_value (const int8NDArray& inda);
+  octave_value (const ArrayN<octave_int8>& inda);
+  octave_value (const int16NDArray& inda);
+  octave_value (const ArrayN<octave_int16>& inda);
+  octave_value (const int32NDArray& inda);
+  octave_value (const ArrayN<octave_int32>& inda);
+  octave_value (const int64NDArray& inda);
+  octave_value (const ArrayN<octave_int64>& inda);
+  octave_value (const uint8NDArray& inda);
+  octave_value (const ArrayN<octave_uint8>& inda);
+  octave_value (const uint16NDArray& inda);
+  octave_value (const ArrayN<octave_uint16>& inda);
+  octave_value (const uint32NDArray& inda);
+  octave_value (const ArrayN<octave_uint32>& inda);
+  octave_value (const uint64NDArray& inda);
+  octave_value (const ArrayN<octave_uint64>& inda);
+  octave_value (double base, double limit, double inc);
+  octave_value (const Range& r);
+  octave_value (const Octave_map& m);
+  octave_value (const Octave_map& m, const std::string& id);
+  octave_value (const octave_value_list& m, bool is_cs_list = false);
+  octave_value (octave_value::magic_colon);
+
+  octave_value (octave_base_value *new_rep);
+  octave_value (octave_base_value *new_rep, int xcount);
+
+  // Copy constructor.
+
+  octave_value (const octave_value& a)
+    {
+      rep = a.rep;
+      rep->count++;
+    }
+
+  // This should only be called for derived types.
+
+  octave_base_value *clone (void) const;
+
+  octave_base_value *empty_clone (void) const
+    { return rep->empty_clone (); }
+
+  // Delete the representation of this constant if the count drops to
+  // zero.
+
+  ~octave_value (void)
+  {
+    if (--rep->count == 0)
+      delete rep;
+  }
+
+  void make_unique (void)
+    {
+      if (rep->count > 1)
+	{
+	  --rep->count;
+	  rep = rep->clone ();
+	  rep->count = 1;
+	}
+    }
+
+  // This uniquifies the value if it is referenced by more than a certain
+  // number of shallow copies. This is useful for optimizations where we
+  // know a certain copy, typically within a cell array, to be obsolete.
+  void make_unique (int obsolete_copies)
+    {
+      if (rep->count > obsolete_copies + 1)
+	{
+	  --rep->count;
+	  rep = rep->clone ();
+	  rep->count = 1;
+	}
+    }
+
+  // Simple assignment.
+
+  octave_value& operator = (const octave_value& a)
+    {
+      if (rep != a.rep)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = a.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+  int get_count (void) const { return rep->count; }
+
+  octave_base_value::type_conv_info numeric_conversion_function (void) const
+    { return rep->numeric_conversion_function (); }
+
+  octave_base_value::type_conv_info numeric_demotion_function (void) const
+    { return rep->numeric_demotion_function (); }
+
+  void maybe_mutate (void);
+
+  octave_value squeeze (void) const
+    { return rep->squeeze (); }
+
+  // The result of full().
+  octave_value full_value (void) const
+    { return rep->full_value (); }
+
+  octave_base_value *try_narrowing_conversion (void)
+    { return rep->try_narrowing_conversion (); }
+
+  octave_value single_subsref (const std::string& type,
+			       const octave_value_list& idx);
+
+  octave_value subsref (const std::string& type,
+                        const std::list<octave_value_list>& idx)
+    { return rep->subsref (type, idx); }
+
+  octave_value subsref (const std::string& type,
+                        const std::list<octave_value_list>& idx,
+                        bool auto_add)
+    { return rep->subsref (type, idx, auto_add); }
+
+  octave_value_list subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             int nargout);
+
+  octave_value next_subsref (const std::string& type, const
+			     std::list<octave_value_list>& idx,
+			     size_t skip = 1);
+
+  octave_value_list next_subsref (int nargout,
+				  const std::string& type, const
+				  std::list<octave_value_list>& idx,
+				  size_t skip = 1);
+
+  octave_value next_subsref (bool auto_add, const std::string& type, const
+			     std::list<octave_value_list>& idx,
+			     size_t skip = 1);
+
+  octave_value do_index_op (const octave_value_list& idx,
+			    bool resize_ok = false)
+    { return rep->do_index_op (idx, resize_ok); }
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& idx);
+
+  octave_value subsasgn (const std::string& type,
+				 const std::list<octave_value_list>& idx,
+				 const octave_value& rhs);
+
+  octave_value assign (assign_op op, const std::string& type,
+		       const std::list<octave_value_list>& idx,
+		       const octave_value& rhs);
+
+  const octave_value& assign (assign_op, const octave_value& rhs);
+
+  idx_vector index_vector (void) const
+    { return rep->index_vector (); }
+
+  // Size.
+
+  dim_vector dims (void) const
+    { return rep->dims (); }
+
+  octave_idx_type rows (void) const { return rep->rows (); }
+
+  octave_idx_type columns (void) const { return rep->columns (); }
+
+  octave_idx_type length (void) const;
+
+  int ndims (void) const { return rep->ndims (); }
+
+  bool all_zero_dims (void) const { return dims().all_zero (); }
+
+  octave_idx_type numel (void) const
+    { return rep->numel (); }
+
+  octave_idx_type capacity (void) const
+    { return rep->capacity (); }
+
+  Matrix size (void) const;
+
+  size_t byte_size (void) const
+    { return rep->byte_size (); }
+
+  octave_idx_type nnz (void) const { return rep->nnz (); }
+
+  octave_idx_type nzmax (void) const { return rep->nzmax (); }
+
+  octave_idx_type nfields (void) const { return rep->nfields (); }
+
+  octave_value reshape (const dim_vector& dv) const
+    { return rep->reshape (dv); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return rep->permute (vec, inv); }
+
+  octave_value ipermute (const Array<int>& vec) const
+    { return rep->permute (vec, true); }
+
+  octave_value resize (const dim_vector& dv, bool fill = false) const
+    { return rep->resize (dv, fill);}
+
+  MatrixType matrix_type (void) const
+  { return rep->matrix_type (); }
+
+  MatrixType matrix_type (const MatrixType& typ) const
+  { return rep->matrix_type (typ); }
+
+  // Does this constant have a type?  Both of these are provided since
+  // it is sometimes more natural to write is_undefined() instead of
+  // ! is_defined().
+
+  bool is_defined (void) const
+    { return rep->is_defined (); }
+
+  bool is_undefined (void) const
+    { return ! is_defined (); }
+
+  bool is_empty (void) const
+    { return rep->is_empty (); }
+
+  bool is_cell (void) const
+    { return rep->is_cell (); }
+
+  bool is_cellstr (void) const
+    { return rep->is_cellstr (); }
+
+  bool is_real_scalar (void) const
+    { return rep->is_real_scalar (); }
+
+  bool is_real_matrix (void) const
+    { return rep->is_real_matrix (); }
+
+  bool is_real_nd_array (void) const
+    { return rep->is_real_nd_array (); }
+
+  bool is_complex_scalar (void) const
+    { return rep->is_complex_scalar (); }
+
+  bool is_complex_matrix (void) const
+    { return rep->is_complex_matrix (); }
+
+  bool is_bool_scalar (void) const
+    { return rep->is_bool_scalar (); }
+
+  bool is_bool_matrix (void) const
+    { return rep->is_bool_matrix (); }
+
+  bool is_char_matrix (void) const
+    { return rep->is_char_matrix (); }
+
+  bool is_diag_matrix (void) const
+    { return rep->is_diag_matrix (); }
+
+  bool is_perm_matrix (void) const
+    { return rep->is_perm_matrix (); }
+
+  bool is_string (void) const
+    { return rep->is_string (); }
+
+  bool is_sq_string (void) const
+    { return rep->is_sq_string (); }
+
+  bool is_dq_string (void) const
+    { return rep->is_string () && ! rep->is_sq_string (); }
+
+  bool is_range (void) const
+    { return rep->is_range (); }
+
+  bool is_map (void) const
+    { return rep->is_map (); }
+
+  bool is_object (void) const
+    { return rep->is_object (); }
+
+  bool is_cs_list (void) const
+    { return rep->is_cs_list (); }
+
+  bool is_list (void) const
+    { return rep->is_list (); }
+
+  bool is_magic_colon (void) const
+    { return rep->is_magic_colon (); }
+
+  bool is_null_value (void) const
+    { return rep->is_null_value (); }
+
+  // Are any or all of the elements in this constant nonzero?
+
+  octave_value all (int dim = 0) const
+    { return rep->all (dim); }
+
+  octave_value any (int dim = 0) const
+    { return rep->any (dim); }
+
+  // Floating point types.
+
+  bool is_double_type (void) const
+    { return rep->is_double_type (); }
+
+  bool is_single_type (void) const
+    { return rep->is_single_type (); }
+
+  bool is_float_type (void) const
+    { return rep->is_float_type (); }
+
+  // Integer types.
+
+  bool is_int8_type (void) const
+    { return rep->is_int8_type (); }
+
+  bool is_int16_type (void) const
+    { return rep->is_int16_type (); }
+
+  bool is_int32_type (void) const
+    { return rep->is_int32_type (); }
+
+  bool is_int64_type (void) const
+   { return rep->is_int64_type (); }
+
+  bool is_uint8_type (void) const
+    { return rep->is_uint8_type (); }
+
+  bool is_uint16_type (void) const
+    { return rep->is_uint16_type (); }
+
+  bool is_uint32_type (void) const
+    { return rep->is_uint32_type (); }
+
+  bool is_uint64_type (void) const
+    { return rep->is_uint64_type (); }
+
+  // Other type stuff.
+
+  bool is_bool_type (void) const
+    { return rep->is_bool_type (); }
+
+  bool is_integer_type (void) const
+    { return rep->is_integer_type (); }
+
+  bool is_real_type (void) const
+    { return rep->is_real_type (); }
+
+  bool is_complex_type (void) const
+    { return rep->is_complex_type (); }
+
+  bool is_scalar_type (void) const
+    { return rep->is_scalar_type (); }
+
+  bool is_matrix_type (void) const
+    { return rep->is_matrix_type (); }
+
+  bool is_numeric_type (void) const
+    { return rep->is_numeric_type (); }
+
+  bool is_sparse_type (void) const
+    { return rep->is_sparse_type (); }
+
+  // Does this constant correspond to a truth value?
+
+  bool is_true (void) const
+    { return rep->is_true (); }
+
+  // Do two constants match (in a switch statement)?
+  
+  bool is_equal (const octave_value&) const;
+
+  // Are the dimensions of this constant zero by zero?
+
+  bool is_zero_by_zero (void) const
+    { return (rows () == 0 && columns () == 0); }
+
+  bool is_constant (void) const
+    { return rep->is_constant (); }
+
+  bool is_function_handle (void) const
+    { return rep->is_function_handle (); }
+
+  bool is_inline_function (void) const
+    { return rep->is_inline_function (); }
+
+  bool is_function (void) const
+    { return rep->is_function (); }
+
+  bool is_user_script (void) const
+    { return rep->is_user_script (); }
+
+  bool is_user_function (void) const
+    { return rep->is_user_function (); }
+
+  bool is_user_code (void) const
+    { return rep->is_user_code (); }
+
+  bool is_builtin_function (void) const
+    { return rep->is_builtin_function (); }
+
+  bool is_dld_function (void) const
+    { return rep->is_dld_function (); }
+
+  bool is_mex_function (void) const
+    { return rep->is_mex_function (); }
+
+  void erase_subfunctions (void) { rep->erase_subfunctions (); }
+
+  // Values.
+
+  octave_value eval (void) { return *this; }
+
+  short int
+  short_value (bool req_int = false, bool frc_str_conv = false) const
+    { return rep->short_value (req_int, frc_str_conv); }
+
+  unsigned short int
+  ushort_value (bool req_int = false, bool frc_str_conv = false) const
+    { return rep->ushort_value (req_int, frc_str_conv); }
+
+  int int_value (bool req_int = false, bool frc_str_conv = false) const
+    { return rep->int_value (req_int, frc_str_conv); }
+
+  unsigned int
+  uint_value (bool req_int = false, bool frc_str_conv = false) const
+    { return rep->uint_value (req_int, frc_str_conv); }
+
+  int nint_value (bool frc_str_conv = false) const
+    { return rep->nint_value (frc_str_conv); }
+
+  long int
+  long_value (bool req_int = false, bool frc_str_conv = false) const
+    { return rep->long_value (req_int, frc_str_conv); }
+
+  unsigned long int
+  ulong_value (bool req_int = false, bool frc_str_conv = false) const
+    { return rep->ulong_value (req_int, frc_str_conv); }
+
+  octave_idx_type
+  idx_type_value (bool req_int = false, bool frc_str_conv = false) const;
+
+  double double_value (bool frc_str_conv = false) const
+    { return rep->double_value (frc_str_conv); }
+
+  float float_value (bool frc_str_conv = false) const
+    { return rep->float_value (frc_str_conv); }
+
+  double scalar_value (bool frc_str_conv = false) const
+    { return rep->scalar_value (frc_str_conv); }
+
+  float float_scalar_value (bool frc_str_conv = false) const
+    { return rep->float_scalar_value (frc_str_conv); }
+
+  Cell cell_value (void) const;
+
+  Matrix matrix_value (bool frc_str_conv = false) const
+    { return rep->matrix_value (frc_str_conv); }
+
+  FloatMatrix float_matrix_value (bool frc_str_conv = false) const
+    { return rep->float_matrix_value (frc_str_conv); }
+
+  NDArray array_value (bool frc_str_conv = false) const
+    { return rep->array_value (frc_str_conv); }
+
+  FloatNDArray float_array_value (bool frc_str_conv = false) const
+    { return rep->float_array_value (frc_str_conv); }
+
+  Complex complex_value (bool frc_str_conv = false) const
+    { return rep->complex_value (frc_str_conv); }
+
+  FloatComplex float_complex_value (bool frc_str_conv = false) const
+    { return rep->float_complex_value (frc_str_conv); }
+
+  ComplexMatrix complex_matrix_value (bool frc_str_conv = false) const
+    { return rep->complex_matrix_value (frc_str_conv); }
+
+  FloatComplexMatrix float_complex_matrix_value (bool frc_str_conv = false) const
+    { return rep->float_complex_matrix_value (frc_str_conv); }
+
+  ComplexNDArray complex_array_value (bool frc_str_conv = false) const
+    { return rep->complex_array_value (frc_str_conv); }
+
+  FloatComplexNDArray float_complex_array_value (bool frc_str_conv = false) const
+    { return rep->float_complex_array_value (frc_str_conv); }
+
+  bool bool_value (bool warn = false) const
+    { return rep->bool_value (warn); }
+
+  boolMatrix bool_matrix_value (bool warn = false) const
+    { return rep->bool_matrix_value (warn); }
+
+  boolNDArray bool_array_value (bool warn = false) const
+    { return rep->bool_array_value (warn); }
+
+  charMatrix char_matrix_value (bool frc_str_conv = false) const
+    { return rep->char_matrix_value (frc_str_conv); }
+
+  charNDArray char_array_value (bool frc_str_conv = false) const
+    { return rep->char_array_value (frc_str_conv); }
+
+  SparseMatrix sparse_matrix_value (bool frc_str_conv = false) const
+    { return rep->sparse_matrix_value (frc_str_conv); }
+
+  SparseComplexMatrix sparse_complex_matrix_value (bool frc_str_conv = false) const
+    { return rep->sparse_complex_matrix_value (frc_str_conv); }
+
+  SparseBoolMatrix sparse_bool_matrix_value (bool frc_str_conv = false) const
+    { return rep->sparse_bool_matrix_value (frc_str_conv); }
+
+  DiagMatrix diag_matrix_value (bool force = false) const
+    { return rep->diag_matrix_value (force); }
+  
+  FloatDiagMatrix float_diag_matrix_value (bool force = false) const
+    { return rep->float_diag_matrix_value (force); }
+  
+  ComplexDiagMatrix complex_diag_matrix_value (bool force = false) const
+    { return rep->complex_diag_matrix_value (force); }
+  
+  FloatComplexDiagMatrix float_complex_diag_matrix_value (bool force = false) const
+    { return rep->float_complex_diag_matrix_value (force); }
+
+  PermMatrix perm_matrix_value (void) const
+    { return rep->perm_matrix_value (); }
+  
+  octave_int8 int8_scalar_value (void) const
+    { return rep->int8_scalar_value (); }
+
+  octave_int16 int16_scalar_value (void) const
+    { return rep->int16_scalar_value (); }
+
+  octave_int32 int32_scalar_value (void) const
+    { return rep->int32_scalar_value (); }
+
+  octave_int64 int64_scalar_value (void) const
+    { return rep->int64_scalar_value (); }
+
+  octave_uint8 uint8_scalar_value (void) const
+    { return rep->uint8_scalar_value (); }
+
+  octave_uint16 uint16_scalar_value (void) const
+    { return rep->uint16_scalar_value (); }
+
+  octave_uint32 uint32_scalar_value (void) const
+    { return rep->uint32_scalar_value (); }
+
+  octave_uint64 uint64_scalar_value (void) const
+    { return rep->uint64_scalar_value (); }
+
+  int8NDArray int8_array_value (void) const
+    { return rep->int8_array_value (); }
+
+  int16NDArray int16_array_value (void) const
+    { return rep->int16_array_value (); }
+
+  int32NDArray int32_array_value (void) const
+    { return rep->int32_array_value (); }
+
+  int64NDArray int64_array_value (void) const
+    { return rep->int64_array_value (); }
+
+  uint8NDArray uint8_array_value (void) const
+    { return rep->uint8_array_value (); }
+
+  uint16NDArray uint16_array_value (void) const
+    { return rep->uint16_array_value (); }
+
+  uint32NDArray uint32_array_value (void) const
+    { return rep->uint32_array_value (); }
+
+  uint64NDArray uint64_array_value (void) const
+    { return rep->uint64_array_value (); }
+
+  string_vector all_strings (bool pad = false) const
+    { return rep->all_strings (pad); }
+
+  std::string string_value (bool force = false) const
+    { return rep->string_value (force); }
+
+  Array<std::string> cellstr_value (void) const
+    { return rep->cellstr_value (); }
+
+  Range range_value (void) const
+    { return rep->range_value (); }
+
+  Octave_map map_value (void) const;
+
+  string_vector map_keys (void) const
+    { return rep->map_keys (); }
+
+  size_t nparents (void) const
+    { return rep->nparents (); }
+
+  std::list<std::string> parent_class_name_list (void) const
+    { return rep->parent_class_name_list (); }
+
+  string_vector parent_class_names (void) const
+    { return rep->parent_class_names (); }
+
+  octave_base_value *
+  find_parent_class (const std::string& parent_class_name)
+    { return rep->find_parent_class (parent_class_name); }
+
+  octave_function *function_value (bool silent = false);
+
+  const octave_function *function_value (bool silent = false) const;
+
+  octave_user_function *user_function_value (bool silent = false);
+
+  octave_user_script *user_script_value (bool silent = false);
+
+  octave_user_code *user_code_value (bool silent = false);
+
+  octave_fcn_handle *fcn_handle_value (bool silent = false);
+
+  octave_fcn_inline *fcn_inline_value (bool silent = false);
+
+  octave_value_list list_value (void) const;
+
+  ColumnVector column_vector_value (bool frc_str_conv = false,
+			     bool frc_vec_conv = false) const;
+
+  ComplexColumnVector
+  complex_column_vector_value (bool frc_str_conv = false,
+			bool frc_vec_conv = false) const;
+
+  RowVector row_vector_value (bool frc_str_conv = false,
+			      bool frc_vec_conv = false) const;
+
+  ComplexRowVector
+  complex_row_vector_value (bool frc_str_conv = false,
+			    bool frc_vec_conv = false) const;
+
+
+  FloatColumnVector float_column_vector_value (bool frc_str_conv = false,
+			     bool frc_vec_conv = false) const;
+
+  FloatComplexColumnVector
+  float_complex_column_vector_value (bool frc_str_conv = false,
+			bool frc_vec_conv = false) const;
+
+  FloatRowVector float_row_vector_value (bool frc_str_conv = false,
+			      bool frc_vec_conv = false) const;
+
+  FloatComplexRowVector
+  float_complex_row_vector_value (bool frc_str_conv = false,
+			    bool frc_vec_conv = false) const;
+
+
+
+
+  Array<int> int_vector_value (bool req_int = false,
+			       bool frc_str_conv = false,
+			       bool frc_vec_conv = false) const;
+
+  Array<octave_idx_type>
+  octave_idx_type_vector_value (bool req_int = false,
+				bool frc_str_conv = false,
+				bool frc_vec_conv = false) const;
+
+  Array<double> vector_value (bool frc_str_conv = false,
+			      bool frc_vec_conv = false) const;
+
+  Array<Complex> complex_vector_value (bool frc_str_conv = false,
+				       bool frc_vec_conv = false) const;
+
+  Array<float> float_vector_value (bool frc_str_conv = false,
+			      bool frc_vec_conv = false) const;
+
+  Array<FloatComplex> float_complex_vector_value (bool frc_str_conv = false,
+				       bool frc_vec_conv = false) const;
+
+  // Possibly economize a lazy-indexed value.
+
+  void maybe_economize (void)
+    { rep->maybe_economize (); }
+
+  // The following two hook conversions are called on any octave_value prior to
+  // storing it to a "permanent" location, like a named variable, a cell or a
+  // struct component, or a return value of a function. 
+
+  octave_value storable_value (void) const;
+
+  // Ditto, but in place, i.e. equivalent to *this = this->storable_value (),
+  // but possibly more efficient.
+
+  void make_storable_value (void);
+
+  // Conversions.  These should probably be private.  If a user of this
+  // class wants a certain kind of constant, he should simply ask for
+  // it, and we should convert it if possible.
+
+  octave_value convert_to_str (bool pad = false, bool force = false,
+			       char type = '"') const
+  { return rep->convert_to_str (pad, force, type); }
+
+  octave_value
+  convert_to_str_internal (bool pad, bool force, char type) const
+    { return rep->convert_to_str_internal (pad, force, type); }
+
+  void convert_to_row_or_column_vector (void)
+    { rep->convert_to_row_or_column_vector (); }
+
+  bool print_as_scalar (void) const
+    { return rep->print_as_scalar (); }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const
+    { rep->print (os, pr_as_read_syntax); }
+
+  void print_raw (std::ostream& os,
+			  bool pr_as_read_syntax = false) const
+    { rep->print_raw (os, pr_as_read_syntax); }
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const
+    { return rep->print_name_tag (os, name); }
+
+  void print_with_name (std::ostream& os, const std::string& name,
+			bool print_padding = true) const
+    { rep->print_with_name (os, name, print_padding); }
+
+  int type_id (void) const { return rep->type_id (); }
+
+  std::string type_name (void) const { return rep->type_name (); }
+
+  std::string class_name (void) const { return rep->class_name (); }
+
+  // Unary and binary operations.
+
+  friend OCTINTERP_API octave_value do_unary_op (unary_op op,
+				   const octave_value& a);
+
+  const octave_value& do_non_const_unary_op (unary_op op);
+
+  void do_non_const_unary_op (unary_op op, const octave_value_list& idx);
+
+  octave_value do_non_const_unary_op (unary_op op, const std::string& type,
+				      const std::list<octave_value_list>& idx);
+
+  friend OCTINTERP_API octave_value do_binary_op (binary_op op,
+				    const octave_value& a,
+				    const octave_value& b);
+
+  friend OCTINTERP_API octave_value do_binary_op (compound_binary_op op,
+                                                  const octave_value& a,
+                                                  const octave_value& b);
+
+  friend OCTINTERP_API octave_value do_cat_op (const octave_value& a,
+				 const octave_value& b,
+				 const Array<octave_idx_type>& ra_idx);
+
+  const octave_base_value& get_rep (void) const { return *rep; }
+
+  bool is_copy_of (const octave_value &val) const { return rep == val.rep; }
+
+  void print_info (std::ostream& os,
+			   const std::string& prefix = std::string ()) const;
+
+  bool save_ascii (std::ostream& os) { return rep->save_ascii (os); }
+
+  bool load_ascii (std::istream& is) { return rep->load_ascii (is); }
+
+  bool save_binary (std::ostream& os, bool& save_as_floats)
+    { return rep->save_binary (os, save_as_floats); }
+
+  bool load_binary (std::istream& is, bool swap,
+			    oct_mach_info::float_format fmt)
+    { return rep->load_binary (is, swap, fmt); }
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+    { return rep->save_hdf5 (loc_id, name, save_as_floats); }
+
+  bool load_hdf5 (hid_t loc_id, const char *name,
+			  bool have_h5giterate_bug)
+    { return rep->load_hdf5 (loc_id, name, have_h5giterate_bug); }
+#endif
+
+  int write (octave_stream& os, int block_size,
+		     oct_data_conv::data_type output_type, int skip,
+		     oct_mach_info::float_format flt_fmt) const;
+
+  octave_base_value *internal_rep (void) const { return rep; }
+
+  // Unsafe.  These functions exist to support the MEX interface.
+  // You should not use them anywhere else.
+  void *mex_get_data (void) const { return rep->mex_get_data (); }
+
+  octave_idx_type *mex_get_ir (void) const { return rep->mex_get_ir (); }
+
+  octave_idx_type *mex_get_jc (void) const { return rep->mex_get_jc (); }
+
+  mxArray *as_mxArray (void) const { return rep->as_mxArray (); }
+
+  octave_value diag (octave_idx_type k = 0) const
+    { return rep->diag (k); }
+
+  octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+    { return rep->sort (dim, mode); } 
+  octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
+		 sortmode mode = ASCENDING) const
+    { return rep->sort (sidx, dim, mode); } 
+
+  sortmode is_sorted (sortmode mode = UNSORTED) const
+    { return rep->is_sorted (mode); }
+
+  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const
+    { return rep->sort_rows_idx (mode); }
+
+  sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+    { return rep->is_sorted_rows (mode); }
+
+  void lock (void) { rep->lock (); }
+
+  void unlock (void) { rep->unlock (); }
+
+  bool islocked (void) const { return rep->islocked (); }
+
+  void dump (std::ostream& os) const { rep->dump (os); }
+
+#define MAPPER_FORWARD(F) \
+  octave_value F (void) const { return rep->F (); }
+
+  MAPPER_FORWARD (abs)
+  MAPPER_FORWARD (acos)
+  MAPPER_FORWARD (acosh)
+  MAPPER_FORWARD (angle)
+  MAPPER_FORWARD (arg)
+  MAPPER_FORWARD (asin)
+  MAPPER_FORWARD (asinh)
+  MAPPER_FORWARD (atan)
+  MAPPER_FORWARD (atanh)
+  MAPPER_FORWARD (ceil)
+  MAPPER_FORWARD (conj)
+  MAPPER_FORWARD (cos)
+  MAPPER_FORWARD (cosh)
+  MAPPER_FORWARD (erf)
+  MAPPER_FORWARD (erfc)
+  MAPPER_FORWARD (exp)
+  MAPPER_FORWARD (expm1)
+  MAPPER_FORWARD (finite)
+  MAPPER_FORWARD (fix)
+  MAPPER_FORWARD (floor)
+  MAPPER_FORWARD (gamma)
+  MAPPER_FORWARD (imag)
+  MAPPER_FORWARD (isinf)
+  MAPPER_FORWARD (isna)
+  MAPPER_FORWARD (isnan)
+  MAPPER_FORWARD (lgamma)
+  MAPPER_FORWARD (log)
+  MAPPER_FORWARD (log2)
+  MAPPER_FORWARD (log10)
+  MAPPER_FORWARD (log1p)
+  MAPPER_FORWARD (real)
+  MAPPER_FORWARD (round)
+  MAPPER_FORWARD (roundb)
+  MAPPER_FORWARD (signum)
+  MAPPER_FORWARD (sin)
+  MAPPER_FORWARD (sinh)
+  MAPPER_FORWARD (sqrt)
+  MAPPER_FORWARD (tan)
+  MAPPER_FORWARD (tanh)
+
+  // These functions are prefixed with X to avoid potential macro
+  // conflicts.
+
+  MAPPER_FORWARD (xisalnum)
+  MAPPER_FORWARD (xisalpha)
+  MAPPER_FORWARD (xisascii)
+  MAPPER_FORWARD (xiscntrl)
+  MAPPER_FORWARD (xisdigit)
+  MAPPER_FORWARD (xisgraph)
+  MAPPER_FORWARD (xislower)
+  MAPPER_FORWARD (xisprint)
+  MAPPER_FORWARD (xispunct)
+  MAPPER_FORWARD (xisspace)
+  MAPPER_FORWARD (xisupper)
+  MAPPER_FORWARD (xisxdigit)
+  MAPPER_FORWARD (xtoascii)
+  MAPPER_FORWARD (xtolower)
+  MAPPER_FORWARD (xtoupper)
+
+#undef MAPPER_FORWARD
+
+protected:
+
+  // The real representation.
+  octave_base_value *rep;
+
+private:
+
+  assign_op unary_op_to_assign_op (unary_op op);
+
+  binary_op op_eq_to_binary_op (assign_op op);
+
+  DECLARE_OCTAVE_ALLOCATOR
+};
+
+// Publish externally used friend functions.
+
+extern OCTINTERP_API octave_value
+do_unary_op (octave_value::unary_op op, const octave_value& a);
+
+extern OCTINTERP_API octave_value
+do_binary_op (octave_value::binary_op op,
+	      const octave_value& a, const octave_value& b);
+
+extern OCTINTERP_API octave_value
+do_binary_op (octave_value::compound_binary_op op,
+              const octave_value& a, const octave_value& b);
+
+#define OV_UNOP_FN(name) \
+  inline octave_value \
+  name (const octave_value& a) \
+  { \
+    return do_unary_op (octave_value::name, a); \
+  }
+
+#define OV_UNOP_OP(name, op) \
+  inline octave_value \
+  operator op (const octave_value& a) \
+  { \
+    return name (a); \
+  }
+
+#define OV_UNOP_FN_OP(name, op) \
+  OV_UNOP_FN (name) \
+  OV_UNOP_OP (name, op)
+
+OV_UNOP_FN_OP (op_not, !)
+OV_UNOP_FN_OP (op_uplus, +)
+OV_UNOP_FN_OP (op_uminus, -)
+
+OV_UNOP_FN (op_transpose)
+OV_UNOP_FN (op_hermitian)
+
+// No simple way to define these for prefix and suffix ops?
+//
+//   incr
+//   decr
+
+#define OV_BINOP_FN(name) \
+  inline octave_value \
+  name (const octave_value& a1, const octave_value& a2) \
+  { \
+    return do_binary_op (octave_value::name, a1, a2); \
+  }
+
+#define OV_BINOP_OP(name, op) \
+  inline octave_value \
+  operator op (const octave_value& a1, const octave_value& a2) \
+  { \
+    return name (a1, a2); \
+  }
+
+#define OV_BINOP_FN_OP(name, op) \
+  OV_BINOP_FN (name) \
+  OV_BINOP_OP (name, op)
+
+OV_BINOP_FN_OP (op_add, +)
+OV_BINOP_FN_OP (op_sub, -)
+OV_BINOP_FN_OP (op_mul, *)
+OV_BINOP_FN_OP (op_div, /)
+
+OV_BINOP_FN (op_pow)
+OV_BINOP_FN (op_ldiv)
+OV_BINOP_FN (op_lshift)
+OV_BINOP_FN (op_rshift)
+
+OV_BINOP_FN_OP (op_lt, <)
+OV_BINOP_FN_OP (op_le, <=)
+OV_BINOP_FN_OP (op_eq, ==)
+OV_BINOP_FN_OP (op_ge, >=)
+OV_BINOP_FN_OP (op_gt, >)
+OV_BINOP_FN_OP (op_ne, !=)
+
+OV_BINOP_FN (op_el_mul)
+OV_BINOP_FN (op_el_div)
+OV_BINOP_FN (op_el_pow)
+OV_BINOP_FN (op_el_ldiv)
+OV_BINOP_FN (op_el_and)
+OV_BINOP_FN (op_el_or)
+
+OV_BINOP_FN (op_struct_ref)
+
+#define OV_COMP_BINOP_FN(name) \
+  inline octave_value \
+  name (const octave_value& a1, const octave_value& a2) \
+  { \
+    return do_binary_op (octave_value::name, a1, a2); \
+  }
+
+OV_COMP_BINOP_FN (op_trans_mul)
+OV_COMP_BINOP_FN (op_mul_trans)
+OV_COMP_BINOP_FN (op_herm_mul)
+OV_COMP_BINOP_FN (op_mul_herm)
+
+extern OCTINTERP_API void install_types (void);
+
+// FIXME -- these trait classes probably belong somehwere else...
+
+template <typename T>
+class
+octave_type_traits
+{
+public:
+  typedef T val_type;
+};
+
+#define OCTAVE_TYPE_TRAIT(T, VAL_T) \
+  template <> \
+  class \
+  octave_type_traits<T> \
+  { \
+  public: \
+    typedef VAL_T val_type; \
+  }
+
+OCTAVE_TYPE_TRAIT (octave_int8, octave_int8::val_type);
+OCTAVE_TYPE_TRAIT (octave_uint8, octave_uint8::val_type);
+OCTAVE_TYPE_TRAIT (octave_int16, octave_int16::val_type);
+OCTAVE_TYPE_TRAIT (octave_uint16, octave_uint16::val_type);
+OCTAVE_TYPE_TRAIT (octave_int32, octave_int32::val_type);
+OCTAVE_TYPE_TRAIT (octave_uint32, octave_uint32::val_type);
+OCTAVE_TYPE_TRAIT (octave_int64, octave_int64::val_type);
+OCTAVE_TYPE_TRAIT (octave_uint64, octave_uint64::val_type);
+
+template <typename T>
+class octave_array_type_traits
+{
+public:
+  typedef T element_type;
+};
+
+#define OCTAVE_ARRAY_TYPE_TRAIT(T, ELT_T) \
+  template <> \
+  class \
+  octave_array_type_traits<T> \
+  { \
+  public: \
+    typedef ELT_T element_type; \
+  }
+
+OCTAVE_ARRAY_TYPE_TRAIT (charNDArray, char);
+OCTAVE_ARRAY_TYPE_TRAIT (boolNDArray, bool);
+OCTAVE_ARRAY_TYPE_TRAIT (int8NDArray, octave_int8);
+OCTAVE_ARRAY_TYPE_TRAIT (uint8NDArray, octave_uint8);
+OCTAVE_ARRAY_TYPE_TRAIT (int16NDArray, octave_int16);
+OCTAVE_ARRAY_TYPE_TRAIT (uint16NDArray, octave_uint16);
+OCTAVE_ARRAY_TYPE_TRAIT (int32NDArray, octave_int32);
+OCTAVE_ARRAY_TYPE_TRAIT (uint32NDArray, octave_uint32);
+OCTAVE_ARRAY_TYPE_TRAIT (int64NDArray, octave_int64);
+OCTAVE_ARRAY_TYPE_TRAIT (uint64NDArray, octave_uint64);
+OCTAVE_ARRAY_TYPE_TRAIT (NDArray, double);
+OCTAVE_ARRAY_TYPE_TRAIT (FloatNDArray, float);
+
+// This will eventually go away, but for now it can be used to
+// simplify the transition to the new octave_value class hierarchy,
+// which uses octave_base_value instead of octave_value for the type
+// of octave_value::rep.
+#define OV_REP_TYPE octave_base_value
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pager.cc b/src/pager.cc
new file mode 100644
index 0000000..6385a1e
--- /dev/null
+++ b/src/pager.cc
@@ -0,0 +1,605 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include "cmd-edit.h"
+#include "oct-env.h"
+
+#include "procstream.h"
+
+#include <defaults.h>
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "sighandlers.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// Our actual connection to the external pager.
+static oprocstream *external_pager = 0;
+
+// TRUE means we write to the diary file.
+static bool write_to_diary_file = false;
+
+// The name of the current diary file.
+static std::string diary_file;
+
+// The diary file.
+static std::ofstream external_diary_file;
+
+static std::string
+default_pager (void)
+{
+  std::string pager_binary = octave_env::getenv ("PAGER");
+
+#ifdef OCTAVE_DEFAULT_PAGER
+  if (pager_binary.empty ())
+    pager_binary = OCTAVE_DEFAULT_PAGER;
+#endif
+
+  return pager_binary;
+}
+
+// The shell command to run as the pager.
+static std::string VPAGER = default_pager ();
+
+// The options to pass to the pager.
+static std::string VPAGER_FLAGS;
+
+// TRUE means that if output is going to the pager, it is sent as soon
+// as it is available.  Otherwise, it is buffered and only sent to the
+// pager when it is time to print another prompt.
+static bool Vpage_output_immediately = false;
+
+// TRUE means all output intended for the screen should be passed
+// through the pager.
+static bool Vpage_screen_output = true;
+
+static bool really_flush_to_pager = false;
+
+static bool flushing_output_to_pager = false;
+
+static void
+clear_external_pager (void)
+{
+  if (external_pager)
+    {
+      octave_child_list::remove (external_pager->pid ());
+
+      delete external_pager;
+      external_pager = 0;
+    }
+}
+
+static bool
+pager_event_handler (pid_t pid, int status)
+{
+  bool retval = false;
+
+  if (pid > 0)
+    {
+      if (WIFEXITED (status) || WIFSIGNALLED (status))
+	{
+	  // Avoid warning() since that will put us back in the pager,
+	  // which would be bad news.
+
+	  std::cerr << "warning: connection to external pager lost (pid = "
+		    << pid << ")" << std::endl;
+	  std::cerr << "warning: flushing pending output (please wait)"
+		    << std::endl;
+
+	  // Request removal of this PID from the list of child
+	  // processes.
+
+	  retval = true;
+	}
+    }
+
+  return retval;
+}
+
+static std::string
+pager_command (void)
+{
+  std::string cmd = VPAGER;
+
+  if (! (cmd.empty () || VPAGER_FLAGS.empty ()))
+    cmd += " " + VPAGER_FLAGS;
+
+  return cmd;
+}
+
+static void
+do_sync (const char *msg, int len, bool bypass_pager)
+{
+  if (msg && len > 0)
+    {
+      if (bypass_pager)
+	{
+	  std::cout.write (msg, len);
+	  std::cout.flush ();
+	}
+      else
+	{
+	  if (! external_pager)
+	    {
+	      std::string pgr = pager_command ();
+
+	      if (! pgr.empty ())
+		{
+		  external_pager = new oprocstream (pgr.c_str ());
+
+		  if (external_pager)
+		    octave_child_list::insert (external_pager->pid (),
+					       pager_event_handler);
+		}
+	    }
+
+	  if (external_pager)
+	    {
+	      if (external_pager->good ())
+		{
+		  external_pager->write (msg, len);
+
+		  external_pager->flush ();
+
+#if defined (EPIPE)
+		  if (errno == EPIPE)
+		    external_pager->setstate (std::ios::failbit);
+#endif
+		}
+	      else
+		{
+		  // FIXME -- omething is not right with the
+		  // pager.  If it died then we should receive a
+		  // signal for that.  If there is some other problem,
+		  // then what?
+		}
+	    }
+	  else
+	    {
+	      std::cout.write (msg, len);
+	      std::cout.flush ();
+	    }
+	}
+    }
+}
+
+// Assume our terminal wraps long lines.
+
+static bool
+more_than_a_screenful (const char *s, int len)
+{
+  if (s)
+    {
+      int available_rows = command_editor::terminal_rows () - 2;
+
+      int cols = command_editor::terminal_cols ();
+
+      int count = 0;
+
+      int chars_this_line = 0;
+
+      for (int i = 0; i < len; i++)
+	{
+	  if (*s++ == '\n')
+	    {
+	      count += chars_this_line / cols + 1;
+	      chars_this_line = 0;
+	    }
+	  else
+	    chars_this_line++;
+	}
+
+      if (count > available_rows)
+ 	return true;
+    }
+
+  return false;
+}
+
+int
+octave_pager_buf::sync (void)
+{
+  if (! interactive
+      || really_flush_to_pager
+      || (Vpage_screen_output && Vpage_output_immediately)
+      || ! Vpage_screen_output)
+    {
+      char *buf = eback ();
+
+      int len = pptr () - buf;
+
+      bool bypass_pager = (! interactive
+			   || ! Vpage_screen_output
+			   || (really_flush_to_pager
+			       && Vpage_screen_output
+			       && ! Vpage_output_immediately
+			       && ! more_than_a_screenful (buf, len)));
+
+      if (len > 0)
+	{
+	  do_sync (buf, len, bypass_pager);
+
+	  flush_current_contents_to_diary ();
+
+	  seekoff (0, std::ios::beg);
+	}
+    }
+
+  return 0;
+}
+
+void
+octave_pager_buf::flush_current_contents_to_diary (void)
+{
+  char *buf = eback () + diary_skip;
+
+  size_t len = pptr () - buf;
+
+  octave_diary.write (buf, len);
+
+  diary_skip = 0;
+}
+
+void
+octave_pager_buf::set_diary_skip (void)
+{
+  diary_skip = pptr () - eback ();
+}
+
+int
+octave_diary_buf::sync (void)
+{
+  if (write_to_diary_file && external_diary_file)
+    {
+      char *buf = eback ();
+
+      int len = pptr () - buf;
+
+      if (len > 0)
+	external_diary_file.write (buf, len);
+    }
+
+  seekoff (0, std::ios::beg);
+
+  return 0;
+}
+
+octave_pager_stream *octave_pager_stream::instance = 0;
+
+octave_pager_stream::octave_pager_stream (void) : std::ostream (0), pb (0)
+{
+  pb = new octave_pager_buf ();
+  rdbuf (pb);
+  setf (unitbuf);
+}
+
+octave_pager_stream::~octave_pager_stream (void)
+{
+  flush ();
+  delete pb;
+}
+
+octave_pager_stream&
+octave_pager_stream::stream (void)
+{
+  if (! instance)
+    instance = new octave_pager_stream ();
+
+  return *instance;
+}
+
+void
+octave_pager_stream::flush_current_contents_to_diary (void)
+{
+  if (pb)
+    pb->flush_current_contents_to_diary ();
+}
+
+void
+octave_pager_stream::set_diary_skip (void)
+{
+  if (pb)
+    pb->set_diary_skip ();
+}
+
+octave_diary_stream *octave_diary_stream::instance = 0;
+
+octave_diary_stream::octave_diary_stream (void) : std::ostream (0), db (0)
+{
+  db = new octave_diary_buf ();
+  rdbuf (db);
+  setf (unitbuf);
+}
+
+octave_diary_stream::~octave_diary_stream (void)
+{
+  flush ();
+  delete db;
+}
+
+octave_diary_stream&
+octave_diary_stream::stream (void)
+{
+  if (! instance)
+    instance = new octave_diary_stream ();
+
+  return *instance;
+}
+
+void
+flush_octave_stdout (void)
+{
+  if (! flushing_output_to_pager)
+    {
+      unwind_protect::begin_frame ("flush_octave_stdout");
+
+      unwind_protect_bool (really_flush_to_pager);
+      unwind_protect_bool (flushing_output_to_pager);
+
+      really_flush_to_pager = true;
+      flushing_output_to_pager = true;
+
+      octave_stdout.flush ();
+
+      clear_external_pager ();
+
+      unwind_protect::run_frame ("flush_octave_stdout");
+    }
+}
+
+static void
+close_diary_file (void)
+{
+  // Try to flush the current buffer to the diary now, so that things
+  // like
+  //
+  // function foo ()
+  //   diary on;
+  //   ...
+  //   diary off;
+  // endfunction
+  //
+  // will do the right thing.
+
+  octave_stdout.flush_current_contents_to_diary ();
+
+  if (external_diary_file.is_open ())
+    {
+      octave_diary.flush ();
+      external_diary_file.close ();
+    }
+}
+
+static void
+open_diary_file (void)
+{
+  close_diary_file ();
+
+  // If there is pending output in the pager buf, it should not go
+  // into the diary file.
+ 
+  octave_stdout.set_diary_skip ();
+
+  external_diary_file.open (diary_file.c_str (), std::ios::app);
+
+  if (! external_diary_file)
+    error ("diary: can't open diary file `%s'", diary_file.c_str ());
+}
+
+DEFUN (diary, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} diary options\n\
+Record a list of all commands @emph{and} the output they produce, mixed\n\
+together just as you see them on your terminal.  Valid options are:\n\
+\n\
+ at table @code\n\
+ at item on\n\
+Start recording your session in a file called @file{diary} in your\n\
+current working directory.\n\
+\n\
+ at item off\n\
+Stop recording your session in the diary file.\n\
+\n\
+ at item @var{file}\n\
+Record your session in the file named @var{file}.\n\
+ at end table\n\
+\n\
+With no arguments, @code{diary} toggles the current diary state.\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("diary");
+
+  if (error_state)
+    return retval;
+
+  if (diary_file.empty ())
+    diary_file = "diary";
+
+  switch (argc)
+    {
+    case 1:
+      write_to_diary_file = ! write_to_diary_file;
+      open_diary_file ();
+      break;
+
+    case 2:
+      {
+	std::string arg = argv[1];
+
+	if (arg == "on")
+	  {
+	    write_to_diary_file = true;
+	    open_diary_file ();
+	  }	
+	else if (arg == "off")
+	  {
+	    close_diary_file ();
+	    write_to_diary_file = false;
+	  }
+	else
+	  {
+	    diary_file = arg;
+	    write_to_diary_file = true;
+	    open_diary_file ();
+	  }
+      }
+      break;
+
+    default:
+      print_usage ();
+      break;
+    }
+
+  return retval;
+}
+
+DEFUN (more, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} more\n\
+ at deffnx {Command} more on\n\
+ at deffnx {Command} more off\n\
+Turn output pagination on or off.  Without an argument, @code{more}\n\
+toggles the current state.\n\
+The current state can be determined via @code{page_screen_output}.\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("more");
+
+  if (error_state)
+    return retval;
+
+  if (argc == 2)
+    {
+      std::string arg = argv[1];
+
+      if (arg == "on")
+	Vpage_screen_output = true;
+      else if (arg == "off")
+	Vpage_screen_output = false;
+      else
+	error ("more: unrecognized argument `%s'", arg.c_str ());
+    }
+  else if (argc == 1)
+    Vpage_screen_output = ! Vpage_screen_output;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (terminal_size, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} terminal_size ()\n\
+Return a two-element row vector containing the current size of the\n\
+terminal window in characters (rows and columns).\n\
+ at seealso{list_in_columns}\n\
+ at end deftypefn")
+{
+  RowVector size (2, 0.0);
+
+  size(0) = command_editor::terminal_rows ();
+  size(1) = command_editor::terminal_cols ();
+
+  return octave_value (size);
+}
+
+DEFUN (page_output_immediately, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} page_output_immediately ()\n\
+ at deftypefnx {Built-in Function} {@var{val} =} page_output_immediately (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave sends\n\
+output to the pager as soon as it is available.  Otherwise, Octave\n\
+buffers its output and waits until just before the prompt is printed to\n\
+flush it to the pager.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (page_output_immediately);
+}
+
+DEFUN (page_screen_output, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} page_screen_output ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} page_screen_output (@var{new_val})\n\
+Query or set the internal variable that controls whether output intended\n\
+for the terminal window that is longer than one page is sent through a\n\
+pager.  This allows you to view one screenful at a time.  Some pagers\n\
+(such as @code{less}---see @ref{Installation}) are also capable of moving\n\
+backward on the output.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (page_screen_output);
+}
+
+DEFUN (PAGER, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} PAGER ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} PAGER (@var{new_val})\n\
+Query or set the internal variable that specifies the program to use\n\
+to display terminal output on your system.  The default value is\n\
+normally @code{\"less\"}, @code{\"more\"}, or\n\
+ at code{\"pg\"}, depending on what programs are installed on your system.\n\
+ at xref{Installation}.\n\
+ at seealso{more, page_screen_output, page_output_immediately, PAGER_FLAGS}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (PAGER);
+}
+
+DEFUN (PAGER_FLAGS, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} PAGER_FLAGS ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} PAGER_FLAGS (@var{new_val})\n\
+Query or set the internal variable that specifies the options to pass\n\
+to the pager.\n\
+ at seealso{PAGER}\n\
+ at end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (PAGER_FLAGS);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pager.h b/src/pager.h
new file mode 100644
index 0000000..dda4c0c
--- /dev/null
+++ b/src/pager.h
@@ -0,0 +1,139 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2005, 2006,
+              2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_pager_h)
+#define octave_pager_h 1
+
+#include <iosfwd>
+#include <sstream>
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+class
+OCTINTERP_API
+octave_pager_buf : public std::stringbuf
+{
+public:
+
+  octave_pager_buf (void) : std::stringbuf (), diary_skip (0) { }
+
+  void flush_current_contents_to_diary (void);
+
+  void set_diary_skip (void);
+
+protected:
+
+  int sync (void);
+
+private:
+
+  size_t diary_skip;
+};
+
+class
+OCTINTERP_API
+octave_pager_stream : public std::ostream
+{
+protected:
+
+  octave_pager_stream (void);
+
+public:
+
+  ~octave_pager_stream (void);
+
+  void flush_current_contents_to_diary (void);
+
+  void set_diary_skip (void);
+
+  static octave_pager_stream& stream (void);
+
+private:
+
+  static octave_pager_stream *instance;
+
+  octave_pager_buf *pb;
+
+  // No copying!
+
+  octave_pager_stream (const octave_pager_stream&);
+
+  octave_pager_stream& operator = (const octave_pager_stream&);
+};
+
+class
+OCTINTERP_API
+octave_diary_buf : public std::stringbuf
+{
+public:
+
+  octave_diary_buf (void) : std::stringbuf () { }
+
+protected:
+
+  int sync (void);
+};
+
+class
+OCTINTERP_API
+octave_diary_stream : public std::ostream
+{
+protected:
+
+  octave_diary_stream (void);
+
+public:
+
+  ~octave_diary_stream (void);
+
+  static octave_diary_stream& stream (void);
+
+private:
+
+  static octave_diary_stream *instance;
+
+  octave_diary_buf *db;
+
+  // No copying!
+
+  octave_diary_stream (const octave_diary_stream&);
+
+  octave_diary_stream& operator = (const octave_diary_stream&);
+};
+
+#define octave_stdout (octave_pager_stream::stream ())
+
+#define octave_diary (octave_diary_stream::stream ())
+
+extern OCTINTERP_API void flush_octave_stdout (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/parse.cc b/src/parse.cc
new file mode 100644
index 0000000..af6fc87
--- /dev/null
+++ b/src/parse.cc
@@ -0,0 +1,6759 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can 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, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse octave_parse
+#define yylex   octave_lex
+#define yyerror octave_error
+#define yylval  octave_lval
+#define yychar  octave_char
+#define yydebug octave_debug
+#define yynerrs octave_nerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ADD_EQ = 258,
+     SUB_EQ = 259,
+     MUL_EQ = 260,
+     DIV_EQ = 261,
+     LEFTDIV_EQ = 262,
+     POW_EQ = 263,
+     EMUL_EQ = 264,
+     EDIV_EQ = 265,
+     ELEFTDIV_EQ = 266,
+     EPOW_EQ = 267,
+     AND_EQ = 268,
+     OR_EQ = 269,
+     LSHIFT_EQ = 270,
+     RSHIFT_EQ = 271,
+     LSHIFT = 272,
+     RSHIFT = 273,
+     EXPR_AND_AND = 274,
+     EXPR_OR_OR = 275,
+     EXPR_AND = 276,
+     EXPR_OR = 277,
+     EXPR_NOT = 278,
+     EXPR_LT = 279,
+     EXPR_LE = 280,
+     EXPR_EQ = 281,
+     EXPR_NE = 282,
+     EXPR_GE = 283,
+     EXPR_GT = 284,
+     LEFTDIV = 285,
+     EMUL = 286,
+     EDIV = 287,
+     ELEFTDIV = 288,
+     EPLUS = 289,
+     EMINUS = 290,
+     QUOTE = 291,
+     TRANSPOSE = 292,
+     PLUS_PLUS = 293,
+     MINUS_MINUS = 294,
+     POW = 295,
+     EPOW = 296,
+     NUM = 297,
+     IMAG_NUM = 298,
+     STRUCT_ELT = 299,
+     NAME = 300,
+     END = 301,
+     DQ_STRING = 302,
+     SQ_STRING = 303,
+     FOR = 304,
+     WHILE = 305,
+     DO = 306,
+     UNTIL = 307,
+     IF = 308,
+     ELSEIF = 309,
+     ELSE = 310,
+     SWITCH = 311,
+     CASE = 312,
+     OTHERWISE = 313,
+     BREAK = 314,
+     CONTINUE = 315,
+     FUNC_RET = 316,
+     UNWIND = 317,
+     CLEANUP = 318,
+     TRY = 319,
+     CATCH = 320,
+     GLOBAL = 321,
+     STATIC = 322,
+     FCN_HANDLE = 323,
+     END_OF_INPUT = 324,
+     LEXICAL_ERROR = 325,
+     FCN = 326,
+     SCRIPT = 327,
+     CLOSE_BRACE = 328,
+     UNARY = 329
+   };
+#endif
+/* Tokens.  */
+#define ADD_EQ 258
+#define SUB_EQ 259
+#define MUL_EQ 260
+#define DIV_EQ 261
+#define LEFTDIV_EQ 262
+#define POW_EQ 263
+#define EMUL_EQ 264
+#define EDIV_EQ 265
+#define ELEFTDIV_EQ 266
+#define EPOW_EQ 267
+#define AND_EQ 268
+#define OR_EQ 269
+#define LSHIFT_EQ 270
+#define RSHIFT_EQ 271
+#define LSHIFT 272
+#define RSHIFT 273
+#define EXPR_AND_AND 274
+#define EXPR_OR_OR 275
+#define EXPR_AND 276
+#define EXPR_OR 277
+#define EXPR_NOT 278
+#define EXPR_LT 279
+#define EXPR_LE 280
+#define EXPR_EQ 281
+#define EXPR_NE 282
+#define EXPR_GE 283
+#define EXPR_GT 284
+#define LEFTDIV 285
+#define EMUL 286
+#define EDIV 287
+#define ELEFTDIV 288
+#define EPLUS 289
+#define EMINUS 290
+#define QUOTE 291
+#define TRANSPOSE 292
+#define PLUS_PLUS 293
+#define MINUS_MINUS 294
+#define POW 295
+#define EPOW 296
+#define NUM 297
+#define IMAG_NUM 298
+#define STRUCT_ELT 299
+#define NAME 300
+#define END 301
+#define DQ_STRING 302
+#define SQ_STRING 303
+#define FOR 304
+#define WHILE 305
+#define DO 306
+#define UNTIL 307
+#define IF 308
+#define ELSEIF 309
+#define ELSE 310
+#define SWITCH 311
+#define CASE 312
+#define OTHERWISE 313
+#define BREAK 314
+#define CONTINUE 315
+#define FUNC_RET 316
+#define UNWIND 317
+#define CLEANUP 318
+#define TRY 319
+#define CATCH 320
+#define GLOBAL 321
+#define STATIC 322
+#define FCN_HANDLE 323
+#define END_OF_INPUT 324
+#define LEXICAL_ERROR 325
+#define FCN 326
+#define SCRIPT 327
+#define CLOSE_BRACE 328
+#define UNARY 329
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 28 "parse.y"
+
+#define YYDEBUG 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cstdio>
+
+#ifdef YYBYACC
+#include <cstdlib>
+#endif
+
+#include <iostream>
+#include <map>
+#include <sstream>
+
+#include "Cell.h"
+#include "Matrix.h"
+#include "cmd-edit.h"
+#include "cmd-hist.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+
+#include "comment-list.h"
+#include "defaults.h"
+#include "defun.h"
+#include "dirfns.h"
+#include "dynamic-ld.h"
+#include "error.h"
+#include "input.h"
+#include "lex.h"
+#include "load-path.h"
+#include "oct-hist.h"
+#include "oct-map.h"
+#include "ov-fcn-handle.h"
+#include "ov-usr-fcn.h"
+#include "ov-null-mat.h"
+#include "toplev.h"
+#include "pager.h"
+#include "parse.h"
+#include "pt-all.h"
+#include "pt-eval.h"
+#include "symtab.h"
+#include "token.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// The current input line number.
+int input_line_number = 1;
+
+// The column of the current token.
+int current_input_column = 1;
+
+// Buffer for help text snagged from function files.
+std::stack<std::string> help_buf;
+
+// Buffer for comments appearing before a function statement.
+static std::string fcn_comment_header;
+
+// TRUE means we are using readline.
+// (--no-line-editing)
+bool line_editing = true;
+
+// TRUE means we printed messages about reading startup files.
+bool reading_startup_message_printed = false;
+
+// TRUE means input is coming from startup file.
+bool input_from_startup_file = false;
+
+// Keep a count of how many END tokens we expect.
+int end_tokens_expected = 0;
+
+// Keep track of symbol table information when parsing functions.
+std::stack<symbol_table::scope_id> symtab_context;
+
+// Name of parent function when parsing function files that might
+// contain nested functions.
+std::string parent_function_name;
+
+// Name of the current class when we are parsing class methods or
+// constructors.
+std::string current_class_name;
+
+// TRUE means we are in the process of autoloading a function.
+static bool autoloading = false;
+
+// TRUE means the current function file was found in a relative path
+// element.
+static bool fcn_file_from_relative_lookup = false;
+
+// If nonzero, this is a pointer to the function we just finished
+// parsing.
+static octave_function *curr_fcn_ptr = 0;
+
+// List of autoloads (function -> file mapping).
+static std::map<std::string, std::string> autoload_map;
+
+// Forward declarations for some functions defined at the bottom of
+// the file.
+
+// Generic error messages.
+static void
+yyerror (const char *s);
+
+// Error mesages for mismatched end tokens.
+static void
+end_error (const char *type, token::end_tok_type ettype, int l, int c);
+
+// Check to see that end tokens are properly matched.
+static bool
+end_token_ok (token *tok, token::end_tok_type expected);
+
+// Maybe print a warning if an assignment expression is used as the
+// test in a logical expression.
+static void
+maybe_warn_assign_as_truth_value (tree_expression *expr);
+
+// Maybe print a warning about switch labels that aren't constants.
+static void
+maybe_warn_variable_switch_label (tree_expression *expr);
+
+// Finish building a range.
+static tree_expression *
+finish_colon_expression (tree_colon_expression *e);
+
+// Build a constant.
+static tree_constant *
+make_constant (int op, token *tok_val);
+
+// Build a function handle.
+static tree_fcn_handle *
+make_fcn_handle (token *tok_val);
+
+// Build an anonymous function handle.
+static tree_anon_fcn_handle *
+make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt);
+
+// Build a binary expression.
+static tree_expression *
+make_binary_op (int op, tree_expression *op1, token *tok_val,
+		tree_expression *op2);
+
+// Build a boolean expression.
+static tree_expression *
+make_boolean_op (int op, tree_expression *op1, token *tok_val,
+		 tree_expression *op2);
+
+// Build a prefix expression.
+static tree_expression *
+make_prefix_op (int op, tree_expression *op1, token *tok_val);
+
+// Build a postfix expression.
+static tree_expression *
+make_postfix_op (int op, tree_expression *op1, token *tok_val);
+
+// Build an unwind-protect command.
+static tree_command *
+make_unwind_command (token *unwind_tok, tree_statement_list *body,
+		     tree_statement_list *cleanup, token *end_tok,
+		     octave_comment_list *lc, octave_comment_list *mc);
+
+// Build a try-catch command.
+static tree_command *
+make_try_command (token *try_tok, tree_statement_list *body,
+		  tree_statement_list *cleanup, token *end_tok,
+		  octave_comment_list *lc, octave_comment_list *mc);
+
+// Build a while command.
+static tree_command *
+make_while_command (token *while_tok, tree_expression *expr,
+		    tree_statement_list *body, token *end_tok,
+		    octave_comment_list *lc);
+
+// Build a do-until command.
+static tree_command *
+make_do_until_command (token *until_tok, tree_statement_list *body,
+		       tree_expression *expr, octave_comment_list *lc);
+
+// Build a for command.
+static tree_command *
+make_for_command (token *for_tok, tree_argument_list *lhs,
+		  tree_expression *expr, tree_statement_list *body,
+		  token *end_tok, octave_comment_list *lc);
+
+// Build a break command.
+static tree_command *
+make_break_command (token *break_tok);
+
+// Build a continue command.
+static tree_command *
+make_continue_command (token *continue_tok);
+
+// Build a return command.
+static tree_command *
+make_return_command (token *return_tok);
+
+// Start an if command.
+static tree_if_command_list *
+start_if_command (tree_expression *expr, tree_statement_list *list);
+
+// Finish an if command.
+static tree_if_command *
+finish_if_command (token *if_tok, tree_if_command_list *list,
+		   token *end_tok, octave_comment_list *lc);
+
+// Build an elseif clause.
+static tree_if_clause *
+make_elseif_clause (token *elseif_tok, tree_expression *expr,
+		    tree_statement_list *list, octave_comment_list *lc);
+
+// Finish a switch command.
+static tree_switch_command *
+finish_switch_command (token *switch_tok, tree_expression *expr,
+		       tree_switch_case_list *list, token *end_tok,
+		       octave_comment_list *lc);
+
+// Build a switch case.
+static tree_switch_case *
+make_switch_case (token *case_tok, tree_expression *expr,
+		  tree_statement_list *list, octave_comment_list *lc);
+
+// Build an assignment to a variable.
+static tree_expression *
+make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
+		tree_expression *rhs);
+
+// Define a script.
+static void
+make_script (tree_statement_list *cmds, tree_statement *end_script);
+
+// Begin defining a function.
+static octave_user_function *
+start_function (tree_parameter_list *param_list, tree_statement_list *body,
+		tree_statement *end_function);
+
+// Create a no-op statement for end_function.
+static tree_statement *
+make_end (const std::string& type, int l, int c);
+
+// Do most of the work for defining a function.
+static octave_user_function *
+frob_function (const std::string& fname, octave_user_function *fcn);
+
+// Finish defining a function.
+static tree_function_def *
+finish_function (tree_parameter_list *ret_list,
+		 octave_user_function *fcn, octave_comment_list *lc);
+
+// Reset state after parsing function.
+static void
+recover_from_parsing_function (void);
+
+// Make an index expression.
+static tree_index_expression *
+make_index_expression (tree_expression *expr,
+		       tree_argument_list *args, char type);
+
+// Make an indirect reference expression.
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, const std::string&);
+
+// Make an indirect reference expression with dynamic field name.
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, tree_expression *field);
+
+// Make a declaration command.
+static tree_decl_command *
+make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst);
+
+// Finish building a matrix list.
+static tree_expression *
+finish_matrix (tree_matrix *m);
+
+// Finish building a cell list.
+static tree_expression *
+finish_cell (tree_cell *c);
+
+// Maybe print a warning.  Duh.
+static void
+maybe_warn_missing_semi (tree_statement_list *);
+
+// Set the print flag for a statement based on the separator type.
+static tree_statement_list *
+set_stmt_print_flag (tree_statement_list *, char, bool);
+
+// Create a statement list.
+static tree_statement_list *make_statement_list (tree_statement *stmt);
+
+// Append a statement to an existing statement list.
+static tree_statement_list *
+append_statement_list (tree_statement_list *list, char sep,
+		       tree_statement *stmt, bool warn_missing_semi);
+
+// Finish building a statement.
+template <class T>
+static tree_statement *
+make_statement (T *arg)
+{
+  octave_comment_list *comment = octave_comment_buffer::get_comment ();
+
+  return new tree_statement (arg, comment);
+}
+
+#define ABORT_PARSE \
+  do \
+    { \
+      global_command = 0; \
+      yyerrok; \
+      if (! symtab_context.empty ()) \
+        { \
+	  symbol_table::set_scope (symtab_context.top ()); \
+	  symtab_context.pop (); \
+        } \
+      if (interactive || forced_interactive) \
+	YYACCEPT; \
+      else \
+	YYABORT; \
+    } \
+  while (0)
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 364 "parse.y"
+{
+  // The type of the basic tokens returned by the lexer.
+  token *tok_val;
+
+  // Comment strings that we need to deal with mid-rule.
+  octave_comment_list *comment_type;
+
+  // Types for the nonterminals we generate.
+  char sep_type;
+  tree *tree_type;
+  tree_matrix *tree_matrix_type;
+  tree_cell *tree_cell_type;
+  tree_expression *tree_expression_type;
+  tree_constant *tree_constant_type;
+  tree_fcn_handle *tree_fcn_handle_type;
+  tree_anon_fcn_handle *tree_anon_fcn_handle_type;
+  tree_identifier *tree_identifier_type;
+  tree_index_expression *tree_index_expression_type;
+  tree_colon_expression *tree_colon_expression_type;
+  tree_argument_list *tree_argument_list_type;
+  tree_parameter_list *tree_parameter_list_type;
+  tree_command *tree_command_type;
+  tree_if_command *tree_if_command_type;
+  tree_if_clause *tree_if_clause_type;
+  tree_if_command_list *tree_if_command_list_type;
+  tree_switch_command *tree_switch_command_type;
+  tree_switch_case *tree_switch_case_type;
+  tree_switch_case_list *tree_switch_case_list_type;
+  tree_decl_elt *tree_decl_elt_type;
+  tree_decl_init_list *tree_decl_init_list_type;
+  tree_decl_command *tree_decl_command_type;
+  tree_statement *tree_statement_type;
+  tree_statement_list *tree_statement_list_type;
+  octave_user_function *octave_user_function_type;
+}
+/* Line 187 of yacc.c.  */
+#line 616 "parse.cc"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 629 "parse.cc"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  110
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   986
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  92
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  77
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  209
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  366
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   329
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      82,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      84,    91,     7,     6,    81,     5,    85,     8,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     4,    80,
+       2,     3,     2,     2,    90,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    87,     2,    88,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    86,     2,    89,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,
+      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,
+      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,
+      71,    72,    73,    74,    75,    76,    77,    78,    79,    83
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     5,     8,    10,    12,    14,    16,    19,
+      22,    25,    27,    31,    32,    34,    37,    39,    43,    45,
+      47,    49,    52,    54,    57,    59,    61,    63,    65,    67,
+      69,    72,    76,    80,    84,    86,    89,    91,    95,    98,
+     102,   106,   108,   111,   113,   117,   119,   122,   125,   129,
+     131,   133,   135,   137,   139,   143,   145,   147,   149,   153,
+     157,   159,   161,   165,   170,   174,   179,   182,   185,   188,
+     191,   195,   201,   203,   205,   208,   211,   214,   217,   220,
+     224,   228,   232,   236,   240,   244,   248,   252,   256,   260,
+     264,   268,   270,   272,   276,   278,   282,   286,   290,   294,
+     298,   302,   306,   310,   314,   318,   322,   326,   328,   332,
+     336,   340,   344,   348,   352,   356,   360,   364,   368,   372,
+     376,   380,   384,   388,   392,   394,   396,   398,   400,   402,
+     404,   406,   408,   410,   412,   413,   417,   421,   423,   426,
+     427,   429,   434,   436,   438,   443,   445,   448,   452,   455,
+     462,   467,   474,   475,   477,   480,   482,   485,   492,   497,
+     504,   511,   520,   531,   533,   535,   537,   547,   557,   563,
+     564,   566,   568,   572,   575,   576,   578,   580,   584,   587,
+     589,   593,   595,   599,   603,   607,   610,   615,   617,   620,
+     625,   629,   631,   633,   634,   636,   638,   640,   642,   645,
+     648,   649,   651,   653,   655,   657,   660,   663,   666,   667
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int16 yyrhs[] =
+{
+      93,     0,    -1,    94,    -1,    95,   164,    -1,   164,    -1,
+      82,    -1,    75,    -1,    95,    -1,    95,    82,    -1,    95,
+      75,    -1,    96,   166,    -1,   100,    -1,    96,   165,   100,
+      -1,    -1,    98,    -1,    99,   168,    -1,   100,    -1,    99,
+     167,   100,    -1,   127,    -1,   128,    -1,   101,    -1,   103,
+     102,    -1,   104,    -1,   102,   104,    -1,    51,    -1,    53,
+      -1,    54,    -1,    48,    -1,    49,    -1,   104,    -1,    87,
+      88,    -1,    87,    80,    88,    -1,    87,    81,    88,    -1,
+      87,   107,    88,    -1,   108,    -1,   108,    80,    -1,   112,
+      -1,   108,    80,   112,    -1,    86,    89,    -1,    86,    80,
+      89,    -1,    86,   110,    89,    -1,   111,    -1,   111,    80,
+      -1,   112,    -1,   111,    80,   112,    -1,   117,    -1,   117,
+      81,    -1,    90,    74,    -1,    90,   151,   100,    -1,   103,
+      -1,   105,    -1,   113,    -1,   106,    -1,   109,    -1,    84,
+     127,    91,    -1,     4,    -1,   127,    -1,   116,    -1,   117,
+      81,   116,    -1,   117,    81,   127,    -1,    85,    -1,   115,
+      -1,   119,    84,    91,    -1,   119,    84,   117,    91,    -1,
+     119,    86,    89,    -1,   119,    86,   117,    89,    -1,   119,
+      44,    -1,   119,    45,    -1,   119,    42,    -1,   119,    43,
+      -1,   119,   118,    50,    -1,   119,   118,    84,   127,    91,
+      -1,   119,    -1,   121,    -1,    44,   120,    -1,    45,   120,
+      -1,    29,   120,    -1,     6,   120,    -1,     5,   120,    -1,
+     120,    46,   120,    -1,   120,    47,   120,    -1,   120,     6,
+     120,    -1,   120,     5,   120,    -1,   120,     7,   120,    -1,
+     120,     8,   120,    -1,   120,    40,   120,    -1,   120,    41,
+     120,    -1,   120,    37,   120,    -1,   120,    38,   120,    -1,
+     120,    36,   120,    -1,   120,    39,   120,    -1,   123,    -1,
+     120,    -1,   123,     4,   120,    -1,   122,    -1,   124,    23,
+     124,    -1,   124,    24,   124,    -1,   124,    30,   124,    -1,
+     124,    31,   124,    -1,   124,    32,   124,    -1,   124,    34,
+     124,    -1,   124,    35,   124,    -1,   124,    33,   124,    -1,
+     124,    27,   124,    -1,   124,    28,   124,    -1,   124,    25,
+     124,    -1,   124,    26,   124,    -1,   124,    -1,    87,   117,
+      79,    -1,   125,     3,   127,    -1,   125,     9,   127,    -1,
+     125,    10,   127,    -1,   125,    11,   127,    -1,   125,    12,
+     127,    -1,   125,    13,   127,    -1,   125,    14,   127,    -1,
+     125,    21,   127,    -1,   125,    22,   127,    -1,   125,    15,
+     127,    -1,   125,    16,   127,    -1,   125,    17,   127,    -1,
+     125,    18,   127,    -1,   125,    19,   127,    -1,   125,    20,
+     127,    -1,   124,    -1,   126,    -1,   114,    -1,   130,    -1,
+     134,    -1,   145,    -1,   146,    -1,   147,    -1,   158,    -1,
+     156,    -1,    -1,    72,   129,   131,    -1,    73,   129,   131,
+      -1,   133,    -1,   131,   133,    -1,    -1,   103,    -1,   103,
+       3,   132,   127,    -1,   135,    -1,   140,    -1,    59,   163,
+     136,    52,    -1,   137,    -1,   137,   139,    -1,   127,   168,
+      97,    -1,   137,   138,    -1,    60,   163,   168,   127,   168,
+      97,    -1,    61,   163,   168,    97,    -1,    62,   163,   127,
+     168,   141,    52,    -1,    -1,   142,    -1,   142,   144,    -1,
+     143,    -1,   142,   143,    -1,    63,   163,   168,   127,   168,
+      97,    -1,    64,   163,   168,    97,    -1,    56,   163,   127,
+     168,    97,    52,    -1,    57,   163,   168,    97,    58,   127,
+      -1,    55,   163,   125,     3,   127,   168,    97,    52,    -1,
+      55,   163,    84,   125,     3,   127,    91,   168,    97,    52,
+      -1,    65,    -1,    66,    -1,    67,    -1,    68,   163,   168,
+      97,    69,   163,   168,    97,    52,    -1,    70,   163,   168,
+      97,    71,   163,   168,    97,    52,    -1,    70,   163,   168,
+      97,    52,    -1,    -1,    84,    -1,    91,    -1,   149,   152,
+     150,    -1,   149,     1,    -1,    -1,   153,    -1,   133,    -1,
+     153,    81,   133,    -1,    87,    88,    -1,   155,    -1,    87,
+     155,    88,    -1,   103,    -1,   155,    81,   103,    -1,    78,
+      97,    75,    -1,   148,    77,   163,    -1,   157,   160,    -1,
+     157,   154,     3,   160,    -1,   103,    -1,   159,   161,    -1,
+     151,   168,    97,   162,    -1,   168,    97,   162,    -1,    52,
+      -1,    75,    -1,    -1,    76,    -1,     1,    -1,    81,    -1,
+      80,    -1,   165,    81,    -1,   165,    80,    -1,    -1,   165,
+      -1,    81,    -1,    80,    -1,    82,    -1,   167,    81,    -1,
+     167,    80,    -1,   167,    82,    -1,    -1,   167,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   491,   491,   497,   499,   503,   505,   510,   512,   514,
+     518,   522,   524,   529,   530,   534,   538,   540,   544,   546,
+     548,   560,   564,   566,   577,   584,   586,   590,   592,   594,
+     598,   604,   610,   616,   624,   626,   630,   632,   639,   641,
+     643,   647,   649,   653,   655,   663,   665,   669,   676,   680,
+     682,   684,   686,   688,   690,   694,   701,   703,   705,   710,
+     717,   721,   723,   725,   727,   729,   731,   733,   735,   737,
+     739,   741,   745,   747,   749,   751,   753,   755,   757,   761,
+     763,   765,   767,   769,   771,   773,   775,   777,   779,   781,
+     783,   787,   791,   793,   800,   802,   804,   806,   808,   810,
+     812,   814,   816,   818,   820,   822,   824,   831,   836,   850,
+     852,   854,   856,   858,   860,   862,   864,   866,   868,   870,
+     872,   874,   876,   878,   882,   884,   886,   894,   896,   898,
+     900,   902,   904,   906,   916,   918,   923,   930,   932,   940,
+     942,   944,   955,   957,   965,   972,   974,   981,   983,   990,
+     994,  1002,  1010,  1011,  1013,  1020,  1022,  1029,  1033,  1043,
+    1048,  1053,  1058,  1069,  1074,  1079,  1090,  1096,  1102,  1114,
+    1127,  1140,  1147,  1152,  1161,  1162,  1172,  1174,  1185,  1190,
+    1198,  1208,  1210,  1221,  1237,  1241,  1246,  1253,  1268,  1279,
+    1281,  1285,  1292,  1311,  1314,  1316,  1319,  1321,  1323,  1325,
+    1330,  1331,  1335,  1337,  1339,  1341,  1343,  1345,  1350,  1351
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "'='", "':'", "'-'", "'+'", "'*'", "'/'",
+  "ADD_EQ", "SUB_EQ", "MUL_EQ", "DIV_EQ", "LEFTDIV_EQ", "POW_EQ",
+  "EMUL_EQ", "EDIV_EQ", "ELEFTDIV_EQ", "EPOW_EQ", "AND_EQ", "OR_EQ",
+  "LSHIFT_EQ", "RSHIFT_EQ", "LSHIFT", "RSHIFT", "EXPR_AND_AND",
+  "EXPR_OR_OR", "EXPR_AND", "EXPR_OR", "EXPR_NOT", "EXPR_LT", "EXPR_LE",
+  "EXPR_EQ", "EXPR_NE", "EXPR_GE", "EXPR_GT", "LEFTDIV", "EMUL", "EDIV",
+  "ELEFTDIV", "EPLUS", "EMINUS", "QUOTE", "TRANSPOSE", "PLUS_PLUS",
+  "MINUS_MINUS", "POW", "EPOW", "NUM", "IMAG_NUM", "STRUCT_ELT", "NAME",
+  "END", "DQ_STRING", "SQ_STRING", "FOR", "WHILE", "DO", "UNTIL", "IF",
+  "ELSEIF", "ELSE", "SWITCH", "CASE", "OTHERWISE", "BREAK", "CONTINUE",
+  "FUNC_RET", "UNWIND", "CLEANUP", "TRY", "CATCH", "GLOBAL", "STATIC",
+  "FCN_HANDLE", "END_OF_INPUT", "LEXICAL_ERROR", "FCN", "SCRIPT",
+  "CLOSE_BRACE", "';'", "','", "'\\n'", "UNARY", "'('", "'.'", "'{'",
+  "'['", "']'", "'}'", "'@'", "')'", "$accept", "input", "input1",
+  "simple_list", "simple_list1", "opt_list", "list", "list1", "statement",
+  "word_list_cmd", "word_list", "identifier", "string", "constant",
+  "matrix", "matrix_rows", "matrix_rows1", "cell", "cell_rows",
+  "cell_rows1", "cell_or_matrix_row", "fcn_handle", "anon_fcn_handle",
+  "primary_expr", "magic_colon", "arg_list", "indirect_ref_op",
+  "postfix_expr", "prefix_expr", "binary_expr", "colon_expr",
+  "colon_expr1", "simple_expr", "assign_lhs", "assign_expr", "expression",
+  "command", "parsing_decl_list", "declaration", "decl1",
+  "decl_param_init", "decl2", "select_command", "if_command",
+  "if_cmd_list", "if_cmd_list1", "elseif_clause", "else_clause",
+  "switch_command", "case_list", "case_list1", "switch_case",
+  "default_case", "loop_command", "jump_command", "except_command",
+  "push_fcn_symtab", "param_list_beg", "param_list_end", "param_list",
+  "param_list1", "param_list2", "return_list", "return_list1", "script",
+  "function_beg", "function", "fcn_name", "function1", "function2",
+  "function_end", "stash_comment", "parse_error", "sep_no_nl",
+  "opt_sep_no_nl", "sep", "opt_sep", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,    61,    58,    45,    43,    42,    47,   258,
+     259,   260,   261,   262,   263,   264,   265,   266,   267,   268,
+     269,   270,   271,   272,   273,   274,   275,   276,   277,   278,
+     279,   280,   281,   282,   283,   284,   285,   286,   287,   288,
+     289,   290,   291,   292,   293,   294,   295,   296,   297,   298,
+     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
+     309,   310,   311,   312,   313,   314,   315,   316,   317,   318,
+     319,   320,   321,   322,   323,   324,   325,   326,   327,   328,
+      59,    44,    10,   329,    40,    46,   123,    91,    93,   125,
+      64,    41
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    92,    93,    93,    93,    94,    94,    94,    94,    94,
+      95,    96,    96,    97,    97,    98,    99,    99,   100,   100,
+     100,   101,   102,   102,   103,   104,   104,   105,   105,   105,
+     106,   106,   106,   106,   107,   107,   108,   108,   109,   109,
+     109,   110,   110,   111,   111,   112,   112,   113,   114,   115,
+     115,   115,   115,   115,   115,   116,   117,   117,   117,   117,
+     118,   119,   119,   119,   119,   119,   119,   119,   119,   119,
+     119,   119,   120,   120,   120,   120,   120,   120,   120,   121,
+     121,   121,   121,   121,   121,   121,   121,   121,   121,   121,
+     121,   122,   123,   123,   124,   124,   124,   124,   124,   124,
+     124,   124,   124,   124,   124,   124,   124,   125,   125,   126,
+     126,   126,   126,   126,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   127,   127,   127,   128,   128,   128,
+     128,   128,   128,   128,   129,   130,   130,   131,   131,   132,
+     133,   133,   134,   134,   135,   136,   136,   137,   137,   138,
+     139,   140,   141,   141,   141,   142,   142,   143,   144,   145,
+     145,   145,   145,   146,   146,   146,   147,   147,   147,   148,
+     149,   150,   151,   151,   152,   152,   153,   153,   154,   154,
+     154,   155,   155,   156,   157,   158,   158,   159,   160,   161,
+     161,   162,   162,   163,   164,   164,   165,   165,   165,   165,
+     166,   166,   167,   167,   167,   167,   167,   167,   168,   168
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     1,     2,     1,     1,     1,     1,     2,     2,
+       2,     1,     3,     0,     1,     2,     1,     3,     1,     1,
+       1,     2,     1,     2,     1,     1,     1,     1,     1,     1,
+       2,     3,     3,     3,     1,     2,     1,     3,     2,     3,
+       3,     1,     2,     1,     3,     1,     2,     2,     3,     1,
+       1,     1,     1,     1,     3,     1,     1,     1,     3,     3,
+       1,     1,     3,     4,     3,     4,     2,     2,     2,     2,
+       3,     5,     1,     1,     2,     2,     2,     2,     2,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     1,     1,     3,     1,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     1,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     0,     3,     3,     1,     2,     0,
+       1,     4,     1,     1,     4,     1,     2,     3,     2,     6,
+       4,     6,     0,     1,     2,     1,     2,     6,     4,     6,
+       6,     8,    10,     1,     1,     1,     9,     9,     5,     0,
+       1,     1,     3,     2,     0,     1,     1,     3,     2,     1,
+       3,     1,     3,     3,     3,     2,     4,     1,     2,     4,
+       3,     1,     1,     0,     1,     1,     1,     1,     2,     2,
+       0,     1,     1,     1,     1,     2,     2,     2,     0,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       0,   195,     0,     0,     0,     0,     0,    27,    28,    24,
+      25,    26,   193,   193,   193,   193,   193,   163,   164,   165,
+     193,   193,   134,   134,     6,   194,    13,     5,     0,     0,
+       0,     0,     0,     2,     0,   200,    11,    20,    49,    29,
+      50,    52,    53,    51,   126,    61,    72,    92,    73,    94,
+      91,   124,     0,   125,    18,    19,   127,   128,   142,   143,
+     129,   130,   131,     0,   133,     0,   132,     4,     0,     0,
+      49,    78,    77,    76,    74,    75,     0,     0,   208,     0,
+       0,   208,   208,     0,     0,     0,    14,   208,    16,     0,
+      55,     0,    38,     0,    41,    43,    57,    45,    56,     0,
+       0,    30,     0,    34,    36,    45,    47,   170,     0,   169,
+       1,     9,     8,     3,   197,   196,   201,    10,    21,    22,
+      68,    69,    66,    67,     0,    60,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   193,     0,
+     187,     0,   179,   208,   185,     0,   107,     0,   208,   203,
+     202,   204,   209,    13,   208,     0,   145,   208,    13,    13,
+     140,   135,   137,   136,   183,   209,    15,    54,    39,    40,
+      42,    46,    31,    32,    33,    35,   108,   173,   176,     0,
+     175,    48,   199,   198,    12,    23,    62,     0,    64,     0,
+      70,     0,    82,    81,    83,    84,    89,    87,    88,    90,
+      85,    86,    79,    80,    93,    95,    96,   105,   106,   103,
+     104,    97,    98,    99,   102,   100,   101,   109,   110,   111,
+     112,   113,   114,   115,   118,   119,   120,   121,   122,   123,
+     116,   117,   184,   178,   181,     0,     0,     0,   208,   188,
+      13,     0,     0,    13,   206,   205,   207,     0,    13,   144,
+     193,   193,   148,   146,   152,     0,     0,   139,   138,    17,
+      44,    58,    59,    37,   171,   172,     0,     0,    63,    65,
+       0,   180,   187,   186,   182,    13,     0,     0,   208,     0,
+       0,   147,   208,   208,   193,     0,   153,   155,   193,   168,
+     193,     0,   177,    71,     0,   191,   192,   190,     0,    13,
+     159,   160,     0,    13,   208,   151,   193,   156,   154,   208,
+     208,   141,   189,   208,     0,   208,   150,     0,   208,    13,
+      13,    13,   161,    13,   208,    13,     0,     0,     0,   149,
+      13,   158,   166,   167,   162,   157
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,    32,    33,    34,    35,    85,    86,    87,    88,    37,
+     118,    70,    39,    40,    41,   102,   103,    42,    93,    94,
+     104,    43,    44,    45,    96,    97,   127,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    83,    56,   191,
+     321,   192,    57,    58,   185,   186,   282,   283,    59,   315,
+     316,   317,   338,    60,    61,    62,    63,   108,   295,   109,
+     209,   210,   171,   172,    64,    65,    66,   173,   174,   269,
+     327,    76,    67,   116,   117,   182,   183
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -191
+static const yytype_int16 yypact[] =
+{
+     351,  -191,   843,   843,   843,   843,   843,  -191,  -191,  -191,
+    -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,
+    -191,  -191,  -191,  -191,  -191,  -191,   705,  -191,   857,   438,
+     426,   -54,    29,  -191,    42,   -36,  -191,  -191,    23,  -191,
+    -191,  -191,  -191,  -191,  -191,  -191,   -11,   561,  -191,  -191,
+      62,   951,   539,  -191,  -191,  -191,  -191,  -191,  -191,  -191,
+    -191,  -191,  -191,    -5,  -191,   -29,  -191,  -191,   426,    11,
+    -191,    76,    76,    76,    76,    76,   869,   857,   -57,   857,
+     857,   -57,   -57,    31,    31,    21,  -191,   -57,  -191,     9,
+    -191,    40,  -191,    63,    73,  -191,  -191,    39,  -191,    79,
+      80,  -191,    82,    91,  -191,    34,  -191,  -191,    20,   774,
+    -191,  -191,  -191,  -191,  -191,  -191,   636,  -191,    23,  -191,
+    -191,  -191,  -191,  -191,     8,  -191,   490,   -15,   843,   843,
+     843,   843,   843,   843,   843,   843,   843,   843,   843,   843,
+     843,   843,   843,   843,   843,   843,   843,   843,   843,   843,
+     843,   843,   843,   857,   857,   857,   857,   857,   857,   857,
+     857,   857,   857,   857,   857,   857,   857,   857,  -191,   -24,
+      12,   169,    92,     6,  -191,   857,   712,   171,   -57,  -191,
+    -191,  -191,    45,   705,   -57,   126,    84,   -57,   705,   705,
+     173,    31,  -191,    31,  -191,   567,  -191,  -191,  -191,  -191,
+     541,   541,  -191,  -191,  -191,   541,  -191,  -191,  -191,    88,
+     101,  -191,  -191,  -191,  -191,  -191,  -191,   -13,  -191,   -53,
+    -191,   857,   252,   252,    76,    76,    76,    76,    76,    76,
+     252,   252,  -191,  -191,   561,  -191,  -191,   131,   307,    16,
+     354,   124,   124,   124,   124,   124,   124,  -191,  -191,  -191,
+    -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,
+    -191,  -191,  -191,  -191,  -191,   -18,    31,    31,   -57,  -191,
+     705,   657,   857,   705,  -191,  -191,  -191,   122,   705,  -191,
+    -191,  -191,  -191,  -191,   121,   116,   -33,  -191,  -191,  -191,
+    -191,  -191,  -191,  -191,  -191,  -191,    31,   541,  -191,  -191,
+      96,  -191,  -191,  -191,  -191,   705,   -34,   857,   -57,   138,
+     857,  -191,   -57,   -57,  -191,   140,    86,  -191,  -191,  -191,
+    -191,   857,  -191,  -191,   -34,  -191,  -191,  -191,   105,   705,
+    -191,  -191,   857,   705,   -57,  -191,  -191,  -191,  -191,   -57,
+     -57,  -191,  -191,   -57,   146,   -57,  -191,   857,   -57,   705,
+     705,   705,  -191,   705,   -57,   705,   147,   149,   167,  -191,
+     705,  -191,  -191,  -191,  -191,  -191
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -191,  -191,  -191,  -191,  -191,    14,  -191,  -191,     5,  -191,
+    -191,     0,   -21,  -191,  -191,  -191,  -191,  -191,  -191,  -191,
+     -19,  -191,  -191,  -191,  -190,   -14,  -191,  -191,    99,  -191,
+    -191,  -191,    -9,   -69,  -191,    51,  -191,   197,  -191,   137,
+    -191,  -102,  -191,  -191,  -191,  -191,  -191,  -191,  -191,  -191,
+    -191,   -94,  -191,  -191,  -191,  -191,  -191,  -191,  -191,    50,
+    -191,  -191,  -191,    55,  -191,  -191,  -191,  -191,   -41,  -191,
+     -84,   -12,   208,  -191,  -191,   156,   -27
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -182
+static const yytype_int16 yytable[] =
+{
+      38,    77,    78,    79,    80,    36,   208,   177,    81,    82,
+      95,   291,    90,     2,     3,  -181,   105,   119,   325,   319,
+     106,   207,     9,   179,   180,   181,    38,     9,   297,   110,
+     107,   120,   121,   122,   123,   220,   299,     4,   320,   141,
+     142,   326,    -7,     1,   114,   115,   147,   148,   149,   150,
+     151,   152,     5,     6,   188,   189,     7,     8,   169,     9,
+     196,    10,    11,   267,   263,   170,   140,   176,   297,   221,
+     301,     9,   168,   124,   125,   126,    10,    11,   298,    89,
+      98,    98,     9,   190,   190,   106,   179,   180,   181,   288,
+     107,   288,    28,  -181,    29,    30,   194,   215,    31,   216,
+     197,    71,    72,    73,    74,    75,   271,   291,   190,    38,
+     217,  -174,   219,   206,   211,   201,    38,   111,    25,    98,
+     201,   214,   138,   139,   112,   274,   275,   276,   178,   198,
+     184,   187,   235,   236,   237,   238,   239,   240,   241,   242,
+     243,   244,   245,   246,   280,   281,   270,   141,   142,   314,
+     336,   273,   199,   200,   141,   142,   262,   278,   145,   146,
+     284,   147,   148,   149,   150,   151,   152,   202,   203,   264,
+     204,   205,   266,   267,   272,    98,   287,    98,   279,   294,
+     310,   290,   296,    38,   314,   318,   293,   323,    38,    38,
+     330,   190,   335,   190,   322,    38,   343,   277,   352,   362,
+     289,   363,   285,   286,   247,   248,   249,   250,   251,   252,
+     253,   254,   255,   256,   257,   258,   259,   260,   261,   364,
+      84,   193,   337,   268,   265,   303,    89,   222,   223,   224,
+     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
+     342,   305,   113,   195,     0,     0,     0,     0,     0,     0,
+       0,    98,   292,     0,     0,     0,    98,     0,     0,   130,
+     131,     0,     0,     0,     0,     0,   302,   304,   312,   313,
+      38,     0,   300,    38,     0,     0,     0,     0,    38,     0,
+       0,   329,     0,     0,   306,   332,   333,   309,   132,   133,
+     134,   135,   311,     0,     0,     0,   190,     0,   138,   139,
+       0,     0,   334,     0,     0,    38,   339,   347,   340,     0,
+       0,     0,   349,   350,     0,     0,   351,     0,   353,   324,
+       0,   355,     0,   308,   348,     0,     0,   360,     0,    38,
+     141,   142,   143,    38,   145,   146,     0,   147,   148,   149,
+     150,   151,   152,   344,     0,     0,     0,   346,   292,    38,
+      38,    38,     1,    38,     0,    38,     2,     3,   328,     0,
+      38,   331,     0,   356,   357,   358,     0,   359,     0,   361,
+       0,     0,   341,     0,   365,     0,     0,   141,   142,     0,
+       4,   145,     0,   345,   147,   148,   149,   150,   151,   152,
+       0,     0,     0,     0,     0,     5,     6,     0,   354,     7,
+       8,     0,     9,     0,    10,    11,    12,    13,    14,     0,
+      15,     0,     0,    16,     0,     0,    17,    18,    19,    20,
+       0,    21,     0,    22,    23,     0,    24,    25,  -169,    26,
+      90,     2,     3,    27,     0,    28,     0,    29,    30,     0,
+       0,    31,    90,     2,     3,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     4,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     4,     0,     0,
+       5,     6,     0,     0,     7,     8,     0,     9,     0,    10,
+      11,     0,     5,     6,     0,     0,     7,     8,     0,     9,
+       0,    10,    11,     0,    90,     2,     3,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    99,   100,     0,     0,
+      28,     0,    29,    30,   101,     0,    31,     0,    91,     4,
+       0,     0,    28,     0,    29,    30,     0,    92,    31,     0,
+       0,     0,     0,     0,     5,     6,     0,     0,     7,     8,
+       0,     9,   153,    10,    11,    90,     2,     3,   154,   155,
+     156,   157,   158,   159,   160,   161,   162,   163,   164,   165,
+     166,   167,     0,     0,     0,     0,   128,   129,   130,   131,
+       4,     0,     2,     3,    28,     0,    29,    30,     0,   218,
+      31,     0,     0,     0,     0,     5,     6,     0,     0,     7,
+       8,     0,     9,     0,    10,    11,     4,   132,   133,   134,
+     135,   136,   137,     0,     0,     0,     0,   138,   139,     0,
+       0,     5,     6,     0,     0,     7,     8,     0,     9,     0,
+      10,    11,    12,    13,    14,    28,    15,    29,    30,    16,
+       0,    31,    17,    18,    19,    20,     0,    21,     0,    22,
+      23,     2,     3,     0,  -169,    26,     0,   274,   275,   276,
+       0,    28,     0,    29,    30,     0,     0,    31,     0,     0,
+     307,     0,     0,     0,     0,     4,   154,   155,   156,   157,
+     158,   159,   160,   161,   162,   163,   164,   165,   166,   167,
+       5,     6,     0,     0,     7,     8,     0,     9,     0,    10,
+      11,    12,    13,    14,     0,    15,     0,     0,    16,     0,
+       0,    17,    18,    19,    20,     0,    21,     0,    22,    23,
+       2,     3,     0,  -169,    26,     0,   212,   213,     0,     0,
+      28,     0,    29,    30,     0,     0,    31,     0,     0,     0,
+       0,     0,     0,     0,     4,   141,   142,   143,   144,   145,
+     146,     0,   147,   148,   149,   150,   151,   152,     0,     5,
+       6,     0,     0,     7,     8,     0,     9,     0,    10,    11,
+      12,    13,    14,     0,    15,     0,     0,    16,     0,     0,
+      17,    18,    19,    20,     0,    21,     0,    22,    23,     2,
+       3,     0,  -169,    26,     0,     0,     0,     0,     0,    28,
+       0,    29,    30,     0,     0,    31,     0,     0,     0,     0,
+       0,     0,     0,     4,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     5,     6,
+       0,     0,     7,     8,     0,     9,     0,    10,    11,    12,
+      13,    14,     0,    15,     0,     0,    16,     0,     0,    17,
+      18,    19,    20,     0,    21,     0,    22,    23,     2,     3,
+       0,     0,    26,     0,     0,     0,     0,     0,    28,     0,
+      29,    30,     2,     3,    31,     0,     0,     0,     0,     0,
+       0,     0,     4,     0,     2,     3,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     4,     5,     6,     0,
+       0,     7,     8,     0,     9,     0,    10,    11,     4,     0,
+       0,     5,     6,     0,     0,     7,     8,     0,     9,     0,
+      10,    11,     0,     5,     6,     0,     0,     7,     8,     0,
+       9,     0,    10,    11,     0,     0,     0,    28,     0,    29,
+      68,     0,     0,    69,     0,     0,     0,     0,     0,     0,
+       0,    28,     0,    29,    30,     0,     0,    31,     0,     0,
+       0,     0,     0,   175,  -107,    29,    30,     0,     0,    69,
+    -107,  -107,  -107,  -107,  -107,  -107,  -107,  -107,  -107,  -107,
+    -107,  -107,  -107,  -107,   141,   142,   143,   144,   145,   146,
+       0,   147,   148,   149,   150,   151,   152
+};
+
+static const yytype_int16 yycheck[] =
+{
+       0,    13,    14,    15,    16,     0,   108,    76,    20,    21,
+      29,   201,     4,     5,     6,     3,    30,    38,    52,    52,
+      74,     1,    51,    80,    81,    82,    26,    51,    81,     0,
+      84,    42,    43,    44,    45,    50,    89,    29,    71,    23,
+      24,    75,     0,     1,    80,    81,    30,    31,    32,    33,
+      34,    35,    44,    45,    81,    82,    48,    49,    87,    51,
+      87,    53,    54,    81,    88,    65,     4,    76,    81,    84,
+      88,    51,    77,    84,    85,    86,    53,    54,    91,    28,
+      29,    30,    51,    83,    84,    74,    80,    81,    82,   191,
+      84,   193,    84,    81,    86,    87,    75,   118,    90,    91,
+      91,     2,     3,     4,     5,     6,   175,   297,   108,   109,
+     124,    91,   126,    79,   109,    81,   116,    75,    76,    68,
+      81,   116,    46,    47,    82,    80,    81,    82,    77,    89,
+      79,    80,   141,   142,   143,   144,   145,   146,   147,   148,
+     149,   150,   151,   152,    60,    61,   173,    23,    24,    63,
+      64,   178,    89,    80,    23,    24,   168,   184,    27,    28,
+     187,    30,    31,    32,    33,    34,    35,    88,    88,   169,
+      88,    80,     3,    81,     3,   124,     3,   126,    52,    91,
+      58,   200,    81,   183,    63,    69,   205,    91,   188,   189,
+      52,   191,    52,   193,   296,   195,    91,   183,    52,    52,
+     195,    52,   188,   189,   153,   154,   155,   156,   157,   158,
+     159,   160,   161,   162,   163,   164,   165,   166,   167,    52,
+      23,    84,   316,   173,   169,   266,   175,   128,   129,   130,
+     131,   132,   133,   134,   135,   136,   137,   138,   139,   140,
+     324,   268,    34,    87,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   200,   201,    -1,    -1,    -1,   205,    -1,    -1,     7,
+       8,    -1,    -1,    -1,    -1,    -1,   266,   267,   280,   281,
+     270,    -1,   221,   273,    -1,    -1,    -1,    -1,   278,    -1,
+      -1,   308,    -1,    -1,   270,   312,   313,   273,    36,    37,
+      38,    39,   278,    -1,    -1,    -1,   296,    -1,    46,    47,
+      -1,    -1,   314,    -1,    -1,   305,   318,   334,   320,    -1,
+      -1,    -1,   339,   340,    -1,    -1,   343,    -1,   345,   305,
+      -1,   348,    -1,   272,   336,    -1,    -1,   354,    -1,   329,
+      23,    24,    25,   333,    27,    28,    -1,    30,    31,    32,
+      33,    34,    35,   329,    -1,    -1,    -1,   333,   297,   349,
+     350,   351,     1,   353,    -1,   355,     5,     6,   307,    -1,
+     360,   310,    -1,   349,   350,   351,    -1,   353,    -1,   355,
+      -1,    -1,   321,    -1,   360,    -1,    -1,    23,    24,    -1,
+      29,    27,    -1,   332,    30,    31,    32,    33,    34,    35,
+      -1,    -1,    -1,    -1,    -1,    44,    45,    -1,   347,    48,
+      49,    -1,    51,    -1,    53,    54,    55,    56,    57,    -1,
+      59,    -1,    -1,    62,    -1,    -1,    65,    66,    67,    68,
+      -1,    70,    -1,    72,    73,    -1,    75,    76,    77,    78,
+       4,     5,     6,    82,    -1,    84,    -1,    86,    87,    -1,
+      -1,    90,     4,     5,     6,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    29,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    29,    -1,    -1,
+      44,    45,    -1,    -1,    48,    49,    -1,    51,    -1,    53,
+      54,    -1,    44,    45,    -1,    -1,    48,    49,    -1,    51,
+      -1,    53,    54,    -1,     4,     5,     6,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    80,    81,    -1,    -1,
+      84,    -1,    86,    87,    88,    -1,    90,    -1,    80,    29,
+      -1,    -1,    84,    -1,    86,    87,    -1,    89,    90,    -1,
+      -1,    -1,    -1,    -1,    44,    45,    -1,    -1,    48,    49,
+      -1,    51,     3,    53,    54,     4,     5,     6,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    -1,    -1,    -1,    -1,     5,     6,     7,     8,
+      29,    -1,     5,     6,    84,    -1,    86,    87,    -1,    89,
+      90,    -1,    -1,    -1,    -1,    44,    45,    -1,    -1,    48,
+      49,    -1,    51,    -1,    53,    54,    29,    36,    37,    38,
+      39,    40,    41,    -1,    -1,    -1,    -1,    46,    47,    -1,
+      -1,    44,    45,    -1,    -1,    48,    49,    -1,    51,    -1,
+      53,    54,    55,    56,    57,    84,    59,    86,    87,    62,
+      -1,    90,    65,    66,    67,    68,    -1,    70,    -1,    72,
+      73,     5,     6,    -1,    77,    78,    -1,    80,    81,    82,
+      -1,    84,    -1,    86,    87,    -1,    -1,    90,    -1,    -1,
+       3,    -1,    -1,    -1,    -1,    29,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      44,    45,    -1,    -1,    48,    49,    -1,    51,    -1,    53,
+      54,    55,    56,    57,    -1,    59,    -1,    -1,    62,    -1,
+      -1,    65,    66,    67,    68,    -1,    70,    -1,    72,    73,
+       5,     6,    -1,    77,    78,    -1,    80,    81,    -1,    -1,
+      84,    -1,    86,    87,    -1,    -1,    90,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    29,    23,    24,    25,    26,    27,
+      28,    -1,    30,    31,    32,    33,    34,    35,    -1,    44,
+      45,    -1,    -1,    48,    49,    -1,    51,    -1,    53,    54,
+      55,    56,    57,    -1,    59,    -1,    -1,    62,    -1,    -1,
+      65,    66,    67,    68,    -1,    70,    -1,    72,    73,     5,
+       6,    -1,    77,    78,    -1,    -1,    -1,    -1,    -1,    84,
+      -1,    86,    87,    -1,    -1,    90,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    44,    45,
+      -1,    -1,    48,    49,    -1,    51,    -1,    53,    54,    55,
+      56,    57,    -1,    59,    -1,    -1,    62,    -1,    -1,    65,
+      66,    67,    68,    -1,    70,    -1,    72,    73,     5,     6,
+      -1,    -1,    78,    -1,    -1,    -1,    -1,    -1,    84,    -1,
+      86,    87,     5,     6,    90,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    29,    -1,     5,     6,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    29,    44,    45,    -1,
+      -1,    48,    49,    -1,    51,    -1,    53,    54,    29,    -1,
+      -1,    44,    45,    -1,    -1,    48,    49,    -1,    51,    -1,
+      53,    54,    -1,    44,    45,    -1,    -1,    48,    49,    -1,
+      51,    -1,    53,    54,    -1,    -1,    -1,    84,    -1,    86,
+      87,    -1,    -1,    90,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    84,    -1,    86,    87,    -1,    -1,    90,    -1,    -1,
+      -1,    -1,    -1,    84,     3,    86,    87,    -1,    -1,    90,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      -1,    30,    31,    32,    33,    34,    35
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     1,     5,     6,    29,    44,    45,    48,    49,    51,
+      53,    54,    55,    56,    57,    59,    62,    65,    66,    67,
+      68,    70,    72,    73,    75,    76,    78,    82,    84,    86,
+      87,    90,    93,    94,    95,    96,   100,   101,   103,   104,
+     105,   106,   109,   113,   114,   115,   119,   120,   121,   122,
+     123,   124,   125,   126,   127,   128,   130,   134,   135,   140,
+     145,   146,   147,   148,   156,   157,   158,   164,    87,    90,
+     103,   120,   120,   120,   120,   120,   163,   163,   163,   163,
+     163,   163,   163,   129,   129,    97,    98,    99,   100,   127,
+       4,    80,    89,   110,   111,   112,   116,   117,   127,    80,
+      81,    88,   107,   108,   112,   117,    74,    84,   149,   151,
+       0,    75,    82,   164,    80,    81,   165,   166,   102,   104,
+      42,    43,    44,    45,    84,    85,    86,   118,     5,     6,
+       7,     8,    36,    37,    38,    39,    40,    41,    46,    47,
+       4,    23,    24,    25,    26,    27,    28,    30,    31,    32,
+      33,    34,    35,     3,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    77,    87,
+     103,   154,   155,   159,   160,    84,   124,   125,   127,    80,
+      81,    82,   167,   168,   127,   136,   137,   127,   168,   168,
+     103,   131,   133,   131,    75,   167,   168,    91,    89,    89,
+      80,    81,    88,    88,    88,    80,    79,     1,   133,   152,
+     153,   100,    80,    81,   100,   104,    91,   117,    89,   117,
+      50,    84,   120,   120,   120,   120,   120,   120,   120,   120,
+     120,   120,   120,   120,   120,   124,   124,   124,   124,   124,
+     124,   124,   124,   124,   124,   124,   124,   127,   127,   127,
+     127,   127,   127,   127,   127,   127,   127,   127,   127,   127,
+     127,   127,   163,    88,   103,   155,     3,    81,   151,   161,
+     168,   125,     3,   168,    80,    81,    82,    97,   168,    52,
+      60,    61,   138,   139,   168,    97,    97,     3,   133,   100,
+     112,   116,   127,   112,    91,   150,    81,    81,    91,    89,
+     127,    88,   103,   160,   103,   168,    97,     3,   127,    97,
+      58,    97,   163,   163,    63,   141,   142,   143,    69,    52,
+      71,   132,   133,    91,    97,    52,    75,   162,   127,   168,
+      52,   127,   168,   168,   163,    52,    64,   143,   144,   163,
+     163,   127,   162,    91,    97,   127,    97,   168,   163,   168,
+     168,   168,    52,   168,   127,   168,    97,    97,    97,    97,
+     168,    97,    52,    52,    52,    97
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+	break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 492 "parse.y"
+    {
+		    global_command = (yyvsp[(1) - (1)].tree_statement_list_type);
+		    promptflag = 1;
+		    YYACCEPT;
+		  }
+    break;
+
+  case 3:
+#line 498 "parse.y"
+    { ABORT_PARSE; }
+    break;
+
+  case 4:
+#line 500 "parse.y"
+    { ABORT_PARSE; }
+    break;
+
+  case 5:
+#line 504 "parse.y"
+    { (yyval.tree_statement_list_type) = 0; }
+    break;
+
+  case 6:
+#line 506 "parse.y"
+    {
+		    parser_end_of_input = 1;
+		    (yyval.tree_statement_list_type) = 0;
+		  }
+    break;
+
+  case 7:
+#line 511 "parse.y"
+    { (yyval.tree_statement_list_type) = (yyvsp[(1) - (1)].tree_statement_list_type); }
+    break;
+
+  case 8:
+#line 513 "parse.y"
+    { (yyval.tree_statement_list_type) = (yyvsp[(1) - (2)].tree_statement_list_type); }
+    break;
+
+  case 9:
+#line 515 "parse.y"
+    { (yyval.tree_statement_list_type) = (yyvsp[(1) - (2)].tree_statement_list_type); }
+    break;
+
+  case 10:
+#line 519 "parse.y"
+    { (yyval.tree_statement_list_type) = set_stmt_print_flag ((yyvsp[(1) - (2)].tree_statement_list_type), (yyvsp[(2) - (2)].sep_type), false); }
+    break;
+
+  case 11:
+#line 523 "parse.y"
+    { (yyval.tree_statement_list_type) = make_statement_list ((yyvsp[(1) - (1)].tree_statement_type)); }
+    break;
+
+  case 12:
+#line 525 "parse.y"
+    { (yyval.tree_statement_list_type) = append_statement_list ((yyvsp[(1) - (3)].tree_statement_list_type), (yyvsp[(2) - (3)].sep_type), (yyvsp[(3) - (3)].tree_statement_type), false); }
+    break;
+
+  case 13:
+#line 529 "parse.y"
+    { (yyval.tree_statement_list_type) = new tree_statement_list (); }
+    break;
+
+  case 14:
+#line 531 "parse.y"
+    { (yyval.tree_statement_list_type) = (yyvsp[(1) - (1)].tree_statement_list_type); }
+    break;
+
+  case 15:
+#line 535 "parse.y"
+    { (yyval.tree_statement_list_type) = set_stmt_print_flag ((yyvsp[(1) - (2)].tree_statement_list_type), (yyvsp[(2) - (2)].sep_type), true); }
+    break;
+
+  case 16:
+#line 539 "parse.y"
+    { (yyval.tree_statement_list_type) = make_statement_list ((yyvsp[(1) - (1)].tree_statement_type)); }
+    break;
+
+  case 17:
+#line 541 "parse.y"
+    { (yyval.tree_statement_list_type) = append_statement_list ((yyvsp[(1) - (3)].tree_statement_list_type), (yyvsp[(2) - (3)].sep_type), (yyvsp[(3) - (3)].tree_statement_type), true); }
+    break;
+
+  case 18:
+#line 545 "parse.y"
+    { (yyval.tree_statement_type) = make_statement ((yyvsp[(1) - (1)].tree_expression_type)); }
+    break;
+
+  case 19:
+#line 547 "parse.y"
+    { (yyval.tree_statement_type) = make_statement ((yyvsp[(1) - (1)].tree_command_type)); }
+    break;
+
+  case 20:
+#line 549 "parse.y"
+    { (yyval.tree_statement_type) = make_statement ((yyvsp[(1) - (1)].tree_index_expression_type)); }
+    break;
+
+  case 21:
+#line 561 "parse.y"
+    { (yyval.tree_index_expression_type) = make_index_expression ((yyvsp[(1) - (2)].tree_identifier_type), (yyvsp[(2) - (2)].tree_argument_list_type), '('); }
+    break;
+
+  case 22:
+#line 565 "parse.y"
+    { (yyval.tree_argument_list_type) = new tree_argument_list ((yyvsp[(1) - (1)].tree_constant_type)); }
+    break;
+
+  case 23:
+#line 567 "parse.y"
+    {
+		    (yyvsp[(1) - (2)].tree_argument_list_type)->append ((yyvsp[(2) - (2)].tree_constant_type));
+		    (yyval.tree_argument_list_type) = (yyvsp[(1) - (2)].tree_argument_list_type);
+		  }
+    break;
+
+  case 24:
+#line 578 "parse.y"
+    {
+		    symbol_table::symbol_record *sr = (yyvsp[(1) - (1)].tok_val)->sym_rec ();
+		    (yyval.tree_identifier_type) = new tree_identifier (*sr, (yyvsp[(1) - (1)].tok_val)->line (), (yyvsp[(1) - (1)].tok_val)->column ());
+		  }
+    break;
+
+  case 25:
+#line 585 "parse.y"
+    { (yyval.tree_constant_type) = make_constant (DQ_STRING, (yyvsp[(1) - (1)].tok_val)); }
+    break;
+
+  case 26:
+#line 587 "parse.y"
+    { (yyval.tree_constant_type) = make_constant (SQ_STRING, (yyvsp[(1) - (1)].tok_val)); }
+    break;
+
+  case 27:
+#line 591 "parse.y"
+    { (yyval.tree_constant_type) = make_constant (NUM, (yyvsp[(1) - (1)].tok_val)); }
+    break;
+
+  case 28:
+#line 593 "parse.y"
+    { (yyval.tree_constant_type) = make_constant (IMAG_NUM, (yyvsp[(1) - (1)].tok_val)); }
+    break;
+
+  case 29:
+#line 595 "parse.y"
+    { (yyval.tree_constant_type) = (yyvsp[(1) - (1)].tree_constant_type); }
+    break;
+
+  case 30:
+#line 599 "parse.y"
+    {
+		    (yyval.tree_expression_type) = new tree_constant (octave_null_matrix::instance);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+    break;
+
+  case 31:
+#line 605 "parse.y"
+    {
+		    (yyval.tree_expression_type) = new tree_constant (octave_null_matrix::instance);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+    break;
+
+  case 32:
+#line 611 "parse.y"
+    {
+		    (yyval.tree_expression_type) = new tree_constant (octave_null_matrix::instance);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+    break;
+
+  case 33:
+#line 617 "parse.y"
+    {
+		    (yyval.tree_expression_type) = finish_matrix ((yyvsp[(2) - (3)].tree_matrix_type));
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+    break;
+
+  case 34:
+#line 625 "parse.y"
+    { (yyval.tree_matrix_type) = (yyvsp[(1) - (1)].tree_matrix_type); }
+    break;
+
+  case 35:
+#line 627 "parse.y"
+    { (yyval.tree_matrix_type) = (yyvsp[(1) - (2)].tree_matrix_type); }
+    break;
+
+  case 36:
+#line 631 "parse.y"
+    { (yyval.tree_matrix_type) = new tree_matrix ((yyvsp[(1) - (1)].tree_argument_list_type)); }
+    break;
+
+  case 37:
+#line 633 "parse.y"
+    {
+		    (yyvsp[(1) - (3)].tree_matrix_type)->append ((yyvsp[(3) - (3)].tree_argument_list_type));
+		    (yyval.tree_matrix_type) = (yyvsp[(1) - (3)].tree_matrix_type);
+		  }
+    break;
+
+  case 38:
+#line 640 "parse.y"
+    { (yyval.tree_expression_type) = new tree_constant (octave_value (Cell ())); }
+    break;
+
+  case 39:
+#line 642 "parse.y"
+    { (yyval.tree_expression_type) = new tree_constant (octave_value (Cell ())); }
+    break;
+
+  case 40:
+#line 644 "parse.y"
+    { (yyval.tree_expression_type) = finish_cell ((yyvsp[(2) - (3)].tree_cell_type)); }
+    break;
+
+  case 41:
+#line 648 "parse.y"
+    { (yyval.tree_cell_type) = (yyvsp[(1) - (1)].tree_cell_type); }
+    break;
+
+  case 42:
+#line 650 "parse.y"
+    { (yyval.tree_cell_type) = (yyvsp[(1) - (2)].tree_cell_type); }
+    break;
+
+  case 43:
+#line 654 "parse.y"
+    { (yyval.tree_cell_type) = new tree_cell ((yyvsp[(1) - (1)].tree_argument_list_type)); }
+    break;
+
+  case 44:
+#line 656 "parse.y"
+    {
+		    (yyvsp[(1) - (3)].tree_cell_type)->append ((yyvsp[(3) - (3)].tree_argument_list_type));
+		    (yyval.tree_cell_type) = (yyvsp[(1) - (3)].tree_cell_type);
+		  }
+    break;
+
+  case 45:
+#line 664 "parse.y"
+    { (yyval.tree_argument_list_type) = (yyvsp[(1) - (1)].tree_argument_list_type); }
+    break;
+
+  case 46:
+#line 666 "parse.y"
+    { (yyval.tree_argument_list_type) = (yyvsp[(1) - (2)].tree_argument_list_type); }
+    break;
+
+  case 47:
+#line 670 "parse.y"
+    {
+		    (yyval.tree_fcn_handle_type) = make_fcn_handle ((yyvsp[(2) - (2)].tok_val));
+		    lexer_flags.looking_at_function_handle--;
+		  }
+    break;
+
+  case 48:
+#line 677 "parse.y"
+    { (yyval.tree_anon_fcn_handle_type) = make_anon_fcn_handle ((yyvsp[(2) - (3)].tree_parameter_list_type), (yyvsp[(3) - (3)].tree_statement_type)); }
+    break;
+
+  case 49:
+#line 681 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_identifier_type); }
+    break;
+
+  case 50:
+#line 683 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_constant_type); }
+    break;
+
+  case 51:
+#line 685 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_fcn_handle_type); }
+    break;
+
+  case 52:
+#line 687 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 53:
+#line 689 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 54:
+#line 691 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(2) - (3)].tree_expression_type)->mark_in_parens (); }
+    break;
+
+  case 55:
+#line 695 "parse.y"
+    {
+		    octave_value tmp (octave_value::magic_colon_t);
+		    (yyval.tree_constant_type) = new tree_constant (tmp);
+		  }
+    break;
+
+  case 56:
+#line 702 "parse.y"
+    { (yyval.tree_argument_list_type) = new tree_argument_list ((yyvsp[(1) - (1)].tree_expression_type)); }
+    break;
+
+  case 57:
+#line 704 "parse.y"
+    { (yyval.tree_argument_list_type) = new tree_argument_list ((yyvsp[(1) - (1)].tree_constant_type)); }
+    break;
+
+  case 58:
+#line 706 "parse.y"
+    {
+		    (yyvsp[(1) - (3)].tree_argument_list_type)->append ((yyvsp[(3) - (3)].tree_constant_type));
+		    (yyval.tree_argument_list_type) = (yyvsp[(1) - (3)].tree_argument_list_type);
+		  }
+    break;
+
+  case 59:
+#line 711 "parse.y"
+    {
+		    (yyvsp[(1) - (3)].tree_argument_list_type)->append ((yyvsp[(3) - (3)].tree_expression_type));
+		    (yyval.tree_argument_list_type) = (yyvsp[(1) - (3)].tree_argument_list_type);
+		  }
+    break;
+
+  case 60:
+#line 718 "parse.y"
+    { lexer_flags.looking_at_indirect_ref = true; }
+    break;
+
+  case 61:
+#line 722 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 62:
+#line 724 "parse.y"
+    { (yyval.tree_expression_type) = make_index_expression ((yyvsp[(1) - (3)].tree_expression_type), 0, '('); }
+    break;
+
+  case 63:
+#line 726 "parse.y"
+    { (yyval.tree_expression_type) = make_index_expression ((yyvsp[(1) - (4)].tree_expression_type), (yyvsp[(3) - (4)].tree_argument_list_type), '('); }
+    break;
+
+  case 64:
+#line 728 "parse.y"
+    { (yyval.tree_expression_type) = make_index_expression ((yyvsp[(1) - (3)].tree_expression_type), 0, '{'); }
+    break;
+
+  case 65:
+#line 730 "parse.y"
+    { (yyval.tree_expression_type) = make_index_expression ((yyvsp[(1) - (4)].tree_expression_type), (yyvsp[(3) - (4)].tree_argument_list_type), '{'); }
+    break;
+
+  case 66:
+#line 732 "parse.y"
+    { (yyval.tree_expression_type) = make_postfix_op (PLUS_PLUS, (yyvsp[(1) - (2)].tree_expression_type), (yyvsp[(2) - (2)].tok_val)); }
+    break;
+
+  case 67:
+#line 734 "parse.y"
+    { (yyval.tree_expression_type) = make_postfix_op (MINUS_MINUS, (yyvsp[(1) - (2)].tree_expression_type), (yyvsp[(2) - (2)].tok_val)); }
+    break;
+
+  case 68:
+#line 736 "parse.y"
+    { (yyval.tree_expression_type) = make_postfix_op (QUOTE, (yyvsp[(1) - (2)].tree_expression_type), (yyvsp[(2) - (2)].tok_val)); }
+    break;
+
+  case 69:
+#line 738 "parse.y"
+    { (yyval.tree_expression_type) = make_postfix_op (TRANSPOSE, (yyvsp[(1) - (2)].tree_expression_type), (yyvsp[(2) - (2)].tok_val)); }
+    break;
+
+  case 70:
+#line 740 "parse.y"
+    { (yyval.tree_expression_type) = make_indirect_ref ((yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(3) - (3)].tok_val)->text ()); }
+    break;
+
+  case 71:
+#line 742 "parse.y"
+    { (yyval.tree_expression_type) = make_indirect_ref ((yyvsp[(1) - (5)].tree_expression_type), (yyvsp[(4) - (5)].tree_expression_type)); }
+    break;
+
+  case 72:
+#line 746 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 73:
+#line 748 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 74:
+#line 750 "parse.y"
+    { (yyval.tree_expression_type) = make_prefix_op (PLUS_PLUS, (yyvsp[(2) - (2)].tree_expression_type), (yyvsp[(1) - (2)].tok_val)); }
+    break;
+
+  case 75:
+#line 752 "parse.y"
+    { (yyval.tree_expression_type) = make_prefix_op (MINUS_MINUS, (yyvsp[(2) - (2)].tree_expression_type), (yyvsp[(1) - (2)].tok_val)); }
+    break;
+
+  case 76:
+#line 754 "parse.y"
+    { (yyval.tree_expression_type) = make_prefix_op (EXPR_NOT, (yyvsp[(2) - (2)].tree_expression_type), (yyvsp[(1) - (2)].tok_val)); }
+    break;
+
+  case 77:
+#line 756 "parse.y"
+    { (yyval.tree_expression_type) = make_prefix_op ('+', (yyvsp[(2) - (2)].tree_expression_type), (yyvsp[(1) - (2)].tok_val)); }
+    break;
+
+  case 78:
+#line 758 "parse.y"
+    { (yyval.tree_expression_type) = make_prefix_op ('-', (yyvsp[(2) - (2)].tree_expression_type), (yyvsp[(1) - (2)].tok_val)); }
+    break;
+
+  case 79:
+#line 762 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (POW, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 80:
+#line 764 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EPOW, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 81:
+#line 766 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op ('+', (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 82:
+#line 768 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op ('-', (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 83:
+#line 770 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op ('*', (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 84:
+#line 772 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op ('/', (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 85:
+#line 774 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op ('+', (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 86:
+#line 776 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op ('-', (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 87:
+#line 778 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EMUL, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 88:
+#line 780 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EDIV, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 89:
+#line 782 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (LEFTDIV, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 90:
+#line 784 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (ELEFTDIV, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 91:
+#line 788 "parse.y"
+    { (yyval.tree_expression_type) = finish_colon_expression ((yyvsp[(1) - (1)].tree_colon_expression_type)); }
+    break;
+
+  case 92:
+#line 792 "parse.y"
+    { (yyval.tree_colon_expression_type) = new tree_colon_expression ((yyvsp[(1) - (1)].tree_expression_type)); }
+    break;
+
+  case 93:
+#line 794 "parse.y"
+    {
+		    if (! ((yyval.tree_colon_expression_type) = (yyvsp[(1) - (3)].tree_colon_expression_type)->append ((yyvsp[(3) - (3)].tree_expression_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 94:
+#line 801 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 95:
+#line 803 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (LSHIFT, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 96:
+#line 805 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (RSHIFT, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 97:
+#line 807 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_LT, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 98:
+#line 809 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_LE, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 99:
+#line 811 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_EQ, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 100:
+#line 813 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_GE, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 101:
+#line 815 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_GT, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 102:
+#line 817 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_NE, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 103:
+#line 819 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_AND, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 104:
+#line 821 "parse.y"
+    { (yyval.tree_expression_type) = make_binary_op (EXPR_OR, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 105:
+#line 823 "parse.y"
+    { (yyval.tree_expression_type) = make_boolean_op (EXPR_AND_AND, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 106:
+#line 825 "parse.y"
+    { (yyval.tree_expression_type) = make_boolean_op (EXPR_OR_OR, (yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 107:
+#line 832 "parse.y"
+    {
+		    (yyval.tree_argument_list_type) = new tree_argument_list ((yyvsp[(1) - (1)].tree_expression_type));
+		    (yyval.tree_argument_list_type)->mark_as_simple_assign_lhs ();
+		  }
+    break;
+
+  case 108:
+#line 837 "parse.y"
+    {
+		    (yyval.tree_argument_list_type) = (yyvsp[(2) - (3)].tree_argument_list_type);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    for (std::set<std::string>::const_iterator p = lexer_flags.pending_local_variables.begin ();
+			 p != lexer_flags.pending_local_variables.end ();
+			 p++)
+		      {
+			symbol_table::force_variable (*p);
+		      }
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+    break;
+
+  case 109:
+#line 851 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op ('=', (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 110:
+#line 853 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (ADD_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 111:
+#line 855 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (SUB_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 112:
+#line 857 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (MUL_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 113:
+#line 859 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (DIV_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 114:
+#line 861 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (LEFTDIV_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 115:
+#line 863 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (POW_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 116:
+#line 865 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (LSHIFT_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 117:
+#line 867 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (RSHIFT_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 118:
+#line 869 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (EMUL_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 119:
+#line 871 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (EDIV_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 120:
+#line 873 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (ELEFTDIV_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 121:
+#line 875 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (EPOW_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 122:
+#line 877 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (AND_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 123:
+#line 879 "parse.y"
+    { (yyval.tree_expression_type) = make_assign_op (OR_EQ, (yyvsp[(1) - (3)].tree_argument_list_type), (yyvsp[(2) - (3)].tok_val), (yyvsp[(3) - (3)].tree_expression_type)); }
+    break;
+
+  case 124:
+#line 883 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 125:
+#line 885 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_expression_type); }
+    break;
+
+  case 126:
+#line 887 "parse.y"
+    { (yyval.tree_expression_type) = (yyvsp[(1) - (1)].tree_anon_fcn_handle_type); }
+    break;
+
+  case 127:
+#line 895 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_decl_command_type); }
+    break;
+
+  case 128:
+#line 897 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_command_type); }
+    break;
+
+  case 129:
+#line 899 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_command_type); }
+    break;
+
+  case 130:
+#line 901 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_command_type); }
+    break;
+
+  case 131:
+#line 903 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_command_type); }
+    break;
+
+  case 132:
+#line 905 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_command_type); }
+    break;
+
+  case 133:
+#line 907 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_command_type); }
+    break;
+
+  case 134:
+#line 916 "parse.y"
+    { lexer_flags.looking_at_decl_list = true; }
+    break;
+
+  case 135:
+#line 919 "parse.y"
+    {
+		    (yyval.tree_decl_command_type) = make_decl_command (GLOBAL, (yyvsp[(1) - (3)].tok_val), (yyvsp[(3) - (3)].tree_decl_init_list_type));
+		    lexer_flags.looking_at_decl_list = false;
+		  }
+    break;
+
+  case 136:
+#line 924 "parse.y"
+    {
+		    (yyval.tree_decl_command_type) = make_decl_command (STATIC, (yyvsp[(1) - (3)].tok_val), (yyvsp[(3) - (3)].tree_decl_init_list_type));
+		    lexer_flags.looking_at_decl_list = false;
+		  }
+    break;
+
+  case 137:
+#line 931 "parse.y"
+    { (yyval.tree_decl_init_list_type) = new tree_decl_init_list ((yyvsp[(1) - (1)].tree_decl_elt_type)); }
+    break;
+
+  case 138:
+#line 933 "parse.y"
+    {
+		    (yyvsp[(1) - (2)].tree_decl_init_list_type)->append ((yyvsp[(2) - (2)].tree_decl_elt_type));
+		    (yyval.tree_decl_init_list_type) = (yyvsp[(1) - (2)].tree_decl_init_list_type);
+		  }
+    break;
+
+  case 139:
+#line 940 "parse.y"
+    { lexer_flags.looking_at_initializer_expression = true; }
+    break;
+
+  case 140:
+#line 943 "parse.y"
+    { (yyval.tree_decl_elt_type) = new tree_decl_elt ((yyvsp[(1) - (1)].tree_identifier_type)); }
+    break;
+
+  case 141:
+#line 945 "parse.y"
+    {
+		    lexer_flags.looking_at_initializer_expression = false;
+		    (yyval.tree_decl_elt_type) = new tree_decl_elt ((yyvsp[(1) - (4)].tree_identifier_type), (yyvsp[(4) - (4)].tree_expression_type));
+		  }
+    break;
+
+  case 142:
+#line 956 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_if_command_type); }
+    break;
+
+  case 143:
+#line 958 "parse.y"
+    { (yyval.tree_command_type) = (yyvsp[(1) - (1)].tree_switch_command_type); }
+    break;
+
+  case 144:
+#line 966 "parse.y"
+    {
+		    if (! ((yyval.tree_if_command_type) = finish_if_command ((yyvsp[(1) - (4)].tok_val), (yyvsp[(3) - (4)].tree_if_command_list_type), (yyvsp[(4) - (4)].tok_val), (yyvsp[(2) - (4)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 145:
+#line 973 "parse.y"
+    { (yyval.tree_if_command_list_type) = (yyvsp[(1) - (1)].tree_if_command_list_type); }
+    break;
+
+  case 146:
+#line 975 "parse.y"
+    {
+		    (yyvsp[(1) - (2)].tree_if_command_list_type)->append ((yyvsp[(2) - (2)].tree_if_clause_type));
+		    (yyval.tree_if_command_list_type) = (yyvsp[(1) - (2)].tree_if_command_list_type);
+		  }
+    break;
+
+  case 147:
+#line 982 "parse.y"
+    { (yyval.tree_if_command_list_type) = start_if_command ((yyvsp[(1) - (3)].tree_expression_type), (yyvsp[(3) - (3)].tree_statement_list_type)); }
+    break;
+
+  case 148:
+#line 984 "parse.y"
+    {
+		    (yyvsp[(1) - (2)].tree_if_command_list_type)->append ((yyvsp[(2) - (2)].tree_if_clause_type));
+		    (yyval.tree_if_command_list_type) = (yyvsp[(1) - (2)].tree_if_command_list_type);
+		  }
+    break;
+
+  case 149:
+#line 991 "parse.y"
+    { (yyval.tree_if_clause_type) = make_elseif_clause ((yyvsp[(1) - (6)].tok_val), (yyvsp[(4) - (6)].tree_expression_type), (yyvsp[(6) - (6)].tree_statement_list_type), (yyvsp[(2) - (6)].comment_type)); }
+    break;
+
+  case 150:
+#line 995 "parse.y"
+    { (yyval.tree_if_clause_type) = new tree_if_clause ((yyvsp[(4) - (4)].tree_statement_list_type), (yyvsp[(2) - (4)].comment_type)); }
+    break;
+
+  case 151:
+#line 1003 "parse.y"
+    {
+		    if (! ((yyval.tree_switch_command_type) = finish_switch_command ((yyvsp[(1) - (6)].tok_val), (yyvsp[(3) - (6)].tree_expression_type), (yyvsp[(5) - (6)].tree_switch_case_list_type), (yyvsp[(6) - (6)].tok_val), (yyvsp[(2) - (6)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 152:
+#line 1010 "parse.y"
+    { (yyval.tree_switch_case_list_type) = new tree_switch_case_list (); }
+    break;
+
+  case 153:
+#line 1012 "parse.y"
+    { (yyval.tree_switch_case_list_type) = (yyvsp[(1) - (1)].tree_switch_case_list_type); }
+    break;
+
+  case 154:
+#line 1014 "parse.y"
+    {
+		    (yyvsp[(1) - (2)].tree_switch_case_list_type)->append ((yyvsp[(2) - (2)].tree_switch_case_type));
+		    (yyval.tree_switch_case_list_type) = (yyvsp[(1) - (2)].tree_switch_case_list_type);
+		  }
+    break;
+
+  case 155:
+#line 1021 "parse.y"
+    { (yyval.tree_switch_case_list_type) = new tree_switch_case_list ((yyvsp[(1) - (1)].tree_switch_case_type)); }
+    break;
+
+  case 156:
+#line 1023 "parse.y"
+    {
+		    (yyvsp[(1) - (2)].tree_switch_case_list_type)->append ((yyvsp[(2) - (2)].tree_switch_case_type));
+		    (yyval.tree_switch_case_list_type) = (yyvsp[(1) - (2)].tree_switch_case_list_type);
+		  }
+    break;
+
+  case 157:
+#line 1030 "parse.y"
+    { (yyval.tree_switch_case_type) = make_switch_case ((yyvsp[(1) - (6)].tok_val), (yyvsp[(4) - (6)].tree_expression_type), (yyvsp[(6) - (6)].tree_statement_list_type), (yyvsp[(2) - (6)].comment_type)); }
+    break;
+
+  case 158:
+#line 1034 "parse.y"
+    {
+		    (yyval.tree_switch_case_type) = new tree_switch_case ((yyvsp[(4) - (4)].tree_statement_list_type), (yyvsp[(2) - (4)].comment_type));
+		  }
+    break;
+
+  case 159:
+#line 1044 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_while_command ((yyvsp[(1) - (6)].tok_val), (yyvsp[(3) - (6)].tree_expression_type), (yyvsp[(5) - (6)].tree_statement_list_type), (yyvsp[(6) - (6)].tok_val), (yyvsp[(2) - (6)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 160:
+#line 1049 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_do_until_command ((yyvsp[(5) - (6)].tok_val), (yyvsp[(4) - (6)].tree_statement_list_type), (yyvsp[(6) - (6)].tree_expression_type), (yyvsp[(2) - (6)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 161:
+#line 1054 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_for_command ((yyvsp[(1) - (8)].tok_val), (yyvsp[(3) - (8)].tree_argument_list_type), (yyvsp[(5) - (8)].tree_expression_type), (yyvsp[(7) - (8)].tree_statement_list_type), (yyvsp[(8) - (8)].tok_val), (yyvsp[(2) - (8)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 162:
+#line 1059 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_for_command ((yyvsp[(1) - (10)].tok_val), (yyvsp[(4) - (10)].tree_argument_list_type), (yyvsp[(6) - (10)].tree_expression_type), (yyvsp[(9) - (10)].tree_statement_list_type), (yyvsp[(10) - (10)].tok_val), (yyvsp[(2) - (10)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 163:
+#line 1070 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_break_command ((yyvsp[(1) - (1)].tok_val))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 164:
+#line 1075 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_continue_command ((yyvsp[(1) - (1)].tok_val))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 165:
+#line 1080 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_return_command ((yyvsp[(1) - (1)].tok_val))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 166:
+#line 1092 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_unwind_command ((yyvsp[(1) - (9)].tok_val), (yyvsp[(4) - (9)].tree_statement_list_type), (yyvsp[(8) - (9)].tree_statement_list_type), (yyvsp[(9) - (9)].tok_val), (yyvsp[(2) - (9)].comment_type), (yyvsp[(6) - (9)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 167:
+#line 1098 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_try_command ((yyvsp[(1) - (9)].tok_val), (yyvsp[(4) - (9)].tree_statement_list_type), (yyvsp[(8) - (9)].tree_statement_list_type), (yyvsp[(9) - (9)].tok_val), (yyvsp[(2) - (9)].comment_type), (yyvsp[(6) - (9)].comment_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 168:
+#line 1103 "parse.y"
+    {
+		    if (! ((yyval.tree_command_type) = make_try_command ((yyvsp[(1) - (5)].tok_val), (yyvsp[(4) - (5)].tree_statement_list_type), 0, (yyvsp[(5) - (5)].tok_val), (yyvsp[(2) - (5)].comment_type), 0)))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 169:
+#line 1114 "parse.y"
+    {
+		    symtab_context.push (symbol_table::current_scope ());
+		    symbol_table::set_scope (symbol_table::alloc_scope ());
+
+		    if (! lexer_flags.parsing_nested_function)
+		      symbol_table::set_parent_scope (symbol_table::current_scope ());
+		  }
+    break;
+
+  case 170:
+#line 1128 "parse.y"
+    {
+		    lexer_flags.looking_at_parameter_list = true;
+
+		    if (lexer_flags.looking_at_function_handle)
+		      {
+		        symtab_context.push (symbol_table::current_scope ());
+			symbol_table::set_scope (symbol_table::alloc_scope ());
+			lexer_flags.looking_at_function_handle--;
+		      }
+		  }
+    break;
+
+  case 171:
+#line 1141 "parse.y"
+    {
+		    lexer_flags.looking_at_parameter_list = false;
+		    lexer_flags.looking_for_object_index = false;
+		  }
+    break;
+
+  case 172:
+#line 1148 "parse.y"
+    {
+		    lexer_flags.quote_is_transpose = false;
+		    (yyval.tree_parameter_list_type) = (yyvsp[(2) - (3)].tree_parameter_list_type);
+		  }
+    break;
+
+  case 173:
+#line 1153 "parse.y"
+    {
+		    yyerror ("invalid parameter list");
+		    (yyval.tree_parameter_list_type) = 0;
+		    ABORT_PARSE;
+		  }
+    break;
+
+  case 174:
+#line 1161 "parse.y"
+    { (yyval.tree_parameter_list_type) = 0; }
+    break;
+
+  case 175:
+#line 1163 "parse.y"
+    {
+		    (yyvsp[(1) - (1)].tree_parameter_list_type)->mark_as_formal_parameters ();
+		    if ((yyvsp[(1) - (1)].tree_parameter_list_type)->validate (tree_parameter_list::in))
+		      (yyval.tree_parameter_list_type) = (yyvsp[(1) - (1)].tree_parameter_list_type);
+		    else
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 176:
+#line 1173 "parse.y"
+    { (yyval.tree_parameter_list_type) = new tree_parameter_list ((yyvsp[(1) - (1)].tree_decl_elt_type)); }
+    break;
+
+  case 177:
+#line 1175 "parse.y"
+    {
+		    (yyvsp[(1) - (3)].tree_parameter_list_type)->append ((yyvsp[(3) - (3)].tree_decl_elt_type));
+		    (yyval.tree_parameter_list_type) = (yyvsp[(1) - (3)].tree_parameter_list_type);
+		  }
+    break;
+
+  case 178:
+#line 1186 "parse.y"
+    {
+		    lexer_flags.looking_at_return_list = false;
+		    (yyval.tree_parameter_list_type) = new tree_parameter_list ();
+		  }
+    break;
+
+  case 179:
+#line 1191 "parse.y"
+    {
+		    lexer_flags.looking_at_return_list = false;
+		    if ((yyvsp[(1) - (1)].tree_parameter_list_type)->validate (tree_parameter_list::out))
+		      (yyval.tree_parameter_list_type) = (yyvsp[(1) - (1)].tree_parameter_list_type);
+		    else
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 180:
+#line 1199 "parse.y"
+    {
+		    lexer_flags.looking_at_return_list = false;
+		    if ((yyvsp[(2) - (3)].tree_parameter_list_type)->validate (tree_parameter_list::out))
+		      (yyval.tree_parameter_list_type) = (yyvsp[(2) - (3)].tree_parameter_list_type);
+		    else
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 181:
+#line 1209 "parse.y"
+    { (yyval.tree_parameter_list_type) = new tree_parameter_list (new tree_decl_elt ((yyvsp[(1) - (1)].tree_identifier_type))); }
+    break;
+
+  case 182:
+#line 1211 "parse.y"
+    {
+		    (yyvsp[(1) - (3)].tree_parameter_list_type)->append (new tree_decl_elt ((yyvsp[(3) - (3)].tree_identifier_type)));
+		    (yyval.tree_parameter_list_type) = (yyvsp[(1) - (3)].tree_parameter_list_type);
+		  }
+    break;
+
+  case 183:
+#line 1222 "parse.y"
+    {
+		    tree_statement *end_of_script
+		      = make_end ("endscript", input_line_number,
+				  current_input_column);
+
+		    make_script ((yyvsp[(2) - (3)].tree_statement_list_type), end_of_script);
+
+		    (yyval.tree_command_type) = 0;
+		  }
+    break;
+
+  case 184:
+#line 1238 "parse.y"
+    { (yyval.comment_type) = (yyvsp[(3) - (3)].comment_type); }
+    break;
+
+  case 185:
+#line 1242 "parse.y"
+    {
+		    (yyval.tree_command_type) = finish_function (0, (yyvsp[(2) - (2)].octave_user_function_type), (yyvsp[(1) - (2)].comment_type));
+		    recover_from_parsing_function ();
+		  }
+    break;
+
+  case 186:
+#line 1247 "parse.y"
+    {
+		    (yyval.tree_command_type) = finish_function ((yyvsp[(2) - (4)].tree_parameter_list_type), (yyvsp[(4) - (4)].octave_user_function_type), (yyvsp[(1) - (4)].comment_type));
+		    recover_from_parsing_function ();
+		  }
+    break;
+
+  case 187:
+#line 1254 "parse.y"
+    {
+		    std::string id_name = (yyvsp[(1) - (1)].tree_identifier_type)->name ();
+
+		    if (reading_fcn_file
+		        && ! lexer_flags.parsing_nested_function)
+		      parent_function_name = (curr_fcn_file_name == id_name)
+			? id_name : curr_fcn_file_name;
+
+		    lexer_flags.parsed_function_name = true;
+
+		    (yyval.tree_identifier_type) = (yyvsp[(1) - (1)].tree_identifier_type);
+		  }
+    break;
+
+  case 188:
+#line 1269 "parse.y"
+    {
+		    std::string fname = (yyvsp[(1) - (2)].tree_identifier_type)->name ();
+
+		    delete (yyvsp[(1) - (2)].tree_identifier_type);
+
+		    if (! ((yyval.octave_user_function_type) = frob_function (fname, (yyvsp[(2) - (2)].octave_user_function_type))))
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 189:
+#line 1280 "parse.y"
+    { (yyval.octave_user_function_type) = start_function ((yyvsp[(1) - (4)].tree_parameter_list_type), (yyvsp[(3) - (4)].tree_statement_list_type), (yyvsp[(4) - (4)].tree_statement_type)); }
+    break;
+
+  case 190:
+#line 1282 "parse.y"
+    { (yyval.octave_user_function_type) = start_function (0, (yyvsp[(2) - (3)].tree_statement_list_type), (yyvsp[(3) - (3)].tree_statement_type)); }
+    break;
+
+  case 191:
+#line 1286 "parse.y"
+    {
+		    if (end_token_ok ((yyvsp[(1) - (1)].tok_val), token::function_end))
+		      (yyval.tree_statement_type) = make_end ("endfunction", (yyvsp[(1) - (1)].tok_val)->line (), (yyvsp[(1) - (1)].tok_val)->column ());
+		    else
+		      ABORT_PARSE;
+		  }
+    break;
+
+  case 192:
+#line 1293 "parse.y"
+    {
+		    if (lexer_flags.parsing_nested_function)
+		      lexer_flags.parsing_nested_function = -1;
+
+		    if (reading_fcn_file || reading_script_file
+			|| get_input_from_eval_string)
+		      (yyval.tree_statement_type) = make_end ("endfunction", input_line_number,
+				     current_input_column);
+		    else
+		      YYABORT;
+		  }
+    break;
+
+  case 193:
+#line 1311 "parse.y"
+    { (yyval.comment_type) = octave_comment_buffer::get_comment (); }
+    break;
+
+  case 194:
+#line 1315 "parse.y"
+    { yyerror ("parse error"); }
+    break;
+
+  case 196:
+#line 1320 "parse.y"
+    { (yyval.sep_type) = ','; }
+    break;
+
+  case 197:
+#line 1322 "parse.y"
+    { (yyval.sep_type) = ';'; }
+    break;
+
+  case 198:
+#line 1324 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (2)].sep_type); }
+    break;
+
+  case 199:
+#line 1326 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (2)].sep_type); }
+    break;
+
+  case 200:
+#line 1330 "parse.y"
+    { (yyval.sep_type) = 0; }
+    break;
+
+  case 201:
+#line 1332 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (1)].sep_type); }
+    break;
+
+  case 202:
+#line 1336 "parse.y"
+    { (yyval.sep_type) = ','; }
+    break;
+
+  case 203:
+#line 1338 "parse.y"
+    { (yyval.sep_type) = ';'; }
+    break;
+
+  case 204:
+#line 1340 "parse.y"
+    { (yyval.sep_type) = '\n'; }
+    break;
+
+  case 205:
+#line 1342 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (2)].sep_type); }
+    break;
+
+  case 206:
+#line 1344 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (2)].sep_type); }
+    break;
+
+  case 207:
+#line 1346 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (2)].sep_type); }
+    break;
+
+  case 208:
+#line 1350 "parse.y"
+    { (yyval.sep_type) = 0; }
+    break;
+
+  case 209:
+#line 1352 "parse.y"
+    { (yyval.sep_type) = (yyvsp[(1) - (1)].sep_type); }
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 3576 "parse.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+#line 1355 "parse.y"
+
+
+// Generic error messages.
+
+static void
+yyerror (const char *s)
+{
+  int err_col = current_input_column - 1;
+
+  std::ostringstream output_buf;
+
+  if (reading_fcn_file || reading_script_file)
+    output_buf << "parse error near line " << input_line_number
+	       << " of file " << curr_fcn_file_full_name;
+  else
+    output_buf << "parse error:";
+
+  if (s && strcmp (s, "parse error") != 0)
+    output_buf << "\n\n  " << s;
+
+  output_buf << "\n\n";
+
+  if (! current_input_line.empty ())
+    {
+      size_t len = current_input_line.length ();
+
+      if (current_input_line[len-1] == '\n')
+        current_input_line.resize (len-1);
+
+      // Print the line, maybe with a pointer near the error token.
+
+      output_buf << ">>> " << current_input_line << "\n";
+
+      if (err_col == 0)
+	err_col = len;
+
+      for (int i = 0; i < err_col + 3; i++)
+	output_buf << " ";
+
+      output_buf << "^";
+    }
+
+  output_buf << "\n";
+
+  std::string msg = output_buf.str ();
+
+  parse_error ("%s", msg.c_str ());
+}
+
+// Error mesages for mismatched end tokens.
+
+static void
+end_error (const char *type, token::end_tok_type ettype, int l, int c)
+{
+  static const char *fmt
+    = "`%s' command matched by `%s' near line %d column %d";
+
+  switch (ettype)
+    {
+    case token::simple_end:
+      error (fmt, type, "end", l, c);
+      break;
+
+    case token::for_end:
+      error (fmt, type, "endfor", l, c);
+      break;
+
+    case token::function_end:
+      error (fmt, type, "endfunction", l, c);
+      break;
+
+    case token::if_end:
+      error (fmt, type, "endif", l, c);
+      break;
+
+    case token::switch_end:
+      error (fmt, type, "endswitch", l, c); 
+      break;
+
+    case token::while_end:
+      error (fmt, type, "endwhile", l, c); 
+      break;
+
+    case token::try_catch_end:
+      error (fmt, type, "end_try_catch", l, c); 
+      break;
+
+    case token::unwind_protect_end:
+      error (fmt, type, "end_unwind_protect", l, c); 
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+}
+
+// Check to see that end tokens are properly matched.
+
+static bool
+end_token_ok (token *tok, token::end_tok_type expected)
+{
+  bool retval = true;
+
+  token::end_tok_type ettype = tok->ettype ();
+
+  if (ettype != expected && ettype != token::simple_end)
+    {
+      retval = false;
+
+      yyerror ("parse error");
+
+      int l = tok->line ();
+      int c = tok->column ();
+
+      switch (expected)
+	{
+	case token::for_end:
+	  end_error ("for", ettype, l, c);
+	  break;
+
+	case token::function_end:
+	  end_error ("function", ettype, l, c);
+	  break;
+
+	case token::if_end:
+	  end_error ("if", ettype, l, c);
+	  break;
+
+	case token::try_catch_end:
+	  end_error ("try", ettype, l, c);
+	  break;
+
+	case token::switch_end:
+	  end_error ("switch", ettype, l, c);
+	  break;
+
+	case token::unwind_protect_end:
+	  end_error ("unwind_protect", ettype, l, c);
+	  break;
+
+	case token::while_end:
+	  end_error ("while", ettype, l, c);
+	  break;
+
+	default:
+	  panic_impossible ();
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+// Maybe print a warning if an assignment expression is used as the
+// test in a logical expression.
+
+static void
+maybe_warn_assign_as_truth_value (tree_expression *expr)
+{
+  if (expr->is_assignment_expression ()
+      && expr->paren_count () < 2)
+    {
+      if (curr_fcn_file_full_name.empty ())
+	warning_with_id
+	  ("Octave:assign-as-truth-value",
+	   "suggest parenthesis around assignment used as truth value");
+      else
+	warning_with_id
+	  ("Octave:assign-as-truth-value",
+	   "suggest parenthesis around assignment used as truth value near line %d, column %d in file `%s'",
+	   expr->line (), expr->column (), curr_fcn_file_full_name.c_str ());
+    }
+}
+
+// Maybe print a warning about switch labels that aren't constants.
+
+static void
+maybe_warn_variable_switch_label (tree_expression *expr)
+{
+  if (! expr->is_constant ())
+    {
+      if (curr_fcn_file_full_name.empty ())
+	warning_with_id ("Octave:variable-switch-label",
+			 "variable switch label");
+      else
+	warning_with_id
+	  ("Octave:variable-switch-label",
+	   "variable switch label near line %d, column %d in file `%s'",
+	   expr->line (), expr->column (), curr_fcn_file_full_name.c_str ());
+    }
+}
+
+static tree_expression *
+fold (tree_binary_expression *e)
+{
+  tree_expression *retval = e;
+
+  unwind_protect::begin_frame ("fold_binary_expression");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  tree_expression *op1 = e->lhs ();
+  tree_expression *op2 = e->rhs ();
+
+  octave_value::binary_op op_type = e->op_type ();
+
+  if (op1->is_constant () && op2->is_constant ()
+      && (! ((warning_enabled ("Octave:associativity-change")
+	      && (op_type == POW || op_type == EPOW))
+	     || (warning_enabled ("Octave:precedence-change")
+		 && (op_type == EXPR_OR || op_type == EXPR_OR_OR)))))
+    {
+      octave_value tmp = e->rvalue1 ();
+
+      if (! (error_state || warning_state))
+	{
+	  tree_constant *tc_retval
+	    = new tree_constant (tmp, op1->line (), op1->column ());
+
+	  std::ostringstream buf;
+
+	  tree_print_code tpc (buf);
+
+	  e->accept (tpc);
+
+	  tc_retval->stash_original_text (buf.str ());
+
+	  delete e;
+
+	  retval = tc_retval;
+	}
+    }
+
+  unwind_protect::run_frame ("fold_binary_expression");
+
+  return retval;
+}
+
+static tree_expression *
+fold (tree_unary_expression *e)
+{
+  tree_expression *retval = e;
+
+  unwind_protect::begin_frame ("fold_unary_expression");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  tree_expression *op = e->operand ();
+
+  if (op->is_constant ())
+    {
+      octave_value tmp = e->rvalue1 ();
+
+      if (! (error_state || warning_state))
+	{
+	  tree_constant *tc_retval
+	    = new tree_constant (tmp, op->line (), op->column ());
+
+	  std::ostringstream buf;
+
+	  tree_print_code tpc (buf);
+
+	  e->accept (tpc);
+
+	  tc_retval->stash_original_text (buf.str ());
+
+	  delete e;
+
+	  retval = tc_retval;
+	}
+    }
+
+  unwind_protect::run_frame ("fold_unary_expression");
+
+  return retval;
+}
+
+// Finish building a range.
+
+static tree_expression *
+finish_colon_expression (tree_colon_expression *e)
+{
+  tree_expression *retval = e;
+
+  unwind_protect::begin_frame ("finish_colon_expression");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  tree_expression *base = e->base ();
+  tree_expression *limit = e->limit ();
+  tree_expression *incr = e->increment ();
+
+  if (base)
+    {
+      if (limit)
+	{
+	  if (base->is_constant () && limit->is_constant ()
+	      && (! incr || (incr && incr->is_constant ())))
+	    {
+	      octave_value tmp = e->rvalue1 ();
+
+	      if (! (error_state || warning_state))
+		{
+		  tree_constant *tc_retval
+		    = new tree_constant (tmp, base->line (), base->column ());
+
+		  std::ostringstream buf;
+
+		  tree_print_code tpc (buf);
+
+		  e->accept (tpc);
+
+		  tc_retval->stash_original_text (buf.str ());
+
+		  delete e;
+
+		  retval = tc_retval;
+		}
+	    }
+	}
+      else
+	{
+	  e->preserve_base ();
+	  delete e;
+
+	  // FIXME -- need to attempt constant folding here
+	  // too (we need a generic way to do that).
+	  retval = base;
+	}
+    }
+
+  unwind_protect::run_frame ("finish_colon_expression");
+
+  return retval;
+}
+
+// Make a constant.
+
+static tree_constant *
+make_constant (int op, token *tok_val)
+{
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_constant *retval = 0;
+
+  switch (op)
+    {
+    case NUM:
+      {
+	octave_value tmp (tok_val->number ());
+	retval = new tree_constant (tmp, l, c);
+	retval->stash_original_text (tok_val->text_rep ());
+      }
+      break;
+
+    case IMAG_NUM:
+      {
+	octave_value tmp (Complex (0.0, tok_val->number ()));
+	retval = new tree_constant (tmp, l, c);
+	retval->stash_original_text (tok_val->text_rep ());
+      }
+      break;
+
+    case DQ_STRING:
+    case SQ_STRING:
+      {
+	std::string txt = tok_val->text ();
+
+        char delim = op == DQ_STRING ? '"' : '\'';
+        octave_value tmp (txt, delim);
+
+        if (txt.empty ())
+          {
+            if (op == DQ_STRING)
+              tmp = octave_null_str::instance;
+            else
+              tmp = octave_null_sq_str::instance;
+          }
+
+	retval = new tree_constant (tmp, l, c);
+
+	if (op == DQ_STRING)
+	  txt = undo_string_escapes (txt);
+
+	// FIXME -- maybe this should also be handled by
+	// tok_val->text_rep () for character strings?
+	retval->stash_original_text (delim + txt + delim);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return retval;
+}
+
+// Make a function handle.
+
+static tree_fcn_handle *
+make_fcn_handle (token *tok_val)
+{
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_fcn_handle *retval = new tree_fcn_handle (tok_val->text (), l, c);
+
+  return retval;
+}
+
+// Make an anonymous function handle.
+
+static tree_anon_fcn_handle *
+make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt)
+{
+  // FIXME -- need to get these from the location of the @ symbol.
+
+  int l = -1;
+  int c = -1;
+
+  tree_parameter_list *ret_list = 0;
+
+  symbol_table::scope_id fcn_scope = symbol_table::current_scope ();
+
+  if (symtab_context.empty ())
+    panic_impossible ();
+
+  symbol_table::set_scope (symtab_context.top ());
+
+  symtab_context.pop ();
+
+  stmt->set_print_flag (false);
+
+  tree_statement_list *body = new tree_statement_list (stmt);
+
+  body->mark_as_anon_function_body ();
+
+  tree_anon_fcn_handle *retval
+    = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c);
+
+  return retval;
+}
+
+static void
+maybe_warn_associativity_change (tree_expression *op)
+{
+  if (op->paren_count () == 0 && op->is_binary_expression ())
+    {
+      tree_binary_expression *e
+	= dynamic_cast<tree_binary_expression *> (op);
+
+      octave_value::binary_op op_type = e->op_type ();
+
+      if (op_type == octave_value::op_pow
+	  || op_type == octave_value::op_el_pow)
+	{
+	  std::string op_str = octave_value::binary_op_as_string (op_type);
+
+	  if (curr_fcn_file_full_name.empty ())
+	    warning_with_id
+	      ("Octave:associativity-change",
+	       "meaning may have changed due to change in associativity for %s operator",
+	       op_str.c_str ());
+	  else
+	    warning_with_id
+	      ("Octave:associativity-change",
+	       "meaning may have changed due to change in associativity for %s operator near line %d, column %d in file `%s'",
+	       op_str.c_str (), op->line (), op->column (),
+	       curr_fcn_file_full_name.c_str ());
+	}
+    }
+}
+
+// Build a binary expression.
+
+static tree_expression *
+make_binary_op (int op, tree_expression *op1, token *tok_val,
+		tree_expression *op2)
+{
+  octave_value::binary_op t = octave_value::unknown_binary_op;
+
+  switch (op)
+    {
+    case POW:
+      t = octave_value::op_pow;
+      maybe_warn_associativity_change (op1);
+      break;
+
+    case EPOW:
+      t = octave_value::op_el_pow;
+      maybe_warn_associativity_change (op1);
+      break;
+
+    case '+':
+      t = octave_value::op_add;
+      break;
+
+    case '-':
+      t = octave_value::op_sub;
+      break;
+
+    case '*':
+      t = octave_value::op_mul;
+      break;
+
+    case '/':
+      t = octave_value::op_div;
+      break;
+
+    case EMUL:
+      t = octave_value::op_el_mul;
+      break;
+
+    case EDIV:
+      t = octave_value::op_el_div;
+      break;
+
+    case LEFTDIV:
+      t = octave_value::op_ldiv;
+      break;
+
+    case ELEFTDIV:
+      t = octave_value::op_el_ldiv;
+      break;
+
+    case LSHIFT:
+      t = octave_value::op_lshift;
+      break;
+
+    case RSHIFT:
+      t = octave_value::op_rshift;
+      break;
+
+    case EXPR_LT:
+      t = octave_value::op_lt;
+      break;
+
+    case EXPR_LE:
+      t = octave_value::op_le;
+      break;
+
+    case EXPR_EQ:
+      t = octave_value::op_eq;
+      break;
+
+    case EXPR_GE:
+      t = octave_value::op_ge;
+      break;
+
+    case EXPR_GT:
+      t = octave_value::op_gt;
+      break;
+
+    case EXPR_NE:
+      t = octave_value::op_ne;
+      break;
+
+    case EXPR_AND:
+      t = octave_value::op_el_and;
+      break;
+
+    case EXPR_OR:
+      t = octave_value::op_el_or;
+      if (op2->paren_count () == 0 && op2->is_binary_expression ())
+        {
+	  tree_binary_expression *e
+	    = dynamic_cast<tree_binary_expression *> (op2);
+
+	  if (e->op_type () == octave_value::op_el_and)
+	    {
+	      if (curr_fcn_file_full_name.empty ())
+		warning_with_id
+		  ("Octave:precedence-change",
+		   "meaning may have changed due to change in precedence for & and | operators");
+	      else
+		warning_with_id
+		  ("Octave:precedence-change",
+		   "meaning may have changed due to change in precedence for & and | operators near line %d, column %d in file `%s'",
+		   op2->line (), op2->column (),
+		   curr_fcn_file_full_name.c_str ());
+	    }
+        }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_binary_expression *e
+    = maybe_compound_binary_expression (op1, op2, l, c, t);
+
+  return fold (e);
+}
+
+// Build a boolean expression.
+
+static tree_expression *
+make_boolean_op (int op, tree_expression *op1, token *tok_val,
+		 tree_expression *op2)
+{
+  tree_boolean_expression::type t;
+
+  switch (op)
+    {
+    case EXPR_AND_AND:
+      t = tree_boolean_expression::bool_and;
+      break;
+
+    case EXPR_OR_OR:
+      t = tree_boolean_expression::bool_or;
+      if (op2->paren_count () == 0 && op2->is_boolean_expression ())
+        {
+	  tree_boolean_expression *e
+	    = dynamic_cast<tree_boolean_expression *> (op2);
+
+	  if (e->op_type () == tree_boolean_expression::bool_and)
+	    warning_with_id
+	      ("Octave:precedence-change",
+	       "meaning may have changed due to change in precedence for && and || operators");
+        }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_boolean_expression *e
+    = new tree_boolean_expression (op1, op2, l, c, t);
+
+  return fold (e);
+}
+
+// Build a prefix expression.
+
+static tree_expression *
+make_prefix_op (int op, tree_expression *op1, token *tok_val)
+{
+  octave_value::unary_op t = octave_value::unknown_unary_op;
+
+  switch (op)
+    {
+    case EXPR_NOT:
+      t = octave_value::op_not;
+      break;
+
+    case '+':
+      t = octave_value::op_uplus;
+      break;
+
+    case '-':
+      t = octave_value::op_uminus;
+      break;
+
+    case PLUS_PLUS:
+      t = octave_value::op_incr;
+      break;
+
+    case MINUS_MINUS:
+      t = octave_value::op_decr;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_prefix_expression *e
+    = new tree_prefix_expression (op1, l, c, t);
+
+  return fold (e);
+}
+
+// Build a postfix expression.
+
+static tree_expression *
+make_postfix_op (int op, tree_expression *op1, token *tok_val)
+{
+  octave_value::unary_op t = octave_value::unknown_unary_op;
+
+  switch (op)
+    {
+    case QUOTE:
+      t = octave_value::op_hermitian;
+      break;
+
+    case TRANSPOSE:
+      t = octave_value::op_transpose;
+      break;
+
+    case PLUS_PLUS:
+      t = octave_value::op_incr;
+      break;
+
+    case MINUS_MINUS:
+      t = octave_value::op_decr;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_postfix_expression *e
+    = new tree_postfix_expression (op1, l, c, t);
+
+  return fold (e);
+}
+
+// Build an unwind-protect command.
+
+static tree_command *
+make_unwind_command (token *unwind_tok, tree_statement_list *body,
+		     tree_statement_list *cleanup, token *end_tok,
+		     octave_comment_list *lc, octave_comment_list *mc)
+{
+  tree_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::unwind_protect_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = unwind_tok->line ();
+      int c = unwind_tok->column ();
+
+      retval = new tree_unwind_protect_command (body, cleanup,
+						lc, mc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a try-catch command.
+
+static tree_command *
+make_try_command (token *try_tok, tree_statement_list *body,
+		  tree_statement_list *cleanup, token *end_tok,
+		  octave_comment_list *lc, octave_comment_list *mc)
+{
+  tree_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::try_catch_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = try_tok->line ();
+      int c = try_tok->column ();
+
+      retval = new tree_try_catch_command (body, cleanup,
+					   lc, mc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a while command.
+
+static tree_command *
+make_while_command (token *while_tok, tree_expression *expr,
+		    tree_statement_list *body, token *end_tok,
+		    octave_comment_list *lc)
+{
+  tree_command *retval = 0;
+
+  maybe_warn_assign_as_truth_value (expr);
+
+  if (end_token_ok (end_tok, token::while_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      lexer_flags.looping--;
+
+      int l = while_tok->line ();
+      int c = while_tok->column ();
+
+      retval = new tree_while_command (expr, body, lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a do-until command.
+
+static tree_command *
+make_do_until_command (token *until_tok, tree_statement_list *body,
+		       tree_expression *expr, octave_comment_list *lc)
+{
+  tree_command *retval = 0;
+
+  maybe_warn_assign_as_truth_value (expr);
+
+  octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+  lexer_flags.looping--;
+
+  int l = until_tok->line ();
+  int c = until_tok->column ();
+
+  retval = new tree_do_until_command (expr, body, lc, tc, l, c);
+
+  return retval;
+}
+
+// Build a for command.
+
+static tree_command *
+make_for_command (token *for_tok, tree_argument_list *lhs,
+		  tree_expression *expr, tree_statement_list *body,
+		  token *end_tok, octave_comment_list *lc)
+{
+  tree_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::for_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      lexer_flags.looping--;
+
+      int l = for_tok->line ();
+      int c = for_tok->column ();
+
+      if (lhs->length () == 1)
+	{
+	  tree_expression *tmp = lhs->remove_front ();
+
+	  retval = new tree_simple_for_command (tmp, expr, body,
+						lc, tc, l, c);
+
+	  delete lhs;
+	}
+      else
+	retval = new tree_complex_for_command (lhs, expr, body,
+					       lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a break command.
+
+static tree_command *
+make_break_command (token *break_tok)
+{
+  tree_command *retval = 0;
+
+  int l = break_tok->line ();
+  int c = break_tok->column ();
+
+  // We check to see if we are evaluating a function, script, or loop
+  // so that we don't turn eval ("break;") inside a function, script,
+  // or loop into a no-op command.
+
+  if (lexer_flags.looping || lexer_flags.defining_func
+      || reading_script_file || tree_evaluator::in_fcn_or_script_body
+      || tree_evaluator::in_loop_command)
+    retval = new tree_break_command (l, c);
+  else
+    retval = new tree_no_op_command ("break", l, c);
+
+  return retval;
+}
+
+// Build a continue command.
+
+static tree_command *
+make_continue_command (token *continue_tok)
+{
+  tree_command *retval = 0;
+
+  int l = continue_tok->line ();
+  int c = continue_tok->column ();
+
+  // We check to see if we are evaluating a loop so that we don't turn
+  // eval ("continue;") into a no-op command inside a loop.
+
+  if (lexer_flags.looping || tree_evaluator::in_loop_command)
+    retval = new tree_continue_command (l, c);
+  else
+    retval = new tree_no_op_command ("continue", l, c);
+
+  return retval;
+}
+
+// Build a return command.
+
+static tree_command *
+make_return_command (token *return_tok)
+{
+  tree_command *retval = 0;
+
+  int l = return_tok->line ();
+  int c = return_tok->column ();
+
+  if (Vdebugging)
+    {
+      Vdebugging = false;
+
+      retval = new tree_no_op_command ("return", l, c);
+    }
+  else
+    {
+      // We check to see if we are evaluating a function or script so
+      // that we don't turn eval ("return;") inside a function, script,
+      // or loop into a no-op command.
+
+      if (lexer_flags.defining_func || reading_script_file
+          || tree_evaluator::in_fcn_or_script_body)
+        retval = new tree_return_command (l, c);
+      else
+        retval = new tree_no_op_command ("return", l, c);
+    }
+
+  return retval;
+}
+
+// Start an if command.
+
+static tree_if_command_list *
+start_if_command (tree_expression *expr, tree_statement_list *list)
+{
+  maybe_warn_assign_as_truth_value (expr);
+
+  tree_if_clause *t = new tree_if_clause (expr, list);
+
+  return new tree_if_command_list (t);
+}
+
+// Finish an if command.
+
+static tree_if_command *
+finish_if_command (token *if_tok, tree_if_command_list *list,
+		   token *end_tok, octave_comment_list *lc)
+{
+  tree_if_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::if_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = if_tok->line ();
+      int c = if_tok->column ();
+
+      if (list && ! list->empty ())
+	{
+	  tree_if_clause *elt = list->front ();
+
+	  if (elt)
+	    {
+	      elt->line (l);
+	      elt->column (c);
+	    }
+	}
+
+      retval = new tree_if_command (list, lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build an elseif clause.
+
+static tree_if_clause *
+make_elseif_clause (token *elseif_tok, tree_expression *expr,
+		    tree_statement_list *list, octave_comment_list *lc)
+{
+  maybe_warn_assign_as_truth_value (expr);
+
+  int l = elseif_tok->line ();
+  int c = elseif_tok->column ();
+
+  return new tree_if_clause (expr, list, lc, l, c);
+}
+
+// Finish a switch command.
+
+static tree_switch_command *
+finish_switch_command (token *switch_tok, tree_expression *expr,
+		       tree_switch_case_list *list, token *end_tok,
+		       octave_comment_list *lc)
+{
+  tree_switch_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::switch_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = switch_tok->line ();
+      int c = switch_tok->column ();
+
+      if (list && ! list->empty ())
+	{
+	  tree_switch_case *elt = list->front ();
+
+	  if (elt)
+	    {
+	      elt->line (l);
+	      elt->column (c);
+	    }
+	}
+
+      retval = new tree_switch_command (expr, list, lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a switch case.
+
+static tree_switch_case *
+make_switch_case (token *case_tok, tree_expression *expr,
+		  tree_statement_list *list, octave_comment_list *lc)
+{
+  maybe_warn_variable_switch_label (expr);
+
+  int l = case_tok->line ();
+  int c = case_tok->column ();
+
+  return new tree_switch_case (expr, list, lc, l, c);
+}
+
+// Build an assignment to a variable.
+
+static tree_expression *
+make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
+		tree_expression *rhs)
+{
+  tree_expression *retval = 0;
+
+  octave_value::assign_op t = octave_value::unknown_assign_op;
+
+  switch (op)
+    {
+    case '=':
+      t = octave_value::op_asn_eq;
+      break;
+
+    case ADD_EQ:
+      t = octave_value::op_add_eq;
+      break;
+
+    case SUB_EQ:
+      t = octave_value::op_sub_eq;
+      break;
+
+    case MUL_EQ:
+      t = octave_value::op_mul_eq;
+      break;
+
+    case DIV_EQ:
+      t = octave_value::op_div_eq;
+      break;
+
+    case LEFTDIV_EQ:
+      t = octave_value::op_ldiv_eq;
+      break;
+
+    case POW_EQ:
+      t = octave_value::op_pow_eq;
+      break;
+
+    case LSHIFT_EQ:
+      t = octave_value::op_lshift_eq;
+      break;
+
+    case RSHIFT_EQ:
+      t = octave_value::op_rshift_eq;
+      break;
+
+    case EMUL_EQ:
+      t = octave_value::op_el_mul_eq;
+      break;
+
+    case EDIV_EQ:
+      t = octave_value::op_el_div_eq;
+      break;
+
+    case ELEFTDIV_EQ:
+      t = octave_value::op_el_ldiv_eq;
+      break;
+
+    case EPOW_EQ:
+      t = octave_value::op_el_pow_eq;
+      break;
+
+    case AND_EQ:
+      t = octave_value::op_el_and_eq;
+      break;
+
+    case OR_EQ:
+      t = octave_value::op_el_or_eq;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = eq_tok->line ();
+  int c = eq_tok->column ();
+
+  if (lhs->is_simple_assign_lhs ())
+    {
+      tree_expression *tmp = lhs->remove_front ();
+
+      retval = new tree_simple_assignment (tmp, rhs, false, l, c, t);
+
+      delete lhs;
+    }
+  else
+    return new tree_multi_assignment (lhs, rhs, false, l, c, t);
+
+  return retval;
+}
+
+// Define a function.
+
+static void
+make_script (tree_statement_list *cmds, tree_statement *end_script)
+{
+  std::string doc_string;
+
+  if (! help_buf.empty ())
+    {
+      doc_string = help_buf.top ();
+      help_buf.pop ();
+    }
+
+  if (! cmds)
+    cmds = new tree_statement_list ();
+
+  cmds->append (end_script);
+
+  octave_user_script *script
+    = new octave_user_script (curr_fcn_file_full_name, curr_fcn_file_name,
+			      cmds, doc_string);
+
+  octave_time now;
+
+  script->stash_fcn_file_time (now);
+
+  curr_fcn_ptr = script;
+
+  // Unmark any symbols that may have been tagged as local variables
+  // while parsing (for example, by force_local_variable in lex.l).
+
+  symbol_table::unmark_forced_variables ();
+}
+
+// Begin defining a function.
+
+static octave_user_function *
+start_function (tree_parameter_list *param_list, tree_statement_list *body,
+		tree_statement *end_fcn_stmt)
+{
+  // We'll fill in the return list later.
+
+  if (! body)
+    body = new tree_statement_list ();
+
+  body->append (end_fcn_stmt);
+
+  octave_user_function *fcn
+    = new octave_user_function (symbol_table::current_scope (),
+				param_list, 0, body);
+
+  if (fcn)
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      fcn->stash_trailing_comment (tc);
+    }
+
+  return fcn;
+}
+
+static tree_statement *
+make_end (const std::string& type, int l, int c)
+{
+  return make_statement (new tree_no_op_command (type, l, c));
+}
+
+// Do most of the work for defining a function.
+
+static octave_user_function *
+frob_function (const std::string& fname, octave_user_function *fcn)
+{
+  std::string id_name = fname;
+
+  // If input is coming from a file, issue a warning if the name of
+  // the file does not match the name of the function stated in the
+  // file.  Matlab doesn't provide a diagnostic (it ignores the stated
+  // name).
+
+  if (reading_fcn_file || autoloading)
+    {
+      if (! (autoloading
+	     || lexer_flags.parsing_nested_function
+	     || lexer_flags.parsing_class_method))
+	{
+	  // FIXME -- should curr_fcn_file_name already be
+	  // preprocessed when we get here?  It seems to only be a
+	  // problem with relative file names.
+
+	  std::string nm = curr_fcn_file_name;
+
+	  size_t pos = nm.find_last_of (file_ops::dir_sep_chars ());
+
+	  if (pos != std::string::npos)
+	    nm = curr_fcn_file_name.substr (pos+1);
+
+	  if (nm != id_name)
+	    {
+	      warning_with_id
+		("Octave:function-name-clash",
+		 "function name `%s' does not agree with function file name `%s'",
+		 id_name.c_str (), curr_fcn_file_full_name.c_str ());
+
+	      id_name = nm;
+	    }
+	}
+
+      octave_time now;
+
+      fcn->stash_fcn_file_name (curr_fcn_file_full_name);
+      fcn->stash_fcn_file_time (now);
+      fcn->mark_as_system_fcn_file ();
+
+      if (fcn_file_from_relative_lookup)
+	fcn->mark_relative ();
+
+      if (lexer_flags.parsing_nested_function)
+        {
+          fcn->stash_parent_fcn_name (parent_function_name);
+          fcn->stash_parent_fcn_scope (symbol_table::parent_scope ());
+	}
+
+      if (lexer_flags.parsing_class_method)
+	{
+	  if (current_class_name == id_name)
+	    fcn->mark_as_class_constructor ();
+	  else
+	    fcn->mark_as_class_method ();
+
+	  fcn->stash_dispatch_class (current_class_name);
+	}
+
+      std::string nm = fcn->fcn_file_name ();
+
+      file_stat fs (nm);
+
+      if (fs && fs.is_newer (now))
+        warning_with_id ("Octave:future-time-stamp",
+			 "time stamp for `%s' is in the future", nm.c_str ());
+    }
+  else if (! (input_from_tmp_history_file || input_from_startup_file)
+	   && reading_script_file
+	   && curr_fcn_file_name == id_name)
+    {
+      warning ("function `%s' defined within script file `%s'",
+	       id_name.c_str (), curr_fcn_file_full_name.c_str ());
+    }
+
+  fcn->stash_function_name (id_name);
+
+  if (! help_buf.empty ())
+    {
+      fcn->document (help_buf.top ());
+
+      help_buf.pop ();
+    }
+
+  if (reading_fcn_file && ! lexer_flags.parsing_nested_function)
+    curr_fcn_ptr = fcn;
+  else
+    curr_fcn_ptr = 0;
+
+  return fcn;
+}
+
+static tree_function_def *
+finish_function (tree_parameter_list *ret_list,
+		 octave_user_function *fcn, octave_comment_list *lc)
+{
+  tree_function_def *retval = 0;
+
+  if (ret_list)
+    ret_list->mark_as_formal_parameters ();
+
+  if (fcn)
+    {
+      std::string nm = fcn->name ();
+      std::string file = fcn->fcn_file_name ();
+
+      std::string tmp = nm;
+      if (! file.empty ())
+	tmp += ": " + file;
+
+      symbol_table::cache_name (fcn->scope (), tmp);
+
+      if (lc)
+	fcn->stash_leading_comment (lc);
+
+      fcn->define_ret_list (ret_list);
+
+      if (lexer_flags.parsing_nested_function)
+	{
+	  fcn->mark_as_nested_function ();
+
+	  symbol_table::install_subfunction (nm, octave_value (fcn));
+
+	  if (lexer_flags.parsing_nested_function < 0)
+	    {
+	      lexer_flags.parsing_nested_function = 0;
+	      symbol_table::reset_parent_scope ();
+	    }
+	}
+      else if (! curr_fcn_ptr)
+	{
+	  // FIXME -- there should be a better way to indicate that we
+	  // should create a tree_function_def object other than
+	  // looking at curr_fcn_ptr...
+
+	  retval = new tree_function_def (fcn);
+	}
+
+      // Unmark any symbols that may have been tagged as local
+      // variables while parsing (for example, by force_local_variable
+      // in lex.l).
+
+      symbol_table::unmark_forced_variables (fcn->scope ());
+    }
+
+  return retval;
+}
+
+static void
+recover_from_parsing_function (void)
+{
+  if (symtab_context.empty ())
+    panic_impossible ();
+
+  symbol_table::set_scope (symtab_context.top ());
+  symtab_context.pop ();
+
+  lexer_flags.defining_func = false;
+  lexer_flags.parsed_function_name = false;
+  lexer_flags.looking_at_return_list = false;
+  lexer_flags.looking_at_parameter_list = false;
+}
+
+// Make an index expression.
+
+static tree_index_expression *
+make_index_expression (tree_expression *expr, tree_argument_list *args,
+		       char type)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  expr->mark_postfix_indexed ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (args, type);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, args, l, c, type);
+
+  return retval;
+}
+
+// Make an indirect reference expression.
+
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, const std::string& elt)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (elt);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, elt, l, c);
+
+  lexer_flags.looking_at_indirect_ref = false;
+
+  return retval;
+}
+
+// Make an indirect reference expression with dynamic field name.
+
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, tree_expression *elt)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (elt);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, elt, l, c);
+
+  lexer_flags.looking_at_indirect_ref = false;
+
+  return retval;
+}
+
+// Make a declaration command.
+
+static tree_decl_command *
+make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst)
+{
+  tree_decl_command *retval = 0;
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  switch (tok)
+    {
+    case GLOBAL:
+      retval = new tree_global_command (lst, l, c);
+      break;
+
+    case STATIC:
+      if (lexer_flags.defining_func)
+	retval = new tree_static_command (lst, l, c);
+      else
+	{
+	  if (reading_script_file)
+	    warning ("ignoring persistent declaration near line %d of file `%s'",
+		     l, curr_fcn_file_full_name.c_str ());
+	  else
+	    warning ("ignoring persistent declaration near line %d", l);
+	}
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return retval;
+}
+
+// Finish building a matrix list.
+
+static tree_expression *
+finish_matrix (tree_matrix *m)
+{
+  tree_expression *retval = m;
+
+  unwind_protect::begin_frame ("finish_matrix");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  if (m->all_elements_are_constant ())
+    {
+      octave_value tmp = m->rvalue1 ();
+
+      if (! (error_state || warning_state))
+	{
+	  tree_constant *tc_retval
+	    = new tree_constant (tmp, m->line (), m->column ());
+
+	  std::ostringstream buf;
+
+	  tree_print_code tpc (buf);
+
+	  m->accept (tpc);
+
+	  tc_retval->stash_original_text (buf.str ());
+
+	  delete m;
+
+	  retval = tc_retval;
+	}
+    }
+
+  unwind_protect::run_frame ("finish_matrix");
+
+  return retval;
+}
+
+// Finish building a cell list.
+
+static tree_expression *
+finish_cell (tree_cell *c)
+{
+  return finish_matrix (c);
+}
+
+static void
+maybe_warn_missing_semi (tree_statement_list *t)
+{
+  if (lexer_flags.defining_func)
+    {
+      tree_statement *tmp = t->back();
+
+      if (tmp->is_expression ())
+	warning_with_id
+	  ("Octave:missing-semicolon",
+	   "missing semicolon near line %d, column %d in file `%s'",
+	    tmp->line (), tmp->column (), curr_fcn_file_full_name.c_str ());
+    }
+}
+
+static tree_statement_list *
+set_stmt_print_flag (tree_statement_list *list, char sep,
+		     bool warn_missing_semi)
+{
+  tree_statement *tmp = list->back ();
+
+  switch (sep)
+    {
+    case ';':
+      tmp->set_print_flag (false);
+      break;
+
+    case 0:
+    case ',':
+    case '\n':
+      tmp->set_print_flag (true);
+      if (warn_missing_semi)
+	maybe_warn_missing_semi (list);
+      break;
+
+    default:
+      warning ("unrecognized separator type!");
+      break;
+    }
+
+  // Even if a statement is null, we add it to the list then remove it
+  // here so that the print flag is applied to the correct statement.
+
+  if (tmp->is_null_statement ())
+    {
+      list->pop_back ();
+      delete tmp;
+    }
+
+  return list;
+}
+
+static tree_statement_list *
+make_statement_list (tree_statement *stmt)
+{
+  return new tree_statement_list (stmt);
+}
+
+static tree_statement_list *
+append_statement_list (tree_statement_list *list, char sep,
+		       tree_statement *stmt, bool warn_missing_semi)
+{
+  set_stmt_print_flag (list, sep, warn_missing_semi);
+
+  list->append (stmt);
+
+  return list;
+}
+
+static void
+safe_fclose (void *f)
+{
+  // FIXME -- comments at the end of an input file are
+  // discarded (otherwise, they would be appended to the next
+  // statement, possibly from the command line or another file, which
+  // can be quite confusing).
+
+  octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+  delete tc;
+
+  if (f)
+    fclose (static_cast<FILE *> (f));
+}
+
+static bool
+looks_like_copyright (const std::string& s)
+{
+  bool retval = false;
+
+  if (! s.empty ())
+    {
+      size_t offset = s.find_first_not_of (" \t");
+  
+      retval = (s.substr (offset, 9) == "Copyright");
+    }
+
+  return retval;
+}
+
+static int
+text_getc (FILE *f)
+{
+  int c = getc (f);
+
+  // Convert CRLF into just LF and single CR into LF.
+
+  if (c == '\r')
+    {
+      c = getc (f);
+
+      if (c != '\n')
+	{
+	  ungetc (c, f);
+	  c = '\n';
+	}
+    }
+
+  if (c == '\n')
+    input_line_number++;
+
+  return c;
+}
+
+class
+stdio_stream_reader : public stream_reader
+{
+public:
+  stdio_stream_reader (FILE *f_arg) : stream_reader (), f (f_arg) { }
+
+  int getc (void) { return ::text_getc (f); }
+  int ungetc (int c)
+  {
+    if (c == '\n')
+      input_line_number--;
+
+    return ::ungetc (c, f);
+  }
+  
+private:
+  FILE *f;
+};
+
+static bool
+skip_white_space (stream_reader& reader)
+{
+  int c = 0;
+
+  while ((c = reader.getc ()) != EOF)
+    {
+      switch (c)
+	{
+	case ' ':
+	case '\t':
+	  current_input_column++;
+	  break;
+
+	case '\n':
+	  current_input_column = 0;
+	  break;
+
+	default:
+	  current_input_column--;
+	  reader.ungetc (c);
+	  goto done;
+	}
+    }
+
+ done:
+
+  return (c == EOF);
+}
+
+static std::string
+gobble_leading_white_space (FILE *ffile, bool& eof)
+{
+  std::string help_txt;
+
+  eof = false;
+
+  // TRUE means we have already cached the help text.
+  bool have_help_text = false;
+
+  std::string txt;
+
+  stdio_stream_reader stdio_reader (ffile);
+
+  while (true)
+    {
+      eof = skip_white_space (stdio_reader);
+
+      if (eof)
+	break;
+
+      txt = grab_comment_block (stdio_reader, true, eof);
+
+      if (txt.empty ())
+	break;
+
+      if (! (have_help_text || looks_like_copyright (txt)))
+	{
+	  help_txt = txt;
+	  have_help_text = true;
+	}
+
+      octave_comment_buffer::append (txt);
+
+      if (eof)
+	break;
+    }
+
+  return help_txt;
+}
+
+static bool
+looking_at_function_keyword (FILE *ffile)
+{
+  bool status = false;
+
+  long pos = ftell (ffile);
+
+  char buf [10];
+  fgets (buf, 10, ffile);
+  size_t len = strlen (buf);
+  if (len > 8 && strncmp (buf, "function", 8) == 0
+      && ! (isalnum (buf[8]) || buf[8] == '_'))
+    status = true;
+
+  fseek (ffile, pos, SEEK_SET);
+
+  return status;
+}
+
+static void
+restore_command_history (void *)
+{
+  command_history::ignore_entries (! Vsaving_history);
+}
+
+static void
+restore_input_stream (void *f)
+{
+  command_editor::set_input_stream (static_cast<FILE *> (f));
+}
+
+static octave_function *
+parse_fcn_file (const std::string& ff, const std::string& dispatch_type,
+		bool force_script = false, bool require_file = true,
+		const std::string& warn_for = std::string ())
+{
+  unwind_protect::begin_frame ("parse_fcn_file");
+
+  octave_function *fcn_ptr = 0;
+
+  // Open function file and parse.
+
+  bool old_reading_fcn_file_state = reading_fcn_file;
+
+  FILE *in_stream = command_editor::get_input_stream ();
+
+  unwind_protect::add (restore_input_stream, in_stream);
+
+  unwind_protect_ptr (ff_instream);
+
+  unwind_protect_int (input_line_number);
+  unwind_protect_int (current_input_column);
+  unwind_protect_int (end_tokens_expected);
+  unwind_protect_bool (reading_fcn_file);
+  unwind_protect_bool (line_editing);
+  unwind_protect_str (parent_function_name);
+  unwind_protect_str (current_class_name);
+
+  input_line_number = 1;
+  current_input_column = 1;
+  end_tokens_expected = 0;
+  reading_fcn_file = true;
+  line_editing = false;
+  parent_function_name = "";
+  current_class_name = dispatch_type;
+
+  // The next four lines must be in this order.
+  unwind_protect::add (restore_command_history, 0);
+
+  // FIXME -- we shouldn't need both the
+  // command_history object and the
+  // Vsaving_history variable...
+  command_history::ignore_entries ();
+
+  unwind_protect_bool (Vsaving_history);
+
+  Vsaving_history = false;
+
+  FILE *ffile = get_input_from_file (ff, 0);
+
+  unwind_protect::add (safe_fclose, ffile);
+
+  if (ffile)
+    {
+      bool eof;
+
+      std::string help_txt = gobble_leading_white_space (ffile, eof);
+
+      if (! eof)
+	{
+	  std::string file_type;
+
+	  bool parsing_script = false;
+
+	  unwind_protect_bool (get_input_from_eval_string);
+	  unwind_protect_bool (parser_end_of_input);
+
+	  get_input_from_eval_string = false;
+	  parser_end_of_input = false;
+
+	  if (! force_script && looking_at_function_keyword (ffile))
+	    {
+	      file_type = "function";
+
+	      unwind_protect_int (Vecho_executing_commands);
+	      unwind_protect_bool (reading_fcn_file);
+
+	      Vecho_executing_commands = ECHO_OFF;
+	      reading_fcn_file = true;
+	    }
+	  else
+	    {
+	      file_type = "script";
+
+	      // The value of `reading_fcn_file' will be restored to the
+	      // proper value when we unwind from this frame.
+	      reading_fcn_file = old_reading_fcn_file_state;
+
+	      unwind_protect_bool (reading_script_file);
+
+	      reading_script_file = true;
+
+	      parsing_script = true;
+	    }
+
+	  YY_BUFFER_STATE old_buf = current_buffer ();
+	  YY_BUFFER_STATE new_buf = create_buffer (ffile);
+
+	  unwind_protect::add (restore_input_buffer, old_buf);
+	  unwind_protect::add (delete_input_buffer, new_buf);
+
+	  switch_to_buffer (new_buf);
+
+	  unwind_protect_ptr (curr_fcn_ptr);
+	  curr_fcn_ptr = 0;
+
+	  reset_parser ();
+
+	  // Do this with an unwind-protect cleanup function so that
+	  // the forced variables will be unmarked in the event of an
+	  // interrupt. 
+	  symbol_table::scope_id scope = symbol_table::top_scope ();
+	  unwind_protect::add (symbol_table::unmark_forced_variables, &scope);
+
+	  if (! help_txt.empty ())
+	    help_buf.push (help_txt);
+
+	  if (parsing_script)
+	    prep_lexer_for_script ();
+
+	  lexer_flags.parsing_class_method = ! dispatch_type.empty ();
+
+	  int status = yyparse ();
+
+	  fcn_ptr = curr_fcn_ptr;
+
+	  if (status != 0)
+	    error ("parse error while reading %s file %s",
+		   file_type.c_str(), ff.c_str ());
+	}
+    }
+  else if (require_file)
+    error ("no such file, `%s'", ff.c_str ());
+  else if (! warn_for.empty ())
+    error ("%s: unable to open file `%s'", warn_for.c_str (), ff.c_str ());    
+
+  unwind_protect::run_frame ("parse_fcn_file");
+
+  return fcn_ptr;
+}
+
+std::string
+get_help_from_file (const std::string& nm, bool& symbol_found,
+		    std::string& file)
+{
+  std::string retval;
+
+  file = fcn_file_in_path (nm);
+
+  if (! file.empty ())
+    {
+      symbol_found = true;
+
+      FILE *fptr = fopen (file.c_str (), "r");
+
+      if (fptr)
+	{
+	  unwind_protect::add (safe_fclose, fptr);
+
+	  bool eof;
+	  retval = gobble_leading_white_space (fptr, eof);
+
+	  if (retval.empty ())
+	    {
+	      octave_function *fcn = parse_fcn_file (file, "");
+
+	      if (fcn)
+		{
+		  retval = fcn->doc_string ();
+
+		  delete fcn;
+		}
+	    }
+
+	  unwind_protect::run ();
+	}
+    }
+
+  return retval;
+}
+
+std::string
+get_help_from_file (const std::string& nm, bool& symbol_found)
+{
+  std::string file;
+  return get_help_from_file (nm, symbol_found, file);
+}
+
+std::string
+lookup_autoload (const std::string& nm)
+{
+  std::string retval;
+
+  typedef std::map<std::string, std::string>::const_iterator am_iter;
+
+  am_iter p = autoload_map.find (nm);
+
+  if (p != autoload_map.end ())
+    retval = load_path::find_file (p->second);
+
+  return retval;
+}
+
+string_vector 
+autoloaded_functions (void)
+{
+  string_vector names (autoload_map.size());
+
+  octave_idx_type i = 0;
+  typedef std::map<std::string, std::string>::const_iterator am_iter;
+  for (am_iter p = autoload_map.begin (); p != autoload_map.end (); p++)
+    names[i++] = p->first;
+
+  return names;
+}
+
+string_vector
+reverse_lookup_autoload (const std::string& nm)
+{
+  string_vector names;
+
+  typedef std::map<std::string, std::string>::const_iterator am_iter;
+  for (am_iter p = autoload_map.begin (); p != autoload_map.end (); p++)
+    if (nm == p->second)
+      names.append (p->first);
+
+  return names;
+}
+
+octave_function *
+load_fcn_from_file (const std::string& file_name, const std::string& dir_name,
+		    const std::string& dispatch_type,
+		    const std::string& fcn_name, bool autoload)
+{
+  octave_function *retval = 0;
+
+  unwind_protect::begin_frame ("load_fcn_from_file");
+
+  std::string nm = file_name;
+
+  size_t nm_len = nm.length ();
+
+  std::string file;
+
+  unwind_protect_bool (fcn_file_from_relative_lookup);
+
+  fcn_file_from_relative_lookup = false;
+
+  file = nm;
+
+  if ((nm_len > 4 && nm.substr (nm_len-4) == ".oct")
+      || (nm_len > 4 && nm.substr (nm_len-4) == ".mex")
+      || (nm_len > 2 && nm.substr (nm_len-2) == ".m"))
+    {
+      nm = octave_env::base_pathname (file);
+      nm = nm.substr (0, nm.find_last_of ('.'));
+    }
+
+  if (autoload)
+    {
+      unwind_protect_bool (autoloading);
+      autoloading = true;
+    }
+
+  fcn_file_from_relative_lookup = ! octave_env::absolute_pathname (file);
+
+  file = octave_env::make_absolute (file, octave_env::getcwd ());
+
+  int len = file.length ();
+
+  if (len > 4 && file.substr (len-4, len-1) == ".oct")
+    {
+      if (autoload && ! fcn_name.empty ())
+	nm = fcn_name;
+
+      retval = octave_dynamic_loader::load_oct (nm, file, fcn_file_from_relative_lookup);
+    }
+  else if (len > 4 && file.substr (len-4, len-1) == ".mex")
+    retval = octave_dynamic_loader::load_mex (nm, file, fcn_file_from_relative_lookup);
+  else if (len > 2)
+    {
+      // These are needed by yyparse.
+
+      unwind_protect_str (curr_fcn_file_name);
+      unwind_protect_str (curr_fcn_file_full_name);
+
+      curr_fcn_file_name = nm;
+      curr_fcn_file_full_name = file;
+
+      retval = parse_fcn_file (file, dispatch_type, autoloading);
+    }
+
+  if (retval)
+    {
+      retval->stash_dir_name (dir_name);
+
+      if (retval->is_user_function ())
+	{
+	  symbol_table::scope_id id = retval->scope ();
+
+	  symbol_table::stash_dir_name_for_subfunctions (id, dir_name);
+	}
+    }
+
+  unwind_protect::run_frame ("load_fcn_from_file");
+
+  return retval;
+}
+
+DEFUN (autoload, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\
+Define @var{function} to autoload from @var{file}.\n\
+\n\
+The second argument, @var{file}, should be an absolute file name or\n\
+a file name in the same directory as the function or script from which\n\
+the autoload command was run.  @var{file} should not depend on the\n\
+Octave load path.\n\
+\n\
+Normally, calls to @code{autoload} appear in PKG_ADD script files that\n\
+are evaluated when a directory is added to the Octave's load path.  To\n\
+avoid having to hardcode directory names in @var{file}, if @var{file}\n\
+is in the same directory as the PKG_ADD script then\n\
+\n\
+ at example\n\
+autoload (\"foo\", \"bar.oct\");\n\
+ at end example\n\
+\n\
+will load the function @code{foo} from the file @code{bar.oct}.  The above\n\
+when @code{bar.oct} is not in the same directory or uses like\n\
+\n\
+ at example\n\
+autoload (\"foo\", file_in_loadpath (\"bar.oct\"))\n\
+ at end example\n\
+\n\
+ at noindent\n\
+are strongly discouraged, as their behavior might be unpredictable.\n\
+\n\
+With no arguments, return a structure containing the current autoload map.\n\
+ at seealso{PKG_ADD}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      Cell func_names (dim_vector (autoload_map.size ()), 1);
+      Cell file_names (dim_vector (autoload_map.size ()), 1);
+
+      octave_idx_type i = 0;
+      typedef std::map<std::string, std::string>::const_iterator am_iter;
+      for (am_iter p = autoload_map.begin (); p != autoload_map.end (); p++)
+	{
+	  func_names(i) = p->first;
+	  file_names(i) = p->second;
+
+	  i++;
+	}
+
+      Octave_map m;
+
+      m.assign ("function", func_names);
+      m.assign ("file", file_names);
+
+      retval = m;
+    }
+  else if (nargin == 2)
+    {
+      string_vector argv = args.make_argv ("autoload");
+
+      if (! error_state)
+        {
+	  std::string nm = argv[2];
+
+	  if (! octave_env::absolute_pathname (nm))
+	    {
+	      octave_user_code *fcn = octave_call_stack::caller_user_code ();
+
+	      bool found = false;
+
+	      if (fcn)
+		{
+		  std::string fname = fcn->fcn_file_name ();
+
+		  if (! fname.empty ())
+		    {
+		      fname = octave_env::make_absolute (fname, octave_env::getcwd ());
+		      fname = fname.substr (0, fname.find_last_of (file_ops::dir_sep_str ()) + 1);
+
+		      file_stat fs (fname + nm);
+
+		      if (fs.exists ())
+			{
+			  nm = fname + nm;
+			  found = true;
+			}
+		    }
+		}
+	      if (! found)
+		warning_with_id ("Octave:autoload-relative-file-name",
+				 "autoload: `%s' is not an absolute file name",
+				 nm.c_str ());
+	    }
+	  autoload_map[argv[1]] = nm;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+void
+source_file (const std::string& file_name, const std::string& context,
+	     bool verbose, bool require_file, const std::string& warn_for)
+{
+  std::string file_full_name = file_ops::tilde_expand (file_name);
+
+  unwind_protect::begin_frame ("source_file");
+
+  unwind_protect_str (curr_fcn_file_name);
+  unwind_protect_str (curr_fcn_file_full_name);
+
+  curr_fcn_file_name = file_name;
+  curr_fcn_file_full_name = file_full_name;
+
+  if (! context.empty ())
+    {
+      if (context == "caller")
+	octave_call_stack::goto_caller_frame ();
+      else if (context == "base")
+	octave_call_stack::goto_base_frame ();
+      else
+	error ("source: context must be \"caller\" or \"base\"");
+
+      if (! error_state)
+	unwind_protect::add (octave_call_stack::unwind_pop);
+    }      
+
+  if (! error_state)
+    {
+      octave_function *fcn = parse_fcn_file (file_full_name, "", true,
+					     require_file, warn_for);
+
+      if (! error_state)
+	{
+	  if (fcn && fcn->is_user_script ())
+	    {
+	      octave_value_list args;
+
+	      if (verbose)
+		{
+		  std::cout << "executing commands from " << file_full_name << " ... ";
+		  reading_startup_message_printed = true;
+		  std::cout.flush ();
+		}
+
+	      fcn->do_multi_index_op (0, args);
+
+	      if (verbose)
+		std::cout << "done." << std::endl;
+
+	      delete fcn;
+	    }
+	}
+      else
+	error ("source: error sourcing file `%s'",
+	       file_full_name.c_str ());
+    }
+
+  unwind_protect::run_frame ("source_file");
+}
+
+DEFUN (mfilename, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mfilename ()\n\
+ at deftypefnx {Built-in Function} {} mfilename (@code{\"fullpath\"})\n\
+ at deftypefnx {Built-in Function} {} mfilename (@code{\"fullpathext\"})\n\
+Return the name of the currently executing file.  At the top-level,\n\
+return the empty string.  Given the argument @code{\"fullpath\"},\n\
+include the directory part of the file name, but not the extension.\n\
+Given the argument @code{\"fullpathext\"}, include the directory part\n\
+of the file name and the extension.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string arg;
+
+  if (nargin == 1)
+    {
+      arg = args(0).string_value ();
+
+      if (error_state)
+	{
+	  error ("mfilename: expecting argument to be a character string");
+	  return retval;
+	}
+    }
+
+  std::string fname;
+
+  octave_user_code *fcn = octave_call_stack::caller_user_code ();
+
+  if (fcn)
+    {
+      fname = fcn->fcn_file_name ();
+
+      if (fname.empty ())
+        fname = fcn->name ();
+    }
+
+  if (arg == "fullpathext")
+    retval = fname;
+  else
+    {
+      size_t dpos = fname.rfind (file_ops::dir_sep_char ());
+      size_t epos = fname.rfind ('.');
+
+      if (epos <= dpos)
+        epos = std::string::npos;
+
+      fname = (epos != std::string::npos) ? fname.substr (0, epos) : fname;
+
+      if (arg == "fullpath")
+	retval = fname;
+      else
+        retval = (dpos != std::string::npos) ? fname.substr (dpos+1) : fname;
+    }
+
+  return retval;
+}
+
+
+DEFUN (source, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} source (@var{file})\n\
+Parse and execute the contents of @var{file}.  This is equivalent to\n\
+executing commands from a script file, but without requiring the file to\n\
+be named @file{@var{file}.m}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string file_name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string context;
+
+	  if (nargin == 2)
+	    context = args(1).string_value ();
+
+	  if (! error_state)
+	    source_file (file_name, context);
+	  else
+	    error ("source: expecting context to be character string");
+	}
+      else
+	error ("source: expecting file name as argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Evaluate an Octave function (built-in or interpreted) and return
+// the list of result values.  NAME is the name of the function to
+// call.  ARGS are the arguments to the function.  NARGOUT is the
+// number of output arguments expected. 
+
+octave_value_list
+feval (const std::string& name, const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  octave_value fcn = symbol_table::find_function (name, args);
+
+  if (fcn.is_defined ())
+    retval = fcn.do_multi_index_op (nargout, args);
+  else
+    error ("feval: function `%s' not found", name.c_str ());
+
+  return retval;
+}
+
+octave_value_list
+feval (octave_function *fcn, const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  if (fcn)
+    retval = fcn->do_multi_index_op (nargout, args);
+
+  return retval;
+}
+
+static octave_value_list
+get_feval_args (const octave_value_list& args)
+{
+  int tmp_nargin = args.length () - 1;
+
+  octave_value_list retval (tmp_nargin, octave_value ());
+
+  for (int i = 0; i < tmp_nargin; i++)
+    retval(i) = args(i+1);
+
+  string_vector arg_names = args.name_tags ();
+
+  if (! arg_names.empty ())
+    {
+      // tmp_nargin and arg_names.length () - 1 may differ if
+      // we are passed all_va_args.
+
+      int n = arg_names.length () - 1;
+
+      int len = n > tmp_nargin ? tmp_nargin : n;
+
+      string_vector tmp_arg_names (len);
+
+      for (int i = 0; i < len; i++)
+	tmp_arg_names(i) = arg_names(i+1);
+
+      retval.stash_name_tags (tmp_arg_names);
+    }
+
+  return retval;
+}
+
+
+// Evaluate an Octave function (built-in or interpreted) and return
+// the list of result values.  The first element of ARGS should be a
+// string containing the name of the function to call, then the rest
+// are the actual arguments to the function.  NARGOUT is the number of
+// output arguments expected.
+
+octave_value_list
+feval (const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      octave_value f_arg = args(0);
+
+      if (f_arg.is_string ())
+        {
+	  std::string name = f_arg.string_value ();
+
+	  if (! error_state)
+	    {
+	      octave_value_list tmp_args = get_feval_args (args);
+
+	      retval = feval (name, tmp_args, nargout);
+	    }
+	}
+      else
+	{
+	  octave_function *fcn = f_arg.function_value ();
+
+	  if (fcn)
+	    {
+	      octave_value_list tmp_args = get_feval_args (args);
+
+	      retval = feval (fcn, tmp_args, nargout);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (feval, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} feval (@var{name}, @dots{})\n\
+Evaluate the function named @var{name}.  Any arguments after the first\n\
+are passed on to the named function.  For example,\n\
+\n\
+ at example\n\
+feval (\"acos\", -1)\n\
+     @result{} 3.1416\n\
+ at end example\n\
+\n\
+ at noindent\n\
+calls the function @code{acos} with the argument @samp{-1}.\n\
+\n\
+The function @code{feval} is necessary in order to be able to write\n\
+functions that call user-supplied functions, because Octave does not\n\
+have a way to declare a pointer to a function (like C) or to declare a\n\
+special kind of variable that can be used to hold the name of a function\n\
+(like @code{EXTERNAL} in Fortran).  Instead, you must refer to functions\n\
+by name, and use @code{feval} to call them.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    retval = feval (args, nargout);
+  else
+    print_usage ();
+
+  return retval;
+}
+
+octave_value_list
+eval_string (const std::string& s, bool silent, int& parse_status, int nargout)
+{
+  octave_value_list retval;
+
+  unwind_protect::begin_frame ("eval_string");
+
+  unwind_protect_int (input_line_number);
+  unwind_protect_int (current_input_column);
+  unwind_protect_bool (get_input_from_eval_string);
+  unwind_protect_bool (input_from_eval_string_pending);
+  unwind_protect_bool (parser_end_of_input);
+  unwind_protect_bool (line_editing);
+  unwind_protect_str (current_eval_string);
+
+  input_line_number = 1;
+  current_input_column = 1;
+  get_input_from_eval_string = true;
+  input_from_eval_string_pending = true;
+  parser_end_of_input = false;
+  line_editing = false;
+
+  current_eval_string = s;
+
+  YY_BUFFER_STATE old_buf = current_buffer ();
+  YY_BUFFER_STATE new_buf = create_buffer (0);
+
+  unwind_protect::add (restore_input_buffer, old_buf);
+  unwind_protect::add (delete_input_buffer, new_buf);
+
+  switch_to_buffer (new_buf);
+
+  do
+    {
+      reset_parser ();
+
+      unwind_protect_ptr (global_command);
+
+      // Do this with an unwind-protect cleanup function so that the
+      // forced variables will be unmarked in the event of an
+      // interrupt.
+      symbol_table::scope_id scope = symbol_table::top_scope ();
+      unwind_protect::add (symbol_table::unmark_forced_variables, &scope);
+
+      parse_status = yyparse ();
+
+      tree_statement_list *command_list = global_command;
+
+      // Unmark forced variables.
+      unwind_protect::run ();
+
+      // Restore previous value of global_command.
+      unwind_protect::run ();
+
+      if (parse_status == 0)
+        {
+	  if (command_list)
+	    {
+	      tree_statement *stmt = 0;
+
+	      if (command_list->length () == 1
+		  && (stmt = command_list->front ())
+		  && stmt->is_expression ())
+		{
+		  tree_expression *expr = stmt->expression ();
+
+		  if (silent)
+		    expr->set_print_flag (false);
+
+		  bool do_bind_ans = false;
+
+		  if (expr->is_identifier ())
+		    {
+		      tree_identifier *id
+			= dynamic_cast<tree_identifier *> (expr);
+
+		      do_bind_ans = (! id->is_variable ());
+		    }
+		  else
+		    do_bind_ans = (! expr->is_assignment_expression ());
+
+		  retval = expr->rvalue (nargout);
+
+		  if (do_bind_ans && ! (error_state || retval.empty ()))
+		    bind_ans (retval(0), expr->print_result ());
+
+		  if (nargout == 0)
+		    retval = octave_value_list ();
+		}
+	      else if (nargout == 0)
+		command_list->accept (*current_evaluator);
+	      else
+		error ("eval: invalid use of statement list");
+
+	      delete command_list;
+
+	      command_list = 0;
+
+	      if (error_state
+		  || tree_return_command::returning
+		  || tree_break_command::breaking
+		  || tree_continue_command::continuing)
+		break;
+	    }
+	  else if (parser_end_of_input)
+	    break;
+        }
+    }
+  while (parse_status == 0);
+
+  unwind_protect::run_frame ("eval_string");
+
+  return retval;
+}
+
+octave_value
+eval_string (const std::string& s, bool silent, int& parse_status)
+{
+  octave_value retval;
+
+  octave_value_list tmp = eval_string (s, silent, parse_status, 1);
+
+  if (! tmp.empty ())
+    retval = tmp(0);
+
+  return retval;
+}
+
+static octave_value_list
+eval_string (const octave_value& arg, bool silent, int& parse_status,
+	     int nargout)
+{
+  std::string s = arg.string_value ();
+
+  if (error_state)
+    {
+      error ("eval: expecting std::string argument");
+      return octave_value (-1);
+    }
+
+  return eval_string (s, silent, parse_status, nargout);
+}
+
+DEFUN (eval, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} eval (@var{try}, @var{catch})\n\
+Parse the string @var{try} and evaluate it as if it were an Octave\n\
+program.  If that fails, evaluate the optional string @var{catch}.\n\
+The string @var{try} is evaluated in the current context,\n\
+so any results remain available after @code{eval} returns.\n\
+\n\
+The following example makes the variable @var{a} with the approximate\n\
+value 3.1416 available.\n\
+\n\
+ at example\n\
+eval(\"a = acos(-1);\");\n\
+ at end example\n\
+\n\
+If an error occurs during the evaluation of @var{try} the @var{catch}\n\
+string is evaluated, as the following example shows:\n\
+\n\
+ at example\n\
+eval ('error (\"This is a bad example\");',\n\
+      'printf (\"This error occurred:\\n%s\\n\", lasterr ());');\n\
+     @print{} This error occurred:\n\
+        This is a bad example\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      unwind_protect::begin_frame ("Feval");
+
+      if (nargin > 1)
+	{
+	  unwind_protect_int (buffer_error_messages);
+	  buffer_error_messages++;
+	}
+
+      int parse_status = 0;
+
+      octave_value_list tmp = eval_string (args(0), nargout > 0,
+					   parse_status, nargout);
+
+      if (nargin > 1 && (parse_status != 0 || error_state))
+	{
+	  error_state = 0;
+
+	  // Set up for letting the user print any messages from
+	  // errors that occurred in the first part of this eval().
+
+	  buffer_error_messages--;
+
+	  tmp = eval_string (args(1), nargout > 0, parse_status, nargout);
+
+	  if (nargout > 0)
+	    retval = tmp;
+	}
+      else if (nargout > 0)
+	retval = tmp;
+
+      unwind_protect::run_frame ("Feval");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%% test/octave.test/eval/eval-1.m
+%!#test
+%! x = 1;
+%! assert(eval ("x"),1);
+
+%% test/octave.test/eval/eval-2.m
+%!test
+%! x = 1;
+%! assert(eval ("x;"));
+
+%% test/octave.test/eval/eval-3.m
+%!test
+%! x = 1;
+%! assert(eval ("x;"),1);
+
+%% FIXME
+%% Disable this test as adding the ";" is redundant with eval-1 and
+%% in any case is a syntax error with assert
+%% test/octave.test/eval/eval-4.m
+%!#test
+%! x = 1;
+%! assert(eval ("x");,1);
+
+%% test/octave.test/eval/eval-5.m
+%!test
+%! eval ("flipud = 2;");
+%! assert(flipud,2);
+
+%% test/octave.test/eval/eval-6.m
+%!function y = f ()
+%!  eval ("flipud = 2;");
+%!  y = flipud;
+%!test
+%! assert(f,2);
+
+%% test/octave.test/eval/eval-7.m
+%!#test
+%! eval ("x = 1");
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-8.m
+%!test
+%! eval ("x = 1;")
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-9.m
+%!test
+%! eval ("x = 1;");
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-10.m
+%!#test
+%! eval ("x = 1")
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-11.m
+%!test
+%! x = 1;
+%! y = eval ("x");
+%! assert(y,1);
+
+%% test/octave.test/eval/eval-12.m
+%!test
+%! x = 1;
+%! y = eval ("x;");
+%! assert(y,1);
+
+%% test/octave.test/eval/eval-13.m
+%!test
+%! x = 1;
+%! y = eval ("x;");
+%! assert(y,1);
+
+%% test/octave.test/eval/eval-14.m
+%!test
+%! x = 1;
+%! y = eval ("x");
+%! assert(y,1);
+
+*/
+
+DEFUN (assignin, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\
+Assign @var{value} to @var{varname} in context @var{context}, which\n\
+may be either @code{\"base\"} or @code{\"caller\"}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 3)
+    {
+      std::string context = args(0).string_value ();
+
+      if (! error_state)
+        {
+	  unwind_protect::begin_frame ("Fassignin");
+
+	  if (context == "caller")
+	    octave_call_stack::goto_caller_frame ();
+	  else if (context == "base")
+	    octave_call_stack::goto_base_frame ();
+	  else
+	    error ("assignin: context must be \"caller\" or \"base\"");
+
+	  if (! error_state)
+	    {
+	      unwind_protect::add (octave_call_stack::unwind_pop);
+
+	      std::string nm = args(1).string_value ();
+
+	      if (! error_state)
+		{
+		  if (valid_identifier (nm))
+		    symbol_table::varref (nm) = args(2);
+		  else
+		    error ("assignin: invalid variable name");
+		}
+	      else
+		error ("assignin: expecting variable name as second argument");
+	    }
+
+	  unwind_protect::run_frame ("Fassignin");
+	}
+      else
+        error ("assignin: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (evalin, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\
+Like @code{eval}, except that the expressions are evaluated in the\n\
+context @var{context}, which may be either @code{\"caller\"} or\n\
+ at code{\"base\"}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 1)
+    {
+      std::string context = args(0).string_value ();
+
+      if (! error_state)
+        {
+	  unwind_protect::begin_frame ("Fevalin");
+
+	  if (context == "caller")
+	    octave_call_stack::goto_caller_frame ();
+	  else if (context == "base")
+	    octave_call_stack::goto_base_frame ();
+	  else
+	    error ("evalin: context must be \"caller\" or \"base\"");
+
+	  if (! error_state)
+	    {
+	      unwind_protect::add (octave_call_stack::unwind_pop);
+
+	      if (nargin > 2)
+	        {
+		  unwind_protect_int (buffer_error_messages);
+		  buffer_error_messages++;
+		}
+
+	      int parse_status = 0;
+
+	      octave_value_list tmp = eval_string (args(1), nargout > 0,
+						   parse_status, nargout);
+
+	      if (nargout > 0)
+		retval = tmp;
+
+	      if (nargin > 2 && (parse_status != 0 || error_state))
+		{
+		  error_state = 0;
+
+		  // Set up for letting the user print any messages from
+		  // errors that occurred in the first part of this eval().
+
+		  buffer_error_messages--;
+
+		  tmp = eval_string (args(2), nargout > 0,
+				     parse_status, nargout);
+
+		  retval = (nargout > 0) ? tmp : octave_value_list ();
+		}
+	    }
+
+	  unwind_protect::run_frame ("Fevalin");
+	}
+      else
+        error ("evalin: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__parser_debug_flag__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{old_val} =} __parser_debug_flag__ (@var{new_val}))\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  bool debug_flag = octave_debug;
+
+  retval = set_internal_variable (debug_flag, args, nargout,
+           			  "__parser_debug_flag__");
+
+  octave_debug = debug_flag;
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: text ***
+;;; End: ***
+*/
+
diff --git a/src/parse.h b/src/parse.h
new file mode 100644
index 0000000..583c3e1
--- /dev/null
+++ b/src/parse.h
@@ -0,0 +1,130 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_parse_h)
+#define octave_parse_h 1
+
+#include <cstdio>
+
+#include <string>
+
+#include <stack>
+
+extern void reset_parser (void);
+extern int octave_lex (void);
+extern int octave_parse (void);
+
+class tree;
+class tree_matrix;
+class tree_identifier;
+class octave_function;
+
+#include "oct-obj.h"
+
+// Nonzero means print parser debugging info (-d).
+extern int octave_debug;
+
+// The current input line number.
+extern int input_line_number;
+
+// The column of the current token.
+extern int current_input_column;
+
+// Buffer for help text snagged from function files.
+extern std::stack<std::string> help_buf;
+
+// TRUE means we are using readline.
+extern bool line_editing;
+
+// TRUE means we printed messages about reading startup files.
+extern bool reading_startup_message_printed;
+
+// TRUE means input is coming from startup file.
+extern bool input_from_startup_file;
+
+// Keep track of symbol table information when parsing functions.
+extern std::stack<symbol_table::scope_id> symtab_context;
+
+// Name of parent function when parsing function files that might
+// contain nested functions.
+extern std::string parent_function_name;
+
+// Name of the current class when we are parsing class methods or
+// constructors.
+extern std::string current_class_name;
+
+// Keep a count of how many END tokens we expect.
+extern int end_tokens_expected;
+
+extern OCTINTERP_API std::string
+get_help_from_file (const std::string& nm, bool& symbol_found,
+		    std::string& file);
+
+extern OCTINTERP_API std::string
+get_help_from_file (const std::string& nm, bool& symbol_found);
+
+extern OCTINTERP_API std::string lookup_autoload (const std::string& nm);
+
+extern OCTINTERP_API string_vector autoloaded_functions (void);
+
+extern OCTINTERP_API string_vector reverse_lookup_autoload (const std::string& nm);
+
+extern OCTINTERP_API octave_function *
+load_fcn_from_file (const std::string& file_name,
+		    const std::string& dir_name = std::string (),
+		    const std::string& dispatch_type = std::string (),
+		    const std::string& fcn_name = std::string (),
+		    bool autoload = false);
+
+extern OCTINTERP_API void
+source_file (const std::string& file_name,
+	     const std::string& context = std::string (),
+	     bool verbose = false, bool require_file = true,
+	     const std::string& warn_for = std::string ());
+
+extern OCTINTERP_API octave_value_list
+feval (const std::string& name,
+       const octave_value_list& args = octave_value_list (),
+       int nargout = 0);
+
+extern OCTINTERP_API octave_value_list
+feval (octave_function *fcn,
+       const octave_value_list& args = octave_value_list (),
+       int nargout = 0);
+
+extern OCTINTERP_API octave_value_list
+feval (const octave_value_list& args, int nargout = 0);
+
+extern OCTINTERP_API octave_value_list
+eval_string (const std::string&, bool silent, int& parse_status, int hargout);
+
+extern OCTINTERP_API octave_value
+eval_string (const std::string&, bool silent, int& parse_status);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/parse.y b/src/parse.y
new file mode 100644
index 0000000..489cf03
--- /dev/null
+++ b/src/parse.y
@@ -0,0 +1,4323 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009  John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Parser for Octave.
+
+// C decarations.
+
+%{
+#define YYDEBUG 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cstdio>
+
+#ifdef YYBYACC
+#include <cstdlib>
+#endif
+
+#include <iostream>
+#include <map>
+#include <sstream>
+
+#include "Cell.h"
+#include "Matrix.h"
+#include "cmd-edit.h"
+#include "cmd-hist.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+
+#include "comment-list.h"
+#include "defaults.h"
+#include "defun.h"
+#include "dirfns.h"
+#include "dynamic-ld.h"
+#include "error.h"
+#include "input.h"
+#include "lex.h"
+#include "load-path.h"
+#include "oct-hist.h"
+#include "oct-map.h"
+#include "ov-fcn-handle.h"
+#include "ov-usr-fcn.h"
+#include "ov-null-mat.h"
+#include "toplev.h"
+#include "pager.h"
+#include "parse.h"
+#include "pt-all.h"
+#include "pt-eval.h"
+#include "symtab.h"
+#include "token.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// The current input line number.
+int input_line_number = 1;
+
+// The column of the current token.
+int current_input_column = 1;
+
+// Buffer for help text snagged from function files.
+std::stack<std::string> help_buf;
+
+// Buffer for comments appearing before a function statement.
+static std::string fcn_comment_header;
+
+// TRUE means we are using readline.
+// (--no-line-editing)
+bool line_editing = true;
+
+// TRUE means we printed messages about reading startup files.
+bool reading_startup_message_printed = false;
+
+// TRUE means input is coming from startup file.
+bool input_from_startup_file = false;
+
+// Keep a count of how many END tokens we expect.
+int end_tokens_expected = 0;
+
+// Keep track of symbol table information when parsing functions.
+std::stack<symbol_table::scope_id> symtab_context;
+
+// Name of parent function when parsing function files that might
+// contain nested functions.
+std::string parent_function_name;
+
+// Name of the current class when we are parsing class methods or
+// constructors.
+std::string current_class_name;
+
+// TRUE means we are in the process of autoloading a function.
+static bool autoloading = false;
+
+// TRUE means the current function file was found in a relative path
+// element.
+static bool fcn_file_from_relative_lookup = false;
+
+// If nonzero, this is a pointer to the function we just finished
+// parsing.
+static octave_function *curr_fcn_ptr = 0;
+
+// List of autoloads (function -> file mapping).
+static std::map<std::string, std::string> autoload_map;
+
+// Forward declarations for some functions defined at the bottom of
+// the file.
+
+// Generic error messages.
+static void
+yyerror (const char *s);
+
+// Error mesages for mismatched end tokens.
+static void
+end_error (const char *type, token::end_tok_type ettype, int l, int c);
+
+// Check to see that end tokens are properly matched.
+static bool
+end_token_ok (token *tok, token::end_tok_type expected);
+
+// Maybe print a warning if an assignment expression is used as the
+// test in a logical expression.
+static void
+maybe_warn_assign_as_truth_value (tree_expression *expr);
+
+// Maybe print a warning about switch labels that aren't constants.
+static void
+maybe_warn_variable_switch_label (tree_expression *expr);
+
+// Finish building a range.
+static tree_expression *
+finish_colon_expression (tree_colon_expression *e);
+
+// Build a constant.
+static tree_constant *
+make_constant (int op, token *tok_val);
+
+// Build a function handle.
+static tree_fcn_handle *
+make_fcn_handle (token *tok_val);
+
+// Build an anonymous function handle.
+static tree_anon_fcn_handle *
+make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt);
+
+// Build a binary expression.
+static tree_expression *
+make_binary_op (int op, tree_expression *op1, token *tok_val,
+		tree_expression *op2);
+
+// Build a boolean expression.
+static tree_expression *
+make_boolean_op (int op, tree_expression *op1, token *tok_val,
+		 tree_expression *op2);
+
+// Build a prefix expression.
+static tree_expression *
+make_prefix_op (int op, tree_expression *op1, token *tok_val);
+
+// Build a postfix expression.
+static tree_expression *
+make_postfix_op (int op, tree_expression *op1, token *tok_val);
+
+// Build an unwind-protect command.
+static tree_command *
+make_unwind_command (token *unwind_tok, tree_statement_list *body,
+		     tree_statement_list *cleanup, token *end_tok,
+		     octave_comment_list *lc, octave_comment_list *mc);
+
+// Build a try-catch command.
+static tree_command *
+make_try_command (token *try_tok, tree_statement_list *body,
+		  tree_statement_list *cleanup, token *end_tok,
+		  octave_comment_list *lc, octave_comment_list *mc);
+
+// Build a while command.
+static tree_command *
+make_while_command (token *while_tok, tree_expression *expr,
+		    tree_statement_list *body, token *end_tok,
+		    octave_comment_list *lc);
+
+// Build a do-until command.
+static tree_command *
+make_do_until_command (token *until_tok, tree_statement_list *body,
+		       tree_expression *expr, octave_comment_list *lc);
+
+// Build a for command.
+static tree_command *
+make_for_command (token *for_tok, tree_argument_list *lhs,
+		  tree_expression *expr, tree_statement_list *body,
+		  token *end_tok, octave_comment_list *lc);
+
+// Build a break command.
+static tree_command *
+make_break_command (token *break_tok);
+
+// Build a continue command.
+static tree_command *
+make_continue_command (token *continue_tok);
+
+// Build a return command.
+static tree_command *
+make_return_command (token *return_tok);
+
+// Start an if command.
+static tree_if_command_list *
+start_if_command (tree_expression *expr, tree_statement_list *list);
+
+// Finish an if command.
+static tree_if_command *
+finish_if_command (token *if_tok, tree_if_command_list *list,
+		   token *end_tok, octave_comment_list *lc);
+
+// Build an elseif clause.
+static tree_if_clause *
+make_elseif_clause (token *elseif_tok, tree_expression *expr,
+		    tree_statement_list *list, octave_comment_list *lc);
+
+// Finish a switch command.
+static tree_switch_command *
+finish_switch_command (token *switch_tok, tree_expression *expr,
+		       tree_switch_case_list *list, token *end_tok,
+		       octave_comment_list *lc);
+
+// Build a switch case.
+static tree_switch_case *
+make_switch_case (token *case_tok, tree_expression *expr,
+		  tree_statement_list *list, octave_comment_list *lc);
+
+// Build an assignment to a variable.
+static tree_expression *
+make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
+		tree_expression *rhs);
+
+// Define a script.
+static void
+make_script (tree_statement_list *cmds, tree_statement *end_script);
+
+// Begin defining a function.
+static octave_user_function *
+start_function (tree_parameter_list *param_list, tree_statement_list *body,
+		tree_statement *end_function);
+
+// Create a no-op statement for end_function.
+static tree_statement *
+make_end (const std::string& type, int l, int c);
+
+// Do most of the work for defining a function.
+static octave_user_function *
+frob_function (const std::string& fname, octave_user_function *fcn);
+
+// Finish defining a function.
+static tree_function_def *
+finish_function (tree_parameter_list *ret_list,
+		 octave_user_function *fcn, octave_comment_list *lc);
+
+// Reset state after parsing function.
+static void
+recover_from_parsing_function (void);
+
+// Make an index expression.
+static tree_index_expression *
+make_index_expression (tree_expression *expr,
+		       tree_argument_list *args, char type);
+
+// Make an indirect reference expression.
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, const std::string&);
+
+// Make an indirect reference expression with dynamic field name.
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, tree_expression *field);
+
+// Make a declaration command.
+static tree_decl_command *
+make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst);
+
+// Finish building a matrix list.
+static tree_expression *
+finish_matrix (tree_matrix *m);
+
+// Finish building a cell list.
+static tree_expression *
+finish_cell (tree_cell *c);
+
+// Maybe print a warning.  Duh.
+static void
+maybe_warn_missing_semi (tree_statement_list *);
+
+// Set the print flag for a statement based on the separator type.
+static tree_statement_list *
+set_stmt_print_flag (tree_statement_list *, char, bool);
+
+// Create a statement list.
+static tree_statement_list *make_statement_list (tree_statement *stmt);
+
+// Append a statement to an existing statement list.
+static tree_statement_list *
+append_statement_list (tree_statement_list *list, char sep,
+		       tree_statement *stmt, bool warn_missing_semi);
+
+// Finish building a statement.
+template <class T>
+static tree_statement *
+make_statement (T *arg)
+{
+  octave_comment_list *comment = octave_comment_buffer::get_comment ();
+
+  return new tree_statement (arg, comment);
+}
+
+#define ABORT_PARSE \
+  do \
+    { \
+      global_command = 0; \
+      yyerrok; \
+      if (! symtab_context.empty ()) \
+        { \
+	  symbol_table::set_scope (symtab_context.top ()); \
+	  symtab_context.pop (); \
+        } \
+      if (interactive || forced_interactive) \
+	YYACCEPT; \
+      else \
+	YYABORT; \
+    } \
+  while (0)
+
+%}
+
+// Bison declarations.
+
+// Don't add spaces around the = here; it causes some versions of
+// bison to fail to properly recognize the directive.
+
+%name-prefix="octave_"
+
+%union
+{
+  // The type of the basic tokens returned by the lexer.
+  token *tok_val;
+
+  // Comment strings that we need to deal with mid-rule.
+  octave_comment_list *comment_type;
+
+  // Types for the nonterminals we generate.
+  char sep_type;
+  tree *tree_type;
+  tree_matrix *tree_matrix_type;
+  tree_cell *tree_cell_type;
+  tree_expression *tree_expression_type;
+  tree_constant *tree_constant_type;
+  tree_fcn_handle *tree_fcn_handle_type;
+  tree_anon_fcn_handle *tree_anon_fcn_handle_type;
+  tree_identifier *tree_identifier_type;
+  tree_index_expression *tree_index_expression_type;
+  tree_colon_expression *tree_colon_expression_type;
+  tree_argument_list *tree_argument_list_type;
+  tree_parameter_list *tree_parameter_list_type;
+  tree_command *tree_command_type;
+  tree_if_command *tree_if_command_type;
+  tree_if_clause *tree_if_clause_type;
+  tree_if_command_list *tree_if_command_list_type;
+  tree_switch_command *tree_switch_command_type;
+  tree_switch_case *tree_switch_case_type;
+  tree_switch_case_list *tree_switch_case_list_type;
+  tree_decl_elt *tree_decl_elt_type;
+  tree_decl_init_list *tree_decl_init_list_type;
+  tree_decl_command *tree_decl_command_type;
+  tree_statement *tree_statement_type;
+  tree_statement_list *tree_statement_list_type;
+  octave_user_function *octave_user_function_type;
+}
+
+// Tokens with line and column information.
+%token <tok_val> '=' ':' '-' '+' '*' '/'
+%token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ
+%token <tok_val> EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ AND_EQ OR_EQ
+%token <tok_val> LSHIFT_EQ RSHIFT_EQ LSHIFT RSHIFT
+%token <tok_val> EXPR_AND_AND EXPR_OR_OR
+%token <tok_val> EXPR_AND EXPR_OR EXPR_NOT
+%token <tok_val> EXPR_LT EXPR_LE EXPR_EQ EXPR_NE EXPR_GE EXPR_GT
+%token <tok_val> LEFTDIV EMUL EDIV ELEFTDIV EPLUS EMINUS
+%token <tok_val> QUOTE TRANSPOSE
+%token <tok_val> PLUS_PLUS MINUS_MINUS POW EPOW
+%token <tok_val> NUM IMAG_NUM
+%token <tok_val> STRUCT_ELT
+%token <tok_val> NAME
+%token <tok_val> END
+%token <tok_val> DQ_STRING SQ_STRING
+%token <tok_val> FOR WHILE DO UNTIL
+%token <tok_val> IF ELSEIF ELSE
+%token <tok_val> SWITCH CASE OTHERWISE
+%token <tok_val> BREAK CONTINUE FUNC_RET
+%token <tok_val> UNWIND CLEANUP
+%token <tok_val> TRY CATCH
+%token <tok_val> GLOBAL STATIC
+%token <tok_val> FCN_HANDLE
+
+// Other tokens.
+%token END_OF_INPUT LEXICAL_ERROR
+%token FCN SCRIPT
+// %token VARARGIN VARARGOUT
+%token CLOSE_BRACE
+
+// Nonterminals we construct.
+%type <comment_type> stash_comment function_beg
+%type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep
+%type <tree_type> input
+%type <tree_constant_type> string constant magic_colon
+%type <tree_anon_fcn_handle_type> anon_fcn_handle
+%type <tree_fcn_handle_type> fcn_handle
+%type <tree_matrix_type> matrix_rows matrix_rows1
+%type <tree_cell_type> cell_rows cell_rows1
+%type <tree_expression_type> matrix cell
+%type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr
+%type <tree_expression_type> simple_expr colon_expr assign_expr expression
+%type <tree_identifier_type> identifier fcn_name
+%type <octave_user_function_type> function1 function2
+%type <tree_index_expression_type> word_list_cmd
+%type <tree_colon_expression_type> colon_expr1
+%type <tree_argument_list_type> arg_list word_list assign_lhs
+%type <tree_argument_list_type> cell_or_matrix_row
+%type <tree_parameter_list_type> param_list param_list1 param_list2
+%type <tree_parameter_list_type> return_list return_list1
+%type <tree_command_type> command select_command loop_command
+%type <tree_command_type> jump_command except_command function script
+%type <tree_if_command_type> if_command
+%type <tree_if_clause_type> elseif_clause else_clause
+%type <tree_if_command_list_type> if_cmd_list1 if_cmd_list
+%type <tree_switch_command_type> switch_command
+%type <tree_switch_case_type> switch_case default_case
+%type <tree_switch_case_list_type> case_list1 case_list
+%type <tree_decl_elt_type> decl2
+%type <tree_decl_init_list_type> decl1
+%type <tree_decl_command_type> declaration
+%type <tree_statement_type> statement function_end
+%type <tree_statement_list_type> simple_list simple_list1 list list1
+%type <tree_statement_list_type> opt_list input1
+
+// Precedence and associativity.
+%left ';' ',' '\n'
+%right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ
+%left EXPR_OR_OR
+%left EXPR_AND_AND
+%left EXPR_OR
+%left EXPR_AND
+%left EXPR_LT EXPR_LE EXPR_EQ EXPR_NE EXPR_GE EXPR_GT
+%left LSHIFT RSHIFT
+%left ':'
+%left '-' '+' EPLUS EMINUS
+%left '*' '/' LEFTDIV EMUL EDIV ELEFTDIV
+%left UNARY PLUS_PLUS MINUS_MINUS EXPR_NOT
+%left POW EPOW QUOTE TRANSPOSE
+%left '(' '.' '{'
+
+// Where to start.
+%start input
+
+%%
+
+// ==============================
+// Statements and statement lists
+// ==============================
+
+input		: input1
+		  {
+		    global_command = $1;
+		    promptflag = 1;
+		    YYACCEPT;
+		  }
+		| simple_list parse_error
+		  { ABORT_PARSE; }
+		| parse_error
+		  { ABORT_PARSE; }
+		;
+
+input1		: '\n'
+		  { $$ = 0; }
+		| END_OF_INPUT
+		  {
+		    parser_end_of_input = 1;
+		    $$ = 0;
+		  }
+		| simple_list
+		  { $$ = $1; }
+		| simple_list '\n'
+		  { $$ = $1; }
+		| simple_list END_OF_INPUT
+		  { $$ = $1; }
+		;
+
+simple_list	: simple_list1 opt_sep_no_nl
+		  { $$ = set_stmt_print_flag ($1, $2, false); }
+		;
+
+simple_list1	: statement
+		  { $$ = make_statement_list ($1); }
+		| simple_list1 sep_no_nl statement
+		  { $$ = append_statement_list ($1, $2, $3, false); }
+		;
+
+opt_list	: // empty
+		  { $$ = new tree_statement_list (); }
+		| list
+		  { $$ = $1; }
+		;
+
+list		: list1 opt_sep
+		  { $$ = set_stmt_print_flag ($1, $2, true); }
+		;
+
+list1		: statement
+		  { $$ = make_statement_list ($1); }
+		| list1 sep statement
+		  { $$ = append_statement_list ($1, $2, $3, true); }
+		;
+
+statement	: expression
+		  { $$ = make_statement ($1); }
+		| command
+		  { $$ = make_statement ($1); }
+		| word_list_cmd
+		  { $$ = make_statement ($1); }
+		;
+
+// =================
+// Word-list command
+// =================
+
+// These are not really like expressions since they can't appear on
+// the RHS of an assignment.  But they are also not like commands (IF,
+// WHILE, etc.
+
+word_list_cmd	: identifier word_list
+		  { $$ = make_index_expression ($1, $2, '('); }
+		;
+
+word_list	: string
+		  { $$ = new tree_argument_list ($1); }
+		| word_list string
+		  {
+		    $1->append ($2);
+		    $$ = $1;
+		  }
+		;
+
+// ===========
+// Expressions
+// ===========
+
+identifier	: NAME
+		  {
+		    symbol_table::symbol_record *sr = $1->sym_rec ();
+		    $$ = new tree_identifier (*sr, $1->line (), $1->column ());
+		  }
+		;
+
+string		: DQ_STRING
+		  { $$ = make_constant (DQ_STRING, $1); }
+		| SQ_STRING
+		  { $$ = make_constant (SQ_STRING, $1); }
+		;
+
+constant	: NUM
+		  { $$ = make_constant (NUM, $1); }
+		| IMAG_NUM
+		  { $$ = make_constant (IMAG_NUM, $1); }
+		| string
+		  { $$ = $1; }
+		;
+
+matrix		: '[' ']'
+		  {
+		    $$ = new tree_constant (octave_null_matrix::instance);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+		| '[' ';' ']'
+		  {
+		    $$ = new tree_constant (octave_null_matrix::instance);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+		| '[' ',' ']'
+		  {
+		    $$ = new tree_constant (octave_null_matrix::instance);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+		| '[' matrix_rows ']'
+		  {
+		    $$ = finish_matrix ($2);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+		;
+
+matrix_rows	: matrix_rows1
+		  { $$ = $1; }
+		| matrix_rows1 ';'	// Ignore trailing semicolon.
+		  { $$ = $1; }
+		;
+
+matrix_rows1	: cell_or_matrix_row
+		  { $$ = new tree_matrix ($1); }
+		| matrix_rows1 ';' cell_or_matrix_row
+		  {
+		    $1->append ($3);
+		    $$ = $1;
+		  }
+		;
+
+cell		: '{' '}'
+		  { $$ = new tree_constant (octave_value (Cell ())); }
+		| '{' ';' '}'
+		  { $$ = new tree_constant (octave_value (Cell ())); }
+		| '{' cell_rows '}'
+		  { $$ = finish_cell ($2); }
+		;
+
+cell_rows	: cell_rows1
+		  { $$ = $1; }
+		| cell_rows1 ';'	// Ignore trailing semicolon.
+		  { $$ = $1; }
+		;
+
+cell_rows1	: cell_or_matrix_row
+		  { $$ = new tree_cell ($1); }
+		| cell_rows1 ';' cell_or_matrix_row
+		  {
+		    $1->append ($3);
+		    $$ = $1;
+		  }
+		;
+
+cell_or_matrix_row
+		: arg_list
+		  { $$ = $1; }
+		| arg_list ','	// Ignore trailing comma.
+		  { $$ = $1; }
+		;
+
+fcn_handle	: '@' FCN_HANDLE
+		  {
+		    $$ = make_fcn_handle ($2);
+		    lexer_flags.looking_at_function_handle--;
+		  }
+		;
+
+anon_fcn_handle	: '@' param_list statement
+		  { $$ = make_anon_fcn_handle ($2, $3); }
+		;
+
+primary_expr	: identifier
+		  { $$ = $1; }
+		| constant
+		  { $$ = $1; }
+		| fcn_handle
+		  { $$ = $1; }
+		| matrix
+		  { $$ = $1; }
+		| cell
+		  { $$ = $1; }
+		| '(' expression ')'
+		  { $$ = $2->mark_in_parens (); }
+		;
+
+magic_colon	: ':'
+		  {
+		    octave_value tmp (octave_value::magic_colon_t);
+		    $$ = new tree_constant (tmp);
+		  }
+		;
+
+arg_list	: expression
+		  { $$ = new tree_argument_list ($1); }
+		| magic_colon
+		  { $$ = new tree_argument_list ($1); }
+		| arg_list ',' magic_colon
+		  {
+		    $1->append ($3);
+		    $$ = $1;
+		  }
+		| arg_list ',' expression
+		  {
+		    $1->append ($3);
+		    $$ = $1;
+		  }
+		;
+
+indirect_ref_op	: '.'
+		  { lexer_flags.looking_at_indirect_ref = true; }
+		;
+
+postfix_expr	: primary_expr
+		  { $$ = $1; }
+		| postfix_expr '(' ')'
+		  { $$ = make_index_expression ($1, 0, '('); }
+		| postfix_expr '(' arg_list ')'
+		  { $$ = make_index_expression ($1, $3, '('); }
+		| postfix_expr '{' '}'
+		  { $$ = make_index_expression ($1, 0, '{'); }
+		| postfix_expr '{' arg_list '}'
+		  { $$ = make_index_expression ($1, $3, '{'); }
+		| postfix_expr PLUS_PLUS
+		  { $$ = make_postfix_op (PLUS_PLUS, $1, $2); }
+		| postfix_expr MINUS_MINUS
+		  { $$ = make_postfix_op (MINUS_MINUS, $1, $2); }
+		| postfix_expr QUOTE
+		  { $$ = make_postfix_op (QUOTE, $1, $2); }
+		| postfix_expr TRANSPOSE
+		  { $$ = make_postfix_op (TRANSPOSE, $1, $2); }
+		| postfix_expr indirect_ref_op STRUCT_ELT
+		  { $$ = make_indirect_ref ($1, $3->text ()); }
+		| postfix_expr indirect_ref_op '(' expression ')'
+		  { $$ = make_indirect_ref ($1, $4); }
+		;
+
+prefix_expr	: postfix_expr
+		  { $$ = $1; }
+		| binary_expr
+		  { $$ = $1; }
+		| PLUS_PLUS prefix_expr %prec UNARY
+		  { $$ = make_prefix_op (PLUS_PLUS, $2, $1); }
+		| MINUS_MINUS prefix_expr %prec UNARY
+		  { $$ = make_prefix_op (MINUS_MINUS, $2, $1); }
+		| EXPR_NOT prefix_expr %prec UNARY
+		  { $$ = make_prefix_op (EXPR_NOT, $2, $1); }
+		| '+' prefix_expr %prec UNARY
+		  { $$ = make_prefix_op ('+', $2, $1); }
+		| '-' prefix_expr %prec UNARY
+		  { $$ = make_prefix_op ('-', $2, $1); }
+		;
+
+binary_expr	: prefix_expr POW prefix_expr
+		  { $$ = make_binary_op (POW, $1, $2, $3); }
+		| prefix_expr EPOW prefix_expr
+		  { $$ = make_binary_op (EPOW, $1, $2, $3); }
+		| prefix_expr '+' prefix_expr
+		  { $$ = make_binary_op ('+', $1, $2, $3); }
+		| prefix_expr '-' prefix_expr
+		  { $$ = make_binary_op ('-', $1, $2, $3); }
+		| prefix_expr '*' prefix_expr
+		  { $$ = make_binary_op ('*', $1, $2, $3); }
+		| prefix_expr '/' prefix_expr
+		  { $$ = make_binary_op ('/', $1, $2, $3); }
+		| prefix_expr EPLUS prefix_expr
+		  { $$ = make_binary_op ('+', $1, $2, $3); }
+		| prefix_expr EMINUS prefix_expr
+		  { $$ = make_binary_op ('-', $1, $2, $3); }
+		| prefix_expr EMUL prefix_expr
+		  { $$ = make_binary_op (EMUL, $1, $2, $3); }
+		| prefix_expr EDIV prefix_expr
+		  { $$ = make_binary_op (EDIV, $1, $2, $3); }
+		| prefix_expr LEFTDIV prefix_expr
+		  { $$ = make_binary_op (LEFTDIV, $1, $2, $3); }
+		| prefix_expr ELEFTDIV prefix_expr
+		  { $$ = make_binary_op (ELEFTDIV, $1, $2, $3); }
+		;
+
+colon_expr	: colon_expr1
+		  { $$ = finish_colon_expression ($1); }
+		;
+
+colon_expr1	: prefix_expr
+		  { $$ = new tree_colon_expression ($1); }
+		| colon_expr1 ':' prefix_expr
+		  {
+		    if (! ($$ = $1->append ($3)))
+		      ABORT_PARSE;
+		  }
+		;
+
+simple_expr	: colon_expr
+		  { $$ = $1; }
+		| simple_expr LSHIFT simple_expr
+		  { $$ = make_binary_op (LSHIFT, $1, $2, $3); }
+		| simple_expr RSHIFT simple_expr
+		  { $$ = make_binary_op (RSHIFT, $1, $2, $3); }
+		| simple_expr EXPR_LT simple_expr
+		  { $$ = make_binary_op (EXPR_LT, $1, $2, $3); }
+		| simple_expr EXPR_LE simple_expr
+		  { $$ = make_binary_op (EXPR_LE, $1, $2, $3); }
+		| simple_expr EXPR_EQ simple_expr
+		  { $$ = make_binary_op (EXPR_EQ, $1, $2, $3); }
+		| simple_expr EXPR_GE simple_expr
+		  { $$ = make_binary_op (EXPR_GE, $1, $2, $3); }
+		| simple_expr EXPR_GT simple_expr
+		  { $$ = make_binary_op (EXPR_GT, $1, $2, $3); }
+		| simple_expr EXPR_NE simple_expr
+		  { $$ = make_binary_op (EXPR_NE, $1, $2, $3); }
+		| simple_expr EXPR_AND simple_expr
+		  { $$ = make_binary_op (EXPR_AND, $1, $2, $3); }
+		| simple_expr EXPR_OR simple_expr
+		  { $$ = make_binary_op (EXPR_OR, $1, $2, $3); }
+		| simple_expr EXPR_AND_AND simple_expr
+		  { $$ = make_boolean_op (EXPR_AND_AND, $1, $2, $3); }
+		| simple_expr EXPR_OR_OR simple_expr
+		  { $$ = make_boolean_op (EXPR_OR_OR, $1, $2, $3); }
+		;
+
+// Arrange for the lexer to return CLOSE_BRACE for `]' by looking ahead
+// one token for an assignment op.
+
+assign_lhs	: simple_expr
+		  {
+		    $$ = new tree_argument_list ($1);
+		    $$->mark_as_simple_assign_lhs ();
+		  }
+		| '[' arg_list CLOSE_BRACE
+		  {
+		    $$ = $2;
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		    for (std::set<std::string>::const_iterator p = lexer_flags.pending_local_variables.begin ();
+			 p != lexer_flags.pending_local_variables.end ();
+			 p++)
+		      {
+			symbol_table::force_variable (*p);
+		      }
+		    lexer_flags.pending_local_variables.clear ();
+		  }
+		;
+
+assign_expr	: assign_lhs '=' expression
+		  { $$ = make_assign_op ('=', $1, $2, $3); }
+		| assign_lhs ADD_EQ expression
+		  { $$ = make_assign_op (ADD_EQ, $1, $2, $3); }
+		| assign_lhs SUB_EQ expression
+		  { $$ = make_assign_op (SUB_EQ, $1, $2, $3); }
+		| assign_lhs MUL_EQ expression
+		  { $$ = make_assign_op (MUL_EQ, $1, $2, $3); }
+		| assign_lhs DIV_EQ expression
+		  { $$ = make_assign_op (DIV_EQ, $1, $2, $3); }
+		| assign_lhs LEFTDIV_EQ expression
+		  { $$ = make_assign_op (LEFTDIV_EQ, $1, $2, $3); }
+		| assign_lhs POW_EQ expression
+		  { $$ = make_assign_op (POW_EQ, $1, $2, $3); }
+		| assign_lhs LSHIFT_EQ expression
+		  { $$ = make_assign_op (LSHIFT_EQ, $1, $2, $3); }
+		| assign_lhs RSHIFT_EQ expression
+		  { $$ = make_assign_op (RSHIFT_EQ, $1, $2, $3); }
+		| assign_lhs EMUL_EQ expression
+		  { $$ = make_assign_op (EMUL_EQ, $1, $2, $3); }
+		| assign_lhs EDIV_EQ expression
+		  { $$ = make_assign_op (EDIV_EQ, $1, $2, $3); }
+		| assign_lhs ELEFTDIV_EQ expression
+		  { $$ = make_assign_op (ELEFTDIV_EQ, $1, $2, $3); }
+		| assign_lhs EPOW_EQ expression
+		  { $$ = make_assign_op (EPOW_EQ, $1, $2, $3); }
+		| assign_lhs AND_EQ expression
+		  { $$ = make_assign_op (AND_EQ, $1, $2, $3); }
+		| assign_lhs OR_EQ expression
+		  { $$ = make_assign_op (OR_EQ, $1, $2, $3); }
+		;
+
+expression	: simple_expr
+		  { $$ = $1; }
+		| assign_expr
+		  { $$ = $1; }
+		| anon_fcn_handle
+		  { $$ = $1; }
+		;
+
+// ================================================
+// Commands, declarations, and function definitions
+// ================================================
+
+command		: declaration
+		  { $$ = $1; }
+		| select_command
+		  { $$ = $1; }
+		| loop_command
+		  { $$ = $1; }
+		| jump_command
+		  { $$ = $1; }
+		| except_command
+		  { $$ = $1; }
+		| function
+		  { $$ = $1; }
+		| script
+		  { $$ = $1; }
+		;
+
+// =====================
+// Declaration statemnts
+// =====================
+
+parsing_decl_list
+		: // empty
+		  { lexer_flags.looking_at_decl_list = true; }
+
+declaration	: GLOBAL parsing_decl_list decl1
+		  {
+		    $$ = make_decl_command (GLOBAL, $1, $3);
+		    lexer_flags.looking_at_decl_list = false;
+		  }
+		| STATIC parsing_decl_list decl1
+		  {
+		    $$ = make_decl_command (STATIC, $1, $3);
+		    lexer_flags.looking_at_decl_list = false;
+		  }
+		;
+
+decl1		: decl2
+		  { $$ = new tree_decl_init_list ($1); }
+		| decl1 decl2
+		  {
+		    $1->append ($2);
+		    $$ = $1;
+		  }
+		;
+
+decl_param_init : // empty
+		{ lexer_flags.looking_at_initializer_expression = true; }
+
+decl2		: identifier
+		  { $$ = new tree_decl_elt ($1); }
+		| identifier '=' decl_param_init expression
+		  {
+		    lexer_flags.looking_at_initializer_expression = false;
+		    $$ = new tree_decl_elt ($1, $4);
+		  }
+		;
+
+// ====================
+// Selection statements
+// ====================
+
+select_command	: if_command
+		  { $$ = $1; }
+		| switch_command
+		  { $$ = $1; }
+		;
+
+// ============
+// If statement
+// ============
+
+if_command	: IF stash_comment if_cmd_list END
+		  {
+		    if (! ($$ = finish_if_command ($1, $3, $4, $2)))
+		      ABORT_PARSE;
+		  }
+		;
+
+if_cmd_list	: if_cmd_list1
+		  { $$ = $1; }
+		| if_cmd_list1 else_clause
+		  {
+		    $1->append ($2);
+		    $$ = $1;
+		  }
+		;
+
+if_cmd_list1	: expression opt_sep opt_list
+		  { $$ = start_if_command ($1, $3); }
+		| if_cmd_list1 elseif_clause
+		  {
+		    $1->append ($2);
+		    $$ = $1;
+		  }
+		;
+
+elseif_clause	: ELSEIF stash_comment opt_sep expression opt_sep opt_list
+		  { $$ = make_elseif_clause ($1, $4, $6, $2); }
+		;
+
+else_clause	: ELSE stash_comment opt_sep opt_list
+		  { $$ = new tree_if_clause ($4, $2); }
+		;
+
+// ================
+// Switch statement
+// ================
+
+switch_command	: SWITCH stash_comment expression opt_sep case_list END
+		  {
+		    if (! ($$ = finish_switch_command ($1, $3, $5, $6, $2)))
+		      ABORT_PARSE;
+		  }
+		;
+
+case_list	: // empty
+		  { $$ = new tree_switch_case_list (); }
+		| case_list1
+		  { $$ = $1; }
+		| case_list1 default_case
+		  {
+		    $1->append ($2);
+		    $$ = $1;
+		  }		
+		;
+
+case_list1	: switch_case
+		  { $$ = new tree_switch_case_list ($1); }
+		| case_list1 switch_case
+		  {
+		    $1->append ($2);
+		    $$ = $1;
+		  }
+		;
+
+switch_case	: CASE stash_comment opt_sep expression opt_sep opt_list
+		  { $$ = make_switch_case ($1, $4, $6, $2); }
+		;
+
+default_case	: OTHERWISE stash_comment opt_sep opt_list
+		  {
+		    $$ = new tree_switch_case ($4, $2);
+		  }
+		;
+
+// =======
+// Looping
+// =======
+
+loop_command	: WHILE stash_comment expression opt_sep opt_list END
+		  {
+		    if (! ($$ = make_while_command ($1, $3, $5, $6, $2)))
+		      ABORT_PARSE;
+		  }
+		| DO stash_comment opt_sep opt_list UNTIL expression
+		  {
+		    if (! ($$ = make_do_until_command ($5, $4, $6, $2)))
+		      ABORT_PARSE;
+		  }
+		| FOR stash_comment assign_lhs '=' expression opt_sep opt_list END
+		  {
+		    if (! ($$ = make_for_command ($1, $3, $5, $7, $8, $2)))
+		      ABORT_PARSE;
+		  }
+		| FOR stash_comment '(' assign_lhs '=' expression ')' opt_sep opt_list END
+		  {
+		    if (! ($$ = make_for_command ($1, $4, $6, $9, $10, $2)))
+		      ABORT_PARSE;
+		  }
+		;
+
+// =======
+// Jumping
+// =======
+
+jump_command	: BREAK
+		  {
+		    if (! ($$ = make_break_command ($1)))
+		      ABORT_PARSE;
+		  }
+		| CONTINUE
+		  {
+		    if (! ($$ = make_continue_command ($1)))
+		      ABORT_PARSE;
+		  }
+		| FUNC_RET
+		  {
+		    if (! ($$ = make_return_command ($1)))
+		      ABORT_PARSE;
+		  }
+		;
+
+// ==========
+// Exceptions
+// ==========
+
+except_command	: UNWIND stash_comment opt_sep opt_list CLEANUP
+		  stash_comment opt_sep opt_list END
+		  {
+		    if (! ($$ = make_unwind_command ($1, $4, $8, $9, $2, $6)))
+		      ABORT_PARSE;
+		  }
+		| TRY stash_comment opt_sep opt_list CATCH
+		  stash_comment opt_sep opt_list END
+		  {
+		    if (! ($$ = make_try_command ($1, $4, $8, $9, $2, $6)))
+		      ABORT_PARSE;
+		  }
+		| TRY stash_comment opt_sep opt_list END
+		  {
+		    if (! ($$ = make_try_command ($1, $4, 0, $5, $2, 0)))
+		      ABORT_PARSE;
+		  }
+		;
+
+// ===========================================
+// Some `subroutines' for function definitions
+// ===========================================
+
+push_fcn_symtab	: // empty
+		  {
+		    symtab_context.push (symbol_table::current_scope ());
+		    symbol_table::set_scope (symbol_table::alloc_scope ());
+
+		    if (! lexer_flags.parsing_nested_function)
+		      symbol_table::set_parent_scope (symbol_table::current_scope ());
+		  }
+		;
+
+// ===========================
+// List of function parameters
+// ===========================
+
+param_list_beg	: '('
+		  {
+		    lexer_flags.looking_at_parameter_list = true;
+
+		    if (lexer_flags.looking_at_function_handle)
+		      {
+		        symtab_context.push (symbol_table::current_scope ());
+			symbol_table::set_scope (symbol_table::alloc_scope ());
+			lexer_flags.looking_at_function_handle--;
+		      }
+		  }
+		;
+
+param_list_end	: ')'
+		  {
+		    lexer_flags.looking_at_parameter_list = false;
+		    lexer_flags.looking_for_object_index = false;
+		  }
+		;
+
+param_list	: param_list_beg param_list1 param_list_end
+		  {
+		    lexer_flags.quote_is_transpose = false;
+		    $$ = $2;
+		  }
+		| param_list_beg error
+		  {
+		    yyerror ("invalid parameter list");
+		    $$ = 0;
+		    ABORT_PARSE;
+		  }
+		;
+
+param_list1	: // empty
+		  { $$ = 0; }
+		| param_list2
+		  {
+		    $1->mark_as_formal_parameters ();
+		    if ($1->validate (tree_parameter_list::in))
+		      $$ = $1;
+		    else
+		      ABORT_PARSE;
+		  }
+		;
+
+param_list2	: decl2
+		  { $$ = new tree_parameter_list ($1); }
+		| param_list2 ',' decl2
+		  {
+		    $1->append ($3);
+		    $$ = $1;
+		  }
+		;
+
+// ===================================
+// List of function return value names
+// ===================================
+
+return_list	: '[' ']'
+		  {
+		    lexer_flags.looking_at_return_list = false;
+		    $$ = new tree_parameter_list ();
+		  }
+		| return_list1
+		  {
+		    lexer_flags.looking_at_return_list = false;
+		    if ($1->validate (tree_parameter_list::out))
+		      $$ = $1;
+		    else
+		      ABORT_PARSE;
+		  }
+		| '[' return_list1 ']'
+		  {
+		    lexer_flags.looking_at_return_list = false;
+		    if ($2->validate (tree_parameter_list::out))
+		      $$ = $2;
+		    else
+		      ABORT_PARSE;
+		  }
+		;
+
+return_list1	: identifier
+		  { $$ = new tree_parameter_list (new tree_decl_elt ($1)); }
+		| return_list1 ',' identifier
+		  {
+		    $1->append (new tree_decl_elt ($3));
+		    $$ = $1;
+		  }
+		;
+
+// ===========
+// Script file
+// ===========
+
+script		: SCRIPT opt_list END_OF_INPUT
+		  {
+		    tree_statement *end_of_script
+		      = make_end ("endscript", input_line_number,
+				  current_input_column);
+
+		    make_script ($2, end_of_script);
+
+		    $$ = 0;
+		  }
+		;
+
+// ===================
+// Function definition
+// ===================
+
+function_beg	: push_fcn_symtab FCN stash_comment
+		  { $$ = $3; }
+		;
+
+function	: function_beg function1
+		  {
+		    $$ = finish_function (0, $2, $1);
+		    recover_from_parsing_function ();
+		  }
+		| function_beg return_list '=' function1
+		  {
+		    $$ = finish_function ($2, $4, $1);
+		    recover_from_parsing_function ();
+		  }
+		;
+
+fcn_name	: identifier
+		  {
+		    std::string id_name = $1->name ();
+
+		    if (reading_fcn_file
+		        && ! lexer_flags.parsing_nested_function)
+		      parent_function_name = (curr_fcn_file_name == id_name)
+			? id_name : curr_fcn_file_name;
+
+		    lexer_flags.parsed_function_name = true;
+
+		    $$ = $1;
+		  }
+		;
+
+function1	: fcn_name function2
+		  {
+		    std::string fname = $1->name ();
+
+		    delete $1;
+
+		    if (! ($$ = frob_function (fname, $2)))
+		      ABORT_PARSE;
+		  }
+		;
+
+function2	: param_list opt_sep opt_list function_end
+		  { $$ = start_function ($1, $3, $4); }
+		| opt_sep opt_list function_end
+		  { $$ = start_function (0, $2, $3); }
+		;
+
+function_end	: END
+		  {
+		    if (end_token_ok ($1, token::function_end))
+		      $$ = make_end ("endfunction", $1->line (), $1->column ());
+		    else
+		      ABORT_PARSE;
+		  }
+		| END_OF_INPUT
+		  {
+		    if (lexer_flags.parsing_nested_function)
+		      lexer_flags.parsing_nested_function = -1;
+
+		    if (reading_fcn_file || reading_script_file
+			|| get_input_from_eval_string)
+		      $$ = make_end ("endfunction", input_line_number,
+				     current_input_column);
+		    else
+		      YYABORT;
+		  }
+		;
+
+// =============
+// Miscellaneous
+// =============
+
+stash_comment	: // empty
+		  { $$ = octave_comment_buffer::get_comment (); }
+		;
+
+parse_error	: LEXICAL_ERROR
+		  { yyerror ("parse error"); }
+		| error
+		;
+
+sep_no_nl	: ','
+		  { $$ = ','; }
+		| ';'
+		  { $$ = ';'; }
+		| sep_no_nl ','
+		  { $$ = $1; }
+		| sep_no_nl ';'
+		  { $$ = $1; }
+		;
+
+opt_sep_no_nl	: // empty
+		  { $$ = 0; }
+		| sep_no_nl
+		  { $$ = $1; }
+		;
+
+sep		: ','
+		  { $$ = ','; }
+		| ';'
+		  { $$ = ';'; }
+		| '\n'
+		  { $$ = '\n'; }
+		| sep ','
+		  { $$ = $1; }
+		| sep ';'
+		  { $$ = $1; }
+		| sep '\n'
+		  { $$ = $1; }
+		;
+
+opt_sep		: // empty
+		  { $$ = 0; }
+		| sep
+		  { $$ = $1; }
+		;
+
+%%
+
+// Generic error messages.
+
+static void
+yyerror (const char *s)
+{
+  int err_col = current_input_column - 1;
+
+  std::ostringstream output_buf;
+
+  if (reading_fcn_file || reading_script_file)
+    output_buf << "parse error near line " << input_line_number
+	       << " of file " << curr_fcn_file_full_name;
+  else
+    output_buf << "parse error:";
+
+  if (s && strcmp (s, "parse error") != 0)
+    output_buf << "\n\n  " << s;
+
+  output_buf << "\n\n";
+
+  if (! current_input_line.empty ())
+    {
+      size_t len = current_input_line.length ();
+
+      if (current_input_line[len-1] == '\n')
+        current_input_line.resize (len-1);
+
+      // Print the line, maybe with a pointer near the error token.
+
+      output_buf << ">>> " << current_input_line << "\n";
+
+      if (err_col == 0)
+	err_col = len;
+
+      for (int i = 0; i < err_col + 3; i++)
+	output_buf << " ";
+
+      output_buf << "^";
+    }
+
+  output_buf << "\n";
+
+  std::string msg = output_buf.str ();
+
+  parse_error ("%s", msg.c_str ());
+}
+
+// Error mesages for mismatched end tokens.
+
+static void
+end_error (const char *type, token::end_tok_type ettype, int l, int c)
+{
+  static const char *fmt
+    = "`%s' command matched by `%s' near line %d column %d";
+
+  switch (ettype)
+    {
+    case token::simple_end:
+      error (fmt, type, "end", l, c);
+      break;
+
+    case token::for_end:
+      error (fmt, type, "endfor", l, c);
+      break;
+
+    case token::function_end:
+      error (fmt, type, "endfunction", l, c);
+      break;
+
+    case token::if_end:
+      error (fmt, type, "endif", l, c);
+      break;
+
+    case token::switch_end:
+      error (fmt, type, "endswitch", l, c); 
+      break;
+
+    case token::while_end:
+      error (fmt, type, "endwhile", l, c); 
+      break;
+
+    case token::try_catch_end:
+      error (fmt, type, "end_try_catch", l, c); 
+      break;
+
+    case token::unwind_protect_end:
+      error (fmt, type, "end_unwind_protect", l, c); 
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+}
+
+// Check to see that end tokens are properly matched.
+
+static bool
+end_token_ok (token *tok, token::end_tok_type expected)
+{
+  bool retval = true;
+
+  token::end_tok_type ettype = tok->ettype ();
+
+  if (ettype != expected && ettype != token::simple_end)
+    {
+      retval = false;
+
+      yyerror ("parse error");
+
+      int l = tok->line ();
+      int c = tok->column ();
+
+      switch (expected)
+	{
+	case token::for_end:
+	  end_error ("for", ettype, l, c);
+	  break;
+
+	case token::function_end:
+	  end_error ("function", ettype, l, c);
+	  break;
+
+	case token::if_end:
+	  end_error ("if", ettype, l, c);
+	  break;
+
+	case token::try_catch_end:
+	  end_error ("try", ettype, l, c);
+	  break;
+
+	case token::switch_end:
+	  end_error ("switch", ettype, l, c);
+	  break;
+
+	case token::unwind_protect_end:
+	  end_error ("unwind_protect", ettype, l, c);
+	  break;
+
+	case token::while_end:
+	  end_error ("while", ettype, l, c);
+	  break;
+
+	default:
+	  panic_impossible ();
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+// Maybe print a warning if an assignment expression is used as the
+// test in a logical expression.
+
+static void
+maybe_warn_assign_as_truth_value (tree_expression *expr)
+{
+  if (expr->is_assignment_expression ()
+      && expr->paren_count () < 2)
+    {
+      if (curr_fcn_file_full_name.empty ())
+	warning_with_id
+	  ("Octave:assign-as-truth-value",
+	   "suggest parenthesis around assignment used as truth value");
+      else
+	warning_with_id
+	  ("Octave:assign-as-truth-value",
+	   "suggest parenthesis around assignment used as truth value near line %d, column %d in file `%s'",
+	   expr->line (), expr->column (), curr_fcn_file_full_name.c_str ());
+    }
+}
+
+// Maybe print a warning about switch labels that aren't constants.
+
+static void
+maybe_warn_variable_switch_label (tree_expression *expr)
+{
+  if (! expr->is_constant ())
+    {
+      if (curr_fcn_file_full_name.empty ())
+	warning_with_id ("Octave:variable-switch-label",
+			 "variable switch label");
+      else
+	warning_with_id
+	  ("Octave:variable-switch-label",
+	   "variable switch label near line %d, column %d in file `%s'",
+	   expr->line (), expr->column (), curr_fcn_file_full_name.c_str ());
+    }
+}
+
+static tree_expression *
+fold (tree_binary_expression *e)
+{
+  tree_expression *retval = e;
+
+  unwind_protect::begin_frame ("fold_binary_expression");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  tree_expression *op1 = e->lhs ();
+  tree_expression *op2 = e->rhs ();
+
+  octave_value::binary_op op_type = e->op_type ();
+
+  if (op1->is_constant () && op2->is_constant ()
+      && (! ((warning_enabled ("Octave:associativity-change")
+	      && (op_type == POW || op_type == EPOW))
+	     || (warning_enabled ("Octave:precedence-change")
+		 && (op_type == EXPR_OR || op_type == EXPR_OR_OR)))))
+    {
+      octave_value tmp = e->rvalue1 ();
+
+      if (! (error_state || warning_state))
+	{
+	  tree_constant *tc_retval
+	    = new tree_constant (tmp, op1->line (), op1->column ());
+
+	  std::ostringstream buf;
+
+	  tree_print_code tpc (buf);
+
+	  e->accept (tpc);
+
+	  tc_retval->stash_original_text (buf.str ());
+
+	  delete e;
+
+	  retval = tc_retval;
+	}
+    }
+
+  unwind_protect::run_frame ("fold_binary_expression");
+
+  return retval;
+}
+
+static tree_expression *
+fold (tree_unary_expression *e)
+{
+  tree_expression *retval = e;
+
+  unwind_protect::begin_frame ("fold_unary_expression");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  tree_expression *op = e->operand ();
+
+  if (op->is_constant ())
+    {
+      octave_value tmp = e->rvalue1 ();
+
+      if (! (error_state || warning_state))
+	{
+	  tree_constant *tc_retval
+	    = new tree_constant (tmp, op->line (), op->column ());
+
+	  std::ostringstream buf;
+
+	  tree_print_code tpc (buf);
+
+	  e->accept (tpc);
+
+	  tc_retval->stash_original_text (buf.str ());
+
+	  delete e;
+
+	  retval = tc_retval;
+	}
+    }
+
+  unwind_protect::run_frame ("fold_unary_expression");
+
+  return retval;
+}
+
+// Finish building a range.
+
+static tree_expression *
+finish_colon_expression (tree_colon_expression *e)
+{
+  tree_expression *retval = e;
+
+  unwind_protect::begin_frame ("finish_colon_expression");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  tree_expression *base = e->base ();
+  tree_expression *limit = e->limit ();
+  tree_expression *incr = e->increment ();
+
+  if (base)
+    {
+      if (limit)
+	{
+	  if (base->is_constant () && limit->is_constant ()
+	      && (! incr || (incr && incr->is_constant ())))
+	    {
+	      octave_value tmp = e->rvalue1 ();
+
+	      if (! (error_state || warning_state))
+		{
+		  tree_constant *tc_retval
+		    = new tree_constant (tmp, base->line (), base->column ());
+
+		  std::ostringstream buf;
+
+		  tree_print_code tpc (buf);
+
+		  e->accept (tpc);
+
+		  tc_retval->stash_original_text (buf.str ());
+
+		  delete e;
+
+		  retval = tc_retval;
+		}
+	    }
+	}
+      else
+	{
+	  e->preserve_base ();
+	  delete e;
+
+	  // FIXME -- need to attempt constant folding here
+	  // too (we need a generic way to do that).
+	  retval = base;
+	}
+    }
+
+  unwind_protect::run_frame ("finish_colon_expression");
+
+  return retval;
+}
+
+// Make a constant.
+
+static tree_constant *
+make_constant (int op, token *tok_val)
+{
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_constant *retval = 0;
+
+  switch (op)
+    {
+    case NUM:
+      {
+	octave_value tmp (tok_val->number ());
+	retval = new tree_constant (tmp, l, c);
+	retval->stash_original_text (tok_val->text_rep ());
+      }
+      break;
+
+    case IMAG_NUM:
+      {
+	octave_value tmp (Complex (0.0, tok_val->number ()));
+	retval = new tree_constant (tmp, l, c);
+	retval->stash_original_text (tok_val->text_rep ());
+      }
+      break;
+
+    case DQ_STRING:
+    case SQ_STRING:
+      {
+	std::string txt = tok_val->text ();
+
+        char delim = op == DQ_STRING ? '"' : '\'';
+        octave_value tmp (txt, delim);
+
+        if (txt.empty ())
+          {
+            if (op == DQ_STRING)
+              tmp = octave_null_str::instance;
+            else
+              tmp = octave_null_sq_str::instance;
+          }
+
+	retval = new tree_constant (tmp, l, c);
+
+	if (op == DQ_STRING)
+	  txt = undo_string_escapes (txt);
+
+	// FIXME -- maybe this should also be handled by
+	// tok_val->text_rep () for character strings?
+	retval->stash_original_text (delim + txt + delim);
+      }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return retval;
+}
+
+// Make a function handle.
+
+static tree_fcn_handle *
+make_fcn_handle (token *tok_val)
+{
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_fcn_handle *retval = new tree_fcn_handle (tok_val->text (), l, c);
+
+  return retval;
+}
+
+// Make an anonymous function handle.
+
+static tree_anon_fcn_handle *
+make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt)
+{
+  // FIXME -- need to get these from the location of the @ symbol.
+
+  int l = -1;
+  int c = -1;
+
+  tree_parameter_list *ret_list = 0;
+
+  symbol_table::scope_id fcn_scope = symbol_table::current_scope ();
+
+  if (symtab_context.empty ())
+    panic_impossible ();
+
+  symbol_table::set_scope (symtab_context.top ());
+
+  symtab_context.pop ();
+
+  stmt->set_print_flag (false);
+
+  tree_statement_list *body = new tree_statement_list (stmt);
+
+  body->mark_as_anon_function_body ();
+
+  tree_anon_fcn_handle *retval
+    = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c);
+
+  return retval;
+}
+
+static void
+maybe_warn_associativity_change (tree_expression *op)
+{
+  if (op->paren_count () == 0 && op->is_binary_expression ())
+    {
+      tree_binary_expression *e
+	= dynamic_cast<tree_binary_expression *> (op);
+
+      octave_value::binary_op op_type = e->op_type ();
+
+      if (op_type == octave_value::op_pow
+	  || op_type == octave_value::op_el_pow)
+	{
+	  std::string op_str = octave_value::binary_op_as_string (op_type);
+
+	  if (curr_fcn_file_full_name.empty ())
+	    warning_with_id
+	      ("Octave:associativity-change",
+	       "meaning may have changed due to change in associativity for %s operator",
+	       op_str.c_str ());
+	  else
+	    warning_with_id
+	      ("Octave:associativity-change",
+	       "meaning may have changed due to change in associativity for %s operator near line %d, column %d in file `%s'",
+	       op_str.c_str (), op->line (), op->column (),
+	       curr_fcn_file_full_name.c_str ());
+	}
+    }
+}
+
+// Build a binary expression.
+
+static tree_expression *
+make_binary_op (int op, tree_expression *op1, token *tok_val,
+		tree_expression *op2)
+{
+  octave_value::binary_op t = octave_value::unknown_binary_op;
+
+  switch (op)
+    {
+    case POW:
+      t = octave_value::op_pow;
+      maybe_warn_associativity_change (op1);
+      break;
+
+    case EPOW:
+      t = octave_value::op_el_pow;
+      maybe_warn_associativity_change (op1);
+      break;
+
+    case '+':
+      t = octave_value::op_add;
+      break;
+
+    case '-':
+      t = octave_value::op_sub;
+      break;
+
+    case '*':
+      t = octave_value::op_mul;
+      break;
+
+    case '/':
+      t = octave_value::op_div;
+      break;
+
+    case EMUL:
+      t = octave_value::op_el_mul;
+      break;
+
+    case EDIV:
+      t = octave_value::op_el_div;
+      break;
+
+    case LEFTDIV:
+      t = octave_value::op_ldiv;
+      break;
+
+    case ELEFTDIV:
+      t = octave_value::op_el_ldiv;
+      break;
+
+    case LSHIFT:
+      t = octave_value::op_lshift;
+      break;
+
+    case RSHIFT:
+      t = octave_value::op_rshift;
+      break;
+
+    case EXPR_LT:
+      t = octave_value::op_lt;
+      break;
+
+    case EXPR_LE:
+      t = octave_value::op_le;
+      break;
+
+    case EXPR_EQ:
+      t = octave_value::op_eq;
+      break;
+
+    case EXPR_GE:
+      t = octave_value::op_ge;
+      break;
+
+    case EXPR_GT:
+      t = octave_value::op_gt;
+      break;
+
+    case EXPR_NE:
+      t = octave_value::op_ne;
+      break;
+
+    case EXPR_AND:
+      t = octave_value::op_el_and;
+      break;
+
+    case EXPR_OR:
+      t = octave_value::op_el_or;
+      if (op2->paren_count () == 0 && op2->is_binary_expression ())
+        {
+	  tree_binary_expression *e
+	    = dynamic_cast<tree_binary_expression *> (op2);
+
+	  if (e->op_type () == octave_value::op_el_and)
+	    {
+	      if (curr_fcn_file_full_name.empty ())
+		warning_with_id
+		  ("Octave:precedence-change",
+		   "meaning may have changed due to change in precedence for & and | operators");
+	      else
+		warning_with_id
+		  ("Octave:precedence-change",
+		   "meaning may have changed due to change in precedence for & and | operators near line %d, column %d in file `%s'",
+		   op2->line (), op2->column (),
+		   curr_fcn_file_full_name.c_str ());
+	    }
+        }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_binary_expression *e
+    = maybe_compound_binary_expression (op1, op2, l, c, t);
+
+  return fold (e);
+}
+
+// Build a boolean expression.
+
+static tree_expression *
+make_boolean_op (int op, tree_expression *op1, token *tok_val,
+		 tree_expression *op2)
+{
+  tree_boolean_expression::type t;
+
+  switch (op)
+    {
+    case EXPR_AND_AND:
+      t = tree_boolean_expression::bool_and;
+      break;
+
+    case EXPR_OR_OR:
+      t = tree_boolean_expression::bool_or;
+      if (op2->paren_count () == 0 && op2->is_boolean_expression ())
+        {
+	  tree_boolean_expression *e
+	    = dynamic_cast<tree_boolean_expression *> (op2);
+
+	  if (e->op_type () == tree_boolean_expression::bool_and)
+	    warning_with_id
+	      ("Octave:precedence-change",
+	       "meaning may have changed due to change in precedence for && and || operators");
+        }
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_boolean_expression *e
+    = new tree_boolean_expression (op1, op2, l, c, t);
+
+  return fold (e);
+}
+
+// Build a prefix expression.
+
+static tree_expression *
+make_prefix_op (int op, tree_expression *op1, token *tok_val)
+{
+  octave_value::unary_op t = octave_value::unknown_unary_op;
+
+  switch (op)
+    {
+    case EXPR_NOT:
+      t = octave_value::op_not;
+      break;
+
+    case '+':
+      t = octave_value::op_uplus;
+      break;
+
+    case '-':
+      t = octave_value::op_uminus;
+      break;
+
+    case PLUS_PLUS:
+      t = octave_value::op_incr;
+      break;
+
+    case MINUS_MINUS:
+      t = octave_value::op_decr;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_prefix_expression *e
+    = new tree_prefix_expression (op1, l, c, t);
+
+  return fold (e);
+}
+
+// Build a postfix expression.
+
+static tree_expression *
+make_postfix_op (int op, tree_expression *op1, token *tok_val)
+{
+  octave_value::unary_op t = octave_value::unknown_unary_op;
+
+  switch (op)
+    {
+    case QUOTE:
+      t = octave_value::op_hermitian;
+      break;
+
+    case TRANSPOSE:
+      t = octave_value::op_transpose;
+      break;
+
+    case PLUS_PLUS:
+      t = octave_value::op_incr;
+      break;
+
+    case MINUS_MINUS:
+      t = octave_value::op_decr;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  tree_postfix_expression *e
+    = new tree_postfix_expression (op1, l, c, t);
+
+  return fold (e);
+}
+
+// Build an unwind-protect command.
+
+static tree_command *
+make_unwind_command (token *unwind_tok, tree_statement_list *body,
+		     tree_statement_list *cleanup, token *end_tok,
+		     octave_comment_list *lc, octave_comment_list *mc)
+{
+  tree_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::unwind_protect_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = unwind_tok->line ();
+      int c = unwind_tok->column ();
+
+      retval = new tree_unwind_protect_command (body, cleanup,
+						lc, mc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a try-catch command.
+
+static tree_command *
+make_try_command (token *try_tok, tree_statement_list *body,
+		  tree_statement_list *cleanup, token *end_tok,
+		  octave_comment_list *lc, octave_comment_list *mc)
+{
+  tree_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::try_catch_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = try_tok->line ();
+      int c = try_tok->column ();
+
+      retval = new tree_try_catch_command (body, cleanup,
+					   lc, mc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a while command.
+
+static tree_command *
+make_while_command (token *while_tok, tree_expression *expr,
+		    tree_statement_list *body, token *end_tok,
+		    octave_comment_list *lc)
+{
+  tree_command *retval = 0;
+
+  maybe_warn_assign_as_truth_value (expr);
+
+  if (end_token_ok (end_tok, token::while_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      lexer_flags.looping--;
+
+      int l = while_tok->line ();
+      int c = while_tok->column ();
+
+      retval = new tree_while_command (expr, body, lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a do-until command.
+
+static tree_command *
+make_do_until_command (token *until_tok, tree_statement_list *body,
+		       tree_expression *expr, octave_comment_list *lc)
+{
+  tree_command *retval = 0;
+
+  maybe_warn_assign_as_truth_value (expr);
+
+  octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+  lexer_flags.looping--;
+
+  int l = until_tok->line ();
+  int c = until_tok->column ();
+
+  retval = new tree_do_until_command (expr, body, lc, tc, l, c);
+
+  return retval;
+}
+
+// Build a for command.
+
+static tree_command *
+make_for_command (token *for_tok, tree_argument_list *lhs,
+		  tree_expression *expr, tree_statement_list *body,
+		  token *end_tok, octave_comment_list *lc)
+{
+  tree_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::for_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      lexer_flags.looping--;
+
+      int l = for_tok->line ();
+      int c = for_tok->column ();
+
+      if (lhs->length () == 1)
+	{
+	  tree_expression *tmp = lhs->remove_front ();
+
+	  retval = new tree_simple_for_command (tmp, expr, body,
+						lc, tc, l, c);
+
+	  delete lhs;
+	}
+      else
+	retval = new tree_complex_for_command (lhs, expr, body,
+					       lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a break command.
+
+static tree_command *
+make_break_command (token *break_tok)
+{
+  tree_command *retval = 0;
+
+  int l = break_tok->line ();
+  int c = break_tok->column ();
+
+  // We check to see if we are evaluating a function, script, or loop
+  // so that we don't turn eval ("break;") inside a function, script,
+  // or loop into a no-op command.
+
+  if (lexer_flags.looping || lexer_flags.defining_func
+      || reading_script_file || tree_evaluator::in_fcn_or_script_body
+      || tree_evaluator::in_loop_command)
+    retval = new tree_break_command (l, c);
+  else
+    retval = new tree_no_op_command ("break", l, c);
+
+  return retval;
+}
+
+// Build a continue command.
+
+static tree_command *
+make_continue_command (token *continue_tok)
+{
+  tree_command *retval = 0;
+
+  int l = continue_tok->line ();
+  int c = continue_tok->column ();
+
+  // We check to see if we are evaluating a loop so that we don't turn
+  // eval ("continue;") into a no-op command inside a loop.
+
+  if (lexer_flags.looping || tree_evaluator::in_loop_command)
+    retval = new tree_continue_command (l, c);
+  else
+    retval = new tree_no_op_command ("continue", l, c);
+
+  return retval;
+}
+
+// Build a return command.
+
+static tree_command *
+make_return_command (token *return_tok)
+{
+  tree_command *retval = 0;
+
+  int l = return_tok->line ();
+  int c = return_tok->column ();
+
+  if (Vdebugging)
+    {
+      Vdebugging = false;
+
+      retval = new tree_no_op_command ("return", l, c);
+    }
+  else
+    {
+      // We check to see if we are evaluating a function or script so
+      // that we don't turn eval ("return;") inside a function, script,
+      // or loop into a no-op command.
+
+      if (lexer_flags.defining_func || reading_script_file
+          || tree_evaluator::in_fcn_or_script_body)
+        retval = new tree_return_command (l, c);
+      else
+        retval = new tree_no_op_command ("return", l, c);
+    }
+
+  return retval;
+}
+
+// Start an if command.
+
+static tree_if_command_list *
+start_if_command (tree_expression *expr, tree_statement_list *list)
+{
+  maybe_warn_assign_as_truth_value (expr);
+
+  tree_if_clause *t = new tree_if_clause (expr, list);
+
+  return new tree_if_command_list (t);
+}
+
+// Finish an if command.
+
+static tree_if_command *
+finish_if_command (token *if_tok, tree_if_command_list *list,
+		   token *end_tok, octave_comment_list *lc)
+{
+  tree_if_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::if_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = if_tok->line ();
+      int c = if_tok->column ();
+
+      if (list && ! list->empty ())
+	{
+	  tree_if_clause *elt = list->front ();
+
+	  if (elt)
+	    {
+	      elt->line (l);
+	      elt->column (c);
+	    }
+	}
+
+      retval = new tree_if_command (list, lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build an elseif clause.
+
+static tree_if_clause *
+make_elseif_clause (token *elseif_tok, tree_expression *expr,
+		    tree_statement_list *list, octave_comment_list *lc)
+{
+  maybe_warn_assign_as_truth_value (expr);
+
+  int l = elseif_tok->line ();
+  int c = elseif_tok->column ();
+
+  return new tree_if_clause (expr, list, lc, l, c);
+}
+
+// Finish a switch command.
+
+static tree_switch_command *
+finish_switch_command (token *switch_tok, tree_expression *expr,
+		       tree_switch_case_list *list, token *end_tok,
+		       octave_comment_list *lc)
+{
+  tree_switch_command *retval = 0;
+
+  if (end_token_ok (end_tok, token::switch_end))
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      int l = switch_tok->line ();
+      int c = switch_tok->column ();
+
+      if (list && ! list->empty ())
+	{
+	  tree_switch_case *elt = list->front ();
+
+	  if (elt)
+	    {
+	      elt->line (l);
+	      elt->column (c);
+	    }
+	}
+
+      retval = new tree_switch_command (expr, list, lc, tc, l, c);
+    }
+
+  return retval;
+}
+
+// Build a switch case.
+
+static tree_switch_case *
+make_switch_case (token *case_tok, tree_expression *expr,
+		  tree_statement_list *list, octave_comment_list *lc)
+{
+  maybe_warn_variable_switch_label (expr);
+
+  int l = case_tok->line ();
+  int c = case_tok->column ();
+
+  return new tree_switch_case (expr, list, lc, l, c);
+}
+
+// Build an assignment to a variable.
+
+static tree_expression *
+make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
+		tree_expression *rhs)
+{
+  tree_expression *retval = 0;
+
+  octave_value::assign_op t = octave_value::unknown_assign_op;
+
+  switch (op)
+    {
+    case '=':
+      t = octave_value::op_asn_eq;
+      break;
+
+    case ADD_EQ:
+      t = octave_value::op_add_eq;
+      break;
+
+    case SUB_EQ:
+      t = octave_value::op_sub_eq;
+      break;
+
+    case MUL_EQ:
+      t = octave_value::op_mul_eq;
+      break;
+
+    case DIV_EQ:
+      t = octave_value::op_div_eq;
+      break;
+
+    case LEFTDIV_EQ:
+      t = octave_value::op_ldiv_eq;
+      break;
+
+    case POW_EQ:
+      t = octave_value::op_pow_eq;
+      break;
+
+    case LSHIFT_EQ:
+      t = octave_value::op_lshift_eq;
+      break;
+
+    case RSHIFT_EQ:
+      t = octave_value::op_rshift_eq;
+      break;
+
+    case EMUL_EQ:
+      t = octave_value::op_el_mul_eq;
+      break;
+
+    case EDIV_EQ:
+      t = octave_value::op_el_div_eq;
+      break;
+
+    case ELEFTDIV_EQ:
+      t = octave_value::op_el_ldiv_eq;
+      break;
+
+    case EPOW_EQ:
+      t = octave_value::op_el_pow_eq;
+      break;
+
+    case AND_EQ:
+      t = octave_value::op_el_and_eq;
+      break;
+
+    case OR_EQ:
+      t = octave_value::op_el_or_eq;
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = eq_tok->line ();
+  int c = eq_tok->column ();
+
+  if (lhs->is_simple_assign_lhs ())
+    {
+      tree_expression *tmp = lhs->remove_front ();
+
+      retval = new tree_simple_assignment (tmp, rhs, false, l, c, t);
+
+      delete lhs;
+    }
+  else
+    return new tree_multi_assignment (lhs, rhs, false, l, c, t);
+
+  return retval;
+}
+
+// Define a function.
+
+static void
+make_script (tree_statement_list *cmds, tree_statement *end_script)
+{
+  std::string doc_string;
+
+  if (! help_buf.empty ())
+    {
+      doc_string = help_buf.top ();
+      help_buf.pop ();
+    }
+
+  if (! cmds)
+    cmds = new tree_statement_list ();
+
+  cmds->append (end_script);
+
+  octave_user_script *script
+    = new octave_user_script (curr_fcn_file_full_name, curr_fcn_file_name,
+			      cmds, doc_string);
+
+  octave_time now;
+
+  script->stash_fcn_file_time (now);
+
+  curr_fcn_ptr = script;
+
+  // Unmark any symbols that may have been tagged as local variables
+  // while parsing (for example, by force_local_variable in lex.l).
+
+  symbol_table::unmark_forced_variables ();
+}
+
+// Begin defining a function.
+
+static octave_user_function *
+start_function (tree_parameter_list *param_list, tree_statement_list *body,
+		tree_statement *end_fcn_stmt)
+{
+  // We'll fill in the return list later.
+
+  if (! body)
+    body = new tree_statement_list ();
+
+  body->append (end_fcn_stmt);
+
+  octave_user_function *fcn
+    = new octave_user_function (symbol_table::current_scope (),
+				param_list, 0, body);
+
+  if (fcn)
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      fcn->stash_trailing_comment (tc);
+    }
+
+  return fcn;
+}
+
+static tree_statement *
+make_end (const std::string& type, int l, int c)
+{
+  return make_statement (new tree_no_op_command (type, l, c));
+}
+
+// Do most of the work for defining a function.
+
+static octave_user_function *
+frob_function (const std::string& fname, octave_user_function *fcn)
+{
+  std::string id_name = fname;
+
+  // If input is coming from a file, issue a warning if the name of
+  // the file does not match the name of the function stated in the
+  // file.  Matlab doesn't provide a diagnostic (it ignores the stated
+  // name).
+
+  if (reading_fcn_file || autoloading)
+    {
+      if (! (autoloading
+	     || lexer_flags.parsing_nested_function
+	     || lexer_flags.parsing_class_method))
+	{
+	  // FIXME -- should curr_fcn_file_name already be
+	  // preprocessed when we get here?  It seems to only be a
+	  // problem with relative file names.
+
+	  std::string nm = curr_fcn_file_name;
+
+	  size_t pos = nm.find_last_of (file_ops::dir_sep_chars ());
+
+	  if (pos != std::string::npos)
+	    nm = curr_fcn_file_name.substr (pos+1);
+
+	  if (nm != id_name)
+	    {
+	      warning_with_id
+		("Octave:function-name-clash",
+		 "function name `%s' does not agree with function file name `%s'",
+		 id_name.c_str (), curr_fcn_file_full_name.c_str ());
+
+	      id_name = nm;
+	    }
+	}
+
+      octave_time now;
+
+      fcn->stash_fcn_file_name (curr_fcn_file_full_name);
+      fcn->stash_fcn_file_time (now);
+      fcn->mark_as_system_fcn_file ();
+
+      if (fcn_file_from_relative_lookup)
+	fcn->mark_relative ();
+
+      if (lexer_flags.parsing_nested_function)
+        {
+          fcn->stash_parent_fcn_name (parent_function_name);
+          fcn->stash_parent_fcn_scope (symbol_table::parent_scope ());
+	}
+
+      if (lexer_flags.parsing_class_method)
+	{
+	  if (current_class_name == id_name)
+	    fcn->mark_as_class_constructor ();
+	  else
+	    fcn->mark_as_class_method ();
+
+	  fcn->stash_dispatch_class (current_class_name);
+	}
+
+      std::string nm = fcn->fcn_file_name ();
+
+      file_stat fs (nm);
+
+      if (fs && fs.is_newer (now))
+        warning_with_id ("Octave:future-time-stamp",
+			 "time stamp for `%s' is in the future", nm.c_str ());
+    }
+  else if (! (input_from_tmp_history_file || input_from_startup_file)
+	   && reading_script_file
+	   && curr_fcn_file_name == id_name)
+    {
+      warning ("function `%s' defined within script file `%s'",
+	       id_name.c_str (), curr_fcn_file_full_name.c_str ());
+    }
+
+  fcn->stash_function_name (id_name);
+
+  if (! help_buf.empty ())
+    {
+      fcn->document (help_buf.top ());
+
+      help_buf.pop ();
+    }
+
+  if (reading_fcn_file && ! lexer_flags.parsing_nested_function)
+    curr_fcn_ptr = fcn;
+  else
+    curr_fcn_ptr = 0;
+
+  return fcn;
+}
+
+static tree_function_def *
+finish_function (tree_parameter_list *ret_list,
+		 octave_user_function *fcn, octave_comment_list *lc)
+{
+  tree_function_def *retval = 0;
+
+  if (ret_list)
+    ret_list->mark_as_formal_parameters ();
+
+  if (fcn)
+    {
+      std::string nm = fcn->name ();
+      std::string file = fcn->fcn_file_name ();
+
+      std::string tmp = nm;
+      if (! file.empty ())
+	tmp += ": " + file;
+
+      symbol_table::cache_name (fcn->scope (), tmp);
+
+      if (lc)
+	fcn->stash_leading_comment (lc);
+
+      fcn->define_ret_list (ret_list);
+
+      if (lexer_flags.parsing_nested_function)
+	{
+	  fcn->mark_as_nested_function ();
+
+	  symbol_table::install_subfunction (nm, octave_value (fcn));
+
+	  if (lexer_flags.parsing_nested_function < 0)
+	    {
+	      lexer_flags.parsing_nested_function = 0;
+	      symbol_table::reset_parent_scope ();
+	    }
+	}
+      else if (! curr_fcn_ptr)
+	{
+	  // FIXME -- there should be a better way to indicate that we
+	  // should create a tree_function_def object other than
+	  // looking at curr_fcn_ptr...
+
+	  retval = new tree_function_def (fcn);
+	}
+
+      // Unmark any symbols that may have been tagged as local
+      // variables while parsing (for example, by force_local_variable
+      // in lex.l).
+
+      symbol_table::unmark_forced_variables (fcn->scope ());
+    }
+
+  return retval;
+}
+
+static void
+recover_from_parsing_function (void)
+{
+  if (symtab_context.empty ())
+    panic_impossible ();
+
+  symbol_table::set_scope (symtab_context.top ());
+  symtab_context.pop ();
+
+  lexer_flags.defining_func = false;
+  lexer_flags.parsed_function_name = false;
+  lexer_flags.looking_at_return_list = false;
+  lexer_flags.looking_at_parameter_list = false;
+}
+
+// Make an index expression.
+
+static tree_index_expression *
+make_index_expression (tree_expression *expr, tree_argument_list *args,
+		       char type)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  expr->mark_postfix_indexed ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (args, type);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, args, l, c, type);
+
+  return retval;
+}
+
+// Make an indirect reference expression.
+
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, const std::string& elt)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (elt);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, elt, l, c);
+
+  lexer_flags.looking_at_indirect_ref = false;
+
+  return retval;
+}
+
+// Make an indirect reference expression with dynamic field name.
+
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, tree_expression *elt)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (elt);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, elt, l, c);
+
+  lexer_flags.looking_at_indirect_ref = false;
+
+  return retval;
+}
+
+// Make a declaration command.
+
+static tree_decl_command *
+make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst)
+{
+  tree_decl_command *retval = 0;
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  switch (tok)
+    {
+    case GLOBAL:
+      retval = new tree_global_command (lst, l, c);
+      break;
+
+    case STATIC:
+      if (lexer_flags.defining_func)
+	retval = new tree_static_command (lst, l, c);
+      else
+	{
+	  if (reading_script_file)
+	    warning ("ignoring persistent declaration near line %d of file `%s'",
+		     l, curr_fcn_file_full_name.c_str ());
+	  else
+	    warning ("ignoring persistent declaration near line %d", l);
+	}
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  return retval;
+}
+
+// Finish building a matrix list.
+
+static tree_expression *
+finish_matrix (tree_matrix *m)
+{
+  tree_expression *retval = m;
+
+  unwind_protect::begin_frame ("finish_matrix");
+
+  unwind_protect_int (error_state);
+  unwind_protect_int (warning_state);
+
+  unwind_protect_bool (discard_error_messages);
+  unwind_protect_bool (discard_warning_messages);
+
+  discard_error_messages = true;
+  discard_warning_messages = true;
+
+  if (m->all_elements_are_constant ())
+    {
+      octave_value tmp = m->rvalue1 ();
+
+      if (! (error_state || warning_state))
+	{
+	  tree_constant *tc_retval
+	    = new tree_constant (tmp, m->line (), m->column ());
+
+	  std::ostringstream buf;
+
+	  tree_print_code tpc (buf);
+
+	  m->accept (tpc);
+
+	  tc_retval->stash_original_text (buf.str ());
+
+	  delete m;
+
+	  retval = tc_retval;
+	}
+    }
+
+  unwind_protect::run_frame ("finish_matrix");
+
+  return retval;
+}
+
+// Finish building a cell list.
+
+static tree_expression *
+finish_cell (tree_cell *c)
+{
+  return finish_matrix (c);
+}
+
+static void
+maybe_warn_missing_semi (tree_statement_list *t)
+{
+  if (lexer_flags.defining_func)
+    {
+      tree_statement *tmp = t->back();
+
+      if (tmp->is_expression ())
+	warning_with_id
+	  ("Octave:missing-semicolon",
+	   "missing semicolon near line %d, column %d in file `%s'",
+	    tmp->line (), tmp->column (), curr_fcn_file_full_name.c_str ());
+    }
+}
+
+static tree_statement_list *
+set_stmt_print_flag (tree_statement_list *list, char sep,
+		     bool warn_missing_semi)
+{
+  tree_statement *tmp = list->back ();
+
+  switch (sep)
+    {
+    case ';':
+      tmp->set_print_flag (false);
+      break;
+
+    case 0:
+    case ',':
+    case '\n':
+      tmp->set_print_flag (true);
+      if (warn_missing_semi)
+	maybe_warn_missing_semi (list);
+      break;
+
+    default:
+      warning ("unrecognized separator type!");
+      break;
+    }
+
+  // Even if a statement is null, we add it to the list then remove it
+  // here so that the print flag is applied to the correct statement.
+
+  if (tmp->is_null_statement ())
+    {
+      list->pop_back ();
+      delete tmp;
+    }
+
+  return list;
+}
+
+static tree_statement_list *
+make_statement_list (tree_statement *stmt)
+{
+  return new tree_statement_list (stmt);
+}
+
+static tree_statement_list *
+append_statement_list (tree_statement_list *list, char sep,
+		       tree_statement *stmt, bool warn_missing_semi)
+{
+  set_stmt_print_flag (list, sep, warn_missing_semi);
+
+  list->append (stmt);
+
+  return list;
+}
+
+static void
+safe_fclose (void *f)
+{
+  // FIXME -- comments at the end of an input file are
+  // discarded (otherwise, they would be appended to the next
+  // statement, possibly from the command line or another file, which
+  // can be quite confusing).
+
+  octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+  delete tc;
+
+  if (f)
+    fclose (static_cast<FILE *> (f));
+}
+
+static bool
+looks_like_copyright (const std::string& s)
+{
+  bool retval = false;
+
+  if (! s.empty ())
+    {
+      size_t offset = s.find_first_not_of (" \t");
+  
+      retval = (s.substr (offset, 9) == "Copyright");
+    }
+
+  return retval;
+}
+
+static int
+text_getc (FILE *f)
+{
+  int c = getc (f);
+
+  // Convert CRLF into just LF and single CR into LF.
+
+  if (c == '\r')
+    {
+      c = getc (f);
+
+      if (c != '\n')
+	{
+	  ungetc (c, f);
+	  c = '\n';
+	}
+    }
+
+  if (c == '\n')
+    input_line_number++;
+
+  return c;
+}
+
+class
+stdio_stream_reader : public stream_reader
+{
+public:
+  stdio_stream_reader (FILE *f_arg) : stream_reader (), f (f_arg) { }
+
+  int getc (void) { return ::text_getc (f); }
+  int ungetc (int c)
+  {
+    if (c == '\n')
+      input_line_number--;
+
+    return ::ungetc (c, f);
+  }
+  
+private:
+  FILE *f;
+};
+
+static bool
+skip_white_space (stream_reader& reader)
+{
+  int c = 0;
+
+  while ((c = reader.getc ()) != EOF)
+    {
+      switch (c)
+	{
+	case ' ':
+	case '\t':
+	  current_input_column++;
+	  break;
+
+	case '\n':
+	  current_input_column = 0;
+	  break;
+
+	default:
+	  current_input_column--;
+	  reader.ungetc (c);
+	  goto done;
+	}
+    }
+
+ done:
+
+  return (c == EOF);
+}
+
+static std::string
+gobble_leading_white_space (FILE *ffile, bool& eof)
+{
+  std::string help_txt;
+
+  eof = false;
+
+  // TRUE means we have already cached the help text.
+  bool have_help_text = false;
+
+  std::string txt;
+
+  stdio_stream_reader stdio_reader (ffile);
+
+  while (true)
+    {
+      eof = skip_white_space (stdio_reader);
+
+      if (eof)
+	break;
+
+      txt = grab_comment_block (stdio_reader, true, eof);
+
+      if (txt.empty ())
+	break;
+
+      if (! (have_help_text || looks_like_copyright (txt)))
+	{
+	  help_txt = txt;
+	  have_help_text = true;
+	}
+
+      octave_comment_buffer::append (txt);
+
+      if (eof)
+	break;
+    }
+
+  return help_txt;
+}
+
+static bool
+looking_at_function_keyword (FILE *ffile)
+{
+  bool status = false;
+
+  long pos = ftell (ffile);
+
+  char buf [10];
+  fgets (buf, 10, ffile);
+  size_t len = strlen (buf);
+  if (len > 8 && strncmp (buf, "function", 8) == 0
+      && ! (isalnum (buf[8]) || buf[8] == '_'))
+    status = true;
+
+  fseek (ffile, pos, SEEK_SET);
+
+  return status;
+}
+
+static void
+restore_command_history (void *)
+{
+  command_history::ignore_entries (! Vsaving_history);
+}
+
+static void
+restore_input_stream (void *f)
+{
+  command_editor::set_input_stream (static_cast<FILE *> (f));
+}
+
+static octave_function *
+parse_fcn_file (const std::string& ff, const std::string& dispatch_type,
+		bool force_script = false, bool require_file = true,
+		const std::string& warn_for = std::string ())
+{
+  unwind_protect::begin_frame ("parse_fcn_file");
+
+  octave_function *fcn_ptr = 0;
+
+  // Open function file and parse.
+
+  bool old_reading_fcn_file_state = reading_fcn_file;
+
+  FILE *in_stream = command_editor::get_input_stream ();
+
+  unwind_protect::add (restore_input_stream, in_stream);
+
+  unwind_protect_ptr (ff_instream);
+
+  unwind_protect_int (input_line_number);
+  unwind_protect_int (current_input_column);
+  unwind_protect_int (end_tokens_expected);
+  unwind_protect_bool (reading_fcn_file);
+  unwind_protect_bool (line_editing);
+  unwind_protect_str (parent_function_name);
+  unwind_protect_str (current_class_name);
+
+  input_line_number = 1;
+  current_input_column = 1;
+  end_tokens_expected = 0;
+  reading_fcn_file = true;
+  line_editing = false;
+  parent_function_name = "";
+  current_class_name = dispatch_type;
+
+  // The next four lines must be in this order.
+  unwind_protect::add (restore_command_history, 0);
+
+  // FIXME -- we shouldn't need both the
+  // command_history object and the
+  // Vsaving_history variable...
+  command_history::ignore_entries ();
+
+  unwind_protect_bool (Vsaving_history);
+
+  Vsaving_history = false;
+
+  FILE *ffile = get_input_from_file (ff, 0);
+
+  unwind_protect::add (safe_fclose, ffile);
+
+  if (ffile)
+    {
+      bool eof;
+
+      std::string help_txt = gobble_leading_white_space (ffile, eof);
+
+      if (! eof)
+	{
+	  std::string file_type;
+
+	  bool parsing_script = false;
+
+	  unwind_protect_bool (get_input_from_eval_string);
+	  unwind_protect_bool (parser_end_of_input);
+
+	  get_input_from_eval_string = false;
+	  parser_end_of_input = false;
+
+	  if (! force_script && looking_at_function_keyword (ffile))
+	    {
+	      file_type = "function";
+
+	      unwind_protect_int (Vecho_executing_commands);
+	      unwind_protect_bool (reading_fcn_file);
+
+	      Vecho_executing_commands = ECHO_OFF;
+	      reading_fcn_file = true;
+	    }
+	  else
+	    {
+	      file_type = "script";
+
+	      // The value of `reading_fcn_file' will be restored to the
+	      // proper value when we unwind from this frame.
+	      reading_fcn_file = old_reading_fcn_file_state;
+
+	      unwind_protect_bool (reading_script_file);
+
+	      reading_script_file = true;
+
+	      parsing_script = true;
+	    }
+
+	  YY_BUFFER_STATE old_buf = current_buffer ();
+	  YY_BUFFER_STATE new_buf = create_buffer (ffile);
+
+	  unwind_protect::add (restore_input_buffer, old_buf);
+	  unwind_protect::add (delete_input_buffer, new_buf);
+
+	  switch_to_buffer (new_buf);
+
+	  unwind_protect_ptr (curr_fcn_ptr);
+	  curr_fcn_ptr = 0;
+
+	  reset_parser ();
+
+	  // Do this with an unwind-protect cleanup function so that
+	  // the forced variables will be unmarked in the event of an
+	  // interrupt. 
+	  symbol_table::scope_id scope = symbol_table::top_scope ();
+	  unwind_protect::add (symbol_table::unmark_forced_variables, &scope);
+
+	  if (! help_txt.empty ())
+	    help_buf.push (help_txt);
+
+	  if (parsing_script)
+	    prep_lexer_for_script ();
+
+	  lexer_flags.parsing_class_method = ! dispatch_type.empty ();
+
+	  int status = yyparse ();
+
+	  fcn_ptr = curr_fcn_ptr;
+
+	  if (status != 0)
+	    error ("parse error while reading %s file %s",
+		   file_type.c_str(), ff.c_str ());
+	}
+    }
+  else if (require_file)
+    error ("no such file, `%s'", ff.c_str ());
+  else if (! warn_for.empty ())
+    error ("%s: unable to open file `%s'", warn_for.c_str (), ff.c_str ());    
+
+  unwind_protect::run_frame ("parse_fcn_file");
+
+  return fcn_ptr;
+}
+
+std::string
+get_help_from_file (const std::string& nm, bool& symbol_found,
+		    std::string& file)
+{
+  std::string retval;
+
+  file = fcn_file_in_path (nm);
+
+  if (! file.empty ())
+    {
+      symbol_found = true;
+
+      FILE *fptr = fopen (file.c_str (), "r");
+
+      if (fptr)
+	{
+	  unwind_protect::add (safe_fclose, fptr);
+
+	  bool eof;
+	  retval = gobble_leading_white_space (fptr, eof);
+
+	  if (retval.empty ())
+	    {
+	      octave_function *fcn = parse_fcn_file (file, "");
+
+	      if (fcn)
+		{
+		  retval = fcn->doc_string ();
+
+		  delete fcn;
+		}
+	    }
+
+	  unwind_protect::run ();
+	}
+    }
+
+  return retval;
+}
+
+std::string
+get_help_from_file (const std::string& nm, bool& symbol_found)
+{
+  std::string file;
+  return get_help_from_file (nm, symbol_found, file);
+}
+
+std::string
+lookup_autoload (const std::string& nm)
+{
+  std::string retval;
+
+  typedef std::map<std::string, std::string>::const_iterator am_iter;
+
+  am_iter p = autoload_map.find (nm);
+
+  if (p != autoload_map.end ())
+    retval = load_path::find_file (p->second);
+
+  return retval;
+}
+
+string_vector 
+autoloaded_functions (void)
+{
+  string_vector names (autoload_map.size());
+
+  octave_idx_type i = 0;
+  typedef std::map<std::string, std::string>::const_iterator am_iter;
+  for (am_iter p = autoload_map.begin (); p != autoload_map.end (); p++)
+    names[i++] = p->first;
+
+  return names;
+}
+
+string_vector
+reverse_lookup_autoload (const std::string& nm)
+{
+  string_vector names;
+
+  typedef std::map<std::string, std::string>::const_iterator am_iter;
+  for (am_iter p = autoload_map.begin (); p != autoload_map.end (); p++)
+    if (nm == p->second)
+      names.append (p->first);
+
+  return names;
+}
+
+octave_function *
+load_fcn_from_file (const std::string& file_name, const std::string& dir_name,
+		    const std::string& dispatch_type,
+		    const std::string& fcn_name, bool autoload)
+{
+  octave_function *retval = 0;
+
+  unwind_protect::begin_frame ("load_fcn_from_file");
+
+  std::string nm = file_name;
+
+  size_t nm_len = nm.length ();
+
+  std::string file;
+
+  unwind_protect_bool (fcn_file_from_relative_lookup);
+
+  fcn_file_from_relative_lookup = false;
+
+  file = nm;
+
+  if ((nm_len > 4 && nm.substr (nm_len-4) == ".oct")
+      || (nm_len > 4 && nm.substr (nm_len-4) == ".mex")
+      || (nm_len > 2 && nm.substr (nm_len-2) == ".m"))
+    {
+      nm = octave_env::base_pathname (file);
+      nm = nm.substr (0, nm.find_last_of ('.'));
+    }
+
+  if (autoload)
+    {
+      unwind_protect_bool (autoloading);
+      autoloading = true;
+    }
+
+  fcn_file_from_relative_lookup = ! octave_env::absolute_pathname (file);
+
+  file = octave_env::make_absolute (file, octave_env::getcwd ());
+
+  int len = file.length ();
+
+  if (len > 4 && file.substr (len-4, len-1) == ".oct")
+    {
+      if (autoload && ! fcn_name.empty ())
+	nm = fcn_name;
+
+      retval = octave_dynamic_loader::load_oct (nm, file, fcn_file_from_relative_lookup);
+    }
+  else if (len > 4 && file.substr (len-4, len-1) == ".mex")
+    retval = octave_dynamic_loader::load_mex (nm, file, fcn_file_from_relative_lookup);
+  else if (len > 2)
+    {
+      // These are needed by yyparse.
+
+      unwind_protect_str (curr_fcn_file_name);
+      unwind_protect_str (curr_fcn_file_full_name);
+
+      curr_fcn_file_name = nm;
+      curr_fcn_file_full_name = file;
+
+      retval = parse_fcn_file (file, dispatch_type, autoloading);
+    }
+
+  if (retval)
+    {
+      retval->stash_dir_name (dir_name);
+
+      if (retval->is_user_function ())
+	{
+	  symbol_table::scope_id id = retval->scope ();
+
+	  symbol_table::stash_dir_name_for_subfunctions (id, dir_name);
+	}
+    }
+
+  unwind_protect::run_frame ("load_fcn_from_file");
+
+  return retval;
+}
+
+DEFUN (autoload, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\
+Define @var{function} to autoload from @var{file}.\n\
+\n\
+The second argument, @var{file}, should be an absolute file name or\n\
+a file name in the same directory as the function or script from which\n\
+the autoload command was run.  @var{file} should not depend on the\n\
+Octave load path.\n\
+\n\
+Normally, calls to @code{autoload} appear in PKG_ADD script files that\n\
+are evaluated when a directory is added to the Octave's load path.  To\n\
+avoid having to hardcode directory names in @var{file}, if @var{file}\n\
+is in the same directory as the PKG_ADD script then\n\
+\n\
+ at example\n\
+autoload (\"foo\", \"bar.oct\");\n\
+ at end example\n\
+\n\
+will load the function @code{foo} from the file @code{bar.oct}.  The above\n\
+when @code{bar.oct} is not in the same directory or uses like\n\
+\n\
+ at example\n\
+autoload (\"foo\", file_in_loadpath (\"bar.oct\"))\n\
+ at end example\n\
+\n\
+ at noindent\n\
+are strongly discouraged, as their behavior might be unpredictable.\n\
+\n\
+With no arguments, return a structure containing the current autoload map.\n\
+ at seealso{PKG_ADD}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      Cell func_names (dim_vector (autoload_map.size ()), 1);
+      Cell file_names (dim_vector (autoload_map.size ()), 1);
+
+      octave_idx_type i = 0;
+      typedef std::map<std::string, std::string>::const_iterator am_iter;
+      for (am_iter p = autoload_map.begin (); p != autoload_map.end (); p++)
+	{
+	  func_names(i) = p->first;
+	  file_names(i) = p->second;
+
+	  i++;
+	}
+
+      Octave_map m;
+
+      m.assign ("function", func_names);
+      m.assign ("file", file_names);
+
+      retval = m;
+    }
+  else if (nargin == 2)
+    {
+      string_vector argv = args.make_argv ("autoload");
+
+      if (! error_state)
+        {
+	  std::string nm = argv[2];
+
+	  if (! octave_env::absolute_pathname (nm))
+	    {
+	      octave_user_code *fcn = octave_call_stack::caller_user_code ();
+
+	      bool found = false;
+
+	      if (fcn)
+		{
+		  std::string fname = fcn->fcn_file_name ();
+
+		  if (! fname.empty ())
+		    {
+		      fname = octave_env::make_absolute (fname, octave_env::getcwd ());
+		      fname = fname.substr (0, fname.find_last_of (file_ops::dir_sep_str ()) + 1);
+
+		      file_stat fs (fname + nm);
+
+		      if (fs.exists ())
+			{
+			  nm = fname + nm;
+			  found = true;
+			}
+		    }
+		}
+	      if (! found)
+		warning_with_id ("Octave:autoload-relative-file-name",
+				 "autoload: `%s' is not an absolute file name",
+				 nm.c_str ());
+	    }
+	  autoload_map[argv[1]] = nm;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+void
+source_file (const std::string& file_name, const std::string& context,
+	     bool verbose, bool require_file, const std::string& warn_for)
+{
+  std::string file_full_name = file_ops::tilde_expand (file_name);
+
+  unwind_protect::begin_frame ("source_file");
+
+  unwind_protect_str (curr_fcn_file_name);
+  unwind_protect_str (curr_fcn_file_full_name);
+
+  curr_fcn_file_name = file_name;
+  curr_fcn_file_full_name = file_full_name;
+
+  if (! context.empty ())
+    {
+      if (context == "caller")
+	octave_call_stack::goto_caller_frame ();
+      else if (context == "base")
+	octave_call_stack::goto_base_frame ();
+      else
+	error ("source: context must be \"caller\" or \"base\"");
+
+      if (! error_state)
+	unwind_protect::add (octave_call_stack::unwind_pop);
+    }      
+
+  if (! error_state)
+    {
+      octave_function *fcn = parse_fcn_file (file_full_name, "", true,
+					     require_file, warn_for);
+
+      if (! error_state)
+	{
+	  if (fcn && fcn->is_user_script ())
+	    {
+	      octave_value_list args;
+
+	      if (verbose)
+		{
+		  std::cout << "executing commands from " << file_full_name << " ... ";
+		  reading_startup_message_printed = true;
+		  std::cout.flush ();
+		}
+
+	      fcn->do_multi_index_op (0, args);
+
+	      if (verbose)
+		std::cout << "done." << std::endl;
+
+	      delete fcn;
+	    }
+	}
+      else
+	error ("source: error sourcing file `%s'",
+	       file_full_name.c_str ());
+    }
+
+  unwind_protect::run_frame ("source_file");
+}
+
+DEFUN (mfilename, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mfilename ()\n\
+ at deftypefnx {Built-in Function} {} mfilename (@code{\"fullpath\"})\n\
+ at deftypefnx {Built-in Function} {} mfilename (@code{\"fullpathext\"})\n\
+Return the name of the currently executing file.  At the top-level,\n\
+return the empty string.  Given the argument @code{\"fullpath\"},\n\
+include the directory part of the file name, but not the extension.\n\
+Given the argument @code{\"fullpathext\"}, include the directory part\n\
+of the file name and the extension.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string arg;
+
+  if (nargin == 1)
+    {
+      arg = args(0).string_value ();
+
+      if (error_state)
+	{
+	  error ("mfilename: expecting argument to be a character string");
+	  return retval;
+	}
+    }
+
+  std::string fname;
+
+  octave_user_code *fcn = octave_call_stack::caller_user_code ();
+
+  if (fcn)
+    {
+      fname = fcn->fcn_file_name ();
+
+      if (fname.empty ())
+        fname = fcn->name ();
+    }
+
+  if (arg == "fullpathext")
+    retval = fname;
+  else
+    {
+      size_t dpos = fname.rfind (file_ops::dir_sep_char ());
+      size_t epos = fname.rfind ('.');
+
+      if (epos <= dpos)
+        epos = std::string::npos;
+
+      fname = (epos != std::string::npos) ? fname.substr (0, epos) : fname;
+
+      if (arg == "fullpath")
+	retval = fname;
+      else
+        retval = (dpos != std::string::npos) ? fname.substr (dpos+1) : fname;
+    }
+
+  return retval;
+}
+
+
+DEFUN (source, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} source (@var{file})\n\
+Parse and execute the contents of @var{file}.  This is equivalent to\n\
+executing commands from a script file, but without requiring the file to\n\
+be named @file{@var{file}.m}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string file_name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string context;
+
+	  if (nargin == 2)
+	    context = args(1).string_value ();
+
+	  if (! error_state)
+	    source_file (file_name, context);
+	  else
+	    error ("source: expecting context to be character string");
+	}
+      else
+	error ("source: expecting file name as argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Evaluate an Octave function (built-in or interpreted) and return
+// the list of result values.  NAME is the name of the function to
+// call.  ARGS are the arguments to the function.  NARGOUT is the
+// number of output arguments expected. 
+
+octave_value_list
+feval (const std::string& name, const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  octave_value fcn = symbol_table::find_function (name, args);
+
+  if (fcn.is_defined ())
+    retval = fcn.do_multi_index_op (nargout, args);
+  else
+    error ("feval: function `%s' not found", name.c_str ());
+
+  return retval;
+}
+
+octave_value_list
+feval (octave_function *fcn, const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  if (fcn)
+    retval = fcn->do_multi_index_op (nargout, args);
+
+  return retval;
+}
+
+static octave_value_list
+get_feval_args (const octave_value_list& args)
+{
+  int tmp_nargin = args.length () - 1;
+
+  octave_value_list retval (tmp_nargin, octave_value ());
+
+  for (int i = 0; i < tmp_nargin; i++)
+    retval(i) = args(i+1);
+
+  string_vector arg_names = args.name_tags ();
+
+  if (! arg_names.empty ())
+    {
+      // tmp_nargin and arg_names.length () - 1 may differ if
+      // we are passed all_va_args.
+
+      int n = arg_names.length () - 1;
+
+      int len = n > tmp_nargin ? tmp_nargin : n;
+
+      string_vector tmp_arg_names (len);
+
+      for (int i = 0; i < len; i++)
+	tmp_arg_names(i) = arg_names(i+1);
+
+      retval.stash_name_tags (tmp_arg_names);
+    }
+
+  return retval;
+}
+
+
+// Evaluate an Octave function (built-in or interpreted) and return
+// the list of result values.  The first element of ARGS should be a
+// string containing the name of the function to call, then the rest
+// are the actual arguments to the function.  NARGOUT is the number of
+// output arguments expected.
+
+octave_value_list
+feval (const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      octave_value f_arg = args(0);
+
+      if (f_arg.is_string ())
+        {
+	  std::string name = f_arg.string_value ();
+
+	  if (! error_state)
+	    {
+	      octave_value_list tmp_args = get_feval_args (args);
+
+	      retval = feval (name, tmp_args, nargout);
+	    }
+	}
+      else
+	{
+	  octave_function *fcn = f_arg.function_value ();
+
+	  if (fcn)
+	    {
+	      octave_value_list tmp_args = get_feval_args (args);
+
+	      retval = feval (fcn, tmp_args, nargout);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (feval, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} feval (@var{name}, @dots{})\n\
+Evaluate the function named @var{name}.  Any arguments after the first\n\
+are passed on to the named function.  For example,\n\
+\n\
+ at example\n\
+feval (\"acos\", -1)\n\
+     @result{} 3.1416\n\
+ at end example\n\
+\n\
+ at noindent\n\
+calls the function @code{acos} with the argument @samp{-1}.\n\
+\n\
+The function @code{feval} is necessary in order to be able to write\n\
+functions that call user-supplied functions, because Octave does not\n\
+have a way to declare a pointer to a function (like C) or to declare a\n\
+special kind of variable that can be used to hold the name of a function\n\
+(like @code{EXTERNAL} in Fortran).  Instead, you must refer to functions\n\
+by name, and use @code{feval} to call them.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    retval = feval (args, nargout);
+  else
+    print_usage ();
+
+  return retval;
+}
+
+octave_value_list
+eval_string (const std::string& s, bool silent, int& parse_status, int nargout)
+{
+  octave_value_list retval;
+
+  unwind_protect::begin_frame ("eval_string");
+
+  unwind_protect_int (input_line_number);
+  unwind_protect_int (current_input_column);
+  unwind_protect_bool (get_input_from_eval_string);
+  unwind_protect_bool (input_from_eval_string_pending);
+  unwind_protect_bool (parser_end_of_input);
+  unwind_protect_bool (line_editing);
+  unwind_protect_str (current_eval_string);
+
+  input_line_number = 1;
+  current_input_column = 1;
+  get_input_from_eval_string = true;
+  input_from_eval_string_pending = true;
+  parser_end_of_input = false;
+  line_editing = false;
+
+  current_eval_string = s;
+
+  YY_BUFFER_STATE old_buf = current_buffer ();
+  YY_BUFFER_STATE new_buf = create_buffer (0);
+
+  unwind_protect::add (restore_input_buffer, old_buf);
+  unwind_protect::add (delete_input_buffer, new_buf);
+
+  switch_to_buffer (new_buf);
+
+  do
+    {
+      reset_parser ();
+
+      unwind_protect_ptr (global_command);
+
+      // Do this with an unwind-protect cleanup function so that the
+      // forced variables will be unmarked in the event of an
+      // interrupt.
+      symbol_table::scope_id scope = symbol_table::top_scope ();
+      unwind_protect::add (symbol_table::unmark_forced_variables, &scope);
+
+      parse_status = yyparse ();
+
+      tree_statement_list *command_list = global_command;
+
+      // Unmark forced variables.
+      unwind_protect::run ();
+
+      // Restore previous value of global_command.
+      unwind_protect::run ();
+
+      if (parse_status == 0)
+        {
+	  if (command_list)
+	    {
+	      tree_statement *stmt = 0;
+
+	      if (command_list->length () == 1
+		  && (stmt = command_list->front ())
+		  && stmt->is_expression ())
+		{
+		  tree_expression *expr = stmt->expression ();
+
+		  if (silent)
+		    expr->set_print_flag (false);
+
+		  bool do_bind_ans = false;
+
+		  if (expr->is_identifier ())
+		    {
+		      tree_identifier *id
+			= dynamic_cast<tree_identifier *> (expr);
+
+		      do_bind_ans = (! id->is_variable ());
+		    }
+		  else
+		    do_bind_ans = (! expr->is_assignment_expression ());
+
+		  retval = expr->rvalue (nargout);
+
+		  if (do_bind_ans && ! (error_state || retval.empty ()))
+		    bind_ans (retval(0), expr->print_result ());
+
+		  if (nargout == 0)
+		    retval = octave_value_list ();
+		}
+	      else if (nargout == 0)
+		command_list->accept (*current_evaluator);
+	      else
+		error ("eval: invalid use of statement list");
+
+	      delete command_list;
+
+	      command_list = 0;
+
+	      if (error_state
+		  || tree_return_command::returning
+		  || tree_break_command::breaking
+		  || tree_continue_command::continuing)
+		break;
+	    }
+	  else if (parser_end_of_input)
+	    break;
+        }
+    }
+  while (parse_status == 0);
+
+  unwind_protect::run_frame ("eval_string");
+
+  return retval;
+}
+
+octave_value
+eval_string (const std::string& s, bool silent, int& parse_status)
+{
+  octave_value retval;
+
+  octave_value_list tmp = eval_string (s, silent, parse_status, 1);
+
+  if (! tmp.empty ())
+    retval = tmp(0);
+
+  return retval;
+}
+
+static octave_value_list
+eval_string (const octave_value& arg, bool silent, int& parse_status,
+	     int nargout)
+{
+  std::string s = arg.string_value ();
+
+  if (error_state)
+    {
+      error ("eval: expecting std::string argument");
+      return octave_value (-1);
+    }
+
+  return eval_string (s, silent, parse_status, nargout);
+}
+
+DEFUN (eval, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} eval (@var{try}, @var{catch})\n\
+Parse the string @var{try} and evaluate it as if it were an Octave\n\
+program.  If that fails, evaluate the optional string @var{catch}.\n\
+The string @var{try} is evaluated in the current context,\n\
+so any results remain available after @code{eval} returns.\n\
+\n\
+The following example makes the variable @var{a} with the approximate\n\
+value 3.1416 available.\n\
+\n\
+ at example\n\
+eval(\"a = acos(-1);\");\n\
+ at end example\n\
+\n\
+If an error occurs during the evaluation of @var{try} the @var{catch}\n\
+string is evaluated, as the following example shows:\n\
+\n\
+ at example\n\
+eval ('error (\"This is a bad example\");',\n\
+      'printf (\"This error occurred:\\n%s\\n\", lasterr ());');\n\
+     @print{} This error occurred:\n\
+        This is a bad example\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      unwind_protect::begin_frame ("Feval");
+
+      if (nargin > 1)
+	{
+	  unwind_protect_int (buffer_error_messages);
+	  buffer_error_messages++;
+	}
+
+      int parse_status = 0;
+
+      octave_value_list tmp = eval_string (args(0), nargout > 0,
+					   parse_status, nargout);
+
+      if (nargin > 1 && (parse_status != 0 || error_state))
+	{
+	  error_state = 0;
+
+	  // Set up for letting the user print any messages from
+	  // errors that occurred in the first part of this eval().
+
+	  buffer_error_messages--;
+
+	  tmp = eval_string (args(1), nargout > 0, parse_status, nargout);
+
+	  if (nargout > 0)
+	    retval = tmp;
+	}
+      else if (nargout > 0)
+	retval = tmp;
+
+      unwind_protect::run_frame ("Feval");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%% test/octave.test/eval/eval-1.m
+%!#test
+%! x = 1;
+%! assert(eval ("x"),1);
+
+%% test/octave.test/eval/eval-2.m
+%!test
+%! x = 1;
+%! assert(eval ("x;"));
+
+%% test/octave.test/eval/eval-3.m
+%!test
+%! x = 1;
+%! assert(eval ("x;"),1);
+
+%% FIXME
+%% Disable this test as adding the ";" is redundant with eval-1 and
+%% in any case is a syntax error with assert
+%% test/octave.test/eval/eval-4.m
+%!#test
+%! x = 1;
+%! assert(eval ("x");,1);
+
+%% test/octave.test/eval/eval-5.m
+%!test
+%! eval ("flipud = 2;");
+%! assert(flipud,2);
+
+%% test/octave.test/eval/eval-6.m
+%!function y = f ()
+%!  eval ("flipud = 2;");
+%!  y = flipud;
+%!test
+%! assert(f,2);
+
+%% test/octave.test/eval/eval-7.m
+%!#test
+%! eval ("x = 1");
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-8.m
+%!test
+%! eval ("x = 1;")
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-9.m
+%!test
+%! eval ("x = 1;");
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-10.m
+%!#test
+%! eval ("x = 1")
+%! assert(x,1);
+
+%% test/octave.test/eval/eval-11.m
+%!test
+%! x = 1;
+%! y = eval ("x");
+%! assert(y,1);
+
+%% test/octave.test/eval/eval-12.m
+%!test
+%! x = 1;
+%! y = eval ("x;");
+%! assert(y,1);
+
+%% test/octave.test/eval/eval-13.m
+%!test
+%! x = 1;
+%! y = eval ("x;");
+%! assert(y,1);
+
+%% test/octave.test/eval/eval-14.m
+%!test
+%! x = 1;
+%! y = eval ("x");
+%! assert(y,1);
+
+*/
+
+DEFUN (assignin, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\
+Assign @var{value} to @var{varname} in context @var{context}, which\n\
+may be either @code{\"base\"} or @code{\"caller\"}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 3)
+    {
+      std::string context = args(0).string_value ();
+
+      if (! error_state)
+        {
+	  unwind_protect::begin_frame ("Fassignin");
+
+	  if (context == "caller")
+	    octave_call_stack::goto_caller_frame ();
+	  else if (context == "base")
+	    octave_call_stack::goto_base_frame ();
+	  else
+	    error ("assignin: context must be \"caller\" or \"base\"");
+
+	  if (! error_state)
+	    {
+	      unwind_protect::add (octave_call_stack::unwind_pop);
+
+	      std::string nm = args(1).string_value ();
+
+	      if (! error_state)
+		{
+		  if (valid_identifier (nm))
+		    symbol_table::varref (nm) = args(2);
+		  else
+		    error ("assignin: invalid variable name");
+		}
+	      else
+		error ("assignin: expecting variable name as second argument");
+	    }
+
+	  unwind_protect::run_frame ("Fassignin");
+	}
+      else
+        error ("assignin: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (evalin, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\
+Like @code{eval}, except that the expressions are evaluated in the\n\
+context @var{context}, which may be either @code{\"caller\"} or\n\
+ at code{\"base\"}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 1)
+    {
+      std::string context = args(0).string_value ();
+
+      if (! error_state)
+        {
+	  unwind_protect::begin_frame ("Fevalin");
+
+	  if (context == "caller")
+	    octave_call_stack::goto_caller_frame ();
+	  else if (context == "base")
+	    octave_call_stack::goto_base_frame ();
+	  else
+	    error ("evalin: context must be \"caller\" or \"base\"");
+
+	  if (! error_state)
+	    {
+	      unwind_protect::add (octave_call_stack::unwind_pop);
+
+	      if (nargin > 2)
+	        {
+		  unwind_protect_int (buffer_error_messages);
+		  buffer_error_messages++;
+		}
+
+	      int parse_status = 0;
+
+	      octave_value_list tmp = eval_string (args(1), nargout > 0,
+						   parse_status, nargout);
+
+	      if (nargout > 0)
+		retval = tmp;
+
+	      if (nargin > 2 && (parse_status != 0 || error_state))
+		{
+		  error_state = 0;
+
+		  // Set up for letting the user print any messages from
+		  // errors that occurred in the first part of this eval().
+
+		  buffer_error_messages--;
+
+		  tmp = eval_string (args(2), nargout > 0,
+				     parse_status, nargout);
+
+		  retval = (nargout > 0) ? tmp : octave_value_list ();
+		}
+	    }
+
+	  unwind_protect::run_frame ("Fevalin");
+	}
+      else
+        error ("evalin: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__parser_debug_flag__, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{old_val} =} __parser_debug_flag__ (@var{new_val}))\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  bool debug_flag = octave_debug;
+
+  retval = set_internal_variable (debug_flag, args, nargout,
+           			  "__parser_debug_flag__");
+
+  octave_debug = debug_flag;
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: text ***
+;;; End: ***
+*/
diff --git a/src/pr-output.cc b/src/pr-output.cc
new file mode 100644
index 0000000..876aca0
--- /dev/null
+++ b/src/pr-output.cc
@@ -0,0 +1,3854 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstdio>
+#include <cstring>
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "Array-util.h"
+#include "CMatrix.h"
+#include "Range.h"
+#include "cmd-edit.h"
+#include "dMatrix.h"
+#include "lo-mappers.h"
+#include "lo-math.h"
+#include "mach-info.h"
+#include "oct-cmplx.h"
+#include "quit.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "oct-stream.h"
+#include "pager.h"
+#include "pr-output.h"
+#include "sysdep.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// TRUE means use a scaled fixed point format for `format long' and
+// `format short'.
+static bool Vfixed_point_format = false;
+
+// The maximum field width for a number printed by the default output
+// routines.
+static int Voutput_max_field_width = 10;
+
+// The precision of the numbers printed by the default output
+// routines.
+static int Voutput_precision = 5;
+
+// TRUE means that the dimensions of empty objects should be printed
+// like this: x = [](2x0).
+bool Vprint_empty_dimensions = true;
+
+// TRUE means that the rows of big matrices should be split into
+// smaller slices that fit on the screen.
+static bool Vsplit_long_rows = true;
+
+// How many levels of structure elements should we print?
+int Vstruct_levels_to_print = 2;
+
+// TRUE means don't do any fancy formatting.
+static bool free_format = false;
+
+// TRUE means print plus sign for nonzero, blank for zero.
+static bool plus_format = false;
+
+// First char for > 0, second for < 0, third for == 0.
+static std::string plus_format_chars = "+  ";
+
+// TRUE means always print in a rational approximation
+static bool rat_format = false;
+
+// Used to force the length of the rational approximation string for Frats
+static int rat_string_len = -1;
+
+// TRUE means always print like dollars and cents.
+static bool bank_format = false;
+
+// TRUE means print data in hexadecimal format.
+static int hex_format = 0;
+
+// TRUE means print data in binary-bit-pattern format.
+static int bit_format = 0;
+
+// TRUE means don't put newlines around the column number headers.
+static bool compact_format = false;
+
+// TRUE means use an e format.
+static bool print_e = false;
+
+// TRUE means use a g format.
+static bool print_g = false;
+
+// TRUE means print E instead of e for exponent field.
+static bool print_big_e = false;
+
+class pr_formatted_float;
+class pr_rational_float;
+
+static int
+current_output_max_field_width (void)
+{
+  return Voutput_max_field_width;
+}
+
+static int
+current_output_precision (void)
+{
+  return Voutput_precision;
+}
+
+class
+float_format
+{
+public:
+
+  float_format (int w = current_output_max_field_width (),
+		int p = current_output_precision (), int f = 0)
+    : fw (w), prec (p), fmt (f), up (0), sp (0) { }
+
+  float_format (const float_format& ff)
+    : fw (ff.fw), prec (ff.prec), fmt (ff.fmt), up (ff.up), sp (ff.sp) { }
+
+  float_format& operator = (const float_format& ff)
+    {
+      if (&ff != this)
+	{
+	  fw = ff.fw;
+	  prec = ff.prec;
+	  fmt = ff.fmt;
+	  up = ff.up;
+	  sp = ff.sp;
+	}
+
+      return *this;
+    }
+
+  ~float_format (void) { }
+
+  float_format& scientific (void) { fmt = std::ios::scientific; return *this; }
+  float_format& fixed (void) { fmt = std::ios::fixed; return *this; }
+  float_format& general (void) { fmt = 0; return *this; }
+
+  float_format& uppercase (void) { up = std::ios::uppercase; return *this; }
+  float_format& lowercase (void) { up = 0; return *this; }
+
+  float_format& precision (int p) { prec = p; return *this; }
+
+  float_format& width (int w) { fw = w; return *this; }
+
+  float_format& trailing_zeros (bool tz = true)
+    { sp = tz ? std::ios::showpoint : 0; return *this; }
+
+  friend std::ostream& operator << (std::ostream& os,
+				    const pr_formatted_float& pff);
+
+  friend std::ostream& operator << (std::ostream& os,
+				    const pr_rational_float& pff);
+
+private:
+
+  // Field width.  Zero means as wide as necessary.
+  int fw;
+
+  // Precision.
+  int prec;
+
+  // Format.
+  int fmt;
+
+  // E or e.
+  int up;
+
+  // Show trailing zeros.
+  int sp;
+};
+
+class
+pr_formatted_float
+{
+public:
+
+  const float_format& f;
+
+  double val;
+
+  pr_formatted_float (const float_format& f_arg, double val_arg)
+    : f (f_arg), val (val_arg) { }
+};
+
+std::ostream&
+operator << (std::ostream& os, const pr_formatted_float& pff)
+{
+  if (pff.f.fw >= 0)
+    os << std::setw (pff.f.fw);
+
+  if (pff.f.prec >= 0)
+    os << std::setprecision (pff.f.prec);
+
+  std::ios::fmtflags oflags = 
+    os.flags (static_cast<std::ios::fmtflags> 
+              (pff.f.fmt | pff.f.up | pff.f.sp));
+
+  os << pff.val;
+
+  os.flags (oflags);
+
+  return os;
+}
+
+static inline std::string
+rational_approx (double val, int len)
+{
+  std::string s;
+
+  if (len <= 0)
+    len = 10;
+
+  if (xisinf (val))
+    s = "1/0";
+  else if (xisnan (val))
+    s = "0/0";
+  else if (val < INT_MIN || val > INT_MAX || D_NINT (val) == val)
+    {
+      std::ostringstream buf;
+      buf.flags (std::ios::fixed);
+      buf << std::setprecision (0) << xround(val);
+      s = buf.str ();
+    }
+  else
+    {
+      double lastn = 1.;
+      double lastd = 0.;
+      double n = xround (val);
+      double d = 1.;
+      double frac = val - n;
+      int m = 0;
+
+      std::ostringstream buf2;
+      buf2.flags (std::ios::fixed);
+      buf2 << std::setprecision (0) << static_cast<int>(n); 
+      s = buf2.str();
+
+      while (1)
+	{
+	  double flip = 1. / frac;
+	  double step = xround (flip);
+	  double nextn = n;
+	  double nextd = d;
+
+	  // Have we converged to 1/intmax ?
+	  if (m > 100 || fabs (frac) < 1 / static_cast<double>(INT_MAX))
+	    {
+	      lastn = n;
+	      lastd = d;
+	      break;
+	    }
+
+	  frac = flip - step;
+	  n = n * step + lastn;
+	  d = d * step + lastd;
+	  lastn = nextn;
+	  lastd = nextd;
+
+	  std::ostringstream buf;
+	  buf.flags (std::ios::fixed);
+	  buf << std::setprecision (0) << static_cast<int>(n) 
+	      << "/" << static_cast<int>(d);
+	  m++;
+
+	  if (n < 0 && d < 0)
+	    {
+	      // Double negative, string can be two characters longer..
+	      if (buf.str().length() > static_cast<unsigned int>(len + 2) && 
+		  m > 1) 
+		break;
+	    }
+	  else if (buf.str().length() > static_cast<unsigned int>(len) && 
+		   m > 1) 
+	    break;
+
+	  s = buf.str();
+	}
+
+      if (lastd < 0.)
+	{
+	  // Move sign to the top
+	  lastd = - lastd;
+	  lastn = - lastn;
+	  std::ostringstream buf;
+	  buf.flags (std::ios::fixed);
+	  buf << std::setprecision (0) << static_cast<int>(lastn) 
+	       << "/" << static_cast<int>(lastd);
+	  s = buf.str();
+	}
+    }
+
+  return s;
+}
+
+class
+pr_rational_float
+{
+public:
+
+  const float_format& f;
+
+  double val;
+
+  pr_rational_float (const float_format& f_arg, double val_arg)
+    : f (f_arg), val (val_arg) { }
+};
+
+std::ostream&
+operator << (std::ostream& os, const pr_rational_float& prf)
+{
+  int fw = (rat_string_len > 0 ? rat_string_len : prf.f.fw);
+  std::string s = rational_approx (prf.val, fw);
+
+  if (fw >= 0)
+    os << std::setw (fw);
+
+  std::ios::fmtflags oflags = 
+    os.flags (static_cast<std::ios::fmtflags> 
+              (prf.f.fmt | prf.f.up | prf.f.sp));
+
+  if (fw > 0 && s.length() > static_cast<unsigned int>(fw))
+    os << "*";
+  else
+    os << s;
+
+  os.flags (oflags);
+
+  return os;
+}
+
+// Current format for real numbers and the real part of complex
+// numbers.
+static float_format *curr_real_fmt = 0;
+
+// Current format for the imaginary part of complex numbers.
+static float_format *curr_imag_fmt = 0;
+
+static double
+pr_max_internal (const Matrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  double result = -DBL_MAX;
+
+  bool all_inf_or_nan = true;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	double val = m(i,j);
+	if (xisinf (val) || xisnan (val))
+	  continue;
+
+	all_inf_or_nan = false;
+
+	if (val > result)
+	  result = val;
+      }
+
+  if (all_inf_or_nan)
+    result = 0.0;
+
+  return result;
+}
+
+static double
+pr_min_internal (const Matrix& m)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  double result = DBL_MAX;
+
+  bool all_inf_or_nan = true;
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	double val = m(i,j);
+	if (xisinf (val) || xisnan (val))
+	  continue;
+
+	all_inf_or_nan = false;
+
+	if (val < result)
+	  result = val;
+      }
+
+  if (all_inf_or_nan)
+    result = 0.0;
+
+  return result;
+}
+
+// FIXME -- it would be nice to share more code among these
+// functions,..
+
+static void
+set_real_format (int digits, bool inf_or_nan, bool int_only, int &fw)
+{
+  static float_format fmt;
+
+  int prec = Voutput_precision;
+
+  int ld, rd;
+
+  if (rat_format)
+    {
+      fw = 0;
+      rd = 0;
+    }
+  else if (bank_format)
+    {
+      fw = digits < 0 ? 4 : digits + 3;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+      rd = 2;
+    }
+  else if (hex_format)
+    {
+      fw = 2 * sizeof (double);
+      rd = 0;
+    }
+  else if (bit_format)
+    {
+      fw = 8 * sizeof (double);
+      rd = 0;
+    }
+  else if (inf_or_nan || int_only)
+    {
+      fw = 1 + digits;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+      rd = fw;
+    }
+  else
+    {
+      if (digits > 0)
+	{
+	  ld = digits;
+	  rd = prec > digits ? prec - digits : prec;
+	  digits++;
+	}
+      else
+	{
+	  ld = 1;
+	  rd = prec > digits ? prec - digits : prec;
+	  digits = -digits + 1;
+	}
+
+      fw = 1 + ld + 1 + rd;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+    }
+
+  if (! (rat_format || bank_format || hex_format || bit_format)
+      && (fw > Voutput_max_field_width || print_e || print_g))
+    {
+      if (print_g)
+	fmt = float_format ();
+      else
+	{
+	  int exp_field = 4;
+	  if (digits > 100)
+	    exp_field++;
+
+	  fw = 2 + prec + exp_field;
+	  if (inf_or_nan && fw < 4)
+	    fw = 4;
+
+	  fmt = float_format (fw, prec - 1, std::ios::scientific);
+	}
+
+      if (print_big_e)
+	fmt.uppercase ();
+    }
+  else if (! bank_format && (inf_or_nan || int_only))
+    fmt = float_format (fw, rd);
+  else
+    fmt = float_format (fw, rd, std::ios::fixed);
+
+  curr_real_fmt = &fmt;
+}
+
+static void
+set_format (double d, int& fw)
+{
+  curr_real_fmt = 0;
+  curr_imag_fmt = 0;
+
+  if (free_format)
+    return;
+
+  bool inf_or_nan = (xisinf (d) || xisnan (d));
+
+  bool int_only = (! inf_or_nan && D_NINT (d) == d);
+
+  double d_abs = d < 0.0 ? -d : d;
+
+  int digits = (inf_or_nan || d_abs == 0.0)
+    ? 0 : static_cast<int> (floor (log10 (d_abs) + 1.0));
+
+  set_real_format (digits, inf_or_nan, int_only, fw);
+}
+
+static inline void
+set_format (double d)
+{
+  int fw;
+  set_format (d, fw);
+}
+
+static void
+set_real_matrix_format (int x_max, int x_min, bool inf_or_nan,
+			int int_or_inf_or_nan, int& fw)
+{
+  static float_format fmt;
+
+  int prec = Voutput_precision;
+
+  int ld, rd;
+
+  if (rat_format)
+    {
+      fw = 9;
+      rd = 0;
+    }
+  else if (bank_format)
+    {
+      int digits = x_max > x_min ? x_max : x_min;
+      fw = digits <= 0 ? 4 : digits + 3;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+      rd = 2;
+    }
+  else if (hex_format)
+    {
+      fw = 2 * sizeof (double);
+      rd = 0;
+    }
+  else if (bit_format)
+    {
+      fw = 8 * sizeof (double);
+      rd = 0;
+    }
+  else if (Vfixed_point_format && ! print_g)
+    {
+      rd = prec;
+      fw = rd + 2;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+    }
+  else if (int_or_inf_or_nan)
+    {
+      int digits = x_max > x_min ? x_max : x_min;
+      fw = digits <= 0 ? 2 : digits + 1;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+      rd = fw;
+    }
+  else
+    {
+      int ld_max, rd_max;
+      if (x_max > 0)
+	{
+	  ld_max = x_max;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max++;
+	}
+      else
+	{
+	  ld_max = 1;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max = -x_max + 1;
+	}
+
+      int ld_min, rd_min;
+      if (x_min > 0)
+	{
+	  ld_min = x_min;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min++;
+	}
+      else
+	{
+	  ld_min = 1;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min = -x_min + 1;
+	}
+
+      ld = ld_max > ld_min ? ld_max : ld_min;
+      rd = rd_max > rd_min ? rd_max : rd_min;
+
+      fw = 1 + ld + 1 + rd;
+      if (inf_or_nan && fw < 4)
+	fw = 4;
+    }
+
+  if (! (rat_format || bank_format || hex_format || bit_format)
+      && (print_e
+	  || print_g
+	  || (! Vfixed_point_format && fw > Voutput_max_field_width)))
+    {
+      if (print_g)
+	fmt = float_format ();
+      else
+	{
+	  int exp_field = 4;
+	  if (x_max > 100 || x_min > 100)
+	    exp_field++;
+
+	  fw = 2 + prec + exp_field;
+	  if (inf_or_nan && fw < 4)
+	    fw = 4;
+
+	  fmt = float_format (fw, prec - 1, std::ios::scientific);
+	}
+
+      if (print_big_e)
+	fmt.uppercase ();
+    }
+  else if (! bank_format && int_or_inf_or_nan)
+    fmt = float_format (fw, rd);
+  else
+    fmt = float_format (fw, rd, std::ios::fixed);
+
+  curr_real_fmt = &fmt;
+}
+
+static void
+set_format (const Matrix& m, int& fw, double& scale)
+{
+  curr_real_fmt = 0;
+  curr_imag_fmt = 0;
+
+  if (free_format)
+    return;
+
+  bool inf_or_nan = m.any_element_is_inf_or_nan ();
+
+  bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan ();
+
+  Matrix m_abs = m.abs ();
+  double max_abs = pr_max_internal (m_abs);
+  double min_abs = pr_min_internal (m_abs);
+
+  int x_max = max_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (max_abs) + 1.0));
+
+  int x_min = min_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (min_abs) + 1.0));
+
+  scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 : std::pow (10.0, x_max - 1);
+
+  set_real_matrix_format (x_max, x_min, inf_or_nan, int_or_inf_or_nan, fw);
+}
+
+static inline void
+set_format (const Matrix& m)
+{
+  int fw;
+  double scale;
+  set_format (m, fw, scale);
+}
+
+static void
+set_complex_format (int x_max, int x_min, int r_x, bool inf_or_nan,
+		    int int_only, int& r_fw, int& i_fw)
+{
+  static float_format r_fmt;
+  static float_format i_fmt;
+
+  int prec = Voutput_precision;
+
+  int ld, rd;
+
+  if (rat_format)
+    {
+      i_fw = 0;
+      r_fw = 0;
+      rd = 0;
+    }
+  else if (bank_format)
+    {
+      int digits = r_x;
+      i_fw = 0;
+      r_fw = digits <= 0 ? 4 : digits + 3;
+      if (inf_or_nan && r_fw < 4)
+	r_fw = 4;
+      rd = 2;
+    }
+  else if (hex_format)
+    {
+      r_fw = 2 * sizeof (double);
+      i_fw = 2 * sizeof (double);
+      rd = 0;
+    }
+  else if (bit_format)
+    {
+      r_fw = 8 * sizeof (double);
+      i_fw = 8 * sizeof (double);
+      rd = 0;
+    }
+  else if (inf_or_nan || int_only)
+    {
+      int digits = x_max > x_min ? x_max : x_min;
+      i_fw = digits <= 0 ? 1 : digits;
+      r_fw = i_fw + 1;
+      if (inf_or_nan && i_fw < 3)
+	{
+	  i_fw = 3;
+	  r_fw = 4;
+	}
+      rd = r_fw;
+    }
+  else
+    {
+      int ld_max, rd_max;
+      if (x_max > 0)
+	{
+	  ld_max = x_max;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max++;
+	}
+      else
+	{
+	  ld_max = 1;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max = -x_max + 1;
+	}
+
+      int ld_min, rd_min;
+      if (x_min > 0)
+	{
+	  ld_min = x_min;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min++;
+	}
+      else
+	{
+	  ld_min = 1;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min = -x_min + 1;
+	}
+
+      ld = ld_max > ld_min ? ld_max : ld_min;
+      rd = rd_max > rd_min ? rd_max : rd_min;
+
+      i_fw = ld + 1 + rd;
+      r_fw = i_fw + 1;
+      if (inf_or_nan && i_fw < 3)
+	{
+	  i_fw = 3;
+	  r_fw = 4;
+	}
+    }
+
+  if (! (rat_format || bank_format || hex_format || bit_format)
+      && (r_fw > Voutput_max_field_width || print_e || print_g))
+    {
+      if (print_g)
+	{
+	  r_fmt = float_format ();
+	  i_fmt = float_format ();
+	}
+      else
+	{
+	  int exp_field = 4;
+	  if (x_max > 100 || x_min > 100)
+	    exp_field++;
+
+	  i_fw = prec + exp_field;
+	  r_fw = i_fw + 1;
+	  if (inf_or_nan && i_fw < 3)
+	    {
+	      i_fw = 3;
+	      r_fw = 4;
+	    }
+
+	  r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
+	  i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
+	}
+
+      if (print_big_e)
+	{
+	  r_fmt.uppercase ();
+	  i_fmt.uppercase ();
+	}
+    }
+  else if (! bank_format && (inf_or_nan || int_only))
+    {
+      r_fmt = float_format (r_fw, rd);
+      i_fmt = float_format (i_fw, rd);
+    }
+  else
+    {
+      r_fmt = float_format (r_fw, rd, std::ios::fixed);
+      i_fmt = float_format (i_fw, rd, std::ios::fixed);
+    }
+
+  curr_real_fmt = &r_fmt;
+  curr_imag_fmt = &i_fmt;
+}
+
+static void
+set_format (const Complex& c, int& r_fw, int& i_fw)
+{
+  curr_real_fmt = 0;
+  curr_imag_fmt = 0;
+
+  if (free_format)
+    return;
+
+  double rp = c.real ();
+  double ip = c.imag ();
+
+  bool inf_or_nan = (xisinf (c) || xisnan (c));
+
+  bool int_only = (D_NINT (rp) == rp && D_NINT (ip) == ip);
+
+  double r_abs = rp < 0.0 ? -rp : rp;
+  double i_abs = ip < 0.0 ? -ip : ip;
+
+  int r_x = (xisinf (rp) || xisnan (rp) || r_abs == 0.0)
+    ? 0 : static_cast<int> (floor (log10 (r_abs) + 1.0));
+
+  int i_x = (xisinf (ip) || xisnan (ip) || i_abs == 0.0)
+    ? 0 : static_cast<int> (floor (log10 (i_abs) + 1.0));
+
+  int x_max, x_min;
+
+  if (r_x > i_x)
+    {
+      x_max = r_x;
+      x_min = i_x;
+    }
+  else
+    {
+      x_max = i_x;
+      x_min = r_x;
+    }
+
+  set_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, r_fw, i_fw);
+}
+
+static inline void
+set_format (const Complex& c)
+{
+  int r_fw, i_fw;
+  set_format (c, r_fw, i_fw);
+}
+
+static void
+set_complex_matrix_format (int x_max, int x_min, int r_x_max,
+			   int r_x_min, bool inf_or_nan,
+			   int int_or_inf_or_nan, int& r_fw, int& i_fw)
+{
+  static float_format r_fmt;
+  static float_format i_fmt;
+
+  int prec = Voutput_precision;
+
+  int ld, rd;
+
+  if (rat_format)
+    {
+      i_fw = 9;
+      r_fw = 9;
+      rd = 0;
+    }
+  else if (bank_format)
+    {
+      int digits = r_x_max > r_x_min ? r_x_max : r_x_min;
+      i_fw = 0;
+      r_fw = digits <= 0 ? 4 : digits + 3;
+      if (inf_or_nan && r_fw < 4)
+	r_fw = 4;
+      rd = 2;
+    }
+  else if (hex_format)
+    {
+      r_fw = 2 * sizeof (double);
+      i_fw = 2 * sizeof (double);
+      rd = 0;
+    }
+  else if (bit_format)
+    {
+      r_fw = 8 * sizeof (double);
+      i_fw = 8 * sizeof (double);
+      rd = 0;
+    }
+  else if (Vfixed_point_format && ! print_g)
+    {
+      rd = prec;
+      i_fw = rd + 1;
+      r_fw = i_fw + 1;
+      if (inf_or_nan && i_fw < 3)
+	{
+	  i_fw = 3;
+	  r_fw = 4;
+	}
+    }
+  else if (int_or_inf_or_nan)
+    {
+      int digits = x_max > x_min ? x_max : x_min;
+      i_fw = digits <= 0 ? 1 : digits;
+      r_fw = i_fw + 1;
+      if (inf_or_nan && i_fw < 3)
+	{
+	  i_fw = 3;
+	  r_fw = 4;
+	}
+      rd = r_fw;
+    }
+  else
+    {
+      int ld_max, rd_max;
+      if (x_max > 0)
+	{
+	  ld_max = x_max;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max++;
+	}
+      else
+	{
+	  ld_max = 1;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max = -x_max + 1;
+	}
+
+      int ld_min, rd_min;
+      if (x_min > 0)
+	{
+	  ld_min = x_min;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min++;
+	}
+      else
+	{
+	  ld_min = 1;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min = -x_min + 1;
+	}
+
+      ld = ld_max > ld_min ? ld_max : ld_min;
+      rd = rd_max > rd_min ? rd_max : rd_min;
+
+      i_fw = ld + 1 + rd;
+      r_fw = i_fw + 1;
+      if (inf_or_nan && i_fw < 3)
+	{
+	  i_fw = 3;
+	  r_fw = 4;
+	}
+    }
+
+  if (! (rat_format || bank_format || hex_format || bit_format)
+      && (print_e
+	  || print_g
+	  || (! Vfixed_point_format && r_fw > Voutput_max_field_width)))
+    {
+      if (print_g)
+	{
+	  r_fmt = float_format ();
+	  i_fmt = float_format ();
+	}
+      else
+	{
+	  int exp_field = 4;
+	  if (x_max > 100 || x_min > 100)
+	    exp_field++;
+
+	  i_fw = prec + exp_field;
+	  r_fw = i_fw + 1;
+	  if (inf_or_nan && i_fw < 3)
+	    {
+	      i_fw = 3;
+	      r_fw = 4;
+	    }
+
+	  r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
+	  i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
+	}
+
+      if (print_big_e)
+	{
+	  r_fmt.uppercase ();
+	  i_fmt.uppercase ();
+	}
+    }
+  else if (! bank_format && int_or_inf_or_nan)
+    {
+      r_fmt = float_format (r_fw, rd);
+      i_fmt = float_format (i_fw, rd);
+    }
+  else
+    {
+      r_fmt = float_format (r_fw, rd, std::ios::fixed);
+      i_fmt = float_format (i_fw, rd, std::ios::fixed);
+    }
+
+  curr_real_fmt = &r_fmt;
+  curr_imag_fmt = &i_fmt;
+}
+
+static void
+set_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale)
+{
+  curr_real_fmt = 0;
+  curr_imag_fmt = 0;
+
+  if (free_format)
+    return;
+
+  Matrix rp = real (cm);
+  Matrix ip = imag (cm);
+
+  bool inf_or_nan = cm.any_element_is_inf_or_nan ();
+
+  bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan ()
+			    && ip.all_elements_are_int_or_inf_or_nan ());
+
+  Matrix r_m_abs = rp.abs ();
+  double r_max_abs = pr_max_internal (r_m_abs);
+  double r_min_abs = pr_min_internal (r_m_abs);
+
+  Matrix i_m_abs = ip.abs ();
+  double i_max_abs = pr_max_internal (i_m_abs);
+  double i_min_abs = pr_min_internal (i_m_abs);
+
+  int r_x_max = r_max_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (r_max_abs) + 1.0));
+
+  int r_x_min = r_min_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (r_min_abs) + 1.0));
+
+  int i_x_max = i_max_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (i_max_abs) + 1.0));
+
+  int i_x_min = i_min_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (i_min_abs) + 1.0));
+
+  int x_max = r_x_max > i_x_max ? r_x_max : i_x_max;
+  int x_min = r_x_min > i_x_min ? r_x_min : i_x_min;
+
+  scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 : std::pow (10.0, x_max - 1);
+
+  set_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, inf_or_nan,
+			     int_or_inf_or_nan, r_fw, i_fw);
+}
+
+static inline void
+set_format (const ComplexMatrix& cm)
+{
+  int r_fw, i_fw;
+  double scale;
+  set_format (cm, r_fw, i_fw, scale);
+}
+
+static void
+set_range_format (int x_max, int x_min, int all_ints, int& fw)
+{
+  static float_format fmt;
+
+  int prec = Voutput_precision;
+
+  int ld, rd;
+
+  if (rat_format)
+    {
+      fw = 9;
+      rd = 0;
+    }
+  else if (bank_format)
+    {
+      int digits = x_max > x_min ? x_max : x_min;
+      fw = digits < 0 ? 5 : digits + 4;
+      rd = 2;
+    }
+  else if (hex_format)
+    {
+      fw = 2 * sizeof (double);
+      rd = 0;
+    }
+  else if (bit_format)
+    {
+      fw = 8 * sizeof (double);
+      rd = 0;
+    }
+  else if (all_ints)
+    {
+      int digits = x_max > x_min ? x_max : x_min;
+      fw = digits + 1;
+      rd = fw;
+    }
+  else if (Vfixed_point_format && ! print_g)
+    {
+      rd = prec;
+      fw = rd + 3;
+    }
+  else
+    {
+      int ld_max, rd_max;
+      if (x_max > 0)
+	{
+	  ld_max = x_max;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max++;
+	}
+      else
+	{
+	  ld_max = 1;
+	  rd_max = prec > x_max ? prec - x_max : prec;
+	  x_max = -x_max + 1;
+	}
+
+      int ld_min, rd_min;
+      if (x_min > 0)
+	{
+	  ld_min = x_min;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min++;
+	}
+      else
+	{
+	  ld_min = 1;
+	  rd_min = prec > x_min ? prec - x_min : prec;
+	  x_min = -x_min + 1;
+	}
+
+      ld = ld_max > ld_min ? ld_max : ld_min;
+      rd = rd_max > rd_min ? rd_max : rd_min;
+
+      fw = ld + rd + 3;
+    }
+
+  if (! (rat_format || bank_format || hex_format || bit_format)
+      && (print_e
+	  || print_g
+	  || (! Vfixed_point_format && fw > Voutput_max_field_width)))
+    {
+      if (print_g)
+	fmt = float_format ();
+      else
+	{
+	  int exp_field = 4;
+	  if (x_max > 100 || x_min > 100)
+	    exp_field++;
+
+	  fw = 3 + prec + exp_field;
+
+	  fmt = float_format (fw, prec - 1, std::ios::scientific);
+	}
+
+      if (print_big_e)
+	fmt.uppercase ();
+    }
+  else if (! bank_format && all_ints)
+    fmt = float_format (fw, rd);
+  else
+    fmt = float_format (fw, rd, std::ios::fixed);
+
+  curr_real_fmt = &fmt;
+}
+
+static void
+set_format (const Range& r, int& fw, double& scale)
+{
+  curr_real_fmt = 0;
+  curr_imag_fmt = 0;
+
+  if (free_format)
+    return;
+
+  double r_min = r.base ();
+  double r_max = r.limit ();
+
+  if (r_max < r_min)
+    {
+      double tmp = r_max;
+      r_max = r_min;
+      r_min = tmp;
+    }
+
+  bool all_ints = r.all_elements_are_ints ();
+
+  double max_abs = r_max < 0.0 ? -r_max : r_max;
+  double min_abs = r_min < 0.0 ? -r_min : r_min;
+
+  int x_max = max_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (max_abs) + 1.0));
+
+  int x_min = min_abs == 0.0
+    ? 0 : static_cast<int> (floor (log10 (min_abs) + 1.0));
+
+  scale = (x_max == 0 || all_ints) ? 1.0 : std::pow (10.0, x_max - 1);
+
+  set_range_format (x_max, x_min, all_ints, fw);
+}
+
+static inline void
+set_format (const Range& r)
+{
+  int fw;
+  double scale;
+  set_format (r, fw, scale);
+}
+
+union equiv
+{
+  double d;
+  unsigned char i[sizeof (double)];
+};
+
+#define PRINT_CHAR_BITS(os, c) \
+  do \
+    { \
+      unsigned char ctmp = c; \
+      char stmp[9]; \
+      stmp[0] = (ctmp & 0x80) ? '1' : '0'; \
+      stmp[1] = (ctmp & 0x40) ? '1' : '0'; \
+      stmp[2] = (ctmp & 0x20) ? '1' : '0'; \
+      stmp[3] = (ctmp & 0x10) ? '1' : '0'; \
+      stmp[4] = (ctmp & 0x08) ? '1' : '0'; \
+      stmp[5] = (ctmp & 0x04) ? '1' : '0'; \
+      stmp[6] = (ctmp & 0x02) ? '1' : '0'; \
+      stmp[7] = (ctmp & 0x01) ? '1' : '0'; \
+      stmp[8] = '\0'; \
+      os << stmp; \
+    } \
+  while (0)
+
+#define PRINT_CHAR_BITS_SWAPPED(os, c) \
+  do \
+    { \
+      unsigned char ctmp = c; \
+      char stmp[9]; \
+      stmp[0] = (ctmp & 0x01) ? '1' : '0'; \
+      stmp[1] = (ctmp & 0x02) ? '1' : '0'; \
+      stmp[2] = (ctmp & 0x04) ? '1' : '0'; \
+      stmp[3] = (ctmp & 0x08) ? '1' : '0'; \
+      stmp[4] = (ctmp & 0x10) ? '1' : '0'; \
+      stmp[5] = (ctmp & 0x20) ? '1' : '0'; \
+      stmp[6] = (ctmp & 0x40) ? '1' : '0'; \
+      stmp[7] = (ctmp & 0x80) ? '1' : '0'; \
+      stmp[8] = '\0'; \
+      os << stmp; \
+    } \
+  while (0)
+
+static void
+pr_any_float (const float_format *fmt, std::ostream& os, double d, int fw = 0)
+{
+  if (fmt)
+    {
+      // Unless explicitly asked for, always print in big-endian
+      // format for hex and bit formats.
+      //
+      //   {bit,hex}_format == 1: print big-endian
+      //   {bit,hex}_format == 2: print native
+
+      if (hex_format)
+	{
+	  equiv tmp;
+	  tmp.d = d;
+
+	  // Unless explicitly asked for, always print in big-endian
+	  // format.
+
+	  // FIXME -- is it correct to swap bytes for VAX
+	  // formats and not for Cray?
+
+	  // FIXME -- will bad things happen if we are
+	  // interrupted before resetting the format flags and fill
+	  // character?
+
+	  oct_mach_info::float_format flt_fmt =
+	    oct_mach_info::native_float_format ();
+
+	  char ofill = os.fill ('0');
+
+	  std::ios::fmtflags oflags
+	    = os.flags (std::ios::right | std::ios::hex);
+
+	  if (hex_format > 1
+	      || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
+	      || flt_fmt == oct_mach_info::flt_fmt_cray
+	      || flt_fmt == oct_mach_info::flt_fmt_unknown)
+	    {
+	      for (size_t i = 0; i < sizeof (double); i++)
+		os << std::setw (2) << static_cast<int> (tmp.i[i]);
+	    }
+	  else
+	    {
+	      for (int i = sizeof (double) - 1; i >= 0; i--)
+		os << std::setw (2) << static_cast<int> (tmp.i[i]);
+	    }
+
+	  os.fill (ofill);
+	  os.setf (oflags);	  
+	}
+      else if (bit_format)
+	{
+	  equiv tmp;
+	  tmp.d = d;
+
+	  // FIXME -- is it correct to swap bytes for VAX
+	  // formats and not for Cray?
+
+	  oct_mach_info::float_format flt_fmt =
+	    oct_mach_info::native_float_format ();
+
+	  if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
+	      || flt_fmt == oct_mach_info::flt_fmt_cray
+	      || flt_fmt == oct_mach_info::flt_fmt_unknown)
+	    {
+	      for (size_t i = 0; i < sizeof (double); i++)
+		PRINT_CHAR_BITS (os, tmp.i[i]);
+	    }
+	  else
+	    {
+	      if (bit_format > 1)
+		{
+		  for (size_t i = 0; i < sizeof (double); i++)
+		    PRINT_CHAR_BITS_SWAPPED (os, tmp.i[i]);
+		}
+	      else
+		{
+		  for (int i = sizeof (double) - 1; i >= 0; i--)
+		    PRINT_CHAR_BITS (os, tmp.i[i]);
+		}
+	    }
+	}
+      else if (octave_is_NA (d))
+	{
+	  if (fw > 0)
+	    os << std::setw (fw) << "NA";
+	  else
+	    os << "NA";
+	}
+      else if (rat_format)
+	os << pr_rational_float (*fmt, d);
+      else if (xisinf (d))
+	{
+	  const char *s;
+	  if (d < 0.0)
+	    s = "-Inf";
+	  else
+	    s = "Inf";
+
+	  if (fw > 0)
+	    os << std::setw (fw) << s;
+	  else
+	    os << s;
+	}
+      else if (xisnan (d))
+	{
+	  if (fw > 0)
+	    os << std::setw (fw) << "NaN";
+	  else
+	    os << "NaN";
+	}
+      else
+	os << pr_formatted_float (*fmt, d);
+    }
+  else
+    os << d;
+}
+
+static inline void
+pr_float (std::ostream& os, double d, int fw = 0, double scale = 1.0)
+{
+  if (Vfixed_point_format && ! print_g && scale != 1.0)
+    d /= scale;
+
+  pr_any_float (curr_real_fmt, os, d, fw);
+}
+
+static inline void
+pr_imag_float (std::ostream& os, double d, int fw = 0)
+{
+  pr_any_float (curr_imag_fmt, os, d, fw);
+}
+
+static void
+pr_complex (std::ostream& os, const Complex& c, int r_fw = 0,
+	    int i_fw = 0, double scale = 1.0)
+{
+  Complex tmp
+    = (Vfixed_point_format && ! print_g && scale != 1.0) ? c / scale : c;
+
+  double r = tmp.real ();
+
+  pr_float (os, r, r_fw);
+
+  if (! bank_format)
+    {
+      double i = tmp.imag ();
+      if (! (hex_format || bit_format) && lo_ieee_signbit (i))
+	{
+	  os << " - ";
+	  i = -i;
+	  pr_imag_float (os, i, i_fw);
+	}
+      else
+	{
+	  if (hex_format || bit_format)
+	    os << "  ";
+	  else
+	    os << " + ";
+
+	  pr_imag_float (os, i, i_fw);
+	}
+      os << "i";
+    }
+}
+
+static void
+print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc, bool pr_as_read_syntax)
+{
+  assert (nr == 0 || nc == 0);
+
+  if (pr_as_read_syntax)
+    {
+      if (nr == 0 && nc == 0)
+	os << "[]";
+      else
+	os << "zeros (" << nr << ", " << nc << ")";
+    }
+  else
+    {
+      os << "[]";
+
+      if (Vprint_empty_dimensions)
+	os << "(" << nr << "x" << nc << ")";
+    }
+}
+
+static void
+print_empty_nd_array (std::ostream& os, const dim_vector& dims,
+		      bool pr_as_read_syntax)
+{
+  assert (dims.any_zero ());
+
+  if (pr_as_read_syntax)
+    os << "zeros (" << dims.str (',') << ")";
+  else
+    {
+      os << "[]";
+
+      if (Vprint_empty_dimensions)
+	os << "(" << dims.str () << ")";
+    }
+}
+
+static void
+pr_scale_header (std::ostream& os, double scale)
+{
+  if (Vfixed_point_format && ! print_g && scale != 1.0)
+    {
+      os << "  "
+	 << std::setw (8) << std::setprecision (1)
+	 << std::setiosflags (std::ios::scientific|std::ios::left)
+	 << scale
+	 << std::resetiosflags (std::ios::scientific|std::ios::left)
+	 << " *\n";
+
+      if (! compact_format)
+	os << "\n";
+    }
+}
+
+static void
+pr_col_num_header (std::ostream& os, octave_idx_type total_width, int max_width,
+		   octave_idx_type lim, octave_idx_type col, int extra_indent)
+{
+  if (total_width > max_width && Vsplit_long_rows)
+    {
+      if (col != 0)
+	{
+	  if (compact_format)
+	    os << "\n";
+	  else
+	    os << "\n\n";
+	}
+
+      octave_idx_type num_cols = lim - col;
+
+      os << std::setw (extra_indent) << "";
+
+      if (num_cols == 1)
+	os << " Column " << col + 1 << ":\n";
+      else if (num_cols == 2)
+	os << " Columns " << col + 1 << " and " << lim << ":\n";
+      else
+	os << " Columns " << col + 1 << " through " << lim << ":\n";
+
+      if (! compact_format)
+	os << "\n";
+    }
+}
+
+template <class T>
+/* static */ inline void
+pr_plus_format (std::ostream& os, const T& val)
+{
+  if (val > T (0))
+    os << plus_format_chars[0];
+  else if (val < T (0))
+    os << plus_format_chars[1];
+  else
+    os << plus_format_chars[2];
+}
+
+void
+octave_print_internal (std::ostream& os, double d,
+		       bool /* pr_as_read_syntax */)
+{
+  if (plus_format)
+    {
+      pr_plus_format (os, d);
+    }
+  else
+    {
+      set_format (d);
+      if (free_format)
+	os << d;
+      else
+	pr_float (os, d);
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const Matrix& m,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  if (nr == 0 || nc == 0)
+    print_empty_matrix (os, nr, nc, pr_as_read_syntax);
+  else if (plus_format && ! pr_as_read_syntax)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      pr_plus_format (os, m(i,j));
+	    }
+
+	  if (i < nr - 1)
+	    os << "\n";
+	}
+    }
+  else
+    {
+      int fw;
+      double scale = 1.0;
+      set_format (m, fw, scale);
+      int column_width = fw + 2;
+      octave_idx_type total_width = nc * column_width;
+      octave_idx_type max_width = command_editor::terminal_cols ();
+
+      if (pr_as_read_syntax)
+	max_width -= 4;
+      else
+	max_width -= extra_indent;
+
+      if (max_width < 0)
+	max_width = 0;
+
+      if (free_format)
+	{
+	  if (pr_as_read_syntax)
+	    os << "[\n";
+
+	  os << m;
+
+	  if (pr_as_read_syntax)
+	    os << "]";
+
+	  return;
+	}
+
+      octave_idx_type inc = nc;
+      if (total_width > max_width && Vsplit_long_rows)
+	{
+	  inc = max_width / column_width;
+	  if (inc == 0)
+	    inc++;
+	}
+
+      if (pr_as_read_syntax)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      octave_idx_type col = 0;
+	      while (col < nc)
+		{
+		  octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      if (i == 0 && j == 0)
+			os << "[ ";
+		      else
+			{
+			  if (j > col && j < lim)
+			    os << ", ";
+			  else
+			    os << "  ";
+			}
+
+		      pr_float (os, m(i,j));
+		    }
+
+		  col += inc;
+
+		  if (col >= nc)
+		    {
+		      if (i == nr - 1)
+			os << " ]";
+		      else
+			os << ";\n";
+		    }
+		  else
+		    os << " ...\n";
+		}
+	    }
+	}
+      else
+	{
+	  pr_scale_header (os, scale);
+
+	  for (octave_idx_type col = 0; col < nc; col += inc)
+	    {
+	      octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+	      pr_col_num_header (os, total_width, max_width, lim, col,
+				 extra_indent);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  os << std::setw (extra_indent) << "";
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      os << "  ";
+
+		      pr_float (os, m(i,j), fw, scale);
+		    }
+
+		  if (i < nr - 1)
+		    os << "\n";
+		}
+	    }
+	}
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const DiagMatrix& m,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  if (nr == 0 || nc == 0)
+    print_empty_matrix (os, nr, nc, pr_as_read_syntax);
+  else if (plus_format && ! pr_as_read_syntax)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      pr_plus_format (os, m(i,j));
+	    }
+
+	  if (i < nr - 1)
+	    os << "\n";
+	}
+    }
+  else
+    {
+      int fw;
+      double scale = 1.0;
+      set_format (Matrix (m.diag ()), fw, scale);
+      int column_width = fw + 2;
+      octave_idx_type total_width = nc * column_width;
+      octave_idx_type max_width = command_editor::terminal_cols ();
+
+      if (pr_as_read_syntax)
+	max_width -= 4;
+      else
+	max_width -= extra_indent;
+
+      if (max_width < 0)
+	max_width = 0;
+
+      if (free_format)
+	{
+	  if (pr_as_read_syntax)
+	    os << "[\n";
+
+	  os << Matrix (m);
+
+	  if (pr_as_read_syntax)
+	    os << "]";
+
+	  return;
+	}
+
+      octave_idx_type inc = nc;
+      if (total_width > max_width && Vsplit_long_rows)
+	{
+	  inc = max_width / column_width;
+	  if (inc == 0)
+	    inc++;
+	}
+
+      if (pr_as_read_syntax)
+	{
+          os << "diag (";
+
+          octave_idx_type col = 0;
+          while (col < nc)
+            {
+              octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+              for (octave_idx_type j = col; j < lim; j++)
+                {
+                  OCTAVE_QUIT;
+
+                  if (j == 0)
+                    os << "[ ";
+                  else
+                    {
+                      if (j > col && j < lim)
+                        os << ", ";
+                      else
+                        os << "  ";
+                    }
+
+                  pr_float (os, m(j,j));
+                }
+
+              col += inc;
+
+              if (col >= nc)
+                  os << " ]";
+              else
+                os << " ...\n";
+            }
+          os << ")";
+	}
+      else
+	{
+          os << "Diagonal Matrix\n\n";
+	  pr_scale_header (os, scale);
+
+          // kluge. Get the true width of a number.
+          int zero_fw;
+
+            { 
+              std::ostringstream tmp_oss;
+              pr_float (tmp_oss, 0.0, fw, scale);
+              zero_fw = tmp_oss.str ().length ();
+            }
+
+	  for (octave_idx_type col = 0; col < nc; col += inc)
+	    {
+	      octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+	      pr_col_num_header (os, total_width, max_width, lim, col,
+				 extra_indent);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  os << std::setw (extra_indent) << "";
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      os << "  ";
+
+                      if (i == j)
+                        pr_float (os, m(i,j), fw, scale);
+                      else
+                        os << std::setw (zero_fw) << '0';
+
+		    }
+
+		  if (i < nr - 1)
+		    os << "\n";
+		}
+	    }
+	}
+    }
+}
+#define PRINT_ND_ARRAY(os, nda, NDA_T, ELT_T, MAT_T) \
+  do \
+    { \
+      if (nda.is_empty ()) \
+        print_empty_nd_array (os, nda.dims (), pr_as_read_syntax); \
+      else \
+        { \
+ \
+          int ndims = nda.ndims (); \
+ \
+          dim_vector dims = nda.dims (); \
+ \
+          Array<octave_idx_type> ra_idx (ndims, 0); \
+ \
+          octave_idx_type m = 1; \
+ \
+          for (int i = 2; i < ndims; i++) \
+            m *= dims(i); \
+ \
+          octave_idx_type nr = dims(0); \
+          octave_idx_type nc = dims(1); \
+ \
+          for (octave_idx_type i = 0; i < m; i++) \
+            { \
+	      OCTAVE_QUIT; \
+ \
+              std::string nm = "ans"; \
+ \
+              if (m > 1) \
+                { \
+                  nm += "(:,:,"; \
+ \
+		  std::ostringstream buf; \
+ \
+                  for (int k = 2; k < ndims; k++) \
+                    { \
+                      buf << ra_idx(k) + 1; \
+ \
+                      if (k < ndims - 1) \
+                        buf << ","; \
+                      else \
+                        buf << ")"; \
+                    } \
+ \
+                  nm += buf.str (); \
+                } \
+ \
+              Array<idx_vector> idx (ndims); \
+ \
+              idx(0) = idx_vector (':'); \
+              idx(1) = idx_vector (':'); \
+ \
+              for (int k = 2; k < ndims; k++) \
+                idx(k) = idx_vector (ra_idx(k)); \
+ \
+              octave_value page \
+                = MAT_T (Array2<ELT_T> (nda.index (idx), nr, nc)); \
+ \
+              page.print_with_name (os, nm); \
+ \
+              if (i < m) \
+                NDA_T::increment_index (ra_idx, dims, 2); \
+            } \
+        } \
+    } \
+  while (0)
+
+void
+octave_print_internal (std::ostream& os, const NDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent);
+      break;
+
+    default:
+      PRINT_ND_ARRAY (os, nda, NDArray, double, Matrix);
+      break;
+    }
+}
+
+template <>
+/* static */ inline void
+pr_plus_format<> (std::ostream& os, const Complex& c)
+{
+  double rp = c.real ();
+  double ip = c.imag ();
+
+  if (rp == 0.0)
+    {
+      if (ip == 0.0)
+	os << " ";
+      else
+	os << "i";
+    }
+  else if (ip == 0.0)
+    pr_plus_format (os, rp);
+  else
+    os << "c";
+}
+
+void
+octave_print_internal (std::ostream& os, const Complex& c,
+		       bool /* pr_as_read_syntax */)
+{
+  if (plus_format)
+    {
+      pr_plus_format (os, c);
+    }
+  else
+    {
+      set_format (c);
+      if (free_format)
+	os << c;
+      else
+	pr_complex (os, c);
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const ComplexMatrix& cm,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_idx_type nr = cm.rows ();
+  octave_idx_type nc = cm.columns ();
+
+ if (nr == 0 || nc == 0)
+    print_empty_matrix (os, nr, nc, pr_as_read_syntax);
+  else if (plus_format && ! pr_as_read_syntax)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      pr_plus_format (os, cm(i,j));
+	    }
+
+	  if (i < nr - 1)
+	    os << "\n";
+	}
+    }
+  else
+    {
+      int r_fw, i_fw;
+      double scale = 1.0;
+      set_format (cm, r_fw, i_fw, scale);
+      int column_width = i_fw + r_fw;
+      column_width += (rat_format || bank_format || hex_format 
+		       || bit_format) ? 2 : 7;
+      octave_idx_type total_width = nc * column_width;
+      octave_idx_type max_width = command_editor::terminal_cols ();
+
+      if (pr_as_read_syntax)
+	max_width -= 4;
+      else
+	max_width -= extra_indent;
+
+      if (max_width < 0)
+	max_width = 0;
+
+      if (free_format)
+	{
+	  if (pr_as_read_syntax)
+	    os << "[\n";
+
+	  os << cm;
+
+	  if (pr_as_read_syntax)
+	    os << "]";
+
+	  return;
+	}
+
+      octave_idx_type inc = nc;
+      if (total_width > max_width && Vsplit_long_rows)
+	{
+	  inc = max_width / column_width;
+	  if (inc == 0)
+	    inc++;
+	}
+
+      if (pr_as_read_syntax)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      octave_idx_type col = 0;
+	      while (col < nc)
+		{
+		  octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      if (i == 0 && j == 0)
+			os << "[ ";
+		      else
+			{
+			  if (j > col && j < lim)
+			    os << ", ";
+			  else
+			    os << "  ";
+			}
+
+		      pr_complex (os, cm(i,j));
+		    }
+
+		  col += inc;
+
+		  if (col >= nc)
+		    {
+		      if (i == nr - 1)
+			os << " ]";
+		      else
+			os << ";\n";
+		    }
+		  else
+		    os << " ...\n";
+		}
+	    }
+	}
+      else
+	{
+	  pr_scale_header (os, scale);
+
+	  for (octave_idx_type col = 0; col < nc; col += inc)
+	    {
+	      octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+	      pr_col_num_header (os, total_width, max_width, lim, col,
+				 extra_indent);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  os << std::setw (extra_indent) << "";
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      os << "  ";
+
+		      pr_complex (os, cm(i,j), r_fw, i_fw, scale);
+		    }
+
+		  if (i < nr - 1) 
+		    os << "\n";
+		}
+	    }
+	}
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const ComplexDiagMatrix& cm,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_idx_type nr = cm.rows ();
+  octave_idx_type nc = cm.columns ();
+
+ if (nr == 0 || nc == 0)
+    print_empty_matrix (os, nr, nc, pr_as_read_syntax);
+  else if (plus_format && ! pr_as_read_syntax)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      pr_plus_format (os, cm(i,j));
+	    }
+
+	  if (i < nr - 1)
+	    os << "\n";
+	}
+    }
+  else
+    {
+      int r_fw, i_fw;
+      double scale = 1.0;
+      set_format (ComplexMatrix (cm.diag ()), r_fw, i_fw, scale);
+      int column_width = i_fw + r_fw;
+      column_width += (rat_format || bank_format || hex_format 
+		       || bit_format) ? 2 : 7;
+      octave_idx_type total_width = nc * column_width;
+      octave_idx_type max_width = command_editor::terminal_cols ();
+
+      if (pr_as_read_syntax)
+	max_width -= 4;
+      else
+	max_width -= extra_indent;
+
+      if (max_width < 0)
+	max_width = 0;
+
+      if (free_format)
+	{
+	  if (pr_as_read_syntax)
+	    os << "[\n";
+
+	  os << ComplexMatrix (cm);
+
+	  if (pr_as_read_syntax)
+	    os << "]";
+
+	  return;
+	}
+
+      octave_idx_type inc = nc;
+      if (total_width > max_width && Vsplit_long_rows)
+	{
+	  inc = max_width / column_width;
+	  if (inc == 0)
+	    inc++;
+	}
+
+      if (pr_as_read_syntax)
+	{
+          os << "diag (";
+
+          octave_idx_type col = 0;
+          while (col < nc)
+            {
+              octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+              for (octave_idx_type j = col; j < lim; j++)
+                {
+                  OCTAVE_QUIT;
+
+                  if (j == 0)
+                    os << "[ ";
+                  else
+                    {
+                      if (j > col && j < lim)
+                        os << ", ";
+                      else
+                        os << "  ";
+                    }
+
+                  pr_complex (os, cm(j,j));
+                }
+
+              col += inc;
+
+              if (col >= nc)
+                  os << " ]";
+              else
+                os << " ...\n";
+            }
+          os << ")";
+	}
+      else
+	{
+          os << "Diagonal Matrix\n\n";
+	  pr_scale_header (os, scale);
+
+          // kluge. Get the true width of a number.
+          int zero_fw;
+
+            { 
+              std::ostringstream tmp_oss;
+              pr_complex (tmp_oss, Complex (0.0), r_fw, i_fw, scale);
+              zero_fw = tmp_oss.str ().length ();
+            }
+
+	  for (octave_idx_type col = 0; col < nc; col += inc)
+	    {
+	      octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+	      pr_col_num_header (os, total_width, max_width, lim, col,
+				 extra_indent);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  os << std::setw (extra_indent) << "";
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      os << "  ";
+
+                      if (i == j)
+                        pr_complex (os, cm(i,j), r_fw, i_fw, scale);
+                      else
+                        os << std::setw (zero_fw) << '0';
+		    }
+
+		  if (i < nr - 1) 
+		    os << "\n";
+		}
+	    }
+	}
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const PermMatrix& m,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_idx_type nr = m.rows ();
+  octave_idx_type nc = m.columns ();
+
+  if (nr == 0 || nc == 0)
+    print_empty_matrix (os, nr, nc, pr_as_read_syntax);
+  else if (plus_format && ! pr_as_read_syntax)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    {
+	      OCTAVE_QUIT;
+
+	      pr_plus_format (os, m(i,j));
+	    }
+
+	  if (i < nr - 1)
+	    os << "\n";
+	}
+    }
+  else
+    {
+      int fw = 2;
+      int column_width = fw + 2;
+      octave_idx_type total_width = nc * column_width;
+      octave_idx_type max_width = command_editor::terminal_cols ();
+
+      if (pr_as_read_syntax)
+	max_width -= 4;
+      else
+	max_width -= extra_indent;
+
+      if (max_width < 0)
+	max_width = 0;
+
+      if (free_format)
+	{
+	  if (pr_as_read_syntax)
+	    os << "[\n";
+
+	  os << Matrix (m);
+
+	  if (pr_as_read_syntax)
+	    os << "]";
+
+	  return;
+	}
+
+      octave_idx_type inc = nc;
+      if (total_width > max_width && Vsplit_long_rows)
+	{
+	  inc = max_width / column_width;
+	  if (inc == 0)
+	    inc++;
+	}
+
+      if (pr_as_read_syntax)
+        {
+          Array<octave_idx_type> pvec = m.pvec ();
+          bool colp = m.is_col_perm ();
+
+          os << "eye (";
+          if (colp) os << ":, ";
+
+          octave_idx_type col = 0;
+          while (col < nc)
+            {
+              octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+              for (octave_idx_type j = col; j < lim; j++)
+                {
+                  OCTAVE_QUIT;
+
+                  if (j == 0)
+                    os << "[ ";
+                  else
+                    {
+                      if (j > col && j < lim)
+                        os << ", ";
+                      else
+                        os << "  ";
+                    }
+
+                  os << pvec (j);
+                }
+
+              col += inc;
+
+              if (col >= nc)
+                  os << " ]";
+              else
+                os << " ...\n";
+            }
+          if (! colp) os << ", :";
+          os << ")";
+	}
+      else
+	{
+          os << "Permutation Matrix\n\n";
+
+	  for (octave_idx_type col = 0; col < nc; col += inc)
+	    {
+	      octave_idx_type lim = col + inc < nc ? col + inc : nc;
+
+	      pr_col_num_header (os, total_width, max_width, lim, col,
+				 extra_indent);
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  os << std::setw (extra_indent) << "";
+
+		  for (octave_idx_type j = col; j < lim; j++)
+		    {
+		      OCTAVE_QUIT;
+
+		      os << "  ";
+
+                      os << std::setw (fw) << m(i,j);
+		    }
+
+		  if (i < nr - 1)
+		    os << "\n";
+		}
+	    }
+	}
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent);
+      break;
+
+    default:
+      PRINT_ND_ARRAY (os, nda, ComplexNDArray, Complex, ComplexMatrix);
+      break;
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, bool d, bool pr_as_read_syntax)
+{ 
+  octave_print_internal (os, double (d), pr_as_read_syntax); 
+}
+
+// FIXME -- write single precision versions of the printing functions.
+
+void
+octave_print_internal (std::ostream& os, float d, bool pr_as_read_syntax)
+{ 
+  octave_print_internal (os, double (d), pr_as_read_syntax); 
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatMatrix& m,
+		       bool pr_as_read_syntax, int extra_indent)
+{ 
+  octave_print_internal (os, Matrix (m), pr_as_read_syntax, extra_indent); 
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatDiagMatrix& m,
+		       bool pr_as_read_syntax, int extra_indent)
+{ 
+  octave_print_internal (os, DiagMatrix (m), pr_as_read_syntax, extra_indent); 
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatNDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_print_internal (os, NDArray (nda), pr_as_read_syntax, extra_indent); 
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatComplex& c,
+		       bool pr_as_read_syntax)
+{
+  octave_print_internal (os, Complex (c), pr_as_read_syntax); 
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatComplexMatrix& cm,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_print_internal (os, ComplexMatrix (cm), pr_as_read_syntax, extra_indent);
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatComplexDiagMatrix& cm,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_print_internal (os, ComplexDiagMatrix (cm), pr_as_read_syntax, extra_indent);
+}
+
+void
+octave_print_internal (std::ostream& os, const FloatComplexNDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  octave_print_internal (os, ComplexNDArray (nda), pr_as_read_syntax, extra_indent);
+}
+
+void
+octave_print_internal (std::ostream& os, const Range& r,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  double base = r.base ();
+  double increment = r.inc ();
+  double limit = r.limit ();
+  octave_idx_type num_elem = r.nelem ();
+
+  if (plus_format && ! pr_as_read_syntax)
+    {
+      for (octave_idx_type i = 0; i < num_elem; i++)
+	{
+	  OCTAVE_QUIT;
+
+	  double val = base + i * increment;
+
+	  pr_plus_format (os, val);
+	}
+    }
+  else
+    {
+      int fw;
+      double scale = 1.0;
+      set_format (r, fw, scale);
+
+      if (pr_as_read_syntax)
+	{
+	  if (free_format)
+	    {
+	      os << base << " : ";
+	      if (increment != 1.0)
+		os << increment << " : ";
+	      os << limit;
+	    }
+	  else
+	    {
+	      pr_float (os, base, fw);
+	      os << " : ";
+	      if (increment != 1.0)
+		{
+		  pr_float (os, increment, fw);
+		  os << " : ";
+		}
+	      pr_float (os, limit, fw);
+	    }
+	}
+      else
+	{
+	  int column_width = fw + 2;
+	  octave_idx_type total_width = num_elem * column_width;
+	  octave_idx_type max_width = command_editor::terminal_cols ();
+
+	  if (free_format)
+	    {
+	      os << r;
+	      return;
+	    }
+
+	  octave_idx_type inc = num_elem;
+	  if (total_width > max_width && Vsplit_long_rows)
+	    {
+	      inc = max_width / column_width;
+	      if (inc == 0)
+		inc++;
+	    }
+
+	  max_width -= extra_indent;
+
+	  if (max_width < 0)
+	    max_width = 0;
+
+	  pr_scale_header (os, scale);
+
+	  octave_idx_type col = 0;
+	  while (col < num_elem)
+	    {
+	      octave_idx_type lim = col + inc < num_elem ? col + inc : num_elem;
+
+	      pr_col_num_header (os, total_width, max_width, lim, col,
+				 extra_indent);
+
+	      os << std::setw (extra_indent) << "";
+
+	      for (octave_idx_type i = col; i < lim; i++)
+		{
+		  OCTAVE_QUIT;
+
+		  double val = base + i * increment;
+
+		  if (i == num_elem - 1)
+		    {
+		      // See the comments in Range::matrix_value.
+
+		      if ((increment > 0 && val > limit)
+			  || (increment < 0 && val < limit))
+			val = limit;
+		    }
+
+		  os << "  ";
+
+		  pr_float (os, val, fw, scale);
+		}
+
+	      col += inc;
+	    }
+	}
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const boolMatrix& bm,
+		       bool pr_as_read_syntax,
+		       int extra_indent)
+{
+  Matrix tmp (bm);
+  octave_print_internal (os, tmp, pr_as_read_syntax, extra_indent);
+}
+
+void
+octave_print_internal (std::ostream& os, const boolNDArray& nda,
+		       bool pr_as_read_syntax,
+		       int extra_indent)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent);
+      break;
+
+    default:
+      PRINT_ND_ARRAY (os, nda, boolNDArray, bool, boolMatrix);
+      break;
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const charMatrix& chm,
+		       bool pr_as_read_syntax,
+		       int /* extra_indent FIXME */,
+		       bool pr_as_string)
+{
+  if (pr_as_string)
+    {
+      octave_idx_type nstr = chm.rows ();
+
+      if (pr_as_read_syntax && nstr > 1)
+	os << "[ ";
+
+      if (nstr != 0)
+	{
+	  for (octave_idx_type i = 0; i < nstr; i++)
+	    {
+	      OCTAVE_QUIT;
+
+	      std::string row = chm.row_as_string (i);
+
+	      if (pr_as_read_syntax)
+		{
+		  os << "\"" << undo_string_escapes (row) << "\"";
+
+		  if (i < nstr - 1)
+		    os << "; ";
+		}
+	      else
+		{
+		  os << row;
+
+		  if (i < nstr - 1)
+		    os << "\n";
+		}
+	    }
+	}
+
+      if (pr_as_read_syntax && nstr > 1)
+	os << " ]";
+    }
+  else
+    {
+      os << "sorry, printing char matrices not implemented yet\n";
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const charNDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent,
+		       bool pr_as_string)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent, pr_as_string);
+      break;
+
+    default:
+      PRINT_ND_ARRAY (os, nda, charNDArray, char, charMatrix);
+      break;
+    }
+}
+
+void
+octave_print_internal (std::ostream& os, const std::string& s,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  ArrayN<std::string> nda (dim_vector (1, 1), s);
+
+  octave_print_internal (os, nda, pr_as_read_syntax, extra_indent);
+}
+
+void
+octave_print_internal (std::ostream& os, const ArrayN<std::string>& nda,
+		       bool pr_as_read_syntax, int /* extra_indent */)
+{
+  // FIXME -- this mostly duplicates the code in the
+  // PRINT_ND_ARRAY macro.
+
+  if (nda.is_empty ())
+    print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
+  else if (nda.length () == 1)
+    {
+      os << nda(0);
+    }
+  else
+    {
+      int ndims = nda.ndims ();
+
+      dim_vector dims = nda.dims ();
+
+      Array<octave_idx_type> ra_idx (ndims, 0);
+
+      octave_idx_type m = 1;
+
+      for (int i = 2; i < ndims; i++)
+	m *= dims(i);
+
+      octave_idx_type nr = dims(0);
+      octave_idx_type nc = dims(1);
+
+      for (octave_idx_type i = 0; i < m; i++)
+	{
+	  std::string nm = "ans";
+
+	  if (m > 1)
+	    {
+	      nm += "(:,:,";
+
+	      std::ostringstream buf;
+
+	      for (int k = 2; k < ndims; k++)
+		{
+		  buf << ra_idx(k) + 1;
+
+		  if (k < ndims - 1)
+		    buf << ",";
+		  else
+		    buf << ")";
+		}
+
+	      nm += buf.str ();
+	    }
+
+	  Array<idx_vector> idx (ndims);
+
+	  idx(0) = idx_vector (':');
+	  idx(1) = idx_vector (':');
+
+	  for (int k = 2; k < ndims; k++)
+	    idx(k) = idx_vector (ra_idx(k));
+
+	  Array2<std::string> page (nda.index (idx), nr, nc);
+
+	  // FIXME -- need to do some more work to put these
+	  // in neatly aligned columns...
+
+	  octave_idx_type n_rows = page.rows ();
+	  octave_idx_type n_cols = page.cols ();
+
+	  os << nm << " =\n\n";
+
+	  for (octave_idx_type ii = 0; ii < n_rows; ii++)
+	    {
+	      for (octave_idx_type jj = 0; jj < n_cols; jj++)
+		os << "  " << page(ii,jj);
+
+	      os << "\n";
+	    }
+
+	  if (i < m - 1)
+	    os << "\n";
+
+	  if (i < m)
+	    increment_index (ra_idx, dims, 2);
+	}
+    }
+}
+
+template <class T>
+class
+octave_print_conv
+{
+public:
+  typedef T print_conv_type;
+};
+
+#define PRINT_CONV(T1, T2) \
+  template <> \
+  class \
+  octave_print_conv<T1> \
+  { \
+  public: \
+    typedef T2 print_conv_type; \
+  }
+
+PRINT_CONV (octave_int8, octave_int16);
+PRINT_CONV (octave_uint8, octave_uint16);
+
+#undef PRINT_CONV
+
+template <class T>
+/* static */ inline void
+pr_int (std::ostream& os, const T& d, int fw = 0)
+{
+  size_t sz = d.byte_size();
+  const unsigned char * tmpi = d.iptr();
+
+  // Unless explicitly asked for, always print in big-endian
+  // format for hex and bit formats.
+  //
+  //   {bit,hex}_format == 1: print big-endian
+  //   {bit,hex}_format == 2: print native
+
+  if (hex_format)
+    {
+      char ofill = os.fill ('0');
+
+      std::ios::fmtflags oflags
+	= os.flags (std::ios::right | std::ios::hex);
+
+      if (hex_format > 1 || oct_mach_info::words_big_endian ())
+	{
+	  for (size_t i = 0; i < sz; i++)
+	    os << std::setw (2) << static_cast<int> (tmpi[i]);
+	}
+      else
+	{
+	  for (int i = sz - 1; i >= 0; i--)
+	    os << std::setw (2) << static_cast<int> (tmpi[i]);
+	}
+
+      os.fill (ofill);
+      os.setf (oflags);	  
+    }
+  else if (bit_format)
+    {
+      if (oct_mach_info::words_big_endian ())
+	{
+	  for (size_t i = 0; i < sz; i++)
+	    PRINT_CHAR_BITS (os, tmpi[i]);
+	}
+      else
+	{
+	  if (bit_format > 1)
+	    {
+	      for (size_t i = 0; i < sz; i++)
+		PRINT_CHAR_BITS_SWAPPED (os, tmpi[i]);
+	    }
+	  else
+	    {
+	      for (int i = sz - 1; i >= 0; i--)
+		PRINT_CHAR_BITS (os, tmpi[i]);
+	    }
+	}
+    }
+  else
+    {
+      os << std::setw (fw)
+	 << typename octave_print_conv<T>::print_conv_type (d);
+
+      if (bank_format)
+	os << ".00";
+    }
+}
+
+// FIXME -- all this mess with abs is an attempt to avoid seeing
+//
+//   warning: comparison of unsigned expression < 0 is always false
+//
+// from GCC.  Isn't there a better way
+
+template <class T>
+/* static */ inline T
+abs (T x)
+{
+  return x < 0 ? -x : x;
+}
+
+#define INSTANTIATE_ABS(T) \
+  template /* static */ inline T abs (T)
+
+INSTANTIATE_ABS(signed char);
+INSTANTIATE_ABS(short);
+INSTANTIATE_ABS(int);
+INSTANTIATE_ABS(long);
+INSTANTIATE_ABS(long long);
+
+#define SPECIALIZE_UABS(T) \
+  template <> \
+  /* static */ inline unsigned T \
+  abs (unsigned T x) \
+  { \
+    return x; \
+  }
+
+SPECIALIZE_UABS(char)
+SPECIALIZE_UABS(short)
+SPECIALIZE_UABS(int)
+SPECIALIZE_UABS(long)
+SPECIALIZE_UABS(long long)
+
+template void
+pr_int (std::ostream&, const octave_int8&, int);
+
+template void
+pr_int (std::ostream&, const octave_int16&, int);
+
+template void
+pr_int (std::ostream&, const octave_int32&, int);
+
+template void
+pr_int (std::ostream&, const octave_int64&, int);
+
+template void
+pr_int (std::ostream&, const octave_uint8&, int);
+
+template void
+pr_int (std::ostream&, const octave_uint16&, int);
+
+template void
+pr_int (std::ostream&, const octave_uint32&, int);
+
+template void
+pr_int (std::ostream&, const octave_uint64&, int);
+
+template <class T>
+void
+octave_print_internal_template (std::ostream& os, const octave_int<T>& val,
+				bool)
+{
+  if (plus_format)
+    {
+      pr_plus_format (os, val);
+    }
+  else
+    {
+      if (free_format)
+	os << typename octave_print_conv<octave_int<T> >::print_conv_type (val);
+      else
+	pr_int (os, val);
+    }
+}
+
+#define PRINT_INT_SCALAR_INTERNAL(TYPE) \
+  OCTINTERP_API void \
+  octave_print_internal (std::ostream& os, const octave_int<TYPE>& val, bool dummy) \
+  { \
+    octave_print_internal_template (os, val, dummy); \
+  }
+
+PRINT_INT_SCALAR_INTERNAL (int8_t)
+PRINT_INT_SCALAR_INTERNAL (uint8_t)
+PRINT_INT_SCALAR_INTERNAL (int16_t)
+PRINT_INT_SCALAR_INTERNAL (uint16_t)
+PRINT_INT_SCALAR_INTERNAL (int32_t)
+PRINT_INT_SCALAR_INTERNAL (uint32_t)
+PRINT_INT_SCALAR_INTERNAL (int64_t)
+PRINT_INT_SCALAR_INTERNAL (uint64_t)
+
+template <class T>
+/* static */ inline void
+octave_print_internal_template (std::ostream& os, const intNDArray<T>& nda,
+				bool pr_as_read_syntax, int extra_indent)
+{
+  // FIXME -- this mostly duplicates the code in the
+  // PRINT_ND_ARRAY macro.
+
+  if (nda.is_empty ())
+    print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
+  else if (nda.length () == 1)
+    octave_print_internal_template (os, nda(0), pr_as_read_syntax);
+  else if (plus_format && ! pr_as_read_syntax)
+    {
+      int ndims = nda.ndims ();
+
+      Array<octave_idx_type> ra_idx (ndims, 0);
+
+      dim_vector dims = nda.dims ();
+
+      octave_idx_type m = 1;
+
+      for (int i = 2; i < ndims; i++)
+	m *= dims(i);
+
+      octave_idx_type nr = dims(0);
+      octave_idx_type nc = dims(1);
+
+      for (octave_idx_type i = 0; i < m; i++)
+	{
+	  if (m > 1)
+	    {
+	      std::string nm = "ans(:,:,";
+
+	      std::ostringstream buf;
+
+	      for (int k = 2; k < ndims; k++)
+		{
+		  buf << ra_idx(k) + 1;
+
+		  if (k < ndims - 1)
+		    buf << ",";
+		  else
+		    buf << ")";
+		}
+
+	      nm += buf.str ();
+
+	      os << nm << " =\n\n";
+	    }
+
+	  Array<idx_vector> idx (ndims);
+
+	  idx(0) = idx_vector (':');
+	  idx(1) = idx_vector (':');
+
+	  for (int k = 2; k < ndims; k++)
+	    idx(k) = idx_vector (ra_idx(k));
+
+	  Array2<T> page (nda.index (idx), nr, nc);
+
+	  for (octave_idx_type ii = 0; ii < nr; ii++)
+	    {
+	      for (octave_idx_type jj = 0; jj < nc; jj++)
+		{
+		  OCTAVE_QUIT;
+
+		  pr_plus_format (os, page(ii,jj));
+		}
+
+	      if ((ii < nr - 1) || (i < m -1))
+		os << "\n";
+	    }
+
+	  if (i < m - 1)
+	    {
+	      os << "\n";
+	      increment_index (ra_idx, dims, 2);
+	    }
+	}
+    }
+  else
+    {
+      int ndims = nda.ndims ();
+
+      dim_vector dims = nda.dims ();
+
+      Array<octave_idx_type> ra_idx (ndims, 0);
+
+      octave_idx_type m = 1;
+
+      for (int i = 2; i < ndims; i++)
+	m *= dims(i);
+
+      octave_idx_type nr = dims(0);
+      octave_idx_type nc = dims(1);
+
+      int fw = 0;
+      if (hex_format)
+	fw = 2 * nda(0).byte_size ();
+      else if (bit_format)
+	fw = nda(0).nbits ();
+      else
+	{
+	  bool isneg = false;
+	  int digits = 0;
+
+	  for (octave_idx_type i = 0; i < dims.numel (); i++)
+	    {
+	      int new_digits = static_cast<int> 
+		(floor (log10 (double (abs (nda(i).value ()))) + 1.0));
+
+	      if (new_digits > digits)
+		digits = new_digits;
+
+	      if (! isneg)
+	      isneg = (abs (nda(i).value ()) != nda(i).value ());
+	    }
+
+	  fw = digits + isneg;
+	}
+
+      int column_width = fw + (rat_format ?  0 : (bank_format ? 5 : 2));
+      octave_idx_type total_width = nc * column_width;
+      int max_width = command_editor::terminal_cols () - extra_indent;
+      octave_idx_type inc = nc;
+      if (total_width > max_width && Vsplit_long_rows)
+	{
+	  inc = max_width / column_width;
+	  if (inc == 0)
+	    inc++;
+	}
+
+      for (octave_idx_type i = 0; i < m; i++)
+	{
+	  if (m > 1)
+	    {
+	      std::string nm = "ans(:,:,";
+
+	      std::ostringstream buf;
+
+	      for (int k = 2; k < ndims; k++)
+		{
+		  buf << ra_idx(k) + 1;
+
+		  if (k < ndims - 1)
+		    buf << ",";
+		  else
+		    buf << ")";
+		}
+
+	      nm += buf.str ();
+
+	      os << nm << " =\n\n";
+	    }
+
+	  Array<idx_vector> idx (ndims);
+
+	  idx(0) = idx_vector (':');
+	  idx(1) = idx_vector (':');
+
+	  for (int k = 2; k < ndims; k++)
+	    idx(k) = idx_vector (ra_idx(k));
+
+	  Array2<T> page (nda.index (idx), nr, nc);
+
+	  if (free_format)
+	    {
+	      if (pr_as_read_syntax)
+		os << "[\n";
+
+	      for (octave_idx_type ii = 0; ii < nr; ii++)
+		{
+		  for (octave_idx_type jj = 0; jj < nc; jj++)
+		    {
+		      OCTAVE_QUIT;
+		      os << "  ";
+		      os << typename octave_print_conv<T>::print_conv_type (page(ii,jj));
+		    }
+		  os << "\n";
+		}
+
+	      if (pr_as_read_syntax)
+		os << "]";
+	    }
+	  else
+	    {
+	      octave_idx_type n_rows = page.rows ();
+	      octave_idx_type n_cols = page.cols ();
+
+	      for (octave_idx_type col = 0; col < n_cols; col += inc)
+		{
+		  octave_idx_type lim = col + inc < n_cols ? col + inc : n_cols;
+
+		  pr_col_num_header (os, total_width, max_width, lim, col,
+				     extra_indent);
+
+		  for (octave_idx_type ii = 0; ii < n_rows; ii++)
+		    {
+		      os << std::setw (extra_indent) << "";
+		      
+		      for (octave_idx_type jj = col; jj < lim; jj++)
+			{
+			  OCTAVE_QUIT;
+			  os << "  ";
+			  pr_int (os, page(ii,jj), fw);
+			}
+		      if ((ii < n_rows - 1) || (i < m -1))
+			os << "\n";
+		    }
+		}
+	    }
+
+	  if (i < m - 1)
+	    {
+	      os << "\n";
+	      increment_index (ra_idx, dims, 2);
+	    }
+	}
+    }
+}
+
+#define PRINT_INT_ARRAY_INTERNAL(TYPE) \
+  OCTINTERP_API void \
+  octave_print_internal (std::ostream& os, const intNDArray<TYPE>& nda, \
+			 bool pr_as_read_syntax, int extra_indent) \
+  { \
+    octave_print_internal_template (os, nda, pr_as_read_syntax, extra_indent); \
+  }
+
+PRINT_INT_ARRAY_INTERNAL (octave_int8)
+PRINT_INT_ARRAY_INTERNAL (octave_uint8)
+PRINT_INT_ARRAY_INTERNAL (octave_int16)
+PRINT_INT_ARRAY_INTERNAL (octave_uint16)
+PRINT_INT_ARRAY_INTERNAL (octave_int32)
+PRINT_INT_ARRAY_INTERNAL (octave_uint32)
+PRINT_INT_ARRAY_INTERNAL (octave_int64)
+PRINT_INT_ARRAY_INTERNAL (octave_uint64)
+
+void
+octave_print_internal (std::ostream&, const Cell&, bool, int, bool)
+{
+  panic_impossible ();
+}
+
+DEFUN (rats, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} rats (@var{x}, @var{len})\n\
+Convert @var{x} into a rational approximation represented as a string.\n\
+You can convert the string back into a matrix as follows:\n\
+\n\
+ at example\n\
+ at group\n\
+   r = rats(hilb(4));\n\
+   x = str2num(r)\n\
+ at end group\n\
+ at end example\n\
+\n\
+The optional second argument defines the maximum length of the string\n\
+representing the elements of @var{x}.  By default @var{len} is 9.\n\
+ at seealso{format, rat}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2 || nargout > 1)
+    print_usage ();
+  else
+    {
+      unwind_protect::begin_frame ("Frats");
+
+      unwind_protect_int (rat_string_len);
+
+      rat_string_len = 9;
+
+      if (nargin == 2)
+	rat_string_len = args(1).nint_value ();
+
+      if (! error_state)
+	{
+	  octave_value arg = args(0);
+
+	  if (arg.is_numeric_type ())
+	    {
+	      unwind_protect_bool (rat_format);
+
+	      rat_format = true;
+
+	      std::ostringstream buf;
+	      args(0).print (buf);
+	      std::string s = buf.str ();
+
+	      std::list<std::string> lst;
+
+	      size_t n = 0;
+	      size_t s_len = s.length ();
+
+	      while (n < s_len)
+		{
+		  size_t m = s.find ('\n',  n);
+
+		  if (m == std::string::npos)
+		    {
+		      lst.push_back (s.substr (n));
+		      break;
+		    }
+		  else
+		    {
+		      lst.push_back (s.substr (n, m - n));
+		      n = m + 1;
+		    }
+		}
+
+	      retval = string_vector (lst);
+	    }
+	  else
+	    error ("rats: expecting numeric input");
+	}
+
+      unwind_protect::run_frame ("Frats");
+    }
+
+  return retval;
+}
+
+DEFUN (disp, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} disp (@var{x})\n\
+Display the value of @var{x}.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+disp (\"The value of pi is:\"), disp (pi)\n\
+\n\
+     @print{} the value of pi is:\n\
+     @print{} 3.1416\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Note that the output from @code{disp} always ends with a newline.\n\
+\n\
+If an output value is requested, @code{disp} prints nothing and\n\
+returns the formatted output in a string.\n\
+ at seealso{fdisp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 && nargout < 2)
+    {
+      if (nargout == 0)
+	args(0).print (octave_stdout);
+      else
+	{
+	  octave_value arg = args(0);
+	  std::ostringstream buf;
+	  arg.print (buf);
+	  retval = octave_value (buf.str (), arg.is_dq_string () ? '"' : '\'');
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fdisp, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})\n\
+Display the value of @var{x} on the stream @var{fid}.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+fdisp (stdout, \"The value of pi is:\"), fdisp (stdout, pi)\n\
+\n\
+     @print{} the value of pi is:\n\
+     @print{} 3.1416\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Note that the output from @code{fdisp} always ends with a newline.\n\
+ at seealso{disp}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      int fid = octave_stream_list::get_file_number (args (0));
+
+      octave_stream os = octave_stream_list::lookup (fid, "fdisp");
+
+      if (! error_state)
+	{
+	  std::ostream *osp = os.output_stream ();
+
+	  if (osp)
+	    args(1).print (*osp);
+	  else
+	    error ("fdisp: stream not open for writing");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/* 
+%!test
+%! format short
+%! fd = tmpfile ();
+%! for r = [0, Inf -Inf, NaN]
+%!   for i = [0, Inf -Inf, NaN]
+%!     fdisp (fd, complex (r, i));
+%!   endfor
+%! endfor
+%! fclose (fd);
+*/                                 
+
+static void
+init_format_state (void)
+{
+  free_format = false;
+  plus_format = false;
+  rat_format = false;
+  bank_format = false;
+  hex_format = 0;
+  bit_format = 0;
+  compact_format = false;
+  print_e = false;
+  print_big_e = false;
+  print_g = false;
+}
+
+static void
+set_output_prec_and_fw (int prec, int fw)
+{
+  Voutput_precision =  prec;
+  Voutput_max_field_width = fw;
+}
+
+static void
+set_format_style (int argc, const string_vector& argv)
+{
+  int idx = 1;
+
+  if (--argc > 0)
+    {
+      std::string arg = argv[idx++];
+
+      if (arg == "short")
+	{
+	  if (--argc > 0)
+	    {
+	      arg = argv[idx++];
+
+	      if (arg == "e")
+		{
+		  init_format_state ();
+		  print_e = true;
+		}
+	      else if (arg == "E")
+		{
+		  init_format_state ();
+		  print_e = true;
+		  print_big_e = true;
+		}
+	      else if (arg == "g")
+		{
+		  init_format_state ();
+		  print_g = true;
+		}
+	      else if (arg == "G")
+		{
+		  init_format_state ();
+		  print_g = true;
+		  print_big_e = true;
+		}
+	      else
+		{
+		  error ("format: unrecognized option `short %s'",
+			 arg.c_str ());
+		  return;
+		}
+	    }
+	  else
+	    init_format_state ();
+
+	  set_output_prec_and_fw (5, 10);
+	}
+      else if (arg == "long")
+	{
+	  if (--argc > 0)
+	    {
+	      arg = argv[idx++];
+
+	      if (arg == "e")
+		{
+		  init_format_state ();
+		  print_e = true;
+		}
+	      else if (arg == "E")
+		{
+		  init_format_state ();
+		  print_e = true;
+		  print_big_e = true;
+		}
+	      else if (arg == "g")
+		{
+		  init_format_state ();
+		  print_g = true;
+		}
+	      else if (arg == "G")
+		{
+		  init_format_state ();
+		  print_g = true;
+		  print_big_e = true;
+		}
+	      else
+		{
+		  error ("format: unrecognized option `long %s'",
+			 arg.c_str ());
+		  return;
+		}
+	    }
+	  else
+	    init_format_state ();
+
+	  set_output_prec_and_fw (15, 20);
+	}
+      else if (arg == "hex")
+	{
+	  init_format_state ();
+	  hex_format = 1;
+	}
+      else if (arg == "native-hex")
+	{
+	  init_format_state ();
+	  hex_format = 2;
+	}
+      else if (arg == "bit")
+	{
+	  init_format_state ();
+	  bit_format = 1;
+	}
+      else if (arg == "native-bit")
+	{
+	  init_format_state ();
+	  bit_format = 2;
+	}
+      else if (arg == "+" || arg == "plus")
+	{
+	  if (--argc > 0)
+	    {
+	      arg = argv[idx++];
+
+	      if (arg.length () == 3)
+		plus_format_chars = arg;
+	      else
+		{
+		  error ("format: invalid option for plus format");
+		  return;
+		}
+	    }
+	  else
+	    plus_format_chars = "+  ";
+
+	  init_format_state ();
+	  plus_format = true;
+	}
+      else if (arg == "rat")
+	{
+	  init_format_state ();
+	  rat_format = true;
+	}
+      else if (arg == "bank")
+	{
+	  init_format_state ();
+	  bank_format = true;
+	}
+      else if (arg == "free")
+	{
+	  init_format_state ();
+	  free_format = true;
+	}
+      else if (arg == "none")
+	{
+	  init_format_state ();
+	  free_format = true;
+	}
+      else if (arg == "compact")
+	{
+	  compact_format = true;
+	}
+      else if (arg == "loose")
+	{
+	  compact_format = false;
+	}
+      else
+	error ("format: unrecognized format state `%s'", arg.c_str ());
+    }
+  else
+    {
+      init_format_state ();
+      set_output_prec_and_fw (5, 10);
+    }
+}
+
+DEFUN (format, args, ,
+  "-*- texinfo -*-\n\
+ at deffn  {Command} format\n\
+ at deffnx {Command} format options\n\
+Reset or specify the format of the output produced by @code{disp} and\n\
+Octave's normal echoing mechanism.  This command only affects the display\n\
+of numbers but not how they are stored or computed.  To change the internal\n\
+representation from the default double use one of the conversion functions\n\
+such as @code{single}, @code{uint8}, @code{int64}, etc.\n\
+\n\
+By default, Octave displays 5 significant digits in a human readable form\n\
+(option @samp{short} paired with @samp{loose} format for matrices).\n\
+If @code{format} is invoked without any options, this default format\n\
+is restored.\n\
+\n\
+Valid formats for floating point numbers are listed in the following\n\
+table.\n\
+\n\
+ at table @code\n\
+ at item short\n\
+Fixed point format with 5 significant figures in a field that is a maximum\n\
+of 10 characters wide.  (default).\n\
+\n\
+If Octave is unable to format a matrix so that columns line up on the\n\
+decimal point and all numbers fit within the maximum field width then\n\
+it switches to an exponential @samp{e} format.\n\
+\n\
+ at item long\n\
+Fixed point format with 15 significant figures in a field that is a maximum\n\
+of 20 characters wide.\n\
+\n\
+As with the @samp{short} format, Octave will switch to an exponential\n\
+ at samp{e} format if it is unable to format a matrix properly using the\n\
+current format.\n\
+\n\
+ at item  short e\n\
+ at itemx long e\n\
+Exponential format.  The number to be represented is split between a mantissa\n\
+and an exponent (power of 10).  The mantissa has 5 significant digits in the\n\
+short format and 15 digits in the long format.\n\
+For example, with the @samp{short e} format, @code{pi} is displayed as\n\
+ at code{3.1416e+00}.\n\
+\n\
+ at item  short E\n\
+ at itemx long E\n\
+Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\
+ at samp{E} to indicate the exponent.\n\
+For example, with the @samp{long E} format, @code{pi} is displayed as\n\
+ at code{3.14159265358979E+00}.\n\
+\n\
+ at item  short g\n\
+ at itemx long g\n\
+Optimally choose between fixed point and exponential format based on\n\
+the magnitude of the number.\n\
+For example, with the @samp{short g} format,\n\
+ at code{pi .^ [2; 4; 8; 16; 32]} is displayed as\n\
+\n\
+ at example\n\
+ at group\n\
+ans =\n\
+\n\
+      9.8696\n\
+      97.409\n\
+      9488.5\n\
+  9.0032e+07\n\
+  8.1058e+15\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at item long G\n\
+ at itemx short G\n\
+Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\
+ at samp{E} to indicate the exponent.\n\
+\n\
+ at item free\n\
+ at itemx none\n\
+Print output in free format, without trying to line up columns of\n\
+matrices on the decimal point.  This also causes complex numbers to be\n\
+formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead\n\
+of like this @samp{0.60419 + 0.60709i}.\n\
+ at end table\n\
+\n\
+The following formats affect all numeric output (floating point and\n\
+integer types).\n\
+\n\
+ at table @code\n\
+ at item  +\n\
+ at itemx + @var{chars}\n\
+ at itemx plus\n\
+ at itemx plus @var{chars}\n\
+Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\
+matrix elements.  This format can be very useful for examining the\n\
+structure of a large sparse matrix.\n\
+\n\
+The optional argument @var{chars} specifies a list of 3 characters to use\n\
+for printing values greater than zero, less than zero and equal to zero.\n\
+For example, with the @samp{+ \"+-.\"} format, @code{[1, 0, -1; -1, 0, 1]}\n\
+is displayed as\n\
+\n\
+ at example\n\
+ at group\n\
+ans =\n\
+\n\
++.-\n\
+-.+\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at item bank\n\
+Print in a fixed format with two digits to the right of the decimal\n\
+point.\n\
+\n\
+ at item native-hex\n\
+Print the hexadecimal representation of numbers as they are stored in\n\
+memory.  For example, on a workstation which stores 8 byte real values\n\
+in IEEE format with the least significant byte first, the value of\n\
+ at code{pi} when printed in @code{native-hex} format is @code{400921fb54442d18}.\n\
+\n\
+ at item hex\n\
+The same as @code{native-hex}, but always print the most significant\n\
+byte first.\n\
+ at item native-bit\n\
+Print the bit representation of numbers as stored in memory.\n\
+For example, the value of @code{pi} is\n\
+\n\
+ at example\n\
+ at group\n\
+01000000000010010010000111111011\n\
+01010100010001000010110100011000\n\
+ at end group\n\
+ at end example\n\
+\n\
+(shown here in two 32 bit sections for typesetting purposes) when\n\
+printed in native-bit format on a workstation which stores 8 byte real values\n\
+in IEEE format with the least significant byte first.\n\
+ at item bit\n\
+The same as @code{native-bit}, but always print the most significant\n\
+bits first.\n\
+\n\
+ at item rat\n\
+Print a rational approximation, i.e., values are approximated\n\
+as the ratio of small integers.\n\
+For example, with the @samp{rat} format,\n\
+ at code{pi} is displayed as @code{355/113}.\n\
+ at end table\n\
+\n\
+The following two options affect the display of all matrices.\n\
+\n\
+ at table @code\n\
+ at item compact\n\
+Remove extra blank space around column number labels producing more compact\n\
+output with more data per page.\n\
+ at item loose\n\
+Insert blank lines above and below column number labels to produce a more\n\
+readable output with less data per page.  (default).\n\
+ at end table\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("format");
+
+  if (error_state)
+    return retval;
+
+  set_format_style (argc, argv);
+
+  return retval;
+}
+
+DEFUN (fixed_point_format, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} fixed_point_format ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} fixed_point_format (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave will\n\
+use a scaled format to print matrix values such that the largest\n\
+element may be written with a single leading digit with the scaling\n\
+factor is printed on the first line of output.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+octave:1> logspace (1, 7, 5)'\n\
+ans =\n\
+\n\
+  1.0e+07  *\n\
+\n\
+  0.00000\n\
+  0.00003\n\
+  0.00100\n\
+  0.03162\n\
+  1.00000\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+Notice that first value appears to be zero when it is actually 1.  For\n\
+this reason, you should be careful when setting\n\
+ at code{fixed_point_format} to a nonzero value.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (fixed_point_format);
+}
+
+DEFUN (print_empty_dimensions, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} print_empty_dimensions ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} print_empty_dimensions (@var{new_val})\n\
+Query or set the internal variable that controls whether the\n\
+dimensions of empty matrices are printed along with the empty matrix\n\
+symbol, @samp{[]}.  For example, the expression\n\
+\n\
+ at example\n\
+zeros (3, 0)\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will print\n\
+\n\
+ at example\n\
+ans = [](3x0)\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (print_empty_dimensions);
+}
+
+DEFUN (split_long_rows, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} split_long_rows ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} split_long_rows (@var{new_val})\n\
+Query or set the internal variable that controls whether rows of a matrix\n\
+may be split when displayed to a terminal window.  If the rows are split,\n\
+Octave will display the matrix in a series of smaller pieces, each of\n\
+which can fit within the limits of your terminal width and each set of\n\
+rows is labeled so that you can easily see which columns are currently\n\
+being displayed.  For example:\n\
+\n\
+ at example\n\
+ at group\n\
+octave:13> rand (2,10)\n\
+ans =\n\
+\n\
+ Columns 1 through 6:\n\
+\n\
+  0.75883  0.93290  0.40064  0.43818  0.94958  0.16467\n\
+  0.75697  0.51942  0.40031  0.61784  0.92309  0.40201\n\
+\n\
+ Columns 7 through 10:\n\
+\n\
+  0.90174  0.11854  0.72313  0.73326\n\
+  0.44672  0.94303  0.56564  0.82150\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (split_long_rows);
+}
+
+DEFUN (output_max_field_width, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} output_max_field_width ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} output_max_field_width (@var{new_val})\n\
+Query or set the internal variable that specifies the maximum width\n\
+of a numeric output field.\n\
+ at seealso{format, output_precision}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_precision, 0, INT_MAX);
+}
+
+DEFUN (output_precision, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} output_precision ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} output_precision (@var{new_val})\n\
+Query or set the internal variable that specifies the minimum number of\n\
+significant figures to display for numeric output.\n\
+ at seealso{format, output_max_field_width}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_precision, -1, INT_MAX);
+}
+
+DEFUN (struct_levels_to_print, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} struct_levels_to_print ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} struct_levels_to_print (@var{new_val})\n\
+Query or set the internal variable that specifies the number of\n\
+structure levels to display.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE_WITH_LIMITS (struct_levels_to_print,
+					    -1, INT_MAX);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pr-output.h b/src/pr-output.h
new file mode 100644
index 0000000..bd95765
--- /dev/null
+++ b/src/pr-output.h
@@ -0,0 +1,269 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_pr_output_h)
+#define octave_pr_output_h 1
+
+#include <iosfwd>
+
+#include "oct-cmplx.h"
+
+template <typename T> class ArrayN;
+class ComplexMatrix;
+class FloatComplexMatrix;
+class ComplexDiagMatrix;
+class FloatComplexDiagMatrix;
+class ComplexNDArray;
+class FloatComplexNDArray;
+class Matrix;
+class FloatMatrix;
+class DiagMatrix;
+class FloatDiagMatrix;
+class NDArray;
+class FloatNDArray;
+class Range;
+class boolMatrix;
+class boolNDArray;
+class charMatrix;
+class charNDArray;
+class PermMatrix;
+class Cell;
+
+#include "intNDArray.h"
+#include "oct-inttypes.h"
+
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, bool d,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, double d,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, float d,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const Matrix& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const DiagMatrix& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatMatrix& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatDiagMatrix& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const NDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatNDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const Complex& c,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatComplex& c,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const ComplexMatrix& cm,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const ComplexDiagMatrix& cm,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatComplexMatrix& cm,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatComplexDiagMatrix& cm,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const FloatComplexNDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const PermMatrix& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const Range& r,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const boolMatrix& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const boolNDArray& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const charMatrix& chm,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0,
+		       bool pr_as_string = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const charNDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0,
+		       bool pr_as_string = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const std::string& s,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const ArrayN<std::string>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_int8>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_uint8>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_int16>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_uint16>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_int32>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_uint32>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_int64>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const intNDArray<octave_uint64>& sa,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<int8_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<uint8_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<int16_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<uint16_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<int32_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<uint32_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<int64_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const octave_int<uint64_t>& sa,
+		       bool pr_as_read_syntax = false);
+
+extern OCTINTERP_API void
+octave_print_internal (std::ostream& os, const Cell& cell,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0,
+		       bool pr_as_string = false);
+
+// TRUE means that the dimensions of empty objects should be printed
+// like this: x = [](2x0).
+extern bool Vprint_empty_dimensions;
+
+// How many levels of structure elements should we print?
+extern OCTINTERP_API int Vstruct_levels_to_print;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/procstream.cc b/src/procstream.cc
new file mode 100644
index 0000000..eb3ba1d
--- /dev/null
+++ b/src/procstream.cc
@@ -0,0 +1,77 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004,
+              2005, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "procstream.h"
+
+procstreambase::procstreambase (const std::string& command, int mode)
+{
+  pb_init ();
+
+  if (! pb.open (command.c_str (), mode))
+    std::ios::setstate (std::ios::badbit);
+}
+
+procstreambase::procstreambase (const char *command, int mode)
+{
+  pb_init ();
+
+  if (! pb.open (command, mode))
+    std::ios::setstate (std::ios::badbit);
+}
+
+void
+procstreambase::open (const char *command, int mode)
+{
+  clear ();
+
+  if (! pb.open (command, mode))
+    std::ios::setstate (std::ios::badbit);
+}
+
+int
+procstreambase::close (void)
+{
+  int status = 0;
+
+  if (is_open ())
+    {
+      if (! pb.close ())
+	std::ios::setstate (std::ios::failbit);
+
+      status = pb.wait_status ();
+    }
+
+  return status;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/procstream.h b/src/procstream.h
new file mode 100644
index 0000000..0a0636e
--- /dev/null
+++ b/src/procstream.h
@@ -0,0 +1,170 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
+              2004, 2005, 2006, 2007, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_procstream_h)
+#define octave_procstream_h 1
+
+#include <iosfwd>
+#include <string>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "oct-procbuf.h"
+
+class
+OCTINTERP_API
+procstreambase : virtual public std::ios
+{
+public:
+
+  procstreambase (void) { pb_init (); }
+
+  procstreambase (const std::string& name, int mode);
+
+  procstreambase (const char *name, int mode);
+
+  ~procstreambase (void) { close (); }
+
+  void open (const std::string& name, int mode)
+    { open (name.c_str (), mode); }
+
+  void open (const char *name, int mode);
+
+  int is_open (void) const { return pb.is_open (); }
+
+  int close (void);
+
+  pid_t pid (void) const { return pb.pid (); }
+
+  int file_number (void) const { return pb.file_number (); }
+
+private:
+
+  octave_procbuf pb;
+
+  void pb_init (void) { init (&pb); }
+
+  procstreambase (const procstreambase&);
+
+  procstreambase& operator = (const procstreambase&);
+};
+
+class
+OCTINTERP_API
+iprocstream : public std::istream, public procstreambase
+// iprocstream : public procstreambase, public std::istream
+{
+public:
+
+  iprocstream (void) : std::istream (0), procstreambase () { }
+
+  iprocstream (const std::string& name, int mode = std::ios::in)
+    : std::istream (0), procstreambase (name, mode) { }
+
+  iprocstream (const char *name, int mode = std::ios::in)
+    : std::istream (0), procstreambase (name, mode) { }
+
+  ~iprocstream (void) { }
+
+  void open (const std::string& name, int mode = std::ios::in)
+    { procstreambase::open (name, mode); }
+
+  void open (const char *name, int mode = std::ios::in)
+    { procstreambase::open (name, mode); }
+
+private:
+
+  iprocstream (const iprocstream&);
+
+  iprocstream& operator = (const iprocstream&);
+};
+
+class
+OCTINTERP_API
+oprocstream : public std::ostream, public procstreambase
+// oprocstream : public procstreambase, public std::ostream
+{
+public:
+ 
+  oprocstream (void) : std::ostream (0), procstreambase () { }
+
+  oprocstream (const std::string& name, int mode = std::ios::out)
+    : std::ostream (0), procstreambase(name, mode) { }
+
+  oprocstream (const char *name, int mode = std::ios::out)
+    : std::ostream (0), procstreambase(name, mode) { }
+
+  ~oprocstream (void) { }
+
+  void open (const std::string& name, int mode = std::ios::out)
+    { procstreambase::open (name, mode); }
+
+  void open (const char *name, int mode = std::ios::out)
+    { procstreambase::open (name, mode); }
+
+private:
+
+  oprocstream (const oprocstream&);
+
+  oprocstream& operator = (const oprocstream&);
+};
+
+class
+OCTINTERP_API
+procstream : public std::iostream, public procstreambase
+// procstream : public procstreambase, public std::iostream
+{
+public:
+
+  procstream (void) : std::iostream (0), procstreambase () { }
+
+  procstream (const std::string& name, int mode)
+    : std::iostream (0), procstreambase (name, mode) { }
+
+  procstream (const char *name, int mode)
+    : std::iostream (0), procstreambase (name, mode) { }
+
+  ~procstream (void) { }
+
+  void open (const std::string& name, int mode)
+    { procstreambase::open (name, mode); }
+
+  void open (const char *name, int mode)
+    { procstreambase::open (name, mode); }
+
+private:
+
+  procstream (const procstream&);
+
+  procstream& operator = (const procstream&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-all.h b/src/pt-all.h
new file mode 100644
index 0000000..0b7685f
--- /dev/null
+++ b/src/pt-all.h
@@ -0,0 +1,61 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_all_h)
+#define octave_tree_all_h 1
+
+#include "pt.h"
+#include "pt-arg-list.h"
+#include "pt-assign.h"
+#include "pt-bp.h"
+#include "pt-binop.h"
+#include "pt-cbinop.h"
+#include "pt-check.h"
+#include "pt-cmd.h"
+#include "pt-colon.h"
+#include "pt-const.h"
+#include "pt-decl.h"
+#include "pt-except.h"
+#include "pt-exp.h"
+#include "pt-fcn-handle.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-jump.h"
+#include "pt-loop.h"
+#include "pt-mat.h"
+#include "pt-cell.h"
+#include "pt-misc.h"
+#include "pt-pr-code.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
+#include "pt-unop.h"
+#include "pt-pr-code.h"
+#include "pt-walk.h"
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-arg-list.cc b/src/pt-arg-list.cc
new file mode 100644
index 0000000..4023c1f
--- /dev/null
+++ b/src/pt-arg-list.cc
@@ -0,0 +1,289 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "str-vec.h"
+
+#include "defun.h"
+#include "error.h"
+#include "oct-lvalue.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-usr-fcn.h"
+#include "parse.h"
+#include "pt-arg-list.h"
+#include "pt-exp.h"
+#include "pt-pr-code.h"
+#include "pt-walk.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+
+// Argument lists.
+
+tree_argument_list::~tree_argument_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+bool
+tree_argument_list::has_magic_end (void) const
+{
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      tree_expression *elt = *p;
+
+      if (elt && elt->has_magic_end ())
+	return true;
+    }
+
+  return false;
+}
+
+void
+tree_argument_list::append (const element_type& s)
+{
+  octave_base_list<tree_expression *>::append (s);
+
+  if (! list_includes_magic_end && s && s->has_magic_end ())
+    list_includes_magic_end = true;
+}
+
+bool
+tree_argument_list::all_elements_are_constant (void) const
+{
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      tree_expression *elt = *p;
+
+      if (! elt->is_constant ())
+	return false;
+    }
+
+  return true;
+}
+
+static const octave_value *indexed_object = 0;
+static int index_position = 0;
+static int num_indices = 0;
+
+DEFCONSTFUN (__end__, , ,
+  "internal function")
+{
+  octave_value retval;
+
+  if (indexed_object)
+    {
+      if (indexed_object->is_object ())
+	{
+	  octave_value_list args;
+
+	  args(2) = num_indices;
+	  args(1) = index_position + 1;
+	  args(0) = *indexed_object;
+
+	  std::string class_name = indexed_object->class_name ();
+
+	  octave_value meth = symbol_table::find_method ("end", class_name);
+
+	  if (meth.is_defined ())
+	    return feval (meth.function_value (), args, 1);
+	}
+
+      dim_vector dv = indexed_object->dims ();
+      int ndims = dv.length ();
+
+      if (num_indices < ndims)
+	{
+	  for (int i = num_indices; i < ndims; i++)
+	    dv(num_indices-1) *= dv(i);
+
+	  if (num_indices == 1)
+	    {
+	      ndims = 2;
+	      dv.resize (ndims);
+	      dv(1) = 1;
+	    }
+	  else
+	    {
+	      ndims = num_indices;
+	      dv.resize (ndims);
+	    }
+	}
+
+      if (index_position < ndims)
+	retval = dv(index_position);
+      else
+	retval = 1;
+    }
+  else
+    ::error ("invalid use of end");
+
+  return retval;
+}
+
+octave_value_list
+tree_argument_list::convert_to_const_vector (const octave_value *object)
+{
+  // END doesn't make sense for functions.  Maybe we need a different
+  // way of asking an octave_value object this question?
+
+  bool stash_object = (list_includes_magic_end
+		       && object
+		       && ! (object->is_function ()
+			     || object->is_function_handle ()));
+
+  if (stash_object)
+    {
+      unwind_protect::begin_frame ("convert_to_const_vector");
+
+      unwind_protect_const_ptr (indexed_object);
+
+      indexed_object = object;
+    }
+
+  int len = length ();
+
+  std::list<octave_value_list> args;
+
+  iterator p = begin ();
+  for (int k = 0; k < len; k++)
+    {
+      if (stash_object)
+	{
+	  unwind_protect_int (index_position);
+	  unwind_protect_int (num_indices);
+
+	  index_position = k;
+	  num_indices = len;
+	}
+
+      tree_expression *elt = *p++;
+
+      if (elt)
+	{
+	  octave_value tmp = elt->rvalue1 ();
+
+	  if (error_state)
+	    {
+	      ::error ("evaluating argument list element number %d", k+1);
+	      args.clear ();
+	      break;
+	    }
+	  else
+	    {
+	      if (tmp.is_cs_list ())
+                args.push_back (tmp.list_value ());
+	      else if (tmp.is_defined ())
+                args.push_back (tmp);
+	    }
+	}
+      else
+	{
+	  args.push_back (octave_value ());
+	  break;
+	}
+    }
+
+  if (stash_object)
+    unwind_protect::run_frame ("convert_to_const_vector");
+
+  return args;
+}
+
+std::list<octave_lvalue>
+tree_argument_list::lvalue_list (void)
+{
+  std::list<octave_lvalue> retval;
+
+  for (tree_argument_list::iterator p = begin ();
+       p != end ();
+       p++)
+    {
+      tree_expression *elt = *p;
+
+      retval.push_back (elt->lvalue ());
+    }
+
+  return retval;
+}
+
+string_vector
+tree_argument_list::get_arg_names (void) const
+{
+  int len = length ();
+
+  string_vector retval (len);
+
+  int k = 0;
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      tree_expression *elt = *p;
+
+      retval(k++) = elt->str_print_code ();
+    }
+
+  return retval;
+}
+
+tree_argument_list *
+tree_argument_list::dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context) const
+{
+  tree_argument_list *new_list = new tree_argument_list ();
+
+  new_list->list_includes_magic_end = list_includes_magic_end;
+  new_list->simple_assign_lhs = simple_assign_lhs;
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_expression *elt = *p;
+
+      new_list->append (elt ? elt->dup (scope, context) : 0);
+    }
+
+  return new_list;
+}
+
+void
+tree_argument_list::accept (tree_walker& tw)
+{
+  tw.visit_argument_list (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-arg-list.h b/src/pt-arg-list.h
new file mode 100644
index 0000000..8c21fae
--- /dev/null
+++ b/src/pt-arg-list.h
@@ -0,0 +1,105 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_arg_list_h)
+#define octave_tree_arg_list_h 1
+
+#include <list>
+
+class octave_value_list;
+class octave_lvalue;
+class tree_expression;
+class tree_walker;
+
+#include "str-vec.h"
+
+#include "base-list.h"
+
+// Argument lists.  Used to hold the list of expressions that are the
+// arguments in a function call or index expression.
+
+class
+tree_argument_list : public octave_base_list<tree_expression *>
+{
+public:
+
+  typedef tree_expression* element_type;
+
+  tree_argument_list (void)
+    : list_includes_magic_end (false), simple_assign_lhs (false) { }
+
+  tree_argument_list (tree_expression *t)
+    : list_includes_magic_end (false), simple_assign_lhs (false)
+  { append (t); }
+
+  ~tree_argument_list (void);
+
+  bool has_magic_end (void) const;
+
+  tree_expression *remove_front (void)
+    {
+      iterator p = begin ();
+      tree_expression *retval = *p;
+      erase (p);
+      return retval;
+    }
+
+  void append (const element_type& s);
+
+  void mark_as_simple_assign_lhs (void) { simple_assign_lhs = true; }
+
+  bool is_simple_assign_lhs (void) { return simple_assign_lhs; }
+
+  bool all_elements_are_constant (void) const;
+
+  octave_value_list convert_to_const_vector (const octave_value *object = 0);
+
+  std::list<octave_lvalue> lvalue_list (void);
+
+  string_vector get_arg_names (void) const;
+
+  tree_argument_list *dup (symbol_table::scope_id scope,
+			   symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  bool list_includes_magic_end;
+
+  bool simple_assign_lhs;
+
+  // No copying!
+
+  tree_argument_list (const tree_argument_list&);
+
+  tree_argument_list& operator = (const tree_argument_list&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-assign.cc b/src/pt-assign.cc
new file mode 100644
index 0000000..d074f31
--- /dev/null
+++ b/src/pt-assign.cc
@@ -0,0 +1,509 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <set>
+
+#include "defun.h"
+#include "error.h"
+#include "input.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "pager.h"
+#include "ov.h"
+#include "pt-arg-list.h"
+#include "pt-bp.h"
+#include "pt-assign.h"
+#include "pt-walk.h"
+#include "utils.h"
+#include "variables.h"
+
+// Simple assignment expressions.
+
+// FIXME -- the following variable and the function that uses it
+// should be removed from some future version of Octave.
+
+static const char *former_built_in_variables[] =
+{
+  "DEFAULT_EXEC_PATH",
+  "DEFAULT_LOADPATH",
+  "EDITOR",
+  "EXEC_PATH",
+  "FFTW_WISDOM_PROGRAM",
+  "IMAGEPATH",
+  "INFO_FILE",
+  "INFO_PROGRAM",
+  "LOADPATH",
+  "MAKEINFO_PROGRAM",
+  "PAGER",
+  "PS1",
+  "PS2",
+  "PS4",
+  "__kluge_procbuf_delay__",
+  "automatic_replot",
+  "beep_on_error",
+  "completion_append_char",
+  "crash_dumps_octave_core",
+  "current_script_file_name",
+  "debug_on_error",
+  "debug_on_interrupt",
+  "debug_on_warning",
+  "debug_symtab_lookups",
+  "default_save_format",
+  "echo_executing_commands",
+  "fixed_point_format",
+  "gnuplot_binary",
+  "gnuplot_command_axes",
+  "gnuplot_command_end",
+  "gnuplot_command_plot",
+  "gnuplot_command_replot",
+  "gnuplot_command_splot",
+  "gnuplot_command_title",
+  "gnuplot_command_using",
+  "gnuplot_command_with",
+  "gnuplot_has_frames",
+  "history_file",
+  "history_size",
+  "ignore_function_time_stamp",
+  "max_recursion_depth",
+  "octave_core_file_format",
+  "octave_core_file_limit",
+  "octave_core_file_name",
+  "output_max_field_width",
+  "output_precision",
+  "page_output_immediately",
+  "page_screen_output",
+  "print_answer_id_name",
+  "print_empty_dimensions",
+  "print_rhs_assign_val",
+  "save_header_format_string",
+  "save_precision",
+  "saving_history",
+  "sighup_dumps_octave_core",
+  "sigterm_dumps_octave_core",
+  "silent_functions",
+  "split_long_rows",
+  "string_fill_char",
+  "struct_levels_to_print",
+  "suppress_verbose_help_message",
+  "variables_can_hide_functions",
+  "warn_assign_as_truth_value",
+  "warn_associativity_change",
+  "warn_divide_by_zero",
+  "warn_empty_list_elements",
+  "warn_fortran_indexing",
+  "warn_function_name_clash",
+  "warn_future_time_stamp",
+  "warn_imag_to_real",
+  "warn_matlab_incompatible",
+  "warn_missing_semicolon",
+  "warn_neg_dim_as_zero",
+  "warn_num_to_str",
+  "warn_precedence_change",
+  "warn_reload_forces_clear",
+  "warn_resize_on_range_error",
+  "warn_separator_insert",
+  "warn_single_quote_string",
+  "warn_str_to_num",
+  "warn_undefined_return_values",
+  "warn_variable_switch_label",
+  "whos_line_format",
+  0,
+};
+
+static void
+maybe_warn_former_built_in_variable (const std::string& nm)
+{
+  static bool initialized = false;
+
+  static std::set<std::string> vars;
+
+  if (! initialized)
+    {
+      const char **p = former_built_in_variables;
+
+      while (*p)
+	vars.insert (*p++);
+
+      initialized = true;
+    }
+
+  if (vars.find (nm) != vars.end ())
+    {
+      const char *nm_c_str = nm.c_str ();
+
+      warning_with_id ("Octave:built-in-variable-assignment",
+		       "%s is now a function instead of a built-in variable.  By assigning to %s, you have created a variable that hides the function %s.  To remove the variable and restore the function, type \"clear %s\"",
+		       nm_c_str, nm_c_str, nm_c_str, nm_c_str);
+    }
+}
+
+tree_simple_assignment::tree_simple_assignment
+  (tree_expression *le, tree_expression *re,
+   bool plhs, int l, int c, octave_value::assign_op t)
+    : tree_expression (l, c), lhs (le), rhs (re), preserve (plhs), etype (t),
+      first_execution (true) { }
+
+tree_simple_assignment::~tree_simple_assignment (void)
+{
+  if (! preserve)
+    delete lhs;
+
+  delete rhs;
+}
+
+octave_value_list
+tree_simple_assignment::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for expression X = RHS");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_simple_assignment::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (first_execution && lhs)
+    maybe_warn_former_built_in_variable (lhs->name ());
+
+  if (error_state)
+    return retval;
+
+  if (rhs)
+    {
+      octave_value rhs_val = rhs->rvalue1 ();
+
+      if (! error_state)
+	{
+	  if (rhs_val.is_undefined ())
+	    {
+	      error ("value on right hand side of assignment is undefined");
+	      return retval;
+	    }
+	  else
+	    {
+	      if (rhs_val.is_cs_list ())
+		{
+		  const octave_value_list lst = rhs_val.list_value ();
+
+		  if (! lst.empty ())
+		    rhs_val = lst(0);
+		  else
+		    {
+		      error ("invalid number of elements on RHS of assignment");
+		      return retval;
+		    }
+		}
+
+	      octave_lvalue ult = lhs->lvalue ();
+
+	      if (! error_state)
+		{
+		  ult.assign (etype, rhs_val);
+
+		  if (! error_state)
+		    {
+		      if (etype == octave_value::op_asn_eq)
+			retval = rhs_val;
+		      else
+			retval = ult.value ();
+
+		      if (print_result ())
+			{
+			  // We clear any index here so that we can
+			  // get the new value of the referenced
+			  // object below, instead of the indexed
+			  // value (which should be the same as the
+			  // right hand side value).
+
+			  ult.clear_index ();
+
+			  octave_value lhs_val = ult.value ();
+
+			  if (! error_state)
+			    lhs_val.print_with_name (octave_stdout,
+						     lhs->name ());
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+  first_execution = false;
+
+  return retval;
+}
+
+std::string
+tree_simple_assignment::oper (void) const
+{
+  return octave_value::assign_op_as_string (etype);
+}
+
+tree_expression *
+tree_simple_assignment::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context) const
+{
+  tree_simple_assignment *new_sa
+    = new tree_simple_assignment (lhs ? lhs->dup (scope, context) : 0,
+				  rhs ? rhs->dup (scope, context) : 0,
+				  preserve, etype);
+
+  new_sa->copy_base (*this);
+
+  return new_sa;
+}
+
+void
+tree_simple_assignment::accept (tree_walker& tw)
+{
+  tw.visit_simple_assignment (*this);
+}
+
+// Multi-valued assignment expressions.
+
+tree_multi_assignment::tree_multi_assignment
+  (tree_argument_list *lst, tree_expression *r,
+   bool plhs, int l, int c, octave_value::assign_op t)
+    : tree_expression (l, c), lhs (lst), rhs (r), preserve (plhs), etype (t),
+      first_execution (true) { }
+
+tree_multi_assignment::~tree_multi_assignment (void)
+{
+  if (! preserve)
+    delete lhs;
+
+  delete rhs;
+}
+
+octave_value
+tree_multi_assignment::rvalue1 (int nargout)
+{
+  octave_value retval;
+
+  const octave_value_list tmp = rvalue (nargout);
+
+  if (! tmp.empty ())
+    retval = tmp(0);
+
+  return retval;
+}
+
+// FIXME -- this works, but it would look a little better if
+// it were broken up into a couple of separate functions.
+
+octave_value_list
+tree_multi_assignment::rvalue (int)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  if (first_execution)
+    {
+      for (tree_argument_list::iterator p = lhs->begin (); p != lhs->end (); p++)
+        {
+          tree_expression *lhs_expr = *p;
+
+          if (lhs_expr)
+            maybe_warn_former_built_in_variable (lhs_expr->name ());
+        }
+    }
+
+  if (rhs)
+    {
+      std::list<octave_lvalue> lvalue_list = lhs->lvalue_list ();
+
+      if (error_state)
+	return retval;
+
+      int n_out = 0;
+
+      for (std::list<octave_lvalue>::const_iterator p = lvalue_list.begin ();
+	   p != lvalue_list.end ();
+	   p++)
+	n_out += p->numel ();
+
+      // The following trick is used to keep rhs_val constant.
+      const octave_value_list rhs_val1 = rhs->rvalue (n_out);
+      const octave_value_list rhs_val = (rhs_val1.length () == 1 && rhs_val1(0).is_cs_list ()
+                                         ? rhs_val1(0).list_value () : rhs_val1);
+
+      if (error_state)
+	return retval;
+
+      if (rhs_val.empty ())
+	{
+	  if (n_out > 0)
+	    {
+	      error ("value on right hand side of assignment is undefined");
+	      return retval;
+	    }
+	}
+      else
+	{
+	  octave_idx_type k = 0;
+
+	  octave_idx_type n = rhs_val.length ();
+
+          // To avoid copying per elements and possible optimizations, we
+          // postpone joining the final values.
+          std::list<octave_value_list> retval_list;
+
+	  tree_argument_list::iterator q = lhs->begin ();
+
+	  for (std::list<octave_lvalue>::iterator p = lvalue_list.begin ();
+	       p != lvalue_list.end ();
+	       p++)
+	    {
+	      tree_expression *lhs_elt = *q++;
+
+	      octave_lvalue ult = *p;
+
+	      octave_idx_type nel = ult.numel ();
+
+	      if (nel > 1)
+		{
+		  if (k + nel <= n)
+		    {
+		      if (etype == octave_value::op_asn_eq)
+			{
+                          // This won't do a copy.
+			  octave_value_list ovl  = rhs_val.slice (k, nel);
+
+			  ult.assign (etype, octave_value (ovl, true));
+
+			  if (! error_state)
+			    {
+                              retval_list.push_back (ovl);
+
+			      k += nel;
+			    }
+			}
+		      else
+			{
+			  std::string op = octave_value::assign_op_as_string (etype);
+			  error ("operator %s unsupported for comma-separated list assignment",
+				 op.c_str ());
+			}
+		    }
+		  else
+		    error ("some elements undefined in return list");
+		}
+	      else if (nel == 1)
+		{
+		  if (k < n)
+		    {
+		      ult.assign (etype, rhs_val(k));
+
+		      if (! error_state)
+			{
+			  if (etype == octave_value::op_asn_eq)
+                            retval_list.push_back (rhs_val(k));
+			  else
+                            retval_list.push_back (ult.value ());
+
+			  k++;
+			}
+		    }
+		  else
+		    error ("element number %d undefined in return list", k+1);
+		}
+
+	      if (error_state)
+		break;
+	      else if (print_result ())
+		{
+		  // We clear any index here so that we can get
+		  // the new value of the referenced object below,
+		  // instead of the indexed value (which should be
+		  // the same as the right hand side value).
+
+		  ult.clear_index ();
+
+		  octave_value lhs_val = ult.value ();
+
+		  if (! error_state)
+		    lhs_val.print_with_name (octave_stdout,
+					     lhs_elt->name ());
+		}
+
+	      if (error_state)
+		break;
+
+	    }
+          
+          // Concatenate return values.
+          retval = retval_list;
+	}
+    }
+
+  first_execution = false;
+
+  return retval;
+}
+
+std::string
+tree_multi_assignment::oper (void) const
+{
+  return octave_value::assign_op_as_string (etype);
+}
+
+tree_expression *
+tree_multi_assignment::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const
+{
+  tree_multi_assignment *new_ma
+    = new tree_multi_assignment (lhs ? lhs->dup (scope, context) : 0,
+				 rhs ? rhs->dup (scope, context) : 0,
+				 preserve, etype);
+
+  new_ma->copy_base (*this);
+
+  return new_ma;
+}
+
+void
+tree_multi_assignment::accept (tree_walker& tw)
+{
+  tw.visit_multi_assignment (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-assign.h b/src/pt-assign.h
new file mode 100644
index 0000000..e145af0
--- /dev/null
+++ b/src/pt-assign.h
@@ -0,0 +1,185 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_assign_h)
+#define octave_tree_assign_h 1
+
+#include <iosfwd>
+#include <string>
+
+class tree_argument_list;
+class tree_walker;
+
+class octave_value;
+class octave_value_list;
+class octave_lvalue;
+
+#include "ov.h"
+#include "pt-exp.h"
+#include "symtab.h"
+
+// Simple assignment expressions.
+
+class
+tree_simple_assignment : public tree_expression
+{
+public:
+
+  tree_simple_assignment (bool plhs = false, int l = -1, int c = -1,
+			  octave_value::assign_op t = octave_value::op_asn_eq)
+    : tree_expression (l, c), lhs (0), rhs (0), preserve (plhs), etype (t),
+      first_execution (true) { }
+
+  tree_simple_assignment (tree_expression *le, tree_expression *re,
+			  bool plhs = false, int l = -1, int c = -1,
+			  octave_value::assign_op t = octave_value::op_asn_eq);
+
+  ~tree_simple_assignment (void);
+
+  bool has_magic_end (void) const { return (rhs && rhs->has_magic_end ()); }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  bool is_assignment_expression (void) const { return true; }
+
+  std::string oper (void) const;
+
+  tree_expression *left_hand_side (void) { return lhs; }
+
+  tree_expression *right_hand_side (void) { return rhs; }
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  octave_value::assign_op op_type (void) const { return etype; }
+
+private:
+
+  void do_assign (octave_lvalue& ult, const octave_value_list& args,
+		  const octave_value& rhs_val);
+
+  void do_assign (octave_lvalue& ult, const octave_value& rhs_val);
+
+  // The left hand side of the assignment.
+  tree_expression *lhs;
+
+  // The right hand side of the assignment.
+  tree_expression *rhs;
+
+  // True if we should not delete the lhs.
+  bool preserve;
+
+  // True if this is an assignment to the automatic variable ans.
+  bool ans_ass;
+
+  // The type of the expression.
+  octave_value::assign_op etype;
+
+  // true only on first rvalue() call.
+  bool first_execution;
+
+  // No copying!
+
+  tree_simple_assignment (const tree_simple_assignment&);
+
+  tree_simple_assignment& operator = (const tree_simple_assignment&);
+};
+
+// Multi-valued assignment expressions.
+
+class
+tree_multi_assignment : public tree_expression
+{
+public:
+
+  tree_multi_assignment (bool plhs = false, int l = -1, int c = -1,
+			 octave_value::assign_op t = octave_value::op_asn_eq)
+    : tree_expression (l, c), lhs (0), rhs (0), preserve (plhs), etype(t),
+      first_execution (true) { }
+
+  tree_multi_assignment (tree_argument_list *lst, tree_expression *r,
+			 bool plhs = false, int l = -1, int c = -1,
+			 octave_value::assign_op t = octave_value::op_asn_eq);
+
+  ~tree_multi_assignment (void);
+
+  bool has_magic_end (void) const { return (rhs && rhs->has_magic_end ()); }
+
+  bool is_assignment_expression (void) const { return true; }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  std::string oper (void) const;
+
+  tree_argument_list *left_hand_side (void) { return lhs; }
+
+  tree_expression *right_hand_side (void) { return rhs; }
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+  
+  octave_value::assign_op op_type (void) const { return etype; }
+
+private:
+
+  // The left hand side of the assignment.
+  tree_argument_list *lhs;
+
+  // The right hand side of the assignment.
+  tree_expression *rhs;
+
+  // True if we should not delete the lhs.
+  bool preserve;
+
+  // The type of the expression.
+  octave_value::assign_op etype;
+
+  // true only on first rvalue() call.
+  bool first_execution;
+
+  // No copying!
+
+  tree_multi_assignment (const tree_multi_assignment&);
+
+  tree_multi_assignment& operator = (const tree_multi_assignment&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-binop.cc b/src/pt-binop.cc
new file mode 100644
index 0000000..7e9d683
--- /dev/null
+++ b/src/pt-binop.cc
@@ -0,0 +1,215 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "pt-binop.h"
+#include "pt-bp.h"
+#include "pt-walk.h"
+
+// Binary expressions.
+ 
+octave_value_list
+tree_binary_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("binary operator `%s': invalid number of output arguments",
+	   oper () . c_str ());
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_binary_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  if (op_lhs)
+    {
+      octave_value a = op_lhs->rvalue1 ();
+
+      if (! error_state && a.is_defined () && op_rhs)
+	{
+	  octave_value b = op_rhs->rvalue1 ();
+
+	  if (! error_state && b.is_defined ())
+	    {
+	      retval = ::do_binary_op (etype, a, b);
+
+	      if (error_state)
+		retval = octave_value ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+std::string
+tree_binary_expression::oper (void) const
+{
+  return octave_value::binary_op_as_string (etype);
+}
+
+tree_expression *
+tree_binary_expression::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context) const
+{
+  tree_binary_expression *new_be
+    = new tree_binary_expression (op_lhs ? op_lhs->dup (scope, context) : 0,
+				  op_rhs ? op_rhs->dup (scope, context) : 0,
+				  line (), column (), etype);
+
+  new_be->copy_base (*this);
+
+  return new_be;
+}
+
+void
+tree_binary_expression::accept (tree_walker& tw)
+{
+  tw.visit_binary_expression (*this);
+}
+
+// Boolean expressions.
+ 
+octave_value_list
+tree_boolean_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("binary operator `%s': invalid number of output arguments",
+	   oper () . c_str ());
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_boolean_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  bool result = false;
+
+  if (op_lhs)
+    {
+      octave_value a = op_lhs->rvalue1 ();
+
+      if (! error_state)
+	{
+	  bool a_true = a.is_true ();
+
+	  if (! error_state)
+	    {
+	      if (a_true)
+		{
+		  if (etype == bool_or)
+		    {
+		      result = true;
+		      goto done;
+		    }
+		}
+	      else
+		{
+		  if (etype == bool_and)
+		    goto done;
+		}
+
+	      if (op_rhs)
+		{
+		  octave_value b = op_rhs->rvalue1 ();
+
+		  if (! error_state)
+		    result = b.is_true ();
+		}
+
+	    done:
+
+	      if (! error_state)
+		retval = octave_value (result);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+std::string
+tree_boolean_expression::oper (void) const
+{
+  std::string retval = "<unknown>";
+
+  switch (etype)
+    {
+    case bool_and:
+      retval = "&&";
+      break;
+
+    case bool_or:
+      retval = "||";
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
+}
+
+tree_expression *
+tree_boolean_expression::dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context) const
+{
+  tree_boolean_expression *new_be
+    = new tree_boolean_expression (op_lhs ? op_lhs->dup (scope, context) : 0,
+				   op_rhs ? op_rhs->dup (scope, context) : 0,
+				   line (), column (), etype);
+
+  new_be->copy_base (*this);
+
+  return new_be;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-binop.h b/src/pt-binop.h
new file mode 100644
index 0000000..3b496a3
--- /dev/null
+++ b/src/pt-binop.h
@@ -0,0 +1,163 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_binop_h)
+#define octave_tree_binop_h 1
+
+#include <string>
+
+class tree_walker;
+
+class octave_value;
+class octave_value_list;
+class octave_lvalue;
+
+#include "ov.h"
+#include "pt-exp.h"
+#include "symtab.h"
+
+// Binary expressions.
+
+class
+tree_binary_expression : public tree_expression
+{
+public:
+
+  tree_binary_expression (int l = -1, int c = -1,
+			  octave_value::binary_op t
+			    = octave_value::unknown_binary_op)
+    : tree_expression (l, c), op_lhs (0), op_rhs (0), etype (t) { }
+
+  tree_binary_expression (tree_expression *a, tree_expression *b,
+			  int l = -1, int c = -1,
+			  octave_value::binary_op t
+			    = octave_value::unknown_binary_op)
+    : tree_expression (l, c), op_lhs (a), op_rhs (b), etype (t) { }
+
+  ~tree_binary_expression (void)
+    {
+      delete op_lhs;
+      delete op_rhs;
+    }
+
+  bool has_magic_end (void) const
+    {
+      return ((op_lhs && op_lhs->has_magic_end ())
+	      || (op_rhs && op_rhs->has_magic_end ()));
+    }
+
+  bool is_binary_expression (void) const { return true; }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  std::string oper (void) const;
+
+  octave_value::binary_op op_type (void) const { return etype; }
+
+  tree_expression *lhs (void) { return op_lhs; }
+  tree_expression *rhs (void) { return op_rhs; }
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+protected:
+
+  // The operands for the expression.
+  tree_expression *op_lhs;
+  tree_expression *op_rhs;
+
+private:
+
+  // The type of the expression.
+  octave_value::binary_op etype;
+
+  // No copying!
+
+  tree_binary_expression (const tree_binary_expression&);
+
+  tree_binary_expression& operator = (const tree_binary_expression&);
+};
+
+// Boolean expressions.
+
+class
+tree_boolean_expression : public tree_binary_expression
+{
+public:
+
+  enum type
+    {
+      unknown,
+      bool_and,
+      bool_or
+    };
+
+  tree_boolean_expression (int l = -1, int c = -1, type t = unknown)
+    : tree_binary_expression (l, c), etype (t) { }
+
+  tree_boolean_expression (tree_expression *a, tree_expression *b,
+			   int l = -1, int c = -1, type t = unknown)
+    : tree_binary_expression (a, b, l, c), etype (t) { }
+
+  ~tree_boolean_expression (void) { }
+
+  bool is_boolean_expression (void) const { return true; }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  std::string oper (void) const;
+
+  type op_type (void) const { return etype; }
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+private:
+
+  // The type of the expression.
+  type etype;
+
+  // No copying!
+
+  tree_boolean_expression (const tree_boolean_expression&);
+
+  tree_boolean_expression& operator = (const tree_boolean_expression&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-bp.cc b/src/pt-bp.cc
new file mode 100644
index 0000000..41a2633
--- /dev/null
+++ b/src/pt-bp.cc
@@ -0,0 +1,502 @@
+/*
+
+Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Ben Sapp
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov-usr-fcn.h"
+#include "ov-list.h"
+#include "pager.h"
+#include "pt-all.h"
+
+// TRUE means SIGINT should put us in the debugger at the next
+// available breakpoint.
+bool octave_debug_on_interrupt_state = false;
+
+void
+tree_breakpoint::visit_while_command (tree_while_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+
+  if (! found)
+    {
+      tree_statement_list *lst = cmd.body ();
+
+      if (lst)
+	lst->accept (*this);
+    }
+}
+
+void
+tree_breakpoint::visit_do_until_command (tree_do_until_command& cmd)
+{
+  if (! found)
+    {
+      tree_statement_list *lst = cmd.body ();
+
+      if (lst)
+	lst->accept (*this);
+
+      if (! found)
+	{
+	  if (cmd.line () >= line)
+	    take_action (cmd);
+	}
+    }
+}
+
+void
+tree_breakpoint::visit_argument_list (tree_argument_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_binary_expression (tree_binary_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_break_command (tree_break_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+}
+
+void
+tree_breakpoint::visit_colon_expression (tree_colon_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_continue_command (tree_continue_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+}
+
+void
+tree_breakpoint::do_decl_command (tree_decl_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+}
+
+void
+tree_breakpoint::visit_global_command (tree_global_command& cmd)
+{
+  do_decl_command (cmd);
+}
+
+void
+tree_breakpoint::visit_static_command (tree_static_command& cmd)
+{
+  do_decl_command (cmd);
+}
+
+void
+tree_breakpoint::visit_decl_elt (tree_decl_elt&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_decl_init_list (tree_decl_init_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_simple_for_command (tree_simple_for_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+
+  if (! found)
+    {
+      tree_statement_list *lst = cmd.body ();
+
+      if (lst)
+	lst->accept (*this);
+    }
+}
+
+void
+tree_breakpoint::visit_complex_for_command (tree_complex_for_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+
+  if (! found)
+    {
+      tree_statement_list *lst = cmd.body ();
+
+      if (lst)
+	lst->accept (*this);
+    }
+}
+
+void
+tree_breakpoint::visit_octave_user_script (octave_user_script& fcn)
+{
+  tree_statement_list *cmd_list = fcn.body ();
+
+  if (cmd_list)
+    cmd_list->accept (*this);
+}
+
+void
+tree_breakpoint::visit_octave_user_function (octave_user_function& fcn)
+{
+  tree_statement_list *cmd_list = fcn.body ();
+
+  if (cmd_list)
+    cmd_list->accept (*this);
+}
+
+void
+tree_breakpoint::visit_octave_user_function_header (octave_user_function&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_octave_user_function_trailer (octave_user_function&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_function_def (tree_function_def& fdef)
+{
+  octave_value fcn = fdef.function ();
+
+  octave_function *f = fcn.function_value ();
+
+  if (f)
+    f->accept (*this);
+}
+
+void
+tree_breakpoint::visit_identifier (tree_identifier&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_if_clause (tree_if_clause&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_if_command (tree_if_command& cmd)
+{
+  tree_if_command_list *lst = cmd.cmd_list ();
+
+  if (lst)
+    lst->accept (*this);
+}
+
+void
+tree_breakpoint::visit_if_command_list (tree_if_command_list& lst)
+{
+  for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++)
+    {
+      tree_if_clause *t = *p;
+
+      if (t->line () >= line)
+	take_action (*t);
+
+      if (! found)
+	{      
+	  tree_statement_list *stmt_lst = t->commands ();
+
+	  if (stmt_lst)
+	    stmt_lst->accept (*this);
+	}
+
+      if (found)
+	break;
+    }
+}
+
+void
+tree_breakpoint::visit_index_expression (tree_index_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_matrix (tree_matrix&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_cell (tree_cell&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_multi_assignment (tree_multi_assignment&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_no_op_command (tree_no_op_command&)
+{
+}
+
+void
+tree_breakpoint::visit_anon_fcn_handle (tree_anon_fcn_handle&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_constant (tree_constant&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_fcn_handle (tree_fcn_handle&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_parameter_list (tree_parameter_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_postfix_expression (tree_postfix_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_prefix_expression (tree_prefix_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_return_command (tree_return_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+}
+
+void
+tree_breakpoint::visit_return_list (tree_return_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_simple_assignment (tree_simple_assignment&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_statement (tree_statement& stmt)
+{
+  if (stmt.line () >= line)
+    {
+      take_action (stmt);
+    }
+  else if (stmt.is_command ())
+    {
+      tree_command *cmd = stmt.command ();
+
+      cmd->accept (*this);
+    }
+
+  // There is no need to do anything for expressions because they
+  // can't contain additional lists of statements.
+}
+
+void
+tree_breakpoint::visit_statement_list (tree_statement_list& lst)
+{
+  for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
+    {
+      tree_statement *elt = *p;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (found)
+	    break;
+	}
+    }
+}
+
+void
+tree_breakpoint::visit_switch_case (tree_switch_case&)
+{
+  panic_impossible ();
+}
+
+void
+tree_breakpoint::visit_switch_case_list (tree_switch_case_list& lst)
+{
+  for (tree_switch_case_list::iterator p = lst.begin (); p != lst.end (); p++)
+    {
+      tree_switch_case *t = *p;
+
+      if (t->line () >= line)
+	take_action (*t);
+
+      if (! found)
+	{
+	  tree_statement_list *stmt_lst = t->commands ();
+
+	  if (stmt_lst)
+	    stmt_lst->accept (*this);
+	}
+
+      if (found)
+	break;
+    }
+}
+
+void
+tree_breakpoint::visit_switch_command (tree_switch_command& cmd)
+{
+  if (cmd.line () >= line)
+    take_action (cmd);
+
+  if (! found)
+    {
+      tree_switch_case_list *lst = cmd.case_list ();
+
+      if (lst)
+	lst->accept (*this);
+    }
+}
+
+void
+tree_breakpoint::visit_try_catch_command (tree_try_catch_command& cmd)
+{
+  tree_statement_list *try_code = cmd.body ();
+
+  if (try_code)
+    try_code->accept (*this);
+
+  if (! found)
+    {
+      tree_statement_list *catch_code = cmd.cleanup ();
+
+      if (catch_code)
+	catch_code->accept (*this);
+    }
+}
+
+void
+tree_breakpoint::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
+{
+  tree_statement_list *body = cmd.body ();
+
+  if (body)
+    body->accept (*this);
+
+  if (! found)
+    {
+      tree_statement_list *cleanup = cmd.cleanup ();
+
+      if (cleanup)
+	cleanup->accept (*this);
+    }
+}
+
+void
+tree_breakpoint::take_action (tree& tr)
+{
+  if (act == set)
+    {
+      tr.set_breakpoint ();
+      line = tr.line ();
+      found = true;
+    }
+  else if (act == clear)
+    {
+      tr.delete_breakpoint ();
+      found = true;
+    }
+  else if (act == list)
+    {
+      if (tr.is_breakpoint ())
+	{
+	  bp_list.append (octave_value (tr.line ()));
+	  line = tr.line () + 1;
+	}
+    }
+  else
+    panic_impossible ();
+}
+
+void
+tree_breakpoint::take_action (tree_statement& stmt)
+{
+  int lineno = stmt.line ();
+
+  if (act == set)
+    {
+      stmt.set_breakpoint ();
+      line = lineno;
+      found = true;
+    }
+  else if (act == clear)
+    {
+      stmt.delete_breakpoint ();
+      found = true;
+    }
+  else if (act == list)
+    {
+      if (stmt.is_breakpoint ())
+	{
+	  bp_list.append (octave_value (lineno));
+	  line = lineno + 1;
+	}
+    }
+  else
+    panic_impossible ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-bp.h b/src/pt-bp.h
new file mode 100644
index 0000000..d68e3a9
--- /dev/null
+++ b/src/pt-bp.h
@@ -0,0 +1,176 @@
+/*
+
+Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Ben Sapp
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_bp_h)
+#define octave_tree_bp_h 1
+
+#include "input.h"
+#include "ov-usr-fcn.h"
+#include "pt-walk.h"
+#include "pt-pr-code.h"
+#include "toplev.h"
+
+class tree;
+class tree_decl_command;
+
+class
+tree_breakpoint : public tree_walker
+{
+ public:
+
+  enum action { set = 1, clear = 2, list = 3 };
+
+  tree_breakpoint (int l, action a)
+    : line (l), act (a), found (false), bp_list () { }
+
+  ~tree_breakpoint (void) { }
+
+  bool success (void) const { return found; }
+
+  void visit_argument_list (tree_argument_list&);
+
+  void visit_binary_expression (tree_binary_expression&);
+
+  void visit_break_command (tree_break_command&);
+
+  void visit_colon_expression (tree_colon_expression&);
+
+  void visit_continue_command (tree_continue_command&);
+
+  void visit_global_command (tree_global_command&);
+
+  void visit_static_command (tree_static_command&);
+
+  void visit_decl_elt (tree_decl_elt&);
+
+  void visit_decl_init_list (tree_decl_init_list&);  
+
+  void visit_while_command (tree_while_command&);
+
+  void visit_do_until_command (tree_do_until_command&);
+
+  void visit_simple_for_command (tree_simple_for_command&);
+
+  void visit_complex_for_command (tree_complex_for_command&);
+
+  void visit_octave_user_script (octave_user_script&);
+
+  void visit_octave_user_function (octave_user_function&);
+
+  void visit_octave_user_function_header (octave_user_function&);
+
+  void visit_octave_user_function_trailer (octave_user_function&);
+
+  void visit_function_def (tree_function_def&);
+
+  void visit_identifier (tree_identifier&);
+
+  void visit_if_clause (tree_if_clause&);
+
+  void visit_if_command (tree_if_command&);
+
+  void visit_if_command_list (tree_if_command_list&);
+
+  void visit_index_expression (tree_index_expression&);
+
+  void visit_matrix (tree_matrix&);
+
+  void visit_cell (tree_cell&);
+
+  void visit_multi_assignment (tree_multi_assignment&);
+
+  void visit_no_op_command (tree_no_op_command&);
+
+  void visit_anon_fcn_handle (tree_anon_fcn_handle&);
+
+  void visit_constant (tree_constant&);
+
+  void visit_fcn_handle (tree_fcn_handle&);
+
+  void visit_parameter_list (tree_parameter_list&);
+
+  void visit_postfix_expression (tree_postfix_expression&);
+
+  void visit_prefix_expression (tree_prefix_expression&);
+
+  void visit_return_command (tree_return_command&);
+
+  void visit_return_list (tree_return_list&);
+
+  void visit_simple_assignment (tree_simple_assignment&);
+
+  void visit_statement (tree_statement&);
+
+  void visit_statement_list (tree_statement_list&);
+
+  void visit_switch_case (tree_switch_case&);
+
+  void visit_switch_case_list (tree_switch_case_list&);
+
+  void visit_switch_command (tree_switch_command&);
+
+  void visit_try_catch_command (tree_try_catch_command&);
+
+  void visit_unwind_protect_command (tree_unwind_protect_command&);
+
+  octave_value_list get_list (void) { return bp_list; }
+  
+  int get_line (void) { return line; }
+
+ private:
+
+  void do_decl_command (tree_decl_command&);
+
+  void take_action (tree& tr);
+
+  void take_action (tree_statement& stmt);
+
+  // Statement line number we are looking for.
+  int line;
+
+  // What to do.
+  action act;
+
+  // Have we already found the line?
+  bool found;
+
+  // List of breakpoint line numbers.
+  octave_value_list bp_list;
+
+  // No copying!
+
+  tree_breakpoint (const tree_breakpoint&);
+
+  tree_breakpoint& operator = (const tree_breakpoint&);
+};
+
+// TRUE means SIGINT should put us in the debugger at the next
+// available breakpoint.
+extern bool octave_debug_on_interrupt_state;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-cbinop.cc b/src/pt-cbinop.cc
new file mode 100644
index 0000000..8858002
--- /dev/null
+++ b/src/pt-cbinop.cc
@@ -0,0 +1,201 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "pt-cbinop.h"
+#include "pt-bp.h"
+#include "pt-unop.h"
+#include "pt-walk.h"
+
+// If a tree expression is a transpose or hermitian transpose, return
+// the argument and corresponding operator.
+
+static octave_value::unary_op 
+strip_trans_herm (tree_expression *&exp)
+{
+  if (exp->is_unary_expression ())
+    {
+      tree_unary_expression *uexp = 
+        dynamic_cast<tree_unary_expression *> (exp);
+
+      octave_value::unary_op op = uexp->op_type ();
+
+      if (op == octave_value::op_transpose
+          || op == octave_value::op_hermitian)
+	exp = uexp->operand ();
+      else
+	op = octave_value::unknown_unary_op;
+
+      return op;
+    }
+  else
+    return octave_value::unknown_unary_op;
+}
+
+static octave_value::unary_op 
+strip_not (tree_expression *&exp)
+{
+  if (exp->is_unary_expression ())
+    {
+      tree_unary_expression *uexp = 
+        dynamic_cast<tree_unary_expression *> (exp);
+
+      octave_value::unary_op op = uexp->op_type ();
+
+      if (op == octave_value::op_not)
+	exp = uexp->operand ();
+      else
+	op = octave_value::unknown_unary_op;
+
+      return op;
+    }
+  else
+    return octave_value::unknown_unary_op;
+}
+
+// Possibly convert multiplication to trans_mul, mul_trans, herm_mul,
+// or mul_herm.
+
+static octave_value::compound_binary_op
+simplify_mul_op (tree_expression *&a, tree_expression *&b)
+{
+  octave_value::compound_binary_op retop;
+  octave_value::unary_op opa = strip_trans_herm (a);
+
+  if (opa == octave_value::op_hermitian)
+    retop = octave_value::op_herm_mul;
+  else if (opa == octave_value::op_transpose)
+    retop = octave_value::op_trans_mul;
+  else
+    {
+      octave_value::unary_op opb = strip_trans_herm (b);
+
+      if (opb == octave_value::op_hermitian)
+        retop = octave_value::op_mul_herm;
+      else if (opb == octave_value::op_transpose)
+        retop = octave_value::op_mul_trans;
+      else
+        retop = octave_value::unknown_compound_binary_op;
+    }
+
+  return retop;
+}
+
+// Possibly contract and/or with negation.
+
+static octave_value::compound_binary_op
+simplify_and_or_op (tree_expression *&a, tree_expression *&b, octave_value::binary_op op)
+{
+  octave_value::compound_binary_op retop;
+  octave_value::unary_op opa = strip_not (a);
+
+  if (opa == octave_value::op_not)
+    {
+      if (op == octave_value::op_el_and)
+        retop = octave_value::op_el_not_and;
+      else if (op == octave_value::op_el_or)
+        retop = octave_value::op_el_not_or;
+    }
+  else
+    {
+      octave_value::unary_op opb = strip_not (b);
+
+      if (opb == octave_value::op_not)
+        {
+          if (op == octave_value::op_el_and)
+            retop = octave_value::op_el_and_not;
+          else if (op == octave_value::op_el_or)
+            retop = octave_value::op_el_or_not;
+        }
+      else
+        retop = octave_value::unknown_compound_binary_op;
+    }
+
+  return retop;
+}
+
+tree_binary_expression *
+maybe_compound_binary_expression (tree_expression *a, tree_expression *b,
+                                  int l, int c, octave_value::binary_op t)
+{
+  tree_expression *ca = a, *cb = b;
+  octave_value::compound_binary_op ct;
+
+  switch (t)
+    {
+    case octave_value::op_mul:
+      ct = simplify_mul_op (ca, cb);
+      break;
+
+    case octave_value::op_el_and:
+    case octave_value::op_el_or:
+      ct = simplify_and_or_op (ca, cb, t);
+      break;
+
+    default:
+      ct = octave_value::unknown_compound_binary_op;
+      break;
+    }
+
+  tree_binary_expression *ret = (ct == octave_value::unknown_compound_binary_op)
+    ? new tree_binary_expression (a, b, l, c, t)
+    : new tree_compound_binary_expression (a, b, l, c, t, ca, cb, ct);
+
+  return ret;
+}
+
+octave_value
+tree_compound_binary_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  if (op_lhs)
+    {
+      octave_value a = op_lhs->rvalue1 ();
+
+      if (! error_state && a.is_defined () && op_rhs)
+	{
+	  octave_value b = op_rhs->rvalue1 ();
+
+	  if (! error_state && b.is_defined ())
+	    {
+	      retval = ::do_binary_op (etype, a, b);
+
+	      if (error_state)
+		retval = octave_value ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+
diff --git a/src/pt-cbinop.h b/src/pt-cbinop.h
new file mode 100644
index 0000000..3bb87ff
--- /dev/null
+++ b/src/pt-cbinop.h
@@ -0,0 +1,78 @@
+/*
+
+Copyright (C) 2008, 2009 Jaroslav Hajek
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_cbinop_h)
+#define octave_tree_cbinop_h 1
+
+#include <string>
+
+class tree_walker;
+
+class octave_value;
+class octave_value_list;
+class octave_lvalue;
+
+#include "ov.h"
+#include "pt-binop.h"
+#include "symtab.h"
+
+// Binary expressions that can be reduced to compound operations
+
+class
+tree_compound_binary_expression : public tree_binary_expression
+{
+public:
+
+  tree_compound_binary_expression (tree_expression *a, tree_expression *b,
+                                   int l, int c,
+                                   octave_value::binary_op t,
+                                   tree_expression *ca, tree_expression *cb,
+                                   octave_value::compound_binary_op ct)
+    : tree_binary_expression (a, b, l, c, t), op_lhs (ca), op_rhs (cb),
+      etype (ct) { }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value::compound_binary_op cop_type (void) const { return etype; }
+
+private:
+
+  tree_expression *op_lhs;
+  tree_expression *op_rhs;
+  octave_value::compound_binary_op etype;
+};
+
+// a "virtual constructor"
+
+tree_binary_expression *
+maybe_compound_binary_expression (tree_expression *a, tree_expression *b,
+                                  int l = -1, int c = -1,
+                                  octave_value::binary_op t
+                                  = octave_value::unknown_binary_op);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-cell.cc b/src/pt-cell.cc
new file mode 100644
index 0000000..e3e6299
--- /dev/null
+++ b/src/pt-cell.cc
@@ -0,0 +1,133 @@
+/*
+
+Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "pt-arg-list.h"
+#include "pt-bp.h"
+#include "pt-exp.h"
+#include "pt-cell.h"
+#include "pt-walk.h"
+#include "utils.h"
+#include "ov.h"
+#include "variables.h"
+
+octave_value
+tree_cell::rvalue1 (int)
+{
+  octave_value retval;
+
+  octave_idx_type nr = length ();
+  octave_idx_type nc = -1;
+
+  Cell val;
+
+  int i = 0;
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      tree_argument_list *elt = *p;
+
+      octave_value_list row = elt->convert_to_const_vector ();
+      
+      if (nr == 1)
+        // Optimize the single row case.
+        val = row.cell_value ();
+      else if (nc < 0)
+	{
+	  nc = row.length ();
+
+	  val = Cell (nr, nc);
+	}
+      else
+	{
+	  octave_idx_type this_nc = row.length ();
+
+	  if (nc != this_nc)
+	    {
+	      ::error ("number of columns must match");
+	      return retval;
+	    }
+	}
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	val(i,j) = row(j);
+
+      i++;
+    }
+
+  retval = val;
+
+  return retval;
+}
+
+octave_value_list
+tree_cell::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for cell array");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+tree_expression *
+tree_cell::dup (symbol_table::scope_id scope,
+		symbol_table::context_id context) const
+{
+  tree_cell *new_cell = new tree_cell (0, line (), column ());
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_argument_list *elt = *p;
+
+      new_cell->append (elt ? elt->dup (scope, context) : 0);
+    }
+
+  new_cell->copy_base (*this);
+
+  return new_cell;
+}
+
+void
+tree_cell::accept (tree_walker& tw)
+{
+  tw.visit_cell (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-cell.h b/src/pt-cell.h
new file mode 100644
index 0000000..1e75c5b
--- /dev/null
+++ b/src/pt-cell.h
@@ -0,0 +1,76 @@
+/*
+
+Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_cell_h)
+#define octave_tree_cell_h 1
+
+#include <iosfwd>
+
+class octave_value;
+class octave_value_list;
+class tree_argument_list;
+
+class tree_walker;
+
+#include "pt-mat.h"
+#include "symtab.h"
+
+// General cells.
+
+class
+tree_cell : public tree_matrix
+{
+public:
+
+  tree_cell (tree_argument_list *row = 0, int l = -1, int c = -1)
+    : tree_matrix (row, l, c) { }
+
+  ~tree_cell (void) { }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int);
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_cell (const tree_cell&);
+
+  tree_cell& operator = (const tree_cell&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-check.cc b/src/pt-check.cc
new file mode 100644
index 0000000..eef2c15
--- /dev/null
+++ b/src/pt-check.cc
@@ -0,0 +1,563 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "input.h"
+#include "ov-usr-fcn.h"
+#include "pt-all.h"
+
+void
+tree_checker::visit_argument_list (tree_argument_list& lst)
+{
+  tree_argument_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_expression *elt = *p++;
+
+      if (elt)
+	{
+	  if (do_lvalue_check && ! elt->lvalue_ok ())
+	    gripe ("invalid lvalue in multiple assignment", elt->line ());
+	}
+    }
+}
+
+void
+tree_checker::visit_binary_expression (tree_binary_expression& expr)
+{
+  tree_expression *op1 = expr.lhs ();
+
+  if (op1)
+    op1->accept (*this);
+
+  tree_expression *op2 = expr.rhs ();
+
+  if (op2)
+    op2->accept (*this);
+}
+
+void
+tree_checker::visit_break_command (tree_break_command&)
+{
+}
+
+void
+tree_checker::visit_colon_expression (tree_colon_expression& expr)
+{
+  tree_expression *op1 = expr.base ();
+
+  if (op1)
+    op1->accept (*this);
+
+  tree_expression *op3 = expr.increment ();
+
+  if (op3)
+    op3->accept (*this);
+
+  tree_expression *op2 = expr.limit ();
+
+  if (op2)
+    op2->accept (*this);
+}
+
+void
+tree_checker::visit_continue_command (tree_continue_command&)
+{
+}
+
+void
+tree_checker::do_decl_command (tree_decl_command& cmd)
+{
+  tree_decl_init_list *init_list = cmd.initializer_list ();
+
+  if (init_list)
+    init_list->accept (*this);
+}
+
+void
+tree_checker::visit_global_command (tree_global_command& cmd)
+{
+  do_decl_command (cmd);
+}
+
+void
+tree_checker::visit_static_command (tree_static_command& cmd)
+{
+  do_decl_command (cmd);
+}
+
+void
+tree_checker::visit_decl_elt (tree_decl_elt& cmd)
+{
+  tree_identifier *id = cmd.ident ();
+
+  if (id)
+    id->accept (*this);
+
+  tree_expression *expr = cmd.expression ();
+
+  if (expr)
+    expr->accept (*this);
+}
+
+void
+tree_checker::visit_decl_init_list (tree_decl_init_list& lst)
+{
+  tree_decl_init_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_decl_elt *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_simple_for_command (tree_simple_for_command& cmd)
+{
+  tree_expression *lhs = cmd.left_hand_side ();
+
+  if (lhs)
+    {
+      if (! lhs->lvalue_ok ())
+	gripe ("invalid lvalue in for command", cmd.line ());
+    }
+
+  tree_expression *expr = cmd.control_expr ();
+
+  if (expr)
+    expr->accept (*this);
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_complex_for_command (tree_complex_for_command& cmd)
+{
+  tree_argument_list *lhs = cmd.left_hand_side ();
+
+  if (lhs)
+    {
+      int len = lhs->length ();
+
+      if (len == 0 || len > 2)
+	gripe ("invalid number of output arguments in for command",
+	       cmd.line ());
+
+      do_lvalue_check = true;
+
+      lhs->accept (*this);
+
+      do_lvalue_check = false;
+    }
+
+  tree_expression *expr = cmd.control_expr ();
+
+  if (expr)
+    expr->accept (*this);
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_octave_user_script (octave_user_script& fcn)
+{
+  tree_statement_list *cmd_list = fcn.body ();
+
+  if (cmd_list)
+    cmd_list->accept (*this);
+}
+
+void
+tree_checker::visit_octave_user_function (octave_user_function& fcn)
+{
+  tree_statement_list *cmd_list = fcn.body ();
+
+  if (cmd_list)
+    cmd_list->accept (*this);
+}
+
+void
+tree_checker::visit_function_def (tree_function_def& fdef)
+{
+  octave_value fcn = fdef.function ();
+
+  octave_function *f = fcn.function_value ();
+
+  if (f)
+    f->accept (*this);
+}
+
+void
+tree_checker::visit_identifier (tree_identifier& /* id */)
+{
+}
+
+void
+tree_checker::visit_if_clause (tree_if_clause& cmd)
+{
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  tree_statement_list *list = cmd.commands ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_if_command (tree_if_command& cmd)
+{
+  tree_if_command_list *list = cmd.cmd_list ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_if_command_list (tree_if_command_list& lst)
+{
+  tree_if_command_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_if_clause *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_index_expression (tree_index_expression& expr)
+{
+  tree_expression *e = expr.expression ();
+
+  if (e)
+    e->accept (*this);
+
+  std::list<tree_argument_list *> lst = expr.arg_lists ();
+
+  std::list<tree_argument_list *>::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_argument_list *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_matrix (tree_matrix& lst)
+{
+  tree_matrix::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_argument_list *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_cell (tree_cell& lst)
+{
+  tree_matrix::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_argument_list *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_multi_assignment (tree_multi_assignment& expr)
+{
+  tree_argument_list *lhs = expr.left_hand_side ();
+
+  if (lhs)
+    {
+      do_lvalue_check = true;
+
+      lhs->accept (*this);
+
+      do_lvalue_check = false;
+    }
+
+  tree_expression *rhs = expr.right_hand_side ();
+
+  if (rhs)
+    rhs->accept (*this);
+}
+
+void
+tree_checker::visit_no_op_command (tree_no_op_command& /* cmd */)
+{
+}
+
+void
+tree_checker::visit_anon_fcn_handle (tree_anon_fcn_handle& /* afh */)
+{
+}
+
+void
+tree_checker::visit_constant (tree_constant& /* val */)
+{
+}
+
+void
+tree_checker::visit_fcn_handle (tree_fcn_handle& /* fh */)
+{
+}
+
+void
+tree_checker::visit_parameter_list (tree_parameter_list& lst)
+{
+  tree_parameter_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_decl_elt *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_postfix_expression (tree_postfix_expression& expr)
+{
+  tree_expression *e = expr.operand ();
+
+  if (e)
+    e->accept (*this);
+}
+
+void
+tree_checker::visit_prefix_expression (tree_prefix_expression& expr)
+{
+  tree_expression *e = expr.operand ();
+
+  if (e)
+    e->accept (*this);
+}
+
+void
+tree_checker::visit_return_command (tree_return_command&)
+{
+}
+
+void
+tree_checker::visit_return_list (tree_return_list& lst)
+{
+  tree_return_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_index_expression *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_simple_assignment (tree_simple_assignment& expr)
+{
+  tree_expression *lhs = expr.left_hand_side ();
+
+  if (lhs)
+    {
+      if (! lhs->lvalue_ok ())
+	gripe ("invalid lvalue in assignment", expr.line ());
+    }
+
+  tree_expression *rhs = expr.right_hand_side ();
+
+  if (rhs)
+    rhs->accept (*this);
+}
+
+void
+tree_checker::visit_statement (tree_statement& stmt)
+{
+  tree_command *cmd = stmt.command ();
+
+  if (cmd)
+    cmd->accept (*this);
+  else
+    {
+      tree_expression *expr = stmt.expression ();
+
+      if (expr)
+	expr->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_statement_list (tree_statement_list& lst)
+{
+  for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
+    {
+      tree_statement *elt = *p;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_switch_case (tree_switch_case& cs)
+{
+  tree_expression *label = cs.case_label ();
+
+  if (label)
+    label->accept (*this);
+
+  tree_statement_list *list = cs.commands ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_switch_case_list (tree_switch_case_list& lst)
+{
+  tree_switch_case_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_switch_case *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_checker::visit_switch_command (tree_switch_command& cmd)
+{
+  tree_expression *expr = cmd.switch_value ();
+
+  if (expr)
+    expr->accept (*this);
+
+  tree_switch_case_list *list = cmd.case_list ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_try_catch_command (tree_try_catch_command& cmd)
+{
+  tree_statement_list *try_code = cmd.body ();
+
+  if (try_code)
+    try_code->accept (*this);
+
+  tree_statement_list *catch_code = cmd.cleanup ();
+
+  if (catch_code)
+    catch_code->accept (*this);
+}
+
+void
+tree_checker::visit_unwind_protect_command
+  (tree_unwind_protect_command& cmd)
+{
+  tree_statement_list *unwind_protect_code = cmd.body ();
+
+  if (unwind_protect_code)
+    unwind_protect_code->accept (*this);
+
+  tree_statement_list *cleanup_code = cmd.cleanup ();
+
+  if (cleanup_code)
+    cleanup_code->accept (*this);
+}
+
+void
+tree_checker::visit_while_command (tree_while_command& cmd)
+{
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    list->accept (*this);
+}
+
+void
+tree_checker::visit_do_until_command (tree_do_until_command& cmd)
+{
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    list->accept (*this);
+
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+}
+
+void
+tree_checker::gripe (const std::string& msg, int line)
+{
+  if (curr_fcn_file_name.empty ())
+    error ("%s", msg.c_str ());
+  else
+    error ("%s: %d: %s", curr_fcn_file_name.c_str (), line, msg.c_str ());
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-check.h b/src/pt-check.h
new file mode 100644
index 0000000..4d546a6
--- /dev/null
+++ b/src/pt-check.h
@@ -0,0 +1,146 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_checker_h)
+#define octave_tree_checker_h 1
+
+#include "pt-walk.h"
+
+class tree_decl_command;
+
+// How to check the semantics of the code that the parse trees represent.
+
+class
+tree_checker : public tree_walker
+{
+public:
+
+  tree_checker (void)
+    : do_lvalue_check (false) { }
+
+  ~tree_checker (void) { }
+
+  void visit_argument_list (tree_argument_list&);
+
+  void visit_binary_expression (tree_binary_expression&);
+
+  void visit_break_command (tree_break_command&);
+
+  void visit_colon_expression (tree_colon_expression&);
+
+  void visit_continue_command(tree_continue_command&);
+
+  void visit_global_command (tree_global_command&);
+
+  void visit_static_command (tree_static_command&);
+
+  void visit_decl_elt (tree_decl_elt&);
+
+  void visit_decl_init_list (tree_decl_init_list&);
+
+  void visit_simple_for_command (tree_simple_for_command&);
+
+  void visit_complex_for_command (tree_complex_for_command&);
+
+  void visit_octave_user_script (octave_user_script&);
+
+  void visit_octave_user_function (octave_user_function&);
+
+  void visit_function_def (tree_function_def&);
+
+  void visit_identifier (tree_identifier&);
+
+  void visit_if_clause (tree_if_clause&);
+
+  void visit_if_command (tree_if_command&);
+
+  void visit_if_command_list (tree_if_command_list&);
+
+  void visit_index_expression (tree_index_expression&);
+
+  void visit_matrix (tree_matrix&);
+
+  void visit_cell (tree_cell&);
+
+  void visit_multi_assignment (tree_multi_assignment&);
+
+  void visit_no_op_command (tree_no_op_command&);
+
+  void visit_anon_fcn_handle (tree_anon_fcn_handle&);
+
+  void visit_constant (tree_constant&);
+
+  void visit_fcn_handle (tree_fcn_handle&);
+
+  void visit_parameter_list (tree_parameter_list&);
+
+  void visit_postfix_expression (tree_postfix_expression&);
+
+  void visit_prefix_expression (tree_prefix_expression&);
+
+  void visit_return_command (tree_return_command&);
+
+  void visit_return_list (tree_return_list&);
+
+  void visit_simple_assignment (tree_simple_assignment&);
+
+  void visit_statement (tree_statement&);
+
+  void visit_statement_list (tree_statement_list&);
+
+  void visit_switch_case (tree_switch_case&);
+
+  void visit_switch_case_list (tree_switch_case_list&);
+
+  void visit_switch_command (tree_switch_command&);
+
+  void visit_try_catch_command (tree_try_catch_command&);
+
+  void visit_unwind_protect_command (tree_unwind_protect_command&);
+
+  void visit_while_command (tree_while_command&);
+
+  void visit_do_until_command (tree_do_until_command&);
+
+private:
+
+  bool do_lvalue_check;
+
+  void do_decl_command (tree_decl_command&);
+
+  void gripe (const std::string& msg, int line);
+
+  // No copying!
+
+  tree_checker (const tree_checker&);
+
+  tree_checker& operator = (const tree_checker&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-cmd.cc b/src/pt-cmd.cc
new file mode 100644
index 0000000..9af17f4
--- /dev/null
+++ b/src/pt-cmd.cc
@@ -0,0 +1,65 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2002, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pt-cmd.h"
+#include "pt-walk.h"
+
+// No-op.
+
+tree_command *
+tree_no_op_command::dup (symbol_table::scope_id,
+			 symbol_table::context_id) const
+{
+  return new tree_no_op_command (orig_cmd, line (), column ());
+}
+
+void
+tree_no_op_command::accept (tree_walker& tw)
+{
+  tw.visit_no_op_command (*this);
+}
+
+// Function definition.
+
+tree_command *
+tree_function_def::dup (symbol_table::scope_id,
+			symbol_table::context_id) const
+{
+  return new tree_function_def (fcn, line (), column ());
+}
+
+void
+tree_function_def::accept (tree_walker& tw)
+{
+  tw.visit_function_def (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-cmd.h b/src/pt-cmd.h
new file mode 100644
index 0000000..0d1d2c0
--- /dev/null
+++ b/src/pt-cmd.h
@@ -0,0 +1,134 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_cmd_h)
+#define octave_tree_cmd_h 1
+
+#include <string>
+
+class tree_walker;
+
+#include "ov-fcn.h"
+#include "pt.h"
+#include "pt-bp.h"
+#include "symtab.h"
+
+// A base class for commands.
+
+class
+tree_command : public tree
+{
+public:
+
+  tree_command (int l = -1, int c = -1)
+    : tree (l, c) { }
+
+  virtual ~tree_command (void) { }
+
+  virtual tree_command *dup (symbol_table::scope_id,
+			     symbol_table::context_id context) const = 0;
+
+private:
+
+  // No copying!
+
+  tree_command (const tree_command&);
+
+  tree_command& operator = (const tree_command&);
+};
+
+// No-op.
+
+class
+tree_no_op_command : public tree_command
+{
+public:
+
+  tree_no_op_command (const std::string& cmd = "no_op", int l = -1, int c = -1)
+    : tree_command (l, c), eof (cmd == "endfunction" || cmd == "endscript"),
+      orig_cmd (cmd) { }
+
+  ~tree_no_op_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  bool is_end_of_fcn_or_script (void) const { return eof; }
+
+  std::string original_command (void) { return orig_cmd; }
+
+private:
+
+  bool eof;
+
+  std::string orig_cmd;
+
+  // No copying!
+
+  tree_no_op_command (const tree_no_op_command&);
+
+  tree_no_op_command& operator = (const tree_no_op_command&);
+};
+
+// Function definition.
+
+class
+tree_function_def : public tree_command
+{
+public:
+
+  tree_function_def (octave_function *f, int l = -1, int c = -1)
+    : tree_command (l, c), fcn (f) { }
+
+  ~tree_function_def (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  octave_value function (void) { return fcn; }
+
+private:
+
+  octave_value fcn;
+
+  tree_function_def (const octave_value& v, int l = -1, int c = -1)
+    : tree_command (l, c), fcn (v) { }
+
+  // No copying!
+
+  tree_function_def (const tree_function_def&);
+
+  tree_function_def& operator = (const tree_function_def&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-colon.cc b/src/pt-colon.cc
new file mode 100644
index 0000000..247c882
--- /dev/null
+++ b/src/pt-colon.cc
@@ -0,0 +1,292 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "ov.h"
+#include "pt-bp.h"
+#include "pt-colon.h"
+#include "pt-walk.h"
+
+// Colon expressions.
+
+tree_colon_expression *
+tree_colon_expression::append (tree_expression *t)
+{
+  tree_colon_expression *retval = 0;
+
+  if (op_base)
+    {
+      if (op_limit)
+	{
+	  if (op_increment)
+	    ::error ("invalid colon expression");
+	  else
+	    {
+	      // Stupid syntax:
+	      //
+	      // base : limit
+	      // base : increment : limit
+
+	      op_increment = op_limit;
+	      op_limit = t;
+	    }
+	}
+      else
+	op_limit = t;
+
+      retval = this;
+    }
+  else
+    ::error ("invalid colon expression");
+
+  return retval;
+}
+
+octave_value_list
+tree_colon_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for colon expression");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_colon_expression::make_range (const Matrix& m_base,
+				   const Matrix& m_limit,
+				   const Matrix& m_increment,
+				   bool result_is_str, bool dq_str) const
+{
+  octave_value retval;
+
+  bool base_empty = m_base.is_empty ();
+  bool limit_empty = m_limit.is_empty ();
+  bool increment_empty = m_increment.is_empty ();
+
+  if (base_empty || limit_empty || increment_empty)
+    retval = Range ();
+  else
+    {
+      retval = Range (m_base(0), m_limit(0), m_increment(0));
+
+      if (result_is_str)
+	retval = retval.convert_to_str (false, true, dq_str ? '"' : '\'');
+    }
+
+  return retval;
+}
+
+octave_value
+tree_colon_expression::make_range (const octave_value& ov_base,
+				   const octave_value& ov_limit,
+				   const octave_value& ov_increment) const
+{
+  octave_value retval;
+
+  if (ov_base.is_object () || ov_limit.is_object () || 
+      ov_increment.is_object ())
+    {
+      octave_value_list tmp1;
+      tmp1(2) = ov_limit;
+      tmp1(1) = ov_increment;
+      tmp1(0) = ov_base;
+
+      octave_value fcn = symbol_table::find_function ("colon", tmp1);
+
+      if (fcn.is_defined ())
+	{
+	  octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1);
+		      
+	  if (! error_state)
+	    retval = tmp2 (0);
+	}
+      else
+	::error ("can not find overloaded colon function");
+    }
+  else
+    {
+      bool result_is_str = (ov_base.is_string () && ov_limit.is_string ());
+      bool dq_str = (ov_base.is_dq_string () || ov_limit.is_dq_string ());
+
+      Matrix m_base = ov_base.matrix_value (true);
+
+      if (error_state)
+	eval_error ("invalid base value in colon expression");
+      else
+	{
+	  Matrix m_limit = ov_limit.matrix_value (true);
+
+	  if (error_state)
+	    eval_error ("invalid limit value in colon expression");
+	  else
+	    {
+	      Matrix m_increment = ov_increment.matrix_value (true);
+
+	      if (error_state)
+		eval_error ("invalid increment value in colon expression");
+	      else
+		retval = make_range (m_base, m_limit, m_increment,
+				     result_is_str, dq_str);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+octave_value
+tree_colon_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state || ! op_base || ! op_limit)
+    return retval;
+
+  octave_value ov_base = op_base->rvalue1 ();
+
+  if (error_state || ov_base.is_undefined ())
+    eval_error ("invalid base value in colon expression");
+  else
+    {
+      octave_value ov_limit = op_limit->rvalue1 ();
+
+      if (error_state || ov_limit.is_undefined ())
+	eval_error ("invalid limit value in colon expression");
+      else if (ov_base.is_object () || ov_limit.is_object ())
+	{
+	  octave_value_list tmp1;
+
+	  if (op_increment)
+	    {
+	      octave_value ov_increment = op_increment->rvalue1 ();
+
+	      if (error_state || ov_increment.is_undefined ())
+		eval_error ("invalid increment value in colon expression");
+	      else
+		{
+		  tmp1(2) = ov_limit;
+		  tmp1(1) = ov_increment;
+		  tmp1(0) = ov_base;
+		}
+	    }
+	  else
+	    {
+	      tmp1(1) = ov_limit;
+	      tmp1(0) = ov_base;
+	    }
+
+	  if (!error_state)
+	    {
+	      octave_value fcn = symbol_table::find_function ("colon", tmp1);
+
+	      if (fcn.is_defined ())
+		{
+		  octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1);
+		      
+		  if (! error_state)
+		    retval = tmp2 (0);
+		}
+	      else
+		::error ("can not find overloaded colon function");
+	    }
+	}
+      else
+	{
+	  octave_value ov_increment = 1.0;
+
+	  if (op_increment)
+	    {
+	      ov_increment = op_increment->rvalue1 ();
+
+	      if (error_state || ov_increment.is_undefined ())
+		eval_error ("invalid increment value in colon expression");
+	    }
+
+	  if (! error_state)
+	    retval = make_range (ov_base, ov_limit, ov_increment);
+	}
+    }
+
+  return retval;
+}
+
+void
+tree_colon_expression::eval_error (const std::string& s) const
+{
+  ::error ("%s", s.c_str ());
+}
+
+int
+tree_colon_expression::line (void) const
+{
+  return (op_base ? op_base->line ()
+	  : (op_increment ? op_increment->line ()
+	     : (op_limit ? op_limit->line ()
+		: -1)));
+}
+
+int
+tree_colon_expression::column (void) const
+{
+  return (op_base ? op_base->column ()
+	  : (op_increment ? op_increment->column ()
+	     : (op_limit ? op_limit->column ()
+		: -1)));
+}
+
+tree_expression *
+tree_colon_expression::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const
+{
+  tree_colon_expression *new_ce = new
+    tree_colon_expression (op_base ? op_base->dup (scope, context) : 0,
+			   op_limit ? op_limit->dup (scope, context) : 0,
+			   op_increment ? op_increment->dup (scope, context) : 0,
+			   line (), column ());
+
+  new_ce->copy_base (*new_ce);
+
+  return new_ce;
+}
+
+void
+tree_colon_expression::accept (tree_walker& tw)
+{
+  tw.visit_colon_expression (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-colon.h b/src/pt-colon.h
new file mode 100644
index 0000000..3c5aa0a
--- /dev/null
+++ b/src/pt-colon.h
@@ -0,0 +1,131 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_colon_h)
+#define octave_tree_colon 1
+
+#include <string>
+
+class tree_walker;
+
+class octave_value;
+class octave_value_list;
+class octave_lvalue;
+
+#include "pt-exp.h"
+#include "symtab.h"
+
+// Colon expressions.
+
+class
+tree_colon_expression : public tree_expression
+{
+public:
+
+  tree_colon_expression (int l = -1, int c = -1)
+    : tree_expression (l, c), op_base (0), op_limit (0),
+      op_increment (0), save_base (false) { }
+
+  tree_colon_expression (tree_expression *e, int l = -1, int c = -1)
+    : tree_expression (l, c), op_base (e), op_limit (0),
+      op_increment (0), save_base (false) { }
+
+  tree_colon_expression (tree_expression *bas, tree_expression *lim,
+			 tree_expression *inc, int l = -1, int c = -1)
+    : tree_expression (l, c), op_base (bas), op_limit (lim),
+      op_increment (inc), save_base (false) { }
+
+  ~tree_colon_expression (void)
+    {
+      if (! save_base)
+	delete op_base;
+
+      delete op_limit;
+      delete op_increment;
+    }
+
+  bool has_magic_end (void) const
+    {
+      return ((op_base && op_base->has_magic_end ())
+	      || (op_limit && op_limit->has_magic_end ())
+	      || (op_increment && op_increment->has_magic_end ()));
+    }
+
+  void preserve_base (void) { save_base = true; }
+
+  tree_colon_expression *append (tree_expression *t);
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  void eval_error (const std::string& s) const;
+
+  tree_expression *base (void) { return op_base; }
+
+  tree_expression *limit (void) { return op_limit; }
+
+  tree_expression *increment (void) { return op_increment; }
+
+  int line (void) const;
+  int column (void) const;
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The components of the expression.
+  tree_expression *op_base;
+  tree_expression *op_limit;
+  tree_expression *op_increment;
+
+  bool save_base;
+
+  octave_value
+  make_range (const Matrix& m_base, const Matrix& m_limit,
+	      const Matrix& m_increment, bool result_is_str,
+	      bool dq_str) const;
+
+  octave_value
+  make_range (const octave_value& ov_base, const octave_value& ov_limit,
+	      const octave_value& ov_increment) const;
+
+  // No copying!
+
+  tree_colon_expression (const tree_colon_expression&);
+
+  tree_colon_expression& operator = (const tree_colon_expression&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-const.cc b/src/pt-const.cc
new file mode 100644
index 0000000..0e91d03
--- /dev/null
+++ b/src/pt-const.cc
@@ -0,0 +1,95 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "error.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "pt-const.h"
+#include "pt-walk.h"
+
+// We are likely to have a lot of tree_constant objects to allocate,
+// so make the grow_size large.
+octave_allocator
+tree_constant::allocator (sizeof (tree_constant), 1024);
+
+void
+tree_constant::print (std::ostream& os, bool pr_as_read_syntax, bool pr_orig_text)
+{
+  if (pr_orig_text && ! orig_text.empty ())
+    os << orig_text;
+  else
+    val.print (os, pr_as_read_syntax);
+}
+
+void
+tree_constant::print_raw (std::ostream& os, bool pr_as_read_syntax,
+			  bool pr_orig_text) 
+{
+  if (pr_orig_text && ! orig_text.empty ())
+    os << orig_text;
+  else
+    val.print_raw (os, pr_as_read_syntax);
+}
+
+octave_value_list
+tree_constant::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for constant expression");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+tree_expression *
+tree_constant::dup (symbol_table::scope_id,
+		    symbol_table::context_id) const
+{
+  tree_constant *new_tc
+    = new tree_constant (val, orig_text, line (), column ());
+
+  new_tc->copy_base (*this);
+
+  return new_tc;
+}
+
+void
+tree_constant::accept (tree_walker& tw)
+{
+  tw.visit_constant (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-const.h b/src/pt-const.h
new file mode 100644
index 0000000..8887550
--- /dev/null
+++ b/src/pt-const.h
@@ -0,0 +1,117 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_const_h)
+#define octave_tree_const_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "oct-alloc.h"
+
+class octave_value_list;
+class tree_walker;
+
+#include "ov.h"
+#include "pt-bp.h"
+#include "pt-exp.h"
+#include "symtab.h"
+
+class
+tree_constant : public tree_expression
+{
+public:
+
+  tree_constant (int l = -1, int c = -1)
+    : tree_expression (l, c), val (), orig_text () { }
+
+  tree_constant (const octave_value& v, int l = -1, int c = -1)
+    : tree_expression (l, c), val (v), orig_text () { }
+
+  tree_constant (const octave_value& v, const std::string& ot,
+		 int l = -1, int c = -1)
+    : tree_expression (l, c), val (v), orig_text (ot) { }
+
+  ~tree_constant (void) { }
+
+  bool has_magic_end (void) const { return false; }
+
+  void *operator new (size_t size) { return allocator.alloc (size); }
+
+  void operator delete (void *p, size_t size) { allocator.free (p, size); }
+
+  // Type.  It would be nice to eliminate the need for this.
+
+  bool is_constant (void) const { return true; }
+
+  void maybe_mutate (void) { val.maybe_mutate (); }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false,
+	      bool pr_orig_txt = true);
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false,
+		  bool pr_orig_txt = true);
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int = 1) { return val; }
+
+  octave_value_list rvalue (int nargout);
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  // Store the original text corresponding to this constant for later
+  // pretty printing.
+
+  void stash_original_text (const std::string& s) { orig_text = s; }
+
+  std::string original_text (void) const { return orig_text; }
+
+private:
+
+  // For custom memory management.
+  static octave_allocator allocator;
+
+  // The actual value that this constant refers to.
+  octave_value val;
+
+  // The original text form of this constant.
+  std::string orig_text;
+
+  // No copying!
+
+  tree_constant (const tree_constant&);
+
+  tree_constant& operator = (const tree_constant&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-decl.cc b/src/pt-decl.cc
new file mode 100644
index 0000000..e323b99
--- /dev/null
+++ b/src/pt-decl.cc
@@ -0,0 +1,154 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun.h"
+#include "error.h"
+#include "pt-cmd.h"
+#include "ov.h"
+#include "oct-lvalue.h"
+#include "pt-bp.h"
+#include "pt-decl.h"
+#include "pt-exp.h"
+#include "pt-id.h"
+#include "pt-walk.h"
+#include "utils.h"
+#include "variables.h"
+
+// Declarations (global, static, etc.).
+
+tree_decl_elt::~tree_decl_elt (void)
+{
+  delete id;
+  delete expr;
+}
+
+bool
+tree_decl_elt::eval (void)
+{
+  bool retval = false;
+
+  if (id && expr)
+    {
+      octave_lvalue ult = id->lvalue ();
+
+      octave_value init_val = expr->rvalue1 ();
+
+      if (! error_state)
+	{
+	  ult.assign (octave_value::op_asn_eq, init_val);
+
+	  retval = true;
+	}
+    }
+
+  return retval;
+}
+
+tree_decl_elt *
+tree_decl_elt::dup (symbol_table::scope_id scope,
+		    symbol_table::context_id context) const
+{
+  return new tree_decl_elt (id ? id->dup (scope, context) : 0,
+			    expr ? expr->dup (scope, context) : 0);
+}
+
+void
+tree_decl_elt::accept (tree_walker& tw)
+{
+  tw.visit_decl_elt (*this);
+}
+
+// Initializer lists for declaration statements.
+
+tree_decl_init_list *
+tree_decl_init_list::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context) const
+{
+  tree_decl_init_list *new_dil = new tree_decl_init_list ();
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_decl_elt *elt = *p;
+
+      new_dil->append (elt ? elt->dup (scope, context) : 0);
+    }
+  
+  return new_dil;
+}
+
+void
+tree_decl_init_list::accept (tree_walker& tw)
+{
+  tw.visit_decl_init_list (*this);
+}
+
+// Base class for declaration commands (global, static).
+
+tree_decl_command::~tree_decl_command (void)
+{
+  delete init_list;
+}
+
+// Global.
+
+tree_command *
+tree_global_command::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context) const
+{
+  return
+    new tree_global_command (init_list ? init_list->dup (scope, context) : 0,
+			     line (), column ());
+}
+
+void
+tree_global_command::accept (tree_walker& tw)
+{
+  tw.visit_global_command (*this);
+}
+
+// Static.
+
+tree_command *
+tree_static_command::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context) const
+{
+  return
+    new tree_static_command (init_list ? init_list->dup (scope, context) : 0,
+			     line (), column ());
+}
+
+void
+tree_static_command::accept (tree_walker& tw)
+{
+  tw.visit_static_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-decl.h b/src/pt-decl.h
new file mode 100644
index 0000000..7691c67
--- /dev/null
+++ b/src/pt-decl.h
@@ -0,0 +1,248 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_decl_h)
+#define octave_tree_decl_h 1
+
+class tree_expression;
+class tree_identifier;
+
+class tree_walker;
+
+#include <string>
+
+#include "base-list.h"
+#include "oct-lvalue.h"
+#include "pt-cmd.h"
+#include "pt-id.h"
+#include "symtab.h"
+
+// List of expressions that make up a declaration statement.
+
+class
+tree_decl_elt
+{
+public:
+
+  tree_decl_elt (tree_identifier *i = 0, tree_expression *e = 0)
+    : id (i), expr (e) { }
+
+  ~tree_decl_elt (void);
+
+  bool eval (void);
+
+  bool is_defined (void) { return id ? id->is_defined () : false; }
+
+  bool is_variable (void) { return id ? id->is_variable () : false; }
+
+  void mark_as_formal_parameter (void)
+  {
+    if (id)
+      id->mark_as_formal_parameter ();
+  }
+
+  bool lvalue_ok (void) { return id ? id->lvalue_ok () : false; }
+
+  // Do not allow functions to return null values.
+  octave_value rvalue1 (int nargout = 1)
+  {
+    return id ? id->rvalue1 (nargout).storable_value () : octave_value ();
+  }
+
+  octave_value_list rvalue (int nargout)
+  {
+    octave_value_list retval;
+
+    if (nargout > 1)
+      error ("invalid number of output arguments in declaration list");
+    else
+      retval = rvalue1 (nargout);
+
+    return retval;
+  }
+
+  octave_lvalue lvalue (void) { return id ? id->lvalue () : octave_lvalue (); }
+
+  tree_identifier *ident (void) { return id; }
+
+  tree_expression *expression (void) { return expr; }
+
+  tree_decl_elt *dup (symbol_table::scope_id scope,
+		      symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // An identifier to tag with the declared property.
+  tree_identifier *id;
+
+  // An initializer expression (may be zero);
+  tree_expression *expr;
+
+  // No copying!
+
+  tree_decl_elt (const tree_decl_elt&);
+
+  tree_decl_elt& operator = (const tree_decl_elt&);
+};
+
+class
+tree_decl_init_list : public octave_base_list<tree_decl_elt *>
+{
+public:
+
+  tree_decl_init_list (void) { }
+
+  tree_decl_init_list (tree_decl_elt *t) { append (t); }
+
+  ~tree_decl_init_list (void)
+    {
+      while (! empty ())
+	{
+	  iterator p = begin ();
+	  delete *p;
+	  erase (p);
+	}
+    }
+
+  tree_decl_init_list *dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_decl_init_list (const tree_decl_init_list&);
+
+  tree_decl_init_list& operator = (const tree_decl_init_list&);
+};
+
+// Base class for declaration commands -- global, static, etc.
+
+class
+tree_decl_command : public tree_command
+{
+public:
+
+  tree_decl_command (const std::string& n, int l = -1, int c = -1)
+    : tree_command (l, c), cmd_name (n), init_list (0) { }
+
+  tree_decl_command (const std::string& n, tree_decl_init_list *t,
+		     int l = -1, int c = -1)
+    : tree_command (l, c), cmd_name (n), init_list (t) { }
+
+  ~tree_decl_command (void);
+
+  tree_decl_init_list *initializer_list (void) { return init_list; }
+
+  std::string name (void) { return cmd_name; }
+
+protected:
+
+  // The name of this command -- global, static, etc.
+  std::string cmd_name;
+
+  // The list of variables or initializers in this declaration command.
+  tree_decl_init_list *init_list;
+
+private:
+
+  // No copying!
+
+  tree_decl_command (const tree_decl_command&);
+
+  tree_decl_command& operator = (const tree_decl_command&);
+};
+
+// Global.
+
+class
+tree_global_command : public tree_decl_command
+{
+public:
+
+  tree_global_command (int l = -1, int c = -1)
+    : tree_decl_command ("global", l, c) { }
+
+  tree_global_command (tree_decl_init_list *t, int l = -1, int c = -1)
+    : tree_decl_command ("global", t, l, c) { }
+
+  ~tree_global_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  static void do_init (tree_decl_elt& elt);
+
+  // No copying!
+
+  tree_global_command (const tree_global_command&);
+
+  tree_global_command& operator = (const tree_global_command&);
+};
+
+// Static.
+
+class
+tree_static_command : public tree_decl_command
+{
+public:
+
+  tree_static_command (int l = -1, int c = -1)
+    : tree_decl_command ("static", l, c) { }
+
+  tree_static_command (tree_decl_init_list *t, int l = -1, int c = -1)
+    : tree_decl_command ("static", t, l, c) { }
+
+  ~tree_static_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  static void do_init (tree_decl_elt& elt);
+
+  // No copying!
+
+  tree_static_command (const tree_static_command&);
+
+  tree_static_command& operator = (const tree_static_command&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-eval.cc b/src/pt-eval.cc
new file mode 100644
index 0000000..b7daa5a
--- /dev/null
+++ b/src/pt-eval.cc
@@ -0,0 +1,1221 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <iostream>
+
+#include <fstream>
+#include <typeinfo>
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "ov-fcn-handle.h"
+#include "ov-usr-fcn.h"
+#include "variables.h"
+#include "pt-all.h"
+#include "pt-eval.h"
+#include "symtab.h"
+#include "unwind-prot.h"
+
+static tree_evaluator std_evaluator;
+
+tree_evaluator *current_evaluator = &std_evaluator;
+
+int tree_evaluator::dbstep_flag = 0;
+
+size_t tree_evaluator::current_frame = 0;
+
+bool tree_evaluator::debug_mode = false;
+
+bool tree_evaluator::in_fcn_or_script_body = false;
+
+bool tree_evaluator::in_loop_command = false;
+
+int tree_evaluator::db_line = -1;
+int tree_evaluator::db_column = -1;
+
+// If TRUE, turn off printing of results in functions (as if a
+// semicolon has been appended to each statement).
+static bool Vsilent_functions = false;
+
+// Normal evaluator.
+
+void
+tree_evaluator::visit_anon_fcn_handle (tree_anon_fcn_handle&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_argument_list (tree_argument_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_binary_expression (tree_binary_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_break_command (tree_break_command& cmd)
+{
+  if (! error_state)
+    {
+      if (debug_mode)
+	do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
+
+      tree_break_command::breaking = 1;
+    }
+}
+
+void
+tree_evaluator::visit_colon_expression (tree_colon_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_continue_command (tree_continue_command&)
+{
+  if (! error_state)
+    tree_continue_command::continuing = 1;
+}
+
+static inline void
+do_global_init (tree_decl_elt& elt)
+{
+  tree_identifier *id = elt.ident ();
+
+  if (id)
+    {
+      id->mark_global ();
+
+      if (! error_state)
+	{
+	  octave_lvalue ult = id->lvalue ();
+
+	  if (ult.is_undefined ())
+	    {
+	      tree_expression *expr = elt.expression ();
+
+	      octave_value init_val;
+
+	      if (expr)
+		init_val = expr->rvalue1 ();
+	      else
+		init_val = Matrix ();
+
+	      ult.assign (octave_value::op_asn_eq, init_val);
+	    }
+	}
+    }
+}
+
+static inline void
+do_static_init (tree_decl_elt& elt)
+{
+  tree_identifier *id = elt.ident ();
+
+  if (id)
+    {
+      id->mark_as_static ();
+
+      octave_lvalue ult = id->lvalue ();
+
+      if (ult.is_undefined ())
+	{
+	  tree_expression *expr = elt.expression ();
+
+	  octave_value init_val;
+
+	  if (expr)
+	    init_val = expr->rvalue1 ();
+	  else
+	    init_val = Matrix ();
+
+	  ult.assign (octave_value::op_asn_eq, init_val);
+	}
+    }
+}
+
+void
+tree_evaluator::do_decl_init_list (decl_elt_init_fcn fcn,
+				   tree_decl_init_list *init_list)
+{
+  if (init_list)
+    {
+      for (tree_decl_init_list::iterator p = init_list->begin ();
+	   p != init_list->end (); p++)
+	{
+	  tree_decl_elt *elt = *p;
+
+	  fcn (*elt);
+
+	  if (error_state)
+	    break;
+	}
+    }
+}
+
+void
+tree_evaluator::visit_global_command (tree_global_command& cmd)
+{
+  if (debug_mode)
+    do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
+
+  do_decl_init_list (do_global_init, cmd.initializer_list ());
+}
+
+void
+tree_evaluator::visit_static_command (tree_static_command& cmd)
+{
+  if (debug_mode)
+    do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
+
+  do_decl_init_list (do_static_init, cmd.initializer_list ());
+}
+
+void
+tree_evaluator::visit_decl_elt (tree_decl_elt&)
+{
+  panic_impossible ();
+}
+
+#if 0
+bool
+tree_decl_elt::eval (void)
+{
+  bool retval = false;
+
+  if (id && expr)
+    {
+      octave_lvalue ult = id->lvalue ();
+
+      octave_value init_val = expr->rvalue1 ();
+
+      if (! error_state)
+       {
+         ult.assign (octave_value::op_asn_eq, init_val);
+
+         retval = true;
+       }
+    }
+
+  return retval;
+}
+#endif
+
+void
+tree_evaluator::visit_decl_init_list (tree_decl_init_list&)
+{
+  panic_impossible ();
+}
+
+// Decide if it's time to quit a for or while loop.
+static inline bool
+quit_loop_now (void)
+{
+  OCTAVE_QUIT;
+
+  // Maybe handle `continue N' someday...
+
+  if (tree_continue_command::continuing)
+    tree_continue_command::continuing--;
+
+  bool quit = (error_state
+	       || tree_return_command::returning
+	       || tree_break_command::breaking
+	       || tree_continue_command::continuing);
+
+  if (tree_break_command::breaking)
+    tree_break_command::breaking--;
+
+  return quit;
+}
+
+#define DO_SIMPLE_FOR_LOOP_ONCE(VAL) \
+  do \
+    { \
+      ult.assign (octave_value::op_asn_eq, VAL); \
+ \
+      if (! error_state && loop_body) \
+	loop_body->accept (*this); \
+ \
+      quit = quit_loop_now (); \
+    } \
+  while (0)
+
+void
+tree_evaluator::visit_simple_for_command (tree_simple_for_command& cmd)
+{
+  if (error_state)
+    return;
+
+  if (debug_mode)
+    do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
+
+  unwind_protect::begin_frame ("tree_evaluator::visit_simple_for_command");
+
+  unwind_protect_bool (in_loop_command);
+
+  in_loop_command = true;
+
+  tree_expression *expr = cmd.control_expr ();
+
+  octave_value rhs = expr->rvalue1 ();
+
+  if (error_state || rhs.is_undefined ())
+    goto cleanup;
+
+  {
+    tree_expression *lhs = cmd.left_hand_side ();
+
+    octave_lvalue ult = lhs->lvalue ();
+
+    if (error_state)
+      goto cleanup;
+
+    tree_statement_list *loop_body = cmd.body ();
+
+    if (rhs.is_range ())
+      {
+	Range rng = rhs.range_value ();
+
+	octave_idx_type steps = rng.nelem ();
+	double b = rng.base ();
+	double increment = rng.inc ();
+	bool quit = false;
+
+	for (octave_idx_type i = 0; i < steps; i++)
+	  {
+	    // Use multiplication here rather than declaring a
+	    // temporary variable outside the loop and using
+	    //
+	    //   tmp_val += increment
+	    //
+	    // to avoid problems with limited precision.  Also, this
+	    // is consistent with the way Range::matrix_value is
+	    // implemented.
+
+	    octave_value val (b + i * increment);
+
+	    DO_SIMPLE_FOR_LOOP_ONCE (val);
+
+	    if (quit)
+	      break;
+	  }
+      }
+    else if (rhs.is_scalar_type ())
+      {
+	bool quit = false;
+
+	DO_SIMPLE_FOR_LOOP_ONCE (rhs);
+      }
+    else if (rhs.is_matrix_type () || rhs.is_cell () || rhs.is_string ()
+             || rhs.is_map ())
+      {
+        // A matrix or cell is reshaped to 2 dimensions and iterated by
+        // columns.
+
+        bool quit = false;
+
+        dim_vector dv = rhs.dims ().redim (2);
+
+        octave_idx_type nrows = dv(0), steps = dv(1);
+
+        if (steps > 0)
+          {
+            octave_value arg = rhs;
+            if (rhs.ndims () > 2)
+              arg = arg.reshape (dv);
+
+            // for row vectors, use single index to speed things up.
+            octave_value_list idx;
+            octave_idx_type iidx;
+            if (nrows == 1)
+              {
+                idx.resize (1);
+                iidx = 0;
+              }
+            else
+              {
+                idx.resize (2);
+                idx(0) = octave_value::magic_colon_t;
+                iidx = 1;
+              }
+
+            for (octave_idx_type i = 1; i <= steps; i++)
+              {
+                // do_index_op expects one-based indices.
+                idx(iidx) = i;
+                octave_value val = arg.do_index_op (idx);
+                DO_SIMPLE_FOR_LOOP_ONCE (val);
+
+                if (quit)
+                  break;
+              }
+          }
+      }
+    else
+      {
+	::error ("invalid type in for loop expression near line %d, column %d",
+		 cmd.line (), cmd.column ());
+      }
+  }
+
+ cleanup:
+  unwind_protect::run_frame ("tree_evaluator::visit_simple_for_command");
+}
+
+void
+tree_evaluator::visit_complex_for_command (tree_complex_for_command& cmd)
+{
+  if (error_state)
+    return;
+
+  if (debug_mode)
+    do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
+
+  unwind_protect::begin_frame ("tree_evaluator::visit_complex_for_command");
+
+  unwind_protect_bool (in_loop_command);
+
+  in_loop_command = true;
+
+  tree_expression *expr = cmd.control_expr ();
+
+  octave_value rhs = expr->rvalue1 ();
+
+  if (error_state || rhs.is_undefined ())
+    goto cleanup;
+
+  if (rhs.is_map ())
+    {
+      // Cycle through structure elements.  First element of id_list
+      // is set to value and the second is set to the name of the
+      // structure element.
+
+      tree_argument_list *lhs = cmd.left_hand_side ();
+
+      tree_argument_list::iterator p = lhs->begin ();
+
+      tree_expression *elt = *p++;
+
+      octave_lvalue val_ref = elt->lvalue ();
+
+      elt = *p;
+
+      octave_lvalue key_ref = elt->lvalue ();
+
+      const Octave_map tmp_val = rhs.map_value ();
+
+      tree_statement_list *loop_body = cmd.body ();
+
+      string_vector keys = tmp_val.keys ();
+
+      octave_idx_type nel = keys.numel ();
+
+      for (octave_idx_type i = 0; i < nel; i++)
+	{
+	  std::string key = keys[i];
+
+	  const Cell val_lst = tmp_val.contents (key);
+
+	  octave_idx_type n = val_lst.numel ();
+
+	  octave_value val = (n == 1) ? val_lst(0) : octave_value (val_lst);
+
+	  val_ref.assign (octave_value::op_asn_eq, val);
+	  key_ref.assign (octave_value::op_asn_eq, key);
+
+	  if (! error_state && loop_body)
+	    loop_body->accept (*this);
+
+	  if (quit_loop_now ())
+	    break;
+	}
+    }
+  else
+    error ("in statement `for [X, Y] = VAL', VAL must be a structure");
+
+ cleanup:
+  unwind_protect::run_frame ("tree_evaluator::visit_complex_for_command");
+}
+
+void
+tree_evaluator::visit_octave_user_script (octave_user_script&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_octave_user_function (octave_user_function&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_octave_user_function_header (octave_user_function&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_octave_user_function_trailer (octave_user_function&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_function_def (tree_function_def& cmd)
+{
+  octave_value fcn = cmd.function ();
+
+  octave_function *f = fcn.function_value ();
+
+  if (f)
+    {
+      std::string nm = f->name ();
+
+      symbol_table::install_cmdline_function (nm, fcn);
+
+      // Make sure that any variable with the same name as the new
+      // function is cleared.
+
+      symbol_table::varref (nm) = octave_value ();
+    }
+}
+
+void
+tree_evaluator::visit_identifier (tree_identifier&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_if_clause (tree_if_clause&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_if_command (tree_if_command& cmd)
+{
+  tree_if_command_list *lst = cmd.cmd_list ();
+
+  if (lst)
+    lst->accept (*this);
+}
+
+void
+tree_evaluator::visit_if_command_list (tree_if_command_list& lst)
+{
+  for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++)
+    {
+      tree_if_clause *tic = *p;
+
+      tree_expression *expr = tic->condition ();
+
+      if (debug_mode && ! tic->is_else_clause ())
+	do_breakpoint (tic->is_breakpoint (), tic->line (), tic->column ());
+
+      if (tic->is_else_clause () || expr->is_logically_true ("if"))
+	{
+	  if (! error_state)
+	    {
+	      tree_statement_list *stmt_lst = tic->commands ();
+
+	      if (stmt_lst)
+		stmt_lst->accept (*this);
+	    }
+
+	  break;
+	}
+    }
+}
+
+void
+tree_evaluator::visit_index_expression (tree_index_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_matrix (tree_matrix&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_cell (tree_cell&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_multi_assignment (tree_multi_assignment&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_no_op_command (tree_no_op_command& cmd)
+{
+  if (debug_mode && cmd.is_end_of_fcn_or_script ())
+    do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column (), true);
+}
+
+void
+tree_evaluator::visit_constant (tree_constant&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_fcn_handle (tree_fcn_handle&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_parameter_list (tree_parameter_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_postfix_expression (tree_postfix_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_prefix_expression (tree_prefix_expression&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_return_command (tree_return_command& cmd)
+{
+  if (! error_state)
+    {
+      if (debug_mode)
+	do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
+
+      tree_return_command::returning = 1;
+    }
+}
+
+void
+tree_evaluator::visit_return_list (tree_return_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_simple_assignment (tree_simple_assignment&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_statement (tree_statement& stmt)
+{
+  tree_command *cmd = stmt.command ();
+  tree_expression *expr = stmt.expression ();
+
+  if (cmd || expr)
+    {
+      if (in_fcn_or_script_body)
+	{
+	  octave_call_stack::set_statement (&stmt);
+
+	  if (Vecho_executing_commands & ECHO_FUNCTIONS)
+	    stmt.echo_code ();
+	}
+
+      try
+	{
+	  if (cmd)
+	    cmd->accept (*this);
+	  else
+	    {
+	      if (debug_mode)
+		do_breakpoint (expr->is_breakpoint (), expr->line (),
+			       expr->column ());
+
+	      if (in_fcn_or_script_body && Vsilent_functions)
+		expr->set_print_flag (false);
+
+	      // FIXME -- maybe all of this should be packaged in
+	      // one virtual function that returns a flag saying whether
+	      // or not the expression will take care of binding ans and
+	      // printing the result.
+
+	      // FIXME -- it seems that we should just have to
+	      // call expr->rvalue1 () and that should take care of
+	      // everything, binding ans as necessary?
+
+	      bool do_bind_ans = false;
+
+	      if (expr->is_identifier ())
+		{
+		  tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
+
+		  do_bind_ans = (! id->is_variable ());
+		}
+	      else
+		do_bind_ans = (! expr->is_assignment_expression ());
+
+	      octave_value tmp_result = expr->rvalue1 (0);
+
+	      if (do_bind_ans && ! (error_state || tmp_result.is_undefined ()))
+		bind_ans (tmp_result, expr->print_result ());
+
+	      //	      if (tmp_result.is_defined ())
+	      //		result_values(0) = tmp_result;
+	    }
+	}
+      catch (octave_execution_exception)
+	{
+	  gripe_library_execution_error ();
+	}
+    }
+}
+
+void
+tree_evaluator::visit_statement_list (tree_statement_list& lst)
+{
+  static octave_value_list empty_list;
+
+  if (error_state)
+    return;
+
+  tree_statement_list::iterator p = lst.begin ();
+
+  if (p != lst.end ())
+    {
+      while (true)
+	{
+	  tree_statement *elt = *p++;
+
+	  if (elt)
+	    {
+	      OCTAVE_QUIT;
+
+	      elt->accept (*this);
+
+	      if (error_state)
+		break;
+
+	      if (tree_break_command::breaking
+		  || tree_continue_command::continuing)
+		break;
+
+	      if (tree_return_command::returning)
+		break;
+
+	      if (p == lst.end ())
+		break;
+	      else
+		{
+		  // Clear preivous values before next statement is
+		  // evaluated so that we aren't holding an extra
+		  // reference to a value that may be used next.  For
+		  // example, in code like this:
+		  //
+		  //   X = rand (N);  ## refcount for X should be 1
+		  //                  ## after this statement
+		  //
+		  //   X(idx) = val;  ## no extra copy of X should be
+		  //                  ## needed, but we will be faked
+		  //                  ## out if retval is not cleared
+		  //                  ## between statements here
+
+		  //		  result_values = empty_list;
+		}
+	    }
+	  else
+	    error ("invalid statement found in statement list!");
+	}
+    }
+}
+
+void
+tree_evaluator::visit_switch_case (tree_switch_case&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_switch_case_list (tree_switch_case_list&)
+{
+  panic_impossible ();
+}
+
+void
+tree_evaluator::visit_switch_command (tree_switch_command& cmd)
+{
+  tree_expression *expr = cmd.switch_value ();
+
+  if (expr)
+    {
+      octave_value val = expr->rvalue1 ();
+
+      tree_switch_case_list *lst = cmd.case_list ();
+
+      if (! error_state && lst)
+	{
+	  for (tree_switch_case_list::iterator p = lst->begin ();
+	       p != lst->end (); p++)
+	    {
+	      tree_switch_case *t = *p;
+
+	      if (debug_mode && ! t->is_default_case ())
+		do_breakpoint (t->is_breakpoint (), t->line (), t->column ());
+
+	      if (t->is_default_case () || t->label_matches (val))
+		{
+		  if (error_state)
+		    break;
+
+		  tree_statement_list *stmt_lst = t->commands ();
+
+		  if (stmt_lst)
+		    stmt_lst->accept (*this);
+
+		  break;
+		}
+	    }
+	}
+    }
+  else
+    ::error ("missing value in switch command near line %d, column %d",
+	     cmd.line (), cmd.column ());
+}
+
+static void
+do_catch_code (void *ptr)
+{
+  // Is it safe to call OCTAVE_QUIT here?  We are already running
+  // something on the unwind_protect stack, but the element for this
+  // action would have already been popped from the top of the stack,
+  // so we should not be attempting to run it again.
+
+  OCTAVE_QUIT;
+
+  // If we are interrupting immediately, or if an interrupt is in
+  // progress (octave_interrupt_state < 0), then we don't want to run
+  // the catch code (it should only run on errors, not interrupts).
+
+  // If octave_interrupt_state is positive, an interrupt is pending.
+  // The only way that could happen would be for the interrupt to
+  // come in after the OCTAVE_QUIT above and before the if statement
+  // below -- it's possible, but unlikely.  In any case, we should
+  // probably let the catch code throw the exception because we don't
+  // want to skip that and potentially run some other code.  For
+  // example, an error may have originally brought us here for some
+  // cleanup operation and we shouldn't skip that.
+
+  if (octave_interrupt_immediately || octave_interrupt_state < 0)
+    return;
+
+  tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
+
+  // Set up for letting the user print any messages from errors that
+  // occurred in the body of the try_catch statement.
+
+  buffer_error_messages--;
+
+  if (list)
+    list->accept (*current_evaluator);
+}
+
+void
+tree_evaluator::visit_try_catch_command (tree_try_catch_command& cmd)
+{
+  unwind_protect::begin_frame ("tree_evaluator::visit_try_catch_command");
+  
+  unwind_protect_int (buffer_error_messages);
+  unwind_protect_bool (Vdebug_on_error);
+  unwind_protect_bool (Vdebug_on_warning);
+
+  buffer_error_messages++;
+  Vdebug_on_error = false;
+  Vdebug_on_warning = false;
+
+  tree_statement_list *catch_code = cmd.cleanup ();
+
+  unwind_protect::add (do_catch_code, catch_code);
+
+  tree_statement_list *try_code = cmd.body ();
+
+  if (try_code)
+    try_code->accept (*this);
+
+  if (catch_code && error_state)
+    {
+      error_state = 0;
+      unwind_protect::run_frame ("tree_evaluator::visit_try_catch_command");
+    }
+  else
+    {
+      error_state = 0;
+
+      // Unwind stack elements must be cleared or run in the reverse
+      // order in which they were added to the stack.
+
+      // For clearing the do_catch_code cleanup function.
+      unwind_protect::discard ();
+
+      // For restoring Vdebug_on_warning, Vdebug_on_error, and
+      // buffer_error_messages.
+      unwind_protect::run ();
+      unwind_protect::run ();
+      unwind_protect::run ();
+
+      // Also clear the frame marker.
+      unwind_protect::discard ();
+    }
+}
+
+void restore_interrupt_state (void *ptr)
+{
+  octave_interrupt_state = *(reinterpret_cast<sig_atomic_t *> (ptr));
+}
+
+static void
+do_unwind_protect_cleanup_code (void *ptr)
+{
+  tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
+
+  sig_atomic_t saved_octave_interrupt_state = octave_interrupt_state;
+  unwind_protect::add (restore_interrupt_state, &saved_octave_interrupt_state);
+  octave_interrupt_state = 0;
+
+  // We want to run the cleanup code without error_state being set,
+  // but we need to restore its value, so that any errors encountered
+  // in the first part of the unwind_protect are not completely
+  // ignored.
+
+  unwind_protect_int (error_state);
+  error_state = 0;
+
+  // Similarly, if we have seen a return or break statement, allow all
+  // the cleanup code to run before returning or handling the break.
+  // We don't have to worry about continue statements because they can
+  // only occur in loops.
+
+  unwind_protect_int (tree_return_command::returning);
+  tree_return_command::returning = 0;
+
+  unwind_protect_int (tree_break_command::breaking);
+  tree_break_command::breaking = 0;
+
+  if (list)
+    list->accept (*current_evaluator);
+
+  // The unwind_protects are popped off the stack in the reverse of
+  // the order they are pushed on.
+
+  // FIXME -- these statements say that if we see a break or
+  // return statement in the cleanup block, that we want to use the
+  // new value of the breaking or returning flag instead of restoring
+  // the previous value.  Is that the right thing to do?  I think so.
+  // Consider the case of
+  //
+  //   function foo ()
+  //     unwind_protect
+  //       stderr << "1: this should always be executed\n";
+  //       break;
+  //       stderr << "1: this should never be executed\n";
+  //     unwind_protect_cleanup
+  //       stderr << "2: this should always be executed\n";
+  //       return;
+  //       stderr << "2: this should never be executed\n";
+  //     end_unwind_protect
+  //   endfunction
+  //
+  // If we reset the value of the breaking flag, both the returning
+  // flag and the breaking flag will be set, and we shouldn't have
+  // both.  So, use the most recent one.  If there is no return or
+  // break in the cleanup block, the values should be reset to
+  // whatever they were when the cleanup block was entered.
+
+  if (tree_break_command::breaking || tree_return_command::returning)
+    {
+      unwind_protect::discard ();
+      unwind_protect::discard ();
+    }
+  else
+    {
+      unwind_protect::run ();
+      unwind_protect::run ();
+    }
+
+  // We don't want to ignore errors that occur in the cleanup code, so
+  // if an error is encountered there, leave error_state alone.
+  // Otherwise, set it back to what it was before.
+
+  if (error_state)
+    unwind_protect::discard ();
+  else
+    unwind_protect::run ();
+
+  unwind_protect::run ();
+}
+
+void
+tree_evaluator::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
+{
+  tree_statement_list *cleanup_code = cmd.cleanup ();
+
+  unwind_protect::add (do_unwind_protect_cleanup_code, cleanup_code);
+
+  tree_statement_list *unwind_protect_code = cmd.body ();
+
+  if (unwind_protect_code)
+    unwind_protect_code->accept (*this);
+
+  unwind_protect::run ();
+}
+
+void
+tree_evaluator::visit_while_command (tree_while_command& cmd)
+{
+  if (error_state)
+    return;
+
+  unwind_protect::begin_frame ("tree_evaluator::visit_while_command");
+
+  unwind_protect_bool (in_loop_command);
+
+  in_loop_command = true;
+
+  tree_expression *expr = cmd.condition ();
+
+  if (! expr)
+    panic_impossible ();
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  for (;;)
+    {
+      if (debug_mode)
+	do_breakpoint (cmd.is_breakpoint (), l, c);
+
+      if (expr->is_logically_true ("while"))
+	{
+	  tree_statement_list *loop_body = cmd.body ();
+
+	  if (loop_body)
+	    {
+	      loop_body->accept (*this);
+
+	      if (error_state)
+		goto cleanup;
+	    }
+
+	  if (quit_loop_now ())
+	    break;
+	}
+      else
+	break;
+    }
+
+ cleanup:
+  unwind_protect::run_frame ("tree_evaluator::visit_while_command");
+}
+
+void
+tree_evaluator::visit_do_until_command (tree_do_until_command& cmd)
+{
+  if (error_state)
+    return;
+
+  unwind_protect::begin_frame ("tree_evaluator::visit_do_until_command");
+
+  unwind_protect_bool (in_loop_command);
+
+  in_loop_command = true;
+
+  tree_expression *expr = cmd.condition ();
+
+  if (! expr)
+    panic_impossible ();
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  for (;;)
+    {
+      tree_statement_list *loop_body = cmd.body ();
+
+      if (loop_body)
+	{
+	  loop_body->accept (*this);
+
+	  if (error_state)
+	    goto cleanup;
+	}
+
+      if (quit_loop_now ())
+	break;
+
+      if (debug_mode)
+	do_breakpoint (cmd.is_breakpoint (), l, c);
+
+      if (expr->is_logically_true ("do-until"))
+	break;
+    }
+
+ cleanup:
+  unwind_protect::run_frame ("tree_evaluator::visit_do_until_command");
+}
+
+void
+tree_evaluator::do_breakpoint (tree_statement& stmt) const
+{
+  do_breakpoint (stmt.is_breakpoint (), stmt.line (), stmt.column (),
+		 stmt.is_end_of_fcn_or_script ());
+}
+
+void
+tree_evaluator::do_breakpoint (bool is_breakpoint, int l, int c,
+			       bool is_end_of_fcn_or_script) const
+{
+  bool break_on_this_statement = false;
+
+  // Don't decrement break flag unless we are in the same frame as we
+  // were when we saw the "dbstep N" command.
+
+  if (dbstep_flag > 1)
+    {
+      if (octave_call_stack::current_frame () == current_frame)
+	{
+	  // Don't allow dbstep N to step past end of current frame.
+
+	  if (is_end_of_fcn_or_script)
+	    dbstep_flag = 1;
+	  else
+	    dbstep_flag--;
+	}
+    }
+
+  if (octave_debug_on_interrupt_state)
+    {
+      break_on_this_statement = true;
+
+      octave_debug_on_interrupt_state = false;
+
+      current_frame = octave_call_stack::current_frame ();
+    }
+  else if (is_breakpoint)
+    {
+      break_on_this_statement = true;
+
+      dbstep_flag = 0;
+
+      current_frame = octave_call_stack::current_frame ();
+    }
+  else if (dbstep_flag == 1)
+    {
+      if (octave_call_stack::current_frame () == current_frame)
+	{
+	  // We get here if we are doing a "dbstep" or a "dbstep N"
+	  // and the count has reached 1 and we are in the current
+	  // debugging frame.
+
+	  break_on_this_statement = true;
+
+	  dbstep_flag = 0;
+	}
+    }
+  else if (dbstep_flag == -1)
+    {
+      // We get here if we are doing a "dbstep in".
+
+      break_on_this_statement = true;
+
+      dbstep_flag = 0;
+
+      current_frame = octave_call_stack::current_frame ();
+    }
+  else if (dbstep_flag == -2)
+    {
+      // We get here if we are doing a "dbstep out".
+
+      if (is_end_of_fcn_or_script)
+	dbstep_flag = -1;
+    }
+
+  if (break_on_this_statement)
+    {
+      octave_function *xfcn = octave_call_stack::current ();
+
+      if (xfcn)
+	std::cerr << xfcn->name () << ": "; 
+
+      std::cerr << "line " << l << ", " << "column " << c << std::endl;
+
+      db_line = l;
+      db_column = c;
+
+      // FIXME -- probably we just want to print one line, not the
+      // entire statement, which might span many lines...
+      //
+      // tree_print_code tpc (octave_stdout);
+      // stmt.accept (tpc);
+
+      do_keyboard ();
+    }
+}
+
+DEFUN (silent_functions, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} silent_functions ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} silent_functions (@var{new_val})\n\
+Query or set the internal variable that controls whether internal\n\
+output from a function is suppressed.  If this option is disabled,\n\
+Octave will display the results produced by evaluating expressions\n\
+within a function body that are not terminated with a semicolon.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (silent_functions);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-eval.h b/src/pt-eval.h
new file mode 100644
index 0000000..6a349d8
--- /dev/null
+++ b/src/pt-eval.h
@@ -0,0 +1,184 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_eval_h)
+#define octave_tree_eval_h 1
+
+#include <stack>
+#include <string>
+
+#include "comment-list.h"
+#include "oct-obj.h"
+#include "pt-walk.h"
+
+class tree_expression;
+
+// How to evaluate the code that the parse trees represent.
+
+class
+OCTINTERP_API
+tree_evaluator : public tree_walker
+{
+public:
+
+  typedef void (*decl_elt_init_fcn) (tree_decl_elt&);
+
+  tree_evaluator (void) { }
+
+  ~tree_evaluator (void) { }
+
+  void visit_anon_fcn_handle (tree_anon_fcn_handle&);
+
+  void visit_argument_list (tree_argument_list&);
+
+  void visit_binary_expression (tree_binary_expression&);
+
+  void visit_break_command (tree_break_command&);
+
+  void visit_colon_expression (tree_colon_expression&);
+
+  void visit_continue_command (tree_continue_command&);
+
+  void visit_global_command (tree_global_command&);
+
+  void visit_static_command (tree_static_command&);
+
+  void visit_decl_elt (tree_decl_elt&);
+
+  void visit_decl_init_list (tree_decl_init_list&);
+
+  void visit_simple_for_command (tree_simple_for_command&);
+
+  void visit_complex_for_command (tree_complex_for_command&);
+
+  void visit_octave_user_script (octave_user_script&);
+
+  void visit_octave_user_function (octave_user_function&);
+
+  void visit_octave_user_function_header (octave_user_function&);
+
+  void visit_octave_user_function_trailer (octave_user_function&);
+
+  void visit_function_def (tree_function_def&);
+
+  void visit_identifier (tree_identifier&);
+
+  void visit_if_clause (tree_if_clause&);
+
+  void visit_if_command (tree_if_command&);
+
+  void visit_if_command_list (tree_if_command_list&);
+
+  void visit_index_expression (tree_index_expression&);
+
+  void visit_matrix (tree_matrix&);
+
+  void visit_cell (tree_cell&);
+
+  void visit_multi_assignment (tree_multi_assignment&);
+
+  void visit_no_op_command (tree_no_op_command&);
+
+  void visit_constant (tree_constant&);
+
+  void visit_fcn_handle (tree_fcn_handle&);
+
+  void visit_parameter_list (tree_parameter_list&);
+
+  void visit_postfix_expression (tree_postfix_expression&);
+
+  void visit_prefix_expression (tree_prefix_expression&);
+
+  void visit_return_command (tree_return_command&);
+
+  void visit_return_list (tree_return_list&);
+
+  void visit_simple_assignment (tree_simple_assignment&);
+
+  void visit_statement (tree_statement&);
+
+  void visit_statement_list (tree_statement_list&);
+
+  void visit_switch_case (tree_switch_case&);
+
+  void visit_switch_case_list (tree_switch_case_list&);
+
+  void visit_switch_command (tree_switch_command&);
+
+  void visit_try_catch_command (tree_try_catch_command&);
+
+  void visit_unwind_protect_command (tree_unwind_protect_command&);
+
+  void visit_while_command (tree_while_command&);
+
+  void visit_do_until_command (tree_do_until_command&);
+
+  static int debug_line (void) { return db_line; }
+
+  static int debug_column (void) { return db_column; }
+
+  // If > 0, stop executing at the (N-1)th stopping point, counting
+  //         from the the current execution point in the current frame.
+  //
+  // If < 0, stop executing at the next possible stopping point.
+  static int dbstep_flag;
+
+  // The number of the stack frame we are currently debugging.
+  static size_t current_frame;
+
+  static bool debug_mode;
+
+  // TRUE means we are evaluating a function or script body.
+  static bool in_fcn_or_script_body;
+
+  // TRUE means we are evaluating some kind of looping construct.
+  static bool in_loop_command;
+
+private:
+
+  void do_decl_init_list (decl_elt_init_fcn fcn,
+			  tree_decl_init_list *init_list);
+
+  void do_breakpoint (tree_statement& stmt) const;
+
+  void do_breakpoint (bool is_breakpoint, int l, int c,
+		      bool is_end_of_fcn_or_script = false) const;
+
+  static int db_line;
+  static int db_column;
+
+  // No copying!
+
+  tree_evaluator (const tree_evaluator&);
+
+  tree_evaluator& operator = (const tree_evaluator&);
+};
+
+extern tree_evaluator *current_evaluator;
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-except.cc b/src/pt-except.cc
new file mode 100644
index 0000000..ddbd15d
--- /dev/null
+++ b/src/pt-except.cc
@@ -0,0 +1,107 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "quit.h"
+
+#include "error.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pt-bp.h"
+#include "pt-cmd.h"
+#include "pt-except.h"
+#include "pt-exp.h"
+#include "pt-jump.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "unwind-prot.h"
+#include "variables.h"
+
+// Simple exception handling.
+
+tree_try_catch_command::~tree_try_catch_command (void)
+{
+  delete try_code;
+  delete catch_code;
+  delete lead_comm;
+  delete mid_comm;
+  delete trail_comm;
+}
+
+tree_command *
+tree_try_catch_command::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context) const
+{
+  return new
+    tree_try_catch_command (try_code ? try_code->dup (scope, context) : 0,
+			    catch_code ? catch_code->dup (scope, context) : 0,
+			    lead_comm ? lead_comm->dup () : 0,
+			    mid_comm ? mid_comm->dup () : 0,
+			    trail_comm ? trail_comm->dup () : 0,
+			    line (), column ());
+}
+
+void
+tree_try_catch_command::accept (tree_walker& tw)
+{
+  tw.visit_try_catch_command (*this);
+}
+
+// Simple exception handling.
+
+tree_unwind_protect_command::~tree_unwind_protect_command (void)
+{
+  delete unwind_protect_code;
+  delete cleanup_code;
+  delete lead_comm;
+  delete mid_comm;
+  delete trail_comm;
+}
+
+tree_command *
+tree_unwind_protect_command::dup (symbol_table::scope_id scope,
+				  symbol_table::context_id context) const
+{
+  return new tree_unwind_protect_command
+    (unwind_protect_code ? unwind_protect_code->dup (scope, context) : 0,
+     cleanup_code ? cleanup_code->dup (scope, context) : 0,
+     lead_comm ? lead_comm->dup () : 0,
+     mid_comm ? mid_comm->dup () : 0,
+     trail_comm ? trail_comm->dup () : 0,
+     line (), column ());
+}
+
+void
+tree_unwind_protect_command::accept (tree_walker& tw)
+{
+  tw.visit_unwind_protect_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-except.h b/src/pt-except.h
new file mode 100644
index 0000000..5de1d2a
--- /dev/null
+++ b/src/pt-except.h
@@ -0,0 +1,163 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_except_h)
+#define octave_tree_except_h 1
+
+class tree_statement_list;
+
+class tree_walker;
+
+#include "comment-list.h"
+#include "pt-cmd.h"
+#include "symtab.h"
+
+// Simple exception handling.
+
+class
+tree_try_catch_command : public tree_command
+{
+public:
+
+  tree_try_catch_command (int l = -1, int c = -1)
+    : tree_command (l, c), try_code (0), catch_code (0), lead_comm (0),
+      mid_comm (0), trail_comm (0) { }
+
+  tree_try_catch_command (tree_statement_list *tc, tree_statement_list *cc,
+			  octave_comment_list *cl = 0,
+			  octave_comment_list *cm = 0,
+			  octave_comment_list *ct = 0,
+			  int l = -1, int c = -1)
+    : tree_command (l, c), try_code (tc), catch_code (cc),
+      lead_comm (cl), mid_comm (cm), trail_comm (ct) { }
+
+  ~tree_try_catch_command (void);
+
+  tree_statement_list *body (void) { return try_code; }
+
+  tree_statement_list *cleanup (void) { return catch_code; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *middle_comment (void) { return mid_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The first block of code to attempt to execute.
+  tree_statement_list *try_code;
+
+  // The code to execute if an error occurs in the first block.
+  tree_statement_list *catch_code;
+
+  // Comment preceding TRY token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding CATCH token.
+  octave_comment_list *mid_comm;
+
+  // Comment preceding END_TRY_CATCH token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_try_catch_command (const tree_try_catch_command&);
+
+  tree_try_catch_command& operator = (const tree_try_catch_command&);
+};
+
+// Simple exception handling.
+
+class
+tree_unwind_protect_command : public tree_command
+{
+public:
+
+  tree_unwind_protect_command (int l = -1, int c = -1)
+    : tree_command (l, c), unwind_protect_code (0), cleanup_code (0),
+      lead_comm (0), mid_comm (0), trail_comm (0) { }
+
+  tree_unwind_protect_command (tree_statement_list *tc,
+			       tree_statement_list *cc,
+			       octave_comment_list *cl = 0,
+			       octave_comment_list *cm = 0,
+			       octave_comment_list *ct = 0,
+			       int l = -1, int c = -1)
+    : tree_command (l, c), unwind_protect_code (tc), cleanup_code (cc),
+      lead_comm (cl), mid_comm (cm), trail_comm (ct) { }
+
+  ~tree_unwind_protect_command (void);
+
+  tree_statement_list *body (void) { return unwind_protect_code; }
+
+  tree_statement_list *cleanup (void) { return cleanup_code; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *middle_comment (void) { return mid_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The first body of code to attempt to execute.
+  tree_statement_list *unwind_protect_code;
+
+  // The body of code to execute no matter what happens in the first
+  // body of code.
+  tree_statement_list *cleanup_code;
+
+  // Comment preceding TRY token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding CATCH token.
+  octave_comment_list *mid_comm;
+
+  // Comment preceding END_TRY_CATCH token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_unwind_protect_command (const tree_unwind_protect_command&);
+
+  tree_unwind_protect_command& operator = (const tree_unwind_protect_command&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-exp.cc b/src/pt-exp.cc
new file mode 100644
index 0000000..4698b7f
--- /dev/null
+++ b/src/pt-exp.cc
@@ -0,0 +1,89 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2007, 2008,
+              2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "error.h"
+#include "pager.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pt-exp.h"
+
+// Expressions.
+
+bool
+tree_expression::is_logically_true (const char *warn_for)
+{
+  bool expr_value = false;
+
+  octave_value t1 = rvalue1 ();
+
+  if (! error_state)
+    {
+      if (t1.is_defined ())
+	return t1.is_true ();
+      else
+	::error ("%s: undefined value used in conditional expression",
+		 warn_for);
+    }
+
+  return expr_value;
+}
+
+octave_value
+tree_expression::rvalue1 (int)
+{
+  ::error ("invalid rvalue function called in expression");
+  return octave_value ();
+}
+
+octave_value_list
+tree_expression::rvalue (int)
+{
+  ::error ("invalid rvalue function called in expression");
+  return octave_value_list ();
+}
+
+octave_lvalue
+tree_expression::lvalue (void)
+{
+  ::error ("invalid lvalue function called in expression");
+  return octave_lvalue ();
+}
+
+std::string
+tree_expression::original_text (void) const
+{
+  return std::string ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-exp.h b/src/pt-exp.h
new file mode 100644
index 0000000..1134a00
--- /dev/null
+++ b/src/pt-exp.h
@@ -0,0 +1,152 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_expr_h)
+#define octave_tree_expr_h 1
+
+#include <string>
+
+class octave_value;
+class octave_lvalue;
+
+#include "pt.h"
+#include "symtab.h"
+
+// A base class for expressions.
+
+class
+tree_expression : public tree
+{
+public:
+
+  tree_expression (int l = -1, int c = -1)
+    : tree (l, c), num_parens (0), postfix_indexed (false),
+      print_flag (false) { }
+
+  virtual ~tree_expression (void) { }
+
+  virtual bool has_magic_end (void) const = 0;
+
+  virtual tree_expression *dup (symbol_table::scope_id,
+				symbol_table::context_id context) const = 0;
+
+  virtual bool is_constant (void) const { return false; }
+
+  virtual bool is_matrix_constant (void) const { return false; }
+
+  virtual bool is_identifier (void) const { return false; }
+
+  virtual bool is_index_expression (void) const { return false; }
+
+  virtual bool is_assignment_expression (void) const { return false; }
+
+  virtual bool is_prefix_expression (void) const { return false; }
+
+  virtual bool is_unary_expression (void) const { return false; }
+
+  virtual bool is_binary_expression (void) const { return false; }
+
+  virtual bool is_boolean_expression (void) const { return false; }
+
+  virtual bool is_logically_true (const char *);
+
+  virtual bool lvalue_ok (void) const { return false; }
+
+  virtual bool rvalue_ok (void) const { return false; }
+
+  virtual octave_value rvalue1 (int nargout = 1);
+
+  virtual octave_value_list rvalue (int nargout);
+
+  virtual octave_lvalue lvalue (void);
+
+  int paren_count (void) const { return num_parens; }
+
+  bool is_postfix_indexed (void) const { return postfix_indexed; }
+
+  bool print_result (void) const { return print_flag; }
+
+  virtual std::string oper (void) const { return "<unknown>"; }
+
+  virtual std::string name (void) const { return "<unknown>"; }
+
+  virtual std::string original_text (void) const;
+
+  tree_expression *mark_in_parens (void)
+    {
+      num_parens++;
+      return this;
+    }
+
+  tree_expression *mark_postfix_indexed (void)
+    {
+      postfix_indexed = true;
+      return this;
+    }
+
+  tree_expression *set_print_flag (bool print)
+    {
+      print_flag = print;
+      return this;
+    }
+
+  virtual void copy_base (const tree_expression& e)
+    {
+      num_parens = e.num_parens;
+      postfix_indexed = e.postfix_indexed;
+      print_flag = e.print_flag;
+    }
+
+protected:
+
+  // A count of the number of times this expression appears directly
+  // inside a set of parentheses.
+  //
+  //   (((e1)) + e2)  ==> 2 for expression e1
+  //                  ==> 1 for expression ((e1)) + e2
+  //                  ==> 0 for expression e2
+  int num_parens;
+
+  // A flag that says whether this expression has an index associated
+  // with it.  See the code in tree_identifier::rvalue for the rationale.
+  bool postfix_indexed;
+
+  // Print result of rvalue for this expression?
+  bool print_flag;
+
+private:
+
+  // No copying!
+
+  tree_expression (const tree_expression&);
+
+  tree_expression& operator = (const tree_expression&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-fcn-handle.cc b/src/pt-fcn-handle.cc
new file mode 100644
index 0000000..02885c5
--- /dev/null
+++ b/src/pt-fcn-handle.cc
@@ -0,0 +1,204 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-fcn-handle.h"
+#include "pt-fcn-handle.h"
+#include "pager.h"
+#include "pt-const.h"
+#include "pt-walk.h"
+#include "variables.h"
+
+void
+tree_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax,
+			bool pr_orig_text)
+{
+  print_raw (os, pr_as_read_syntax, pr_orig_text);
+}
+
+void
+tree_fcn_handle::print_raw (std::ostream& os, bool pr_as_read_syntax,
+			    bool pr_orig_text) 
+{
+  os << ((pr_as_read_syntax || pr_orig_text) ? "@" : "") << nm;
+}
+
+octave_value
+tree_fcn_handle::rvalue1 (int)
+{
+  return make_fcn_handle (nm);
+}
+
+octave_value_list
+tree_fcn_handle::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for function handle expression");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+tree_expression *
+tree_fcn_handle::dup (symbol_table::scope_id,
+		      symbol_table::context_id) const
+{
+  tree_fcn_handle *new_fh = new tree_fcn_handle (nm, line (), column ());
+
+  new_fh->copy_base (*this);
+
+  return new_fh;
+}
+
+void
+tree_fcn_handle::accept (tree_walker& tw)
+{
+  tw.visit_fcn_handle (*this);
+}
+
+octave_value
+tree_anon_fcn_handle::rvalue1 (int)
+{
+  // FIXME -- should CMD_LIST be limited to a single expression?
+  // I think that is what Matlab does.
+
+  tree_parameter_list *param_list = parameter_list ();
+  tree_parameter_list *ret_list = return_list ();
+  tree_statement_list *cmd_list = body ();
+  symbol_table::scope_id this_scope = scope ();
+
+  symbol_table::scope_id new_scope = symbol_table::dup_scope (this_scope);
+
+  if (new_scope > 0)
+    symbol_table::inherit (new_scope, symbol_table::current_scope (),
+			   symbol_table::current_context ());
+
+  octave_user_function *uf
+    = new octave_user_function (new_scope,
+				param_list ? param_list->dup (new_scope, 0) : 0,
+				ret_list ? ret_list->dup (new_scope, 0) : 0,
+				cmd_list ? cmd_list->dup (new_scope, 0) : 0);
+
+  octave_function *curr_fcn = octave_call_stack::current ();
+
+  if (curr_fcn)
+    {
+      uf->stash_parent_fcn_name (curr_fcn->name ());
+
+      symbol_table::scope_id parent_scope = curr_fcn->parent_fcn_scope ();
+
+      if (parent_scope < 0)
+	parent_scope = curr_fcn->scope ();
+	
+      uf->stash_parent_fcn_scope (parent_scope);
+    }
+
+  uf->mark_as_inline_function ();
+
+  octave_value ov_fcn (uf);
+
+  octave_value fh (new octave_fcn_handle (ov_fcn, "@<anonymous>"));
+
+  return fh;
+}
+
+/*
+%!function r = f2 (f, x)
+%!  r = f (x);
+%!function f = f1 (k)
+%!  f = @(x) f2 (@(y) y-k, x);
+%!test
+%! assert ((f1 (3)) (10) == 7)
+%!
+%!shared g
+%! g = @(t) feval (@(x) t*x, 2);
+%!assert (g(0.5) == 1)
+%!
+%!shared f, g, h
+%! h = @(x) sin (x);
+%! g = @(f, x) h (x);
+%! f = @() g (@(x) h, pi);
+%!assert (f () == sin (pi))
+*/
+
+octave_value_list
+tree_anon_fcn_handle::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for anonymous function handle expression");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+tree_expression *
+tree_anon_fcn_handle::dup (symbol_table::scope_id,
+			   symbol_table::context_id) const
+{
+  tree_parameter_list *param_list = parameter_list ();
+  tree_parameter_list *ret_list = return_list ();
+  tree_statement_list *cmd_list = body ();
+  symbol_table::scope_id this_scope = scope ();
+
+  symbol_table::scope_id new_scope = symbol_table::dup_scope (this_scope);
+
+  if (new_scope > 0)
+    symbol_table::inherit (new_scope, symbol_table::current_scope (),
+			   symbol_table::current_context ());
+
+  tree_anon_fcn_handle *new_afh = new
+    tree_anon_fcn_handle (param_list ? param_list->dup (new_scope, 0) : 0,
+			  ret_list ? ret_list->dup (new_scope, 0) : 0,
+			  cmd_list ? cmd_list->dup (new_scope, 0) : 0,
+			  new_scope, line (), column ());
+
+  new_afh->copy_base (*this);
+
+  return new_afh;
+}
+
+void
+tree_anon_fcn_handle::accept (tree_walker& tw)
+{
+  tw.visit_anon_fcn_handle (*this);
+}
+
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-fcn-handle.h b/src/pt-fcn-handle.h
new file mode 100644
index 0000000..7b4399a
--- /dev/null
+++ b/src/pt-fcn-handle.h
@@ -0,0 +1,156 @@
+/*
+
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_fcn_handle_h)
+#define octave_fcn_handle_h 1
+
+#include <iosfwd>
+#include <string>
+
+#include "pt-bp.h"
+#include "pt-exp.h"
+#include "pt-misc.h"
+#include "pt-stmt.h"
+#include "symtab.h"
+
+class octave_value_list;
+
+class tree_walker;
+
+#include "ov.h"
+#include "ov-usr-fcn.h"
+#include "symtab.h"
+
+class
+tree_fcn_handle : public tree_expression
+{
+public:
+
+  tree_fcn_handle (int l = -1, int c = -1)
+    : tree_expression (l, c), nm () { }
+
+  tree_fcn_handle (const std::string& n, int l = -1, int c = -1)
+    : tree_expression (l, c), nm (n) { }
+
+  ~tree_fcn_handle (void) { }
+
+  bool has_magic_end (void) const { return false; }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false,
+	      bool pr_orig_txt = true);
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false,
+		  bool pr_orig_txt = true);
+
+  std::string name (void) const { return nm; }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The name of this function handle.
+  std::string nm;
+
+  // No copying!
+
+  tree_fcn_handle (const tree_fcn_handle&);
+
+  tree_fcn_handle& operator = (const tree_fcn_handle&);
+};
+
+class
+tree_anon_fcn_handle : public tree_expression
+{
+public:
+
+  tree_anon_fcn_handle (int l = -1, int c = -1)
+    : tree_expression (l, c), fcn (0) { }
+
+  tree_anon_fcn_handle (tree_parameter_list *pl, tree_parameter_list *rl,
+			tree_statement_list *cl, symbol_table::scope_id sid,
+			int l = -1, int c = -1)
+    : tree_expression (l, c),
+      fcn (new octave_user_function (sid, pl, rl, cl)) { }
+
+  ~tree_anon_fcn_handle (void) { delete fcn; }
+
+  bool has_magic_end (void) const { return false; }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  tree_parameter_list *parameter_list (void) const
+  {
+    return fcn ? fcn->parameter_list () : 0;
+  }
+
+  tree_parameter_list *return_list (void) const
+  {
+    return fcn ? fcn->return_list () : 0;
+  }
+
+  tree_statement_list *body (void) const
+  {
+    return fcn ? fcn->body () : 0;
+  }
+
+  symbol_table::scope_id scope (void) const
+  {
+    return fcn ? fcn->scope () : -1;
+  }
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The function.
+  octave_user_function *fcn;
+
+  // No copying!
+
+  tree_anon_fcn_handle (const tree_anon_fcn_handle&);
+
+  tree_anon_fcn_handle& operator = (const tree_anon_fcn_handle&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-id.cc b/src/pt-id.cc
new file mode 100644
index 0000000..cad5768
--- /dev/null
+++ b/src/pt-id.cc
@@ -0,0 +1,150 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "pager.h"
+#include "pt-bp.h"
+#include "pt-const.h"
+#include "pt-id.h"
+#include "pt-walk.h"
+#include "symtab.h"
+#include "utils.h"
+#include "variables.h"
+
+// Symbols from the symbol table.
+
+void
+tree_identifier::eval_undefined_error (void)
+{
+  int l = line ();
+  int c = column ();
+
+  if (l == -1 && c == -1)
+    ::error ("`%s' undefined", name ().c_str ());
+  else
+    ::error ("`%s' undefined near line %d column %d",
+	     name ().c_str (), l, c);
+}
+
+octave_value_list
+tree_identifier::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  octave_value_list evaluated_args;
+  bool args_evaluated = false;
+
+  octave_value val = xsym().find (0, string_vector (), evaluated_args,
+				  args_evaluated);
+
+  if (val.is_defined ())
+    {
+      // GAGME -- this would be cleaner if we required
+      // parens to indicate function calls.
+      //
+      // If this identifier refers to a function, we need to know
+      // whether it is indexed so that we can do the same thing
+      // for `f' and `f()'.  If the index is present, return the
+      // function object and let tree_index_expression::rvalue
+      // handle indexing.  Otherwise, arrange to call the function
+      // here, so that we don't return the function definition as
+      // a value.
+
+      if (val.is_function () && ! is_postfix_indexed ())
+	{
+	  octave_value_list tmp_args;
+
+	  retval = val.do_multi_index_op (nargout, tmp_args);
+	}
+      else
+	{
+	  if (print_result () && nargout == 0)
+	    val.print_with_name (octave_stdout, name ());
+
+	  retval = val;
+	}
+    }
+  else
+    eval_undefined_error ();
+
+  return retval;
+}
+
+octave_value
+tree_identifier::rvalue1 (int nargout)
+{
+  octave_value retval;
+
+  octave_value_list tmp = rvalue (nargout);
+
+  if (! tmp.empty ())
+    retval = tmp(0);
+
+  return retval;
+}
+
+octave_lvalue
+tree_identifier::lvalue (void)
+{
+  return octave_lvalue (&(xsym().varref ()));
+}
+
+tree_identifier *
+tree_identifier::dup (symbol_table::scope_id sc,
+		      symbol_table::context_id) const
+{
+  // The new tree_identifier object contains a symbol_record
+  // entry from the duplicated scope.
+
+  // FIXME -- is this the best way?
+  symbol_table::symbol_record new_sym
+    = symbol_table::find_symbol (name (), sc);
+
+  tree_identifier *new_id
+    = new tree_identifier (new_sym, line (), column ());
+
+  new_id->copy_base (*this);
+
+  return new_id;
+}
+
+void
+tree_identifier::accept (tree_walker& tw)
+{
+  tw.visit_identifier (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-id.h b/src/pt-id.h
new file mode 100644
index 0000000..b16e5da
--- /dev/null
+++ b/src/pt-id.h
@@ -0,0 +1,153 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
+              2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_identifier_h)
+#define octave_tree_identifier_h 1
+
+#include <iosfwd>
+#include <string>
+
+class octave_value;
+class octave_value_list;
+class octave_function;
+
+class tree_walker;
+
+#include "pt-bp.h"
+#include "pt-exp.h"
+#include "symtab.h"
+
+// Symbols from the symbol table.
+
+class
+tree_identifier : public tree_expression
+{
+  friend class tree_index_expression;
+
+public:
+
+  tree_identifier (int l = -1, int c = -1)
+    : tree_expression (l, c), sym (), scope (-1) { }
+
+  tree_identifier (const symbol_table::symbol_record& s,
+		   int l = -1, int c = -1,
+		   symbol_table::scope_id sc = symbol_table::current_scope ())
+    : tree_expression (l, c), sym (s), scope (sc) { }
+
+  ~tree_identifier (void) { }
+
+  bool has_magic_end (void) const { return (name () == "__end__"); }
+
+  bool is_identifier (void) const { return true; }
+
+  // The name doesn't change with scope, so use sym instead of
+  // accessing it through sym so that this function may remain const.
+  std::string name (void) const { return sym.name (); }
+
+  bool is_defined (void) { return xsym().is_defined (); }
+
+  bool is_variable (void) { return xsym().is_variable (); }
+
+  // Try to find a definition for an identifier.  Here's how:
+  //
+  //   * If the identifier is already defined and is a function defined
+  //     in an function file that has been modified since the last time 
+  //     we parsed it, parse it again.
+  //
+  //   * If the identifier is not defined, try to find a builtin
+  //     variable or an already compiled function with the same name.
+  //
+  //   * If the identifier is still undefined, try looking for an
+  //     function file to parse.
+  //
+  //   * On systems that support dynamic linking, we prefer .oct files,
+  //     then .mex files, then .m files.
+
+  octave_value
+  do_lookup (tree_argument_list *args, const string_vector& arg_names,
+	     octave_value_list& evaluated_args, bool& args_evaluated)
+  {
+    return xsym().find (args, arg_names, evaluated_args, args_evaluated);
+  }
+
+  void mark_global (void) { xsym().mark_global (); }
+
+  void mark_as_static (void) { xsym().init_persistent (); }
+
+  void mark_as_formal_parameter (void) { xsym().mark_formal (); }
+
+  // We really need to know whether this symbol referst to a variable
+  // or a function, but we may not know that yet.
+
+  bool lvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  octave_lvalue lvalue (void);
+
+  void eval_undefined_error (void);
+
+  tree_identifier *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The symbol record that this identifier references.
+  symbol_table::symbol_record sym;
+
+  symbol_table::scope_id scope;
+
+  // A script may be executed in multiple scopes.  If the last one was
+  // different from the one we are in now, update sym to be from the
+  // new scope.
+  symbol_table::symbol_record& xsym (void)
+  {
+    symbol_table::scope_id curr_scope = symbol_table::current_scope ();
+
+    if (scope != curr_scope)
+      {
+	scope = curr_scope;
+	sym = symbol_table::insert (sym.name ());
+      }
+
+    return sym;
+  }
+
+  // No copying!
+
+  tree_identifier (const tree_identifier&);
+
+  tree_identifier& operator = (const tree_identifier&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-idx.cc b/src/pt-idx.cc
new file mode 100644
index 0000000..95460c1
--- /dev/null
+++ b/src/pt-idx.cc
@@ -0,0 +1,678 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Cell.h"
+#include "error.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pager.h"
+#include "pt-arg-list.h"
+#include "pt-bp.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-walk.h"
+#include "utils.h"
+#include "variables.h"
+#include "gripes.h"
+
+// Index expressions.
+
+tree_index_expression::tree_index_expression (int l, int c)
+  : tree_expression (l, c), expr (0), args (0), type (),
+    arg_nm (), dyn_field () { }
+
+tree_index_expression::tree_index_expression (tree_expression *e,
+					      tree_argument_list *lst,
+					      int l, int c, char t)
+  : tree_expression (l, c), expr (e), args (0), type (),
+    arg_nm (), dyn_field ()
+{
+  append (lst, t);
+}
+
+tree_index_expression::tree_index_expression (tree_expression *e,
+					      const std::string& n,
+					      int l, int c)
+  : tree_expression (l, c), expr (e), args (0), type (),
+    arg_nm (), dyn_field ()
+{
+  append (n);
+}
+
+tree_index_expression::tree_index_expression (tree_expression *e,
+					      tree_expression *df,
+					      int l, int c)
+  : tree_expression (l, c), expr (e), args (0), type (),
+    arg_nm (), dyn_field ()
+{
+  append (df);
+}
+
+void
+tree_index_expression::append (tree_argument_list *lst, char t)
+{
+  args.push_back (lst);
+  type.append (1, t);
+  arg_nm.push_back (lst ? lst->get_arg_names () : string_vector ());
+  dyn_field.push_back (static_cast<tree_expression *> (0));
+}
+
+void
+tree_index_expression::append (const std::string& n)
+{
+  args.push_back (static_cast<tree_argument_list *> (0));
+  type.append (".");
+  arg_nm.push_back (n);
+  dyn_field.push_back (static_cast<tree_expression *> (0));
+}
+
+void
+tree_index_expression::append (tree_expression *df)
+{
+  args.push_back (static_cast<tree_argument_list *> (0));
+  type.append (".");
+  arg_nm.push_back ("");
+  dyn_field.push_back (df);
+}
+
+tree_index_expression::~tree_index_expression (void)
+{
+  delete expr;
+
+  while (! args.empty ())
+    {
+      std::list<tree_argument_list *>::iterator p = args.begin ();
+      delete *p;
+      args.erase (p);
+    }
+}
+
+bool
+tree_index_expression::has_magic_end (void) const
+{
+  for (std::list<tree_argument_list *>::const_iterator p = args.begin ();
+       p != args.end ();
+       p++)
+    {
+      tree_argument_list *elt = *p;
+
+      if (elt && elt->has_magic_end ())
+	return true;
+    }
+  
+  return false;
+}
+
+// This is useful for printing the name of the variable in an indexed
+// assignment.
+
+std::string
+tree_index_expression::name (void) const
+{
+  return expr->name ();
+}
+
+static Cell
+make_subs_cell (tree_argument_list *args, const string_vector& arg_nm)
+{
+  Cell retval;
+
+  octave_value_list arg_values;
+
+  if (args)
+    arg_values = args->convert_to_const_vector ();
+
+  if (! error_state)
+    {
+      int n = arg_values.length ();
+
+      if (n > 0)
+	{
+	  arg_values.stash_name_tags (arg_nm);
+
+	  retval.resize (dim_vector (1, n));
+
+	  for (int i = 0; i < n; i++)
+	    retval(0,i) = arg_values(i);
+	}
+    }
+
+  return retval;
+}
+
+static inline octave_value_list
+make_value_list (tree_argument_list *args, const string_vector& arg_nm,
+		 const octave_value *object)
+{
+  octave_value_list retval;
+
+  if (args)
+    {
+      if (object && args->has_magic_end () && object->is_undefined ())
+        gripe_invalid_inquiry_subscript ();
+      else
+        retval = args->convert_to_const_vector (object);
+    }
+
+  if (! error_state)
+    {
+      int n = retval.length ();
+
+      if (n > 0)
+	retval.stash_name_tags (arg_nm);
+    }
+
+  return retval;
+}
+
+std::string
+tree_index_expression::get_struct_index
+  (std::list<string_vector>::const_iterator p_arg_nm,
+   std::list<tree_expression *>::const_iterator p_dyn_field) const
+{
+  std::string fn = (*p_arg_nm)(0);
+
+  if (fn.empty ())
+    {
+      tree_expression *df = *p_dyn_field;
+
+      if (df)
+	{
+	  octave_value t = df->rvalue1 ();
+
+	  if (! error_state)
+	    {
+	      fn = t.string_value ();
+
+	      if (! valid_identifier (fn))
+		::error ("invalid structure field name `%s'", fn.c_str ());
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+
+  return fn;
+}
+
+Octave_map
+tree_index_expression::make_arg_struct (void) const
+{
+  int n = args.size ();
+
+  Cell type_field (n, 1);
+  Cell subs_field (n, 1);
+
+  std::list<tree_argument_list *>::const_iterator p_args = args.begin ();
+  std::list<string_vector>::const_iterator p_arg_nm = arg_nm.begin ();
+  std::list<tree_expression *>::const_iterator p_dyn_field = dyn_field.begin ();
+
+  Octave_map m;
+
+  for (int i = 0; i < n; i++)
+    {
+      switch (type[i])
+	{
+	case '(':
+	  subs_field(i) = make_subs_cell (*p_args, *p_arg_nm);
+	  break;
+
+	case '{':
+	  subs_field(i) = make_subs_cell (*p_args, *p_arg_nm);
+	  break;
+
+	case '.':
+	  subs_field(i) = get_struct_index (p_arg_nm, p_dyn_field);
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+
+      if (error_state)
+	return m;
+
+      p_args++;
+      p_arg_nm++;
+      p_dyn_field++;
+    }
+
+  m.assign ("type", type_field);
+  m.assign ("subs", subs_field);
+
+  return m;
+}
+
+octave_value_list
+tree_index_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  octave_value first_expr_val;
+
+  octave_value_list first_args;
+
+  bool have_args = false;
+
+  if (expr->is_identifier () && type[0] == '(')
+    {
+      tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
+
+      if (! (id->is_variable () || args.empty ()))
+	{
+	  tree_argument_list *al = *(args.begin ());
+
+	  size_t n = al ? al->length () : 0;
+
+	  if (n > 0)
+	    {
+	      string_vector anm = *(arg_nm.begin ());
+
+	      first_expr_val = id->do_lookup  (al, anm, first_args, have_args);
+	    }
+	}
+    }
+
+  if (! error_state)
+    {
+      if (first_expr_val.is_undefined ())
+	first_expr_val = expr->rvalue1 ();
+
+      octave_value tmp = first_expr_val;
+      octave_idx_type tmpi = 0;
+
+      std::list<octave_value_list> idx;
+
+      int n = args.size ();
+
+      std::list<tree_argument_list *>::iterator p_args = args.begin ();
+      std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
+      std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
+
+      for (int i = 0; i < n; i++)
+	{
+	  if (i > 0)
+	    {
+	      tree_argument_list *al = *p_args;
+
+	      if (al && al->has_magic_end ())
+		{
+		  // We have an expression like
+		  //
+		  //   x{end}.a(end)
+		  //
+		  // and we are looking at the argument list that
+		  // contains the second (or third, etc.) "end" token,
+		  // so we must evaluate everything up to the point of
+		  // that argument list so we can pass the appropriate
+		  // value to the built-in __end__ function.
+
+		  const octave_value_list tmp_list
+		    = tmp.subsref (type.substr (tmpi, i - tmpi), idx, nargout);
+
+		  tmp = tmp_list(0);
+                  tmpi = i;
+                  idx.clear ();
+                  
+                  if (tmp.is_cs_list ())
+                    gripe_indexed_cs_list ();
+
+		  if (error_state)
+		    break;
+		}
+	    }
+
+	  switch (type[i])
+	    {
+	    case '(':
+	      if (have_args)
+		{
+		  idx.push_back (first_args);
+		  have_args = false;
+		}
+	      else
+		idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
+	      break;
+
+	    case '{':
+	      idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
+	      break;
+
+	    case '.':
+	      idx.push_back (octave_value (get_struct_index (p_arg_nm, p_dyn_field)));
+	      break;
+
+	    default:
+	      panic_impossible ();
+	    }
+
+	  if (error_state)
+	    break;
+
+	  p_args++;
+	  p_arg_nm++;
+	  p_dyn_field++;
+	}
+
+      if (! error_state)
+	retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout);
+    }
+
+  return retval;
+}
+
+octave_value
+tree_index_expression::rvalue1 (int nargout)
+{
+  octave_value retval;
+
+  const octave_value_list tmp = rvalue (nargout);
+
+  if (! tmp.empty ())
+    retval = tmp(0);
+
+  return retval;
+}
+
+static octave_idx_type
+get_numel (const octave_value& val,
+           const octave_value_list& idx)
+{
+  octave_idx_type retval;
+
+  octave_idx_type len = idx.length ();
+
+  if (len == 0)
+    retval = val.numel ();
+  else
+    {
+      const dim_vector dv = val.dims ().redim (len);
+      retval = 1;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          if (idx(i).is_magic_colon ())
+            retval *= dv(i);
+          else
+            retval *= idx(i).numel ();
+        }
+    }
+
+  return retval;
+}
+
+octave_lvalue
+tree_index_expression::lvalue (void)
+{
+  octave_lvalue retval;
+
+  std::list<octave_value_list> idx;
+  std::string tmp_type;
+
+  int n = args.size ();
+
+  std::list<tree_argument_list *>::iterator p_args = args.begin ();
+  std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
+  std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
+
+  retval = expr->lvalue ();
+
+  if (! error_state)
+    {
+      const octave_value *tro = retval.object ();
+
+      octave_value tmp;
+
+      if (tro)
+	tmp = *tro;
+
+      octave_idx_type tmpi = 0;
+      std::list<octave_value_list> tmpidx;
+
+      for (int i = 0; i < n; i++)
+	{
+          if (retval.numel () != 1)
+            gripe_indexed_cs_list ();
+          else if (tmpi < i)
+            {
+              tmp = tmp.subsref (type.substr (tmpi, i - tmpi), tmpidx, true);
+              tmpidx.clear ();
+            }
+
+          if (error_state)
+            break;
+
+	  switch (type[i])
+	    {
+	    case '(':
+              {
+                octave_value_list tidx
+                  = make_value_list (*p_args, *p_arg_nm, &tmp);
+
+                idx.push_back (tidx);
+
+                if (i < n - 1)
+                  {
+                    if (type[i+1] == '.')
+                      {
+                        tmpidx.push_back (tidx);
+                        tmpi = i+1;
+                      }
+                    else
+                      error ("() must be followed by . or close the index chain");
+                  }
+              }
+              break;
+
+	    case '{':
+	      {
+		octave_value_list tidx
+		  = make_value_list (*p_args, *p_arg_nm, &tmp);
+
+                if (tmp.is_undefined ())
+                  {
+                    if (tidx.has_magic_colon ())
+                      gripe_invalid_inquiry_subscript ();
+                    else
+                      tmp = Cell ();
+                  }
+                else if (tmp.is_zero_by_zero () 
+                         && (tmp.is_matrix_type () || tmp.is_string ()))
+                  {
+                    tmp = Cell ();
+                  }
+
+                retval.numel (get_numel (tmp, tidx));
+
+                if (error_state)
+                  break;
+
+		idx.push_back (tidx);
+                tmpidx.push_back (tidx);
+                tmpi = i;
+	      }
+	      break;
+
+	    case '.':
+	      {
+		octave_value tidx = get_struct_index (p_arg_nm, p_dyn_field);
+                if (error_state)
+                  break;
+
+                bool autoconv = (tmp.is_zero_by_zero () 
+                                 && (tmp.is_matrix_type () || tmp.is_string ()
+                                     || tmp.is_cell ()));
+
+                if (i > 0 && type [i-1] == '(')
+                  {
+                    octave_value_list pidx = idx.back ();
+
+                    if (tmp.is_undefined ())
+                      {
+                        if (pidx.has_magic_colon ())
+                          gripe_invalid_inquiry_subscript ();
+                        else
+                          tmp = Octave_map ();
+                      }
+                    else if (autoconv)
+                      tmp = Octave_map ();
+
+                    retval.numel (get_numel (tmp, pidx));
+
+                    tmpi = i-1;
+                    tmpidx.push_back (tidx);
+                  }
+                else
+                  {
+                    if (tmp.is_undefined () || autoconv)
+                      {
+                        tmpi = i+1;
+                        tmp = octave_value ();
+                      }
+                    else
+                      {
+                        retval.numel (get_numel (tmp, octave_value_list ()));
+
+                        tmpi = i;
+                        tmpidx.push_back (tidx);
+                      }
+                  }
+
+                if (error_state)
+                  break;
+
+                idx.push_back (tidx);
+	      }
+	      break;
+
+	    default:
+	      panic_impossible ();
+	    }
+
+          if (idx.back ().empty ())
+            error ("invalid empty index list");
+
+	  if (error_state)
+	    break;
+
+	  p_args++;
+	  p_arg_nm++;
+	  p_dyn_field++;
+	}
+
+      if (! error_state)
+	retval.set_index (type, idx);
+
+    }
+
+  return retval;
+}
+
+/*
+%!test
+%! x = {1, 2, 3};
+%! [x{:}] = deal (4, 5, 6);
+%! assert (x, {4, 5, 6});
+
+%!test
+%! [x.a, x.b.c] = deal (1, 2);
+%! assert (x.a == 1 && x.b.c == 2);
+
+%!test
+%! [x.a, x(2).b] = deal (1, 2);
+%! assert (x(1).a == 1 && isempty (x(2).a) && isempty (x(1).b) && x(2).b == 2);
+
+%!test
+%! x = struct (zeros (0, 1), {"a", "b"});
+%! x(2).b = 1;
+%! assert (x(2).b == 1);
+
+%!test
+%! x = struct (zeros (0, 1), {"a", "b"});
+%! x(2).b = 1;
+%! assert (x(2).b == 1);
+*/
+
+tree_index_expression *
+tree_index_expression::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const
+{
+  tree_index_expression *new_idx_expr
+    = new tree_index_expression (line (), column ());
+
+  new_idx_expr->expr = expr ? expr->dup (scope, context) : 0;
+
+  std::list<tree_argument_list *> new_args;
+
+  for (std::list<tree_argument_list *>::const_iterator p = args.begin ();
+       p != args.end ();
+       p++)
+    {
+      const tree_argument_list *elt = *p;
+
+      new_args.push_back (elt ? elt->dup (scope, context) : 0);
+    }
+
+  new_idx_expr->args = new_args;
+  
+  new_idx_expr->type = type;
+
+  new_idx_expr->arg_nm = arg_nm;
+
+  std::list<tree_expression *> new_dyn_field;
+
+  for (std::list<tree_expression *>::const_iterator p = dyn_field.begin ();
+       p != dyn_field.end ();
+       p++)
+    {
+      const tree_expression *elt = *p;
+
+      new_dyn_field.push_back (elt ? elt->dup (scope, context) : 0);
+    }
+
+  new_idx_expr->dyn_field = new_dyn_field;
+
+  new_idx_expr->copy_base (*this);
+  
+  return new_idx_expr;
+}
+
+void
+tree_index_expression::accept (tree_walker& tw)
+{
+  tw.visit_index_expression (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-idx.h b/src/pt-idx.h
new file mode 100644
index 0000000..2882ba1
--- /dev/null
+++ b/src/pt-idx.h
@@ -0,0 +1,136 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_index_h)
+#define octave_tree_index_h 1
+
+#include <list>
+
+class tree_argument_list;
+
+class tree_walker;
+
+class Octave_map;
+class octave_value;
+class octave_value_list;
+class octave_lvalue;
+
+#include "str-vec.h"
+
+#include "pt-exp.h"
+#include "symtab.h"
+
+// Index expressions.
+
+class
+tree_index_expression : public tree_expression
+{
+public:
+
+  tree_index_expression (tree_expression *e = 0, tree_argument_list *lst = 0,
+			 int l = -1, int c = -1, char t = '(');
+
+  tree_index_expression (tree_expression *e, const std::string& n,
+			 int l = -1, int c = -1);
+
+  tree_index_expression (tree_expression *e, tree_expression* df,
+			 int l = -1, int c = -1);
+
+  ~tree_index_expression (void);
+
+  bool has_magic_end (void) const;
+
+  void append (tree_argument_list *lst = 0, char t = '(');
+
+  void append (const std::string& n);
+
+  void append (tree_expression *df);
+
+  bool is_index_expression (void) const { return true; }
+
+  std::string name (void) const;
+
+  tree_expression *expression (void) { return expr; }
+
+  std::list<tree_argument_list *> arg_lists (void) { return args; }
+
+  std::string type_tags (void) { return type; }
+
+  std::list<string_vector> arg_names (void) { return arg_nm; }
+
+  bool lvalue_ok (void) const { return expr->lvalue_ok (); }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  octave_lvalue lvalue (void);
+
+  tree_index_expression *dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The LHS of this index expression.
+  tree_expression *expr;
+
+  // The indices (only valid if type == paren || type == brace).
+  std::list<tree_argument_list *> args;
+
+  // The type of this index expression.
+  std::string type;
+
+  // The names of the arguments.  Used for constant struct element
+  // references.
+  std::list<string_vector> arg_nm;
+
+  // The list of dynamic field names, if any.
+  std::list<tree_expression *> dyn_field;
+
+  tree_index_expression (int l, int c);
+
+  Octave_map make_arg_struct (void) const;
+
+  std::string
+  get_struct_index
+    (std::list<string_vector>::const_iterator p_arg_nm,
+     std::list<tree_expression *>::const_iterator p_dyn_field) const; 
+
+  // No copying!
+
+  tree_index_expression (const tree_index_expression&);
+
+  tree_index_expression& operator = (const tree_index_expression&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-jump.cc b/src/pt-jump.cc
new file mode 100644
index 0000000..d9f2995
--- /dev/null
+++ b/src/pt-jump.cc
@@ -0,0 +1,94 @@
+/*
+
+Copyright (C) 1996, 1997, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "pt-bp.h"
+#include "pt-jump.h"
+#include "pt-walk.h"
+
+class octave_value_list;
+
+// Break.
+
+// Nonzero means we're breaking out of a loop or function body.
+int tree_break_command::breaking = 0;
+
+tree_command *
+tree_break_command::dup (symbol_table::scope_id,
+			 symbol_table::context_id) const
+{
+  return new tree_break_command (line (), column ());
+}
+
+void
+tree_break_command::accept (tree_walker& tw)
+{
+  tw.visit_break_command (*this);
+}
+
+// Continue.
+
+// Nonzero means we're jumping to the end of a loop.
+int tree_continue_command::continuing = 0;
+
+tree_command *
+tree_continue_command::dup (symbol_table::scope_id,
+			    symbol_table::context_id) const
+{
+  return new tree_continue_command (line (), column ());
+}
+
+void
+tree_continue_command::accept (tree_walker& tw)
+{
+  tw.visit_continue_command (*this);
+}
+
+// Return.
+
+// Nonzero means we're returning from a function.
+int tree_return_command::returning = 0;
+
+tree_command *
+tree_return_command::dup (symbol_table::scope_id,
+			  symbol_table::context_id) const
+{
+  return new tree_return_command (line (), column ());
+}
+
+void
+tree_return_command::accept (tree_walker& tw)
+{
+  tw.visit_return_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-jump.h b/src/pt-jump.h
new file mode 100644
index 0000000..ad65227
--- /dev/null
+++ b/src/pt-jump.h
@@ -0,0 +1,122 @@
+/*
+
+Copyright (C) 1996, 1997, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_jump_h)
+#define octave_tree_jump_h 1
+
+class tree_walker;
+
+#include "pt-cmd.h"
+#include "symtab.h"
+
+// Break.
+
+class
+tree_break_command : public tree_command
+{
+public:
+
+  tree_break_command (int l = -1, int c = -1)
+    : tree_command (l, c) { }
+
+  ~tree_break_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  static int breaking;
+
+private:
+
+  // No copying!
+
+  tree_break_command (const tree_break_command&);
+
+  tree_break_command& operator = (const tree_break_command&);
+};
+
+// Continue.
+
+class
+tree_continue_command : public tree_command
+{
+public:
+
+  tree_continue_command (int l = -1, int c = -1)
+    : tree_command (l, c) { }
+
+  ~tree_continue_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  static int continuing;
+
+private:
+
+  // No copying!
+
+  tree_continue_command (const tree_continue_command&);
+
+  tree_continue_command& operator = (const tree_continue_command&);
+};
+
+// Return.
+
+class
+tree_return_command : public tree_command
+{
+public:
+
+  tree_return_command (int l = -1, int c = -1)
+    : tree_command (l, c) { }
+
+  ~tree_return_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+  static int returning;
+
+private:
+
+  // No copying!
+
+  tree_return_command (const tree_return_command&);
+
+  tree_return_command& operator = (const tree_return_command&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-loop.cc b/src/pt-loop.cc
new file mode 100644
index 0000000..491e06d
--- /dev/null
+++ b/src/pt-loop.cc
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "quit.h"
+
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pt-arg-list.h"
+#include "pt-bp.h"
+#include "pt-cmd.h"
+#include "pt-exp.h"
+#include "pt-jump.h"
+#include "pt-loop.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "unwind-prot.h"
+
+// While.
+
+tree_while_command::~tree_while_command (void)
+{
+  delete expr;
+  delete list;
+  delete lead_comm;
+  delete trail_comm;
+}
+
+tree_command *
+tree_while_command::dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context) const
+{
+  return new tree_while_command (expr ? expr->dup (scope, context) : 0,
+				 list ? list->dup (scope, context) : 0,
+				 lead_comm ? lead_comm->dup () : 0,
+				 trail_comm ? trail_comm->dup (): 0,
+				 line (), column ());
+}
+
+void
+tree_while_command::accept (tree_walker& tw)
+{
+  tw.visit_while_command (*this);
+}
+
+// Do-Until
+
+tree_command *
+tree_do_until_command::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const
+{
+  return new tree_do_until_command (expr ? expr->dup (scope, context) : 0,
+				    list ? list->dup (scope, context) : 0,
+				    lead_comm ? lead_comm->dup () : 0,
+				    trail_comm ? trail_comm->dup (): 0,
+				    line (), column ());
+}
+
+void
+tree_do_until_command::accept (tree_walker& tw)
+{
+  tw.visit_do_until_command (*this);
+}
+
+// For.
+
+tree_simple_for_command::~tree_simple_for_command (void)
+{
+  delete expr;
+  delete list;
+  delete lead_comm;
+  delete trail_comm;
+}
+
+tree_command *
+tree_simple_for_command::dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context) const
+{
+  return new tree_simple_for_command (lhs ? lhs->dup (scope, context) : 0,
+				      expr ? expr->dup (scope, context) : 0,
+				      list ? list->dup (scope, context) : 0,
+				      lead_comm ? lead_comm->dup () : 0,
+				      trail_comm ? trail_comm->dup () : 0,
+				      line (), column ());
+}
+
+void
+tree_simple_for_command::accept (tree_walker& tw)
+{
+  tw.visit_simple_for_command (*this);
+}
+
+tree_complex_for_command::~tree_complex_for_command (void)
+{
+  delete expr;
+  delete list;
+  delete lead_comm;
+  delete trail_comm;
+}
+
+tree_command *
+tree_complex_for_command::dup (symbol_table::scope_id scope,
+			       symbol_table::context_id context) const
+{
+  return new tree_complex_for_command (lhs ? lhs->dup (scope, context) : 0,
+				       expr ? expr->dup (scope, context) : 0,
+				       list ? list->dup (scope, context) : 0,
+				       lead_comm ? lead_comm->dup () : 0,
+				       trail_comm ? trail_comm->dup () : 0,
+				       line (), column ());
+}
+
+void
+tree_complex_for_command::accept (tree_walker& tw)
+{
+  tw.visit_complex_for_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-loop.h b/src/pt-loop.h
new file mode 100644
index 0000000..0fade61
--- /dev/null
+++ b/src/pt-loop.h
@@ -0,0 +1,265 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_loop_h)
+#define octave_tree_loop_h 1
+
+class octave_value;
+class octave_lvalue;
+
+class tree_argument_list;
+class tree_expression;
+class tree_statement_list;
+
+class tree_walker;
+
+#include "comment-list.h"
+#include "pt-cmd.h"
+#include "symtab.h"
+
+// While.
+
+class
+tree_while_command : public tree_command
+{
+public:
+
+  tree_while_command (int l = -1, int c = -1)
+    : tree_command (l, c), expr (0), list (0), lead_comm (0),
+      trail_comm (0) { }
+
+  tree_while_command (tree_expression *e,
+		      octave_comment_list *lc = 0,
+		      octave_comment_list *tc = 0,
+		      int l = -1, int c = -1)
+    : tree_command (l, c), expr (e), list (0), lead_comm (lc),
+      trail_comm (tc) { }
+
+  tree_while_command (tree_expression *e, tree_statement_list *lst,
+		      octave_comment_list *lc = 0,
+		      octave_comment_list *tc = 0,
+		      int l = -1, int c = -1)
+    : tree_command (l, c), expr (e), list (lst), lead_comm (lc),
+      trail_comm (tc) { }
+
+  ~tree_while_command (void);
+
+  tree_expression *condition (void) { return expr; }
+
+  tree_statement_list *body (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+protected:
+
+  // Expression to test.
+  tree_expression *expr;
+
+  // List of commands to execute.
+  tree_statement_list *list;
+
+  // Comment preceding WHILE token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding ENDWHILE token.
+  octave_comment_list *trail_comm;
+
+private:
+
+  // No copying!
+
+  tree_while_command (const tree_while_command&);
+
+  tree_while_command& operator = (const tree_while_command&);
+};
+
+// Do-Until.
+
+class
+tree_do_until_command : public tree_while_command
+{
+public:
+
+  tree_do_until_command (int l = -1, int c = -1)
+    : tree_while_command (l, c) { }
+
+  tree_do_until_command (tree_expression *e,
+			 octave_comment_list *lc = 0,
+			 octave_comment_list *tc = 0,
+			 int l = -1, int c = -1)
+    : tree_while_command (e, lc, tc, l, c) { }
+
+  tree_do_until_command (tree_expression *e, tree_statement_list *lst,
+			 octave_comment_list *lc = 0,
+			 octave_comment_list *tc = 0,
+			 int l = -1, int c = -1)
+    : tree_while_command (e, lst, lc, tc, l, c) { }
+
+  ~tree_do_until_command (void) { }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_do_until_command (const tree_do_until_command&);
+
+  tree_do_until_command& operator = (const tree_do_until_command&);
+};
+
+// For.
+
+class
+tree_simple_for_command : public tree_command
+{
+public:
+
+  tree_simple_for_command (int l = -1, int c = -1)
+    : tree_command (l, c), lhs (0), expr (0), list (0), lead_comm (0),
+      trail_comm (0) { }
+
+  tree_simple_for_command (tree_expression *le, tree_expression *re,
+			   tree_statement_list *lst,
+			   octave_comment_list *lc = 0,
+			   octave_comment_list *tc = 0,
+			   int l = -1, int c = -1)
+    : tree_command (l, c), lhs (le), expr (re), list (lst),
+      lead_comm (lc), trail_comm (tc) { }
+
+  ~tree_simple_for_command (void);
+
+  tree_expression *left_hand_side (void) { return lhs; }
+
+  tree_expression *control_expr (void) { return expr; }
+
+  tree_statement_list *body (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Expression to modify.
+  tree_expression *lhs;
+
+  // Expression to evaluate.
+  tree_expression *expr;
+
+  // List of commands to execute.
+  tree_statement_list *list;
+
+  // Comment preceding FOR token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding ENDFOR token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_simple_for_command (const tree_simple_for_command&);
+
+  tree_simple_for_command& operator = (const tree_simple_for_command&);
+};
+
+class
+tree_complex_for_command : public tree_command
+{
+public:
+
+  tree_complex_for_command (int l = -1, int c = -1)
+    : tree_command (l, c), lhs (0), expr (0), list (0), lead_comm (0),
+      trail_comm (0) { }
+
+  tree_complex_for_command (tree_argument_list *le, tree_expression *re,
+			    tree_statement_list *lst,
+			    octave_comment_list *lc = 0,
+			    octave_comment_list *tc = 0,
+			    int l = -1, int c = -1)
+    : tree_command (l, c), lhs (le), expr (re), list (lst),
+      lead_comm (lc), trail_comm (tc) { }
+
+  ~tree_complex_for_command (void);
+
+  tree_argument_list *left_hand_side (void) { return lhs; }
+
+  tree_expression *control_expr (void) { return expr; }
+
+  tree_statement_list *body (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Expression to modify.
+  tree_argument_list *lhs;
+
+  // Expression to evaluate.
+  tree_expression *expr;
+
+  // List of commands to execute.
+  tree_statement_list *list;
+
+  // Comment preceding FOR token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding ENDFOR token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_complex_for_command (const tree_complex_for_command&);
+
+  tree_complex_for_command& operator = (const tree_complex_for_command&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-mat.cc b/src/pt-mat.cc
new file mode 100644
index 0000000..a5e48ac
--- /dev/null
+++ b/src/pt-mat.cc
@@ -0,0 +1,1104 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "quit.h"
+
+#include "defun.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "pt-arg-list.h"
+#include "pt-bp.h"
+#include "pt-exp.h"
+#include "pt-mat.h"
+#include "pt-walk.h"
+#include "utils.h"
+#include "ov.h"
+#include "variables.h"
+
+#include "ov-cx-mat.h"
+#include "ov-flt-cx-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// The character to fill with when creating string arrays.
+char Vstring_fill_char = ' ';
+
+// General matrices.  This list type is much more work to handle than
+// constant matrices, but it allows us to construct matrices from
+// other matrices, variables, and functions.
+
+// But first, some internal classes that make our job much easier.
+
+class
+tm_row_const
+{
+private:
+
+  class
+  tm_row_const_rep : public octave_base_list<octave_value>
+  {
+  public:
+
+    tm_row_const_rep (void)
+      : count (1), dv (0, 0), all_str (false),
+	all_sq_str (false), all_dq_str (false),
+	some_str (false), all_real (false), all_cmplx (false),
+	all_mt (true), any_sparse (false), any_class (false),
+	class_nm (), ok (false)
+    { }
+
+    tm_row_const_rep (const tree_argument_list& row)
+      : count (1), dv (0, 0), all_str (false), all_sq_str (false),
+	some_str (false), all_real (false), all_cmplx (false),
+	all_mt (true), any_sparse (false), any_class (false),
+	class_nm (), ok (false)
+    { init (row); }
+
+    ~tm_row_const_rep (void) { }
+
+    int count;
+
+    dim_vector dv;
+
+    bool all_str;
+    bool all_sq_str;
+    bool all_dq_str;
+    bool some_str;
+    bool all_real;
+    bool all_cmplx;
+    bool all_mt;
+    bool any_sparse;
+    bool any_class;
+
+    std::string class_nm;
+
+    bool ok;
+
+    bool do_init_element (tree_expression *, const octave_value&, bool&);
+
+    void init (const tree_argument_list&);
+
+  private:
+
+    tm_row_const_rep (const tm_row_const_rep&);
+
+    tm_row_const_rep& operator = (const tm_row_const_rep&);
+
+    void eval_error (const char *msg, int l, int c,
+		     int x = -1, int y = -1) const;
+
+    void eval_warning (const char *msg, int l, int c) const;
+  };
+
+public:
+
+  typedef tm_row_const_rep::iterator iterator;
+  typedef tm_row_const_rep::const_iterator const_iterator;
+
+  tm_row_const (void)
+    : rep (0) { }
+
+  tm_row_const (const tree_argument_list& row)
+    : rep (new tm_row_const_rep (row)) { }
+
+  tm_row_const (const tm_row_const& x)
+    : rep (x.rep)
+  {
+    if (rep)
+      rep->count++;
+  }
+
+  tm_row_const& operator = (const tm_row_const& x)
+  {
+    if (this != &x && rep != x.rep)
+      {
+	if (rep && --rep->count == 0)
+	  delete rep;
+
+	rep = x.rep;
+
+	if (rep)
+	  rep->count++;
+      }
+
+    return *this;
+  }
+
+  ~tm_row_const (void)
+  {
+    if (rep && --rep->count == 0)
+      delete rep;
+  }
+
+  octave_idx_type rows (void) { return rep->dv(0); }
+  octave_idx_type cols (void) { return rep->dv(1); }
+
+  bool empty (void) const { return rep->empty (); }
+
+  size_t length (void) const { return rep->length (); }
+
+  dim_vector dims (void) { return rep->dv; }
+
+  bool all_strings_p (void) const { return rep->all_str; }
+  bool all_sq_strings_p (void) const { return rep->all_sq_str; }
+  bool all_dq_strings_p (void) const { return rep->all_dq_str; }
+  bool some_strings_p (void) const { return rep->some_str; }
+  bool all_real_p (void) const { return rep->all_real; }
+  bool all_complex_p (void) const { return rep->all_cmplx; }
+  bool all_empty_p (void) const { return rep->all_mt; }
+  bool any_sparse_p (void) const { return rep->any_sparse; }
+  bool any_class_p (void) const { return rep->any_class; }
+
+  std::string class_name (void) const { return rep->class_nm; }
+
+  operator bool () const { return (rep && rep->ok); }
+
+  iterator begin (void) { return rep->begin (); }
+  const_iterator begin (void) const { return rep->begin (); }
+
+  iterator end (void) { return rep->end (); }
+  const_iterator end (void) const { return rep->end (); }
+
+private:
+
+  tm_row_const_rep *rep;
+};
+
+std::string
+get_concat_class (const std::string& c1, const std::string& c2)
+{
+  std::string retval = octave_base_value::static_class_name ();
+
+  if (c1 == c2)
+    retval = c1;
+  else if (c1.empty ())
+    retval = c2;
+  else if (c2.empty ())
+    retval = c1;
+  else
+    {
+      bool c1_is_int = (c1 == "int8" || c1 == "uint8"
+			|| c1 == "int16" || c1 == "uint16"
+			|| c1 == "int32" || c1 == "uint32"
+			|| c1 == "int64" || c1 == "uint64");
+      bool c2_is_int = (c2 == "int8" || c2 == "uint8"
+			|| c2 == "int16" || c2 == "uint16"
+			|| c2 == "int32" || c2 == "uint32"
+			|| c2 == "int64" || c2 == "uint64");
+
+      bool c1_is_char = (c1 == "char");
+      bool c2_is_char = (c2 == "char");
+
+      bool c1_is_double = (c1 == "double");
+      bool c2_is_double = (c2 == "double");
+
+      bool c1_is_single = (c1 == "single");
+      bool c2_is_single = (c2 == "single");
+
+      bool c1_is_logical = (c1 == "logical");
+      bool c2_is_logical = (c2 == "logical");
+
+      bool c1_is_built_in_type
+	= (c1_is_int || c1_is_char || c1_is_double || c1_is_single
+	   || c1_is_logical);
+
+      bool c2_is_built_in_type
+	= (c2_is_int || c2_is_char ||  c2_is_double || c2_is_single
+	   || c2_is_logical);
+
+      // Order is important here...
+
+      if (c1_is_char && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_char && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_int && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_int && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_single && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_single && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_double && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_double && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_logical && c2_is_logical)
+	retval = c1;
+    }
+
+  return retval;    
+}
+
+bool
+tm_row_const::tm_row_const_rep::do_init_element (tree_expression *elt,
+						 const octave_value& val,
+						 bool& first_elem)
+{
+  octave_idx_type this_elt_nr = val.rows ();
+  octave_idx_type this_elt_nc = val.columns ();
+
+  std::string this_elt_class_nm = val.class_name ();
+
+  dim_vector this_elt_dv = val.dims ();
+
+  class_nm = get_concat_class (class_nm, this_elt_class_nm);
+
+
+  if (! this_elt_dv.all_zero ())
+    {
+      all_mt = false;
+
+      if (first_elem)
+	{
+	  first_elem = false;
+
+	  dv.resize (this_elt_dv.length ());
+	  for (int i = 2; i < dv.length (); i++)
+	    dv.elem (i) = this_elt_dv.elem (i);
+
+	  dv.elem (0) = this_elt_nr;
+
+	  dv.elem (1) = 0;
+	}
+      else
+	{
+	  int len = (this_elt_dv.length () < dv.length ()
+		     ? this_elt_dv.length () : dv.length ());
+
+	  if (this_elt_nr != dv (0))
+	    {
+	      eval_error ("number of rows must match",
+			  elt->line (), elt->column (), this_elt_nr, dv (0));
+	      return false;
+	    }
+	  for (int i = 2; i < len; i++)
+	    {
+	      if (this_elt_dv (i) != dv (i))
+		{
+		  eval_error ("dimensions mismatch", elt->line (), elt->column (), this_elt_dv (i), dv (i));
+		  return false;
+		}
+	    }
+
+	  if (this_elt_dv.length () > len)
+	    for (int i = len; i < this_elt_dv.length (); i++)
+	      if (this_elt_dv (i) != 1)
+		{
+		  eval_error ("dimensions mismatch", elt->line (), elt->column (), this_elt_dv (i), 1);
+		  return false;
+		}
+
+	  if (dv.length () > len)
+	    for (int i = len; i < dv.length (); i++)
+	      if (dv (i) != 1)
+		{
+		  eval_error ("dimensions mismatch", elt->line (), elt->column (), 1, dv (i));
+		  return false;
+		}
+	}
+      dv.elem (1) = dv.elem (1) + this_elt_nc;
+
+    }
+  else
+    eval_warning ("empty matrix found in matrix list",
+		  elt->line (), elt->column ());
+
+  append (val);
+
+  if (all_str && ! val.is_string ())
+    all_str = false;
+
+  if (all_sq_str && ! val.is_sq_string ())
+    all_sq_str = false;
+
+  if (all_dq_str && ! val.is_dq_string ())
+    all_dq_str = false;
+
+  if (! some_str && val.is_string ())
+    some_str = true;
+
+  if (all_real && ! val.is_real_type ())
+    all_real = false;
+
+  if (all_cmplx && ! (val.is_complex_type () || val.is_real_type ()))
+    all_cmplx = false;
+
+  if (!any_sparse && val.is_sparse_type ())
+    any_sparse = true;
+
+  if (!any_class && val.is_object ())
+    any_class = true;
+
+  return true;
+}
+
+void
+tm_row_const::tm_row_const_rep::init (const tree_argument_list& row)
+{
+  all_str = true;
+  all_sq_str = true;
+  all_dq_str = true;
+  all_real = true;
+  all_cmplx = true;
+  any_sparse = false;
+  any_class = false;
+
+  bool first_elem = true;
+
+  for (tree_argument_list::const_iterator p = row.begin ();
+       p != row.end ();
+       p++)
+    {
+      OCTAVE_QUIT;
+
+      tree_expression *elt = *p;
+
+      octave_value tmp = elt->rvalue1 ();
+
+      if (error_state || tmp.is_undefined ())
+	break;
+      else
+	{
+	  if (tmp.is_cs_list ())
+	    {
+	      octave_value_list tlst = tmp.list_value ();
+
+	      for (octave_idx_type i = 0; i < tlst.length (); i++)
+		{
+		  OCTAVE_QUIT;
+
+		  if (! do_init_element (elt, tlst(i), first_elem))
+		    goto done;
+		}
+	    }
+	  else
+	    {
+	      if (! do_init_element (elt, tmp, first_elem))
+		goto done;
+	    }
+	}
+    }
+
+ done:
+
+  ok = ! error_state;
+}
+
+void
+tm_row_const::tm_row_const_rep::eval_error (const char *msg, int l,
+					    int c, int x, int y) const
+{
+  if (l == -1 && c == -1)
+    {
+      if (x == -1 || y == -1)
+	::error ("%s", msg);
+      else
+	::error ("%s (%d != %d)", msg, x, y);
+    }
+  else
+    {
+      if (x == -1 || y == -1)
+	::error ("%s near line %d, column %d", msg, l, c);
+      else
+	::error ("%s (%d != %d) near line %d, column %d", msg, x, y, l, c);
+    }
+}
+
+void
+tm_row_const::tm_row_const_rep::eval_warning (const char *msg, int l,
+					      int c) const
+{
+  if (l == -1 && c == -1)
+    warning_with_id ("Octave:empty-list-elements", "%s", msg);
+  else
+    warning_with_id ("Octave:empty-list-elements",
+		     "%s near line %d, column %d", msg, l, c);
+}
+
+class
+tm_const : public octave_base_list<tm_row_const>
+{
+public:
+
+  tm_const (const tree_matrix& tm)
+    : dv (0, 0), all_str (false), all_sq_str (false), all_dq_str (false),
+      some_str (false), all_real (false), all_cmplx (false),
+      all_mt (true), any_sparse (false), any_class (false),
+      class_nm (), ok (false)
+  { init (tm); }
+
+  ~tm_const (void) { }
+
+  octave_idx_type rows (void) const { return dv.elem (0); }
+  octave_idx_type cols (void) const { return dv.elem (1); }
+
+  dim_vector dims (void) const { return dv; }
+
+  bool all_strings_p (void) const { return all_str; }
+  bool all_sq_strings_p (void) const { return all_sq_str; }
+  bool all_dq_strings_p (void) const { return all_dq_str; }
+  bool some_strings_p (void) const { return some_str; }
+  bool all_real_p (void) const { return all_real; }
+  bool all_complex_p (void) const { return all_cmplx; }
+  bool all_empty_p (void) const { return all_mt; }
+  bool any_sparse_p (void) const { return any_sparse; }
+  bool any_class_p (void) const { return any_class; }
+
+  std::string class_name (void) const { return class_nm; }
+
+  operator bool () const { return ok; }
+
+private:
+
+  dim_vector dv;
+
+  bool all_str;
+  bool all_sq_str;
+  bool all_dq_str;
+  bool some_str;
+  bool all_real;
+  bool all_cmplx;
+  bool all_mt;
+  bool any_sparse;
+  bool any_class;
+
+  std::string class_nm;
+
+  bool ok;
+
+  tm_const (void);
+
+  tm_const (const tm_const&);
+
+  tm_const& operator = (const tm_const&);
+
+  void init (const tree_matrix& tm);
+};
+
+void
+tm_const::init (const tree_matrix& tm)
+{
+  all_str = true;
+  all_sq_str = true;
+  all_dq_str = true;
+  all_real = true;
+  all_cmplx = true;
+  any_sparse = false;
+  any_class = false;
+
+  bool first_elem = true;
+
+  // Just eval and figure out if what we have is complex or all
+  // strings.  We can't check columns until we know that this is a
+  // numeric matrix -- collections of strings can have elements of
+  // different lengths.
+
+  for (tree_matrix::const_iterator p = tm.begin (); p != tm.end (); p++)
+    {
+      OCTAVE_QUIT;
+
+      tree_argument_list *elt = *p;
+
+      tm_row_const tmp (*elt);
+
+      if (tmp && ! tmp.empty ())
+	{
+	  if (all_str && ! tmp.all_strings_p ())
+	    all_str = false;
+
+	  if (all_sq_str && ! tmp.all_sq_strings_p ())
+	    all_sq_str = false;
+
+	  if (all_dq_str && ! tmp.all_dq_strings_p ())
+	    all_dq_str = false;
+
+	  if (! some_str && tmp.some_strings_p ())
+	    some_str = true;
+
+	  if (all_real && ! tmp.all_real_p ())
+	    all_real = false;
+
+	  if (all_cmplx && ! tmp.all_complex_p ())
+	    all_cmplx = false;
+
+	  if (all_mt && ! tmp.all_empty_p ())
+	    all_mt = false;
+
+	  if (!any_sparse && tmp.any_sparse_p ())
+	    any_sparse = true;
+
+	  if (!any_class && tmp.any_class_p ())
+	    any_class = true;
+
+	  append (tmp);
+	}
+      else
+	break;
+    }
+
+  if (! error_state)
+    {
+      for (iterator p = begin (); p != end (); p++)
+	{
+	  OCTAVE_QUIT;
+
+	  tm_row_const elt = *p;
+
+	  octave_idx_type this_elt_nr = elt.rows ();
+	  octave_idx_type this_elt_nc = elt.cols ();
+
+	  std::string this_elt_class_nm = elt.class_name ();
+
+	  dim_vector this_elt_dv = elt.dims ();
+
+	  if (!this_elt_dv.all_zero ())
+	    {
+	      all_mt = false;
+
+	      if (first_elem)
+		{
+		  first_elem = false;
+
+		  class_nm = this_elt_class_nm;
+
+		  dv.resize (this_elt_dv.length ());
+		  for (int i = 2; i < dv.length (); i++)
+		    dv.elem (i) = this_elt_dv.elem (i);
+
+		  dv.elem (0) = 0;
+
+		  dv.elem (1) = this_elt_nc;
+		}
+	      else if (all_str)
+		{
+		  class_nm = get_concat_class (class_nm, this_elt_class_nm);
+
+		  if (this_elt_nc > cols ())
+		    dv.elem (1) = this_elt_nc;
+		}
+	      else
+		{
+		  class_nm = get_concat_class (class_nm, this_elt_class_nm);
+
+		  bool get_out = false;
+		  int len = (this_elt_dv.length () < dv.length ()
+			     ? this_elt_dv.length () : dv.length ());
+
+		  for (int i = 1; i < len; i++)
+		    {
+		      if (i == 1 && this_elt_nc != dv (1))
+			{
+			  ::error ("number of columns must match (%d != %d)",
+				   this_elt_nc, dv (1));
+			  get_out = true;
+			  break;
+			}
+		      else if (this_elt_dv (i) != dv (i))
+			{
+			  ::error ("dimensions mismatch (dim = %i, %d != %d)", i+1, this_elt_dv (i), dv (i));
+			  get_out = true;
+			  break;
+			}
+		    }
+
+		  if (this_elt_dv.length () > len)
+		    for (int i = len; i < this_elt_dv.length (); i++)
+		      if (this_elt_dv (i) != 1)
+			{
+			  ::error ("dimensions mismatch (dim = %i, %d != %d)", i+1, this_elt_dv (i), 1);
+			  get_out = true;
+			  break;
+			}
+
+		  if (dv.length () > len)
+		    for (int i = len; i < dv.length (); i++)
+		      if (dv (i) != 1)
+			{
+			  ::error ("dimensions mismatch (dim = %i, %d != %d)", i+1, 1, dv(i));
+			  get_out = true;
+			  break;
+			}
+
+		  if (get_out)
+		    break;
+		}
+	      dv.elem (0) = dv.elem (0) + this_elt_nr;
+	    }
+	  else
+	    warning_with_id ("Octave:empty-list-elements",
+			     "empty matrix found in matrix list");
+	}
+    }
+
+  ok = ! error_state;
+}
+
+tree_matrix::~tree_matrix (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+bool
+tree_matrix::has_magic_end (void) const
+{
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      OCTAVE_QUIT;
+
+      tree_argument_list *elt = *p;
+
+      if (elt && elt->has_magic_end ())
+	return true;
+    }
+
+  return false;
+}
+
+bool
+tree_matrix::all_elements_are_constant (void) const
+{
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      OCTAVE_QUIT;
+
+      tree_argument_list *elt = *p;
+
+      if (! elt->all_elements_are_constant ())
+	return false;
+    }
+
+  return true;
+}
+
+octave_value_list
+tree_matrix::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("invalid number of output arguments for matrix list");
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+void
+maybe_warn_string_concat (bool all_dq_strings_p, bool all_sq_strings_p)
+{
+  if (! (all_dq_strings_p || all_sq_strings_p))
+    warning_with_id ("Octave:string-concat",
+		     "concatenation of different character string types may have unintended consequences");
+}
+
+#define SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
+  do \
+    { \
+      int dv_len = dv.length (); \
+      Array<octave_idx_type> ra_idx (dv_len > 1 ? dv_len : 2, 0); \
+ \
+      for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) \
+	{ \
+          OCTAVE_QUIT; \
+ \
+	  tm_row_const row = *p; \
+ \
+	  for (tm_row_const::iterator q = row.begin (); \
+	       q != row.end (); \
+	       q++) \
+	    { \
+	      OCTAVE_QUIT; \
+ \
+	      TYPE ra = q->EXTRACTOR (); \
+ \
+	      if (! error_state) \
+		{ \
+		  result.insert (ra, ra_idx); \
+ \
+		  if (! error_state) \
+		    ra_idx(1) += ra.columns (); \
+		  else \
+		    goto done; \
+		} \
+	      else \
+		goto done; \
+	    } \
+ \
+	  ra_idx(0) += row.rows (); \
+	  ra_idx(1) = 0; \
+	} \
+    } \
+ while (0)
+
+#define DO_SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
+  do \
+    { \
+      TYPE result (dv); \
+ \
+      SINGLE_TYPE_CONCAT (TYPE, EXTRACTOR); \
+ \
+      retval = result; \
+    } \
+  while (0)
+
+#define DO_SINGLE_TYPE_CONCAT_NO_MUTATE(TYPE, EXTRACTOR, OV_TYPE) \
+  do \
+    { \
+      TYPE result (dv); \
+ \
+      SINGLE_TYPE_CONCAT (TYPE, EXTRACTOR); \
+ \
+      retval = octave_value (new OV_TYPE (result)); \
+    } \
+  while (0)
+
+octave_value
+tree_matrix::rvalue1 (int)
+{
+  octave_value retval = Matrix ();
+
+  bool all_strings_p = false;
+  bool all_sq_strings_p = false;
+  bool all_dq_strings_p = false;
+  bool all_empty_p = false;
+  bool all_real_p = false;
+  bool all_complex_p = false;
+  bool any_sparse_p = false;
+  bool any_class_p = false;
+  bool frc_str_conv = false;
+
+  tm_const tmp (*this);
+
+  if (tmp && ! tmp.empty ())
+    {
+      dim_vector dv = tmp.dims ();
+      all_strings_p = tmp.all_strings_p ();
+      all_sq_strings_p = tmp.all_sq_strings_p ();
+      all_dq_strings_p = tmp.all_dq_strings_p ();
+      all_empty_p = tmp.all_empty_p ();
+      all_real_p = tmp.all_real_p ();
+      all_complex_p = tmp.all_complex_p ();
+      any_sparse_p = tmp.any_sparse_p ();
+      any_class_p = tmp.any_class_p ();
+      frc_str_conv = tmp.some_strings_p ();
+
+      // Try to speed up the common cases.
+
+      std::string result_type = tmp.class_name ();
+
+      if (any_class_p)
+	{
+	  octave_value_list tmp3 (tmp.length (), octave_value ());
+
+	  int j = 0;
+	  for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
+	    {
+	      OCTAVE_QUIT;
+
+	      tm_row_const row = *p;
+
+	      if (row.length () == 1)
+		tmp3 (j++) = *(row.begin ());
+	      else
+		{
+		  octave_value_list tmp1 (row.length (), octave_value ());
+
+		  int i = 0;
+		  for (tm_row_const::iterator q = row.begin (); 
+		       q != row.end (); q++)
+		    tmp1 (i++) = *q;
+
+		  octave_value_list tmp2;
+		  octave_value fcn = 
+		    symbol_table::find_function ("horzcat", tmp1);
+
+		  if (fcn.is_defined ())
+		    {
+		      tmp2 = fcn.do_multi_index_op (1, tmp1);
+		      
+		      if (error_state)
+			goto done;
+
+		      tmp3 (j++) = tmp2 (0);
+		    }
+		  else
+		    {
+		      ::error ("cat not find overloaded horzcat function");
+		      goto done;
+		    }
+		}
+	    }
+
+	  if (tmp.length () == 1)
+	    retval = tmp3 (0);
+	  else
+	    {
+	      octave_value_list tmp2;
+	      octave_value fcn = symbol_table::find_function ("vertcat", tmp3);
+
+	      if (fcn.is_defined ())
+		{
+		  tmp2 = fcn.do_multi_index_op (1, tmp3);
+		      
+		  if (! error_state)
+		    retval = tmp2 (0);
+		}
+	      else
+		::error ("cat not find overloaded vertcat function");
+	    }
+	}
+      else if (result_type == "double")
+	{
+	  if (any_sparse_p)
+	    {	    
+	      if (all_real_p)
+		DO_SINGLE_TYPE_CONCAT (SparseMatrix, sparse_matrix_value);
+	      else
+		DO_SINGLE_TYPE_CONCAT_NO_MUTATE (SparseComplexMatrix,
+						 sparse_complex_matrix_value,
+						 octave_sparse_complex_matrix);
+	    }
+	  else
+	    {
+	      if (all_real_p)
+		DO_SINGLE_TYPE_CONCAT (NDArray, array_value);
+	      else
+		DO_SINGLE_TYPE_CONCAT_NO_MUTATE (ComplexNDArray,
+						 complex_array_value,
+						 octave_complex_matrix);
+	    }
+	}
+      else if (result_type == "single")
+	{
+	  if (all_real_p)
+	    DO_SINGLE_TYPE_CONCAT (FloatNDArray, float_array_value);
+	  else
+	    DO_SINGLE_TYPE_CONCAT_NO_MUTATE (FloatComplexNDArray,
+					     float_complex_array_value,
+					     octave_float_complex_matrix);
+	}
+      else if (result_type == "char")
+	{
+	  char type = all_dq_strings_p ? '"' : '\'';
+
+	  maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p);
+
+	  charNDArray result (dv, Vstring_fill_char);
+
+	  SINGLE_TYPE_CONCAT (charNDArray, char_array_value);
+
+	  retval = octave_value (result, true, type);
+	}
+      else if (result_type == "logical")
+	{
+	  if (any_sparse_p)
+	    DO_SINGLE_TYPE_CONCAT (SparseBoolMatrix, sparse_bool_matrix_value);
+	  else
+	    DO_SINGLE_TYPE_CONCAT (boolNDArray, bool_array_value);
+	}
+      else if (result_type == "int8")
+	DO_SINGLE_TYPE_CONCAT (int8NDArray, int8_array_value);
+      else if (result_type == "int16")
+	DO_SINGLE_TYPE_CONCAT (int16NDArray, int16_array_value);
+      else if (result_type == "int32")
+	DO_SINGLE_TYPE_CONCAT (int32NDArray, int32_array_value);
+      else if (result_type == "int64")
+	DO_SINGLE_TYPE_CONCAT (int64NDArray, int64_array_value);
+      else if (result_type == "uint8")
+	DO_SINGLE_TYPE_CONCAT (uint8NDArray, uint8_array_value);
+      else if (result_type == "uint16")
+	DO_SINGLE_TYPE_CONCAT (uint16NDArray, uint16_array_value);
+      else if (result_type == "uint32")
+	DO_SINGLE_TYPE_CONCAT (uint32NDArray, uint32_array_value);
+      else if (result_type == "uint64")
+	DO_SINGLE_TYPE_CONCAT (uint64NDArray, uint64_array_value);
+      else
+	{
+	  // The line below might seem crazy, since we take a copy of
+	  // the first argument, resize it to be empty and then resize
+	  // it to be full. This is done since it means that there is
+	  // no recopying of data, as would happen if we used a single
+	  // resize.  It should be noted that resize operation is also
+	  // significantly slower than the do_cat_op function, so it
+	  // makes sense to have an empty matrix and copy all data.
+	  //
+	  // We might also start with a empty octave_value using
+	  //
+	  //    ctmp = octave_value_typeinfo::lookup_type
+	  //          (tmp.begin() -> begin() -> type_name());
+	  //
+	  // and then directly resize. However, for some types there
+	  // might be some additional setup needed, and so this should
+	  // be avoided.
+
+	  octave_value ctmp;
+
+	  // Find the first non-empty object
+
+	  if (any_sparse_p)
+	    {
+	      // Start with sparse matrix to avoid issues memory issues
+	      // with things like [ones(1,4),sprandn(1e8,4,1e-4)]
+	      if (all_real_p)
+		ctmp = octave_sparse_matrix ().resize (dv); 
+	      else
+		ctmp = octave_sparse_complex_matrix ().resize (dv); 
+	    }
+	  else
+	    {
+	      for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
+		{
+		  OCTAVE_QUIT;
+
+		  tm_row_const row = *p;
+
+		  for (tm_row_const::iterator q = row.begin (); 
+		       q != row.end (); q++)
+		    {
+		      OCTAVE_QUIT;
+
+		      ctmp = *q;
+
+		      if (! ctmp.all_zero_dims ())
+			goto found_non_empty;
+		    }
+		}
+
+	      ctmp = (*(tmp.begin() -> begin()));
+
+	    found_non_empty:
+
+	      if (! all_empty_p)
+		ctmp = ctmp.resize (dim_vector (0,0)).resize (dv);
+	    }
+
+	  if (! error_state)
+	    {
+	      // Now, extract the values from the individual elements and
+	      // insert them in the result matrix.
+
+	      int dv_len = dv.length ();
+	      Array<octave_idx_type> ra_idx (dv_len > 1 ? dv_len : 2, 0);
+
+	      for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
+		{
+		  OCTAVE_QUIT;
+
+		  tm_row_const row = *p;
+
+		  for (tm_row_const::iterator q = row.begin ();
+		       q != row.end ();
+		       q++)
+		    {
+		      OCTAVE_QUIT;
+
+		      octave_value elt = *q;
+
+		      ctmp = do_cat_op (ctmp, elt, ra_idx);
+
+		      if (error_state)
+			goto done;
+
+		      ra_idx (1) += elt.columns ();
+		    }
+
+		  ra_idx (0) += row.rows ();
+		  ra_idx (1) = 0;
+		}
+
+	      retval = ctmp;
+
+	      if (frc_str_conv && ! retval.is_string ())
+		retval = retval.convert_to_str ();
+	    }
+	}
+    }
+
+done:
+  return retval;
+}
+
+tree_expression *
+tree_matrix::dup (symbol_table::scope_id scope,
+		  symbol_table::context_id context) const
+{
+  tree_matrix *new_matrix = new tree_matrix (0, line (), column ());
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_argument_list *elt = *p;
+
+      new_matrix->append (elt ? elt->dup (scope, context) : 0);
+    }
+
+  new_matrix->copy_base (*this);
+
+  return new_matrix;
+}
+
+void
+tree_matrix::accept (tree_walker& tw)
+{
+  tw.visit_matrix (*this);
+}
+
+DEFUN (string_fill_char, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} string_fill_char ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} string_fill_char (@var{new_val})\n\
+Query or set the internal variable used to pad all rows of a character\n\
+matrix to the same length.  It must be a single character.  The default\n\
+value is @code{\" \"} (a single space).  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+string_fill_char (\"X\");\n\
+[ \"these\"; \"are\"; \"strings\" ]\n\
+     @result{} \"theseXX\"\n\
+        \"areXXXX\"\n\
+        \"strings\"\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (string_fill_char);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-mat.h b/src/pt-mat.h
new file mode 100644
index 0000000..79c0ffa
--- /dev/null
+++ b/src/pt-mat.h
@@ -0,0 +1,102 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_mat_h)
+#define octave_tree_mat_h 1
+
+#include <iosfwd>
+
+class octave_value;
+class octave_value_list;
+class tree_argument_list;
+
+class tree_walker;
+
+#include "base-list.h"
+#include "pt-exp.h"
+#include "symtab.h"
+
+// General matrices.  This allows us to construct matrices from
+// other matrices, variables, and functions.
+
+class
+tree_matrix : public tree_expression,
+	      public octave_base_list<tree_argument_list *>
+{
+public:
+
+  tree_matrix (tree_argument_list *row = 0, int l = -1, int c = -1)
+    : tree_expression (l, c)
+  {
+    if (row)
+      append (row);
+  }
+
+  ~tree_matrix (void);
+
+  bool has_magic_end (void) const;
+
+  bool all_elements_are_constant (void) const;
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_matrix (const tree_matrix&);
+
+  tree_matrix& operator = (const tree_matrix&);
+};
+
+// The character to fill with when creating string arrays.
+extern char Vstring_fill_char;
+
+extern std::string 
+get_concat_class (const std::string& c1, const std::string& c2);
+
+extern void
+maybe_warn_string_concat (bool all_dq_strings_p, bool all_sq_strings_p);
+
+extern std::string 
+get_concat_class (const std::string& c1, const std::string& c2);
+
+extern void
+maybe_warn_string_concat (bool all_dq_strings_p, bool all_sq_strings_p);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-misc.cc b/src/pt-misc.cc
new file mode 100644
index 0000000..6bb0938
--- /dev/null
+++ b/src/pt-misc.cc
@@ -0,0 +1,312 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Cell.h"
+
+#include "defun.h"
+#include "error.h"
+#include "ov.h"
+#include "oct-lvalue.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-misc.h"
+#include "pt-walk.h"
+#include "utils.h"
+
+// Parameter lists.
+
+tree_parameter_list::~tree_parameter_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+void
+tree_parameter_list::mark_as_formal_parameters (void)
+{
+  for (iterator p = begin (); p != end (); p++)
+    {
+      tree_decl_elt *elt = *p;
+      elt->mark_as_formal_parameter ();
+    }
+}
+
+bool
+tree_parameter_list::validate (in_or_out type)
+{
+  bool retval = true;
+
+  std::set<std::string> dict;
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      tree_decl_elt *elt = *p;
+
+      tree_identifier *id = elt->ident ();
+
+      if (id)
+	{
+	  std::string name = id->name ();
+
+	  if (dict.find (name) != dict.end ())
+	    {
+	      retval = false;
+	      error ("`%s' appears more than once in parameter list",
+		     name.c_str ());
+	      break;
+	    }
+	  else
+	    dict.insert (name);
+	}
+    }
+
+  if (! error_state)
+    {
+      std::string va_type = (type == in ? "varargin" : "varargout");
+
+      size_t len = length ();
+
+      if (len > 0)
+	{
+	  tree_decl_elt *elt = back ();
+
+	  tree_identifier *id = elt->ident ();
+
+	  if (id && id->name () == va_type)
+	    {
+	      if (len == 1)
+		mark_varargs_only ();
+	      else
+		mark_varargs ();
+
+	      iterator p = end ();
+	      --p;
+	      delete *p;
+	      erase (p);
+	    }
+	}
+    }
+
+  return retval;
+}
+
+void
+tree_parameter_list::initialize_undefined_elements (const std::string& warnfor,
+						    int nargout,
+						    const octave_value& val)
+{
+  bool warned = false;
+
+  int count = 0;
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      if (++count > nargout)
+	break;
+
+      tree_decl_elt *elt = *p;
+
+      if (! elt->is_variable ())
+	{
+	  if (! warned)
+	    {
+	      warned = true;
+
+	      warning_with_id
+		("Octave:undefined-return-values",
+		 "%s: some elements in list of return values are undefined",
+		 warnfor.c_str ());
+	    }
+
+	  octave_lvalue tmp = elt->lvalue ();
+
+	  tmp.assign (octave_value::op_asn_eq, val);
+	}
+    }
+}
+
+void
+tree_parameter_list::define_from_arg_vector (const octave_value_list& args)
+{
+  int nargin = args.length ();
+
+  int expected_nargin = length ();
+
+  iterator p = begin ();
+
+  for (int i = 0; i < expected_nargin; i++)
+    {
+      tree_decl_elt *elt = *p++;
+
+      octave_lvalue ref = elt->lvalue ();
+
+      if (i < nargin)
+	{
+	  if (args(i).is_defined () && args(i).is_magic_colon ())
+	    {
+	      if (! elt->eval ())
+		{
+		  ::error ("no default value for argument %d\n", i+1);
+		  return;
+		}
+	    }
+	  else
+	    ref.define (args(i));
+	}
+      else
+	elt->eval ();
+    }
+}
+
+void
+tree_parameter_list::undefine (void)
+{
+  int len = length ();
+
+  iterator p = begin ();
+
+  for (int i = 0; i < len; i++)
+    {
+      tree_decl_elt *elt = *p++;
+
+      octave_lvalue ref = elt->lvalue ();
+
+      ref.assign (octave_value::op_asn_eq, octave_value ());
+    }
+}
+
+octave_value_list
+tree_parameter_list::convert_to_const_vector (const Cell& varargout)
+{
+  octave_idx_type vlen = varargout.numel ();
+
+  int nout = length () + vlen;
+
+  octave_value_list retval (nout, octave_value ());
+
+  int i = 0;
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      tree_decl_elt *elt = *p;
+
+      retval(i++) = elt->is_defined () ? elt->rvalue1 () : octave_value ();
+    }
+
+  for (octave_idx_type j = 0; j < vlen; j++)
+    retval(i++) = varargout(j);
+
+  return retval;
+}
+
+bool
+tree_parameter_list::is_defined (void)
+{
+  bool status = true;
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      tree_decl_elt *elt = *p;
+
+      if (! elt->is_variable ())
+	{
+	  status = false;
+	  break;
+	}
+    }
+
+  return status;
+}
+
+tree_parameter_list *
+tree_parameter_list::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context) const
+{
+  tree_parameter_list *new_list = new tree_parameter_list ();
+
+  if (takes_varargs ())
+    new_list->mark_varargs ();
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_decl_elt *elt = *p;
+
+      new_list->append (elt->dup (scope, context));
+    }
+
+  return new_list;
+}
+
+void
+tree_parameter_list::accept (tree_walker& tw)
+{
+  tw.visit_parameter_list (*this);
+}
+
+// Return lists.
+
+tree_return_list::~tree_return_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+tree_return_list *
+tree_return_list::dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context) const
+{
+  tree_return_list *new_list = new tree_return_list ();
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_index_expression *elt = *p;
+
+      new_list->append (elt->dup (scope, context));
+    }
+
+  return new_list;
+}
+
+void
+tree_return_list::accept (tree_walker& tw)
+{
+  tw.visit_return_list (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-misc.h b/src/pt-misc.h
new file mode 100644
index 0000000..41190e3
--- /dev/null
+++ b/src/pt-misc.h
@@ -0,0 +1,156 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_misc_h)
+#define octave_tree_misc_h 1
+
+class Cell;
+
+class octave_value;
+class octave_value_list;
+
+class tree_identifier;
+class tree_index_expression;
+class tree_va_return_list;
+
+class tree_walker;
+
+#include "base-list.h"
+#include "pt-decl.h"
+#include "symtab.h"
+
+// Parameter lists.  Used to hold the list of input and output
+// parameters in a function definition.  Elements are identifiers
+// only.
+
+class
+tree_parameter_list : public octave_base_list<tree_decl_elt *>
+{
+public:
+
+  enum in_or_out
+    {
+      in = 1,
+      out = 2
+    };
+
+  tree_parameter_list (void)
+    : marked_for_varargs (0) { }
+
+  tree_parameter_list (tree_decl_elt *t)
+    : marked_for_varargs (0) { append (t); }
+
+  ~tree_parameter_list (void);
+
+  void mark_as_formal_parameters (void);
+
+  bool validate (in_or_out type);
+
+  bool takes_varargs (void) const { return marked_for_varargs != 0; }
+
+  bool varargs_only (void) { return (marked_for_varargs < 0); }
+
+  void initialize_undefined_elements (const std::string& warnfor,
+				      int nargout, const octave_value& val);
+
+  void define_from_arg_vector (const octave_value_list& args);
+
+  void undefine (void);
+
+  bool is_defined (void);
+
+  octave_value_list convert_to_const_vector (const Cell& varargout);
+
+  tree_parameter_list *dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  int marked_for_varargs;
+
+  void mark_varargs (void) { marked_for_varargs = 1; }
+
+  void mark_varargs_only (void) { marked_for_varargs = -1; }
+
+  // No copying!
+
+  tree_parameter_list (const tree_parameter_list&);
+
+  tree_parameter_list& operator = (const tree_parameter_list&);
+};
+
+// Return lists.  Used to hold the right hand sides of multiple
+// assignment expressions.
+
+class
+tree_return_list : public octave_base_list<tree_index_expression *>
+{
+public:
+
+  tree_return_list (void) { }
+
+  tree_return_list (tree_index_expression *t) { append (t); }
+
+  ~tree_return_list (void);
+
+  tree_return_list *dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_return_list (const tree_return_list&);
+
+  tree_return_list& operator = (const tree_return_list&);
+};
+
+class
+tree_va_return_list : public octave_base_list<octave_value>
+{
+public:
+
+  tree_va_return_list (void) { }
+
+  ~tree_va_return_list (void) { }
+
+private:
+
+  // No copying!
+
+  tree_va_return_list (const tree_va_return_list&);
+
+  tree_va_return_list& operator = (const tree_va_return_list&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-pr-code.cc b/src/pt-pr-code.cc
new file mode 100644
index 0000000..3f6e039
--- /dev/null
+++ b/src/pt-pr-code.cc
@@ -0,0 +1,1294 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <iostream>
+
+#include "comment-list.h"
+#include "error.h"
+#include "ov-usr-fcn.h"
+#include "pr-output.h"
+#include "pt-all.h"
+
+void
+tree_print_code::visit_anon_fcn_handle (tree_anon_fcn_handle& afh)
+{
+  indent ();
+
+  print_parens (afh, "(");
+
+  os << "@(";
+
+  tree_parameter_list *param_list = afh.parameter_list ();
+
+  if (param_list)
+    param_list->accept (*this);
+
+  os << ") ";
+
+  tree_statement_list *body = afh.body ();
+
+  if (body)
+    body->accept (*this);
+
+  print_parens (afh, ")");
+}
+
+void
+tree_print_code::visit_argument_list (tree_argument_list& lst)
+{
+  tree_argument_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_expression *elt = *p++;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p != lst.end ())
+	    os << ", ";
+	}
+    }
+}
+
+void
+tree_print_code::visit_binary_expression (tree_binary_expression& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  tree_expression *op1 = expr.lhs ();
+
+  if (op1)
+    op1->accept (*this);
+
+  os << " " << expr.oper () << " ";
+
+  tree_expression *op2 = expr.rhs ();
+
+  if (op2)
+    op2->accept (*this);
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_break_command (tree_break_command&)
+{
+  indent ();
+
+  os << "break";
+}
+
+void
+tree_print_code::visit_colon_expression (tree_colon_expression& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  tree_expression *op1 = expr.base ();
+
+  if (op1)
+    op1->accept (*this);
+
+  // Stupid syntax.
+
+  tree_expression *op3 = expr.increment ();
+
+  if (op3)
+    {
+      os << ":";
+      op3->accept (*this);
+    }
+
+  tree_expression *op2 = expr.limit ();
+
+  if (op2)
+    {
+      os << ":";
+      op2->accept (*this);
+    }
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_continue_command (tree_continue_command&)
+{
+  indent ();
+
+  os << "continue";
+}
+
+void
+tree_print_code::do_decl_command (tree_decl_command& cmd)
+{
+  indent ();
+
+  os << cmd.name () << " ";
+
+  tree_decl_init_list *init_list = cmd.initializer_list ();
+
+  if (init_list)
+    init_list->accept (*this);
+}
+
+void
+tree_print_code::visit_global_command (tree_global_command& cmd)
+{
+  do_decl_command (cmd);
+}
+
+void
+tree_print_code::visit_static_command (tree_static_command& cmd)
+{
+  do_decl_command (cmd);
+}
+
+void
+tree_print_code::visit_decl_elt (tree_decl_elt& cmd)
+{
+  tree_identifier *id = cmd.ident ();
+
+  if (id)
+    id->accept (*this);
+
+  tree_expression *expr = cmd.expression ();
+
+  if (expr)
+    {
+      os << " = ";
+
+      expr->accept (*this);
+    }
+}
+
+void
+tree_print_code::visit_decl_init_list (tree_decl_init_list& lst)
+{
+  tree_decl_init_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_decl_elt *elt = *p++;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p != lst.end ())
+	    os << ", ";
+	}
+    }
+}
+
+void
+tree_print_code::visit_simple_for_command (tree_simple_for_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "for ";
+
+  tree_expression *lhs = cmd.left_hand_side ();
+
+  if (lhs)
+    lhs->accept (*this);
+
+  os << " = ";
+
+  tree_expression *expr = cmd.control_expr ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "endfor";
+}
+
+void
+tree_print_code::visit_complex_for_command (tree_complex_for_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "for [";
+  nesting.push ('[');
+
+  tree_argument_list *lhs = cmd.left_hand_side ();
+
+  if (lhs)
+    lhs->accept (*this);
+
+  nesting.pop ();
+  os << "] = ";
+
+  tree_expression *expr = cmd.control_expr ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "endfor";
+}
+
+void
+tree_print_code::visit_octave_user_script (octave_user_script& fcn)
+{
+  reset ();
+
+  tree_statement_list *cmd_list = fcn.body ();
+
+  if (cmd_list)
+    cmd_list->accept (*this);
+}
+
+void
+tree_print_code::visit_octave_user_function (octave_user_function& fcn)
+{
+  reset ();
+
+  visit_octave_user_function_header (fcn);
+
+  tree_statement_list *cmd_list = fcn.body ();
+
+  if (cmd_list)
+    {
+      increment_indent_level ();
+
+      cmd_list->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  visit_octave_user_function_trailer (fcn);
+}
+
+void
+tree_print_code::visit_octave_user_function_header (octave_user_function& fcn)
+{
+  octave_comment_list *leading_comment = fcn.leading_comment ();
+
+  if (leading_comment)
+    {
+      print_comment_list (leading_comment);
+      newline ();
+    }
+
+  indent ();
+
+  os << "function ";
+
+  tree_parameter_list *ret_list = fcn.return_list ();
+
+  if (ret_list)
+    {
+      bool takes_var_return = fcn.takes_var_return ();
+
+      int len = ret_list->length ();
+
+      if (len > 1 || takes_var_return)
+	{
+	  os << "[";
+	  nesting.push ('[');
+	}
+
+      ret_list->accept (*this);
+
+      if (takes_var_return)
+	{
+	  if (len > 0)
+	    os << ", ";
+
+	  os << "varargout";
+	}
+
+      if (len > 1 || takes_var_return)
+	{
+	  nesting.pop ();
+	  os << "]";
+	}
+
+      os << " = ";
+    }
+
+  std::string fcn_name = fcn.name ();
+
+  os << (fcn_name.empty () ? std::string ("(empty)") : fcn_name) << " ";
+
+  tree_parameter_list *param_list = fcn.parameter_list ();
+
+  if (param_list)
+    {
+      bool takes_varargs = fcn.takes_varargs ();
+
+      int len = param_list->length ();
+
+      if (len > 0 || takes_varargs)
+	{
+	  os << "(";
+	  nesting.push ('(');
+	}
+
+      param_list->accept (*this);
+
+      if (takes_varargs)
+	{
+	  if (len > 0)
+	    os << ", ";
+
+	  os << "varargin";
+	}
+
+      if (len > 0 || takes_varargs)
+	{
+	  nesting.pop ();
+	  os << ")";
+	  newline ();
+	}
+    }
+  else
+    {
+      os << "()";
+      newline ();
+    }
+}
+
+void
+tree_print_code::visit_octave_user_function_trailer (octave_user_function& fcn)
+{
+  print_indented_comment (fcn.trailing_comment ());
+
+  indent ();
+
+  os << "endfunction";
+
+  newline ();
+}
+
+void
+tree_print_code::visit_function_def (tree_function_def& fdef)
+{
+  indent ();
+
+  octave_value fcn = fdef.function ();
+
+  octave_function *f = fcn.function_value ();
+
+  if (f)
+    f->accept (*this);
+}
+
+void
+tree_print_code::visit_identifier (tree_identifier& id)
+{
+  indent ();
+
+  print_parens (id, "(");
+
+  std::string nm = id.name ();
+  os << (nm.empty () ? std::string ("(empty)") : nm);
+
+  print_parens (id, ")");
+}
+
+void
+tree_print_code::visit_if_clause (tree_if_clause& cmd)
+{
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+
+  tree_statement_list *list = cmd.commands ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      decrement_indent_level ();
+    }
+}
+
+void
+tree_print_code::visit_if_command (tree_if_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "if ";
+
+  tree_if_command_list *list = cmd.cmd_list ();
+
+  if (list)
+    list->accept (*this);
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "endif";
+}
+
+void
+tree_print_code::visit_if_command_list (tree_if_command_list& lst)
+{
+  tree_if_command_list::iterator p = lst.begin ();
+
+  bool first_elt = true;
+
+  while (p != lst.end ())
+    {
+      tree_if_clause *elt = *p++;
+
+      if (elt)
+	{
+	  if (! first_elt)
+	    {
+	      print_indented_comment (elt->leading_comment ());
+
+	      indent ();
+
+	      if (elt->is_else_clause ())
+		os << "else";
+	      else
+		os << "elseif ";
+	    }
+
+	  elt->accept (*this);
+	}
+
+      first_elt = false;
+    }
+}
+
+void
+tree_print_code::visit_index_expression (tree_index_expression& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  bool expr_has_parens = false;
+
+  tree_expression *e = expr.expression ();
+
+  if (e)
+    {
+      e->accept (*this);
+
+      expr_has_parens = e->is_postfix_indexed ();
+    }
+
+  std::list<tree_argument_list *> arg_lists = expr.arg_lists ();
+  std::string type_tags = expr.type_tags ();
+  std::list<string_vector> arg_names = expr.arg_names ();
+
+  int n = type_tags.length ();
+
+  std::list<tree_argument_list *>::iterator p_arg_lists = arg_lists.begin ();
+  std::list<string_vector>::iterator p_arg_names = arg_names.begin ();
+
+  for (int i = 0; i < n; i++)
+    {
+      switch (type_tags[i])
+	{
+	case '(':
+	  {
+	    char nc = nesting.top ();
+	    if ((nc == '[' || nc == '{') && expr.paren_count () == 0)
+	      os << "(";
+	    else
+	      os << " (";
+	    nesting.push ('(');
+
+	    tree_argument_list *l = *p_arg_lists;
+	    if (l)
+	      l->accept (*this);
+
+	    nesting.pop ();
+	    os << ")";
+	  }
+	  break;
+	    
+	case '{':
+	  {
+	    char nc = nesting.top ();
+	    if ((nc == '[' || nc == '{') && expr.paren_count () == 0)
+	      os << "{";
+	    else
+	      os << " {";
+	    // We only care about whitespace inside [] and {} when we
+	    // are defining matrix and cell objects, not when indexing.
+	    nesting.push ('(');
+
+	    tree_argument_list *l = *p_arg_lists;
+	    if (l)
+	      l->accept (*this);
+
+	    nesting.pop ();
+	    os << "}";
+	  }
+	  break;
+	    
+	case '.':
+	  {
+	    string_vector nm = *p_arg_names;
+	    assert (nm.length () == 1);
+	    os << "." << nm(0);
+	  }
+	  break;
+
+	default:
+	  panic_impossible ();
+	}
+
+      p_arg_lists++;
+      p_arg_names++;
+    }
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_matrix (tree_matrix& lst)
+{
+  indent ();
+
+  print_parens (lst, "(");
+
+  os << "[";
+  nesting.push ('[');
+
+  tree_matrix::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_argument_list *elt = *p++;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p != lst.end ())
+	    os << "; ";
+	}
+    }
+
+  nesting.pop ();
+  os << "]";
+
+  print_parens (lst, ")");
+}
+
+void
+tree_print_code::visit_cell (tree_cell& lst)
+{
+  indent ();
+
+  print_parens (lst, "(");
+
+  os << "{";
+  nesting.push ('{');
+
+  tree_cell::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_argument_list *elt = *p++;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p != lst.end ())
+	    os << "; ";
+	}
+    }
+
+  nesting.pop ();
+  os << "}";
+
+  print_parens (lst, ")");
+}
+
+void
+tree_print_code::visit_multi_assignment (tree_multi_assignment& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  tree_argument_list *lhs = expr.left_hand_side ();
+
+  if (lhs)
+    {
+      int len = lhs->length ();
+
+      if (len > 1)
+	{
+	  os << "[";
+	  nesting.push ('[');
+	}
+
+      lhs->accept (*this);
+
+      if (len > 1)
+	{
+	  nesting.pop ();
+	  os << "]";
+	}
+    }
+
+  os << " " << expr.oper () << " ";
+
+  tree_expression *rhs = expr.right_hand_side ();
+
+  if (rhs)
+    rhs->accept (*this);
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_no_op_command (tree_no_op_command& cmd)
+{
+  indent ();
+
+  os << cmd.original_command ();
+}
+
+void
+tree_print_code::visit_constant (tree_constant& val)
+{
+  indent ();
+
+  print_parens (val, "(");
+
+  val.print_raw (os, true, print_original_text);
+
+  print_parens (val, ")");
+}
+
+void
+tree_print_code::visit_fcn_handle (tree_fcn_handle& fh)
+{
+  indent ();
+
+  print_parens (fh, "(");
+
+  fh.print_raw (os, true, print_original_text);
+
+  print_parens (fh, ")");
+}
+
+void
+tree_print_code::visit_parameter_list (tree_parameter_list& lst)
+{
+  tree_parameter_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_decl_elt *elt = *p++;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p != lst.end ())
+	    os << ", ";
+	}
+    }
+}
+
+void
+tree_print_code::visit_postfix_expression (tree_postfix_expression& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  tree_expression *e = expr.operand ();
+
+  if (e)
+    e->accept (*this);
+
+  os << expr.oper ();
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_prefix_expression (tree_prefix_expression& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  os << expr.oper ();
+
+  tree_expression *e = expr.operand ();
+
+  if (e)
+    e->accept (*this);
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_return_command (tree_return_command&)
+{
+  indent ();
+
+  os << "return";
+}
+
+void
+tree_print_code::visit_return_list (tree_return_list& lst)
+{
+  tree_return_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_index_expression *elt = *p++;
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p != lst.end ())
+	    os << ", ";
+	}
+    }
+}
+
+void
+tree_print_code::visit_simple_assignment (tree_simple_assignment& expr)
+{
+  indent ();
+
+  print_parens (expr, "(");
+
+  tree_expression *lhs = expr.left_hand_side ();
+
+  if (lhs)
+    lhs->accept (*this);
+
+  os << " " << expr.oper () << " ";
+
+  tree_expression *rhs = expr.right_hand_side ();
+
+  if (rhs)
+    rhs->accept (*this);
+
+  print_parens (expr, ")");
+}
+
+void
+tree_print_code::visit_statement (tree_statement& stmt)
+{
+  print_comment_list (stmt.comment_text ());
+
+  tree_command *cmd = stmt.command ();
+
+  if (cmd)
+    {
+      cmd->accept (*this);
+
+      if (! stmt.print_result ())
+	{
+	  os << ";";
+	  newline (" ");
+	}
+      else
+	newline ();
+    }
+  else
+    {
+      tree_expression *expr = stmt.expression ();
+
+      if (expr)
+	{
+	  expr->accept (*this);
+
+	  if (! stmt.print_result ())
+	    {
+	      os << ";";
+	      newline (" ");
+	    }
+	  else
+	    newline ();
+	}
+    }
+}
+
+void
+tree_print_code::visit_statement_list (tree_statement_list& lst)
+{
+  for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
+    {
+      tree_statement *elt = *p;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_print_code::visit_switch_case (tree_switch_case& cs)
+{
+  print_comment_list (cs.leading_comment ());
+
+  indent ();
+
+  if (cs.is_default_case ())
+    os << "otherwise";
+  else
+    os << "case ";
+
+  tree_expression *label = cs.case_label ();
+
+  if (label)
+    label->accept (*this);
+
+  newline ();
+
+  tree_statement_list *list = cs.commands ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      newline ();
+
+      decrement_indent_level ();
+    }
+}
+
+void
+tree_print_code::visit_switch_case_list (tree_switch_case_list& lst)
+{
+  tree_switch_case_list::iterator p = lst.begin ();
+
+  while (p != lst.end ())
+    {
+      tree_switch_case *elt = *p++;
+
+      if (elt)
+	elt->accept (*this);
+    }
+}
+
+void
+tree_print_code::visit_switch_command (tree_switch_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "switch ";
+
+  tree_expression *expr = cmd.switch_value ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+
+  tree_switch_case_list *list = cmd.case_list ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.leading_comment ());
+
+  indent ();
+
+  os << "endswitch";
+}
+
+void
+tree_print_code::visit_try_catch_command (tree_try_catch_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "try";
+
+  newline ();
+
+  tree_statement_list *try_code = cmd.body ();
+
+  if (try_code)
+    {
+      increment_indent_level ();
+
+      try_code->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.middle_comment ());
+
+  indent ();
+
+  os << "catch";
+
+  newline ();
+
+  tree_statement_list *catch_code = cmd.cleanup ();
+
+  if (catch_code)
+    {
+      increment_indent_level ();
+
+      catch_code->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "end_try_catch";
+}
+
+void
+tree_print_code::visit_unwind_protect_command
+  (tree_unwind_protect_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "unwind_protect";
+
+  newline ();
+
+  tree_statement_list *unwind_protect_code = cmd.body ();
+
+  if (unwind_protect_code)
+    {
+      increment_indent_level ();
+
+      unwind_protect_code->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.middle_comment ());
+
+  indent ();
+
+  os << "unwind_protect_cleanup";
+
+  newline ();
+
+  tree_statement_list *cleanup_code = cmd.cleanup ();
+
+  if (cleanup_code)
+    {
+      increment_indent_level ();
+
+      cleanup_code->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "end_unwind_protect";
+}
+
+void
+tree_print_code::visit_while_command (tree_while_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "while ";
+
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "endwhile";
+}
+
+void
+tree_print_code::visit_do_until_command (tree_do_until_command& cmd)
+{
+  print_comment_list (cmd.leading_comment ());
+
+  indent ();
+
+  os << "do";
+
+  newline ();
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    {
+      increment_indent_level ();
+
+      list->accept (*this);
+
+      decrement_indent_level ();
+    }
+
+  print_indented_comment (cmd.trailing_comment ());
+
+  indent ();
+
+  os << "until";
+
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+}
+
+// Each print_code() function should call this before printing
+// anything.
+//
+// This doesn't need to be fast, but isn't there a better way?
+
+void
+tree_print_code::indent (void)
+{
+  assert (curr_print_indent_level >= 0);
+
+  if (printing_newlines)
+    {
+      if (beginning_of_line)
+	{
+	  os << prefix;
+
+	  for (int i = 0; i < curr_print_indent_level; i++)
+	    os << " ";
+
+	  beginning_of_line = false;
+	}
+    }
+}
+
+// All print_code() functions should use this to print new lines.
+
+void
+tree_print_code::newline (const char *alt_txt)
+{
+  os << (printing_newlines ? "\n" : alt_txt);
+
+  beginning_of_line = true;
+}
+
+// For ressetting print_code state.
+
+void
+tree_print_code::reset (void)
+{
+  beginning_of_line = true;
+  curr_print_indent_level = 0;
+  while (nesting.top () != 'n')
+    nesting.pop ();
+}
+
+void
+tree_print_code::print_parens (const tree_expression& expr, const char *txt)
+{
+  int n = expr.paren_count ();
+
+  for (int i = 0; i < n; i++)
+    os << txt;
+}
+
+void
+tree_print_code::print_comment_elt (const octave_comment_elt& elt)
+{
+  bool printed_something = false;
+
+  bool prev_char_was_newline = false;
+
+  std::string comment = elt.text ();
+
+  size_t len = comment.length ();
+
+  size_t i = 0;
+
+  while (i < len && comment[i++] == '\n')
+    ; /* Skip leading new lines. */
+  i--;
+
+  while (i < len)
+    {
+      char c = comment[i++];
+
+      if (c == '\n')
+	{
+	  if (prev_char_was_newline)
+	    os << "##";
+
+	  newline ();
+
+	  prev_char_was_newline = true;
+	}
+      else
+	{
+	  if (beginning_of_line)
+	    {
+	      printed_something = true;
+
+	      indent ();
+
+	      os << "##";
+
+	      if (! (isspace (c) || c == '!'))
+		os << " ";
+	    }
+
+	  os << static_cast<char> (c);
+
+	  prev_char_was_newline = false;
+	}
+    }
+
+  if (printed_something && ! beginning_of_line)
+    newline ();
+}
+
+void
+tree_print_code::print_comment_list (octave_comment_list *comment_list)
+{
+  if (comment_list)
+    {
+      octave_comment_list::iterator p = comment_list->begin ();
+
+      while (p != comment_list->end ())
+	{
+	  octave_comment_elt elt = *p++;
+
+	  print_comment_elt (elt);
+
+	  if (p != comment_list->end ())
+	    newline ();
+	}
+    }
+}
+
+void
+tree_print_code::print_indented_comment (octave_comment_list *comment_list)
+{
+  increment_indent_level ();
+
+  print_comment_list (comment_list);
+
+  decrement_indent_level ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-pr-code.h b/src/pt-pr-code.h
new file mode 100644
index 0000000..fd57954
--- /dev/null
+++ b/src/pt-pr-code.h
@@ -0,0 +1,205 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_print_code_h)
+#define octave_tree_print_code_h 1
+
+#include <stack>
+#include <string>
+
+#include "comment-list.h"
+#include "pt-walk.h"
+
+class tree_decl_command;
+class tree_expression;
+
+// How to print the code that the parse trees represent.
+
+class
+tree_print_code : public tree_walker
+{
+public:
+
+  tree_print_code (std::ostream& os_arg,
+		   const std::string& pfx = std::string (),
+		   bool pr_orig_txt = true)
+    : os (os_arg), prefix (pfx), nesting (),
+      print_original_text (pr_orig_txt),
+      curr_print_indent_level (0), beginning_of_line (true),
+      printing_newlines (true)
+  {
+    // For "none".
+    nesting.push ('n');
+  }
+
+  ~tree_print_code (void) { }
+
+  void visit_anon_fcn_handle (tree_anon_fcn_handle&);
+
+  void visit_argument_list (tree_argument_list&);
+
+  void visit_binary_expression (tree_binary_expression&);
+
+  void visit_break_command (tree_break_command&);
+
+  void visit_colon_expression (tree_colon_expression&);
+
+  void visit_continue_command (tree_continue_command&);
+
+  void visit_global_command (tree_global_command&);
+
+  void visit_static_command (tree_static_command&);
+
+  void visit_decl_elt (tree_decl_elt&);
+
+  void visit_decl_init_list (tree_decl_init_list&);
+
+  void visit_simple_for_command (tree_simple_for_command&);
+
+  void visit_complex_for_command (tree_complex_for_command&);
+
+  void visit_octave_user_script (octave_user_script&);
+
+  void visit_octave_user_function (octave_user_function&);
+
+  void visit_octave_user_function_header (octave_user_function&);
+
+  void visit_octave_user_function_trailer (octave_user_function&);
+
+  void visit_function_def (tree_function_def&);
+
+  void visit_identifier (tree_identifier&);
+
+  void visit_if_clause (tree_if_clause&);
+
+  void visit_if_command (tree_if_command&);
+
+  void visit_if_command_list (tree_if_command_list&);
+
+  void visit_index_expression (tree_index_expression&);
+
+  void visit_matrix (tree_matrix&);
+
+  void visit_cell (tree_cell&);
+
+  void visit_multi_assignment (tree_multi_assignment&);
+
+  void visit_no_op_command (tree_no_op_command&);
+
+  void visit_constant (tree_constant&);
+
+  void visit_fcn_handle (tree_fcn_handle&);
+
+  void visit_parameter_list (tree_parameter_list&);
+
+  void visit_postfix_expression (tree_postfix_expression&);
+
+  void visit_prefix_expression (tree_prefix_expression&);
+
+  void visit_return_command (tree_return_command&);
+
+  void visit_return_list (tree_return_list&);
+
+  void visit_simple_assignment (tree_simple_assignment&);
+
+  void visit_statement (tree_statement&);
+
+  void visit_statement_list (tree_statement_list&);
+
+  void visit_switch_case (tree_switch_case&);
+
+  void visit_switch_case_list (tree_switch_case_list&);
+
+  void visit_switch_command (tree_switch_command&);
+
+  void visit_try_catch_command (tree_try_catch_command&);
+
+  void visit_unwind_protect_command (tree_unwind_protect_command&);
+
+  void visit_while_command (tree_while_command&);
+
+  void visit_do_until_command (tree_do_until_command&);
+
+  void suspend_newline (void) { printing_newlines = false; }
+
+  void resume_newline (void) { printing_newlines = true; }
+
+private:
+
+  std::ostream& os;
+
+  std::string prefix;
+
+  std::stack<char> nesting;
+
+  bool print_original_text;
+
+  // Current indentation.
+  int curr_print_indent_level;
+
+  // TRUE means we are at the beginning of a line.
+  bool beginning_of_line;
+
+  // TRUE means we are printing newlines and indenting.
+  bool printing_newlines;
+
+  void do_decl_command (tree_decl_command& cmd);
+
+  void reset_indent_level (void) { curr_print_indent_level = 0; }
+
+  void increment_indent_level (void) { curr_print_indent_level += 2; }
+
+  void decrement_indent_level (void) { curr_print_indent_level -= 2; }
+
+  void newline (const char *alt_txt = ", ");
+
+  void indent (void);
+
+  void reset (void);
+
+  void print_parens (const tree_expression& expr, const char *txt);
+
+  void print_comment_list (octave_comment_list *comment_list);
+
+  void print_comment_elt (const octave_comment_elt& comment_elt);
+
+  void print_indented_comment (octave_comment_list *comment_list);
+
+  // Must create with an output stream!
+
+  tree_print_code (void);
+
+  // No copying!
+
+  tree_print_code (const tree_print_code&);
+
+  tree_print_code& operator = (const tree_print_code&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-select.cc b/src/pt-select.cc
new file mode 100644
index 0000000..1e4d1bc
--- /dev/null
+++ b/src/pt-select.cc
@@ -0,0 +1,278 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "pt-cmd.h"
+#include "pt-exp.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "Cell.h"
+#include "ov-typeinfo.h"
+
+// If clauses.
+
+tree_if_clause::~tree_if_clause (void)
+{
+  delete expr;
+  delete list;
+  delete lead_comm;
+}
+
+tree_if_clause *
+tree_if_clause::dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const
+{
+  return new tree_if_clause (expr ? expr->dup (scope, context) : 0,
+			     list ? list->dup (scope, context) : 0,
+			     lead_comm ? lead_comm->dup () : 0);
+}
+
+void
+tree_if_clause::accept (tree_walker& tw)
+{
+  tw.visit_if_clause (*this);
+}
+
+// List of if commands.
+
+tree_if_command_list *
+tree_if_command_list::dup (symbol_table::scope_id scope,
+			   symbol_table::context_id context) const
+{
+  tree_if_command_list *new_icl = new tree_if_command_list ();
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_if_clause *elt = *p;
+
+      new_icl->append (elt ? elt->dup (scope, context) : 0);
+    }
+
+  return new_icl;
+}
+
+void
+tree_if_command_list::accept (tree_walker& tw)
+{
+  tw.visit_if_command_list (*this);
+}
+
+// If.
+
+tree_if_command::~tree_if_command (void)
+{
+  delete list;
+  delete lead_comm;
+  delete trail_comm;
+}
+
+void
+tree_if_command::set_breakpoint (void)
+{
+  if (list)
+    {
+      tree_if_clause *elt = list->front ();
+
+      if (elt)
+	elt->set_breakpoint ();
+    }
+}
+
+void
+tree_if_command::delete_breakpoint (void)
+{
+  if (list)
+    {
+      tree_if_clause *elt = list->front ();
+
+      if (elt)
+	elt->set_breakpoint ();
+    }
+}
+
+tree_command *
+tree_if_command::dup (symbol_table::scope_id scope,
+		      symbol_table::context_id context) const
+{
+  return new tree_if_command (list ? list->dup (scope, context) : 0,
+			      lead_comm ? lead_comm->dup () : 0,
+			      trail_comm ? trail_comm->dup () : 0,
+			      line (), column ());
+}
+
+void
+tree_if_command::accept (tree_walker& tw)
+{
+  tw.visit_if_command (*this);
+}
+
+// Switch cases.
+
+tree_switch_case::~tree_switch_case (void)
+{
+  delete label;
+  delete list;
+  delete lead_comm;
+}
+
+
+bool
+tree_switch_case::label_matches (const octave_value& val)
+{
+  octave_value label_value = label->rvalue1 ();
+
+  if (! error_state && label_value.is_defined() )
+    {
+      if (label_value.is_cell ())
+	{
+	  Cell cell (label_value.cell_value ());
+
+	  for (octave_idx_type i = 0; i < cell.rows (); i++)
+	    {
+	      for (octave_idx_type j = 0; j < cell.columns (); j++)
+		{
+		  bool match = val.is_equal (cell(i,j));
+
+		  if (error_state)
+		    return false;
+		  else if (match)
+		    return true;
+		}
+	    }
+	}
+      else
+	{
+	  bool match = val.is_equal (label_value);
+
+	  if (error_state)
+	    return false;
+	  else
+	    return match;
+	}
+    }
+
+  return false;
+}
+
+tree_switch_case *
+tree_switch_case::dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context) const
+{
+  return new tree_switch_case (label ? label->dup (scope, context) : 0,
+			       list ? list->dup (scope, context) : 0,
+			       lead_comm ? lead_comm->dup () : 0);
+}
+
+void
+tree_switch_case::accept (tree_walker& tw)
+{
+  tw.visit_switch_case (*this);
+}
+
+// List of switch cases.
+
+tree_switch_case_list *
+tree_switch_case_list::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const
+{
+  tree_switch_case_list *new_scl = new tree_switch_case_list ();
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_switch_case *elt = *p;
+
+      new_scl->append (elt ? elt->dup (scope, context) : 0);
+    }
+  
+  return new_scl;
+}
+
+void
+tree_switch_case_list::accept (tree_walker& tw)
+{
+  tw.visit_switch_case_list (*this);
+}
+
+// Switch.
+
+tree_switch_command::~tree_switch_command (void)
+{
+  delete expr;
+  delete list;
+  delete lead_comm;
+  delete trail_comm;
+}
+
+void
+tree_switch_command::set_breakpoint (void)
+{
+  if (list)
+    {
+      tree_switch_case *elt = list->front ();
+
+      if (elt)
+	elt->set_breakpoint ();
+    }
+}
+
+void
+tree_switch_command::delete_breakpoint (void)
+{
+  if (list)
+    {
+      tree_switch_case *elt = list->front ();
+
+      if (elt)
+	elt->set_breakpoint ();
+    }
+}
+
+tree_command *
+tree_switch_command::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context) const
+{
+  return new tree_switch_command (expr ? expr->dup (scope, context) : 0,
+				  list ? list->dup (scope, context) : 0,
+				  lead_comm ? lead_comm->dup () : 0,
+				  trail_comm ? trail_comm->dup () : 0,
+				  line (), column ());
+}
+
+void
+tree_switch_command::accept (tree_walker& tw)
+{
+  tw.visit_switch_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-select.h b/src/pt-select.h
new file mode 100644
index 0000000..47ee28e
--- /dev/null
+++ b/src/pt-select.h
@@ -0,0 +1,317 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_select_h)
+#define octave_tree_select_h 1
+
+class expression;
+class tree_statement_list;
+
+class tree_walker;
+
+#include "base-list.h"
+#include "comment-list.h"
+#include "pt-cmd.h"
+#include "symtab.h"
+
+// If.
+
+class
+tree_if_clause : public tree
+{
+public:
+
+  tree_if_clause (int l = -1, int c = -1)
+    : tree (l, c), expr (0), list (0), lead_comm (0) { }
+
+  tree_if_clause (tree_statement_list *sl, octave_comment_list *lc = 0,
+		  int l = -1, int c = -1)
+    : tree (l, c), expr (0), list (sl), lead_comm (lc) { }
+
+  tree_if_clause (tree_expression *e, tree_statement_list *sl,
+		  octave_comment_list *lc = 0,
+		  int l = -1, int c = -1)
+    : tree (l, c), expr (e), list (sl), lead_comm (lc) { }
+
+  ~tree_if_clause (void);
+
+  bool is_else_clause (void) { return ! expr; }
+
+  tree_expression *condition (void) { return expr; }
+
+  tree_statement_list *commands (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  tree_if_clause *dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The condition to test.
+  tree_expression *expr;
+
+  // The list of statements to evaluate if expr is true.
+  tree_statement_list *list;
+
+  // Comment preceding ELSE or ELSEIF token.
+  octave_comment_list *lead_comm;
+
+  // No copying!
+
+  tree_if_clause (const tree_if_clause&);
+
+  tree_if_clause& operator = (const tree_if_clause&);
+};
+
+class
+tree_if_command_list : public octave_base_list<tree_if_clause *>
+{
+public:
+
+  tree_if_command_list (void) { }
+
+  tree_if_command_list (tree_if_clause *t) { append (t); }
+
+  ~tree_if_command_list (void)
+    {
+      while (! empty ())
+	{
+	  iterator p = begin ();
+	  delete *p;
+	  erase (p);
+	}
+    }
+
+  tree_if_command_list *dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_if_command_list (const tree_if_command_list&);
+
+  tree_if_command_list& operator = (const tree_if_command_list&);
+};
+
+class
+tree_if_command : public tree_command
+{
+public:
+
+  tree_if_command (int l = -1, int c = -1)
+    : tree_command (l, c), list (0), lead_comm (0), trail_comm (0) { }
+
+  tree_if_command (tree_if_command_list *lst, octave_comment_list *lc,
+		   octave_comment_list *tc, int l = -1, int c = -1)
+    : tree_command (l, c), list (lst), lead_comm (lc), trail_comm (tc) { }
+
+  ~tree_if_command (void);
+
+  void set_breakpoint (void);
+
+  void delete_breakpoint (void);
+
+  tree_if_command_list *cmd_list (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // List of if commands (if, elseif, elseif, ... else, endif)
+  tree_if_command_list *list;
+
+  // Comment preceding IF token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding ENDIF token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_if_command (const tree_if_command&);
+
+  tree_if_command& operator = (const tree_if_command&);
+};
+
+// Switch.
+
+class
+tree_switch_case : public tree
+{
+public:
+
+  tree_switch_case (int l = -1, int c = -1)
+    : tree (l, c), label (0), list (0), lead_comm (0) { }
+
+  tree_switch_case (tree_statement_list *sl, octave_comment_list *lc = 0,
+		    int l = -1, int c = -1)
+    : tree (l, c), label (0), list (sl), lead_comm (lc) { }
+
+  tree_switch_case (tree_expression *e, tree_statement_list *sl,
+		    octave_comment_list *lc = 0,
+		    int l = -1, int c = -1)
+    : tree (l, c), label (e), list (sl), lead_comm (lc) { }
+
+  ~tree_switch_case (void);
+
+  bool is_default_case (void) { return ! label; }
+
+  bool label_matches (const octave_value& val);
+
+  tree_expression *case_label (void) { return label; }
+
+  tree_statement_list *commands (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  tree_switch_case *dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The case label.
+  tree_expression *label;
+
+  // The list of statements to evaluate if the label matches.
+  tree_statement_list *list;
+
+  // Comment preceding CASE or OTHERWISE token.
+  octave_comment_list *lead_comm;
+
+  // No copying!
+
+  tree_switch_case (const tree_switch_case&);
+
+  tree_switch_case& operator = (const tree_switch_case&);
+};
+
+class
+tree_switch_case_list : public octave_base_list<tree_switch_case *>
+{
+public:
+
+  tree_switch_case_list (void) { }
+
+  tree_switch_case_list (tree_switch_case *t) { append (t); }
+
+  ~tree_switch_case_list (void)
+    {
+      while (! empty ())
+	{
+	  iterator p = begin ();
+	  delete *p;
+	  erase (p);
+	}
+    }
+
+  tree_switch_case_list *dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_switch_case_list (const tree_switch_case_list&);
+
+  tree_switch_case_list& operator = (const tree_switch_case_list&);
+};
+
+class
+tree_switch_command : public tree_command
+{
+public:
+
+  tree_switch_command (int l = -1, int c = -1)
+    : tree_command (l, c), expr (0), list (0), lead_comm (0),
+      trail_comm (0) { }
+
+  tree_switch_command (tree_expression *e, tree_switch_case_list *lst,
+		       octave_comment_list *lc, octave_comment_list *tc, 
+		       int l = -1, int c = -1)
+    : tree_command (l, c), expr (e), list (lst), lead_comm (lc),
+      trail_comm (tc) { }
+
+  ~tree_switch_command (void);
+
+  void set_breakpoint (void);
+
+  void delete_breakpoint (void);
+
+  tree_expression *switch_value (void) { return expr; }
+
+  tree_switch_case_list *case_list (void) { return list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Value on which to switch.
+  tree_expression *expr;
+
+  // List of cases (case 1, case 2, ..., default)
+  tree_switch_case_list *list;
+
+  // Comment preceding SWITCH token.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding ENDSWITCH token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_switch_command (const tree_switch_command&);
+
+  tree_switch_command& operator = (const tree_switch_command&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-stmt.cc b/src/pt-stmt.cc
new file mode 100644
index 0000000..2d90682
--- /dev/null
+++ b/src/pt-stmt.cc
@@ -0,0 +1,223 @@
+/*
+
+Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <typeinfo>
+
+#include "quit.h"
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "ov.h"
+#include "oct-lvalue.h"
+#include "input.h"
+#include "pager.h"
+#include "pt-bp.h"
+#include "pt-cmd.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-jump.h"
+#include "pt-pr-code.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// A list of commands to be executed.
+
+tree_statement::~tree_statement (void)
+{
+  delete cmd;
+  delete expr;
+  delete comm;
+}
+
+void
+tree_statement::set_print_flag (bool print_flag)
+{
+  if (expr)
+    expr->set_print_flag (print_flag);
+}
+
+bool
+tree_statement::print_result (void)
+{
+  return expr && expr->print_result ();
+}
+
+void
+tree_statement::set_breakpoint (void)
+{
+  if (cmd)
+    cmd->set_breakpoint ();
+  else if (expr)
+    expr->set_breakpoint ();
+}
+
+void
+tree_statement::delete_breakpoint (void)
+{
+  if (cmd)
+    cmd->delete_breakpoint ();
+  else if (expr)
+    expr->delete_breakpoint ();
+}
+
+bool
+tree_statement::is_breakpoint (void) const
+{
+  return cmd ? cmd->is_breakpoint () : (expr ? expr->is_breakpoint () : false);
+}
+
+int
+tree_statement::line (void) const
+{
+  return cmd ? cmd->line () : (expr ? expr->line () : -1);
+}
+
+int
+tree_statement::column (void) const
+{
+  return cmd ? cmd->column () : (expr ? expr->column () : -1);
+}
+
+void
+tree_statement::echo_code (void)
+{
+  tree_print_code tpc (octave_stdout, VPS4);
+
+  accept (tpc);
+}
+
+bool
+tree_statement::is_end_of_fcn_or_script (void) const
+{
+  bool retval = false;
+
+  if (cmd)
+    {
+      tree_no_op_command *no_op_cmd
+	= dynamic_cast<tree_no_op_command *> (cmd);
+
+      if (no_op_cmd)
+	retval = no_op_cmd->is_end_of_fcn_or_script ();
+    }
+
+  return retval;
+}
+
+tree_statement *
+tree_statement::dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context) const
+{
+  tree_statement *new_stmt = new tree_statement ();
+
+  new_stmt->cmd = cmd ? cmd->dup (scope, context) : 0;
+
+  new_stmt->expr = expr ? expr->dup (scope, context) : 0;
+
+  new_stmt->comm = comm ? comm->dup () : 0;
+
+  return new_stmt;
+}
+
+void
+tree_statement::accept (tree_walker& tw)
+{
+  tw.visit_statement (*this);
+}
+
+int
+tree_statement_list::set_breakpoint (int line)
+{
+  tree_breakpoint tbp (line, tree_breakpoint::set);
+  accept (tbp);
+  
+  return tbp.get_line ();
+}
+
+void
+tree_statement_list::delete_breakpoint (int line)
+{
+  if (line < 0)
+    {
+      octave_value_list bp_lst = list_breakpoints ();
+
+      int len = bp_lst.length ();
+
+      for (int i = 0; i < len; i++)
+	{
+	  tree_breakpoint tbp (i, tree_breakpoint::clear);
+	  accept (tbp);
+	}
+    }
+  else
+    {
+      tree_breakpoint tbp (line, tree_breakpoint::clear); 
+      accept (tbp);
+    }
+}
+
+octave_value_list
+tree_statement_list::list_breakpoints (void)
+{
+  tree_breakpoint tbp (0, tree_breakpoint::list);
+  accept (tbp);
+
+  return tbp.get_list ();
+}
+
+tree_statement_list *
+tree_statement_list::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context) const
+{
+  tree_statement_list *new_list = new tree_statement_list ();
+
+  new_list->function_body = function_body;
+
+  for (const_iterator p = begin (); p != end (); p++)
+    {
+      const tree_statement *elt = *p;
+
+      new_list->append (elt ? elt->dup (scope, context) : 0);
+    }
+
+  return new_list;
+}
+
+void
+tree_statement_list::accept (tree_walker& tw)
+{
+  tw.visit_statement_list (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-stmt.h b/src/pt-stmt.h
new file mode 100644
index 0000000..c2496e2
--- /dev/null
+++ b/src/pt-stmt.h
@@ -0,0 +1,192 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_stmt_h)
+#define octave_tree_stmt_h 1
+
+class octave_value_list;
+
+class tree_command;
+class tree_expression;
+
+class tree_walker;
+
+#include <deque>
+
+#include "base-list.h"
+#include "comment-list.h"
+#include "symtab.h"
+
+// A statement is either a command to execute or an expression to
+// evaluate.
+
+class
+tree_statement
+{
+public:
+
+  tree_statement (void)
+    : cmd (0), expr (0), comm (0) { }
+
+  tree_statement (tree_command *c, octave_comment_list *cl)
+    : cmd (c), expr (0), comm (cl) { }
+
+  tree_statement (tree_expression *e, octave_comment_list *cl)
+    : cmd (0), expr (e), comm (cl) { }
+
+  ~tree_statement (void);
+
+  void set_print_flag (bool print_flag);
+
+  bool print_result (void);
+
+  bool is_command (void) const { return cmd != 0; }
+
+  bool is_expression (void) const { return expr != 0; }
+
+  void set_breakpoint (void);
+
+  void delete_breakpoint (void);
+
+  bool is_breakpoint (void) const;
+
+  int line (void) const;
+  int column (void) const;
+
+  void echo_code (void);
+
+  tree_command *command (void) { return cmd; }
+
+  tree_expression *expression (void) { return expr; }
+
+  octave_comment_list *comment_text (void) { return comm; }
+
+  bool is_null_statement (void) const { return ! (cmd || expr || comm); }
+
+  bool is_end_of_fcn_or_script (void) const;
+
+  // Allow modification of this statement.  Note that there is no
+  // checking.  If you use these, are you sure you knwo what you are
+  // doing?
+
+  void set_command (tree_command *c) { cmd = c; }
+
+  void set_expression (tree_expression *e) { expr = e; }
+
+  tree_statement *dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Only one of cmd or expr can be valid at once.
+
+  // Command to execute.
+  tree_command *cmd;
+
+  // Expression to evaluate.
+  tree_expression *expr;
+
+  // Comment associated with this statement.
+  octave_comment_list *comm;
+
+  // No copying!
+  tree_statement (const tree_statement&);
+
+  tree_statement& operator = (const tree_statement&);
+};
+
+// A list of statements to evaluate.
+
+class
+tree_statement_list : public octave_base_list<tree_statement *>
+{
+public:
+
+  tree_statement_list (void)
+    : function_body (false), anon_function_body (false),
+      script_body (false) { }
+
+  tree_statement_list (tree_statement *s)
+    : function_body (false), anon_function_body (false),
+      script_body (false) { append (s); }
+
+  ~tree_statement_list (void)
+    {
+      while (! empty ())
+	{
+	  iterator p = begin ();
+	  delete *p;
+	  erase (p);
+	}
+    }
+
+  void mark_as_function_body (void) { function_body = true; }
+
+  void mark_as_anon_function_body (void) { anon_function_body = true; }
+
+  void mark_as_script_body (void) { script_body = true; }
+
+  bool is_function_body (void) const { return function_body; }
+
+  bool is_anon_function_body (void) const { return anon_function_body; }
+
+  bool is_script_body (void) const { return script_body; }
+
+  int set_breakpoint (int line);
+
+  void delete_breakpoint (int line);
+
+  octave_value_list list_breakpoints (void);
+
+  tree_statement_list *dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Does this list of statements make up the body of a function?
+  bool function_body;
+
+  // Does this list of statements make up the body of a function?
+  bool anon_function_body;
+
+  // Does this list of statements make up the body of a script?
+  bool script_body;
+
+  // No copying!
+
+  tree_statement_list (const tree_statement_list&);
+
+  tree_statement_list& operator = (const tree_statement_list&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-unop.cc b/src/pt-unop.cc
new file mode 100644
index 0000000..736d9db
--- /dev/null
+++ b/src/pt-unop.cc
@@ -0,0 +1,204 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pt-bp.h"
+#include "pt-unop.h"
+#include "pt-walk.h"
+
+// Unary expressions.
+
+std::string
+tree_unary_expression::oper (void) const
+{
+  return octave_value::unary_op_as_string (etype);
+}
+
+// Prefix expressions.
+
+octave_value_list
+tree_prefix_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("prefix operator `%s': invalid number of output arguments",
+	   oper () . c_str ());
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_prefix_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  if (op)
+    {
+      if (etype == octave_value::op_incr || etype == octave_value::op_decr)
+	{
+	  op->rvalue1 ();
+
+	  if (! error_state)
+	    {
+	      octave_lvalue ref = op->lvalue ();
+
+	      if (! error_state && ref.is_defined ())
+		{
+		  ref.do_unary_op (etype);
+
+		  retval = ref.value ();
+		}
+	    }
+	}
+      else
+	{
+	  octave_value val = op->rvalue1 ();
+
+	  if (! error_state && val.is_defined ())
+	    {
+	      retval = ::do_unary_op (etype, val);
+
+	      if (error_state)
+		retval = octave_value ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+tree_expression *
+tree_prefix_expression::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context) const
+{
+  tree_prefix_expression *new_pe
+    = new tree_prefix_expression (op ? op->dup (scope, context) : 0,
+				  line (), column (), etype);
+
+  new_pe->copy_base (*this);
+
+  return new_pe;
+}
+
+void
+tree_prefix_expression::accept (tree_walker& tw)
+{
+  tw.visit_prefix_expression (*this);
+}
+
+// Postfix expressions.
+
+octave_value_list
+tree_postfix_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("postfix operator `%s': invalid number of output arguments",
+	   oper () . c_str ());
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_postfix_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  if (op)
+    {
+      if (etype == octave_value::op_incr || etype == octave_value::op_decr)
+	{
+	  op->rvalue1 ();
+
+	  if (! error_state)
+	    {
+	      octave_lvalue ref = op->lvalue ();
+
+	      if (! error_state && ref.is_defined ())
+		{
+		  retval = ref.value ();
+
+		  ref.do_unary_op (etype);
+		}
+	    }
+	}
+      else
+	{
+	  octave_value val = op->rvalue1 ();
+
+	  if (! error_state && val.is_defined ())
+	    {
+	      retval = ::do_unary_op (etype, val);
+
+	      if (error_state)
+		retval = octave_value ();
+	    }
+	}
+    }
+
+  return retval;
+}
+
+tree_expression *
+tree_postfix_expression::dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context) const
+{
+  tree_postfix_expression *new_pe
+    = new tree_postfix_expression (op ? op->dup (scope, context) : 0,
+				   line (), column (), etype);
+
+  new_pe->copy_base (*this);
+
+  return new_pe;
+}
+
+void
+tree_postfix_expression::accept (tree_walker& tw)
+{
+  tw.visit_postfix_expression (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-unop.h b/src/pt-unop.h
new file mode 100644
index 0000000..d682881
--- /dev/null
+++ b/src/pt-unop.h
@@ -0,0 +1,164 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
+              2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_unop_h)
+#define octave_tree_unop_h 1
+
+#include <string>
+
+class tree_walker;
+
+class octave_value;
+class octave_value_list;
+class octave_lvalue;
+
+#include "pt-exp.h"
+#include "symtab.h"
+
+// Unary expressions.
+
+class
+tree_unary_expression : public tree_expression
+{
+public:
+
+  tree_unary_expression (int l = -1, int c = -1,
+			 octave_value::unary_op t
+			   = octave_value::unknown_unary_op)
+    : tree_expression (l, c), op (0), etype (t)  { }
+
+  tree_unary_expression (tree_expression *e, int l = -1, int c = -1,
+			 octave_value::unary_op t
+			   = octave_value::unknown_unary_op)
+    : tree_expression (l, c), op (e), etype (t) { }
+
+  ~tree_unary_expression (void) { delete op; }
+
+  bool is_unary_expression (void) const { return true; }
+
+  bool has_magic_end (void) const { return (op && op->has_magic_end ()); }
+
+  tree_expression *operand (void) { return op; }
+
+  std::string oper (void) const;
+  
+  octave_value::unary_op op_type (void) const { return etype; }
+
+protected:
+
+  // The operand for the expression.
+  tree_expression *op;
+
+  // The type of the expression.
+  octave_value::unary_op etype;
+
+private:
+
+  // No copying!
+
+  tree_unary_expression (const tree_unary_expression&);
+
+  tree_unary_expression& operator = (const tree_unary_expression&);
+};
+
+// Prefix expressions.
+
+class
+tree_prefix_expression : public tree_unary_expression
+{
+public:
+
+  tree_prefix_expression (int l = -1, int c = -1)
+    : tree_unary_expression (l, c, octave_value::unknown_unary_op) { }
+
+  tree_prefix_expression (tree_expression *e, int l = -1, int c = -1,
+			  octave_value::unary_op t
+			    = octave_value::unknown_unary_op)
+    : tree_unary_expression (e, l, c, t) { }
+
+  ~tree_prefix_expression (void) { }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_prefix_expression (const tree_prefix_expression&);
+
+  tree_prefix_expression& operator = (const tree_prefix_expression&);
+};
+
+// Postfix expressions.
+
+class
+tree_postfix_expression : public tree_unary_expression
+{
+public:
+
+  tree_postfix_expression (int l = -1, int c = -1)
+    : tree_unary_expression (l, c, octave_value::unknown_unary_op) { }
+
+  tree_postfix_expression (tree_expression *e, int l = -1, int c = -1,
+			   octave_value::unary_op t
+			     = octave_value::unknown_unary_op)
+    : tree_unary_expression (e, l, c, t) { }
+
+  ~tree_postfix_expression (void) { }
+
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_postfix_expression (const tree_postfix_expression&);
+
+  tree_postfix_expression& operator = (const tree_postfix_expression&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt-walk.h b/src/pt-walk.h
new file mode 100644
index 0000000..791f357
--- /dev/null
+++ b/src/pt-walk.h
@@ -0,0 +1,218 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_walker_h)
+#define octave_tree_walker_h 1
+
+class tree_anon_fcn_handle;
+class tree_argument_list;
+class tree_binary_expression;
+class tree_break_command;
+class tree_colon_expression;
+class tree_continue_command;
+class tree_global_command;
+class tree_static_command;
+class tree_decl_elt;
+class tree_decl_init_list;
+class tree_simple_for_command;
+class tree_complex_for_command;
+class octave_user_script;
+class octave_user_function;
+class tree_function_def;
+class tree_identifier;
+class tree_if_clause;
+class tree_if_command;
+class tree_if_command_list;
+class tree_switch_case;
+class tree_switch_case_list;
+class tree_switch_command;
+class tree_index_expression;
+class tree_matrix;
+class tree_cell;
+class tree_multi_assignment;
+class tree_no_op_command;
+class tree_constant;
+class tree_fcn_handle;
+class tree_parameter_list;
+class tree_postfix_expression;
+class tree_prefix_expression;
+class tree_return_command;
+class tree_return_list;
+class tree_simple_assignment;
+class tree_statement;
+class tree_statement_list;
+class tree_try_catch_command;
+class tree_unwind_protect_command;
+class tree_while_command;
+class tree_do_until_command;
+
+class
+tree_walker
+{
+public:
+
+  virtual void
+  visit_anon_fcn_handle (tree_anon_fcn_handle&) = 0;
+
+  virtual void
+  visit_argument_list (tree_argument_list&) = 0;
+
+  virtual void
+  visit_binary_expression (tree_binary_expression&) = 0;
+
+  virtual void
+  visit_break_command (tree_break_command&) = 0;
+
+  virtual void
+  visit_colon_expression (tree_colon_expression&) = 0;
+
+  virtual void
+  visit_continue_command (tree_continue_command&) = 0;
+
+  virtual void
+  visit_global_command (tree_global_command&) = 0;
+
+  virtual void
+  visit_static_command (tree_static_command&) = 0;
+
+  virtual void
+  visit_decl_elt (tree_decl_elt&) = 0;
+
+  virtual void
+  visit_decl_init_list (tree_decl_init_list&) = 0;
+
+  virtual void
+  visit_simple_for_command (tree_simple_for_command&) = 0;
+
+  virtual void
+  visit_complex_for_command (tree_complex_for_command&) = 0;
+
+  virtual void
+  visit_octave_user_script (octave_user_script&) = 0;
+
+  virtual void
+  visit_octave_user_function (octave_user_function&) = 0;
+
+  virtual void
+  visit_function_def (tree_function_def&) = 0;
+
+  virtual void
+  visit_identifier (tree_identifier&) = 0;
+
+  virtual void
+  visit_if_clause (tree_if_clause&) = 0;
+
+  virtual void
+  visit_if_command (tree_if_command&) = 0;
+
+  virtual void
+  visit_if_command_list (tree_if_command_list&) = 0;
+
+  virtual void
+  visit_switch_case (tree_switch_case&) = 0;
+
+  virtual void
+  visit_switch_case_list (tree_switch_case_list&) = 0;
+
+  virtual void
+  visit_switch_command (tree_switch_command&) = 0;
+
+  virtual void
+  visit_index_expression (tree_index_expression&) = 0;
+
+  virtual void
+  visit_matrix (tree_matrix&) = 0;
+
+  virtual void
+  visit_cell (tree_cell&) = 0;
+
+  virtual void
+  visit_multi_assignment (tree_multi_assignment&) = 0;
+
+  virtual void
+  visit_no_op_command (tree_no_op_command&) = 0;
+
+  virtual void
+  visit_constant (tree_constant&) = 0;
+
+  virtual void
+  visit_fcn_handle (tree_fcn_handle&) = 0;
+
+  virtual void
+  visit_parameter_list (tree_parameter_list&) = 0;
+
+  virtual void
+  visit_postfix_expression (tree_postfix_expression&) = 0;
+
+  virtual void
+  visit_prefix_expression (tree_prefix_expression&) = 0;
+
+  virtual void
+  visit_return_command (tree_return_command&) = 0;
+
+  virtual void
+  visit_return_list (tree_return_list&) = 0;
+
+  virtual void
+  visit_simple_assignment (tree_simple_assignment&) = 0;
+
+  virtual void
+  visit_statement (tree_statement&) = 0;
+
+  virtual void
+  visit_statement_list (tree_statement_list&) = 0;
+
+  virtual void
+  visit_try_catch_command (tree_try_catch_command&) = 0;
+
+  virtual void
+  visit_unwind_protect_command (tree_unwind_protect_command&) = 0;
+
+  virtual void
+  visit_while_command (tree_while_command&) = 0;
+
+  virtual void
+  visit_do_until_command (tree_do_until_command&) = 0;
+
+protected:
+
+  tree_walker (void) { }
+
+  virtual ~tree_walker (void) { }
+
+private:
+
+  // No copying!
+
+  tree_walker (const tree_walker&);
+
+  tree_walker& operator = (const tree_walker&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt.cc b/src/pt.cc
new file mode 100644
index 0000000..bba1087
--- /dev/null
+++ b/src/pt.cc
@@ -0,0 +1,57 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "ov-fcn.h"
+#include "pt.h"
+#include "pt-pr-code.h"
+
+// Hide the details of the string buffer so that we are less likely to
+// create a memory leak.
+
+std::string
+tree::str_print_code (void)
+{
+  std::ostringstream buf;
+
+  tree_print_code tpc (buf);
+
+  accept (tpc);
+
+  std::string retval = buf.str ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/pt.h b/src/pt.h
new file mode 100644
index 0000000..6bdaa42
--- /dev/null
+++ b/src/pt.h
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_h)
+#define octave_tree_h 1
+
+#include <string>
+
+#include <iosfwd>
+
+class octave_function;
+class tree_walker;
+
+// Base class for the parse tree.
+
+class
+tree
+{
+public:
+
+  tree (int l = -1, int c = -1)
+    : line_num (l), column_num (c), bp (false) { }
+
+  virtual ~tree (void) { }
+
+  virtual int line (void) const { return line_num; }
+
+  virtual int column (void) const { return column_num; }
+
+  void line (int l) { line_num = l; }
+
+  void column (int c) { column_num = c; }
+
+  virtual void set_breakpoint (void) { bp = true; }
+
+  virtual void delete_breakpoint (void) { bp = false; }
+
+  bool is_breakpoint (void) const { return bp; }
+
+  std::string str_print_code (void);
+
+  virtual void accept (tree_walker& tw) = 0;
+
+private:
+
+  // The input line and column where we found the text that was
+  // eventually converted to this tree node.
+  int line_num;
+  int column_num;
+
+  // Breakpoint flag.
+  bool bp;
+
+  // No copying!
+
+  tree (const tree&);
+
+  tree& operator = (const tree&);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sighandlers.cc b/src/sighandlers.cc
new file mode 100644
index 0000000..858402a
--- /dev/null
+++ b/src/sighandlers.cc
@@ -0,0 +1,1045 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <iostream>
+#include <new>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "oct-syscalls.h"
+#include "quit.h"
+
+#include "debug.h"
+#include "defun.h"
+#include "error.h"
+#include "load-save.h"
+#include "oct-map.h"
+#include "pager.h"
+#include "pt-bp.h"
+#include "pt-eval.h"
+#include "sighandlers.h"
+#include "sysdep.h"
+#include "syswait.h"
+#include "toplev.h"
+#include "utils.h"
+#include "variables.h"
+
+// Nonzero means we have already printed a message for this series of
+// SIGPIPES.  We assume that the writer will eventually give up.
+int pipe_handler_error_count = 0;
+
+// TRUE means we can be interrupted.
+bool can_interrupt = false;
+
+// TRUE means we should try to enter the debugger on SIGINT.
+static bool Vdebug_on_interrupt = false;
+
+// Allow users to avoid writing octave-core for SIGHUP (sent by
+// closing gnome-terminal, for example).  Note that this variable has
+// no effect if Vcrash_dumps_octave_core is FALSE.
+static bool Vsighup_dumps_octave_core = true;
+
+// Similar to Vsighup_dumps_octave_core, but for SIGTERM signal.
+static bool Vsigterm_dumps_octave_core = true;
+
+#if defined (RETSIGTYPE_IS_VOID)
+#define SIGHANDLER_RETURN(status) return
+#else
+#define SIGHANDLER_RETURN(status) return status
+#endif
+
+#if defined (MUST_REINSTALL_SIGHANDLERS)
+#define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \
+  octave_set_signal_handler (sig, handler)
+#define REINSTALL_USES_SIG 1
+#else
+#define MAYBE_REINSTALL_SIGHANDLER(sig, handler) \
+  do { } while (0)
+#endif
+
+#if defined (__EMX__)
+#define MAYBE_ACK_SIGNAL(sig) \
+  octave_set_signal_handler (sig, SIG_ACK)
+#define ACK_USES_SIG 1
+#else
+#define MAYBE_ACK_SIGNAL(sig) \
+  do { } while (0)
+#endif
+
+// List of signals we have caught since last call to octave_signal_handler.
+static bool octave_signals_caught[NSIG];
+
+// Called from OCTAVE_QUIT to actually do something about the signals
+// we have caught.
+
+void
+octave_signal_handler (void)
+{
+  // The list of signals is relatively short, so we will just go
+  // linearly through the list.
+
+  for (int i = 0; i < NSIG; i++)
+    {
+      if (octave_signals_caught[i])
+	{
+	  octave_signals_caught[i] = false;
+
+	  switch (i)
+	    {
+#ifdef SIGCHLD
+	    case SIGCHLD:
+	      octave_child_list::reap ();
+	      break;
+#endif
+
+	    case SIGFPE:
+	      std::cerr << "warning: floating point exception -- trying to return to prompt" << std::endl;
+	      break;
+
+#ifdef SIGPIPE
+	    case SIGPIPE:
+	      std::cerr << "warning: broken pipe -- some output may be lost" << std::endl;
+	      break;
+#endif
+	    }
+	}
+    }
+}
+
+static void
+my_friendly_exit (const char *sig_name, int sig_number,
+		  bool save_vars = true)
+{
+  static bool been_there_done_that = false;
+
+  if (been_there_done_that)
+    {
+#if defined (SIGABRT)
+      octave_set_signal_handler (SIGABRT, SIG_DFL);
+#endif
+
+      std::cerr << "panic: attempted clean up apparently failed -- aborting...\n";
+
+      MINGW_SIGNAL_CLEANUP ();
+
+      abort ();
+    }
+  else
+    {
+      been_there_done_that = true;
+
+      std::cerr << "panic: " << sig_name << " -- stopping myself...\n";
+
+      if (save_vars)
+	dump_octave_core ();
+
+      if (sig_number < 0)
+	{
+	  MINGW_SIGNAL_CLEANUP ();
+
+	  exit (1);
+	}
+      else
+	{
+	  octave_set_signal_handler (sig_number, SIG_DFL);
+
+#if defined (HAVE_RAISE)
+	  raise (sig_number);
+#elif defined (HAVE_KILL)
+	  kill (getpid (), sig_number);
+#else
+	  exit (1);
+#endif
+	}
+
+    }
+}
+
+sig_handler *
+octave_set_signal_handler (int sig, sig_handler *handler,
+			   bool restart_syscalls)
+{
+#if defined (HAVE_POSIX_SIGNALS)
+  struct sigaction act, oact;
+
+  act.sa_handler = handler;
+  act.sa_flags = 0;
+
+  if (sig == SIGALRM)
+    {
+#if defined (SA_INTERRUPT)
+      act.sa_flags |= SA_INTERRUPT;
+#endif
+    }
+#if defined (SA_RESTART)
+  // FIXME -- Do we also need to explicitly disable SA_RESTART?
+  else if (restart_syscalls)
+    act.sa_flags |= SA_RESTART;
+#endif
+
+  sigemptyset (&act.sa_mask);
+  sigemptyset (&oact.sa_mask);
+
+  sigaction (sig, &act, &oact);
+
+  return oact.sa_handler;
+#else
+  return signal (sig, handler);
+#endif
+}
+
+static RETSIGTYPE
+generic_sig_handler (int sig)
+{
+  my_friendly_exit (strsignal (sig), sig);
+
+  SIGHANDLER_RETURN (0);
+}
+
+// Handle SIGCHLD.
+
+#ifdef SIGCHLD
+static RETSIGTYPE
+sigchld_handler (int /* sig */)
+{
+  volatile octave_interrupt_handler saved_interrupt_handler
+     = octave_ignore_interrupts ();
+
+  // I wonder if this is really right, or if SIGCHLD should just be
+  // blocked on OS/2 systems the same as for systems with POSIX signal
+  // functions.
+
+#if defined (__EMX__)
+  volatile sig_handler *saved_sigchld_handler
+    = octave_set_signal_handler (SIGCHLD, SIG_IGN);
+#endif
+
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+
+  if (octave_child_list::wait ())
+    {
+      // The status of some child changed.
+
+      octave_signal_caught = 1;
+
+      octave_signals_caught[SIGCHLD] = true;
+    }
+
+  octave_set_interrupt_handler (saved_interrupt_handler);
+
+  UNBLOCK_CHILD (oset);
+
+#ifdef __EMX__
+  octave_set_signal_handler (SIGCHLD, saved_sigchld_handler);
+#endif
+
+  MAYBE_ACK_SIGNAL (SIGCHLD);
+
+  MAYBE_REINSTALL_SIGHANDLER (SIGCHLD, sigchld_handler);
+
+  SIGHANDLER_RETURN (0);
+}
+#endif /* defined(SIGCHLD) */
+
+#ifdef SIGFPE
+#if defined (__alpha__)
+static RETSIGTYPE
+sigfpe_handler (int /* sig */)
+{
+  MAYBE_ACK_SIGNAL (SIGFPE);
+
+  MAYBE_REINSTALL_SIGHANDLER (SIGFPE, sigfpe_handler);
+
+  if (can_interrupt && octave_interrupt_state >= 0)
+    {
+      octave_signal_caught = 1;
+
+      octave_signals_caught[SIGFPE] = true;
+
+      octave_interrupt_state++;
+    }
+
+  SIGHANDLER_RETURN (0);
+}
+#endif /* defined(__alpha__) */
+#endif /* defined(SIGFPE) */
+
+#if defined (SIGHUP) || defined (SIGTERM)
+static RETSIGTYPE
+sig_hup_or_term_handler (int sig)
+{
+  MAYBE_ACK_SIGNAL (sig);
+
+  MAYBE_REINSTALL_SIGHANDLER (sig, sig_hup_or_term_handler);
+
+  switch (sig)
+    {
+#if defined (SIGHUP)
+    case SIGHUP:
+      {
+	if (Vsighup_dumps_octave_core)
+	  dump_octave_core ();
+      }
+      break;
+#endif
+
+#if defined (SIGTERM)
+    case SIGTERM:
+      {
+	if (Vsigterm_dumps_octave_core)
+	  dump_octave_core ();
+      }
+      break;
+#endif
+
+    default:
+      break;
+    }
+
+  clean_up_and_exit (0);
+
+  SIGHANDLER_RETURN (0);
+}
+#endif
+
+#if 0
+#if defined (SIGWINCH)
+static RETSIGTYPE
+sigwinch_handler (int /* sig */)
+{
+  MAYBE_ACK_SIGNAL (SIGWINCH);
+
+  MAYBE_REINSTALL_SIGHANDLER (SIGWINCH, sigwinch_handler);
+
+  command_editor::resize_terminal ();
+
+  SIGHANDLER_RETURN (0);
+}
+#endif
+#endif
+
+// Handle SIGINT by restarting the parser (see octave.cc).
+//
+// This also has to work for SIGBREAK (on systems that have it), so we
+// use the value of sig, instead of just assuming that it is called
+// for SIGINT only.
+
+static void
+user_abort (const char *sig_name, int sig_number)
+{
+  if (! octave_initialized)
+    exit (1);
+
+  if (can_interrupt)
+    {
+      if (Vdebug_on_interrupt)
+	{
+	  if (! octave_debug_on_interrupt_state)
+	    {
+	      tree_evaluator::debug_mode = true;
+	      octave_debug_on_interrupt_state = true;
+
+	      return;
+	    }
+	  else
+	    {
+	      // Clear the flag and do normal interrupt stuff.
+
+	      tree_evaluator::debug_mode = bp_table::have_breakpoints ();
+	      octave_debug_on_interrupt_state = false;
+	    }
+	}
+
+      if (octave_interrupt_immediately)
+	{
+	  if (octave_interrupt_state == 0)
+	    octave_interrupt_state = 1;
+
+	  octave_jump_to_enclosing_context ();
+	}
+      else
+	{
+	  // If we are already cleaning up from a previous interrupt,
+	  // take note of the fact that another interrupt signal has
+	  // arrived.
+
+	  if (octave_interrupt_state < 0)
+	    octave_interrupt_state = 0;
+
+	  octave_signal_caught = 1;
+	  octave_interrupt_state++;
+
+	  if (interactive && octave_interrupt_state == 2)
+	    std::cerr << "Press Control-C again to abort." << std::endl;
+
+	  if (octave_interrupt_state >= 3)
+	    my_friendly_exit (sig_name, sig_number, true);
+	}
+    }
+
+}
+
+static RETSIGTYPE
+sigint_handler (int sig)
+{
+  MAYBE_ACK_SIGNAL (sig);
+
+  MAYBE_REINSTALL_SIGHANDLER (sig, sigint_handler);
+
+#ifdef USE_W32_SIGINT
+  if (w32_in_main_thread ())
+    user_abort (strsignal (sig), sig);
+  else
+    w32_raise (sig);
+#else
+  user_abort (strsignal (sig), sig);
+#endif
+
+  SIGHANDLER_RETURN (0);
+}
+
+#ifdef SIGPIPE
+static RETSIGTYPE
+sigpipe_handler (int /* sig */)
+{
+  MAYBE_ACK_SIGNAL (SIGPIPE);
+
+  MAYBE_REINSTALL_SIGHANDLER (SIGPIPE, sigpipe_handler);
+
+  octave_signal_caught = 1;
+
+  octave_signals_caught[SIGPIPE] = true;
+
+  // Don't loop forever on account of this.
+
+  if (pipe_handler_error_count++ > 100 && octave_interrupt_state >= 0)
+    octave_interrupt_state++;
+
+  SIGHANDLER_RETURN (0);
+}
+#endif /* defined(SIGPIPE) */
+
+#ifdef USE_W32_SIGINT
+static BOOL CALLBACK
+w32_sigint_handler (DWORD sig)
+{
+  const char *sig_name;
+
+  switch(sig)
+    {
+      case CTRL_BREAK_EVENT:   
+	sig_name = "Ctrl-Break"; 
+	break;
+      case CTRL_C_EVENT:
+	sig_name = "Ctrl-C";
+	break;
+      case CTRL_CLOSE_EVENT:
+	sig_name = "close console";
+	break;
+      case CTRL_LOGOFF_EVENT:
+	sig_name = "logoff";
+	break;
+      case CTRL_SHUTDOWN_EVENT:
+	sig_name = "shutdown";
+	break;
+      default:
+	sig_name = "unknown console event";
+	break;
+    }
+
+  switch(sig)
+    {
+      case CTRL_BREAK_EVENT:
+      case CTRL_C_EVENT:
+	w32_raise (SIGINT);
+        break;
+
+      case CTRL_CLOSE_EVENT:
+      case CTRL_LOGOFF_EVENT:
+      case CTRL_SHUTDOWN_EVENT:
+      default:
+        // We should do the following:
+        //    clean_up_and_exit (0);
+        // We can't because we aren't running in the normal Octave thread.
+	user_abort(sig_name, sig);
+        break;
+    }
+
+  // Return TRUE if the event was handled, or FALSE if another handler 
+  // should be called.
+  // FIXME check that windows terminates the thread.
+  return TRUE;
+}
+#endif /* w32_sigint_handler */
+
+
+octave_interrupt_handler
+octave_catch_interrupts (void)
+{
+  octave_interrupt_handler retval;
+
+#ifdef SIGINT
+  retval.int_handler = octave_set_signal_handler (SIGINT, sigint_handler);
+#endif
+
+#ifdef SIGBREAK
+  retval.brk_handler = octave_set_signal_handler (SIGBREAK, sigint_handler);
+#endif
+
+#ifdef USE_W32_SIGINT
+
+  // Intercept windows console control events.
+  // Note that the windows console signal handlers chain, so if 
+  // install_signal_handlers is called more than once in the same program,
+  // then first call the following to avoid duplicates:
+  //
+  //   SetConsoleCtrlHandler (w32_sigint_handler, FALSE);
+
+  if (! SetConsoleCtrlHandler (w32_sigint_handler, TRUE))
+    error ("SetConsoleCtrlHandler failed with %ld\n", GetLastError ());
+
+  w32_set_quiet_shutdown ();
+
+#endif
+
+  return retval;
+}
+
+octave_interrupt_handler
+octave_ignore_interrupts (void)
+{
+  octave_interrupt_handler retval;
+
+#ifdef SIGINT
+  retval.int_handler = octave_set_signal_handler (SIGINT, SIG_IGN);
+#endif
+
+#ifdef SIGBREAK
+  retval.brk_handler = octave_set_signal_handler (SIGBREAK, SIG_IGN);
+#endif
+
+  return retval;
+}
+
+octave_interrupt_handler
+octave_set_interrupt_handler (const volatile octave_interrupt_handler& h,
+			      bool restart_syscalls)
+{
+  octave_interrupt_handler retval;
+
+#ifdef SIGINT
+  retval.int_handler = octave_set_signal_handler (SIGINT, h.int_handler,
+						  restart_syscalls);
+#endif
+
+#ifdef SIGBREAK
+  retval.brk_handler = octave_set_signal_handler (SIGBREAK, h.brk_handler,
+						  restart_syscalls);
+#endif
+
+  return retval;
+}
+
+// Install all the handlers for the signals we might care about.
+
+void
+install_signal_handlers (void)
+{
+  for (int i = 0; i < NSIG; i++)
+    octave_signals_caught[i] = false;
+
+  octave_catch_interrupts ();
+
+#ifdef SIGABRT
+  octave_set_signal_handler (SIGABRT, generic_sig_handler);
+#endif
+
+#ifdef SIGALRM
+  octave_set_signal_handler (SIGALRM, generic_sig_handler);
+#endif
+
+#ifdef SIGBUS
+  octave_set_signal_handler (SIGBUS, generic_sig_handler);
+#endif
+
+#ifdef SIGCHLD
+  octave_set_signal_handler (SIGCHLD, sigchld_handler);
+#endif
+
+  // SIGCLD
+  // SIGCONT
+
+#ifdef SIGEMT
+  octave_set_signal_handler (SIGEMT, generic_sig_handler);
+#endif
+
+#ifdef SIGFPE
+#if defined (__alpha__)
+  octave_set_signal_handler (SIGFPE, sigfpe_handler);
+#else
+  octave_set_signal_handler (SIGFPE, generic_sig_handler);
+#endif
+#endif
+
+#ifdef SIGHUP
+  octave_set_signal_handler (SIGHUP, sig_hup_or_term_handler);
+#endif
+
+#ifdef SIGILL
+  octave_set_signal_handler (SIGILL, generic_sig_handler);
+#endif
+
+  // SIGINFO
+  // SIGINT
+
+#ifdef SIGIOT
+  octave_set_signal_handler (SIGIOT, generic_sig_handler);
+#endif
+
+#ifdef SIGLOST
+  octave_set_signal_handler (SIGLOST, generic_sig_handler);
+#endif
+
+#ifdef SIGPIPE
+  octave_set_signal_handler (SIGPIPE, sigpipe_handler);
+#endif
+
+#ifdef SIGPOLL
+  octave_set_signal_handler (SIGPOLL, SIG_IGN);
+#endif
+
+  // SIGPROF
+  // SIGPWR
+
+#ifdef SIGQUIT
+  octave_set_signal_handler (SIGQUIT, generic_sig_handler);
+#endif
+
+#ifdef SIGSEGV
+  octave_set_signal_handler (SIGSEGV, generic_sig_handler);
+#endif
+
+  // SIGSTOP
+
+#ifdef SIGSYS
+  octave_set_signal_handler (SIGSYS, generic_sig_handler);
+#endif
+
+#ifdef SIGTERM
+  octave_set_signal_handler (SIGTERM, sig_hup_or_term_handler);
+#endif
+
+#ifdef SIGTRAP
+  octave_set_signal_handler (SIGTRAP, generic_sig_handler);
+#endif
+
+  // SIGTSTP
+  // SIGTTIN
+  // SIGTTOU
+  // SIGURG
+
+#ifdef SIGUSR1
+  octave_set_signal_handler (SIGUSR1, generic_sig_handler);
+#endif
+
+#ifdef SIGUSR2
+  octave_set_signal_handler (SIGUSR2, generic_sig_handler);
+#endif
+
+#ifdef SIGVTALRM
+  octave_set_signal_handler (SIGVTALRM, generic_sig_handler);
+#endif
+
+#ifdef SIGIO
+  octave_set_signal_handler (SIGIO, SIG_IGN);
+#endif
+
+#if 0
+#ifdef SIGWINCH
+  octave_set_signal_handler (SIGWINCH, sigwinch_handler);
+#endif
+#endif
+
+#ifdef SIGXCPU
+  octave_set_signal_handler (SIGXCPU, generic_sig_handler);
+#endif
+
+#ifdef SIGXFSZ
+  octave_set_signal_handler (SIGXFSZ, generic_sig_handler);
+#endif
+
+}
+
+static Octave_map
+make_sig_struct (void)
+{
+  Octave_map m;
+
+#ifdef SIGABRT
+  m.assign ("ABRT", SIGABRT);
+#endif
+
+#ifdef SIGALRM
+  m.assign ("ALRM", SIGALRM);
+#endif
+
+#ifdef SIGBUS
+  m.assign ("BUS", SIGBUS);
+#endif
+
+#ifdef SIGCHLD
+  m.assign ("CHLD", SIGCHLD);
+#endif
+
+#ifdef SIGCLD
+  m.assign ("CLD", SIGCLD);
+#endif
+
+#ifdef SIGCONT
+  m.assign ("CONT", SIGCONT);
+#endif
+
+#ifdef SIGEMT
+  m.assign ("EMT", SIGEMT);
+#endif
+
+#ifdef SIGFPE
+  m.assign ("FPE", SIGFPE);
+#endif
+
+#ifdef SIGHUP
+  m.assign ("HUP", SIGHUP);
+#endif
+
+#ifdef SIGILL
+  m.assign ("ILL", SIGILL);
+#endif
+
+#ifdef SIGINFO
+  m.assign ("INFO", SIGINFO);
+#endif
+
+#ifdef SIGINT
+  m.assign ("INT", SIGINT);
+#endif
+
+#ifdef SIGIOT
+  m.assign ("IOT", SIGIOT);
+#endif
+
+#ifdef SIGLOST
+  m.assign ("LOST", SIGLOST);
+#endif
+
+#ifdef SIGPIPE
+  m.assign ("PIPE", SIGPIPE);
+#endif
+
+#ifdef SIGPOLL
+  m.assign ("POLL", SIGPOLL);
+#endif
+
+#ifdef SIGPROF
+  m.assign ("PROF", SIGPROF);
+#endif
+
+#ifdef SIGPWR
+  m.assign ("PWR", SIGPWR);
+#endif
+
+#ifdef SIGQUIT
+  m.assign ("QUIT", SIGQUIT);
+#endif
+
+#ifdef SIGSEGV
+  m.assign ("SEGV", SIGSEGV);
+#endif
+
+#ifdef SIGSTOP
+  m.assign ("STOP", SIGSTOP);
+#endif
+
+#ifdef SIGSYS
+  m.assign ("SYS", SIGSYS);
+#endif
+
+#ifdef SIGTERM
+  m.assign ("TERM", SIGTERM);
+#endif
+
+#ifdef SIGTRAP
+  m.assign ("TRAP", SIGTRAP);
+#endif
+
+#ifdef SIGTSTP
+  m.assign ("TSTP", SIGTSTP);
+#endif
+
+#ifdef SIGTTIN
+  m.assign ("TTIN", SIGTTIN);
+#endif
+
+#ifdef SIGTTOU
+  m.assign ("TTOU", SIGTTOU);
+#endif
+
+#ifdef SIGURG
+  m.assign ("URG", SIGURG);
+#endif
+
+#ifdef SIGUSR1
+  m.assign ("USR1", SIGUSR1);
+#endif
+
+#ifdef SIGUSR2
+  m.assign ("USR2", SIGUSR2);
+#endif
+
+#ifdef SIGVTALRM
+  m.assign ("VTALRM", SIGVTALRM);
+#endif
+
+#ifdef SIGIO
+  m.assign ("IO", SIGIO);
+#endif
+
+#ifdef SIGWINCH
+  m.assign ("WINCH", SIGWINCH);
+#endif
+
+#ifdef SIGXCPU
+  m.assign ("XCPU", SIGXCPU);
+#endif
+
+#ifdef SIGXFSZ
+  m.assign ("XFSZ", SIGXFSZ);
+#endif
+
+  return m;
+}
+
+octave_child_list::octave_child_list_rep *octave_child_list::instance = 0;
+
+bool
+octave_child_list::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_child_list_rep ();
+
+  if (! instance)
+    {
+      ::error ("unable to create child list object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+octave_child_list::insert (pid_t pid, octave_child::child_event_handler f)
+{
+  if (instance_ok ())
+    instance->insert (pid, f);
+}
+
+void
+octave_child_list::reap (void)
+{
+  if (instance_ok ())
+    instance->reap ();
+}
+
+bool
+octave_child_list::wait (void)
+{
+  return (instance_ok ()) ? instance->wait () : false;
+}
+
+class pid_equal
+{
+public:
+
+  pid_equal (pid_t v) : val (v) { }
+
+  bool operator () (const octave_child& oc) const { return oc.pid == val; }
+
+private:
+
+  pid_t val;
+};
+
+void
+octave_child_list::remove (pid_t pid)
+{
+  if (instance_ok ())
+    instance->remove_if (pid_equal (pid));
+}
+
+#define OCL_REP octave_child_list::octave_child_list_rep
+
+void
+OCL_REP::insert (pid_t pid, octave_child::child_event_handler f)
+{
+  append (octave_child (pid, f));
+}
+
+void
+OCL_REP::reap (void)
+{
+  // Mark the record for PID invalid.
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      // The call to the octave_child::child_event_handler might
+      // invalidate the iterator (for example, by calling
+      // octave_child_list::remove), so we increment the iterator
+      // here.
+
+      octave_child& oc = *p;
+
+      if (oc.have_status)
+	{
+	  oc.have_status = 0;
+
+	  octave_child::child_event_handler f = oc.handler;
+
+	  if (f && f (oc.pid, oc.status))
+	    oc.pid = -1;
+	}
+    }
+
+  remove_if (pid_equal (-1));
+}
+
+// Wait on our children and record any changes in their status.
+
+bool
+OCL_REP::wait (void)
+{
+  bool retval = false;
+
+  for (iterator p = begin (); p != end (); p++)
+    {
+      octave_child& oc = *p;
+
+      pid_t pid = oc.pid;
+
+      if (pid > 0)
+	{
+	  int status;
+
+	  if (octave_syscalls::waitpid (pid, &status, WNOHANG) > 0)
+	    {
+	      oc.have_status = 1;
+
+	      oc.status = status;
+
+	      retval = true;
+
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (SIG, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} SIG ()\n\
+Return a structure containing Unix signal names and their defined values.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    {
+      static Octave_map m = make_sig_struct ();
+
+      retval = m;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (debug_on_interrupt, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} debug_on_interrupt (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave will try\n\
+to enter debugging mode when it receives an interrupt signal (typically\n\
+generated with @kbd{C-c}).  If a second interrupt signal is received\n\
+before reaching the debugging mode, a normal interrupt will occur.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (debug_on_interrupt);
+}
+
+DEFUN (sighup_dumps_octave_core, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave tries\n\
+to save all current variables to the file \"octave-core\" if it receives\n\
+a hangup signal.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core);
+}
+
+DEFUN (sigterm_dumps_octave_core, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave tries\n\
+to save all current variables to the file \"octave-core\" if it receives\n\
+a terminate signal.\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sighandlers.h b/src/sighandlers.h
new file mode 100644
index 0000000..806fc00
--- /dev/null
+++ b/src/sighandlers.h
@@ -0,0 +1,212 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2005, 2006,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+The signal blocking macros defined below were adapted from similar
+functions from GNU Bash, the Bourne Again SHell, copyright (C) 1994
+Free Software Foundation, Inc.
+
+*/
+
+// This file should always be included after config.h!
+
+#if !defined (octave_sighandlers_h)
+#define octave_sighandlers_h 1
+
+// Include signal.h, not csignal since the latter might only define
+// the ANSI standard C signal interface.
+
+#include <signal.h>
+
+#include "syswait.h"
+#include "siglist.h"
+
+#include "base-list.h"
+
+// Signal handler return type.
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+#ifndef BADSIG
+#define BADSIG (RETSIGTYPE (*)(int))-1
+#endif
+
+#define BLOCK_SIGNAL(sig, nvar, ovar) \
+  do \
+    { \
+      sigemptyset (&nvar); \
+      sigaddset (&nvar, sig); \
+      sigemptyset (&ovar); \
+      sigprocmask (SIG_BLOCK, &nvar, &ovar); \
+    } \
+  while (0)
+
+#if !defined (SIGCHLD) && defined (SIGCLD)
+#define SIGCHLD SIGCLD
+#endif
+
+#if defined (HAVE_POSIX_SIGNALS)
+#define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar)
+#define UNBLOCK_CHILD(ovar) sigprocmask (SIG_SETMASK, &ovar, 0)
+#else
+#define BLOCK_CHILD(nvar, ovar) ovar = sigblock (sigmask (SIGCHLD))
+#define UNBLOCK_CHILD(ovar) sigsetmask (ovar)
+#endif
+
+typedef RETSIGTYPE sig_handler (int);
+
+// FIXME -- the data should probably be private...
+
+struct
+octave_interrupt_handler
+{
+#ifdef SIGINT
+  sig_handler *int_handler;
+#endif
+
+#ifdef SIGBREAK
+  sig_handler *brk_handler;
+#endif
+};
+
+// Nonzero means we have already printed a message for this series of
+// SIGPIPES.  We assume that the writer will eventually give up.
+extern int pipe_handler_error_count;
+
+// TRUE means we can be interrupted.
+extern OCTINTERP_API bool can_interrupt;
+
+extern OCTINTERP_API sig_handler *octave_set_signal_handler (int, sig_handler *,
+					       bool restart_syscalls = true);
+
+extern OCTINTERP_API void install_signal_handlers (void);
+
+extern OCTINTERP_API void octave_signal_handler (void);
+
+extern OCTINTERP_API octave_interrupt_handler octave_catch_interrupts (void);
+
+extern OCTINTERP_API octave_interrupt_handler octave_ignore_interrupts (void);
+
+extern OCTINTERP_API octave_interrupt_handler
+octave_set_interrupt_handler (const volatile octave_interrupt_handler&,
+			      bool restart_syscalls = true);
+
+// extern void ignore_sigchld (void);
+
+// Maybe this should be in a separate file?
+
+class
+OCTINTERP_API
+octave_child
+{
+public:
+  
+  // Do whatever to handle event for child with PID (might not
+  // actually be dead, could just be stopped).  Return true if
+  // the list element corresponding to PID should be removed from
+  // list.  This function should not call any functions that modify
+  // the octave_child_list.
+
+  typedef bool (*child_event_handler) (pid_t, int);
+
+  octave_child (pid_t id = -1, child_event_handler f = 0)
+    : pid (id), handler (f), have_status (0), status (0) { }
+
+  octave_child (const octave_child& oc)
+    : pid (oc.pid), handler (oc.handler),
+      have_status (oc.have_status), status (oc.status) { }
+ 
+  octave_child& operator = (const octave_child& oc)
+    {
+      if (&oc != this)
+	{
+	  pid = oc.pid;
+	  handler = oc.handler;
+	  have_status = oc.have_status;
+	  status = oc.status;
+	}
+      return *this;
+    }
+
+  ~octave_child (void) { }
+
+  // The process id of this child.
+  pid_t pid;
+
+  // The function we call if an event happens for this child.
+  child_event_handler handler;
+
+  // Nonzero if this child has stopped or terminated.
+  sig_atomic_t have_status;
+
+  // The status of this child; 0 if running, otherwise a status value
+  // from waitpid.
+  int status;
+};
+
+class
+OCTINTERP_API
+octave_child_list
+{
+protected:
+
+  octave_child_list (void) { }
+
+  class octave_child_list_rep : public octave_base_list<octave_child>
+  {
+  public:
+
+    void insert (pid_t pid, octave_child::child_event_handler f);
+
+    void reap (void);
+
+    bool wait (void);
+  };
+
+public:
+
+  ~octave_child_list (void) { }
+
+  static void insert (pid_t pid, octave_child::child_event_handler f);
+
+  static void reap (void);
+
+  static bool wait (void);
+
+  static void remove (pid_t pid);
+
+private:
+
+  static bool instance_ok (void);
+
+  static octave_child_list_rep *instance;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/siglist.c b/src/siglist.c
new file mode 100644
index 0000000..ac62a5e
--- /dev/null
+++ b/src/siglist.c
@@ -0,0 +1,238 @@
+/*
+
+Copyright (C) 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+
+#include "siglist.h"
+
+/* The following is all borrowed from Emacs.  */
+
+#if ! (defined HAVE_STRSIGNAL || HAVE_DECL_SYS_SIGLIST)
+
+static char *my_sys_siglist[NSIG];
+
+#ifdef sys_siglist
+#undef sys_siglist
+#endif
+#define sys_siglist my_sys_siglist
+
+#endif
+
+void
+init_signals (void)
+{
+#if ! (defined HAVE_STRSIGNAL || HAVE_DECL_SYS_SIGLIST)
+
+  static int initialized = 0;
+
+  if (! initialized)
+    {
+      initialized = 1;
+
+# ifdef SIGABRT
+      sys_siglist[SIGABRT] = "Aborted";
+# endif
+# ifdef SIGAIO
+      sys_siglist[SIGAIO] = "LAN I/O interrupt";
+# endif
+# ifdef SIGALRM
+      sys_siglist[SIGALRM] = "Alarm clock";
+# endif
+# ifdef SIGBUS
+      sys_siglist[SIGBUS] = "Bus error";
+# endif
+# ifdef SIGCLD
+      sys_siglist[SIGCLD] = "Child status changed";
+# endif
+# ifdef SIGCHLD
+      sys_siglist[SIGCHLD] = "Child status changed";
+# endif
+# ifdef SIGCONT
+      sys_siglist[SIGCONT] = "Continued";
+# endif
+# ifdef SIGDANGER
+      sys_siglist[SIGDANGER] = "Swap space dangerously low";
+# endif
+# ifdef SIGDGNOTIFY
+      sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
+# endif
+# ifdef SIGEMT
+      sys_siglist[SIGEMT] = "Emulation trap";
+# endif
+# ifdef SIGFPE
+      sys_siglist[SIGFPE] = "Arithmetic exception";
+# endif
+# ifdef SIGFREEZE
+      sys_siglist[SIGFREEZE] = "SIGFREEZE";
+# endif
+# ifdef SIGGRANT
+      sys_siglist[SIGGRANT] = "Monitor mode granted";
+# endif
+# ifdef SIGHUP
+      sys_siglist[SIGHUP] = "Hangup";
+# endif
+# ifdef SIGILL
+      sys_siglist[SIGILL] = "Illegal instruction";
+# endif
+# ifdef SIGINT
+      sys_siglist[SIGINT] = "Interrupt";
+# endif
+# ifdef SIGIO
+      sys_siglist[SIGIO] = "I/O possible";
+# endif
+# ifdef SIGIOINT
+      sys_siglist[SIGIOINT] = "I/O intervention required";
+# endif
+# ifdef SIGIOT
+      sys_siglist[SIGIOT] = "IOT trap";
+# endif
+# ifdef SIGKILL
+      sys_siglist[SIGKILL] = "Killed";
+# endif
+# ifdef SIGLOST
+      sys_siglist[SIGLOST] = "Resource lost";
+# endif
+# ifdef SIGLWP
+      sys_siglist[SIGLWP] = "SIGLWP";
+# endif
+# ifdef SIGMSG
+      sys_siglist[SIGMSG] = "Monitor mode data available";
+# endif
+# ifdef SIGPHONE
+      sys_siglist[SIGWIND] = "SIGPHONE";
+# endif
+# ifdef SIGPIPE
+      sys_siglist[SIGPIPE] = "Broken pipe";
+# endif
+# ifdef SIGPOLL
+      sys_siglist[SIGPOLL] = "Pollable event occurred";
+# endif
+# ifdef SIGPROF
+      sys_siglist[SIGPROF] = "Profiling timer expired";
+# endif
+# ifdef SIGPTY
+      sys_siglist[SIGPTY] = "PTY I/O interrupt";
+# endif
+# ifdef SIGPWR
+      sys_siglist[SIGPWR] = "Power-fail restart";
+# endif
+# ifdef SIGQUIT
+      sys_siglist[SIGQUIT] = "Quit";
+# endif
+# ifdef SIGRETRACT
+      sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
+# endif
+# ifdef SIGSAK
+      sys_siglist[SIGSAK] = "Secure attention";
+# endif
+# ifdef SIGSEGV
+      sys_siglist[SIGSEGV] = "Segmentation violation";
+# endif
+# ifdef SIGSOUND
+      sys_siglist[SIGSOUND] = "Sound completed";
+# endif
+# ifdef SIGSTOP
+      sys_siglist[SIGSTOP] = "Stopped (signal)";
+# endif
+# ifdef SIGSTP
+      sys_siglist[SIGSTP] = "Stopped (user)";
+# endif
+# ifdef SIGSYS
+      sys_siglist[SIGSYS] = "Bad argument to system call";
+# endif
+# ifdef SIGTERM
+      sys_siglist[SIGTERM] = "Terminated";
+# endif
+# ifdef SIGTHAW
+      sys_siglist[SIGTHAW] = "SIGTHAW";
+# endif
+# ifdef SIGTRAP
+      sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
+# endif
+# ifdef SIGTSTP
+      sys_siglist[SIGTSTP] = "Stopped (user)";
+# endif
+# ifdef SIGTTIN
+      sys_siglist[SIGTTIN] = "Stopped (tty input)";
+# endif
+# ifdef SIGTTOU
+      sys_siglist[SIGTTOU] = "Stopped (tty output)";
+# endif
+# ifdef SIGURG
+      sys_siglist[SIGURG] = "Urgent I/O condition";
+# endif
+# ifdef SIGUSR1
+      sys_siglist[SIGUSR1] = "User defined signal 1";
+# endif
+# ifdef SIGUSR2
+      sys_siglist[SIGUSR2] = "User defined signal 2";
+# endif
+# ifdef SIGVTALRM
+      sys_siglist[SIGVTALRM] = "Virtual timer expired";
+# endif
+# ifdef SIGWAITING
+      sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
+# endif
+# ifdef SIGWINCH
+      sys_siglist[SIGWINCH] = "Window size changed";
+# endif
+# ifdef SIGWIND
+      sys_siglist[SIGWIND] = "SIGWIND";
+# endif
+# ifdef SIGXCPU
+      sys_siglist[SIGXCPU] = "CPU time limit exceeded";
+# endif
+# ifdef SIGXFSZ
+      sys_siglist[SIGXFSZ] = "File size limit exceeded";
+# endif
+    }
+
+#endif
+}
+
+#if ! defined (HAVE_STRSIGNAL)
+
+char *
+strsignal (int code)
+{
+  char *signame = "";
+
+  if (0 <= code && code < NSIG)
+    {
+      /* Cast to suppress warning if the table has const char *.  */
+      signame = (char *) sys_siglist[code];
+    }
+
+  return signame;
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; End: ***
+*/
diff --git a/src/siglist.h b/src/siglist.h
new file mode 100644
index 0000000..b926769
--- /dev/null
+++ b/src/siglist.h
@@ -0,0 +1,53 @@
+/*
+
+Copyright (C) 2000, 2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_siglist_h)
+#define octave_siglist_h 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* This is borrowed from Emacs.  */
+
+#if ! defined (HAVE_DECL_SYS_SIGLIST)
+extern char *sys_siglist[];
+#endif
+
+extern void init_signals (void);
+
+#if ! defined (HAVE_STRSIGNAL)
+extern char *strsignal (int);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sparse-xdiv.cc b/src/sparse-xdiv.cc
new file mode 100644
index 0000000..fd94343
--- /dev/null
+++ b/src/sparse-xdiv.cc
@@ -0,0 +1,639 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "Array-util.h"
+#include "oct-cmplx.h"
+#include "quit.h"
+#include "error.h"
+#include "lo-ieee.h"
+
+#include "dSparse.h"
+#include "dDiagMatrix.h"
+#include "CSparse.h"
+#include "CDiagMatrix.h"
+#include "oct-spparms.h"
+#include "sparse-xdiv.h"
+
+static void
+solve_singularity_warning (double rcond)
+{
+  warning ("matrix singular to machine precision, rcond = %g", rcond);
+  warning ("attempting to find minimum norm solution");
+}
+
+template <class T1, class T2>
+bool
+mx_leftdiv_conform (const T1& a, const T2& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type b_nr = b.rows ();
+
+  if (a_nr != b_nr)
+    {
+      octave_idx_type a_nc = a.cols ();
+      octave_idx_type b_nc = b.cols ();
+
+      gripe_nonconformant ("operator \\", a_nr, a_nc, b_nr, b_nc);
+      return false;
+    }
+
+  return true;
+}
+
+#define INSTANTIATE_MX_LEFTDIV_CONFORM(T1, T2) \
+  template bool mx_leftdiv_conform (const T1&, const T2&)
+
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseMatrix, SparseMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseComplexMatrix, SparseMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseComplexMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseMatrix, Matrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseMatrix, ComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseComplexMatrix, Matrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (SparseComplexMatrix, ComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (DiagMatrix, SparseMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (DiagMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexDiagMatrix, SparseMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexDiagMatrix, SparseComplexMatrix);
+
+template <class T1, class T2>
+bool
+mx_div_conform (const T1& a, const T2& b)
+{
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nc)
+    {
+      octave_idx_type a_nr = a.rows ();
+      octave_idx_type b_nr = b.rows ();
+
+      gripe_nonconformant ("operator /", a_nr, a_nc, b_nr, b_nc);
+      return false;
+    }
+
+  return true;
+}
+
+#define INSTANTIATE_MX_DIV_CONFORM(T1, T2) \
+  template bool mx_div_conform (const T1&, const T2&)
+
+INSTANTIATE_MX_DIV_CONFORM (SparseMatrix, SparseMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseComplexMatrix, SparseMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseComplexMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (Matrix, SparseMatrix);
+INSTANTIATE_MX_DIV_CONFORM (Matrix, SparseComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, SparseMatrix);
+INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseMatrix, DiagMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseMatrix, ComplexDiagMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseComplexMatrix, DiagMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseComplexMatrix, ComplexDiagMatrix);
+
+// Right division functions.  X / Y = X * inv(Y) = (inv (Y') * X')'
+//
+//                  Y / X:   m   cm   sm  scm
+//                   +--   +---+----+----+----+
+//   sparse matrix         | 1 |  3 |  5 |  7 |
+//                         +---+----+----+----+
+//   sparse complex_matrix | 2 |  4 |  6 |  8 |
+//                         +---+----+----+----+
+//   diagonal matrix                |  9 | 11 |
+//                                  +----+----+
+//   complex diag. matrix           | 10 | 12 |
+//                                  +----+----+
+
+// -*- 1 -*-
+Matrix
+xdiv (const Matrix& a, const SparseMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return Matrix ();
+
+  Matrix atmp = a.transpose ();
+  SparseMatrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  Matrix result = btmp.solve (btyp, atmp, info, rcond, 
+			      solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.transpose ();
+}
+
+// -*- 2 -*-
+ComplexMatrix
+xdiv (const Matrix& a, const SparseComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return ComplexMatrix ();
+
+  Matrix atmp = a.transpose ();
+  SparseComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  ComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 3 -*-
+ComplexMatrix
+xdiv (const ComplexMatrix& a, const SparseMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return ComplexMatrix ();
+
+  ComplexMatrix atmp = a.hermitian ();
+  SparseMatrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  ComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 4 -*-
+ComplexMatrix
+xdiv (const ComplexMatrix& a, const SparseComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return ComplexMatrix ();
+
+  ComplexMatrix atmp = a.hermitian ();
+  SparseComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  ComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 5 -*-
+SparseMatrix
+xdiv (const SparseMatrix& a, const SparseMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return SparseMatrix ();
+
+  SparseMatrix atmp = a.transpose ();
+  SparseMatrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  SparseMatrix result = btmp.solve (btyp, atmp, info, rcond, 
+				    solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.transpose ();
+}
+
+// -*- 6 -*-
+SparseComplexMatrix
+xdiv (const SparseMatrix& a, const SparseComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return SparseComplexMatrix ();
+
+  SparseMatrix atmp = a.transpose ();
+  SparseComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  SparseComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 7 -*-
+SparseComplexMatrix
+xdiv (const SparseComplexMatrix& a, const SparseMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return SparseComplexMatrix ();
+
+  SparseComplexMatrix atmp = a.hermitian ();
+  SparseMatrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  SparseComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 8 -*-
+SparseComplexMatrix
+xdiv (const SparseComplexMatrix& a, const SparseComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return SparseComplexMatrix ();
+
+  SparseComplexMatrix atmp = a.hermitian ();
+  SparseComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  SparseComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+template <typename RT, typename SM, typename DM>
+RT do_rightdiv_sm_dm (const SM& a, const DM& d)
+{
+  const octave_idx_type d_nr = d.rows ();
+
+  const octave_idx_type a_nr = a.rows ();
+  const octave_idx_type a_nc = a.cols ();
+
+  using std::min;
+  const octave_idx_type nc = min (d_nr, a_nc);
+
+  if ( ! mx_div_conform (a, d))
+    return RT ();
+
+  const octave_idx_type nz = a.nnz ();
+  RT r (a_nr, nc, nz);
+
+  typedef typename DM::element_type DM_elt_type;
+  const DM_elt_type zero = DM_elt_type ();
+
+  octave_idx_type k_result = 0;
+  for (octave_idx_type j = 0; j < nc; ++j)
+    {
+      OCTAVE_QUIT;
+      const DM_elt_type s = d.dgelem (j);
+      const octave_idx_type colend = a.cidx (j+1);
+      r.xcidx (j) = k_result;
+      if (s != zero)
+	for (octave_idx_type k = a.cidx (j); k < colend; ++k)
+	  {
+	    r.xdata (k_result) = a.data (k) / s;
+	    r.xridx (k_result) = a.ridx (k);
+	    ++k_result;
+	  }
+    }
+  r.xcidx (nc) = k_result;
+
+  r.maybe_compress (true);
+  return r;
+}
+
+// -*- 9 -*-
+SparseMatrix
+xdiv (const SparseMatrix& a, const DiagMatrix& b, MatrixType &)
+{
+  return do_rightdiv_sm_dm<SparseMatrix> (a, b);
+}
+
+// -*- 10 -*-
+SparseComplexMatrix
+xdiv (const SparseMatrix& a, const ComplexDiagMatrix& b, MatrixType &)
+{
+  return do_rightdiv_sm_dm<SparseComplexMatrix> (a, b);
+}
+
+// -*- 11 -*-
+SparseComplexMatrix
+xdiv (const SparseComplexMatrix& a, const DiagMatrix& b, MatrixType &)
+{
+  return do_rightdiv_sm_dm<SparseComplexMatrix> (a, b);
+}
+
+// -*- 12 -*-
+SparseComplexMatrix
+xdiv (const SparseComplexMatrix& a, const ComplexDiagMatrix& b, MatrixType &)
+{
+  return do_rightdiv_sm_dm<SparseComplexMatrix> (a, b);
+}
+
+// Funny element by element division operations.
+//
+//       op2 \ op1:   s   cs
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+Matrix
+x_el_div (double a, const SparseMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  Matrix result;
+  if (a == 0.)
+    result = Matrix (nr, nc, octave_NaN);
+  else if (a > 0.)
+    result = Matrix (nr, nc, octave_Inf);
+  else
+    result = Matrix (nr, nc, -octave_Inf);
+
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+      {
+	OCTAVE_QUIT;
+	result.elem (b.ridx(i), j) = a / b.data (i);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+x_el_div (double a, const SparseComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix  result (nr, nc, Complex(octave_NaN, octave_NaN));
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+      {
+	OCTAVE_QUIT;
+	result.elem (b.ridx(i), j) = a / b.data (i);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+x_el_div (const Complex a, const SparseMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc, (a / 0.0));
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+      {
+	OCTAVE_QUIT;
+	result.elem (b.ridx(i), j) = a / b.data (i);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+x_el_div (const Complex a, const SparseComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc, (a / 0.0));
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++)
+      {
+	OCTAVE_QUIT;
+	result.elem (b.ridx(i), j) = a / b.data (i);
+      }
+
+  return result;
+}
+
+// Left division functions.  X \ Y = inv(X) * Y
+//
+//               Y  \  X :   sm  scm  dm  dcm
+//                   +--   +---+----+
+//   matrix                | 1 |  5 |
+//                         +---+----+
+//   complex_matrix        | 2 |  6 |
+//                         +---+----+----+----+
+//   sparse matrix         | 3 |  7 |  9 | 11 |
+//                         +---+----+----+----+
+//   sparse complex_matrix | 4 |  8 | 10 | 12 |
+//                         +---+----+----+----+
+
+// -*- 1 -*-
+Matrix
+xleftdiv (const SparseMatrix& a, const Matrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return Matrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 2 -*-
+ComplexMatrix
+xleftdiv (const SparseMatrix& a, const ComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return ComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 3 -*-
+SparseMatrix
+xleftdiv (const SparseMatrix& a, const SparseMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return SparseMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 4 -*-
+SparseComplexMatrix
+xleftdiv (const SparseMatrix& a, const SparseComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return SparseComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 5 -*-
+ComplexMatrix
+xleftdiv (const SparseComplexMatrix& a, const Matrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return ComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 6 -*-
+ComplexMatrix
+xleftdiv (const SparseComplexMatrix& a, const ComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return ComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 7 -*-
+SparseComplexMatrix
+xleftdiv (const SparseComplexMatrix& a, const SparseMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return SparseComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 8 -*-
+SparseComplexMatrix
+xleftdiv (const SparseComplexMatrix& a, const SparseComplexMatrix& b, 
+	  MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return SparseComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+template <typename RT, typename DM, typename SM>
+RT do_leftdiv_dm_sm (const DM& d, const SM& a)
+{
+  const octave_idx_type a_nr = a.rows ();
+  const octave_idx_type a_nc = a.cols ();
+
+  const octave_idx_type d_nc = d.cols ();
+
+  using std::min;
+  const octave_idx_type nr = min (d_nc, a_nr);
+
+  if ( ! mx_leftdiv_conform (d, a))
+    return RT ();
+
+  const octave_idx_type nz = a.nnz ();
+  RT r (nr, a_nc, nz);
+
+  typedef typename DM::element_type DM_elt_type;
+  const DM_elt_type zero = DM_elt_type ();
+
+  octave_idx_type k_result = 0;
+  for (octave_idx_type j = 0; j < a_nc; ++j)
+    {
+      OCTAVE_QUIT;
+      const octave_idx_type colend = a.cidx (j+1);
+      r.xcidx (j) = k_result;
+      for (octave_idx_type k = a.cidx (j); k < colend; ++k)
+	{
+	  const octave_idx_type i = a.ridx (k);
+	  if (i < nr)
+	    {
+	      const DM_elt_type s = d.dgelem (i);
+	      if (s != zero)
+		{
+		  r.xdata (k_result) = a.data (k) / s;
+		  r.xridx (k_result) = i;
+		  ++k_result;
+		}
+	    }
+	}
+    }
+  r.xcidx (a_nc) = k_result;
+
+  r.maybe_compress (true);
+  return r;
+}
+
+// -*- 9 -*-
+SparseMatrix
+xleftdiv (const DiagMatrix& d, const SparseMatrix& a,  MatrixType&)
+{
+  return do_leftdiv_dm_sm<SparseMatrix> (d, a);
+}
+
+// -*- 10 -*-
+SparseComplexMatrix
+xleftdiv (const DiagMatrix& d, const SparseComplexMatrix& a,  MatrixType&)
+{
+  return do_leftdiv_dm_sm<SparseComplexMatrix> (d, a);
+}
+
+// -*- 11 -*-
+SparseComplexMatrix
+xleftdiv (const ComplexDiagMatrix& d, const SparseMatrix& a,  MatrixType&)
+{
+  return do_leftdiv_dm_sm<SparseComplexMatrix> (d, a);
+}
+
+// -*- 12 -*-
+SparseComplexMatrix
+xleftdiv (const ComplexDiagMatrix& d, const SparseComplexMatrix& a,  MatrixType&)
+{
+  return do_leftdiv_dm_sm<SparseComplexMatrix> (d, a);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sparse-xdiv.h b/src/sparse-xdiv.h
new file mode 100644
index 0000000..183a9fb
--- /dev/null
+++ b/src/sparse-xdiv.h
@@ -0,0 +1,99 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007, 2009 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_xdiv_h)
+#define octave_sparse_xdiv_h 1
+
+#include "oct-cmplx.h"
+#include "MatrixType.h"
+
+class DiagMatrix;
+class ComplexDiagMatrix;
+class SparseMatrix;
+class SparseComplexMatrix;
+
+extern Matrix xdiv (const Matrix& a, const SparseMatrix& b, MatrixType &typ);
+extern ComplexMatrix xdiv (const Matrix& a, const SparseComplexMatrix& b,
+			   MatrixType &typ);
+extern ComplexMatrix xdiv (const ComplexMatrix& a, const SparseMatrix& b,
+			   MatrixType &typ);
+extern ComplexMatrix xdiv (const ComplexMatrix& a, 
+			   const SparseComplexMatrix& b, MatrixType &typ);
+
+extern SparseMatrix xdiv (const SparseMatrix& a, const SparseMatrix& b,
+			  MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseMatrix& a, 
+				 const SparseComplexMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a, 
+				 const SparseMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a, 
+				 const SparseComplexMatrix& b, MatrixType &typ);
+
+extern SparseMatrix xdiv (const SparseMatrix& a, 
+			  const DiagMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseMatrix& a, 
+				 const ComplexDiagMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a, 
+				 const DiagMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a, 
+				 const ComplexDiagMatrix& b, MatrixType &typ);
+
+extern Matrix x_el_div (double a, const SparseMatrix& b);
+extern ComplexMatrix x_el_div (double a, const SparseComplexMatrix& b);
+extern ComplexMatrix x_el_div (const Complex a, const SparseMatrix& b);
+extern ComplexMatrix x_el_div (const Complex a, 
+			       const SparseComplexMatrix& b);
+
+extern Matrix xleftdiv (const SparseMatrix& a, const Matrix& b, 
+			MatrixType& typ);
+extern ComplexMatrix xleftdiv (const SparseMatrix& a, const ComplexMatrix& b,
+			       MatrixType &typ);
+extern ComplexMatrix xleftdiv (const SparseComplexMatrix& a, const Matrix& b,
+			       MatrixType &typ);
+extern ComplexMatrix xleftdiv (const SparseComplexMatrix& a, 
+			       const ComplexMatrix& b, MatrixType &typ);
+
+extern SparseMatrix xleftdiv (const SparseMatrix& a, const SparseMatrix& b,
+			      MatrixType &typ);
+extern SparseComplexMatrix xleftdiv (const SparseMatrix& a, 
+				     const SparseComplexMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xleftdiv (const SparseComplexMatrix& a, 
+				     const SparseMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xleftdiv (const SparseComplexMatrix& a, 
+				     const SparseComplexMatrix& b, MatrixType &typ);
+
+extern SparseMatrix xleftdiv (const DiagMatrix&, const SparseMatrix&, MatrixType&);
+extern SparseComplexMatrix xleftdiv (const ComplexDiagMatrix&, const SparseMatrix&, 
+				     MatrixType&);
+extern SparseComplexMatrix xleftdiv (const DiagMatrix&, const SparseComplexMatrix&, 
+				     MatrixType&);
+extern SparseComplexMatrix xleftdiv (const ComplexDiagMatrix&, const SparseComplexMatrix&, 
+				     MatrixType&);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sparse-xpow.cc b/src/sparse-xpow.cc
new file mode 100644
index 0000000..8acc475
--- /dev/null
+++ b/src/sparse-xpow.cc
@@ -0,0 +1,736 @@
+/*
+
+Copyright (C) 2004, 2005, 2006, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <climits>
+
+#include "Array-util.h"
+#include "oct-cmplx.h"
+#include "quit.h"
+
+#include "error.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#include "dSparse.h"
+#include "CSparse.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "sparse-xpow.h"
+
+static inline int
+xisint (double x)
+{
+  return (D_NINT (x) == x
+	  && ((x >= 0 && x < INT_MAX)
+	      || (x <= 0 && x > INT_MIN)));
+}
+
+
+// Safer pow functions. Only two make sense for sparse matrices, the
+// others should all promote to full matrices.
+
+octave_value
+xpow (const SparseMatrix& a, double b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+	  int btmp = static_cast<int> (b);
+	  if (btmp == 0)
+	    {
+	      SparseMatrix tmp = SparseMatrix (nr, nr, nr);
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  tmp.data (i) = 1.0;
+		  tmp.ridx (i) = i;
+		}
+	      for (octave_idx_type i = 0; i < nr + 1; i++)
+		tmp.cidx (i) = i;
+
+	      retval = tmp;
+	    }
+	  else
+	    {
+	      SparseMatrix atmp;
+	      if (btmp < 0)
+		{
+		  btmp = -btmp;
+
+		  octave_idx_type info;
+		  double rcond = 0.0;
+		  MatrixType mattyp (a);
+
+		  atmp = a.inverse (mattyp, info, rcond, 1);
+
+		  if (info == -1)
+		    warning ("inverse: matrix singular to machine\
+ precision, rcond = %g", rcond);
+		}
+	      else
+		atmp = a;
+
+	      SparseMatrix result (atmp);
+
+	      btmp--;
+
+	      while (btmp > 0)
+		{
+		  if (btmp & 1)
+		    result = result * atmp;
+
+		  btmp >>= 1;
+
+		  if (btmp > 0)
+		    atmp = atmp * atmp;
+		}
+
+	      retval = result;
+	    }
+	}
+      else
+	error ("use full(a) ^ full(b)");
+    }
+
+  return retval;
+}
+
+octave_value
+xpow (const SparseComplexMatrix& a, double b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+	  int btmp = static_cast<int> (b);
+	  if (btmp == 0)
+	    {
+	      SparseMatrix tmp = SparseMatrix (nr, nr, nr);
+	      for (octave_idx_type i = 0; i < nr; i++)
+		{
+		  tmp.data (i) = 1.0;
+		  tmp.ridx (i) = i;
+		}
+	      for (octave_idx_type i = 0; i < nr + 1; i++)
+		tmp.cidx (i) = i;
+
+	      retval = tmp;
+	    }
+	  else
+	    {
+	      SparseComplexMatrix atmp;
+	      if (btmp < 0)
+		{
+		  btmp = -btmp;
+
+		  octave_idx_type info;
+		  double rcond = 0.0;
+		  MatrixType mattyp (a);
+
+		  atmp = a.inverse (mattyp, info, rcond, 1);
+
+		  if (info == -1)
+		    warning ("inverse: matrix singular to machine\
+ precision, rcond = %g", rcond);
+		}
+	      else
+		atmp = a;
+
+	      SparseComplexMatrix result (atmp);
+
+	      btmp--;
+
+	      while (btmp > 0)
+		{
+		  if (btmp & 1)
+		    result = result * atmp;
+
+		  btmp >>= 1;
+
+		  if (btmp > 0)
+		    atmp = atmp * atmp;
+		}
+
+	      retval = result;
+	    }
+	}
+      else
+	error ("use full(a) ^ full(b)");
+    }
+
+  return retval;
+}
+
+// Safer pow functions that work elementwise for matrices.
+//
+//       op2 \ op1:   s   m   cs   cm
+//            +--   +---+---+----+----+
+//   scalar   |     | * | 3 |  * |  9 |
+//                  +---+---+----+----+
+//   matrix         | 1 | 4 |  7 | 10 |
+//                  +---+---+----+----+
+//   complex_scalar | * | 5 |  * | 11 |
+//                  +---+---+----+----+
+//   complex_matrix | 2 | 6 |  8 | 12 |
+//                  +---+---+----+----+
+//
+//   * -> not needed.
+
+// FIXME -- these functions need to be fixed so that things
+// like
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
+//
+// and
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
+//
+// produce identical results.  Also, it would be nice if -1^0.5
+// produced a pure imaginary result instead of a complex number with a
+// small real part.  But perhaps that's really a problem with the math
+// library...
+
+// -*- 1 -*-
+octave_value
+elem_xpow (double a, const SparseMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  double d1, d2;
+
+  if (a < 0.0 && ! b.all_integers (d1, d2))
+    {
+      Complex atmp (a);
+      ComplexMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = std::pow (atmp, b(i,j));
+	    }
+	}
+
+      retval = result;
+    }
+  else
+    {
+      Matrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result (i, j) = std::pow (a, b(i,j));
+	    }
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+elem_xpow (double a, const SparseComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  Complex atmp (a);
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  result (i, j) = std::pow (atmp, b(i,j));
+	}
+    }
+
+  return result;
+}
+
+// -*- 3 -*-
+octave_value
+elem_xpow (const SparseMatrix& a, double b)
+{
+  // FIXME What should a .^ 0 give?? Matlab gives a 
+  // sparse matrix with same structure as a, which is strictly
+  // incorrect. Keep compatiability.
+
+  octave_value retval;
+
+  octave_idx_type nz = a.nzmax ();
+
+  if (b <= 0.0)
+    {
+      octave_idx_type nr = a.rows ();
+      octave_idx_type nc = a.cols ();
+
+      if (static_cast<int> (b) != b && a.any_element_is_negative ())
+	{
+	  ComplexMatrix result (nr, nc, Complex (std::pow (0.0, b)));
+
+	  // FIXME -- avoid apparent GNU libm bug by
+	  // converting A and B to complex instead of just A.
+	  Complex btmp (b);
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	      {
+		OCTAVE_QUIT;
+	      
+		Complex atmp (a.data (i));
+		
+		result (a.ridx(i), j) = std::pow (atmp, btmp);
+	      }
+
+	  retval = octave_value (result);
+	}
+      else
+	{
+	  Matrix result (nr, nc, (std::pow (0.0, b)));
+
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	      {
+		OCTAVE_QUIT;
+		result (a.ridx(i), j) = std::pow (a.data (i), b);
+	      }
+
+	  retval = octave_value (result);
+	}
+    }
+  else if (static_cast<int> (b) != b && a.any_element_is_negative ())
+    {
+      SparseComplexMatrix result (a);
+
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  OCTAVE_QUIT;
+
+	  // FIXME -- avoid apparent GNU libm bug by
+	  // converting A and B to complex instead of just A.
+
+	  Complex atmp (a.data (i));
+	  Complex btmp (b);
+
+	  result.data (i) = std::pow (atmp, btmp);
+	}
+
+      result.maybe_compress (true);
+
+      retval = result;
+    }
+  else
+    {
+      SparseMatrix result (a);
+
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  OCTAVE_QUIT;
+	  result.data (i) = std::pow (a.data (i), b);
+	}
+
+      result.maybe_compress (true);
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 4 -*-
+octave_value
+elem_xpow (const SparseMatrix& a, const SparseMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  int convert_to_complex = 0;
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+      {
+	if (a.data(i) < 0.0)
+	  {
+	    double btmp = b (a.ridx(i), j);
+	    if (static_cast<int> (btmp) != btmp)
+	      {
+		convert_to_complex = 1;
+		goto done;
+	      }
+	  }
+      }
+
+done:
+
+  // This is a dumb operator for sparse matrices anyway, and there is
+  // no sensible way to handle the 0.^0 versus the 0.^x cases. Therefore
+  // allocate a full matrix filled for the 0.^0 case and shrink it later
+  // as needed
+
+  if (convert_to_complex)
+    {
+      SparseComplexMatrix complex_result (nr, nc, Complex(1.0, 0.0));
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	    {
+	      OCTAVE_QUIT;
+	      complex_result.xelem(a.ridx(i), j) =
+		std::pow (Complex(a.data(i)), Complex(b(a.ridx(i), j)));
+	    }
+	}
+      complex_result.maybe_compress (true);
+      retval = complex_result;
+    }
+  else
+    {
+      SparseMatrix result (nr, nc, 1.0);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	{
+	  for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	    {
+	      OCTAVE_QUIT;
+	      result.xelem(a.ridx(i), j) = std::pow (a.data(i), 
+						     b (a.ridx(i), j));
+	    }
+	}
+      result.maybe_compress (true);
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+elem_xpow (const SparseMatrix& a, const Complex& b)
+{
+  octave_value retval;
+
+  if (b == 0.0)
+    // Can this case ever happen, due to automatic retyping with maybe_mutate?
+    retval = octave_value (NDArray (a.dims (), 1));
+  else
+    {
+      octave_idx_type nz = a.nzmax ();
+      SparseComplexMatrix result (a);
+      
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  OCTAVE_QUIT;
+	  result.data (i) = std::pow (Complex (a.data (i)), b);
+	}
+  
+      result.maybe_compress (true);
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 6 -*-
+octave_value
+elem_xpow (const SparseMatrix& a, const SparseComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  SparseComplexMatrix result (nr, nc, Complex(1.0, 0.0));
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	{
+	  OCTAVE_QUIT;
+	  result.xelem(a.ridx(i), j) = std::pow (a.data(i), b (a.ridx(i), j));
+	}
+    }
+
+  result.maybe_compress (true);
+
+  return result;
+}
+
+// -*- 7 -*-
+octave_value
+elem_xpow (const Complex& a, const SparseMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = 0; i < nr; i++)
+	{
+	  OCTAVE_QUIT;
+	  double btmp = b (i, j);
+	  if (xisint (btmp))
+	    result (i, j) = std::pow (a, static_cast<int> (btmp));
+	  else
+	    result (i, j) = std::pow (a, btmp);
+	}
+    }
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+elem_xpow (const Complex& a, const SparseComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc);
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a, b (i, j));
+      }
+
+  return result;
+}
+
+// -*- 9 -*-
+octave_value
+elem_xpow (const SparseComplexMatrix& a, double b)
+{
+  octave_value retval;
+
+  if (b <= 0)
+    {
+      octave_idx_type nr = a.rows ();
+      octave_idx_type nc = a.cols ();
+
+      ComplexMatrix result (nr, nc, Complex (std::pow (0.0, b)));
+
+      if (xisint (b))
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	      {
+		OCTAVE_QUIT;
+		result (a.ridx(i), j) = 
+		  std::pow (a.data (i), static_cast<int> (b));
+	      }
+	}
+      else
+	{
+	  for (octave_idx_type j = 0; j < nc; j++)
+	    for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	      {
+		OCTAVE_QUIT;
+		result (a.ridx(i), j) = std::pow (a.data (i), b);
+	      }
+	}  
+
+      retval = result;
+    }
+  else
+    {
+      octave_idx_type nz = a.nzmax ();
+
+      SparseComplexMatrix result (a);
+  
+      if (xisint (b))
+	{
+	  for (octave_idx_type i = 0; i < nz; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result.data (i) = std::pow (a.data (i), static_cast<int> (b));
+	    }
+	}
+      else
+	{
+	  for (octave_idx_type i = 0; i < nz; i++)
+	    {
+	      OCTAVE_QUIT;
+	      result.data (i) = std::pow (a.data (i), b);
+	    }
+	}  
+
+      result.maybe_compress (true);
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 10 -*-
+octave_value
+elem_xpow (const SparseComplexMatrix& a, const SparseMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  SparseComplexMatrix result (nr, nc, Complex(1.0, 0.0));
+  for (octave_idx_type j = 0; j < nc; j++)
+    {
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	{
+	  OCTAVE_QUIT;
+	  double btmp = b (a.ridx(i), j);
+	  Complex tmp;
+
+	  if (xisint (btmp))
+	    result.xelem(a.ridx(i), j) = std::pow (a.data (i), 
+					      static_cast<int> (btmp));
+	  else
+	    result.xelem(a.ridx(i), j) = std::pow (a.data (i), btmp);
+	}
+    }
+
+  result.maybe_compress (true);
+
+  return result;
+}
+
+// -*- 11 -*-
+octave_value
+elem_xpow (const SparseComplexMatrix& a, const Complex& b)
+{
+  octave_value retval;
+
+  if (b == 0.0)
+    // Can this case ever happen, due to automatic retyping with maybe_mutate?
+    retval = octave_value (NDArray (a.dims (), 1));
+  else
+    {
+
+      octave_idx_type nz = a.nzmax ();
+
+      SparseComplexMatrix result (a);
+
+      for (octave_idx_type i = 0; i < nz; i++)
+	{
+	  OCTAVE_QUIT;
+	  result.data (i) = std::pow (a.data (i), b);
+	}
+
+      result.maybe_compress (true);
+      
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 12 -*-
+octave_value
+elem_xpow (const SparseComplexMatrix& a, const SparseComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  SparseComplexMatrix result (nr, nc, Complex(1.0, 0.0));
+  for (octave_idx_type j = 0; j < nc; j++) 
+    {
+      for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
+	{
+	  OCTAVE_QUIT;
+	  result.xelem(a.ridx(i), j) = std::pow (a.data (i), b (a.ridx(i), j));
+	}
+    }
+  result.maybe_compress (true);
+
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sparse-xpow.h b/src/sparse-xpow.h
new file mode 100644
index 0000000..2e07d75
--- /dev/null
+++ b/src/sparse-xpow.h
@@ -0,0 +1,63 @@
+/*
+
+Copyright (C) 2004, 2005, 2007 David Bateman
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sparse_xpow_h)
+#define octave_sparse_xpow_h 1
+
+#include "oct-cmplx.h"
+
+class SparseMatrix;
+class SparseComplexMatrix;
+class octave_value;
+
+extern octave_value xpow (const SparseMatrix& a, double b);
+extern octave_value xpow (const SparseComplexMatrix& a, double b);
+
+extern octave_value elem_xpow (double a, const SparseMatrix& b);
+extern octave_value elem_xpow (double a, const SparseComplexMatrix& b);
+
+extern octave_value elem_xpow (const SparseMatrix& a, double b);
+extern octave_value elem_xpow (const SparseMatrix& a, const SparseMatrix& b);
+extern octave_value elem_xpow (const SparseMatrix& a, const Complex& b);
+extern octave_value elem_xpow (const SparseMatrix& a, 
+			       const SparseComplexMatrix& b);
+
+extern octave_value elem_xpow (const Complex& a, const SparseMatrix& b);
+extern octave_value elem_xpow (const Complex& a, 
+			       const SparseComplexMatrix& b);
+
+extern octave_value elem_xpow (const SparseComplexMatrix& a, double b);
+extern octave_value elem_xpow (const SparseComplexMatrix& a, 
+			       const SparseMatrix& b);
+extern octave_value elem_xpow (const SparseComplexMatrix& a, 
+			       const Complex& b);
+extern octave_value elem_xpow (const SparseComplexMatrix& a, 
+			       const SparseComplexMatrix& b);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/strfns.cc b/src/strfns.cc
new file mode 100644
index 0000000..febd789
--- /dev/null
+++ b/src/strfns.cc
@@ -0,0 +1,989 @@
+/*
+
+Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <queue>
+#include <sstream>
+
+#include "dMatrix.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "ov.h"
+#include "oct-obj.h"
+#include "unwind-prot.h"
+#include "utils.h"
+
+DEFUN (char, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} char (@var{x})\n\
+ at deftypefnx {Built-in Function} {} char (@var{x}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} char (@var{s1}, @var{s2}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} char (@var{cell_array})\n\
+Create a string array from one or more numeric matrices, character\n\
+matrices, or cell arrays.  Arguments are concatenated vertically.\n\
+The returned values are padded with blanks as needed to make each row\n\
+of the string array have the same length.  Empty input strings are\n\
+significant and will concatenated in the output.\n\
+\n\
+For numerical input, each element is converted\n\
+to the corresponding ASCII character.  A range error results if an input\n\
+is outside the ASCII range (0-255).\n\
+\n\
+For cell arrays, each element is concatenated separately.  Cell arrays converted through\n\
+ at code{char} can mostly be converted back with @code{cellstr}.\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+char ([97, 98, 99], \"\", @{\"98\", \"99\", 100@}, \"str1\", [\"ha\", \"lf\"])\n\
+     @result{} [\"abc    \"\n\
+         \"       \"\n\
+         \"98     \"\n\
+         \"99     \"\n\
+         \"d      \"\n\
+         \"str1   \"\n\
+         \"half   \"]\n\
+ at end group\n\
+ at end example\n\
+ at seealso{strvcat, cellstr}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    retval = args(0).convert_to_str (true, true,
+				     args(0).is_dq_string () ? '"' : '\'');
+  else if (nargin > 1)
+    {
+      int n_elts = 0;
+
+      int max_len = 0;
+
+      std::queue<string_vector> args_as_strings;
+
+      for (int i = 0; i < nargin; i++)
+	{
+	  string_vector s = args(i).all_strings ();
+
+	  if (error_state)
+	    {
+	      error ("char: unable to convert some args to strings");
+	      return retval;
+	    }
+
+	  if (s.length () > 0)
+            n_elts += s.length ();
+          else
+            n_elts += 1;
+
+	  int s_max_len = s.max_length ();
+
+	  if (s_max_len > max_len)
+	    max_len = s_max_len;
+
+	  args_as_strings.push (s);
+	}
+
+      string_vector result (n_elts);
+
+      int k = 0;
+
+      for (int i = 0; i < nargin; i++)
+	{
+	  string_vector s = args_as_strings.front ();
+	  args_as_strings.pop ();
+
+	  int n = s.length ();
+
+          if (n > 0)
+            {
+	      for (int j = 0; j < n; j++)
+	        {
+	          std::string t = s[j];
+	          int t_len = t.length ();
+
+	          if (max_len > t_len)
+		    t += std::string (max_len - t_len, ' ');
+
+	          result[k++] = t;
+	        }
+            }
+          else
+	    result[k++] = std::string (max_len, ' ');
+	}
+
+      retval = octave_value (result, '\'');
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!error <Invalid call to char> char()
+%!assert (char (100) == "d");
+%!assert (all(char (100,100) == ["d";"d"]));
+%!assert (all(char ({100,100}) == ["d";"d"]));
+%!assert (all(char ([100,100]) == ["dd"]));
+%!assert (all(char ({100,{100}}) == ["d";"d"]));
+%!assert (all(char (100, [], 100) == ["d";" ";"d"]))
+%!assert (all(char ({100, [], 100}) == ["d";" ";"d"]))
+%!assert (all(char ({100,{100, {""}}}) == ["d";"d";" "]))
+%!assert (all(char (["a";"be"], {"c", 100}) == ["a";"be";"c";"d"]))
+%!assert(strcmp (char ("a", "bb", "ccc"), ["a  "; "bb "; "ccc"]));
+*/
+
+DEFUN (strvcat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {} strvcat (@var{x})\n\
+ at deftypefnx {Built-in Function} {} strvcat (@var{x}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} strvcat (@var{s1}, @var{s2}, @dots{})\n\
+ at deftypefnx {Built-in Function} {} strvcat (@var{cell_array})\n\
+Create a character array from one or more numeric matrices, character\n\
+matrices, or cell arrays.  Arguments are concatenated vertically.\n\
+The returned values are padded with blanks as needed to make each row\n\
+of the string array have the same length.  Unlike @code{char}, empty\n\
+strings are removed and will not appear in the output.\n\
+\n\
+For numerical input, each element is converted\n\
+to the corresponding ASCII character.  A range error results if an input\n\
+is outside the ASCII range (0-255).\n\
+\n\
+For cell arrays, each element is concatenated separately.  Cell arrays converted through\n\
+ at code{strvcat} can mostly be converted back with @code{cellstr}.\n\
+For example,\n\
+\n\
+ at example\n\
+ at group\n\
+strvcat ([97, 98, 99], \"\", @{\"98\", \"99\", 100@}, \"str1\", [\"ha\", \"lf\"])\n\
+     @result{} [\"abc    \"\n\
+         \"98     \"\n\
+         \"99     \"\n\
+         \"d      \"\n\
+         \"str1   \"\n\
+         \"half   \"]\n\
+ at end group\n\
+ at end example\n\
+ at seealso{char, strcat, cstrcat}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      int n_elts = 0;
+
+      size_t max_len = 0;
+
+      std::queue<string_vector> args_as_strings;
+
+      for (int i = 0; i < nargin; i++)
+	{
+	  string_vector s = args(i).all_strings ();
+
+	  if (error_state)
+	    {
+	      error ("strvcat: unable to convert some args to strings");
+	      return retval;
+	    }
+
+          size_t n = s.length ();
+
+          // do not count empty strings in calculation of number of elements
+          if (n > 0)
+            {
+              for (size_t j = 0; j < n; j++)
+                {
+                  if (s[j].length () > 0)
+                    n_elts++;
+                }
+            }
+
+	  size_t s_max_len = s.max_length ();
+
+	  if (s_max_len > max_len)
+	    max_len = s_max_len;
+
+	  args_as_strings.push (s);
+	}
+
+      string_vector result (n_elts);
+
+      octave_idx_type k = 0;
+
+      for (int i = 0; i < nargin; i++)
+	{
+	  string_vector s = args_as_strings.front ();
+	  args_as_strings.pop ();
+
+	  size_t n = s.length ();
+
+          if (n > 0)
+            {
+	      for (size_t j = 0; j < n; j++)
+	        {
+	          std::string t = s[j];
+                  if (t.length () > 0)
+                    {
+                      size_t t_len = t.length ();
+
+                      if (max_len > t_len)
+                        t += std::string (max_len - t_len, ' ');
+
+                      result[k++] = t;
+                    }
+	        }
+            }
+	}
+
+      retval = octave_value (result, '\'');
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!error <Invalid call to strvcat> strvcat()
+%!assert (strvcat (""), "");
+%!assert (strvcat (100) == "d");
+%!assert (all(strvcat (100,100) == ["d";"d"]));
+%!assert (all(strvcat ({100,100}) == ["d";"d"]));
+%!assert (all(strvcat ([100,100]) == ["dd"]));
+%!assert (all(strvcat ({100,{100}}) == ["d";"d"]));
+%!assert (all(strvcat (100, [], 100) == ["d";"d"]))
+%!assert (all(strvcat ({100, [], 100}) == ["d";"d"]))
+%!assert (all(strvcat ({100,{100, {""}}}) == ["d";"d"]))
+%!assert (all(strvcat (["a";"be"], {"c", 100}) == ["a";"be";"c";"d"]))
+%!assert(strcmp (strvcat ("a", "bb", "ccc"), ["a  "; "bb "; "ccc"]));
+*/
+
+
+DEFUN (ischar, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} ischar (@var{a})\n\
+Return 1 if @var{a} is a character array.  Otherwise, return 0.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 && args(0).is_defined ())
+    retval = args(0).is_string ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert (ischar ("a"), logical (1));
+%!assert (ischar (["ab";"cd"]), logical (1));
+%!assert (ischar ({"ab"}), logical (0));
+%!assert (ischar (1), logical (0));
+%!error <Invalid call to ischar.*> ischar ();
+
+ */
+
+DEFUN (strcmp, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} strcmp (@var{s1}, @var{s2})\n\
+Return 1 if the character strings @var{s1} and @var{s2} are the same,\n\
+and 0 otherwise.\n\
+\n\
+If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\
+of the same size is returned, containing the values described above for\n\
+every member of the cell array.  The other argument may also be a cell\n\
+array of strings (of the same size or with only one element), char matrix\n\
+or character string.\n\
+\n\
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmp\n\
+function returns 1 if the character strings are equal, and 0 otherwise.\n\
+This is just the opposite of the corresponding C library function.\n\
+ at seealso{strcmpi, strncmp, strncmpi}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      bool s1_string = args(0).is_string ();
+      bool s1_cell = args(0).is_cell ();
+      bool s2_string = args(1).is_string ();
+      bool s2_cell = args(1).is_cell ();
+
+      if (s1_string && s2_string)
+	{
+	  // Must match exactly in all dimensions.
+
+	  const dim_vector dv1 = args(0).dims ();
+	  const dim_vector dv2 = args(1).dims ();
+
+	  if (dv1.length () == dv2.length ())
+	    {
+	      for (octave_idx_type i = 0; i < dv1.length (); i++)
+		{
+		  if (dv1(i) != dv2(i))
+		    {
+		      retval = false;
+		      return retval;
+		    }
+		}
+
+	      if (dv1(0) == 0)
+		retval = true;
+	      else
+		{
+		  const charNDArray s1 = args(0).char_array_value ();
+		  const charNDArray s2 = args(1).char_array_value ();
+
+		  for (octave_idx_type i = 0; i < dv1.numel (); i++)
+		    {
+		      if (s1(i) != s2(i))
+			{
+			  retval = false;
+			  return retval;
+			}
+		    }
+
+		  retval = true;
+		}
+	    }
+	}
+      else if ((s1_string && s2_cell) || (s1_cell && s2_string))
+	{
+          octave_value str_val, cell_val;
+
+	  if (s1_string)
+	    {
+	      str_val = args (0);
+              cell_val = args (1);
+	    }
+	  else
+	    {
+	      str_val = args (1);
+              cell_val = args (0);
+	    }
+
+          const Cell cell = cell_val.cell_value ();
+	  const string_vector str = str_val.all_strings ();
+	  octave_idx_type r = str.rows ();
+
+	  if (r == 0 || r == 1)
+	    {
+	      // Broadcast the string.
+
+	      boolNDArray output (cell_val.dims (), false);
+
+	      std::string s = r == 0 ? std::string () : str[0];
+
+              if (cell_val.is_cellstr ())
+                {
+                  const Array<std::string> cellstr = cell_val.cellstr_value ();
+                  for (octave_idx_type i = 0; i < cellstr.length (); i++)
+                    output(i) = cellstr(i) == s;
+                }
+              else
+                {
+                  // FIXME: should we warn here?
+                  for (octave_idx_type i = 0; i < cell.length (); i++)
+                    {
+                      if (cell(i).is_string ())
+                        output(i) = (cell(i).string_value () == s);
+                    }
+                }
+
+	      retval = output;
+	    }
+	  else if (r > 1)
+	    {
+	      if (cell.length () == 1)
+		{
+		  // Broadcast the cell.
+
+		  const dim_vector dv (r, 1);
+		  boolNDArray output (dv, false);
+
+		  if (cell(0).is_string ())
+		    {
+		      const std::string str2 = cell(0).string_value ();
+
+		      for (octave_idx_type i = 0; i < r; i++)
+			output(i) = (str[i] == str2);
+		    }
+
+		  retval = output;
+		}
+	      else
+		{
+		  // Must match in all dimensions.
+
+		  boolNDArray output (cell.dims (), false);
+
+		  if (cell.length () == r)
+		    {
+                      if (cell_val.is_cellstr ())
+                        {
+                          const Array<std::string> cellstr = cell_val.cellstr_value ();
+                          for (octave_idx_type i = 0; i < cellstr.length (); i++)
+                            output(i) = str[i] == cellstr(i);
+                        }
+                      else
+                        {
+                          // FIXME: should we warn here?
+                          for (octave_idx_type i = 0; i < r; i++)
+                            {
+                              if (cell(i).is_string ())
+                                output(i) = (str[i] == cell(i).string_value ());
+                            }
+                        }
+
+		      retval = output;
+		    }
+		  else
+		    retval = false;
+		}
+	    }
+	}
+      else if (s1_cell && s2_cell)
+	{
+          octave_value cell1_val, cell2_val;
+	  octave_idx_type r1 = args(0).numel (), r2;
+
+	  if (r1 == 1)
+	    {
+	      // Make the singleton cell2.
+
+	      cell1_val = args(1);
+	      cell2_val = args(0);
+	    }
+	  else
+	    {
+	      cell1_val = args(0);
+	      cell2_val = args(1);
+	    }
+
+	  const Cell cell1 = cell1_val.cell_value ();
+	  const Cell cell2 = cell2_val.cell_value ();
+          r1 = cell1.numel ();
+          r2 = cell2.numel ();
+
+	  const dim_vector size1 = cell1.dims ();
+	  const dim_vector size2 = cell2.dims ();
+
+	  boolNDArray output (size1, false);
+
+	  if (r2 == 1)
+	    {
+	      // Broadcast cell2.
+
+	      if (cell2(0).is_string ())
+		{
+		  const std::string str2 = cell2(0).string_value ();
+
+                  if (cell1_val.is_cellstr ())
+                    {
+                      const Array<std::string> cellstr = cell1_val.cellstr_value ();
+                      for (octave_idx_type i = 0; i < cellstr.length (); i++)
+                        output(i) = cellstr(i) == str2;
+                    }
+                  else
+                    {
+                      // FIXME: should we warn here?
+                      for (octave_idx_type i = 0; i < r1; i++)
+                        {
+                          if (cell1(i).is_string ())
+                            {
+                              const std::string str1 = cell1(i).string_value ();
+                              output(i) = (str1 == str2);
+                            }
+                        }
+                    }
+		}
+	    }
+	  else
+	    {
+	      if (size1 != size2)
+		{
+		  error ("strcmp: nonconformant cell arrays");
+		  return retval;
+		}
+
+              if (cell1.is_cellstr () && cell2.is_cellstr ())
+                {
+                  const Array<std::string> cellstr1 = cell1_val.cellstr_value ();
+                  const Array<std::string> cellstr2 = cell2_val.cellstr_value ();
+                  for (octave_idx_type i = 0; i < r1; i++)
+                    output (i) = cellstr1(i) == cellstr2(i);
+                }
+              else
+                {
+                  // FIXME: should we warn here?
+                  for (octave_idx_type i = 0; i < r1; i++)
+                    {
+                      if (cell1(i).is_string () && cell2(i).is_string ())
+                        {
+                          const std::string str1 = cell1(i).string_value ();
+                          const std::string str2 = cell2(i).string_value ();
+                          output(i) = (str1 == str2);
+                        }
+                    }
+                }
+	    }
+
+	  retval = output;
+	}
+      else
+	retval = false;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!shared x
+%!  x = char (zeros (0, 2));
+%!assert (strcmp ('', x) == false);
+%!assert (strcmp (x, '') == false);
+%!assert (strcmp (x, x) == true);
+## %!assert (strcmp ({''}, x) == false);
+## %!assert (strcmp ({x}, '') == false);
+## %!assert (strcmp ({x}, x) == true);
+## %!assert (strcmp ('', {x}) == false);
+## %!assert (strcmp (x, {''}) == false);
+## %!assert (strcmp (x, {x}) == true);
+## %!assert (all (strcmp ({x; x}, '') == [false; false]));
+## %!assert (all (strcmp ({x; x}, {''}) == [false; false]));
+## %!assert (all (strcmp ('', {x; x}) == [false; false]));
+## %!assert (all (strcmp ({''}, {x; x}) == [false; false]));
+%!assert (strcmp ({'foo'}, x) == false);
+%!assert (strcmp ({'foo'}, 'foo') == true);
+%!assert (strcmp ({'foo'}, x) == false);
+%!assert (strcmp (x, {'foo'}) == false);
+%!assert (strcmp ('foo', {'foo'}) == true);
+%!assert (strcmp (x, {'foo'}) == false);
+%!shared y
+%!  y = char (zeros (2, 0));
+%!assert (strcmp ('', y) == false);
+%!assert (strcmp (y, '') == false);
+%!assert (strcmp (y, y) == true);
+%!assert (all (strcmp ({''}, y) == [true; true]));
+%!assert (strcmp ({y}, '') == true);
+%!assert (all (strcmp ({y}, y) == [true; true]));
+%!assert (all (strcmp ('', {y}) == [true; true]));
+%!assert (all (strcmp (y, {''}) == [true; true]));
+%!assert (all (strcmp (y, {y}) == [true; true]));
+## %!assert (all (strcmp ({y; y}, '') == [false; false]));
+## %!assert (all (strcmp ({y; y}, {''}) == [false; false]));
+## %!assert (all (strcmp ('', {y; y}) == [false; false]));
+## %!assert (all (strcmp ({''}, {y; y}) == [false; false]));
+%!assert (all (strcmp ({'foo'}, y) == [false; false]));
+%!assert (all (strcmp ({'foo'}, y) == [false; false]));
+%!assert (all (strcmp (y, {'foo'}) == [false; false]));
+%!assert (all (strcmp (y, {'foo'}) == [false; false]));
+*/
+
+DEFUN (strncmp, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} strncmp (@var{s1}, @var{s2}, @var{n})\n\
+Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2} are the same,\n\
+and 0 otherwise.\n\
+\n\
+ at example\n\
+ at group\n\
+strncmp (\"abce\", \"abcd\", 3)\n\
+     @result{} 1\n\
+ at end group\n\
+ at end example\n\
+\n\
+If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\
+of the same size is returned, containing the values described above for\n\
+every member of the cell array.  The other argument may also be a cell\n\
+array of strings (of the same size or with only one element), char matrix\n\
+or character string.\n\
+\n\
+ at example\n\
+ at group\n\
+strncmp (\"abce\", @{\"abcd\", \"bca\", \"abc\"@}, 3)\n\
+     @result{} [1, 0, 1]\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmp\n\
+function returns 1 if the character strings are equal, and 0 otherwise.\n\
+This is just the opposite of the corresponding C library function.\n\
+ at seealso{strncmpi, strcmp, strcmpi}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 3)
+    {
+      bool s1_string = args(0).is_string ();
+      bool s1_cell = args(0).is_cell ();
+      bool s2_string = args(1).is_string ();
+      bool s2_cell = args(1).is_cell ();
+
+      // Match only first n strings.
+      int n = args(2).int_value ();
+
+      if (n <= 0)
+	{
+	  error ("strncmp: N must be greater than 0");
+	  return retval;
+	}
+
+      if (s1_string && s2_string)
+	{
+	  // The only restriction here is that each string has equal or 
+	  // greater than n characters
+
+	  const dim_vector dv1 = args(0).dims ();
+	  const dim_vector dv2 = args(1).dims ();
+
+	  if (dv1.numel () >= n && dv2.numel () >= n)
+	    {
+	      // Follow Matlab in the sense that the first n characters of 
+	      // the two strings (in column major order) need to be the same.
+	      charNDArray s1 = args(0).char_array_value ();
+	      charNDArray s2 = args(1).char_array_value ();
+	      
+	      for (int i = 0; i < n; i++)
+		{
+		  if (s1(i) != s2(i))
+		    {
+		      retval = false;
+		      return retval;
+		    }
+		}
+
+	      retval = true;
+	    }
+	  else
+	    retval = false;
+	}
+      else if ((s1_string && s2_cell) || (s1_cell && s2_string))
+	{
+	  string_vector str;
+	  Cell cell;
+	  octave_idx_type r, c;
+
+	  if (s1_string)
+	    {
+	      str = args(0).all_strings ();
+	      r = args(0).rows ();
+	      c = args(0).columns ();
+	      cell = args(1).cell_value ();
+	    }
+	  else
+	    {
+	      str = args(1).all_strings ();
+	      r = args(1).rows ();
+	      c = args(1).columns ();
+	      cell = args(0).cell_value ();
+	    }
+
+	  if (r == 1)
+	    {
+	      // Broadcast the string.
+
+	      boolNDArray output (cell.dims (), false);
+
+	      if (c < n)
+		{
+		  for (octave_idx_type i = 0; i < cell.length (); i++)
+		    output(i) = false;
+		}
+	      else
+		{
+		  for (octave_idx_type i = 0; i < cell.length (); i++)
+		    {
+		      if (cell(i).is_string ())
+			{
+			  const std::string str2 = cell(i).string_value ();
+
+			  if (str2.length () >= n
+			      && str2.compare (0, n, str[0], 0, n) == 0)
+				output(i) = true;
+			}
+		    }
+		}
+
+	      retval = output;
+	    }
+	  else if (r > 1)
+	    {
+	      if (cell.length () == 1)
+		{
+		  // Broadcast the cell.
+
+		  const dim_vector dv (r, 1);
+		  boolNDArray output (dv, false);
+
+		  if (cell(0).is_string () && c >= n)
+		    {
+		      const std::string str2 = cell(0).string_value ();
+		      
+		      if (str2.length () >= n)
+			{
+			  for (octave_idx_type i = 0; i < r; i++)
+			    {
+			      if (str[i].compare (0, n, str2, 0, n) == 0)
+				output(i) = true;
+			    }
+			}
+		    }
+
+		  retval = output;
+		}
+	      else
+		{
+		  // Must match in all dimensions.
+
+		  boolNDArray output (cell.dims (), false);
+
+		  if (cell.numel () == r)
+		    {
+		      for (octave_idx_type i = 0; i < r; i++)
+			{
+			  if (cell(i).is_string () && c >= n)
+			    {
+			      std::string str2 = cell(i).string_value ();
+
+			      if (str2.length () >= n
+				  && str2.compare (0, n, str[i], 0, n) == 0)
+				output(i) = true;
+			    }
+			}
+
+		      retval = output;
+		    }
+		  else
+		    {
+		      error ("strncmp: the number of rows of the string matrix must match the number of elements in the cell");
+		      return retval;
+		    }
+		}
+	    }
+	}
+      else if (s1_cell && s2_cell)
+	{
+	  Cell cell1;
+	  Cell cell2;
+
+	  octave_idx_type r1 = args(0).numel ();
+	  octave_idx_type r2;
+
+	  if (r1 == 1)
+	    {
+	      // Make the singleton cell2.
+
+	      cell1 = args(1).cell_value ();
+	      cell2 = args(0).cell_value ();
+	      r1 = cell1.length ();
+	      r2 = 1;
+	    }
+	  else
+	    {
+	      cell1 = args(0).cell_value ();
+	      cell2 = args(1).cell_value ();
+	      r2 = cell2.length ();
+	    }
+
+	  const dim_vector size1 = cell1.dims ();
+	  const dim_vector size2 = cell2.dims ();
+
+	  boolNDArray output (size1, false);
+
+	  if (r2 == 1)
+	    {
+	      // Broadcast cell2.
+
+	      if (cell2(0).is_string ())
+		{
+		  const std::string str2 = cell2(0).string_value ();
+
+		  for (octave_idx_type i = 0; i < r1; i++)
+		    {
+		      if (cell1(i).is_string ())
+			{
+			  const std::string str1 = cell1(i).string_value ();
+
+			  if (str1.length () >= n && str2.length () >= n
+			      && str1.compare (0, n, str2, 0, n) == 0)
+			    output(i) = true;
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      if (size1 != size2)
+		{
+		  error ("strncmp: nonconformant cell arrays");
+		  return retval;
+		}
+
+	      for (octave_idx_type i = 0; i < r1; i++)
+		{
+		  if (cell1(i).is_string () && cell2(i).is_string ())
+		    {
+		      const std::string str1 = cell1(i).string_value ();
+		      const std::string str2 = cell2(i).string_value ();
+
+		      if (str1.length () >= n && str2.length () >= n
+			  && str1.compare (0, n, str2, 0, n) == 0)
+			output(i) = true;
+		    }
+		}
+	    }
+
+	  retval = output;
+	}
+      else
+	retval = false;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!error <Invalid call to strncmp.*> strncmp ();
+%!error <Invalid call to strncmp.*> strncmp ("abc", "def");
+%!assert (strncmp ("abce", "abc", 3) == 1)
+%!assert (strncmp (100, 100, 1) == 0)
+%!assert (all (strncmp ("abce", {"abcd", "bca", "abc"}, 3) == [1, 0, 1]))
+%!assert (all (strncmp ("abc",  {"abcd", "bca", "abc"}, 4) == [0, 0, 0]))
+%!assert (all (strncmp ({"abcd", "bca", "abc"},"abce", 3) == [1, 0, 1]))
+%!assert (all (strncmp ({"abcd", "bca", "abc"},{"abcd", "bca", "abe"}, 3) == [1, 1, 0]))
+%!assert (all (strncmp("abc", {"abcd", 10}, 2) == [1, 0]))
+*/
+
+
+DEFUN (list_in_columns, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} list_in_columns (@var{arg}, @var{width})\n\
+Return a string containing the elements of @var{arg} listed in\n\
+columns with an overall maximum width of @var{width}.  The argument\n\
+ at var{arg} must be a cell array of character strings or a character array.\n\
+If @var{width} is not specified, the width of the terminal screen is used.\n\
+Newline characters are used to break the lines in the output string.\n\
+For example:\n\
+\n\
+ at example\n\
+ at group\n\
+list_in_columns (@{\"abc\", \"def\", \"ghijkl\", \"mnop\", \"qrs\", \"tuv\"@}, 20)\n\
+     @result{} ans = abc     mnop\n\
+            def     qrs\n\
+            ghijkl  tuv\n\
+\n\
+whos ans\n\
+     @result{}\n\
+     Variables in the current scope:\n\
+\n\
+       Attr Name        Size                     Bytes  Class\n\
+       ==== ====        ====                     =====  =====\n\
+            ans         1x37                        37  char\n\
+\n\
+     Total is 37 elements using 37 bytes\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at seealso{terminal_size}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      string_vector s = args(0).all_strings ();
+
+      if (! error_state)
+	{
+	  std::ostringstream buf;
+
+	  if (nargin == 1)
+	    // Let list_in_columns query terminal width.
+	    s.list_in_columns (buf);
+	  else
+	    {
+	      int width = args(1).int_value ();
+
+	      if (! error_state)
+		s.list_in_columns (buf, width);
+	      else
+		error ("list_in_columns: expecting width to be an integer");
+	    }
+
+	  retval = buf.str ();
+	}
+      else
+	error ("list_in_columns: expecting cellstr or char array");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!error <Invalid call to list_in_columns.*> list_in_columns ();
+%!error <Invalid call to list_in_columns.*> list_in_columns (["abc", "def"], 20, 2);
+%!error <invalid conversion from string to real scalar.*> list_in_columns (["abc", "def"], "a");
+%!test
+%!  input  = {"abc", "def", "ghijkl", "mnop", "qrs", "tuv"};
+%!  result = "abc     mnop\ndef     qrs\nghijkl  tuv\n";
+%!  assert (list_in_columns (input, 20) == result);
+%!test
+%!  input  = ["abc"; "def"; "ghijkl"; "mnop"; "qrs"; "tuv"];
+%!  result = "abc     mnop  \ndef     qrs   \nghijkl  tuv   \n";
+%!  assert (list_in_columns (input, 20) == result);
+*/
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/symtab.cc b/src/symtab.cc
new file mode 100644
index 0000000..8036f48
--- /dev/null
+++ b/src/symtab.cc
@@ -0,0 +1,1396 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+  
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-env.h"
+#include "oct-time.h"
+#include "file-ops.h"
+#include "file-stat.h"
+
+#include "defun.h"
+#include "dirfns.h"
+#include "input.h"
+#include "load-path.h"
+#include "symtab.h"
+#include "ov-fcn.h"
+#include "ov-usr-fcn.h"
+#include "pager.h"
+#include "parse.h"
+#include "pt-arg-list.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "debug.h"
+
+symbol_table *symbol_table::instance = 0;
+
+symbol_table::scope_id_cache *symbol_table::scope_id_cache::instance = 0;
+
+std::map<symbol_table::scope_id, symbol_table*> symbol_table::all_instances;
+
+std::map<std::string, octave_value> symbol_table::global_table;
+
+std::map<std::string, symbol_table::fcn_info> symbol_table::fcn_table;
+
+std::map<std::string, std::set<std::string> > symbol_table::class_precedence_table;
+
+const symbol_table::scope_id symbol_table::xglobal_scope = 0;
+const symbol_table::scope_id symbol_table::xtop_scope = 1;
+
+symbol_table::scope_id symbol_table::xcurrent_scope = 1;
+
+symbol_table::scope_id symbol_table::xparent_scope = -1;
+
+symbol_table::context_id symbol_table::xcurrent_context = 0;
+
+// Should Octave always check to see if function files have changed
+// since they were last compiled?
+static int Vignore_function_time_stamp = 1;
+
+void
+symbol_table::symbol_record::symbol_record_rep::dump
+  (std::ostream& os, const std::string& prefix) const
+{
+  octave_value val = varval (xcurrent_context);
+
+  os << prefix << name;
+
+  if (val.is_defined ())
+    {
+      os << " ["
+	 << (is_local () ? "l" : "")
+	 << (is_automatic () ? "a" : "")
+	 << (is_formal () ? "f" : "")
+	 << (is_hidden () ? "h" : "")
+	 << (is_inherited () ? "i" : "")
+	 << (is_global () ? "g" : "")
+	 << (is_persistent () ? "p" : "")
+	 << "] ";
+      val.dump (os);
+    }
+
+  os << "\n";
+}
+
+octave_value
+symbol_table::symbol_record::find (tree_argument_list *args,
+				   const string_vector& arg_names,
+				   octave_value_list& evaluated_args,
+				   bool& args_evaluated) const
+{
+  octave_value retval;
+
+  if (is_global ())
+    return symbol_table::global_varref (name ());
+  else
+    {
+      octave_value val = varval ();
+
+      if (val.is_defined ())
+	return val;
+    }
+
+  return symbol_table::find_function (name (), args, arg_names,
+				      evaluated_args, args_evaluated);
+}
+
+// Check the load path to see if file that defined this is still
+// visible.  If the file is no longer visible, then erase the
+// definition and move on.  If the file is visible, then we also
+// need to check to see whether the file has changed since the the
+// function was loaded/parsed.  However, this check should only
+// happen once per prompt (for files found from relative path
+// elements, we also check if the working directory has changed
+// since the last time the function was loaded/parsed).
+//
+// FIXME -- perhaps this should be done for all loaded functions when
+// the prompt is printed or the directory has changed, and then we
+// would not check for it when finding symbol definitions.
+
+static inline bool
+load_out_of_date_fcn (const std::string& ff, const std::string& dir_name,
+		      octave_value& function,
+		      const std::string& dispatch_type = std::string ())
+{
+  bool retval = false;
+
+  octave_function *fcn = load_fcn_from_file (ff, dir_name, dispatch_type);
+
+  if (fcn)
+    {
+      retval = true;
+
+      function = octave_value (fcn);
+    }
+  else
+    function = octave_value ();
+
+  return retval;
+}
+
+static inline bool
+out_of_date_check_internal (octave_function *fcn, octave_value& function,
+			    const std::string& dispatch_type = std::string ())
+{
+  bool retval = false;
+
+  if (fcn)
+    {
+      // FIXME -- we need to handle nested functions properly here.
+
+      if (! fcn->is_nested_function ())
+	{
+	  std::string ff = fcn->fcn_file_name ();
+
+	  if (! ff.empty ())
+	    {
+	      octave_time tc = fcn->time_checked ();
+
+	      bool relative = fcn->is_relative ();
+
+	      if (tc < Vlast_prompt_time
+		  || (relative && tc < Vlast_chdir_time))
+		{
+		  bool clear_breakpoints = false;
+		  std::string nm = fcn->name ();
+
+		  int nm_len = nm.length ();
+
+		  std::string file;
+		  std::string dir_name;
+
+		  if (octave_env::absolute_pathname (nm)
+		      && ((nm_len > 4 && (nm.substr (nm_len-4) == ".oct"
+					  || nm.substr (nm_len-4) == ".mex"))
+			  || (nm_len > 2 && nm.substr (nm_len-2) == ".m")))
+		    file = nm;
+		  else
+		    {
+		      // We don't want to make this an absolute name,
+		      // because load_fcn_file looks at the name to
+		      // decide whether it came from a relative lookup.
+
+		      if (! dispatch_type.empty ())
+			file = load_path::find_method (dispatch_type, nm,
+						       dir_name);
+
+		      if (file.empty ())
+			file = load_path::find_fcn (nm, dir_name);
+		    }
+
+		  if (file.empty ())
+		    {
+		      // Can't see this function from current
+		      // directory, so we should clear it.
+
+		      function = octave_value ();
+
+		      clear_breakpoints = true;
+		    }
+		  else if (same_file (file, ff))
+		    {
+		      // Same file.  If it is out of date, then reload it.
+
+		      octave_time ottp = fcn->time_parsed ();
+		      time_t tp = ottp.unix_time ();
+
+		      fcn->mark_fcn_file_up_to_date (octave_time ());
+
+		      if (! (Vignore_function_time_stamp == 2
+			     || (Vignore_function_time_stamp
+				 && fcn->is_system_fcn_file ())))
+			{
+			  file_stat fs (ff);
+
+			  if (fs)
+			    {
+			      if (fs.is_newer (tp))
+				{
+				  retval = load_out_of_date_fcn (ff, dir_name,
+								 function,
+								 dispatch_type);
+
+				  clear_breakpoints = true;
+				}
+			    }
+			  else
+			    {
+			      function = octave_value ();
+
+			      clear_breakpoints = true;
+			    }
+			}
+		    }
+		  else
+		    {
+		      // Not the same file, so load the new file in
+		      // place of the old.
+
+		      retval = load_out_of_date_fcn (file, dir_name, function,
+						     dispatch_type);
+
+		      clear_breakpoints = true;
+		    }
+
+		  // If the function has been replaced then clear any 
+		  // breakpoints associated with it
+		  if (clear_breakpoints)
+		    bp_table::remove_all_breakpoints_in_file (nm, true);
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+out_of_date_check_internal (octave_value& function,
+			    const std::string& dispatch_type = std::string ())
+{
+  return out_of_date_check_internal (function.function_value (true),
+				     function, dispatch_type);
+}
+
+bool
+out_of_date_check (octave_value& function)
+{
+  return out_of_date_check_internal (function);
+}
+
+bool
+out_of_date_check (octave_function* fcn)
+{
+  octave_value function;
+  return out_of_date_check_internal (fcn, function);
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::load_private_function
+  (const std::string& dir_name)
+{
+  octave_value retval;
+
+  std::string file_name = load_path::find_private_fcn (dir_name, name);
+
+  if (! file_name.empty ())
+    {
+      octave_function *fcn = load_fcn_from_file (file_name, dir_name);
+
+      if (fcn)
+	{
+	  std::string class_name;
+
+	  size_t pos = dir_name.find_last_of (file_ops::dir_sep_chars ());
+
+	  if (pos != std::string::npos)
+	    {
+	      std::string tmp = dir_name.substr (pos+1);
+
+	      if (tmp[0] == '@')
+		class_name = tmp.substr (1);
+	    }
+
+	  fcn->mark_as_private_function (class_name);
+
+	  retval = octave_value (fcn);
+
+	  private_functions[dir_name] = retval;
+	}
+    }
+
+  return retval;
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::load_class_constructor (void)
+{
+  octave_value retval;
+
+  std::string dir_name;
+
+  std::string file_name = load_path::find_method (name, name, dir_name);
+
+  if (! file_name.empty ())
+    {
+      octave_function *fcn = load_fcn_from_file (file_name, dir_name, name);
+
+      if (fcn)
+	{
+	  retval = octave_value (fcn);
+
+	  class_constructors[name] = retval;
+	}
+    }
+
+  return retval;
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::load_class_method
+  (const std::string& dispatch_type)
+{
+  octave_value retval;
+
+  if (name == dispatch_type)
+    retval = load_class_constructor ();
+  else
+    {
+      std::string dir_name;
+
+      std::string file_name = load_path::find_method (dispatch_type, name,
+						      dir_name);
+
+      if (! file_name.empty ())
+	{
+	  octave_function *fcn = load_fcn_from_file (file_name, dir_name,
+						     dispatch_type);
+
+	  if (fcn)
+	    {
+	      retval = octave_value (fcn);
+
+	      class_methods[dispatch_type] = retval;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+void
+symbol_table::fcn_info::fcn_info_rep::print_dispatch (std::ostream& os) const
+{
+  if (dispatch_map.empty ())
+    os << "dispatch: " << name << " is not overloaded" << std::endl;
+  else
+    {
+      os << "Overloaded function " << name << ":\n\n";
+
+      for (dispatch_map_const_iterator p = dispatch_map.begin ();
+	   p != dispatch_map.end (); p++)
+	os << "  " << name << " (" << p->first << ", ...) -> " 
+	   << p->second << " (" << p->first << ", ...)\n";
+
+      os << std::endl;
+    }
+}
+
+std::string
+symbol_table::fcn_info::fcn_info_rep::help_for_dispatch (void) const
+{
+  std::string retval;
+
+  if (! dispatch_map.empty ())
+    {
+      retval = "Overloaded function:\n\n";
+
+      for (dispatch_map_const_iterator p = dispatch_map.begin ();
+	   p != dispatch_map.end (); p++)
+	retval += "  " + p->second + " (" + p->first + ", ...)\n\n";
+    }
+
+  return retval;
+}
+
+static std::string
+get_dispatch_type (const octave_value_list& evaluated_args)
+{
+  std::string dispatch_type;
+
+  int n = evaluated_args.length ();
+
+  if (n > 0)
+    {
+      // Find first object, if any.
+
+      int i;
+
+      for (i = 0; i < n; i++)
+	{
+	  octave_value arg = evaluated_args(i);
+
+	  if (arg.is_object ())
+	    {
+	      dispatch_type = arg.class_name ();
+	      break;
+	    }
+	}
+
+      for (int j = i+1; j < n; j++)
+	{
+	  octave_value arg = evaluated_args(j);
+
+	  if (arg.is_object ())
+	    {
+	      std::string cname = arg.class_name ();
+
+	      // Only switch to type of ARG if it is marked superior
+	      // to the current DISPATCH_TYPE.
+	      if (! symbol_table::is_superiorto (dispatch_type, cname)
+		  && symbol_table::is_superiorto (cname, dispatch_type))
+		dispatch_type = cname;
+	    }
+	}
+
+      if (dispatch_type.empty ())
+	{
+	  // No object found, so use class of first argument.
+
+	  dispatch_type = evaluated_args(0).class_name ();
+	}
+    }
+
+  return dispatch_type;
+}
+
+// Find the definition of NAME according to the following precedence
+// list:
+//
+//   variable
+//   subfunction
+//   private function
+//   class constructor
+//   class method
+//   legacy dispatch
+//   command-line function
+//   autoload function
+//   function on the path
+//   built-in function
+
+// Notes:
+//
+// FIXME -- we need to evaluate the argument list to determine the
+// dispatch type.  The method used here works (pass in the args, pass
+// out the evaluated args and a flag saying whether the evaluation was
+// needed), but it seems a bit inelegant.  We do need to save the
+// evaluated args in some way to avoid evaluating them multiple times.
+//  Maybe evaluated args could be attached to the tree_argument_list
+// object?  Then the argument list could be evaluated outside of this
+// function and we could elimnate the arg_names, evaluated_args, and
+// args_evaluated arguments.  We would still want to avoid computing
+// the dispatch type unless it is needed, so the args should be passed
+// rather than the dispatch type.  But the arguments will need to be
+// evaluated no matter what, so evaluating them beforehand should be
+// OK.  If the evaluated arguments are attached to args, then we would
+// need to determine the appropriate place(s) to clear them (for
+// example, before returning from tree_index_expression::rvalue).
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::find
+  (tree_argument_list *args, const string_vector& arg_names,
+   octave_value_list& evaluated_args, bool& args_evaluated)
+{
+  octave_value retval = xfind (args, arg_names, evaluated_args, args_evaluated);
+
+  if (! retval.is_defined ())
+    {
+      // It is possible that the user created a file on the fly since
+      // the last prompt or chdir, so try updating the load path and
+      // searching again.
+
+      load_path::update ();
+
+      retval = xfind (args, arg_names, evaluated_args, args_evaluated);
+    }
+
+  return retval;
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::xfind
+  (tree_argument_list *args, const string_vector& arg_names,
+   octave_value_list& evaluated_args, bool& args_evaluated)
+{
+  // Subfunction.  I think it only makes sense to check for
+  // subfunctions if we are currently executing a function defined
+  // from a .m file.
+
+  scope_val_iterator r = subfunctions.find (xcurrent_scope);
+
+  octave_function *curr_fcn = 0;
+
+  if (r != subfunctions.end ())
+    {
+      // FIXME -- out-of-date check here.
+
+      return r->second;
+    }
+  else
+    {
+      curr_fcn = octave_call_stack::current ();
+
+      if (curr_fcn)
+	{
+	  scope_id pscope = curr_fcn->parent_fcn_scope ();
+
+	  if (pscope > 0)
+	    {
+	      r = subfunctions.find (pscope);
+
+	      if (r != subfunctions.end ())
+		{
+		  // FIXME -- out-of-date check here.
+
+		  return r->second;
+		}
+	    }
+	}
+    }
+
+  // Private function.
+
+  if (! curr_fcn)
+    curr_fcn = octave_call_stack::current ();
+
+  if (curr_fcn)
+    {
+      std::string dir_name = curr_fcn->dir_name ();
+
+      if (! dir_name.empty ())
+	{
+	  str_val_iterator q = private_functions.find (dir_name);
+
+	  if (q == private_functions.end ())
+	    {
+	      octave_value val = load_private_function (dir_name);
+
+	      if (val.is_defined ())
+		return val;
+	    }
+	  else
+	    {
+	      octave_value& fval = q->second;
+
+	      if (fval.is_defined ())
+		out_of_date_check_internal (fval);
+
+	      if (fval.is_defined ())
+		return fval;
+	      else
+		{
+		  octave_value val = load_private_function (dir_name);
+
+		  if (val.is_defined ())
+		    return val;
+		}
+	    }
+	}
+    }
+
+  // Class constructors.  The class name and function name are the same.
+
+  str_val_iterator q = class_constructors.find (name);
+
+  if (q == class_constructors.end ())
+    {
+      octave_value val = load_class_constructor ();
+
+      if (val.is_defined ())
+	return val;
+    }
+  else
+    {
+      octave_value& fval = q->second;
+
+      if (fval.is_defined ())
+	out_of_date_check_internal (fval, name);
+
+      if (fval.is_defined ())
+	return fval;
+      else
+	{
+	  octave_value val = load_class_constructor ();
+
+	  if (val.is_defined ())
+	    return val;
+	}
+    }
+
+  // Class methods.
+
+  if (args_evaluated || (args && args->length () > 0))
+    {
+      if (! args_evaluated)
+	evaluated_args = args->convert_to_const_vector ();
+
+      if (! error_state)
+	{
+	  int n = evaluated_args.length ();
+
+	  if (n > 0 && ! args_evaluated)
+	    evaluated_args.stash_name_tags (arg_names);
+
+	  args_evaluated = true;
+
+	  if (n > 0)
+	    {
+	      std::string dispatch_type = get_dispatch_type (evaluated_args);
+
+	      octave_value fcn = find_method (dispatch_type);
+
+	      if (fcn.is_defined ())
+		return fcn;
+	    }
+	}
+      else
+	return octave_value ();
+    }
+
+  // Legacy dispatch.  We just check args_evaluated here because the
+  // actual evaluation will have happened already when searching for
+  // class methods.
+
+  if (args_evaluated && ! dispatch_map.empty ())
+    {
+      std::string dispatch_type = 
+        const_cast<const octave_value_list&>(evaluated_args)(0).type_name ();
+
+      std::string fname;
+
+      dispatch_map_iterator p = dispatch_map.find (dispatch_type);
+
+      if (p == dispatch_map.end ())
+	p = dispatch_map.find ("any");
+
+      if (p != dispatch_map.end ())
+	{
+	  fname = p->second;
+
+	  octave_value fcn
+	    = symbol_table::find_function (fname, evaluated_args);
+
+	  if (fcn.is_defined ())
+	    return fcn;
+	}
+    }
+
+  // Command-line function.
+
+  if (cmdline_function.is_defined ())
+    return cmdline_function;
+
+  // Autoload?
+
+  octave_value fcn = find_autoload ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Function on the path.
+
+  fcn = find_user_function ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Built-in function (might be undefined).
+
+  return built_in_function;
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::find_method (const std::string& dispatch_type)
+{
+  octave_value retval;
+
+  str_val_iterator q = class_methods.find (dispatch_type);
+
+  if (q == class_methods.end ())
+    {
+      octave_value val = load_class_method (dispatch_type);
+
+      if (val.is_defined ())
+	return val;
+    }
+  else
+    {
+      octave_value& fval = q->second;
+
+      if (fval.is_defined ())
+	out_of_date_check_internal (fval, dispatch_type);
+
+      if (fval.is_defined ())
+	return fval;
+      else
+	{
+	  octave_value val = load_class_method (dispatch_type);
+
+	  if (val.is_defined ())
+	    return val;
+	}
+    }
+
+  return retval;
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::find_autoload (void)
+{
+  octave_value retval;
+
+  // Autoloaded function.
+
+  if (autoload_function.is_defined ())
+    out_of_date_check_internal (autoload_function);
+
+  if (! autoload_function.is_defined ())
+    {
+      std::string file_name = lookup_autoload (name);
+
+      if (! file_name.empty ())
+	{
+	  size_t pos = file_name.find_last_of (file_ops::dir_sep_chars ());
+
+	  std::string dir_name = file_name.substr (0, pos);
+
+	  octave_function *fcn = load_fcn_from_file (file_name, dir_name,
+						     "", name, true);
+
+	  if (fcn)
+	    autoload_function = octave_value (fcn);
+	}
+    }
+
+  return autoload_function;
+}
+
+octave_value
+symbol_table::fcn_info::fcn_info_rep::find_user_function (void)
+{
+  // Function on the path.
+
+  if (function_on_path.is_defined ())
+    out_of_date_check_internal (function_on_path);
+
+  if (! function_on_path.is_defined ())
+    {
+      std::string dir_name;
+
+      std::string file_name = load_path::find_fcn (name, dir_name);
+
+      if (! file_name.empty ())
+	{
+	  octave_function *fcn = load_fcn_from_file (file_name, dir_name);
+
+	  if (fcn)
+	    function_on_path = octave_value (fcn);
+	}
+    }
+
+  return function_on_path;
+}
+
+// Insert INF_CLASS in the set of class names that are considered
+// inferior to SUP_CLASS.  Return FALSE if INF_CLASS is currently
+// marked as superior to  SUP_CLASS.
+
+bool
+symbol_table::set_class_relationship (const std::string& sup_class,
+				      const std::string& inf_class)
+{
+  class_precedence_table_const_iterator p
+    = class_precedence_table.find (inf_class);
+
+  if (p != class_precedence_table.end ())
+    {
+      const std::set<std::string>& inferior_classes = p->second;
+
+      std::set<std::string>::const_iterator q
+	= inferior_classes.find (sup_class);
+
+      if (q != inferior_classes.end ())
+	return false;
+    }
+
+  class_precedence_table[sup_class].insert (inf_class);
+
+  return true;
+}
+
+// Has class A been marked as superior to class B?  Also returns
+// TRUE if B has been marked as inferior to A, since we only keep
+// one table, and convert inferiort information to a superiorto
+// relationship.  Two calls are required to determine whether there
+// is no relationship between two classes:
+//
+//  if (symbol_table::is_superiorto (a, b))
+//    // A is superior to B, or B has been marked inferior to A.
+//  else if (symbol_table::is_superiorto (b, a))
+//    // B is superior to A, or A has been marked inferior to B.
+//  else
+//    // No relation.
+
+bool
+symbol_table::is_superiorto (const std::string& a, const std::string& b)
+{
+  bool retval = false;
+
+  class_precedence_table_const_iterator p = class_precedence_table.find (a);
+
+  if (p != class_precedence_table.end ())
+    {
+      const std::set<std::string>& inferior_classes = p->second;
+      std::set<std::string>::const_iterator q = inferior_classes.find (b);
+
+      if (q != inferior_classes.end ())
+	retval = true;
+    }
+
+  return retval;
+}
+
+static std::string
+fcn_file_name (const octave_value& fcn)
+{
+  const octave_function *f = fcn.function_value ();
+
+  return f ? f->fcn_file_name () : std::string ();
+}
+
+void
+symbol_table::fcn_info::fcn_info_rep::dump
+  (std::ostream& os, const std::string& prefix) const
+{
+  os << prefix << name
+     << " ["
+     << (cmdline_function.is_defined () ? "c" : "")
+     << (built_in_function.is_defined () ? "b" : "")
+     << "]\n";
+
+  std::string tprefix = prefix + "  ";
+
+  if (autoload_function.is_defined ())
+    os << tprefix << "autoload: "
+       << fcn_file_name (autoload_function) << "\n";
+
+  if (function_on_path.is_defined ())
+    os << tprefix << "function from path: "
+       << fcn_file_name (function_on_path) << "\n";
+
+  if (! subfunctions.empty ())
+    {
+      for (scope_val_const_iterator p = subfunctions.begin ();
+	   p != subfunctions.end (); p++)
+	os << tprefix << "subfunction: " << fcn_file_name (p->second)
+	   << " [" << p->first << "]\n";
+    }
+
+  if (! private_functions.empty ())
+    {
+      for (str_val_const_iterator p = private_functions.begin ();
+	   p != private_functions.end (); p++)
+	os << tprefix << "private: " << fcn_file_name (p->second)
+	   << " [" << p->first << "]\n";
+    }
+
+  if (! class_constructors.empty ())
+    {
+      for (str_val_const_iterator p = class_constructors.begin ();
+	   p != class_constructors.end (); p++)
+	os << tprefix << "constructor: " << fcn_file_name (p->second)
+	   << " [" << p->first << "]\n";
+    }
+
+  if (! class_methods.empty ())
+    {
+      for (str_val_const_iterator p = class_methods.begin ();
+	   p != class_methods.end (); p++)
+	os << tprefix << "method: " << fcn_file_name (p->second)
+	   << " [" << p->first << "]\n";
+    }
+
+  if (! dispatch_map.empty ())
+    {
+      for (dispatch_map_const_iterator p = dispatch_map.begin ();
+	   p != dispatch_map.end (); p++)
+	os << tprefix << "dispatch: " << fcn_file_name (p->second)
+	   << " [" << p->first << "]\n";
+    }
+}
+
+octave_value
+symbol_table::fcn_info::find (tree_argument_list *args,
+			      const string_vector& arg_names,
+			      octave_value_list& evaluated_args,
+			      bool& args_evaluated)
+{
+  return rep->find (args, arg_names, evaluated_args, args_evaluated);
+}
+
+octave_value
+symbol_table::find (const std::string& name, tree_argument_list *args,
+		    const string_vector& arg_names,
+		    octave_value_list& evaluated_args, bool& args_evaluated,
+		    bool skip_variables)
+{
+  symbol_table *inst = get_instance (xcurrent_scope);
+
+  return inst
+    ? inst->do_find (name, args, arg_names, evaluated_args,
+		     args_evaluated, skip_variables)
+    : octave_value ();
+}
+
+octave_value
+symbol_table::find_function (const std::string& name, tree_argument_list *args,
+			     const string_vector& arg_names,
+			     octave_value_list& evaluated_args,
+			     bool& args_evaluated)
+{
+  octave_value retval;
+
+  if (! name.empty () && name[0] == '@')
+    {
+      // Look for a class specific function.
+      std::string dispatch_type = 
+	name.substr (1, name.find_first_of (file_ops::dir_sep_str ()) - 1);
+
+      std::string method = 
+	name.substr (name.find_last_of (file_ops::dir_sep_str ()) + 1, 
+		     std::string::npos);
+
+      retval = find_method (method, dispatch_type);
+    }
+  else
+    {
+      size_t pos = name.find_first_of (Vfilemarker);
+
+      if (pos == std::string::npos)
+	retval = find (name, args, arg_names, evaluated_args,
+		       args_evaluated, true);
+      else
+	{
+	  std::string fcn_scope = name.substr (0, pos);
+	  scope_id stored_scope = xcurrent_scope;
+	  xcurrent_scope = xtop_scope;
+	  octave_value parent = find_function (name.substr(0, pos));
+
+	  if (parent.is_defined ())
+	    {
+	      octave_function *parent_fcn = parent.function_value ();
+
+	      if (parent_fcn)
+		{
+		  xcurrent_scope = parent_fcn->scope ();
+
+		  if (xcurrent_scope > 1)
+		    retval = find_function (name.substr (pos + 1), args,
+					    arg_names, evaluated_args, 
+					    args_evaluated);
+		}
+	    }
+
+	  xcurrent_scope = stored_scope;
+	}
+    }
+
+  return retval;
+}
+
+void
+symbol_table::dump (std::ostream& os, scope_id scope)
+{
+  if (scope == xglobal_scope)
+    dump_global (os);
+  else
+    {
+      symbol_table *inst = get_instance (scope, false);
+
+      if (inst)
+	{
+	  os << "*** dumping symbol table scope " << scope
+	     << " (" << inst->table_name << ")\n\n";
+
+	  std::map<std::string, octave_value> sfuns
+	    = symbol_table::subfunctions_defined_in_scope (scope);
+
+	  if (! sfuns.empty ())
+	    {
+	      os << "  subfunctions defined in this scope:\n";
+
+	      for (std::map<std::string, octave_value>::const_iterator p = sfuns.begin ();
+		   p != sfuns.end (); p++)
+		os << "    " << p->first << "\n";
+
+	      os << "\n";
+	    }
+
+	  inst->do_dump (os);
+	}
+    }
+}
+
+void
+symbol_table::dump_global (std::ostream& os)
+{
+  if (! global_table.empty ())
+    {
+      os << "*** dumping global symbol table\n\n";
+
+      for (global_table_const_iterator p = global_table.begin ();
+	   p != global_table.end (); p++)
+	{
+	  std::string nm = p->first;
+	  octave_value val = p->second;
+
+	  os << "  " << nm << " ";
+	  val.dump (os);
+	  os << "\n";
+	}
+    }
+}
+
+void
+symbol_table::dump_functions (std::ostream& os)
+{
+  if (! fcn_table.empty ())
+    {
+      os << "*** dumping globally visible functions from symbol table\n"
+	 << "    (c=commandline, b=built-in)\n\n";
+
+      for (fcn_table_const_iterator p = fcn_table.begin ();
+	   p != fcn_table.end (); p++)
+	p->second.dump (os, "  ");
+
+      os << "\n";
+    }
+}
+
+void
+symbol_table::stash_dir_name_for_subfunctions (scope_id scope,
+					       const std::string& dir_name)
+{
+  // FIXME -- is this the best way to do this?  Maybe it would be
+  // better if we had a map from scope to list of subfunctions
+  // stored with the function.  Do we?
+
+  for (fcn_table_const_iterator p = fcn_table.begin ();
+       p != fcn_table.end (); p++)
+    {
+      std::pair<std::string, octave_value> tmp
+	= p->second.subfunction_defined_in_scope (scope);
+
+      std::string nm = tmp.first;
+
+      if (! nm.empty ())
+	{
+	  octave_value& fcn = tmp.second;
+
+	  octave_user_function *f = fcn.user_function_value ();
+
+	  if (f)
+	    f->stash_dir_name (dir_name);
+	}
+    }
+}
+
+octave_value
+symbol_table::do_find (const std::string& name, tree_argument_list *args,
+		       const string_vector& arg_names,
+		       octave_value_list& evaluated_args,
+		       bool& args_evaluated, bool skip_variables)
+{
+  octave_value retval;
+
+  // Variable.
+
+  if (! skip_variables)
+    {
+      table_iterator p = table.find (name);
+
+      if (p != table.end ())
+	{
+	  symbol_record sr = p->second;
+
+	  // FIXME -- should we be using something other than varref here?
+
+	  if (sr.is_global ())
+	    return symbol_table::global_varref (name);
+	  else
+	    {
+	      octave_value& val = sr.varref ();
+
+	      if (val.is_defined ())
+		return val;
+	    }
+	}
+    }
+
+  fcn_table_iterator p = fcn_table.find (name);
+
+  if (p != fcn_table.end ())
+    return p->second.find (args, arg_names, evaluated_args, args_evaluated);
+  else
+    {
+      fcn_info finfo (name);
+
+      octave_value fcn = finfo.find (args, arg_names, evaluated_args,
+				     args_evaluated);
+
+      if (fcn.is_defined ())
+	fcn_table[name] = finfo;
+
+      return fcn;
+    }
+
+  return retval;
+}
+
+void
+symbol_table::do_dump (std::ostream& os)
+{
+  if (! persistent_table.empty ())
+    {
+      os << "  persistent variables in this scope:\n\n";
+
+      for (persistent_table_const_iterator p = persistent_table.begin ();
+	   p != persistent_table.end (); p++)
+	{
+	  std::string nm = p->first;
+	  octave_value val = p->second;
+
+	  os << "    " << nm << " ";
+	  val.dump (os);
+	  os << "\n";
+	}
+
+      os << "\n";
+    }
+
+  if (! table.empty ())
+    {
+      os << "  other symbols in this scope (l=local; a=auto; f=formal\n"
+	 << "    h=hidden; i=inherited; g=global; p=persistent)\n\n";
+
+      for (table_const_iterator p = table.begin (); p != table.end (); p++)
+	p->second.dump (os, "    ");
+
+      os << "\n";
+    }
+}
+
+DEFUN (ignore_function_time_stamp, args, nargout,
+    "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{val} =} ignore_function_time_stamp ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})\n\
+Query or set the internal variable that controls whether Octave checks\n\
+the time stamp on files each time it looks up functions defined in\n\
+function files.  If the internal variable is set to @code{\"system\"},\n\
+Octave will not automatically recompile function files in subdirectories of\n\
+ at file{@var{octave-home}/lib/@var{version}} if they have changed since\n\
+they were last compiled, but will recompile other function files in the\n\
+search path if they change.  If set to @code{\"all\"}, Octave will not\n\
+recompile any function files unless their definitions are removed with\n\
+ at code{clear}.  If set to \"none\", Octave will always check time stamps\n\
+on files to determine whether functions defined in function files\n\
+need to recompiled.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (nargout > 0)
+    {
+      switch (Vignore_function_time_stamp)
+	{
+	case 1:
+	  retval = "system";
+	  break;
+
+	case 2:
+	  retval = "all";
+	  break;
+
+	default:
+	  retval = "none";
+	  break;
+	}
+    }
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string sval = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  if (sval == "all")
+	    Vignore_function_time_stamp = 2;
+	  else if (sval == "system")
+	    Vignore_function_time_stamp = 1;
+	  else if (sval == "none")
+	    Vignore_function_time_stamp = 0;
+	  else
+	    error ("ignore_function_time_stamp: expecting argument to be \"all\", \"system\", or \"none\"");
+	}
+      else
+	error ("ignore_function_time_stamp: expecting argument to be character string");
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__current_scope__, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{scope}, @var{context}]} __dump_symtab_info__ ()\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = symbol_table::current_context ();
+  retval(0) = symbol_table::current_scope ();
+
+  return retval;
+}
+
+DEFUN (__dump_symtab_info__, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} __dump_symtab_info__ ()\n\
+ at deftypefnx {Built-in Function} {} __dump_symtab_info__ (@var{scope})\n\
+ at deftypefnx {Built-in Function} {} __dump_symtab_info__ (\"scopes\")\n\
+ at deftypefnx {Built-in Function} {} __dump_symtab_info__ (\"functions\")\n\
+Undocumented internal function.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      symbol_table::dump_functions (octave_stdout);
+
+      symbol_table::dump_global (octave_stdout);
+
+      std::list<symbol_table::scope_id> lst = symbol_table::scopes ();
+
+      for (std::list<symbol_table::scope_id>::const_iterator p = lst.begin ();
+	   p != lst.end (); p++)
+	symbol_table::dump (octave_stdout, *p);
+    }
+  else if (nargin == 1)
+    {
+      octave_value arg = args(0);
+
+      if (arg.is_string ())
+	{
+	  std::string s_arg = arg.string_value ();
+
+	  if (s_arg == "scopes")
+	    {
+	      std::list<symbol_table::scope_id> lst = symbol_table::scopes ();
+
+	      RowVector v (lst.size ());
+
+	      octave_idx_type k = 0;
+
+	      for (std::list<symbol_table::scope_id>::const_iterator p = lst.begin ();
+		   p != lst.end (); p++)
+		v.xelem (k++) = *p;
+
+	      retval = v;
+	    }
+	  else if (s_arg == "functions")
+	    {
+	      symbol_table::dump_functions (octave_stdout);
+	    }
+	  else
+	    error ("__dump_symtab_info__: expecting \"functions\" or \"scopes\"");
+	}
+      else
+	{
+	  int s = arg.int_value ();
+
+	  if (! error_state)
+	    symbol_table::dump (octave_stdout, s);
+	  else
+	    error ("__dump_symtab_info__: expecting string or scope id");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#if 0
+
+// FIXME -- should we have functions like this in Octave?
+
+DEFUN (set_variable, args, , "set_variable (NAME, VALUE)")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	symbol_table::varref (name) = args(1);
+      else
+	error ("set_variable: expecting variable name as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (variable_value, args, , "VALUE = variable_value (NAME)")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  retval = symbol_table::varval (name);
+
+	  if (retval.is_undefined ())
+	    error ("variable_value: `%s' is not a variable in the current scope",
+		   name.c_str ());
+	}
+      else
+	error ("variable_value: expecting variable name as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/symtab.h b/src/symtab.h
new file mode 100644
index 0000000..d187096
--- /dev/null
+++ b/src/symtab.h
@@ -0,0 +1,2363 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+  
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_symtab_h)
+#define octave_symtab_h 1
+
+#include <deque>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include "glob-match.h"
+#include "regex-match.h"
+
+class tree_argument_list;
+
+#include "oct-obj.h"
+#include "ov.h"
+
+class
+OCTINTERP_API
+symbol_table
+{
+public:
+
+  typedef int scope_id;
+  typedef size_t context_id;
+
+  class
+  scope_id_cache
+  {
+  protected:
+
+    typedef std::set<scope_id>::iterator set_iterator;
+    typedef std::set<scope_id>::const_iterator set_const_iterator;
+
+    // We start with 2 because we allocate 0 for the global symbols
+    // and 1 for the top-level workspace.
+
+    scope_id_cache (void) : next_available (2), in_use (), free_list () { }
+
+  public:
+
+    ~scope_id_cache (void) { }
+
+    static scope_id alloc (void)
+    {
+      return instance_ok () ? instance->do_alloc () : -1;
+    }
+
+    static void free (scope_id scope)
+    {
+      if (instance_ok ())
+	return instance->do_free (scope);
+    }
+
+    static std::list<scope_id> scopes (void)
+    {
+      return instance_ok () ? instance->do_scopes () : std::list<scope_id> ();
+    }
+
+    static bool instance_ok (void)
+    {
+      bool retval = true;
+
+      if (! instance)
+	instance = new scope_id_cache ();
+
+      if (! instance)
+	{
+	  ::error ("unable to create scope_id_cache object!");
+
+	  retval = false;
+	}
+
+      return retval;
+    }
+
+  private:
+
+    static scope_id_cache *instance;
+
+    // The next available scope not in the free list.
+    scope_id next_available;
+
+    // The set of scope IDs that are currently allocated.
+    std::set<scope_id> in_use;
+
+    // The set of scope IDs that are currently available.
+    std::set<scope_id> free_list;
+
+    scope_id do_alloc (void)
+    {
+      scope_id retval;
+
+      set_iterator p = free_list.begin ();
+
+      if (p != free_list.end ())
+	{
+	  retval = *p;
+	  free_list.erase (p);
+	}
+      else
+	retval = next_available++;
+
+      in_use.insert (retval);
+
+      return retval;
+    }
+
+    void do_free (scope_id scope)
+    {
+      set_iterator p = in_use.find (scope);
+
+      if (p != in_use.end ())
+	{
+	  in_use.erase (p);
+	  free_list.insert (scope);
+	}
+      else
+	error ("free_scope: scope %d not found!", scope);
+    }
+
+    std::list<scope_id> do_scopes (void) const
+    {
+      std::list<scope_id> retval;
+
+      for (set_const_iterator p = in_use.begin (); p != in_use.end (); p++)
+	retval.push_back (*p);
+
+      retval.sort ();
+
+      return retval;
+    }
+  };
+
+  class
+  symbol_record
+  {
+  public:
+
+    // generic variable
+    static const unsigned int local = 1;
+
+    // varargin, argn, .nargin., .nargout.
+    // (FIXME -- is this really used now?)
+    static const unsigned int automatic = 2;
+
+    // formal parameter
+    static const unsigned int formal = 4;
+
+    // not listed or cleared (.nargin., .nargout.)
+    static const unsigned int hidden = 8;
+
+    // inherited from parent scope; not cleared at function exit
+    static const unsigned int inherited = 16;
+
+    // global (redirects to global scope)
+    static const unsigned int global = 32;
+
+    // not cleared at function exit
+    static const unsigned int persistent = 64;
+
+    // temporary variables forced into symbol table for parsing
+    static const unsigned int forced = 128;
+
+  private:
+
+    class
+    symbol_record_rep
+    {
+    public:
+
+      symbol_record_rep (const std::string& nm, const octave_value& v,
+			 unsigned int sc)
+	: name (nm), value_stack (), storage_class (sc), count (1)
+      {
+	value_stack.push_back (v);
+      }
+
+      void force_variable (context_id context)
+      {
+	octave_value& val = varref (context);
+
+	if (! val.is_defined ())
+	  mark_forced ();
+      }
+
+      octave_value& varref (context_id context)
+      {
+	if (is_global ())
+	  return symbol_table::global_varref (name);
+	else if (is_persistent ())
+	  return symbol_table::persistent_varref (name);
+	else
+	  {
+	    context_id n = value_stack.size ();
+	    while (n++ <= context)
+	      value_stack.push_back (octave_value ());
+
+	    return value_stack[context];
+	  }
+      }
+
+      octave_value varval (context_id context) const
+      {
+	if (is_global ())
+	  return symbol_table::global_varval (name);
+	else if (is_persistent ())
+	  return symbol_table::persistent_varval (name);
+	else
+	  {
+	    if (context < value_stack.size ())
+	      return value_stack[context];
+	    else
+	      return octave_value ();
+	  }
+      }
+
+      void push_context (void)
+      {
+	if (! (is_persistent () || is_global ()))
+	  value_stack.push_back (octave_value ());
+      }
+
+      // If pop_context returns 0, we are out of values and this element
+      // of the symbol table should be deleted.  This can happen for
+      // functions like
+      //
+      //   function foo (n)
+      //     if (n > 0)
+      //       foo (n-1);
+      //     else
+      //       eval ("x = 1");
+      //     endif
+      //   endfunction
+      //
+      // Here, X should only exist in the final stack frame.
+
+      size_t pop_context (void)
+      {
+	size_t retval = 1;
+
+	if (! (is_persistent () || is_global ()))
+	  {
+	    value_stack.pop_back ();
+	    retval = value_stack.size ();
+	  }
+
+	return retval;
+      }
+
+      void clear (void)
+      {
+	if (! (is_hidden () || is_inherited ()))
+	  {
+	    if (is_global ())
+	      unmark_global ();
+
+	    if (is_persistent ())
+	      {
+		symbol_table::persistent_varref (name)
+		  = varval (xcurrent_context);
+
+		unmark_persistent ();
+	      }
+
+	    varref (xcurrent_context) = octave_value ();
+	  }
+      }
+
+      bool is_defined (context_id context) const
+      {
+	return varval (context).is_defined ();
+      }
+
+      bool is_variable (context_id context) const
+      {
+	return (! is_local () || is_defined (context) || is_forced ());
+      }
+
+      bool is_local (void) const { return storage_class & local; }
+      bool is_automatic (void) const { return storage_class & automatic; }
+      bool is_formal (void) const { return storage_class & formal; }
+      bool is_hidden (void) const { return storage_class & hidden; }
+      bool is_inherited (void) const { return storage_class & inherited; }
+      bool is_global (void) const { return storage_class & global; }
+      bool is_persistent (void) const { return storage_class & persistent; }
+      bool is_forced (void) const { return storage_class & forced; }
+
+      void mark_local (void) { storage_class |= local; }
+      void mark_automatic (void) { storage_class |= automatic; }
+      void mark_formal (void) { storage_class |= formal; }
+      void mark_hidden (void) { storage_class |= hidden; }
+      void mark_inherited (void) { storage_class |= inherited; }
+      void mark_global (void)
+      {
+	if (is_persistent ())
+	  error ("can't make persistent variable %s global", name.c_str ());
+	else
+	  storage_class |= global;
+      }
+      void mark_persistent (void)
+      {
+	if (is_global ())
+	  error ("can't make global variable %s persistent", name.c_str ());
+	else
+	  storage_class |= persistent;
+      }
+      void mark_forced (void) { storage_class |= forced; }
+
+      void unmark_local (void) { storage_class &= ~local; }
+      void unmark_automatic (void) { storage_class &= ~automatic; }
+      void unmark_formal (void) { storage_class &= ~formal; }
+      void unmark_hidden (void) { storage_class &= ~hidden; }
+      void unmark_inherited (void) { storage_class &= ~inherited; }
+      void unmark_global (void) { storage_class &= ~global; }
+      void unmark_persistent (void) { storage_class &= ~persistent; }
+      void unmark_forced (void) { storage_class &= ~forced; }
+
+      void init_persistent (void)
+      {
+	if (! is_defined (xcurrent_context))
+	  {
+	    mark_persistent ();
+
+	    varref (xcurrent_context) = symbol_table::persistent_varval (name);
+	  }
+	// FIXME -- this causes trouble with recursive calls.
+	// else
+	//   error ("unable to declare existing variable persistent");
+      }
+
+      void erase_persistent (void)
+      {
+	unmark_persistent ();
+	symbol_table::erase_persistent (name);
+      }
+
+      symbol_record_rep *dup (void) const
+      {
+	return new symbol_record_rep (name, varval (xcurrent_context),
+				      storage_class);
+      }
+
+      void dump (std::ostream& os, const std::string& prefix) const;
+
+      std::string name;
+
+      std::deque<octave_value> value_stack;
+
+      unsigned int storage_class;
+
+      size_t count;
+
+    private:
+
+      // No copying!
+
+      symbol_record_rep (const symbol_record_rep& ov);
+
+      symbol_record_rep& operator = (const symbol_record_rep&);
+    };
+
+  public:
+
+    symbol_record (const std::string& nm = std::string (),
+		   const octave_value& v = octave_value (),
+		   unsigned int sc = local)
+      : rep (new symbol_record_rep (nm, v, sc)) { }
+
+    symbol_record (const symbol_record& sr)
+      : rep (sr.rep)
+    { 
+      rep->count++;
+    }
+
+    symbol_record& operator = (const symbol_record& sr)
+    {
+      if (this != &sr)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = sr.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+    ~symbol_record (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+    symbol_record dup (void) const { return symbol_record (rep->dup ()); }
+
+    std::string name (void) const { return rep->name; }
+
+    octave_value
+    find (tree_argument_list *args, const string_vector& arg_names,
+	  octave_value_list& evaluated_args, bool& args_evaluated) const;
+
+    void force_variable (context_id context = xcurrent_context)
+    {
+      rep->force_variable (context);
+    }
+
+    octave_value& varref (context_id context = xcurrent_context)
+    {
+      return rep->varref (context);
+    }
+
+    octave_value varval (context_id context = xcurrent_context) const
+    {
+      return rep->varval (context);
+    }
+
+    void push_context (void) { rep->push_context (); }
+
+    size_t pop_context (void) { return rep->pop_context (); }
+
+    void clear (void) { rep->clear (); }
+
+    bool is_defined (context_id context = xcurrent_context) const
+    {
+      return rep->is_defined (context);
+    }
+
+    bool is_variable (context_id context = xcurrent_context) const
+    {
+      return rep->is_variable (context);
+    }
+
+    bool is_local (void) const { return rep->is_local (); }
+    bool is_automatic (void) const { return rep->is_automatic (); }
+    bool is_formal (void) const { return rep->is_formal (); }
+    bool is_global (void) const { return rep->is_global (); }
+    bool is_hidden (void) const { return rep->is_hidden (); }
+    bool is_inherited (void) const { return rep->is_inherited (); }
+    bool is_persistent (void) const { return rep->is_persistent (); }
+    bool is_forced (void) const { return rep->is_forced (); }
+
+    void mark_local (void) { rep->mark_local (); }
+    void mark_automatic (void) { rep->mark_automatic (); }
+    void mark_formal (void) { rep->mark_formal (); }
+    void mark_hidden (void) { rep->mark_hidden (); }
+    void mark_inherited (void) { rep->mark_inherited (); }
+    void mark_global (void) { rep->mark_global (); }
+    void mark_persistent (void) { rep->mark_persistent (); }
+    void mark_forced (void) { rep->mark_forced (); }
+
+    void unmark_local (void) { rep->unmark_local (); }
+    void unmark_automatic (void) { rep->unmark_automatic (); }
+    void unmark_formal (void) { rep->unmark_formal (); }
+    void unmark_hidden (void) { rep->unmark_hidden (); }
+    void unmark_inherited (void) { rep->unmark_inherited (); }
+    void unmark_global (void) { rep->unmark_global (); }
+    void unmark_persistent (void) { rep->unmark_persistent (); }
+    void unmark_forced (void) { rep->unmark_forced (); }
+
+    void init_persistent (void) { rep->init_persistent (); }
+
+    void erase_persistent (void) { rep->erase_persistent (); }
+
+    unsigned int xstorage_class (void) const { return rep->storage_class; }
+
+    void
+    dump (std::ostream& os, const std::string& prefix = std::string ()) const
+    {
+      rep->dump (os, prefix);
+    }
+
+  private:
+
+    symbol_record_rep *rep;
+
+    symbol_record (symbol_record_rep *new_rep) : rep (new_rep) { }
+  };
+
+  class
+  fcn_info
+  {
+  public:
+
+    typedef std::map<std::string, std::string> dispatch_map_type;
+
+    typedef std::map<scope_id, octave_value>::const_iterator scope_val_const_iterator;
+    typedef std::map<scope_id, octave_value>::iterator scope_val_iterator;
+
+    typedef std::map<std::string, octave_value>::const_iterator str_val_const_iterator;
+    typedef std::map<std::string, octave_value>::iterator str_val_iterator;
+
+    typedef dispatch_map_type::const_iterator dispatch_map_const_iterator;
+    typedef dispatch_map_type::iterator dispatch_map_iterator;
+
+  private:
+
+    class
+    fcn_info_rep
+    {
+    public:
+
+      fcn_info_rep (const std::string& nm)
+	: name (nm), subfunctions (), private_functions (),
+	  class_constructors (), class_methods (), cmdline_function (),
+	  autoload_function (), function_on_path (), built_in_function (),
+	  count (1) { }
+
+      octave_value load_private_function (const std::string& dir_name);
+
+      octave_value load_class_constructor (void);
+
+      octave_value load_class_method (const std::string& dispatch_type);
+
+      octave_value
+      find (tree_argument_list *args, const string_vector& arg_names,
+	    octave_value_list& evaluated_args, bool& args_evaluated);
+
+      octave_value find_method (const std::string& dispatch_type);
+
+      octave_value find_autoload (void);
+
+      octave_value find_user_function (void);
+
+      bool is_user_function_defined (void) const
+      {
+	return function_on_path.is_defined ();
+      }
+
+      octave_value find_function (void)
+      {
+	octave_value_list args;
+
+	return find_function (args);
+      }
+
+      octave_value find_function (const octave_value_list& args)
+      {
+	string_vector arg_names;
+	octave_value_list evaluated_args = args;
+	bool args_evaluated = false;
+
+	return find (0, arg_names, evaluated_args, args_evaluated);
+      }
+
+      void lock_subfunction (scope_id scope)
+      {
+	scope_val_iterator p = subfunctions.find (scope);
+
+	if (p != subfunctions.end ())
+	  p->second.lock ();
+      }
+
+      void unlock_subfunction (scope_id scope)
+      {
+	scope_val_iterator p = subfunctions.find (scope);
+
+	if (p != subfunctions.end ())
+	  p->second.unlock ();
+      }
+
+      std::pair<std::string, octave_value>
+      subfunction_defined_in_scope (scope_id scope) const
+      {
+	scope_val_const_iterator p = subfunctions.find (scope);
+
+	return p == subfunctions.end ()
+	  ? std::pair<std::string, octave_value> ()
+	  : std::pair<std::string, octave_value> (name, p->second);
+      }	     
+
+      void erase_subfunction (scope_id scope)
+      {
+	scope_val_iterator p = subfunctions.find (scope);
+
+	if (p != subfunctions.end ())
+	  subfunctions.erase (p);
+      }
+
+      void install_cmdline_function (const octave_value& f)
+      {
+	cmdline_function = f;
+      }
+
+      void install_subfunction (const octave_value& f, scope_id scope)
+      {
+	subfunctions[scope] = f;
+      }
+
+      void install_user_function (const octave_value& f)
+      {
+	function_on_path = f;
+      }
+
+      void install_built_in_function (const octave_value& f)
+      {
+	built_in_function = f;
+      }
+
+      template <class T>
+      void
+      clear_unlocked (std::map<T, octave_value>& map)
+      {
+	typename std::map<T, octave_value>::iterator p = map.begin ();
+
+	while (p != map.end ())
+	  {
+	    if (p->second.islocked ())
+	      p++;
+	    else
+	      map.erase (p++);
+	  }
+      }
+
+      void clear_cmdline_function (void)
+      {
+	if (! cmdline_function.islocked ())
+	  cmdline_function = octave_value ();
+      }
+
+      void clear_autoload_function (void)
+      {
+	if (! autoload_function.islocked ())
+	  autoload_function = octave_value ();
+      }
+
+      // FIXME -- should this also clear the cmdline and other "user
+      // defined" functions?
+      void clear_user_function (void)
+      {
+	if (! function_on_path.islocked ())
+	  {
+	    function_on_path.erase_subfunctions ();
+
+	    function_on_path = octave_value ();
+	  }
+      }
+
+      void clear_mex_function (void)
+      {
+	if (function_on_path.is_mex_function ())
+	  clear_user_function ();
+      }
+
+      void clear (void)
+      {
+	clear_unlocked (subfunctions);
+	clear_unlocked (private_functions);
+	clear_unlocked (class_constructors);
+	clear_unlocked (class_methods);
+	clear_cmdline_function ();
+	clear_autoload_function ();
+	clear_user_function ();
+      }
+
+      void add_dispatch (const std::string& type, const std::string& fname)
+      {
+	dispatch_map[type] = fname;
+      }
+
+      void clear_dispatch (const std::string& type)
+      {
+	dispatch_map_iterator p = dispatch_map.find (type);
+
+	if (p != dispatch_map.end ())
+	  dispatch_map.erase (p);
+      }
+
+      void print_dispatch (std::ostream& os) const;
+
+      std::string help_for_dispatch (void) const;
+
+      dispatch_map_type get_dispatch (void) const { return dispatch_map; }
+
+      void dump (std::ostream& os, const std::string& prefix) const;
+
+      std::string name;
+
+      // Scope id to function object.
+      std::map<scope_id, octave_value> subfunctions;
+
+      // Directory name to function object.
+      std::map<std::string, octave_value> private_functions;
+
+      // Class name to function object.
+      std::map<std::string, octave_value> class_constructors;
+
+      // Dispatch type to function object.
+      std::map<std::string, octave_value> class_methods;
+
+      // Legacy dispatch map (dispatch type name to function name).
+      dispatch_map_type dispatch_map;
+
+      octave_value cmdline_function;
+
+      octave_value autoload_function;
+
+      octave_value function_on_path;
+
+      octave_value built_in_function;
+
+      size_t count;
+
+    private:
+
+      octave_value
+      xfind (tree_argument_list *args, const string_vector& arg_names,
+	     octave_value_list& evaluated_args, bool& args_evaluated);
+
+      // No copying!
+
+      fcn_info_rep (const fcn_info_rep&);
+
+      fcn_info_rep& operator = (const fcn_info_rep&);
+    };
+
+  public:
+
+    fcn_info (const std::string& nm = std::string ())
+      : rep (new fcn_info_rep (nm)) { }
+
+    fcn_info (const fcn_info& fi) : rep (fi.rep)
+    { 
+      rep->count++;
+    }
+
+    fcn_info& operator = (const fcn_info& fi)
+    {
+      if (this != &fi)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = fi.rep;
+	  rep->count++;
+	}
+
+      return *this;
+    }
+
+    ~fcn_info (void)
+    {
+      if (--rep->count == 0)
+	delete rep;
+    }
+
+    octave_value
+    find (tree_argument_list *args, const string_vector& arg_names,
+	  octave_value_list& evaluated_args, bool& args_evaluated);
+
+    octave_value find_method (const std::string& dispatch_type) const
+    {
+      return rep->find_method (dispatch_type);
+    }
+
+    octave_value find_built_in_function (void) const
+    {
+      return rep->built_in_function;
+    }
+
+    octave_value find_autoload (void)
+    {
+      return rep->find_autoload ();
+    }
+
+    octave_value find_user_function (void)
+    {
+      return rep->find_user_function ();
+    }
+
+    bool is_user_function_defined (void) const
+    {
+      return rep->is_user_function_defined ();
+    }
+
+    octave_value find_function (void)
+    {
+      return rep->find_function ();
+    }
+
+    octave_value find_function (const octave_value_list& args)
+    {
+      return rep->find_function (args);
+    }
+
+    void lock_subfunction (scope_id scope)
+    {
+      rep->lock_subfunction (scope);
+    }
+
+    void unlock_subfunction (scope_id scope)
+    {
+      rep->unlock_subfunction (scope);
+    }
+
+    std::pair<std::string, octave_value>
+    subfunction_defined_in_scope (scope_id scope = xcurrent_scope) const
+    {
+      return rep->subfunction_defined_in_scope (scope);
+    }	     
+
+    void erase_subfunction (scope_id scope)
+    {
+      rep->erase_subfunction (scope);
+    }
+
+    void install_cmdline_function (const octave_value& f)
+    {
+      rep->install_cmdline_function (f);
+    }
+
+    void install_subfunction (const octave_value& f, scope_id scope)
+    {
+      rep->install_subfunction (f, scope);
+    }
+
+    void install_user_function (const octave_value& f)
+    {
+      rep->install_user_function (f);
+    }
+
+    void install_built_in_function (const octave_value& f)
+    {
+      rep->install_built_in_function (f);
+    }
+
+    void clear (void) { rep->clear (); }
+
+    void clear_user_function (void) { rep->clear_user_function (); }
+    
+    void clear_mex_function (void) { rep->clear_mex_function (); }
+
+    void add_dispatch (const std::string& type, const std::string& fname)
+    {
+      rep->add_dispatch (type, fname);
+    }
+
+    void clear_dispatch (const std::string& type)
+    {
+      rep->clear_dispatch (type);
+    }
+
+    void print_dispatch (std::ostream& os) const
+    {
+      rep->print_dispatch (os);
+    }
+
+    std::string help_for_dispatch (void) const { return rep->help_for_dispatch (); }
+
+    dispatch_map_type get_dispatch (void) const
+    {
+      return rep->get_dispatch ();
+    }
+
+    void
+    dump (std::ostream& os, const std::string& prefix = std::string ()) const
+    {
+      rep->dump (os, prefix);
+    }
+
+  private:
+
+    fcn_info_rep *rep;
+  };
+
+  static scope_id global_scope (void) { return xglobal_scope; }
+  static scope_id top_scope (void) { return xtop_scope; }
+
+  static scope_id current_scope (void) { return xcurrent_scope; }
+
+  static context_id current_context (void) { return xcurrent_context; }
+
+  // We use parent_scope to handle parsing subfunctions.
+  static scope_id parent_scope (void) { return xparent_scope; }
+
+  static scope_id alloc_scope (void) { return scope_id_cache::alloc (); }
+
+  static void set_scope (scope_id scope)
+  {
+    if (scope == xglobal_scope)
+      error ("can't set scope to global");
+    else if (scope != xcurrent_scope)
+      {
+	all_instances_iterator p = all_instances.find (scope);
+
+	if (p == all_instances.end ())
+	  {
+	    symbol_table *inst = new symbol_table ();
+
+	    if (inst)
+	      all_instances[scope] = instance = inst;
+	  }
+	else
+	  instance = p->second;
+
+	xcurrent_scope = scope;
+	xcurrent_context = 0;
+      }
+  }
+
+  static void set_scope_and_context (scope_id scope, context_id context)
+  {
+    if (scope == xglobal_scope)
+      error ("can't set scope to global");
+    else
+      {
+	if (scope != xcurrent_scope)
+	  {
+	    all_instances_iterator p = all_instances.find (scope);
+
+	    if (p == all_instances.end ())
+	      error ("scope not found!");
+	    else
+	      {
+		instance = p->second;
+
+		xcurrent_scope = scope;
+
+                xcurrent_context = context;
+	      }
+	  }
+        else
+          xcurrent_context = context;
+      }
+  }
+
+  static void set_parent_scope (scope_id scope)
+  {
+    xparent_scope = scope;
+  }
+
+  static void reset_parent_scope (void)
+  {
+    set_parent_scope (-1);
+  }
+
+  static void erase_scope (void *ptr)
+  {
+    scope_id *pscope = static_cast<scope_id *> (ptr);
+
+    erase_scope (*pscope);
+  }
+
+  static void erase_scope (scope_id scope)
+  {
+    assert (scope != xglobal_scope);
+
+    all_instances_iterator p = all_instances.find (scope);
+
+    if (p != all_instances.end ())
+      {
+	delete p->second;
+
+	all_instances.erase (p);
+
+	free_scope (scope);
+      }
+  }
+
+  static void erase_subfunctions_in_scope (scope_id scope)
+  {
+    for (fcn_table_iterator q = fcn_table.begin ();
+	 q != fcn_table.end (); q++)
+      q->second.erase_subfunction (scope);
+  }
+
+  static scope_id dup_scope (scope_id scope)
+  {
+    scope_id retval = -1;
+
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      {
+	scope_id new_scope = alloc_scope ();
+
+	symbol_table *new_symbol_table = new symbol_table ();
+
+	if (new_symbol_table)
+	  {
+	    all_instances[new_scope] = new_symbol_table;
+
+	    inst->do_dup_scope (*new_symbol_table);
+
+	    retval = new_scope;
+	  }
+      }
+
+    return retval;
+  }
+
+  static std::list<scope_id> scopes (void)
+  {
+    return scope_id_cache::scopes ();
+  }
+
+  static symbol_record
+  find_symbol (const std::string& name, scope_id scope = xcurrent_scope)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    return inst ? inst->do_find_symbol (name) : symbol_record ();
+  }
+
+  static void
+  inherit (scope_id scope, scope_id donor_scope, context_id donor_context)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      {
+	symbol_table *donor_symbol_table = get_instance (donor_scope);
+
+	if (donor_symbol_table)
+	  inst->do_inherit (*donor_symbol_table, donor_context);
+      }
+  }
+
+  static bool at_top_level (void) { return xcurrent_scope == xtop_scope; }
+
+  // Find a value corresponding to the given name in the table.
+  static octave_value
+  find (const std::string& name, tree_argument_list *args,
+	const string_vector& arg_names,
+	octave_value_list& evaluated_args, bool& args_evaluated,
+	bool skip_variables = false);
+
+  // Insert a new name in the table.
+  static symbol_record& insert (const std::string& name)
+  {
+    static symbol_record foobar;
+
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_insert (name) : foobar;
+  }
+
+  static void force_variable (const std::string& name,
+			      scope_id scope = xcurrent_scope,
+			      context_id context = xcurrent_context)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      inst->do_force_variable (name, context);
+  }
+
+  static octave_value& varref (const std::string& name,
+			       scope_id scope = xcurrent_scope,
+			       context_id context = xcurrent_context)
+  {
+    static octave_value foobar;
+
+    symbol_table *inst = get_instance (scope);
+
+    return inst ? inst->do_varref (name, context) : foobar;
+  }
+
+  static octave_value varval (const std::string& name,
+			      scope_id scope = xcurrent_scope,
+			      context_id context = xcurrent_context)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    return inst ? inst->do_varval (name, context) : octave_value ();
+  }
+
+  static octave_value&
+  global_varref (const std::string& name)
+  {
+    global_table_iterator p = global_table.find (name);
+
+    return (p == global_table.end ()) ? global_table[name] : p->second;
+  }
+
+  static octave_value
+  global_varval (const std::string& name)
+  {
+    global_table_const_iterator p = global_table.find (name);
+
+    return (p != global_table.end ()) ? p->second : octave_value ();
+  }
+
+  static octave_value& persistent_varref (const std::string& name)
+  {
+    static octave_value foobar;
+
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_persistent_varref (name) : foobar;
+  }
+
+  static octave_value persistent_varval (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_persistent_varval (name) : octave_value ();
+  }
+
+  static void erase_persistent (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_erase_persistent (name);
+  }
+
+  static bool is_variable (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_is_variable (name) : false;
+  }
+
+  static bool
+  is_built_in_function_name (const std::string& name)
+  {
+    octave_value val = find_built_in_function (name);
+
+    return val.is_defined ();
+  }
+
+  static octave_value
+  find_method (const std::string& name, const std::string& dispatch_type)
+  {
+    fcn_table_const_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      return p->second.find_method (dispatch_type);
+    else
+      {
+	fcn_info finfo (name);
+
+	octave_value fcn = finfo.find_method (dispatch_type);
+
+	if (fcn.is_defined ())
+	  fcn_table[name] = finfo;
+
+	return fcn;
+      }
+  }
+
+  static octave_value
+  find_built_in_function (const std::string& name)
+  {
+    fcn_table_const_iterator p = fcn_table.find (name);
+
+    return (p != fcn_table.end ())
+      ? p->second.find_built_in_function () : octave_value ();
+  }
+
+  static octave_value
+  find_autoload (const std::string& name)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    return (p != fcn_table.end ())
+      ? p->second.find_autoload () : octave_value ();
+  }
+
+  static octave_value
+  find_function (const std::string& name, tree_argument_list *args,
+		 const string_vector& arg_names,
+		 octave_value_list& evaluated_args, bool& args_evaluated);
+
+  static octave_value find_user_function (const std::string& name)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    return (p != fcn_table.end ())
+      ? p->second.find_user_function () : octave_value ();
+  }
+
+  static octave_value find_function (const std::string& name)
+  {
+    octave_value_list evaluated_args;
+
+    return find_function (name, evaluated_args);
+  }
+
+  static octave_value
+  find_function (const std::string& name, const octave_value_list& args)
+  {
+    string_vector arg_names;
+    octave_value_list evaluated_args = args;
+    bool args_evaluated = ! args.empty ();
+
+    return find_function (name, 0, arg_names, evaluated_args, args_evaluated);
+  }
+
+  static void install_cmdline_function (const std::string& name,
+					const octave_value& fcn)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.install_cmdline_function (fcn);
+      }
+    else
+      {
+	fcn_info finfo (name);
+
+	finfo.install_cmdline_function (fcn);
+
+	fcn_table[name] = finfo;
+      }
+  }
+
+  static void install_subfunction (const std::string& name,
+				   const octave_value& fcn,
+				   scope_id scope = xparent_scope)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.install_subfunction (fcn, scope);
+      }
+    else
+      {
+	fcn_info finfo (name);
+
+	finfo.install_subfunction (fcn, scope);
+
+	fcn_table[name] = finfo;
+      }
+  }
+
+  static void install_user_function (const std::string& name,
+				     const octave_value& fcn)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.install_user_function (fcn);
+      }
+    else
+      {
+	fcn_info finfo (name);
+
+	finfo.install_user_function (fcn);
+
+	fcn_table[name] = finfo;
+      }
+  }
+
+  static void install_built_in_function (const std::string& name,
+					 const octave_value& fcn)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.install_built_in_function (fcn);
+      }
+    else
+      {
+	fcn_info finfo (name);
+
+	finfo.install_built_in_function (fcn);
+
+	fcn_table[name] = finfo;
+      }
+  }
+
+  static void clear (const std::string& name)
+  {
+    clear_variable (name);
+  }
+
+  static void clear_all (void)
+  {
+    clear_variables ();
+
+    clear_functions ();
+  }
+
+  static void clear_variables (scope_id scope = xcurrent_scope)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      inst->do_clear_variables ();
+  }
+
+  static void clear_objects (scope_id scope = xcurrent_scope)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      inst->do_clear_objects ();
+  }
+
+  static void unmark_forced_variables (scope_id scope = xcurrent_scope)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      inst->do_unmark_forced_variables ();
+  }
+
+  // For unwind_protect.
+  static void unmark_forced_variables (void *arg)
+  {
+    // Unmark any symbols that may have been tagged as local variables
+    // while parsing (for example, by force_local_variable in lex.l).
+
+    symbol_table::scope_id *p = static_cast <symbol_table::scope_id *> (arg);
+
+  if (p)
+    unmark_forced_variables (*p);
+}
+
+
+  // For unwind_protect.
+  static void clear_variables (void *) { clear_variables (); }
+
+  static void clear_functions (void)
+  {
+    for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
+      p->second.clear ();
+  }
+
+  static void clear_function (const std::string& name)
+  {
+    clear_user_function (name);
+  }
+
+  static void clear_global (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_clear_global (name);
+  }
+
+  static void clear_variable (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_clear_variable (name);
+  }
+
+  static void clear_symbol (const std::string& name)
+  {
+    // FIXME -- are we supposed to do both here?
+
+    clear_variable (name);
+    clear_function (name);
+  }
+
+  static void clear_function_pattern (const std::string& pat)
+  {
+    glob_match pattern (pat);
+
+    for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
+      {
+	if (pattern.match (p->first))
+	  p->second.clear_user_function ();
+      }
+  }
+
+  static void clear_global_pattern (const std::string& pat)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_clear_global_pattern (pat);
+  }
+
+  static void clear_variable_pattern (const std::string& pat)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_clear_variable_pattern (pat);
+  }
+
+  static void clear_variable_regexp (const std::string& pat)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_clear_variable_regexp (pat);
+  }
+
+  static void clear_symbol_pattern (const std::string& pat)
+  {
+    // FIXME -- are we supposed to do both here?
+
+    clear_variable_pattern (pat);
+    clear_function_pattern (pat);
+  }
+
+  static void clear_user_function (const std::string& name)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.clear_user_function ();
+      }
+    // FIXME -- is this necessary, or even useful?
+    // else
+    //   error ("clear: no such function `%s'", name.c_str ());
+  }
+
+  static void clear_mex_functions (void)
+  {
+    for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.clear_mex_function ();
+      }
+  }
+
+  static bool set_class_relationship (const std::string& sup_class,
+				      const std::string& inf_class);
+
+  static bool is_superiorto (const std::string& a, const std::string& b);
+    
+  static void alias_built_in_function (const std::string& alias,
+				       const std::string& name)
+  {
+    octave_value fcn = find_built_in_function (name);
+
+    if (fcn.is_defined ())
+      {
+	fcn_info finfo (alias);
+
+	finfo.install_built_in_function (fcn);
+
+	fcn_table[alias] = finfo;
+      }
+    else
+      panic ("alias: `%s' is undefined", name.c_str ());
+  }
+
+  static void add_dispatch (const std::string& name, const std::string& type,
+			    const std::string& fname)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.add_dispatch (type, fname);
+      }
+    else
+      {
+	fcn_info finfo (name);
+
+	finfo.add_dispatch (type, fname);
+
+	fcn_table[name] = finfo;
+      }
+  }
+
+  static void clear_dispatch (const std::string& name, const std::string& type)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.clear_dispatch (type);
+      }
+  }
+
+  static void print_dispatch (std::ostream& os, const std::string& name)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	finfo.print_dispatch (os);
+      }
+  }
+
+  static fcn_info::dispatch_map_type get_dispatch (const std::string& name)
+  {
+    fcn_info::dispatch_map_type retval;
+
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	retval = finfo.get_dispatch ();
+      }
+
+    return retval;
+  }
+
+  static std::string help_for_dispatch (const std::string& name)
+  {
+    std::string retval;
+
+    fcn_table_iterator p = fcn_table.find (name);
+
+    if (p != fcn_table.end ())
+      {
+	fcn_info& finfo = p->second;
+
+	retval = finfo.help_for_dispatch ();
+      }
+
+    return retval;
+  }
+
+  static void push_context (void)
+  {
+    if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope)
+      error ("invalid call to xymtab::push_context");
+    else
+      {
+	symbol_table *inst = get_instance (xcurrent_scope);
+
+	if (inst)
+	  inst->do_push_context ();
+      }
+  }
+
+  static void pop_context (void)
+  {
+    if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope)
+      error ("invalid call to xymtab::pop_context");
+    else
+      {
+	symbol_table *inst = get_instance (xcurrent_scope);
+
+	if (inst)
+	  inst->do_pop_context ();
+      }
+  }
+
+  // For unwind_protect.
+  static void pop_context (void *) { pop_context (); }
+
+  static void mark_hidden (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_mark_hidden (name);
+  }
+
+  static void mark_global (const std::string& name)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    if (inst)
+      inst->do_mark_global (name);
+  }
+
+  static std::list<symbol_record>
+  all_variables (scope_id scope = xcurrent_scope,
+		 context_id context = xcurrent_context,
+		 bool defined_only = true)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    return inst
+      ? inst->do_all_variables (context, defined_only) : std::list<symbol_record> ();
+  }
+
+  static std::list<symbol_record> glob (const std::string& pattern)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_glob (pattern) : std::list<symbol_record> ();
+  }
+
+  static std::list<symbol_record> regexp (const std::string& pattern)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_regexp (pattern) : std::list<symbol_record> ();
+  }
+
+  static std::list<symbol_record> glob_variables (const std::string& pattern)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_glob (pattern, true) : std::list<symbol_record> ();
+  }
+
+  static std::list<symbol_record> regexp_variables (const std::string& pattern)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_regexp (pattern, true) : std::list<symbol_record> ();
+  }
+
+  static std::list<symbol_record>
+  glob_global_variables (const std::string& pattern)
+  {
+    std::list<symbol_record> retval;
+
+    glob_match pat (pattern);
+
+    for (global_table_const_iterator p = global_table.begin ();
+	 p != global_table.end (); p++)
+      {
+	// We generate a list of symbol_record objects so that
+	// the results from glob_variables and glob_global_variables
+	// may be handled the same way.
+
+	if (pat.match (p->first))
+	  retval.push_back (symbol_record (p->first, p->second,
+					   symbol_record::global));
+      }
+
+    return retval;
+  }
+
+  static std::list<symbol_record>
+  regexp_global_variables (const std::string& pattern)
+  {
+    std::list<symbol_record> retval;
+
+    regex_match pat (pattern);
+
+    for (global_table_const_iterator p = global_table.begin ();
+	 p != global_table.end (); p++)
+      {
+	// We generate a list of symbol_record objects so that
+	// the results from regexp_variables and regexp_global_variables
+	// may be handled the same way.
+
+	if (pat.match (p->first))
+	  retval.push_back (symbol_record (p->first, p->second,
+					   symbol_record::global));
+      }
+
+    return retval;
+  }
+
+  static std::list<symbol_record> glob_variables (const string_vector& patterns)
+  {
+    std::list<symbol_record> retval;
+
+    size_t len = patterns.length ();
+
+    for (size_t i = 0; i < len; i++)
+      {
+	std::list<symbol_record> tmp = glob_variables (patterns[i]);
+
+	retval.insert (retval.begin (), tmp.begin (), tmp.end ());
+      }
+
+    return retval;
+  }
+
+  static std::list<symbol_record> regexp_variables 
+    (const string_vector& patterns)
+  {
+    std::list<symbol_record> retval;
+
+    size_t len = patterns.length ();
+
+    for (size_t i = 0; i < len; i++)
+      {
+	std::list<symbol_record> tmp = regexp_variables (patterns[i]);
+
+	retval.insert (retval.begin (), tmp.begin (), tmp.end ());
+      }
+
+    return retval;
+  }
+
+  static std::list<std::string> user_function_names (void)
+  {
+    std::list<std::string> retval;
+
+    for (fcn_table_iterator p = fcn_table.begin ();
+	 p != fcn_table.end (); p++)
+      {
+	if (p->second.is_user_function_defined ())
+	  retval.push_back (p->first);
+      }
+
+    if (! retval.empty ())
+      retval.sort ();
+
+    return retval;
+  }
+
+  static std::list<std::string> global_variable_names (void)
+  {
+    std::list<std::string> retval;
+
+    for (global_table_const_iterator p = global_table.begin ();
+	 p != global_table.end (); p++)
+      retval.push_back (p->first);
+
+    retval.sort ();
+
+    return retval;
+  }
+
+  static std::list<std::string> top_level_variable_names (void)
+  {
+    symbol_table *inst = get_instance (xtop_scope);
+
+    return inst ? inst->do_variable_names () : std::list<std::string> ();
+  }
+
+  static std::list<std::string> variable_names (void)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst ? inst->do_variable_names () : std::list<std::string> ();
+  }
+
+  static std::list<std::string> built_in_function_names (void)
+  {
+    std::list<std::string> retval;
+
+    for (fcn_table_const_iterator p = fcn_table.begin ();
+	 p != fcn_table.end (); p++)
+      {
+	octave_value fcn = p->second.find_built_in_function ();
+
+	if (fcn.is_defined ())
+	  retval.push_back (p->first);
+      }
+
+    if (! retval.empty ())
+      retval.sort ();
+
+    return retval;
+  }
+
+  static bool is_local_variable (const std::string& name)
+  {
+    if (xcurrent_scope == xglobal_scope)
+      return false;
+    else
+      {
+	symbol_table *inst = get_instance (xcurrent_scope);
+
+	return inst ? inst->do_is_local_variable (name) : false;
+      }
+  }
+
+  static bool is_global (const std::string& name)
+  {
+    if (xcurrent_scope == xglobal_scope)
+      return true;
+    else
+      {
+	symbol_table *inst = get_instance (xcurrent_scope);
+
+	return inst ? inst->do_is_global (name) : false;
+      }
+  }
+
+  static void dump (std::ostream& os, scope_id scope = xcurrent_scope);
+
+  static void dump_global (std::ostream& os);
+
+  static void dump_functions (std::ostream& os);
+
+  static void cache_name (scope_id scope, const std::string& name)
+  {
+    symbol_table *inst = get_instance (scope, false);
+
+    if (inst)
+      inst->do_cache_name (name);
+  }
+
+  static void lock_subfunctions (scope_id scope = xcurrent_scope)
+  {
+    for (fcn_table_iterator p = fcn_table.begin ();
+	 p != fcn_table.end (); p++)
+      p->second.lock_subfunction (scope);
+  }    
+
+  static void unlock_subfunctions (scope_id scope = xcurrent_scope)
+  {
+    for (fcn_table_iterator p = fcn_table.begin ();
+	 p != fcn_table.end (); p++)
+      p->second.unlock_subfunction (scope);
+  }    
+
+  static void free_scope (scope_id scope)
+  {
+    if (scope == xglobal_scope || scope == xtop_scope)
+      error ("can't free global or top-level scopes!");
+    else
+      symbol_table::scope_id_cache::free (scope);
+  }
+
+  static void stash_dir_name_for_subfunctions (scope_id scope,
+					       const std::string& dir_name);
+
+private:
+
+  typedef std::map<std::string, symbol_record>::const_iterator table_const_iterator;
+  typedef std::map<std::string, symbol_record>::iterator table_iterator;
+
+  typedef std::map<std::string, octave_value>::const_iterator global_table_const_iterator;
+  typedef std::map<std::string, octave_value>::iterator global_table_iterator;
+
+  typedef std::map<std::string, octave_value>::const_iterator persistent_table_const_iterator;
+  typedef std::map<std::string, octave_value>::iterator persistent_table_iterator;
+
+  typedef std::map<scope_id, symbol_table*>::const_iterator all_instances_const_iterator;
+  typedef std::map<scope_id, symbol_table*>::iterator all_instances_iterator;
+
+  typedef std::map<std::string, fcn_info>::const_iterator fcn_table_const_iterator;
+  typedef std::map<std::string, fcn_info>::iterator fcn_table_iterator;
+
+  // Name for this table (usually the file name of the function
+  // corresponding to the scope);
+  std::string table_name;
+
+  // Map from symbol names to symbol info.
+  std::map<std::string, symbol_record> table;
+
+  // Map from names of global variables to values.
+  static std::map<std::string, octave_value> global_table;
+
+  // Map from names of persistent variables to values.
+  std::map<std::string, octave_value> persistent_table;
+
+  // Pointer to symbol table for current scope (variables only).
+  static symbol_table *instance;
+
+  // Map from scope id to symbol table instances.
+  static std::map<scope_id, symbol_table*> all_instances;
+
+  // Map from function names to function info (subfunctions, private
+  // functions, class constructors, class methods, etc.)
+  static std::map<std::string, fcn_info> fcn_table;
+
+  // Mape from class names to set of classes that have lower
+  // precedence.
+  static std::map<std::string, std::set<std::string> > class_precedence_table;
+
+  typedef std::map<std::string, std::set<std::string> >::const_iterator class_precedence_table_const_iterator;
+  typedef std::map<std::string, std::set<std::string> >::iterator class_precedence_table_iterator;
+
+  static const scope_id xglobal_scope;
+  static const scope_id xtop_scope;
+
+  static scope_id xcurrent_scope;
+
+  // We use parent_scope to handle parsing subfunctions.
+  static scope_id xparent_scope;
+
+  static context_id xcurrent_context;
+
+  symbol_table (void)
+    : table_name (), table () { }
+
+  ~symbol_table (void) { }
+
+  static symbol_table *get_instance (scope_id scope, bool create = true)
+  {
+    symbol_table *retval = 0;
+
+    bool ok = true;
+
+    if (scope != xglobal_scope)
+      {
+	if (scope == xcurrent_scope)
+	  {
+	    if (! instance && create)
+	      {
+		symbol_table *inst = new symbol_table ();
+
+		if (inst)
+		  {
+		    all_instances[scope] = instance = inst;
+
+		    if (scope == xtop_scope)
+		      instance->do_cache_name ("top-level");
+		  }
+	      }
+
+	    if (! instance)
+	      ok = false;
+
+	    retval = instance;
+	  }
+	else
+	  {
+	    all_instances_iterator p = all_instances.find (scope);
+
+	    if (p == all_instances.end ())
+	      {
+		if (create)
+		  {
+		    retval = new symbol_table ();
+
+		    if (retval)
+		      all_instances[scope] = retval;
+		    else
+		      ok = false;
+		  }
+		else
+		  ok = false;
+	      }
+	    else
+	      retval = p->second;
+	  }
+      }
+
+    if (! ok)
+      error ("unable to %s symbol_table object for scope %d!",
+	     create ? "create" : "find", scope);
+
+    return retval;
+  }
+
+  void insert_symbol_record (const symbol_record& sr)
+  {
+    table[sr.name ()] = sr;
+  }
+
+  void
+  do_dup_scope (symbol_table& new_symbol_table) const
+  {
+    for (table_const_iterator p = table.begin (); p != table.end (); p++)
+      new_symbol_table.insert_symbol_record (p->second.dup ());
+  }
+
+  symbol_record do_find_symbol (const std::string& name)
+  {
+    table_iterator p = table.find (name);
+
+    if (p == table.end ())
+      return do_insert (name);
+    else
+      return p->second;
+  }
+
+  void do_inherit (symbol_table& donor_table, context_id donor_context)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      {
+	symbol_record& sr = p->second;
+
+	if (! (sr.is_automatic () || sr.is_formal ()))
+	  {
+	    std::string nm = sr.name ();
+
+	    if (nm != "__retval__")
+	      {
+		octave_value val = donor_table.do_varval (nm, donor_context);
+
+		if (val.is_defined ())
+		  {
+		    sr.varref (0) = val;
+
+		    sr.mark_inherited ();
+		  }
+	      }
+	  }
+      }
+  }
+
+  octave_value
+  do_find (const std::string& name, tree_argument_list *args,
+	   const string_vector& arg_names,
+	   octave_value_list& evaluated_args, bool& args_evaluated,
+	   bool skip_variables);
+
+  symbol_record& do_insert (const std::string& name)
+  {
+    table_iterator p = table.find (name);
+
+    return p == table.end ()
+      ? (table[name] = symbol_record (name)) : p->second;
+  }
+
+  void do_force_variable (const std::string& name, context_id context)
+  {
+    table_iterator p = table.find (name);
+
+    if (p == table.end ())
+      {
+	symbol_record& sr = do_insert (name);
+
+	sr.force_variable (context);
+      }
+    else
+      p->second.force_variable (context);
+  }
+
+  octave_value& do_varref (const std::string& name, context_id context)
+  {
+    table_iterator p = table.find (name);
+
+    if (p == table.end ())
+      {
+	symbol_record& sr = do_insert (name);
+
+	return sr.varref (context);
+      }
+    else
+      return p->second.varref (context);
+  }
+
+  octave_value do_varval (const std::string& name, context_id context) const
+  {
+    table_const_iterator p = table.find (name);
+
+    return (p != table.end ()) ? p->second.varval (context) : octave_value ();
+  }
+
+  octave_value& do_persistent_varref (const std::string& name)
+  {
+    persistent_table_iterator p = persistent_table.find (name);
+
+    return (p == persistent_table.end ())
+      ? persistent_table[name] : p->second;
+  }
+
+  octave_value do_persistent_varval (const std::string& name)
+  {
+    persistent_table_const_iterator p = persistent_table.find (name);
+
+    return (p != persistent_table.end ()) ? p->second : octave_value ();
+  }
+
+  void do_erase_persistent (const std::string& name)
+  {
+    persistent_table_iterator p = persistent_table.find (name);
+
+    if (p != persistent_table.end ())
+      persistent_table.erase (p);
+  }
+
+  bool do_is_variable (const std::string& name) const
+  {
+    bool retval = false;
+
+    table_const_iterator p = table.find (name);
+
+    if (p != table.end ())
+      {
+	const symbol_record& sr = p->second;
+
+	retval = sr.is_variable ();
+      }
+
+    return retval;
+  }
+
+  void do_push_context (void)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      p->second.push_context ();
+  }
+
+  void do_pop_context (void)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); )
+      {
+	if (p->second.pop_context () == 0)
+	  table.erase (p++);
+	else
+	  p++;
+      }
+  }
+
+  void do_clear_variables (void)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      p->second.clear ();
+  }
+
+  void do_clear_objects (void)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      {
+	symbol_record& sr = p->second;
+	octave_value& val = sr.varref ();
+	if (val.is_object())
+	  p->second.clear ();
+      }
+  }
+
+ void do_unmark_forced_variables (void)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      p->second.unmark_forced ();
+  }
+
+  void do_clear_global (const std::string& name)
+  {
+    table_iterator p = table.find (name);
+
+    if (p != table.end ())
+      {
+	symbol_record& sr = p->second;
+
+	if (sr.is_global ())
+          sr.unmark_global ();
+      }
+
+    global_table_iterator q = global_table.find (name);
+
+    if (q != global_table.end ())
+      global_table.erase (q);
+
+  }
+
+  void do_clear_variable (const std::string& name)
+  {
+    table_iterator p = table.find (name);
+
+    if (p != table.end ())
+      p->second.clear ();
+  }
+
+  void do_clear_global_pattern (const std::string& pat)
+  {
+    glob_match pattern (pat);
+
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      {
+	symbol_record& sr = p->second;
+
+	if (sr.is_global () && pattern.match (sr.name ()))
+          sr.unmark_global ();
+      }
+
+    for (global_table_iterator q = global_table.begin (); 
+         q != global_table.end (); q++)
+      {
+	if (pattern.match (q->first))
+          global_table.erase (q);
+      }
+
+
+  }
+
+  void do_clear_variable_pattern (const std::string& pat)
+  {
+    glob_match pattern (pat);
+
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      {
+	symbol_record& sr = p->second;
+
+	if (sr.is_defined () || sr.is_global ())
+	  {
+	    if (pattern.match (sr.name ()))
+	      sr.clear ();
+	  }
+      }
+  }
+
+  void do_clear_variable_regexp (const std::string& pat)
+  {
+    regex_match pattern (pat);
+
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      {
+	symbol_record& sr = p->second;
+
+	if (sr.is_defined () || sr.is_global ())
+	  {
+	    if (pattern.match (sr.name ()))
+	      sr.clear ();
+	  }
+      }
+  }
+
+  void do_mark_hidden (const std::string& name)
+  {
+    table_iterator p = table.find (name);
+
+    if (p != table.end ())
+      p->second.mark_hidden ();
+  }
+
+  void do_mark_global (const std::string& name)
+  {
+    table_iterator p = table.find (name);
+
+    if (p != table.end ())
+      p->second.mark_global ();
+  }
+
+  std::list<symbol_record>
+  do_all_variables (context_id context, bool defined_only) const
+  {
+    std::list<symbol_record> retval;
+
+    for (table_const_iterator p = table.begin (); p != table.end (); p++)
+      {
+	const symbol_record& sr = p->second;
+
+	if (defined_only && ! sr.is_defined (context))
+	  continue;
+
+	retval.push_back (sr);
+      }
+
+    return retval;
+  }
+
+  std::list<symbol_record> do_glob (const std::string& pattern,
+				    bool vars_only = false) const
+  {
+    std::list<symbol_record> retval;
+
+    glob_match pat (pattern);
+
+    for (table_const_iterator p = table.begin (); p != table.end (); p++)
+      {
+	if (pat.match (p->first))
+	  {
+	    const symbol_record& sr = p->second;
+
+	    if (vars_only && ! sr.is_variable ())
+	      continue;
+
+	    retval.push_back (sr);
+	  }
+      }
+
+    return retval;
+  }
+
+  std::list<symbol_record> do_regexp (const std::string& pattern,
+				      bool vars_only = false) const
+  {
+    std::list<symbol_record> retval;
+
+    regex_match pat (pattern);
+
+    for (table_const_iterator p = table.begin (); p != table.end (); p++)
+      {
+	if (pat.match (p->first))
+	  {
+	    const symbol_record& sr = p->second;
+
+	    if (vars_only && ! sr.is_variable ())
+	      continue;
+
+	    retval.push_back (sr);
+	  }
+      }
+
+    return retval;
+  }
+
+  std::list<std::string> do_variable_names (void)
+  {
+    std::list<std::string> retval;
+
+    for (table_const_iterator p = table.begin (); p != table.end (); p++)
+      {
+	if (p->second.is_variable ())
+	  retval.push_back (p->first);
+      }
+
+    retval.sort ();
+
+    return retval;
+  }
+
+  static std::map<std::string, octave_value>
+  subfunctions_defined_in_scope (scope_id scope = xcurrent_scope)
+  {
+    std::map<std::string, octave_value> retval;
+
+    for (fcn_table_const_iterator p = fcn_table.begin ();
+	 p != fcn_table.end (); p++)
+      {
+	std::pair<std::string, octave_value> tmp
+	  = p->second.subfunction_defined_in_scope (scope);
+
+	std::string nm = tmp.first;
+
+	if (! nm.empty ())
+	  retval[nm] = tmp.second;
+      }
+
+    return retval;
+  }
+
+  bool do_is_local_variable (const std::string& name) const
+  {
+    table_const_iterator p = table.find (name);
+
+    return (p != table.end ()
+	    && ! p->second.is_global ()
+	    && p->second.is_defined ());
+  }
+
+  bool do_is_global (const std::string& name) const
+  {
+    table_const_iterator p = table.find (name);
+
+    return p != table.end () && p->second.is_global ();
+  }
+
+  void do_dump (std::ostream& os);
+
+  void do_cache_name (const std::string& name) { table_name = name; }
+};
+
+extern bool out_of_date_check (octave_value& function);
+
+extern bool out_of_date_check (octave_function* fcn);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/syscalls.cc b/src/syscalls.cc
new file mode 100644
index 0000000..15f2451
--- /dev/null
+++ b/src/syscalls.cc
@@ -0,0 +1,1912 @@
+/*
+
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+              2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Thomas Baier <baier at ci.tuwien.ac.at> added the original versions of
+// the following functions:
+//
+//   mkfifo  unlink  waitpid
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdio>
+#include <cstring>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-syscalls.h"
+#include "oct-uname.h"
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "lo-utils.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "oct-stdstrm.h"
+#include "oct-stream.h"
+#include "sysdep.h"
+#include "utils.h"
+#include "variables.h"
+#include "input.h"
+
+static Octave_map
+mk_stat_map (const base_file_stat& fs)
+{
+  Octave_map m;
+
+  m.assign ("dev", static_cast<double> (fs.dev ()));
+  m.assign ("ino", fs.ino ());
+  m.assign ("mode", fs.mode ());
+  m.assign ("modestr", fs.mode_as_string ());
+  m.assign ("nlink", fs.nlink ());
+  m.assign ("uid", fs.uid ());
+  m.assign ("gid", fs.gid ());
+#if defined (HAVE_STRUCT_STAT_ST_RDEV)
+  m.assign ("rdev", static_cast<double> (fs.rdev ()));
+#endif
+  m.assign ("size", fs.size ());
+  m.assign ("atime", fs.atime ());
+  m.assign ("mtime", fs.mtime ());
+  m.assign ("ctime", fs.ctime ());
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+  m.assign ("blksize", fs.blksize ());
+#endif
+#if defined (HAVE_STRUCT_STAT_ST_BLOCKS)
+  m.assign ("blocks", fs.blocks ());
+#endif
+
+  return m;
+}
+
+DEFUN (dup2, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} dup2 (@var{old}, @var{new})\n\
+Duplicate a file descriptor.\n\
+\n\
+If successful, @var{fid} is greater than zero and contains the new file\n\
+ID.  Otherwise, @var{fid} is negative and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      octave_stream old_stream
+	= octave_stream_list::lookup (args(0), "dup2");
+
+      if (! error_state)
+	{
+	  octave_stream new_stream
+	    = octave_stream_list::lookup (args(1), "dup2");
+
+	  if (! error_state)
+	    {
+	      int i_old = old_stream.file_number ();
+	      int i_new = new_stream.file_number ();
+
+	      if (i_old >= 0 && i_new >= 0)
+		{
+		  std::string msg;
+
+		  int status = octave_syscalls::dup2 (i_old, i_new, msg);
+
+		  retval(0) = status;
+		  retval(1) = msg;
+		}
+	    }
+	}
+      else
+	error ("dup2: invalid stream");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (exec, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} exec (@var{file}, @var{args})\n\
+Replace current process with a new process.  Calling @code{exec} without\n\
+first calling @code{fork} will terminate your current Octave process and\n\
+replace it with the program named by @var{file}.  For example,\n\
+\n\
+ at example\n\
+exec (\"ls\" \"-l\")\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will run @code{ls} and return you to your shell prompt.\n\
+\n\
+If successful, @code{exec} does not return.  If @code{exec} does return,\n\
+ at var{err} will be nonzero, and @var{msg} will contain a system-dependent\n\
+error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string exec_file = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  string_vector exec_args;
+
+	  if (nargin == 2)
+	    {
+	      string_vector tmp = args(1).all_strings ();
+
+	      if (! error_state)
+		{
+		  int len = tmp.length ();
+
+		  exec_args.resize (len + 1);
+
+		  exec_args[0] = exec_file;
+
+		  for (int i = 0; i < len; i++)
+		    exec_args[i+1] = tmp[i];
+		}
+	      else
+		error ("exec: arguments must be character strings");
+	    }
+	  else
+	    {
+	      exec_args.resize (1);
+
+	      exec_args[0] = exec_file;
+	    }
+
+	  if (! error_state)
+	    {
+	      std::string msg;
+
+	      int status = octave_syscalls::execvp (exec_file, exec_args, msg);
+
+	      retval(0) = status;
+	      retval(1) = msg;
+	    }
+	}
+      else
+	error ("exec: first argument must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (popen2, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args})\n\
+Start a subprocess with two-way communication.  The name of the process\n\
+is given by @var{command}, and @var{args} is an array of strings\n\
+containing options for the command.  The file identifiers for the input\n\
+and output streams of the subprocess are returned in @var{in} and\n\
+ at var{out}.  If execution of the command is successful, @var{pid}\n\
+contains the process ID of the subprocess.  Otherwise, @var{pid} is\n\
+ at minus{}1.\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+[in, out, pid] = popen2 (\"sort\", \"-r\");\n\
+fputs (in, \"these\\nare\\nsome\\nstrings\\n\");\n\
+fclose (in);\n\
+EAGAIN = errno (\"EAGAIN\");\n\
+done = false;\n\
+do\n\
+  s = fgets (out);\n\
+  if (ischar (s))\n\
+    fputs (stdout, s);\n\
+  elseif (errno () == EAGAIN)\n\
+    sleep (0.1);\n\
+    fclear (out);\n\
+  else\n\
+    done = true;\n\
+  endif\n\
+until (done)\n\
+fclose (out);\n\
+waitpid (pid);\n\
+     @print{} these\n\
+     @print{} strings\n\
+     @print{} some\n\
+     @print{} are\n\
+ at end example\n\
+\n\
+Note that @code{popen2}, unlike @code{popen}, will not \"reap\" the\n\
+child process.  If you don't use @code{waitpid} to check the child's\n\
+exit status, it will linger until Octave exits.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = -1;
+  retval(1) = Matrix ();
+  retval(0) = Matrix ();
+
+  int nargin = args.length ();
+
+  if (nargin >= 1 && nargin <= 3)
+    {
+      std::string exec_file = args(0).string_value();
+
+      if (! error_state)
+        {
+	  string_vector arg_list;
+
+	  if (nargin >= 2)
+	    {
+	      string_vector tmp = args(1).all_strings ();
+
+	      if (! error_state)
+		{
+		  int len = tmp.length ();
+
+		  arg_list.resize (len + 1);
+
+		  arg_list[0] = exec_file;
+
+		  for (int i = 0; i < len; i++)
+		    arg_list[i+1] = tmp[i];
+		}
+	      else
+		error ("popen2: arguments must be character strings");
+	    }
+	  else
+	    {
+	      arg_list.resize (1);
+
+	      arg_list[0] = exec_file;
+	    }
+
+          if (! error_state)
+            {
+              bool sync_mode = (nargin == 3 ? args(2).bool_value() : false);
+
+              if (! error_state)
+                {
+                  int fildes[2];
+                  std::string msg;
+                  pid_t pid;
+
+                  pid = octave_syscalls::popen2 (exec_file, arg_list, sync_mode, fildes, msg, interactive);
+                  if (pid >= 0)
+                    {
+                      FILE *ifile = fdopen (fildes[1], "r");
+                      FILE *ofile = fdopen (fildes[0], "w");
+
+                      std::string nm;
+
+                      octave_stream is = octave_stdiostream::create (nm, ifile,
+                          std::ios::in);
+
+                      octave_stream os = octave_stdiostream::create (nm, ofile,
+                          std::ios::out);
+
+                      Cell file_ids (1, 2);
+
+                      retval(0) = octave_stream_list::insert (os);
+                      retval(1) = octave_stream_list::insert (is);
+					  retval(2) = pid;
+                    }
+				  else
+                    error (msg.c_str ());
+                }
+            }
+          else
+            error ("popen2: arguments must be character strings");
+        }
+      else
+        error ("popen2: first argument must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%!  if (isunix())
+%!    [in, out, pid] = popen2 ("sort", "-r");
+%!    EAGAIN = errno ("EAGAIN");
+%!  else
+%!    [in, out, pid] = popen2 ("sort", "/R");
+%!    EAGAIN = errno ("EINVAL");
+%!  endif
+%!  fputs (in, "these\nare\nsome\nstrings\n");
+%!  fclose (in);
+%!  done = false;
+%!  str = {};
+%!  idx = 0;
+%!  errs = 0;
+%!  do
+%!     if (!isunix())
+%!       errno (0);
+%!     endif
+%!     s = fgets (out);
+%!     if (ischar (s))
+%!       idx++;
+%!       str{idx} = s;
+%!     elseif (errno () == EAGAIN)
+%!       fclear (out);
+%!       sleep (0.1);
+%!       if (++errs == 100)
+%!         done = true;
+%!       endif
+%!     else
+%!       done = true;
+%!     endif
+%!  until (done)
+%!  fclose (out);
+%!  if (isunix())
+%!    assert(str,{"these\n","strings\n","some\n","are\n"})
+%!  else
+%!    assert(str,{"these\r\n","strings\r\n","some\r\n","are\r\n"})
+%!  end
+
+*/
+
+DEFUN (fcntl, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg})\n\
+Change the properties of the open file @var{fid}.  The following values\n\
+may be passed as @var{request}:\n\
+\n\
+ at vtable @code\n\
+ at item F_DUPFD\n\
+Return a duplicate file descriptor.\n\
+\n\
+ at item F_GETFD\n\
+Return the file descriptor flags for @var{fid}.\n\
+\n\
+ at item F_SETFD\n\
+Set the file descriptor flags for @var{fid}.\n\
+\n\
+ at item F_GETFL\n\
+Return the file status flags for @var{fid}.  The following codes may be\n\
+returned (some of the flags may be undefined on some systems).\n\
+\n\
+ at vtable @code\n\
+ at item O_RDONLY\n\
+Open for reading only.\n\
+\n\
+ at item O_WRONLY\n\
+Open for writing only.\n\
+\n\
+ at item O_RDWR\n\
+Open for reading and writing.\n\
+\n\
+ at item O_APPEND\n\
+Append on each write.\n\
+\n\
+ at item O_CREAT\n\
+Create the file if it does not exist.\n\
+\n\
+ at item O_NONBLOCK\n\
+Nonblocking mode.\n\
+\n\
+ at item O_SYNC\n\
+Wait for writes to complete.\n\
+\n\
+ at item O_ASYNC\n\
+Asynchronous I/O.\n\
+ at end vtable\n\
+\n\
+ at item F_SETFL\n\
+Set the file status flags for @var{fid} to the value specified by\n\
+ at var{arg}.  The only flags that can be changed are @w{@code{O_APPEND}} and\n\
+ at w{@code{O_NONBLOCK}}.\n\
+ at end vtable\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 3)
+    {
+      octave_stream strm = octave_stream_list::lookup (args (0), "fcntl");
+
+      if (! error_state)
+	{
+	  int fid = strm.file_number ();
+
+	  int req = args(1).int_value (true);
+	  int arg = args(2).int_value (true);
+
+	  if (! error_state)
+	    {
+	      // FIXME -- Need better checking here?
+	      if (fid < 0)
+		error ("fcntl: invalid file id");
+	      else
+		{
+		  std::string msg;
+
+		  int status = octave_syscalls::fcntl (fid, req, arg, msg);
+
+		  retval(0) = status;
+		  retval(1) = msg;
+		}
+	    }
+	}
+      else
+	error ("fcntl: file id, request, and argument must be integers");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fork, args, ,
+ "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{pid}, @var{msg}] =} fork ()\n\
+Create a copy of the current process.\n\
+\n\
+Fork can return one of the following values:\n\
+\n\
+ at table @asis\n\
+ at item > 0\n\
+You are in the parent process.  The value returned from @code{fork} is\n\
+the process id of the child process.  You should probably arrange to\n\
+wait for any child processes to exit.\n\
+\n\
+ at item 0\n\
+You are in the child process.  You can call @code{exec} to start another\n\
+process.  If that fails, you should probably call @code{exit}.\n\
+\n\
+ at item < 0\n\
+The call to @code{fork} failed for some reason.  You must take evasive\n\
+action.  A system dependent error message will be waiting in @var{msg}.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      pid_t pid = octave_syscalls::fork (msg);
+
+      retval(0) = pid;
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (getpgrp, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {pgid =} getpgrp ()\n\
+Return the process group id of the current process.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      std::string msg;
+
+      retval(0) = octave_syscalls::getpgrp (msg);
+      retval(1) = msg;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (getpid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {pid =} getpid ()\n\
+Return the process id of the current process.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_syscalls::getpid ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (getppid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {pid =} getppid ()\n\
+Return the process id of the parent process.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_syscalls::getppid ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (getegid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {egid =} getegid ()\n\
+Return the effective group id of the current process.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_syscalls::getegid ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (getgid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {gid =} getgid ()\n\
+Return the real group id of the current process.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_syscalls::getgid ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (geteuid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {euid =} geteuid ()\n\
+Return the effective user id of the current process.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_syscalls::geteuid ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (getuid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {uid =} getuid ()\n\
+Return the real user id of the current process.\n\
+ at end deftypefn")
+{
+  octave_value retval = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = octave_syscalls::getuid ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (kill, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} kill (@var{pid}, @var{sig})\n\
+Send signal @var{sig} to process @var{pid}.\n\
+\n\
+If @var{pid} is positive, then signal @var{sig} is sent to @var{pid}.\n\
+\n\
+If @var{pid} is 0, then signal @var{sig} is sent to every process\n\
+in the process group of the current process.\n\
+\n\
+If @var{pid} is -1, then signal @var{sig} is sent to every process\n\
+except process 1.\n\
+\n\
+If @var{pid} is less than -1, then signal @var{sig} is sent to every\n\
+process in the process group @var{-pid}.\n\
+\n\
+If @var{sig} is 0, then no signal is sent, but error checking is still\n\
+performed.\n\
+\n\
+Return 0 if successful, otherwise return -1.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  if (args.length () == 2)
+    {
+      pid_t pid = args(0).int_value (true);
+
+      if (! error_state)
+	{
+	  int sig = args(1).int_value (true);
+
+	  if (! error_state)
+	    {
+	      std::string msg;
+
+	      int status = octave_syscalls::kill (pid, sig, msg);
+
+	      retval(1) = msg;
+	      retval(0) = status;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (fstat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} fstat (@var{fid})\n\
+Return information about the open file @var{fid}.  See @code{stat}\n\
+for a description of the contents of @var{info}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      int fid = octave_stream_list::get_file_number (args(0));
+
+      if (! error_state)
+	{
+	  file_fstat fs (fid);
+
+	  if (fs)
+	    {
+	      retval(2) = std::string ();
+	      retval(1) = 0;
+	      retval(0) = octave_value (mk_stat_map (fs));
+	    }
+	  else
+	    {
+	      retval(2) = fs.error ();
+	      retval(1) = -1;
+	      retval(0) = Matrix ();
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (lstat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})\n\
+See stat.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      std::string fname = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  file_stat fs (fname, false);
+
+	  if (fs)
+	    {
+	      retval(2) = std::string ();
+	      retval(1) = 0;
+	      retval(0) = mk_stat_map (fs);
+	    }
+	  else
+	    {
+	      retval(2) = fs.error ();
+	      retval(1) = -1;
+	      retval(0) = Matrix ();
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+
+
+DEFUN (mkfifo, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\
+Create a @var{fifo} special file named @var{name} with file mode @var{mode}\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      if (args(0).is_string ())
+	{
+	  std::string name = args(0).string_value ();
+
+	  if (args(1).is_scalar_type ())
+	    {
+	      long mode = args(1).long_value ();
+
+	      if (! error_state)
+		{
+		  std::string msg;
+
+		  int status = file_ops::mkfifo (name, mode, msg);
+
+		  retval(0) = status;
+
+		  if (status < 0)
+		    retval(1) = msg;
+		}
+	      else
+		error ("mkfifo: invalid MODE");
+	    }
+	  else
+	    error ("mkfifo: MODE must be an integer");
+	}
+      else
+	error ("mkfifo: file name must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (pipe, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe ()\n\
+Create a pipe and return the reading and writing ends of the pipe\n\
+into @var{read_fd} and @var{write_fd} respectively.\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(3) = std::string ();
+  retval(2) = -1;
+  retval(1) = -1;
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      int fid[2];
+
+      std::string msg;
+
+      int status = octave_syscalls::pipe (fid, msg);
+
+      if (status < 0)
+	retval(3) = msg;
+      else
+	{
+	  FILE *ifile = fdopen (fid[0], "r");
+	  FILE *ofile = fdopen (fid[1], "w");
+
+	  std::string nm;
+
+	  octave_stream is = octave_stdiostream::create (nm, ifile,
+							 std::ios::in);
+
+	  octave_stream os = octave_stdiostream::create (nm, ofile,
+							 std::ios::out);
+
+	  retval(1) = octave_stream_list::insert (os);
+	  retval(0) = octave_stream_list::insert (is);
+
+	  retval(2) = status;
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (stat, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{file})\n\
+ at deftypefnx {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})\n\
+Return a structure @var{s} containing the following information about\n\
+ at var{file}.\n\
+\n\
+ at table @code\n\
+ at item dev\n\
+ID of device containing a directory entry for this file.\n\
+\n\
+ at item ino\n\
+File number of the file.\n\
+\n\
+ at item mode\n\
+File mode, as an integer.  Use the functions @w{@code{S_ISREG}},\n\
+ at w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}}, @w{@code{S_ISFIFO}},\n\
+ at w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract information from this\n\
+value.\n\
+\n\
+ at item modestr\n\
+File mode, as a string of ten letters or dashes as would be returned by\n\
+ at kbd{ls -l}.\n\
+\n\
+ at item nlink\n\
+Number of links.\n\
+\n\
+ at item uid\n\
+User ID of file's owner.\n\
+\n\
+ at item gid\n\
+Group ID of file's group.\n\
+\n\
+ at item rdev\n\
+ID of device for block or character special files.\n\
+\n\
+ at item size\n\
+Size in bytes.\n\
+\n\
+ at item atime\n\
+Time of last access in the same form as time values returned from\n\
+ at code{time}.  @xref{Timing Utilities}.\n\
+\n\
+ at item mtime\n\
+Time of last modification in the same form as time values returned from\n\
+ at code{time}.  @xref{Timing Utilities}.\n\
+\n\
+ at item ctime\n\
+Time of last file status change in the same form as time values\n\
+returned from @code{time}.  @xref{Timing Utilities}.\n\
+\n\
+ at item blksize\n\
+Size of blocks in the file.\n\
+\n\
+ at item blocks\n\
+Number of blocks allocated for file.\n\
+ at end table\n\
+\n\
+If the call is successful @var{err} is 0 and @var{msg} is an empty\n\
+string.  If the file does not exist, or some other error occurs, @var{s}\n\
+is an empty matrix, @var{err} is @minus{}1, and @var{msg} contains the\n\
+corresponding system error message.\n\
+\n\
+If @var{file} is a symbolic link, @code{stat} will return information\n\
+about the actual file that is referenced by the link.  Use @code{lstat}\n\
+if you want information about the symbolic link itself.\n\
+\n\
+For example,\n\
+\n\
+ at example\n\
+[s, err, msg] = stat (\"/vmlinuz\")\n\
+      @result{} s =\n\
+        @{\n\
+          atime = 855399756\n\
+          rdev = 0\n\
+          ctime = 847219094\n\
+          uid = 0\n\
+          size = 389218\n\
+          blksize = 4096\n\
+          mtime = 847219094\n\
+          gid = 6\n\
+          nlink = 1\n\
+          blocks = 768\n\
+          mode = -rw-r--r--\n\
+          modestr = -rw-r--r--\n\
+          ino = 9316\n\
+          dev = 2049\n\
+        @}\n\
+     @result{} err = 0\n\
+     @result{} msg = \n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      std::string fname = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  file_stat fs (fname);
+
+	  if (fs)
+	    {
+	      retval(2) = std::string ();
+	      retval(1) = 0;
+	      retval(0) = octave_value (mk_stat_map (fs));
+	    }
+	  else
+	    {
+	      retval(2) = fs.error ();
+	      retval(1) = -1;
+	      retval(0) = Matrix ();
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISREG", FS_ISREG, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISREG (@var{mode})\n\
+Return true if @var{mode} corresponds to a regular file.  The value\n\
+of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_reg (static_cast<mode_t> (mode));
+      else
+	error ("S_ISREG: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISDIR", FS_ISDIR, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISDIR (@var{mode})\n\
+Return true if @var{mode} corresponds to a directory.  The value\n\
+of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_dir (static_cast<mode_t> (mode));
+      else
+	error ("S_ISDIR: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISCHR", FS_ISCHR, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISCHR (@var{mode})\n\
+Return true if @var{mode} corresponds to a character devicey.  The value\n\
+of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_chr (static_cast<mode_t> (mode));
+      else
+	error ("S_ISCHR: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISBLK", FS_ISBLK, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISBLK (@var{mode})\n\
+Return true if @var{mode} corresponds to a block device.  The value\n\
+of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_blk (static_cast<mode_t> (mode));
+      else
+	error ("S_ISBLK: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISFIFO", FS_ISFIFO, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISFIFO (@var{mode})\n\
+Return true if @var{mode} corresponds to a fifo.  The value\n\
+of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_fifo (static_cast<mode_t> (mode));
+      else
+	error ("S_ISFIFO: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISLNK", FS_ISLNK, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISLNK (@var{mode})\n\
+Return true if @var{mode} corresponds to a symbolic link.  The value\n\
+of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_lnk (static_cast<mode_t> (mode));
+      else
+	error ("S_ISLNK: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("S_ISSOCK", FS_ISSOCK, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} S_ISSOCK (@var{mode})\n\
+ at seealso{stat, lstat}\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    {
+      double mode = args(0).double_value ();
+
+      if (! error_state)
+	retval = file_stat::is_sock (static_cast<mode_t> (mode));
+      else
+	error ("S_ISSOCK: invalid mode value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (uname, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{uts}, @var{err}, @var{msg}] =} uname ()\n\
+Return system information in the structure.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+uname ()\n\
+     @result{} @{\n\
+           sysname = x86_64\n\
+           nodename = segfault\n\
+           release = 2.6.15-1-amd64-k8-smp\n\
+           version = Linux\n\
+           machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006\n\
+         @}\n\
+ at end group\n\
+ at end example\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 0)
+    {
+      octave_uname sysinfo;
+
+      Octave_map m;
+
+      m.assign ("sysname", sysinfo.sysname ());
+      m.assign ("nodename", sysinfo.nodename ());
+      m.assign ("release", sysinfo.release ());
+      m.assign ("version", sysinfo.version ());
+      m.assign ("machine", sysinfo.machine ());
+
+      retval(2) = sysinfo.message ();
+      retval(1) = sysinfo.error ();
+      retval(0) = m;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (unlink, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} unlink (@var{file})\n\
+Delete the file named @var{file}.\n\
+\n\
+If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
+system-dependent error message.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	{
+	  std::string name = args(0).string_value ();
+
+	  std::string msg;
+
+	  int status = file_ops::unlink (name, msg);
+
+	  retval(0) = status;
+	  retval(1) = msg;	    
+	}
+      else
+	error ("unlink: file name must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (waitpid, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{pid}, @var{status}, @var{msg}] =} waitpid (@var{pid}, @var{options})\n\
+Wait for process @var{pid} to terminate.  The @var{pid} argument can be:\n\
+\n\
+ at table @asis\n\
+ at item @minus{}1\n\
+Wait for any child process.\n\
+\n\
+ at item 0\n\
+Wait for any child process whose process group ID is equal to that of\n\
+the Octave interpreter process.\n\
+\n\
+ at item > 0\n\
+Wait for termination of the child process with ID @var{pid}.\n\
+ at end table\n\
+\n\
+The @var{options} argument can be a bitwise OR of zero or more of\n\
+the following constants:\n\
+\n\
+ at table @code\n\
+ at item 0\n\
+Wait until signal is received or a child process exits (this is the\n\
+default if the @var{options} argument is missing).\n\
+\n\
+ at item WNOHANG\n\
+Do not hang if status is not immediately available.\n\
+\n\
+ at item WUNTRACED\n\
+Report the status of any child processes that are stopped, and whose\n\
+status has not yet been reported since they stopped.\n\
+\n\
+ at item WCONTINUE\n\
+Return if a stopped child has been resumed by delivery of @code{SIGCONT}.\n\
+This value may not be meaningful on all systems.\n\
+ at end table\n\
+\n\
+If the returned value of @var{pid} is greater than 0, it is the process\n\
+ID of the child process that exited.  If an error occurs, @var{pid} will\n\
+be less than zero and @var{msg} will contain a system-dependent error\n\
+message.  The value of @var{status} contains additional system-dependent\n\
+information about the subprocess that exited.\n\
+ at seealso{WCONTINUE, WCOREDUMP, WEXITSTATUS, WIFCONTINUED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = 0;
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      pid_t pid = args(0).int_value (true);
+  
+      if (! error_state)
+	{
+	  int options = 0;
+
+	  if (args.length () == 2)
+	    options = args(1).int_value (true);
+
+	  if (! error_state)
+	    {
+	      std::string msg;
+
+	      int status = 0;
+
+	      pid_t result = octave_syscalls::waitpid (pid, &status, options, msg);
+
+	      retval(0) = result;
+	      retval(1) = status;
+	      retval(2) = msg;
+	    }
+	  else
+	    error ("waitpid: OPTIONS must be an integer");
+	}
+      else
+	error ("waitpid: PID must be an integer value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("WIFEXITED", FWIFEXITED, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WIFEXITED (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return true if the\n\
+child terminated normally.\n\
+ at seealso{waitpid, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WIFEXITED)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WIFEXITED (status);
+      else
+	error ("WIFEXITED: expecting integer argument");
+    }
+#else
+  warning ("WIFEXITED always returns false in this version of Octave")
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WEXITSTATUS", FWEXITSTATUS, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WEXITSTATUS (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return the exit\n\
+status of the child.  This function should only be employed if\n\
+ at code{WIFEXITED} returned true.\n\
+ at seealso{waitpid, WIFEXITED, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WEXITSTATUS)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WEXITSTATUS (status);
+      else
+	error ("WEXITSTATUS: expecting integer argument");
+    }
+#else
+  warning ("WEXITSTATUS always returns false in this version of Octave")
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WIFSIGNALED", FWIFSIGNALED, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WIFSIGNALED (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return true if the\n\
+child process was terminated by a signal.\n\
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WIFSIGNALED)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WIFSIGNALED (status);
+      else
+	error ("WIFSIGNALED: expecting integer argument");
+    }
+#else
+  warning ("WIFSIGNALED always returns false in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WTERMSIG", FWTERMSIG, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WTERMSIG (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return the number of\n\
+the signal that caused the child process to terminate.  This function\n\
+should only be employed if @code{WIFSIGNALED} returned true.\n\
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WTERMSIG)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WTERMSIG (status);
+      else
+	error ("WTERMSIG: expecting integer argument");
+    }
+#else
+  warning ("WTERMSIG always returns false in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WCOREDUMP", FWCOREDUMP, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WCOREDUMP (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return true if the\n\
+child produced a core dump.  This function should only be employed if\n\
+ at code{WIFSIGNALED} returned true.  The macro used to implement this\n\
+function is not specified in POSIX.1-2001 and is not available on some\n\
+Unix implementations (e.g., AIX, SunOS).\n\
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WCOREDUMP)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WCOREDUMP (status);
+      else
+	error ("WCOREDUMP: expecting integer argument");
+    }
+#else
+  warning ("WCOREDUMP always returns false in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WIFSTOPPED", FWIFSTOPPED, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WIFSTOPPED (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return true if the\n\
+child process was stopped by delivery of a signal; this is only\n\
+possible if the call was done using @code{WUNTRACED} or when the child\n\
+is being traced (see ptrace(2)).\n\
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WSTOPSIG, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WIFSTOPPED)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WIFSTOPPED (status);
+      else
+	error ("WIFSTOPPED: expecting integer argument");
+    }
+#else
+  warning ("WIFSTOPPED always returns false in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WSTOPSIG", FWSTOPSIG, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WSTOPSIG (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return the number of\n\
+the signal which caused the child to stop.  This function should only\n\
+be employed if @code{WIFSTOPPED} returned true.\n\
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WIFCONTINUED}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WSTOPSIG)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WSTOPSIG (status);
+      else
+	error ("WSTOPSIG: expecting integer argument");
+    }
+#else
+  warning ("WSTOPSIG always returns false in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUNX ("WIFCONTINUED", FWIFCONTINUED, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WIFCONTINUED (@var{status})\n\
+Given @var{status} from a call to @code{waitpid}, return true if the\n\
+child process was resumed by delivery of @code{SIGCONT}.\n\
+ at seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG}\n\
+ at end deftypefn")
+{
+  octave_value retval = 0.0;
+
+#if defined (WIFCONTINUED)
+  if (args.length () == 1)
+    {
+      int status = args(0).int_value ();
+
+      if (! error_state)
+	retval = WIFCONTINUED (status);
+      else
+	error ("WIFCONTINUED: expecting integer argument");
+    }
+#else
+  warning ("WIFCONTINUED always returns false in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUN (canonicalize_file_name, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {[@var{cname}, @var{status}, @var{msg}]} canonicalize_file_name (@var{name})\n\
+Return the canonical name of file @var{name}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string msg;
+
+	  std::string result = file_ops::canonicalize_file_name (name, msg);
+
+	  retval(2) = msg;
+	  retval(1) = msg.empty () ? 0 : -1;
+	  retval(0) = result;
+	}
+      else
+	error ("canonicalize_file_name: argument must be a character string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static octave_value
+const_value (const octave_value_list& args, int val)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    retval = val;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#if !defined (O_NONBLOCK) && defined (O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
+#if defined (F_DUPFD)
+DEFUNX ("F_DUPFD", FF_DUPFD, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} F_DUPFD ()\n\
+Return the value required to request that @code{fcntl} return a\n\
+duplicate file descriptor.\n\
+ at seealso{fcntl, F_GETFD, F_GETFL, F_SETFD, F_SETFL}\n\
+ at end deftypefn")
+{
+  return const_value (args, F_DUPFD);
+}
+#endif
+
+#if defined (F_GETFD)
+DEFUNX ("F_GETFD", FF_GETFD, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} F_GETFD ()\n\
+Return the value required to request that @code{fcntl} to return the\n\
+file descriptor flags.\n\
+ at seealso{fcntl, F_DUPFD, F_GETFL, F_SETFD, F_SETFL}\n\
+ at end deftypefn")
+{
+  return const_value (args, F_GETFD);
+}
+#endif
+
+#if defined (F_GETFL)
+DEFUNX ("F_GETFL", FF_GETFL, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} F_GETFL ()\n\
+Return the value required to request that @code{fcntl} to return the\n\
+file status flags.\n\
+ at seealso{fcntl, F_DUPFD, F_GETFD, F_SETFD, F_SETFL}\n\
+ at end deftypefn")
+{
+  return const_value (args, F_GETFL);
+}
+#endif
+
+#if defined (F_SETFD)
+DEFUNX ("F_SETFD", FF_SETFD, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} F_SETFD ()\n\
+Return the value required to request that @code{fcntl} to set the file\n\
+descriptor flags.\n\
+ at seealso{fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFL}\n\
+ at end deftypefn")
+{
+  return const_value (args, F_SETFD);
+}
+#endif
+
+#if defined (F_SETFL)
+DEFUNX ("F_SETFL", FF_SETFL, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} F_SETFL ()\n\
+Return the value required to request that @code{fcntl} to set the file\n\
+status flags.\n\
+ at seealso{fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFD}\n\
+ at end deftypefn")
+{
+  return const_value (args, F_SETFL);
+}
+#endif
+
+#if defined (O_APPEND)
+DEFUNX ("O_APPEND", FO_APPEND, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_APPEND ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate each write operation appends,\n\
+or that may be passed to @code{fcntl} to set the write mode to append.\\n\
+ at seealso{fcntl, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_APPEND);
+}
+#endif
+
+#if defined (O_ASYNC)
+DEFUNX ("O_ASYNC", FO_ASYNC, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_ASYNC ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate asynchronous I/O.\n\
+ at seealso{fcntl, O_APPEND, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_ASYNC);
+}
+#endif
+
+#if defined (O_CREAT)
+DEFUNX ("O_CREAT", FO_CREAT, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_CREAT ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that a file should be\n\
+created if it does not exist.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_CREAT);
+}
+#endif
+
+#if defined (O_EXCL)
+DEFUNX ("O_EXCL", FO_EXCL, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_EXCL ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that file locking is used.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_EXCL);
+}
+#endif
+
+#if defined (O_NONBLOCK)
+DEFUNX ("O_NONBLOCK", FO_NONBLOCK, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_NONBLOCK ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that non-blocking I/O is in use,\n\
+or that may be passsed to @code{fcntl} to set non-blocking I/O.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_NONBLOCK);
+}
+#endif
+
+#if defined (O_RDONLY)
+DEFUNX ("O_RDONLY", FO_RDONLY, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_RDONLY ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that a file is open for\n\
+reading only.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_RDONLY);
+}
+#endif
+
+#if defined (O_RDWR)
+DEFUNX ("O_RDWR", FO_RDWR, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_RDWR ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that a file is open for both\n\
+reading and writing.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_SYNC, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_RDWR);
+}
+#endif
+
+#if defined (O_SYNC)
+DEFUNX ("O_SYNC", FO_SYNC, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_SYNC ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that a file is open for\n\
+synchronous I/O.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_SYNC);
+}
+#endif
+
+#if defined (O_TRUNC)
+DEFUNX ("O_TRUNC", FO_TRUNC, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Variable} O_TRUNC ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that if file exists, it should\n\
+be truncated when writing.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_WRONLY}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_TRUNC);
+}
+#endif
+
+#if defined (O_WRONLY)
+DEFUNX ("O_WRONLY", FO_WRONLY, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} O_WRONLY ()\n\
+Return the numerical value of the file status flag that may be\n\
+returned by @code{fcntl} to indicate that a file is open for\n\
+writing only.\n\
+ at seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC}\n\
+ at end deftypefn")
+{
+  return const_value (args, O_WRONLY);
+}
+#endif
+
+#if !defined (WNOHANG)
+#define WNOHANG 0
+#endif
+
+DEFUNX ("WNOHANG", FWNOHANG, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WNOHANG ()\n\
+Return the numerical value of the option argument that may be\n\
+passed to @code{waitpid} to indicate that it should return its\n\
+status immediately instead of waiting for a process to exit.\n\
+ at seealso{waitpid, WUNTRACED, WCONTINUE}\n\
+ at end deftypefn")
+{
+  return const_value (args, WNOHANG);
+}
+
+#if !defined (WUNTRACED)
+#define WUNTRACED 0
+#endif
+
+DEFUNX ("WUNTRACED", FWUNTRACED, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} WUNTRACED ()\n\
+Return the numerical value of the option argument that may be\n\
+passed to @code{waitpid} to indicate that it should also return\n\
+if the child process has stopped but is not traced via the\n\
+ at code{ptrace} system call\n\
+ at seealso{waitpid, WNOHANG, WCONTINUE}\n\
+ at end deftypefn")
+{
+  return const_value (args, WUNTRACED);
+}
+
+#if !defined (WCONTINUE)
+#define WCONTINUE 0
+#endif
+
+DEFUNX ("WCONTINUE", FWCONTINUE, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} WCONINTUE ()\n\
+Return the numerical value of the option argument that may be\n\
+passed to @code{waitpid} to indicate that it should also return\n\
+if a stopped child has been resumed by delivery of a @code{SIGCONT}\n\
+signal.\n\
+ at seealso{waitpid, WNOHANG, WUNTRACED}\n\
+ at end deftypefn")
+{
+  return const_value (args, WCONTINUE);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sysdep.cc b/src/sysdep.cc
new file mode 100644
index 0000000..97a6834
--- /dev/null
+++ b/src/sysdep.cc
@@ -0,0 +1,887 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
+              2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <iostream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#if defined (HAVE_TERMIOS_H)
+#include <termios.h>
+#elif defined (HAVE_TERMIO_H)
+#include <termio.h>
+#elif defined (HAVE_SGTTY_H)
+#include <sgtty.h>
+#endif 
+
+#if defined (HAVE_CONIO_H)
+#include <conio.h>
+#endif
+
+#if defined (HAVE_SYS_IOCTL_H)
+#include <sys/ioctl.h>
+#endif
+
+#if defined (HAVE_FLOATINGPOINT_H)
+#include <floatingpoint.h>
+#endif
+
+#if defined (HAVE_IEEEFP_H)
+#include <ieeefp.h>
+#endif
+
+#if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
+#include <sys/utsname.h>
+#endif
+
+#include "cmd-edit.h"
+#include "file-ops.h"
+#include "lo-mappers.h"
+#include "lo-math.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "quit.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "input.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "pager.h"
+#include "parse.h"
+#include "sighandlers.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "utils.h"
+#include "file-stat.h"
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 1
+#endif
+
+#if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
+static void
+BSD_init (void)
+{
+#if defined (HAVE_FLOATINGPOINT_H)
+  // Disable trapping on common exceptions.
+#ifndef FP_X_DNML
+#define FP_X_DNML 0
+#endif
+  fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
+#endif
+}
+#endif
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+static void
+w32_set_octave_home (void)
+{
+  int n = 1024;
+
+  std::string bin_dir (n, '\0');
+
+  while (true)
+    {
+      HMODULE hMod = GetModuleHandle ("octinterp");
+      int status = GetModuleFileName (hMod, &bin_dir[0], n);
+
+      if (status < n)
+	{
+	  bin_dir.resize (status);
+	  break;
+	}
+      else
+	{
+	  n *= 2;
+	  bin_dir.resize (n);
+	}
+    }
+
+  if (! bin_dir.empty ())
+    {
+      size_t pos = bin_dir.rfind ("\\bin\\");
+
+      if (pos != std::string::npos)
+	octave_env::putenv ("OCTAVE_HOME", bin_dir.substr (0, pos));
+    }
+}
+
+void
+w32_set_quiet_shutdown (void)
+{
+  // Let the user close the console window or shutdown without the
+  // pesky dialog.
+  //
+  // FIXME -- should this be user configurable?
+  SetProcessShutdownParameters (0x280, SHUTDOWN_NORETRY);
+}
+
+void
+MINGW_signal_cleanup (void)
+{
+  w32_set_quiet_shutdown ();
+
+  w32_raise_final ();
+}
+#endif
+
+#if defined (__MINGW32__)
+static void
+MINGW_init (void)
+{
+  w32_set_octave_home ();
+
+  // Init mutex to protect setjmp/longjmp and get main thread context
+  w32_sigint_init ();
+
+  w32_set_quiet_shutdown ();
+}
+#endif
+
+#if defined (_MSC_VER)
+static void
+MSVC_init (void)
+{
+  w32_set_octave_home ();
+  
+  // Init mutex to protect setjmp/longjmp and get main thread context
+  w32_sigint_init ();
+
+  w32_set_quiet_shutdown ();
+}
+#endif
+
+
+// Return TRUE if FILE1 and FILE2 refer to the same (physical) file.
+
+bool
+same_file_internal (const std::string& file1, const std::string& file2)
+{
+#ifdef OCTAVE_USE_WINDOWS_API
+
+  bool retval = false;
+
+  // Windows native code 
+  // Reference: http://msdn2.microsoft.com/en-us/library/aa363788.aspx
+
+  HANDLE hfile1 = CreateFile (file1.c_str (), 0, FILE_SHARE_READ, 0,
+			      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
+
+  if (hfile1 != INVALID_HANDLE_VALUE)
+    {
+      HANDLE hfile2 = CreateFile (file2.c_str (), 0, FILE_SHARE_READ, 0,
+				  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+      if (hfile2 != INVALID_HANDLE_VALUE)
+	{  
+	  BY_HANDLE_FILE_INFORMATION hfi1;
+	  BY_HANDLE_FILE_INFORMATION hfi2;
+  
+	  if (GetFileInformationByHandle (hfile1, &hfi1)
+	      && GetFileInformationByHandle (hfile2, &hfi2))
+  
+	    retval = (hfi1.dwVolumeSerialNumber == hfi2.dwVolumeSerialNumber
+		      && hfi1.nFileIndexHigh == hfi2.nFileIndexHigh
+		      && hfi1.nFileIndexLow == hfi2.nFileIndexLow);
+
+	  CloseHandle (hfile2);
+	}
+
+      CloseHandle (hfile1);
+    }
+
+  return retval;
+
+#else
+
+  // POSIX Code
+
+  file_stat fs_file1 (file1);
+  file_stat fs_file2 (file2);
+
+  return (fs_file1 && fs_file2
+	  && fs_file1.ino () == fs_file2.ino ()
+	  && fs_file1.dev () == fs_file2.dev ());
+
+#endif
+}
+
+#if defined (__DECCXX)
+
+// These don't seem to be instantiated automatically...
+
+template std::istream&
+std::operator >> (std::istream&, std::complex<double>&);
+
+template std::string&
+std::string::append (const std::string&, size_t, size_t);
+
+#endif
+
+#if defined (NeXT)
+extern "C"
+{
+  typedef void (*_cplus_fcn_int) (int);
+  extern void (*malloc_error (_cplus_fcn_int)) (int);
+}
+
+static void
+malloc_handler (int code)
+{
+  if (code == 5)
+    warning ("hopefully recoverable malloc error: freeing wild pointer");
+  else
+    panic ("probably irrecoverable malloc error: code %d", code);
+}
+
+static void
+NeXT_init (void)
+{
+  malloc_error (malloc_handler);
+}
+#endif
+
+#if defined (__EMX__)
+OS2_init (void)
+{
+  _control87 ((EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW
+	       | EM_UNDERFLOW | EM_INEXACT), MCW_EM);
+}
+#endif
+
+#if defined (SCO)
+static void
+SCO_init (void)
+{
+#if defined (HAVE_IEEEFP_H)
+  // Disable trapping on common exceptions.
+  fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
+#endif
+}
+#endif
+
+void
+sysdep_init (void)
+{
+#if defined (__386BSD__) || defined (__FreeBSD__) || defined(__NetBSD__)
+  BSD_init ();
+#elif defined (__MINGW32__)
+  MINGW_init ();
+#elif defined (_MSC_VER)
+  MSVC_init ();
+#elif defined (NeXT)
+  NeXT_init ();
+#elif defined (__EMX__)
+  OS2_init ();
+#elif defined (SCO)
+  SCO_init ();
+#endif
+
+  octave_ieee_init ();
+}
+
+void
+sysdep_cleanup (void)
+{
+  MINGW_SIGNAL_CLEANUP ();
+}
+
+// Set terminal in raw mode.  From less-177.
+//
+// Change terminal to "raw mode", or restore to "normal" mode.
+// "Raw mode" means 
+//	1. An outstanding read will complete on receipt of a single keystroke.
+//	2. Input is not echoed.  
+//	3. On output, \n is mapped to \r\n.
+//	4. \t is NOT expanded into spaces.
+//	5. Signal-causing characters such as ctrl-C (interrupt),
+//	   etc. are NOT disabled.
+// It doesn't matter whether an input \n is mapped to \r, or vice versa.
+
+void
+raw_mode (bool on, bool wait)
+{
+  static bool curr_on = false;
+
+  int tty_fd = STDIN_FILENO;
+  if (! isatty (tty_fd))
+    {
+      if (interactive)
+	error ("stdin is not a tty!");
+      return;
+    }
+
+  if (on == curr_on)
+    return;
+
+#if defined (HAVE_TERMIOS_H)
+  {
+    struct termios s;
+    static struct termios save_term;
+
+    if (on)
+      {
+	// Get terminal modes.
+
+	tcgetattr (tty_fd, &s);
+
+	// Save modes and set certain variables dependent on modes.
+
+	save_term = s;
+//	ospeed = s.c_cflag & CBAUD;
+//	erase_char = s.c_cc[VERASE];
+//	kill_char = s.c_cc[VKILL];
+
+	// Set the modes to the way we want them.
+
+	s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
+	s.c_oflag |=  (OPOST|ONLCR);
+#if defined (OCRNL)
+	s.c_oflag &= ~(OCRNL);
+#endif
+#if defined (ONOCR)
+	s.c_oflag &= ~(ONOCR);
+#endif
+#if defined (ONLRET)
+	s.c_oflag &= ~(ONLRET);
+#endif
+	s.c_cc[VMIN] = wait ? 1 : 0;
+	s.c_cc[VTIME] = 0;
+      }      
+    else
+      {
+	// Restore saved modes.
+
+	s = save_term;
+      }
+
+    tcsetattr (tty_fd, wait ? TCSAFLUSH : TCSADRAIN, &s);
+  }
+#elif defined (HAVE_TERMIO_H)
+  {
+    struct termio s;
+    static struct termio save_term;
+
+    if (on)
+      {
+	// Get terminal modes.
+
+	ioctl (tty_fd, TCGETA, &s);
+
+	// Save modes and set certain variables dependent on modes.
+
+	save_term = s;
+//	ospeed = s.c_cflag & CBAUD;
+//	erase_char = s.c_cc[VERASE];
+//	kill_char = s.c_cc[VKILL];
+
+	// Set the modes to the way we want them.
+
+	s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
+	s.c_oflag |=  (OPOST|ONLCR);
+#if defined (OCRNL)
+	s.c_oflag &= ~(OCRNL);
+#endif
+#if defined (ONOCR)
+	s.c_oflag &= ~(ONOCR);
+#endif
+#if defined (ONLRET)
+	s.c_oflag &= ~(ONLRET);
+#endif
+	s.c_cc[VMIN] = wait ? 1 : 0;
+      }      
+    else
+      {
+	// Restore saved modes.
+
+	s = save_term;
+      }
+
+    ioctl (tty_fd, TCSETAW, &s);
+  }
+#elif defined (HAVE_SGTTY_H)
+  {
+    struct sgttyb s;
+    static struct sgttyb save_term;
+
+    if (on)
+      {
+	// Get terminal modes.
+
+	ioctl (tty_fd, TIOCGETP, &s);
+
+	// Save modes and set certain variables dependent on modes.
+
+	save_term = s;
+//	ospeed = s.sg_ospeed;
+//	erase_char = s.sg_erase;
+//	kill_char = s.sg_kill;
+
+	// Set the modes to the way we want them.
+
+	s.sg_flags |= CBREAK;
+	s.sg_flags &= ~(ECHO);
+      } 
+    else
+      {
+	// Restore saved modes.
+
+	s = save_term;
+      }
+
+    ioctl (tty_fd, TIOCSETN, &s);
+  }
+#else
+  warning ("no support for raw mode console I/O on this system");
+
+  // Make sure the current mode doesn't toggle.
+  on = curr_on;
+#endif
+
+  curr_on = on;
+}
+
+FILE *
+octave_popen (const char *command, const char *mode)
+{
+#if defined (__MINGW32__) || defined (_MSC_VER)
+  if (mode && mode[0] && ! mode[1])
+    {
+      char tmode[3];
+      tmode[0] = mode[0];
+      tmode[1] = 'b';
+      tmode[2] = 0;
+
+      return _popen (command, tmode);
+    }
+  else
+    return _popen (command, mode);
+#else
+  return popen (command, mode);
+#endif
+}
+
+int
+octave_pclose (FILE *f)
+{
+#if defined (__MINGW32__) || defined (_MSC_VER)
+  return _pclose (f);
+#else
+  return pclose (f);
+#endif
+}
+
+// Read one character from the terminal.
+
+int
+octave_kbhit (bool wait)
+{
+#ifdef HAVE__KBHIT
+  int c = (! wait && ! _kbhit ()) ? 0 : std::cin.get ();
+#else
+  raw_mode (true, wait);
+
+  // Get current handler.
+  octave_interrupt_handler saved_interrupt_handler
+    = octave_ignore_interrupts ();
+
+  // Restore it, disabling system call restarts (if possible) so the
+  // read can be interrupted.
+
+  octave_set_interrupt_handler (saved_interrupt_handler, false);
+
+  int c = std::cin.get ();
+ 
+  if (std::cin.fail () || std::cin.eof ())
+    std::cin.clear ();
+
+  // Restore it, enabling system call restarts (if possible).
+  octave_set_interrupt_handler (saved_interrupt_handler, true);
+
+  raw_mode (false, true);
+#endif
+
+  return c;
+}
+
+DEFUN (clc, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} clc ()\n\
+ at deftypefnx {Built-in Function} {} home ()\n\
+Clear the terminal screen and move the cursor to the upper left corner.\n\
+ at end deftypefn")
+{
+  command_editor::clear_screen ();
+
+  return octave_value_list ();
+}
+
+DEFALIAS (home, clc);
+
+DEFUN (getenv, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} getenv (@var{var})\n\
+Return the value of the environment variable @var{var}.  For example,\n\
+\n\
+ at example\n\
+getenv (\"PATH\")\n\
+ at end example\n\
+\n\
+ at noindent\n\
+returns a string containing the value of your path.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	retval = octave_env::getenv (name);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (putenv, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} putenv (@var{var}, @var{value})\n\
+ at deftypefnx {Built-in Function} {} setenv (@var{var}, @var{value})\n\
+Set the value of the environment variable @var{var} to @var{value}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 || nargin == 1)
+    {
+      std::string var = args(0).string_value (); 
+
+      if (! error_state)
+	{
+	  std::string val = (nargin == 2
+			     ? args(1).string_value () : std::string ()); 
+
+	  if (! error_state)
+	    octave_env::putenv (var, val);
+	  else
+	    error ("putenv: second argument should be a string");
+	}
+      else
+	error ("putenv: first argument should be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+DEFALIAS (setenv, putenv);
+
+// FIXME -- perhaps kbhit should also be able to print a prompt?
+
+DEFUN (kbhit, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} kbhit ()\n\
+Read a single keystroke from the keyboard.  If called with one\n\
+argument, don't wait for a keypress.  For example,\n\
+\n\
+ at example\n\
+x = kbhit ();\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will set @var{x} to the next character typed at the keyboard as soon as\n\
+it is typed.\n\
+\n\
+ at example\n\
+x = kbhit (1);\n\
+ at end example\n\
+\n\
+ at noindent\n\
+identical to the above example, but don't wait for a keypress,\n\
+returning the empty string if no key is available.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  // FIXME -- add timeout and default value args?
+
+  if (interactive || forced_interactive)
+    {
+      feval ("drawnow");
+
+      int c = octave_kbhit (args.length () == 0);
+
+      if (c == -1)
+	c = 0;
+
+      char *s = new char [2];
+      s[0] = c;
+      s[1] = '\0';
+      retval = s;
+    }
+
+  return retval;
+}
+
+DEFUN (pause, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} pause (@var{seconds})\n\
+Suspend the execution of the program.  If invoked without any arguments,\n\
+Octave waits until you type a character.  With a numeric argument, it\n\
+pauses for the given number of seconds.  For example, the following\n\
+statement prints a message and then waits 5 seconds before clearing the\n\
+screen.\n\
+\n\
+ at example\n\
+ at group\n\
+fprintf (stderr, \"wait please...\\n\");\n\
+pause (5);\n\
+clc;\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (! (nargin == 0 || nargin == 1))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (nargin == 1)
+    {
+      double dval = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  if (! xisnan (dval))
+	    {
+	      feval ("drawnow");
+
+	      if (xisinf (dval))
+		{
+		  flush_octave_stdout ();
+		  octave_kbhit ();
+		}
+	      else
+		octave_sleep (dval);
+	    }
+	  else
+	    warning ("pause: NaN is an invalid delay");
+	}
+    }
+  else
+    {
+      feval ("drawnow");
+      flush_octave_stdout ();
+      octave_kbhit ();
+    }
+
+  return retval;
+}
+
+DEFUN (sleep, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} sleep (@var{seconds})\n\
+Suspend the execution of the program for the given number of seconds.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      double dval = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  if (xisnan (dval))
+	    warning ("sleep: NaN is an invalid delay");
+	  else
+	    {
+	      feval ("drawnow");
+	      octave_sleep (dval);
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (usleep, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} usleep (@var{microseconds})\n\
+Suspend the execution of the program for the given number of\n\
+microseconds.  On systems where it is not possible to sleep for periods\n\
+of time less than one second, @code{usleep} will pause the execution for\n\
+ at code{round (@var{microseconds} / 1e6)} seconds.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      double dval = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  if (xisnan (dval))
+	    warning ("usleep: NaN is an invalid delay");
+	  else
+	    {
+	      feval ("drawnow");
+
+	      int delay = NINT (dval);
+
+	      if (delay > 0)
+		octave_usleep (delay);
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// FIXME -- maybe this should only return 1 if IEEE floating
+// point functions really work.
+
+DEFUN (isieee, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isieee ()\n\
+Return 1 if your computer claims to conform to the IEEE standard for\n\
+floating point calculations.\n\
+ at end deftypefn")
+{
+  oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format ();
+
+  return octave_value (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
+		       || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
+}
+
+DEFUN (native_float_format, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} native_float_format ()\n\
+Return the native floating point format as a string\n\
+ at end deftypefn")
+{
+  oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format ();
+
+  return octave_value (oct_mach_info::float_format_as_string (flt_fmt));
+}
+
+DEFUN (tilde_expand, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} tilde_expand (@var{string})\n\
+Performs tilde expansion on @var{string}.  If @var{string} begins with a\n\
+tilde character, (@samp{~}), all of the characters preceding the first\n\
+slash (or all characters, if there is no slash) are treated as a\n\
+possible user name, and the tilde and the following characters up to the\n\
+slash are replaced by the home directory of the named user.  If the\n\
+tilde is followed immediately by a slash, the tilde is replaced by the\n\
+home directory of the user running Octave.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+tilde_expand (\"~joeuser/bin\")\n\
+     @result{} \"/home/joeuser/bin\"\n\
+tilde_expand (\"~/bin\")\n\
+     @result{} \"/home/jwe/bin\"\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+
+      string_vector sv = arg.all_strings ();
+
+      if (! error_state)
+	{
+	  sv = file_ops::tilde_expand (sv);
+
+	  if (arg.is_cellstr ())
+	    retval = Cell (arg.dims (), sv);
+	  else
+	    retval = sv;
+	}
+      else
+	error ("tilde_expand: expecting argument to be char or cellstr object");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#if defined (__EMX__) && defined (OS2)
+
+DEFUN (extproc, , ,
+  "extproc: ignored by Octave")
+{
+  return octave_value_list ();
+}
+
+DEFALIAS (EXTPROC, extproc);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/sysdep.h b/src/sysdep.h
new file mode 100644
index 0000000..a260fb5
--- /dev/null
+++ b/src/sysdep.h
@@ -0,0 +1,63 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2005, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_sysdep_h)
+#define octave_sysdep_h 1
+
+#include <cstdio>
+
+#include <string>
+
+#include "lo-ieee.h"
+#include "lo-sysdep.h"
+
+extern void sysdep_init (void);
+
+extern void sysdep_cleanup (void);
+
+extern OCTINTERP_API void raw_mode (bool, bool wait = true);
+
+extern OCTINTERP_API FILE *octave_popen (const char *command, const char *mode);
+extern OCTINTERP_API int octave_pclose (FILE *f);
+
+extern OCTINTERP_API int octave_kbhit (bool wait = true);
+
+extern void w32_set_quiet_shutdown (void);
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+extern void MINGW_signal_cleanup (void);
+#define USE_W32_SIGINT 1
+#define MINGW_SIGNAL_CLEANUP() MINGW_signal_cleanup ()
+#else
+#define MINGW_SIGNAL_CLEANUP() do { } while (0)
+#endif
+
+extern OCTINTERP_API bool same_file_internal (const std::string&, const std::string&);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/token.cc b/src/token.cc
new file mode 100644
index 0000000..2bde0d3
--- /dev/null
+++ b/src/token.cc
@@ -0,0 +1,135 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005,
+              2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "error.h"
+#include "oct-obj.h"
+#include "symtab.h"
+#include "token.h"
+#include "utils.h"
+
+token::token (int l, int c)
+{
+  line_num = l;
+  column_num = c;
+  type_tag = generic_token;
+}
+
+token::token (const std::string& s, int l, int c)
+{
+  line_num = l;
+  column_num = c;
+  type_tag = string_token;
+  str = new std::string (s);
+}
+
+token::token (double d, const std::string& s, int l, int c)
+{
+  line_num = l;
+  column_num = c;
+  type_tag = double_token;
+  num = d;
+  orig_text = s;
+}
+
+token::token (end_tok_type t, int l, int c)
+{
+  line_num = l;
+  column_num = c;
+  type_tag = ettype_token;
+  et = t;
+}
+
+token::token (plot_tok_type t, int l, int c)
+{
+  line_num = l;
+  column_num = c;
+  type_tag = pttype_token;
+  pt = t;
+}
+
+token::token (symbol_table::symbol_record *s, int l, int c)
+{
+  line_num = l;
+  column_num = c;
+  type_tag = sym_rec_token;
+  sr = s;
+}
+
+token::~token (void)
+{
+  if (type_tag == string_token)
+    delete str;
+}
+
+std::string
+token::text (void)
+{
+  assert (type_tag == string_token);
+  return *str;
+}
+
+double
+token::number (void)
+{
+  assert (type_tag == double_token);
+  return num;
+}
+
+token::end_tok_type
+token::ettype (void)
+{
+  assert (type_tag == ettype_token);
+  return et;
+}
+
+token::plot_tok_type
+token::pttype (void)
+{
+  assert (type_tag == pttype_token);
+  return pt;
+}
+
+symbol_table::symbol_record *
+token::sym_rec (void)
+{
+  assert (type_tag == sym_rec_token);
+  return sr;
+}
+
+std::string
+token::text_rep (void)
+{
+  return orig_text;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/token.h b/src/token.h
new file mode 100644
index 0000000..03d2240
--- /dev/null
+++ b/src/token.h
@@ -0,0 +1,112 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005,
+              2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_token_h)
+#define octave_token_h 1
+
+#include <string>
+
+class
+token
+{
+public:
+
+  enum token_type
+    {
+      generic_token,
+      string_token,
+      double_token,
+      ettype_token,
+      pttype_token,
+      sym_rec_token
+    };
+
+  enum end_tok_type
+    {
+      simple_end,
+      for_end,
+      function_end,
+      if_end,
+      switch_end,
+      while_end,
+      try_catch_end,
+      unwind_protect_end
+    };
+
+  enum plot_tok_type
+    {
+      replot = 1,
+      two_dee = 2,
+      three_dee = 3
+    };
+
+  token (int l = -1, int c = -1);
+  token (const std::string& s, int l = -1, int c = -1);
+  token (double d, const std::string& s = std::string (),
+	 int l = -1, int c = -1);
+  token (end_tok_type t, int l = -1, int c = -1);
+  token (plot_tok_type t, int l = -1, int c = -1);
+  token (symbol_table::symbol_record *s, int l = -1, int c = -1);
+
+  ~token (void);
+
+  int line (void) { return line_num; }
+  int column (void) { return column_num; }
+
+  std::string text (void);
+  double number (void);
+  end_tok_type ettype (void);
+  plot_tok_type pttype (void);
+  symbol_table::symbol_record *sym_rec (void);
+
+  std::string text_rep (void);
+
+private:
+
+  // No copying!
+
+  token (const token& tok);
+
+  token& operator = (const token& tok);
+
+  int line_num;
+  int column_num;
+  token_type type_tag;
+  union
+    {
+      std::string *str;
+      double num;
+      end_tok_type et;
+      plot_tok_type pt;
+      symbol_table::symbol_record *sr;
+    };
+  std::string orig_text;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/toplev.cc b/src/toplev.cc
new file mode 100644
index 0000000..a361ee7
--- /dev/null
+++ b/src/toplev.cc
@@ -0,0 +1,1426 @@
+/*
+
+Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <new>
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "cmd-edit.h"
+#include "file-ops.h"
+#include "lo-error.h"
+#include "lo-mappers.h"
+#include "oct-env.h"
+#include "quit.h"
+#include "str-vec.h"
+#include "oct-locbuf.h"
+
+#include <defaults.h>
+#include "defun.h"
+#include "error.h"
+#include "file-io.h"
+#include "input.h"
+#include "lex.h"
+#include <oct-conf.h>
+#include "oct-hist.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "parse.h"
+#include "pathsearch.h"
+#include "procstream.h"
+#include "ov.h"
+#include "pt-eval.h"
+#include "pt-jump.h"
+#include "pt-stmt.h"
+#include "sighandlers.h"
+#include "sysdep.h"
+#include "syswait.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include <version.h>
+
+void (*octave_exit) (int) = ::exit;
+
+// TRUE means the quit() call is allowed.
+bool quit_allowed = true;
+
+// TRUE means we are exiting via the builtin exit or quit functions.
+bool quitting_gracefully = false;
+// This stores the exit status.
+int exit_status = 0;
+
+// TRUE means we are ready to interpret commands, but not everything
+// is ready for interactive use.
+bool octave_interpreter_ready = false;
+
+// TRUE means we've processed all the init code and we are good to go.
+bool octave_initialized = false;
+
+// Current command to execute.
+tree_statement_list *global_command = 0;
+
+octave_call_stack *octave_call_stack::instance = 0;
+
+int
+octave_call_stack::do_current_line (void) const
+{
+  tree_statement *stmt = do_top_statement ();
+
+  return stmt ? stmt->line () : -1;
+}
+
+int
+octave_call_stack::do_current_column (void) const
+{
+  tree_statement *stmt = do_top_statement ();
+
+  return stmt ? stmt->column () : -1;
+}
+
+int
+octave_call_stack::do_caller_user_code_line (void) const
+{
+  int retval = -1;
+
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
+    {
+      const call_stack_elt& elt = *(--p);
+
+      octave_function *f = elt.fcn;
+
+      if (f && f->is_user_code ())
+	{
+	  tree_statement *stmt = elt.stmt;
+
+	  if (stmt)
+	    {
+	      retval = stmt->line ();
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+int
+octave_call_stack::do_caller_user_code_column (void) const
+{
+  int retval = -1;
+
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
+    {
+      const call_stack_elt& elt = *(--p);
+
+      octave_function *f = elt.fcn;
+
+      if (f && f->is_user_code ())
+	{
+	  tree_statement *stmt = elt.stmt;
+
+	  if (stmt)
+	    {
+	      retval = stmt->column ();
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+size_t
+octave_call_stack::do_num_user_code_frames (octave_idx_type& curr_user_frame) const
+{
+  size_t retval = 0;
+
+  curr_user_frame = 0;
+
+  // Look for the caller of dbstack.
+  size_t frame = cs[curr_frame].prev;
+
+  bool found = false;
+
+  size_t k = cs.size ();
+
+  for (const_reverse_iterator p = cs.rbegin (); p != cs.rend (); p++)
+    {
+      octave_function *f = (*p).fcn;
+
+      if (--k == frame)
+	found = true;
+
+      if (f && f->is_user_code ())
+	{
+	  if (! found)
+	    curr_user_frame++;
+
+	  retval++;
+	}
+    }
+
+  // We counted how many user frames were not the one, in reverse.
+  // Now set curr_user_frame to be the index in the other direction.
+  curr_user_frame = retval - curr_user_frame - 1;
+
+  return retval;
+}
+
+octave_user_code *
+octave_call_stack::do_caller_user_code (size_t nskip) const
+{
+  octave_user_code *retval = 0;
+
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
+    {
+      const call_stack_elt& elt = *(--p);
+
+      octave_function *f = elt.fcn;
+
+      if (f && f->is_user_code ())
+	{
+	  if (nskip > 0)
+	    nskip--;
+	  else
+	    {
+	      retval = dynamic_cast<octave_user_code *> (f);
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+Octave_map
+octave_call_stack::do_backtrace (size_t nskip,
+				 octave_idx_type& curr_user_frame) const
+{
+  Octave_map retval;
+
+  size_t user_code_frames = do_num_user_code_frames (curr_user_frame);
+
+  size_t nframes = nskip <= user_code_frames ? user_code_frames - nskip : 0;
+
+  // Our list is reversed.
+  curr_user_frame = nframes - curr_user_frame - 1;
+
+  Cell keys (6, 1);
+
+  keys(0) = "file";
+  keys(1) = "name";
+  keys(2) = "line";
+  keys(3) = "column";
+  keys(4) = "scope";
+  keys(5) = "context";
+
+  Cell file (nframes, 1);
+  Cell name (nframes, 1);
+  Cell line (nframes, 1);
+  Cell column (nframes, 1);
+  Cell scope (nframes, 1);
+  Cell context (nframes, 1);
+
+  if (nframes > 0)
+    {
+      int k = 0;
+
+      for (const_reverse_iterator p = cs.rbegin (); p != cs.rend (); p++)
+	{
+	  const call_stack_elt& elt = *p;
+
+	  octave_function *f = elt.fcn;
+
+	  if (f && f->is_user_code ())
+	    {
+	      if (nskip > 0)
+		nskip--;
+	      else
+		{
+		  scope(k) = elt.scope;
+		  context(k) = elt.context;
+
+		  file(k) = f->fcn_file_name ();
+		  std::string parent_fcn_name = f->parent_fcn_name ();
+		  if (parent_fcn_name == std::string ())
+		    name(k) = f->name ();
+		  else
+		    name(k) = f->parent_fcn_name () + Vfilemarker + f->name ();
+
+		  tree_statement *stmt = elt.stmt;
+
+		  if (stmt)
+		    {
+		      line(k) = stmt->line ();
+		      column(k) = stmt->column ();
+		    }
+		  else
+		    {
+		      line(k) = -1;
+		      column(k) = -1;
+		    }
+
+		  k++;
+		}
+	    }
+	}
+
+      retval.assign ("file", file);
+      retval.assign ("name", name);
+      retval.assign ("line", line);
+      retval.assign ("column", column);
+      retval.assign ("scope", scope);
+      retval.assign ("context", context);
+    }
+
+  return retval;
+}
+
+bool
+octave_call_stack::do_goto_frame (size_t n, bool verbose)
+{
+  bool retval = false;
+
+  if (n < cs.size ())
+    {
+      retval = true;
+
+      curr_frame = n;
+
+      const call_stack_elt& elt = cs[n];
+
+      symbol_table::set_scope_and_context (elt.scope, elt.context);
+
+      if (verbose)
+	{
+	  octave_function *f = elt.fcn;
+	  std::string nm = f ? f->name () : std::string ("<unknown>");
+
+	  tree_statement *s = elt.stmt;
+	  int l = -1;
+	  int c = -1;
+	  if (s)
+	    {
+	      l = s->line ();
+	      c = s->column ();
+	    }
+
+	  octave_stdout << "stopped in " << nm
+			<< " at line " << l << " column " << c
+			<< " (" << elt.scope << "[" << elt.context << "])"
+			<< std::endl;
+	}
+    }
+
+  return retval;
+}
+
+bool
+octave_call_stack::do_goto_frame_relative (int nskip, bool verbose)
+{
+  bool retval = false;
+
+  int incr = 0;
+
+  if (nskip < 0)
+    incr = -1;
+  else if (nskip > 0)
+    incr = 1;
+
+  // Start looking with the caller of dbup/dbdown/keyboard.
+  size_t frame = cs[curr_frame].prev;
+
+  while (true)
+    {
+      if ((incr < 0 && frame == 0) || (incr > 0 && frame == cs.size () - 1))
+	break;
+
+      frame += incr;
+
+      const call_stack_elt& elt = cs[frame];
+
+      octave_function *f = elt.fcn;
+
+      if (f && f->is_user_code ())
+	{
+	  if (nskip > 0)
+	    nskip--;
+	  else if (nskip < 0)
+	    nskip++;
+
+	  if (nskip == 0)
+	    {
+	      curr_frame = frame;
+	      cs[cs.size () - 1].prev = curr_frame;
+
+	      symbol_table::set_scope_and_context (elt.scope, elt.context);
+
+	      if (verbose)
+		{
+		  tree_statement *s = elt.stmt;
+		  int l = -1;
+		  int c = -1;
+		  if (s)
+		    {
+		      l = s->line ();
+		      c = s->column ();
+		    }
+
+		  std::ostringstream buf;
+		  buf << f->name () << ": " << " line " << l
+		      << ", column " << c << std::endl;
+
+		  octave_stdout << buf.str ();
+		}
+
+	      retval = true;
+	      break;
+	    }
+	}
+
+      // There is no need to set scope and context here.  That will
+      // happen when the dbup/dbdown/keyboard frame is popped and we
+      // jump to the new "prev" frame set above.
+    }
+
+  return retval;
+}
+
+void
+octave_call_stack::do_goto_caller_frame (void)
+{
+  size_t frame = curr_frame;
+
+  bool skipped = false;
+
+  while (frame != 0)
+    {
+      frame = cs[frame].prev;
+
+      const call_stack_elt& elt = cs[frame];
+
+      octave_function *f = elt.fcn;
+
+      if (frame == 0 || (f && f->is_user_code ()))
+	{
+	  if (! skipped)
+	    // We found the current user code frame, so skip it.
+	    skipped = true;
+	  else
+	    {
+	      // We found the caller user code frame.
+	      call_stack_elt tmp (elt);
+	      tmp.prev = curr_frame;
+
+	      curr_frame = cs.size ();
+
+	      cs.push_back (tmp);
+
+	      symbol_table::set_scope_and_context (tmp.scope, tmp.context);
+
+	      break;
+	    }
+	}
+    }
+}
+
+void
+octave_call_stack::do_goto_base_frame (void)
+{
+  call_stack_elt tmp (cs[0]);
+  tmp.prev = curr_frame;
+
+  curr_frame = cs.size ();
+
+  cs.push_back (tmp);
+
+  symbol_table::set_scope_and_context (tmp.scope, tmp.context);
+}
+
+void
+octave_call_stack::do_backtrace_error_message (void) const
+{
+  if (error_state > 0)
+    {
+      error_state = -1;
+
+      error ("called from:");
+    }
+
+  if (! cs.empty ())
+    {
+      const call_stack_elt& elt = cs.back ();
+
+      octave_function *fcn = elt.fcn;
+      tree_statement *stmt = elt.stmt;
+
+      std::string fcn_name = "?unknown?";
+
+      if (fcn)
+	{
+	  fcn_name = fcn->fcn_file_name ();
+
+	  if (fcn_name.empty ())
+	    fcn_name = fcn->name ();
+	}
+
+      int line = stmt ? stmt->line () : -1;
+      int column = stmt ? stmt->column () : -1;
+
+      error ("  %s at line %d, column %d",
+	     fcn_name.c_str (), line, column);
+    }
+}
+
+void
+recover_from_exception (void)
+{
+  can_interrupt = true;
+  octave_interrupt_immediately = 0;
+  octave_interrupt_state = 0;
+  octave_signal_caught = 0;
+  octave_exception_state = octave_no_exception;
+  octave_restore_signal_mask ();
+  octave_catch_interrupts ();
+}
+
+int
+main_loop (void)
+{
+  octave_save_signal_mask ();
+
+  can_interrupt = true;
+
+  octave_signal_hook = octave_signal_handler;
+  octave_interrupt_hook = unwind_protect::run_all;
+  octave_bad_alloc_hook = unwind_protect::run_all;
+
+  octave_catch_interrupts ();
+
+  octave_initialized = true;
+
+  // The big loop.
+
+  int retval = 0;
+  do
+    {
+      try
+	{
+	  unwind_protect::begin_frame ("main_loop");
+
+	  reset_error_handler ();
+
+	  reset_parser ();
+
+	  // Do this with an unwind-protect cleanup function so that
+	  // the forced variables will be unmarked in the event of an
+	  // interrupt.
+	  symbol_table::scope_id scope = symbol_table::top_scope ();
+	  unwind_protect::add (symbol_table::unmark_forced_variables, &scope);
+
+	  // This is the same as yyparse in parse.y.
+	  retval = octave_parse ();
+
+	  if (retval == 0)
+	    {
+	      if (global_command)
+		{
+		  global_command->accept (*current_evaluator);
+
+		  delete global_command;
+
+		  global_command = 0;
+
+		  OCTAVE_QUIT;
+
+		  if (! (interactive || forced_interactive))
+		    {
+		      bool quit = (tree_return_command::returning
+				   || tree_break_command::breaking);
+
+		      if (tree_return_command::returning)
+			tree_return_command::returning = 0;
+
+		      if (tree_break_command::breaking)
+			tree_break_command::breaking--;
+
+		      if (quit)
+			break;
+		    }
+
+		  if (error_state)
+		    {
+		      if (! (interactive || forced_interactive))
+			{
+			  // We should exit with a non-zero status.
+			  retval = 1;
+			  break;
+			}
+		    }
+		  else
+		    {
+		      if (octave_completion_matches_called)
+			octave_completion_matches_called = false;	    
+		      else
+			command_editor::increment_current_command_number ();
+		    }
+		}
+	      else if (parser_end_of_input)
+		break;
+	    }
+
+	  unwind_protect::run_frame ("main_loop");
+	}
+      catch (octave_interrupt_exception)
+	{
+	  recover_from_exception ();
+          octave_stdout << "\n";
+          if (quitting_gracefully)
+            {
+              clean_up_and_exit (exit_status);
+              break; // If user has overriden the exit func.
+            }
+	}
+      catch (octave_execution_exception)
+	{
+	  recover_from_exception ();
+	  std::cerr
+	    << "error: unhandled execution exception -- trying to return to prompt"
+	    << std::endl;
+	}
+      catch (std::bad_alloc)
+	{
+	  recover_from_exception ();
+	  std::cerr
+	    << "error: memory exhausted or requested size too large for range of Octave's index type -- trying to return to prompt"
+	    << std::endl;
+	}
+    }
+  while (retval == 0);
+
+  return retval;
+}
+
+// Call a function with exceptions handled to avoid problems with
+// errors while shutting down.
+
+#define IGNORE_EXCEPTION(E) \
+  catch (E) \
+    { \
+      std::cerr << "error: ignoring " #E " while preparing to exit" << std::endl; \
+      recover_from_exception (); \
+    }
+
+#define SAFE_CALL(F, ARGS) \
+  try \
+    { \
+      F ARGS; \
+    } \
+  IGNORE_EXCEPTION (octave_interrupt_exception) \
+  IGNORE_EXCEPTION (octave_execution_exception) \
+  IGNORE_EXCEPTION (std::bad_alloc)
+
+// Fix up things before exiting.
+
+void
+clean_up_and_exit (int retval)
+{
+  do_octave_atexit ();
+
+  SAFE_CALL (sysdep_cleanup, ())
+
+  if (octave_exit)
+    (*octave_exit) (retval == EOF ? 0 : retval);
+}
+
+DEFUN (quit, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} exit (@var{status})\n\
+ at deftypefnx {Built-in Function} {} quit (@var{status})\n\
+Exit the current Octave session.  If the optional integer value\n\
+ at var{status} is supplied, pass that value to the operating system as the\n\
+Octave's exit status.  The default value is zero.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (! quit_allowed)
+    error ("quit: not supported in embedded mode.");
+  else if (nargout == 0)
+    {
+      if (args.length () > 0)
+	{
+	  int tmp = args(0).nint_value ();
+
+	  if (! error_state)
+	    exit_status = tmp;
+	}
+
+      if (! error_state)
+        {
+          quitting_gracefully = true;
+
+          // Simulate interrupt.
+
+          octave_interrupt_state = -1;
+
+          octave_throw_interrupt_exception ();
+        }
+    }
+  else
+    error ("quit: invalid number of output arguments");
+
+  return retval;
+}
+
+DEFALIAS (exit, quit);
+
+DEFUN (warranty, , ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} warranty ()\n\
+Describe the conditions for copying and distributing Octave.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  octave_stdout << "\n" \
+    OCTAVE_NAME_VERSION_AND_COPYRIGHT "\n\
+\n\
+This program is free software; you can redistribute it and/or modify\n\
+it under the terms of the GNU General Public License as published by\n\
+the Free Software Foundation; either version 3 of the License, or\n\
+(at your option) any later version.\n\
+\n\
+This program is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
+GNU General Public License for more details.\n\
+\n\
+You should have received a copy of the GNU General Public License\n\
+along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\
+\n";
+
+  return retval;
+}
+
+// Execute a shell command.
+
+static void
+cleanup_iprocstream (void *p)
+{
+  iprocstream *cmd = static_cast<iprocstream *> (p);
+
+  octave_child_list::remove (cmd->pid ());
+
+  delete cmd;
+}
+
+static int
+wait_for_input (int fid)
+{
+  int retval = -1;
+
+#if defined (HAVE_SELECT)
+  if (fid >= 0)
+    {
+      fd_set set;
+
+      FD_ZERO (&set);
+      FD_SET (fid, &set);
+
+      retval = select (FD_SETSIZE, &set, 0, 0, 0);
+    }
+#else
+  retval = 1;
+#endif
+
+  return retval;
+}
+
+static octave_value_list
+run_command_and_return_output (const std::string& cmd_str)
+{
+  octave_value_list retval;
+
+  iprocstream *cmd = new iprocstream (cmd_str.c_str ());
+
+  if (cmd)
+    {
+      unwind_protect::add (cleanup_iprocstream, cmd);
+
+      if (*cmd)
+	{
+	  int fid = cmd->file_number ();
+
+	  std::ostringstream output_buf;
+
+	  char ch;
+
+	  for (;;)
+	    {
+	      if (cmd->get (ch))
+		output_buf.put (ch);
+	      else
+		{
+		  if (! cmd->eof () && errno == EAGAIN)
+		    {
+		      cmd->clear ();
+
+		      if (wait_for_input (fid) != 1)
+			break;			
+		    }
+		  else
+		    break;
+		}
+	    }
+
+	  int cmd_status = cmd->close ();
+
+	  if (WIFEXITED (cmd_status))
+	    cmd_status = WEXITSTATUS (cmd_status);
+	  else
+	    cmd_status = 127;
+
+	  retval(0) = cmd_status;
+	  retval(1) = output_buf.str ();
+	}
+
+      unwind_protect::run ();
+    }
+  else
+    error ("unable to start subprocess for `%s'", cmd_str.c_str ());
+
+  return retval;
+}
+
+enum system_exec_type { et_sync, et_async };
+
+DEFUN (system, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} system (@var{string}, @var{return_output}, @var{type})\n\
+Execute a shell command specified by @var{string}.  The second\n\
+argument is optional.  If @var{type} is @code{\"async\"}, the process\n\
+is started in the background and the process id of the child process\n\
+is returned immediately.  Otherwise, the process is started, and\n\
+Octave waits until it exits.  If the @var{type} argument is omitted, a\n\
+value of @code{\"sync\"} is assumed.\n\
+\n\
+If two input arguments are given (the actual value of\n\
+ at var{return_output} is irrelevant) and the subprocess is started\n\
+synchronously, or if @var{system} is called with one input argument and\n\
+one or more output arguments, the output from the command is returned.\n\
+Otherwise, if the subprocess is executed synchronously, its output is\n\
+sent to the standard output.  To send the output of a command executed\n\
+with @var{system} through the pager, use a command like\n\
+\n\
+ at example\n\
+disp (system (cmd, 1));\n\
+ at end example\n\
+\n\
+ at noindent\n\
+or\n\
+\n\
+ at example\n\
+printf (\"%s\\n\", system (cmd, 1));\n\
+ at end example\n\
+\n\
+The @code{system} function can return two values.  The first is the\n\
+exit status of the command and the second is any output from the\n\
+command that was written to the standard output stream.  For example,\n\
+\n\
+ at example\n\
+[status, output] = system (\"echo foo; exit 2\");\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will set the variable @code{output} to the string @samp{foo}, and the\n\
+variable @code{status} to the integer @samp{2}.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  unwind_protect::begin_frame ("Fsystem");
+
+  int nargin = args.length ();
+
+  if (nargin > 0 && nargin < 4)
+    {
+      bool return_output = (nargout > 1 || nargin > 1);
+
+      std::string cmd_str = args(0).string_value ();
+
+      system_exec_type type = et_sync;
+
+      if (! error_state)
+	{
+	  if (nargin > 2)
+	    {
+	      std::string type_str = args(2).string_value ();
+
+	      if (! error_state)
+		{
+		  if (type_str == "sync")
+		    type = et_sync;
+		  else if (type_str == "async")
+		    type = et_async;
+		  else
+		    error ("system: third arg must be \"sync\" or \"async\"");
+		}
+	      else
+		error ("system: third argument must be a string");
+	    }
+	}
+      else
+	error ("system: expecting std::string as first argument");
+
+      if (! error_state)
+	{
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+	  // Work around weird double-quote handling on Windows systems.
+          if (type == et_sync)
+            cmd_str = "\"" + cmd_str + "\"";
+#endif
+
+	  if (type == et_async)
+	    {
+	      // FIXME -- maybe this should go in sysdep.cc?
+#ifdef HAVE_FORK
+	      pid_t pid = fork ();
+
+	      if (pid < 0) 
+		error ("system: fork failed -- can't create child process");
+	      else if (pid == 0)
+		{
+		  // FIXME -- should probably replace this
+		  // call with something portable.
+
+		  execl ("/bin/sh", "sh", "-c", cmd_str.c_str (),
+			 static_cast<void *> (0));
+
+		  panic_impossible ();
+		}
+	      else
+		retval(0) = pid;
+#elif defined (__WIN32__)
+              STARTUPINFO si;
+              PROCESS_INFORMATION pi;
+              ZeroMemory (&si, sizeof (si));
+              ZeroMemory (&pi, sizeof (pi));
+	      OCTAVE_LOCAL_BUFFER (char, xcmd_str, cmd_str.length()+1);
+	      strcpy (xcmd_str, cmd_str.c_str ());
+
+              if (! CreateProcess (0, xcmd_str, 0, 0, FALSE, 0, 0, 0, &si, &pi))
+                error ("system: CreateProcess failed -- can't create child process");
+              else
+                {
+                  retval(0) = pi.dwProcessId;
+                  CloseHandle (pi.hProcess);
+                  CloseHandle (pi.hThread);
+                }
+#else
+ 	      error ("asynchronous system calls are not supported");
+#endif
+	    }
+	  else if (return_output)
+	    retval = run_command_and_return_output (cmd_str);
+	  else
+	    {
+	      int status = system (cmd_str.c_str ());
+
+	      // The value in status is as returned by waitpid.  If
+	      // the process exited normally, extract the actual exit
+	      // status of the command.  Otherwise, return 127 as a
+	      // failure code.
+
+	      if (WIFEXITED (status))
+		status = WEXITSTATUS (status);
+
+	      retval(0) = status;
+	    }
+	}
+    }
+  else
+    print_usage ();
+
+  unwind_protect::run_frame ("Fsystem");
+
+  return retval;
+}
+
+DEFALIAS (shell_cmd, system);
+
+// FIXME -- this should really be static, but that causes
+// problems on some systems.
+std::list<std::string> octave_atexit_functions;
+
+void
+do_octave_atexit (void)
+{
+  static bool deja_vu = false;
+
+  while (! octave_atexit_functions.empty ())
+    {
+      std::string fcn = octave_atexit_functions.front ();
+
+      octave_atexit_functions.pop_front ();
+
+      SAFE_CALL (reset_error_handler, ())
+
+      SAFE_CALL (feval, (fcn, octave_value_list (), 0))
+
+      SAFE_CALL (flush_octave_stdout, ())
+    }
+
+  if (! deja_vu)
+    {
+      deja_vu = true;
+
+      // Do this explicitly so that destructors for mex file objects
+      // are called, so that functions registered with mexAtExit are
+      // called.
+      SAFE_CALL (clear_mex_functions, ())
+
+	SAFE_CALL (command_editor::restore_terminal_state, ())
+
+      // FIXME -- is this needed?  Can it cause any trouble?
+      SAFE_CALL (raw_mode, (0))
+
+      SAFE_CALL (octave_history_write_timestamp, ())
+
+      if (Vsaving_history)
+	SAFE_CALL (command_history::clean_up_and_save, ())
+
+      SAFE_CALL (close_files, ())
+
+      SAFE_CALL (cleanup_tmp_files, ())
+
+      SAFE_CALL (flush_octave_stdout, ())
+
+      if (! quitting_gracefully && (interactive || forced_interactive))
+	{
+	  octave_stdout << "\n";
+
+	  // Yes, we want this to be separate from the call to
+	  // flush_octave_stdout above.
+
+	  SAFE_CALL (flush_octave_stdout, ())
+	}
+    }
+}
+
+void
+octave_add_atexit_function (const std::string& fname)
+{
+  octave_atexit_functions.push_front (fname);
+}
+
+bool
+octave_remove_atexit_function (const std::string& fname)
+{
+  bool found = false;
+
+  for (std::list<std::string>::iterator p = octave_atexit_functions.begin ();
+       p != octave_atexit_functions.end (); p++)
+    {
+      if (*p == fname)
+	{
+	  octave_atexit_functions.erase (p);
+	  found = true;
+	  break;
+	}
+    }
+
+  return found;
+}
+
+
+DEFUN (atexit, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} atexit (@var{fcn})\n\
+ at deftypefnx {Built-in Function} {} atexit (@var{fcn}, @var{flag})\n\
+Register a function to be called when Octave exits.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+function last_words ()\n\
+  disp (\"Bye bye\");\n\
+endfunction\n\
+atexit (\"last_words\");\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will print the message \"Bye bye\" when Octave exits.\n\
+\n\
+The additional argument @var{flag} will register or unregister\n\
+ at var{fcn} from the list of functions to be called when Octave\n\
+exits.  If @var{flag} is true, the function is registered, and if\n\
+ at var{flag} is false, it is unregistered.  For example,\n\
+after registering the function @code{last_words} above,\n\
+\n\
+ at example\n\
+atexit (\"last_words\", false);\n\
+ at end example\n\
+\n\
+ at noindent\n\
+will remove the function from the list and Octave will not call\n\
+ at code{last_words} when it exits.\n\
+\n\
+Note that @code{atexit} only removes the first occurrence of a function\n\
+from the list, so if a function was placed in the list multiple\n\
+times with @code{atexit}, it must also be removed from the list\n\
+multiple times.\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string arg = args(0).string_value ();
+
+      if (! error_state)
+        {
+          bool add_mode = true;
+
+          if (nargin == 2)
+            {
+              add_mode = args(1).bool_value ();
+
+              if (error_state)
+                error ("atexit: second argument must be a logical value");
+            }
+
+          if (! error_state)
+	    {
+	      if (add_mode)
+		octave_add_atexit_function (arg);
+	      else
+		{
+		  bool found = octave_remove_atexit_function (arg);
+
+		  if (nargout > 0)
+		    retval(0) = found;
+		}
+	    }
+	}
+      else
+        error ("atexit: argument must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (octave_config_info, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} octave_config_info (@var{option})\n\
+Return a structure containing configuration and installation\n\
+information for Octave.\n\
+\n\
+if @var{option} is a string, return the configuration information for the\n\
+specified option.\n\
+\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+#if defined (ENABLE_DYNAMIC_LINKING)
+  bool octave_supports_dynamic_linking = true;
+#else
+  bool octave_supports_dynamic_linking = false;
+#endif
+
+  static bool initialized = false;
+  static Octave_map m;
+
+  struct conf_info_struct
+  {
+    bool subst_home;
+    const char *key;
+    const char *val;
+  };
+
+  static const conf_info_struct conf_info[] =
+    {
+      { false, "ALL_CFLAGS", OCTAVE_CONF_ALL_CFLAGS },
+      { false, "ALL_CXXFLAGS", OCTAVE_CONF_ALL_CXXFLAGS },
+      { false, "ALL_FFLAGS", OCTAVE_CONF_ALL_FFLAGS },
+      { false, "ALL_LDFLAGS", OCTAVE_CONF_ALL_LDFLAGS },
+      { false, "AR", OCTAVE_CONF_AR },
+      { false, "ARFLAGS", OCTAVE_CONF_ARFLAGS },
+      { false, "BLAS_LIBS", OCTAVE_CONF_BLAS_LIBS },
+      { false, "CARBON_LIBS", OCTAVE_CONF_CARBON_LIBS },
+      { false, "CC", OCTAVE_CONF_CC },
+      { false, "CC_VERSION", OCTAVE_CONF_CC_VERSION },
+      { false, "CFLAGS", OCTAVE_CONF_CFLAGS },
+      { false, "CPICFLAG", OCTAVE_CONF_CPICFLAG },
+      { false, "CPPFLAGS", OCTAVE_CONF_CPPFLAGS },
+      { false, "CURL_LIBS", OCTAVE_CONF_CURL_LIBS },
+      { false, "CXX", OCTAVE_CONF_CXX },
+      { false, "CXXCPP", OCTAVE_CONF_CXXCPP },
+      { false, "CXXFLAGS", OCTAVE_CONF_CXXFLAGS },
+      { false, "CXXPICFLAG", OCTAVE_CONF_CXXPICFLAG },
+      { false, "CXX_VERSION", OCTAVE_CONF_CXX_VERSION },
+      { false, "DEFAULT_PAGER", OCTAVE_DEFAULT_PAGER },
+      { false, "DEFS", OCTAVE_CONF_DEFS },
+      { false, "DL_LD", OCTAVE_CONF_DL_LD },
+      { false, "DL_LDFLAGS", OCTAVE_CONF_DL_LDFLAGS },
+      { false, "ENABLE_DYNAMIC_LINKING", OCTAVE_CONF_ENABLE_DYNAMIC_LINKING },
+      { false, "EXEEXT", OCTAVE_CONF_EXEEXT },
+      { false, "F77", OCTAVE_CONF_F77 },
+      { false, "F77_FLOAT_STORE_FLAG", OCTAVE_CONF_F77_FLOAT_STORE_FLAG },
+      { false, "FC", OCTAVE_CONF_FC },
+      { false, "FFLAGS", OCTAVE_CONF_FFLAGS },
+      { false, "FFTW_LIBS", OCTAVE_CONF_FFTW_LIBS },
+      { false, "FLIBS", OCTAVE_CONF_FLIBS },
+      { false, "FPICFLAG", OCTAVE_CONF_FPICFLAG },
+      { false, "GLPK_LIBS", OCTAVE_CONF_GLPK_LIBS },
+      { false, "GNUPLOT", OCTAVE_CONF_GNUPLOT },
+      { false, "INCFLAGS", OCTAVE_CONF_INCFLAGS },
+      { false, "LDFLAGS", OCTAVE_CONF_LDFLAGS },
+      { false, "LD_CXX", OCTAVE_CONF_LD_CXX },
+      { false, "LD_STATIC_FLAG", OCTAVE_CONF_LD_STATIC_FLAG },
+      { false, "LEX", OCTAVE_CONF_LEX },
+      { false, "LEXLIB", OCTAVE_CONF_LEXLIB },
+      { false, "LFLAGS", OCTAVE_CONF_LFLAGS },
+      { false, "LIBCRUFT", OCTAVE_CONF_LIBCRUFT },
+      { false, "LIBEXT", OCTAVE_CONF_LIBEXT },
+      { false, "LIBFLAGS", OCTAVE_CONF_LIBFLAGS },
+      { false, "LIBOCTAVE", OCTAVE_CONF_LIBOCTAVE },
+      { false, "LIBOCTINTERP", OCTAVE_CONF_LIBOCTINTERP },
+      { false, "LIBREADLINE", OCTAVE_CONF_LIBREADLINE },
+      { false, "LIBS", OCTAVE_CONF_LIBS },
+      { false, "LN_S", OCTAVE_CONF_LN_S },
+      { false, "MAGICK_INCFLAGS", OCTAVE_CONF_MAGICK_INCFLAGS },
+      { false, "MAGICK_LIBS", OCTAVE_CONF_MAGICK_LIBS },
+      { false, "MKOCTFILE_DL_LDFLAGS", OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS },
+      { false, "RANLIB", OCTAVE_CONF_RANLIB },
+      { false, "RDYNAMIC_FLAG", OCTAVE_CONF_RDYNAMIC_FLAG },
+      { false, "RLD_FLAG", OCTAVE_CONF_RLD_FLAG },
+      { false, "SED", OCTAVE_CONF_SED },
+      { false, "SHARED_LIBS", OCTAVE_CONF_SHARED_LIBS },
+      { false, "SHLEXT", OCTAVE_CONF_SHLEXT },
+      { false, "SHLEXT_VER", OCTAVE_CONF_SHLEXT_VER },
+      { false, "SH_LD", OCTAVE_CONF_SH_LD },
+      { false, "SH_LDFLAGS", OCTAVE_CONF_SH_LDFLAGS },
+      { false, "SONAME_FLAGS", OCTAVE_CONF_SONAME_FLAGS },
+      { false, "STATIC_LIBS", OCTAVE_CONF_STATIC_LIBS },
+      { false, "UGLY_DEFS", OCTAVE_CONF_UGLY_DEFS },
+      { false, "USE_64_BIT_IDX_T", OCTAVE_CONF_USE_64_BIT_IDX_T },
+      { false, "X11_INCFLAGS", OCTAVE_CONF_X11_INCFLAGS },
+      { false, "X11_LIBS", OCTAVE_CONF_X11_LIBS },
+      { false, "XTRA_CFLAGS", OCTAVE_CONF_XTRA_CFLAGS },
+      { false, "XTRA_CXXFLAGS", OCTAVE_CONF_XTRA_CXXFLAGS },
+      { false, "YACC", OCTAVE_CONF_YACC },
+      { false, "YFLAGS", OCTAVE_CONF_YFLAGS },
+      { false, "api_version", OCTAVE_API_VERSION },
+      { true, "archlibdir", OCTAVE_ARCHLIBDIR },
+      { true, "bindir", OCTAVE_BINDIR },
+      { false, "canonical_host_type", OCTAVE_CANONICAL_HOST_TYPE },
+      { false, "config_opts", OCTAVE_CONF_config_opts },
+      { true, "datadir", OCTAVE_DATADIR },
+      { true, "datarootdir", OCTAVE_DATAROOTDIR },
+      { true, "exec_prefix", OCTAVE_EXEC_PREFIX },
+      { true, "fcnfiledir", OCTAVE_FCNFILEDIR },
+      { true, "imagedir", OCTAVE_IMAGEDIR },
+      { true, "includedir", OCTAVE_INCLUDEDIR },
+      { true, "infodir", OCTAVE_INFODIR },
+      { true, "infofile", OCTAVE_INFOFILE },
+      { true, "libdir", OCTAVE_LIBDIR },
+      { true, "libexecdir", OCTAVE_LIBEXECDIR },
+      { true, "localapiarchlibdir", OCTAVE_LOCALAPIARCHLIBDIR },
+      { true, "localapifcnfiledir", OCTAVE_LOCALAPIFCNFILEDIR },
+      { true, "localapioctfiledir", OCTAVE_LOCALAPIOCTFILEDIR },
+      { true, "localarchlibdir", OCTAVE_LOCALARCHLIBDIR },
+      { true, "localfcnfiledir", OCTAVE_LOCALFCNFILEDIR },
+      { true, "localoctfiledir", OCTAVE_LOCALOCTFILEDIR },
+      { true, "localstartupfiledir", OCTAVE_LOCALSTARTUPFILEDIR },
+      { true, "localverarchlibdir", OCTAVE_LOCALVERARCHLIBDIR },
+      { true, "localverfcnfiledir", OCTAVE_LOCALVERFCNFILEDIR },
+      { true, "localveroctfiledir", OCTAVE_LOCALVEROCTFILEDIR },
+      { true, "man1dir", OCTAVE_MAN1DIR },
+      { false, "man1ext", OCTAVE_MAN1EXT },
+      { true, "mandir", OCTAVE_MANDIR },
+      { true, "octfiledir", OCTAVE_OCTFILEDIR },
+      { true, "octetcdir", OCTAVE_OCTETCDIR },
+      { true, "octincludedir", OCTAVE_OCTINCLUDEDIR },
+      { true, "octlibdir", OCTAVE_OCTLIBDIR },
+      { true, "prefix", OCTAVE_PREFIX },
+      { true, "startupfiledir", OCTAVE_STARTUPFILEDIR },
+      { false, "version", OCTAVE_VERSION },
+      { false, 0, 0 }
+    };
+
+  if (! initialized)
+    {
+      m.assign ("dld", octave_value (octave_supports_dynamic_linking));
+
+      oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
+      m.assign ("float_format",
+		octave_value (oct_mach_info::float_format_as_string (ff)));
+
+      m.assign ("words_big_endian",
+		octave_value (oct_mach_info::words_big_endian ()));
+
+      m.assign ("words_little_endian",
+		octave_value (oct_mach_info::words_little_endian ()));
+
+      int i = 0;
+
+      while (true)
+	{
+	  const conf_info_struct& elt = conf_info[i++];
+
+	  const char *key = elt.key;
+
+	  if (key)
+	    {
+	      if (elt.subst_home)
+		m.assign (key, octave_value (subst_octave_home (elt.val)));
+	      else
+		m.assign (key, octave_value (elt.val));
+	    }
+	  else
+	    break;
+	}
+
+      bool unix_system = true;
+      bool mac_system = false;
+      bool windows_system = false;
+
+#if defined (WIN32)
+      windows_system = true;
+#if !defined (__CYGWIN__)
+      unix_system = false;
+#endif
+#endif
+
+#if defined (OCTAVE_USE_OS_X_API)
+      mac_system = true;
+#endif
+
+      m.assign ("unix", octave_value (unix_system));
+      m.assign ("mac", octave_value (mac_system));
+      m.assign ("windows", octave_value (windows_system));
+
+      initialized = true;
+    }
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string arg = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  Cell c = m.contents (arg.c_str ());
+
+	  if (c.is_empty ())
+	    error ("octave_config_info: no info for `%s'", arg.c_str ());
+	  else
+	    retval = c(0);
+	}
+    }
+  else if (nargin == 0)
+    retval = m;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+#if defined (__GNUG__) && defined (DEBUG_NEW_DELETE)
+
+int debug_new_delete = 0;
+
+typedef void (*vfp)(void);
+extern vfp __new_handler;
+
+void *
+__builtin_new (size_t sz)
+{
+  void *p;
+
+  /* malloc (0) is unpredictable; avoid it.  */
+  if (sz == 0)
+    sz = 1;
+  p = malloc (sz);
+  while (p == 0)
+    {
+      (*__new_handler) ();
+      p = malloc (sz);
+    }
+
+  if (debug_new_delete)
+    std::cerr << "__builtin_new: " << p << std::endl;
+
+  return p;
+}
+
+void
+__builtin_delete (void *ptr)
+{
+  if (debug_new_delete)
+    std::cerr << "__builtin_delete: " << ptr << std::endl;
+
+  if (ptr)
+    free (ptr);
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/toplev.h b/src/toplev.h
new file mode 100644
index 0000000..c829e9e
--- /dev/null
+++ b/src/toplev.h
@@ -0,0 +1,429 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_toplev_h)
+#define octave_toplev_h 1
+
+#include <cstdio>
+
+#include <deque>
+#include <string>
+
+class octave_value;
+class octave_value_list;
+class octave_function;
+class octave_user_script;
+class tree_statement;
+class tree_statement_list;
+class charMatrix;
+
+#include "quit.h"
+
+#include "input.h"
+#include "oct-map.h"
+
+
+typedef void (*octave_exit_func) (int);
+extern OCTINTERP_API octave_exit_func octave_exit;
+
+extern OCTINTERP_API bool quit_allowed;
+
+extern OCTINTERP_API bool quitting_gracefully;
+
+extern OCTINTERP_API int exit_status;
+
+extern OCTINTERP_API void
+clean_up_and_exit (int);
+
+extern OCTINTERP_API void recover_from_exception (void);
+
+extern OCTINTERP_API int main_loop (void);
+
+extern OCTINTERP_API void
+do_octave_atexit (void);
+
+extern OCTINTERP_API void
+octave_add_atexit_function (const std::string& fname);
+
+extern OCTINTERP_API bool
+octave_remove_atexit_function (const std::string& fname);
+
+// Current command to execute.
+extern OCTINTERP_API tree_statement_list *global_command;
+
+// TRUE means we are ready to interpret commands, but not everything
+// is ready for interactive use.
+extern OCTINTERP_API bool octave_interpreter_ready;
+
+// TRUE means we've processed all the init code and we are good to go.
+extern OCTINTERP_API bool octave_initialized;
+
+class
+OCTINTERP_API
+octave_call_stack
+{
+private:
+
+  struct call_stack_elt
+  {
+    call_stack_elt (octave_function *f, symbol_table::scope_id s,
+		    symbol_table::context_id c, size_t p = 0)
+      : fcn (f), stmt (0), scope (s), context (c), prev (p) { }
+
+    call_stack_elt (const call_stack_elt& elt)
+      : fcn (elt.fcn), stmt (elt.stmt), scope (elt.scope),
+	context (elt.context), prev (elt.prev) { }
+
+    octave_function *fcn;
+    tree_statement *stmt;
+    symbol_table::scope_id scope;
+    symbol_table::context_id context;
+    size_t prev;
+  };
+
+protected:
+
+  octave_call_stack (void) : cs (), curr_frame (0) { }
+
+public:
+
+  typedef std::deque<call_stack_elt>::iterator iterator;
+  typedef std::deque<call_stack_elt>::const_iterator const_iterator;
+
+  typedef std::deque<call_stack_elt>::reverse_iterator reverse_iterator;
+  typedef std::deque<call_stack_elt>::const_reverse_iterator const_reverse_iterator;
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      {
+	instance = new octave_call_stack ();
+
+	if (instance)
+	  instance->do_push (0, symbol_table::top_scope (), 0);
+	else
+	  {
+	    ::error ("unable to create call stack object!");
+
+	    retval = false;
+	  }
+      }
+
+    return retval;
+  }
+
+  // Current function (top of stack).
+  static octave_function *current (void) { return top (); }
+
+  // Current statement (top of stack).
+  static tree_statement *current_statement (void) { return top_statement (); }
+
+  // Current line in current function.
+  static int current_line (void)
+  {
+    return instance_ok () ? instance->do_current_line () : -1;
+  }
+
+  // Current column in current function.
+  static int current_column (void)
+  {
+    return instance_ok () ? instance->do_current_column () : -1;
+  }
+
+  // Line in user code caller.
+  static int caller_user_code_line (void)
+  {
+    return instance_ok () ? instance->do_caller_user_code_line () : -1;
+  }
+
+  // Column in user code caller.
+  static int caller_user_code_column (void)
+  {
+    return instance_ok () ? instance->do_caller_user_code_column () : -1;
+  }
+
+  // Caller function, may be built-in.
+  static octave_function *caller (void)
+  {
+    return instance_ok () ? instance->do_caller () : 0;
+  }
+
+  static size_t current_frame (void)
+  {
+    return instance_ok () ? instance->do_current_frame () : 0;
+  }
+
+  static size_t size (void)
+  {
+    return instance_ok () ? instance->do_size () : 0;
+  }
+
+  static size_t num_user_code_frames (octave_idx_type& curr_user_frame)
+  {
+    return instance_ok ()
+      ? instance->do_num_user_code_frames (curr_user_frame) : 0;
+  }
+
+  static symbol_table::scope_id current_scope (void)
+  {
+    return instance_ok () ? instance->do_current_scope () : 0;
+  }
+
+  static symbol_table::context_id current_context (void)
+  {
+    return instance_ok () ? instance->do_current_context () : 0;
+  }
+
+  // Function at location N on the call stack (N == 0 is current), may
+  // be built-in.
+  static octave_function *element (size_t n)
+  {
+    return instance_ok () ? instance->do_element (n) : 0;
+  }
+  
+  // First user-defined function on the stack.
+  static octave_user_code *caller_user_code (size_t nskip = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_code (nskip) : 0;
+  }
+
+  static void
+  push (octave_function *f,
+	symbol_table::scope_id scope = symbol_table::current_scope (),
+	symbol_table::context_id context = symbol_table::current_context ())
+  {
+    if (instance_ok ())
+      instance->do_push (f, scope, context);
+  }
+
+  static void
+  push (symbol_table::scope_id scope = symbol_table::current_scope (),
+	symbol_table::context_id context = symbol_table::current_context ())
+  {
+    if (instance_ok ())
+      instance->do_push (0, scope, context);
+  }
+
+  static octave_function *top (void)
+  {
+    return instance_ok () ? instance->do_top (): 0;
+  }
+
+  static tree_statement *top_statement (void)
+  {
+    return instance_ok () ? instance->do_top_statement (): 0;
+  }
+
+  static void set_statement (tree_statement *s)
+  {
+    if (instance_ok ())
+      instance->do_set_statement (s);
+  }
+
+  static bool goto_frame (size_t n = 0, bool verbose = false)
+  {
+    return instance_ok () ? instance->do_goto_frame (n, verbose) : false;
+  }
+
+  static bool goto_frame_relative (int n, bool verbose = false)
+  {
+    return instance_ok ()
+      ? instance->do_goto_frame_relative (n, verbose) : false;
+  }
+
+  static void goto_caller_frame (void)
+  {
+    if (instance_ok ())
+      instance->do_goto_caller_frame ();
+  }
+
+  static void goto_base_frame (void)
+  {
+    if (instance_ok ())
+      instance->do_goto_base_frame ();
+  }
+
+  static Octave_map backtrace (size_t nskip, octave_idx_type& curr_user_frame)
+  {
+    return instance_ok ()
+      ? instance->do_backtrace (nskip, curr_user_frame) : Octave_map ();
+  }
+
+  static void pop (void)
+  {
+    if (instance_ok ())
+      instance->do_pop ();
+  }
+  
+  // A function for popping the top of the call stack that is suitable
+  // for use as an unwind_protect handler.
+  static void unwind_pop (void *) { pop (); }
+
+  static void clear (void)
+  {
+    if (instance_ok ())
+      instance->do_clear ();
+  }
+
+  static void backtrace_error_message (void)
+  {
+    if (instance_ok ())
+      instance->do_backtrace_error_message ();
+  }
+
+private:
+
+  // The current call stack.
+  std::deque<call_stack_elt> cs;
+
+  size_t curr_frame;
+
+  static octave_call_stack *instance;
+
+  int do_current_line (void) const;
+
+  int do_current_column (void) const;
+
+  int do_caller_user_code_line (void) const;
+
+  int do_caller_user_code_column (void) const;
+
+  octave_function *do_caller (void) const
+  {
+    return curr_frame > 1 ? cs[curr_frame-1].fcn : cs[0].fcn;
+  }
+
+  size_t do_current_frame (void) { return curr_frame; }
+
+  size_t do_size (void) { return cs.size (); }
+
+  size_t do_num_user_code_frames (octave_idx_type& curr_user_frame) const;
+
+  symbol_table::scope_id do_current_scope (void) const
+  {
+    return curr_frame > 0 && curr_frame < cs.size ()
+      ? cs[curr_frame].scope : 0;
+  }
+
+  symbol_table::context_id do_current_context (void) const
+  {
+    return curr_frame > 0 && curr_frame < cs.size ()
+      ? cs[curr_frame].context : 0;
+  }
+
+  octave_function *do_element (size_t n)
+  {
+    octave_function *retval = 0;
+
+    if (cs.size () > n)
+      {
+	call_stack_elt& elt = cs[n];
+	retval = elt.fcn;
+      }
+
+    return retval;
+  }
+
+  octave_user_code *do_caller_user_code (size_t nskip) const; 
+
+  void do_push (octave_function *f, symbol_table::scope_id scope,
+		symbol_table::context_id context)
+  {
+    size_t prev_frame = curr_frame;
+    curr_frame = cs.size ();
+    cs.push_back (call_stack_elt (f, scope, context, prev_frame));
+    symbol_table::set_scope_and_context (scope, context);
+  }
+
+  octave_function *do_top (void) const
+  {
+    octave_function *retval = 0;
+
+    if (! cs.empty ())
+      {
+	const call_stack_elt& elt = cs.back ();
+	retval = elt.fcn;
+      }
+
+    return retval;
+  }
+
+  tree_statement *do_top_statement (void) const
+  {
+    tree_statement *retval = 0;
+
+    if (! cs.empty ())
+      {
+	const call_stack_elt& elt = cs.back ();
+	retval = elt.stmt;
+      }
+
+    return retval;
+  }
+
+  void do_set_statement (tree_statement *s)
+  {
+    if (! cs.empty ())
+      {
+	call_stack_elt& elt = cs.back ();
+	elt.stmt = s;
+      }
+  }
+
+  Octave_map do_backtrace (size_t nskip,
+			   octave_idx_type& curr_user_frame) const;
+
+  bool do_goto_frame (size_t n, bool verbose);
+
+  bool do_goto_frame_relative (int n, bool verbose);
+
+  void do_goto_caller_frame (void);
+
+  void do_goto_base_frame (void);
+
+  void do_pop (void)
+  {
+    if (cs.size () > 1)
+      {
+	const call_stack_elt& elt = cs.back ();
+	curr_frame = elt.prev;
+	cs.pop_back ();
+	const call_stack_elt& new_elt = cs[curr_frame];
+	symbol_table::set_scope_and_context (new_elt.scope, new_elt.context);
+      }
+  }
+
+  void do_clear (void) { cs.clear (); }
+
+  void do_backtrace_error_message (void) const;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/unwind-prot.cc b/src/unwind-prot.cc
new file mode 100644
index 0000000..04a0c5e
--- /dev/null
+++ b/src/unwind-prot.cc
@@ -0,0 +1,334 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+              2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstddef>
+#include <cstring>
+
+#include "CMatrix.h"
+
+#include "error.h"
+#include "unwind-prot.h"
+#include "utils.h"
+
+std::stack<unwind_elem> unwind_protect::elt_list;
+
+class
+saved_variable
+{
+public:
+
+  enum var_type
+  {
+    boolean,
+    integer,
+    size_type,
+    string_type,
+    generic_ptr,
+    generic
+  };
+
+  saved_variable (void);
+
+  saved_variable (bool *p, bool v);
+
+  saved_variable (int *p, int v);
+
+  saved_variable (size_t *p, size_t v);
+
+  saved_variable (std::string *p, const std::string& v);
+
+  saved_variable (void **p, void *v);
+
+  ~saved_variable (void);
+
+  void restore_value (void);
+
+  static void restore (void *s);
+
+private:
+
+  union
+    {
+      bool *ptr_to_bool;
+      int *ptr_to_int;
+      size_t *ptr_to_size_t;
+      void *gen_ptr;
+      void **ptr_to_gen_ptr;
+    };
+
+  union
+    {
+      bool bool_value;
+      int int_value;
+      size_t size_t_value;
+      std::string *str_value;
+      void *gen_ptr_value;
+    };
+
+  var_type type_tag;
+
+  size_t size;
+};
+
+saved_variable::saved_variable (void)
+{
+  gen_ptr = 0;
+  gen_ptr_value = 0;
+  type_tag = generic;
+  size = 0;
+}
+
+saved_variable::saved_variable (bool *p, bool v)
+{
+  type_tag = boolean;
+  ptr_to_bool = p;
+  bool_value = v;
+  size = sizeof (bool);  // Is this necessary?
+}
+
+saved_variable::saved_variable (int *p, int v)
+{
+  type_tag = integer;
+  ptr_to_int = p;
+  int_value = v;
+  size = sizeof (int);  // Is this necessary?
+}
+
+saved_variable::saved_variable (size_t *p, size_t v)
+{
+  type_tag = size_type;
+  ptr_to_size_t = p;
+  size_t_value = v;
+  size = sizeof (size_t);  // Is this necessary?
+}
+
+saved_variable::saved_variable (std::string *p, const std::string& v)
+{
+  type_tag = string_type;
+  gen_ptr = p;
+  str_value = new std::string (v);
+  size = sizeof (std::string);  // Is this necessary?
+}
+
+saved_variable::saved_variable (void **p, void *v)
+{
+  type_tag = generic_ptr;
+  ptr_to_gen_ptr = p;
+  gen_ptr_value = v;
+  size = sizeof (void *);
+}
+
+saved_variable::~saved_variable (void)
+{
+  switch (type_tag)
+    {
+    case string_type:
+      delete str_value;
+      break;
+
+    case generic:
+      // FIXME
+      // delete [] gen_ptr_value;
+      break;
+
+    default:
+      break;
+    }
+}
+
+void
+saved_variable::restore_value (void)
+{
+  switch (type_tag)
+    {
+    case boolean:
+      *ptr_to_bool = bool_value;
+      break;
+
+    case integer:
+      *ptr_to_int = int_value;
+      break;
+
+    case size_type:
+      *ptr_to_size_t = size_t_value;
+      break;
+
+    case string_type:
+      (static_cast<std::string *> (gen_ptr)) -> assign (*str_value);
+      break;
+
+    case generic_ptr:
+      *ptr_to_gen_ptr = gen_ptr_value;
+      break;
+
+    case generic:
+      memcpy (gen_ptr, gen_ptr_value, size);
+      break;
+
+    default:
+      panic_impossible ();
+      break;
+    }
+}
+
+void
+saved_variable::restore (void *s)
+{
+  saved_variable *sv = static_cast<saved_variable *> (s);
+  sv->restore_value ();
+  delete sv;
+}
+
+void
+unwind_protect::add (unwind_elem::cleanup_func fptr, void *ptr)
+{
+  unwind_elem el (fptr, ptr);
+  elt_list.push (el);
+}
+
+void
+unwind_protect::run (void)
+{
+  unwind_elem el = elt_list.top ();
+
+  elt_list.pop ();
+
+  unwind_elem::cleanup_func f = el.fptr ();
+
+  if (f)
+    f (el.ptr ());
+}
+
+void
+unwind_protect::discard (void)
+{
+  elt_list.pop ();
+}
+
+void
+unwind_protect::begin_frame (const std::string& tag)
+{
+  unwind_elem elem (tag);
+  elt_list.push (elem);
+}
+
+void
+unwind_protect::run_frame (const std::string& tag)
+{
+  while (! elt_list.empty ())
+    {
+      unwind_elem el = elt_list.top ();
+
+      elt_list.pop ();
+
+      unwind_elem::cleanup_func f = el.fptr ();
+
+      if (f)
+	f (el.ptr ());
+
+      if (tag == el.tag ())
+	break;
+    }
+}
+
+void
+unwind_protect::discard_frame (const std::string& tag)
+{
+  while (! elt_list.empty ())
+    {
+      unwind_elem el = elt_list.top ();
+
+      elt_list.pop ();
+
+      if (tag == el.tag ())
+	break;
+    }
+}
+
+void
+unwind_protect::run_all (void)
+{
+  while (! elt_list.empty ())
+    {
+      unwind_elem el = elt_list.top ();
+
+      elt_list.pop ();
+
+      unwind_elem::cleanup_func f = el.fptr ();
+
+      if (f)
+	f (el.ptr ());
+    }
+}
+
+void
+unwind_protect::discard_all (void)
+{
+  while (! elt_list.empty ())
+    elt_list.pop ();
+}
+
+void
+unwind_protect::save_bool (bool *ptr, bool value)
+{
+  saved_variable *s = new saved_variable (ptr, value);
+  add (saved_variable::restore, s);
+}
+
+void
+unwind_protect::save_int (int *ptr, int value)
+{
+  saved_variable *s = new saved_variable (ptr, value);
+  add (saved_variable::restore, s);
+}
+
+void
+unwind_protect::save_size_t (size_t *ptr, size_t value)
+{
+  saved_variable *s = new saved_variable (ptr, value);
+  add (saved_variable::restore, s);
+}
+
+void
+unwind_protect::save_str (std::string *ptr, const std::string& value)
+{
+  saved_variable *s = new saved_variable (ptr, value);
+  add (saved_variable::restore, s);
+}
+
+void
+unwind_protect::save_ptr (void **ptr, void *value)
+{
+  saved_variable *s = new saved_variable (ptr, value);
+  add (saved_variable::restore, s);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/unwind-prot.h b/src/unwind-prot.h
new file mode 100644
index 0000000..5c77298
--- /dev/null
+++ b/src/unwind-prot.h
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004,
+              2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_unwind_prot_h)
+#define octave_unwind_prot_h 1
+
+#include <cstddef>
+
+#include <string>
+#include <stack>
+
+class
+OCTINTERP_API
+unwind_elem
+{
+public:
+
+  typedef void (*cleanup_func) (void *ptr);
+
+  unwind_elem (void)
+    : ue_tag (), ue_fptr (0), ue_ptr (0) { }
+
+  unwind_elem (const std::string &t)
+    : ue_tag (t), ue_fptr (0), ue_ptr (0) { }
+
+  unwind_elem (cleanup_func f, void *p)
+    : ue_tag (), ue_fptr (f), ue_ptr (p) { }
+
+  unwind_elem (const unwind_elem& el)
+    : ue_tag (el.ue_tag), ue_fptr (el.ue_fptr), ue_ptr (el.ue_ptr) { }
+
+  ~unwind_elem (void) { }
+
+  unwind_elem& operator = (const unwind_elem& el)
+    {
+      ue_tag = el.ue_tag;
+      ue_fptr = el.ue_fptr;
+      ue_ptr = el.ue_ptr;
+
+      return *this;
+    }
+
+  std::string tag (void) { return ue_tag; }
+
+  cleanup_func fptr (void) { return ue_fptr; }
+
+  void *ptr (void) { return ue_ptr; }
+
+private:
+
+  std::string ue_tag;
+
+  cleanup_func ue_fptr;
+
+  void *ue_ptr;
+};
+
+class
+OCTINTERP_API
+unwind_protect
+{
+public:
+
+  static void add (unwind_elem::cleanup_func fptr, void *ptr = 0);
+
+  static void run (void);
+
+  static void discard (void);
+
+  static void begin_frame (const std::string& tag);
+
+  static void run_frame (const std::string& tag);
+
+  static void discard_frame (const std::string& tag);
+
+  static void run_all (void);
+
+  static void discard_all (void);
+
+  // Ways to save variables.
+
+  static void save_bool (bool *ptr, bool value);
+
+  static void save_int (int *ptr, int value);
+
+  static void save_size_t (size_t *ptr, size_t value);
+
+  static void save_str (std::string *ptr, const std::string& value);
+
+  static void save_ptr (void **ptr, void *value);
+
+  static void save_var (void *ptr, void *value, size_t size);
+
+  static std::stack<unwind_elem> elt_list;
+};
+
+// We could get by without these macros, but they are nice to have...
+
+#define unwind_protect_bool(b) \
+  unwind_protect::save_bool (&(b), (b))
+
+#define unwind_protect_int(i) \
+  unwind_protect::save_int (&(i), (i))
+
+#define unwind_protect_size_t(i) \
+  unwind_protect::save_size_t (&(i), (i))
+
+#define unwind_protect_str(s) \
+  unwind_protect::save_str (&(s), (s))
+
+#define unwind_protect_ptr(p) \
+  unwind_protect::save_ptr (reinterpret_cast<void **> (&(p)), \
+                            reinterpret_cast<void *> (p))
+
+#define unwind_protect_fptr(p) \
+  unwind_protect::save_ptr (reinterpret_cast<void **> (&(p)), \
+                            FCN_PTR_CAST (void *, p))
+
+#define unwind_protect_const_ptr(p) \
+  unwind_protect::save_ptr (const_cast<void **> (reinterpret_cast<const void **> (&(p))), \
+                            const_cast<void *> (reinterpret_cast<const void *> (p)))
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/utils.cc b/src/utils.cc
new file mode 100644
index 0000000..a0e43c4
--- /dev/null
+++ b/src/utils.cc
@@ -0,0 +1,1238 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+#include <climits>
+#include <cstring>
+
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "quit.h"
+
+#include "dir-ops.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "lo-mappers.h"
+#include "oct-cmplx.h"
+#include "oct-env.h"
+#include "pathsearch.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include <defaults.h>
+#include "defun.h"
+#include "dirfns.h"
+#include "error.h"
+#include "gripes.h"
+#include "input.h"
+#include "load-path.h"
+#include "oct-errno.h"
+#include "oct-hist.h"
+#include "oct-obj.h"
+#include "pager.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// Return TRUE if S is a valid identifier.
+
+bool
+valid_identifier (const char *s)
+{
+  if (! s || ! (isalpha (*s) || *s == '_' || *s == '$'))
+     return false;
+
+  while (*++s != '\0')
+    if (! (isalnum (*s) || *s == '_' || *s == '$'))
+      return false;
+
+  return true;
+}
+
+bool
+valid_identifier (const std::string& s)
+{
+  return valid_identifier (s.c_str ());
+}
+
+DEFUN (isvarname, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isvarname (@var{name})\n\
+Return true if @var{name} is a valid variable name\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("isvarname");
+
+  if (error_state)
+    return retval;
+
+  if (argc == 2)
+    retval = valid_identifier (argv[1]);
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Return TRUE if F and G are both names for the same file.
+
+bool
+same_file (const std::string& f, const std::string& g)
+{
+  return same_file_internal (f, g);
+}
+
+int
+almost_match (const std::string& std, const std::string& s, int min_match_len,
+	      int case_sens)
+{
+  int stdlen = std.length ();
+  int slen = s.length ();
+
+  return (slen <= stdlen
+	  && slen >= min_match_len
+	  && (case_sens
+	      ? (strncmp (std.c_str (), s.c_str (), slen) == 0)
+	      : (octave_strncasecmp (std.c_str (), s.c_str (), slen) == 0)));
+}
+
+// Ugh.
+
+int
+keyword_almost_match (const char * const *std, int *min_len, const std::string& s,
+		      int min_toks_to_match, int max_toks)
+{
+  int status = 0;
+  int tok_count = 0;
+  int toks_matched = 0;
+
+  if (s.empty () || max_toks < 1)
+    return status;
+
+  char *kw = strsave (s.c_str ());
+
+  char *t = kw;
+  while (*t != '\0')
+    {
+      if (*t == '\t')
+	*t = ' ';
+      t++;
+    }
+
+  char *beg = kw;
+  while (*beg == ' ')
+    beg++;
+
+  if (*beg == '\0')
+    return status;
+
+
+  const char **to_match = new const char * [max_toks + 1];
+  const char * const *s1 = std;
+  const char **s2 = to_match;
+
+  if (! s1 || ! s2)
+    goto done;
+
+  s2[tok_count] = beg;
+  char *end;
+  while ((end = strchr (beg, ' ')) != 0)
+    {
+      *end = '\0';
+      beg = end + 1;
+
+      while (*beg == ' ')
+	beg++;
+
+      if (*beg == '\0')
+	break;
+
+      tok_count++;
+      if (tok_count >= max_toks)
+	goto done;
+
+      s2[tok_count] = beg;
+    }
+  s2[tok_count+1] = 0;
+
+  s2 = to_match;
+
+  for (;;)
+    {
+      if (! almost_match (*s1, *s2, min_len[toks_matched], 0))
+	goto done;
+
+      toks_matched++;
+
+      s1++;
+      s2++;
+
+      if (! *s2)
+	{
+	  status = (toks_matched >= min_toks_to_match);
+	  goto done;
+	}
+
+      if (! *s1)
+	goto done;
+    }
+
+ done:
+
+  delete [] kw;
+  delete [] to_match;
+
+  return status;
+}
+
+// Return non-zero if either NR or NC is zero.  Return -1 if this
+// should be considered fatal; return 1 if this is ok.
+
+int
+empty_arg (const char * /* name */, octave_idx_type nr, octave_idx_type nc)
+{
+  return (nr == 0 || nc == 0);
+}
+
+// See if the given file is in the path.
+
+std::string
+search_path_for_file (const std::string& path, const string_vector& names)
+{
+  dir_path p (path);
+
+  return octave_env::make_absolute (p.find_first_of (names),
+				    octave_env::getcwd ());
+}
+
+// Find all locations of the given file in the path.
+
+string_vector
+search_path_for_all_files (const std::string& path, const string_vector& names)
+{
+  dir_path p (path);
+
+  string_vector sv = p.find_all_first_of (names);
+
+  octave_idx_type len = sv.length ();
+
+  for (octave_idx_type i = 0; i < len; i++)
+    sv[i] = octave_env::make_absolute (sv[i], octave_env::getcwd ());
+
+  return sv;
+}
+
+static string_vector
+make_absolute (const string_vector& sv)
+{
+  octave_idx_type len = sv.length ();
+
+  string_vector retval (len);
+
+  for (octave_idx_type i = 0; i < len; i++)
+    retval[i] = octave_env::make_absolute (sv[i], octave_env::getcwd ());
+ 
+  return retval;
+}
+
+DEFUN (file_in_loadpath, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} file_in_loadpath (@var{file})\n\
+ at deftypefnx {Built-in Function} {} file_in_loadpath (@var{file}, \"all\")\n\
+\n\
+Return the absolute name of @var{file} if it can be found in\n\
+the list of directories specified by @code{path}.\n\
+If no file is found, return an empty matrix.\n\
+\n\
+If the first argument is a cell array of strings, search each\n\
+directory of the loadpath for element of the cell array and return\n\
+the first that matches.\n\
+\n\
+If the second optional argument @code{\"all\"} is supplied, return\n\
+a cell array containing the list of all files that have the same\n\
+name in the path.  If no files are found, return an empty cell array.\n\
+ at seealso{file_in_path, path}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      string_vector names = args(0).all_strings ();
+
+      if (! error_state && names.length () > 0)
+	{
+	  if (nargin == 1)
+	    {
+	      std::string fname = octave_env::make_absolute
+		(load_path::find_first_of (names), octave_env::getcwd ());
+
+	      if (fname.empty ())
+		retval = Matrix ();
+	      else
+		retval = fname;
+	    }
+	  else if (nargin == 2)
+	    {
+	      std::string opt = args(1).string_value ();
+
+	      if (! error_state && opt == "all")
+		retval = Cell (make_absolute (load_path::find_all_first_of (names)));
+	      else
+		error ("file_in_loadpath: invalid option");
+	    }
+	}
+      else
+	error ("file_in_loadpath: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (file_in_path, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} file_in_path (@var{path}, @var{file})\n\
+ at deftypefnx {Built-in Function} {} file_in_path (@var{path}, @var{file}, \"all\")\n\
+Return the absolute name of @var{file} if it can be found in\n\
+ at var{path}.  The value of @var{path} should be a colon-separated list of\n\
+directories in the format described for @code{path}.  If no file\n\
+is found, return an empty matrix.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+file_in_path (EXEC_PATH, \"sh\")\n\
+     @result{} \"/bin/sh\"\n\
+ at end group\n\
+ at end example\n\
+\n\
+If the second argument is a cell array of strings, search each\n\
+directory of the path for element of the cell array and return\n\
+the first that matches.\n\
+\n\
+If the third optional argument @code{\"all\"} is supplied, return\n\
+a cell array containing the list of all files that have the same\n\
+name in the path.  If no files are found, return an empty cell array.\n\
+ at seealso{file_in_loadpath}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2 || nargin == 3)
+    {
+      std::string path = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  string_vector names = args(1).all_strings ();
+
+	  if (! error_state && names.length () > 0)
+	    {
+	      if (nargin == 2)
+		{
+		  std::string fname = search_path_for_file (path, names);
+
+		  if (fname.empty ())
+		    retval = Matrix ();
+		  else
+		    retval = fname;
+		}
+	      else if (nargin == 3)
+		{
+		  std::string opt = args(2).string_value ();
+
+		  if (! error_state && opt == "all")
+		    retval = Cell (make_absolute (search_path_for_all_files (path, names)));
+		  else
+		    error ("file_in_path: invalid option");
+		}
+	    }
+	  else
+	    error ("file_in_path: expecting string as second argument");
+	}
+      else
+	error ("file_in_path: expecting string as first argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+std::string
+file_in_path (const std::string& name, const std::string& suffix)
+{
+  std::string nm = name;
+
+  if (! suffix.empty ())
+    nm.append (suffix);
+
+  return octave_env::make_absolute
+    (load_path::find_file (nm), octave_env::getcwd ());
+}
+
+// See if there is an function file in the path.  If so, return the
+// full path to the file.
+
+std::string
+fcn_file_in_path (const std::string& name)
+{
+  std::string retval;
+
+  int len = name.length ();
+  
+  if (len > 0)
+    {
+      if (octave_env::absolute_pathname (name))
+	{
+	  file_stat fs (name);
+
+	  if (fs.exists ())
+	    retval = name;
+	}
+      else if (len > 2 && name [len - 2] == '.' && name [len - 1] == 'm')
+	retval = load_path::find_fcn_file (name.substr (0, len-2));
+      else
+	{
+	  std::string fname = name;
+	  size_t pos = name.find_first_of (Vfilemarker);
+	  if (pos != std::string::npos)
+	    fname = name.substr (0, pos);
+
+	  retval = load_path::find_fcn_file (fname);
+	}
+    }
+
+  return retval;
+}
+
+// See if there is a directory called "name" in the path and if it
+// contains a Contents.m file return the full path to this file.
+
+std::string
+contents_file_in_path (const std::string& dir)
+{
+  std::string retval;
+
+  if (dir.length () > 0)
+    {
+      std::string tcontents = file_ops::concat (load_path::find_dir (dir), 
+						std::string ("Contents.m"));
+
+      file_stat fs (tcontents);
+
+      if (fs.exists ())
+	retval = octave_env::make_absolute (tcontents, octave_env::getcwd ());
+    }
+
+  return retval;
+}
+
+// See if there is a .oct file in the path.  If so, return the
+// full path to the file.
+
+std::string
+oct_file_in_path (const std::string& name)
+{
+  std::string retval;
+
+  int len = name.length ();
+  
+  if (len > 0)
+    {
+      if (octave_env::absolute_pathname (name))
+	{
+	  file_stat fs (name);
+
+	  if (fs.exists ())
+	    retval = name;
+	}
+      else if (len > 4 && name [len - 4] == '.' && name [len - 3] == 'o'
+	       && name [len - 2] == 'c' && name [len - 1] == 't')
+	retval = load_path::find_oct_file (name.substr (0, len-4));
+      else
+	retval = load_path::find_oct_file (name);
+    }
+
+  return retval;
+}
+
+// See if there is a .mex file in the path.  If so, return the
+// full path to the file.
+
+std::string
+mex_file_in_path (const std::string& name)
+{
+  std::string retval;
+
+  int len = name.length ();
+  
+  if (len > 0)
+    {
+      if (octave_env::absolute_pathname (name))
+	{
+	  file_stat fs (name);
+
+	  if (fs.exists ())
+	    retval = name;
+	}
+      else if (len > 4 && name [len - 4] == '.' && name [len - 3] == 'm'
+	       && name [len - 2] == 'e' && name [len - 1] == 'x')
+	retval = load_path::find_mex_file (name.substr (0, len-4));
+      else
+	retval = load_path::find_mex_file (name);
+    }
+
+  return retval;
+}
+
+// Replace backslash escapes in a string with the real values.
+
+std::string
+do_string_escapes (const std::string& s)
+{
+  std::string retval;
+
+  size_t i = 0;
+  size_t j = 0;
+  size_t len = s.length ();
+
+  retval.resize (len);
+
+  while (j < len)
+    {
+      if (s[j] == '\\' && j+1 < len)
+	{
+	  switch (s[++j])
+	    {
+	    case '0':
+	      retval[i] = '\0';
+	      break;
+
+	    case 'a':
+	      retval[i] = '\a';
+	      break;
+
+	    case 'b': // backspace
+	      retval[i] = '\b';
+	      break;
+
+	    case 'f': // formfeed
+	      retval[i] = '\f';
+	      break;
+
+	    case 'n': // newline
+	      retval[i] = '\n';
+	      break;
+
+	    case 'r': // carriage return
+	      retval[i] = '\r';
+	      break;
+
+	    case 't': // horizontal tab
+	      retval[i] = '\t';
+	      break;
+
+	    case 'v': // vertical tab
+	      retval[i] = '\v';
+	      break;
+
+	    case '\\': // backslash
+	      retval[i] = '\\';
+	      break;
+
+	    case '\'': // quote
+	      retval[i] = '\'';
+	      break;
+
+	    case '"': // double quote
+	      retval[i] = '"';
+	      break;
+
+	    default:
+	      warning ("unrecognized escape sequence `\\%c' --\
+ converting to `%c'", s[j], s[j]);
+	      retval[i] = s[j];
+	      break;
+	    }
+	}
+      else
+	{
+	  retval[i] = s[j];
+	}
+
+      i++;
+      j++;
+    }
+
+  retval.resize (i);
+
+  return retval;
+}
+
+DEFUN (do_string_escapes, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} do_string_escapes (@var{string})\n\
+Convert special characters in @var{string} to their escaped forms.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	retval = do_string_escapes (args(0).string_value ());
+      else
+	error ("do_string_escapes: argument must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+const char *
+undo_string_escape (char c)
+{
+  if (! c)
+    return "";
+
+  switch (c)
+    {
+    case '\0':
+      return "\\0";
+
+    case '\a':
+      return "\\a";
+
+    case '\b': // backspace
+      return "\\b";
+
+    case '\f': // formfeed
+      return "\\f";
+
+    case '\n': // newline
+      return "\\n";
+
+    case '\r': // carriage return
+      return "\\r";
+
+    case '\t': // horizontal tab
+      return "\\t";
+
+    case '\v': // vertical tab
+      return "\\v";
+
+    case '\\': // backslash
+      return "\\\\";
+
+    case '"': // double quote
+      return "\\\"";
+
+    default:
+      {
+	static char retval[2];
+	retval[0] = c;
+	retval[1] = '\0';
+	return retval;
+      }
+    }
+}
+
+std::string
+undo_string_escapes (const std::string& s)
+{
+  std::string retval;
+
+  for (size_t i = 0; i < s.length (); i++)
+    retval.append (undo_string_escape (s[i]));
+
+  return retval;
+}
+
+DEFUN (undo_string_escapes, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} undo_string_escapes (@var{s})\n\
+Converts special characters in strings back to their escaped forms.  For\n\
+example, the expression\n\
+\n\
+ at example\n\
+bell = \"\\a\";\n\
+ at end example\n\
+\n\
+ at noindent\n\
+assigns the value of the alert character (control-g, ASCII code 7) to\n\
+the string variable @code{bell}.  If this string is printed, the\n\
+system will ring the terminal bell (if it is possible).  This is\n\
+normally the desired outcome.  However, sometimes it is useful to be\n\
+able to print the original representation of the string, with the\n\
+special characters replaced by their escape sequences.  For example,\n\
+\n\
+ at example\n\
+ at group\n\
+octave:13> undo_string_escapes (bell)\n\
+ans = \\a\n\
+ at end group\n\
+ at end example\n\
+\n\
+ at noindent\n\
+replaces the unprintable alert character with its printable\n\
+representation.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	retval = undo_string_escapes (args(0).string_value ());
+      else
+	error ("undo_string_escapes: argument must be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (is_absolute_filename, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} is_absolute_filename (@var{file})\n\
+Return true if @var{file} is an absolute filename.\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    retval = (args(0).is_string ()
+	      && octave_env::absolute_pathname (args(0).string_value ()));
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (is_rooted_relative_filename, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} is_rooted_relative_filename (@var{file})\n\
+Return true if @var{file} is a rooted-relative filename.\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  if (args.length () == 1)
+    retval = (args(0).is_string ()
+	      && octave_env::rooted_relative_pathname (args(0).string_value ()));
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (make_absolute_filename, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} make_absolute_filename (@var{file})\n\
+Return the full name of @var{file}, relative to the current directory.\n\
+ at end deftypefn")
+{
+  octave_value retval = std::string ();
+
+  if (args.length () == 1)
+    {
+      std::string nm = args(0).string_value ();
+
+      if (! error_state)
+	retval = octave_env::make_absolute (nm, octave_env::getcwd ());
+      else
+	error ("make_absolute_filename: expecting argument to be a file name");
+    }      
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (find_dir_in_path, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} find_dir_in_path (@var{dir})\n\
+Return the full name of the path element matching @var{dir}.  The\n\
+match is performed at the end of each path element.  For example, if\n\
+ at var{dir} is @code{\"foo/bar\"}, it matches the path element\n\
+ at code{\"/some/dir/foo/bar\"}, but not @code{\"/some/dir/foo/bar/baz\"}\n\
+or @code{\"/some/dir/allfoo/bar\"}.\n\
+ at end deftypefn")
+{
+  octave_value retval = std::string ();
+
+  if (args.length () == 1)
+    {
+      std::string dir = args(0).string_value ();
+
+      if (! error_state)
+	retval = load_path::find_dir (dir);
+      else
+	error ("find_dir_in_path: expecting argument to be a directory name");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUNX ("errno", Ferrno, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {@var{err} =} errno ()\n\
+ at deftypefnx {Built-in Function} {@var{err} =} errno (@var{val})\n\
+ at deftypefnx {Built-in Function} {@var{err} =} errno (@var{name})\n\
+Return the current value of the system-dependent variable errno,\n\
+set its value to @var{val} and return the previous value, or return\n\
+the named error code given @var{name} as a character string, or -1\n\
+if @var{name} is not found.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	{
+	  std::string nm = args(0).string_value ();
+
+	  if (! error_state)
+	    retval = octave_errno::lookup (nm);
+	  else
+	    error ("errno: expecting character string argument");
+	}
+      else
+	{
+	  int val = args(0).int_value ();
+
+	  if (! error_state)
+	    retval = octave_errno::set (val);
+	  else
+	    error ("errno: expecting integer argument");
+	}
+    }
+  else if (nargin == 0)
+    retval = octave_errno::get ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (errno_list, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} errno_list ()\n\
+Return a structure containing the system-dependent errno values.\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = octave_errno::list ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+static void
+check_dimensions (octave_idx_type& nr, octave_idx_type& nc, const char *warnfor)
+{
+  if (nr < 0 || nc < 0)
+    {
+      warning_with_id ("Octave:neg-dim-as-zero",
+		       "%s: converting negative dimension to zero", warnfor);
+
+      nr = (nr < 0) ? 0 : nr;
+      nc = (nc < 0) ? 0 : nc;
+    }
+}
+
+void
+check_dimensions (dim_vector& dim, const char *warnfor)
+{
+  bool neg = false;
+
+  for (int i = 0; i < dim.length (); i++)
+    {
+      if (dim(i) < 0)
+        {
+          dim(i) = 0;
+          neg = true;
+        }
+    }
+
+  if (neg)
+    warning_with_id ("Octave:neg-dim-as-zero",
+		     "%s: converting negative dimension to zero", warnfor);
+}
+
+
+void
+get_dimensions (const octave_value& a, const char *warn_for,
+                dim_vector& dim)
+{
+  if (a.is_scalar_type ())
+    {
+      dim.resize (2);
+      dim(0) = a.int_value ();
+      dim(1) = dim(0);
+    }
+  else
+    {
+      octave_idx_type nr = a.rows ();
+      octave_idx_type nc = a.columns ();
+
+      if (nr == 1 || nc == 1)
+        {
+          Array<double> v = a.vector_value ();
+
+          if (error_state)
+            return;
+
+          octave_idx_type n = v.length ();
+          dim.resize (n);
+          for (octave_idx_type i = 0; i < n; i++)
+            dim(i) = static_cast<int> (fix (v(i)));
+        }
+      else
+        error ("%s (A): use %s (size (A)) instead", warn_for, warn_for);
+    }
+
+  if (! error_state)
+    check_dimensions (dim, warn_for); // May set error_state.
+}
+
+
+void
+get_dimensions (const octave_value& a, const char *warn_for,
+		octave_idx_type& nr, octave_idx_type& nc)
+{
+  if (a.is_scalar_type ())
+    {
+      nr = nc = a.int_value ();
+    }
+  else
+    {
+      nr = a.rows ();
+      nc = a.columns ();
+
+      if ((nr == 1 && nc == 2) || (nr == 2 && nc == 1))
+	{
+	  Array<double> v = a.vector_value ();
+
+	  if (error_state)
+	    return;
+
+	  nr = static_cast<octave_idx_type> (fix (v (0)));
+	  nc = static_cast<octave_idx_type> (fix (v (1)));
+	}
+      else
+	error ("%s (A): use %s (size (A)) instead", warn_for, warn_for);
+    }
+
+  if (! error_state)
+    check_dimensions (nr, nc, warn_for); // May set error_state.
+}
+
+void
+get_dimensions (const octave_value& a, const octave_value& b,
+		const char *warn_for, octave_idx_type& nr, octave_idx_type& nc)
+{
+  nr = a.is_empty () ? 0 : a.int_value ();
+  nc = b.is_empty () ? 0 : b.int_value ();
+
+  if (error_state)
+    error ("%s: expecting two scalar arguments", warn_for);
+  else
+    check_dimensions (nr, nc, warn_for); // May set error_state.
+}
+
+Matrix
+identity_matrix (octave_idx_type nr, octave_idx_type nc)
+{
+  Matrix m (nr, nc, 0.0);
+
+  if (nr > 0 && nc > 0)
+    {
+      octave_idx_type n = std::min (nr, nc);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	m (i, i) = 1.0;
+    }
+
+  return m;
+}
+
+FloatMatrix
+float_identity_matrix (octave_idx_type nr, octave_idx_type nc)
+{
+  FloatMatrix m (nr, nc, 0.0);
+
+  if (nr > 0 && nc > 0)
+    {
+      octave_idx_type n = std::min (nr, nc);
+
+      for (octave_idx_type i = 0; i < n; i++)
+	m (i, i) = 1.0;
+    }
+
+  return m;
+}
+
+int
+octave_format (std::ostream& os, const char *fmt, ...)
+{
+  int retval = -1;
+
+  va_list args;
+  va_start (args, fmt);
+
+  retval = octave_vformat (os, fmt, args);
+
+  va_end (args);
+
+  return retval;
+}
+
+int
+octave_vformat (std::ostream& os, const char *fmt, va_list args)
+{
+  int retval = -1;
+
+#if defined (__GNUG__) && !CXX_ISO_COMPLIANT_LIBRARY
+
+  std::streambuf *sb = os.rdbuf ();
+
+  if (sb)
+    {
+      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+      retval = sb->vform (fmt, args);
+
+      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+    }
+
+#else
+
+  char *s = octave_vsnprintf (fmt, args);
+
+  if (s)
+    {
+      os << s;
+
+      retval = strlen (s);
+    }
+
+#endif
+
+  return retval;
+}
+
+// We manage storage.  User should not free it, and its contents are
+// only valid until next call to vsnprintf.
+
+// Interrupts might happen if someone makes a call with something that
+// will require a very large buffer.  If we are interrupted in that
+// case, we should make the buffer size smaller for the next call.
+
+#define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF \
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; \
+  delete [] buf; \
+  buf = 0; \
+  size = initial_size; \
+  octave_rethrow_exception (); \
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2
+
+#if defined __GNUC__ && defined __va_copy
+#define SAVE_ARGS(saved_args, args) __va_copy (saved_args, args)
+#elif defined va_copy
+#define SAVE_ARGS(saved_args, args) va_copy (saved_args, args)
+#else
+#define SAVE_ARGS(saved_args, args) saved_args = args
+#endif
+
+char *
+octave_vsnprintf (const char *fmt, va_list args)
+{
+  static const size_t initial_size = 100;
+
+  static size_t size = initial_size;
+
+  static char *buf = 0;
+
+#if defined (HAVE_C99_VSNPRINTF)
+  size_t nchars = 0;
+#else
+  int nchars = 0;
+#endif
+
+  if (! buf)
+    buf = new char [size];
+
+  if (! buf)
+    return 0;
+
+#if defined (HAVE_C99_VSNPRINTF)
+
+  // Note that the caller is responsible for calling va_end on args.
+  // We will do it for saved_args.
+
+  va_list saved_args;
+
+  SAVE_ARGS (saved_args, args);
+
+  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF;
+
+  nchars = octave_raw_vsnprintf (buf, size, fmt, args);
+
+  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+  if (nchars >= size)
+    {
+      size = nchars + 1;
+
+      delete [] buf;
+
+      buf = new char [size];
+
+      if (buf)
+	{
+	  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF;
+
+	  octave_raw_vsnprintf (buf, size, fmt, saved_args);
+
+	  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+	}
+    }
+
+  va_end (saved_args);
+
+#else
+
+  while (1)
+    {
+      va_list saved_args;
+
+      SAVE_ARGS (saved_args, args);
+
+      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF;
+
+      nchars = octave_raw_vsnprintf (buf, size, fmt, saved_args);
+
+      va_end (saved_args);
+
+      END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+      if (nchars > -1 && nchars < size-1)
+       return buf;
+      else
+       {
+	 delete [] buf;
+
+         size *= 2;
+
+	 buf = new char [size];
+
+         if (! buf)
+           return 0;
+       }
+    }
+
+#endif
+
+  return buf;
+}
+
+char *
+octave_snprintf (const char *fmt, ...)
+{
+  char *retval = 0;
+
+  va_list args;
+  va_start (args, fmt);
+
+  retval = octave_vsnprintf (fmt, args);
+
+  va_end (args);
+
+  return retval;
+}
+
+void
+octave_sleep (double seconds)
+{
+  if (seconds > 0)
+    {
+      double t;
+
+      unsigned int usec
+	= static_cast<unsigned int> (modf (seconds, &t) * 1000000);
+
+      unsigned int sec
+	= (t > UINT_MAX) ? UINT_MAX : static_cast<unsigned int> (t);
+
+      // Versions of these functions that accept unsigned int args are
+      // defined in cutils.c.
+      octave_sleep (sec);
+      octave_usleep (usec);
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..6b570fc
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,126 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_utils_h)
+#define octave_utils_h 1
+
+#include <cstdarg>
+
+#include <iosfwd>
+#include <string>
+
+#include "dMatrix.h"
+#include "lo-utils.h"
+
+class octave_value;
+class octave_value_list;
+class string_vector;
+
+extern OCTINTERP_API bool valid_identifier (const char *s);
+extern OCTINTERP_API bool valid_identifier (const std::string& s);
+
+extern OCTINTERP_API bool
+same_file (const std::string& f, const std::string& g);
+
+extern OCTINTERP_API int almost_match (const std::string& std,
+				       const std::string& s,
+				       int min_match_len = 1,
+				       int case_sens = 1);
+
+extern OCTINTERP_API int
+keyword_almost_match (const char * const *std, int *min_len,
+		      const std::string& s, int min_toks_to_match,
+		      int max_toks);
+
+extern OCTINTERP_API int empty_arg (const char *name, octave_idx_type nr,
+				    octave_idx_type nc);
+
+extern OCTINTERP_API std::string
+search_path_for_file (const std::string&, const string_vector&);
+
+extern OCTINTERP_API string_vector
+search_path_for_all_files (const std::string&, const string_vector&);
+
+extern OCTINTERP_API std::string
+file_in_path (const std::string&, const std::string&);
+
+extern OCTINTERP_API std::string contents_file_in_path (const std::string&);
+
+extern OCTINTERP_API std::string fcn_file_in_path (const std::string&);
+extern OCTINTERP_API std::string oct_file_in_path (const std::string&);
+extern OCTINTERP_API std::string mex_file_in_path (const std::string&);
+
+extern OCTINTERP_API std::string do_string_escapes (const std::string& s);
+
+extern OCTINTERP_API const char *undo_string_escape (char c);
+
+extern OCTINTERP_API std::string undo_string_escapes (const std::string& s);
+
+extern OCTINTERP_API void
+check_dimensions (dim_vector& dim, const char *warnfor);
+
+extern OCTINTERP_API void
+get_dimensions (const octave_value& a, const char *warn_for,
+                dim_vector& dim);
+
+extern OCTINTERP_API void
+get_dimensions (const octave_value& a, const octave_value& b,
+		const char *warn_for, octave_idx_type& nr,
+		octave_idx_type& nc);
+
+extern OCTINTERP_API void
+get_dimensions (const octave_value& a,const char *warn_for,
+		octave_idx_type& nr, octave_idx_type& nc);
+
+extern OCTINTERP_API Matrix
+identity_matrix (octave_idx_type nr, octave_idx_type nc);
+
+extern OCTINTERP_API FloatMatrix
+float_identity_matrix (octave_idx_type nr, octave_idx_type nc);
+
+extern OCTINTERP_API int
+octave_format (std::ostream& os, const char *fmt, ...);
+
+extern OCTINTERP_API int
+octave_vformat (std::ostream& os, const char *fmt, va_list args);
+
+extern OCTINTERP_API char *octave_vsnprintf (const char *fmt, va_list args);
+
+extern OCTINTERP_API char *octave_snprintf (const char *fmt, ...);
+
+extern OCTINTERP_API void octave_sleep (double seconds);
+
+extern "C" OCTINTERP_API void octave_sleep (unsigned int seconds);
+
+extern "C" OCTINTERP_API void octave_usleep (unsigned int useconds);
+
+extern "C" OCTINTERP_API int
+octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, va_list args);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/variables.cc b/src/variables.cc
new file mode 100644
index 0000000..66adc53
--- /dev/null
+++ b/src/variables.cc
@@ -0,0 +1,2333 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdio>
+#include <cstring>
+
+#include <iomanip>
+#include <set>
+#include <string>
+
+#include "file-stat.h"
+#include "oct-env.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "regex-match.h"
+#include "str-vec.h"
+
+#include <defaults.h>
+#include "Cell.h"
+#include "defun.h"
+#include "dirfns.h"
+#include "error.h"
+#include "gripes.h"
+#include "help.h"
+#include "input.h"
+#include "lex.h"
+#include "load-path.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-class.h"
+#include "ov-usr-fcn.h"
+#include "pager.h"
+#include "parse.h"
+#include "symtab.h"
+#include "toplev.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+
+// Defines layout for the whos/who -long command
+static std::string Vwhos_line_format
+  = "  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\n";
+
+void
+clear_mex_functions (void)
+{
+  symbol_table::clear_mex_functions ();
+}
+
+void
+clear_function (const std::string& nm)
+{
+  symbol_table::clear_function (nm);
+}
+
+void
+clear_variable (const std::string& nm)
+{
+  symbol_table::clear_variable (nm);
+}
+
+void
+clear_symbol (const std::string& nm)
+{
+  symbol_table::clear_symbol (nm);
+}
+
+// Attributes of variables and functions.
+
+// Is this octave_value a valid function?
+
+octave_function *
+is_valid_function (const std::string& fcn_name,
+		   const std::string& warn_for, bool warn)
+{
+  octave_function *ans = 0;
+
+  if (! fcn_name.empty ())
+    {
+      octave_value val = symbol_table::find_function (fcn_name);
+
+      if (val.is_defined ())
+	ans = val.function_value (true);
+    }
+
+  if (! ans && warn)
+    error ("%s: the symbol `%s' is not valid as a function",
+	   warn_for.c_str (), fcn_name.c_str ());
+
+  return ans;
+}
+
+octave_function *
+is_valid_function (const octave_value& arg,
+		   const std::string& warn_for, bool warn)
+{
+  octave_function *ans = 0;
+
+  std::string fcn_name;
+
+  if (arg.is_string ())
+    {
+      fcn_name = arg.string_value ();
+
+      if (! error_state)
+	ans = is_valid_function (fcn_name, warn_for, warn);
+      else if (warn)
+	error ("%s: expecting function name as argument", warn_for.c_str ());
+    }
+  else if (warn)
+    error ("%s: expecting function name as argument", warn_for.c_str ());
+
+  return ans;
+}
+
+octave_function *
+extract_function (const octave_value& arg, const std::string& warn_for,
+		  const std::string& fname, const std::string& header,
+		  const std::string& trailer)
+{
+  octave_function *retval = 0;
+
+  retval = is_valid_function (arg, warn_for, 0);
+
+  if (! retval)
+    {
+      std::string s = arg.string_value ();
+
+      std::string cmd = header;
+      cmd.append (s);
+      cmd.append (trailer);
+
+      if (! error_state)
+	{
+	  int parse_status;
+
+	  eval_string (cmd, true, parse_status, 0);
+
+	  if (parse_status == 0)
+	    {
+	      retval = is_valid_function (fname, warn_for, 0);
+      
+	      if (! retval)
+		{
+		  error ("%s: `%s' is not valid as a function",
+			 warn_for.c_str (), fname.c_str ());
+		  return retval;
+		}
+
+              warning ("%s: passing function body as a string is obsolete."
+                       " Please use anonymous functions.", warn_for.c_str ());
+	    }
+	  else
+	    error ("%s: `%s' is not valid as a function",
+		   warn_for.c_str (), fname.c_str ());
+	}
+      else
+	error ("%s: expecting first argument to be a string",
+	       warn_for.c_str ());
+    }
+
+  return retval;
+}
+
+string_vector
+get_struct_elts (const std::string& text)
+{
+  int n = 1;
+
+  size_t pos = 0;
+
+  size_t len = text.length ();
+
+  while ((pos = text.find ('.', pos)) != std::string::npos)
+    {
+      if (++pos == len)
+	break;
+
+      n++;
+    }
+
+  string_vector retval (n);
+
+  pos = 0;
+
+  for (int i = 0; i < n; i++)
+    {
+      len = text.find ('.', pos);
+
+      if (len != std::string::npos)
+	len -= pos;
+
+      retval[i] = text.substr (pos, len);
+
+      if (len != std::string::npos)
+	pos += len + 1;
+    }
+
+  return retval;
+}
+
+static inline bool
+is_variable (const std::string& name)
+{
+  bool retval = false;
+
+  if (! name.empty ())
+    {
+      octave_value val = symbol_table::varval (name);
+
+      retval = val.is_defined ();
+    }
+
+  return retval;
+}
+
+string_vector
+generate_struct_completions (const std::string& text,
+			     std::string& prefix, std::string& hint)
+{
+  string_vector names;
+
+  size_t pos = text.rfind ('.');
+
+  if (pos != std::string::npos)
+    {
+      if (pos == text.length ())
+	hint = "";
+      else
+	hint = text.substr (pos+1);
+
+      prefix = text.substr (0, pos);
+
+      std::string base_name = prefix;
+
+      pos = base_name.find_first_of ("{(.");
+
+      if (pos != std::string::npos)
+	base_name = base_name.substr (0, pos);
+
+      if (is_variable (base_name))
+	{
+	  int parse_status;
+
+	  unwind_protect::begin_frame ("generate_struct_completions");
+
+	  unwind_protect_int (error_state);
+	  unwind_protect_int (warning_state);
+
+	  unwind_protect_bool (discard_error_messages);
+	  unwind_protect_bool (discard_warning_messages);
+
+	  discard_error_messages = true;
+	  discard_warning_messages = true;
+
+	  octave_value tmp = eval_string (prefix, true, parse_status);
+
+	  unwind_protect::run_frame ("generate_struct_completions");
+
+	  if (tmp.is_defined () && tmp.is_map ())
+	    names = tmp.map_keys ();
+	}
+    }
+
+  return names;
+}
+
+// FIXME -- this will have to be much smarter to work
+// "correctly".
+
+bool
+looks_like_struct (const std::string& text)
+{
+  bool retval = (! text.empty ()
+		 && text != "."
+		 && text.find_first_of (file_ops::dir_sep_chars ()) == std::string::npos
+		 && text.find ("..") == std::string::npos
+		 && text.rfind ('.') != std::string::npos);
+
+#if 0
+  symbol_record *sr = curr_sym_tab->lookup (text);
+
+  if (sr && ! sr->is_function ())
+    {
+      int parse_status;
+
+      unwind_protect::begin_frame ("looks_like_struct");
+
+      unwind_protect_bool (discard_error_messages);
+      unwind_protect_int (error_state);
+
+      discard_error_messages = true;
+
+      octave_value tmp = eval_string (text, true, parse_status);
+
+      unwind_protect::run_frame ("looks_like_struct");
+
+      retval = (tmp.is_defined () && tmp.is_map ());
+    }
+#endif
+
+  return retval;
+}
+
+static octave_value
+do_isglobal (const octave_value_list& args)
+{
+  octave_value retval = false;
+
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string name = args(0).string_value ();
+
+  if (error_state)
+    {
+      error ("isglobal: expecting std::string argument");
+      return retval;
+    }
+
+  return symbol_table::is_global (name);
+}
+
+DEFUN (isglobal, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isglobal (@var{name})\n\
+Return 1 if @var{name} is globally visible.  Otherwise, return 0.  For\n\
+example,\n\
+\n\
+ at example\n\
+ at group\n\
+global x\n\
+isglobal (\"x\")\n\
+     @result{} 1\n\
+ at end group\n\
+ at end example\n\
+ at end deftypefn")
+{
+  return do_isglobal (args);
+}
+
+DEFUN (is_global, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} isglobal (@var{name})\n\
+This function has been deprecated.  Use isglobal instead.\n\
+ at end deftypefn")
+{
+  return do_isglobal (args);
+}
+
+int
+symbol_exist (const std::string& name, const std::string& type)
+{
+  int retval = 0;
+
+  std::string struct_elts;
+  std::string symbol_name = name;
+
+  size_t pos = name.find ('.');
+
+  if (pos != std::string::npos && pos > 0)
+    {
+      struct_elts = name.substr (pos+1);
+      symbol_name = name.substr (0, pos);
+    }
+
+  // We shouldn't need to look in the global symbol table, since any
+  // name that is visible in the current scope will be in the local
+  // symbol table.
+
+  octave_value_list evaluated_args;
+  bool args_evaluated = false;
+
+  octave_value val = symbol_table::find (symbol_name, 0, string_vector (),
+					 evaluated_args, args_evaluated);
+
+  if (val.is_defined ())
+    {
+      bool not_a_struct = struct_elts.empty ();
+      bool var_ok = not_a_struct /* || val.is_map_element (struct_elts) */;
+
+      if (! retval
+	  && var_ok
+	  && (type == "any" || type == "var")
+	  && (val.is_constant () || val.is_object ()
+	      || val.is_inline_function () || val.is_function_handle ()))
+	{
+	  retval = 1;
+	}
+
+      if (! retval
+	  && (type == "any" || type == "builtin"))
+	{
+	  if (not_a_struct && val.is_builtin_function ())
+	    {
+	      retval = 5;
+	    }
+	}
+
+      if (! retval
+	  && not_a_struct
+	  && (type == "any" || type == "file")
+	  && (val.is_user_function () || val.is_dld_function ()))
+	{
+	  octave_function *f = val.function_value (true);
+	  std::string s = f ? f->fcn_file_name () : std::string ();
+
+	  retval = s.empty () ? 103 : (val.is_user_function () ? 2 : 3);
+	}
+    }
+
+  if (! (type == "var" || type == "builtin"))
+    {
+      if (! retval)
+	{
+	  std::string file_name = lookup_autoload (name);
+
+	  if (file_name.empty ())
+	    file_name = load_path::find_fcn (name);
+
+	  size_t len = file_name.length ();
+
+	  if (len > 0)
+	    {
+	      if (type == "any" || type == "file")
+		{
+		  if (len > 4 && (file_name.substr (len-4) == ".oct"
+				  || file_name.substr (len-4) == ".mex"))
+		    retval = 3;
+		  else
+		    retval = 2;
+		}
+	    }
+	}
+
+      if (! retval)
+	{
+	  std::string file_name = file_in_path (name, "");
+
+	  if (file_name.empty ())
+	    file_name = name;
+
+	  file_stat fs (file_name);
+
+	  if (fs)
+	    {
+	      if ((type == "any" || type == "file")
+		  && fs.is_reg ())
+		{
+		  retval = 2;
+		}
+	      else if ((type == "any" || type == "dir")
+		       && fs.is_dir ())
+		{
+		  retval = 7;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+#define GET_IDX(LEN) \
+  static_cast<int> ((LEN-1) * static_cast<double> (rand ()) / RAND_MAX)
+
+std::string
+unique_symbol_name (const std::string& basename)
+{
+  static const std::string alpha
+    = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+  static size_t len = alpha.length ();
+
+  std::string nm = basename + alpha[GET_IDX (len)];
+
+  size_t pos = nm.length ();
+
+  if (nm.substr (0, 2) == "__")
+    nm.append ("__");
+
+  while (symbol_exist (nm, "any"))
+    nm.insert (pos++, 1, alpha[GET_IDX (len)]);
+
+  return nm;
+}
+
+DEFUN (exist, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} exist (@var{name}, @var{type})\n\
+Return 1 if the name exists as a variable, 2 if the name is an\n\
+absolute file name, an ordinary file in Octave's @code{path}, or (after\n\
+appending @samp{.m}) a function file in Octave's @code{path}, 3 if the\n\
+name is a @samp{.oct} or @samp{.mex} file in Octave's @code{path},\n\
+5 if the name is a built-in function, 7 if the name is a directory, or 103\n\
+if the name is a function not associated with a file (entered on\n\
+the command line).\n\
+\n\
+Otherwise, return 0.\n\
+\n\
+This function also returns 2 if a regular file called @var{name}\n\
+exists in Octave's search path.  If you want information about\n\
+other types of files, you should use some combination of the functions\n\
+ at code{file_in_path} and @code{stat} instead.\n\
+\n\
+If the optional argument @var{type} is supplied, check only for\n\
+symbols of the specified type.  Valid types are\n\
+\n\
+ at table @samp\n\
+ at item \"var\"\n\
+Check only for variables.\n\
+ at item \"builtin\"\n\
+Check only for built-in functions.\n\
+ at item \"file\"\n\
+Check only for files.\n\
+ at item \"dir\"\n\
+Check only for directories.\n\
+ at end table\n\
+ at end deftypefn")
+{
+  octave_value retval = false;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string type
+	    = (nargin == 2) ? args(1).string_value () : std::string ("any");
+
+	  if (! error_state)
+	    retval = symbol_exist (name, type);
+	  else
+	    error ("exist: expecting second argument to be a string");
+	}
+      else
+	error ("exist: expecting first argument to be a string");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+octave_value
+lookup_function_handle (const std::string& nm)
+{
+  octave_value val = symbol_table::varval (nm);
+
+  return val.is_function_handle () ? val : octave_value ();
+}
+
+octave_value
+get_global_value (const std::string& nm, bool silent)
+{
+  octave_value val = symbol_table::global_varval (nm);
+
+  if (val.is_undefined () && ! silent)
+    error ("get_global_by_name: undefined symbol `%s'", nm.c_str ());
+
+  return val;
+}
+
+void
+set_global_value (const std::string& nm, const octave_value& val)
+{
+  symbol_table::global_varref (nm) = val;
+}
+
+// Variable values.
+
+octave_value
+set_internal_variable (bool& var, const octave_value_list& args,
+		       int nargout, const char *nm)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 0 || nargin == 0)
+    retval = var;
+
+  if (nargin == 1)
+    {
+      bool bval = args(0).bool_value ();
+
+      if (! error_state)
+	var = bval;
+      else
+	error ("%s: expecting arg to be a logical value", nm);
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+octave_value
+set_internal_variable (char& var, const octave_value_list& args,
+		       int nargout, const char *nm)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 0 || nargin == 0)
+    retval = var;
+
+  if (nargin == 1)
+    {
+      std::string sval = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  switch (sval.length ())
+	    {
+	    case 1:
+	      var = sval[0];
+	      break;
+
+	    case 0:
+	      var = '\0';
+	      break;
+
+	    default:
+	      error ("%s: argument must be a single character", nm);
+	      break;
+	    }
+	}
+      else
+	error ("%s: argument must be a single character", nm);
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+octave_value
+set_internal_variable (int& var, const octave_value_list& args,
+		       int nargout, const char *nm,
+		       int minval, int maxval)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 0 || nargin == 0)
+    retval = var;
+
+  if (nargin == 1)
+    {
+      int ival = args(0).int_value ();
+
+      if (! error_state)
+	{
+	  if (ival < minval)
+	    error ("%s: expecting arg to be greater than %d", nm, minval);
+	  else if (ival > maxval)
+	    error ("%s: expecting arg to be less than or equal to %d",
+		   nm, maxval);
+	  else
+	    var = ival;
+	}
+      else
+	error ("%s: expecting arg to be an integer value", nm);
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+octave_value
+set_internal_variable (double& var, const octave_value_list& args,
+		       int nargout, const char *nm,
+		       double minval, double maxval)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 0 || nargin == 0)
+    retval = var;
+
+  if (nargin == 1)
+    {
+      double dval = args(0).scalar_value ();
+
+      if (! error_state)
+	{
+	  if (dval < minval)
+	    error ("%s: expecting arg to be greater than %g", minval);
+	  else if (dval > maxval)
+	    error ("%s: expecting arg to be less than or equal to %g", maxval);
+	  else
+	    var = dval;
+	}
+      else
+	error ("%s: expecting arg to be a scalar value", nm);
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+octave_value
+set_internal_variable (std::string& var, const octave_value_list& args,
+		       int nargout, const char *nm, bool empty_ok)
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 0 || nargin == 0)
+    retval = var;
+
+  if (nargin == 1)
+    {
+      std::string sval = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  if (empty_ok || ! sval.empty ())
+	    var = sval;
+	  else
+	    error ("%s: value must not be empty", nm);
+	}
+      else
+	error ("%s: expecting arg to be a character string", nm);
+    }
+  else if (nargin > 1)
+    print_usage ();
+
+  return retval;
+}
+
+struct
+whos_parameter
+{
+  char command;
+  char modifier;
+  int parameter_length;
+  int first_parameter_length;
+  int balance;
+  std::string text;
+  std::string line;
+};
+
+static void
+print_descriptor (std::ostream& os, std::list<whos_parameter> params)
+{
+  // This method prints a line of information on a given symbol
+  std::list<whos_parameter>::iterator i = params.begin ();
+  std::ostringstream param_buf;
+
+  while (i != params.end ())
+    {
+      whos_parameter param = *i;
+
+      if (param.command != '\0')
+        {
+	  // Do the actual printing
+	  switch (param.modifier)
+	    {
+	    case 'l':
+	      os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
+	      param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
+	      break;
+
+	    case 'r':
+	      os << std::setiosflags (std::ios::right) << std::setw (param.parameter_length);
+	      param_buf << std::setiosflags (std::ios::right) << std::setw (param.parameter_length);
+	      break;
+
+	    case 'c':
+	      if (param.command != 's')
+	        {
+		  os << std::setiosflags (std::ios::left)
+		     << std::setw (param.parameter_length);
+		  param_buf << std::setiosflags (std::ios::left)
+			    << std::setw (param.parameter_length);
+		}
+	      break;
+
+	    default:
+	      os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
+	      param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
+	    }
+
+	  if (param.command == 's' && param.modifier == 'c')
+	    {
+	      int a, b;
+	     
+	      if (param.modifier == 'c')
+	        {
+		  a = param.first_parameter_length - param.balance;
+		  a = (a < 0 ? 0 : a);
+		  b = param.parameter_length - a - param.text . length ();
+		  b = (b < 0 ? 0 : b);
+		  os << std::setiosflags (std::ios::left) << std::setw (a)
+		     << "" << std::resetiosflags (std::ios::left) << param.text
+		     << std::setiosflags (std::ios::left)
+		     << std::setw (b) << ""
+		     << std::resetiosflags (std::ios::left);
+		  param_buf << std::setiosflags (std::ios::left) << std::setw (a)
+		     << "" << std::resetiosflags (std::ios::left) << param.line
+		     << std::setiosflags (std::ios::left)
+		     << std::setw (b) << ""
+		     << std::resetiosflags (std::ios::left);
+		}
+	    }
+	  else
+	    {
+	      os << param.text;
+	      param_buf << param.line;
+	    }
+	  os << std::resetiosflags (std::ios::left)
+	     << std::resetiosflags (std::ios::right);
+	  param_buf << std::resetiosflags (std::ios::left)
+		    << std::resetiosflags (std::ios::right);
+	  i++;
+	}
+      else
+	{
+	  os << param.text;
+	  param_buf << param.line;
+	  i++;
+	}
+    }
+
+  os << param_buf.str ();
+}
+
+class
+symbol_info_list
+{
+private:
+  struct symbol_info
+  {
+    symbol_info (const symbol_table::symbol_record& sr,
+		 const std::string& expr_str = std::string (),
+		 const octave_value& expr_val = octave_value ())
+      : name (expr_str.empty () ? sr.name () : expr_str),
+	is_automatic (sr.is_automatic ()),
+	is_formal (sr.is_formal ()),
+	is_global (sr.is_global ()),
+	is_persistent (sr.is_persistent ()),
+	varval (expr_val.is_undefined () ? sr.varval () : expr_val)
+    { }
+
+    void display_line (std::ostream& os,
+		       const std::list<whos_parameter>& params) const
+    {
+      dim_vector dims = varval.dims ();
+      std::string dims_str = dims.str ();
+
+      std::list<whos_parameter>::const_iterator i = params.begin ();
+
+      while (i != params.end ())
+	{
+	  whos_parameter param = *i;
+
+	  if (param.command != '\0')
+	    {
+	      // Do the actual printing.
+
+	      switch (param.modifier)
+		{
+		case 'l':
+		  os << std::setiosflags (std::ios::left)
+		     << std::setw (param.parameter_length);
+		  break;
+
+		case 'r':
+		  os << std::setiosflags (std::ios::right)
+		     << std::setw (param.parameter_length);
+		  break;
+
+		case 'c':
+		  if (param.command == 's')
+		    {
+		      int front = param.first_parameter_length
+			- dims_str.find ('x');
+		      int back = param.parameter_length
+			- dims_str.length ()
+			- front;
+		      front = (front > 0) ? front : 0;
+		      back = (back > 0) ? back : 0;
+
+		      os << std::setiosflags (std::ios::left)
+			 << std::setw (front)
+			 << ""
+			 << std::resetiosflags (std::ios::left)
+			 << dims_str
+			 << std::setiosflags (std::ios::left)
+			 << std::setw (back)
+			 << ""
+			 << std::resetiosflags (std::ios::left);
+		    }
+		  else
+		    {
+		      os << std::setiosflags (std::ios::left)
+			 << std::setw (param.parameter_length);
+		    }
+		  break;
+
+		default:
+		  error ("whos_line_format: modifier `%c' unknown",
+			 param.modifier);
+
+		  os << std::setiosflags (std::ios::right)
+		     << std::setw (param.parameter_length);
+		}
+
+	      switch (param.command)
+		{
+		case 'a':
+		  {
+		    char tmp[5];
+
+		    tmp[0] = (is_automatic ? 'a' : ' ');
+		    tmp[1] = (is_formal ? 'f' : ' ');
+		    tmp[2] = (is_global ? 'g' : ' ');
+		    tmp[3] = (is_persistent ? 'p' : ' ');
+		    tmp[4] = 0;
+
+		    os << tmp;
+		  }
+		  break;
+
+		case 'b':
+		  os << varval.byte_size ();
+		  break;
+
+		case 'c':
+		  os << varval.class_name ();
+		  break;
+
+		case 'e':
+		  os << varval.capacity ();
+		  break;
+
+		case 'n':
+		  os << name;
+		  break;
+
+		case 's':
+		  if (param.modifier != 'c')
+		    os << dims_str;
+		  break;
+
+		case 't':
+		  os << varval.type_name ();
+		  break;
+	    
+		default:
+		  error ("whos_line_format: command `%c' unknown",
+			 param.command);
+		}
+
+	      os << std::resetiosflags (std::ios::left)
+		 << std::resetiosflags (std::ios::right);
+	      i++;
+	    }
+	  else
+	    {
+	      os << param.text;
+	      i++;
+	    }
+	}
+    }
+
+    std::string name;
+    bool is_automatic;
+    bool is_formal;
+    bool is_global;
+    bool is_persistent;
+    octave_value varval;
+  };
+
+public:
+  symbol_info_list (void) : lst () { }
+
+  symbol_info_list (const symbol_info_list& sil) : lst (sil.lst) { }
+
+  symbol_info_list& operator = (const symbol_info_list& sil)
+  {
+    if (this != &sil)
+      lst = sil.lst;
+
+    return *this;
+  }
+
+  ~symbol_info_list (void) { }
+
+  void append (const symbol_table::symbol_record& sr)
+  {
+    lst.push_back (symbol_info (sr));
+  }
+
+  void append (const symbol_table::symbol_record& sr,
+	       const std::string& expr_str,
+	       const octave_value& expr_val)
+  {
+    lst.push_back (symbol_info (sr, expr_str, expr_val));
+  }
+
+  size_t size (void) const { return lst.size (); }
+
+  bool empty (void) const { return lst.empty (); }
+
+  Octave_map
+  map_value (const std::string& caller_function_name, int nesting_level) const
+  {
+    size_t len = lst.size ();
+
+    Array<octave_value> name_info (len, 1);
+    Array<octave_value> size_info (len, 1);
+    Array<octave_value> bytes_info (len, 1);
+    Array<octave_value> class_info (len, 1);
+    Array<octave_value> global_info (len, 1);
+    Array<octave_value> sparse_info (len, 1);
+    Array<octave_value> complex_info (len, 1);
+    Array<octave_value> nesting_info (len, 1);
+    Array<octave_value> persistent_info (len, 1);
+
+    std::list<symbol_info>::const_iterator p = lst.begin ();
+
+    for (size_t j = 0; j < len; j++)
+      {
+	const symbol_info& si = *p++;
+
+	Octave_map ni;
+
+	ni.assign ("function", caller_function_name);
+	ni.assign ("level", nesting_level);
+
+	name_info(j) = si.name;
+	global_info(j) = si.is_global;
+	persistent_info(j) = si.is_persistent;
+
+	octave_value val = si.varval;
+
+	size_info(j) = val.size ();
+	bytes_info(j) = val.byte_size ();
+	class_info(j) = val.class_name ();
+	sparse_info(j) = val.is_sparse_type ();
+	complex_info(j) = val.is_complex_type ();
+	nesting_info(j) = ni;
+      }
+
+    Octave_map info;
+
+    info.assign ("name", name_info);
+    info.assign ("size", size_info);
+    info.assign ("bytes", bytes_info);
+    info.assign ("class", class_info);
+    info.assign ("global", global_info);
+    info.assign ("sparse", sparse_info);
+    info.assign ("complex", complex_info);
+    info.assign ("nesting", nesting_info);
+    info.assign ("persistent", persistent_info);
+
+    return info;
+  }
+
+  void display (std::ostream& os)
+  {
+    if (! lst.empty ())
+      {
+	size_t bytes = 0;
+	size_t elements = 0;
+
+	std::list<whos_parameter> params = parse_whos_line_format ();
+
+	print_descriptor (os, params);
+
+	octave_stdout << "\n";
+
+	for (std::list<symbol_info>::const_iterator p = lst.begin ();
+	     p != lst.end (); p++)
+	  {
+	    p->display_line (os, params);
+
+	    octave_value val = p->varval;
+
+	    elements += val.capacity ();
+	    bytes += val.byte_size ();
+	  }
+
+	os << "\nTotal is " << elements
+	   << (elements == 1 ? " element" : " elements")
+	   << " using " << bytes << (bytes == 1 ? " byte" : " bytes")
+	   << "\n";
+      }
+  }
+
+  // Parse the string whos_line_format, and return a parameter list,
+  // containing all information needed to print the given
+  // attributtes of the symbols.
+  std::list<whos_parameter> parse_whos_line_format (void)
+  {
+    int idx;
+    size_t format_len = Vwhos_line_format.length ();
+    char garbage;
+    std::list<whos_parameter> params;
+
+    size_t bytes1;
+    int elements1;
+
+    std::string param_string = "abcenst";
+    Array<int> param_length (dim_vector (param_string.length (), 1));
+    Array<std::string> param_names (dim_vector (param_string.length (), 1));
+    size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t;
+
+    pos_a = param_string.find ('a'); // Attributes
+    pos_b = param_string.find ('b'); // Bytes
+    pos_c = param_string.find ('c'); // Class
+    pos_e = param_string.find ('e'); // Elements
+    pos_n = param_string.find ('n'); // Name
+    pos_s = param_string.find ('s'); // Size
+    pos_t = param_string.find ('t'); // Type
+
+    param_names(pos_a) = "Attr";
+    param_names(pos_b) = "Bytes";
+    param_names(pos_c) = "Class";
+    param_names(pos_e) = "Elements";
+    param_names(pos_n) = "Name";
+    param_names(pos_s) = "Size";
+    param_names(pos_t) = "Type";
+
+    for (size_t i = 0; i < param_string.length (); i++)
+      param_length(i) = param_names(i) . length ();
+
+    // Calculating necessary spacing for name column,
+    // bytes column, elements column and class column
+
+    for (std::list<symbol_info>::const_iterator p = lst.begin ();
+	 p != lst.end (); p++)
+      {
+	std::stringstream ss1, ss2;
+	std::string str;
+
+	str = p->name;
+	param_length(pos_n) = ((str.length ()
+				> static_cast<size_t> (param_length(pos_n)))
+			       ? str.length () : param_length(pos_n));
+
+	octave_value val = p->varval;
+
+	str = val.type_name ();
+	param_length(pos_t) = ((str.length ()
+				> static_cast<size_t> (param_length(pos_t)))
+			       ? str.length () : param_length(pos_t));
+
+	elements1 = val.capacity ();
+	ss1 << elements1;
+	str = ss1.str ();
+	param_length(pos_e) = ((str.length ()
+				> static_cast<size_t> (param_length(pos_e)))
+			       ? str.length () : param_length(pos_e));
+
+	bytes1 = val.byte_size ();
+	ss2 << bytes1;
+	str = ss2.str ();
+	param_length(pos_b) = ((str.length ()
+				> static_cast<size_t> (param_length(pos_b)))
+			       ? str.length () : param_length (pos_b));
+      }
+
+    idx = 0;
+    while (static_cast<size_t> (idx) < format_len)
+      {
+	whos_parameter param;
+	param.command = '\0';
+
+	if (Vwhos_line_format[idx] == '%')
+	  {
+	    bool error_encountered = false;
+	    param.modifier = 'r';
+	    param.parameter_length = 0;
+
+	    int a = 0, b = -1, balance = 1;
+	    unsigned int items;
+	    size_t pos;
+	    std::string cmd;
+
+	    // Parse one command from whos_line_format
+	    cmd = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
+	    pos = cmd.find (';');
+	    if (pos != std::string::npos)
+	      cmd = cmd.substr (0, pos+1);
+	    else
+	      error ("parameter without ; in whos_line_format");
+
+	    idx += cmd.length ();
+
+	    // FIXME -- use iostream functions instead of sscanf!
+
+	    if (cmd.find_first_of ("crl") != 1)
+	      items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d;",
+			      &garbage, &param.command, &a, &b, &balance);
+	    else
+	      items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d;",
+			      &garbage, &param.modifier, &param.command,
+			      &a, &b, &balance) - 1;
+
+	    if (items < 2)
+	      {
+		error ("whos_line_format: parameter structure without command in whos_line_format");
+		error_encountered = true;
+	      }
+
+	    // Insert data into parameter
+	    param.first_parameter_length = 0;
+	    pos = param_string.find (param.command);
+	    if (pos != std::string::npos)
+	      {
+		param.parameter_length = param_length(pos);
+		param.text = param_names(pos);
+		param.line.assign (param_names(pos).length (), '=');
+
+		param.parameter_length = (a > param.parameter_length
+					  ? a : param.parameter_length);
+		if (param.command == 's' && param.modifier == 'c' && b > 0)
+		  param.first_parameter_length = b;
+	      }
+	    else
+	      {
+		error ("whos_line_format: '%c' is not a command",
+		       param.command);
+		error_encountered = true;
+	      }
+
+	    if (param.command == 's')
+	      {
+		// Have to calculate space needed for printing
+		// matrix dimensions Space needed for Size column is
+		// hard to determine in prior, because it depends on
+		// dimensions to be shown. That is why it is
+		// recalculated for each Size-command int first,
+		// rest = 0, total;
+		int rest = 0;
+		int first = param.first_parameter_length;
+		int total = param.parameter_length;
+
+		for (std::list<symbol_info>::const_iterator p = lst.begin ();
+		     p != lst.end (); p++)
+		  {
+		    octave_value val = p->varval;
+		    dim_vector dims = val.dims ();
+		    std::string dims_str = dims.str ();
+		    int first1 = dims_str.find ('x');
+		    int total1 = dims_str.length ();
+		    int rest1 = total1 - first1;
+		    rest = (rest1 > rest ? rest1 : rest);
+		    first = (first1 > first ? first1 : first);
+		    total = (total1 > total ? total1 : total);
+		  }
+
+		if (param.modifier == 'c')
+		  {
+		    if (first < balance)
+		      first += balance - first;
+		    if (rest + balance < param.parameter_length)
+		      rest += param.parameter_length - rest - balance;
+
+		    param.parameter_length = first + rest;
+		    param.first_parameter_length = first;
+		    param.balance = balance;
+		  }
+		else
+		  {
+		    param.parameter_length = total;
+		    param.first_parameter_length = 0;
+		  }
+	      }
+	    else if (param.modifier == 'c')
+	      {
+		error ("whos_line_format: modifier 'c' not available for command '%c'",
+		       param.command);
+		error_encountered = true;
+	      }
+
+	    // What happens if whos_line_format contains negative numbers
+	    // at param_length positions?
+	    param.balance = (b < 0 ? 0 : param.balance);
+	    param.first_parameter_length = (b < 0 ? 0 :
+					    param.first_parameter_length);
+	    param.parameter_length = (a < 0
+				      ? 0
+				      : (param.parameter_length
+					 < param_length(pos_s)
+					 ? param_length(pos_s)
+					 : param.parameter_length));
+
+	    // Parameter will not be pushed into parameter list if ...
+	    if (! error_encountered)
+	      params.push_back (param);
+	  }
+	else
+	  {
+	    // Text string, to be printed as it is ...
+	    std::string text;
+	    size_t pos;
+	    text = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
+	    pos = text.find ('%');
+	    if (pos != std::string::npos)
+	      text = text.substr (0, pos);
+
+	    // Push parameter into list ...
+	    idx += text.length ();
+	    param.text=text;
+	    param.line.assign (text.length(), ' ');
+	    params.push_back (param);
+	  }
+      }
+
+    return params;
+  }
+
+private:
+  std::list<symbol_info> lst;
+
+};
+
+static octave_value
+do_who (int argc, const string_vector& argv, bool return_list,
+	bool verbose = false, std::string msg = std::string ())
+{
+  octave_value retval;
+
+  std::string my_name = argv[0];
+
+  bool global_only = false;
+  bool have_regexp = false;
+
+  int i;
+  for (i = 1; i < argc; i++)
+    {
+      if (argv[i] == "-file")
+	{
+	  // FIXME. This is an inefficient manner to implement this as the 
+	  // variables are loaded in to a temporary context and then treated.
+	  // It would be better to refecat symbol_info_list to not store the
+	  // symbol records and then use it in load-save.cc (do_load) to
+	  // implement this option there so that the variables are never 
+	  // stored at all.
+	  if (i == argc - 1)
+	    error ("whos: -file argument must be followed by a file name");
+	  else
+	    {
+	      std::string nm = argv [i + 1];
+
+	      unwind_protect::begin_frame ("do_who_file");
+
+	      // Set up temporary scope.
+
+	      symbol_table::scope_id tmp_scope = symbol_table::alloc_scope ();
+	      unwind_protect::add (symbol_table::erase_scope, &tmp_scope);
+
+	      symbol_table::set_scope (tmp_scope);
+
+	      octave_call_stack::push (tmp_scope, 0);
+	      unwind_protect::add (octave_call_stack::unwind_pop, 0);
+
+	      unwind_protect::add (symbol_table::clear_variables);
+
+	      feval ("load", octave_value (nm), 0);
+
+	      if (! error_state)
+		{
+		  std::string newmsg = std::string ("Variables in the file ") + 
+		    nm + ":\n\n";
+
+		  retval =  do_who (i, argv, return_list, verbose, newmsg);
+		}
+
+	      unwind_protect::run_frame ("do_who_file");
+	    }
+
+	  return retval;
+	}
+      else if (argv[i] == "-regexp")
+	have_regexp = true;
+      else if (argv[i] == "global")
+	global_only = true;
+      else if (argv[i][0] == '-')
+	warning ("%s: unrecognized option `%s'", my_name.c_str (),
+		 argv[i].c_str ());
+      else
+	break;
+    }
+
+  int npats = argc - i;
+  string_vector pats;
+  if (npats > 0)
+    {
+      pats.resize (npats);
+      for (int j = 0; j < npats; j++)
+	pats[j] = argv[i+j];
+    }
+  else
+    {
+      pats.resize (++npats);
+      pats[0] = "*";
+    }
+    
+  symbol_info_list symbol_stats;
+  std::list<std::string> symbol_names;
+
+  for (int j = 0; j < npats; j++)
+    {
+      std::string pat = pats[j];
+
+      if (have_regexp)
+	{
+	  std::list<symbol_table::symbol_record> tmp = global_only
+	    ? symbol_table::regexp_global_variables (pat)
+	    : symbol_table::regexp_variables (pat);
+
+	  for (std::list<symbol_table::symbol_record>::const_iterator p = tmp.begin ();
+	       p != tmp.end (); p++)
+	    {
+	      if (p->is_variable ())
+		{
+		  if (verbose)
+		    symbol_stats.append (*p);
+		  else
+		    symbol_names.push_back (p->name ());
+		}
+	    }
+	}
+      else
+	{
+	  size_t pos = pat.find_first_of (".({");
+
+	  if (pos != std::string::npos && pos > 0)
+	    {
+	      if (verbose)
+		{
+		  // NOTE: we can only display information for
+		  // expressions based on global values if the variable is
+		  // global in the current scope because we currently have
+		  // no way of looking up the base value in the global
+		  // scope and then evaluating the arguments in the
+		  // current scope.
+
+		  std::string base_name = pat.substr (0, pos);
+
+		  if (symbol_table::is_variable (base_name))
+		    {
+		      symbol_table::symbol_record sr
+			= symbol_table::find_symbol (base_name);
+
+		      if (! global_only || sr.is_global ())
+			{
+			  int parse_status;
+
+			  octave_value expr_val
+			    = eval_string (pat, true, parse_status);
+
+			  if (! error_state)
+			    symbol_stats.append (sr, pat, expr_val);
+			  else
+			    return retval;
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      std::list<symbol_table::symbol_record> tmp = global_only
+		? symbol_table::glob_global_variables (pat)
+		: symbol_table::glob_variables (pat);
+
+	      for (std::list<symbol_table::symbol_record>::const_iterator p = tmp.begin ();
+		   p != tmp.end (); p++)
+		{
+                  if (p->is_variable ())
+                    {
+                      if (verbose)
+                        symbol_stats.append (*p);
+                      else
+                        symbol_names.push_back (p->name ());
+                    }
+		}
+	    }
+	}
+    }
+
+  if (return_list)
+    {
+      if (verbose)
+	{
+	  std::string caller_function_name;
+	  octave_function *caller = octave_call_stack::caller ();
+	  if (caller)
+	    caller_function_name = caller->name ();
+
+	  retval = symbol_stats.map_value (caller_function_name, 1);
+	}
+      else
+	retval = Cell (string_vector (symbol_names));
+    }
+  else if (! (symbol_stats.empty () && symbol_names.empty ()))
+    {
+      if (msg.length () == 0)
+	if (global_only)
+	  octave_stdout << "Global variables:\n\n";
+	else
+	  octave_stdout << "Variables in the current scope:\n\n";
+      else
+	octave_stdout << msg;
+
+      if (verbose)
+	symbol_stats.display (octave_stdout);
+      else
+	{
+	  string_vector names (symbol_names);
+
+	  names.list_in_columns (octave_stdout);
+	}
+
+      octave_stdout << "\n";
+    }
+
+  return retval;
+}
+
+DEFUN (who, args, nargout,
+  "-*- texinfo -*-\n\
+ at deffn  {Command} who\n\
+ at deffnx {Command} who pattern @dots{}\n\
+ at deffnx {Command} who option pattern @dots{}\n\
+ at deffnx {Command} C = who(\"pattern\", @dots{})\n\
+List currently defined variables matching the given patterns.  Valid\n\
+pattern syntax is the same as described for the @code{clear} command.\n\
+If no patterns are supplied, all variables are listed.\n\
+By default, only variables visible in the local scope are displayed.\n\
+\n\
+The following are valid options but may not be combined.\n\
+\n\
+ at table @code\n\
+ at item global\n\
+List variables in the global scope rather than the current scope.\n\
+ at item -regexp\n\
+The patterns are considered to be regular expressions when matching the\n\
+variables to display.  The same pattern syntax accepted by\n\
+the @code{regexp} function is used.\n\
+ at item -file\n\
+The next argument is treated as a filename.  All variables found within the\n\
+specified file are listed.  No patterns are accepted when reading variables\n\
+from a file.\n\
+ at end table\n\
+\n\
+If called as a function, return a cell array of defined variable names\n\
+matching the given patterns.\n\
+ at seealso{whos, regexp}\n\
+ at end deffn")
+{
+  octave_value retval;
+
+  if (nargout < 2)
+    {
+      int argc = args.length () + 1;
+
+      string_vector argv = args.make_argv ("who");
+
+      if (! error_state)
+	retval = do_who (argc, argv, nargout == 1);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (whos, args, nargout,
+  "-*- texinfo -*-\n\
+ at deffn  {Command} whos\n\
+ at deffnx {Command} whos pattern @dots{}\n\
+ at deffnx {Command} whos option pattern @dots{}\n\
+ at deffnx {Command} S = whos(\"pattern\", @dots{})\n\
+Provide detailed information on currently defined variables matching the\n\
+given patterns.  Options and pattern syntax are the same as for the\n\
+ at code{who} command.  Extended information about each variable is\n\
+summarized in a table with the following default entries.\n\
+\n\
+ at table @asis\n\
+ at item Attr\n\
+Attributes of the listed variable.  Possible attributes are:\n\
+ at table @asis\n\
+ at item blank\n\
+Variable in local scope\n\
+ at item @code{g}\n\
+Variable with global scope\n\
+ at item @code{p}\n\
+Persistent variable\n\
+ at end table\n\
+ at item Name\n\
+The name of the variable.\n\
+ at item Size\n\
+The logical size of the variable.  A scalar is 1x1, a vector is 1xN or Nx1,\n\
+a 2-D matrix is MxN.\n\
+ at item Bytes\n\
+The amount of memory currently used to store the variable.\n\
+ at item Class\n\
+The class of the variable.  Examples include double, single, char, uint16,\n\
+cell, and struct.\n\
+ at end table\n\
+\n\
+The table can be customized to display more or less information through\n\
+the function @code{whos_line_format}.\n\
+\n\
+If @code{whos} is called as a function, return a struct array of defined\n\
+variable names matching the given patterns.  Fields in the structure\n\
+describing each variable are: name, size, bytes, class, global, sparse, \n\
+complex, nesting, persistent.\n\
+ at seealso{who, whos_line_format}\n\
+ at end deffn")
+{
+  octave_value retval;
+
+  if (nargout < 2)
+    {
+      int argc = args.length () + 1;
+
+      string_vector argv = args.make_argv ("whos");
+
+      if (! error_state)
+	retval = do_who (argc, argv, nargout == 1, true);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Defining variables.
+
+void
+bind_ans (const octave_value& val, bool print)
+{
+  static std::string ans = "ans";
+
+  if (val.is_defined ())
+    {
+      if (val.is_cs_list ())
+	{
+	  octave_value_list lst = val.list_value ();
+
+	  for (octave_idx_type i = 0; i < lst.length (); i++)
+	    bind_ans (lst(i), print);
+	}
+      else
+	{
+	  symbol_table::varref (ans) = val;
+
+	  if (print)
+	    val.print_with_name (octave_stdout, ans);
+	}
+    }
+}
+
+void
+bind_internal_variable (const std::string& fname, const octave_value& val)
+{
+  octave_value_list args;
+
+  args(0) = val;
+
+  feval (fname, args, 0);
+}
+
+void 
+mlock (void)
+{
+  octave_function *fcn = octave_call_stack::current ();
+
+  if (fcn)
+    fcn->lock ();
+  else
+    error ("mlock: invalid use outside a function");
+}
+
+void 
+munlock (const std::string& nm)
+{
+  octave_value val = symbol_table::find_function (nm);
+
+  if (val.is_defined ())
+    {
+      octave_function *fcn = val.function_value ();
+
+      if (fcn)
+	fcn->unlock ();
+    }
+}
+
+bool
+mislocked (const std::string& nm)
+{
+  bool retval = false;
+
+  octave_value val = symbol_table::find_function (nm);
+
+  if (val.is_defined ())
+    {
+      octave_function *fcn = val.function_value ();
+
+      if (fcn)
+	retval = fcn->islocked ();
+    }
+
+  return retval;
+}
+
+DEFUN (mlock, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mlock ()\n\
+Lock the current function into memory so that it can't be cleared.\n\
+ at seealso{munlock, mislocked, persistent}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 0)
+    {
+      octave_function *fcn = octave_call_stack::caller ();
+
+      if (fcn)
+	fcn->lock ();
+      else
+	error ("mlock: invalid use outside a function");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (munlock, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} munlock (@var{fcn})\n\
+Unlock the named function.  If no function is named\n\
+then unlock the current function.\n\
+ at seealso{mlock, mislocked, persistent}\n\
+ at end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length() == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+        munlock (name);
+      else
+	error ("munlock: expecting argument to be a function name");
+    }
+  else if (args.length () == 0)
+    {
+      octave_function *fcn = octave_call_stack::caller ();
+
+      if (fcn)
+        fcn->unlock ();
+      else
+        error ("munlock: invalid use outside a function");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+
+DEFUN (mislocked, args, ,
+  "-*- texinfo -*-\n\
+ at deftypefn {Built-in Function} {} mislocked (@var{fcn})\n\
+Return true if the named function is locked.  If no function is named\n\
+then return true if the current function is locked.\n\
+ at seealso{mlock, munlock, persistent}\n\
+ at end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length() == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+        retval = mislocked (name);
+      else
+	error ("mislocked: expecting argument to be a function name");
+    }
+  else if (args.length () == 0)
+    {
+      octave_function *fcn = octave_call_stack::caller ();
+
+      if (fcn)
+        retval = fcn->islocked ();
+      else
+        error ("mislocked: invalid use outside a function");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+// Deleting names from the symbol tables.
+
+static inline bool
+name_matches_any_pattern (const std::string& nm, const string_vector& argv, 
+			  int argc, int idx, bool have_regexp = false)
+{
+  bool retval = false;
+
+  for (int k = idx; k < argc; k++)
+    {
+      std::string patstr = argv[k];
+      if (! patstr.empty ())
+	{
+	  if (have_regexp)
+	    {
+	      regex_match pattern (patstr);
+
+	      if (pattern.match (nm))
+		{
+		  retval = true;
+		  break;
+		}
+	    }
+	  else
+	    {
+	      glob_match pattern (patstr);
+
+	      if (pattern.match (nm))
+		{
+		  retval = true;
+		  break;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static inline void
+maybe_warn_exclusive (bool exclusive)
+{
+  if (exclusive)
+    warning ("clear: ignoring --exclusive option");
+}
+
+static void
+do_clear_functions (const string_vector& argv, int argc, int idx,
+		    bool exclusive = false)
+{
+  if (idx == argc)
+    symbol_table::clear_functions ();
+  else
+    {
+      if (exclusive)
+	{
+	  string_vector fcns = symbol_table::user_function_names ();
+
+	  int fcount = fcns.length ();
+
+	  for (int i = 0; i < fcount; i++)
+	    {
+	      std::string nm = fcns[i];
+
+	      if (! name_matches_any_pattern (nm, argv, argc, idx))
+		symbol_table::clear_function (nm);
+	    }
+	}
+      else
+	{
+	  while (idx < argc)
+	    symbol_table::clear_function_pattern (argv[idx++]);
+	}
+    }
+}
+
+static void
+do_clear_globals (const string_vector& argv, int argc, int idx,
+		  bool exclusive = false)
+{
+  if (idx == argc)
+    {
+      string_vector gvars = symbol_table::global_variable_names ();
+
+      int gcount = gvars.length ();
+
+      for (int i = 0; i < gcount; i++)
+	symbol_table::clear_global (gvars[i]);
+    }
+  else
+    {
+      if (exclusive)
+	{
+	  string_vector gvars = symbol_table::global_variable_names ();
+
+	  int gcount = gvars.length ();
+
+	  for (int i = 0; i < gcount; i++)
+	    {
+	      std::string nm = gvars[i];
+
+	      if (! name_matches_any_pattern (nm, argv, argc, idx))
+		symbol_table::clear_global (nm);
+	    }
+	}
+      else
+	{
+	  while (idx < argc)
+	    symbol_table::clear_global_pattern (argv[idx++]);
+	}
+    }
+}
+
+static void
+do_clear_variables (const string_vector& argv, int argc, int idx,
+		    bool exclusive = false, bool have_regexp = false)
+{
+  if (idx == argc)
+    symbol_table::clear_variables ();
+  else
+    {
+      if (exclusive)
+	{
+	  string_vector lvars = symbol_table::variable_names ();
+
+	  int lcount = lvars.length ();
+
+	  for (int i = 0; i < lcount; i++)
+	    {
+	      std::string nm = lvars[i];
+
+	      if (! name_matches_any_pattern (nm, argv, argc, idx, have_regexp))
+		symbol_table::clear_variable (nm);
+	    }
+	}
+      else
+	{
+	  if (have_regexp)
+	    while (idx < argc)
+	      symbol_table::clear_variable_regexp (argv[idx++]);
+	  else
+	    while (idx < argc)
+	      symbol_table::clear_variable_pattern (argv[idx++]);
+	}
+    }
+}
+
+static void
+do_clear_symbols (const string_vector& argv, int argc, int idx,
+		  bool exclusive = false)
+{
+  if (idx == argc)
+    symbol_table::clear_variables ();
+  else
+    {
+      if (exclusive)
+	{
+	  // FIXME -- is this really what we want, or do we
+	  // somehow want to only clear the functions that are not
+	  // shadowed by local variables?  It seems that would be a
+	  // bit harder to do.
+
+	  do_clear_variables (argv, argc, idx, exclusive);
+	  do_clear_functions (argv, argc, idx, exclusive);
+	}
+      else
+	{
+	  while (idx < argc)
+	    symbol_table::clear_symbol_pattern (argv[idx++]);
+	}
+    }
+}
+
+static void
+do_matlab_compatible_clear (const string_vector& argv, int argc, int idx)
+{
+  // This is supposed to be mostly Matlab compatible.
+
+  for (; idx < argc; idx++)
+    {
+      if (argv[idx] == "all"
+	  && ! symbol_table::is_local_variable ("all"))
+	{
+	  symbol_table::clear_all ();
+	}
+      else if (argv[idx] == "functions"
+	       && ! symbol_table::is_local_variable ("functions"))
+	{
+	  do_clear_functions (argv, argc, ++idx);
+	}
+      else if (argv[idx] == "global"
+	       && ! symbol_table::is_local_variable ("global"))
+	{
+	  do_clear_globals (argv, argc, ++idx);
+	}
+      else if (argv[idx] == "variables"
+	       && ! symbol_table::is_local_variable ("variables"))
+	{
+	  symbol_table::clear_variables ();
+	}
+      else if (argv[idx] == "classes"
+	       && ! symbol_table::is_local_variable ("classes"))
+	{
+	  symbol_table::clear_objects ();
+	  octave_class::clear_exemplar_map ();
+	}
+      else
+	{
+	  symbol_table::clear_symbol_pattern (argv[idx]);
+	}
+    }
+}
+
+#define CLEAR_OPTION_ERROR(cond) \
+  do \
+    { \
+      if (cond) \
+        { \
+          print_usage (); \
+          return retval; \
+        } \
+    } \
+  while (0)
+
+DEFUN (clear, args, ,
+  "-*- texinfo -*-\n\
+ at deffn {Command} clear [options] pattern @dots{}\n\
+Delete the names matching the given patterns from the symbol table.  The\n\
+pattern may contain the following special characters:\n\
+\n\
+ at table @code\n\
+ at item ?\n\
+Match any single character.\n\
+\n\
+ at item *\n\
+Match zero or more characters.\n\
+\n\
+ at item [ @var{list} ]\n\
+Match the list of characters specified by @var{list}.  If the first\n\
+character is @code{!} or @code{^}, match all characters except those\n\
+specified by @var{list}.  For example, the pattern @samp{[a-zA-Z]} will\n\
+match all lower and upper case alphabetic characters.\n\
+ at end table\n\
+\n\
+For example, the command\n\
+\n\
+ at example\n\
+clear foo b*r\n\
+ at end example\n\
+\n\
+ at noindent\n\
+clears the name @code{foo} and all names that begin with the letter\n\
+ at code{b} and end with the letter @code{r}.\n\
+\n\
+If @code{clear} is called without any arguments, all user-defined\n\
+variables (local and global) are cleared from the symbol table.  If\n\
+ at code{clear} is called with at least one argument, only the visible\n\
+names matching the arguments are cleared.  For example, suppose you have\n\
+defined a function @code{foo}, and then hidden it by performing the\n\
+assignment @code{foo = 2}.  Executing the command @kbd{clear foo} once\n\
+will clear the variable definition and restore the definition of\n\
+ at code{foo} as a function.  Executing @kbd{clear foo} a second time will\n\
+clear the function definition.\n\
+\n\
+The following options are available in both long and short form\n\
+ at table @code\n\
+ at item -all, -a\n\
+Clears all local and global user-defined variables and all functions\n\
+from the symbol table.\n\
+\n\
+ at item -exclusive, -x\n\
+Clears the variables that don't match the following pattern.\n\
+\n\
+ at item -functions, -f\n\
+Clears the function names and the built-in symbols names.\n\
+ at item -global, -g\n\
+Clears the global symbol names.\n\
+ at item -variables, -v\n\
+Clears the local variable names.\n\
+ at item -classes, -c\n\
+Clears the class structure table and clears all objects.\n\
+ at item -regexp, -r\n\
+The arguments are treated as regular expressions as any variables that\n\
+match will be cleared.\n\
+ at end table\n\
+With the exception of @code{exclusive}, all long options can be used \n\
+without the dash as well.\n\
+ at end deffn")
+{
+  octave_value_list retval;
+
+  int argc = args.length () + 1;
+
+  string_vector argv = args.make_argv ("clear");
+
+  if (! error_state)
+    {
+      if (argc == 1)
+	{
+          do_clear_globals (argv, argc, 1);
+          do_clear_variables (argv, argc, 1); 
+	}
+      else
+	{
+	  int idx = 0;
+
+	  bool clear_all = false;
+	  bool clear_functions = false;
+	  bool clear_globals = false;
+	  bool clear_variables = false;
+          bool clear_objects = false;
+	  bool exclusive = false;
+	  bool have_regexp = false;
+	  bool have_dash_option = false;
+
+	  while (++idx < argc)
+	    {
+	      if (argv[idx] == "-all" || argv[idx] == "-a")
+		{
+		  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+		  have_dash_option = true;
+		  clear_all = true;
+		}
+	      else if (argv[idx] == "-exclusive" || argv[idx] == "-x")
+		{
+		  have_dash_option = true;
+		  exclusive = true;
+		}
+	      else if (argv[idx] == "-functions" || argv[idx] == "-f")
+		{
+		  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+		  have_dash_option = true;
+		  clear_functions = true;
+		}
+	      else if (argv[idx] == "-global" || argv[idx] == "-g")
+		{
+		  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+		  have_dash_option = true;
+		  clear_globals = true;
+		}
+	      else if (argv[idx] == "-variables" || argv[idx] == "-v")
+		{
+		  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+		  have_dash_option = true;
+		  clear_variables = true;
+		}
+	      else if (argv[idx] == "-classes" || argv[idx] == "-c")
+		{
+		  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+		  have_dash_option = true;
+		  clear_objects = true;
+		}
+	      else if (argv[idx] == "-regexp" || argv[idx] == "-r")
+		{
+		  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+		  have_dash_option = true;
+		  have_regexp = true;
+		}
+	      else
+		break;
+	    }
+
+	  if (idx <= argc)
+	    {
+	      if (! have_dash_option)
+		{
+		  do_matlab_compatible_clear (argv, argc, idx);
+		}
+	      else
+		{
+		  if (clear_all)
+		    {
+		      maybe_warn_exclusive (exclusive);
+
+		      if (++idx < argc)
+			warning
+			  ("clear: ignoring extra arguments after -all");
+
+		      symbol_table::clear_all ();
+		    }
+		  else if (have_regexp)
+		    {
+		      do_clear_variables (argv, argc, idx, exclusive, true);
+		    }
+		  else if (clear_functions)
+		    {
+		      do_clear_functions (argv, argc, idx, exclusive);
+		    }
+		  else if (clear_globals)
+		    {
+		      do_clear_globals (argv, argc, idx, exclusive);
+		    }
+		  else if (clear_variables)
+		    {
+		      do_clear_variables (argv, argc, idx, exclusive);
+		    }
+		  else if (clear_objects)
+		    {
+		      symbol_table::clear_objects ();
+		      octave_class::clear_exemplar_map ();
+		    }
+		  else
+		    {
+		      do_clear_symbols (argv, argc, idx, exclusive);
+		    }
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
+DEFUN (whos_line_format, args, nargout,
+  "-*- texinfo -*-\n\
+ at deftypefn  {Built-in Function} {@var{val} =} whos_line_format ()\n\
+ at deftypefnx {Built-in Function} {@var{old_val} =} whos_line_format (@var{new_val})\n\
+Query or set the format string used by the command @code{whos}.\n\
+\n\
+A full format string is:\n\
+\n\
+ at c Set example in small font to prevent overfull line\n\
+ at smallexample\n\
+%[modifier]<command>[:width[:left-min[:balance]]];\n\
+ at end smallexample\n\
+\n\
+The following command sequences are available:\n\
+\n\
+ at table @code\n\
+ at item %a\n\
+Prints attributes of variables (g=global, p=persistent,\n\
+f=formal parameter, a=automatic variable).\n\
+ at item %b\n\
+Prints number of bytes occupied by variables.\n\
+ at item %c\n\
+Prints class names of variables.\n\
+ at item %e\n\
+Prints elements held by variables.\n\
+ at item %n\n\
+Prints variable names.\n\
+ at item %s\n\
+Prints dimensions of variables.\n\
+ at item %t\n\
+Prints type names of variables.\n\
+ at end table\n\
+\n\
+Every command may also have an alignment modifier:\n\
+\n\
+ at table @code\n\
+ at item l\n\
+Left alignment.\n\
+ at item r\n\
+Right alignment (default).\n\
+ at item c\n\
+Column-aligned (only applicable to command %s).\n\
+ at end table\n\
+\n\
+The @code{width} parameter is a positive integer specifying the minimum\n\
+number of columns used for printing.  No maximum is needed as the field will\n\
+auto-expand as required.\n\
+\n\
+The parameters @code{left-min} and @code{balance} are only available when the\n\
+column-aligned modifier is used with the command @samp{%s}.\n\
+ at code{balance} specifies the column number within the field width which will\n\
+be aligned between entries.  Numbering starts from 0 which indicates the\n\
+leftmost column.  @code{left-min} specifies the minimum field width to the\n\
+left of the specified balance column.\n\
+\n\
+The default format is\n\
+ at code{\"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\\n\"}.\n\
+ at seealso{whos}\n\
+ at end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (whos_line_format);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/variables.h b/src/variables.h
new file mode 100644
index 0000000..0d9060f
--- /dev/null
+++ b/src/variables.h
@@ -0,0 +1,137 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+              2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_variables_h)
+#define octave_variables_h 1
+
+class octave_function;
+class octave_user_function;
+
+class tree_identifier;
+class octave_value;
+class octave_value_list;
+class octave_builtin;
+class string_vector;
+
+#include <climits>
+#include <cfloat>
+
+#include <string>
+
+#include "ov.h"
+#include "ov-builtin.h"
+#include "symtab.h"
+
+extern OCTINTERP_API void clear_mex_functions (void);
+
+extern OCTINTERP_API octave_function *
+is_valid_function (const octave_value&, const std::string& = std::string (),
+		   bool warn = false); 
+
+extern OCTINTERP_API octave_function *
+is_valid_function (const std::string&, const std::string& = std::string (),
+		   bool warn = false); 
+
+extern OCTINTERP_API octave_function *
+extract_function (const octave_value& arg, const std::string& warn_for,
+		  const std::string& fname, const std::string& header,
+		  const std::string& trailer);
+
+extern OCTINTERP_API string_vector
+get_struct_elts (const std::string& text);
+
+extern OCTINTERP_API string_vector
+generate_struct_completions (const std::string& text, std::string& prefix,
+			     std::string& hint);
+
+extern OCTINTERP_API bool
+looks_like_struct (const std::string& text);
+
+extern OCTINTERP_API int
+symbol_exist (const std::string& name, const std::string& type = "any");
+
+extern OCTINTERP_API std::string
+unique_symbol_name (const std::string& basename);
+
+extern OCTINTERP_API octave_value lookup_function_handle (const std::string& nm);
+
+extern OCTINTERP_API octave_value
+get_global_value (const std::string& nm, bool silent = false);
+
+extern OCTINTERP_API void set_global_value (const std::string& nm, const octave_value& val);
+
+extern OCTINTERP_API octave_value
+set_internal_variable (bool& var, const octave_value_list& args,
+		       int nargout, const char *nm);
+
+extern OCTINTERP_API octave_value
+set_internal_variable (char& var, const octave_value_list& args,
+		       int nargout, const char *nm);
+
+extern OCTINTERP_API octave_value
+set_internal_variable (int& var, const octave_value_list& args,
+		       int nargout, const char *nm,
+		       int minval = INT_MIN, int maxval = INT_MAX);
+
+extern OCTINTERP_API octave_value
+set_internal_variable (double& var, const octave_value_list& args,
+		       int nargout, const char *nm,
+		       double minval = DBL_MIN, double maxval = DBL_MAX);
+
+extern OCTINTERP_API octave_value
+set_internal_variable (std::string& var, const octave_value_list& args,
+		       int nargout, const char *nm, bool empty_ok = true);
+
+#define SET_INTERNAL_VARIABLE(NM) \
+  set_internal_variable (V ## NM, args, nargout, #NM)
+
+#define SET_NONEMPTY_INTERNAL_STRING_VARIABLE(NM) \
+  set_internal_variable (V ## NM, args, nargout, #NM, false)
+
+#define SET_INTERNAL_VARIABLE_WITH_LIMITS(NM, MINVAL, MAXVAL) \
+  set_internal_variable (V ## NM, args, nargout, #NM, MINVAL, MAXVAL)
+
+extern OCTINTERP_API std::string builtin_string_variable (const std::string&);
+extern OCTINTERP_API int builtin_real_scalar_variable (const std::string&, double&);
+extern OCTINTERP_API octave_value builtin_any_variable (const std::string&);
+
+extern OCTINTERP_API void bind_ans (const octave_value& val, bool print);
+
+extern OCTINTERP_API void
+bind_internal_variable (const std::string& fname, const octave_value& val);
+
+extern OCTINTERP_API void mlock (void);
+extern OCTINTERP_API void munlock (const std::string&);
+extern OCTINTERP_API bool mislocked (const std::string&);
+
+extern OCTINTERP_API void clear_function (const std::string& nm);
+extern OCTINTERP_API void clear_variable (const std::string& nm);
+extern OCTINTERP_API void clear_symbol (const std::string& nm);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..397ea1e
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,99 @@
+/*
+
+Copyright (C) 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
+              2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_version_h)
+#define octave_version_h 1
+
+#define OCTAVE_VERSION "3.2.4"
+
+#define OCTAVE_API_VERSION "api-v37"
+
+#define OCTAVE_RELEASE_DATE "2010-01-22"
+
+#define OCTAVE_COPYRIGHT "Copyright (C) 2009 John W. Eaton and others."
+
+// This is the first line printed by --version.  The GNU coding
+// standards say that the version number should follow the last space
+// on the line.
+
+#define OCTAVE_NAME_AND_VERSION "GNU Octave, version " OCTAVE_VERSION
+
+#define OCTAVE_CONFIG_STATEMENT \
+  "Octave was configured for \"" OCTAVE_CANONICAL_HOST_TYPE "\"."
+
+#define OCTAVE_COPYING_STATEMENT \
+  "This is free software; see the source code for copying conditions."
+
+#define X_OCTAVE_WARRANTY_STATEMENT(ARG) \
+  "There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or\n\
+FITNESS FOR A PARTICULAR PURPOSE." ARG
+
+#define OCTAVE_WARRANTY_STATEMENT \
+  X_OCTAVE_WARRANTY_STATEMENT ("")
+
+#define OCTAVE_WWW_STATEMENT \
+  "Additional information about Octave is available at http://www.octave.org."
+
+#define OCTAVE_CONTRIB_STATEMENT \
+  "Please contribute if you find this software useful.\n\
+For more information, visit http://www.octave.org/help-wanted.html"
+
+#define OCTAVE_BUGS_STATEMENT \
+  "Report bugs to <bug at octave.org> (but first, please read\n\
+http://www.octave.org/bugs.html to learn how to write a helpful report)."
+
+#define OCTAVE_NAME_VERSION_AND_COPYRIGHT \
+  OCTAVE_NAME_AND_VERSION "\n" \
+  OCTAVE_COPYRIGHT
+
+#define OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY \
+  X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY("") \
+
+#define X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY(ARG) \
+  OCTAVE_NAME_VERSION_AND_COPYRIGHT "\n" \
+  OCTAVE_COPYING_STATEMENT "\n" \
+  X_OCTAVE_WARRANTY_STATEMENT (ARG) "\n\n" \
+  OCTAVE_CONFIG_STATEMENT
+
+#define X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS(ARG) \
+  X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY(ARG) "\n\n" \
+  OCTAVE_WWW_STATEMENT "\n\n" \
+  OCTAVE_CONTRIB_STATEMENT "\n\n" \
+  OCTAVE_BUGS_STATEMENT
+
+#define OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS \
+  X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS ("")
+
+#define OCTAVE_STARTUP_MESSAGE \
+  X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS \
+    ("  For details, type `warranty'.") "\n\n" \
+  "For information about changes from previous versions, type `news'."
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/xdiv.cc b/src/xdiv.cc
new file mode 100644
index 0000000..e0a290e
--- /dev/null
+++ b/src/xdiv.cc
@@ -0,0 +1,1038 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003,
+              2005, 2006, 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+
+#include "Array-util.h"
+#include "CMatrix.h"
+#include "dMatrix.h"
+#include "CNDArray.h"
+#include "dNDArray.h"
+#include "fCMatrix.h"
+#include "fMatrix.h"
+#include "fCNDArray.h"
+#include "fNDArray.h"
+#include "oct-cmplx.h"
+#include "dDiagMatrix.h"
+#include "fDiagMatrix.h"
+#include "CDiagMatrix.h"
+#include "fCDiagMatrix.h"
+#include "quit.h"
+
+#include "error.h"
+#include "xdiv.h"
+
+static inline bool
+result_ok (octave_idx_type info)
+{
+  assert (info != -1);
+
+  return (info != -2);
+}
+
+static void
+solve_singularity_warning (double rcond)
+{
+  warning ("matrix singular to machine precision, rcond = %g", rcond);
+  warning ("attempting to find minimum norm solution");
+}
+
+template <class T1, class T2>
+bool
+mx_leftdiv_conform (const T1& a, const T2& b)
+{
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type b_nr = b.rows ();
+
+  if (a_nr != b_nr)
+    {
+      octave_idx_type a_nc = a.cols ();
+      octave_idx_type b_nc = b.cols ();
+
+      gripe_nonconformant ("operator \\", a_nr, a_nc, b_nr, b_nc);
+      return false;
+    }
+
+  return true;
+}
+
+#define INSTANTIATE_MX_LEFTDIV_CONFORM(T1, T2) \
+  template bool mx_leftdiv_conform (const T1&, const T2&)
+
+INSTANTIATE_MX_LEFTDIV_CONFORM (Matrix, Matrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (Matrix, ComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexMatrix, Matrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexMatrix, ComplexMatrix);
+
+template <class T1, class T2>
+bool
+mx_div_conform (const T1& a, const T2& b)
+{
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nc != b_nc)
+    {
+      octave_idx_type a_nr = a.rows ();
+      octave_idx_type b_nr = b.rows ();
+
+      gripe_nonconformant ("operator /", a_nr, a_nc, b_nr, b_nc);
+      return false;
+    }
+
+  return true;
+}
+
+#define INSTANTIATE_MX_DIV_CONFORM(T1, T2) \
+  template bool mx_div_conform (const T1&, const T2&)
+
+INSTANTIATE_MX_DIV_CONFORM (Matrix, Matrix);
+INSTANTIATE_MX_DIV_CONFORM (Matrix, ComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, Matrix);
+INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, ComplexMatrix);
+
+// Right division functions.
+//
+//       op2 / op1:   m   cm
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+// -*- 1 -*-
+Matrix
+xdiv (const Matrix& a, const Matrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return Matrix ();
+
+  Matrix atmp = a.transpose ();
+  Matrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+
+  Matrix result 
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.transpose ();
+}
+
+// -*- 2 -*-
+ComplexMatrix
+xdiv (const Matrix& a, const ComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return ComplexMatrix ();
+
+  Matrix atmp = a.transpose ();
+  ComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+
+  ComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 3 -*-
+ComplexMatrix
+xdiv (const ComplexMatrix& a, const Matrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return ComplexMatrix ();
+
+  ComplexMatrix atmp = a.hermitian ();
+  Matrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+
+  ComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 4 -*-
+ComplexMatrix
+xdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return ComplexMatrix ();
+
+  ComplexMatrix atmp = a.hermitian ();
+  ComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+
+  ComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// Funny element by element division operations.
+//
+//       op2 \ op1:   s   cs
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+Matrix
+x_el_div (double a, const Matrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  Matrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+x_el_div (double a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+x_el_div (const Complex a, const Matrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+ComplexMatrix
+x_el_div (const Complex a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+// Funny element by element division operations.
+//
+//          op2 \ op1:   s   cs
+//               +--   +---+----+
+//   N-d array         | 1 |  3 |
+//                     +---+----+
+//   complex N-d array | 2 |  4 |
+//                     +---+----+
+
+NDArray
+x_el_div (double a, const NDArray& b)
+{
+  NDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+ComplexNDArray
+x_el_div (double a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+ComplexNDArray
+x_el_div (const Complex a, const NDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+ComplexNDArray
+x_el_div (const Complex a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+// Left division functions.
+//
+//       op2 \ op1:   m   cm
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+// -*- 1 -*-
+Matrix
+xleftdiv (const Matrix& a, const Matrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return Matrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 2 -*-
+ComplexMatrix
+xleftdiv (const Matrix& a, const ComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return ComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 3 -*-
+ComplexMatrix
+xleftdiv (const ComplexMatrix& a, const Matrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return ComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 4 -*-
+ComplexMatrix
+xleftdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return ComplexMatrix ();
+
+  octave_idx_type info;
+  double rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+static void
+solve_singularity_warning (float rcond)
+{
+  warning ("matrix singular to machine precision, rcond = %g", rcond);
+  warning ("attempting to find minimum norm solution");
+}
+
+INSTANTIATE_MX_LEFTDIV_CONFORM (FloatMatrix, FloatMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (FloatMatrix, FloatComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (FloatComplexMatrix, FloatMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (FloatComplexMatrix, FloatComplexMatrix);
+
+INSTANTIATE_MX_DIV_CONFORM (FloatMatrix, FloatMatrix);
+INSTANTIATE_MX_DIV_CONFORM (FloatMatrix, FloatComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (FloatComplexMatrix, FloatMatrix);
+INSTANTIATE_MX_DIV_CONFORM (FloatComplexMatrix, FloatComplexMatrix);
+
+// Right division functions.
+//
+//       op2 / op1:   m   cm
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+// -*- 1 -*-
+FloatMatrix
+xdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return FloatMatrix ();
+
+  FloatMatrix atmp = a.transpose ();
+  FloatMatrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+
+  FloatMatrix result 
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.transpose ();
+}
+
+// -*- 2 -*-
+FloatComplexMatrix
+xdiv (const FloatMatrix& a, const FloatComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return FloatComplexMatrix ();
+
+  FloatMatrix atmp = a.transpose ();
+  FloatComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+
+  FloatComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 3 -*-
+FloatComplexMatrix
+xdiv (const FloatComplexMatrix& a, const FloatMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return FloatComplexMatrix ();
+
+  FloatComplexMatrix atmp = a.hermitian ();
+  FloatMatrix btmp = b.transpose ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+
+  FloatComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// -*- 4 -*-
+FloatComplexMatrix
+xdiv (const FloatComplexMatrix& a, const FloatComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_div_conform (a, b))
+    return FloatComplexMatrix ();
+
+  FloatComplexMatrix atmp = a.hermitian ();
+  FloatComplexMatrix btmp = b.hermitian ();
+  MatrixType btyp = typ.transpose ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+
+  FloatComplexMatrix result
+    = btmp.solve (btyp, atmp, info, rcond, solve_singularity_warning);
+
+  typ = btyp.transpose ();
+  return result.hermitian ();
+}
+
+// Funny element by element division operations.
+//
+//       op2 \ op1:   s   cs
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+FloatMatrix
+x_el_div (float a, const FloatMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  FloatMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+x_el_div (float a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+x_el_div (const FloatComplex a, const FloatMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+FloatComplexMatrix
+x_el_div (const FloatComplex a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.columns ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = a / b (i, j);
+      }
+
+  return result;
+}
+
+// Funny element by element division operations.
+//
+//          op2 \ op1:   s   cs
+//               +--   +---+----+
+//   N-d array         | 1 |  3 |
+//                     +---+----+
+//   complex N-d array | 2 |  4 |
+//                     +---+----+
+
+FloatNDArray
+x_el_div (float a, const FloatNDArray& b)
+{
+  FloatNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+x_el_div (float a, const FloatComplexNDArray& b)
+{
+  FloatComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+x_el_div (const FloatComplex a, const FloatNDArray& b)
+{
+  FloatComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+FloatComplexNDArray
+x_el_div (const FloatComplex a, const FloatComplexNDArray& b)
+{
+  FloatComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+// Left division functions.
+//
+//       op2 \ op1:   m   cm
+//            +--   +---+----+
+//   matrix         | 1 |  3 |
+//                  +---+----+
+//   complex_matrix | 2 |  4 |
+//                  +---+----+
+
+// -*- 1 -*-
+FloatMatrix
+xleftdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return FloatMatrix ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 2 -*-
+FloatComplexMatrix
+xleftdiv (const FloatMatrix& a, const FloatComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return FloatComplexMatrix ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 3 -*-
+FloatComplexMatrix
+xleftdiv (const FloatComplexMatrix& a, const FloatMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return FloatComplexMatrix ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// -*- 4 -*-
+FloatComplexMatrix
+xleftdiv (const FloatComplexMatrix& a, const FloatComplexMatrix& b, MatrixType &typ)
+{
+  if (! mx_leftdiv_conform (a, b))
+    return FloatComplexMatrix ();
+
+  octave_idx_type info;
+  float rcond = 0.0;
+  return a.solve (typ, b, info, rcond, solve_singularity_warning);
+}
+
+// Diagonal matrix division.
+
+template <class MT, class DMT>
+MT
+mdm_div_impl (const MT& a, const DMT& d)
+{
+  if (! mx_div_conform (a, d))
+    return MT ();
+
+  octave_idx_type m = a.rows (), n = d.rows (), l = d.length ();
+  MT x (m, n);
+  typedef typename DMT::element_type S;
+  typedef typename MT::element_type T;
+  const T *aa = a.data ();
+  const S *dd = d.data ();
+  T *xx = x.fortran_vec ();
+
+  for (octave_idx_type j = 0; j < l; j++)
+    {
+      const S del = dd[j];
+      if (del != S ())
+        for (octave_idx_type i = 0; i < m; i++)
+          xx[i] = aa[i] / del;
+      else
+        for (octave_idx_type i = 0; i < m; i++)
+          xx[i] = T ();
+      aa += m; xx += m;
+    }
+
+  for (octave_idx_type i = l*m; i < n*m; i++)
+    xx[i] = T ();
+
+  return x;
+}
+
+// Right division functions.
+//
+//       op2 / op1:   dm  cdm
+//            +--   +---+----+
+//   matrix         | 1 |    |
+//                  +---+----+
+//   complex_matrix | 2 |  3 |
+//                  +---+----+
+
+// -*- 1 -*-
+Matrix
+xdiv (const Matrix& a, const DiagMatrix& b)
+{ return mdm_div_impl (a, b); }
+
+// -*- 2 -*-
+ComplexMatrix
+xdiv (const ComplexMatrix& a, const DiagMatrix& b)
+{ return mdm_div_impl (a, b); }
+
+// -*- 3 -*-
+ComplexMatrix
+xdiv (const ComplexMatrix& a, const ComplexDiagMatrix& b)
+{ return mdm_div_impl (a, b); }
+
+// Right division functions, float type.
+//
+//       op2 / op1:   dm  cdm
+//            +--   +---+----+
+//   matrix         | 1 |    |
+//                  +---+----+
+//   complex_matrix | 2 |  3 |
+//                  +---+----+
+
+// -*- 1 -*-
+FloatMatrix
+xdiv (const FloatMatrix& a, const FloatDiagMatrix& b)
+{ return mdm_div_impl (a, b); }
+
+// -*- 2 -*-
+FloatComplexMatrix
+xdiv (const FloatComplexMatrix& a, const FloatDiagMatrix& b)
+{ return mdm_div_impl (a, b); }
+
+// -*- 3 -*-
+FloatComplexMatrix
+xdiv (const FloatComplexMatrix& a, const FloatComplexDiagMatrix& b)
+{ return mdm_div_impl (a, b); }
+
+template <class MT, class DMT>
+MT
+dmm_leftdiv_impl (const DMT& d, const MT& a)
+{
+  if (! mx_leftdiv_conform (d, a))
+    return MT ();
+
+  octave_idx_type m = d.cols (), n = a.cols (), k = a.rows (), l = d.length ();
+  MT x (m, n);
+  typedef typename DMT::element_type S;
+  typedef typename MT::element_type T;
+  const T *aa = a.data ();
+  const S *dd = d.data ();
+  T *xx = x.fortran_vec ();
+
+  for (octave_idx_type j = 0; j < n; j++)
+    {
+      for (octave_idx_type i = 0; i < l; i++)
+        xx[i] = dd[i] != S () ? aa[i] / dd[i] : T ();
+      for (octave_idx_type i = l; i < m; i++)
+        xx[i] = T ();
+      aa += k; xx += m;
+    }
+
+  return x;
+}
+
+// Left division functions.
+//
+//       op2 \ op1:         m   cm
+//                        +---+----+
+//   diag_matrix          | 1 |  2 |
+//                        +---+----+
+//   complex_diag_matrix  |   |  3 |
+//                        +---+----+
+
+// -*- 1 -*-
+Matrix
+xleftdiv (const DiagMatrix& a, const Matrix& b)
+{ return dmm_leftdiv_impl (a, b); }
+
+// -*- 2 -*-
+ComplexMatrix
+xleftdiv (const DiagMatrix& a, const ComplexMatrix& b)
+{ return dmm_leftdiv_impl (a, b); }
+
+// -*- 3 -*-
+ComplexMatrix
+xleftdiv (const ComplexDiagMatrix& a, const ComplexMatrix& b)
+{ return dmm_leftdiv_impl (a, b); }
+
+// Left division functions, float type.
+//
+//       op2 \ op1:         m   cm
+//                        +---+----+
+//   diag_matrix          | 1 |  2 |
+//                        +---+----+
+//   complex_diag_matrix  |   |  3 |
+//                        +---+----+
+
+// -*- 1 -*-
+FloatMatrix
+xleftdiv (const FloatDiagMatrix& a, const FloatMatrix& b)
+{ return dmm_leftdiv_impl (a, b); }
+
+// -*- 2 -*-
+FloatComplexMatrix
+xleftdiv (const FloatDiagMatrix& a, const FloatComplexMatrix& b)
+{ return dmm_leftdiv_impl (a, b); }
+
+// -*- 3 -*-
+FloatComplexMatrix
+xleftdiv (const FloatComplexDiagMatrix& a, const FloatComplexMatrix& b)
+{ return dmm_leftdiv_impl (a, b); }
+
+// Diagonal by diagonal matrix division.
+
+template <class MT, class DMT>
+MT
+dmdm_div_impl (const MT& a, const DMT& d)
+{
+  if (! mx_div_conform (a, d))
+    return MT ();
+
+  octave_idx_type m = a.rows (), n = d.rows (), k = d.cols ();
+  octave_idx_type l = std::min (m, n), lk = std::min (l, k);
+  MT x (m, n);
+  typedef typename DMT::element_type S;
+  typedef typename MT::element_type T;
+  const T *aa = a.data ();
+  const S *dd = d.data ();
+  T *xx = x.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < lk; i++)
+    xx[i] = dd[i] != S () ? aa[i] / dd[i] : T ();
+  for (octave_idx_type i = lk; i < l; i++)
+    xx[i] = T ();
+
+  return x;
+}
+
+// Right division functions.
+//
+//       op2 / op1:        dm  cdm
+//            +--        +---+----+
+//   diag_matrix         | 1 |    |
+//                       +---+----+
+//   complex_diag_matrix | 2 |  3 |
+//                       +---+----+
+
+// -*- 1 -*-
+DiagMatrix
+xdiv (const DiagMatrix& a, const DiagMatrix& b)
+{ return dmdm_div_impl (a, b); }
+
+// -*- 2 -*-
+ComplexDiagMatrix
+xdiv (const ComplexDiagMatrix& a, const DiagMatrix& b)
+{ return dmdm_div_impl (a, b); }
+
+// -*- 3 -*-
+ComplexDiagMatrix
+xdiv (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b)
+{ return dmdm_div_impl (a, b); }
+
+// Right division functions, float type.
+//
+//       op2 / op1:        dm  cdm
+//            +--        +---+----+
+//   diag_matrix         | 1 |    |
+//                       +---+----+
+//   complex_diag_matrix | 2 |  3 |
+//                       +---+----+
+
+// -*- 1 -*-
+FloatDiagMatrix
+xdiv (const FloatDiagMatrix& a, const FloatDiagMatrix& b)
+{ return dmdm_div_impl (a, b); }
+
+// -*- 2 -*-
+FloatComplexDiagMatrix
+xdiv (const FloatComplexDiagMatrix& a, const FloatDiagMatrix& b)
+{ return dmdm_div_impl (a, b); }
+
+// -*- 3 -*-
+FloatComplexDiagMatrix
+xdiv (const FloatComplexDiagMatrix& a, const FloatComplexDiagMatrix& b)
+{ return dmdm_div_impl (a, b); }
+
+template <class MT, class DMT>
+MT
+dmdm_leftdiv_impl (const DMT& d, const MT& a)
+{
+  if (! mx_leftdiv_conform (d, a))
+    return MT ();
+
+  octave_idx_type m = d.cols (), n = a.cols (), k = d.rows ();
+  octave_idx_type l = std::min (m, n), lk = std::min (l, k);
+  MT x (m, n);
+  typedef typename DMT::element_type S;
+  typedef typename MT::element_type T;
+  const T *aa = a.data ();
+  const S *dd = d.data ();
+  T *xx = x.fortran_vec ();
+
+  for (octave_idx_type i = 0; i < lk; i++)
+    xx[i] = dd[i] != S () ? aa[i] / dd[i] : T ();
+  for (octave_idx_type i = lk; i < l; i++)
+    xx[i] = T ();
+
+  return x;
+}
+
+// Left division functions.
+//
+//       op2 \ op1:         dm  cdm
+//                        +---+----+
+//   diag_matrix          | 1 |  2 |
+//                        +---+----+
+//   complex_diag_matrix  |   |  3 |
+//                        +---+----+
+
+// -*- 1 -*-
+DiagMatrix
+xleftdiv (const DiagMatrix& a, const DiagMatrix& b)
+{ return dmdm_leftdiv_impl (a, b); }
+
+// -*- 2 -*-
+ComplexDiagMatrix
+xleftdiv (const DiagMatrix& a, const ComplexDiagMatrix& b)
+{ return dmdm_leftdiv_impl (a, b); }
+
+// -*- 3 -*-
+ComplexDiagMatrix
+xleftdiv (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b)
+{ return dmdm_leftdiv_impl (a, b); }
+
+// Left division functions, float type.
+//
+//       op2 \ op1:         dm  cdm
+//                        +---+----+
+//   diag_matrix          | 1 |  2 |
+//                        +---+----+
+//   complex_diag_matrix  |   |  3 |
+//                        +---+----+
+
+// -*- 1 -*-
+FloatDiagMatrix
+xleftdiv (const FloatDiagMatrix& a, const FloatDiagMatrix& b)
+{ return dmdm_leftdiv_impl (a, b); }
+
+// -*- 2 -*-
+FloatComplexDiagMatrix
+xleftdiv (const FloatDiagMatrix& a, const FloatComplexDiagMatrix& b)
+{ return dmdm_leftdiv_impl (a, b); }
+
+// -*- 3 -*-
+FloatComplexDiagMatrix
+xleftdiv (const FloatComplexDiagMatrix& a, const FloatComplexDiagMatrix& b)
+{ return dmdm_leftdiv_impl (a, b); }
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/xdiv.h b/src/xdiv.h
new file mode 100644
index 0000000..8943dd9
--- /dev/null
+++ b/src/xdiv.h
@@ -0,0 +1,151 @@
+/*
+
+Copyright (C) 2008 Jaroslav Hajek
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2003, 2005, 2006, 2007
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_xdiv_h)
+#define octave_xdiv_h 1
+
+#include "oct-cmplx.h"
+#include "MatrixType.h"
+
+class Matrix;
+class ComplexMatrix;
+
+class NDArray;
+class ComplexNDArray;
+
+extern Matrix xdiv (const Matrix& a, const Matrix& b, MatrixType &typ);
+extern ComplexMatrix xdiv (const Matrix& a, const ComplexMatrix& b,
+			   MatrixType &typ);
+extern ComplexMatrix xdiv (const ComplexMatrix& a, const Matrix& b,
+			   MatrixType &typ);
+extern ComplexMatrix xdiv (const ComplexMatrix& a, const ComplexMatrix& b,
+			   MatrixType &typ);
+
+extern Matrix x_el_div (double a, const Matrix& b);
+extern ComplexMatrix x_el_div (double a, const ComplexMatrix& b);
+extern ComplexMatrix x_el_div (const Complex a, const Matrix& b);
+extern ComplexMatrix x_el_div (const Complex a, const ComplexMatrix& b);
+
+extern NDArray x_el_div (double a, const NDArray& b);
+extern ComplexNDArray x_el_div (double a, const ComplexNDArray& b);
+extern ComplexNDArray x_el_div (const Complex a, const NDArray& b);
+extern ComplexNDArray x_el_div (const Complex a, const ComplexNDArray& b);
+
+extern Matrix xleftdiv (const Matrix& a, const Matrix& b, MatrixType &typ);
+extern ComplexMatrix xleftdiv (const Matrix& a, const ComplexMatrix& b,
+			       MatrixType &typ);
+extern ComplexMatrix xleftdiv (const ComplexMatrix& a, const Matrix& b,
+			       MatrixType &typ);
+extern ComplexMatrix xleftdiv (const ComplexMatrix& a, const ComplexMatrix& b,
+			       MatrixType &typ);
+
+class FloatMatrix;
+class FloatComplexMatrix;
+
+class FloatNDArray;
+class FloatComplexNDArray;
+
+extern FloatMatrix xdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType &typ);
+extern FloatComplexMatrix xdiv (const FloatMatrix& a, const FloatComplexMatrix& b,
+			   MatrixType &typ);
+extern FloatComplexMatrix xdiv (const FloatComplexMatrix& a, const FloatMatrix& b,
+			   MatrixType &typ);
+extern FloatComplexMatrix xdiv (const FloatComplexMatrix& a, const FloatComplexMatrix& b,
+			   MatrixType &typ);
+
+extern FloatMatrix x_el_div (float a, const FloatMatrix& b);
+extern FloatComplexMatrix x_el_div (float a, const FloatComplexMatrix& b);
+extern FloatComplexMatrix x_el_div (const FloatComplex a, const FloatMatrix& b);
+extern FloatComplexMatrix x_el_div (const FloatComplex a, const FloatComplexMatrix& b);
+
+extern FloatNDArray x_el_div (float a, const FloatNDArray& b);
+extern FloatComplexNDArray x_el_div (float a, const FloatComplexNDArray& b);
+extern FloatComplexNDArray x_el_div (const FloatComplex a, const FloatNDArray& b);
+extern FloatComplexNDArray x_el_div (const FloatComplex a, const FloatComplexNDArray& b);
+
+extern FloatMatrix xleftdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType &typ);
+extern FloatComplexMatrix xleftdiv (const FloatMatrix& a, const FloatComplexMatrix& b,
+			       MatrixType &typ);
+extern FloatComplexMatrix xleftdiv (const FloatComplexMatrix& a, const FloatMatrix& b,
+			       MatrixType &typ);
+extern FloatComplexMatrix xleftdiv (const FloatComplexMatrix& a, const FloatComplexMatrix& b,
+			       MatrixType &typ);
+
+
+class DiagMatrix;
+class FloatDiagMatrix;
+class ComplexDiagMatrix;
+class FloatComplexDiagMatrix;
+
+extern Matrix xdiv (const Matrix& a, const DiagMatrix& b);
+extern ComplexMatrix xdiv (const ComplexMatrix& a, const DiagMatrix& b);
+extern ComplexMatrix xdiv (const ComplexMatrix& a, const ComplexDiagMatrix& b);
+
+extern DiagMatrix xdiv (const DiagMatrix& a, const DiagMatrix& b);
+extern ComplexDiagMatrix xdiv (const ComplexDiagMatrix& a, const DiagMatrix& b);
+extern ComplexDiagMatrix xdiv (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b);
+
+extern FloatMatrix xdiv (const FloatMatrix& a, const FloatDiagMatrix& b);
+extern FloatComplexMatrix xdiv (const FloatComplexMatrix& a, 
+                                const FloatDiagMatrix& b); 
+extern FloatComplexMatrix xdiv (const FloatMatrix& a, 
+                                const FloatComplexDiagMatrix& b); 
+extern FloatComplexMatrix xdiv (const FloatComplexMatrix& a, 
+                                const FloatComplexDiagMatrix& b);
+
+extern FloatDiagMatrix xdiv (const FloatDiagMatrix& a, const FloatDiagMatrix& b);
+extern FloatComplexDiagMatrix xdiv (const FloatComplexDiagMatrix& a, 
+                                    const FloatDiagMatrix& b);
+extern FloatComplexDiagMatrix xdiv (const FloatComplexDiagMatrix& a, 
+                                    const FloatComplexDiagMatrix& b);
+
+extern Matrix xleftdiv (const DiagMatrix& a, const Matrix& b);
+extern ComplexMatrix xleftdiv (const DiagMatrix& a, const ComplexMatrix& b);
+extern ComplexMatrix xleftdiv (const ComplexDiagMatrix& a, const ComplexMatrix& b);
+
+extern DiagMatrix xleftdiv (const DiagMatrix& a, const DiagMatrix& b);
+extern ComplexDiagMatrix xleftdiv (const DiagMatrix& a, const ComplexDiagMatrix& b);
+extern ComplexDiagMatrix xleftdiv (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b);
+
+extern FloatMatrix xleftdiv (const FloatDiagMatrix& a, 
+                             const FloatMatrix& b);
+extern FloatComplexMatrix xleftdiv (const FloatDiagMatrix& a, 
+                                    const FloatComplexMatrix& b);
+extern FloatComplexMatrix xleftdiv (const FloatComplexDiagMatrix& a, 
+                                    const FloatComplexMatrix& b);
+
+extern FloatDiagMatrix xleftdiv (const FloatDiagMatrix& a, 
+                                 const FloatDiagMatrix& b);
+extern FloatComplexDiagMatrix xleftdiv (const FloatDiagMatrix& a, 
+                                        const FloatComplexDiagMatrix& b);
+extern FloatComplexDiagMatrix xleftdiv (const FloatComplexDiagMatrix& a, 
+                                        const FloatComplexDiagMatrix& b);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/xnorm.cc b/src/xnorm.cc
new file mode 100644
index 0000000..f5c6b0b
--- /dev/null
+++ b/src/xnorm.cc
@@ -0,0 +1,212 @@
+/*
+
+Copyright (C) 2008 VZLU Prague, a.s.
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// author: Jaroslav Hajek <highegg at gmail.com>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <cfloat>
+#include <cmath>
+
+#include "oct-norm.h"
+
+#include "error.h"
+#include "xnorm.h"
+#include "ov.h"
+#include "gripes.h"
+
+octave_value xnorm (const octave_value& x, const octave_value& p)
+{
+  octave_value retval;
+
+  bool isvector = (x.columns () == 1 || x.rows () == 1);
+  bool iscomplex = x.is_complex_type ();
+  bool issparse = x.is_sparse_type ();
+  bool isfloat = x.is_single_type ();
+
+  if (isfloat || x.is_double_type ())
+    {
+      if (isvector)
+        {
+          if (isfloat & iscomplex)
+            retval = xnorm (x.float_complex_column_vector_value (),
+                            p.float_value ());
+          else if (isfloat)
+            retval = xnorm (x.float_column_vector_value (),
+                            p.float_value ());
+          else if (iscomplex)
+            retval = xnorm (x.complex_column_vector_value (),
+                            p.double_value ());
+          else 
+            retval = xnorm (x.column_vector_value (),
+                            p.double_value ());
+        }
+      else if (issparse)
+        {
+          if (iscomplex)
+            retval = xnorm (x.sparse_complex_matrix_value (),
+                            p.double_value ());
+          else 
+            retval = xnorm (x.sparse_matrix_value (),
+                            p.double_value ());
+        }
+      else
+        {
+          if (isfloat & iscomplex)
+            retval = xnorm (x.float_complex_matrix_value (),
+                            p.float_value ());
+          else if (isfloat)
+            retval = xnorm (x.float_matrix_value (),
+                            p.float_value ());
+          else if (iscomplex)
+            retval = xnorm (x.complex_matrix_value (),
+                            p.double_value ());
+          else 
+            retval = xnorm (x.matrix_value (),
+                            p.double_value ());
+        }
+    }
+  else
+    gripe_wrong_type_arg ("xnorm", x, true);
+
+  return retval;
+}
+
+octave_value xcolnorms (const octave_value& x, const octave_value& p)
+{
+  octave_value retval;
+
+  bool iscomplex = x.is_complex_type ();
+  bool issparse = x.is_sparse_type ();
+  bool isfloat = x.is_single_type ();
+
+  if (isfloat || x.is_double_type ())
+    {
+      if (issparse)
+        {
+          if (iscomplex)
+            retval = xcolnorms (x.sparse_complex_matrix_value (),
+                                p.double_value ());
+          else 
+            retval = xcolnorms (x.sparse_matrix_value (),
+                                p.double_value ());
+        }
+      else
+        {
+          if (isfloat & iscomplex)
+            retval = xcolnorms (x.float_complex_matrix_value (),
+                                p.float_value ());
+          else if (isfloat)
+            retval = xcolnorms (x.float_matrix_value (),
+                                p.float_value ());
+          else if (iscomplex)
+            retval = xcolnorms (x.complex_matrix_value (),
+                                p.double_value ());
+          else 
+            retval = xcolnorms (x.matrix_value (),
+                                p.double_value ());
+        }
+    }
+  else
+    gripe_wrong_type_arg ("xcolnorms", x, true);
+
+  return retval;
+}
+
+octave_value xrownorms (const octave_value& x, const octave_value& p)
+{
+  octave_value retval;
+
+  bool iscomplex = x.is_complex_type ();
+  bool issparse = x.is_sparse_type ();
+  bool isfloat = x.is_single_type ();
+
+  if (isfloat || x.is_double_type ())
+    {
+      if (issparse)
+        {
+          if (iscomplex)
+            retval = xrownorms (x.sparse_complex_matrix_value (),
+                                p.double_value ());
+          else 
+            retval = xrownorms (x.sparse_matrix_value (),
+                                p.double_value ());
+        }
+      else
+        {
+          if (isfloat & iscomplex)
+            retval = xrownorms (x.float_complex_matrix_value (),
+                                p.float_value ());
+          else if (isfloat)
+            retval = xrownorms (x.float_matrix_value (),
+                                p.float_value ());
+          else if (iscomplex)
+            retval = xrownorms (x.complex_matrix_value (),
+                                p.double_value ());
+          else 
+            retval = xrownorms (x.matrix_value (),
+                                p.double_value ());
+        }
+    }
+  else
+    gripe_wrong_type_arg ("xrownorms", x, true);
+
+  return retval;
+}
+
+octave_value xfrobnorm (const octave_value& x)
+{
+  octave_value retval;
+
+  bool iscomplex = x.is_complex_type ();
+  bool issparse = x.is_sparse_type ();
+  bool isfloat = x.is_single_type ();
+
+  if (isfloat || x.is_double_type ())
+    {
+      if (issparse)
+        {
+          if (iscomplex)
+            retval = xfrobnorm (x.sparse_complex_matrix_value ());
+          else 
+            retval = xfrobnorm (x.sparse_matrix_value ());
+        }
+      else
+        {
+          if (isfloat & iscomplex)
+            retval = xfrobnorm (x.float_complex_matrix_value ());
+          else if (isfloat)
+            retval = xfrobnorm (x.float_matrix_value ());
+          else if (iscomplex)
+            retval = xfrobnorm (x.complex_matrix_value ());
+          else 
+            retval = xfrobnorm (x.matrix_value ());
+        }
+    }
+  else
+    gripe_wrong_type_arg ("xfrobnorm", x, true);
+
+  return retval;
+}
diff --git a/src/xnorm.h b/src/xnorm.h
new file mode 100644
index 0000000..0a60872
--- /dev/null
+++ b/src/xnorm.h
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2008 VZLU Prague, a.s.
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// author: Jaroslav Hajek <highegg at gmail.com>
+
+#if !defined (octave_xnorm_h)
+#define octave_xnorm_h 1
+
+class octave_value;
+
+extern octave_value xnorm (const octave_value& x, const octave_value& p);
+extern octave_value xcolnorms (const octave_value& x, const octave_value& p);
+extern octave_value xrownorms (const octave_value& x, const octave_value& p);
+extern octave_value xfrobnorm (const octave_value& x);
+
+#endif
diff --git a/src/xpow.cc b/src/xpow.cc
new file mode 100644
index 0000000..81e418b
--- /dev/null
+++ b/src/xpow.cc
@@ -0,0 +1,2787 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003,
+              2004, 2005, 2006, 2007, 2008 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cassert>
+#include <climits>
+
+#include "Array-util.h"
+#include "CColVector.h"
+#include "CDiagMatrix.h"
+#include "fCDiagMatrix.h"
+#include "CMatrix.h"
+#include "EIG.h"
+#include "fEIG.h"
+#include "dDiagMatrix.h"
+#include "fDiagMatrix.h"
+#include "dMatrix.h"
+#include "PermMatrix.h"
+#include "mx-cm-cdm.h"
+#include "oct-cmplx.h"
+#include "Range.h"
+#include "quit.h"
+
+#include "error.h"
+#include "oct-obj.h"
+#include "utils.h"
+#include "xpow.h"
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+static inline int
+xisint (double x)
+{
+  return (D_NINT (x) == x
+	  && ((x >= 0 && x < INT_MAX)
+	      || (x <= 0 && x > INT_MIN)));
+}
+
+// Safer pow functions.
+//
+//       op2 \ op1:   s   m   cs   cm
+//            +--   +---+---+----+----+
+//   scalar   |     | 1 | 5 |  7 | 11 |
+//                  +---+---+----+----+
+//   matrix         | 2 | * |  8 |  * |
+//                  +---+---+----+----+
+//   complex_scalar | 3 | 6 |  9 | 12 |
+//                  +---+---+----+----+
+//   complex_matrix | 4 | * | 10 |  * |
+//                  +---+---+----+----+
+
+// -*- 1 -*-
+octave_value
+xpow (double a, double b)
+{
+  double retval;
+
+  if (a < 0.0 && ! xisint (b))
+    {
+      Complex atmp (a);
+
+      return std::pow (atmp, b);
+    }
+  else
+    retval = std::pow (a, b);
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+xpow (double a, const Matrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      EIG b_eig (b);
+
+      if (! error_state)
+	{
+	  ComplexColumnVector lambda (b_eig.eigenvalues ());
+	  ComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      Complex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  ComplexDiagMatrix D (lambda);
+
+	  retval = ComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 3 -*-
+octave_value
+xpow (double a, const Complex& b)
+{
+  Complex result;
+  Complex atmp (a);
+  result = std::pow (atmp, b);
+  return result;
+}
+
+// -*- 4 -*-
+octave_value
+xpow (double a, const ComplexMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      EIG b_eig (b);
+
+      if (! error_state)
+	{
+	  ComplexColumnVector lambda (b_eig.eigenvalues ());
+	  ComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      Complex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  ComplexDiagMatrix D (lambda);
+
+	  retval = ComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+xpow (const Matrix& a, double b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+	  int btmp = static_cast<int> (b);
+	  if (btmp == 0)
+	    {
+	      retval = DiagMatrix (nr, nr, 1.0);
+	    }
+	  else
+	    {
+	      // Too much copying?
+	      // FIXME -- we shouldn't do this if the exponent is
+	      // large...
+
+	      Matrix atmp;
+	      if (btmp < 0)
+		{
+		  btmp = -btmp;
+
+		  octave_idx_type info;
+		  double rcond = 0.0;
+		  MatrixType mattype (a);
+
+		  atmp = a.inverse (mattype, info, rcond, 1);
+
+		  if (info == -1)
+		    warning ("inverse: matrix singular to machine\
+ precision, rcond = %g", rcond);
+		}
+	      else
+		atmp = a;
+
+	      Matrix result (atmp);
+
+	      btmp--;
+
+	      while (btmp > 0)
+		{
+		  if (btmp & 1)
+		    result = result * atmp;
+
+		  btmp >>= 1;
+
+		  if (btmp > 0)
+		    atmp = atmp * atmp;
+		}
+
+	      retval = result;
+	    }
+	}
+      else
+	{
+	  EIG a_eig (a);
+
+	  if (! error_state)
+	    {
+	      ComplexColumnVector lambda (a_eig.eigenvalues ());
+	      ComplexMatrix Q (a_eig.eigenvectors ());
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		lambda(i) = std::pow (lambda(i), b);
+
+	      ComplexDiagMatrix D (lambda);
+
+	      retval = ComplexMatrix (Q * D * Q.inverse ());
+	    }
+	  else
+	    error ("xpow: matrix diagonalization failed");
+	}
+    }
+
+  return retval;
+}
+
+// -*- 5d -*-
+octave_value
+xpow (const DiagMatrix& a, double b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+          DiagMatrix r (nr, nc);
+          for (octave_idx_type i = 0; i < nc; i++)
+            r(i, i) = std::pow (a(i, i), b);
+          retval = r;
+        }
+      else
+	{
+          ComplexDiagMatrix r (nr, nc);
+          for (octave_idx_type i = 0; i < nc; i++)
+            r(i, i) = std::pow (static_cast<Complex> (a(i, i)), b);
+          retval = r;
+	}
+    }
+
+  return retval;
+}
+
+// -*- 5p -*-
+octave_value
+xpow (const PermMatrix& a, double b)
+{
+  octave_value retval;
+  int btmp = static_cast<int> (b);
+  if (btmp == b)
+    return a.power (btmp);
+  else
+    return xpow (Matrix (a), b);
+}
+
+// -*- 6 -*-
+octave_value
+xpow (const Matrix& a, const Complex& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      EIG a_eig (a);
+
+      if (! error_state)
+	{
+	  ComplexColumnVector lambda (a_eig.eigenvalues ());
+	  ComplexMatrix Q (a_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    lambda(i) = std::pow (lambda(i), b);
+
+	  ComplexDiagMatrix D (lambda);
+
+	  retval = ComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 7 -*-
+octave_value
+xpow (const Complex& a, double b)
+{
+  Complex result;
+
+  if (xisint (b))
+    result = std::pow (a, static_cast<int> (b));
+  else
+    result = std::pow (a, b);
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+xpow (const Complex& a, const Matrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      EIG b_eig (b);
+
+      if (! error_state)
+	{
+	  ComplexColumnVector lambda (b_eig.eigenvalues ());
+	  ComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      Complex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  ComplexDiagMatrix D (lambda);
+
+	  retval = ComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 9 -*-
+octave_value
+xpow (const Complex& a, const Complex& b)
+{
+  Complex result;
+  result = std::pow (a, b);
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+xpow (const Complex& a, const ComplexMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      EIG b_eig (b);
+
+      if (! error_state)
+	{
+	  ComplexColumnVector lambda (b_eig.eigenvalues ());
+	  ComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      Complex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  ComplexDiagMatrix D (lambda);
+
+	  retval = ComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 11 -*-
+octave_value
+xpow (const ComplexMatrix& a, double b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+	  int btmp = static_cast<int> (b);
+	  if (btmp == 0)
+	    {
+	      retval = DiagMatrix (nr, nr, 1.0);
+	    }
+	  else
+	    {
+	      // Too much copying?
+	      // FIXME -- we shouldn't do this if the exponent is
+	      // large...
+
+	      ComplexMatrix atmp;
+	      if (btmp < 0)
+		{
+		  btmp = -btmp;
+
+		  octave_idx_type info;
+		  double rcond = 0.0;
+		  MatrixType mattype (a);
+
+		  atmp = a.inverse (mattype, info, rcond, 1);
+
+		  if (info == -1)
+		    warning ("inverse: matrix singular to machine\
+ precision, rcond = %g", rcond);
+		}
+	      else
+		atmp = a;
+
+	      ComplexMatrix result (atmp);
+
+	      btmp--;
+
+	      while (btmp > 0)
+		{
+		  if (btmp & 1)
+		    result = result * atmp;
+
+		  btmp >>= 1;
+
+		  if (btmp > 0)
+		    atmp = atmp * atmp;
+		}
+
+	      retval = result;
+	    }
+	}
+      else
+	{
+	  EIG a_eig (a);
+
+	  if (! error_state)
+	    {
+	      ComplexColumnVector lambda (a_eig.eigenvalues ());
+	      ComplexMatrix Q (a_eig.eigenvectors ());
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		lambda(i) = std::pow (lambda(i), b);
+
+	      ComplexDiagMatrix D (lambda);
+
+	      retval = ComplexMatrix (Q * D * Q.inverse ());
+	    }
+	  else
+	    error ("xpow: matrix diagonalization failed");
+	}
+    }
+
+  return retval;
+}
+
+// -*- 12 -*-
+octave_value
+xpow (const ComplexMatrix& a, const Complex& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      EIG a_eig (a);
+
+      if (! error_state)
+	{
+	  ComplexColumnVector lambda (a_eig.eigenvalues ());
+	  ComplexMatrix Q (a_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    lambda(i) = std::pow (lambda(i), b);
+
+	  ComplexDiagMatrix D (lambda);
+
+	  retval = ComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 12d -*-
+octave_value
+xpow (const ComplexDiagMatrix& a, const Complex& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      ComplexDiagMatrix r (nr, nc);
+      for (octave_idx_type i = 0; i < nc; i++)
+        r(i, i) = std::pow (a(i, i), b);
+      retval = r;
+    }
+
+  return retval;
+}
+
+// mixed
+octave_value
+xpow (const ComplexDiagMatrix& a, double b)
+{
+  return xpow (a, static_cast<Complex> (b));
+}
+
+octave_value
+xpow (const DiagMatrix& a, const Complex& b)
+{
+  return xpow (ComplexDiagMatrix (a), b);
+}
+
+
+// Safer pow functions that work elementwise for matrices.
+//
+//       op2 \ op1:   s   m   cs   cm
+//            +--   +---+---+----+----+
+//   scalar   |     | * | 3 |  * |  9 |
+//                  +---+---+----+----+
+//   matrix         | 1 | 4 |  7 | 10 |
+//                  +---+---+----+----+
+//   complex_scalar | * | 5 |  * | 11 |
+//                  +---+---+----+----+
+//   complex_matrix | 2 | 6 |  8 | 12 |
+//                  +---+---+----+----+
+//
+//   * -> not needed.
+
+// FIXME -- these functions need to be fixed so that things
+// like
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
+//
+// and
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
+//
+// produce identical results.  Also, it would be nice if -1^0.5
+// produced a pure imaginary result instead of a complex number with a
+// small real part.  But perhaps that's really a problem with the math
+// library...
+
+// -*- 1 -*-
+octave_value
+elem_xpow (double a, const Matrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  double d1, d2;
+
+  if (a < 0.0 && ! b.all_integers (d1, d2))
+    {
+      Complex atmp (a);
+      ComplexMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (atmp, b (i, j));
+	  }
+
+      retval = result;
+    }
+  else
+    {
+      Matrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a, b (i, j));
+	  }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+elem_xpow (double a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc);
+  Complex atmp (a);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (atmp, b (i, j));
+      }
+
+  return result;
+}
+
+static inline bool 
+same_sign (double a, double b)
+{
+  return (a >= 0 && b >= 0) || (a <= 0 && b <= 0);
+}
+
+octave_value
+elem_xpow (double a, const Range& r)
+{
+  octave_value retval;
+
+  // Only optimize powers with ranges that are integer and monotonic in
+  // magnitude.
+  if (r.nelem () > 1 && r.all_elements_are_ints ()
+      && same_sign (r.base (), r.limit ()))
+    {
+      octave_idx_type n = r.nelem ();
+      Matrix result (1, n);
+      if (same_sign (r.base (), r.inc ()))
+        {
+          double base = std::pow (a, r.base ());
+          double inc = std::pow (a, r.inc ());
+          result(0) = base;
+          for (octave_idx_type i = 1; i < n; i++)
+            result(i) = (base *= inc);
+        }
+      else
+        {
+          // Don't use Range::limit () here.
+          double limit = std::pow (a, r.base () + (n-1) * r.inc ());
+          double inc = std::pow (a, -r.inc ());
+          result(n-1) = limit;
+          for (octave_idx_type i = n-2; i >= 0; i--)
+            result(i) = (limit *= inc);
+        }
+
+      retval = result;
+    }  
+  else
+    retval = elem_xpow (a, r.matrix_value ());
+
+  return retval;
+}
+
+// -*- 3 -*-
+octave_value
+elem_xpow (const Matrix& a, double b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (! xisint (b) && a.any_element_is_negative ())
+    {
+      ComplexMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT; 
+      
+	    Complex atmp (a (i, j));
+
+	    result (i, j) = std::pow (atmp, b);
+	  }
+
+      retval = result;
+    }
+  else
+    {
+      Matrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), b);
+	  }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 4 -*-
+octave_value
+elem_xpow (const Matrix& a, const Matrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  int convert_to_complex = 0;
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	double atmp = a (i, j);
+	double btmp = b (i, j);
+	if (atmp < 0.0 && static_cast<int> (btmp) != btmp)
+	  {
+	    convert_to_complex = 1;
+	    goto done;
+	  }
+      }
+
+done:
+
+  if (convert_to_complex)
+    {
+      ComplexMatrix complex_result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    Complex atmp (a (i, j));
+	    Complex btmp (b (i, j));
+	    complex_result (i, j) = std::pow (atmp, btmp);
+	  }
+
+      retval = complex_result;
+    }
+  else
+    {
+      Matrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), b (i, j));
+	  }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+elem_xpow (const Matrix& a, const Complex& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (Complex (a (i, j)), b);
+      }
+
+  return result;
+}
+
+// -*- 6 -*-
+octave_value
+elem_xpow (const Matrix& a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (Complex (a (i, j)), b (i, j));
+      }
+
+  return result;
+}
+
+// -*- 7 -*-
+octave_value
+elem_xpow (const Complex& a, const Matrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	double btmp = b (i, j);
+	if (xisint (btmp))
+	  result (i, j) = std::pow (a, static_cast<int> (btmp));
+	else
+	  result (i, j) = std::pow (a, btmp);
+      }
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+elem_xpow (const Complex& a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a, b (i, j));
+      }
+
+  return result;
+}
+
+octave_value
+elem_xpow (const Complex& a, const Range& r)
+{
+  octave_value retval;
+
+  // Only optimize powers with ranges that are integer and monotonic in
+  // magnitude.
+  if (r.nelem () > 1 && r.all_elements_are_ints ()
+      && same_sign (r.base (), r.limit ()))
+    {
+      octave_idx_type n = r.nelem ();
+      ComplexMatrix result (1, n);
+
+      if (same_sign (r.base (), r.inc ()))
+        {
+          Complex base = std::pow (a, r.base ());
+          Complex inc = std::pow (a, r.inc ());
+          result(0) = base;
+          for (octave_idx_type i = 1; i < n; i++)
+            result(i) = (base *= inc);
+        }
+      else
+        {
+          // Don't use Range::limit () here.
+          Complex limit = std::pow (a, r.base () + (n-1) * r.inc ());
+          Complex inc = std::pow (a, -r.inc ());
+          result(n-1) = limit;
+          for (octave_idx_type i = n-2; i >= 0; i--)
+            result(i) = (limit *= inc);
+        }
+
+      retval = result;
+    }  
+  else
+    retval = elem_xpow (a, r.matrix_value ());
+
+
+  return retval;
+}
+
+// -*- 9 -*-
+octave_value
+elem_xpow (const ComplexMatrix& a, double b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  ComplexMatrix result (nr, nc);
+
+  if (xisint (b))
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), static_cast<int> (b));
+	  }
+    }
+  else
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), b);
+	  }
+    }
+
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+elem_xpow (const ComplexMatrix& a, const Matrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	double btmp = b (i, j);
+	if (xisint (btmp))
+	  result (i, j) = std::pow (a (i, j), static_cast<int> (btmp));
+	else
+	  result (i, j) = std::pow (a (i, j), btmp);
+      }
+
+  return result;
+}
+
+// -*- 11 -*-
+octave_value
+elem_xpow (const ComplexMatrix& a, const Complex& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a (i, j), b);
+      }
+
+  return result;
+}
+
+// -*- 12 -*-
+octave_value
+elem_xpow (const ComplexMatrix& a, const ComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  ComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a (i, j), b (i, j));
+      }
+
+  return result;
+}
+
+// Safer pow functions that work elementwise for N-d arrays.
+//
+//       op2 \ op1:   s   nd  cs   cnd
+//            +--   +---+---+----+----+
+//   scalar   |     | * | 3 |  * |  9 |
+//                  +---+---+----+----+
+//   N_d            | 1 | 4 |  7 | 10 |
+//                  +---+---+----+----+
+//   complex_scalar | * | 5 |  * | 11 |
+//                  +---+---+----+----+
+//   complex_N_d    | 2 | 6 |  8 | 12 |
+//                  +---+---+----+----+
+//
+//   * -> not needed.
+
+// FIXME -- these functions need to be fixed so that things
+// like
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
+//
+// and
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
+//
+// produce identical results.  Also, it would be nice if -1^0.5
+// produced a pure imaginary result instead of a complex number with a
+// small real part.  But perhaps that's really a problem with the math
+// library...
+
+// -*- 1 -*-
+octave_value
+elem_xpow (double a, const NDArray& b)
+{
+  octave_value retval;
+
+  double d1, d2;
+
+  if (a < 0.0 && ! b.all_integers (d1, d2))
+    {
+      Complex atmp (a);
+      ComplexNDArray result (b.dims ());
+      for (octave_idx_type i = 0; i < b.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = std::pow (atmp, b(i));
+	}
+
+      retval = result;
+    }
+  else
+    {
+      NDArray result (b.dims ());
+      for (octave_idx_type i = 0; i < b.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result (i) = std::pow (a, b(i));
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+elem_xpow (double a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+  Complex atmp (a);
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (atmp, b(i));
+    }
+
+  return result;
+}
+
+// -*- 3 -*-
+octave_value
+elem_xpow (const NDArray& a, double b)
+{
+  octave_value retval;
+
+  if (! xisint (b))
+    {
+      if (a.any_element_is_negative ())
+        {
+          ComplexNDArray result (a.dims ());
+
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+
+              Complex atmp (a (i));
+
+              result(i) = std::pow (atmp, b);
+            }
+
+          retval = result;
+        }
+      else
+        {
+          NDArray result (a.dims ());
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+              result(i) = std::pow (a(i), b);
+            }
+
+          retval = result;
+        }
+    }
+  else
+    {
+      NDArray result (a.dims ());
+
+      int ib = static_cast<int> (b);
+      if (ib == 2)
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            result.xelem (i) = a(i) * a(i);
+        }
+      else if (ib == -1)
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            result.xelem (i) = 1.0 / a(i);
+        }
+      else
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+              result(i) = std::pow (a(i), ib);
+            }
+        }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 4 -*-
+octave_value
+elem_xpow (const NDArray& a, const NDArray& b)
+{
+  octave_value retval;
+
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  int len = a.length ();
+
+  bool convert_to_complex = false;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+      double atmp = a(i);
+      double btmp = b(i);
+      if (atmp < 0.0 && static_cast<int> (btmp) != btmp)
+	{
+	  convert_to_complex = true;
+	  goto done;
+	}
+    }
+
+done:
+
+  if (convert_to_complex)
+    {
+      ComplexNDArray complex_result (a_dims);
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  OCTAVE_QUIT;
+	  Complex atmp (a(i));
+	  Complex btmp (b(i));
+	  complex_result(i) = std::pow (atmp, btmp);
+	}
+
+      retval = complex_result;
+    }
+  else
+    {
+      NDArray result (a_dims);
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = std::pow (a(i), b(i));
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+elem_xpow (const NDArray& a, const Complex& b)
+{
+  ComplexNDArray result (a.dims ());
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (Complex (a(i)), b);
+    }
+
+  return result;
+}
+
+// -*- 6 -*-
+octave_value
+elem_xpow (const NDArray& a, const ComplexNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  ComplexNDArray result (a_dims);
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (Complex (a(i)), b(i));
+    }
+
+  return result;
+}
+
+// -*- 7 -*-
+octave_value
+elem_xpow (const Complex& a, const NDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      double btmp = b(i);
+      if (xisint (btmp))
+	result(i) = std::pow (a, static_cast<int> (btmp));
+      else
+	result(i) = std::pow (a, btmp);
+    }
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+elem_xpow (const Complex& a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (a, b(i));
+    }
+
+  return result;
+}
+
+// -*- 9 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, double b)
+{
+  ComplexNDArray result (a.dims ());
+
+  if (xisint (b))
+    {
+      if (b == -1)
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            result.xelem (i) = std::conj (a(i)) / std::norm (a(i));
+        }
+      else
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+              result(i) = std::pow (a(i), static_cast<int> (b));
+            }
+        }
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < a.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = std::pow (a(i), b);
+	}
+    }
+
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, const NDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  ComplexNDArray result (a_dims);
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      double btmp = b(i);
+      if (xisint (btmp))
+	result(i) = std::pow (a(i), static_cast<int> (btmp));
+      else
+	result(i) = std::pow (a(i), btmp);
+    }
+
+  return result;
+}
+
+// -*- 11 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, const Complex& b)
+{
+  ComplexNDArray result (a.dims ());
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (a(i), b);
+    }
+
+  return result;
+}
+
+// -*- 12 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, const ComplexNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  ComplexNDArray result (a_dims);
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (a(i), b(i));
+    }
+
+  return result;
+}
+
+static inline int
+xisint (float x)
+{
+  return (D_NINT (x) == x
+	  && ((x >= 0 && x < INT_MAX)
+	      || (x <= 0 && x > INT_MIN)));
+}
+
+// Safer pow functions.
+//
+//       op2 \ op1:   s   m   cs   cm
+//            +--   +---+---+----+----+
+//   scalar   |     | 1 | 5 |  7 | 11 |
+//                  +---+---+----+----+
+//   matrix         | 2 | * |  8 |  * |
+//                  +---+---+----+----+
+//   complex_scalar | 3 | 6 |  9 | 12 |
+//                  +---+---+----+----+
+//   complex_matrix | 4 | * | 10 |  * |
+//                  +---+---+----+----+
+
+// -*- 1 -*-
+octave_value
+xpow (float a, float b)
+{
+  float retval;
+
+  if (a < 0.0 && ! xisint (b))
+    {
+      FloatComplex atmp (a);
+
+      return std::pow (atmp, b);
+    }
+  else
+    retval = std::pow (a, b);
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+xpow (float a, const FloatMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      FloatEIG b_eig (b);
+
+      if (! error_state)
+	{
+	  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
+	  FloatComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      FloatComplex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  FloatComplexDiagMatrix D (lambda);
+
+	  retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 3 -*-
+octave_value
+xpow (float a, const FloatComplex& b)
+{
+  FloatComplex result;
+  FloatComplex atmp (a);
+  result = std::pow (atmp, b);
+  return result;
+}
+
+// -*- 4 -*-
+octave_value
+xpow (float a, const FloatComplexMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      FloatEIG b_eig (b);
+
+      if (! error_state)
+	{
+	  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
+	  FloatComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      FloatComplex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  FloatComplexDiagMatrix D (lambda);
+
+	  retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+xpow (const FloatMatrix& a, float b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+	  int btmp = static_cast<int> (b);
+	  if (btmp == 0)
+	    {
+	      retval = FloatDiagMatrix (nr, nr, 1.0);
+	    }
+	  else
+	    {
+	      // Too much copying?
+	      // FIXME -- we shouldn't do this if the exponent is
+	      // large...
+
+	      FloatMatrix atmp;
+	      if (btmp < 0)
+		{
+		  btmp = -btmp;
+
+		  octave_idx_type info;
+		  float rcond = 0.0;
+		  MatrixType mattype (a);
+
+		  atmp = a.inverse (mattype, info, rcond, 1);
+
+		  if (info == -1)
+		    warning ("inverse: matrix singular to machine\
+ precision, rcond = %g", rcond);
+		}
+	      else
+		atmp = a;
+
+	      FloatMatrix result (atmp);
+
+	      btmp--;
+
+	      while (btmp > 0)
+		{
+		  if (btmp & 1)
+		    result = result * atmp;
+
+		  btmp >>= 1;
+
+		  if (btmp > 0)
+		    atmp = atmp * atmp;
+		}
+
+	      retval = result;
+	    }
+	}
+      else
+	{
+	  FloatEIG a_eig (a);
+
+	  if (! error_state)
+	    {
+	      FloatComplexColumnVector lambda (a_eig.eigenvalues ());
+	      FloatComplexMatrix Q (a_eig.eigenvectors ());
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		lambda(i) = std::pow (lambda(i), b);
+
+	      FloatComplexDiagMatrix D (lambda);
+
+	      retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	    }
+	  else
+	    error ("xpow: matrix diagonalization failed");
+	}
+    }
+
+  return retval;
+}
+
+// -*- 5d -*-
+octave_value
+xpow (const FloatDiagMatrix& a, float b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+          FloatDiagMatrix r (nr, nc);
+          for (octave_idx_type i = 0; i < nc; i++)
+            r(i, i) = std::pow (a(i, i), b);
+          retval = r;
+        }
+      else
+	{
+          FloatComplexDiagMatrix r (nr, nc);
+          for (octave_idx_type i = 0; i < nc; i++)
+            r(i, i) = std::pow (static_cast<FloatComplex> (a(i, i)), b);
+          retval = r;
+	}
+    }
+
+  return retval;
+}
+
+// -*- 6 -*-
+octave_value
+xpow (const FloatMatrix& a, const FloatComplex& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      FloatEIG a_eig (a);
+
+      if (! error_state)
+	{
+	  FloatComplexColumnVector lambda (a_eig.eigenvalues ());
+	  FloatComplexMatrix Q (a_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    lambda(i) = std::pow (lambda(i), b);
+
+	  FloatComplexDiagMatrix D (lambda);
+
+	  retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 7 -*-
+octave_value
+xpow (const FloatComplex& a, float b)
+{
+  FloatComplex result;
+
+  if (xisint (b))
+    result = std::pow (a, static_cast<int> (b));
+  else
+    result = std::pow (a, b);
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+xpow (const FloatComplex& a, const FloatMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      FloatEIG b_eig (b);
+
+      if (! error_state)
+	{
+	  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
+	  FloatComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      FloatComplex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  FloatComplexDiagMatrix D (lambda);
+
+	  retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 9 -*-
+octave_value
+xpow (const FloatComplex& a, const FloatComplex& b)
+{
+  FloatComplex result;
+  result = std::pow (a, b);
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+xpow (const FloatComplex& a, const FloatComplexMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for x^A, A must be square");
+  else
+    {
+      FloatEIG b_eig (b);
+
+      if (! error_state)
+	{
+	  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
+	  FloatComplexMatrix Q (b_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    {
+	      FloatComplex elt = lambda(i);
+	      if (std::imag (elt) == 0.0)
+		lambda(i) = std::pow (a, std::real (elt));
+	      else
+		lambda(i) = std::pow (a, elt);
+	    }
+	  FloatComplexDiagMatrix D (lambda);
+
+	  retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 11 -*-
+octave_value
+xpow (const FloatComplexMatrix& a, float b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      if (static_cast<int> (b) == b)
+	{
+	  int btmp = static_cast<int> (b);
+	  if (btmp == 0)
+	    {
+	      retval = FloatDiagMatrix (nr, nr, 1.0);
+	    }
+	  else
+	    {
+	      // Too much copying?
+	      // FIXME -- we shouldn't do this if the exponent is
+	      // large...
+
+	      FloatComplexMatrix atmp;
+	      if (btmp < 0)
+		{
+		  btmp = -btmp;
+
+		  octave_idx_type info;
+		  float rcond = 0.0;
+		  MatrixType mattype (a);
+
+		  atmp = a.inverse (mattype, info, rcond, 1);
+
+		  if (info == -1)
+		    warning ("inverse: matrix singular to machine\
+ precision, rcond = %g", rcond);
+		}
+	      else
+		atmp = a;
+
+	      FloatComplexMatrix result (atmp);
+
+	      btmp--;
+
+	      while (btmp > 0)
+		{
+		  if (btmp & 1)
+		    result = result * atmp;
+
+		  btmp >>= 1;
+
+		  if (btmp > 0)
+		    atmp = atmp * atmp;
+		}
+
+	      retval = result;
+	    }
+	}
+      else
+	{
+	  FloatEIG a_eig (a);
+
+	  if (! error_state)
+	    {
+	      FloatComplexColumnVector lambda (a_eig.eigenvalues ());
+	      FloatComplexMatrix Q (a_eig.eigenvectors ());
+
+	      for (octave_idx_type i = 0; i < nr; i++)
+		lambda(i) = std::pow (lambda(i), b);
+
+	      FloatComplexDiagMatrix D (lambda);
+
+	      retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	    }
+	  else
+	    error ("xpow: matrix diagonalization failed");
+	}
+    }
+
+  return retval;
+}
+
+// -*- 12 -*-
+octave_value
+xpow (const FloatComplexMatrix& a, const FloatComplex& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      FloatEIG a_eig (a);
+
+      if (! error_state)
+	{
+	  FloatComplexColumnVector lambda (a_eig.eigenvalues ());
+	  FloatComplexMatrix Q (a_eig.eigenvectors ());
+
+	  for (octave_idx_type i = 0; i < nr; i++)
+	    lambda(i) = std::pow (lambda(i), b);
+
+	  FloatComplexDiagMatrix D (lambda);
+
+	  retval = FloatComplexMatrix (Q * D * Q.inverse ());
+	}
+      else
+	error ("xpow: matrix diagonalization failed");
+    }
+
+  return retval;
+}
+
+// -*- 12d -*-
+octave_value
+xpow (const FloatComplexDiagMatrix& a, const FloatComplex& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (nr == 0 || nc == 0 || nr != nc)
+    error ("for A^b, A must be square");
+  else
+    {
+      FloatComplexDiagMatrix r (nr, nc);
+      for (octave_idx_type i = 0; i < nc; i++)
+        r(i, i) = std::pow (a(i, i), b);
+      retval = r;
+    }
+
+  return retval;
+}
+
+// mixed
+octave_value
+xpow (const FloatComplexDiagMatrix& a, float b)
+{
+  return xpow (a, static_cast<FloatComplex> (b));
+}
+
+octave_value
+xpow (const FloatDiagMatrix& a, const FloatComplex& b)
+{
+  return xpow (FloatComplexDiagMatrix (a), b);
+}
+
+// Safer pow functions that work elementwise for matrices.
+//
+//       op2 \ op1:   s   m   cs   cm
+//            +--   +---+---+----+----+
+//   scalar   |     | * | 3 |  * |  9 |
+//                  +---+---+----+----+
+//   matrix         | 1 | 4 |  7 | 10 |
+//                  +---+---+----+----+
+//   complex_scalar | * | 5 |  * | 11 |
+//                  +---+---+----+----+
+//   complex_matrix | 2 | 6 |  8 | 12 |
+//                  +---+---+----+----+
+//
+//   * -> not needed.
+
+// FIXME -- these functions need to be fixed so that things
+// like
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
+//
+// and
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
+//
+// produce identical results.  Also, it would be nice if -1^0.5
+// produced a pure imaginary result instead of a complex number with a
+// small real part.  But perhaps that's really a problem with the math
+// library...
+
+// -*- 1 -*-
+octave_value
+elem_xpow (float a, const FloatMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  float d1, d2;
+
+  if (a < 0.0 && ! b.all_integers (d1, d2))
+    {
+      FloatComplex atmp (a);
+      FloatComplexMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (atmp, b (i, j));
+	  }
+
+      retval = result;
+    }
+  else
+    {
+      FloatMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a, b (i, j));
+	  }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+elem_xpow (float a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  FloatComplexMatrix result (nr, nc);
+  FloatComplex atmp (a);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (atmp, b (i, j));
+      }
+
+  return result;
+}
+
+// -*- 3 -*-
+octave_value
+elem_xpow (const FloatMatrix& a, float b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  if (! xisint (b) && a.any_element_is_negative ())
+    {
+      FloatComplexMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT; 
+      
+	    FloatComplex atmp (a (i, j));
+
+	    result (i, j) = std::pow (atmp, b);
+	  }
+
+      retval = result;
+    }
+  else
+    {
+      FloatMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), b);
+	  }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 4 -*-
+octave_value
+elem_xpow (const FloatMatrix& a, const FloatMatrix& b)
+{
+  octave_value retval;
+
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  int convert_to_complex = 0;
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	float atmp = a (i, j);
+	float btmp = b (i, j);
+	if (atmp < 0.0 && static_cast<int> (btmp) != btmp)
+	  {
+	    convert_to_complex = 1;
+	    goto done;
+	  }
+      }
+
+done:
+
+  if (convert_to_complex)
+    {
+      FloatComplexMatrix complex_result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    FloatComplex atmp (a (i, j));
+	    FloatComplex btmp (b (i, j));
+	    complex_result (i, j) = std::pow (atmp, btmp);
+	  }
+
+      retval = complex_result;
+    }
+  else
+    {
+      FloatMatrix result (nr, nc);
+
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), b (i, j));
+	  }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+elem_xpow (const FloatMatrix& a, const FloatComplex& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (FloatComplex (a (i, j)), b);
+      }
+
+  return result;
+}
+
+// -*- 6 -*-
+octave_value
+elem_xpow (const FloatMatrix& a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (FloatComplex (a (i, j)), b (i, j));
+      }
+
+  return result;
+}
+
+// -*- 7 -*-
+octave_value
+elem_xpow (const FloatComplex& a, const FloatMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	float btmp = b (i, j);
+	if (xisint (btmp))
+	  result (i, j) = std::pow (a, static_cast<int> (btmp));
+	else
+	  result (i, j) = std::pow (a, btmp);
+      }
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+elem_xpow (const FloatComplex& a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = b.rows ();
+  octave_idx_type nc = b.cols ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a, b (i, j));
+      }
+
+  return result;
+}
+
+// -*- 9 -*-
+octave_value
+elem_xpow (const FloatComplexMatrix& a, float b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  if (xisint (b))
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), static_cast<int> (b));
+	  }
+    }
+  else
+    {
+      for (octave_idx_type j = 0; j < nc; j++)
+	for (octave_idx_type i = 0; i < nr; i++)
+	  {
+	    OCTAVE_QUIT;
+	    result (i, j) = std::pow (a (i, j), b);
+	  }
+    }
+
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+elem_xpow (const FloatComplexMatrix& a, const FloatMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	float btmp = b (i, j);
+	if (xisint (btmp))
+	  result (i, j) = std::pow (a (i, j), static_cast<int> (btmp));
+	else
+	  result (i, j) = std::pow (a (i, j), btmp);
+      }
+
+  return result;
+}
+
+// -*- 11 -*-
+octave_value
+elem_xpow (const FloatComplexMatrix& a, const FloatComplex& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a (i, j), b);
+      }
+
+  return result;
+}
+
+// -*- 12 -*-
+octave_value
+elem_xpow (const FloatComplexMatrix& a, const FloatComplexMatrix& b)
+{
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.cols ();
+
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (nr != b_nr || nc != b_nc)
+    {
+      gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
+      return octave_value ();
+    }
+
+  FloatComplexMatrix result (nr, nc);
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+	OCTAVE_QUIT;
+	result (i, j) = std::pow (a (i, j), b (i, j));
+      }
+
+  return result;
+}
+
+// Safer pow functions that work elementwise for N-d arrays.
+//
+//       op2 \ op1:   s   nd  cs   cnd
+//            +--   +---+---+----+----+
+//   scalar   |     | * | 3 |  * |  9 |
+//                  +---+---+----+----+
+//   N_d            | 1 | 4 |  7 | 10 |
+//                  +---+---+----+----+
+//   complex_scalar | * | 5 |  * | 11 |
+//                  +---+---+----+----+
+//   complex_N_d    | 2 | 6 |  8 | 12 |
+//                  +---+---+----+----+
+//
+//   * -> not needed.
+
+// FIXME -- these functions need to be fixed so that things
+// like
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
+//
+// and
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
+//
+// produce identical results.  Also, it would be nice if -1^0.5
+// produced a pure imaginary result instead of a complex number with a
+// small real part.  But perhaps that's really a problem with the math
+// library...
+
+// -*- 1 -*-
+octave_value
+elem_xpow (float a, const FloatNDArray& b)
+{
+  octave_value retval;
+
+  float d1, d2;
+
+  if (a < 0.0 && ! b.all_integers (d1, d2))
+    {
+      FloatComplex atmp (a);
+      FloatComplexNDArray result (b.dims ());
+      for (octave_idx_type i = 0; i < b.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = std::pow (atmp, b(i));
+	}
+
+      retval = result;
+    }
+  else
+    {
+      FloatNDArray result (b.dims ());
+      for (octave_idx_type i = 0; i < b.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result (i) = std::pow (a, b(i));
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+elem_xpow (float a, const FloatComplexNDArray& b)
+{
+  FloatComplexNDArray result (b.dims ());
+  FloatComplex atmp (a);
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (atmp, b(i));
+    }
+
+  return result;
+}
+
+// -*- 3 -*-
+octave_value
+elem_xpow (const FloatNDArray& a, float b)
+{
+  octave_value retval;
+
+  if (! xisint (b))
+    {
+      if (a.any_element_is_negative ())
+        {
+          FloatComplexNDArray result (a.dims ());
+
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+
+              FloatComplex atmp (a (i));
+
+              result(i) = std::pow (atmp, b);
+            }
+
+          retval = result;
+        }
+      else
+        {
+          FloatNDArray result (a.dims ());
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+              result(i) = std::pow (a(i), b);
+            }
+
+          retval = result;
+        }
+    }
+  else
+    {
+      FloatNDArray result (a.dims ());
+
+      int ib = static_cast<int> (b);
+      if (ib == 2)
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            result.xelem (i) = a(i) * a(i);
+        }
+      else if (ib == -1)
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            result.xelem (i) = 1.0f / a(i);
+        }
+      else
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+              result(i) = std::pow (a(i), ib);
+            }
+        }
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 4 -*-
+octave_value
+elem_xpow (const FloatNDArray& a, const FloatNDArray& b)
+{
+  octave_value retval;
+
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  int len = a.length ();
+
+  bool convert_to_complex = false;
+
+  for (octave_idx_type i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+      float atmp = a(i);
+      float btmp = b(i);
+      if (atmp < 0.0 && static_cast<int> (btmp) != btmp)
+	{
+	  convert_to_complex = true;
+	  goto done;
+	}
+    }
+
+done:
+
+  if (convert_to_complex)
+    {
+      FloatComplexNDArray complex_result (a_dims);
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  OCTAVE_QUIT;
+	  FloatComplex atmp (a(i));
+	  FloatComplex btmp (b(i));
+	  complex_result(i) = std::pow (atmp, btmp);
+	}
+
+      retval = complex_result;
+    }
+  else
+    {
+      FloatNDArray result (a_dims);
+
+      for (octave_idx_type i = 0; i < len; i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = std::pow (a(i), b(i));
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+elem_xpow (const FloatNDArray& a, const FloatComplex& b)
+{
+  FloatComplexNDArray result (a.dims ());
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (FloatComplex (a(i)), b);
+    }
+
+  return result;
+}
+
+// -*- 6 -*-
+octave_value
+elem_xpow (const FloatNDArray& a, const FloatComplexNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  FloatComplexNDArray result (a_dims);
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (FloatComplex (a(i)), b(i));
+    }
+
+  return result;
+}
+
+// -*- 7 -*-
+octave_value
+elem_xpow (const FloatComplex& a, const FloatNDArray& b)
+{
+  FloatComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      float btmp = b(i);
+      if (xisint (btmp))
+	result(i) = std::pow (a, static_cast<int> (btmp));
+      else
+	result(i) = std::pow (a, btmp);
+    }
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+elem_xpow (const FloatComplex& a, const FloatComplexNDArray& b)
+{
+  FloatComplexNDArray result (b.dims ());
+
+  for (octave_idx_type i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (a, b(i));
+    }
+
+  return result;
+}
+
+// -*- 9 -*-
+octave_value
+elem_xpow (const FloatComplexNDArray& a, float b)
+{
+  FloatComplexNDArray result (a.dims ());
+
+  if (xisint (b))
+    {
+      if (b == -1)
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            result.xelem (i) = std::conj (a(i)) / std::norm (a(i));
+        }
+      else
+        {
+          for (octave_idx_type i = 0; i < a.length (); i++)
+            {
+              OCTAVE_QUIT;
+              result(i) = std::pow (a(i), static_cast<int> (b));
+            }
+        }
+    }
+  else
+    {
+      for (octave_idx_type i = 0; i < a.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = std::pow (a(i), b);
+	}
+    }
+
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+elem_xpow (const FloatComplexNDArray& a, const FloatNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  FloatComplexNDArray result (a_dims);
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      float btmp = b(i);
+      if (xisint (btmp))
+	result(i) = std::pow (a(i), static_cast<int> (btmp));
+      else
+	result(i) = std::pow (a(i), btmp);
+    }
+
+  return result;
+}
+
+// -*- 11 -*-
+octave_value
+elem_xpow (const FloatComplexNDArray& a, const FloatComplex& b)
+{
+  FloatComplexNDArray result (a.dims ());
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (a(i), b);
+    }
+
+  return result;
+}
+
+// -*- 12 -*-
+octave_value
+elem_xpow (const FloatComplexNDArray& a, const FloatComplexNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  FloatComplexNDArray result (a_dims);
+
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = std::pow (a(i), b(i));
+    }
+
+  return result;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/xpow.h b/src/xpow.h
new file mode 100644
index 0000000..d4f2304
--- /dev/null
+++ b/src/xpow.h
@@ -0,0 +1,165 @@
+/*
+
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 2002, 2003, 2005, 2007, 2008
+              John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_xpow_h)
+#define octave_xpow_h 1
+
+#include "oct-cmplx.h"
+
+class Matrix;
+class ComplexMatrix;
+class FloatMatrix;
+class FloatComplexMatrix;
+class DiagMatrix;
+class ComplexDiagMatrix;
+class FloatDiagMatrix;
+class FloatComplexDiagMatrix;
+class PermMatrix;
+class NDArray;
+class FloatNDArray;
+class ComplexNDArray;
+class FloatComplexNDArray;
+class octave_value;
+class Range;
+
+extern octave_value xpow (double a, double b);
+extern octave_value xpow (double a, const Matrix& b);
+extern octave_value xpow (double a, const Complex& b);
+extern octave_value xpow (double a, const ComplexMatrix& b);
+
+extern octave_value xpow (const Matrix& a, double b);
+extern octave_value xpow (const Matrix& a, const Complex& b);
+
+extern octave_value xpow (const DiagMatrix& a, double b);
+extern octave_value xpow (const DiagMatrix& a, const Complex& b);
+
+extern octave_value xpow (const PermMatrix& a, double b);
+
+extern octave_value xpow (const Complex& a, double b);
+extern octave_value xpow (const Complex& a, const Matrix& b);
+extern octave_value xpow (const Complex& a, const Complex& b);
+extern octave_value xpow (const Complex& a, const ComplexMatrix& b);
+
+extern octave_value xpow (const ComplexMatrix& a, double b);
+extern octave_value xpow (const ComplexMatrix& a, const Complex& b);
+
+extern octave_value xpow (const ComplexDiagMatrix& a, double b);
+extern octave_value xpow (const ComplexDiagMatrix& a, const Complex& b);
+
+extern octave_value elem_xpow (double a, const Matrix& b);
+extern octave_value elem_xpow (double a, const ComplexMatrix& b);
+extern octave_value elem_xpow (double a, const Range& r);
+
+extern octave_value elem_xpow (const Matrix& a, double b);
+extern octave_value elem_xpow (const Matrix& a, const Matrix& b);
+extern octave_value elem_xpow (const Matrix& a, const Complex& b);
+extern octave_value elem_xpow (const Matrix& a, const ComplexMatrix& b);
+
+extern octave_value elem_xpow (const Complex& a, const Matrix& b);
+extern octave_value elem_xpow (const Complex& a, const ComplexMatrix& b);
+extern octave_value elem_xpow (const Complex& a, const Range& r);
+
+extern octave_value elem_xpow (const ComplexMatrix& a, double b);
+extern octave_value elem_xpow (const ComplexMatrix& a, const Matrix& b);
+extern octave_value elem_xpow (const ComplexMatrix& a, const Complex& b);
+extern octave_value elem_xpow (const ComplexMatrix& a, const ComplexMatrix& b);
+
+
+extern octave_value elem_xpow (double a, const NDArray& b);
+extern octave_value elem_xpow (double a, const ComplexNDArray& b);
+
+extern octave_value elem_xpow (const NDArray& a, double b);
+extern octave_value elem_xpow (const NDArray& a, const NDArray& b);
+extern octave_value elem_xpow (const NDArray& a, const Complex& b);
+extern octave_value elem_xpow (const NDArray& a, const ComplexNDArray& b);
+
+extern octave_value elem_xpow (const Complex& a, const NDArray& b);
+extern octave_value elem_xpow (const Complex& a, const ComplexNDArray& b);
+
+extern octave_value elem_xpow (const ComplexNDArray& a, double b);
+extern octave_value elem_xpow (const ComplexNDArray& a, const NDArray& b);
+extern octave_value elem_xpow (const ComplexNDArray& a, const Complex& b);
+extern octave_value elem_xpow (const ComplexNDArray& a, const ComplexNDArray& b);
+
+extern octave_value xpow (float a, float b);
+extern octave_value xpow (float a, const FloatMatrix& b);
+extern octave_value xpow (float a, const FloatComplex& b);
+extern octave_value xpow (float a, const FloatComplexMatrix& b);
+
+extern octave_value xpow (const FloatMatrix& a, float b);
+extern octave_value xpow (const FloatMatrix& a, const FloatComplex& b);
+
+extern octave_value xpow (const FloatDiagMatrix& a, float b);
+extern octave_value xpow (const FloatDiagMatrix& a, const FloatComplex& b);
+
+extern octave_value xpow (const FloatComplex& a, float b);
+extern octave_value xpow (const FloatComplex& a, const FloatMatrix& b);
+extern octave_value xpow (const FloatComplex& a, const FloatComplex& b);
+extern octave_value xpow (const FloatComplex& a, const FloatComplexMatrix& b);
+
+extern octave_value xpow (const FloatComplexMatrix& a, float b);
+extern octave_value xpow (const FloatComplexMatrix& a, const FloatComplex& b);
+
+extern octave_value xpow (const FloatComplexDiagMatrix& a, float b);
+extern octave_value xpow (const FloatComplexDiagMatrix& a, const FloatComplex& b);
+
+extern octave_value elem_xpow (float a, const FloatMatrix& b);
+extern octave_value elem_xpow (float a, const FloatComplexMatrix& b);
+
+extern octave_value elem_xpow (const FloatMatrix& a, float b);
+extern octave_value elem_xpow (const FloatMatrix& a, const FloatMatrix& b);
+extern octave_value elem_xpow (const FloatMatrix& a, const FloatComplex& b);
+extern octave_value elem_xpow (const FloatMatrix& a, const FloatComplexMatrix& b);
+
+extern octave_value elem_xpow (const FloatComplex& a, const FloatMatrix& b);
+extern octave_value elem_xpow (const FloatComplex& a, const FloatComplexMatrix& b);
+
+extern octave_value elem_xpow (const FloatComplexMatrix& a, float b);
+extern octave_value elem_xpow (const FloatComplexMatrix& a, const FloatMatrix& b);
+extern octave_value elem_xpow (const FloatComplexMatrix& a, const FloatComplex& b);
+extern octave_value elem_xpow (const FloatComplexMatrix& a, const FloatComplexMatrix& b);
+
+
+extern octave_value elem_xpow (float a, const FloatNDArray& b);
+extern octave_value elem_xpow (float a, const FloatComplexNDArray& b);
+
+extern octave_value elem_xpow (const FloatNDArray& a, float b);
+extern octave_value elem_xpow (const FloatNDArray& a, const FloatNDArray& b);
+extern octave_value elem_xpow (const FloatNDArray& a, const FloatComplex& b);
+extern octave_value elem_xpow (const FloatNDArray& a, const FloatComplexNDArray& b);
+
+extern octave_value elem_xpow (const FloatComplex& a, const FloatNDArray& b);
+extern octave_value elem_xpow (const FloatComplex& a, const FloatComplexNDArray& b);
+
+extern octave_value elem_xpow (const FloatComplexNDArray& a, float b);
+extern octave_value elem_xpow (const FloatComplexNDArray& a, const FloatNDArray& b);
+extern octave_value elem_xpow (const FloatComplexNDArray& a, const FloatComplex& b);
+extern octave_value elem_xpow (const FloatComplexNDArray& a, const FloatComplexNDArray& b);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/y.tab.h b/src/y.tab.h
new file mode 100644
index 0000000..1a010ce
--- /dev/null
+++ b/src/y.tab.h
@@ -0,0 +1,240 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can 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, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ADD_EQ = 258,
+     SUB_EQ = 259,
+     MUL_EQ = 260,
+     DIV_EQ = 261,
+     LEFTDIV_EQ = 262,
+     POW_EQ = 263,
+     EMUL_EQ = 264,
+     EDIV_EQ = 265,
+     ELEFTDIV_EQ = 266,
+     EPOW_EQ = 267,
+     AND_EQ = 268,
+     OR_EQ = 269,
+     LSHIFT_EQ = 270,
+     RSHIFT_EQ = 271,
+     LSHIFT = 272,
+     RSHIFT = 273,
+     EXPR_AND_AND = 274,
+     EXPR_OR_OR = 275,
+     EXPR_AND = 276,
+     EXPR_OR = 277,
+     EXPR_NOT = 278,
+     EXPR_LT = 279,
+     EXPR_LE = 280,
+     EXPR_EQ = 281,
+     EXPR_NE = 282,
+     EXPR_GE = 283,
+     EXPR_GT = 284,
+     LEFTDIV = 285,
+     EMUL = 286,
+     EDIV = 287,
+     ELEFTDIV = 288,
+     EPLUS = 289,
+     EMINUS = 290,
+     QUOTE = 291,
+     TRANSPOSE = 292,
+     PLUS_PLUS = 293,
+     MINUS_MINUS = 294,
+     POW = 295,
+     EPOW = 296,
+     NUM = 297,
+     IMAG_NUM = 298,
+     STRUCT_ELT = 299,
+     NAME = 300,
+     END = 301,
+     DQ_STRING = 302,
+     SQ_STRING = 303,
+     FOR = 304,
+     WHILE = 305,
+     DO = 306,
+     UNTIL = 307,
+     IF = 308,
+     ELSEIF = 309,
+     ELSE = 310,
+     SWITCH = 311,
+     CASE = 312,
+     OTHERWISE = 313,
+     BREAK = 314,
+     CONTINUE = 315,
+     FUNC_RET = 316,
+     UNWIND = 317,
+     CLEANUP = 318,
+     TRY = 319,
+     CATCH = 320,
+     GLOBAL = 321,
+     STATIC = 322,
+     FCN_HANDLE = 323,
+     END_OF_INPUT = 324,
+     LEXICAL_ERROR = 325,
+     FCN = 326,
+     SCRIPT = 327,
+     CLOSE_BRACE = 328,
+     UNARY = 329
+   };
+#endif
+/* Tokens.  */
+#define ADD_EQ 258
+#define SUB_EQ 259
+#define MUL_EQ 260
+#define DIV_EQ 261
+#define LEFTDIV_EQ 262
+#define POW_EQ 263
+#define EMUL_EQ 264
+#define EDIV_EQ 265
+#define ELEFTDIV_EQ 266
+#define EPOW_EQ 267
+#define AND_EQ 268
+#define OR_EQ 269
+#define LSHIFT_EQ 270
+#define RSHIFT_EQ 271
+#define LSHIFT 272
+#define RSHIFT 273
+#define EXPR_AND_AND 274
+#define EXPR_OR_OR 275
+#define EXPR_AND 276
+#define EXPR_OR 277
+#define EXPR_NOT 278
+#define EXPR_LT 279
+#define EXPR_LE 280
+#define EXPR_EQ 281
+#define EXPR_NE 282
+#define EXPR_GE 283
+#define EXPR_GT 284
+#define LEFTDIV 285
+#define EMUL 286
+#define EDIV 287
+#define ELEFTDIV 288
+#define EPLUS 289
+#define EMINUS 290
+#define QUOTE 291
+#define TRANSPOSE 292
+#define PLUS_PLUS 293
+#define MINUS_MINUS 294
+#define POW 295
+#define EPOW 296
+#define NUM 297
+#define IMAG_NUM 298
+#define STRUCT_ELT 299
+#define NAME 300
+#define END 301
+#define DQ_STRING 302
+#define SQ_STRING 303
+#define FOR 304
+#define WHILE 305
+#define DO 306
+#define UNTIL 307
+#define IF 308
+#define ELSEIF 309
+#define ELSE 310
+#define SWITCH 311
+#define CASE 312
+#define OTHERWISE 313
+#define BREAK 314
+#define CONTINUE 315
+#define FUNC_RET 316
+#define UNWIND 317
+#define CLEANUP 318
+#define TRY 319
+#define CATCH 320
+#define GLOBAL 321
+#define STATIC 322
+#define FCN_HANDLE 323
+#define END_OF_INPUT 324
+#define LEXICAL_ERROR 325
+#define FCN 326
+#define SCRIPT 327
+#define CLOSE_BRACE 328
+#define UNARY 329
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 364 "parse.y"
+{
+  // The type of the basic tokens returned by the lexer.
+  token *tok_val;
+
+  // Comment strings that we need to deal with mid-rule.
+  octave_comment_list *comment_type;
+
+  // Types for the nonterminals we generate.
+  char sep_type;
+  tree *tree_type;
+  tree_matrix *tree_matrix_type;
+  tree_cell *tree_cell_type;
+  tree_expression *tree_expression_type;
+  tree_constant *tree_constant_type;
+  tree_fcn_handle *tree_fcn_handle_type;
+  tree_anon_fcn_handle *tree_anon_fcn_handle_type;
+  tree_identifier *tree_identifier_type;
+  tree_index_expression *tree_index_expression_type;
+  tree_colon_expression *tree_colon_expression_type;
+  tree_argument_list *tree_argument_list_type;
+  tree_parameter_list *tree_parameter_list_type;
+  tree_command *tree_command_type;
+  tree_if_command *tree_if_command_type;
+  tree_if_clause *tree_if_clause_type;
+  tree_if_command_list *tree_if_command_list_type;
+  tree_switch_command *tree_switch_command_type;
+  tree_switch_case *tree_switch_case_type;
+  tree_switch_case_list *tree_switch_case_list_type;
+  tree_decl_elt *tree_decl_elt_type;
+  tree_decl_init_list *tree_decl_init_list_type;
+  tree_decl_command *tree_decl_command_type;
+  tree_statement *tree_statement_type;
+  tree_statement_list *tree_statement_list_type;
+  octave_user_function *octave_user_function_type;
+}
+/* Line 1489 of yacc.c.  */
+#line 233 "y.tab.h"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE octave_lval;
+
diff --git a/src/zfstream.cc b/src/zfstream.cc
new file mode 100644
index 0000000..72ef9c5
--- /dev/null
+++ b/src/zfstream.cc
@@ -0,0 +1,631 @@
+/*
+
+Copyright (C) 2005, 2007, 2008 Ludwig Schwardt, Kevin Ruland 
+
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+ This file is adapted from the zlib 1.2.2 contrib/iostream3 code,
+ written by
+
+   Ludwig Schwardt <schwardt at sun.ac.za>
+   original version by Kevin Ruland <kevin at rodin.wustl.edu>
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+
+#include "zfstream.h"
+
+#ifdef HAVE_ZLIB
+
+#include <cstring>          // for strcpy, strcat, strlen (mode strings)
+#include <cstdio>           // for BUFSIZ
+
+// Internal buffer sizes (default and "unbuffered" versions)
+#define STASHED_CHARACTERS 16
+#define BIGBUFSIZE (256 * 1024 + STASHED_CHARACTERS) 
+#define SMALLBUFSIZE 1
+
+/*****************************************************************************/
+
+// Default constructor
+gzfilebuf::gzfilebuf()
+: file(0), io_mode(std::ios_base::openmode(0)), own_fd(false),
+  buffer(0), buffer_size(BIGBUFSIZE), own_buffer(true)
+{
+  // No buffers to start with
+  this->disable_buffer();
+}
+
+// Destructor
+gzfilebuf::~gzfilebuf()
+{
+  // Sync output buffer and close only if responsible for file
+  // (i.e. attached streams should be left open at this stage)
+  this->sync();
+  if (own_fd)
+    this->close();
+  // Make sure internal buffer is deallocated
+  this->disable_buffer();
+}
+
+// Set compression level and strategy
+int
+gzfilebuf::setcompression(int comp_level,
+                          int comp_strategy)
+{
+  return gzsetparams(file, comp_level, comp_strategy);
+}
+
+// Open gzipped file
+gzfilebuf*
+gzfilebuf::open(const char *name,
+                std::ios_base::openmode mode)
+{
+  // Fail if file already open
+  if (this->is_open())
+    return 0;
+  // Don't support simultaneous read/write access (yet)
+  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+    return 0;
+
+  // Build mode string for gzopen and check it [27.8.1.3.2]
+  char char_mode[6] = "\0\0\0\0\0";
+  if (!this->open_mode(mode, char_mode))
+    return 0;
+
+  // Attempt to open file
+  if ((file = gzopen(name, char_mode)) == 0)
+    return 0;
+
+  // On success, allocate internal buffer and set flags
+  this->enable_buffer();
+  io_mode = mode;
+  own_fd = true;
+  return this;
+}
+
+// Attach to gzipped file
+gzfilebuf*
+gzfilebuf::attach(int fd,
+                  std::ios_base::openmode mode)
+{
+  // Fail if file already open
+  if (this->is_open())
+    return 0;
+  // Don't support simultaneous read/write access (yet)
+  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+    return 0;
+
+  // Build mode string for gzdopen and check it [27.8.1.3.2]
+  char char_mode[6] = "\0\0\0\0\0";
+  if (!this->open_mode(mode, char_mode))
+    return 0;
+
+  // Attempt to attach to file
+  if ((file = gzdopen(fd, char_mode)) == 0)
+    return 0;
+
+  // On success, allocate internal buffer and set flags
+  this->enable_buffer();
+  io_mode = mode;
+  own_fd = false;
+  return this;
+}
+
+// Close gzipped file
+gzfilebuf*
+gzfilebuf::close()
+{
+  // Fail immediately if no file is open
+  if (!this->is_open())
+    return 0;
+  // Assume success
+  gzfilebuf* retval = this;
+  // Attempt to sync and close gzipped file
+  if (this->sync() == -1)
+    retval = 0;
+  if (gzclose(file) < 0)
+    retval = 0;
+  // File is now gone anyway (postcondition [27.8.1.3.8])
+  file = 0;
+  own_fd = false;
+  // Destroy internal buffer if it exists
+  this->disable_buffer();
+  return retval;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Convert int open mode to mode string
+bool
+gzfilebuf::open_mode(std::ios_base::openmode mode,
+                     char* c_mode) const
+{
+  // FIXME -- do we need testb?
+  // bool testb = mode & std::ios_base::binary;
+  bool testi = mode & std::ios_base::in;
+  bool testo = mode & std::ios_base::out;
+  bool testt = mode & std::ios_base::trunc;
+  bool testa = mode & std::ios_base::app;
+
+  // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
+  // Original zfstream hardcoded the compression level to maximum here...
+  // Double the time for less than 1% size improvement seems
+  // excessive though - keeping it at the default level
+  // To change back, just append "9" to the next three mode strings
+  if (!testi && testo && !testt && !testa)
+    strcpy(c_mode, "w");
+  if (!testi && testo && !testt && testa)
+    strcpy(c_mode, "a");
+  if (!testi && testo && testt && !testa)
+    strcpy(c_mode, "w");
+  if (testi && !testo && !testt && !testa)
+    strcpy(c_mode, "r");
+  // No read/write mode yet
+//  if (testi && testo && !testt && !testa)
+//    strcpy(c_mode, "r+");
+//  if (testi && testo && testt && !testa)
+//    strcpy(c_mode, "w+");
+
+  // Mode string should be empty for invalid combination of flags
+  if (strlen(c_mode) == 0)
+    return false;
+
+  strcat(c_mode, "b");
+
+  return true;
+}
+
+// Determine number of characters in internal get buffer
+std::streamsize
+gzfilebuf::showmanyc()
+{
+  // Calls to underflow will fail if file not opened for reading
+  if (!this->is_open() || !(io_mode & std::ios_base::in))
+    return -1;
+  // Make sure get area is in use
+  if (this->gptr() && (this->gptr() < this->egptr()))
+    return std::streamsize(this->egptr() - this->gptr());
+  else
+    return 0;
+}
+
+// Puts back a character to the stream in two cases. Firstly, when there
+// is no putback position available, and secondly when the character putback
+// differs from the one in the file. We can only support the first case 
+// with gzipped files.
+gzfilebuf::int_type
+gzfilebuf::pbackfail (gzfilebuf::int_type c)
+{
+  if (this->is_open())
+    {
+      if (gzseek (file, this->gptr() - this->egptr() - 1, SEEK_CUR) < 0)
+	return traits_type::eof();
+  
+      // Invalidates contents of the buffer
+      enable_buffer ();
+
+      // Attempt to fill internal buffer from gzipped file
+      // (buffer must be guaranteed to exist...)
+      int bytes_read = gzread(file, buffer, buffer_size);
+      // Indicates error or EOF
+      if (bytes_read <= 0)
+	{
+	  // Reset get area
+	  this->setg(buffer, buffer, buffer);
+	  return traits_type::eof();
+	}
+
+      // Make all bytes read from file available as get area
+      this->setg(buffer, buffer, buffer + bytes_read);
+
+      // If next character in get area differs from putback character
+      // flag a failure
+      gzfilebuf::int_type ret = traits_type::to_int_type(*(this->gptr()));
+      if (ret != c)
+	return traits_type::eof();
+      else
+	return ret;
+    }
+  else
+    return traits_type::eof();
+}
+
+// Fill get area from gzipped file
+gzfilebuf::int_type
+gzfilebuf::underflow()
+{
+  // If something is left in the get area by chance, return it
+  // (this shouldn't normally happen, as underflow is only supposed
+  // to be called when gptr >= egptr, but it serves as error check)
+  if (this->gptr() && (this->gptr() < this->egptr()))
+    return traits_type::to_int_type(*(this->gptr()));
+
+  // If the file hasn't been opened for reading, produce error
+  if (!this->is_open() || !(io_mode & std::ios_base::in))
+    return traits_type::eof();
+
+  // Copy the final characters to the front of the buffer
+  int stash = 0;
+  if (this->eback() && buffer && buffer_size > STASHED_CHARACTERS)
+    {
+      char_type *ptr1 = buffer;
+      char_type *ptr2 = this->egptr() - STASHED_CHARACTERS + 1;
+      if (ptr2 > this->eback())
+	while (stash++ <= STASHED_CHARACTERS)
+	  *ptr1++ = *ptr2++;
+    }
+
+  // Attempt to fill internal buffer from gzipped file
+  // (buffer must be guaranteed to exist...)
+  int bytes_read = gzread(file, buffer + stash, buffer_size - stash);
+
+  // Indicates error or EOF
+  if (bytes_read <= 0)
+  {
+    // Reset get area
+    this->setg(buffer, buffer, buffer);
+    return traits_type::eof();
+  }
+  // Make all bytes read from file plus the stash available as get area
+  this->setg(buffer, buffer + stash, buffer + bytes_read + stash);
+
+  // Return next character in get area
+  return traits_type::to_int_type(*(this->gptr()));
+}
+
+// Write put area to gzipped file
+gzfilebuf::int_type
+gzfilebuf::overflow(int_type c)
+{
+  // Determine whether put area is in use
+  if (this->pbase())
+  {
+    // Double-check pointer range
+    if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
+      return traits_type::eof();
+    // Add extra character to buffer if not EOF
+    if (!traits_type::eq_int_type(c, traits_type::eof()))
+    {
+      *(this->pptr()) = traits_type::to_char_type(c);
+      this->pbump(1);
+    }
+    // Number of characters to write to file
+    int bytes_to_write = this->pptr() - this->pbase();
+    // Overflow doesn't fail if nothing is to be written
+    if (bytes_to_write > 0)
+    {
+      // If the file hasn't been opened for writing, produce error
+      if (!this->is_open() || !(io_mode & std::ios_base::out))
+        return traits_type::eof();
+      // If gzipped file won't accept all bytes written to it, fail
+      if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
+        return traits_type::eof();
+      // Reset next pointer to point to pbase on success
+      this->pbump(-bytes_to_write);
+    }
+  }
+  // Write extra character to file if not EOF
+  else if (!traits_type::eq_int_type(c, traits_type::eof()))
+  {
+    // If the file hasn't been opened for writing, produce error
+    if (!this->is_open() || !(io_mode & std::ios_base::out))
+      return traits_type::eof();
+    // Impromptu char buffer (allows "unbuffered" output)
+    char_type last_char = traits_type::to_char_type(c);
+    // If gzipped file won't accept this character, fail
+    if (gzwrite(file, &last_char, 1) != 1)
+      return traits_type::eof();
+  }
+
+  // If you got here, you have succeeded (even if c was EOF)
+  // The return value should therefore be non-EOF
+  if (traits_type::eq_int_type(c, traits_type::eof()))
+    return traits_type::not_eof(c);
+  else
+    return c;
+}
+
+// Assign new buffer
+std::streambuf*
+gzfilebuf::setbuf(char_type* p,
+                  std::streamsize n)
+{
+  // First make sure stuff is sync'ed, for safety
+  if (this->sync() == -1)
+    return 0;
+  // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
+  // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
+  // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
+  // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
+  if (!p || !n)
+  {
+    // Replace existing buffer (if any) with small internal buffer
+    this->disable_buffer();
+    buffer = 0;
+    buffer_size = 0;
+    own_buffer = true;
+    this->enable_buffer();
+  }
+  else
+  {
+    // Replace existing buffer (if any) with external buffer
+    this->disable_buffer();
+    buffer = p;
+    buffer_size = n;
+    own_buffer = false;
+    this->enable_buffer();
+  }
+  return this;
+}
+
+// Write put area to gzipped file (i.e. ensures that put area is empty)
+int
+gzfilebuf::sync()
+{
+  return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Allocate internal buffer
+void
+gzfilebuf::enable_buffer()
+{
+  // If internal buffer required, allocate one
+  if (own_buffer && !buffer)
+  {
+    // Check for buffered vs. "unbuffered"
+    if (buffer_size > 0)
+    {
+      // Allocate internal buffer
+      buffer = new char_type[buffer_size];
+      // Get area starts empty and will be expanded by underflow as need arises
+      this->setg(buffer, buffer, buffer);
+      // Setup entire internal buffer as put area.
+      // The one-past-end pointer actually points to the last element of the buffer,
+      // so that overflow(c) can safely add the extra character c to the sequence.
+      // These pointers remain in place for the duration of the buffer
+      this->setp(buffer, buffer + buffer_size - 1);
+    }
+    else
+    {
+      // Even in "unbuffered" case, (small?) get buffer is still required
+      buffer_size = SMALLBUFSIZE;
+      buffer = new char_type[buffer_size];
+      this->setg(buffer, buffer, buffer);
+      // "Unbuffered" means no put buffer
+      this->setp(0, 0);
+    }
+  }
+  else
+  {
+    // If buffer already allocated, reset buffer pointers just to make sure no
+    // stale chars are lying around
+    this->setg(buffer, buffer, buffer);
+    this->setp(buffer, buffer + buffer_size - 1);
+  }
+}
+
+// Destroy internal buffer
+void
+gzfilebuf::disable_buffer()
+{
+  // If internal buffer exists, deallocate it
+  if (own_buffer && buffer)
+  {
+    // Preserve unbuffered status by zeroing size
+    if (!this->pbase())
+      buffer_size = 0;
+    delete[] buffer;
+    buffer = 0;
+    this->setg(0, 0, 0);
+    this->setp(0, 0);
+  }
+  else
+  {
+    // Reset buffer pointers to initial state if external buffer exists
+    this->setg(buffer, buffer, buffer);
+    if (buffer)
+      this->setp(buffer, buffer + buffer_size - 1);
+    else
+      this->setp(0, 0);
+  }
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Seek functions
+gzfilebuf::pos_type
+gzfilebuf::seekoff(off_type off, std::ios_base::seekdir way, 
+		   std::ios_base::openmode)
+{
+  pos_type ret = pos_type (off_type (-1));
+
+  if (this->is_open())
+    {
+      off_type computed_off = off;
+
+      if ((io_mode & std::ios_base::in) && way == std::ios_base::cur)
+	computed_off += this->gptr() - this->egptr();
+
+      if (way == std::ios_base::beg)
+	ret = pos_type (gzseek (file, computed_off, SEEK_SET));
+      else if (way == std::ios_base::cur)
+	ret = pos_type (gzseek (file, computed_off, SEEK_CUR));
+      else
+	// Can't seek from end of a gzipped file, so this will give -1
+	ret = pos_type (gzseek (file, computed_off, SEEK_END));
+  
+      if (io_mode & std::ios_base::in)
+	// Invalidates contents of the buffer
+	enable_buffer ();
+      else
+	// flush contents of buffer to file
+	overflow ();
+    }
+
+  return ret;
+}
+
+gzfilebuf::pos_type
+gzfilebuf::seekpos(pos_type sp, std::ios_base::openmode)
+{
+  pos_type ret = pos_type (off_type (-1));
+
+  if (this->is_open ())
+    {
+      ret = pos_type (gzseek (file, sp, SEEK_SET));
+
+      if (io_mode & std::ios_base::in)
+	// Invalidates contents of the buffer
+	enable_buffer ();
+      else
+	// flush contents of buffer to file
+	overflow ();
+    }
+
+  return ret;
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzifstream::gzifstream()
+: std::istream(0), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzifstream::gzifstream(const char* name,
+                       std::ios_base::openmode mode)
+: std::istream(0), sb()
+{
+  this->init(&sb);
+  this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzifstream::gzifstream(int fd,
+                       std::ios_base::openmode mode)
+: std::istream(0), sb()
+{
+  this->init(&sb);
+  this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzifstream::open(const char* name,
+                 std::ios_base::openmode mode)
+{
+  if (!sb.open(name, mode | std::ios_base::in))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzifstream::attach(int fd,
+                   std::ios_base::openmode mode)
+{
+  if (!sb.attach(fd, mode | std::ios_base::in))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Close file
+void
+gzifstream::close()
+{
+  if (!sb.close())
+    this->setstate(std::ios_base::failbit);
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzofstream::gzofstream()
+: std::ostream(0), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzofstream::gzofstream(const char* name,
+                       std::ios_base::openmode mode)
+: std::ostream(0), sb()
+{
+  this->init(&sb);
+  this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzofstream::gzofstream(int fd,
+                       std::ios_base::openmode mode)
+: std::ostream(0), sb()
+{
+  this->init(&sb);
+  this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzofstream::open(const char* name,
+                 std::ios_base::openmode mode)
+{
+  if (!sb.open(name, mode | std::ios_base::out))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzofstream::attach(int fd,
+                   std::ios_base::openmode mode)
+{
+  if (!sb.attach(fd, mode | std::ios_base::out))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Close file
+void
+gzofstream::close()
+{
+  if (!sb.close())
+    this->setstate(std::ios_base::failbit);
+}
+
+#endif // HAVE_ZLIB
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/zfstream.h b/src/zfstream.h
new file mode 100644
index 0000000..480764f
--- /dev/null
+++ b/src/zfstream.h
@@ -0,0 +1,515 @@
+/*
+
+Copyright (C) 2005, 2007, 2008 Ludwig Schwardt, Kevin Ruland 
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+ This file is adapted from the zlib 1.2.2 contrib/iostream3 code,
+ written by
+
+   Ludwig Schwardt <schwardt at sun.ac.za>
+   original version by Kevin Ruland <kevin at rodin.wustl.edu>
+
+*/
+
+#ifndef ZFSTREAM_H
+#define ZFSTREAM_H
+
+#ifdef HAVE_ZLIB
+
+#include <iosfwd>
+
+#include "zlib.h"
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file stream buffer class.
+ *
+ *  This class implements basic_filebuf for gzipped files. It doesn't yet support
+ *  seeking (allowed by zlib but slow/limited), putback and read/write access
+ *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
+ *  file streambuf.
+*/
+class gzfilebuf : public std::streambuf
+{
+public:
+  //  Default constructor.
+  gzfilebuf();
+
+  //  Destructor.
+  virtual
+  ~gzfilebuf();
+
+  /**
+   *  @brief  Set compression level and strategy on the fly.
+   *  @param  comp_level  Compression level (see zlib.h for allowed values)
+   *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)
+   *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.
+   *
+   *  Unfortunately, these parameters cannot be modified separately, as the
+   *  previous zfstream version assumed. Since the strategy is seldom changed,
+   *  it can default and setcompression(level) then becomes like the old
+   *  setcompressionlevel(level).
+  */
+  int
+  setcompression(int comp_level,
+                 int comp_strategy = Z_DEFAULT_STRATEGY);
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() const { return (file != 0); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  open(const char* name,
+       std::ios_base::openmode mode);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  attach(int fd,
+         std::ios_base::openmode mode);
+
+  /**
+   *  @brief  Close gzipped file.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  close();
+
+protected:
+  /**
+   *  @brief  Convert ios open mode int to mode string used by zlib.
+   *  @return  True if valid mode flag combination.
+  */
+  bool
+  open_mode(std::ios_base::openmode mode,
+            char* c_mode) const;
+
+  /**
+   *  @brief  Number of characters available in stream buffer.
+   *  @return  Number of characters.
+   *
+   *  This indicates number of characters in get area of stream buffer.
+   *  These characters can be read without accessing the gzipped file.
+  */
+  virtual std::streamsize
+  showmanyc();
+
+  /**
+   *  @brief  Fill get area from gzipped file.
+   *  @return  First character in get area on success, EOF on error.
+   *
+   *  This actually reads characters from gzipped file to stream
+   *  buffer. Always buffered.
+  */
+  virtual int_type
+  underflow();
+
+  /**
+   *  @brief  Write put area to gzipped file.
+   *  @param  c  Extra character to add to buffer contents.
+   *  @return  Non-EOF on success, EOF on error.
+   *
+   *  This actually writes characters in stream buffer to
+   *  gzipped file. With unbuffered output this is done one
+   *  character at a time.
+  */
+  virtual int_type
+  overflow(int_type c = traits_type::eof());
+
+  /**
+   *  @brief  Installs external stream buffer.
+   *  @param  p  Pointer to char buffer.
+   *  @param  n  Size of external buffer.
+   *  @return  @c this on success, NULL on failure.
+   *
+   *  Call setbuf(0,0) to enable unbuffered output.
+  */
+  virtual std::streambuf*
+  setbuf(char_type* p,
+         std::streamsize n);
+
+  /**
+   *  @brief  Flush stream buffer to file.
+   *  @return  0 on success, -1 on error.
+   *
+   *  This calls underflow(EOF) to do the job.
+  */
+  virtual int
+  sync();
+
+  /**
+   *  @brief  Alters the stream positions.
+   *
+   *  Each derived class provides its own appropriate behavior.
+   */
+  virtual pos_type
+  seekoff(off_type off, std::ios_base::seekdir way,
+	  std::ios_base::openmode mode = 
+	  std::ios_base::in|std::ios_base::out);
+
+  /**
+   *  @brief  Alters the stream positions.
+   *
+   *  Each derived class provides its own appropriate behavior.
+   */
+  virtual pos_type
+  seekpos(pos_type sp, std::ios_base::openmode mode = 
+	  std::ios_base::in|std::ios_base::out);
+
+  virtual int_type
+  pbackfail (int_type c = traits_type::eof());
+
+//
+// Some future enhancements
+//
+//  virtual int_type uflow();
+//  virtual int_type pbackfail(int_type c = traits_type::eof());
+
+private:
+  /**
+   *  @brief  Allocate internal buffer.
+   *
+   *  This function is safe to call multiple times. It will ensure
+   *  that a proper internal buffer exists if it is required. If the
+   *  buffer already exists or is external, the buffer pointers will be
+   *  reset to their original state.
+  */
+  void
+  enable_buffer();
+
+  /**
+   *  @brief  Destroy internal buffer.
+   *
+   *  This function is safe to call multiple times. It will ensure
+   *  that the internal buffer is deallocated if it exists. In any
+   *  case, it will also reset the buffer pointers.
+  */
+  void
+  disable_buffer();
+
+  /**
+   *  Underlying file pointer.
+  */
+  gzFile file;
+
+  /**
+   *  Mode in which file was opened.
+  */
+  std::ios_base::openmode io_mode;
+
+  /**
+   *  @brief  True if this object owns file descriptor.
+   *
+   *  This makes the class responsible for closing the file
+   *  upon destruction.
+  */
+  bool own_fd;
+
+  /**
+   *  @brief  Stream buffer.
+   *
+   *  For simplicity this remains allocated on the free store for the
+   *  entire life span of the gzfilebuf object, unless replaced by setbuf.
+  */
+  char_type* buffer;
+
+  /**
+   *  @brief  Stream buffer size.
+   *
+   *  Defaults to system default buffer size (typically 8192 bytes).
+   *  Modified by setbuf.
+  */
+  std::streamsize buffer_size;
+
+  /**
+   *  @brief  True if this object owns stream buffer.
+   *
+   *  This makes the class responsible for deleting the buffer
+   *  upon destruction.
+  */
+  bool own_buffer;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file input stream class.
+ *
+ *  This class implements ifstream for gzipped files. Seeking and putback
+ *  is not supported yet.
+*/
+class gzifstream : public std::istream
+{
+public:
+  //  Default constructor
+  gzifstream();
+
+  /**
+   *  @brief  Construct stream on gzipped file to be opened.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+  */
+  explicit
+  gzifstream(const char* name,
+             std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Construct stream on already open gzipped file.
+   *  @param  fd    File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+  */
+  explicit
+  gzifstream(int fd,
+             std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  Obtain underlying stream buffer.
+  */
+  gzfilebuf*
+  rdbuf() const
+  { return const_cast<gzfilebuf*>(&sb); }
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() { return sb.is_open(); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+   *
+   *  Stream will be in state good() if file opens successfully;
+   *  otherwise in state fail(). This differs from the behavior of
+   *  ifstream, which never sets the state to good() and therefore
+   *  won't allow you to reuse the stream for a second file unless
+   *  you manually clear() the state. The choice is a matter of
+   *  convenience.
+  */
+  void
+  open(const char* name,
+       std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+   *
+   *  Stream will be in state good() if attach succeeded; otherwise
+   *  in state fail().
+  */
+  void
+  attach(int fd,
+         std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Close gzipped file.
+   *
+   *  Stream will be in state fail() if close failed.
+  */
+  void
+  close();
+
+private:
+  /**
+   *  Underlying stream buffer.
+  */
+  gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file output stream class.
+ *
+ *  This class implements ofstream for gzipped files. Seeking and putback
+ *  is not supported yet.
+*/
+class gzofstream : public std::ostream
+{
+public:
+  //  Default constructor
+  gzofstream();
+
+  /**
+   *  @brief  Construct stream on gzipped file to be opened.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+  */
+  explicit
+  gzofstream(const char* name,
+             std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Construct stream on already open gzipped file.
+   *  @param  fd    File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+  */
+  explicit
+  gzofstream(int fd,
+             std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  Obtain underlying stream buffer.
+  */
+  gzfilebuf*
+  rdbuf() const
+  { return const_cast<gzfilebuf*>(&sb); }
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() { return sb.is_open(); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+   *
+   *  Stream will be in state good() if file opens successfully;
+   *  otherwise in state fail(). This differs from the behavior of
+   *  ofstream, which never sets the state to good() and therefore
+   *  won't allow you to reuse the stream for a second file unless
+   *  you manually clear() the state. The choice is a matter of
+   *  convenience.
+  */
+  void
+  open(const char* name,
+       std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+   *
+   *  Stream will be in state good() if attach succeeded; otherwise
+   *  in state fail().
+  */
+  void
+  attach(int fd,
+         std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Close gzipped file.
+   *
+   *  Stream will be in state fail() if close failed.
+  */
+  void
+  close();
+
+private:
+  /**
+   *  Underlying stream buffer.
+  */
+  gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file output stream manipulator class.
+ *
+ *  This class defines a two-argument manipulator for gzofstream. It is used
+ *  as base for the setcompression(int,int) manipulator.
+*/
+template<typename T1, typename T2>
+  class gzomanip2
+  {
+  public:
+    // Allows insertor to peek at internals
+    template <typename Ta, typename Tb>
+      friend gzofstream&
+      operator<<(gzofstream&,
+                 const gzomanip2<Ta,Tb>&);
+
+    // Constructor
+    gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
+              T1 v1,
+              T2 v2);
+  private:
+    // Underlying manipulator function
+    gzofstream&
+    (*func)(gzofstream&, T1, T2);
+
+    // Arguments for manipulator function
+    T1 val1;
+    T2 val2;
+  };
+
+/*****************************************************************************/
+
+// Manipulator function thunks through to stream buffer
+inline gzofstream&
+setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
+{
+  (gzs.rdbuf())->setcompression(l, s);
+  return gzs;
+}
+
+// Manipulator constructor stores arguments
+template<typename T1, typename T2>
+  inline
+  gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
+                              T1 v1,
+                              T2 v2)
+  : func(f), val1(v1), val2(v2)
+  { }
+
+// Insertor applies underlying manipulator function to stream
+template<typename T1, typename T2>
+  inline gzofstream&
+  operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
+  { return (*m.func)(s, m.val1, m.val2); }
+
+// Insert this onto stream to simplify setting of compression level
+inline gzomanip2<int,int>
+setcompression(int l, int s = Z_DEFAULT_STRATEGY)
+{ return gzomanip2<int,int>(&setcompression, l, s); }
+
+#endif // HAVE_ZLIB
+
+#endif // ZFSTREAM_H
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/test/ChangeLog b/test/ChangeLog
new file mode 100644
index 0000000..4752aff
--- /dev/null
+++ b/test/ChangeLog
@@ -0,0 +1,668 @@
+2010-01-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.4 released.
+
+	2009-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.3 released.
+
+	2009-07-21  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.2 released.
+
+2009-06-22  Jaroslav Hajek  <highegg at gmail.com>
+
+	* test_null_assign.m: Fix test.
+
+	2009-05-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	Version 3.2.0 released.
+
+2009-04-17  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* test_struct.m: Add tests to prevent regression of bug with
+	indexed assignment into empty struct array.
+
+2009-04-15  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* test_struct.m: Add tests for lazy copying in nested assignments
+	of struct elements.
+
+2009-04-12  Thorsten Meyer  <thorsten.meyier at gmx.de>
+
+	* test_contin.m, test_error.m, test_eval-catch.m, test_for.m,
+        test_global.m,  test_if.m, test_index-wfi-f.m,
+        /test_index-wfi-t.m, test_io.m, test_logical-wfi-f.m,
+        test_logical-wfi-t.m, test_prefer.m, test_recursion.m,
+        test_return.m, test_string.m, test_struct.m, test_switch.m,
+        test_system.m, test_transpose.m, test_try.m, test_unwind.m,
+        test_while.m: Remove obsolete comments.
+
+2009-04-07  Carlo de Falco  <kingcrimson at tiscali.it>
+
+	* test_io.m: Add a test for saving and reading a matrix with the
+	"-ascii" format.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* test_diag_perm.m: Add tests for permuting sparse matrices and
+	for the correct types from interactions between
+	pseudo-scalars (1x1 matrices).
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* build_sparse_tests.sh: Add LU tests to the rectangular tests.
+
+2009-03-10  Jason Riedy  <jason at acm.org>
+
+	* test_diag_perm.m: Add a test for conversion to sparse form.
+
+2009-03-09  Jason Riedy  <jason at acm.org>
+
+	* test_diag_perm.m: Add tests for diag + sparse.
+
+2009-03-08  Jason Riedy  <jason at acm.org>
+
+	* test_diag_perm.m: Add tests for inverse scaling and sparse structure.
+
+2009-03-08  Jason Riedy  <jason at acm.org>
+
+	* test_diag_perm.m: Add tests for preserving sparse structure when scaling.
+
+2009-02-25  John W. Eaton  <jwe at octave.org>
+
+	* build_sparse_tests.sh: Note that saving sparse matrices to MAT
+	files fails when using 64-bit indexing.
+
+2009-02-22  John W. Eaton  <jwe at octave.org>
+
+	* build_sparse_tests.sh: Fix diag matrix divide by zero test.
+
+2009-02-18  John W. Eaton  <jwe at octave.org>
+
+	* test_args.m: Don't use assert to test for function handles.
+
+2009-02-15  John W. Eaton  <jwe at octave.org>
+
+	* test_io.m, test_prefer.m: Avoid command-style function call
+	syntax when assigning results.
+
+2009-02-09  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m (hastests): Error if fopen fails.
+
+2009-01-29  John W. Eaton  <jwe at octave.org>
+
+	* test_system.m: Use isfield instead of struct_contains.
+
+2009-01-25  Thorsten Meyer  <thorsten at hexe>
+
+	* test_struct.m: Add struct array tests.
+
+2009-01-23  Søren Hauberg  <hauberg at gmail.com>
+
+	* test_prefer.m: Update to match new API of the 'type' function.
+
+2008-12-24  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m (hastests): Use fread instead of fscanf to preserve
+	whitespace.
+
+2008-12-02  Jaroslav Hajek  <highegg at gmail.com>
+
+	* build_sparse_tests.sh: Fix test.
+
+2008-10-28  Jaroslav Hajek <highegg at gmail.com>
+
+	* test_logical-wfi-f.m: Fix error messages.
+	* test_logical-wfi-t.m: Fix error messages.
+	* test_slice.m: Fix error messages.
+
+2008-09-26  Jaroslav Hajek  <highegg at gmail.com>
+
+	* test_null_assign.m: More test for null assignments.
+
+2008-09-18  Jaroslav Hajek  <highegg at gmail.com>
+
+	* test_null_assign.m: New tests.
+
+2008-06-11  John W. Eaton  <jwe at octave.org>
+
+	* test_error.m: Fix tests for usage.
+	* test_eval-catch.m, test_try.m: Fix expected output from lasterr.
+
+2008-06-02  David Bateman  <dbateman at free.fr>
+
+	* test_arith.m: Delete and move tests close to function
+	definitions.
+	* test_func.m: Also test for single precision return values.
+
+	* test_infnan.m, test_linalg.m, test_matrix.m, test_number.m):
+	Delet and move tests close to function definitions.
+	* test_range.m: Also test single precision examples.
+
+2008-05-19  Bill Denney  <bill at denney.ws>
+
+	* test_args.m: Update format to allow running "test test_args" 
+	and add default argument tests.
+
+2008-05-09  Rafael Laboissiere <rafael at debian.org>
+
+	* test_io.m, test_system.m: Use ischar instead of deprecated isstr.
+
+2008-05-06  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m: Use puts instead of printf where appropriate.
+	Fix missing newline in message.
+
+2008-03-26  David Bateman  <dbateman at free.fr>
+
+	* test_index-wfi-f.m: Split large block of tests.  New tests.
+
+2008-03-26  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m (report_files_with_no_tests): New function.
+	Use it to report number of .m and .cc files without tests separately.
+
+2008-03-25  John W. Eaton  <jwe at octave.org>
+
+	* test_index-wfi-f.m: New tests.
+
+2008-03-25  Jaroslav Hajek  <highegg at gmail.com>
+
+	* test_io.m: Add test for save with -struct modifier.
+
+2008-03-20  David Bateman  <dbateman at free.fr>
+
+	* test_func.m: Modify to test for char, cell and structure arrays.
+
+	* test_func.m: New test code that ensures that all operations
+	which work on dimensions alone (squeeze, triu, etc.) work for all
+	objects and preserve type.
+
+2008-04-09  Michael Goffioul  <michael.goffioul at gmail.com>
+
+	* test_string.m: Fix isprint test under Win32, where
+	isprint(setstr(9)) is true.
+	* test_system.m: Add condition for various syscall tests. Make cd test
+	able to deal with drive-letter-only pathnames (e.g. C:\) under Win32.
+
+2008-03-07  John W. Eaton  <jwe at octave.org>
+
+	* test_logical-wfi-t.m, test_logical-wfi-f.m: Update tests for
+	logical indexing bug fix.
+
+2008-03-06  John W. Eaton  <jwe at octave.org>
+
+	* test_eval.m, test_diffeq.m, test_quad.m, test_signal.m:
+	Delete files with no tests.
+
+2008-02-25  Ben Abbott <bpabbott at mac.com>
+
+	* test_eval-catch.m, test_io.m, test_try.m: Use cstrcat instead of
+	strcat.
+
+2008-02-22  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: Replaced removed sparse functions like
+	spdiag with their generic names. Fix lu tests for modified
+	syntax. Test vector and scaling or LU and chol functions. 
+	* test_linalg.m: Change error message of failing chol/lu test.
+
+2008-02-19  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: Replaced removed spars functions like
+	spmin, with their  generic names.
+
+2008-01-22  John W. Eaton  <jwe at octave.org>
+
+	* test_poly.m, test_set.m, test_stats.m: Delete files with no tests.
+
+2008-01-22  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* test_linalg.m, test_matrix.m, test_number.m, test_poly.m,
+	test_signal.m, test_stats.m, test_string.m, test_system.m: 
+	Move tests to individual source files.
+
+2008-01-15  Thomas Weber  <thomas.weber.mail at gmail.com>
+
+	* test_arith.m: Move tests to source files.
+
+2008-01-15  John W. Eaton  <jwe at octave.org>
+
+	* test_audio.m, test_control.m, test_image.m, test_optim.m,
+	test_plot.m, test_unix.m: Delete files with no tests.
+
+2007-12-21  John W. Eaton  <jwe at octave.org>
+
+	Version 3.0.0 released.
+
+2007-12-18  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: Add tests for indexing like a([1,1],:),
+	a(:,[1,1]) and sparse(42)([1,1]).
+
+2007-12-11  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: Drop argument to Fsparse to force mutation.
+	* test_range.m: Ditto.
+
+2007-12-10  John W. Eaton  <jwe at octave.org>
+
+	* test_nonlin.m: Delete.
+
+2007-12-03  David Bateman  <dbateman at free.fr>
+
+	* fntests.m: Also count the skipped tests.
+	* build_sparse_tests.sh: As appropriate make tests conditional on
+	HAVE_UMFPACK, HAVE_CHOLMOD and HAVE_CXSPARSE.
+
+2007-11-26  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: More care with sparse return values.
+
+2007-10-30  Kim Hansen  <kimhanse at gmail.com>
+
+	* build_sparse_tests.sh: Fix typo.
+
+2007-10-23  John W. Eaton  <jwe at octave.org>
+
+	* build_sparse_tests.sh (gen_sparsesparse_elementop_tests):
+	Use xtest for "assert(as./bs,sparse(af./bf,true),100*eps);" test.
+
+2007-10-12  John W. Eaton  <jwe at octave.org>
+
+	* Change copyright notices in all files that are part of Octave to
+	GPLv3 or any later version.
+
+2007-10-06  John W. Eaton  <jwe at octave.org>
+
+	* test_poly.m: Move residue test to residue.m.
+
+2007-09-29  Kim Hansen  <kimhanse at gmail.com>
+
+	* test_range.m: Test range data
+
+2007-09-21  John W. Eaton  <jwe at octave.org>
+
+	* test_slice.m: Fix test for x = ones ([0, 2]); x(idx) = N case.
+	See change for liboctave/Array.cc.
+
+2007-06-15  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m: Also report expected failures in summary.
+	Improved wording from Thomas Weber <thomas.weber.mail at gmail.com>.
+
+2007-06-06  John W. Eaton  <jwe at octave.org>
+
+	* test_signal.m: Rename internal assert function to xassert.
+
+2007-04-26  David Bateman  <dbateman at free.fr>
+
+	* test_for.m: Add tests for multi-dimensional matrices and cell
+	arrays.
+
+2007-04-04  Rafael Laboissiere  <rafael at debian.org>
+
+	* Makefile.in (clean): Also remove a.wav file created by
+	testing wavwrite.m.
+
+2007-04-03  Kim Hansen  <kimhanse at gmail.com>
+
+	* test_slice.m: New file.
+
+2007-03-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (dist): Use ln, not $(LN_S).
+
+2007-02-26  From Michael Goffioul  <michael.goffioul at swing.be>
+
+	* Makefile.in: Use $(LN_S) instead of ln or ln -s.
+
+2007-02-20  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (check): Use --norc instead of --no-site-file.
+	From: Alex Zvoleff  <azvoleff at ucsd.edu>
+
+2007-02-19  John W. Eaton  <jwe at octave.org>
+
+	* test_system.m: Handle confirm_recursive_rmdir as function
+	instead of built-in variable.
+
+2007-02-07  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m: Add plea for help writing tests.
+
+2007-01-11  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m: Also handle scripts directory in the build tree.
+
+	* Makefile.in (OCTAVE_SCRIPT_PATH): Delete unused variable.
+
+2006-11-14  Luis F. Ortiz  <lortiz at interactivesupercomputing.com>
+
+	* fntests.m: Include liboctave in the list of directories to test.
+
+2006-08-25  John W. Eaton  <jwe at octave.org>
+
+	* test_io.m (testls): Allow for small variance in loaded values
+	for text data formats.  Use persistent local variables instead of
+	resetting rand seed.
+
+2006-08-22  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: Don't force conversion to sparse boolean
+	return type for string mapper functions.
+
+2006-08-21  John W. Eaton  <jwe at octave.org>
+
+	* test_io.m: Use isequal (a, b) instead of a != b.  Use isequal
+	for struct and cell tests instead of more complex constructs.
+
+2006-06-27  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (distclean): Also remove test_sparse.m.
+
+2006-06-07  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m: Keep track of files with tests and report total.
+
+2006-06-01  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m (print_test_file_name, print_pass_fail): New functions.
+	(runtestdir, runtestscript): Use them.  Print info for each file
+	with tests.  Print info about files without tests to log file.
+	(run_test_dir): Rename from runtestdir.  Change all uses.
+	(run_test_script): Rename from runtestscript.  Change all uses.
+	Handle page_screen_output as a function instead of a built-in
+	variable.
+
+2006-05-04  John W. Eaton  <jwe at octave.org>
+
+	* test_prefer.m: Adjust tests for eliminated built-in variables.
+
+2006-04-29  John W. Eaton  <jwe at octave.org>
+
+	* Makefile.in (check): Use run-octave script.
+
+2006-04-28  John W. Eaton  <jwe at octave.org>
+
+	* test_prefer.m: Adjust tests for new way of handling warning state.
+	* build_sparse_tests.sh: Likewise.
+
+2006-04-11  John W. Eaton  <jwe at octave.org>
+
+	* test_system.m, test_struct.m, test_string.m, test_quad.m,
+	test_number.m, test_nonlin.m, test_matrix.m, test_linalg.m,
+	test_io.m, test_diffeq.m, test_arith.m: Update for new usage
+	message format.
+
+2006-04-03  David Bateman  <dbateman at free.fr>
+
+	* test_number.m: Reverse sense of isscalar and isvector tests
+          for recent changes.
+
+2006-03-21  John W. Eaton  <jwe at octave.org>
+
+	* test_system.m: Use cell arrays of character strings in fnmatch
+	tests.
+
+2006-03-16  John W. Eaton  <jwe at octave.org>
+
+	* test_system.m: End all *pwent tests with a call to endpwent.
+	End all *grent tests with a call to endgrent.
+
+2006-03-14  John W. Eaton  <jwe at octave.org>
+
+	* fntests.m: Prettier printing of output.
+	* test_eval.m: Disable chatty tests.
+
+2006-03-08  David Bateman  <dbateman at free.fr>
+
+	* test_system.m: Fix recursive rmdir test for recent change.
+
+2006-02-20  David Bateman  <dbateman at free.fr>
+
+	* build_spase_tests.sh: Add tests for ldiv tests for rectangular
+	diagonal, permuted diagonal, triangular and permuted triangular
+	matrices.
+
+2006-02-09  David Bateman  <dbateman at free.fr>
+
+        * build_sparse_tests.sh: Add tests for sparse QR solvers.
+
+2006-01-21  David Bateman  <dbateman at free.fr>
+
+        * build_sparsetest.sh: Add new un-ordered indexing, assignment and
+        deletion tests.
+
+2006-01-13  Bill Denney  <bill at givebillmoney.com>
+
+	* test_system.m: Use filesep instead of "/" where needed.
+
+2005-12-14  David Bateman  <dbateman at free.fr>
+
+	* build_sparse_tests.sh: New script to build sparse matrix tests.
+	* fntests.m: New script to run the octave test code, with "make check".
+	* Makefile.in (DISTDIRS): Delete.
+	(dist): Simplify.
+	(OCTAVE_SCRIPT_PATH): Include . and $(srcdir).
+	(check): Run tests with fntest.m instead of runtest.
+	(test_sparse.m): New target.
+	(clean): Remove fntests.log instead of octave.log and octave.sum.
+	
+	* tests/test_args.m, tests/test_infnan.m, tests/test_set.m,
+	tests/test_arith.m, tests/test_io.m, tests/test_signal.m,
+	tests/test_audio.m, tests/test_linalg.m, tests/test_sparse.m,
+	tests/test_contin.m, tests/test_logical-wfi-f.m, tests/test_stats.m,
+	tests/test_control.m, tests/test_logical-wfi-t.m, tests/test_string.m,
+	tests/test_diffeq.m, tests/test_matrix.m, tests/test_struct.m,
+	tests/test_error.m, tests/test_nonlin.m, tests/test_switch.m,
+	tests/test_eval-catch.m, tests/test_number.m, tests/test_system.m,
+	tests/test_eval.m, tests/test_optim.m, tests/test_transpose.m,
+	tests/test_for.m, tests/test_plot.m, tests/test_try.m,
+	tests/test_global.m, tests/test_poly.m, tests/test_unix.m,
+	tests/test_if.m, tests/test_prefer.m, tests/test_unwind.m,
+	tests/test_image.m, tests/test_quad.m, tests/test_while.m,
+	tests/test_index-wfi-f.m, tests/test_recursion.m,
+	tests/test_index-wfi-t.m, tests/test_return.m: Initial of conversion 
+	of DejaGnu tests to test/assert infrastructure.
+
+2005-05-11  John W. Eaton  <jwe at octave.org>
+
+	* config/unix.exp: Start Octave with -H.
+
+2002-10-31  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/arith/prod-4.m, octave.test/arith/sum-4.m:
+	Cover more cases for empty matrices.
+
+2002-10-15  Paul Kienzle <pkienzle at users.sf.net>
+
+	* Makefile.in: Use @library_path_var@ instead of LD_LIBRARY_PATH.
+
+2002-09-27  Paul Kienzle <pkienzle at users.sf.net>
+
+	* qr-7.m: Remove randomness from complex matrix generator.
+	Increase tolerance on rosser matrix test.
+
+2002-09-26  Paul Kienzle <pkienzle at users.sf.net>
+
+	* octave.test/linalg/qr-7.m: Replace large random matrix tests 
+	of economy QR decomposition with small predictable tests.
+	Include numerically sensitive rosser matrix test.  Don't
+	report the measured norms. 
+
+2002-04-24  Bill Lash  <lash at tellabs.com>
+
+	* test/octave.test/signal/signal.exp: Add unwrap test.
+	* test/octave.test/signal/unwrap-1.m: New file.
+
+2002-04-24  David Billinghurst <David.Billinghurst at riotinto.com.au>
+
+	* octave.test/signal/signal.exp: Add tests for fft, ifft
+	fft2, ifft2 and detrend.
+	* octave.test/signal/detrend-1.m: New test.
+	* octave.test/signal/detrend-2.m: New test.
+	* octave.test/signal/detrend-3.m: New test.
+	* octave.test/signal/fft-1.m: New test.
+	* octave.test/signal/ifft-1.m: New test.
+	* octave.test/signal/fft2-1.m: New test.
+	* octave.test/signal/ifft2-1.m: New test.
+
+2002-04-22  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/diffeq/dassl-1.m (tol): Use relative tolerance for test. 
+	* octave.test/diffeq/dassl-2.m (tol): Likewise.
+	* octave.test/diffeq/lsode-1.m (tol): Likewise.
+	* octave.test/diffeq/lsode-2.m (tol): Likewise.
+	* octave.test/diffeq/lsode-3.m (tol): Likewise.
+
+2002-04-12  Kienzle <pkienzle at jazz.ncnr.nist.gov>
+
+	* config/unix.exp: Allow running of individual tests with
+	"runtest *.exp" from any of the directories under test/octave.test.
+
+2002-04-02  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/linalg/qr-7.m: New test.
+	From Paul Kienzle <pkienzle at jazz.ncnr.nist.gov>.
+	
+2001-04-24  Christoph Spiel <cspiel at hammersmith-consulting.com>
+
+	* Makefile.in (check): Allow user to specify which .exp file to run.
+	* octave.test/try, octave.test/eval-catch: New directories and tests.
+
+2000-06-07  Ben Sapp <bsapp at nua.lampf.lanl.gov>
+
+	* octave.test/quad/quad-1.m: Use absolute value of difference
+	from expected value when comparing with sqrt (eps).  Potential
+	problems like this were noticed by Przemek Klosowski
+	<przemek at rrdjazz.nist.gov>.
+	* octave.test/quad/quad-2.m: Likewise.
+	* octave.test/arith/exp-1.m: Likewise.
+	* octave.test/linalg/cond-1.m: Likewise.
+	* octave.test/linalg/eig-1.m: Likewise.
+	* octave.test/linalg/eig-2.m: Likewise.
+	* octave.test/linalg/inv-1.m: Likewise.
+	* octave.test/linalg/lu-2.m: Likewise.
+	* octave.test/linalg/svd-2.m: Likewise.
+	* octave.test/linalg/svd-10.m: Likewise.
+
+1999-10-29  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/system/mktime-1.m (t): Compare whole seconds only.
+
+Fri Dec  4 20:55:47 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/system/clock-1.m: Use standard format specifiers %d
+	and %H instead of %e and %k.
+
+Fri Oct 23 15:53:01 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/arith/exp-5.m: New test.
+
+	* octave.test/stats/mean-3.m: New version of mean accepts a second
+	optional arg.
+
+	* octave.test/system/date-1.m: Correct test for new Y2K-compliant
+	date function.
+
+Wed May 27 00:38:27 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/diffeq/dassl-1.m, octave.test/diffeq/dassl-2.m,
+	octave.test/diffeq/lsode-1.m: New tests, from David Billinghurst
+	<David.Billinghurst at riotinto.com.au>.
+
+	* octave.test/diffeq/lsode-2.m, octave.test/diffeq/lsode-3.m:
+ 	New tests, from Peter Hopfgartner <phopfgartner at memc.inet.it>.
+
+Thu Apr 23 01:45:16 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in: If $(SHARED_LIBS), set LD_LIBRARY_PATH for running
+	Octave before installation is complete.
+
+Wed Apr 15 15:23:43 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/index/dfi-f/m-2.m, octave.test/index/dfi-f/index.exp:
+	Expect this test to succed now.
+
+Thu Mar  5 20:35:26 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/system/gmtime-1.m, octave.test/system/localtime-1.m:
+	Not all systems have time zone info in the struct.
+
+Mon Mar  2 14:36:50 1998  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/io/binary-io-1.m (id): Use binary flag in fopen call.
+
+Wed Apr  2 21:59:15 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/prefer/prefer.exp: Delete prefer-36 and prefer-37.
+	* octave.test/prefer/prefer-36.m, octave.test/prefer/prefer-37.m:
+	Delete test files.
+
+Wed Mar 12 16:56:41 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (install-strip): New target.
+
+Sat Mar  1 15:23:14 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.5 released.
+
+Thu Feb 20 02:58:05 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.4 released.
+
+Tue Feb 18 09:22:04 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.3 released.
+
+Mon Jan 27 15:51:58 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.2 released.
+
+Thu Jan 23 13:48:19 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* octave.test/unwind/unwind-2.m: Scripts now stop executing when
+	errors are encountered.
+
+	* octave.test/return/return.exp: Return at top level is no longer
+	an error.
+
+Tue Jan  7 00:16:23 1997  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0.1 released.
+
+Tue Dec 10 01:43:05 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 2.0 released.
+
+Fri Dec  6 15:23:39 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.94.
+
+Wed Nov 20 01:00:02 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.93.
+
+Thu Nov 14 00:05:57 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.92
+
+Thu Nov  7 12:43:03 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.91.
+
+Wed Oct 30 17:19:12 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Version 1.90.
+
+	* Makefile.in (DISTFILES): Add ChangeLog.
+
+Fri Feb  9 21:40:49 1996  John W. Eaton  <jwe at bevo.che.wisc.edu>
+
+	* Makefile.in (OCTAVE_SCRIPT_PATH): Add ../src directory (for .oct
+	files) and current directory (why not?).
+
+See ChangeLog.1 in the top level directory for earlier changes.
diff --git a/test/Makefile.in b/test/Makefile.in
new file mode 100644
index 0000000..6925cd1
--- /dev/null
+++ b/test/Makefile.in
@@ -0,0 +1,86 @@
+# Makefile for octave's test directory
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2006, 2007
+#               John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ..
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+include $(TOPDIR)/Makeconf
+
+SOURCES = $(wildcard $(srcdir)/test_*.m)
+
+DISTFILES = $(addprefix $(srcdir)/, ChangeLog Makefile.in \
+	build_sparse_tests.sh fntests.m) $(SOURCES)
+
+OCTAVE_BINARY = ../src/octave
+
+ifeq ($(SHARED_LIBS), true)
+  OCTAVE_LD_LIBRARY_PATH = `pwd`/../src:`pwd`/../liboctave:`pwd`/../libcruft
+  ifeq ($(@library_path_var@),)
+    XLD_LIBRARY_PATH = $(OCTAVE_LD_LIBRARY_PATH)
+  else
+    XLD_LIBRARY_PATH = $(OCTAVE_LD_LIBRARY_PATH):$(@library_path_var@)
+  endif
+  SET_LD_LIBRARY_PATH = @library_path_var@="$(XLD_LIBRARY_PATH)"
+endif
+
+all: check
+.PHONY: all
+
+check: test_sparse.m
+	../run-octave --norc --silent --no-history $(srcdir)/fntests.m $(srcdir)
+.PHONY: check
+
+test_sparse.m: build_sparse_tests.sh
+	$(srcdir)/build_sparse_tests.sh
+
+install install-strip: all
+.PHONY: install install-strip
+
+uninstall:
+.PHONY: uninstall
+
+tags: $(SOURCES)
+	ctags $(SOURCES)
+
+TAGS: $(SOURCES)
+	etags $(SOURCES)
+
+clean:
+	rm -f fntests.log a.wav
+.PHONY: clean
+
+mostlyclean:
+.PHONY: mostlyclean
+
+distclean: clean
+	rm -f Makefile test_sparse.m
+.PHONY: distclean
+
+maintainer-clean: distclean
+	rm -f tags TAGS
+.PHONY: maintainer-clean
+
+dist:
+	ln $(DISTFILES) ../`cat ../.fname`/test
+.PHONY: dist
diff --git a/test/build_sparse_tests.sh b/test/build_sparse_tests.sh
new file mode 100755
index 0000000..feff6ae
--- /dev/null
+++ b/test/build_sparse_tests.sh
@@ -0,0 +1,1295 @@
+#!/bin/sh
+
+# Copyright (C) 2006, 2007, 2008, 2009 David Bateman
+#
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Some tests are commented out because they are known to be broken!
+# Search for "# fails"   
+
+# ./buildtest.sh preset
+#    creates test_sparse.m with preset tests.
+#    Use "test test_sparse" from octave to run the tests.
+#
+# ./buildtest.sh random
+#    Creates test_sprandom.m with randomly generated matrices.
+
+# buildtest.sh generates tests for real and complex sparse matrices.
+# Also, we want to run both fixed tests with known outputs (quick tests)
+# and longer tests with unknown outputs (thorough tests).  This requires
+# two sets of tests --- one which uses preset matrices and another which
+# uses randomly generated matrices.
+#
+# The tests are mostly identical for each case but the code is different,
+# so it is important that the tests be run on all cases.  Because our test 
+# harness doesn't have support for looping or macros (it is only needed
+# for new data types), but sh does, we use sh to generate inline versions of
+# the tests for each case.
+#
+# Our 'macros' use shared variables as parameters.  This allows us to
+# for example define A complex and include all the unary ops tests, 
+# then set A=real(A) and include all the unary ops tests.  Thus the
+# same tests work for real and complex.  For binary tests it is even
+# more complicated because we want full X sparse, sparse X full and
+# sparse X sparse tested.
+#
+# We use the following macros:
+#
+#    gen_section
+#        place a separator in the test file
+#    gen_function
+#        define the function definion
+#    helper gen_specific
+#        specific tests such as error handling and null input
+#    helper gen_eat_zeros
+#        make sure sparse-scalar ops which generate 0 work
+#    gen_specific_tests
+#        specific and eat zeros tests 
+#    helper gen_ordering_tests
+#        ordered comparison operators for real valued tests
+#    helper gen_sparsesparse_ordering_tests
+#        ordered comparison operators for real valued sparse-sparse tests
+#    helper gen_elementop_tests
+#        element-wise matrix binary operators, including scalar-matrix ops.
+#        horizontal/vertical concatenation are here as well.
+#    helper gen_sparsesparse_elementop_tests
+#        element-wise matrix binary operators, for sparse-sparse ops.
+#        horizontal/vertical concatenation are here as well.
+#    helper gen_divop_tests
+#        left and right matrix division operators of rectangular matrices. 
+#        Needs QR solvers
+#    helper gen_square_divop_tests
+#        left and right matrix division operators of square matrices. 
+#    helper gen_matrixop_tests
+#        rectangular matrix binary operators: * 
+#    helper gen_matrixdiag_tests
+#        Tests extract of diag and creation of diagonal matrices using
+#        diag and spdiags functions
+#    helper gen_matrixreshape_tests
+#        Test the reshape function on sparse matrices
+#    helper print_mapper_test
+#        sub-helper function of gen_mapper_tests to print individual tests
+#    helper gen_mapper_tests
+#        Tests all of the one argument mapper functions. There are a few
+#        specific tests that abs, real and imag return real values.
+#    helper gen_unaryop_tests
+#        functions and operators which transform a single matrix
+#    helper gen_save_tests
+#        Tests the load/save functionality for ascii/binary and hdf5 formats
+#    gen_scalar_tests
+#        element ops for real and complex scalar and sparse
+#    gen_rectangular_tests
+#        unary, element, and matrix tests for a and full/sparse b
+#    gen_square_tests
+#        operations which require square matrices: lu, inv, \
+#        A square non-singular matrix is defined from the rectangular
+#        inputs A and B.
+#    gen_assembly_tests
+#        test for sparse constructors with 'sum' vs. 'unique'
+#    gen_select_tests
+#        indexing tests
+#    gen_solver_tests
+#        Tests the solve function with triangular/banded, etc matrices
+
+case $1 in
+    random) preset=false ;;
+    preset) preset=true ;;
+    '') preset=true ;;
+    *) echo "buildtest.sh random|preset" && exit 1 ;;
+esac
+
+if $preset; then
+    TESTS=test_sparse.m
+else
+    TESTS=test_sprandom.m
+fi
+
+# create initial file
+cat >$TESTS <<EOF
+## THIS IS AN AUTOMATICALLY GENERATED FILE --- DO NOT EDIT ---
+## instead modify build_sparse_tests.sh to generate the tests that you want.
+EOF
+
+
+# define all functions
+
+
+# =======================================================
+# Section separator
+
+gen_section() {
+cat >>$TESTS <<EOF
+
+# ==============================================================
+
+EOF
+}
+
+
+# =======================================================
+# Specific preset tests
+
+# =======================================================
+# If a sparse operation yields zeros, then those elements 
+# of the returned sparse matrix should be eaten.
+gen_eat_zeros() {
+cat >>$TESTS <<EOF
+%% Make sure newly introduced zeros get eaten
+%!assert(nnz(sparse([bf,bf,1]).^realmax),1);
+%!assert(nnz(sparse([1,bf,bf]).^realmax),1);
+%!assert(nnz(sparse([bf,bf,bf]).^realmax),0); 
+
+%!assert(nnz(sparse([bf;bf;1]).^realmax),1);
+%!assert(nnz(sparse([1;bf;bf]).^realmax),1);
+%!assert(nnz(sparse([0.5;bf;bf]).^realmax),0);
+
+%!assert(nnz(sparse([bf,bf,1])*realmin),1);
+%!assert(nnz(sparse([1,bf,bf])*realmin),1);
+%!assert(nnz(sparse([bf,bf,bf])*realmin),0);
+
+%!assert(nnz(sparse([bf;bf;1])*realmin),1);
+%!assert(nnz(sparse([1;bf;bf])*realmin),1);
+%!assert(nnz(sparse([bf;bf;bf])*realmin),0);
+
+EOF
+}
+
+gen_specific() {
+cat >>$TESTS <<EOF
+
+%!test # segfault test from edd at debian.org
+%! n = 510;
+%! sparse(kron((1:n)', ones(n,1)), kron(ones(n,1), (1:n)'), ones(n)); 
+
+%% segfault tests from Fabian at isas-berlin.de
+%% Note that the last four do not fail, but rather give a warning
+%% of a singular matrix, which is consistent with the full matrix
+%% behaviour. They are therefore disabled.. 
+%!testif HAVE_UMFPACK
+%! assert(inv(sparse([1,1;1,1+i])),sparse([1-1i,1i;1i,-1i]),10*eps);
+% !error inv( sparse( [1,1;1,1]   ) );
+% !error inv( sparse( [0,0;0,1]   ) );
+% !error inv( sparse( [0,0;0,1+i] ) );
+% !error inv( sparse( [0,0;0,0]   ) );
+
+%% error handling in constructor
+%!error sparse(1,[2,3],[1,2,3]);
+%!error sparse([1,1],[1,1],[1,2],3,3,"bogus");
+%!error sparse([1,3],[1,-4],[3,5],2,2);
+%!error sparse([1,3],[1,-4],[3,5i],2,2);
+%!error sparse(-1,-1,1);
+EOF
+}
+
+
+gen_specific_tests() {
+    gen_section
+    gen_specific
+    gen_section
+    echo '%!shared bf' >> $TESTS
+    echo '%!test bf=realmin;' >> $TESTS
+    gen_eat_zeros
+    echo '%!test bf=realmin+realmin*1i;' >> $TESTS
+    gen_eat_zeros
+    cat >>$TESTS <<EOF
+%!assert(nnz(sparse([-1,realmin,realmin]).^1.5),1);
+%!assert(nnz(sparse([-1,realmin,realmin,1]).^1.5),2);
+
+%!assert(nnz(sparse(1,1,0)),0); # Make sure scalar v==0 doesn't confuse matters
+%!assert(nnz(sparse(eye(3))*0),0);
+%!assert(nnz(sparse(eye(3))-sparse(eye(3))),0);
+
+%!test
+%! wdbz = warning ("query", "Octave:divide-by-zero");
+%! warning ("off", "Octave:divide-by-zero");
+%! assert(full(sparse(eye(3))/0),full(eye(3)/0));
+%! warning (wdbz.state, "Octave:divide-by-zero");
+
+EOF
+}
+
+
+# =======================================================
+# Main function definition
+
+gen_function() {
+    if $preset; then
+	cat >>$TESTS <<EOF
+##
+## test_sparse
+##
+##    run preset sparse tests.  All should pass.
+function [passes,tests] = test_sparse
+  disp("writing test output to sptest.log");
+  test("test_sparse","normal","sptest.log");
+endfunction
+
+EOF
+    else
+	cat >>$TESTS <<EOF
+##
+## test_sprandom
+##
+##  total_passes=0; total_tests=0;
+##  for i=1:10
+##     [passes,tests] = sprandomtest;
+##    total_passes += passes;
+##    total_tests += tests;
+##  end
+##  The test log is appended to sprandomtest.log
+function [passes,total] = test_sprandom
+  warning("untested --- fix the source in buildtests.sh");
+  disp("appending test output to sprandomtest.log");
+  fid = fopen("sprandomtest.log","at");
+  test("test_sprandom","normal",fid);
+  ##[passes, total] = test("sprandomtest","normal",fid);
+  fclose(fid);
+endfunction
+
+EOF
+    fi
+    
+}
+
+
+# =======================================================
+# matrix ops
+
+# test ordered comparisons: uses as,af,bs,bf
+gen_ordering_tests() {
+    cat >>$TESTS <<EOF
+%% real values can be ordered (uses as,af)
+%!assert(as<=bf,sparse(af<=bf))
+%!assert(bf<=as,sparse(bf<=af))
+
+%!assert(as>=bf,sparse(af>=bf))
+%!assert(bf>=as,sparse(bf>=af))
+
+%!assert(as<bf,sparse(af<bf))
+%!assert(bf<as,sparse(bf<af))
+
+%!assert(as>bf,sparse(af>bf))
+%!assert(bf>as,sparse(bf>af))
+
+EOF
+}
+
+gen_sparsesparse_ordering_tests() {
+    cat >>$TESTS <<EOF
+%!assert(as<=bs,sparse(af<=bf))
+%!assert(as>=bs,sparse(af>=bf))
+%!assert(as<bs,sparse(af<bf))
+%!assert(as>bs,sparse(af>bf))
+EOF
+}
+
+# test element-wise binary operations: uses as,af,bs,bf,scalar
+gen_elementop_tests() {
+    cat >>$TESTS <<EOF
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+EOF
+}
+
+gen_sparsesparse_elementop_tests() {
+    cat >>$TESTS <<EOF
+%!assert(as==bs,sparse(af==bf))
+%!assert(as!=bs,sparse(af!=bf))
+%!assert(as+bs,sparse(af+bf))
+%!assert(as-bs,sparse(af-bf))
+%!assert(as.*bs,sparse(af.*bf))
+%!xtest assert(as./bs,sparse(af./bf),100*eps);
+%!test
+%! sv = as.^bs;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+EOF
+}
+
+# test matrix-matrix left and right division: uses as,af,bs,bf
+gen_divop_tests() {
+    cat >>$TESTS <<EOF
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as/bf,af/bf,100*eps)
+%!assert(af/bs,af/bf,100*eps)
+%!assert(as/bs,sparse(af/bf),100*eps)
+%!assert(bs\af',bf\af',100*eps)
+%!assert(bf\as',bf\af',100*eps)
+%!assert(bs\as',sparse(bf\af'),100*eps)
+
+EOF
+}
+
+# test matrix-matrix left and right division: uses as,af,bs,bf
+gen_square_divop_tests() {
+    cat >>$TESTS <<EOF
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as/bf,af/bf,100*eps)
+%!assert(af/bs,af/bf,100*eps)
+%!assert(as/bs,sparse(af/bf),100*eps)
+%!assert(bs\af',bf\af',100*eps)
+%!assert(bf\as',bf\af',100*eps)
+%!assert(bs\as',sparse(bf\af'),100*eps)
+
+EOF
+}
+
+# test matrix-matrix operations: uses as,af,bs,bf
+gen_matrixop_tests() {
+    cat >>$TESTS <<EOF
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as*bf',af*bf')
+%!assert(af*bs',af*bf')
+%!assert(as*bs',sparse(af*bf'))
+
+EOF
+}
+
+# test diagonal operations
+gen_matrixdiag_tests() {
+    cat >>$TESTS <<EOF
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(diag(as),sparse(diag(af)))
+%!assert(diag(bs),sparse(diag(bf)))
+%!assert(diag(as,1),sparse(diag(af,1)))
+%!assert(diag(bs,1),sparse(diag(bf,1)))
+%!assert(diag(as,-1),sparse(diag(af,-1)))
+%!assert(diag(bs,-1),sparse(diag(bf,-1)))
+%!assert(diag(as(:)),sparse(diag(af(:))))
+%!assert(diag(as(:),1),sparse(diag(af(:),1)))
+%!assert(diag(as(:),-1),sparse(diag(af(:),-1)))
+%!assert(diag(as(:)'),sparse(diag(af(:)')))
+%!assert(diag(as(:)',1),sparse(diag(af(:)',1)))
+%!assert(diag(as(:)',-1),sparse(diag(af(:)',-1)))
+%!assert(spdiags(as,[0,1]),[diag(af,0),diag(af,1)])
+%!test [tb,tc]=spdiags(as); 
+%! assert(spdiags(tb,tc,sparse(zeros(size(as)))),as)
+%! assert(spdiags(tb,tc,size(as,1),size(as,2)),as)
+
+EOF
+}
+
+# test matrix reshape operations
+gen_matrixreshape_tests() {
+    cat >>$TESTS <<EOF
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(reshape(as,1,prod(size(as))),sparse(reshape(af,1,prod(size(af)))))
+%!assert(reshape(as,prod(size(as)),1),sparse(reshape(af,prod(size(af)),1)))
+%!assert(reshape(as,fliplr(size(as))),sparse(reshape(af,fliplr(size(af)))))
+%!assert(reshape(bs,1,prod(size(as))),sparse(reshape(bf,1,prod(size(af)))))
+%!assert(reshape(bs,prod(size(as)),1),sparse(reshape(bf,prod(size(af)),1)))
+%!assert(reshape(bs,fliplr(size(as))),sparse(reshape(bf,fliplr(size(af)))))
+
+EOF
+}
+
+# test mapper matrix operations: uses as,af
+print_mapper_test() {
+echo "%!assert($1(as),sparse($1(af)))" >>$TESTS
+}
+
+print_real_mapper_test() {
+    cat >>$TESTS <<EOF
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if ($2)
+%!     assert($1(as),sparse($1(af)))
+%!   else
+%!     assert($1(as),$1(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+EOF
+}
+
+gen_mapper_tests() {
+echo "%% Unary matrix tests (uses af,as)">>$TESTS
+print_mapper_test abs
+print_mapper_test acos
+print_mapper_test acosh
+print_mapper_test angle
+print_mapper_test arg
+print_mapper_test asin
+print_mapper_test asinh
+print_mapper_test atan
+print_mapper_test atanh
+print_mapper_test ceil
+print_mapper_test conj
+print_mapper_test cos
+print_mapper_test cosh
+print_mapper_test exp
+print_mapper_test finite
+print_mapper_test fix
+print_mapper_test floor
+print_mapper_test imag
+print_mapper_test isinf
+print_mapper_test isna
+print_mapper_test isnan
+print_mapper_test log
+#print_mapper_test log10   ## fails with different NaN, not a problem
+print_mapper_test real
+print_mapper_test round
+print_mapper_test sign
+print_mapper_test sin
+print_mapper_test sinh
+print_mapper_test sqrt
+print_mapper_test tan
+print_mapper_test tanh
+
+# Specific tests for certain mapper functions
+    cat >>$TESTS <<EOF
+%!assert(issparse(abs(as))&&isreal(abs(as)))
+%!assert(issparse(real(as))&&isreal(real(as)))
+%!assert(issparse(imag(as))&&isreal(imag(as)))
+
+EOF
+}
+
+gen_real_mapper_tests() {
+echo "%% Unary matrix tests (uses af,as)">>$TESTS
+print_real_mapper_test erf 1
+print_real_mapper_test erfc 1
+#print_real_mapper_test gamma 1
+print_real_mapper_test isalnum 0
+print_real_mapper_test isalpha 0
+print_real_mapper_test isascii 0
+print_real_mapper_test iscntrl 0
+print_real_mapper_test isdigit 0
+print_real_mapper_test isgraph 0
+print_real_mapper_test islower 0
+print_real_mapper_test isprint 0
+print_real_mapper_test ispunct 0
+print_real_mapper_test isspace 0
+print_real_mapper_test isupper 0
+print_real_mapper_test isxdigit 0
+#print_real_mapper_test lgamma 1
+
+# Specific tests for certain mapper functions
+    cat >>$TESTS <<EOF
+
+%% These mapper functions always return a full matrix
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!    assert(toascii(as),toascii(af))
+%!    assert(tolower(as),tolower(af))
+%!    assert(toupper(as),toupper(af))
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+EOF
+}
+
+# test matrix operations: uses as,af
+gen_unaryop_tests() {
+    cat >>$TESTS <<EOF
+%% Unary matrix tests (uses af,as)
+%!assert(issparse(as))
+%!assert(!issparse(af))
+%!assert(!(issparse(af)&&iscomplex(af)))
+%!assert(!(issparse(af)&&isreal(af)))
+%!assert(sum(as),sparse(sum(af)))
+%!assert(sum(as,1),sparse(sum(af,1)))
+%!assert(sum(as,2),sparse(sum(af,2)))
+%!assert(cumsum(as),sparse(cumsum(af)))
+%!assert(cumsum(as,1),sparse(cumsum(af,1)))
+%!assert(cumsum(as,2),sparse(cumsum(af,2)))
+%!assert(sumsq(as),sparse(sumsq(af)))
+%!assert(sumsq(as,1),sparse(sumsq(af,1)))
+%!assert(sumsq(as,2),sparse(sumsq(af,2)))
+%!assert(prod(as),sparse(prod(af)))
+%!assert(prod(as,1),sparse(prod(af,1)))
+%!assert(prod(as,2),sparse(prod(af,2)))
+%!assert(cumprod(as),sparse(cumprod(af)))
+%!assert(cumprod(as,1),sparse(cumprod(af,1)))
+%!assert(cumprod(as,2),sparse(cumprod(af,2)))
+
+%!assert(min(as),sparse(min(af)))
+%!assert(full(min(as(:))),min(af(:)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,[],2),sparse(min(af,[],2)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,0),sparse(min(af,0)))
+%!assert(min(as,bs),sparse(min(af,bf)))
+%!assert(max(as),sparse(max(af)))
+%!assert(full(max(as(:))),max(af(:)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,[],2),sparse(max(af,[],2)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,0),sparse(max(af,0)))
+%!assert(max(as,bs),sparse(max(af,bf)))
+
+%!assert(as==as)
+%!assert(as==af)
+%!assert(af==as)
+%!test
+%! [ii,jj,vv,nr,nc] = find(as);
+%! assert(af,full(sparse(ii,jj,vv,nr,nc)));
+%!assert(nnz(as),sum(af(:)!=0))
+%!assert(nnz(as),nnz(af))
+%!assert(issparse(as.'))
+%!assert(issparse(as'))
+%!assert(issparse(-as))
+%!assert(~as,sparse(~af))
+%!assert(as.', sparse(af.'));
+%!assert(as',  sparse(af'));
+%!assert(-as, sparse(-af));
+%!assert(~as, sparse(~af));
+%!error [i,j]=size(af);as(i-1,j+1);
+%!error [i,j]=size(af);as(i+1,j-1);
+%!test
+%! [Is,Js,Vs] = find(as);
+%! [If,Jf,Vf] = find(af);
+%! assert(Is,If);
+%! assert(Js,Jf);
+%! assert(Vs,Vf);
+%!error as(0,1);
+%!error as(1,0);
+%!assert(find(as),find(af))
+%!test
+%! [i,j,v] = find(as);
+%! [m,n] = size(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!test
+%! [i,j,v,m,n] = find(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!assert(issparse(horzcat(as,as)));
+%!assert(issparse(vertcat(as,as)));
+%!assert(issparse(cat(1,as,as)));
+%!assert(issparse(cat(2,as,as)));
+%!assert(issparse([as,as]));
+%!assert(issparse([as;as]));
+%!assert(horzcat(as,as), sparse([af,af]));
+%!assert(vertcat(as,as), sparse([af;af]));
+%!assert(horzcat(as,as,as), sparse([af,af,af]));
+%!assert(vertcat(as,as,as), sparse([af;af;af]));
+%!assert([as,as], sparse([af,af]));
+%!assert([as;as], sparse([af;af]));
+%!assert([as,as,as], sparse([af,af,af]));
+%!assert([as;as;as], sparse([af;af;af]));
+%!assert(cat(2,as,as), sparse([af,af]));
+%!assert(cat(1,as,as), sparse([af;af]));
+%!assert(cat(2,as,as,as), sparse([af,af,af]));
+%!assert(cat(1,as,as,as), sparse([af;af;af]));
+%!assert(issparse([as,af]));
+%!assert(issparse([af,as]));
+%!assert([as,af], sparse([af,af]));
+%!assert([as;af], sparse([af;af]));
+
+EOF
+}
+
+# operations which require square matrices.
+gen_square_tests() {
+# The \ and / operator tests on square matrices
+    gen_square_divop_tests
+
+    cat >>$TESTS <<EOF
+%!testif HAVE_UMFPACK
+%! assert(det(bs+speye(size(bs))),det(bf+eye(size(bf))),100*eps*abs(det(bf+eye(size(bf)))))
+
+%!testif HAVE_UMFPACK 
+%! [l,u]=lu(sparse([1,1;1,1]));
+%! assert(l*u,[1,1;1,1],10*eps);
+
+%!testif HAVE_UMFPACK
+%! [l,u]=lu(sparse([1,1;1,1+i]));
+%! assert(l,sparse([1,2,2],[1,1,2],1),10*eps);
+%! assert(u,sparse([1,1,2],[1,2,2],[1,1,1i]),10*eps);
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# inverse
+%! assert(inv(bs)*bs,sparse(eye(rows(bs))),1e-10);
+
+%!assert(bf\as',bf\af',100*eps);
+%!assert(bs\af',bf\af',100*eps);
+%!assert(bs\as',sparse(bf\af'),100*eps);
+
+EOF
+}
+
+# Cholesky tests
+gen_cholesky_tests() {
+    cat >>$TESTS <<EOF
+%!testif HAVE_CHOLMOD
+%! assert(chol(bs)'*chol(bs),bs,1e-10);
+%!testif HAVE_CHOLMOD 
+%! assert(chol(bs,'lower')*chol(bs,'lower')',bs,1e-10);
+%!testif HAVE_CHOLMOD
+%! assert(chol(bs,'lower'),chol(bs)',1e-10);
+
+%!testif HAVE_CHOLMOD ;# Return Partial Cholesky factorization
+%! [RS,PS] = chol(bs);
+%! assert(RS'*RS,bs,1e-10);
+%! assert(PS,0);
+%! [LS,PS] = chol(bs,'lower');
+%! assert(LS*LS',bs,1e-10);
+%! assert(PS,0);
+
+%!testif HAVE_CHOLMOD ;# Permuted Cholesky factorization
+%! [RS,PS,QS] = chol(bs);
+%! assert(RS'*RS,QS*bs*QS',1e-10);
+%! assert(PS,0);
+%! [LS,PS,QS] = chol(bs,'lower');
+%! assert(LS*LS',QS*bs*QS',1e-10);
+%! assert(PS,0);
+
+EOF
+}
+
+# test scalar operations: uses af and real scalar bf; modifies as,bf,bs
+gen_scalar_tests() {
+    echo '%!test as=sparse(af);' >> $TESTS
+    echo '%!test bs=bf;' >> $TESTS
+    gen_elementop_tests
+    gen_ordering_tests
+    echo '%!test bf=bf+1i;' >>$TESTS
+    echo '%!test bs=bf;' >> $TESTS
+    gen_elementop_tests
+}
+
+# test matrix operations: uses af and bf; modifies as,bs
+gen_rectangular_tests() {
+    echo '%!test as=sparse(af);' >> $TESTS
+    echo '%!test bs=sparse(bf);' >>$TESTS
+    gen_mapper_tests
+    gen_real_mapper_tests
+    gen_unaryop_tests
+    gen_elementop_tests
+    gen_sparsesparse_elementop_tests
+    gen_matrixop_tests
+    # gen_divop_tests # Disable rectangular \ and / for now
+    gen_matrixdiag_tests
+    gen_matrixreshape_tests
+    cat >>$TESTS <<EOF
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+EOF
+}
+
+
+# =======================================================
+# sparse assembly tests
+
+gen_assembly_tests() {
+cat >>$TESTS <<EOF
+%%Assembly tests
+%!test
+%! m=max([m;r(:)]);
+%! n=max([n;c(:)]);
+%! funiq=fsum=zeros(m,n);
+%! funiq(r(:) + m*(c(:)-1) ) = ones(size(r(:)));
+%! funiq = sparse(funiq);
+%! for k=1:length(r), fsum(r(k),c(k)) += 1; end
+%! fsum = sparse(fsum);
+%!assert(sparse(r,c,1),sparse(fsum(1:max(r),1:max(c))));
+%!assert(sparse(r,c,1,"sum"),sparse(fsum(1:max(r),1:max(c))));
+%!assert(sparse(r,c,1,"unique"),sparse(funiq(1:max(r),1:max(c))));
+%!assert(sparse(r,c,1,m,n),sparse(fsum));
+%!assert(sparse(r,c,1,m,n,"sum"),sparse(fsum));
+%!assert(sparse(r,c,1,m,n,"unique"),sparse(funiq));
+
+%!assert(sparse(r,c,1i),sparse(fsum(1:max(r),1:max(c))*1i));
+%!assert(sparse(r,c,1i,"sum"),sparse(fsum(1:max(r),1:max(c))*1i));
+%!assert(sparse(r,c,1i,"unique"),sparse(funiq(1:max(r),1:max(c))*1i));
+%!assert(sparse(r,c,1i,m,n),sparse(fsum*1i));
+%!assert(sparse(r,c,1i,m,n,"sum"),sparse(fsum*1i));
+%!assert(sparse(r,c,1i,m,n,"unique"),sparse(funiq*1i));
+
+%!test
+%! if (issparse(funiq))
+%!  assert(sparse(full(1i*funiq)),sparse(1i*funiq));
+%! endif
+
+%!assert(sparse(full(funiq)),funiq);
+
+
+EOF
+}
+
+# =======================================================
+# sparse selection tests
+
+gen_scalar_select_tests () {
+    cat >>$TESTS <<EOF
+%!assert (sparse(42)([1,1]),sparse([42,42]))
+%!assert (sparse(42*1i)([1,1]),sparse([42,42].*1i))
+EOF
+}
+
+gen_select_tests() {
+    cat >>$TESTS <<EOF
+%!test as=sparse(af);
+
+%% Point tests
+%!test idx=ridx(:)+rows(as)*(cidx(:)-1);
+%!assert(sparse(as(idx)),sparse(af(idx)));
+%!assert(as(idx),sparse(af(idx)));
+%!assert(as(idx'),sparse(af(idx')));
+%!assert(as(flipud(idx(:))),sparse(af(flipud(idx(:)))))
+%!assert(as([idx,idx]),sparse(af([idx,idx])));
+%!error(as(reshape([idx;idx],[1,length(idx),2])));
+
+%% Slice tests
+%!assert(as(ridx,cidx), sparse(af(ridx,cidx)))
+%!assert(as(ridx,:), sparse(af(ridx,:)))
+%!assert(as(:,cidx), sparse(af(:,cidx)))
+%!assert(as(:,:), sparse(af(:,:)))
+%!assert(as((size(as,1):-1:1),:),sparse(af((size(af,1):-1:1),:)))
+%!assert(as(:,(size(as,2):-1:1)),sparse(af(:,(size(af,2):-1:1))))
+
+%% Indexing tests
+%!assert(full(as([1,1],:)), af([1,1],:))
+%!assert(full(as(:,[1,1])), af(:,[1,1]))
+%!test
+%! [i,j,v] = find (as);
+%! assert (as(i(1),j(1))([1,1]), sparse([v(1),v(1)]))
+
+%% Assignment test
+%!test
+%! ts=as;ts(:,:)=ts(fliplr(1:size(as,1)),:);
+%! tf=af;tf(:,:)=tf(fliplr(1:size(af,1)),:);
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(fliplr(1:size(as,1)),:)=ts;
+%! tf=af;tf(fliplr(1:size(af,1)),:)=tf;
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(:,fliplr(1:size(as,2)))=ts;
+%! tf=af;tf(:,fliplr(1:size(af,2)))=tf;
+%! assert(ts,sparse(tf));
+%!test
+%! ts(fliplr(1:size(as,1)))=as(:,1);tf(fliplr(1:size(af,1)))=af(:,1);
+%! assert(ts,sparse(tf));
+
+%% Deletion tests
+%!test
+%! ts=as;ts(1,:)=[];tf=af;tf(1,:)=[];
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(:,1)=[];tf=af;tf(:,1)=[];
+%! assert(ts,sparse(tf));
+
+%% Test 'end' keyword
+%!assert(full(as(end)), af(end))
+%!assert(full(as(1,end)), af(1,end))
+%!assert(full(as(end,1)), af(end,1))
+%!assert(full(as(end,end)), af(end,end))
+%!assert(as(2:end,2:end), sparse(af(2:end,2:end)))
+%!assert(as(1:end-1,1:end-1), sparse(af(1:end-1,1:end-1)))
+EOF
+}
+
+# =======================================================
+# sparse save and load tests
+
+gen_save_tests() {
+    cat >>$TESTS <<EOF
+%!test # save ascii
+%! savefile= tmpnam();
+%! as_save=as; save("-text",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+%!test # save binary
+%! savefile= tmpnam();
+%! as_save=as; save("-binary",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+%!testif HAVE_HDF5 # save hdf5
+%! savefile= tmpnam();
+%! as_save=as; save("-hdf5",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+## FIXME -- we should skip (or mark as an expected failure) the test for
+## saving sparse matrices to MAT files when using 64-bit indexing since
+## that is not implemented yet.
+%!test # save matlab
+%! savefile= tmpnam();
+%! as_save=as; save("-mat",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+EOF
+}
+
+# =============================================================
+# Specific solver tests for matrices that will test all of the solver
+# code. Uses alpha and beta
+gen_solver_tests() {
+
+if $preset; then
+  cat >>$TESTS <<EOF
+%! n=8;
+%! lf=diag(1:n);lf(n-1,1)=0.5*alpha;lf(n,2)=0.25*alpha;ls=sparse(lf);
+%! uf=diag(1:n);uf(1,n-1)=2*alpha;uf(2,n)=alpha;us=sparse(uf);
+%! ts=spdiags(ones(n,3),-1:1,n,n)+diag(1:n); tf = full(ts);
+EOF
+else
+  cat >>$TESTS <<EOF
+%! n=floor(lognormal_rnd(8,2)+1)'
+%! ls = tril(sprandn(8,8,0.2),-1).*alpha + n*speye(8); lf = full(ls);
+%! us = triu(sprandn(8,8,0.2),1).*alpha + n*speye(8); uf = full(us);
+%! ts = spdiags(randn(8,3),-1:1,8,8).*alpha; tf = full(ts);
+EOF
+fi
+
+cat >>$TESTS <<EOF
+%! df = diag(1:n).* alpha; ds = sparse(df);
+%! pdf = df(randperm(n),randperm(n)); pds = sparse(pdf);
+%! plf = lf(randperm(n),randperm(n)); pls = sparse(plf);
+%! puf = uf(randperm(n),randperm(n)); pus = sparse(puf);
+%! bs = spdiags(repmat([1:n]',1,4),-2:1,n,n).*alpha; bf = full(bs);
+%! cf = lf + lf'; cs = sparse(cf);
+%! bcf = bf + bf'; bcs = sparse(bcf);
+%! tcf = tf + tf'; tcs = sparse(tcf);
+%! xf = diag(1:n) + fliplr(diag(1:n)).*beta; xs = sparse(xf);
+%!assert(ds\xf,df\xf,1e-10);
+%!assert(ds\xs,sparse(df\xf),1e-10);
+%!assert(pds\xf,pdf\xf,1e-10);
+%!assert(pds\xs,sparse(pdf\xf),1e-10);
+%!assert(ls\xf,lf\xf,1e-10);
+%!assert(sparse(ls\xs),sparse(lf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pls\xf,plf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pls\xs),sparse(plf\xf),1e-10);
+%!assert(us\xf,uf\xf,1e-10);
+%!assert(sparse(us\xs),sparse(uf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pus\xf,puf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pus\xs),sparse(puf\xf),1e-10);
+%!assert(bs\xf,bf\xf,1e-10);
+%!assert(sparse(bs\xs),sparse(bf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(cs\xf,cf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(cs\xs),sparse(cf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(bcs\xf,bcf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(bcs\xs),sparse(bcf\xf),1e-10);
+%!assert(ts\xf,tf\xf,1e-10);
+%!assert(sparse(ts\xs),sparse(tf\xf),1e-10);
+%!assert(tcs\xf,tcf\xf,1e-10);
+%!assert(sparse(tcs\xs),sparse(tcf\xf),1e-10);
+
+EOF
+
+cat >>$TESTS <<EOF
+%% QR solver tests
+
+%!function f(a, sz, feps)
+%! b = randn(sz); x = a \b; 
+%! assert (a * x, b, feps);
+%! b = randn(sz)+1i*randn(sz); x = a \ b;  
+%! assert (a * x, b, feps);
+%! b = sprandn(sz(1),sz(2),0.2); x = a \b;
+%! assert (sparse(a * x), b, feps);
+%! b = sprandn(sz(1),sz(2),0.2)+1i*sprandn(sz(1),sz(2),0.2); x = a \b; 
+%! assert (sparse(a * x), b, feps);
+%!testif HAVE_CXSPARSE
+%! a = alpha*sprandn(10,11,0.2)+speye(10,11); f(a,[10,2],1e-10);
+%! ## Test this by forcing matrix_type, as can't get a certain 
+%! ## result for over-determined systems.
+%! a = alpha*sprandn(10,10,0.2)+speye(10,10); matrix_type(a, "Singular");
+%! f(a,[10,2],1e-10);
+
+%% Rectanguar solver tests that don't use QR
+
+%!test
+%! ds = alpha * spdiags([1:11]',0,10,11);
+%! df = full(ds);
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:10],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! ds = alpha * spdiags([1:11]',0,11,10);
+%! df = full(ds);
+%! xf = beta * ones(11,2);
+%! xs = speye(11,11);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:11],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! us = alpha*[[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]];
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xs),xs,100*eps)
+%!test
+%! pus = us(:,[2,1,3:12]);
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xs),xs,100*eps)
+%!test
+%! us = alpha*[speye(11,9),[1;sparse(8,1);1;0]];
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xf);
+%! assert(us\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(us\xs,r\c,100*eps)
+%!test
+%! pus = us(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xs,r\c,100*eps)
+%!test
+%! ls = alpha*[speye(9,11);[1,sparse(1,8),1,0]];
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ls*(ls\xf),xf,100*eps)
+%!assert(ls*(ls\xs),xs,100*eps)
+%!test
+%! pls = ls([1:8,10,9],:);
+%!assert(pls*(pls\xf),xf,100*eps)
+%!assert(pls*(pls\xs),xs,100*eps)
+%!test
+%! ls = alpha*[speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]];
+%! xf = beta * ones(12,2);
+%! xs = speye(12,12);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xf);
+%! assert(ls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(ls\xs,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! pls = ls(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xs,r\c,100*eps)
+
+EOF
+}
+
+
+# =============================================================
+# Putting it all together: defining the combined tests
+
+
+# initial function
+gen_function
+gen_section
+
+# specific tests
+if $preset; then 
+    gen_specific_tests
+    gen_section
+fi
+
+# scalar operations
+echo '%!shared as,af,bs,bf' >> $TESTS
+if $preset; then
+    echo '%!test af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];' >> $TESTS
+    echo '%!test bf=3;' >>$TESTS
+else
+    cat >>$TESTS <<EOF
+%!test
+%! % generate m,n from 1 to <5000
+%! m=floor(lognormal_rnd(8,2)+1);
+%! n=floor(lognormal_rnd(8,2)+1);
+%! as=sprandn(m,n,0.3); af = full(as+1i*sprandn(as));
+%! bf = randn;
+EOF
+fi
+
+gen_scalar_tests
+gen_section
+
+# rectangular operations
+if $preset; then
+    echo '%!test af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];' >> $TESTS
+    echo '%!test bf=[0,1-1i,0,0;2+1i,0,0,0;3-1i,2+3i,0,0];' >> $TESTS
+else
+    cat >>$TESTS <<EOF
+%!test
+%! m=floor(lognormal_rnd(8,2)+1);
+%! n=floor(lognormal_rnd(8,2)+1);
+%! as=sprandn(m,n,0.3); af = full(as+1i*sprandn(as));
+%! bs=sprandn(m,n,0.3); bf = full(bs+1i*sprandn(bs));
+EOF
+fi
+
+gen_rectangular_tests
+gen_section
+gen_save_tests
+gen_section
+echo '%!test bf=real(bf);' >> $TESTS
+gen_rectangular_tests
+gen_section
+gen_sparsesparse_ordering_tests
+gen_section
+echo '%!test af=real(af);' >> $TESTS
+gen_rectangular_tests
+gen_section
+gen_save_tests
+gen_section
+echo '%!test bf=bf+1i*(bf~=0);' >> $TESTS
+gen_rectangular_tests
+gen_section
+
+# square operations
+if $preset; then
+    echo '%!test af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];' >> $TESTS
+    echo '%! as=sparse(af);' >> $TESTS
+    echo '%!test bf=[0,1-1i,0,0;2+1i,0,0,0;3-1i,2+3i,0,0];' >> $TESTS
+else
+    cat >>$TESTS <<EOF
+%!test
+%! m=floor(lognormal_rnd(8,2)+1);
+%! n=floor(lognormal_rnd(8,2)+1);
+%! as=sprandn(m,n,0.3); af = full(as+1i*sprandn(as));
+%! bs=sprandn(m,n,0.3); bf = full(bs+1i*sprandn(bs));
+EOF
+fi
+
+cat >>$TESTS <<EOF
+%!test ;# invertible matrix
+%! bf=af'*bf+max(abs([af(:);bf(:)]))*sparse(eye(columns(as)));
+%! bs=sparse(bf);
+
+EOF
+
+gen_square_tests
+gen_section
+echo '%!test bf=real(bf);' >> $TESTS
+echo '%! bs=sparse(bf);' >> $TESTS
+gen_square_tests
+gen_section
+echo '%!test af=real(af);' >> $TESTS
+echo '%! as=sparse(af);' >> $TESTS
+gen_square_tests
+gen_section
+echo '%!test bf=bf+1i*(bf~=0);' >> $TESTS
+echo '%! bs=sparse(bf);' >> $TESTS
+gen_square_tests
+gen_section
+
+# cholesky tests
+if $preset; then
+  echo '%!test bf=[5,0,1+1i,0;0,5,0,1-2i;1-1i,0,5,0;0,1+2i,0,5];' >> $TESTS
+  echo '%! bs=sparse(bf);' >> $TESTS
+else
+  echo '# This has a small chance of failing to create a positive definite matrix' >> $TESTS
+  echo '%!test n=floor(lognormal_rnd(8,2)+1)' >> $TESTS
+  echo '%! bs = n*speye(n,n) + sprandn(n,n,0.3); bf = full(bs);' >> $TESTS
+fi
+
+gen_cholesky_tests
+gen_section
+echo '%!test bf=real(bf);' >> $TESTS
+echo '%! bs=sparse(bf);' >> $TESTS
+gen_cholesky_tests
+gen_section
+
+# assembly tests
+echo '%!shared r,c,m,n,fsum,funiq' >>$TESTS
+if $use_preset; then
+    cat >>$TESTS <<EOF
+%!test
+%! r=[1,1,2,1,2,3];
+%! c=[2,1,1,1,2,1];
+%! m=n=0;
+EOF
+else
+    cat >>$TESTS <<EOF
+%!test
+%! % generate m,n from 1 to <5000
+%! m=floor(lognormal_rnd(8,2)+1);
+%! n=floor(lognormal_rnd(8,2)+1);
+%! nz=ceil((m+n)/2);
+%! r=floor(rand(5,nz)*n)+1;
+%! c=floor(rand(5,nn)*m)+1;
+EOF
+fi
+gen_assembly_tests #includes real and complex tests
+gen_section
+
+# slicing tests
+echo '%!shared ridx,cidx,idx,as,af' >>$TESTS
+if $use_preset; then
+    cat >>$TESTS <<EOF
+%!test
+%! af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];
+%! ridx=[1,3]; cidx=[2,3];
+EOF
+else
+    cat >>$TESTS <<EOF
+%!test
+%! % generate m,n from 1 to <5000
+%! m=floor(lognormal_rnd(8,2)+1);
+%! n=floor(lognormal_rnd(8,2)+1);
+%! as=sprandn(m,n,0.3); af = full(as+1i*sprandn(as));
+%! ridx = ceil(m*rand(1,ceil(rand*m))
+%! cidx = ceil(n*rand(1,ceil(rand*n))
+EOF
+fi
+gen_scalar_select_tests
+gen_select_tests
+echo '%!test af=real(af);' >> $TESTS
+gen_select_tests
+gen_section
+echo '%!shared alpha,beta,df,pdf,lf,plf,uf,puf,bf,cf,bcf,tf,tcf,xf,ds,pds,ls,pls,us,pus,bs,cs,bcs,ts,tcs,xs' >>$TESTS
+echo '%!test alpha=1;beta=1;' >> $TESTS
+gen_solver_tests
+echo '%!test alpha=1;beta=1i;' >> $TESTS
+gen_solver_tests
+echo '%!test alpha=1i;beta=1;' >> $TESTS
+gen_solver_tests
+echo '%!test alpha=1i;beta=1i;' >> $TESTS
+gen_solver_tests
+gen_section
diff --git a/test/fntests.m b/test/fntests.m
new file mode 100644
index 0000000..9f625e4
--- /dev/null
+++ b/test/fntests.m
@@ -0,0 +1,255 @@
+## Copyright (C) 2005, 2006, 2007, 2008, 2009 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+clear all;
+
+global files_with_no_tests = {};
+global files_with_tests = {};
+global topsrcdir;
+global topbuilddir;
+
+currdir = canonicalize_file_name (".");
+
+if (nargin == 1)
+  xdir = argv(){1};
+else
+  xdir = ".";
+endif
+
+srcdir = canonicalize_file_name (xdir);
+topsrcdir = canonicalize_file_name (fullfile (xdir, ".."));
+topbuilddir = canonicalize_file_name (fullfile (currdir, ".."));
+
+if (strcmp (currdir, srcdir))
+  testdirs = {srcdir};
+else
+  testdirs = {currdir, srcdir};
+endif
+
+src_tree = canonicalize_file_name (fullfile (topsrcdir, "src"));
+liboctave_tree = canonicalize_file_name (fullfile (topsrcdir, "liboctave"));
+script_tree = canonicalize_file_name (fullfile (topsrcdir, "scripts"));
+local_script_tree = canonicalize_file_name (fullfile (currdir, "../scripts"));
+
+fundirs = {src_tree, liboctave_tree, script_tree};
+
+if (! strcmp (currdir, srcdir))
+  fundirs{end+1} = local_script_tree;
+endif
+
+function print_test_file_name (nm)
+  filler = repmat (".", 1, 55-length (nm));
+  printf ("  %s %s", nm, filler);
+endfunction
+
+function print_pass_fail (n, p)
+  if (n > 0)
+    printf (" PASS %4d/%-4d", p, n);
+    nfail = n - p;
+    if (nfail > 0)
+      printf (" FAIL %d", nfail);
+    endif
+  endif
+  puts ("\n");
+endfunction
+
+## FIXME -- should we only try match the keyword at the start of a line?
+function y = hastests (f)
+  fid = fopen (f);
+  if (fid < 0)
+    error ("fopen failed: %s", f);
+  else
+    str = fread (fid, "*char")';
+    fclose (fid);
+    y = (findstr (str, "%!test") || findstr (str, "%!assert")
+	 || findstr (str, "%!error") || findstr (str, "%!warning"));
+  endif
+endfunction
+
+function [dp, dn, dxf, dsk] = run_test_dir (fid, d);
+  global files_with_tests;
+  global files_with_no_tests;
+  lst = dir (d);
+  dp = dn = dxf = dsk = 0;
+  for i = 1:length (lst)
+    nm = lst(i).name;
+    if (length (nm) > 5 && strcmp (nm(1:5), "test_")
+	&& strcmp (nm((end-1):end), ".m"))
+      p = n = 0;
+      ffnm = fullfile (d, nm);
+      if (hastests (ffnm))
+	print_test_file_name (nm);
+	[p, n, xf, sk] = test (nm(1:(end-2)), "quiet", fid);
+	print_pass_fail (n, p);
+	files_with_tests(end+1) = ffnm;
+      else
+	files_with_no_tests(end+1) = ffnm;
+      endif
+      dp += p;
+      dn += n;
+      dxf += xf;
+      dsk += sk;
+    endif
+  endfor
+endfunction
+
+function [dp, dn, dxf, dsk] = run_test_script (fid, d);
+  global files_with_tests;
+  global files_with_no_tests;
+  global topsrcdir;
+  global topbuilddir;
+  lst = dir (d);
+  dp = dn = dxf = dsk = 0;
+  for i = 1:length (lst)
+    nm = lst(i).name;
+    if (lst(i).isdir && ! strcmp (nm, ".") && ! strcmp (nm, "..")
+	&& ! strcmp (nm, "CVS"))
+      [p, n, xf, sk] = run_test_script (fid, [d, "/", nm]);
+      dp += p;
+      dn += n;
+      dxf += xf;
+      dsk += sk;
+    endif
+  endfor
+  for i = 1:length (lst)
+    nm = lst(i).name;
+    if ((length (nm) > 3 && strcmp (nm((end-2):end), ".cc"))
+	|| (length (nm) > 2 && strcmp (nm((end-1):end), ".m")))
+      f = fullfile (d, nm);
+      p = n = xf = 0;
+      ## Only run if it contains %!test, %!assert %!error or %!warning
+      if (hastests (f))
+	tmp = strrep (f, [topsrcdir, "/"], "");
+	tmp = strrep (tmp, [topbuilddir, "/"], "../");
+	print_test_file_name (tmp);
+	[p, n, xf, sk] = test (f, "quiet", fid);
+	print_pass_fail (n, p);
+	dp += p;
+	dn += n;
+	dxf += xf;
+	dsk += sk;
+	files_with_tests(end+1) = f;
+      else
+	files_with_no_tests(end+1) = f;
+      endif
+    endif
+  endfor 
+  ##  printf("%s%s -> passes %d of %d tests\n", ident, d, dp, dn);
+endfunction
+
+function printf_assert (varargin)
+  global _assert_printf;
+  _assert_printf = cat (2, _assert_printf, sprintf (varargin{:}));
+endfunction
+
+function ret = prog_output_assert (str)
+  global _assert_printf;
+  if (isempty (_assert_printf))
+    ret = isempty (str);
+  elseif (_assert_printf(end) == "\n")
+    ret = strcmp (_assert_printf(1:(end-1)), str);
+  else
+    ret = strcmp (_assert_printf, str);
+  endif
+  _assert_printf = "";
+endfunction
+
+function n = num_elts_matching_pattern (lst, pat)
+  n = 0;
+  for i = 1:length (lst)
+    if (! isempty (regexp (lst{i}, pat)))
+      n++;
+    endif
+  endfor
+endfunction
+
+function report_files_with_no_tests (with, without, typ)
+  pat = cstrcat ("\\", typ, "$");
+  n_with = num_elts_matching_pattern (with, pat);
+  n_without = num_elts_matching_pattern (without, pat);
+  n_tot = n_with + n_without;
+  printf ("\n%d (of %d) %s files have no tests.\n", n_without, n_tot, typ);
+endfunction
+
+pso = page_screen_output ();
+warn_state = warning ("query", "quiet");
+warning ("on", "quiet");
+try
+  page_screen_output (0);
+  fid = fopen ("fntests.log", "wt");
+  if (fid < 0)
+    error ("could not open fntests.log for writing");
+  endif
+  test ("", "explain", fid);
+  dp = dn = dxf = dsk = 0;
+  puts ("\nIntegrated test scripts:\n\n");
+  for i = 1:length (fundirs)
+    [p, n, xf, sk] = run_test_script (fid, fundirs{i});
+    dp += p;
+    dn += n;
+    dxf += xf;
+    dsk += sk;
+  endfor
+  puts ("\nFixed test scripts:\n\n");
+  for i = 1:length (testdirs)
+    [p, n, xf, sk] = run_test_dir (fid, testdirs{i});
+    dp += p;
+    dn += n;
+    dxf += xf;
+    dsk += sk;
+  endfor
+  printf ("\nSummary:\n\n  PASS %6d\n", dp);
+  nfail = dn - dp;
+  printf ("  FAIL %6d\n", nfail);
+  if (dxf > 0)
+    if (dxf > 1)
+      t1 = "were";
+      t2 = "failures";
+    else
+      t1 = "was";
+      t2 = "failure";
+    endif
+    printf ("\nThere %s %d expected %s (see fntests.log for details).\n",
+	    t1, dxf, t2);
+    puts ("\nExpected failures are known bugs.  Please help improve\n");
+    puts ("Octave by contributing fixes for them.\n");
+  endif
+  if (dsk > 0)
+    printf ("\nThere were %d skipped tests (see fntest.log for details).\n", dsk);
+    puts ("Skipped tests are features that are disabled in this version\n");
+    puts ("of Octave as the needed libraries were not present when Octave\n");
+    puts ("was built\n");
+  endif
+
+  report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m");
+  report_files_with_no_tests (files_with_tests, files_with_no_tests, ".cc");
+
+  puts ("\nPlease help improve Octave by  contributing tests for\n");
+  puts ("these files (see the list in the file fntests.log).\n");
+
+  fprintf (fid, "\nFiles with no tests:\n\n%s",
+	  list_in_columns (files_with_no_tests, 80));
+  fclose (fid);
+
+  page_screen_output (pso);
+  warning (warn_state.state, "quiet");
+catch
+  page_screen_output (pso);
+  warning (warn_state.state, "quiet");
+  disp (lasterr ());
+end_try_catch
diff --git a/test/test_args.m b/test/test_args.m
new file mode 100644
index 0000000..c0b8fef
--- /dev/null
+++ b/test/test_args.m
@@ -0,0 +1,209 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+########################################
+## No inputs or no outputs
+
+## no input or output arguments
+%!function f ()
+%!  assert (nargin, 0);
+%!  assert (nargout, 0);
+%!test
+%! f;
+
+## one input with two possible inputs
+%!function f (x, y)
+%!  assert (nargin, 1);
+%!  assert (nargout, 0);
+%!test
+%! f (1);
+
+## no inputs, one of multiple outputs
+%!function [x, y] = f ()
+%!  assert (nargin, 0);
+%!  assert (nargout, 1);
+%!  x = 2;
+%!test
+%! assert (f (), 2);
+
+## one of multiple inputs, one of multiple outputs
+%!function [x, y] = f (a, b)
+%!  assert (nargin, 1);
+%!  assert (nargout, 1);
+%!  x = a;
+%!test
+%! assert (f (1), 1);
+
+########################################
+## Varargin, varargout
+
+## varargin and varargout with no inputs or outputs
+%!function [varargout] = f (varargin)
+%!  assert (nargin, 0);
+%!  assert (nargout, 0);
+%!test
+%! f;
+
+## varargin and varargout with one input
+%!function [varargout] = f (x, varargin)
+%!  assert (nargin, 1);
+%!  assert (nargout, 0);
+%!test
+%! f (1);
+
+## varargin and varargout with one output
+%!function [x, varargout] = f (varargin)
+%!  assert (nargin, 0);
+%!  assert (nargout, 1);
+%!  x = 2;
+%!test
+%! assert (f (), 2);
+
+## varargin and varargout with one input and output
+%!function [varargout] = f (varargin)
+%!  assert (nargin, 1);
+%!  assert (nargout, 1);
+%!  varargout{1} = varargin{1};
+%!test
+%! assert (f (1), 1);
+
+## multiple inputs, multiple outputs, but not all of either
+## WARNING: The original test did not assign the outputs, it just
+## requested them, and I think that is supposed to be an error.  It also
+## still has a non-assigned output argument.
+%!function [x, y, z] = f (a, b, c, d, e)
+%!  assert (nargin, 4);
+%!  assert (nargout, 2);
+%!  x = a;
+%!  y = b;
+%!test
+%! [s, t] = f (1, 2, 3, 4);
+%! assert([s t], [1 2]);
+
+## Fully used varargin and varargout
+%!function [varargout] = f (varargin)
+%!  assert (nargin, 3);
+%!  assert (nargout, 4);
+%!  varargout{1} = varargin{1};
+%!  varargout{2} = varargin{2};
+%!  varargout{3} = varargin{3};
+%!  varargout{4} = 4;
+%!test
+%! [s, t, u, v] = f (1, 2, 3);
+%! assert([s t u v], [1 2 3 4]);
+
+## Test default arguments
+## numeric
+%!function f (x = 0)
+%!  assert (x, 0)
+%!test
+%!  f()
+
+## numeric vector (spaces)
+%!function f (x = [0 1 2])
+%!  assert (x, [0 1 2])
+%!test
+%!  f()
+
+## numeric vector (range)
+%!function f (x = 1:3)
+%!  assert (x, 1:3)
+%!test
+%!  f()
+
+## numeric vector (commas)
+%!function f (x = [0,1,2])
+%!  assert (x, [0 1 2])
+%!test
+%!  f()
+
+## numeric vector (commas and spaces)
+%!function f (x = [0, 1, 2])
+%!  assert (x, [0 1 2])
+%!test
+%!  f()
+
+## numeric matrix
+%!function f (x = [0, 1, 2;3, 4, 5])
+%!  assert (x, [0 1 2;3 4 5])
+%!test
+%!  f()
+
+## empty cell
+%!function f (x = {})
+%!  assert (x, {})
+%!test
+%!  f()
+
+## full cell
+%!function f (x = {1})
+%!  assert (x, {1})
+%!test
+%!  f()
+
+## many cells
+%!function f (x = {1 'a' "b" 2.0 struct("a", 3)})
+%!  assert (x, {1 'a' "b" 2.0 struct("a", 3)})
+%!test
+%!  f()
+
+## struct
+%!function f (x = struct("a", 3))
+%!  assert (x, struct ("a", 3))
+%!test
+%!  f()
+
+## char (double quotes)
+%!function f (x = "a")
+%!  assert (x, "a")
+%!test
+%!  f()
+
+## char (single quotes)
+%!function f (x = 'a')
+%!  assert (x, "a")
+%!test
+%!  f()
+
+## char (string, double quotes)
+%!function f (x = "abc123")
+%!  assert (x, "abc123")
+%!test
+%!  f()
+
+## char (string, double quotes, punctuation)
+%!function f (x = "abc123`1234567890-=~!@#$%^&*()_+[]{}|;':\",./<>?\\")
+%!  assert (x, "abc123`1234567890-=~!@#$%^&*()_+[]{}|;':\",./<>?\\")
+%!test
+%!  f()
+
+## Function handle (builtin)
+%!function f (x = @sin)
+%!  finfo = functions (x);
+%!  fname = finfo.function;
+%!  assert (isa (x, "function_handle") && strcmp (fname, "sin"));
+%!test
+%!  f()
+
+## Function handle (anonymous)
+%!function f (x = @(x) x.^2)
+%!  finfo = functions (x);
+%!  ftype = finfo.type;
+%!  assert (isa (x, "function_handle") && strcmp (ftype, "anonymous"));
+%!test
+%!  f()
diff --git a/test/test_contin.m b/test/test_contin.m
new file mode 100644
index 0000000..ca14db3
--- /dev/null
+++ b/test/test_contin.m
@@ -0,0 +1,163 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/contin/contin-1.m
+%!test
+%! x = [1,2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-2.m
+%!test
+%! x = [1,2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-3.m
+%!test
+%! x = [1,2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-4.m
+%!test
+%! x = [1,2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments ok here
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-5.m
+%!test
+%! x = [1,2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-6.m
+%!test
+%! x = [1,2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-7.m
+%!test
+%! x = [1;2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! ;\
+%! 
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-8.m
+%!test
+%! x = [1;2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! ;\
+%! 
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-9.m
+%!test
+%! x = [1;2];
+%! a = 1;
+%! b = 2;
+%! y = [a... # comments here ok
+%! ;\
+%! 
+%! b];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-10.m
+%!assert(1 + ...
+%! 2 - \# comments here ok
+%! 3 / ... # comments here ok
+%! -1,6);
+
+%% test/octave.test/contin/contin-11.m
+%!function y = f (a,...
+%!                b,  ...
+%!                c,  ...   % comments ok
+%!                x,  # continuation characters not required in parens
+%!                y,  \# but they should work too.
+%!                z)
+%!
+%!  y = 1;
+%!test
+%! assert(f (),1);
+
+%% test/octave.test/contin/contin-12.m
+%!test
+%!assert(1 == 1
+%! && 2 == 2
+%! || 3 == 5);
+
+%% test/octave.test/contin/contin-13.m
+%!test
+%! x = [1, ...
+%! 
+%! ...
+%! 
+%! 2];
+%! y = [1;2];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-14.m
+%!test
+%! x = [1, ...
+%! 
+%! ...
+%! 
+%! 2];
+%! y = [1;2];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-15.m
+%!test
+%! x = [1,...
+%! 2];
+%! y = [1,2];
+%! assert(all (y == x));
+
+%% test/octave.test/contin/contin-16.m
+%!test
+%! x = [ 1 , ...
+%! 2];
+%! y = [1,2];
+%! assert(all (y == x));
+
diff --git a/test/test_diag_perm.m b/test/test_diag_perm.m
new file mode 100644
index 0000000..031ad90
--- /dev/null
+++ b/test/test_diag_perm.m
@@ -0,0 +1,265 @@
+## Copyright (C) 2009 E. Jason Riedy
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+########################################
+## Permutation matrices
+
+## row permutation
+%!test
+%! n = 5;
+%! A = rand (n);
+%! perm = randperm (n);
+%! Prow = eye (n) (perm, :);
+%! assert (A(perm, :), Prow * A);
+%! invperm(perm) = 1:n;
+%! assert (Prow \ A, A(invperm, :));
+%! assert (Prow' * A, A(invperm, :));
+
+## column permutation
+%!test
+%! n = 7;
+%! A = rand (n);
+%! perm = randperm (n);
+%! Pcol = eye (n) (:, perm);
+%! assert (A(:, perm), A * Pcol);
+%! invperm(perm) = 1:n;
+%! assert (A / Pcol, A(:, invperm));
+%! assert (A * Pcol.', A(:, invperm));
+
+## fall back to a matrix in addition
+%!test
+%! n = 4;
+%! P1 = eye (n) (:, randperm (n));
+%! A = zeros (n) + P1;
+%! assert (sum (A), full (ones (1, n)));
+%! assert (sum (A, 2), full (ones (n, 1)));
+
+## preserve dense matrix structure
+%!test
+%! n = 7;
+%! Pc = eye (n) (:, randperm (n));
+%! Pr = eye (n) (randperm (n), :);
+%! assert (typeinfo (rand (n) * Pc), "matrix");
+%! assert (typeinfo (Pr * rand (n)), "matrix");
+
+## preserve sparse matrix structure
+%!test
+%! n = 7;
+%! Pc = eye (n) (:, randperm (n));
+%! Ac = sprand (n-3, n, .5) + I () * sprand (n-3, n, .5);
+%! Pr = eye (n) (randperm (n), :);
+%! Ar = sprand (n, n+2, .5);
+%! assert (typeinfo (Ac * Pc), "sparse complex matrix");
+%! assert (full (Ac * Pc), full (Ac) * Pc);
+%! assert (full (Ac / Pc), full (Ac) / Pc);
+%! assert (typeinfo (Pr * Ar), "sparse matrix");
+%! assert (full (Pr * Ar), Pr * full (Ar));
+%! assert (full (Pr \ Ar), Pr \ full (Ar));
+
+## structure rules for 1x1 dense / scalar and 1x1 perm
+%!test
+%! n = 7;
+%! P1 = eye (1) (:, [1]);
+%! A1 = 1;
+%! P = eye (n) (:, randperm (n));
+%! A = rand (n-3, n, .5);
+%! assert (typeinfo (A * P1), "matrix");
+%! assert (full (A * P1), full (A) * P1);
+%! assert (typeinfo (P1 * A), "matrix");
+%! assert (full (P1 * A), P1 * full (A));
+%! assert (typeinfo (A1 * P), "matrix");
+%! assert (full (A1 * P), full (A1) * P);
+%! assert (typeinfo (P * A1), "matrix");
+%! assert (full (P * A1), P * full (A1));
+
+## structure rules for 1x1 sparse and 1x1 perm
+%!test
+%! n = 7;
+%! P1 = eye (1) (:, [1]);
+%! A1 = sparse (1, 1, 2);
+%! P = eye (n) (:, randperm (n));
+%! A = sprand (n-3, n, .5);
+%! assert (typeinfo (A * P1), "sparse matrix");
+%! assert (full (A * P1), full (A) * P1);
+%! assert (typeinfo (P1 * A), "sparse matrix");
+%! assert (full (P1 * A), P1 * full (A));
+%! assert (typeinfo (A1 * P), "sparse matrix");
+%! assert (full (A1 * P), full (A1) * P);
+%! assert (typeinfo (P * A1), "sparse matrix");
+%! assert (full (P * A1), P * full (A1));
+
+## permuting a matrix with exceptional values does not introduce new ones.
+%!test
+%! n = 5;
+%! pc = randperm (n);
+%! Pc = eye (n) (:, pc);
+%! pr = randperm (n);
+%! Pr = eye (n) (pr, :);
+%! A = rand (n);
+%! A(n, n-2) = NaN;
+%! A(3, 1) = Inf;
+%! assert (Pr * A * Pc, A(pr, pc));
+
+## conversion to sparse form
+%!test
+%! n = 7;
+%! P = eye (n) (:, randperm (n));
+%! sP = sparse (P);
+%! assert (full (sP), full (P));
+%! assert (size (find (sP), 1), n);
+%! [I, J, V] = find (sP);
+%! assert (all (V == 1));
+
+########################################
+## Diagonal matrices
+
+## square row scaling
+%!test
+%! m = 7;
+%! n = 11;
+%! A = rand (m, n);
+%! scalefact = rand (m, 1);
+%! Dr = diag (scalefact);
+%! assert (Dr * A, repmat (scalefact, 1, n) .* A);
+%! assert (Dr \ A, A ./ repmat (scalefact, 1, n));
+%! scalefact(m-1) = Inf;
+%! Dr(m-1, m-1) = 0;
+%! assert (Dr \ A, A ./ repmat (scalefact, 1, n));
+
+## square column scaling
+%!test
+%! m = 13;
+%! n = 11;
+%! A = rand (m, n);
+%! scalefact = rand (1, n);
+%! Dc = diag (scalefact);
+%! assert (A * Dc, repmat (scalefact, m, 1) .* A);
+%! assert (A / Dc, A ./ repmat (scalefact, m, 1));
+%! scalefact(n-1) = Inf;
+%! Dc(n-1, n-1) = 0;
+%! assert (A / Dc, A ./ repmat (scalefact, m, 1));
+
+## arithmetic
+%!test
+%! m = 9;
+%! n = 7;
+%! mn = min (m, n);
+%! d1 = rand (mn, 1) + I () * rand (mn, 1);
+%! D1 = diag (d1, m, n);
+%! d2 = rand (mn, 1);
+%! D2 = diag (d2, m, n);
+%! D1D2 = D1 + D2;
+%! assert (typeinfo (D1D2), "complex diagonal matrix");
+%! assert (diag (D1D2), d1 + d2);
+%! D1D2 = D2.' * D1;
+%! assert (typeinfo (D1D2), "complex diagonal matrix");
+%! assert (diag (D1D2), d1 .* d2);
+
+## slicing
+%!test
+%! m = 13;
+%! n = 6;
+%! mn = min (m, n);
+%! d = rand (mn, 1);
+%! D = diag (d, m, n);
+%! Dslice = D (1:(m-3), 1:(n-2));
+%! assert (typeinfo (Dslice), "diagonal matrix");
+
+## preserve dense matrix structure when scaling
+%!assert (typeinfo (rand (8) * (3 * eye (8))), "matrix");
+%!assert (typeinfo ((3 * eye (8)) * rand (8)), "matrix");
+
+## preserve sparse matrix structure when scaling
+%!assert (typeinfo (sprand (8, 8, .5) * (3 * eye (8))), "sparse matrix");
+%!assert (typeinfo (sprand (8, 8, .5) * (3 * eye (8))'), "sparse matrix");
+%!assert (typeinfo (((3 + 2 * I ()) * eye (8)) * sprand (8, 8, .5)), "sparse complex matrix");
+%!assert (typeinfo (((3 + 2 * I ()) * eye (8))' * sprand (8, 8, .5)), "sparse complex matrix");
+%!assert (typeinfo (sprand (8, 8, .5) * ((3 + 2 * I ()) * eye (8)).'), "sparse complex matrix");
+
+## scaling a matrix with exceptional values does not introduce new ones.
+%!test
+%! n = 6;
+%! dr = rand (n, 1);
+%! Dr = diag (dr);
+%! dc = rand (1, n);
+%! Dc = diag (dc);
+%! A = rand (n);
+%! A(n, n-2) = NaN;
+%! A(4, 1) = Inf;
+%! assert (Dr * A * Dc, A .* kron (dr, dc), eps);
+
+## sparse inverse row scaling with a zero factor
+%!test
+%! n = 8;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (n, 1);
+%! Dr = diag (scalefact);
+%! scalefact(n-1) = Inf;
+%! Dr(n-1, n-1) = 0;
+%! assert (full (Dr \ A), full (A) ./ repmat (scalefact, 1, n));
+
+## narrow sparse inverse row scaling
+%!test
+%! n = 8;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (n-2, 1);
+%! Dr = diag (scalefact, n, n-2);
+%! assert (full (Dr \ A), Dr \ full(A))
+
+## sparse inverse column scaling with a zero factor
+%!test
+%! n = 11;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (1, n);
+%! Dc = diag (scalefact);
+%! scalefact(n-1) = Inf;
+%! Dc(n-1, n-1) = 0;
+%! assert (full (A / Dc), full(A) / Dc)
+
+## short sparse inverse column scaling
+%!test
+%! n = 7;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (1, n-2) + I () * rand(1, n-2);
+%! Dc = diag (scalefact, n-2, n);
+%! assert (full (A / Dc), full(A) / Dc)
+
+## adding sparse and diagonal stays sparse
+%!test
+%! n = 9;
+%! A = sprand (n, n, .5);
+%! D = 2 * eye (n);
+%! assert (typeinfo (A + D), "sparse matrix")
+%! assert (typeinfo (A - D), "sparse matrix")
+%! D = D * I () + D;
+%! assert (typeinfo (A - D), "sparse complex matrix")
+%! A = A * I () + A;
+%! assert (typeinfo (D - A), "sparse complex matrix")
+
+## adding sparse and diagonal stays sparse
+%!test
+%! n = 9;
+%! A = sprand (n, n, .5);
+%! D = 2 * eye (n);
+%! assert (full (A + D), full (A) + D)
+%! assert (full (A - D), full (A) - D)
+%! D = D * I () + D;
+%! assert (full (D + A), D + full (A))
+%! A = A * I () + A;
+%! A(6, 4) = nan ();
+%! assert (full (D - A), D - full (A))
diff --git a/test/test_error.m b/test/test_error.m
new file mode 100644
index 0000000..3557ec1
--- /dev/null
+++ b/test/test_error.m
@@ -0,0 +1,83 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/error/error-1.m
+%!function g () 
+%! error ("foo");
+%!function f () 
+%! g (); 
+%!error <foo> f ();
+
+%% test/octave.test/error/error-2.m
+%!function g () 
+%! error ("foo\n");
+%!function f () 
+%! g 
+%!error <foo> f ();
+
+%% test/octave.test/error/error-3.m
+%!error error ();
+
+%% test/octave.test/error/error-4.m
+%!error <foo> error ("foo\n");
+
+%% FIXME Why can't I use %!warning <foo> f;
+%% test/octave.test/error/warning-1.m
+%!function g ()
+%! warning ("foo");
+%!function f ()
+%! g;
+%!test
+%! fail("f","warning","foo");
+
+%% test/octave.test/error/warning-2.m
+%!test
+%! st.identifier = "backtrace";
+%! ws = warning ("query","backtrace");
+%! warning ("on","backtrace");
+%! st.state = "on";
+%! assert(warning ("query","backtrace"),st);
+%! warning ("off","backtrace");
+%! st.state = "off";
+%! assert(warning ("query","backtrace"),st);
+%! warning (ws.state,"backtrace");
+
+%% FIXME This test no longer makes sense with new warning syntax
+%% test/octave.test/error/warning-3.m
+%!#warning <foo> warning ("foo", 1);
+
+%% test/octave.test/error/usage-1.m
+%!function g () 
+%! usage ("foo");
+%!function f () 
+%! g (); 
+%!error <foo> f ();
+
+%% test/octave.test/error/usage-2.m
+%!function g () 
+%! usage ("foo");
+%!function f () 
+%! g 
+%!error <foo> f ();
+
+%% test/octave.test/error/usage-3.m
+%!error usage ();
+
+%% test/octave.test/error/usage-4.m
+%!error <foo> usage ("foo\n");
+
diff --git a/test/test_eval-catch.m b/test/test_eval-catch.m
new file mode 100644
index 0000000..5b1f853
--- /dev/null
+++ b/test/test_eval-catch.m
@@ -0,0 +1,74 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/eval-catch/eval-catch-1.m
+%!test
+%! eval ("clear a; a;", "");
+
+%% test/octave.test/eval-catch/eval-catch-2.m
+%!test
+%! eval ("", "error('Shouldn't get here');");
+
+%% test/octave.test/eval-catch/eval-catch-3.m
+%!test
+%! eval ("clear a; a; x = 0;", "x = 1;");
+%! assert (x, 1);
+
+%% FIXME This is redundant with the changes to the above
+%% test/octave.test/eval-catch/eval-catch-4.m
+
+%% test/octave.test/eval-catch/eval-catch-5.m
+%!test
+%! eval ("clear a; a; str = '';", "str=lasterr;");
+%! assert(lasterr()(1:13),"`a' undefined");
+%! assert(str(1:13),"`a' undefined");
+
+%% test/octave.test/eval-catch/eval-catch-6.m
+%!test
+%! eval ("error (\"user-defined error\"); str = '';", "str = lasterr;");
+%! assert(lasterr()(1:18),"user-defined error");
+%! assert(str(1:18),"user-defined error");
+
+%% test/octave.test/eval-catch/eval-catch-7.m
+%!function ms = mangle (s)
+%!  ## Wrap angle brackets around S.
+%!  ms = cstrcat ("<", s, ">");
+%!test
+%! eval ("clear a; a; str='';", "str = mangle (lasterr);");
+%! assert(mangle(lasterr)(1:14),"<`a' undefined");
+%! assert(str(1:14),"<`a' undefined");
+
+%% test/octave.test/eval-catch/eval-catch-8.m
+%!test
+%! eval ("eval (\"clear a; a;str1='';\", \"str1=lasterr;\"); clear b; b; str2='';",
+%! "str2 = lasterr;");
+%! assert(str1(1:13),"`a' undefined");
+%! assert(str2(1:13),"`b' undefined");
+
+%% test/octave.test/eval-catch/eval-catch-9.m
+%!test
+%! eval ("clear a; a; str1='';",
+%! "eval (\"clear b; b; str2='';\", \"str2=lasterr;\"); str1=lasterr;");
+%! assert(str1(1:13),"`b' undefined");
+%! assert(str2(1:13),"`b' undefined");
+
+%% test/octave.test/eval-catch/eval-catch-10.m
+%!test
+%! eval ("eval (\"clear a; a; str='';\",\"error (cstrcat (\\\"rethrow: \\\", lasterr));str='';\");",
+%! "str=lasterr;");
+%! assert(str(1:22),"rethrow: `a' undefined");
diff --git a/test/test_for.m b/test/test_for.m
new file mode 100644
index 0000000..69bcc22
--- /dev/null
+++ b/test/test_for.m
@@ -0,0 +1,111 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/for/for-1.m
+%!test
+%! for i = 1
+%! printf_assert ("%d", i);
+%! end
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1"));
+
+%% test/octave.test/for/for-2.m
+%!test
+%! for i = 1:4
+%! printf_assert ("%d", i);
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1234"));
+
+%% test/octave.test/for/for-3.m
+%!test
+%! for i = [1,2,3,4]
+%! printf_assert ("%d", i);
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1234"));
+
+%% test/octave.test/for/for-4.m
+%!test
+%! for i = [1,2;3,4]
+%! printf_assert ("%d", i(1,1));
+%! printf_assert ("%d", i(2,1));
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1324"));
+
+%% test/octave.test/for/for-5.m
+%!test
+%! for i = I
+%! printf_assert ("%d", imag (i));
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1"));
+
+%% test/octave.test/for/for-6.m
+%!test
+%! for i = [1,2,3,4]*I
+%! printf_assert ("%d", imag (i));
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1234"));
+
+%% test/octave.test/for/for-7.m
+%!test
+%! for i = [1,2;3,4]*I
+%! printf_assert ("%d", imag (i(1,1)));
+%! printf_assert ("%d", imag (i(2,1)));
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("1324"));
+
+%% test/octave.test/for/for-8.m
+%!test
+%! for i = [1,2,3,4]
+%! if (i > 2)
+%! break;
+%! endif
+%! printf_assert ("%d", i);
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("12"));
+
+%% test/octave.test/for/for-9.m
+%!test
+%! for i = [1,2,3,4]
+%! if (i < 3)
+%! continue;
+%! endif
+%! printf_assert ("%d", i);
+%! endfor
+%! printf_assert ("\n");
+%! assert(prog_output_assert("34"));
+
+%!test
+%! a = [1,3;2,4];
+%! j = 0;
+%! for i = cat (3, a, 4 + a)
+%!   assert (i, [1;2] + 2*j++)
+%! endfor
+
+%!test
+%! a = {1,3;2,4};
+%! j = 0;
+%! for i = cat (3, a, cellfun(@(x) 4 + x, a, 'UniformOutput', 0))
+%!   assert (i, {1 + 2*j; 2 + 2*j++})
+%! endfor
diff --git a/test/test_func.m b/test/test_func.m
new file mode 100644
index 0000000..b133988
--- /dev/null
+++ b/test/test_func.m
@@ -0,0 +1,192 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## This piece of test code ensures that all operations which work on 
+## dimensions alone (squeeze, triu, etc.) work for all objects and 
+## preserve type. Even if the object is an empty matrix. This code is
+## not to check that the function itself returns teh correct result,
+## just that the results are consistent for all types.
+
+%!function __fntestfunc__ (fn, mn, varargin)
+%!  typ = {'double', 'complex', 'logical', 'sparse', 'complex sparse', ...
+%!         'logical sparse', 'int8', 'int16', 'int32', 'int64', 'uint8', ...
+%!         'uint16', 'uint32', 'uint64', 'char', 'cell', 'struct', ...
+%!         'single', 'single complex'};
+%!
+%!  cmplx = [2, 5, 18];
+%!  nlogical = [3, 6];
+%!  ninteger = [7, 8, 9, 10, 11, 12, 13, 14];
+%!  nsparse = [4, 5, 6];
+%!  skip = {};
+%!
+%!  if (length (varargin) > 0 && iscell (varargin{1}))
+%!    skip = varargin{1};
+%!    varargin(1) = [];
+%!  endif
+%!
+%!  for i = 1 : length(typ)
+%!    if (any (strcmp (skip, typ {i})))
+%!      continue;
+%!    endif
+%!    m = mn;
+%!
+%!    if (any (nsparse == i))
+%!      if (ndims (m) > 2)
+%!        sz = size (m);
+%!        m = reshape (m, [sz(1), prod(sz (2:end))]);
+%!      endif
+%!      if (any (cmplx == i))
+%!        m = sparse ((1 + 1i) * m);
+%!      else
+%!        m = sparse (m);
+%!      endif
+%!    else
+%!      if (any (cmplx == i))
+%!        m = (1 + 1i) * m;
+%!      endif
+%!    endif
+%!    if (any (nlogical == i))
+%!      m = cast (m, 'logical');
+%!    endif
+%!    if (any (ninteger == i))
+%!      m = cast (m, typ{i});
+%!    endif
+%!    if (strcmp (typ{i}, 'cell'))
+%!      m = num2cell (m);
+%!    elseif (strcmp (typ{i}, 'struct'))
+%!      m = struct ('fld', num2cell (m));
+%!    endif
+%!
+%!    y = feval (fn, m, varargin{:});
+%!    y2 = feval (fn, reshape (mn, size (m)), varargin{:});
+%!    if (!strcmp (class (y), class (m)) ||
+%!	   issparse (y) != issparse (m) || !size_equal (y, y2))
+%!      error ('failed for type %s\n', typ{i});
+%!    endif
+%!    if (!(strcmp (typ{i}, 'cell') || strcmp (typ{i}, 'struct')) &&
+%!	  any (vec (cast (real (y), 'double')) !=
+%!             vec (feval (fn , cast (real (m), 'double'), varargin{:}))))
+%!      error ('failed for type %s\n', typ{i});
+%!    endif
+%!  endfor
+%! endfunction
+
+%!shared m0, m1, m2, m3
+%! m0 = [1:5];
+%! m1 = reshape ([1 : 30], [5, 6]);
+%! m2 = reshape ([1 : 30], [5, 1, 6]);
+%! m3 = [];
+
+%!test
+%! __fntestfunc__('triu', m1, {'struct'});
+%!test
+%! __fntestfunc__ ('triu', m1, {'struct'}, -1);
+%!test
+%! __fntestfunc__ ('triu', m1, {'struct'}, 1);
+%!test
+%! __fntestfunc__('triu', m3, {'struct'});
+%!test
+%! __fntestfunc__ ('tril', m1, {'struct'});
+%!test
+%! __fntestfunc__ ('tril', m1, {'struct'}, -1);
+%!test
+%! __fntestfunc__ ('tril', m1, {'struct'}, 1);
+%!test
+%! __fntestfunc__('tril', m3, {'struct'});
+%!test
+%! __fntestfunc__ ('squeeze', m2);
+%!test
+%! __fntestfunc__ ('squeeze', m3);
+%!test
+%! __fntestfunc__ ('permute', m1, [2, 1]);
+%!test
+%! __fntestfunc__ ('permute', m2, {'sparse', 'logical sparse', 'complex sparse'}, [3, 1, 2]);
+%!test
+%! __fntestfunc__ ('permute', m3, [2, 1]);
+%!test
+%! __fntestfunc__ ('ipermute', m1, [2, 1]);
+%!test
+%! __fntestfunc__ ('ipermute', m2, {'sparse', 'logical sparse', 'complex sparse'}, [3, 1, 2]);
+%!test
+%! __fntestfunc__ ('ipermute', m3, [2, 1]);
+%!test
+%! __fntestfunc__ ('shiftdim', m2, 1);
+%!test
+%! __fntestfunc__ ('shiftdim', m2, {'sparse', 'logical sparse', 'complex sparse'}, -1);
+%!test
+%! __fntestfunc__ ('shiftdim', m3, 1);
+%!test
+%! __fntestfunc__ ('circshift', m2, 1);
+%!test
+%! __fntestfunc__ ('circshift', m2, [1, -1]);
+%!test
+%! __fntestfunc__ ('circshift', m3, 1);
+%!test
+%! __fntestfunc__ ('reshape', m2, [6, 5]);
+%!test
+%! __fntestfunc__ ('reshape', m3, [1, 0]);
+%!test
+%! __fntestfunc__ ('diag', m0, {'struct'});
+%!test
+%! __fntestfunc__ ('diag', m0, {'struct'}, 1);
+%!test
+%! __fntestfunc__ ('diag', m0, {'struct'}, -1);
+%!test
+%! __fntestfunc__ ('diag', m1, {'struct'});
+%!test
+%! __fntestfunc__ ('diag', m1, {'struct'}, 1);
+%!test
+%! __fntestfunc__ ('diag', m1, {'struct'}, -1);
+%!test
+%! __fntestfunc__ ('diag', m3, {'struct'});
+%!test
+%! __fntestfunc__ ('fliplr', m1);
+%!test
+%! __fntestfunc__ ('fliplr', m3);
+%!test
+%! __fntestfunc__ ('flipud', m1);
+%!test
+%! __fntestfunc__ ('flipud', m3);
+%!test
+%! __fntestfunc__ ('flipdim', m1, 2);
+%!test
+%! __fntestfunc__ ('flipdim', m3, 2);
+%!test
+%! __fntestfunc__ ('transpose', m1);
+%!test
+%! __fntestfunc__ ('transpose', m3);
+%!test
+%! __fntestfunc__ ('ctranspose', m1);
+%!test
+%! __fntestfunc__ ('ctranspose', m3);
+%!test
+%! __fntestfunc__ ('rot90', m1);
+%!test
+%! __fntestfunc__ ('rot90', m1, 2);
+%!test
+%! __fntestfunc__ ('rot90', m1, -1);
+%!test
+%! __fntestfunc__ ('rot90', m3);
+%!test
+%! __fntestfunc__ ('rotdim', m2, 1, [1, 2]);
+%!test
+%! __fntestfunc__ ('rotdim', m2, 2, [1, 2]);
+%!test
+%! __fntestfunc__ ('rotdim', m2, -1, [1, 2]);
+%!test
+%! __fntestfunc__ ('rotdim', m3, 1, [1, 2]);
diff --git a/test/test_global.m b/test/test_global.m
new file mode 100644
index 0000000..e3c4fad
--- /dev/null
+++ b/test/test_global.m
@@ -0,0 +1,82 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/global/global-1.m
+%!test
+%! global G = 1;
+%! assert(G,1)
+
+%% test/octave.test/global/global-2.m
+%!function f ()
+%!  global G;
+%!  assert(G,1);
+%!test
+%! global G = 1;
+%! f;
+
+%% test/octave.test/global/global-3.m
+%!function f ()
+%!  fail("G");
+%!test
+%! global G = 1;
+%! f();
+
+%% test/octave.test/global/global-4.m
+%!function f ()
+%!  global H = 1;
+%!test
+%!  f;
+%!  fail("H");
+
+%% test/octave.test/global/global-5.m
+%!function f ()
+%!  global H = 1;
+%!test
+%!function g ()
+%!  fail("H");
+%!test
+%! g();
+
+%% test/octave.test/global/global-6.m
+%!function f ()
+%!  global H = 1;
+%!function g ()
+%!  global H;
+%!  assert(H,1);
+%!test
+%! f();
+%! g();
+
+%% test/octave.test/global/global-7.m
+%!test
+%!function f ()
+%!  global H = 1;
+%!test
+%! fail("H");
+
+%% test/octave.test/global/global-8.m
+%!function f ()
+%!  global H = 1;
+%!function g ()
+%!  global H;
+%!  assert(H,1)
+%!test
+%! f;
+%! clear H
+%! g;
+
diff --git a/test/test_if.m b/test/test_if.m
new file mode 100644
index 0000000..cacc4d1
--- /dev/null
+++ b/test/test_if.m
@@ -0,0 +1,87 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/if/if-1.m
+%!test
+%! i = 0;
+%! if (i == 0)
+%! i++;
+%! printf_assert ("%d\n", i);
+%! endif
+%! assert(prog_output_assert("1"));
+
+%% test/octave.test/if/if-2.m
+%!test
+%! if (eye (2))
+%! printf_assert ("fail\n");
+%! else
+%! printf_assert ("pass\n");
+%! end
+%! assert(prog_output_assert("pass"));
+
+%% test/octave.test/if/if-3.m
+%!test
+%! x = 2;
+%! if (eye (2))
+%! printf_assert ("fail\n");
+%! elseif (x)
+%! printf_assert ("pass\n");
+%! endif
+%! assert(prog_output_assert("pass"));
+
+%% test/octave.test/if/if-4.m
+%!test
+%! x = 0;
+%! y = -2;
+%! if (eye (2))
+%! printf_assert ("fail\n");
+%! elseif (x)
+%! printf_assert ("fail\n");
+%! elseif (y)
+%! printf_assert ("pass\n");
+%! end
+%! assert(prog_output_assert("pass"));
+
+%% test/octave.test/if/if-5.m
+%!test
+%! x = 0;
+%! y = -2;
+%! if (eye (2))
+%! printf_assert ("fail\n");
+%! elseif (x)
+%! printf_assert ("fail\n");
+%! elseif (x)
+%! printf_assert ("fail\n");
+%! else
+%! printf_assert ("pass\n");
+%! endif
+%! assert(prog_output_assert("pass"));
+
+%% test/octave.test/if/if-6.m
+%!test
+%! x = 0;
+%! y = -2;
+%! if (y)
+%! printf_assert ("pass\n");
+%! elseif (x)
+%! printf_assert ("fail\n");
+%! elseif (x)
+%! printf_assert ("fail\n");
+%! end
+%! assert(prog_output_assert("pass"));
+
diff --git a/test/test_index-wfi-f.m b/test/test_index-wfi-f.m
new file mode 100644
index 0000000..74b693d
--- /dev/null
+++ b/test/test_index-wfi-f.m
@@ -0,0 +1,507 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/index-wfi-f/s-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [];
+%! assert(isempty (a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(1),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(:),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(:,:),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-5.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(1,:),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-6.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(:,1),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-7.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(isempty (a(logical (0))));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-8.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(-1)");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-9.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(2);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-10.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(2,:);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-11.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(:,2);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-12.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(-1,:);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-13.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(:,-1);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-14.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([1,2,3]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-15.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([1;2;3]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-16.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([1,2;3,4]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-17.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([0,1]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-18.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([0;1]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-19.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([-1,0]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/s-20.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([-1;0]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(a(1),4);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(a(2),3);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(:) == a_prime));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(1,:) == a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-5.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(a(:,3),2);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-6.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(:,:) == a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-7.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(logical ([0,1,1,0])) == mid_a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-8.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(0);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-9.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(5);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-10.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(0,1);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-11.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a(logical (0),:)));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-12.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(:,0);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-13.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a([])));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-14.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a([],:)));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/v-15.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a(:,[])));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/m-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! assert(all (all (a(:,:) == a)));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/m-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! assert(all (a(:) == a_fvec));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/m-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! fail("a(0);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-f/m-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! assert(a(2),3);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% Additional tests
+%!shared a, b
+%! a = [1,2;3,4];
+%! b = a;
+%! b(:,:,2) = [5,6;7,8];
+
+%!assert (a(:), [1;3;2;4]);
+%!assert (a(1:2), [1,3]);
+%!assert (a(:,:), [1,2;3,4]);
+%!assert (a(:,1), [1;3]);
+%!assert (a(1,1), 1);
+%!assert (a(1:2,1), [1;3]);
+%!assert (a(:,:,1), [1,2;3,4]);
+
+%!test
+%! c(:,:,1) = [1,2;3,4];
+%! c(:,:,2) = [1,2;3,4];
+%! assert (a(:,:,[1,1]),c)
+
+%!test
+%! c(:,:,1,1) = [1,2;3,4];
+%! c(:,:,1,2) = [1,2;3,4];
+%! assert (a(:,:,1,[1,1]),c)
+
+%!test
+%! c(:,:,1,1) = [1,2;3,4];
+%! c(:,:,2,1) = [1,2;3,4];
+%! c(:,:,1,2) = [1,2;3,4];
+%! c(:,:,2,2) = [1,2;3,4];
+%! assert (a(:,:,[1,1],[1,1]),c)
+
+%!assert (a(1,[]), zeros(1,0));
+%!assert (a(1,[],[1,1]), zeros(1,0,2));
+%!assert (a(1,1,[]), zeros(1,1,0));
+
+%!test
+%! c (1:10,1) = 1:10;
+%! assert (c, [1:10]');
+
+%!assert (b(:), [1; 3; 2; 4; 5; 7; 6; 8]);
+%!assert (b(:,:), [1, 2, 5, 6; 3, 4, 7, 8]);
+%!assert (b(:,1), [1;3]);
+%!assert (b(:,:,:), reshape ([1,3,2,4,5,7,6,8],[2,2,2]));
+%!assert (b(:,1,1), [1;3]);
+%!assert (b(:,1,1,[1,1]),reshape([1,3,1,3],[2,1,1,2]));
+%!assert (b(1,3), 5);
+%!assert (b(1,[3,4]), [5,6]);
+%!assert (b(1,1:4), [1,2,5,6]);
+%!assert (b(1,[],:), zeros (1,0,2));
+%!assert (b(1,[]), zeros(1,0));
+%!assert (b(:,3), [5;7])
+%!assert (b([1,2],3), [5;7])
+%!assert (b(true(2,1),3), [5;7])
+%!assert (b(false(2,1),3), zeros(0,1))
+%!assert (b([],3), zeros(0,1));
+
+%!shared x
+%! # Dummy shared block to clear any previous definitions
+%! x = 1;
+
+%!test
+%! a(1,:) = [1,3];
+%! assert (a, [1,3]);
+
+%!test
+%! a(1,:) = [1;3];
+%! assert (a, [1,3]);
+
+%!test
+%! a(:,1) = [1;3];
+%! assert (a, [1;3]);
+
+%!test
+%! a = [1,2;3,4];
+%! b (1,:,:) = a;
+%! assert (b, reshape (a, [1,2,2]));
+
+%!test
+%! a(1,1:4,2) = reshape (1:4, [1,1,4]);
+%! b(:,:,2) = 1:4;
+%! assert (a, b);
+
+%!test
+%! a(:,:,:) = 1:4; 
+%! assert (a, [1:4]);
+
+%!test
+%! a(:,:,1) = 1:4;;
+%! assert (a, [1:4]);
+
+%!test
+%! a(:,:,1) = [1:4]';
+%! assert (a, [1:4]');
+
+%!test
+%! a(:,:,1) = reshape(1:4,[1,1,4]);
+%! assert (a, [1:4]');
+
+%!test
+%! a(:,1,:) = 1:4;
+%! assert (a, reshape (1:4,[1,1,4]));
+
+%!test
+%! a(:,1,:) = [1:4]';
+%! assert (a, [1:4]');
+
+%!test
+%! a(:,1,:) = reshape(1:4,[1,1,4]);;
+%! assert (a, [1:4]');
+
+%!test
+%! a(1,:,:) = 1:4;
+%! assert (a, reshape (1:4,[1,1,4]));
+
+%!test
+%! a(1,:,:) = [1:4]';
+%! assert (a, [1:4]);
+
+%!test
+%! a(1,:,:) = reshape(1:4,[1,1,4]);
+%! assert (a, [1:4]);
+
+%!test
+%! a(1,:,:,:) = reshape(1:4,[1,1,4]);
+%! assert (a, reshape (1:4,[1,1,1,4]));
+
+%!error (a(1:2,1:2) = 1:4)
diff --git a/test/test_index-wfi-t.m b/test/test_index-wfi-t.m
new file mode 100644
index 0000000..c6727db
--- /dev/null
+++ b/test/test_index-wfi-t.m
@@ -0,0 +1,379 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/index-wfi-t/s-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warn_fortran_indexing = 1;
+%! a = [];
+%! assert(isempty (a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(1),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(:),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(:,:),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-5.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(1,:),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-6.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(a(:,1),1);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-7.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! assert(isempty (a(logical (0))));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-8.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(-1);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-9.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(2);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-10.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(2,:);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-11.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(:,2);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-12.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(-1,:);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-13.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a(:,-1);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-14.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([1,2,3]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-15.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([1;2;3]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-16.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([1,2;3,4]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-17.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([0,1]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-18.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([0;1]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-19.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([-1,0]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/s-20.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 1;
+%! fail("a([-1;0]);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(a(1),4);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(a(2),3);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(:) == a_prime));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(1,:) == a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-5.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(a(:,3),2);
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-6.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(:,:) == a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-7.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(all (a(logical ([0,1,1,0])) == mid_a));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-8.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(0);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-9.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(5);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-10.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(0,1);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-11.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a(logical (0),:)));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-12.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! fail("a(:,0);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-13.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a([])));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-14.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a([],:)));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/v-15.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [4,3,2,1];
+%! a_prime = [4;3;2;1];
+%! mid_a = [3,2];
+%! assert(isempty (a(:,[])));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/m-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! assert(all (all (a(:,:) == a)));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/m-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! assert(all (a(:) == a_fvec));
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/m-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! fail("a(0);");
+%! warning (wfi.state, "Octave:fortran-indexing");
+
+%% test/octave.test/index-wfi-t/m-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [1,2;3,4];
+%! a_fvec = [1;3;2;4];
+%! a_col_1 = [1;3];
+%! a_col_2 = [2;4];
+%! a_row_1 = [1,2];
+%! a_row_2 = [3,4];
+%! fail("a(2);","warning");
+%! warning (wfi.state, "Octave:fortran-indexing");
diff --git a/test/test_io.m b/test/test_io.m
new file mode 100644
index 0000000..1e9597c
--- /dev/null
+++ b/test/test_io.m
@@ -0,0 +1,594 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## FIXME -- we should skip (or mark as an expected failure) the test for
+## saving sparse matrices to MAT files when using 64-bit indexing since
+## that is not implemented yet.
+
+%% test/octave.test/io/load-save.m
+%!function [ret, files] = testls (input)
+%!  ## flag a1 global so as to test the storage of global flags
+%!  global a1;
+%!
+%!  ## Input or output, so as to be able to exchange between versions
+%!  if (nargin < 1)
+%!    input = 0;
+%!  endif
+%!
+%!  ## Setup some variable to be saved or compared to loaded variables
+%!
+%!  ## scalar
+%!  a1 = 1;
+%!  ## matrix
+%!  persistent a2 = hilb(3);
+%!  ## complex scalar
+%!  persistent a3 = 1 + 1i;
+%!  ## complex matrix
+%!  persistent a4 = hilb(3) + 1i*hilb(3);
+%!  ## bool
+%!  persistent a5 = (1 == 1);
+%!  ## bool matrix
+%!  persistent a6 = ([ones(1,5), zeros(1,5)] == ones(1,10));
+%!  ## range
+%!  persistent a7 = 1:10;
+%!  ## structure
+%!  persistent a8 = struct ("a", a1, "b", a3);
+%!  ## cell array
+%!  persistent a9 = {a1, a3};
+%!  ## string
+%!  persistent a10 = ["test"; "strings"];
+%!  ## int8 array
+%!  persistent a11 = int8(floor(256*rand(2,2)));
+%!  ## int16 array
+%!  persistent a12 = int16(floor(65536*rand(2,2)));
+%!  ## int32 array
+%!  persistent a13 = int32(floor(1e6*rand(2,2)));
+%!  ## int64 array
+%!  persistent a14 = int64(floor(10*rand(2,2)));
+%!  ## uint8 array
+%!  persistent a15 = uint8(floor(256*rand(2,2)));
+%!  ## uint16 array
+%!  persistent a16 = uint16(floor(65536*rand(2,2)));
+%!  ## int32 array
+%!  persistent a17 = uint32(floor(1e6*rand(2,2)));
+%!  ## uint64 array
+%!  persistent a18 = uint64(floor(10*rand(2,2)));
+%!  ## sparse
+%!  persistent a19 = sprandn(100,100,0.01);
+%!  ## complex sparse
+%!  persistent a20 = sprandn(100,100,0.01) + 1i * sprandn(100,100,0.01);
+%!
+%!  ret = 0;
+%!
+%!  files = {"text.mat", "binary.mat", "mat5.mat", "mat7.mat"};
+%!  opts = {"-z -text", "-z -binary", "-z -mat", "-v7"};
+%!  tols = {2*eps, 0, 0, 0};
+%!
+%!  vars = "a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20";
+%!  if (! input)
+%!    for i = 1:length (files)
+%!      eval (sprintf ("save %s %s %s", opts{i}, files{i}, vars));
+%!    endfor
+%!  else
+%!    b1 = a1; b2 = a2; b3 = a3; b4 = a4; b5 = a5;
+%!    b6 = a6; b7 = a7; b8 = a8; b9 = a9;
+%!    b10 = a10; b11 = a11; b12 = a12; b13 = a13; b14 = a14; b15 = a15;
+%!    b16 = a16; b17 = a17; b18 = a18; b19 = a19; b20 = a20;
+%!
+%!    for i = length (files)
+%!
+%!      clear a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a19 a20;
+%!
+%!      file = files{i};
+%!      tol = tols{i};
+%!
+%!      load (file);
+%!
+%!      assert (a1, b1, tol);
+%!      assert (a2, b2, tol);
+%!      assert (a3, b3, tol);
+%!      assert (a4, b4, tol);
+%!
+%!      if (! isequal (a5, b5))
+%!	  error ("failed: %s boolean", file);
+%!      endif
+%!
+%!      if (! strcmp (file, "mat5") && ! strcmp (file, "mat7"))
+%!        if (! isequal (a6, b6))
+%!	    error ("failed: %s boolean matrix", file);
+%!        endif
+%!      endif
+%!
+%!      assert ([a7], [b7], tol);
+%!
+%!      if (! isequal (a8, b8))
+%!	  error ("failed: %s struct", file);
+%!      endif
+%!      
+%!      if (! isequal (a9, b9))
+%!	  error ("failed: %s cell", file);
+%!      endif
+%!      
+%!      if (! isequal (a10, b10))
+%!	  error ("failed: %s string", file);
+%!      endif
+%!
+%!      if (! isequal (a11, b11))
+%!	  error ("failed: %s int8", file);
+%!      endif
+%!
+%!      if (! isequal (a12, b12))
+%!	  error ("failed: %s int16", file);
+%!      endif
+%!
+%!      if (! isequal (a13, b13))
+%!	  error ("failed: %s int32", file);
+%!      endif
+%!
+%!      if (! isequal (a14, b14))
+%!	  error ("failed: %s int64", file);
+%!      endif
+%!
+%!      if (! isequal (a15, b15))
+%!	  error ("failed: %s uint8", file);
+%!      endif
+%!
+%!      if (! isequal (a16, b16))
+%!	  error ("failed: %s uint16", file);
+%!      endif
+%!
+%!      if (! isequal (a17, b17))
+%!	  error ("failed: %s uint32", file);
+%!      endif
+%!
+%!      if (! isequal (a18, b18))
+%!	  error ("failed: %s uint64", file);
+%!      endif
+%!
+%!      assert (a19, b19, tol);
+%!      assert (a20, b20, tol);
+%!
+%!      ## Test for global flags
+%!      if (! isglobal ("a1") || isglobal ("a2") || isglobal ("a3")
+%!          || isglobal ("a4") || isglobal ("a5") || isglobal ("a6")
+%!          || isglobal ("a7") || isglobal ("a8") || isglobal ("a9")
+%!          || isglobal ("a10") || isglobal ("a11") || isglobal ("a12")
+%!          || isglobal ("a13") || isglobal ("a14") || isglobal ("a15")
+%!          || isglobal ("a16") || isglobal ("a17") || isglobal ("a18")
+%!          || isglobal ("a19") || isglobal ("a20"))
+%!	  error ("failed: %s global test", file); 
+%!      endif
+%!    endfor
+%!  endif
+%!
+%!  ret = 1;
+%!
+%!test
+%! 
+%! [save_status, save_files] = testls (0);
+%! [load_status, load_files] = testls (1);
+%! 
+%! for f = [save_files, load_files]
+%!   unlink (f{1});
+%! endfor
+%! 
+%! assert(save_status && load_status);
+%!
+%!test
+%! 
+%! STR.scalar_fld = 1;
+%! STR.matrix_fld = [1.1,2;3,4];
+%! STR.string_fld = "Octave";
+%! STR.struct_fld.x = 0;
+%! STR.struct_fld.y = 1;
+%! 
+%! save struct.dat -struct STR;
+%! STR = load ("struct.dat");
+%!
+%! assert(STR.scalar_fld == 1 && ...
+%! 	STR.matrix_fld == [1.1,2;3,4] && ...
+%! 	STR.string_fld == "Octave" && ...
+%! 	STR.struct_fld.x == 0 && ...
+%! 	STR.struct_fld.y == 1 );
+%!
+%!
+%! save -binary struct.dat -struct STR matrix_fld str*_fld;
+%! STR = load ("struct.dat");
+%!
+%! assert(!isfield(STR,"scalar_fld") && ...
+%! 	STR.matrix_fld == [1.1,2;3,4] && ...
+%! 	STR.string_fld == "Octave" && ...
+%! 	STR.struct_fld.x == 0 && ...
+%! 	STR.struct_fld.y == 1);
+%!
+%! delete struct.dat;
+%!
+%!test
+%! matrix1 = rand(100, 2);
+%! save -ascii matrix.ascii matrix1
+%! matrix2 = load ("matrix.ascii");
+%! assert (matrix1, matrix2, 1e-9)
+%!
+%! delete matrix.ascii;
+
+%% FIXME Disable this test as it writes to stdout and there is no easy
+%% way to recover output. Need to spawn new octave process and pipe stdout
+%% somewhere to treat this case
+%% test/octave.test/io/puts-1.m
+%!#test
+%! puts ("foo\n");
+
+%% test/octave.test/io/puts-2.m
+%!assert(puts (1),-1);
+
+%% test/octave.test/io/puts-3.m
+%!error <Invalid call to puts.*> puts ();
+
+%% test/octave.test/io/puts-4.m
+%!error <Invalid call to puts.*> puts (1, 2);
+
+%% test/octave.test/io/sscanf-1.m
+%!test
+%! [a, b, c] = sscanf ("1.2 3 foo", "%f%d%s", "C");
+%! [v1, c1, m1] = sscanf ("1 2 3 4 5 6", "%d");
+%! [v2, c2, m2] = sscanf ("1 2 bar 3 4 5 6", "%d");
+%! 
+%! assert((a == 1.2 && b == 3 && c == "foo"
+%! && v1 == [1; 2; 3; 4; 5; 6] && c1 == 6 && ischar (m1)
+%! && v2 == [1; 2] && c2 == 2 && ischar (m2)));
+
+%% test/octave.test/io/sscanf-2.m
+%!error <Invalid call to sscanf.*> sscanf ();
+
+%% test/octave.test/io/sscanf-3.m
+%!error sscanf (1, 2);
+
+%% test/octave.test/io/sscanf-4.m
+%!error <Invalid call to sscanf.*> sscanf ("foo", "bar", "C", 1);
+
+%% test/octave.test/io/sscanf-5.m
+%!test
+%! [x, n] = sscanf("   0.024000 0.200 0.200 2.000         1987           5           0  0 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 0 0 0 0 0 0 0 0 0 0 0 0    0 2 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 4 5 1 2    2 5 5 8 2 8 12 6 15 18 28 26 47 88 118 162 192 130 88 56 27 23 14 9 6 3 4 1 0    2 3 1 0 0 0 0 1 0 1 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0   0.026000 0.250 0.250 2.100         3115           3           0  0 0 0 0 0 0 0 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 0 0 0 0 0 0    0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0    0 0 0 0 1 0 1 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 1 0 1    1 1 0 1 0 1 3 2 0 5 15 25 44 66 145 179 193 172 104 57 17 11 12 2 1 0 1 1 0 1    0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.028000 0.300 0.300 2.200         4929           3           0  1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0    0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0    1 0 1 0 1 2 2 3 2 3 14 21 49 80 148 184 218 159 124 63 37 13 12 3 1 1 0 0 0 0    0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.030000 0.350 0.350 2.300         7051           5           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0    0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1    0 0 1 0 0 0 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1    0 0 0 2 0 0 0 1 5 6 14 28 51 88 154 177 208 169 124 65 39 15 5 3 3 2 1 0 1 0 1   0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0    0 0 0 1 0 0 0 0 0 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 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.032000 0.400 0.400 2.400         9113           4           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0    1 0 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 2 0    1 0 0 1 1 0 2 3 5 3 17 30 60 117 156 189 209 129 102 64 56 16 11 4 2 2 0 0 0 0   1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0   0.034000 0.450 0.450 2.500        11811           6           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0    0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0    0 0 2 1 0 0 1 0 5 5 15 21 57 99 149 190 195 159 130 69 41 16 10 2 5 3 0 1 0 0    0 0 0 1 0 1 0 1 0 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 0 0 0 0    0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.036000 0.500 0.500 2.600        14985           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 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 0 0 0 0 0 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 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0    0 0 0 0 1 0 0 2 2 6 10 34 60 95 126 177 194 155 99 71 44 17 6 7 2 0 0 0 3 0 0    1 0 0 0 1 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 1 0 0 0 1 0 0    0 0 0 0 0 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 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.038000 0.550 0.550 2.700        18391           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 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 1 0 0 0 0 0 0 0 0 0 0 0 0 2    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 2 0 0 1 1 0 1    2 1 0 0 0 1 0 1 3 6 19 27 52 95 161 154 169 134 94 64 37 19 9 6 0 2 1 0 0 0 0    1 2 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 2 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.040000 0.600 0.600 2.800        22933           5           0  0 0 0 0 0 0 0 0 0 0 0 0 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 0    0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 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 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1    0 0 0 0 0 2 0 3 4 7 18 27 47 82 134 163 133 138 101 58 34 26 10 5 2 1 2 1 1 0    2 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0   0.042000 0.650 0.650 2.900        27719           5           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 1 0 0 1 0 0 0 0 0 0 1 0 0 2 0 0 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 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 1 0 0 0 1 1 2 8 16 37 51 87 128 153 146 123 105 62 35 24 8 3 5 0 1 2 1 0 0   0 1 1 1 0 0 0 1 0 1 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0    0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.044000 0.700 0.700 3.000        32922           5           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 2 0    0 0 0 0 0 0 0 2 1 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1    1 1 0 0 0 1 4 3 5 5 15 35 54 88 132 168 149 105 92 62 30 16 17 4 5 1 0 0 1 0 1   1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 1 0 0 0 0 0 0 0    0 0 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 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.046000 0.750 0.750 3.100        38973           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 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 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0    0 0 0 1 0 0 0 4 3 5 20 37 56 94 110 135 149 124 84 58 36 17 14 7 1 0 2 0 1 0 0   1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1    1 0 1 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0    1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.048000 0.800 0.800 3.200        45376           5           0  1 0 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 0 0 0 0 0 0 0 1 0 0 0    0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 0 2 1 1 2 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0    0 0 0 1 0 0 0 0 1 3 18 34 55 82 104 135 116 99 79 60 51 29 10 4 3 1 1 1 0 0 1    0 0 0 1 0 0 3 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1    0 0 0 0 1 0 0 0 1 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    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.050000 0.850 0.850 3.300        52060           3           0  0 0 0 0 0 0 0 0 0 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 0 0 0 0    0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 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 0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 1    0 0 0 0 0 2 2 1 3 12 24 40 39 107 121 127 138 100 86 68 44 23 15 7 3 1 1 0 1 1   0 0 2 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 2 0 0 0 1 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.052000 0.900 0.900 3.400        59454           3           0  0 0 0 0 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 2 0 0 0 0 1 0 0 0 1    0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0    0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 2 0 2 1 0 0 0 1 0    0 1 0 0 0 0 0 3 3 6 21 32 68 90 132 111 122 107 73 57 47 24 11 7 4 2 2 1 0 0 0   0 0 0 0 0 1 0 0 1 0 0 2 0 1 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0    0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 1 0 0 0 0 0 0 0   0.054000 0.950 0.950 3.500        67013           3           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 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 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 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0    1 0 1 0 1 2 4 3 7 9 28 31 71 94 115 96 108 78 82 60 38 17 12 11 4 3 1 1 0 2 1    0 0 0 2 1 3 0 0 0 0 3 0 0 1 0 0 0 0 0 0 0 2 0 0 0 1 0 2 0 1 0 2 0 1 0 0 1 0 0    0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0   0.056000 1.000 1.000 3.600        75475           3           0  0 0 0 0 0 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 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 2 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 3 0 0 1    1 2 0 1 4 0 1 8 6 7 17 41 56 71 109 113 84 103 72 54 35 22 6 9 1 7 5 4 0 0 1 0   0 0 0 0 0 1 0 0 2 1 0 0 0 0 2 0 0 1 0 0 1 0 0 0 0 0 0 1 0 2 0 1 0 0 0 0 1 0 1    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 0 0 0 1 1 0 0 2 0 0 0 0    0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0   0.058000 1.050 1.050 3.700        83558           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0    0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 2 0 0    2 0 0 1 0 3 2 3 6 15 27 41 77 73 94 94 92 76 61 56 42 23 13 11 6 2 1 2 0 1 2 0   0 1 0 1 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 2 0 0 0 0 0 1 2 0    0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0   0.060000 1.100 1.100 3.800        93087           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1    0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 2 2 0 0 0 1 0 1 1 0 0 0 1 1 0 4    0 0 1 2 0 3 1 3 5 13 33 31 65 75 77 96 97 80 59 45 36 32 18 2 5 0 1 0 0 1 0 0    3 0 0 0 0 1 0 0 0 0 0 1 0 0 1 2 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 2 0 0 2 0 1 0    0 0 0 0 0 0 1 2 0 0 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 0 0 0    0 1 1 0 0 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.062000 1.150 1.150 3.900       102829           3           0  0 0 0 0 0 0 0 0 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 0 0 0 1 0    0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0    0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 1 0 1 1 0 2 0 2    1 2 0 0 2 4 3 5 11 9 23 43 53 68 65 87 83 77 59 49 34 18 15 9 4 2 3 2 0 0 0 4    0 1 1 0 0 2 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 2 0 0 0 0 1 0 0 1 1 1 1 0 0 0 1 0    0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0   0.064000 1.200 1.200 4.000       113442           3           0  0 0 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 0 0 0 0 0 0 0 0 0 0 0    0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0    0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 1 1 1 0 0 0 1    2 0 0 0 2 0 4 5 11 13 29 39 61 68 61 75 76 74 73 44 37 29 19 6 3 3 2 0 1 2 1 0   0 0 0 1 1 1 0 1 1 0 0 0 1 0 1 1 0 1 2 0 2 1 1 1 0 0 0 0 1 0 0 1 1 1 1 1 0 0 0    0 0 0 0 1 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0    0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0   0.066000 1.250 1.250 4.100       126668           3           0  0 0 0 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 0 0 0 0 0 0 0 0 0 0    0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1    0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 2 3 0 2 1 2 0 1 0 3 0 0 0 1 0 1 1 3    0 0 1 3 0 2 4 3 12 12 30 48 56 66 77 78 71 82 52 31 32 19 20 16 8 2 1 3 0 0 2    1 0 1 0 1 0 0 0 1 3 1 0 1 0 1 1 1 0 0 0 0 0 2 0 2 0 0 0 0 0 1 0 0 0 0 1 1 0 0    0 0 0 1 0 0 0 0 0 2 0 3 1 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0    0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.068000 1.300 1.300 4.200       138042           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 2 0 0 1 0 1 0 0 0 0 0    0 0 0 1 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0    0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 3 0 0 1 0 0 1 2 0 0 0 3 0 1 0 0 3 0    1 0 1 1 3 1 4 7 11 14 27 36 44 68 72 70 71 45 44 46 29 13 16 11 5 2 0 3 0 0 0    0 1 1 2 0 0 1 1 2 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 2 0 0 1 1 0 1 1 1 0    0 1 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 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 1 0 0 1 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   0.070000 1.350 1.350 4.300       152335           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0    0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0    1 0 0 0 2 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 1 1 1 0 1 1 0 1 1 1 1 0 2 0    0 0 0 0 2 0 1 7 14 19 34 35 54 72 68 72 68 58 48 36 37 27 25 17 1 4 1 0 0 0 1    2 2 0 0 1 1 1 2 1 0 3 1 0 1 0 2 1 0 0 0 1 1 1 2 0 0 0 0 1 1 0 1 1 0 2 1 1 1 1    0 0 0 1 1 0 0 2 0 0 1 0 0 0 1 1 0 2 1 1 0 0 0 0 2 0 0 0 0 0 0 0 1 1 0 0 0 0 1    0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0   0.072000 1.400 1.400 4.400       166280           4           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0    0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0    2 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 0 3 4 2 2 0 0 0 0 0 1 1 3 1 0 3 2 2    1 2 2 0 2 2 1 8 14 26 24 29 47 47 68 65 63 55 42 41 26 29 17 8 4 4 1 0 1 2 0 0   0 1 1 2 0 1 2 1 0 0 1 1 1 0 0 1 0 0 0 1 0 0 1 2 1 2 1 0 0 0 0 0 1 1 2 0 2 2 0    0 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0    0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0   0.074000 1.450 1.450 4.500       179484           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0    1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 1 0 1 0 0 1 0 1 2 0 0 0 0 0 0 0 0 0 1 0    0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 1 1 1 2 0 0 1 1 2 1 0    1 1 2 2 0 1 5 6 10 20 43 50 57 62 53 62 66 45 42 33 27 26 23 14 3 0 2 0 1 0 0    1 1 0 0 2 1 1 0 0 3 0 1 1 1 0 1 1 0 1 0 1 2 1 0 0 1 2 0 2 0 0 0 0 1 1 3 1 0 0    2 1 1 1 0 0 0 0 0 0 1 2 0 1 0 0 0 0 0 1 1 0 2 0 0 0 0 0 1 0 2 1 0 0 0 0 0 0 1    0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0   0.076000 1.500 1.500 4.600       197657           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0    0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 2 0 0 0 1 0 0 0 0    0 0 1 0 1 0 0 0 0 0 0 0 0 1 2 0 0 0 2 1 1 0 1 1 0 1 1 3 2 1 1 2 1 0 1 0 0 0 0    0 1 1 1 0 5 3 7 12 24 38 32 41 48 54 66 71 49 46 31 38 25 15 8 6 6 5 0 1 3 0 1   1 1 1 1 0 1 2 0 1 0 0 0 1 0 2 1 2 0 0 0 0 1 3 1 0 0 0 0 1 1 0 1 0 1 1 1 1 1 0    4 1 1 1 0 3 0 0 0 2 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0   0.078000 1.550 1.550 4.700       212054           3           0  0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0    0 1 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1    0 0 2 0 0 0 1 0 0 1 0 1 1 0 1 3 1 0 0 1 2 0 0 0 1 0 0 0 0 0 2 1 2 1 1 1 0 0 1    5 1 1 2 3 5 7 9 11 22 31 37 48 50 52 54 57 37 38 38 33 24 11 19 11 3 1 2 0 3 3   2 1 0 1 3 0 1 1 1 1 1 2 0 0 0 1 1 2 0 1 1 3 0 1 1 0 0 1 0 2 0 1 0 0 1 3 0 2 0    1 0 1 2 0 1 1 1 1 1 0 3 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0    0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0   0.080000 1.600 1.600 4.800       231971           3           0  0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 1 1 1 0 1 0 0 0 0 1 0 1 1    0 0 0 0 2 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 2 1 0 1 1 1 0 1 0 0 1 0 1 3 0 0 0 1 0    0 0 1 1 1 0 0 4 1 1 0 2 0 1 1 1 2 0 0 0 1 0 1 2 1 2 3 2 0 1 0 4 3 1 1 1 1 3 1    0 0 0 2 1 0 2 7 17 13 29 47 58 59 52 38 51 51 38 34 35 21 14 13 4 1 0 1 1 1 0    2 2 4 1 0 1 1 4 0 0 0 2 0 2 2 2 0 0 1 3 2 1 1 2 2 2 2 1 0 3 0 2 1 2 1 2 2 0 0    1 1 0 2 0 2 2 0 1 0 2 2 3 1 2 3 1 1 0 1 0 2 0 1 2 1 2 0 2 1 0 0 3 0 0 1 1 1 1    0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0   0.082000 1.650 1.650 4.900       252503           3           0  0 0 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 0 1 1 0 0 0 0 0 2 0 0    0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0    0 0 0 0 2 0 0 1 0 1 2 2 2 1 0 2 0 1 0 1 1 2 2 0 3 0 0 4 1 0 0 3 0 0 1 2 0 1 1    1 3 0 1 0 2 9 11 25 27 34 53 41 49 43 47 36 31 38 22 30 22 18 9 5 9 2 2 1 2 2    3 1 4 1 1 0 0 1 2 0 2 1 0 0 1 3 2 2 1 0 0 0 1 2 1 0 0 0 2 1 1 0 2 0 0 1 0 0 2    1 3 1 1 1 0 2 1 1 0 2 1 0 1 3 0 0 0 0 2 0 0 1 0 0 0 0 0 1 2 1 1 1 0 2 1 0 0 0    2 0 1 0 0 0 0 1 0 0 0 0 1 0 0 2 0 1 0 1 0 0 0 0 0 0 0 0 0 0   0.084000 1.700 1.700 5.000       267889           3           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 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1    0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0    0 1 0 1 1 0 3 0 1 1 1 0 1 2 1 0 2 0 2 4 0 1 0 0 0 1 1 0 1 3 2 0 2 0 4 0 0 2 0    1 4 2 4 3 3 6 10 14 28 37 54 36 40 52 40 50 46 40 32 26 29 12 18 5 2 0 2 4 1 2   1 0 2 1 2 2 1 0 1 0 2 1 2 4 1 1 5 1 0 2 0 1 2 3 2 2 1 2 1 0 2 1 2 1 1 4 1 2 1    4 0 2 2 0 0 3 1 0 2 0 0 1 1 1 0 0 2 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 0    0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0   0.086000 1.750 1.750 5.100       290294           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 2 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0    0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 3 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 2    1 0 1 0 1 0 0 2 2 0 1 2 2 0 2 0 2 0 1 0 0 1 1 1 3 1 1 1 1 3 4 1 1 2 2 2 1 0 3    0 0 0 2 4 5 6 16 18 20 31 40 54 55 46 41 52 35 27 21 28 27 20 15 8 6 7 1 0 0 3   0 0 2 2 0 3 1 3 1 1 2 0 0 1 2 1 3 2 0 1 2 1 3 1 1 1 1 1 2 0 2 1 0 1 1 1 3 1 1    2 0 1 0 1 0 2 1 1 0 0 1 2 0 3 1 1 0 0 0 1 3 1 1 1 0 0 1 2 1 0 0 1 1 1 0 0 1 0    0 0 0 0 0 2 0 1 0 0 0 2 1 0 2 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0   0.088000 1.800 1.800 5.200       312476           6           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0    0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 2 0 0 0 1 0 1 0 0 0 0 0 0 2    1 0 0 1 0 0 1 1 1 1 4 2 0 1 0 0 3 0 0 0 0 0 1 1 4 0 0 0 0 1 1 2 1 0 3 0 0 2 2    4 0 3 1 6 9 10 13 21 24 32 43 33 41 43 49 50 32 26 31 27 12 16 17 3 3 3 5 0 3    0 2 1 3 3 2 1 2 3 1 2 1 1 1 2 0 1 1 0 2 0 3 0 0 2 0 0 0 0 1 0 1 1 3 3 0 1 1 1    1 1 1 2 2 2 0 3 1 0 2 2 2 0 0 0 0 3 1 2 5 1 1 2 0 0 3 3 0 2 2 0 0 0 0 1 2 0 0    1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0   0.090000 1.850 1.850 5.300       337348           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 0 1 0 1 0 0 0 1 0 0 0    0 0 0 1 0 0 0 0 2 0 1 1 0 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0    2 0 0 0 1 3 2 0 0 2 2 3 3 2 2 2 0 0 1 1 3 1 3 0 0 0 0 0 0 1 2 1 2 1 2 2 2 0 1    1 0 4 2 2 7 6 15 22 21 39 37 50 31 51 30 33 34 34 26 21 14 13 10 9 4 3 3 4 2 2   0 1 2 3 3 0 1 3 2 5 3 2 2 4 0 2 3 0 4 2 1 2 2 2 4 2 1 3 1 3 2 1 3 1 2 4 1 1 1    1 2 4 1 3 3 3 1 0 4 1 0 1 1 1 1 2 3 0 3 0 0 4 1 1 1 0 2 2 2 1 2 2 0 1 1 0 0 0    2 0 1 0 1 0 0 1 0 0 0 1 3 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 0   0.092000 1.900 1.900 5.400       357303           3           0  0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0    0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 3 1 0 1 0 0 0 0 1 0 0 1 0 0 1 1 2 2 0 0 2    2 1 1 1 1 1 1 0 1 0 0 1 1 1 3 1 1 1 1 1 0 1 4 0 1 1 1 3 0 1 1 2 2 2 0 2 3 2 2    2 2 1 2 1 3 8 22 14 32 36 46 39 42 39 29 36 38 26 24 26 18 16 19 10 9 3 6 5 0    3 2 1 1 1 2 0 2 1 1 0 1 1 3 1 0 2 4 2 2 1 4 1 2 2 1 1 0 1 2 0 2 2 2 4 2 1 1 0    2 1 3 1 2 3 4 2 3 2 3 0 1 2 1 0 0 0 4 1 1 1 2 1 3 1 0 5 1 0 0 0 0 0 0 1 0 2 0    1 2 1 0 1 0 0 0 0 0 1 1 0 1 0 1 4 0 0 0 1 0 1 0 0 0 0 0 0 0 0   0.094000 1.950 1.950 5.500       383138           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1 0    0 0 1 0 0 2 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 2 1 1 1 1    2 1 0 2 0 1 0 3 2 1 3 0 1 3 1 1 0 5 0 1 0 1 2 0 0 1 1 2 0 0 6 1 0 3 2 2 3 4 5    0 4 2 1 5 4 11 15 22 27 28 57 38 38 40 38 39 38 27 26 30 18 14 10 10 4 4 4 3 3   2 2 2 2 1 1 1 1 2 2 3 4 1 2 3 1 2 1 2 2 2 1 3 2 1 5 0 1 1 1 3 2 2 2 1 3 1 1 0    3 2 2 0 0 2 2 2 0 0 0 2 0 1 3 1 2 3 2 1 1 0 1 1 1 0 3 2 2 1 0 0 1 3 1 1 0 1 0    0 0 0 0 1 0 0 0 0 1 0 0 3 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 0   0.096000 2.000 2.000 5.600       409868           3           0  0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 1 0 2 0 0    1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 2 0 1 0 0 2 0 2 0 0 0 0 1 0 0 2 1    2 2 2 1 2 1 1 1 1 1 2 0 0 1 1 0 1 0 2 1 2 0 2 0 3 1 2 1 3 1 5 0 2 2 1 2 4 1 2    0 3 1 4 7 5 9 13 22 19 31 27 28 41 34 39 37 22 23 21 22 17 23 15 8 9 3 8 0 3 1   2 2 2 3 1 0 4 2 4 2 2 2 2 4 2 1 1 0 2 0 3 0 3 2 2 1 2 2 1 4 1 2 2 1 1 5 2 1 2    1 2 2 1 0 2 4 3 2 1 2 2 3 2 3 1 2 1 1 1 1 2 1 1 2 2 1 2 3 2 1 1 0 2 2 4 0 1 1    1 1 1 0 0 1 1 3 0 0 0 0 0 1 0 0 2 0 1 2 0 1 1 1 0 1 0 1 0 0   0.098000 2.050 2.050 5.700       439102           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 1 1 0 0 1 0 1 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0    0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 2 0 0 1 1 1 1 2 0 1 1 0 0 0 0 1 1 1 0 4 0 0    0 2 1 1 0 3 4 0 1 2 2 1 0 3 0 3 2 0 0 2 0 1 0 0 1 0 1 3 1 3 5 0 2 2 3 5 2 2 2    0 3 2 3 6 5 16 21 19 23 28 29 35 42 42 44 39 33 23 30 18 25 24 15 13 5 4 2 2 0   3 3 0 0 1 3 0 1 1 3 2 4 3 4 2 1 1 1 3 1 0 0 2 2 4 2 2 1 4 2 4 2 2 2 1 2 2 1 2    0 4 2 2 3 1 2 1 1 2 2 1 2 4 2 1 4 1 2 2 2 2 0 2 0 3 0 1 0 2 1 0 4 2 1 3 2 1 0    2 1 1 1 1 0 1 1 2 1 1 1 2 0 1 0 2 1 1 0 0 1 0 0 1 0 0 0 0 0 0   0.100000 2.100 2.100 5.800       467340           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 1 0 0 1 2 0 0 0 0 0 1 0 2 0 0 2 0 0 1 1 0 0    0 1 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 2 0 2    2 4 1 0 1 1 2 3 4 1 4 1 5 1 2 1 0 2 2 2 1 5 4 1 5 4 0 1 2 4 2 2 0 2 1 2 5 4 1    1 1 2 5 7 9 16 23 31 15 22 36 36 44 42 29 31 28 28 18 35 12 10 13 8 4 3 2 2 5    1 2 3 3 1 3 3 5 2 0 3 4 1 2 2 3 0 0 5 2 3 6 2 1 2 5 3 4 3 1 1 1 1 2 2 4 0 2 3    1 2 1 2 4 5 4 3 5 2 1 2 0 5 0 2 2 4 1 0 4 1 0 2 1 2 0 0 1 3 2 4 3 0 2 3 3 3 4    2 2 0 0 0 0 1 1 0 3 2 0 1 2 0 4 2 1 1 1 2 0 0 0 0 0 0 0 0 0 0   0.102000 2.150 2.150 5.900       497495           5           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 2 1 0 0 0 0 1 0 1 0 0 0 0 1 2    0 0 0 0 0 2 0 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 1 1 2 0 0 1 0 0 0 1 0 2 2 1 0 0 0    2 0 2 1 1 1 6 3 2 0 3 2 2 2 1 1 3 4 1 0 1 2 4 2 3 3 1 1 1 1 3 3 1 4 1 3 4 3 2    3 1 2 2 5 11 11 14 26 27 28 28 28 36 39 42 29 33 24 20 29 18 13 17 13 6 10 4 3   3 6 1 0 1 0 2 1 3 2 3 1 2 3 1 2 1 2 0 2 2 3 1 3 1 1 2 4 4 1 4 3 2 2 3 5 5 3 0    2 5 3 5 1 4 1 1 3 4 2 2 2 2 1 3 0 1 1 2 2 4 2 1 3 2 0 1 2 1 0 2 3 1 2 0 0 0 2    0 0 1 3 0 0 1 2 0 3 1 0 3 1 2 2 1 1 2 0 0 0 0 2 0 0 1 0 0 0 0 0   0.104000 2.200 2.200 6.000       529288           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 2 0 0    0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 1 3 0 2 0 2 0 0    3 2 2 0 4 0 3 2 2 1 3 1 7 3 1 1 0 4 3 2 1 0 0 3 2 3 5 2 1 4 1 5 1 0 3 2 3 0 1    2 4 7 3 7 8 12 15 20 24 34 39 34 35 27 36 34 23 22 26 15 24 12 12 14 5 3 0 7 1   1 3 5 1 2 2 2 4 3 1 2 5 2 2 3 1 1 4 2 1 3 0 4 5 4 6 4 5 3 3 3 3 1 1 5 0 6 1 2    4 2 3 2 1 3 2 0 0 0 1 3 3 0 1 4 0 3 2 3 0 3 3 0 2 3 4 3 1 1 1 2 5 3 1 2 1 1 2    4 1 0 2 4 1 3 0 0 3 0 1 3 0 1 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 0   0.106000 2.250 2.250 6.100       560628           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 2 0 1 0 1 0 1 0 1 0 0 1 0 0 0 0 0 0 1 1 0 1    1 0 0 1 1 1 0 1 1 0 0 0 1 1 1 1 0 0 1 1 2 0 0 0 0 2 0 3 1 1 0 0 2 2 2 0 5 2 1    1 1 1 3 1 2 3 0 1 0 0 0 0 1 0 2 2 1 2 1 0 4 3 2 1 2 1 0 4 2 2 0 2 1 1 2 3 1 2    1 2 4 4 11 12 17 19 19 29 30 24 30 35 51 32 36 34 31 19 22 17 11 19 11 7 6 6 3   4 0 3 3 2 0 2 2 2 3 1 5 3 2 3 5 1 0 2 2 5 4 2 3 2 0 1 6 1 2 2 2 2 1 1 2 2 1 4    3 2 2 1 2 5 2 0 2 0 2 5 4 5 2 1 3 6 1 3 4 4 0 0 6 0 2 6 1 2 2 2 0 1 3 1 3 4 2    1 4 2 1 2 3 3 0 3 1 0 2 0 2 1 0 2 1 2 0 0 1 1 0 2 0 0 0 0 0 0 0   0.108000 2.300 2.300 6.200       593293           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 2 0 2 2 1 0 0 2 0 1 0 1 0 0 1 2 2 1 0    0 1 0 2 0 0 0 0 0 1 1 1 1 1 0 0 1 1 0 0 1 1 1 2 2 1 0 1 1 0 1 5 0 2 4 1 0 1 4    2 1 3 2 2 3 2 3 2 0 0 3 4 3 1 3 2 2 0 3 0 2 4 0 3 2 5 1 2 1 4 6 1 2 4 0 3 6 1    7 6 4 5 4 10 16 24 22 20 40 37 44 34 29 21 28 36 36 27 23 24 14 10 4 5 2 5 3 6   2 3 3 1 4 2 1 5 1 3 5 3 2 1 2 2 6 2 3 1 1 0 5 3 3 3 4 5 2 2 3 3 5 5 1 6 2 3 2    6 0 5 2 4 3 5 1 2 2 5 1 2 3 1 2 2 2 4 2 5 5 2 2 2 5 0 1 2 5 2 3 2 3 1 1 2 4 0    2 1 4 2 1 1 1 0 1 2 0 0 1 3 1 0 2 1 1 3 3 2 0 0 0 1 2 0 0 0 0   0.110000 2.350 2.350 6.300       636559           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 1 0 0 0 1 1 2 0 0 1 0 0 0 0 0 0 0    1 2 0 0 1 1 1 0 0 0 0 1 0 1 1 0 0 1 0 0 2 0 1 0 1 0 1 0 0 1 1 3 0 1 2 2 0 2 1    1 1 1 0 1 0 1 3 0 3 2 3 4 3 3 4 3 3 2 6 3 1 1 1 2 4 2 3 1 5 1 3 1 4 5 3 3 2 1    3 7 4 3 10 19 17 19 23 27 28 33 39 36 23 23 32 32 16 19 35 23 12 11 12 8 4 5 7   1 2 2 1 2 3 5 4 2 3 2 6 4 4 2 4 1 2 2 1 2 3 0 4 2 1 2 6 2 2 1 3 3 1 6 4 8 5 2    3 5 2 3 0 3 2 3 1 2 2 3 4 3 8 6 2 1 4 6 3 1 2 0 2 0 2 5 0 3 3 3 3 1 3 3 2 5 4    2 1 4 2 2 4 4 1 3 2 5 2 3 1 2 0 4 0 1 0 6 3 1 2 0 2 0 1 0 0 0 0   0.112000 2.400 2.400 6.400       670484           3           0  0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 2    0 1 1 1 3 0 0 0 2 1 3 0 1 1 1 0 1 1 1 0 0 1 2 0 1 3 1 5 2 3 0 4 0 2 0 0 1 2 1    0 1 0 0 1 0 2 2 3 2 3 2 2 2 3 4 4 2 3 5 3 3 2 3 3 4 2 4 0 3 2 4 4 1 3 1 3 4 2    2 5 2 8 6 12 17 14 22 27 26 29 39 30 24 36 22 22 20 9 19 15 5 12 16 4 7 5 7 5    5 1 4 5 5 4 4 1 4 4 3 3 3 4 2 2 4 2 4 4 4 4 0 2 3 2 1 4 3 6 1 3 3 3 4 5 4 2 2    2 5 3 0 2 5 4 2 5 3 5 1 1 3 1 1 3 6 6 2 3 2 0 3 2 4 3 4 1 2 2 6 2 0 3 2 2 5 3    3 5 2 1 0 3 1 1 2 2 0 1 1 3 2 3 2 1 1 1 1 3 2 1 0 0 0 0 0 0 0   0.114000 2.450 2.450 6.500       711783           4           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 1 0 2 1 2 0 1 0 0 1 0 0 1 1 1 1 0 0 0 1    1 2 0 1 1 0 0 0 2 1 1 1 1 1 2 1 2 3 3 1 1 1 2 3 1 3 2 2 1 0 1 1 4 4 4 1 0 4 0    0 1 1 2 1 3 2 0 3 4 1 1 1 1 3 2 0 1 3 2 1 2 1 0 3 3 2 5 4 2 5 3 4 2 2 5 3 3 3    3 5 5 8 7 14 12 28 22 24 23 36 33 26 32 27 26 18 30 24 15 13 19 15 17 6 5 7 5    4 3 5 3 1 4 4 9 5 3 1 4 0 0 6 2 5 3 3 3 1 2 3 2 4 1 5 5 3 8 2 1 1 4 1 7 5 6 6    4 4 3 2 6 3 3 3 3 1 3 4 5 4 3 4 3 1 2 3 1 2 1 2 2 6 5 2 2 2 4 2 2 0 2 3 3 2 7    4 4 1 4 2 0 3 1 1 2 1 2 3 1 3 2 2 4 3 1 4 0 0 4 2 2 2 1 0 0 0 0   0.116000 2.500 2.500 6.600       745364           5           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 2 1 1 2 1 1 1 0 1 0 2 0 1 1    0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 2 3 0 1 4 4 0 4 0 1 0 1 3 3 0 2 1 2 3    2 1 1 1 2 0 4 0 0 4 5 2 5 4 1 3 5 5 4 0 4 4 2 3 2 3 5 2 2 4 2 3 4 2 3 3 3 3 3    2 4 12 10 13 14 19 22 23 24 36 19 32 25 25 36 24 18 20 21 14 18 13 8 6 9 2 9 5   2 5 3 4 4 3 3 0 4 3 2 5 3 4 2 2 6 3 4 0 2 4 1 3 4 7 4 5 3 2 4 5 5 3 4 4 4 2 3    2 4 4 2 1 5 7 1 5 2 4 1 5 5 3 4 4 3 2 4 2 4 0 6 2 3 4 1 2 2 2 4 1 4 2 2 2 5 6    5 1 4 4 2 3 3 3 1 4 3 4 2 6 2 5 3 2 2 1 3 2 2 5 1 1 0 0 1 0 0 0   0.118000 2.550 2.550 6.700       791846           4           0  0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 2 1 1 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 1 1 0 1 0    1 4 1 2 3 0 3 1 0 1 1 1 0 3 1 2 1 1 1 0 0 1 1 1 3 1 3 2 3 1 2 2 1 3 2 4 1 4 0    2 4 1 4 3 2 1 1 2 1 3 2 3 3 2 1 1 5 3 3 3 3 2 3 4 3 5 3 1 1 2 2 3 5 1 2 1 1 4    4 6 9 6 6 13 17 21 20 24 22 25 20 29 23 28 30 26 27 18 20 17 16 17 12 10 8 5 6   6 6 4 3 1 2 4 6 9 2 2 3 5 7 6 2 3 8 5 4 5 6 4 6 5 3 5 3 2 5 3 2 8 3 5 4 5 3 5    4 3 4 8 4 3 8 3 3 3 1 1 2 2 5 4 7 3 2 3 3 2 2 3 6 3 2 2 1 1 5 2 5 6 3 5 3 4 1    3 1 2 1 0 4 1 4 2 2 2 3 1 1 1 1 3 2 0 1 6 1 1 0 2 1 0 1 0 0 0 0   0.120000 2.600 2.600 6.800       833394           3           0  0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 2 1 1 1 2 1 0 0 0 1 0 1 0 0 0 1 0 0 1 1 2 1 0 0    0 0 0 2 2 0 3 1 0 0 2 1 1 1 1 0 1 2 1 5 0 1 0 2 2 1 2 0 4 2 1 4 3 4 2 2 1 2 1    5 2 3 1 3 0 2 2 2 2 3 4 0 4 2 3 3 4 5 2 2 6 3 4 5 5 5 3 4 6 5 1 3 0 5 4 5 1 3    2 2 6 18 13 17 27 27 21 28 28 24 26 27 29 23 21 16 17 19 22 14 11 9 5 14 7 7 6   4 4 12 3 6 4 5 4 6 4 2 0 1 8 1 6 8 5 2 3 4 5 6 4 2 5 8 3 1 1 6 3 7 8 4 1 6 5 2   8 11 5 6 5 6 2 4 5 1 2 7 2 2 5 5 6 3 3 2 3 8 5 1 9 3 3 2 3 6 3 5 3 2 4 6 3 1 3   5 4 4 4 6 3 3 5 0 2 2 5 1 3 2 2 1 4 2 0 2 2 2 2 4 1 2 1 2 1 1 0   0.122000 2.650 2.650 6.900       876007           3           0  0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 2 1 1 1 1 2 2 1 0 0 1 0 0 0 1 1 0 0 0 2 0 0    4 1 0 2 1 2 0 1 2 0 1 3 2 1 0 1 1 0 1 2 1 0 2 3 3 5 3 3 3 0 1 4 0 1 5 3 4 3 1    2 2 2 4 1 3 3 3 2 3 2 3 2 1 4 4 2 2 5 5 3 4 1 2 1 2 4 2 4 7 2 4 4 2 7 3 5 7 5    3 6 8 10 10 18 21 22 24 14 25 27 29 31 22 25 24 21 27 20 19 22 19 14 13 14 10    5 7 3 4 5 5 3 1 4 3 8 4 5 4 0 3 4 3 4 1 7 6 1 1 3 4 4 3 4 3 6 4 3 4 2 4 4 3 5    6 5 1 1 6 2 6 6 3 5 5 3 2 6 5 4 3 4 6 4 3 5 5 6 5 6 2 4 2 1 2 2 4 2 7 6 2 1 3    1 5 2 1 2 4 3 3 3 2 5 2 4 1 4 3 2 2 5 5 1 1 3 3 2 2 2 2 1 0 0 0 0 0   0.124000 2.700 2.700 7.000       925764           3           0  0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 2 1 3 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0    1 2 0 0 3 2 0 1 2 1 1 2 0 2 1 2 2 0 0 2 3 2 3 2 2 3 2 2 4 0 2 0 5 1 3 2 3 1 2    3 2 0 6 4 3 6 2 5 0 5 2 1 4 4 5 7 4 2 3 5 2 0 2 5 2 4 7 4 4 4 8 5 3 1 7 2 2 1    5 5 5 14 19 16 22 18 30 29 25 36 23 23 22 25 25 27 26 23 14 20 16 16 10 6 6 6    4 2 6 6 6 6 6 4 6 1 0 3 4 4 5 2 4 3 2 4 4 5 5 5 6 10 6 3 6 8 5 5 8 7 4 6 4 3 4   8 5 5 7 4 6 3 5 8 4 3 4 4 3 4 3 1 3 3 7 2 4 8 3 6 4 3 3 2 5 4 4 3 7 4 5 4 4 3    4 7 2 3 3 4 3 0 2 2 4 3 4 2 4 2 2 6 4 4 6 6 1 5 1 1 2 1 0 0 0 0 0   0.126000 2.750 2.750 7.100       969560           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 1 0 1 2 0 2 0 2 2 0 1 1 1 0 0 1 0 1 1 1 1 2 0    1 2 2 1 2 0 0 1 0 1 0 2 1 0 1 0 1 1 2 0 3 0 3 4 3 1 3 2 0 4 0 1 2 0 3 1 1 2 3    2 2 2 5 1 7 1 5 1 5 4 2 0 0 1 2 1 3 2 3 3 5 4 10 10 2 5 11 4 1 2 1 7 3 5 4 4 1   5 10 8 7 9 9 20 20 21 33 21 28 20 27 32 21 29 22 20 24 15 13 27 14 13 15 10 9    3 11 6 7 5 3 6 8 5 4 4 1 3 3 5 2 7 3 6 6 1 6 4 6 5 3 4 2 4 3 3 9 4 5 4 4 5 2 3   10 4 3 2 6 10 6 3 6 5 5 5 4 8 8 5 4 3 6 4 4 2 4 4 4 5 7 4 4 4 4 5 2 2 3 4 5 2    1 3 2 6 2 7 7 1 6 4 4 6 5 5 4 0 2 2 3 2 7 5 0 4 1 1 4 6 1 0 3 2 0 0 1   0.128000 2.800 2.800 7.200      1022713           5           0  0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 1 0 1 1 0 0 1 1 1 0 0 0 2 1 0 0 4 0 0 1 2 3    1 1 0 1 0 1 0 3 1 1 1 2 2 1 1 1 3 1 0 2 4 2 1 2 1 2 0 3 1 3 2 1 5 2 1 3 1 2 1    5 3 2 1 2 5 3 8 2 3 2 5 5 4 3 6 4 4 4 3 2 3 8 4 3 4 5 4 5 4 7 6 5 3 3 3 5 2 9    10 7 9 12 11 13 17 15 22 19 33 24 28 30 26 21 24 22 27 20 26 16 10 10 9 20 10    7 4 5 7 7 2 7 5 3 5 1 6 1 5 7 5 6 3 1 5 1 1 3 4 8 6 3 9 5 5 3 6 7 4 6 7 6 4 2    4 6 2 3 6 5 6 7 6 4 4 9 6 8 6 9 7 1 2 6 2 7 5 4 4 4 4 5 5 4 4 3 6 3 5 3 6 4 3    6 6 2 5 2 8 4 5 3 6 5 4 5 8 4 3 5 6 5 5 2 8 1 2 2 5 4 1 3 0 0 0 0 0   0.130000 2.850 2.850 7.300      1081669           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 5 0 0 2 2 0 0 1 0 0 0 1 1 0 2 0 2 2 2 1 0    1 0 2 2 3 1 1 0 2 0 1 0 2 1 1 2 2 0 1 4 3 0 2 1 1 0 2 5 2 1 0 1 3 2 5 2 1 2 5    2 3 4 3 6 6 6 4 6 6 3 1 3 2 3 4 7 5 2 9 7 4 1 4 4 3 2 2 2 7 4 8 4 7 4 6 8 5 1    8 6 10 18 21 18 15 21 24 21 26 22 30 28 27 23 22 21 17 25 20 17 13 17 9 12 7 8   5 4 4 5 5 2 4 1 1 2 5 7 6 4 9 7 7 5 5 5 5 5 2 4 5 3 6 8 2 4 9 4 10 5 1 4 5 5 5   10 3 2 8 6 5 7 3 13 3 3 6 5 1 4 5 9 5 2 7 4 5 6 3 5 6 5 4 5 9 6 4 3 4 4 4 5 8    5 5 0 3 6 3 4 3 7 5 6 4 3 3 6 8 4 1 3 1 2 7 3 4 6 6 1 3 4 1 0 1 0 0   0.132000 2.900 2.900 7.400      1131887           3           0  0 0 0 0 0 0 0 0 1 0 0 1 2 1 1 0 0 0 1 2 2 1 1 0 2 1 1 0 1 1 1 0 2 2 3 1 0 1 0    1 0 2 0 2 0 1 4 0 1 2 2 0 0 0 2 3 0 1 2 3 0 1 2 3 5 6 2 2 3 1 4 4 8 4 3 3 3 7    2 2 5 7 4 1 2 4 8 1 5 2 7 3 4 2 9 6 5 5 6 2 2 3 6 2 5 6 7 7 2 8 3 3 3 3 6 6 5    3 10 15 15 17 19 13 29 20 23 22 34 28 28 33 20 20 22 17 22 18 15 19 14 11 9 13   6 6 13 4 2 9 8 8 7 6 5 6 4 4 9 6 2 8 9 7 2 6 3 7 3 6 3 7 4 4 5 4 5 6 4 7 5 4     10 2 6 6 8 3 6 6 9 5 8 8 7 6 4 8 5 7 5 5 7 3 5 5 5 10 7 3 8 7 5 7 2 4 4 6 4 10   7 6 4 4 4 4 3 2 4 2 6 5 9 7 3 2 6 2 5 1 5 6 2 2 1 9 2 5 2 5 1 0 0 0 1 1   0.134000 2.950 2.950 7.500      1185706           3           0  0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 3 2 1 0 1 1 0 0 0 0 0 1 0 1 1 2 0 1 0 1 2 0 0 0    1 1 0 1 1 1 0 2 2 0 1 3 3 2 3 0 0 2 2 3 2 1 1 3 0 0 1 1 3 4 3 1 1 9 1 4 0 1 3    4 1 3 2 6 4 7 7 3 2 8 5 2 5 2 4 6 7 3 7 7 8 4 7 2 4 7 7 9 9 2 5 5 8 3 5 7 3 6    10 6 10 15 10 13 14 29 21 23 37 26 20 28 20 16 24 25 16 19 21 20 20 17 11 10     12 8 7 7 5 5 5 4 5 6 7 3 6 5 7 5 11 9 6 8 11 6 4 6 8 8 7 7 7 4 5 4 8 5 4 3 4 8   10 7 9 4 7 6 8 9 7 3 5 7 7 6 2 6 4 7 3 9 8 12 7 6 6 6 4 5 7 2 4 7 3 2 4 4 7 1    4 5 0 4 6 3 10 8 5 4 3 4 5 7 5 7 5 7 3 5 2 5 6 4 5 2 4 1 6 6 2 4 2 0 0 1 0   0.136000 3.000 3.000 7.600      1238426           3           0  0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 2 4 0 2 0 2 2 0 1 1 1 0 2 1 1 2 1 0 1 1 0 3 1 0    0 1 0 1 0 0 2 1 1 0 4 0 2 6 3 3 4 0 3 1 2 4 0 4 4 0 1 5 2 2 5 1 3 4 3 3 5 2 4    4 6 2 5 3 4 5 4 5 6 7 5 6 2 8 3 4 7 2 4 4 3 7 6 5 1 4 8 3 7 10 3 3 6 1 5 3 8     11 5 7 15 11 15 17 21 23 21 24 28 16 21 29 15 22 27 28 20 13 19 13 7 15 10 11    9 6 8 8 4 7 5 4 6 5 10 6 7 8 9 3 5 5 9 5 9 4 4 4 3 5 7 4 10 6 8 4 9 8 4 6 7 9    11 6 8 3 5 8 12 3 6 9 7 11 9 6 7 4 7 7 7 2 5 4 5 0 2 9 5 5 5 10 7 5 6 3 9 4 4    13 2 7 5 7 4 7 2 0 4 5 4 4 6 8 1 2 5 6 4 7 3 11 4 3 3 5 5 4 4 3 1 4 2 2 1 1 0   0.138000 3.050 3.050 7.700      1299809           6           0  0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 2 1 1 0 0 1 0 0 2 0 1 2 0 0 3 0 0 1 3 1    2 0 2 0 1 1 2 1 2 3 2 1 2 5 2 2 2 4 3 2 5 3 0 3 2 4 5 4 3 0 5 4 1 4 3 8 6 4 4    7 4 5 4 3 6 5 6 10 3 6 6 2 6 3 4 4 3 6 7 6 8 3 4 7 5 4 9 2 4 8 5 9 8 3 7 5 7 7   13 7 11 15 17 16 18 18 18 20 17 26 25 19 20 26 31 22 18 20 18 14 11 16 4 7 11    10 8 9 9 6 3 8 8 7 5 6 10 3 5 6 6 3 12 7 8 8 2 10 4 13 9 9 12 4 5 9 7 9 5 7 4    8 9 6 7 8 10 8 7 5 7 11 6 4 4 4 6 4 9 4 5 9 10 7 4 12 7 4 9 5 10 10 6 8 4 7 2    4 7 2 6 8 4 11 3 3 9 7 6 7 3 8 7 4 8 5 3 7 4 5 5 7 4 6 7 5 5 3 5 2 5 4 1 2 0 0   1   0.140000 3.100 3.100 7.800      1361810           3           0  0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 2 1 0 0 0 1 1 1 2 0 0 0 0 1 0 2 2 2 1 0 0 3 3 0    2 0 6 2 3 1 0 3 3 1 2 2 5 3 5 3 3 2 2 7 3 2 2 3 4 2 3 4 4 1 3 7 4 5 4 2 3 5 4    2 1 3 6 3 4 3 8 7 6 5 3 5 11 5 5 3 3 7 3 6 4 4 2 4 4 4 1 5 5 9 6 6 9 3 10 8 6    8 3 10 8 16 16 13 18 23 29 25 19 19 20 27 19 22 27 24 21 15 18 11 20 21 17 12    5 18 6 12 7 9 11 7 12 11 4 8 8 4 8 7 7 2 6 4 4 9 6 9 3 4 7 7 7 4 10 4 11 5 8 8   8 5 4 4 8 6 4 9 8 12 12 8 5 8 3 10 8 7 5 3 5 6 8 5 6 10 7 2 11 2 5 5 6 8 10 2    7 5 5 14 2 7 3 9 3 5 2 8 2 3 4 4 7 9 5 4 7 6 7 5 6 3 5 4 7 6 7 7 9 3 0 2 1 1 1   0 0   0.142000 3.150 3.150 7.900      1429499           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 1 2 1 1 0 0 0 3 0 2 2 1 0 3 0 2 1 3 0 0 1    1 3 1 2 4 1 5 3 5 1 0 7 1 3 2 3 2 2 2 3 0 0 1 3 6 3 2 2 4 4 4 6 4 3 6 4 10 3 7   2 5 4 7 4 5 8 4 7 4 1 7 11 5 2 10 2 11 3 7 8 10 9 6 3 5 3 6 3 10 11 5 5 9 7 10   8 9 5 15 11 9 18 18 15 24 17 23 17 19 25 17 24 18 37 16 17 21 17 14 20 17 15     15 9 4 11 7 3 8 10 8 8 6 8 3 4 5 8 4 6 3 9 9 6 2 10 4 4 3 8 4 9 1 7 5 9 7 10 9   10 4 6 5 8 6 6 10 10 6 5 7 6 6 10 5 7 8 8 8 7 7 11 12 8 3 10 6 9 13 11 4 6 7 6   3 10 5 8 4 7 7 7 5 8 4 9 5 5 7 6 6 7 11 11 7 8 5 3 5 7 7 10 3 3 6 5 7 9 2 3 7    1 0 0 0 0 1   0.144000 3.200 3.200 8.000      1493946           3           0  0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 2 3 0 0 1 2 1 1 1 4 1 0 1 0 1 2 1 3 1 1 1 1 2    1 1 3 2 6 0 4 0 1 4 2 4 5 2 1 3 0 2 2 4 2 3 2 4 3 5 4 4 4 1 5 1 3 4 5 6 4 7 2    8 8 8 5 3 6 0 7 3 2 2 5 7 5 7 5 8 9 6 4 3 6 8 6 10 2 5 6 3 3 6 6 6 6 17 5 10 6   6 11 11 13 12 21 26 18 24 21 24 23 30 18 22 20 24 19 13 17 25 22 17 15 8 13 7    10 8 9 6 7 9 8 7 8 9 7 7 6 12 5 9 9 12 9 12 6 9 7 10 7 7 4 9 7 4 2 7 4 5 8 8 9   7 6 7 5 9 4 8 13 6 5 4 7 9 6 7 7 9 4 4 5 8 10 9 10 6 6 7 9 12 11 8 8 9 11 5 8    7 5 5 8 5 9 10 5 5 11 11 6 8 8 4 8 5 5 5 4 7 4 5 6 5 6 6 7 7 4 2 6 3 2 1 0 0 0   0 0   0.146000 3.250 3.250 8.100      1562352           5           0  0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 2 0 1 2 1 1 0 0 1 0 1 2 0 0 0 3 1 2 0 4 4 2 0    0 2 3 2 0 1 3 3 4 0 1 4 3 3 4 5 5 4 2 1 4 2 5 3 2 7 6 3 5 6 5 5 5 1 5 2 7 4 8    7 4 6 5 7 5 3 5 8 1 6 4 6 8 7 6 7 6 3 4 6 3 5 8 4 10 3 3 11 6 5 3 9 6 4 3 17 9   11 11 24 13 15 14 25 26 26 21 17 32 32 22 18 25 29 29 27 24 21 12 23 14 12 11    9 17 7 9 11 3 7 6 5 5 12 3 6 8 7 4 7 11 10 8 9 5 8 2 10 9 8 10 10 7 7 4 7 5 7    7 9 10 8 7 7 16 6 8 10 5 6 6 12 12 7 11 11 8 9 7 8 12 10 7 8 7 11 8 9 7 7 4 9    4 7 14 9 8 8 13 9 8 7 13 5 9 5 7 4 9 5 7 8 7 8 7 3 10 9 3 4 4 4 5 2 6 6 3 5 10   4 4 2 3 0 1 0 0   0.148000 3.300 3.300 8.200      1630559           3           0  0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 4 2 1 1 1 2 1 2 0 2 1 5 0 1 1 4 0 2 1 4 5 3 0    1 1 1 2 1 3 3 3 1 1 1 1 1 3 4 6 6 8 8 4 3 2 7 2 2 1 7 4 4 5 1 10 6 4 4 4 3 3 3   6 11 6 4 5 4 8 5 5 9 4 5 5 7 6 4 13 12 3 6 7 5 2 7 9 7 8 8 4 7 6 4 10 6 8 9 9    9 13 15 17 23 25 13 16 24 22 26 21 27 24 24 21 21 21 15 17 22 25 21 22 17 14     11 8 12 5 9 7 8 5 11 10 6 6 5 9 13 10 9 8 8 8 6 4 9 10 9 9 7 8 7 5 7 8 14 13 5   14 5 12 11 8 9 6 5 4 9 13 7 10 13 11 11 8 5 9 10 8 7 6 7 13 3 13 8 7 13 17 5 8   5 10 7 12 7 6 6 9 7 8 8 11 8 11 9 11 11 8 5 6 10 4 9 3 10 8 7 10 8 7 8 10 10 7   4 11 5 7 8 2 4 3 0 0 1 0 1   0.150000 3.350 3.350 8.300      1707576           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 1 2 1 0 2 0 2 3 1 3 2 2 2 2 0 2 1 4 3 2 2 3    1 2 1 0 2 2 4 2 5 3 3 5 2 8 4 5 4 2 3 6 7 6 1 0 7 4 7 7 6 5 4 3 4 6 6 7 6 2 7    4 4 2 5 5 6 9 3 3 3 6 6 5 3 5 7 8 8 6 8 8 6 8 3 9 6 6 8 8 6 4 8 6 6 10 4 11 6    11 15 23 16 8 17 20 21 19 24 15 14 19 21 30 25 21 15 19 16 18 21 21 15 14 12     16 8 10 12 7 10 9 8 10 10 7 9 8 10 12 6 6 9 11 6 5 9 12 6 7 12 7 5 6 8 5 9 4     11 9 8 8 10 7 6 10 7 11 13 7 4 13 11 8 11 9 16 6 12 11 10 10 19 2 9 11 8 7 8 8   6 13 6 10 12 12 9 12 9 9 8 7 7 9 6 12 8 4 9 9 8 5 7 8 9 5 12 5 7 5 9 10 9 10 3   6 6 8 7 11 3 5 5 4 2 0 0 0 0   0.152000 3.400 3.400 8.400      1777231           3           0  0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 1 3 1 0 3 4 2 3 3 3 3 3 2 1 1 1 1 3 3 0    1 8 0 0 5 3 7 4 4 4 4 4 3 5 2 2 5 3 6 1 7 6 1 2 2 5 2 1 6 6 8 7 7 5 10 4 1 6 9   3 4 5 3 5 8 4 9 8 11 8 3 2 7 7 9 10 9 10 8 6 8 6 8 7 10 8 7 3 8 4 10 7 6 8 9 6   5 16 9 19 24 23 17 23 24 22 30 21 15 23 27 20 20 20 18 20 23 18 17 15 19 17 18   13 9 4 4 7 12 7 10 4 8 6 10 5 6 13 2 3 8 7 8 7 3 11 8 7 9 7 19 7 8 9 6 14 8 8    11 10 11 13 14 10 16 8 9 13 8 9 9 12 7 12 11 6 9 15 5 9 9 9 11 11 13 6 10 6 4    12 9 9 12 11 8 6 9 16 10 10 10 8 10 10 6 7 4 1 15 6 8 4 9 13 11 8 10 11 9 8 3    3 6 6 7 9 4 6 8 7 4 2 1 2 2 1 0   0.154000 3.450 3.450 8.500      1849489           6           0  0 0 0 0 0 0 0 0 0 0 1 1 3 0 1 2 2 0 1 4 1 1 0 1 0 2 1 0 0 1 1 1 1 6 3 6 1 3 1    3 3 0 6 0 4 2 7 4 6 4 4 3 7 4 5 7 5 5 2 3 9 9 2 5 5 3 9 4 2 7 6 2 8 2 5 7 12 6   5 4 5 10 4 12 10 6 4 14 7 9 10 11 7 7 7 7 3 9 7 4 3 8 7 5 7 9 6 8 9 6 8 8 12 6   5 11 12 13 11 13 21 26 19 23 25 18 23 22 23 23 18 27 20 15 20 25 24 19 18 12     14 13 15 8 15 10 11 7 9 13 11 12 13 11 11 7 11 13 6 5 10 6 6 10 8 14 5 14 11 8   5 9 7 10 10 8 7 15 13 3 13 12 18 15 7 10 9 10 8 15 9 6 8 9 10 10 9 5 7 7 5 10    11 13 12 12 12 10 6 17 10 11 9 4 8 7 6 6 9 12 8 16 18 7 5 10 8 12 10 15 6 13     11 6 10 16 10 11 16 8 9 5 11 10 14 11 5 2 5 7 3 1 1 0 1 0   0.156000 3.500 3.500 8.600      1920727           4           0  0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 2 1 2 0 3 0 1 1 0 1 0 3 0 4 4 1 3 1 2 3 3 4 3    1 2 3 9 5 2 3 7 3 3 6 5 2 6 1 4 3 2 3 6 5 1 8 3 8 5 3 7 6 13 11 9 5 8 7 7 5 8    7 4 8 6 4 10 4 6 5 6 9 9 12 6 7 10 9 9 8 8 3 8 9 8 8 2 12 11 13 8 13 7 8 6 6 9   6 8 16 13 14 16 16 22 20 21 21 17 20 18 19 22 20 11 20 22 21 14 19 15 23 17 15   12 14 19 16 10 11 14 11 9 11 9 12 8 16 14 9 6 18 10 11 7 10 11 17 10 13 8 10     12 9 12 7 7 10 10 11 11 9 8 8 14 10 10 9 14 9 14 13 9 19 16 17 4 11 8 12 11 10   21 6 10 8 9 12 9 7 7 12 7 16 14 10 13 6 13 8 9 10 6 10 8 7 10 4 6 11 19 12 6 7   5 8 11 10 12 13 9 6 10 5 11 11 4 14 10 7 2 6 5 1 2 5 1 1 0 0   0.158000 3.550 3.550 8.700      1999833           3           0  0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 2 3 2 2 2 1 2 3 0 1 0 1 3 2 0 0 3 2 3 2 5 7 0    3 4 1 10 7 7 4 5 2 3 4 3 8 3 6 4 4 4 8 2 3 4 5 5 7 1 6 7 8 1 6 8 1 4 4 11 9 4    7 11 9 10 5 6 8 4 3 9 7 9 11 5 5 8 8 4 8 7 8 11 9 12 6 4 13 4 12 10 6 9 11 10    11 10 11 11 11 14 15 14 23 18 17 29 16 26 23 15 19 14 18 19 22 31 13 21 20 12    16 15 14 18 17 15 8 12 14 13 10 10 10 10 10 13 11 6 8 11 8 14 8 10 11 11 8 10    13 5 14 7 12 9 10 10 12 15 18 8 6 9 9 12 8 9 20 14 16 10 11 14 5 5 13 6 11 9     11 15 6 9 13 11 7 8 7 10 8 16 12 11 8 10 14 11 17 11 8 16 13 9 10 5 10 17 13     14 16 8 10 9 11 5 10 9 10 12 8 11 12 11 8 6 7 12 15 13 12 7 13 5 0 3 2 0 0 0 0   0.160000 3.600 3.600 8.800      2073149           3           0  0 0 0 0 0 0 0 0 0 1 0 0 0 0 2 1 2 1 2 2 1 0 2 2 1 0 3 6 4 5 5 2 2 2 5 5 3 6 4    6 4 5 2 4 4 3 2 4 6 3 3 6 5 7 4 5 7 5 3 5 6 13 5 3 10 5 9 7 4 5 6 5 10 6 5 5 6   6 4 14 7 6 11 6 9 10 9 8 5 3 8 10 10 6 6 8 9 5 6 14 7 11 10 9 9 11 13 8 4 5 10   12 6 16 8 8 7 19 20 23 10 16 27 25 23 19 26 21 16 20 21 24 18 25 8 11 13 16 18   13 22 18 9 16 4 16 10 12 13 9 7 9 8 17 11 10 13 10 14 4 9 12 16 8 9 16 17 13     11 14 8 8 13 9 11 15 10 11 14 8 6 4 9 11 18 9 9 8 9 15 11 11 11 9 6 13 13 10 7   8 10 15 14 9 7 4 10 12 17 10 14 13 10 10 12 20 9 7 6 11 15 11 10 8 9 6 10 13     17 6 8 9 6 13 13 16 10 15 5 11 14 11 12 6 5 12 9 4 9 2 4 1 1 0 0 0   0.162000 3.650 3.650 8.900      2156456           5           0  0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 2 0 1 1 3 2 3 4 3 3 2 1 3 6 5 2 3 4 4 3 6 2 3    4 4 5 5 3 4 1 4 5 9 3 3 4 3 3 8 5 6 12 2 10 3 4 6 8 9 8 8 2 2 7 5 8 2 8 9 7 2    6 8 6 5 8 2 7 5 6 13 5 6 8 11 6 10 5 6 3 8 10 11 10 10 14 10 11 8 11 8 12 6 12   5 15 12 13 10 13 13 18 23 12 21 18 21 23 20 30 20 23 26 24 24 21 21 29 19 21     16 23 20 13 19 13 16 11 15 13 13 11 8 11 14 14 13 4 16 15 18 13 9 19 8 11 6 9    14 8 13 12 13 10 13 10 14 11 13 11 8 10 13 11 11 14 11 8 14 11 10 9 14 12 14     18 8 12 7 13 12 10 14 14 8 12 17 11 13 9 12 12 15 7 9 13 17 11 11 11 12 17 12    11 16 15 8 9 12 7 13 15 11 16 7 10 7 14 5 18 10 10 8 8 6 6 13 14 6 9 11 9 9 3    5 1 1 3 0 0   0.164000 3.700 3.700 9.000      2234753           3           0  0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 4 1 4 2 1 3 1 1 3 2 3 3 1 3 6 2 4 4 3 3 3 6 5 2    6 4 1 3 3 7 1 4 4 6 12 4 5 2 6 4 9 3 1 8 11 5 2 7 6 3 8 4 7 3 8 3 9 6 7 8 9 2    7 6 9 6 15 6 9 5 9 4 9 17 15 10 2 10 6 8 12 12 11 12 10 9 7 11 8 7 5 11 10 14    16 7 7 7 13 15 10 16 17 21 19 14 18 24 19 27 27 24 20 22 24 21 20 14 24 17 17    18 32 15 12 13 15 12 8 14 11 11 19 11 14 15 18 10 5 12 11 11 9 15 9 7 9 16 12    9 12 10 15 9 18 7 11 12 14 7 20 8 10 13 14 11 6 6 9 11 8 10 16 8 17 13 17 9 16   11 10 9 13 20 17 14 12 10 13 11 9 9 17 20 10 16 8 14 13 14 18 15 15 8 10 12 11   22 12 13 9 12 9 11 14 19 12 12 8 8 12 11 19 11 11 12 15 11 15 13 9 9 10 9 4 9    4 2 1 0 0   0.166000 3.750 3.750 9.100      2327990           3           0  0 0 0 0 0 0 0 0 0 0 0 0 3 2 2 0 1 2 2 1 1 0 0 3 1 4 2 6 4 2 4 3 2 5 5 2 3 1 3    1 2 10 2 7 4 3 4 3 3 4 3 10 6 9 6 3 8 5 5 3 4 4 6 8 4 4 7 5 5 11 14 5 3 6 8 8    7 10 11 7 17 7 11 10 8 7 8 12 13 11 12 6 13 9 7 7 6 5 8 13 10 10 14 11 11 8 12   15 14 9 13 10 9 18 13 18 12 23 14 17 24 15 23 25 31 19 17 29 19 19 19 26 25 19   17 22 19 19 19 11 11 12 22 21 8 10 18 10 14 19 17 13 14 10 6 9 10 15 11 5 13     13 11 11 17 16 9 7 14 7 19 6 10 13 7 12 18 14 7 12 15 13 13 9 13 13 13 12 12     14 12 19 10 16 18 18 12 8 10 10 9 7 14 9 11 13 12 8 15 12 11 10 12 11 17 15 19   14 14 12 7 7 12 11 15 16 12 11 12 10 19 19 12 14 12 15 11 20 13 7 18 9 15 19     16 11 5 9 8 6 2 4 0 2 0 1   0.168000 3.800 3.800 9.200      2406866           3           0  0 0 0 0 0 0 0 0 0 1 0 2 0 1 0 2 3 2 3 1 2 1 2 2 5 2 1 2 3 2 2 2 5 3 5 3 3 1 3    6 8 6 1 3 9 6 3 6 10 5 5 7 4 5 7 12 9 5 7 5 6 6 8 3 5 4 7 8 5 6 5 8 13 4 10 2    10 9 7 7 16 9 10 9 13 8 12 9 13 15 9 15 9 10 11 6 6 6 7 7 6 8 15 9 8 9 6 12 12   11 14 12 11 13 8 17 18 18 11 14 19 14 25 21 15 10 15 19 27 23 22 24 17 19 18     12 16 22 21 25 9 25 15 19 15 21 15 8 11 13 12 10 12 7 13 11 17 11 13 10 16 19    14 23 11 8 12 13 10 9 17 4 14 10 7 10 17 14 11 11 20 18 13 8 12 6 8 13 12 23     15 14 15 16 9 14 9 13 14 17 11 17 11 10 15 17 11 6 12 12 14 15 17 12 16 16 8     17 15 15 10 15 11 10 15 12 13 9 12 9 12 15 12 6 18 7 15 14 12 21 18 11 10 18     11 19 11 7 11 3 2 5 4 0 1 1   0.170000 3.850 3.850 9.300      2508471           7           0  0 0 0 0 0 0 0 0 0 0 0 0 1 3 1 2 1 4 3 3 1 2 7 0 3 2 2 2 2 5 2 3 2 3 3 4 3 7 3    5 3 4 4 6 2 3 10 4 11 3 13 7 7 5 6 3 8 10 6 6 4 10 11 4 12 7 8 9 7 7 8 4 6 7 9   9 5 9 11 5 14 9 10 7 9 8 8 5 6 11 13 14 10 10 10 10 8 9 9 9 9 14 14 13 11 8 18   9 10 9 16 12 13 15 13 10 17 16 20 14 22 20 26 29 29 27 24 20 37 21 24 13 18 13   28 24 22 25 21 13 14 15 9 11 18 8 16 17 16 13 12 16 11 11 17 15 11 15 10 11 12   13 12 12 20 15 14 15 16 12 17 15 15 12 10 14 14 17 15 19 15 13 13 11 12 16 14    17 16 8 16 12 8 14 13 13 10 10 9 12 11 19 20 13 11 4 15 11 14 11 20 18 18 13     20 12 20 21 15 15 12 13 18 18 11 16 9 14 9 18 11 10 11 20 11 13 17 13 13 12 14   16 10 12 12 23 12 11 12 8 8 1 0 1 2 0   0.172000 3.900 3.900 9.400      2591210           3           0  0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 4 4 3 2 1 3 3 2 3 0 3 6 1 3 1 5 5 4 3 9 9 0 4 7    5 3 5 5 8 7 3 3 5 5 8 5 11 10 8 10 3 6 6 6 7 7 8 8 12 9 6 10 8 7 10 8 8 10 4 6   12 20 4 6 11 7 9 10 7 5 10 6 12 11 7 13 13 16 12 6 8 14 13 9 7 5 14 17 17 10     12 11 6 13 11 17 3 23 13 21 12 21 28 11 23 30 28 23 24 26 26 17 21 15 27 23 33   16 22 25 11 20 22 23 21 20 7 21 13 16 12 16 16 13 18 18 9 13 16 15 9 20 13 19    15 8 9 11 14 13 10 9 10 16 15 14 17 15 19 16 12 14 12 14 14 16 19 19 4 24 8 12   15 16 11 15 14 20 14 13 13 14 16 19 14 13 19 14 18 23 15 15 4 14 17 14 8 10 15   20 11 15 19 12 9 13 12 11 16 12 16 13 14 16 13 16 16 19 19 12 11 10 19 15 15     14 12 5 11 18 17 10 13 12 9 6 2 0 0 1 0   0.174000 3.950 3.950 9.500      2675515           3           0  0 0 0 0 0 0 0 0 0 0 2 0 1 1 0 2 1 2 3 3 1 3 1 3 7 5 3 6 4 3 9 4 5 2 5 3 3 3 6    9 5 5 2 6 8 5 8 4 8 5 6 5 6 4 6 3 7 11 6 9 9 3 6 6 7 6 8 7 9 12 18 6 9 8 11 11   8 14 15 15 11 15 13 9 19 10 15 14 9 4 18 5 8 10 8 10 13 9 12 11 8 8 12 6 15 8    9 9 18 7 17 21 9 13 18 14 21 24 18 22 17 26 15 21 23 25 19 26 23 20 27 17 27     20 26 15 22 15 19 15 16 24 12 15 24 13 13 17 11 7 10 21 15 15 16 13 20 22 12     16 12 16 15 14 18 11 12 14 14 24 10 13 16 19 8 11 18 19 15 15 23 16 16 11 12     18 11 13 14 16 10 14 13 18 12 15 15 14 8 11 17 12 22 13 12 14 15 10 11 15 19     15 12 17 8 21 23 13 19 11 8 12 15 11 14 15 19 15 10 17 9 16 14 18 14 16 14 14    23 14 14 13 16 12 14 15 14 9 14 7 5 2 3 1 1 1   0.176000 4.000 4.000 9.600      2779386           5           0  0 0 0 0 0 0 0 0 0 0 0 2 2 3 0 1 3 0 6 2 6 3 1 5 0 4 1 6 5 1 6 3 6 5 6 2 5 4 5    3 9 8 5 7 5 8 4 12 8 12 6 8 5 7 5 7 10 5 5 6 7 9 7 10 7 10 10 8 12 10 6 13 10    11 12 11 10 10 16 9 6 12 9 11 17 10 11 10 14 11 16 7 11 13 12 10 17 14 11 13     12 10 13 16 16 17 17 15 14 11 8 15 13 27 22 14 19 17 22 22 27 18 28 19 27 32     24 33 21 17 23 12 27 25 20 20 17 22 14 15 22 21 14 9 16 12 19 16 17 16 16 20     14 18 15 14 18 10 12 9 16 12 12 10 13 19 12 12 15 14 15 22 12 11 15 18 19 18     10 6 11 14 10 23 17 14 16 19 10 10 16 19 17 23 16 18 19 18 16 12 14 14 14 13     11 10 24 21 22 26 18 18 18 14 17 5 13 17 11 13 16 14 18 16 9 15 15 18 16 14 21   13 22 17 9 8 16 17 16 16 19 7 20 19 18 16 10 6 10 6 3 5 1 0 0 2   0.178000 4.050 4.050 9.700      2869617           3           0  0 0 0 0 0 0 0 0 0 0 2 2 2 0 1 4 1 3 2 2 1 2 3 2 2 4 4 7 5 6 5 3 6 6 5 7 8 1 5    2 3 5 5 8 10 7 6 10 9 6 8 9 7 8 10 15 4 10 5 8 8 6 11 8 8 11 7 5 8 14 5 11 7     13 10 9 7 8 9 14 12 10 9 11 6 14 15 14 13 11 9 18 18 10 14 14 10 12 16 12 9 8    14 15 6 11 11 12 10 14 12 11 18 13 13 27 16 23 23 20 21 32 20 18 25 22 24 32     25 34 19 23 21 25 22 25 19 23 19 21 16 19 16 18 9 18 6 13 12 13 18 12 8 19 14    14 11 16 13 15 14 21 11 14 14 13 11 20 14 14 26 10 22 16 18 15 20 24 18 19 19    16 14 14 14 21 13 19 18 20 13 17 11 17 14 22 17 15 15 20 8 21 15 16 16 23 17     13 19 21 20 12 15 18 15 19 15 18 17 20 15 13 14 24 18 15 15 14 18 20 19 17 19    20 21 21 15 19 19 17 11 16 16 11 23 10 20 13 10 5 10 2 3 1 1 0   0.180000 4.100 4.100 9.800      2975040           3           0  0 0 0 0 0 0 0 0 1 0 0 1 2 2 4 4 2 4 4 1 2 5 0 3 3 5 2 5 5 4 9 2 7 8 4 8 3 11 6   10 4 7 8 6 6 5 8 8 7 11 4 4 11 12 7 11 7 10 11 7 11 11 10 9 7 13 12 18 8 14 12   14 12 8 8 16 10 10 14 16 10 6 8 15 15 15 22 13 19 18 12 6 11 10 7 12 12 24 15    17 9 17 21 10 17 18 14 14 14 9 22 11 23 17 15 23 32 20 11 12 20 15 23 30 20 25   19 26 29 19 27 23 15 19 11 30 16 21 24 18 18 14 8 6 25 13 21 13 13 19 13 21 25   23 18 14 14 13 20 12 14 8 10 25 14 15 20 15 10 15 16 21 8 15 20 21 20 13 16 15   20 11 18 17 17 9 12 24 19 13 18 17 20 14 15 20 10 23 19 25 8 7 13 14 11 15 18    13 10 12 10 17 11 24 16 17 11 12 13 16 20 14 26 12 17 13 14 16 16 6 20 16 23     22 11 17 16 14 25 19 17 21 22 19 13 19 16 18 10 11 7 4 6 0 0 2   0.182000 4.150 4.150 9.900      3083416           6           0  0 0 0 0 0 0 0 0 0 0 2 1 1 4 1 3 4 3 5 6 2 1 4 2 3 5 6 6 7 2 4 1 11 7 5 2 6 6 8   9 8 12 7 11 9 6 12 7 8 9 6 6 8 11 6 6 8 11 8 11 12 11 13 9 10 7 9 6 11 9 13 12   12 8 14 15 8 9 8 8 11 22 16 6 11 16 15 9 13 12 12 13 11 15 9 9 16 14 14 12 21    12 12 12 16 19 10 15 18 8 16 14 16 16 21 30 22 9 25 19 19 26 23 33 25 22 21 19   21 20 20 21 20 26 20 29 27 25 25 21 20 25 21 21 18 14 19 15 6 20 18 16 20 16     13 13 15 15 15 15 22 16 15 15 11 21 19 11 19 13 14 15 17 21 12 18 12 22 18 21    18 13 23 15 18 9 21 11 14 23 18 21 25 18 22 15 21 23 15 15 16 19 21 18 19 21     17 13 24 23 22 19 14 20 22 15 14 14 20 20 23 13 18 15 18 20 20 24 9 12 17 21     21 12 16 17 16 16 21 26 19 15 21 22 24 15 11 13 13 6 8 1 4 0 1 0   0.184000 4.200 4.200 10.00      3174897           3           0  0 0 0 0 0 0 0 0 0 0 1 1 2 3 0 5 4 3 3 0 7 3 2 4 2 8 6 4 5 9 3 8 6 4 2 7 6 8 7    9 3 5 8 5 9 7 7 6 11 14 7 12 9 9 5 15 12 14 15 12 9 11 5 8 13 11 12 10 9 17 12   11 8 17 11 19 11 15 9 11 7 15 14 16 16 16 7 12 10 14 13 13 16 16 11 15 13 14     12 16 11 12 13 17 10 13 19 11 17 11 13 14 13 10 19 19 23 24 22 24 24 31 19 23    22 28 21 25 29 17 23 17 21 30 22 19 25 27 27 22 23 23 17 25 17 20 17 12 23 21    9 17 20 16 19 16 17 20 9 16 11 22 16 15 12 15 17 23 24 16 16 18 26 11 16 20 18   10 14 17 26 19 17 15 17 19 12 21 20 24 17 27 13 16 18 19 23 14 19 14 10 11 18    19 6 15 21 23 25 17 17 18 21 27 20 17 18 20 25 22 20 18 22 18 17 15 24 16 15     22 18 22 14 20 20 22 18 22 25 19 26 12 19 19 13 12 16 19 14 9 7 5 4 2 0 2   0.186000 4.250 4.250 10.10      3283256           3           0  0 0 0 0 0 0 0 1 0 0 1 1 4 1 5 2 5 5 3 4 6 3 2 4 7 8 2 6 6 4 10 7 8 7 5 4 4 9 8   18 10 7 6 6 13 12 10 13 10 7 15 4 7 10 13 12 8 8 13 5 14 6 9 14 9 10 16 12 13    11 8 12 11 10 13 9 11 15 17 23 18 13 10 12 11 12 14 14 14 10 12 12 16 13 15 13   13 14 18 10 13 17 14 14 14 12 12 8 18 14 23 20 16 19 16 16 16 27 18 21 19 20     19 37 22 21 22 28 24 26 18 21 28 21 22 21 21 22 16 15 13 22 22 27 22 11 13 20    10 17 16 19 20 30 18 25 8 7 22 18 17 14 23 16 17 11 16 24 19 18 22 15 15 23 16   13 15 22 14 8 12 18 13 15 22 17 15 15 17 27 21 19 21 24 17 10 12 14 19 17 22     18 19 17 28 19 15 14 16 28 17 20 15 11 22 18 19 16 21 17 24 19 22 22 20 10 20    18 18 18 21 18 23 18 32 26 21 21 22 20 22 16 17 20 22 21 17 13 13 11 9 5 0 1 1   1   0.188000 4.300 4.300 10.20      3396610           5           0  0 0 0 0 0 0 0 0 0 0 1 2 3 0 2 5 5 4 3 3 5 1 2 3 6 9 3 3 3 8 7 2 9 5 7 5 11 8 9   7 6 9 6 4 5 8 6 10 9 14 10 15 6 7 13 15 10 13 7 15 10 10 11 14 14 6 7 17 13 19   3 13 9 6 13 13 14 10 11 12 16 17 13 10 15 15 19 19 11 11 15 11 13 9 13 20 8 18   14 18 23 23 23 15 19 20 14 11 7 18 16 15 22 28 20 24 22 25 17 20 39 24 26 25     25 33 25 25 25 33 15 29 18 29 18 12 18 23 17 24 28 22 16 20 33 23 18 23 26 23    15 24 16 16 16 16 17 15 15 16 14 11 9 23 17 13 13 18 12 19 20 30 20 20 15 21     19 16 18 20 23 19 15 10 11 15 19 13 22 22 18 19 16 19 23 16 10 25 23 20 21 20    31 19 19 18 15 22 18 14 13 21 18 19 22 19 16 17 21 14 20 26 18 26 22 19 26 19    20 22 15 13 24 23 15 21 21 21 27 18 22 19 24 17 22 16 18 23 10 12 3 5 3 3 0 0   0.190000 4.350 4.350 10.30      3502025           3           0  0 0 0 0 0 0 0 0 0 0 0 3 0 3 2 3 4 4 3 4 5 10 7 6 6 4 5 12 10 6 6 13 10 6 7 14    9 6 13 10 12 16 3 9 9 7 5 6 13 11 10 8 11 19 12 14 13 16 13 14 9 12 14 13 14     16 10 14 7 16 18 16 9 15 11 20 15 10 14 14 11 14 17 10 6 16 10 15 12 17 17 20    15 7 12 23 15 8 13 12 8 16 15 20 16 16 20 14 11 20 24 23 20 16 18 27 25 31 27    27 25 21 31 27 20 23 24 32 17 21 34 27 17 19 19 25 30 27 21 24 28 30 19 26 21    14 16 21 23 27 8 17 21 17 11 23 15 22 15 18 10 17 20 23 18 18 17 19 22 15 22     21 19 23 18 18 26 17 18 26 18 24 15 22 23 23 19 23 25 23 24 26 10 21 16 32 23    18 19 24 21 28 26 22 19 19 14 30 21 24 23 22 21 13 27 20 27 24 15 20 22 22 13    25 14 19 32 21 18 18 23 22 22 14 18 20 24 14 19 20 18 17 24 29 27 20 12 18 17    11 9 2 3 2 1 0   0.192000 4.400 4.400 10.40      3593938           3           0  0 0 0 0 0 0 0 0 0 0 1 0 1 1 2 3 4 7 8 1 5 6 8 3 7 5 4 9 8 8 7 7 9 7 9 9 15 5 7   8 15 14 9 9 13 8 8 15 10 7 10 9 10 14 7 8 18 16 17 11 14 15 13 8 15 8 15 18 16   16 22 12 8 16 13 10 13 13 10 21 11 10 16 16 13 13 17 16 20 23 13 22 16 14 15     22 19 22 15 22 24 16 16 16 19 12 15 16 17 20 18 19 26 17 23 18 32 20 28 36 22    25 30 29 31 36 24 24 21 29 24 32 29 30 23 34 19 33 34 25 20 31 27 24 16 14 21    20 13 24 17 28 13 24 16 26 15 26 21 11 15 20 13 20 18 25 23 18 24 26 22 16 22    14 13 16 20 24 25 19 29 20 15 20 16 25 26 21 22 17 24 22 21 17 23 23 15 19 30    23 17 21 19 18 21 26 14 29 24 20 33 19 15 20 23 28 19 23 25 15 19 17 31 23 18    29 26 25 14 24 25 18 19 19 24 35 31 23 23 14 15 19 11 20 19 24 17 16 9 10 12 3   2 2 0 1   0.194000 4.450 4.450 10.50      3712573           7           0  0 0 0 0 0 0 0 0 0 0 0 1 1 1 5 3 5 4 3 11 3 10 4 6 7 8 5 5 5 8 9 12 7 7 11 8 6    7 9 10 13 10 6 13 9 9 9 11 14 14 12 13 10 6 13 13 15 12 13 19 8 14 13 16 11 13   14 15 9 15 16 13 16 17 17 17 23 18 16 19 10 13 18 16 10 9 21 11 22 14 20 14 18   13 15 12 13 14 16 14 15 20 29 17 14 18 8 15 21 15 19 15 22 20 17 15 23 26 16     26 24 23 23 23 23 30 24 29 28 26 35 33 31 22 23 22 20 37 22 27 33 26 27 26 17    16 18 27 22 21 24 18 18 18 17 15 18 14 19 24 22 15 20 21 15 19 25 15 16 26 19    22 29 20 16 13 15 16 32 24 23 13 33 17 22 18 18 23 24 22 21 20 26 21 16 22 18    18 16 15 26 26 17 22 21 13 25 24 13 23 18 18 25 32 20 24 21 17 19 24 24 23 33    19 19 21 32 18 22 23 19 23 32 18 31 22 25 23 23 31 29 21 16 20 20 15 22 14 12    5 10 9 2 1 0 1   0.196000 4.500 4.500 10.60      3829518           3           0  0 0 0 0 0 0 0 0 0 1 2 2 1 6 2 6 5 9 3 5 6 8 6 3 8 10 7 11 9 4 8 9 5 11 10 13 9   16 13 10 9 5 12 9 15 10 13 9 12 18 14 19 9 13 14 12 13 21 17 17 18 16 13 12 16   14 18 10 15 15 16 11 15 22 17 19 17 11 12 26 12 17 19 18 21 20 27 17 18 19 21    14 19 16 12 16 21 20 18 8 17 17 13 13 18 15 19 15 19 20 28 21 29 27 27 34 24     26 31 25 24 16 17 23 23 30 28 18 28 32 28 37 18 26 18 16 33 21 31 21 20 22 19    20 25 18 18 20 11 17 20 22 23 14 14 17 18 20 25 20 19 20 22 19 16 33 25 21 21    24 18 16 22 29 22 16 27 26 28 21 20 22 17 25 23 20 23 18 16 19 26 22 21 22 23    15 20 19 17 23 19 20 15 22 18 22 26 23 23 31 17 29 18 13 15 19 18 24 22 28 22    17 23 24 26 21 23 25 24 29 26 18 41 24 29 22 27 23 28 16 30 24 18 23 19 17 18    21 17 14 8 2 5 2 0 0   0.198000 4.550 4.550 10.70      3950740           3           0  0 0 0 0 0 0 0 0 1 1 1 2 1 3 7 5 6 7 7 7 4 5 6 4 1 8 9 10 9 8 10 8 12 6 10 8 10   8 11 9 10 15 7 11 8 13 11 13 15 15 17 12 10 8 17 12 9 14 12 14 11 14 21 14 15    20 18 16 8 15 22 24 14 10 18 14 15 16 12 10 16 21 16 25 17 20 17 17 20 15 24     15 17 22 25 17 13 22 18 20 19 11 21 22 21 16 21 24 16 22 17 21 17 24 22 24 35    27 24 28 24 32 37 34 25 24 29 37 37 25 28 21 23 24 22 21 20 25 22 32 19 21 22    24 20 21 20 22 18 27 17 14 20 22 22 22 14 19 20 20 21 23 22 14 20 21 23 20 18    23 20 25 31 24 18 22 14 23 22 21 23 27 27 20 21 18 22 23 24 23 21 18 22 17 22    21 35 15 24 24 12 27 30 27 28 22 31 24 24 19 27 24 28 23 25 26 35 27 22 29 21    24 18 19 26 33 29 31 23 25 19 24 26 21 10 23 24 26 28 20 27 26 17 29 22 18 14    22 8 10 11 4 4 1 2 0   0.200000 4.600 4.600 10.80      4068161           5           0  0 0 0 0 0 0 0 0 0 1 1 0 1 5 5 2 9 3 11 6 9 8 7 7 8 3 3 13 10 8 7 5 8 13 8 7 14   12 10 7 15 13 13 11 12 12 14 12 13 12 10 15 11 14 7 16 15 8 15 13 15 13 18 13    17 21 15 12 13 13 17 18 18 18 16 19 20 17 14 17 24 13 12 18 19 19 13 21 18 26    21 23 16 14 18 19 13 33 13 19 20 14 20 23 14 26 19 22 21 21 16 27 30 25 28 22    32 21 30 27 31 21 30 22 27 27 31 27 21 17 38 41 17 21 20 19 30 24 27 20 20 21    30 20 19 19 31 25 24 13 21 23 19 24 33 24 17 20 17 12 25 23 18 24 11 24 25 22    33 20 11 22 31 21 20 26 27 21 26 24 14 23 23 20 20 26 28 10 20 27 24 22 17 27    28 20 23 23 33 20 24 26 32 33 29 21 25 24 17 18 19 27 26 20 24 26 24 24 26 21    19 24 21 36 32 18 33 33 20 23 25 33 19 27 25 27 24 27 21 21 23 28 18 27 25 19    24 15 17 12 15 7 2 1 0 0 ", "%f ", Inf);
+%! assert(rows (x) == n);
+
+%% Note use fprintf so output not sent to stdout
+%% test/octave.test/io/printf-1.m
+%!test
+%! nm = tmpnam();
+%! fid1 = fopen(nm,"w");
+%! x = fprintf (fid1, "%s: %d\n", "test", 1);
+%! fclose(fid1);
+%! fid2 = fopen(nm,"r");
+%! str = fscanf(fid2,"%s");
+%! fclose(fid2);
+%! unlink(nm);
+%! assert(x,8);
+%! assert(str,"test:1");
+
+%% test/octave.test/io/printf-2.m
+%!error printf (1);
+
+%% test/octave.test/io/printf-3.m
+%!error <Invalid call to printf.*> printf ();
+
+%% test/octave.test/io/sprintf-1.m
+%!test
+%! [s, msg, status] = sprintf ("%s: %d\n", "test", 1);
+%! 
+%! assert(s == "test: 1\n" && ischar (msg) && status == 8);
+
+%% test/octave.test/io/sprintf-2.m
+%!error sprintf (1);
+
+%% test/octave.test/io/sprintf-3.m
+%!error <Invalid call to sprintf.*> sprintf ();
+
+%% test/octave.test/io/fopen-1.m
+%!test
+%! arch_list = ["native"; "ieee-le"; "ieee-be"; "vaxd"; "vaxg"; "cray"];
+%! 
+%! status = 1;
+%! 
+%! for i = 1:6
+%!   arch = deblank (arch_list (i,:));
+%!   for j = 1:6
+%!     if (j == 1)
+%!       mode_list = ["w"; "r"; "a"];
+%!     elseif (j == 2)
+%!       mode_list = ["w+"; "r+"; "a+"];
+%!     endif
+%!     nm = tmpnam ();
+%!     for k = 1:3
+%!       mode = deblank (mode_list (k,:));
+%!       [id, err] = fopen (nm, mode, arch);
+%!       if (id < 0)
+%!         printf_assert ("open failed: %s (%s, %s): %s\n", nm, mode, arch, err);
+%!         status = 0;
+%!         break;
+%!       else
+%!         fclose (id);
+%!       endif
+%!       tmp_mode = cstrcat (mode, "b");
+%!       [id, err] = fopen (nm, tmp_mode, arch);
+%!       if (id < 0)
+%!         printf_assert ("open failed: %s (%s, %s): %s\n", nm, tmp_mode, arch, err);
+%!         status = 0;
+%!         break;
+%!       else
+%!         fclose (id);
+%!       endif
+%!       tmp_mode = cstrcat (mode, "t");
+%!       [id, err] = fopen (nm, tmp_mode, arch);
+%!       if (id < 0)
+%!         printf_assert ("open failed: %s (%s, %s): %s\n", nm, tmp_mode, arch, err);
+%!         status = 0;
+%!         break;
+%!       else
+%!         fclose (id);
+%!       endif
+%!     endfor
+%!     unlink (nm);
+%!     if (status == 0)
+%!       break;
+%!     endif
+%!   endfor
+%!   if (status == 0)
+%!     break;
+%!   endif
+%! endfor
+%! 
+%! assert(status == 1);
+
+%% test/octave.test/io/fopen-2.m
+%!test
+%! s.a = 1;
+%! fail("fopen (s)");
+
+%% test/octave.test/io/fopen-3.m
+%!error fopen ("foo", "x");
+
+%% test/octave.test/io/fopen-4.m
+%! fopen ("foo", "wb", "noodle");
+%! assert(prog_output_assert("error:.*"));
+
+%% test/octave.test/io/fopen-5.m
+%!error <Invalid call to fopen.*> fopen ();
+
+%% test/octave.test/io/fopen-6.m
+%!error <Invalid call to fopen.*> fopen ("foo", "wb", "native", 1);
+
+%% test/octave.test/io/fclose-1.m
+%!error fclose (0);
+
+%% test/octave.test/io/fclose-2.m
+%!error <Invalid call to fclose.*> fclose (1, 2);
+
+%% test/octave.test/io/tmpnam-1.m
+%!assert(ischar (tmpnam ()));
+
+%% test/octave.test/io/tmpnam-2.m
+%!warning tmpnam (1);
+
+%% test/octave.test/io/tmpnam-3.m
+%!warning tmpnam ("foo", 1);
+
+%% test/octave.test/io/tmpnam-4.m
+%!error <Invalid call to tmpnam.*> tmpnam (1, 2, 3);
+
+%% test/octave.test/io/binary-io-1.m
+%!test
+%! type_list = ["char"; "char*1"; "integer*1"; "int8";
+%! "schar"; "signed char"; "uchar"; "unsigned char";
+%! "short"; "ushort"; "unsigned short"; "int";
+%! "uint"; "unsigned int"; "long"; "ulong"; "unsigned long";
+%! "float"; "float32"; "real*4"; "double"; "float64";
+%! "real*8"; "int16"; "integer*2"; "int32"; "integer*4"];
+%! 
+%! n = rows (type_list);
+%! 
+%! nm = tmpnam ();
+%! 
+%! id = fopen (nm, "wb");
+%! 
+%! if (id > 0)
+%! 
+%! for i = 1:n
+%! fwrite (id, i, deblank (type_list(i,:)));
+%! endfor
+%! 
+%! fclose (id);
+%! 
+%! id = fopen (nm, "rb");
+%! 
+%! if (id > 0)
+%! 
+%! x = zeros (1, n);
+%! 
+%! for i = 1:n
+%! x(i) = fread (id, [1, 1], deblank (type_list(i,:)));
+%! endfor
+%! 
+%! if (x == 1:n)
+%! printf_assert ("ok\n");
+%! endif
+%! 
+%! endif
+%! 
+%! endif
+%! 
+%! unlink (nm);
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/io/file-pos-1.m
+%!test
+%! nm = tmpnam ();
+%! id = fopen (nm, "wb");
+%! if (id > 0)
+%!   fprintf (id, "%d\n", 1:100);
+%!   fclose (id);
+%!   id = fopen (nm, "rb");
+%!   if (id > 0)
+%!     for i = 1:101
+%!       fgets (id);
+%!     endfor
+%!     if (feof (id))
+%!       fclose (id);
+%!       id = fopen (nm, "rb");
+%!       pos_one = ftell (id);
+%!       s_one = fgets (id);
+%!       for i = 1:48
+%!         s = fgets (id);
+%!       endfor
+%!       pos_fifty = ftell (id);
+%!       s_fifty = fgets (id);
+%!       fseek (id, pos_one, SEEK_SET);
+%!       s_one_x = fgets (id);
+%!       fseek (id, pos_fifty, SEEK_SET);
+%!       s_fifty_x = fgets (id);
+%!       if (s_one == s_one_x && s_fifty == s_fifty_x)
+%!         frewind (id);
+%!         s_one_x = fgets (id);
+%!         if (s_one != s_one_x)
+%!           error("bombed!!");
+%!         endif
+%!       endif
+%!     endif
+%!   endif
+%! endif
+%! unlink (nm);
+
+%% test/octave.test/io/fputs-1.m
+%!error <Invalid call to fputs.*> fputs ();
+
+%% test/octave.test/io/fputs-2.m
+%!error <Invalid call to fputs.*> fputs (1, "foo", 1);
+
+%% test/octave.test/io/fputs-3.m
+%!assert(fputs (1, 1),-1);
+
+%% test/octave.test/io/fgetl-1.m
+%!error <Invalid call to fgetl.*> fgetl ();
+
+%% test/octave.test/io/fgetl-2.m
+%!error <Invalid call to fgetl.*> fgetl (1, 2, 3);
+
+%% test/octave.test/io/fgetl-3.m
+%!error fgetl ("foo", 1);
+
+%% test/octave.test/io/fgets-1.m
+%!error <Invalid call to fgets.*> fgets ();
+
+%% test/octave.test/io/fgets-2.m
+%!error <Invalid call to fgets.*> fgets (1, 2, 3);
+
+%% test/octave.test/io/fgets-3.m
+%!error fgets ("foo", 1);
+
+%% test/octave.test/io/fprintf-1.m
+%!error <Invalid call to fprintf.*> fprintf ();
+
+%% test/octave.test/io/fprintf-2.m
+%!error <Invalid call to fprintf.*> fprintf (1);
+
+%% test/octave.test/io/fprintf-3.m
+%!test
+%! s.a = 1;
+%! fail("fprintf (s)","Invalid call to fprintf.*");
+
+%% test/octave.test/io/fprintf-4.m
+%!error fprintf (1, 1);
+
+%% test/octave.test/io/fprintf-5.m
+%!error fprintf (-1, "foo");
+
+%% test/octave.test/io/fscanf-1.m
+%!error <Invalid call to fscanf.*> fscanf ();
+
+%% test/octave.test/io/fscanf-2.m
+%!error <Invalid call to fscanf.*> fscanf (1);
+
+%% test/octave.test/io/fscanf-3.m
+%!error fscanf ("foo", "bar");
+
+%% test/octave.test/io/fread-1.m
+%!error <Invalid call to fread.*> fread ();
+
+%% test/octave.test/io/fread-2.m
+%!error <Invalid call to fread.*> fread (1, 2, "char", 1, "native", 2);
+
+%% test/octave.test/io/fread-3.m
+%!error fread ("foo");
+
+%% test/octave.test/io/fwrite-1.m
+%!error <Invalid call to fwrite.*> fwrite ();
+
+%% test/octave.test/io/fwrite-2.m
+%!error <Invalid call to fwrite.*> fwrite (1, rand (10), "char", 1, "native", 2);
+
+%% test/octave.test/io/fwrite-3.m
+%!error fwrite ("foo", 1);
+
+%% test/octave.test/io/feof-1.m
+%!error <Invalid call to feof.*> feof ();
+
+%% test/octave.test/io/feof-2.m
+%!error <Invalid call to feof.*> feof (1, 2);
+
+%% test/octave.test/io/feof-3.m
+%!error feof ("foo");
+
+%% FIXME trimerr in test.m finds and strips ".*ferror:"!!
+%% So use fail for the next two tests instead.
+%% test/octave.test/io/ferror-1.m
+%!test
+%! fail("ferror ();","Invalid call to ferror.*");
+
+%% test/octave.test/io/ferror-2.m
+%!test
+%! fail("ferror (1, \"clear\", 2);","Invalid call to ferror.*"); 
+
+%% test/octave.test/io/ferror-3.m
+%!error ferror ("foo");
+
+%% test/octave.test/io/ftell-1.m
+%!error <Invalid call to ftell.*> ftell ();
+
+%% test/octave.test/io/ftell-2.m
+%!error <Invalid call to ftell.*> ftell (1, 2);
+
+%% test/octave.test/io/ftell-3.m
+%!error ftell ("foo");
+
+%% test/octave.test/io/fseek-1.m
+%!error <Invalid call to fseek.*> fseek ();
+
+%% test/octave.test/io/fseek-2.m
+%!error <Invalid call to fseek.*> fseek (1, 0, SEEK_SET, 1);
+
+%% test/octave.test/io/fseek-3.m
+%!error fseek ("foo", 0, SEEK_SET);
+
+%% test/octave.test/io/frewind-1.m
+%!error <Invalid call to frewind.*> frewind ();
+
+%% test/octave.test/io/frewind-2.m
+%!error <Invalid call to frewind.*> frewind (1, 2);
+
+%% test/octave.test/io/frewind-3.m
+%!error frewind ("foo");
+
diff --git a/test/test_logical-wfi-f.m b/test/test_logical-wfi-f.m
new file mode 100644
index 0000000..99d3145
--- /dev/null
+++ b/test/test_logical-wfi-f.m
@@ -0,0 +1,371 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/logical-wfi-f/s-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [];
+%! fail("a(0);");
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/s-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 2;
+%! assert(a(1) == 2);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/s-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = 2;
+%! assert(a(1) == 2);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/s-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%!shared a
+%!  a = 2;
+%!error <A\(I\): Index exceeds matrix dimension\.> a(logical ([1,1]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/v-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(isempty (a(logical ([0,0,0,0]))));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/v-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(all (a(logical ([1,1,1,1])) == [9,8,7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/v-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(all (a(logical ([0,1,1,0])) == [8,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/v-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(all (a(logical ([1,1])) == [9,8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(isempty (a(logical ([0,0,0,0]))));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1,1,1])) == [9,7,8,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1,1,0])) == [7,8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical (0:1),logical (0:1)) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-5.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),2:-1:1) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-6.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical (0:1),logical ([0,1])) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-7.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),[2,1]) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-8.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),:) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-9.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical (0:1),1) == 7);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-10.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),logical ([1,1])) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-11.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(2:-1:1,logical (0:1)) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-12.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(2:-1:1,logical ([0,1])) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-13.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(2:-1:1,logical ([1,1])) == [7,6;9,8])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-14.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical ([0,1]),logical (0:1)) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-15.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),2:-1:1) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-16.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical ([0,1]),logical ([0,1])) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-17.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),[2,1]) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-18.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),:) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-19.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical ([0,1]),1) == 7);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-20.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),logical ([1,1])) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-21.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a([2,1],logical (0:1)) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-22.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a([2,1],logical ([0,1])) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-23.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a([2,1],logical ([1,1])) == [7,6;9,8])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-24.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(:,logical (0:1)) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-25.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(:,logical ([0,1])) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-26.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(:,logical ([1,1])) == [9,8;7,6])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-27.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(1,logical (0:1)) == 8);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-28.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(1,logical ([0,1])) == 8);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-29.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(1,logical ([1,1])) == [9,8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-30.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1]),logical (0:1)) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-31.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),2:-1:1) == [8,9;6,7])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-32.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1]),logical ([0,1])) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-33.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),[2,1]) == [8,9;6,7])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-34.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),:) == [9,8;7,6])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-35.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1]),1) == [9;7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-f/m-36.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("off", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),logical ([1,1])) == [9,8;7,6])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
diff --git a/test/test_logical-wfi-t.m b/test/test_logical-wfi-t.m
new file mode 100644
index 0000000..130629a
--- /dev/null
+++ b/test/test_logical-wfi-t.m
@@ -0,0 +1,371 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/logical-wfi-t/s-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [];
+%! fail("a(0);");
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/s-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 2;
+%! assert(a(1) == 2);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/s-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = 2;
+%! assert(a(1) == 2);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/s-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%!shared a
+%! a = 2;
+%!error <A\(I\): Index exceeds matrix dimension\.> a(logical ([1,1]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/v-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(isempty (a(logical ([0,0,0,0]))));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/v-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(all (a(logical ([1,1,1,1])) == [9,8,7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/v-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(all (a(logical ([0,1,1,0])) == [8,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/v-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8,7,6];
+%! assert(all (a(logical ([1,1])) == [9,8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-1.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! isempty (a(logical ([0,0,0,0])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-2.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! all (a(logical ([1,1,1,1])) == [9,7,8,6]);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-3.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! all (a(logical ([0,1,1,0])) == [7,8]);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-4.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical (0:1),logical (0:1)) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-5.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),2:-1:1) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-6.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical (0:1),logical ([0,1])) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-7.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),[2,1]) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-8.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),:) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-9.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical (0:1),1) == 7);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-10.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical (0:1),logical ([1,1])) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-11.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(2:-1:1,logical (0:1)) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-12.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(2:-1:1,logical ([0,1])) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-13.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(2:-1:1,logical ([1,1])) == [7,6;9,8])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-14.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical ([0,1]),logical (0:1)) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-15.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),2:-1:1) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-16.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical ([0,1]),logical ([0,1])) == 6);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-17.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),[2,1]) == [6,7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-18.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),:) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-19.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(logical ([0,1]),1) == 7);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-20.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([0,1]),logical ([1,1])) == [7,6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-21.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a([2,1],logical (0:1)) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-22.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a([2,1],logical ([0,1])) == [6;8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-23.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a([2,1],logical ([1,1])) == [7,6;9,8])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-24.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(:,logical (0:1)) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-25.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(:,logical ([0,1])) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-26.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(:,logical ([1,1])) == [9,8;7,6])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-27.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(1,logical (0:1)) == 8);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-28.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(a(1,logical ([0,1])) == 8);
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-29.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(1,logical ([1,1])) == [9,8]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-30.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1]),logical (0:1)) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-31.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),2:-1:1) == [8,9;6,7])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-32.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1]),logical ([0,1])) == [8;6]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-33.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),[2,1]) == [8,9;6,7])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-34.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),:) == [9,8;7,6])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-35.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (a(logical ([1,1]),1) == [9;7]));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
+%% test/octave.test/logical-wfi-t/m-36.m
+%!test
+%! wfi = warning ("query", "Octave:fortran-indexing");
+%! warning ("on", "Octave:fortran-indexing");
+%! a = [9,8;7,6];
+%! assert(all (all (a(logical ([1,1]),logical ([1,1])) == [9,8;7,6])));
+%! warning ("wfi.state", "Octave:fortran-indexing");
+
diff --git a/test/test_null_assign.m b/test/test_null_assign.m
new file mode 100644
index 0000000..4c9907f
--- /dev/null
+++ b/test/test_null_assign.m
@@ -0,0 +1,63 @@
+## Copyright (C) 2008 Jaroslav Hajek
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%!test
+%! a = 1:3; a(:) = []; assert (size (a), [0, 0])
+%!test
+%! a = 1:3; a(1:3) = []; assert (size (a), [1, 0])
+%!test
+%! a = (1:3).'; a(1:3) = []; assert (size (a), [0, 1])
+%!test
+%! a = ones (3); a(:,:) = []; assert (size (a), [0, 3])
+%!test
+%! a = ones (3); a(1:3,:) = []; assert (size (a), [0, 3])
+%!test
+%! a = ones (3); a(:,1:3) = []; assert (size (a), [3, 0])
+%!test
+%! a = ones (3); fail ("a(1:2,1:2) = []", ".*");
+%!test
+%! a = ones (3); fail ("a(1:3,1:3) = []", ".*");
+
+% null strings should delete. [,] and [;] should delete.
+%!test
+%! a = ones (3); a(1:2,:) = [,]; assert (size (a), [1,3])
+%!test
+%! a = ones (3); a(1:2,:) = [;]; assert (size (a), [1,3])
+%!test
+%! a = ones (3); a(1:2,:) = ''; assert (size (a), [1,3])
+%!test
+%! a = ones (3); a(1:2,:) = ""; assert (size (a), [1,3])
+
+% null matrix stored anywhere should lose its special status
+%!test
+%! a = ones (3); b = []; fail ("a(:,1:3) = b", ".")
+%!test
+%! a = ones (3); b{1} = []; fail ("a(:,1:3) = b{1}", ".")
+%!test
+%! a = ones (3); b.x = []; fail ("a(:,1:3) = b.x", ".")
+
+% filtering a null matrix through a function should not delete
+%!test
+%! a = ones (3); fail ("a(:,1:3) = double ([])")
+
+% subsasgn should work the same way
+%!test
+%! a = ones (3); a = subsasgn (a, substruct ('()', {':',1:2}), []); assert (size (a), [3,1])
+%!test
+%! a = ones (3); b = []; fail ("subsasgn (a, substruct ('()', {':',1:2}), b)", ".")
+
diff --git a/test/test_prefer.m b/test/test_prefer.m
new file mode 100644
index 0000000..6a4a973
--- /dev/null
+++ b/test/test_prefer.m
@@ -0,0 +1,246 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/prefer/prefer-1.m
+%!test
+%! m = [3 2];
+%! assert(all (m == (3:-1:2)));
+
+%% test/octave.test/prefer/prefer-2.m
+%!test
+%! m = [3,
+%! 2];
+%! assert(all (m == (3:-1:2)'));
+
+%% test/octave.test/prefer/prefer-3.m
+%!test
+%! a = 2;
+%! assert([a - 1],1);
+
+%% test/octave.test/prefer/prefer-4.m
+%!test
+%! m = [3,2];
+%! fail("[m ']");
+
+%% test/octave.test/prefer/prefer-5.m
+%!assert(all ([3 2] == (3:-1:2)));
+
+%% test/octave.test/prefer/prefer-6.m
+%!assert(all ([3, 2] == (3:-1:2)));
+
+%% test/octave.test/prefer/prefer-7.m
+%!test
+%! m = [3,2];
+%! assert(all ([m (1)] == (3:-1:1)));
+
+%% test/octave.test/prefer/prefer-8.m
+%!test
+%! m = [3,2];
+%! assert([m(1)],3);
+
+%% test/octave.test/prefer/prefer-9.m
+%!test
+%! m = [3,2];
+%! assert(all ([m (1)] == (3:-1:1)));
+
+%% test/octave.test/prefer/prefer-10.m
+%!test
+%! a = 2;
+%! assert([a- 1],1);
+
+%% test/octave.test/prefer/prefer-11.m
+%!test
+%! a = 1;
+%! assert(all ([a -1] == (1:-2:-1)));
+
+%% test/octave.test/prefer/prefer-12.m
+%!test
+%! wsn = warning ("query", "Octave:str-to-num");
+%! warning ("off", "Octave:str-to-num");
+%! assert("d" + 0,100);
+%! warning (wsn.state, "Octave:str-to-num");
+
+%% test/octave.test/prefer/prefer-13.m
+%!test
+%! wsn = warning ("query", "Octave:str-to-num");
+%! warning ("on", "Octave:str-to-num");
+%! fail("'d' + 0","warning");
+%! warning (wsn.state, "Octave:str-to-num");
+
+%% test/octave.test/prefer/prefer-14.m
+%!test
+%! wir = warning ("query", "Ocave:imag-to-real");
+%! warning ("off", "Ocave:imag-to-real");
+%! assert(eye (1+i),1);
+%! warning (wir.state, "Ocave:imag-to-real");
+
+%% test/octave.test/prefer/prefer-15.m
+%!test
+%! wir = warning ("query", "Ocave:imag-to-real");
+%! warning ("on", "Ocave:imag-to-real");
+%! fail("eye (1+i)","warning");
+%! warning (wir.state, "Ocave:imag-to-real");
+
+%% test/octave.test/prefer/prefer-17.m
+%!test
+%! wrre = warning ("query", "Octave:resize-on-range-error");
+%! warning ("off", "Octave:resize-on-range-error");
+%! clear a; 
+%! a(2) = 1; a(3) = 2; 
+%! assert(all (a == [0,1,2]));
+%! warning (wrre.state, "Octave:resize-on-range-error");
+
+%% test/octave.test/prefer/prefer-18.m
+%!test
+%! clear a; 
+%! a(1) = 1; a(2) = 2;
+%! assert(all (a == [1,2]));
+
+%% FIXME How the hell do I test this one in test/assert 
+%% test/octave.test/prefer/prefer-19.m
+%!#test
+%! pid = print_answer_id_name ();
+%! print_answer_id_name (0);
+%! a = 1
+%! print_answer_id_name (pid);
+
+%% FIXME How the hell do I test this one in test/assert 
+%% test/octave.test/prefer/prefer-20.m
+%!#test
+%! pid = print_answer_id_name ();
+%! print_answer_id_name (1);
+%! a = 1
+%! print_answer_id_name (pid);
+
+%% test/octave.test/prefer/prefer-21.m
+%!test
+%! ped = print_empty_dimensions ();
+%! print_empty_dimensions (0);
+%! a = cell (1, 1);
+%! b = type ("-q", "a");
+%! assert (!isempty (findstr (b{1}, "[]")));
+%! assert (isempty (findstr (b{1} ,"[](0x0)")));
+%! print_empty_dimensions (ped);
+
+%% test/octave.test/prefer/prefer-22.m
+%!test
+%! ped = print_empty_dimensions ();
+%! print_empty_dimensions (1);
+%! a = cell (1, 1);
+%! b = type ("-q", "a");
+%! assert (!isempty (findstr (b{1}, "[](0x0)")));
+%! print_empty_dimensions (ped);
+
+%% test/octave.test/prefer/prefer-23.m
+%!assert(all (size (inv ([])) == [0, 0]));
+
+%% test/octave.test/prefer/prefer-24.m
+%!assert(all (svd ([]) == zeros (0, 1)));
+
+%% test/octave.test/prefer/prefer-27.m
+%!test
+%! sp = save_precision ();
+%! save_precision (1);
+%! x = pi;
+%! nm = tmpnam();
+%! save("-text",nm,"x");
+%! clear x;
+%! load(nm);
+%! unlink(nm);
+%! assert(x,3);
+%! save_precision (sp);
+
+%% test/octave.test/prefer/prefer-28.m
+%!test
+%! sp = save_precision ();
+%! save_precision (5);
+%! x = pi;
+%! nm = tmpnam();
+%! save("-text",nm,"x");
+%! clear x;
+%! load(nm);
+%! unlink(nm);
+%! assert(x,3.1416);
+%! save_precision (sp);
+
+%% FIXME Same problem as above!!!
+%% test/octave.test/prefer/prefer-29.m
+%!function f ()
+%! 1
+%!#test
+%! sf = silent_functions ();
+%! silent_functions (0);
+%! f
+%! assert(??);
+%! silent_functions (sf);
+
+%% FIXME Same problem as above!!!
+%% test/octave.test/prefer/prefer-30.m
+%!function f ()
+%! 1
+%!#test
+%! sf = silent_functions ();
+%! silent_functions (1);
+%! f
+%! assert(??);
+%! silent_functions (sf);
+
+%% test/octave.test/prefer/prefer-32.m
+%!test
+%! wndz = warning ("query", "Octave:neg-dim-as-zero");
+%! warning ("on", "Octave:neg-dim-as-zero");
+%! fail("eye (-1) == []","warning");
+%! warning (wndz.state, "Octave:neg-dim-as-zero");
+
+%% test/octave.test/prefer/prefer-33.m
+%!test
+%! wndz = warning ("query", "Octave:neg-dim-as-zero");
+%! warning ("off", "Octave:neg-dim-as-zero");
+%! assert(all (size (eye (-1)) == [0, 0]));
+%! warning (wndz.state, "Octave:neg-dim-as-zero");
+
+%% test/octave.test/prefer/prefer-34.m
+%!test
+%! watv = warning ("query", "Octave:assign-as-truth-value");
+%! warning ("off", "Octave:assign-as-truth-value");
+%! if (x = 1) 1; endif
+%! warning (watv.state, "Octave:assign-as-truth-value");
+
+%% test/octave.test/prefer/prefer-35.m
+%!test
+%! watv = warning ("query", "Octave:assign-as-truth-value");
+%! warning ("on", "Octave:assign-as-truth-value");
+%! fail("if (x = 1) 1; endif","warning");
+%! warning (watv.state, "Octave:assign-as-truth-value");
+
+%% test/octave.test/prefer/prefer-38.m
+%!test
+%! wdbz = warning ("query", "Octave:divide-by-zero");
+%! warning ("off", "Octave:divide-by-zero");
+%! assert(isinf (1/0));
+%! warning (wdbz.state, "Octave:divide-by-zero");
+
+%% test/octave.test/prefer/prefer-39.m
+%!test
+%! wdbz = warning ("query", "Octave:divide-by-zero");
+%! warning ("on", "Octave:divide-by-zero");
+%! a = 1;
+%! b = 0;
+%! fail("isinf (a/b);","warning")
+%! warning (wdbz.state, "Octave:divide-by-zero");
+
diff --git a/test/test_range.m b/test/test_range.m
new file mode 100644
index 0000000..bffeae4
--- /dev/null
+++ b/test/test_range.m
@@ -0,0 +1,74 @@
+## Copyright (C) 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## Test values of range
+
+%!assert(full(1:9), [ 1 2 3 4 5 6 7 8 9 ])
+%!assert(full(1:0.4:3), [ 1.0 1.4 1.8 2.2 2.6 3.0 ])
+%!assert(full(9:1), zeros(1,0))
+%!assert(full(9:-1:1), [ 9 8 7 6 5 4 3 2 1 ])
+%!assert(full(1:-1:9), zeros(1,0))
+
+
+## Test mixing integer range with other types
+
+%!shared expect, r, z
+%! expect = [ 1 2 3 4 5 6 7 8 9
+%!            0 0 0 0 0 0 0 0 0 ];
+%! z = zeros(1,9);
+%! r = 1:9;
+
+%!assert([ r ; z                  ], expect)
+%!assert([ r ; single(z)          ], single (expect))
+%!assert([ r ; logical(z)         ], expect)
+%!assert([ r ; sparse(z)          ], sparse (expect))
+%!assert([ r ; sparse(logical(z)) ], sparse (expect))
+
+%!assert([ r ; int8(z)            ], int8(expect))
+%!assert([ r ; int16(z)           ], int16(expect))
+%!assert([ r ; int32(z)           ], int32(expect))
+%!assert([ r ; int64(z)           ], int64(expect))
+%!assert([ r ; uint8(z)           ], uint8(expect))
+%!assert([ r ; uint16(z)          ], uint16(expect))
+%!assert([ r ; uint32(z)          ], uint32(expect))
+%!assert([ r ; uint64(z)          ], uint64(expect))
+
+
+## Test mixing non integer range with other types
+
+%!shared expect, r, z
+%! expect = [ 1.0 1.4 1.8 2.2 2.6 3.0
+%!            0   0   0   0   0   0   ];
+%! z = zeros(1,6);
+%! r = 1:0.4:3;
+
+%!assert([ r ; z                  ], expect)
+%!assert([ r ; single(z)          ], single (expect))
+%!assert([ r ; logical(z)         ], expect)
+%!assert([ r ; sparse(z)          ], sparse (expect))
+%!assert([ r ; sparse(logical(z)) ], sparse (expect))
+
+%!assert([ r ; int8(z)            ], int8(expect))
+%!assert([ r ; int16(z)           ], int16(expect))
+%!assert([ r ; int32(z)           ], int32(expect))
+%!assert([ r ; int64(z)           ], int64(expect))
+%!assert([ r ; uint8(z)           ], uint8(expect))
+%!assert([ r ; uint16(z)          ], uint16(expect))
+%!assert([ r ; uint32(z)          ], uint32(expect))
+%!assert([ r ; uint64(z)          ], uint64(expect))
+
diff --git a/test/test_recursion.m b/test/test_recursion.m
new file mode 100644
index 0000000..671ab33
--- /dev/null
+++ b/test/test_recursion.m
@@ -0,0 +1,40 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/recursion/recursion-1.m
+%!function y = f (x)
+%!  if (x == 1)
+%!    y = x;
+%!    return;
+%!  else
+%!    y = x * f (x-1);
+%!  endif
+%!test
+%! assert(f (5),120);
+
+%% test/octave.test/recursion/recursion-2.m
+%!function y = f (x)
+%!  if (x == 1)
+%!    y = x;
+%!    return;
+%!  else
+%!    y = f (x-1) * x;
+%!  endif
+%!test
+%! assert(f (5),120);
+
diff --git a/test/test_return.m b/test/test_return.m
new file mode 100644
index 0000000..b97202f
--- /dev/null
+++ b/test/test_return.m
@@ -0,0 +1,29 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/return/return-1.m
+%!function y = f ()
+%!  y = 1;
+%!  return
+%!  y = 2;
+%!assert(f(),1)
+
+%% test/octave.test/return/return-2.m
+%!test
+%! return;
+
diff --git a/test/test_slice.m b/test/test_slice.m
new file mode 100644
index 0000000..a5dec12
--- /dev/null
+++ b/test/test_slice.m
@@ -0,0 +1,180 @@
+## Copyright (C) 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%!function x = set_slice(size, dim, slice)
+%!  x = ones(size);
+%!  switch dim
+%!    case 11
+%!      x(slice) = 2;
+%!    case 21
+%!      x(slice, :) = 2;
+%!    case 22
+%!      x(:, slice) = 2;
+%!    case 31
+%!      x(slice, :, :) = 2;
+%!    case 32
+%!      x(:, slice, :) = 2;
+%!    case 33
+%!      x(:, :, slice) = 2;
+%!    otherwise
+%!      error("invalid dim, '%d'", dim);
+%!  endswitch
+%! endfunction
+
+## size = [2 0]
+%!assert(set_slice([2 0], 11, []), zeros([2 0]));
+%!error <resize: Invalid.*> set_slice([2 0], 11, 1)
+%!error <resize: Invalid.*> set_slice([2 0], 11, 2)
+%!error <resize: Invalid.*> set_slice([2 0], 11, 3)
+%!assert(set_slice([2 0], 21, []), zeros([2 0]));
+%!assert(set_slice([2 0], 21, 1), zeros([2 0]));
+%!assert(set_slice([2 0], 21, 2), zeros([2 0]));
+%!assert(set_slice([2 0], 21, 3), zeros([3 0]));
+%!assert(set_slice([2 0], 22, []), zeros([2 0]));
+%!assert(set_slice([2 0], 22, 1), [2 2]');
+%!assert(set_slice([2 0], 22, 2), [0 0;2 2]');
+%!assert(set_slice([2 0], 22, 3), [0 0;0 0;2 2]');
+%!assert(set_slice([2 0], 31, []), zeros([2 0]));
+%!assert(set_slice([2 0], 31, 1), zeros([2 0]));
+%!assert(set_slice([2 0], 31, 2), zeros([2 0]));
+%!assert(set_slice([2 0], 31, 3), zeros([3 0]));
+%!assert(set_slice([2 0], 32, []), zeros([2 0]));
+%!assert(set_slice([2 0], 32, 1), [2 2]');
+%!assert(set_slice([2 0], 32, 2), [0 0;2 2]');
+%!assert(set_slice([2 0], 32, 3), [0 0;0 0;2 2]');
+%!assert(set_slice([2 0], 33, []), zeros([2 0]));
+%!assert(set_slice([2 0], 33, 1), zeros([2 0]));
+%!assert(set_slice([2 0], 33, 2), zeros([2 0 2]));
+%!assert(set_slice([2 0], 33, 3), zeros([2 0 3]));
+
+## size = [0 2]
+%!assert(set_slice([0 2], 11, []), zeros([0 2]));
+%!assert(set_slice([0 2], 11, 1), 2);
+%!assert(set_slice([0 2], 11, 2), [0, 2]);
+%!assert(set_slice([0 2], 11, 3), [0, 0, 2]);
+%!assert(set_slice([0 2], 21, []), zeros([0 2]));
+%!assert(set_slice([0 2], 21, 1), [2 2]);
+%!assert(set_slice([0 2], 21, 2), [0 0;2 2]);
+%!assert(set_slice([0 2], 21, 3), [0 0;0 0;2 2]);
+%!assert(set_slice([0 2], 22, []), zeros([0 2]));
+%!assert(set_slice([0 2], 22, 1), zeros([0 2]));
+%!assert(set_slice([0 2], 22, 2), zeros([0 2]));
+%!assert(set_slice([0 2], 22, 3), zeros([0 3]));
+%!assert(set_slice([0 2], 31, []), zeros([0 2]));
+%!assert(set_slice([0 2], 31, 1), [2 2]);
+%!assert(set_slice([0 2], 31, 2), [0 0;2 2]);
+%!assert(set_slice([0 2], 31, 3), [0 0;0 0;2 2]);
+%!assert(set_slice([0 2], 32, []), zeros([0 2]));
+%!assert(set_slice([0 2], 32, 1), zeros([0 2]));
+%!assert(set_slice([0 2], 32, 2), zeros([0 2]));
+%!assert(set_slice([0 2], 32, 3), zeros([0 3]));
+%!assert(set_slice([0 2], 33, []), zeros([0 2]));
+%!assert(set_slice([0 2], 33, 1), zeros([0 2]));
+%!assert(set_slice([0 2], 33, 2), zeros([0 2 2]));
+%!assert(set_slice([0 2], 33, 3), zeros([0 2 3]));
+
+## size = [2 1]
+%!assert(set_slice([2 1], 11, []), ones([2 1]));
+%!assert(set_slice([2 1], 11, 1), [2 1]');
+%!assert(set_slice([2 1], 11, 2), [1 2]');
+%!assert(set_slice([2 1], 11, 3), [1 1 2]');
+%!assert(set_slice([2 1], 11, 4), [1 1 0 2]');
+%!assert(set_slice([2 1], 21, []), ones([2 1]));
+%!assert(set_slice([2 1], 21, 1), [2 1]');
+%!assert(set_slice([2 1], 21, 2), [1 2]');
+%!assert(set_slice([2 1], 21, 3), [1 1 2]');
+%!assert(set_slice([2 1], 21, 4), [1 1 0 2]');
+%!assert(set_slice([2 1], 22, []), ones([2 1]));
+%!assert(set_slice([2 1], 22, 1), [2 2]');
+%!assert(set_slice([2 1], 22, 2), [1 1;2 2]');
+%!assert(set_slice([2 1], 22, 3), [1 1;0 0;2 2]');
+%!assert(set_slice([2 1], 31, []), ones([2 1]));
+%!assert(set_slice([2 1], 31, 1), [2 1]');
+%!assert(set_slice([2 1], 31, 2), [1 2]');
+%!assert(set_slice([2 1], 31, 3), [1 1 2]');
+%!assert(set_slice([2 1], 31, 4), [1 1 0 2]');
+%!assert(set_slice([2 1], 32, []), ones([2 1]));
+%!assert(set_slice([2 1], 32, 1), [2 2]');
+%!assert(set_slice([2 1], 32, 2), [1 1;2 2]');
+%!assert(set_slice([2 1], 32, 3), [1 1;0 0;2 2]');
+%!assert(set_slice([2 1], 33, []), ones([2 1]));
+%!assert(set_slice([2 1], 33, 1), [2 2]');
+%!assert(set_slice([2 1], 33, 2), reshape([1 1 2 2],[2 1 2]));
+%!assert(set_slice([2 1], 33, 3), reshape([1 1 0 0 2 2],[2 1 3]));
+
+## size = [1 2]
+%!assert(set_slice([1 2], 11, []), full(ones([1 2])));
+%!assert(set_slice([1 2], 11, 1), [2 1]);
+%!assert(set_slice([1 2], 11, 2), [1 2]);
+%!assert(set_slice([1 2], 11, 3), [1 1 2]);
+%!assert(set_slice([1 2], 11, 4), [1 1 0 2]);
+%!assert(set_slice([1 2], 21, []), full(ones([1 2])));
+%!assert(set_slice([1 2], 21, 1), [2 2]);
+%!assert(set_slice([1 2], 21, 2), [1 1;2 2]);
+%!assert(set_slice([1 2], 21, 3), [1 1;0 0;2 2]);
+%!assert(set_slice([1 2], 22, []), full(ones([1 2])));
+%!assert(set_slice([1 2], 22, 1), [2 1]);
+%!assert(set_slice([1 2], 22, 2), [1 2]);
+%!assert(set_slice([1 2], 22, 3), [1 1 2]);
+%!assert(set_slice([1 2], 22, 4), [1 1 0 2]);
+%!assert(set_slice([1 2], 31, []), full(ones([1 2])));
+%!assert(set_slice([1 2], 31, 1), [2 2]);
+%!assert(set_slice([1 2], 31, 2), [1 1;2 2]);
+%!assert(set_slice([1 2], 31, 3), [1 1;0 0;2 2]);
+%!assert(set_slice([1 2], 32, []), full(ones([1 2])));
+%!assert(set_slice([1 2], 32, 1), [2 1]);
+%!assert(set_slice([1 2], 32, 2), [1 2]);
+%!assert(set_slice([1 2], 32, 3), [1 1 2]);
+%!assert(set_slice([1 2], 32, 4), [1 1 0 2]);
+%!assert(set_slice([1 2], 33, []), full(ones([1 2])));
+%!assert(set_slice([1 2], 33, 1), [2 2]);
+%!assert(set_slice([1 2], 33, 2), reshape([1 1 2 2],[1 2 2]));
+%!assert(set_slice([1 2], 33, 3), reshape([1 1 0 0 2 2],[1 2 3]));
+
+## size = [2 2]
+%!assert(set_slice([2 2], 11, []), ones([2 2]));
+%!assert(set_slice([2 2], 11, 1), [2 1;1 1]);
+%!assert(set_slice([2 2], 11, 2), [1 1;2 1]);
+%!assert(set_slice([2 2], 11, 3), [1 2;1 1]);
+%!assert(set_slice([2 2], 11, 4), [1 1;1 2]);
+%!error <resize: Invalid.*> set_slice([2 2], 11, 5)
+%!error <resize: Invalid.*> set_slice([2 2], 11, 6)
+%!assert(set_slice([2 2], 21, []), ones([2 2]));
+%!assert(set_slice([2 2], 21, 1), [2 2;1 1]);
+%!assert(set_slice([2 2], 21, 2), [1 1;2 2]);
+%!assert(set_slice([2 2], 21, 3), [1 1;1 1;2 2]);
+%!assert(set_slice([2 2], 21, 4), [1 1;1 1;0 0;2 2]);
+%!assert(set_slice([2 2], 22, []), ones([2 2]));
+%!assert(set_slice([2 2], 22, 1), [2 2;1 1]');
+%!assert(set_slice([2 2], 22, 2), [1 1;2 2]');
+%!assert(set_slice([2 2], 22, 3), [1 1;1 1;2 2]');
+%!assert(set_slice([2 2], 22, 4), [1 1;1 1;0 0;2 2]');
+%!assert(set_slice([2 2], 31, []), ones([2 2]));
+%!assert(set_slice([2 2], 31, 1), [2 2;1 1]);
+%!assert(set_slice([2 2], 31, 2), [1 1;2 2]);
+%!assert(set_slice([2 2], 31, 3), [1 1;1 1;2 2]);
+%!assert(set_slice([2 2], 31, 4), [1 1;1 1;0 0;2 2]);
+%!assert(set_slice([2 2], 32, []), ones([2 2]));
+%!assert(set_slice([2 2], 32, 1), [2 2;1 1]');
+%!assert(set_slice([2 2], 32, 2), [1 1;2 2]');
+%!assert(set_slice([2 2], 32, 3), [1 1;1 1;2 2]');
+%!assert(set_slice([2 2], 32, 4), [1 1;1 1;0 0;2 2]');
+%!assert(set_slice([2 2], 33, []), ones([2 2]));
+%!assert(set_slice([2 2], 33, 1), [2 2;2 2]);
+%!assert(set_slice([2 2], 33, 2), reshape([1 1 1 1 2 2 2 2],[2 2 2]));
+%!assert(set_slice([2 2], 33, 3), reshape([1 1 1 1 0 0 0 0 2 2 2 2],[2 2 3]));
diff --git a/test/test_sparse.m b/test/test_sparse.m
new file mode 100644
index 0000000..ef46749
--- /dev/null
+++ b/test/test_sparse.m
@@ -0,0 +1,3070 @@
+## THIS IS AN AUTOMATICALLY GENERATED FILE --- DO NOT EDIT ---
+## instead modify build_sparse_tests.sh to generate the tests that you want.
+##
+## test_sparse
+##
+##    run preset sparse tests.  All should pass.
+function [passes,tests] = test_sparse
+  disp("writing test output to sptest.log");
+  test("test_sparse","normal","sptest.log");
+endfunction
+
+
+# ==============================================================
+
+
+# ==============================================================
+
+
+%!test # segfault test from edd at debian.org
+%! n = 510;
+%! sparse(kron((1:n)', ones(n,1)), kron(ones(n,1), (1:n)'), ones(n)); 
+
+%% segfault tests from Fabian at isas-berlin.de
+%% Note that the last four do not fail, but rather give a warning
+%% of a singular matrix, which is consistent with the full matrix
+%% behaviour. They are therefore disabled.. 
+%!testif HAVE_UMFPACK
+%! assert(inv(sparse([1,1;1,1+i])),sparse([1-1i,1i;1i,-1i]),10*eps);
+% !error inv( sparse( [1,1;1,1]   ) );
+% !error inv( sparse( [0,0;0,1]   ) );
+% !error inv( sparse( [0,0;0,1+i] ) );
+% !error inv( sparse( [0,0;0,0]   ) );
+
+%% error handling in constructor
+%!error sparse(1,[2,3],[1,2,3]);
+%!error sparse([1,1],[1,1],[1,2],3,3,"bogus");
+%!error sparse([1,3],[1,-4],[3,5],2,2);
+%!error sparse([1,3],[1,-4],[3,5i],2,2);
+%!error sparse(-1,-1,1);
+
+# ==============================================================
+
+%!shared bf
+%!test bf=realmin;
+%% Make sure newly introduced zeros get eaten
+%!assert(nnz(sparse([bf,bf,1]).^realmax),1);
+%!assert(nnz(sparse([1,bf,bf]).^realmax),1);
+%!assert(nnz(sparse([bf,bf,bf]).^realmax),0); 
+
+%!assert(nnz(sparse([bf;bf;1]).^realmax),1);
+%!assert(nnz(sparse([1;bf;bf]).^realmax),1);
+%!assert(nnz(sparse([0.5;bf;bf]).^realmax),0);
+
+%!assert(nnz(sparse([bf,bf,1])*realmin),1);
+%!assert(nnz(sparse([1,bf,bf])*realmin),1);
+%!assert(nnz(sparse([bf,bf,bf])*realmin),0);
+
+%!assert(nnz(sparse([bf;bf;1])*realmin),1);
+%!assert(nnz(sparse([1;bf;bf])*realmin),1);
+%!assert(nnz(sparse([bf;bf;bf])*realmin),0);
+
+%!test bf=realmin+realmin*1i;
+%% Make sure newly introduced zeros get eaten
+%!assert(nnz(sparse([bf,bf,1]).^realmax),1);
+%!assert(nnz(sparse([1,bf,bf]).^realmax),1);
+%!assert(nnz(sparse([bf,bf,bf]).^realmax),0); 
+
+%!assert(nnz(sparse([bf;bf;1]).^realmax),1);
+%!assert(nnz(sparse([1;bf;bf]).^realmax),1);
+%!assert(nnz(sparse([0.5;bf;bf]).^realmax),0);
+
+%!assert(nnz(sparse([bf,bf,1])*realmin),1);
+%!assert(nnz(sparse([1,bf,bf])*realmin),1);
+%!assert(nnz(sparse([bf,bf,bf])*realmin),0);
+
+%!assert(nnz(sparse([bf;bf;1])*realmin),1);
+%!assert(nnz(sparse([1;bf;bf])*realmin),1);
+%!assert(nnz(sparse([bf;bf;bf])*realmin),0);
+
+%!assert(nnz(sparse([-1,realmin,realmin]).^1.5),1);
+%!assert(nnz(sparse([-1,realmin,realmin,1]).^1.5),2);
+
+%!assert(nnz(sparse(1,1,0)),0); # Make sure scalar v==0 doesn't confuse matters
+%!assert(nnz(sparse(eye(3))*0),0);
+%!assert(nnz(sparse(eye(3))-sparse(eye(3))),0);
+
+%!test
+%! wdbz = warning ("query", "Octave:divide-by-zero");
+%! warning ("off", "Octave:divide-by-zero");
+%! assert(full(sparse(eye(3))/0),full(eye(3)/0));
+%! warning (wdbz.state, "Octave:divide-by-zero");
+
+
+# ==============================================================
+
+%!shared as,af,bs,bf
+%!test af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];
+%!test bf=3;
+%!test as=sparse(af);
+%!test bs=bf;
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%% real values can be ordered (uses as,af)
+%!assert(as<=bf,sparse(af<=bf))
+%!assert(bf<=as,sparse(bf<=af))
+
+%!assert(as>=bf,sparse(af>=bf))
+%!assert(bf>=as,sparse(bf>=af))
+
+%!assert(as<bf,sparse(af<bf))
+%!assert(bf<as,sparse(bf<af))
+
+%!assert(as>bf,sparse(af>bf))
+%!assert(bf>as,sparse(bf>af))
+
+%!test bf=bf+1i;
+%!test bs=bf;
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+
+# ==============================================================
+
+%!test af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];
+%!test bf=[0,1-1i,0,0;2+1i,0,0,0;3-1i,2+3i,0,0];
+%!test as=sparse(af);
+%!test bs=sparse(bf);
+%% Unary matrix tests (uses af,as)
+%!assert(abs(as),sparse(abs(af)))
+%!assert(acos(as),sparse(acos(af)))
+%!assert(acosh(as),sparse(acosh(af)))
+%!assert(angle(as),sparse(angle(af)))
+%!assert(arg(as),sparse(arg(af)))
+%!assert(asin(as),sparse(asin(af)))
+%!assert(asinh(as),sparse(asinh(af)))
+%!assert(atan(as),sparse(atan(af)))
+%!assert(atanh(as),sparse(atanh(af)))
+%!assert(ceil(as),sparse(ceil(af)))
+%!assert(conj(as),sparse(conj(af)))
+%!assert(cos(as),sparse(cos(af)))
+%!assert(cosh(as),sparse(cosh(af)))
+%!assert(exp(as),sparse(exp(af)))
+%!assert(finite(as),sparse(finite(af)))
+%!assert(fix(as),sparse(fix(af)))
+%!assert(floor(as),sparse(floor(af)))
+%!assert(imag(as),sparse(imag(af)))
+%!assert(isinf(as),sparse(isinf(af)))
+%!assert(isna(as),sparse(isna(af)))
+%!assert(isnan(as),sparse(isnan(af)))
+%!assert(log(as),sparse(log(af)))
+%!assert(real(as),sparse(real(af)))
+%!assert(round(as),sparse(round(af)))
+%!assert(sign(as),sparse(sign(af)))
+%!assert(sin(as),sparse(sin(af)))
+%!assert(sinh(as),sparse(sinh(af)))
+%!assert(sqrt(as),sparse(sqrt(af)))
+%!assert(tan(as),sparse(tan(af)))
+%!assert(tanh(as),sparse(tanh(af)))
+%!assert(issparse(abs(as))&&isreal(abs(as)))
+%!assert(issparse(real(as))&&isreal(real(as)))
+%!assert(issparse(imag(as))&&isreal(imag(as)))
+
+%% Unary matrix tests (uses af,as)
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erf(as),sparse(erf(af)))
+%!   else
+%!     assert(erf(as),erf(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erfc(as),sparse(erfc(af)))
+%!   else
+%!     assert(erfc(as),erfc(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalnum(as),sparse(isalnum(af)))
+%!   else
+%!     assert(isalnum(as),isalnum(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalpha(as),sparse(isalpha(af)))
+%!   else
+%!     assert(isalpha(as),isalpha(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isascii(as),sparse(isascii(af)))
+%!   else
+%!     assert(isascii(as),isascii(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(iscntrl(as),sparse(iscntrl(af)))
+%!   else
+%!     assert(iscntrl(as),iscntrl(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isdigit(as),sparse(isdigit(af)))
+%!   else
+%!     assert(isdigit(as),isdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isgraph(as),sparse(isgraph(af)))
+%!   else
+%!     assert(isgraph(as),isgraph(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(islower(as),sparse(islower(af)))
+%!   else
+%!     assert(islower(as),islower(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isprint(as),sparse(isprint(af)))
+%!   else
+%!     assert(isprint(as),isprint(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(ispunct(as),sparse(ispunct(af)))
+%!   else
+%!     assert(ispunct(as),ispunct(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isspace(as),sparse(isspace(af)))
+%!   else
+%!     assert(isspace(as),isspace(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isupper(as),sparse(isupper(af)))
+%!   else
+%!     assert(isupper(as),isupper(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isxdigit(as),sparse(isxdigit(af)))
+%!   else
+%!     assert(isxdigit(as),isxdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+
+%% These mapper functions always return a full matrix
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!    assert(toascii(as),toascii(af))
+%!    assert(tolower(as),tolower(af))
+%!    assert(toupper(as),toupper(af))
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%% Unary matrix tests (uses af,as)
+%!assert(issparse(as))
+%!assert(!issparse(af))
+%!assert(!(issparse(af)&&iscomplex(af)))
+%!assert(!(issparse(af)&&isreal(af)))
+%!assert(sum(as),sparse(sum(af)))
+%!assert(sum(as,1),sparse(sum(af,1)))
+%!assert(sum(as,2),sparse(sum(af,2)))
+%!assert(cumsum(as),sparse(cumsum(af)))
+%!assert(cumsum(as,1),sparse(cumsum(af,1)))
+%!assert(cumsum(as,2),sparse(cumsum(af,2)))
+%!assert(sumsq(as),sparse(sumsq(af)))
+%!assert(sumsq(as,1),sparse(sumsq(af,1)))
+%!assert(sumsq(as,2),sparse(sumsq(af,2)))
+%!assert(prod(as),sparse(prod(af)))
+%!assert(prod(as,1),sparse(prod(af,1)))
+%!assert(prod(as,2),sparse(prod(af,2)))
+%!assert(cumprod(as),sparse(cumprod(af)))
+%!assert(cumprod(as,1),sparse(cumprod(af,1)))
+%!assert(cumprod(as,2),sparse(cumprod(af,2)))
+
+%!assert(min(as),sparse(min(af)))
+%!assert(full(min(as(:))),min(af(:)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,[],2),sparse(min(af,[],2)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,0),sparse(min(af,0)))
+%!assert(min(as,bs),sparse(min(af,bf)))
+%!assert(max(as),sparse(max(af)))
+%!assert(full(max(as(:))),max(af(:)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,[],2),sparse(max(af,[],2)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,0),sparse(max(af,0)))
+%!assert(max(as,bs),sparse(max(af,bf)))
+
+%!assert(as==as)
+%!assert(as==af)
+%!assert(af==as)
+%!test
+%! [ii,jj,vv,nr,nc] = find(as);
+%! assert(af,full(sparse(ii,jj,vv,nr,nc)));
+%!assert(nnz(as),sum(af(:)!=0))
+%!assert(nnz(as),nnz(af))
+%!assert(issparse(as.'))
+%!assert(issparse(as'))
+%!assert(issparse(-as))
+%!assert(~as,sparse(~af))
+%!assert(as.', sparse(af.'));
+%!assert(as',  sparse(af'));
+%!assert(-as, sparse(-af));
+%!assert(~as, sparse(~af));
+%!error [i,j]=size(af);as(i-1,j+1);
+%!error [i,j]=size(af);as(i+1,j-1);
+%!test
+%! [Is,Js,Vs] = find(as);
+%! [If,Jf,Vf] = find(af);
+%! assert(Is,If);
+%! assert(Js,Jf);
+%! assert(Vs,Vf);
+%!error as(0,1);
+%!error as(1,0);
+%!assert(find(as),find(af))
+%!test
+%! [i,j,v] = find(as);
+%! [m,n] = size(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!test
+%! [i,j,v,m,n] = find(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!assert(issparse(horzcat(as,as)));
+%!assert(issparse(vertcat(as,as)));
+%!assert(issparse(cat(1,as,as)));
+%!assert(issparse(cat(2,as,as)));
+%!assert(issparse([as,as]));
+%!assert(issparse([as;as]));
+%!assert(horzcat(as,as), sparse([af,af]));
+%!assert(vertcat(as,as), sparse([af;af]));
+%!assert(horzcat(as,as,as), sparse([af,af,af]));
+%!assert(vertcat(as,as,as), sparse([af;af;af]));
+%!assert([as,as], sparse([af,af]));
+%!assert([as;as], sparse([af;af]));
+%!assert([as,as,as], sparse([af,af,af]));
+%!assert([as;as;as], sparse([af;af;af]));
+%!assert(cat(2,as,as), sparse([af,af]));
+%!assert(cat(1,as,as), sparse([af;af]));
+%!assert(cat(2,as,as,as), sparse([af,af,af]));
+%!assert(cat(1,as,as,as), sparse([af;af;af]));
+%!assert(issparse([as,af]));
+%!assert(issparse([af,as]));
+%!assert([as,af], sparse([af,af]));
+%!assert([as;af], sparse([af;af]));
+
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%!assert(as==bs,sparse(af==bf))
+%!assert(as!=bs,sparse(af!=bf))
+%!assert(as+bs,sparse(af+bf))
+%!assert(as-bs,sparse(af-bf))
+%!assert(as.*bs,sparse(af.*bf))
+%!xtest assert(as./bs,sparse(af./bf),100*eps);
+%!test
+%! sv = as.^bs;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as*bf',af*bf')
+%!assert(af*bs',af*bf')
+%!assert(as*bs',sparse(af*bf'))
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(diag(as),sparse(diag(af)))
+%!assert(diag(bs),sparse(diag(bf)))
+%!assert(diag(as,1),sparse(diag(af,1)))
+%!assert(diag(bs,1),sparse(diag(bf,1)))
+%!assert(diag(as,-1),sparse(diag(af,-1)))
+%!assert(diag(bs,-1),sparse(diag(bf,-1)))
+%!assert(diag(as(:)),sparse(diag(af(:))))
+%!assert(diag(as(:),1),sparse(diag(af(:),1)))
+%!assert(diag(as(:),-1),sparse(diag(af(:),-1)))
+%!assert(diag(as(:)'),sparse(diag(af(:)')))
+%!assert(diag(as(:)',1),sparse(diag(af(:)',1)))
+%!assert(diag(as(:)',-1),sparse(diag(af(:)',-1)))
+%!assert(spdiags(as,[0,1]),[diag(af,0),diag(af,1)])
+%!test [tb,tc]=spdiags(as); 
+%! assert(spdiags(tb,tc,sparse(zeros(size(as)))),as)
+%! assert(spdiags(tb,tc,size(as,1),size(as,2)),as)
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(reshape(as,1,prod(size(as))),sparse(reshape(af,1,prod(size(af)))))
+%!assert(reshape(as,prod(size(as)),1),sparse(reshape(af,prod(size(af)),1)))
+%!assert(reshape(as,fliplr(size(as))),sparse(reshape(af,fliplr(size(af)))))
+%!assert(reshape(bs,1,prod(size(as))),sparse(reshape(bf,1,prod(size(af)))))
+%!assert(reshape(bs,prod(size(as)),1),sparse(reshape(bf,prod(size(af)),1)))
+%!assert(reshape(bs,fliplr(size(as))),sparse(reshape(bf,fliplr(size(af)))))
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+
+# ==============================================================
+
+%!test # save ascii
+%! savefile= tmpnam();
+%! as_save=as; save("-text",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+%!test # save binary
+%! savefile= tmpnam();
+%! as_save=as; save("-binary",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+%!testif HAVE_HDF5 # save hdf5
+%! savefile= tmpnam();
+%! as_save=as; save("-hdf5",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+## FIXME -- we should skip (or mark as an expected failure) the test for
+## saving sparse matrices to MAT files when using 64-bit indexing since
+## that is not implemented yet.
+%!test # save matlab
+%! savefile= tmpnam();
+%! as_save=as; save("-mat",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+
+# ==============================================================
+
+%!test bf=real(bf);
+%!test as=sparse(af);
+%!test bs=sparse(bf);
+%% Unary matrix tests (uses af,as)
+%!assert(abs(as),sparse(abs(af)))
+%!assert(acos(as),sparse(acos(af)))
+%!assert(acosh(as),sparse(acosh(af)))
+%!assert(angle(as),sparse(angle(af)))
+%!assert(arg(as),sparse(arg(af)))
+%!assert(asin(as),sparse(asin(af)))
+%!assert(asinh(as),sparse(asinh(af)))
+%!assert(atan(as),sparse(atan(af)))
+%!assert(atanh(as),sparse(atanh(af)))
+%!assert(ceil(as),sparse(ceil(af)))
+%!assert(conj(as),sparse(conj(af)))
+%!assert(cos(as),sparse(cos(af)))
+%!assert(cosh(as),sparse(cosh(af)))
+%!assert(exp(as),sparse(exp(af)))
+%!assert(finite(as),sparse(finite(af)))
+%!assert(fix(as),sparse(fix(af)))
+%!assert(floor(as),sparse(floor(af)))
+%!assert(imag(as),sparse(imag(af)))
+%!assert(isinf(as),sparse(isinf(af)))
+%!assert(isna(as),sparse(isna(af)))
+%!assert(isnan(as),sparse(isnan(af)))
+%!assert(log(as),sparse(log(af)))
+%!assert(real(as),sparse(real(af)))
+%!assert(round(as),sparse(round(af)))
+%!assert(sign(as),sparse(sign(af)))
+%!assert(sin(as),sparse(sin(af)))
+%!assert(sinh(as),sparse(sinh(af)))
+%!assert(sqrt(as),sparse(sqrt(af)))
+%!assert(tan(as),sparse(tan(af)))
+%!assert(tanh(as),sparse(tanh(af)))
+%!assert(issparse(abs(as))&&isreal(abs(as)))
+%!assert(issparse(real(as))&&isreal(real(as)))
+%!assert(issparse(imag(as))&&isreal(imag(as)))
+
+%% Unary matrix tests (uses af,as)
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erf(as),sparse(erf(af)))
+%!   else
+%!     assert(erf(as),erf(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erfc(as),sparse(erfc(af)))
+%!   else
+%!     assert(erfc(as),erfc(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalnum(as),sparse(isalnum(af)))
+%!   else
+%!     assert(isalnum(as),isalnum(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalpha(as),sparse(isalpha(af)))
+%!   else
+%!     assert(isalpha(as),isalpha(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isascii(as),sparse(isascii(af)))
+%!   else
+%!     assert(isascii(as),isascii(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(iscntrl(as),sparse(iscntrl(af)))
+%!   else
+%!     assert(iscntrl(as),iscntrl(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isdigit(as),sparse(isdigit(af)))
+%!   else
+%!     assert(isdigit(as),isdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isgraph(as),sparse(isgraph(af)))
+%!   else
+%!     assert(isgraph(as),isgraph(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(islower(as),sparse(islower(af)))
+%!   else
+%!     assert(islower(as),islower(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isprint(as),sparse(isprint(af)))
+%!   else
+%!     assert(isprint(as),isprint(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(ispunct(as),sparse(ispunct(af)))
+%!   else
+%!     assert(ispunct(as),ispunct(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isspace(as),sparse(isspace(af)))
+%!   else
+%!     assert(isspace(as),isspace(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isupper(as),sparse(isupper(af)))
+%!   else
+%!     assert(isupper(as),isupper(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isxdigit(as),sparse(isxdigit(af)))
+%!   else
+%!     assert(isxdigit(as),isxdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+
+%% These mapper functions always return a full matrix
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!    assert(toascii(as),toascii(af))
+%!    assert(tolower(as),tolower(af))
+%!    assert(toupper(as),toupper(af))
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%% Unary matrix tests (uses af,as)
+%!assert(issparse(as))
+%!assert(!issparse(af))
+%!assert(!(issparse(af)&&iscomplex(af)))
+%!assert(!(issparse(af)&&isreal(af)))
+%!assert(sum(as),sparse(sum(af)))
+%!assert(sum(as,1),sparse(sum(af,1)))
+%!assert(sum(as,2),sparse(sum(af,2)))
+%!assert(cumsum(as),sparse(cumsum(af)))
+%!assert(cumsum(as,1),sparse(cumsum(af,1)))
+%!assert(cumsum(as,2),sparse(cumsum(af,2)))
+%!assert(sumsq(as),sparse(sumsq(af)))
+%!assert(sumsq(as,1),sparse(sumsq(af,1)))
+%!assert(sumsq(as,2),sparse(sumsq(af,2)))
+%!assert(prod(as),sparse(prod(af)))
+%!assert(prod(as,1),sparse(prod(af,1)))
+%!assert(prod(as,2),sparse(prod(af,2)))
+%!assert(cumprod(as),sparse(cumprod(af)))
+%!assert(cumprod(as,1),sparse(cumprod(af,1)))
+%!assert(cumprod(as,2),sparse(cumprod(af,2)))
+
+%!assert(min(as),sparse(min(af)))
+%!assert(full(min(as(:))),min(af(:)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,[],2),sparse(min(af,[],2)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,0),sparse(min(af,0)))
+%!assert(min(as,bs),sparse(min(af,bf)))
+%!assert(max(as),sparse(max(af)))
+%!assert(full(max(as(:))),max(af(:)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,[],2),sparse(max(af,[],2)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,0),sparse(max(af,0)))
+%!assert(max(as,bs),sparse(max(af,bf)))
+
+%!assert(as==as)
+%!assert(as==af)
+%!assert(af==as)
+%!test
+%! [ii,jj,vv,nr,nc] = find(as);
+%! assert(af,full(sparse(ii,jj,vv,nr,nc)));
+%!assert(nnz(as),sum(af(:)!=0))
+%!assert(nnz(as),nnz(af))
+%!assert(issparse(as.'))
+%!assert(issparse(as'))
+%!assert(issparse(-as))
+%!assert(~as,sparse(~af))
+%!assert(as.', sparse(af.'));
+%!assert(as',  sparse(af'));
+%!assert(-as, sparse(-af));
+%!assert(~as, sparse(~af));
+%!error [i,j]=size(af);as(i-1,j+1);
+%!error [i,j]=size(af);as(i+1,j-1);
+%!test
+%! [Is,Js,Vs] = find(as);
+%! [If,Jf,Vf] = find(af);
+%! assert(Is,If);
+%! assert(Js,Jf);
+%! assert(Vs,Vf);
+%!error as(0,1);
+%!error as(1,0);
+%!assert(find(as),find(af))
+%!test
+%! [i,j,v] = find(as);
+%! [m,n] = size(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!test
+%! [i,j,v,m,n] = find(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!assert(issparse(horzcat(as,as)));
+%!assert(issparse(vertcat(as,as)));
+%!assert(issparse(cat(1,as,as)));
+%!assert(issparse(cat(2,as,as)));
+%!assert(issparse([as,as]));
+%!assert(issparse([as;as]));
+%!assert(horzcat(as,as), sparse([af,af]));
+%!assert(vertcat(as,as), sparse([af;af]));
+%!assert(horzcat(as,as,as), sparse([af,af,af]));
+%!assert(vertcat(as,as,as), sparse([af;af;af]));
+%!assert([as,as], sparse([af,af]));
+%!assert([as;as], sparse([af;af]));
+%!assert([as,as,as], sparse([af,af,af]));
+%!assert([as;as;as], sparse([af;af;af]));
+%!assert(cat(2,as,as), sparse([af,af]));
+%!assert(cat(1,as,as), sparse([af;af]));
+%!assert(cat(2,as,as,as), sparse([af,af,af]));
+%!assert(cat(1,as,as,as), sparse([af;af;af]));
+%!assert(issparse([as,af]));
+%!assert(issparse([af,as]));
+%!assert([as,af], sparse([af,af]));
+%!assert([as;af], sparse([af;af]));
+
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%!assert(as==bs,sparse(af==bf))
+%!assert(as!=bs,sparse(af!=bf))
+%!assert(as+bs,sparse(af+bf))
+%!assert(as-bs,sparse(af-bf))
+%!assert(as.*bs,sparse(af.*bf))
+%!xtest assert(as./bs,sparse(af./bf),100*eps);
+%!test
+%! sv = as.^bs;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as*bf',af*bf')
+%!assert(af*bs',af*bf')
+%!assert(as*bs',sparse(af*bf'))
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(diag(as),sparse(diag(af)))
+%!assert(diag(bs),sparse(diag(bf)))
+%!assert(diag(as,1),sparse(diag(af,1)))
+%!assert(diag(bs,1),sparse(diag(bf,1)))
+%!assert(diag(as,-1),sparse(diag(af,-1)))
+%!assert(diag(bs,-1),sparse(diag(bf,-1)))
+%!assert(diag(as(:)),sparse(diag(af(:))))
+%!assert(diag(as(:),1),sparse(diag(af(:),1)))
+%!assert(diag(as(:),-1),sparse(diag(af(:),-1)))
+%!assert(diag(as(:)'),sparse(diag(af(:)')))
+%!assert(diag(as(:)',1),sparse(diag(af(:)',1)))
+%!assert(diag(as(:)',-1),sparse(diag(af(:)',-1)))
+%!assert(spdiags(as,[0,1]),[diag(af,0),diag(af,1)])
+%!test [tb,tc]=spdiags(as); 
+%! assert(spdiags(tb,tc,sparse(zeros(size(as)))),as)
+%! assert(spdiags(tb,tc,size(as,1),size(as,2)),as)
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(reshape(as,1,prod(size(as))),sparse(reshape(af,1,prod(size(af)))))
+%!assert(reshape(as,prod(size(as)),1),sparse(reshape(af,prod(size(af)),1)))
+%!assert(reshape(as,fliplr(size(as))),sparse(reshape(af,fliplr(size(af)))))
+%!assert(reshape(bs,1,prod(size(as))),sparse(reshape(bf,1,prod(size(af)))))
+%!assert(reshape(bs,prod(size(as)),1),sparse(reshape(bf,prod(size(af)),1)))
+%!assert(reshape(bs,fliplr(size(as))),sparse(reshape(bf,fliplr(size(af)))))
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+
+# ==============================================================
+
+%!assert(as<=bs,sparse(af<=bf))
+%!assert(as>=bs,sparse(af>=bf))
+%!assert(as<bs,sparse(af<bf))
+%!assert(as>bs,sparse(af>bf))
+
+# ==============================================================
+
+%!test af=real(af);
+%!test as=sparse(af);
+%!test bs=sparse(bf);
+%% Unary matrix tests (uses af,as)
+%!assert(abs(as),sparse(abs(af)))
+%!assert(acos(as),sparse(acos(af)))
+%!assert(acosh(as),sparse(acosh(af)))
+%!assert(angle(as),sparse(angle(af)))
+%!assert(arg(as),sparse(arg(af)))
+%!assert(asin(as),sparse(asin(af)))
+%!assert(asinh(as),sparse(asinh(af)))
+%!assert(atan(as),sparse(atan(af)))
+%!assert(atanh(as),sparse(atanh(af)))
+%!assert(ceil(as),sparse(ceil(af)))
+%!assert(conj(as),sparse(conj(af)))
+%!assert(cos(as),sparse(cos(af)))
+%!assert(cosh(as),sparse(cosh(af)))
+%!assert(exp(as),sparse(exp(af)))
+%!assert(finite(as),sparse(finite(af)))
+%!assert(fix(as),sparse(fix(af)))
+%!assert(floor(as),sparse(floor(af)))
+%!assert(imag(as),sparse(imag(af)))
+%!assert(isinf(as),sparse(isinf(af)))
+%!assert(isna(as),sparse(isna(af)))
+%!assert(isnan(as),sparse(isnan(af)))
+%!assert(log(as),sparse(log(af)))
+%!assert(real(as),sparse(real(af)))
+%!assert(round(as),sparse(round(af)))
+%!assert(sign(as),sparse(sign(af)))
+%!assert(sin(as),sparse(sin(af)))
+%!assert(sinh(as),sparse(sinh(af)))
+%!assert(sqrt(as),sparse(sqrt(af)))
+%!assert(tan(as),sparse(tan(af)))
+%!assert(tanh(as),sparse(tanh(af)))
+%!assert(issparse(abs(as))&&isreal(abs(as)))
+%!assert(issparse(real(as))&&isreal(real(as)))
+%!assert(issparse(imag(as))&&isreal(imag(as)))
+
+%% Unary matrix tests (uses af,as)
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erf(as),sparse(erf(af)))
+%!   else
+%!     assert(erf(as),erf(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erfc(as),sparse(erfc(af)))
+%!   else
+%!     assert(erfc(as),erfc(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalnum(as),sparse(isalnum(af)))
+%!   else
+%!     assert(isalnum(as),isalnum(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalpha(as),sparse(isalpha(af)))
+%!   else
+%!     assert(isalpha(as),isalpha(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isascii(as),sparse(isascii(af)))
+%!   else
+%!     assert(isascii(as),isascii(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(iscntrl(as),sparse(iscntrl(af)))
+%!   else
+%!     assert(iscntrl(as),iscntrl(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isdigit(as),sparse(isdigit(af)))
+%!   else
+%!     assert(isdigit(as),isdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isgraph(as),sparse(isgraph(af)))
+%!   else
+%!     assert(isgraph(as),isgraph(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(islower(as),sparse(islower(af)))
+%!   else
+%!     assert(islower(as),islower(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isprint(as),sparse(isprint(af)))
+%!   else
+%!     assert(isprint(as),isprint(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(ispunct(as),sparse(ispunct(af)))
+%!   else
+%!     assert(ispunct(as),ispunct(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isspace(as),sparse(isspace(af)))
+%!   else
+%!     assert(isspace(as),isspace(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isupper(as),sparse(isupper(af)))
+%!   else
+%!     assert(isupper(as),isupper(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isxdigit(as),sparse(isxdigit(af)))
+%!   else
+%!     assert(isxdigit(as),isxdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+
+%% These mapper functions always return a full matrix
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!    assert(toascii(as),toascii(af))
+%!    assert(tolower(as),tolower(af))
+%!    assert(toupper(as),toupper(af))
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%% Unary matrix tests (uses af,as)
+%!assert(issparse(as))
+%!assert(!issparse(af))
+%!assert(!(issparse(af)&&iscomplex(af)))
+%!assert(!(issparse(af)&&isreal(af)))
+%!assert(sum(as),sparse(sum(af)))
+%!assert(sum(as,1),sparse(sum(af,1)))
+%!assert(sum(as,2),sparse(sum(af,2)))
+%!assert(cumsum(as),sparse(cumsum(af)))
+%!assert(cumsum(as,1),sparse(cumsum(af,1)))
+%!assert(cumsum(as,2),sparse(cumsum(af,2)))
+%!assert(sumsq(as),sparse(sumsq(af)))
+%!assert(sumsq(as,1),sparse(sumsq(af,1)))
+%!assert(sumsq(as,2),sparse(sumsq(af,2)))
+%!assert(prod(as),sparse(prod(af)))
+%!assert(prod(as,1),sparse(prod(af,1)))
+%!assert(prod(as,2),sparse(prod(af,2)))
+%!assert(cumprod(as),sparse(cumprod(af)))
+%!assert(cumprod(as,1),sparse(cumprod(af,1)))
+%!assert(cumprod(as,2),sparse(cumprod(af,2)))
+
+%!assert(min(as),sparse(min(af)))
+%!assert(full(min(as(:))),min(af(:)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,[],2),sparse(min(af,[],2)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,0),sparse(min(af,0)))
+%!assert(min(as,bs),sparse(min(af,bf)))
+%!assert(max(as),sparse(max(af)))
+%!assert(full(max(as(:))),max(af(:)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,[],2),sparse(max(af,[],2)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,0),sparse(max(af,0)))
+%!assert(max(as,bs),sparse(max(af,bf)))
+
+%!assert(as==as)
+%!assert(as==af)
+%!assert(af==as)
+%!test
+%! [ii,jj,vv,nr,nc] = find(as);
+%! assert(af,full(sparse(ii,jj,vv,nr,nc)));
+%!assert(nnz(as),sum(af(:)!=0))
+%!assert(nnz(as),nnz(af))
+%!assert(issparse(as.'))
+%!assert(issparse(as'))
+%!assert(issparse(-as))
+%!assert(~as,sparse(~af))
+%!assert(as.', sparse(af.'));
+%!assert(as',  sparse(af'));
+%!assert(-as, sparse(-af));
+%!assert(~as, sparse(~af));
+%!error [i,j]=size(af);as(i-1,j+1);
+%!error [i,j]=size(af);as(i+1,j-1);
+%!test
+%! [Is,Js,Vs] = find(as);
+%! [If,Jf,Vf] = find(af);
+%! assert(Is,If);
+%! assert(Js,Jf);
+%! assert(Vs,Vf);
+%!error as(0,1);
+%!error as(1,0);
+%!assert(find(as),find(af))
+%!test
+%! [i,j,v] = find(as);
+%! [m,n] = size(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!test
+%! [i,j,v,m,n] = find(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!assert(issparse(horzcat(as,as)));
+%!assert(issparse(vertcat(as,as)));
+%!assert(issparse(cat(1,as,as)));
+%!assert(issparse(cat(2,as,as)));
+%!assert(issparse([as,as]));
+%!assert(issparse([as;as]));
+%!assert(horzcat(as,as), sparse([af,af]));
+%!assert(vertcat(as,as), sparse([af;af]));
+%!assert(horzcat(as,as,as), sparse([af,af,af]));
+%!assert(vertcat(as,as,as), sparse([af;af;af]));
+%!assert([as,as], sparse([af,af]));
+%!assert([as;as], sparse([af;af]));
+%!assert([as,as,as], sparse([af,af,af]));
+%!assert([as;as;as], sparse([af;af;af]));
+%!assert(cat(2,as,as), sparse([af,af]));
+%!assert(cat(1,as,as), sparse([af;af]));
+%!assert(cat(2,as,as,as), sparse([af,af,af]));
+%!assert(cat(1,as,as,as), sparse([af;af;af]));
+%!assert(issparse([as,af]));
+%!assert(issparse([af,as]));
+%!assert([as,af], sparse([af,af]));
+%!assert([as;af], sparse([af;af]));
+
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%!assert(as==bs,sparse(af==bf))
+%!assert(as!=bs,sparse(af!=bf))
+%!assert(as+bs,sparse(af+bf))
+%!assert(as-bs,sparse(af-bf))
+%!assert(as.*bs,sparse(af.*bf))
+%!xtest assert(as./bs,sparse(af./bf),100*eps);
+%!test
+%! sv = as.^bs;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as*bf',af*bf')
+%!assert(af*bs',af*bf')
+%!assert(as*bs',sparse(af*bf'))
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(diag(as),sparse(diag(af)))
+%!assert(diag(bs),sparse(diag(bf)))
+%!assert(diag(as,1),sparse(diag(af,1)))
+%!assert(diag(bs,1),sparse(diag(bf,1)))
+%!assert(diag(as,-1),sparse(diag(af,-1)))
+%!assert(diag(bs,-1),sparse(diag(bf,-1)))
+%!assert(diag(as(:)),sparse(diag(af(:))))
+%!assert(diag(as(:),1),sparse(diag(af(:),1)))
+%!assert(diag(as(:),-1),sparse(diag(af(:),-1)))
+%!assert(diag(as(:)'),sparse(diag(af(:)')))
+%!assert(diag(as(:)',1),sparse(diag(af(:)',1)))
+%!assert(diag(as(:)',-1),sparse(diag(af(:)',-1)))
+%!assert(spdiags(as,[0,1]),[diag(af,0),diag(af,1)])
+%!test [tb,tc]=spdiags(as); 
+%! assert(spdiags(tb,tc,sparse(zeros(size(as)))),as)
+%! assert(spdiags(tb,tc,size(as,1),size(as,2)),as)
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(reshape(as,1,prod(size(as))),sparse(reshape(af,1,prod(size(af)))))
+%!assert(reshape(as,prod(size(as)),1),sparse(reshape(af,prod(size(af)),1)))
+%!assert(reshape(as,fliplr(size(as))),sparse(reshape(af,fliplr(size(af)))))
+%!assert(reshape(bs,1,prod(size(as))),sparse(reshape(bf,1,prod(size(af)))))
+%!assert(reshape(bs,prod(size(as)),1),sparse(reshape(bf,prod(size(af)),1)))
+%!assert(reshape(bs,fliplr(size(as))),sparse(reshape(bf,fliplr(size(af)))))
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+
+# ==============================================================
+
+%!test # save ascii
+%! savefile= tmpnam();
+%! as_save=as; save("-text",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+%!test # save binary
+%! savefile= tmpnam();
+%! as_save=as; save("-binary",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+%!testif HAVE_HDF5 # save hdf5
+%! savefile= tmpnam();
+%! as_save=as; save("-hdf5",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+## FIXME -- we should skip (or mark as an expected failure) the test for
+## saving sparse matrices to MAT files when using 64-bit indexing since
+## that is not implemented yet.
+%!test # save matlab
+%! savefile= tmpnam();
+%! as_save=as; save("-mat",savefile,"bf","as_save","af");
+%! clear as_save;
+%! load(savefile,"as_save");
+%! unlink(savefile);
+%! assert(as_save,sparse(af));
+
+# ==============================================================
+
+%!test bf=bf+1i*(bf~=0);
+%!test as=sparse(af);
+%!test bs=sparse(bf);
+%% Unary matrix tests (uses af,as)
+%!assert(abs(as),sparse(abs(af)))
+%!assert(acos(as),sparse(acos(af)))
+%!assert(acosh(as),sparse(acosh(af)))
+%!assert(angle(as),sparse(angle(af)))
+%!assert(arg(as),sparse(arg(af)))
+%!assert(asin(as),sparse(asin(af)))
+%!assert(asinh(as),sparse(asinh(af)))
+%!assert(atan(as),sparse(atan(af)))
+%!assert(atanh(as),sparse(atanh(af)))
+%!assert(ceil(as),sparse(ceil(af)))
+%!assert(conj(as),sparse(conj(af)))
+%!assert(cos(as),sparse(cos(af)))
+%!assert(cosh(as),sparse(cosh(af)))
+%!assert(exp(as),sparse(exp(af)))
+%!assert(finite(as),sparse(finite(af)))
+%!assert(fix(as),sparse(fix(af)))
+%!assert(floor(as),sparse(floor(af)))
+%!assert(imag(as),sparse(imag(af)))
+%!assert(isinf(as),sparse(isinf(af)))
+%!assert(isna(as),sparse(isna(af)))
+%!assert(isnan(as),sparse(isnan(af)))
+%!assert(log(as),sparse(log(af)))
+%!assert(real(as),sparse(real(af)))
+%!assert(round(as),sparse(round(af)))
+%!assert(sign(as),sparse(sign(af)))
+%!assert(sin(as),sparse(sin(af)))
+%!assert(sinh(as),sparse(sinh(af)))
+%!assert(sqrt(as),sparse(sqrt(af)))
+%!assert(tan(as),sparse(tan(af)))
+%!assert(tanh(as),sparse(tanh(af)))
+%!assert(issparse(abs(as))&&isreal(abs(as)))
+%!assert(issparse(real(as))&&isreal(real(as)))
+%!assert(issparse(imag(as))&&isreal(imag(as)))
+
+%% Unary matrix tests (uses af,as)
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erf(as),sparse(erf(af)))
+%!   else
+%!     assert(erf(as),erf(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (1)
+%!     assert(erfc(as),sparse(erfc(af)))
+%!   else
+%!     assert(erfc(as),erfc(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalnum(as),sparse(isalnum(af)))
+%!   else
+%!     assert(isalnum(as),isalnum(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isalpha(as),sparse(isalpha(af)))
+%!   else
+%!     assert(isalpha(as),isalpha(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isascii(as),sparse(isascii(af)))
+%!   else
+%!     assert(isascii(as),isascii(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(iscntrl(as),sparse(iscntrl(af)))
+%!   else
+%!     assert(iscntrl(as),iscntrl(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isdigit(as),sparse(isdigit(af)))
+%!   else
+%!     assert(isdigit(as),isdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isgraph(as),sparse(isgraph(af)))
+%!   else
+%!     assert(isgraph(as),isgraph(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(islower(as),sparse(islower(af)))
+%!   else
+%!     assert(islower(as),islower(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isprint(as),sparse(isprint(af)))
+%!   else
+%!     assert(isprint(as),isprint(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(ispunct(as),sparse(ispunct(af)))
+%!   else
+%!     assert(ispunct(as),ispunct(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isspace(as),sparse(isspace(af)))
+%!   else
+%!     assert(isspace(as),isspace(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isupper(as),sparse(isupper(af)))
+%!   else
+%!     assert(isupper(as),isupper(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!   if (0)
+%!     assert(isxdigit(as),sparse(isxdigit(af)))
+%!   else
+%!     assert(isxdigit(as),isxdigit(af))
+%!   endif
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+
+%% These mapper functions always return a full matrix
+%!test
+%! wn2s = warning ("query", "Octave:num-to-str");
+%! warning ("off", "Octave:num-to-str");
+%! if isreal(af)
+%!    assert(toascii(as),toascii(af))
+%!    assert(tolower(as),tolower(af))
+%!    assert(toupper(as),toupper(af))
+%! endif
+%! warning (wn2s.state, "Octave:num-to-str");
+
+%% Unary matrix tests (uses af,as)
+%!assert(issparse(as))
+%!assert(!issparse(af))
+%!assert(!(issparse(af)&&iscomplex(af)))
+%!assert(!(issparse(af)&&isreal(af)))
+%!assert(sum(as),sparse(sum(af)))
+%!assert(sum(as,1),sparse(sum(af,1)))
+%!assert(sum(as,2),sparse(sum(af,2)))
+%!assert(cumsum(as),sparse(cumsum(af)))
+%!assert(cumsum(as,1),sparse(cumsum(af,1)))
+%!assert(cumsum(as,2),sparse(cumsum(af,2)))
+%!assert(sumsq(as),sparse(sumsq(af)))
+%!assert(sumsq(as,1),sparse(sumsq(af,1)))
+%!assert(sumsq(as,2),sparse(sumsq(af,2)))
+%!assert(prod(as),sparse(prod(af)))
+%!assert(prod(as,1),sparse(prod(af,1)))
+%!assert(prod(as,2),sparse(prod(af,2)))
+%!assert(cumprod(as),sparse(cumprod(af)))
+%!assert(cumprod(as,1),sparse(cumprod(af,1)))
+%!assert(cumprod(as,2),sparse(cumprod(af,2)))
+
+%!assert(min(as),sparse(min(af)))
+%!assert(full(min(as(:))),min(af(:)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,[],2),sparse(min(af,[],2)))
+%!assert(min(as,[],1),sparse(min(af,[],1)))
+%!assert(min(as,0),sparse(min(af,0)))
+%!assert(min(as,bs),sparse(min(af,bf)))
+%!assert(max(as),sparse(max(af)))
+%!assert(full(max(as(:))),max(af(:)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,[],2),sparse(max(af,[],2)))
+%!assert(max(as,[],1),sparse(max(af,[],1)))
+%!assert(max(as,0),sparse(max(af,0)))
+%!assert(max(as,bs),sparse(max(af,bf)))
+
+%!assert(as==as)
+%!assert(as==af)
+%!assert(af==as)
+%!test
+%! [ii,jj,vv,nr,nc] = find(as);
+%! assert(af,full(sparse(ii,jj,vv,nr,nc)));
+%!assert(nnz(as),sum(af(:)!=0))
+%!assert(nnz(as),nnz(af))
+%!assert(issparse(as.'))
+%!assert(issparse(as'))
+%!assert(issparse(-as))
+%!assert(~as,sparse(~af))
+%!assert(as.', sparse(af.'));
+%!assert(as',  sparse(af'));
+%!assert(-as, sparse(-af));
+%!assert(~as, sparse(~af));
+%!error [i,j]=size(af);as(i-1,j+1);
+%!error [i,j]=size(af);as(i+1,j-1);
+%!test
+%! [Is,Js,Vs] = find(as);
+%! [If,Jf,Vf] = find(af);
+%! assert(Is,If);
+%! assert(Js,Jf);
+%! assert(Vs,Vf);
+%!error as(0,1);
+%!error as(1,0);
+%!assert(find(as),find(af))
+%!test
+%! [i,j,v] = find(as);
+%! [m,n] = size(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!test
+%! [i,j,v,m,n] = find(as);
+%! x = sparse(i,j,v,m,n);
+%! assert(x,as);
+%!assert(issparse(horzcat(as,as)));
+%!assert(issparse(vertcat(as,as)));
+%!assert(issparse(cat(1,as,as)));
+%!assert(issparse(cat(2,as,as)));
+%!assert(issparse([as,as]));
+%!assert(issparse([as;as]));
+%!assert(horzcat(as,as), sparse([af,af]));
+%!assert(vertcat(as,as), sparse([af;af]));
+%!assert(horzcat(as,as,as), sparse([af,af,af]));
+%!assert(vertcat(as,as,as), sparse([af;af;af]));
+%!assert([as,as], sparse([af,af]));
+%!assert([as;as], sparse([af;af]));
+%!assert([as,as,as], sparse([af,af,af]));
+%!assert([as;as;as], sparse([af;af;af]));
+%!assert(cat(2,as,as), sparse([af,af]));
+%!assert(cat(1,as,as), sparse([af;af]));
+%!assert(cat(2,as,as,as), sparse([af,af,af]));
+%!assert(cat(1,as,as,as), sparse([af;af;af]));
+%!assert(issparse([as,af]));
+%!assert(issparse([af,as]));
+%!assert([as,af], sparse([af,af]));
+%!assert([as;af], sparse([af;af]));
+
+%% Elementwise binary tests (uses as,af,bs,bf,scalar)
+%!assert(as==bs,sparse(af==bf))
+%!assert(bf==as,sparse(bf==af))
+
+%!assert(as!=bf,sparse(af!=bf))
+%!assert(bf!=as,sparse(bf!=af))
+
+%!assert(as+bf,af+bf)
+%!assert(bf+as,bf+af)
+
+%!assert(as-bf,af-bf)
+%!assert(bf-as,bf-af)
+
+%!assert(as.*bf,sparse(af.*bf))
+%!assert(bf.*as,sparse(bf.*af))
+
+%!assert(as./bf,sparse(af./bf),100*eps)
+%!assert(bf.\as,sparse(bf.\af),100*eps)
+
+%!test
+%! sv = as.^bf;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%!assert(as==bs,sparse(af==bf))
+%!assert(as!=bs,sparse(af!=bf))
+%!assert(as+bs,sparse(af+bf))
+%!assert(as-bs,sparse(af-bf))
+%!assert(as.*bs,sparse(af.*bf))
+%!xtest assert(as./bs,sparse(af./bf),100*eps);
+%!test
+%! sv = as.^bs;
+%! fv = af.^bf;
+%! idx = find(af~=0);
+%! assert(sv(:)(idx),sparse(fv(:)(idx)),100*eps)
+
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as*bf',af*bf')
+%!assert(af*bs',af*bf')
+%!assert(as*bs',sparse(af*bf'))
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(diag(as),sparse(diag(af)))
+%!assert(diag(bs),sparse(diag(bf)))
+%!assert(diag(as,1),sparse(diag(af,1)))
+%!assert(diag(bs,1),sparse(diag(bf,1)))
+%!assert(diag(as,-1),sparse(diag(af,-1)))
+%!assert(diag(bs,-1),sparse(diag(bf,-1)))
+%!assert(diag(as(:)),sparse(diag(af(:))))
+%!assert(diag(as(:),1),sparse(diag(af(:),1)))
+%!assert(diag(as(:),-1),sparse(diag(af(:),-1)))
+%!assert(diag(as(:)'),sparse(diag(af(:)')))
+%!assert(diag(as(:)',1),sparse(diag(af(:)',1)))
+%!assert(diag(as(:)',-1),sparse(diag(af(:)',-1)))
+%!assert(spdiags(as,[0,1]),[diag(af,0),diag(af,1)])
+%!test [tb,tc]=spdiags(as); 
+%! assert(spdiags(tb,tc,sparse(zeros(size(as)))),as)
+%! assert(spdiags(tb,tc,size(as,1),size(as,2)),as)
+
+%% Matrix diagonal tests (uses af,as,bf,bs)
+%!assert(reshape(as,1,prod(size(as))),sparse(reshape(af,1,prod(size(af)))))
+%!assert(reshape(as,prod(size(as)),1),sparse(reshape(af,prod(size(af)),1)))
+%!assert(reshape(as,fliplr(size(as))),sparse(reshape(af,fliplr(size(af)))))
+%!assert(reshape(bs,1,prod(size(as))),sparse(reshape(bf,1,prod(size(af)))))
+%!assert(reshape(bs,prod(size(as)),1),sparse(reshape(bf,prod(size(af)),1)))
+%!assert(reshape(bs,fliplr(size(as))),sparse(reshape(bf,fliplr(size(af)))))
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+
+# ==============================================================
+
+%!test af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];
+%! as=sparse(af);
+%!test bf=[0,1-1i,0,0;2+1i,0,0,0;3-1i,2+3i,0,0];
+%!test ;# invertible matrix
+%! bf=af'*bf+max(abs([af(:);bf(:)]))*sparse(eye(columns(as)));
+%! bs=sparse(bf);
+
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as/bf,af/bf,100*eps)
+%!assert(af/bs,af/bf,100*eps)
+%!assert(as/bs,sparse(af/bf),100*eps)
+%!assert(bs\af',bf\af',100*eps)
+%!assert(bf\as',bf\af',100*eps)
+%!assert(bs\as',sparse(bf\af'),100*eps)
+
+%!testif HAVE_UMFPACK
+%! assert(det(bs+speye(size(bs))),det(bf+eye(size(bf))),100*eps*abs(det(bf+eye(size(bf)))))
+
+%!testif HAVE_UMFPACK 
+%! [l,u]=lu(sparse([1,1;1,1]));
+%! assert(l*u,[1,1;1,1],10*eps);
+
+%!testif HAVE_UMFPACK
+%! [l,u]=lu(sparse([1,1;1,1+i]));
+%! assert(l,sparse([1,2,2],[1,1,2],1),10*eps);
+%! assert(u,sparse([1,1,2],[1,2,2],[1,1,1i]),10*eps);
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# inverse
+%! assert(inv(bs)*bs,sparse(eye(rows(bs))),1e-10);
+
+%!assert(bf\as',bf\af',100*eps);
+%!assert(bs\af',bf\af',100*eps);
+%!assert(bs\as',sparse(bf\af'),100*eps);
+
+
+# ==============================================================
+
+%!test bf=real(bf);
+%! bs=sparse(bf);
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as/bf,af/bf,100*eps)
+%!assert(af/bs,af/bf,100*eps)
+%!assert(as/bs,sparse(af/bf),100*eps)
+%!assert(bs\af',bf\af',100*eps)
+%!assert(bf\as',bf\af',100*eps)
+%!assert(bs\as',sparse(bf\af'),100*eps)
+
+%!testif HAVE_UMFPACK
+%! assert(det(bs+speye(size(bs))),det(bf+eye(size(bf))),100*eps*abs(det(bf+eye(size(bf)))))
+
+%!testif HAVE_UMFPACK 
+%! [l,u]=lu(sparse([1,1;1,1]));
+%! assert(l*u,[1,1;1,1],10*eps);
+
+%!testif HAVE_UMFPACK
+%! [l,u]=lu(sparse([1,1;1,1+i]));
+%! assert(l,sparse([1,2,2],[1,1,2],1),10*eps);
+%! assert(u,sparse([1,1,2],[1,2,2],[1,1,1i]),10*eps);
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# inverse
+%! assert(inv(bs)*bs,sparse(eye(rows(bs))),1e-10);
+
+%!assert(bf\as',bf\af',100*eps);
+%!assert(bs\af',bf\af',100*eps);
+%!assert(bs\as',sparse(bf\af'),100*eps);
+
+
+# ==============================================================
+
+%!test af=real(af);
+%! as=sparse(af);
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as/bf,af/bf,100*eps)
+%!assert(af/bs,af/bf,100*eps)
+%!assert(as/bs,sparse(af/bf),100*eps)
+%!assert(bs\af',bf\af',100*eps)
+%!assert(bf\as',bf\af',100*eps)
+%!assert(bs\as',sparse(bf\af'),100*eps)
+
+%!testif HAVE_UMFPACK
+%! assert(det(bs+speye(size(bs))),det(bf+eye(size(bf))),100*eps*abs(det(bf+eye(size(bf)))))
+
+%!testif HAVE_UMFPACK 
+%! [l,u]=lu(sparse([1,1;1,1]));
+%! assert(l*u,[1,1;1,1],10*eps);
+
+%!testif HAVE_UMFPACK
+%! [l,u]=lu(sparse([1,1;1,1+i]));
+%! assert(l,sparse([1,2,2],[1,1,2],1),10*eps);
+%! assert(u,sparse([1,1,2],[1,2,2],[1,1,1i]),10*eps);
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# inverse
+%! assert(inv(bs)*bs,sparse(eye(rows(bs))),1e-10);
+
+%!assert(bf\as',bf\af',100*eps);
+%!assert(bs\af',bf\af',100*eps);
+%!assert(bs\as',sparse(bf\af'),100*eps);
+
+
+# ==============================================================
+
+%!test bf=bf+1i*(bf~=0);
+%! bs=sparse(bf);
+%% Matrix-matrix operators (uses af,as,bs,bf)
+%!assert(as/bf,af/bf,100*eps)
+%!assert(af/bs,af/bf,100*eps)
+%!assert(as/bs,sparse(af/bf),100*eps)
+%!assert(bs\af',bf\af',100*eps)
+%!assert(bf\as',bf\af',100*eps)
+%!assert(bs\as',sparse(bf\af'),100*eps)
+
+%!testif HAVE_UMFPACK
+%! assert(det(bs+speye(size(bs))),det(bf+eye(size(bf))),100*eps*abs(det(bf+eye(size(bf)))))
+
+%!testif HAVE_UMFPACK 
+%! [l,u]=lu(sparse([1,1;1,1]));
+%! assert(l*u,[1,1;1,1],10*eps);
+
+%!testif HAVE_UMFPACK
+%! [l,u]=lu(sparse([1,1;1,1+i]));
+%! assert(l,sparse([1,2,2],[1,1,2],1),10*eps);
+%! assert(u,sparse([1,1,2],[1,2,2],[1,1,1i]),10*eps);
+
+%!testif HAVE_UMFPACK ;# permuted LU
+%! [L,U] = lu(bs);
+%! assert(L*U,bs,1e-10);
+
+%!testif HAVE_UMFPACK ;# simple LU + row permutations
+%! [L,U,P] = lu(bs);
+%! assert(P'*L*U,bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# simple LU + row/col permutations
+%! [L,U,P,Q] = lu(bs);
+%! assert(P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with vector permutations
+%! [L,U,P,Q] = lu(bs,'vector');
+%! assert(L(P,:)*U(:,Q),bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# LU with scaling
+%! [L,U,P,Q,R] = lu(bs);
+%! assert(R*P'*L*U*Q',bs,1e-10);
+%! # triangularity
+%! [i,j,v]=find(L);
+%! assert(i-j>=0);
+%! [i,j,v]=find(U);
+%! assert(j-i>=0);
+
+%!testif HAVE_UMFPACK ;# inverse
+%! assert(inv(bs)*bs,sparse(eye(rows(bs))),1e-10);
+
+%!assert(bf\as',bf\af',100*eps);
+%!assert(bs\af',bf\af',100*eps);
+%!assert(bs\as',sparse(bf\af'),100*eps);
+
+
+# ==============================================================
+
+%!test bf=[5,0,1+1i,0;0,5,0,1-2i;1-1i,0,5,0;0,1+2i,0,5];
+%! bs=sparse(bf);
+%!testif HAVE_CHOLMOD
+%! assert(chol(bs)'*chol(bs),bs,1e-10);
+%!testif HAVE_CHOLMOD 
+%! assert(chol(bs,'lower')*chol(bs,'lower')',bs,1e-10);
+%!testif HAVE_CHOLMOD
+%! assert(chol(bs,'lower'),chol(bs)',1e-10);
+
+%!testif HAVE_CHOLMOD ;# Return Partial Cholesky factorization
+%! [RS,PS] = chol(bs);
+%! assert(RS'*RS,bs,1e-10);
+%! assert(PS,0);
+%! [LS,PS] = chol(bs,'lower');
+%! assert(LS*LS',bs,1e-10);
+%! assert(PS,0);
+
+%!testif HAVE_CHOLMOD ;# Permuted Cholesky factorization
+%! [RS,PS,QS] = chol(bs);
+%! assert(RS'*RS,QS*bs*QS',1e-10);
+%! assert(PS,0);
+%! [LS,PS,QS] = chol(bs,'lower');
+%! assert(LS*LS',QS*bs*QS',1e-10);
+%! assert(PS,0);
+
+
+# ==============================================================
+
+%!test bf=real(bf);
+%! bs=sparse(bf);
+%!testif HAVE_CHOLMOD
+%! assert(chol(bs)'*chol(bs),bs,1e-10);
+%!testif HAVE_CHOLMOD 
+%! assert(chol(bs,'lower')*chol(bs,'lower')',bs,1e-10);
+%!testif HAVE_CHOLMOD
+%! assert(chol(bs,'lower'),chol(bs)',1e-10);
+
+%!testif HAVE_CHOLMOD ;# Return Partial Cholesky factorization
+%! [RS,PS] = chol(bs);
+%! assert(RS'*RS,bs,1e-10);
+%! assert(PS,0);
+%! [LS,PS] = chol(bs,'lower');
+%! assert(LS*LS',bs,1e-10);
+%! assert(PS,0);
+
+%!testif HAVE_CHOLMOD ;# Permuted Cholesky factorization
+%! [RS,PS,QS] = chol(bs);
+%! assert(RS'*RS,QS*bs*QS',1e-10);
+%! assert(PS,0);
+%! [LS,PS,QS] = chol(bs,'lower');
+%! assert(LS*LS',QS*bs*QS',1e-10);
+%! assert(PS,0);
+
+
+# ==============================================================
+
+%!shared r,c,m,n,fsum,funiq
+%!test
+%! r=[1,1,2,1,2,3];
+%! c=[2,1,1,1,2,1];
+%! m=n=0;
+%%Assembly tests
+%!test
+%! m=max([m;r(:)]);
+%! n=max([n;c(:)]);
+%! funiq=fsum=zeros(m,n);
+%! funiq(r(:) + m*(c(:)-1) ) = ones(size(r(:)));
+%! funiq = sparse(funiq);
+%! for k=1:length(r), fsum(r(k),c(k)) += 1; end
+%! fsum = sparse(fsum);
+%!assert(sparse(r,c,1),sparse(fsum(1:max(r),1:max(c))));
+%!assert(sparse(r,c,1,"sum"),sparse(fsum(1:max(r),1:max(c))));
+%!assert(sparse(r,c,1,"unique"),sparse(funiq(1:max(r),1:max(c))));
+%!assert(sparse(r,c,1,m,n),sparse(fsum));
+%!assert(sparse(r,c,1,m,n,"sum"),sparse(fsum));
+%!assert(sparse(r,c,1,m,n,"unique"),sparse(funiq));
+
+%!assert(sparse(r,c,1i),sparse(fsum(1:max(r),1:max(c))*1i));
+%!assert(sparse(r,c,1i,"sum"),sparse(fsum(1:max(r),1:max(c))*1i));
+%!assert(sparse(r,c,1i,"unique"),sparse(funiq(1:max(r),1:max(c))*1i));
+%!assert(sparse(r,c,1i,m,n),sparse(fsum*1i));
+%!assert(sparse(r,c,1i,m,n,"sum"),sparse(fsum*1i));
+%!assert(sparse(r,c,1i,m,n,"unique"),sparse(funiq*1i));
+
+%!test
+%! if (issparse(funiq))
+%!  assert(sparse(full(1i*funiq)),sparse(1i*funiq));
+%! endif
+
+%!assert(sparse(full(funiq)),funiq);
+
+
+
+# ==============================================================
+
+%!shared ridx,cidx,idx,as,af
+%!test
+%! af=[1+1i,2-1i,0,0;0,0,0,3+2i;0,0,0,4];
+%! ridx=[1,3]; cidx=[2,3];
+%!assert (sparse(42)([1,1]),sparse([42,42]))
+%!assert (sparse(42*1i)([1,1]),sparse([42,42].*1i))
+%!test as=sparse(af);
+
+%% Point tests
+%!test idx=ridx(:)+rows(as)*(cidx(:)-1);
+%!assert(sparse(as(idx)),sparse(af(idx)));
+%!assert(as(idx),sparse(af(idx)));
+%!assert(as(idx'),sparse(af(idx')));
+%!assert(as(flipud(idx(:))),sparse(af(flipud(idx(:)))))
+%!assert(as([idx,idx]),sparse(af([idx,idx])));
+%!error(as(reshape([idx;idx],[1,length(idx),2])));
+
+%% Slice tests
+%!assert(as(ridx,cidx), sparse(af(ridx,cidx)))
+%!assert(as(ridx,:), sparse(af(ridx,:)))
+%!assert(as(:,cidx), sparse(af(:,cidx)))
+%!assert(as(:,:), sparse(af(:,:)))
+%!assert(as((size(as,1):-1:1),:),sparse(af((size(af,1):-1:1),:)))
+%!assert(as(:,(size(as,2):-1:1)),sparse(af(:,(size(af,2):-1:1))))
+
+%% Indexing tests
+%!assert(full(as([1,1],:)), af([1,1],:))
+%!assert(full(as(:,[1,1])), af(:,[1,1]))
+%!test
+%! [i,j,v] = find (as);
+%! assert (as(i(1),j(1))([1,1]), sparse([v(1),v(1)]))
+
+%% Assignment test
+%!test
+%! ts=as;ts(:,:)=ts(fliplr(1:size(as,1)),:);
+%! tf=af;tf(:,:)=tf(fliplr(1:size(af,1)),:);
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(fliplr(1:size(as,1)),:)=ts;
+%! tf=af;tf(fliplr(1:size(af,1)),:)=tf;
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(:,fliplr(1:size(as,2)))=ts;
+%! tf=af;tf(:,fliplr(1:size(af,2)))=tf;
+%! assert(ts,sparse(tf));
+%!test
+%! ts(fliplr(1:size(as,1)))=as(:,1);tf(fliplr(1:size(af,1)))=af(:,1);
+%! assert(ts,sparse(tf));
+
+%% Deletion tests
+%!test
+%! ts=as;ts(1,:)=[];tf=af;tf(1,:)=[];
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(:,1)=[];tf=af;tf(:,1)=[];
+%! assert(ts,sparse(tf));
+
+%% Test 'end' keyword
+%!assert(full(as(end)), af(end))
+%!assert(full(as(1,end)), af(1,end))
+%!assert(full(as(end,1)), af(end,1))
+%!assert(full(as(end,end)), af(end,end))
+%!assert(as(2:end,2:end), sparse(af(2:end,2:end)))
+%!assert(as(1:end-1,1:end-1), sparse(af(1:end-1,1:end-1)))
+%!test af=real(af);
+%!test as=sparse(af);
+
+%% Point tests
+%!test idx=ridx(:)+rows(as)*(cidx(:)-1);
+%!assert(sparse(as(idx)),sparse(af(idx)));
+%!assert(as(idx),sparse(af(idx)));
+%!assert(as(idx'),sparse(af(idx')));
+%!assert(as(flipud(idx(:))),sparse(af(flipud(idx(:)))))
+%!assert(as([idx,idx]),sparse(af([idx,idx])));
+%!error(as(reshape([idx;idx],[1,length(idx),2])));
+
+%% Slice tests
+%!assert(as(ridx,cidx), sparse(af(ridx,cidx)))
+%!assert(as(ridx,:), sparse(af(ridx,:)))
+%!assert(as(:,cidx), sparse(af(:,cidx)))
+%!assert(as(:,:), sparse(af(:,:)))
+%!assert(as((size(as,1):-1:1),:),sparse(af((size(af,1):-1:1),:)))
+%!assert(as(:,(size(as,2):-1:1)),sparse(af(:,(size(af,2):-1:1))))
+
+%% Indexing tests
+%!assert(full(as([1,1],:)), af([1,1],:))
+%!assert(full(as(:,[1,1])), af(:,[1,1]))
+%!test
+%! [i,j,v] = find (as);
+%! assert (as(i(1),j(1))([1,1]), sparse([v(1),v(1)]))
+
+%% Assignment test
+%!test
+%! ts=as;ts(:,:)=ts(fliplr(1:size(as,1)),:);
+%! tf=af;tf(:,:)=tf(fliplr(1:size(af,1)),:);
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(fliplr(1:size(as,1)),:)=ts;
+%! tf=af;tf(fliplr(1:size(af,1)),:)=tf;
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(:,fliplr(1:size(as,2)))=ts;
+%! tf=af;tf(:,fliplr(1:size(af,2)))=tf;
+%! assert(ts,sparse(tf));
+%!test
+%! ts(fliplr(1:size(as,1)))=as(:,1);tf(fliplr(1:size(af,1)))=af(:,1);
+%! assert(ts,sparse(tf));
+
+%% Deletion tests
+%!test
+%! ts=as;ts(1,:)=[];tf=af;tf(1,:)=[];
+%! assert(ts,sparse(tf));
+%!test
+%! ts=as;ts(:,1)=[];tf=af;tf(:,1)=[];
+%! assert(ts,sparse(tf));
+
+%% Test 'end' keyword
+%!assert(full(as(end)), af(end))
+%!assert(full(as(1,end)), af(1,end))
+%!assert(full(as(end,1)), af(end,1))
+%!assert(full(as(end,end)), af(end,end))
+%!assert(as(2:end,2:end), sparse(af(2:end,2:end)))
+%!assert(as(1:end-1,1:end-1), sparse(af(1:end-1,1:end-1)))
+
+# ==============================================================
+
+%!shared alpha,beta,df,pdf,lf,plf,uf,puf,bf,cf,bcf,tf,tcf,xf,ds,pds,ls,pls,us,pus,bs,cs,bcs,ts,tcs,xs
+%!test alpha=1;beta=1;
+%! n=8;
+%! lf=diag(1:n);lf(n-1,1)=0.5*alpha;lf(n,2)=0.25*alpha;ls=sparse(lf);
+%! uf=diag(1:n);uf(1,n-1)=2*alpha;uf(2,n)=alpha;us=sparse(uf);
+%! ts=spdiags(ones(n,3),-1:1,n,n)+diag(1:n); tf = full(ts);
+%! df = diag(1:n).* alpha; ds = sparse(df);
+%! pdf = df(randperm(n),randperm(n)); pds = sparse(pdf);
+%! plf = lf(randperm(n),randperm(n)); pls = sparse(plf);
+%! puf = uf(randperm(n),randperm(n)); pus = sparse(puf);
+%! bs = spdiags(repmat([1:n]',1,4),-2:1,n,n).*alpha; bf = full(bs);
+%! cf = lf + lf'; cs = sparse(cf);
+%! bcf = bf + bf'; bcs = sparse(bcf);
+%! tcf = tf + tf'; tcs = sparse(tcf);
+%! xf = diag(1:n) + fliplr(diag(1:n)).*beta; xs = sparse(xf);
+%!assert(ds\xf,df\xf,1e-10);
+%!assert(ds\xs,sparse(df\xf),1e-10);
+%!assert(pds\xf,pdf\xf,1e-10);
+%!assert(pds\xs,sparse(pdf\xf),1e-10);
+%!assert(ls\xf,lf\xf,1e-10);
+%!assert(sparse(ls\xs),sparse(lf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pls\xf,plf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pls\xs),sparse(plf\xf),1e-10);
+%!assert(us\xf,uf\xf,1e-10);
+%!assert(sparse(us\xs),sparse(uf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pus\xf,puf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pus\xs),sparse(puf\xf),1e-10);
+%!assert(bs\xf,bf\xf,1e-10);
+%!assert(sparse(bs\xs),sparse(bf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(cs\xf,cf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(cs\xs),sparse(cf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(bcs\xf,bcf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(bcs\xs),sparse(bcf\xf),1e-10);
+%!assert(ts\xf,tf\xf,1e-10);
+%!assert(sparse(ts\xs),sparse(tf\xf),1e-10);
+%!assert(tcs\xf,tcf\xf,1e-10);
+%!assert(sparse(tcs\xs),sparse(tcf\xf),1e-10);
+
+%% QR solver tests
+
+%!function f(a, sz, feps)
+%! b = randn(sz); x = a \b; 
+%! assert (a * x, b, feps);
+%! b = randn(sz)+1i*randn(sz); x = a \ b;  
+%! assert (a * x, b, feps);
+%! b = sprandn(sz(1),sz(2),0.2); x = a \b;
+%! assert (sparse(a * x), b, feps);
+%! b = sprandn(sz(1),sz(2),0.2)+1i*sprandn(sz(1),sz(2),0.2); x = a \b; 
+%! assert (sparse(a * x), b, feps);
+%!testif HAVE_CXSPARSE
+%! a = alpha*sprandn(10,11,0.2)+speye(10,11); f(a,[10,2],1e-10);
+%! ## Test this by forcing matrix_type, as can't get a certain 
+%! ## result for over-determined systems.
+%! a = alpha*sprandn(10,10,0.2)+speye(10,10); matrix_type(a, "Singular");
+%! f(a,[10,2],1e-10);
+
+%% Rectanguar solver tests that don't use QR
+
+%!test
+%! ds = alpha * spdiags([1:11]',0,10,11);
+%! df = full(ds);
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:10],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! ds = alpha * spdiags([1:11]',0,11,10);
+%! df = full(ds);
+%! xf = beta * ones(11,2);
+%! xs = speye(11,11);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:11],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! us = alpha*[[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]];
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xs),xs,100*eps)
+%!test
+%! pus = us(:,[2,1,3:12]);
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xs),xs,100*eps)
+%!test
+%! us = alpha*[speye(11,9),[1;sparse(8,1);1;0]];
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xf);
+%! assert(us\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(us\xs,r\c,100*eps)
+%!test
+%! pus = us(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xs,r\c,100*eps)
+%!test
+%! ls = alpha*[speye(9,11);[1,sparse(1,8),1,0]];
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ls*(ls\xf),xf,100*eps)
+%!assert(ls*(ls\xs),xs,100*eps)
+%!test
+%! pls = ls([1:8,10,9],:);
+%!assert(pls*(pls\xf),xf,100*eps)
+%!assert(pls*(pls\xs),xs,100*eps)
+%!test
+%! ls = alpha*[speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]];
+%! xf = beta * ones(12,2);
+%! xs = speye(12,12);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xf);
+%! assert(ls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(ls\xs,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! pls = ls(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xs,r\c,100*eps)
+
+%!test alpha=1;beta=1i;
+%! n=8;
+%! lf=diag(1:n);lf(n-1,1)=0.5*alpha;lf(n,2)=0.25*alpha;ls=sparse(lf);
+%! uf=diag(1:n);uf(1,n-1)=2*alpha;uf(2,n)=alpha;us=sparse(uf);
+%! ts=spdiags(ones(n,3),-1:1,n,n)+diag(1:n); tf = full(ts);
+%! df = diag(1:n).* alpha; ds = sparse(df);
+%! pdf = df(randperm(n),randperm(n)); pds = sparse(pdf);
+%! plf = lf(randperm(n),randperm(n)); pls = sparse(plf);
+%! puf = uf(randperm(n),randperm(n)); pus = sparse(puf);
+%! bs = spdiags(repmat([1:n]',1,4),-2:1,n,n).*alpha; bf = full(bs);
+%! cf = lf + lf'; cs = sparse(cf);
+%! bcf = bf + bf'; bcs = sparse(bcf);
+%! tcf = tf + tf'; tcs = sparse(tcf);
+%! xf = diag(1:n) + fliplr(diag(1:n)).*beta; xs = sparse(xf);
+%!assert(ds\xf,df\xf,1e-10);
+%!assert(ds\xs,sparse(df\xf),1e-10);
+%!assert(pds\xf,pdf\xf,1e-10);
+%!assert(pds\xs,sparse(pdf\xf),1e-10);
+%!assert(ls\xf,lf\xf,1e-10);
+%!assert(sparse(ls\xs),sparse(lf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pls\xf,plf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pls\xs),sparse(plf\xf),1e-10);
+%!assert(us\xf,uf\xf,1e-10);
+%!assert(sparse(us\xs),sparse(uf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pus\xf,puf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pus\xs),sparse(puf\xf),1e-10);
+%!assert(bs\xf,bf\xf,1e-10);
+%!assert(sparse(bs\xs),sparse(bf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(cs\xf,cf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(cs\xs),sparse(cf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(bcs\xf,bcf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(bcs\xs),sparse(bcf\xf),1e-10);
+%!assert(ts\xf,tf\xf,1e-10);
+%!assert(sparse(ts\xs),sparse(tf\xf),1e-10);
+%!assert(tcs\xf,tcf\xf,1e-10);
+%!assert(sparse(tcs\xs),sparse(tcf\xf),1e-10);
+
+%% QR solver tests
+
+%!function f(a, sz, feps)
+%! b = randn(sz); x = a \b; 
+%! assert (a * x, b, feps);
+%! b = randn(sz)+1i*randn(sz); x = a \ b;  
+%! assert (a * x, b, feps);
+%! b = sprandn(sz(1),sz(2),0.2); x = a \b;
+%! assert (sparse(a * x), b, feps);
+%! b = sprandn(sz(1),sz(2),0.2)+1i*sprandn(sz(1),sz(2),0.2); x = a \b; 
+%! assert (sparse(a * x), b, feps);
+%!testif HAVE_CXSPARSE
+%! a = alpha*sprandn(10,11,0.2)+speye(10,11); f(a,[10,2],1e-10);
+%! ## Test this by forcing matrix_type, as can't get a certain 
+%! ## result for over-determined systems.
+%! a = alpha*sprandn(10,10,0.2)+speye(10,10); matrix_type(a, "Singular");
+%! f(a,[10,2],1e-10);
+
+%% Rectanguar solver tests that don't use QR
+
+%!test
+%! ds = alpha * spdiags([1:11]',0,10,11);
+%! df = full(ds);
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:10],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! ds = alpha * spdiags([1:11]',0,11,10);
+%! df = full(ds);
+%! xf = beta * ones(11,2);
+%! xs = speye(11,11);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:11],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! us = alpha*[[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]];
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xs),xs,100*eps)
+%!test
+%! pus = us(:,[2,1,3:12]);
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xs),xs,100*eps)
+%!test
+%! us = alpha*[speye(11,9),[1;sparse(8,1);1;0]];
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xf);
+%! assert(us\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(us\xs,r\c,100*eps)
+%!test
+%! pus = us(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xs,r\c,100*eps)
+%!test
+%! ls = alpha*[speye(9,11);[1,sparse(1,8),1,0]];
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ls*(ls\xf),xf,100*eps)
+%!assert(ls*(ls\xs),xs,100*eps)
+%!test
+%! pls = ls([1:8,10,9],:);
+%!assert(pls*(pls\xf),xf,100*eps)
+%!assert(pls*(pls\xs),xs,100*eps)
+%!test
+%! ls = alpha*[speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]];
+%! xf = beta * ones(12,2);
+%! xs = speye(12,12);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xf);
+%! assert(ls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(ls\xs,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! pls = ls(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xs,r\c,100*eps)
+
+%!test alpha=1i;beta=1;
+%! n=8;
+%! lf=diag(1:n);lf(n-1,1)=0.5*alpha;lf(n,2)=0.25*alpha;ls=sparse(lf);
+%! uf=diag(1:n);uf(1,n-1)=2*alpha;uf(2,n)=alpha;us=sparse(uf);
+%! ts=spdiags(ones(n,3),-1:1,n,n)+diag(1:n); tf = full(ts);
+%! df = diag(1:n).* alpha; ds = sparse(df);
+%! pdf = df(randperm(n),randperm(n)); pds = sparse(pdf);
+%! plf = lf(randperm(n),randperm(n)); pls = sparse(plf);
+%! puf = uf(randperm(n),randperm(n)); pus = sparse(puf);
+%! bs = spdiags(repmat([1:n]',1,4),-2:1,n,n).*alpha; bf = full(bs);
+%! cf = lf + lf'; cs = sparse(cf);
+%! bcf = bf + bf'; bcs = sparse(bcf);
+%! tcf = tf + tf'; tcs = sparse(tcf);
+%! xf = diag(1:n) + fliplr(diag(1:n)).*beta; xs = sparse(xf);
+%!assert(ds\xf,df\xf,1e-10);
+%!assert(ds\xs,sparse(df\xf),1e-10);
+%!assert(pds\xf,pdf\xf,1e-10);
+%!assert(pds\xs,sparse(pdf\xf),1e-10);
+%!assert(ls\xf,lf\xf,1e-10);
+%!assert(sparse(ls\xs),sparse(lf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pls\xf,plf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pls\xs),sparse(plf\xf),1e-10);
+%!assert(us\xf,uf\xf,1e-10);
+%!assert(sparse(us\xs),sparse(uf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pus\xf,puf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pus\xs),sparse(puf\xf),1e-10);
+%!assert(bs\xf,bf\xf,1e-10);
+%!assert(sparse(bs\xs),sparse(bf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(cs\xf,cf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(cs\xs),sparse(cf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(bcs\xf,bcf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(bcs\xs),sparse(bcf\xf),1e-10);
+%!assert(ts\xf,tf\xf,1e-10);
+%!assert(sparse(ts\xs),sparse(tf\xf),1e-10);
+%!assert(tcs\xf,tcf\xf,1e-10);
+%!assert(sparse(tcs\xs),sparse(tcf\xf),1e-10);
+
+%% QR solver tests
+
+%!function f(a, sz, feps)
+%! b = randn(sz); x = a \b; 
+%! assert (a * x, b, feps);
+%! b = randn(sz)+1i*randn(sz); x = a \ b;  
+%! assert (a * x, b, feps);
+%! b = sprandn(sz(1),sz(2),0.2); x = a \b;
+%! assert (sparse(a * x), b, feps);
+%! b = sprandn(sz(1),sz(2),0.2)+1i*sprandn(sz(1),sz(2),0.2); x = a \b; 
+%! assert (sparse(a * x), b, feps);
+%!testif HAVE_CXSPARSE
+%! a = alpha*sprandn(10,11,0.2)+speye(10,11); f(a,[10,2],1e-10);
+%! ## Test this by forcing matrix_type, as can't get a certain 
+%! ## result for over-determined systems.
+%! a = alpha*sprandn(10,10,0.2)+speye(10,10); matrix_type(a, "Singular");
+%! f(a,[10,2],1e-10);
+
+%% Rectanguar solver tests that don't use QR
+
+%!test
+%! ds = alpha * spdiags([1:11]',0,10,11);
+%! df = full(ds);
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:10],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! ds = alpha * spdiags([1:11]',0,11,10);
+%! df = full(ds);
+%! xf = beta * ones(11,2);
+%! xs = speye(11,11);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:11],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! us = alpha*[[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]];
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xs),xs,100*eps)
+%!test
+%! pus = us(:,[2,1,3:12]);
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xs),xs,100*eps)
+%!test
+%! us = alpha*[speye(11,9),[1;sparse(8,1);1;0]];
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xf);
+%! assert(us\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(us\xs,r\c,100*eps)
+%!test
+%! pus = us(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xs,r\c,100*eps)
+%!test
+%! ls = alpha*[speye(9,11);[1,sparse(1,8),1,0]];
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ls*(ls\xf),xf,100*eps)
+%!assert(ls*(ls\xs),xs,100*eps)
+%!test
+%! pls = ls([1:8,10,9],:);
+%!assert(pls*(pls\xf),xf,100*eps)
+%!assert(pls*(pls\xs),xs,100*eps)
+%!test
+%! ls = alpha*[speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]];
+%! xf = beta * ones(12,2);
+%! xs = speye(12,12);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xf);
+%! assert(ls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(ls\xs,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! pls = ls(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xs,r\c,100*eps)
+
+%!test alpha=1i;beta=1i;
+%! n=8;
+%! lf=diag(1:n);lf(n-1,1)=0.5*alpha;lf(n,2)=0.25*alpha;ls=sparse(lf);
+%! uf=diag(1:n);uf(1,n-1)=2*alpha;uf(2,n)=alpha;us=sparse(uf);
+%! ts=spdiags(ones(n,3),-1:1,n,n)+diag(1:n); tf = full(ts);
+%! df = diag(1:n).* alpha; ds = sparse(df);
+%! pdf = df(randperm(n),randperm(n)); pds = sparse(pdf);
+%! plf = lf(randperm(n),randperm(n)); pls = sparse(plf);
+%! puf = uf(randperm(n),randperm(n)); pus = sparse(puf);
+%! bs = spdiags(repmat([1:n]',1,4),-2:1,n,n).*alpha; bf = full(bs);
+%! cf = lf + lf'; cs = sparse(cf);
+%! bcf = bf + bf'; bcs = sparse(bcf);
+%! tcf = tf + tf'; tcs = sparse(tcf);
+%! xf = diag(1:n) + fliplr(diag(1:n)).*beta; xs = sparse(xf);
+%!assert(ds\xf,df\xf,1e-10);
+%!assert(ds\xs,sparse(df\xf),1e-10);
+%!assert(pds\xf,pdf\xf,1e-10);
+%!assert(pds\xs,sparse(pdf\xf),1e-10);
+%!assert(ls\xf,lf\xf,1e-10);
+%!assert(sparse(ls\xs),sparse(lf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pls\xf,plf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pls\xs),sparse(plf\xf),1e-10);
+%!assert(us\xf,uf\xf,1e-10);
+%!assert(sparse(us\xs),sparse(uf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(pus\xf,puf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(pus\xs),sparse(puf\xf),1e-10);
+%!assert(bs\xf,bf\xf,1e-10);
+%!assert(sparse(bs\xs),sparse(bf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(cs\xf,cf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(cs\xs),sparse(cf\xf),1e-10);
+%!testif HAVE_UMFPACK
+%! assert(bcs\xf,bcf\xf,1e-10);
+%!testif HAVE_UMFPACK
+%! assert(sparse(bcs\xs),sparse(bcf\xf),1e-10);
+%!assert(ts\xf,tf\xf,1e-10);
+%!assert(sparse(ts\xs),sparse(tf\xf),1e-10);
+%!assert(tcs\xf,tcf\xf,1e-10);
+%!assert(sparse(tcs\xs),sparse(tcf\xf),1e-10);
+
+%% QR solver tests
+
+%!function f(a, sz, feps)
+%! b = randn(sz); x = a \b; 
+%! assert (a * x, b, feps);
+%! b = randn(sz)+1i*randn(sz); x = a \ b;  
+%! assert (a * x, b, feps);
+%! b = sprandn(sz(1),sz(2),0.2); x = a \b;
+%! assert (sparse(a * x), b, feps);
+%! b = sprandn(sz(1),sz(2),0.2)+1i*sprandn(sz(1),sz(2),0.2); x = a \b; 
+%! assert (sparse(a * x), b, feps);
+%!testif HAVE_CXSPARSE
+%! a = alpha*sprandn(10,11,0.2)+speye(10,11); f(a,[10,2],1e-10);
+%! ## Test this by forcing matrix_type, as can't get a certain 
+%! ## result for over-determined systems.
+%! a = alpha*sprandn(10,10,0.2)+speye(10,10); matrix_type(a, "Singular");
+%! f(a,[10,2],1e-10);
+
+%% Rectanguar solver tests that don't use QR
+
+%!test
+%! ds = alpha * spdiags([1:11]',0,10,11);
+%! df = full(ds);
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:10],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! ds = alpha * spdiags([1:11]',0,11,10);
+%! df = full(ds);
+%! xf = beta * ones(11,2);
+%! xs = speye(11,11);
+%!assert(ds\xf,df\xf,100*eps)
+%!assert(ds\xs,sparse(df\xs),100*eps)
+%!test
+%! pds = ds([2,1,3:11],:);
+%! pdf = full(pds);
+%!assert(pds\xf,pdf\xf,100*eps)
+%!assert(pds\xs,sparse(pdf\xs),100*eps)
+%!test
+%! us = alpha*[[speye(10,10);sparse(1,10)],[[1,1];sparse(9,2);[1,1]]];
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(us*(us\xs),xs,100*eps)
+%!test
+%! pus = us(:,[2,1,3:12]);
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xf),xf,100*eps)
+%!testif HAVE_UMFPACK
+%! assert(pus*(pus\xs),xs,100*eps)
+%!test
+%! us = alpha*[speye(11,9),[1;sparse(8,1);1;0]];
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xf);
+%! assert(us\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (us, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(us\xs,r\c,100*eps)
+%!test
+%! pus = us(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pus, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pus\xs,r\c,100*eps)
+%!test
+%! ls = alpha*[speye(9,11);[1,sparse(1,8),1,0]];
+%! xf = beta * ones(10,2);
+%! xs = speye(10,10);
+%!assert(ls*(ls\xf),xf,100*eps)
+%!assert(ls*(ls\xs),xs,100*eps)
+%!test
+%! pls = ls([1:8,10,9],:);
+%!assert(pls*(pls\xf),xf,100*eps)
+%!assert(pls*(pls\xs),xs,100*eps)
+%!test
+%! ls = alpha*[speye(10,10),sparse(10,1);[1;1],sparse(2,9),[1;1]];
+%! xf = beta * ones(12,2);
+%! xs = speye(12,12);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xf);
+%! assert(ls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (ls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(ls\xs,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! pls = ls(:,[1:8,10,9]);
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xf);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xf,r\c,100*eps)
+%!testif HAVE_CXSPARSE
+%! [c,r] = qr (pls, xs);
+%! r = matrix_type(r,"Singular"); ## Force Matrix Type
+%! assert(pls\xs,r\c,100*eps)
+
+
+# ==============================================================
+
diff --git a/test/test_string.m b/test/test_string.m
new file mode 100644
index 0000000..8760959
--- /dev/null
+++ b/test/test_string.m
@@ -0,0 +1,454 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/string/str-esc-1.m
+%!test
+%! x = 7;
+%! if (strcmp ("\a", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-2.m
+%!test
+%! x = 8;
+%! if (strcmp ("\b", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-3.m
+%!test
+%! x = 12;
+%! if (strcmp ("\f", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-4.m
+%!test
+%! x = 10;
+%! if (strcmp ("\n", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-5.m
+%!test
+%! x = 13;
+%! if (strcmp ("\r", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-6.m
+%!test
+%! x = 9;
+%! if (strcmp ("\t", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-7.m
+%!test
+%! x = 11;
+%! if (strcmp ("\v", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-8.m
+%!test
+%! x = 92;
+%! if (strcmp ("\\", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-9.m
+%!test
+%! x = 39;
+%! if (strcmp ("\'", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-10.m
+%!test
+%! x = 34;
+%! if (strcmp ("\"", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/string/str-esc-11.m
+%!test
+%! x = 120;
+%! fail('strcmp ("\x", setstr (x))',"warning",".*unrecognized escape sequence.*");
+
+%% test/octave.test/string/str-esc-12.m
+%!test
+%! x = [7, 8, 12, 10, 13, 9, 11, 92, 39, 34];
+%! if (strcmp ("\a\b\f\n\r\t\v\\\'\"", setstr (x)))
+%! printf_assert ("ok\n");
+%! endif
+%! assert(prog_output_assert("ok"));
+
+%% FIXME
+%% Why do the next two tests fail?
+%% test/octave.test/string/string_fill_char-1.m
+%!#test
+%! sfc = string_fill_char;
+%! string_fill_char = "X";
+%! str = ["these"; "are"; "strings"];
+%! assert(str,["theseXX"; "areXXXX"; "strings"]);
+%! string_fill_char = sfc;
+
+%% test/octave.test/string/string_fill_char-2.m
+%!#test
+%! sfc = string_fill_char;
+%! string_fill_char = " ";
+%! str = ["these"; "are"; "strings"];
+%! assert(str,["these  "; "are    "; "strings"]);
+%! string_fill_char = sfc;
+
+%% test/octave.test/string/ischar-1.m
+%!assert(!(ischar (1)));
+
+%% test/octave.test/string/ischar-2.m
+%!assert(!(ischar ([1, 2])));
+
+%% test/octave.test/string/ischar-3.m
+%!assert(!(ischar ([])));
+
+%% test/octave.test/string/ischar-4.m
+%!assert(!(ischar ([1, 2; 3, 4])));
+
+%% test/octave.test/string/ischar-5.m
+%!assert(ischar (""));
+
+%% test/octave.test/string/ischar-6.m
+%!assert(ischar ("t"));
+
+%% test/octave.test/string/ischar-7.m
+%!assert(ischar ("test"));
+
+%% test/octave.test/string/ischar-8.m
+%!assert(ischar (["test"; "ing"]));
+
+%% test/octave.test/string/ischar-9.m
+%!test
+%! s.a = "test";
+%! assert(!(ischar (s)));
+
+%% test/octave.test/string/ischar-10.m
+%!error <Invalid call to ischar.*> ischar ();
+
+%% test/octave.test/string/ischar-11.m
+%!error <Invalid call to ischar.*> ischar ("test", 1);
+
+
+%% test/octave.test/string/char-1.m
+%!assert(strcmp (char ([65, 83, 67, 73, 73]), "ASCII"));
+
+%% test/octave.test/string/char-2.m
+%!error <Invalid call to char.*> char ();
+
+%% test/octave.test/string/char-3.m
+%!test
+%! x = char ("foo", "bar", "foobar");
+%! assert((strcmp (x(1,:), "foo   ")
+%! && strcmp (x(2,:), "bar   ")
+%! && strcmp (x(3,:), "foobar")));
+
+
+%% test/octave.test/string/strcmp-1.m
+%!assert(strcmp ("foobar", "foobar") && strcmp ("fooba", "foobar") == 0);
+
+%% test/octave.test/string/strcmp-2.m
+%!error <Invalid call to strcmp.*> strcmp ();
+
+%% test/octave.test/string/strcmp-3.m
+%!error <Invalid call to strcmp.*> strcmp ("foo", "bar", 3);
+
+
+
+%% test/octave.test/string/undo_string_escapes-1.m
+%!assert(strcmp (undo_string_escapes ("abc\a\b\n\r\t\v\f123"),
+%! "abc\\a\\b\\n\\r\\t\\v\\f123"));
+
+%% test/octave.test/string/undo_string_escapes-2.m
+%!error <Invalid call to undo_string_escapes.*> undo_string_escapes ();
+
+%% test/octave.test/string/undo_string_escapes-3.m
+%!error <Invalid call to undo_string_escapes.*> undo_string_escapes ("string", 2);
+
+%% test/octave.test/string/toascii-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = 0:127;
+%! 
+%! assert(all (toascii (charset) == result));
+
+%% test/octave.test/string/toascii-3.m
+%!error toascii (1, 2);
+
+%% test/octave.test/string/toascii-3.m
+%!error toascii (1, 2);
+
+%% test/octave.test/string/tolower-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = charset;
+%! 
+%! result ((toascii("A"):toascii("Z"))+1) \
+%! = result ((toascii("a"):toascii("z"))+1);
+%! 
+%! assert(all (tolower (charset) == result));
+
+%% test/octave.test/string/tolower-3.m
+%!error tolower (1, 2);
+
+%% test/octave.test/string/tolower-3.m
+%!error tolower (1, 2);
+
+%% test/octave.test/string/toupper-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = charset;
+%! 
+%! result ((toascii("a"):toascii("z"))+1) \
+%! = result ((toascii("A"):toascii("Z"))+1);
+%! 
+%! assert(all (toupper (charset) == result));
+
+%% test/octave.test/string/toupper-3.m
+%!error toupper (1, 2);
+
+%% test/octave.test/string/toupper-3.m
+%!error toupper (1, 2);
+
+%% test/octave.test/string/isalnum-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result ((toascii("A"):toascii("Z"))+1) = 1;
+%! result ((toascii("0"):toascii("9"))+1) = 1;
+%! result ((toascii("a"):toascii("z"))+1) = 1;
+%! 
+%! assert(all (isalnum (charset) == result));
+
+%% test/octave.test/string/isalnum-2.m
+%!error isalnum (1, 2);
+
+%% test/octave.test/string/isalnum-3.m
+%!error isalnum ();
+
+%% test/octave.test/string/isalpha-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result ((toascii("A"):toascii("Z"))+1) = 1;
+%! result ((toascii("a"):toascii("z"))+1) = 1;
+%! 
+%! assert(all (isalpha (charset) == result));
+
+%% test/octave.test/string/isalpha-2.m
+%!error isalpha (1, 2);
+
+%% test/octave.test/string/isalpha-3.m
+%!error isalpha ();
+
+%% test/octave.test/string/isascii-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = ones (1, 128);
+%! 
+%! assert(all (isascii (charset) == result));
+
+%% test/octave.test/string/isascii-2.m
+%!error isascii (1, 2);
+
+%% test/octave.test/string/isascii-3.m
+%!error isascii ();
+
+%% test/octave.test/string/iscntrl-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result (1:32) = 1;
+%! result (128) = 1;
+%! 
+%! assert(all (iscntrl (charset) == result));
+
+%% test/octave.test/string/iscntrl-2.m
+%!error iscntrl (1, 2);
+
+%% test/octave.test/string/iscntrl-3.m
+%!error iscntrl ();
+
+%% test/octave.test/string/isdigit-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result ((toascii("0"):toascii("9"))+1) = 1;
+%! 
+%! assert(all (isdigit (charset) == result));
+
+%% test/octave.test/string/isdigit-2.m
+%!error isdigit (1, 2);
+
+%% test/octave.test/string/isdigit-3.m
+%!error isdigit ();
+
+%% test/octave.test/string/isgraph-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result (34:127) = 1;
+%! 
+%! assert(all (isgraph (charset) == result));
+
+%% test/octave.test/string/isgraph-2.m
+%!error isgraph (1, 2);
+
+%% test/octave.test/string/isgraph-3.m
+%!error isgraph ();
+
+%% test/octave.test/string/islower-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result ((toascii("a"):toascii("z"))+1) = 1;
+%! 
+%! assert(all (islower (charset) == result));
+
+%% test/octave.test/string/islower-2.m
+%!error islower (1, 2);
+
+%% test/octave.test/string/islower-3.m
+%!error islower ();
+
+%% test/octave.test/string/isprint-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result (33:127) = 1;
+%! if (ispc () && ! isunix ())
+%!   result(10) = 1;
+%! endif
+%! 
+%! assert(all (isprint (charset) == result));
+
+%% test/octave.test/string/isprint-2.m
+%!error isprint (1, 2);
+
+%% test/octave.test/string/isprint-3.m
+%!error isprint ();
+
+%% test/octave.test/string/ispunct-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result (34:48) = 1;
+%! result (59:65) = 1;
+%! result (92:97) = 1;
+%! result (124:127) = 1;
+%! 
+%! assert(all (ispunct (charset) == result));
+
+%% test/octave.test/string/ispunct-2.m
+%!error ispunct (1, 2);
+
+%% test/octave.test/string/ispunct-3.m
+%!error ispunct ();
+
+%% test/octave.test/string/isspace-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result (toascii (" \f\n\r\t\v")+1) = 1;
+%! 
+%! assert(all (isspace (charset) == result));
+
+%% test/octave.test/string/isspace-2.m
+%!error isspace (1, 2);
+
+%% test/octave.test/string/isspace-3.m
+%!error isspace ();
+
+%% test/octave.test/string/isupper-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result ((toascii("A"):toascii("Z"))+1) = 1;
+%! 
+%! assert(all (isupper (charset) == result));
+
+%% test/octave.test/string/isupper-2.m
+%!error isupper (1, 2);
+
+%% test/octave.test/string/isupper-3.m
+%!error isupper ();
+
+%% test/octave.test/string/isxdigit-1.m
+%!test
+%! charset = setstr (0:127);
+%! 
+%! result = zeros (1, 128);
+%! 
+%! result ((toascii("A"):toascii("F"))+1) = 1;
+%! result ((toascii("0"):toascii("9"))+1) = 1;
+%! result ((toascii("a"):toascii("f"))+1) = 1;
+%! 
+%! assert(all (isxdigit (charset) == result));
+
+%% test/octave.test/string/isxdigit-2.m
+%!error isxdigit (1, 2);
+
+%% test/octave.test/string/isxdigit-3.m
+%!error isxdigit ();
+
+%% test concatenation with all zero matrices
+%!assert([ '' 65*ones(1,10) ], 'AAAAAAAAAA');
+%!assert([ 65*ones(1,10) '' ], 'AAAAAAAAAA');
+
diff --git a/test/test_struct.m b/test/test_struct.m
new file mode 100644
index 0000000..410080a
--- /dev/null
+++ b/test/test_struct.m
@@ -0,0 +1,264 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/struct/fieldnames-1.m
+%!test
+%! s.a = 1;
+%! c = fieldnames (s);
+%! assert(iscell (c) && strcmp (c{1}, "a"));
+
+%% test/octave.test/struct/fieldnames-2.m
+%!test
+%! s.a.b = 1;
+%! c = fieldnames (s.a);
+%! assert(iscell (c) && strcmp (c{1}, "b"));
+
+%% test/octave.test/struct/fieldnames-3.m
+%!error <Invalid call to fieldnames.*> fieldnames ();
+
+%% test/octave.test/struct/fieldnames-4.m
+%!test
+%! s.a = 1;
+%! fail("fieldnames (s, 1)","Invalid call to fieldnames.*");
+
+%% test/octave.test/struct/fieldnames-5.m
+%!error fieldnames (1);
+
+%% test/octave.test/struct/isfield-1.m
+%!test
+%! s.aaa = 1;
+%! s.a = 2;
+%! assert(isfield (s, "a"));
+
+%% test/octave.test/struct/isfield-2.m
+%!test
+%! s.aaa = 1;
+%! s.a = 2;
+%! assert(!(isfield (s, "b")));
+
+%% test/octave.test/struct/isfield-3.m
+%!error <Invalid call to isfield.*> isfield ();
+
+%% test/octave.test/struct/isfield-4.m
+%!test
+%! s.aaa = 1;
+%! s.a = 2;
+%! fail("isfield (s, 'a', 3);","Invalid call to isfield.*");
+
+%% test/octave.test/struct/isfield-5.m
+%!assert(isfield (1, "m") == 0);
+
+%% test/octave.test/struct/isfield-6.m
+%!test
+%! s.a = 2;
+%! assert(isfield (s, 2) == 0);
+
+%% test/octave.test/struct/isstruct-1.m
+%!assert(!(isstruct (1)));
+
+%% test/octave.test/struct/isstruct-2.m
+%!assert(!(isstruct ([1, 2])));
+
+%% test/octave.test/struct/isstruct-3.m
+%!assert(!(isstruct ([])));
+
+%% test/octave.test/struct/isstruct-4.m
+%!assert(!(isstruct ([1, 2; 3, 4])));
+
+%% test/octave.test/struct/isstruct-5.m
+%!assert(!(isstruct ("t")));
+
+%% test/octave.test/struct/isstruct-6.m
+%!assert(!(isstruct ("test")));
+
+%% test/octave.test/struct/isstruct-7.m
+%!assert(!(isstruct (["test"; "ing"])));
+
+%% test/octave.test/struct/isstruct-8.m
+%!test
+%! s.a = 1;
+%! assert(isstruct (s));
+
+%% test/octave.test/struct/isstruct-9.m
+%!test
+%! s.a.b = 1;
+%! assert(isstruct (s.a));
+
+%% test/octave.test/struct/isstruct-10.m
+%!error <Invalid call to isstruct.*> isstruct ();
+
+%% test/octave.test/struct/isstruct-11.m
+%!test
+%! s.a = 1;
+%! fail("isstruct (s, 1)","Invalid call to isstruct.*");
+
+## increment element of matrix stored in struct array field
+%!test
+%!  a = struct("c", {[1, 2, 3], [4, 5, 6], [7, 8, 9]});
+%!  a(2).c(3)++;
+%!  assert(a(2).c, [4, 5, 7]);
+
+## create struct array by assignment to cs-list
+%!test
+%!  [a(1:2).x] = deal (1, 3);
+%!  assert(a, struct("x", {1, 3}));
+%!  assert({a(1:2).x}, {1, 3});
+
+## assign to subrange of struct array field
+%!test
+%!  b = struct ("name", {"a", "b", "c"; "d", "e", "f"}, "value", 100);
+%!  [b(1:2, [1,3]).name] = deal("aaa", "ddd", "ccc", "fff");
+%!  assert ({b.name}, {"aaa", "ddd", "b", "e", "ccc", "fff"});
+
+## index into nested struct arrays
+%!test
+%!  a = struct ("name", {"a", "b", "c"; "d", "e", "f"}, "value", 0);
+%!  a(2).value = a;
+%!  assert (a(2).value(2,3).name, "f");
+
+## assign to subrange of field in nested struct array
+%!test
+%!  b = struct ("name", {"a", "b", "c"; "d", "e", "f"}, "value", 0);
+%!  b(3, 1).value = b;
+%!  [b(3, 1).value(1, [1, 3]).name] = deal ("aaa", "ccc");
+%!  assert (size (b), [3, 3]);
+%!  assert (b(3,1).value(1, 3).name, "ccc");
+
+## test 4 dimensional struct array
+%!test
+%!  c(4, 4, 4, 4).name  = "a";
+%!  c(3, 3, 3, 3).value = 1;
+%!  assert (c(2,2,2,2), struct ("name", [], "value", []));
+
+## assign to subrange of field in 4d struct array
+%!test
+%!  c(4, 4, 4, 4).name  = "a";
+%!  c(3, 3, 3, 3).value = 1;
+%!  [c([1, 3], 2, :, [3, 4]).value] = deal (1);
+%!  assert (length(find([c.value] == 1)), 17);
+%!  assert (length(find([c.value])), 17);
+
+## swap elements of struct array
+%!test
+%!  b = struct ("name", {"a", "b", "c"; "d", "e", "f"}, "value", 0);
+%!  [b([2, 1], [3, 1]).name] = deal(b([1, 2], [1, 2]).name);
+%!  assert ({b.name}, {"e", "b", "b", "e", "d", "a"});
+
+## test internal ordering of struct array fields
+%!test
+%!  c(4, 4, 4, 4).value = 3;
+%!  c(1, 2, 3, 4).value = 2;
+%!  c(3, 3, 3, 3).value = 1;
+%!  d = reshape ({c.value}, size(c));
+%!  assert ([d{4, 4, 4, 4}, d{1, 2, 3, 4}, d{3, 3, 3, 3}],
+%!          [3, 2, 1]);
+
+## test assignment to mixed cs-list of field element subranges
+%!test
+%!  b = struct ("name", {"a", "b", "c"; "d", "e", "f"}, "value", 100);
+%!  [b(1:2, [1, 3]).name, b(2, 1:3).value] = ...
+%!    deal (1, 2, 3, 4, "5", "6", "7");
+%!  assert ({b.name}, {1, 2, "b", "e", 3, 4});
+%!  assert ({b.value}, {100, "5", 100, "6", 100, "7"});
+
+%!error <a cs-list cannot be further indexed>
+%!  [a(1:3).x] = deal ([1, 5], [3, 7], [8, 9]);
+%!  [a(2:3).x(2)] = deal (10, 11);
+
+%!error <can't perform indexing operations for cs-list type>
+%!  [a(1:3).x] = deal ([1, 5], [3, 7], [8, 9]);
+%!  a(2:3).x(2);
+
+%!error <Index exceeds matrix dimension>
+%!  a(1).x.x = 1;
+%!  a(2).x;
+
+%!error <invalid number of output arguments for constant expression>
+%!  a = struct ("value", {1, 2, 3, 4, 5});
+%!  [a(2:4).value] = 1;
+
+%!error <invalid assignment to cs-list outside multiple assignment>
+%!  c(4, 4, 4, 4).name  = "a";
+%!  c(3, 3, 3, 3).value = 1;
+%!  c([1, 3], 2, :, [3, 4]).value = 1;
+
+## test lazy copying in structs: nested assignment to self
+%!test
+%!  a.a = 1;
+%!  a.b = a;
+%!  a.b.c = a;
+%!  assert (a.b.c.b, struct ("a", 1));
+
+## test lazy copying in structs: indirect nested assignment to self
+%!test
+%!  a.a = 1;
+%!  a.b = 2;
+%!  b.c = a;
+%!  b.d = 3;
+%!  c.d = b;
+%!  c.e = 4;
+%!  a.b = c;
+%!  a.b.e = a;
+%!  assert (a.b.e.b.d.c, struct ("a", 1, "b", 2));
+
+## test lazy copying in structs: nested assignment via function
+%!function aa = do_nest (a);
+%!  aa   = a;
+%!  aa.b = a;
+%! endfunction
+%!test
+%!  a.c = 1;
+%!  a = do_nest (a);
+%!  a = do_nest (a);
+%!  a = do_nest (a);
+%!  assert (a.b.b.b, struct ("c", 1));
+
+## test lazy copying in structs: nested assignment via function
+%!function aa = do_nest (a);
+%!  aa   = a;
+%!  aa.b = a;
+%!  aa.b.c = aa;
+%! endfunction
+%!test
+%!  a.c = 1;
+%!  a = do_nest (a);
+%!  a = do_nest (a);
+%!  a = do_nest (a);
+%!  assert (a.b.c.b.b.c.b.b.c.b, struct ("c", 1));
+
+## test lazy copying in structs: nested assignment on different levels.
+%!test
+%!  a.b = 1;
+%!  b.c = a;
+%!  b.d.e = a;
+%!  b.f.g.h = a;
+%!  b.i.j.k.l = a;
+%!  a.m = b;
+%!  a.m.c.b = a;
+%!  assert (a.m.c.b.m.i.j.k.l, struct ("b", 1));
+
+## test indexed assignment into empty struct array
+%!test
+%!  s = resize(struct(),3,2);
+%!  s(3).foo = 42;
+%!  assert (s(3), struct ("foo", 42));
+
+%!error <Index exceeds matrix dimension>
+%!  s = resize(struct(),3,2);
+%!  s(3).foo = 42;
+%!  s(7);
\ No newline at end of file
diff --git a/test/test_switch.m b/test/test_switch.m
new file mode 100644
index 0000000..ad3e263
--- /dev/null
+++ b/test/test_switch.m
@@ -0,0 +1,84 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/switch/switch-1.m
+%!test
+%! a = 1;
+%! b = 2;
+%! c = 3;
+%! 
+%! switch 0 case 1 x = a; case 2 x = b; otherwise x = c; endswitch
+%! switch 1 case 1 y = a; case 2 y = b; otherwise y = c; endswitch
+%! switch 2 case 1 z = a; case 2 z = b; otherwise z = c; endswitch
+%! switch 3 case 1 p = a; case 2 p = b; otherwise p = c; endswitch
+%! 
+%! assert(x == c && y == a && z == b && p == c);
+
+%% test/octave.test/switch/switch-2.m
+%!test
+%! a = 1;
+%! b = 2;
+%! c = 3;
+%! 
+%! x = zeros (1, 4);
+%! 
+%! k = 1;
+%! 
+%! for i = 0:3
+%! switch (i)
+%! case a
+%! x(k) = a;
+%! case b
+%! x(k) = b;
+%! otherwise
+%! x(k) = c;
+%! endswitch
+%! k++;
+%! endfor
+%! 
+%! assert(all (x == [3, 1, 2, 3]));
+
+%% test/octave.test/switch/switch-3.m
+%!test
+%! a = 1;
+%! b = 2;
+%! c = 3;
+%! 
+%! x = zeros (1, 4);
+%! 
+%! k = 1;
+%! 
+%! for i = 0:3
+%! switch (i)
+%! case a
+%! x(k) = a;
+%! endswitch
+%! k++;
+%! endfor
+%! 
+%! assert(all (x == [0, 1, 0, 0]));
+
+%% test/octave.test/switch/switch-4.m
+%!error <syntax error> eval("switch endswitch");
+
+%% test/octave.test/switch/switch-5.m
+%!error <syntax error> eval("switch case endswitch");
+
+%% test/octave.test/switch/switch-6.m
+%!error <syntax error> eval("switch 1 default 1; endswitch");
+
diff --git a/test/test_system.m b/test/test_system.m
new file mode 100644
index 0000000..71cbe2b
--- /dev/null
+++ b/test/test_system.m
@@ -0,0 +1,483 @@
+## Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/system/cputime-1.m
+%!test
+%! [t1, u1, s1] = cputime ();
+%! for i = 1:200
+%! sin (i);
+%! endfor
+%! [t2, u2, s2] = cputime ();
+%! assert(t1 == u1 + s1 && t2 == u2 + s2 && t2 >= t1 && u2 >= u2 && s2 >= s2);
+
+
+%% test/octave.test/system/tic-toc-1.m
+%!test
+%! tic ();
+%! sleep (2);
+%! assert(toc () > 0);
+
+%% test/octave.test/system/pause-1.m
+%!test
+%! pause (0);
+%! printf_assert ("ok\n");
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/system/pause-2.m
+%!error <Invalid call to pause.*> pause (1, 2);
+
+%% test/octave.test/system/sleep-1.m
+%!test
+%! sleep (0);
+%! printf_assert ("ok\n");
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/system/sleep-2.m
+%!error <Invalid call to sleep.*> sleep ();
+
+%% test/octave.test/system/sleep-3.m
+%!error <Invalid call to sleep.*> sleep (1, 2);
+
+%% test/octave.test/system/usleep-1.m
+%!test
+%! usleep (0);
+%! printf_assert ("ok\n");
+%! assert(prog_output_assert("ok"));
+
+%% test/octave.test/system/usleep-2.m
+%!error <Invalid call to usleep.*> usleep ();
+
+%% test/octave.test/system/usleep-3.m
+%!error <Invalid call to usleep.*> usleep (1, 2);
+
+%% test/octave.test/system/rename-1.m
+%!test
+%! from = tmpnam ();
+%! to = tmpnam ();
+%! id = fopen (from, "wb");
+%! if (id > 0 && fclose (id) == 0)
+%!   [s, e] = stat (from);
+%!   if (! e)
+%!     if (rename (from, to) == 0)
+%!       [s, e] = stat (from);
+%!       if (e < 0)
+%!         [s, e] = stat (to);
+%!         assert(e == 0);
+%!         unlink (to);
+%!       endif
+%!     endif
+%!   endif
+%! endif
+
+%% test/octave.test/system/rename-2.m
+%!error <Invalid call to rename.*> rename ();
+
+%% test/octave.test/system/rename-3.m
+%!error <Invalid call to rename.*> rename ("foo", "bar", 1);
+
+%% test/octave.test/system/unlink-1.m
+%!test
+%! nm = tmpnam ();
+%! if ((id = fopen (nm, "wb")) > 0)
+%!   [s, err] = stat (nm);
+%!   if (! err && fclose (id) == 0 && unlink (nm) == 0)
+%!     [s, err] = stat (nm);
+%!     assert(err < 0);
+%!   endif
+%! endif
+
+%% test/octave.test/system/unlink-2.m
+%!error <Invalid call to unlink.*> unlink ();
+
+%% test/octave.test/system/unlink-3.m
+%!error <Invalid call to unlink.*> unlink ("foo", 1);
+
+%% test/octave.test/system/readdir-1.m
+%!test
+%! [files, status, msg] = readdir (filesep);
+%! assert(iscell (files) && status == 0 && strcmp (msg, ""));
+
+%% test/octave.test/system/readdir-2.m
+%!error <Invalid call to readdir.*> readdir ();
+
+%% test/octave.test/system/readdir-3.m
+%!error <Invalid call to readdir.*> readdir ("foo", 1);
+
+%% test/octave.test/system/mk-rm-dir-1.m
+%!test
+%! nm = tmpnam ();
+%! e1 = mkdir (nm);
+%! [s2, e2] = stat (nm);
+%! e3 = rmdir (nm);
+%! [s4, e4] = stat (nm);
+%! assert((e1 && strcmp (s2.modestr(1), "d") && e3 && e4 < 0));
+
+%% test/octave.test/system/mkdir-1.m
+%!error <Invalid call to mkdir.*> mkdir ();
+
+%% test/octave.test/system/mkdir-2.m
+%!error <Invalid call to mkdir.*> mkdir ("foo", 1, 2);
+
+%% test/octave.test/system/rmdir-1.m
+%!error <Invalid call to rmdir.*> rmdir ();
+
+%% test/octave.test/system/rmdir-2.m
+%!test
+%! crr = confirm_recursive_rmdir ();
+%! confirm_recursive_rmdir (0);
+%! assert(!rmdir ("foo", "s"));
+%! confirm_recursive_rmdir (crr);
+
+%% FIXME This test messes up the path it seems!! Why?
+%% test/octave.test/system/umask-1.m
+%!#test
+%! umask (0);
+%! nm = tmpnam ();
+%! id = fopen (nm, "wb");
+%! s1 = stat (nm);
+%! fclose (id);
+%! unlink (nm);
+%! 
+%! umask (777);
+%! nm = tmpnam ();
+%! id = fopen (nm, "wb");
+%! s2 = stat (nm);
+%! fclose (id);
+%! unlink (nm);
+%! 
+%! assert(strcmp (s1.modestr, "-rw-rw-rw-") && strcmp (s2.modestr, "----------"));
+
+%% test/octave.test/system/umask-2.m
+%!error <Invalid call to umask.*> umask ();
+
+%% test/octave.test/system/umask-3.m
+%!error <Invalid call to umask.*> umask (1, 2);
+
+%% test/octave.test/system/stat-1.m
+%!test
+%! [s, err, msg] = stat (filesep);
+%! assert((err == 0
+%! && isstruct (s)
+%! && isfield (s, "dev")
+%! && isfield (s, "ino")
+%! && isfield (s, "modestr")
+%! && isfield (s, "nlink")
+%! && isfield (s, "uid")
+%! && isfield (s, "gid")
+%! && isfield (s, "size")
+%! && isfield (s, "atime")
+%! && isfield (s, "mtime")
+%! && isfield (s, "ctime")
+%! && ischar (msg)));
+
+%% test/octave.test/system/stat-2.m
+%!error <Invalid call to stat.*> stat ();
+
+%% test/octave.test/system/stat-3.m
+%!error <Invalid call to stat.*> stat ("foo", 1);
+
+%% test/octave.test/system/lstat-1.m
+%!test
+%! [s, err, msg] = lstat (filesep);
+%! assert((err == 0
+%! && isstruct (s)
+%! && isfield (s, "dev")
+%! && isfield (s, "ino")
+%! && isfield (s, "modestr")
+%! && isfield (s, "nlink")
+%! && isfield (s, "uid")
+%! && isfield (s, "gid")
+%! && isfield (s, "size")
+%! && isfield (s, "atime")
+%! && isfield (s, "mtime")
+%! && isfield (s, "ctime")
+%! && ischar (msg)));
+
+%% test/octave.test/system/lstat-2.m
+%!error <Invalid call to lstat.*> lstat ();
+
+%% test/octave.test/system/lstat-3.m
+%!error <Invalid call to lstat.*> lstat ("foo", 1);
+
+%% test/octave.test/system/glob-1.m
+%!assert(iscell (glob ([filesep "*"])));
+
+%% test/octave.test/system/glob-2.m
+%!error <Invalid call to glob*> glob ();
+
+%% test/octave.test/system/glob-3.m
+%!error <Invalid call to glob.*> glob ("foo", 1);
+
+%% test/octave.test/system/fnmatch-1.m
+%!test
+%! string_fill_char = setstr (0);
+%! assert((fnmatch ("a*a", {"aba"; "xxxba"; "aa"}) == [1; 0; 1]
+%! && fnmatch ({"a*a"; "b*b"}, "bob")
+%! && fnmatch ("x[0-5]*", {"x1"; "x6"}) == [1; 0]
+%! && fnmatch ("x[0-5]*", {"x1"; "x6"; "x001"}) == [1; 0; 1]
+%! && fnmatch ("x???y", {"xabcy"; "xy"}) == [1; 0]));
+
+%% test/octave.test/system/fnmatch-2.m
+%!error <Invalid call to fnmatch.*> fnmatch ();
+
+%% test/octave.test/system/fnmatch-3.m
+%!error <Invalid call to fnmatch.*> fnmatch ("foo", "bar", 3);
+
+%% test/octave.test/system/file_in_path-1.m
+%!assert(ischar (file_in_path (path (), "date.m")));
+
+%% test/octave.test/system/file_in_path-2.m
+%!error <invalid option> file_in_path ("foo", "bar", 1);
+
+%% test/octave.test/system/file_in_path-3.m
+%!error <Invalid call to file_in_path.*> file_in_path ();
+
+%% test/octave.test/system/file_in_path-4.m
+%!error <Invalid call to file_in_path.*> file_in_path ("foo", "bar", "baz", "ooka");
+
+%% test/octave.test/system/tilde_expand-1.m
+%!testif HAVE_GETPWUID
+%! x = getpwuid (getuid ());
+%! assert((strcmp (x.dir, tilde_expand ("~"))
+%! && strcmp (x.dir, tilde_expand (sprintf ("~%s", x.name)))
+%! && strcmp ("foobar", tilde_expand ("foobar"))));
+
+%% test/octave.test/system/tilde_expand-2.m
+%!error <Invalid call to tilde_expand.*> tilde_expand ();
+
+%% test/octave.test/system/tilde_expand-3.m
+%!error <Invalid call to tilde_expand.*> tilde_expand ("str", 2);
+
+%% test/octave.test/system/getpgrp-1.m
+%!testif HAVE_GETPGRP
+%! assert(getpgrp () > 0);
+
+%% test/octave.test/system/getpgrp-2.m
+%!error <... getpgrp> getpgrp (1);
+
+%% test/octave.test/system/getpid-1.m
+%!assert(getpid () > 0);
+
+%% test/octave.test/system/getpid-2.m
+%!error <... getpid> getpid (1);
+
+%% test/octave.test/system/getppid-1.m
+%!testif HAVE_GETPPID
+%! assert(getppid () > 0);
+
+%% test/octave.test/system/getppid-2.m
+%!error <... getppid> getppid (1);
+
+%% test/octave.test/system/geteuid-1.m
+%!assert(geteuid () >= 0);
+
+%% test/octave.test/system/geteuid-2.m
+%!error <... geteuid> geteuid (1);
+
+%% test/octave.test/system/getuid-1.m
+%!assert(getuid () >= 0);
+
+%% test/octave.test/system/getuid-2.m
+%!error <... getuid> getuid (1);
+
+%% test/octave.test/system/getegid-1.m
+%!assert(getegid () >= 0);
+
+%% test/octave.test/system/getegid-2.m
+%!error <... getegid> getegid (1);
+
+%% test/octave.test/system/getgid-1.m
+%!assert(getgid () >= 0);
+
+%% test/octave.test/system/getgid-2.m
+%!error <... getgid> getgid (1);
+
+%% test/octave.test/system/getenv-1.m
+%!assert(strcmp (getenv ("HOME"), tilde_expand ("~")));
+
+%% test/octave.test/system/getenv-2.m
+%!error <Invalid call to getenv.*> getenv ();
+
+%% test/octave.test/system/getenv-3.m
+%!error <Invalid call to getenv.*> getenv ("foo", 1);
+
+%% test/octave.test/system/getenv-4.m
+%!test
+%! wns = warning ("query", "Octave:num-to-str");
+%! warning ("on", "Octave:num-to-str");
+%! fail("getenv (1)","warning");
+%! warning (wns.state, "Octave:num-to-str");
+
+%% test/octave.test/system/putenv-1.m
+%!test
+%! putenv ("foobar", "baz");
+%! assert(strcmp (getenv ("foobar"), "baz"));
+
+%% test/octave.test/system/putenv-2.m
+%!error <Invalid call to putenv.*> putenv ();
+
+%% test/octave.test/system/putenv-3.m
+%!error <Invalid call to putenv.*> putenv ("foo", "bar", 1);
+
+%% test/octave.test/system/putenv-4.m
+%!test
+%! wns = warning ("query", "Octave:num-to-str");
+%! warning ("on", "Octave:num-to-str");
+%! fail("putenv (1, 2)","warning");
+%! warning (wns.state, "Octave:num-to-str");
+
+%% test/octave.test/system/cd-1.m
+%!test
+%! xdir = pwd ();
+%! cd /
+%! d1 = pwd ();
+%! cd (xdir);
+%! if (ispc () && ! isunix ())
+%!   # should be a drive letter
+%!   assert(length (d1), 3);
+%!   assert(d1(2), ":");
+%!   assert(d1(3), "\\");
+%! else
+%!   assert("/", d1);
+%! endif
+%! assert(pwd(), xdir);
+
+%% test/octave.test/system/cd-2.m
+%!error cd (1);
+
+%% test/octave.test/system/pwd-1.m
+%!assert(ischar (pwd ()));
+
+%% test/octave.test/system/getpwent-1.m
+%!testif HAVE_GETPWENT
+%! s = getpwent ();
+%! endpwent (); 
+%! assert((isstruct (s)
+%! && isfield (s, "name")
+%! && isfield (s, "passwd")
+%! && isfield (s, "uid")
+%! && isfield (s, "gid")
+%! && isfield (s, "gecos")
+%! && isfield (s, "dir")
+%! && isfield (s, "shell")));
+
+%% test/octave.test/system/getpwent-2.m
+%!error <Invalid call to getpwent.*> getpwent (1);
+
+%% test/octave.test/system/getpwuid-1.m
+%!testif HAVE_GETPWUID
+%! x = getpwent ();
+%! y = getpwuid (x.uid);
+%! endpwent (); 
+%! assert(strcmp (x.name, y.name) && x.uid == y.uid && x.gid == y.gid);
+
+%% test/octave.test/system/getpwuid-2.m
+%!error <Invalid call to getpwuid.*> getpwuid ();
+
+%% test/octave.test/system/getpwuid-3.m
+%!error <Invalid call to getpwuid.*> getpwuid (1, 2);
+
+%% test/octave.test/system/getpwnam-1.m
+%!testif HAVE_GETPWNAM
+%! x = getpwent ();
+%! y = getpwnam (x.name);
+%! endpwent (); 
+%! assert(strcmp (x.name, y.name) && x.uid == y.uid && x.gid == y.gid);
+
+%% test/octave.test/system/getpwnam-2.m
+%!error <Invalid call to getpwnam.*> getpwnam ();
+
+%% test/octave.test/system/getpwnam-3.m
+%!error <Invalid call to getpwnam.*> getpwnam ("foo", 1);
+
+%% test/octave.test/system/setpwent-1.m
+%!testif HAVE_SETPWENT
+%! x = getpwent ();
+%! setpwent ();
+%! y = getpwent ();
+%! endpwent (); 
+%! assert(strcmp (x.name, y.name) && x.uid == y.uid && x.gid == y.gid);
+
+%% test/octave.test/system/setpwent-2.m
+%!error <Invalid call to setpwent.*> setpwent (1);
+
+%% test/octave.test/system/endpwent-1.m
+%!error <Invalid call to endpwent.*> endpwent (1);
+
+%% test/octave.test/system/getgrent-1.m
+%!testif HAVE_GETGRENT
+%! x = getgrent ();
+%! endgrent ();
+%! assert((isstruct (x)
+%! && isfield (x, "name")
+%! && isfield (x, "passwd")
+%! && isfield (x, "gid")
+%! && isfield (x, "mem")));
+
+%% test/octave.test/system/getgrent-2.m
+%!error <Invalid call to getgrent.*> getgrent (1);
+
+%% test/octave.test/system/getgrgid-1.m
+%!testif HAVE_GETGRGID
+%! x = getgrent ();
+%! y = getgrgid (x.gid);
+%! endgrent ();
+%! assert(strcmp (x.name, y.name) && x.gid == y.gid);
+
+%% test/octave.test/system/getgrgid-2.m
+%!error <Invalid call to getgrgid.*> getgrgid ();
+
+%% test/octave.test/system/getgrgid-3.m
+%!error <Invalid call to getgrgid.*> getgrgid (1, 2);
+
+%% test/octave.test/system/getgrnam-1.m
+%!testif HAVE_GETGRNAM
+%! x = getgrent ();
+%! y = getgrnam (x.name);
+%! endgrent ();
+%! assert(strcmp (x.name, y.name) && x.gid == y.gid);
+
+%% test/octave.test/system/getgrnam-2.m
+%!error <Invalid call to getgrnam.*> getgrnam ();
+
+%% test/octave.test/system/getgrnam-3.m
+%!error <Invalid call to getgrnam.*> getgrnam ("foo", 1);
+
+%% test/octave.test/system/setgrent-1.m
+%!testif HAVE_SETGRENT
+%! x = getgrent ();
+%! setgrent ();
+%! y = getgrent ();
+%! endgrent ();
+%! assert(strcmp (x.name, y.name) && x.gid == y.gid);
+
+%% test/octave.test/system/setgrent-2.m
+%!error <Invalid call to setgrent.*> setgrent (1);
+
+%% test/octave.test/system/endgrent-1.m
+%!error <Invalid call to endgrent.*> endgrent (1);
+
+%% test/octave.test/system/isieee-1.m
+%!assert(isieee () == 1 || isieee () == 0);
+
+%% test/octave.test/system/octave_config_info-1.m
+%!assert(isstruct (octave_config_info ()));
+
+%% test/octave.test/system/getrusage-1.m
+%!assert(isstruct (getrusage ()));
+
diff --git a/test/test_transpose.m b/test/test_transpose.m
new file mode 100644
index 0000000..0b0e85a
--- /dev/null
+++ b/test/test_transpose.m
@@ -0,0 +1,38 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/transpose/transpose-1.m
+%!test
+%! scalar = 2;
+%! assert(scalar',2);
+
+%% test/octave.test/transpose/transpose-2.m
+%!test
+%! range = 1:4;
+%! assert(range',[1;2;3;4]);
+
+%% test/octave.test/transpose/transpose-3.m
+%!test
+%! vector = [1;2;3;4];
+%! assert(vector',[1,2,3,4]);
+
+%% test/octave.test/transpose/transpose-4.m
+%!test
+%! matrix = [1,2;3,4];
+%! assert(matrix',[1,3;2,4]);
+
diff --git a/test/test_try.m b/test/test_try.m
new file mode 100644
index 0000000..cefa528
--- /dev/null
+++ b/test/test_try.m
@@ -0,0 +1,139 @@
+## Copyright (C) 2006, 2007, 2008 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/try/try-1.m
+%!test
+%! try
+%! catch
+%!   error("Shoudn't get here");
+%! end_try_catch
+
+%% test/octave.test/try/try-2.m
+%!test
+%! try
+%!   clear a
+%!   a;
+%! catch
+%! end_try_catch
+%! a = 1;
+%! assert(a,1);
+
+%% test/octave.test/try/try-3.m
+%!test
+%! clear x;
+%! try
+%!   clear a
+%!   a;
+%!   x = 1;
+%! catch
+%! end_try_catch
+%! a = 2;
+%! assert(!exist('x'))
+%! assert(a,2)
+
+%% test/octave.test/try/try-4.m
+%!test
+%! try
+%!   clear a
+%!   a;
+%! catch
+%!   x = 1;
+%! end_try_catch
+%! assert(exist('x'))
+
+%% test/octave.test/try/try-5.m
+%!test
+%! try
+%!   clear a;
+%!   a;
+%!   error("Shoudn't get here");
+%! catch
+%!   assert (strcmp(lasterr()(1:13), "`a' undefined"))
+%! end_try_catch
+%! assert (strcmp(lasterr()(1:13), "`a' undefined"))
+
+%% test/octave.test/try/try-6.m
+%!test 
+%! try
+%!   error ("user-defined error")
+%! catch
+%!   assert(lasterr,"user-defined error");
+%! end_try_catch
+
+%% test/octave.test/try/try-7.m
+%!function ms = mangle (s)
+%!  ## Wrap angle brackets around S.
+%!  ms = cstrcat ("<", s, ">");
+%!test
+%! try
+%!   clear a
+%!   a;
+%!   error("Shoudn't get here");
+%! catch
+%!   assert(strcmp(mangle (lasterr)(1:14),"<`a' undefined"))
+%! end_try_catch
+
+
+%% test/octave.test/try/try-8.m
+%!test
+%! try
+%!   try
+%!     clear a
+%!     a;
+%!     error("Shoudn't get here");
+%!   catch
+%!     assert(strcmp(lasterr()(1:13), "`a' undefined"))
+%!   end_try_catch
+%!   clear b
+%!   b;
+%!   error("Shoudn't get here");
+%! catch
+%!   assert(strcmp(lasterr()(1:13), "`b' undefined"))
+%! end_try_catch
+
+%% test/octave.test/try/try-9.m
+%!test
+%! try
+%!   clear a
+%!   a;
+%!   error("Shoudn't get here");
+%! catch
+%!   try
+%!     assert(strcmp(lasterr()(1:13), "`a' undefined"))
+%!     clear b
+%!     b;
+%!     error("Shoudn't get here");
+%!   catch
+%!     assert(strcmp(lasterr()(1:13), "`b' undefined"))
+%!   end_try_catch
+%! end_try_catch
+
+%% test/octave.test/try/try-10.m
+%!test
+%! try
+%!   try
+%!     clear a
+%!     a;
+%!     error("Shoudn't get here");
+%!   catch
+%!     error(cstrcat("rethrow: ",lasterr));
+%!   end_try_catch
+%! catch
+%!   assert(strcmp(lasterr()(1:22), "rethrow: `a' undefined"))
+%! end_try_catch
+
diff --git a/test/test_unwind.m b/test/test_unwind.m
new file mode 100644
index 0000000..50b511d
--- /dev/null
+++ b/test/test_unwind.m
@@ -0,0 +1,56 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/unwind/unwind-1.m
+%!function y = f (x)
+%!  global g;
+%!  save_g = g;
+%!  unwind_protect
+%!    g = 0;
+%!    y = g;
+%!    [1,2;x];
+%!    g = 1;
+%!    y = [y, g];
+%!  unwind_protect_cleanup
+%!    g = save_g;
+%!    y = [y, g];
+%!  end_unwind_protect
+%!test
+%! global g = -1;
+%! y = f ([3,4]);
+%! assert(y,[0,1,-1]);
+
+%% test/octave.test/unwind/unwind-2.m
+%!function y = f (x)
+%!  global g;
+%!  save_g = g;
+%!  unwind_protect
+%!    g = 0;
+%!    y = g;
+%!    [1,2;x];
+%!    g = 1;
+%!    y = [y, g];
+%!  unwind_protect_cleanup
+%!    g = save_g;
+%!    y = [y, g];
+%!    assert(y,[0,-1]);
+%!  end_unwind_protect
+%!test
+%! global g = -1;
+%! fail("y = f (3);","number of columns must match");
+
diff --git a/test/test_while.m b/test/test_while.m
new file mode 100644
index 0000000..efbbaf7
--- /dev/null
+++ b/test/test_while.m
@@ -0,0 +1,70 @@
+## Copyright (C) 2006, 2007, 2009 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%% test/octave.test/while/while-1.m
+%!test
+%! i = 0;
+%! while (eye (2))
+%! i++;
+%! printf_assert ("%d\n", i);
+%! endwhile;
+%! assert(prog_output_assert(""));
+
+%% test/octave.test/while/while-2.m
+%!test
+%! i = 5;
+%! while (--i)
+%! printf_assert ("%d", i);
+%! endwhile
+%! printf_assert ("\n");
+%! assert(prog_output_assert("4321"));
+
+%% test/octave.test/while/while-3.m
+%!test
+%! i = 5;
+%! while (i)
+%! i--;
+%! printf_assert ("%d", i);
+%! endwhile
+%! printf_assert ("\n");
+%! assert(prog_output_assert("43210"));
+
+%% test/octave.test/while/while-4.m
+%!test
+%! i = 0;
+%! while (i++ < 20)
+%! if (i > 2)
+%! break;
+%! endif
+%! printf_assert ("%d", i);
+%! endwhile;
+%! printf_assert ("\n");
+%! assert(prog_output_assert("12"));
+
+%% test/octave.test/while/while-5.m
+%!test
+%! i = 0;
+%! while (++i < 5)
+%! if (i < 3)
+%! continue;
+%! endif
+%! printf_assert ("%d", i);
+%! endwhile
+%! printf_assert ("\n");
+%! assert(prog_output_assert("34"));
+

-- 
Debian packaging for octave



More information about the Pkg-octave-commit mailing list